v1.0.9 changes from 1.1.1
24
src/svelte-components/.gitignore
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
lerna-debug.log*
|
||||
|
||||
node_modules
|
||||
dist
|
||||
dist-ssr
|
||||
*.local
|
||||
|
||||
# Editor directories and files
|
||||
.vscode/*
|
||||
!.vscode/extensions.json
|
||||
.idea
|
||||
.DS_Store
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
48
src/svelte-components/README.md
Normal file
@@ -0,0 +1,48 @@
|
||||
# Svelte + TS + Vite
|
||||
|
||||
This template should help get you started developing with Svelte and TypeScript in Vite.
|
||||
|
||||
## Recommended IDE Setup
|
||||
|
||||
[VS Code](https://code.visualstudio.com/) + [Svelte](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode).
|
||||
|
||||
## Need an official Svelte framework?
|
||||
|
||||
Check out [SvelteKit](https://github.com/sveltejs/kit#readme), which is also powered by Vite. Deploy anywhere with its serverless-first approach and adapt to various platforms, with out of the box support for TypeScript, SCSS, and Less, and easily-added support for mdsvex, GraphQL, PostCSS, Tailwind CSS, and more.
|
||||
|
||||
## Technical considerations
|
||||
|
||||
**Why use this over SvelteKit?**
|
||||
|
||||
- It brings its own routing solution which might not be preferable for some users.
|
||||
- It is first and foremost a framework that just happens to use Vite under the hood, not a Vite app.
|
||||
`vite dev` and `vite build` wouldn't work in a SvelteKit environment, for example.
|
||||
|
||||
This template contains as little as possible to get started with Vite + TypeScript + Svelte, while taking into account the developer experience with regards to HMR and intellisense. It demonstrates capabilities on par with the other `create-vite` templates and is a good starting point for beginners dipping their toes into a Vite + Svelte project.
|
||||
|
||||
Should you later need the extended capabilities and extensibility provided by SvelteKit, the template has been structured similarly to SvelteKit so that it is easy to migrate.
|
||||
|
||||
**Why `global.d.ts` instead of `compilerOptions.types` inside `jsconfig.json` or `tsconfig.json`?**
|
||||
|
||||
Setting `compilerOptions.types` shuts out all other types not explicitly listed in the configuration. Using triple-slash references keeps the default TypeScript setting of accepting type information from the entire workspace, while also adding `svelte` and `vite/client` type information.
|
||||
|
||||
**Why include `.vscode/extensions.json`?**
|
||||
|
||||
Other templates indirectly recommend extensions via the README, but this file allows VS Code to prompt the user to install the recommended extension upon opening the project.
|
||||
|
||||
**Why enable `allowJs` in the TS template?**
|
||||
|
||||
While `allowJs: false` would indeed prevent the use of `.js` files in the project, it does not prevent the use of JavaScript syntax in `.svelte` files. In addition, it would force `checkJs: false`, bringing the worst of both worlds: not being able to guarantee the entire codebase is TypeScript, and also having worse typechecking for the existing JavaScript. In addition, there are valid use cases in which a mixed codebase may be relevant.
|
||||
|
||||
**Why is HMR not preserving my local component state?**
|
||||
|
||||
HMR state preservation comes with a number of gotchas! It has been disabled by default in both `svelte-hmr` and `@sveltejs/vite-plugin-svelte` due to its often surprising behavior. You can read the details [here](https://github.com/rixo/svelte-hmr#svelte-hmr).
|
||||
|
||||
If you have state that's important to retain within a component, consider creating an external store which would not be replaced by HMR.
|
||||
|
||||
```ts
|
||||
// store.ts
|
||||
// An extremely simple external store
|
||||
import { writable } from 'svelte/store'
|
||||
export default writable(0)
|
||||
```
|
||||
13
src/svelte-components/index.html
Normal file
@@ -0,0 +1,13 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Svelte + TS + Vite App</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<script type="module" src="/src/main.ts"></script>
|
||||
</body>
|
||||
</html>
|
||||
10382
src/svelte-components/package-lock.json
generated
Normal file
31
src/svelte-components/package.json
Normal file
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"name": "svelte-components",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "vite build",
|
||||
"postbuild": "smui-theme compile dist/smui.css -i src/theme",
|
||||
"preview": "vite preview",
|
||||
"check": "svelte-check --tsconfig ./tsconfig.json"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@sveltejs/kit": "^1.0.0-next.392",
|
||||
"@sveltejs/vite-plugin-svelte": "^1.0.1",
|
||||
"@tsconfig/svelte": "^3.0.0",
|
||||
"node-sass": "^7.0.1",
|
||||
"polyfill-object.fromentries": "^1.0.1",
|
||||
"smui-theme": "^6.0.0-beta.16",
|
||||
"string.prototype.matchall": "^4.0.7",
|
||||
"svelte": "^3.49.0",
|
||||
"svelte-check": "^2.8.0",
|
||||
"svelte-icon": "^1.2.4",
|
||||
"svelte-material-ui": "^6.0.0-beta.16",
|
||||
"svelte-preprocess": "^4.10.7",
|
||||
"svelte-tiny-virtual-list": "^2.0.5",
|
||||
"tslib": "^2.4.0",
|
||||
"typescript": "^4.7.4",
|
||||
"vite": "^3.0.2"
|
||||
}
|
||||
}
|
||||
BIN
src/svelte-components/public/favicon.ico
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
215
src/svelte-components/src/components/AdminNetworkView.svelte
Normal file
@@ -0,0 +1,215 @@
|
||||
<script lang="ts">
|
||||
import WifiConnectionDialog from "$dialogs/WifiConnectionDialog.svelte";
|
||||
import ChangeHostnameDialog from "$dialogs/ChangeHostnameDialog.svelte";
|
||||
import Button, { Label } from "@smui/button";
|
||||
import List, { Item, Graphic, Text, Meta } from "@smui/list";
|
||||
import Card from "@smui/card";
|
||||
import { networkInfo, type WifiNetwork } from "$lib/NetworkInfo";
|
||||
import {GET} from "$lib/api"
|
||||
import {processNetworkInfo} from "$lib/NetworkInfo"
|
||||
|
||||
let networkData = GET("network")
|
||||
networkData.then(value=>processNetworkInfo(value))
|
||||
|
||||
let changeHostnameDialog = {
|
||||
open: false,
|
||||
};
|
||||
|
||||
let wifiConnectionDialog = {
|
||||
open: false,
|
||||
network: {} as WifiNetwork,
|
||||
};
|
||||
|
||||
function getWifiStrengthStyle(network: WifiNetwork) {
|
||||
const strength = Math.ceil((Number(network.Quality) / 100) * 4);
|
||||
|
||||
switch (strength) {
|
||||
case 0:
|
||||
return "clip-path: circle(0px at 12.5px 19px);";
|
||||
|
||||
case 1:
|
||||
return "clip-path: circle(4px at 12.5px 19px);";
|
||||
|
||||
case 2:
|
||||
return "clip-path: circle(8px at 12.5px 19px);";
|
||||
|
||||
case 3:
|
||||
return "clip-path: circle(14px at 12.5px 19px);";
|
||||
|
||||
case 4:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
function onChangeHostname() {
|
||||
changeHostnameDialog = {
|
||||
open: true,
|
||||
};
|
||||
}
|
||||
|
||||
function onNetworkSelected(network: WifiNetwork) {
|
||||
wifiConnectionDialog = {
|
||||
open: true,
|
||||
network,
|
||||
};
|
||||
}
|
||||
</script>
|
||||
|
||||
<WifiConnectionDialog {...wifiConnectionDialog} />
|
||||
<ChangeHostnameDialog {...changeHostnameDialog} />
|
||||
|
||||
<div class="admin-network-view">
|
||||
<h1>Network Info</h1>
|
||||
|
||||
<div class="pure-form pure-form-aligned">
|
||||
<div class="pure-control-group">
|
||||
<label for="hostname">Hostname</label>
|
||||
<Card id="hostname" variant="outlined">
|
||||
<Text id="hostname">
|
||||
{$networkInfo.hostname}
|
||||
</Text>
|
||||
</Card>
|
||||
<Button on:click={onChangeHostname} touch variant="raised">
|
||||
<Label>Change</Label>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="pure-form pure-form-aligned">
|
||||
<div class="pure-control-group">
|
||||
<label for="ip-addresses">IP Addresses</label>
|
||||
<Card id="ip-addresses" variant="outlined">
|
||||
{#each $networkInfo.ipAddresses as ipAddress}
|
||||
<div>
|
||||
<Text id="hostname">
|
||||
{ipAddress}
|
||||
</Text>
|
||||
</div>
|
||||
{/each}
|
||||
</Card>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="pure-form pure-form-aligned">
|
||||
<div class="pure-control-group">
|
||||
<label for="wifi">Wi-Fi</label>
|
||||
<div class="wifi-networks">
|
||||
<Card id="wifi" variant="outlined">
|
||||
<List>
|
||||
{#if $networkInfo.wifi.networks.length === 0}
|
||||
<Item class="wifi-network">
|
||||
<Text>Scanning...</Text>
|
||||
</Item>
|
||||
{:else}
|
||||
{#each $networkInfo.wifi.networks as network}
|
||||
<Item
|
||||
class="wifi-network"
|
||||
on:SMUI:action={() =>
|
||||
onNetworkSelected(network)}
|
||||
>
|
||||
<Graphic
|
||||
class="strength {$networkInfo.wifi
|
||||
.ssid === network.Name
|
||||
? 'active'
|
||||
: ''}"
|
||||
>
|
||||
<span class="fa fa-wifi background" />
|
||||
<span
|
||||
class="fa fa-wifi"
|
||||
style={getWifiStrengthStyle(
|
||||
network
|
||||
)}
|
||||
/>
|
||||
</Graphic>
|
||||
<Text style="margin-right: 20px;"
|
||||
>{network.Name}</Text
|
||||
>
|
||||
{#if network.Encryption !== "Open"}
|
||||
<Meta>
|
||||
<span class="fa fa-lock" />
|
||||
</Meta>
|
||||
{/if}
|
||||
</Item>
|
||||
{/each}
|
||||
{/if}
|
||||
</List>
|
||||
</Card>
|
||||
<em style="display: block;">
|
||||
Click on a Wi-Fi network to connect or disconnect.
|
||||
</em>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style lang="scss">
|
||||
$primary: #0078e7;
|
||||
$very-dark: #555;
|
||||
$text: #777;
|
||||
$grey: #bbb;
|
||||
$light: #ddd;
|
||||
|
||||
:global {
|
||||
.admin-network-view {
|
||||
.pure-form-aligned .pure-control-group label {
|
||||
vertical-align: top;
|
||||
font-size: 15pt;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
button {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.mdc-card {
|
||||
width: 400px;
|
||||
min-height: 38px;
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
margin-bottom: 20px;
|
||||
margin-right: 20px;
|
||||
padding: 5px 15px;
|
||||
}
|
||||
|
||||
.wifi-networks {
|
||||
display: inline-block;
|
||||
|
||||
.mdc-card {
|
||||
padding: 0;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.wifi-network {
|
||||
.lock {
|
||||
font-size: 20px;
|
||||
vertical-align: text-bottom;
|
||||
}
|
||||
|
||||
.strength {
|
||||
border-radius: 50%;
|
||||
padding: 3px;
|
||||
background-color: $light;
|
||||
color: $very-dark;
|
||||
margin-right: 10px;
|
||||
position: relative;
|
||||
|
||||
&.active {
|
||||
background-color: $primary;
|
||||
color: white;
|
||||
}
|
||||
|
||||
span {
|
||||
position: absolute;
|
||||
top: 5px;
|
||||
font-size: 22px;
|
||||
|
||||
&.background {
|
||||
opacity: 0.25;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
196
src/svelte-components/src/components/ConfigTemplatedInput.svelte
Normal file
@@ -0,0 +1,196 @@
|
||||
<script lang="ts">
|
||||
import configTemplate from "../../../resources/config-template.json";
|
||||
import { Config, DisplayUnits } from "$lib/ConfigStore";
|
||||
import { ControllerMethods } from "$lib/RegisterControllerMethods";
|
||||
import { onMount } from "svelte";
|
||||
|
||||
type ValueType =
|
||||
| string
|
||||
| number
|
||||
| { title: string; value: string | number };
|
||||
|
||||
type Template = {
|
||||
type?: string;
|
||||
values?: Array<ValueType>;
|
||||
unit?: "string";
|
||||
iunit?: "string";
|
||||
min?: number;
|
||||
max?: number;
|
||||
step?: number;
|
||||
help?: string;
|
||||
default?: string | number;
|
||||
scale?: number;
|
||||
};
|
||||
|
||||
const namesByKey = {
|
||||
"gamepad-default-type": "Default type",
|
||||
"probing-prompts": "Show safety prompts",
|
||||
"probe-xdim": "Probe block width",
|
||||
"probe-ydim": "Probe block length",
|
||||
"probe-zdim": "Probe block height",
|
||||
"probe-fast-seek": "Fast seek speed",
|
||||
"probe-slow-seek": "Slow seek speed",
|
||||
"program-start": "On program start",
|
||||
"tool-change": "On tool change",
|
||||
"program-end": "On program end",
|
||||
"max-deviation": "Maximum deviation",
|
||||
"junction-accel": "Junction acceleration",
|
||||
};
|
||||
|
||||
export let key: string;
|
||||
let keyParts: string[];
|
||||
let template: Template;
|
||||
let name: string;
|
||||
let title: string;
|
||||
let units: string;
|
||||
let value;
|
||||
|
||||
onMount(() => {
|
||||
keyParts = (key || "").split(".");
|
||||
template = getTemplate();
|
||||
|
||||
name = keyParts[keyParts.length - 1];
|
||||
name = namesByKey[name] || name;
|
||||
title = getTitle();
|
||||
value = getValue();
|
||||
});
|
||||
|
||||
$: metric = $DisplayUnits === "METRIC";
|
||||
$: if (template) {
|
||||
units = metric || !template.iunit ? template.unit : template.iunit;
|
||||
}
|
||||
|
||||
function getTemplate(): Template {
|
||||
let template = configTemplate;
|
||||
for (const part of keyParts) {
|
||||
template = template[part];
|
||||
}
|
||||
|
||||
return template as Template;
|
||||
}
|
||||
|
||||
function getTitle(): string {
|
||||
const help = template.help ? `${template.help}\n` : "";
|
||||
return `${help}Default: ${template.default} ${template.unit || ""}`;
|
||||
}
|
||||
|
||||
function getValue(): string | number {
|
||||
let value: any = $Config;
|
||||
for (const part of keyParts) {
|
||||
value = value[part];
|
||||
}
|
||||
|
||||
if (template.scale) {
|
||||
if (metric) {
|
||||
return Number.parseFloat(value.toFixed(3));
|
||||
}
|
||||
|
||||
return Number.parseFloat((value / template.scale).toFixed(4));
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
function onChange(event) {
|
||||
Config.update((config) => {
|
||||
let target = config;
|
||||
for (const part of keyParts.slice(0, -1)) {
|
||||
target = target[part];
|
||||
}
|
||||
|
||||
const value = getValueFromElement(event.target);
|
||||
target[keyParts[keyParts.length - 1]] = value;
|
||||
|
||||
return config;
|
||||
});
|
||||
|
||||
ControllerMethods.dispatch("config-changed");
|
||||
}
|
||||
|
||||
function getValueFromElement(element) {
|
||||
switch (template.type) {
|
||||
case "float":
|
||||
case "int":
|
||||
return Number(element.value);
|
||||
|
||||
case "bool":
|
||||
return element.checked;
|
||||
|
||||
default:
|
||||
return element.value;
|
||||
}
|
||||
}
|
||||
|
||||
function getOptionValue(opt: ValueType) {
|
||||
switch (typeof opt) {
|
||||
case "object":
|
||||
return opt.value || opt;
|
||||
|
||||
default:
|
||||
return opt;
|
||||
}
|
||||
}
|
||||
|
||||
function getOptionTitle(opt: ValueType) {
|
||||
switch (typeof opt) {
|
||||
case "object":
|
||||
return opt.title || opt;
|
||||
|
||||
default:
|
||||
return opt;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
{#if template}
|
||||
<div class="pure-control-group" {title}>
|
||||
<label for={name}>{name}</label>
|
||||
|
||||
{#if template.values}
|
||||
<select {name} bind:value on:change={onChange}>
|
||||
{#each template.values as opt}
|
||||
<option
|
||||
value={getOptionValue(opt)}
|
||||
disabled={opt === "-----"}
|
||||
>
|
||||
{getOptionTitle(opt)}
|
||||
</option>
|
||||
{/each}
|
||||
</select>
|
||||
{:else if template.type === "bool"}
|
||||
<input
|
||||
{name}
|
||||
type="checkbox"
|
||||
checked={value}
|
||||
on:change={onChange}
|
||||
/>
|
||||
{:else if template.type === "float"}
|
||||
<input
|
||||
{name}
|
||||
type="number"
|
||||
min={template.min}
|
||||
max={template.max}
|
||||
step={template.step || "any"}
|
||||
bind:value
|
||||
on:keyup={onChange}
|
||||
/>
|
||||
{:else if template.type === "int"}
|
||||
<input
|
||||
{name}
|
||||
type="number"
|
||||
min={template.min}
|
||||
max={template.max}
|
||||
bind:value
|
||||
on:keyup={onChange}
|
||||
/>
|
||||
{:else if template.type === "string"}
|
||||
<input {name} type="text" bind:value on:keyup={onChange} />
|
||||
{:else if template.type == "text"}
|
||||
<textarea {name} bind:value on:keyup={onChange} />
|
||||
{/if}
|
||||
|
||||
<label for="" class="units">{units || ""}</label>
|
||||
|
||||
<slot name="extra" />
|
||||
</div>
|
||||
{/if}
|
||||
62
src/svelte-components/src/components/HelpView.svelte
Normal file
@@ -0,0 +1,62 @@
|
||||
<script lang="ts">
|
||||
import RemoteDiagnosticsDialog from "$dialogs/RemoteDiagnosticsDialog.svelte";
|
||||
import Button, { Label } from "@smui/button";
|
||||
|
||||
let showRemoteDiagnosticsDialog = false;
|
||||
</script>
|
||||
|
||||
<RemoteDiagnosticsDialog bind:open={showRemoteDiagnosticsDialog} />
|
||||
|
||||
<h2>Support & Contact Info</h2>
|
||||
<p>
|
||||
Please visit
|
||||
<a href="https://onefinitycnc.com/support" target="_blank">
|
||||
onefinitycnc.com/support
|
||||
</a>
|
||||
for a variety of support resources, and to find our contact information.
|
||||
</p>
|
||||
|
||||
<Button
|
||||
touch
|
||||
variant="raised"
|
||||
on:click={() => (showRemoteDiagnosticsDialog = true)}
|
||||
>
|
||||
<Label>Remote Diagnostics</Label>
|
||||
</Button>
|
||||
|
||||
<h2>Discussion Forum</h2>
|
||||
<p>
|
||||
Check out our support and discussion forum at
|
||||
<a href="https://forum.onefinitycnc.com" target="_blank"
|
||||
>forum.onefinitycnc.com</a
|
||||
>. Register on the site and post a message. We can't wait to hear from you.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
We also maintain a list of
|
||||
<a
|
||||
href="https://forum.onefinitycnc.com/t/what-cad-cam-software-can-be-used-to-make-gcode-files-for-the-onefinity-cnc/10253"
|
||||
target="_blank"
|
||||
>
|
||||
recommended software packages
|
||||
</a>
|
||||
on the forum.
|
||||
</p>
|
||||
|
||||
<h2>Credits & Acknowledgements</h2>
|
||||
<h4 style="margin-bottom: 0;">Artwork</h4>
|
||||
<p style="margin-top: 0;">
|
||||
Special thanks to
|
||||
<a href="https://www.instagram.com/fierysquirrelart/" target="_blank">
|
||||
@fierysquirrelart
|
||||
</a>
|
||||
for many of the graphics used in the controller.
|
||||
</p>
|
||||
|
||||
<h4 style="margin-bottom: 0;">Buildbotics</h4>
|
||||
<p style="margin-top: 0;">
|
||||
This controller is based on the
|
||||
<a href="http://buildbotics.com" target="_blank"
|
||||
>Buildbotics CNC Controller</a
|
||||
>.
|
||||
</p>
|
||||
129
src/svelte-components/src/components/SettingsView.svelte
Normal file
@@ -0,0 +1,129 @@
|
||||
<script lang="ts">
|
||||
import configTemplate from "../../../resources/config-template.json";
|
||||
import ScreenRotationDialog from "$dialogs/ScreenRotationDialog.svelte";
|
||||
import ConfigTemplatedInput from "./ConfigTemplatedInput.svelte";
|
||||
import SetTimeDialog from "$dialogs/SetTimeDialog.svelte";
|
||||
import Button, { Label } from "@smui/button";
|
||||
|
||||
const gcodeURL = "https://linuxcnc.org/docs/html/gcode/g-code.html";
|
||||
|
||||
let showScreenRotationDialog = false;
|
||||
let showSetTimeDialog = false;
|
||||
</script>
|
||||
|
||||
<ScreenRotationDialog bind:open={showScreenRotationDialog} />
|
||||
<SetTimeDialog bind:open={showSetTimeDialog} />
|
||||
|
||||
<div class="settings-view">
|
||||
<h1>Settings</h1>
|
||||
|
||||
<div class="pure-form pure-form-aligned">
|
||||
<h2>User Interface</h2>
|
||||
<fieldset>
|
||||
<div class="pure-control-group">
|
||||
<label for="screen-rotation" />
|
||||
<Button
|
||||
name="screen-rotation"
|
||||
touch
|
||||
variant="raised"
|
||||
on:click={() => (showScreenRotationDialog = true)}
|
||||
>
|
||||
<Label>Change Screen Rotation</Label>
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<div class="pure-control-group">
|
||||
<label for="set-time" />
|
||||
<Button
|
||||
name="set-time"
|
||||
touch
|
||||
variant="raised"
|
||||
on:click={() => (showSetTimeDialog = true)}
|
||||
>
|
||||
<Label>Change Time & Timezone</Label>
|
||||
</Button>
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
<h2>Gamepads / Joypads</h2>
|
||||
<fieldset>
|
||||
<ConfigTemplatedInput key={`settings.gamepad-default-type`} />
|
||||
<div class="tip">
|
||||
If your gamepad doesn't work as expected, try one of the other
|
||||
types.
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
<h2>Probing</h2>
|
||||
<fieldset>
|
||||
<ConfigTemplatedInput key={`settings.probing-prompts`} />
|
||||
<div class="tip">
|
||||
Onefinity highly recommends that you keep the safety prompts
|
||||
enabled. If you choose to live dangerously, and disable the
|
||||
safety prompts, Onefinity cannot be held responsible.
|
||||
</div>
|
||||
|
||||
<br />
|
||||
|
||||
{#each Object.keys(configTemplate.probe) as key}
|
||||
{#if key !== "probe-diameter"}
|
||||
<ConfigTemplatedInput key={`probe.${key}`} />
|
||||
{/if}
|
||||
{/each}
|
||||
</fieldset>
|
||||
|
||||
<fieldset>
|
||||
<h2>GCode</h2>
|
||||
{#each Object.keys(configTemplate.gcode) as key}
|
||||
<ConfigTemplatedInput key={`gcode.${key}`} />
|
||||
{/each}
|
||||
</fieldset>
|
||||
|
||||
<h2>Path Accuracy</h2>
|
||||
<fieldset>
|
||||
<ConfigTemplatedInput key={`settings.max-deviation`} />
|
||||
|
||||
<div class="tip">
|
||||
Lower the maximum deviation to follow the programmed path more
|
||||
precisely but at a slower speed.
|
||||
</div>
|
||||
|
||||
<div class="tip">
|
||||
In order to improve traversal speed, the path planner may merge
|
||||
consecutive moves or round off sharp corners if doing so would
|
||||
deviate from the program path by less than the maximum
|
||||
deviation.
|
||||
</div>
|
||||
|
||||
<div class="tip">
|
||||
GCode commands
|
||||
<a href={`${gcodeURL}#gcode:g61`} target="_blank">G61, G61.1</a>
|
||||
and <a href={`${gcodeURL}#gcode:g64`} target="_blank">G64</a> also
|
||||
affect path planning accuracy.
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
<h2>Cornering Speed (Advanced)</h2>
|
||||
<fieldset>
|
||||
<ConfigTemplatedInput key={`settings.junction-accel`} />
|
||||
<div class="tip">
|
||||
Junction acceleration limits the cornering speed the planner
|
||||
will allow. Increasing this value will allow for faster
|
||||
traversal of corners but may cause the planner to violate axis
|
||||
jerk limits and stall the motors. Use with caution.
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style lang="scss">
|
||||
.settings-view {
|
||||
.tip {
|
||||
margin-left: 210px;
|
||||
margin-bottom: 15px;
|
||||
font-style: italic;
|
||||
font-size: 90%;
|
||||
line-height: 1.5;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,90 @@
|
||||
<script lang="ts">
|
||||
import TextField from "@smui/textfield";
|
||||
import Icon from "@smui/textfield/icon";
|
||||
import HelperText from "@smui/textfield/helper-text";
|
||||
import MenuSurface, {
|
||||
type MenuSurfaceComponentDev,
|
||||
} from "@smui/menu-surface";
|
||||
import List, { Item, Text } from "@smui/list";
|
||||
import { virtualKeyboardChange } from "$lib/CustomActions";
|
||||
import { onDestroy } from "svelte";
|
||||
|
||||
let menuSurface: MenuSurfaceComponentDev;
|
||||
let menuTimeout;
|
||||
let optionSelected: boolean = false;
|
||||
|
||||
export let value: string;
|
||||
export let options: string[][];
|
||||
export let valid: boolean;
|
||||
export let helperText: string;
|
||||
|
||||
onDestroy(() => {
|
||||
if (menuTimeout) {
|
||||
clearTimeout(menuTimeout);
|
||||
menuTimeout = undefined;
|
||||
}
|
||||
});
|
||||
|
||||
function showMenu(show: boolean) {
|
||||
if (show && optionSelected) {
|
||||
return;
|
||||
}
|
||||
|
||||
optionSelected = false;
|
||||
|
||||
if (menuTimeout) {
|
||||
clearTimeout(menuTimeout);
|
||||
}
|
||||
|
||||
// Use a timeout to "debounce" the display of the menu.
|
||||
menuTimeout = setTimeout(() => menuSurface.setOpen(show), 100);
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="textfield-with-options">
|
||||
<TextField
|
||||
bind:value
|
||||
on:focusin={() => showMenu(true)}
|
||||
on:focusout={() => showMenu(false)}
|
||||
use={[virtualKeyboardChange((v) => (value = v))]}
|
||||
{...$$restProps}
|
||||
>
|
||||
<div slot="trailingIcon">
|
||||
{#if valid}
|
||||
<Icon class="fa fa-check-circle-o" style="color: green;" />
|
||||
{/if}
|
||||
</div>
|
||||
<HelperText persistent slot="helper">{helperText}</HelperText>
|
||||
</TextField>
|
||||
|
||||
<MenuSurface bind:this={menuSurface} anchorCorner="BOTTOM_LEFT">
|
||||
<div style="display: flex; flex-direction: row;">
|
||||
{#each options as group}
|
||||
<List>
|
||||
{#each group as option}
|
||||
<Item
|
||||
on:SMUI:action={() => {
|
||||
value = option;
|
||||
showMenu(false);
|
||||
|
||||
optionSelected = true;
|
||||
}}
|
||||
>
|
||||
<Text>{option}</Text>
|
||||
</Item>
|
||||
{/each}
|
||||
</List>
|
||||
{/each}
|
||||
</div>
|
||||
</MenuSurface>
|
||||
</div>
|
||||
|
||||
<style lang="scss">
|
||||
:global {
|
||||
.textfield-with-options {
|
||||
.mdc-deprecated-list-item {
|
||||
height: 32px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
101
src/svelte-components/src/dialogs/ChangeHostnameDialog.svelte
Normal file
@@ -0,0 +1,101 @@
|
||||
<script lang="ts">
|
||||
import Dialog, {
|
||||
Title,
|
||||
Content,
|
||||
Actions,
|
||||
InitialFocus,
|
||||
} from "@smui/dialog";
|
||||
import Button, { Label } from "@smui/button";
|
||||
import TextField from "@smui/textfield";
|
||||
import MessageDialog from "$dialogs/MessageDialog.svelte";
|
||||
import * as api from "$lib/api";
|
||||
import { virtualKeyboardChange } from "$lib/CustomActions";
|
||||
|
||||
// https://man7.org/linux/man-pages/man7/hostname.7.html
|
||||
//
|
||||
// Each element of the hostname must be from 1 to 63 characters long
|
||||
// and the entire hostname, including the dots, can be at most 253
|
||||
// characters long. Valid characters for hostnames are ASCII(7)
|
||||
// letters from a to z, the digits from 0 to 9, and the hyphen (-).
|
||||
// A hostname may not start with a hyphen.
|
||||
|
||||
const pattern = /[a-zA-Z0-9][a-zA-Z0-9-]{0,62}/;
|
||||
|
||||
export let open = false;
|
||||
|
||||
let rebooting = false;
|
||||
let redirectTimeout = 45;
|
||||
let hostname = "";
|
||||
|
||||
$: setTimeout(() => {
|
||||
hostname = (hostname.match(pattern) || [""])[0].toLowerCase();
|
||||
}, 0);
|
||||
|
||||
$: if (open) {
|
||||
hostname = "";
|
||||
}
|
||||
|
||||
async function onConfirm() {
|
||||
rebooting = true;
|
||||
await api.PUT("hostname", { hostname });
|
||||
await api.PUT("reboot");
|
||||
|
||||
const interval = setInterval(() => {
|
||||
if (0 < redirectTimeout) {
|
||||
redirectTimeout -= 1;
|
||||
} else {
|
||||
clearInterval(interval);
|
||||
location.hostname = getRedirectTarget();
|
||||
}
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
function getRedirectTarget() {
|
||||
if (location.hostname.endsWith(".local")) {
|
||||
return `${hostname}.local`;
|
||||
}
|
||||
|
||||
if (location.hostname.endsWith(".lan")) {
|
||||
return `${hostname}.lan`;
|
||||
}
|
||||
|
||||
return hostname;
|
||||
}
|
||||
</script>
|
||||
|
||||
<MessageDialog open={rebooting} title="Rebooting" noaction>
|
||||
Rebooting to apply the hostname change...
|
||||
</MessageDialog>
|
||||
|
||||
<Dialog
|
||||
bind:open
|
||||
scrimClickAction=""
|
||||
aria-labelledby="change-hostname-dialog-title"
|
||||
aria-describedby="change-hostname-dialog-content"
|
||||
>
|
||||
<Title id="change-hostname-dialog-title">Change Hostname</Title>
|
||||
|
||||
<Content id="change-hostname-dialog-content">
|
||||
<TextField
|
||||
bind:value={hostname}
|
||||
use={[InitialFocus, virtualKeyboardChange((v) => (hostname = v))]}
|
||||
label="New Hostname"
|
||||
spellcheck="false"
|
||||
variant="filled"
|
||||
style="width: 100%;"
|
||||
/>
|
||||
</Content>
|
||||
|
||||
<Actions>
|
||||
<Button>
|
||||
<Label>Cancel</Label>
|
||||
</Button>
|
||||
<Button
|
||||
defaultAction
|
||||
on:click={onConfirm}
|
||||
disabled={hostname.length === 0}
|
||||
>
|
||||
<Label>Confirm & Reboot</Label>
|
||||
</Button>
|
||||
</Actions>
|
||||
</Dialog>
|
||||
244
src/svelte-components/src/dialogs/DialogHost.svelte
Normal file
@@ -0,0 +1,244 @@
|
||||
<script lang="ts" context="module">
|
||||
import { writable } from "svelte/store";
|
||||
import HomeMachineDialog from "$dialogs/HomeMachineDialog.svelte";
|
||||
import ProbeDialog from "$dialogs/ProbeDialog.svelte";
|
||||
import ScreenRotationDialog from "$dialogs/ScreenRotationDialog.svelte";
|
||||
import UploadDialog from "$dialogs/UploadDialog.svelte";
|
||||
import SetTimeDialog from "./SetTimeDialog.svelte";
|
||||
import ManualHomeAxisDialog from "./ManualHomeAxisDialog.svelte";
|
||||
import SetAxisPositionDialog from "./SetAxisPositionDialog.svelte";
|
||||
import MoveToZeroDialog from "./MoveToZeroDialog.svelte";
|
||||
import ShutdownDialog from "./ShutdownDialog.svelte";
|
||||
import MessageDialog from "./MessageDialog.svelte";
|
||||
|
||||
const HomeMachineDialogProps = writable<HomeMachineDialogPropsType>();
|
||||
type HomeMachineDialogPropsType = {
|
||||
open: boolean;
|
||||
home: () => void;
|
||||
};
|
||||
|
||||
const ProbeDialogProps = writable<ProbeDialogPropsType>();
|
||||
type ProbeDialogPropsType = {
|
||||
open: boolean;
|
||||
probeType: "xyz" | "z";
|
||||
};
|
||||
|
||||
const ScreenRotationDialogProps = writable<ScreenRotationDialogPropsType>();
|
||||
type ScreenRotationDialogPropsType = {
|
||||
open: boolean;
|
||||
};
|
||||
|
||||
const UploadDialogProps = writable<UploadDialogPropsType>();
|
||||
type UploadDialogPropsType = {
|
||||
open: boolean;
|
||||
file: File;
|
||||
onComplete: () => void;
|
||||
};
|
||||
|
||||
const SetTimeDialogProps = writable<SetTimeDialogPropsType>();
|
||||
type SetTimeDialogPropsType = {
|
||||
open: boolean;
|
||||
};
|
||||
|
||||
const ManualHomeAxisDialogProps = writable<ManualHomeAxisDialogPropsType>();
|
||||
type ManualHomeAxisDialogPropsType = {
|
||||
open: boolean;
|
||||
axis: string;
|
||||
};
|
||||
|
||||
const SetAxisPositionDialogProps =
|
||||
writable<SetAxisPositionDialogPropsType>();
|
||||
type SetAxisPositionDialogPropsType = {
|
||||
open: boolean;
|
||||
axis: string;
|
||||
};
|
||||
|
||||
const MoveToZeroDialogProps = writable<MoveToZeroDialogPropsType>();
|
||||
type MoveToZeroDialogPropsType = {
|
||||
open: boolean;
|
||||
axes: "xy" | "z";
|
||||
};
|
||||
|
||||
const ShutdownDialogProps = writable<ShutdownDialogPropsType>();
|
||||
type ShutdownDialogPropsType = {
|
||||
open: boolean;
|
||||
};
|
||||
|
||||
const MessageDialogProps = writable<MessageDialogPropsType>();
|
||||
type MessageDialogPropsType = {
|
||||
open: boolean;
|
||||
title: string;
|
||||
message: string;
|
||||
noaction: boolean;
|
||||
};
|
||||
|
||||
export function showDialog(
|
||||
dialog: "HomeMachine",
|
||||
props: Omit<HomeMachineDialogPropsType, "open">
|
||||
);
|
||||
|
||||
export function showDialog(
|
||||
dialog: "Probe",
|
||||
props: Omit<ProbeDialogPropsType, "open">
|
||||
);
|
||||
|
||||
export function showDialog(
|
||||
dialog: "ScreenRotation",
|
||||
props: Omit<ScreenRotationDialogPropsType, "open">
|
||||
);
|
||||
|
||||
export function showDialog(
|
||||
dialog: "Upload",
|
||||
props: Omit<UploadDialogPropsType, "open">
|
||||
);
|
||||
|
||||
export function showDialog(
|
||||
dialog: "SetTime",
|
||||
props: Omit<SetTimeDialogPropsType, "open">
|
||||
);
|
||||
|
||||
export function showDialog(
|
||||
dialog: "ManualHomeAxis",
|
||||
props: Omit<ManualHomeAxisDialogPropsType, "open">
|
||||
);
|
||||
|
||||
export function showDialog(
|
||||
dialog: "SetAxisPosition",
|
||||
props: Omit<SetAxisPositionDialogPropsType, "open">
|
||||
);
|
||||
|
||||
export function showDialog(
|
||||
dialog: "MoveToZero",
|
||||
props: Omit<MoveToZeroDialogPropsType, "open">
|
||||
);
|
||||
|
||||
export function showDialog(
|
||||
dialog: "Shutdown",
|
||||
props: Omit<ShutdownDialogPropsType, "open">
|
||||
);
|
||||
|
||||
export function showDialog(
|
||||
dialog: "Message",
|
||||
props: Omit<MessageDialogPropsType, "open">
|
||||
);
|
||||
|
||||
export function showDialog(dialog: string, props: any) {
|
||||
switch (dialog) {
|
||||
case "HomeMachine":
|
||||
HomeMachineDialogProps.set({ ...props, open: true });
|
||||
break;
|
||||
|
||||
case "Probe":
|
||||
ProbeDialogProps.set({ ...props, open: true });
|
||||
break;
|
||||
|
||||
case "ScreenRotation":
|
||||
ScreenRotationDialogProps.set({ ...props, open: true });
|
||||
break;
|
||||
|
||||
case "Upload":
|
||||
UploadDialogProps.set({ ...props, open: true });
|
||||
break;
|
||||
|
||||
case "SetTime":
|
||||
SetTimeDialogProps.set({ ...props, open: true });
|
||||
break;
|
||||
|
||||
case "ManualHomeAxis":
|
||||
ManualHomeAxisDialogProps.set({ ...props, open: true });
|
||||
break;
|
||||
|
||||
case "SetAxisPosition":
|
||||
SetAxisPositionDialogProps.set({ ...props, open: true });
|
||||
break;
|
||||
|
||||
case "MoveToZero":
|
||||
MoveToZeroDialogProps.set({ ...props, open: true });
|
||||
break;
|
||||
|
||||
case "Shutdown":
|
||||
ShutdownDialogProps.set({ ...props, open: true });
|
||||
break;
|
||||
|
||||
case "Message":
|
||||
MessageDialogProps.set({ ...props, open: true });
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new Error(`Unknown dialog '${dialog}'`);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
import { onMount, onDestroy } from "svelte";
|
||||
|
||||
let bodyObserver: MutationObserver;
|
||||
let keyboardObserver: MutationObserver;
|
||||
|
||||
onMount(() => {
|
||||
bodyObserver = new MutationObserver(() => {
|
||||
const virtualKeyboard = document.getElementById(
|
||||
"virtualKeyboardChromeExtension"
|
||||
);
|
||||
|
||||
if (virtualKeyboard) {
|
||||
bodyObserver.disconnect();
|
||||
bodyObserver = undefined;
|
||||
|
||||
const virtualKeyboardOverlay = document.getElementById(
|
||||
"virtualKeyboardChromeExtensionOverlayScrollExtend"
|
||||
);
|
||||
|
||||
keyboardObserver = new MutationObserver(() => {
|
||||
const open =
|
||||
virtualKeyboard.getAttribute("_state") === "open";
|
||||
const keyboardHeight = Number.parseFloat(
|
||||
virtualKeyboardOverlay.style.height
|
||||
);
|
||||
|
||||
const dialogContainers =
|
||||
document.querySelectorAll<HTMLDivElement>(
|
||||
".mdc-dialog .mdc-dialog__container"
|
||||
);
|
||||
|
||||
for (let dialogContainer of dialogContainers) {
|
||||
dialogContainer.style["marginBottom"] = open
|
||||
? `${keyboardHeight}px`
|
||||
: "";
|
||||
}
|
||||
});
|
||||
|
||||
keyboardObserver.observe(virtualKeyboard, { attributes: true });
|
||||
}
|
||||
});
|
||||
|
||||
bodyObserver.observe(document.querySelector("body"), {
|
||||
subtree: false,
|
||||
childList: true,
|
||||
});
|
||||
});
|
||||
|
||||
onDestroy(() => {
|
||||
if (bodyObserver) {
|
||||
bodyObserver.disconnect();
|
||||
bodyObserver = undefined;
|
||||
}
|
||||
|
||||
if (keyboardObserver) {
|
||||
keyboardObserver.disconnect();
|
||||
keyboardObserver = undefined;
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<HomeMachineDialog {...$HomeMachineDialogProps} />
|
||||
<ProbeDialog {...$ProbeDialogProps} />
|
||||
<ScreenRotationDialog {...$ScreenRotationDialogProps} />
|
||||
<UploadDialog {...$UploadDialogProps} />
|
||||
<SetTimeDialog {...$SetTimeDialogProps} />
|
||||
<ManualHomeAxisDialog {...$ManualHomeAxisDialogProps} />
|
||||
<SetAxisPositionDialog {...$SetAxisPositionDialogProps} />
|
||||
<MoveToZeroDialog {...$MoveToZeroDialogProps} />
|
||||
<ShutdownDialog {...$ShutdownDialogProps} />
|
||||
<MessageDialog {...$MessageDialogProps} />
|
||||
33
src/svelte-components/src/dialogs/HomeMachineDialog.svelte
Normal file
@@ -0,0 +1,33 @@
|
||||
<script lang="ts">
|
||||
import Dialog, {
|
||||
Title,
|
||||
Content,
|
||||
Actions,
|
||||
InitialFocus,
|
||||
} from "@smui/dialog";
|
||||
import Button, { Label } from "@smui/button";
|
||||
|
||||
export let open;
|
||||
export let home: () => any;
|
||||
</script>
|
||||
|
||||
<Dialog
|
||||
bind:open
|
||||
scrimClickAction=""
|
||||
aria-labelledby="home-machine-dialog-title"
|
||||
aria-describedby="home-machine-dialog-content"
|
||||
>
|
||||
<Title id="home-machine-dialog-title">Home Machine</Title>
|
||||
|
||||
<Content id="home-machine-dialog-content">Home the machine?</Content>
|
||||
|
||||
<Actions>
|
||||
<Button>
|
||||
<Label>Cancel</Label>
|
||||
</Button>
|
||||
|
||||
<Button defaultAction use={[InitialFocus]} on:click={home}>
|
||||
<Label>OK</Label>
|
||||
</Button>
|
||||
</Actions>
|
||||
</Dialog>
|
||||
@@ -0,0 +1,54 @@
|
||||
<script lang="ts">
|
||||
import Dialog, {
|
||||
Title,
|
||||
Content,
|
||||
Actions,
|
||||
InitialFocus,
|
||||
} from "@smui/dialog";
|
||||
import TextField from "@smui/textfield";
|
||||
import Button, { Label } from "@smui/button";
|
||||
import { ControllerMethods } from "$lib/RegisterControllerMethods";
|
||||
import { virtualKeyboardChange } from "$lib/CustomActions";
|
||||
|
||||
export let open: boolean;
|
||||
export let axis = "";
|
||||
|
||||
let value = 0;
|
||||
|
||||
function onConfirm() {
|
||||
ControllerMethods.set_home(axis, value);
|
||||
}
|
||||
</script>
|
||||
|
||||
<Dialog
|
||||
bind:open
|
||||
scrimClickAction=""
|
||||
aria-labelledby="manual-home-axis-dialog-title"
|
||||
aria-describedby="manual-home-axis-dialog-content"
|
||||
>
|
||||
<Title id="manual-home-axis-dialog-title">
|
||||
Manually Home {axis.toUpperCase()} Axis
|
||||
</Title>
|
||||
|
||||
<Content id="manual-home-axis-dialog-content">
|
||||
<p>Set axis absolute position</p>
|
||||
|
||||
<TextField
|
||||
label="Absolute"
|
||||
type="number"
|
||||
bind:value
|
||||
use={[InitialFocus, virtualKeyboardChange((v) => (value = v))]}
|
||||
variant="filled"
|
||||
style="width: 100%;"
|
||||
/>
|
||||
</Content>
|
||||
|
||||
<Actions>
|
||||
<Button>
|
||||
<Label>Cancel</Label>
|
||||
</Button>
|
||||
<Button defaultAction on:click={onConfirm}>
|
||||
<Label>Set</Label>
|
||||
</Button>
|
||||
</Actions>
|
||||
</Dialog>
|
||||
36
src/svelte-components/src/dialogs/MessageDialog.svelte
Normal file
@@ -0,0 +1,36 @@
|
||||
<script lang="ts">
|
||||
import Dialog, {
|
||||
Title,
|
||||
Content,
|
||||
Actions,
|
||||
InitialFocus,
|
||||
} from "@smui/dialog";
|
||||
import Button, { Label } from "@smui/button";
|
||||
|
||||
export let open: boolean;
|
||||
export let title = "";
|
||||
export let message = "";
|
||||
export let noaction = false;
|
||||
</script>
|
||||
|
||||
<Dialog
|
||||
bind:open
|
||||
scrimClickAction=""
|
||||
escapeKeyAction=""
|
||||
aria-labelledby="message-dialog-title"
|
||||
aria-describedby="message-dialog-content"
|
||||
>
|
||||
<Title id="message-dialog-title">{title}</Title>
|
||||
|
||||
<Content id="message-dialog-content">
|
||||
<slot>{message}</slot>
|
||||
</Content>
|
||||
|
||||
{#if !noaction}
|
||||
<Actions>
|
||||
<Button defaultAction use={[InitialFocus]}>
|
||||
<Label>OK</Label>
|
||||
</Button>
|
||||
</Actions>
|
||||
{/if}
|
||||
</Dialog>
|
||||
33
src/svelte-components/src/dialogs/MoveToZeroDialog.svelte
Normal file
@@ -0,0 +1,33 @@
|
||||
<script lang="ts">
|
||||
import Dialog, { Title, Actions, InitialFocus } from "@smui/dialog";
|
||||
import Button, { Label } from "@smui/button";
|
||||
import { ControllerMethods } from "$lib/RegisterControllerMethods";
|
||||
|
||||
export let open;
|
||||
export let axes: "xy" | "z";
|
||||
</script>
|
||||
|
||||
<Dialog
|
||||
bind:open
|
||||
scrimClickAction=""
|
||||
aria-labelledby="move-to-zero-dialog-title"
|
||||
aria-describedby="move-to-zero-dialog-content"
|
||||
>
|
||||
<Title id="move-to-zero-dialog-title">
|
||||
Move to {(axes || "").toUpperCase()} origin?
|
||||
</Title>
|
||||
|
||||
<Actions>
|
||||
<Button>
|
||||
<Label>Cancel</Label>
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
defaultAction
|
||||
use={[InitialFocus]}
|
||||
on:click={() => ControllerMethods.gotoZero(axes)}
|
||||
>
|
||||
<Label>Confirm</Label>
|
||||
</Button>
|
||||
</Actions>
|
||||
</Dialog>
|
||||
517
src/svelte-components/src/dialogs/ProbeDialog.svelte
Normal file
@@ -0,0 +1,517 @@
|
||||
<script type="ts">
|
||||
import Dialog, { Title, Content, Actions } from "@smui/dialog";
|
||||
import Button, { Label } from "@smui/button";
|
||||
import LinearProgress from "@smui/linear-progress";
|
||||
import { waitForChange } from "$lib/StoreHelpers";
|
||||
import { ControllerMethods } from "$lib/RegisterControllerMethods";
|
||||
import { Config } from "$lib/ConfigStore";
|
||||
import { writable, type Writable } from "svelte/store";
|
||||
import {
|
||||
probingActive,
|
||||
probeContacted,
|
||||
probingComplete,
|
||||
probingFailed,
|
||||
probingStarted,
|
||||
} from "$lib/ControllerState";
|
||||
import { numberWithUnit } from "$lib/RegexHelpers";
|
||||
import TextFieldWithOptions from "$components/TextFieldWithOptions.svelte";
|
||||
import Icon from "svelte-icon";
|
||||
import BitDiameter from "../svgs/probe-bit-diameter.svg?raw";
|
||||
import CheckXYZ from "../svgs/probe-check-xyz.svg?raw";
|
||||
import CheckZ from "../svgs/probe-check-z.svg?raw";
|
||||
import PlaceXYZ from "../svgs/probe-place-xyz.svg?raw";
|
||||
import PlaceZ from "../svgs/probe-place-z.svg?raw";
|
||||
import PutAwayXYZ from "../svgs/probe-put-away-xyz.svg?raw";
|
||||
import PutAwayZ from "../svgs/probe-put-away-z.svg?raw";
|
||||
|
||||
const ValidSteps = [
|
||||
"None",
|
||||
"CheckProbe",
|
||||
"BitDimensions",
|
||||
"PlaceProbeBlock",
|
||||
"Probe",
|
||||
"Done",
|
||||
] as const;
|
||||
|
||||
type Step = typeof ValidSteps[number];
|
||||
|
||||
function isStep(str): str is Step {
|
||||
return ValidSteps.includes(str);
|
||||
}
|
||||
|
||||
const stepLabels: Record<Step, string> = {
|
||||
None: "",
|
||||
CheckProbe: "Check probe",
|
||||
BitDimensions: "Bit dimensions",
|
||||
PlaceProbeBlock: "Place probe block",
|
||||
Probe: "Probe",
|
||||
Done: "Done",
|
||||
};
|
||||
|
||||
const cancelled = writable(false);
|
||||
const userAcknowledged = writable(false);
|
||||
|
||||
const imperialBits: `${number}/${number} in`[] = [
|
||||
"1/2 in",
|
||||
"3/8 in",
|
||||
"1/4 in",
|
||||
"1/8 in",
|
||||
"1/16 in",
|
||||
"1/32 in",
|
||||
];
|
||||
|
||||
const metricBits: `${number} mm`[] = [
|
||||
"12 mm",
|
||||
"10 mm",
|
||||
"8 mm",
|
||||
"6 mm",
|
||||
"4 mm",
|
||||
"3 mm",
|
||||
];
|
||||
|
||||
export let open;
|
||||
export let probeType: "xyz" | "z";
|
||||
let currentStep: Step = "None";
|
||||
let cutterDiameterString: string = "";
|
||||
let cutterDiameterMetric: number;
|
||||
let showCancelButton = true;
|
||||
let steps: Step[] = [];
|
||||
let nextButton = {
|
||||
label: "Next",
|
||||
disabled: false,
|
||||
allowClose: false,
|
||||
};
|
||||
|
||||
$: metric = $Config.settings?.units === "METRIC";
|
||||
$: cutterDiameterMetric = numberWithUnit
|
||||
.parse(cutterDiameterString)
|
||||
?.toMetric();
|
||||
|
||||
$: if (open) {
|
||||
cutterDiameterString = localStorage.getItem("cutterDiameter") ?? "";
|
||||
|
||||
// Svelte appears not to like it when you invoke
|
||||
// an async function from a reactive statement, so we
|
||||
// use requestAnimationFrame to call 'begin' at a later moment.
|
||||
requestAnimationFrame(begin);
|
||||
}
|
||||
|
||||
$: if (cutterDiameterString) {
|
||||
updateButtons();
|
||||
}
|
||||
|
||||
async function begin() {
|
||||
try {
|
||||
$probingActive = true;
|
||||
assertValidProbeType();
|
||||
|
||||
$probingFailed = false;
|
||||
|
||||
const enableSafety = $Config.settings["probing-prompts"];
|
||||
|
||||
steps = [
|
||||
enableSafety ? "CheckProbe" : undefined,
|
||||
probeType === "xyz" ? "BitDimensions" : undefined,
|
||||
enableSafety ? "PlaceProbeBlock" : undefined,
|
||||
"Probe",
|
||||
"Done",
|
||||
].filter<Step>(isStep);
|
||||
|
||||
await stepCompleted("CheckProbe", probeContacted);
|
||||
|
||||
if (probeType === "xyz") {
|
||||
await stepCompleted("BitDimensions", userAcknowledged);
|
||||
localStorage.setItem(
|
||||
"cutterDiameter",
|
||||
numberWithUnit.normalize(cutterDiameterString)
|
||||
);
|
||||
}
|
||||
|
||||
await stepCompleted("PlaceProbeBlock", userAcknowledged);
|
||||
await stepCompleted("Probe", probingComplete, probingFailed);
|
||||
await stepCompleted("Done", userAcknowledged);
|
||||
|
||||
if (probeType === "xyz") {
|
||||
ControllerMethods.gotoZero("xy");
|
||||
}
|
||||
} catch (err) {
|
||||
if (err.message !== "cancelled") {
|
||||
console.error("Error during probing:", err);
|
||||
}
|
||||
} finally {
|
||||
$probingActive = false;
|
||||
currentStep = "None";
|
||||
|
||||
if ($probingStarted) {
|
||||
ControllerMethods.stop();
|
||||
}
|
||||
|
||||
clearFlags();
|
||||
}
|
||||
}
|
||||
|
||||
function assertValidProbeType() {
|
||||
switch (probeType) {
|
||||
case "xyz":
|
||||
case "z":
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new Error(`Invalid probe type: ${probeType}`);
|
||||
}
|
||||
}
|
||||
|
||||
async function stepCompleted(
|
||||
nextStep: Step,
|
||||
...writables: Array<Writable<any>>
|
||||
) {
|
||||
currentStep = nextStep;
|
||||
|
||||
if (!steps.includes(currentStep)) {
|
||||
return;
|
||||
}
|
||||
|
||||
clearFlags();
|
||||
updateButtons();
|
||||
|
||||
if (currentStep === "Probe") {
|
||||
executeProbe();
|
||||
}
|
||||
|
||||
await Promise.race([
|
||||
...writables.map((writable) => waitForChange(writable)),
|
||||
waitForChange(cancelled),
|
||||
]);
|
||||
|
||||
if ($cancelled) {
|
||||
throw new Error("cancelled");
|
||||
}
|
||||
}
|
||||
|
||||
function clearFlags(foo: string = "") {
|
||||
$cancelled = false;
|
||||
$probeContacted = false;
|
||||
$probingStarted = false;
|
||||
$probingComplete = false;
|
||||
$userAcknowledged = false;
|
||||
}
|
||||
|
||||
function updateButtons() {
|
||||
showCancelButton = true;
|
||||
|
||||
nextButton = {
|
||||
label: "Next",
|
||||
disabled: false,
|
||||
allowClose: false,
|
||||
};
|
||||
|
||||
switch (currentStep) {
|
||||
case "CheckProbe":
|
||||
case "Probe":
|
||||
nextButton.disabled = true;
|
||||
break;
|
||||
|
||||
case "BitDimensions":
|
||||
nextButton.disabled = !isFinite(cutterDiameterMetric);
|
||||
break;
|
||||
|
||||
case "Done":
|
||||
showCancelButton = false;
|
||||
nextButton = {
|
||||
disabled: false,
|
||||
label: "Done",
|
||||
allowClose: true,
|
||||
};
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function executeProbe() {
|
||||
const probeBlockWidth = $Config.probe["probe-xdim"];
|
||||
const probeBlockLength = $Config.probe["probe-ydim"];
|
||||
const probeBlockHeight = $Config.probe["probe-zdim"];
|
||||
const slowSeek = $Config.probe["probe-slow-seek"];
|
||||
const fastSeek = $Config.probe["probe-fast-seek"];
|
||||
|
||||
const cutterLength = 12.7;
|
||||
const zLift = 1;
|
||||
const xOffset = probeBlockWidth + cutterDiameterMetric / 2.0;
|
||||
const yOffset = probeBlockLength + cutterDiameterMetric / 2.0;
|
||||
const zOffset = probeBlockHeight;
|
||||
|
||||
if (probeType === "z") {
|
||||
ControllerMethods.send(`
|
||||
G21
|
||||
G92 Z0
|
||||
|
||||
G38.2 Z -25.4 F${fastSeek}
|
||||
G91 G1 Z 1
|
||||
G38.2 Z -2 F${slowSeek}
|
||||
G92 Z ${zOffset}
|
||||
|
||||
G91 G0 Z 25
|
||||
|
||||
M2
|
||||
`);
|
||||
} else {
|
||||
// After probing Z, we want to drop the bit down:
|
||||
// Ideally, 12.7mm/0.5in
|
||||
// And we don't want to be more than 90% down on the probe block
|
||||
// Also, add zlift to compensate for the fact that we lift after probing Z
|
||||
const plunge = Math.min(cutterLength, zOffset * 0.9) + zLift;
|
||||
|
||||
ControllerMethods.send(`
|
||||
G21
|
||||
G92 X0 Y0 Z0
|
||||
|
||||
G38.2 Z -25 F${fastSeek}
|
||||
G91 G1 Z 1
|
||||
G38.2 Z -2 F${slowSeek}
|
||||
G92 Z ${zOffset}
|
||||
|
||||
G91 G0 Z ${zLift}
|
||||
G91 G0 X 20
|
||||
G91 G0 Z ${-plunge}
|
||||
G38.2 X -20 F${fastSeek}
|
||||
G91 G1 X 1
|
||||
G38.2 X -2 F${slowSeek}
|
||||
G92 X ${xOffset}
|
||||
|
||||
G91 G0 X 1
|
||||
G91 G0 Y 20
|
||||
G91 G0 X -20
|
||||
G38.2 Y -20 F${fastSeek}
|
||||
G91 G1 Y 1
|
||||
G38.2 Y -2 F${slowSeek}
|
||||
G92 Y ${yOffset}
|
||||
|
||||
G91 G0 Y 3
|
||||
G91 G0 Z 25
|
||||
|
||||
M2
|
||||
`);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<Dialog
|
||||
bind:open
|
||||
class="probe-dialog"
|
||||
scrimClickAction=""
|
||||
aria-labelledby="probe-dialog-title"
|
||||
aria-describedby="probe-dialog-content"
|
||||
surface$style="width: 700px; max-width: calc(100vw - 32px);"
|
||||
>
|
||||
<Title id="probe-dialog-title">Probing {probeType?.toUpperCase()}</Title>
|
||||
|
||||
<Content id="probe-dialog-content" style="overflow: visible;">
|
||||
<div class="steps">
|
||||
<p>
|
||||
<b>Step {steps.indexOf(currentStep) + 1} of {steps.length}</b>
|
||||
</p>
|
||||
<ul>
|
||||
{#each steps as step}
|
||||
<li class:active={currentStep === step}>
|
||||
{stepLabels[step]}
|
||||
</li>
|
||||
{/each}
|
||||
</ul>
|
||||
</div>
|
||||
<div style="width: 100%">
|
||||
{#if currentStep === "CheckProbe"}
|
||||
<p>
|
||||
Attach the probe magnet to the collet, then touch the probe
|
||||
block to the bit.
|
||||
</p>
|
||||
|
||||
<Icon
|
||||
data={probeType === "xyz" ? CheckXYZ : CheckZ}
|
||||
size="300px"
|
||||
class="probe-icon-svg"
|
||||
/>
|
||||
{:else if currentStep === "BitDimensions"}
|
||||
<TextFieldWithOptions
|
||||
label="Cutter diameter"
|
||||
variant="filled"
|
||||
spellcheck="false"
|
||||
style="width: 100%;"
|
||||
bind:value={cutterDiameterString}
|
||||
options={[imperialBits, metricBits]}
|
||||
valid={isFinite(cutterDiameterMetric)}
|
||||
helperText={`Examples: 1/2", 10 mm, 0.25 in`}
|
||||
/>
|
||||
|
||||
<Icon data={BitDiameter} size="150px" class="probe-icon-svg" />
|
||||
{:else if currentStep === "PlaceProbeBlock"}
|
||||
<p>
|
||||
{#if probeType === "xyz"}
|
||||
Place the probe block face up, on the lower-left corner
|
||||
of your workpiece.
|
||||
{:else}
|
||||
Place the probe block face down, with the bit above the
|
||||
recess.
|
||||
{/if}
|
||||
</p>
|
||||
|
||||
<Icon
|
||||
data={probeType === "xyz" ? PlaceXYZ : PlaceZ}
|
||||
width="304px"
|
||||
height="129px"
|
||||
class="probe-icon-svg"
|
||||
/>
|
||||
|
||||
<p>
|
||||
The probing procedure will begin as soon as you click
|
||||
'Next'.
|
||||
</p>
|
||||
{:else if currentStep === "Probe"}
|
||||
<p>Probing in progress...</p>
|
||||
|
||||
<LinearProgress indeterminate />
|
||||
{:else if currentStep === "Done"}
|
||||
{#if $probingFailed}
|
||||
<h3>Emergency Stop!</h3>
|
||||
|
||||
<p>Could not find the probe block during probing!</p>
|
||||
|
||||
<p>
|
||||
Make sure the tip of the bit is less than {metric
|
||||
? "25mm"
|
||||
: "1 in"}
|
||||
above the probe block, and try again.
|
||||
</p>
|
||||
{:else}
|
||||
<p>Don't forget to put away the probe!</p>
|
||||
|
||||
<Icon
|
||||
data={probeType === "xyz" ? PutAwayXYZ : PutAwayZ}
|
||||
width="329px"
|
||||
height="256px"
|
||||
class="probe-icon-svg"
|
||||
/>
|
||||
|
||||
{#if probeType === "xyz"}
|
||||
<p>The machine will now move to the XY origin.</p>
|
||||
|
||||
<p>Watch your hands!</p>
|
||||
{/if}
|
||||
{/if}
|
||||
{/if}
|
||||
</div>
|
||||
</Content>
|
||||
|
||||
<Actions>
|
||||
{#if showCancelButton}
|
||||
<Button on:click={() => ($cancelled = true)}>
|
||||
<Label>Cancel</Label>
|
||||
</Button>
|
||||
{/if}
|
||||
<Button
|
||||
defaultAction
|
||||
data-mdc-dialog-action={nextButton.allowClose ? "close" : ""}
|
||||
disabled={nextButton.disabled}
|
||||
on:click={() => ($userAcknowledged = true)}
|
||||
>
|
||||
<Label>
|
||||
{nextButton.label}
|
||||
</Label>
|
||||
</Button>
|
||||
</Actions>
|
||||
</Dialog>
|
||||
|
||||
<style lang="scss">
|
||||
$primary: #0078e7;
|
||||
$very-dark: #555;
|
||||
$text: #777;
|
||||
$grey: #bbb;
|
||||
$light: #ddd;
|
||||
|
||||
:global {
|
||||
.probe-dialog {
|
||||
.mdc-linear-progress {
|
||||
height: 10px;
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
.mdc-linear-progress__bar-inner {
|
||||
border-top-width: 10px;
|
||||
}
|
||||
|
||||
.probe-icon-svg {
|
||||
display: block;
|
||||
margin: 20px auto;
|
||||
}
|
||||
|
||||
#probe-dialog-content {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.bit-dimensions {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.steps {
|
||||
margin-right: 50px;
|
||||
|
||||
ul {
|
||||
margin: 0 auto;
|
||||
list-style-type: none;
|
||||
counter-reset: steps;
|
||||
margin: 0;
|
||||
font-family: sans-serif;
|
||||
padding-inline-start: 20px;
|
||||
}
|
||||
|
||||
ul li {
|
||||
padding: 0 0 12px 30px;
|
||||
position: relative;
|
||||
margin: 0;
|
||||
white-space: nowrap;
|
||||
color: $text;
|
||||
|
||||
&:after {
|
||||
position: absolute;
|
||||
top: 3px;
|
||||
left: 0.5px;
|
||||
content: "";
|
||||
border: 2px solid $text;
|
||||
border-radius: 50%;
|
||||
display: inline-block;
|
||||
height: 11px;
|
||||
width: 11px;
|
||||
text-align: center;
|
||||
line-height: 12px;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
&:before {
|
||||
position: absolute;
|
||||
left: 7px;
|
||||
top: 22px;
|
||||
bottom: 0;
|
||||
content: "";
|
||||
width: 0;
|
||||
border-left: 2px solid $text;
|
||||
}
|
||||
|
||||
&:last-of-type:before {
|
||||
border: none;
|
||||
}
|
||||
|
||||
&.active {
|
||||
color: $primary;
|
||||
font-weight: bold;
|
||||
|
||||
&:after {
|
||||
border: 3px solid $primary;
|
||||
top: 2.5px;
|
||||
left: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,67 @@
|
||||
<script lang="ts">
|
||||
import * as api from "$lib/api";
|
||||
import TextField from "@smui/textfield";
|
||||
import Dialog, {
|
||||
Title,
|
||||
Content,
|
||||
Actions,
|
||||
InitialFocus,
|
||||
} from "@smui/dialog";
|
||||
import Button, { Label } from "@smui/button";
|
||||
import { virtualKeyboardChange } from "$lib/CustomActions";
|
||||
|
||||
export let open;
|
||||
|
||||
let code = "";
|
||||
|
||||
async function onContinue() {
|
||||
const url = `remote-diagnostics?command=connect&code=${code}`;
|
||||
const result = await api.GET(url);
|
||||
|
||||
if (result.code === 401) {
|
||||
alert("The 6-digit code you provided was incorrect");
|
||||
} else {
|
||||
alert("Success!");
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<Dialog
|
||||
bind:open
|
||||
scrimClickAction=""
|
||||
aria-labelledby="remote-diagnostics-dialog-title"
|
||||
aria-describedby="remote-diagnostics-dialog-content"
|
||||
>
|
||||
<Title id="remote-diagnostics-dialog-title">Remote Diagnostics</Title>
|
||||
|
||||
<Content id="remote-diagnostics-dialog-content">
|
||||
<p>
|
||||
This feature enables remote diagnosis of customer issues. It
|
||||
requires a 6-digit code that is provided by Onefinity support during
|
||||
a live support session.
|
||||
</p>
|
||||
|
||||
<TextField
|
||||
bind:value={code}
|
||||
label="6-digit code"
|
||||
type="number"
|
||||
variant="filled"
|
||||
invalid={code?.length !== 6}
|
||||
use={[InitialFocus, virtualKeyboardChange((v) => (code = v))]}
|
||||
/>
|
||||
</Content>
|
||||
|
||||
<Actions>
|
||||
<Button>
|
||||
<Label>Cancel</Label>
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
defaultAction
|
||||
on:click={onContinue}
|
||||
disabled={code?.length !== 6}
|
||||
>
|
||||
<Label>Continue</Label>
|
||||
</Button>
|
||||
</Actions>
|
||||
</Dialog>
|
||||
@@ -0,0 +1,81 @@
|
||||
<script type="ts">
|
||||
import Dialog, {
|
||||
Title,
|
||||
Content,
|
||||
Actions,
|
||||
InitialFocus,
|
||||
} from "@smui/dialog";
|
||||
import Button, { Label } from "@smui/button";
|
||||
import Radio from "@smui/radio";
|
||||
import FormField from "@smui/form-field";
|
||||
import MessageDialog from "$dialogs/MessageDialog.svelte";
|
||||
import * as Api from "$lib/api";
|
||||
import { onMount } from "svelte";
|
||||
|
||||
const options = [
|
||||
{ value: 0, label: "Normal" },
|
||||
{ value: 1, label: "Upside-down" },
|
||||
];
|
||||
|
||||
export let open;
|
||||
let currentValue;
|
||||
let value;
|
||||
let rebooting;
|
||||
|
||||
onMount(async () => {
|
||||
const result = await Api.GET("screen-rotation");
|
||||
currentValue = value = result.rotated ? 1 : 0;
|
||||
});
|
||||
|
||||
async function onConfirm() {
|
||||
rebooting = true;
|
||||
|
||||
await Api.PUT("screen-rotation", { rotated: value === 1 });
|
||||
}
|
||||
</script>
|
||||
|
||||
<MessageDialog open={rebooting} title="Rebooting" noaction>
|
||||
Rebooting to apply the new screen rotation...
|
||||
</MessageDialog>
|
||||
|
||||
<Dialog
|
||||
bind:open
|
||||
scrimClickAction=""
|
||||
aria-labelledby="screen-rotation-dialog-title"
|
||||
aria-describedby="screen-rotation-dialog-content"
|
||||
>
|
||||
<Title id="screen-rotation-dialog-title">Screen Rotation</Title>
|
||||
|
||||
<Content id="screen-rotation-dialog-content">
|
||||
{#each options as option}
|
||||
<FormField>
|
||||
<Radio bind:group={value} value={option.value} />
|
||||
<span slot="label">
|
||||
{option.label}
|
||||
</span>
|
||||
</FormField>
|
||||
{/each}
|
||||
</Content>
|
||||
|
||||
<Actions>
|
||||
<Button use={[InitialFocus]}>
|
||||
<Label>Cancel</Label>
|
||||
</Button>
|
||||
<Button
|
||||
defaultAction
|
||||
disabled={value === currentValue}
|
||||
on:click={onConfirm}
|
||||
>
|
||||
<Label>Confirm & Reboot</Label>
|
||||
</Button>
|
||||
</Actions>
|
||||
</Dialog>
|
||||
|
||||
<style lang="scss">
|
||||
:global {
|
||||
#screen-rotation-dialog-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,72 @@
|
||||
<script lang="ts">
|
||||
import Dialog, {
|
||||
Title,
|
||||
Content,
|
||||
Actions,
|
||||
InitialFocus,
|
||||
} from "@smui/dialog";
|
||||
import TextField from "@smui/textfield";
|
||||
import Button, { Label } from "@smui/button";
|
||||
import { ControllerMethods } from "$lib/RegisterControllerMethods";
|
||||
import { virtualKeyboardChange } from "$lib/CustomActions";
|
||||
|
||||
export let open: boolean;
|
||||
export let axis = "";
|
||||
|
||||
let value = 0;
|
||||
let homed = false;
|
||||
let wasOpen = false;
|
||||
|
||||
$: if (open != wasOpen) {
|
||||
if (open) {
|
||||
homed = ControllerMethods.isAxisHomed(axis);
|
||||
}
|
||||
|
||||
wasOpen = open;
|
||||
}
|
||||
|
||||
function onUnhome() {
|
||||
ControllerMethods.unhome(axis);
|
||||
}
|
||||
|
||||
function onConfirm() {
|
||||
ControllerMethods.set_position(axis, value);
|
||||
}
|
||||
</script>
|
||||
|
||||
<Dialog
|
||||
bind:open
|
||||
scrimClickAction=""
|
||||
aria-labelledby="set-axis-position-dialog-title"
|
||||
aria-describedby="set-axis-position-dialog-content"
|
||||
>
|
||||
<Title id="set-axis-position-dialog-title">
|
||||
Set {axis.toUpperCase()} Axis Position
|
||||
</Title>
|
||||
|
||||
<Content id="set-axis-position-dialog-content">
|
||||
<TextField
|
||||
label="Position"
|
||||
type="number"
|
||||
bind:value
|
||||
use={[InitialFocus, virtualKeyboardChange((v) => (value = v))]}
|
||||
spellcheck="false"
|
||||
variant="filled"
|
||||
style="width: 100%;"
|
||||
/>
|
||||
</Content>
|
||||
|
||||
<Actions>
|
||||
<Button>
|
||||
<Label>Cancel</Label>
|
||||
</Button>
|
||||
{#if homed}
|
||||
<Button on:click={onUnhome}>
|
||||
<Label>Unhome</Label>
|
||||
</Button>
|
||||
{/if}
|
||||
<Button defaultAction on:click={onConfirm}>
|
||||
<Label>Set</Label>
|
||||
</Button>
|
||||
</Actions>
|
||||
</Dialog>
|
||||
290
src/svelte-components/src/dialogs/SetTimeDialog.svelte
Normal file
@@ -0,0 +1,290 @@
|
||||
<script lang="ts">
|
||||
import Dialog, {
|
||||
Title,
|
||||
Content,
|
||||
Actions,
|
||||
InitialFocus,
|
||||
} from "@smui/dialog";
|
||||
import Button, { Label } from "@smui/button";
|
||||
import TextField from "@smui/textfield";
|
||||
import Select, { Option } from "@smui/select";
|
||||
import CircularProgress from "@smui/circular-progress";
|
||||
import VirtualList from "svelte-tiny-virtual-list";
|
||||
import * as api from "$lib/api";
|
||||
import { virtualKeyboardChange } from "$lib/CustomActions";
|
||||
|
||||
const itemHeight = 35;
|
||||
|
||||
type Timezone = {
|
||||
label: string;
|
||||
value: string;
|
||||
};
|
||||
|
||||
export let open = false;
|
||||
let year = "";
|
||||
let month = "";
|
||||
let day = "";
|
||||
let hour = "";
|
||||
let minute = "";
|
||||
let am = true;
|
||||
let wasOpen = false;
|
||||
let loading = true;
|
||||
let timezones: Timezone[] = [];
|
||||
let currentTimezoneIndex: number;
|
||||
let selectedTimezoneIndex: number;
|
||||
let networkTimeSynchronized: boolean;
|
||||
|
||||
$: if (open != wasOpen) {
|
||||
if (!wasOpen) {
|
||||
loadData();
|
||||
}
|
||||
|
||||
wasOpen = open;
|
||||
}
|
||||
|
||||
async function loadData() {
|
||||
loading = true;
|
||||
|
||||
const result = await api.GET("time");
|
||||
|
||||
parseTimezones(result.timezones);
|
||||
parseTimeinfo(result.timeinfo);
|
||||
|
||||
const date = new Date();
|
||||
year = date.getFullYear().toString();
|
||||
month = (date.getMonth() + 1).toString();
|
||||
day = date.getDate().toString();
|
||||
hour = date.getHours().toString();
|
||||
minute = date.getMinutes().toString();
|
||||
am = date.getHours() >= 12;
|
||||
|
||||
loading = false;
|
||||
}
|
||||
|
||||
function parseTimeinfo(str: string) {
|
||||
const matches = Array.from(str.matchAll(/\s*([^:]+):\s+(.+)/gm));
|
||||
|
||||
let currentTimezoneValue;
|
||||
for (const match of matches) {
|
||||
let [, label, value] = match;
|
||||
|
||||
switch (label) {
|
||||
case "Time zone":
|
||||
currentTimezoneValue = value.split(" ")[0];
|
||||
break;
|
||||
|
||||
case "NTP synchronized":
|
||||
networkTimeSynchronized = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
currentTimezoneIndex = timezones.findIndex(
|
||||
(tz) => tz.value === currentTimezoneValue
|
||||
);
|
||||
selectedTimezoneIndex = currentTimezoneIndex;
|
||||
}
|
||||
|
||||
function parseTimezones(str: string) {
|
||||
const matches = Array.from(str.matchAll(/\s*(\S+)\s*/gm));
|
||||
|
||||
timezones = [];
|
||||
for (let [, value] of matches) {
|
||||
timezones.push({
|
||||
label: value.replace(/_/g, " "),
|
||||
value,
|
||||
});
|
||||
}
|
||||
|
||||
// Sort alphabetically, but with the current timezone at the top of the list
|
||||
timezones.sort((a, b) => {
|
||||
switch (true) {
|
||||
case a.value === "UTC":
|
||||
return -1;
|
||||
|
||||
case b.value === "UTC":
|
||||
return 1;
|
||||
|
||||
default:
|
||||
return a.value.localeCompare(b.value);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async function onConfirm() {
|
||||
const YY = year.toString().padStart(2, "0");
|
||||
const MM = month.toString().padStart(2, "0");
|
||||
const DD = day.toString().padStart(2, "0");
|
||||
let hh = hour.toString().padStart(2, "0");
|
||||
const mm = minute.toString().padStart(2, "0");
|
||||
|
||||
if (Number(hour) < 12 && !am) {
|
||||
hh = (hour + 12).toString().padStart(2, "0");
|
||||
}
|
||||
|
||||
await api.PUT("time", {
|
||||
datetime: `${YY}-${MM}-${DD} ${hh}:${mm}:00`,
|
||||
timezone: timezones[selectedTimezoneIndex].value,
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<Dialog
|
||||
bind:open
|
||||
scrimClickAction=""
|
||||
aria-labelledby="set-time-dialog-title"
|
||||
aria-describedby="set-time-dialog-content"
|
||||
>
|
||||
<Title id="set-time-dialog-title">Change Time & Timezone</Title>
|
||||
|
||||
<Content id="set-time-dialog-content">
|
||||
{#if loading}
|
||||
<div style="display: flex; justify-content: center">
|
||||
<CircularProgress
|
||||
style="height: 32px; width: 32px;"
|
||||
indeterminate
|
||||
/>
|
||||
</div>
|
||||
{:else}
|
||||
{#if networkTimeSynchronized}
|
||||
<p>
|
||||
Because this controller is connected to the internet, the
|
||||
time is managed automatically, and cannot be manually set.
|
||||
</p>
|
||||
{:else}
|
||||
<p>
|
||||
Any time the controller is turned off, the time will need to
|
||||
be reset. If you connect the controller to the internet, the
|
||||
time will be managed automatically.
|
||||
</p>
|
||||
|
||||
<TextField
|
||||
bind:value={year}
|
||||
use={[
|
||||
InitialFocus,
|
||||
virtualKeyboardChange((v) => (year = v)),
|
||||
]}
|
||||
label="Year"
|
||||
type="number"
|
||||
variant="filled"
|
||||
style="width: 70px;"
|
||||
/>
|
||||
<TextField
|
||||
bind:value={month}
|
||||
use={[virtualKeyboardChange((v) => (month = v))]}
|
||||
label="Month"
|
||||
type="number"
|
||||
variant="filled"
|
||||
style="width: 70px;"
|
||||
/>
|
||||
<TextField
|
||||
bind:value={day}
|
||||
use={[virtualKeyboardChange((v) => (day = v))]}
|
||||
label="Day"
|
||||
type="number"
|
||||
variant="filled"
|
||||
style="width: 70px;"
|
||||
/>
|
||||
|
||||
<span style="display: inline-block; width: 20px;" />
|
||||
|
||||
<TextField
|
||||
bind:value={hour}
|
||||
use={[virtualKeyboardChange((v) => (hour = v))]}
|
||||
label="Hour"
|
||||
type="number"
|
||||
variant="filled"
|
||||
style="width: 70px;"
|
||||
/>
|
||||
<TextField
|
||||
bind:value={minute}
|
||||
use={[virtualKeyboardChange((v) => (minute = v))]}
|
||||
label="Minute"
|
||||
type="number"
|
||||
variant="filled"
|
||||
style="width: 70px;"
|
||||
/>
|
||||
|
||||
<Select
|
||||
label=""
|
||||
bind:value={am}
|
||||
style="width: 90px;"
|
||||
variant="filled"
|
||||
>
|
||||
<Option value={true}>AM</Option>
|
||||
<Option value={false}>PM</Option>
|
||||
</Select>
|
||||
{/if}
|
||||
|
||||
<div class="timezones-container" style="margin-top: 30px;">
|
||||
<VirtualList
|
||||
width="100%"
|
||||
height={itemHeight * 6}
|
||||
itemCount={timezones.length}
|
||||
itemSize={itemHeight}
|
||||
scrollToIndex={currentTimezoneIndex}
|
||||
scrollToAlignment="center"
|
||||
>
|
||||
<div
|
||||
slot="item"
|
||||
let:index
|
||||
let:style
|
||||
{style}
|
||||
class="timezone"
|
||||
class:selected={index === selectedTimezoneIndex}
|
||||
on:click={() => (selectedTimezoneIndex = index)}
|
||||
>
|
||||
{timezones[index].label}
|
||||
</div>
|
||||
</VirtualList>
|
||||
</div>
|
||||
{/if}
|
||||
</Content>
|
||||
|
||||
<Actions>
|
||||
<Button>
|
||||
<Label>Cancel</Label>
|
||||
</Button>
|
||||
<Button
|
||||
defaultAction
|
||||
disabled={selectedTimezoneIndex === -1}
|
||||
on:click={onConfirm}
|
||||
>
|
||||
<Label>Confirm</Label>
|
||||
</Button>
|
||||
</Actions>
|
||||
</Dialog>
|
||||
|
||||
<style lang="scss">
|
||||
@use "sass:color";
|
||||
|
||||
$primary: #0078e7;
|
||||
$very-dark: #555;
|
||||
$text: #777;
|
||||
$grey: #bbb;
|
||||
$light: #ddd;
|
||||
|
||||
.timezones-container {
|
||||
:global {
|
||||
.virtual-list-wrapper {
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 3px;
|
||||
overflow-x: hidden;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
}
|
||||
.timezone {
|
||||
font-size: 14px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin: 0;
|
||||
padding-left: 10px;
|
||||
|
||||
&.selected {
|
||||
color: $primary;
|
||||
background-color: color.adjust($primary, $lightness: 50%);
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
38
src/svelte-components/src/dialogs/ShutdownDialog.svelte
Normal file
@@ -0,0 +1,38 @@
|
||||
<script lang="ts">
|
||||
import Dialog, { Title, Actions, InitialFocus } from "@smui/dialog";
|
||||
import Button, { Label } from "@smui/button";
|
||||
import * as Api from "$lib/api";
|
||||
|
||||
export let open;
|
||||
|
||||
function shutdown() {
|
||||
Api.PUT("shutdown");
|
||||
}
|
||||
|
||||
function restart() {
|
||||
Api.PUT("reboot");
|
||||
}
|
||||
</script>
|
||||
|
||||
<Dialog
|
||||
bind:open
|
||||
scrimClickAction=""
|
||||
aria-labelledby="shutdown-dialog-title"
|
||||
aria-describedby="shutdown-dialog-content"
|
||||
>
|
||||
<Title id="shutdown-dialog-title">Confirm Shutdown?</Title>
|
||||
|
||||
<Actions>
|
||||
<Button>
|
||||
<Label>Cancel</Label>
|
||||
</Button>
|
||||
|
||||
<Button on:click={shutdown}>
|
||||
<Label>Shutdown</Label>
|
||||
</Button>
|
||||
|
||||
<Button use={[InitialFocus]} on:click={restart}>
|
||||
<Label>Restart</Label>
|
||||
</Button>
|
||||
</Actions>
|
||||
</Dialog>
|
||||
83
src/svelte-components/src/dialogs/UploadDialog.svelte
Normal file
@@ -0,0 +1,83 @@
|
||||
<script lang="ts">
|
||||
import Dialog, {
|
||||
Title,
|
||||
Content,
|
||||
Actions,
|
||||
InitialFocus,
|
||||
} from "@smui/dialog";
|
||||
import Button, { Label } from "@smui/button";
|
||||
import LinearProgress from "@smui/linear-progress";
|
||||
|
||||
export let open = false;
|
||||
export let file: File;
|
||||
export let onComplete: () => void;
|
||||
|
||||
let wasOpen = false;
|
||||
let xhr;
|
||||
let progress;
|
||||
|
||||
$: if (open != wasOpen) {
|
||||
if (!wasOpen) {
|
||||
beginUpload();
|
||||
}
|
||||
|
||||
wasOpen = open;
|
||||
}
|
||||
|
||||
$: if (!open) {
|
||||
xhr = undefined;
|
||||
}
|
||||
|
||||
async function beginUpload() {
|
||||
progress = 0;
|
||||
|
||||
xhr = new XMLHttpRequest();
|
||||
xhr.upload.onload = () => {
|
||||
open = false;
|
||||
if (onComplete) {
|
||||
onComplete();
|
||||
}
|
||||
};
|
||||
|
||||
xhr.upload.onerror = () => {
|
||||
open = false;
|
||||
alert("Upload failed.");
|
||||
};
|
||||
|
||||
xhr.upload.onabort = () => {
|
||||
open = false;
|
||||
};
|
||||
|
||||
xhr.upload.onprogress = (event) => {
|
||||
progress = event.loaded / event.total;
|
||||
};
|
||||
|
||||
xhr.open("PUT", `/api/file/${encodeURIComponent(file.name)}`);
|
||||
xhr.send(file);
|
||||
}
|
||||
|
||||
function onCancel() {
|
||||
xhr.abort();
|
||||
}
|
||||
</script>
|
||||
|
||||
<Dialog
|
||||
bind:open
|
||||
scrimClickAction=""
|
||||
aria-labelledby="upload-dialog-title"
|
||||
aria-describedby="upload-dialog-content"
|
||||
>
|
||||
<Title id="upload-dialog-title">
|
||||
Uploading {#if file}{file.name}...{/if}
|
||||
</Title>
|
||||
|
||||
<Content id="upload-dialog-content">
|
||||
<LinearProgress {progress} />
|
||||
</Content>
|
||||
|
||||
<Actions>
|
||||
<Button on:click={onCancel} use={[InitialFocus]}>
|
||||
<Label>Cancel</Label>
|
||||
</Button>
|
||||
</Actions>
|
||||
</Dialog>
|
||||
112
src/svelte-components/src/dialogs/WifiConnectionDialog.svelte
Normal file
@@ -0,0 +1,112 @@
|
||||
<script lang="ts">
|
||||
import Dialog, {
|
||||
Title,
|
||||
Content,
|
||||
Actions,
|
||||
InitialFocus,
|
||||
} from "@smui/dialog";
|
||||
import Button, { Label } from "@smui/button";
|
||||
import TextField from "@smui/textfield";
|
||||
import Icon from "@smui/textfield/icon";
|
||||
import HelperText from "@smui/textfield/helper-text";
|
||||
import MessageDialog from "$dialogs/MessageDialog.svelte";
|
||||
import type { WifiNetwork } from "$lib/NetworkInfo";
|
||||
import * as api from "$lib/api";
|
||||
import { virtualKeyboardChange } from "$lib/CustomActions";
|
||||
|
||||
export let open = false;
|
||||
export let network: WifiNetwork;
|
||||
|
||||
let rebooting = false;
|
||||
let password = "";
|
||||
let showPassword = false;
|
||||
|
||||
$: needPassword = !network?.active && network?.Encryption !== "Open";
|
||||
$: connectOrDisconnect = network?.active ? "Disconnect" : "Connect";
|
||||
$: connectToOrDisconnectFrom = network?.active
|
||||
? "Disconnect from"
|
||||
: "Connect to";
|
||||
|
||||
$: if (open) {
|
||||
password = "";
|
||||
}
|
||||
|
||||
async function onConfirm() {
|
||||
rebooting = true;
|
||||
|
||||
await api.PUT("network", {
|
||||
wifi: {
|
||||
enabled: !network.active,
|
||||
ssid: network.Name,
|
||||
password,
|
||||
},
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<MessageDialog open={rebooting} title="Rebooting" noaction>
|
||||
Rebooting to apply Wifi changes...
|
||||
</MessageDialog>
|
||||
|
||||
<Dialog
|
||||
bind:open
|
||||
scrimClickAction=""
|
||||
aria-labelledby="wifi-connection-dialog-title"
|
||||
aria-describedby="wifi-connection-dialog-content"
|
||||
>
|
||||
<Title id="wifi-connection-dialog-title">
|
||||
{connectToOrDisconnectFrom}
|
||||
{network.Name}
|
||||
</Title>
|
||||
|
||||
<Content id="wifi-connection-dialog-content">
|
||||
{#if needPassword}
|
||||
<TextField
|
||||
bind:value={password}
|
||||
use={[
|
||||
InitialFocus,
|
||||
virtualKeyboardChange((v) => (password = v)),
|
||||
]}
|
||||
label="Password"
|
||||
spellcheck="false"
|
||||
variant="filled"
|
||||
type={showPassword ? "text" : "password"}
|
||||
style="width: 100%;"
|
||||
>
|
||||
<div
|
||||
slot="trailingIcon"
|
||||
on:click={() => (showPassword = !showPassword)}
|
||||
>
|
||||
<Icon
|
||||
class={`fa ${showPassword ? "fa-eye-slash" : "fa-eye"}`}
|
||||
/>
|
||||
</div>
|
||||
<HelperText persistent slot="helper">
|
||||
Wifi passwords must be 8 to 128 characters
|
||||
</HelperText>
|
||||
</TextField>
|
||||
{/if}
|
||||
|
||||
<p>
|
||||
<em>
|
||||
Clicking {connectOrDisconnect} will reboot the controller to apply
|
||||
the changes.
|
||||
</em>
|
||||
</p>
|
||||
</Content>
|
||||
|
||||
<Actions>
|
||||
<Button>
|
||||
<Label>Cancel</Label>
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
defaultAction
|
||||
on:click={onConfirm}
|
||||
disabled={needPassword &&
|
||||
(password.length < 8 || password.length > 128)}
|
||||
>
|
||||
<Label>{connectOrDisconnect} & Reboot</Label>
|
||||
</Button>
|
||||
</Actions>
|
||||
</Dialog>
|
||||
14
src/svelte-components/src/lib/ConfigStore.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import { writable } from "svelte/store";
|
||||
|
||||
type DisplayUnits = "METRIC" | "IMPERIAL";
|
||||
|
||||
export const Config = writable<Record<string, any>>({});
|
||||
export const DisplayUnits = writable<DisplayUnits>();
|
||||
|
||||
export function handleConfigUpdate(config: Record<string, any>) {
|
||||
Config.set(config);
|
||||
}
|
||||
|
||||
export function setDisplayUnits(value: DisplayUnits) {
|
||||
DisplayUnits.set(value);
|
||||
}
|
||||
32
src/svelte-components/src/lib/ControllerState.ts
Normal file
@@ -0,0 +1,32 @@
|
||||
import { get, writable } from "svelte/store";
|
||||
import { processNetworkInfo } from "./NetworkInfo";
|
||||
|
||||
export const networkInfo = writable({});
|
||||
|
||||
export const probingActive = writable(false);
|
||||
export const probeContacted = writable(false);
|
||||
export const probingStarted = writable(false);
|
||||
export const probingFailed = writable(false);
|
||||
export const probingComplete = writable(false);
|
||||
|
||||
export function handleControllerStateUpdate(state: Record<string, any>) {
|
||||
|
||||
if (get(probingActive)) {
|
||||
if (state.pw === 0) {
|
||||
probeContacted.set(true);
|
||||
}
|
||||
|
||||
if (state.log?.msg === "Switch not found") {
|
||||
probingFailed.set(true);
|
||||
}
|
||||
|
||||
if (state.cycle !== "idle") {
|
||||
probingStarted.set(true);
|
||||
}
|
||||
|
||||
if (state.cycle === "idle" && get(probingStarted)) {
|
||||
probingStarted.set(false);
|
||||
probingComplete.set(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
15
src/svelte-components/src/lib/CustomActions.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import type { HTMLActionEntry } from "@smui/common/internal";
|
||||
|
||||
export function virtualKeyboardChange(cb: (v: any) => void): HTMLActionEntry {
|
||||
const func = (node: HTMLElement, cb: (value: any) => void) => {
|
||||
const input = node.querySelector("input");
|
||||
if (!input) {
|
||||
console.error("Could not find the textfield's <input>:", node);
|
||||
throw new Error("Could not find the textfield's <input>");
|
||||
}
|
||||
|
||||
input.addEventListener("keyup", () => cb(input.value));
|
||||
};
|
||||
|
||||
return [ func, cb ];
|
||||
}
|
||||
81
src/svelte-components/src/lib/NetworkInfo.ts
Normal file
@@ -0,0 +1,81 @@
|
||||
import { writable } from "svelte/store";
|
||||
|
||||
export type WifiNetwork = {
|
||||
Quality: string;
|
||||
Channel: string;
|
||||
Frequency: string;
|
||||
Mode: string;
|
||||
"Bit Rates": string;
|
||||
Name: string;
|
||||
Address: string;
|
||||
Encryption: string;
|
||||
"Signal Level": string;
|
||||
"Noise Level": string;
|
||||
lastSeen: number;
|
||||
active: boolean;
|
||||
};
|
||||
|
||||
export type NetworkInfo = {
|
||||
ipAddresses: Array<string>;
|
||||
hostname: string;
|
||||
wifi: {
|
||||
ssid: string;
|
||||
networks: Array<WifiNetwork>;
|
||||
};
|
||||
};
|
||||
|
||||
const empty: NetworkInfo = {
|
||||
ipAddresses: [],
|
||||
hostname: "",
|
||||
wifi: {
|
||||
ssid: "",
|
||||
networks: []
|
||||
}
|
||||
};
|
||||
|
||||
export const networkInfo = writable<NetworkInfo>(empty);
|
||||
|
||||
export function processNetworkInfo(rawNetworkInfo: NetworkInfo) {
|
||||
const now = Date.now();
|
||||
const networksByName: Record<string, WifiNetwork> = {};
|
||||
|
||||
for (const network of rawNetworkInfo.wifi.networks) {
|
||||
if (network.Name) {
|
||||
network.lastSeen = now;
|
||||
network.active = rawNetworkInfo.wifi.ssid === network.Name;
|
||||
|
||||
// There can be many entries for the same ssid, so
|
||||
// we want to take the one with the highest quality
|
||||
const currentNetwork = networksByName[network.Name] ?? { Quality: 0 };
|
||||
if (network.Quality >= currentNetwork.Quality) {
|
||||
networksByName[network.Name] = network;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const network of Object.values(networksByName)) {
|
||||
if (network.lastSeen - now > 30000) {
|
||||
delete networksByName[network.Name];
|
||||
}
|
||||
}
|
||||
|
||||
networkInfo.set({
|
||||
ipAddresses: rawNetworkInfo.ipAddresses,
|
||||
hostname: rawNetworkInfo.hostname,
|
||||
wifi: {
|
||||
ssid: rawNetworkInfo.wifi.ssid,
|
||||
networks: Object.values(networksByName).sort((a, b) => {
|
||||
switch (true) {
|
||||
case a.active:
|
||||
return -1;
|
||||
|
||||
case b.active:
|
||||
return 1;
|
||||
|
||||
default:
|
||||
return a.Name.localeCompare(b.Name);
|
||||
}
|
||||
})
|
||||
}
|
||||
});
|
||||
}
|
||||
85
src/svelte-components/src/lib/RegexHelpers.ts
Normal file
@@ -0,0 +1,85 @@
|
||||
function numberWithUnitToMetric() {
|
||||
return this.metric ? this.value : this.value * 25.4;
|
||||
}
|
||||
|
||||
function isPojo(value) {
|
||||
if (value === null || typeof value !== "object") {
|
||||
return false;
|
||||
}
|
||||
|
||||
return Object.getPrototypeOf(value) === Object.prototype;
|
||||
}
|
||||
|
||||
const fractions = [
|
||||
{ value: 0.75, formatted: "3/4" },
|
||||
{ value: 0.625, formatted: "5/8" },
|
||||
{ value: 0.5, formatted: "1/2" },
|
||||
{ value: 0.375, formatted: "3/8" },
|
||||
{ value: 0.25, formatted: "1/4" },
|
||||
{ value: 0.1875, formatted: "3/16" },
|
||||
{ value: 0.125, formatted: "1/8" },
|
||||
{ value: 0.09375, formatted: "3/32" },
|
||||
{ value: 0.0625, formatted: "1/16" },
|
||||
{ value: 0.03125, formatted: "1/32" },
|
||||
];
|
||||
|
||||
function formatFraction(value: number) {
|
||||
const fraction = fractions.find(f => f.value === value);
|
||||
|
||||
return fraction ? fraction.formatted : value.toString();
|
||||
}
|
||||
|
||||
export const numberWithUnit = {
|
||||
regex: /^\s*(?:(\d+)\s*\/\s*(\d+)|(\d*\.\d+)|(\d+(?:\.\d+)?))\s*("|in|inch|inches|mm|millimeters)\s*$/,
|
||||
parse: function(str: string) {
|
||||
// eslint-disable-next-line prefer-const
|
||||
let [ , numerator, denominator, decimal1, decimal2, unit ]: any = str?.match(numberWithUnit.regex) ?? [];
|
||||
|
||||
numerator = Number.parseFloat(numerator);
|
||||
denominator = Number.parseFloat(denominator);
|
||||
decimal1 = Number.parseFloat(decimal1);
|
||||
decimal2 = Number.parseFloat(decimal2);
|
||||
|
||||
const metric = (unit ?? "").includes("m");
|
||||
|
||||
switch (true) {
|
||||
case isFinite(numerator) && isFinite(denominator):
|
||||
return {
|
||||
value: numerator / denominator,
|
||||
metric,
|
||||
toMetric: numberWithUnitToMetric
|
||||
};
|
||||
|
||||
case isFinite(decimal1) && decimal1 !== 0:
|
||||
return {
|
||||
value: decimal1,
|
||||
metric,
|
||||
toMetric: numberWithUnitToMetric
|
||||
};
|
||||
|
||||
case isFinite(decimal2) && decimal2 !== 0:
|
||||
return {
|
||||
value: decimal2,
|
||||
metric,
|
||||
toMetric: numberWithUnitToMetric
|
||||
};
|
||||
|
||||
default:
|
||||
return undefined;
|
||||
}
|
||||
},
|
||||
normalize: function(str) {
|
||||
const value = this.parse(str);
|
||||
|
||||
switch (true) {
|
||||
case !isPojo(value):
|
||||
return "";
|
||||
|
||||
case value.metric:
|
||||
return `${value.value} mm`;
|
||||
|
||||
default:
|
||||
return `${formatFraction(value.value)} in`;
|
||||
}
|
||||
}
|
||||
};
|
||||
44
src/svelte-components/src/lib/RegisterControllerMethods.ts
Normal file
@@ -0,0 +1,44 @@
|
||||
interface RegisterableControllerMethods {
|
||||
stop: () => void;
|
||||
send: (gcode: string) => void;
|
||||
dispatch: (event: string, ...args: any[]) => void;
|
||||
isAxisHomed: (axis: string) => boolean;
|
||||
unhome: (axis: string) => void;
|
||||
set_position: (axis: string, value: number) => void;
|
||||
set_home: (axis: string, value: number) => void;
|
||||
}
|
||||
|
||||
interface ControllerMethods extends RegisterableControllerMethods {
|
||||
gotoZero: (axes: "xy" | "z") => void;
|
||||
}
|
||||
|
||||
export let ControllerMethods: ControllerMethods;
|
||||
|
||||
export function registerControllerMethods(methods: Partial<RegisterableControllerMethods>) {
|
||||
ControllerMethods = {
|
||||
...ControllerMethods,
|
||||
...methods,
|
||||
gotoZero
|
||||
};
|
||||
}
|
||||
|
||||
function gotoZero(axes: "xy" | "z") {
|
||||
let axesClause = "";
|
||||
switch (axes.toLowerCase()) {
|
||||
case "xy":
|
||||
axesClause = "X0Y0";
|
||||
break;
|
||||
|
||||
case "z":
|
||||
axesClause = "Z0";
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new Error(`Invalid axes: ${axes}`);
|
||||
}
|
||||
|
||||
ControllerMethods.send(`
|
||||
G90
|
||||
G0 ${axesClause}
|
||||
`);
|
||||
}
|
||||
18
src/svelte-components/src/lib/StoreHelpers.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import { get, type Writable } from "svelte/store";
|
||||
|
||||
export function listenForChange<T>(writable: Writable<T>, cb: (value: T) => void) {
|
||||
const priorValue = get(writable);
|
||||
|
||||
const unsubscribe = writable.subscribe((value) => {
|
||||
if (value !== priorValue) {
|
||||
unsubscribe();
|
||||
cb(value);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export function waitForChange<T>(writable: Writable<T>): Promise<T> {
|
||||
return new Promise((resolve) => {
|
||||
listenForChange(writable, (value) => resolve(value));
|
||||
});
|
||||
}
|
||||
41
src/svelte-components/src/lib/api.ts
Normal file
@@ -0,0 +1,41 @@
|
||||
type HttpMethod = "GET" | "PUT" | "POST" | "DELETE";
|
||||
|
||||
async function doFetch(method: HttpMethod, url: string, data: any, config: RequestInit) {
|
||||
try {
|
||||
const response = await fetch(`/api/${url}`, {
|
||||
...config,
|
||||
method,
|
||||
cache: "no-cache",
|
||||
body: (typeof data === "object")
|
||||
? JSON.stringify(data)
|
||||
: undefined,
|
||||
headers: (typeof data === "object")
|
||||
? {
|
||||
"Content-Type": "application/json; charset=utf-8"
|
||||
}
|
||||
: {}
|
||||
});
|
||||
|
||||
return await response.json();
|
||||
} catch (error) {
|
||||
console.debug(`API Error: ${url}: ${error}`);
|
||||
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
export function GET(url: string, config: RequestInit = {}) {
|
||||
return doFetch("GET", url, undefined, config);
|
||||
}
|
||||
|
||||
export function PUT(url: string, data: any = undefined, config: RequestInit = {}) {
|
||||
return doFetch("PUT", url, data, config);
|
||||
}
|
||||
|
||||
export function POST(url: string, data: any = undefined, config: RequestInit = {}) {
|
||||
return doFetch("POST", url, data, config);
|
||||
}
|
||||
|
||||
export function DELETE(url: string, config = {}) {
|
||||
return doFetch("DELETE", url, undefined, config);
|
||||
}
|
||||
39
src/svelte-components/src/main.ts
Normal file
@@ -0,0 +1,39 @@
|
||||
import "polyfill-object.fromentries";
|
||||
import matchAll from "string.prototype.matchall";
|
||||
|
||||
matchAll.shim();
|
||||
|
||||
import AdminNetworkView from "$components/AdminNetworkView.svelte";
|
||||
import SettingsView from "$components/SettingsView.svelte";
|
||||
import HelpView from "$components/HelpView.svelte";
|
||||
import DialogHost, { showDialog } from "$dialogs/DialogHost.svelte";
|
||||
import { handleConfigUpdate, setDisplayUnits } from "$lib/ConfigStore";
|
||||
import { handleControllerStateUpdate } from "$lib/ControllerState";
|
||||
import { registerControllerMethods } from "$lib/RegisterControllerMethods";
|
||||
|
||||
export function createComponent(component: string, target: HTMLElement, props: Record<string, any>) {
|
||||
switch (component) {
|
||||
case "AdminNetworkView":
|
||||
return new AdminNetworkView({ target, props });
|
||||
|
||||
case "SettingsView":
|
||||
return new SettingsView({ target, props });
|
||||
|
||||
case "HelpView":
|
||||
return new HelpView({ target, props });
|
||||
|
||||
case "DialogHost":
|
||||
return new DialogHost({ target, props });
|
||||
|
||||
default:
|
||||
throw new Error("Unknown component");
|
||||
}
|
||||
}
|
||||
|
||||
export {
|
||||
showDialog,
|
||||
handleControllerStateUpdate,
|
||||
handleConfigUpdate,
|
||||
registerControllerMethods,
|
||||
setDisplayUnits
|
||||
};
|
||||
75
src/svelte-components/src/svgs/probe-bit-diameter.svg
Normal file
@@ -0,0 +1,75 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?><svg id="Layer_1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100.88 191.47">
|
||||
<polygon
|
||||
points="21.64 186.89 12.57 189.89 3.5 186.89 3.5 88.81 1.5 85.76 1.5 1.5 23.64 1.5 23.64 85.76 21.64 88.81 21.64 186.89"
|
||||
style="fill:#fff; stroke:#231f20; stroke-miterlimit:10; stroke-width:3px;" />
|
||||
<line x1="3.5" y1="88.81" x2="21.64" y2="88.81"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10; stroke-width:3px;" />
|
||||
<line x1="3.5" y1="185.56" x2="21.64" y2="177.06"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<line x1="3.5" y1="174.91" x2="21.64" y2="166.4"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<line x1="3.5" y1="164.21" x2="21.64" y2="155.71"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<line x1="3.5" y1="153.6" x2="21.64" y2="145.09"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<line x1="3.5" y1="142.9" x2="21.64" y2="134.4"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<line x1="3.5" y1="131.88" x2="21.64" y2="123.37"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<line x1="3.5" y1="121.18" x2="21.64" y2="112.68"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<line x1="3.5" y1="110.57" x2="21.64" y2="102.06"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<line x1="3.5" y1="99.87" x2="21.64" y2="91.37"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<g>
|
||||
<line x1="27.28" y1="1.5" x2="29.78" y2="1.5"
|
||||
style="fill:none; stroke:#a7a9ac; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<line x1="31.28" y1="1.5" x2="38.5" y2="1.5"
|
||||
style="fill:none; stroke:#a7a9ac; stroke-dasharray:0 0 0 0 2.49 1.5 2.49 1.5; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<polyline points="39.25 1.5 41.75 1.5 41.75 4"
|
||||
style="fill:none; stroke:#a7a9ac; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<line x1="41.75" y1="6.64" x2="41.75" y2="19.39"
|
||||
style="fill:none; stroke:#a7a9ac; stroke-dasharray:0 0 0 0 4.4 2.64 4.4 2.64; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<line x1="41.75" y1="20.71" x2="41.75" y2="82.72"
|
||||
style="fill:none; stroke:#a7a9ac; stroke-dasharray:0 0 0 0 0 0 4.4 2.64 4.4 2.64 4.4 2.64; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<polyline points="41.75 84.04 41.75 86.54 39.25 86.54"
|
||||
style="fill:none; stroke:#a7a9ac; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<line x1="37.76" y1="86.54" x2="30.53" y2="86.54"
|
||||
style="fill:none; stroke:#a7a9ac; stroke-dasharray:0 0 0 0 2.49 1.5 2.49 1.5; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<line x1="29.78" y1="86.54" x2="27.28" y2="86.54"
|
||||
style="fill:none; stroke:#a7a9ac; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
</g>
|
||||
<g>
|
||||
<line x1="27.28" y1="90.04" x2="29.78" y2="90.04"
|
||||
style="fill:none; stroke:#a7a9ac; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<line x1="30.59" y1="90.04" x2="34.53" y2="90.04"
|
||||
style="fill:none; stroke:#a7a9ac; stroke-dasharray:0 0 0 0 1.36 .81 1.36 .81; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<polyline points="34.94 90.04 37.44 90.04 37.44 92.54"
|
||||
style="fill:none; stroke:#a7a9ac; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<line x1="37.44" y1="95.64" x2="37.44" y2="110.63"
|
||||
style="fill:none; stroke:#a7a9ac; stroke-dasharray:0 0 0 0 5.17 3.1 5.17 3.1; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<line x1="37.44" y1="112.18" x2="37.44" y2="185.03"
|
||||
style="fill:none; stroke:#a7a9ac; stroke-dasharray:0 0 0 0 0 0 5.17 3.1 5.17 3.1 5.17 3.1; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<polyline points="37.44 186.58 37.44 189.08 34.94 189.08"
|
||||
style="fill:none; stroke:#a7a9ac; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<line x1="34.13" y1="189.08" x2="30.22" y2="189.08"
|
||||
style="fill:none; stroke:#a7a9ac; stroke-dasharray:0 0 0 0 1.35 .81 1.35 .81; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<line x1="29.81" y1="189.08" x2="27.31" y2="189.08"
|
||||
style="fill:none; stroke:#a7a9ac; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
</g>
|
||||
<line x1="41.75" y1="44.02" x2="56.79" y2="44.02"
|
||||
style="fill:none; stroke:#a7a9ac; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<line x1="37.44" y1="138.65" x2="56.79" y2="138.65"
|
||||
style="fill:none; stroke:#a7a9ac; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<circle cx="78.33" cy="44.02" r="21.54"
|
||||
style="fill:none; stroke:#a7a9ac; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<circle cx="78.33" cy="138.65" r="21.54"
|
||||
style="fill:none; stroke:#a7a9ac; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<line x1="68.56" y1="34.24" x2="88.11" y2="53.8"
|
||||
style="fill:none; stroke:#be1e2d; stroke-miterlimit:10; stroke-width:4px;" />
|
||||
<line x1="88.11" y1="34.24" x2="68.56" y2="53.8"
|
||||
style="fill:none; stroke:#be1e2d; stroke-miterlimit:10; stroke-width:4px;" />
|
||||
<polyline points="64.73 141.61 72.43 149.31 91.94 129.81"
|
||||
style="fill:none; stroke:#00a651; stroke-miterlimit:10; stroke-width:4px;" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 5.4 KiB |
243
src/svelte-components/src/svgs/probe-check-xyz.svg
Normal file
@@ -0,0 +1,243 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?><svg id="Layer_1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 307.88 290.65">
|
||||
<g>
|
||||
<polygon
|
||||
points="306.38 163.14 243.73 245.91 98.03 245.91 98.03 230.65 160.68 147.88 306.38 147.88 306.38 163.14"
|
||||
style="fill:#fff; stroke:#231f20; stroke-miterlimit:10; stroke-width:3px;" />
|
||||
<polyline points="306.38 147.88 243.73 230.65 98.03 230.65"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10; stroke-width:3px;" />
|
||||
<line x1="243.73" y1="230.65" x2="243.73" y2="245.91"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10; stroke-width:3px;" />
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<line x1="146.89" y1="186.96" x2="146.89" y2="190.46"
|
||||
style="fill:none; stroke:#37b34a; stroke-miterlimit:10; stroke-width:1.75px;" />
|
||||
<line x1="146.89" y1="191.76" x2="146.89" y2="202.85"
|
||||
style="fill:none; stroke:#37b34a; stroke-dasharray:0 0 0 0 4.56 1.3 4.56 1.3; stroke-miterlimit:10; stroke-width:1.75px;" />
|
||||
<line x1="146.89" y1="203.5" x2="146.89" y2="207"
|
||||
style="fill:none; stroke:#37b34a; stroke-miterlimit:10; stroke-width:1.75px;" />
|
||||
</g>
|
||||
<polyline points="142.67 191.08 146.89 185.87 150.95 190.95"
|
||||
style="fill:none; stroke:#37b34a; stroke-miterlimit:10; stroke-width:1.75px;" />
|
||||
</g>
|
||||
<g>
|
||||
<polygon points="150.06 174.24 132.23 197.79 90.77 197.79 90.77 186.45 108.6 162.89 150.06 162.89 150.06 174.24"
|
||||
style="fill:#fff; stroke:#231f20; stroke-miterlimit:10; stroke-width:3px;" />
|
||||
<polyline points="150.06 162.89 132.23 186.45 90.77 186.45"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10; stroke-width:3px;" />
|
||||
<line x1="132.23" y1="186.45" x2="132.23" y2="197.79"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10; stroke-width:3px;" />
|
||||
<ellipse cx="138.4" cy="167.46" rx="3.83" ry="1.56" style="fill:none; stroke:#231f20; stroke-miterlimit:10;" />
|
||||
<circle cx="110.61" cy="192.12" r="3.12" style="fill:none; stroke:#231f20; stroke-miterlimit:10;" />
|
||||
<g>
|
||||
<polygon points="123.91 172.78 120.77 169.36 118.81 171.98 121.94 175.4 123.91 172.78"
|
||||
style="fill:#29b473; opacity:.42;" />
|
||||
<polygon points="120.79 176.92 117.66 173.5 115.69 176.12 118.83 179.54 120.79 176.92"
|
||||
style="fill:#29b473; opacity:.42;" />
|
||||
<polygon points="117.09 181.85 117.68 181.06 114.55 177.65 111.39 181.85 114.47 181.55 117.09 181.85"
|
||||
style="fill:#29b473; opacity:.42;" />
|
||||
<polygon points="127.88 167.49 122.18 167.49 121.92 167.84 125.05 171.25 127.88 167.49"
|
||||
style="fill:#29b473; opacity:.42;" />
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<g>
|
||||
<path
|
||||
d="M1.25,178.73c8.14-4.37,16.49-8.51,25.42-10.9s16.85-8.86,25.66-6.05c3.11,.99,4.86,.29,7.84,1.63,7.16,3.22,14.5,6.16,22.19,7.73,.92,.19,1.85,.36,2.75,.64,.76,.24,1.49,.57,2.23,.85,3.03,1.13,6.35,1.46,9.56,1.07,1.51-.18,3.03-.52,4.52-.25s2.98,1.36,3.1,2.87c.15,1.87-1.69,3.22-3.31,4.16-5.19,3.04-10.67,6.16-16.68,6.31-1.06,.03-2.12-.04-3.16,.13-.96,.16-1.87,.52-2.8,.81-5.16,1.61-10.98,.91-15.62-1.86-.45-.27-.97-.56-1.45-.36-.27,.11-.46,.36-.64,.6-5.22,6.94-13.45,11.53-22.1,12.33"
|
||||
style="fill:#fff;" />
|
||||
<path
|
||||
d="M1.88,179.81c5.74-3.07,11.56-6.05,17.66-8.36,2.91-1.1,5.89-1.89,8.85-2.83,2.68-.84,5.25-1.98,7.82-3.08s5.22-2.2,7.99-2.8,5.43-.39,8.23,.37c2.52,.69,5.09,.51,7.53,1.56,2.93,1.27,5.84,2.56,8.82,3.7s6.08,2.19,9.2,3.02c1.49,.4,2.99,.73,4.5,1.04,1.66,.34,3.14,.9,4.73,1.47,2.8,1,5.85,1.37,8.81,1.13,1.5-.12,2.99-.5,4.5-.43,1.2,.05,3.18,.83,2.69,2.38-.36,1.13-1.67,1.85-2.62,2.42-1.33,.79-2.68,1.56-4.05,2.3-2.68,1.44-5.47,2.72-8.45,3.39s-6.08,.21-9.05,1.18-5.77,1.32-8.75,.89c-1.5-.22-3-.62-4.4-1.2s-2.85-1.93-4.35-1.72c-1.35,.19-2.09,1.71-2.9,2.64-.98,1.12-2.04,2.17-3.17,3.15-4.66,4.01-10.59,6.55-16.7,7.15-1.59,.16-1.6,2.66,0,2.5,5.78-.57,11.36-2.61,16.08-6.01,2.3-1.65,4.4-3.57,6.18-5.77,.18-.22,.7-1.1,.95-1.15,.34-.07,1.44,.81,1.81,.98,1.47,.71,3.01,1.26,4.61,1.6,2.93,.63,5.97,.65,8.91,.02,1.49-.32,2.91-1.01,4.41-1.23,1.65-.24,3.34-.05,5-.27,3.13-.41,6.08-1.52,8.91-2.88s5.65-2.73,7.99-4.62c2.05-1.66,3.05-4.46,1-6.58-2.35-2.43-5.65-1.48-8.6-1.24-3.43,.27-6.5-.44-9.69-1.64s-6.65-1.57-9.9-2.54-6.43-2.13-9.56-3.41c-1.61-.66-3.21-1.34-4.8-2.05-1.38-.61-2.73-1.24-4.23-1.49-1.3-.22-2.63-.22-3.92-.5-1.45-.31-2.83-.8-4.32-.97-2.8-.32-5.64,.17-8.31,1-3.25,1.01-6.32,2.49-9.46,3.78-3.37,1.38-6.89,2.22-10.33,3.39-7.25,2.48-14.12,5.94-20.86,9.55-1.42,.76-.16,2.92,1.26,2.16h0Z"
|
||||
style="fill:#231f20;" />
|
||||
</g>
|
||||
<g>
|
||||
<path
|
||||
d="M90.74,193.11c-1.29,.17-2.57,.39-3.84,.65-.92,.19-1.85,.39-2.79,.36-.92-.04-1.82-.31-2.72-.51-4.42-.97-7.32-.5-11.78,.27"
|
||||
style="fill:#fff;" />
|
||||
<path
|
||||
d="M90.41,191.9c-1.83,.25-3.67,.77-5.5,.93s-3.78-.62-5.62-.86c-3.38-.43-6.69,.12-10.01,.69-1.58,.27-.91,2.68,.66,2.41,3.37-.58,6.73-1.08,10.14-.47,1.83,.33,3.52,.91,5.4,.66s3.72-.7,5.6-.96c1.59-.22,.91-2.63-.66-2.41h0Z"
|
||||
style="fill:#231f20;" />
|
||||
</g>
|
||||
<g>
|
||||
<path
|
||||
d="M69.76,187.81c-1.62,2.32-1,5.49-1.75,8.21-.39,1.43-1.18,2.75-1.38,4.22-.21,1.55,.25,3.1,.55,4.63,.07,.36,.13,.74,0,1.09-.11,.31-.36,.55-.59,.8-1.37,1.46-2.16,3.44-2.16,5.44"
|
||||
style="fill:#fff;" />
|
||||
<path
|
||||
d="M68.68,187.18c-1.16,1.8-1.31,3.87-1.49,5.95-.09,1.07-.22,2.11-.57,3.14-.37,1.08-.89,2.12-1.12,3.24s-.17,2.25,.01,3.38c.1,.62,.27,1.23,.37,1.85,.12,.73,.02,.88-.44,1.43-1.45,1.71-2.2,3.8-2.26,6.03-.04,1.61,2.46,1.61,2.5,0,.03-1.13,.28-2.2,.82-3.2,.48-.88,1.34-1.51,1.76-2.41,.38-.82,.19-1.66,.03-2.51-.26-1.28-.63-2.59-.39-3.9,.36-1.96,1.39-3.66,1.65-5.68s.12-4.25,1.28-6.06c.88-1.36-1.29-2.61-2.16-1.26h0Z"
|
||||
style="fill:#231f20;" />
|
||||
</g>
|
||||
<g>
|
||||
<path
|
||||
d="M67.04,206.15c1.3-.46,2.66-.76,4.03-.87,.35-.03,.69-.05,1.03-.11,.48-.09,.93-.27,1.39-.44,3.91-1.5,8.12-2.77,12.23-2.02"
|
||||
style="fill:#fff;" />
|
||||
<path
|
||||
d="M67.37,207.35c1.57-.54,3.1-.69,4.72-.93,1.39-.21,2.71-.89,4.04-1.33,2.97-.99,6.13-1.71,9.26-1.18,1.57,.27,2.25-2.14,.66-2.41-3.36-.57-6.69-.06-9.92,.96-1.44,.46-2.88,1.23-4.37,1.5-1.73,.31-3.37,.4-5.07,.98-1.51,.52-.86,2.94,.66,2.41h0Z"
|
||||
style="fill:#231f20;" />
|
||||
</g>
|
||||
<g>
|
||||
<path
|
||||
d="M58.89,226.43c-2.05-4.85,.54-11.14,5.42-13.14,2.12-.87,4.51-.99,6.57-2,2.05-1,3.61-2.78,5.6-3.89,2.67-1.49,5.93-1.66,8.55-3.22,1.82-1.08,3.21-2.76,4.88-4.07,2.03-1.59,4.44-2.59,6.82-3.58,1.75-.73,3.72-1.46,5.49-.79,2.12,.8,3.09,3.41,2.7,5.64s-1.83,4.12-3.34,5.8c-7.7,8.57-18.19,14.03-28.44,19.3-2.72,1.4-5.45,2.8-8.28,3.96-2.26,.92-4.6,1.69-6.7,2.94-1.64,.98-3.1,2.23-4.66,3.35-5.43,3.91-11.97,6.11-18.6,6.96-6.63,.86-13.38,.43-19.99-.57"
|
||||
style="fill:#fff;" />
|
||||
<path
|
||||
d="M60.1,226.09c-1.55-3.87-.15-8.67,3.4-10.97,2.14-1.39,4.8-1.45,7.13-2.37s4.01-2.79,6.14-4.07c2.27-1.37,4.99-1.67,7.41-2.69s4.22-3.03,6.29-4.72,4.72-2.79,7.21-3.78c2.31-.91,5.06-1.29,5.9,1.63,.7,2.44-.84,4.79-2.36,6.57-1.71,2.01-3.64,3.85-5.65,5.56-4.04,3.43-8.55,6.28-13.16,8.88s-9.7,5.28-14.66,7.65c-2.68,1.28-5.5,2.22-8.2,3.46-2.54,1.16-4.6,2.92-6.86,4.52-10.84,7.7-24.78,8.03-37.46,6.14-1.57-.23-2.25,2.17-.66,2.41,12.35,1.84,25.58,1.74,36.69-4.67,2.65-1.53,4.89-3.64,7.52-5.2,2.79-1.66,5.97-2.56,8.92-3.9,5.5-2.5,10.9-5.39,16.16-8.37s9.92-6.02,14.27-9.85c3.62-3.19,8.96-7.83,8-13.24-.39-2.22-1.92-4.25-4.2-4.73-2.8-.6-5.73,.98-8.21,2.11-2.8,1.27-4.98,2.98-7.24,5.02-1.1,.99-2.27,1.84-3.66,2.37s-2.94,.87-4.39,1.36-2.72,1.1-3.93,1.98c-1.3,.94-2.48,2.07-3.9,2.83-2.74,1.46-6.03,1.3-8.65,3.12-4.22,2.94-6.21,8.78-4.27,13.61,.59,1.47,3.01,.83,2.41-.66h0Z"
|
||||
style="fill:#231f20;" />
|
||||
</g>
|
||||
<g>
|
||||
<path
|
||||
d="M110.32,191.95c2.31,.23,4.18,2.27,4.64,4.55s-.3,4.67-1.62,6.57c-1.32,1.91-3.14,3.4-5.01,4.77-6.3,4.62-13.39,8.15-20.87,10.4"
|
||||
style="fill:#fff;" />
|
||||
<path
|
||||
d="M109.98,193.15c3.4,.48,4.45,4.11,3.45,7.02-1.14,3.32-4.23,5.56-6.99,7.49-5.91,4.13-12.43,7.28-19.32,9.38-1.53,.47-.88,2.88,.66,2.41,8.11-2.47,15.89-6.34,22.57-11.59,3.04-2.38,5.73-5.52,5.97-9.55,.21-3.46-2.09-7.07-5.68-7.57-1.57-.22-2.25,2.19-.66,2.41h0Z"
|
||||
style="fill:#231f20;" />
|
||||
</g>
|
||||
<g>
|
||||
<path d="M85.05,190.29l-.83,3.58" style="fill:#fff;" />
|
||||
<path
|
||||
d="M83.84,189.96l-.83,3.58c-.15,.64,.2,1.38,.87,1.54,.64,.15,1.38-.19,1.54-.87l.83-3.58c.15-.64-.2-1.38-.87-1.54-.64-.15-1.38,.19-1.54,.87h0Z"
|
||||
style="fill:#231f20;" />
|
||||
</g>
|
||||
<g>
|
||||
<path d="M84.5,198.52c-.06,.99-.02,1.98,.13,2.96" style="fill:#fff;" />
|
||||
<path
|
||||
d="M83.25,198.52c-.07,1.1,0,2.2,.17,3.29,.04,.29,.33,.61,.57,.75,.27,.16,.66,.22,.96,.13s.59-.29,.75-.57l.13-.3c.06-.22,.06-.44,0-.66-.01-.08-.02-.15-.03-.23l.04,.33c-.12-.9-.15-1.82-.1-2.73,.02-.31-.15-.67-.37-.88s-.57-.38-.88-.37-.66,.12-.88,.37-.34,.54-.37,.88h0Z"
|
||||
style="fill:#231f20;" />
|
||||
</g>
|
||||
<g>
|
||||
<path d="M72.52,210.78c-.46,1.52-.91,3.05-1.05,4.64s.08,3.24,.9,4.6" style="fill:#fff;" />
|
||||
<path
|
||||
d="M71.31,210.44c-.99,3.32-1.88,7-.02,10.2,.81,1.39,2.97,.13,2.16-1.26-1.47-2.53-.52-5.62,.28-8.27,.19-.65-.23-1.36-.87-1.54s-1.34,.22-1.54,.87h0Z"
|
||||
style="fill:#231f20;" />
|
||||
</g>
|
||||
<g>
|
||||
<path d="M84.74,205.93c-.61,1.54-.48,3.36,.34,4.8" style="fill:#fff;" />
|
||||
<path
|
||||
d="M83.54,205.6c-.71,1.86-.5,4.03,.46,5.76,.32,.57,1.15,.81,1.71,.45s.79-1.1,.45-1.71c-.05-.09-.1-.18-.15-.28-.02-.05-.05-.09-.07-.14-.05-.12-.04-.1,.03,.08,.01-.04-.08-.21-.1-.26-.03-.09-.06-.17-.08-.26-.06-.2-.11-.41-.14-.61v-.08c-.03-.14-.03-.1,0,.1,.02-.09-.02-.22-.03-.31-.01-.18-.01-.37,0-.55,0-.11,0-.21,.02-.31,0-.05,0-.1,.02-.16-.03,.2-.03,.23-.01,.1,.07-.39,.17-.77,.31-1.14,.23-.61-.26-1.4-.87-1.54-.71-.16-1.29,.22-1.54,.87h0Z"
|
||||
style="fill:#231f20;" />
|
||||
</g>
|
||||
<g>
|
||||
<path d="M52.32,198.92c-4.57,5.84-6,13.57-6.04,20.99-.02,2.89,.15,5.85-.65,8.63" style="fill:#fff;" />
|
||||
<path
|
||||
d="M51.25,198.29c-3.09,4.01-4.82,8.88-5.6,13.85-.38,2.44-.58,4.9-.61,7.36-.04,2.92,.16,5.85-.61,8.71-.42,1.56,1.99,2.22,2.41,.66,.71-2.63,.7-5.34,.69-8.04,0-2.54,.09-5.09,.46-7.61,.72-4.93,2.35-9.68,5.41-13.66,.98-1.27-1.19-2.52-2.16-1.26h0Z"
|
||||
style="fill:#231f20;" />
|
||||
</g>
|
||||
<g>
|
||||
<path d="M43.94,197.7c-.58,3.78-3.36,6.94-6.64,8.9s-7.05,2.93-10.75,3.87" style="fill:#fff;" />
|
||||
<path
|
||||
d="M42.73,197.37c-1.3,7.8-9.97,10.24-16.52,11.9-1.56,.39-.9,2.81,.66,2.41,4.15-1.05,8.48-2.15,12.04-4.64,3.06-2.14,5.59-5.25,6.22-9.01,.26-1.57-2.15-2.25-2.41-.66h0Z"
|
||||
style="fill:#231f20;" />
|
||||
</g>
|
||||
<g>
|
||||
<path
|
||||
d="M91.16,173.72c.9,.4,1.5,1.25,2.27,1.85,1.63,1.28,3.91,1.36,5.95,.98,.45-.08,.91-.19,1.3-.43s.71-.64,.75-1.1c.06-.7-.53-1.28-1.06-1.74"
|
||||
style="fill:#fff;" />
|
||||
<path
|
||||
d="M90.53,174.79c.58,.28,.96,.69,1.44,1.14s1.03,.91,1.63,1.22c1.28,.66,2.75,.9,4.19,.83s3.25-.23,4.25-1.39c.56-.65,.78-1.51,.56-2.34-.2-.75-.77-1.36-1.34-1.86-.51-.44-1.27-.5-1.77,0-.45,.45-.51,1.32,0,1.77,.19,.17,.4,.34,.56,.54,0,0,.17,.36,.14,.17,0-.03,.04-.03,.05-.05-.06,.15-.05,.1-.12,.17-.11,.1-.29,.17-.46,.21-.96,.28-1.98,.34-2.99,.26-.84-.07-1.76-.34-2.47-.89-.81-.63-1.44-1.49-2.4-1.95-.61-.29-1.35-.17-1.71,.45-.32,.55-.16,1.42,.45,1.71h0Z"
|
||||
style="fill:#231f20;" />
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<path
|
||||
d="M1.25,178.57c8.14-4.37,16.49-8.51,25.42-10.9,8.93-2.39,16.85-8.86,25.66-6.05,3.11,.99,4.86,.29,7.84,1.63,7.16,3.22,14.5,6.16,22.19,7.73,.92,.19,1.85,.36,2.75,.64,.76,.24,1.49,.57,2.23,.85,3.03,1.13,6.35,1.46,9.56,1.07,1.51-.18,3.03-.52,4.52-.25s2.98,1.36,3.1,2.87c.15,1.87-1.69,3.22-3.31,4.16-5.19,3.04-10.67,6.16-16.68,6.31-1.06,.03-2.12-.04-3.16,.13-.96,.16-1.87,.52-2.8,.81-5.16,1.61-10.98,.91-15.62-1.86-.45-.27-.97-.56-1.45-.36-.27,.11-.46,.36-.64,.6"
|
||||
style="fill:#fff;" />
|
||||
<path
|
||||
d="M1.88,179.65c4.86-2.6,9.78-5.14,14.87-7.25,2.49-1.03,5.01-1.96,7.58-2.76,2.41-.74,4.83-1.37,7.18-2.29,4.42-1.74,8.72-4.06,13.44-4.92,2.29-.42,4.6-.32,6.84,.33s4.33,.55,6.45,1.12c2.51,.67,4.91,2.06,7.31,3.05s5.01,1.99,7.57,2.84,5.29,1.63,7.99,2.22c1.22,.27,2.46,.45,3.65,.83,1.32,.42,2.57,1.02,3.92,1.38,2.52,.68,5.18,.89,7.77,.63,1.78-.18,5.97-1.37,6.75,1.15,.63,2.02-3.24,3.63-4.54,4.37-2.34,1.34-4.72,2.63-7.25,3.57-2.8,1.04-5.51,1.41-8.47,1.47-2.79,.06-5.28,1.39-8.03,1.68s-5.61-.04-8.26-.98c-2.04-.72-4.85-3.38-6.68-1.03-.98,1.25,.78,3.03,1.77,1.77,.36-.46,.86,.14,1.3,.37,.49,.26,.99,.5,1.5,.72,1.24,.54,2.53,.97,3.85,1.26,2.53,.55,5.13,.63,7.68,.24,1.24-.19,2.43-.52,3.63-.9,1.41-.46,2.68-.62,4.16-.63,2.68-.02,5.3-.5,7.82-1.4s5.08-2.18,7.48-3.54c2-1.13,4.41-2.21,5.78-4.13,1.29-1.8,.98-4.13-.71-5.56-2.12-1.78-4.81-1.28-7.34-.97-2.82,.34-5.69,.13-8.4-.74-1.34-.43-2.61-1.04-3.97-1.39s-2.89-.6-4.32-.94c-5.66-1.37-11.12-3.43-16.46-5.74-2.36-1.02-4.53-2.1-7.12-2.39-1.12-.12-2.24-.2-3.33-.49-1.24-.33-2.43-.68-3.71-.82-4.99-.56-9.77,1.38-14.26,3.29-2.63,1.12-5.26,2.29-8,3.12-3.06,.92-6.11,1.8-9.1,2.95-6.07,2.35-11.88,5.29-17.61,8.36-1.42,.76-.16,2.92,1.26,2.16h0Z"
|
||||
style="fill:#231f20;" />
|
||||
</g>
|
||||
<path d="M69.76,189.67c1.61,0,1.61-2.5,0-2.5s-1.61,2.5,0,2.5h0Z" style="fill:#231f20;" />
|
||||
<g>
|
||||
<path
|
||||
d="M91.16,173.56c.9,.4,1.5,1.25,2.27,1.85,1.63,1.28,3.91,1.36,5.95,.98,.45-.08,.91-.19,1.3-.43s.71-.64,.75-1.1c.06-.7-.53-1.28-1.06-1.74"
|
||||
style="fill:#fff;" />
|
||||
<path
|
||||
d="M90.53,174.64c.58,.28,.96,.69,1.44,1.14s1.03,.91,1.63,1.22c1.28,.66,2.75,.9,4.19,.83s3.25-.23,4.25-1.39c.56-.65,.78-1.51,.56-2.34-.2-.75-.77-1.36-1.34-1.86-.51-.44-1.27-.5-1.77,0-.45,.45-.51,1.32,0,1.77,.19,.17,.4,.34,.56,.54,0,0,.17,.36,.14,.17,0-.03,.04-.03,.05-.05-.06,.15-.05,.1-.12,.17-.11,.1-.29,.17-.46,.21-.96,.28-1.98,.34-2.99,.26-.84-.07-1.76-.34-2.47-.89-.81-.63-1.44-1.49-2.4-1.95-.61-.29-1.35-.17-1.71,.45-.32,.55-.16,1.42,.45,1.71h0Z"
|
||||
style="fill:#231f20;" />
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<path
|
||||
d="M107.25,200.34c-.57,.69-1.44,1.13-2.4,1.13-1.72,0-3.12-1.4-3.12-3.12,0-.71,.24-1.36,.63-1.88l5.79-6.56c.56-.56,1.34-.91,2.2-.91,1.72,0,3.12,1.4,3.12,3.12,0,.91-.39,1.72-1,2.29l-5.22,5.93Z"
|
||||
style="fill:#fff; stroke:#231f20; stroke-miterlimit:10;" />
|
||||
<path
|
||||
d="M107.97,198.36c0,.75-.27,1.45-.71,1.99-.57,.69-1.44,1.13-2.4,1.13-1.72,0-3.12-1.4-3.12-3.12,0-.71,.24-1.36,.63-1.88,.57-.75,1.47-1.23,2.48-1.23,1.72,0,3.12,1.4,3.12,3.12Z"
|
||||
style="fill:#fff; stroke:#231f20; stroke-miterlimit:10;" />
|
||||
</g>
|
||||
<g>
|
||||
<polygon
|
||||
points="142.87 164.83 137.76 166.52 132.66 164.83 132.66 109.62 131.53 107.91 131.53 60.47 144 60.47 144 107.91 142.87 109.62 142.87 164.83"
|
||||
style="fill:#fff; stroke:#231f20; stroke-miterlimit:10; stroke-width:3px;" />
|
||||
<line x1="132.66" y1="109.62" x2="142.87" y2="109.62"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10; stroke-width:3px;" />
|
||||
<line x1="132.66" y1="164.09" x2="142.87" y2="159.3"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<line x1="132.66" y1="158.09" x2="142.87" y2="153.3"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<line x1="132.66" y1="152.07" x2="142.87" y2="147.28"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<line x1="132.66" y1="146.09" x2="142.87" y2="141.31"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<line x1="132.66" y1="140.07" x2="142.87" y2="135.28"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<line x1="132.66" y1="133.87" x2="142.87" y2="129.08"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<line x1="132.66" y1="127.85" x2="142.87" y2="123.06"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<line x1="132.66" y1="121.87" x2="142.87" y2="117.08"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<line x1="132.66" y1="115.85" x2="142.87" y2="111.06"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
</g>
|
||||
<path d="M169.68,0V57.54c0,2.23-1.82,4.05-4.05,4.05h-56.36c-2.23,0-4.05-1.82-4.05-4.05V0"
|
||||
style="fill:#fff; stroke:#231f20; stroke-miterlimit:10; stroke-width:3px;" />
|
||||
<rect x="125.74" y="61.6" width="24.04" height="24.04"
|
||||
style="fill:#fff; stroke:#231f20; stroke-miterlimit:10; stroke-width:3px;" />
|
||||
<rect x="122.08" y="85.64" width="31.37" height="19.04"
|
||||
style="fill:#fff; stroke:#231f20; stroke-miterlimit:10; stroke-width:3px;" />
|
||||
<line x1="134.29" y1="85.64" x2="134.29" y2="104.68"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10; stroke-width:3px;" />
|
||||
<line x1="148.31" y1="85.64" x2="148.31" y2="104.68"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10; stroke-width:3px;" />
|
||||
<ellipse cx="128.14" cy="95.16" rx="2.39" ry="4.57"
|
||||
style="fill:#fff; stroke:#231f20; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<path
|
||||
d="M113.51,99.73c-1.32,0-2.39-2.05-2.39-4.57s1.07-4.57,2.39-4.57h14.44c1.32,0,2.39,2.05,2.39,4.57s-1.07,4.57-2.39,4.57h-14.44Z"
|
||||
style="fill:#fff; stroke:#231f20; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<ellipse cx="113.51" cy="95.16" rx="2.39" ry="4.57"
|
||||
style="fill:#fff; stroke:#231f20; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<g>
|
||||
<g>
|
||||
<line x1="127.88" y1="202.38" x2="127.88" y2="205.88"
|
||||
style="fill:none; stroke:#37b34a; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<line x1="127.88" y1="207.38" x2="127.88" y2="220.16"
|
||||
style="fill:none; stroke:#37b34a; stroke-dasharray:0 0 0 0 5.26 1.5 5.26 1.5; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<line x1="127.88" y1="220.92" x2="127.88" y2="224.42"
|
||||
style="fill:none; stroke:#37b34a; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
</g>
|
||||
<polyline points="122.99 207.33 127.88 201.28 132.72 207.33"
|
||||
style="fill:none; stroke:#37b34a; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<line x1="95.86" y1="94.9" x2="92.36" y2="94.9"
|
||||
style="fill:none; stroke:#37b34a; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<line x1="90.8" y1="94.9" x2="77.59" y2="94.9"
|
||||
style="fill:none; stroke:#37b34a; stroke-dasharray:0 0 0 0 5.44 1.55 5.44 1.55; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<line x1="76.81" y1="94.9" x2="56.6" y2="94.9"
|
||||
style="fill:none; stroke:#37b34a; stroke-dasharray:0 0 0 0 0 0 5.44 1.55 5.44 1.55 5.44 1.55; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<line x1="55.82" y1="94.9" x2="52.32" y2="94.9"
|
||||
style="fill:none; stroke:#37b34a; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
</g>
|
||||
<polyline points="90.9 90 96.95 94.9 90.9 99.73"
|
||||
style="fill:none; stroke:#37b34a; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
</g>
|
||||
<path
|
||||
d="M111.84,93.61c-5.44,.15-10.02,3.72-13.85,7.24-2.01,1.85-3.9,3.81-5.83,5.74s-4.16,3.88-6.06,6.02c-4.2,4.74-7.49,10.2-10.3,15.85-2.66,5.36-5.36,10.73-7.5,16.33-2.35,6.16-3.71,12.57-4.38,19.12-.1,1.01,.94,1.88,1.88,1.88,1.1,0,1.77-.86,1.88-1.88,.57-5.54,1.71-10.99,3.56-16.25s4.22-10.04,6.62-14.91c2.64-5.36,5.4-10.68,9.12-15.38,3.31-4.18,7.41-7.76,11.19-11.51s8.22-8.36,13.67-8.51c2.41-.07,2.42-3.82,0-3.75h0Z"
|
||||
style="fill:#231f20;" />
|
||||
<path
|
||||
d="M59.12,233.43c2.05,17.35-4.54,34.73-17.73,46.21-3.46,3.02-7.33,5.53-11.45,7.56-2.17,1.06-.27,4.3,1.89,3.24,16.06-7.89,27.69-23.39,30.62-41.06,.88-5.28,1.04-10.63,.41-15.94-.12-1.01-.78-1.88-1.88-1.88-.92,0-1.99,.86-1.88,1.88h0Z"
|
||||
style="fill:#231f20;" />
|
||||
<path
|
||||
d="M103.49,197.11c-7.6,6.84-13.89,15.16-18.3,24.39-2.34,4.9-4.19,10.04-7.16,14.61s-6.89,8.75-10.54,12.93c-4.48,5.13-8.96,10.26-13.44,15.38-1.58,1.81,1.06,4.47,2.65,2.65,3.93-4.5,7.87-9.01,11.8-13.51,3.72-4.25,7.58-8.42,10.96-12.96s5.44-9.33,7.66-14.32c2.1-4.74,4.55-9.28,7.51-13.54,3.31-4.76,7.2-9.1,11.52-12.98,1.8-1.62-.86-4.26-2.65-2.65h0Z"
|
||||
style="fill:#231f20;" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 21 KiB |
275
src/svelte-components/src/svgs/probe-check-z.svg
Normal file
@@ -0,0 +1,275 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg id="Layer_1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 307.88 288.65">
|
||||
<g>
|
||||
<polygon
|
||||
points="306.38 161.14 243.73 243.91 98.03 243.91 98.03 228.65 160.68 145.88 306.38 145.88 306.38 161.14"
|
||||
style="fill:#fff; stroke:#231f20; stroke-miterlimit:10; stroke-width:3px;" />
|
||||
<polyline points="306.38 145.88 243.73 228.65 98.03 228.65"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10; stroke-width:3px;" />
|
||||
<line x1="243.73" y1="228.65" x2="243.73" y2="243.91"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10; stroke-width:3px;" />
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<line x1="146.89" y1="184.96" x2="146.89" y2="188.46"
|
||||
style="fill:none; stroke:#39b54a; stroke-miterlimit:10; stroke-width:1.75px;" />
|
||||
<line x1="146.89" y1="189.76" x2="146.89" y2="200.85"
|
||||
style="fill:none; stroke:#39b54a; stroke-dasharray:0 0 0 0 4.56 1.3 4.56 1.3; stroke-miterlimit:10; stroke-width:1.75px;" />
|
||||
<line x1="146.89" y1="201.5" x2="146.89" y2="205"
|
||||
style="fill:none; stroke:#39b54a; stroke-miterlimit:10; stroke-width:1.75px;" />
|
||||
</g>
|
||||
<polyline points="142.67 189.08 146.89 183.87 150.95 188.95"
|
||||
style="fill:none; stroke:#39b54a; stroke-miterlimit:10; stroke-width:1.75px;" />
|
||||
</g>
|
||||
<g>
|
||||
<polygon
|
||||
points="150.06 172.24 132.23 195.79 90.77 195.79 90.77 184.45 108.6 160.89 118.18 160.89 118.19 163.9 150.06 163.9 150.06 172.24"
|
||||
style="fill:#fff; stroke:#231f20; stroke-miterlimit:10; stroke-width:3px;" />
|
||||
<polyline points="149.25 164.78 137.31 180.56 137.3 178.27 136.9 178.28 132.23 184.45 90.77 184.45"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10; stroke-width:3px;" />
|
||||
<line x1="132.23" y1="184.45" x2="132.23" y2="195.79"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10; stroke-width:3px;" />
|
||||
<ellipse cx="138.4" cy="165.46" rx="3.83" ry="1.56" style="fill:none; stroke:#231f20; stroke-miterlimit:10;" />
|
||||
<circle cx="110.61" cy="190.12" r="3.12" style="fill:none; stroke:#231f20; stroke-miterlimit:10;" />
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<polygon
|
||||
points="149.65 164.78 149.65 172.23 131.83 195.79 131.83 184.45 136.5 178.28 136.9 178.27 136.91 180.56 148.85 164.78 149.65 164.78"
|
||||
style="fill:#fff;" />
|
||||
<polygon
|
||||
points="117.79 163.9 149.65 163.9 149.65 164.78 148.85 164.78 136.91 180.56 136.9 178.27 136.5 178.28 136.3 177.75 107.89 177.75 107.89 177.3 117.79 163.9"
|
||||
style="fill:#8dc63f;" />
|
||||
<polygon
|
||||
points="136.3 177.75 136.5 178.28 131.83 184.45 110.21 184.45 90.37 184.45 108.19 160.89 116.92 160.89 104.6 177.75 107.89 177.75 136.3 177.75"
|
||||
style="fill:#ed1c24;" />
|
||||
<path d="M131.83,184.45v11.34h-21.62v-2.55c1.72,0,3.12-1.4,3.12-3.12s-1.4-3.12-3.12-3.12v-2.55h21.62Z"
|
||||
style="fill:#fff;" />
|
||||
<circle cx="110.21" cy="190.12" r="3.12" style="fill:#fff;" />
|
||||
<path d="M110.21,193.24v2.55h-19.84v-11.34h19.84v2.55c-1.72,0-3.12,1.39-3.12,3.12s1.4,3.12,3.12,3.12Z"
|
||||
style="fill:#fff;" />
|
||||
<polygon
|
||||
points="104.6 177.75 116.92 160.89 117.77 160.89 117.79 163.9 107.89 177.3 107.89 177.75 104.6 177.75"
|
||||
style="fill:#fff;" />
|
||||
</g>
|
||||
<g>
|
||||
<polygon
|
||||
points="149.65 164.78 149.65 172.23 131.83 195.79 110.21 195.79 90.37 195.79 90.37 184.45 108.19 160.89 116.92 160.89 117.77 160.89 117.79 163.9 149.65 163.9 149.65 164.78"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10; stroke-width:3px;" />
|
||||
<polyline
|
||||
points="148.85 164.78 136.91 180.56 136.9 178.27 136.5 178.28 131.83 184.45 110.21 184.45 90.37 184.45"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10; stroke-width:3px;" />
|
||||
<line x1="131.83" y1="184.45" x2="131.83" y2="195.79"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10; stroke-width:3px;" />
|
||||
<circle cx="110.21" cy="190.12" r="3.12" style="fill:none; stroke:#231f20; stroke-miterlimit:10;" />
|
||||
<polyline points="116.92 160.89 104.6 177.75 107.89 177.75 136.3 177.75"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<line x1="117.79" y1="163.9" x2="107.89" y2="177.3"
|
||||
style="fill:none; stroke:#231f20; stroke-linecap:round; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<g>
|
||||
<path
|
||||
d="M1.25,176.73c8.14-4.37,16.49-8.51,25.42-10.9,8.93-2.39,16.85-8.86,25.66-6.05,3.11,.99,4.86,.29,7.84,1.63,7.16,3.22,14.5,6.16,22.19,7.73,.92,.19,1.85,.36,2.75,.64,.76,.24,1.49,.57,2.23,.85,3.03,1.13,6.35,1.46,9.56,1.07,1.51-.18,3.03-.52,4.52-.25s2.98,1.36,3.1,2.87c.15,1.87-1.69,3.22-3.31,4.16-5.19,3.04-10.67,6.16-16.68,6.31-1.06,.03-2.12-.04-3.16,.13-.96,.16-1.87,.52-2.8,.81-5.16,1.61-10.98,.91-15.62-1.86-.45-.27-.97-.56-1.45-.36-.27,.11-.46,.36-.64,.6-5.22,6.94-13.45,11.53-22.1,12.33"
|
||||
style="fill:#fff;" />
|
||||
<path
|
||||
d="M1.88,177.81c5.74-3.07,11.56-6.05,17.66-8.36,2.91-1.1,5.89-1.89,8.85-2.83,2.68-.84,5.25-1.98,7.82-3.08s5.22-2.2,7.99-2.8,5.43-.39,8.23,.37c2.52,.69,5.09,.51,7.53,1.56,2.93,1.27,5.84,2.56,8.82,3.7s6.08,2.19,9.2,3.02c1.49,.4,2.99,.73,4.5,1.04,1.66,.34,3.14,.9,4.73,1.47,2.8,1,5.85,1.37,8.81,1.13,1.5-.12,2.99-.5,4.5-.43,1.2,.05,3.18,.83,2.69,2.38-.36,1.13-1.67,1.85-2.62,2.42-1.33,.79-2.68,1.56-4.05,2.3-2.68,1.44-5.47,2.72-8.45,3.39s-6.08,.21-9.05,1.18-5.77,1.32-8.75,.89c-1.5-.22-3-.62-4.4-1.2s-2.85-1.93-4.35-1.72c-1.35,.19-2.09,1.71-2.9,2.64-.98,1.12-2.04,2.17-3.17,3.15-4.66,4.01-10.59,6.55-16.7,7.15-1.59,.16-1.6,2.66,0,2.5,5.78-.57,11.36-2.61,16.08-6.01,2.3-1.65,4.4-3.57,6.18-5.77,.18-.22,.7-1.1,.95-1.15,.34-.07,1.44,.81,1.81,.98,1.47,.71,3.01,1.26,4.61,1.6,2.93,.63,5.97,.65,8.91,.02,1.49-.32,2.91-1.01,4.41-1.23,1.65-.24,3.34-.05,5-.27,3.13-.41,6.08-1.52,8.91-2.88s5.65-2.73,7.99-4.62c2.05-1.66,3.05-4.46,1-6.58-2.35-2.43-5.65-1.48-8.6-1.24-3.43,.27-6.5-.44-9.69-1.64s-6.65-1.57-9.9-2.54-6.43-2.13-9.56-3.41c-1.61-.66-3.21-1.34-4.8-2.05-1.38-.61-2.73-1.24-4.23-1.49-1.3-.22-2.63-.22-3.92-.5-1.45-.31-2.83-.8-4.32-.97-2.8-.32-5.64,.17-8.31,1-3.25,1.01-6.32,2.49-9.46,3.78-3.37,1.38-6.89,2.22-10.33,3.39-7.25,2.48-14.12,5.94-20.86,9.55-1.42,.76-.16,2.92,1.26,2.16h0Z"
|
||||
style="fill:#231f20;" />
|
||||
</g>
|
||||
<g>
|
||||
<path
|
||||
d="M90.74,191.11c-1.29,.17-2.57,.39-3.84,.65-.92,.19-1.85,.39-2.79,.36-.92-.04-1.82-.31-2.72-.51-4.42-.97-7.32-.5-11.78,.27"
|
||||
style="fill:#fff;" />
|
||||
<path
|
||||
d="M90.41,189.9c-1.83,.25-3.67,.77-5.5,.93s-3.78-.62-5.62-.86c-3.38-.43-6.69,.12-10.01,.69-1.58,.27-.91,2.68,.66,2.41,3.37-.58,6.73-1.08,10.14-.47,1.83,.33,3.52,.91,5.4,.66s3.72-.7,5.6-.96c1.59-.22,.91-2.63-.66-2.41h0Z"
|
||||
style="fill:#231f20;" />
|
||||
</g>
|
||||
<g>
|
||||
<path
|
||||
d="M69.76,185.81c-1.62,2.32-1,5.49-1.75,8.21-.39,1.43-1.18,2.75-1.38,4.22-.21,1.55,.25,3.1,.55,4.63,.07,.36,.13,.74,0,1.09-.11,.31-.36,.55-.59,.8-1.37,1.46-2.16,3.44-2.16,5.44"
|
||||
style="fill:#fff;" />
|
||||
<path
|
||||
d="M68.68,185.18c-1.16,1.8-1.31,3.87-1.49,5.95-.09,1.07-.22,2.11-.57,3.14-.37,1.08-.89,2.12-1.12,3.24s-.17,2.25,.01,3.38c.1,.62,.27,1.23,.37,1.85,.12,.73,.02,.88-.44,1.43-1.45,1.71-2.2,3.8-2.26,6.03-.04,1.61,2.46,1.61,2.5,0,.03-1.13,.28-2.2,.82-3.2,.48-.88,1.34-1.51,1.76-2.41,.38-.82,.19-1.66,.03-2.51-.26-1.28-.63-2.59-.39-3.9,.36-1.96,1.39-3.66,1.65-5.68s.12-4.25,1.28-6.06c.88-1.36-1.29-2.61-2.16-1.26h0Z"
|
||||
style="fill:#231f20;" />
|
||||
</g>
|
||||
<g>
|
||||
<path
|
||||
d="M67.04,204.15c1.3-.46,2.66-.76,4.03-.87,.35-.03,.69-.05,1.03-.11,.48-.09,.93-.27,1.39-.44,3.91-1.5,8.12-2.77,12.23-2.02"
|
||||
style="fill:#fff;" />
|
||||
<path
|
||||
d="M67.37,205.35c1.57-.54,3.1-.69,4.72-.93,1.39-.21,2.71-.89,4.04-1.33,2.97-.99,6.13-1.71,9.26-1.18,1.57,.27,2.25-2.14,.66-2.41-3.36-.57-6.69-.06-9.92,.96-1.44,.46-2.88,1.23-4.37,1.5-1.73,.31-3.37,.4-5.07,.98-1.51,.52-.86,2.94,.66,2.41h0Z"
|
||||
style="fill:#231f20;" />
|
||||
</g>
|
||||
<g>
|
||||
<path
|
||||
d="M58.89,224.43c-2.05-4.85,.54-11.14,5.42-13.14,2.12-.87,4.51-.99,6.57-2,2.05-1,3.61-2.78,5.6-3.89,2.67-1.49,5.93-1.66,8.55-3.22,1.82-1.08,3.21-2.76,4.88-4.07,2.03-1.59,4.44-2.59,6.82-3.58,1.75-.73,3.72-1.46,5.49-.79,2.12,.8,3.09,3.41,2.7,5.64s-1.83,4.12-3.34,5.8c-7.7,8.57-18.19,14.03-28.44,19.3-2.72,1.4-5.45,2.8-8.28,3.96-2.26,.92-4.6,1.69-6.7,2.94-1.64,.98-3.1,2.23-4.66,3.35-5.43,3.91-11.97,6.11-18.6,6.96-6.63,.86-13.38,.43-19.99-.57"
|
||||
style="fill:#fff;" />
|
||||
<path
|
||||
d="M60.1,224.09c-1.55-3.87-.15-8.67,3.4-10.97,2.14-1.39,4.8-1.45,7.13-2.37s4.01-2.79,6.14-4.07c2.27-1.37,4.99-1.67,7.41-2.69s4.22-3.03,6.29-4.72,4.72-2.79,7.21-3.78c2.31-.91,5.06-1.29,5.9,1.63,.7,2.44-.84,4.79-2.36,6.57-1.71,2.01-3.64,3.85-5.65,5.56-4.04,3.43-8.55,6.28-13.16,8.88s-9.7,5.28-14.66,7.65c-2.68,1.28-5.5,2.22-8.2,3.46-2.54,1.16-4.6,2.92-6.86,4.52-10.84,7.7-24.78,8.03-37.46,6.14-1.57-.23-2.25,2.17-.66,2.41,12.35,1.84,25.58,1.74,36.69-4.67,2.65-1.53,4.89-3.64,7.52-5.2,2.79-1.66,5.97-2.56,8.92-3.9,5.5-2.5,10.9-5.39,16.16-8.37s9.92-6.02,14.27-9.85c3.62-3.19,8.96-7.83,8-13.24-.39-2.22-1.92-4.25-4.2-4.73-2.8-.6-5.73,.98-8.21,2.11-2.8,1.27-4.98,2.98-7.24,5.02-1.1,.99-2.27,1.84-3.66,2.37s-2.94,.87-4.39,1.36-2.72,1.1-3.93,1.98c-1.3,.94-2.48,2.07-3.9,2.83-2.74,1.46-6.03,1.3-8.65,3.12-4.22,2.94-6.21,8.78-4.27,13.61,.59,1.47,3.01,.83,2.41-.66h0Z"
|
||||
style="fill:#231f20;" />
|
||||
</g>
|
||||
<g>
|
||||
<path
|
||||
d="M110.32,189.95c2.31,.23,4.18,2.27,4.64,4.55s-.3,4.67-1.62,6.57c-1.32,1.91-3.14,3.4-5.01,4.77-6.3,4.62-13.39,8.15-20.87,10.4"
|
||||
style="fill:#fff;" />
|
||||
<path
|
||||
d="M109.98,191.15c3.4,.48,4.45,4.11,3.45,7.02-1.14,3.32-4.23,5.56-6.99,7.49-5.91,4.13-12.43,7.28-19.32,9.38-1.53,.47-.88,2.88,.66,2.41,8.11-2.47,15.89-6.34,22.57-11.59,3.04-2.38,5.73-5.52,5.97-9.55,.21-3.46-2.09-7.07-5.68-7.57-1.57-.22-2.25,2.19-.66,2.41h0Z"
|
||||
style="fill:#231f20;" />
|
||||
</g>
|
||||
<g>
|
||||
<path d="M85.05,188.29l-.83,3.58" style="fill:#fff;" />
|
||||
<path
|
||||
d="M83.84,187.96l-.83,3.58c-.15,.64,.2,1.38,.87,1.54,.64,.15,1.38-.19,1.54-.87l.83-3.58c.15-.64-.2-1.38-.87-1.54-.64-.15-1.38,.19-1.54,.87h0Z"
|
||||
style="fill:#231f20;" />
|
||||
</g>
|
||||
<g>
|
||||
<path d="M84.5,196.52c-.06,.99-.02,1.98,.13,2.96" style="fill:#fff;" />
|
||||
<path
|
||||
d="M83.25,196.52c-.07,1.1,0,2.2,.17,3.29,.04,.29,.33,.61,.57,.75,.27,.16,.66,.22,.96,.13s.59-.29,.75-.57l.13-.3c.06-.22,.06-.44,0-.66-.01-.08-.02-.15-.03-.23l.04,.33c-.12-.9-.15-1.82-.1-2.73,.02-.31-.15-.67-.37-.88s-.57-.38-.88-.37-.66,.12-.88,.37-.34,.54-.37,.88h0Z"
|
||||
style="fill:#231f20;" />
|
||||
</g>
|
||||
<g>
|
||||
<path d="M72.52,208.78c-.46,1.52-.91,3.05-1.05,4.64s.08,3.24,.9,4.6" style="fill:#fff;" />
|
||||
<path
|
||||
d="M71.31,208.44c-.99,3.32-1.88,7-.02,10.2,.81,1.39,2.97,.13,2.16-1.26-1.47-2.53-.52-5.62,.28-8.27,.19-.65-.23-1.36-.87-1.54s-1.34,.22-1.54,.87h0Z"
|
||||
style="fill:#231f20;" />
|
||||
</g>
|
||||
<g>
|
||||
<path d="M84.74,203.93c-.61,1.54-.48,3.36,.34,4.8" style="fill:#fff;" />
|
||||
<path
|
||||
d="M83.54,203.6c-.71,1.86-.5,4.03,.46,5.76,.32,.57,1.15,.81,1.71,.45s.79-1.1,.45-1.71c-.05-.09-.1-.18-.15-.28-.02-.05-.05-.09-.07-.14-.05-.12-.04-.1,.03,.08,.01-.04-.08-.21-.1-.26-.03-.09-.06-.17-.08-.26-.06-.2-.11-.41-.14-.61v-.08c-.03-.14-.03-.1,0,.1,.02-.09-.02-.22-.03-.31-.01-.18-.01-.37,0-.55,0-.11,0-.21,.02-.31,0-.05,0-.1,.02-.16-.03,.2-.03,.23-.01,.1,.07-.39,.17-.77,.31-1.14,.23-.61-.26-1.4-.87-1.54-.71-.16-1.29,.22-1.54,.87h0Z"
|
||||
style="fill:#231f20;" />
|
||||
</g>
|
||||
<g>
|
||||
<path d="M52.32,196.92c-4.57,5.84-6,13.57-6.04,20.99-.02,2.89,.15,5.85-.65,8.63" style="fill:#fff;" />
|
||||
<path
|
||||
d="M51.25,196.29c-3.09,4.01-4.82,8.88-5.6,13.85-.38,2.44-.58,4.9-.61,7.36-.04,2.92,.16,5.85-.61,8.71-.42,1.56,1.99,2.22,2.41,.66,.71-2.63,.7-5.34,.69-8.04,0-2.54,.09-5.09,.46-7.61,.72-4.93,2.35-9.68,5.41-13.66,.98-1.27-1.19-2.52-2.16-1.26h0Z"
|
||||
style="fill:#231f20;" />
|
||||
</g>
|
||||
<g>
|
||||
<path d="M43.94,195.7c-.58,3.78-3.36,6.94-6.64,8.9s-7.05,2.93-10.75,3.87" style="fill:#fff;" />
|
||||
<path
|
||||
d="M42.73,195.37c-1.3,7.8-9.97,10.24-16.52,11.9-1.56,.39-.9,2.81,.66,2.41,4.15-1.05,8.48-2.15,12.04-4.64,3.06-2.14,5.59-5.25,6.22-9.01,.26-1.57-2.15-2.25-2.41-.66h0Z"
|
||||
style="fill:#231f20;" />
|
||||
</g>
|
||||
<g>
|
||||
<path
|
||||
d="M91.16,171.72c.9,.4,1.5,1.25,2.27,1.85,1.63,1.28,3.91,1.36,5.95,.98,.45-.08,.91-.19,1.3-.43s.71-.64,.75-1.1c.06-.7-.53-1.28-1.06-1.74"
|
||||
style="fill:#fff;" />
|
||||
<path
|
||||
d="M90.53,172.79c.58,.28,.96,.69,1.44,1.14s1.03,.91,1.63,1.22c1.28,.66,2.75,.9,4.19,.83s3.25-.23,4.25-1.39c.56-.65,.78-1.51,.56-2.34-.2-.75-.77-1.36-1.34-1.86-.51-.44-1.27-.5-1.77,0-.45,.45-.51,1.32,0,1.77,.19,.17,.4,.34,.56,.54,0,0,.17,.36,.14,.17,0-.03,.04-.03,.05-.05-.06,.15-.05,.1-.12,.17-.11,.1-.29,.17-.46,.21-.96,.28-1.98,.34-2.99,.26-.84-.07-1.76-.34-2.47-.89-.81-.63-1.44-1.49-2.4-1.95-.61-.29-1.35-.17-1.71,.45-.32,.55-.16,1.42,.45,1.71h0Z"
|
||||
style="fill:#231f20;" />
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<path
|
||||
d="M1.25,176.57c8.14-4.37,16.49-8.51,25.42-10.9,8.93-2.39,16.85-8.86,25.66-6.05,3.11,.99,4.86,.29,7.84,1.63,7.16,3.22,14.5,6.16,22.19,7.73,.92,.19,1.85,.36,2.75,.64,.76,.24,1.49,.57,2.23,.85,3.03,1.13,6.35,1.46,9.56,1.07,1.51-.18,3.03-.52,4.52-.25s2.98,1.36,3.1,2.87c.15,1.87-1.69,3.22-3.31,4.16-5.19,3.04-10.67,6.16-16.68,6.31-1.06,.03-2.12-.04-3.16,.13-.96,.16-1.87,.52-2.8,.81-5.16,1.61-10.98,.91-15.62-1.86-.45-.27-.97-.56-1.45-.36-.27,.11-.46,.36-.64,.6"
|
||||
style="fill:#fff;" />
|
||||
<path
|
||||
d="M1.88,177.65c4.86-2.6,9.78-5.14,14.87-7.25,2.49-1.03,5.01-1.96,7.58-2.76,2.41-.74,4.83-1.37,7.18-2.29,4.42-1.74,8.72-4.06,13.44-4.92,2.29-.42,4.6-.32,6.84,.33s4.33,.55,6.45,1.12c2.51,.67,4.91,2.06,7.31,3.05s5.01,1.99,7.57,2.84,5.29,1.63,7.99,2.22c1.22,.27,2.46,.45,3.65,.83,1.32,.42,2.57,1.02,3.92,1.38,2.52,.68,5.18,.89,7.77,.63,1.78-.18,5.97-1.37,6.75,1.15,.63,2.02-3.24,3.63-4.54,4.37-2.34,1.34-4.72,2.63-7.25,3.57-2.8,1.04-5.51,1.41-8.47,1.47-2.79,.06-5.28,1.39-8.03,1.68s-5.61-.04-8.26-.98c-2.04-.72-4.85-3.38-6.68-1.03-.98,1.25,.78,3.03,1.77,1.77,.36-.46,.86,.14,1.3,.37,.49,.26,.99,.5,1.5,.72,1.24,.54,2.53,.97,3.85,1.26,2.53,.55,5.13,.63,7.68,.24,1.24-.19,2.43-.52,3.63-.9,1.41-.46,2.68-.62,4.16-.63,2.68-.02,5.3-.5,7.82-1.4s5.08-2.18,7.48-3.54c2-1.13,4.41-2.21,5.78-4.13,1.29-1.8,.98-4.13-.71-5.56-2.12-1.78-4.81-1.28-7.34-.97-2.82,.34-5.69,.13-8.4-.74-1.34-.43-2.61-1.04-3.97-1.39s-2.89-.6-4.32-.94c-5.66-1.37-11.12-3.43-16.46-5.74-2.36-1.02-4.53-2.1-7.12-2.39-1.12-.12-2.24-.2-3.33-.49-1.24-.33-2.43-.68-3.71-.82-4.99-.56-9.77,1.38-14.26,3.29-2.63,1.12-5.26,2.29-8,3.12-3.06,.92-6.11,1.8-9.1,2.95-6.07,2.35-11.88,5.29-17.61,8.36-1.42,.76-.16,2.92,1.26,2.16h0Z"
|
||||
style="fill:#231f20;" />
|
||||
</g>
|
||||
<path d="M69.76,187.67c1.61,0,1.61-2.5,0-2.5s-1.61,2.5,0,2.5h0Z" style="fill:#231f20;" />
|
||||
<g>
|
||||
<path
|
||||
d="M91.16,171.56c.9,.4,1.5,1.25,2.27,1.85,1.63,1.28,3.91,1.36,5.95,.98,.45-.08,.91-.19,1.3-.43s.71-.64,.75-1.1c.06-.7-.53-1.28-1.06-1.74"
|
||||
style="fill:#fff;" />
|
||||
<path
|
||||
d="M90.53,172.64c.58,.28,.96,.69,1.44,1.14s1.03,.91,1.63,1.22c1.28,.66,2.75,.9,4.19,.83s3.25-.23,4.25-1.39c.56-.65,.78-1.51,.56-2.34-.2-.75-.77-1.36-1.34-1.86-.51-.44-1.27-.5-1.77,0-.45,.45-.51,1.32,0,1.77,.19,.17,.4,.34,.56,.54,0,0,.17,.36,.14,.17,0-.03,.04-.03,.05-.05-.06,.15-.05,.1-.12,.17-.11,.1-.29,.17-.46,.21-.96,.28-1.98,.34-2.99,.26-.84-.07-1.76-.34-2.47-.89-.81-.63-1.44-1.49-2.4-1.95-.61-.29-1.35-.17-1.71,.45-.32,.55-.16,1.42,.45,1.71h0Z"
|
||||
style="fill:#231f20;" />
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<path
|
||||
d="M107.25,198.34c-.57,.69-1.44,1.13-2.4,1.13-1.72,0-3.12-1.4-3.12-3.12,0-.71,.24-1.36,.63-1.88l5.79-6.56c.56-.56,1.34-.91,2.2-.91,1.72,0,3.12,1.4,3.12,3.12,0,.91-.39,1.72-1,2.29l-5.22,5.93Z"
|
||||
style="fill:#fff; stroke:#231f20; stroke-miterlimit:10;" />
|
||||
<path
|
||||
d="M107.97,196.36c0,.75-.27,1.45-.71,1.99-.57,.69-1.44,1.13-2.4,1.13-1.72,0-3.12-1.4-3.12-3.12,0-.71,.24-1.36,.63-1.88,.57-.75,1.47-1.23,2.48-1.23,1.72,0,3.12,1.4,3.12,3.12Z"
|
||||
style="fill:#fff; stroke:#231f20; stroke-miterlimit:10;" />
|
||||
</g>
|
||||
<g>
|
||||
<polygon
|
||||
points="142.87 164.83 137.76 166.52 132.66 164.83 132.66 109.62 131.53 107.91 131.53 60.47 144 60.47 144 107.91 142.87 109.62 142.87 164.83"
|
||||
style="fill:#fff; stroke:#231f20; stroke-miterlimit:10; stroke-width:3px;" />
|
||||
<line x1="132.66" y1="109.62" x2="142.87" y2="109.62"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10; stroke-width:3px;" />
|
||||
<line x1="132.66" y1="164.09" x2="142.87" y2="159.3"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<line x1="132.66" y1="158.09" x2="142.87" y2="153.3"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<line x1="132.66" y1="152.07" x2="142.87" y2="147.28"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<line x1="132.66" y1="146.09" x2="142.87" y2="141.31"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<line x1="132.66" y1="140.07" x2="142.87" y2="135.28"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<line x1="132.66" y1="133.87" x2="142.87" y2="129.08"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<line x1="132.66" y1="127.85" x2="142.87" y2="123.06"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<line x1="132.66" y1="121.87" x2="142.87" y2="117.08"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<line x1="132.66" y1="115.85" x2="142.87" y2="111.06"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
</g>
|
||||
<path d="M169.68,0V57.54c0,2.23-1.82,4.05-4.05,4.05h-56.36c-2.23,0-4.05-1.82-4.05-4.05V0"
|
||||
style="fill:#fff; stroke:#231f20; stroke-miterlimit:10; stroke-width:3px;" />
|
||||
<rect x="125.74" y="61.6" width="24.04" height="24.04"
|
||||
style="fill:#fff; stroke:#231f20; stroke-miterlimit:10; stroke-width:3px;" />
|
||||
<rect x="122.08" y="85.64" width="31.37" height="19.04"
|
||||
style="fill:#fff; stroke:#231f20; stroke-miterlimit:10; stroke-width:3px;" />
|
||||
<line x1="134.29" y1="85.64" x2="134.29" y2="104.68"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10; stroke-width:3px;" />
|
||||
<line x1="148.31" y1="85.64" x2="148.31" y2="104.68"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10; stroke-width:3px;" />
|
||||
<ellipse cx="128.14" cy="95.16" rx="2.39" ry="4.57"
|
||||
style="fill:#fff; stroke:#231f20; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<path
|
||||
d="M113.51,99.73c-1.32,0-2.39-2.05-2.39-4.57s1.07-4.57,2.39-4.57h14.44c1.32,0,2.39,2.05,2.39,4.57s-1.07,4.57-2.39,4.57h-14.44Z"
|
||||
style="fill:#fff; stroke:#231f20; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<ellipse cx="113.51" cy="95.16" rx="2.39" ry="4.57"
|
||||
style="fill:#fff; stroke:#231f20; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<g>
|
||||
<g>
|
||||
<line x1="127.88" y1="200.38" x2="127.88" y2="203.88"
|
||||
style="fill:none; stroke:#39b54a; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<line x1="127.88" y1="205.38" x2="127.88" y2="218.16"
|
||||
style="fill:none; stroke:#39b54a; stroke-dasharray:0 0 0 0 5.26 1.5 5.26 1.5; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<line x1="127.88" y1="218.92" x2="127.88" y2="222.42"
|
||||
style="fill:none; stroke:#39b54a; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
</g>
|
||||
<polyline points="122.99 205.33 127.88 199.28 132.72 205.33"
|
||||
style="fill:none; stroke:#39b54a; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<line x1="95.86" y1="94.9" x2="92.36" y2="94.9"
|
||||
style="fill:none; stroke:#39b54a; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<line x1="90.8" y1="94.9" x2="77.59" y2="94.9"
|
||||
style="fill:none; stroke:#39b54a; stroke-dasharray:0 0 0 0 5.44 1.55 5.44 1.55; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<line x1="76.81" y1="94.9" x2="56.6" y2="94.9"
|
||||
style="fill:none; stroke:#39b54a; stroke-dasharray:0 0 0 0 0 0 5.44 1.55 5.44 1.55 5.44 1.55; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<line x1="55.82" y1="94.9" x2="52.32" y2="94.9"
|
||||
style="fill:none; stroke:#39b54a; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
</g>
|
||||
<polyline points="90.9 90 96.95 94.9 90.9 99.73"
|
||||
style="fill:none; stroke:#39b54a; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
</g>
|
||||
<path
|
||||
d="M111.84,93.61c-5.44,.15-10.02,3.72-13.85,7.24-2.01,1.85-3.9,3.81-5.83,5.74s-4.16,3.88-6.06,6.02c-4.2,4.74-7.48,10.2-10.3,15.85-2.6,5.24-5.32,10.43-7.5,15.87-2.39,5.97-3.72,12.19-4.38,18.58-.1,1.01,.94,1.88,1.88,1.88,1.1,0,1.77-.86,1.88-1.88,.56-5.4,1.68-10.7,3.56-15.79s4.27-9.66,6.62-14.38c2.66-5.35,5.4-10.67,9.12-15.37,3.31-4.18,7.41-7.76,11.19-11.51s8.22-8.36,13.67-8.51c2.41-.07,2.42-3.82,0-3.75h0Z"
|
||||
style="fill:#231f20;" />
|
||||
<path
|
||||
d="M59.12,231.43c2.05,17.35-4.54,34.73-17.73,46.21-3.46,3.02-7.33,5.53-11.45,7.56-2.17,1.06-.27,4.3,1.89,3.24,16.06-7.89,27.69-23.39,30.62-41.06,.88-5.28,1.04-10.63,.41-15.94-.12-1.01-.78-1.88-1.88-1.88-.92,0-1.99,.86-1.88,1.88h0Z"
|
||||
style="fill:#231f20;" />
|
||||
<path
|
||||
d="M103.49,195.11c-7.6,6.84-13.89,15.16-18.3,24.39-2.34,4.9-4.19,10.04-7.16,14.61s-6.89,8.75-10.54,12.93c-4.48,5.13-8.96,10.26-13.44,15.38-1.58,1.81,1.06,4.47,2.65,2.65,3.93-4.5,7.87-9.01,11.8-13.51,3.72-4.25,7.58-8.42,10.96-12.96s5.44-9.33,7.66-14.32c2.1-4.74,4.55-9.28,7.51-13.54,3.31-4.76,7.2-9.1,11.52-12.98,1.8-1.62-.86-4.26-2.65-2.65h0Z"
|
||||
style="fill:#231f20;" />
|
||||
<polyline points="117.33 160.89 105.01 177.76 136.71 177.76"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<line x1="118.19" y1="163.9" x2="108.3" y2="177.3"
|
||||
style="fill:none; stroke:#231f20; stroke-linecap:round; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 23 KiB |
49
src/svelte-components/src/svgs/probe-place-xyz.svg
Normal file
@@ -0,0 +1,49 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?><svg id="Layer_1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 303.91 128.94">
|
||||
<polygon
|
||||
points="167.2 14.19 171.09 20.83 167.49 22.75 163.59 16.12 152.92 21.83 151.59 19.59 162.28 13.87 158.38 7.24 161.99 5.31 165.88 11.95 176.56 6.23 177.87 8.48 167.2 14.19"
|
||||
style="fill:#be1e2d;" />
|
||||
<polygon
|
||||
points="277.18 14.19 281.07 20.83 277.47 22.75 273.57 16.12 262.9 21.83 261.58 19.59 272.26 13.87 268.36 7.24 271.97 5.31 275.86 11.95 286.55 6.23 287.86 8.48 277.18 14.19"
|
||||
style="fill:#be1e2d;" />
|
||||
<polygon
|
||||
points="234.48 71.98 238.37 78.62 234.77 80.55 230.87 73.91 220.2 79.62 218.88 77.38 229.56 71.67 225.66 65.03 229.27 63.1 233.16 69.74 243.85 64.02 245.15 66.27 234.48 71.98"
|
||||
style="fill:#be1e2d;" />
|
||||
<polygon
|
||||
points="200.71 41.95 204.59 48.59 200.99 50.51 197.09 43.88 186.42 49.59 185.1 47.35 195.78 41.63 191.88 35 195.5 33.07 199.38 39.71 210.07 33.99 211.38 36.24 200.71 41.95"
|
||||
style="fill:#be1e2d;" />
|
||||
<polyline points="112.27 66.96 118.93 76.72 136.87 63.1"
|
||||
style="fill:none; stroke:#00a651; stroke-miterlimit:10; stroke-width:4px;" />
|
||||
<polygon points="302.41 16.76 239.77 99.53 94.07 99.53 94.07 84.27 156.71 1.5 302.41 1.5 302.41 16.76"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10; stroke-width:3px;" />
|
||||
<polyline points="302.41 1.5 239.77 84.27 94.07 84.27"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10; stroke-width:3px;" />
|
||||
<line x1="239.77" y1="84.27" x2="239.77" y2="99.53"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10; stroke-width:3px;" />
|
||||
<polygon points="60.79 103.89 42.96 127.44 1.5 127.44 1.5 116.1 19.33 92.55 60.79 92.55 60.79 103.89"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10; stroke-width:3px;" />
|
||||
<polyline points="60.79 92.55 42.96 116.1 1.5 116.1"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10; stroke-width:3px;" />
|
||||
<line x1="42.96" y1="116.1" x2="42.96" y2="127.44"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10; stroke-width:3px;" />
|
||||
<ellipse cx="49.13" cy="97.11" rx="3.83" ry="1.56" style="fill:none; stroke:#231f20; stroke-miterlimit:10;" />
|
||||
<circle cx="21.34" cy="121.77" r="3.12" style="fill:none; stroke:#231f20; stroke-miterlimit:10;" />
|
||||
<g>
|
||||
<polygon points="34.63 102.43 31.5 99.01 29.54 101.63 32.67 105.05 34.63 102.43" style="fill:#bcbec0;" />
|
||||
<polygon points="31.52 106.57 28.39 103.16 26.42 105.77 29.56 109.19 31.52 106.57" style="fill:#bcbec0;" />
|
||||
<polygon points="27.82 111.51 28.41 110.72 25.28 107.3 22.12 111.51 25.2 111.2 27.82 111.51"
|
||||
style="fill:#bcbec0;" />
|
||||
<polygon points="38.61 97.14 32.91 97.14 32.65 97.49 35.78 100.91 38.61 97.14" style="fill:#bcbec0;" />
|
||||
</g>
|
||||
<g>
|
||||
<line x1="93.77" y1="75.66" x2="91.3" y2="76.07"
|
||||
style="fill:none; stroke:#a7a9ac; stroke-miterlimit:10; stroke-width:3px;" />
|
||||
<line x1="87.94" y1="76.63" x2="71.68" y2="79.35"
|
||||
style="fill:none; stroke:#a7a9ac; stroke-dasharray:0 0 0 0 5.68 3.41 5.68 3.41; stroke-miterlimit:10; stroke-width:3px;" />
|
||||
<line x1="70" y1="79.64" x2="44.78" y2="83.86"
|
||||
style="fill:none; stroke:#a7a9ac; stroke-dasharray:0 0 0 0 0 0 5.68 3.41 5.68 3.41 5.68 3.41; stroke-miterlimit:10; stroke-width:3px;" />
|
||||
<line x1="43.1" y1="84.14" x2="40.63" y2="84.55"
|
||||
style="fill:none; stroke:#a7a9ac; stroke-miterlimit:10; stroke-width:3px;" />
|
||||
</g>
|
||||
<polyline points="82.19 71.95 93.77 75.66 85.96 83.49"
|
||||
style="fill:none; stroke:#a7a9ac; stroke-miterlimit:10; stroke-width:3px;" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.6 KiB |
60
src/svelte-components/src/svgs/probe-place-z.svg
Normal file
@@ -0,0 +1,60 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?><svg id="Layer_1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 326.35 123.59">
|
||||
<polygon points="324.85 16.76 262.21 99.53 116.51 99.53 116.51 84.27 179.15 1.5 324.85 1.5 324.85 16.76"
|
||||
style="fill:#fff; stroke:#231f20; stroke-miterlimit:10; stroke-width:3px;" />
|
||||
<polygon points="206.56 67.29 185.57 36.09 197.9 27.68 210.04 45.9 256.99 10.26 266.02 22.15 206.56 67.29"
|
||||
style="fill:#00a651;" />
|
||||
<polyline points="324.85 1.5 262.21 84.27 116.51 84.27"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10; stroke-width:3px;" />
|
||||
<line x1="262.21" y1="84.27" x2="262.21" y2="99.53"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10; stroke-width:3px;" />
|
||||
<g>
|
||||
<line x1="159.81" y1="65.69" x2="157.36" y2="66.17"
|
||||
style="fill:none; stroke:#a7a9ac; stroke-miterlimit:10; stroke-width:3px;" />
|
||||
<line x1="154.33" y1="66.76" x2="139.7" y2="69.61"
|
||||
style="fill:none; stroke:#a7a9ac; stroke-dasharray:0 0 0 0 5.14 3.08 5.14 3.08; stroke-miterlimit:10; stroke-width:3px;" />
|
||||
<line x1="138.19" y1="69.91" x2="67.04" y2="83.78"
|
||||
style="fill:none; stroke:#a7a9ac; stroke-dasharray:0 0 0 0 0 0 5.14 3.08 5.14 3.08 5.14 3.08; stroke-miterlimit:10; stroke-width:3px;" />
|
||||
<line x1="65.53" y1="84.07" x2="63.07" y2="84.55"
|
||||
style="fill:none; stroke:#a7a9ac; stroke-miterlimit:10; stroke-width:3px;" />
|
||||
</g>
|
||||
<polyline points="151.51 61.52 163.08 65.23 155.28 73.06"
|
||||
style="fill:none; stroke:#a7a9ac; stroke-miterlimit:10; stroke-width:3px;" />
|
||||
<g>
|
||||
<g>
|
||||
<polygon
|
||||
points="60.79 91.08 60.79 98.53 42.96 122.09 42.96 110.74 47.63 104.58 48.03 104.56 48.04 106.86 59.98 91.08 60.79 91.08"
|
||||
style="fill:#fff;" />
|
||||
<polygon
|
||||
points="28.92 90.2 60.79 90.2 60.79 91.08 59.98 91.08 48.04 106.86 48.03 104.56 47.63 104.58 47.44 104.05 19.03 104.05 19.03 103.6 28.92 90.2"
|
||||
style="fill:#8dc63f;" />
|
||||
<polygon
|
||||
points="47.44 104.05 47.63 104.58 42.96 110.74 21.34 110.74 1.5 110.74 19.33 87.19 28.06 87.19 15.74 104.05 19.03 104.05 47.44 104.05"
|
||||
style="fill:#ed1c24;" />
|
||||
<path d="M42.96,110.74v11.35H21.34v-2.56c1.73,0,3.12-1.39,3.12-3.11s-1.39-3.12-3.12-3.12v-2.56h21.62Z"
|
||||
style="fill:#fff;" />
|
||||
<path
|
||||
d="M21.34,113.3c1.73,0,3.12,1.39,3.12,3.12s-1.39,3.11-3.12,3.11-3.11-1.39-3.11-3.11,1.39-3.12,3.11-3.12Z"
|
||||
style="fill:#fff;" />
|
||||
<path d="M21.34,119.53v2.56H1.5v-11.35H21.34v2.56c-1.72,0-3.11,1.39-3.11,3.12s1.39,3.11,3.11,3.11Z"
|
||||
style="fill:#fff;" />
|
||||
<polygon points="15.74 104.05 28.06 87.19 28.91 87.19 28.92 90.2 19.03 103.6 19.03 104.05 15.74 104.05"
|
||||
style="fill:#fff;" />
|
||||
</g>
|
||||
<g>
|
||||
<polygon
|
||||
points="60.79 91.08 60.79 98.53 42.96 122.09 21.34 122.09 1.5 122.09 1.5 110.74 19.33 87.19 28.06 87.19 28.91 87.19 28.92 90.2 60.79 90.2 60.79 91.08"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10; stroke-width:3px;" />
|
||||
<polyline points="59.98 91.08 48.04 106.86 48.03 104.56 47.63 104.58 42.96 110.74 21.34 110.74 1.5 110.74"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10; stroke-width:3px;" />
|
||||
<line x1="42.96" y1="110.74" x2="42.96" y2="122.09"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10; stroke-width:3px;" />
|
||||
<path
|
||||
d="M21.34,113.3c1.73,0,3.12,1.39,3.12,3.12s-1.39,3.11-3.12,3.11-3.11-1.39-3.11-3.11,1.39-3.12,3.11-3.12Z"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10;" />
|
||||
<polyline points="28.06 87.19 15.74 104.05 19.03 104.05 47.44 104.05"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<line x1="28.92" y1="90.2" x2="19.03" y2="103.6"
|
||||
style="fill:none; stroke:#231f20; stroke-linecap:round; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.1 KiB |
115
src/svelte-components/src/svgs/probe-put-away-xyz.svg
Normal file
@@ -0,0 +1,115 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?><svg id="Layer_1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 328.41 256.15">
|
||||
<g>
|
||||
<polygon
|
||||
points="326.91 163.14 264.27 245.91 118.57 245.91 118.57 230.65 181.21 147.88 326.91 147.88 326.91 163.14"
|
||||
style="fill:#fff; stroke:#231f20; stroke-miterlimit:10; stroke-width:3px;" />
|
||||
<polyline points="326.91 147.88 264.27 230.65 118.57 230.65"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10; stroke-width:3px;" />
|
||||
<line x1="264.27" y1="230.65" x2="264.27" y2="245.91"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10; stroke-width:3px;" />
|
||||
</g>
|
||||
<g>
|
||||
<polygon points="111.56 197.79 93.74 221.34 52.27 221.34 52.27 210 70.1 186.45 111.56 186.45 111.56 197.79"
|
||||
style="fill:#fff; stroke:#231f20; stroke-miterlimit:10; stroke-width:3px;" />
|
||||
<polyline points="111.56 186.45 93.74 210 52.27 210"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10; stroke-width:3px;" />
|
||||
<line x1="93.74" y1="210" x2="93.74" y2="221.34"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10; stroke-width:3px;" />
|
||||
<ellipse cx="99.9" cy="191.01" rx="3.83" ry="1.56" style="fill:none; stroke:#231f20; stroke-miterlimit:10;" />
|
||||
<circle cx="72.12" cy="215.67" r="3.12" style="fill:none; stroke:#231f20; stroke-miterlimit:10;" />
|
||||
<g>
|
||||
<polygon points="85.41 196.33 82.28 192.91 80.31 195.53 83.44 198.95 85.41 196.33"
|
||||
style="fill:#2bb673; opacity:.42;" />
|
||||
<polygon points="82.3 200.48 79.16 197.06 77.2 199.68 80.33 203.09 82.3 200.48"
|
||||
style="fill:#2bb673; opacity:.42;" />
|
||||
<polygon points="78.59 205.41 79.19 204.62 76.05 201.2 72.89 205.41 75.97 205.1 78.59 205.41"
|
||||
style="fill:#2bb673; opacity:.42;" />
|
||||
<polygon points="89.38 191.04 83.68 191.04 83.42 191.39 86.56 194.81 89.38 191.04"
|
||||
style="fill:#2bb673; opacity:.42;" />
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<path
|
||||
d="M69.35,223.89c-.57,.69-1.44,1.13-2.4,1.13-1.72,0-3.12-1.4-3.12-3.12,0-.71,.24-1.36,.63-1.88l5.79-6.56c.56-.56,1.34-.91,2.2-.91,1.72,0,3.12,1.4,3.12,3.12,0,.91-.39,1.72-1,2.29l-5.22,5.93Z"
|
||||
style="fill:#fff; stroke:#231f20; stroke-miterlimit:10;" />
|
||||
<path
|
||||
d="M70.06,221.91c0,.75-.27,1.45-.71,1.99-.57,.69-1.44,1.13-2.4,1.13-1.72,0-3.12-1.4-3.12-3.12,0-.71,.24-1.36,.63-1.88,.57-.75,1.47-1.23,2.48-1.23,1.72,0,3.12,1.4,3.12,3.12Z"
|
||||
style="fill:#fff; stroke:#231f20; stroke-miterlimit:10;" />
|
||||
</g>
|
||||
<g>
|
||||
<polygon
|
||||
points="163.4 164.83 158.3 166.52 153.19 164.83 153.19 109.62 152.06 107.91 152.06 60.47 164.53 60.47 164.53 107.91 163.4 109.62 163.4 164.83"
|
||||
style="fill:#fff; stroke:#231f20; stroke-miterlimit:10; stroke-width:3px;" />
|
||||
<line x1="153.19" y1="109.62" x2="163.4" y2="109.62"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10; stroke-width:3px;" />
|
||||
<line x1="153.19" y1="164.09" x2="163.4" y2="159.3"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<line x1="153.19" y1="158.09" x2="163.4" y2="153.3"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<line x1="153.19" y1="152.07" x2="163.4" y2="147.28"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<line x1="153.19" y1="146.09" x2="163.4" y2="141.31"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<line x1="153.19" y1="140.07" x2="163.4" y2="135.28"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<line x1="153.19" y1="133.87" x2="163.4" y2="129.08"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<line x1="153.19" y1="127.85" x2="163.4" y2="123.06"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<line x1="153.19" y1="121.87" x2="163.4" y2="117.08"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<line x1="153.19" y1="115.85" x2="163.4" y2="111.06"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
</g>
|
||||
<path d="M190.21,0V57.54c0,2.23-1.82,4.05-4.05,4.05h-56.36c-2.23,0-4.05-1.82-4.05-4.05V0"
|
||||
style="fill:#fff; stroke:#231f20; stroke-miterlimit:10; stroke-width:3px;" />
|
||||
<rect x="146.28" y="61.6" width="24.04" height="24.04"
|
||||
style="fill:#fff; stroke:#231f20; stroke-miterlimit:10; stroke-width:3px;" />
|
||||
<rect x="142.61" y="85.64" width="31.37" height="19.04"
|
||||
style="fill:#fff; stroke:#231f20; stroke-miterlimit:10; stroke-width:3px;" />
|
||||
<line x1="154.82" y1="85.64" x2="154.82" y2="104.68"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10; stroke-width:3px;" />
|
||||
<line x1="168.85" y1="85.64" x2="168.85" y2="104.68"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10; stroke-width:3px;" />
|
||||
<ellipse cx="148.67" cy="95.16" rx="2.39" ry="4.57"
|
||||
style="fill:#fff; stroke:#231f20; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<path
|
||||
d="M71.21,99.73c-1.32,0-2.39-2.05-2.39-4.57s1.07-4.57,2.39-4.57h14.44c1.32,0,2.39,2.05,2.39,4.57s-1.07,4.57-2.39,4.57h-14.44Z"
|
||||
style="fill:#fff; stroke:#231f20; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<ellipse cx="71.21" cy="95.16" rx="2.39" ry="4.57"
|
||||
style="fill:#fff; stroke:#231f20; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<g>
|
||||
<g>
|
||||
<line x1="94.11" y1="94.84" x2="97.61" y2="94.84"
|
||||
style="fill:none; stroke:#ed1c24; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<line x1="99.16" y1="94.84" x2="112.38" y2="94.84"
|
||||
style="fill:none; stroke:#ed1c24; stroke-dasharray:0 0 0 0 5.44 1.55 5.44 1.55; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<line x1="113.16" y1="94.84" x2="133.36" y2="94.84"
|
||||
style="fill:none; stroke:#ed1c24; stroke-dasharray:0 0 0 0 0 0 5.44 1.55 5.44 1.55 5.44 1.55; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<line x1="134.14" y1="94.84" x2="137.64" y2="94.84"
|
||||
style="fill:none; stroke:#ed1c24; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
</g>
|
||||
<polyline points="99.06 99.73 93.02 94.84 99.06 90"
|
||||
style="fill:none; stroke:#ed1c24; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<line x1="116.95" y1="190.46" x2="120.38" y2="189.78"
|
||||
style="fill:none; stroke:#ed1c24; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<line x1="121.44" y1="189.58" x2="130.44" y2="187.81"
|
||||
style="fill:none; stroke:#ed1c24; stroke-dasharray:0 0 0 0 3.78 1.08 3.78 1.08; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<line x1="130.97" y1="187.71" x2="144.73" y2="185"
|
||||
style="fill:none; stroke:#ed1c24; stroke-dasharray:0 0 0 0 0 0 3.78 1.08 3.78 1.08 3.78 1.08; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<line x1="145.26" y1="184.9" x2="148.7" y2="184.23"
|
||||
style="fill:none; stroke:#ed1c24; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
</g>
|
||||
<polyline points="122.75 194.3 115.88 190.67 120.88 184.75"
|
||||
style="fill:none; stroke:#ed1c24; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
</g>
|
||||
<path
|
||||
d="M69.9,93.3c-9.07-.24-17.32,4.41-24.11,10.04s-11.88,12.04-15.84,19.44c-3.11,5.81-5.51,11.98-5.9,18.6-.35,5.97,.4,12,1.35,17.89,2.21,13.7,5.99,27.09,8.74,40.68,1.18,5.8,2.23,11.68,2.47,17.61,.23,5.59-.33,11.4-3.15,16.41-2.42,4.3-6.54,6.35-11.01,7.98-5.9,2.15-11.79,4.15-17.12,7.56-1.66,1.06-3.24,2.24-4.78,3.47-.8,.64-.65,1.98,0,2.65,.77,.79,1.87,.63,2.65,0,5.19-4.16,11.12-6.84,17.35-9.03,4.73-1.67,9.74-3.29,13.34-6.97,4.21-4.31,5.86-10.66,6.38-16.5,.48-5.48-.24-11.05-1.1-16.46-2.14-13.43-5.87-26.56-8.58-39.87-1.26-6.18-2.38-12.42-2.75-18.72-.32-5.39,0-10.38,1.81-15.46,2.77-7.7,7.16-14.85,12.71-20.85s12.9-11.91,21.18-14c2.09-.53,4.2-.76,6.36-.7,2.41,.06,2.41-3.69,0-3.75h0Z"
|
||||
style="fill:#231f20;" />
|
||||
<path
|
||||
d="M64.5,221.06c-1.88,3.18-2.66,6.86-3.58,10.4-.78,3.05-1.59,6.62-4.02,8.83-1.32,1.2-3.18,1.8-4.87,2.26-2.03,.56-4.11,.84-6.21,.96-4.68,.27-9.37-.13-14.04-.35-5.05-.24-10.18-.31-15.11,.94-2.34,.59-1.35,4.21,1,3.62,9.17-2.32,18.84,.08,28.16-.46,4.16-.24,8.99-.9,12.5-3.33,3.09-2.14,4.57-5.69,5.59-9.17,1.15-3.94,1.71-8.22,3.82-11.8,1.23-2.08-2.01-3.97-3.24-1.89h0Z"
|
||||
style="fill:#231f20;" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 8.5 KiB |
134
src/svelte-components/src/svgs/probe-put-away-z.svg
Normal file
@@ -0,0 +1,134 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?><svg id="Layer_1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 328.41 256.15">
|
||||
<g>
|
||||
<g>
|
||||
<polygon
|
||||
points="111.57 190.34 111.57 197.79 93.74 221.35 93.74 210.01 98.41 203.84 98.81 203.83 98.82 206.12 110.76 190.34 111.57 190.34"
|
||||
style="fill:#fff;" />
|
||||
<polygon
|
||||
points="98.22 203.31 69.81 203.31 69.81 202.86 79.7 189.46 111.57 189.46 111.57 190.34 110.76 190.34 98.82 206.12 98.81 203.83 98.41 203.84 98.22 203.31"
|
||||
style="fill:#8dc63f;" />
|
||||
<polygon
|
||||
points="98.22 203.31 98.41 203.84 93.74 210.01 72.12 210.01 52.28 210.01 70.11 186.45 78.83 186.45 66.52 203.31 69.81 203.31 98.22 203.31"
|
||||
style="fill:#ed1c24;" />
|
||||
<path d="M93.74,210.01v11.34h-21.62v-2.56c1.72,0,3.12-1.39,3.12-3.11s-1.4-3.12-3.12-3.12v-2.55h21.62Z"
|
||||
style="fill:#fff;" />
|
||||
<path
|
||||
d="M72.12,212.56c1.72,0,3.12,1.39,3.12,3.12s-1.4,3.11-3.12,3.11-3.12-1.39-3.12-3.11,1.4-3.12,3.12-3.12Z"
|
||||
style="fill:#fff;" />
|
||||
<path d="M72.12,218.79v2.56h-19.84v-11.34h19.84v2.55c-1.72,0-3.12,1.39-3.12,3.12s1.4,3.11,3.12,3.11Z"
|
||||
style="fill:#fff;" />
|
||||
<polygon points="79.7 189.46 69.81 202.86 69.81 203.31 66.52 203.31 78.83 186.45 79.68 186.45 79.7 189.46"
|
||||
style="fill:#fff;" />
|
||||
</g>
|
||||
<g>
|
||||
<polygon
|
||||
points="111.57 190.34 111.57 197.79 93.74 221.35 72.12 221.35 52.28 221.35 52.28 210.01 70.11 186.45 78.83 186.45 79.68 186.45 79.7 189.46 111.57 189.46 111.57 190.34"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10; stroke-width:3px;" />
|
||||
<polyline
|
||||
points="110.76 190.34 98.82 206.12 98.81 203.83 98.41 203.84 93.74 210.01 72.12 210.01 52.28 210.01"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10; stroke-width:3px;" />
|
||||
<line x1="93.74" y1="210.01" x2="93.74" y2="221.35"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10; stroke-width:3px;" />
|
||||
<path
|
||||
d="M72.12,212.56c1.72,0,3.12,1.39,3.12,3.12s-1.4,3.11-3.12,3.11-3.12-1.39-3.12-3.11,1.4-3.12,3.12-3.12Z"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10;" />
|
||||
<polyline points="78.83 186.45 66.52 203.31 69.81 203.31 98.22 203.31"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<line x1="79.7" y1="189.46" x2="69.81" y2="202.86"
|
||||
style="fill:none; stroke:#231f20; stroke-linecap:round; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<polygon
|
||||
points="326.91 163.14 264.27 245.91 118.57 245.91 118.57 230.65 181.21 147.88 326.91 147.88 326.91 163.14"
|
||||
style="fill:#fff; stroke:#231f20; stroke-miterlimit:10; stroke-width:3px;" />
|
||||
<polyline points="326.91 147.88 264.27 230.65 118.57 230.65"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10; stroke-width:3px;" />
|
||||
<line x1="264.27" y1="230.65" x2="264.27" y2="245.91"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10; stroke-width:3px;" />
|
||||
</g>
|
||||
<g>
|
||||
<path
|
||||
d="M69.35,223.89c-.57,.69-1.44,1.13-2.4,1.13-1.72,0-3.12-1.4-3.12-3.12,0-.71,.24-1.36,.63-1.88l5.79-6.56c.56-.56,1.34-.91,2.2-.91,1.72,0,3.12,1.4,3.12,3.12,0,.91-.39,1.72-1,2.29l-5.22,5.93Z"
|
||||
style="fill:#fff; stroke:#231f20; stroke-miterlimit:10;" />
|
||||
<path
|
||||
d="M70.06,221.91c0,.75-.27,1.45-.71,1.99-.57,.69-1.44,1.13-2.4,1.13-1.72,0-3.12-1.4-3.12-3.12,0-.71,.24-1.36,.63-1.88,.57-.75,1.47-1.23,2.48-1.23,1.72,0,3.12,1.4,3.12,3.12Z"
|
||||
style="fill:#fff; stroke:#231f20; stroke-miterlimit:10;" />
|
||||
</g>
|
||||
<g>
|
||||
<polygon
|
||||
points="163.4 164.83 158.3 166.52 153.19 164.83 153.19 109.62 152.06 107.91 152.06 60.47 164.53 60.47 164.53 107.91 163.4 109.62 163.4 164.83"
|
||||
style="fill:#fff; stroke:#231f20; stroke-miterlimit:10; stroke-width:3px;" />
|
||||
<line x1="153.19" y1="109.62" x2="163.4" y2="109.62"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10; stroke-width:3px;" />
|
||||
<line x1="153.19" y1="164.09" x2="163.4" y2="159.3"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<line x1="153.19" y1="158.09" x2="163.4" y2="153.3"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<line x1="153.19" y1="152.07" x2="163.4" y2="147.28"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<line x1="153.19" y1="146.09" x2="163.4" y2="141.31"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<line x1="153.19" y1="140.07" x2="163.4" y2="135.28"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<line x1="153.19" y1="133.87" x2="163.4" y2="129.08"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<line x1="153.19" y1="127.85" x2="163.4" y2="123.06"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<line x1="153.19" y1="121.87" x2="163.4" y2="117.08"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<line x1="153.19" y1="115.85" x2="163.4" y2="111.06"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
</g>
|
||||
<path d="M190.21,0V57.54c0,2.23-1.82,4.05-4.05,4.05h-56.36c-2.23,0-4.05-1.82-4.05-4.05V0"
|
||||
style="fill:#fff; stroke:#231f20; stroke-miterlimit:10; stroke-width:3px;" />
|
||||
<rect x="146.28" y="61.6" width="24.04" height="24.04"
|
||||
style="fill:#fff; stroke:#231f20; stroke-miterlimit:10; stroke-width:3px;" />
|
||||
<rect x="142.61" y="85.64" width="31.37" height="19.04"
|
||||
style="fill:#fff; stroke:#231f20; stroke-miterlimit:10; stroke-width:3px;" />
|
||||
<line x1="154.82" y1="85.64" x2="154.82" y2="104.68"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10; stroke-width:3px;" />
|
||||
<line x1="168.85" y1="85.64" x2="168.85" y2="104.68"
|
||||
style="fill:none; stroke:#231f20; stroke-miterlimit:10; stroke-width:3px;" />
|
||||
<ellipse cx="148.67" cy="95.16" rx="2.39" ry="4.57"
|
||||
style="fill:#fff; stroke:#231f20; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<path
|
||||
d="M71.21,99.73c-1.32,0-2.39-2.05-2.39-4.57s1.07-4.57,2.39-4.57h14.44c1.32,0,2.39,2.05,2.39,4.57s-1.07,4.57-2.39,4.57h-14.44Z"
|
||||
style="fill:#fff; stroke:#231f20; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<ellipse cx="71.21" cy="95.16" rx="2.39" ry="4.57"
|
||||
style="fill:#fff; stroke:#231f20; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<g>
|
||||
<g>
|
||||
<line x1="94.11" y1="94.84" x2="97.61" y2="94.84"
|
||||
style="fill:none; stroke:#ed1c24; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<line x1="99.16" y1="94.84" x2="112.38" y2="94.84"
|
||||
style="fill:none; stroke:#ed1c24; stroke-dasharray:0 0 0 0 5.44 1.55 5.44 1.55; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<line x1="113.16" y1="94.84" x2="133.36" y2="94.84"
|
||||
style="fill:none; stroke:#ed1c24; stroke-dasharray:0 0 0 0 0 0 5.44 1.55 5.44 1.55 5.44 1.55; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<line x1="134.14" y1="94.84" x2="137.64" y2="94.84"
|
||||
style="fill:none; stroke:#ed1c24; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
</g>
|
||||
<polyline points="99.06 99.73 93.02 94.84 99.06 90"
|
||||
style="fill:none; stroke:#ed1c24; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<line x1="116.95" y1="190.46" x2="120.38" y2="189.78"
|
||||
style="fill:none; stroke:#ed1c24; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<line x1="121.44" y1="189.58" x2="130.44" y2="187.81"
|
||||
style="fill:none; stroke:#ed1c24; stroke-dasharray:0 0 0 0 3.78 1.08 3.78 1.08; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<line x1="130.97" y1="187.71" x2="144.73" y2="185"
|
||||
style="fill:none; stroke:#ed1c24; stroke-dasharray:0 0 0 0 0 0 3.78 1.08 3.78 1.08 3.78 1.08; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
<line x1="145.26" y1="184.9" x2="148.7" y2="184.23"
|
||||
style="fill:none; stroke:#ed1c24; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
</g>
|
||||
<polyline points="122.75 194.3 115.88 190.67 120.88 184.75"
|
||||
style="fill:none; stroke:#ed1c24; stroke-miterlimit:10; stroke-width:2px;" />
|
||||
</g>
|
||||
<path
|
||||
d="M69.9,93.3c-9.07-.24-17.32,4.41-24.11,10.04s-11.88,12.04-15.84,19.44c-3.11,5.81-5.51,11.98-5.9,18.6-.35,5.97,.4,12,1.35,17.89,2.21,13.7,5.99,27.09,8.74,40.68,1.18,5.8,2.23,11.68,2.47,17.61,.23,5.59-.33,11.4-3.15,16.41-2.42,4.3-6.54,6.35-11.01,7.98-5.9,2.15-11.79,4.15-17.12,7.56-1.66,1.06-3.24,2.24-4.78,3.47-.8,.64-.65,1.98,0,2.65,.77,.79,1.87,.63,2.65,0,5.19-4.16,11.12-6.84,17.35-9.03,4.73-1.67,9.74-3.29,13.34-6.97,4.21-4.31,5.86-10.66,6.38-16.5,.48-5.48-.24-11.05-1.1-16.46-2.14-13.43-5.87-26.56-8.58-39.87-1.26-6.18-2.38-12.42-2.75-18.72-.32-5.39,0-10.38,1.81-15.46,2.77-7.7,7.16-14.85,12.71-20.85s12.9-11.91,21.18-14c2.09-.53,4.2-.76,6.36-.7,2.41,.06,2.41-3.69,0-3.75h0Z"
|
||||
style="fill:#231f20;" />
|
||||
<path
|
||||
d="M64.5,221.06c-1.88,3.18-2.66,6.86-3.58,10.4-.78,3.05-1.59,6.62-4.02,8.83-1.32,1.2-3.18,1.8-4.87,2.26-2.03,.56-4.11,.84-6.21,.96-4.68,.27-9.37-.13-14.04-.35-5.05-.24-10.18-.31-15.11,.94-2.34,.59-1.35,4.21,1,3.62,9.17-2.32,18.84,.08,28.16-.46,4.16-.24,8.99-.9,12.5-3.33,3.09-2.14,4.57-5.69,5.59-9.17,1.15-3.94,1.71-8.22,3.82-11.8,1.23-2.08-2.01-3.97-3.24-1.89h0Z"
|
||||
style="fill:#231f20;" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 9.7 KiB |
46
src/svelte-components/src/theme/_smui-theme.scss
Normal file
@@ -0,0 +1,46 @@
|
||||
@use "sass:color";
|
||||
|
||||
@use "@material/theme/color-palette";
|
||||
|
||||
// Svelte Colors!
|
||||
@use "@material/theme/index" as theme with (
|
||||
$primary: #0078e7,
|
||||
$secondary: #676778,
|
||||
$surface: #fff,
|
||||
$background: #fff,
|
||||
$error: color-palette.$red-900,
|
||||
$on-surface: #777
|
||||
);
|
||||
|
||||
@use "@material/elevation/mdc-elevation";
|
||||
@use "@material/list";
|
||||
|
||||
@include list.deprecated-core-styles;
|
||||
|
||||
:root {
|
||||
--mdc-theme-text-primary-on-background: #777;
|
||||
|
||||
.mdc-dialog .mdc-dialog__container {
|
||||
transition: margin-bottom 0.5s;
|
||||
}
|
||||
|
||||
.mdc-dialog .mdc-dialog__content {
|
||||
color: #777;
|
||||
}
|
||||
|
||||
.mdc-dialog .mdc-dialog__title {
|
||||
color: #777;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
input::-webkit-outer-spin-button,
|
||||
input::-webkit-inner-spin-button {
|
||||
-webkit-appearance: none;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* Firefox */
|
||||
input[type="number"] {
|
||||
-moz-appearance: textfield;
|
||||
}
|
||||
}
|
||||
12
src/svelte-components/src/theme/dark/_smui-theme.scss
Normal file
@@ -0,0 +1,12 @@
|
||||
@use 'sass:color';
|
||||
|
||||
@use '@material/theme/color-palette';
|
||||
|
||||
// Svelte Colors! (Dark Theme)
|
||||
@use '@material/theme/index' as theme with (
|
||||
$primary: #ff3e00,
|
||||
$secondary: color.scale(#676778, $whiteness: -10%),
|
||||
$surface: color.adjust(color-palette.$grey-900, $blue: +4),
|
||||
$background: #000,
|
||||
$error: color-palette.$red-700
|
||||
);
|
||||
2
src/svelte-components/src/vite-env.d.ts
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
/// <reference types="svelte" />
|
||||
/// <reference types="vite/client" />
|
||||
7
src/svelte-components/svelte.config.js
Normal file
@@ -0,0 +1,7 @@
|
||||
import sveltePreprocess from "svelte-preprocess";
|
||||
|
||||
export default {
|
||||
// Consult https://github.com/sveltejs/svelte-preprocess
|
||||
// for more information about preprocessors
|
||||
preprocess: sveltePreprocess()
|
||||
};
|
||||
27
src/svelte-components/tsconfig.json
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"extends": "@tsconfig/svelte/tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"target": "esnext",
|
||||
"useDefineForClassFields": true,
|
||||
"module": "esnext",
|
||||
"resolveJsonModule": true,
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"$lib/*": ["src/lib/*"],
|
||||
"$components/*": ["src/components/*"],
|
||||
"$dialogs/*": ["src/dialogs/*"]
|
||||
},
|
||||
/**
|
||||
* Typecheck JS in `.svelte` and `.js` files by default.
|
||||
* Disable checkJs if you'd like to use dynamic types in JS.
|
||||
* Note that setting allowJs false does not prevent the use
|
||||
* of JS in `.svelte` files.
|
||||
*/
|
||||
"allowJs": true,
|
||||
"checkJs": true,
|
||||
"isolatedModules": true,
|
||||
"moduleSuffixes": [".svelte", ""]
|
||||
},
|
||||
"include": ["src/**/*.d.ts", "src/**/*.ts", "src/**/*.js", "src/**/*.svelte"],
|
||||
"references": [{ "path": "./tsconfig.node.json" }]
|
||||
}
|
||||
8
src/svelte-components/tsconfig.node.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"composite": true,
|
||||
"module": "esnext",
|
||||
"moduleResolution": "node"
|
||||
},
|
||||
"include": ["vite.config.ts"]
|
||||
}
|
||||
26
src/svelte-components/vite.config.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import { defineConfig } from "vite";
|
||||
import { svelte } from "@sveltejs/vite-plugin-svelte";
|
||||
import { resolve } from "path";
|
||||
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig({
|
||||
plugins: [
|
||||
svelte()
|
||||
],
|
||||
resolve: {
|
||||
alias: {
|
||||
$lib: resolve("./src/lib"),
|
||||
$dialogs: resolve("./src/dialogs"),
|
||||
$components: resolve("./src/components")
|
||||
}
|
||||
},
|
||||
build: {
|
||||
target: "chrome60",
|
||||
lib: {
|
||||
entry: resolve(__dirname, "src/main.ts"),
|
||||
name: "SvelteComponents",
|
||||
formats: [ "iife" ],
|
||||
fileName: () => "index.js"
|
||||
}
|
||||
}
|
||||
});
|
||||