Some better typing and infra for integration testing.

This commit is contained in:
rgthree
2024-07-24 22:30:06 -04:00
parent 37d8759dbf
commit 00841a8baf
9 changed files with 399 additions and 163 deletions
+34 -19
View File
@@ -6,26 +6,30 @@ from shutil import rmtree, copytree, ignore_patterns
from glob import glob
import time
import re
import argparse
from py.log import COLORS
from py.config import RGTHREE_CONFIG
start = time.time()
parser = argparse.ArgumentParser()
parser.add_argument("-t", "--with-tests", default=False, action="store_true")
args = parser.parse_args()
THIS_DIR = os.path.dirname(os.path.abspath(__file__))
DIR_SRC_WEB = os.path.abspath(f'{THIS_DIR}/src_web/')
DIR_WEB = os.path.abspath(f'{THIS_DIR}/web/')
DIR_WEB_COMFYUI = os.path.abspath(f'{DIR_WEB}/comfyui/')
rmtree(DIR_WEB)
def log_step(msg=None, status=None):
""" Logs a step keeping track of timing and initial msg. """
global step_msg # pylint: disable=W0601
global step_start # pylint: disable=W0601
if msg:
step_msg = f'▻ [Starting] {msg}...'
tag=f'{COLORS["YELLOW"]}[ Notice ]' if status == 'Notice' else f'{COLORS["RESET"]}[Starting]'
step_msg = f'▻ {tag}{COLORS["RESET"]} {msg}...'
step_start = time.time()
print(step_msg, end="\r")
elif status:
@@ -34,12 +38,11 @@ def log_step(msg=None, status=None):
status_msg=f'{COLORS["RED"]}⤫ {status}{COLORS["RESET"]}'
else:
status_msg=f'{COLORS["BRIGHT_GREEN"]}🗸 {status}{COLORS["RESET"]}'
print(
f'{step_msg.ljust(50, ".")} {COLORS["BRIGHT_GREEN"]}🗸 {status}{COLORS["RESET"]} ({step_time}s)'
)
print(f'{step_msg.ljust(64, ".")} {status_msg} ({step_time}s)')
log_step(msg='Copying web directory')
rmtree(DIR_WEB)
copytree(DIR_SRC_WEB, DIR_WEB, ignore=ignore_patterns("typings*", "*.ts", "*.scss"))
log_step(status="Done")
@@ -47,6 +50,18 @@ log_step(msg='TypeScript')
checked = subprocess.run(["node", "./node_modules/typescript/bin/tsc"], check=True)
log_step(status="Done")
if args.with_tests:
log_step(msg='Removing directories (KEEPING TESTING)', status="Notice")
else:
log_step(msg='Removing uneeded directories')
test_path=os.path.join(DIR_WEB, 'comfyui', 'tests')
if os.path.exists(test_path):
rmtree(test_path)
rmtree(os.path.join(DIR_WEB, 'comfyui', 'testing'))
# Always remove the dummy scripts_comfy directory
rmtree(os.path.join(DIR_WEB, 'scripts_comfy'))
log_step(status="Done")
scsss = glob(os.path.join(DIR_SRC_WEB, "**", "*.scss"), recursive=True)
log_step(msg=f'SASS for {len(scsss)} files')
scsss = [i.replace(THIS_DIR, '.') for i in scsss]
@@ -64,19 +79,19 @@ log_step(status="Done")
# "src_web/common" directory, but then need to rewrite the comfyui JS files to load from
# "../../rgthree/common" (which we map correctly in rgthree_server.py).
log_step(msg='Cleaning Imports')
print('▻ [Starting] Cleaning Imports...', end="\r")
web_subfolders = [f.name for f in os.scandir(DIR_WEB) if f.is_dir()]
for subfolder in web_subfolders:
js_files = glob(os.path.join(DIR_WEB, subfolder, '*.js'), recursive=True)
for file in js_files:
with open(file, 'r', encoding="utf-8") as f:
filedata = f.read()
if subfolder == 'comfyui':
filedata = re.sub(r'(from\s+["\'])rgthree/', '\\1../../rgthree/', filedata)
else:
filedata = re.sub(r'(from\s+["\'])rgthree/', '\\1../', filedata)
with open(file, 'w', encoding="utf-8") as f:
f.write(filedata)
js_files = glob(os.path.join(DIR_WEB, '**', '*.js'), recursive=True)
for file in js_files:
rel_path = file.replace(f'{DIR_WEB}/', "")
with open(file, 'r', encoding="utf-8") as f:
filedata = f.read()
num = rel_path.count(os.sep)
if rel_path.startswith('comfyui'):
filedata = re.sub(r'(from\s+["\'])rgthree/', f'\\1{"../" * (num + 1)}rgthree/', filedata)
filedata = re.sub(r'(from\s+["\'])scripts/', f'\\1{"../" * (num + 1)}scripts/', filedata)
else:
filedata = re.sub(r'(from\s+["\'])rgthree/', f'\\1{"../" * num}', filedata)
with open(file, 'w', encoding="utf-8") as f:
f.write(filedata)
log_step(status="Done")
print(f'Finished all in {round(time.time() - start, 3)}s')
+7 -7
View File
@@ -18,14 +18,14 @@ COLORS = {
'BRIGHT_CYAN': '\33[96m',
'BRIGHT_WHITE': '\33[97m',
# Styles.
'RESET': '\33[0m',
'BOLD': '\33[1m',
'RESET': '\33[00m',
'BOLD': '\33[01m',
'NORMAL': '\33[22m',
'ITALIC': '\33[3m',
'UNDERLINE': '\33[4m',
'BLINK': '\33[5m',
'BLINK2': '\33[6m',
'SELECTED': '\33[7m',
'ITALIC': '\33[03m',
'UNDERLINE': '\33[04m',
'BLINK': '\33[05m',
'BLINK2': '\33[06m',
'SELECTED': '\33[07m',
# Backgrounds
'BG_BLACK': '\33[40m',
'BG_RED': '\33[41m',
+67
View File
@@ -0,0 +1,67 @@
import { app } from "scripts/app.js";
import { NodeTypesString } from "../constants.js";
import { wait } from "rgthree/common/shared_utils.js";
import type { LGraphNode } from "typings/litegraph.js";
type addNodeOptions = {
placement?: string;
};
/**
* A testing environment to make setting up, clearing, and queuing more predictable in an
* integration test environment.
*/
export class ComfyUITestEnvironment {
private lastNode: LGraphNode | null = null;
private maxY = 0;
constructor() {}
async addNode(nodeString: string, options: addNodeOptions = {}) {
const [canvas, graph] = [app.canvas, app.graph];
const node = LiteGraph.createNode(nodeString);
let x = 0;
let y = 30;
if (this.lastNode) {
const placement = options.placement || "right";
if (placement === "under") {
x = this.lastNode.pos[0];
y = this.lastNode.pos[1] + this.lastNode.size[1] + 30;
} else if (placement === "right") {
x = this.lastNode.pos[0] + this.lastNode.size[0] + 100;
y = this.lastNode.pos[1];
} else if (placement === "start") {
x = 0;
y = this.maxY + 50;
}
}
canvas.graph.add(node);
node.pos = [x, y];
canvas.selectNode(node);
app.graph.setDirtyCanvas(true, true);
await wait();
this.lastNode = node;
this.maxY = Math.max(this.maxY, y + this.lastNode.size[1]);
return (this.lastNode = node);
}
async clear() {
app.clean();
app.graph.clear();
const nodeConfig = await this.addNode(NodeTypesString.KSAMPLER_CONFIG);
const displayAny = await this.addNode(NodeTypesString.DISPLAY_ANY);
nodeConfig.widgets[0]!.value = Math.round(Math.random() * 100);
nodeConfig.connect(0, displayAny, 0);
await this.queuePrompt();
app.clean();
app.graph.clear();
this.lastNode = null;
this.maxY = 0;
await wait();
}
async queuePrompt() {
await app.queuePrompt();
await wait(150);
}
}
+133
View File
@@ -0,0 +1,133 @@
/**
* @fileoverview A set of methods that mimic a bit of the Jasmine testing library, but simpler and
* more succinct for manipulating a comfy integration test.
*/
import { wait } from "rgthree/common/shared_utils.js";
type TestContext = {
label?: string;
beforeEach?: Function[];
};
let contexts: TestContext[] = [];
export function describe(label: string, fn: Function) {
return async () => {
await describeRun(label, fn);
};
}
export async function describeRun(label: string, fn: Function) {
await wait();
contexts.push({ label });
console.group(`[Start] ${contexts[contexts.length - 1]!.label}`);
await fn();
contexts.pop();
console.groupEnd();
}
export async function should(declaration: string, fn: Function) {
if (!contexts[contexts.length - 1]) {
throw Error("Called should outside of a describe.");
}
console.group(`...should ${declaration}`);
try {
for (const context of contexts) {
for (const beforeEachFn of context?.beforeEach || []) {
await beforeEachFn();
}
}
await fn();
} catch (e: any) {
fail(e);
}
console.groupEnd();
}
export async function beforeEach(fn: Function) {
if (!contexts[contexts.length - 1]) {
throw Error("Called beforeEach outside of a describe.");
}
const last = contexts[contexts.length - 1]!;
last.beforeEach = last?.beforeEach || [];
last.beforeEach.push(fn);
}
export function fail(e: Error) {
log(`X Failure: ${e}`, "color:#600; background:#fdd; padding: 2px 6px;");
}
function log(msg: string, styles: string) {
if (styles) {
console.log(`%c ${msg}`, styles);
} else {
console.log(msg);
}
}
class Expectation {
private propertyLabel: string | null = "";
private expectedLabel: string | null = "";
private expectedFn!: (v: any) => boolean;
private value: any;
constructor(value: any) {
this.value = value;
}
toBe(labelOrExpected: any, maybeExpected?: any) {
const expected = maybeExpected !== undefined ? maybeExpected : labelOrExpected;
this.propertyLabel = maybeExpected !== undefined ? labelOrExpected : null;
this.expectedLabel = JSON.stringify(expected);
this.expectedFn = (v) => v == expected;
return this.toBeEval();
}
toBeUndefined(propertyLabel: string) {
this.expectedFn = (v) => v === undefined;
this.propertyLabel = propertyLabel || "";
this.expectedLabel = "undefined";
return this.toBeEval(true);
}
toBeNullOrUndefined(propertyLabel: string) {
this.expectedFn = (v) => v == null;
this.propertyLabel = propertyLabel || "";
this.expectedLabel = "null or undefined";
return this.toBeEval(true);
}
toBeTruthy(propertyLabel: string) {
this.expectedFn = (v) => !v;
this.propertyLabel = propertyLabel || "";
this.expectedLabel = "truthy";
return this.toBeEval(false);
}
toBeANumber(propertyLabel: string) {
this.expectedFn = (v) => typeof v === "number";
this.propertyLabel = propertyLabel || "";
this.expectedLabel = "a number";
return this.toBeEval();
}
toBeEval(strict = false) {
let evaluation = this.expectedFn(this.value);
let msg = `Expected ${this.propertyLabel ? this.propertyLabel + " to be " : ""}${
this.expectedLabel
}`;
msg += evaluation ? "." : `, but was ${JSON.stringify(this.value)}`;
this.log(evaluation, msg);
return evaluation;
}
log(value: boolean, msg: string) {
if (value) {
log(`🗸 ${msg}`, "color:#060; background:#cec; padding: 2px 6px;");
} else {
log(`X ${msg}`, "color:#600; background:#fdd; padding: 2px 6px;");
}
}
}
export function expect(value: any, msg?: string) {
const expectation = new Expectation(value);
if (msg) {
expectation.log(value, msg);
}
return expectation;
}
+6
View File
@@ -0,0 +1,6 @@
Here lies dummy ts files that decalre/export ComfyUI's own scripts files as typed types w/o needing
to symlink to the actual implementation.
Actual code in the comfyui/ directory can import these like `import {app} from "/scripts/app.js"`
and have access to `app` as the fully typed `ComfyApp`. The `__build__.py` script will rewrite these
to the relative browser path.
+7
View File
@@ -0,0 +1,7 @@
import { ComfyApp } from "../typings/comfy";
/**
* A dummy ComfyApp that we can import from our code, which we'll rewrite later to the comfyui
* hosted app.js
*/
export declare const app: ComfyApp;
+10 -3
View File
@@ -1,11 +1,17 @@
import type { LGraphNode, IWidget, SerializedLGraphNode, LGraph } from "./litegraph";
import type { LGraphNode, IWidget, SerializedLGraphNode, LGraph, LGraphCanvas, LiteGraph as TLiteGraph } from "./litegraph";
import type {Constructor, SerializedGraph} from './index';
declare global {
const LiteGraph: typeof TLiteGraph;
}
// @rgthree: Types on ComfyApp as needed.
export interface ComfyApp {
extensions: ComfyExtension[];
queuePrompt(number: number, batchCount = 1): void;
async queuePrompt(number?: number, batchCount = 1): Promise<void>;
graph: LGraph;
canvas: LGraphCanvas;
clean() : void;
registerExtension(extension: ComfyExtension): void;
}
@@ -70,11 +76,12 @@ export interface ComfyExtension {
>;
/**
* Allows the extension to add additional handling to the node before it is registered with LGraph
* @rgthree changed nodeType from `typeof LGraphNode` to `ComfyNodeConstructor`
* @param nodeType The node class (not an instance)
* @param nodeData The original node object info config object
* @param app The ComfyUI app instance
*/
beforeRegisterNodeDef?(nodeType: typeof LGraphNode, nodeData: ComfyObjectInfo, app: ComfyApp): Promise<void>;
beforeRegisterNodeDef?(nodeType: ComfyNodeConstructor, nodeData: ComfyObjectInfo, app: ComfyApp): Promise<void>;
/**
* Allows the extension to register additional nodes with LGraph after standard nodes are added
* @param app The ComfyUI app instance
+2 -1
View File
@@ -9,7 +9,8 @@
"paths": {
"typings/*": ["src_web/typings/*"],
"rgthree/common/*": ["src_web/common/*"],
"node_modules": ["node_modules/*"]
"node_modules": ["node_modules/*"],
"scripts/*": ["src_web/scripts_comfy/*"],
},
"outDir": "web/",
"removeComments": true,
+133 -133
View File
@@ -1,156 +1,156 @@
import { createElement as $el } from "../utils_dom.js";
export const logoRgthree = `<svg viewBox="0 0 256 256" fill="currentColor" class="rgthree-logo">
<path d="M88.503,158.997 L152.731,196.103 L152.738,196.092 L152.762,196.103 L152.769,196.106 L152.771,196.103 L183.922,142.084 L174.153,136.437 L148.611,180.676 L101.512,153.484 L132.193,30.415 L156.124,71.869 L165.896,66.225 L128.002,0.59 "></path>
<path d="M55.586,148.581l13.44,47.521l0.014,0.051l0.168-0.051l10.689-3.022l-6.589-23.313l45.609,26.335l0.087,0.051l0.027-0.051 l5.617-9.718l-42.648-24.622l35.771-143.45L33.232,164.729l9.77,5.645L55.586,148.581z M87.394,93.484l-16.708,67.018l-5.018-17.747 l-8.028,2.27L87.394,93.484z"></path>
<path d="M189.85,107.717 L137.892,137.718 L143.532,147.49 L185.723,123.133 L231.109,201.746 L24.895,201.746 L37.363,180.146 L27.592,174.505 L5.347,213.03 L250.653,213.03 "></path>
<path d="M5.347,247.299v8.111h245.307v-8.111l-41.94-0.003c-1.336,0-2.404-1.065-2.441-2.396v-12.14 c0.037-1.315,1.089-2.368,2.41-2.385h41.972v-8.11H5.347v8.11h41.951c1.338,0.017,2.427,1.104,2.427,2.449v12.01 c0,1.365-1.105,2.462-2.457,2.462L5.347,247.299z M139.438,247.296c-1.334,0-2.406-1.065-2.439-2.396v-12.14 c0.033-1.315,1.085-2.368,2.41-2.385h46.415c1.335,0.017,2.425,1.104,2.425,2.449v12.01c0,1.365-1.103,2.462-2.459,2.462H139.438z M70.193,247.296c-1.339,0-2.408-1.065-2.441-2.396v-12.14c0.033-1.315,1.086-2.368,2.407-2.385h46.418 c1.336,0.017,2.425,1.104,2.425,2.449v12.01c0,1.365-1.103,2.462-2.458,2.462H70.193z"></path>
export const logoRgthree = `<svg viewBox="0 0 256 256" fill="currentColor" class="rgthree-logo">
<path d="M88.503,158.997 L152.731,196.103 L152.738,196.092 L152.762,196.103 L152.769,196.106 L152.771,196.103 L183.922,142.084 L174.153,136.437 L148.611,180.676 L101.512,153.484 L132.193,30.415 L156.124,71.869 L165.896,66.225 L128.002,0.59 "></path>
<path d="M55.586,148.581l13.44,47.521l0.014,0.051l0.168-0.051l10.689-3.022l-6.589-23.313l45.609,26.335l0.087,0.051l0.027-0.051 l5.617-9.718l-42.648-24.622l35.771-143.45L33.232,164.729l9.77,5.645L55.586,148.581z M87.394,93.484l-16.708,67.018l-5.018-17.747 l-8.028,2.27L87.394,93.484z"></path>
<path d="M189.85,107.717 L137.892,137.718 L143.532,147.49 L185.723,123.133 L231.109,201.746 L24.895,201.746 L37.363,180.146 L27.592,174.505 L5.347,213.03 L250.653,213.03 "></path>
<path d="M5.347,247.299v8.111h245.307v-8.111l-41.94-0.003c-1.336,0-2.404-1.065-2.441-2.396v-12.14 c0.037-1.315,1.089-2.368,2.41-2.385h41.972v-8.11H5.347v8.11h41.951c1.338,0.017,2.427,1.104,2.427,2.449v12.01 c0,1.365-1.105,2.462-2.457,2.462L5.347,247.299z M139.438,247.296c-1.334,0-2.406-1.065-2.439-2.396v-12.14 c0.033-1.315,1.085-2.368,2.41-2.385h46.415c1.335,0.017,2.425,1.104,2.425,2.449v12.01c0,1.365-1.103,2.462-2.459,2.462H139.438z M70.193,247.296c-1.339,0-2.408-1.065-2.441-2.396v-12.14c0.033-1.315,1.086-2.368,2.407-2.385h46.418 c1.336,0.017,2.425,1.104,2.425,2.449v12.01c0,1.365-1.103,2.462-2.458,2.462H70.193z"></path>
</svg>`;
export const github = `<svg viewBox="0 0 16 16" fill="currentColor" class="github-logo">
<path d="M8 0c4.42 0 8 3.58 8 8a8.013 8.013 0 0 1-5.45 7.59c-.4.08-.55-.17-.55-.38 0-.27.01-1.13.01-2.2 0-.75-.25-1.23-.54-1.48 1.78-.2 3.65-.88 3.65-3.95 0-.88-.31-1.59-.82-2.15.08-.2.36-1.02-.08-2.12 0 0-.67-.22-2.2.82-.64-.18-1.32-.27-2-.27-.68 0-1.36.09-2 .27-1.53-1.03-2.2-.82-2.2-.82-.44 1.1-.16 1.92-.08 2.12-.51.56-.82 1.28-.82 2.15 0 3.06 1.86 3.75 3.64 3.95-.23.2-.44.55-.51 1.07-.46.21-1.61.55-2.33-.66-.15-.24-.6-.83-1.23-.82-.67.01-.27.38.01.53.34.19.73.9.82 1.13.16.45.68 1.31 2.69.94 0 .67.01 1.3.01 1.49 0 .21-.15.45-.55.38A7.995 7.995 0 0 1 0 8c0-4.42 3.58-8 8-8Z"></path>
export const github = `<svg viewBox="0 0 16 16" fill="currentColor" class="github-logo">
<path d="M8 0c4.42 0 8 3.58 8 8a8.013 8.013 0 0 1-5.45 7.59c-.4.08-.55-.17-.55-.38 0-.27.01-1.13.01-2.2 0-.75-.25-1.23-.54-1.48 1.78-.2 3.65-.88 3.65-3.95 0-.88-.31-1.59-.82-2.15.08-.2.36-1.02-.08-2.12 0 0-.67-.22-2.2.82-.64-.18-1.32-.27-2-.27-.68 0-1.36.09-2 .27-1.53-1.03-2.2-.82-2.2-.82-.44 1.1-.16 1.92-.08 2.12-.51.56-.82 1.28-.82 2.15 0 3.06 1.86 3.75 3.64 3.95-.23.2-.44.55-.51 1.07-.46.21-1.61.55-2.33-.66-.15-.24-.6-.83-1.23-.82-.67.01-.27.38.01.53.34.19.73.9.82 1.13.16.45.68 1.31 2.69.94 0 .67.01 1.3.01 1.49 0 .21-.15.45-.55.38A7.995 7.995 0 0 1 0 8c0-4.42 3.58-8 8-8Z"></path>
</svg>`;
export const iconStarFilled = `<svg viewBox="0 0 16 16" fill="currentColor" class="github-star">
<path d="M8 .25a.75.75 0 0 1 .673.418l1.882 3.815 4.21.612a.75.75 0 0 1 .416 1.279l-3.046 2.97.719 4.192a.751.751 0 0 1-1.088.791L8 12.347l-3.766 1.98a.75.75 0 0 1-1.088-.79l.72-4.194L.818 6.374a.75.75 0 0 1 .416-1.28l4.21-.611L7.327.668A.75.75 0 0 1 8 .25Z"></path>
export const iconStarFilled = `<svg viewBox="0 0 16 16" fill="currentColor" class="github-star">
<path d="M8 .25a.75.75 0 0 1 .673.418l1.882 3.815 4.21.612a.75.75 0 0 1 .416 1.279l-3.046 2.97.719 4.192a.751.751 0 0 1-1.088.791L8 12.347l-3.766 1.98a.75.75 0 0 1-1.088-.79l.72-4.194L.818 6.374a.75.75 0 0 1 .416-1.28l4.21-.611L7.327.668A.75.75 0 0 1 8 .25Z"></path>
</svg>`;
export const iconReplace = `<svg viewBox="0 0 52 52" fill="currentColor">
<path d="M20,37.5c0-0.8-0.7-1.5-1.5-1.5h-15C2.7,36,2,36.7,2,37.5v11C2,49.3,2.7,50,3.5,50h15c0.8,0,1.5-0.7,1.5-1.5 V37.5z"/>
<path d="M8.1,22H3.2c-1,0-1.5,0.9-0.9,1.4l8,8.3c0.4,0.3,1,0.3,1.4,0l8-8.3c0.6-0.6,0.1-1.4-0.9-1.4h-4.7 c0-5,4.9-10,9.9-10V6C15,6,8.1,13,8.1,22z"/>
<path d="M41.8,20.3c-0.4-0.3-1-0.3-1.4,0l-8,8.3c-0.6,0.6-0.1,1.4,0.9,1.4h4.8c0,6-4.1,10-10.1,10v6 c9,0,16.1-7,16.1-16H49c1,0,1.5-0.9,0.9-1.4L41.8,20.3z"/>
<path d="M50,3.5C50,2.7,49.3,2,48.5,2h-15C32.7,2,32,2.7,32,3.5v11c0,0.8,0.7,1.5,1.5,1.5h15c0.8,0,1.5-0.7,1.5-1.5 V3.5z"/>
export const iconReplace = `<svg viewBox="0 0 52 52" fill="currentColor">
<path d="M20,37.5c0-0.8-0.7-1.5-1.5-1.5h-15C2.7,36,2,36.7,2,37.5v11C2,49.3,2.7,50,3.5,50h15c0.8,0,1.5-0.7,1.5-1.5 V37.5z"/>
<path d="M8.1,22H3.2c-1,0-1.5,0.9-0.9,1.4l8,8.3c0.4,0.3,1,0.3,1.4,0l8-8.3c0.6-0.6,0.1-1.4-0.9-1.4h-4.7 c0-5,4.9-10,9.9-10V6C15,6,8.1,13,8.1,22z"/>
<path d="M41.8,20.3c-0.4-0.3-1-0.3-1.4,0l-8,8.3c-0.6,0.6-0.1,1.4,0.9,1.4h4.8c0,6-4.1,10-10.1,10v6 c9,0,16.1-7,16.1-16H49c1,0,1.5-0.9,0.9-1.4L41.8,20.3z"/>
<path d="M50,3.5C50,2.7,49.3,2,48.5,2h-15C32.7,2,32,2.7,32,3.5v11c0,0.8,0.7,1.5,1.5,1.5h15c0.8,0,1.5-0.7,1.5-1.5 V3.5z"/>
</svg>`;
export const iconNode = `<svg viewBox="0 -0.5 25 25" fill="none">
<path fill-rule="evenodd" clip-rule="evenodd" d="M15.5 19H9.5C7.29086 19 5.5 17.2091 5.5 15V9C5.5 6.79086 7.29086 5 9.5 5H15.5C17.7091 5 19.5 6.79086 19.5 9V15C19.5 17.2091 17.7091 19 15.5 19Z" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M19.5 9.75C19.9142 9.75 20.25 9.41421 20.25 9C20.25 8.58579 19.9142 8.25 19.5 8.25V9.75ZM5.5 8.25C5.08579 8.25 4.75 8.58579 4.75 9C4.75 9.41421 5.08579 9.75 5.5 9.75V8.25ZM11.5 14.25C11.0858 14.25 10.75 14.5858 10.75 15C10.75 15.4142 11.0858 15.75 11.5 15.75V14.25ZM13.5 15.75C13.9142 15.75 14.25 15.4142 14.25 15C14.25 14.5858 13.9142 14.25 13.5 14.25V15.75ZM19.5 8.25H5.5V9.75H19.5V8.25ZM11.5 15.75H13.5V14.25H11.5V15.75Z" fill="currentColor" />
export const iconNode = `<svg viewBox="0 -0.5 25 25" fill="none">
<path fill-rule="evenodd" clip-rule="evenodd" d="M15.5 19H9.5C7.29086 19 5.5 17.2091 5.5 15V9C5.5 6.79086 7.29086 5 9.5 5H15.5C17.7091 5 19.5 6.79086 19.5 9V15C19.5 17.2091 17.7091 19 15.5 19Z" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M19.5 9.75C19.9142 9.75 20.25 9.41421 20.25 9C20.25 8.58579 19.9142 8.25 19.5 8.25V9.75ZM5.5 8.25C5.08579 8.25 4.75 8.58579 4.75 9C4.75 9.41421 5.08579 9.75 5.5 9.75V8.25ZM11.5 14.25C11.0858 14.25 10.75 14.5858 10.75 15C10.75 15.4142 11.0858 15.75 11.5 15.75V14.25ZM13.5 15.75C13.9142 15.75 14.25 15.4142 14.25 15C14.25 14.5858 13.9142 14.25 13.5 14.25V15.75ZM19.5 8.25H5.5V9.75H19.5V8.25ZM11.5 15.75H13.5V14.25H11.5V15.75Z" fill="currentColor" />
</svg>`;
export const iconGear = `<svg viewBox="0 0 24 24" fill="currentColor">
<path fill-rule="evenodd" clip-rule="evenodd" d="M12.7848 0.449982C13.8239 0.449982 14.7167 1.16546 14.9122 2.15495L14.9991 2.59495C15.3408 4.32442 17.1859 5.35722 18.9016 4.7794L19.3383 4.63233C20.3199 4.30175 21.4054 4.69358 21.9249 5.56605L22.7097 6.88386C23.2293 7.75636 23.0365 8.86366 22.2504 9.52253L21.9008 9.81555C20.5267 10.9672 20.5267 13.0328 21.9008 14.1844L22.2504 14.4774C23.0365 15.1363 23.2293 16.2436 22.7097 17.1161L21.925 18.4339C21.4054 19.3064 20.3199 19.6982 19.3382 19.3676L18.9017 19.2205C17.1859 18.6426 15.3408 19.6754 14.9991 21.405L14.9122 21.845C14.7167 22.8345 13.8239 23.55 12.7848 23.55H11.2152C10.1761 23.55 9.28331 22.8345 9.08781 21.8451L9.00082 21.4048C8.65909 19.6754 6.81395 18.6426 5.09822 19.2205L4.66179 19.3675C3.68016 19.6982 2.59465 19.3063 2.07505 18.4338L1.2903 17.1161C0.770719 16.2436 0.963446 15.1363 1.74956 14.4774L2.09922 14.1844C3.47324 13.0327 3.47324 10.9672 2.09922 9.8156L1.74956 9.52254C0.963446 8.86366 0.77072 7.75638 1.2903 6.8839L2.07508 5.56608C2.59466 4.69359 3.68014 4.30176 4.66176 4.63236L5.09831 4.77939C6.81401 5.35722 8.65909 4.32449 9.00082 2.59506L9.0878 2.15487C9.28331 1.16542 10.176 0.449982 11.2152 0.449982H12.7848ZM12 15.3C13.8225 15.3 15.3 13.8225 15.3 12C15.3 10.1774 13.8225 8.69998 12 8.69998C10.1774 8.69998 8.69997 10.1774 8.69997 12C8.69997 13.8225 10.1774 15.3 12 15.3Z" />
export const iconGear = `<svg viewBox="0 0 24 24" fill="currentColor">
<path fill-rule="evenodd" clip-rule="evenodd" d="M12.7848 0.449982C13.8239 0.449982 14.7167 1.16546 14.9122 2.15495L14.9991 2.59495C15.3408 4.32442 17.1859 5.35722 18.9016 4.7794L19.3383 4.63233C20.3199 4.30175 21.4054 4.69358 21.9249 5.56605L22.7097 6.88386C23.2293 7.75636 23.0365 8.86366 22.2504 9.52253L21.9008 9.81555C20.5267 10.9672 20.5267 13.0328 21.9008 14.1844L22.2504 14.4774C23.0365 15.1363 23.2293 16.2436 22.7097 17.1161L21.925 18.4339C21.4054 19.3064 20.3199 19.6982 19.3382 19.3676L18.9017 19.2205C17.1859 18.6426 15.3408 19.6754 14.9991 21.405L14.9122 21.845C14.7167 22.8345 13.8239 23.55 12.7848 23.55H11.2152C10.1761 23.55 9.28331 22.8345 9.08781 21.8451L9.00082 21.4048C8.65909 19.6754 6.81395 18.6426 5.09822 19.2205L4.66179 19.3675C3.68016 19.6982 2.59465 19.3063 2.07505 18.4338L1.2903 17.1161C0.770719 16.2436 0.963446 15.1363 1.74956 14.4774L2.09922 14.1844C3.47324 13.0327 3.47324 10.9672 2.09922 9.8156L1.74956 9.52254C0.963446 8.86366 0.77072 7.75638 1.2903 6.8839L2.07508 5.56608C2.59466 4.69359 3.68014 4.30176 4.66176 4.63236L5.09831 4.77939C6.81401 5.35722 8.65909 4.32449 9.00082 2.59506L9.0878 2.15487C9.28331 1.16542 10.176 0.449982 11.2152 0.449982H12.7848ZM12 15.3C13.8225 15.3 15.3 13.8225 15.3 12C15.3 10.1774 13.8225 8.69998 12 8.69998C10.1774 8.69998 8.69997 10.1774 8.69997 12C8.69997 13.8225 10.1774 15.3 12 15.3Z" />
</svg>`;
export const checkmark = `<svg viewBox="0 0 32 32" fill="currentColor" class="icon-checkmark">
<g transform="translate(-518.000000, -1039.000000)">
<path d="M548.783,1040.2 C547.188,1038.57 544.603,1038.57 543.008,1040.2 L528.569,1054.92 L524.96,1051.24 C523.365,1049.62 520.779,1049.62 519.185,1051.24 C517.59,1052.87 517.59,1055.51 519.185,1057.13 L525.682,1063.76 C527.277,1065.39 529.862,1065.39 531.457,1063.76 L548.783,1046.09 C550.378,1044.46 550.378,1041.82 548.783,1040.2"></path>
</g>
export const checkmark = `<svg viewBox="0 0 32 32" fill="currentColor" class="icon-checkmark">
<g transform="translate(-518.000000, -1039.000000)">
<path d="M548.783,1040.2 C547.188,1038.57 544.603,1038.57 543.008,1040.2 L528.569,1054.92 L524.96,1051.24 C523.365,1049.62 520.779,1049.62 519.185,1051.24 C517.59,1052.87 517.59,1055.51 519.185,1057.13 L525.682,1063.76 C527.277,1065.39 529.862,1065.39 531.457,1063.76 L548.783,1046.09 C550.378,1044.46 550.378,1041.82 548.783,1040.2"></path>
</g>
</svg>`;
export const logoCivitai = `<svg viewBox="0 0 178 178" class="logo-civitai">
<defs>
<linearGradient id="bgblue" gradientUnits="userSpaceOnUse" x1="89.3" y1="-665.5" x2="89.3" y2="-841.1" gradientTransform="matrix(1 0 0 -1 0 -664)">
<stop offset="0" style="stop-color:#1284F7"/>
<stop offset="1" style="stop-color:#0A20C9"/>
</linearGradient>
</defs>
<path fill="#000" d="M13.3,45.4v87.7l76,43.9l76-43.9V45.4l-76-43.9L13.3,45.4z"/>
<path style="fill:url(#bgblue);" d="M89.3,29.2l52,30v60l-52,30l-52-30v-60 L89.3,29.2 M89.3,1.5l-76,43.9v87.8l76,43.9l76-43.9V45.4L89.3,1.5z" />
<path fill="#FFF" d="M104.1,97.2l-14.9,8.5l-14.9-8.5v-17l14.9-8.5l14.9,8.5h18.2V69.7l-33-19l-33,19v38.1l33,19l33-19V97.2H104.1z" />
export const logoCivitai = `<svg viewBox="0 0 178 178" class="logo-civitai">
<defs>
<linearGradient id="bgblue" gradientUnits="userSpaceOnUse" x1="89.3" y1="-665.5" x2="89.3" y2="-841.1" gradientTransform="matrix(1 0 0 -1 0 -664)">
<stop offset="0" style="stop-color:#1284F7"/>
<stop offset="1" style="stop-color:#0A20C9"/>
</linearGradient>
</defs>
<path fill="#000" d="M13.3,45.4v87.7l76,43.9l76-43.9V45.4l-76-43.9L13.3,45.4z"/>
<path style="fill:url(#bgblue);" d="M89.3,29.2l52,30v60l-52,30l-52-30v-60 L89.3,29.2 M89.3,1.5l-76,43.9v87.8l76,43.9l76-43.9V45.4L89.3,1.5z" />
<path fill="#FFF" d="M104.1,97.2l-14.9,8.5l-14.9-8.5v-17l14.9-8.5l14.9,8.5h18.2V69.7l-33-19l-33,19v38.1l33,19l33-19V97.2H104.1z" />
</svg>`;
export const iconOutLink = `<svg viewBox="0 0 32 32">
<path d="M 18 5 L 18 7 L 23.5625 7 L 11.28125 19.28125 L 12.71875 20.71875 L 25 8.4375 L 25 14 L 27 14 L 27 5 Z M 5 9 L 5 27 L 23 27 L 23 14 L 21 16 L 21 25 L 7 25 L 7 11 L 16 11 L 18 9 Z"></path>
export const iconOutLink = `<svg viewBox="0 0 32 32">
<path d="M 18 5 L 18 7 L 23.5625 7 L 11.28125 19.28125 L 12.71875 20.71875 L 25 8.4375 L 25 14 L 27 14 L 27 5 Z M 5 9 L 5 27 L 23 27 L 23 14 L 21 16 L 21 25 L 7 25 L 7 11 L 16 11 L 18 9 Z"></path>
</svg>`;
export const link = `<svg viewBox="0 0 640 512">
<path d="M598.6 41.41C570.1 13.8 534.8 0 498.6 0s-72.36 13.8-99.96 41.41l-43.36 43.36c15.11 8.012 29.47 17.58 41.91 30.02c3.146 3.146 5.898 6.518 8.742 9.838l37.96-37.96C458.5 72.05 477.1 64 498.6 64c20.67 0 40.1 8.047 54.71 22.66c14.61 14.61 22.66 34.04 22.66 54.71s-8.049 40.1-22.66 54.71l-133.3 133.3C405.5 343.1 386 352 365.4 352s-40.1-8.048-54.71-22.66C296 314.7 287.1 295.3 287.1 274.6s8.047-40.1 22.66-54.71L314.2 216.4C312.1 212.5 309.9 208.5 306.7 205.3C298.1 196.7 286.8 192 274.6 192c-11.93 0-23.1 4.664-31.61 12.97c-30.71 53.96-23.63 123.6 22.39 169.6C293 402.2 329.2 416 365.4 416c36.18 0 72.36-13.8 99.96-41.41L598.6 241.3c28.45-28.45 42.24-66.01 41.37-103.3C639.1 102.1 625.4 68.16 598.6 41.41zM234 387.4L196.1 425.3C181.5 439.1 162 448 141.4 448c-20.67 0-40.1-8.047-54.71-22.66c-14.61-14.61-22.66-34.04-22.66-54.71s8.049-40.1 22.66-54.71l133.3-133.3C234.5 168 253.1 160 274.6 160s40.1 8.048 54.71 22.66c14.62 14.61 22.66 34.04 22.66 54.71s-8.047 40.1-22.66 54.71L325.8 295.6c2.094 3.939 4.219 7.895 7.465 11.15C341.9 315.3 353.3 320 365.4 320c11.93 0 23.1-4.664 31.61-12.97c30.71-53.96 23.63-123.6-22.39-169.6C346.1 109.8 310.8 96 274.6 96C238.4 96 202.3 109.8 174.7 137.4L41.41 270.7c-27.6 27.6-41.41 63.78-41.41 99.96c-.0001 36.18 13.8 72.36 41.41 99.97C69.01 498.2 105.2 512 141.4 512c36.18 0 72.36-13.8 99.96-41.41l43.36-43.36c-15.11-8.012-29.47-17.58-41.91-30.02C239.6 394.1 236.9 390.7 234 387.4z"/>
export const link = `<svg viewBox="0 0 640 512">
<path d="M598.6 41.41C570.1 13.8 534.8 0 498.6 0s-72.36 13.8-99.96 41.41l-43.36 43.36c15.11 8.012 29.47 17.58 41.91 30.02c3.146 3.146 5.898 6.518 8.742 9.838l37.96-37.96C458.5 72.05 477.1 64 498.6 64c20.67 0 40.1 8.047 54.71 22.66c14.61 14.61 22.66 34.04 22.66 54.71s-8.049 40.1-22.66 54.71l-133.3 133.3C405.5 343.1 386 352 365.4 352s-40.1-8.048-54.71-22.66C296 314.7 287.1 295.3 287.1 274.6s8.047-40.1 22.66-54.71L314.2 216.4C312.1 212.5 309.9 208.5 306.7 205.3C298.1 196.7 286.8 192 274.6 192c-11.93 0-23.1 4.664-31.61 12.97c-30.71 53.96-23.63 123.6 22.39 169.6C293 402.2 329.2 416 365.4 416c36.18 0 72.36-13.8 99.96-41.41L598.6 241.3c28.45-28.45 42.24-66.01 41.37-103.3C639.1 102.1 625.4 68.16 598.6 41.41zM234 387.4L196.1 425.3C181.5 439.1 162 448 141.4 448c-20.67 0-40.1-8.047-54.71-22.66c-14.61-14.61-22.66-34.04-22.66-54.71s8.049-40.1 22.66-54.71l133.3-133.3C234.5 168 253.1 160 274.6 160s40.1 8.048 54.71 22.66c14.62 14.61 22.66 34.04 22.66 54.71s-8.047 40.1-22.66 54.71L325.8 295.6c2.094 3.939 4.219 7.895 7.465 11.15C341.9 315.3 353.3 320 365.4 320c11.93 0 23.1-4.664 31.61-12.97c30.71-53.96 23.63-123.6-22.39-169.6C346.1 109.8 310.8 96 274.6 96C238.4 96 202.3 109.8 174.7 137.4L41.41 270.7c-27.6 27.6-41.41 63.78-41.41 99.96c-.0001 36.18 13.8 72.36 41.41 99.97C69.01 498.2 105.2 512 141.4 512c36.18 0 72.36-13.8 99.96-41.41l43.36-43.36c-15.11-8.012-29.47-17.58-41.91-30.02C239.6 394.1 236.9 390.7 234 387.4z"/>
</svg>`;
export const pencil = `<svg viewBox="0 0 24 24">
<path d="M 16.9375 1.0625 L 3.875 14.125 L 1.0742188 22.925781 L 9.875 20.125 L 22.9375 7.0625 C 22.9375 7.0625 22.8375 4.9615 20.9375 3.0625 C 19.0375 1.1625 16.9375 1.0625 16.9375 1.0625 z M 17.3125 2.6875 C 18.3845 2.8915 19.237984 3.3456094 19.896484 4.0214844 C 20.554984 4.6973594 21.0185 5.595 21.3125 6.6875 L 19.5 8.5 L 15.5 4.5 L 16.9375 3.0625 L 17.3125 2.6875 z M 4.9785156 15.126953 C 4.990338 15.129931 6.1809555 15.430955 7.375 16.625 C 8.675 17.825 8.875 18.925781 8.875 18.925781 L 8.9179688 18.976562 L 5.3691406 20.119141 L 3.8730469 18.623047 L 4.9785156 15.126953 z"/>
export const pencil = `<svg viewBox="0 0 24 24">
<path d="M 16.9375 1.0625 L 3.875 14.125 L 1.0742188 22.925781 L 9.875 20.125 L 22.9375 7.0625 C 22.9375 7.0625 22.8375 4.9615 20.9375 3.0625 C 19.0375 1.1625 16.9375 1.0625 16.9375 1.0625 z M 17.3125 2.6875 C 18.3845 2.8915 19.237984 3.3456094 19.896484 4.0214844 C 20.554984 4.6973594 21.0185 5.595 21.3125 6.6875 L 19.5 8.5 L 15.5 4.5 L 16.9375 3.0625 L 17.3125 2.6875 z M 4.9785156 15.126953 C 4.990338 15.129931 6.1809555 15.430955 7.375 16.625 C 8.675 17.825 8.875 18.925781 8.875 18.925781 L 8.9179688 18.976562 L 5.3691406 20.119141 L 3.8730469 18.623047 L 4.9785156 15.126953 z"/>
</svg>`;
export const dotdotdot = `<svg viewBox="0 0 24 24" fill="currentColor">
<circle cy="12" r="3" cx="3"></circle>
<circle cy="12" r="3" cx="12"></circle>
<circle cx="21" cy="12" r="3"></circle>
export const dotdotdot = `<svg viewBox="0 0 24 24" fill="currentColor">
<circle cy="12" r="3" cx="3"></circle>
<circle cy="12" r="3" cx="12"></circle>
<circle cx="21" cy="12" r="3"></circle>
</svg>`;
export const models = `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M4 4h6v6h-6z"></path>
<path d="M14 4h6v6h-6z"></path>
<path d="M4 14h6v6h-6z"></path>
<path d="M17 17m-3 0a3 3 0 1 0 6 0a3 3 0 1 0 -6 0"></path>
export const models = `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M4 4h6v6h-6z"></path>
<path d="M14 4h6v6h-6z"></path>
<path d="M4 14h6v6h-6z"></path>
<path d="M17 17m-3 0a3 3 0 1 0 6 0a3 3 0 1 0 -6 0"></path>
</svg>`;
export const pencilColored = `<svg viewBox="0 0 64 64">
<path fill="#ffce31" d="M7.934 41.132L39.828 9.246l14.918 14.922l-31.895 31.886z"></path>
<path d="M61.3 4.6l-1.9-1.9C55.8-.9 50-.9 46.3 2.7l-6.5 6.5l15 15l6.5-6.5c3.6-3.6 3.6-9.5 0-13.1" fill="#ed4c5c"></path>
<path fill="#93a2aa" d="M35.782 13.31l4.1-4.102l14.92 14.92l-4.1 4.101z"></path>
<path fill="#c7d3d8" d="M37.338 14.865l4.1-4.101l11.739 11.738l-4.102 4.1z"></path>
<path fill="#fed0ac" d="M7.9 41.1l-6.5 17l4.5 4.5l17-6.5z"/>
<path d="M.3 61.1c-.9 2.4.3 3.5 2.7 2.6l8.2-3.1l-7.7-7.7l-3.2 8.2" fill="#333"></path>
<path fill="#ffdf85" d="M7.89 41.175l27.86-27.86l4.95 4.95l-27.86 27.86z"/>
<path fill="#ff8736" d="M17.904 51.142l27.86-27.86l4.95 4.95l-27.86 27.86z"></path>
export const pencilColored = `<svg viewBox="0 0 64 64">
<path fill="#ffce31" d="M7.934 41.132L39.828 9.246l14.918 14.922l-31.895 31.886z"></path>
<path d="M61.3 4.6l-1.9-1.9C55.8-.9 50-.9 46.3 2.7l-6.5 6.5l15 15l6.5-6.5c3.6-3.6 3.6-9.5 0-13.1" fill="#ed4c5c"></path>
<path fill="#93a2aa" d="M35.782 13.31l4.1-4.102l14.92 14.92l-4.1 4.101z"></path>
<path fill="#c7d3d8" d="M37.338 14.865l4.1-4.101l11.739 11.738l-4.102 4.1z"></path>
<path fill="#fed0ac" d="M7.9 41.1l-6.5 17l4.5 4.5l17-6.5z"/>
<path d="M.3 61.1c-.9 2.4.3 3.5 2.7 2.6l8.2-3.1l-7.7-7.7l-3.2 8.2" fill="#333"></path>
<path fill="#ffdf85" d="M7.89 41.175l27.86-27.86l4.95 4.95l-27.86 27.86z"/>
<path fill="#ff8736" d="M17.904 51.142l27.86-27.86l4.95 4.95l-27.86 27.86z"></path>
</svg>`;
export const diskColored = `<svg viewBox="-0.01 -0.008 100.016 100.016">
<path fill="#26f" fill_="#23475F" d="M88.555-.008H83v.016a2 2 0 0 1-2 2H19a2 2 0 0 1-2-2v-.016H4a4 4 0 0 0-4 4v92.016a4 4 0 0 0 4 4h92a4 4 0 0 0 4-4V11.517c.049-.089-11.436-11.454-11.445-11.525z"/>
<path fill="#04d" fill_="#1C3C50" d="M81.04 53.008H18.96a2 2 0 0 0-2 2v45h66.08v-45c0-1.106-.895-2-2-2zm-61.957-10h61.834a2 2 0 0 0 2-2V.547A1.993 1.993 0 0 1 81 2.007H19c-.916 0-1.681-.62-1.917-1.46v40.46a2 2 0 0 0 2 2.001z"/>
<path fill="#EBF0F1" d="M22 55.977h56a2 2 0 0 1 2 2v37.031a2 2 0 0 1-2 2H22c-1.104 0-2-.396-2-1.5V57.977a2 2 0 0 1 2-2z"/>
<path fill="#BCC4C8" d="M25 77.008h50v1H25v-1zm0 10h50v1H25v-1z"/>
<path fill="#1C3C50" d="M7 84.008h3a2 2 0 0 1 2 2v3a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2v-3a2 2 0 0 1 2-2zm83 0h3a2 2 0 0 1 2 2v3a2 2 0 0 1-2 2h-3a2 2 0 0 1-2-2v-3a2 2 0 0 1 2-2z"/>
<path fill="#BCC4C8" d="M37 1.981v36.026a2 2 0 0 0 2 2h39a2 2 0 0 0 2-2V1.981c0 .007-42.982.007-43 0zm37 29.027a2 2 0 0 1-2 2h-6a2 2 0 0 1-2-2V10.981a2 2 0 0 1 2-2h6a2 2 0 0 1 2 2v20.027z"/>
<path fill="#FF9D00" d="M78 55.977H22a2 2 0 0 0-2 2v10.031h60V57.977a2 2 0 0 0-2-2z"/>
export const diskColored = `<svg viewBox="-0.01 -0.008 100.016 100.016">
<path fill="#26f" fill_="#23475F" d="M88.555-.008H83v.016a2 2 0 0 1-2 2H19a2 2 0 0 1-2-2v-.016H4a4 4 0 0 0-4 4v92.016a4 4 0 0 0 4 4h92a4 4 0 0 0 4-4V11.517c.049-.089-11.436-11.454-11.445-11.525z"/>
<path fill="#04d" fill_="#1C3C50" d="M81.04 53.008H18.96a2 2 0 0 0-2 2v45h66.08v-45c0-1.106-.895-2-2-2zm-61.957-10h61.834a2 2 0 0 0 2-2V.547A1.993 1.993 0 0 1 81 2.007H19c-.916 0-1.681-.62-1.917-1.46v40.46a2 2 0 0 0 2 2.001z"/>
<path fill="#EBF0F1" d="M22 55.977h56a2 2 0 0 1 2 2v37.031a2 2 0 0 1-2 2H22c-1.104 0-2-.396-2-1.5V57.977a2 2 0 0 1 2-2z"/>
<path fill="#BCC4C8" d="M25 77.008h50v1H25v-1zm0 10h50v1H25v-1z"/>
<path fill="#1C3C50" d="M7 84.008h3a2 2 0 0 1 2 2v3a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2v-3a2 2 0 0 1 2-2zm83 0h3a2 2 0 0 1 2 2v3a2 2 0 0 1-2 2h-3a2 2 0 0 1-2-2v-3a2 2 0 0 1 2-2z"/>
<path fill="#BCC4C8" d="M37 1.981v36.026a2 2 0 0 0 2 2h39a2 2 0 0 0 2-2V1.981c0 .007-42.982.007-43 0zm37 29.027a2 2 0 0 1-2 2h-6a2 2 0 0 1-2-2V10.981a2 2 0 0 1 2-2h6a2 2 0 0 1 2 2v20.027z"/>
<path fill="#FF9D00" d="M78 55.977H22a2 2 0 0 0-2 2v10.031h60V57.977a2 2 0 0 0-2-2z"/>
</svg>`;
export const folderColored = `<svg viewBox="0 0 501.379 501.379">
<path style="fill:#EF9F2C;" d="M406.423,93.889H205.889c-17.067,0-30.933-13.867-30.933-30.933s-13.867-30.933-30.933-30.933H30.956
c-17.067,0-30.933,13.867-30.933,30.933v375.467c0,17.067,13.867,30.933,30.933,30.933h375.467
c17.067,0,30.933-13.867,30.933-30.933v-313.6C436.289,107.756,422.423,93.889,406.423,93.889z"/>
<path style="fill:#FEC656;" d="M470.423,157.889H97.089c-13.867,0-26.667,9.6-29.867,22.4l-66.133,249.6
c-5.333,19.2,9.6,38.4,29.867,38.4h373.333c13.867,0,26.667-9.6,29.867-22.4l66.133-248.533
C505.623,177.089,490.689,157.889,470.423,157.889z"/>
export const folderColored = `<svg viewBox="0 0 501.379 501.379">
<path style="fill:#EF9F2C;" d="M406.423,93.889H205.889c-17.067,0-30.933-13.867-30.933-30.933s-13.867-30.933-30.933-30.933H30.956
c-17.067,0-30.933,13.867-30.933,30.933v375.467c0,17.067,13.867,30.933,30.933,30.933h375.467
c17.067,0,30.933-13.867,30.933-30.933v-313.6C436.289,107.756,422.423,93.889,406.423,93.889z"/>
<path style="fill:#FEC656;" d="M470.423,157.889H97.089c-13.867,0-26.667,9.6-29.867,22.4l-66.133,249.6
c-5.333,19.2,9.6,38.4,29.867,38.4h373.333c13.867,0,26.667-9.6,29.867-22.4l66.133-248.533
C505.623,177.089,490.689,157.889,470.423,157.889z"/>
</svg>`;
export const modelsColored = `<svg viewBox="0 0 24 24">
<path fill="#aa3366" d="M0 0h10v10h-10z"></path>
<path d="M14 0h10v10h-10z" fill="#3366aa"></path>
<path d="M0 14h10v10h-10z" fill="#66aa33"></path>
<path fill="#dd9922" d="M19 19m-5 0 a5 5 0 1 0 10 0 a5 5 0 1 0 -10 0"></path>
export const modelsColored = `<svg viewBox="0 0 24 24">
<path fill="#aa3366" d="M0 0h10v10h-10z"></path>
<path d="M14 0h10v10h-10z" fill="#3366aa"></path>
<path d="M0 14h10v10h-10z" fill="#66aa33"></path>
<path fill="#dd9922" d="M19 19m-5 0 a5 5 0 1 0 10 0 a5 5 0 1 0 -10 0"></path>
</svg>`;
export const legoBlocksColored = `<svg viewBox="0 0 512 512">
<g>
<rect x="57.67" style="fill:#00BAB9;" width="101.275" height="78.769"/>
<rect x="205.363" style="fill:#00BAB9;" width="101.275" height="78.769"/>
<rect x="353.055" style="fill:#00BAB9;" width="101.275" height="78.769"/>
</g>
<polygon style="fill:#B8DE6F;" points="478.242,289.758 478.242,512 33.758,512 33.758,289.758 256,267.253 "/>
<polygon style="fill:#41D4D3;" points="478.242,67.516 478.242,289.758 33.758,289.758 33.758,67.516 57.67,67.516 158.945,67.516
205.363,67.516 306.637,67.516 353.055,67.516 454.33,67.516 "/>
<g>
<circle style="fill:#00BAB9;" cx="402.286" cy="143.473" r="8.44"/>
<circle style="fill:#00BAB9;" cx="368.527" cy="177.231" r="8.44"/>
</g>
<circle style="fill:#7BD288;" cx="109.714" cy="436.044" r="8.44"/>
export const legoBlocksColored = `<svg viewBox="0 0 512 512">
<g>
<rect x="57.67" style="fill:#00BAB9;" width="101.275" height="78.769"/>
<rect x="205.363" style="fill:#00BAB9;" width="101.275" height="78.769"/>
<rect x="353.055" style="fill:#00BAB9;" width="101.275" height="78.769"/>
</g>
<polygon style="fill:#B8DE6F;" points="478.242,289.758 478.242,512 33.758,512 33.758,289.758 256,267.253 "/>
<polygon style="fill:#41D4D3;" points="478.242,67.516 478.242,289.758 33.758,289.758 33.758,67.516 57.67,67.516 158.945,67.516
205.363,67.516 306.637,67.516 353.055,67.516 454.33,67.516 "/>
<g>
<circle style="fill:#00BAB9;" cx="402.286" cy="143.473" r="8.44"/>
<circle style="fill:#00BAB9;" cx="368.527" cy="177.231" r="8.44"/>
</g>
<circle style="fill:#7BD288;" cx="109.714" cy="436.044" r="8.44"/>
</svg>`;
export const legoBlockColored = `<svg viewBox="0 0 256 256">
<style>
.s0 { fill: #ff0000 }
.s1 { fill: #c30000 }
.s2 { fill: #800000 }
.s3 { fill: #cc0000 }
.s4 { fill: #e00000 }
</style>
<g id="Folder 2">
<path id="Shape 1 copy 2" class="s0" d="m128 61l116 45-116 139-116-139z"/>
<path id="Shape 1" class="s1" d="m12 106l116 45v95l-116-45z"/>
<path id="Shape 1 copy" class="s2" d="m244 106l-116 45v95l116-45z"/>
<g id="Folder 1">
<path id="Shape 2" class="s3" d="m102 111.2c0-6.1 11.4-9.9 25.5-9.9 14.1 0 25.5 3.8 25.5 9.9 0 3.3 0 13.3 0 16.6 0 6.1-11.4 10.9-25.5 10.9-14.1 0-25.5-4.8-25.5-10.9 0-3.3 0-13.3 0-16.6z"/>
<path id="Shape 2 copy 4" class="s1" d="m102 111.2c0-6.1 11.4-9.9 25.5-9.9 14.1 0 25.5 3.8 25.5 9.9 0 3.3 0 13.3 0 16.6 0 6.1-11.4 10.9-25.5 10.9-14.1 0-25.5-4.8-25.5-10.9 0-3.3 0-13.3 0-16.6z"/>
<path id="Shape 2 copy 2" class="s2" d="m127.5 101.3c14.1 0 25.5 3.8 25.5 9.9 0 3.3 0 13.3 0 16.6 0 6.1-11.4 10.9-25.5 10.9 0-13.1 0-25.7 0-37.4z"/>
<path id="Shape 2 copy" class="s0" d="m127.5 118.8c-12.2 0-22-3.4-22-7.6 0-4.2 9.8-7.7 22-7.7 12.2 0 22 3.5 22 7.7 0 4.2-9.8 7.6-22 7.6zm0 0c-12.2 0-22-3.4-22-7.6 0-4.2 9.8-7.7 22-7.7 12.2 0 22 3.5 22 7.7 0 4.2-9.8 7.6-22 7.6z"/>
</g>
<g id="Folder 1 copy">
<path id="Shape 2" class="s4" d="m103 67.5c0-5.8 11-9.5 24.5-9.5 13.5 0 24.5 3.7 24.5 9.5 0 3.2 0 12.8 0 16 0 5.8-11 10.5-24.5 10.5-13.5 0-24.5-4.7-24.5-10.5 0-3.2 0-12.8 0-16z"/>
<path id="Shape 2 copy 4" class="s1" d="m103 67.5c0-5.8 11-9.5 24.5-9.5 13.5 0 24.5 3.7 24.5 9.5 0 3.2 0 12.8 0 16 0 5.8-11 10.5-24.5 10.5-13.5 0-24.5-4.7-24.5-10.5 0-3.2 0-12.8 0-16z"/>
<path id="Shape 2 copy 2" class="s2" d="m127.5 58c13.5 0 24.5 3.7 24.5 9.5 0 3.2 0 12.8 0 16 0 5.8-11 10.5-24.5 10.5 0-12.6 0-24.8 0-36z"/>
<path id="Shape 2 copy" class="s0" d="m127.5 74.9c-11.7 0-21.2-3.3-21.2-7.4 0-4.1 9.5-7.4 21.2-7.4 11.7 0 21.2 3.3 21.2 7.4 0 4.1-9.5 7.4-21.2 7.4zm0 0c-11.7 0-21.2-3.3-21.2-7.4 0-4.1 9.5-7.4 21.2-7.4 11.7 0 21.2 3.3 21.2 7.4 0 4.1-9.5 7.4-21.2 7.4z"/>
</g>
<g id="Folder 1 copy 2">
<path id="Shape 2" class="s4" d="m161 89.5c0-5.8 11-9.5 24.5-9.5 13.5 0 24.5 3.7 24.5 9.5 0 3.2 0 12.8 0 16 0 5.8-11 10.5-24.5 10.5-13.5 0-24.5-4.7-24.5-10.5 0-3.2 0-12.8 0-16z"/>
<path id="Shape 2 copy 4" class="s1" d="m161 89.5c0-5.8 11-9.5 24.5-9.5 13.5 0 24.5 3.7 24.5 9.5 0 3.2 0 12.8 0 16 0 5.8-11 10.5-24.5 10.5-13.5 0-24.5-4.7-24.5-10.5 0-3.2 0-12.8 0-16z"/>
<path id="Shape 2 copy 2" class="s2" d="m185.5 80c13.5 0 24.5 3.7 24.5 9.5 0 3.2 0 12.8 0 16 0 5.8-11 10.5-24.5 10.5 0-12.6 0-24.8 0-36z"/>
<path id="Shape 2 copy" class="s0" d="m185.5 96.9c-11.7 0-21.2-3.3-21.2-7.4 0-4.1 9.5-7.4 21.2-7.4 11.7 0 21.2 3.3 21.2 7.4 0 4.1-9.5 7.4-21.2 7.4zm0 0c-11.7 0-21.2-3.3-21.2-7.4 0-4.1 9.5-7.4 21.2-7.4 11.7 0 21.2 3.3 21.2 7.4 0 4.1-9.5 7.4-21.2 7.4z"/>
</g>
<g id="Folder 1 copy 3">
<path id="Shape 2" class="s4" d="m45 89.5c0-5.8 11-9.5 24.5-9.5 13.5 0 24.5 3.7 24.5 9.5 0 3.2 0 12.8 0 16 0 5.8-11 10.5-24.5 10.5-13.5 0-24.5-4.7-24.5-10.5 0-3.2 0-12.8 0-16z"/>
<path id="Shape 2 copy 4" class="s1" d="m45 89.5c0-5.8 11-9.5 24.5-9.5 13.5 0 24.5 3.7 24.5 9.5 0 3.2 0 12.8 0 16 0 5.8-11 10.5-24.5 10.5-13.5 0-24.5-4.7-24.5-10.5 0-3.2 0-12.8 0-16z"/>
<path id="Shape 2 copy 2" class="s2" d="m69.5 80c13.5 0 24.5 3.7 24.5 9.5 0 3.2 0 12.8 0 16 0 5.8-11 10.5-24.5 10.5 0-12.6 0-24.8 0-36z"/>
<path id="Shape 2 copy" class="s0" d="m69.5 96.9c-11.7 0-21.2-3.3-21.2-7.4 0-4.1 9.5-7.4 21.2-7.4 11.7 0 21.2 3.3 21.2 7.4 0 4.1-9.5 7.4-21.2 7.4zm0 0c-11.7 0-21.2-3.3-21.2-7.4 0-4.1 9.5-7.4 21.2-7.4 11.7 0 21.2 3.3 21.2 7.4 0 4.1-9.5 7.4-21.2 7.4z"/>
</g>
</g>
export const legoBlockColored = `<svg viewBox="0 0 256 256">
<style>
.s0 { fill: #ff0000 }
.s1 { fill: #c30000 }
.s2 { fill: #800000 }
.s3 { fill: #cc0000 }
.s4 { fill: #e00000 }
</style>
<g id="Folder 2">
<path id="Shape 1 copy 2" class="s0" d="m128 61l116 45-116 139-116-139z"/>
<path id="Shape 1" class="s1" d="m12 106l116 45v95l-116-45z"/>
<path id="Shape 1 copy" class="s2" d="m244 106l-116 45v95l116-45z"/>
<g id="Folder 1">
<path id="Shape 2" class="s3" d="m102 111.2c0-6.1 11.4-9.9 25.5-9.9 14.1 0 25.5 3.8 25.5 9.9 0 3.3 0 13.3 0 16.6 0 6.1-11.4 10.9-25.5 10.9-14.1 0-25.5-4.8-25.5-10.9 0-3.3 0-13.3 0-16.6z"/>
<path id="Shape 2 copy 4" class="s1" d="m102 111.2c0-6.1 11.4-9.9 25.5-9.9 14.1 0 25.5 3.8 25.5 9.9 0 3.3 0 13.3 0 16.6 0 6.1-11.4 10.9-25.5 10.9-14.1 0-25.5-4.8-25.5-10.9 0-3.3 0-13.3 0-16.6z"/>
<path id="Shape 2 copy 2" class="s2" d="m127.5 101.3c14.1 0 25.5 3.8 25.5 9.9 0 3.3 0 13.3 0 16.6 0 6.1-11.4 10.9-25.5 10.9 0-13.1 0-25.7 0-37.4z"/>
<path id="Shape 2 copy" class="s0" d="m127.5 118.8c-12.2 0-22-3.4-22-7.6 0-4.2 9.8-7.7 22-7.7 12.2 0 22 3.5 22 7.7 0 4.2-9.8 7.6-22 7.6zm0 0c-12.2 0-22-3.4-22-7.6 0-4.2 9.8-7.7 22-7.7 12.2 0 22 3.5 22 7.7 0 4.2-9.8 7.6-22 7.6z"/>
</g>
<g id="Folder 1 copy">
<path id="Shape 2" class="s4" d="m103 67.5c0-5.8 11-9.5 24.5-9.5 13.5 0 24.5 3.7 24.5 9.5 0 3.2 0 12.8 0 16 0 5.8-11 10.5-24.5 10.5-13.5 0-24.5-4.7-24.5-10.5 0-3.2 0-12.8 0-16z"/>
<path id="Shape 2 copy 4" class="s1" d="m103 67.5c0-5.8 11-9.5 24.5-9.5 13.5 0 24.5 3.7 24.5 9.5 0 3.2 0 12.8 0 16 0 5.8-11 10.5-24.5 10.5-13.5 0-24.5-4.7-24.5-10.5 0-3.2 0-12.8 0-16z"/>
<path id="Shape 2 copy 2" class="s2" d="m127.5 58c13.5 0 24.5 3.7 24.5 9.5 0 3.2 0 12.8 0 16 0 5.8-11 10.5-24.5 10.5 0-12.6 0-24.8 0-36z"/>
<path id="Shape 2 copy" class="s0" d="m127.5 74.9c-11.7 0-21.2-3.3-21.2-7.4 0-4.1 9.5-7.4 21.2-7.4 11.7 0 21.2 3.3 21.2 7.4 0 4.1-9.5 7.4-21.2 7.4zm0 0c-11.7 0-21.2-3.3-21.2-7.4 0-4.1 9.5-7.4 21.2-7.4 11.7 0 21.2 3.3 21.2 7.4 0 4.1-9.5 7.4-21.2 7.4z"/>
</g>
<g id="Folder 1 copy 2">
<path id="Shape 2" class="s4" d="m161 89.5c0-5.8 11-9.5 24.5-9.5 13.5 0 24.5 3.7 24.5 9.5 0 3.2 0 12.8 0 16 0 5.8-11 10.5-24.5 10.5-13.5 0-24.5-4.7-24.5-10.5 0-3.2 0-12.8 0-16z"/>
<path id="Shape 2 copy 4" class="s1" d="m161 89.5c0-5.8 11-9.5 24.5-9.5 13.5 0 24.5 3.7 24.5 9.5 0 3.2 0 12.8 0 16 0 5.8-11 10.5-24.5 10.5-13.5 0-24.5-4.7-24.5-10.5 0-3.2 0-12.8 0-16z"/>
<path id="Shape 2 copy 2" class="s2" d="m185.5 80c13.5 0 24.5 3.7 24.5 9.5 0 3.2 0 12.8 0 16 0 5.8-11 10.5-24.5 10.5 0-12.6 0-24.8 0-36z"/>
<path id="Shape 2 copy" class="s0" d="m185.5 96.9c-11.7 0-21.2-3.3-21.2-7.4 0-4.1 9.5-7.4 21.2-7.4 11.7 0 21.2 3.3 21.2 7.4 0 4.1-9.5 7.4-21.2 7.4zm0 0c-11.7 0-21.2-3.3-21.2-7.4 0-4.1 9.5-7.4 21.2-7.4 11.7 0 21.2 3.3 21.2 7.4 0 4.1-9.5 7.4-21.2 7.4z"/>
</g>
<g id="Folder 1 copy 3">
<path id="Shape 2" class="s4" d="m45 89.5c0-5.8 11-9.5 24.5-9.5 13.5 0 24.5 3.7 24.5 9.5 0 3.2 0 12.8 0 16 0 5.8-11 10.5-24.5 10.5-13.5 0-24.5-4.7-24.5-10.5 0-3.2 0-12.8 0-16z"/>
<path id="Shape 2 copy 4" class="s1" d="m45 89.5c0-5.8 11-9.5 24.5-9.5 13.5 0 24.5 3.7 24.5 9.5 0 3.2 0 12.8 0 16 0 5.8-11 10.5-24.5 10.5-13.5 0-24.5-4.7-24.5-10.5 0-3.2 0-12.8 0-16z"/>
<path id="Shape 2 copy 2" class="s2" d="m69.5 80c13.5 0 24.5 3.7 24.5 9.5 0 3.2 0 12.8 0 16 0 5.8-11 10.5-24.5 10.5 0-12.6 0-24.8 0-36z"/>
<path id="Shape 2 copy" class="s0" d="m69.5 96.9c-11.7 0-21.2-3.3-21.2-7.4 0-4.1 9.5-7.4 21.2-7.4 11.7 0 21.2 3.3 21.2 7.4 0 4.1-9.5 7.4-21.2 7.4zm0 0c-11.7 0-21.2-3.3-21.2-7.4 0-4.1 9.5-7.4 21.2-7.4 11.7 0 21.2 3.3 21.2 7.4 0 4.1-9.5 7.4-21.2 7.4z"/>
</g>
</g>
</svg>`;
export const gearColored = `<svg viewBox="0 0 128 128" preserveAspectRatio="xMidYMid meet">
<path d="M124 71.85v-15.7c0-.59-.45-1.09-1.03-1.15l-17.83-1.89c-.47-.05-.85-.38-.98-.83c-.86-2.95-2.03-5.76-3.48-8.39c-.23-.41-.19-.92.11-1.28l11.28-13.94c.37-.46.34-1.13-.08-1.54l-11.1-11.1a1.15 1.15 0 0 0-1.54-.08L85.39 27.22c-.37.3-.87.33-1.28.11a41.796 41.796 0 0 0-8.39-3.48c-.45-.13-.78-.51-.83-.98L73 5.03C72.94 4.45 72.44 4 71.85 4h-15.7c-.59 0-1.09.45-1.15 1.03l-1.89 17.83c-.05.47-.38.85-.83.98c-2.95.86-5.76 2.03-8.39 3.48c-.41.23-.92.19-1.28-.11L28.67 15.94a1.15 1.15 0 0 0-1.54.08l-11.1 11.1a1.15 1.15 0 0 0-.08 1.54L27.23 42.6c.3.37.33.87.11 1.28a41.796 41.796 0 0 0-3.48 8.39c-.13.45-.51.78-.98.83L5.03 55c-.58.06-1.03.56-1.03 1.15v15.7c0 .59.45 1.09 1.03 1.15l17.83 1.89c.47.05.85.38.98.83c.86 2.95 2.03 5.76 3.48 8.39c.23.41.19.92-.11 1.28L15.94 99.33c-.37.46-.34 1.13.08 1.54l11.1 11.1c.42.42 1.08.45 1.54.08l13.94-11.28c.37-.3.87-.33 1.28-.11c2.64 1.45 5.45 2.62 8.39 3.48c.45.13.78.51.83.98l1.9 17.85c.06.59.56 1.03 1.15 1.03h15.7c.59 0 1.09-.45 1.15-1.03l1.89-17.83c.05-.47.38-.85.83-.98c2.95-.86 5.76-2.03 8.39-3.48c.41-.23.92-.19 1.28.11l13.94 11.28c.46.37 1.13.34 1.54-.08l11.1-11.1c.42-.42.45-1.08.08-1.54l-11.28-13.94c-.3-.37-.33-.87-.11-1.28c1.45-2.64 2.62-5.45 3.48-8.39c.13-.45.51-.78.98-.83L122.97 73c.58-.06 1.03-.56 1.03-1.15zm-60 3.43c-6.23 0-11.28-5.05-11.28-11.28S57.77 52.72 64 52.72S75.28 57.77 75.28 64S70.23 75.28 64 75.28z" fill="#82aec0"></path>
<path d="M80.56 49.48c3.67 4.18 5.78 9.77 5.43 15.85c-.65 11.16-9.83 20.19-21 20.68c-4.75.21-9.18-1.09-12.86-3.45c-.28-.18-.58.2-.34.44a22.412 22.412 0 0 0 17.85 6.67c10.78-.85 19.56-9.5 20.55-20.27c.77-8.36-3.06-15.87-9.23-20.33c-.29-.2-.62.15-.4.41z" fill="#2f7889"></path>
<path d="M43.87 65.32c-.67-13.15 7.83-22.79 20.01-22.79c.65 0 1.68 0 2.48.92c1.01 1.18 1.1 2.6 0 3.77c-.81.86-1.95.92-2.53 1c-12.3 1.59-15.18 9.35-15.83 16.77c-.03.33.06 2.35-1.71 2.56c-2.15.25-2.41-1.91-2.42-2.23z" fill="#b9e4ea"></path>
<path d="M25.24 65.87c-.01-22.03 15.9-40.19 38.13-41.05c.68-.03 2.45 0 3.55.99c1.01.91 1.38 2.51.79 3.82c-.95 2.11-2.85 2.07-3.36 2.09c-18.51.66-34.18 15.73-34.19 33.95c0 .29-.05.58-.15.84l-.1.25c-.76 1.98-3.52 2.09-4.43.18c-.15-.34-.24-.7-.24-1.07z" fill="#94d1e0"></path>
export const gearColored = `<svg viewBox="0 0 128 128" preserveAspectRatio="xMidYMid meet">
<path d="M124 71.85v-15.7c0-.59-.45-1.09-1.03-1.15l-17.83-1.89c-.47-.05-.85-.38-.98-.83c-.86-2.95-2.03-5.76-3.48-8.39c-.23-.41-.19-.92.11-1.28l11.28-13.94c.37-.46.34-1.13-.08-1.54l-11.1-11.1a1.15 1.15 0 0 0-1.54-.08L85.39 27.22c-.37.3-.87.33-1.28.11a41.796 41.796 0 0 0-8.39-3.48c-.45-.13-.78-.51-.83-.98L73 5.03C72.94 4.45 72.44 4 71.85 4h-15.7c-.59 0-1.09.45-1.15 1.03l-1.89 17.83c-.05.47-.38.85-.83.98c-2.95.86-5.76 2.03-8.39 3.48c-.41.23-.92.19-1.28-.11L28.67 15.94a1.15 1.15 0 0 0-1.54.08l-11.1 11.1a1.15 1.15 0 0 0-.08 1.54L27.23 42.6c.3.37.33.87.11 1.28a41.796 41.796 0 0 0-3.48 8.39c-.13.45-.51.78-.98.83L5.03 55c-.58.06-1.03.56-1.03 1.15v15.7c0 .59.45 1.09 1.03 1.15l17.83 1.89c.47.05.85.38.98.83c.86 2.95 2.03 5.76 3.48 8.39c.23.41.19.92-.11 1.28L15.94 99.33c-.37.46-.34 1.13.08 1.54l11.1 11.1c.42.42 1.08.45 1.54.08l13.94-11.28c.37-.3.87-.33 1.28-.11c2.64 1.45 5.45 2.62 8.39 3.48c.45.13.78.51.83.98l1.9 17.85c.06.59.56 1.03 1.15 1.03h15.7c.59 0 1.09-.45 1.15-1.03l1.89-17.83c.05-.47.38-.85.83-.98c2.95-.86 5.76-2.03 8.39-3.48c.41-.23.92-.19 1.28.11l13.94 11.28c.46.37 1.13.34 1.54-.08l11.1-11.1c.42-.42.45-1.08.08-1.54l-11.28-13.94c-.3-.37-.33-.87-.11-1.28c1.45-2.64 2.62-5.45 3.48-8.39c.13-.45.51-.78.98-.83L122.97 73c.58-.06 1.03-.56 1.03-1.15zm-60 3.43c-6.23 0-11.28-5.05-11.28-11.28S57.77 52.72 64 52.72S75.28 57.77 75.28 64S70.23 75.28 64 75.28z" fill="#82aec0"></path>
<path d="M80.56 49.48c3.67 4.18 5.78 9.77 5.43 15.85c-.65 11.16-9.83 20.19-21 20.68c-4.75.21-9.18-1.09-12.86-3.45c-.28-.18-.58.2-.34.44a22.412 22.412 0 0 0 17.85 6.67c10.78-.85 19.56-9.5 20.55-20.27c.77-8.36-3.06-15.87-9.23-20.33c-.29-.2-.62.15-.4.41z" fill="#2f7889"></path>
<path d="M43.87 65.32c-.67-13.15 7.83-22.79 20.01-22.79c.65 0 1.68 0 2.48.92c1.01 1.18 1.1 2.6 0 3.77c-.81.86-1.95.92-2.53 1c-12.3 1.59-15.18 9.35-15.83 16.77c-.03.33.06 2.35-1.71 2.56c-2.15.25-2.41-1.91-2.42-2.23z" fill="#b9e4ea"></path>
<path d="M25.24 65.87c-.01-22.03 15.9-40.19 38.13-41.05c.68-.03 2.45 0 3.55.99c1.01.91 1.38 2.51.79 3.82c-.95 2.11-2.85 2.07-3.36 2.09c-18.51.66-34.18 15.73-34.19 33.95c0 .29-.05.58-.15.84l-.1.25c-.76 1.98-3.52 2.09-4.43.18c-.15-.34-.24-.7-.24-1.07z" fill="#94d1e0"></path>
</svg>`;
export function $svg(markup, attrs) {
if (!markup.match(/^\s*<svg/)) {