@snowcone-app/canvas 0.27.0 → 0.28.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 (61) hide show
  1. package/ERROR_CONTRACT.md +13 -0
  2. package/dist/{CanvasRenderer-yszzrDfo.js → CanvasRenderer-B_3GISlW.js} +1124 -1068
  3. package/dist/CanvasRenderer-B_3GISlW.js.map +1 -0
  4. package/dist/{CanvasStateV1-BTbCD_xC.js → CanvasStateV1-kL09wsAn.js} +3 -3
  5. package/dist/{CanvasStateV1-BTbCD_xC.js.map → CanvasStateV1-kL09wsAn.js.map} +1 -1
  6. package/dist/ContextualToolbars-C69oYLdw.js +5771 -0
  7. package/dist/ContextualToolbars-C69oYLdw.js.map +1 -0
  8. package/dist/{EditorCanvasImpl-Ui8Ceb-h.js → EditorCanvasImpl-CrI9C_xM.js} +8 -8
  9. package/dist/{EditorCanvasImpl-Ui8Ceb-h.js.map → EditorCanvasImpl-CrI9C_xM.js.map} +1 -1
  10. package/dist/{ExportManager-BTcyj4cf.js → ExportManager-J2xK86uq.js} +12 -16
  11. package/dist/ExportManager-J2xK86uq.js.map +1 -0
  12. package/dist/{FontAnalyzer-EF3gLPr8.js → FontAnalyzer-PE6nysqE.js} +658 -639
  13. package/dist/FontAnalyzer-PE6nysqE.js.map +1 -0
  14. package/dist/{ImagePanel-CIk6z41z.js → ImagePanel-CmQCxBGm.js} +6 -6
  15. package/dist/{ImagePanel-CIk6z41z.js.map → ImagePanel-CmQCxBGm.js.map} +1 -1
  16. package/dist/{SnowconeCanvas-DuWALOAt.js → SnowconeCanvas-CQiFVR0X.js} +10 -10
  17. package/dist/{SnowconeCanvas-DuWALOAt.js.map → SnowconeCanvas-CQiFVR0X.js.map} +1 -1
  18. package/dist/{UnifiedFontService-CHVYDBDW.js → UnifiedFontService-BJzoqfBF.js} +755 -713
  19. package/dist/UnifiedFontService-BJzoqfBF.js.map +1 -0
  20. package/dist/advanced.mjs +14 -14
  21. package/dist/components/MultiSelectionToolbar.d.ts +18 -0
  22. package/dist/components/ui/toolbar-button.d.ts +2 -0
  23. package/dist/core/GestureConstraints.d.ts +92 -0
  24. package/dist/core/InteractionStateMachine.d.ts +16 -2
  25. package/dist/core/ResizeHandler.d.ts +4 -1
  26. package/dist/core/ResizePipeline.d.ts +3 -0
  27. package/dist/{custom-icons-CcLMyybv.js → custom-icons-BWiUGqD6.js} +2 -2
  28. package/dist/{custom-icons-CcLMyybv.js.map → custom-icons-BWiUGqD6.js.map} +1 -1
  29. package/dist/{design-builder-cZY958Rw.js → design-builder-bquxIHct.js} +2 -2
  30. package/dist/{design-builder-cZY958Rw.js.map → design-builder-bquxIHct.js.map} +1 -1
  31. package/dist/{editorErrors-BhrZ_nwj.js → editorErrors-8uDRMhow.js} +2 -2
  32. package/dist/editorErrors-8uDRMhow.js.map +1 -0
  33. package/dist/{embed-CJswRZte.js → embed-L3oRIgsj.js} +10 -10
  34. package/dist/{embed-CJswRZte.js.map → embed-L3oRIgsj.js.map} +1 -1
  35. package/dist/embed.mjs +6 -6
  36. package/dist/errors/editorError.d.ts +7 -1
  37. package/dist/{guards-DIX8aXWM.js → guards-BlbhM5MX.js} +2 -2
  38. package/dist/{guards-DIX8aXWM.js.map → guards-BlbhM5MX.js.map} +1 -1
  39. package/dist/hooks/index.d.ts +2 -0
  40. package/dist/hooks/useAlignDistribute.d.ts +19 -0
  41. package/dist/index.mjs +8 -8
  42. package/dist/internals.mjs +5 -5
  43. package/dist/{template-fields-BXl29sgh.js → template-fields-ai7vnW8g.js} +6 -6
  44. package/dist/{template-fields-BXl29sgh.js.map → template-fields-ai7vnW8g.js.map} +1 -1
  45. package/dist/testing.mjs +4 -4
  46. package/dist/{usePieceGuideBundle-DE21DQGZ.js → usePieceGuideBundle-CMe5br2a.js} +2 -2
  47. package/dist/{usePieceGuideBundle-DE21DQGZ.js.map → usePieceGuideBundle-CMe5br2a.js.map} +1 -1
  48. package/dist/utils/alignDistribute.d.ts +41 -0
  49. package/dist/{validation-DGXAQmUC.js → validation-B8kIYutI.js} +2592 -2562
  50. package/dist/validation-B8kIYutI.js.map +1 -0
  51. package/dist/workers/export-worker.bundle.string.d.ts +1 -1
  52. package/example/package.json +1 -1
  53. package/package.json +1 -1
  54. package/dist/CanvasRenderer-yszzrDfo.js.map +0 -1
  55. package/dist/ContextualToolbars-BHjYsril.js +0 -5556
  56. package/dist/ContextualToolbars-BHjYsril.js.map +0 -1
  57. package/dist/ExportManager-BTcyj4cf.js.map +0 -1
  58. package/dist/FontAnalyzer-EF3gLPr8.js.map +0 -1
  59. package/dist/UnifiedFontService-CHVYDBDW.js.map +0 -1
  60. package/dist/editorErrors-BhrZ_nwj.js.map +0 -1
  61. package/dist/validation-DGXAQmUC.js.map +0 -1
