@pixerate/editor 0.271.0 → 0.272.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. package/dist/agent/index.cjs +34 -32
  2. package/dist/agent/index.js +10 -8
  3. package/dist/animation-editor/index.cjs +60 -60
  4. package/dist/animation-editor/index.js +4 -4
  5. package/dist/brushes/index.cjs +69 -66
  6. package/dist/brushes/index.js +6 -3
  7. package/dist/brushes/patch.d.cts +1 -1
  8. package/dist/brushes/patch.d.ts +1 -1
  9. package/dist/brushes/schema.d.cts +1 -0
  10. package/dist/brushes/schema.d.ts +1 -0
  11. package/dist/brushes/types.d.cts +8 -0
  12. package/dist/brushes/types.d.ts +8 -0
  13. package/dist/{brushstrokeRender-WR2N5HHY.cjs → brushstrokeRender-5YBCLFDQ.cjs} +15 -15
  14. package/dist/{brushstrokeRender-A727TTNQ.js → brushstrokeRender-DZGFU3J4.js} +3 -3
  15. package/dist/canvas/index.cjs +13 -13
  16. package/dist/canvas/index.js +1 -1
  17. package/dist/chart/contract.d.cts +95 -0
  18. package/dist/chart/contract.d.ts +95 -0
  19. package/dist/chart/controller.d.cts +4 -0
  20. package/dist/chart/controller.d.ts +4 -0
  21. package/dist/chart/index.cjs +492 -26
  22. package/dist/chart/index.d.cts +1 -0
  23. package/dist/chart/index.d.ts +1 -0
  24. package/dist/chart/index.js +476 -10
  25. package/dist/chart/tools.d.cts +3 -0
  26. package/dist/chart/tools.d.ts +3 -0
  27. package/dist/chart-maps/index.cjs +4 -64
  28. package/dist/chart-maps/index.js +3 -63
  29. package/dist/{chunk-YNFSH72F.js → chunk-2F3YDXCN.js} +1 -1
  30. package/dist/{chunk-QYXUE37Q.js → chunk-2XDNF73E.js} +1 -1
  31. package/dist/{chunk-3KNQ2W6X.cjs → chunk-3JKCREEU.cjs} +59 -53
  32. package/dist/{chunk-NMZQMPFZ.js → chunk-4LZQO5Y7.js} +2 -0
  33. package/dist/{chunk-B5W677L7.js → chunk-5HP2VSAS.js} +1 -1
  34. package/dist/chunk-5UGRMVNE.js +328 -0
  35. package/dist/{chunk-X4FTNFIA.js → chunk-7MGPW2OV.js} +1 -1
  36. package/dist/{chunk-BPJSI4NT.cjs → chunk-7W2EQQBP.cjs} +2 -2
  37. package/dist/{chunk-DGITFN73.cjs → chunk-BWJBZAUE.cjs} +8 -8
  38. package/dist/chunk-CHZYVNXZ.js +336 -0
  39. package/dist/{chunk-LETF75CA.js → chunk-CLB2I2FU.js} +1 -1
  40. package/dist/chunk-DRMZ5R3S.cjs +67 -0
  41. package/dist/{chunk-BAZMCFVL.js → chunk-DZVRH63Y.js} +1 -1
  42. package/dist/chunk-EI5GFTKG.js +67 -0
  43. package/dist/{chunk-U2ASNGO6.cjs → chunk-FXVCB6YG.cjs} +35 -35
  44. package/dist/{chunk-EU2ZZA6L.cjs → chunk-GHGBIAWQ.cjs} +126 -39
  45. package/dist/chunk-JV7DKLMX.js +1073 -0
  46. package/dist/{chunk-2WOGXEDX.cjs → chunk-M3RZOF3G.cjs} +1 -1
  47. package/dist/chunk-MFBUQC67.cjs +328 -0
  48. package/dist/{chunk-GSTSZPSR.js → chunk-N3SKPQEH.js} +225 -18
  49. package/dist/{chunk-J5VQYK7T.cjs → chunk-N5IMDAHM.cjs} +251 -44
  50. package/dist/{chunk-ININNHLM.js → chunk-NAHJV3O6.js} +11 -5
  51. package/dist/{chunk-IBXEQOGI.js → chunk-PYHB2EHE.js} +2 -324
  52. package/dist/chunk-QEUI6OGE.cjs +336 -0
  53. package/dist/{chunk-6ZSFRRJI.js → chunk-RSF6BT34.js} +1 -1
  54. package/dist/{chunk-JJ2H25JG.cjs → chunk-SNAFFCAX.cjs} +200 -174
  55. package/dist/chunk-T2HUQBRC.cjs +1073 -0
  56. package/dist/{chunk-M2ZVPU7L.cjs → chunk-TNLKFW7D.cjs} +23 -23
  57. package/dist/{chunk-KZI3YWKW.js → chunk-UXYCY3HP.js} +93 -6
  58. package/dist/{chunk-GSLOH2IN.cjs → chunk-VF6ODSYX.cjs} +2 -0
  59. package/dist/{chunk-NQUKTRKN.cjs → chunk-WZLNNGG3.cjs} +45 -45
  60. package/dist/{chunk-NRBGAEFI.cjs → chunk-Y3RUYOOW.cjs} +8 -330
  61. package/dist/{chunk-DDL3ZBHK.cjs → chunk-YJANF2BL.cjs} +86 -86
  62. package/dist/{chunk-TNHDCP4R.js → chunk-ZEI7ZEA4.js} +31 -5
  63. package/dist/commands/index.cjs +7 -323
  64. package/dist/commands/index.js +5 -321
  65. package/dist/extensions/index.cjs +4 -4
  66. package/dist/extensions/index.js +3 -3
  67. package/dist/image-editor/index.cjs +789 -789
  68. package/dist/image-editor/index.js +5 -5
  69. package/dist/index.cjs +9 -9
  70. package/dist/index.js +3 -3
  71. package/dist/paint/index.cjs +2 -2
  72. package/dist/paint/index.js +1 -1
  73. package/dist/paint/wet/world.d.cts +37 -1
  74. package/dist/paint/wet/world.d.ts +37 -1
  75. package/dist/paint-editor/brush-controls.d.cts +2 -0
  76. package/dist/paint-editor/brush-controls.d.ts +2 -0
  77. package/dist/paint-editor/brush-model.d.cts +14 -1
  78. package/dist/paint-editor/brush-model.d.ts +14 -1
  79. package/dist/paint-editor/index.cjs +343 -306
  80. package/dist/paint-editor/index.js +48 -11
  81. package/dist/paint-editor/ui.d.cts +1 -1
  82. package/dist/paint-editor/ui.d.ts +1 -1
  83. package/dist/paint-editor/wet.d.cts +8 -1
  84. package/dist/paint-editor/wet.d.ts +8 -1
  85. package/dist/persistence/index.cjs +24 -1042
  86. package/dist/persistence/index.js +22 -1040
  87. package/dist/tools/index.cjs +5 -3
  88. package/dist/tools/index.js +8 -6
  89. package/dist/vector/index.cjs +999 -999
  90. package/dist/vector/index.js +5 -5
  91. package/package.json +1 -1
  92. package/skills/pixerate-brushes/SKILL.md +1 -0
  93. package/skills/pixerate-paint-editor/SKILL.md +4 -11
  94. package/skills/pixerate-paint-editor/references/brush-facets.md +1 -0
  95. package/skills/pixerate-paint-editor/references/ghost.md +47 -0
  96. package/skills/pixerate-paint-watercolour/SKILL.md +1 -0
@@ -8,7 +8,7 @@
8
8
 
9
9
 
10
10
 
11
- var _chunkEU2ZZA6Lcjs = require('./chunk-EU2ZZA6L.cjs');
11
+ var _chunkGHGBIAWQcjs = require('./chunk-GHGBIAWQ.cjs');
12
12
 
13
13
 
14
14
 
@@ -73,7 +73,8 @@ var _chunkJBZRVLXVcjs = require('./chunk-JBZRVLXV.cjs');
73
73
 
74
74
 
75
75
 
76
- var _chunkJ5VQYK7Tcjs = require('./chunk-J5VQYK7T.cjs');
76
+
77
+ var _chunkN5IMDAHMcjs = require('./chunk-N5IMDAHM.cjs');
77
78
 
78
79
 
79
80
 
