init commit
129
frontend/src/App.svelte
Normal file
@@ -0,0 +1,129 @@
|
||||
<script lang="js">
|
||||
import { onMount } from "svelte";
|
||||
import Tools from "./components/Tools.svelte";
|
||||
import Light from "./components/Light.svelte";
|
||||
import ErrorPage from "./components/ErrorPage.svelte";
|
||||
import ControlButton from "./components/ControlButton.svelte";
|
||||
import Github from "./icons/github.svelte";
|
||||
import { getState, toggle, setupApi } from "./utils/tower.js";
|
||||
|
||||
const { VITE_APP_TITLE, VITE_DEVICE_URL, VITE_DEVICE_PATH, VITE_GITHUB_SOURCE } = import.meta.env;
|
||||
|
||||
const title =
|
||||
VITE_APP_TITLE?.length > 0
|
||||
? VITE_APP_TITLE
|
||||
: "Patlite Tower Light Controller";
|
||||
setupApi(VITE_DEVICE_URL, VITE_DEVICE_PATH);
|
||||
|
||||
// light tower state, seeded from API
|
||||
// & used as APP state
|
||||
let state = { a: 0, b: 0, c: 0 };
|
||||
let error;
|
||||
|
||||
async function toggleLight(color, value) {
|
||||
return toggle(color)
|
||||
.then(() => (state[color] = !value))
|
||||
.catch((error) => console.log("error while toggling light:\n", error));
|
||||
}
|
||||
|
||||
onMount(() =>
|
||||
getState()
|
||||
.then((s) => (state = s))
|
||||
.catch((err) => (error = err)),
|
||||
);
|
||||
</script>
|
||||
|
||||
{#if error}
|
||||
<ErrorPage {error} />
|
||||
{/if}
|
||||
|
||||
<main class="container">
|
||||
<h1>{title}</h1>
|
||||
|
||||
<div class="tower">
|
||||
{#each Object.entries(state || {}) as [color, value] (color)}
|
||||
<Light {color} state={value} onclick={() => toggleLight(color, value)} />
|
||||
{/each}
|
||||
<div class="leg"></div>
|
||||
</div>
|
||||
|
||||
<div class="actions">
|
||||
<Tools updateState={(_state) => (state = _state)} />
|
||||
|
||||
<div class="controls">
|
||||
{#each Object.entries(state || {}) as [color, value] (color)}
|
||||
<ControlButton
|
||||
{color}
|
||||
state={value}
|
||||
onclick={() => toggleLight(color, value)}
|
||||
/>
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<footer>
|
||||
<span><a href={VITE_GITHUB_SOURCE || '/'}><Github /></a> with svelte ❤️</span>
|
||||
</footer>
|
||||
|
||||
<style lang="scss">
|
||||
h1 {
|
||||
max-width: 800px;
|
||||
font-size: 3rem;
|
||||
}
|
||||
|
||||
.tower {
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
:global(.tower > .light:first-of-type::before) {
|
||||
position: absolute;
|
||||
content: "";
|
||||
--height: 10px;
|
||||
--whitespace: 8%;
|
||||
height: var(--height);
|
||||
width: calc(100% - var(--whitespace));
|
||||
top: calc((var(--height) * -2) + 5px);
|
||||
left: calc(var(--whitespace) / 2);
|
||||
background-color: grey;
|
||||
border-top-left-radius: 6px;
|
||||
border-top-right-radius: 6px;
|
||||
}
|
||||
|
||||
:global(.tower > .light:nth-of-type(3)::after) {
|
||||
position: absolute;
|
||||
content: "";
|
||||
--height: 16px;
|
||||
--whitespace: 10%;
|
||||
height: var(--height);
|
||||
width: calc(100% - var(--whitespace));
|
||||
bottom: calc(-1 * var(--height) - 5px);
|
||||
left: calc(var(--whitespace) / 2);
|
||||
background-color: grey;
|
||||
border-bottom-left-radius: 6px;
|
||||
border-bottom-right-radius: 6px;
|
||||
}
|
||||
|
||||
.leg {
|
||||
height: 4rem;
|
||||
width: 2rem;
|
||||
margin: 0 auto;
|
||||
background-color: grey;
|
||||
|
||||
border-bottom-left-radius: 6px;
|
||||
border-bottom-right-radius: 6px;
|
||||
}
|
||||
|
||||
.actions {
|
||||
width: 100%;
|
||||
max-width: 450px;
|
||||
}
|
||||
|
||||
.controls {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
flex-wrap: wrap;
|
||||
gap: 0.5rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
</style>
|
||||
76
frontend/src/components/ControlButton.svelte
Normal file
@@ -0,0 +1,76 @@
|
||||
<script>
|
||||
import Lamp from "../icons/lamp.svelte";
|
||||
import LampBright from "../icons/lamp-bright.svelte";
|
||||
|
||||
let { color, state, onclick } = $props();
|
||||
</script>
|
||||
|
||||
<button class={`control-btn ${color}-btn`} class:active={state} {onclick}>
|
||||
<svelte:component this={state ? LampBright : Lamp} />
|
||||
</button>
|
||||
|
||||
<style lang="scss">
|
||||
.control-btn {
|
||||
margin-top: 2rem;
|
||||
padding: 1rem;
|
||||
display: flex;
|
||||
flex: 1;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-size: 1rem;
|
||||
font-weight: bold;
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 1rem;
|
||||
cursor: pointer;
|
||||
max-height: 5rem;
|
||||
transition:
|
||||
transform 0.2s ease,
|
||||
box-shadow 0.3s ease,
|
||||
background-color 0.3s ease;
|
||||
|
||||
&:hover {
|
||||
transform: scale(1.1);
|
||||
}
|
||||
|
||||
&:focus {
|
||||
outline: none;
|
||||
box-shadow: 0 0 15px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
}
|
||||
|
||||
:global(.control-btn svg) {
|
||||
max-height: 40px;
|
||||
}
|
||||
|
||||
/* Individual Button Colors */
|
||||
.green-btn {
|
||||
background-color: #2ecc71;
|
||||
box-shadow: 0 0 10px rgba(46, 204, 113, 0.6);
|
||||
|
||||
&.active {
|
||||
background-color: #27ae60;
|
||||
box-shadow: 0 0 25px rgba(39, 174, 96, 0.9);
|
||||
}
|
||||
}
|
||||
|
||||
.orange-btn {
|
||||
background-color: #f39c12;
|
||||
box-shadow: 0 0 10px rgba(243, 156, 18, 0.6);
|
||||
|
||||
&.active {
|
||||
background-color: #e67e22;
|
||||
box-shadow: 0 0 25px rgba(230, 126, 34, 0.9);
|
||||
}
|
||||
}
|
||||
|
||||
.red-btn {
|
||||
background-color: #e74c3c;
|
||||
box-shadow: 0 0 10px rgba(231, 76, 60, 0.6);
|
||||
|
||||
&.active {
|
||||
background-color: #c0392b;
|
||||
box-shadow: 0 0 25px rgba(192, 57, 43, 0.9);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
84
frontend/src/components/ErrorPage.svelte
Normal file
@@ -0,0 +1,84 @@
|
||||
<script>
|
||||
let { error, title = "Whoops! A error occured" } = $props();
|
||||
|
||||
const importantEnvironmentVariables = {
|
||||
VITE_DEVICE_URL: "",
|
||||
VITE_DEVICE_PATH: "",
|
||||
};
|
||||
|
||||
const env = { ...importantEnvironmentVariables, ...import.meta.env };
|
||||
</script>
|
||||
|
||||
<article>
|
||||
<h1>{title}</h1>
|
||||
<p>
|
||||
it is sad when the application does not work, but below is a stack trace and
|
||||
current environment variables for deugging.
|
||||
</p>
|
||||
|
||||
<div>
|
||||
<label>Stack trace</label>
|
||||
<code>
|
||||
<p>Error occured and returned message: "{error}"</p>
|
||||
|
||||
<p>{error?.stack}</p>
|
||||
</code>
|
||||
|
||||
<label>Environment variables</label>
|
||||
<code>
|
||||
{#each Object.entries(env) as [key, value] (key)}
|
||||
<span>{key}: {value}<br /></span>
|
||||
{/each}
|
||||
</code>
|
||||
</div>
|
||||
</article>
|
||||
|
||||
<style style="scss">
|
||||
article {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
--margin: 1rem;
|
||||
width: calc(100% - var(--margin) * 4);
|
||||
max-width: 800px;
|
||||
margin: var(--margin);
|
||||
padding: var(--margin);
|
||||
border: 4px dashed #ff8800;
|
||||
border-radius: 0.5rem;
|
||||
|
||||
@media screen and (max-width: 750px) {
|
||||
width: unset;
|
||||
border: none;
|
||||
margin: 0;
|
||||
padding: 0.5rem;
|
||||
}
|
||||
|
||||
> div {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
> p {
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
}
|
||||
|
||||
label {
|
||||
font-weight: bold;
|
||||
margin-bottom: 0.5rem;
|
||||
margin-top: 2rem;
|
||||
}
|
||||
|
||||
code {
|
||||
overflow: scroll;
|
||||
max-width: 90vw;
|
||||
background-color: #1c1819;
|
||||
max-height: calc(90vh - 10rem);
|
||||
color: #fff;
|
||||
border-radius: 0.75rem;
|
||||
padding: 1rem;
|
||||
line-height: 1.4;
|
||||
}
|
||||
</style>
|
||||
59
frontend/src/components/Light.svelte
Normal file
@@ -0,0 +1,59 @@
|
||||
<script>
|
||||
let { color, state, onclick } = $props();
|
||||
</script>
|
||||
|
||||
<button class={`light ${color}`} class:active={state} {onclick} />
|
||||
|
||||
<style style="scss">
|
||||
.light {
|
||||
position: relative;
|
||||
height: 1.875rem;
|
||||
height: 10vh;
|
||||
aspect-ratio: 3 / 1;
|
||||
margin: 10px auto;
|
||||
border-radius: 1rem;
|
||||
background-color: #ccc;
|
||||
cursor: pointer;
|
||||
transition:
|
||||
transform 0.1s ease,
|
||||
box-shadow 0.2s ease,
|
||||
background-color 0.2s ease;
|
||||
|
||||
border: none;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.green {
|
||||
background-color: #2ecc71;
|
||||
|
||||
&.active {
|
||||
background-color: #2ecc71;
|
||||
box-shadow:
|
||||
0 0 25px rgba(46, 204, 113, 0.9),
|
||||
0 0 20px rgba(46, 204, 113, 0.5);
|
||||
transform: scale(1.1);
|
||||
}
|
||||
}
|
||||
.orange {
|
||||
background-color: #f39c12;
|
||||
|
||||
&.active {
|
||||
background-color: #f39c12;
|
||||
box-shadow:
|
||||
0 0 25px rgba(243, 156, 18, 0.9),
|
||||
0 0 20px rgba(243, 156, 18, 0.5);
|
||||
transform: scale(1.1);
|
||||
}
|
||||
}
|
||||
.red {
|
||||
background-color: #e74c3c;
|
||||
|
||||
&.active {
|
||||
background-color: #e74c3c;
|
||||
box-shadow:
|
||||
0 0 25px rgba(231, 76, 60, 0.9),
|
||||
0 0 20px rgba(231, 76, 60, 0.5);
|
||||
transform: scale(1.1);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
209
frontend/src/components/Tools.svelte
Normal file
@@ -0,0 +1,209 @@
|
||||
<script>
|
||||
import { setTower } from "../utils/tower.js";
|
||||
import { warningSeq, errorSeq, trafficSeq, sleep } from "../utils/actions.js";
|
||||
|
||||
// action icons
|
||||
import RubberDuck from "../icons/rubber-duck.svelte";
|
||||
import Warning from "../icons/warning.svelte";
|
||||
import Siren from "../icons/siren.svelte";
|
||||
import SirenBright from "../icons/siren-bright.svelte";
|
||||
import TrafficLights from "../icons/traffic-lights.svelte";
|
||||
import Bell from "../icons/bell.svelte";
|
||||
import FireHazard from "../icons/fire-hazard.svelte";
|
||||
|
||||
let { updateState } = $props();
|
||||
|
||||
let active = $state("");
|
||||
let seqRunning = $state(false);
|
||||
let iterator = $state(0);
|
||||
let iteratorSelector = 1;
|
||||
const ACTIONS = [
|
||||
{
|
||||
label: "siren",
|
||||
icons: [Siren, SirenBright],
|
||||
color: "#F63C3D",
|
||||
sequence: errorSeq,
|
||||
},
|
||||
{
|
||||
label: "warning",
|
||||
icons: [Warning],
|
||||
color: "#FFEF10",
|
||||
sequence: warningSeq,
|
||||
},
|
||||
{
|
||||
label: "traffic",
|
||||
icons: [TrafficLights],
|
||||
color: "#828C8A",
|
||||
sequence: trafficSeq,
|
||||
},
|
||||
{
|
||||
label: "fire",
|
||||
icons: [FireHazard],
|
||||
color: "#FF8800",
|
||||
sequence: warningSeq,
|
||||
},
|
||||
{
|
||||
label: "duck",
|
||||
icons: [RubberDuck],
|
||||
color: "#F8CE4C",
|
||||
sequence: [
|
||||
[0, 1, 0, 10],
|
||||
[0, 0, 0, 0],
|
||||
],
|
||||
},
|
||||
{
|
||||
label: "bell",
|
||||
icons: [Bell],
|
||||
color: "#CDB376",
|
||||
sequence: warningSeq,
|
||||
},
|
||||
];
|
||||
|
||||
async function runSequence(sequence) {
|
||||
iterator = iteratorSelector;
|
||||
|
||||
while (iterator > 0) {
|
||||
for (let seq in sequence) {
|
||||
const value = sequence[seq];
|
||||
const [green, orange, red, timeout] = value;
|
||||
|
||||
await setTower(value.slice(0, 3));
|
||||
updateState({ green, orange, red });
|
||||
await sleep(timeout);
|
||||
}
|
||||
|
||||
iterator -= 1;
|
||||
}
|
||||
|
||||
await setTower([0, 0, 0]);
|
||||
}
|
||||
|
||||
function toggleAction(action) {
|
||||
// abort if currently running
|
||||
if (active?.length > 0 || seqRunning) return;
|
||||
|
||||
seqRunning = true;
|
||||
active = action.label;
|
||||
|
||||
runSequence(action?.sequence).then(() => {
|
||||
seqRunning = false;
|
||||
active = null;
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<details class="tools">
|
||||
<summary>
|
||||
<label
|
||||
>Actions <input
|
||||
bind:value={iteratorSelector}
|
||||
type="number"
|
||||
min="1"
|
||||
/></label
|
||||
>
|
||||
<p>Select modes for quick actions</p>
|
||||
</summary>
|
||||
|
||||
<div>
|
||||
{#each ACTIONS as action (action)}
|
||||
<button
|
||||
class:active={action.label === active}
|
||||
style={`--hover-bg: ${action?.color};`}
|
||||
on:click={() => toggleAction(action)}
|
||||
>
|
||||
{#if action?.icons?.length > 1 && action.label === active}
|
||||
<svelte:component this={action.icons[1]} />
|
||||
{:else}
|
||||
<svelte:component this={action.icons[0]} />
|
||||
{/if}
|
||||
</button>
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
<footer>
|
||||
{#if seqRunning}
|
||||
<p>
|
||||
Currently running: {active}, {1 + iteratorSelector - iterator} of {iteratorSelector}
|
||||
</p>
|
||||
{/if}
|
||||
</footer>
|
||||
</details>
|
||||
|
||||
<style lang="scss">
|
||||
.tools {
|
||||
background-color: #f0f0f0;
|
||||
border-radius: 0.5rem;
|
||||
padding: 1rem;
|
||||
|
||||
> div {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-evenly;
|
||||
margin-top: 1rem;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
summary {
|
||||
width: 100%;
|
||||
text-align: left;
|
||||
cursor: pointer;
|
||||
-webkit-user-select: none;
|
||||
user-select: none;
|
||||
|
||||
&::-webkit-details-marker,
|
||||
&::marker {
|
||||
display: none;
|
||||
}
|
||||
|
||||
label,
|
||||
p {
|
||||
width: 100%;
|
||||
text-align: left;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
label {
|
||||
font-size: 1.2rem;
|
||||
font-weight: 600;
|
||||
|
||||
input {
|
||||
width: 2rem;
|
||||
padding: 0.5rem 0.5rem 0.5rem 0.25rem;
|
||||
font-size: 1.2rem;
|
||||
float: right;
|
||||
text-align: right;
|
||||
border-radius: 0.5rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
button {
|
||||
width: 8rem;
|
||||
height: 5rem;
|
||||
background-color: white;
|
||||
padding: 0.5rem;
|
||||
border: none;
|
||||
border-radius: 0.5rem;
|
||||
box-shadow: 0 0 15px rgba(0, 0, 0, 0.2);
|
||||
transition: all 0.2s ease;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover,
|
||||
&.active {
|
||||
scale: 1.1;
|
||||
background-color: var(--hover-bg, rgba(0, 0, 0, 0.7));
|
||||
fill: white;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
footer {
|
||||
p {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
:global(.tools button svg) {
|
||||
max-height: 64px;
|
||||
}
|
||||
</style>
|
||||
15
frontend/src/icons/bell.svelte
Normal file
@@ -0,0 +1,15 @@
|
||||
<!-- Generated by IcoMoon.io -->
|
||||
<svg
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="100%"
|
||||
height="100%"
|
||||
viewBox="0 0 768 768"
|
||||
>
|
||||
<g id="icomoon-ignore"> </g>
|
||||
<path
|
||||
d="M116.9 546c34.2-12.6 53.3-36.8 64-80.8 11.1-45.9 11.1-106.7 11.1-177.2 0-51.3 20-99.5 56.2-135.8 20.7-20.7 45.4-36.1 72.2-45.5 0.8-14.8 2.9-29.6 8.4-41.8 9.8-21.8 28.3-32.9 55.2-32.9s45.4 11.1 55.2 32.9c5.5 12.2 7.6 27 8.4 41.8 26.9 9.4 51.5 24.8 72.2 45.5 36.2 36.3 56.2 84.5 56.2 135.8 0 70.5 0 131.3 11.1 177.2 10.7 44 29.8 68.2 64 80.8 12.6 4.6 20.9 16.6 20.9 30v64c0 17.7-14.3 32-32 32h-192c0 35.3-28.7 64-64 64s-64-28.7-64-64h-192c-17.7 0-32-14.3-32-32v-64c0-13.4 8.4-25.4 20.9-30zM384 64c-18.5 0-27.6 5.9-30.7 34.4 10-1.6 20.3-2.4 30.7-2.4s20.7 0.8 30.7 2.4c-3.1-28.5-12.2-34.4-30.7-34.4zM384 704c17.6 0 32-14.4 32-32h-64c0 17.6 14.4 32 32 32zM160 608h448v-11.3c-42.3-22.3-69.6-60.6-83.1-116.5-12.9-53.2-12.9-117.6-12.9-192.2 0-70.6-57.4-128-128-128s-128 57.4-128 128c0 74.6 0 139-12.9 192.3-13.5 55.9-40.8 94.2-83.1 116.5v11.2z"
|
||||
></path>
|
||||
<path d="M384 192v32c-35.3 0-64 28.7-64 64v64h-32v-64c0-52.9 43.1-96 96-96z"
|
||||
></path>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
16
frontend/src/icons/cactus.svelte
Normal file
@@ -0,0 +1,16 @@
|
||||
<!-- Generated by IcoMoon.io -->
|
||||
<svg
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="100%"
|
||||
height="100%"
|
||||
viewBox="0 0 768 768"
|
||||
>
|
||||
<g id="icomoon-ignore"> </g>
|
||||
<path d="M352 128h32v32h-32v-32z"></path>
|
||||
<path d="M384 256h32v32h-32v-32z"></path>
|
||||
<path d="M352 384h32v32h-32v-32z"></path>
|
||||
<path
|
||||
d="M768 384v-32h-33.1c0.7-10.5 1.1-21.2 1.1-32 0-41.7-26.8-77.3-64-90.5v-37.5h-32v32c-20.7 0-39.9 6.6-55.6 17.8l-24.4-24.4-22.6 22.6 24.4 24.4c-11.2 15.7-17.8 34.9-17.8 55.6 0 44-6.3 94.3-32 116.5v-308.5c0-12.6-1.8-24.7-5.2-36.2l43.8-43.8-22.6-22.6-35.2 35.2c-22.6-36.4-62.9-60.6-108.8-60.6-37.7 0-71.6 16.4-95 42.3l-17-17-22.6 22.7 21 21c-9.2 17.7-14.4 37.7-14.4 59v148.5c-25.7-22.2-32-72.5-32-116.5 0-37.1-21.2-69.4-52-85.3l26.6-26.7-22.6-22.6-39 39c-2.9-0.3-5.9-0.4-9-0.4-11.2 0-22 1.9-32 5.5v-37.5h-32v56.5c-19.6 17.6-32 43.1-32 71.5h-32v32h33.1c3.3 49.4 14.5 95.6 32.5 135.8l-40.2 40.2 22.6 22.6 32.9-32.9c5.1 8.7 10.5 17 16.3 24.9 15.3 20.9 32.9 38.6 52.5 53l-28.3 28.4 22.6 22.6 33.5-33.5c0.3 0.2 0.6 0.3 1 0.5 24 12.7 50 20.8 77.6 24.3v258h-64v32h384v-32h-64v-98c27.6-3.5 53.6-11.7 77.6-24.3 0.3-0.2 0.6-0.3 1-0.5l33.5 33.5 22.6-22.6-28.3-28.3c19.6-14.4 37.2-32.2 52.5-53 5.8-7.9 11.2-16.2 16.3-24.9l32.9 32.9 22.6-22.6-40.2-40.2c14.1-31.4 23.9-66.5 29.2-103.8h36.2zM619.2 504.7c-34.3 46.6-82.4 71.3-139.2 71.3-17.7 0-32 14.3-32 32v128h-128v-288c0-17.7-14.3-32-32-32-56.8 0-104.9-24.7-139.2-71.3-34.1-46.3-52.8-111.9-52.8-184.7 0-17.6 14.4-32 32-32s32 14.4 32 32c0 53.1 8.5 96.1 25.1 128 10.4 19.8 24 35.4 40.5 46.2 18 11.8 39 17.8 62.4 17.8 17.7 0 32-14.3 32-32v-192c0-35.3 28.7-64 64-64s64 28.7 64 64v352c0 17.7 14.3 32 32 32 23.4 0 44.4-6 62.4-17.8 16.5-10.8 30.1-26.4 40.5-46.2 16.7-31.9 25.1-74.9 25.1-128 0-17.6 14.4-32 32-32s32 14.4 32 32c0 72.8-18.7 138.4-52.8 184.7z"
|
||||
></path>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.8 KiB |
21
frontend/src/icons/fire-hazard-active.svelte
Normal file
@@ -0,0 +1,21 @@
|
||||
<svg
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="100%"
|
||||
height="100%"
|
||||
viewBox="0 0 768 768"
|
||||
>
|
||||
<g id="icomoon-ignore"> </g>
|
||||
<path
|
||||
fill="#F63C3D"
|
||||
d="M761.2 675.3l-320-639.9c-10.8-21.8-32.8-35.4-57.2-35.4-24.5 0-46.4 13.6-57.2 35.4l-320 639.9c-4.4 8.8-6.8 18.7-6.8 28.7 0 35.3 28.7 64 64 64h640c35.3 0 64-28.7 64-64 0-10-2.4-19.9-6.8-28.7zM64 704l320-640c0 0 0 0 0 0l320 640h-640zM704 704c0 0 0 0 0 0s0.1 0 0 0c0.1 0 0 0 0 0z"
|
||||
></path>
|
||||
<path
|
||||
fill="#FFE016"
|
||||
d="M384 608c35.3 0 64-28.7 64-64 0-54-35.2-89.8-36.7-91.3-4.9-4.9-12.3-6.1-18.5-3-3 1.5-72.8 37.1-72.8 94.3 0 35.3 28.7 64 64 64zM396.3 484.7c8 11.3 19.7 32.4 19.7 59.3 0 17.6-14.4 32-32 32s-32-14.4-32-32c0-25.2 26.2-47.6 44.3-59.3z"
|
||||
></path>
|
||||
<path
|
||||
fill="#F63C3D"
|
||||
d="M355.3 290c-5 2.8-8.2 8.2-8.2 14 0 71.4-25.6 108.2-50.3 143.8-24.9 35.8-48.4 69.7-38.5 129 0 0.2 0.1 0.4 0.1 0.6 6.4 30.8 25.2 57.3 53 74.6 21.2 13.2 46.1 20 72 20 7.5 0 15-0.6 22.5-1.7 0.1 0 0.2 0 0.3 0 33.4-5.7 62.1-23.3 80.9-49.6 21.3-29.9 29.2-69.9 22.7-115.9 0-0.1 0-0.2 0-0.3-11.7-74.1-48.5-128.3-77.3-160.7-31.2-35.1-59.8-52.7-61-53.4-5-3.1-11.2-3.2-16.2-0.4zM478.1 509.3c11.7 83.6-32.2 121.6-77.2 129.4-52.7 8-101.4-21.6-111.1-67.4-7.6-46.3 10.5-72.3 33.3-105.2 21.6-31.1 47.8-68.8 54.5-131.2 31.5 26.7 86.4 84.8 100.5 174.4z"
|
||||
></path>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
19
frontend/src/icons/fire-hazard.svelte
Normal file
@@ -0,0 +1,19 @@
|
||||
<!-- Generated by IcoMoon.io -->
|
||||
<svg
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="100%"
|
||||
height="100%"
|
||||
viewBox="0 0 768 768"
|
||||
>
|
||||
<g id="icomoon-ignore"> </g>
|
||||
<path
|
||||
d="M761.2 675.3l-320-639.9c-10.8-21.8-32.8-35.4-57.2-35.4-24.5 0-46.4 13.6-57.2 35.4l-320 639.9c-4.4 8.8-6.8 18.7-6.8 28.7 0 35.3 28.7 64 64 64h640c35.3 0 64-28.7 64-64 0-10-2.4-19.9-6.8-28.7zM64 704l320-640c0 0 0 0 0 0l320 640h-640zM704 704c0 0 0 0 0 0s0.1 0 0 0c0.1 0 0 0 0 0z"
|
||||
></path>
|
||||
<path
|
||||
d="M384 608c35.3 0 64-28.7 64-64 0-54-35.2-89.8-36.7-91.3-4.9-4.9-12.3-6.1-18.5-3-3 1.5-72.8 37.1-72.8 94.3 0 35.3 28.7 64 64 64zM396.3 484.7c8 11.3 19.7 32.4 19.7 59.3 0 17.6-14.4 32-32 32s-32-14.4-32-32c0-25.2 26.2-47.6 44.3-59.3z"
|
||||
></path>
|
||||
<path
|
||||
d="M355.3 290c-5 2.8-8.2 8.2-8.2 14 0 71.4-25.6 108.2-50.3 143.8-24.9 35.8-48.4 69.7-38.5 129 0 0.2 0.1 0.4 0.1 0.6 6.4 30.8 25.2 57.3 53 74.6 21.2 13.2 46.1 20 72 20 7.5 0 15-0.6 22.5-1.7 0.1 0 0.2 0 0.3 0 33.4-5.7 62.1-23.3 80.9-49.6 21.3-29.9 29.2-69.9 22.7-115.9 0-0.1 0-0.2 0-0.3-11.7-74.1-48.5-128.3-77.3-160.7-31.2-35.1-59.8-52.7-61-53.4-5-3.1-11.2-3.2-16.2-0.4zM478.1 509.3c11.7 83.6-32.2 121.6-77.2 129.4-52.7 8-101.4-21.6-111.1-67.4-7.6-46.3 10.5-72.3 33.3-105.2 21.6-31.1 47.8-68.8 54.5-131.2 31.5 26.7 86.4 84.8 100.5 174.4z"
|
||||
></path>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
13
frontend/src/icons/flower.svelte
Normal file
@@ -0,0 +1,13 @@
|
||||
<!-- Generated by IcoMoon.io -->
|
||||
<svg
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="100%"
|
||||
height="100%"
|
||||
viewBox="0 0 768 768"
|
||||
>
|
||||
<g id="icomoon-ignore"> </g>
|
||||
<path
|
||||
d="M768.2 384c0-57.1-37.6-105.6-89.3-122 9.4-18 14.4-38.2 14.4-59.1 0-34.2-13.3-66.3-37.5-90.5s-56.3-37.5-90.5-37.5c-20.9 0-41 5-59.1 14.4-16.4-51.7-64.9-89.3-122-89.3-57.2-0.1-105.7 37.5-122.2 89.3-48.2-25-109.2-17.3-149.6 23.1s-48.1 101.4-23.1 149.6c-51.7 16.4-89.3 64.9-89.3 122s37.6 105.6 89.4 122.1c-25 48.2-17.3 109.2 23.1 149.6s101.3 48.1 149.6 23.1c16.4 51.8 64.9 89.4 122.1 89.4 57.1 0 105.6-37.6 122-89.3 18 9.4 38.2 14.4 59.1 14.4 34.2 0 66.3-13.3 90.5-37.5s37.5-56.3 37.5-90.5c0-20.9-5-41-14.4-59.1 51.7-16.6 89.3-65.1 89.3-122.2zM506.7 167.9c0.6-0.4 1.3-0.9 1.8-1.2 3.1-2.1 7.4-5 11.4-9 25-25 65.6-25 90.5 0 25 25 25 65.6 0 90.5-4 4-6.7 8-8.9 11.3-0.4 0.6-1 1.4-1.4 2-6.3 5.2-10.1 12.5-11.2 20.3l-93.8 38.9c-11.4-19.9-27.9-36.5-47.8-47.8l38.9-93.7c7.9-1.1 15.2-5 20.5-11.3zM384 448c-35.3 0-64-28.7-64-64s28.7-64 64-64c35.3 0 64 28.7 64 64s-28.7 64-64 64zM318.4 142.4c0.7-3.7 1.7-8.8 1.7-14.5 0-35.3 28.7-64 64-64s64 28.7 64 64c0 5.7 1 10.7 1.7 14.4 0.1 0.7 0.3 1.6 0.4 2.3-0.7 8.1 1.7 16 6.4 22.3l-38.9 93.7c-10.8-3-22.1-4.5-33.8-4.5s-23 1.6-33.8 4.5l-38.7-93.6c4.8-6.3 7.3-14.2 6.6-22.4 0.1-0.7 0.3-1.5 0.4-2.2zM157.7 157.6c25-25 65.6-25 90.5 0 4 4 8 6.7 11.3 8.9 0.6 0.4 1.4 1 2 1.4 5.2 6.2 12.5 10.1 20.2 11.2l38.9 93.7c-19.9 11.4-36.5 27.9-47.8 47.8l-93.6-38.8c-1-7.8-4.9-15.2-11.2-20.4-0.4-0.6-0.9-1.2-1.2-1.8-2.1-3.1-5-7.4-9-11.4-25-25-25-65.6-0.1-90.6zM64 384c0-35.3 28.7-64 64-64 5.7 0 10.7-1 14.4-1.7 0.7-0.1 1.6-0.3 2.3-0.4 8.1 0.7 16.1-1.7 22.3-6.5l93.6 38.8c-3 10.8-4.5 22.1-4.5 33.8s1.6 23 4.5 33.8l-93.6 38.8c-6.2-4.8-14.1-7.2-22.3-6.5-0.7-0.1-1.5-0.3-2.2-0.4-3.7-0.7-8.8-1.7-14.5-1.7-35.3 0-64-28.7-64-64zM261.5 600.1c-0.6 0.4-1.2 0.9-1.8 1.2-3.1 2.1-7.4 5-11.4 9-25 25-65.6 25-90.5 0-25-25-25-65.6 0-90.5 4-4 6.7-8 8.9-11.3 0.4-0.6 1-1.4 1.4-2 6.3-5.2 10.1-12.6 11.2-20.4l93.6-38.8c11.4 19.9 27.9 36.5 47.8 47.8l-38.9 93.7c-7.8 1.2-15.1 5.1-20.3 11.3zM449.8 625.6c-0.7 3.7-1.7 8.8-1.7 14.5 0 35.3-28.7 64-64 64s-64-28.7-64-64c0-5.7-1-10.7-1.7-14.4-0.1-0.7-0.3-1.6-0.4-2.3 0.7-8.2-1.7-16.2-6.6-22.4l38.8-93.6c10.8 3 22.1 4.5 33.8 4.5s23-1.6 33.8-4.5l38.9 93.7c-4.7 6.2-7.2 14.1-6.5 22.2-0.1 0.8-0.3 1.6-0.4 2.3zM610.5 610.4c-25 25-65.6 25-90.5 0-4-4-8-6.7-11.3-8.9-0.6-0.4-1.4-1-2-1.4-5.3-6.3-12.6-10.2-20.4-11.2l-38.9-93.7c19.9-11.4 36.5-27.9 47.8-47.8l93.8 38.9c1.1 7.8 4.9 15.1 11.2 20.3 0.4 0.6 0.9 1.3 1.2 1.8 2.1 3.1 5 7.4 9 11.4 25 25 25 65.6 0.1 90.6zM640.2 448c-5.7 0-10.7 1-14.4 1.7-0.7 0.1-1.6 0.3-2.3 0.4-8.2-0.7-16.1 1.7-22.4 6.5l-93.7-38.9c3-10.8 4.5-22.1 4.5-33.8s-1.6-23-4.5-33.8l93.7-38.9c6.2 4.8 14.2 7.3 22.3 6.5 0.7 0.1 1.5 0.3 2.2 0.4 3.7 0.7 8.8 1.7 14.5 1.7 35.3 0 64 28.7 64 64 0.1 35.5-28.6 64.2-63.9 64.2z"
|
||||
></path>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.8 KiB |
1
frontend/src/icons/github.svelte
Normal file
@@ -0,0 +1 @@
|
||||
<svg width="100%" height="100%" viewBox="0 0 96 98" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M48.854 0C21.839 0 0 22 0 49.217c0 21.756 13.993 40.172 33.405 46.69 2.427.49 3.316-1.059 3.316-2.362 0-1.141-.08-5.052-.08-9.127-13.59 2.934-16.42-5.867-16.42-5.867-2.184-5.704-5.42-7.17-5.42-7.17-4.448-3.015.324-3.015.324-3.015 4.934.326 7.523 5.052 7.523 5.052 4.367 7.496 11.404 5.378 14.235 4.074.404-3.178 1.699-5.378 3.074-6.6-10.839-1.141-22.243-5.378-22.243-24.283 0-5.378 1.94-9.778 5.014-13.2-.485-1.222-2.184-6.275.486-13.038 0 0 4.125-1.304 13.426 5.052a46.97 46.97 0 0 1 12.214-1.63c4.125 0 8.33.571 12.213 1.63 9.302-6.356 13.427-5.052 13.427-5.052 2.67 6.763.97 11.816.485 13.038 3.155 3.422 5.015 7.822 5.015 13.2 0 18.905-11.404 23.06-22.324 24.283 1.78 1.548 3.316 4.481 3.316 9.126 0 6.6-.08 11.897-.08 13.526 0 1.304.89 2.853 3.316 2.364 19.412-6.52 33.405-24.935 33.405-46.691C97.707 22 75.788 0 48.854 0z" fill="#24292f"/></svg>
|
||||
|
After Width: | Height: | Size: 988 B |
28
frontend/src/icons/lamp-bright.svelte
Normal file
@@ -0,0 +1,28 @@
|
||||
<!-- Generated by IcoMoon.io -->
|
||||
<svg
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="100%"
|
||||
height="100%"
|
||||
viewBox="0 0 768 768"
|
||||
>
|
||||
<g id="icomoon-ignore"> </g>
|
||||
<path
|
||||
d="M542.4 66.6c-42.3-42.8-98.3-66.4-157.7-66.6-0.2 0-0.4 0-0.6 0-59.7 0-115.8 23.2-158.2 65.4-42.5 42.4-65.9 98.7-65.9 158.6 0 99.7 34.7 143.5 62.7 178.7 19.3 24.4 33.3 42 33.3 77.3v96c0 35.3 28.7 64 64 64h128c35.3 0 64-28.7 64-64v-96c0-35.2 14-52.9 33.3-77.2 27.5-34.6 61.8-77.6 62.7-174.7 0.3-30.6-5.5-60.5-17.2-88.7-11.4-27.3-27.6-51.8-48.4-72.8zM544 227.5c-0.7 75-24.1 104.4-48.8 135.4 0 0 0 0 0 0-22.1 27.9-47.2 59.5-47.2 117v96h-128v-96c0-57.5-25.1-89.2-47.2-117.1-25.1-31.5-48.8-61.4-48.8-138.8 0-42.8 16.7-83 47.1-113.2 30.2-30.2 70.3-46.8 112.9-46.8 0.2 0 0.3 0 0.5 0 42.2 0.1 82.1 17 112.3 47.6 30.9 31.2 47.6 72.3 47.2 115.9z"
|
||||
></path>
|
||||
<path d="M288 672h192v32h-192v-32z"></path>
|
||||
<path d="M352 736h64v32h-64v-32z"></path>
|
||||
<path d="M672 224h96v32h-96v-32z"></path>
|
||||
<path
|
||||
d="M634.493 72.858l92.659-46.33 14.311 28.621-92.66 46.33-14.311-28.621z"
|
||||
></path>
|
||||
<path
|
||||
d="M634.494 407.159l14.311-28.621 92.659 46.33-14.311 28.621-92.66-46.33z"
|
||||
></path>
|
||||
<path d="M0 224h96v32h-96v-32z"></path>
|
||||
<path d="M26.512 55.147l14.311-28.621 92.66 46.33-14.311 28.621-92.66-46.33z"
|
||||
></path>
|
||||
<path
|
||||
d="M26.503 424.848l92.659-46.33 14.311 28.621-92.66 46.33-14.311-28.621z"
|
||||
></path>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.4 KiB |
15
frontend/src/icons/lamp.svelte
Normal file
@@ -0,0 +1,15 @@
|
||||
<!-- Generated by IcoMoon.io -->
|
||||
<svg
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="100%"
|
||||
height="100%"
|
||||
viewBox="0 0 768 768"
|
||||
>
|
||||
<g id="icomoon-ignore"> </g>
|
||||
<path
|
||||
d="M590.8 139.4c-11.3-27.3-27.6-51.8-48.4-72.8-42.3-42.8-98.3-66.4-157.7-66.6-0.2 0-0.4 0-0.6 0-59.7 0-115.8 23.2-158.2 65.4-42.5 42.4-65.9 98.7-65.9 158.6 0 99.7 34.7 143.5 62.7 178.7 19.3 24.4 33.3 42 33.3 77.3v96c0 35.3 28.7 64 64 64h128c35.3 0 64-28.7 64-64v-96c0-35.2 14-52.9 33.3-77.2 27.5-34.6 61.8-77.6 62.7-174.7 0.3-30.6-5.5-60.5-17.2-88.7zM544 227.5c-0.7 75-24.1 104.4-48.8 135.4 0 0 0 0 0 0-22.1 27.9-47.2 59.5-47.2 117v96h-128v-96c0-57.5-25.1-89.2-47.2-117.1-25.1-31.5-48.8-61.4-48.8-138.8 0-42.8 16.7-83 47.1-113.2 30.2-30.2 70.3-46.8 112.9-46.8 0.2 0 0.3 0 0.5 0 42.2 0.1 82.1 17 112.3 47.6 30.9 31.2 47.6 72.3 47.2 115.9z"
|
||||
></path>
|
||||
<path d="M288 672h192v32h-192v-32z"></path>
|
||||
<path d="M352 736h64v32h-64v-32z"></path>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 938 B |
14
frontend/src/icons/no-connection.svelte
Normal file
@@ -0,0 +1,14 @@
|
||||
<svg
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="100%"
|
||||
height="100%"
|
||||
viewBox="0 0 768 768"
|
||||
>
|
||||
<g id="icomoon-ignore"> </g>
|
||||
<path
|
||||
d="M704 384h-128v-32h144c26.5 0 48-21.5 48-48 0-7.5-1.8-14.9-5.1-21.5l-128-255.9c-8-16.2-24.8-26.6-42.9-26.6s-34.9 10.4-42.9 26.5l-50.7 101.5h-82.4v-64c0-35.3-28.7-64-64-64h-288c-35.3 0-64 28.7-64 64v160c0 35.3 28.7 64 64 64h42.2l-9.8 58.7c-1.5 9.3 1.1 18.8 7.1 25.9s15 11.3 24.4 11.3h160c9.4 0 18.3-4.1 24.4-11.3s8.7-16.7 7.1-25.9l-9.8-58.7h42.4c35.3 0 64-28.7 64-64v-64h66.4l-61.2 122.5c-3.3 6.6-5.1 14-5.1 21.5 0 26.5 21.5 48 48 48h80v32h-128.1c-35.3 0-64 28.7-64 64v160c0 35.3 28.7 64 64 64h42.2l-9.8 58.7c-1.5 9.3 1.1 18.8 7.1 25.9 6.1 7.2 15 11.3 24.4 11.3h160c9.4 0 18.3-4.1 24.4-11.3s8.7-16.7 7.1-25.9l-9.8-58.7h42.4c35.3 0 64-28.7 64-64v-160c0-35.3-28.7-64-64-64zM255.6 352h-95.1l10.7-64h73.8l10.6 64zM352 224h-288v-160h288v160c0 0 0 0 0 0zM448 304c0-2.5 0.6-4.9 1.6-7l128.1-256.2c2.6-5.3 8.2-8.8 14.3-8.8s11.6 3.5 14.3 8.9l128.1 256.1c1.1 2.1 1.6 4.5 1.6 7 0 8.8-7.2 16-16 16h-256c-8.8 0-16-7.2-16-16zM607.6 736h-95.1l10.7-64h73.8l10.6 64zM704 608h-288v-160h288v160c0 0 0 0 0 0z"
|
||||
></path>
|
||||
<path d="M576 256h32v32h-32v-32z"></path>
|
||||
<path d="M576 96h32v128h-32v-128z"></path>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
16
frontend/src/icons/rubber-duck.svelte
Normal file
@@ -0,0 +1,16 @@
|
||||
<!-- Generated by IcoMoon.io -->
|
||||
<svg
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="100%"
|
||||
height="100%"
|
||||
viewBox="0 0 768 768"
|
||||
>
|
||||
<g id="icomoon-ignore"> </g>
|
||||
<path
|
||||
d="M731.1 164.5c-3.2-3.1-7.5-4.7-11.9-4.5-22.7 1.1-59 0.3-84.8-5-0.4-1.3-0.7-2.5-1.1-3.8-12.7-41.1-39.7-75.6-75.9-97.1-38.1-22.5-82.6-28.2-125.5-16-40 11.4-73 38.5-92.9 76.1-20.7 39.1-24.5 85.8-10.5 128.2 9.1 30.5 24.3 47.2 36.5 60.7 12.6 13.8 18.9 20.8 18.9 43.5 0 21.1-28.1 34.3-55.8 36.5-3.2 0.3-6.5 0.4-9.7 0.4-30.9 0-62.6-11.3-88.3-31.8-36.1-28.7-60.1-74.7-69.3-133-2.1-13.1-12.1-23.6-25.1-26.3s-26.4 2.9-33.5 14.2c-39.7 62.4-62.5 126.8-67.8 191.5-5.1 62.6 7.1 122.9 35.4 174.4 56.8 103.9 171.7 163.5 314.9 163.5 117.2 0 184.8-45 220.9-82.8 41.3-43.3 65-101.2 65-158.9 0-65-31.6-110.4-76.9-110.4-8.3 0-13.7-0.6-17-1.3 0.6-2.6 1.7-6.4 3.8-11.7 4-10.5 10.2-23.2 16.7-36.6 4.2-8.6 8.6-17.7 13-27.3 36.2-10.3 65.2-25.6 86.5-45.5 25.3-23.5 38.9-53.1 39.3-85.4 0.1-4.3-1.7-8.6-4.9-11.6zM593.5 447.9c1.4 0.8 6.5 6 10 19.6 4.2 16.5 4.1 37.2-0.3 58.2-7.1 34.3-44.2 146.3-218.5 146.3-119.2 0-213.5-47.4-259-130.2-36.5-66.4-37.6-149.5-5.1-231.9 16.5 37.4 39.9 68.6 69.5 92 41 32.6 93.1 49 142.9 45.1 67.6-5.3 114.8-46.5 114.8-100.3 0-47.5-19.7-69.2-35.6-86.6-9.9-10.9-17.7-19.5-22.6-36.2-0.1-0.4-0.2-0.7-0.3-1.1-8.7-26.1-6.4-54.7 6.2-78.7 11.7-22.1 30.8-37.9 53.9-44.5 58.1-16.6 108 22.8 122.7 70.4 13.1 42.5-11.1 92.3-32.5 136.2-8.9 18.4-17.4 35.8-22.5 51.7-2.9 9-11.6 36.4 3.2 60 18.7 29.9 59.5 30 73.2 30zM626.1 267.8c8.7-25.1 14.6-52 13.5-79.4 22.5 3.5 46.3 4.1 62.5 4-7 32.2-33.5 58.2-76 75.4z"
|
||||
></path>
|
||||
<path
|
||||
d="M544 192c0-17.6-14.4-32-32-32s-32 14.4-32 32 14.4 32 32 32 32-14.4 32-32zM512 192c0 0 0 0 0 0v0z"
|
||||
></path>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.7 KiB |
33
frontend/src/icons/siren-bright.svelte
Normal file
@@ -0,0 +1,33 @@
|
||||
<!-- Generated by IcoMoon.io -->
|
||||
<svg
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="100%"
|
||||
height="100%"
|
||||
viewBox="0 0 768 768"
|
||||
>
|
||||
<g id="icomoon-ignore"> </g>
|
||||
<path
|
||||
d="M634.493 296.859l92.659-46.33 14.311 28.621-92.659 46.33-14.311-28.621z"
|
||||
></path>
|
||||
<path
|
||||
d="M569.332 176.029l86.62-86.62 22.627 22.627-86.62 86.62-22.628-22.627z"
|
||||
></path>
|
||||
<path
|
||||
d="M443.744 154.11l42.118-126.367 30.358 10.118-42.118 126.367-30.358-10.118z"
|
||||
></path>
|
||||
<path
|
||||
d="M26.506 279.143l14.311-28.621 92.66 46.33-14.311 28.621-92.659-46.33z"
|
||||
></path>
|
||||
<path d="M89.339 111.968l22.627-22.627 86.62 86.62-22.628 22.628-86.62-86.62z"
|
||||
></path>
|
||||
<path
|
||||
d="M251.764 37.886l30.358-10.118 42.118 126.367-30.359 10.118-42.118-126.367z"
|
||||
></path>
|
||||
<path
|
||||
d="M640 576h-5.3l-59.2-325.7c-1.3-7-4.9-13.4-10.2-18.2-40.7-36.2-140.4-40.1-181.3-40.1s-140.6 3.9-181.3 40.1c-5.3 4.8-8.9 11.2-10.2 18.2l-59.2 325.7h-5.3c-35.3 0-64 28.7-64 64v112c0 8.8 7.2 16 16 16h608c8.8 0 16-7.2 16-16v-112c0-35.3-28.7-64-64-64zM253 275.2c6.9-3.3 19.3-7.8 40.4-11.7 25.7-4.8 57.9-7.5 90.6-7.5s64.9 2.6 90.6 7.5c21.1 3.9 33.4 8.4 40.4 11.7l54.7 300.8h-371.4l54.7-300.8zM128 736v-96h512v96h-512z"
|
||||
></path>
|
||||
<path
|
||||
d="M445.174 323.446l31.379-6.275 38.279 191.413-31.379 6.275-38.279-191.413z"
|
||||
></path>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
16
frontend/src/icons/siren.svelte
Normal file
@@ -0,0 +1,16 @@
|
||||
<!-- Generated by IcoMoon.io -->
|
||||
<svg
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="100%"
|
||||
height="100%"
|
||||
viewBox="0 0 768 768"
|
||||
>
|
||||
<g id="icomoon-ignore"> </g>
|
||||
<path
|
||||
d="M640 480h-5.3l-59.2-325.7c-1.3-7-4.9-13.4-10.2-18.2-40.7-36.2-140.4-40.1-181.3-40.1s-140.6 3.9-181.3 40.1c-5.3 4.8-8.9 11.2-10.2 18.2l-59.2 325.7h-5.3c-35.3 0-64 28.7-64 64v112c0 8.8 7.2 16 16 16h608c8.8 0 16-7.2 16-16v-112c0-35.3-28.7-64-64-64zM253 179.2c6.9-3.3 19.3-7.8 40.4-11.7 25.7-4.8 57.9-7.5 90.6-7.5s64.9 2.6 90.6 7.5c21.1 3.9 33.4 8.4 40.4 11.7l54.7 300.8h-371.4l54.7-300.8zM128 640v-96h512v96h-512z"
|
||||
></path>
|
||||
<path
|
||||
d="M445.175 227.444l31.379-6.275 38.279 191.413-31.379 6.275-38.279-191.413z"
|
||||
></path>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 725 B |
22
frontend/src/icons/traffic-lights.svelte
Normal file
@@ -0,0 +1,22 @@
|
||||
<!-- Generated by IcoMoon.io -->
|
||||
<svg
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="100%"
|
||||
height="100%"
|
||||
viewBox="0 0 768 768"
|
||||
>
|
||||
<g id="icomoon-ignore"> </g>
|
||||
<path
|
||||
d="M384 96c-35.3 0-64 28.7-64 64s28.7 64 64 64c35.3 0 64-28.7 64-64s-28.7-64-64-64zM384 192c-17.6 0-32-14.4-32-32s14.4-32 32-32c17.6 0 32 14.4 32 32s-14.4 32-32 32z"
|
||||
></path>
|
||||
<path
|
||||
d="M384 256c-35.3 0-64 28.7-64 64s28.7 64 64 64c35.3 0 64-28.7 64-64s-28.7-64-64-64zM384 352c-17.6 0-32-14.4-32-32s14.4-32 32-32c17.6 0 32 14.4 32 32s-14.4 32-32 32z"
|
||||
></path>
|
||||
<path
|
||||
d="M384 416c-35.3 0-64 28.7-64 64s28.7 64 64 64c35.3 0 64-28.7 64-64s-28.7-64-64-64zM384 512c-17.6 0-32-14.4-32-32s14.4-32 32-32c17.6 0 32 14.4 32 32s-14.4 32-32 32z"
|
||||
></path>
|
||||
<path
|
||||
d="M663.9 157.9c5-2.8 8.1-8.2 8.1-13.9v-32c0-8.8-7.2-16-16-16h-80v-32c0-35.3-28.7-64-64-64h-256c-35.3 0-64 28.7-64 64v32h-80c-8.8 0-16 7.2-16 16v32c0 5.7 3.1 11 8.1 13.9l87.9 50.3v47.8h-80c-8.8 0-16 7.2-16 16v32c0 5.7 3.1 11 8.1 13.9l87.9 50.3v47.8h-80c-8.8 0-16 7.2-16 16v32c0 5.7 3.1 11 8.1 13.9l87.9 50.3v47.8c0 35.3 28.7 64 64 64h32v112c0 8.8 7.2 16 16 16h160c8.8 0 16-7.2 16-16v-112h32c35.3 0 64-28.7 64-64v-47.9l87.9-50.3c5-2.8 8.1-8.2 8.1-13.9v-32c0-8.8-7.2-16-16-16h-80v-47.9l87.9-50.3c5-2.8 8.1-8.2 8.1-13.9v-32c0-8.8-7.2-16-16-16h-80v-47.9l87.9-50zM128 134.7v-6.7h64v43.3l-64-36.6zM128 294.7v-6.7h64v43.3l-64-36.6zM128 454.7v-6.7h64v43.3l-64-36.6zM640 128v6.7l-64 36.6v-43.3h64zM416 736h-64v-96h64v96zM512 576h-256v-512h256v512c0.1 0 0 0 0 0zM640 448v6.7l-64 36.6v-43.3h64zM640 288v6.7l-64 36.6v-43.3h64z"
|
||||
></path>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.6 KiB |
18
frontend/src/icons/warning.svelte
Normal file
@@ -0,0 +1,18 @@
|
||||
<!-- Generated by IcoMoon.io -->
|
||||
<svg
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="100%"
|
||||
height="100%"
|
||||
viewBox="0 0 768 768"
|
||||
>
|
||||
<g id="icomoon-ignore"> </g>
|
||||
<path
|
||||
d="M761.2 675.3l-320-639.9c-10.8-21.8-32.8-35.4-57.2-35.4-24.5 0-46.4 13.6-57.2 35.4l-320 639.9c-4.4 8.8-6.8 18.7-6.8 28.7 0 35.3 28.7 64 64 64h640c35.3 0 64-28.7 64-64 0-10-2.4-19.9-6.8-28.7zM64 704l320-640c0 0 0 0 0 0l320 640h-640zM704 704c0 0 0 0 0 0s0.1 0 0 0c0.1 0 0 0 0 0z"
|
||||
></path>
|
||||
<path
|
||||
d="M369.7 164.1l-242.3 484.7c-2.5 5-2.2 10.8 0.7 15.6 2.9 4.7 8.1 7.6 13.6 7.6h146.3v-32h-120.4l216.4-432.9 216.4 432.9h-120.4v32h146.3c5.5 0 10.7-2.9 13.6-7.6s3.2-10.6 0.7-15.6l-242.3-484.7c-2.7-5.4-8.3-8.8-14.3-8.8-6.1 0-11.6 3.4-14.3 8.8z"
|
||||
></path>
|
||||
<path d="M352 352h64v224h-64v-224z"></path>
|
||||
<path d="M352 608h64v64h-64v-64z"></path>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 845 B |
22
frontend/src/icons/weight-1kg.svelte
Normal file
@@ -0,0 +1,22 @@
|
||||
<!-- Generated by IcoMoon.io -->
|
||||
<svg
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="100%"
|
||||
height="100%"
|
||||
viewBox="0 0 768 768"
|
||||
>
|
||||
<g id="icomoon-ignore"> </g>
|
||||
<path
|
||||
d="M480 192c0-52.9-43.1-96-96-96s-96 43.1-96 96 43.1 96 96 96 96-43.1 96-96zM320 192c0-35.3 28.7-64 64-64s64 28.7 64 64-28.7 64-64 64c-35.3 0-64-28.7-64-64z"
|
||||
></path>
|
||||
<path
|
||||
d="M764 683.5l-118.4-351.9c-8.6-26.1-32.9-43.6-60.6-43.6h-34.7c1.7-2.9 3.3-5.8 4.8-8.8 13.7-26.8 20.9-57 20.9-87.2 0-50.9-19.7-98.8-55.4-134.9s-83.3-56.4-134.1-57.1c-51.3-0.7-99.9 18.8-136.8 55-36.9 36.1-57.4 84.2-57.7 135.5-0.2 30.5 6.9 61 20.6 88.1 1.6 3.2 3.3 6.3 5.1 9.4h-34.7c-27.4 0-51.8 17.5-60.6 43.6l-118.5 351.8c-6.6 19.5-3.4 41.1 8.6 57.8s31.4 26.7 52 26.7h638.9c20.6 0 40-10 52-26.7s15.2-38.3 8.6-57.7zM585 352c0 0 0 0 0 0v0zM64.5 703.9l118.5-352h105c13.8 0 26-8.8 30.4-21.9s-0.1-27.5-11.2-35.7c-32.8-24.6-51.5-62.3-51.2-103.4 0.2-34.1 13.9-66.1 38.5-90.2 24.2-23.7 55.9-36.7 89.4-36.7 0.6 0 1.2 0 1.8 0 69.6 1 126.3 58.4 126.3 128 0 40.7-18.7 78-51.2 102.4-11 8.3-15.5 22.7-11.1 35.7s16.5 21.9 30.3 21.9h104.9l118.5 351.9h-638.9z"
|
||||
></path>
|
||||
<path
|
||||
d="M358.6 494.6l-24-21.2-46.6 52.7v-110.1h-32v192h32v-33.5l3.7-4.2 44.3 44.3 22.6-22.6-45.7-45.7z"
|
||||
></path>
|
||||
<path
|
||||
d="M480 488.6c-9.4-5.5-20.4-8.6-32-8.6-35.3 0-64 28.7-64 64s28.7 64 64 64c11.6 0 22.6-3.1 32-8.6v8.6c0 17.6-14.4 32-32 32h-64v32h64c35.3 0 64-28.7 64-64v-128h-32v8.6zM448 576c-17.6 0-32-14.4-32-32s14.4-32 32-32 32 14.4 32 32-14.4 32-32 32z"
|
||||
></path>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
7
frontend/src/main.js
Normal file
@@ -0,0 +1,7 @@
|
||||
import App from "./App.svelte";
|
||||
|
||||
const app = new App({
|
||||
target: document.getElementById("app"),
|
||||
});
|
||||
|
||||
export default app;
|
||||
39
frontend/src/utils/actions.js
Normal file
@@ -0,0 +1,39 @@
|
||||
export function sleep(hundredSeconds) {
|
||||
return new Promise((resolve) => setTimeout(resolve, hundredSeconds * 100));
|
||||
}
|
||||
|
||||
export const errorSeq = [
|
||||
[0, 0, 1, 1],
|
||||
[0, 0, 0, 1],
|
||||
[0, 0, 1, 1],
|
||||
[0, 0, 0, 1],
|
||||
[0, 0, 1, 1],
|
||||
[0, 0, 0, 6],
|
||||
[0, 0, 1, 2],
|
||||
[0, 0, 0, 2],
|
||||
[0, 0, 1, 2],
|
||||
[0, 0, 0, 2],
|
||||
[0, 0, 1, 2],
|
||||
[0, 0, 0, 6],
|
||||
[0, 0, 1, 1],
|
||||
[0, 0, 0, 1],
|
||||
[0, 0, 1, 1],
|
||||
[0, 0, 0, 1],
|
||||
[0, 0, 1, 1],
|
||||
[0, 0, 0, 20],
|
||||
];
|
||||
|
||||
export const trafficSeq = [
|
||||
[0, 0, 1, 15],
|
||||
[0, 1, 1, 15],
|
||||
[1, 0, 0, 50],
|
||||
[0, 1, 0, 15],
|
||||
[0, 0, 1, 20],
|
||||
];
|
||||
|
||||
export const warningSeq = [
|
||||
[0, 1, 0, 3],
|
||||
[0, 0, 0, 3],
|
||||
[0, 1, 0, 3],
|
||||
[0, 0, 0, 10],
|
||||
];
|
||||
32
frontend/src/utils/tower.js
Normal file
@@ -0,0 +1,32 @@
|
||||
let BASE_URL, BASE_PATH;
|
||||
|
||||
export function setupApi(url, path) {
|
||||
BASE_URL = url;
|
||||
BASE_PATH = path;
|
||||
}
|
||||
|
||||
export async function getState() {
|
||||
const url = `${BASE_URL}${BASE_PATH}state`;
|
||||
|
||||
return fetch(url).then((resp) => resp.json());
|
||||
}
|
||||
|
||||
export async function toggle(color) {
|
||||
const url = `${BASE_URL}${BASE_PATH}toggle/${color}`;
|
||||
const options = { method: "POST" };
|
||||
|
||||
return fetch(url, options);
|
||||
}
|
||||
|
||||
export async function setTower(colorStates) {
|
||||
const url = `${BASE_URL}${BASE_PATH}state/set`;
|
||||
const options = {
|
||||
method: "POST",
|
||||
header: {
|
||||
"Content-Type": "plain/text",
|
||||
},
|
||||
body: colorStates.join(","),
|
||||
};
|
||||
|
||||
return fetch(url, options);
|
||||
}
|
||||