diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml
new file mode 100644
index 0000000..001d53f
--- /dev/null
+++ b/.github/workflows/deploy.yml
@@ -0,0 +1,46 @@
+name: Build and deploy to pages
+
+on:
+ push:
+ branches: [ "master" ]
+ pull_request:
+ branches: [ "master" ]
+
+permissions:
+ pages: write
+ id-token: write
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ with:
+ submodules: true
+ - name: Use Node.js 22.x
+ uses: actions/setup-node@v4
+ with:
+ node-version: 22.x
+ cache: 'npm'
+ - name: Install dependencies
+ run: npm ci
+ - name: Build
+ run: npm run build
+ - name: Upload
+ uses: actions/upload-pages-artifact@v3
+ with:
+ path: dist/
+
+ deploy:
+ environment:
+ name: github-pages
+ url: ${{ steps.deployment.outputs.page_url }}
+ runs-on: ubuntu-latest
+ if: github.event_name == 'push' && needs.build.result == 'success'
+ needs: build
+ steps:
+ - name: Deploy to GitHub Pages
+ id: deployment
+ uses: actions/deploy-pages@v4
+ with:
+ token: ${{ github.token }}
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..384c1d3
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,3 @@
+dist/
+node_modules/
+*.tsbuildinfo
\ No newline at end of file
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..4cd1699
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "packages/skyltrendering"]
+ path = packages/skyltrendering
+ url = https://github.com/axelw3/skyltrendering
diff --git a/config.json b/config.json
deleted file mode 100644
index 00cdde0..0000000
--- a/config.json
+++ /dev/null
@@ -1,102 +0,0 @@
-{
- "properties": {
- "inherit": ["color", "background", "font", "borderRadius", "lineHeight", "lineSpacing"],
- "globalDefaults": { "borderFeatures": {}, "borderWidth": 0, "padding": 0 },
- "rootDefaults": { "background": "#06a", "color": "white", "borderRadius": 8, "font": "sans-serif", "lineHeight": 46, "lineSpacing": 4, "fillCorners": true },
- "defaults": {
- ".": { "borderWidth": 4, "padding": 8 },
- "skylt": { "padding": 6, "blockDisplay": false, "passAnchor": false, "alignContentsV": "middle", "alignContents": "left", "xSpacing": 8 },
- "vagnr": { "value": "000", "borderWidth": 3, "borderRadius": 7, "dashedInset": false, "padding": [14, 2] },
- "text": { "value": "Text" },
- "newline": {},
- "symbol": { "padding": 5, "type": "arrow-small", "grow": true }
- }
- },
- "signTypes": {
- "junction": {
- "width": 120,
- "height": 240,
- "core": [0.4, 0.6, 0.15, 0.44],
- "nodes": {
- "fwd": { "x": [0.2, 0.8], "y": [0, 0], "ay": "bottom" },
- "right": { "x": [1, 1], "y": [0.27, 0.27], "ax": "left" },
- "left": { "x": [0, 0], "y": [0.27, 0.27], "ax": "right" },
- "lright": { "x": [1, 1], "y": [0.434, 0.434], "ax": "left" }
- }
- },
- "roundabout": {
- "width": 240,
- "height": 480,
- "core": [0.35, 0.75, 0.09, 0.35],
- "nodes": {
- "fwd": { "x": [0.5, 0.5], "y": [0.03, 0.03], "ay": "bottom" },
- "right": { "x": [0.9, 0.9], "y": [0.21, 0.21], "ax": "left" },
- "left": { "x": [0.1, 0.1], "y": [0.21, 0.21], "ax": "right" }
- }
- },
- "water": {
- "width": 209,
- "height": 19,
- "core": [0, 1, 0, 1],
- "nodes": {
- "name": { "x": [0.5, 0.5], "y": [-0.1, -0.1], "ax": "center", "ay": "bottom" }
- }
- },
- "spanish": {
- "width": 200,
- "height": 360,
- "core": [0.12, 0.78, 0, 0.65],
- "nodes": {
- "fwd": { "x": [0.08, 0.72], "y": [0, 0], "ay": "bottom" },
- "left": { "x": [0, 0], "y": [0.22, 0.22], "ax": "right" },
- "right": { "x": [1, 1], "y": [0.22, 0.22], "ax": "left" }
- }
- }
- },
- "symbols": {
- "arrow-small": { "width": 48, "height": [48, 192], "default": "left" },
- "exit": { "width": 46, "height": [26, 26], "default": "" },
- "h1": { "width": 40, "height": [40, 40], "default": "" },
- "h2": { "width": 40, "height": [40, 40], "default": "" },
- "h3": { "width": 40, "height": [40, 40], "default": "" },
- "h4": { "width": 40, "height": [40, 40], "default": "cng" },
- "h5": { "width": 40, "height": [40, 40], "default": "" },
- "h6": { "width": 40, "height": [40, 40], "default": "" },
- "h7": { "width": 40, "height": [40, 40], "default": "" },
- "h8": { "width": 40, "height": [40, 40], "default": "" },
- "h9": { "width": 40, "height": [40, 40], "default": "" },
- "h10": { "width": 40, "height": [40, 40], "default": "" },
- "h11": { "width": 40, "height": [40, 40], "default": "" },
- "h12": { "width": 40, "height": [40, 40], "default": "" },
- "h13": { "width": 40, "height": [40, 40], "default": "" },
- "h14": { "width": 40, "height": [40, 40], "default": "" },
- "h15": { "width": 40, "height": [40, 40], "default": "" },
- "h16": { "width": 40, "height": [40, 40], "default": "" },
- "h17": { "width": 40, "height": [40, 40], "default": "" },
- "h18": { "width": 40, "height": [40, 40], "default": "" },
- "h19": { "width": 40, "height": [40, 40], "default": "" },
- "h20": { "width": 40, "height": [40, 40], "default": "" },
- "h21": { "width": 40, "height": [40, 40], "default": "" },
- "h22": { "width": 40, "height": [40, 40], "default": "" },
- "h24": { "width": 40, "height": [40, 40], "default": "" },
- "h25": { "width": 40, "height": [40, 40], "default": "" },
- "h26": { "width": 40, "height": [40, 40], "default": "" },
- "h27": { "width": 40, "height": [40, 40], "default": "" },
- "h28": { "width": 40, "height": [40, 40], "default": "" }
- },
- "borderFeatures": {
- "bracket": { "paths": [{ "p": "M-${bw/2},0H0L22,27L44,0H${bw/2+w}", "s": 1, "f": 2 }], "w": 44, "h": 27, "cover": false },
- "arrow": { "paths": [{ "p": "M0,0V${h}H${w}V0z", "f": -2, "s": -2 }, { "p": "M0,0L${w/2},${h*17/27}L${w},0z", "f": 2 }, { "p": "M0,-${bw/2}V0L${w/2},${h*17/27}L${w},0V-${bw/2}V0L${w/2},${h*25/27}L0,0z", "s": 1, "f": 1 }], "w": 0, "h": "w*27/44", "cover": true },
- "diag": {
- "vars": [["k", "35/60"], ["x1", "1-(k/sqrt((k*k+1)))*bra"], ["xr", "1-(k/sqrt((k*k+1)))*brb"], ["a", "-2*brb+w+xr-x1*k+sqrt((2*bra-x1*x1))-sqrt((2*brb-xr*xr))"], ["margin", "30"]],
- "paths": [
- { "p": "M0,0V${-k*x1+sqrt((2*bra-x1*x1))+margin}L${w},${-sqrt((k*k+1))-k+1*bw/2+h}V0z", "f": -2, "s": -2 },
- { "p": "M0,-${bw/2}V${margin}A${bra},${bra},0,0,0,${x1},${sqrt((2*bra-x1*x1))+margin}L${-2*brb+w+xr},${a+sqrt((2*brb-xr*xr))+margin}A${brb},${brb},0,0,0,${w},${a+margin}V-${bw/2}", "s": 1, "f": 2 },
- { "p": "M${w/2-43},0m5,0l-5,7l65,38l-8,14l29,-7l-10,-27l-8,12l-64,-36z", "f": 1 }
- ],
- "w": 0,
- "h": "w-x1*k+sqrt((2*bra-x1*x1))+(sqrt((k*k+1))+k-1*bw/2)+margin",
- "cover": true
- }
- }
-}
\ No newline at end of file
diff --git a/formatver.json b/formatver.json
deleted file mode 100644
index c0e9afb..0000000
--- a/formatver.json
+++ /dev/null
@@ -1 +0,0 @@
-["4b2b419"]
\ No newline at end of file
diff --git a/graphics.js b/graphics.js
deleted file mode 100644
index ccb4db9..0000000
--- a/graphics.js
+++ /dev/null
@@ -1,125 +0,0 @@
-function roundedFrame(ctx, x0, y0, innerWidth, innerHeight, nominalLineWidth = [4, 4, 4, 4], color = "#000", borderRadius = [0, 0, 0, 0], lineDash = [1, 0]){
- // lineDash = [längd, mellanrum]
-
- if(Math.max(...nominalLineWidth) <= 0) return;
-
- let drawCorner = (cx, cy, signX, signY, i) => {
- let w0 = nominalLineWidth[(Math.ceil(i / 2) * 2) % 4],
- w1 = nominalLineWidth[Math.floor(i / 2) * 2 + 1],
- br = borderRadius[i];
-
- let arx = Math.max(br - w0, 0),
- ary = Math.max(br - w1, 0);
-
- cx -= signX * arx;
- cy -= signY * ary;
-
- let startAngle = ((i - 2) * Math.PI) / 2 + Math.PI/4;
-
- let v1 = startAngle - signX*signY*Math.PI/4,
- v2 = startAngle + signX*signY*Math.PI/4;
-
- ctx.beginPath();
- //ctx.moveTo(cx + signX * arx, cy);
- ctx.moveTo(cx + signX*(arx+w0), cy);
- ctx.lineTo(cx + signX*(arx+w0), cy + signY * Math.max(0, w1 - br));
- ctx.ellipse(cx + signX*Math.max(0, w0 - br), cy + signY * Math.max(0, w1 - br), br, br, 0, v1, v2, signX !== signY);
- ctx.lineTo(cx, cy + signY*(ary+w1));
- ctx.lineTo(cx, cy + signY*ary);
- ctx.ellipse(cx, cy, arx, ary, 0, v2, v1, signX === signY);
- //ctx.closePath();
-
- ctx.fillStyle = color;
- ctx.fill();
- };
-
- drawCorner(x0, y0, -1, -1, 0);
- drawCorner(x0 + innerWidth, y0, 1, -1, 1);
- drawCorner(x0 + innerWidth, y0 + innerHeight, 1, 1, 2);
- drawCorner(x0, y0 + innerHeight, -1, 1, 3);
-
- let drawLineDash = (innerLength, cb) => {
- let actualLineDash = [lineDash[0], lineDash[1]];
-
- let r = 0;
- while(true){
- r = (innerLength + actualLineDash[1]) % (actualLineDash[0] + actualLineDash[1]);
- if(r >= actualLineDash[1]) break;
- actualLineDash[0]++;
- }
-
- let z = Math.floor(r / 2);
- do{
- cb(z, actualLineDash[0]);
- z += actualLineDash[0] + actualLineDash[1];
- }while(z + actualLineDash[0] <= innerLength);
-
- };
-
- ctx.fillStyle = color;
-
- // Ovanför
- drawLineDash(
- innerWidth - Math.max(0, borderRadius[0] - nominalLineWidth[0]) - Math.max(0, borderRadius[1] - nominalLineWidth[2]),
- (x, w) => ctx.fillRect(x0 + Math.max(0, borderRadius[0] - nominalLineWidth[0]) + x, y0 - nominalLineWidth[1], w, nominalLineWidth[1])
- );
-
- // Nedanför
- drawLineDash(
- innerWidth - Math.max(0, borderRadius[3] - nominalLineWidth[0]) - Math.max(0, borderRadius[2] - nominalLineWidth[2]),
- (x, w) => ctx.fillRect(x0 + Math.max(0, borderRadius[3] - nominalLineWidth[0]) + x, y0 + innerHeight, w, nominalLineWidth[3])
- );
-
- // Vänster
- drawLineDash(
- innerHeight - Math.max(0, borderRadius[0] - nominalLineWidth[1]) - Math.max(0, borderRadius[3] - nominalLineWidth[3]),
- (y, h) => ctx.fillRect(x0 - nominalLineWidth[0], y0 + Math.max(0, borderRadius[0] - nominalLineWidth[1]) + y, nominalLineWidth[0], h)
- );
-
- // Höger
- drawLineDash(
- innerHeight - Math.max(0, borderRadius[1] - nominalLineWidth[1]) - Math.max(0, borderRadius[2] - nominalLineWidth[3]),
- (y, h) => ctx.fillRect(x0 + innerWidth, y0 + Math.max(0, borderRadius[1] - nominalLineWidth[1]) + y, nominalLineWidth[2], h)
- );
-}
-
-
-function roundedFill(ctx, x0, y0, innerWidth, innerHeight, borderWidth = [4, 4, 4, 4], borderRadius = [0, 0, 0, 0], background = "#fff", fillCorners = false){
- // lineDash = [längd, mellanrum]
-
- ctx.fillStyle = background;
-
- if(fillCorners || Math.max(...borderWidth) === 0){
- ctx.fillRect(x0 - borderWidth[0], y0 - borderWidth[1], innerWidth + borderWidth[0] + borderWidth[2], innerHeight + borderWidth[1] + borderWidth[3]);
- return;
- }
-
- let drawCorner = (cx, cy, signX, signY, i) => {
- let arx = borderRadius[i] + borderWidth[(Math.ceil(i / 2) * 2) % 4] / 2,
- ary = borderRadius[i] + borderWidth[Math.floor(i / 2) * 2 + 1] / 2;
-
- let startAngle = ((i - 2) * Math.PI) / 2;
- ctx.ellipse(
- cx - signX * borderRadius[i], cy - signY * borderRadius[i],
- arx, ary,
- 0,
- startAngle, startAngle + Math.PI / 2,
- false
- );
- };
-
- ctx.beginPath();
- drawCorner(x0, y0, -1, -1, 0);
- drawCorner(x0 + innerWidth, y0, 1, -1, 1);
- drawCorner(x0 + innerWidth, y0 + innerHeight, 1, 1, 2);
- drawCorner(x0, y0 + innerHeight, -1, 1, 3);
- ctx.fill();
-
- // mitten
- ctx.fillRect(
- x0 + Math.max(borderRadius[0], borderRadius[3]),
- y0 + Math.max(borderRadius[0], borderRadius[1]),
- innerWidth - Math.max(borderRadius[0], borderRadius[3]) - Math.max(borderRadius[1], borderRadius[2]),
- innerHeight - Math.max(borderRadius[0], borderRadius[1]) - Math.max(borderRadius[2], borderRadius[3])
- );
-}
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
new file mode 100644
index 0000000..f0f3132
--- /dev/null
+++ b/package-lock.json
@@ -0,0 +1,39 @@
+{
+ "name": "skyltprogram",
+ "version": "1.0.0",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "skyltprogram",
+ "version": "1.0.0",
+ "license": "AGPL-3.0-or-later",
+ "devDependencies": {
+ "ncp": "^2.0.0",
+ "typescript": "^5.8.2"
+ }
+ },
+ "node_modules/ncp": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz",
+ "integrity": "sha512-zIdGUrPRFTUELUvr3Gmc7KZ2Sw/h1PiVM0Af/oHB6zgnV1ikqSfRk+TOufi79aHYCW3NiOXmr1BP5nWbzojLaA==",
+ "dev": true,
+ "bin": {
+ "ncp": "bin/ncp"
+ }
+ },
+ "node_modules/typescript": {
+ "version": "5.8.2",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.2.tgz",
+ "integrity": "sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==",
+ "dev": true,
+ "bin": {
+ "tsc": "bin/tsc",
+ "tsserver": "bin/tsserver"
+ },
+ "engines": {
+ "node": ">=14.17"
+ }
+ }
+ }
+}
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..3bf4d56
--- /dev/null
+++ b/package.json
@@ -0,0 +1,14 @@
+{
+ "name": "skyltprogram",
+ "version": "1.0.0",
+ "description": "",
+ "scripts": {
+ "build": "tsc && ncp public/ dist/"
+ },
+ "author": "axelw3",
+ "license": "AGPL-3.0-or-later",
+ "devDependencies": {
+ "ncp": "^2.0.0",
+ "typescript": "^5.8.2"
+ }
+}
diff --git a/packages/skyltrendering b/packages/skyltrendering
new file mode 160000
index 0000000..303c0ea
--- /dev/null
+++ b/packages/skyltrendering
@@ -0,0 +1 @@
+Subproject commit 303c0ea3d00c4380748b93bd25ff16759cacdb98
diff --git a/styles.css b/public/css/styles.css
similarity index 100%
rename from styles.css
rename to public/css/styles.css
diff --git a/TRATEXPOSVERSAL-POSVERSAL.otf b/public/font/TRATEXPOSVERSAL-POSVERSAL.otf
similarity index 100%
rename from TRATEXPOSVERSAL-POSVERSAL.otf
rename to public/font/TRATEXPOSVERSAL-POSVERSAL.otf
diff --git a/TratexSvart-Regular.otf b/public/font/TratexSvart-Regular.otf
similarity index 100%
rename from TratexSvart-Regular.otf
rename to public/font/TratexSvart-Regular.otf
diff --git a/index.html b/public/index.html
similarity index 70%
rename from index.html
rename to public/index.html
index 14f55ef..ee75ddd 100644
--- a/index.html
+++ b/public/index.html
@@ -3,7 +3,7 @@
Skyltprogram
-
+
@@ -24,29 +24,11 @@
});
};
- const PREVIOUS_FORMAT_VERSIONS = await getJSON("formatver.json");
- const CURRENT_FORMAT_ID = PREVIOUS_FORMAT_VERSIONS.length;
-
let data_input = document.getElementById("input"), fr = document.getElementById("render");
data_input.addEventListener("change", () => {
let parsed = JSON.parse(data_input.value);
-
- let dataVersion = parseInt(parsed.format);
- if(isNaN(dataVersion)) dataVersion = 0;
-
- if(dataVersion < 0 || dataVersion > CURRENT_FORMAT_ID){
- alert("ERROR: Unknown data version " + dataVersion + ".");
- return;
- }
-
- let url = "render.html?";
-
- if(dataVersion !== CURRENT_FORMAT_ID){
- url += "f=" + PREVIOUS_FORMAT_VERSIONS[dataVersion] + "&";
- }
-
- fr.setAttribute("src", url + "data=" + window.encodeURIComponent(JSON.stringify(parsed)));
+ fr.setAttribute("src", "render.html?data=" + window.encodeURIComponent(JSON.stringify(parsed)));
});
getJSON("templates.json").then(templateData => {
@@ -57,8 +39,6 @@
option_el.appendChild(document.createTextNode(template.name));
option_el.setAttribute("value", i.toString(10));
templateSelect.appendChild(option_el);
-
- template.json = Object.assign({format: CURRENT_FORMAT_ID}, template.json);
});
templateSelect.value = data_input.value.length < 6 ? 0 : (-1);
diff --git a/public/render.html b/public/render.html
new file mode 100644
index 0000000..37ef042
--- /dev/null
+++ b/public/render.html
@@ -0,0 +1,10 @@
+
+
+
+ Skyltprogram (rendering)
+
+
+
+
+
+
\ No newline at end of file
diff --git a/public/res/junction.json b/public/res/junction.json
new file mode 100644
index 0000000..89c0729
--- /dev/null
+++ b/public/res/junction.json
@@ -0,0 +1,18 @@
+{
+ "width": 120,
+ "height": 240,
+ "vectorSize": [3, 6],
+ "defs": [
+ {"path": "M1.5,.2l.5.5a.1,.1,0,0,1,-.1,.1h-.3v.8h-.2v-.8h-.3a.1,.1,0,0,1,-.1,-.1z", "fill": "currentColor"},
+ {"path": "M1.5,1.5h.7v-.3a.1,.1,0,0,1,.1,-.1l.5,.5l-.5,.5a.1,.1,0,0,1,-.1,-.1v-.3h-.7z", "fill": "currentColor"},
+ {"path": "M1.5,1.5h-.7v-.3a.1,.1,0,0,0,-.1-.1l-.5,.5l.5,.5a.1,.1,0,0,0,.1-.1v-.3h.7z", "fill": "currentColor"},
+ {"path": "M1.6,1.5v4.5h-.2v-4.5z", "fill": "currentColor"}
+ ],
+ "core": [{"use": 3}],
+ "components": {
+ "fwd": [{"use": 0}],
+ "left": [{"use": 2}],
+ "right": [{"use": 1}],
+ "lright": [{"use": 1, "translate":[0,1]}]
+ }
+}
\ No newline at end of file
diff --git a/public/res/roundabout.json b/public/res/roundabout.json
new file mode 100644
index 0000000..ba40b88
--- /dev/null
+++ b/public/res/roundabout.json
@@ -0,0 +1,17 @@
+{
+ "width": 240,
+ "height": 480,
+ "vectorSize": [6, 12],
+ "defs": [
+ {"path": "M4,2.5v-.1h.5v-.3a.1,.1,0,0,1,.1,-.1l.5,.5l-.5,.5a.1,.1,0,0,1,-.1,-.1v-.3h-.5v.1z", "fill": "currentColor"},
+ {"path": "M2,2.5v-.1h-.5v-.3a.1,.1,0,0,0,-.1,-.1l-.5,.5l.5,.5a.1,.1,0,0,0,.1-.1v-.3h.5v.1z", "fill": "currentColor"},
+ {"path": "M3,1.5h-.1v-.5h-.3a.1,.1,0,0,1,-.1,-.1l.5,-.5l.5,.5a.1,.1,0,0,1,-.1.1h-.3v.5h.1z", "fill": "currentColor"},
+ {"path": "M2.9,12v-8.6h.1a.9.9,0,1,0-.9-.9v.1h-.2v-.1a1.1,1.1,0,1,1,1.2,1.096v8.404z", "fill": "currentColor"},
+ {"path": "M2.9,12v-8.6h.1a.9.9,0,0,0,0-1.8h-.1v-.2h.1a1.1,1.1,0,0,1,.1,2.1955v8.4045z", "fill": "currentColor"}
+ ],
+ "components": {
+ "fwd": [{"use": 4}, {"use": 2}],
+ "left": [{"use": 3}, {"use": 1}],
+ "right": [{"use": 0}]
+ }
+}
\ No newline at end of file
diff --git a/public/res/spanish.json b/public/res/spanish.json
new file mode 100644
index 0000000..6cfecf6
--- /dev/null
+++ b/public/res/spanish.json
@@ -0,0 +1,20 @@
+{
+ "width": 200,
+ "height": 360,
+ "vectorSize": [5, 9],
+ "defs": [
+ {"path": "M.72,2.06h1.4c1.1,0 2.05,1.7 .7,2.65l-.75,.47v.7q0,-.4,.15,-.5l.75,-.47c1.35,-.8,.85,-3,-.85,-3.09h-1.4zM2,.2l-.5.5a.1,.1,0,0,0,.1,.1h.28v7.04h.24v-7.04h.28a.1,.1,0,0,0,.1,-.1z", "fill": "currentColor"},
+ {"path": "M2,2.785a.725.725,0,0,0,0,1.45a.725.725,0,0,0,0,-1.45z", "fill": "#e45"},
+ {"path": "M2,2.935a.575.575,0,0,0,0,1.15a.575.575,0,0,0,0,-1.15z", "fill": "#fd0"},
+ {"path": "M1.66,3.26h.45a.2.2,0,0,1,.2.2v.49h-.18v-.47a.05.05,0,0,0-.05-.05h-.42v.05l-.14-.14l.14-.14z", "fill": "#000"},
+ {"path": "M1.65,3l.85,1l-.08.08l-.85-1z", "fill": "#e45"},
+ {"path": "M.28,1.94l.5,.5a.1,.1,0,0,0,.1,-.1v-.8a.1,.1,0,0,0,-.1,-.1l-.5,.5z", "fill": "currentColor"},
+ {"path": "M4.72,1.94l-.5,.5a.1,.1,0,0,1,-.1,-.1v-.28h-2v-.24h2v-.28a.1,.1,0,0,1,.1,-.1l.5,.5z", "fill": "currentColor"}
+ ],
+ "core": [{"use": 0}, {"use": 1}, {"use": 2}, {"use": 3}, {"use": 4}],
+ "components": {
+ "fwd": [],
+ "left": [{"use": 5}],
+ "right": [{"use": 6}]
+ }
+}
\ No newline at end of file
diff --git a/public/res/symbol/arrow-small.json b/public/res/symbol/arrow-small.json
new file mode 100644
index 0000000..6c0863f
--- /dev/null
+++ b/public/res/symbol/arrow-small.json
@@ -0,0 +1,17 @@
+{
+ "width": 48,
+ "height": 192,
+ "vectorSize": [1, 4],
+ "defs": [
+ {"path": "M0,0.4l0.33,0.33a0.07,0.07,0,0,0,0.12,-0.05v-0.19h0.25a0.11,0.11,0,0,1,0.11,0.11v3.4h0.18v-3.4a0.29,0.29,0,0,0,-0.29,-0.29h-0.25v-0.19a0.07,0.07,0,0,0,-0.12,-0.05l-0.33,0.33z", "fill": "currentColor"},
+ {"path": "M0,0.4m1,0l-0.33,0.33a0.07,0.07,0,0,1,-0.12,-0.05v-0.19h-0.25a0.11,0.11,0,0,0,-0.11,0.11v3.4h-0.18v-3.4a0.29,0.29,0,0,1,0.29,-0.29h0.25v-0.19a0.07,0.07,0,0,1,0.12,-0.05l0.33,0.33z", "fill": "currentColor"},
+ {"path": "M0.5,0.05l0.33,0.33a0.07,0.07,0,0,1,-0.05,0.12h-0.19v3.5h-0.18v-3.5h-0.19a0.07,0.07,0,0,1,-0.05,-0.12z", "fill": "currentColor"},
+ {"path": "M0.25,0.45l0.19,-0.19l-0.14,-0.14a0.07,0.07,0,0,1,0.04,-0.12h0.5v0.5a0.07,0.07,0,0,1,-0.12,0.04l-0.14,-0.14l-0.19,0.19q-0.06,0.07,-0.07,0.16v3.25h-0.19v-3.25q0,-0.16,0.12,-0.3z", "fill": "currentColor"}
+ ],
+ "components": {
+ "left": [{"use": 0}],
+ "right": [{"use": 1}],
+ "fwd": [{"use": 2}],
+ "exit": [{"use": 3}]
+ }
+}
\ No newline at end of file
diff --git a/public/res/symbol/exit.json b/public/res/symbol/exit.json
new file mode 100644
index 0000000..49911bb
--- /dev/null
+++ b/public/res/symbol/exit.json
@@ -0,0 +1,8 @@
+{
+ "width": 46,
+ "height": 26,
+ "vectorSize": [46, 26],
+ "defs": [
+ {"path": "M11,0l-11,26h13l3,-26h-5zM19,0l3,26h13l-11,-26zM46,0h-12l4.5,4.5q-4,3.5,-9,10l5.5,11.5q-1,-8,6.5,-18l4.5,4.5z", "fill": "currentColor"}
+ ]
+}
\ No newline at end of file
diff --git a/public/res/symbol/h1.json b/public/res/symbol/h1.json
new file mode 100644
index 0000000..dd4aeb4
--- /dev/null
+++ b/public/res/symbol/h1.json
@@ -0,0 +1,9 @@
+{
+ "width": 40,
+ "height": 40,
+ "vectorSize": [283.465, 283.465],
+ "defs": [
+ {"path": "M184.177,66.276c0,-23.441,-19.003,-42.443,-42.444,-42.443c-23.442,0,-42.444,19.002,-42.444,42.443c0,23.441,19.002,42.444,42.444,42.444c23.441,0,42.444,-19.003,42.444,-42.444z", "fill": "#111"},
+ {"path": "M201.153,240.297l6.602,0l0,9.902l-132.047,0l0,-9.902l6.602,0c4.503,0,8.821,-1.789,12.005,-4.973c3.184,-3.185,4.973,-7.504,4.973,-12.006l0,-78.285c0,-4.503,-1.789,-8.82,-4.973,-12.005c-3.184,-3.184,-7.502,-4.972,-12.005,-4.972l-6.131,0l0,-9.904l107.997,0l0,105.166c0,4.502,1.788,8.821,4.972,12.006c3.184,3.184,7.502,4.973,12.005,4.973z", "fill": "#111"}
+ ]
+}
\ No newline at end of file
diff --git a/public/res/symbol/h10.json b/public/res/symbol/h10.json
new file mode 100644
index 0000000..2967c9a
--- /dev/null
+++ b/public/res/symbol/h10.json
@@ -0,0 +1,9 @@
+{
+ "width": 40,
+ "height": 40,
+ "vectorSize": [283.465, 283.465],
+ "defs": [
+ {"path": "M16.376,135.843l125.356,-87.775l125.356,87.775l-16.696,23.842l-22.203,-15.548l0,88.304l-86.457,0l-86.457,0l0,-88.304l-22.204,15.548l-16.695,-23.842z", "fill": "#111"},
+ {"path": "M141.732,144.567l-36.378,0l72.755,0l0,28.346l-36.377,0l-36.378,0l0,-28.346l36.378,0z", "fill": "#fff"}
+ ]
+}
\ No newline at end of file
diff --git a/public/res/symbol/h11.json b/public/res/symbol/h11.json
new file mode 100644
index 0000000..700d1a1
--- /dev/null
+++ b/public/res/symbol/h11.json
@@ -0,0 +1,9 @@
+{
+ "width": 40,
+ "height": 40,
+ "vectorSize": [283.465, 283.465],
+ "defs": [
+ {"path": "M122.749,71.606l-100.072,173.332l238.11,0l-100.073,-173.332l7.447,-12.898l23.407,-40.543l-37.965,0l-11.871,20.562l-11.872,-20.562l-37.965,0l30.854,53.441z", "fill": "#111"},
+ {"path": "M81.732,216.85l-4.725,0l25.195,-43.637l39.53,-68.469l39.53,68.469l25.194,43.637l-4.724,0l-17.48,0l-42.52,-73.646l-42.52,73.646l-17.48,0z", "fill": "#fff"}
+ ]
+}
\ No newline at end of file
diff --git a/public/res/symbol/h12.json b/public/res/symbol/h12.json
new file mode 100644
index 0000000..64df22b
--- /dev/null
+++ b/public/res/symbol/h12.json
@@ -0,0 +1,10 @@
+{
+ "width": 40,
+ "height": 40,
+ "vectorSize": [283.465, 283.465],
+ "defs": [
+ {"path": "M8.555,183.992l0,16.064l3.32,0c-0.215,4.075,2.347,7.783,6.236,9.023c3.889,1.241,8.124,-0.298,10.309,-3.745c2.186,-3.447,1.771,-7.935,-1.011,-10.923c-2.78,-2.987,-7.227,-3.722,-10.821,-1.789l0,-8.63l101.102,0c0,-15.916,12.902,-28.818,28.818,-28.818c15.917,0,28.82,12.902,28.82,28.818l79.842,0c3.383,0,6.627,-1.343,9.02,-3.736c2.392,-2.391,3.736,-5.637,3.736,-9.019l0,-85.483c0,-6.123,-4.204,-11.447,-10.161,-12.867c-75.195,-17.926,-153.522,-18.178,-228.831,-0.736c-5.569,1.29,-9.512,6.251,-9.512,11.967l0,82.866c-0.065,2.899,0.416,5.784,1.418,8.504l-17.008,0l0,8.504l4.724,0zM171.076,183.992c0,-13.568,-10.999,-24.567,-24.568,-24.567c-13.567,0,-24.567,10.999,-24.567,24.567c0,13.569,11,24.568,24.567,24.568c13.569,0,24.568,-10.999,24.568,-24.568z", "fill": "#111"},
+ {"path": "M155.484,183.992c0,-4.957,-4.019,-8.976,-8.977,-8.976c-4.957,0,-8.976,4.019,-8.976,8.976c0,4.958,4.019,8.977,8.976,8.977c4.958,0,8.977,-4.019,8.977,-8.977zM157.846,75.331c-1.128,0,-2.209,0.448,-3.007,1.246c-0.797,0.797,-1.245,1.879,-1.245,3.006l0,25.512c0,1.128,0.448,2.209,1.245,3.007c0.798,0.797,1.879,1.245,3.007,1.245l75.591,0c2.348,0,4.252,-1.904,4.252,-4.252l0,-25.512c0,-1.127,-0.448,-2.209,-1.246,-3.006c-0.797,-0.798,-1.879,-1.246,-3.006,-1.246l-75.591,0zM55.799,105.095c0,2.348,1.904,4.252,4.252,4.252l25.511,0c1.128,0,2.21,-0.448,3.007,-1.245c0.798,-0.798,1.246,-1.879,1.246,-3.007l0,-25.512c0,-1.127,-0.448,-2.209,-1.246,-3.006c-0.797,-0.798,-1.879,-1.246,-3.007,-1.246l-25.511,0c-1.128,0,-2.209,0.448,-3.007,1.246c-0.797,0.797,-1.245,1.879,-1.245,3.006l0,25.512z", "fill": "#fff"},
+ {"path": "M274.067,233.126l-264.567,0l0,-23.622l264.567,0l0,23.622z", "fill": "#111"}
+ ]
+}
\ No newline at end of file
diff --git a/public/res/symbol/h13.json b/public/res/symbol/h13.json
new file mode 100644
index 0000000..74f0791
--- /dev/null
+++ b/public/res/symbol/h13.json
@@ -0,0 +1,8 @@
+{
+ "width": 40,
+ "height": 40,
+ "vectorSize": [283.465, 283.465],
+ "defs": [
+ {"path": "M45.355,208.819l-27.874,0l0,-20.788l80.314,0l0,20.788l-25.511,0l0,28.346l87.402,0l0,-70.393l-70.395,0l42.048,-42.047l-18.425,0l42.52,-42.52l-17.953,0l34.724,-60.144l34.725,60.144l-18.898,0l42.52,42.52l-18.426,0l42.048,42.047l-70.866,0l0,70.393l69.449,0l0,21.732l-235.276,0l0,-21.732l0.472,0l17.953,0l9.449,0l0,-28.346z", "fill": "#111"}
+ ]
+}
\ No newline at end of file
diff --git a/public/res/symbol/h14.json b/public/res/symbol/h14.json
new file mode 100644
index 0000000..2629a40
--- /dev/null
+++ b/public/res/symbol/h14.json
@@ -0,0 +1,9 @@
+{
+ "width": 40,
+ "height": 40,
+ "vectorSize": [283.465, 283.465],
+ "defs": [
+ {"path": "M94.488,234.803l94.488,0l0,-186.142l-94.488,0l0,186.142zM91.181,77.008l0,-31.181l101.102,0l0,31.181l6.605,0l15.6,-51.024l-72.756,0l-72.756,0l15.599,51.024l6.606,0zM265.985,257.481l0,-18.899l-248.504,0l0,18.899l124.252,0l124.252,0z", "fill": "#111"},
+ {"path": "M127.559,120c5.664,4.067,10.479,9.203,14.173,15.118c3.693,-5.915,8.508,-11.051,14.173,-15.118c4.498,-3.271,7.813,-7.913,9.449,-13.228c1.47,-6.319,-2.399,-12.649,-8.692,-14.223c-6.294,-1.573,-12.687,2.192,-14.363,8.459c-0.041,0.28,-0.253,0.505,-0.531,0.561c-0.31,-0.018,-0.562,-0.254,-0.603,-0.561c-1.676,-6.267,-8.069,-10.032,-14.363,-8.459c-6.294,1.574,-10.162,7.904,-8.692,14.223c1.635,5.315,4.951,9.957,9.449,13.228z", "fill": "#fff"}
+ ]
+}
\ No newline at end of file
diff --git a/public/res/symbol/h15.json b/public/res/symbol/h15.json
new file mode 100644
index 0000000..4a85b53
--- /dev/null
+++ b/public/res/symbol/h15.json
@@ -0,0 +1,8 @@
+{
+ "width": 40,
+ "height": 40,
+ "vectorSize": [283.465, 283.465],
+ "defs": [
+ {"path": "M14.173,196.064c3.995,-0.421,8.01,0.583,11.338,2.834c18.563,11.338,41.91,11.338,60.473,0c8.084,-3.78,17.428,-3.78,25.512,0c18.562,11.338,41.909,11.338,60.472,0c8.084,-3.78,17.428,-3.78,25.512,0c18.562,11.338,41.909,11.338,60.473,0c3.327,-2.251,7.343,-3.255,11.337,-2.834l0,-33.071c-3.994,-0.421,-8.01,0.583,-11.337,2.834c-18.564,11.338,-41.911,11.338,-60.473,0c-8.084,-3.78,-17.428,-3.78,-25.512,0c-18.563,11.338,-41.91,11.338,-60.472,0c-8.084,-3.78,-17.428,-3.78,-25.512,0c-18.563,11.338,-41.91,11.338,-60.473,0c-3.328,-2.251,-7.343,-3.255,-11.338,-2.834l0,33.071zM269.29,252.756c-3.994,-0.42,-8.01,0.584,-11.337,2.835c-18.564,11.339,-41.911,11.339,-60.473,0c-8.084,-3.78,-17.428,-3.78,-25.512,0c-18.563,11.339,-41.91,11.339,-60.472,0c-8.084,-3.78,-17.428,-3.78,-25.512,0c-18.563,11.339,-41.91,11.339,-60.473,0c-3.328,-2.251,-7.343,-3.255,-11.338,-2.835l0,-33.07c3.995,-0.421,8.01,0.583,11.338,2.834c18.563,11.338,41.91,11.338,60.473,0c8.084,-3.78,17.428,-3.78,25.512,0c18.562,11.338,41.909,11.338,60.472,0c8.084,-3.78,17.428,-3.78,25.512,0c18.562,11.338,41.909,11.338,60.473,0c3.327,-2.251,7.343,-3.255,11.337,-2.834l0,33.07zM229.119,159.668c-11.143,0.27,-22.127,-2.676,-31.639,-8.487c-8.084,-3.779,-17.428,-3.779,-25.512,0c-18.563,11.339,-41.91,11.339,-60.472,0c-8.084,-3.779,-17.428,-3.779,-25.512,0c-9.105,5.562,-19.567,8.504,-30.236,8.504l8.314,-7.558c5.344,-5.645,11.126,-10.858,17.292,-15.591c3.418,-3.228,7.619,-5.508,12.188,-6.614l10.395,-3.78l10.393,-3.78c3.464,-1.326,5.976,-4.377,6.614,-8.031l0.7,-5.947c0.025,-0.42,-0.023,-0.841,-0.144,-1.245c-0.247,-0.747,-0.634,-1.439,-1.142,-2.04c-0.35,-0.397,-0.765,-0.732,-1.227,-0.991c-0.396,-0.217,-0.8,-0.418,-1.212,-0.603l-7.361,-2.804c-0.705,-0.276,-1.418,-0.534,-2.137,-0.773c-1.768,-0.722,-2.963,-2.398,-3.067,-4.305c-0.195,-2.582,-0.606,-5.142,-1.228,-7.654c-1.197,-2.958,-2.207,-5.987,-3.024,-9.071c-0.253,-2.987,-0.253,-5.99,0,-8.976l0.472,-3.78l0.473,-3.78c0.74,-3.883,0.069,-7.904,-1.89,-11.338c-4.717,-10.461,-2.935,-22.71,4.568,-31.393c0.69,-0.779,1.474,-1.47,2.333,-2.058c6.225,-4.177,13.285,-6.949,20.69,-8.124c11.13,-1.562,22.476,-0.283,32.98,3.719c1.728,0.686,3.382,1.545,4.939,2.561c4.332,3.186,7.797,7.406,10.081,12.275c0.513,1.192,0.947,2.418,1.298,3.666c2.586,10.68,4.051,21.599,4.371,32.582l0,4.484c-0.013,0.249,-0.035,0.497,-0.062,0.745c-0.598,4.533,-2.19,8.878,-4.662,12.724l-8.032,14.174c-1.014,2.052,-1.501,4.325,-1.417,6.614l0,6.613c0.064,1.887,0.815,3.685,2.11,5.059c0.604,0.554,1.263,1.046,1.964,1.472c0.4,0.25,0.805,0.493,1.214,0.728c3.498,2.154,7.094,4.146,10.774,5.97l12.756,6.614c9.752,5.037,18.295,12.129,25.04,20.787l8.031,9.449l-0.014,-0.017z", "fill": "#111"}
+ ]
+}
\ No newline at end of file
diff --git a/public/res/symbol/h16.json b/public/res/symbol/h16.json
new file mode 100644
index 0000000..0f1c62f
--- /dev/null
+++ b/public/res/symbol/h16.json
@@ -0,0 +1,8 @@
+{
+ "width": 40,
+ "height": 40,
+ "vectorSize": [283.465, 283.465],
+ "defs": [
+ {"path": "M152.615,106.043c0.183,3.768,1.942,7.286,4.849,9.69c1.428,0.919,2.737,2.013,3.895,3.254c3.657,3.802,6.843,8.031,9.487,12.595c3.352,4.906,6.203,10.135,8.514,15.609c0.807,2.129,1.577,4.273,2.309,6.429c1.455,4.601,2.98,9.18,4.574,13.734c1.245,2.72,0.722,5.922,-1.322,8.103c-0.673,0.563,-1.532,0.852,-2.408,0.813c-2.376,0.06,-4.54,-1.366,-5.421,-3.574c-2.398,-6.145,-4.526,-12.393,-6.378,-18.724c-0.256,-0.848,-0.637,-1.652,-1.133,-2.386c-2.369,-3.519,-5.123,-6.761,-8.212,-9.668c-0.073,6.016,1.033,11.988,3.255,17.579c2.593,7.056,5.605,13.952,9.019,20.65c3.951,8.091,8.365,15.947,13.22,23.531c-4.14,2.117,-8.442,3.898,-12.866,5.326c3.855,8.012,7.129,16.287,9.801,24.768c3.521,-9.02,7.728,-17.754,12.58,-26.131c3.392,-6.174,6.943,-12.26,10.649,-18.248c3.847,-5.575,6.827,-11.698,8.838,-18.164c1.224,-3.623,1.489,-7.501,0.767,-11.257c-0.432,-1.981,-0.958,-3.939,-1.575,-5.871c-1.806,0.362,-3.681,0.115,-5.332,-0.701c-0.506,-0.265,-0.95,-0.635,-1.302,-1.084c-0.521,-0.741,-0.922,-1.558,-1.188,-2.423c-0.354,-0.953,-0.715,-1.903,-1.084,-2.851c-3.732,-9.474,-6.601,-19.265,-8.568,-29.256c-0.603,-2.096,0.213,-4.342,2.021,-5.562c0.717,-0.576,1.635,-0.844,2.549,-0.743c0.914,0.1,1.752,0.56,2.327,1.278c2.428,3.136,4.636,6.434,6.61,9.872c2.668,-2.678,4.215,-6.272,4.327,-10.051c0.254,-2.085,0.377,-4.185,0.373,-6.285c0.025,-0.68,-0.125,-1.355,-0.436,-1.96c-0.377,-0.989,-0.769,-1.972,-1.178,-2.948c-0.216,-0.503,-0.543,-0.95,-0.955,-1.308c-0.689,-0.575,-1.542,-0.917,-2.437,-0.977c-4.522,-0.197,-8.238,-3.635,-8.785,-8.128c-0.299,-1.751,-0.578,-3.504,-0.839,-5.261c-0.565,-2.961,-0.813,-5.975,-0.739,-8.988c0.613,-4.595,4.234,-8.206,8.83,-8.808c3.347,-0.548,6.779,-0.241,9.975,0.892c0.676,0.278,1.318,0.634,1.91,1.061c2.3,1.907,3.874,4.546,4.46,7.476c0.268,3.024,0.481,6.053,0.639,9.085c0.463,3.014,1.292,5.96,2.469,8.773c0.451,1.179,1.347,2.133,2.496,2.657c2.267,0.96,4.453,2.107,6.533,3.428l-3.092,-12.998c4.004,-1.562,8.135,-2.78,12.346,-3.643c3.766,-0.154,7.156,2.26,8.244,5.868c4.506,17.131,8.801,34.317,12.886,51.553c0.468,3.937,-1.736,7.706,-5.398,9.228c-3.539,1.048,-7.099,2.025,-10.677,2.934c1.328,4.044,1.449,8.386,0.348,12.497c-1.531,5.643,-2.391,11.446,-2.559,17.29c-0.046,8.963,1.495,17.861,4.552,26.285c5.417,14.379,12.526,28.064,21.174,40.765l-15.998,9.409c-6.669,-9.578,-12.822,-19.504,-18.431,-29.741c-5.698,-12.339,-9.913,-25.31,-12.557,-38.644c-8.775,13.603,-16.768,27.697,-23.933,42.215c-3.813,8.519,-7.124,17.256,-9.912,26.162c-6.066,-2.205,-12.108,-4.477,-18.125,-6.817c0.685,-2.228,1.406,-4.447,2.163,-6.652c-5.572,-12.017,-11.947,-23.646,-19.081,-34.807c-7.281,0.081,-14.553,-0.535,-21.715,-1.841c-1.729,9.939,-5.554,19.398,-11.22,27.744c-0.765,1.123,-1.516,2.256,-2.254,3.396c-1.339,2.061,-2.353,4.315,-3.007,6.684c-0.705,2.928,-1.664,5.789,-2.867,8.553c-2.797,-0.85,-5.579,-1.746,-8.345,-2.694c2.45,-7.051,4.845,-14.121,7.185,-21.211c2.439,-8.386,4.418,-16.902,5.927,-25.506c0.458,-2.306,0.944,-4.607,1.458,-6.902c3.522,-16.865,5.519,-34.011,5.967,-51.233c-2.99,5.242,-5.969,10.491,-8.938,15.745c-1.652,2.711,-3.182,5.495,-4.585,8.344c-1.44,2.336,-3.154,4.494,-5.106,6.423c-0.782,0.698,-1.235,1.692,-1.25,2.741c-0.85,3.714,-1.655,7.441,-2.413,11.175c-0.122,0.801,-0.4,1.571,-0.818,2.264c-0.149,0.201,-0.317,0.389,-0.5,0.559c-0.336,0.291,-0.724,0.515,-1.142,0.66c-1.149,0.262,-2.342,0.262,-3.491,0.002c-2.921,-0.52,-5.795,-1.276,-8.592,-2.264c0.256,3.811,0.371,7.631,0.344,11.451c0.225,6.315,0.494,12.625,0.808,18.936c0.281,5.226,1.667,10.332,4.063,14.984c2.256,4.006,4.668,7.922,7.232,11.737c-3.003,2.005,-6.029,3.976,-9.079,5.91c-3.955,-5.43,-7.649,-11.045,-11.071,-16.828c-1.037,-1.422,-1.738,-3.061,-2.051,-4.793c-1.12,-4.922,-2.155,-9.864,-3.106,-14.823c-2.691,4.784,-5.289,9.618,-7.793,14.5c-3.138,6.946,-5.951,14.034,-8.428,21.239c-3.443,-0.877,-6.855,-1.87,-10.231,-2.975c0.667,-2.408,1.471,-4.777,2.409,-7.094c1.923,-4.369,3.716,-8.795,5.377,-13.269c2.809,-6.487,5.259,-13.123,7.338,-19.879c0.744,-3.582,1.248,-7.209,1.507,-10.86c-3.784,2.084,-7.603,4.102,-11.456,6.053c-1.699,0.756,-3.234,1.834,-4.524,3.174c-1.071,1.416,-2.637,2.379,-4.385,2.697c-0.804,0.125,-1.617,-0.164,-2.162,-0.769c-0.545,-0.606,-0.747,-1.446,-0.538,-2.233c0.658,-3.056,2.51,-5.724,5.143,-7.412c2.367,-1.359,4.619,-2.908,6.734,-4.635c2.711,-2.337,5.314,-4.798,7.798,-7.378c2.336,-2.702,4.893,-5.206,7.646,-7.481c1.18,-0.959,2.118,-2.182,2.738,-3.568c0.547,-1.354,-0.014,-2.903,-1.302,-3.59c-0.803,-0.393,-1.609,-0.779,-2.418,-1.158c-1.267,-0.606,-2.157,-1.791,-2.385,-3.177c-0.522,-1.863,-0.778,-3.791,-0.758,-5.726c-0.094,-1.095,-0.116,-2.195,-0.065,-3.293c-0.087,-1.211,0.012,-2.428,0.294,-3.61c0.662,-3.067,2.831,-5.59,5.763,-6.705c3.396,-1.261,7.131,-1.263,10.528,-0.004c2.247,0.817,3.972,2.651,4.653,4.942c0.898,2.239,1.353,4.629,1.342,7.041c0.116,3.402,-0.422,6.795,-1.586,9.995c-0.975,2.168,-0.202,4.724,1.811,5.988c2.08,1.127,4.164,2.244,6.253,3.351c0.829,-2.191,1.619,-4.396,2.37,-6.613c0.63,-1.789,1.195,-3.599,1.693,-5.429c0.118,-1.294,0.727,-2.493,1.702,-3.352c1.927,-2.243,3.727,-4.593,5.389,-7.039c1.927,-3.083,3.685,-6.268,5.268,-9.542c0.589,-1.383,1.121,-2.789,1.596,-4.216c2.987,-10.167,8.009,-19.621,14.761,-27.789c1.759,-1.936,3.347,-4.02,4.744,-6.232c0.166,-0.28,0.298,-0.578,0.394,-0.889c0.526,-1.736,0.469,-3.596,-0.162,-5.297c-0.575,-0.855,-1.363,-1.545,-2.285,-2.002c-2.189,-1.234,-3.81,-3.273,-4.518,-5.684c-0.817,-2.612,-1.047,-5.371,-0.676,-8.082c0.391,-2.142,0.374,-4.338,-0.049,-6.473c-0.494,-1.972,-0.149,-4.061,0.952,-5.77c3.653,-4.862,9.72,-7.27,15.713,-6.237c5.058,1.534,9.03,5.471,10.609,10.516c1.224,3.527,2.869,6.894,4.897,10.03c1.224,2.198,2.933,4.087,4.997,5.523c0.047,0.03,0.089,0.068,0.124,0.111c0.043,0.064,0.06,0.142,0.05,0.219c-0.01,0.045,-0.031,0.088,-0.061,0.123c-0.039,0.042,-0.086,0.079,-0.136,0.107c-0.039,0.017,-0.078,0.034,-0.118,0.049c-4.861,1.972,-9.905,3.46,-15.059,4.441zM67.746,82.787c-0.532,-9.668,3.255,-19.072,10.339,-25.673c12.585,-10.836,27.729,-18.278,43.996,-21.622c22.694,-5.113,45.887,-7.676,69.15,-7.638l43.225,0l0,-14.247l-220.85,0l0,255.413l15.952,0l0,-32.028c-0.303,-17.492,1.488,-34.957,5.336,-52.023c8.718,-33.649,39.073,-57.156,73.834,-57.175l0.025,-12.785c-11.394,-0.194,-22.417,-4.087,-31.406,-11.092c-6.08,-5.342,-9.576,-13.036,-9.601,-21.13z", "fill": "#111"}
+ ]
+}
\ No newline at end of file
diff --git a/public/res/symbol/h17.json b/public/res/symbol/h17.json
new file mode 100644
index 0000000..3ca953a
--- /dev/null
+++ b/public/res/symbol/h17.json
@@ -0,0 +1,8 @@
+{
+ "width": 40,
+ "height": 40,
+ "vectorSize": [283.465, 283.465],
+ "defs": [
+ {"path": "M200.044,97.842c0.842,-2.807,1.865,-5.557,3.063,-8.232c2.276,0.214,4.457,-0.971,5.517,-2.997c2.737,-4.422,3.909,-9.636,3.327,-14.804c-0.286,-3.803,-2.075,-7.337,-4.969,-9.821c-3.336,-2.52,-7.62,-3.429,-11.692,-2.48c-5.853,-0.207,-11.65,1.213,-16.744,4.102l2.592,3.304c2.967,-2.496,6.365,-4.432,10.026,-5.712c-0.567,0.778,-1.023,1.629,-1.354,2.532c-0.464,1.166,-0.826,2.372,-1.081,3.601c-0.349,1.599,-0.458,3.243,-0.323,4.875c0.399,3.076,1.285,6.069,2.623,8.867c0.283,0.601,0.373,1.274,0.258,1.927c-0.191,1.371,-0.721,2.672,-1.544,3.784c5.079,1.711,8.952,5.868,10.301,11.054zM133.1,69.685c0.349,-0.296,0.655,-0.639,0.909,-1.019c0.807,-1.464,1.504,-2.985,2.085,-4.552c2.67,-7.332,2.574,-15.387,-0.27,-22.654c-1.4,-2.934,-3.844,-5.24,-6.854,-6.47c-4.427,-2.236,-9.676,-2.12,-14,0.309c-7.209,0.372,-14.232,2.423,-20.508,5.99l3.659,4.576c3.963,-3.491,8.586,-6.149,13.597,-7.817c-1.645,2.002,-2.665,4.444,-2.93,7.021c-0.228,3.331,0.421,6.664,1.881,9.666c1.091,1.809,1.858,3.793,2.268,5.865c0.058,2.384,-0.308,4.759,-1.081,7.015c4.8,1.795,8.613,5.543,10.49,10.311c1.324,-2.491,2.64,-4.987,3.946,-7.487c2.215,1.135,4.895,0.838,6.808,-0.754zM186.615,136.763c-0.634,-1.364,-1.131,-2.787,-1.485,-4.249c-0.724,-3.075,-1.078,-6.226,-1.054,-9.385c0.697,3.522,1.732,6.969,3.093,10.292c1.639,4.347,4.205,8.286,7.519,11.543c1.14,1.283,2.658,2.17,4.336,2.533c1.341,0.23,2.694,-0.336,3.472,-1.452c0.109,-0.182,0.214,-0.365,0.316,-0.551c2.62,-4.949,5.049,-9.996,7.283,-15.131c1.486,-3.822,2.748,-7.729,3.779,-11.699c0.744,-3.615,0.879,-7.328,0.4,-10.987c-0.182,-1.876,-0.709,-3.702,-1.555,-5.386c-0.034,-0.058,-0.074,-0.114,-0.119,-0.165c-1.056,-1.179,-2.773,-1.502,-4.185,-0.785c-0.32,0.168,-0.591,0.415,-0.785,0.719c-2.01,3.767,-3.994,7.549,-5.951,11.343c-0.614,-3.98,-1.619,-7.89,-2.999,-11.673c-1.126,-3.439,-3.082,-6.548,-5.696,-9.05c-2.428,-2.382,-5.826,-3.498,-9.194,-3.019c-2.5,0.588,-4.725,2.011,-6.307,4.034l4.231,-15.301l-12.963,-4.054c-3.455,-0.518,-6.798,1.469,-7.994,4.751l-15.45,55.895c-0.657,2.015,-0.444,4.212,0.588,6.063c1.032,1.851,2.79,3.187,4.849,3.686l13.357,3.035c-0.031,1.161,-0.04,2.324,-0.024,3.486c0.053,2.025,0.172,4.049,0.356,6.066c0.27,3.362,0.875,6.69,1.804,9.932c0.333,1.355,0.663,2.71,0.99,4.065c0.305,1.592,0.544,3.195,0.716,4.806c0.049,1.871,-0.054,3.742,-0.309,5.596c-0.309,2.349,-0.788,4.672,-1.432,6.949c-0.72,2.553,-1.482,5.092,-2.285,7.619c-1.467,4.738,-3.279,9.365,-5.418,13.842c-1.839,4.166,-3.912,8.225,-6.207,12.156c-2.342,-7.574,-5.07,-15.023,-8.169,-22.318c-0.064,-0.16,-0.13,-0.32,-0.199,-0.479c-3.712,-9.595,-7.892,-19.006,-12.528,-28.191c-0.061,-0.126,-0.125,-0.252,-0.191,-0.375c-3.441,-7.299,-7.782,-14.137,-12.923,-20.356l3.588,-8.839c-6.074,-6.112,-10.739,-13.477,-13.669,-21.58c-1.93,-4.633,-2.731,-9.658,-2.338,-14.661c0.825,2.993,1.804,5.941,2.935,8.833c2.393,6.965,6.432,13.249,11.774,18.32c0.633,0.577,1.365,1.035,2.162,1.352c1.679,0.404,3.426,-0.328,4.315,-1.809c2.111,-3.475,4.113,-7.016,6.003,-10.616c0.212,-0.408,0.41,-0.822,0.593,-1.243c2.237,-5.42,4.103,-10.985,5.581,-16.659c0.118,-0.495,0.223,-0.992,0.314,-1.493c1.142,-5.518,1.057,-11.219,-0.246,-16.7c-0.174,-0.508,-0.486,-0.957,-0.9,-1.298c-1.211,-0.992,-2.918,-1.106,-4.25,-0.284c-0.098,0.07,-0.193,0.144,-0.284,0.223c-0.504,0.503,-0.941,1.07,-1.3,1.685l-7.435,11.773c-0.44,-6.943,-2.506,-13.684,-6.033,-19.679c-0.566,-0.984,-1.156,-1.953,-1.769,-2.907c-1.807,-2.717,-4.775,-4.438,-8.031,-4.655c-3.255,-0.218,-6.427,1.093,-8.578,3.546l3.678,-14.244l-15.555,-3.164c-2.158,-0.521,-4.433,-0.189,-6.352,0.926c-0.721,0.46,-1.364,1.03,-1.907,1.69c-0.796,0.896,-1.368,1.967,-1.669,3.126l-15.804,59.034c-0.053,0.213,-0.093,0.429,-0.121,0.646c-0.572,4.475,2.345,8.654,6.743,9.658l16.535,3.312l-0.319,1.551l-0.165,0.871c-0.423,2.513,-0.789,5.035,-1.096,7.565l-0.058,1.1l-0.052,1.368l0.07,1.541l0.113,2.092l0.243,1.941l0.223,1.343c0.229,1.269,0.521,2.528,0.874,3.769l0.612,2.601l0.39,2.27l0.58,3.545l0.068,2.699l-0.124,1.944l-0.212,2.592l-0.365,2.009l-0.593,2.059l-0.823,2.73l-0.884,2.391l-1.586,3.754l-1.205,2.777l-1.151,2.326l-2.11,4.362l-3.49,6.808l-2.783,5.219l-3.811,6.672l-3.478,5.89l-4.775,7.311l-5.112,7.795l-7.225,10.687l16.383,13.196l3.028,-4.35l7.389,-11.021c3.609,-5.149,7.036,-10.424,10.272,-15.815l3.124,-5.293c4.455,-7.162,8.603,-14.51,12.435,-22.023c3.323,-6.615,6.52,-13.291,9.59,-20.028c3.133,3.788,6.058,7.743,8.761,11.848l1.141,1.996c3.374,5.801,6.292,11.856,8.728,18.11l1.503,4.132c2.49,7.014,4.818,14.082,6.981,21.202l0.42,1.423c1.712,6.219,3.432,12.436,5.158,18.651l11.476,0.088c1.031,-1.674,2.044,-3.36,3.036,-5.055c1.043,-1.885,2.09,-3.77,3.14,-5.65l4.036,-7.496c3.453,-6.397,6.759,-12.87,9.915,-19.417c0.377,-0.773,0.762,-1.541,1.154,-2.306c2.481,-5.444,4.84,-10.942,7.076,-16.49l0.767,-1.846c1.71,-4.043,3.304,-8.133,4.783,-12.266c2.072,2.86,4.023,5.805,5.844,8.828l0.574,0.965c2.385,4.114,4.511,8.373,6.363,12.75l1.199,2.643c2.483,5.691,4.801,11.451,6.954,17.275l0.716,1.932c2.117,5.543,4.024,11.166,5.715,16.853l2.666,8.346l16.977,-6.41c-1.89,-5.867,-3.828,-11.719,-5.817,-17.553c-2.535,-7.414,-5.392,-14.715,-8.564,-21.879c-2.854,-7.355,-5.975,-14.603,-9.358,-21.73c-2.633,-5.354,-5.515,-10.582,-8.636,-15.667c-2.394,-3.964,-5.039,-7.771,-7.919,-11.398l3.69,-10.53c-2.815,-2.367,-5.344,-5.057,-7.531,-8.014c-1.758,-2.414,-3.288,-4.985,-4.572,-7.68c0,0,0,0,0,-0.001z", "fill": "#111"}
+ ]
+}
\ No newline at end of file
diff --git a/public/res/symbol/h18.json b/public/res/symbol/h18.json
new file mode 100644
index 0000000..65cb5b9
--- /dev/null
+++ b/public/res/symbol/h18.json
@@ -0,0 +1,9 @@
+{
+ "width": 40,
+ "height": 40,
+ "vectorSize": [283.465, 283.465],
+ "defs": [
+ {"path": "M3.382,51.902l112.52,-18.5l0.078,0.977l1.824,0.619l0.358,23.841l-26.497,1.805c-11.573,2.024,-19.714,12.509,-18.808,24.223l-0.091,39.084c-1.793,2.78,-3.11,5.84,-3.896,9.053l-7.785,30.763c-0.93,2.545,-0.691,5.371,0.652,7.724c1.344,2.353,3.655,3.995,6.32,4.488l6.095,1.691l0.368,27.344l66.265,-7.725l5.118,58.899l44.075,-5.342c-4.648,-4.018,-10.03,-7.096,-15.85,-9.065c-1.277,-0.724,-2.022,-2.121,-1.914,-3.588l-0.131,-45.71c0.076,-3.004,-1.118,-5.903,-3.289,-7.983c-2.17,-2.08,-5.116,-3.148,-8.115,-2.943l1.571,49.099c0.052,2.463,-0.044,4.928,-0.286,7.379c-1.215,-2.236,-1.928,-4.711,-2.09,-7.25l-1.885,-44.181c-0.23,-4.211,-2.893,-7.901,-6.817,-9.446c-0.096,-0.035,-0.192,-0.066,-0.289,-0.095c-2.794,-0.772,-5.699,-1.069,-8.593,-0.875l-20.617,0.822l-7.492,-21.533c-0.92,-2.018,-1.612,-4.132,-2.061,-6.303c-1.624,-5.704,-3.636,-11.289,-6.022,-16.717c-1.808,-3.135,-4.808,-5.405,-8.316,-6.292c-0.822,-0.246,-1.416,-0.96,-1.509,-1.813c-0.093,-0.852,0.334,-1.678,1.083,-2.094c1.874,-0.731,3.597,-1.799,5.085,-3.15c0.33,-0.312,0.615,-0.667,0.85,-1.055c0.919,-1.559,1.444,-3.318,1.528,-5.125c0.371,-2.638,0.262,-5.32,-0.319,-7.92c-0.134,-0.846,-0.264,-1.693,-0.392,-2.539c-0.213,-3.338,-0.887,-6.63,-2.001,-9.783c-0.162,-0.371,-0.354,-0.729,-0.572,-1.071c-1.706,-2.547,-4.245,-4.423,-7.18,-5.308c-7.092,-2.241,-14.734,1.212,-17.74,8.015l0.022,-9.446c-0.981,-9.752,5.655,-18.636,15.286,-20.461l30.018,-2.045l0,-3.588l-0.358,-23.841l1.088,-2.568l156.787,-25.06l0,-4.785l-157.272,25.138l-0.175,-1.698c-2.258,0.321,-4.462,0.945,-6.553,1.856l0.068,0.852l-112.144,18.437l0,4.789z", "fill": "#111"},
+ {"path": "M76.569,110.94c1.548,3.721,3.835,7.089,6.724,9.9c0.303,0.238,0.5,0.586,0.547,0.969c0,0.025,0,0.052,-0.002,0.077c-0.041,0.266,-0.191,0.503,-0.413,0.654c-0.234,0.109,-0.495,0.152,-0.751,0.123c-0.145,-0.027,-0.286,-0.064,-0.424,-0.112c-1.85,-0.535,-3.791,-0.679,-5.699,-0.426l0.026,-11.165l-0.008,-0.02z", "fill": "#fff"}
+ ]
+}
\ No newline at end of file
diff --git a/public/res/symbol/h19.json b/public/res/symbol/h19.json
new file mode 100644
index 0000000..f8f4690
--- /dev/null
+++ b/public/res/symbol/h19.json
@@ -0,0 +1,9 @@
+{
+ "width": 40,
+ "height": 40,
+ "vectorSize": [283.465, 283.465],
+ "defs": [
+ {"path": "M252.178,200.08c5.133,-4.966,9.658,-10.521,13.484,-16.551c-0.671,4.793,-1.78,9.515,-3.314,14.105c-1.102,2.939,-2.744,5.645,-4.845,7.977c-2.159,1.607,-4.56,2.861,-7.112,3.715l-144.047,58.392l-17.246,0.173l62.804,-25.51c-0.726,-2.179,-1.488,-4.345,-2.287,-6.498l-79.231,32.156l-14.29,-0.056l72.14,-29.275c-3.253,-7.944,-6.585,-15.856,-9.995,-23.735c-2.498,-5.49,-5.323,-10.828,-8.458,-15.981c-6.554,-10.433,-13.34,-20.718,-20.352,-30.849c-2.72,-0.722,-5.388,-1.623,-7.988,-2.698c-1.869,-0.639,-3.041,-2.494,-2.816,-4.456c23.175,7.565,48.297,6.544,70.782,-2.875l-2.536,-12.174c-12.615,5.359,-26.235,7.939,-39.937,7.568l55.238,-53.1l0.962,-0.918l-1.038,0.839l-41.096,32.177l-24.66,20.125c-7.457,-1.039,-14.764,-2.955,-21.772,-5.709l-34.455,70.723l5.588,5.594l-2.34,2.337l-4.78,-4.786l-7.393,15.176l-3.823,-1.862l8.037,-16.498l-4.806,-4.811l2.34,-2.337l3.998,4.003l27.958,-57.385l-39.695,56.524l5.095,5.045l-2.327,2.351l-4.696,-4.65l-9.1,12.958l-3.48,-2.444l9.516,-13.549l-5.396,-5.343l2.327,-2.35l4.996,4.947l50.305,-71.631c-3.206,-9.879,-6.029,-19.878,-8.464,-29.975c-0.506,1.739,-0.573,3.577,-0.194,5.348c1.332,7.49,3.238,14.865,5.7,22.062c0.208,0.506,0.335,1.042,0.374,1.588c-0.017,1.205,-0.688,2.305,-1.752,2.872c-0.634,0.232,-1.32,0.29,-1.984,0.165c-3.495,-0.768,-6.86,-2.04,-9.988,-3.776c-3.618,-1.603,-5.617,-5.521,-4.791,-9.391c0.334,-8.456,1.467,-16.862,3.383,-25.105c0.8,-4.457,2.407,-8.731,4.744,-12.611c1.08,-1.819,2.742,-3.222,4.716,-3.983c1.872,-0.756,3.626,-1.776,5.208,-3.029c0.697,-0.463,1.135,-1.229,1.181,-2.065c0.045,-0.836,-0.307,-1.645,-0.95,-2.181c-2.924,-3.343,-5.946,-6.599,-9.062,-9.763c-1.53,-1.695,-2.636,-3.728,-3.228,-5.933c-1.233,-5.188,-0.91,-10.624,0.927,-15.63c1.204,-2.609,3.355,-4.661,6.017,-5.742c6.195,-2.48,13.148,-2.242,19.16,0.656c2.525,1.629,4.448,4.037,5.478,6.859c1.472,3.906,2.6,7.933,3.374,12.035c0.686,4.525,-1.445,9.014,-5.384,11.343c-1.511,0.557,-2.689,1.766,-3.208,3.29c-0.565,1.832,0.38,3.789,2.165,4.487c9.643,4.162,19.971,6.513,30.465,6.938c12.519,1.179,25.081,1.859,37.655,2.038c5.418,-0.192,10.837,-0.303,16.259,-0.333c1.153,-0.852,2.444,-1.499,3.817,-1.912l95.521,-84.089l6.435,0l-96.007,84.518c1.041,1.35,1.072,3.223,0.076,4.606c-0.713,0.841,-1.572,1.545,-2.537,2.078c-1.344,0.806,-2.85,1.307,-4.408,1.468l-47.871,46.019c1.019,1.949,2.094,3.868,3.224,5.755c7.496,-1.408,14.744,-3.912,21.512,-7.428l4.164,19.986c-5.351,2.268,-10.801,4.296,-16.334,6.078c5.094,9.105,9.523,18.566,13.252,28.309c3.714,10.165,7.1,20.448,10.15,30.831l66.063,-26.808c2.482,-1.045,4.67,-2.684,6.369,-4.774c2.514,-2.909,4.758,-6.041,6.705,-9.356c0.074,3.909,-0.433,7.807,-1.504,11.567c-0.517,2.173,-1.965,4.007,-3.959,5.014c-1.482,0.781,-2.998,1.499,-4.543,2.15l-67.622,27.446c0.627,2.221,1.24,4.447,1.835,6.677l76.479,-31.066c3.914,-1.627,7.644,-3.667,11.123,-6.087z", "fill": "#111"},
+ {"path": "M138.41,234.551l9.256,-3.728c-2.373,-5.924,-5.015,-11.736,-7.92,-17.417c-3.033,-7.361,-6.996,-14.304,-11.792,-20.658c-2.263,-2.842,-5.019,-5.254,-8.135,-7.12c6.947,16.013,13.151,32.337,18.591,48.923zM110.137,113.69c-1.451,-2.723,-2.58,-5.605,-3.364,-8.589c5.502,0.117,11.005,-0.162,16.466,-0.837c11.725,-1.551,23.372,-3.635,34.907,-6.244l-39.768,31.138c-2.873,-5.088,-5.622,-10.245,-8.241,-15.468z", "fill": "#fff"}
+ ]
+}
\ No newline at end of file
diff --git a/public/res/symbol/h2.json b/public/res/symbol/h2.json
new file mode 100644
index 0000000..73a3da6
--- /dev/null
+++ b/public/res/symbol/h2.json
@@ -0,0 +1,8 @@
+{
+ "width": 40,
+ "height": 40,
+ "vectorSize": [283.465, 283.465],
+ "defs": [
+ {"path": "M121.469,19.844c2.524,-0.894,4.896,-2.169,7.035,-3.78l45.827,0l0.472,0l0,31.654l-0.472,0l-18.425,0l0,16.535l18.425,0l0.472,0l0,25.984l-0.472,0l-18.425,0l0,35.906l10.393,0l0,142.205l-49.133,0l0,-142.205l10.393,0l0,-35.906l-49.133,0l0,-25.984l49.133,0l0,-16.535l-49.133,0l0,-19.842c14.701,-0.196,29.26,-2.912,43.043,-8.032z", "fill": "#111"}
+ ]
+}
\ No newline at end of file
diff --git a/public/res/symbol/h20.json b/public/res/symbol/h20.json
new file mode 100644
index 0000000..2661730
--- /dev/null
+++ b/public/res/symbol/h20.json
@@ -0,0 +1,8 @@
+{
+ "width": 40,
+ "height": 40,
+ "vectorSize": [283.465, 283.465],
+ "defs": [
+ {"path": "M151.152,55.474c0.81,-0.601,1.454,-1.396,1.873,-2.313c0.203,-0.462,0.319,-0.958,0.342,-1.462c-0.047,-1.047,-0.123,-2.092,-0.228,-3.134c-0.499,-3.188,-1.495,-6.276,-2.952,-9.153c-1.043,-1.964,-2.294,-3.809,-3.735,-5.503c-0.356,-0.369,-0.725,-0.725,-1.106,-1.069c-0.568,-0.443,-1.169,-0.844,-1.797,-1.199c-0.497,-0.201,-0.993,-0.405,-1.487,-0.611c-1.745,-0.578,-3.564,-0.897,-5.401,-0.949c-2.775,0.064,-5.474,0.915,-7.785,2.453c-1.898,1.442,-3.33,3.41,-4.119,5.659c-0.48,1.255,-0.864,2.544,-1.147,3.858c-0.123,0.6,-0.223,1.205,-0.3,1.814c-0.096,0.721,-0.162,1.446,-0.197,2.173c-0.063,2.42,0.331,4.831,1.162,7.106c1.335,3.268,2.914,6.43,4.725,9.46c0.898,2.005,2.052,3.885,3.434,5.593c0.73,0.788,1.815,1.143,2.869,0.937c0.878,-0.467,1.696,-1.038,2.437,-1.702c2.691,-2.364,5.347,-4.768,7.968,-7.211c1.821,-1.56,3.628,-3.138,5.42,-4.733c0.007,-0.006,0.016,-0.011,0.024,-0.014zM129.805,15.086c-1.321,-0.499,-2.653,-0.967,-3.996,-1.404c-1.659,-0.476,-3.445,-0.029,-4.683,1.172c-1.704,1.859,-3.5,3.631,-5.38,5.311c-0.284,0.305,-0.445,0.706,-0.448,1.124c0.013,0.411,0.166,0.806,0.435,1.119c0.904,1.217,2.372,1.881,3.884,1.755c1.125,-0.007,2.25,0.023,3.374,0.088c2.264,0.141,4.524,0.336,6.778,0.585c2.674,0.413,5.344,0.852,8.009,1.316c2.219,0.401,4.405,0.965,6.542,1.688c1.398,0.377,2.808,0.714,4.227,1.008c0.815,0.227,1.681,0.19,2.475,-0.106c0.536,-0.159,1.007,-0.492,1.338,-0.946c0.148,-0.242,0.205,-0.53,0.158,-0.811c-0.016,-0.064,-0.035,-0.128,-0.057,-0.19c-0.141,-0.366,-0.34,-0.706,-0.586,-1.01c-0.334,-0.367,-0.738,-0.66,-1.19,-0.865c-2.029,-0.765,-4.002,-1.672,-5.903,-2.715c-2.154,-1.013,-4.287,-2.068,-6.399,-3.164c-2.764,-1.517,-5.63,-2.838,-8.578,-3.955zM94.451,173.744c-0.237,-0.328,-0.533,-0.607,-0.873,-0.826c-2.944,-2.691,-5.87,-5.402,-8.779,-8.132c-1.884,-1.587,-3.138,-3.797,-3.535,-6.229c-0.333,-2.934,-0.258,-5.9,0.222,-8.814c0.299,-1.52,0.684,-3.021,1.152,-4.497l28.393,-91.016c0.532,-1.581,1.181,-3.122,1.939,-4.609c0.708,-1.076,1.575,-2.038,2.569,-2.857c1.233,-0.836,2.083,-2.129,2.36,-3.594c0.441,-1.963,1.107,-3.87,1.987,-5.681c0.777,-1.846,2.052,-3.439,3.684,-4.6c0.904,-0.665,1.849,-1.273,2.829,-1.819c0.154,-0.087,0.3,-0.186,0.439,-0.296c0.032,-0.028,0.062,-0.059,0.089,-0.093c0.059,-0.079,0.106,-0.165,0.141,-0.256c0.009,-0.024,0.015,-0.048,0.02,-0.073c0.021,-0.148,0.003,-0.297,-0.053,-0.435c-0.099,-0.19,-0.269,-0.333,-0.472,-0.398c-0.909,-0.239,-1.813,-0.493,-2.713,-0.761c-1.043,-0.292,-2.121,-0.433,-3.203,-0.422c-1.738,-0.007,-3.473,0.133,-5.188,0.42c-0.751,0.152,-1.479,0.403,-2.164,0.748c-0.5,0.273,-0.967,0.602,-1.394,0.98c-1.83,1.518,-3.267,3.455,-4.189,5.647c-0.271,0.802,-0.518,1.612,-0.74,2.43c-0.484,1.875,-0.935,3.759,-1.352,5.651c-0.281,1.595,-0.252,3.23,0.086,4.814c0.076,0.201,0.141,0.407,0.195,0.616c0.129,0.976,0.032,1.967,-0.282,2.899l-28.263,90.6c-0.495,1.653,-0.973,3.311,-1.432,4.974c-0.326,1.189,-0.605,2.39,-0.836,3.601c-0.438,2.095,-0.798,4.206,-1.082,6.328c-0.343,2.108,-0.346,4.258,-0.008,6.367c0.347,1.916,0.951,3.775,1.797,5.529c0.816,1.613,1.883,3.087,3.162,4.366c1.434,1.645,3.033,3.139,4.772,4.46c1.154,0.672,2.416,1.141,3.731,1.385c0.97,0.187,1.972,0.129,2.915,-0.168c0.657,-0.256,1.286,-0.583,1.873,-0.975c0.994,-0.605,1.803,-1.471,2.336,-2.505c0.413,-0.886,0.363,-1.918,-0.133,-2.759zM197.097,234.044c0.529,-4.192,0.959,-8.399,1.288,-12.611c0.219,-3.031,0.465,-6.058,0.742,-9.083c0.939,-15.894,1.302,-31.818,1.085,-47.738c0.025,-10.444,-1.233,-20.851,-3.746,-30.988c-0.438,-1.509,-0.922,-3.004,-1.451,-4.483c-1.6,-5.143,-3.258,-10.267,-4.977,-15.372c-1.975,-5.261,-4.389,-10.347,-7.216,-15.204c-1.413,-2.703,-2.848,-5.394,-4.309,-8.072c-0.306,-0.636,-0.561,-1.295,-0.762,-1.972c-0.478,-1.454,-0.757,-2.967,-0.825,-4.496c-0.04,-0.821,0.004,-1.642,0.131,-2.454c0.318,-1.673,0.612,-3.35,0.884,-5.031l1.237,-7.688c0.131,-0.817,0.212,-1.641,0.241,-2.468c0.027,-0.75,0.051,-1.5,0.067,-2.25c-0.024,-0.428,-0.037,-0.857,-0.044,-1.286c-0.035,-1.001,-0.738,-1.853,-1.713,-2.08c-0.459,-0.08,-0.933,-0.01,-1.349,0.201c-0.439,0.334,-0.817,0.739,-1.121,1.2l-18.502,24.679c-0.039,0.053,-0.078,0.106,-0.116,0.16c-0.105,0.152,-0.239,0.283,-0.392,0.385c-0.012,0.008,-0.024,0.015,-0.035,0.022c-0.289,0.144,-0.628,0.148,-0.92,0.009c-0.058,-0.031,-0.112,-0.073,-0.154,-0.122c-0.174,-0.203,-0.264,-0.465,-0.251,-0.732c0.036,-0.247,0.134,-0.482,0.284,-0.681l21.031,-29.633c2.19,-2.612,3.464,-5.869,3.627,-9.273c-0.17,-1.395,-0.58,-2.75,-1.213,-4.006c-1.396,-2.643,-3.791,-4.619,-6.65,-5.488c-1.548,-0.479,-3.098,-0.948,-4.652,-1.407c-3.265,-0.83,-6.479,-1.852,-9.624,-3.062c-2.156,-0.788,-4.361,-1.441,-6.599,-1.955c-0.178,-0.061,-0.369,-0.066,-0.551,-0.015c-0.207,0.056,-0.331,0.268,-0.277,0.476c0.031,0.185,0.092,0.363,0.184,0.527c0.087,0.197,0.175,0.392,0.265,0.588c0.148,0.348,0.293,0.697,0.434,1.048c1.355,2.829,2.543,5.736,3.554,8.706c0.424,1.21,0.721,2.461,0.887,3.734c0.076,0.568,0.439,1.058,0.96,1.298c0.077,0.035,0.157,0.066,0.237,0.094c0.002,0.001,0.004,0.001,0.007,0.001c0.503,0.216,1.007,0.431,1.513,0.644c0.236,0.086,0.47,0.176,0.703,0.272c0.297,0.091,0.537,0.31,0.655,0.597c0.118,0.286,0.104,0.61,-0.041,0.885c-0.03,0.061,-0.064,0.12,-0.1,0.177c-0.561,1.037,-1.198,2.032,-1.905,2.975c-1.268,1.678,-2.707,3.219,-4.294,4.598c-2.68,2.611,-5.452,5.13,-8.305,7.551c-1.637,1.249,-3.222,2.563,-4.755,3.938c-3.076,2.602,-5.92,5.467,-8.501,8.562c-1.035,1.106,-1.907,2.353,-2.59,3.705c-0.866,1.701,-1.365,3.565,-1.462,5.471c0.013,0.985,0.119,1.967,0.314,2.933c0.304,1.278,0.696,2.533,1.175,3.756c0.495,1.158,1.037,2.294,1.627,3.407c1.351,2.441,2.807,4.822,4.363,7.139c6.222,8.349,12.325,16.787,18.305,25.311c0.467,0.614,0.818,1.306,1.037,2.044c0.25,1.017,0.199,2.084,-0.146,3.072c-0.125,0.326,-0.282,0.638,-0.471,0.932c-0.656,0.977,-1.281,1.974,-1.873,2.992c-0.613,0.998,-1.092,2.074,-1.424,3.199c-0.158,0.524,-0.287,1.055,-0.386,1.593c-0.342,1.652,-0.459,3.343,-0.346,5.026c0.046,4.918,0.251,9.832,0.611,14.737c0.611,9.62,1.268,19.236,1.969,28.85c0.141,1.732,-0.017,3.475,-0.463,5.154c-0.363,1.814,-1.228,3.49,-2.496,4.838c-0.805,0.946,-1.655,1.853,-2.549,2.716c-1.28,1.356,-2.618,2.656,-4.01,3.896c-4.651,3.983,-9.149,8.143,-13.485,12.467c-3.307,3.085,-6.691,6.085,-10.15,8.997c-4.069,3.603,-8.293,7.027,-12.66,10.261c-3.344,2.296,-6.669,4.618,-9.975,6.967c-0.459,0.293,-0.909,0.599,-1.351,0.918c-0.158,0.119,-0.31,0.245,-0.456,0.379c-0.094,0.092,-0.183,0.189,-0.269,0.289c-0.455,0.563,-0.757,1.232,-0.879,1.944c-0.029,0.789,0.061,1.577,0.267,2.339c0.871,3.358,2.112,6.611,3.7,9.696c1.332,2.458,2.629,4.934,3.892,7.428c0.777,1.357,1.741,2.599,2.863,3.689c0.878,0.9,2.043,1.465,3.294,1.597c1.142,0.121,2.297,0.056,3.418,-0.192c0.707,-0.169,1.216,-0.787,1.247,-1.512c0,-0.046,-0.001,-0.091,-0.006,-0.137c-0.271,-1.528,-0.522,-3.059,-0.754,-4.593c-0.438,-2.794,-0.485,-5.634,-0.14,-8.441c0.125,-1.57,0.371,-3.129,0.733,-4.661c0.443,-0.666,1.254,-0.984,2.031,-0.798c4.148,2.147,8.333,4.22,12.556,6.215c1.221,0.649,2.729,0.362,3.626,-0.69c1.429,-1.442,2.786,-2.954,4.066,-4.53c7.511,-8.424,14.846,-17.005,21.998,-25.736c4.016,-4.954,7.92,-9.999,11.711,-15.129c1.229,-1.401,2.229,-2.985,2.965,-4.696c1.046,-2.202,1.766,-4.545,2.137,-6.954c0.79,-3.259,1.542,-6.527,2.256,-9.804c0.345,-1.74,0.65,-3.487,0.915,-5.24c0.14,-0.762,0.5,-1.465,1.038,-2.023c0.117,-0.119,0.285,-0.173,0.45,-0.143c0.071,0.018,0.136,0.059,0.183,0.117c0.128,0.151,0.199,0.342,0.203,0.54c0.219,2.645,0.294,5.3,0.222,7.954c-0.095,4.88,-0.584,9.744,-1.464,14.546c-1.356,6.468,-2.564,12.968,-3.623,19.493c-0.676,5.954,-1.742,11.857,-3.191,17.672c-1.123,5.295,-2.5,10.534,-4.13,15.697c-1.162,3.684,-2.339,7.362,-3.533,11.035c-0.078,0.249,-0.128,0.506,-0.15,0.766c0.017,0.7,0.258,1.377,0.688,1.93c0.074,0.08,0.163,0.143,0.263,0.185c1.348,0.475,2.752,0.771,4.177,0.883c2.135,-0.042,4.241,-0.515,6.19,-1.392c0.046,-0.02,0.092,-0.043,0.136,-0.066c5.163,-2.852,10.378,-5.611,15.64,-8.276c1.675,-0.804,2.848,-2.381,3.135,-4.217c0.022,-0.328,0.047,-0.654,0.075,-0.981c1.506,-9.401,2.936,-18.815,4.29,-28.241z", "fill": "#111"}
+ ]
+}
\ No newline at end of file
diff --git a/public/res/symbol/h21.json b/public/res/symbol/h21.json
new file mode 100644
index 0000000..52534ea
--- /dev/null
+++ b/public/res/symbol/h21.json
@@ -0,0 +1,9 @@
+{
+ "width": 40,
+ "height": 40,
+ "vectorSize": [283.465, 283.465],
+ "defs": [
+ {"path": "M185.624,230.492c3.383,-1.439,6.67,-3.099,9.837,-4.968c2.695,0.072,5.391,-0.054,8.068,-0.376c6.295,-0.682,12.57,-1.53,18.82,-2.542c-6.551,4.668,-12.847,9.683,-18.861,15.026c-5.129,4.461,-9.986,9.225,-14.544,14.268c-1.114,-0.212,-2.201,-0.551,-3.239,-1.009c-4.032,-1.779,-7.922,-3.859,-11.639,-6.224c-3.408,-1.951,-6.514,-4.389,-9.218,-7.236c2.021,-0.719,4.07,-1.354,6.142,-1.905c4.992,-1.326,9.883,-3.007,14.634,-5.034zM204.198,214.55c-18.803,10.91,-39.516,18.132,-61.027,21.275l-14.904,1.367l-15.33,0.791l-16.238,-0.108c4.214,-2.59,8.074,-5.716,11.482,-9.301l3.367,-3.958c2.758,-3.376,4.945,-7.181,6.474,-11.264c0.802,-2.46,1.428,-4.975,1.872,-7.524l0.99,-5.984l16.229,-1.811l12.576,-1.61l8.528,-1.338c4.868,-0.91,9.668,-2.144,14.371,-3.692l15.733,-5.632l12.135,-5.247l12.173,-6.138l11.61,-6.289l9.027,-6.291l11.603,-10.705l8.592,-11.762l-0.585,4.432c-2.362,14.646,-7.729,28.644,-15.764,41.115c-5.249,8.365,-12.11,15.604,-20.182,21.292l-4.181,2.925l-8.551,5.457zM234.396,73.508c-3.484,-2.635,-7.264,-4.857,-11.263,-6.618l-66.77,-27.776l-1.056,-0.468c-0.454,-0.284,-1.049,-0.183,-1.386,0.234c-0.272,0.273,-0.423,0.644,-0.419,1.031c0.004,0.385,0.165,0.753,0.443,1.02l18.606,24.05l3.992,5.652c0.918,1.725,1.451,3.629,1.562,5.579c0.051,1.98,-0.245,3.954,-0.875,5.831l-2.083,4.128l-1.878,2.746c3.685,-0.637,7.373,-1.247,11.067,-1.829c5.485,-1.084,11.048,-1.737,16.636,-1.954c4.321,-0.246,8.649,-0.365,12.977,-0.356c3.725,0.057,7.445,0.299,11.147,0.724c2.316,0.269,4.609,0.701,6.863,1.294c1.732,0.604,3.38,1.426,4.906,2.446c2.365,1.602,4.215,3.858,5.32,6.492c1.047,2.08,1.617,4.366,1.668,6.693c0.849,-2.33,1.221,-4.807,1.094,-7.284c-0.11,-2.769,-0.533,-5.517,-1.265,-8.19c-1.073,-2.921,-2.497,-5.7,-4.243,-8.275c-1.477,-1.772,-3.081,-3.433,-4.801,-4.97c-0.078,-0.07,-0.158,-0.136,-0.242,-0.2zM243.819,143.676c4.472,-5.424,7.759,-11.725,9.647,-18.497c0.832,-3.185,1.457,-6.421,1.874,-9.686c0.353,-2.748,0.292,-5.534,-0.179,-8.266c-0.463,-2.92,-1.252,-5.779,-2.354,-8.523c-0.716,-1.786,-1.598,-3.501,-2.634,-5.123c0.039,1.218,0.083,2.436,0.131,3.653c-0.135,3.098,-0.547,6.178,-1.227,9.204c-0.736,2.73,-1.824,5.353,-3.237,7.802c-1.001,1.924,-2.244,3.713,-3.699,5.321c-1.944,2.279,-4.151,4.321,-6.573,6.083c-2.299,1.791,-4.689,3.464,-7.158,5.013c-2.672,1.676,-5.489,3.11,-8.416,4.285c-2.351,1.08,-4.798,1.936,-7.309,2.559c-3.014,0.912,-6.111,1.522,-9.246,1.821c-2.27,0.262,-4.557,0.362,-6.84,0.3c-0.573,-0.059,-1.045,-0.477,-1.172,-1.038c-0.045,-0.438,0.061,-0.878,0.301,-1.247c0.483,-0.626,0.968,-1.251,1.456,-1.873l12.29,-14.862l-45.026,3.666c-3.601,0.419,-7.244,0.331,-10.821,-0.26c-2.897,-0.454,-5.726,-1.27,-8.419,-2.43c-3.61,-1.727,-7.188,-3.522,-10.732,-5.381l-13.622,37.546c-4.407,1.092,-8.777,2.331,-13.102,3.715c-3.365,1.185,-6.73,2.367,-10.098,3.545c-3.439,1.227,-6.792,2.679,-10.038,4.349c-6.561,3.16,-12.906,6.753,-18.992,10.752c-3.365,2.283,-6.684,4.631,-9.957,7.045c-2.534,2.003,-5.054,4.023,-7.561,6.058l48.975,-173.516l-4.28,-1.137l-50.79,180.678c-3.611,3.48,-6.825,7.351,-9.581,11.542c1.255,0.309,2.506,0.631,3.755,0.964c0.588,0.158,1.172,0.326,1.754,0.505c1.915,0.591,3.829,1.187,5.742,1.787c0.583,0.183,1.165,0.37,1.745,0.562c1.453,0.48,2.889,1.012,4.305,1.594c3.302,1.357,6.584,2.765,9.843,4.222c1.367,0.612,2.71,1.274,4.028,1.986c0.629,0.339,1.231,0.728,1.799,1.162c0.087,0.066,0.161,0.146,0.22,0.239c0.101,0.129,0.19,0.267,0.266,0.412c0.137,0.289,0.145,0.623,0.022,0.918c-0.123,0.296,-0.365,0.525,-0.667,0.632c-2.282,0.496,-4.587,0.879,-6.907,1.146c-3.445,0.566,-6.871,1.236,-10.275,2.009c-3.323,0.815,-6.609,1.776,-9.847,2.882c-2.345,0.733,-4.669,1.529,-6.972,2.388c-2.003,0.656,-3.993,1.346,-5.971,2.073c-0.338,0.046,-0.619,0.284,-0.717,0.61c0.012,0.182,0.105,0.348,0.253,0.453c0.148,0.107,0.336,0.141,0.511,0.094l49.843,3.591c1.467,0.109,2.94,0.074,4.4,-0.105c3.099,-0.307,6.129,-1.107,8.975,-2.37c3.581,-1.673,6.886,-3.881,9.802,-6.548c2.656,-2.465,5.037,-5.21,7.1,-8.188c1.752,-2.752,3.177,-5.698,4.248,-8.78c1.083,-2.919,1.853,-5.944,2.299,-9.025c0.331,-2.47,0.503,-4.959,0.516,-7.451c12.018,-1.044,24.003,-2.422,35.945,-4.131c18.75,-3.254,36.861,-9.473,53.652,-18.427c4.563,-2.309,9.055,-4.754,13.47,-7.334c3.477,-1.824,6.804,-3.925,9.944,-6.282c2.536,-2.085,5.029,-4.222,7.475,-6.411c2.788,-2.586,5.404,-5.35,7.833,-8.275z", "fill": "#111"},
+ {"path": "M71.645,194.339c0,-3.561,-2.886,-6.447,-6.447,-6.447c-3.561,0,-6.447,2.886,-6.447,6.447c0,3.56,2.886,6.447,6.447,6.447c3.561,0,6.447,-2.887,6.447,-6.447z", "fill": "#fff"}
+ ]
+}
\ No newline at end of file
diff --git a/public/res/symbol/h22.json b/public/res/symbol/h22.json
new file mode 100644
index 0000000..1a82216
--- /dev/null
+++ b/public/res/symbol/h22.json
@@ -0,0 +1,9 @@
+{
+ "width": 40,
+ "height": 40,
+ "vectorSize": [283.465, 283.465],
+ "defs": [
+ {"path": "M215.905,120.946l-25.039,0l0,41.574l25.039,0c29.484,0,53.385,23.902,53.385,53.386c0,29.485,-23.901,53.385,-53.385,53.385c-29.484,0,-53.386,-23.9,-53.386,-53.385l0,-25.039l-41.575,0l0,25.039c0,29.485,-23.902,53.385,-53.386,53.385c-29.484,0,-53.385,-23.9,-53.385,-53.385c0,-29.484,23.901,-53.386,53.385,-53.386l25.04,0l0,-41.574l-25.04,0c-29.484,0,-53.385,-23.902,-53.385,-53.387c0,-29.483,23.901,-53.385,53.385,-53.385c29.484,0,53.386,23.902,53.386,53.385l0,25.04l41.575,0l0,-25.04c0,-29.483,23.902,-53.385,53.386,-53.385c29.484,0,53.385,23.902,53.385,53.385c0,29.485,-23.901,53.387,-53.385,53.387z", "fill": "#111"},
+ {"path": "M190.867,92.599l0,-25.04c0,-13.828,11.211,-25.039,25.039,-25.039c13.829,0,25.039,11.211,25.039,25.039c0,13.83,-11.21,25.04,-25.039,25.04l-25.039,0zM190.867,215.906c0,13.828,11.211,25.039,25.039,25.039c13.829,0,25.039,-11.211,25.039,-25.039c0,-13.828,-11.21,-25.039,-25.039,-25.039l-25.039,0l0,25.039zM92.598,215.906l0,-25.039l-25.04,0c-10.127,0,-19.257,6.1,-23.133,15.457c-3.876,9.356,-1.733,20.127,5.428,27.287c7.161,7.163,17.931,9.305,27.288,5.428c9.356,-3.875,15.457,-13.006,15.457,-23.133zM92.599,67.559c0,-13.828,-11.211,-25.039,-25.04,-25.039c-13.828,0,-25.039,11.211,-25.039,25.039c0,13.83,11.211,25.04,25.039,25.04l25.04,0l0,-25.04zM120.945,162.52l0,-41.574l41.575,0l0,41.574l-41.575,0z", "fill": "#fff"}
+ ]
+}
\ No newline at end of file
diff --git a/public/res/symbol/h24.json b/public/res/symbol/h24.json
new file mode 100644
index 0000000..3541951
--- /dev/null
+++ b/public/res/symbol/h24.json
@@ -0,0 +1,10 @@
+{
+ "width": 40,
+ "height": 40,
+ "vectorSize": [283.465, 283.465],
+ "defs": [
+ {"path": "M25.684,25.512l33.515,0c9.468,0,18.09,5.45,22.152,14.002c4.062,8.551,2.838,18.678,-3.143,26.016c7.88,7.221,10.519,18.538,6.645,28.499c-3.874,9.961,-13.465,16.523,-24.153,16.523l-35.016,0l0,-50.024l0,-35.016zM177.459,110.552l-15.383,-19.995c3.545,-7.645,6.377,-15.598,8.465,-23.76l-14.092,-5.221c-1.268,5.233,-2.879,10.375,-4.822,15.396l-10.143,-13.184c2.307,-2.004,4.475,-4.163,6.49,-6.461c6.154,-8.318,5.639,-19.812,-1.238,-27.546c-3.69,-3.122,-8.399,-4.777,-13.231,-4.649c-7.779,-0.044,-14.824,4.585,-17.87,11.742c-1.145,3.593,-1.534,7.383,-1.146,11.133c1.148,4.412,3.011,8.605,5.514,12.414l-0.06,0.038c-12.253,7.024,-17.756,21.786,-13.094,35.118c0.036,0.094,0.074,0.188,0.116,0.28c3.354,8.105,10.749,13.829,19.439,15.043c9.5,1.043,19.014,-1.839,26.338,-7.979l5.871,7.631l18.846,0zM200.252,25.512l33.516,0c9.467,0,18.09,5.45,22.152,14.002c4.061,8.551,2.838,18.678,-3.144,26.016c7.881,7.221,10.519,18.538,6.644,28.499c-3.873,9.961,-13.464,16.523,-24.152,16.523l-35.016,0l0,-50.024l0,-35.016z", "fill": "#111"},
+ {"path": "M41.191,59.027l18.009,0c4.973,0,9.004,-4.031,9.004,-9.003c0,-4.973,-4.031,-9.004,-9.004,-9.004l-18.009,0l0,18.007zM60.701,95.044c4.956,-0.005,9.221,-3.506,10.194,-8.366c0.971,-4.861,-1.62,-9.732,-6.193,-11.643c-1.477,-0.332,-2.987,-0.5,-4.502,-0.5l-19.009,0l0,20.509l19.51,0zM130.762,96.165c4.754,-0.127,9.309,-1.934,12.858,-5.101l-14.442,-18.774l-1.564,0.992c-6.047,3.315,-8.893,10.453,-6.781,17.018c1.656,3.815,5.539,6.17,9.687,5.877l0.242,-0.012zM134.629,51.464c1.868,-1.568,3.411,-3.487,4.541,-5.649c0.35,-1.604,0.248,-3.274,-0.293,-4.824c-0.916,-1.39,-2.269,-2.436,-3.845,-2.971c-1.893,-0.66,-3.994,-0.23,-5.477,1.119c-1.117,0.879,-1.828,2.175,-1.965,3.59c-0.343,1.693,-0.084,3.454,0.735,4.977c0.99,2.006,2.332,3.82,3.957,5.359c0.787,-0.527,1.57,-1.06,2.347,-1.601zM215.761,59.027l18.008,0c4.973,0,9.004,-4.031,9.004,-9.003c0,-4.973,-4.031,-9.004,-9.004,-9.004l-18.008,0l0,18.007zM235.268,95.044c4.957,-0.005,9.223,-3.506,10.193,-8.366c0.973,-4.861,-1.617,-9.732,-6.191,-11.643c-1.477,-0.332,-2.986,-0.5,-4.502,-0.5l-19.008,0l0,20.509l19.508,0z", "fill": "#fff"},
+ {"path": "M17.007,173.73l0,92.727l19.216,0l0,-19.039l211.018,0l0,19.039l19.215,0l0,-118.201c0,-5.289,-4.276,-9.584,-9.565,-9.608c-5.289,-0.025,-9.603,4.231,-9.65,9.52l0,37.373c-3.524,19.644,-19.709,34.53,-39.578,36.403l-171.44,0l0,-48.214c0,-5.307,-4.302,-9.608,-9.608,-9.608c-5.306,0,-9.608,4.301,-9.608,9.608zM236.295,177.412c-4.562,-5.776,-16.96,-3.588,-27.689,4.888c-10.73,8.476,-15.73,20.03,-11.168,25.806c4.563,5.776,16.961,3.587,27.691,-4.888c10.729,-8.476,15.729,-20.029,11.166,-25.806zM181.573,212.512c2.627,0.086,5.154,-1.015,6.881,-2.997c1.726,-1.983,2.468,-4.637,2.021,-7.228c-0.877,-5.084,-4.209,-9.405,-8.902,-11.547c-40.832,-13.926,-85.129,-13.926,-125.959,0c-5.017,1.712,-8.523,6.259,-8.902,11.547c-0.182,2.538,0.655,5.044,2.326,6.963c1.671,1.919,4.037,3.093,6.576,3.262l125.959,0z", "fill": "#111"}
+ ]
+}
\ No newline at end of file
diff --git a/public/res/symbol/h25.json b/public/res/symbol/h25.json
new file mode 100644
index 0000000..ff9a93c
--- /dev/null
+++ b/public/res/symbol/h25.json
@@ -0,0 +1,15 @@
+{
+ "width": 40,
+ "height": 40,
+ "vectorSize": [283.465, 283.465],
+ "defs": [
+ {"path": "M34.015,30.236l0,9.143l102.284,38.751l72.615,0c11.817,0,22.954,5.527,30.101,14.939c3.068,4.041,8.674,5.149,13.049,2.579c4.376,-2.571,6.137,-8.007,4.101,-12.655c-0.812,-1.856,-0.573,-4.004,0.626,-5.635c1.201,-1.631,3.181,-2.499,5.193,-2.275c2.013,0.224,3.754,1.504,4.567,3.359c3.264,7.452,2.012,16.111,-3.231,22.332c-5.243,6.22,-13.565,8.921,-21.462,6.966l-13.311,31.583c3.756,2.173,7.392,4.545,10.894,7.106c3.916,2.865,7.559,6.087,10.881,9.624c3.432,3.653,6.517,7.616,9.216,11.84c5.651,8.842,8.704,19.095,8.808,29.588c-0.104,10.493,-3.157,20.745,-8.808,29.587c-2.699,4.224,-5.784,8.187,-9.216,11.841c-3.322,3.536,-6.965,6.758,-10.881,9.623c-3.655,2.673,-7.456,5.14,-11.385,7.389c-3.737,2.139,-7.61,4.03,-11.594,5.66c-3.694,1.51,-7.444,2.885,-11.24,4.121c-3.643,1.185,-7.346,2.177,-11.093,2.972c-3.531,0.75,-7.083,1.402,-10.65,1.954c-3.512,0.543,-7.049,0.922,-10.597,1.134c-3.45,0.206,-6.906,0.327,-10.362,0.365c-3.457,-0.038,-6.913,-0.159,-10.364,-0.365c-3.548,-0.212,-7.084,-0.591,-10.596,-1.134c-3.568,-0.552,-7.119,-1.204,-10.65,-1.954c-3.748,-0.795,-7.45,-1.787,-11.094,-2.972c-3.795,-1.236,-7.544,-2.611,-11.239,-4.121c-3.985,-1.63,-7.858,-3.521,-11.595,-5.66c-3.929,-2.249,-7.73,-4.716,-11.385,-7.389c-3.916,-2.865,-7.559,-6.087,-10.881,-9.623c-3.431,-3.654,-6.517,-7.617,-9.216,-11.841c-5.651,-8.842,-8.704,-19.094,-8.808,-29.587c0.104,-10.493,3.157,-20.746,8.808,-29.588c2.699,-4.224,5.785,-8.187,9.216,-11.84c3.322,-3.537,6.965,-6.759,10.881,-9.624c3.502,-2.561,7.139,-4.933,10.894,-7.106l-13.047,-30.957l-49.429,0l0,144.862c0,4.01,-1.593,7.856,-4.428,10.691c-2.835,2.834,-6.681,4.427,-10.69,4.427l-3.78,0l0,-253.228l3.78,0c4.009,0,7.855,1.593,10.69,4.428c2.835,2.835,4.428,6.681,4.428,10.69z", "fill": "#111"},
+ {"path": "M101.698,163.382c-3.131,-3.591,-7.685,-5.625,-12.45,-5.557c-4.231,-0.019,-8.271,1.759,-11.116,4.89c-3.465,4.016,-5.36,9.149,-5.336,14.452c-0.024,5.303,1.871,10.436,5.336,14.451c2.845,3.133,6.885,4.91,11.116,4.891c8.104,0.372,15.062,-5.705,15.785,-13.784l0,-7.114l-15.785,0l0,6.803l8.978,0c-0.551,4.386,-4.426,7.584,-8.837,7.29c-2.334,0.059,-4.58,-0.888,-6.166,-2.6c-2.362,-2.77,-3.648,-6.297,-3.624,-9.937c-0.024,-3.64,1.262,-7.167,3.624,-9.937c1.56,-1.685,3.761,-2.63,6.057,-2.602c2.952,-0.062,5.761,1.265,7.588,3.584l4.83,-4.83zM121.838,168.421c-0.665,0.119,-1.319,0.295,-1.954,0.527c-2.928,1.273,-5.298,3.563,-6.67,6.448c-1.69,4.516,-1.69,9.49,0,14.006c1.5,3.297,4.329,5.802,7.782,6.892c1.754,0.42,3.582,0.42,5.336,0c1.648,-0.339,3.198,-1.046,4.535,-2.068l0,1.846l6.803,0l0,-27.591l-6.803,0l0,2.096c-1.062,-0.868,-2.294,-1.504,-3.616,-1.867c2.455,-1.121,3.827,-3.772,3.325,-6.422c-0.503,-2.651,-2.751,-4.616,-5.445,-4.759c-2.694,-0.144,-5.138,1.572,-5.919,4.155c-0.78,2.582,0.304,5.364,2.626,6.737z", "fill": "#fff"},
+ {"path": "M127.276,163.378c0,-1.356,-1.1,-2.456,-2.457,-2.456c-1.357,0,-2.457,1.1,-2.457,2.456c0,1.358,1.1,2.458,2.457,2.458c1.357,0,2.457,-1.1,2.457,-2.458zM130.866,185.413c-0.627,2.263,-2.447,4.001,-4.738,4.52c-1.426,0.313,-2.917,-0.019,-4.076,-0.906c-1.592,-1.293,-2.635,-3.14,-2.924,-5.171c-0.148,-1.04,-0.148,-2.097,0,-3.137c0.289,-2.031,1.332,-3.878,2.924,-5.171c1.159,-0.886,2.65,-1.218,4.076,-0.906c2.291,0.52,4.111,2.257,4.738,4.521l0,6.25z", "fill": "#111"},
+ {"path": "M146.74,196.072l0,-27.591l6.803,0l0,2.08c3.123,-2.002,6.893,-2.737,10.539,-2.058l0,7.019c-0.774,-0.321,-1.609,-0.471,-2.446,-0.437c-1.432,-0.038,-2.841,0.354,-4.048,1.125c-2.203,1.301,-3.691,3.537,-4.045,6.072l0,13.79l-6.803,0zM177.333,168.948c-2.929,1.273,-5.298,3.563,-6.67,6.448c-1.69,4.516,-1.69,9.49,0,14.006c1.5,3.297,4.328,5.802,7.781,6.892c1.754,0.42,3.582,0.42,5.336,0c1.649,-0.339,3.199,-1.046,4.536,-2.068l0,1.846l6.803,0l0,-37.795l-6.803,0l0,12.3c-1.308,-1.07,-2.871,-1.783,-4.536,-2.074c-2.147,-0.463,-4.382,-0.309,-6.447,0.445z", "fill": "#fff"},
+ {"path": "M188.315,185.413c-0.626,2.263,-2.447,4.001,-4.739,4.52c-1.426,0.313,-2.916,-0.019,-4.076,-0.906c-1.591,-1.293,-2.635,-3.14,-2.923,-5.171c-0.148,-1.04,-0.148,-2.097,0,-3.137c0.288,-2.031,1.332,-3.878,2.923,-5.171c1.16,-0.886,2.65,-1.218,4.076,-0.906c2.292,0.52,4.113,2.257,4.739,4.521l0,6.25z", "fill": "#111"},
+ {"path": "M206.599,187c1.937,1.308,4.152,2.148,6.468,2.454c1.491,0.207,3.005,0.132,4.466,-0.224c0.55,-0.129,1.034,-0.451,1.365,-0.909c0.319,-0.436,0.4,-1.001,0.216,-1.509c-0.185,-0.508,-0.611,-0.89,-1.136,-1.018l-9.336,-2.222c-3.023,-0.941,-5.133,-3.672,-5.282,-6.834c-0.147,-3.162,1.7,-6.078,4.621,-7.297c1.557,-0.623,3.203,-0.997,4.876,-1.108c4.724,-0.478,9.464,0.753,13.358,3.471l-3.825,5.626c-2.77,-1.768,-6.043,-2.58,-9.319,-2.308c-0.695,0.021,-1.381,0.173,-2.02,0.45c-0.48,0.269,-0.756,0.796,-0.707,1.344c0.049,0.547,0.415,1.015,0.934,1.196c0.221,0.085,0.445,0.16,0.672,0.224l8.671,2c2.648,0.689,4.739,2.716,5.508,5.341c0.77,2.624,0.104,5.46,-1.753,7.469c-1.67,1.645,-3.859,2.66,-6.193,2.874c-2.432,0.309,-4.893,0.309,-7.325,0.001c-2.908,-0.386,-5.662,-1.533,-7.982,-3.327l3.723,-5.694zM121.063,219.972c2.928,1.274,5.297,3.564,6.669,6.447c1.691,4.516,1.691,9.491,0,14.006c-1.499,3.297,-4.328,5.802,-7.781,6.893c-1.754,0.42,-3.582,0.42,-5.336,0c-1.648,-0.34,-3.198,-1.047,-4.535,-2.068l0,1.845l-6.803,0l0,-37.795l6.803,0l0,12.3c1.308,-1.069,2.87,-1.783,4.535,-2.073c2.148,-0.464,4.384,-0.31,6.448,0.445z", "fill": "#fff"},
+ {"path": "M110.079,236.436c0.627,2.265,2.447,4.001,4.738,4.522c1.426,0.311,2.917,-0.02,4.077,-0.907c1.591,-1.294,2.635,-3.14,2.923,-5.171c0.148,-1.041,0.148,-2.097,0,-3.137c-0.288,-2.031,-1.332,-3.877,-2.923,-5.171c-1.16,-0.887,-2.651,-1.219,-4.077,-0.906c-2.291,0.519,-4.111,2.256,-4.738,4.521l0,6.249z", "fill": "#111"},
+ {"path": "M159.591,247.095l0,-27.59l-6.804,0l0,16.63c0,2.505,-2.03,4.535,-4.535,4.535c-2.505,0,-4.535,-2.03,-4.535,-4.535l0,-16.63l-6.803,0l0,17.764c0,3.765,2.073,7.225,5.394,8.999c3.321,1.776,7.348,1.577,10.479,-0.515l0,1.342l6.804,0zM166.394,219.505l2.645,0l0,-6.913l6.804,-3.292l0,10.205l3.401,0l0,6.803l-3.401,0l0,12.473c0,0.835,0.677,1.512,1.512,1.512l1.152,0l0,6.802l-4.932,0c-2.505,0,-4.536,-2.03,-4.536,-4.535l0,-16.252l-2.645,0l0,-6.803zM187.182,219.505l6.802,0l0,27.59l-6.802,0l0,-27.59zM194.741,212.702c0,-2.296,-1.861,-4.158,-4.157,-4.158c-2.296,0,-4.157,1.862,-4.157,4.158c0,2.296,1.861,4.157,4.157,4.157c2.296,0,4.157,-1.861,4.157,-4.157zM209.859,247.095l0,-8.262l2.787,-2.819l7.695,11.081l8.283,0l-11.113,-16.003l11.454,-11.587l-9.566,0l-9.54,9.651l0,-19.856l-6.803,0l0,37.795l6.803,0zM102.538,77.464l-68.523,-25.96l0,26.626l70.591,0c-0.7,-0.187,-1.391,-0.409,-2.068,-0.666zM101.838,136.439c2.207,-1.104,4.455,-2.124,6.739,-3.058c3.695,-1.511,7.444,-2.886,11.239,-4.121c3.644,-1.186,7.346,-2.178,11.094,-2.973c3.531,-0.75,7.082,-1.401,10.65,-1.953c3.512,-0.545,7.048,-0.923,10.596,-1.135c3.451,-0.206,6.907,-0.327,10.364,-0.364c3.456,0.037,6.912,0.158,10.362,0.364c3.548,0.212,7.085,0.59,10.597,1.135c3.567,0.552,7.119,1.203,10.65,1.953c3.747,0.795,7.45,1.787,11.093,2.973c3.796,1.235,7.546,2.61,11.24,4.121c2.284,0.934,4.531,1.954,6.738,3.058l13.053,-30.969c-1.593,-0.927,-3.059,-2.056,-4.361,-3.359c-4.005,-4.004,-9.437,-6.254,-15.1,-6.254c-5.664,0,-11.095,2.25,-15.1,6.254c-4.004,4.005,-9.436,6.255,-15.1,6.255l-96.586,0l11.832,28.073z", "fill": "#fff"}
+ ]
+}
\ No newline at end of file
diff --git a/public/res/symbol/h26.json b/public/res/symbol/h26.json
new file mode 100644
index 0000000..9303961
--- /dev/null
+++ b/public/res/symbol/h26.json
@@ -0,0 +1,8 @@
+{
+ "width": 40,
+ "height": 40,
+ "vectorSize": [283.465, 283.465],
+ "defs": [
+ {"path": "M184.927,59.931c-1.231,-0.637,-2.32,-1.515,-3.201,-2.584c-4.003,-4.852,-6.581,-10.719,-7.447,-16.95c-0.424,-3.056,-0.949,-6.097,-1.571,-9.118c-1.059,-5.133,-3.407,-9.912,-6.824,-13.887c-2.229,-2.726,-5.667,-4.167,-9.174,-3.843c-5.9,0.544,-11.516,2.793,-16.161,6.473c-0.753,0.501,-1.393,1.155,-1.879,1.918c-2.714,4.263,-3.439,9.496,-1.986,14.337l3.879,10.027l2.666,8.644c1.281,3.08,4.191,5.174,7.519,5.41c1.445,-0.163,2.91,0.005,4.281,0.492c0.874,0.31,1.54,1.03,1.783,1.926c0.241,0.896,0.026,1.853,-0.574,2.561l-3.048,4.736l-2.306,4.757c-2.244,3.827,-3.41,8.19,-3.377,12.627l1.346,19.317c-0.019,2.534,-0.929,4.98,-2.573,6.91l-17.526,20.579l-0.886,0.755l-6.764,6.058l-5.764,5.096c-2.537,1.763,-3.635,4.969,-2.712,7.917c0.924,2.949,3.656,4.955,6.745,4.955c3.253,-0.054,6.334,-1.474,8.488,-3.913l4.335,-4.277l1.93,2.528l30.691,-27.23c-1.918,27.428,-5.717,54.691,-11.372,81.598c-0.405,2.398,-0.897,4.782,-1.475,7.144c2.114,0.29,4.231,0.566,6.349,0.827c0.002,0.036,0.004,0.073,0.007,0.109c-0.352,13.342,-0.654,26.687,-0.907,40.032c-0.017,0.877,-0.516,1.674,-1.297,2.073c-7.22,3.687,-14.671,6.901,-22.307,9.623c-1.493,0.532,-2.646,1.741,-3.107,3.258c-0.461,1.517,-0.176,3.162,0.769,4.436l35.572,0c0.529,0,1.021,-0.272,1.305,-0.719c3.119,-12.881,6.199,-25.773,9.239,-38.673c1.399,-5.94,2.747,-11.891,4.043,-17.853c9.316,0.679,18.652,1.08,27.993,1.204c0.225,1.072,0.38,2.158,0.467,3.25c1.051,13.35,2.656,26.65,4.809,39.867c0.159,0.973,-0.409,1.92,-1.342,2.237c-4.294,1.461,-8.424,3.374,-12.314,5.706c-0.975,0.585,-1.624,1.587,-1.76,2.715c-0.134,1.129,0.26,2.256,1.07,3.054l23.209,0l15.672,-4.537c0.44,-0.127,0.75,-0.522,0.769,-0.98c0.026,-0.626,-0.011,-1.254,-0.11,-1.872c-2.936,-18.278,-5.847,-36.561,-8.734,-54.847c-0.571,-5.082,-0.951,-10.183,-1.138,-15.294c-0.172,-4.688,-0.562,-9.367,-1.169,-14.019c0.082,-3.208,0.221,-6.414,0.42,-9.617c0.252,-3.423,0.591,-6.839,1.017,-10.246c0.235,-3.525,0.21,-7.064,-0.072,-10.586c-0.354,-6.376,-1.287,-12.708,-2.787,-18.916c-1.248,-5.162,-2.925,-10.21,-5.012,-15.093c-8.834,-20.662,-20.447,-40.021,-34.52,-57.54c-0.863,-1.073,-1.946,-1.947,-3.177,-2.562zM81.382,114.379l-22.846,0c-0.85,0,-1.629,0.475,-2.017,1.23c-0.389,0.756,-0.322,1.666,0.172,2.357c8.49,11.866,10.707,27.109,5.949,40.901c-0.239,0.693,-0.128,1.459,0.297,2.055c0.426,0.598,1.113,0.953,1.847,0.953l16.598,0l16.6,0c0.732,0,1.42,-0.355,1.846,-0.953c0.425,-0.596,0.536,-1.362,0.297,-2.055c-4.758,-13.792,-2.541,-29.035,5.949,-40.901c0.494,-0.691,0.561,-1.601,0.173,-2.357c-0.389,-0.755,-1.167,-1.23,-2.017,-1.23l-22.848,0zM92.72,185.633c0,-0.601,0.239,-1.178,0.664,-1.603c0.426,-0.426,1.002,-0.665,1.604,-0.665l40.819,0c0.601,0,1.178,-0.238,1.603,-0.664c0.425,-0.425,0.665,-1.002,0.665,-1.604l0,-12.471c0,-1.253,-1.016,-2.269,-2.268,-2.269l-108.85,0c-1.253,0,-2.268,1.016,-2.268,2.269l0,12.471c0,0.602,0.239,1.179,0.664,1.604c0.425,0.426,1.002,0.664,1.604,0.664l40.818,0c0.602,0,1.179,0.239,1.604,0.665c0.425,0.425,0.664,1.002,0.664,1.603l0,70.343c0,1.252,-1.015,2.268,-2.268,2.268l-23.811,0c-1.252,0,-2.268,1.014,-2.268,2.267l0,12.473c0,1.252,1.016,2.268,2.268,2.268l74.835,0c1.252,0,2.267,-1.016,2.267,-2.268l0,-12.473c0,-1.253,-1.015,-2.267,-2.267,-2.267l-23.811,0c-1.253,0,-2.268,-1.016,-2.268,-2.268l0,-70.343z", "fill": "#111"}
+ ]
+}
\ No newline at end of file
diff --git a/public/res/symbol/h27.json b/public/res/symbol/h27.json
new file mode 100644
index 0000000..ac8e858
--- /dev/null
+++ b/public/res/symbol/h27.json
@@ -0,0 +1,10 @@
+{
+ "width": 40,
+ "height": 40,
+ "vectorSize": [525.738, 525.738],
+ "defs": [
+ {"path": "M384.249,314.619l0,169.061l141.489,0l0,-213.152c-19.298,-27.956,-54.533,-40.115,-86.966,-30.009c-32.431,10.107,-54.523,40.131,-54.523,74.1z", "fill": "#111"},
+ {"path": "M416.563,371.05l51.708,-23.269l-11.376,44.986l-18.773,-6.123l11.532,54.398l41.526,-36.981l-18.757,-6.157l39.282,-89.937l-72.907,34.127l29.473,-57.912l-32.058,-11.376l-19.65,98.244z", "fill": "#e23"},
+ {"path": "M0,422.218l0,-163.108l125.736,0l-32.963,-61.997c-30.307,-7.806,-61.477,-11.757,-92.773,-11.757l0,-38.149c34.236,0,68.348,4.134,101.593,12.313c10.539,2.592,19.475,9.551,24.571,19.134l43.793,82.364c25.72,21.446,37.515,55.33,30.673,88.111l-13.701,51.132l0,46.541c0,20.367,-16.511,36.878,-36.878,36.878c-20.366,0,-36.877,-16.511,-36.877,-36.878l0,-24.584l-113.174,0zM201.738,342.651l0.247,0.12l1.289,0.611l0.784,0.375l1.035,0.443l1.12,0.486l1.289,0.549l1.078,0.38l1.33,0.528l1.289,0.422l1.305,0.422l1.162,0.359l1.098,0.274l1.268,0.296l1.12,0.21l1.141,0.233l1.225,0.147l1.139,0.127l1.289,0.085l1.373,-0.022l1.12,-0.021l1.183,-0.126l1.986,-0.296l1.31,-0.295l0.866,-0.254l1.219,-0.425l1.268,-0.464l1.563,-0.634l1.374,-0.654l1.33,-0.676l1.332,-0.675l1.183,-0.697l0.986,-0.556l1.289,-0.76l1.31,-0.802l0.993,-0.57l1.374,-0.823l1.161,-0.654l0.824,-0.486l0.969,-0.526l1.204,-0.655l1.352,-0.697l1.352,-0.653l1.099,-0.465l1.12,-0.465l1.12,-0.442l1.476,-0.465l0.634,-0.212l0.909,-0.273l0.528,-0.106l0.76,-0.211l1.078,-0.212l0.993,-0.232l1.12,-0.126l0.845,-0.147l1.221,-0.148l1.099,-0.085l0.93,-0.084l1.141,-0.063l0.951,-0.064l1.732,0l1.352,0.022l1.204,0.063l0.931,0.033l0.719,0.022l0.971,0.063l0.74,0.042l0.76,0.064l0.888,0.105l0.781,0.063l0.825,0.105l0.845,0.106l0.866,0.085l0.845,0.126l0.845,0.085l0.803,0.127l0.824,0.127l0.823,0.084l0.909,0.147l1.015,0.168l0.823,0.17l0.845,0.126l0.825,0.127l0.823,0.148l0.825,0.148l0.823,0.147l0.846,0.127l0.844,0.169l0,-6.392l2.525,0l0,-15.14l37.852,0l0,7.571l23.94,0c2.092,0,3.786,1.694,3.786,3.784c0,2.091,-1.694,3.785,-3.786,3.785l-23.94,0l0,20.19l23.94,0c2.092,0,3.786,1.694,3.786,3.784c0,2.092,-1.694,3.786,-3.786,3.786l-23.94,0l0,7.571l-37.852,0l0,-15.141l-2.525,0l0,-6.392l-0.844,-0.169l-0.846,-0.127l-0.823,-0.147l-0.825,-0.147l-0.823,-0.148l-0.825,-0.127l-0.845,-0.127l-0.823,-0.169l-1.015,-0.169l-0.909,-0.147l-0.823,-0.085l-0.824,-0.126l-0.803,-0.126l-0.845,-0.085l-0.845,-0.127l-0.866,-0.084l-0.845,-0.105l-0.825,-0.107l-0.781,-0.062l-0.888,-0.107l-0.76,-0.062l-0.74,-0.043l-0.971,-0.064l-0.719,-0.02l-0.931,-0.035l-1.204,-0.062l-1.352,-0.021l-1.732,0l-0.951,0.063l-1.141,0.062l-0.93,0.085l-1.099,0.085l-1.221,0.148l-0.845,0.147l-1.12,0.127l-0.993,0.233l-1.078,0.21l-0.76,0.212l-0.528,0.105l-0.909,0.274l-0.634,0.211l-1.476,0.464l-1.12,0.445l-1.12,0.463l-1.099,0.464l-1.352,0.656l-1.352,0.696l-1.204,0.654l-0.969,0.527l-0.824,0.486l-1.161,0.653l-1.374,0.823l-0.993,0.571l-1.31,0.802l-1.289,0.76l-0.986,0.556l-1.183,0.696l-1.332,0.676l-1.33,0.675l-1.374,0.655l-1.563,0.633l-1.268,0.465l-1.219,0.425l-0.866,0.253l-1.31,0.295l-1.986,0.296l-1.183,0.127l-1.12,0.022l-1.373,0.02l-1.289,-0.084l-1.139,-0.127l-1.225,-0.147l-1.141,-0.233l-1.12,-0.212l-1.268,-0.295l-1.098,-0.274l-1.162,-0.359l-1.305,-0.422l-1.289,-0.422l-1.33,-0.528l-1.078,-0.379l-1.289,-0.549l-1.12,-0.486l-1.035,-0.443l-0.784,-0.376l-1.289,-0.611l-0.824,-0.401l-0.353,-0.159l-0.277,-0.12l0.099,-0.368c0.448,-2.146,0.817,-4.307,1.108,-6.478z", "fill": "#111"}
+ ]
+}
\ No newline at end of file
diff --git a/public/res/symbol/h28.json b/public/res/symbol/h28.json
new file mode 100644
index 0000000..dfb568a
--- /dev/null
+++ b/public/res/symbol/h28.json
@@ -0,0 +1,9 @@
+{
+ "width": 40,
+ "height": 40,
+ "vectorSize": [525.738, 525.738],
+ "defs": [
+ {"path": "M82.778,364.78a33,33,0,0,0,66,0a33,33,0,0,0-66,0zM352.778,364.78a33,33,0,0,0,66,0a33,33,0,0,0-66,0zM56.651,145.327l-6.644,13.288c-0.782,1.564,-1.188,3.289,-1.188,5.038l0,17.85c0,1.749,0.406,3.474,1.188,5.038l6.963,13.926c1.909,3.817,5.809,6.228,10.077,6.228l39.387,0l-37.686,70.662l-35.89,16.452c-4.004,1.836,-6.571,5.836,-6.571,10.241l0,35.719c0,1.791,0.427,3.556,1.245,5.148l6.877,13.383c1.931,3.755,5.798,6.115,10.02,6.115l26.921,0c0,-16.098,8.589,-30.975,22.532,-39.025c13.942,-8.05,31.121,-8.05,45.063,0c13.943,8.05,22.532,22.927,22.532,39.025l180.253,0c0,-24.886,20.176,-45.062,45.063,-45.062c24.888,0,45.063,20.176,45.063,45.062l22.532,0l33.797,0c6.222,0,11.266,-5.043,11.266,-11.264l0,-180.561c0,-6.223,-5.044,-11.267,-11.266,-11.267l-168.082,0c-1.211,0,-2.414,-0.195,-3.562,-0.578l-63.203,-21.068c-1.149,-0.382,-2.352,-0.578,-3.563,-0.578l-183.047,0c-4.267,0,-8.168,2.411,-10.077,6.228z", "fill": "#111"},
+ {"path": "M109.538,222.263c1.177,-2.196,3.466,-3.567,5.958,-3.567l47.502,0c1.792,0,3.511,0.713,4.78,1.98c1.267,1.268,1.979,2.987,1.979,4.78l0,45.142l-89.743,6.759l29.524,-55.094zM93.52,193.377l76.607,0c3.733,0,6.759,-3.026,6.759,-6.76l0,-20.278c0,-3.733,-3.026,-6.76,-6.759,-6.76l-76.607,0c-3.734,0,-6.76,3.027,-6.76,6.76l0,20.278c0,3.734,3.026,6.76,6.76,6.76zM217.464,275.025l99.139,0c3.733,0,6.76,-3.026,6.76,-6.759l0,-54.076c0,-3.733,-3.027,-6.76,-6.76,-6.76l-99.139,0c-3.733,0,-6.76,3.027,-6.76,6.76l0,54.076c0,3.733,3.027,6.759,6.76,6.759zM401.833,275.025l54.077,0c3.732,0,6.759,-3.026,6.759,-6.759l0,-54.076c0,-3.733,-3.027,-6.76,-6.759,-6.76l-54.077,0c-3.734,0,-6.759,3.027,-6.759,6.76l0,54.076c0,3.733,3.025,6.759,6.759,6.759z", "fill": "#fff"}
+ ]
+}
\ No newline at end of file
diff --git a/public/res/symbol/h3.json b/public/res/symbol/h3.json
new file mode 100644
index 0000000..da7a2b2
--- /dev/null
+++ b/public/res/symbol/h3.json
@@ -0,0 +1,9 @@
+{
+ "width": 40,
+ "height": 40,
+ "vectorSize": [283.465, 283.465],
+ "defs": [
+ {"path": "M104.374,118.75l15.118,0l0,144.871l126.388,0l0,-219.968c0,-13.151,-10.66,-23.811,-23.81,-23.811l-78.767,0c-13.15,0,-23.811,10.66,-23.811,23.811l0,1.362l-21.883,0c-23.094,0,-43.309,15.511,-49.286,37.818l-27.036,100.901c-4.257,15.868,1.065,32.762,13.647,43.325c12.582,10.561,30.144,12.877,45.033,5.935c14.889,-6.94,24.407,-21.879,24.407,-38.306l0,-75.938z", "fill": "#111"},
+ {"path": "M42.277,189.366c-2.068,7.708,0.518,15.916,6.63,21.048c6.112,5.131,14.644,6.255,21.877,2.884c7.234,-3.372,11.858,-10.63,11.858,-18.61l0,-88.221l23.399,-22.205l13.451,0l0,-19.006l-22.209,0c-12.829,0,-24.06,8.617,-27.38,21.009l-27.626,103.101zM147.811,89.067l0,-44.052l68.176,0l0,44.052l-68.176,0z", "fill": "#fff"}
+ ]
+}
\ No newline at end of file
diff --git a/public/res/symbol/h4.json b/public/res/symbol/h4.json
new file mode 100644
index 0000000..0f69c6b
--- /dev/null
+++ b/public/res/symbol/h4.json
@@ -0,0 +1,27 @@
+{
+ "width": 40,
+ "height": 40,
+ "vectorSize": [283.465, 283.465],
+ "defs": [
+ {"path": "M195.636,94.625v-13.088h47.262v30.539h-26.54v121.006h47.262v-152.489c0,-9.116,-7.389,-16.507,-16.506,-16.507h-54.603c-9.117,0,-16.506,7.391,-16.506,16.507v0.944v13.088h19.631z", "fill": "#059"},
+ {"path": "M119.261,163.191h10.48v100.43h87.617v-152.489c0,-9.117,-7.39,-16.507,-16.505,-16.507h-54.604c-9.117,0,-16.508,7.39,-16.508,16.507v0.944h-15.17c-16.009,0,-30.021,10.753,-34.166,26.217l-18.742,69.948c-2.951,10.999,0.738,22.712,9.461,30.033c8.721,7.323,20.897,8.927,31.217,4.116c10.322,-4.812,16.92,-15.168,16.92,-26.556v-52.643z", "fill": "#111"},
+ {"path": "M148.374,112.076h47.262v30.539h-47.262zM75.214,212.145c-1.434,5.343,0.359,11.034,4.596,14.591c4.238,3.557,10.152,4.336,15.166,1.998c5.015,-2.336,8.22,-7.368,8.22,-12.9v-61.158l16.221,-15.393h9.324v-13.176h-15.394c-8.895,0,-16.68,5.974,-18.983,14.565l-19.15,71.473z", "fill": "#fff"},
+
+ {"path": "M159.232,33.137l7.336,-7.337c-4.697,-5.389,-11.527,-8.438,-18.673,-8.337c-6.348,-0.028,-12.409,2.639,-16.676,7.337c-5.197,6.022,-8.039,13.722,-8.004,21.677c-0.035,7.954,2.807,15.654,8.004,21.677c4.267,4.698,10.328,7.364,16.676,7.336c12.154,0.559,22.591,-8.557,23.675,-20.676l0,-10.672l-23.675,0l0,10.338l13.337,0c-0.783,5.789,-5.511,10.24,-11.337,10.672c-0.666,0.052,-1.334,0.052,-2,0c-3.612,0.052,-7.049,-1.544,-9.338,-4.336c-3.274,-4.058,-5.041,-9.125,-5.004,-14.339c-0.037,-5.215,1.73,-10.282,5.004,-14.341c2.289,-2.791,5.726,-4.386,9.338,-4.335c4.408,-0.106,8.609,1.871,11.337,5.336zM67.858,18.141l11.674,0l22.01,37.684l0,-37.684l10.338,0l0,56.693l-11.209,0l-22.473,-38.479l0,38.479l-10.34,0l0,-56.693zM56.692,23.527c-5.084,-4.314,-11.709,-6.363,-18.341,-5.67c-7.723,1.212,-14.475,5.876,-18.342,12.672c-2.547,4.944,-3.809,10.449,-3.668,16.008c-0.088,5.806,1.289,11.541,4.002,16.674c3.709,6.829,10.599,11.339,18.342,12.006c6.525,0.648,13.031,-1.401,18.007,-5.67l-6.728,-7.847c-2.854,2.447,-6.588,3.612,-10.326,3.222c-4.287,-0.346,-8.114,-2.825,-10.184,-6.596c-1.916,-3.648,-2.869,-7.724,-2.771,-11.843c-0.133,-3.818,0.699,-7.608,2.416,-11.02c2.279,-3.886,6.152,-6.573,10.59,-7.348c3.74,-0.321,7.453,0.865,10.316,3.294l6.687,-7.882z", "fill": "#111"},
+
+ {"path": "M139.561,33.137l7.337,-7.337c-4.698,-5.389,-11.528,-8.438,-18.676,-8.337c-6.347,-0.028,-12.407,2.639,-16.675,7.337c-5.197,6.022,-8.04,13.722,-8.003,21.677c-0.037,7.954,2.806,15.654,8.003,21.676c4.268,4.699,10.328,7.365,16.675,7.337c12.155,0.559,22.593,-8.557,23.678,-20.676l0,-10.672l-23.678,0l0,10.338l13.34,0c-0.785,5.789,-5.513,10.24,-11.339,10.672c-0.666,0.052,-1.335,0.052,-2.001,0c-3.61,0.052,-7.047,-1.544,-9.338,-4.336c-3.273,-4.058,-5.041,-9.125,-5.002,-14.339c-0.039,-5.215,1.729,-10.282,5.002,-14.341c2.291,-2.791,5.728,-4.386,9.338,-4.335c4.409,-0.106,8.61,1.871,11.339,5.336zM67.529,74.834l-10.339,0l0,-56.693l22.011,0c9.301,0,16.841,7.54,16.841,16.841c0,9.301,-7.54,16.841,-16.841,16.841l-11.672,0l0,23.011z", "fill": "#111"},
+ {"path": "M67.529,41.485l0,-13.006l11.672,0c3.591,0,6.503,2.912,6.503,6.503c0,3.592,-2.912,6.503,-6.503,6.503l-11.672,0z", "fill": "#fff"},
+ {"path": "M30.18,41.485l0,23.011l18.009,0l0,10.338l-28.347,0l0,-33.349l0,-23.344l10.338,0l0,23.344z", "fill": "#111"},
+
+ {"path": "M25.916,63.366l17.94,0l0,10.312l-28.252,0l0,-56.506l10.312,0l0,46.193zM61.584,17.173l11.654,0l21.895,37.576l0,-37.576l10.312,0l0,56.506l-11.053,0l-22.497,-38.467l0,38.467l-10.312,0l0,-56.506zM149.026,27.3l-0.494,0c-3.72,0,-6.757,1.437,-9.112,4.309c-3.344,4.144,-5.015,8.853,-5.015,14.126l0,0.353c0,5.274,1.671,9.983,5.015,14.126c2.354,2.873,5.392,4.309,9.112,4.309l0.212,0c0.328,0,0.658,0,0.989,0c0.282,0,0.61,0,0.989,0c2.871,-0.188,5.367,-1.282,7.486,-3.285c2.119,-2.001,3.391,-4.461,3.815,-7.381l-13.278,0l0,-10.242l23.591,0l0,10.595c-0.519,5.839,-2.943,10.736,-7.276,14.691c-4.332,3.955,-9.44,5.933,-15.326,5.933c-0.331,0,-0.66,0,-0.989,0c-6.65,0,-12.207,-2.448,-16.67,-7.346c-5.322,-6.121,-7.981,-13.255,-7.981,-21.401l0,-0.353c0,-8.098,2.66,-15.232,7.981,-21.401c4.463,-4.897,10.02,-7.346,16.67,-7.346l0.282,0c7.392,0,13.491,2.779,18.294,8.335l-7.276,7.275c-2.826,-3.532,-6.498,-5.297,-11.019,-5.297z", "fill": "#111"},
+
+ {"path": "M24.5,74.217l0,-56.506l10.312,0l0,21.26l20.907,0l0,-21.26l10.312,0l0,56.506l-10.312,0l0,-24.934l-20.907,0l0,24.934l-10.312,0zM104.446,82.529l0,5.707l-22.711,0c0,-0.21,0,-0.419,0,-0.63c0,-2.702,0.656,-5.222,1.968,-7.558c1.312,-2.335,3.122,-4.158,5.432,-5.471l7.754,-4.448c0.787,-0.472,1.338,-1.141,1.653,-2.007c0.183,-0.472,0.276,-0.97,0.276,-1.496c0,-0.498,-0.092,-0.983,-0.276,-1.456c-0.42,-1.207,-1.22,-2.02,-2.4,-2.441c-0.972,-0.262,-1.956,-0.394,-2.952,-0.394c-0.998,0,-1.982,0.132,-2.953,0.394c-0.84,0.289,-1.509,0.787,-2.007,1.496c-0.499,0.708,-0.747,1.496,-0.747,2.362c0,0.105,0,0.183,0,0.236l-5.747,0c0,-0.079,0,-0.197,0,-0.355c0,-2.047,0.597,-3.903,1.791,-5.569c1.194,-1.666,2.748,-2.84,4.664,-3.522c1.678,-0.498,3.397,-0.748,5.156,-0.748c1.522,0,3.004,0.197,4.448,0.591c2.938,1.023,4.972,2.991,6.1,5.903c0.394,1.129,0.59,2.297,0.59,3.503c0,1.208,-0.197,2.376,-0.59,3.503c-0.865,2.204,-2.282,3.871,-4.251,4.999l-7.754,4.409c-1.207,0.787,-2.191,1.785,-2.952,2.991l15.508,0z", "fill": "#111"}
+ ],
+ "core": [{"use": 0}, {"use": 1}, {"use": 2}],
+ "components": {
+ "cng": [{"use": 3}],
+ "lpg": [{"use": 4}, {"use": 5}, {"use": 6}],
+ "lng": [{"use": 7}],
+ "hydrogen": [{"use": 8}]
+ }
+}
\ No newline at end of file
diff --git a/public/res/symbol/h5.json b/public/res/symbol/h5.json
new file mode 100644
index 0000000..43cd3a1
--- /dev/null
+++ b/public/res/symbol/h5.json
@@ -0,0 +1,9 @@
+{
+ "width": 40,
+ "height": 40,
+ "vectorSize": [283.465, 283.465],
+ "defs": [
+ {"path": "M191.572,199.37c6.026,-9.719,10.71,-20.208,13.928,-31.18c26.248,-1.992,46.856,-23.307,47.961,-49.607l0,-43.937l-40.186,0l1.217,-27.874l-72.999,0l-73.944,0l4.023,92.126c1.09,21.43,7.591,42.235,18.897,60.472l-75.59,0c-2.096,0.779,-3.68,2.532,-4.245,4.695c-0.564,2.164,-0.038,4.467,1.409,6.171c17.51,17.277,40.653,27.674,65.197,29.291l64.252,0l64.251,0c24.545,-1.617,47.688,-12.014,65.197,-29.291c1.45,-1.704,1.975,-4.007,1.411,-6.171c-0.565,-2.163,-2.149,-3.916,-4.245,-4.695l-76.535,0z", "fill": "#111"},
+ {"path": "M209.335,150.236c14.549,-3.939,25.036,-16.622,26.173,-31.653l0,-25.984l-23.019,0l-2.021,46.299c-0.192,3.79,-0.555,7.568,-1.086,11.326c-0.002,0.01,-0.01,0.019,-0.02,0.022c-0.009,0.003,-0.021,-0.001,-0.027,-0.01z", "fill": "#fff"}
+ ]
+}
\ No newline at end of file
diff --git a/public/res/symbol/h6.json b/public/res/symbol/h6.json
new file mode 100644
index 0000000..af422d2
--- /dev/null
+++ b/public/res/symbol/h6.json
@@ -0,0 +1,8 @@
+{
+ "width": 40,
+ "height": 40,
+ "vectorSize": [283.465, 283.465],
+ "defs": [
+ {"path": "M247.559,218.338l-80.391,-74.367l-2.884,-2.668l25.718,-27.281c10.471,4.26,22.387,2.914,31.645,-3.572c1.365,-1.154,2.703,-2.338,4.014,-3.553l35.571,-35.102c3.028,-3.304,2.958,-8.395,-0.16,-11.614c-3.117,-3.219,-8.203,-3.451,-11.601,-0.53l-36.291,36.087c-0.313,0.271,-0.672,0.483,-1.061,0.626c-1.859,0.585,-3.888,-0.005,-5.144,-1.498c-1.256,-1.491,-1.493,-3.591,-0.6,-5.325c0.1,-0.177,0.22,-0.342,0.359,-0.49l36.651,-36.443c0.056,-0.065,0.107,-0.135,0.154,-0.209c2.045,-3.358,1.602,-7.667,-1.082,-10.541c-2.808,-2.645,-7.017,-3.142,-10.365,-1.225c-0.192,0.119,-0.372,0.257,-0.537,0.411l-36.094,36.001c-0.426,0.381,-0.902,0.7,-1.416,0.949c-1.772,0.629,-3.748,0.172,-5.065,-1.172c-1.317,-1.343,-1.734,-3.328,-1.07,-5.088c0.158,-0.32,0.362,-0.616,0.606,-0.878l36.177,-36.084c2.936,-3.386,2.724,-8.473,-0.482,-11.604c-3.206,-3.131,-8.297,-3.222,-11.611,-0.207l-35.85,36.029c-1.254,1.265,-2.404,2.629,-3.437,4.078c-6.131,9.147,-7.342,20.732,-3.234,30.948l-28.304,26.464l-16.861,-15.597c5.524,-15.051,0.533,-31.944,-12.283,-41.576c-15.544,-14.305,-34.4,-24.522,-54.872,-29.733c-0.725,-0.159,-1.46,-0.273,-2.199,-0.34c-4.069,-0.262,-8.139,0.483,-11.851,2.168c-0.912,0.427,-1.794,0.914,-2.64,1.46c-1.983,1.39,-3.645,3.189,-4.874,5.274c-2.232,4.136,-3.243,8.821,-2.917,13.509c0.049,0.674,0.152,1.344,0.309,2.002c5.247,20.507,15.519,39.384,29.89,54.927c9.661,12.794,26.564,17.746,41.603,12.188l14.931,16.067l-86.562,80.935c-0.943,1.118,-1.794,2.312,-2.542,3.569c-3.96,7.751,-2.263,17.191,4.149,23.076c6.075,6.673,15.952,8.265,23.816,3.84c1.02,-0.596,1.968,-1.309,2.823,-2.124l80.516,-85.408l2.986,3.214l73.674,79.276c0.617,0.59,1.27,1.141,1.955,1.647c8.063,5.019,18.571,3.472,24.844,-3.657c6.887,-6.088,8.562,-16.169,4.016,-24.156c-0.653,-0.944,-1.364,-1.847,-2.127,-2.703z", "fill": "#111"}
+ ]
+}
\ No newline at end of file
diff --git a/public/res/symbol/h7.json b/public/res/symbol/h7.json
new file mode 100644
index 0000000..136f36a
--- /dev/null
+++ b/public/res/symbol/h7.json
@@ -0,0 +1,9 @@
+{
+ "width": 40,
+ "height": 40,
+ "vectorSize": [283.465, 283.465],
+ "defs": [
+ {"path": "M268.347,198.638c0.002,-1.887,-0.146,-3.771,-0.444,-5.634c-11.218,-40.291,-45.112,-70.196,-86.486,-76.311c-6.219,-7.126,-13.561,-13.19,-21.732,-17.952l0,-67.56c-0.26,-8.945,-7.586,-16.062,-16.536,-16.062c-8.949,0,-16.276,7.117,-16.535,16.062l0,21.733l-75.591,0l0,-21.733c-0.259,-8.945,-7.586,-16.062,-16.535,-16.062c-8.95,0,-16.276,7.117,-16.536,16.062l0,159.685c1.262,8.156,8.283,14.173,16.536,14.173c8.253,0,15.273,-6.017,16.535,-14.173l0,-33.543l61.417,51.535l0,42.481c0.768,8.56,7.942,15.118,16.536,15.118c8.594,0,15.767,-6.558,16.535,-15.118l0,-41.575l89.763,0l0,41.575c0.769,8.56,7.942,15.118,16.537,15.118c8.593,0,15.766,-6.558,16.536,-15.118l0,-52.824l0,0.123z", "fill": "#111"},
+ {"path": "M79.842,125.671c29.482,-16.632,64.511,-20.39,96.85,-10.394c-34.093,-32.181,-85.409,-37.811,-125.669,-13.788l28.819,24.182z", "fill": "#fff"}
+ ]
+}
\ No newline at end of file
diff --git a/public/res/symbol/h8.json b/public/res/symbol/h8.json
new file mode 100644
index 0000000..990d13a
--- /dev/null
+++ b/public/res/symbol/h8.json
@@ -0,0 +1,9 @@
+{
+ "width": 40,
+ "height": 40,
+ "vectorSize": [283.465, 283.465],
+ "defs": [
+ {"path": "M49.133,137.008c-2.016,24.12,-14.877,46.019,-34.96,59.527c13.189,3.566,27.248,1.873,39.212,-4.723l0,34.488l-40.157,0l0,21.731l254.173,0l0.473,0l0,-21.731l-0.473,0l-10.866,0l0,-108.189l18.897,0l-89.054,-92.22l-89.055,92.22l18.897,0l0,108.189l-48.662,0l0,-34.488c12.846,6.501,27.598,8.176,41.575,4.723c-21.203,-12.488,-34.564,-34.935,-35.433,-59.527c8.202,7.117,18.467,11.422,29.292,12.283c-23.51,-22.127,-38.268,-51.978,-41.575,-84.094c-4.059,31.698,-18.321,61.215,-40.63,84.094c10.479,-1.114,20.368,-5.4,28.346,-12.283z", "fill": "#111"},
+ {"path": "M167.715,170.079l0,56.221l37.796,0l0,-56.221l-37.796,0z", "fill": "#fff"}
+ ]
+}
\ No newline at end of file
diff --git a/public/res/symbol/h9.json b/public/res/symbol/h9.json
new file mode 100644
index 0000000..82d0d29
--- /dev/null
+++ b/public/res/symbol/h9.json
@@ -0,0 +1,9 @@
+{
+ "width": 40,
+ "height": 40,
+ "vectorSize": [283.465, 283.465],
+ "defs": [
+ {"path": "M151.304,57.05l58.225,-40.77l58.226,40.77l-7.754,11.074l-10.314,-7.222l0,41.015l-40.158,0l-40.157,0l0,-41.015l-10.314,7.222l-7.754,-11.074zM5.775,96.785l78.904,-55.249l78.903,55.249l-10.508,15.007l-13.976,-9.786l0,55.582l-54.419,0l-54.419,0l0,-55.582l-13.977,9.786l-10.508,-15.007zM89.656,194.744l94.017,-65.831l94.016,65.831l-12.52,17.881l-16.654,-11.66l0,66.228l-64.842,0l-64.843,0l0,-66.228l-16.654,11.66l-12.52,-17.881z", "fill": "#111"},
+ {"path": "M192.633,74.268l0,-13.166l33.795,0l0,13.166l-33.795,0zM61.78,120.119l0,-17.842l45.796,0l0,17.842l-45.796,0zM156.391,222.547l0,-21.26l54.566,0l0,21.26l-54.566,0z", "fill": "#fff"}
+ ]
+}
\ No newline at end of file
diff --git a/public/res/water.json b/public/res/water.json
new file mode 100644
index 0000000..ec35bd3
--- /dev/null
+++ b/public/res/water.json
@@ -0,0 +1,8 @@
+{
+ "width": 209,
+ "height": 19,
+ "vectorSize": [11, 1],
+ "defs": [
+ {"path": "M.5,.67a1.093,1.093,0,0,0,1,-.657a1.093,1.093,0,0,0,2,0a1.093,1.093,0,0,0,2,0a1.093,1.093,0,0,0,2,0a1.093,1.093,0,0,0,2,0a1.093,1.093,0,0,0,1,.657v.234a1.327,1.327,0,0,1,-1,-.46a1.327,1.327,0,0,1,-2,0a1.327,1.327,0,0,1,-2,0a1.327,1.327,0,0,1,-2,0a1.327,1.327,0,0,1,-2,0a1.327,1.327,0,0,1,-1,.46z", "fill": "currentColor"}
+ ]
+}
\ No newline at end of file
diff --git a/templates.json b/public/templates.json
similarity index 100%
rename from templates.json
rename to public/templates.json
diff --git a/render.html b/render.html
deleted file mode 100644
index b292035..0000000
--- a/render.html
+++ /dev/null
@@ -1,42 +0,0 @@
-
-
-
- Skyltprogram (rendering)
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/render.js b/render.js
deleted file mode 100644
index 1f638a4..0000000
--- a/render.js
+++ /dev/null
@@ -1,662 +0,0 @@
-(async function(){
-
-const CONFIG = JSON.parse(await getText("config.json"));
-
-// Priority:
-// 1. Specified value
-// 2. Value from parent (if property is inherited) or DEFAULTS (if root)
-// 3. Default value (from DEFAULT_PROPERTIES)
-// 4. Global defaults (GLOBAL_DEFAULTS)
-
-//const INHERITED = CONFIG.properties.inherit; // properties that can be inherited
-const GLOBAL_DEFAULTS = CONFIG.properties.globalDefaults;
-const DEFAULTS = CONFIG.properties.rootDefaults;
-const DEFAULT_PROPERTIES = CONFIG.properties.defaults;
-
-const SKYLTTYPER = CONFIG.signTypes;
-const SYMBOLER = CONFIG.symbols;
-
-// Samtliga designer sparas i "nedre kant"-form, dvs.
-// i en orientering motsvarande klammern i skylt
-// F9 (samlingsmärke för vägvisning).
-const BORDER_FEATURES = CONFIG.borderFeatures;
-
-const TEMPLATES = {
- "avfart": (no = "1") => ({
- "type": "skylt",
- "properties": {
- "padding": 0,
- "background": "#aaa",
- "color": "black"
- },
- "elements": [
- {
- "type": "skylt",
- "properties": {
- "background": "#fd0",
- "borderWidth": 4,
- "borderRadius": 22,
- "padding": [5, 0]
- },
- "elements": [
- {
- "type": "symbol",
- "properties": { "type": "exit" }
- },
- {
- "type": "text",
- "properties": {
- "value": no
- }
- }
- ]
- }
- ]
- }),
- "vagnr": (no = "000") => ({
- "type": "vagnr",
- "properties": {
- "value": no
- }
- }),
- "symgroup": (...s) => ({
- "type": "skylt",
- "properties": {"padding": 0, "xSpacing": 0, "borderWidth": [3, 0, 0, 0], "borderRadius": 0, "color": "black", "background": "white"},
- "elements": s.map(x => ({"type": "symbol", "properties": {"type": Array.isArray(x) ? x[0] : x, "variant": Array.isArray(x) ? x[1] : undefined , "borderWidth": [0, 3, 3, 3], "padding": 1}}))
- })
-};
-
-function to4EForm(data){
- if(!Array.isArray(data)) data = [ data, data ];
- if(data.length != 4) data = [ data[0], data[1], data[0], data[1] ];
- return data;
-}
-
-class BorderElement{
- constructor(featureName, bw, brA, brB, sideLength){
- let w0 = BORDER_FEATURES[featureName].w,
- h0 = BORDER_FEATURES[featureName].h,
- cvr = !!BORDER_FEATURES[featureName].cover;
-
- if(cvr) w0 = sideLength - bw;
-
- this.env = BorderElement.calculateEnv(featureName, bw, brA, brB, w0);
-
- if(cvr) h0 = mathEval(h0, this.env);
-
- this.env["h"] = h0;
-
- this.w = w0 + bw;
- this.h = h0 + bw;
- this.n = featureName;
- }
-
- static calculateEnv(featureName, bw, brA, brB, w0){
- let env = {bra: brA, brb: brB, bw: bw, w: w0};
-
- let feature = BORDER_FEATURES[featureName];
- if(!Array.isArray(feature.vars)) return env;
-
- for(let i = 0; i < feature.vars.length; i++){
- env[feature.vars[i][0]] = mathEval(feature.vars[i][1], env);
- }
-
- return env;
- }
-}
-
-class BorderDimensions{
- constructor(heights){
- this.h = [0, 0, 0, 0].map((_, i) => heights[i]);
- this.el = [null, null, null, null];
- }
-
- set(i, el){
- this.el[i] = el;
- this.h[i] = Math.floor(el.h);
- }
-}
-
-class SignElement{
- static borderSize(innerWidth, innerHeight, properties){
- let bs = new BorderDimensions(properties.borderWidth);
-
- if(properties.borderFeatures["left"] !== undefined)
- bs.set(0, new BorderElement(properties.borderFeatures["left"], properties.borderWidth[0], properties.borderRadius[0], properties.borderRadius[3], innerHeight + properties.borderWidth[1] + properties.borderWidth[3]));
-
- if(properties.borderFeatures["right"] !== undefined)
- bs.set(2, new BorderElement(properties.borderFeatures["right"], properties.borderWidth[2], properties.borderRadius[2], properties.borderRadius[1], innerHeight + properties.borderWidth[1] + properties.borderWidth[3]));
-
- if(properties.borderFeatures["top"] !== undefined)
- bs.set(1, new BorderElement(properties.borderFeatures["top"], properties.borderWidth[1], properties.borderRadius[1], properties.borderRadius[0], innerWidth + properties.borderWidth[0] + properties.borderWidth[2]));
-
- if(properties.borderFeatures["bottom"] !== undefined)
- bs.set(3, new BorderElement(properties.borderFeatures["bottom"], properties.borderWidth[3], properties.borderRadius[3], properties.borderRadius[2], innerWidth + properties.borderWidth[0] + properties.borderWidth[2]));
-
- return bs;
- }
-
- static calculateAlignmentOffset(alignMode, innerWidth, outerWidth){
- switch(alignMode){
- case "center":
- return Math.floor((outerWidth - innerWidth) / 2);
- case "right":
- return outerWidth - innerWidth;
- default:
- // "left" or unknown value (left-aligned is the default)
- return 0;
- }
- }
-
- static renderBorderFeature(ctx, x0, y0, featureName, side, properties, bs, borderBoxInnerW, innerHeight){
- let color = properties.color,
- background = properties.background;
-
- let lr = (side === "left" || side === "right");
- let bri = lr ? (side === "left" ? 0 : 2) : (side === "top" ? 1 : 3);
-
- let bw = properties.borderWidth[bri];
- let s = [bs.el[bri].w, bs.el[bri].h];
-
- let feature = BORDER_FEATURES[featureName];
-
- let w = lr ? s[1] : s[0],
- h = lr ? s[0] : s[1];
-
- switch(side){
- case "bottom":
- y0 += innerHeight + bs.h[1];
- case "top":
- x0 += bs.h[0] + Math.floor((borderBoxInnerW - w) / 2);
- break;
- case "right":
- x0 += borderBoxInnerW + bs.h[0];
- default:
- y0 += bs.h[1] + Math.floor((innerHeight - h) / 2);
- break;
- }
-
- // left: cos 0 sin -1
- // top: cos -1 sin 0
- // right: cos 0 sin 1
- // bottom: cos 1 sin 0
-
- let sr = lr ? (side === "left" ? 1 : (-1)) : 0, cr = lr ? 0 : (side === "top" ? (-1) : 1);
- let [a, b] = [(s[0] - bw) / 2, (s[1] - bw) / 2];
-
- let tm = new DOMMatrix().translateSelf(x0 + w / 2, y0 + h / 2).multiplySelf(new DOMMatrix([
- cr, sr, -sr, cr, -a*cr + b*sr, -a*sr - b*cr
- ]));
-
- //ctx.fillStyle="#000";
- //ctx.fillRect(x0, y0, w, h);
-
- ctx.fillStyle = background;
- ctx.fillRect(x0 + (side === "left" ? (s[1] - bw) : 0) + (lr ? 0 : (bw/2)), y0 + (side === "top" ? (s[1] - bw) : 0) + (lr ? (bw/2) : 0), lr ? bw : (s[0] - bw), lr ? (s[0] - bw) : bw);
-
- ctx.lineWidth = bw;
-
- feature.paths.forEach(path => {
- let p = new Path2D();
- p.addPath(new Path2D(parseVarStr(path.p, bs.el[bri].env)), tm);
-
- if(path.f !== undefined){
- ctx.fillStyle = [color, background][Math.abs(path.f)-1];
- if(path.f > 0 || properties.fillCorners) ctx.fill(p);
- }
-
- if(path.s !== undefined){
- ctx.strokeStyle = [color, background][Math.abs(path.s)-1];
- if(path.s > 0 || properties.fillCorners) ctx.stroke(p);
- }
- });
- }
-
- constructor(data, parentProperties){
- while(data.type.startsWith("#")){
- let templateName = data.type.slice(1);
- if(!TEMPLATES[templateName]){
- alert("ERROR: Unknown template \"" + templateName + "\".")
- break;
- }
-
- let template = TEMPLATES[templateName](...(data.params || []));
- Object.assign(template.properties, data.properties);
- data = template;
- }
-
- this.type = data.type;
-
- let prop = Object.assign(
- {},
- GLOBAL_DEFAULTS,
- DEFAULT_PROPERTIES[data.type.startsWith(".") ? "." : data.type],
- parentProperties === null ? DEFAULTS : parentProperties,
- data.properties
- );
-
- this.properties = Object.assign(prop, {
- padding: to4EForm(prop.padding),
- borderRadius: to4EForm(prop.borderRadius),
- borderWidth: to4EForm(prop.borderWidth)
- });
-
- let inh = this._getInhProperties();
-
- this.children = (data.elements || []).map(element => new SignElement(element, inh));
-
- this.nodes = (data.nodes || {});
- Object.keys(this.nodes).forEach(key => this.nodes[key].signelement = new SignElement(this.nodes[key].data, inh));
- }
-
- _getInhProperties(){
- const { background, borderRadius, color, font, lineHeight, lineSpacing } = this.properties;
- return { background, borderRadius, color, font, lineHeight, lineSpacing };
- }
-
- render(){
- let firstLastCenter = null; // [cx_first, cy_firstrow, cx_last, cy_lastrow]
-
- let padding = Array.from(this.properties.padding);
-
- let width = 0, height = 0, maxHeight = 0;
- let renderPromise = (ctx, x0, y0, _) => Promise.resolve();
-
- if(this.type == "skylt"){
- let w = [0], h = [0], j = 0;
-
- let totalLineSpacing = 0;
-
- let ch = this.children.map((c, i) => {
- let c2 = { isn: c.type == "newline" };
-
- if(c2.isn || (i > 0 && this.properties.blockDisplay)){
- j++;
- w.push(0);
- h.push(0);
- totalLineSpacing += (this.properties.blockDisplay ? this.properties.lineSpacing : c.properties.lineSpacing);
- }
-
- c2.r = c.render();
- c2.row = j;
- c2.bs = c2.r.bs;
-
- if(!c2.isn){
- if(w[j] > 0){
- w[j] += this.properties.xSpacing;
- }
-
- c2.x = w[j];
- w[j] += c2.r.w + c2.bs[0] + c2.bs[2];
-
- let h0 = c2.r.h + c2.bs[1] + c2.bs[3];
- if(h0 > h[j]) h[j] = h0;
- }
-
- return c2;
- });
-
- width = Math.max(...w);
- height = h.reduce((a, b) => a + b, totalLineSpacing);
-
- ch = ch.map(c2 => {
- if(!c2.isn && !this.properties.blockDisplay){
- c2.x += SignElement.calculateAlignmentOffset(this.properties.alignContents, w[c2.row], width);
- }
-
- return c2;
- });
-
- // mitt-x (element), se även if-sats nedan
- // mitt-y (rad), se även if-sats nedan
- firstLastCenter = [
- padding[0] + ch[0].x + ch[0].bs[0],
- padding[1],
- padding[0] + ch[ch.length - 1].x + ch[ch.length - 1].bs[0],
- height + padding[1]
- ];
-
- if(this.properties.passAnchor){
- firstLastCenter[0] += ch[0].r.flc[0];
- firstLastCenter[1] += ch[0].bs[1] + ch[0].r.flc[1];
- firstLastCenter[2] += ch[ch.length - 1].r.flc[2];
- firstLastCenter[3] += ch[ch.length - 1].bs[1] - h[h.length - 1] + ch[ch.length - 1].r.flc[3];
- }else{
- firstLastCenter[0] += Math.floor(ch[0].r.w / 2);
- firstLastCenter[1] += Math.floor(h[0] / 2);
- firstLastCenter[2] += Math.floor(ch[ch.length - 1].r.w / 2);
- firstLastCenter[3] += Math.floor(-h[h.length - 1] / 2);
- }
-
- let y = 0;
-
- renderPromise = (ctx, x0, y0, _) => Promise.all(ch.map((c2, i) => {
- if(c2.isn || (i > 0 && this.properties.blockDisplay)){
- y += (this.properties.blockDisplay ? this.properties.lineSpacing : this.children[i].properties.lineSpacing);
- y += h[c2.row - 1];
- }
-
- if(c2.isn) return;
-
- let dx = 0, iw = this.properties.blockDisplay ? (width - c2.bs[0] - c2.bs[2]) : c2.r.w;
-
- if(this.properties.blockDisplay){
- dx += SignElement.calculateAlignmentOffset(this.children[i].properties.alignContents, w[c2.row], iw + c2.bs[0] + c2.bs[2]);
- }
-
- return c2.r.doRender(
- ctx,
- x0 + padding[0] + c2.x, y0 + padding[1] + y,
- dx,
- this.children[i].properties,
- this.properties,
- h[c2.row] - c2.bs[1] - c2.bs[3],
- iw
- );
- }));
- }else if(this.type == "vagnr" || this.type == "text"){
- let ctx_temp = document.createElement("canvas").getContext("2d");
- ctx_temp.font = "32px " + this.properties.font;
-
- let box = ctx_temp.measureText(this.properties.value);
-
- width = Math.floor(box.width);
- height = this.properties.lineHeight;
-
- renderPromise = (ctx, x0, y0, _) => new Promise(res => {
- if(this.properties.dashedInset){
- let bw = this.properties.borderWidth;
-
- roundedFrame(
- ctx,
- x0 + 2*bw[0], y0 + 2*bw[1],
- width + padding[0] + padding[2] - 2*bw[0] - 2*bw[2], height + padding[1] + padding[3] - 2*bw[1] - 2*bw[3],
- bw,
- this.properties.color,
- this.properties.borderRadius,
- [10, 10]
- );
- }
-
- ctx.font = "32px " + this.properties.font;
- ctx.textBaseline = "middle";
- ctx.textAlign = "left";
-
- ctx.fillStyle = this.properties.color;
- ctx.fillText(this.properties.value, x0 + padding[0], y0 + firstLastCenter[1]);
-
- res();
- });
- }else if(this.type == "symbol"){
- let symbolType = SYMBOLER[this.properties.type];
- let img = document.createElement("img");
-
- width = img.width = symbolType.width;
- height = symbolType.height[0];
- img.height = maxHeight = symbolType.height[1];
-
- renderPromise = (ctx, x0, y0, maxInnerHeight) => new Promise((res, rej) => {
- img.addEventListener("load", () => {
- ctx.drawImage(
- img,
- 0, 0,
- img.width, maxInnerHeight - padding[1] - padding[3],
- x0 + padding[0], y0 + padding[1],
- img.width, maxInnerHeight - padding[1] - padding[3]
- );
- res();
- });
- img.addEventListener("error", rej);
-
- let url = "svg/symbol/" + window.encodeURIComponent(this.properties.type) + ".svg";
-
- getText(url).then(xml => {
- img.src = "data:image/svg+xml;utf8,"
- + window.encodeURIComponent(String(xml).replace(/currentColor/g, this.properties.color))
- + "#" + window.encodeURIComponent(this.properties.variant || symbolType.default);
- });
- });
- }else if(this.type == "newline"){
- width = 0;
- height = 0;
- }else if(this.type.startsWith(".")){
- let t = SKYLTTYPER[this.type.slice(1)];
- let keys = Object.keys(t.nodes).sort().filter(nodeName => !!this.nodes[nodeName]);
-
- let svg = document.createElement("img");
- svg.width = t.width;
- svg.height = t.height;
-
- let svgBox = Array.from(t.core);
- keys.forEach(nodeName => {
- svgBox[0] = Math.min(svgBox[0], t.nodes[nodeName].x[0]);
- svgBox[1] = Math.max(svgBox[1], t.nodes[nodeName].x[1]);
- svgBox[2] = Math.min(svgBox[2], t.nodes[nodeName].y[0]);
- svgBox[3] = Math.max(svgBox[3], t.nodes[nodeName].y[1]);
- });
-
- let boundingBox = [
- svgBox[0] * t.width,
- svgBox[1] * t.width,
- svgBox[2] * t.height,
- svgBox[3] * t.height
- ].map(Math.floor);
-
- // fonts and svg loaded successfully
- let r = keys.map(nodeName => {
- let n = this.nodes[nodeName];
- let s = n.signelement;
-
- let tn = t.nodes[nodeName];
-
- n.anchor = Object.assign({ "x": tn.ax, "y": tn.ay }, n.anchor);
-
- let result = s.render();
- let bs = result.bs;
-
- let rse = [ result.w + bs[0] + bs[2], result.h + bs[1] + bs[3] ];
-
- let leftX = tn.x.map(x => x * t.width).map(Math.floor), topY = tn.y.map(y => y * t.height).map(Math.floor);
-
- switch(n.anchor.x){
- case "right":
- leftX = leftX[1] - rse[0];
- break;
- case "center":
- leftX = Math.floor((leftX[0] + leftX[1]) / 2 - Math.floor(rse[0] / 2));
- break;
- case "center-first":
- leftX = Math.floor((leftX[0] + leftX[1]) / 2) - result.flc[0];
- break;
- case "center-last":
- leftX = Math.floor((leftX[0] + leftX[1]) / 2) - result.flc[2];
- break;
- default:
- leftX = leftX[0];
- }
-
- switch(n.anchor.y){
- case "bottom":
- topY = topY[1] - rse[1];
- break;
- case "middle":
- topY = Math.floor((topY[0] + topY[1]) / 2) - Math.floor(rse[1] / 2);
- break;
- case "middle-first":
- topY = Math.floor((topY[0] + topY[1]) / 2) - result.flc[1] - bs[1];
- break;
- case "middle-last":
- topY = Math.floor((topY[0] + topY[1]) / 2) - result.flc[3] - bs[1];
- break;
- default:
- topY = topY[0];
- }
-
- boundingBox = [
- Math.min(boundingBox[0], leftX),
- Math.max(boundingBox[1], leftX + rse[0]),
- Math.min(boundingBox[2], topY),
- Math.max(boundingBox[3], topY + rse[1])
- ];
-
- return { renderPromise: result, x: leftX, y: topY, p: s.properties };
- });
-
- width = boundingBox[1] - boundingBox[0];
- height = boundingBox[3] - boundingBox[2];
-
- renderPromise = (ctx, x0, y0, _) => Promise.all(r.map(res => {
- let x1 = res.x - boundingBox[0],
- y1 = res.y - boundingBox[2];
-
- let dx = 0;
-
- return res.renderPromise.doRender(ctx, x0 + padding[0] + x1, y0 + padding[1] + y1, dx, res.p, this.properties, res.renderPromise.h);
- })).then(() => {
- if(t.width == 0 || t.height == 0) return;
-
- svgBox[0] = Math.min(1, Math.max(0, boundingBox[0] / t.width));
- svgBox[1] = Math.max(0, Math.min(1, boundingBox[1] / t.width));
- svgBox[2] = Math.min(1, Math.max(0, boundingBox[2] / t.height));
- svgBox[3] = Math.max(0, Math.min(1, boundingBox[3] / t.height));
-
- let crop = [
- svgBox[0] * t.width,
- svgBox[2] * t.height,
- (svgBox[1] - svgBox[0]) * t.width,
- (svgBox[3] - svgBox[2]) * t.height
- ]; // [x0, y0, w, h]
-
- return new Promise((resolve, reject) => {
- svg.onload = resolve;
- svg.onerror = reject;
- svg.src = "svg/" + this.type.slice(1) + ".svg#" + keys.join("_");
- }).then(() => {
- let svgRasterized = document.createElement("canvas");
- Object.assign(svgRasterized, { width: t.width, height: t.height });
- svgRasterized.getContext("2d").drawImage(svg, 0, 0, t.width, t.height);
-
- ctx.drawImage(
- svgRasterized,
- crop[0], crop[1], // sx, sy
- crop[2], crop[3], // sw, sh
- x0 + this.properties.padding[0] - boundingBox[0] + crop[0], // dx
- y0 + this.properties.padding[1] - boundingBox[2] + crop[1], // dy
- crop[2], crop[3] // dw, dh
- );
-
- return;
- });
- });
- }else{
- alert("Fel!");
- }
-
- let bs = SignElement.borderSize(width + padding[0] + padding[2], height + padding[1] + padding[3], this.properties);
-
- if(firstLastCenter === null){
- firstLastCenter = [
- Math.floor((width + padding[0] + padding[2]) / 2),
- Math.floor((height + padding[1] + padding[3]) / 2)
- ];
- firstLastCenter.push(...firstLastCenter);
- }
-
- if(maxHeight < height) maxHeight = height;
-
- return {
- flc: firstLastCenter,
- w: width + padding[0] + padding[2],
- h: height + padding[1] + padding[3],
- bs: bs.h,
- doRender: async (ctx, x0, y0, dx, prop, parentProperties = {}, maxInnerHeight, iw = 0) => {
- const dy = 0;
- const innerWidth = iw === 0 ? (width + padding[0] + padding[2]) : iw;
- let innerHeight = height + padding[1] + padding[3];
-
- if(this.properties.grow && innerHeight < maxInnerHeight){
- innerHeight = Math.min(maxInnerHeight, padding[1] + padding[3] + maxHeight);
- }
-
- switch (parentProperties.alignContentsV) {
- case "middle":
- y0 += Math.floor((maxInnerHeight - innerHeight) / 2);
- break;
- case "bottom":
- y0 += maxInnerHeight - innerHeight;
- break;
- }
-
- // tag bort rundade hörn på sidor med hela kantutsmyckningar
- let bfs = ["left", "top", "right", "bottom"].map(s => {
- let bf = prop.borderFeatures[s];
- return bf !== undefined && BORDER_FEATURES[bf].cover; // cover => hel, täcker hela kantens längd
- });
-
- let br = Array.from(prop.borderRadius);
-
- for(let i = 0; i < 4; i++){
- if(bfs[i] || bfs[(i + 1) % 4]) br[i] = 0;
- }
-
- roundedFill(
- ctx,
- x0 + bs.h[0], y0 + bs.h[1],
- innerWidth, innerHeight,
- prop.borderWidth.map((x, i) => bfs[i] ? 0 : x),
- br,
- prop.background,
- !!prop.fillCorners
- );
-
- await renderPromise(ctx, x0 + dx + bs.h[0], y0 + dy + bs.h[1], innerHeight);
-
- roundedFrame(
- ctx,
- x0 + bs.h[0], y0 + bs.h[1],
- innerWidth, innerHeight,
- prop.borderWidth.map((x, i) => bfs[i] ? 0 : x),
- prop.color,
- br
- );
-
- Object.entries(prop.borderFeatures).forEach(feature => {
- SignElement.renderBorderFeature(ctx, x0, y0, feature[1], feature[0], prop, bs, innerWidth, innerHeight);
- });
- }
- };
- }
-}
-
-const canvas = document.getElementsByTagName("canvas")[0];
-const ctx = canvas.getContext("2d");
-
-const tratex = new FontFace(
- "Tratex",
- "url(TratexSvart-Regular.otf)",
-);
-
-const tratexVersal = new FontFace(
- "TratexVersal",
- "url(TRATEXPOSVERSAL-POSVERSAL.otf)",
-);
-
-document.fonts.add(tratex);
-document.fonts.add(tratexVersal);
-
-Promise.all([tratex.load(), tratexVersal.load()]).then(() => {
- let url = new URL(window.location.href);
- if(!url.searchParams.has("data")) return;
-
- let data = JSON.parse(url.searchParams.get("data"));
-
- let sign = new SignElement(data, null);
- let r = sign.render();
-
- let bs = r.bs;
- Object.assign(canvas, { width: r.w + bs[0] + bs[2], height: r.h + bs[1] + bs[3] });
-
- r.doRender(ctx, 0, 0, 0, sign.properties, {}, r.h);
-});
-
-})();
\ No newline at end of file
diff --git a/src/config.ts b/src/config.ts
new file mode 100644
index 0000000..38d79d9
--- /dev/null
+++ b/src/config.ts
@@ -0,0 +1,133 @@
+export default {
+ "signTypes": {
+ "junction": {
+ "width": 120,
+ "height": 240,
+ "core": [0.4, 0.6, 0.15, 0.44],
+ "nodes": {
+ "fwd": { "x": [0.2, 0.8], "y": [0, 0], "ay": "bottom" },
+ "right": { "x": [1, 1], "y": [0.27, 0.27], "ax": "left" },
+ "left": { "x": [0, 0], "y": [0.27, 0.27], "ax": "right" },
+ "lright": { "x": [1, 1], "y": [0.434, 0.434], "ax": "left" }
+ }
+ },
+ "roundabout": {
+ "width": 240,
+ "height": 480,
+ "core": [0.35, 0.75, 0.09, 0.35],
+ "nodes": {
+ "fwd": { "x": [0.5, 0.5], "y": [0.03, 0.03], "ay": "bottom" },
+ "right": { "x": [0.9, 0.9], "y": [0.21, 0.21], "ax": "left" },
+ "left": { "x": [0.1, 0.1], "y": [0.21, 0.21], "ax": "right" }
+ }
+ },
+ "water": {
+ "width": 209,
+ "height": 19,
+ "core": [0, 1, 0, 1],
+ "nodes": {
+ "name": { "x": [0.5, 0.5], "y": [-0.1, -0.1], "ax": "center", "ay": "bottom" }
+ }
+ },
+ "spanish": {
+ "width": 200,
+ "height": 360,
+ "core": [0.12, 0.78, 0, 0.65],
+ "nodes": {
+ "fwd": { "x": [0.08, 0.72], "y": [0, 0], "ay": "bottom" },
+ "left": { "x": [0, 0], "y": [0.22, 0.22], "ax": "right" },
+ "right": { "x": [1, 1], "y": [0.22, 0.22], "ax": "left" }
+ }
+ }
+ },
+ "symbols": {
+ "arrow-small": { "width": 48, "height": [48, 192], "default": "left" },
+ "exit": { "width": 46, "height": [26, 26] },
+ "h1": { "width": 40, "height": [40, 40] },
+ "h2": { "width": 40, "height": [40, 40] },
+ "h3": { "width": 40, "height": [40, 40] },
+ "h4": { "width": 40, "height": [40, 40], "default": "cng" },
+ "h5": { "width": 40, "height": [40, 40] },
+ "h6": { "width": 40, "height": [40, 40] },
+ "h7": { "width": 40, "height": [40, 40] },
+ "h8": { "width": 40, "height": [40, 40] },
+ "h9": { "width": 40, "height": [40, 40] },
+ "h10": { "width": 40, "height": [40, 40] },
+ "h11": { "width": 40, "height": [40, 40] },
+ "h12": { "width": 40, "height": [40, 40] },
+ "h13": { "width": 40, "height": [40, 40] },
+ "h14": { "width": 40, "height": [40, 40] },
+ "h15": { "width": 40, "height": [40, 40] },
+ "h16": { "width": 40, "height": [40, 40] },
+ "h17": { "width": 40, "height": [40, 40] },
+ "h18": { "width": 40, "height": [40, 40] },
+ "h19": { "width": 40, "height": [40, 40] },
+ "h20": { "width": 40, "height": [40, 40] },
+ "h21": { "width": 40, "height": [40, 40] },
+ "h22": { "width": 40, "height": [40, 40] },
+ "h24": { "width": 40, "height": [40, 40] },
+ "h25": { "width": 40, "height": [40, 40] },
+ "h26": { "width": 40, "height": [40, 40] },
+ "h27": { "width": 40, "height": [40, 40] },
+ "h28": { "width": 40, "height": [40, 40] }
+ },
+ "borderFeatures": {
+ "bracket": { "paths": [{ "p": "M-${bw/2},0H0L22,27L44,0H${bw/2+w}", "s": 1, "f": 2 }], "w": 44, "h": 27, "cover": false },
+ "arrow": { "paths": [{ "p": "M0,0V${h}H${w}V0z", "f": -2, "s": -2 }, { "p": "M0,0L${w/2},${h*17/27}L${w},0z", "f": 2 }, { "p": "M0,-${bw/2}V0L${w/2},${h*17/27}L${w},0V-${bw/2}V0L${w/2},${h*25/27}L0,0z", "s": 1, "f": 1 }], "w": 0, "h": "w*27/44", "cover": true },
+ "diag": {
+ "vars": [["k", "35/60"], ["x1", "1-(k/sqrt((k*k+1)))*bra"], ["xr", "1-(k/sqrt((k*k+1)))*brb"], ["a", "-2*brb+w+xr-x1*k+sqrt((2*bra-x1*x1))-sqrt((2*brb-xr*xr))"], ["margin", "30"]],
+ "paths": [
+ { "p": "M0,0V${-k*x1+sqrt((2*bra-x1*x1))+margin}L${w},${-sqrt((k*k+1))-k+1*bw/2+h}V0z", "f": -2, "s": -2 },
+ { "p": "M0,-${bw/2}V${margin}A${bra},${bra},0,0,0,${x1},${sqrt((2*bra-x1*x1))+margin}L${-2*brb+w+xr},${a+sqrt((2*brb-xr*xr))+margin}A${brb},${brb},0,0,0,${w},${a+margin}V-${bw/2}", "s": 1, "f": 2 },
+ { "p": "M${w/2-43},0m5,0l-5,7l65,38l-8,14l29,-7l-10,-27l-8,12l-64,-36z", "f": 1 }
+ ],
+ "w": 0,
+ "h": "w-x1*k+sqrt((2*bra-x1*x1))+(sqrt((k*k+1))+k-1*bw/2)+margin",
+ "cover": true
+ }
+ },
+ "templates": {
+ "avfart": (no = "1") => ({
+ "type": "skylt",
+ "properties": {
+ "padding": 0,
+ "background": "#aaa",
+ "color": "black"
+ },
+ "elements": [
+ {
+ "type": "skylt",
+ "properties": {
+ "background": "#fd0",
+ "borderWidth": 4,
+ "borderRadius": 22,
+ "padding": [5, 0]
+ },
+ "elements": [
+ {
+ "type": "symbol",
+ "properties": { "type": "exit" }
+ },
+ {
+ "type": "text",
+ "properties": {
+ "value": no
+ }
+ }
+ ]
+ }
+ ]
+ }),
+ "vagnr": (no = "000") => ({
+ "type": "vagnr",
+ "properties": {
+ "value": no
+ }
+ }),
+ "symgroup": (...s: (string | string[])[]) => ({
+ "type": "skylt",
+ "properties": {"padding": 0, "xSpacing": 0, "borderWidth": [3, 0, 0, 0], "borderRadius": 0, "color": "black", "background": "white"},
+ "elements": s.map(x => ({"type": "symbol", "properties": {"type": Array.isArray(x) ? x[0] : x, "variant": Array.isArray(x) ? x[1] : undefined , "borderWidth": [0, 3, 3, 3], "padding": 1}}))
+ })
+ }
+};
\ No newline at end of file
diff --git a/src/render.ts b/src/render.ts
new file mode 100644
index 0000000..c5b4529
--- /dev/null
+++ b/src/render.ts
@@ -0,0 +1,26 @@
+import { SignRenderer } from "../packages/skyltrendering/src/browser.js";
+import CONFIG from "./config.js"
+
+const tratex = new FontFace(
+ "Tratex",
+ "url(font/TratexSvart-Regular.otf)",
+);
+
+const tratexVersal = new FontFace(
+ "TratexVersal",
+ "url(font/TRATEXPOSVERSAL-POSVERSAL.otf)",
+);
+
+document.fonts.add(tratex);
+document.fonts.add(tratexVersal);
+
+Promise.all([tratex.load(), tratexVersal.load()]).then(() => {
+ let url = new URL(window.location.href);
+ if(!url.searchParams.has("data")) return;
+
+ let data = JSON.parse(url.searchParams.get("data") || "");
+
+ new SignRenderer(CONFIG).render(data).then((canv: HTMLCanvasElement) => {
+ document.body.appendChild(canv);
+ });
+});
\ No newline at end of file
diff --git a/svg/junction.svg b/svg/junction.svg
deleted file mode 100644
index aae14e0..0000000
--- a/svg/junction.svg
+++ /dev/null
@@ -1,53 +0,0 @@
-
\ No newline at end of file
diff --git a/svg/plain.svg b/svg/plain.svg
deleted file mode 100644
index f665f43..0000000
--- a/svg/plain.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/svg/roundabout.svg b/svg/roundabout.svg
deleted file mode 100644
index 221a576..0000000
--- a/svg/roundabout.svg
+++ /dev/null
@@ -1,37 +0,0 @@
-
\ No newline at end of file
diff --git a/svg/spanish.svg b/svg/spanish.svg
deleted file mode 100644
index f54f0a7..0000000
--- a/svg/spanish.svg
+++ /dev/null
@@ -1,23 +0,0 @@
-
\ No newline at end of file
diff --git a/svg/symbol/arrow-small.svg b/svg/symbol/arrow-small.svg
deleted file mode 100644
index 01fd0d7..0000000
--- a/svg/symbol/arrow-small.svg
+++ /dev/null
@@ -1,18 +0,0 @@
-
\ No newline at end of file
diff --git a/svg/symbol/exit.svg b/svg/symbol/exit.svg
deleted file mode 100644
index 2112420..0000000
--- a/svg/symbol/exit.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-
\ No newline at end of file
diff --git a/svg/symbol/h1.svg b/svg/symbol/h1.svg
deleted file mode 100644
index 5835a83..0000000
--- a/svg/symbol/h1.svg
+++ /dev/null
@@ -1,4 +0,0 @@
-
diff --git a/svg/symbol/h10.svg b/svg/symbol/h10.svg
deleted file mode 100644
index 9422c77..0000000
--- a/svg/symbol/h10.svg
+++ /dev/null
@@ -1,4 +0,0 @@
-
diff --git a/svg/symbol/h11.svg b/svg/symbol/h11.svg
deleted file mode 100644
index 02f5b66..0000000
--- a/svg/symbol/h11.svg
+++ /dev/null
@@ -1,4 +0,0 @@
-
diff --git a/svg/symbol/h12.svg b/svg/symbol/h12.svg
deleted file mode 100644
index abf0fc2..0000000
--- a/svg/symbol/h12.svg
+++ /dev/null
@@ -1,8 +0,0 @@
-
diff --git a/svg/symbol/h13.svg b/svg/symbol/h13.svg
deleted file mode 100644
index 4faa744..0000000
--- a/svg/symbol/h13.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-
diff --git a/svg/symbol/h14.svg b/svg/symbol/h14.svg
deleted file mode 100644
index 16c3e6e..0000000
--- a/svg/symbol/h14.svg
+++ /dev/null
@@ -1,6 +0,0 @@
-
diff --git a/svg/symbol/h15.svg b/svg/symbol/h15.svg
deleted file mode 100644
index f76d604..0000000
--- a/svg/symbol/h15.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-
diff --git a/svg/symbol/h16.svg b/svg/symbol/h16.svg
deleted file mode 100644
index 12d35b7..0000000
--- a/svg/symbol/h16.svg
+++ /dev/null
@@ -1,4 +0,0 @@
-
diff --git a/svg/symbol/h17.svg b/svg/symbol/h17.svg
deleted file mode 100644
index 26ab80e..0000000
--- a/svg/symbol/h17.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-
diff --git a/svg/symbol/h18.svg b/svg/symbol/h18.svg
deleted file mode 100644
index f1ba666..0000000
--- a/svg/symbol/h18.svg
+++ /dev/null
@@ -1,4 +0,0 @@
-
diff --git a/svg/symbol/h19.svg b/svg/symbol/h19.svg
deleted file mode 100644
index 86733a4..0000000
--- a/svg/symbol/h19.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-
diff --git a/svg/symbol/h2.svg b/svg/symbol/h2.svg
deleted file mode 100644
index 031ad0d..0000000
--- a/svg/symbol/h2.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-
diff --git a/svg/symbol/h20.svg b/svg/symbol/h20.svg
deleted file mode 100644
index 9fd0e97..0000000
--- a/svg/symbol/h20.svg
+++ /dev/null
@@ -1,6 +0,0 @@
-
diff --git a/svg/symbol/h21.svg b/svg/symbol/h21.svg
deleted file mode 100644
index 0f1fbe4..0000000
--- a/svg/symbol/h21.svg
+++ /dev/null
@@ -1,7 +0,0 @@
-
diff --git a/svg/symbol/h22.svg b/svg/symbol/h22.svg
deleted file mode 100644
index 7c778b7..0000000
--- a/svg/symbol/h22.svg
+++ /dev/null
@@ -1,8 +0,0 @@
-
diff --git a/svg/symbol/h24.svg b/svg/symbol/h24.svg
deleted file mode 100644
index 26962c3..0000000
--- a/svg/symbol/h24.svg
+++ /dev/null
@@ -1,14 +0,0 @@
-
diff --git a/svg/symbol/h25.svg b/svg/symbol/h25.svg
deleted file mode 100644
index 5c8d5ed..0000000
--- a/svg/symbol/h25.svg
+++ /dev/null
@@ -1,20 +0,0 @@
-
diff --git a/svg/symbol/h26.svg b/svg/symbol/h26.svg
deleted file mode 100644
index e89ae68..0000000
--- a/svg/symbol/h26.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-
diff --git a/svg/symbol/h27.svg b/svg/symbol/h27.svg
deleted file mode 100644
index 3db4de6..0000000
--- a/svg/symbol/h27.svg
+++ /dev/null
@@ -1,6 +0,0 @@
-
diff --git a/svg/symbol/h28.svg b/svg/symbol/h28.svg
deleted file mode 100644
index 1e6e811..0000000
--- a/svg/symbol/h28.svg
+++ /dev/null
@@ -1,9 +0,0 @@
-
diff --git a/svg/symbol/h3.svg b/svg/symbol/h3.svg
deleted file mode 100644
index 5b34529..0000000
--- a/svg/symbol/h3.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-
diff --git a/svg/symbol/h4.svg b/svg/symbol/h4.svg
deleted file mode 100644
index 44ae70b..0000000
--- a/svg/symbol/h4.svg
+++ /dev/null
@@ -1,44 +0,0 @@
-
diff --git a/svg/symbol/h5.svg b/svg/symbol/h5.svg
deleted file mode 100644
index 4c95f8a..0000000
--- a/svg/symbol/h5.svg
+++ /dev/null
@@ -1,4 +0,0 @@
-
diff --git a/svg/symbol/h6.svg b/svg/symbol/h6.svg
deleted file mode 100644
index 83d4875..0000000
--- a/svg/symbol/h6.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-
diff --git a/svg/symbol/h7.svg b/svg/symbol/h7.svg
deleted file mode 100644
index ac74451..0000000
--- a/svg/symbol/h7.svg
+++ /dev/null
@@ -1,4 +0,0 @@
-
diff --git a/svg/symbol/h8.svg b/svg/symbol/h8.svg
deleted file mode 100644
index ab42c01..0000000
--- a/svg/symbol/h8.svg
+++ /dev/null
@@ -1,4 +0,0 @@
-
diff --git a/svg/symbol/h9.svg b/svg/symbol/h9.svg
deleted file mode 100644
index e5baccd..0000000
--- a/svg/symbol/h9.svg
+++ /dev/null
@@ -1,8 +0,0 @@
-
diff --git a/svg/water.svg b/svg/water.svg
deleted file mode 100644
index 7d436fb..0000000
--- a/svg/water.svg
+++ /dev/null
@@ -1,4 +0,0 @@
-
\ No newline at end of file
diff --git a/tsconfig.json b/tsconfig.json
new file mode 100644
index 0000000..968f2e2
--- /dev/null
+++ b/tsconfig.json
@@ -0,0 +1,36 @@
+{
+ "compilerOptions": {
+ /* Language and Environment */
+ "target": "es2017",
+ "noLib": false,
+
+ /* Modules */
+ "module": "es6",
+ "rootDir": ".",
+
+ /* Emit */
+ "outDir": "./dist",
+ "removeComments": true,
+
+ /* Interop Constraints */
+ "esModuleInterop": false,
+ "forceConsistentCasingInFileNames": true,
+
+ /* Type Checking */
+ "strict": true,
+ "noImplicitAny": true,
+ "strictNullChecks": true,
+ "strictFunctionTypes": true,
+ "strictPropertyInitialization": true,
+ "noImplicitThis": true,
+ "alwaysStrict": true,
+ "noUnusedLocals": true,
+ "noUnusedParameters": true,
+ "noImplicitReturns": true,
+ "noUncheckedIndexedAccess": false,
+ "noImplicitOverride": true
+ },
+ "files": ["./packages/skyltrendering/src/browser.ts", "./src/render.ts"],
+ "include": ["./src/**.ts", "./packages/skyltrendering/src/**.ts"],
+ "exclude": ["./packages/skyltrendering/src/main.ts"]
+}
diff --git a/utils.js b/utils.js
deleted file mode 100644
index 3c71a38..0000000
--- a/utils.js
+++ /dev/null
@@ -1,93 +0,0 @@
-function mathEval(str = "", vars = {}){
- let values = [0], operators = ["+"], tmp = "";
-
- let doOp = (a, op, b) => {
- switch(op){
- case "+":
- a += b;
- break;
- case "-":
- a -= b;
- break;
- case "*":
- a *= b;
- break;
- case "/":
- a /= b;
- break;
- case "sqrt":
- a = Math.sqrt(b);
- //console.log(a, b);
- break;
- }
-
- return a;
- };
-
- let c;
- for(let i = 0; i <= str.length; i++){
- switch(c = str.charAt(i) || "+"){
- case " ":
- continue;
- case "(":
- values.push(0);
- if(tmp.length > 0){
- operators.push(tmp);
- tmp = "";
- break;
- }
- operators.push("+");
- break;
- case ")":
- case "*":
- case "/":
- case "+":
- case "-":
- let x0 = tmp.length > 0 ? doOp(values.pop(), operators.pop(), isNaN(tmp) ? vars[tmp] : parseFloat(tmp)) : values.pop();
- tmp = "";
-
- if(c === ")"){
- values[values.length - 1] = doOp(values[values.length - 1], operators.pop(), x0);
- break;
- }
-
- values.push(x0);
- operators.push(c);
- break;
- default:
- tmp += c;
- }
- }
-
- return values[0];
-}
-
-function parseVarStr(str, vars = {}){
- const EXPRESSION = new RegExp(/\$\{([^\{\}]+)\}/g);
-
- let result = [];
-
- let i = 0;
- while(true){
- let match = EXPRESSION.exec(str);
-
- if(match === null || EXPRESSION.lastIndex === 0) break;
-
- result.push(str.substring(i, match.index).concat(String(mathEval(match[1], vars))));
-
- i = match.index + match[0].length;
- }
-
- return result.join("") + str.substring(i);
-}
-
-function getText(url){
- return new Promise((resolve, reject) => {
- let req = new XMLHttpRequest();
- req.addEventListener("load", () => {
- resolve(req.responseText);
- });
- req.open("GET", url);
- req.send();
- });
-}
\ No newline at end of file