@@ -2792,7 +2793,7 @@ function effectDabField(img, rect, cov, centre, mixed, field, steps = 0, dab = n
2792
2793
  var samplers = /* @__PURE__ */ new WeakMap();
2793
2794
  function stampSampler(ref, art, hardness = 1) {
2794
2795
  const sampler = baseSampler(ref, art);
2795
- if (!sampler || hardness >= 1 || !_chunkEU2ZZA6Lcjs.isBrushSourceRef.call(void 0, ref)) return sampler;
2796
+ if (!sampler || hardness >= 1 || !_chunkGHGBIAWQcjs.isBrushSourceRef.call(void 0, ref)) return sampler;
2796
2797
  const h = Math.max(0, hardness);
2797
2798
  return (u, v2, seed) => {
2798
2799
  const r = Math.hypot(u, v2) / Math.SQRT2;
@@ -2867,7 +2868,7 @@ function rasterizeStampDab(d, sample, seed, rect, out) {
2867
2868
  }
2868
2869
  function brushStickerRefs(brush) {
2869
2870
  const refs = brush.engine === "sticker" ? [...brush.sticker.stamps] : brush.engine === "particle" ? [...brush.particle.dotTextures] : brush.engine === "dab" && brush.stamp ? [brush.stamp] : [];
2870
- return [...new Set(refs.filter((r) => r.includes(":") && !r.startsWith("editor:") && !_chunkEU2ZZA6Lcjs.isBrushSourceRef.call(void 0, r)))];
2871
+ return [...new Set(refs.filter((r) => r.includes(":") && !r.startsWith("editor:") && !_chunkGHGBIAWQcjs.isBrushSourceRef.call(void 0, r)))];
2871
2872
  }
2872
2873
  function sprayDroplets(d, spray, seed) {
2873
2874
  const count = 1 + Math.round(spray.density * 31);
@@ -3699,7 +3700,7 @@ var PaintDabStroke = (_class4 = class {
3699
3700
 
3700
3701
  // src/paint-editor/wet.ts
3701
3702
  var STROKE_WATER = 0.9;
3702
- var STROKE_MASS = _chunkJ5VQYK7Tcjs.PIGMENT_UNIT * 2.5;
3703
+ var STROKE_MASS = _chunkN5IMDAHMcjs.PIGMENT_UNIT * 2.5;
3703
3704
  var STROKE_LIGHT = 1.5;
3704
3705
  var COVERAGE_STEPS = 4096;
3705
3706
  function union(a, b) {
@@ -3729,12 +3730,17 @@ var WetStrokeDriver = (_class5 = class {
3729
3730
  const spacing = Math.max(0.02, brush.tip.spacing);
3730
3731
  const perDab = Math.min(1, spacing * 1.2);
3731
3732
  const thin = wet.thinner;
3732
- this.medium = new (0, _chunkJ5VQYK7Tcjs.WetMedium)(init.world, init.laneId, {
3733
+ const body = wet.body * (1 - thin);
3734
+ this.medium = new (0, _chunkN5IMDAHMcjs.WetMedium)(init.world, init.laneId, {
3733
3735
  water: STROKE_WATER * Math.min(1, wet.water * (1 + thin)) * perDab,
3734
3736
  mass: STROKE_MASS * wet.pigment * (1 - 0.6 * thin) * perDab,
3735
- body: wet.body * (1 - thin),
3737
+ body,
3736
3738
  light: 0
3737
3739
  });
3740
+ if (wet.tool === "paint" && brush.ghost && wet.pigment > 0) {
3741
+ const one = _chunkN5IMDAHMcjs.pigmentOf.call(void 0, init.color, body);
3742
+ init.world.startGhost(init.laneId, [one[0], one[1], one[2], one[3]], brush.ghost.linger, _nullishCoalesce(init.speed, () => ( 120)));
3743
+ }
3738
3744
  this.lightBase = wet.tool === "paint" ? STROKE_LIGHT * brush.light.amount * (1 - 0.6 * thin) * perDab : 0;
3739
3745
  const rates = _chunkNIBFKXMDcjs.exchangeRates.call(void 0, brush.behavior.pickup, brush.behavior.mix, wet.load, brush.behavior.mixing);
3740
3746
  this.states = copies.map((c, i) => ({
@@ -3863,6 +3869,22 @@ var WetStrokeDriver = (_class5 = class {
3863
3869
  if (!(k > 0)) return;
3864
3870
  switch (wet.tool) {
3865
3871
  case "paint": {
3872
+ if (brush.ghost) {
3873
+ const smear = brush.ghost.smear;
3874
+ if (wet.pigment > 0) {
3875
+ this.medium.options.light = this.medium.options.mass;
3876
+ this.medium.deposit(rect, cov, k, this.init.color, null);
3877
+ } else {
3878
+ this.medium.options.light = 0;
3879
+ world.paint(laneId, rect, cov, this.medium.options.water * k * (wet.water > 0 ? 1 : 0), null);
3880
+ }
3881
+ if (smear > 0) {
3882
+ const rw = Math.max(wet.rewet, 0.6) * smear;
3883
+ if (rw > 0) world.rewet(laneId, rect, cov, rw * k * 0.5, this.init.paperColor, true);
3884
+ if (st.last) world.drag(laneId, rect, tip, d.x - st.last.x, d.y - st.last.y, smear * k);
3885
+ }
3886
+ break;
3887
+ }
3866
3888
  const ex = st.exchange;
3867
3889
  this.medium.options.light = this.lightBase * (brush.light.pressure ? d.pressure : 1);
3868
3890
  let flow = 1;
@@ -3935,7 +3957,7 @@ var PaintWetLayers = (_class6 = class {
3935
3957
 
3936
3958
 
3937
3959
  __init41() {this.world = null}
3938
- __init42() {this.tilt = { ..._chunkJ5VQYK7Tcjs.FLAT }}
3960
+ __init42() {this.tilt = { ..._chunkN5IMDAHMcjs.FLAT }}
3939
3961
  __init43() {this.settings = /* @__PURE__ */ new Map()}
3940
3962
  __init44() {this.paused = false}
3941
3963
  /** Wet strokes dry as soon as they end (one undo step with the stroke). */
@@ -3959,8 +3981,8 @@ var PaintWetLayers = (_class6 = class {
3959
3981
  /** Starts the GPU engine for the world (once; it may turn out unavailable). */
3960
3982
  startGpu() {
3961
3983
  if (this.gpuMode === "off" || this.gpu || this.gpuStarting || this.gpuSupport) return;
3962
- const provider = this.options.gpuProvider === void 0 ? _chunkJ5VQYK7Tcjs.findWebGpu.call(void 0, ) : this.options.gpuProvider;
3963
- this.gpuStarting = _chunkJ5VQYK7Tcjs.createWetGpuEngine.call(void 0, provider).then(({ engine, support }) => {
3984
+ const provider = this.options.gpuProvider === void 0 ? _chunkN5IMDAHMcjs.findWebGpu.call(void 0, ) : this.options.gpuProvider;
3985
+ this.gpuStarting = _chunkN5IMDAHMcjs.createWetGpuEngine.call(void 0, provider).then(({ engine, support }) => {
3964
3986
  this.gpuSupport = support;
3965
3987
  if (!engine) return;
3966
3988
  if (this.gpuMode === "off" || !this.world) {
@@ -4019,7 +4041,7 @@ var PaintWetLayers = (_class6 = class {
4019
4041
  return this.world;
4020
4042
  }
4021
4043
  makeWorld(width, height, paper) {
4022
- const world = new (0, _chunkJ5VQYK7Tcjs.WetWorld)(width, height, wetPaperInput(paper), { kernel: this.options.kernel, threads: this.options.threads });
4044
+ const world = new (0, _chunkN5IMDAHMcjs.WetWorld)(width, height, wetPaperInput(paper), { kernel: this.options.kernel, threads: this.options.threads });
4023
4045
  world.setTilt(this.tilt);
4024
4046
  world.gpuMinTiles = this.gpuMinTiles;
4025
4047
  if (this.gpu) world.attachGpu(this.gpu);
@@ -4031,7 +4053,7 @@ var PaintWetLayers = (_class6 = class {
4031
4053
  * sides: the shift has to be whole wet tiles (256 px), and no wet stroke may be live.
4032
4054
  */
4033
4055
  canExtend(left2, top) {
4034
- return left2 % _chunkJ5VQYK7Tcjs.WET_TILE === 0 && top % _chunkJ5VQYK7Tcjs.WET_TILE === 0 && !this.driver;
4056
+ return left2 % _chunkN5IMDAHMcjs.WET_TILE === 0 && top % _chunkN5IMDAHMcjs.WET_TILE === 0 && !this.driver;
4035
4057
  }
4036
4058
  /**
4037
4059
  * Keeps the wet paint while the canvas grows to `width`×`height` by `left` / `top` on those
@@ -4049,12 +4071,12 @@ var PaintWetLayers = (_class6 = class {
4049
4071
  this.lastTick = null;
4050
4072
  this.stepsOwed = 0;
4051
4073
  if (!old || !snap) return;
4052
- const moved = _chunkJ5VQYK7Tcjs.moveWetSnapshot.call(void 0, snap, old, { width, height }, left2, top, (l) => {
4074
+ const moved = _chunkN5IMDAHMcjs.moveWetSnapshot.call(void 0, snap, old, { width, height }, left2, top, (l) => {
4053
4075
  const flow = _optionalChain([this, 'access', _100 => _100.settings, 'access', _101 => _101.get, 'call', _102 => _102(l.id), 'optionalAccess', _103 => _103.flow]);
4054
4076
  return {
4055
4077
  base: _chunk474IQG74cjs.translateSurface.call(void 0, l.base, left2, top),
4056
4078
  ...l.light ? { light: _chunk474IQG74cjs.translateSurface.call(void 0, l.light, left2, top) } : {},
4057
- flow: l.flow && flow && flow.kind !== "none" ? _chunkJ5VQYK7Tcjs.flowField.call(void 0, flow, width, height) : l.flow
4079
+ flow: l.flow && flow && flow.kind !== "none" ? _chunkN5IMDAHMcjs.flowField.call(void 0, flow, width, height) : l.flow
4058
4080
  };
4059
4081
  });
4060
4082
  this.world = this.makeWorld(width, height, paper);
@@ -4082,7 +4104,7 @@ var PaintWetLayers = (_class6 = class {
4082
4104
  settingsOf(layerId, medium = "watercolor") {
4083
4105
  let s = this.settings.get(layerId);
4084
4106
  if (!s) {
4085
- s = { params: _chunkJ5VQYK7Tcjs.normalizeWetParams.call(void 0, WET_MEDIUM_PARAMS[medium], _chunkJ5VQYK7Tcjs.DEFAULT_WET_PARAMS), flow: { ..._chunkJ5VQYK7Tcjs.DEFAULT_FLOW } };
4107
+ s = { params: _chunkN5IMDAHMcjs.normalizeWetParams.call(void 0, WET_MEDIUM_PARAMS[medium], _chunkN5IMDAHMcjs.DEFAULT_WET_PARAMS), flow: { ..._chunkN5IMDAHMcjs.DEFAULT_FLOW } };
4086
4108
  this.settings.set(layerId, s);
4087
4109
  }
4088
4110
  return s;
@@ -4093,29 +4115,29 @@ var PaintWetLayers = (_class6 = class {
4093
4115
  if (!w.hasLane(layerId)) {
4094
4116
  const base = _nullishCoalesce(this.host.layerSurface(layerId), () => ( new (0, _chunk474IQG74cjs.TiledSurface)(4, /* @__PURE__ */ new Map(), 0)));
4095
4117
  const s = this.settingsOf(layerId, medium);
4096
- w.ensureLane(layerId, { params: s.params, base, light: this.host.layerLight(layerId) });
4118
+ w.ensureLane(layerId, { params: s.params, base, light: this.host.layerLight(layerId), ghost: s.ghost });
4097
4119
  const { width, height } = this.host.canvas();
4098
- if (s.flow.kind !== "none") w.setFlow(layerId, _chunkJ5VQYK7Tcjs.flowField.call(void 0, s.flow, width, height), s.flow.strength);
4120
+ if (s.flow.kind !== "none") w.setFlow(layerId, _chunkN5IMDAHMcjs.flowField.call(void 0, s.flow, width, height), s.flow.strength);
4099
4121
  }
4100
4122
  return w;
4101
4123
  }
4102
4124
  setParams(layerId, update) {
4103
4125
  const s = this.settingsOf(layerId);
4104
- s.params = _chunkJ5VQYK7Tcjs.normalizeWetParams.call(void 0, update, s.params);
4126
+ s.params = _chunkN5IMDAHMcjs.normalizeWetParams.call(void 0, update, s.params);
4105
4127
  if (_optionalChain([this, 'access', _109 => _109.world, 'optionalAccess', _110 => _110.hasLane, 'call', _111 => _111(layerId)])) this.world.setParams(layerId, s.params);
4106
4128
  return { ...s.params };
4107
4129
  }
4108
4130
  setFlow(layerId, update) {
4109
4131
  const s = this.settingsOf(layerId);
4110
- s.flow = _chunkJ5VQYK7Tcjs.normalizeFlow.call(void 0, update, s.flow);
4132
+ s.flow = _chunkN5IMDAHMcjs.normalizeFlow.call(void 0, update, s.flow);
4111
4133
  if (_optionalChain([this, 'access', _112 => _112.world, 'optionalAccess', _113 => _113.hasLane, 'call', _114 => _114(layerId)])) {
4112
4134
  const { width, height } = this.host.canvas();
4113
- this.world.setFlow(layerId, _chunkJ5VQYK7Tcjs.flowField.call(void 0, s.flow, width, height), s.flow.strength);
4135
+ this.world.setFlow(layerId, _chunkN5IMDAHMcjs.flowField.call(void 0, s.flow, width, height), s.flow.strength);
4114
4136
  }
4115
4137
  return { ...s.flow };
4116
4138
  }
4117
4139
  setTilt(update) {
4118
- this.tilt = _chunkJ5VQYK7Tcjs.normalizeTilt.call(void 0, update, this.tilt);
4140
+ this.tilt = _chunkN5IMDAHMcjs.normalizeTilt.call(void 0, update, this.tilt);
4119
4141
  _optionalChain([this, 'access', _115 => _115.world, 'optionalAccess', _116 => _116.setTilt, 'call', _117 => _117(this.tilt)]);
4120
4142
  return { ...this.tilt };
4121
4143
  }
@@ -4127,18 +4149,20 @@ var PaintWetLayers = (_class6 = class {
4127
4149
  info(layerId) {
4128
4150
  const s = this.settingsOf(layerId);
4129
4151
  const st = _optionalChain([this, 'access', _121 => _121.world, 'optionalAccess', _122 => _122.hasLane, 'call', _123 => _123(layerId)]) ? this.world.stats(layerId) : null;
4152
+ const g = _optionalChain([this, 'access', _124 => _124.world, 'optionalAccess', _125 => _125.hasLane, 'call', _126 => _126(layerId)]) ? this.world.getGhost(layerId) : _nullishCoalesce(s.ghost, () => ( null));
4130
4153
  return {
4131
4154
  layerId,
4132
4155
  wet: Boolean(st && st.wetCells > 0),
4133
- wetCells: _nullishCoalesce(_optionalChain([st, 'optionalAccess', _124 => _124.wetCells]), () => ( 0)),
4134
- wetBounds: _nullishCoalesce(_optionalChain([st, 'optionalAccess', _125 => _125.wetBounds]), () => ( null)),
4135
- activeTiles: _nullishCoalesce(_optionalChain([st, 'optionalAccess', _126 => _126.activeTiles]), () => ( 0)),
4156
+ wetCells: _nullishCoalesce(_optionalChain([st, 'optionalAccess', _127 => _127.wetCells]), () => ( 0)),
4157
+ wetBounds: _nullishCoalesce(_optionalChain([st, 'optionalAccess', _128 => _128.wetBounds]), () => ( null)),
4158
+ activeTiles: _nullishCoalesce(_optionalChain([st, 'optionalAccess', _129 => _129.activeTiles]), () => ( 0)),
4136
4159
  params: { ...s.params },
4137
- flow: { ...s.flow }
4160
+ flow: { ...s.flow },
4161
+ ...g ? { ghost: { remaining: Math.round(g.remaining * _chunkN5IMDAHMcjs.FREE_INTERVAL / this.speed * 100) / 100 } } : {}
4138
4162
  };
4139
4163
  }
4140
4164
  backend() {
4141
- return _nullishCoalesce(_optionalChain([this, 'access', _127 => _127.world, 'optionalAccess', _128 => _128.backend, 'call', _129 => _129()]), () => ( null));
4165
+ return _nullishCoalesce(_optionalChain([this, 'access', _130 => _130.world, 'optionalAccess', _131 => _131.backend, 'call', _132 => _132()]), () => ( null));
4142
4166
  }
4143
4167
  /** Shows the current wet pixels (at most `maxTiles` reshaded per layer). */
4144
4168
  syncDisplays(maxTiles = Infinity) {
@@ -4187,10 +4211,12 @@ var PaintWetLayers = (_class6 = class {
4187
4211
  const w = this.world;
4188
4212
  if (!w) return;
4189
4213
  for (const id of w.laneIds()) {
4190
- if (w.isActive(id) || _optionalChain([this, 'access', _130 => _130.driver, 'optionalAccess', _131 => _131.init, 'access', _132 => _132.laneId]) === id) continue;
4214
+ if (w.isActive(id) || _optionalChain([this, 'access', _133 => _133.driver, 'optionalAccess', _134 => _134.init, 'access', _135 => _135.laneId]) === id) continue;
4191
4215
  const base = w.getBase(id);
4192
4216
  const light = w.isLit(id) ? w.getLight(id) : null;
4193
4217
  w.removeLane(id);
4218
+ const s = this.settings.get(id);
4219
+ if (_optionalChain([s, 'optionalAccess', _136 => _136.ghost])) delete s.ghost;
4194
4220
  if (light && this.host.layerLight(id) !== light) this.host.updateLights(/* @__PURE__ */ new Map([[id, light]]));
4195
4221
  this.host.updateSurfaces(/* @__PURE__ */ new Map([[id, base]]), []);
4196
4222
  }
@@ -4269,7 +4295,7 @@ var PaintWetLayers = (_class6 = class {
4269
4295
  if (!d || !this.world) return;
4270
4296
  const rects = d.flush();
4271
4297
  if (rects.length) this.syncDisplays(DISPLAY_TILES_PER_TICK);
4272
- if (d.done) _optionalChain([this, 'access', _133 => _133.onDriverDone, 'optionalCall', _134 => _134(d)]);
4298
+ if (d.done) _optionalChain([this, 'access', _137 => _137.onDriverDone, 'optionalCall', _138 => _138(d)]);
4273
4299
  }
4274
4300
  /** Called when a live stroke that ended mid-batch has finished applying. */
4275
4301
  __init56() {this.onDriverDone = null}
@@ -4313,13 +4339,13 @@ var PaintWetLayers = (_class6 = class {
4313
4339
  /** The layer's light paint with all its wet paint dried (`null` without a wet layer or light), without changing anything. */
4314
4340
  bakedLight(layerId) {
4315
4341
  const w = this.world;
4316
- if (!_optionalChain([w, 'optionalAccess', _135 => _135.hasLane, 'call', _136 => _136(layerId)]) || !w.isLit(layerId)) return null;
4342
+ if (!_optionalChain([w, 'optionalAccess', _139 => _139.hasLane, 'call', _140 => _140(layerId)]) || !w.isLit(layerId)) return null;
4317
4343
  return w.bakedLight(layerId);
4318
4344
  }
4319
4345
  /** The layer's pixels with all its wet paint dried (deterministic), without changing anything. */
4320
4346
  bakedSurface(layerId) {
4321
4347
  const w = this.world;
4322
- if (!_optionalChain([w, 'optionalAccess', _137 => _137.hasLane, 'call', _138 => _138(layerId)])) return null;
4348
+ if (!_optionalChain([w, 'optionalAccess', _141 => _141.hasLane, 'call', _142 => _142(layerId)])) return null;
4323
4349
  return w.bakedSurface(layerId);
4324
4350
  }
4325
4351
  /** A snapshot of the world for undo (`null` when there is none). */
@@ -4340,13 +4366,13 @@ var PaintWetLayers = (_class6 = class {
4340
4366
  this.syncDisplays();
4341
4367
  }
4342
4368
  dropWorld() {
4343
- _optionalChain([this, 'access', _139 => _139.world, 'optionalAccess', _140 => _140.destroy, 'call', _141 => _141()]);
4369
+ _optionalChain([this, 'access', _143 => _143.world, 'optionalAccess', _144 => _144.destroy, 'call', _145 => _145()]);
4344
4370
  this.world = null;
4345
4371
  this.driver = null;
4346
4372
  }
4347
4373
  /** Forgets everything wet (a new canvas, a resize, opening a document). */
4348
4374
  reset() {
4349
- _optionalChain([this, 'access', _142 => _142.world, 'optionalAccess', _143 => _143.destroy, 'call', _144 => _144()]);
4375
+ _optionalChain([this, 'access', _146 => _146.world, 'optionalAccess', _147 => _147.destroy, 'call', _148 => _148()]);
4350
4376
  this.world = null;
4351
4377
  this.driver = null;
4352
4378
  this.settings.clear();
@@ -4376,15 +4402,15 @@ var PaintWetLayers = (_class6 = class {
4376
4402
  return out;
4377
4403
  }
4378
4404
  destroy() {
4379
- _optionalChain([this, 'access', _145 => _145.world, 'optionalAccess', _146 => _146.destroy, 'call', _147 => _147()]);
4405
+ _optionalChain([this, 'access', _149 => _149.world, 'optionalAccess', _150 => _150.destroy, 'call', _151 => _151()]);
4380
4406
  this.world = null;
4381
- _optionalChain([this, 'access', _148 => _148.gpu, 'optionalAccess', _149 => _149.destroy, 'call', _150 => _150()]);
4407
+ _optionalChain([this, 'access', _152 => _152.gpu, 'optionalAccess', _153 => _153.destroy, 'call', _154 => _154()]);
4382
4408
  this.gpu = null;
4383
4409
  }
4384
4410
  }, _class6);
4385
4411
  function wetPigmentOf(hex, body) {
4386
4412
  const [r, g, b] = hexToRgb8(hex);
4387
- return Array.from(_chunkJ5VQYK7Tcjs.pigmentOf.call(void 0, [r / 255, g / 255, b / 255], body));
4413
+ return Array.from(_chunkN5IMDAHMcjs.pigmentOf.call(void 0, [r / 255, g / 255, b / 255], body));
4388
4414
  }
4389
4415
 
4390
4416
  // src/vector/brushstrokeMedia.ts
@@ -4420,8 +4446,8 @@ function place(input, brush, options, pad = 0) {
4420
4446
  const [r, g, b, a] = options.color;
4421
4447
  const hex = "#" + [r, g, b].map((v2) => Math.round(Math.min(255, Math.max(0, v2))).toString(16).padStart(2, "0")).join("");
4422
4448
  const source = _nullishCoalesce(options.paint, () => ( null));
4423
- const paint = _optionalChain([source, 'optionalAccess', _151 => _151.type]) === "gradient" ? _chunkNIBFKXMDcjs.resolvePaintGradient.call(void 0, _chunkNIBFKXMDcjs.scalePaintGradient.call(void 0, source, scale3), { paint: hex, secondary: "#ffffff" }) : null;
4424
- const color2 = _optionalChain([source, 'optionalAccess', _152 => _152.type]) === "color" ? hexRgb(source.color) : [r / 255, g / 255, b / 255];
4449
+ const paint = _optionalChain([source, 'optionalAccess', _155 => _155.type]) === "gradient" ? _chunkNIBFKXMDcjs.resolvePaintGradient.call(void 0, _chunkNIBFKXMDcjs.scalePaintGradient.call(void 0, source, scale3), { paint: hex, secondary: "#ffffff" }) : null;
4450
+ const color2 = _optionalChain([source, 'optionalAccess', _156 => _156.type]) === "color" ? hexRgb(source.color) : [r / 255, g / 255, b / 255];
4425
4451
  return { points, brush: sized, rect, scale: scale3, color: color2, alpha: Math.min(1, Math.max(0, a / 255)), paint };
4426
4452
  }
4427
4453
  function hexRgb(hex) {
@@ -4472,7 +4498,7 @@ var WetBrushstrokeJob = (_class7 = class {
4472
4498
  return;
4473
4499
  }
4474
4500
  const { rect, points } = this.placed;
4475
- this.world = new (0, _chunkJ5VQYK7Tcjs.WetWorld)(rect.width, rect.height, wetPaperInput(DEFAULT_PAPER), { kernel: "typescript", threads: 0 });
4501
+ this.world = new (0, _chunkN5IMDAHMcjs.WetWorld)(rect.width, rect.height, wetPaperInput(DEFAULT_PAPER), { kernel: "typescript", threads: 0 });
4476
4502
  const medium = _nullishCoalesce(this.placed.brush.wet.medium, () => ( "watercolor"));
4477
4503
  this.world.ensureLane("s", { params: _nullishCoalesce(WET_MEDIUM_PARAMS[medium], () => ( {})) });
4478
4504
  const color2 = this.placed.color;
@@ -4531,7 +4557,7 @@ var WetBrushstrokeJob = (_class7 = class {
4531
4557
  return this.final;
4532
4558
  }
4533
4559
  destroy() {
4534
- _optionalChain([this, 'access', _153 => _153.world, 'optionalAccess', _154 => _154.destroy, 'call', _155 => _155()]);
4560
+ _optionalChain([this, 'access', _157 => _157.world, 'optionalAccess', _158 => _158.destroy, 'call', _159 => _159()]);
4535
4561
  }
4536
4562
  bake() {
4537
4563
  if (!this.world || !this.placed) return EMPTY;
@@ -4556,8 +4582,8 @@ function renderBackdropBrushstroke(input, brush, options) {
4556
4582
  const area = { x: 0, y: 0, width: rect.width, height: rect.height };
4557
4583
  const before = options.backdrop ? options.backdrop(rect, placed.scale) : new Uint8ClampedArray(rect.width * rect.height * 4);
4558
4584
  if (before.length !== rect.width * rect.height * 4) throw new Error(`The backdrop must be ${rect.width}\xD7${rect.height} RGBA pixels.`);
4559
- const cached = _optionalChain([options, 'access', _156 => _156.cache, 'optionalCall', _157 => _157(before)]);
4560
- const hit = _optionalChain([cached, 'optionalAccess', _158 => _158.get, 'call', _159 => _159()]);
4585
+ const cached = _optionalChain([options, 'access', _160 => _160.cache, 'optionalCall', _161 => _161(before)]);
4586
+ const hit = _optionalChain([cached, 'optionalAccess', _162 => _162.get, 'call', _163 => _163()]);
4561
4587
  if (hit) return hit;
4562
4588
  const base = _chunk474IQG74cjs.writeRegion.call(void 0, _chunk474IQG74cjs.emptySurface.call(void 0, 4), area, before);
4563
4589
  const live = /* @__PURE__ */ new Map();
@@ -4565,7 +4591,7 @@ function renderBackdropBrushstroke(input, brush, options) {
4565
4591
  offset: { x: 0, y: 0 },
4566
4592
  lockTransparency: false,
4567
4593
  selection: null,
4568
- readTile: (tx, ty) => _nullishCoalesce(_nullishCoalesce(live.get(_chunk474IQG74cjs.tileKey.call(void 0, tx, ty)), () => ( _optionalChain([base, 'access', _160 => _160.tiles, 'access', _161 => _161.get, 'call', _162 => _162(_chunk474IQG74cjs.tileKey.call(void 0, tx, ty)), 'optionalAccess', _163 => _163.data]))), () => ( null)),
4594
+ readTile: (tx, ty) => _nullishCoalesce(_nullishCoalesce(live.get(_chunk474IQG74cjs.tileKey.call(void 0, tx, ty)), () => ( _optionalChain([base, 'access', _164 => _164.tiles, 'access', _165 => _165.get, 'call', _166 => _166(_chunk474IQG74cjs.tileKey.call(void 0, tx, ty)), 'optionalAccess', _167 => _167.data]))), () => ( null)),
4569
4595
  writeTile: (tx, ty) => {
4570
4596
  const key = _chunk474IQG74cjs.tileKey.call(void 0, tx, ty);
4571
4597
  let t = live.get(key);
@@ -4583,17 +4609,17 @@ function renderBackdropBrushstroke(input, brush, options) {
4583
4609
  for (const [key, data] of live) tiles.set(key, { data, uniform: null });
4584
4610
  _chunk474IQG74cjs.readRegion.call(void 0, new (0, _chunk474IQG74cjs.TiledSurface)(4, tiles), area, after);
4585
4611
  const result = cropped(after, placed, stroke.dabCount, (i) => after[i] !== before[i] || after[i + 1] !== before[i + 1] || after[i + 2] !== before[i + 2] || after[i + 3] !== before[i + 3]);
4586
- _optionalChain([cached, 'optionalAccess', _164 => _164.set, 'call', _165 => _165(result)]);
4612
+ _optionalChain([cached, 'optionalAccess', _168 => _168.set, 'call', _169 => _169(result)]);
4587
4613
  return result;
4588
4614
  }
4589
4615
 
4590
4616
  // src/vector/brushstroke.ts
4591
4617
  var VECTOR_BRUSHSTROKE_SCALE = 2;
4592
- var PRESETS = _chunkEU2ZZA6Lcjs.listPresets.call(void 0, _chunkEU2ZZA6Lcjs.VECTOR_PROFILE).map((spec) => _chunkEU2ZZA6Lcjs.BUILTIN_BRUSHES.find((b) => b.id === spec.id));
4618
+ var PRESETS = _chunkGHGBIAWQcjs.listPresets.call(void 0, _chunkGHGBIAWQcjs.VECTOR_PROFILE).map((spec) => _chunkGHGBIAWQcjs.BUILTIN_BRUSHES.find((b) => b.id === spec.id));
4593
4619
  function admitted(spec) {
4594
4620
  try {
4595
- const brush = _chunkEU2ZZA6Lcjs.normalizeBrushSpec.call(void 0, spec);
4596
- return _chunkEU2ZZA6Lcjs.checkBrush.call(void 0, brush, _chunkEU2ZZA6Lcjs.VECTOR_PROFILE).ok && isVectorBrushstrokeEngine(_chunkEU2ZZA6Lcjs.resolveBrush.call(void 0, brush)) ? brush : null;
4621
+ const brush = _chunkGHGBIAWQcjs.normalizeBrushSpec.call(void 0, spec);
4622
+ return _chunkGHGBIAWQcjs.checkBrush.call(void 0, brush, _chunkGHGBIAWQcjs.VECTOR_PROFILE).ok && isVectorBrushstrokeEngine(_chunkGHGBIAWQcjs.resolveBrush.call(void 0, brush)) ? brush : null;
4597
4623
  } catch (e6) {
4598
4624
  return null;
4599
4625
  }
@@ -4605,7 +4631,7 @@ function vectorBrushstrokeBrushes(user = []) {
4605
4631
  const out = [...PRESETS];
4606
4632
  for (const raw of user) {
4607
4633
  const brush = admitted(raw);
4608
- if (brush && !out.some((b) => b.id === brush.id)) out.push(_chunkEU2ZZA6Lcjs.resolveBrush.call(void 0, brush));
4634
+ if (brush && !out.some((b) => b.id === brush.id)) out.push(_chunkGHGBIAWQcjs.resolveBrush.call(void 0, brush));
4609
4635
  }
4610
4636
  return out;
4611
4637
  }
@@ -4615,7 +4641,7 @@ function vectorBrushstrokeBrush(id) {
4615
4641
  function vectorBrushstrokeBrushOf(brush) {
4616
4642
  if (brush.spec) {
4617
4643
  const saved = admitted(brush.spec);
4618
- return saved && saved.id === brush.brushId ? _chunkEU2ZZA6Lcjs.resolveBrush.call(void 0, saved) : null;
4644
+ return saved && saved.id === brush.brushId ? _chunkGHGBIAWQcjs.resolveBrush.call(void 0, saved) : null;
4619
4645
  }
4620
4646
  return vectorBrushstrokeBrush(brush.brushId);
4621
4647
  }
@@ -4623,15 +4649,15 @@ function vectorBrushstrokeBrushError(id, user = []) {
4623
4649
  if (vectorBrushstrokeBrush(id)) return null;
4624
4650
  const saved = user.find((b) => b.id === id);
4625
4651
  const ids = vectorBrushstrokeBrushes(user).map((b) => b.id);
4626
- const reasons = (b) => _chunkEU2ZZA6Lcjs.checkBrush.call(void 0, b, _chunkEU2ZZA6Lcjs.VECTOR_PROFILE).issues.filter((i) => i.severity === "error").map((i) => `${i.reason} ${i.fix}`).join(" ") || "its engine does not paint brushstrokes.";
4652
+ const reasons = (b) => _chunkGHGBIAWQcjs.checkBrush.call(void 0, b, _chunkGHGBIAWQcjs.VECTOR_PROFILE).issues.filter((i) => i.severity === "error").map((i) => `${i.reason} ${i.fix}`).join(" ") || "its engine does not paint brushstrokes.";
4627
4653
  if (saved) return admitted(saved) ? null : `Brush "${id}" (${saved.name}) can't paint a brushstroke: ${reasons(saved)} Use one of: ${ids.join(", ")}.`;
4628
- const preset2 = _chunkEU2ZZA6Lcjs.BRUSH_PRESETS.find((b) => b.id === id);
4654
+ const preset2 = _chunkGHGBIAWQcjs.BRUSH_PRESETS.find((b) => b.id === id);
4629
4655
  if (preset2) return `Brush "${id}" (${preset2.name}) can't paint a brushstroke: ${reasons(preset2)} Use one of: ${ids.join(", ")}.`;
4630
- return `Unknown brush "${id}". ${_chunkEU2ZZA6Lcjs.closest.call(void 0, id, ids)}Use one of: ${ids.join(", ")} (vector.listBrushes lists them).`;
4656
+ return `Unknown brush "${id}". ${_chunkGHGBIAWQcjs.closest.call(void 0, id, ids)}Use one of: ${ids.join(", ")} (vector.listBrushes lists them).`;
4631
4657
  }
4632
4658
  function vectorBrushstrokeDefaultColour(id, user = [], scheme = "light") {
4633
- const brush = _nullishCoalesce(_chunkEU2ZZA6Lcjs.BRUSH_PRESETS.find((b) => b.id === id), () => ( user.find((b) => b.id === id)));
4634
- return brush ? _chunkJBZRVLXVcjs.brushColourHex.call(void 0, _optionalChain([brush, 'access', _166 => _166.colour, 'optionalAccess', _167 => _167.default]), scheme) : null;
4659
+ const brush = _nullishCoalesce(_chunkGHGBIAWQcjs.BRUSH_PRESETS.find((b) => b.id === id), () => ( user.find((b) => b.id === id)));
4660
+ return brush ? _chunkJBZRVLXVcjs.brushColourHex.call(void 0, _optionalChain([brush, 'access', _170 => _170.colour, 'optionalAccess', _171 => _171.default]), scheme) : null;
4635
4661
  }
4636
4662
  function sanitizeVectorBrushstroke(value, user = []) {
4637
4663
  if (!value || typeof value !== "object") return null;
@@ -4755,7 +4781,7 @@ function strokePaintOf(node, layer, brush, length2) {
4755
4781
  const color2 = [c[0] * 255, c[1] * 255, c[2] * 255, c[3] * 255].map(Math.round);
4756
4782
  if (layer.brush.paint) return { color: color2, paint: layer.brush.paint, within: null };
4757
4783
  const g = layer.paint;
4758
- if (isVectorGradient(g) && _optionalChain([g, 'access', _168 => _168.stops, 'optionalAccess', _169 => _169.length])) {
4784
+ if (isVectorGradient(g) && _optionalChain([g, 'access', _172 => _172.stops, 'optionalAccess', _173 => _173.length])) {
4759
4785
  const mode = _nullishCoalesce(g.strokeMode, () => ( "within"));
4760
4786
  if (mode === "along") return { color: [color2[0], color2[1], color2[2], 255], paint: gradientPaint(g, { by: "distance", length: Math.max(1, length2), repeat: REPEAT[_nullishCoalesce(g.spread, () => ( "pad"))], unit: "px" }), within: null };
4761
4787
  if (mode === "across") return { color: [color2[0], color2[1], color2[2], 255], paint: gradientPaint(g, { by: "across-tip" }), within: null };
@@ -4910,7 +4936,7 @@ function vectorBrushstrokeImages(node, layer, context = {}) {
4910
4936
  const source = usesVectorBackdrop(engine) && backdropSource ? backdropSource(document2, node, Math.max(0, index), settle) : null;
4911
4937
  const deps = source ? [...source.deps, wetGeneration] : null;
4912
4938
  let byLayer = layerCache.get(node);
4913
- const hit = _optionalChain([byLayer, 'optionalAccess', _170 => _170.get, 'call', _171 => _171(layer)]);
4939
+ const hit = _optionalChain([byLayer, 'optionalAccess', _174 => _174.get, 'call', _175 => _175(layer)]);
4914
4940
  const stale = hit && (hit.pending.length && hit.pending.some((k) => wetSettled.has(k)) || settle === "now" && !hit.settled);
4915
4941
  if (hit && sameDeps(hit.deps, deps) && !stale) return hit.images;
4916
4942
  const brush = layer.brush.size ? { ...preset2, tip: { ...preset2.tip, size: layer.brush.size } } : preset2;
@@ -4935,7 +4961,7 @@ function vectorBrushstrokeImages(node, layer, context = {}) {
4935
4961
  const key = mediaKey(input, brush, options);
4936
4962
  stroke = renderBackdropBrushstroke(input, brush, {
4937
4963
  ...options,
4938
- backdrop: _nullishCoalesce(_optionalChain([source, 'optionalAccess', _172 => _172.backdrop]), () => ( null)),
4964
+ backdrop: _nullishCoalesce(_optionalChain([source, 'optionalAccess', _176 => _176.backdrop]), () => ( null)),
4939
4965
  cache: (bytes) => {
4940
4966
  const k = `${key}:${hashBytes(bytes).toString(16)}`;
4941
4967
  return { get: () => backdropResults.get(k), set: (img) => backdropResults.set(k, img) };
@@ -5039,7 +5065,7 @@ function withVectorFills(node, fills) {
5039
5065
  const next = { ...node };
5040
5066
  if (fills.length === 0 || fills.length === 1 && isPlainVectorPaintLayer(fills[0])) {
5041
5067
  delete next.fills;
5042
- next.fill = _nullishCoalesce(_optionalChain([fills, 'access', _173 => _173[0], 'optionalAccess', _174 => _174.paint]), () => ( null));
5068
+ next.fill = _nullishCoalesce(_optionalChain([fills, 'access', _177 => _177[0], 'optionalAccess', _178 => _178.paint]), () => ( null));
5043
5069
  return next;
5044
5070
  }
5045
5071
  next.fills = fills.map((l) => ({ ...l }));
@@ -5064,8 +5090,8 @@ function withVectorStrokes(node, strokes) {
5064
5090
  var json = (v2) => JSON.stringify(_nullishCoalesce(v2, () => ( null)));
5065
5091
  function strokeShorthandDiff(node, top) {
5066
5092
  const out = [];
5067
- if (json(node.stroke) !== json(_optionalChain([top, 'optionalAccess', _175 => _175.paint]))) out.push("stroke");
5068
- for (const key of VECTOR_STROKE_SETTING_KEYS) if (json(node[key]) !== json(_optionalChain([top, 'optionalAccess', _176 => _176[key]]))) out.push(key);
5093
+ if (json(node.stroke) !== json(_optionalChain([top, 'optionalAccess', _179 => _179.paint]))) out.push("stroke");
5094
+ for (const key of VECTOR_STROKE_SETTING_KEYS) if (json(node[key]) !== json(_optionalChain([top, 'optionalAccess', _180 => _180[key]]))) out.push(key);
5069
5095
  return out;
5070
5096
  }
5071
5097
  var checked = /* @__PURE__ */ new WeakSet();
@@ -5082,7 +5108,7 @@ function normalizeVectorPaintStacks(node, prefer = "shorthand") {
5082
5108
  if (Array.isArray(node.fills)) {
5083
5109
  let fills = node.fills;
5084
5110
  const top = fills[fills.length - 1];
5085
- if (prefer === "shorthand" && json(node.fill) !== json(_optionalChain([top, 'optionalAccess', _177 => _177.paint]))) {
5111
+ if (prefer === "shorthand" && json(node.fill) !== json(_optionalChain([top, 'optionalAccess', _181 => _181.paint]))) {
5086
5112
  if (!draws(node.fill)) fills = [];
5087
5113
  else fills = top ? [...fills.slice(0, -1), { ...top, paint: node.fill }] : [{ paint: node.fill }];
5088
5114
  }
@@ -5298,8 +5324,8 @@ var Measured = class {
5298
5324
  append(sa, sb, out) {
5299
5325
  for (const piece of _chunkGF2RBSDMcjs.trimSegments.call(void 0, this.segs, sa, sb, this.lens)) {
5300
5326
  if (degenerate(piece)) continue;
5301
- const last = _optionalChain([out, 'access', _178 => _178[out.length - 1], 'optionalAccess', _179 => _179.segs]);
5302
- const end = _optionalChain([last, 'optionalAccess', _180 => _180[last.length - 1], 'optionalAccess', _181 => _181.at, 'call', _182 => _182(-1)]);
5327
+ const last = _optionalChain([out, 'access', _182 => _182[out.length - 1], 'optionalAccess', _183 => _183.segs]);
5328
+ const end = _optionalChain([last, 'optionalAccess', _184 => _184[last.length - 1], 'optionalAccess', _185 => _185.at, 'call', _186 => _186(-1)]);
5303
5329
  if (!end || Math.hypot(end[0] - piece[0][0], end[1] - piece[0][1]) > 1e-6) out.push({ segs: [piece], closed: false });
5304
5330
  else last.push(piece);
5305
5331
  }
@@ -5611,9 +5637,9 @@ function vectorRepeaterCopies(r, pivot) {
5611
5637
  for (let i = 0; i < n; i++) {
5612
5638
  const k = i + offset;
5613
5639
  let m = translateMatrix(-pivot.x, -pivot.y);
5614
- m = multiplyMatrices(m, scaleMatrix(Math.pow((_nullishCoalesce(_optionalChain([r, 'access', _183 => _183.scale, 'optionalAccess', _184 => _184.x]), () => ( 100))) / 100, k), Math.pow((_nullishCoalesce(_optionalChain([r, 'access', _185 => _185.scale, 'optionalAccess', _186 => _186.y]), () => ( 100))) / 100, k)));
5640
+ m = multiplyMatrices(m, scaleMatrix(Math.pow((_nullishCoalesce(_optionalChain([r, 'access', _187 => _187.scale, 'optionalAccess', _188 => _188.x]), () => ( 100))) / 100, k), Math.pow((_nullishCoalesce(_optionalChain([r, 'access', _189 => _189.scale, 'optionalAccess', _190 => _190.y]), () => ( 100))) / 100, k)));
5615
5641
  m = multiplyMatrices(m, rotateMatrix((_nullishCoalesce(r.rotation, () => ( 0))) * k));
5616
- m = multiplyMatrices(m, translateMatrix(pivot.x + (_nullishCoalesce(_optionalChain([r, 'access', _187 => _187.position, 'optionalAccess', _188 => _188.x]), () => ( 0))) * k, pivot.y + (_nullishCoalesce(_optionalChain([r, 'access', _189 => _189.position, 'optionalAccess', _190 => _190.y]), () => ( 0))) * k));
5642
+ m = multiplyMatrices(m, translateMatrix(pivot.x + (_nullishCoalesce(_optionalChain([r, 'access', _191 => _191.position, 'optionalAccess', _192 => _192.x]), () => ( 0))) * k, pivot.y + (_nullishCoalesce(_optionalChain([r, 'access', _193 => _193.position, 'optionalAccess', _194 => _194.y]), () => ( 0))) * k));
5617
5643
  const t = n > 1 ? i / (n - 1) : 0;
5618
5644
  const partial = i + 1 === n && fract > 0 ? fract : 1;
5619
5645
  out.push({ index: i, matrix: m, opacity: Math.min(1, Math.max(0, (so + (eo - so) * t) * partial)) });
@@ -5777,7 +5803,7 @@ function mapBezierPath(path, f, tolerance = 0.1, options = {}) {
5777
5803
 
5778
5804
  // src/vector/frames.ts
5779
5805
  function isVectorFrame(node) {
5780
- return _optionalChain([node, 'optionalAccess', _191 => _191.type]) === "group" && !!node.frame && !node.blend && !node.liveBoolean && !node.mask;
5806
+ return _optionalChain([node, 'optionalAccess', _195 => _195.type]) === "group" && !!node.frame && !node.blend && !node.liveBoolean && !node.mask;
5781
5807
  }
5782
5808
  function vectorFrameRectPath(frame) {
5783
5809
  const { x, y, width: w, height: h } = frame;
@@ -5822,8 +5848,8 @@ function placeSpan(rule, a0, a1, f0, f1, g0, g1) {
5822
5848
  }
5823
5849
  }
5824
5850
  function vectorFrameChildMatrix(resizing, box, from, to) {
5825
- const [x0, x1] = placeSpan(_nullishCoalesce(H[_nullishCoalesce(_optionalChain([resizing, 'optionalAccess', _192 => _192.horizontal]), () => ( "left"))], () => ( "start")), box.x, box.x + box.width, from.x, from.x + from.width, to.x, to.x + to.width);
5826
- const [y0, y1] = placeSpan(_nullishCoalesce(V[_nullishCoalesce(_optionalChain([resizing, 'optionalAccess', _193 => _193.vertical]), () => ( "top"))], () => ( "start")), box.y, box.y + box.height, from.y, from.y + from.height, to.y, to.y + to.height);
5851
+ const [x0, x1] = placeSpan(_nullishCoalesce(H[_nullishCoalesce(_optionalChain([resizing, 'optionalAccess', _196 => _196.horizontal]), () => ( "left"))], () => ( "start")), box.x, box.x + box.width, from.x, from.x + from.width, to.x, to.x + to.width);
5852
+ const [y0, y1] = placeSpan(_nullishCoalesce(V[_nullishCoalesce(_optionalChain([resizing, 'optionalAccess', _197 => _197.vertical]), () => ( "top"))], () => ( "start")), box.y, box.y + box.height, from.y, from.y + from.height, to.y, to.y + to.height);
5827
5853
  const sx = box.width > 1e-9 ? (x1 - x0) / box.width : 1;
5828
5854
  const sy = box.height > 1e-9 ? (y1 - y0) / box.height : 1;
5829
5855
  return [sx, 0, 0, sy, x0 - sx * box.x, y0 - sy * box.y];
@@ -5879,7 +5905,7 @@ function vectorFrameDocument(doc, id, find) {
5879
5905
  height,
5880
5906
  ...doc.background ? { background: doc.background } : {},
5881
5907
  nodes: [placed],
5882
- ..._optionalChain([doc, 'access', _194 => _194.symbols, 'optionalAccess', _195 => _195.length]) ? { symbols: doc.symbols } : {}
5908
+ ..._optionalChain([doc, 'access', _198 => _198.symbols, 'optionalAccess', _199 => _199.length]) ? { symbols: doc.symbols } : {}
5883
5909
  };
5884
5910
  }
5885
5911
  function getVectorFramePanel(state) {
@@ -5899,7 +5925,7 @@ function getVectorFramePanel(state) {
5899
5925
  const one = (values) => values.every((v2) => v2 === values[0]) ? values[0] : "mixed";
5900
5926
  return {
5901
5927
  frame: f ? { id: f.id, name: _nullishCoalesce(f.name, () => ( "Frame")), artboard: parents.get(f.id) === null, frame: f.frame } : null,
5902
- resizing: children.length ? { ids: children.map((c) => c.id), horizontal: one(children.map((c) => _nullishCoalesce(_optionalChain([c, 'access', _196 => _196.resizing, 'optionalAccess', _197 => _197.horizontal]), () => ( "left")))), vertical: one(children.map((c) => _nullishCoalesce(_optionalChain([c, 'access', _198 => _198.resizing, 'optionalAccess', _199 => _199.vertical]), () => ( "top")))) } : null
5928
+ resizing: children.length ? { ids: children.map((c) => c.id), horizontal: one(children.map((c) => _nullishCoalesce(_optionalChain([c, 'access', _200 => _200.resizing, 'optionalAccess', _201 => _201.horizontal]), () => ( "left")))), vertical: one(children.map((c) => _nullishCoalesce(_optionalChain([c, 'access', _202 => _202.resizing, 'optionalAccess', _203 => _203.vertical]), () => ( "top")))) } : null
5903
5929
  };
5904
5930
  }
5905
5931
 
@@ -6285,7 +6311,7 @@ function normalizeVectorFilterParams(type, params, base) {
6285
6311
  if (!isVectorFilterType(type)) return null;
6286
6312
  const out = { ...VECTOR_FILTER_DEFAULTS[type], ..._nullishCoalesce(base, () => ( {})) };
6287
6313
  for (const spec of VECTOR_FILTER_PARAM_SPECS[type]) {
6288
- const v2 = _optionalChain([params, 'optionalAccess', _200 => _200[spec.key]]);
6314
+ const v2 = _optionalChain([params, 'optionalAccess', _204 => _204[spec.key]]);
6289
6315
  if (v2 === void 0) continue;
6290
6316
  if (spec.kind === "number" && typeof v2 === "number" && Number.isFinite(v2)) out[spec.key] = Math.min(_nullishCoalesce(spec.max, () => ( Infinity)), Math.max(_nullishCoalesce(spec.min, () => ( -Infinity)), v2));
6291
6317
  else if (spec.kind === "color" && typeof v2 === "string" && v2.trim()) out[spec.key] = v2.trim();
@@ -6417,7 +6443,7 @@ function vectorFilterSvg(filters, id, bounds) {
6417
6443
  primitives.push(fe("feGaussianBlur", { in: body, stdDeviation: round(f.params.radius / 2), result: name("body") }));
6418
6444
  body = name("body");
6419
6445
  }
6420
- const lastResult = _optionalChain([primitives, 'access', _201 => _201[primitives.length - 1], 'optionalAccess', _202 => _202.attrs, 'access', _203 => _203.result]);
6446
+ const lastResult = _optionalChain([primitives, 'access', _205 => _205[primitives.length - 1], 'optionalAccess', _206 => _206.attrs, 'access', _207 => _207.result]);
6421
6447
  if (lastResult !== body) primitives.push(fe("feMerge", {}, [fe("feMergeNode", { in: body })]));
6422
6448
  const pad = vectorFilterReach(active) + 2;
6423
6449
  return {
@@ -6432,7 +6458,7 @@ function vectorFilterSvg(filters, id, bounds) {
6432
6458
  var escapeAttr = (value) => value.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
6433
6459
  function primitiveMarkup(p) {
6434
6460
  const attrs = Object.entries(p.attrs).map(([k, v2]) => ` ${k}="${escapeAttr(String(v2))}"`).join("");
6435
- return _optionalChain([p, 'access', _204 => _204.children, 'optionalAccess', _205 => _205.length]) ? `<${p.tag}${attrs}>${p.children.map(primitiveMarkup).join("")}</${p.tag}>` : `<${p.tag}${attrs}/>`;
6461
+ return _optionalChain([p, 'access', _208 => _208.children, 'optionalAccess', _209 => _209.length]) ? `<${p.tag}${attrs}>${p.children.map(primitiveMarkup).join("")}</${p.tag}>` : `<${p.tag}${attrs}/>`;
6436
6462
  }
6437
6463
  function vectorFilterMarkup(filter, extra = "") {
6438
6464
  return `<filter id="${escapeAttr(filter.id)}" filterUnits="userSpaceOnUse" x="${filter.x}" y="${filter.y}" width="${filter.width}" height="${filter.height}" color-interpolation-filters="sRGB"${extra}>${filter.primitives.map(primitiveMarkup).join("")}</filter>`;
@@ -6450,7 +6476,7 @@ function sanitizeVectorMask(value) {
6450
6476
  return r.invert === true ? { type: r.type, invert: true } : { type: r.type };
6451
6477
  }
6452
6478
  function isVectorMaskGroup(node) {
6453
- return _optionalChain([node, 'optionalAccess', _206 => _206.type]) === "group" && !!node.mask && isVectorMaskType(node.mask.type) && !node.blend && !node.liveBoolean && node.children.length > 0;
6479
+ return _optionalChain([node, 'optionalAccess', _210 => _210.type]) === "group" && !!node.mask && isVectorMaskType(node.mask.type) && !node.blend && !node.liveBoolean && node.children.length > 0;
6454
6480
  }
6455
6481
  function isVectorMaskActive(node) {
6456
6482
  return isVectorMaskGroup(node) && node.children[0].visible !== false;
@@ -6485,7 +6511,7 @@ function vectorMaskRegionShapes(node, type, parent = IDENTITY_MATRIX, self = tru
6485
6511
  if (!self && node.visible === false) return [];
6486
6512
  if (isVectorFrame(node)) node = vectorFrameDrawn(node);
6487
6513
  const m = multiplyMatrices(nodeMatrix(node), parent);
6488
- if (isVectorMaskActive(node) || node.type === "group" && _optionalChain([node, 'access', _207 => _207.effects, 'optionalAccess', _208 => _208.length])) {
6514
+ if (isVectorMaskActive(node) || node.type === "group" && _optionalChain([node, 'access', _211 => _211.effects, 'optionalAccess', _212 => _212.length])) {
6489
6515
  return vectorAppearanceShapes(node).flatMap((s) => regionOfPath(s.path, s.source, type, m));
6490
6516
  }
6491
6517
  const drawn = expandVectorAppearance(node);
@@ -6690,7 +6716,7 @@ function fitRuns(runs, length2, fallback) {
6690
6716
  }
6691
6717
  if (left2 > 0) {
6692
6718
  if (out.length) out[out.length - 1] = { ...out[out.length - 1], length: out[out.length - 1].length + left2 };
6693
- else out.push({ length: left2, style: _nullishCoalesce(_optionalChain([runs, 'access', _209 => _209[runs.length - 1], 'optionalAccess', _210 => _210.style]), () => ( fallback)) });
6719
+ else out.push({ length: left2, style: _nullishCoalesce(_optionalChain([runs, 'access', _213 => _213[runs.length - 1], 'optionalAccess', _214 => _214.style]), () => ( fallback)) });
6694
6720
  }
6695
6721
  return compact(out);
6696
6722
  }
@@ -6700,7 +6726,7 @@ function styleAt(runs, index, fallback) {
6700
6726
  if (index < at2 + r.length) return r.style;
6701
6727
  at2 += r.length;
6702
6728
  }
6703
- return _nullishCoalesce(_optionalChain([runs, 'access', _211 => _211[runs.length - 1], 'optionalAccess', _212 => _212.style]), () => ( fallback));
6729
+ return _nullishCoalesce(_optionalChain([runs, 'access', _215 => _215[runs.length - 1], 'optionalAccess', _216 => _216.style]), () => ( fallback));
6704
6730
  }
6705
6731
  function restyleRange(runs, start, end, patch) {
6706
6732
  const out = [];
@@ -6756,7 +6782,7 @@ function paragraphRanges(text) {
6756
6782
  return out;
6757
6783
  }
6758
6784
  function fitParagraphRuns(runs, text) {
6759
- const fallback = _nullishCoalesce(_optionalChain([runs, 'access', _213 => _213[0], 'optionalAccess', _214 => _214.style]), () => ( {}));
6785
+ const fallback = _nullishCoalesce(_optionalChain([runs, 'access', _217 => _217[0], 'optionalAccess', _218 => _218.style]), () => ( {}));
6760
6786
  const out = compact(paragraphRanges(text).map((p) => ({ length: p.end - p.start, style: styleAt(runs, p.start, fallback) })));
6761
6787
  return out.length ? out : [{ length: 0, style: fallback }];
6762
6788
  }
@@ -6806,7 +6832,7 @@ function textLineRect(l) {
6806
6832
  var layoutCache = /* @__PURE__ */ new WeakMap();
6807
6833
  function layoutText(layer, shaper) {
6808
6834
  let byShaper = layoutCache.get(layer);
6809
- const hit = _optionalChain([byShaper, 'optionalAccess', _215 => _215.get, 'call', _216 => _216(shaper.id)]);
6835
+ const hit = _optionalChain([byShaper, 'optionalAccess', _219 => _219.get, 'call', _220 => _220(shaper.id)]);
6810
6836
  if (hit) return hit;
6811
6837
  const out = computeLayout(layer, shaper);
6812
6838
  if (!byShaper) {
@@ -6870,7 +6896,7 @@ function computeLayout(layer, shaper) {
6870
6896
  const code = seg.charCodeAt(k);
6871
6897
  if (isLow(code) && index > 0 && isHigh(text.charCodeAt(index - 1))) {
6872
6898
  const prev = chars[chars.length - 1];
6873
- if (_optionalChain([prev, 'optionalAccess', _217 => _217.up])) {
6899
+ if (_optionalChain([prev, 'optionalAccess', _221 => _221.up])) {
6874
6900
  chars.push({ index, ch: seg[k], advance: 0, style, up: prev.up, low: true });
6875
6901
  } else chars.push({ index, ch: seg[k], advance, style, low: true });
6876
6902
  continue;
@@ -7198,7 +7224,7 @@ function createCanvasTextShaper(options = {}) {
7198
7224
  return null;
7199
7225
  })));
7200
7226
  const canvas = make(1, 1);
7201
- const ctx = _optionalChain([canvas, 'optionalAccess', _218 => _218.getContext, 'call', _219 => _219("2d")]);
7227
+ const ctx = _optionalChain([canvas, 'optionalAccess', _222 => _222.getContext, 'call', _223 => _223("2d")]);
7202
7228
  if (!ctx || typeof ctx.measureText !== "function") return null;
7203
7229
  const fallback = _nullishCoalesce(options.fallbackFamily, () => ( "sans-serif"));
7204
7230
  const available = /* @__PURE__ */ new Map();
@@ -7271,10 +7297,10 @@ function createOutlineTextShaper(fonts, options = {}) {
7271
7297
  const entries = fonts.map((f) => {
7272
7298
  const e = "face" in f ? f : { face: f };
7273
7299
  const names = e.face.names;
7274
- const family = _nullishCoalesce(_nullishCoalesce(_nullishCoalesce(e.family, () => ( _optionalChain([names, 'optionalAccess', _220 => _220.fontFamily, 'optionalAccess', _221 => _221.en]))), () => ( Object.values(_nullishCoalesce(_optionalChain([names, 'optionalAccess', _222 => _222.fontFamily]), () => ( {})))[0])), () => ( "Font"));
7275
- const weight = _nullishCoalesce(_nullishCoalesce(e.weight, () => ( _optionalChain([e, 'access', _223 => _223.face, 'access', _224 => _224.tables, 'optionalAccess', _225 => _225.os2, 'optionalAccess', _226 => _226.usWeightClass]))), () => ( 400));
7276
- const italic = _nullishCoalesce(e.italic, () => ( Boolean((_nullishCoalesce(_optionalChain([e, 'access', _227 => _227.face, 'access', _228 => _228.tables, 'optionalAccess', _229 => _229.os2, 'optionalAccess', _230 => _230.fsSelection]), () => ( 0))) & 1)));
7277
- const postScript = _nullishCoalesce(_optionalChain([names, 'optionalAccess', _231 => _231.postScriptName, 'optionalAccess', _232 => _232.en]), () => ( Object.values(_nullishCoalesce(_optionalChain([names, 'optionalAccess', _233 => _233.postScriptName]), () => ( {})))[0]));
7300
+ const family = _nullishCoalesce(_nullishCoalesce(_nullishCoalesce(e.family, () => ( _optionalChain([names, 'optionalAccess', _224 => _224.fontFamily, 'optionalAccess', _225 => _225.en]))), () => ( Object.values(_nullishCoalesce(_optionalChain([names, 'optionalAccess', _226 => _226.fontFamily]), () => ( {})))[0])), () => ( "Font"));
7301
+ const weight = _nullishCoalesce(_nullishCoalesce(e.weight, () => ( _optionalChain([e, 'access', _227 => _227.face, 'access', _228 => _228.tables, 'optionalAccess', _229 => _229.os2, 'optionalAccess', _230 => _230.usWeightClass]))), () => ( 400));
7302
+ const italic = _nullishCoalesce(e.italic, () => ( Boolean((_nullishCoalesce(_optionalChain([e, 'access', _231 => _231.face, 'access', _232 => _232.tables, 'optionalAccess', _233 => _233.os2, 'optionalAccess', _234 => _234.fsSelection]), () => ( 0))) & 1)));
7303
+ const postScript = _nullishCoalesce(_optionalChain([names, 'optionalAccess', _235 => _235.postScriptName, 'optionalAccess', _236 => _236.en]), () => ( Object.values(_nullishCoalesce(_optionalChain([names, 'optionalAccess', _237 => _237.postScriptName]), () => ( {})))[0]));
7278
7304
  return { face: e.face, family, key: family.toLowerCase(), weight, italic, postScript };
7279
7305
  });
7280
7306
  const fallbackKey = (_nullishCoalesce(options.fallback, () => ( entries[0].family))).toLowerCase();
@@ -7321,12 +7347,12 @@ function createOutlineTextShaper(fonts, options = {}) {
7321
7347
  return out;
7322
7348
  },
7323
7349
  outline(text, font, x, y, opts) {
7324
- return toPath(pick(font).entry.face.getPath(text, x, y, font.size, _optionalChain([opts, 'optionalAccess', _234 => _234.vertical]) ? { kerning: true, vertical: true } : { kerning: true }).commands);
7350
+ return toPath(pick(font).entry.face.getPath(text, x, y, font.size, _optionalChain([opts, 'optionalAccess', _238 => _238.vertical]) ? { kerning: true, vertical: true } : { kerning: true }).commands);
7325
7351
  },
7326
7352
  vertical(char, font) {
7327
7353
  const { face } = pick(font).entry;
7328
7354
  const k = font.size / face.unitsPerEm;
7329
- const v2 = _optionalChain([face, 'access', _235 => _235.getVerticalMetrics, 'optionalCall', _236 => _236(char)]);
7355
+ const v2 = _optionalChain([face, 'access', _239 => _239.getVerticalMetrics, 'optionalCall', _240 => _240(char)]);
7330
7356
  if (v2) return { advance: v2.advance * k, originY: v2.originY * k, alternate: v2.alternate };
7331
7357
  return { advance: (face.ascender - face.descender) * k, originY: face.ascender * k, alternate: false };
7332
7358
  },
@@ -7387,7 +7413,7 @@ function vectorTextHasOutlines() {
7387
7413
  return typeof getVectorTextShaper().outline === "function";
7388
7414
  }
7389
7415
  function vectorTextFamilies() {
7390
- return _nullishCoalesce(_optionalChain([getVectorTextShaper, 'call', _237 => _237(), 'access', _238 => _238.families, 'optionalCall', _239 => _239()]), () => ( ["sans-serif", "serif", "monospace"]));
7416
+ return _nullishCoalesce(_optionalChain([getVectorTextShaper, 'call', _241 => _241(), 'access', _242 => _242.families, 'optionalCall', _243 => _243()]), () => ( ["sans-serif", "serif", "monospace"]));
7391
7417
  }
7392
7418
  var DEFAULT_VECTOR_FONT = { fontFamily: "sans-serif", fontWeight: 400, fontSize: 24 };
7393
7419
  var VECTOR_CHARACTER_STYLE_KEYS = ["fontFamily", "fontWeight", "italic", "fontSize", "tracking", "leading", "baselineShift", "underline", "strikethrough", "upright"];
@@ -7563,7 +7589,7 @@ function computeLayout2(node, shaper) {
7563
7589
  const fragments = [];
7564
7590
  const lines = [];
7565
7591
  let overflow = false;
7566
- const fillOf = (f) => _optionalChain([runs, 'access', _240 => _240.find, 'call', _241 => _241((r) => f.start >= r.start && f.start < r.end), 'optionalAccess', _242 => _242.fill]);
7592
+ const fillOf = (f) => _optionalChain([runs, 'access', _244 => _244.find, 'call', _245 => _245((r) => f.start >= r.start && f.start < r.end), 'optionalAccess', _246 => _246.fill]);
7567
7593
  const styleOf = (f) => {
7568
7594
  const { color: _c, opacity: _o, postScriptName: _p, ...style } = f.style;
7569
7595
  return style;
@@ -7602,11 +7628,11 @@ function computeLayout2(node, shaper) {
7602
7628
  } else {
7603
7629
  const line = text.lines[0];
7604
7630
  const measure = measureVectorPath(subpathPath(frame.path), !!frame.flip);
7605
- const align = _nullishCoalesce(_optionalChain([node, 'access', _243 => _243.paragraph, 'optionalAccess', _244 => _244.align]), () => ( "left"));
7631
+ const align = _nullishCoalesce(_optionalChain([node, 'access', _247 => _247.paragraph, 'optionalAccess', _248 => _248.align]), () => ( "left"));
7606
7632
  const start = Math.max(0, _nullishCoalesce(frame.start, () => ( 0)));
7607
7633
  const end = Math.max(0, _nullishCoalesce(frame.end, () => ( 0)));
7608
7634
  const upright = frame.orientation === "upright";
7609
- const baselineOffset = pathBaselineOffset(_nullishCoalesce(frame.baseline, () => ( "baseline")), _nullishCoalesce(_optionalChain([line, 'optionalAccess', _245 => _245.ascent]), () => ( 0)), _nullishCoalesce(_optionalChain([line, 'optionalAccess', _246 => _246.descent]), () => ( 0)));
7635
+ const baselineOffset = pathBaselineOffset(_nullishCoalesce(frame.baseline, () => ( "baseline")), _nullishCoalesce(_optionalChain([line, 'optionalAccess', _249 => _249.ascent]), () => ( 0)), _nullishCoalesce(_optionalChain([line, 'optionalAccess', _250 => _250.descent]), () => ( 0)));
7610
7636
  if (line) {
7611
7637
  const chars = line.chars.filter((c) => {
7612
7638
  const lo = block.text.charCodeAt(c.index);
@@ -7615,7 +7641,7 @@ function computeLayout2(node, shaper) {
7615
7641
  const advanceOf = (c) => {
7616
7642
  const pair = charAt(block.text, c.index).length === 2;
7617
7643
  const low = pair ? line.chars.find((d) => d.index === c.index + 1) : void 0;
7618
- return c.advance + (_nullishCoalesce(_optionalChain([low, 'optionalAccess', _247 => _247.advance]), () => ( 0)));
7644
+ return c.advance + (_nullishCoalesce(_optionalChain([low, 'optionalAccess', _251 => _251.advance]), () => ( 0)));
7619
7645
  };
7620
7646
  const pivots = chars.map((c) => c.x + advanceOf(c) / 2);
7621
7647
  const positions = vectorPathTextPositions(pivots, [line.x, line.x + line.width], align, measure.length, start, end);
@@ -7670,7 +7696,7 @@ function computeLayout2(node, shaper) {
7670
7696
  if (x0 < Infinity) bounds = { x: x0, y: y0, width: x1 - x0, height: y1 - y0 };
7671
7697
  else if (frame.kind === "point") {
7672
7698
  const l = text.lines[0];
7673
- bounds = { x: frame.x, y: frame.y - (_nullishCoalesce(_optionalChain([l, 'optionalAccess', _248 => _248.ascent]), () => ( 0))), width: 0, height: (_nullishCoalesce(_optionalChain([l, 'optionalAccess', _249 => _249.ascent]), () => ( 0))) + (_nullishCoalesce(_optionalChain([l, 'optionalAccess', _250 => _250.descent]), () => ( 0))) };
7699
+ bounds = { x: frame.x, y: frame.y - (_nullishCoalesce(_optionalChain([l, 'optionalAccess', _252 => _252.ascent]), () => ( 0))), width: 0, height: (_nullishCoalesce(_optionalChain([l, 'optionalAccess', _253 => _253.ascent]), () => ( 0))) + (_nullishCoalesce(_optionalChain([l, 'optionalAccess', _254 => _254.descent]), () => ( 0))) };
7674
7700
  }
7675
7701
  }
7676
7702
  return { shaper: shaper.id, glyphs, fragments, lines, origin, text, bounds, overflow, missingFonts: text.missingFonts };
@@ -7791,7 +7817,7 @@ function vectorTextCaret(node, index) {
7791
7817
  const t = { x: Math.cos(r), y: Math.sin(r) };
7792
7818
  const n2 = { x: -t.y, y: t.x };
7793
7819
  const o = { x: g2.x + t.x * u, y: g2.y + t.y * u };
7794
- return { top: { x: o.x - n2.x * g2.ascent, y: o.y - n2.y * g2.ascent }, bottom: { x: o.x + n2.x * g2.descent, y: o.y + n2.y * g2.descent }, line: _nullishCoalesce(_optionalChain([layout, 'access', _251 => _251.fragments, 'access', _252 => _252[g2.fragment], 'optionalAccess', _253 => _253.line]), () => ( 0)) };
7820
+ return { top: { x: o.x - n2.x * g2.ascent, y: o.y - n2.y * g2.ascent }, bottom: { x: o.x + n2.x * g2.descent, y: o.y + n2.y * g2.descent }, line: _nullishCoalesce(_optionalChain([layout, 'access', _255 => _255.fragments, 'access', _256 => _256[g2.fragment], 'optionalAccess', _257 => _257.line]), () => ( 0)) };
7795
7821
  };
7796
7822
  if (node.frame.kind !== "path") {
7797
7823
  const c = caretAt(layout.text, index);
@@ -7931,7 +7957,7 @@ function sanitizeVectorTextFrame(value, path = "frame") {
7931
7957
  return { kind: "area", x: num2(f.x, `${path}.x`, -1e7, 1e7), y: num2(f.y, `${path}.y`, -1e7, 1e7), width: num2(f.width, `${path}.width`, 0, 1e7), height: num2(f.height, `${path}.height`, 0, 1e7) };
7932
7958
  if (f.kind === "path") {
7933
7959
  const sp = f.path;
7934
- if (!sp || !Array.isArray(sp.anchors) || sp.anchors.length < 2 || !sp.anchors.every((a) => isNum(_optionalChain([a, 'optionalAccess', _254 => _254.x])) && isNum(_optionalChain([a, 'optionalAccess', _255 => _255.y])))) fail(`${path}.path must be a subpath with at least two anchors.`);
7960
+ if (!sp || !Array.isArray(sp.anchors) || sp.anchors.length < 2 || !sp.anchors.every((a) => isNum(_optionalChain([a, 'optionalAccess', _258 => _258.x])) && isNum(_optionalChain([a, 'optionalAccess', _259 => _259.y])))) fail(`${path}.path must be a subpath with at least two anchors.`);
7935
7961
  const out = { kind: "path", path: { closed: !!sp.closed, anchors: sp.anchors.map((a) => ({ ...a })) } };
7936
7962
  if (f.start !== void 0 && f.start !== 0) out.start = num2(f.start, `${path}.start`, 0, 1e7);
7937
7963
  if (f.end !== void 0 && f.end !== 0) out.end = num2(f.end, `${path}.end`, 0, 1e7);
@@ -7949,7 +7975,7 @@ function sanitizeVectorTextFrame(value, path = "frame") {
7949
7975
  return fail(`${path}.kind must be point, area or path, got ${JSON.stringify(f.kind)}.`);
7950
7976
  }
7951
7977
  function normalizeVectorTextRuns(text, runs) {
7952
- if (!_optionalChain([runs, 'optionalAccess', _256 => _256.length])) return null;
7978
+ if (!_optionalChain([runs, 'optionalAccess', _260 => _260.length])) return null;
7953
7979
  const cleaned = fitVectorTextRuns(
7954
7980
  runs.map((r) => ({ length: r.length, style: stripUndefined(r.style) })),
7955
7981
  text.length
@@ -7989,7 +8015,7 @@ function replaceVectorText(node, start, end, insert) {
7989
8015
  const clean2 = insert.replace(/\r\n?/g, "\n");
7990
8016
  const text = node.text.slice(0, start) + clean2 + node.text.slice(end);
7991
8017
  let runs = null;
7992
- if (_optionalChain([node, 'access', _257 => _257.runs, 'optionalAccess', _258 => _258.length])) {
8018
+ if (_optionalChain([node, 'access', _261 => _261.runs, 'optionalAccess', _262 => _262.length])) {
7993
8019
  const fitted = fitVectorTextRuns(node.runs, node.text.length);
7994
8020
  const style = styleAt(fitted, start > 0 ? start - 1 : start, {});
7995
8021
  runs = normalizeVectorTextRuns(text, spliceRuns(fitted, start, end, clean2.length, style));
@@ -8005,7 +8031,7 @@ function styleVectorText(node, start, end, patch) {
8005
8031
  if (whole) {
8006
8032
  let next2 = { ...node, font: patchVectorCharacterStyle(node.font, fields, "style") };
8007
8033
  const keys = Object.keys(fields).filter((k) => fields[k] !== void 0);
8008
- if (_optionalChain([next2, 'access', _259 => _259.runs, 'optionalAccess', _260 => _260.length]) && (keys.length || fill !== void 0)) {
8034
+ if (_optionalChain([next2, 'access', _263 => _263.runs, 'optionalAccess', _264 => _264.length]) && (keys.length || fill !== void 0)) {
8009
8035
  const runs2 = normalizeVectorTextRuns(
8010
8036
  next2.text,
8011
8037
  next2.runs.map((r) => {
@@ -8050,7 +8076,7 @@ function bakeVectorTextGeometry(node, m) {
8050
8076
  ...s.baselineShift !== void 0 ? { baselineShift: s.baselineShift * k } : {}
8051
8077
  });
8052
8078
  const font = scaleStyle(node.font);
8053
- const runs = _optionalChain([node, 'access', _261 => _261.runs, 'optionalAccess', _262 => _262.map, 'call', _263 => _263((r) => ({ length: r.length, style: scaleStyle(r.style) }))]);
8079
+ const runs = _optionalChain([node, 'access', _265 => _265.runs, 'optionalAccess', _266 => _266.map, 'call', _267 => _267((r) => ({ length: r.length, style: scaleStyle(r.style) }))]);
8054
8080
  const p = node.paragraph;
8055
8081
  const paragraph = p ? {
8056
8082
  ...p,
@@ -8339,7 +8365,7 @@ function vectorInstanceGroup(node, bake) {
8339
8365
  const m = _nullishCoalesce(node.transform, () => ( [1, 0, 0, 1, 0, 0]));
8340
8366
  const { rigid, residual } = decomposeRigid(m);
8341
8367
  const k = Math.sqrt(Math.abs(residual[0] * residual[3] - residual[1] * residual[2]));
8342
- const hidden = new Set(_nullishCoalesce(_optionalChain([node, 'access', _264 => _264.overrides, 'optionalAccess', _265 => _265.hidden]), () => ( [])));
8368
+ const hidden = new Set(_nullishCoalesce(_optionalChain([node, 'access', _268 => _268.overrides, 'optionalAccess', _269 => _269.hidden]), () => ( [])));
8343
8369
  const keep = (list) => list.filter((n) => !hidden.has(n.id)).map((n) => n.type === "group" ? { ...n, children: keep(n.children) } : n);
8344
8370
  let children = prefixVectorIds(keep(_nullishCoalesce(node.art, () => ( []))), node.id);
8345
8371
  if (!isIdentityMatrix(residual)) children = children.map((c) => bake(c, residual));
@@ -8352,8 +8378,8 @@ function vectorInstanceGroup(node, bake) {
8352
8378
  if (node.locked) group.locked = true;
8353
8379
  if (node.opacity !== void 0) group.opacity = node.opacity;
8354
8380
  if (node.blendMode) group.blendMode = node.blendMode;
8355
- if (_optionalChain([node, 'access', _266 => _266.filters, 'optionalAccess', _267 => _267.length])) group.filters = node.filters;
8356
- if (_optionalChain([node, 'access', _268 => _268.effects, 'optionalAccess', _269 => _269.length])) group.effects = node.effects;
8381
+ if (_optionalChain([node, 'access', _270 => _270.filters, 'optionalAccess', _271 => _271.length])) group.filters = node.filters;
8382
+ if (_optionalChain([node, 'access', _272 => _272.effects, 'optionalAccess', _273 => _273.length])) group.effects = node.effects;
8357
8383
  if (node.booleanOperation) group.booleanOperation = node.booleanOperation;
8358
8384
  if (node.blendStep) group.blendStep = true;
8359
8385
  return group;
@@ -8606,8 +8632,8 @@ function vectorLensDrawn(node) {
8606
8632
  if (wire) {
8607
8633
  contents.push(shapePath(shape, id, changed, { fill: null, fills: void 0, stroke: wire, strokes: void 0, strokeWidth: 1, strokeAlign: void 0, strokeDasharray: void 0, strokeWidthProfile: void 0, opacity: Math.min(1, Math.max(0, lens.amount / 100)) }));
8608
8634
  } else if (recolour) {
8609
- const fills = _optionalChain([shape, 'access', _270 => _270.source, 'access', _271 => _271.fills, 'optionalAccess', _272 => _272.map, 'call', _273 => _273((l) => ({ ...l, paint: _nullishCoalesce(mapVectorPaintColors(l.paint, recolour), () => ( null)) }))]);
8610
- const strokes = _optionalChain([shape, 'access', _274 => _274.source, 'access', _275 => _275.strokes, 'optionalAccess', _276 => _276.map, 'call', _277 => _277((l) => ({ ...l, paint: _nullishCoalesce(mapVectorPaintColors(l.paint, recolour), () => ( null)) }))]);
8635
+ const fills = _optionalChain([shape, 'access', _274 => _274.source, 'access', _275 => _275.fills, 'optionalAccess', _276 => _276.map, 'call', _277 => _277((l) => ({ ...l, paint: _nullishCoalesce(mapVectorPaintColors(l.paint, recolour), () => ( null)) }))]);
8636
+ const strokes = _optionalChain([shape, 'access', _278 => _278.source, 'access', _279 => _279.strokes, 'optionalAccess', _280 => _280.map, 'call', _281 => _281((l) => ({ ...l, paint: _nullishCoalesce(mapVectorPaintColors(l.paint, recolour), () => ( null)) }))]);
8611
8637
  contents.push(shapePath(shape, id, changed, { fill: _nullishCoalesce(mapVectorPaintColors(shape.source.fill, recolour), () => ( null)), stroke: _nullishCoalesce(mapVectorPaintColors(shape.source.stroke, recolour), () => ( null)), ...fills ? { fills } : {}, ...strokes ? { strokes } : {} }));
8612
8638
  } else contents.push(shapePath(shape, id, changed));
8613
8639
  }
@@ -8620,7 +8646,7 @@ function vectorLensDrawn(node) {
8620
8646
  const { lens: _l, lensView: _v, transform: _t, opacity: _o, effects: _e, blendMode: _bm, filters: _f, ...style } = node;
8621
8647
  const fillOpacity = lens.type === "transparency" ? 1 - Math.min(100, Math.max(0, lens.amount)) / 100 : 0;
8622
8648
  children.push({ ...style, id: `${node.id}~lens-fill`, stroke: null, strokes: void 0, opacity: fillOpacity });
8623
- const stroked = (_nullishCoalesce(_optionalChain([node, 'access', _278 => _278.strokes, 'optionalAccess', _279 => _279.length]), () => ( 0))) > 0 || node.stroke != null && node.stroke !== "none";
8649
+ const stroked = (_nullishCoalesce(_optionalChain([node, 'access', _282 => _282.strokes, 'optionalAccess', _283 => _283.length]), () => ( 0))) > 0 || node.stroke != null && node.stroke !== "none";
8624
8650
  if (stroked) children.push({ ...style, id: `${node.id}~lens-stroke`, fill: null, fills: void 0 });
8625
8651
  const out = {
8626
8652
  id: node.id,
@@ -8629,7 +8655,7 @@ function vectorLensDrawn(node) {
8629
8655
  ...node.transform ? { transform: node.transform } : {},
8630
8656
  ...node.opacity !== void 0 ? { opacity: node.opacity } : {},
8631
8657
  ...node.blendMode ? { blendMode: node.blendMode } : {},
8632
- ..._optionalChain([node, 'access', _280 => _280.filters, 'optionalAccess', _281 => _281.length]) ? { filters: node.filters } : {},
8658
+ ..._optionalChain([node, 'access', _284 => _284.filters, 'optionalAccess', _285 => _285.length]) ? { filters: node.filters } : {},
8633
8659
  children
8634
8660
  };
8635
8661
  drawnCache2.set(node, out);
@@ -9630,7 +9656,7 @@ function normalizeVectorEffectParams(type, params, base) {
9630
9656
  if (!defaults) return null;
9631
9657
  const out = { ...defaults, ..._nullishCoalesce(base, () => ( {})) };
9632
9658
  for (const spec of VECTOR_EFFECT_PARAM_SPECS[type]) {
9633
- const v2 = _optionalChain([params, 'optionalAccess', _282 => _282[spec.key]]);
9659
+ const v2 = _optionalChain([params, 'optionalAccess', _286 => _286[spec.key]]);
9634
9660
  if (v2 === void 0) continue;
9635
9661
  if (spec.kind === "number" && typeof v2 === "number" && Number.isFinite(v2)) out[spec.key] = Math.min(_nullishCoalesce(spec.max, () => ( Infinity)), Math.max(_nullishCoalesce(spec.min, () => ( -Infinity)), v2));
9636
9662
  else if (spec.kind === "boolean" && typeof v2 === "boolean") out[spec.key] = v2;
@@ -9642,7 +9668,7 @@ function normalizeVectorEffectParams(type, params, base) {
9642
9668
  const o = out;
9643
9669
  o.rows = Math.round(o.rows);
9644
9670
  o.columns = Math.round(o.columns);
9645
- const given = _optionalChain([params, 'optionalAccess', _283 => _283.mesh]);
9671
+ const given = _optionalChain([params, 'optionalAccess', _287 => _287.mesh]);
9646
9672
  let mesh = given !== void 0 ? isValidWarpMesh(given) ? cloneMesh(given) : null : o.mesh;
9647
9673
  if (o.style !== "mesh") mesh = null;
9648
9674
  if (mesh && given !== void 0) {
@@ -9659,10 +9685,10 @@ function createVectorEffect(type, id, params) {
9659
9685
  }
9660
9686
  var isEnabled = (e) => e.enabled !== false && !!VECTOR_EFFECT_DEFAULTS[e.type];
9661
9687
  function activeVectorEffects(node) {
9662
- return _nullishCoalesce(_optionalChain([node, 'access', _284 => _284.effects, 'optionalAccess', _285 => _285.filter, 'call', _286 => _286(isEnabled)]), () => ( []));
9688
+ return _nullishCoalesce(_optionalChain([node, 'access', _288 => _288.effects, 'optionalAccess', _289 => _289.filter, 'call', _290 => _290(isEnabled)]), () => ( []));
9663
9689
  }
9664
9690
  function hasOwnVectorAppearance(node) {
9665
- return node.type === "text" || node.type === "instance" || node.type === "group" && !!node.liveBoolean || isVectorFrame(node) || isVectorSymmetryGroup(node) || isVectorLens(node) || !!_optionalChain([node, 'access', _287 => _287.effects, 'optionalAccess', _288 => _288.some, 'call', _289 => _289(isEnabled)]);
9691
+ return node.type === "text" || node.type === "instance" || node.type === "group" && !!node.liveBoolean || isVectorFrame(node) || isVectorSymmetryGroup(node) || isVectorLens(node) || !!_optionalChain([node, 'access', _291 => _291.effects, 'optionalAccess', _292 => _292.some, 'call', _293 => _293(isEnabled)]);
9666
9692
  }
9667
9693
  var liveCache = /* @__PURE__ */ new WeakMap();
9668
9694
  function hasVectorAppearance(node) {
@@ -9674,7 +9700,7 @@ function hasVectorAppearance(node) {
9674
9700
  return v2;
9675
9701
  }
9676
9702
  function isVectorLiveBoolean(node) {
9677
- return _optionalChain([node, 'optionalAccess', _290 => _290.type]) === "group" && !!node.liveBoolean;
9703
+ return _optionalChain([node, 'optionalAccess', _294 => _294.type]) === "group" && !!node.liveBoolean;
9678
9704
  }
9679
9705
  function vectorOperandOperation(group, child) {
9680
9706
  return _nullishCoalesce(_nullishCoalesce(child.booleanOperation, () => ( group.liveBoolean)), () => ( "union"));
@@ -9791,7 +9817,7 @@ var compareOrder = (a, b) => {
9791
9817
  for (let i = 0; i < n; i++) if (a[i] !== b[i]) return a[i] - b[i];
9792
9818
  return a.length - b.length;
9793
9819
  };
9794
- var add3 = (a, b) => ({ x: a.x + (_nullishCoalesce(_optionalChain([b, 'optionalAccess', _291 => _291.x]), () => ( 0))), y: a.y + (_nullishCoalesce(_optionalChain([b, 'optionalAccess', _292 => _292.y]), () => ( 0))) });
9820
+ var add3 = (a, b) => ({ x: a.x + (_nullishCoalesce(_optionalChain([b, 'optionalAccess', _295 => _295.x]), () => ( 0))), y: a.y + (_nullishCoalesce(_optionalChain([b, 'optionalAccess', _296 => _296.y]), () => ( 0))) });
9795
9821
  var mapPaths = (shapes, fn) => {
9796
9822
  const out = fn(shapes.map((s) => s.path));
9797
9823
  return shapes.map((s, i) => ({ ...s, path: _nullishCoalesce(out[i], () => ( [])) }));
@@ -9819,7 +9845,7 @@ function contourShapes(shapes, c) {
9819
9845
  const power = 2 ** (Math.min(100, Math.max(-100, c.acceleration)) / 50);
9820
9846
  for (let k = 1; k <= n; k++) {
9821
9847
  const [path] = offsetPaths([s.path], (outside ? 1 : -1) * step * k, c.join, c.miterLimit, 1, 0);
9822
- if (!_optionalChain([path, 'optionalAccess', _293 => _293.length])) break;
9848
+ if (!_optionalChain([path, 'optionalAccess', _297 => _297.length])) break;
9823
9849
  const t = (k / n) ** power;
9824
9850
  const source = { ...s.source, fill: _nullishCoalesce(blendPaint(s.source.fill, c.fillColor, t), () => ( null)), stroke: _nullishCoalesce(blendPaint(s.source.stroke, c.strokeColor, t), () => ( null)), fills: void 0, strokes: void 0 };
9825
9851
  out.push({ source, path, opacity: s.opacity, order: [outside ? n - k : k, ...s.order] });
@@ -9894,8 +9920,8 @@ function bevelShapes(shapes, b) {
9894
9920
  out.push({ source, path: f.path, opacity: s.opacity, order: [...s.order, 1, k] });
9895
9921
  });
9896
9922
  const [middle] = offsetPaths([s.path], -b.width, "miter", 4, 1, 0);
9897
- if (_optionalChain([middle, 'optionalAccess', _294 => _294.length])) out.push({ ...s, source: fillOnly, path: middle, order: [...s.order, 2] });
9898
- const hasStroke = _optionalChain([s, 'access', _295 => _295.source, 'access', _296 => _296.strokes, 'optionalAccess', _297 => _297.length]) || s.source.stroke != null && s.source.stroke !== "none";
9923
+ if (_optionalChain([middle, 'optionalAccess', _298 => _298.length])) out.push({ ...s, source: fillOnly, path: middle, order: [...s.order, 2] });
9924
+ const hasStroke = _optionalChain([s, 'access', _299 => _299.source, 'access', _300 => _300.strokes, 'optionalAccess', _301 => _301.length]) || s.source.stroke != null && s.source.stroke !== "none";
9899
9925
  if (hasStroke) out.push({ ...s, source: { ...s.source, fill: null, fills: void 0 }, order: [...s.order, 3] });
9900
9926
  }
9901
9927
  return out;
@@ -10028,10 +10054,10 @@ function vectorEffectInputBounds(node, effectId) {
10028
10054
  return paths ? pathsBounds(paths) : null;
10029
10055
  }
10030
10056
  function vectorNodeEnvelope(node) {
10031
- return _nullishCoalesce(_optionalChain([node, 'optionalAccess', _298 => _298.effects, 'optionalAccess', _299 => _299.find, 'call', _300 => _300((e) => e.type === "envelope" && e.enabled !== false)]), () => ( null));
10057
+ return _nullishCoalesce(_optionalChain([node, 'optionalAccess', _302 => _302.effects, 'optionalAccess', _303 => _303.find, 'call', _304 => _304((e) => e.type === "envelope" && e.enabled !== false)]), () => ( null));
10032
10058
  }
10033
10059
  function vectorEnvelopeFrame(node, effectId) {
10034
- const e = effectId ? _optionalChain([node, 'access', _301 => _301.effects, 'optionalAccess', _302 => _302.find, 'call', _303 => _303((x) => x.id === effectId)]) : vectorNodeEnvelope(node);
10060
+ const e = effectId ? _optionalChain([node, 'access', _305 => _305.effects, 'optionalAccess', _306 => _306.find, 'call', _307 => _307((x) => x.id === effectId)]) : vectorNodeEnvelope(node);
10035
10061
  if (!e || e.type !== "envelope") return null;
10036
10062
  const bounds = vectorEffectInputBounds(node, e.id);
10037
10063
  if (!bounds || !(bounds.width > 0 && bounds.height > 0)) return null;
@@ -10092,7 +10118,7 @@ function placement(node) {
10092
10118
  ...node.blendStep ? { blendStep: true } : {},
10093
10119
  ...node.booleanOperation ? { booleanOperation: node.booleanOperation } : {},
10094
10120
  ...node.blendMode ? { blendMode: node.blendMode } : {},
10095
- ..._optionalChain([node, 'access', _304 => _304.filters, 'optionalAccess', _305 => _305.length]) ? { filters: node.filters } : {}
10121
+ ..._optionalChain([node, 'access', _308 => _308.filters, 'optionalAccess', _309 => _309.length]) ? { filters: node.filters } : {}
10096
10122
  };
10097
10123
  }
10098
10124
  function vectorAppearanceNodes(node) {
@@ -10224,7 +10250,7 @@ function vectorMasterPages(doc) {
10224
10250
  function fillTokens(node, page, pages) {
10225
10251
  const map = (s) => s.replace(/\{page\}/g, String(page)).replace(/\{pages\}/g, String(pages));
10226
10252
  if (!/\{pages?\}/.test(node.text)) return node;
10227
- if (!_optionalChain([node, 'access', _306 => _306.runs, 'optionalAccess', _307 => _307.length])) return { ...node, text: map(node.text) };
10253
+ if (!_optionalChain([node, 'access', _310 => _310.runs, 'optionalAccess', _311 => _311.length])) return { ...node, text: map(node.text) };
10228
10254
  let at2 = 0;
10229
10255
  let text = "";
10230
10256
  const runs = [];
@@ -10247,7 +10273,7 @@ function vectorMasterArt(master, page, number, count) {
10247
10273
  const f = page.frame;
10248
10274
  const key = `${page.id}|${f.x}|${f.y}|${f.width}|${f.height}|${number}|${count}`;
10249
10275
  let byKey = artCache.get(master);
10250
- const hit = _optionalChain([byKey, 'optionalAccess', _308 => _308.get, 'call', _309 => _309(key)]);
10276
+ const hit = _optionalChain([byKey, 'optionalAccess', _312 => _312.get, 'call', _313 => _313(key)]);
10251
10277
  if (hit) return hit;
10252
10278
  const art = master.children.filter((c) => c.visible !== false).map((c) => {
10253
10279
  const box = vectorNodeBounds(c);
@@ -10292,7 +10318,7 @@ function stripVectorMasterArt(doc) {
10292
10318
  // src/vector/connectors.ts
10293
10319
  var SIDES = ["top", "right", "bottom", "left", "center"];
10294
10320
  function isVectorConnector(node) {
10295
- return _optionalChain([node, 'optionalAccess', _310 => _310.type]) === "path" && !!node.connector;
10321
+ return _optionalChain([node, 'optionalAccess', _314 => _314.type]) === "path" && !!node.connector;
10296
10322
  }
10297
10323
  function vectorConnectionSites(nodes, id) {
10298
10324
  const node = findVectorNode(nodes, id);
@@ -10349,7 +10375,7 @@ function facingSite(sites, toward) {
10349
10375
  }
10350
10376
  function storedEnds(node, world) {
10351
10377
  const sp = node.subpaths[0];
10352
- if (!_optionalChain([sp, 'optionalAccess', _311 => _311.anchors, 'access', _312 => _312.length])) return null;
10378
+ if (!_optionalChain([sp, 'optionalAccess', _315 => _315.anchors, 'access', _316 => _316.length])) return null;
10353
10379
  const a = sp.anchors[0];
10354
10380
  const b = sp.anchors[sp.anchors.length - 1];
10355
10381
  return [applyMatrix(world, a), applyMatrix(world, b)];
@@ -10456,8 +10482,8 @@ function routeVectorConnector(nodes, id) {
10456
10482
  }));
10457
10483
  return {
10458
10484
  subpaths: [{ closed: false, anchors: local }],
10459
- startSide: _nullishCoalesce(_optionalChain([s, 'optionalAccess', _313 => _313.side]), () => ( null)),
10460
- endSide: _nullishCoalesce(_optionalChain([e, 'optionalAccess', _314 => _314.side]), () => ( null)),
10485
+ startSide: _nullishCoalesce(_optionalChain([s, 'optionalAccess', _317 => _317.side]), () => ( null)),
10486
+ endSide: _nullishCoalesce(_optionalChain([e, 'optionalAccess', _318 => _318.side]), () => ( null)),
10461
10487
  dropped: { start: !!startGlue && !s, end: !!endGlue && !e }
10462
10488
  };
10463
10489
  }
@@ -10469,7 +10495,7 @@ function sameSubpaths(a, b) {
10469
10495
  const o = b[i];
10470
10496
  return sp.closed === o.closed && sp.anchors.length === o.anchors.length && sp.anchors.every((p, k) => {
10471
10497
  const q = o.anchors[k];
10472
- return samePoint(p, q) && samePoint(p.in, q.in) && samePoint(p.out, q.out) && (_nullishCoalesce(_optionalChain([p, 'access', _315 => _315.corner, 'optionalAccess', _316 => _316.radius]), () => ( 0))) === (_nullishCoalesce(_optionalChain([q, 'access', _317 => _317.corner, 'optionalAccess', _318 => _318.radius]), () => ( 0)));
10498
+ return samePoint(p, q) && samePoint(p.in, q.in) && samePoint(p.out, q.out) && (_nullishCoalesce(_optionalChain([p, 'access', _319 => _319.corner, 'optionalAccess', _320 => _320.radius]), () => ( 0))) === (_nullishCoalesce(_optionalChain([q, 'access', _321 => _321.corner, 'optionalAccess', _322 => _322.radius]), () => ( 0)));
10473
10499
  });
10474
10500
  });
10475
10501
  }
@@ -10748,7 +10774,7 @@ function applyVectorCornersAttribute(subpaths, value) {
10748
10774
  for (const item of value.trim().split(/\s+/)) {
10749
10775
  const m = /^(\d+)\.(\d+):([\d.eE+-]+)(?::([a-z]+))?$/.exec(item);
10750
10776
  if (!m) continue;
10751
- const a = _optionalChain([subpaths, 'access', _319 => _319[+m[1]], 'optionalAccess', _320 => _320.anchors, 'access', _321 => _321[+m[2]]]);
10777
+ const a = _optionalChain([subpaths, 'access', _323 => _323[+m[1]], 'optionalAccess', _324 => _324.anchors, 'access', _325 => _325[+m[2]]]);
10752
10778
  const radius = parseFloat(m[3]);
10753
10779
  if (!a || !(radius > 0)) continue;
10754
10780
  const kind = VECTOR_CORNER_KINDS.includes(m[4]) ? m[4] : void 0;
@@ -10773,7 +10799,7 @@ function vectorPaintToSvg(paint, gradientId, options = {}) {
10773
10799
  const area2 = bounds2 ? { x: bounds2.x - reach2, y: bounds2.y - reach2, width: bounds2.width + 2 * reach2, height: bounds2.height + 2 * reach2 } : null;
10774
10800
  const key2 = `${gradientId}|${_nullishCoalesce(options.role, () => ( "fill"))}|${_nullishCoalesce(options.precision, () => ( 3))}|${area2 ? [area2.x, area2.y, area2.width, area2.height].join(",") : ""}`;
10775
10801
  let byKey2 = paintCache.get(paint);
10776
- const hit = _optionalChain([byKey2, 'optionalAccess', _322 => _322.get, 'call', _323 => _323(key2)]);
10802
+ const hit = _optionalChain([byKey2, 'optionalAccess', _326 => _326.get, 'call', _327 => _327(key2)]);
10777
10803
  if (hit) return { value: `url(#${gradientId})`, defs: hit };
10778
10804
  const defs2 = vectorShadedSvgDefs(paint, gradientId, { bounds: bounds2, area: area2, precision: _nullishCoalesce(options.precision, () => ( 3)) });
10779
10805
  if (!byKey2) paintCache.set(paint, byKey2 = /* @__PURE__ */ new Map());
@@ -10785,7 +10811,7 @@ function vectorPaintToSvg(paint, gradientId, options = {}) {
10785
10811
  const precision = _nullishCoalesce(options.precision, () => ( 3));
10786
10812
  const key = `${gradientId}|${role}|${precision}`;
10787
10813
  const owner = _nullishCoalesce(options.node, () => ( paint));
10788
- const cached = _optionalChain([paintCache, 'access', _324 => _324.get, 'call', _325 => _325(owner), 'optionalAccess', _326 => _326.get, 'call', _327 => _327(key)]);
10814
+ const cached = _optionalChain([paintCache, 'access', _328 => _328.get, 'call', _329 => _329(owner), 'optionalAccess', _330 => _330.get, 'call', _331 => _331(key)]);
10789
10815
  if (cached && (!options.node || (role === "fill" ? options.node.fill : options.node.stroke) === paint)) return { value: `url(#${gradientId})`, defs: cached };
10790
10816
  const node = options.node;
10791
10817
  const bounds = node ? vectorPathLocalBounds(node) : null;
@@ -10839,7 +10865,7 @@ function vectorNodeLocalPaintBounds(node) {
10839
10865
  }
10840
10866
  var filterCache = /* @__PURE__ */ new WeakMap();
10841
10867
  function vectorNodeFilterSvg(node, id) {
10842
- if (!_optionalChain([node, 'access', _328 => _328.filters, 'optionalAccess', _329 => _329.length])) return null;
10868
+ if (!_optionalChain([node, 'access', _332 => _332.filters, 'optionalAccess', _333 => _333.length])) return null;
10843
10869
  const hit = filterCache.get(node);
10844
10870
  if (hit && hit.id === id) return hit.filter;
10845
10871
  const active = activeVectorFilters(node);
@@ -10925,7 +10951,7 @@ function vectorDocumentToSvg(doc, options = {}) {
10925
10951
  if (node.type === "path" && node.lens) out2 += ` data-vector-lens="${escapeAttr2(JSON.stringify(node.lens))}"`;
10926
10952
  const blend = vectorBlendModeCss(node.blendMode);
10927
10953
  if (blend) out2 += ` style="mix-blend-mode:${blend}"`;
10928
- if (_optionalChain([node, 'access', _330 => _330.filters, 'optionalAccess', _331 => _331.length])) {
10954
+ if (_optionalChain([node, 'access', _334 => _334.filters, 'optionalAccess', _335 => _335.length])) {
10929
10955
  const filter = vectorNodeFilterSvg(node, `${prefix}filter-${node.id}`);
10930
10956
  const data = ` data-vector-filters="${escapeAttr2(JSON.stringify(node.filters))}"`;
10931
10957
  if (filter) {
@@ -10972,7 +10998,7 @@ function vectorDocumentToSvg(doc, options = {}) {
10972
10998
  let out2 = ` stroke="${escapeAttr2(strokeValue)}" stroke-width="${num3(width)}"`;
10973
10999
  if (node.strokeLinecap && node.strokeLinecap !== "butt") out2 += ` stroke-linecap="${node.strokeLinecap}"`;
10974
11000
  if (node.strokeLinejoin && node.strokeLinejoin !== "miter") out2 += ` stroke-linejoin="${node.strokeLinejoin}"`;
10975
- if (_optionalChain([node, 'access', _332 => _332.strokeDasharray, 'optionalAccess', _333 => _333.length])) out2 += ` stroke-dasharray="${node.strokeDasharray.map(num3).join(" ")}"`;
11001
+ if (_optionalChain([node, 'access', _336 => _336.strokeDasharray, 'optionalAccess', _337 => _337.length])) out2 += ` stroke-dasharray="${node.strokeDasharray.map(num3).join(" ")}"`;
10976
11002
  return out2;
10977
11003
  };
10978
11004
  const liveCorners = (node) => {
@@ -11021,7 +11047,7 @@ function vectorDocumentToSvg(doc, options = {}) {
11021
11047
  };
11022
11048
  const emit2 = (node, depth) => {
11023
11049
  if (node.visible === false && !options.includeHidden) return;
11024
- const wrappers = _nullishCoalesce(_optionalChain([options, 'access', _334 => _334.wrap, 'optionalAccess', _335 => _335[node.id]]), () => ( []));
11050
+ const wrappers = _nullishCoalesce(_optionalChain([options, 'access', _338 => _338.wrap, 'optionalAccess', _339 => _339[node.id]]), () => ( []));
11025
11051
  wrappers.forEach((w2, i) => {
11026
11052
  let attrs = w2.id !== void 0 ? ` id="${escapeAttr2(w2.id)}"` : "";
11027
11053
  if (w2.transform) attrs += ` transform="${escapeAttr2(w2.transform)}"`;
@@ -11042,7 +11068,7 @@ function vectorDocumentToSvg(doc, options = {}) {
11042
11068
  };
11043
11069
  const emitMaskGroup = (node, depth) => {
11044
11070
  const [source, ...contents] = node.children;
11045
- const body = _optionalChain([node, 'access', _336 => _336.effects, 'optionalAccess', _337 => _337.length]) && contents.length ? [{ id: `${node.id}~content`, type: "group", effects: node.effects, children: contents }] : contents;
11071
+ const body = _optionalChain([node, 'access', _340 => _340.effects, 'optionalAccess', _341 => _341.length]) && contents.length ? [{ id: `${node.id}~content`, type: "group", effects: node.effects, children: contents }] : contents;
11046
11072
  const settings = { type: node.mask.type, ...node.mask.invert ? { invert: true } : {} };
11047
11073
  lines.push(`${indent(depth)}<g${common(node)} data-vector-mask="${escapeAttr2(JSON.stringify(settings))}">`);
11048
11074
  const mask = vectorMaskRenderData(node, `${prefix}mask-${node.id}`, `${prefix}mask-filter-${node.id}`, precision);
@@ -11059,7 +11085,7 @@ function vectorDocumentToSvg(doc, options = {}) {
11059
11085
  lines.push(`${indent(depth + 1)}<g data-vector-part="mask-source" display="none">`);
11060
11086
  emitNode(source, depth + 2);
11061
11087
  lines.push(`${indent(depth + 1)}</g>`);
11062
- if (_optionalChain([mask, 'optionalAccess', _338 => _338.clip])) {
11088
+ if (_optionalChain([mask, 'optionalAccess', _342 => _342.clip])) {
11063
11089
  defs.push(`<clipPath id="${escapeAttr2(mask.id)}">${mask.clip.map((c) => `<path d="${c.d}" clip-rule="${c.clipRule}"/>`).join("")}</clipPath>`);
11064
11090
  ref = ` clip-path="url(#${escapeAttr2(mask.id)})"`;
11065
11091
  }
@@ -11071,7 +11097,7 @@ function vectorDocumentToSvg(doc, options = {}) {
11071
11097
  };
11072
11098
  const emitTextElement = (node, depth, attrs) => {
11073
11099
  const geometry = vectorTextGeometryNode(node);
11074
- const fields = { text: node.text, font: node.font, ..._optionalChain([node, 'access', _339 => _339.runs, 'optionalAccess', _340 => _340.length]) ? { runs: node.runs } : {}, ...node.paragraph ? { paragraph: node.paragraph } : {}, frame: node.frame, ...node.orientation ? { orientation: node.orientation } : {}, ..._optionalChain([node, 'access', _341 => _341.effects, 'optionalAccess', _342 => _342.length]) ? { effects: node.effects } : {} };
11100
+ const fields = { text: node.text, font: node.font, ..._optionalChain([node, 'access', _343 => _343.runs, 'optionalAccess', _344 => _344.length]) ? { runs: node.runs } : {}, ...node.paragraph ? { paragraph: node.paragraph } : {}, frame: node.frame, ...node.orientation ? { orientation: node.orientation } : {}, ..._optionalChain([node, 'access', _345 => _345.effects, 'optionalAccess', _346 => _346.length]) ? { effects: node.effects } : {} };
11075
11101
  let data = ` data-vector-text="${escapeAttr2(JSON.stringify(fields))}"`;
11076
11102
  if (hasVectorPaintStacks(node)) data += ` data-vector-fills="${escapeAttr2(JSON.stringify(vectorFills(node)))}" data-vector-strokes="${escapeAttr2(JSON.stringify(vectorStrokes(node)))}"`;
11077
11103
  else {
@@ -11113,12 +11139,12 @@ function vectorDocumentToSvg(doc, options = {}) {
11113
11139
  };
11114
11140
  const emitText = (node, depth) => {
11115
11141
  const outlines = vectorTextPaths(node).outlines;
11116
- const effects = !!_optionalChain([node, 'access', _343 => _343.effects, 'optionalAccess', _344 => _344.some, 'call', _345 => _345((e) => e.enabled !== false)]);
11142
+ const effects = !!_optionalChain([node, 'access', _347 => _347.effects, 'optionalAccess', _348 => _348.some, 'call', _349 => _349((e) => e.enabled !== false)]);
11117
11143
  if (!outlines || !effects && options.text !== "outlines") {
11118
11144
  emitTextElement(node, depth, common(node));
11119
11145
  return;
11120
11146
  }
11121
- lines.push(`${indent(depth)}<g${common(node)} data-vector-live="${escapeAttr2(JSON.stringify({ kind: "text", ..._optionalChain([node, 'access', _346 => _346.effects, 'optionalAccess', _347 => _347.length]) ? { effects: node.effects } : {} }))}">`);
11147
+ lines.push(`${indent(depth)}<g${common(node)} data-vector-live="${escapeAttr2(JSON.stringify({ kind: "text", ..._optionalChain([node, 'access', _350 => _350.effects, 'optionalAccess', _351 => _351.length]) ? { effects: node.effects } : {} }))}">`);
11122
11148
  lines.push(`${indent(depth + 1)}<g data-vector-part="appearance">`);
11123
11149
  for (const shape of vectorAppearanceNodes(node)) emit2(shape, depth + 2);
11124
11150
  lines.push(`${indent(depth + 1)}</g>`);
@@ -11132,7 +11158,7 @@ function vectorDocumentToSvg(doc, options = {}) {
11132
11158
  const symbolRef = (symbolId) => {
11133
11159
  const hit = symbolIds.get(symbolId);
11134
11160
  if (hit) return hit;
11135
- const sym2 = _optionalChain([doc, 'access', _348 => _348.symbols, 'optionalAccess', _349 => _349.find, 'call', _350 => _350((x) => x.id === symbolId)]);
11161
+ const sym2 = _optionalChain([doc, 'access', _352 => _352.symbols, 'optionalAccess', _353 => _353.find, 'call', _354 => _354((x) => x.id === symbolId)]);
11136
11162
  if (!sym2) return null;
11137
11163
  const id = `${prefix}symbol-${symbolId}`;
11138
11164
  symbolIds.set(symbolId, id);
@@ -11142,20 +11168,20 @@ function vectorDocumentToSvg(doc, options = {}) {
11142
11168
  };
11143
11169
  const emitInstance = (node, depth) => {
11144
11170
  const data = { symbolId: node.symbolId, ...node.scaleStrokes === false ? { scaleStrokes: false } : {}, ...node.overrides ? { overrides: node.overrides } : {} };
11145
- const exact2 = !node.overrides && node.scaleStrokes !== false && !_optionalChain([node, 'access', _351 => _351.effects, 'optionalAccess', _352 => _352.length]) && !_optionalChain([node, 'access', _353 => _353.filters, 'optionalAccess', _354 => _354.length]);
11171
+ const exact2 = !node.overrides && node.scaleStrokes !== false && !_optionalChain([node, 'access', _355 => _355.effects, 'optionalAccess', _356 => _356.length]) && !_optionalChain([node, 'access', _357 => _357.filters, 'optionalAccess', _358 => _358.length]);
11146
11172
  const ref = symbolRef(node.symbolId);
11147
11173
  if (exact2 && ref) {
11148
11174
  lines.push(`${indent(depth)}<use${common(node)} href="#${escapeAttr2(ref)}" data-vector-instance="${escapeAttr2(JSON.stringify(data))}"/>`);
11149
11175
  return;
11150
11176
  }
11151
- const full = { ...data, ...node.transform ? { transform: node.transform } : {}, ..._optionalChain([node, 'access', _355 => _355.effects, 'optionalAccess', _356 => _356.length]) ? { effects: node.effects } : {} };
11177
+ const full = { ...data, ...node.transform ? { transform: node.transform } : {}, ..._optionalChain([node, 'access', _359 => _359.effects, 'optionalAccess', _360 => _360.length]) ? { effects: node.effects } : {} };
11152
11178
  lines.push(`${indent(depth)}<g data-vector-instance="${escapeAttr2(JSON.stringify(full))}">`);
11153
11179
  emitNode(vectorInstanceDrawn(node), depth + 1);
11154
11180
  lines.push(`${indent(depth)}</g>`);
11155
11181
  };
11156
11182
  const emitFrame = (node, depth) => {
11157
11183
  const f = node.frame;
11158
- const data = { ...f, ..._optionalChain([node, 'access', _357 => _357.effects, 'optionalAccess', _358 => _358.length]) ? { effects: node.effects } : {} };
11184
+ const data = { ...f, ..._optionalChain([node, 'access', _361 => _361.effects, 'optionalAccess', _362 => _362.length]) ? { effects: node.effects } : {} };
11159
11185
  lines.push(`${indent(depth)}<g${common(node)} data-vector-frame="${escapeAttr2(JSON.stringify(data))}">`);
11160
11186
  const rect = vectorFrameRectPath(f);
11161
11187
  if (f.fill !== void 0 && f.fill !== null && f.fill !== "none") {
@@ -11170,7 +11196,7 @@ function vectorDocumentToSvg(doc, options = {}) {
11170
11196
  ref = ` clip-path="url(#${escapeAttr2(id)})"`;
11171
11197
  }
11172
11198
  lines.push(`${indent(depth + 1)}<g data-vector-part="frame-contents"${ref}>`);
11173
- if (_optionalChain([node, 'access', _359 => _359.masterArt, 'optionalAccess', _360 => _360.length])) {
11199
+ if (_optionalChain([node, 'access', _363 => _363.masterArt, 'optionalAccess', _364 => _364.length])) {
11174
11200
  lines.push(`${indent(depth + 2)}<g data-vector-part="frame-master">`);
11175
11201
  for (const child of node.masterArt) emit2(child, depth + 3);
11176
11202
  lines.push(`${indent(depth + 2)}</g>`);
@@ -11199,7 +11225,7 @@ function vectorDocumentToSvg(doc, options = {}) {
11199
11225
  if (hasOwnVectorAppearance(node)) {
11200
11226
  const live2 = {
11201
11227
  kind: node.type,
11202
- ..._optionalChain([node, 'access', _361 => _361.effects, 'optionalAccess', _362 => _362.length]) ? { effects: node.effects } : {},
11228
+ ..._optionalChain([node, 'access', _365 => _365.effects, 'optionalAccess', _366 => _366.length]) ? { effects: node.effects } : {},
11203
11229
  ...node.type === "group" && node.liveBoolean ? { liveBoolean: node.liveBoolean } : {},
11204
11230
  ...node.type === "group" && node.symmetry ? { symmetry: node.symmetry } : {}
11205
11231
  };
@@ -11250,7 +11276,7 @@ function vectorDocumentToSvg(doc, options = {}) {
11250
11276
  data += ` data-vector-width-profile="${widthProfileToAttribute(profile)}"`;
11251
11277
  if (node.strokeLinecap && node.strokeLinecap !== "butt") data += ` data-vector-stroke-linecap="${node.strokeLinecap}"`;
11252
11278
  if (node.strokeLinejoin && node.strokeLinejoin !== "miter") data += ` data-vector-stroke-linejoin="${node.strokeLinejoin}"`;
11253
- if (_optionalChain([node, 'access', _363 => _363.strokeDasharray, 'optionalAccess', _364 => _364.length])) data += ` data-vector-stroke-dasharray="${node.strokeDasharray.map(num3).join(" ")}"`;
11279
+ if (_optionalChain([node, 'access', _367 => _367.strokeDasharray, 'optionalAccess', _368 => _368.length])) data += ` data-vector-stroke-dasharray="${node.strokeDasharray.map(num3).join(" ")}"`;
11254
11280
  }
11255
11281
  lines.push(`${indent(depth)}<g${common(node)}${data}>`);
11256
11282
  lines.push(`${indent(depth + 1)}<path data-vector-part="fill" d="${d}"${fillAttrs}${live}/>`);
@@ -11431,7 +11457,7 @@ function readStyle(el, parent, cssRules) {
11431
11457
  const { mixBlendMode: _m, filter: _f, ...inherited } = parent;
11432
11458
  const out = { ...inherited };
11433
11459
  for (const [attr, key] of Object.entries(STYLE_KEYS)) if (el.attrs[attr] !== void 0) out[key] = el.attrs[attr].trim();
11434
- if (_optionalChain([cssRules, 'optionalAccess', _365 => _365.length])) {
11460
+ if (_optionalChain([cssRules, 'optionalAccess', _369 => _369.length])) {
11435
11461
  for (const rule of cssRules) {
11436
11462
  if (matchesSelector(el, rule.selector)) {
11437
11463
  for (const [prop, val] of Object.entries(rule.properties)) {
@@ -11487,7 +11513,7 @@ function attrOrStyle(el, name) {
11487
11513
  return el.attrs[name];
11488
11514
  }
11489
11515
  function urlId(value) {
11490
- return _nullishCoalesce(_optionalChain([/^url\(\s*['"]?#([^'")\s]+)['"]?\s*\)/, 'access', _366 => _366.exec, 'call', _367 => _367((_nullishCoalesce(value, () => ( ""))).trim()), 'optionalAccess', _368 => _368[1]]), () => ( null));
11516
+ return _nullishCoalesce(_optionalChain([/^url\(\s*['"]?#([^'")\s]+)['"]?\s*\)/, 'access', _370 => _370.exec, 'call', _371 => _371((_nullishCoalesce(value, () => ( ""))).trim()), 'optionalAccess', _372 => _372[1]]), () => ( null));
11491
11517
  }
11492
11518
  function clipRulesAsFillRules(el) {
11493
11519
  const attrs = { ...el.attrs };
@@ -11552,9 +11578,9 @@ function resolveGradient(id, raw) {
11552
11578
  for (let el = first; el && !chain.includes(el) && chain.length < 32; ) {
11553
11579
  chain.push(el);
11554
11580
  const href = _nullishCoalesce(el.attrs.href, () => ( el.attrs["xlink:href"]));
11555
- el = _optionalChain([href, 'optionalAccess', _369 => _369.startsWith, 'call', _370 => _370("#")]) ? raw.get(href.slice(1)) : void 0;
11581
+ el = _optionalChain([href, 'optionalAccess', _373 => _373.startsWith, 'call', _374 => _374("#")]) ? raw.get(href.slice(1)) : void 0;
11556
11582
  }
11557
- const attr = (name) => _optionalChain([chain, 'access', _371 => _371.find, 'call', _372 => _372((el) => el.attrs[name] !== void 0), 'optionalAccess', _373 => _373.attrs, 'access', _374 => _374[name]]);
11583
+ const attr = (name) => _optionalChain([chain, 'access', _375 => _375.find, 'call', _376 => _376((el) => el.attrs[name] !== void 0), 'optionalAccess', _377 => _377.attrs, 'access', _378 => _378[name]]);
11558
11584
  const stops = _nullishCoalesce(chain.map(readStops).find((s) => s.length), () => ( []));
11559
11585
  if (!stops.length) return null;
11560
11586
  const user = attr("gradientUnits") === "userSpaceOnUse";
@@ -11726,7 +11752,7 @@ function parseVectorSvg(svg, options = {}) {
11726
11752
  const stackedPath = (g, _style, m, meta) => {
11727
11753
  const fillEl = g.children.find((c) => c.name === "path" && c.attrs["data-vector-part"] === "fill");
11728
11754
  const subpaths = fillEl ? shapeOf(fillEl) : null;
11729
- if (!_optionalChain([subpaths, 'optionalAccess', _375 => _375.length])) return null;
11755
+ if (!_optionalChain([subpaths, 'optionalAccess', _379 => _379.length])) return null;
11730
11756
  const parse = (v2) => {
11731
11757
  try {
11732
11758
  return v2 ? JSON.parse(v2) : [];
@@ -11745,7 +11771,7 @@ function parseVectorSvg(svg, options = {}) {
11745
11771
  const key = (n) => JSON.stringify([n.subpaths, _nullishCoalesce(n.transform, () => ( null)), _nullishCoalesce(n.opacity, () => ( 1)), n.visible !== false, _nullishCoalesce(n.filters, () => ( null)), _nullishCoalesce(n.blendMode, () => ( "normal")), _nullishCoalesce(n.fillRule, () => ( "nonzero")), _nullishCoalesce(n.booleanOperation, () => ( null))]);
11746
11772
  for (const n of nodes2) {
11747
11773
  const prev = out[out.length - 1];
11748
- if (_optionalChain([prev, 'optionalAccess', _376 => _376.type]) === "path" && n.type === "path" && key(prev) === key(n)) {
11774
+ if (_optionalChain([prev, 'optionalAccess', _380 => _380.type]) === "path" && n.type === "path" && key(prev) === key(n)) {
11749
11775
  const fills = vectorFills(n);
11750
11776
  const strokesBefore = vectorStrokes(prev);
11751
11777
  if (!(fills.length && strokesBefore.length)) {
@@ -11763,7 +11789,7 @@ function parseVectorSvg(svg, options = {}) {
11763
11789
  const part = (name) => g.children.find((c) => c.name === "path" && c.attrs["data-vector-part"] === name);
11764
11790
  const fillEl = part("fill");
11765
11791
  const subpaths = fillEl ? shapeOf(fillEl) : null;
11766
- if (!fillEl || !_optionalChain([subpaths, 'optionalAccess', _377 => _377.length])) return null;
11792
+ if (!fillEl || !_optionalChain([subpaths, 'optionalAccess', _381 => _381.length])) return null;
11767
11793
  const a = g.attrs;
11768
11794
  const fs = readStyle(fillEl, style, styleRules);
11769
11795
  const strokeEl = part("stroke");
@@ -11800,7 +11826,7 @@ function parseVectorSvg(svg, options = {}) {
11800
11826
  ...profile.length ? { strokeWidthProfile: profile } : {},
11801
11827
  ...keptCap ? { strokeLinecap: keptCap } : {},
11802
11828
  ...keptJoin ? { strokeLinejoin: keptJoin } : {},
11803
- ..._optionalChain([keptDash, 'optionalAccess', _378 => _378.length]) ? { strokeDasharray: keptDash } : {}
11829
+ ..._optionalChain([keptDash, 'optionalAccess', _382 => _382.length]) ? { strokeDasharray: keptDash } : {}
11804
11830
  };
11805
11831
  return placed(node, m);
11806
11832
  };
@@ -11865,8 +11891,8 @@ function parseVectorSvg(svg, options = {}) {
11865
11891
  } else {
11866
11892
  const fill = json2(g.attrs["data-vector-fill"]);
11867
11893
  const stroke = json2(g.attrs["data-vector-stroke"]);
11868
- node.fill = fill == null ? null : _nullishCoalesce(_optionalChain([sanitizeVectorFills, 'call', _379 => _379([{ paint: fill }]), 'access', _380 => _380[0], 'optionalAccess', _381 => _381.paint]), () => ( null));
11869
- node.stroke = stroke == null ? null : _nullishCoalesce(_optionalChain([sanitizeVectorFills, 'call', _382 => _382([{ paint: stroke }]), 'access', _383 => _383[0], 'optionalAccess', _384 => _384.paint]), () => ( null));
11894
+ node.fill = fill == null ? null : _nullishCoalesce(_optionalChain([sanitizeVectorFills, 'call', _383 => _383([{ paint: fill }]), 'access', _384 => _384[0], 'optionalAccess', _385 => _385.paint]), () => ( null));
11895
+ node.stroke = stroke == null ? null : _nullishCoalesce(_optionalChain([sanitizeVectorFills, 'call', _386 => _386([{ paint: stroke }]), 'access', _387 => _387[0], 'optionalAccess', _388 => _388.paint]), () => ( null));
11870
11896
  const settings = json2(g.attrs["data-vector-stroke-settings"]);
11871
11897
  if (settings && typeof settings === "object") {
11872
11898
  const strokes = sanitizeVectorStrokes([{ paint: _nullishCoalesce(node.stroke, () => ( "#000")), ...settings }]);
@@ -11902,8 +11928,8 @@ function parseVectorSvg(svg, options = {}) {
11902
11928
  const anchor = attrOrStyle(el, "text-anchor");
11903
11929
  const first0 = (v2) => _nullishCoalesce(numberList(v2)[0], () => ( 0));
11904
11930
  const tspan = el.children.find((c) => c.name === "tspan");
11905
- const x = el.attrs.x !== void 0 ? first0(el.attrs.x) : first0(_optionalChain([tspan, 'optionalAccess', _385 => _385.attrs, 'access', _386 => _386.x]));
11906
- const y = el.attrs.y !== void 0 ? first0(el.attrs.y) : first0(_optionalChain([tspan, 'optionalAccess', _387 => _387.attrs, 'access', _388 => _388.y]));
11931
+ const x = el.attrs.x !== void 0 ? first0(el.attrs.x) : first0(_optionalChain([tspan, 'optionalAccess', _389 => _389.attrs, 'access', _390 => _390.x]));
11932
+ const y = el.attrs.y !== void 0 ? first0(el.attrs.y) : first0(_optionalChain([tspan, 'optionalAccess', _391 => _391.attrs, 'access', _392 => _392.y]));
11907
11933
  const fillValue = _nullishCoalesce(attrOrStyle(el, "fill"), () => ( style.fill));
11908
11934
  let node = {
11909
11935
  id: idFor(el),
@@ -11934,12 +11960,12 @@ function parseVectorSvg(svg, options = {}) {
11934
11960
  if (symbolOfElement.has(el)) return symbolOfElement.get(el);
11935
11961
  symbolOfElement.set(el, null);
11936
11962
  const own = json2(el.attrs["data-vector-symbol"]);
11937
- let id = typeof _optionalChain([own, 'optionalAccess', _389 => _389.id]) === "string" && own.id ? own.id : _nullishCoalesce(el.attrs.id, () => ( createId()));
11963
+ let id = typeof _optionalChain([own, 'optionalAccess', _393 => _393.id]) === "string" && own.id ? own.id : _nullishCoalesce(el.attrs.id, () => ( createId()));
11938
11964
  while (usedSymbolIds.has(id)) id = `${id}-${usedSymbolIds.size}`;
11939
11965
  usedSymbolIds.add(id);
11940
11966
  const style = readStyle(el, rootStyle, styleRules);
11941
11967
  const nodes2 = el.name === "symbol" ? visit2(el, style, IDENTITY_MATRIX) : visitOne({ ...el, attrs: { ...el.attrs, transform: "" } }, rootStyle, parseSvgTransform(el.attrs.transform));
11942
- symbols.push({ id, name: typeof _optionalChain([own, 'optionalAccess', _390 => _390.name]) === "string" && own.name ? own.name : _nullishCoalesce(el.attrs.id, () => ( "Symbol")), nodes: nodes2 });
11968
+ symbols.push({ id, name: typeof _optionalChain([own, 'optionalAccess', _394 => _394.name]) === "string" && own.name ? own.name : _nullishCoalesce(el.attrs.id, () => ( "Symbol")), nodes: nodes2 });
11943
11969
  symbolOfElement.set(el, id);
11944
11970
  return id;
11945
11971
  };
@@ -11951,13 +11977,13 @@ function parseVectorSvg(svg, options = {}) {
11951
11977
  if (!symbolId) return null;
11952
11978
  const own = json2(el.attrs["data-vector-instance"]);
11953
11979
  const place3 = multiplyMatrices(translateMatrix(length(el.attrs.x), length(el.attrs.y)), m);
11954
- const node = { id: idFor(el), type: "instance", ...meta, symbolId, ..._optionalChain([own, 'optionalAccess', _391 => _391.scaleStrokes]) === false ? { scaleStrokes: false } : {}, ..._optionalChain([own, 'optionalAccess', _392 => _392.overrides]) ? { overrides: own.overrides } : {} };
11980
+ const node = { id: idFor(el), type: "instance", ...meta, symbolId, ..._optionalChain([own, 'optionalAccess', _395 => _395.scaleStrokes]) === false ? { scaleStrokes: false } : {}, ..._optionalChain([own, 'optionalAccess', _396 => _396.overrides]) ? { overrides: own.overrides } : {} };
11955
11981
  return isIdentityMatrix(place3) ? node : { ...node, transform: place3 };
11956
11982
  };
11957
11983
  const ownInstance = (g, m, meta) => {
11958
11984
  const raw = json2(g.attrs["data-vector-instance"]);
11959
11985
  if (!raw || typeof raw.symbolId !== "string") return null;
11960
- const sym2 = [...byId.values()].find((e) => e.name === "symbol" && _optionalChain([json2, 'call', _393 => _393(e.attrs["data-vector-symbol"]), 'optionalAccess', _394 => _394.id]) === raw.symbolId);
11986
+ const sym2 = [...byId.values()].find((e) => e.name === "symbol" && _optionalChain([json2, 'call', _397 => _397(e.attrs["data-vector-symbol"]), 'optionalAccess', _398 => _398.id]) === raw.symbolId);
11961
11987
  const symbolId = sym2 ? symbolFor(sym2) : raw.symbolId;
11962
11988
  if (!symbolId) return null;
11963
11989
  const t = Array.isArray(raw.transform) && raw.transform.length === 6 && raw.transform.every(Number.isFinite) ? raw.transform : IDENTITY_MATRIX;
@@ -11965,7 +11991,7 @@ function parseVectorSvg(svg, options = {}) {
11965
11991
  const drawn = g.children.find((c) => c.name === "g");
11966
11992
  const effects = sanitizeVectorEffects(raw.effects);
11967
11993
  const node = {
11968
- id: _nullishCoalesce(_optionalChain([drawn, 'optionalAccess', _395 => _395.attrs, 'access', _396 => _396.id]), () => ( idFor(g))),
11994
+ id: _nullishCoalesce(_optionalChain([drawn, 'optionalAccess', _399 => _399.attrs, 'access', _400 => _400.id]), () => ( idFor(g))),
11969
11995
  type: "instance",
11970
11996
  ...meta,
11971
11997
  symbolId,
@@ -12022,12 +12048,12 @@ function parseVectorSvg(svg, options = {}) {
12022
12048
  const masked = (el, nodes2, m) => {
12023
12049
  let out = nodes2;
12024
12050
  const clipEl = rawMasks.get(_nullishCoalesce(urlId(attrOrStyle(el, "clip-path")), () => ( "")));
12025
- if (_optionalChain([clipEl, 'optionalAccess', _397 => _397.name]) === "clipPath") {
12051
+ if (_optionalChain([clipEl, 'optionalAccess', _401 => _401.name]) === "clipPath") {
12026
12052
  const source = maskNode(clipEl, m, out, clipEl.attrs.clipPathUnits);
12027
12053
  if (source) out = [{ id: idFor({ name: "g", attrs: {}, children: [] }), type: "group", name: "Clip Group", mask: { type: "clip" }, children: [source, ...out] }];
12028
12054
  }
12029
12055
  const maskEl = rawMasks.get(_nullishCoalesce(urlId(attrOrStyle(el, "mask")), () => ( "")));
12030
- if (_optionalChain([maskEl, 'optionalAccess', _398 => _398.name]) === "mask") {
12056
+ if (_optionalChain([maskEl, 'optionalAccess', _402 => _402.name]) === "mask") {
12031
12057
  const source = maskNode(maskEl, m, out, maskEl.attrs.maskContentUnits);
12032
12058
  const type = attrOrStyle(maskEl, "mask-type") === "alpha" ? "alpha" : "luminance";
12033
12059
  if (source) out = [{ id: idFor({ name: "g", attrs: {}, children: [] }), type: "group", name: "Opacity Mask", mask: { type }, children: [source, ...out] }];
@@ -12049,19 +12075,19 @@ function parseVectorSvg(svg, options = {}) {
12049
12075
  let sourceEl = part("mask-source");
12050
12076
  if (!sourceEl) {
12051
12077
  const el = rawMasks.get(_nullishCoalesce(urlId(maskedEl.attrs.mask), () => ( "")));
12052
- const invert2 = _optionalChain([el, 'optionalAccess', _399 => _399.children, 'access', _400 => _400.find, 'call', _401 => _401((c) => c.name === "g" && c.attrs["data-vector-part"] === "mask-invert")]);
12078
+ const invert2 = _optionalChain([el, 'optionalAccess', _403 => _403.children, 'access', _404 => _404.find, 'call', _405 => _405((c) => c.name === "g" && c.attrs["data-vector-part"] === "mask-invert")]);
12053
12079
  sourceEl = _nullishCoalesce(invert2, () => ( el));
12054
12080
  }
12055
12081
  const source = sourceEl ? visit2(sourceEl, style, m)[0] : void 0;
12056
12082
  let contents = visit2(maskedEl, style, m);
12057
12083
  let effects;
12058
12084
  const wrapper = contents.length === 1 && contents[0].type === "group" && contents[0].id === `${id}~content` ? contents[0] : null;
12059
- if (_optionalChain([wrapper, 'optionalAccess', _402 => _402.type]) === "group") {
12085
+ if (_optionalChain([wrapper, 'optionalAccess', _406 => _406.type]) === "group") {
12060
12086
  effects = _nullishCoalesce(wrapper.effects, () => ( void 0));
12061
12087
  contents = wrapper.children;
12062
12088
  }
12063
12089
  if (!source) return contents.length ? { id, type: "group", ...meta, children: contents } : null;
12064
- return { id, type: "group", ...meta, mask, ..._optionalChain([effects, 'optionalAccess', _403 => _403.length]) ? { effects } : {}, children: [source, ...contents] };
12090
+ return { id, type: "group", ...meta, mask, ..._optionalChain([effects, 'optionalAccess', _407 => _407.length]) ? { effects } : {}, children: [source, ...contents] };
12065
12091
  };
12066
12092
  const frameGroup = (g, style, m, meta) => {
12067
12093
  const raw = parseJson(g.attrs["data-vector-frame"]);
@@ -12073,7 +12099,7 @@ function parseVectorSvg(svg, options = {}) {
12073
12099
  const { rigid, residual } = decomposeRigid(m);
12074
12100
  const r = _chunkGF2RBSDMcjs.bezierPathBounds.call(void 0, _chunkGF2RBSDMcjs.transformBezierPath.call(void 0, subpathsToBezier(vectorFrameRectPath(frame)), residual));
12075
12101
  const back = invertMatrix(rigid);
12076
- const effects = sanitizeVectorEffects(_optionalChain([raw, 'optionalAccess', _404 => _404.effects]));
12102
+ const effects = sanitizeVectorEffects(_optionalChain([raw, 'optionalAccess', _408 => _408.effects]));
12077
12103
  return {
12078
12104
  id,
12079
12105
  type: "group",
@@ -12545,13 +12571,13 @@ function hitTestVectorNode(node, p, tolerance = 0, parent = IDENTITY_MATRIX, opt
12545
12571
  }
12546
12572
  if (isVectorMaskGroup(node)) {
12547
12573
  const m = multiplyMatrices(nodeMatrix(node), parent);
12548
- const entered = !!_optionalChain([options, 'access', _405 => _405.entered, 'optionalAccess', _406 => _406.has, 'call', _407 => _407(node.id)]);
12574
+ const entered = !!_optionalChain([options, 'access', _409 => _409.entered, 'optionalAccess', _410 => _410.has, 'call', _411 => _411(node.id)]);
12549
12575
  if (!entered && isVectorMaskActive(node) && !vectorMaskContains(node, applyMatrix(invertMatrix(m), p), tolerance)) return false;
12550
12576
  const shown = !entered && hasOwnVectorAppearance(node) ? expandVectorAppearance(node).children : node.children;
12551
12577
  for (let i = shown.length - 1; i >= 1; i--) if (hitTestVectorNode(shown[i], p, tolerance, m, options)) return true;
12552
12578
  return entered && hitTestVectorMaskSource(node, p, tolerance, m, options);
12553
12579
  }
12554
- if (!(node.type === "group" && (!hasOwnVectorAppearance(node) || _optionalChain([options, 'access', _408 => _408.entered, 'optionalAccess', _409 => _409.has, 'call', _410 => _410(node.id)])))) node = expandVectorAppearance(node);
12580
+ if (!(node.type === "group" && (!hasOwnVectorAppearance(node) || _optionalChain([options, 'access', _412 => _412.entered, 'optionalAccess', _413 => _413.has, 'call', _414 => _414(node.id)])))) node = expandVectorAppearance(node);
12555
12581
  if (node.type === "group") {
12556
12582
  const m = multiplyMatrices(nodeMatrix(node), parent);
12557
12583
  return node.children.some((c) => hitTestVectorNode(c, p, tolerance, m, options));
@@ -12563,7 +12589,7 @@ function hitTestVectorNode(node, p, tolerance = 0, parent = IDENTITY_MATRIX, opt
12563
12589
  function hitTestVectorMaskSource(group, p, tolerance, m, options) {
12564
12590
  const source = group.children[0];
12565
12591
  if (source.visible === false) return false;
12566
- if (_optionalChain([group, 'access', _411 => _411.mask, 'optionalAccess', _412 => _412.type]) !== "clip") return hitTestVectorNode(source, p, tolerance, m, options);
12592
+ if (_optionalChain([group, 'access', _415 => _415.mask, 'optionalAccess', _416 => _416.type]) !== "clip") return hitTestVectorNode(source, p, tolerance, m, options);
12567
12593
  const paths = collectPathNodes(source).filter((n) => n.visible !== false);
12568
12594
  const pt2 = [p.x, p.y];
12569
12595
  return paths.some((n) => {
@@ -12612,24 +12638,24 @@ function mapAnchor(a, m) {
12612
12638
  }
12613
12639
  function bakeIntoGeometry(node, m) {
12614
12640
  if (isIdentityMatrix(m)) return node;
12615
- if (_optionalChain([node, 'access', _413 => _413.effects, 'optionalAccess', _414 => _414.length])) node = { ...node, effects: transformVectorEffects(node.effects, m, node) };
12641
+ if (_optionalChain([node, 'access', _417 => _417.effects, 'optionalAccess', _418 => _418.length])) node = { ...node, effects: transformVectorEffects(node.effects, m, node) };
12616
12642
  if (isVectorFrame(node)) return bakeFrame(node, m);
12617
12643
  if (node.type === "group") {
12618
12644
  const group = node;
12619
12645
  const children = group.children.map((c) => transformVectorNode(c, m));
12620
12646
  const sym2 = group.symmetry ? { symmetry: transformVectorSymmetry(group.symmetry, m) } : {};
12621
- const spine = _optionalChain([group, 'access', _415 => _415.blend, 'optionalAccess', _416 => _416.spine]);
12647
+ const spine = _optionalChain([group, 'access', _419 => _419.blend, 'optionalAccess', _420 => _420.spine]);
12622
12648
  if (!spine) return { ...group, ...sym2, children };
12623
12649
  const moved = { closed: spine.closed, anchors: spine.anchors.map((a) => mapAnchor(a, m)) };
12624
12650
  return { ...group, children, blend: { ...group.blend, spine: moved } };
12625
12651
  }
12626
12652
  const path = node.type === "text" ? bakeVectorTextGeometry(node, m) : node;
12627
12653
  const flips = m[0] * m[3] - m[1] * m[2] < 0;
12628
- const mirrored = flips && _optionalChain([path, 'access', _417 => _417.strokeWidthProfile, 'optionalAccess', _418 => _418.length]);
12654
+ const mirrored = flips && _optionalChain([path, 'access', _421 => _421.strokeWidthProfile, 'optionalAccess', _422 => _422.length]);
12629
12655
  const layer = (l) => ({
12630
12656
  ...l,
12631
12657
  ...isVectorGradient(l.paint) || isVectorShadedPaint(l.paint) ? { paint: transformVectorPaint(l.paint, m) } : {},
12632
- ...flips && _optionalChain([l, 'access', _419 => _419.strokeWidthProfile, 'optionalAccess', _420 => _420.length]) ? { strokeWidthProfile: mirrorWidthProfile(l.strokeWidthProfile) } : {}
12658
+ ...flips && _optionalChain([l, 'access', _423 => _423.strokeWidthProfile, 'optionalAccess', _424 => _424.length]) ? { strokeWidthProfile: mirrorWidthProfile(l.strokeWidthProfile) } : {}
12633
12659
  });
12634
12660
  return {
12635
12661
  ...path,
@@ -12864,7 +12890,7 @@ function roundSubpaths(subpaths, precision = 3) {
12864
12890
 
12865
12891
  // src/vector/symmetry.ts
12866
12892
  function isVectorSymmetryGroup(node) {
12867
- return _optionalChain([node, 'optionalAccess', _421 => _421.type]) === "group" && !!node.symmetry && !node.blend && !node.liveBoolean && !node.mask && !node.frame;
12893
+ return _optionalChain([node, 'optionalAccess', _425 => _425.type]) === "group" && !!node.symmetry && !node.blend && !node.liveBoolean && !node.mask && !node.frame;
12868
12894
  }
12869
12895
  var rad = (deg) => deg * Math.PI / 180;
12870
12896
  var exact = (v2) => Math.abs(v2) < 1e-12 ? 0 : v2;