@multiplekex/shallot 0.1.12 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. package/package.json +3 -4
  2. package/src/core/builder.ts +71 -32
  3. package/src/core/component.ts +25 -11
  4. package/src/core/index.ts +14 -13
  5. package/src/core/math.ts +135 -0
  6. package/src/core/runtime.ts +0 -1
  7. package/src/core/state.ts +9 -68
  8. package/src/core/xml.ts +381 -265
  9. package/src/editor/format.ts +5 -0
  10. package/src/editor/index.ts +101 -0
  11. package/src/extras/arrows/index.ts +28 -69
  12. package/src/extras/gradient/index.ts +36 -52
  13. package/src/extras/lines/index.ts +51 -122
  14. package/src/extras/orbit/index.ts +40 -15
  15. package/src/extras/text/font.ts +546 -0
  16. package/src/extras/text/index.ts +158 -204
  17. package/src/extras/text/sdf.ts +429 -0
  18. package/src/standard/activity/index.ts +172 -0
  19. package/src/standard/compute/graph.ts +23 -23
  20. package/src/standard/compute/index.ts +76 -61
  21. package/src/standard/defaults.ts +8 -5
  22. package/src/standard/index.ts +1 -0
  23. package/src/standard/input/index.ts +30 -19
  24. package/src/standard/loading/index.ts +18 -13
  25. package/src/standard/render/bvh/blas.ts +752 -0
  26. package/src/standard/render/bvh/radix.ts +476 -0
  27. package/src/standard/render/bvh/structs.ts +167 -0
  28. package/src/standard/render/bvh/tlas.ts +886 -0
  29. package/src/standard/render/bvh/traverse.ts +467 -0
  30. package/src/standard/render/camera.ts +302 -27
  31. package/src/standard/render/data.ts +93 -0
  32. package/src/standard/render/depth.ts +117 -0
  33. package/src/standard/render/forward/index.ts +259 -0
  34. package/src/standard/render/forward/raster.ts +228 -0
  35. package/src/standard/render/index.ts +443 -70
  36. package/src/standard/render/indirect.ts +40 -0
  37. package/src/standard/render/instance.ts +214 -0
  38. package/src/standard/render/intersection.ts +72 -0
  39. package/src/standard/render/light.ts +16 -16
  40. package/src/standard/render/mesh/index.ts +67 -75
  41. package/src/standard/render/mesh/unified.ts +96 -0
  42. package/src/standard/render/{transparent.ts → overlay.ts} +14 -15
  43. package/src/standard/render/pass.ts +10 -4
  44. package/src/standard/render/postprocess.ts +142 -64
  45. package/src/standard/render/ray.ts +61 -0
  46. package/src/standard/render/scene.ts +38 -164
  47. package/src/standard/render/shaders.ts +484 -0
  48. package/src/standard/render/surface/compile.ts +3 -10
  49. package/src/standard/render/surface/index.ts +60 -30
  50. package/src/standard/render/surface/noise.ts +45 -0
  51. package/src/standard/render/surface/structs.ts +60 -19
  52. package/src/standard/render/surface/wgsl.ts +573 -0
  53. package/src/standard/render/triangle.ts +84 -0
  54. package/src/standard/transforms/index.ts +4 -6
  55. package/src/standard/tween/index.ts +10 -1
  56. package/src/standard/tween/sequence.ts +24 -16
  57. package/src/standard/tween/tween.ts +67 -16
  58. package/src/core/types.ts +0 -37
  59. package/src/standard/compute/inspect.ts +0 -201
  60. package/src/standard/compute/pass.ts +0 -23
  61. package/src/standard/compute/timing.ts +0 -139
  62. package/src/standard/render/forward.ts +0 -273
@@ -1,30 +1,25 @@
1
1
  import { resource, type Plugin, type State, type System } from "../../core";
2
2
  import { ComputeGraph, type ExecutionContext, type ResourceId } from "./graph";
3
- import { createTimingCollector, type FrameTiming } from "./timing";
4
3
 
5
- export * from "./graph";
6
- export * from "./inspect";
7
- export * from "./pass";
8
- export * from "./readback";
9
- export * from "./timing";
4
+ export { ComputeGraph } from "./graph";
5
+ export type {
6
+ ResourceId,
7
+ NodeId,
8
+ ResourceRef,
9
+ ExecutionContext,
10
+ ComputeNode,
11
+ ExecutionPlan,
12
+ } from "./graph";
10
13
 
