@vectojs/core 0.2.1 → 0.2.3

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.
package/dist/index.js CHANGED
@@ -3,16 +3,16 @@
3
3
 
4
4
 
5
5
 
6
- var _chunk72WVPMSJjs = require('./chunk-72WVPMSJ.js');
6
+ var _chunkVVOQNUBKjs = require('./chunk-VVOQNUBK.js');
7
7
 
8
8
 
9
9
 
10
10
 
11
11
 
12
12
 
13
- var _chunkLIX7DJTIjs = require('./chunk-LIX7DJTI.js');
14
13
 
15
14
 
15
+ var _chunkTXA3LZDMjs = require('./chunk-TXA3LZDM.js');
16
16
 
17
17
 
18
18
 
@@ -22,12 +22,14 @@ var _chunkLIX7DJTIjs = require('./chunk-LIX7DJTI.js');
22
22
 
23
23
 
24
24
 
25
- var _chunkLA3FJLP2js = require('./chunk-LA3FJLP2.js');
26
25
 
27
26
 
27
+ var _chunkKPWVPGHRjs = require('./chunk-KPWVPGHR.js');
28
28
 
29
29
 
30
- var _chunkRW6NC4RBjs = require('./chunk-RW6NC4RB.js');
30
+
31
+
32
+ var _chunk6I53LI3Zjs = require('./chunk-6I53LI3Z.js');
31
33
 
32
34
  // src/tree/ComputeParticleEntity.ts
33
35
  var PARTICLE_STRIDE_FLOATS = 8;
@@ -39,7 +41,7 @@ var PARTICLE_OFFSET_ORIGIN_X = 4;
39
41
  var PARTICLE_OFFSET_ORIGIN_Y = 5;
40
42
  var PARTICLE_OFFSET_SIZE = 6;
41
43
  var PARTICLE_OFFSET_LIFE = 7;
