@vectojs/core 1.7.0 → 1.8.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.
package/dist/index.js CHANGED
@@ -3,7 +3,7 @@
3
3
 
4
4
 
5
5
 
6
- var _chunkZBKKRYDHjs = require('./chunk-ZBKKRYDH.js');
6
+ var _chunkBA5HUUDFjs = require('./chunk-BA5HUUDF.js');
7
7
 
8
8
 
9
9
 
@@ -26,12 +26,13 @@ var _chunkBPMNCGU7js = require('./chunk-BPMNCGU7.js');
26
26
 
27
27
 
28
28
 
29
- var _chunkDFNK6OV6js = require('./chunk-DFNK6OV6.js');
30
29
 
30
+ var _chunkFIQAIF55js = require('./chunk-FIQAIF55.js');
31
31
 
32
32
 
33
33
 
34
- var _chunkCTZQOM5Zjs = require('./chunk-CTZQOM5Z.js');
34
+
35
+ var _chunk4AR425ARjs = require('./chunk-4AR425AR.js');
35
36
 
36
37
  // src/tree/ComputeParticleEntity.ts
37
38
  var PARTICLE_STRIDE_FLOATS = 8;
@@ -43,7 +44,7 @@ var PARTICLE_OFFSET_ORIGIN_X = 4;
43
44
  var PARTICLE_OFFSET_ORIGIN_Y = 5;
44
45
  var PARTICLE_OFFSET_SIZE = 6;
45
46
  var PARTICLE_OFFSET_LIFE = 7;
