@snowcone-app/canvas 0.28.0 → 0.30.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 (84) hide show
  1. package/ERROR_CONTRACT.md +13 -0
  2. package/dist/{CanvasRenderer-B_3GISlW.js → CanvasRenderer-BEf0hXeF.js} +1083 -1071
  3. package/dist/CanvasRenderer-BEf0hXeF.js.map +1 -0
  4. package/dist/{CanvasStateV1-kL09wsAn.js → CanvasStateV1-BDSyYo4A.js} +872 -844
  5. package/dist/{CanvasStateV1-kL09wsAn.js.map → CanvasStateV1-BDSyYo4A.js.map} +1 -1
  6. package/dist/ContextualToolbars-C3D_6sep.js +5960 -0
  7. package/dist/ContextualToolbars-C3D_6sep.js.map +1 -0
  8. package/dist/{EditorCanvasImpl-CrI9C_xM.js → EditorCanvasImpl-DXeBz2CX.js} +8 -8
  9. package/dist/{EditorCanvasImpl-CrI9C_xM.js.map → EditorCanvasImpl-DXeBz2CX.js.map} +1 -1
  10. package/dist/{ExportManager-J2xK86uq.js → ExportManager-DUdis6se.js} +1307 -970
  11. package/dist/ExportManager-DUdis6se.js.map +1 -0
  12. package/dist/{FontAnalyzer-PE6nysqE.js → FontAnalyzer-DKG5JK0x.js} +1419 -1342
  13. package/dist/FontAnalyzer-DKG5JK0x.js.map +1 -0
  14. package/dist/{ImagePanel-CmQCxBGm.js → ImagePanel-CBgGqmVV.js} +53 -53
  15. package/dist/{ImagePanel-CmQCxBGm.js.map → ImagePanel-CBgGqmVV.js.map} +1 -1
  16. package/dist/SnowconeCanvas-BWPBngvI.js +1192 -0
  17. package/dist/SnowconeCanvas-BWPBngvI.js.map +1 -0
  18. package/dist/{UnifiedFontService-BJzoqfBF.js → UnifiedFontService-Co9tQ59z.js} +869 -826
  19. package/dist/UnifiedFontService-Co9tQ59z.js.map +1 -0
  20. package/dist/advanced.mjs +14 -14
  21. package/dist/api/embed.d.ts +2 -0
  22. package/dist/api/stable.d.ts +2 -0
  23. package/dist/components/CanvasContextMenu.d.ts +15 -0
  24. package/dist/components/CanvasEditor/hooks/useCanvasInteraction.d.ts +27 -0
  25. package/dist/components/CanvasEditor.d.ts +8 -0
  26. package/dist/components/embed/SnowconeCanvas.d.ts +13 -0
  27. package/dist/components/embed/kernel.d.ts +8 -0
  28. package/dist/components/toolbars/SecondaryPanels.d.ts +11 -0
  29. package/dist/components/ui/icons.d.ts +2 -0
  30. package/dist/contexts/CanvasServicesContext.d.ts +17 -0
  31. package/dist/contexts/EditorContext.d.ts +7 -0
  32. package/dist/core/TextElement.d.ts +13 -0
  33. package/dist/core/TextMetrics.d.ts +17 -3
  34. package/dist/core/rich-text-layout.d.ts +2 -0
  35. package/dist/core/text-spacing.d.ts +74 -0
  36. package/dist/{custom-icons-BWiUGqD6.js → custom-icons-BIaRovwG.js} +2 -2
  37. package/dist/{custom-icons-BWiUGqD6.js.map → custom-icons-BIaRovwG.js.map} +1 -1
  38. package/dist/{design-builder-bquxIHct.js → design-builder-JYLO_Hyi.js} +2 -2
  39. package/dist/{design-builder-bquxIHct.js.map → design-builder-JYLO_Hyi.js.map} +1 -1
  40. package/dist/{editorErrors-8uDRMhow.js → editorErrors-WzaNxU1Y.js} +181 -194
  41. package/dist/editorErrors-WzaNxU1Y.js.map +1 -0
  42. package/dist/{embed-L3oRIgsj.js → embed-Csez1hui.js} +113 -112
  43. package/dist/{embed-L3oRIgsj.js.map → embed-Csez1hui.js.map} +1 -1
  44. package/dist/embed.mjs +51 -45
  45. package/dist/embed.mjs.map +1 -1
  46. package/dist/errors/editorError.d.ts +8 -0
  47. package/dist/{guards-BlbhM5MX.js → guards-BSoX73yg.js} +2 -2
  48. package/dist/{guards-BlbhM5MX.js.map → guards-BSoX73yg.js.map} +1 -1
  49. package/dist/hooks/useKeyboardShortcuts.d.ts +15 -2
  50. package/dist/hooks/useLayers.d.ts +2 -0
  51. package/dist/hooks/useTextToolbar.d.ts +8 -0
  52. package/dist/index.mjs +42 -37
  53. package/dist/index.mjs.map +1 -1
  54. package/dist/internals.mjs +47 -47
  55. package/dist/rendering/renderer-types.d.ts +4 -0
  56. package/dist/rendering/rich-text-renderer.d.ts +4 -0
  57. package/dist/rendering/text-renderer.d.ts +4 -1
  58. package/dist/state/CanvasStateV1.d.ts +34 -3
  59. package/dist/state/index.d.ts +2 -2
  60. package/dist/{template-fields-ai7vnW8g.js → template-fields-DYPW7bVU.js} +40 -40
  61. package/dist/{template-fields-ai7vnW8g.js.map → template-fields-DYPW7bVU.js.map} +1 -1
  62. package/dist/testing.mjs +13 -13
  63. package/dist/types/index.d.ts +26 -0
  64. package/dist/{usePieceGuideBundle-CMe5br2a.js → usePieceGuideBundle-CRLY2iQa.js} +2 -2
  65. package/dist/{usePieceGuideBundle-CMe5br2a.js.map → usePieceGuideBundle-CRLY2iQa.js.map} +1 -1
  66. package/dist/utils/custom-fonts.d.ts +99 -0
  67. package/dist/utils/featureApplied.d.ts +6 -0
  68. package/dist/validation-BGEl9rrE.js +8686 -0
  69. package/dist/validation-BGEl9rrE.js.map +1 -0
  70. package/dist/workers/export-protocol.d.ts +13 -0
  71. package/dist/workers/export-worker.bundle.string.d.ts +1 -1
  72. package/example/package.json +1 -1
  73. package/package.json +1 -1
  74. package/dist/CanvasRenderer-B_3GISlW.js.map +0 -1
  75. package/dist/ContextualToolbars-C69oYLdw.js +0 -5771
  76. package/dist/ContextualToolbars-C69oYLdw.js.map +0 -1
  77. package/dist/ExportManager-J2xK86uq.js.map +0 -1
  78. package/dist/FontAnalyzer-PE6nysqE.js.map +0 -1
  79. package/dist/SnowconeCanvas-CQiFVR0X.js +0 -1173
  80. package/dist/SnowconeCanvas-CQiFVR0X.js.map +0 -1
  81. package/dist/UnifiedFontService-BJzoqfBF.js.map +0 -1
  82. package/dist/editorErrors-8uDRMhow.js.map +0 -1
  83. package/dist/validation-B8kIYutI.js +0 -8397
  84. package/dist/validation-B8kIYutI.js.map +0 -1