11
- const MIN_CANVAS_SIZE = 1;
12
-
13
- function syncCanvasSize(canvas: HTMLCanvasElement): void {
14
- const dpr = window.devicePixelRatio || 1;
15
- const rect = canvas.getBoundingClientRect();
16
-
17
- const width = Math.max(MIN_CANVAS_SIZE, Math.floor(rect.width * dpr));
18
- const height = Math.max(MIN_CANVAS_SIZE, Math.floor(rect.height * dpr));
14
+ export { readBuffer, readFloat32, readUint32, StagingPool } from "./readback";
19
15
 
20
- if (canvas.width !== width || canvas.height !== height) {
21
- canvas.width = width;
22
- canvas.height = height;
23
- }
16
+ export interface Canvas {
17
+ readonly element: HTMLCanvasElement;
18
+ readonly context: GPUCanvasContext;
19
+ readonly format: GPUTextureFormat;
24
20
  }
25
21
 
26
- let resizeObserver: ResizeObserver | null = null;
27
- let observedCanvas: HTMLCanvasElement | null = null;
22
+ export const Canvas = resource<Canvas>("canvas");
28
23
 
29
24
  export function createEntityIdBuffer(device: GPUDevice, maxInstances: number): GPUBuffer {
30
25
  return device.createBuffer({
@@ -46,11 +41,21 @@ export async function requestGPU(): Promise<GPUDevice> {
46
41
 
47
42
  const maxTextureDimension2D = adapter.limits.maxTextureDimension2D;
48
43
 
49
- return adapter.requestDevice({
44
+ const device = await adapter.requestDevice({
50
45
  requiredLimits: {
51
46
  maxTextureDimension2D,
52
47
  },
53
48
  });
49
+
50
+ device.lost.then((info) => {
51
+ console.error(`GPU device lost: ${info.reason}`, info.message);
52
+ });
53
+
54
+ device.onuncapturederror = (event) => {
55
+ console.error("GPU uncaptured error:", event.error);
56
+ };
57
+
58
+ return device;
54
59
  }
55
60
 
56
61
  export interface ComputeResources {
@@ -59,25 +64,41 @@ export interface ComputeResources {
59
64
  buffers: Map<ResourceId, GPUBuffer>;
60
65
  }
61
66
 
62
- export interface ComputeState {
67
+ export interface Compute {
63
68
  readonly device: GPUDevice;
64
- readonly context: GPUCanvasContext;
65
- readonly format: GPUTextureFormat;
66
69
  readonly graph: ComputeGraph;
67
70
  readonly resources: ComputeResources;
68
- lastFrameTiming: FrameTiming | null;
69
71
  frameIndex: number;
70
72
  }
71
73
 
72
- export const Compute = resource<ComputeState>("compute");
74
+ export const Compute = resource<Compute>("compute");
75
+
76
+ const MIN_CANVAS_SIZE = 1;
77
+
78
+ function syncCanvasSize(canvas: HTMLCanvasElement): void {
79
+ const dpr = window.devicePixelRatio || 1;
80
+ const rect = canvas.getBoundingClientRect();
81
+
82
+ const width = Math.max(MIN_CANVAS_SIZE, Math.floor(rect.width * dpr));
83
+ const height = Math.max(MIN_CANVAS_SIZE, Math.floor(rect.height * dpr));
84
+
85
+ if (canvas.width !== width || canvas.height !== height) {
86
+ canvas.width = width;
87
+ canvas.height = height;
88
+ }
89
+ }
90
+
91
+ let resizeObserver: ResizeObserver | null = null;
92
+ let observedCanvas: HTMLCanvasElement | null = null;
73
93
 
74
94
  export const ComputeSystem: System = {
75
95
  group: "draw",
76
96
 
77
97
  setup(state: State) {
78
- if (!state.canvas) return;
98
+ const canvas = Canvas.from(state);
99
+ if (!canvas) return;
79
100
 
80
- observedCanvas = state.canvas;
101
+ observedCanvas = canvas.element;
81
102
  syncCanvasSize(observedCanvas);
82
103
 
83
104
  resizeObserver = new ResizeObserver(() => {
@@ -88,21 +109,22 @@ export const ComputeSystem: System = {
88
109
 
89
110
  update(state: State) {
90
111
  const compute = Compute.from(state);
91
- if (!compute) return;
112
+ const canvas = Canvas.from(state);
113
+ if (!compute || !canvas) return;
92
114
 
93
- const { device, context, format, graph, resources } = compute;
115
+ const { device, graph, resources } = compute;
116
+ const { context, format } = canvas;
94
117
  const plan = graph.compile();
95
118
 
96
119
  if (plan.sorted.length === 0) return;
97
120
 
98
121
  const canvasTexture = context.getCurrentTexture();
99
122
  const canvasView = canvasTexture.createView();
100
- const encoder = device.createCommandEncoder();
101
123
 
102
124
  const ctx: ExecutionContext = {
103
125
  device,
104
126
  queue: device.queue,
105
- encoder,
127
+ encoder: null as unknown as GPUCommandEncoder,
106
128
  context,
107
129
  format,
108
130
  canvasView,
@@ -126,17 +148,20 @@ export const ComputeSystem: System = {
126
148
  },
127
149
  };
128
150
 
129
- const collector = createTimingCollector();
151
+ let encoder = device.createCommandEncoder();
152
+ (ctx as { encoder: GPUCommandEncoder }).encoder = encoder;
130
153
 
131
154
  for (const node of plan.sorted) {
132
- collector.beginNode(node.id);
133
155
  node.execute(ctx);
134
- collector.endNode(node.id);
156
+
157
+ if (node.sync) {
158
+ device.queue.submit([encoder.finish()]);
159
+ encoder = device.createCommandEncoder();
160
+ (ctx as { encoder: GPUCommandEncoder }).encoder = encoder;
161
+ }
135
162
  }
136
163
 
137
164
  device.queue.submit([encoder.finish()]);
138
-
139
- compute.lastFrameTiming = collector.finish(compute.frameIndex);
140
165
  compute.frameIndex++;
141
166
  },
142
167
 
@@ -150,24 +175,14 @@ export const ComputeSystem: System = {
150
175
  export const ComputePlugin: Plugin = {
151
176
  systems: [ComputeSystem],
152
177
 
153
- async initialize(state: State) {
154
- if (!state.canvas) {
155
- throw new Error("ComputePlugin requires a canvas");
156
- }
178
+ async initialize(state: State, onProgress?: (progress: number) => void) {
179
+ const canvas = Canvas.from(state);
180
+ if (!canvas) return;
157
181
 
158
182
  const device = await requestGPU();
183
+ const { context, format } = canvas;
159
184
 
160
- const context = state.canvas.getContext("webgpu");
161
- if (!context) {
162
- throw new Error("Failed to get WebGPU context");
163
- }
164
-
165
- const format = navigator.gpu.getPreferredCanvasFormat();
166
- context.configure({
167
- device,
168
- format,
169
- alphaMode: "premultiplied",
170
- });
185
+ context.configure({ device, format, alphaMode: "premultiplied" });
171
186
 
172
187
  const graph = new ComputeGraph();
173
188
  const resources: ComputeResources = {
@@ -176,14 +191,14 @@ export const ComputePlugin: Plugin = {
176
191
  buffers: new Map(),
177
192
  };
178
193
 
179
- state.setResource(Compute, {
180
- device,
181
- context,
182
- format,
183
- graph,
184
- resources,
185
- lastFrameTiming: null,
186
- frameIndex: 0,
187
- });
194
+ state.setResource(Compute, { device, graph, resources, frameIndex: 0 });
195
+ onProgress?.(1);
188
196
  },
189
197
  };
198
+
199
+ export function initCanvas(state: State, element: HTMLCanvasElement): void {
200
+ const context = element.getContext("webgpu")!;
201
+ const format = navigator.gpu.getPreferredCanvasFormat();
202
+ element.style.imageRendering = "pixelated";
203
+ state.setResource(Canvas, { element, context, format });
204
+ }
@@ -1,12 +1,13 @@
1
- import type { Plugin } from "../core/types";
2
- import { StateBuilder } from "../core/builder";
1
+ import { StateBuilder, type Plugin } from "../core/builder";
3
2
  import { TransformsPlugin } from "./transforms";
4
3
  import { InputPlugin } from "./input";
5
- import { canvasLoading } from "./loading";
6
- import { ComputePlugin } from "./compute";
4
+ import { ComputePlugin, initCanvas } from "./compute";
7
5
  import { RenderPlugin } from "./render";
6
+ import { ActivityPlugin, spinnerDark } from "./activity";
7
+ import { shallotDark } from "./loading";
8
8
 
9
9
  export const DEFAULT_PLUGINS: readonly Plugin[] = [
10
+ ActivityPlugin,
10
11
  TransformsPlugin,
11
12
  InputPlugin,
12
13
  ComputePlugin,
@@ -14,4 +15,6 @@ export const DEFAULT_PLUGINS: readonly Plugin[] = [
14
15
  ];
15
16
 
16
17
  StateBuilder.defaultPlugins = DEFAULT_PLUGINS;
17
- StateBuilder.loading = canvasLoading;
18
+ StateBuilder.initCanvas = initCanvas;
19
+ StateBuilder.defaultLoading = shallotDark;
20
+ ActivityPlugin.spinner = spinnerDark;
@@ -1,3 +1,4 @@
1
+ export * from "./activity";
1
2
  export * from "./compute";
2
3
  export * from "./input";
3
4
  export * from "./tween";
@@ -1,28 +1,38 @@
1
- import {
2
- resource,
3
- type State,
4
- type System,
5
- type Plugin,
6
- type InputState,
7
- type MouseState,
8
- } from "../../core";
1
+ import { resource, type State, type System, type Plugin } from "../../core";
2
+ import { Canvas } from "../compute";
3
+
4
+ export interface Mouse {
5
+ deltaX: number;
6
+ deltaY: number;
7
+ scroll: number;
8
+ left: boolean;
9
+ right: boolean;
10
+ middle: boolean;
11
+ }
12
+
13
+ export interface Inputs {
14
+ readonly mouse: Readonly<Mouse>;
15
+ isKeyDown(code: string): boolean;
16
+ isKeyPressed(code: string): boolean;
17
+ isKeyReleased(code: string): boolean;
18
+ }
9
19
 
10
- export const Input = resource<InputState>("input");
20
+ export const Inputs = resource<Inputs>("inputs");
11
21
 
12
22
  const keys = new Set<string>();
13
23
  const keysPressed = new Set<string>();
14
24
  const keysReleased = new Set<string>();
15
25
 
16
- const mouse: MouseState = {
26
+ const mouse: Mouse = {
17
27
  deltaX: 0,
18
28
  deltaY: 0,
19
- scrollDelta: 0,
29
+ scroll: 0,
20
30
  left: false,
21
31
  right: false,
22
32
  middle: false,
23
33
  };
24
34
 
25
- const inputState: InputState = {
35
+ const inputs: Inputs = {
26
36
  mouse,
27
37
  isKeyDown: (code: string) => keys.has(code),
28
38
  isKeyPressed: (code: string) => keysPressed.has(code),
@@ -100,7 +110,7 @@ function handlePointerMove(e: PointerEvent): void {
100
110
 
101
111
  function handleWheel(e: WheelEvent): void {
102
112
  if (e.target !== canvas) return;
103
- mouse.scrollDelta += e.deltaY;
113
+ mouse.scroll += e.deltaY;
104
114
  e.preventDefault();
105
115
  }
106
116
 
@@ -115,7 +125,7 @@ function resetFrameState(): void {
115
125
  keysReleased.clear();
116
126
  mouse.deltaX = 0;
117
127
  mouse.deltaY = 0;
118
- mouse.scrollDelta = 0;
128
+ mouse.scroll = 0;
119
129
  }
120
130
 
121
131
  function clearAllState(): void {
@@ -124,7 +134,7 @@ function clearAllState(): void {
124
134
  keysReleased.clear();
125
135
  mouse.deltaX = 0;
126
136
  mouse.deltaY = 0;
127
- mouse.scrollDelta = 0;
137
+ mouse.scroll = 0;
128
138
  mouse.left = false;
129
139
  mouse.right = false;
130
140
  mouse.middle = false;
@@ -138,8 +148,9 @@ export const InputSystem: System = {
138
148
  group: "simulation",
139
149
 
140
150
  setup(state: State) {
141
- if (!state.canvas) return;
142
- canvas = state.canvas;
151
+ const canvasRes = Canvas.from(state);
152
+ if (!canvasRes) return;
153
+ canvas = canvasRes.element;
143
154
  canvas.style.touchAction = "none";
144
155
 
145
156
  window.addEventListener("keydown", handleKeyDown);
@@ -151,7 +162,7 @@ export const InputSystem: System = {
151
162
  canvas.addEventListener("wheel", handleWheel, { passive: false });
152
163
  canvas.addEventListener("contextmenu", handleContextMenu);
153
164
 
154
- state.setResource(Input, inputState);
165
+ state.setResource(Inputs, inputs);
155
166
  },
156
167
 
157
168
  dispose(state: State) {
@@ -168,7 +179,7 @@ export const InputSystem: System = {
168
179
  }
169
180
 
170
181
  clearAllState();
171
- state.deleteResource(Input);
182
+ state.deleteResource(Inputs);
172
183
  },
173
184
  };
174
185
 
@@ -1,4 +1,5 @@
1
- import type { Loading } from "../../core";
1
+ import type { Loading } from "../../core/builder";
2
+ export type { Loading };
2
3
 
3
4
  interface Theme {
4
5
  bg: string;
@@ -9,7 +10,7 @@ interface Theme {
9
10
  const dark: Theme = { bg: "#1a1a1a", track: "#333", bar: "#E8A86B" };
10
11
  const light: Theme = { bg: "#f5f5f5", track: "#ddd", bar: "#B87654" };
11
12
 
12
- const LOGO_SVG = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 80 80">
13
+ const LOGO_SVG = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 285 80">
13
14
  <defs>
14
15
  <radialGradient id="baseGradient" cx="35%" cy="30%" r="70%" fx="25%" fy="20%">
15
16
  <stop offset="0%" stop-color="#F5D4B8"/>
@@ -17,14 +18,18 @@ const LOGO_SVG = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 80 80">
17
18
  <stop offset="100%" stop-color="#B87654"/>
18
19
  </radialGradient>
19
20
  </defs>
20
- <g transform="rotate(35 40.0 40.0)">
21
- <path d="M40.0,2 C44.0,10 66.0,28 66.0,46 C66.0,60 48.0,70 40.0,78 C32.0,70 14.0,60 14.0,46 C14.0,28 36.0,10 40.0,2 Z" fill="url(#baseGradient)"/>
22
- <path d="M40.0,6 C37.0,14 22.0,28 20.0,44 C20.0,52 28.0,62 36.0,70 C34.0,58 26.0,46 26.0,38 C26.0,26 38.0,12 40.0,6 Z" fill="#B87654" opacity="0.45"/>
23
- <path d="M40.0,6 C43.0,14 58.0,28 60.0,44 C60.0,52 52.0,62 44.0,70 C46.0,58 54.0,46 54.0,38 C54.0,26 42.0,12 40.0,6 Z" fill="#B87654" opacity="0.35"/>
24
- <path d="M40.0,8 C40.0,20 40.0,50 40.0,72" stroke="#B87654" stroke-width="1" stroke-opacity="0.4" fill="none" stroke-linecap="round"/>
25
- <path d="M40.0,78 C48.0,70 66.0,60 66.0,46 C61.0,58 44.0,70 40.0,73 Z" fill="#B87654"/>
26
- <path d="M40.0,2 C36.0,10 14.0,28 14.0,46 C19.0,30 41.0,8 40.0,7 Z" fill="#F5D4B8" opacity="0.7"/>
27
- <path d="M40.0,2 C44.0,10 66.0,28 66.0,46 C66.0,60 48.0,70 40.0,78 C32.0,70 14.0,60 14.0,46 C14.0,28 36.0,10 40.0,2 Z" fill="none" stroke="#6B4230" stroke-width="2"/>
21
+ <g id="Icon" transform="rotate(35 40 40)">
22
+ <path id="Background" d="M40,2 C44,10 66,28 66,46 C66,60 48,70 40,78 C32,70 14,60 14,46 C14,28 36,10 40,2 Z" fill="#E8A86B"/>
23
+ <path id="CloveLeft" d="M40,6 C37,14 22,28 20,44 C20,52 28,62 36,70 C34,58 26,46 26,38 C26,26 38,12 40,6 Z" fill="#D49560"/>
24
+ <path id="CloveRight" d="M40,6 C43,14 58,28 60,44 C60,52 52,62 44,70 C46,58 54,46 54,38 C54,26 42,12 40,6 Z" fill="#D49560"/>
25
+ <path id="CenterCrease" d="M40,8 C40,20 40,50 40,72" stroke="#6B4230" stroke-width="1" stroke-opacity="0.4" fill="none" stroke-linecap="round"/>
26
+ <path id="BottomEdge" d="M40,78 C48,70 66,60 66,46 C61,58 44,70 40,73 Z" fill="#D49560"/>
27
+ <path id="Outline" d="M40,2 C44,10 66,28 66,46 C66,60 48,70 40,78 C32,70 14,60 14,46 C14,28 36,10 40,2 Z" fill="none" stroke="#6B4230" stroke-width="2"/>
28
+ </g>
29
+ <g id="Text" transform="translate(80 59)">
30
+ <path d="M13.37 0.73Q10.88 0.73 8.47 0.07Q6.06 -0.58 4.02 -1.75Q1.97 -2.93 0.52 -4.52L5.54 -9.63Q6.96 -8.09 8.87 -7.26Q10.79 -6.44 13.05 -6.44Q14.62 -6.44 15.44 -6.89Q16.27 -7.34 16.27 -8.18Q16.27 -9.22 15.27 -9.77Q14.27 -10.32 12.7 -10.74Q11.14 -11.17 9.4 -11.7Q7.66 -12.24 6.08 -13.17Q4.5 -14.09 3.51 -15.73Q2.52 -17.37 2.52 -19.95Q2.52 -22.65 3.92 -24.66Q5.31 -26.68 7.86 -27.83Q10.41 -28.97 13.86 -28.97Q17.43 -28.97 20.49 -27.74Q23.55 -26.51 25.46 -24.04L20.42 -18.94Q19.08 -20.5 17.43 -21.16Q15.78 -21.81 14.18 -21.81Q12.67 -21.81 11.93 -21.36Q11.19 -20.91 11.19 -20.13Q11.19 -19.23 12.18 -18.7Q13.17 -18.18 14.73 -17.78Q16.3 -17.37 18.02 -16.81Q19.75 -16.24 21.32 -15.24Q22.88 -14.24 23.87 -12.59Q24.85 -10.93 24.85 -8.29Q24.85 -4.15 21.75 -1.71Q18.65 0.73 13.37 0.73Z M48.31 0V-16.04Q48.31 -18.27 46.95 -19.62Q45.59 -20.97 43.48 -20.97Q42.04 -20.97 40.93 -20.36Q39.82 -19.75 39.19 -18.63Q38.57 -17.52 38.57 -16.04L35.12 -17.72Q35.12 -21.05 36.53 -23.53Q37.93 -26.01 40.42 -27.39Q42.91 -28.77 46.15 -28.77Q49.45 -28.77 51.94 -27.39Q54.43 -26.01 55.81 -23.61Q57.19 -21.2 57.19 -18.04V0ZM29.7 0V-42.11H38.57V0Z M74.65 0.58Q70.76 0.58 67.7 -1.33Q64.64 -3.25 62.89 -6.55Q61.13 -9.86 61.13 -14.07Q61.13 -18.3 62.89 -21.62Q64.64 -24.94 67.7 -26.85Q70.76 -28.77 74.65 -28.77Q77.49 -28.77 79.78 -27.67Q82.07 -26.56 83.51 -24.62Q84.94 -22.68 85.14 -20.18V-8Q84.94 -5.51 83.52 -3.57Q82.1 -1.62 79.79 -0.52Q77.49 0.58 74.65 0.58ZM76.44 -7.42Q79.29 -7.42 81.03 -9.29Q82.77 -11.17 82.77 -14.09Q82.77 -16.07 81.98 -17.56Q81.2 -19.05 79.78 -19.91Q78.36 -20.76 76.47 -20.76Q74.62 -20.76 73.2 -19.91Q71.78 -19.05 70.95 -17.55Q70.12 -16.04 70.12 -14.09Q70.12 -12.15 70.93 -10.64Q71.75 -9.13 73.18 -8.28Q74.62 -7.42 76.44 -7.42ZM82.39 0V-7.57L83.72 -14.44L82.39 -21.26V-28.19H91.12V0Z M97.38 0V-42.11H106.26V0Z M112.52 0V-42.11H121.39V0Z M141.23 0.64Q136.85 0.64 133.36 -1.31Q129.86 -3.25 127.83 -6.61Q125.8 -9.98 125.8 -14.15Q125.8 -18.33 127.82 -21.63Q129.83 -24.94 133.33 -26.88Q136.82 -28.83 141.2 -28.83Q145.61 -28.83 149.09 -26.9Q152.57 -24.97 154.6 -21.65Q156.63 -18.33 156.63 -14.15Q156.63 -9.98 154.61 -6.61Q152.6 -3.25 149.12 -1.31Q145.64 0.64 141.23 0.64ZM141.2 -7.42Q143.12 -7.42 144.56 -8.27Q146.02 -9.11 146.81 -10.63Q147.61 -12.15 147.61 -14.12Q147.61 -16.1 146.78 -17.59Q145.96 -19.08 144.54 -19.92Q143.12 -20.76 141.2 -20.76Q139.34 -20.76 137.9 -19.91Q136.45 -19.05 135.63 -17.56Q134.82 -16.07 134.82 -14.09Q134.82 -12.15 135.63 -10.63Q136.45 -9.11 137.9 -8.27Q139.34 -7.42 141.2 -7.42Z M165.07 0V-39.85H173.94V0ZM158.69 -20.65V-28.19H180.32V-20.65Z" fill="#3D2415" transform="translate(2.5 3)"/>
31
+ <path d="M13.37 0.73Q10.88 0.73 8.47 0.07Q6.06 -0.58 4.02 -1.75Q1.97 -2.93 0.52 -4.52L5.54 -9.63Q6.96 -8.09 8.87 -7.26Q10.79 -6.44 13.05 -6.44Q14.62 -6.44 15.44 -6.89Q16.27 -7.34 16.27 -8.18Q16.27 -9.22 15.27 -9.77Q14.27 -10.32 12.7 -10.74Q11.14 -11.17 9.4 -11.7Q7.66 -12.24 6.08 -13.17Q4.5 -14.09 3.51 -15.73Q2.52 -17.37 2.52 -19.95Q2.52 -22.65 3.92 -24.66Q5.31 -26.68 7.86 -27.83Q10.41 -28.97 13.86 -28.97Q17.43 -28.97 20.49 -27.74Q23.55 -26.51 25.46 -24.04L20.42 -18.94Q19.08 -20.5 17.43 -21.16Q15.78 -21.81 14.18 -21.81Q12.67 -21.81 11.93 -21.36Q11.19 -20.91 11.19 -20.13Q11.19 -19.23 12.18 -18.7Q13.17 -18.18 14.73 -17.78Q16.3 -17.37 18.02 -16.81Q19.75 -16.24 21.32 -15.24Q22.88 -14.24 23.87 -12.59Q24.85 -10.93 24.85 -8.29Q24.85 -4.15 21.75 -1.71Q18.65 0.73 13.37 0.73Z M48.31 0V-16.04Q48.31 -18.27 46.95 -19.62Q45.59 -20.97 43.48 -20.97Q42.04 -20.97 40.93 -20.36Q39.82 -19.75 39.19 -18.63Q38.57 -17.52 38.57 -16.04L35.12 -17.72Q35.12 -21.05 36.53 -23.53Q37.93 -26.01 40.42 -27.39Q42.91 -28.77 46.15 -28.77Q49.45 -28.77 51.94 -27.39Q54.43 -26.01 55.81 -23.61Q57.19 -21.2 57.19 -18.04V0ZM29.7 0V-42.11H38.57V0Z M74.65 0.58Q70.76 0.58 67.7 -1.33Q64.64 -3.25 62.89 -6.55Q61.13 -9.86 61.13 -14.07Q61.13 -18.3 62.89 -21.62Q64.64 -24.94 67.7 -26.85Q70.76 -28.77 74.65 -28.77Q77.49 -28.77 79.78 -27.67Q82.07 -26.56 83.51 -24.62Q84.94 -22.68 85.14 -20.18V-8Q84.94 -5.51 83.52 -3.57Q82.1 -1.62 79.79 -0.52Q77.49 0.58 74.65 0.58ZM76.44 -7.42Q79.29 -7.42 81.03 -9.29Q82.77 -11.17 82.77 -14.09Q82.77 -16.07 81.98 -17.56Q81.2 -19.05 79.78 -19.91Q78.36 -20.76 76.47 -20.76Q74.62 -20.76 73.2 -19.91Q71.78 -19.05 70.95 -17.55Q70.12 -16.04 70.12 -14.09Q70.12 -12.15 70.93 -10.64Q71.75 -9.13 73.18 -8.28Q74.62 -7.42 76.44 -7.42ZM82.39 0V-7.57L83.72 -14.44L82.39 -21.26V-28.19H91.12V0Z M97.38 0V-42.11H106.26V0Z M112.52 0V-42.11H121.39V0Z M141.23 0.64Q136.85 0.64 133.36 -1.31Q129.86 -3.25 127.83 -6.61Q125.8 -9.98 125.8 -14.15Q125.8 -18.33 127.82 -21.63Q129.83 -24.94 133.33 -26.88Q136.82 -28.83 141.2 -28.83Q145.61 -28.83 149.09 -26.9Q152.57 -24.97 154.6 -21.65Q156.63 -18.33 156.63 -14.15Q156.63 -9.98 154.61 -6.61Q152.6 -3.25 149.12 -1.31Q145.64 0.64 141.23 0.64ZM141.2 -7.42Q143.12 -7.42 144.56 -8.27Q146.02 -9.11 146.81 -10.63Q147.61 -12.15 147.61 -14.12Q147.61 -16.1 146.78 -17.59Q145.96 -19.08 144.54 -19.92Q143.12 -20.76 141.2 -20.76Q139.34 -20.76 137.9 -19.91Q136.45 -19.05 135.63 -17.56Q134.82 -16.07 134.82 -14.09Q134.82 -12.15 135.63 -10.63Q136.45 -9.11 137.9 -8.27Q139.34 -7.42 141.2 -7.42Z M165.07 0V-39.85H173.94V0ZM158.69 -20.65V-28.19H180.32V-20.65Z" fill="none" stroke="#6B4230" stroke-width="3.5" stroke-linejoin="round"/>
32
+ <path d="M13.37 0.73Q10.88 0.73 8.47 0.07Q6.06 -0.58 4.02 -1.75Q1.97 -2.93 0.52 -4.52L5.54 -9.63Q6.96 -8.09 8.87 -7.26Q10.79 -6.44 13.05 -6.44Q14.62 -6.44 15.44 -6.89Q16.27 -7.34 16.27 -8.18Q16.27 -9.22 15.27 -9.77Q14.27 -10.32 12.7 -10.74Q11.14 -11.17 9.4 -11.7Q7.66 -12.24 6.08 -13.17Q4.5 -14.09 3.51 -15.73Q2.52 -17.37 2.52 -19.95Q2.52 -22.65 3.92 -24.66Q5.31 -26.68 7.86 -27.83Q10.41 -28.97 13.86 -28.97Q17.43 -28.97 20.49 -27.74Q23.55 -26.51 25.46 -24.04L20.42 -18.94Q19.08 -20.5 17.43 -21.16Q15.78 -21.81 14.18 -21.81Q12.67 -21.81 11.93 -21.36Q11.19 -20.91 11.19 -20.13Q11.19 -19.23 12.18 -18.7Q13.17 -18.18 14.73 -17.78Q16.3 -17.37 18.02 -16.81Q19.75 -16.24 21.32 -15.24Q22.88 -14.24 23.87 -12.59Q24.85 -10.93 24.85 -8.29Q24.85 -4.15 21.75 -1.71Q18.65 0.73 13.37 0.73Z M48.31 0V-16.04Q48.31 -18.27 46.95 -19.62Q45.59 -20.97 43.48 -20.97Q42.04 -20.97 40.93 -20.36Q39.82 -19.75 39.19 -18.63Q38.57 -17.52 38.57 -16.04L35.12 -17.72Q35.12 -21.05 36.53 -23.53Q37.93 -26.01 40.42 -27.39Q42.91 -28.77 46.15 -28.77Q49.45 -28.77 51.94 -27.39Q54.43 -26.01 55.81 -23.61Q57.19 -21.2 57.19 -18.04V0ZM29.7 0V-42.11H38.57V0Z M74.65 0.58Q70.76 0.58 67.7 -1.33Q64.64 -3.25 62.89 -6.55Q61.13 -9.86 61.13 -14.07Q61.13 -18.3 62.89 -21.62Q64.64 -24.94 67.7 -26.85Q70.76 -28.77 74.65 -28.77Q77.49 -28.77 79.78 -27.67Q82.07 -26.56 83.51 -24.62Q84.94 -22.68 85.14 -20.18V-8Q84.94 -5.51 83.52 -3.57Q82.1 -1.62 79.79 -0.52Q77.49 0.58 74.65 0.58ZM76.44 -7.42Q79.29 -7.42 81.03 -9.29Q82.77 -11.17 82.77 -14.09Q82.77 -16.07 81.98 -17.56Q81.2 -19.05 79.78 -19.91Q78.36 -20.76 76.47 -20.76Q74.62 -20.76 73.2 -19.91Q71.78 -19.05 70.95 -17.55Q70.12 -16.04 70.12 -14.09Q70.12 -12.15 70.93 -10.64Q71.75 -9.13 73.18 -8.28Q74.62 -7.42 76.44 -7.42ZM82.39 0V-7.57L83.72 -14.44L82.39 -21.26V-28.19H91.12V0Z M97.38 0V-42.11H106.26V0Z M112.52 0V-42.11H121.39V0Z M141.23 0.64Q136.85 0.64 133.36 -1.31Q129.86 -3.25 127.83 -6.61Q125.8 -9.98 125.8 -14.15Q125.8 -18.33 127.82 -21.63Q129.83 -24.94 133.33 -26.88Q136.82 -28.83 141.2 -28.83Q145.61 -28.83 149.09 -26.9Q152.57 -24.97 154.6 -21.65Q156.63 -18.33 156.63 -14.15Q156.63 -9.98 154.61 -6.61Q152.6 -3.25 149.12 -1.31Q145.64 0.64 141.23 0.64ZM141.2 -7.42Q143.12 -7.42 144.56 -8.27Q146.02 -9.11 146.81 -10.63Q147.61 -12.15 147.61 -14.12Q147.61 -16.1 146.78 -17.59Q145.96 -19.08 144.54 -19.92Q143.12 -20.76 141.2 -20.76Q139.34 -20.76 137.9 -19.91Q136.45 -19.05 135.63 -17.56Q134.82 -16.07 134.82 -14.09Q134.82 -12.15 135.63 -10.63Q136.45 -9.11 137.9 -8.27Q139.34 -7.42 141.2 -7.42Z M165.07 0V-39.85H173.94V0ZM158.69 -20.65V-28.19H180.32V-20.65Z" fill="#E8A86B"/>
28
33
  </g>
29
34
  </svg>`;
30
35
 
@@ -38,7 +43,7 @@ function createOverlay(canvas: HTMLCanvasElement, bg: string): HTMLDivElement {
38
43
  align-items: center;
39
44
  justify-content: center;
40
45
  background: ${bg};
41
- z-index: 1000;
46
+ z-index: 10000;
42
47
  `;
43
48
 
44
49
  const parent = canvas.parentElement;
@@ -55,7 +60,7 @@ function createOverlay(canvas: HTMLCanvasElement, bg: string): HTMLDivElement {
55
60
  function createProgressBar(theme: Theme): { track: HTMLDivElement; bar: HTMLDivElement } {
56
61
  const track = document.createElement("div");
57
62
  track.style.cssText = `
58
- width: 200px;
63
+ width: 228px;
59
64
  height: 4px;
60
65
  background: ${theme.track};
61
66
  border-radius: 2px;
@@ -84,7 +89,7 @@ function shallotLoading(canvas: HTMLCanvasElement, theme: Theme): Loading {
84
89
 
85
90
  const logo = document.createElement("div");
86
91
  logo.innerHTML = LOGO_SVG;
87
- logo.style.cssText = "width: 64px; height: 64px; margin-bottom: 24px;";
92
+ logo.style.cssText = "width: 228px; height: 64px; margin-bottom: 24px;";
88
93
  overlay.appendChild(logo);
89
94
 
90
95
  const progressBar = createProgressBar(theme);