42
- var ComputeParticleEntity = (_class = class extends _chunkLA3FJLP2js.Entity {
44
+ var ComputeParticleEntity = (_class = class extends _chunkKPWVPGHRjs.Entity {
43
45
 
44
46
 
45
47
 
@@ -408,7 +410,7 @@ var Scene = (_class2 = class _Scene {
408
410
  this.particleBackend = _nullishCoalesce(options.particleBackend, () => ( "auto"));
409
411
  this.a11ySyncInterval = _nullishCoalesce(options.a11ySyncInterval, () => ( 0));
410
412
  this.reducedMotionQuery = typeof window !== "undefined" && typeof window.matchMedia === "function" ? window.matchMedia("(prefers-reduced-motion: reduce)") : null;
411
- this.root = new class RootEntity extends _chunkLA3FJLP2js.Entity {
413
+ this.root = new class RootEntity extends _chunkKPWVPGHRjs.Entity {
412
414
  isPointInside() {
413
415
  return false;
414
416
  }
@@ -417,7 +419,7 @@ var Scene = (_class2 = class _Scene {
417
419
  }
418
420
  }("root");
419
421
  this.root._scene = this;
420
- this.overlayRoot = new class OverlayRoot extends _chunkLA3FJLP2js.Entity {
422
+ this.overlayRoot = new class OverlayRoot extends _chunkKPWVPGHRjs.Entity {
421
423
  isPointInside() {
422
424
  return false;
423
425
  }
@@ -428,7 +430,7 @@ var Scene = (_class2 = class _Scene {
428
430
  if (options.renderer) {
429
431
  this.renderer = options.renderer;
430
432
  } else {
431
- this.renderer = new (0, _chunkLIX7DJTIjs.CanvasRenderer)(canvas);
433
+ this.renderer = new (0, _chunkTXA3LZDMjs.CanvasRenderer)(canvas);
432
434
  }
433
435
  if (typeof document !== "undefined") {
434
436
  this.a11yRoot = document.createElement("div");
@@ -489,6 +491,17 @@ var Scene = (_class2 = class _Scene {
489
491
  getRenderer() {
490
492
  return this.renderer;
491
493
  }
494
+ /** Convert browser viewport coordinates into this Scene's logical coordinates. */
495
+ clientToScene(clientX, clientY) {
496
+ const rect = _optionalChain([this, 'access', _19 => _19.canvas, 'access', _20 => _20.getBoundingClientRect, 'optionalCall', _21 => _21()]);
497
+ if (!rect) return { x: clientX, y: clientY };
498
+ const cssWidth = rect.width || this.canvas.clientWidth || this.width;
499
+ const cssHeight = rect.height || this.canvas.clientHeight || this.height;
500
+ return {
501
+ x: (clientX - rect.left) * (cssWidth > 0 ? this.width / cssWidth : 1),
502
+ y: (clientY - rect.top) * (cssHeight > 0 ? this.height / cssHeight : 1)
503
+ };
504
+ }
492
505
  /**
493
506
  * Add a top-level entity to the scene graph.
494
507
  *
@@ -563,12 +576,21 @@ var Scene = (_class2 = class _Scene {
563
576
  this.removeA11yRecursively(overlay);
564
577
  this.markDirty();
565
578
  }
579
+ destroyEntitySubtree(entity) {
580
+ while (entity.children.length > 0) this.destroyEntitySubtree(entity.children.at(-1));
581
+ entity.destroy();
582
+ }
566
583
  /**
567
584
  * Tear down the Scene, halt the loop, and clean up event listeners and DOM elements.
568
585
  */
569
586
  destroy() {
587
+ if (this.destroyed) return;
570
588
  this.destroyed = true;
571
589
  this.stop();
590
+ while (this.root.children.length > 0) this.destroyEntitySubtree(this.root.children.at(-1));
591
+ while (this.overlayRoot.children.length > 0) {
592
+ this.destroyEntitySubtree(this.overlayRoot.children.at(-1));
593
+ }
572
594
  if (typeof window !== "undefined" && !this.disableWindowResize) {
573
595
  window.removeEventListener("resize", this.resizeHandler);
574
596
  }
@@ -580,12 +602,13 @@ var Scene = (_class2 = class _Scene {
580
602
  this.canvas.removeEventListener("pointerleave", this.pointerLeaveListener);
581
603
  }
582
604
  }
583
- _optionalChain([this, 'access', _19 => _19.a11yRoot, 'optionalAccess', _20 => _20.remove, 'call', _21 => _21()]);
584
- _optionalChain([this, 'access', _22 => _22.portalRoot, 'optionalAccess', _23 => _23.remove, 'call', _24 => _24()]);
605
+ _optionalChain([this, 'access', _22 => _22.a11yRoot, 'optionalAccess', _23 => _23.remove, 'call', _24 => _24()]);
606
+ _optionalChain([this, 'access', _25 => _25.portalRoot, 'optionalAccess', _26 => _26.remove, 'call', _27 => _27()]);
585
607
  this.a11yElements.clear();
586
- _optionalChain([this, 'access', _25 => _25.pointRenderer, 'optionalAccess', _26 => _26.destroy, 'call', _27 => _27()]);
587
- _optionalChain([this, 'access', _28 => _28.glCanvas, 'optionalAccess', _29 => _29.remove, 'call', _30 => _30()]);
588
- _optionalChain([this, 'access', _31 => _31.gpuCanvas, 'optionalAccess', _32 => _32.remove, 'call', _33 => _33()]);
608
+ _optionalChain([this, 'access', _28 => _28.pointRenderer, 'optionalAccess', _29 => _29.destroy, 'call', _30 => _30()]);
609
+ _optionalChain([this, 'access', _31 => _31.renderer, 'access', _32 => _32.dispose, 'optionalCall', _33 => _33()]);
610
+ _optionalChain([this, 'access', _34 => _34.glCanvas, 'optionalAccess', _35 => _35.remove, 'call', _36 => _36()]);
611
+ _optionalChain([this, 'access', _37 => _37.gpuCanvas, 'optionalAccess', _38 => _38.remove, 'call', _39 => _39()]);
589
612
  this.gpuCanvas = null;
590
613
  this.gpuContext = null;
591
614
  if (this.recoveryTimerId) {
@@ -603,9 +626,9 @@ var Scene = (_class2 = class _Scene {
603
626
  }
604
627
  if (typeof window !== "undefined" && this.canvas && typeof this.canvas.addEventListener === "function") {
605
628
  this.pointerMoveListener = (e) => {
606
- const rect = this.canvas.getBoundingClientRect();
607
- this.mouseX = e.clientX - rect.left;
608
- this.mouseY = e.clientY - rect.top;
629
+ const point = this.clientToScene(e.clientX, e.clientY);
630
+ this.mouseX = point.x;
631
+ this.mouseY = point.y;
609
632
  };
610
633
  this.pointerLeaveListener = () => {
611
634
  this.mouseX = -9999;
@@ -656,6 +679,17 @@ var Scene = (_class2 = class _Scene {
656
679
  this.caretBlinkTimer = null;
657
680
  }
658
681
  }
682
+ /**
683
+ * Manually advance the scene clock by `dt` milliseconds and render synchronously.
684
+ * Essential for deterministic rendering (e.g. video export).
685
+ * Note: You should call `scene.stop()` before using this to avoid conflict with the rAF loop.
686
+ */
687
+ step(dt) {
688
+ const time = this.lastTime + dt;
689
+ this.lastTime = time;
690
+ this.render(this.renderer, dt, time);
691
+ this.dirty = false;
692
+ }
659
693
  /**
660
694
  * Mark the scene as needing a redraw on the next frame.
661
695
  *
@@ -710,6 +744,7 @@ var Scene = (_class2 = class _Scene {
710
744
  el.id = node.id;
711
745
  el.setAttribute("data-vecto-id", node.id);
712
746
  el.style.position = "absolute";
747
+ el.style.transformOrigin = "0 0";
713
748
  el.style.pointerEvents = "auto";
714
749
  el.style.touchAction = "pinch-zoom";
715
750
  el.style.margin = "0";
@@ -725,42 +760,42 @@ var Scene = (_class2 = class _Scene {
725
760
  el.style.background = "transparent";
726
761
  }
727
762
  el.addEventListener("click", (e) => {
728
- node.dispatchEvent(new (0, _chunkLA3FJLP2js.VectoJSEvent)("click", node, e));
763
+ node.dispatchEvent(new (0, _chunkKPWVPGHRjs.VectoJSEvent)("click", node, e));
729
764
  });
730
765
  el.addEventListener("mouseenter", (e) => {
731
766
  if (this.debugA11y) el.style.backgroundColor = "rgba(56, 189, 248, 0.2)";
732
- node.dispatchEvent(new (0, _chunkLA3FJLP2js.VectoJSEvent)("hover", node, e, false));
767
+ node.dispatchEvent(new (0, _chunkKPWVPGHRjs.VectoJSEvent)("hover", node, e, false));
733
768
  });
734
769
  el.addEventListener("mouseleave", (e) => {
735
770
  if (this.debugA11y) el.style.backgroundColor = "rgba(56, 189, 248, 0.05)";
736
- node.dispatchEvent(new (0, _chunkLA3FJLP2js.VectoJSEvent)("pointerleave", node, e, false));
771
+ node.dispatchEvent(new (0, _chunkKPWVPGHRjs.VectoJSEvent)("pointerleave", node, e, false));
737
772
  });
738
773
  const capEl = el;
739
774
  el.addEventListener("pointerdown", (e) => {
740
775
  if (typeof capEl.setPointerCapture === "function") capEl.setPointerCapture(e.pointerId);
741
- node.dispatchEvent(new (0, _chunkLA3FJLP2js.VectoJSEvent)("pointerdown", node, e));
776
+ node.dispatchEvent(new (0, _chunkKPWVPGHRjs.VectoJSEvent)("pointerdown", node, e));
742
777
  });
743
778
  el.addEventListener("pointerup", (e) => {
744
779
  if (typeof capEl.releasePointerCapture === "function")
745
780
  capEl.releasePointerCapture(e.pointerId);
746
- node.dispatchEvent(new (0, _chunkLA3FJLP2js.VectoJSEvent)("pointerup", node, e));
781
+ node.dispatchEvent(new (0, _chunkKPWVPGHRjs.VectoJSEvent)("pointerup", node, e));
747
782
  });
748
783
  el.addEventListener(
749
784
  "pointermove",
750
- (e) => node.dispatchEvent(new (0, _chunkLA3FJLP2js.VectoJSEvent)("pointermove", node, e))
785
+ (e) => node.dispatchEvent(new (0, _chunkKPWVPGHRjs.VectoJSEvent)("pointermove", node, e))
751
786
  );
752
787
  el.addEventListener(
753
788
  "wheel",
754
789
  (e) => {
755
- node.dispatchEvent(new (0, _chunkLA3FJLP2js.VectoJSEvent)("wheel", node, e));
790
+ node.dispatchEvent(new (0, _chunkKPWVPGHRjs.VectoJSEvent)("wheel", node, e));
756
791
  },
757
792
  { passive: false }
758
793
  );
759
794
  el.addEventListener("keydown", (e) => {
760
- node.dispatchEvent(new (0, _chunkLA3FJLP2js.VectoJSEvent)("keydown", node, e));
795
+ node.dispatchEvent(new (0, _chunkKPWVPGHRjs.VectoJSEvent)("keydown", node, e));
761
796
  });
762
797
  el.addEventListener("keyup", (e) => {
763
- node.dispatchEvent(new (0, _chunkLA3FJLP2js.VectoJSEvent)("keyup", node, e));
798
+ node.dispatchEvent(new (0, _chunkKPWVPGHRjs.VectoJSEvent)("keyup", node, e));
764
799
  });
765
800
  if (el instanceof HTMLInputElement || el instanceof HTMLTextAreaElement) {
766
801
  const input = el;
@@ -786,7 +821,7 @@ var Scene = (_class2 = class _Scene {
786
821
  });
787
822
  el.addEventListener("compositionupdate", (e) => {
788
823
  const data = _nullishCoalesce(e.data, () => ( ""));
789
- composition = { start: _nullishCoalesce(_optionalChain([composition, 'optionalAccess', _34 => _34.start]), () => ( 0)), length: data.length };
824
+ composition = { start: _nullishCoalesce(_optionalChain([composition, 'optionalAccess', _40 => _40.start]), () => ( 0)), length: data.length };
790
825
  forward();
791
826
  });
792
827
  el.addEventListener("compositionend", () => {
@@ -832,7 +867,7 @@ var Scene = (_class2 = class _Scene {
832
867
  el.addEventListener("keydown", (e) => {
833
868
  if (e.key === "Enter" || e.key === " ") {
834
869
  e.preventDefault();
835
- node.dispatchEvent(new (0, _chunkLA3FJLP2js.VectoJSEvent)("click", node, e));
870
+ node.dispatchEvent(new (0, _chunkKPWVPGHRjs.VectoJSEvent)("click", node, e));
836
871
  }
837
872
  });
838
873
  }
@@ -857,7 +892,8 @@ var Scene = (_class2 = class _Scene {
857
892
  if (el.placeholder !== attrs.placeholder) el.placeholder = attrs.placeholder;
858
893
  }
859
894
  if (attrs.href !== void 0 && el instanceof HTMLAnchorElement) {
860
- if (el.getAttribute("href") !== attrs.href) el.setAttribute("href", attrs.href);
895
+ const safeHref = _chunkTXA3LZDMjs.sanitizeUrl.call(void 0, attrs.href);
896
+ if (el.getAttribute("href") !== safeHref) el.setAttribute("href", safeHref);
861
897
  }
862
898
  if (el instanceof HTMLImageElement) {
863
899
  if (attrs.src !== void 0 && el.src !== attrs.src) el.src = attrs.src;
@@ -918,12 +954,12 @@ var Scene = (_class2 = class _Scene {
918
954
  el.style.height = `${this.height}px`;
919
955
  el.style.transform = "";
920
956
  } else {
921
- const pos = node.getGlobalPosition();
922
- el.style.left = `${pos.x + node.a11yOffsetX}px`;
923
- el.style.top = `${pos.y + node.a11yOffsetY}px`;
924
- el.style.width = `${node.width * node.scaleX}px`;
925
- el.style.height = `${node.height * node.scaleY}px`;
926
- el.style.transform = `rotate(${node.rotation}rad)`;
957
+ const { a, b, c, d, e, f } = node.getWorldTransform();
958
+ el.style.left = `${e + node.a11yOffsetX}px`;
959
+ el.style.top = `${f + node.a11yOffsetY}px`;
960
+ el.style.width = `${node.width}px`;
961
+ el.style.height = `${node.height}px`;
962
+ el.style.transform = `matrix(${a}, ${b}, ${c}, ${d}, 0, 0)`;
927
963
  }
928
964
  }
929
965
  for (const child of node.children) this.syncA11y(child);
@@ -985,6 +1021,35 @@ var Scene = (_class2 = class _Scene {
985
1021
  }
986
1022
  this.a11yNeedsReorder = false;
987
1023
  }
1024
+ /** Keep DOM/WebGL overlay layers aligned with the canvas's CSS box. */
1025
+ syncOverlayGeometry() {
1026
+ const parent = this.canvas.parentElement;
1027
+ if (!parent) return;
1028
+ const canvasRect = _optionalChain([this, 'access', _41 => _41.canvas, 'access', _42 => _42.getBoundingClientRect, 'optionalCall', _43 => _43()]);
1029
+ const parentRect = _optionalChain([parent, 'access', _44 => _44.getBoundingClientRect, 'optionalCall', _45 => _45()]);
1030
+ const cssWidth = _optionalChain([canvasRect, 'optionalAccess', _46 => _46.width]) || this.canvas.clientWidth || this.width;
1031
+ const cssHeight = _optionalChain([canvasRect, 'optionalAccess', _47 => _47.height]) || this.canvas.clientHeight || this.height;
1032
+ const left = (_nullishCoalesce(_optionalChain([canvasRect, 'optionalAccess', _48 => _48.left]), () => ( 0))) - (_nullishCoalesce(_optionalChain([parentRect, 'optionalAccess', _49 => _49.left]), () => ( 0))) - (parent.clientLeft || 0) + parent.scrollLeft;
1033
+ const top = (_nullishCoalesce(_optionalChain([canvasRect, 'optionalAccess', _50 => _50.top]), () => ( 0))) - (_nullishCoalesce(_optionalChain([parentRect, 'optionalAccess', _51 => _51.top]), () => ( 0))) - (parent.clientTop || 0) + parent.scrollTop;
1034
+ const scaleX = this.width > 0 ? cssWidth / this.width : 1;
1035
+ const scaleY = this.height > 0 ? cssHeight / this.height : 1;
1036
+ for (const root of [this.a11yRoot, this.portalRoot]) {
1037
+ if (!root) continue;
1038
+ root.style.left = `${left}px`;
1039
+ root.style.top = `${top}px`;
1040
+ root.style.width = `${this.width}px`;
1041
+ root.style.height = `${this.height}px`;
1042
+ root.style.transformOrigin = "0 0";
1043
+ root.style.transform = `scale(${scaleX}, ${scaleY})`;
1044
+ }
1045
+ for (const canvas of [this.glCanvas, this.gpuCanvas]) {
1046
+ if (!canvas) continue;
1047
+ canvas.style.left = `${left}px`;
1048
+ canvas.style.top = `${top}px`;
1049
+ canvas.style.width = `${cssWidth}px`;
1050
+ canvas.style.height = `${cssHeight}px`;
1051
+ }
1052
+ }
988
1053
  getA11yTree() {
989
1054
  const map = /* @__PURE__ */ new Map();
990
1055
  const roots = [];
@@ -1028,7 +1093,7 @@ var Scene = (_class2 = class _Scene {
1028
1093
  traverse(this.root, null);
1029
1094
  return roots;
1030
1095
  }
1031
- renderPortalDOM(portal, te, tf, a, b, c, d) {
1096
+ renderPortalDOM(portal, te, tf, a, b, c, d, opacity) {
1032
1097
  if (!this.portalRoot) return;
1033
1098
  this.activePortalsThisFrame.add(portal.id);
1034
1099
  this.portalEntities.set(portal.id, portal);
@@ -1062,6 +1127,11 @@ var Scene = (_class2 = class _Scene {
1062
1127
  portal.domElement.style.zIndex = zIndexStr;
1063
1128
  portal.lastZIndex = zIndexStr;
1064
1129
  }
1130
+ const opacityStr = String(opacity);
1131
+ if (portal.lastOpacity !== opacityStr) {
1132
+ portal.domElement.style.opacity = opacityStr;
1133
+ portal.lastOpacity = opacityStr;
1134
+ }
1065
1135
  }
1066
1136
  reconcilePortals() {
1067
1137
  if (!this.portalRoot) return;
@@ -1085,7 +1155,7 @@ var Scene = (_class2 = class _Scene {
1085
1155
  * (and {@link respectReducedMotion} is on). `0` means uncapped.
1086
1156
  */
1087
1157
  effectiveMaxFPS() {
1088
- const reduced = this.respectReducedMotion && !!_optionalChain([this, 'access', _35 => _35.reducedMotionQuery, 'optionalAccess', _36 => _36.matches]);
1158
+ const reduced = this.respectReducedMotion && !!_optionalChain([this, 'access', _52 => _52.reducedMotionQuery, 'optionalAccess', _53 => _53.matches]);
1089
1159
  if (reduced)
1090
1160
  return this.maxFPS > 0 ? Math.min(this.maxFPS, REDUCED_MOTION_FPS) : REDUCED_MOTION_FPS;
1091
1161
  return this.maxFPS;
@@ -1109,19 +1179,17 @@ var Scene = (_class2 = class _Scene {
1109
1179
  }
1110
1180
  this.render(this.renderer, dt, time);
1111
1181
  const hasActiveAnimation = this.hasAnyPendingAnimation(this.root) || this.hasAnyPendingAnimation(this.overlayRoot);
1112
- if (hasActiveAnimation) {
1182
+ const hasInteractive = this.hasAnyInteractive(this.root) || this.hasAnyInteractive(this.overlayRoot);
1183
+ const shouldSyncInterval = this.a11ySyncInterval <= 0 || time - this.lastA11ySync >= this.a11ySyncInterval;
1184
+ if ((hasInteractive || this.a11yElements.size > 0) && (shouldSyncInterval || this.a11yPendingSyncAfterAnimation)) {
1185
+ this.lastA11ySync = time;
1186
+ if (hasInteractive) {
1187
+ this.syncA11y(this.root);
1188
+ }
1189
+ this.enforceA11yDomOrder();
1190
+ this.a11yPendingSyncAfterAnimation = hasActiveAnimation;
1191
+ } else if (hasActiveAnimation) {
1113
1192
  this.a11yPendingSyncAfterAnimation = true;
1114
- } else {
1115
- const hasInteractive = this.hasAnyInteractive(this.root) || this.hasAnyInteractive(this.overlayRoot);
1116
- const shouldSyncInterval = this.a11ySyncInterval <= 0 || time - this.lastA11ySync >= this.a11ySyncInterval;
1117
- if ((hasInteractive || this.a11yElements.size > 0) && (shouldSyncInterval || this.a11yPendingSyncAfterAnimation)) {
1118
- this.lastA11ySync = time;
1119
- if (hasInteractive) {
1120
- this.syncA11y(this.root);
1121
- }
1122
- this.enforceA11yDomOrder();
1123
- this.a11yPendingSyncAfterAnimation = false;
1124
- }
1125
1193
  }
1126
1194
  this.dirty = false;
1127
1195
  this.scheduleFrame();
@@ -1134,14 +1202,18 @@ var Scene = (_class2 = class _Scene {
1134
1202
  * @param time - Current absolute time in milliseconds (default 0).
1135
1203
  */
1136
1204
  render(renderer, dt = 0, time = 0) {
1137
- if (this.a11yRoot && this.canvas.parentElement) {
1205
+ const isMainRenderer = renderer === this.renderer;
1206
+ if (isMainRenderer && this.a11yRoot && this.canvas.parentElement) {
1138
1207
  const parentStyle = this.canvas.parentElement.style;
1139
1208
  if (!parentStyle.position || parentStyle.position === "static") {
1140
1209
  parentStyle.position = "relative";
1141
1210
  }
1211
+ this.syncOverlayGeometry();
1212
+ }
1213
+ if (isMainRenderer) {
1214
+ this.renderOrderCounter = 0;
1215
+ this.activePortalsThisFrame.clear();
1142
1216
  }
1143
- this.renderOrderCounter = 0;
1144
- this.activePortalsThisFrame.clear();
1145
1217
  const computeEntities = [];
1146
1218
  const collectComputeEntities = (node) => {
1147
1219
  if (node instanceof ComputeParticleEntity) {
@@ -1156,7 +1228,8 @@ var Scene = (_class2 = class _Scene {
1156
1228
  collectComputeEntities(overlay);
1157
1229
  }
1158
1230
  if (computeEntities.length > 0) {
1159
- if (!this.device && !this.webgpuDisabled && !this.initializingWebGPU && !this.deviceLost) {
1231
+ const isMainRenderPath = renderer === this.renderer;
1232
+ if (isMainRenderPath && !this.device && !this.webgpuDisabled && !this.initializingWebGPU && !this.deviceLost) {
1160
1233
  this.initializingWebGPU = true;
1161
1234
  this.initWebGPUContext(computeEntities).then((newDevice) => {
1162
1235
  this.device = newDevice;
@@ -1179,12 +1252,16 @@ var Scene = (_class2 = class _Scene {
1179
1252
  }
1180
1253
  }
1181
1254
  }).catch((err) => {
1182
- console.error("Failed to initialize WebGPU:", err);
1255
+ if (this.particleBackend === "webgpu") {
1256
+ console.error("Failed to initialize WebGPU:", err);
1257
+ } else {
1258
+ console.warn("WebGPU unavailable; using CPU particle fallback.", err);
1259
+ }
1183
1260
  this.webgpuDisabled = true;
1184
1261
  this.initializingWebGPU = false;
1185
1262
  });
1186
1263
  }
1187
- if (this.device && this.manager && !this.deviceLost && !this.webgpuDisabled) {
1264
+ if (isMainRenderPath && this.device && this.manager && !this.deviceLost && !this.webgpuDisabled) {
1188
1265
  try {
1189
1266
  const commandEncoder = this.device.createCommandEncoder();
1190
1267
  const computePass = commandEncoder.beginComputePass();
@@ -1232,21 +1309,20 @@ var Scene = (_class2 = class _Scene {
1232
1309
  this.device = null;
1233
1310
  this.recreateWebGPUDeviceWithRetry(computeEntities);
1234
1311
  }
1235
- } else {
1312
+ } else if (isMainRenderPath) {
1236
1313
  for (const entity of computeEntities) {
1237
1314
  entity.updateCPU(dt / 1e3, this.mouseX, this.mouseY, this.width, this.height);
1238
1315
  }
1239
1316
  }
1240
1317
  }
1241
1318
  renderer.clear();
1242
- const isMainRenderer = renderer === this.renderer;
1243
1319
  if (isMainRenderer) {
1244
- _optionalChain([this, 'access', _37 => _37.pointRenderer, 'optionalAccess', _38 => _38.begin, 'call', _39 => _39()]);
1320
+ _optionalChain([this, 'access', _54 => _54.pointRenderer, 'optionalAccess', _55 => _55.begin, 'call', _56 => _56()]);
1245
1321
  }
1246
1322
  const vw = this.width;
1247
1323
  const vh = this.height;
1248
- const renderNode = (node, pa, pb, pc, pd, pe, pf) => {
1249
- node.update(dt, time);
1324
+ const renderNode = (node, pa, pb, pc, pd, pe, pf, parentOpacity) => {
1325
+ if (isMainRenderer) node.update(dt, time);
1250
1326
  const cos = Math.cos(node.rotation);
1251
1327
  const sin = Math.sin(node.rotation);
1252
1328
  const te = pa * node.x + pc * node.y + pe;
@@ -1255,16 +1331,24 @@ var Scene = (_class2 = class _Scene {
1255
1331
  const sxSin = node.scaleX * sin;
1256
1332
  const syCos = node.scaleY * cos;
1257
1333
  const sySin = node.scaleY * sin;
1258
- const a = pa * sxCos + pc * sxSin;
1259
- const b = pb * sxCos + pd * sxSin;
1260
- const c = pa * -sySin + pc * syCos;
1261
- const d = pb * -sySin + pd * syCos;
1262
- const a11yEl = this.a11yElements.get(node.id);
1334
+ const a = pa * sxCos + pc * sySin;
1335
+ const b = pb * sxCos + pd * sySin;
1336
+ const c = pa * -sxSin + pc * syCos;
1337
+ const d = pb * -sxSin + pd * syCos;
1338
+ const worldScaleX = Math.hypot(a, b);
1339
+ const worldScaleY = Math.hypot(c, d);
1340
+ const worldOpacity = parentOpacity * node.opacity;
1341
+ const scaleTolerance = Math.max(1, worldScaleX, worldScaleY) * 1e-6;
1342
+ const orthogonalTolerance = Math.max(1, worldScaleX * worldScaleY) * 1e-6;
1343
+ const isSimilarityTransform = Number.isFinite(worldScaleX) && Number.isFinite(worldScaleY) && Math.abs(worldScaleX - worldScaleY) <= scaleTolerance && Math.abs(a * c + b * d) <= orthogonalTolerance;
1344
+ const a11yEl = isMainRenderer ? this.a11yElements.get(node.id) : void 0;
1263
1345
  if (a11yEl) {
1264
1346
  a11yEl.style.zIndex = String(this.renderOrderCounter++);
1265
1347
  }
1266
1348
  if (node.isDOMPortal) {
1267
- this.renderPortalDOM(node, te, tf, a, b, c, d);
1349
+ if (isMainRenderer) {
1350
+ this.renderPortalDOM(node, te, tf, a, b, c, d, worldOpacity);
1351
+ }
1268
1352
  return;
1269
1353
  }
1270
1354
  let visible = true;
@@ -1290,33 +1374,27 @@ var Scene = (_class2 = class _Scene {
1290
1374
  if (node.children.length === 0 && node.scaleX === node.scaleY) {
1291
1375
  const bc = node.getBatchCircle();
1292
1376
  if (bc) {
1293
- if (visible) {
1294
- if (isMainRenderer && this.pointRenderer) {
1295
- this.pointRenderer.addCircle(
1296
- te,
1297
- tf,
1298
- bc.radius * Math.hypot(a, b),
1299
- bc.color,
1300
- node.opacity
1301
- );
1302
- } else {
1303
- renderer.fillCircle(node.x, node.y, bc.radius * node.scaleX, bc.color, node.opacity);
1377
+ if (!visible) return;
1378
+ if (isMainRenderer && this.pointRenderer) {
1379
+ if (isSimilarityTransform) {
1380
+ this.pointRenderer.addCircle(te, tf, bc.radius * worldScaleX, bc.color, worldOpacity);
1381
+ return;
1304
1382
  }
1383
+ } else {
1384
+ renderer.fillCircle(node.x, node.y, bc.radius * node.scaleX, bc.color, worldOpacity);
1385
+ return;
1305
1386
  }
1306
- return;
1307
- }
1308
- if (isMainRenderer && this.pointRenderer) {
1387
+ } else if (isMainRenderer && this.pointRenderer) {
1309
1388
  const br = node.getBatchRect();
1310
- if (br) {
1389
+ if (br && isSimilarityTransform && a * d - b * c >= 0) {
1311
1390
  if (visible) {
1312
- const ws = Math.hypot(a, b);
1313
1391
  this.pointRenderer.addRect(
1314
1392
  te,
1315
1393
  tf,
1316
- br.width * ws,
1317
- br.height * ws,
1394
+ br.width * worldScaleX,
1395
+ br.height * worldScaleX,
1318
1396
  br.color,
1319
- node.opacity,
1397
+ worldOpacity,
1320
1398
  Math.atan2(b, a)
1321
1399
  );
1322
1400
  }
@@ -1329,11 +1407,11 @@ var Scene = (_class2 = class _Scene {
1329
1407
  renderer.translate(node.x, node.y);
1330
1408
  renderer.scale(node.scaleX, node.scaleY);
1331
1409
  renderer.rotate(node.rotation);
1332
- renderer.setGlobalAlpha(node.opacity);
1410
+ renderer.setGlobalAlpha(worldOpacity);
1333
1411
  if (visible) {
1334
1412
  if (node instanceof ComputeParticleEntity) {
1335
1413
  if (this.deviceLost || this.webgpuDisabled || !this.device || !this.manager) {
1336
- this.renderCPUParticles(renderer, node);
1414
+ this.renderCPUParticles(renderer, node, worldOpacity);
1337
1415
  }
1338
1416
  } else {
1339
1417
  node.render(renderer);
@@ -1343,26 +1421,26 @@ var Scene = (_class2 = class _Scene {
1343
1421
  renderer.clip(0, 0, node.width, node.height);
1344
1422
  }
1345
1423
  for (const child of node.children) {
1346
- renderNode(child, a, b, c, d, te, tf);
1424
+ renderNode(child, a, b, c, d, te, tf, worldOpacity);
1347
1425
  }
1348
1426
  renderer.flush();
1349
1427
  renderer.restore();
1350
1428
  };
1351
- renderNode(this.root, 1, 0, 0, 1, 0, 0);
1429
+ renderNode(this.root, 1, 0, 0, 1, 0, 0, 1);
1352
1430
  for (const overlay of this.overlayRoot.children) {
1353
- renderNode(overlay, 1, 0, 0, 1, 0, 0);
1431
+ renderNode(overlay, 1, 0, 0, 1, 0, 0, 1);
1354
1432
  }
1355
- this.reconcilePortals();
1433
+ if (isMainRenderer) this.reconcilePortals();
1356
1434
  renderer.flush();
1357
1435
  if (isMainRenderer) {
1358
- _optionalChain([this, 'access', _40 => _40.pointRenderer, 'optionalAccess', _41 => _41.flush, 'call', _42 => _42()]);
1436
+ _optionalChain([this, 'access', _57 => _57.pointRenderer, 'optionalAccess', _58 => _58.flush, 'call', _59 => _59()]);
1359
1437
  }
1360
1438
  }
1361
1439
  /**
1362
1440
  * Export the current scene state to a lightweight, flat SVG XML string.
1363
1441
  */
1364
1442
  toSVG() {
1365
- const renderer = new (0, _chunkLIX7DJTIjs.SVGRenderer)(this.width, this.height);
1443
+ const renderer = new (0, _chunkTXA3LZDMjs.SVGRenderer)(this.width, this.height);
1366
1444
  this.render(renderer, 0, 0);
1367
1445
  return renderer.toXMLString();
1368
1446
  }
@@ -1375,7 +1453,7 @@ var Scene = (_class2 = class _Scene {
1375
1453
  if (typeof this.renderer.resize === "function") {
1376
1454
  this.renderer.resize(width, height);
1377
1455
  }
1378
- _optionalChain([this, 'access', _43 => _43.pointRenderer, 'optionalAccess', _44 => _44.resize, 'call', _45 => _45(width, height)]);
1456
+ _optionalChain([this, 'access', _60 => _60.pointRenderer, 'optionalAccess', _61 => _61.resize, 'call', _62 => _62(width, height)]);
1379
1457
  this.markDirty();
1380
1458
  }
1381
1459
  /**
@@ -1482,13 +1560,15 @@ var Scene = (_class2 = class _Scene {
1482
1560
  this.manager.initPipelines(format);
1483
1561
  for (const entity of entities) {
1484
1562
  this.manager.setupEntityResources(entity);
1485
- newDevice.queue.writeBuffer(entity.gpuStorageBuffer, 0, entity.particleData);
1563
+ if (entity.gpuStorageBuffer) {
1564
+ newDevice.queue.writeBuffer(entity.gpuStorageBuffer, 0, entity.particleData);
1565
+ }
1486
1566
  }
1487
1567
  }
1488
1568
  }).catch(() => this.recreateWebGPUDeviceWithRetry(entities, attempt + 1));
1489
1569
  }, backoff);
1490
1570
  }
1491
- renderCPUParticles(renderer, entity) {
1571
+ renderCPUParticles(renderer, entity, worldOpacity) {
1492
1572
  const data = entity.particleData;
1493
1573
  const size = entity.maxParticles;
1494
1574
  const isMain = renderer === this.renderer;
@@ -1499,7 +1579,7 @@ var Scene = (_class2 = class _Scene {
1499
1579
  const pSize = data[idx + 6];
1500
1580
  const life = data[idx + 7];
1501
1581
  if (life === 0) continue;
1502
- const opacity = life < 0 ? entity.opacity : entity.opacity * Math.min(1, life);
1582
+ const opacity = life < 0 ? worldOpacity : worldOpacity * Math.min(1, life);
1503
1583
  const scale = life >= 0 ? Math.min(1, life) : 1;
1504
1584
  if (isMain && this.pointRenderer) {
1505
1585
  this.pointRenderer.addCircle(x, y, pSize * scale, entity.baseColor, opacity);
@@ -1523,10 +1603,10 @@ var Scene = (_class2 = class _Scene {
1523
1603
  // src/components/TextEntity.ts
1524
1604
  var sharedMeasurer;
1525
1605
  function defaultMeasurer() {
1526
- if (sharedMeasurer === void 0) sharedMeasurer = _chunk72WVPMSJjs.createCanvasMeasurer.call(void 0, "sans-serif");
1606
+ if (sharedMeasurer === void 0) sharedMeasurer = _chunkVVOQNUBKjs.createCanvasMeasurer.call(void 0, "sans-serif");
1527
1607
  return sharedMeasurer;
1528
1608
  }
1529
- var TextEntity = (_class3 = class extends _chunkLA3FJLP2js.Entity {
1609
+ var TextEntity = (_class3 = class extends _chunkKPWVPGHRjs.Entity {
1530
1610
 
1531
1611
 
1532
1612
 
@@ -1543,7 +1623,7 @@ var TextEntity = (_class3 = class extends _chunkLA3FJLP2js.Entity {
1543
1623
  this.text = text;
1544
1624
  this.atlas = atlas;
1545
1625
  this.fontSize = fontSize;
1546
- this.layout = new (0, _chunk72WVPMSJjs.LayoutEngine)(maxWidth, 1e4, defaultMeasurer());
1626
+ this.layout = new (0, _chunkVVOQNUBKjs.LayoutEngine)(maxWidth, 1e4, defaultMeasurer());
1547
1627
  this.prepared = this.layout.prepare(this.text, this.atlas, this.fontSize);
1548
1628
  this.applyLayout();
1549
1629
  this.interactive = true;
@@ -1583,10 +1663,9 @@ var TextEntity = (_class3 = class extends _chunkLA3FJLP2js.Entity {
1583
1663
  this.a11yOffsetY = 0;
1584
1664
  }
1585
1665
  isPointInside(globalX, globalY) {
1586
- const pos = this.getGlobalPosition();
1587
- const lx = globalX - pos.x;
1588
- const ly = globalY - pos.y;
1589
- return lx >= 0 && lx <= this.width && ly >= 0 && ly <= this.height;
1666
+ const local = this.worldToLocal(globalX, globalY);
1667
+ if (!local) return false;
1668
+ return local.x >= 0 && local.x <= this.width && local.y >= 0 && local.y <= this.height;
1590
1669
  }
1591
1670
  render(renderer) {
1592
1671
  const currentFill = this.isHovered ? this.hoveredFillStyle : this.fillStyle;
@@ -1625,7 +1704,7 @@ var TextEntity = (_class3 = class extends _chunkLA3FJLP2js.Entity {
1625
1704
  }, _class3);
1626
1705
 
1627
1706
  // src/components/GridTextEntity.ts
1628
- var GridTextEntity = (_class4 = class extends _chunkLA3FJLP2js.Entity {
1707
+ var GridTextEntity = (_class4 = class extends _chunkKPWVPGHRjs.Entity {
1629
1708
 
1630
1709
  __init54() {this.fillStyle = "#ffffff"}
1631
1710
  __init55() {this.grid = []}
@@ -1644,7 +1723,7 @@ var GridTextEntity = (_class4 = class extends _chunkLA3FJLP2js.Entity {
1644
1723
  updateGrid(ascii) {
1645
1724
  this.grid = ascii;
1646
1725
  this.rows = ascii.length;
1647
- this.cols = _optionalChain([ascii, 'access', _46 => _46[0], 'optionalAccess', _47 => _47.length]) || 0;
1726
+ this.cols = _optionalChain([ascii, 'access', _63 => _63[0], 'optionalAccess', _64 => _64.length]) || 0;
1648
1727
  }
1649
1728
  isPointInside(_globalX, _globalY) {
1650
1729
  return false;
@@ -1719,7 +1798,7 @@ function distSqToSegment(px, py, x1, y1, x2, y2) {
1719
1798
  const ey = py - cy;
1720
1799
  return ex * ex + ey * ey;
1721
1800
  }
1722
- var SplineEntity = (_class5 = class extends _chunkLA3FJLP2js.Entity {
1801
+ var SplineEntity = (_class5 = class extends _chunkKPWVPGHRjs.Entity {
1723
1802
 
1724
1803
 
1725
1804
 
@@ -1801,10 +1880,9 @@ var SplineEntity = (_class5 = class extends _chunkLA3FJLP2js.Entity {
1801
1880
  * this method already calls it as a refinement when it is overridden.
1802
1881
  */
1803
1882
  isPointInside(globalX, globalY) {
1804
- const pos = this.getGlobalPosition();
1805
- const scale = this.getWorldScale();
1806
- const lx = (globalX - pos.x) / (scale.x || 1);
1807
- const ly = (globalY - pos.y) / (scale.y || 1);
1883
+ const local = this.worldToLocal(globalX, globalY);
1884
+ if (!local) return false;
1885
+ const { x: lx, y: ly } = local;
1808
1886
  const inAabb = lx >= this.bounds.x && lx <= this.bounds.x + this.bounds.width && ly >= this.bounds.y && ly <= this.bounds.y + this.bounds.height;
1809
1887
  if (!inAabb) return false;
1810
1888
  const refined = this.hitTestCurve(lx, ly);
@@ -2041,7 +2119,7 @@ var SpatialHashGrid = (_class6 = class {
2041
2119
  const keys = this.entityCells.get(id);
2042
2120
  if (!keys) return;
2043
2121
  for (const key of keys) {
2044
- _optionalChain([this, 'access', _48 => _48.grid, 'access', _49 => _49.get, 'call', _50 => _50(key), 'optionalAccess', _51 => _51.delete, 'call', _52 => _52(id)]);
2122
+ _optionalChain([this, 'access', _65 => _65.grid, 'access', _66 => _66.get, 'call', _67 => _67(key), 'optionalAccess', _68 => _68.delete, 'call', _69 => _69(id)]);
2045
2123
  }
2046
2124
  this.entityCells.delete(id);
2047
2125
  }
@@ -2077,7 +2155,7 @@ var SpatialHashGrid = (_class6 = class {
2077
2155
  }, _class6);
2078
2156
 
2079
2157
  // src/tree/DOMPortalEntity.ts
2080
- var DOMPortalEntity = (_class7 = class extends _chunkLA3FJLP2js.Entity {
2158
+ var DOMPortalEntity = (_class7 = class extends _chunkKPWVPGHRjs.Entity {
2081
2159
 
2082
2160
  __init64() {this.isDOMPortal = true}
2083
2161
  __init65() {this.domListeners = []}
@@ -2088,8 +2166,9 @@ var DOMPortalEntity = (_class7 = class extends _chunkLA3FJLP2js.Entity {
2088
2166
  __init70() {this.lastHeight = ""}
2089
2167
  __init71() {this.lastTransform = ""}
2090
2168
  __init72() {this.lastZIndex = ""}
2169
+ __init73() {this.lastOpacity = ""}
2091
2170
  constructor(domElement, width, height, id) {
2092
- super(id);_class7.prototype.__init64.call(this);_class7.prototype.__init65.call(this);_class7.prototype.__init66.call(this);_class7.prototype.__init67.call(this);_class7.prototype.__init68.call(this);_class7.prototype.__init69.call(this);_class7.prototype.__init70.call(this);_class7.prototype.__init71.call(this);_class7.prototype.__init72.call(this);;
2171
+ super(id);_class7.prototype.__init64.call(this);_class7.prototype.__init65.call(this);_class7.prototype.__init66.call(this);_class7.prototype.__init67.call(this);_class7.prototype.__init68.call(this);_class7.prototype.__init69.call(this);_class7.prototype.__init70.call(this);_class7.prototype.__init71.call(this);_class7.prototype.__init72.call(this);_class7.prototype.__init73.call(this);;
2093
2172
  this.domElement = domElement;
2094
2173
  this.width = _nullishCoalesce(width, () => ( 0));
2095
2174
  this.height = _nullishCoalesce(height, () => ( 0));
@@ -2111,7 +2190,7 @@ var DOMPortalEntity = (_class7 = class extends _chunkLA3FJLP2js.Entity {
2111
2190
  const events = ["click", "pointerdown", "pointerup", "pointermove", "wheel"];
2112
2191
  for (const type of events) {
2113
2192
  const handler = (e) => {
2114
- this.dispatchEvent(new (0, _chunkLA3FJLP2js.VectoJSEvent)(type, this, e));
2193
+ this.dispatchEvent(new (0, _chunkKPWVPGHRjs.VectoJSEvent)(type, this, e));
2115
2194
  };
2116
2195
  this.domElement.addEventListener(type, handler);
2117
2196
  this.domListeners.push({ type, handler, capture: false });
@@ -2122,7 +2201,7 @@ var DOMPortalEntity = (_class7 = class extends _chunkLA3FJLP2js.Entity {
2122
2201
  ];
2123
2202
  for (const { native, vecto } of hoverEvents) {
2124
2203
  const handler = (e) => {
2125
- this.dispatchEvent(new (0, _chunkLA3FJLP2js.VectoJSEvent)(vecto, this, e, false));
2204
+ this.dispatchEvent(new (0, _chunkKPWVPGHRjs.VectoJSEvent)(vecto, this, e, false));
2126
2205
  };
2127
2206
  this.domElement.addEventListener(native, handler);
2128
2207
  this.domListeners.push({ type: native, handler, capture: false });
@@ -2130,7 +2209,7 @@ var DOMPortalEntity = (_class7 = class extends _chunkLA3FJLP2js.Entity {
2130
2209
  const focusEvents = ["focus", "blur"];
2131
2210
  for (const type of focusEvents) {
2132
2211
  const handler = (e) => {
2133
- this.dispatchEvent(new (0, _chunkLA3FJLP2js.VectoJSEvent)(type, this, e, true));
2212
+ this.dispatchEvent(new (0, _chunkKPWVPGHRjs.VectoJSEvent)(type, this, e, true));
2134
2213
  };
2135
2214
  this.domElement.addEventListener(type, handler, true);
2136
2215
  this.domListeners.push({ type, handler, capture: true });
@@ -2138,22 +2217,15 @@ var DOMPortalEntity = (_class7 = class extends _chunkLA3FJLP2js.Entity {
2138
2217
  }
2139
2218
  }
2140
2219
  isPointInside(globalX, globalY) {
2141
- const pos = this.getGlobalPosition();
2142
- const scale = this.getWorldScale();
2143
- const rot = this.getWorldRotation();
2144
- const dx = globalX - pos.x;
2145
- const dy = globalY - pos.y;
2146
- const cos = Math.cos(-rot);
2147
- const sin = Math.sin(-rot);
2148
- const lx = (dx * cos - dy * sin) / scale.x;
2149
- const ly = (dx * sin + dy * cos) / scale.y;
2150
2220
  const w = this.width > 0 ? this.width : this.cachedWidth;
2151
2221
  const h = this.height > 0 ? this.height : this.cachedHeight;
2152
- return lx >= 0 && lx <= w && ly >= 0 && ly <= h;
2222
+ const local = this.worldToLocal(globalX, globalY);
2223
+ if (!local) return false;
2224
+ return local.x >= 0 && local.x <= w && local.y >= 0 && local.y <= h;
2153
2225
  }
2154
- add(child) {
2226
+ add(_child) {
2155
2227
  console.warn(`DOMPortalEntity (${this.id}) is a leaf node. Child entities are not supported.`);
2156
- return super.add(child);
2228
+ return this;
2157
2229
  }
2158
2230
  render() {
2159
2231
  }
@@ -2176,8 +2248,10 @@ var DOMPortalEntity = (_class7 = class extends _chunkLA3FJLP2js.Entity {
2176
2248
  }, _class7);
2177
2249
 
2178
2250
  // src/index.ts
2179
- Scene.registerWebGLPointRendererCreator(_chunkLIX7DJTIjs.createWebGLPointRenderer);
2180
- Scene.registerWebGPUParticleSystemManager(_chunkLIX7DJTIjs.WebGPUParticleSystemManager);
2251
+ Scene.registerWebGLPointRendererCreator(_chunkTXA3LZDMjs.createWebGLPointRenderer);
2252
+ Scene.registerWebGPUParticleSystemManager(_chunkTXA3LZDMjs.WebGPUParticleSystemManager);
2253
+
2254
+
2181
2255
 
2182
2256
 
2183
2257
 
@@ -2220,4 +2294,4 @@ Scene.registerWebGPUParticleSystemManager(_chunkLIX7DJTIjs.WebGPUParticleSystemM
2220
2294
 
2221
2295
 
2222
2296
 
2223
- exports.ArabicShaper = _chunkRW6NC4RBjs.ArabicShaper; exports.BidiResolver = _chunkRW6NC4RBjs.BidiResolver; exports.CanvasRenderer = _chunkLIX7DJTIjs.CanvasRenderer; exports.ComputeParticleEntity = ComputeParticleEntity; exports.DOMPortalEntity = DOMPortalEntity; exports.Easing = _chunkLA3FJLP2js.Easing; exports.Entity = _chunkLA3FJLP2js.Entity; exports.GridTextEntity = GridTextEntity; exports.LayoutEngine = _chunk72WVPMSJjs.LayoutEngine; exports.LayoutResultBuffer = _chunk72WVPMSJjs.LayoutResultBuffer; exports.LayoutWorkerManager = _chunkRW6NC4RBjs.LayoutWorkerManager; exports.MSDFFont = _chunkLA3FJLP2js.MSDFFont; exports.MSDFTextEntity = _chunkLA3FJLP2js.MSDFTextEntity; exports.PARTICLE_OFFSET_LIFE = PARTICLE_OFFSET_LIFE; exports.PARTICLE_OFFSET_ORIGIN_X = PARTICLE_OFFSET_ORIGIN_X; exports.PARTICLE_OFFSET_ORIGIN_Y = PARTICLE_OFFSET_ORIGIN_Y; exports.PARTICLE_OFFSET_POSITION_X = PARTICLE_OFFSET_POSITION_X; exports.PARTICLE_OFFSET_POSITION_Y = PARTICLE_OFFSET_POSITION_Y; exports.PARTICLE_OFFSET_SIZE = PARTICLE_OFFSET_SIZE; exports.PARTICLE_OFFSET_VELOCITY_X = PARTICLE_OFFSET_VELOCITY_X; exports.PARTICLE_OFFSET_VELOCITY_Y = PARTICLE_OFFSET_VELOCITY_Y; exports.PARTICLE_STRIDE_FLOATS = PARTICLE_STRIDE_FLOATS; exports.REDUCED_MOTION_FPS = REDUCED_MOTION_FPS; exports.SVGEntity = _chunkLA3FJLP2js.SVGEntity; exports.SVGRenderer = _chunkLIX7DJTIjs.SVGRenderer; exports.Scene = Scene; exports.SpatialHashGrid = SpatialHashGrid; exports.SplineEntity = SplineEntity; exports.SpringDriver = _chunkLA3FJLP2js.SpringDriver; exports.SpringPhysics = _chunkLA3FJLP2js.SpringPhysics; exports.TextEntity = TextEntity; exports.TweenDriver = _chunkLA3FJLP2js.TweenDriver; exports.VectoJSEvent = _chunkLA3FJLP2js.VectoJSEvent; exports.WebGPUParticleSystemManager = _chunkLIX7DJTIjs.WebGPUParticleSystemManager; exports.computeLineSegments = _chunk72WVPMSJjs.computeLineSegments; exports.createCanvasMeasurer = _chunk72WVPMSJjs.createCanvasMeasurer; exports.createWebGLPointRenderer = _chunkLIX7DJTIjs.createWebGLPointRenderer; exports.isTweenConfig = _chunkLA3FJLP2js.isTweenConfig; exports.loadSpline = loadSpline; exports.parseColorToRGBA = _chunkLIX7DJTIjs.parseColorToRGBA; exports.polySegmentToBezier = polySegmentToBezier;
2297
+ exports.ArabicShaper = _chunk6I53LI3Zjs.ArabicShaper; exports.BidiResolver = _chunk6I53LI3Zjs.BidiResolver; exports.CanvasRenderer = _chunkTXA3LZDMjs.CanvasRenderer; exports.ComputeParticleEntity = ComputeParticleEntity; exports.DOMPortalEntity = DOMPortalEntity; exports.Easing = _chunkKPWVPGHRjs.Easing; exports.Entity = _chunkKPWVPGHRjs.Entity; exports.GridTextEntity = GridTextEntity; exports.LayoutEngine = _chunkVVOQNUBKjs.LayoutEngine; exports.LayoutResultBuffer = _chunkVVOQNUBKjs.LayoutResultBuffer; exports.LayoutWorkerManager = _chunk6I53LI3Zjs.LayoutWorkerManager; exports.MSDFFont = _chunkKPWVPGHRjs.MSDFFont; exports.MSDFTextEntity = _chunkKPWVPGHRjs.MSDFTextEntity; exports.PARTICLE_OFFSET_LIFE = PARTICLE_OFFSET_LIFE; exports.PARTICLE_OFFSET_ORIGIN_X = PARTICLE_OFFSET_ORIGIN_X; exports.PARTICLE_OFFSET_ORIGIN_Y = PARTICLE_OFFSET_ORIGIN_Y; exports.PARTICLE_OFFSET_POSITION_X = PARTICLE_OFFSET_POSITION_X; exports.PARTICLE_OFFSET_POSITION_Y = PARTICLE_OFFSET_POSITION_Y; exports.PARTICLE_OFFSET_SIZE = PARTICLE_OFFSET_SIZE; exports.PARTICLE_OFFSET_VELOCITY_X = PARTICLE_OFFSET_VELOCITY_X; exports.PARTICLE_OFFSET_VELOCITY_Y = PARTICLE_OFFSET_VELOCITY_Y; exports.PARTICLE_STRIDE_FLOATS = PARTICLE_STRIDE_FLOATS; exports.REDUCED_MOTION_FPS = REDUCED_MOTION_FPS; exports.SVGEntity = _chunkKPWVPGHRjs.SVGEntity; exports.SVGRenderer = _chunkTXA3LZDMjs.SVGRenderer; exports.Scene = Scene; exports.SpatialHashGrid = SpatialHashGrid; exports.SplineEntity = SplineEntity; exports.SpringDriver = _chunkKPWVPGHRjs.SpringDriver; exports.SpringPhysics = _chunkKPWVPGHRjs.SpringPhysics; exports.TextEntity = TextEntity; exports.TweenDriver = _chunkKPWVPGHRjs.TweenDriver; exports.VectoJSEvent = _chunkKPWVPGHRjs.VectoJSEvent; exports.WebGPUParticleSystemManager = _chunkTXA3LZDMjs.WebGPUParticleSystemManager; exports.computeLineSegments = _chunkVVOQNUBKjs.computeLineSegments; exports.createCanvasMeasurer = _chunkVVOQNUBKjs.createCanvasMeasurer; exports.createWebGLPointRenderer = _chunkTXA3LZDMjs.createWebGLPointRenderer; exports.isSafeUrl = _chunkTXA3LZDMjs.isSafeUrl; exports.isTweenConfig = _chunkKPWVPGHRjs.isTweenConfig; exports.loadSpline = loadSpline; exports.parseColorToRGBA = _chunkTXA3LZDMjs.parseColorToRGBA; exports.polySegmentToBezier = polySegmentToBezier; exports.sanitizeUrl = _chunkTXA3LZDMjs.sanitizeUrl;