@@ -1,12 +1,12 @@
1
- import { c as N, G as pe, a2 as Me, a3 as Oe, a4 as Re, a5 as he, a6 as J, a7 as Ln, a0 as Be, a1 as Le, z as Hn, R as Ne, a8 as Ue, a9 as j, aa as ze, ab as $n, P as We, S as Ge, I as kn, M as He, W as Ve, H as je, D as qe, O as Xe, J as Ye, K as Ke, A as Vn } from "./FontAnalyzer-PE6nysqE.js";
2
- let be = null;
3
- function Je(e) {
4
- be = e;
1
+ import { c as U, G as xe, a5 as ze, a6 as Ge, a7 as He, a8 as ve, a9 as Gn, aa as Ve, ab as Q, a3 as je, a4 as qe, ac as on, ad as Hn, C as Jn, R as Xe, ae as Ye, af as q, ag as Ke, ah as wn, P as Je, S as Ze, I as An, Q as Qe, Y as nt, L as et, J as tt, W as at, M as rt, N as st, A as Zn, E as we } from "./FontAnalyzer-DKG5JK0x.js";
2
+ let Se = null;
3
+ function it(e) {
4
+ Se = e;
5
5
  }
6
- function xa() {
7
- return be;
6
+ function Da() {
7
+ return Se;
8
8
  }
9
- const Ze = N("TextureManager"), sn = class sn {
9
+ const ot = U("TextureManager"), ln = class ln {
10
10
  /**
11
11
  * Load a texture by ID or URL
12
12
  */
@@ -20,7 +20,7 @@ const Ze = N("TextureManager"), sn = class sn {
20
20
  s.crossOrigin = "anonymous", s.onload = () => {
21
21
  this.cache.set(n, s), this.cache.set(t, s), this.loading.delete(n), this.loading.delete(t), r(s);
22
22
  }, s.onerror = () => {
23
- Ze.error("Failed to load texture:", t), this.loading.delete(n), this.loading.delete(t), o(new Error(`Failed to load texture: ${t}`));
23
+ ot.error("Failed to load texture:", t), this.loading.delete(n), this.loading.delete(t), o(new Error(`Failed to load texture: ${t}`));
24
24
  }, s.src = t;
25
25
  });
26
26
  return this.loading.set(n, a), t !== n && this.loading.set(t, a), a;
@@ -86,7 +86,7 @@ const Ze = N("TextureManager"), sn = class sn {
86
86
  return (t == null ? void 0 : t.presetColor) || "#ffffff";
87
87
  }
88
88
  };
89
- sn.cache = /* @__PURE__ */ new Map(), sn.loading = /* @__PURE__ */ new Map(), sn.TEXTURES = [
89
+ ln.cache = /* @__PURE__ */ new Map(), ln.loading = /* @__PURE__ */ new Map(), ln.TEXTURES = [
90
90
  {
91
91
  id: "glass-frame",
92
92
  name: "Glass Frame",
@@ -96,33 +96,33 @@ sn.cache = /* @__PURE__ */ new Map(), sn.loading = /* @__PURE__ */ new Map(), sn
96
96
  // Light gray
97
97
  }
98
98
  ];
99
- let K = sn;
100
- const Qe = N("ElementPreviewRenderer"), nt = {
99
+ let Z = ln;
100
+ const ct = U("ElementPreviewRenderer"), lt = {
101
101
  width: 40,
102
102
  height: 40,
103
103
  padding: 4,
104
104
  backgroundColor: "transparent"
105
105
  };
106
- function et(e, n = {}) {
107
- Un();
108
- const t = { ...nt, ...n }, a = document.createElement("canvas");
106
+ function dt(e, n = {}) {
107
+ jn();
108
+ const t = { ...lt, ...n }, a = document.createElement("canvas");
109
109
  a.width = t.width, a.height = t.height;
110
110
  const r = a.getContext("2d");
111
111
  if (!r)
112
112
  return "";
113
113
  t.backgroundColor !== "transparent" && (r.fillStyle = t.backgroundColor, r.fillRect(0, 0, t.width, t.height)), r.save();
114
114
  try {
115
- e instanceof pe ? at(r, e, t) : tt(r, e, t);
115
+ e instanceof xe ? ut(r, e, t) : ft(r, e, t);
116
116
  } catch (o) {
117
- Qe.warn("Failed to generate preview:", o);
117
+ ct.warn("Failed to generate preview:", o);
118
118
  }
119
119
  return r.restore(), a.toDataURL("image/png");
120
120
  }
121
- function tt(e, n, t) {
121
+ function ft(e, n, t) {
122
122
  var f;
123
123
  const a = ((f = n.getBoundingBox) == null ? void 0 : f.call(n)) || { x: 0, y: 0, width: 100, height: 100 }, r = a.width, o = a.height;
124
124
  if (r === 0 || o === 0) {
125
- jn(e, n, t);
125
+ Qn(e, n, t);
126
126
  return;
127
127
  }
128
128
  const s = t.width - t.padding * 2, c = t.height - t.padding * 2, i = Math.min(
@@ -131,14 +131,14 @@ function tt(e, n, t) {
131
131
  1
132
132
  // Don't scale up, only down
133
133
  ), l = r * i, d = o * i, u = t.padding + (s - l) / 2, p = t.padding + (c - d) / 2;
134
- e.save(), e.translate(u - a.x * i, p - a.y * i), e.scale(i, i), typeof n.render == "function" ? n.render(e, !1, !1) : jn(e, n, t), e.restore();
134
+ e.save(), e.translate(u - a.x * i, p - a.y * i), e.scale(i, i), typeof n.render == "function" ? n.render(e, !1, !1) : Qn(e, n, t), e.restore();
135
135
  }
136
- function jn(e, n, t) {
136
+ function Qn(e, n, t) {
137
137
  e.fillStyle = "#888888", e.font = "10px Arial", e.textAlign = "center", e.textBaseline = "middle";
138
138
  const a = n.transformType || "Element";
139
139
  e.fillText(a, t.width / 2, t.height / 2);
140
140
  }
141
- function at(e, n, t) {
141
+ function ut(e, n, t) {
142
142
  const a = t.width - t.padding * 2, r = t.height - t.padding * 2, o = t.padding, s = t.padding;
143
143
  e.fillStyle = "#888888", e.strokeStyle = "#666666", e.lineWidth = 1;
144
144
  const c = r * 0.7, i = s + r * 0.3, l = a * 0.4, d = r * 0.2;
@@ -148,21 +148,21 @@ function at(e, n, t) {
148
148
  i + c / 2
149
149
  ));
150
150
  }
151
- function va(e, n, t) {
151
+ function Ma(e, n, t) {
152
152
  var l;
153
153
  e.translate(n.x || 0, n.y || 0), e.rotate(-(n.rotation || 0) * Math.PI / 180);
154
154
  const a = n, r = a.fontSize || 24, o = a.fontFamily || "Arial", s = a.bold || !1, c = a.italic || !1;
155
- e.font = Me(r, o, s, c);
155
+ e.font = ze(r, o, s, c);
156
156
  const i = a.text || "";
157
157
  if (n.transformType === "custom") {
158
- const u = ((l = n.transformData) == null ? void 0 : l.width) || 200, p = Oe(i, r, o, s, c), f = Math.min(p, u), m = r * 1.2;
159
- e.rect(-f / 2, -m / 2, f, m);
158
+ const u = ((l = n.transformData) == null ? void 0 : l.width) || 200, p = Ge(i, r, o, s, c), f = Math.min(p, u), $ = r * 1.2;
159
+ e.rect(-f / 2, -$ / 2, f, $);
160
160
  } else {
161
161
  const d = e.measureText(i).width;
162
162
  e.beginPath(), e.moveTo(-d / 2, 0), e.lineTo(d / 2, 0), e.moveTo(-d / 2, -r), e.lineTo(d / 2, -r), e.moveTo(-d / 2, r * 0.2), e.lineTo(d / 2, r * 0.2);
163
163
  }
164
164
  }
165
- function rt(e, n) {
165
+ function pt(e, n) {
166
166
  if (!n.transformData) return;
167
167
  const { borderRadius: t = 0 } = n.transformData, a = n.transformData.width ?? 100, r = n.transformData.height ?? 100;
168
168
  if (e.translate(n.x || 0, n.y || 0), e.rotate(-(n.rotation || 0) * Math.PI / 180), e.beginPath(), t > 0) {
@@ -171,22 +171,22 @@ function rt(e, n) {
171
171
  } else
172
172
  e.rect(-a / 2, -r / 2, a, r);
173
173
  }
174
- function wa(e, n, t, a) {
174
+ function Oa(e, n, t, a) {
175
175
  e.beginPath(), e.arc(n, t, a, 0, Math.PI * 2), e.closePath();
176
176
  }
177
- function Sa(e, n, t, a, r) {
177
+ function Ra(e, n, t, a, r) {
178
178
  e.beginPath(), e.rect(n, t, a, r), e.closePath();
179
179
  }
180
- function ge(e, n) {
180
+ function Ce(e, n) {
181
181
  e.strokeStyle = n.color, e.lineWidth = n.width, e.lineCap = n.lineCap || "butt", e.lineJoin = n.lineJoin || "miter", n.miterLimit !== void 0 && (e.miterLimit = n.miterLimit), n.dashArray && n.dashArray.length > 0 ? e.setLineDash(n.dashArray) : e.setLineDash([]), n.opacity !== void 0 && (e.globalAlpha = n.opacity);
182
182
  }
183
- function st(e, n) {
183
+ function ht(e, n) {
184
184
  if (typeof OffscreenCanvas < "u")
185
185
  return new OffscreenCanvas(e, n);
186
186
  const t = document.createElement("canvas");
187
187
  return t.width = e, t.height = n, t;
188
188
  }
189
- function me(e, n, t) {
189
+ function ke(e, n, t) {
190
190
  var i;
191
191
  if (!((i = n.stroke) != null && i.enabled)) return;
192
192
  const a = n;
@@ -194,148 +194,149 @@ function me(e, n, t) {
194
194
  const o = (t == null ? void 0 : t.isKnockout) === !0, s = n.stroke.opacity ?? 1;
195
195
  if (!o && s < 1)
196
196
  try {
197
- it(e, n, a, t, s);
197
+ bt(e, n, a, t, s);
198
198
  } catch {
199
- rn(e, n, a, t, !1);
199
+ cn(e, n, a, t, !1);
200
200
  }
201
201
  else
202
- rn(e, n, a, t, o);
202
+ cn(e, n, a, t, o);
203
203
  }
204
- function it(e, n, t, a, r) {
205
- var C, _;
206
- const o = t.text || "", s = t.fontSize || 24, c = n.stroke.width, i = n.stroke.feather || 0, l = n.transformType === "custom" && ((C = n.transformData) == null ? void 0 : C.width), d = l ? ((_ = n.transformData) == null ? void 0 : _.width) ?? 200 : 0, u = l ? d + c * 2 + i * 2 + 40 : s * o.length * 0.7 + c * 2 + i * 2 + 40, p = s * 3 + c * 2 + i * 2 + 40, f = e.getTransform(), m = Math.max(Math.abs(f.a), Math.abs(f.d), 1), b = Math.ceil(u * m / 2) * 2, h = Math.ceil(p * m / 2) * 2;
207
- if (b <= 0 || h <= 0) {
208
- rn(e, n, t, a, !1);
204
+ function bt(e, n, t, a, r) {
205
+ var k, _;
206
+ const o = t.text || "", s = t.fontSize || 24, c = n.stroke.width, i = n.stroke.feather || 0, l = n.transformType === "custom" && ((k = n.transformData) == null ? void 0 : k.width), d = l ? ((_ = n.transformData) == null ? void 0 : _.width) ?? 200 : 0, u = l ? d + c * 2 + i * 2 + 40 : s * o.length * 0.7 + c * 2 + i * 2 + 40, p = s * 3 + c * 2 + i * 2 + 40, f = e.getTransform(), $ = Math.max(Math.abs(f.a), Math.abs(f.d), 1), h = Math.ceil(u * $ / 2) * 2, b = Math.ceil(p * $ / 2) * 2;
207
+ if (h <= 0 || b <= 0) {
208
+ cn(e, n, t, a, !1);
209
209
  return;
210
210
  }
211
- const S = st(b, h), $ = S.getContext("2d");
212
- if (!$) {
213
- rn(e, n, t, a, !1);
211
+ const v = ht(h, b), y = v.getContext("2d");
212
+ if (!y) {
213
+ cn(e, n, t, a, !1);
214
214
  return;
215
215
  }
216
- const v = n.x || 0, g = n.y || 0, y = f.a * v + f.c * g + f.e, k = f.b * v + f.d * g + f.f;
217
- $.setTransform(
216
+ const x = n.x || 0, m = n.y || 0, g = f.a * x + f.c * m + f.e, C = f.b * x + f.d * m + f.f;
217
+ y.setTransform(
218
218
  f.a,
219
219
  f.b,
220
220
  f.c,
221
221
  f.d,
222
- b / 2 - y + f.e,
223
- h / 2 - k + f.f
222
+ h / 2 - g + f.e,
223
+ b / 2 - C + f.f
224
224
  );
225
225
  const T = n.stroke.opacity;
226
- n.stroke.opacity = 1, rn($, n, t, a, !1), n.stroke.opacity = T, e.save(), e.resetTransform(), e.globalAlpha = r, e.drawImage(
227
- S,
228
- Math.round(y - b / 2),
229
- Math.round(k - h / 2)
226
+ n.stroke.opacity = 1, cn(y, n, t, a, !1), n.stroke.opacity = T, e.save(), e.resetTransform(), e.globalAlpha = r, e.drawImage(
227
+ v,
228
+ Math.round(g - h / 2),
229
+ Math.round(C - b / 2)
230
230
  ), e.restore();
231
231
  }
232
- function rn(e, n, t, a, r) {
232
+ function cn(e, n, t, a, r) {
233
233
  var f;
234
234
  const o = t.text || "";
235
235
  e.save(), a != null && a.positionApplied || (e.translate(n.x || 0, n.y || 0), e.rotate(-(n.rotation || 0) * Math.PI / 180));
236
236
  const s = t.fontSize || 24, c = t.fontFamily || "Arial", i = t.bold || !1, l = t.italic || !1, d = t.textAlign || "center";
237
237
  e.font = `${l ? "italic " : ""}${i ? "bold " : ""}${s}px ${c}`, e.textAlign = d, e.textBaseline = "alphabetic", r ? (e.strokeStyle = "#000000", e.globalAlpha = 1) : (e.strokeStyle = n.stroke.color, n.stroke.opacity !== void 0 && (e.globalAlpha = n.stroke.opacity)), e.lineWidth = n.stroke.width, e.lineCap = n.stroke.lineCap || "round", e.lineJoin = n.stroke.lineJoin || "round", n.stroke.miterLimit !== void 0 && (e.miterLimit = n.stroke.miterLimit), !r && n.stroke.feather && n.stroke.feather > 0 && "filter" in e && (e.filter = `blur(${n.stroke.feather}px)`);
238
- const u = Re(s, c, i, l);
238
+ const u = He(s, c, i, l);
239
239
  if (n.transformType === "custom" && ((f = n.transformData) == null ? void 0 : f.width)) {
240
- const m = n.transformData, b = (m == null ? void 0 : m.width) ?? 200, h = b - J * 2, { lines: S, height: $ } = he(
240
+ const $ = n.transformData, h = ($ == null ? void 0 : $.width) ?? 200, b = h - Q * 2, v = t.letterSpacing ?? 0, { lines: y, height: x } = ve(
241
241
  o,
242
- h,
242
+ b,
243
243
  s,
244
244
  c,
245
245
  i,
246
246
  l,
247
247
  void 0,
248
248
  // No locked line count for stroke
249
- !0
249
+ !0,
250
250
  // strict: wrap exactly at maxWidth
251
- ), v = -b / 2, g = -$ / 2, y = s * Ln;
252
- S.forEach((k, T) => {
253
- const C = T === 0, _ = T === S.length - 1;
254
- let w = k;
255
- if (!C) {
256
- const P = k.match(/^ +/), A = P ? P[0].length : 0;
257
- A > 0 && (w = w.substring(A));
258
- }
251
+ { letterSpacing: v, lineHeight: t.lineHeight }
252
+ ), m = -h / 2, g = -x / 2, C = s * (t.lineHeight ?? Gn);
253
+ y.forEach((T, k) => {
254
+ const _ = k === 0, w = k === y.length - 1;
255
+ let A = T;
259
256
  if (!_) {
260
- const P = w.match(/ +$/), A = P ? P[0].length : 0;
261
- A > 0 && (w = w.substring(0, w.length - A));
257
+ const P = T.match(/^ +/), I = P ? P[0].length : 0;
258
+ I > 0 && (A = A.substring(I));
259
+ }
260
+ if (!w) {
261
+ const P = A.match(/ +$/), I = P ? P[0].length : 0;
262
+ I > 0 && (A = A.substring(0, A.length - I));
262
263
  }
263
- let E = v + J;
264
- d === "center" ? E = v + b / 2 : d === "right" && (E = v + b - J);
265
- const x = g + u.ascent + T * y;
266
- e.strokeText(w, E, x);
264
+ let E = m + Q;
265
+ d === "center" ? E = m + h / 2 : d === "right" && (E = m + h - Q);
266
+ const S = g + u.ascent + k * C;
267
+ Ve(e, A, E, S, v);
267
268
  });
268
269
  } else {
269
- const h = -u.height / 2 + u.ascent;
270
- e.strokeText(o, 0, h);
270
+ const b = -u.height / 2 + u.ascent;
271
+ e.strokeText(o, 0, b);
271
272
  }
272
273
  e.restore();
273
274
  }
274
- function ot(e, n, t) {
275
+ function gt(e, n, t) {
275
276
  var r;
276
277
  if (!((r = n.stroke) != null && r.enabled) || !n.transformData) return;
277
278
  const a = (t == null ? void 0 : t.isKnockout) === !0;
278
- e.save(), a ? (e.strokeStyle = "#000000", e.lineWidth = n.stroke.width, e.lineCap = n.stroke.lineCap || "butt", e.lineJoin = n.stroke.lineJoin || "miter", e.globalAlpha = 1, n.stroke.miterLimit !== void 0 && (e.miterLimit = n.stroke.miterLimit)) : ge(e, n.stroke), !a && n.stroke.feather && n.stroke.feather > 0 && "filter" in e && (e.filter = `blur(${n.stroke.feather}px)`), rt(e, n), e.stroke(), e.restore();
279
+ e.save(), a ? (e.strokeStyle = "#000000", e.lineWidth = n.stroke.width, e.lineCap = n.stroke.lineCap || "butt", e.lineJoin = n.stroke.lineJoin || "miter", e.globalAlpha = 1, n.stroke.miterLimit !== void 0 && (e.miterLimit = n.stroke.miterLimit)) : Ce(e, n.stroke), !a && n.stroke.feather && n.stroke.feather > 0 && "filter" in e && (e.filter = `blur(${n.stroke.feather}px)`), pt(e, n), e.stroke(), e.restore();
279
280
  }
280
- function Ca(e, n, t) {
281
- n.enabled && (e.save(), ge(e, n), n.feather && n.feather > 0 && "filter" in e && (e.filter = `blur(${n.feather}px)`), e.beginPath(), t(), e.stroke(), e.restore());
281
+ function Ba(e, n, t) {
282
+ n.enabled && (e.save(), Ce(e, n), n.feather && n.feather > 0 && "filter" in e && (e.filter = `blur(${n.feather}px)`), e.beginPath(), t(), e.stroke(), e.restore());
282
283
  }
283
- const qn = N("GlyphRenderer");
284
- function ct(e, n, t, a, r, o, s, c = {}) {
284
+ const ne = U("GlyphRenderer");
285
+ function mt(e, n, t, a, r, o, s, c = {}) {
285
286
  try {
286
287
  const i = [];
287
- Object.entries(s).forEach(([h, S]) => {
288
- S && i.push(h);
288
+ Object.entries(s).forEach(([b, v]) => {
289
+ v && i.push(b);
289
290
  });
290
291
  const l = [];
291
- n.GSUB && n.GSUB.featureList && n.GSUB.featureList.forEach((h) => {
292
- l.push(h.tag);
292
+ n.GSUB && n.GSUB.featureList && n.GSUB.featureList.forEach((b) => {
293
+ l.push(b.tag);
293
294
  });
294
295
  const d = {};
295
- d.ccmp = !0, d.locl = !0, d.kern = !0, i.forEach((h) => {
296
- d[h] = !0;
296
+ d.ccmp = !0, d.locl = !0, d.kern = !0, i.forEach((b) => {
297
+ d[b] = !0;
297
298
  }), d.calt && (d.liga = !0, d.init = !0, d.fina = !0);
298
299
  const u = n.layout(t, d, "latn"), p = o / n.unitsPerEm;
299
300
  let f = 0;
300
- u.glyphs.forEach((h) => {
301
- f += h.advanceWidth * p;
301
+ u.glyphs.forEach((b) => {
302
+ f += b.advanceWidth * p;
302
303
  });
303
- let m = a;
304
- c.align === "center" ? m = a - f / 2 : c.align === "right" && (m = a - f), e.save(), e.fillStyle = c.color || "#000000";
305
- let b = m;
306
- u.glyphs.forEach((h, S) => {
307
- const $ = u.positions[S];
308
- let v = null;
304
+ let $ = a;
305
+ c.align === "center" ? $ = a - f / 2 : c.align === "right" && ($ = a - f), e.save(), e.fillStyle = c.color || "#000000";
306
+ let h = $;
307
+ u.glyphs.forEach((b, v) => {
308
+ const y = u.positions[v];
309
+ let x = null;
309
310
  try {
310
- if (h.path && typeof h.path.toPath == "function")
311
- v = h.path.toPath();
312
- else if (h.path && typeof h.path.toSVG == "function") {
313
- const g = h.path.toSVG();
314
- if (g && /^[MmLlHhVvCcSsQqTtAaZz]/.test(g))
315
- v = g;
311
+ if (b.path && typeof b.path.toPath == "function")
312
+ x = b.path.toPath();
313
+ else if (b.path && typeof b.path.toSVG == "function") {
314
+ const m = b.path.toSVG();
315
+ if (m && /^[MmLlHhVvCcSsQqTtAaZz]/.test(m))
316
+ x = m;
316
317
  else {
317
- const y = g == null ? void 0 : g.match(/\bd=["']([^"']+)["']/);
318
- v = y ? y[1] : null;
318
+ const g = m == null ? void 0 : m.match(/\bd=["']([^"']+)["']/);
319
+ x = g ? g[1] : null;
319
320
  }
320
321
  }
321
- } catch (g) {
322
- qn.warn("Error getting path for glyph:", h.name, g);
322
+ } catch (m) {
323
+ ne.warn("Error getting path for glyph:", b.name, m);
323
324
  }
324
- if (v) {
325
- const g = new Path2D(v);
326
- e.save(), e.translate(b + $.xOffset * p, r + $.yOffset * p), e.scale(p, -p), e.fill(g), e.restore();
325
+ if (x) {
326
+ const m = new Path2D(x);
327
+ e.save(), e.translate(h + y.xOffset * p, r + y.yOffset * p), e.scale(p, -p), e.fill(m), e.restore();
327
328
  }
328
- b += h.advanceWidth * p;
329
+ h += b.advanceWidth * p;
329
330
  }), e.restore();
330
331
  } catch (i) {
331
- qn.error("Error rendering with fontkit:", i), e.fillStyle = c.color || "#000000", e.textAlign = c.align || "left", e.fillText(t, a, r);
332
+ ne.error("Error rendering with fontkit:", i), e.fillStyle = c.color || "#000000", e.textAlign = c.align || "left", e.fillText(t, a, r);
332
333
  }
333
334
  }
334
- function lt(e, n, t, a, r, o, s, c = {}) {
335
- const l = ((h) => {
336
- for (const S of h) {
337
- const $ = S.codePointAt(0);
338
- if ($ && $ >= 983040 && $ <= 1048573) return !0;
335
+ function yt(e, n, t, a, r, o, s, c = {}) {
336
+ const l = ((b) => {
337
+ for (const v of b) {
338
+ const y = v.codePointAt(0);
339
+ if (y && y >= 983040 && y <= 1048573) return !0;
339
340
  }
340
341
  return !1;
341
342
  })(t);
@@ -344,172 +345,177 @@ function lt(e, n, t, a, r, o, s, c = {}) {
344
345
  return;
345
346
  }
346
347
  const d = /* @__PURE__ */ new Map();
347
- s && s.forEach((h) => {
348
- d.set(h.charIndex, h.glyphIndex);
348
+ s && s.forEach((b) => {
349
+ d.set(b.charIndex, b.glyphIndex);
349
350
  });
350
351
  const u = o / n.unitsPerEm, p = Array.from(t);
351
352
  let f = 0;
352
- p.forEach((h, S) => {
353
- const $ = h.codePointAt(0) || 0;
354
- let v;
355
- if ($ >= 983040 && $ <= 1048573)
356
- v = $ - 983040;
357
- else if (v = d.get(S), v === void 0) {
358
- const y = n.glyphForCodePoint($);
359
- v = y ? y.id : 0;
360
- }
361
- const g = n.getGlyph(v);
362
- g && (f += g.advanceWidth * u);
353
+ p.forEach((b, v) => {
354
+ const y = b.codePointAt(0) || 0;
355
+ let x;
356
+ if (y >= 983040 && y <= 1048573)
357
+ x = y - 983040;
358
+ else if (x = d.get(v), x === void 0) {
359
+ const g = n.glyphForCodePoint(y);
360
+ x = g ? g.id : 0;
361
+ }
362
+ const m = n.getGlyph(x);
363
+ m && (f += m.advanceWidth * u);
363
364
  });
364
- let m = a;
365
- c.align === "center" ? m = a - f / 2 : c.align === "right" && (m = a - f), e.save(), e.fillStyle = c.color || "#000000";
366
- let b = m;
367
- p.forEach((h, S) => {
368
- const $ = h.codePointAt(0) || 0;
369
- let v;
370
- if ($ >= 983040 && $ <= 1048573)
371
- v = $ - 983040;
372
- else if (v = d.get(S), v === void 0) {
373
- const y = n.glyphForCodePoint($);
374
- v = y ? y.id : 0;
375
- }
376
- const g = n.getGlyph(v);
377
- if (g) {
378
- const y = g.path.toSVG();
379
- if (y) {
380
- const k = new Path2D(y);
381
- e.save(), e.translate(b, r), e.scale(u, -u), e.fill(k), e.restore();
365
+ let $ = a;
366
+ c.align === "center" ? $ = a - f / 2 : c.align === "right" && ($ = a - f), e.save(), e.fillStyle = c.color || "#000000";
367
+ let h = $;
368
+ p.forEach((b, v) => {
369
+ const y = b.codePointAt(0) || 0;
370
+ let x;
371
+ if (y >= 983040 && y <= 1048573)
372
+ x = y - 983040;
373
+ else if (x = d.get(v), x === void 0) {
374
+ const g = n.glyphForCodePoint(y);
375
+ x = g ? g.id : 0;
376
+ }
377
+ const m = n.getGlyph(x);
378
+ if (m) {
379
+ const g = m.path.toSVG();
380
+ if (g) {
381
+ const C = new Path2D(g);
382
+ e.save(), e.translate(h, r), e.scale(u, -u), e.fill(C), e.restore();
382
383
  }
383
- b += g.advanceWidth * u;
384
+ h += m.advanceWidth * u;
384
385
  }
385
386
  }), e.restore();
386
387
  }
387
- function dt(e, n, t, a, r) {
388
+ function $t(e, n, t, a, r) {
388
389
  e.fillStyle = t.color;
389
- const o = t.textAlign || "center", s = Be(n);
390
- let c, i;
391
- a !== void 0 && a > 0 && !r ? (c = [], i = [], s.forEach((m) => {
392
- const b = Le(m, a, t);
393
- b.forEach((h, S) => {
394
- c.push(h), i.push({
395
- isParagraphStart: S === 0,
396
- isParagraphEnd: S === b.length - 1
390
+ const o = t.textAlign || "center", s = (h) => h.letterSpacing !== void 0 ? h.letterSpacing : t.letterSpacing ?? 0, c = je(n);
391
+ let i, l;
392
+ a !== void 0 && a > 0 && !r ? (i = [], l = [], c.forEach((h) => {
393
+ const b = qe(h, a, t);
394
+ b.forEach((v, y) => {
395
+ i.push(v), l.push({
396
+ isParagraphStart: y === 0,
397
+ isParagraphEnd: y === b.length - 1
397
398
  });
398
399
  });
399
- })) : (c = s, i = s.map(() => ({
400
+ })) : (i = c, l = c.map(() => ({
400
401
  isParagraphStart: !0,
401
402
  isParagraphEnd: !0
402
403
  })));
403
- const l = [];
404
- c.forEach((m, b) => {
405
- const h = [];
406
- let S = 0, $ = 0;
407
- const v = i[b].isParagraphStart, g = i[b].isParagraphEnd;
408
- m.forEach((x) => {
409
- const P = x.style.fontSize !== void 0 ? x.style.fontSize : t.fontSize, A = x.style.fontFamily !== void 0 ? x.style.fontFamily : t.fontFamily, F = x.style.bold !== void 0 ? x.style.bold : t.bold || !1, D = x.style.italic !== void 0 ? x.style.italic : t.italic || !1;
410
- e.font = R(P, A, F, D);
411
- const I = e.measureText(x.text).width;
412
- h.push(I);
413
- const M = cn(P, A, F, D);
414
- S = Math.max(S, M.height), $ = Math.max($, M.ascent);
404
+ const d = [];
405
+ i.forEach((h, b) => {
406
+ const v = [];
407
+ let y = 0, x = 0;
408
+ const m = l[b].isParagraphStart, g = l[b].isParagraphEnd;
409
+ h.forEach((S) => {
410
+ const P = S.style.fontSize !== void 0 ? S.style.fontSize : t.fontSize, I = S.style.fontFamily !== void 0 ? S.style.fontFamily : t.fontFamily, F = S.style.bold !== void 0 ? S.style.bold : t.bold || !1, D = S.style.italic !== void 0 ? S.style.italic : t.italic || !1;
411
+ e.font = B(P, I, F, D);
412
+ const M = on(e.measureText(S.text).width, S.text, s(S.style));
413
+ v.push(M);
414
+ const L = fn(P, I, F, D);
415
+ y = Math.max(y, L.height), x = Math.max(x, L.ascent);
415
416
  });
416
- const y = m.map((x) => x.text).join(""), k = y.match(/^ +/), T = y.match(/ +$/), C = k ? k[0].length : 0, _ = T ? T[0].length : 0;
417
- let w = 0, E = 0;
418
- m.forEach((x) => {
419
- const P = x.style.fontSize !== void 0 ? x.style.fontSize : t.fontSize, A = x.style.fontFamily !== void 0 ? x.style.fontFamily : t.fontFamily, F = x.style.bold !== void 0 ? x.style.bold : t.bold || !1, D = x.style.italic !== void 0 ? x.style.italic : t.italic || !1;
420
- let I = x.text;
421
- const M = E, en = E + x.text.length;
422
- if (!v && C > 0 && M < C) {
423
- const B = Math.min(C - M, x.text.length);
424
- I = I.substring(B);
417
+ const C = h.map((S) => S.text).join(""), T = C.match(/^ +/), k = C.match(/ +$/), _ = T ? T[0].length : 0, w = k ? k[0].length : 0;
418
+ let A = 0, E = 0;
419
+ h.forEach((S) => {
420
+ const P = S.style.fontSize !== void 0 ? S.style.fontSize : t.fontSize, I = S.style.fontFamily !== void 0 ? S.style.fontFamily : t.fontFamily, F = S.style.bold !== void 0 ? S.style.bold : t.bold || !1, D = S.style.italic !== void 0 ? S.style.italic : t.italic || !1;
421
+ let M = S.text;
422
+ const L = E, kn = E + S.text.length;
423
+ if (!m && _ > 0 && L < _) {
424
+ const R = Math.min(_ - L, S.text.length);
425
+ M = M.substring(R);
425
426
  }
426
- if (!g && _ > 0) {
427
- const B = y.length - _;
428
- if (en > B) {
429
- const H = !v && C > 0 && M < C ? Math.min(C - M, x.text.length) : 0, wn = Math.max(0, B - M - H);
430
- I = I.substring(0, wn);
427
+ if (!g && w > 0) {
428
+ const R = C.length - w;
429
+ if (kn > R) {
430
+ const H = !m && _ > 0 && L < _ ? Math.min(_ - L, S.text.length) : 0, Tn = Math.max(0, R - L - H);
431
+ M = M.substring(0, Tn);
431
432
  }
432
433
  }
433
- E += x.text.length, I.length > 0 && (e.save(), e.font = R(P, A, F, D), w += e.measureText(I).width, e.restore());
434
- }), l.push({
435
- spans: m,
436
- width: w,
434
+ E += S.text.length, M.length > 0 && (e.save(), e.font = B(P, I, F, D), A += on(
435
+ e.measureText(M).width,
436
+ M,
437
+ s(S.style)
438
+ ), e.restore());
439
+ }), d.push({
440
+ spans: h,
441
+ width: A,
437
442
  // Use adjusted width for alignment (may be 0 for empty lines)
438
- height: S,
439
- ascent: $,
440
- spanWidths: h,
441
- isParagraphStart: v,
443
+ height: y,
444
+ ascent: x,
445
+ spanWidths: v,
446
+ isParagraphStart: m,
442
447
  // Store metadata with line
443
448
  isParagraphEnd: g
444
449
  });
445
450
  });
446
- const d = cn(t.fontSize, t.fontFamily, t.bold, t.italic), u = t.fontSize * Ln;
447
- let p;
448
- l.length === 0 ? p = 0 : l.length === 1 ? p = d.height : p = (l.length - 1) * u + d.height;
449
- const f = -p / 2;
450
- l.forEach((m, b) => {
451
- const { spans: h, width: S, isParagraphStart: $, isParagraphEnd: v } = m;
451
+ const u = fn(t.fontSize, t.fontFamily, t.bold, t.italic), p = t.fontSize * (t.lineHeight ?? Gn);
452
+ let f;
453
+ d.length === 0 ? f = 0 : d.length === 1 ? f = u.height : f = (d.length - 1) * p + u.height;
454
+ const $ = -f / 2;
455
+ d.forEach((h, b) => {
456
+ const { spans: v, width: y, isParagraphStart: x, isParagraphEnd: m } = h;
452
457
  let g;
453
- o === "center" ? g = -S / 2 : o === "right" ? g = a !== void 0 ? a / 2 - S : -S : g = a !== void 0 ? -a / 2 : 0;
454
- const y = f + d.ascent + b * u, k = h.map((x) => x.text).join(""), T = k.match(/^ +/), C = k.match(/ +$/), _ = T ? T[0].length : 0, w = C ? C[0].length : 0;
458
+ o === "center" ? g = -y / 2 : o === "right" ? g = a !== void 0 ? a / 2 - y : -y : g = a !== void 0 ? -a / 2 : 0;
459
+ const C = $ + u.ascent + b * p, T = v.map((S) => S.text).join(""), k = T.match(/^ +/), _ = T.match(/ +$/), w = k ? k[0].length : 0, A = _ ? _[0].length : 0;
455
460
  let E = 0;
456
- h.forEach((x) => {
457
- const P = x.style.fontSize !== void 0 ? x.style.fontSize : t.fontSize, A = x.style.fontFamily !== void 0 ? x.style.fontFamily : t.fontFamily, F = x.style.color !== void 0 ? x.style.color : t.color, D = x.style.bold !== void 0 ? x.style.bold : t.bold || !1, I = x.style.italic !== void 0 ? x.style.italic : t.italic || !1, M = x.style.underline !== void 0 ? x.style.underline : t.underline || !1, en = x.style.strikethrough !== void 0 ? x.style.strikethrough : t.strikethrough || !1;
458
- let B = x.text, H = E, wn = E + x.text.length;
459
- if (!$ && _ > 0 && H < _) {
460
- const U = Math.min(_ - H, x.text.length);
461
- B = B.substring(U);
461
+ v.forEach((S) => {
462
+ const P = S.style.fontSize !== void 0 ? S.style.fontSize : t.fontSize, I = S.style.fontFamily !== void 0 ? S.style.fontFamily : t.fontFamily, F = S.style.color !== void 0 ? S.style.color : t.color, D = S.style.bold !== void 0 ? S.style.bold : t.bold || !1, M = S.style.italic !== void 0 ? S.style.italic : t.italic || !1, L = S.style.underline !== void 0 ? S.style.underline : t.underline || !1, kn = S.style.strikethrough !== void 0 ? S.style.strikethrough : t.strikethrough || !1;
463
+ let R = S.text, H = E, Tn = E + S.text.length;
464
+ if (!x && w > 0 && H < w) {
465
+ const V = Math.min(w - H, S.text.length);
466
+ R = R.substring(V);
462
467
  }
463
- if (!v && w > 0) {
464
- const U = k.length - w;
465
- if (wn > U) {
466
- const V = !$ && _ > 0 && H < _ ? Math.min(_ - H, x.text.length) : 0, Fe = Math.max(0, U - H - V);
467
- B = B.substring(0, Fe);
468
+ if (!m && A > 0) {
469
+ const V = T.length - A;
470
+ if (Tn > V) {
471
+ const an = !x && w > 0 && H < w ? Math.min(w - H, S.text.length) : 0, j = Math.max(0, V - H - an);
472
+ R = R.substring(0, j);
468
473
  }
469
474
  }
470
- if (E += x.text.length, B.length > 0) {
471
- e.font = R(P, A, D, I), e.fillStyle = F, e.textBaseline = "alphabetic", e.textAlign = "left", e.fillText(B, g, y);
472
- const U = e.measureText(B).width;
473
- if (M) {
474
- const V = y + P * 0.1;
475
- e.beginPath(), e.moveTo(g, V), e.lineTo(g + U, V), e.lineWidth = Math.max(1, P * 0.05), e.strokeStyle = F, e.stroke();
476
- }
477
- if (en) {
478
- const V = y - P * 0.25;
479
- e.beginPath(), e.moveTo(g, V), e.lineTo(g + U, V), e.lineWidth = Math.max(1, P * 0.05), e.strokeStyle = F, e.stroke();
480
- }
481
- g += U;
475
+ if (E += S.text.length, R.length > 0) {
476
+ const V = s(S.style);
477
+ e.font = B(P, I, D, M), e.fillStyle = F, e.textBaseline = "alphabetic", e.textAlign = "left", Hn(e, R, g, C, V);
478
+ const an = on(e.measureText(R).width, R, V);
479
+ if (L) {
480
+ const j = C + P * 0.1;
481
+ e.beginPath(), e.moveTo(g, j), e.lineTo(g + an, j), e.lineWidth = Math.max(1, P * 0.05), e.strokeStyle = F, e.stroke();
482
+ }
483
+ if (kn) {
484
+ const j = C - P * 0.25;
485
+ e.beginPath(), e.moveTo(g, j), e.lineTo(g + an, j), e.lineWidth = Math.max(1, P * 0.05), e.strokeStyle = F, e.stroke();
486
+ }
487
+ g += an;
482
488
  }
483
489
  });
484
490
  });
485
491
  }
486
- const Tn = N("canvas-renderer");
487
- let fn = null;
488
- function Nn() {
489
- if (!fn)
492
+ const Pn = U("canvas-renderer");
493
+ let hn = null;
494
+ function Vn() {
495
+ if (!hn)
490
496
  if (typeof OffscreenCanvas < "u")
491
- fn = new OffscreenCanvas(1, 1).getContext("2d");
497
+ hn = new OffscreenCanvas(1, 1).getContext("2d");
492
498
  else if (typeof document < "u")
493
- fn = document.createElement("canvas").getContext("2d");
499
+ hn = document.createElement("canvas").getContext("2d");
494
500
  else
495
501
  throw new Error("No canvas context available");
496
- return fn;
502
+ return hn;
497
503
  }
498
- function R(e, n, t = !1, a = !1) {
504
+ function B(e, n, t = !1, a = !1) {
499
505
  const r = [];
500
506
  return a && r.push("italic"), t && r.push("bold"), r.push(`${e}px`), r.push(n), r.join(" ");
501
507
  }
502
- function Xn(e, n, t, a = !1, r = !1) {
503
- const o = Nn();
504
- return o.font = R(n, t, a, r), o.measureText(e).width;
508
+ function ee(e, n, t, a = !1, r = !1, o = 0) {
509
+ const s = Vn();
510
+ return s.font = B(n, t, a, r), on(s.measureText(e).width, e, o);
505
511
  }
506
- function cn(e, n, t = !1, a = !1) {
507
- const r = Nn();
508
- r.font = R(e, n, t, a);
512
+ function fn(e, n, t = !1, a = !1) {
513
+ const r = Vn();
514
+ r.font = B(e, n, t, a);
509
515
  const s = r.measureText("ÁÉÍgjpqy"), c = s.actualBoundingBoxAscent || e * 0.8, i = s.actualBoundingBoxDescent || e * 0.2, l = c + i;
510
516
  return { ascent: c, descent: i, height: l };
511
517
  }
512
- function ka(e, n) {
518
+ function La(e, n) {
513
519
  const t = e.map((r, o) => ({
514
520
  isParagraphStart: !n && o === 0,
515
521
  isParagraphEnd: !n && o === e.length - 1
@@ -522,23 +528,23 @@ function ka(e, n) {
522
528
  return s || (i = i.replace(/^ +/, "")), c || (i = i.replace(/ +$/, "")), i;
523
529
  }).filter((r) => r.length > 0);
524
530
  }
525
- function ft(e, n) {
531
+ function xt(e, n) {
526
532
  const t = n.fontSize, a = n.fontFamily, r = n.bold || !1, o = n.italic || !1, s = n.textAlign || "center", c = n.text;
527
- e.font = R(t, a, r, o), e.textAlign = s, e.textBaseline = "alphabetic", e.fillStyle = n.color;
528
- const i = cn(t, a, r, o), u = -i.height / 2 + i.ascent;
529
- e.fillText(c, 0, u);
533
+ e.font = B(t, a, r, o), e.textAlign = s, e.textBaseline = "alphabetic", e.fillStyle = n.color;
534
+ const i = fn(t, a, r, o), u = -i.height / 2 + i.ascent;
535
+ Hn(e, c, 0, u, n.letterSpacing);
530
536
  }
531
- function ut(e, n, t, a, r = !1, o = !1, s) {
532
- const c = Nn();
533
- if (c.font = R(t, a, r, o), e.trim().length === 0)
537
+ function vt(e, n, t, a, r = !1, o = !1, s) {
538
+ const c = Vn();
539
+ if (c.font = B(t, a, r, o), e.trim().length === 0)
534
540
  return [e];
535
541
  if (e.includes(`
536
542
  `)) {
537
- const C = e.split(`
543
+ const k = e.split(`
538
544
  `), _ = [];
539
- for (let w = 0; w < C.length; w++) {
540
- const E = C[w], x = ut(E, n, t, a, r, o);
541
- _.push(...x);
545
+ for (let w = 0; w < k.length; w++) {
546
+ const A = k[w], E = vt(A, n, t, a, r, o);
547
+ _.push(...E);
542
548
  }
543
549
  return _;
544
550
  }
@@ -546,87 +552,87 @@ function ut(e, n, t, a, r = !1, o = !1, s) {
546
552
  if (s !== void 0 && s > 0) {
547
553
  if (s === 1)
548
554
  return [d + f.join(" ") + u];
549
- const C = [], _ = Math.ceil(f.length / s);
555
+ const k = [], _ = Math.ceil(f.length / s);
550
556
  for (let w = 0; w < f.length; w += _) {
551
- const x = f.slice(w, w + _).join(" ");
552
- w === 0 && w + _ >= f.length ? C.push(d + x + u) : w === 0 ? C.push(d + x) : w + _ >= f.length ? C.push(x + u) : C.push(x);
553
- }
554
- return C;
555
- }
556
- const m = f.join(" "), b = d + m + u, h = c.measureText(b).width, S = n < 200, v = Math.max(20, n * (S ? 0.08 : 0.05));
557
- if (h <= n + v)
558
- return [b];
559
- const g = [];
560
- let y = f[0];
561
- const T = Math.max(15, n * (S ? 0.05 : 0.03));
562
- for (let C = 1; C < f.length; C++) {
563
- const _ = f[C], w = y + " " + _;
564
- c.measureText(w).width > n + T ? (g.push(y), y = _) : y = w;
565
- }
566
- return g.push(y), g.length > 0 && (g[0] = d + g[0], g[g.length - 1] = g[g.length - 1] + u), g;
557
+ const E = f.slice(w, w + _).join(" ");
558
+ w === 0 && w + _ >= f.length ? k.push(d + E + u) : w === 0 ? k.push(d + E) : w + _ >= f.length ? k.push(E + u) : k.push(E);
559
+ }
560
+ return k;
561
+ }
562
+ const $ = f.join(" "), h = d + $ + u, b = c.measureText(h).width, v = n < 200, x = Math.max(20, n * (v ? 0.08 : 0.05));
563
+ if (b <= n + x)
564
+ return [h];
565
+ const m = [];
566
+ let g = f[0];
567
+ const T = Math.max(15, n * (v ? 0.05 : 0.03));
568
+ for (let k = 1; k < f.length; k++) {
569
+ const _ = f[k], w = g + " " + _;
570
+ c.measureText(w).width > n + T ? (m.push(g), g = _) : g = w;
571
+ }
572
+ return m.push(g), m.length > 0 && (m[0] = d + m[0], m[m.length - 1] = m[m.length - 1] + u), m;
567
573
  }
568
- function Ta(e, n, t, a, r, o, s = "left", c = 0, i = 0, l = 1.2, d = !1, u = !1, p = !1, f = !1, m, b) {
569
- e.font = R(r, o, d, u), e.textBaseline = "alphabetic", e.textAlign = s;
570
- const h = (w) => {
571
- for (const E of w) {
572
- const x = E.codePointAt(0);
573
- if (x && x >= 983040 && x <= 1048573)
574
+ function Na(e, n, t, a, r, o, s = "left", c = 0, i = 0, l = 1.2, d = !1, u = !1, p = !1, f = !1, $, h) {
575
+ e.font = B(r, o, d, u), e.textBaseline = "alphabetic", e.textAlign = s;
576
+ const b = (w) => {
577
+ for (const A of w) {
578
+ const E = A.codePointAt(0);
579
+ if (E && E >= 983040 && E <= 1048573)
574
580
  return !0;
575
581
  }
576
582
  return !1;
577
- }, S = m && Object.values(m).some((w) => w), $ = b && b.length > 0, v = n.join(" "), g = h(v), y = S || $ || g, k = y ? Hn.getFontSync(o, d ? 700 : 400) : null;
578
- y && !k && (Tn.warn(
579
- `[renderMultilineText] Font ${o} not loaded for fontkit rendering. Text may not render correctly. Has PUA: ${g}, Text: "${v}"`
580
- ), Hn.loadFont(o, d ? 700 : 400).catch((w) => {
581
- Tn.error("[renderMultilineText] Error loading font:", w);
583
+ }, v = $ && Object.values($).some((w) => w), y = h && h.length > 0, x = n.join(" "), m = b(x), g = v || y || m, C = g ? Jn.getFontSync(o, d ? 700 : 400) : null;
584
+ g && !C && (Pn.warn(
585
+ `[renderMultilineText] Font ${o} not loaded for fontkit rendering. Text may not render correctly. Has PUA: ${m}, Text: "${x}"`
586
+ ), Jn.loadFont(o, d ? 700 : 400).catch((w) => {
587
+ Pn.error("[renderMultilineText] Error loading font:", w);
582
588
  }));
583
- const T = cn(r, o, d, u), C = r * l;
589
+ const T = fn(r, o, d, u), k = r * l;
584
590
  let _ = 0;
585
- n.forEach((w, E) => {
586
- let x = t + i;
587
- s === "center" ? x = t + c / 2 : s === "right" && (x = t + c - i);
588
- const P = a + T.ascent + E * C, A = Array.from(w).length, F = $ ? b.filter((D) => {
589
- const I = D.charIndex - _;
590
- return I >= 0 && I < A;
591
- }).map((D) => ({
592
- ...D,
593
- charIndex: D.charIndex - _
591
+ n.forEach((w, A) => {
592
+ let E = t + i;
593
+ s === "center" ? E = t + c / 2 : s === "right" && (E = t + c - i);
594
+ const S = a + T.ascent + A * k, P = Array.from(w).length, I = y ? h.filter((F) => {
595
+ const D = F.charIndex - _;
596
+ return D >= 0 && D < P;
597
+ }).map((F) => ({
598
+ ...F,
599
+ charIndex: F.charIndex - _
594
600
  // Adjust to line-relative index
595
601
  })) : [];
596
- if (k && (S || F.length > 0 || g) ? F.length > 0 || h(w) ? lt(e, k, w, x, P, r, F, {
602
+ if (C && (v || I.length > 0 || m) ? I.length > 0 || b(w) ? yt(e, C, w, E, S, r, I, {
597
603
  color: e.fillStyle,
598
604
  align: s === "start" || s === "end" ? "left" : s
599
- }) : m && ct(e, k, w, x, P, r, m, {
605
+ }) : $ && mt(e, C, w, E, S, r, $, {
600
606
  color: e.fillStyle,
601
607
  align: s === "start" || s === "end" ? "left" : s
602
- }) : e.fillText(w, x, P), _ += A + 1, p) {
603
- const D = Xn(w, r, o, d, u);
604
- let I = x;
605
- s === "center" ? I = x - D / 2 : s === "right" && (I = x - D);
606
- const M = P + r * 0.1;
607
- e.beginPath(), e.moveTo(I, M), e.lineTo(I + D, M), e.lineWidth = Math.max(1, r * 0.05), e.strokeStyle = e.fillStyle, e.stroke();
608
+ }) : e.fillText(w, E, S), _ += P + 1, p) {
609
+ const F = ee(w, r, o, d, u);
610
+ let D = E;
611
+ s === "center" ? D = E - F / 2 : s === "right" && (D = E - F);
612
+ const M = S + r * 0.1;
613
+ e.beginPath(), e.moveTo(D, M), e.lineTo(D + F, M), e.lineWidth = Math.max(1, r * 0.05), e.strokeStyle = e.fillStyle, e.stroke();
608
614
  }
609
615
  if (f) {
610
- const D = Xn(w, r, o, d, u);
611
- let I = x;
612
- s === "center" ? I = x - D / 2 : s === "right" && (I = x - D);
613
- const M = P - r * 0.25;
614
- e.beginPath(), e.moveTo(I, M), e.lineTo(I + D, M), e.lineWidth = Math.max(1, r * 0.05), e.strokeStyle = e.fillStyle, e.stroke();
616
+ const F = ee(w, r, o, d, u);
617
+ let D = E;
618
+ s === "center" ? D = E - F / 2 : s === "right" && (D = E - F);
619
+ const M = S - r * 0.25;
620
+ e.beginPath(), e.moveTo(D, M), e.lineTo(D + F, M), e.lineWidth = Math.max(1, r * 0.05), e.strokeStyle = e.fillStyle, e.stroke();
615
621
  }
616
622
  });
617
623
  }
618
- function _n(e, n) {
619
- pt(e, n);
624
+ function In(e, n) {
625
+ wt(e, n);
620
626
  }
621
- function pt(e, n) {
627
+ function wt(e, n) {
622
628
  var r;
623
- (r = n.stroke) != null && r.enabled && me(e, n), e.save(), e.translate(n.x, n.y), e.rotate(-n.rotation * Math.PI / 180);
624
- const t = n.transformData, a = ((t == null ? void 0 : t.width) ?? 100) - J * 2;
629
+ (r = n.stroke) != null && r.enabled && ke(e, n), e.save(), e.translate(n.x, n.y), e.rotate(-n.rotation * Math.PI / 180);
630
+ const t = n.transformData, a = ((t == null ? void 0 : t.width) ?? 100) - Q * 2;
625
631
  if (n.richText) {
626
- const o = Ne.fromJSON(n.richText);
632
+ const o = Xe.fromJSON(n.richText);
627
633
  e.save(), e.translate(0, 0);
628
634
  const s = n._lockedLineCount;
629
- dt(
635
+ $t(
630
636
  e,
631
637
  o,
632
638
  {
@@ -637,14 +643,16 @@ function pt(e, n) {
637
643
  italic: n.italic,
638
644
  underline: n.underline,
639
645
  strikethrough: n.strikethrough,
640
- textAlign: n.textAlign
646
+ textAlign: n.textAlign,
647
+ letterSpacing: n.letterSpacing,
648
+ lineHeight: n.lineHeight
641
649
  },
642
650
  a,
643
651
  s
644
652
  ), e.restore();
645
653
  } else if (n.text) {
646
654
  e.fillStyle = n.color;
647
- const o = n._lockedLineCount, { lines: s, height: c } = he(
655
+ const o = n._lockedLineCount, s = n.letterSpacing ?? 0, { lines: c, height: i } = ve(
648
656
  n.text,
649
657
  a,
650
658
  n.fontSize,
@@ -652,109 +660,110 @@ function pt(e, n) {
652
660
  n.bold,
653
661
  n.italic,
654
662
  o,
655
- !0
663
+ !0,
656
664
  // strict: true
657
- ), i = cn(
665
+ { letterSpacing: s, lineHeight: n.lineHeight }
666
+ ), l = fn(
658
667
  n.fontSize,
659
668
  n.fontFamily,
660
669
  n.bold,
661
670
  n.italic
662
- ), l = -((t == null ? void 0 : t.width) ?? 100) / 2, d = -c / 2, u = n.fontSize * Ln;
663
- e.font = `${n.italic ? "italic " : ""}${n.bold ? "bold " : ""}${n.fontSize}px ${n.fontFamily}`, e.textBaseline = "alphabetic", e.textAlign = n.textAlign, s.forEach((p, f) => {
664
- const m = f === 0, b = f === s.length - 1;
665
- let h = p;
666
- if (!m) {
667
- const v = p.match(/^ +/), g = v ? v[0].length : 0;
668
- g > 0 && (h = h.substring(g));
671
+ ), d = -((t == null ? void 0 : t.width) ?? 100) / 2, u = -i / 2, p = n.fontSize * (n.lineHeight ?? Gn);
672
+ e.font = `${n.italic ? "italic " : ""}${n.bold ? "bold " : ""}${n.fontSize}px ${n.fontFamily}`, e.textBaseline = "alphabetic", e.textAlign = n.textAlign, c.forEach((f, $) => {
673
+ const h = $ === 0, b = $ === c.length - 1;
674
+ let v = f;
675
+ if (!h) {
676
+ const m = f.match(/^ +/), g = m ? m[0].length : 0;
677
+ g > 0 && (v = v.substring(g));
669
678
  }
670
679
  if (!b) {
671
- const v = h.match(/ +$/), g = v ? v[0].length : 0;
672
- g > 0 && (h = h.substring(0, h.length - g));
680
+ const m = v.match(/ +$/), g = m ? m[0].length : 0;
681
+ g > 0 && (v = v.substring(0, v.length - g));
673
682
  }
674
- let S = l + J;
675
- n.textAlign === "center" ? S = l + ((t == null ? void 0 : t.width) ?? 100) / 2 : n.textAlign === "right" && (S = l + ((t == null ? void 0 : t.width) ?? 100) - J);
676
- const $ = d + i.ascent + f * u;
677
- if (e.fillText(h, S, $), h.length > 0) {
678
- const v = e.measureText(h).width;
679
- let g = S;
680
- if (n.textAlign === "center" ? g -= v / 2 : n.textAlign === "right" && (g -= v), n.underline) {
681
- const y = $ + n.fontSize * 0.1;
682
- e.fillRect(g, y, v, Math.max(1, n.fontSize * 0.05));
683
+ let y = d + Q;
684
+ n.textAlign === "center" ? y = d + ((t == null ? void 0 : t.width) ?? 100) / 2 : n.textAlign === "right" && (y = d + ((t == null ? void 0 : t.width) ?? 100) - Q);
685
+ const x = u + l.ascent + $ * p;
686
+ if (Hn(e, v, y, x, s), v.length > 0) {
687
+ const m = on(e.measureText(v).width, v, s);
688
+ let g = y;
689
+ if (n.textAlign === "center" ? g -= m / 2 : n.textAlign === "right" && (g -= m), n.underline) {
690
+ const C = x + n.fontSize * 0.1;
691
+ e.fillRect(g, C, m, Math.max(1, n.fontSize * 0.05));
683
692
  }
684
693
  if (n.strikethrough) {
685
- const y = $ - i.ascent * 0.4;
686
- e.fillRect(g, y, v, Math.max(1, n.fontSize * 0.05));
694
+ const C = x - l.ascent * 0.4;
695
+ e.fillRect(g, C, m, Math.max(1, n.fontSize * 0.05));
687
696
  }
688
697
  }
689
698
  });
690
699
  }
691
700
  e.restore();
692
701
  }
693
- function _a(e, n) {
702
+ function Ua(e, n) {
694
703
  var s;
695
704
  const t = n.opacity ?? 1, a = !!((s = n.stroke) != null && s.enabled), r = n.type === "custom";
696
705
  if (t < 1 && a && r) {
697
- ht(e, n, t);
706
+ St(e, n, t);
698
707
  return;
699
708
  }
700
709
  const o = e.globalAlpha;
701
- t !== 1 && (e.globalAlpha = t), En(e, n), e.globalAlpha = o;
710
+ t !== 1 && (e.globalAlpha = t), Fn(e, n), e.globalAlpha = o;
702
711
  }
703
- function ht(e, n, t) {
704
- var h;
705
- const a = n.transformData, r = n.fontSize || 24, o = ((h = n.stroke) == null ? void 0 : h.width) || 0, s = ((a == null ? void 0 : a.width) ?? r * n.text.length * 0.7) + o * 2 + 40, c = r * 3 + o * 2 + 40, i = e.getTransform(), l = Math.max(Math.abs(i.a), Math.abs(i.d), 1), d = Math.ceil(s * l), u = Math.ceil(c * l);
712
+ function St(e, n, t) {
713
+ var b;
714
+ const a = n.transformData, r = n.fontSize || 24, o = ((b = n.stroke) == null ? void 0 : b.width) || 0, s = ((a == null ? void 0 : a.width) ?? r * n.text.length * 0.7) + o * 2 + 40, c = r * 3 + o * 2 + 40, i = e.getTransform(), l = Math.max(Math.abs(i.a), Math.abs(i.d), 1), d = Math.ceil(s * l), u = Math.ceil(c * l);
706
715
  let p;
707
716
  typeof OffscreenCanvas < "u" ? p = new OffscreenCanvas(d, u) : (p = document.createElement("canvas"), p.width = d, p.height = u);
708
717
  const f = p.getContext("2d");
709
718
  if (!f) {
710
- const S = e.globalAlpha;
711
- e.globalAlpha = t, En(e, n), e.globalAlpha = S;
719
+ const v = e.globalAlpha;
720
+ e.globalAlpha = t, Fn(e, n), e.globalAlpha = v;
712
721
  return;
713
722
  }
714
- const m = i.a * n.x + i.e, b = i.d * n.y + i.f;
723
+ const $ = i.a * n.x + i.e, h = i.d * n.y + i.f;
715
724
  f.setTransform(
716
725
  i.a,
717
726
  i.b,
718
727
  i.c,
719
728
  i.d,
720
- i.e - m + d / 2,
721
- i.f - b + u / 2
722
- ), En(f, n), e.save(), e.setTransform(1, 0, 0, 1, 0, 0), e.globalAlpha = t, e.drawImage(p, m - d / 2, b - u / 2), e.restore();
729
+ i.e - $ + d / 2,
730
+ i.f - h + u / 2
731
+ ), Fn(f, n), e.save(), e.setTransform(1, 0, 0, 1, 0, 0), e.globalAlpha = t, e.drawImage(p, $ - d / 2, h - u / 2), e.restore();
723
732
  }
724
- function En(e, n) {
733
+ function Fn(e, n) {
725
734
  switch (n.type) {
726
735
  case "custom":
727
- _n(e, n);
736
+ In(e, n);
728
737
  break;
729
738
  case "circle":
730
- ye(e, n);
739
+ Te(e, n);
731
740
  break;
732
741
  case "wave":
733
- $e(e, n);
742
+ _e(e, n);
734
743
  break;
735
744
  case "arch":
736
- xe(e, n);
745
+ Ee(e, n);
737
746
  break;
738
747
  case "ascend":
739
- ve(e, n);
748
+ Ae(e, n);
740
749
  break;
741
750
  case "lean":
742
- we(e, n);
751
+ Pe(e, n);
743
752
  break;
744
753
  case "flag":
745
- Se(e, n);
754
+ Ie(e, n);
746
755
  break;
747
756
  default:
748
- Tn.warn(`[canvas-renderer] Unsupported transform type: ${n.type}`), _n(e, n);
757
+ Pn.warn(`[canvas-renderer] Unsupported transform type: ${n.type}`), In(e, n);
749
758
  }
750
759
  }
751
- function bt(e, n) {
760
+ function Ct(e, n) {
752
761
  if (typeof OffscreenCanvas < "u")
753
762
  return new OffscreenCanvas(e, n);
754
763
  const t = document.createElement("canvas");
755
764
  return t.width = e, t.height = n, t;
756
765
  }
757
- function Q(e, n, t) {
766
+ function en(e, n, t) {
758
767
  if (t != null && t.enabled)
759
768
  if (e.strokeStyle = t.color, e.lineWidth = t.width, e.lineCap = t.lineCap || "round", e.lineJoin = t.lineJoin || "round", t.miterLimit !== void 0 && (e.miterLimit = t.miterLimit), t.opacity !== void 0) {
760
769
  const a = e.globalAlpha;
@@ -762,49 +771,49 @@ function Q(e, n, t) {
762
771
  } else
763
772
  e.strokeText(n, 0, 0);
764
773
  }
765
- function nn(e, n, t) {
774
+ function tn(e, n, t) {
766
775
  const a = n.stroke, r = (a == null ? void 0 : a.opacity) ?? 1, o = e.globalAlpha, s = (a == null ? void 0 : a.enabled) && r < 1, c = (a == null ? void 0 : a.enabled) && o < 1;
767
776
  if (!(s || c)) {
768
777
  t(e, n);
769
778
  return;
770
779
  }
771
- const l = n.fontSize || 24, d = a.width || 0, u = n.transformData, p = l * n.text.length * 0.7, f = u.width ?? (u.radius ? u.radius * 2 : 0), m = Math.max(f, p), b = (a.feather || 0) * 2, h = d * 4 + b + l + 40, S = m + h, $ = u.archHeight ? Math.abs(u.archHeight) * l * 2 : 0, v = u.radius ? u.radius : 0, g = l * 3 + h + $ + v, y = e.getTransform(), k = Math.max(Math.abs(y.a), Math.abs(y.d), 1), T = Math.ceil(S * k / 2) * 2, C = Math.ceil(g * k / 2) * 2;
772
- if (T <= 0 || C <= 0) {
780
+ const l = n.fontSize || 24, d = a.width || 0, u = n.transformData, p = l * n.text.length * 0.7, f = u.width ?? (u.radius ? u.radius * 2 : 0), $ = Math.max(f, p), h = (a.feather || 0) * 2, b = d * 4 + h + l + 40, v = $ + b, y = u.archHeight ? Math.abs(u.archHeight) * l * 2 : 0, x = u.radius ? u.radius : 0, m = l * 3 + b + y + x, g = e.getTransform(), C = Math.max(Math.abs(g.a), Math.abs(g.d), 1), T = Math.ceil(v * C / 2) * 2, k = Math.ceil(m * C / 2) * 2;
781
+ if (T <= 0 || k <= 0) {
773
782
  t(e, n);
774
783
  return;
775
784
  }
776
- const _ = bt(T, C), w = _.getContext("2d");
785
+ const _ = Ct(T, k), w = _.getContext("2d");
777
786
  if (!w) {
778
787
  t(e, n);
779
788
  return;
780
789
  }
781
- const E = n.x || 0, x = n.y || 0, P = y.a * E + y.c * x + y.e, A = y.b * E + y.d * x + y.f, F = Math.round(P - T / 2), D = Math.round(A - C / 2);
790
+ const A = n.x || 0, E = n.y || 0, S = g.a * A + g.c * E + g.e, P = g.b * A + g.d * E + g.f, I = Math.round(S - T / 2), F = Math.round(P - k / 2);
782
791
  if (w.setTransform(
783
- y.a,
784
- y.b,
785
- y.c,
786
- y.d,
787
- T / 2 - P + y.e,
788
- C / 2 - A + y.f
792
+ g.a,
793
+ g.b,
794
+ g.c,
795
+ g.d,
796
+ T / 2 - S + g.e,
797
+ k / 2 - P + g.f
789
798
  ), c) {
790
799
  w.globalAlpha = 1;
791
- const en = a.opacity;
792
- s && (a.opacity = 1), t(w, n), s && (a.opacity = en), e.save(), e.resetTransform(), e.globalAlpha = o, e.drawImage(_, F, D), e.restore();
800
+ const L = a.opacity;
801
+ s && (a.opacity = 1), t(w, n), s && (a.opacity = L), e.save(), e.resetTransform(), e.globalAlpha = o, e.drawImage(_, I, F), e.restore();
793
802
  return;
794
803
  }
795
- const I = a.opacity;
796
- a.opacity = 1, t(w, n), a.opacity = I;
804
+ const D = a.opacity;
805
+ a.opacity = 1, t(w, n), a.opacity = D;
797
806
  const M = a.enabled;
798
807
  a.enabled = !1, t(e, n), a.enabled = M, e.save(), e.resetTransform(), e.globalAlpha = r, e.drawImage(
799
808
  _,
800
- F,
801
- D
809
+ I,
810
+ F
802
811
  ), e.restore();
803
812
  }
804
- function ye(e, n) {
805
- nn(e, n, gt);
813
+ function Te(e, n) {
814
+ tn(e, n, kt);
806
815
  }
807
- function gt(e, n) {
816
+ function kt(e, n) {
808
817
  const t = n.transformData;
809
818
  e.save(), e.translate(n.x, n.y), e.rotate(-n.rotation * Math.PI / 180), e.scale(t.scale, t.scale);
810
819
  const a = n.bold ? "bold" : "normal", r = n.italic ? "italic" : "normal";
@@ -813,84 +822,84 @@ function gt(e, n) {
813
822
  if (t.reverse) {
814
823
  let i = Math.PI / 2 + c / (2 * t.radius);
815
824
  o.forEach((l, d) => {
816
- const p = s[d] / t.radius, f = Math.cos(i - p / 2) * t.radius, m = Math.sin(i - p / 2) * t.radius;
817
- e.save(), e.translate(f, m), e.rotate(i - p / 2 - Math.PI / 2), Q(e, l, n.stroke), e.fillText(l, 0, 0), e.restore(), i -= p;
825
+ const p = s[d] / t.radius, f = Math.cos(i - p / 2) * t.radius, $ = Math.sin(i - p / 2) * t.radius;
826
+ e.save(), e.translate(f, $), e.rotate(i - p / 2 - Math.PI / 2), en(e, l, n.stroke), e.fillText(l, 0, 0), e.restore(), i -= p;
818
827
  });
819
828
  } else {
820
829
  let i = -Math.PI / 2 - c / (2 * t.radius);
821
830
  o.forEach((l, d) => {
822
- const p = s[d] / t.radius, f = Math.cos(i + p / 2) * t.radius, m = Math.sin(i + p / 2) * t.radius;
823
- e.save(), e.translate(f, m), e.rotate(i + p / 2 + Math.PI / 2), Q(e, l, n.stroke), e.fillText(l, 0, 0), e.restore(), i += p;
831
+ const p = s[d] / t.radius, f = Math.cos(i + p / 2) * t.radius, $ = Math.sin(i + p / 2) * t.radius;
832
+ e.save(), e.translate(f, $), e.rotate(i + p / 2 + Math.PI / 2), en(e, l, n.stroke), e.fillText(l, 0, 0), e.restore(), i += p;
824
833
  });
825
834
  }
826
835
  e.restore();
827
836
  }
828
- function $e(e, n) {
829
- nn(e, n, mt);
837
+ function _e(e, n) {
838
+ tn(e, n, Tt);
830
839
  }
831
- function mt(e, n) {
840
+ function Tt(e, n) {
832
841
  const t = n.transformData;
833
- e.save(), e.translate(n.x, n.y), e.rotate(-n.rotation * Math.PI / 180), e.font = R(n.fontSize, n.fontFamily, n.bold, n.italic), e.fillStyle = n.color, e.textAlign = "center", e.textBaseline = "middle";
842
+ e.save(), e.translate(n.x, n.y), e.rotate(-n.rotation * Math.PI / 180), e.font = B(n.fontSize, n.fontFamily, n.bold, n.italic), e.fillStyle = n.color, e.textAlign = "center", e.textBaseline = "middle";
834
843
  const a = n.text.split("");
835
844
  let o = -a.reduce((s, c) => s + e.measureText(c).width, 0) / 2;
836
845
  a.forEach((s) => {
837
846
  const c = e.measureText(s).width, i = o + c / 2, l = i / (t.width / 2), d = t.amplitude * n.fontSize * Math.sin(t.frequency * Math.PI * l), u = t.amplitude * t.frequency * Math.PI * Math.cos(t.frequency * Math.PI * l);
838
- e.save(), e.translate(i, d), e.transform(1, u * Ue, 0, 1, 0, 0), Q(e, s, n.stroke), e.fillText(s, 0, 0), e.restore(), o += c;
847
+ e.save(), e.translate(i, d), e.transform(1, u * Ye, 0, 1, 0, 0), en(e, s, n.stroke), e.fillText(s, 0, 0), e.restore(), o += c;
839
848
  }), e.restore();
840
849
  }
841
- function xe(e, n) {
842
- nn(e, n, yt);
850
+ function Ee(e, n) {
851
+ tn(e, n, _t);
843
852
  }
844
- function yt(e, n) {
853
+ function _t(e, n) {
845
854
  const t = n.transformData;
846
- e.save(), e.translate(n.x, n.y), e.rotate(-n.rotation * Math.PI / 180), e.font = R(n.fontSize, n.fontFamily, n.bold, n.italic), e.fillStyle = n.color, e.textAlign = "center", e.textBaseline = "middle";
855
+ e.save(), e.translate(n.x, n.y), e.rotate(-n.rotation * Math.PI / 180), e.font = B(n.fontSize, n.fontFamily, n.bold, n.italic), e.fillStyle = n.color, e.textAlign = "center", e.textBaseline = "middle";
847
856
  const a = n.text.split(""), r = a.reduce((c, i) => c + e.measureText(i).width, 0), o = t.width / 2;
848
857
  let s = -r / 2;
849
858
  a.forEach((c) => {
850
859
  const i = e.measureText(c).width, l = s + i / 2, d = l / o, u = (Math.pow(d, 2) - 1) * t.archHeight * n.fontSize, p = 2 * d * t.archHeight;
851
- e.save(), e.translate(l, u), e.transform(1, p * 0.3, 0, 1, 0, 0), Q(e, c, n.stroke), e.fillText(c, 0, 0), e.restore(), s += i;
860
+ e.save(), e.translate(l, u), e.transform(1, p * 0.3, 0, 1, 0, 0), en(e, c, n.stroke), e.fillText(c, 0, 0), e.restore(), s += i;
852
861
  }), e.restore();
853
862
  }
854
- function ve(e, n) {
855
- nn(e, n, $t);
863
+ function Ae(e, n) {
864
+ tn(e, n, Et);
856
865
  }
857
- function $t(e, n) {
866
+ function Et(e, n) {
858
867
  const t = n.transformData;
859
- e.save(), e.translate(n.x, n.y), e.rotate(-n.rotation * Math.PI / 180), e.font = R(n.fontSize, n.fontFamily, n.bold, n.italic), e.fillStyle = n.color, e.textAlign = "center", e.textBaseline = "middle";
868
+ e.save(), e.translate(n.x, n.y), e.rotate(-n.rotation * Math.PI / 180), e.font = B(n.fontSize, n.fontFamily, n.bold, n.italic), e.fillStyle = n.color, e.textAlign = "center", e.textBaseline = "middle";
860
869
  const a = n.text.split(""), r = a.reduce((c, i) => c + e.measureText(i).width, 0), o = t.ascendAngle * Math.PI / 180;
861
870
  let s = -r / 2;
862
871
  a.forEach((c) => {
863
872
  const i = e.measureText(c).width, l = s + i / 2, d = l * Math.tan(o), u = Math.tan(o);
864
- e.save(), e.translate(l, d), e.transform(1, u * 1, 0, 1, 0, 0), Q(e, c, n.stroke), e.fillText(c, 0, 0), e.restore(), s += i;
873
+ e.save(), e.translate(l, d), e.transform(1, u * 1, 0, 1, 0, 0), en(e, c, n.stroke), e.fillText(c, 0, 0), e.restore(), s += i;
865
874
  }), e.restore();
866
875
  }
867
- function we(e, n) {
868
- nn(e, n, xt);
876
+ function Pe(e, n) {
877
+ tn(e, n, At);
869
878
  }
870
- function xt(e, n) {
879
+ function At(e, n) {
871
880
  var r;
872
881
  const t = n.transformData;
873
882
  e.save(), e.translate(n.x, n.y), e.rotate(-n.rotation * Math.PI / 180);
874
883
  const a = -t.leanAmount * Math.PI / 4;
875
- e.transform(1, 0, Math.tan(a), 1, 0, 0), e.font = R(n.fontSize, n.fontFamily, n.bold, n.italic), e.fillStyle = n.color, e.textAlign = "center", e.textBaseline = "middle", (r = n.stroke) != null && r.enabled && (e.save(), e.strokeStyle = n.stroke.color, e.lineWidth = n.stroke.width, e.lineCap = n.stroke.lineCap || "round", e.lineJoin = n.stroke.lineJoin || "round", n.stroke.opacity !== void 0 && (e.globalAlpha = n.stroke.opacity), e.strokeText(n.text, 0, 0), e.restore()), e.fillText(n.text, 0, 0), e.restore();
884
+ e.transform(1, 0, Math.tan(a), 1, 0, 0), e.font = B(n.fontSize, n.fontFamily, n.bold, n.italic), e.fillStyle = n.color, e.textAlign = "center", e.textBaseline = "middle", (r = n.stroke) != null && r.enabled && (e.save(), e.strokeStyle = n.stroke.color, e.lineWidth = n.stroke.width, e.lineCap = n.stroke.lineCap || "round", e.lineJoin = n.stroke.lineJoin || "round", n.stroke.opacity !== void 0 && (e.globalAlpha = n.stroke.opacity), e.strokeText(n.text, 0, 0), e.restore()), e.fillText(n.text, 0, 0), e.restore();
876
885
  }
877
- function Se(e, n) {
878
- nn(e, n, vt);
886
+ function Ie(e, n) {
887
+ tn(e, n, Pt);
879
888
  }
880
- function vt(e, n) {
889
+ function Pt(e, n) {
881
890
  const t = n.transformData;
882
- e.save(), e.translate(n.x, n.y), e.rotate(-n.rotation * Math.PI / 180), e.font = R(n.fontSize, n.fontFamily, n.bold, n.italic), e.fillStyle = n.color, e.textAlign = "center", e.textBaseline = "middle";
891
+ e.save(), e.translate(n.x, n.y), e.rotate(-n.rotation * Math.PI / 180), e.font = B(n.fontSize, n.fontFamily, n.bold, n.italic), e.fillStyle = n.color, e.textAlign = "center", e.textBaseline = "middle";
883
892
  const a = n.text.split("");
884
893
  let o = -a.reduce((s, c) => s + e.measureText(c).width, 0) / 2;
885
894
  a.forEach((s) => {
886
- const c = e.measureText(s).width, i = o + c / 2, l = i / (t.width / 2), d = Math.abs(l), u = t.amplitude * d, p = u * n.fontSize * Math.sin(t.frequency * Math.PI * l), f = u * t.frequency * Math.PI * Math.cos(t.frequency * Math.PI * l), m = t.amplitude * Math.sign(l) * Math.sin(t.frequency * Math.PI * l), b = f + m;
887
- e.save(), e.translate(i, p), e.transform(1, b * 0.3, 0, 1, 0, 0), Q(e, s, n.stroke), e.fillText(s, 0, 0), e.restore(), o += c;
895
+ const c = e.measureText(s).width, i = o + c / 2, l = i / (t.width / 2), d = Math.abs(l), u = t.amplitude * d, p = u * n.fontSize * Math.sin(t.frequency * Math.PI * l), f = u * t.frequency * Math.PI * Math.cos(t.frequency * Math.PI * l), $ = t.amplitude * Math.sign(l) * Math.sin(t.frequency * Math.PI * l), h = f + $;
896
+ e.save(), e.translate(i, p), e.transform(1, h * 0.3, 0, 1, 0, 0), en(e, s, n.stroke), e.fillText(s, 0, 0), e.restore(), o += c;
888
897
  }), e.restore();
889
898
  }
890
- function q(e) {
899
+ function Y(e) {
891
900
  return (n, t) => e(n, t);
892
901
  }
893
- function wt(e, n) {
902
+ function It(e, n) {
894
903
  e.save();
895
904
  const t = e.canvas, a = t.width, r = t.height, o = e.getTransform(), s = [];
896
905
  let c = [];
@@ -920,52 +929,53 @@ function wt(e, n) {
920
929
  }
921
930
  e.restore();
922
931
  }
923
- var Yn = !1;
924
- function Un() {
925
- Yn || (Yn = !0, j("arch", q(xe)), j("ascend", q(ve)), j("circle", q(ye)), j("flag", q(Se)), j("lean", q(we)), j("wave", q($e)), j(
932
+ var te = !1;
933
+ function jn() {
934
+ te || (te = !0, q("arch", Y(Ee)), q("ascend", Y(Ae)), q("circle", Y(Te)), q("flag", Y(Ie)), q("lean", Y(Pe)), q("wave", Y(_e)), q(
926
935
  "custom",
927
- (e, n) => _n(e, n)
928
- ), ze(wt), Je(
929
- (e, n) => et(e, n)
936
+ (e, n) => In(e, n)
937
+ ), Ke(It), it(
938
+ (e, n) => dt(e, n)
930
939
  ), globalThis.__scElementPaintersInstalled = !0);
931
940
  }
932
- Un();
933
- function zn(e, n, t = {}) {
941
+ jn();
942
+ function qn(e, n, t = {}) {
934
943
  const a = t.mode || "both";
935
944
  switch (e.save(), e.translate(n.x || 0, n.y || 0), e.rotate(-(n.rotation || 0) * Math.PI / 180), n.transformType) {
936
945
  case "image":
937
- Ct(e, n, a, t);
946
+ Dt(e, n, a, t);
938
947
  break;
939
948
  case "shape":
940
- kt(e, n, a, t);
949
+ Mt(e, n, a, t);
941
950
  break;
942
951
  case "group":
943
952
  break;
944
953
  default:
945
- St(e, n, a, t);
954
+ Ft(e, n, a, t);
946
955
  break;
947
956
  }
948
957
  e.restore();
949
958
  }
950
- function St(e, n, t, a) {
959
+ function Ft(e, n, t, a) {
951
960
  var s;
952
961
  const r = n, o = r.text || "";
953
- o && ((t === "stroke" || t === "both") && ((s = n.stroke) != null && s.enabled) && (e.save(), me(e, n, { ...a.renderingContext, positionApplied: !0 }), e.restore()), (t === "fill" || t === "both") && (e.save(), ft(e, {
962
+ o && ((t === "stroke" || t === "both") && ((s = n.stroke) != null && s.enabled) && (e.save(), ke(e, n, { ...a.renderingContext, positionApplied: !0 }), e.restore()), (t === "fill" || t === "both") && (e.save(), xt(e, {
954
963
  text: o,
955
964
  fontSize: r.fontSize || 24,
956
965
  fontFamily: r.fontFamily || "Arial",
957
966
  bold: r.bold || !1,
958
967
  italic: r.italic || !1,
959
968
  textAlign: r.textAlign || "center",
960
- color: r.color || "#000000"
969
+ color: r.color || "#000000",
970
+ letterSpacing: r.letterSpacing
961
971
  }), e.restore()));
962
972
  }
963
- function Ct(e, n, t, a) {
973
+ function Dt(e, n, t, a) {
964
974
  var o;
965
975
  if (!n.transformData) return;
966
976
  const r = n.transformData;
967
977
  if (t === "fill" || t === "both")
968
- if (Pt(e, n), a.loadedImage) {
978
+ if (Nt(e, n), a.loadedImage) {
969
979
  e.save(), e.clip();
970
980
  const s = r.flipHorizontal ? -1 : 1, c = r.flipVertical ? -1 : 1;
971
981
  e.scale(s, c);
@@ -973,34 +983,34 @@ function Ct(e, n, t, a) {
973
983
  e.drawImage(a.loadedImage, -i / 2, -l / 2, i, l), e.restore();
974
984
  } else
975
985
  e.fillStyle = "#cccccc", e.fill();
976
- (t === "stroke" || t === "both") && ((o = n.stroke) != null && o.enabled) && (e.save(), ot(e, n, a.renderingContext), e.restore());
986
+ (t === "stroke" || t === "both") && ((o = n.stroke) != null && o.enabled) && (e.save(), gt(e, n, a.renderingContext), e.restore());
977
987
  }
978
- function kt(e, n, t, a) {
988
+ function Mt(e, n, t, a) {
979
989
  var s, c;
980
990
  if (!n.transformData) return;
981
991
  const r = n.transformData, o = ((s = a.renderingContext) == null ? void 0 : s.isKnockout) === !0;
982
- e.beginPath(), Ce(e, r), (t === "fill" || t === "both") && (e.fillStyle = o ? "#000000" : r.fillColor || "#3b82f6", e.globalAlpha = o ? 1 : r.fillOpacity ?? 1, e.fill()), (t === "stroke" || t === "both") && ((c = n.stroke) != null && c.enabled) && (e.save(), At(e, n, a.renderingContext), e.restore());
992
+ e.beginPath(), Fe(e, r), (t === "fill" || t === "both") && (e.fillStyle = o ? "#000000" : r.fillColor || "#3b82f6", e.globalAlpha = o ? 1 : r.fillOpacity ?? 1, e.fill()), (t === "stroke" || t === "both") && ((c = n.stroke) != null && c.enabled) && (e.save(), Lt(e, n, a.renderingContext), e.restore());
983
993
  }
984
- function Ce(e, n) {
994
+ function Fe(e, n) {
985
995
  const { shapeType: t } = n, a = n.width ?? 100, r = n.height ?? 100;
986
996
  switch (t) {
987
997
  case "rectangle":
988
- Kn(e, n, a, r);
998
+ ae(e, n, a, r);
989
999
  break;
990
1000
  case "circle":
991
- Tt(e, Math.min(a, r) / 2);
1001
+ Ot(e, Math.min(a, r) / 2);
992
1002
  break;
993
1003
  case "ellipse":
994
- _t(e, a / 2, r / 2);
1004
+ Rt(e, a / 2, r / 2);
995
1005
  break;
996
1006
  case "star":
997
- Et(e, n, Math.min(a, r) / 2);
1007
+ Bt(e, n, Math.min(a, r) / 2);
998
1008
  break;
999
1009
  default:
1000
- Kn(e, n, a, r);
1010
+ ae(e, n, a, r);
1001
1011
  }
1002
1012
  }
1003
- function Kn(e, n, t, a) {
1013
+ function ae(e, n, t, a) {
1004
1014
  const r = n.borderRadius || 0, o = -t / 2, s = -a / 2;
1005
1015
  if (r > 0) {
1006
1016
  const c = Math.min(r / 100 * Math.min(t, a), t / 2, a / 2);
@@ -1008,13 +1018,13 @@ function Kn(e, n, t, a) {
1008
1018
  } else
1009
1019
  e.rect(o, s, t, a);
1010
1020
  }
1011
- function Tt(e, n) {
1021
+ function Ot(e, n) {
1012
1022
  e.arc(0, 0, n, 0, Math.PI * 2);
1013
1023
  }
1014
- function _t(e, n, t) {
1024
+ function Rt(e, n, t) {
1015
1025
  e.ellipse(0, 0, n, t, 0, 0, Math.PI * 2);
1016
1026
  }
1017
- function Et(e, n, t) {
1027
+ function Bt(e, n, t) {
1018
1028
  const a = Math.max(3, Math.min(20, n.points || 5)), r = Math.max(0.1, Math.min(0.9, n.innerRadius || 0.4)), o = t * r, s = Math.PI / a, c = -Math.PI / 2;
1019
1029
  for (let i = 0; i < a * 2; i++) {
1020
1030
  const l = c + s * i, d = i % 2 === 0 ? t : o, u = Math.cos(l) * d, p = Math.sin(l) * d;
@@ -1022,13 +1032,13 @@ function Et(e, n, t) {
1022
1032
  }
1023
1033
  e.closePath();
1024
1034
  }
1025
- function At(e, n, t) {
1035
+ function Lt(e, n, t) {
1026
1036
  var r;
1027
1037
  if (!((r = n.stroke) != null && r.enabled) || !n.transformData) return;
1028
1038
  const a = (t == null ? void 0 : t.isKnockout) === !0;
1029
- e.save(), a ? (e.strokeStyle = "#000000", e.lineWidth = n.stroke.width, e.lineCap = n.stroke.lineCap || "butt", e.lineJoin = n.stroke.lineJoin || "miter", e.globalAlpha = 1) : (e.strokeStyle = n.stroke.color, e.lineWidth = n.stroke.width, e.lineCap = n.stroke.lineCap || "butt", e.lineJoin = n.stroke.lineJoin || "miter", n.stroke.opacity !== void 0 && (e.globalAlpha = n.stroke.opacity)), n.stroke.miterLimit !== void 0 && (e.miterLimit = n.stroke.miterLimit), n.stroke.dashArray && n.stroke.dashArray.length > 0 && e.setLineDash(n.stroke.dashArray), !a && n.stroke.feather && n.stroke.feather > 0 && "filter" in e && (e.filter = `blur(${n.stroke.feather}px)`), e.beginPath(), Ce(e, n.transformData), e.stroke(), e.restore();
1039
+ e.save(), a ? (e.strokeStyle = "#000000", e.lineWidth = n.stroke.width, e.lineCap = n.stroke.lineCap || "butt", e.lineJoin = n.stroke.lineJoin || "miter", e.globalAlpha = 1) : (e.strokeStyle = n.stroke.color, e.lineWidth = n.stroke.width, e.lineCap = n.stroke.lineCap || "butt", e.lineJoin = n.stroke.lineJoin || "miter", n.stroke.opacity !== void 0 && (e.globalAlpha = n.stroke.opacity)), n.stroke.miterLimit !== void 0 && (e.miterLimit = n.stroke.miterLimit), n.stroke.dashArray && n.stroke.dashArray.length > 0 && e.setLineDash(n.stroke.dashArray), !a && n.stroke.feather && n.stroke.feather > 0 && "filter" in e && (e.filter = `blur(${n.stroke.feather}px)`), e.beginPath(), Fe(e, n.transformData), e.stroke(), e.restore();
1030
1040
  }
1031
- function Pt(e, n) {
1041
+ function Nt(e, n) {
1032
1042
  if (!n.transformData) return;
1033
1043
  const { borderRadius: t } = n.transformData, a = n.transformData.width ?? 100, r = n.transformData.height ?? 100, o = -a / 2, s = -r / 2;
1034
1044
  if (e.beginPath(), t && t > 0) {
@@ -1037,8 +1047,8 @@ function Pt(e, n) {
1037
1047
  } else
1038
1048
  e.rect(o, s, a, r);
1039
1049
  }
1040
- function An(e, n, t, a, r, o, s = "destination-out") {
1041
- var v;
1050
+ function Dn(e, n, t, a, r, o, s = "destination-out") {
1051
+ var x;
1042
1052
  if (!n.knockoutParts) return;
1043
1053
  if (!(n.knockoutParts.fill || n.knockoutParts.stroke)) {
1044
1054
  a(e, n);
@@ -1046,25 +1056,25 @@ function An(e, n, t, a, r, o, s = "destination-out") {
1046
1056
  }
1047
1057
  const i = e.getTransform();
1048
1058
  e.save();
1049
- const l = n.knockoutParts.scope || "group", d = It(n, l, t);
1059
+ const l = n.knockoutParts.scope || "group", d = Ut(n, l, t);
1050
1060
  if (d.length === 0 && l === "artboard") {
1051
- Ft(e, n, a), e.restore();
1061
+ zt(e, n, a), e.restore();
1052
1062
  return;
1053
1063
  }
1054
1064
  if (d.length === 0) {
1055
1065
  a(e, n), e.restore();
1056
1066
  return;
1057
1067
  }
1058
- const u = e.canvas, f = e.getTransform().a, m = Mt(u.width, u.height), b = m.getContext("2d");
1059
- if (!b) return;
1060
- b.scale(f, f), r && o && (b.fillStyle = r, b.fillRect(o.x, o.y, o.width, o.height));
1061
- for (const g of d)
1062
- a(b, g);
1063
- n.knockoutParts.fill && !n.knockoutParts.stroke && ((v = n.stroke) != null && v.enabled) && (b.save(), In(b, n), b.restore()), b.save(), b.globalCompositeOperation = s, n.knockoutParts.fill && Pn(b, n), n.knockoutParts.stroke && In(b, n), b.restore(), n.knockoutParts.fill || (b.save(), Pn(b, n), b.restore());
1064
- const h = u.width / f, S = u.height / f;
1065
- e.drawImage(m, 0, 0, h, S), e.restore();
1066
- const $ = e.getTransform();
1067
- (Math.abs($.a - i.a) > 1e-3 || Math.abs($.d - i.d) > 1e-3 || Math.abs($.e - i.e) > 1e-3 || Math.abs($.f - i.f) > 1e-3) && e.setTransform(
1068
+ const u = e.canvas, f = e.getTransform().a, $ = Gt(u.width, u.height), h = $.getContext("2d");
1069
+ if (!h) return;
1070
+ h.scale(f, f), r && o && (h.fillStyle = r, h.fillRect(o.x, o.y, o.width, o.height));
1071
+ for (const m of d)
1072
+ a(h, m);
1073
+ n.knockoutParts.fill && !n.knockoutParts.stroke && ((x = n.stroke) != null && x.enabled) && (h.save(), On(h, n), h.restore()), h.save(), h.globalCompositeOperation = s, n.knockoutParts.fill && Mn(h, n), n.knockoutParts.stroke && On(h, n), h.restore(), n.knockoutParts.fill || (h.save(), Mn(h, n), h.restore());
1074
+ const b = u.width / f, v = u.height / f;
1075
+ e.drawImage($, 0, 0, b, v), e.restore();
1076
+ const y = e.getTransform();
1077
+ (Math.abs(y.a - i.a) > 1e-3 || Math.abs(y.d - i.d) > 1e-3 || Math.abs(y.e - i.e) > 1e-3 || Math.abs(y.f - i.f) > 1e-3) && e.setTransform(
1068
1078
  i.a,
1069
1079
  i.b,
1070
1080
  i.c,
@@ -1073,59 +1083,59 @@ function An(e, n, t, a, r, o, s = "destination-out") {
1073
1083
  i.f
1074
1084
  );
1075
1085
  }
1076
- function Ea(e, n, t, a, r, o) {
1077
- An(e, n, t, a, r, o, "destination-out");
1086
+ function Wa(e, n, t, a, r, o) {
1087
+ Dn(e, n, t, a, r, o, "destination-out");
1078
1088
  }
1079
- function It(e, n, t) {
1080
- return n === "artboard" ? ke(e, t) : Dt(e, t);
1089
+ function Ut(e, n, t) {
1090
+ return n === "artboard" ? De(e, t) : Wt(e, t);
1081
1091
  }
1082
- function ke(e, n) {
1092
+ function De(e, n) {
1083
1093
  const t = n.findIndex((a) => a.id === e.id);
1084
1094
  return t === -1 ? [] : n.slice(0, t);
1085
1095
  }
1086
- function Dt(e, n) {
1087
- const t = Te(e, n);
1096
+ function Wt(e, n) {
1097
+ const t = Me(e, n);
1088
1098
  if (!t)
1089
- return ke(e, n);
1099
+ return De(e, n);
1090
1100
  if (t.transformType !== "group" || !t.children)
1091
1101
  return [];
1092
1102
  const a = t.children.findIndex((r) => r.id === e.id);
1093
1103
  return a === -1 ? [] : t.children.slice(0, a);
1094
1104
  }
1095
- function Te(e, n) {
1105
+ function Me(e, n) {
1096
1106
  for (const t of n)
1097
1107
  if (t.transformType === "group" && t.children) {
1098
1108
  if (t.children.some((r) => r.id === e.id))
1099
1109
  return t;
1100
- const a = Te(e, t.children);
1110
+ const a = Me(e, t.children);
1101
1111
  if (a)
1102
1112
  return a;
1103
1113
  }
1104
1114
  return null;
1105
1115
  }
1106
- function Pn(e, n, t) {
1107
- zn(e, n, {
1116
+ function Mn(e, n, t) {
1117
+ qn(e, n, {
1108
1118
  mode: "fill",
1109
1119
  renderingContext: { isKnockout: !0 }
1110
1120
  });
1111
1121
  }
1112
- function In(e, n) {
1122
+ function On(e, n) {
1113
1123
  var t;
1114
- (t = n.stroke) != null && t.enabled && zn(e, n, {
1124
+ (t = n.stroke) != null && t.enabled && qn(e, n, {
1115
1125
  mode: "stroke",
1116
1126
  renderingContext: { isKnockout: !0 }
1117
1127
  });
1118
1128
  }
1119
- function Ft(e, n, t) {
1129
+ function zt(e, n, t) {
1120
1130
  var r;
1121
1131
  const a = n.knockoutParts;
1122
1132
  if (!a) {
1123
1133
  t(e, n);
1124
1134
  return;
1125
1135
  }
1126
- a.fill || (e.save(), Pn(e, n), e.restore()), !a.stroke && ((r = n.stroke) != null && r.enabled) && (e.save(), In(e, n), e.restore());
1136
+ a.fill || (e.save(), Mn(e, n), e.restore()), !a.stroke && ((r = n.stroke) != null && r.enabled) && (e.save(), On(e, n), e.restore());
1127
1137
  }
1128
- function Mt(e, n) {
1138
+ function Gt(e, n) {
1129
1139
  if (typeof OffscreenCanvas < "u")
1130
1140
  return new OffscreenCanvas(e, n);
1131
1141
  if (typeof document < "u") {
@@ -1134,7 +1144,7 @@ function Mt(e, n) {
1134
1144
  }
1135
1145
  throw new Error("No canvas context available");
1136
1146
  }
1137
- function Jn(e, n, t, a, r = 0) {
1147
+ function re(e, n, t, a, r = 0) {
1138
1148
  if (t <= 0 || a <= 0 || e <= 0 || n <= 0)
1139
1149
  return { width: e + r, height: n + r };
1140
1150
  const o = t / a, s = e / n;
@@ -1144,11 +1154,11 @@ function Jn(e, n, t, a, r = 0) {
1144
1154
  height: i + r
1145
1155
  };
1146
1156
  }
1147
- const tn = 64, Sn = 512;
1148
- function Ot(e, n) {
1157
+ const rn = 64, _n = 512;
1158
+ function Ht(e, n) {
1149
1159
  e.beginPath(), e.arc(n / 2, n / 2, n * 0.45, 0, Math.PI * 2), e.fill();
1150
1160
  }
1151
- function Rt(e, n) {
1161
+ function Vt(e, n) {
1152
1162
  const t = n / 2, a = n / 2, r = n * 0.45, o = r * 0.4, s = 5;
1153
1163
  e.beginPath();
1154
1164
  for (let c = 0; c < s * 2; c++) {
@@ -1157,15 +1167,15 @@ function Rt(e, n) {
1157
1167
  }
1158
1168
  e.closePath(), e.fill();
1159
1169
  }
1160
- function Bt(e, n) {
1170
+ function jt(e, n) {
1161
1171
  const t = n / 2, a = n * 0.42;
1162
1172
  e.beginPath(), e.moveTo(t, n * 0.82), e.bezierCurveTo(t - a * 1.1, n * 0.6, t - a * 1.3, n * 0.2, t, n * 0.35), e.bezierCurveTo(t + a * 1.3, n * 0.2, t + a * 1.1, n * 0.6, t, n * 0.82), e.closePath(), e.fill();
1163
1173
  }
1164
- function Lt(e, n) {
1174
+ function qt(e, n) {
1165
1175
  const t = n / 2, a = n / 2, r = n * 0.4, o = n * 0.48;
1166
1176
  e.beginPath(), e.moveTo(t, a - o), e.lineTo(t + r, a), e.lineTo(t, a + o), e.lineTo(t - r, a), e.closePath(), e.fill();
1167
1177
  }
1168
- function Nt(e, n) {
1178
+ function Xt(e, n) {
1169
1179
  const t = n / 2, a = n / 2, r = n * 0.44;
1170
1180
  e.beginPath();
1171
1181
  for (let o = 0; o < 6; o++) {
@@ -1174,11 +1184,11 @@ function Nt(e, n) {
1174
1184
  }
1175
1185
  e.closePath(), e.fill();
1176
1186
  }
1177
- function Ut(e, n) {
1187
+ function Yt(e, n) {
1178
1188
  const t = n / 2, a = n * 0.4, r = n * 0.12;
1179
1189
  e.beginPath(), e.moveTo(t, r), e.lineTo(t + a, n * 0.25), e.lineTo(t + a, n * 0.55), e.quadraticCurveTo(t + a * 0.3, n * 0.8, t, n * 0.9), e.quadraticCurveTo(t - a * 0.3, n * 0.8, t - a, n * 0.55), e.lineTo(t - a, n * 0.25), e.closePath(), e.fill();
1180
1190
  }
1181
- function zt(e, n) {
1191
+ function Kt(e, n) {
1182
1192
  const t = n / 2, a = n / 2;
1183
1193
  let r = 42;
1184
1194
  const o = () => (r = (r * 16807 + 0) % 2147483647, r / 2147483647);
@@ -1188,7 +1198,7 @@ function zt(e, n) {
1188
1198
  e.beginPath(), e.arc(t + Math.cos(c) * i, a + Math.sin(c) * i, l, 0, Math.PI * 2), e.fill();
1189
1199
  }
1190
1200
  }
1191
- function Wt(e, n) {
1201
+ function Jt(e, n) {
1192
1202
  let t = 123;
1193
1203
  const a = () => (t = (t * 16807 + 0) % 2147483647, t / 2147483647), r = n * 0.08, o = 40;
1194
1204
  e.beginPath(), e.moveTo(r, r);
@@ -1210,7 +1220,7 @@ function Wt(e, n) {
1210
1220
  }
1211
1221
  e.closePath(), e.fill();
1212
1222
  }
1213
- function Gt(e, n) {
1223
+ function Zt(e, n) {
1214
1224
  let t = 77;
1215
1225
  const a = () => (t = (t * 16807 + 0) % 2147483647, t / 2147483647), r = n * 0.25, o = n * 0.75, s = n * 0.1;
1216
1226
  e.beginPath(), e.moveTo(s, r + a() * n * 0.05);
@@ -1224,101 +1234,101 @@ function Gt(e, n) {
1224
1234
  }
1225
1235
  e.closePath(), e.fill();
1226
1236
  }
1227
- function Ht(e, n) {
1237
+ function Qt(e, n) {
1228
1238
  const t = n / 2, a = n * 0.55;
1229
1239
  e.beginPath(), e.arc(t, a, n * 0.2, 0, Math.PI * 2), e.fill(), e.beginPath(), e.arc(t - n * 0.18, a + n * 0.02, n * 0.15, 0, Math.PI * 2), e.fill(), e.beginPath(), e.arc(t + n * 0.18, a + n * 0.02, n * 0.16, 0, Math.PI * 2), e.fill(), e.beginPath(), e.arc(t - n * 0.06, a - n * 0.14, n * 0.14, 0, Math.PI * 2), e.fill(), e.beginPath(), e.arc(t + n * 0.1, a - n * 0.12, n * 0.12, 0, Math.PI * 2), e.fill();
1230
1240
  }
1231
- const Vt = [
1241
+ const na = [
1232
1242
  // Geometric
1233
- { id: "circle", name: "Circle", description: "Perfect circle", imageUrl: "builtin-mask:circle", thumbnailUrl: "", category: "geometric", draw: Ot },
1234
- { id: "star", name: "Star", description: "5-pointed star", imageUrl: "builtin-mask:star", thumbnailUrl: "", category: "geometric", draw: Rt },
1235
- { id: "heart", name: "Heart", description: "Heart shape", imageUrl: "builtin-mask:heart", thumbnailUrl: "", category: "geometric", draw: Bt },
1236
- { id: "diamond", name: "Diamond", description: "Diamond/rhombus", imageUrl: "builtin-mask:diamond", thumbnailUrl: "", category: "geometric", draw: Lt },
1237
- { id: "hexagon", name: "Hexagon", description: "Regular hexagon", imageUrl: "builtin-mask:hexagon", thumbnailUrl: "", category: "geometric", draw: Nt },
1238
- { id: "shield", name: "Shield", description: "Shield/crest shape", imageUrl: "builtin-mask:shield", thumbnailUrl: "", category: "geometric", draw: Ut },
1243
+ { id: "circle", name: "Circle", description: "Perfect circle", imageUrl: "builtin-mask:circle", thumbnailUrl: "", category: "geometric", draw: Ht },
1244
+ { id: "star", name: "Star", description: "5-pointed star", imageUrl: "builtin-mask:star", thumbnailUrl: "", category: "geometric", draw: Vt },
1245
+ { id: "heart", name: "Heart", description: "Heart shape", imageUrl: "builtin-mask:heart", thumbnailUrl: "", category: "geometric", draw: jt },
1246
+ { id: "diamond", name: "Diamond", description: "Diamond/rhombus", imageUrl: "builtin-mask:diamond", thumbnailUrl: "", category: "geometric", draw: qt },
1247
+ { id: "hexagon", name: "Hexagon", description: "Regular hexagon", imageUrl: "builtin-mask:hexagon", thumbnailUrl: "", category: "geometric", draw: Xt },
1248
+ { id: "shield", name: "Shield", description: "Shield/crest shape", imageUrl: "builtin-mask:shield", thumbnailUrl: "", category: "geometric", draw: Yt },
1239
1249
  // Organic
1240
- { id: "splatter", name: "Splatter", description: "Ink splatter", imageUrl: "builtin-mask:splatter", thumbnailUrl: "", category: "organic", draw: zt },
1241
- { id: "torn-edge", name: "Torn Edge", description: "Rough torn paper edge", imageUrl: "builtin-mask:torn-edge", thumbnailUrl: "", category: "organic", draw: Wt },
1242
- { id: "paint-stroke", name: "Paint Stroke", description: "Horizontal brush stroke", imageUrl: "builtin-mask:paint-stroke", thumbnailUrl: "", category: "organic", draw: Gt },
1243
- { id: "cloud", name: "Cloud", description: "Soft cloud shape", imageUrl: "builtin-mask:cloud", thumbnailUrl: "", category: "organic", draw: Ht }
1250
+ { id: "splatter", name: "Splatter", description: "Ink splatter", imageUrl: "builtin-mask:splatter", thumbnailUrl: "", category: "organic", draw: Kt },
1251
+ { id: "torn-edge", name: "Torn Edge", description: "Rough torn paper edge", imageUrl: "builtin-mask:torn-edge", thumbnailUrl: "", category: "organic", draw: Jt },
1252
+ { id: "paint-stroke", name: "Paint Stroke", description: "Horizontal brush stroke", imageUrl: "builtin-mask:paint-stroke", thumbnailUrl: "", category: "organic", draw: Zt },
1253
+ { id: "cloud", name: "Cloud", description: "Soft cloud shape", imageUrl: "builtin-mask:cloud", thumbnailUrl: "", category: "organic", draw: Qt }
1244
1254
  ];
1245
- let Zn = !1;
1246
- function Qn(e, n) {
1255
+ let se = !1;
1256
+ function ie(e, n) {
1247
1257
  if (typeof document > "u") return null;
1248
1258
  const t = document.createElement("canvas");
1249
1259
  return t.width = e, t.height = n, t;
1250
1260
  }
1251
- function jt() {
1252
- if (typeof document > "u" || Zn) return;
1253
- Zn = !0;
1254
- const e = $n.getInstance();
1255
- for (const n of Vt) {
1256
- const t = Qn(Sn, Sn);
1261
+ function ea() {
1262
+ if (typeof document > "u" || se) return;
1263
+ se = !0;
1264
+ const e = wn.getInstance();
1265
+ for (const n of na) {
1266
+ const t = ie(_n, _n);
1257
1267
  if (!t) continue;
1258
1268
  const a = t.getContext("2d");
1259
1269
  if (!a) continue;
1260
- a.fillStyle = "white", n.draw(a, Sn);
1270
+ a.fillStyle = "white", n.draw(a, _n);
1261
1271
  const r = t.toDataURL("image/png"), o = e.acquire(n.imageUrl);
1262
1272
  o.crossOrigin = "anonymous", o.src = r;
1263
- const s = Qn(tn, tn);
1273
+ const s = ie(rn, rn);
1264
1274
  if (s) {
1265
1275
  const c = s.getContext("2d");
1266
- c && (c.fillStyle = "#1a1a2e", c.fillRect(0, 0, tn, tn), c.fillStyle = "white", n.draw(c, tn), n.thumbnailUrl = s.toDataURL("image/png"));
1276
+ c && (c.fillStyle = "#1a1a2e", c.fillRect(0, 0, rn, rn), c.fillStyle = "white", n.draw(c, rn), n.thumbnailUrl = s.toDataURL("image/png"));
1267
1277
  }
1268
1278
  }
1269
1279
  }
1270
- const qt = N("MaskRenderer"), Dn = /* @__PURE__ */ new Map(), Xt = /* @__PURE__ */ new Map();
1271
- function Aa(e) {
1280
+ const ta = U("MaskRenderer"), Rn = /* @__PURE__ */ new Map(), aa = /* @__PURE__ */ new Map();
1281
+ function za(e) {
1272
1282
  const n = [];
1273
- Dn.forEach((t, a) => {
1283
+ Rn.forEach((t, a) => {
1274
1284
  a.startsWith(e) && n.push(a);
1275
- }), n.forEach((t) => Dn.delete(t));
1285
+ }), n.forEach((t) => Rn.delete(t));
1276
1286
  }
1277
- function Pa() {
1278
- Dn.clear();
1287
+ function Ga() {
1288
+ Rn.clear();
1279
1289
  }
1280
- function ne(e, n, t) {
1290
+ function oe(e, n, t) {
1281
1291
  if (!n.masks || n.masks.length === 0) {
1282
1292
  t(e);
1283
1293
  return;
1284
1294
  }
1285
- const a = e.canvas, r = pn(a.width, a.height), o = r.getContext("2d");
1295
+ const a = e.canvas, r = gn(a.width, a.height), o = r.getContext("2d");
1286
1296
  if (!o) {
1287
- qt.error("[renderWithMasks] Failed to get offscreen context");
1297
+ ta.error("[renderWithMasks] Failed to get offscreen context");
1288
1298
  return;
1289
1299
  }
1290
1300
  const s = e.getTransform();
1291
1301
  o.setTransform(s), t(o);
1292
1302
  for (const c of n.masks)
1293
- Yt(o, c, n);
1303
+ ra(o, c, n);
1294
1304
  e.save(), e.setTransform(1, 0, 0, 1, 0, 0), e.drawImage(r, 0, 0), e.restore();
1295
1305
  }
1296
- function Yt(e, n, t) {
1306
+ function ra(e, n, t) {
1297
1307
  switch (n.type) {
1298
1308
  case "clip":
1299
- Kt(e, n, t);
1309
+ sa(e, n, t);
1300
1310
  break;
1301
1311
  case "alpha":
1302
- Jt(e, n, t);
1312
+ ia(e, n, t);
1303
1313
  break;
1304
1314
  case "luma":
1305
- Zt(e, n, t);
1315
+ oa(e, n, t);
1306
1316
  break;
1307
1317
  case "distress":
1308
- Qt(e, n, t);
1318
+ ca(e, n, t);
1309
1319
  break;
1310
1320
  }
1311
1321
  }
1312
- function Kt(e, n, t) {
1313
- e.save(), e.globalCompositeOperation = n.inverted ? "destination-out" : "destination-in", n.opacity !== void 0 && (e.globalAlpha = n.opacity), xn(e, n.maskElement, t), e.restore();
1322
+ function sa(e, n, t) {
1323
+ e.save(), e.globalCompositeOperation = n.inverted ? "destination-out" : "destination-in", n.opacity !== void 0 && (e.globalAlpha = n.opacity), Sn(e, n.maskElement, t), e.restore();
1314
1324
  }
1315
- function Jt(e, n, t) {
1316
- e.save(), e.globalCompositeOperation = n.inverted ? "destination-out" : "destination-in", n.opacity !== void 0 && (e.globalAlpha = n.opacity), xn(e, n.maskElement, t), n.feather && n.feather > 0 && _e(e, n.feather), e.restore();
1325
+ function ia(e, n, t) {
1326
+ e.save(), e.globalCompositeOperation = n.inverted ? "destination-out" : "destination-in", n.opacity !== void 0 && (e.globalAlpha = n.opacity), Sn(e, n.maskElement, t), n.feather && n.feather > 0 && Oe(e, n.feather), e.restore();
1317
1327
  }
1318
- function Zt(e, n, t) {
1319
- const a = pn(e.canvas.width, e.canvas.height), r = a.getContext("2d");
1328
+ function oa(e, n, t) {
1329
+ const a = gn(e.canvas.width, e.canvas.height), r = a.getContext("2d");
1320
1330
  if (!r) return;
1321
- xn(r, n.maskElement, t);
1331
+ Sn(r, n.maskElement, t);
1322
1332
  const o = r.getImageData(0, 0, a.width, a.height), s = o.data;
1323
1333
  for (let c = 0; c < s.length; c += 4) {
1324
1334
  const i = s[c], l = s[c + 1], d = s[c + 2], u = 0.299 * i + 0.587 * l + 0.114 * d;
@@ -1326,10 +1336,10 @@ function Zt(e, n, t) {
1326
1336
  }
1327
1337
  r.putImageData(o, 0, 0), e.save(), e.globalCompositeOperation = "destination-in", n.opacity !== void 0 && (e.globalAlpha = n.opacity), e.drawImage(a, 0, 0), e.restore();
1328
1338
  }
1329
- function Qt(e, n, t) {
1330
- e.save(), e.globalCompositeOperation = n.inverted ? "destination-in" : "destination-out", n.opacity !== void 0 && (e.globalAlpha = n.opacity), xn(e, n.maskElement, t), n.feather && n.feather > 0 && _e(e, n.feather), e.restore();
1339
+ function ca(e, n, t) {
1340
+ e.save(), e.globalCompositeOperation = n.inverted ? "destination-in" : "destination-out", n.opacity !== void 0 && (e.globalAlpha = n.opacity), Sn(e, n.maskElement, t), n.feather && n.feather > 0 && Oe(e, n.feather), e.restore();
1331
1341
  }
1332
- function xn(e, n, t) {
1342
+ function Sn(e, n, t) {
1333
1343
  const a = t.x || 0, r = t.y || 0, o = n.x || 0, s = n.y || 0, c = {
1334
1344
  ...n,
1335
1345
  x: a + o,
@@ -1342,49 +1352,49 @@ function xn(e, n, t) {
1342
1352
  width: u + i,
1343
1353
  height: p + i
1344
1354
  });
1345
- let m, b;
1355
+ let $, h;
1346
1356
  if (n.transformType === "image") {
1347
- const g = n;
1348
- if (g.imageUrl)
1357
+ const m = n;
1358
+ if (m.imageUrl)
1349
1359
  if (typeof document < "u") {
1350
- g.imageUrl.startsWith("builtin-mask:") && jt();
1351
- const y = $n.getInstance(), k = y.acquire(g.imageUrl);
1352
- k.complete && k.naturalWidth > 0 && (m = k), y.release(g.imageUrl);
1360
+ m.imageUrl.startsWith("builtin-mask:") && ea();
1361
+ const g = wn.getInstance(), C = g.acquire(m.imageUrl);
1362
+ C.complete && C.naturalWidth > 0 && ($ = C), g.release(m.imageUrl);
1353
1363
  } else
1354
- b = Xt.get(g.imageUrl);
1364
+ h = aa.get(m.imageUrl);
1355
1365
  }
1356
- const h = c.transformData, S = (f == null ? void 0 : f.width) || 0, $ = (f == null ? void 0 : f.height) || 0, v = S > 0 && $ > 0 && u > 0 && p > 0 && Math.abs(S / $ - u / p) > 1e-3;
1357
- if (b) {
1366
+ const b = c.transformData, v = (f == null ? void 0 : f.width) || 0, y = (f == null ? void 0 : f.height) || 0, x = v > 0 && y > 0 && u > 0 && p > 0 && Math.abs(v / y - u / p) > 1e-3;
1367
+ if (h) {
1358
1368
  e.save();
1359
- const g = (h == null ? void 0 : h.width) || b.width, y = (h == null ? void 0 : h.height) || b.height;
1360
- if (e.translate(c.x || 0, c.y || 0), e.rotate(-(c.rotation || 0) * Math.PI / 180), v) {
1361
- const k = Jn(
1369
+ const m = (b == null ? void 0 : b.width) || h.width, g = (b == null ? void 0 : b.height) || h.height;
1370
+ if (e.translate(c.x || 0, c.y || 0), e.rotate(-(c.rotation || 0) * Math.PI / 180), x) {
1371
+ const C = re(
1372
+ m,
1362
1373
  g,
1374
+ v,
1363
1375
  y,
1364
- S,
1365
- $,
1366
1376
  0
1367
1377
  );
1368
- e.drawImage(b, -k.width / 2, -k.height / 2, k.width, k.height);
1378
+ e.drawImage(h, -C.width / 2, -C.height / 2, C.width, C.height);
1369
1379
  } else
1370
- e.drawImage(b, -g / 2, -y / 2, g, y);
1380
+ e.drawImage(h, -m / 2, -g / 2, m, g);
1371
1381
  e.restore();
1372
- } else if (v && m) {
1373
- const g = (h == null ? void 0 : h.width) || u, y = (h == null ? void 0 : h.height) || p, k = Jn(
1382
+ } else if (x && $) {
1383
+ const m = (b == null ? void 0 : b.width) || u, g = (b == null ? void 0 : b.height) || p, C = re(
1384
+ m,
1374
1385
  g,
1386
+ v,
1375
1387
  y,
1376
- S,
1377
- $,
1378
1388
  0
1379
1389
  );
1380
- e.save(), e.translate(c.x || 0, c.y || 0), e.rotate(-(c.rotation || 0) * Math.PI / 180), e.drawImage(m, -k.width / 2, -k.height / 2, k.width, k.height), e.restore();
1390
+ e.save(), e.translate(c.x || 0, c.y || 0), e.rotate(-(c.rotation || 0) * Math.PI / 180), e.drawImage($, -C.width / 2, -C.height / 2, C.width, C.height), e.restore();
1381
1391
  } else
1382
- zn(e, c, { mode: "both", loadedImage: m });
1392
+ qn(e, c, { mode: "both", loadedImage: $ });
1383
1393
  }
1384
- function _e(e, n) {
1394
+ function Oe(e, n) {
1385
1395
  "filter" in e && (e.filter = `blur(${n}px)`);
1386
1396
  }
1387
- function pn(e, n) {
1397
+ function gn(e, n) {
1388
1398
  if (typeof OffscreenCanvas < "u")
1389
1399
  return new OffscreenCanvas(e, n);
1390
1400
  if (typeof document < "u") {
@@ -1393,51 +1403,51 @@ function pn(e, n) {
1393
1403
  }
1394
1404
  throw new Error("No canvas context available");
1395
1405
  }
1396
- function na(e, n, t, a) {
1406
+ function la(e, n, t, a) {
1397
1407
  if (!n.enabled || !n.imageUrl || n.opacity <= 0) return;
1398
- const r = $n.getInstance(), o = r.acquire(n.imageUrl);
1408
+ const r = wn.getInstance(), o = r.acquire(n.imageUrl);
1399
1409
  if (!o.complete || o.naturalWidth === 0) {
1400
1410
  r.release(n.imageUrl);
1401
1411
  return;
1402
1412
  }
1403
- const { x: s, y: c, width: i, height: l } = t, d = e.getTransform(), u = d.a * s + d.e, p = d.d * c + d.f, f = d.a * i, m = d.d * l, b = Math.ceil(f), h = Math.ceil(m);
1404
- if (b <= 0 || h <= 0) {
1413
+ const { x: s, y: c, width: i, height: l } = t, d = e.getTransform(), u = d.a * s + d.e, p = d.d * c + d.f, f = d.a * i, $ = d.d * l, h = Math.ceil(f), b = Math.ceil($);
1414
+ if (h <= 0 || b <= 0) {
1405
1415
  r.release(n.imageUrl);
1406
1416
  return;
1407
1417
  }
1408
- const S = pn(b, h), $ = S.getContext("2d");
1409
- if (!$) {
1418
+ const v = gn(h, b), y = v.getContext("2d");
1419
+ if (!y) {
1410
1420
  r.release(n.imageUrl);
1411
1421
  return;
1412
1422
  }
1413
- $.drawImage(
1423
+ y.drawImage(
1414
1424
  e.canvas,
1415
1425
  u,
1416
1426
  p,
1417
1427
  f,
1418
- m,
1428
+ $,
1419
1429
  0,
1420
1430
  0,
1421
- b,
1422
- h
1431
+ h,
1432
+ b
1423
1433
  );
1424
- let v;
1425
- if (n.maskType === "luma" ? v = "destination-in" : v = n.inverted ? "destination-out" : "destination-in", n.maskType === "luma") {
1426
- const g = pn(b, h), y = g.getContext("2d");
1427
- if (y) {
1428
- y.drawImage(o, 0, 0, b, h);
1429
- const k = y.getImageData(0, 0, b, h), T = k.data;
1430
- for (let C = 0; C < T.length; C += 4) {
1431
- const _ = 0.299 * T[C] + 0.587 * T[C + 1] + 0.114 * T[C + 2];
1432
- T[C + 3] = n.inverted ? 255 - _ : _;
1434
+ let x;
1435
+ if (n.maskType === "luma" ? x = "destination-in" : x = n.inverted ? "destination-out" : "destination-in", n.maskType === "luma") {
1436
+ const m = gn(h, b), g = m.getContext("2d");
1437
+ if (g) {
1438
+ g.drawImage(o, 0, 0, h, b);
1439
+ const C = g.getImageData(0, 0, h, b), T = C.data;
1440
+ for (let k = 0; k < T.length; k += 4) {
1441
+ const _ = 0.299 * T[k] + 0.587 * T[k + 1] + 0.114 * T[k + 2];
1442
+ T[k + 3] = n.inverted ? 255 - _ : _;
1433
1443
  }
1434
- y.putImageData(k, 0, 0), $.globalCompositeOperation = "destination-in", $.globalAlpha = n.opacity / 100, $.drawImage(g, 0, 0);
1444
+ g.putImageData(C, 0, 0), y.globalCompositeOperation = "destination-in", y.globalAlpha = n.opacity / 100, y.drawImage(m, 0, 0);
1435
1445
  }
1436
1446
  } else
1437
- $.globalCompositeOperation = v, $.globalAlpha = n.opacity / 100, $.drawImage(o, 0, 0, b, h);
1438
- $.globalCompositeOperation = "source-over", $.globalAlpha = 1, e.save(), e.setTransform(1, 0, 0, 1, 0, 0), e.clearRect(u, p, f, m), a && (e.fillStyle = a, e.fillRect(u, p, f, m)), e.drawImage(S, u, p), e.restore(), r.release(n.imageUrl);
1447
+ y.globalCompositeOperation = x, y.globalAlpha = n.opacity / 100, y.drawImage(o, 0, 0, h, b);
1448
+ y.globalCompositeOperation = "source-over", y.globalAlpha = 1, e.save(), e.setTransform(1, 0, 0, 1, 0, 0), e.clearRect(u, p, f, $), a && (e.fillStyle = a, e.fillRect(u, p, f, $)), e.drawImage(v, u, p), e.restore(), r.release(n.imageUrl);
1439
1449
  }
1440
- class ea {
1450
+ class da {
1441
1451
  constructor(n = Math.random()) {
1442
1452
  this.perm = [];
1443
1453
  for (let a = 0; a < 256; a++)
@@ -1475,55 +1485,55 @@ class ea {
1475
1485
  );
1476
1486
  }
1477
1487
  }
1478
- function Cn(e, n, t, a = Date.now()) {
1479
- const s = vn(e, n).getContext("2d").createImageData(e, n), c = s.data, i = new ea(a), l = 0.02, d = 1 - t / 100;
1488
+ function En(e, n, t, a = Date.now()) {
1489
+ const s = Cn(e, n).getContext("2d").createImageData(e, n), c = s.data, i = new da(a), l = 0.02, d = 1 - t / 100;
1480
1490
  for (let u = 0; u < n; u++)
1481
1491
  for (let p = 0; p < e; p++) {
1482
1492
  const f = (u * e + p) * 4;
1483
- let m = 0;
1484
- m += i.noise(p * l, u * l) * 0.5, m += i.noise(p * l * 2, u * l * 2) * 0.25, m += i.noise(p * l * 4, u * l * 4) * 0.125, m = (m + 1) / 2;
1485
- const b = Math.min(p / e, (e - p) / e) * 2, h = Math.min(u / n, (n - u) / n) * 2, S = Math.min(b, h);
1486
- m *= 0.7 + S * 0.3;
1487
- const $ = m > d ? 255 : 0;
1488
- c[f] = 255, c[f + 1] = 255, c[f + 2] = 255, c[f + 3] = $;
1493
+ let $ = 0;
1494
+ $ += i.noise(p * l, u * l) * 0.5, $ += i.noise(p * l * 2, u * l * 2) * 0.25, $ += i.noise(p * l * 4, u * l * 4) * 0.125, $ = ($ + 1) / 2;
1495
+ const h = Math.min(p / e, (e - p) / e) * 2, b = Math.min(u / n, (n - u) / n) * 2, v = Math.min(h, b);
1496
+ $ *= 0.7 + v * 0.3;
1497
+ const y = $ > d ? 255 : 0;
1498
+ c[f] = 255, c[f + 1] = 255, c[f + 2] = 255, c[f + 3] = y;
1489
1499
  }
1490
1500
  return s;
1491
1501
  }
1492
- function ta(e, n, t, a = Date.now()) {
1493
- const o = vn(e, n).getContext("2d");
1502
+ function fa(e, n, t, a = Date.now()) {
1503
+ const o = Cn(e, n).getContext("2d");
1494
1504
  o.clearRect(0, 0, e, n), o.strokeStyle = "#000000", o.lineWidth = 1 + t / 50, o.lineCap = "round";
1495
- const s = Wn(a), c = Math.floor(t / 100 * 30 + 5);
1505
+ const s = Xn(a), c = Math.floor(t / 100 * 30 + 5);
1496
1506
  for (let i = 0; i < c; i++) {
1497
1507
  const l = s() * e, d = s() * n;
1498
- Fn(o, l, d, s() * Math.PI * 2, 50 + s() * 100, s, 0);
1508
+ Bn(o, l, d, s() * Math.PI * 2, 50 + s() * 100, s, 0);
1499
1509
  }
1500
1510
  return o.getImageData(0, 0, e, n);
1501
1511
  }
1502
- function Fn(e, n, t, a, r, o, s) {
1512
+ function Bn(e, n, t, a, r, o, s) {
1503
1513
  if (s > 3 || r < 10) return;
1504
1514
  const c = n + Math.cos(a) * r, i = t + Math.sin(a) * r;
1505
1515
  if (e.beginPath(), e.moveTo(n, t), e.lineTo(c, i), e.stroke(), o() > 0.5) {
1506
1516
  const l = a + (o() - 0.5) * Math.PI / 2;
1507
- Fn(e, c, i, l, r * 0.6, o, s + 1);
1517
+ Bn(e, c, i, l, r * 0.6, o, s + 1);
1508
1518
  }
1509
1519
  if (o() > 0.7) {
1510
1520
  const l = a - (o() - 0.5) * Math.PI / 2;
1511
- Fn(e, c, i, l, r * 0.6, o, s + 1);
1521
+ Bn(e, c, i, l, r * 0.6, o, s + 1);
1512
1522
  }
1513
1523
  }
1514
- function un(e, n, t, a = Date.now()) {
1515
- const s = vn(e, n).getContext("2d").createImageData(e, n), c = s.data, i = Wn(a), l = t / 100 * 0.5;
1524
+ function bn(e, n, t, a = Date.now()) {
1525
+ const s = Cn(e, n).getContext("2d").createImageData(e, n), c = s.data, i = Xn(a), l = t / 100 * 0.5;
1516
1526
  for (let d = 0; d < n; d++)
1517
1527
  for (let u = 0; u < e; u++) {
1518
- const p = (d * e + u) * 4, m = i() < l ? 255 : 0;
1519
- c[p] = 0, c[p + 1] = 0, c[p + 2] = 0, c[p + 3] = m;
1528
+ const p = (d * e + u) * 4, $ = i() < l ? 255 : 0;
1529
+ c[p] = 0, c[p + 1] = 0, c[p + 2] = 0, c[p + 3] = $;
1520
1530
  }
1521
1531
  return s;
1522
1532
  }
1523
- function aa(e, n, t, a = Date.now()) {
1524
- const o = vn(e, n).getContext("2d");
1533
+ function ua(e, n, t, a = Date.now()) {
1534
+ const o = Cn(e, n).getContext("2d");
1525
1535
  o.fillStyle = "#000000";
1526
- const s = Wn(a), c = 4 + t / 100 * 6, i = c * 2;
1536
+ const s = Xn(a), c = 4 + t / 100 * 6, i = c * 2;
1527
1537
  for (let l = 0; l < n; l += i)
1528
1538
  for (let d = 0; d < e; d += i)
1529
1539
  if (s() < t / 100) {
@@ -1532,7 +1542,7 @@ function aa(e, n, t, a = Date.now()) {
1532
1542
  }
1533
1543
  return o.getImageData(0, 0, e, n);
1534
1544
  }
1535
- function vn(e, n) {
1545
+ function Cn(e, n) {
1536
1546
  if (typeof OffscreenCanvas < "u")
1537
1547
  return new OffscreenCanvas(e, n);
1538
1548
  if (typeof document < "u") {
@@ -1541,31 +1551,31 @@ function vn(e, n) {
1541
1551
  }
1542
1552
  throw new Error("No canvas context available");
1543
1553
  }
1544
- function Wn(e) {
1554
+ function Xn(e) {
1545
1555
  let n = Math.sin(e++) * 1e4;
1546
1556
  return () => (n = Math.sin(e++) * 1e4, n - Math.floor(n));
1547
1557
  }
1548
- const L = 42, X = 512, Y = 64;
1549
- function Mn(e) {
1558
+ const N = 42, K = 512, J = 64;
1559
+ function Ln(e) {
1550
1560
  const n = e.data;
1551
1561
  for (let t = 0; t < n.length; t += 4)
1552
1562
  n[t] = 255, n[t + 1] = 255, n[t + 2] = 255;
1553
1563
  return e;
1554
1564
  }
1555
- function ra(e, n) {
1565
+ function pa(e, n) {
1556
1566
  const t = e.data, a = n.data;
1557
1567
  for (let r = 0; r < t.length; r += 4)
1558
1568
  t[r] = 255, t[r + 1] = 255, t[r + 2] = 255, t[r + 3] = Math.min(255, t[r + 3] + a[r + 3]);
1559
1569
  return e;
1560
1570
  }
1561
- const sa = [
1571
+ const ha = [
1562
1572
  {
1563
1573
  id: "grunge-heavy",
1564
1574
  name: "Heavy Grunge",
1565
1575
  textureUrl: "builtin:grunge-heavy",
1566
1576
  thumbnailUrl: "",
1567
1577
  description: "Dense random splatters",
1568
- generate: (e, n) => un(e, n, 80, L)
1578
+ generate: (e, n) => bn(e, n, 80, N)
1569
1579
  },
1570
1580
  {
1571
1581
  id: "grunge-fine",
@@ -1573,7 +1583,7 @@ const sa = [
1573
1583
  textureUrl: "builtin:grunge-fine",
1574
1584
  thumbnailUrl: "",
1575
1585
  description: "Sparse fine grain",
1576
- generate: (e, n) => un(e, n, 25, L + 1)
1586
+ generate: (e, n) => bn(e, n, 25, N + 1)
1577
1587
  },
1578
1588
  {
1579
1589
  id: "concrete",
@@ -1581,7 +1591,7 @@ const sa = [
1581
1591
  textureUrl: "builtin:concrete",
1582
1592
  thumbnailUrl: "",
1583
1593
  description: "Rough surface via Perlin noise",
1584
- generate: (e, n) => Cn(e, n, 55, L + 2)
1594
+ generate: (e, n) => En(e, n, 55, N + 2)
1585
1595
  },
1586
1596
  {
1587
1597
  id: "paper",
@@ -1589,7 +1599,7 @@ const sa = [
1589
1599
  textureUrl: "builtin:paper",
1590
1600
  thumbnailUrl: "",
1591
1601
  description: "Subtle aging",
1592
- generate: (e, n) => Cn(e, n, 20, L + 3)
1602
+ generate: (e, n) => En(e, n, 20, N + 3)
1593
1603
  },
1594
1604
  {
1595
1605
  id: "rust",
@@ -1598,8 +1608,8 @@ const sa = [
1598
1608
  thumbnailUrl: "",
1599
1609
  description: "Noise + splatter combined",
1600
1610
  generate: (e, n) => {
1601
- const t = Cn(e, n, 45, L + 4), a = un(e, n, 35, L + 5);
1602
- return ra(Mn(t), Mn(a));
1611
+ const t = En(e, n, 45, N + 4), a = bn(e, n, 35, N + 5);
1612
+ return pa(Ln(t), Ln(a));
1603
1613
  }
1604
1614
  },
1605
1615
  {
@@ -1608,7 +1618,7 @@ const sa = [
1608
1618
  textureUrl: "builtin:scratches",
1609
1619
  thumbnailUrl: "",
1610
1620
  description: "Branching crack lines",
1611
- generate: (e, n) => ta(e, n, 55, L + 6)
1621
+ generate: (e, n) => fa(e, n, 55, N + 6)
1612
1622
  },
1613
1623
  {
1614
1624
  id: "halftone",
@@ -1616,7 +1626,7 @@ const sa = [
1616
1626
  textureUrl: "builtin:halftone",
1617
1627
  thumbnailUrl: "",
1618
1628
  description: "Dot grid pattern",
1619
- generate: (e, n) => aa(e, n, 55, L + 7)
1629
+ generate: (e, n) => ua(e, n, 55, N + 7)
1620
1630
  },
1621
1631
  {
1622
1632
  id: "spray",
@@ -1624,132 +1634,132 @@ const sa = [
1624
1634
  textureUrl: "builtin:spray",
1625
1635
  thumbnailUrl: "",
1626
1636
  description: "Medium random splatter",
1627
- generate: (e, n) => un(e, n, 55, L + 8)
1637
+ generate: (e, n) => bn(e, n, 55, N + 8)
1628
1638
  }
1629
1639
  ];
1630
- let ee = !1;
1631
- function ia(e, n) {
1640
+ let ce = !1;
1641
+ function ba(e, n) {
1632
1642
  if (typeof OffscreenCanvas < "u")
1633
1643
  return new OffscreenCanvas(e, n);
1634
1644
  const t = document.createElement("canvas");
1635
1645
  return t.width = e, t.height = n, t;
1636
1646
  }
1637
- function te(e, n) {
1647
+ function le(e, n) {
1638
1648
  if (typeof document > "u") return null;
1639
1649
  const t = document.createElement("canvas");
1640
1650
  return t.width = e, t.height = n, t;
1641
1651
  }
1642
- function oa(e) {
1643
- const n = te(e.width, e.height);
1652
+ function ga(e) {
1653
+ const n = le(e.width, e.height);
1644
1654
  if (!n) return "";
1645
1655
  const t = n.getContext("2d");
1646
1656
  if (!t) return "";
1647
1657
  t.putImageData(e, 0, 0);
1648
- const a = te(Y, Y);
1658
+ const a = le(J, J);
1649
1659
  if (!a) return "";
1650
1660
  const r = a.getContext("2d");
1651
1661
  if (!r) return "";
1652
- r.drawImage(n, 0, 0, e.width, e.height, 0, 0, Y, Y);
1653
- const o = r.getImageData(0, 0, Y, Y), s = o.data;
1662
+ r.drawImage(n, 0, 0, e.width, e.height, 0, 0, J, J);
1663
+ const o = r.getImageData(0, 0, J, J), s = o.data;
1654
1664
  for (let c = 0; c < s.length; c += 4) {
1655
1665
  const i = s[c + 3], l = 255 - Math.round(i / 255 * 195);
1656
1666
  s[c] = l, s[c + 1] = l, s[c + 2] = l, s[c + 3] = 255;
1657
1667
  }
1658
1668
  return r.putImageData(o, 0, 0), a.toDataURL("image/png");
1659
1669
  }
1660
- function ca() {
1661
- if (!ee) {
1662
- ee = !0;
1663
- for (const e of sa) {
1664
- const n = e.generate(X, X);
1665
- Mn(n);
1666
- const t = ia(X, X), a = t.getContext("2d");
1667
- a && (a.putImageData(n, 0, 0), la(e.textureUrl, t, X, X)), typeof document < "u" && (e.thumbnailUrl = oa(n));
1670
+ function ma() {
1671
+ if (!ce) {
1672
+ ce = !0;
1673
+ for (const e of ha) {
1674
+ const n = e.generate(K, K);
1675
+ Ln(n);
1676
+ const t = ba(K, K), a = t.getContext("2d");
1677
+ a && (a.putImageData(n, 0, 0), ya(e.textureUrl, t, K, K)), typeof document < "u" && (e.thumbnailUrl = ga(n));
1668
1678
  }
1669
1679
  }
1670
1680
  }
1671
- const W = /* @__PURE__ */ new Set(), G = /* @__PURE__ */ new Map(), hn = /* @__PURE__ */ new Map();
1672
- function ae(e, n) {
1681
+ const z = /* @__PURE__ */ new Set(), G = /* @__PURE__ */ new Map(), mn = /* @__PURE__ */ new Map();
1682
+ function de(e, n) {
1673
1683
  if (typeof OffscreenCanvas < "u")
1674
1684
  return new OffscreenCanvas(e, n);
1675
1685
  const t = document.createElement("canvas");
1676
1686
  return t.width = e, t.height = n, t;
1677
1687
  }
1678
- function re(e) {
1688
+ function fe(e) {
1679
1689
  return e.getContext("2d");
1680
1690
  }
1681
- function se(e) {
1682
- const { width: n, height: t } = e, a = ae(n, t), r = re(a);
1691
+ function ue(e) {
1692
+ const { width: n, height: t } = e, a = de(n, t), r = fe(a);
1683
1693
  if (!r) throw new Error("Failed to get 2d context for temp canvas");
1684
1694
  r.drawImage(e, 0, 0);
1685
1695
  const o = r.getImageData(0, 0, n, t), s = o.data;
1686
1696
  for (let l = 0; l < s.length; l += 4) {
1687
- const d = s[l], u = s[l + 1], p = s[l + 2], m = 255 - (0.299 * d + 0.587 * u + 0.114 * p);
1688
- s[l] = 255, s[l + 1] = 255, s[l + 2] = 255, s[l + 3] = m;
1697
+ const d = s[l], u = s[l + 1], p = s[l + 2], $ = 255 - (0.299 * d + 0.587 * u + 0.114 * p);
1698
+ s[l] = 255, s[l + 1] = 255, s[l + 2] = 255, s[l + 3] = $;
1689
1699
  }
1690
- const c = ae(n, t), i = re(c);
1700
+ const c = de(n, t), i = fe(c);
1691
1701
  if (!i) throw new Error("Failed to get 2d context for mask canvas");
1692
1702
  return i.putImageData(o, 0, 0), { alphaMask: c, width: n, height: t };
1693
1703
  }
1694
- function Ee(e) {
1704
+ function Re(e) {
1695
1705
  const n = G.get(e);
1696
1706
  if (n) return n;
1697
1707
  if (e.startsWith("builtin:")) {
1698
- ca();
1708
+ ma();
1699
1709
  const t = G.get(e);
1700
1710
  return t || null;
1701
1711
  }
1702
- return W.has(e) || (W.add(e), Ae(e)), null;
1712
+ return z.has(e) || (z.add(e), Be(e)), null;
1703
1713
  }
1704
- function Ia(e) {
1714
+ function Ha(e) {
1705
1715
  return G.has(e) ? Promise.resolve() : new Promise((n) => {
1706
1716
  if (G.has(e)) {
1707
1717
  n();
1708
1718
  return;
1709
1719
  }
1710
- const t = hn.get(e) || [];
1711
- t.push(n), hn.set(e, t), W.has(e) || (W.add(e), Ae(e));
1720
+ const t = mn.get(e) || [];
1721
+ t.push(n), mn.set(e, t), z.has(e) || (z.add(e), Be(e));
1712
1722
  });
1713
1723
  }
1714
- function la(e, n, t, a) {
1715
- G.has(e) || (G.set(e, { alphaMask: n, width: t, height: a }), an(e));
1724
+ function ya(e, n, t, a) {
1725
+ G.has(e) || (G.set(e, { alphaMask: n, width: t, height: a }), sn(e));
1716
1726
  }
1717
- function an(e) {
1718
- const n = hn.get(e);
1719
- n && (n.forEach((t) => t()), hn.delete(e));
1727
+ function sn(e) {
1728
+ const n = mn.get(e);
1729
+ n && (n.forEach((t) => t()), mn.delete(e));
1720
1730
  }
1721
- function Ae(e) {
1731
+ function Be(e) {
1722
1732
  if (typeof document < "u") {
1723
1733
  const n = new Image();
1724
1734
  n.crossOrigin = "anonymous", n.onload = () => {
1725
- const t = se(n);
1726
- G.set(e, t), W.delete(e), an(e);
1735
+ const t = ue(n);
1736
+ G.set(e, t), z.delete(e), sn(e);
1727
1737
  }, n.onerror = () => {
1728
- W.delete(e), an(e);
1738
+ z.delete(e), sn(e);
1729
1739
  }, n.src = e;
1730
1740
  } else
1731
1741
  fetch(e).then((n) => n.blob()).then((n) => createImageBitmap(n)).then((n) => {
1732
- const t = se(n);
1733
- G.set(e, t), W.delete(e), an(e);
1742
+ const t = ue(n);
1743
+ G.set(e, t), z.delete(e), sn(e);
1734
1744
  }).catch(() => {
1735
- W.delete(e), an(e);
1745
+ z.delete(e), sn(e);
1736
1746
  });
1737
1747
  }
1738
- function Pe(e, n) {
1748
+ function Le(e, n) {
1739
1749
  if (typeof OffscreenCanvas < "u")
1740
1750
  return new OffscreenCanvas(e, n);
1741
1751
  const t = document.createElement("canvas");
1742
1752
  return t.width = e, t.height = n, t;
1743
1753
  }
1744
- function da(e, n, t, a) {
1754
+ function $a(e, n, t, a) {
1745
1755
  if (!n.enabled || !n.textureUrl || n.intensity <= 0) return;
1746
- const r = Ee(n.textureUrl);
1756
+ const r = Re(n.textureUrl);
1747
1757
  if (!r) return;
1748
- const { x: o, y: s, width: c, height: i } = t, l = e.getTransform(), d = l.a * o + l.e, u = l.d * s + l.f, p = l.a * c, f = l.d * i, m = Math.ceil(p), b = Math.ceil(f);
1749
- if (m <= 0 || b <= 0) return;
1750
- const h = Pe(m, b), S = h.getContext("2d");
1751
- if (!S) return;
1752
- S.drawImage(
1758
+ const { x: o, y: s, width: c, height: i } = t, l = e.getTransform(), d = l.a * o + l.e, u = l.d * s + l.f, p = l.a * c, f = l.d * i, $ = Math.ceil(p), h = Math.ceil(f);
1759
+ if ($ <= 0 || h <= 0) return;
1760
+ const b = Le($, h), v = b.getContext("2d");
1761
+ if (!v) return;
1762
+ v.drawImage(
1753
1763
  e.canvas,
1754
1764
  d,
1755
1765
  u,
@@ -1757,27 +1767,27 @@ function da(e, n, t, a) {
1757
1767
  f,
1758
1768
  0,
1759
1769
  0,
1760
- m,
1761
- b
1770
+ $,
1771
+ h
1762
1772
  );
1763
- const $ = r.alphaMask.getContext("2d");
1764
- if ($) {
1765
- const v = n.intensity / 100, g = $.getImageData(0, 0, r.width, r.height).data, y = r.width, k = r.height, T = S.getImageData(0, 0, m, b), C = T.data;
1766
- for (let _ = 0; _ < b; _++) {
1767
- const w = Math.floor(_ / b * k);
1768
- for (let E = 0; E < m; E++) {
1769
- const x = Math.floor(E / m * y), P = g[(w * y + x) * 4 + 3] / 255, A = (_ * m + E) * 4;
1770
- C[A + 3] = Math.round(C[A + 3] * (1 - P * v));
1773
+ const y = r.alphaMask.getContext("2d");
1774
+ if (y) {
1775
+ const x = n.intensity / 100, m = y.getImageData(0, 0, r.width, r.height).data, g = r.width, C = r.height, T = v.getImageData(0, 0, $, h), k = T.data;
1776
+ for (let _ = 0; _ < h; _++) {
1777
+ const w = Math.floor(_ / h * C);
1778
+ for (let A = 0; A < $; A++) {
1779
+ const E = Math.floor(A / $ * g), S = m[(w * g + E) * 4 + 3] / 255, P = (_ * $ + A) * 4;
1780
+ k[P + 3] = Math.round(k[P + 3] * (1 - S * x));
1771
1781
  }
1772
1782
  }
1773
- S.putImageData(T, 0, 0);
1783
+ v.putImageData(T, 0, 0);
1774
1784
  } else
1775
- S.globalCompositeOperation = "destination-out", S.globalAlpha = n.intensity / 100, S.drawImage(r.alphaMask, 0, 0, m, b), S.globalCompositeOperation = "source-over";
1776
- S.globalAlpha = 1, e.save(), e.setTransform(1, 0, 0, 1, 0, 0), e.clearRect(d, u, p, f), a && (e.fillStyle = a, e.fillRect(d, u, p, f)), e.drawImage(h, d, u), e.restore();
1785
+ v.globalCompositeOperation = "destination-out", v.globalAlpha = n.intensity / 100, v.drawImage(r.alphaMask, 0, 0, $, h), v.globalCompositeOperation = "source-over";
1786
+ v.globalAlpha = 1, e.save(), e.setTransform(1, 0, 0, 1, 0, 0), e.clearRect(d, u, p, f), a && (e.fillStyle = a, e.fillRect(d, u, p, f)), e.drawImage(b, d, u), e.restore();
1777
1787
  }
1778
- function ie(e, n, t, a) {
1788
+ function pe(e, n, t, a) {
1779
1789
  if (!n.enabled || n.style !== "custom" || !n.textureUrl) return;
1780
- const r = Ee(n.textureUrl);
1790
+ const r = Re(n.textureUrl);
1781
1791
  if (!r) {
1782
1792
  a(e);
1783
1793
  return;
@@ -1787,40 +1797,40 @@ function ie(e, n, t, a) {
1787
1797
  y: t.y - p,
1788
1798
  width: t.width + u * 2,
1789
1799
  height: t.height + p * 2
1790
- }, m = s.a * f.x + s.e, b = s.d * f.y + s.f, h = s.a * f.width, S = s.d * f.height, $ = Math.ceil(h), v = Math.ceil(S);
1791
- if ($ <= 0 || v <= 0) {
1800
+ }, $ = s.a * f.x + s.e, h = s.d * f.y + s.f, b = s.a * f.width, v = s.d * f.height, y = Math.ceil(b), x = Math.ceil(v);
1801
+ if (y <= 0 || x <= 0) {
1792
1802
  a(e);
1793
1803
  return;
1794
1804
  }
1795
- const g = Pe($, v), y = g.getContext("2d");
1796
- if (!y) {
1805
+ const m = Le(y, x), g = m.getContext("2d");
1806
+ if (!g) {
1797
1807
  a(e);
1798
1808
  return;
1799
1809
  }
1800
- y.setTransform(
1810
+ g.setTransform(
1801
1811
  s.a,
1802
1812
  s.b,
1803
1813
  s.c,
1804
1814
  s.d,
1805
- s.e - m,
1806
- s.f - b
1807
- ), a(y), y.setTransform(1, 0, 0, 1, 0, 0);
1808
- const k = r.alphaMask.getContext("2d");
1809
- if (k) {
1810
- const T = k.getImageData(0, 0, r.width, r.height).data, C = r.width, _ = r.height, w = y.getImageData(0, 0, $, v), E = w.data;
1811
- for (let x = 0; x < v; x++) {
1812
- const P = Math.floor(x / v * _);
1813
- for (let A = 0; A < $; A++) {
1814
- const F = Math.floor(A / $ * C), D = T[(P * C + F) * 4 + 3] / 255, I = (x * $ + A) * 4;
1815
- E[I + 3] = Math.round(E[I + 3] * (1 - D * o));
1815
+ s.e - $,
1816
+ s.f - h
1817
+ ), a(g), g.setTransform(1, 0, 0, 1, 0, 0);
1818
+ const C = r.alphaMask.getContext("2d");
1819
+ if (C) {
1820
+ const T = C.getImageData(0, 0, r.width, r.height).data, k = r.width, _ = r.height, w = g.getImageData(0, 0, y, x), A = w.data;
1821
+ for (let E = 0; E < x; E++) {
1822
+ const S = Math.floor(E / x * _);
1823
+ for (let P = 0; P < y; P++) {
1824
+ const I = Math.floor(P / y * k), F = T[(S * k + I) * 4 + 3] / 255, D = (E * y + P) * 4;
1825
+ A[D + 3] = Math.round(A[D + 3] * (1 - F * o));
1816
1826
  }
1817
1827
  }
1818
- y.putImageData(w, 0, 0);
1828
+ g.putImageData(w, 0, 0);
1819
1829
  } else
1820
- y.globalCompositeOperation = "destination-out", y.globalAlpha = o, y.drawImage(r.alphaMask, 0, 0, $, v), y.globalCompositeOperation = "source-over", y.globalAlpha = 1;
1821
- e.save(), e.setTransform(1, 0, 0, 1, 0, 0), e.drawImage(g, m, b), e.restore();
1830
+ g.globalCompositeOperation = "destination-out", g.globalAlpha = o, g.drawImage(r.alphaMask, 0, 0, y, x), g.globalCompositeOperation = "source-over", g.globalAlpha = 1;
1831
+ e.save(), e.setTransform(1, 0, 0, 1, 0, 0), e.drawImage(m, $, h), e.restore();
1822
1832
  }
1823
- class bn {
1833
+ class yn {
1824
1834
  /**
1825
1835
  * Create an element instance from a JSON configuration
1826
1836
  * TypeScript ensures all transform types are handled
@@ -1833,33 +1843,33 @@ class bn {
1833
1843
  const { transformType: t } = n;
1834
1844
  switch (t) {
1835
1845
  case "custom":
1836
- return new Ke(n);
1846
+ return new st(n);
1837
1847
  case "distort":
1838
1848
  throw new Error("DistortTransform is not yet implemented");
1839
1849
  case "circle":
1840
- return new Ye(n);
1850
+ return new rt(n);
1841
1851
  case "lean":
1842
- return new Xe(n);
1852
+ return new at(n);
1843
1853
  case "arch":
1844
- return new qe(n);
1854
+ return new tt(n);
1845
1855
  case "ascend":
1846
- return new je(n);
1856
+ return new et(n);
1847
1857
  case "wave":
1848
- return new Ve(n);
1858
+ return new nt(n);
1849
1859
  case "flag":
1850
- return new He(n);
1860
+ return new Qe(n);
1851
1861
  case "image":
1852
- return new kn(n);
1862
+ return new An(n);
1853
1863
  case "group": {
1854
1864
  const r = (n.children || []).map(
1855
- (i) => bn.createFromJSON(i)
1856
- ), { children: o, ...s } = n, c = new pe(s);
1865
+ (i) => yn.createFromJSON(i)
1866
+ ), { children: o, ...s } = n, c = new xe(s);
1857
1867
  return r.forEach((i) => c.addChild(i)), c;
1858
1868
  }
1859
1869
  case "shape":
1860
- return new Ge(n);
1870
+ return new Ze(n);
1861
1871
  case "path":
1862
- return new We(n);
1872
+ return new Je(n);
1863
1873
  default:
1864
1874
  const a = t;
1865
1875
  throw new Error(`Unknown transform type: ${a}`);
@@ -2073,7 +2083,7 @@ class bn {
2073
2083
  return this.createFromJSON(t);
2074
2084
  }
2075
2085
  }
2076
- const oe = N("ImportManager"), Gn = class Gn {
2086
+ const he = U("ImportManager"), Kn = class Kn {
2077
2087
  /**
2078
2088
  * Import workspace from JSON file
2079
2089
  */
@@ -2088,7 +2098,7 @@ const oe = N("ImportManager"), Gn = class Gn {
2088
2098
  return this.migrateV1Document(a);
2089
2099
  const r = [], o = [];
2090
2100
  return a.artboards.forEach((s) => {
2091
- const c = Vn.fromJSON({
2101
+ const c = Zn.fromJSON({
2092
2102
  id: s.id,
2093
2103
  name: s.name,
2094
2104
  x: s.x,
@@ -2099,9 +2109,9 @@ const oe = N("ImportManager"), Gn = class Gn {
2099
2109
  elementIds: s.elements.map((l) => l.id || "")
2100
2110
  }), i = s.elements.map((l) => {
2101
2111
  try {
2102
- return bn.createFromJSON(l);
2112
+ return yn.createFromJSON(l);
2103
2113
  } catch (d) {
2104
- return oe.error("Failed to create element:", l, d), null;
2114
+ return he.error("Failed to create element:", l, d), null;
2105
2115
  }
2106
2116
  }).filter((l) => l !== null);
2107
2117
  r.push(c), o.push(...i);
@@ -2124,7 +2134,7 @@ const oe = N("ImportManager"), Gn = class Gn {
2124
2134
  static async migrateV1Document(n) {
2125
2135
  var t, a, r;
2126
2136
  try {
2127
- const o = n.elements || [], s = new Vn({
2137
+ const o = n.elements || [], s = new Zn({
2128
2138
  id: "artboard-migrated",
2129
2139
  name: "Artboard 1",
2130
2140
  x: 0,
@@ -2134,9 +2144,9 @@ const oe = N("ImportManager"), Gn = class Gn {
2134
2144
  backgroundColor: ((r = n.canvas) == null ? void 0 : r.backgroundColor) || "#ffffff"
2135
2145
  }), c = o.map((i) => {
2136
2146
  try {
2137
- return bn.createFromJSON(i);
2147
+ return yn.createFromJSON(i);
2138
2148
  } catch (l) {
2139
- return oe.error("Failed to create element:", i, l), null;
2149
+ return he.error("Failed to create element:", i, l), null;
2140
2150
  }
2141
2151
  }).filter((i) => i !== null);
2142
2152
  return c.forEach((i) => {
@@ -2287,14 +2297,14 @@ const oe = N("ImportManager"), Gn = class Gn {
2287
2297
  await Promise.all(r);
2288
2298
  }
2289
2299
  };
2290
- Gn.SUPPORTED_VERSIONS = ["1.0.0", "2.0.0"];
2291
- let ce = Gn;
2292
- const le = N("element-serializer"), Ie = 4e3, ln = /* @__PURE__ */ new Set();
2293
- function fa(e, n) {
2294
- const t = n ? ua(n) : "no-src";
2300
+ Kn.SUPPORTED_VERSIONS = ["1.0.0", "2.0.0"];
2301
+ let be = Kn;
2302
+ const ge = U("element-serializer"), Ne = 4e3, un = /* @__PURE__ */ new Set();
2303
+ function xa(e, n) {
2304
+ const t = n ? va(n) : "no-src";
2295
2305
  return `${e}:${t}`;
2296
2306
  }
2297
- function ua(e) {
2307
+ function va(e) {
2298
2308
  let n = 0;
2299
2309
  for (let t = 0; t < e.length; t++) {
2300
2310
  const a = e.charCodeAt(t);
@@ -2302,20 +2312,20 @@ function ua(e) {
2302
2312
  }
2303
2313
  return n.toString(36);
2304
2314
  }
2305
- function On() {
2306
- ln.clear();
2315
+ function Nn() {
2316
+ un.clear();
2307
2317
  }
2308
- function De(e) {
2309
- for (const n of ln)
2310
- n.startsWith(`${e}:`) && ln.delete(n);
2318
+ function Ue(e) {
2319
+ for (const n of un)
2320
+ n.startsWith(`${e}:`) && un.delete(n);
2311
2321
  }
2312
- function pa(e) {
2313
- ln.add(e);
2322
+ function wa(e) {
2323
+ un.add(e);
2314
2324
  }
2315
- function ha(e) {
2316
- return ln.has(e);
2325
+ function Sa(e) {
2326
+ return un.has(e);
2317
2327
  }
2318
- async function ba(e, n = Ie) {
2328
+ async function Ca(e, n = Ne) {
2319
2329
  const { naturalWidth: t, naturalHeight: a } = e;
2320
2330
  if (t <= n && a <= n)
2321
2331
  return createImageBitmap(e);
@@ -2326,20 +2336,20 @@ async function ba(e, n = Ie) {
2326
2336
  resizeQuality: "high"
2327
2337
  });
2328
2338
  }
2329
- let gn = null, mn = null;
2330
- function ga(e, n) {
2331
- gn = e, mn = n;
2339
+ let $n = null, xn = null;
2340
+ function ka(e, n) {
2341
+ $n = e, xn = n;
2332
2342
  }
2333
- function ma() {
2334
- gn = null, mn = null;
2343
+ function Ta() {
2344
+ $n = null, xn = null;
2335
2345
  }
2336
- function Da() {
2337
- On(), gn && gn();
2346
+ function Va() {
2347
+ Nn(), $n && $n();
2338
2348
  }
2339
- function Fa(e) {
2340
- De(e), mn && mn(e);
2349
+ function ja(e) {
2350
+ Ue(e), xn && xn(e);
2341
2351
  }
2342
- function Rn(e, n) {
2352
+ function Un(e, n) {
2343
2353
  const t = e;
2344
2354
  if (typeof t.fontFamily == "string" && n.add(t.fontFamily), t.richText && typeof t.richText == "object") {
2345
2355
  const a = t.richText;
@@ -2354,14 +2364,14 @@ function Rn(e, n) {
2354
2364
  }
2355
2365
  if (t.children && Array.isArray(t.children))
2356
2366
  for (const a of t.children)
2357
- Rn(a, n);
2367
+ Un(a, n);
2358
2368
  if (e.masks && Array.isArray(e.masks))
2359
2369
  for (const a of e.masks)
2360
- a.maskElement && Rn(a.maskElement, n);
2370
+ a.maskElement && Un(a.maskElement, n);
2361
2371
  }
2362
- function de(e) {
2372
+ function me(e) {
2363
2373
  if (typeof document > "u") return e;
2364
- const n = $n.getInstance();
2374
+ const n = wn.getInstance();
2365
2375
  return e.map((t) => {
2366
2376
  if (!(t != null && t.maskElement) || t.maskElement.transformType !== "image") return t;
2367
2377
  const a = t.maskElement.imageUrl;
@@ -2377,41 +2387,41 @@ function de(e) {
2377
2387
  } : t;
2378
2388
  });
2379
2389
  }
2380
- async function fe(e, n, t = Ie) {
2390
+ async function ye(e, n, t = Ne) {
2381
2391
  const a = n.filter((i) => e.hasElementId(i.id)), r = [], o = [], s = /* @__PURE__ */ new Set();
2382
2392
  for (const i of a) {
2383
2393
  const l = i.toJSON();
2384
- if (Rn(l, s), i instanceof kn && !i.imageElement) {
2385
- le.warn(`[element-serializer] Skipping image ${i.id}: image not loaded (state: ${i.imageLoadState})`);
2394
+ if (Un(l, s), i instanceof An && !i.imageElement) {
2395
+ ge.warn(`[element-serializer] Skipping image ${i.id}: image not loaded (state: ${i.imageLoadState})`);
2386
2396
  continue;
2387
2397
  }
2388
- if (i instanceof kn && i.imageElement)
2398
+ if (i instanceof An && i.imageElement)
2389
2399
  try {
2390
- const d = fa(i.id, i.imageUrl);
2391
- if (!ha(d)) {
2392
- const v = await ba(i.imageElement, t);
2393
- o.push({ cacheKey: d, bitmap: v }), pa(d);
2400
+ const d = xa(i.id, i.imageUrl);
2401
+ if (!Sa(d)) {
2402
+ const x = await Ca(i.imageElement, t);
2403
+ o.push({ cacheKey: d, bitmap: x }), wa(d);
2394
2404
  }
2395
- const p = i.transformData || {}, f = l.masks && l.masks.length > 0, m = f ? p.width : p.width * (p.cropWidth ?? 1), b = f ? p.height : p.height * (p.cropHeight ?? 1), h = {
2405
+ const p = i.transformData || {}, f = l.masks && l.masks.length > 0, $ = f ? p.width : p.width * (p.cropWidth ?? 1), h = f ? p.height : p.height * (p.cropHeight ?? 1), b = {
2396
2406
  id: i.id,
2397
2407
  type: "image",
2398
2408
  x: i.x,
2399
2409
  y: i.y,
2400
- width: m,
2401
- height: b,
2410
+ width: $,
2411
+ height: h,
2402
2412
  rotation: i.rotation || 0,
2403
2413
  bitmapCacheKey: d
2404
2414
  };
2405
2415
  if (!f && (p.cropX !== 0 || p.cropY !== 0 || p.cropWidth !== 1 || p.cropHeight !== 1)) {
2406
- const v = i.imageElement.naturalWidth, g = i.imageElement.naturalHeight;
2407
- let y = 1;
2408
- (v > t || g > t) && (y = t / Math.max(v, g)), h.cropX = p.cropX * v * y, h.cropY = p.cropY * g * y, h.cropWidth = p.cropWidth * v * y, h.cropHeight = p.cropHeight * g * y;
2416
+ const x = i.imageElement.naturalWidth, m = i.imageElement.naturalHeight;
2417
+ let g = 1;
2418
+ (x > t || m > t) && (g = t / Math.max(x, m)), b.cropX = p.cropX * x * g, b.cropY = p.cropY * m * g, b.cropWidth = p.cropWidth * x * g, b.cropHeight = p.cropHeight * m * g;
2409
2419
  }
2410
- p.flipHorizontal && (h.flipHorizontal = p.flipHorizontal), p.flipVertical && (h.flipVertical = p.flipVertical), p.borderRadius && (h.borderRadius = p.borderRadius), i.opacity !== void 0 && (h.opacity = i.opacity);
2411
- const $ = h;
2412
- i.distressEffect && ($.distressEffect = { ...i.distressEffect }), l.masks && l.masks.length > 0 && ($.masks = de(l.masks)), l.blendMode && ($.blendMode = l.blendMode), l.knockoutParts && ($.knockoutParts = l.knockoutParts), "getVisualBoundingBox" in i && typeof i.getVisualBoundingBox == "function" ? $._boundingBox = i.getVisualBoundingBox() : "getBoundingBox" in i && typeof i.getBoundingBox == "function" && ($._boundingBox = i.getBoundingBox()), r.push($);
2420
+ p.flipHorizontal && (b.flipHorizontal = p.flipHorizontal), p.flipVertical && (b.flipVertical = p.flipVertical), p.borderRadius && (b.borderRadius = p.borderRadius), i.opacity !== void 0 && (b.opacity = i.opacity);
2421
+ const y = b;
2422
+ i.distressEffect && (y.distressEffect = { ...i.distressEffect }), l.masks && l.masks.length > 0 && (y.masks = me(l.masks)), l.blendMode && (y.blendMode = l.blendMode), l.knockoutParts && (y.knockoutParts = l.knockoutParts), "getVisualBoundingBox" in i && typeof i.getVisualBoundingBox == "function" ? y._boundingBox = i.getVisualBoundingBox() : "getBoundingBox" in i && typeof i.getBoundingBox == "function" && (y._boundingBox = i.getBoundingBox()), r.push(y);
2413
2423
  } catch (d) {
2414
- le.error(`[element-serializer] Failed to create ImageBitmap for ${l.id}:`, d);
2424
+ ge.error(`[element-serializer] Failed to create ImageBitmap for ${l.id}:`, d);
2415
2425
  }
2416
2426
  else {
2417
2427
  const d = {
@@ -2419,7 +2429,7 @@ async function fe(e, n, t = Ie) {
2419
2429
  type: l.transformType
2420
2430
  // Map transformType to type for worker compatibility
2421
2431
  };
2422
- d.masks && Array.isArray(d.masks) && d.masks.length > 0 && (d.masks = de(d.masks)), "getVisualBoundingBox" in i && typeof i.getVisualBoundingBox == "function" ? d._boundingBox = i.getVisualBoundingBox() : "getBoundingBox" in i && typeof i.getBoundingBox == "function" && (d._boundingBox = i.getBoundingBox()), r.push(d);
2432
+ d.masks && Array.isArray(d.masks) && d.masks.length > 0 && (d.masks = me(d.masks)), "getVisualBoundingBox" in i && typeof i.getVisualBoundingBox == "function" ? d._boundingBox = i.getVisualBoundingBox() : "getBoundingBox" in i && typeof i.getBoundingBox == "function" && (d._boundingBox = i.getBoundingBox()), r.push(d);
2423
2433
  }
2424
2434
  }
2425
2435
  const c = Array.from(s);
@@ -2444,7 +2454,7 @@ async function fe(e, n, t = Ie) {
2444
2454
  newBitmaps: o
2445
2455
  };
2446
2456
  }
2447
- const ya = `"use strict";
2457
+ const _a = `"use strict";
2448
2458
  (() => {
2449
2459
  var __create = Object.create;
2450
2460
  var __defProp = Object.defineProperty;
@@ -21839,7 +21849,7 @@ const ya = `"use strict";
21839
21849
  * Check if two styles are equal
21840
21850
  */
21841
21851
  stylesEqual(a, b) {
21842
- return a.color === b.color && a.fontFamily === b.fontFamily && a.fontSize === b.fontSize && a.bold === b.bold && a.italic === b.italic && a.underline === b.underline && a.strikethrough === b.strikethrough;
21852
+ return a.color === b.color && a.fontFamily === b.fontFamily && a.fontSize === b.fontSize && a.bold === b.bold && a.italic === b.italic && a.underline === b.underline && a.strikethrough === b.strikethrough && a.letterSpacing === b.letterSpacing;
21843
21853
  }
21844
21854
  /**
21845
21855
  * Clone this RichText instance
@@ -22199,6 +22209,58 @@ const ya = `"use strict";
22199
22209
  ctx.restore();
22200
22210
  }
22201
22211
 
22212
+ // src/core/text-spacing.ts
22213
+ function countSpacedChars(text) {
22214
+ return Array.from(text).length;
22215
+ }
22216
+ function spacedTextWidth(rawWidth, text, letterSpacing) {
22217
+ if (!letterSpacing) return rawWidth;
22218
+ return rawWidth + letterSpacing * countSpacedChars(text);
22219
+ }
22220
+ function getSpacedCharOffsets(ctx, text, letterSpacing) {
22221
+ const chars = Array.from(text);
22222
+ const offsets = [0];
22223
+ let prefix = "";
22224
+ for (let i = 0; i < chars.length; i++) {
22225
+ prefix += chars[i];
22226
+ offsets.push(ctx.measureText(prefix).width + letterSpacing * (i + 1));
22227
+ }
22228
+ return offsets;
22229
+ }
22230
+ function leftAnchoredStartX(ctx, x, totalWidth) {
22231
+ switch (ctx.textAlign) {
22232
+ case "center":
22233
+ return x - totalWidth / 2;
22234
+ case "right":
22235
+ case "end":
22236
+ return x - totalWidth;
22237
+ default:
22238
+ return x;
22239
+ }
22240
+ }
22241
+ function drawTextWithSpacing(op, ctx, text, x, y, letterSpacing) {
22242
+ if (!letterSpacing || text.length === 0) {
22243
+ ctx[op](text, x, y);
22244
+ return;
22245
+ }
22246
+ const offsets = getSpacedCharOffsets(ctx, text, letterSpacing);
22247
+ const totalWidth = offsets[offsets.length - 1];
22248
+ const startX = leftAnchoredStartX(ctx, x, totalWidth);
22249
+ const previousAlign = ctx.textAlign;
22250
+ ctx.textAlign = "left";
22251
+ const chars = Array.from(text);
22252
+ for (let i = 0; i < chars.length; i++) {
22253
+ ctx[op](chars[i], startX + offsets[i], y);
22254
+ }
22255
+ ctx.textAlign = previousAlign;
22256
+ }
22257
+ function fillTextWithSpacing(ctx, text, x, y, letterSpacing) {
22258
+ drawTextWithSpacing("fillText", ctx, text, x, y, letterSpacing);
22259
+ }
22260
+ function strokeTextWithSpacing(ctx, text, x, y, letterSpacing) {
22261
+ drawTextWithSpacing("strokeText", ctx, text, x, y, letterSpacing);
22262
+ }
22263
+
22202
22264
  // src/core/TextMetrics.ts
22203
22265
  var _measureCanvas = null;
22204
22266
  function getMeasureCanvas() {
@@ -22225,10 +22287,12 @@ const ya = `"use strict";
22225
22287
  parts.push(fontFamily);
22226
22288
  return parts.join(" ");
22227
22289
  }
22228
- function wrapText(text, maxWidth, fontSize, fontFamily, bold = false, italic = false, lockedLineCount, strict = false) {
22290
+ function wrapText(text, maxWidth, fontSize, fontFamily, bold = false, italic = false, lockedLineCount, strict = false, opts) {
22229
22291
  const canvas = getMeasureCanvas();
22230
22292
  const ctx = canvas.getContext("2d");
22231
22293
  ctx.font = buildFontString2(fontSize, fontFamily, bold, italic);
22294
+ const letterSpacing = opts?.letterSpacing ?? 0;
22295
+ const measure = (t) => spacedTextWidth(ctx.measureText(t).width, t, letterSpacing);
22232
22296
  if (text.trim().length === 0) {
22233
22297
  return [text];
22234
22298
  }
@@ -22237,7 +22301,7 @@ const ya = `"use strict";
22237
22301
  const allWrappedLines = [];
22238
22302
  for (let i = 0; i < explicitLines.length; i++) {
22239
22303
  const line = explicitLines[i];
22240
- const wrappedLine = wrapText(line, maxWidth, fontSize, fontFamily, bold, italic, void 0, strict);
22304
+ const wrappedLine = wrapText(line, maxWidth, fontSize, fontFamily, bold, italic, void 0, strict, opts);
22241
22305
  allWrappedLines.push(...wrappedLine);
22242
22306
  }
22243
22307
  return allWrappedLines;
@@ -22266,7 +22330,7 @@ const ya = `"use strict";
22266
22330
  }
22267
22331
  const allText = words.join(" ");
22268
22332
  const allTextWithSpaces = leadingSpaces + allText + trailingSpaces;
22269
- const allTextWidth = ctx.measureText(allTextWithSpaces).width;
22333
+ const allTextWidth = measure(allTextWithSpaces);
22270
22334
  const isSmallSize = maxWidth < 200;
22271
22335
  const wrapTolerancePercent = strict ? 0 : isSmallSize ? 0.08 : 0.05;
22272
22336
  const wrapTolerance = strict ? 0 : Math.max(20, maxWidth * wrapTolerancePercent);
@@ -22279,7 +22343,7 @@ const ya = `"use strict";
22279
22343
  const lineTolerance = strict ? 0 : Math.max(15, maxWidth * lineTolerancePercent);
22280
22344
  for (let i = 0; i < words.length; i++) {
22281
22345
  const word = words[i];
22282
- const wordWidth = ctx.measureText(word).width;
22346
+ const wordWidth = measure(word);
22283
22347
  if (wordWidth > maxWidth + lineTolerance) {
22284
22348
  if (currentLine.length > 0) {
22285
22349
  lines.push(currentLine);
@@ -22289,7 +22353,7 @@ const ya = `"use strict";
22289
22353
  let charBuffer = "";
22290
22354
  for (const char of chars) {
22291
22355
  const testBuffer = charBuffer + char;
22292
- const bufferWidth = ctx.measureText(testBuffer).width;
22356
+ const bufferWidth = measure(testBuffer);
22293
22357
  if (bufferWidth > maxWidth + lineTolerance && charBuffer.length > 0) {
22294
22358
  lines.push(charBuffer);
22295
22359
  charBuffer = char;
@@ -22300,8 +22364,8 @@ const ya = `"use strict";
22300
22364
  currentLine = charBuffer;
22301
22365
  } else {
22302
22366
  const testLine = currentLine.length > 0 ? currentLine + " " + word : word;
22303
- const metrics = ctx.measureText(testLine);
22304
- if (metrics.width > maxWidth + lineTolerance && currentLine.length > 0) {
22367
+ const testLineWidth = measure(testLine);
22368
+ if (testLineWidth > maxWidth + lineTolerance && currentLine.length > 0) {
22305
22369
  lines.push(currentLine);
22306
22370
  currentLine = word;
22307
22371
  } else {
@@ -22315,7 +22379,7 @@ const ya = `"use strict";
22315
22379
  if (lines.length > 0) {
22316
22380
  if (leadingSpaces.length > 0) {
22317
22381
  const firstLineWithSpace = leadingSpaces + lines[0];
22318
- const firstLineWidth = ctx.measureText(firstLineWithSpace).width;
22382
+ const firstLineWidth = measure(firstLineWithSpace);
22319
22383
  if (firstLineWidth > maxWidth + lineTolerance) {
22320
22384
  lines.unshift(leadingSpaces);
22321
22385
  } else {
@@ -22325,7 +22389,7 @@ const ya = `"use strict";
22325
22389
  if (trailingSpaces.length > 0) {
22326
22390
  const lastIdx = lines.length - 1;
22327
22391
  const lastLineWithSpace = lines[lastIdx] + trailingSpaces;
22328
- const lastLineWidth = ctx.measureText(lastLineWithSpace).width;
22392
+ const lastLineWidth = measure(lastLineWithSpace);
22329
22393
  if (lastLineWidth > maxWidth + lineTolerance) {
22330
22394
  lines.push(trailingSpaces);
22331
22395
  } else {
@@ -22346,8 +22410,9 @@ const ya = `"use strict";
22346
22410
  const height = ascent + descent;
22347
22411
  return { ascent, descent, height };
22348
22412
  }
22349
- function calculateVisualBoundsWithSpaceCollapsing(text, maxWidth, fontSize, fontFamily, bold = false, italic = false, lockedLineCount, strict = false) {
22350
- const lines = wrapText(text, maxWidth, fontSize, fontFamily, bold, italic, lockedLineCount, strict);
22413
+ function calculateVisualBoundsWithSpaceCollapsing(text, maxWidth, fontSize, fontFamily, bold = false, italic = false, lockedLineCount, strict = false, opts) {
22414
+ const letterSpacing = opts?.letterSpacing ?? 0;
22415
+ const lines = wrapText(text, maxWidth, fontSize, fontFamily, bold, italic, lockedLineCount, strict, opts);
22351
22416
  const hasExplicitNewlines = text.includes("\\n");
22352
22417
  const paragraphMetadata = lines.map((_, index) => ({
22353
22418
  isParagraphStart: !hasExplicitNewlines && index === 0,
@@ -22381,12 +22446,12 @@ const ya = `"use strict";
22381
22446
  totalLineCount++;
22382
22447
  if (visibleText.length > 0) {
22383
22448
  visibleLines.push(visibleText);
22384
- const lineWidth = ctx.measureText(visibleText).width;
22449
+ const lineWidth = spacedTextWidth(ctx.measureText(visibleText).width, visibleText, letterSpacing);
22385
22450
  maxLineWidth = Math.max(maxLineWidth, lineWidth);
22386
22451
  }
22387
22452
  });
22388
22453
  let height;
22389
- const lineHeight = LINE_HEIGHT_MULTIPLIER;
22454
+ const lineHeight = opts?.lineHeight ?? LINE_HEIGHT_MULTIPLIER;
22390
22455
  if (totalLineCount === 1) {
22391
22456
  height = fontMetrics.height;
22392
22457
  } else if (totalLineCount === 0) {
@@ -22566,6 +22631,7 @@ const ya = `"use strict";
22566
22631
  const transformData = element.transformData;
22567
22632
  const width = transformData?.width ?? 200;
22568
22633
  const availableWidth = width - HORIZONTAL_PADDING * 2;
22634
+ const letterSpacing = textElement.letterSpacing ?? 0;
22569
22635
  const { lines, height: visualHeight } = calculateVisualBoundsWithSpaceCollapsing(
22570
22636
  text,
22571
22637
  availableWidth,
@@ -22575,12 +22641,13 @@ const ya = `"use strict";
22575
22641
  italic,
22576
22642
  void 0,
22577
22643
  // No locked line count for stroke
22578
- true
22644
+ true,
22579
22645
  // strict: wrap exactly at maxWidth
22646
+ { letterSpacing, lineHeight: textElement.lineHeight }
22580
22647
  );
22581
22648
  const topLeftX = -width / 2;
22582
22649
  const topLeftY = -visualHeight / 2;
22583
- const lineSpacing = fontSize * LINE_HEIGHT_MULTIPLIER;
22650
+ const lineSpacing = fontSize * (textElement.lineHeight ?? LINE_HEIGHT_MULTIPLIER);
22584
22651
  lines.forEach((line, index) => {
22585
22652
  const isParagraphStart = index === 0;
22586
22653
  const isParagraphEnd = index === lines.length - 1;
@@ -22606,7 +22673,7 @@ const ya = `"use strict";
22606
22673
  xPos = topLeftX + width - HORIZONTAL_PADDING;
22607
22674
  }
22608
22675
  const yPos = topLeftY + fontMetrics.ascent + index * lineSpacing;
22609
- ctx.strokeText(visibleText, xPos, yPos);
22676
+ strokeTextWithSpacing(ctx, visibleText, xPos, yPos, letterSpacing);
22610
22677
  });
22611
22678
  } else {
22612
22679
  const visualHeight = fontMetrics.height;
@@ -23345,11 +23412,12 @@ const ya = `"use strict";
23345
23412
  const fontFamily = style.fontFamily || element.fontFamily;
23346
23413
  const bold = style.bold !== void 0 ? style.bold : element.bold || false;
23347
23414
  const italic = style.italic !== void 0 ? style.italic : element.italic || false;
23415
+ const letterSpacing = style.letterSpacing !== void 0 ? style.letterSpacing : element.letterSpacing ?? 0;
23348
23416
  ctx.font = buildFontString2(fontSize, fontFamily, bold, italic);
23349
- return ctx.measureText(text).width;
23417
+ return spacedTextWidth(ctx.measureText(text).width, text, letterSpacing);
23350
23418
  };
23351
23419
  const stylesMatch = (s1, s2) => {
23352
- return s1.fontSize === s2.fontSize && s1.fontFamily === s2.fontFamily && s1.color === s2.color && s1.bold === s2.bold && s1.italic === s2.italic && s1.underline === s2.underline && s1.strikethrough === s2.strikethrough;
23420
+ return s1.fontSize === s2.fontSize && s1.fontFamily === s2.fontFamily && s1.color === s2.color && s1.bold === s2.bold && s1.italic === s2.italic && s1.underline === s2.underline && s1.strikethrough === s2.strikethrough && s1.letterSpacing === s2.letterSpacing;
23353
23421
  };
23354
23422
  const mergedSpans = [];
23355
23423
  spans.forEach((span) => {
@@ -23523,6 +23591,7 @@ const ya = `"use strict";
23523
23591
  function renderRichTextFillOnly(ctx, richText, element, maxWidth, lockedLineCount) {
23524
23592
  ctx.fillStyle = element.color;
23525
23593
  const textAlign = element.textAlign || "center";
23594
+ const resolveSpacing = (style) => style.letterSpacing !== void 0 ? style.letterSpacing : element.letterSpacing ?? 0;
23526
23595
  const explicitLines = splitRichTextIntoLines(richText);
23527
23596
  let lines;
23528
23597
  let paragraphMetadata;
@@ -23561,7 +23630,7 @@ const ya = `"use strict";
23561
23630
  const bold = span.style.bold !== void 0 ? span.style.bold : element.bold || false;
23562
23631
  const italic = span.style.italic !== void 0 ? span.style.italic : element.italic || false;
23563
23632
  ctx.font = buildFontString(fontSize, fontFamily, bold, italic);
23564
- const width = ctx.measureText(span.text).width;
23633
+ const width = spacedTextWidth(ctx.measureText(span.text).width, span.text, resolveSpacing(span.style));
23565
23634
  spanWidths.push(width);
23566
23635
  lineWidth += width;
23567
23636
  const metrics = getFontMetrics2(fontSize, fontFamily, bold, italic);
@@ -23599,7 +23668,11 @@ const ya = `"use strict";
23599
23668
  if (visibleText.length > 0) {
23600
23669
  ctx.save();
23601
23670
  ctx.font = buildFontString(fontSize, fontFamily, bold, italic);
23602
- adjustedLineWidth += ctx.measureText(visibleText).width;
23671
+ adjustedLineWidth += spacedTextWidth(
23672
+ ctx.measureText(visibleText).width,
23673
+ visibleText,
23674
+ resolveSpacing(span.style)
23675
+ );
23603
23676
  ctx.restore();
23604
23677
  }
23605
23678
  });
@@ -23617,7 +23690,7 @@ const ya = `"use strict";
23617
23690
  maxLineHeight = Math.max(maxLineHeight, lineHeight);
23618
23691
  });
23619
23692
  const elementFontMetrics = getFontMetrics2(element.fontSize, element.fontFamily, element.bold, element.italic);
23620
- const lineSpacing = element.fontSize * LINE_HEIGHT_MULTIPLIER;
23693
+ const lineSpacing = element.fontSize * (element.lineHeight ?? LINE_HEIGHT_MULTIPLIER);
23621
23694
  let totalHeight;
23622
23695
  if (lineMetrics.length === 0) {
23623
23696
  totalHeight = 0;
@@ -23669,12 +23742,13 @@ const ya = `"use strict";
23669
23742
  }
23670
23743
  charIndexInLine += span.text.length;
23671
23744
  if (renderText.length > 0) {
23745
+ const letterSpacing = resolveSpacing(span.style);
23672
23746
  ctx.font = buildFontString(fontSize, fontFamily, bold, italic);
23673
23747
  ctx.fillStyle = color;
23674
23748
  ctx.textBaseline = "alphabetic";
23675
23749
  ctx.textAlign = "left";
23676
- ctx.fillText(renderText, currentX, baselineY);
23677
- const renderedWidth = ctx.measureText(renderText).width;
23750
+ fillTextWithSpacing(ctx, renderText, currentX, baselineY, letterSpacing);
23751
+ const renderedWidth = spacedTextWidth(ctx.measureText(renderText).width, renderText, letterSpacing);
23678
23752
  if (underline) {
23679
23753
  const underlineY = baselineY + fontSize * 0.1;
23680
23754
  ctx.beginPath();
@@ -23753,7 +23827,7 @@ const ya = `"use strict";
23753
23827
  const visualHeight = fontMetrics.height;
23754
23828
  const topLeftY = -visualHeight / 2;
23755
23829
  const yPos = topLeftY + fontMetrics.ascent;
23756
- ctx.fillText(text, 0, yPos);
23830
+ fillTextWithSpacing(ctx, text, 0, yPos, element.letterSpacing);
23757
23831
  }
23758
23832
  function renderCustomTransform(ctx, elementData) {
23759
23833
  renderCustomTransformNormal(ctx, elementData);
@@ -23783,7 +23857,9 @@ const ya = `"use strict";
23783
23857
  italic: elementData.italic,
23784
23858
  underline: elementData.underline,
23785
23859
  strikethrough: elementData.strikethrough,
23786
- textAlign: elementData.textAlign
23860
+ textAlign: elementData.textAlign,
23861
+ letterSpacing: elementData.letterSpacing,
23862
+ lineHeight: elementData.lineHeight
23787
23863
  },
23788
23864
  availableWidth,
23789
23865
  lockedLineCount
@@ -23793,6 +23869,7 @@ const ya = `"use strict";
23793
23869
  if (elementData.text) {
23794
23870
  ctx.fillStyle = elementData.color;
23795
23871
  const lockedLineCount = elementData._lockedLineCount;
23872
+ const letterSpacing = elementData.letterSpacing ?? 0;
23796
23873
  const { lines, height: visualHeight } = calculateVisualBoundsWithSpaceCollapsing(
23797
23874
  elementData.text,
23798
23875
  availableWidth,
@@ -23801,8 +23878,9 @@ const ya = `"use strict";
23801
23878
  elementData.bold,
23802
23879
  elementData.italic,
23803
23880
  lockedLineCount,
23804
- true
23881
+ true,
23805
23882
  // strict: true
23883
+ { letterSpacing, lineHeight: elementData.lineHeight }
23806
23884
  );
23807
23885
  const fontMetrics = getFontMetrics2(
23808
23886
  elementData.fontSize,
@@ -23812,7 +23890,7 @@ const ya = `"use strict";
23812
23890
  );
23813
23891
  const topLeftX = -(transformData?.width ?? 100) / 2;
23814
23892
  const topLeftY = -visualHeight / 2;
23815
- const lineSpacing = elementData.fontSize * LINE_HEIGHT_MULTIPLIER;
23893
+ const lineSpacing = elementData.fontSize * (elementData.lineHeight ?? LINE_HEIGHT_MULTIPLIER);
23816
23894
  ctx.font = \`\${elementData.italic ? "italic " : ""}\${elementData.bold ? "bold " : ""}\${elementData.fontSize}px \${elementData.fontFamily}\`;
23817
23895
  ctx.textBaseline = "alphabetic";
23818
23896
  ctx.textAlign = elementData.textAlign;
@@ -23841,9 +23919,9 @@ const ya = `"use strict";
23841
23919
  xPos = topLeftX + (transformData?.width ?? 100) - HORIZONTAL_PADDING;
23842
23920
  }
23843
23921
  const yPos = topLeftY + fontMetrics.ascent + index * lineSpacing;
23844
- ctx.fillText(visibleText, xPos, yPos);
23922
+ fillTextWithSpacing(ctx, visibleText, xPos, yPos, letterSpacing);
23845
23923
  if (visibleText.length > 0) {
23846
- const lineWidth = ctx.measureText(visibleText).width;
23924
+ const lineWidth = spacedTextWidth(ctx.measureText(visibleText).width, visibleText, letterSpacing);
23847
23925
  let decorationX = xPos;
23848
23926
  if (elementData.textAlign === "center") decorationX -= lineWidth / 2;
23849
23927
  else if (elementData.textAlign === "right") decorationX -= lineWidth;
@@ -24257,7 +24335,8 @@ const ya = `"use strict";
24257
24335
  bold: textElement.bold || false,
24258
24336
  italic: textElement.italic || false,
24259
24337
  textAlign: textElement.textAlign || "center",
24260
- color: textElement.color || "#000000"
24338
+ color: textElement.color || "#000000",
24339
+ letterSpacing: textElement.letterSpacing
24261
24340
  });
24262
24341
  ctx.restore();
24263
24342
  }
@@ -25761,6 +25840,122 @@ const ya = `"use strict";
25761
25840
  }
25762
25841
  }
25763
25842
 
25843
+ // src/errors/editorError.ts
25844
+ var EditorError = class extends Error {
25845
+ constructor(code, message, data = {}) {
25846
+ super(\`[Editor] \${code}: \${message}\`);
25847
+ this.name = "EditorError";
25848
+ this.code = code;
25849
+ this.data = { code, ...data };
25850
+ }
25851
+ };
25852
+
25853
+ // src/utils/custom-fonts.ts
25854
+ function familyKey(family) {
25855
+ return family.trim().toLowerCase();
25856
+ }
25857
+ function faceKey(font) {
25858
+ return \`\${familyKey(font.family)}|\${font.weight ?? 400}|\${font.style ?? "normal"}\`;
25859
+ }
25860
+ var CustomFontRegistryClass = class {
25861
+ constructor() {
25862
+ this.fonts = /* @__PURE__ */ new Map();
25863
+ this.listeners = /* @__PURE__ */ new Set();
25864
+ /** Stable snapshot for \`useSyncExternalStore\` — replaced only on change. */
25865
+ this.snapshot = [];
25866
+ /** All registered custom fonts (stable reference until a change). */
25867
+ this.list = () => {
25868
+ return this.snapshot;
25869
+ };
25870
+ this.subscribe = (listener) => {
25871
+ this.listeners.add(listener);
25872
+ return () => {
25873
+ this.listeners.delete(listener);
25874
+ };
25875
+ };
25876
+ }
25877
+ /**
25878
+ * Register fonts (idempotent; re-registering the same family/weight/style
25879
+ * replaces the URL). Returns true when anything changed.
25880
+ */
25881
+ register(fonts) {
25882
+ let changed = false;
25883
+ for (const font of fonts) {
25884
+ const key = faceKey(font);
25885
+ const existing = this.fonts.get(key);
25886
+ if (existing && existing.url === font.url && existing.family === font.family) continue;
25887
+ this.fonts.set(key, { ...font });
25888
+ changed = true;
25889
+ }
25890
+ if (changed) {
25891
+ this.snapshot = Object.freeze([...this.fonts.values()]);
25892
+ for (const listener of this.listeners) listener();
25893
+ }
25894
+ return changed;
25895
+ }
25896
+ /** Is this family registered as a custom font? (Shadowing check.) */
25897
+ has(family) {
25898
+ const key = familyKey(family);
25899
+ for (const font of this.fonts.values()) {
25900
+ if (familyKey(font.family) === key) return true;
25901
+ }
25902
+ return false;
25903
+ }
25904
+ /** All registered faces of one family (possibly several weights/styles). */
25905
+ facesOf(family) {
25906
+ const key = familyKey(family);
25907
+ return [...this.fonts.values()].filter((f) => familyKey(f.family) === key);
25908
+ }
25909
+ /** Registered faces whose family appears in \`families\` — what the export
25910
+ * path sends to the worker alongside the used-font list. */
25911
+ forFamilies(families) {
25912
+ const keys = new Set(families.map(familyKey));
25913
+ return [...this.fonts.values()].filter((f) => keys.has(familyKey(f.family)));
25914
+ }
25915
+ /** @internal Test helper — wipe registry state between tests. */
25916
+ clear() {
25917
+ this.fonts.clear();
25918
+ this.snapshot = Object.freeze([]);
25919
+ for (const listener of this.listeners) listener();
25920
+ }
25921
+ };
25922
+ var customFontRegistry = new CustomFontRegistryClass();
25923
+ var loadedFaceKeys = /* @__PURE__ */ new Set();
25924
+ async function loadCustomFont(font, options = {}) {
25925
+ const face = await loadFontFaceFromUrl(
25926
+ font.family,
25927
+ {
25928
+ fontFileUrl: font.url,
25929
+ descriptors: {
25930
+ weight: String(font.weight ?? 400),
25931
+ style: font.style ?? "normal"
25932
+ }
25933
+ },
25934
+ options.fetchImpl ?? fetch
25935
+ );
25936
+ if (!face) {
25937
+ throw new EditorError(
25938
+ "E_FONT_LOAD_FAILED",
25939
+ \`Custom font "\${font.family}" failed to load from \${font.url}. The URL must serve the font binary over a plain cross-origin GET (CORS). Verify the URL is reachable and sends Access-Control-Allow-Origin, then re-register the font. Custom fonts never fall back silently \\u2014 the design would render with the wrong typeface.\`,
25940
+ {
25941
+ family: font.family,
25942
+ url: font.url,
25943
+ weight: font.weight ?? 400,
25944
+ style: font.style ?? "normal"
25945
+ }
25946
+ );
25947
+ }
25948
+ const target = options.fonts ?? (typeof document !== "undefined" ? document.fonts : void 0);
25949
+ target?.add(face);
25950
+ loadedFaceKeys.add(faceKey(font));
25951
+ return face;
25952
+ }
25953
+ async function loadCustomFontFaces(fonts, fontFaceSet, fetchImpl = fetch) {
25954
+ await Promise.all(
25955
+ fonts.map((font) => loadCustomFont(font, { fonts: fontFaceSet, fetchImpl }))
25956
+ );
25957
+ }
25958
+
25764
25959
  // src/workers/export-worker.ts
25765
25960
  var MAX_BITMAP_CACHE_SIZE = 50;
25766
25961
  var workerBitmapCache = /* @__PURE__ */ new Map();
@@ -25819,10 +26014,29 @@ const ya = `"use strict";
25819
26014
  }
25820
26015
  var loadedFonts = /* @__PURE__ */ new Set();
25821
26016
  var failedFonts = /* @__PURE__ */ new Set();
25822
- async function loadFonts(fontFamilies) {
26017
+ async function loadFonts(fontFamilies, customFonts = []) {
25823
26018
  if (!fontFamilies || fontFamilies.length === 0) return;
26019
+ const customByFamily = /* @__PURE__ */ new Map();
26020
+ for (const font of customFonts) {
26021
+ const key = font.family.trim().toLowerCase();
26022
+ const faces = customByFamily.get(key) ?? [];
26023
+ faces.push(font);
26024
+ customByFamily.set(key, faces);
26025
+ }
25824
26026
  const loadPromises = fontFamilies.map(async (fontFamily) => {
25825
26027
  if (loadedFonts.has(fontFamily) || failedFonts.has(fontFamily)) return;
26028
+ const customFaces = customByFamily.get(fontFamily.trim().toLowerCase());
26029
+ if (customFaces) {
26030
+ await loadCustomFontFaces(customFaces, self.fonts);
26031
+ if (self.fonts && self.fonts.ready) {
26032
+ await Promise.race([
26033
+ self.fonts.ready,
26034
+ new Promise((resolve) => setTimeout(resolve, 250))
26035
+ ]);
26036
+ }
26037
+ loadedFonts.add(fontFamily);
26038
+ return;
26039
+ }
25826
26040
  if (SYSTEM_FONTS.has(fontFamily)) {
25827
26041
  loadedFonts.add(fontFamily);
25828
26042
  return;
@@ -25908,6 +26122,7 @@ const ya = `"use strict";
25908
26122
  artboardData,
25909
26123
  elements = [],
25910
26124
  fonts = [],
26125
+ customFonts = [],
25911
26126
  scale = 1,
25912
26127
  format = "png",
25913
26128
  quality = 0.95,
@@ -25915,7 +26130,7 @@ const ya = `"use strict";
25915
26130
  } = request;
25916
26131
  try {
25917
26132
  if (fonts && fonts.length > 0) {
25918
- await loadFonts(fonts);
26133
+ await loadFonts(fonts, customFonts);
25919
26134
  }
25920
26135
  const width = artboardData.width * scale;
25921
26136
  const height = artboardData.height * scale;
@@ -26314,8 +26529,120 @@ const ya = `"use strict";
26314
26529
  console.error("[Export Worker] Unhandled promise rejection:", event.reason);
26315
26530
  };
26316
26531
  })();
26317
- `, O = N("WorkerExport");
26318
- class dn {
26532
+ `;
26533
+ async function Ea(e, n, t = fetch) {
26534
+ try {
26535
+ const a = await t(n.fontFileUrl, { mode: "cors" });
26536
+ if (!a.ok) return null;
26537
+ const r = await a.arrayBuffer(), o = new FontFace(e, r, n.descriptors);
26538
+ return await o.load(), o;
26539
+ } catch {
26540
+ return null;
26541
+ }
26542
+ }
26543
+ function X(e) {
26544
+ return e.trim().toLowerCase();
26545
+ }
26546
+ function Yn(e) {
26547
+ return `${X(e.family)}|${e.weight ?? 400}|${e.style ?? "normal"}`;
26548
+ }
26549
+ class Aa {
26550
+ constructor() {
26551
+ this.fonts = /* @__PURE__ */ new Map(), this.listeners = /* @__PURE__ */ new Set(), this.snapshot = [], this.list = () => this.snapshot, this.subscribe = (n) => (this.listeners.add(n), () => {
26552
+ this.listeners.delete(n);
26553
+ });
26554
+ }
26555
+ /**
26556
+ * Register fonts (idempotent; re-registering the same family/weight/style
26557
+ * replaces the URL). Returns true when anything changed.
26558
+ */
26559
+ register(n) {
26560
+ let t = !1;
26561
+ for (const a of n) {
26562
+ const r = Yn(a), o = this.fonts.get(r);
26563
+ o && o.url === a.url && o.family === a.family || (this.fonts.set(r, { ...a }), t = !0);
26564
+ }
26565
+ if (t) {
26566
+ this.snapshot = Object.freeze([...this.fonts.values()]);
26567
+ for (const a of this.listeners) a();
26568
+ }
26569
+ return t;
26570
+ }
26571
+ /** Is this family registered as a custom font? (Shadowing check.) */
26572
+ has(n) {
26573
+ const t = X(n);
26574
+ for (const a of this.fonts.values())
26575
+ if (X(a.family) === t) return !0;
26576
+ return !1;
26577
+ }
26578
+ /** All registered faces of one family (possibly several weights/styles). */
26579
+ facesOf(n) {
26580
+ const t = X(n);
26581
+ return [...this.fonts.values()].filter((a) => X(a.family) === t);
26582
+ }
26583
+ /** Registered faces whose family appears in `families` — what the export
26584
+ * path sends to the worker alongside the used-font list. */
26585
+ forFamilies(n) {
26586
+ const t = new Set(n.map(X));
26587
+ return [...this.fonts.values()].filter((a) => t.has(X(a.family)));
26588
+ }
26589
+ /** @internal Test helper — wipe registry state between tests. */
26590
+ clear() {
26591
+ this.fonts.clear(), this.snapshot = Object.freeze([]);
26592
+ for (const n of this.listeners) n();
26593
+ }
26594
+ }
26595
+ const Wn = new Aa();
26596
+ function Pa(e) {
26597
+ Wn.register(e);
26598
+ }
26599
+ const We = /* @__PURE__ */ new Set();
26600
+ async function Ia(e, n = {}) {
26601
+ const t = await Ea(
26602
+ e.family,
26603
+ {
26604
+ fontFileUrl: e.url,
26605
+ descriptors: {
26606
+ weight: String(e.weight ?? 400),
26607
+ style: e.style ?? "normal"
26608
+ }
26609
+ },
26610
+ n.fetchImpl ?? fetch
26611
+ );
26612
+ if (!t)
26613
+ throw new we(
26614
+ "E_FONT_LOAD_FAILED",
26615
+ `Custom font "${e.family}" failed to load from ${e.url}. The URL must serve the font binary over a plain cross-origin GET (CORS). Verify the URL is reachable and sends Access-Control-Allow-Origin, then re-register the font. Custom fonts never fall back silently — the design would render with the wrong typeface.`,
26616
+ {
26617
+ family: e.family,
26618
+ url: e.url,
26619
+ weight: e.weight ?? 400,
26620
+ style: e.style ?? "normal"
26621
+ }
26622
+ );
26623
+ const a = n.fonts ?? (typeof document < "u" ? document.fonts : void 0);
26624
+ return a == null || a.add(t), We.add(Yn(e)), t;
26625
+ }
26626
+ async function qa(e, n = {}) {
26627
+ Pa(e);
26628
+ const { onLoadError: t, ...a } = n;
26629
+ await Promise.all(
26630
+ e.map(async (r) => {
26631
+ if (!We.has(Yn(r)))
26632
+ try {
26633
+ await Ia(r, a);
26634
+ } catch (o) {
26635
+ if (t && o instanceof we) {
26636
+ t(o, r);
26637
+ return;
26638
+ }
26639
+ throw o;
26640
+ }
26641
+ })
26642
+ );
26643
+ }
26644
+ const O = U("WorkerExport");
26645
+ class pn {
26319
26646
  constructor() {
26320
26647
  this.worker = null, this.workerBlobUrl = null, this.pendingRequests = /* @__PURE__ */ new Map(), this.requestQueue = [], this.blobRequestQueue = [], this.isProcessingQueue = !1, this.isReady = !1, this.readyPromise = null, this.requestIdCounter = 0, this.workerCrashCount = 0, this.MAX_CRASHES_BEFORE_FALLBACK = 3, this.lastCrashTime = 0, this.CRASH_RESET_TIMEOUT = 6e4, this.progressListeners = /* @__PURE__ */ new Set(), this.idleTimeout = null, this.IDLE_TIMEOUT_MS = 3e4;
26321
26648
  }
@@ -26377,7 +26704,7 @@ class dn {
26377
26704
  * Call this when exiting editor mode to free memory.
26378
26705
  */
26379
26706
  clearWorkerBitmapCache() {
26380
- if (On(), this.worker && this.isReady) {
26707
+ if (Nn(), this.worker && this.isReady) {
26381
26708
  const n = {
26382
26709
  type: "clear-all-bitmaps"
26383
26710
  };
@@ -26389,7 +26716,7 @@ class dn {
26389
26716
  * Call this when an element is removed or its image source changes.
26390
26717
  */
26391
26718
  clearWorkerBitmap(n) {
26392
- if (De(n), this.worker && this.isReady) {
26719
+ if (Ue(n), this.worker && this.isReady) {
26393
26720
  const t = {
26394
26721
  type: "clear-bitmap",
26395
26722
  elementId: n
@@ -26413,13 +26740,13 @@ class dn {
26413
26740
  async initialize() {
26414
26741
  if (this.worker)
26415
26742
  return this.readyPromise || Promise.resolve();
26416
- if (!dn.supportsWorkerExport())
26743
+ if (!pn.supportsWorkerExport())
26417
26744
  throw new Error("Browser does not support OffscreenCanvas or Web Workers");
26418
26745
  return this.readyPromise = new Promise((n, t) => {
26419
26746
  try {
26420
26747
  let a;
26421
26748
  try {
26422
- const s = new Blob([ya], { type: "application/javascript" });
26749
+ const s = new Blob([_a], { type: "application/javascript" });
26423
26750
  a = URL.createObjectURL(s), this.workerBlobUrl = a;
26424
26751
  } catch (s) {
26425
26752
  O.error("Failed to create worker blob:", s), t(new Error(`Worker creation failed: ${s instanceof Error ? s.message : String(s)}`));
@@ -26433,7 +26760,7 @@ class dn {
26433
26760
  const r = setTimeout(() => {
26434
26761
  t(new Error("Worker initialization timeout"));
26435
26762
  }, 15e3), o = (s) => {
26436
- s.data.type === "ready" && (clearTimeout(r), this.isReady = !0, ga(
26763
+ s.data.type === "ready" && (clearTimeout(r), this.isReady = !0, ka(
26437
26764
  () => this.clearWorkerBitmapCache(),
26438
26765
  (c) => this.clearWorkerBitmap(c)
26439
26766
  ), n());
@@ -26510,7 +26837,7 @@ class dn {
26510
26837
  const { artboard: t, elements: a, config: r } = n;
26511
26838
  if ((!this.worker || !this.isReady) && await this.initialize(), !this.worker)
26512
26839
  throw new Error("Worker is not initialized");
26513
- const o = `export-${++this.requestIdCounter}-${Date.now()}`, s = performance.now(), { data: c, newBitmaps: i } = await fe(t, a);
26840
+ const o = `export-${++this.requestIdCounter}-${Date.now()}`, s = performance.now(), { data: c, newBitmaps: i } = await ye(t, a);
26514
26841
  i.length > 0 && this.registerBitmapsWithWorker(i);
26515
26842
  const l = {
26516
26843
  type: "export",
@@ -26518,18 +26845,22 @@ class dn {
26518
26845
  artboardData: c.artboard,
26519
26846
  elements: c.elements,
26520
26847
  fonts: c.fonts,
26848
+ // Custom (brand) fonts among the used families — the worker loads
26849
+ // these from their hosted URL instead of Google Fonts (deterministic
26850
+ // shadowing; see utils/custom-fonts.ts).
26851
+ customFonts: Wn.forFamilies(c.fonts ?? []),
26521
26852
  scale: r.scale || 1,
26522
26853
  format: r.format || "png",
26523
26854
  quality: r.quality || 0.95
26524
- }, d = new Promise((m, b) => {
26855
+ }, d = new Promise(($, h) => {
26525
26856
  this.pendingRequests.set(o, {
26526
26857
  requestId: o,
26527
- resolve: m,
26528
- reject: b,
26858
+ resolve: $,
26859
+ reject: h,
26529
26860
  startTime: s,
26530
26861
  returnFormat: "dataUrl"
26531
26862
  }), setTimeout(() => {
26532
- this.pendingRequests.has(o) && (this.pendingRequests.delete(o), b(new Error("Export request timeout")));
26863
+ this.pendingRequests.has(o) && (this.pendingRequests.delete(o), h(new Error("Export request timeout")));
26533
26864
  }, 3e4);
26534
26865
  });
26535
26866
  this.worker.postMessage(l);
@@ -26567,7 +26898,7 @@ class dn {
26567
26898
  const { artboard: t, elements: a, config: r } = n;
26568
26899
  if ((!this.worker || !this.isReady) && await this.initialize(), !this.worker)
26569
26900
  throw new Error("Worker is not initialized");
26570
- const o = `export-blob-${++this.requestIdCounter}-${Date.now()}`, s = performance.now(), { data: c, newBitmaps: i } = await fe(t, a);
26901
+ const o = `export-blob-${++this.requestIdCounter}-${Date.now()}`, s = performance.now(), { data: c, newBitmaps: i } = await ye(t, a);
26571
26902
  i.length > 0 && this.registerBitmapsWithWorker(i);
26572
26903
  const l = {
26573
26904
  type: "export",
@@ -26575,19 +26906,21 @@ class dn {
26575
26906
  artboardData: c.artboard,
26576
26907
  elements: c.elements,
26577
26908
  fonts: c.fonts,
26909
+ // Same custom-font threading as the dataUrl path above.
26910
+ customFonts: Wn.forFamilies(c.fonts ?? []),
26578
26911
  scale: r.scale || 1,
26579
26912
  format: r.format || "png",
26580
26913
  quality: r.quality || 0.95,
26581
26914
  returnFormat: "blob"
26582
- }, d = new Promise((b, h) => {
26915
+ }, d = new Promise((h, b) => {
26583
26916
  this.pendingRequests.set(o, {
26584
26917
  requestId: o,
26585
- resolve: b,
26586
- reject: h,
26918
+ resolve: h,
26919
+ reject: b,
26587
26920
  startTime: s,
26588
26921
  returnFormat: "blob"
26589
26922
  }), setTimeout(() => {
26590
- this.pendingRequests.has(o) && (this.pendingRequests.delete(o), h(new Error("Export request timeout")));
26923
+ this.pendingRequests.has(o) && (this.pendingRequests.delete(o), b(new Error("Export request timeout")));
26591
26924
  }, 3e4);
26592
26925
  });
26593
26926
  this.worker.postMessage(l);
@@ -26681,7 +27014,7 @@ class dn {
26681
27014
  t.reject(new Error("Worker terminated")), this.pendingRequests.delete(n);
26682
27015
  for (; this.requestQueue.length > 0; )
26683
27016
  this.requestQueue.shift().reject(new Error("Worker terminated"));
26684
- this.worker.terminate(), this.worker = null, this.isReady = !1, this.readyPromise = null, On(), ma(), this.workerBlobUrl && (URL.revokeObjectURL(this.workerBlobUrl), this.workerBlobUrl = null);
27017
+ this.worker.terminate(), this.worker = null, this.isReady = !1, this.readyPromise = null, Nn(), Ta(), this.workerBlobUrl && (URL.revokeObjectURL(this.workerBlobUrl), this.workerBlobUrl = null);
26685
27018
  }
26686
27019
  }
26687
27020
  /**
@@ -26696,32 +27029,32 @@ class dn {
26696
27029
  };
26697
27030
  }
26698
27031
  }
26699
- let Z = null;
26700
- function Ma() {
26701
- return Z || (Z = new dn()), Z;
27032
+ let nn = null;
27033
+ function Xa() {
27034
+ return nn || (nn = new pn()), nn;
26702
27035
  }
26703
- function Oa() {
26704
- Z && (Z.terminate(), Z = null);
27036
+ function Ya() {
27037
+ nn && (nn.terminate(), nn = null);
26705
27038
  }
26706
- Un();
26707
- const z = N("Export");
26708
- function Bn(e, n) {
27039
+ jn();
27040
+ const W = U("Export");
27041
+ function zn(e, n) {
26709
27042
  var t;
26710
27043
  if (!(!e || typeof e != "object")) {
26711
27044
  if (typeof e.fontFamily == "string" && e.fontFamily.trim() && n.add(e.fontFamily), e.richText && Array.isArray(e.richText.spans))
26712
27045
  for (const a of e.richText.spans)
26713
27046
  (t = a == null ? void 0 : a.style) != null && t.fontFamily && typeof a.style.fontFamily == "string" && n.add(a.style.fontFamily);
26714
27047
  if (Array.isArray(e.children))
26715
- for (const a of e.children) Bn(a, n);
27048
+ for (const a of e.children) zn(a, n);
26716
27049
  if (Array.isArray(e.masks))
26717
27050
  for (const a of e.masks)
26718
- a != null && a.maskElement && Bn(a.maskElement, n);
27051
+ a != null && a.maskElement && zn(a.maskElement, n);
26719
27052
  }
26720
27053
  }
26721
- async function ue(e) {
27054
+ async function $e(e) {
26722
27055
  if (typeof document > "u" || !document.fonts) return;
26723
27056
  const n = /* @__PURE__ */ new Set();
26724
- for (const a of e) Bn(a, n);
27057
+ for (const a of e) zn(a, n);
26725
27058
  if (n.size === 0) return;
26726
27059
  const t = [];
26727
27060
  for (const a of n)
@@ -26729,12 +27062,12 @@ async function ue(e) {
26729
27062
  }));
26730
27063
  await Promise.all(t), document.fonts.ready && await document.fonts.ready;
26731
27064
  }
26732
- const on = class on {
27065
+ const dn = class dn {
26733
27066
  /**
26734
27067
  * Check if worker export is supported in this browser
26735
27068
  */
26736
27069
  static supportsWorkerExport() {
26737
- return dn.supportsWorkerExport();
27070
+ return pn.supportsWorkerExport();
26738
27071
  }
26739
27072
  /**
26740
27073
  * Get or initialize the worker manager
@@ -26742,9 +27075,9 @@ const on = class on {
26742
27075
  static async getWorkerManager() {
26743
27076
  return this.supportsWorkerExport() ? this.workerManager ? this.workerManager : this.workerInitPromise ? (await this.workerInitPromise, this.workerManager) : (this.workerInitPromise = (async () => {
26744
27077
  try {
26745
- this.workerManager = new dn(), await this.workerManager.initialize();
27078
+ this.workerManager = new pn(), await this.workerManager.initialize();
26746
27079
  } catch (n) {
26747
- z.error("Failed to initialize worker:", n), this.workerManager = null;
27080
+ W.error("Failed to initialize worker:", n), this.workerManager = null;
26748
27081
  }
26749
27082
  })(), await this.workerInitPromise, this.workerInitPromise = null, this.workerManager) : null;
26750
27083
  }
@@ -26801,8 +27134,8 @@ const on = class on {
26801
27134
  transparentBackground: i,
26802
27135
  backgroundColor: l,
26803
27136
  forceMainThread: u
26804
- }), f = await this.dataUrlToBlob(p), m = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").split("T")[0], b = d || `${n.name}-${m}.${o}`;
26805
- this.downloadBlob(f, b);
27137
+ }), f = await this.dataUrlToBlob(p), $ = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").split("T")[0], h = d || `${n.name}-${$}.${o}`;
27138
+ this.downloadBlob(f, h);
26806
27139
  }
26807
27140
  /**
26808
27141
  * Export artboard to data URL (for preview/testing)
@@ -26821,7 +27154,7 @@ const on = class on {
26821
27154
  try {
26822
27155
  const u = await this.getWorkerManager();
26823
27156
  if (u) {
26824
- const p = new Set(n.getElementIds()), f = t.filter((b) => p.has(b.id));
27157
+ const p = new Set(n.getElementIds()), f = t.filter((h) => p.has(h.id));
26825
27158
  return (await u.exportArtboardToDataURL(n, f, {
26826
27159
  scale: c,
26827
27160
  format: o === "jpg" ? "jpeg" : o,
@@ -26829,7 +27162,7 @@ const on = class on {
26829
27162
  })).dataUrl;
26830
27163
  }
26831
27164
  } catch (u) {
26832
- z.warn("Worker export failed, falling back to main thread:", u);
27165
+ W.warn("Worker export failed, falling back to main thread:", u);
26833
27166
  }
26834
27167
  return this.mainThreadExportToDataURL(n, t, a, {
26835
27168
  format: o,
@@ -26857,7 +27190,7 @@ const on = class on {
26857
27190
  try {
26858
27191
  const u = await this.getWorkerManager();
26859
27192
  if (u) {
26860
- const p = new Set(n.getElementIds()), f = t.filter((b) => p.has(b.id));
27193
+ const p = new Set(n.getElementIds()), f = t.filter((h) => p.has(h.id));
26861
27194
  return (await u.exportArtboardToBlob(n, f, {
26862
27195
  scale: c,
26863
27196
  format: o === "jpg" ? "jpeg" : o,
@@ -26865,7 +27198,7 @@ const on = class on {
26865
27198
  })).blob;
26866
27199
  }
26867
27200
  } catch (u) {
26868
- z.warn("Worker blob export failed, falling back to main thread:", u);
27201
+ W.warn("Worker blob export failed, falling back to main thread:", u);
26869
27202
  }
26870
27203
  return this.mainThreadExportToBlob(n, t, a, {
26871
27204
  format: o,
@@ -26889,53 +27222,53 @@ const on = class on {
26889
27222
  transparentBackground: i = !1,
26890
27223
  backgroundColor: l = n.backgroundColor
26891
27224
  } = r;
26892
- await ue(t);
27225
+ await $e(t);
26893
27226
  const d = document.createElement("canvas"), u = n.width * c, p = n.height * c;
26894
27227
  d.width = u, d.height = p;
26895
27228
  const f = d.getContext("2d");
26896
27229
  if (f.scale(c, c), !i && n.exportBackground) {
26897
27230
  if (f.save(), this.applyExportBackgroundClipPath(f, n), n.backgroundType === "texture" && n.backgroundTexture) {
26898
- const g = K.getTexturePresetColor(n.backgroundTexture);
26899
- f.fillStyle = g, f.fillRect(0, 0, n.width, n.height);
26900
- const y = K.getTexture(n.backgroundTexture);
26901
- y && y.complete && f.drawImage(y, 0, 0, n.width, n.height);
27231
+ const m = Z.getTexturePresetColor(n.backgroundTexture);
27232
+ f.fillStyle = m, f.fillRect(0, 0, n.width, n.height);
27233
+ const g = Z.getTexture(n.backgroundTexture);
27234
+ g && g.complete && f.drawImage(g, 0, 0, n.width, n.height);
26902
27235
  } else
26903
27236
  f.fillStyle = l || n.backgroundColor, f.fillRect(0, 0, n.width, n.height);
26904
27237
  f.restore();
26905
27238
  }
26906
27239
  f.save(), f.translate(-n.x, -n.y), this.applyExportClipPath(f, n);
26907
- const m = new Set(n.getElementIds()), b = t.filter((g) => m.has(g.id)), h = /* @__PURE__ */ new Map();
26908
- b.forEach((g) => h.set(g.id, g));
26909
- const S = (g, y) => {
26910
- if (!y.id) return;
26911
- const k = h.get(y.id);
26912
- k && k.render(g, !1);
26913
- }, $ = b.map((g) => g.toJSON()), v = /* @__PURE__ */ new Set();
26914
- return b.forEach((g, y) => {
26915
- var k;
26916
- if (g.blendMode === "knockout" || g.blendMode === "clip") {
26917
- const T = $[y], C = g.blendMode === "knockout" ? "destination-out" : "destination-in", _ = ((k = T.knockoutParts) == null ? void 0 : k.scope) || "group", w = $.findIndex((E) => E.id === T.id);
27240
+ const $ = new Set(n.getElementIds()), h = t.filter((m) => $.has(m.id)), b = /* @__PURE__ */ new Map();
27241
+ h.forEach((m) => b.set(m.id, m));
27242
+ const v = (m, g) => {
27243
+ if (!g.id) return;
27244
+ const C = b.get(g.id);
27245
+ C && C.render(m, !1);
27246
+ }, y = h.map((m) => m.toJSON()), x = /* @__PURE__ */ new Set();
27247
+ return h.forEach((m, g) => {
27248
+ var C;
27249
+ if (m.blendMode === "knockout" || m.blendMode === "clip") {
27250
+ const T = y[g], k = m.blendMode === "knockout" ? "destination-out" : "destination-in", _ = ((C = T.knockoutParts) == null ? void 0 : C.scope) || "group", w = y.findIndex((A) => A.id === T.id);
26918
27251
  if (w !== -1 && _ === "artboard")
26919
- for (let E = 0; E < w; E++) {
26920
- const x = $[E].id;
26921
- x && v.add(x);
27252
+ for (let A = 0; A < w; A++) {
27253
+ const E = y[A].id;
27254
+ E && x.add(E);
26922
27255
  }
26923
- An(
27256
+ Dn(
26924
27257
  f,
26925
27258
  T,
26926
- $,
26927
- S,
27259
+ y,
27260
+ v,
26928
27261
  i || !n.exportBackground ? void 0 : l,
26929
27262
  n,
26930
- C
26931
- ), v.add(g.id);
27263
+ k
27264
+ ), x.add(m.id);
26932
27265
  }
26933
- }), b.forEach((g) => {
26934
- v.has(g.id) || g.render(f, !1);
26935
- }), f.restore(), new Promise((g, y) => {
27266
+ }), h.forEach((m) => {
27267
+ x.has(m.id) || m.render(f, !1);
27268
+ }), f.restore(), new Promise((m, g) => {
26936
27269
  d.toBlob(
26937
- (k) => {
26938
- k ? g(k) : y(new Error("Failed to create blob from canvas"));
27270
+ (C) => {
27271
+ C ? m(C) : g(new Error("Failed to create blob from canvas"));
26939
27272
  },
26940
27273
  o === "jpg" || o === "jpeg" ? "image/jpeg" : o === "webp" ? "image/webp" : "image/png",
26941
27274
  s
@@ -26949,7 +27282,7 @@ const on = class on {
26949
27282
  * worker), so font readiness matters here even when no fallback occurred.
26950
27283
  */
26951
27284
  static async mainThreadExportToDataURL(n, t, a, r = {}) {
26952
- var y, k;
27285
+ var g, C;
26953
27286
  const {
26954
27287
  format: o = "png",
26955
27288
  quality: s = 0.95,
@@ -26957,79 +27290,79 @@ const on = class on {
26957
27290
  transparentBackground: i = !1,
26958
27291
  backgroundColor: l = n.backgroundColor
26959
27292
  } = r;
26960
- await ue(t);
27293
+ await $e(t);
26961
27294
  const d = document.createElement("canvas"), u = n.width * c, p = n.height * c;
26962
27295
  d.width = u, d.height = p;
26963
27296
  const f = d.getContext("2d");
26964
27297
  if (f.scale(c, c), !i && n.exportBackground) {
26965
27298
  if (f.save(), this.applyExportBackgroundClipPath(f, n), n.backgroundType === "texture" && n.backgroundTexture) {
26966
- const T = K.getTexturePresetColor(n.backgroundTexture);
27299
+ const T = Z.getTexturePresetColor(n.backgroundTexture);
26967
27300
  f.fillStyle = T, f.fillRect(0, 0, n.width, n.height);
26968
- const C = K.getTexture(n.backgroundTexture);
26969
- C && C.complete ? f.drawImage(C, 0, 0, n.width, n.height) : z.warn("Texture not loaded for export:", n.backgroundTexture);
27301
+ const k = Z.getTexture(n.backgroundTexture);
27302
+ k && k.complete ? f.drawImage(k, 0, 0, n.width, n.height) : W.warn("Texture not loaded for export:", n.backgroundTexture);
26970
27303
  } else
26971
27304
  f.fillStyle = l, f.fillRect(0, 0, n.width, n.height);
26972
27305
  f.restore();
26973
27306
  }
26974
27307
  f.save(), f.translate(-n.x, -n.y), this.applyExportClipPath(f, n);
26975
- const m = new Set(n.getElementIds()), b = t.filter((T) => m.has(T.id)), h = /* @__PURE__ */ new Map();
26976
- b.forEach((T) => h.set(T.id, T));
26977
- const S = (T, C) => {
26978
- if (!C.id) return;
26979
- const _ = h.get(C.id);
26980
- _ ? _.render(T, !1) : z.warn("Element not found in map:", C.id);
26981
- }, $ = b.map((T) => T.toJSON()), v = /* @__PURE__ */ new Set();
26982
- b.forEach((T, C) => {
27308
+ const $ = new Set(n.getElementIds()), h = t.filter((T) => $.has(T.id)), b = /* @__PURE__ */ new Map();
27309
+ h.forEach((T) => b.set(T.id, T));
27310
+ const v = (T, k) => {
27311
+ if (!k.id) return;
27312
+ const _ = b.get(k.id);
27313
+ _ ? _.render(T, !1) : W.warn("Element not found in map:", k.id);
27314
+ }, y = h.map((T) => T.toJSON()), x = /* @__PURE__ */ new Set();
27315
+ h.forEach((T, k) => {
26983
27316
  var _;
26984
27317
  if (T.blendMode === "knockout" || T.blendMode === "clip") {
26985
- const w = $[C], E = T.blendMode === "knockout" ? "destination-out" : "destination-in", x = ((_ = w.knockoutParts) == null ? void 0 : _.scope) || "group", P = $.findIndex((A) => A.id === w.id);
26986
- if (P !== -1 && x === "artboard")
26987
- for (let A = 0; A < P; A++) {
26988
- const F = $[A].id;
26989
- F && v.add(F);
27318
+ const w = y[k], A = T.blendMode === "knockout" ? "destination-out" : "destination-in", E = ((_ = w.knockoutParts) == null ? void 0 : _.scope) || "group", S = y.findIndex((P) => P.id === w.id);
27319
+ if (S !== -1 && E === "artboard")
27320
+ for (let P = 0; P < S; P++) {
27321
+ const I = y[P].id;
27322
+ I && x.add(I);
26990
27323
  }
26991
- An(
27324
+ Dn(
26992
27325
  f,
26993
27326
  w,
26994
- $,
26995
- S,
27327
+ y,
27328
+ v,
26996
27329
  i || !n.exportBackground ? void 0 : l,
26997
27330
  n,
26998
- E
26999
- ), v.add(T.id);
27331
+ A
27332
+ ), x.add(T.id);
27000
27333
  }
27001
- }), b.forEach((T, C) => {
27334
+ }), h.forEach((T, k) => {
27002
27335
  var _;
27003
- if (!v.has(T.id)) {
27004
- const w = $[C], E = ((_ = w == null ? void 0 : w.distressEffect) == null ? void 0 : _.enabled) && w.distressEffect.style === "custom" && w.distressEffect.textureUrl, x = (w == null ? void 0 : w.masks) && w.masks.length > 0, P = (A) => {
27005
- T.render(A, !1);
27336
+ if (!x.has(T.id)) {
27337
+ const w = y[k], A = ((_ = w == null ? void 0 : w.distressEffect) == null ? void 0 : _.enabled) && w.distressEffect.style === "custom" && w.distressEffect.textureUrl, E = (w == null ? void 0 : w.masks) && w.masks.length > 0, S = (P) => {
27338
+ T.render(P, !1);
27006
27339
  };
27007
- if (x && E)
27008
- ne(f, w, (A) => {
27009
- const F = T.getVisualBoundingBox();
27010
- ie(A, w.distressEffect, F, P);
27340
+ if (E && A)
27341
+ oe(f, w, (P) => {
27342
+ const I = T.getVisualBoundingBox();
27343
+ pe(P, w.distressEffect, I, S);
27011
27344
  });
27012
- else if (x)
27013
- ne(f, w, P);
27014
- else if (E) {
27015
- const A = T.getVisualBoundingBox();
27016
- ie(f, w.distressEffect, A, P);
27345
+ else if (E)
27346
+ oe(f, w, S);
27347
+ else if (A) {
27348
+ const P = T.getVisualBoundingBox();
27349
+ pe(f, w.distressEffect, P, S);
27017
27350
  } else
27018
27351
  T.render(f, !1);
27019
27352
  }
27020
- }), (y = n.distressTexture) != null && y.enabled && da(f, n.distressTexture, {
27353
+ }), (g = n.distressTexture) != null && g.enabled && $a(f, n.distressTexture, {
27021
27354
  x: n.x,
27022
27355
  y: n.y,
27023
27356
  width: n.width,
27024
27357
  height: n.height
27025
- }), (k = n.imageMask) != null && k.enabled && na(f, n.imageMask, {
27358
+ }), (C = n.imageMask) != null && C.enabled && la(f, n.imageMask, {
27026
27359
  x: n.x,
27027
27360
  y: n.y,
27028
27361
  width: n.width,
27029
27362
  height: n.height
27030
27363
  }), f.restore();
27031
- const g = o === "png" ? "image/png" : o === "webp" ? "image/webp" : "image/jpeg";
27032
- return d.toDataURL(g, s);
27364
+ const m = o === "png" ? "image/png" : o === "webp" ? "image/webp" : "image/jpeg";
27365
+ return d.toDataURL(m, s);
27033
27366
  }
27034
27367
  /**
27035
27368
  * Apply clip path for export background (uses 0,0 as origin since background is drawn before translate)
@@ -27050,7 +27383,7 @@ const on = class on {
27050
27383
  n.clip(i);
27051
27384
  return;
27052
27385
  } catch (i) {
27053
- z.warn("Invalid SVG path, falling back to rectangle:", i), n.rect(s, c, a, r);
27386
+ W.warn("Invalid SVG path, falling back to rectangle:", i), n.rect(s, c, a, r);
27054
27387
  }
27055
27388
  n.clip();
27056
27389
  }
@@ -27074,7 +27407,7 @@ const on = class on {
27074
27407
  n.translate(a, r), n.clip(i), n.translate(-a, -r);
27075
27408
  return;
27076
27409
  } catch (i) {
27077
- z.warn("Invalid SVG path, falling back to rectangle:", i), n.rect(a, r, o, s);
27410
+ W.warn("Invalid SVG path, falling back to rectangle:", i), n.rect(a, r, o, s);
27078
27411
  }
27079
27412
  n.clip();
27080
27413
  }
@@ -27134,24 +27467,24 @@ const on = class on {
27134
27467
  try {
27135
27468
  const l = performance.now(), d = await this.getWorkerManager();
27136
27469
  if (d) {
27137
- const u = new Set(n.getElementIds()), p = t.filter((h) => u.has(h.id)), f = await d.exportArtboardToDataURL(n, p, {
27470
+ const u = new Set(n.getElementIds()), p = t.filter((b) => u.has(b.id)), f = await d.exportArtboardToDataURL(n, p, {
27138
27471
  scale: r.scale || 1,
27139
27472
  format: (r.format === "jpg" ? "jpeg" : r.format) || "png",
27140
27473
  quality: r.quality || 0.95
27141
- }), m = performance.now() - l, b = c / m;
27474
+ }), $ = performance.now() - l, h = c / $;
27142
27475
  return {
27143
27476
  ...i,
27144
27477
  worker: {
27145
- time: m,
27478
+ time: $,
27146
27479
  dataUrl: f.dataUrl,
27147
27480
  mainThreadBlockTime: f.mainThreadBlockTime
27148
27481
  },
27149
- speedup: b,
27150
- recommendation: b > 1.2 ? `Worker export is ${b.toFixed(2)}x faster - recommended for continuous export` : b < 0.8 ? `Main thread export is ${(1 / b).toFixed(2)}x faster - worker overhead not worth it for single exports` : "Performance is similar, but worker keeps UI responsive during export"
27482
+ speedup: h,
27483
+ recommendation: h > 1.2 ? `Worker export is ${h.toFixed(2)}x faster - recommended for continuous export` : h < 0.8 ? `Main thread export is ${(1 / h).toFixed(2)}x faster - worker overhead not worth it for single exports` : "Performance is similar, but worker keeps UI responsive during export"
27151
27484
  };
27152
27485
  }
27153
27486
  } catch (l) {
27154
- z.error("Worker benchmark failed:", l), i.recommendation = "Worker export not available - using main thread export";
27487
+ W.error("Worker benchmark failed:", l), i.recommendation = "Worker export not available - using main thread export";
27155
27488
  }
27156
27489
  else
27157
27490
  i.recommendation = "Worker export not supported in this browser - using main thread export";
@@ -27173,23 +27506,23 @@ const on = class on {
27173
27506
  for (setTimeout(() => {
27174
27507
  d = !1;
27175
27508
  }, o); d; ) {
27176
- const $ = performance.now();
27509
+ const y = performance.now();
27177
27510
  await this.exportArtboardToDataURL(n, t, a, {
27178
27511
  forceMainThread: !c
27179
27512
  });
27180
- const v = performance.now() - $;
27181
- i.push(v), c || (l += v), await new Promise((g) => setTimeout(g, Math.max(0, s - v)));
27513
+ const x = performance.now() - y;
27514
+ i.push(x), c || (l += x), await new Promise((m) => setTimeout(m, Math.max(0, s - x)));
27182
27515
  }
27183
- const u = i.length, p = i.reduce(($, v) => $ + v, 0) / u, f = Math.min(...i), m = Math.max(...i), b = u / o * 1e3, h = l / o * 100, S = h > 20 ? `Main thread blocked ${h.toFixed(1)}% of the time - STRONGLY recommend worker export` : h > 10 ? `Main thread blocked ${h.toFixed(1)}% of the time - consider worker export` : `Main thread blocked ${h.toFixed(1)}% of the time - performance is acceptable`;
27516
+ const u = i.length, p = i.reduce((y, x) => y + x, 0) / u, f = Math.min(...i), $ = Math.max(...i), h = u / o * 1e3, b = l / o * 100, v = b > 20 ? `Main thread blocked ${b.toFixed(1)}% of the time - STRONGLY recommend worker export` : b > 10 ? `Main thread blocked ${b.toFixed(1)}% of the time - consider worker export` : `Main thread blocked ${b.toFixed(1)}% of the time - performance is acceptable`;
27184
27517
  return {
27185
27518
  totalExports: u,
27186
27519
  duration: o,
27187
27520
  averageTime: p,
27188
27521
  minTime: f,
27189
- maxTime: m,
27522
+ maxTime: $,
27190
27523
  totalMainThreadBlockTime: l,
27191
- exportsPerSecond: b,
27192
- recommendation: S
27524
+ exportsPerSecond: h,
27525
+ recommendation: v
27193
27526
  };
27194
27527
  }
27195
27528
  /**
@@ -27261,60 +27594,64 @@ const on = class on {
27261
27594
  return "previewBackgroundColor" in t && delete t.previewBackgroundColor, t;
27262
27595
  }
27263
27596
  };
27264
- on.CURRENT_VERSION = "2.0.0", on.workerManager = null, on.workerInitPromise = null;
27265
- let yn = on;
27266
- const Ra = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
27597
+ dn.CURRENT_VERSION = "2.0.0", dn.workerManager = null, dn.workerInitPromise = null;
27598
+ let vn = dn;
27599
+ const Ka = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
27267
27600
  __proto__: null,
27268
- ExportManager: yn,
27269
- default: yn
27601
+ ExportManager: vn,
27602
+ default: vn
27270
27603
  }, Symbol.toStringTag, { value: "Module" }));
27271
27604
  export {
27272
- Oa as A,
27273
- De as B,
27274
- ut as C,
27275
- Ie as D,
27276
- yn as E,
27277
- bn as F,
27278
- ca as G,
27279
- sa as H,
27280
- ce as I,
27281
- Ia as J,
27282
- An as K,
27283
- ie as L,
27284
- da as M,
27285
- na as N,
27286
- Un as O,
27287
- jt as P,
27288
- Vt as Q,
27289
- et as R,
27290
- Ra as S,
27291
- K as T,
27292
- dn as W,
27293
- ka as a,
27294
- ge as b,
27295
- R as c,
27296
- Da as d,
27297
- Pa as e,
27298
- On as f,
27299
- xa as g,
27300
- wa as h,
27301
- rt as i,
27302
- Sa as j,
27303
- va as k,
27304
- cn as l,
27305
- Ma as m,
27306
- Aa as n,
27307
- Xn as o,
27308
- Fa as p,
27309
- _n as q,
27310
- ot as r,
27311
- Ta as s,
27312
- Ca as t,
27313
- dt as u,
27314
- _a as v,
27315
- ft as w,
27316
- me as x,
27317
- Ea as y,
27318
- ne as z
27605
+ xt as A,
27606
+ ke as B,
27607
+ Wa as C,
27608
+ Ne as D,
27609
+ vn as E,
27610
+ oe as F,
27611
+ Ya as G,
27612
+ Ue as H,
27613
+ be as I,
27614
+ vt as J,
27615
+ yn as K,
27616
+ ma as L,
27617
+ ha as M,
27618
+ Ha as N,
27619
+ Dn as O,
27620
+ pe as P,
27621
+ $a as Q,
27622
+ la as R,
27623
+ jn as S,
27624
+ Z as T,
27625
+ ea as U,
27626
+ na as V,
27627
+ pn as W,
27628
+ dt as X,
27629
+ Ka as Y,
27630
+ gt as a,
27631
+ La as b,
27632
+ Wn as c,
27633
+ Ce as d,
27634
+ qa as e,
27635
+ B as f,
27636
+ Da as g,
27637
+ Va as h,
27638
+ Ga as i,
27639
+ Nn as j,
27640
+ Oa as k,
27641
+ Ia as l,
27642
+ pt as m,
27643
+ Ra as n,
27644
+ Ma as o,
27645
+ fn as p,
27646
+ Xa as q,
27647
+ Pa as r,
27648
+ za as s,
27649
+ ee as t,
27650
+ ja as u,
27651
+ In as v,
27652
+ Na as w,
27653
+ Ba as x,
27654
+ $t as y,
27655
+ Ua as z
27319
27656
  };
27320
- //# sourceMappingURL=ExportManager-J2xK86uq.js.map
27657
+ //# sourceMappingURL=ExportManager-DUdis6se.js.map