@@ -111,8 +111,8 @@ E.chdir = function(r) {
111
111
  E.umask = function() {
112
112
  return 0;
113
113
  };
114
- var ie = Rt.exports;
115
- const Dt = /* @__PURE__ */ te(ie);
114
+ var se = Rt.exports;
115
+ const Dt = /* @__PURE__ */ te(se);
116
116
  let It = 1;
117
117
  class nt {
118
118
  constructor(t = {}) {
@@ -192,7 +192,7 @@ class nt {
192
192
  * Returns true if point is near the border (within tolerance)
193
193
  */
194
194
  hitTestBorder(t, e, o = 5) {
195
- const i = t >= this.x - o && t <= this.x + this.width + o, s = e >= this.y - o && e <= this.y + this.height + o, a = Math.abs(t - this.x) <= o && s, n = Math.abs(t - (this.x + this.width)) <= o && s, h = Math.abs(e - this.y) <= o && i, l = Math.abs(e - (this.y + this.height)) <= o && i;
195
+ const s = t >= this.x - o && t <= this.x + this.width + o, i = e >= this.y - o && e <= this.y + this.height + o, a = Math.abs(t - this.x) <= o && i, n = Math.abs(t - (this.x + this.width)) <= o && i, h = Math.abs(e - this.y) <= o && s, l = Math.abs(e - (this.y + this.height)) <= o && s;
196
196
  return a || n || h || l;
197
197
  }
198
198
  /**
@@ -210,7 +210,9 @@ class nt {
210
210
  backgroundType: this.backgroundType,
211
211
  backgroundTexture: this.backgroundTexture,
212
212
  exportBackground: this.exportBackground,
213
- clipShape: this.clipShape,
213
+ // ClipShape is a string-or-object union — deep-copy object variants so the
214
+ // clone doesn't share nested path/pieces data with the original
215
+ clipShape: typeof this.clipShape == "object" ? structuredClone(this.clipShape) : this.clipShape,
214
216
  previewBackgroundColor: this.previewBackgroundColor,
215
217
  role: this.role,
216
218
  distressTexture: this.distressTexture ? { ...this.distressTexture } : void 0,
@@ -300,11 +302,11 @@ class qe {
300
302
  if (!e)
301
303
  return [];
302
304
  const o = e.getElementIds();
303
- if (o.forEach((i) => {
304
- this.elementToArtboard.delete(i);
305
+ if (o.forEach((s) => {
306
+ this.elementToArtboard.delete(s);
305
307
  }), this.artboards.delete(t), this.activeArtboardId === t) {
306
- const i = Array.from(this.artboards.keys());
307
- this.activeArtboardId = i.length > 0 ? i[0] : null;
308
+ const s = Array.from(this.artboards.keys());
309
+ this.activeArtboardId = s.length > 0 ? s[0] : null;
308
310
  }
309
311
  return o;
310
312
  }
@@ -351,10 +353,10 @@ class qe {
351
353
  const o = this.artboards.get(e);
352
354
  if (!o)
353
355
  return !1;
354
- const i = this.elementToArtboard.get(t);
355
- if (i) {
356
- const s = this.artboards.get(i);
357
- s == null || s.removeElementId(t);
356
+ const s = this.elementToArtboard.get(t);
357
+ if (s) {
358
+ const i = this.artboards.get(s);
359
+ i == null || i.removeElementId(t);
358
360
  }
359
361
  return o.addElementId(t), this.elementToArtboard.set(t, e), !0;
360
362
  }
@@ -394,19 +396,19 @@ class qe {
394
396
  */
395
397
  findArtboardAtPoint(t, e) {
396
398
  const o = Array.from(this.artboards.values()).reverse();
397
- for (const i of o)
398
- if (i.containsPoint(t, e))
399
- return i;
399
+ for (const s of o)
400
+ if (s.containsPoint(t, e))
401
+ return s;
400
402
  return null;
401
403
  }
402
404
  /**
403
405
  * Find artboard border at point (for resize handles)
404
406
  */
405
407
  findArtboardBorderAtPoint(t, e, o = 5) {
406
- const i = Array.from(this.artboards.values()).reverse();
407
- for (const s of i)
408
- if (s.hitTestBorder(t, e, o))
409
- return s;
408
+ const s = Array.from(this.artboards.values()).reverse();
409
+ for (const i of s)
410
+ if (i.hitTestBorder(t, e, o))
411
+ return i;
410
412
  return null;
411
413
  }
412
414
  /**
@@ -447,8 +449,8 @@ class qe {
447
449
  reorderArtboards(t, e) {
448
450
  const o = Array.from(this.artboards.entries());
449
451
  if (t < 0 || t >= o.length || e < 0 || e >= o.length || t === e) return;
450
- const [i] = o.splice(t, 1);
451
- o.splice(e, 0, i), this.artboards = new Map(o);
452
+ const [s] = o.splice(t, 1);
453
+ o.splice(e, 0, s), this.artboards = new Map(o);
452
454
  }
453
455
  /**
454
456
  * Clear all artboards
@@ -471,8 +473,8 @@ class qe {
471
473
  fromJSON(t) {
472
474
  this.clear(), t.artboards.forEach((e) => {
473
475
  const o = nt.fromJSON(e);
474
- this.artboards.set(o.id, o), o.getElementIds().forEach((i) => {
475
- this.elementToArtboard.set(i, o.id);
476
+ this.artboards.set(o.id, o), o.getElementIds().forEach((s) => {
477
+ this.elementToArtboard.set(s, o.id);
476
478
  });
477
479
  }), this.activeArtboardId = t.activeArtboardId;
478
480
  }
@@ -482,11 +484,11 @@ class qe {
482
484
  */
483
485
  validateMappings(t) {
484
486
  const e = new Set(t.map((o) => o.id));
485
- for (const [o, i] of this.elementToArtboard.entries())
487
+ for (const [o, s] of this.elementToArtboard.entries())
486
488
  e.has(o) || this.removeElementFromArtboard(o);
487
489
  for (const o of this.artboards.values()) {
488
- const i = o.getElementIds().filter((s) => e.has(s));
489
- o.clearElementIds(), i.forEach((s) => o.addElementId(s));
490
+ const s = o.getElementIds().filter((i) => e.has(i));
491
+ o.clearElementIds(), s.forEach((i) => o.addElementId(i));
490
492
  }
491
493
  }
492
494
  }
@@ -519,7 +521,7 @@ const D = {
519
521
  return t > 180 && (t -= 360), t;
520
522
  }
521
523
  };
522
- let se = 1;
524
+ let ie = 1;
523
525
  class Q {
524
526
  /** Whether this element clips content below it (derived from blendMode === 'clip') */
525
527
  get isClipping() {
@@ -529,7 +531,7 @@ class Q {
529
531
  t ? (this.blendMode = "clip", this.knockoutParts || (this.knockoutParts = { fill: !0, scope: "group" })) : this.blendMode === "clip" && (this.blendMode = "normal");
530
532
  }
531
533
  constructor(t = {}) {
532
- this.id = t.id || `element-${se++}`, this.x = t.x !== void 0 ? t.x : 100, this.y = t.y !== void 0 ? t.y : 100, this.rotation = t.rotation !== void 0 ? t.rotation : 0, this.opacity = t.opacity !== void 0 ? t.opacity : 1, this.transformType = t.transformType || "custom", this.transformData = t.transformData || {}, this.blendMode = t.blendMode, this.knockoutParts = t.knockoutParts, this.stroke = t.stroke, this.masks = t.masks, this.distressEffect = t.distressEffect, t.isClipping && !t.blendMode && (this.blendMode = "clip", this.knockoutParts || (this.knockoutParts = { fill: !0, scope: "group" })), this.name = t.name, this.visible = t.visible !== void 0 ? t.visible : !0, this.locked = t.locked !== void 0 ? t.locked : !1;
534
+ this.id = t.id || `element-${ie++}`, this.x = t.x !== void 0 ? t.x : 100, this.y = t.y !== void 0 ? t.y : 100, this.rotation = t.rotation !== void 0 ? t.rotation : 0, this.opacity = t.opacity !== void 0 ? t.opacity : 1, this.transformType = t.transformType || "custom", this.transformData = t.transformData || {}, this.blendMode = t.blendMode, this.knockoutParts = t.knockoutParts, this.stroke = t.stroke, this.masks = t.masks, this.distressEffect = t.distressEffect, t.isClipping && !t.blendMode && (this.blendMode = "clip", this.knockoutParts || (this.knockoutParts = { fill: !0, scope: "group" })), this.name = t.name, this.visible = t.visible !== void 0 ? t.visible : !0, this.locked = t.locked !== void 0 ? t.locked : !1;
533
535
  }
534
536
  /**
535
537
  * Get visual bounding box (tight fit around actual rendered content)
@@ -552,7 +554,7 @@ class Q {
552
554
  * Uses visual bounding box for better user experience
553
555
  */
554
556
  hitTest(t, e) {
555
- const o = this.getVisualBoundingBox(), i = this.getRotationAnchor(), s = D.toRadiansInverse(this.rotation), a = Math.cos(s), n = Math.sin(s), h = t - i.x, l = e - i.y, c = h * a - l * n, g = h * n + l * a, d = i.x + c, f = i.y + g;
557
+ const o = this.getVisualBoundingBox(), s = this.getRotationAnchor(), i = D.toRadiansInverse(this.rotation), a = Math.cos(i), n = Math.sin(i), h = t - s.x, l = e - s.y, c = h * a - l * n, g = h * n + l * a, d = s.x + c, f = s.y + g;
556
558
  return d >= o.x && d <= o.x + o.width && f >= o.y && f <= o.y + o.height;
557
559
  }
558
560
  /**
@@ -578,8 +580,16 @@ class Q {
578
580
  // Effects properties (only include if defined)
579
581
  ...this.blendMode && { blendMode: this.blendMode },
580
582
  ...this.knockoutParts && { knockoutParts: { ...this.knockoutParts } },
581
- ...this.stroke && { stroke: { ...this.stroke } },
582
- ...this.masks && { masks: this.masks.map((t) => ({ ...t })) },
583
+ ...this.stroke && {
584
+ stroke: {
585
+ ...this.stroke,
586
+ ...this.stroke.dashArray && { dashArray: [...this.stroke.dashArray] }
587
+ }
588
+ },
589
+ // maskElement is a nested config object — structuredClone so clones don't share it
590
+ ...this.masks && {
591
+ masks: this.masks.map((t) => ({ ...t, maskElement: structuredClone(t.maskElement) }))
592
+ },
583
593
  ...this.distressEffect && { distressEffect: { ...this.distressEffect } },
584
594
  // Layer properties (only include if defined)
585
595
  ...this.name && { name: this.name },
@@ -655,10 +665,10 @@ class R {
655
665
  * @returns Point in local coordinates
656
666
  */
657
667
  worldToLocal(t, e) {
658
- const o = this.element.rotation * Math.PI / 180, i = Math.cos(o), s = Math.sin(o), a = t - this.element.x, n = e - this.element.y;
668
+ const o = this.element.rotation * Math.PI / 180, s = Math.cos(o), i = Math.sin(o), a = t - this.element.x, n = e - this.element.y;
659
669
  return {
660
- x: a * i - n * s,
661
- y: a * s + n * i
670
+ x: a * s - n * i,
671
+ y: a * i + n * s
662
672
  };
663
673
  }
664
674
  /**
@@ -671,7 +681,7 @@ class R {
671
681
  * @returns Point in world coordinates
672
682
  */
673
683
  localToWorld(t, e) {
674
- const o = -this.element.rotation * Math.PI / 180, i = Math.cos(o), s = Math.sin(o), a = t * i - e * s, n = t * s + e * i;
684
+ const o = -this.element.rotation * Math.PI / 180, s = Math.cos(o), i = Math.sin(o), a = t * s - e * i, n = t * i + e * s;
675
685
  return {
676
686
  x: this.element.x + a,
677
687
  y: this.element.y + n
@@ -687,10 +697,10 @@ class R {
687
697
  * @returns Delta in local space
688
698
  */
689
699
  worldDeltaToLocal(t, e) {
690
- const o = this.element.rotation * Math.PI / 180, i = Math.cos(o), s = Math.sin(o);
700
+ const o = this.element.rotation * Math.PI / 180, s = Math.cos(o), i = Math.sin(o);
691
701
  return {
692
- dx: t * i - e * s,
693
- dy: t * s + e * i
702
+ dx: t * s - e * i,
703
+ dy: t * i + e * s
694
704
  };
695
705
  }
696
706
  /**
@@ -702,10 +712,10 @@ class R {
702
712
  * @returns Delta in world space
703
713
  */
704
714
  localDeltaToWorld(t, e) {
705
- const o = -this.element.rotation * Math.PI / 180, i = Math.cos(o), s = Math.sin(o);
715
+ const o = -this.element.rotation * Math.PI / 180, s = Math.cos(o), i = Math.sin(o);
706
716
  return {
707
- dx: t * i - e * s,
708
- dy: t * s + e * i
717
+ dx: t * s - e * i,
718
+ dy: t * i + e * s
709
719
  };
710
720
  }
711
721
  /**
@@ -719,11 +729,11 @@ class R {
719
729
  * @param angleDegrees - Rotation angle in degrees (positive = clockwise in UI)
720
730
  * @returns Rotated point in world space
721
731
  */
722
- static rotatePointAroundAnchor(t, e, o, i, s) {
723
- const a = -s * Math.PI / 180, n = Math.cos(a), h = Math.sin(a), l = t - o, c = e - i, g = l * n - c * h, d = l * h + c * n;
732
+ static rotatePointAroundAnchor(t, e, o, s, i) {
733
+ const a = -i * Math.PI / 180, n = Math.cos(a), h = Math.sin(a), l = t - o, c = e - s, g = l * n - c * h, d = l * h + c * n;
724
734
  return {
725
735
  x: o + g,
726
- y: i + d
736
+ y: s + d
727
737
  };
728
738
  }
729
739
  /**
@@ -2295,8 +2305,8 @@ function Ke(r = 0.1, t) {
2295
2305
  if (e.startsWith("oklch("))
2296
2306
  return `${e.slice(0, -1)} / ${r})`;
2297
2307
  if (e.startsWith("#")) {
2298
- const o = e.replace("#", ""), i = parseInt(o.substring(0, 2), 16), s = parseInt(o.substring(2, 4), 16), a = parseInt(o.substring(4, 6), 16);
2299
- return `rgba(${i}, ${s}, ${a}, ${r})`;
2308
+ const o = e.replace("#", ""), s = parseInt(o.substring(0, 2), 16), i = parseInt(o.substring(2, 4), 16), a = parseInt(o.substring(4, 6), 16);
2309
+ return `rgba(${s}, ${i}, ${a}, ${r})`;
2300
2310
  }
2301
2311
  return e;
2302
2312
  }
@@ -2328,13 +2338,13 @@ function oo(r) {
2328
2338
  const t = he(r);
2329
2339
  return t.startsWith("oklch(") ? `${t.slice(0, -1)} / 0.2)` : "rgba(0,0,0,0.2)";
2330
2340
  }
2331
- function io(r) {
2341
+ function so(r) {
2332
2342
  if (typeof window > "u" || typeof document > "u")
2333
2343
  return "oklch(0% 0 0 / 0.2)";
2334
2344
  const t = document.documentElement;
2335
2345
  return getComputedStyle(t).getPropertyValue("--divider").trim() || "oklch(0% 0 0 / 0.2)";
2336
2346
  }
2337
- function so(r) {
2347
+ function io(r) {
2338
2348
  if (typeof window > "u" || typeof document > "u")
2339
2349
  return "oklch(0% 0 0 / 0.5)";
2340
2350
  const t = document.documentElement, e = getComputedStyle(t).getPropertyValue("--foreground").trim();
@@ -2503,16 +2513,16 @@ class J {
2503
2513
  return e.refCount++, e.image;
2504
2514
  const o = new Image();
2505
2515
  o.crossOrigin = "anonymous";
2506
- const i = {
2516
+ const s = {
2507
2517
  image: o,
2508
2518
  refCount: 1,
2509
2519
  loaded: !1
2510
2520
  };
2511
2521
  return o.onload = () => {
2512
- i.loaded = !0;
2522
+ s.loaded = !0;
2513
2523
  }, o.onerror = () => {
2514
- i.loaded = !0;
2515
- }, this.cache.set(t, i), (!t.includes(":") || /^https?:\/\/|^data:|^blob:/.test(t)) && (o.src = t), o;
2524
+ s.loaded = !0;
2525
+ }, this.cache.set(t, s), (!t.includes(":") || /^https?:\/\/|^data:|^blob:/.test(t)) && (o.src = t), o;
2516
2526
  }
2517
2527
  /**
2518
2528
  * Release a reference to a cached image.
@@ -2568,13 +2578,13 @@ function C(r) {
2568
2578
  class pt extends Q {
2569
2579
  // Track URL acquired from ImageCache for release on destroy
2570
2580
  constructor(t = {}) {
2571
- var e, o, i, s, a, n, h, l, c, g;
2581
+ var e, o, s, i, a, n, h, l, c, g;
2572
2582
  super(t), this.svgBlobUrl = null, this.loadTimeoutId = null, this.retryAttempt = 0, this.cachedImageUrl = null, this.transformType = "image", this.transformData = {
2573
2583
  type: "image",
2574
2584
  width: ((e = t.transformData) == null ? void 0 : e.width) || 200,
2575
2585
  height: ((o = t.transformData) == null ? void 0 : o.height) || 200,
2576
- cropX: ((i = t.transformData) == null ? void 0 : i.cropX) ?? 0,
2577
- cropY: ((s = t.transformData) == null ? void 0 : s.cropY) ?? 0,
2586
+ cropX: ((s = t.transformData) == null ? void 0 : s.cropX) ?? 0,
2587
+ cropY: ((i = t.transformData) == null ? void 0 : i.cropY) ?? 0,
2578
2588
  cropWidth: ((a = t.transformData) == null ? void 0 : a.cropWidth) ?? 1,
2579
2589
  cropHeight: ((n = t.transformData) == null ? void 0 : n.cropHeight) ?? 1,
2580
2590
  flipHorizontal: ((h = t.transformData) == null ? void 0 : h.flipHorizontal) ?? !1,
@@ -2609,28 +2619,28 @@ class pt extends Q {
2609
2619
  this.clearLoadTimeout(), this.releaseImageCache();
2610
2620
  const o = J.getInstance().acquire(t);
2611
2621
  this.cachedImageUrl = t;
2612
- let i = !1;
2613
- const s = () => {
2614
- i = !0, this.clearLoadTimeout();
2622
+ let s = !1;
2623
+ const i = () => {
2624
+ s = !0, this.clearLoadTimeout();
2615
2625
  };
2616
2626
  if (o.complete && o.naturalWidth > 0) {
2617
- s(), this.imageElement = o, this.imageLoaded = !0, this.imageLoadState = "loaded", this.imageLoadError = null, this.imageAspectRatio = o.naturalWidth / o.naturalHeight, this.preserveDimensions || (this.transformData.height = this.transformData.width / this.imageAspectRatio), this.onLoadCallback && this.onLoadCallback(this.clone()), et(this.id);
2627
+ i(), this.imageElement = o, this.imageLoaded = !0, this.imageLoadState = "loaded", this.imageLoadError = null, this.imageAspectRatio = o.naturalWidth / o.naturalHeight, this.preserveDimensions || (this.transformData.height = this.transformData.width / this.imageAspectRatio), this.onLoadCallback && this.onLoadCallback(this.clone()), et(this.id);
2618
2628
  return;
2619
2629
  }
2620
2630
  const a = o.onload, n = o.onerror;
2621
2631
  o.onload = (l) => {
2622
- i || (s(), this.imageElement = o, this.imageLoaded = !0, this.imageLoadState = "loaded", this.imageLoadError = null, this.imageAspectRatio = o.naturalWidth / o.naturalHeight, this.preserveDimensions || (this.transformData.height = this.transformData.width / this.imageAspectRatio), this.onLoadCallback && this.onLoadCallback(this.clone()), et(this.id), a && a !== o.onload && a(l));
2632
+ s || (i(), this.imageElement = o, this.imageLoaded = !0, this.imageLoadState = "loaded", this.imageLoadError = null, this.imageAspectRatio = o.naturalWidth / o.naturalHeight, this.preserveDimensions || (this.transformData.height = this.transformData.width / this.imageAspectRatio), this.onLoadCallback && this.onLoadCallback(this.clone()), et(this.id), a && a !== o.onload && a(l));
2623
2633
  }, o.onerror = (l) => {
2624
- if (i) return;
2625
- s();
2634
+ if (s) return;
2635
+ i();
2626
2636
  const c = new Error(`Failed to load image: ${t}`);
2627
2637
  this.handleLoadFailure(t, c), n && n !== o.onerror && n(l);
2628
2638
  }, this.loadTimeoutId = setTimeout(() => {
2629
- if (i) return;
2630
- s(), o.src = "";
2639
+ if (s) return;
2640
+ i(), o.src = "";
2631
2641
  const l = new Error(`Image load timed out after ${kt}ms: ${t}`);
2632
2642
  this.handleLoadFailure(t, l);
2633
- }, kt), (!o.src || o.src !== t) && (o.src = t), !i && o.complete && o.naturalWidth > 0 && ((h = o.onload) == null || h.call(o, new Event("load")));
2643
+ }, kt), (!o.src || o.src !== t) && (o.src = t), !s && o.complete && o.naturalWidth > 0 && ((h = o.onload) == null || h.call(o, new Event("load")));
2634
2644
  }
2635
2645
  /**
2636
2646
  * Handle a load failure - either retry with backoff or set error state.
@@ -2679,10 +2689,10 @@ class pt extends Q {
2679
2689
  this.revokeSvgBlobUrl();
2680
2690
  const e = new Image();
2681
2691
  e.crossOrigin = "anonymous", e.onload = () => {
2682
- const i = document.createElement("canvas");
2683
- i.width = e.width * 4, i.height = e.height * 4;
2684
- const s = i.getContext("2d");
2685
- s.scale(4, 4), s.drawImage(e, 0, 0), i.toBlob((a) => {
2692
+ const s = document.createElement("canvas");
2693
+ s.width = e.width * 4, s.height = e.height * 4;
2694
+ const i = s.getContext("2d");
2695
+ i.scale(4, 4), i.drawImage(e, 0, 0), s.toBlob((a) => {
2686
2696
  if (!a) {
2687
2697
  ot.error("Failed to convert SVG to blob"), this.imageLoaded = !1;
2688
2698
  return;
@@ -2703,10 +2713,10 @@ class pt extends Q {
2703
2713
  getBoundingBox() {
2704
2714
  if (this.isCropping) {
2705
2715
  const t = this.transformData.width * this.transformData.cropWidth, e = this.transformData.height * this.transformData.cropHeight;
2706
- let o = this.transformData.width / 2 - (this.transformData.cropX * this.transformData.width + t / 2), i = this.transformData.height / 2 - (this.transformData.cropY * this.transformData.height + e / 2);
2707
- const s = this.transformData.flipHorizontal ? -1 : 1, a = this.transformData.flipVertical ? -1 : 1;
2708
- o *= s, i *= a;
2709
- const n = Math.cos(D.toRadians(this.rotation)), h = Math.sin(D.toRadians(this.rotation)), l = o * n - i * h, c = o * h + i * n, g = this.x + l, d = this.y + c;
2716
+ let o = this.transformData.width / 2 - (this.transformData.cropX * this.transformData.width + t / 2), s = this.transformData.height / 2 - (this.transformData.cropY * this.transformData.height + e / 2);
2717
+ const i = this.transformData.flipHorizontal ? -1 : 1, a = this.transformData.flipVertical ? -1 : 1;
2718
+ o *= i, s *= a;
2719
+ const n = Math.cos(D.toRadians(this.rotation)), h = Math.sin(D.toRadians(this.rotation)), l = o * n - s * h, c = o * h + s * n, g = this.x + l, d = this.y + c;
2710
2720
  return {
2711
2721
  x: g - this.transformData.width / 2,
2712
2722
  y: d - this.transformData.height / 2,
@@ -2744,10 +2754,10 @@ class pt extends Q {
2744
2754
  getRotationAnchor() {
2745
2755
  if (this.isCropping) {
2746
2756
  const t = this.transformData.width * this.transformData.cropWidth, e = this.transformData.height * this.transformData.cropHeight;
2747
- let o = this.transformData.width / 2 - (this.transformData.cropX * this.transformData.width + t / 2), i = this.transformData.height / 2 - (this.transformData.cropY * this.transformData.height + e / 2);
2748
- const s = this.transformData.flipHorizontal ? -1 : 1, a = this.transformData.flipVertical ? -1 : 1;
2749
- o *= s, i *= a;
2750
- const n = Math.cos(D.toRadians(this.rotation)), h = Math.sin(D.toRadians(this.rotation)), l = o * n - i * h, c = o * h + i * n;
2757
+ let o = this.transformData.width / 2 - (this.transformData.cropX * this.transformData.width + t / 2), s = this.transformData.height / 2 - (this.transformData.cropY * this.transformData.height + e / 2);
2758
+ const i = this.transformData.flipHorizontal ? -1 : 1, a = this.transformData.flipVertical ? -1 : 1;
2759
+ o *= i, s *= a;
2760
+ const n = Math.cos(D.toRadians(this.rotation)), h = Math.sin(D.toRadians(this.rotation)), l = o * n - s * h, c = o * h + s * n;
2751
2761
  return {
2752
2762
  x: this.x + l,
2753
2763
  y: this.y + c
@@ -2764,10 +2774,10 @@ class pt extends Q {
2764
2774
  hitTest(t, e) {
2765
2775
  const o = this.worldToLocal(t, e);
2766
2776
  if (this.isCropping) {
2767
- const i = this.transformData.width * this.transformData.cropWidth, s = this.transformData.height * this.transformData.cropHeight, a = this.transformData.width / 2 - (this.transformData.cropX * this.transformData.width + i / 2), n = this.transformData.height / 2 - (this.transformData.cropY * this.transformData.height + s / 2), h = this.transformData.width / 2, l = this.transformData.height / 2;
2777
+ const s = this.transformData.width * this.transformData.cropWidth, i = this.transformData.height * this.transformData.cropHeight, a = this.transformData.width / 2 - (this.transformData.cropX * this.transformData.width + s / 2), n = this.transformData.height / 2 - (this.transformData.cropY * this.transformData.height + i / 2), h = this.transformData.width / 2, l = this.transformData.height / 2;
2768
2778
  return o.x >= a - h && o.x <= a + h && o.y >= n - l && o.y <= n + l;
2769
2779
  } else {
2770
- const i = this.transformData.width * this.transformData.cropWidth, s = this.transformData.height * this.transformData.cropHeight, a = i / 2, n = s / 2;
2780
+ const s = this.transformData.width * this.transformData.cropWidth, i = this.transformData.height * this.transformData.cropHeight, a = s / 2, n = i / 2;
2771
2781
  return o.x >= -a && o.x <= a && o.y >= -n && o.y <= n;
2772
2782
  }
2773
2783
  }
@@ -2780,8 +2790,8 @@ class pt extends Q {
2780
2790
  return;
2781
2791
  }
2782
2792
  t.save(), this.opacity !== void 0 && this.opacity !== 1 && (t.globalAlpha = this.opacity), t.translate(this.x, this.y), t.rotate(D.toRadians(this.rotation));
2783
- const i = this.transformData.flipHorizontal ? -1 : 1, s = this.transformData.flipVertical ? -1 : 1;
2784
- if (t.scale(i, s), this.isCropping) {
2793
+ const s = this.transformData.flipHorizontal ? -1 : 1, i = this.transformData.flipVertical ? -1 : 1;
2794
+ if (t.scale(s, i), this.isCropping) {
2785
2795
  const a = this.transformData.width * this.transformData.cropWidth, n = this.transformData.height * this.transformData.cropHeight, h = this.transformData.width / 2 - (this.transformData.cropX * this.transformData.width + a / 2), l = this.transformData.height / 2 - (this.transformData.cropY * this.transformData.height + n / 2), c = h - this.transformData.width / 2, g = l - this.transformData.height / 2, d = this.transformData.borderRadius || 0;
2786
2796
  if (d > 0) {
2787
2797
  t.save();
@@ -2842,48 +2852,48 @@ class pt extends Q {
2842
2852
  */
2843
2853
  renderPlaceholder(t) {
2844
2854
  t.save(), t.translate(this.x, this.y), t.rotate(D.toRadians(this.rotation));
2845
- const e = this.transformData.width * this.transformData.cropWidth, o = this.transformData.height * this.transformData.cropHeight, i = -e / 2, s = -o / 2;
2855
+ const e = this.transformData.width * this.transformData.cropWidth, o = this.transformData.height * this.transformData.cropHeight, s = -e / 2, i = -o / 2;
2846
2856
  let a, n, h;
2847
- this.imageLoadState === "error" ? (a = "#f0e0e0", n = "#993333", h = "Image failed to load") : this.imageLoadState === "retrying" ? (a = "#e0e0e0", n = "#666", h = "Retrying...") : this.imageLoadState === "loading" ? (a = "#e0e0e0", n = "#666", h = "Loading...") : (a = "#e0e0e0", n = "#666", h = this.imageUrl ? "Loading..." : "No image"), t.fillStyle = a, t.fillRect(i, s, e, o), t.fillStyle = n, t.font = "14px system-ui, -apple-system, sans-serif", t.textAlign = "center", t.textBaseline = "middle", t.fillText(h, 0, 0), t.restore();
2857
+ this.imageLoadState === "error" ? (a = "#f0e0e0", n = "#993333", h = "Image failed to load") : this.imageLoadState === "retrying" ? (a = "#e0e0e0", n = "#666", h = "Retrying...") : this.imageLoadState === "loading" ? (a = "#e0e0e0", n = "#666", h = "Loading...") : (a = "#e0e0e0", n = "#666", h = this.imageUrl ? "Loading..." : "No image"), t.fillStyle = a, t.fillRect(s, i, e, o), t.fillStyle = n, t.font = "14px system-ui, -apple-system, sans-serif", t.textAlign = "center", t.textBaseline = "middle", t.fillText(h, 0, 0), t.restore();
2848
2858
  }
2849
2859
  /**
2850
2860
  * Handle resize - maintain aspect ratio
2851
2861
  * @returns {boolean} true if resize was applied
2852
2862
  */
2853
- resize(t, e, o, i) {
2854
- let s, a;
2855
- this.isCropping ? (s = e / C(i).width, a = o / C(i).height) : (s = e / (i.width ?? 1), a = o / (i.height ?? 1));
2856
- const n = (s + a) / 2;
2863
+ resize(t, e, o, s) {
2864
+ let i, a;
2865
+ this.isCropping ? (i = e / C(s).width, a = o / C(s).height) : (i = e / (s.width ?? 1), a = o / (s.height ?? 1));
2866
+ const n = (i + a) / 2;
2857
2867
  let h = t;
2858
- this.isCropping && (h = this.remapAnchorForFlips(t, i));
2868
+ this.isCropping && (h = this.remapAnchorForFlips(t, s));
2859
2869
  let l = n;
2860
2870
  if (this.isCropping) {
2861
- const I = this.transformData.width / C(i).width;
2871
+ const I = this.transformData.width / C(s).width;
2862
2872
  n < I && (l = this.calculateMinScaleForCropBounds(
2863
2873
  h,
2864
- i,
2874
+ s,
2865
2875
  n,
2866
2876
  I
2867
2877
  ));
2868
2878
  }
2869
- this.transformData.width = C(i).width * l, this.transformData.height = this.transformData.width / this.imageAspectRatio, this.rotation = i.rotation;
2879
+ this.transformData.width = C(s).width * l, this.transformData.height = this.transformData.width / this.imageAspectRatio, this.rotation = s.rotation;
2870
2880
  let c, g;
2871
2881
  if (this.isCropping) {
2872
- const I = (C(i).cropX + C(i).cropWidth / 2) * C(i).width - C(i).width / 2, O = (C(i).cropY + C(i).cropHeight / 2) * C(i).height - C(i).height / 2, B = I, L = O, H = R.fromSnapshot(i).localDeltaToWorld(B, L), G = H.dx, $ = H.dy;
2873
- c = i.x - G, g = i.y - $;
2882
+ const I = (C(s).cropX + C(s).cropWidth / 2) * C(s).width - C(s).width / 2, O = (C(s).cropY + C(s).cropHeight / 2) * C(s).height - C(s).height / 2, B = I, L = O, H = R.fromSnapshot(s).localDeltaToWorld(B, L), G = H.dx, $ = H.dy;
2883
+ c = s.x - G, g = s.y - $;
2874
2884
  } else {
2875
- const I = (C(i).cropX + C(i).cropWidth / 2) * C(i).width - C(i).width / 2, O = (C(i).cropY + C(i).cropHeight / 2) * C(i).height - C(i).height / 2, B = I, L = O, H = R.fromSnapshot(i).localDeltaToWorld(B, L), G = H.dx, $ = H.dy;
2876
- c = i.x - G, g = i.y - $;
2885
+ const I = (C(s).cropX + C(s).cropWidth / 2) * C(s).width - C(s).width / 2, O = (C(s).cropY + C(s).cropHeight / 2) * C(s).height - C(s).height / 2, B = I, L = O, H = R.fromSnapshot(s).localDeltaToWorld(B, L), G = H.dx, $ = H.dy;
2886
+ c = s.x - G, g = s.y - $;
2877
2887
  }
2878
2888
  let d, f, u = 0, m = 0;
2879
- h === "top-left" ? (u = C(i).width / 2, m = C(i).height / 2) : h === "top-right" ? (u = -C(i).width / 2, m = C(i).height / 2) : h === "bottom-left" ? (u = C(i).width / 2, m = -C(i).height / 2) : h === "bottom-right" ? (u = -C(i).width / 2, m = -C(i).height / 2) : h === "middle-left" ? (u = C(i).width / 2, m = 0) : h === "middle-right" ? (u = -C(i).width / 2, m = 0) : h === "middle-top" ? (u = 0, m = C(i).height / 2) : h === "middle-bottom" && (u = 0, m = -C(i).height / 2);
2880
- const y = R.fromSnapshot(i).localDeltaToWorld(u, m), x = y.dx, b = y.dy;
2889
+ h === "top-left" ? (u = C(s).width / 2, m = C(s).height / 2) : h === "top-right" ? (u = -C(s).width / 2, m = C(s).height / 2) : h === "bottom-left" ? (u = C(s).width / 2, m = -C(s).height / 2) : h === "bottom-right" ? (u = -C(s).width / 2, m = -C(s).height / 2) : h === "middle-left" ? (u = C(s).width / 2, m = 0) : h === "middle-right" ? (u = -C(s).width / 2, m = 0) : h === "middle-top" ? (u = 0, m = C(s).height / 2) : h === "middle-bottom" && (u = 0, m = -C(s).height / 2);
2890
+ const y = R.fromSnapshot(s).localDeltaToWorld(u, m), x = y.dx, b = y.dy;
2881
2891
  d = c + x, f = g + b;
2882
2892
  let S = 0, v = 0;
2883
2893
  h === "top-left" ? (S = this.transformData.width / 2, v = this.transformData.height / 2) : h === "top-right" ? (S = -this.transformData.width / 2, v = this.transformData.height / 2) : h === "bottom-left" ? (S = this.transformData.width / 2, v = -this.transformData.height / 2) : h === "bottom-right" ? (S = -this.transformData.width / 2, v = -this.transformData.height / 2) : h === "middle-left" ? (S = this.transformData.width / 2, v = 0) : h === "middle-right" ? (S = -this.transformData.width / 2, v = 0) : h === "middle-top" ? (S = 0, v = this.transformData.height / 2) : h === "middle-bottom" && (S = 0, v = -this.transformData.height / 2);
2884
2894
  const T = new R(this).localDeltaToWorld(S, v), F = T.dx, A = T.dy, M = d - F, k = f - A;
2885
2895
  if (this.isCropping) {
2886
- const I = i.x, O = i.y, B = C(i).cropWidth * C(i).width, L = C(i).cropHeight * C(i).height;
2896
+ const I = s.x, O = s.y, B = C(s).cropWidth * C(s).width, L = C(s).cropHeight * C(s).height;
2887
2897
  this.x = I, this.y = O;
2888
2898
  const _ = B / this.transformData.width, H = L / this.transformData.height, G = I - M, $ = O - k, At = new R(this).worldDeltaToLocal(G, $), Jt = At.dx, qt = At.dy, jt = this.transformData.width / 2 + Jt, Zt = this.transformData.height / 2 + qt, Kt = jt / this.transformData.width - _ / 2, Qt = Zt / this.transformData.height - H / 2;
2889
2899
  this.transformData.cropX = Kt, this.transformData.cropY = Qt, this.transformData.cropWidth = _, this.transformData.cropHeight = H;
@@ -2945,9 +2955,9 @@ class pt extends Q {
2945
2955
  // bottom-left
2946
2956
  { x: t.x + t.width, y: t.y + t.height }
2947
2957
  // bottom-right
2948
- ].map((s) => ({
2949
- x: this.x + s.x * e - s.y * o,
2950
- y: this.y + s.x * o + s.y * e
2958
+ ].map((i) => ({
2959
+ x: this.x + i.x * e - i.y * o,
2960
+ y: this.y + i.x * o + i.y * e
2951
2961
  }));
2952
2962
  }
2953
2963
  /**
@@ -2955,8 +2965,8 @@ class pt extends Q {
2955
2965
  * Local coordinates are relative to this.x, this.y (the center of the visible area)
2956
2966
  */
2957
2967
  worldToLocal(t, e) {
2958
- const o = t - this.x, i = e - this.y, s = Math.cos(D.toRadiansInverse(this.rotation)), a = Math.sin(D.toRadiansInverse(this.rotation));
2959
- let n = o * s - i * a, h = o * a + i * s;
2968
+ const o = t - this.x, s = e - this.y, i = Math.cos(D.toRadiansInverse(this.rotation)), a = Math.sin(D.toRadiansInverse(this.rotation));
2969
+ let n = o * i - s * a, h = o * a + s * i;
2960
2970
  const l = this.transformData.flipHorizontal ? -1 : 1, c = this.transformData.flipVertical ? -1 : 1;
2961
2971
  return n *= l, h *= c, {
2962
2972
  x: n,
@@ -2969,9 +2979,9 @@ class pt extends Q {
2969
2979
  * Canvas transformations are applied in reverse: scale -> rotate -> translate
2970
2980
  */
2971
2981
  localToWorld(t, e) {
2972
- const o = this.transformData.flipHorizontal ? -1 : 1, i = this.transformData.flipVertical ? -1 : 1;
2973
- let s = t * o, a = e * i;
2974
- const n = Math.cos(D.toRadians(this.rotation)), h = Math.sin(D.toRadians(this.rotation)), l = s * n - a * h, c = s * h + a * n;
2982
+ const o = this.transformData.flipHorizontal ? -1 : 1, s = this.transformData.flipVertical ? -1 : 1;
2983
+ let i = t * o, a = e * s;
2984
+ const n = Math.cos(D.toRadians(this.rotation)), h = Math.sin(D.toRadians(this.rotation)), l = i * n - a * h, c = i * h + a * n;
2975
2985
  return {
2976
2986
  x: this.x + l,
2977
2987
  y: this.y + c
@@ -2986,29 +2996,29 @@ class pt extends Q {
2986
2996
  */
2987
2997
  hitTestCropHandle(t, e, o = 1) {
2988
2998
  if (!this.isCropping) return null;
2989
- const i = this.getCropBoxBounds();
2990
- if (!i) return null;
2991
- const s = this.worldToLocal(t, e), a = 1 / o, n = ce * a, h = de * a, l = ge * a, c = [
2992
- { x: i.x, y: i.y, anchor: "top-left" },
2993
- { x: i.x + i.width, y: i.y, anchor: "top-right" },
2994
- { x: i.x, y: i.y + i.height, anchor: "bottom-left" },
2995
- { x: i.x + i.width, y: i.y + i.height, anchor: "bottom-right" }
2999
+ const s = this.getCropBoxBounds();
3000
+ if (!s) return null;
3001
+ const i = this.worldToLocal(t, e), a = 1 / o, n = ce * a, h = de * a, l = ge * a, c = [
3002
+ { x: s.x, y: s.y, anchor: "top-left" },
3003
+ { x: s.x + s.width, y: s.y, anchor: "top-right" },
3004
+ { x: s.x, y: s.y + s.height, anchor: "bottom-left" },
3005
+ { x: s.x + s.width, y: s.y + s.height, anchor: "bottom-right" }
2996
3006
  ];
2997
3007
  for (const d of c) {
2998
- const f = s.x - d.x, u = s.y - d.y;
3008
+ const f = i.x - d.x, u = i.y - d.y;
2999
3009
  if (Math.sqrt(f * f + u * u) <= n) {
3000
3010
  const p = this.localToWorld(d.x, d.y);
3001
3011
  return { type: "corner", anchor: d.anchor, worldX: p.x, worldY: p.y };
3002
3012
  }
3003
3013
  }
3004
3014
  const g = [
3005
- { x: i.x + i.width / 2, y: i.y, anchor: "top", orientation: "horizontal" },
3006
- { x: i.x + i.width / 2, y: i.y + i.height, anchor: "bottom", orientation: "horizontal" },
3007
- { x: i.x, y: i.y + i.height / 2, anchor: "left", orientation: "vertical" },
3008
- { x: i.x + i.width, y: i.y + i.height / 2, anchor: "right", orientation: "vertical" }
3015
+ { x: s.x + s.width / 2, y: s.y, anchor: "top", orientation: "horizontal" },
3016
+ { x: s.x + s.width / 2, y: s.y + s.height, anchor: "bottom", orientation: "horizontal" },
3017
+ { x: s.x, y: s.y + s.height / 2, anchor: "left", orientation: "vertical" },
3018
+ { x: s.x + s.width, y: s.y + s.height / 2, anchor: "right", orientation: "vertical" }
3009
3019
  ];
3010
3020
  for (const d of g) {
3011
- const f = s.x - d.x, u = s.y - d.y;
3021
+ const f = i.x - d.x, u = i.y - d.y;
3012
3022
  let m, p;
3013
3023
  if (d.orientation === "horizontal" ? (m = h / 2, p = l / 2) : (m = l / 2, p = h / 2), Math.abs(f) <= m && Math.abs(u) <= p) {
3014
3024
  const y = this.localToWorld(d.x, d.y);
@@ -3025,8 +3035,8 @@ class pt extends Q {
3025
3035
  if (!this.isCropping) return !1;
3026
3036
  const o = this.getCropBoxBounds();
3027
3037
  if (!o) return !1;
3028
- const i = this.worldToLocal(t, e);
3029
- return i.x >= o.x && i.x <= o.x + o.width && i.y >= o.y && i.y <= o.y + o.height;
3038
+ const s = this.worldToLocal(t, e);
3039
+ return s.x >= o.x && s.x <= o.x + o.width && s.y >= o.y && s.y <= o.y + o.height;
3030
3040
  }
3031
3041
  /**
3032
3042
  * Update crop box (normalized 0-1 coordinates)
@@ -3036,46 +3046,46 @@ class pt extends Q {
3036
3046
  * @param {number} cropHeight - Normalized height (0-1)
3037
3047
  * @param {boolean} adjustPosition - Whether to adjust this.x, this.y to keep visual position stable (default: false)
3038
3048
  */
3039
- updateCrop(t, e, o, i, s = !1) {
3040
- let n = Math.max(0.1, Math.min(1, o)), h = Math.max(0.1, Math.min(1, i)), l = Math.max(0, Math.min(1 - n, t)), c = Math.max(0, Math.min(1 - h, e));
3049
+ updateCrop(t, e, o, s, i = !1) {
3050
+ let n = Math.max(0.1, Math.min(1, o)), h = Math.max(0.1, Math.min(1, s)), l = Math.max(0, Math.min(1 - n, t)), c = Math.max(0, Math.min(1 - h, e));
3041
3051
  l + n > 1 && (n = 1 - l), c + h > 1 && (h = 1 - c);
3042
3052
  let g = 0, d = 0;
3043
- if (s) {
3053
+ if (i) {
3044
3054
  const f = this.transformData.cropX * this.transformData.width + this.transformData.cropWidth * this.transformData.width / 2, u = this.transformData.cropY * this.transformData.height + this.transformData.cropHeight * this.transformData.height / 2, m = l * this.transformData.width + n * this.transformData.width / 2, p = c * this.transformData.height + h * this.transformData.height / 2, y = m - f, x = p - u, b = Math.cos(D.toRadians(this.rotation)), S = Math.sin(D.toRadians(this.rotation));
3045
3055
  g = y * b - x * S, d = y * S + x * b;
3046
3056
  }
3047
- this.transformData.cropX = l, this.transformData.cropY = c, this.transformData.cropWidth = n, this.transformData.cropHeight = h, s && (this.x += g, this.y += d);
3057
+ this.transformData.cropX = l, this.transformData.cropY = c, this.transformData.cropWidth = n, this.transformData.cropHeight = h, i && (this.x += g, this.y += d);
3048
3058
  }
3049
3059
  /**
3050
3060
  * Get the local position of the corner opposite to the given anchor
3051
3061
  * Corners are relative to frame center
3052
3062
  */
3053
3063
  getOppositeCornerLocalPosition(t, e, o) {
3054
- const i = e / 2, s = o / 2;
3064
+ const s = e / 2, i = o / 2;
3055
3065
  return {
3056
- "top-left": { x: i, y: s },
3066
+ "top-left": { x: s, y: i },
3057
3067
  // Opposite is bottom-right
3058
- "top-right": { x: -i, y: s },
3068
+ "top-right": { x: -s, y: i },
3059
3069
  // Opposite is bottom-left
3060
- "bottom-left": { x: i, y: -s },
3070
+ "bottom-left": { x: s, y: -i },
3061
3071
  // Opposite is top-right
3062
- "bottom-right": { x: -i, y: -s },
3072
+ "bottom-right": { x: -s, y: -i },
3063
3073
  // Opposite is top-left
3064
- top: { x: 0, y: s },
3074
+ top: { x: 0, y: i },
3065
3075
  // Opposite is bottom edge
3066
- bottom: { x: 0, y: -s },
3076
+ bottom: { x: 0, y: -i },
3067
3077
  // Opposite is top edge
3068
- left: { x: i, y: 0 },
3078
+ left: { x: s, y: 0 },
3069
3079
  // Opposite is right edge
3070
- right: { x: -i, y: 0 },
3080
+ right: { x: -s, y: 0 },
3071
3081
  // Opposite is left edge
3072
- "middle-top": { x: 0, y: s },
3082
+ "middle-top": { x: 0, y: i },
3073
3083
  // Opposite is bottom edge
3074
- "middle-bottom": { x: 0, y: -s },
3084
+ "middle-bottom": { x: 0, y: -i },
3075
3085
  // Opposite is top edge
3076
- "middle-left": { x: i, y: 0 },
3086
+ "middle-left": { x: s, y: 0 },
3077
3087
  // Opposite is right edge
3078
- "middle-right": { x: -i, y: 0 }
3088
+ "middle-right": { x: -s, y: 0 }
3079
3089
  // Opposite is left edge
3080
3090
  }[t];
3081
3091
  }
@@ -3084,7 +3094,7 @@ class pt extends Q {
3084
3094
  * In crop mode, this.x/y is the crop center, not the frame center
3085
3095
  */
3086
3096
  calculateFrameCenterFromCropCenter(t) {
3087
- const e = C(t).width * C(t).cropWidth, o = C(t).height * C(t).cropHeight, i = C(t).width / 2 - (C(t).cropX * C(t).width + e / 2), s = C(t).height / 2 - (C(t).cropY * C(t).height + o / 2), n = new R(t).localDeltaToWorld(i, s);
3097
+ const e = C(t).width * C(t).cropWidth, o = C(t).height * C(t).cropHeight, s = C(t).width / 2 - (C(t).cropX * C(t).width + e / 2), i = C(t).height / 2 - (C(t).cropY * C(t).height + o / 2), n = new R(t).localDeltaToWorld(s, i);
3088
3098
  return {
3089
3099
  x: t.x + n.dx,
3090
3100
  y: t.y + n.dy
@@ -3098,10 +3108,10 @@ class pt extends Q {
3098
3108
  t,
3099
3109
  C(e).width,
3100
3110
  C(e).height
3101
- ), i = this.calculateFrameCenterFromCropCenter(e), a = new R(e).localDeltaToWorld(o.x, o.y);
3111
+ ), s = this.calculateFrameCenterFromCropCenter(e), a = new R(e).localDeltaToWorld(o.x, o.y);
3102
3112
  return {
3103
- x: i.x + a.dx,
3104
- y: i.y + a.dy
3113
+ x: s.x + a.dx,
3114
+ y: s.y + a.dy
3105
3115
  };
3106
3116
  }
3107
3117
  /**
@@ -3109,15 +3119,15 @@ class pt extends Q {
3109
3119
  * The opposite corner from the anchor stays fixed in world space
3110
3120
  */
3111
3121
  calculateFrameCenterAfterResize(t, e, o) {
3112
- const i = this.getFixedCornerWorldPosition(e, o), s = C(o).width * t, a = s / this.imageAspectRatio, n = this.getOppositeCornerLocalPosition(e, s, a), l = new R({
3122
+ const s = this.getFixedCornerWorldPosition(e, o), i = C(o).width * t, a = i / this.imageAspectRatio, n = this.getOppositeCornerLocalPosition(e, i, a), l = new R({
3113
3123
  x: 0,
3114
3124
  // Will calculate frame center
3115
3125
  y: 0,
3116
3126
  rotation: o.rotation
3117
3127
  }).localDeltaToWorld(n.x, n.y);
3118
3128
  return {
3119
- x: i.x - l.dx,
3120
- y: i.y - l.dy
3129
+ x: s.x - l.dx,
3130
+ y: s.y - l.dy
3121
3131
  };
3122
3132
  }
3123
3133
  /**
@@ -3126,7 +3136,7 @@ class pt extends Q {
3126
3136
  * would be positioned within the frame after resize.
3127
3137
  */
3128
3138
  calculateCropStateAtScale(t, e, o) {
3129
- const i = C(o).width * t, s = i / this.imageAspectRatio, a = C(o).cropWidth * C(o).width, n = C(o).cropHeight * C(o).height, h = a / i, l = n / s, c = this.calculateFrameCenterAfterResize(t, e, o), g = {
3139
+ const s = C(o).width * t, i = s / this.imageAspectRatio, a = C(o).cropWidth * C(o).width, n = C(o).cropHeight * C(o).height, h = a / s, l = n / i, c = this.calculateFrameCenterAfterResize(t, e, o), g = {
3130
3140
  x: o.x,
3131
3141
  // In crop mode, this.x/y is the crop center
3132
3142
  y: o.y
@@ -3134,7 +3144,7 @@ class pt extends Q {
3134
3144
  x: c.x,
3135
3145
  y: c.y,
3136
3146
  rotation: o.rotation
3137
- }).worldDeltaToLocal(d, f), p = i / 2 + m.dx, y = s / 2 + m.dy, x = p / i - h / 2, b = y / s - l / 2;
3147
+ }).worldDeltaToLocal(d, f), p = s / 2 + m.dx, y = i / 2 + m.dy, x = p / s - h / 2, b = y / i - l / 2;
3138
3148
  return {
3139
3149
  cropX: x,
3140
3150
  cropY: b,
@@ -3146,20 +3156,20 @@ class pt extends Q {
3146
3156
  * Check if a given scale keeps crop within frame bounds
3147
3157
  */
3148
3158
  isScaleValidForCropBounds(t, e, o) {
3149
- const s = this.calculateCropStateAtScale(t, e, o);
3150
- if (s.cropWidth > 1 + 1e-4 || s.cropHeight > 1 + 1e-4)
3159
+ const i = this.calculateCropStateAtScale(t, e, o);
3160
+ if (i.cropWidth > 1 + 1e-4 || i.cropHeight > 1 + 1e-4)
3151
3161
  return !1;
3152
- const a = s.cropX, n = s.cropX + s.cropWidth, h = s.cropY, l = s.cropY + s.cropHeight;
3162
+ const a = i.cropX, n = i.cropX + i.cropWidth, h = i.cropY, l = i.cropY + i.cropHeight;
3153
3163
  return a >= -1e-4 && h >= -1e-4 && n <= 1 + 1e-4 && l <= 1 + 1e-4;
3154
3164
  }
3155
3165
  /**
3156
3166
  * Calculate minimum scale that keeps crop within frame bounds
3157
3167
  * Uses binary search to find the largest scale >= proposedScale that satisfies constraints
3158
3168
  */
3159
- calculateMinScaleForCropBounds(t, e, o, i) {
3169
+ calculateMinScaleForCropBounds(t, e, o, s) {
3160
3170
  if (this.isScaleValidForCropBounds(o, t, e))
3161
3171
  return o;
3162
- let n = o, h = i;
3172
+ let n = o, h = s;
3163
3173
  for (let l = 0; l < 20; l++) {
3164
3174
  const c = (n + h) / 2;
3165
3175
  if (this.isScaleValidForCropBounds(c, t, e) ? h = c : n = c, Math.abs(h - n) < 1e-4)
@@ -3172,15 +3182,15 @@ class pt extends Q {
3172
3182
  */
3173
3183
  remapAnchorForFlips(t, e) {
3174
3184
  let o = t;
3175
- const i = C(e).flipHorizontal, s = C(e).flipVertical;
3176
- return i && (o.includes("left") ? o = o.replace("left", "right") : o.includes("right") && (o = o.replace("right", "left"))), s && (o.includes("top") ? o = o.replace("top", "bottom") : o.includes("bottom") && (o = o.replace("bottom", "top"))), o;
3185
+ const s = C(e).flipHorizontal, i = C(e).flipVertical;
3186
+ return s && (o.includes("left") ? o = o.replace("left", "right") : o.includes("right") && (o = o.replace("right", "left"))), i && (o.includes("top") ? o = o.replace("top", "bottom") : o.includes("bottom") && (o = o.replace("bottom", "top"))), o;
3177
3187
  }
3178
3188
  /**
3179
3189
  * Clone this element
3180
3190
  */
3181
3191
  clone() {
3182
- const t = this.toJSON(), { imageUrl: e, ...o } = t, i = new pt(o);
3183
- return i.imageUrl = this.imageUrl, i.imageElement = this.imageElement, i.imageLoaded = this.imageLoaded, i.imageAspectRatio = this.imageAspectRatio, i.isCropping = this.isCropping, i.onLoadCallback = this.onLoadCallback, i.isSvg = this.isSvg, i.imageLoadState = this.imageLoadState, i.imageLoadError = this.imageLoadError, i.preserveDimensions = this.preserveDimensions, i;
3192
+ const t = this.toJSON(), { imageUrl: e, ...o } = t, s = new pt(o);
3193
+ return s.imageUrl = this.imageUrl, s.imageElement = this.imageElement, s.imageLoaded = this.imageLoaded, s.imageAspectRatio = this.imageAspectRatio, s.isCropping = this.isCropping, s.onLoadCallback = this.onLoadCallback, s.isSvg = this.isSvg, s.imageLoadState = this.imageLoadState, s.imageLoadError = this.imageLoadError, s.preserveDimensions = this.preserveDimensions, s;
3184
3194
  }
3185
3195
  /**
3186
3196
  * Serialize to JSON
@@ -3200,6 +3210,8 @@ class pt extends Q {
3200
3210
  // Explicitly include to ensure number type
3201
3211
  imageUrl: this.imageUrl,
3202
3212
  imageAspectRatio: this.imageAspectRatio,
3213
+ preserveDimensions: this.preserveDimensions,
3214
+ // dimension lock for cover crop must survive save→load
3203
3215
  transformData: { ...this.transformData }
3204
3216
  };
3205
3217
  }
@@ -3236,7 +3248,7 @@ function Te() {
3236
3248
  }
3237
3249
  class P {
3238
3250
  constructor(t = []) {
3239
- this.spans = t.length > 0 ? t : [{ text: "", style: {} }], this.normalize();
3251
+ this.spans = t.length > 0 ? t.map((e) => ({ ...e, style: { ...e.style } })) : [{ text: "", style: {} }], this.normalize();
3240
3252
  }
3241
3253
  /**
3242
3254
  * Create RichText from plain text string (no special formatting)
@@ -3281,31 +3293,31 @@ class P {
3281
3293
  applyStyle(t, e, o) {
3282
3294
  if (t >= e || t < 0 || e > this.getLength())
3283
3295
  return;
3284
- const i = [];
3285
- let s = 0;
3296
+ const s = [];
3297
+ let i = 0;
3286
3298
  for (const a of this.spans) {
3287
- const n = s, h = s + a.text.length;
3299
+ const n = i, h = i + a.text.length;
3288
3300
  if (h <= t) {
3289
- i.push(a), s = h;
3301
+ s.push(a), i = h;
3290
3302
  continue;
3291
3303
  }
3292
3304
  if (n >= e) {
3293
- i.push(a), s = h;
3305
+ s.push(a), i = h;
3294
3306
  continue;
3295
3307
  }
3296
3308
  const l = Math.max(t, n), c = Math.min(e, h);
3297
- l > n && i.push({
3309
+ l > n && s.push({
3298
3310
  text: a.text.substring(0, l - n),
3299
3311
  style: a.style
3300
- }), i.push({
3312
+ }), s.push({
3301
3313
  text: a.text.substring(l - n, c - n),
3302
3314
  style: { ...a.style, ...o }
3303
- }), c < h && i.push({
3315
+ }), c < h && s.push({
3304
3316
  text: a.text.substring(c - n),
3305
3317
  style: a.style
3306
- }), s = h;
3318
+ }), i = h;
3307
3319
  }
3308
- this.spans = i, this.normalize();
3320
+ this.spans = s, this.normalize();
3309
3321
  }
3310
3322
  /**
3311
3323
  * Insert text at a specific position with a given style
@@ -3315,24 +3327,24 @@ class P {
3315
3327
  */
3316
3328
  insert(t, e, o) {
3317
3329
  if (e.length === 0) return;
3318
- const i = [];
3319
- let s = 0;
3330
+ const s = [];
3331
+ let i = 0;
3320
3332
  for (const a of this.spans) {
3321
- const n = s, h = s + a.text.length;
3322
- if (t <= n && i.length === 0 && i.push({ text: e, style: o }), t > n && t <= h) {
3333
+ const n = i, h = i + a.text.length;
3334
+ if (t <= n && s.length === 0 && s.push({ text: e, style: o }), t > n && t <= h) {
3323
3335
  const l = t - n;
3324
- i.push({
3336
+ s.push({
3325
3337
  text: a.text.substring(0, l),
3326
3338
  style: a.style
3327
- }), i.push({ text: e, style: o }), i.push({
3339
+ }), s.push({ text: e, style: o }), s.push({
3328
3340
  text: a.text.substring(l),
3329
3341
  style: a.style
3330
- }), s = h;
3342
+ }), i = h;
3331
3343
  continue;
3332
3344
  }
3333
- i.push(a), s = h;
3345
+ s.push(a), i = h;
3334
3346
  }
3335
- t >= this.getLength() && !i.some((a) => a.text === e) && i.push({ text: e, style: o }), this.spans = i, this.normalize();
3347
+ t >= this.getLength() && !s.some((a) => a.text === e) && s.push({ text: e, style: o }), this.spans = s, this.normalize();
3336
3348
  }
3337
3349
  /**
3338
3350
  * Delete text in a character range
@@ -3343,28 +3355,28 @@ class P {
3343
3355
  const o = this.getLength();
3344
3356
  if (t = Math.max(0, Math.min(t, o)), e = Math.max(0, Math.min(e, o)), t >= e)
3345
3357
  return;
3346
- const i = [];
3347
- let s = 0;
3358
+ const s = [];
3359
+ let i = 0;
3348
3360
  for (const a of this.spans) {
3349
- const n = s, h = s + a.text.length;
3361
+ const n = i, h = i + a.text.length;
3350
3362
  if (h <= t) {
3351
- i.push(a), s = h;
3363
+ s.push(a), i = h;
3352
3364
  continue;
3353
3365
  }
3354
3366
  if (n >= e) {
3355
- i.push(a), s = h;
3367
+ s.push(a), i = h;
3356
3368
  continue;
3357
3369
  }
3358
3370
  const l = Math.max(t, n), c = Math.min(e, h);
3359
- l > n && i.push({
3371
+ l > n && s.push({
3360
3372
  text: a.text.substring(0, l - n),
3361
3373
  style: a.style
3362
- }), c < h && i.push({
3374
+ }), c < h && s.push({
3363
3375
  text: a.text.substring(c - n),
3364
3376
  style: a.style
3365
- }), s = h;
3377
+ }), i = h;
3366
3378
  }
3367
- this.spans = i.length > 0 ? i : [{ text: "", style: {} }], this.normalize();
3379
+ this.spans = s.length > 0 ? s : [{ text: "", style: {} }], this.normalize();
3368
3380
  }
3369
3381
  /**
3370
3382
  * Normalize spans by:
@@ -3381,11 +3393,11 @@ class P {
3381
3393
  const t = [];
3382
3394
  let e = this.spans[0];
3383
3395
  for (let o = 1; o < this.spans.length; o++) {
3384
- const i = this.spans[o];
3385
- this.stylesEqual(e.style, i.style) ? e = {
3386
- text: e.text + i.text,
3396
+ const s = this.spans[o];
3397
+ this.stylesEqual(e.style, s.style) ? e = {
3398
+ text: e.text + s.text,
3387
3399
  style: e.style
3388
- } : (t.push(e), e = i);
3400
+ } : (t.push(e), e = s);
3389
3401
  }
3390
3402
  t.push(e), this.spans = t;
3391
3403
  }
@@ -3421,7 +3433,7 @@ class P {
3421
3433
  * Serialize to JSON
3422
3434
  */
3423
3435
  toJSON() {
3424
- return { spans: this.spans };
3436
+ return { spans: this.spans.map((t) => ({ ...t, style: { ...t.style } })) };
3425
3437
  }
3426
3438
  /**
3427
3439
  * Deserialize from JSON
@@ -3513,8 +3525,8 @@ class q extends Q {
3513
3525
  * handled by SelectionRenderer and HoverRenderer.
3514
3526
  */
3515
3527
  render(t, e = !1, o = !1) {
3516
- const i = t.globalAlpha;
3517
- this.opacity !== void 0 && this.opacity !== 1 && (t.globalAlpha = this.opacity), gt(this.transformType)(t, this.toJSON()), t.globalAlpha = i;
3528
+ const s = t.globalAlpha;
3529
+ this.opacity !== void 0 && this.opacity !== 1 && (t.globalAlpha = this.opacity), gt(this.transformType)(t, this.toJSON()), t.globalAlpha = s;
3518
3530
  }
3519
3531
  /**
3520
3532
  * Serialize to JSON
@@ -3590,8 +3602,8 @@ class q extends Q {
3590
3602
  * Apply character-level formatting to a text range
3591
3603
  */
3592
3604
  applyFormatting(t, e, o) {
3593
- const i = this.getRichText();
3594
- i.applyStyle(t, e, o), this.text = i.getText();
3605
+ const s = this.getRichText();
3606
+ s.applyStyle(t, e, o), this.text = s.getText();
3595
3607
  }
3596
3608
  /**
3597
3609
  * Update font size
@@ -3607,15 +3619,15 @@ class q extends Q {
3607
3619
  const e = this.color;
3608
3620
  if (this.color = t, this.richText)
3609
3621
  for (let o = 0; o < this.richText.spans.length; o++) {
3610
- const i = this.richText.spans[o];
3611
- (i.style.color === void 0 || i.style.color === e) && (i.style.color = t);
3622
+ const s = this.richText.spans[o];
3623
+ (s.style.color === void 0 || s.style.color === e) && (s.style.color = t);
3612
3624
  }
3613
3625
  }
3614
3626
  /**
3615
3627
  * Handle resize transform
3616
3628
  * Must be implemented by subclasses
3617
3629
  */
3618
- resize(t, e, o, i) {
3630
+ resize(t, e, o, s) {
3619
3631
  throw new Error("resize() must be implemented by subclass");
3620
3632
  }
3621
3633
  /**
@@ -3643,19 +3655,19 @@ function yt() {
3643
3655
  return ht;
3644
3656
  }
3645
3657
  function at(r, t, e = !1, o = !1) {
3646
- const i = [];
3647
- return o && i.push("italic"), e && i.push("bold"), i.push(`${r}px`), i.push(t), i.join(" ");
3658
+ const s = [];
3659
+ return o && s.push("italic"), e && s.push("bold"), s.push(`${r}px`), s.push(t), s.join(" ");
3648
3660
  }
3649
- function vt(r, t, e, o, i = !1, s = !1, a, n = !1) {
3661
+ function vt(r, t, e, o, s = !1, i = !1, a, n = !1) {
3650
3662
  const l = yt().getContext("2d");
3651
- if (l.font = at(e, o, i, s), r.trim().length === 0)
3663
+ if (l.font = at(e, o, s, i), r.trim().length === 0)
3652
3664
  return [r];
3653
3665
  if (r.includes(`
3654
3666
  `)) {
3655
3667
  const M = r.split(`
3656
3668
  `), k = [];
3657
3669
  for (let I = 0; I < M.length; I++) {
3658
- const O = M[I], B = vt(O, t, e, o, i, s, void 0, n);
3670
+ const O = M[I], B = vt(O, t, e, o, s, i, void 0, n);
3659
3671
  k.push(...B);
3660
3672
  }
3661
3673
  return k;
@@ -3705,25 +3717,25 @@ function vt(r, t, e, o, i = !1, s = !1, a, n = !1) {
3705
3717
  }
3706
3718
  return w;
3707
3719
  }
3708
- function Ot(r, t, e, o = !1, i = !1) {
3720
+ function Ot(r, t, e, o = !1, s = !1) {
3709
3721
  const a = yt().getContext("2d");
3710
- return a.font = at(t, e, o, i), a.measureText(r).width;
3722
+ return a.font = at(t, e, o, s), a.measureText(r).width;
3711
3723
  }
3712
3724
  function Tt(r, t, e = !1, o = !1) {
3713
- const s = yt().getContext("2d");
3714
- s.font = at(r, t, e, o);
3715
- const n = s.measureText("ÁÉÍgjpqy"), h = n.actualBoundingBoxAscent || r * 0.8, l = n.actualBoundingBoxDescent || r * 0.2, c = h + l;
3725
+ const i = yt().getContext("2d");
3726
+ i.font = at(r, t, e, o);
3727
+ const n = i.measureText("ÁÉÍgjpqy"), h = n.actualBoundingBoxAscent || r * 0.8, l = n.actualBoundingBoxDescent || r * 0.2, c = h + l;
3716
3728
  return { ascent: h, descent: l, height: c };
3717
3729
  }
3718
- function Bt(r, t, e, o, i = !1, s = !1, a, n = !1) {
3719
- const h = vt(r, t, e, o, i, s, a, n), l = r.includes(`
3730
+ function Bt(r, t, e, o, s = !1, i = !1, a, n = !1) {
3731
+ const h = vt(r, t, e, o, s, i, a, n), l = r.includes(`
3720
3732
  `), c = h.map((x, b) => ({
3721
3733
  isParagraphStart: !l && b === 0,
3722
3734
  isParagraphEnd: !l && b === h.length - 1
3723
3735
  })), d = yt().getContext("2d");
3724
- d.font = at(e, o, i, s);
3736
+ d.font = at(e, o, s, i);
3725
3737
  let f = 0;
3726
- const u = Tt(e, o, i, s);
3738
+ const u = Tt(e, o, s, i);
3727
3739
  let m = 0;
3728
3740
  h.forEach((x, b) => {
3729
3741
  const S = c[b].isParagraphStart, v = c[b].isParagraphEnd;
@@ -3769,7 +3781,7 @@ function ve() {
3769
3781
  return lt;
3770
3782
  }
3771
3783
  function Fe(r, t, e) {
3772
- const o = ve(), i = [], s = (p, y) => {
3784
+ const o = ve(), s = [], i = (p, y) => {
3773
3785
  const x = y.fontSize || e.fontSize, b = y.fontFamily || e.fontFamily, S = y.bold !== void 0 ? y.bold : e.bold || !1, v = y.italic !== void 0 ? y.italic : e.italic || !1;
3774
3786
  return o.font = at(x, b, S, v), o.measureText(p).width;
3775
3787
  }, a = (p, y) => p.fontSize === y.fontSize && p.fontFamily === y.fontFamily && p.color === y.color && p.bold === y.bold && p.italic === y.italic && p.underline === y.underline && p.strikethrough === y.strikethrough, n = [];
@@ -3791,7 +3803,7 @@ function Fe(r, t, e) {
3791
3803
  g.length > 0 && c.push({ text: g, startIdx: d, endIdx: h.length - 1 });
3792
3804
  let f = [], u = 0;
3793
3805
  const m = () => {
3794
- f.length > 0 && (i.push(f), f = [], u = 0);
3806
+ f.length > 0 && (s.push(f), f = [], u = 0);
3795
3807
  };
3796
3808
  return c.forEach((p, y) => {
3797
3809
  const x = [];
@@ -3801,7 +3813,7 @@ function Fe(r, t, e) {
3801
3813
  T !== b ? (x.push({ text: S, style: n[b].style }), S = h[w], b = T) : S += h[w];
3802
3814
  }
3803
3815
  S.length > 0 && x.push({ text: S, style: n[b].style });
3804
- const v = x.reduce((w, T) => w + s(T.text, T.style), 0);
3816
+ const v = x.reduce((w, T) => w + i(T.text, T.style), 0);
3805
3817
  if (p.text === " ") {
3806
3818
  if (f.length > 0) {
3807
3819
  const w = f[f.length - 1];
@@ -3815,7 +3827,7 @@ function Fe(r, t, e) {
3815
3827
  const T = Array.from(w.text);
3816
3828
  let F = "";
3817
3829
  for (const A of T) {
3818
- const M = s(A, w.style);
3830
+ const M = i(A, w.style);
3819
3831
  if (u + M > t && u > 0) {
3820
3832
  if (F.length > 0) {
3821
3833
  if (f.length > 0) {
@@ -3844,27 +3856,27 @@ function Fe(r, t, e) {
3844
3856
  } else
3845
3857
  f.push({ ...w });
3846
3858
  }), u += v;
3847
- }), m(), i.length === 0 && i.push([]), i;
3859
+ }), m(), s.length === 0 && s.push([]), s;
3848
3860
  }
3849
3861
  function Me(r) {
3850
3862
  const t = [];
3851
3863
  let e = [];
3852
3864
  return r.spans.forEach((o) => {
3853
- const i = o.text.split(`
3865
+ const s = o.text.split(`
3854
3866
  `);
3855
- i.forEach((s, a) => {
3856
- s.length > 0 && e.push({ text: s, style: o.style }), a < i.length - 1 && (t.push(e), e = []);
3867
+ s.forEach((i, a) => {
3868
+ i.length > 0 && e.push({ text: i, style: o.style }), a < s.length - 1 && (t.push(e), e = []);
3857
3869
  });
3858
3870
  }), e.length > 0 && t.push(e), t.length === 0 && t.push([]), t;
3859
3871
  }
3860
- function it(r) {
3872
+ function st(r) {
3861
3873
  return typeof r.width == "number" ? r.width : void 0;
3862
3874
  }
3863
3875
  function Ut(r, t) {
3864
3876
  r.width = t;
3865
3877
  }
3866
3878
  function Ae(r, t, e) {
3867
- const o = e.transformData, i = it(o), s = i !== void 0 ? i : e.width ?? 0, a = t / s, n = e.fontSize ?? r.fontSize, h = n * a;
3879
+ const o = e.transformData, s = st(o), i = s !== void 0 ? s : e.width ?? 0, a = t / i, n = e.fontSize ?? r.fontSize, h = n * a;
3868
3880
  let l;
3869
3881
  if (h < 16 ? l = Math.round(h) : l = Math.round(h * 2) / 2, r.setFontSize(l), e.richText && e.richText instanceof P && typeof r.setRichText == "function") {
3870
3882
  const f = e.richText.clone();
@@ -3876,8 +3888,8 @@ function Ae(r, t, e) {
3876
3888
  r.setRichText(f);
3877
3889
  }
3878
3890
  const c = r.transformData;
3879
- if (it(c) !== void 0 && i !== void 0) {
3880
- const d = n > 0 ? l / n : a, f = i * d;
3891
+ if (st(c) !== void 0 && s !== void 0) {
3892
+ const d = n > 0 ? l / n : a, f = s * d;
3881
3893
  Ut(c, Math.max(20, Math.ceil(f)));
3882
3894
  }
3883
3895
  }
@@ -3885,16 +3897,16 @@ function De(r, t, e, o) {
3885
3897
  if (t !== "middle-left" && t !== "middle-right")
3886
3898
  return;
3887
3899
  r.fontSize = o.fontSize ?? r.fontSize;
3888
- const i = r.transformData;
3889
- if (it(i) !== void 0) {
3890
- Ut(i, Math.max(Yt, e));
3891
- const a = D.toRadiansInverse(r.rotation), n = Math.cos(a), h = Math.sin(a), l = o.transformData, g = it(l) ?? o.width ?? 0, f = (it(i) ?? 0) - g;
3900
+ const s = r.transformData;
3901
+ if (st(s) !== void 0) {
3902
+ Ut(s, Math.max(Yt, e));
3903
+ const a = D.toRadiansInverse(r.rotation), n = Math.cos(a), h = Math.sin(a), l = o.transformData, g = st(l) ?? o.width ?? 0, f = (st(s) ?? 0) - g;
3892
3904
  t === "middle-left" ? (r.x = o.x - f / 2 * n, r.y = o.y - f / 2 * h) : t === "middle-right" && (r.x = o.x + f / 2 * n, r.y = o.y + f / 2 * h);
3893
3905
  }
3894
3906
  }
3895
- function Gt(r, t, e, o, i) {
3896
- const s = t.includes("top") || t.includes("bottom"), a = t.includes("middle");
3897
- s ? Ae(r, e, i) : a && De(r, t, e, i);
3907
+ function Gt(r, t, e, o, s) {
3908
+ const i = t.includes("top") || t.includes("bottom"), a = t.includes("middle");
3909
+ i ? Ae(r, e, s) : a && De(r, t, e, s);
3898
3910
  }
3899
3911
  class Ie extends q {
3900
3912
  // Temporary property used during resize operations only
@@ -3915,7 +3927,7 @@ class Ie extends q {
3915
3927
  * Returns the total height based on the tallest font in each line
3916
3928
  */
3917
3929
  calculateRichTextHeight() {
3918
- const t = this.getRichText(), e = this.transformData.width - j * 2, o = Me(t), i = [];
3930
+ const t = this.getRichText(), e = this.transformData.width - j * 2, o = Me(t), s = [];
3919
3931
  if (o.forEach((h) => {
3920
3932
  Fe(h, e, {
3921
3933
  fontSize: this.fontSize,
@@ -3923,22 +3935,22 @@ class Ie extends q {
3923
3935
  bold: this.bold,
3924
3936
  italic: this.italic
3925
3937
  }).forEach((c) => {
3926
- i.push(c);
3938
+ s.push(c);
3927
3939
  });
3928
- }), i.length === 0)
3940
+ }), s.length === 0)
3929
3941
  return 0;
3930
- let s = 0, a = 0;
3931
- i.forEach((h) => {
3942
+ let i = 0, a = 0;
3943
+ s.forEach((h) => {
3932
3944
  h.forEach((l) => {
3933
3945
  const c = l.style.fontSize !== void 0 ? l.style.fontSize : this.fontSize, g = l.style.fontFamily !== void 0 ? l.style.fontFamily : this.fontFamily, d = l.style.bold !== void 0 ? l.style.bold : this.bold, f = l.style.italic !== void 0 ? l.style.italic : this.italic, u = Tt(c, g, d, f);
3934
- s = Math.max(s, u.height), a = Math.max(a, u.ascent);
3946
+ i = Math.max(i, u.height), a = Math.max(a, u.ascent);
3935
3947
  });
3936
3948
  });
3937
3949
  const n = this.fontSize * Xt;
3938
- if (i.length === 1)
3939
- return s;
3950
+ if (s.length === 1)
3951
+ return i;
3940
3952
  {
3941
- const h = Tt(this.fontSize, this.fontFamily, this.bold, this.italic), l = (i.length - 1) * n + h.height, c = Math.max(0, a - h.ascent), g = Math.max(0, s - a - (h.height - h.ascent));
3953
+ const h = Tt(this.fontSize, this.fontFamily, this.bold, this.italic), l = (s.length - 1) * n + h.height, c = Math.max(0, a - h.ascent), g = Math.max(0, i - a - (h.height - h.ascent));
3942
3954
  return l + c + g;
3943
3955
  }
3944
3956
  }
@@ -4023,13 +4035,13 @@ class Ie extends q {
4023
4035
  */
4024
4036
  render(t, e = !1, o = !1) {
4025
4037
  var n;
4026
- const i = this.opacity ?? 1, s = !!((n = this.stroke) != null && n.enabled);
4027
- if (i < 1 && s) {
4028
- this.renderWithOffscreen(t, i);
4038
+ const s = this.opacity ?? 1, i = !!((n = this.stroke) != null && n.enabled);
4039
+ if (s < 1 && i) {
4040
+ this.renderWithOffscreen(t, s);
4029
4041
  return;
4030
4042
  }
4031
4043
  const a = t.globalAlpha;
4032
- i !== 1 && (t.globalAlpha = i), gt("custom")(t, this.toJSON()), t.globalAlpha = a;
4044
+ s !== 1 && (t.globalAlpha = s), gt("custom")(t, this.toJSON()), t.globalAlpha = a;
4033
4045
  }
4034
4046
  /**
4035
4047
  * Render stroke+fill to an offscreen canvas at full opacity, then composite
@@ -4037,7 +4049,7 @@ class Ie extends q {
4037
4049
  */
4038
4050
  renderWithOffscreen(t, e) {
4039
4051
  var d;
4040
- const i = (((d = this.stroke) == null ? void 0 : d.width) || 0) + 20, s = this.getVisualBoundingBox(), a = Math.ceil(s.width + i * 2), n = Math.ceil(s.height + i * 2), h = document.createElement("canvas");
4052
+ const s = (((d = this.stroke) == null ? void 0 : d.width) || 0) + 20, i = this.getVisualBoundingBox(), a = Math.ceil(i.width + s * 2), n = Math.ceil(i.height + s * 2), h = document.createElement("canvas");
4041
4053
  h.width = a, h.height = n;
4042
4054
  const l = h.getContext("2d");
4043
4055
  if (!l) {
@@ -4045,7 +4057,7 @@ class Ie extends q {
4045
4057
  t.globalAlpha = e, gt("custom")(t, this.toJSON()), t.globalAlpha = f;
4046
4058
  return;
4047
4059
  }
4048
- const c = s.x + s.width / 2, g = s.y + s.height / 2;
4060
+ const c = i.x + i.width / 2, g = i.y + i.height / 2;
4049
4061
  l.translate(a / 2 - c, n / 2 - g), gt("custom")(l, this.toJSON()), t.save(), t.globalAlpha = e, t.drawImage(h, c - a / 2, g - n / 2), t.restore();
4050
4062
  }
4051
4063
  /**
@@ -4060,8 +4072,8 @@ class Ie extends q {
4060
4072
  * Corner handles: uniform scale (fontSize and width both change) - line count locked
4061
4073
  * Side handles: only width changes - text re-wraps naturally
4062
4074
  */
4063
- resize(t, e, o, i) {
4064
- if (t === "top-left" || t === "top-right" || t === "bottom-left" || t === "bottom-right" || (this._lockedLineCount = void 0), Gt(this, t, e, o, i), this._lockedLineCount !== void 0 && this._lockedLineCount > 0) {
4075
+ resize(t, e, o, s) {
4076
+ if (t === "top-left" || t === "top-right" || t === "bottom-left" || t === "bottom-right" || (this._lockedLineCount = void 0), Gt(this, t, e, o, s), this._lockedLineCount !== void 0 && this._lockedLineCount > 0) {
4065
4077
  const n = Ot(this.text, this.fontSize, this.fontFamily, this.bold, this.italic) / this._lockedLineCount + j * 2;
4066
4078
  this.transformData.width < n && (this.transformData.width = Math.ceil(n));
4067
4079
  }
@@ -4100,32 +4112,33 @@ class Ie extends q {
4100
4112
  transformType: "custom",
4101
4113
  transformData: {
4102
4114
  type: "custom",
4103
- controlPoints: this.transformData.controlPoints,
4115
+ // Copy point objects so serialized output never aliases the live array
4116
+ controlPoints: this.transformData.controlPoints.map((e) => ({ ...e })),
4104
4117
  width: this.transformData.width
4105
4118
  }
4106
4119
  };
4107
4120
  }
4108
4121
  }
4109
4122
  function ke(r, t, e, o) {
4110
- const i = D.toRadians(o), s = Math.cos(i), a = Math.sin(i);
4123
+ const s = D.toRadians(o), i = Math.cos(s), a = Math.sin(s);
4111
4124
  let n = 0, h = 0;
4112
4125
  e === "top-left" ? (n = r.width, h = r.height) : e === "top-right" ? (n = 0, h = r.height) : e === "bottom-left" ? (n = r.width, h = 0) : e === "bottom-right" && (n = 0, h = 0);
4113
- const l = r.x + (n * s - h * a), c = r.y + (n * a + h * s);
4126
+ const l = r.x + (n * i - h * a), c = r.y + (n * a + h * i);
4114
4127
  let g = 0, d = 0;
4115
4128
  e === "top-left" ? (g = t.width, d = t.height) : e === "top-right" ? (g = 0, d = t.height) : e === "bottom-left" ? (g = t.width, d = 0) : e === "bottom-right" && (g = 0, d = 0);
4116
- const f = l - (g * s - d * a), u = c - (g * a + d * s);
4129
+ const f = l - (g * i - d * a), u = c - (g * a + d * i);
4117
4130
  return { x: f, y: u };
4118
4131
  }
4119
4132
  function No(r, t, e, o = 1) {
4120
- const i = r.width / 2, s = r.height + le / o, a = r.x + i, n = r.y + s, h = D.toRadians(t), l = Math.cos(h), c = Math.sin(h), g = a - e.x, d = n - e.y, f = g * l - d * c, u = g * c + d * l;
4133
+ const s = r.width / 2, i = r.height + le / o, a = r.x + s, n = r.y + i, h = D.toRadians(t), l = Math.cos(h), c = Math.sin(h), g = a - e.x, d = n - e.y, f = g * l - d * c, u = g * c + d * l;
4121
4134
  return {
4122
4135
  x: e.x + f,
4123
4136
  y: e.y + u
4124
4137
  };
4125
4138
  }
4126
4139
  function Uo(r, t, e) {
4127
- const o = D.toRadians(t), i = Math.cos(o), s = Math.sin(o), a = (c, g) => {
4128
- const d = r.x + c, f = r.y + g, u = d - e.x, m = f - e.y, p = u * i - m * s, y = u * s + m * i;
4140
+ const o = D.toRadians(t), s = Math.cos(o), i = Math.sin(o), a = (c, g) => {
4141
+ const d = r.x + c, f = r.y + g, u = d - e.x, m = f - e.y, p = u * s - m * i, y = u * i + m * s;
4129
4142
  return {
4130
4143
  x: e.x + p,
4131
4144
  y: e.y + y
@@ -4160,16 +4173,16 @@ function Uo(r, t, e) {
4160
4173
  l("edge", "middle-bottom", n / 2, h)
4161
4174
  ];
4162
4175
  }
4163
- function Go(r, t, e, o, i) {
4164
- const s = r - e, a = t - o;
4165
- return s * s + a * a <= i * i;
4176
+ function Go(r, t, e, o, s) {
4177
+ const i = r - e, a = t - o;
4178
+ return i * i + a * a <= s * s;
4166
4179
  }
4167
4180
  function $o(r, t, e, o) {
4168
- const i = D.toRadiansInverse(o), s = Math.cos(i), a = Math.sin(i), n = r - e.x, h = t - e.y, l = n * s - h * a, c = n * a + h * s;
4181
+ const s = D.toRadiansInverse(o), i = Math.cos(s), a = Math.sin(s), n = r - e.x, h = t - e.y, l = n * i - h * a, c = n * a + h * i;
4169
4182
  return l >= 0 && l <= e.width && c >= 0 && c <= e.height;
4170
4183
  }
4171
- function tt(r, t, e = "Arial", o = !1, i = !1) {
4172
- const a = document.createElement("canvas").getContext("2d"), n = o ? "bold" : "normal", h = i ? "italic" : "normal";
4184
+ function tt(r, t, e = "Arial", o = !1, s = !1) {
4185
+ const a = document.createElement("canvas").getContext("2d"), n = o ? "bold" : "normal", h = s ? "italic" : "normal";
4173
4186
  return a.font = `${h} ${n} ${t}px ${e}`, a.measureText(r).width;
4174
4187
  }
4175
4188
  function Vo(r) {
@@ -4184,11 +4197,11 @@ function Jo(r, t, e, o) {
4184
4197
  function qo(r, t, e) {
4185
4198
  return Math.abs(r - t) <= e;
4186
4199
  }
4187
- function Ee(r, t, e, o, i, s = 0, a = "") {
4200
+ function Ee(r, t, e, o, s, i = 0, a = "") {
4188
4201
  const n = r - e, h = t - o;
4189
4202
  let l = Math.atan2(h, n) * (180 / Math.PI);
4190
- if (l = (l % 360 + 360) % 360, i === "corner") {
4191
- if (Math.abs(s) < 0.1) {
4203
+ if (l = (l % 360 + 360) % 360, s === "corner") {
4204
+ if (Math.abs(i) < 0.1) {
4192
4205
  if (a === "top-left" || a === "bottom-right")
4193
4206
  return "nwse-resize";
4194
4207
  if (a === "top-right" || a === "bottom-left")
@@ -4209,7 +4222,7 @@ function Oe(r) {
4209
4222
  }
4210
4223
  function jo(r, t, e = []) {
4211
4224
  const o = Oe(r);
4212
- r.lineWidth = o > 0 ? t / o : t, e.length > 0 && r.setLineDash(o > 0 ? e.map((i) => i / o) : e);
4225
+ r.lineWidth = o > 0 ? t / o : t, e.length > 0 && r.setLineDash(o > 0 ? e.map((s) => s / o) : e);
4213
4226
  }
4214
4227
  class Be extends q {
4215
4228
  constructor(t = {}) {
@@ -4241,11 +4254,11 @@ class Be extends q {
4241
4254
  * For circular text, calculate the arc bounds where text actually appears
4242
4255
  */
4243
4256
  getVisualBoundingBox() {
4244
- const t = this.transformData.radius * this.transformData.scale, e = this.fontSize * this.transformData.scale, i = tt(this.text, e, this.fontFamily, this.bold, this.italic) / t, s = -Math.PI / 2 - i / 2, a = -Math.PI / 2 + i / 2, n = t > e / 2 ? t - e / 2 : t * 0.1, h = t + e / 2;
4257
+ const t = this.transformData.radius * this.transformData.scale, e = this.fontSize * this.transformData.scale, s = tt(this.text, e, this.fontFamily, this.bold, this.italic) / t, i = -Math.PI / 2 - s / 2, a = -Math.PI / 2 + s / 2, n = t > e / 2 ? t - e / 2 : t * 0.1, h = t + e / 2;
4245
4258
  let l = 1 / 0, c = -1 / 0, g = 1 / 0, d = -1 / 0;
4246
4259
  const f = 10;
4247
4260
  for (let u = 0; u <= f; u++) {
4248
- const m = s + (a - s) * (u / f), p = this.x + Math.cos(m) * n, y = this.y + Math.sin(m) * n, x = this.x + Math.cos(m) * h, b = this.y + Math.sin(m) * h;
4261
+ const m = i + (a - i) * (u / f), p = this.x + Math.cos(m) * n, y = this.y + Math.sin(m) * n, x = this.x + Math.cos(m) * h, b = this.y + Math.sin(m) * h;
4249
4262
  l = Math.min(l, p, x), c = Math.max(c, p, x), g = Math.min(g, y, b), d = Math.max(d, y, b);
4250
4263
  }
4251
4264
  return {
@@ -4264,15 +4277,15 @@ class Be extends q {
4264
4277
  * Handle resize
4265
4278
  * For circle, we maintain uniform scale and keep scale on the transform
4266
4279
  */
4267
- resize(t, e, o, i) {
4268
- const s = i.transformData, a = (e + o) / 2, n = (i.width + i.height) / 2, h = a / n, l = s.scale * h, c = Math.max(0.1, Math.min(10, l));
4280
+ resize(t, e, o, s) {
4281
+ const i = s.transformData, a = (e + o) / 2, n = (s.width + s.height) / 2, h = a / n, l = i.scale * h, c = Math.max(0.1, Math.min(10, l));
4269
4282
  this.transformData.scale = c;
4270
4283
  const g = this.getBoundingBox(), d = ke(
4271
4284
  {
4272
- x: i.x - s.radius * s.scale,
4273
- y: i.y - s.radius * s.scale,
4274
- width: s.radius * 2 * s.scale,
4275
- height: s.radius * 2 * s.scale
4285
+ x: s.x - i.radius * i.scale,
4286
+ y: s.y - i.radius * i.scale,
4287
+ width: i.radius * 2 * i.scale,
4288
+ height: i.radius * 2 * i.scale
4276
4289
  },
4277
4290
  { width: g.width, height: g.height },
4278
4291
  t,
@@ -4361,10 +4374,10 @@ class Re extends q {
4361
4374
  };
4362
4375
  }
4363
4376
  getVisualBoundingBox() {
4364
- const t = this.text.split(""), e = t.map((u) => tt(u, this.fontSize, this.fontFamily)), o = e.reduce((u, m) => u + m, 0), i = this.transformData.width / 2, s = 0.3, n = this.fontSize / 2;
4377
+ const t = this.text.split(""), e = t.map((u) => tt(u, this.fontSize, this.fontFamily)), o = e.reduce((u, m) => u + m, 0), s = this.transformData.width / 2, i = 0.3, n = this.fontSize / 2;
4365
4378
  let h = 1 / 0, l = -1 / 0, c = 1 / 0, g = -1 / 0, d = -o / 2;
4366
4379
  t.forEach((u, m) => {
4367
- const p = e[m], y = d + p / 2, x = y / i, b = (Math.pow(x, 2) - 1) * this.transformData.archHeight * this.fontSize, S = 2 * x * this.transformData.archHeight;
4380
+ const p = e[m], y = d + p / 2, x = y / s, b = (Math.pow(x, 2) - 1) * this.transformData.archHeight * this.fontSize, S = 2 * x * this.transformData.archHeight;
4368
4381
  [
4369
4382
  { x: -p / 2, y: -n },
4370
4383
  // top-left
@@ -4375,7 +4388,7 @@ class Re extends q {
4375
4388
  { x: p / 2, y: n }
4376
4389
  // bottom-right
4377
4390
  ].forEach((w) => {
4378
- const T = w.x, F = w.y + S * s * w.x, A = y + T, M = b + F;
4391
+ const T = w.x, F = w.y + S * i * w.x, A = y + T, M = b + F;
4379
4392
  h = Math.min(h, A), l = Math.max(l, A), c = Math.min(c, M), g = Math.max(g, M);
4380
4393
  }), d += p;
4381
4394
  });
@@ -4387,22 +4400,22 @@ class Re extends q {
4387
4400
  height: g - c
4388
4401
  };
4389
4402
  }
4390
- resize(t, e, o, i) {
4391
- const s = t.includes("top") || t.includes("bottom"), a = t.includes("middle"), n = i.transformData;
4392
- if (s) {
4393
- const h = e / i.width, l = i.fontSize * h;
4403
+ resize(t, e, o, s) {
4404
+ const i = t.includes("top") || t.includes("bottom"), a = t.includes("middle"), n = s.transformData;
4405
+ if (i) {
4406
+ const h = e / s.width, l = s.fontSize * h;
4394
4407
  this.setFontSize(l);
4395
4408
  const c = n.width * h;
4396
4409
  this.transformData.width = Math.max(50, c);
4397
4410
  } else if (a && (t === "middle-left" || t === "middle-right")) {
4398
- this.fontSize = i.fontSize, this.transformData.width = Math.max(50, e);
4399
- const h = e - i.width, l = this.rotation * Math.PI / 180, c = Math.cos(l), g = Math.sin(l);
4411
+ this.fontSize = s.fontSize, this.transformData.width = Math.max(50, e);
4412
+ const h = e - s.width, l = this.rotation * Math.PI / 180, c = Math.cos(l), g = Math.sin(l);
4400
4413
  if (t === "middle-left") {
4401
4414
  const d = -h / 2;
4402
- this.x = i.x + d * c, this.y = i.y + d * g;
4415
+ this.x = s.x + d * c, this.y = s.y + d * g;
4403
4416
  } else if (t === "middle-right") {
4404
4417
  const d = h / 2;
4405
- this.x = i.x + d * c, this.y = i.y + d * g;
4418
+ this.x = s.x + d * c, this.y = s.y + d * g;
4406
4419
  }
4407
4420
  }
4408
4421
  }
@@ -4434,7 +4447,7 @@ class Re extends q {
4434
4447
  };
4435
4448
  }
4436
4449
  }
4437
- const st = {
4450
+ const it = {
4438
4451
  amplitude: 0.2,
4439
4452
  // 20% - subtle wave effect
4440
4453
  frequency: 1.2,
@@ -4459,9 +4472,9 @@ class We extends q {
4459
4472
  const e = t.transformData;
4460
4473
  this.transformData = {
4461
4474
  type: "wave",
4462
- amplitude: (e == null ? void 0 : e.amplitude) ?? st.amplitude,
4463
- frequency: (e == null ? void 0 : e.frequency) ?? st.frequency,
4464
- width: (e == null ? void 0 : e.width) ?? st.width
4475
+ amplitude: (e == null ? void 0 : e.amplitude) ?? it.amplitude,
4476
+ frequency: (e == null ? void 0 : e.frequency) ?? it.frequency,
4477
+ width: (e == null ? void 0 : e.width) ?? it.width
4465
4478
  };
4466
4479
  }
4467
4480
  getBoundingBox() {
@@ -4474,18 +4487,18 @@ class We extends q {
4474
4487
  };
4475
4488
  }
4476
4489
  getVisualBoundingBox() {
4477
- const t = this.text.split(""), e = t.map((d) => tt(d, this.fontSize, this.fontFamily)), o = e.reduce((d, f) => d + f, 0), s = this.fontSize / 2;
4490
+ const t = this.text.split(""), e = t.map((d) => tt(d, this.fontSize, this.fontFamily)), o = e.reduce((d, f) => d + f, 0), i = this.fontSize / 2;
4478
4491
  let a = 1 / 0, n = -1 / 0, h = 1 / 0, l = -1 / 0, c = -o / 2;
4479
4492
  t.forEach((d, f) => {
4480
4493
  const u = e[f], m = c + u / 2, p = m / (this.transformData.width / 2), y = this.transformData.amplitude * this.fontSize * Math.sin(this.transformData.frequency * Math.PI * p), x = this.transformData.amplitude * this.transformData.frequency * Math.PI * Math.cos(this.transformData.frequency * Math.PI * p);
4481
4494
  [
4482
- { x: -u / 2, y: -s },
4495
+ { x: -u / 2, y: -i },
4483
4496
  // top-left
4484
- { x: u / 2, y: -s },
4497
+ { x: u / 2, y: -i },
4485
4498
  // top-right
4486
- { x: -u / 2, y: s },
4499
+ { x: -u / 2, y: i },
4487
4500
  // bottom-left
4488
- { x: u / 2, y: s }
4501
+ { x: u / 2, y: i }
4489
4502
  // bottom-right
4490
4503
  ].forEach((S) => {
4491
4504
  const v = S.x, w = S.y + x * pe * S.x, T = m + v, F = y + w;
@@ -4500,8 +4513,8 @@ class We extends q {
4500
4513
  height: l - h
4501
4514
  };
4502
4515
  }
4503
- resize(t, e, o, i) {
4504
- Gt(this, t, e, o, i);
4516
+ resize(t, e, o, s) {
4517
+ Gt(this, t, e, o, s);
4505
4518
  }
4506
4519
  getEnabledAnchors() {
4507
4520
  return ["top-left", "top-right", "bottom-left", "bottom-right"];
@@ -4543,7 +4556,7 @@ class ze extends q {
4543
4556
  };
4544
4557
  }
4545
4558
  getVisualBoundingBox() {
4546
- const t = this.text.split(""), e = t.map((f) => tt(f, this.fontSize, this.fontFamily)), o = e.reduce((f, u) => f + u, 0), i = 0.3, a = this.fontSize / 2;
4559
+ const t = this.text.split(""), e = t.map((f) => tt(f, this.fontSize, this.fontFamily)), o = e.reduce((f, u) => f + u, 0), s = 0.3, a = this.fontSize / 2;
4547
4560
  let n = 1 / 0, h = -1 / 0, l = 1 / 0, c = -1 / 0, g = -o / 2;
4548
4561
  t.forEach((f, u) => {
4549
4562
  const m = e[u], p = g + m / 2, y = p / (this.transformData.width / 2), x = Math.abs(y), b = this.transformData.amplitude * x, S = b * this.fontSize * Math.sin(this.transformData.frequency * Math.PI * y), v = b * this.transformData.frequency * Math.PI * Math.cos(this.transformData.frequency * Math.PI * y), w = this.transformData.amplitude * Math.sign(y) * Math.sin(this.transformData.frequency * Math.PI * y), T = v + w;
@@ -4557,7 +4570,7 @@ class ze extends q {
4557
4570
  { x: m / 2, y: a }
4558
4571
  // bottom-right
4559
4572
  ].forEach((A) => {
4560
- const M = A.x, k = A.y + T * i * A.x, I = p + M, O = S + k;
4573
+ const M = A.x, k = A.y + T * s * A.x, I = p + M, O = S + k;
4561
4574
  n = Math.min(n, I), h = Math.max(h, I), l = Math.min(l, O), c = Math.max(c, O);
4562
4575
  }), g += m;
4563
4576
  });
@@ -4569,22 +4582,22 @@ class ze extends q {
4569
4582
  height: c - l
4570
4583
  };
4571
4584
  }
4572
- resize(t, e, o, i) {
4573
- const s = t.includes("top") || t.includes("bottom"), a = t.includes("middle"), n = i.transformData;
4574
- if (s) {
4575
- const h = e / i.width, l = i.fontSize * h;
4585
+ resize(t, e, o, s) {
4586
+ const i = t.includes("top") || t.includes("bottom"), a = t.includes("middle"), n = s.transformData;
4587
+ if (i) {
4588
+ const h = e / s.width, l = s.fontSize * h;
4576
4589
  this.setFontSize(l);
4577
4590
  const c = n.width * h;
4578
4591
  this.transformData.width = Math.max(50, c);
4579
4592
  } else if (a && (t === "middle-left" || t === "middle-right")) {
4580
- this.fontSize = i.fontSize, this.transformData.width = Math.max(50, e);
4581
- const h = e - i.width, l = this.rotation * Math.PI / 180, c = Math.cos(l), g = Math.sin(l);
4593
+ this.fontSize = s.fontSize, this.transformData.width = Math.max(50, e);
4594
+ const h = e - s.width, l = this.rotation * Math.PI / 180, c = Math.cos(l), g = Math.sin(l);
4582
4595
  if (t === "middle-left") {
4583
4596
  const d = -h / 2;
4584
- this.x = i.x + d * c, this.y = i.y + d * g;
4597
+ this.x = s.x + d * c, this.y = s.y + d * g;
4585
4598
  } else if (t === "middle-right") {
4586
4599
  const d = h / 2;
4587
- this.x = i.x + d * c, this.y = i.y + d * g;
4600
+ this.x = s.x + d * c, this.y = s.y + d * g;
4588
4601
  }
4589
4602
  }
4590
4603
  }
@@ -4638,7 +4651,7 @@ class Xe extends q {
4638
4651
  };
4639
4652
  }
4640
4653
  getVisualBoundingBox() {
4641
- const e = tt(this.text, this.fontSize, this.fontFamily), o = this.fontSize * 1.2, i = -this.transformData.leanAmount * Math.PI / 4, s = Math.tan(i), a = [
4654
+ const e = tt(this.text, this.fontSize, this.fontFamily), o = this.fontSize * 1.2, s = -this.transformData.leanAmount * Math.PI / 4, i = Math.tan(s), a = [
4642
4655
  { x: -e / 2, y: -o / 2 },
4643
4656
  // top-left
4644
4657
  { x: e / 2, y: -o / 2 },
@@ -4650,7 +4663,7 @@ class Xe extends q {
4650
4663
  ];
4651
4664
  let n = 1 / 0, h = -1 / 0, l = 1 / 0, c = -1 / 0;
4652
4665
  a.forEach((d) => {
4653
- const f = d.x + s * d.y, u = d.y;
4666
+ const f = d.x + i * d.y, u = d.y;
4654
4667
  n = Math.min(n, f), h = Math.max(h, f), l = Math.min(l, u), c = Math.max(c, u);
4655
4668
  });
4656
4669
  const g = 2;
@@ -4661,22 +4674,22 @@ class Xe extends q {
4661
4674
  height: c - l
4662
4675
  };
4663
4676
  }
4664
- resize(t, e, o, i) {
4665
- const s = t.includes("top") || t.includes("bottom"), a = t.includes("middle"), n = i.transformData;
4666
- if (s) {
4667
- const h = e / i.width, l = i.fontSize * h;
4677
+ resize(t, e, o, s) {
4678
+ const i = t.includes("top") || t.includes("bottom"), a = t.includes("middle"), n = s.transformData;
4679
+ if (i) {
4680
+ const h = e / s.width, l = s.fontSize * h;
4668
4681
  this.setFontSize(l);
4669
4682
  const c = n.width * h;
4670
4683
  this.transformData.width = Math.max(50, c);
4671
4684
  } else if (a && (t === "middle-left" || t === "middle-right")) {
4672
- this.fontSize = i.fontSize, this.transformData.width = Math.max(50, e);
4685
+ this.fontSize = s.fontSize, this.transformData.width = Math.max(50, e);
4673
4686
  const h = e - n.width, l = this.rotation * Math.PI / 180, c = Math.cos(l), g = Math.sin(l);
4674
4687
  if (t === "middle-left") {
4675
4688
  const d = -h / 2;
4676
- this.x = i.x + d * c, this.y = i.y + d * g;
4689
+ this.x = s.x + d * c, this.y = s.y + d * g;
4677
4690
  } else if (t === "middle-right") {
4678
4691
  const d = h / 2;
4679
- this.x = i.x + d * c, this.y = i.y + d * g;
4692
+ this.x = s.x + d * c, this.y = s.y + d * g;
4680
4693
  }
4681
4694
  }
4682
4695
  }
@@ -4719,19 +4732,19 @@ class Ye extends q {
4719
4732
  };
4720
4733
  }
4721
4734
  getBoundingBox() {
4722
- const t = this.transformData.ascendAngle * Math.PI / 180, e = this.transformData.width, o = e * Math.tan(t), i = Math.abs(o) + this.fontSize * 1.2, s = o > 0 ? -i : 0;
4735
+ const t = this.transformData.ascendAngle * Math.PI / 180, e = this.transformData.width, o = e * Math.tan(t), s = Math.abs(o) + this.fontSize * 1.2, i = o > 0 ? -s : 0;
4723
4736
  return {
4724
4737
  x: this.x - e / 2,
4725
- y: this.y + s,
4738
+ y: this.y + i,
4726
4739
  width: e,
4727
- height: i
4740
+ height: s
4728
4741
  };
4729
4742
  }
4730
4743
  getVisualBoundingBox() {
4731
- const t = this.text.split(""), e = t.map((m) => tt(m, this.fontSize, this.fontFamily)), o = e.reduce((m, p) => m + p, 0), i = this.transformData.ascendAngle * Math.PI / 180, s = Math.tan(i), a = 1, h = this.fontSize / 2;
4744
+ const t = this.text.split(""), e = t.map((m) => tt(m, this.fontSize, this.fontFamily)), o = e.reduce((m, p) => m + p, 0), s = this.transformData.ascendAngle * Math.PI / 180, i = Math.tan(s), a = 1, h = this.fontSize / 2;
4732
4745
  let l = 1 / 0, c = -1 / 0, g = 1 / 0, d = -1 / 0, f = -o / 2;
4733
4746
  t.forEach((m, p) => {
4734
- const y = e[p], x = f + y / 2, b = x * s;
4747
+ const y = e[p], x = f + y / 2, b = x * i;
4735
4748
  [
4736
4749
  { x: -y / 2, y: -h },
4737
4750
  // top-left
@@ -4742,7 +4755,7 @@ class Ye extends q {
4742
4755
  { x: y / 2, y: h }
4743
4756
  // bottom-right
4744
4757
  ].forEach((v) => {
4745
- const w = v.x, T = v.y + s * a * v.x, F = x + w, A = b + T;
4758
+ const w = v.x, T = v.y + i * a * v.x, F = x + w, A = b + T;
4746
4759
  l = Math.min(l, F), c = Math.max(c, F), g = Math.min(g, A), d = Math.max(d, A);
4747
4760
  }), f += y;
4748
4761
  });
@@ -4754,22 +4767,22 @@ class Ye extends q {
4754
4767
  height: d - g
4755
4768
  };
4756
4769
  }
4757
- resize(t, e, o, i) {
4758
- const s = t.includes("top") || t.includes("bottom"), a = t.includes("middle"), n = i.transformData;
4759
- if (s) {
4760
- const h = e / i.width, l = i.fontSize * h;
4770
+ resize(t, e, o, s) {
4771
+ const i = t.includes("top") || t.includes("bottom"), a = t.includes("middle"), n = s.transformData;
4772
+ if (i) {
4773
+ const h = e / s.width, l = s.fontSize * h;
4761
4774
  this.setFontSize(l);
4762
4775
  const c = n.width * h;
4763
4776
  this.transformData.width = Math.max(50, c);
4764
4777
  } else if (a && (t === "middle-left" || t === "middle-right")) {
4765
- this.fontSize = i.fontSize, this.transformData.width = Math.max(50, e);
4766
- const h = e - i.width, l = this.rotation * Math.PI / 180, c = Math.cos(l), g = Math.sin(l);
4778
+ this.fontSize = s.fontSize, this.transformData.width = Math.max(50, e);
4779
+ const h = e - s.width, l = this.rotation * Math.PI / 180, c = Math.cos(l), g = Math.sin(l);
4767
4780
  if (t === "middle-left") {
4768
4781
  const d = -h / 2;
4769
- this.x = i.x + d * c, this.y = i.y + d * g;
4782
+ this.x = s.x + d * c, this.y = s.y + d * g;
4770
4783
  } else if (t === "middle-right") {
4771
4784
  const d = h / 2;
4772
- this.x = i.x + d * c, this.y = i.y + d * g;
4785
+ this.x = s.x + d * c, this.y = s.y + d * g;
4773
4786
  }
4774
4787
  }
4775
4788
  }
@@ -4803,14 +4816,14 @@ class Ye extends q {
4803
4816
  }
4804
4817
  class Ft extends Q {
4805
4818
  constructor(t = {}) {
4806
- var o, i, s, a, n, h, l, c, g, d, f;
4819
+ var o, s, i, a, n, h, l, c, g, d, f;
4807
4820
  super(t), this.transformType = "shape";
4808
4821
  const e = "rectangle";
4809
4822
  this.transformData = {
4810
4823
  type: "shape",
4811
4824
  shapeType: ((o = t.transformData) == null ? void 0 : o.shapeType) || e,
4812
- width: ((i = t.transformData) == null ? void 0 : i.width) || 200,
4813
- height: ((s = t.transformData) == null ? void 0 : s.height) || 200,
4825
+ width: ((s = t.transformData) == null ? void 0 : s.width) || 200,
4826
+ height: ((i = t.transformData) == null ? void 0 : i.height) || 200,
4814
4827
  borderRadius: ((a = t.transformData) == null ? void 0 : a.borderRadius) ?? 3,
4815
4828
  // Default 3% radius (~6px on 200x200 shape, matches hover border)
4816
4829
  radiusX: (n = t.transformData) == null ? void 0 : n.radiusX,
@@ -4853,34 +4866,34 @@ class Ft extends Q {
4853
4866
  getVisualBoundingBox() {
4854
4867
  const { shapeType: t, width: e, height: o } = this.transformData;
4855
4868
  if (t === "circle") {
4856
- const i = Math.min(e, o) / 2;
4869
+ const s = Math.min(e, o) / 2;
4857
4870
  return {
4858
- x: this.x - i,
4859
- y: this.y - i,
4860
- width: i * 2,
4861
- height: i * 2
4871
+ x: this.x - s,
4872
+ y: this.y - s,
4873
+ width: s * 2,
4874
+ height: s * 2
4862
4875
  };
4863
4876
  }
4864
4877
  if (t === "polygon" || t === "star") {
4865
- const i = Math.min(e, o) / 2;
4866
- let s = 1 / 0, a = 1 / 0, n = -1 / 0, h = -1 / 0;
4878
+ const s = Math.min(e, o) / 2;
4879
+ let i = 1 / 0, a = 1 / 0, n = -1 / 0, h = -1 / 0;
4867
4880
  if (t === "polygon") {
4868
4881
  const l = this.transformData.sides || 5;
4869
4882
  for (let c = 0; c < l; c++) {
4870
- const g = c * 2 * Math.PI / l - Math.PI / 2, d = i * Math.cos(g), f = i * Math.sin(g);
4871
- d < s && (s = d), d > n && (n = d), f < a && (a = f), f > h && (h = f);
4883
+ const g = c * 2 * Math.PI / l - Math.PI / 2, d = s * Math.cos(g), f = s * Math.sin(g);
4884
+ d < i && (i = d), d > n && (n = d), f < a && (a = f), f > h && (h = f);
4872
4885
  }
4873
4886
  } else {
4874
- const l = this.transformData.points || 5, c = i, g = c * (this.transformData.innerRadius ?? 0.4);
4887
+ const l = this.transformData.points || 5, c = s, g = c * (this.transformData.innerRadius ?? 0.4);
4875
4888
  for (let d = 0; d < l * 2; d++) {
4876
4889
  const f = d * Math.PI / l - Math.PI / 2, u = d % 2 === 0 ? c : g, m = u * Math.cos(f), p = u * Math.sin(f);
4877
- m < s && (s = m), m > n && (n = m), p < a && (a = p), p > h && (h = p);
4890
+ m < i && (i = m), m > n && (n = m), p < a && (a = p), p > h && (h = p);
4878
4891
  }
4879
4892
  }
4880
4893
  return {
4881
- x: this.x + s,
4894
+ x: this.x + i,
4882
4895
  y: this.y + a,
4883
- width: n - s,
4896
+ width: n - i,
4884
4897
  height: h - a
4885
4898
  };
4886
4899
  }
@@ -4897,14 +4910,14 @@ class Ft extends Q {
4897
4910
  */
4898
4911
  render(t, e = !1, o = !1) {
4899
4912
  var n;
4900
- const i = this.opacity ?? 1, s = !!((n = this.stroke) != null && n.enabled);
4901
- if (i < 1 && s) {
4902
- this.renderWithOffscreen(t, i);
4913
+ const s = this.opacity ?? 1, i = !!((n = this.stroke) != null && n.enabled);
4914
+ if (s < 1 && i) {
4915
+ this.renderWithOffscreen(t, s);
4903
4916
  return;
4904
4917
  }
4905
4918
  t.save(), t.translate(this.x, this.y), t.rotate(D.toRadians(this.rotation)), t.fillStyle = this.transformData.fillColor || "#3b82f6";
4906
4919
  const a = this.transformData.fillOpacity ?? 1;
4907
- t.globalAlpha = i * a, this.renderShape(t), t.restore(), s && this.renderStroke(t, i);
4920
+ t.globalAlpha = s * a, this.renderShape(t), t.restore(), i && this.renderStroke(t, s);
4908
4921
  }
4909
4922
  /**
4910
4923
  * Render fill+stroke to a temporary canvas at full opacity, then composite
@@ -4912,7 +4925,7 @@ class Ft extends Q {
4912
4925
  */
4913
4926
  renderWithOffscreen(t, e) {
4914
4927
  var f;
4915
- const { width: o, height: i } = this.transformData, a = (((f = this.stroke) == null ? void 0 : f.width) || 2) + 2, n = Math.ceil(o + a * 2), h = Math.ceil(i + a * 2), l = document.createElement("canvas");
4928
+ const { width: o, height: s } = this.transformData, a = (((f = this.stroke) == null ? void 0 : f.width) || 2) + 2, n = Math.ceil(o + a * 2), h = Math.ceil(s + a * 2), l = document.createElement("canvas");
4916
4929
  l.width = n, l.height = h;
4917
4930
  const c = l.getContext("2d");
4918
4931
  if (!c) {
@@ -4936,55 +4949,55 @@ class Ft extends Q {
4936
4949
  * Trace the shape path without filling or stroking — used by offscreen render
4937
4950
  */
4938
4951
  traceShapePath(t) {
4939
- const { shapeType: e, width: o, height: i } = this.transformData;
4952
+ const { shapeType: e, width: o, height: s } = this.transformData;
4940
4953
  switch (e) {
4941
4954
  case "rectangle": {
4942
- const s = this.transformData.borderRadius || 0, a = -o / 2, n = -i / 2;
4943
- if (s > 0) {
4944
- const h = Math.min(s / 100 * Math.min(o, i), o / 2, i / 2);
4945
- t.roundRect(a, n, o, i, h);
4955
+ const i = this.transformData.borderRadius || 0, a = -o / 2, n = -s / 2;
4956
+ if (i > 0) {
4957
+ const h = Math.min(i / 100 * Math.min(o, s), o / 2, s / 2);
4958
+ t.roundRect(a, n, o, s, h);
4946
4959
  } else
4947
- t.rect(a, n, o, i);
4960
+ t.rect(a, n, o, s);
4948
4961
  break;
4949
4962
  }
4950
4963
  case "circle": {
4951
- const s = Math.min(o, i) / 2;
4952
- t.arc(0, 0, s, 0, Math.PI * 2);
4964
+ const i = Math.min(o, s) / 2;
4965
+ t.arc(0, 0, i, 0, Math.PI * 2);
4953
4966
  break;
4954
4967
  }
4955
4968
  case "ellipse":
4956
- t.ellipse(0, 0, o / 2, i / 2, 0, 0, Math.PI * 2);
4969
+ t.ellipse(0, 0, o / 2, s / 2, 0, 0, Math.PI * 2);
4957
4970
  break;
4958
4971
  case "triangle": {
4959
- const s = o / 2, a = i / 2;
4960
- t.moveTo(0, -a), t.lineTo(s, a), t.lineTo(-s, a), t.closePath();
4972
+ const i = o / 2, a = s / 2;
4973
+ t.moveTo(0, -a), t.lineTo(i, a), t.lineTo(-i, a), t.closePath();
4961
4974
  break;
4962
4975
  }
4963
4976
  case "polygon": {
4964
- const s = this.transformData.sides || 5, a = Math.min(o, i) / 2;
4965
- for (let n = 0; n < s; n++) {
4966
- const h = n * 2 * Math.PI / s - Math.PI / 2, l = a * Math.cos(h), c = a * Math.sin(h);
4977
+ const i = this.transformData.sides || 5, a = Math.min(o, s) / 2;
4978
+ for (let n = 0; n < i; n++) {
4979
+ const h = n * 2 * Math.PI / i - Math.PI / 2, l = a * Math.cos(h), c = a * Math.sin(h);
4967
4980
  n === 0 ? t.moveTo(l, c) : t.lineTo(l, c);
4968
4981
  }
4969
4982
  t.closePath();
4970
4983
  break;
4971
4984
  }
4972
4985
  case "star": {
4973
- const s = this.transformData.points || 5, a = Math.min(o, i) / 2, n = a * (this.transformData.innerRadius || 0.4);
4974
- for (let h = 0; h < s * 2; h++) {
4975
- const l = h * Math.PI / s - Math.PI / 2, c = h % 2 === 0 ? a : n, g = c * Math.cos(l), d = c * Math.sin(l);
4986
+ const i = this.transformData.points || 5, a = Math.min(o, s) / 2, n = a * (this.transformData.innerRadius || 0.4);
4987
+ for (let h = 0; h < i * 2; h++) {
4988
+ const l = h * Math.PI / i - Math.PI / 2, c = h % 2 === 0 ? a : n, g = c * Math.cos(l), d = c * Math.sin(l);
4976
4989
  h === 0 ? t.moveTo(g, d) : t.lineTo(g, d);
4977
4990
  }
4978
4991
  t.closePath();
4979
4992
  break;
4980
4993
  }
4981
4994
  case "line": {
4982
- const s = o / 2, a = i / 2;
4983
- t.rect(-s, -a, o, i);
4995
+ const i = o / 2, a = s / 2;
4996
+ t.rect(-i, -a, o, s);
4984
4997
  break;
4985
4998
  }
4986
4999
  default:
4987
- t.rect(-o / 2, -i / 2, o, i);
5000
+ t.rect(-o / 2, -s / 2, o, s);
4988
5001
  }
4989
5002
  }
4990
5003
  /**
@@ -4994,32 +5007,32 @@ class Ft extends Q {
4994
5007
  t.save(), t.translate(this.x, this.y), t.rotate(D.toRadians(this.rotation));
4995
5008
  const o = this.stroke;
4996
5009
  t.strokeStyle = o.color || "#000000", t.lineWidth = o.width || 2, t.lineCap = o.lineCap || "round", t.lineJoin = o.lineJoin || "round", t.globalAlpha = e * (o.opacity ?? 1), o.dashArray && o.dashArray.length > 0 && t.setLineDash(o.dashArray);
4997
- const { shapeType: i, width: s, height: a } = this.transformData;
4998
- switch (t.beginPath(), i) {
5010
+ const { shapeType: s, width: i, height: a } = this.transformData;
5011
+ switch (t.beginPath(), s) {
4999
5012
  case "rectangle": {
5000
- const n = this.transformData.borderRadius || 0, h = -s / 2, l = -a / 2;
5013
+ const n = this.transformData.borderRadius || 0, h = -i / 2, l = -a / 2;
5001
5014
  if (n > 0) {
5002
- const c = Math.min(n / 100 * Math.min(s, a), s / 2, a / 2);
5003
- t.roundRect(h, l, s, a, c);
5015
+ const c = Math.min(n / 100 * Math.min(i, a), i / 2, a / 2);
5016
+ t.roundRect(h, l, i, a, c);
5004
5017
  } else
5005
- t.rect(h, l, s, a);
5018
+ t.rect(h, l, i, a);
5006
5019
  break;
5007
5020
  }
5008
5021
  case "circle": {
5009
- const n = Math.min(s, a) / 2;
5022
+ const n = Math.min(i, a) / 2;
5010
5023
  t.arc(0, 0, n, 0, Math.PI * 2);
5011
5024
  break;
5012
5025
  }
5013
5026
  case "ellipse":
5014
- t.ellipse(0, 0, s / 2, a / 2, 0, 0, Math.PI * 2);
5027
+ t.ellipse(0, 0, i / 2, a / 2, 0, 0, Math.PI * 2);
5015
5028
  break;
5016
5029
  case "triangle": {
5017
- const n = s / 2, h = a / 2;
5030
+ const n = i / 2, h = a / 2;
5018
5031
  t.moveTo(0, -h), t.lineTo(n, h), t.lineTo(-n, h), t.closePath();
5019
5032
  break;
5020
5033
  }
5021
5034
  case "polygon": {
5022
- const n = this.transformData.sides || 5, h = Math.min(s, a) / 2;
5035
+ const n = this.transformData.sides || 5, h = Math.min(i, a) / 2;
5023
5036
  for (let l = 0; l < n; l++) {
5024
5037
  const c = l * 2 * Math.PI / n - Math.PI / 2, g = h * Math.cos(c), d = h * Math.sin(c);
5025
5038
  l === 0 ? t.moveTo(g, d) : t.lineTo(g, d);
@@ -5028,7 +5041,7 @@ class Ft extends Q {
5028
5041
  break;
5029
5042
  }
5030
5043
  case "star": {
5031
- const n = this.transformData.points || 5, h = Math.min(s, a) / 2, l = h * (this.transformData.innerRadius || 0.4);
5044
+ const n = this.transformData.points || 5, h = Math.min(i, a) / 2, l = h * (this.transformData.innerRadius || 0.4);
5032
5045
  for (let c = 0; c < n * 2; c++) {
5033
5046
  const g = c * Math.PI / n - Math.PI / 2, d = c % 2 === 0 ? h : l, f = d * Math.cos(g), u = d * Math.sin(g);
5034
5047
  c === 0 ? t.moveTo(f, u) : t.lineTo(f, u);
@@ -5037,12 +5050,12 @@ class Ft extends Q {
5037
5050
  break;
5038
5051
  }
5039
5052
  case "line": {
5040
- const n = s / 2, h = a / 2;
5041
- t.rect(-n, -h, s, a);
5053
+ const n = i / 2, h = a / 2;
5054
+ t.rect(-n, -h, i, a);
5042
5055
  break;
5043
5056
  }
5044
5057
  default:
5045
- t.rect(-s / 2, -a / 2, s, a);
5058
+ t.rect(-i / 2, -a / 2, i, a);
5046
5059
  }
5047
5060
  t.stroke(), t.restore();
5048
5061
  }
@@ -5050,32 +5063,32 @@ class Ft extends Q {
5050
5063
  * Render the specific shape based on shapeType
5051
5064
  */
5052
5065
  renderShape(t) {
5053
- const { shapeType: e, width: o, height: i } = this.transformData;
5066
+ const { shapeType: e, width: o, height: s } = this.transformData;
5054
5067
  switch (t.beginPath(), e) {
5055
5068
  case "rectangle":
5056
- this.renderRectangle(t, o, i);
5069
+ this.renderRectangle(t, o, s);
5057
5070
  break;
5058
5071
  case "circle":
5059
- this.renderCircle(t, Math.min(o, i) / 2);
5072
+ this.renderCircle(t, Math.min(o, s) / 2);
5060
5073
  break;
5061
5074
  case "ellipse":
5062
- this.renderEllipse(t, o / 2, i / 2);
5075
+ this.renderEllipse(t, o / 2, s / 2);
5063
5076
  break;
5064
5077
  case "triangle":
5065
- this.renderTriangle(t, o, i);
5078
+ this.renderTriangle(t, o, s);
5066
5079
  break;
5067
5080
  case "polygon":
5068
- this.renderPolygon(t, Math.min(o, i) / 2);
5081
+ this.renderPolygon(t, Math.min(o, s) / 2);
5069
5082
  break;
5070
5083
  case "star":
5071
- this.renderStar(t, Math.min(o, i) / 2);
5084
+ this.renderStar(t, Math.min(o, s) / 2);
5072
5085
  break;
5073
5086
  case "line":
5074
- this.renderLine(t, o, i);
5087
+ this.renderLine(t, o, s);
5075
5088
  return;
5076
5089
  // Line uses stroke, not fill
5077
5090
  default:
5078
- this.renderRectangle(t, o, i);
5091
+ this.renderRectangle(t, o, s);
5079
5092
  }
5080
5093
  t.fill();
5081
5094
  }
@@ -5083,12 +5096,12 @@ class Ft extends Q {
5083
5096
  * Render a rectangle (with optional border radius)
5084
5097
  */
5085
5098
  renderRectangle(t, e, o) {
5086
- const i = this.transformData.borderRadius || 0, s = -e / 2, a = -o / 2;
5087
- if (i > 0) {
5088
- const n = Math.min(i / 100 * Math.min(e, o), e / 2, o / 2);
5089
- t.roundRect(s, a, e, o, n);
5099
+ const s = this.transformData.borderRadius || 0, i = -e / 2, a = -o / 2;
5100
+ if (s > 0) {
5101
+ const n = Math.min(s / 100 * Math.min(e, o), e / 2, o / 2);
5102
+ t.roundRect(i, a, e, o, n);
5090
5103
  } else
5091
- t.rect(s, a, e, o);
5104
+ t.rect(i, a, e, o);
5092
5105
  }
5093
5106
  /**
5094
5107
  * Render a circle
@@ -5106,16 +5119,16 @@ class Ft extends Q {
5106
5119
  * Render a triangle (isosceles, pointing up)
5107
5120
  */
5108
5121
  renderTriangle(t, e, o) {
5109
- const i = e / 2, s = o / 2;
5110
- t.moveTo(0, -s), t.lineTo(i, s), t.lineTo(-i, s), t.closePath();
5122
+ const s = e / 2, i = o / 2;
5123
+ t.moveTo(0, -i), t.lineTo(s, i), t.lineTo(-s, i), t.closePath();
5111
5124
  }
5112
5125
  /**
5113
5126
  * Render a regular polygon
5114
5127
  */
5115
5128
  renderPolygon(t, e) {
5116
- const o = Math.max(3, Math.min(20, this.transformData.sides || 5)), i = Math.PI * 2 / o, s = -Math.PI / 2;
5129
+ const o = Math.max(3, Math.min(20, this.transformData.sides || 5)), s = Math.PI * 2 / o, i = -Math.PI / 2;
5117
5130
  for (let a = 0; a <= o; a++) {
5118
- const n = s + i * a, h = Math.cos(n) * e, l = Math.sin(n) * e;
5131
+ const n = i + s * a, h = Math.cos(n) * e, l = Math.sin(n) * e;
5119
5132
  a === 0 ? t.moveTo(h, l) : t.lineTo(h, l);
5120
5133
  }
5121
5134
  t.closePath();
@@ -5124,9 +5137,9 @@ class Ft extends Q {
5124
5137
  * Render a star
5125
5138
  */
5126
5139
  renderStar(t, e) {
5127
- const o = Math.max(3, Math.min(20, this.transformData.points || 5)), i = Math.max(0.1, Math.min(0.9, this.transformData.innerRadius || 0.4)), s = e * i, a = Math.PI / o, n = -Math.PI / 2;
5140
+ const o = Math.max(3, Math.min(20, this.transformData.points || 5)), s = Math.max(0.1, Math.min(0.9, this.transformData.innerRadius || 0.4)), i = e * s, a = Math.PI / o, n = -Math.PI / 2;
5128
5141
  for (let h = 0; h < o * 2; h++) {
5129
- const l = n + a * h, c = h % 2 === 0 ? e : s, g = Math.cos(l) * c, d = Math.sin(l) * c;
5142
+ const l = n + a * h, c = h % 2 === 0 ? e : i, g = Math.cos(l) * c, d = Math.sin(l) * c;
5130
5143
  h === 0 ? t.moveTo(g, d) : t.lineTo(g, d);
5131
5144
  }
5132
5145
  t.closePath();
@@ -5135,20 +5148,20 @@ class Ft extends Q {
5135
5148
  * Render a line
5136
5149
  */
5137
5150
  renderLine(t, e, o) {
5138
- const i = e / 2, s = o;
5139
- t.moveTo(-i, 0), t.lineTo(i, 0), t.strokeStyle = this.transformData.fillColor || "#3b82f6", t.lineWidth = s, t.lineCap = "round", t.stroke();
5151
+ const s = e / 2, i = o;
5152
+ t.moveTo(-s, 0), t.lineTo(s, 0), t.strokeStyle = this.transformData.fillColor || "#3b82f6", t.lineWidth = i, t.lineCap = "round", t.stroke();
5140
5153
  }
5141
5154
  /**
5142
5155
  * Handle resize - maintain aspect ratio for circles, free resize for others
5143
5156
  */
5144
- resize(t, e, o, i) {
5145
- const { shapeType: s } = this.transformData;
5146
- if (s === "circle" || s === "polygon" || s === "star") {
5147
- const c = Math.max(e / i.transformData.width, o / i.transformData.height);
5148
- this.transformData.width = i.transformData.width * c, this.transformData.height = i.transformData.height * c;
5149
- } else s === "line" ? (this.transformData.width = e, this.transformData.height = i.transformData.height) : (this.transformData.width = e, this.transformData.height = o);
5150
- this.rotation = i.rotation;
5151
- const a = this.getFixedCorner(t, i), n = this.getOppositeAnchor(t), h = this.getBoundingBox(), l = this.getCornerOffset(n, h);
5157
+ resize(t, e, o, s) {
5158
+ const { shapeType: i } = this.transformData;
5159
+ if (i === "circle" || i === "polygon" || i === "star") {
5160
+ const c = Math.max(e / s.transformData.width, o / s.transformData.height);
5161
+ this.transformData.width = s.transformData.width * c, this.transformData.height = s.transformData.height * c;
5162
+ } else i === "line" ? (this.transformData.width = e, this.transformData.height = s.transformData.height) : (this.transformData.width = e, this.transformData.height = o);
5163
+ this.rotation = s.rotation;
5164
+ const a = this.getFixedCorner(t, s), n = this.getOppositeAnchor(t), h = this.getBoundingBox(), l = this.getCornerOffset(n, h);
5152
5165
  return this.x = a.x - l.x, this.y = a.y - l.y, !0;
5153
5166
  }
5154
5167
  /**
@@ -5180,71 +5193,71 @@ class Ft extends Q {
5180
5193
  width: e.transformData.width,
5181
5194
  height: e.transformData.height
5182
5195
  };
5183
- let i, s;
5196
+ let s, i;
5184
5197
  switch (t) {
5185
5198
  case "top-left":
5186
- i = o.x + o.width, s = o.y + o.height;
5199
+ s = o.x + o.width, i = o.y + o.height;
5187
5200
  break;
5188
5201
  case "top-right":
5189
- i = o.x, s = o.y + o.height;
5202
+ s = o.x, i = o.y + o.height;
5190
5203
  break;
5191
5204
  case "bottom-left":
5192
- i = o.x + o.width, s = o.y;
5205
+ s = o.x + o.width, i = o.y;
5193
5206
  break;
5194
5207
  case "bottom-right":
5195
- i = o.x, s = o.y;
5208
+ s = o.x, i = o.y;
5196
5209
  break;
5197
5210
  case "middle-left":
5198
- i = o.x + o.width, s = o.y + o.height / 2;
5211
+ s = o.x + o.width, i = o.y + o.height / 2;
5199
5212
  break;
5200
5213
  case "middle-right":
5201
- i = o.x, s = o.y + o.height / 2;
5214
+ s = o.x, i = o.y + o.height / 2;
5202
5215
  break;
5203
5216
  case "middle-top":
5204
- i = o.x + o.width / 2, s = o.y + o.height;
5217
+ s = o.x + o.width / 2, i = o.y + o.height;
5205
5218
  break;
5206
5219
  case "middle-bottom":
5207
- i = o.x + o.width / 2, s = o.y;
5220
+ s = o.x + o.width / 2, i = o.y;
5208
5221
  break;
5209
5222
  default:
5210
- i = o.x + o.width / 2, s = o.y + o.height / 2;
5223
+ s = o.x + o.width / 2, i = o.y + o.height / 2;
5211
5224
  }
5212
- return { x: i, y: s };
5225
+ return { x: s, y: i };
5213
5226
  }
5214
5227
  /**
5215
5228
  * Get the offset of a corner from the center
5216
5229
  */
5217
5230
  getCornerOffset(t, e) {
5218
- let o, i;
5231
+ let o, s;
5219
5232
  switch (t) {
5220
5233
  case "top-left":
5221
- o = -e.width / 2, i = -e.height / 2;
5234
+ o = -e.width / 2, s = -e.height / 2;
5222
5235
  break;
5223
5236
  case "top-right":
5224
- o = e.width / 2, i = -e.height / 2;
5237
+ o = e.width / 2, s = -e.height / 2;
5225
5238
  break;
5226
5239
  case "bottom-left":
5227
- o = -e.width / 2, i = e.height / 2;
5240
+ o = -e.width / 2, s = e.height / 2;
5228
5241
  break;
5229
5242
  case "bottom-right":
5230
- o = e.width / 2, i = e.height / 2;
5243
+ o = e.width / 2, s = e.height / 2;
5231
5244
  break;
5232
5245
  case "middle-left":
5233
- o = -e.width / 2, i = 0;
5246
+ o = -e.width / 2, s = 0;
5234
5247
  break;
5235
5248
  case "middle-right":
5236
- o = e.width / 2, i = 0;
5249
+ o = e.width / 2, s = 0;
5237
5250
  break;
5238
5251
  case "middle-top":
5239
- o = 0, i = -e.height / 2;
5252
+ o = 0, s = -e.height / 2;
5240
5253
  break;
5241
5254
  case "middle-bottom":
5242
- o = 0, i = e.height / 2;
5255
+ o = 0, s = e.height / 2;
5243
5256
  break;
5244
5257
  default:
5245
- o = 0, i = 0;
5258
+ o = 0, s = 0;
5246
5259
  }
5247
- return { x: o, y: i };
5260
+ return { x: o, y: s };
5248
5261
  }
5249
5262
  /**
5250
5263
  * Get enabled anchors - all 8 anchors for most shapes, only corners for circles/polygons
@@ -5290,13 +5303,13 @@ class Ft extends Q {
5290
5303
  }
5291
5304
  class Mt extends Q {
5292
5305
  constructor(t = {}) {
5293
- var e, o, i, s, a, n, h, l, c, g;
5306
+ var e, o, s, i, a, n, h, l, c, g;
5294
5307
  super(t), this.transformType = "path", this.transformData = {
5295
5308
  type: "path",
5296
5309
  points: ((e = t.transformData) == null ? void 0 : e.points) || [],
5297
5310
  closed: ((o = t.transformData) == null ? void 0 : o.closed) ?? !1,
5298
- width: ((i = t.transformData) == null ? void 0 : i.width) || 200,
5299
- height: ((s = t.transformData) == null ? void 0 : s.height) || 200,
5311
+ width: ((s = t.transformData) == null ? void 0 : s.width) || 200,
5312
+ height: ((i = t.transformData) == null ? void 0 : i.height) || 200,
5300
5313
  fillEnabled: ((a = t.transformData) == null ? void 0 : a.fillEnabled) ?? !1,
5301
5314
  fillColor: ((n = t.transformData) == null ? void 0 : n.fillColor) || zt(),
5302
5315
  fillOpacity: ((h = t.transformData) == null ? void 0 : h.fillOpacity) ?? 1,
@@ -5344,11 +5357,11 @@ class Mt extends Q {
5344
5357
  * @param p3 End point
5345
5358
  * @param t Parameter from 0 to 1
5346
5359
  */
5347
- bezierPoint(t, e, o, i, s) {
5348
- const a = 1 - s, n = a * a, h = n * a, l = s * s, c = l * s;
5360
+ bezierPoint(t, e, o, s, i) {
5361
+ const a = 1 - i, n = a * a, h = n * a, l = i * i, c = l * i;
5349
5362
  return {
5350
- x: h * t.x + 3 * n * s * e.x + 3 * a * l * o.x + c * i.x,
5351
- y: h * t.y + 3 * n * s * e.y + 3 * a * l * o.y + c * i.y
5363
+ x: h * t.x + 3 * n * i * e.x + 3 * a * l * o.x + c * s.x,
5364
+ y: h * t.y + 3 * n * i * e.y + 3 * a * l * o.y + c * s.y
5352
5365
  };
5353
5366
  }
5354
5367
  /**
@@ -5360,14 +5373,14 @@ class Mt extends Q {
5360
5373
  const { points: t } = this.transformData;
5361
5374
  if (t.length === 0)
5362
5375
  return { x: 0, y: 0, width: 0, height: 0 };
5363
- let e = 1 / 0, o = 1 / 0, i = -1 / 0, s = -1 / 0;
5376
+ let e = 1 / 0, o = 1 / 0, s = -1 / 0, i = -1 / 0;
5364
5377
  for (let d = 0; d < t.length; d++) {
5365
5378
  const f = t[d], u = t[(d + 1) % t.length];
5366
5379
  if (d === t.length - 1 && !this.transformData.closed) {
5367
- e = Math.min(e, f.x), o = Math.min(o, f.y), i = Math.max(i, f.x), s = Math.max(s, f.y);
5380
+ e = Math.min(e, f.x), o = Math.min(o, f.y), s = Math.max(s, f.x), i = Math.max(i, f.y);
5368
5381
  break;
5369
5382
  }
5370
- if (e = Math.min(e, f.x), o = Math.min(o, f.y), i = Math.max(i, f.x), s = Math.max(s, f.y), f.handleOut || u.handleIn) {
5383
+ if (e = Math.min(e, f.x), o = Math.min(o, f.y), s = Math.max(s, f.x), i = Math.max(i, f.y), f.handleOut || u.handleIn) {
5371
5384
  const p = { x: f.x, y: f.y }, y = {
5372
5385
  x: f.x + (((h = f.handleOut) == null ? void 0 : h.x) || 0),
5373
5386
  y: f.y + (((l = f.handleOut) == null ? void 0 : l.y) || 0)
@@ -5377,7 +5390,7 @@ class Mt extends Q {
5377
5390
  }, b = { x: u.x, y: u.y }, S = 20;
5378
5391
  for (let v = 0; v <= S; v++) {
5379
5392
  const w = v / S, T = this.bezierPoint(p, y, x, b, w);
5380
- e = Math.min(e, T.x), o = Math.min(o, T.y), i = Math.max(i, T.x), s = Math.max(s, T.y);
5393
+ e = Math.min(e, T.x), o = Math.min(o, T.y), s = Math.max(s, T.x), i = Math.max(i, T.y);
5381
5394
  }
5382
5395
  }
5383
5396
  }
@@ -5385,8 +5398,8 @@ class Mt extends Q {
5385
5398
  return {
5386
5399
  x: e - n,
5387
5400
  y: o - n,
5388
- width: i - e + a,
5389
- height: s - o + a
5401
+ width: s - e + a,
5402
+ height: i - o + a
5390
5403
  };
5391
5404
  }
5392
5405
  /**
@@ -5400,28 +5413,28 @@ class Mt extends Q {
5400
5413
  * Render the path
5401
5414
  */
5402
5415
  render(t, e = !1, o = !1) {
5403
- const { points: i, closed: s, fillEnabled: a, fillColor: n, fillOpacity: h, strokeEnabled: l, strokeColor: c, strokeWidth: g } = this.transformData;
5404
- if (i.length === 0)
5416
+ const { points: s, closed: i, fillEnabled: a, fillColor: n, fillOpacity: h, strokeEnabled: l, strokeColor: c, strokeWidth: g } = this.transformData;
5417
+ if (s.length === 0)
5405
5418
  return;
5406
5419
  t.save(), t.translate(this.x, this.y), t.rotate(D.toRadians(this.rotation));
5407
5420
  const d = this.calculatePathBounds(), f = d.x + d.width / 2, u = d.y + d.height / 2;
5408
- t.translate(-f, -u), t.beginPath(), this.renderPath(t), a && s && n && (t.fillStyle = n, t.globalAlpha = h ?? 1, t.fill()), l && c && g && (t.strokeStyle = c, t.lineWidth = g, t.lineCap = "round", t.lineJoin = "round", t.globalAlpha = 1, t.stroke()), t.restore();
5421
+ t.translate(-f, -u), t.beginPath(), this.renderPath(t), a && i && n && (t.fillStyle = n, t.globalAlpha = h ?? 1, t.fill()), l && c && g && (t.strokeStyle = c, t.lineWidth = g, t.lineCap = "round", t.lineJoin = "round", t.globalAlpha = 1, t.stroke()), t.restore();
5409
5422
  }
5410
5423
  /**
5411
5424
  * Render the path using Canvas API bezier curves
5412
5425
  */
5413
5426
  renderPath(t) {
5414
- var s, a, n, h;
5427
+ var i, a, n, h;
5415
5428
  const { points: e, closed: o } = this.transformData;
5416
5429
  if (e.length === 0) return;
5417
- const i = e[0];
5418
- t.moveTo(i.x, i.y);
5430
+ const s = e[0];
5431
+ t.moveTo(s.x, s.y);
5419
5432
  for (let l = 0; l < e.length; l++) {
5420
5433
  const c = e[l], g = e[(l + 1) % e.length];
5421
5434
  if (l === e.length - 1 && !o)
5422
5435
  break;
5423
5436
  if (c.handleOut || g.handleIn) {
5424
- const f = c.x + (((s = c.handleOut) == null ? void 0 : s.x) || 0), u = c.y + (((a = c.handleOut) == null ? void 0 : a.y) || 0), m = g.x + (((n = g.handleIn) == null ? void 0 : n.x) || 0), p = g.y + (((h = g.handleIn) == null ? void 0 : h.y) || 0);
5437
+ const f = c.x + (((i = c.handleOut) == null ? void 0 : i.x) || 0), u = c.y + (((a = c.handleOut) == null ? void 0 : a.y) || 0), m = g.x + (((n = g.handleIn) == null ? void 0 : n.x) || 0), p = g.y + (((h = g.handleIn) == null ? void 0 : h.y) || 0);
5425
5438
  t.bezierCurveTo(f, u, m, p, g.x, g.y);
5426
5439
  } else
5427
5440
  t.lineTo(g.x, g.y);
@@ -5431,11 +5444,11 @@ class Mt extends Q {
5431
5444
  /**
5432
5445
  * Handle resize - scale all points relative to center
5433
5446
  */
5434
- resize(t, e, o, i) {
5435
- const s = i.transformData.width, a = i.transformData.height;
5436
- if (s === 0 || a === 0)
5447
+ resize(t, e, o, s) {
5448
+ const i = s.transformData.width, a = s.transformData.height;
5449
+ if (i === 0 || a === 0)
5437
5450
  return !1;
5438
- const n = e / s, h = o / a, l = i.transformData.points;
5451
+ const n = e / i, h = o / a, l = s.transformData.points;
5439
5452
  let c = 1 / 0, g = 1 / 0, d = -1 / 0, f = -1 / 0;
5440
5453
  for (const S of l)
5441
5454
  c = Math.min(c, S.x), g = Math.min(g, S.y), d = Math.max(d, S.x), f = Math.max(f, S.y);
@@ -5446,8 +5459,8 @@ class Mt extends Q {
5446
5459
  y: m + (S.y - m) * h,
5447
5460
  handleIn: S.handleIn ? { x: S.handleIn.x * n, y: S.handleIn.y * h } : void 0,
5448
5461
  handleOut: S.handleOut ? { x: S.handleOut.x * n, y: S.handleOut.y * h } : void 0
5449
- })), this.transformData.width = e, this.transformData.height = o, this.rotation = i.rotation;
5450
- const p = this.getFixedCorner(t, i), y = this.getOppositeAnchor(t), x = this.getBoundingBox(), b = this.getCornerOffset(y, x);
5462
+ })), this.transformData.width = e, this.transformData.height = o, this.rotation = s.rotation;
5463
+ const p = this.getFixedCorner(t, s), y = this.getOppositeAnchor(t), x = this.getBoundingBox(), b = this.getCornerOffset(y, x);
5451
5464
  return this.x = p.x - b.x, this.y = p.y - b.y, !0;
5452
5465
  }
5453
5466
  /**
@@ -5479,71 +5492,71 @@ class Mt extends Q {
5479
5492
  width: e.transformData.width,
5480
5493
  height: e.transformData.height
5481
5494
  };
5482
- let i, s;
5495
+ let s, i;
5483
5496
  switch (t) {
5484
5497
  case "top-left":
5485
- i = o.x + o.width, s = o.y + o.height;
5498
+ s = o.x + o.width, i = o.y + o.height;
5486
5499
  break;
5487
5500
  case "top-right":
5488
- i = o.x, s = o.y + o.height;
5501
+ s = o.x, i = o.y + o.height;
5489
5502
  break;
5490
5503
  case "bottom-left":
5491
- i = o.x + o.width, s = o.y;
5504
+ s = o.x + o.width, i = o.y;
5492
5505
  break;
5493
5506
  case "bottom-right":
5494
- i = o.x, s = o.y;
5507
+ s = o.x, i = o.y;
5495
5508
  break;
5496
5509
  case "middle-left":
5497
- i = o.x + o.width, s = o.y + o.height / 2;
5510
+ s = o.x + o.width, i = o.y + o.height / 2;
5498
5511
  break;
5499
5512
  case "middle-right":
5500
- i = o.x, s = o.y + o.height / 2;
5513
+ s = o.x, i = o.y + o.height / 2;
5501
5514
  break;
5502
5515
  case "middle-top":
5503
- i = o.x + o.width / 2, s = o.y + o.height;
5516
+ s = o.x + o.width / 2, i = o.y + o.height;
5504
5517
  break;
5505
5518
  case "middle-bottom":
5506
- i = o.x + o.width / 2, s = o.y;
5519
+ s = o.x + o.width / 2, i = o.y;
5507
5520
  break;
5508
5521
  default:
5509
- i = o.x + o.width / 2, s = o.y + o.height / 2;
5522
+ s = o.x + o.width / 2, i = o.y + o.height / 2;
5510
5523
  }
5511
- return { x: i, y: s };
5524
+ return { x: s, y: i };
5512
5525
  }
5513
5526
  /**
5514
5527
  * Get the offset of a corner from the center
5515
5528
  */
5516
5529
  getCornerOffset(t, e) {
5517
- let o, i;
5530
+ let o, s;
5518
5531
  switch (t) {
5519
5532
  case "top-left":
5520
- o = -e.width / 2, i = -e.height / 2;
5533
+ o = -e.width / 2, s = -e.height / 2;
5521
5534
  break;
5522
5535
  case "top-right":
5523
- o = e.width / 2, i = -e.height / 2;
5536
+ o = e.width / 2, s = -e.height / 2;
5524
5537
  break;
5525
5538
  case "bottom-left":
5526
- o = -e.width / 2, i = e.height / 2;
5539
+ o = -e.width / 2, s = e.height / 2;
5527
5540
  break;
5528
5541
  case "bottom-right":
5529
- o = e.width / 2, i = e.height / 2;
5542
+ o = e.width / 2, s = e.height / 2;
5530
5543
  break;
5531
5544
  case "middle-left":
5532
- o = -e.width / 2, i = 0;
5545
+ o = -e.width / 2, s = 0;
5533
5546
  break;
5534
5547
  case "middle-right":
5535
- o = e.width / 2, i = 0;
5548
+ o = e.width / 2, s = 0;
5536
5549
  break;
5537
5550
  case "middle-top":
5538
- o = 0, i = -e.height / 2;
5551
+ o = 0, s = -e.height / 2;
5539
5552
  break;
5540
5553
  case "middle-bottom":
5541
- o = 0, i = e.height / 2;
5554
+ o = 0, s = e.height / 2;
5542
5555
  break;
5543
5556
  default:
5544
- o = 0, i = 0;
5557
+ o = 0, s = 0;
5545
5558
  }
5546
- return { x: o, y: i };
5559
+ return { x: o, y: s };
5547
5560
  }
5548
5561
  /**
5549
5562
  * Get enabled anchors - all 8 anchors for free resize
@@ -5618,7 +5631,7 @@ const _e = {
5618
5631
  {
5619
5632
  key: "amplitude",
5620
5633
  label: "Wave Amplitude",
5621
- defaultInternalValue: st.amplitude,
5634
+ defaultInternalValue: it.amplitude,
5622
5635
  // Slider 0-100 maps to internal -0.5 to 0.5 (-50% to +50%)
5623
5636
  toSlider: (r) => (r + 0.5) * 100,
5624
5637
  fromSlider: (r) => r / 100 - 0.5,
@@ -5627,7 +5640,7 @@ const _e = {
5627
5640
  {
5628
5641
  key: "frequency",
5629
5642
  label: "Wave Frequency",
5630
- defaultInternalValue: st.frequency,
5643
+ defaultInternalValue: it.frequency,
5631
5644
  step: 5,
5632
5645
  // 5% steps for smoother control
5633
5646
  // Slider 0-100 maps to internal 1 to 5
@@ -5821,17 +5834,17 @@ class ut extends Q {
5821
5834
  getBoundingBox() {
5822
5835
  if (this.children.length === 0)
5823
5836
  return { x: this.x - 50, y: this.y - 50, width: 100, height: 100 };
5824
- let t = 1 / 0, e = 1 / 0, o = -1 / 0, i = -1 / 0;
5825
- return this.children.forEach((s) => {
5826
- const a = s.getVisualBoundingBox();
5827
- this._getRotatedCorners(s, a).forEach((h) => {
5828
- t = Math.min(t, h.x), e = Math.min(e, h.y), o = Math.max(o, h.x), i = Math.max(i, h.y);
5837
+ let t = 1 / 0, e = 1 / 0, o = -1 / 0, s = -1 / 0;
5838
+ return this.children.forEach((i) => {
5839
+ const a = i.getVisualBoundingBox();
5840
+ this._getRotatedCorners(i, a).forEach((h) => {
5841
+ t = Math.min(t, h.x), e = Math.min(e, h.y), o = Math.max(o, h.x), s = Math.max(s, h.y);
5829
5842
  });
5830
5843
  }), {
5831
5844
  x: t,
5832
5845
  y: e,
5833
5846
  width: o - t,
5834
- height: i - e
5847
+ height: s - e
5835
5848
  };
5836
5849
  }
5837
5850
  /**
@@ -5855,7 +5868,7 @@ class ut extends Q {
5855
5868
  * Get the four corners of an element's bounding box in world space
5856
5869
  */
5857
5870
  _getRotatedCorners(t, e) {
5858
- const o = new R(t), i = e.x + e.width / 2, s = e.y + e.height / 2, a = i - t.x, n = s - t.y;
5871
+ const o = new R(t), s = e.x + e.width / 2, i = e.y + e.height / 2, a = s - t.x, n = i - t.y;
5859
5872
  return [
5860
5873
  { localX: a - e.width / 2, localY: n - e.height / 2 },
5861
5874
  { localX: a + e.width / 2, localY: n - e.height / 2 },
@@ -5895,8 +5908,8 @@ class ut extends Q {
5895
5908
  * Elements with isClipping=true clip all elements below them in the group
5896
5909
  */
5897
5910
  render(t, e = !1, o = !1) {
5898
- const i = this.children.filter((a) => a.visible !== !1);
5899
- i.some((a) => a.isClipping) ? Te()(t, i) : i.forEach((a) => {
5911
+ const s = this.children.filter((a) => a.visible !== !1);
5912
+ s.some((a) => a.isClipping) ? Te()(t, s) : s.forEach((a) => {
5900
5913
  a.render(t, !1);
5901
5914
  }), e ? this._renderGroupOutline(t, 1) : o && this._renderGroupOutline(t, 0.3);
5902
5915
  }
@@ -5907,8 +5920,8 @@ class ut extends Q {
5907
5920
  _renderGroupOutline(t, e = 1) {
5908
5921
  const o = this.getOrientedBoundingBox();
5909
5922
  t.save(), t.globalAlpha = e, t.strokeStyle = Wt(), t.lineWidth = 2, t.setLineDash([5, 5]);
5910
- const i = this._rotationCenterX || this.x, s = this._rotationCenterY || this.y;
5911
- this.rotation !== 0 && (t.translate(i, s), t.rotate(-this.rotation * Math.PI / 180), t.translate(-i, -s)), t.strokeRect(o.x, o.y, o.width, o.height), t.setLineDash([]), t.restore();
5923
+ const s = this._rotationCenterX || this.x, i = this._rotationCenterY || this.y;
5924
+ this.rotation !== 0 && (t.translate(s, i), t.rotate(-this.rotation * Math.PI / 180), t.translate(-s, -i)), t.strokeRect(o.x, o.y, o.width, o.height), t.setLineDash([]), t.restore();
5912
5925
  }
5913
5926
  /**
5914
5927
  * Get oriented bounding box (uses cached base dimensions for stability during rotation)
@@ -5925,13 +5938,13 @@ class ut extends Q {
5925
5938
  if (this._baseBBoxWidth > 0 && this._baseBBoxHeight > 0)
5926
5939
  t = this._baseBBoxWidth, e = this._baseBBoxHeight;
5927
5940
  else {
5928
- const s = this.getBoundingBox();
5929
- t = s.width, e = s.height, this._baseBBoxWidth = t, this._baseBBoxHeight = e;
5941
+ const i = this.getBoundingBox();
5942
+ t = i.width, e = i.height, this._baseBBoxWidth = t, this._baseBBoxHeight = e;
5930
5943
  }
5931
- const o = this._rotationCenterX || this.x, i = this._rotationCenterY || this.y;
5944
+ const o = this._rotationCenterX || this.x, s = this._rotationCenterY || this.y;
5932
5945
  return {
5933
5946
  x: o - t / 2,
5934
- y: i - e / 2,
5947
+ y: s - e / 2,
5935
5948
  width: t,
5936
5949
  height: e
5937
5950
  };
@@ -5950,40 +5963,40 @@ class ut extends Q {
5950
5963
  setRotation(t) {
5951
5964
  const e = t - this.rotation;
5952
5965
  this.rotation = t;
5953
- const o = this._rotationCenterX || this.x, i = this._rotationCenterY || this.y;
5954
- this.children.forEach((s) => {
5955
- const a = R.rotatePointAroundAnchor(s.x, s.y, o, i, e);
5956
- s.x = a.x, s.y = a.y, s.setRotation(s.rotation + e);
5957
- }), this.x = o, this.y = i;
5966
+ const o = this._rotationCenterX || this.x, s = this._rotationCenterY || this.y;
5967
+ this.children.forEach((i) => {
5968
+ const a = R.rotatePointAroundAnchor(i.x, i.y, o, s, e);
5969
+ i.x = a.x, i.y = a.y, i.setRotation(i.rotation + e);
5970
+ }), this.x = o, this.y = s;
5958
5971
  }
5959
5972
  /**
5960
5973
  * Resize the group (scales all children proportionally)
5961
5974
  * Uses the same fixed-corner approach as multi-selection resize
5962
5975
  */
5963
- resize(t, e, o, i) {
5964
- if (!i.childrenStartData || !i.width || !i.height)
5976
+ resize(t, e, o, s) {
5977
+ if (!s.childrenStartData || !s.width || !s.height)
5965
5978
  return;
5966
- const s = e / i.width, a = o / i.height, n = (s + a) / 2;
5979
+ const i = e / s.width, a = o / s.height, n = (i + a) / 2;
5967
5980
  let h, l;
5968
5981
  switch (t) {
5969
5982
  case "top-left":
5970
- h = i.width / 2, l = i.height / 2;
5983
+ h = s.width / 2, l = s.height / 2;
5971
5984
  break;
5972
5985
  case "top-right":
5973
- h = -i.width / 2, l = i.height / 2;
5986
+ h = -s.width / 2, l = s.height / 2;
5974
5987
  break;
5975
5988
  case "bottom-left":
5976
- h = i.width / 2, l = -i.height / 2;
5989
+ h = s.width / 2, l = -s.height / 2;
5977
5990
  break;
5978
5991
  case "bottom-right":
5979
- h = -i.width / 2, l = -i.height / 2;
5992
+ h = -s.width / 2, l = -s.height / 2;
5980
5993
  break;
5981
5994
  default:
5982
5995
  h = 0, l = 0;
5983
5996
  }
5984
- const c = -i.rotation * Math.PI / 180, g = Math.cos(c), d = Math.sin(c), f = i.x + (h * g - l * d), u = i.y + (h * d + l * g);
5997
+ const c = -s.rotation * Math.PI / 180, g = Math.cos(c), d = Math.sin(c), f = s.x + (h * g - l * d), u = s.y + (h * d + l * g);
5985
5998
  this.children.forEach((y, x) => {
5986
- const b = i.childrenStartData[x], S = b.x - f, v = b.y - u, w = f + S * n, T = u + v * n;
5999
+ const b = s.childrenStartData[x], S = b.x - f, v = b.y - u, w = f + S * n, T = u + v * n;
5987
6000
  if (y.x = w, y.y = T, y instanceof pt) {
5988
6001
  const F = b.transformData, A = F.width * n, M = F.height * n;
5989
6002
  y.transformData.width = A, y.transformData.height = M;
@@ -5994,8 +6007,8 @@ class ut extends Q {
5994
6007
  const F = (b.width ?? 0) * n, A = (b.height ?? 0) * n;
5995
6008
  y.resize(t, F, A, b);
5996
6009
  }
5997
- }), this._baseBBoxWidth = i.width * n, this._baseBBoxHeight = i.height * n;
5998
- const m = i.x - f, p = i.y - u;
6010
+ }), this._baseBBoxWidth = s.width * n, this._baseBBoxHeight = s.height * n;
6011
+ const m = s.x - f, p = s.y - u;
5999
6012
  this.x = f + m * n, this.y = u + p * n, this._rotationCenterX = this.x, this._rotationCenterY = this.y;
6000
6013
  }
6001
6014
  /**
@@ -6003,16 +6016,16 @@ class ut extends Q {
6003
6016
  * Use cached base dimensions instead of axis-aligned bbox for consistency with visual border
6004
6017
  */
6005
6018
  getTransformStartData() {
6006
- const t = this._baseBBoxWidth > 0 ? this._baseBBoxWidth : this.getBoundingBox().width, e = this._baseBBoxHeight > 0 ? this._baseBBoxHeight : this.getBoundingBox().height, o = this._rotationCenterX || this.x, i = this._rotationCenterY || this.y;
6019
+ const t = this._baseBBoxWidth > 0 ? this._baseBBoxWidth : this.getBoundingBox().width, e = this._baseBBoxHeight > 0 ? this._baseBBoxHeight : this.getBoundingBox().height, o = this._rotationCenterX || this.x, s = this._rotationCenterY || this.y;
6007
6020
  return {
6008
6021
  id: this.id,
6009
6022
  x: o,
6010
- y: i,
6023
+ y: s,
6011
6024
  width: t,
6012
6025
  height: e,
6013
6026
  rotation: this.rotation,
6014
6027
  transformData: this.transformData,
6015
- childrenStartData: this.children.map((s) => s.getTransformStartData())
6028
+ childrenStartData: this.children.map((i) => i.getTransformStartData())
6016
6029
  };
6017
6030
  }
6018
6031
  /**
@@ -6020,10 +6033,10 @@ class ut extends Q {
6020
6033
  * This allows clicking anywhere within the selection border to drag the group
6021
6034
  */
6022
6035
  hitTest(t, e) {
6023
- const o = this.getOrientedBoundingBox(), i = this._rotationCenterX || this.x, s = this._rotationCenterY || this.y;
6036
+ const o = this.getOrientedBoundingBox(), s = this._rotationCenterX || this.x, i = this._rotationCenterY || this.y;
6024
6037
  if (this.rotation === 0)
6025
6038
  return t >= o.x && t <= o.x + o.width && e >= o.y && e <= o.y + o.height;
6026
- const a = this.rotation * Math.PI / 180, n = Math.cos(a), h = Math.sin(a), l = t - i, c = e - s, g = i + (l * n - c * h), d = s + (l * h + c * n);
6039
+ const a = this.rotation * Math.PI / 180, n = Math.cos(a), h = Math.sin(a), l = t - s, c = e - i, g = s + (l * n - c * h), d = i + (l * h + c * n);
6027
6040
  return g >= o.x && g <= o.x + o.width && d >= o.y && d <= o.y + o.height;
6028
6041
  }
6029
6042
  /**
@@ -6057,7 +6070,13 @@ class ut extends Q {
6057
6070
  // Children are element instances here; the constructor handles both instances and configs
6058
6071
  children: t
6059
6072
  });
6060
- return e._baseBBoxWidth = this._baseBBoxWidth, e._baseBBoxHeight = this._baseBBoxHeight, e._rotationCenterX = this._rotationCenterX, e._rotationCenterY = this._rotationCenterY, e.opacity = this.opacity, e.name = this.name, e.visible = this.visible, e.locked = this.locked, this.blendMode && (e.blendMode = this.blendMode), this.knockoutParts && (e.knockoutParts = { ...this.knockoutParts }), this.stroke && (e.stroke = { ...this.stroke }), this.masks && (e.masks = this.masks.map((o) => ({ ...o }))), this.distressEffect && (e.distressEffect = { ...this.distressEffect }), e;
6073
+ return e._baseBBoxWidth = this._baseBBoxWidth, e._baseBBoxHeight = this._baseBBoxHeight, e._rotationCenterX = this._rotationCenterX, e._rotationCenterY = this._rotationCenterY, e.opacity = this.opacity, e.name = this.name, e.visible = this.visible, e.locked = this.locked, this.blendMode && (e.blendMode = this.blendMode), this.knockoutParts && (e.knockoutParts = { ...this.knockoutParts }), this.stroke && (e.stroke = {
6074
+ ...this.stroke,
6075
+ ...this.stroke.dashArray && { dashArray: [...this.stroke.dashArray] }
6076
+ }), this.masks && (e.masks = this.masks.map((o) => ({
6077
+ ...o,
6078
+ maskElement: structuredClone(o.maskElement)
6079
+ }))), this.distressEffect && (e.distressEffect = { ...this.distressEffect }), e;
6061
6080
  }
6062
6081
  /**
6063
6082
  * Add a child to the group
@@ -6084,9 +6103,9 @@ class ut extends Q {
6084
6103
  */
6085
6104
  hitTestChild(t, e) {
6086
6105
  for (let o = this.children.length - 1; o >= 0; o--) {
6087
- const i = this.children[o];
6088
- if (i.hitTest(t, e))
6089
- return i;
6106
+ const s = this.children[o];
6107
+ if (s.hitTest(t, e))
6108
+ return s;
6090
6109
  }
6091
6110
  return null;
6092
6111
  }
@@ -6131,8 +6150,8 @@ class Z {
6131
6150
  getAllByName(t) {
6132
6151
  const e = [];
6133
6152
  for (const o of this.order) {
6134
- const i = this.byId.get(o);
6135
- i && i.name === t && e.push(i);
6153
+ const s = this.byId.get(o);
6154
+ s && s.name === t && e.push(s);
6136
6155
  }
6137
6156
  return e;
6138
6157
  }
@@ -6153,8 +6172,8 @@ class Z {
6153
6172
  const o = this.clone();
6154
6173
  if (t !== e.id) {
6155
6174
  o.byId.delete(t);
6156
- const i = o.order.indexOf(t);
6157
- i !== -1 && (o.order[i] = e.id);
6175
+ const s = o.order.indexOf(t);
6176
+ s !== -1 && (o.order[s] = e.id);
6158
6177
  }
6159
6178
  return o.byId.set(e.id, e), o;
6160
6179
  }
@@ -6167,8 +6186,8 @@ class Z {
6167
6186
  insertAfter(t, e) {
6168
6187
  const o = this.clone();
6169
6188
  o.byId.set(t.id, t);
6170
- const i = o.order.indexOf(e);
6171
- return i !== -1 ? o.order.splice(i + 1, 0, t.id) : o.order.push(t.id), o;
6189
+ const s = o.order.indexOf(e);
6190
+ return s !== -1 ? o.order.splice(s + 1, 0, t.id) : o.order.push(t.id), o;
6172
6191
  }
6173
6192
  /** Remove an element by ID. */
6174
6193
  remove(t) {
@@ -6179,7 +6198,7 @@ class Z {
6179
6198
  /** Reorder element to a new index in the render order. */
6180
6199
  reorder(t, e) {
6181
6200
  const o = this.clone();
6182
- return o.order = o.order.filter((i) => i !== t), o.order.splice(e, 0, t), o;
6201
+ return o.order = o.order.filter((s) => s !== t), o.order.splice(e, 0, t), o;
6183
6202
  }
6184
6203
  /**
6185
6204
  * Apply a batch update: replace elements whose IDs match.
@@ -6247,9 +6266,9 @@ class U {
6247
6266
  throw new Error("Command.undo() must be implemented");
6248
6267
  }
6249
6268
  }
6250
- class ti extends U {
6251
- constructor(t, e, o, i) {
6252
- super(), this.elementId = t, this.oldElement = e ? e.clone() : null, this.newElement = o ? o.clone() : null, this.onUpdate = i;
6269
+ class ts extends U {
6270
+ constructor(t, e, o, s) {
6271
+ super(), this.elementId = t, this.oldElement = e ? e.clone() : null, this.newElement = o ? o.clone() : null, this.onUpdate = s;
6253
6272
  }
6254
6273
  execute() {
6255
6274
  this.newElement && this.onUpdate(this.newElement);
@@ -6258,7 +6277,7 @@ class ti extends U {
6258
6277
  this.oldElement && this.onUpdate(this.oldElement);
6259
6278
  }
6260
6279
  }
6261
- class ei extends U {
6280
+ class es extends U {
6262
6281
  constructor(t, e, o) {
6263
6282
  super(), this.element = t.clone(), this.onAdd = e, this.onRemove = o;
6264
6283
  }
@@ -6269,7 +6288,7 @@ class ei extends U {
6269
6288
  this.onRemove(this.element.id);
6270
6289
  }
6271
6290
  }
6272
- class oi extends U {
6291
+ class os extends U {
6273
6292
  constructor(t, e, o) {
6274
6293
  super(), this.element = t.clone(), this.onAdd = e, this.onRemove = o;
6275
6294
  }
@@ -6357,7 +6376,7 @@ class ct {
6357
6376
  };
6358
6377
  }
6359
6378
  }
6360
- class ii extends U {
6379
+ class ss extends U {
6361
6380
  constructor(t, e) {
6362
6381
  super(), this.artboard = t.clone(), this.artboardManager = e;
6363
6382
  }
@@ -6377,7 +6396,7 @@ class ii extends U {
6377
6396
  this.artboardManager.deleteArtboard(this.artboard.id);
6378
6397
  }
6379
6398
  }
6380
- class si extends U {
6399
+ class is extends U {
6381
6400
  constructor(t, e) {
6382
6401
  super(), this.artboard = t.clone(), this.artboardManager = e, this.elementsOnArtboard = t.getElementIds();
6383
6402
  }
@@ -6400,9 +6419,9 @@ class si extends U {
6400
6419
  });
6401
6420
  }
6402
6421
  }
6403
- class ri extends U {
6404
- constructor(t, e, o, i) {
6405
- super(), this.artboardId = t, this.oldProperties = { ...e }, this.newProperties = { ...o }, this.artboardManager = i;
6422
+ class rs extends U {
6423
+ constructor(t, e, o, s) {
6424
+ super(), this.artboardId = t, this.oldProperties = { ...e }, this.newProperties = { ...o }, this.artboardManager = s;
6406
6425
  }
6407
6426
  execute() {
6408
6427
  this.artboardManager.updateArtboard(this.artboardId, this.newProperties);
@@ -6411,9 +6430,9 @@ class ri extends U {
6411
6430
  this.artboardManager.updateArtboard(this.artboardId, this.oldProperties);
6412
6431
  }
6413
6432
  }
6414
- class ni extends U {
6415
- constructor(t, e, o, i, s) {
6416
- super(), this.draggedId = t, this.targetId = e, this.position = o, this.oldOrder = [...i], this.onReorder = s, this.newOrder = this.calculateNewOrder();
6433
+ class ns extends U {
6434
+ constructor(t, e, o, s, i) {
6435
+ super(), this.draggedId = t, this.targetId = e, this.position = o, this.oldOrder = [...s], this.onReorder = i, this.newOrder = this.calculateNewOrder();
6417
6436
  }
6418
6437
  calculateNewOrder() {
6419
6438
  const t = [...this.oldOrder], e = t.indexOf(this.draggedId);
@@ -6421,8 +6440,8 @@ class ni extends U {
6421
6440
  t.splice(e, 1);
6422
6441
  const o = t.indexOf(this.targetId);
6423
6442
  if (o === -1) return t;
6424
- const i = this.position === "before" ? o : o + 1;
6425
- return t.splice(i, 0, this.draggedId), t;
6443
+ const s = this.position === "before" ? o : o + 1;
6444
+ return t.splice(s, 0, this.draggedId), t;
6426
6445
  }
6427
6446
  execute() {
6428
6447
  this.onReorder(this.newOrder);
@@ -6432,7 +6451,7 @@ class ni extends U {
6432
6451
  }
6433
6452
  }
6434
6453
  const Ge = mt("HybridHistoryManager");
6435
- class ai {
6454
+ class as {
6436
6455
  constructor(t, e = 50) {
6437
6456
  this.commandExecutedCallbacks = [], this.globalHistory = new ct(e), this.artboardHistories = /* @__PURE__ */ new Map(), this.lastOperation = null, this.artboardManager = t, this.maxHistorySize = e;
6438
6457
  }
@@ -6450,11 +6469,11 @@ class ai {
6450
6469
  * Notify all callbacks that a command was executed
6451
6470
  */
6452
6471
  notifyCommandExecuted(t, e, o) {
6453
- for (const i of this.commandExecutedCallbacks)
6472
+ for (const s of this.commandExecutedCallbacks)
6454
6473
  try {
6455
- i(t, e, o);
6456
- } catch (s) {
6457
- Ge.error("Error in command executed callback:", s);
6474
+ s(t, e, o);
6475
+ } catch (i) {
6476
+ Ge.error("Error in command executed callback:", i);
6458
6477
  }
6459
6478
  }
6460
6479
  /**
@@ -6493,8 +6512,8 @@ class ai {
6493
6512
  artboardId: t,
6494
6513
  timestamp: Date.now()
6495
6514
  };
6496
- const i = o.history[o.currentIndex];
6497
- this.notifyCommandExecuted(i, "artboard", t);
6515
+ const s = o.history[o.currentIndex];
6516
+ this.notifyCommandExecuted(s, "artboard", t);
6498
6517
  }
6499
6518
  /**
6500
6519
  * Execute a command on a specific artboard
@@ -6660,12 +6679,12 @@ class ai {
6660
6679
  */
6661
6680
  getState() {
6662
6681
  const t = this.globalHistory.getState(), e = /* @__PURE__ */ new Map();
6663
- return this.artboardHistories.forEach((o, i) => {
6664
- const s = o.getState();
6665
- e.set(i, {
6666
- canUndo: s.canUndo,
6667
- canRedo: s.canRedo,
6668
- historySize: s.historySize
6682
+ return this.artboardHistories.forEach((o, s) => {
6683
+ const i = o.getState();
6684
+ e.set(s, {
6685
+ canUndo: i.canUndo,
6686
+ canRedo: i.canRedo,
6687
+ historySize: i.historySize
6669
6688
  });
6670
6689
  }), {
6671
6690
  global: {
@@ -6743,8 +6762,8 @@ class Ve {
6743
6762
  evictOldestFont() {
6744
6763
  if (this.fontCache.size <= this.MAX_CACHE_SIZE) return;
6745
6764
  let t = null, e = Date.now();
6746
- this.fontCache.forEach((o, i) => {
6747
- o.timestamp < e && (e = o.timestamp, t = i);
6765
+ this.fontCache.forEach((o, s) => {
6766
+ o.timestamp < e && (e = o.timestamp, t = s);
6748
6767
  }), t && this.fontCache.delete(t);
6749
6768
  }
6750
6769
  /**
@@ -6764,7 +6783,7 @@ class Ve {
6764
6783
  */
6765
6784
  async extractFontFileUrl(t, e = 400) {
6766
6785
  try {
6767
- const o = this.getGoogleFontUrl(t, e), s = await (await fetch(o)).text(), a = /@font-face\s*{([^}]*)}/g, n = Array.from(s.matchAll(a));
6786
+ const o = this.getGoogleFontUrl(t, e), i = await (await fetch(o)).text(), a = /@font-face\s*{([^}]*)}/g, n = Array.from(i.matchAll(a));
6768
6787
  if (n.length === 0)
6769
6788
  return N.warn("No @font-face found in CSS"), null;
6770
6789
  let h = null, l = -1;
@@ -6789,24 +6808,24 @@ class Ve {
6789
6808
  const o = `${t}-${e}`;
6790
6809
  if (this.failedFonts.has(o))
6791
6810
  return null;
6792
- const i = this.fontCache.get(o);
6793
- if (i && Date.now() - i.timestamp < this.CACHE_DURATION)
6794
- return i.timestamp = Date.now(), i.font;
6811
+ const s = this.fontCache.get(o);
6812
+ if (s && Date.now() - s.timestamp < this.CACHE_DURATION)
6813
+ return s.timestamp = Date.now(), s.font;
6795
6814
  try {
6796
- const s = await this.extractFontFileUrl(t, e);
6797
- if (!s)
6815
+ const i = await this.extractFontFileUrl(t, e);
6816
+ if (!i)
6798
6817
  return this.failedFonts.add(o), null;
6799
- const a = await fetch(s);
6818
+ const a = await fetch(i);
6800
6819
  if (!a.ok)
6801
6820
  return N.error(`Font fetch failed: ${a.status} ${a.statusText}`), this.failedFonts.add(o), null;
6802
6821
  const n = await a.arrayBuffer(), h = new Uint8Array(n), c = (await $e()).create(h), g = "fonts" in c ? c.fonts[0] : c;
6803
6822
  return this.fontCache.set(o, {
6804
6823
  font: g,
6805
- url: s,
6824
+ url: i,
6806
6825
  timestamp: Date.now()
6807
6826
  }), this.evictOldestFont(), g;
6808
- } catch (s) {
6809
- return N.error(`Error loading font ${t}:`, s), this.failedFonts.add(o), null;
6827
+ } catch (i) {
6828
+ return N.error(`Error loading font ${t}:`, i), this.failedFonts.add(o), null;
6810
6829
  }
6811
6830
  }
6812
6831
  /**
@@ -6814,8 +6833,8 @@ class Ve {
6814
6833
  * Returns null if font is not cached - font should be pre-loaded before rendering
6815
6834
  */
6816
6835
  getFontSync(t, e = 400) {
6817
- const o = `${t}-${e}`, i = this.fontCache.get(o);
6818
- return i && Date.now() - i.timestamp < this.CACHE_DURATION ? (i.timestamp = Date.now(), i.font) : null;
6836
+ const o = `${t}-${e}`, s = this.fontCache.get(o);
6837
+ return s && Date.now() - s.timestamp < this.CACHE_DURATION ? (s.timestamp = Date.now(), s.font) : null;
6819
6838
  }
6820
6839
  /**
6821
6840
  * Clear font cache (useful for debugging or forcing reload)
@@ -6835,13 +6854,13 @@ class Ve {
6835
6854
  var n, h;
6836
6855
  if (this.isSystemFont(t))
6837
6856
  return [];
6838
- const i = await this.loadFont(t, e);
6839
- if (!i)
6857
+ const s = await this.loadFont(t, e);
6858
+ if (!s)
6840
6859
  return [];
6841
- const s = [], a = Math.min(i.numGlyphs, o);
6860
+ const i = [], a = Math.min(s.numGlyphs, o);
6842
6861
  for (let l = 0; l < a; l++)
6843
6862
  try {
6844
- const c = i.getGlyph(l);
6863
+ const c = s.getGlyph(l);
6845
6864
  if (!c || !c.name || c.name === ".notdef" || c.name.startsWith(".null"))
6846
6865
  continue;
6847
6866
  const g = c.codePoints || [];
@@ -6866,42 +6885,42 @@ class Ve {
6866
6885
  const m = c.name.toLowerCase();
6867
6886
  if (m.includes("swash") || m.includes("cswh") ? u = "swash" : c.name.match(/\.(alt|ss\d+|cv\d+|salt|ornament)/) || c.name.match(/_\d+$/) ? u = "stylistic" : m.match(/liga|dlig/) && (u = "ligature"), u === "default")
6868
6887
  continue;
6869
- d && d.length > 0 && s.push({
6888
+ d && d.length > 0 && i.push({
6870
6889
  glyphIndex: c.id,
6871
6890
  unicode: d,
6872
6891
  name: f,
6873
6892
  category: u,
6874
- previewDataUrl: this.generateGlyphPreview(i, c.id, 80)
6893
+ previewDataUrl: this.generateGlyphPreview(s, c.id, 80)
6875
6894
  });
6876
6895
  } catch {
6877
6896
  }
6878
- return s;
6897
+ return i;
6879
6898
  }
6880
6899
  /**
6881
6900
  * Get glyph alternates for a specific character
6882
6901
  */
6883
6902
  async getGlyphAlternates(t, e, o = 400) {
6884
6903
  var l, c, g, d;
6885
- const i = await this.loadFont(t, o);
6886
- if (!i)
6904
+ const s = await this.loadFont(t, o);
6905
+ if (!s)
6887
6906
  return [];
6888
- const s = [], a = e.codePointAt(0);
6907
+ const i = [], a = e.codePointAt(0);
6889
6908
  if (a === void 0)
6890
6909
  return [];
6891
- const n = i.glyphForCodePoint(a);
6892
- n && s.push({
6910
+ const n = s.glyphForCodePoint(a);
6911
+ n && i.push({
6893
6912
  glyphIndex: n.id,
6894
6913
  unicode: e,
6895
6914
  name: n.name || "Default",
6896
6915
  category: "default",
6897
- previewDataUrl: this.generateGlyphPreview(i, n.id, 80)
6916
+ previewDataUrl: this.generateGlyphPreview(s, n.id, 80)
6898
6917
  });
6899
6918
  const h = n == null ? void 0 : n.name;
6900
6919
  if (h) {
6901
6920
  let f = 0;
6902
- for (let u = 0; u < i.numGlyphs; u++)
6921
+ for (let u = 0; u < s.numGlyphs; u++)
6903
6922
  try {
6904
- const m = i.getGlyph(u);
6923
+ const m = s.getGlyph(u);
6905
6924
  if (!m || !m.name) continue;
6906
6925
  if ([
6907
6926
  new RegExp(`^${h}\\.(swash|alt|ss\\d+|salt|ornament)`, "i"),
@@ -6919,19 +6938,19 @@ class Ve {
6919
6938
  const b = (c = m.name.match(/\.ss(\d+)/)) == null ? void 0 : c[1];
6920
6939
  x = `${e} Stylistic Set ${b}`;
6921
6940
  }
6922
- s.push({
6941
+ i.push({
6923
6942
  glyphIndex: m.id,
6924
6943
  unicode: e,
6925
6944
  name: x,
6926
6945
  category: "stylistic",
6927
- previewDataUrl: this.generateGlyphPreview(i, m.id, 80)
6946
+ previewDataUrl: this.generateGlyphPreview(s, m.id, 80)
6928
6947
  });
6929
6948
  }
6930
6949
  } catch {
6931
6950
  }
6932
6951
  }
6933
- if (i.GSUB) {
6934
- const f = i.GSUB;
6952
+ if (s.GSUB) {
6953
+ const f = s.GSUB;
6935
6954
  if (f.featureList)
6936
6955
  for (const u of f.featureList) {
6937
6956
  const m = u.tag;
@@ -6945,12 +6964,12 @@ class Ve {
6945
6964
  if (!b) continue;
6946
6965
  if (this.getCoverageIndex(b, n.id) !== -1) {
6947
6966
  const v = this.getSubstituteGlyph(x, n.id);
6948
- v !== null && s.push({
6967
+ v !== null && i.push({
6949
6968
  glyphIndex: v,
6950
6969
  unicode: e,
6951
6970
  name: `${e} (${m})`,
6952
6971
  category: this.categorizeFeature(m),
6953
- previewDataUrl: this.generateGlyphPreview(i, v, 80)
6972
+ previewDataUrl: this.generateGlyphPreview(s, v, 80)
6954
6973
  });
6955
6974
  }
6956
6975
  }
@@ -6963,12 +6982,12 @@ class Ve {
6963
6982
  const w = v.alternateSets[S];
6964
6983
  if (w)
6965
6984
  for (const T of w)
6966
- s.push({
6985
+ i.push({
6967
6986
  glyphIndex: T,
6968
6987
  unicode: e,
6969
6988
  name: `${e} (${m} alt)`,
6970
6989
  category: this.categorizeFeature(m),
6971
- previewDataUrl: this.generateGlyphPreview(i, T, 80)
6990
+ previewDataUrl: this.generateGlyphPreview(s, T, 80)
6972
6991
  });
6973
6992
  }
6974
6993
  }
@@ -6976,7 +6995,7 @@ class Ve {
6976
6995
  }
6977
6996
  }
6978
6997
  }
6979
- return s;
6998
+ return i;
6980
6999
  }
6981
7000
  /**
6982
7001
  * Get available OpenType features for a font
@@ -6986,38 +7005,38 @@ class Ve {
6986
7005
  if (!o)
6987
7006
  return N.warn(`Font ${t} failed to load`), [];
6988
7007
  try {
6989
- const i = [];
7008
+ const s = [];
6990
7009
  if (o.GSUB && o.GSUB.featureList) {
6991
- const s = /* @__PURE__ */ new Set();
7010
+ const i = /* @__PURE__ */ new Set();
6992
7011
  for (const a of o.GSUB.featureList)
6993
- a.tag && s.add(a.tag);
6994
- i.push(...Array.from(s));
7012
+ a.tag && i.add(a.tag);
7013
+ s.push(...Array.from(i));
6995
7014
  }
6996
7015
  if (o.GPOS && o.GPOS.featureList) {
6997
- const s = /* @__PURE__ */ new Set();
7016
+ const i = /* @__PURE__ */ new Set();
6998
7017
  for (const a of o.GPOS.featureList)
6999
- a.tag && s.add(a.tag);
7000
- i.push(...Array.from(s));
7018
+ a.tag && i.add(a.tag);
7019
+ s.push(...Array.from(i));
7001
7020
  }
7002
- return i;
7003
- } catch (i) {
7004
- return N.error(`Error getting features for ${t}:`, i), [];
7021
+ return s;
7022
+ } catch (s) {
7023
+ return N.error(`Error getting features for ${t}:`, s), [];
7005
7024
  }
7006
7025
  }
7007
7026
  /**
7008
7027
  * Generate a preview image for a glyph
7009
7028
  */
7010
7029
  generateGlyphPreview(t, e, o = 80) {
7011
- const i = document.createElement("canvas");
7012
- i.width = o, i.height = o;
7013
- const s = i.getContext("2d");
7014
- if (!s)
7030
+ const s = document.createElement("canvas");
7031
+ s.width = o, s.height = o;
7032
+ const i = s.getContext("2d");
7033
+ if (!i)
7015
7034
  return "";
7016
7035
  try {
7017
7036
  const a = t.getGlyph(e);
7018
7037
  if (!a)
7019
7038
  return "";
7020
- s.clearRect(0, 0, o, o);
7039
+ i.clearRect(0, 0, o, o);
7021
7040
  const n = a.bbox;
7022
7041
  if (!n)
7023
7042
  return "";
@@ -7028,7 +7047,7 @@ class Ve {
7028
7047
  if (!p)
7029
7048
  return "";
7030
7049
  const y = new Path2D(p);
7031
- return s.save(), s.translate(u, m), s.scale(g, -g), s.translate(-d, -f), s.fillStyle = "#000000", s.fill(y), s.restore(), i.toDataURL("image/png");
7050
+ return i.save(), i.translate(u, m), i.scale(g, -g), i.translate(-d, -f), i.fillStyle = "#000000", i.fill(y), i.restore(), s.toDataURL("image/png");
7032
7051
  } catch (a) {
7033
7052
  return N.error("Error generating glyph preview:", a), "";
7034
7053
  }
@@ -7091,10 +7110,10 @@ class Ve {
7091
7110
  return t.glyphs.indexOf(e);
7092
7111
  if (t.format === 2 && t.ranges) {
7093
7112
  const o = t.ranges;
7094
- for (let i = 0; i < o.length; i++) {
7095
- const s = o[i];
7096
- if (e >= s.start && e <= s.end)
7097
- return s.index + (e - s.start);
7113
+ for (let s = 0; s < o.length; s++) {
7114
+ const i = o[s];
7115
+ if (e >= i.start && e <= i.end)
7116
+ return i.index + (e - i.start);
7098
7117
  }
7099
7118
  }
7100
7119
  return -1;
@@ -7107,9 +7126,9 @@ class Ve {
7107
7126
  if (t.substFormat === 1 && typeof t.deltaGlyphId == "number")
7108
7127
  return e + t.deltaGlyphId;
7109
7128
  if (t.substFormat === 2 && t.substitute) {
7110
- const o = this.getCoverageIndex(t.coverage, e), i = t.substitute;
7111
- if (o !== -1 && i[o] !== void 0)
7112
- return i[o];
7129
+ const o = this.getCoverageIndex(t.coverage, e), s = t.substitute;
7130
+ if (o !== -1 && s[o] !== void 0)
7131
+ return s[o];
7113
7132
  }
7114
7133
  return null;
7115
7134
  }
@@ -7120,9 +7139,9 @@ class Ve {
7120
7139
  const o = await this.loadFont(t, e);
7121
7140
  if (!o)
7122
7141
  return 0;
7123
- let i = 0;
7124
- const s = Math.min(o.numGlyphs, 1500);
7125
- for (let a = 0; a < s; a++)
7142
+ let s = 0;
7143
+ const i = Math.min(o.numGlyphs, 1500);
7144
+ for (let a = 0; a < i; a++)
7126
7145
  try {
7127
7146
  const n = o.getGlyph(a);
7128
7147
  if (!n || !n.name || n.name === ".notdef" || n.name.startsWith(".null"))
@@ -7135,10 +7154,10 @@ class Ve {
7135
7154
  }
7136
7155
  let c = "default";
7137
7156
  const g = n.name.toLowerCase();
7138
- g.includes("swash") || g.includes("cswh") ? c = "swash" : n.name.match(/\.(alt|ss\d+|cv\d+|salt|ornament)/) || n.name.match(/_\d+$/) ? c = "stylistic" : g.match(/liga|dlig/) && (c = "ligature"), c !== "default" && l && l.length > 0 && i++;
7157
+ g.includes("swash") || g.includes("cswh") ? c = "swash" : n.name.match(/\.(alt|ss\d+|cv\d+|salt|ornament)/) || n.name.match(/_\d+$/) ? c = "stylistic" : g.match(/liga|dlig/) && (c = "ligature"), c !== "default" && l && l.length > 0 && s++;
7139
7158
  } catch {
7140
7159
  }
7141
- return i;
7160
+ return s;
7142
7161
  }
7143
7162
  /**
7144
7163
  * Get cache statistics
@@ -7150,7 +7169,7 @@ class Ve {
7150
7169
  };
7151
7170
  }
7152
7171
  }
7153
- const hi = new Ve();
7172
+ const hs = new Ve();
7154
7173
  export {
7155
7174
  be as $,
7156
7175
  nt as A,
@@ -7166,14 +7185,14 @@ export {
7166
7185
  Ie as K,
7167
7186
  Z as L,
7168
7187
  ze as M,
7169
- ai as N,
7188
+ as as N,
7170
7189
  Xe as O,
7171
7190
  Mt as P,
7172
7191
  ye as Q,
7173
7192
  P as R,
7174
7193
  Ft as S,
7175
7194
  q as T,
7176
- ti as U,
7195
+ ts as U,
7177
7196
  ke as V,
7178
7197
  We as W,
7179
7198
  Uo as X,
@@ -7198,8 +7217,8 @@ export {
7198
7217
  Ee as aE,
7199
7218
  qo as aF,
7200
7219
  uo as aG,
7201
- io as aH,
7202
- so as aI,
7220
+ so as aH,
7221
+ io as aI,
7203
7222
  oo as aJ,
7204
7223
  he as aK,
7205
7224
  eo as aL,
@@ -7219,17 +7238,17 @@ export {
7219
7238
  rt as aZ,
7220
7239
  Co as aa,
7221
7240
  J as ab,
7222
- ei as ac,
7223
- oi as ad,
7224
- ii as ae,
7225
- si as af,
7226
- ri as ag,
7227
- ni as ah,
7241
+ es as ac,
7242
+ os as ad,
7243
+ ss as ae,
7244
+ is as af,
7245
+ rs as ag,
7246
+ ns as ah,
7228
7247
  fe as ai,
7229
7248
  ue as aj,
7230
7249
  co as ak,
7231
7250
  He as al,
7232
- st as am,
7251
+ it as am,
7233
7252
  bo as an,
7234
7253
  vt as ao,
7235
7254
  zt as ap,
@@ -7267,6 +7286,6 @@ export {
7267
7286
  ko as w,
7268
7287
  Mo as x,
7269
7288
  Dt as y,
7270
- hi as z
7289
+ hs as z
7271
7290
  };
7272
- //# sourceMappingURL=FontAnalyzer-EF3gLPr8.js.map
7291
+ //# sourceMappingURL=FontAnalyzer-PE6nysqE.js.map