46
- var ComputeParticleEntity = (_class = class extends _chunkDFNK6OV6js.Entity {
47
+ var ComputeParticleEntity = (_class = class extends _chunkFIQAIF55js.Entity {
47
48
 
48
49
 
49
50
 
@@ -317,6 +318,297 @@ function parseInlinePx(value) {
317
318
  const n = parseFloat(value);
318
319
  return Number.isFinite(n) && n > 0 ? n : null;
319
320
  }
321
+ function collectTextNodes(root) {
322
+ const out = [];
323
+ const walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT);
324
+ for (let n = walker.nextNode(); n; n = walker.nextNode()) out.push(n);
325
+ return out;
326
+ }
327
+ var caretGraphemeSegmenter = typeof Intl !== "undefined" && typeof Intl.Segmenter === "function" ? new Intl.Segmenter(void 0, { granularity: "grapheme" }) : null;
328
+ var caretWordSegmenter = typeof Intl !== "undefined" && typeof Intl.Segmenter === "function" ? new Intl.Segmenter(void 0, { granularity: "word" }) : null;
329
+ function graphemeBoundaries(text) {
330
+ if (!caretGraphemeSegmenter) {
331
+ const boundaries2 = [0];
332
+ for (let offset = 0; offset < text.length; ) {
333
+ const codePoint = _nullishCoalesce(text.codePointAt(offset), () => ( 0));
334
+ offset += codePoint > 65535 ? 2 : 1;
335
+ boundaries2.push(offset);
336
+ }
337
+ return boundaries2;
338
+ }
339
+ const boundaries = [0];
340
+ for (const segment of caretGraphemeSegmenter.segment(text)) {
341
+ const end = segment.index + segment.segment.length;
342
+ if (end > boundaries[boundaries.length - 1]) boundaries.push(end);
343
+ }
344
+ return boundaries;
345
+ }
346
+ function distanceToRectSquared(rect, x, y) {
347
+ const dx = x < rect.left ? rect.left - x : x > rect.right ? x - rect.right : 0;
348
+ const dy = y < rect.top ? rect.top - y : y > rect.bottom ? y - rect.bottom : 0;
349
+ return dx * dx + dy * dy;
350
+ }
351
+ function nearestOffsetForPoint(node, x, y) {
352
+ const boundaries = graphemeBoundaries(node.data);
353
+ const range = document.createRange();
354
+ let nearest = { offset: _nullishCoalesce(boundaries[0], () => ( 0)), distance: Infinity };
355
+ for (const offset of boundaries) {
356
+ range.setStart(node, offset);
357
+ range.collapse(true);
358
+ const rect = range.getBoundingClientRect();
359
+ const distance = distanceToRectSquared(rect, x, y);
360
+ if (distance < nearest.distance) nearest = { offset, distance };
361
+ }
362
+ return nearest;
363
+ }
364
+ function gridCellCaret(cell, localX) {
365
+ const node = cell.firstChild;
366
+ if (!(node instanceof Text)) return null;
367
+ const sourceLength = Number(_nullishCoalesce(cell.dataset.vectoGridSourceLength, () => ( node.data.length)));
368
+ const level = Number(_nullishCoalesce(cell.dataset.vectoGridLevel, () => ( 0)));
369
+ const cellX = Number(_nullishCoalesce(cell.dataset.vectoGridX, () => ( 0)));
370
+ const advance = Number(_nullishCoalesce(cell.dataset.vectoGridAdvance, () => ( 0)));
371
+ const caretOffsets = (_nullishCoalesce(cell.dataset.vectoGridCaretOffsets, () => ( `0,${sourceLength}`))).split(",").map(Number).filter((offset) => Number.isInteger(offset) && offset >= 0 && offset <= sourceLength);
372
+ const visuallyRtl = (level & 1) !== 0;
373
+ const visualFraction = advance > 0 ? Math.max(0, Math.min(1, (localX - cellX) / advance)) : 0;
374
+ const sourceFraction = visuallyRtl ? 1 - visualFraction : visualFraction;
375
+ const caretIndex = Math.round(sourceFraction * Math.max(0, caretOffsets.length - 1));
376
+ return {
377
+ node,
378
+ offset: _nullishCoalesce(caretOffsets[caretIndex], () => ( 0))
379
+ };
380
+ }
381
+ function nearestGridPositionInLine(line, localX) {
382
+ let nearest = null;
383
+ for (const cell of line.querySelectorAll("[data-vecto-grid-cell]")) {
384
+ const x = Number(_nullishCoalesce(cell.dataset.vectoGridX, () => ( 0)));
385
+ const advance = Number(_nullishCoalesce(cell.dataset.vectoGridAdvance, () => ( 0)));
386
+ if (localX >= x && localX <= x + advance) return gridCellCaret(cell, localX);
387
+ const distance = localX < x ? x - localX : localX - (x + advance);
388
+ if (!nearest || distance < nearest.distance) nearest = { cell, distance };
389
+ }
390
+ if (!nearest) return null;
391
+ return gridCellCaret(nearest.cell, localX);
392
+ }
393
+ function parseCssMatrix(transform) {
394
+ if (!transform || transform === "none") return [1, 0, 0, 1];
395
+ const values = transform.slice(transform.indexOf("(") + 1, transform.lastIndexOf(")")).split(",").map(Number);
396
+ return values.length >= 4 && values.slice(0, 4).every(Number.isFinite) ? [values[0], values[1], values[2], values[3]] : [1, 0, 0, 1];
397
+ }
398
+ function clientToGridLocal(contentEl, canvas, clientX, clientY) {
399
+ const line = contentEl.querySelector("[data-vecto-grid-line]");
400
+ const originMarker = _optionalChain([line, 'optionalAccess', _13 => _13.querySelector, 'call', _14 => _14('[data-vecto-grid-basis="origin"]')]);
401
+ const xMarker = _optionalChain([line, 'optionalAccess', _15 => _15.querySelector, 'call', _16 => _16('[data-vecto-grid-basis="x"]')]);
402
+ const yMarker = _optionalChain([line, 'optionalAccess', _17 => _17.querySelector, 'call', _18 => _18('[data-vecto-grid-basis="y"]')]);
403
+ if (line && originMarker && xMarker && yMarker) {
404
+ const origin = originMarker.getBoundingClientRect();
405
+ const xPoint = xMarker.getBoundingClientRect();
406
+ const yPoint = yMarker.getBoundingClientRect();
407
+ const xx = xPoint.left - origin.left;
408
+ const xy = xPoint.top - origin.top;
409
+ const yx = yPoint.left - origin.left;
410
+ const yy = yPoint.top - origin.top;
411
+ const determinant2 = xx * yy - xy * yx;
412
+ if (Number.isFinite(determinant2) && Math.abs(determinant2) > 1e-9) {
413
+ const dx2 = clientX - origin.left;
414
+ const dy2 = clientY - origin.top;
415
+ return {
416
+ x: (Number.parseFloat(line.style.left) || 0) + (yy * dx2 - yx * dy2) / determinant2,
417
+ y: (Number.parseFloat(line.style.top) || 0) + (-xy * dx2 + xx * dy2) / determinant2
418
+ };
419
+ }
420
+ }
421
+ const [a, b, c, d] = parseCssMatrix(getComputedStyle(contentEl).transform);
422
+ const canvasRect = canvas.getBoundingClientRect();
423
+ const logicalWidth = Number.parseFloat(canvas.style.width) || canvas.clientWidth || canvas.width;
424
+ const logicalHeight = Number.parseFloat(canvas.style.height) || canvas.clientHeight || canvas.height;
425
+ const scaleX = logicalWidth > 0 ? canvasRect.width / logicalWidth : 1;
426
+ const scaleY = logicalHeight > 0 ? canvasRect.height / logicalHeight : 1;
427
+ const worldX = (clientX - canvasRect.left) / scaleX;
428
+ const worldY = (clientY - canvasRect.top) / scaleY;
429
+ const dx = worldX - (Number.parseFloat(contentEl.style.left) || 0);
430
+ const dy = worldY - (Number.parseFloat(contentEl.style.top) || 0);
431
+ const determinant = a * d - b * c;
432
+ if (!Number.isFinite(determinant) || Math.abs(determinant) <= 1e-9) return null;
433
+ return {
434
+ x: (d * dx - c * dy) / determinant,
435
+ y: (-b * dx + a * dy) / determinant
436
+ };
437
+ }
438
+ function nearestGridPosition(contentEl, canvas, clientX, clientY) {
439
+ const lines = [...contentEl.querySelectorAll("[data-vecto-grid-line]")];
440
+ if (lines.length === 0) return null;
441
+ const [a, b, c, d] = parseCssMatrix(getComputedStyle(contentEl).transform);
442
+ if (a > 0 && d > 0 && Math.abs(b) <= 1e-9 && Math.abs(c) <= 1e-9) {
443
+ let nearest2 = null;
444
+ for (const line of lines) {
445
+ const rect = line.getBoundingClientRect();
446
+ const dy = clientY < rect.top ? rect.top - clientY : clientY > rect.bottom ? clientY - rect.bottom : 0;
447
+ const dx = clientX < rect.left ? rect.left - clientX : clientX > rect.right ? clientX - rect.right : 0;
448
+ const distance = dy * 4096 + dx;
449
+ if (!nearest2 || distance < nearest2.distance) nearest2 = { line, distance, rect };
450
+ }
451
+ if (!nearest2) return null;
452
+ const localWidth = Number.parseFloat(nearest2.line.style.width) || 0;
453
+ const scaleX = localWidth > 0 && nearest2.rect.width > 0 ? nearest2.rect.width / localWidth : 1;
454
+ const localX = (clientX - nearest2.rect.left) / scaleX;
455
+ return nearestGridPositionInLine(nearest2.line, localX);
456
+ }
457
+ const local = clientToGridLocal(contentEl, canvas, clientX, clientY);
458
+ if (!local) return null;
459
+ let nearest = null;
460
+ for (const line of lines) {
461
+ const left = Number.parseFloat(line.style.left) || 0;
462
+ const top = Number.parseFloat(line.style.top) || 0;
463
+ const width = Number.parseFloat(line.style.width) || 0;
464
+ const height = Number.parseFloat(line.style.height) || 0;
465
+ const dy = local.y < top ? top - local.y : local.y > top + height ? local.y - top - height : 0;
466
+ const dx = local.x < left ? left - local.x : local.x > left + width ? local.x - left - width : 0;
467
+ const distance = dy * 4096 + dx;
468
+ if (!nearest || distance < nearest.distance) nearest = { line, distance };
469
+ }
470
+ if (!nearest) return null;
471
+ const lineLeft = Number.parseFloat(nearest.line.style.left) || 0;
472
+ return nearestGridPositionInLine(nearest.line, local.x - lineLeft);
473
+ }
474
+ function nearestTextPositionInLine(line, x, y) {
475
+ const texts = collectTextNodes(line);
476
+ if (texts.length === 0) return null;
477
+ let nearest = null;
478
+ for (const node of texts) {
479
+ const candidate = nearestOffsetForPoint(node, x, y);
480
+ if (!nearest || candidate.distance < nearest.distance) {
481
+ let { offset } = candidate;
482
+ while (offset > 0 && node.data[offset - 1] === "\n") offset--;
483
+ nearest = { position: { node, offset }, distance: candidate.distance };
484
+ }
485
+ }
486
+ return _nullishCoalesce(_optionalChain([nearest, 'optionalAccess', _19 => _19.position]), () => ( null));
487
+ }
488
+ function nearestTextPositionInProjection(contentEl, canvas, x, y, eventTarget) {
489
+ if (contentEl.dataset.vectoContentGrid !== void 0) {
490
+ return nearestGridPosition(contentEl, canvas, x, y);
491
+ }
492
+ let targetLine = eventTarget;
493
+ while (targetLine && targetLine.parentElement !== contentEl) {
494
+ if (!contentEl.contains(targetLine)) {
495
+ targetLine = null;
496
+ break;
497
+ }
498
+ targetLine = targetLine.parentElement;
499
+ }
500
+ if (_optionalChain([targetLine, 'optionalAccess', _20 => _20.parentElement]) === contentEl) {
501
+ return nearestTextPositionInLine(targetLine, x, y);
502
+ }
503
+ let bestLine = null;
504
+ let bestDist = Infinity;
505
+ for (let i = 0; i < contentEl.children.length; i++) {
506
+ const child = contentEl.children[i];
507
+ const rect = child.getBoundingClientRect();
508
+ if (rect.width <= 0 && rect.height <= 0) continue;
509
+ const dy = y < rect.top ? rect.top - y : y > rect.bottom ? y - rect.bottom : 0;
510
+ const dx = x < rect.left ? rect.left - x : x > rect.right ? x - rect.right : 0;
511
+ const dist = dy * 4096 + dx;
512
+ if (dist < bestDist) {
513
+ bestDist = dist;
514
+ bestLine = child;
515
+ }
516
+ }
517
+ if (bestLine) return nearestTextPositionInLine(bestLine, x, y);
518
+ return nearestTextPositionInLine(contentEl, x, y);
519
+ }
520
+ function projectionAbsoluteOffset(root, caret) {
521
+ let offset = 0;
522
+ for (const node of collectTextNodes(root)) {
523
+ if (node === caret.node) return offset + Math.min(caret.offset, node.data.length);
524
+ offset += node.data.length;
525
+ }
526
+ return null;
527
+ }
528
+ function projectionCaretAt(root, absoluteOffset, affinity) {
529
+ const nodes = collectTextNodes(root);
530
+ if (nodes.length === 0) return null;
531
+ let remaining = Math.max(0, absoluteOffset);
532
+ for (let index = 0; index < nodes.length; index++) {
533
+ const node = nodes[index];
534
+ if (remaining < node.data.length || remaining === node.data.length && affinity === "backward") {
535
+ return { node, offset: remaining };
536
+ }
537
+ if (remaining === node.data.length && index === nodes.length - 1) {
538
+ return { node, offset: remaining };
539
+ }
540
+ remaining -= node.data.length;
541
+ }
542
+ const last = nodes[nodes.length - 1];
543
+ return { node: last, offset: last.data.length };
544
+ }
545
+ function selectProjectionUnit(selection, root, caret, unit) {
546
+ const absoluteOffset = projectionAbsoluteOffset(root, caret);
547
+ const text = _nullishCoalesce(root.textContent, () => ( ""));
548
+ if (absoluteOffset === null || text.length === 0) return false;
549
+ let start = absoluteOffset;
550
+ let end = absoluteOffset;
551
+ if (unit === "line") {
552
+ for (let index = Math.max(0, absoluteOffset - 1); index >= 0; index--) {
553
+ if (text[index] === "\n" || text[index] === "\r") {
554
+ start = index + 1;
555
+ if (text[index] === "\r" && text[index + 1] === "\n") start++;
556
+ break;
557
+ }
558
+ }
559
+ const cr = text.indexOf("\r", absoluteOffset);
560
+ const lf = text.indexOf("\n", absoluteOffset);
561
+ const separator = [cr, lf].filter((index) => index >= 0).sort((a, b) => a - b)[0];
562
+ end = separator === void 0 ? text.length : separator;
563
+ } else if (caretWordSegmenter) {
564
+ const segments = [...caretWordSegmenter.segment(text)];
565
+ const selected = _nullishCoalesce(_nullishCoalesce(segments.find(
566
+ (segment) => segment.isWordLike && absoluteOffset >= segment.index && absoluteOffset <= segment.index + segment.segment.length
567
+ ), () => ( segments.find((segment) => segment.isWordLike && segment.index >= absoluteOffset))), () => ( [...segments].reverse().find((segment) => segment.isWordLike)));
568
+ if (selected) {
569
+ start = selected.index;
570
+ end = selected.index + selected.segment.length;
571
+ }
572
+ } else {
573
+ const isWord = (character) => /[\p{L}\p{N}_]/u.test(character);
574
+ while (start > 0 && isWord(text[start - 1])) start--;
575
+ while (end < text.length && isWord(text[end])) end++;
576
+ }
577
+ const anchor = projectionCaretAt(root, start, "forward");
578
+ const focus = projectionCaretAt(root, end, "backward");
579
+ if (!anchor || !focus) return false;
580
+ selection.setBaseAndExtent(anchor.node, anchor.offset, focus.node, focus.offset);
581
+ return true;
582
+ }
583
+ function extendSelection(selection, anchor, focus) {
584
+ try {
585
+ selection.setBaseAndExtent(anchor.node, anchor.offset, focus.node, focus.offset);
586
+ return;
587
+ } catch (e3) {
588
+ }
589
+ try {
590
+ selection.collapse(anchor.node, anchor.offset);
591
+ selection.extend(focus.node, focus.offset);
592
+ return;
593
+ } catch (e4) {
594
+ }
595
+ const anchorRange = document.createRange();
596
+ anchorRange.setStart(anchor.node, anchor.offset);
597
+ anchorRange.collapse(true);
598
+ const focusRange = document.createRange();
599
+ focusRange.setStart(focus.node, focus.offset);
600
+ focusRange.collapse(true);
601
+ const range = document.createRange();
602
+ if (anchorRange.compareBoundaryPoints(Range.START_TO_START, focusRange) <= 0) {
603
+ range.setStart(anchor.node, anchor.offset);
604
+ range.setEnd(focus.node, focus.offset);
605
+ } else {
606
+ range.setStart(focus.node, focus.offset);
607
+ range.setEnd(anchor.node, anchor.offset);
608
+ }
609
+ selection.removeAllRanges();
610
+ selection.addRange(range);
611
+ }
320
612
  var Scene = (_class2 = class _Scene {
321
613
  static __initStatic() {this.webglCreator = null}
322
614
  static __initStatic2() {this.webgpuManagerClass = null}
@@ -355,7 +647,7 @@ var Scene = (_class2 = class _Scene {
355
647
  __init14() {this.reducedMotionQuery = null}
356
648
  /** True when the OS asks for reduced motion and we respect it. Read by the animation drivers. */
357
649
  get prefersReducedMotion() {
358
- return this.respectReducedMotion && !!_optionalChain([this, 'access', _13 => _13.reducedMotionQuery, 'optionalAccess', _14 => _14.matches]);
650
+ return this.respectReducedMotion && !!_optionalChain([this, 'access', _21 => _21.reducedMotionQuery, 'optionalAccess', _22 => _22.matches]);
359
651
  }
360
652
  /**
361
653
  * Throttle interval (ms) for the a11y/automation shadow sync. `0` = every
@@ -373,63 +665,81 @@ var Scene = (_class2 = class _Scene {
373
665
  __init18() {this.a11yElements = /* @__PURE__ */ new Map()}
374
666
  /** DOM nodes mirroring static text content, keyed by entity id. */
375
667
  __init19() {this.contentElements = /* @__PURE__ */ new Map()}
376
- __init20() {this.contentProjectionEnabled = true}
668
+ /** Pending cold font-calibration frame per projected grid entity. */
669
+ __init20() {this.contentGridCalibrationFrames = /* @__PURE__ */ new Map()}
670
+ /** Detached, untransformed font probes used by the cold calibration pass. */
671
+ __init21() {this.contentGridCalibrationProbes = /* @__PURE__ */ new Map()}
672
+ /** Invalidates grid font calibration after browser font availability changes. */
673
+ __init22() {this.contentFontEpoch = 0}
674
+ /** Cached Canvas-to-client scale for the current font/viewport epoch. */
675
+ __init23() {this.contentMetricScaleEpoch = -1}
676
+ __init24() {this.contentMetricScaleX = 1}
677
+ __init25() {this.contentProjectionEnabled = true}
678
+ /**
679
+ * True while a text-selection drag that started on a projection's blank
680
+ * region (no text node under the press) is being driven manually — the
681
+ * browser has no native anchor for it, so mousemove extends the Selection
682
+ * from the position we resolved ourselves.
683
+ */
684
+ __init26() {this.blankRegionSelectionDrag = false}
685
+ __init27() {this.contentSelectionAnchor = null}
686
+ __init28() {this.contentSelectionEndListener = null}
377
687
  // Animation/interactive flags collected during the render walk (tree-walk
378
688
  // fusion): the loop reads last frame's answers instead of re-walking the
379
689
  // tree up to 4× per tick. Start true so the first tick stays conservative.
380
- __init21() {this.frameHadAnimation = true}
381
- __init22() {this.frameHadInteractive = true}
690
+ __init29() {this.frameHadAnimation = true}
691
+ __init30() {this.frameHadInteractive = true}
382
692
 
383
- __init23() {this.focusedA11yElement = null}
384
- __init24() {this.caretBlinkTimer = null}
385
- __init25() {this.a11yNeedsReorder = true}
386
- __init26() {this.portalRoot = null}
387
- __init27() {this.fullViewportElements = []}
388
- __init28() {this.normalElements = []}
389
- __init29() {this.activeIds = /* @__PURE__ */ new Set()}
390
- __init30() {this.activePortalsThisFrame = /* @__PURE__ */ new Set()}
391
- __init31() {this.activePortalsPrevFrame = /* @__PURE__ */ new Set()}
392
- __init32() {this.portalEntities = /* @__PURE__ */ new Map()}
393
- __init33() {this.renderOrderCounter = 0}
693
+ __init31() {this.focusedA11yElement = null}
694
+ __init32() {this.caretBlinkTimer = null}
695
+ __init33() {this.a11yNeedsReorder = true}
696
+ __init34() {this.portalRoot = null}
697
+ __init35() {this.fullViewportElements = []}
698
+ __init36() {this.normalElements = []}
699
+ __init37() {this.activeIds = /* @__PURE__ */ new Set()}
700
+ __init38() {this.activePortalsThisFrame = /* @__PURE__ */ new Set()}
701
+ __init39() {this.activePortalsPrevFrame = /* @__PURE__ */ new Set()}
702
+ __init40() {this.portalEntities = /* @__PURE__ */ new Map()}
703
+ __init41() {this.renderOrderCounter = 0}
394
704
  // Optional WebGL point-cloud layer (see SceneOptions.pointBackend).
395
- __init34() {this.pointRenderer = null}
396
- __init35() {this.glCanvas = null}
705
+ __init42() {this.pointRenderer = null}
706
+ __init43() {this.glCanvas = null}
397
707
 
398
708
 
399
709
 
400
- __init36() {this.disableWindowResize = false}
710
+ __init44() {this.disableWindowResize = false}
401
711
  // WebGPU properties
402
- __init37() {this.destroyed = false}
403
- __init38() {this.device = null}
404
- __init39() {this.deviceLost = false}
405
- __init40() {this.particleBackend = "auto"}
406
- __init41() {this._webgpuDisabled = false}
712
+ __init45() {this.destroyed = false}
713
+ __init46() {this.device = null}
714
+ __init47() {this.deviceLost = false}
715
+ __init48() {this.particleBackend = "auto"}
716
+ __init49() {this._webgpuDisabled = false}
407
717
  get webgpuDisabled() {
408
718
  return this._webgpuDisabled || this.particleBackend === "cpu";
409
719
  }
410
720
  set webgpuDisabled(value) {
411
721
  this._webgpuDisabled = value;
412
722
  }
413
- __init42() {this.recoveryTimerId = null}
414
- __init43() {this.manager = null}
415
- __init44() {this.initializingWebGPU = false}
416
- __init45() {this.gpuCanvas = null}
417
- __init46() {this.gpuContext = null}
723
+ __init50() {this.recoveryTimerId = null}
724
+ __init51() {this.manager = null}
725
+ __init52() {this.initializingWebGPU = false}
726
+ __init53() {this.gpuCanvas = null}
727
+ __init54() {this.gpuContext = null}
418
728
  /** True while the GPU canvas holds a presented particle frame (needs clearing when they leave). */
419
- __init47() {this.gpuHasContent = false}
420
- __init48() {this.mouseX = -9999}
421
- __init49() {this.mouseY = -9999}
422
- __init50() {this.pointerMoveListener = null}
423
- __init51() {this.pointerLeaveListener = null}
424
- __init52() {this.hasWarnedZeroSize = false}
425
- __init53() {this.fontLoadHandler = null}
426
- constructor(canvas, options = {}) {;_class2.prototype.__init7.call(this);_class2.prototype.__init8.call(this);_class2.prototype.__init9.call(this);_class2.prototype.__init10.call(this);_class2.prototype.__init11.call(this);_class2.prototype.__init12.call(this);_class2.prototype.__init13.call(this);_class2.prototype.__init14.call(this);_class2.prototype.__init15.call(this);_class2.prototype.__init16.call(this);_class2.prototype.__init17.call(this);_class2.prototype.__init18.call(this);_class2.prototype.__init19.call(this);_class2.prototype.__init20.call(this);_class2.prototype.__init21.call(this);_class2.prototype.__init22.call(this);_class2.prototype.__init23.call(this);_class2.prototype.__init24.call(this);_class2.prototype.__init25.call(this);_class2.prototype.__init26.call(this);_class2.prototype.__init27.call(this);_class2.prototype.__init28.call(this);_class2.prototype.__init29.call(this);_class2.prototype.__init30.call(this);_class2.prototype.__init31.call(this);_class2.prototype.__init32.call(this);_class2.prototype.__init33.call(this);_class2.prototype.__init34.call(this);_class2.prototype.__init35.call(this);_class2.prototype.__init36.call(this);_class2.prototype.__init37.call(this);_class2.prototype.__init38.call(this);_class2.prototype.__init39.call(this);_class2.prototype.__init40.call(this);_class2.prototype.__init41.call(this);_class2.prototype.__init42.call(this);_class2.prototype.__init43.call(this);_class2.prototype.__init44.call(this);_class2.prototype.__init45.call(this);_class2.prototype.__init46.call(this);_class2.prototype.__init47.call(this);_class2.prototype.__init48.call(this);_class2.prototype.__init49.call(this);_class2.prototype.__init50.call(this);_class2.prototype.__init51.call(this);_class2.prototype.__init52.call(this);_class2.prototype.__init53.call(this);
729
+ __init55() {this.gpuHasContent = false}
730
+ __init56() {this.mouseX = -9999}
731
+ __init57() {this.mouseY = -9999}
732
+ __init58() {this.pointerMoveListener = null}
733
+ __init59() {this.pointerLeaveListener = null}
734
+ __init60() {this.hasWarnedZeroSize = false}
735
+ __init61() {this.fontLoadHandler = null}
736
+ constructor(canvas, options = {}) {;_class2.prototype.__init7.call(this);_class2.prototype.__init8.call(this);_class2.prototype.__init9.call(this);_class2.prototype.__init10.call(this);_class2.prototype.__init11.call(this);_class2.prototype.__init12.call(this);_class2.prototype.__init13.call(this);_class2.prototype.__init14.call(this);_class2.prototype.__init15.call(this);_class2.prototype.__init16.call(this);_class2.prototype.__init17.call(this);_class2.prototype.__init18.call(this);_class2.prototype.__init19.call(this);_class2.prototype.__init20.call(this);_class2.prototype.__init21.call(this);_class2.prototype.__init22.call(this);_class2.prototype.__init23.call(this);_class2.prototype.__init24.call(this);_class2.prototype.__init25.call(this);_class2.prototype.__init26.call(this);_class2.prototype.__init27.call(this);_class2.prototype.__init28.call(this);_class2.prototype.__init29.call(this);_class2.prototype.__init30.call(this);_class2.prototype.__init31.call(this);_class2.prototype.__init32.call(this);_class2.prototype.__init33.call(this);_class2.prototype.__init34.call(this);_class2.prototype.__init35.call(this);_class2.prototype.__init36.call(this);_class2.prototype.__init37.call(this);_class2.prototype.__init38.call(this);_class2.prototype.__init39.call(this);_class2.prototype.__init40.call(this);_class2.prototype.__init41.call(this);_class2.prototype.__init42.call(this);_class2.prototype.__init43.call(this);_class2.prototype.__init44.call(this);_class2.prototype.__init45.call(this);_class2.prototype.__init46.call(this);_class2.prototype.__init47.call(this);_class2.prototype.__init48.call(this);_class2.prototype.__init49.call(this);_class2.prototype.__init50.call(this);_class2.prototype.__init51.call(this);_class2.prototype.__init52.call(this);_class2.prototype.__init53.call(this);_class2.prototype.__init54.call(this);_class2.prototype.__init55.call(this);_class2.prototype.__init56.call(this);_class2.prototype.__init57.call(this);_class2.prototype.__init58.call(this);_class2.prototype.__init59.call(this);_class2.prototype.__init60.call(this);_class2.prototype.__init61.call(this);
427
737
  this.canvas = canvas;
428
738
  this.debugA11y = _nullishCoalesce(options.debugA11y, () => ( false));
429
739
  this.disableWindowResize = _nullishCoalesce(options.disableWindowResize, () => ( false));
430
740
  if (this.disableWindowResize) {
431
- const styleWidth = parseInlinePx(_optionalChain([canvas, 'access', _15 => _15.style, 'optionalAccess', _16 => _16.width]));
432
- const styleHeight = parseInlinePx(_optionalChain([canvas, 'access', _17 => _17.style, 'optionalAccess', _18 => _18.height]));
741
+ const styleWidth = parseInlinePx(_optionalChain([canvas, 'access', _23 => _23.style, 'optionalAccess', _24 => _24.width]));
742
+ const styleHeight = parseInlinePx(_optionalChain([canvas, 'access', _25 => _25.style, 'optionalAccess', _26 => _26.height]));
433
743
  this.width = _nullishCoalesce(styleWidth, () => ( (canvas.width || canvas.clientWidth || 0)));
434
744
  this.height = _nullishCoalesce(styleHeight, () => ( (canvas.height || canvas.clientHeight || 0)));
435
745
  } else {
@@ -437,7 +747,7 @@ var Scene = (_class2 = class _Scene {
437
747
  this.height = typeof window !== "undefined" ? window.innerHeight : canvas.clientHeight || canvas.height || 600;
438
748
  }
439
749
  const globalProcess = typeof globalThis !== "undefined" ? globalThis.process : void 0;
440
- const isTest = globalProcess && (_optionalChain([globalProcess, 'access', _19 => _19.env, 'optionalAccess', _20 => _20.NODE_ENV]) === "test" || _optionalChain([globalProcess, 'access', _21 => _21.env, 'optionalAccess', _22 => _22.VITEST]) === "true");
750
+ const isTest = globalProcess && (_optionalChain([globalProcess, 'access', _27 => _27.env, 'optionalAccess', _28 => _28.NODE_ENV]) === "test" || _optionalChain([globalProcess, 'access', _29 => _29.env, 'optionalAccess', _30 => _30.VITEST]) === "true");
441
751
  this.maxFPS = _nullishCoalesce(options.maxFPS, () => ( (isTest ? 0 : 60)));
442
752
  this.respectReducedMotion = _nullishCoalesce(options.respectReducedMotion, () => ( true));
443
753
  this.autoThrottle = _nullishCoalesce(options.autoThrottle, () => ( true));
@@ -445,7 +755,7 @@ var Scene = (_class2 = class _Scene {
445
755
  this.a11ySyncInterval = _nullishCoalesce(options.a11ySyncInterval, () => ( 0));
446
756
  this.contentProjectionEnabled = _nullishCoalesce(options.contentProjection, () => ( true));
447
757
  this.reducedMotionQuery = typeof window !== "undefined" && typeof window.matchMedia === "function" ? window.matchMedia("(prefers-reduced-motion: reduce)") : null;
448
- this.root = new class RootEntity extends _chunkDFNK6OV6js.Entity {
758
+ this.root = new class RootEntity extends _chunkFIQAIF55js.Entity {
449
759
  isPointInside() {
450
760
  return false;
451
761
  }
@@ -454,7 +764,7 @@ var Scene = (_class2 = class _Scene {
454
764
  }
455
765
  }("root");
456
766
  this.root._scene = this;
457
- this.overlayRoot = new class OverlayRoot extends _chunkDFNK6OV6js.Entity {
767
+ this.overlayRoot = new class OverlayRoot extends _chunkFIQAIF55js.Entity {
458
768
  isPointInside() {
459
769
  return false;
460
770
  }
@@ -480,6 +790,90 @@ var Scene = (_class2 = class _Scene {
480
790
  this.a11yRoot.style.pointerEvents = "none";
481
791
  this.a11yRoot.style.overflow = "hidden";
482
792
  this.a11yRoot.style.zIndex = "10";
793
+ this.a11yRoot.style.userSelect = "text";
794
+ this.a11yRoot.addEventListener("mousedown", (e) => {
795
+ if (e.button !== 0) return;
796
+ const target = e.target;
797
+ const contentEl = target.closest("[data-vecto-content]");
798
+ if (target === this.a11yRoot || !contentEl) return;
799
+ if (getComputedStyle(contentEl).pointerEvents !== "auto") return;
800
+ const selection = window.getSelection();
801
+ if (!selection) return;
802
+ this.a11yRoot.style.pointerEvents = "auto";
803
+ const resolved = nearestTextPositionInProjection(
804
+ contentEl,
805
+ this.canvas,
806
+ e.clientX,
807
+ e.clientY,
808
+ target
809
+ );
810
+ if (resolved) {
811
+ if (e.detail >= 2) {
812
+ selection.removeAllRanges();
813
+ selectProjectionUnit(selection, contentEl, resolved, e.detail >= 3 ? "line" : "word");
814
+ this.endContentSelectionDrag();
815
+ e.preventDefault();
816
+ return;
817
+ }
818
+ const existingAnchor = e.shiftKey && selection.anchorNode instanceof Text ? { node: selection.anchorNode, offset: selection.anchorOffset } : null;
819
+ const anchor = existingAnchor && this.a11yRoot.contains(existingAnchor.node) ? existingAnchor : resolved;
820
+ if (e.shiftKey && existingAnchor) extendSelection(selection, anchor, resolved);
821
+ else selection.collapse(resolved.node, resolved.offset);
822
+ this.contentSelectionAnchor = anchor;
823
+ this.blankRegionSelectionDrag = true;
824
+ e.preventDefault();
825
+ }
826
+ });
827
+ this.a11yRoot.addEventListener("dblclick", (e) => {
828
+ const target = e.target;
829
+ const contentEl = target.closest("[data-vecto-content]");
830
+ if (!contentEl || getComputedStyle(contentEl).pointerEvents !== "auto") return;
831
+ const selection = window.getSelection();
832
+ const caret = nearestTextPositionInProjection(
833
+ contentEl,
834
+ this.canvas,
835
+ e.clientX,
836
+ e.clientY,
837
+ target
838
+ );
839
+ if (!selection || !caret) return;
840
+ selection.removeAllRanges();
841
+ selectProjectionUnit(selection, contentEl, caret, "word");
842
+ this.endContentSelectionDrag();
843
+ e.preventDefault();
844
+ });
845
+ this.a11yRoot.addEventListener("mousemove", (e) => {
846
+ if (!this.blankRegionSelectionDrag) return;
847
+ const selection = window.getSelection();
848
+ if (!selection || selection.rangeCount === 0) return;
849
+ const target = e.target;
850
+ let contentEl = target.closest("[data-vecto-content]");
851
+ if (!contentEl) {
852
+ let bestDistance = Infinity;
853
+ for (const candidate of this.contentElements.values()) {
854
+ if (getComputedStyle(candidate).pointerEvents !== "auto") continue;
855
+ const rect = candidate.getBoundingClientRect();
856
+ const dx = e.clientX < rect.left ? rect.left - e.clientX : e.clientX > rect.right ? e.clientX - rect.right : 0;
857
+ const dy = e.clientY < rect.top ? rect.top - e.clientY : e.clientY > rect.bottom ? e.clientY - rect.bottom : 0;
858
+ const distance = dx * dx + dy * dy;
859
+ if (distance < bestDistance) {
860
+ bestDistance = distance;
861
+ contentEl = candidate;
862
+ }
863
+ }
864
+ }
865
+ const focus = contentEl ? nearestTextPositionInProjection(contentEl, this.canvas, e.clientX, e.clientY, target) : null;
866
+ const anchor = this.contentSelectionAnchor;
867
+ if (focus && anchor) {
868
+ extendSelection(selection, anchor, focus);
869
+ }
870
+ });
871
+ const endDrag = () => this.endContentSelectionDrag();
872
+ this.a11yRoot.addEventListener("mouseup", endDrag);
873
+ this.a11yRoot.addEventListener("mouseleave", endDrag);
874
+ window.addEventListener("mouseup", endDrag);
875
+ window.addEventListener("blur", endDrag);
876
+ this.contentSelectionEndListener = endDrag;
483
877
  if (canvas.parentElement) {
484
878
  canvas.parentElement.appendChild(this.a11yRoot);
485
879
  }
@@ -521,7 +915,8 @@ var Scene = (_class2 = class _Scene {
521
915
  };
522
916
  if (typeof document !== "undefined" && document.fonts) {
523
917
  this.fontLoadHandler = () => {
524
- _chunkDFNK6OV6js.clearCssLineBoxMetrics.call(void 0, );
918
+ _chunkFIQAIF55js.clearCssLineBoxMetrics.call(void 0, );
919
+ this.contentFontEpoch++;
525
920
  this.markDirty();
526
921
  };
527
922
  document.fonts.ready.then(this.fontLoadHandler);
@@ -529,6 +924,18 @@ var Scene = (_class2 = class _Scene {
529
924
  }
530
925
  this.setupEvents();
531
926
  }
927
+ endContentSelectionDrag() {
928
+ this.blankRegionSelectionDrag = false;
929
+ this.contentSelectionAnchor = null;
930
+ if (this.a11yRoot) this.a11yRoot.style.pointerEvents = "none";
931
+ }
932
+ releaseContentSelectionForRebuild(el) {
933
+ const selection = typeof window !== "undefined" && typeof window.getSelection === "function" ? window.getSelection() : null;
934
+ const ownsSelection = this.contentSelectionAnchor && el.contains(this.contentSelectionAnchor.node) || (_optionalChain([selection, 'optionalAccess', _31 => _31.anchorNode]) ? el.contains(selection.anchorNode) : false) || (_optionalChain([selection, 'optionalAccess', _32 => _32.focusNode]) ? el.contains(selection.focusNode) : false);
935
+ if (!ownsSelection) return;
936
+ this.endContentSelectionDrag();
937
+ _optionalChain([selection, 'optionalAccess', _33 => _33.removeAllRanges, 'call', _34 => _34()]);
938
+ }
532
939
  /**
533
940
  * Expose the underlying {@link IRenderer} for advanced direct-draw operations.
534
941
  *
@@ -539,7 +946,7 @@ var Scene = (_class2 = class _Scene {
539
946
  }
540
947
  /** Convert browser viewport coordinates into this Scene's logical coordinates. */
541
948
  clientToScene(clientX, clientY) {
542
- const rect = _optionalChain([this, 'access', _23 => _23.canvas, 'access', _24 => _24.getBoundingClientRect, 'optionalCall', _25 => _25()]);
949
+ const rect = _optionalChain([this, 'access', _35 => _35.canvas, 'access', _36 => _36.getBoundingClientRect, 'optionalCall', _37 => _37()]);
543
950
  if (!rect) return { x: clientX, y: clientY };
544
951
  const cssWidth = rect.width || this.canvas.clientWidth || this.width;
545
952
  const cssHeight = rect.height || this.canvas.clientHeight || this.height;
@@ -559,6 +966,24 @@ var Scene = (_class2 = class _Scene {
559
966
  this.root.add(entity);
560
967
  return this;
561
968
  }
969
+ clearContentGridState(entityId, el) {
970
+ const calibrationFrame = this.contentGridCalibrationFrames.get(entityId);
971
+ if (calibrationFrame !== void 0 && typeof cancelAnimationFrame === "function") {
972
+ cancelAnimationFrame(calibrationFrame);
973
+ }
974
+ this.contentGridCalibrationFrames.delete(entityId);
975
+ _optionalChain([this, 'access', _38 => _38.contentGridCalibrationProbes, 'access', _39 => _39.get, 'call', _40 => _40(entityId), 'optionalAccess', _41 => _41.remove, 'call', _42 => _42()]);
976
+ this.contentGridCalibrationProbes.delete(entityId);
977
+ delete el.dataset.vectoGridCalibrationPending;
978
+ delete el.dataset.vectoGridCalibration;
979
+ delete el.dataset.vectoGridReady;
980
+ delete el.dataset.vectoContentGrid;
981
+ delete el.dataset.vectoGridCarriers;
982
+ delete el.dataset.vectoGridMaterializeMs;
983
+ delete el.dataset.vectoGridCalibrationSamples;
984
+ delete el.dataset.vectoGridCalibrationMs;
985
+ this.releaseContentSelectionForRebuild(el);
986
+ }
562
987
  removeA11yRecursively(node) {
563
988
  if (node.isDOMPortal) {
564
989
  node.domElement.remove();
@@ -568,6 +993,7 @@ var Scene = (_class2 = class _Scene {
568
993
  }
569
994
  const contentEl = this.contentElements.get(node.id);
570
995
  if (contentEl) {
996
+ this.clearContentGridState(node.id, contentEl);
571
997
  contentEl.remove();
572
998
  this.contentElements.delete(node.id);
573
999
  this.a11yNeedsReorder = true;
@@ -649,6 +1075,11 @@ var Scene = (_class2 = class _Scene {
649
1075
  if (typeof window !== "undefined" && !this.disableWindowResize) {
650
1076
  window.removeEventListener("resize", this.resizeHandler);
651
1077
  }
1078
+ if (typeof window !== "undefined" && this.contentSelectionEndListener) {
1079
+ window.removeEventListener("mouseup", this.contentSelectionEndListener);
1080
+ window.removeEventListener("blur", this.contentSelectionEndListener);
1081
+ this.contentSelectionEndListener = null;
1082
+ }
652
1083
  if (typeof window !== "undefined" && this.canvas && typeof this.canvas.removeEventListener === "function") {
653
1084
  if (this.pointerMoveListener) {
654
1085
  this.canvas.removeEventListener("pointermove", this.pointerMoveListener);
@@ -657,15 +1088,24 @@ var Scene = (_class2 = class _Scene {
657
1088
  this.canvas.removeEventListener("pointerleave", this.pointerLeaveListener);
658
1089
  }
659
1090
  }
660
- _optionalChain([this, 'access', _26 => _26.a11yRoot, 'optionalAccess', _27 => _27.remove, 'call', _28 => _28()]);
661
- _optionalChain([this, 'access', _29 => _29.portalRoot, 'optionalAccess', _30 => _30.remove, 'call', _31 => _31()]);
1091
+ _optionalChain([this, 'access', _43 => _43.a11yRoot, 'optionalAccess', _44 => _44.remove, 'call', _45 => _45()]);
1092
+ _optionalChain([this, 'access', _46 => _46.portalRoot, 'optionalAccess', _47 => _47.remove, 'call', _48 => _48()]);
662
1093
  this.a11yElements.clear();
663
1094
  for (const el of this.contentElements.values()) el.remove();
664
1095
  this.contentElements.clear();
665
- _optionalChain([this, 'access', _32 => _32.pointRenderer, 'optionalAccess', _33 => _33.destroy, 'call', _34 => _34()]);
666
- _optionalChain([this, 'access', _35 => _35.renderer, 'access', _36 => _36.dispose, 'optionalCall', _37 => _37()]);
667
- _optionalChain([this, 'access', _38 => _38.glCanvas, 'optionalAccess', _39 => _39.remove, 'call', _40 => _40()]);
668
- _optionalChain([this, 'access', _41 => _41.gpuCanvas, 'optionalAccess', _42 => _42.remove, 'call', _43 => _43()]);
1096
+ if (typeof cancelAnimationFrame === "function") {
1097
+ for (const frame of this.contentGridCalibrationFrames.values()) {
1098
+ cancelAnimationFrame(frame);
1099
+ }
1100
+ }
1101
+ this.contentGridCalibrationFrames.clear();
1102
+ for (const probe of this.contentGridCalibrationProbes.values()) probe.remove();
1103
+ this.contentGridCalibrationProbes.clear();
1104
+ this.endContentSelectionDrag();
1105
+ _optionalChain([this, 'access', _49 => _49.pointRenderer, 'optionalAccess', _50 => _50.destroy, 'call', _51 => _51()]);
1106
+ _optionalChain([this, 'access', _52 => _52.renderer, 'access', _53 => _53.dispose, 'optionalCall', _54 => _54()]);
1107
+ _optionalChain([this, 'access', _55 => _55.glCanvas, 'optionalAccess', _56 => _56.remove, 'call', _57 => _57()]);
1108
+ _optionalChain([this, 'access', _58 => _58.gpuCanvas, 'optionalAccess', _59 => _59.remove, 'call', _60 => _60()]);
669
1109
  this.gpuCanvas = null;
670
1110
  this.gpuContext = null;
671
1111
  if (this.recoveryTimerId) {
@@ -677,7 +1117,7 @@ var Scene = (_class2 = class _Scene {
677
1117
  this.manager = null;
678
1118
  }
679
1119
  if (this.device) {
680
- _optionalChain([this, 'access', _44 => _44.device, 'access', _45 => _45.destroy, 'optionalCall', _46 => _46()]);
1120
+ _optionalChain([this, 'access', _61 => _61.device, 'access', _62 => _62.destroy, 'optionalCall', _63 => _63()]);
681
1121
  this.device = null;
682
1122
  }
683
1123
  }
@@ -819,15 +1259,15 @@ var Scene = (_class2 = class _Scene {
819
1259
  el.style.background = "transparent";
820
1260
  }
821
1261
  el.addEventListener("click", (e) => {
822
- node.dispatchEvent(new (0, _chunkDFNK6OV6js.VectoJSEvent)("click", node, e));
1262
+ node.dispatchEvent(new (0, _chunkFIQAIF55js.VectoJSEvent)("click", node, e));
823
1263
  });
824
1264
  el.addEventListener("mouseenter", (e) => {
825
1265
  if (this.debugA11y) el.style.backgroundColor = "rgba(56, 189, 248, 0.2)";
826
- node.dispatchEvent(new (0, _chunkDFNK6OV6js.VectoJSEvent)("hover", node, e, false));
1266
+ node.dispatchEvent(new (0, _chunkFIQAIF55js.VectoJSEvent)("hover", node, e, false));
827
1267
  });
828
1268
  el.addEventListener("mouseleave", (e) => {
829
1269
  if (this.debugA11y) el.style.backgroundColor = "rgba(56, 189, 248, 0.05)";
830
- node.dispatchEvent(new (0, _chunkDFNK6OV6js.VectoJSEvent)("pointerleave", node, e, false));
1270
+ node.dispatchEvent(new (0, _chunkFIQAIF55js.VectoJSEvent)("pointerleave", node, e, false));
831
1271
  });
832
1272
  const capEl = el;
833
1273
  const releasePointer = (event) => {
@@ -843,32 +1283,32 @@ var Scene = (_class2 = class _Scene {
843
1283
  };
844
1284
  el.addEventListener("pointerdown", (e) => {
845
1285
  if (typeof capEl.setPointerCapture === "function") capEl.setPointerCapture(e.pointerId);
846
- node.dispatchEvent(new (0, _chunkDFNK6OV6js.VectoJSEvent)("pointerdown", node, e));
1286
+ node.dispatchEvent(new (0, _chunkFIQAIF55js.VectoJSEvent)("pointerdown", node, e));
847
1287
  });
848
1288
  el.addEventListener("pointerup", (e) => {
849
1289
  releasePointer(e);
850
- node.dispatchEvent(new (0, _chunkDFNK6OV6js.VectoJSEvent)("pointerup", node, e));
1290
+ node.dispatchEvent(new (0, _chunkFIQAIF55js.VectoJSEvent)("pointerup", node, e));
851
1291
  });
852
1292
  el.addEventListener("pointercancel", (e) => {
853
1293
  releasePointer(e);
854
- node.dispatchEvent(new (0, _chunkDFNK6OV6js.VectoJSEvent)("pointercancel", node, e));
1294
+ node.dispatchEvent(new (0, _chunkFIQAIF55js.VectoJSEvent)("pointercancel", node, e));
855
1295
  });
856
1296
  el.addEventListener(
857
1297
  "pointermove",
858
- (e) => node.dispatchEvent(new (0, _chunkDFNK6OV6js.VectoJSEvent)("pointermove", node, e))
1298
+ (e) => node.dispatchEvent(new (0, _chunkFIQAIF55js.VectoJSEvent)("pointermove", node, e))
859
1299
  );
860
1300
  el.addEventListener(
861
1301
  "wheel",
862
1302
  (e) => {
863
- node.dispatchEvent(new (0, _chunkDFNK6OV6js.VectoJSEvent)("wheel", node, e));
1303
+ node.dispatchEvent(new (0, _chunkFIQAIF55js.VectoJSEvent)("wheel", node, e));
864
1304
  },
865
1305
  { passive: false }
866
1306
  );
867
1307
  el.addEventListener("keydown", (e) => {
868
- node.dispatchEvent(new (0, _chunkDFNK6OV6js.VectoJSEvent)("keydown", node, e));
1308
+ node.dispatchEvent(new (0, _chunkFIQAIF55js.VectoJSEvent)("keydown", node, e));
869
1309
  });
870
1310
  el.addEventListener("keyup", (e) => {
871
- node.dispatchEvent(new (0, _chunkDFNK6OV6js.VectoJSEvent)("keyup", node, e));
1311
+ node.dispatchEvent(new (0, _chunkFIQAIF55js.VectoJSEvent)("keyup", node, e));
872
1312
  });
873
1313
  if (el instanceof HTMLInputElement || el instanceof HTMLTextAreaElement) {
874
1314
  const input = el;
@@ -895,7 +1335,7 @@ var Scene = (_class2 = class _Scene {
895
1335
  });
896
1336
  el.addEventListener("compositionupdate", (e) => {
897
1337
  const data = _nullishCoalesce(e.data, () => ( ""));
898
- composition = { start: _nullishCoalesce(_optionalChain([composition, 'optionalAccess', _47 => _47.start]), () => ( 0)), length: data.length };
1338
+ composition = { start: _nullishCoalesce(_optionalChain([composition, 'optionalAccess', _64 => _64.start]), () => ( 0)), length: data.length };
899
1339
  forward();
900
1340
  });
901
1341
  el.addEventListener("compositionend", () => {
@@ -928,7 +1368,7 @@ var Scene = (_class2 = class _Scene {
928
1368
  el.addEventListener("keydown", (e) => {
929
1369
  if (e.key === "Enter" || e.key === " ") {
930
1370
  e.preventDefault();
931
- node.dispatchEvent(new (0, _chunkDFNK6OV6js.VectoJSEvent)("click", node, e));
1371
+ node.dispatchEvent(new (0, _chunkFIQAIF55js.VectoJSEvent)("click", node, e));
932
1372
  }
933
1373
  });
934
1374
  }
@@ -946,6 +1386,10 @@ var Scene = (_class2 = class _Scene {
946
1386
  if (attrs.label !== void 0 && el.getAttribute("aria-label") !== attrs.label) {
947
1387
  el.setAttribute("aria-label", attrs.label);
948
1388
  }
1389
+ const semanticPointerEvents = _nullishCoalesce(attrs.pointerEvents, () => ( "auto"));
1390
+ if (el.style.pointerEvents !== semanticPointerEvents) {
1391
+ el.style.pointerEvents = semanticPointerEvents;
1392
+ }
949
1393
  const implicitTabIndex = !isNativelyFocusable(el) && attrs.role && INTERACTIVE_A11Y_ROLES.has(attrs.role) ? 0 : null;
950
1394
  const desiredTabIndex = _nullishCoalesce(attrs.tabIndex, () => ( implicitTabIndex));
951
1395
  if (desiredTabIndex === null) {
@@ -1062,6 +1506,7 @@ var Scene = (_class2 = class _Scene {
1062
1506
  let el = this.contentElements.get(node.id);
1063
1507
  if (!projection || !projection.text) {
1064
1508
  if (el) {
1509
+ this.clearContentGridState(node.id, el);
1065
1510
  el.remove();
1066
1511
  this.contentElements.delete(node.id);
1067
1512
  this.a11yNeedsReorder = true;
@@ -1080,12 +1525,11 @@ var Scene = (_class2 = class _Scene {
1080
1525
  s.forcedColorAdjust = "none";
1081
1526
  s.setProperty("-webkit-text-fill-color", "transparent");
1082
1527
  s.whiteSpace = "pre-wrap";
1083
- s.overflow = "hidden";
1084
1528
  s.zIndex = "0";
1085
1529
  el.addEventListener(
1086
1530
  "wheel",
1087
1531
  (e2) => {
1088
- node.dispatchEvent(new (0, _chunkDFNK6OV6js.VectoJSEvent)("wheel", node, e2));
1532
+ node.dispatchEvent(new (0, _chunkFIQAIF55js.VectoJSEvent)("wheel", node, e2));
1089
1533
  },
1090
1534
  { passive: false }
1091
1535
  );
@@ -1094,13 +1538,19 @@ var Scene = (_class2 = class _Scene {
1094
1538
  this.a11yNeedsReorder = true;
1095
1539
  }
1096
1540
  const lines = projection.lines;
1097
- if (lines && lines.length > 0) {
1541
+ if (!projection.grid && el.dataset.vectoContentGrid !== void 0) {
1542
+ this.clearContentGridState(node.id, el);
1543
+ }
1544
+ if (projection.grid) {
1545
+ this.syncContentGridProjection(node, el, projection, projection.grid);
1546
+ } else if (lines && lines.length > 0) {
1098
1547
  const signature = JSON.stringify({
1099
1548
  lines,
1100
1549
  fallbackFont: _nullishCoalesce(projection.font, () => ( "")),
1101
1550
  fallbackLineHeight: _nullishCoalesce(projection.lineHeight, () => ( 16))
1102
1551
  });
1103
1552
  if (el.dataset.vectoProjectionLines !== signature) {
1553
+ this.releaseContentSelectionForRebuild(el);
1104
1554
  el.replaceChildren();
1105
1555
  for (let index = 0; index < lines.length; index++) {
1106
1556
  const line = lines[index];
@@ -1110,7 +1560,7 @@ var Scene = (_class2 = class _Scene {
1110
1560
  lineElement.style.position = "absolute";
1111
1561
  lineElement.dir = "auto";
1112
1562
  lineElement.style.left = `${line.x}px`;
1113
- lineElement.style.top = `${line.y + line.baseline - _chunkDFNK6OV6js.cssLineBoxBaseline.call(void 0, lineFont, lineHeight2)}px`;
1563
+ lineElement.style.top = `${line.y + line.baseline - _chunkFIQAIF55js.cssLineBoxBaseline.call(void 0, lineFont, lineHeight2)}px`;
1114
1564
  lineElement.style.whiteSpace = "pre";
1115
1565
  if (lineFont) lineElement.style.font = lineFont;
1116
1566
  lineElement.style.lineHeight = `${lineHeight2}px`;
@@ -1132,13 +1582,21 @@ var Scene = (_class2 = class _Scene {
1132
1582
  el.dataset.vectoProjectionLines = signature;
1133
1583
  }
1134
1584
  } else {
1135
- if (el.textContent !== projection.text) el.textContent = projection.text;
1585
+ if (el.textContent !== projection.text) {
1586
+ this.releaseContentSelectionForRebuild(el);
1587
+ el.textContent = projection.text;
1588
+ }
1136
1589
  delete el.dataset.vectoProjectionLines;
1137
1590
  }
1138
1591
  const font = _nullishCoalesce(projection.font, () => ( ""));
1139
1592
  if (el.style.font !== font) el.style.font = font;
1140
1593
  const lineHeight = projection.lineHeight !== void 0 ? `${projection.lineHeight}px` : "";
1141
1594
  if (el.style.lineHeight !== lineHeight) el.style.lineHeight = lineHeight;
1595
+ const ligatures = projection.ligatures === "none" ? "none" : "";
1596
+ if (el.style.getPropertyValue("font-variant-ligatures") !== ligatures) {
1597
+ el.style.setProperty("font-variant-ligatures", ligatures);
1598
+ el.style.setProperty("font-kerning", ligatures ? "none" : "");
1599
+ }
1142
1600
  const hidden = node.interactive ? "true" : null;
1143
1601
  if (el.getAttribute("aria-hidden") !== hidden) {
1144
1602
  if (hidden) el.setAttribute("aria-hidden", hidden);
@@ -1154,7 +1612,7 @@ var Scene = (_class2 = class _Scene {
1154
1612
  const { a, b, c, d, e, f } = node.getWorldTransform();
1155
1613
  const contentX = _nullishCoalesce(projection.contentX, () => ( 0));
1156
1614
  const contentY = _nullishCoalesce(projection.contentY, () => ( 0));
1157
- const baselineOffset = lines && lines.length > 0 ? 0 : projection.baseline === void 0 ? 0 : projection.baseline - _chunkDFNK6OV6js.cssLineBoxBaseline.call(void 0, font, _nullishCoalesce(projection.lineHeight, () => ( 16)));
1615
+ const baselineOffset = lines && lines.length > 0 ? 0 : projection.baseline === void 0 ? 0 : projection.baseline - _chunkFIQAIF55js.cssLineBoxBaseline.call(void 0, font, _nullishCoalesce(projection.lineHeight, () => ( 16)));
1158
1616
  const localY = contentY + baselineOffset;
1159
1617
  el.style.left = `${e + a * contentX + c * localY}px`;
1160
1618
  el.style.top = `${f + b * contentX + d * localY}px`;
@@ -1200,6 +1658,245 @@ var Scene = (_class2 = class _Scene {
1200
1658
  const display = visible ? "" : "none";
1201
1659
  if (el.style.display !== display) el.style.display = display;
1202
1660
  }
1661
+ /**
1662
+ * Materialize a prepared grid in logical source order while positioning each
1663
+ * carrier from the shared canvas geometry. Browser font measurement happens
1664
+ * later in one cold read/write batch, never inside projection synchronization.
1665
+ */
1666
+ syncContentGridProjection(node, el, projection, grid) {
1667
+ if (grid.source !== projection.text) {
1668
+ throw new Error("ContentProjection.grid.source must equal ContentProjection.text");
1669
+ }
1670
+ const signature = `${grid.revision}`;
1671
+ if (el.dataset.vectoContentGrid !== signature) {
1672
+ const materializeStart = typeof performance !== "undefined" ? performance.now() : 0;
1673
+ this.clearContentGridState(node.id, el);
1674
+ el.replaceChildren();
1675
+ const projectionLines = _nullishCoalesce(projection.lines, () => ( []));
1676
+ for (let lineIndex = 0; lineIndex < grid.lines.length; lineIndex++) {
1677
+ const gridLine = grid.lines[lineIndex];
1678
+ const projectedLine = projectionLines[lineIndex];
1679
+ const lineHeight = _nullishCoalesce(_optionalChain([projectedLine, 'optionalAccess', _65 => _65.lineHeight]), () => ( grid.lineHeight));
1680
+ const baseline = _nullishCoalesce(_optionalChain([projectedLine, 'optionalAccess', _66 => _66.baseline]), () => ( grid.baseline));
1681
+ const lineFont = _nullishCoalesce(_optionalChain([projectedLine, 'optionalAccess', _67 => _67.font]), () => ( grid.font));
1682
+ const lineElement = document.createElement("span");
1683
+ lineElement.dir = "ltr";
1684
+ lineElement.dataset.vectoGridLine = `${lineIndex}`;
1685
+ lineElement.style.position = "absolute";
1686
+ lineElement.style.left = `${_nullishCoalesce(_optionalChain([projectedLine, 'optionalAccess', _68 => _68.x]), () => ( 0))}px`;
1687
+ lineElement.style.top = `${(_nullishCoalesce(_optionalChain([projectedLine, 'optionalAccess', _69 => _69.y]), () => ( lineIndex * grid.lineHeight))) + baseline - _chunkFIQAIF55js.cssLineBoxBaseline.call(void 0, lineFont, lineHeight)}px`;
1688
+ lineElement.style.width = `${gridLine.width}px`;
1689
+ lineElement.style.height = `${lineHeight}px`;
1690
+ lineElement.style.whiteSpace = "pre";
1691
+ lineElement.style.font = lineFont;
1692
+ lineElement.style.lineHeight = `${lineHeight}px`;
1693
+ if (gridLine.cells.length === 0) {
1694
+ lineElement.textContent = grid.source.slice(gridLine.sourceEnd, gridLine.nextSourceStart);
1695
+ } else {
1696
+ let logicalX = 0;
1697
+ for (let cellIndex = 0; cellIndex < gridLine.cells.length; cellIndex++) {
1698
+ const cell = gridLine.cells[cellIndex];
1699
+ const cellElement = document.createElement("span");
1700
+ cellElement.dir = "ltr";
1701
+ const separator = cellIndex === gridLine.cells.length - 1 ? grid.source.slice(gridLine.sourceEnd, gridLine.nextSourceStart) : "";
1702
+ const sourceText = grid.source.slice(cell.sourceStart, cell.sourceEnd);
1703
+ cellElement.textContent = sourceText + separator;
1704
+ cellElement.dataset.vectoGridCell = `${cellIndex}`;
1705
+ cellElement.dataset.vectoGridSourceLength = `${sourceText.length}`;
1706
+ cellElement.dataset.vectoGridSourceStart = `${cell.sourceStart}`;
1707
+ cellElement.dataset.vectoGridSourceEnd = `${cell.sourceEnd}`;
1708
+ cellElement.dataset.vectoGridCaretOffsets = cell.sourceCaretOffsets.join(",");
1709
+ cellElement.dataset.vectoGridLevel = `${cell.level}`;
1710
+ cellElement.dataset.vectoGridAdvance = `${cell.advance}`;
1711
+ cellElement.dataset.vectoGridX = `${cell.x}`;
1712
+ cellElement.style.position = "relative";
1713
+ cellElement.style.display = "inline-block";
1714
+ cellElement.style.left = `${cell.x - logicalX}px`;
1715
+ cellElement.style.top = "0";
1716
+ cellElement.style.width = `${cell.advance}px`;
1717
+ cellElement.style.height = `${lineHeight}px`;
1718
+ cellElement.style.boxSizing = "border-box";
1719
+ cellElement.style.verticalAlign = "top";
1720
+ cellElement.style.whiteSpace = "pre";
1721
+ cellElement.style.font = lineFont;
1722
+ cellElement.style.lineHeight = `${lineHeight}px`;
1723
+ cellElement.style.transformOrigin = "0 50%";
1724
+ lineElement.appendChild(cellElement);
1725
+ logicalX += cell.advance;
1726
+ }
1727
+ }
1728
+ if (lineIndex === 0) {
1729
+ for (const [basis, left, top] of [
1730
+ ["origin", 0, 0],
1731
+ ["x", 1, 0],
1732
+ ["y", 0, 1]
1733
+ ]) {
1734
+ const marker = document.createElement("span");
1735
+ marker.dataset.vectoGridBasis = basis;
1736
+ marker.setAttribute("aria-hidden", "true");
1737
+ marker.style.position = "absolute";
1738
+ marker.style.left = `${left}px`;
1739
+ marker.style.top = `${top}px`;
1740
+ marker.style.width = "0";
1741
+ marker.style.height = "0";
1742
+ marker.style.pointerEvents = "none";
1743
+ marker.style.userSelect = "none";
1744
+ lineElement.appendChild(marker);
1745
+ }
1746
+ }
1747
+ el.appendChild(lineElement);
1748
+ }
1749
+ el.dataset.vectoProjectionLines = signature;
1750
+ el.dataset.vectoContentGrid = signature;
1751
+ el.dataset.vectoGridCarriers = `${el.querySelectorAll("[data-vecto-grid-cell]").length}`;
1752
+ if (typeof performance !== "undefined") {
1753
+ el.dataset.vectoGridMaterializeMs = `${performance.now() - materializeStart}`;
1754
+ }
1755
+ delete el.dataset.vectoGridCalibration;
1756
+ delete el.dataset.vectoGridReady;
1757
+ }
1758
+ const pageScaleX = this.getContentMetricScaleX();
1759
+ const calibrationKey = `${signature}:${this.contentFontEpoch}:${pageScaleX.toFixed(4)}`;
1760
+ if (el.dataset.vectoGridCalibration !== calibrationKey) {
1761
+ this.scheduleContentGridCalibration(node.id, el, calibrationKey, pageScaleX);
1762
+ }
1763
+ }
1764
+ getContentMetricScaleX() {
1765
+ if (this.contentMetricScaleEpoch === this.contentFontEpoch) {
1766
+ return this.contentMetricScaleX;
1767
+ }
1768
+ const rect = this.canvas.getBoundingClientRect();
1769
+ const inlineWidth = parseInlinePx(this.canvas.style.width);
1770
+ const logicalWidth = _nullishCoalesce(inlineWidth, () => ( (this.canvas.clientWidth || this.width)));
1771
+ const scale = logicalWidth > 0 ? rect.width / logicalWidth : 1;
1772
+ this.contentMetricScaleX = Number.isFinite(scale) && scale > 0 ? scale : 1;
1773
+ this.contentMetricScaleEpoch = this.contentFontEpoch;
1774
+ return this.contentMetricScaleX;
1775
+ }
1776
+ scheduleContentGridCalibration(entityId, el, calibrationKey, pageScaleX) {
1777
+ if (typeof requestAnimationFrame !== "function") return;
1778
+ if (el.dataset.vectoGridCalibrationPending === calibrationKey) return;
1779
+ const previous = this.contentGridCalibrationFrames.get(entityId);
1780
+ if (previous !== void 0 && typeof cancelAnimationFrame === "function") {
1781
+ cancelAnimationFrame(previous);
1782
+ }
1783
+ _optionalChain([this, 'access', _70 => _70.contentGridCalibrationProbes, 'access', _71 => _71.get, 'call', _72 => _72(entityId), 'optionalAccess', _73 => _73.remove, 'call', _74 => _74()]);
1784
+ this.contentGridCalibrationProbes.delete(entityId);
1785
+ const calibrationStart = typeof performance !== "undefined" ? performance.now() : 0;
1786
+ const probe = document.createElement("div");
1787
+ probe.setAttribute("aria-hidden", "true");
1788
+ probe.dataset.vectoGridProbe = entityId;
1789
+ probe.style.position = "absolute";
1790
+ probe.style.left = "-100000px";
1791
+ probe.style.top = "0";
1792
+ probe.style.width = "100000px";
1793
+ probe.style.height = "1px";
1794
+ probe.style.visibility = "hidden";
1795
+ probe.style.pointerEvents = "none";
1796
+ probe.style.whiteSpace = "pre";
1797
+ probe.style.contain = "layout style paint";
1798
+ const probeOrigin = document.createElement("span");
1799
+ probeOrigin.style.position = "absolute";
1800
+ probeOrigin.style.left = "0";
1801
+ probeOrigin.style.top = "0";
1802
+ const probeX = document.createElement("span");
1803
+ probeX.style.position = "absolute";
1804
+ probeX.style.left = "1px";
1805
+ probeX.style.top = "0";
1806
+ probe.append(probeOrigin, probeX);
1807
+ const measurements = [];
1808
+ const measurementsByKey = /* @__PURE__ */ new Map();
1809
+ for (const target of el.querySelectorAll("[data-vecto-grid-cell]")) {
1810
+ const sourceLength = Number(_nullishCoalesce(target.dataset.vectoGridSourceLength, () => ( 0)));
1811
+ const targetWidth = Number(_nullishCoalesce(target.dataset.vectoGridAdvance, () => ( 0)));
1812
+ if (sourceLength <= 0 || targetWidth <= 0) continue;
1813
+ const sourceText = _nullishCoalesce(_optionalChain([target, 'access', _75 => _75.textContent, 'optionalAccess', _76 => _76.slice, 'call', _77 => _77(0, sourceLength)]), () => ( ""));
1814
+ if (!sourceText) continue;
1815
+ const measurementKey = JSON.stringify([
1816
+ target.style.font,
1817
+ target.style.lineHeight,
1818
+ targetWidth,
1819
+ sourceText
1820
+ ]);
1821
+ const shared = measurementsByKey.get(measurementKey);
1822
+ if (shared) {
1823
+ shared.targets.push(target);
1824
+ continue;
1825
+ }
1826
+ const carrier = document.createElement("span");
1827
+ carrier.dir = "ltr";
1828
+ carrier.style.position = "absolute";
1829
+ carrier.style.left = "0";
1830
+ carrier.style.top = "0";
1831
+ carrier.style.whiteSpace = "pre";
1832
+ carrier.style.font = target.style.font;
1833
+ carrier.style.lineHeight = target.style.lineHeight;
1834
+ carrier.style.fontVariantLigatures = "none";
1835
+ carrier.style.fontKerning = "none";
1836
+ const source = document.createTextNode(sourceText);
1837
+ carrier.appendChild(source);
1838
+ probe.appendChild(carrier);
1839
+ const measurement = { targets: [target], targetWidth, sourceLength, source };
1840
+ measurements.push(measurement);
1841
+ measurementsByKey.set(measurementKey, measurement);
1842
+ }
1843
+ (_nullishCoalesce(_nullishCoalesce(this.a11yRoot, () => ( document.body)), () => ( document.documentElement))).appendChild(probe);
1844
+ el.dataset.vectoGridCalibrationSamples = `${measurements.length}`;
1845
+ this.contentGridCalibrationProbes.set(entityId, probe);
1846
+ el.dataset.vectoGridCalibrationPending = calibrationKey;
1847
+ delete el.dataset.vectoGridReady;
1848
+ const readFrame = requestAnimationFrame(() => {
1849
+ if (!el.isConnected || el.dataset.vectoGridCalibrationPending !== calibrationKey) {
1850
+ probe.remove();
1851
+ this.contentGridCalibrationProbes.delete(entityId);
1852
+ this.contentGridCalibrationFrames.delete(entityId);
1853
+ return;
1854
+ }
1855
+ const updates = [];
1856
+ const probeOriginRect = probeOrigin.getBoundingClientRect();
1857
+ const probeXRect = probeX.getBoundingClientRect();
1858
+ const basisScale = Math.abs(probeXRect.left - probeOriginRect.left);
1859
+ const projectionPageScaleX = Number.isFinite(basisScale) && basisScale > 0 ? basisScale : pageScaleX;
1860
+ let valid = true;
1861
+ for (const measurement of measurements) {
1862
+ const range = document.createRange();
1863
+ range.setStart(measurement.source, 0);
1864
+ range.setEnd(measurement.source, measurement.sourceLength);
1865
+ const natural = range.getBoundingClientRect().width;
1866
+ if (!Number.isFinite(natural) || natural <= 0) {
1867
+ valid = false;
1868
+ break;
1869
+ }
1870
+ const scale = measurement.targetWidth * projectionPageScaleX / natural;
1871
+ for (const element of measurement.targets) updates.push({ element, scale });
1872
+ }
1873
+ probe.remove();
1874
+ this.contentGridCalibrationProbes.delete(entityId);
1875
+ if (!valid) {
1876
+ delete el.dataset.vectoGridCalibrationPending;
1877
+ this.contentGridCalibrationFrames.delete(entityId);
1878
+ return;
1879
+ }
1880
+ const writeFrame = requestAnimationFrame(() => {
1881
+ if (!el.isConnected || el.dataset.vectoGridCalibrationPending !== calibrationKey) {
1882
+ this.contentGridCalibrationFrames.delete(entityId);
1883
+ return;
1884
+ }
1885
+ for (const { element, scale } of updates) {
1886
+ element.style.transform = Math.abs(scale - 1) <= 1e-3 ? "" : `scaleX(${scale})`;
1887
+ }
1888
+ el.dataset.vectoGridCalibration = calibrationKey;
1889
+ el.dataset.vectoGridReady = "true";
1890
+ if (typeof performance !== "undefined") {
1891
+ el.dataset.vectoGridCalibrationMs = `${performance.now() - calibrationStart}`;
1892
+ }
1893
+ delete el.dataset.vectoGridCalibrationPending;
1894
+ this.contentGridCalibrationFrames.delete(entityId);
1895
+ });
1896
+ this.contentGridCalibrationFrames.set(entityId, writeFrame);
1897
+ });
1898
+ this.contentGridCalibrationFrames.set(entityId, readFrame);
1899
+ }
1203
1900
  enforceA11yDomOrder() {
1204
1901
  if (!this.a11yRoot) return;
1205
1902
  this.fullViewportElements.length = 0;
@@ -1263,12 +1960,12 @@ var Scene = (_class2 = class _Scene {
1263
1960
  syncOverlayGeometry() {
1264
1961
  const parent = this.canvas.parentElement;
1265
1962
  if (!parent) return;
1266
- const canvasRect = _optionalChain([this, 'access', _48 => _48.canvas, 'access', _49 => _49.getBoundingClientRect, 'optionalCall', _50 => _50()]);
1267
- const parentRect = _optionalChain([parent, 'access', _51 => _51.getBoundingClientRect, 'optionalCall', _52 => _52()]);
1268
- const cssWidth = _optionalChain([canvasRect, 'optionalAccess', _53 => _53.width]) || this.canvas.clientWidth || this.width;
1269
- const cssHeight = _optionalChain([canvasRect, 'optionalAccess', _54 => _54.height]) || this.canvas.clientHeight || this.height;
1270
- const left = (_nullishCoalesce(_optionalChain([canvasRect, 'optionalAccess', _55 => _55.left]), () => ( 0))) - (_nullishCoalesce(_optionalChain([parentRect, 'optionalAccess', _56 => _56.left]), () => ( 0))) - (parent.clientLeft || 0) + parent.scrollLeft;
1271
- const top = (_nullishCoalesce(_optionalChain([canvasRect, 'optionalAccess', _57 => _57.top]), () => ( 0))) - (_nullishCoalesce(_optionalChain([parentRect, 'optionalAccess', _58 => _58.top]), () => ( 0))) - (parent.clientTop || 0) + parent.scrollTop;
1963
+ const canvasRect = _optionalChain([this, 'access', _78 => _78.canvas, 'access', _79 => _79.getBoundingClientRect, 'optionalCall', _80 => _80()]);
1964
+ const parentRect = _optionalChain([parent, 'access', _81 => _81.getBoundingClientRect, 'optionalCall', _82 => _82()]);
1965
+ const cssWidth = _optionalChain([canvasRect, 'optionalAccess', _83 => _83.width]) || this.canvas.clientWidth || this.width;
1966
+ const cssHeight = _optionalChain([canvasRect, 'optionalAccess', _84 => _84.height]) || this.canvas.clientHeight || this.height;
1967
+ const left = (_nullishCoalesce(_optionalChain([canvasRect, 'optionalAccess', _85 => _85.left]), () => ( 0))) - (_nullishCoalesce(_optionalChain([parentRect, 'optionalAccess', _86 => _86.left]), () => ( 0))) - (parent.clientLeft || 0) + parent.scrollLeft;
1968
+ const top = (_nullishCoalesce(_optionalChain([canvasRect, 'optionalAccess', _87 => _87.top]), () => ( 0))) - (_nullishCoalesce(_optionalChain([parentRect, 'optionalAccess', _88 => _88.top]), () => ( 0))) - (parent.clientTop || 0) + parent.scrollTop;
1272
1969
  const scaleX = this.width > 0 ? cssWidth / this.width : 1;
1273
1970
  const scaleY = this.height > 0 ? cssHeight / this.height : 1;
1274
1971
  for (const root of [this.a11yRoot, this.portalRoot]) {
@@ -1393,7 +2090,7 @@ var Scene = (_class2 = class _Scene {
1393
2090
  * (and {@link respectReducedMotion} is on). `0` means uncapped.
1394
2091
  */
1395
2092
  effectiveMaxFPS() {
1396
- const reduced = this.respectReducedMotion && !!_optionalChain([this, 'access', _59 => _59.reducedMotionQuery, 'optionalAccess', _60 => _60.matches]);
2093
+ const reduced = this.respectReducedMotion && !!_optionalChain([this, 'access', _89 => _89.reducedMotionQuery, 'optionalAccess', _90 => _90.matches]);
1397
2094
  if (reduced)
1398
2095
  return this.maxFPS > 0 ? Math.min(this.maxFPS, REDUCED_MOTION_FPS) : REDUCED_MOTION_FPS;
1399
2096
  return this.maxFPS;
@@ -1571,7 +2268,7 @@ var Scene = (_class2 = class _Scene {
1571
2268
  }
1572
2269
  renderer.clear();
1573
2270
  if (isMainRenderer) {
1574
- _optionalChain([this, 'access', _61 => _61.pointRenderer, 'optionalAccess', _62 => _62.begin, 'call', _63 => _63()]);
2271
+ _optionalChain([this, 'access', _91 => _91.pointRenderer, 'optionalAccess', _92 => _92.begin, 'call', _93 => _93()]);
1575
2272
  }
1576
2273
  const vw = this.width;
1577
2274
  const vh = this.height;
@@ -1709,9 +2406,9 @@ var Scene = (_class2 = class _Scene {
1709
2406
  }
1710
2407
  renderer.flush();
1711
2408
  if (isMainRenderer) {
1712
- _optionalChain([this, 'access', _64 => _64.pointRenderer, 'optionalAccess', _65 => _65.flush, 'call', _66 => _66()]);
2409
+ _optionalChain([this, 'access', _94 => _94.pointRenderer, 'optionalAccess', _95 => _95.flush, 'call', _96 => _96()]);
1713
2410
  }
1714
- _optionalChain([renderer, 'access', _67 => _67.present, 'optionalCall', _68 => _68()]);
2411
+ _optionalChain([renderer, 'access', _97 => _97.present, 'optionalCall', _98 => _98()]);
1715
2412
  }
1716
2413
  /**
1717
2414
  * Export the current scene state to a lightweight, flat SVG XML string.
@@ -1727,10 +2424,11 @@ var Scene = (_class2 = class _Scene {
1727
2424
  resize(width, height) {
1728
2425
  this.width = width;
1729
2426
  this.height = height;
2427
+ this.contentFontEpoch++;
1730
2428
  if (typeof this.renderer.resize === "function") {
1731
2429
  this.renderer.resize(width, height);
1732
2430
  }
1733
- _optionalChain([this, 'access', _69 => _69.pointRenderer, 'optionalAccess', _70 => _70.resize, 'call', _71 => _71(width, height)]);
2431
+ _optionalChain([this, 'access', _99 => _99.pointRenderer, 'optionalAccess', _100 => _100.resize, 'call', _101 => _101(width, height)]);
1734
2432
  if (this.gpuCanvas) {
1735
2433
  this.gpuCanvas.width = width;
1736
2434
  this.gpuCanvas.height = height;
@@ -1778,7 +2476,7 @@ var Scene = (_class2 = class _Scene {
1778
2476
  });
1779
2477
  pass.end();
1780
2478
  this.device.queue.submit([encoder.finish()]);
1781
- } catch (e3) {
2479
+ } catch (e5) {
1782
2480
  }
1783
2481
  this.gpuHasContent = false;
1784
2482
  }
@@ -1915,27 +2613,27 @@ var Scene = (_class2 = class _Scene {
1915
2613
  // src/components/TextEntity.ts
1916
2614
  var sharedMeasurer;
1917
2615
  function defaultMeasurer() {
1918
- if (sharedMeasurer === void 0) sharedMeasurer = _chunkZBKKRYDHjs.createCanvasMeasurer.call(void 0, "sans-serif");
2616
+ if (sharedMeasurer === void 0) sharedMeasurer = _chunkBA5HUUDFjs.createCanvasMeasurer.call(void 0, "sans-serif");
1919
2617
  return sharedMeasurer;
1920
2618
  }
1921
- var TextEntity = (_class3 = class extends _chunkDFNK6OV6js.Entity {
2619
+ var TextEntity = (_class3 = class extends _chunkFIQAIF55js.Entity {
1922
2620
 
1923
2621
 
1924
2622
 
1925
2623
 
1926
- __init54() {this.nodes = []}
2624
+ __init62() {this.nodes = []}
1927
2625
 
1928
- __init55() {this.fillStyle = "#94a3b8"}
1929
- __init56() {this.strokeStyle = null}
1930
- __init57() {this.hoveredFillStyle = "#ffffff"}
1931
- __init58() {this.lineWidth = 1}
1932
- __init59() {this.isHovered = false}
2626
+ __init63() {this.fillStyle = "#94a3b8"}
2627
+ __init64() {this.strokeStyle = null}
2628
+ __init65() {this.hoveredFillStyle = "#ffffff"}
2629
+ __init66() {this.lineWidth = 1}
2630
+ __init67() {this.isHovered = false}
1933
2631
  constructor(text, atlas, maxWidth, fontSize = 24) {
1934
- super();_class3.prototype.__init54.call(this);_class3.prototype.__init55.call(this);_class3.prototype.__init56.call(this);_class3.prototype.__init57.call(this);_class3.prototype.__init58.call(this);_class3.prototype.__init59.call(this);;
2632
+ super();_class3.prototype.__init62.call(this);_class3.prototype.__init63.call(this);_class3.prototype.__init64.call(this);_class3.prototype.__init65.call(this);_class3.prototype.__init66.call(this);_class3.prototype.__init67.call(this);;
1935
2633
  this.text = text;
1936
2634
  this.atlas = atlas;
1937
2635
  this.fontSize = fontSize;
1938
- this.layout = new (0, _chunkZBKKRYDHjs.LayoutEngine)(maxWidth, 1e4, defaultMeasurer());
2636
+ this.layout = new (0, _chunkBA5HUUDFjs.LayoutEngine)(maxWidth, 1e4, defaultMeasurer());
1939
2637
  this.prepared = this.layout.prepare(this.text, this.atlas, this.fontSize);
1940
2638
  this.applyLayout();
1941
2639
  this.interactive = true;
@@ -2044,17 +2742,17 @@ var TextEntity = (_class3 = class extends _chunkDFNK6OV6js.Entity {
2044
2742
  }, _class3);
2045
2743
 
2046
2744
  // src/components/GridTextEntity.ts
2047
- var GridTextEntity = (_class4 = class extends _chunkDFNK6OV6js.Entity {
2745
+ var GridTextEntity = (_class4 = class extends _chunkFIQAIF55js.Entity {
2048
2746
 
2049
- __init60() {this.fillStyle = "#ffffff"}
2050
- __init61() {this.grid = []}
2747
+ __init68() {this.fillStyle = "#ffffff"}
2748
+ __init69() {this.grid = []}
2051
2749
  // Array of rows
2052
- __init62() {this.cols = 0}
2053
- __init63() {this.rows = 0}
2750
+ __init70() {this.cols = 0}
2751
+ __init71() {this.rows = 0}
2054
2752
 
2055
2753
 
2056
2754
  constructor(_atlas, fontSize = 10) {
2057
- super();_class4.prototype.__init60.call(this);_class4.prototype.__init61.call(this);_class4.prototype.__init62.call(this);_class4.prototype.__init63.call(this);;
2755
+ super();_class4.prototype.__init68.call(this);_class4.prototype.__init69.call(this);_class4.prototype.__init70.call(this);_class4.prototype.__init71.call(this);;
2058
2756
  this.fontSize = fontSize;
2059
2757
  this.charWidth = fontSize * 1;
2060
2758
  this.charHeight = fontSize * 1.1;
@@ -2063,7 +2761,7 @@ var GridTextEntity = (_class4 = class extends _chunkDFNK6OV6js.Entity {
2063
2761
  updateGrid(ascii) {
2064
2762
  this.grid = ascii;
2065
2763
  this.rows = ascii.length;
2066
- this.cols = _optionalChain([ascii, 'access', _72 => _72[0], 'optionalAccess', _73 => _73.length]) || 0;
2764
+ this.cols = _optionalChain([ascii, 'access', _102 => _102[0], 'optionalAccess', _103 => _103.length]) || 0;
2067
2765
  }
2068
2766
  isPointInside(_globalX, _globalY) {
2069
2767
  return false;
@@ -2138,7 +2836,7 @@ function distSqToSegment(px, py, x1, y1, x2, y2) {
2138
2836
  const ey = py - cy;
2139
2837
  return ex * ex + ey * ey;
2140
2838
  }
2141
- var SplineEntity = (_class5 = class extends _chunkDFNK6OV6js.Entity {
2839
+ var SplineEntity = (_class5 = class extends _chunkFIQAIF55js.Entity {
2142
2840
 
2143
2841
 
2144
2842
 
@@ -2146,23 +2844,23 @@ var SplineEntity = (_class5 = class extends _chunkDFNK6OV6js.Entity {
2146
2844
 
2147
2845
 
2148
2846
 
2149
- __init64() {this.offscreen = null}
2150
- __init65() {this.baked = false}
2847
+ __init72() {this.offscreen = null}
2848
+ __init73() {this.baked = false}
2151
2849
  /** Logical (CSS-pixel) size of the baked bitmap — the blit destination size. */
2152
- __init66() {this.bakedWidth = 0}
2153
- __init67() {this.bakedHeight = 0}
2850
+ __init74() {this.bakedWidth = 0}
2851
+ __init75() {this.bakedHeight = 0}
2154
2852
  /** Gradient strokes can't be baked to a solid-color bitmap; they render per-frame. */
2155
2853
 
2156
2854
  /** Lazily-flattened polylines (one Float32Array of [x,y,...] per segment) for hit-testing. */
2157
- __init68() {this.polylines = null}
2855
+ __init76() {this.polylines = null}
2158
2856
  /**
2159
2857
  * When `true`, the renderer draws a rounded-rect outline of the entity's
2160
2858
  * local bounds after painting the curves. Useful for drag feedback and
2161
2859
  * debugging hit areas. Defaults to `false`.
2162
2860
  */
2163
- __init69() {this.showBounds = false}
2861
+ __init77() {this.showBounds = false}
2164
2862
  constructor(doc, opts = {}) {
2165
- super();_class5.prototype.__init64.call(this);_class5.prototype.__init65.call(this);_class5.prototype.__init66.call(this);_class5.prototype.__init67.call(this);_class5.prototype.__init68.call(this);_class5.prototype.__init69.call(this);;
2863
+ super();_class5.prototype.__init72.call(this);_class5.prototype.__init73.call(this);_class5.prototype.__init74.call(this);_class5.prototype.__init75.call(this);_class5.prototype.__init76.call(this);_class5.prototype.__init77.call(this);;
2166
2864
  this.doc = doc;
2167
2865
  this.lineWidth = _nullishCoalesce(opts.lineWidth, () => ( 2));
2168
2866
  this.cache = _nullishCoalesce(opts.cache, () => ( true));
@@ -2173,7 +2871,7 @@ var SplineEntity = (_class5 = class extends _chunkDFNK6OV6js.Entity {
2173
2871
  this.width = this.bounds.width;
2174
2872
  this.height = this.bounds.height;
2175
2873
  const isGradient = (c) => c !== null && !Array.isArray(c);
2176
- this.containsGradient = (_nullishCoalesce(_optionalChain([this, 'access', _74 => _74.doc, 'access', _75 => _75.equations, 'optionalAccess', _76 => _76.some, 'call', _77 => _77((eq) => isGradient(eq.color_rgb))]), () => ( false))) || (_nullishCoalesce(_optionalChain([this, 'access', _78 => _78.doc, 'access', _79 => _79.paths, 'optionalAccess', _80 => _80.some, 'call', _81 => _81((p) => isGradient(p.color_rgb))]), () => ( false)));
2874
+ this.containsGradient = (_nullishCoalesce(_optionalChain([this, 'access', _104 => _104.doc, 'access', _105 => _105.equations, 'optionalAccess', _106 => _106.some, 'call', _107 => _107((eq) => isGradient(eq.color_rgb))]), () => ( false))) || (_nullishCoalesce(_optionalChain([this, 'access', _108 => _108.doc, 'access', _109 => _109.paths, 'optionalAccess', _110 => _110.some, 'call', _111 => _111((p) => isGradient(p.color_rgb))]), () => ( false)));
2177
2875
  this.interactive = true;
2178
2876
  }
2179
2877
  computeBounds() {
@@ -2415,9 +3113,9 @@ async function loadSpline(url) {
2415
3113
  // src/math/SpatialHashGrid.ts
2416
3114
  var SpatialHashGrid = (_class6 = class {
2417
3115
 
2418
- __init70() {this.grid = /* @__PURE__ */ new Map()}
2419
- __init71() {this.entityCells = /* @__PURE__ */ new Map()}
2420
- constructor(cellSize = 64) {;_class6.prototype.__init70.call(this);_class6.prototype.__init71.call(this);
3116
+ __init78() {this.grid = /* @__PURE__ */ new Map()}
3117
+ __init79() {this.entityCells = /* @__PURE__ */ new Map()}
3118
+ constructor(cellSize = 64) {;_class6.prototype.__init78.call(this);_class6.prototype.__init79.call(this);
2421
3119
  this.cellSize = cellSize;
2422
3120
  }
2423
3121
  hash(cx, cy) {
@@ -2471,7 +3169,7 @@ var SpatialHashGrid = (_class6 = class {
2471
3169
  const keys = this.entityCells.get(id);
2472
3170
  if (!keys) return;
2473
3171
  for (const key of keys) {
2474
- _optionalChain([this, 'access', _82 => _82.grid, 'access', _83 => _83.get, 'call', _84 => _84(key), 'optionalAccess', _85 => _85.delete, 'call', _86 => _86(id)]);
3172
+ _optionalChain([this, 'access', _112 => _112.grid, 'access', _113 => _113.get, 'call', _114 => _114(key), 'optionalAccess', _115 => _115.delete, 'call', _116 => _116(id)]);
2475
3173
  }
2476
3174
  this.entityCells.delete(id);
2477
3175
  }
@@ -2507,20 +3205,20 @@ var SpatialHashGrid = (_class6 = class {
2507
3205
  }, _class6);
2508
3206
 
2509
3207
  // src/tree/DOMPortalEntity.ts
2510
- var DOMPortalEntity = (_class7 = class extends _chunkDFNK6OV6js.Entity {
3208
+ var DOMPortalEntity = (_class7 = class extends _chunkFIQAIF55js.Entity {
2511
3209
 
2512
- __init72() {this.isDOMPortal = true}
2513
- __init73() {this.domListeners = []}
2514
- __init74() {this.resizeObserver = null}
2515
- __init75() {this.cachedWidth = 100}
2516
- __init76() {this.cachedHeight = 100}
2517
- __init77() {this.lastWidth = ""}
2518
- __init78() {this.lastHeight = ""}
2519
- __init79() {this.lastTransform = ""}
2520
- __init80() {this.lastZIndex = ""}
2521
- __init81() {this.lastOpacity = ""}
3210
+ __init80() {this.isDOMPortal = true}
3211
+ __init81() {this.domListeners = []}
3212
+ __init82() {this.resizeObserver = null}
3213
+ __init83() {this.cachedWidth = 100}
3214
+ __init84() {this.cachedHeight = 100}
3215
+ __init85() {this.lastWidth = ""}
3216
+ __init86() {this.lastHeight = ""}
3217
+ __init87() {this.lastTransform = ""}
3218
+ __init88() {this.lastZIndex = ""}
3219
+ __init89() {this.lastOpacity = ""}
2522
3220
  constructor(domElement, width, height, id) {
2523
- super(id);_class7.prototype.__init72.call(this);_class7.prototype.__init73.call(this);_class7.prototype.__init74.call(this);_class7.prototype.__init75.call(this);_class7.prototype.__init76.call(this);_class7.prototype.__init77.call(this);_class7.prototype.__init78.call(this);_class7.prototype.__init79.call(this);_class7.prototype.__init80.call(this);_class7.prototype.__init81.call(this);;
3221
+ super(id);_class7.prototype.__init80.call(this);_class7.prototype.__init81.call(this);_class7.prototype.__init82.call(this);_class7.prototype.__init83.call(this);_class7.prototype.__init84.call(this);_class7.prototype.__init85.call(this);_class7.prototype.__init86.call(this);_class7.prototype.__init87.call(this);_class7.prototype.__init88.call(this);_class7.prototype.__init89.call(this);;
2524
3222
  this.domElement = domElement;
2525
3223
  this.width = _nullishCoalesce(width, () => ( 0));
2526
3224
  this.height = _nullishCoalesce(height, () => ( 0));
@@ -2549,7 +3247,7 @@ var DOMPortalEntity = (_class7 = class extends _chunkDFNK6OV6js.Entity {
2549
3247
  ];
2550
3248
  for (const type of events) {
2551
3249
  const handler = (e) => {
2552
- this.dispatchEvent(new (0, _chunkDFNK6OV6js.VectoJSEvent)(type, this, e));
3250
+ this.dispatchEvent(new (0, _chunkFIQAIF55js.VectoJSEvent)(type, this, e));
2553
3251
  };
2554
3252
  this.domElement.addEventListener(type, handler);
2555
3253
  this.domListeners.push({ type, handler, capture: false });
@@ -2560,7 +3258,7 @@ var DOMPortalEntity = (_class7 = class extends _chunkDFNK6OV6js.Entity {
2560
3258
  ];
2561
3259
  for (const { native, vecto } of hoverEvents) {
2562
3260
  const handler = (e) => {
2563
- this.dispatchEvent(new (0, _chunkDFNK6OV6js.VectoJSEvent)(vecto, this, e, false));
3261
+ this.dispatchEvent(new (0, _chunkFIQAIF55js.VectoJSEvent)(vecto, this, e, false));
2564
3262
  };
2565
3263
  this.domElement.addEventListener(native, handler);
2566
3264
  this.domListeners.push({ type: native, handler, capture: false });
@@ -2568,7 +3266,7 @@ var DOMPortalEntity = (_class7 = class extends _chunkDFNK6OV6js.Entity {
2568
3266
  const focusEvents = ["focus", "blur"];
2569
3267
  for (const type of focusEvents) {
2570
3268
  const handler = (e) => {
2571
- this.dispatchEvent(new (0, _chunkDFNK6OV6js.VectoJSEvent)(type, this, e, true));
3269
+ this.dispatchEvent(new (0, _chunkFIQAIF55js.VectoJSEvent)(type, this, e, true));
2572
3270
  };
2573
3271
  this.domElement.addEventListener(type, handler, true);
2574
3272
  this.domListeners.push({ type, handler, capture: true });
@@ -2655,4 +3353,5 @@ Scene.registerWebGPUParticleSystemManager(_chunkBPMNCGU7js.WebGPUParticleSystemM
2655
3353
 
2656
3354
 
2657
3355
 
2658
- exports.ArabicShaper = _chunkCTZQOM5Zjs.ArabicShaper; exports.BidiResolver = _chunkCTZQOM5Zjs.BidiResolver; exports.CanvasRenderer = _chunkBPMNCGU7js.CanvasRenderer; exports.ComputeParticleEntity = ComputeParticleEntity; exports.DOMPortalEntity = DOMPortalEntity; exports.Easing = _chunkDFNK6OV6js.Easing; exports.Entity = _chunkDFNK6OV6js.Entity; exports.GridTextEntity = GridTextEntity; exports.LayoutEngine = _chunkZBKKRYDHjs.LayoutEngine; exports.LayoutResultBuffer = _chunkZBKKRYDHjs.LayoutResultBuffer; exports.LayoutWorkerManager = _chunkCTZQOM5Zjs.LayoutWorkerManager; exports.MSDFFont = _chunkDFNK6OV6js.MSDFFont; exports.MSDFTextEntity = _chunkDFNK6OV6js.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 = _chunkDFNK6OV6js.SVGEntity; exports.SVGRenderer = _chunkBPMNCGU7js.SVGRenderer; exports.Scene = Scene; exports.SpatialHashGrid = SpatialHashGrid; exports.SplineEntity = SplineEntity; exports.SpringDriver = _chunkDFNK6OV6js.SpringDriver; exports.SpringPhysics = _chunkDFNK6OV6js.SpringPhysics; exports.TextEntity = TextEntity; exports.TweenDriver = _chunkDFNK6OV6js.TweenDriver; exports.VectoJSEvent = _chunkDFNK6OV6js.VectoJSEvent; exports.WebGPUParticleSystemManager = _chunkBPMNCGU7js.WebGPUParticleSystemManager; exports.clearCssLineBoxMetrics = _chunkDFNK6OV6js.clearCssLineBoxMetrics; exports.computeLineSegments = _chunkZBKKRYDHjs.computeLineSegments; exports.createCanvasMeasurer = _chunkZBKKRYDHjs.createCanvasMeasurer; exports.createWebGLPointRenderer = _chunkBPMNCGU7js.createWebGLPointRenderer; exports.cssLineBoxBaseline = _chunkDFNK6OV6js.cssLineBoxBaseline; exports.isSafeUrl = _chunkBPMNCGU7js.isSafeUrl; exports.isTweenConfig = _chunkDFNK6OV6js.isTweenConfig; exports.loadSpline = loadSpline; exports.parseColorToRGBA = _chunkBPMNCGU7js.parseColorToRGBA; exports.polySegmentToBezier = polySegmentToBezier; exports.sanitizeUrl = _chunkBPMNCGU7js.sanitizeUrl;
3356
+
3357
+ exports.ArabicShaper = _chunk4AR425ARjs.ArabicShaper; exports.BidiResolver = _chunk4AR425ARjs.BidiResolver; exports.CanvasRenderer = _chunkBPMNCGU7js.CanvasRenderer; exports.ComputeParticleEntity = ComputeParticleEntity; exports.DOMPortalEntity = DOMPortalEntity; exports.Easing = _chunkFIQAIF55js.Easing; exports.Entity = _chunkFIQAIF55js.Entity; exports.GridTextEntity = GridTextEntity; exports.LayoutEngine = _chunkBA5HUUDFjs.LayoutEngine; exports.LayoutResultBuffer = _chunkBA5HUUDFjs.LayoutResultBuffer; exports.LayoutWorkerManager = _chunk4AR425ARjs.LayoutWorkerManager; exports.MSDFFont = _chunkFIQAIF55js.MSDFFont; exports.MSDFTextEntity = _chunkFIQAIF55js.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 = _chunkFIQAIF55js.SVGEntity; exports.SVGRenderer = _chunkBPMNCGU7js.SVGRenderer; exports.Scene = Scene; exports.SpatialHashGrid = SpatialHashGrid; exports.SplineEntity = SplineEntity; exports.SpringDriver = _chunkFIQAIF55js.SpringDriver; exports.SpringPhysics = _chunkFIQAIF55js.SpringPhysics; exports.TextEntity = TextEntity; exports.TweenDriver = _chunkFIQAIF55js.TweenDriver; exports.VectoJSEvent = _chunkFIQAIF55js.VectoJSEvent; exports.WebGPUParticleSystemManager = _chunkBPMNCGU7js.WebGPUParticleSystemManager; exports.clearCssLineBoxMetrics = _chunkFIQAIF55js.clearCssLineBoxMetrics; exports.computeLineSegments = _chunkBA5HUUDFjs.computeLineSegments; exports.createCanvasMeasurer = _chunkBA5HUUDFjs.createCanvasMeasurer; exports.createWebGLPointRenderer = _chunkBPMNCGU7js.createWebGLPointRenderer; exports.cssLineBoxBaseline = _chunkFIQAIF55js.cssLineBoxBaseline; exports.isSafeUrl = _chunkBPMNCGU7js.isSafeUrl; exports.isTweenConfig = _chunkFIQAIF55js.isTweenConfig; exports.loadSpline = loadSpline; exports.parseColorToRGBA = _chunkBPMNCGU7js.parseColorToRGBA; exports.polySegmentToBezier = polySegmentToBezier; exports.prepareContentGrid = _chunkFIQAIF55js.prepareContentGrid; exports.sanitizeUrl = _chunkBPMNCGU7js.sanitizeUrl;