@pixerate/editor 0.38.0 → 0.39.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -36,7 +36,9 @@ var _chunkQKLRAA4Tcjs = require('../chunk-QKLRAA4T.cjs');
36
36
 
37
37
 
38
38
 
39
- var _chunk7EDLVBOOcjs = require('../chunk-7EDLVBOO.cjs');
39
+
40
+
41
+ var _chunkVNYRI265cjs = require('../chunk-VNYRI265.cjs');
40
42
 
41
43
  // src/vector/types.ts
42
44
  var VECTOR_CORNER_KINDS = ["round", "inverted", "chamfer"];
@@ -80,7 +82,7 @@ var Side = class {
80
82
  constructor(a, h1, h2, b) {
81
83
  this.straight = onAnchor(a, h1) && onAnchor(b, h2);
82
84
  this.curve = this.straight ? [pt(a), pt(b)] : [pt(a), pt(_nullishCoalesce(h1, () => ( a))), pt(_nullishCoalesce(h2, () => ( b))), pt(b)];
83
- this.length = this.straight ? Math.hypot(b.x - a.x, b.y - a.y) : _chunk7EDLVBOOcjs.segmentLength.call(void 0, this.curve);
85
+ this.length = this.straight ? Math.hypot(b.x - a.x, b.y - a.y) : _chunkVNYRI265cjs.segmentLength.call(void 0, this.curve);
84
86
  }
85
87
  /** Unit direction the side leaves the corner in (towards its first control point off the corner). */
86
88
  direction() {
@@ -98,10 +100,10 @@ var Side = class {
98
100
  const t2 = this.length > EPS ? Math.min(1, Math.max(0, s / this.length)) : 0;
99
101
  return { t: t2, p: add(vec(this.curve[0]), mul(u, s)), dir: u };
100
102
  }
101
- const t = _chunk7EDLVBOOcjs.segmentParamAtLength.call(void 0, this.curve, s, this.length);
102
- const d = vec(_chunk7EDLVBOOcjs.segmentDerivative.call(void 0, this.curve, t));
103
+ const t = _chunkVNYRI265cjs.segmentParamAtLength.call(void 0, this.curve, s, this.length);
104
+ const d = vec(_chunkVNYRI265cjs.segmentDerivative.call(void 0, this.curve, t));
103
105
  const l = len(d);
104
- return { t, p: vec(_chunk7EDLVBOOcjs.segmentPoint.call(void 0, this.curve, t)), dir: l > EPS ? mul(d, 1 / l) : u };
106
+ return { t, p: vec(_chunkVNYRI265cjs.segmentPoint.call(void 0, this.curve, t)), dir: l > EPS ? mul(d, 1 / l) : u };
105
107
  }
106
108
  };
107
109
  function cornerOf(sp, s, i) {
@@ -174,7 +176,7 @@ function cutCorner(c, radius, kind) {
174
176
  return { tu: a.t, tv: b.t, start: a.p, out: add(a.p, mul(d1, k)), in: add(b.p, mul(d2, k)), end: b.p };
175
177
  }
176
178
  var radiusOf = (a) => {
177
- const r = _optionalChain([a, 'access', _3 => _3.corner, 'optionalAccess', _4 => _4.radius]);
179
+ const r = _optionalChain([a, 'access', _2 => _2.corner, 'optionalAccess', _3 => _3.radius]);
178
180
  return typeof r === "number" && r > 0 && Number.isFinite(r) ? r : 0;
179
181
  };
180
182
  function hasVectorCorners(subpaths) {
@@ -188,7 +190,7 @@ function expandVectorCornersOf(sp, subpath = 0) {
188
190
  const c = cornerOf(sp, subpath, i);
189
191
  if (!c) return null;
190
192
  const fitted = fitCornerRadius(c, r);
191
- return fitted > EPS ? cutCorner(c, fitted, _nullishCoalesce(_optionalChain([a, 'access', _5 => _5.corner, 'optionalAccess', _6 => _6.kind]), () => ( "round"))) : null;
193
+ return fitted > EPS ? cutCorner(c, fitted, _nullishCoalesce(_optionalChain([a, 'access', _4 => _4.corner, 'optionalAccess', _5 => _5.kind]), () => ( "round"))) : null;
192
194
  });
193
195
  if (!cuts.some(Boolean)) return { subpath: { closed: sp.closed, anchors: sp.anchors.map(plain) }, sources: sp.anchors.map((_, i) => i) };
194
196
  const trimmed = sp.anchors.map((a, j) => {
@@ -202,7 +204,7 @@ function expandVectorCornersOf(sp, subpath = 0) {
202
204
  const s0 = from ? from.tv : 0;
203
205
  const s1 = to ? 1 - to.tu : 1;
204
206
  const seg = [pt(a), pt(_nullishCoalesce(a.out, () => ( a))), pt(_nullishCoalesce(b.in, () => ( b))), pt(b)];
205
- const part = _chunk7EDLVBOOcjs.subSegment.call(void 0, seg, s0, Math.max(s0, s1));
207
+ const part = _chunkVNYRI265cjs.subSegment.call(void 0, seg, s0, Math.max(s0, s1));
206
208
  return { out: vec(part[1]), in: vec(part[2]) };
207
209
  });
208
210
  const anchors = [];
@@ -256,7 +258,7 @@ function expandVectorCorners(subpaths) {
256
258
  function setAnchorCorner(a, radius, kind) {
257
259
  const { corner, ...rest } = a;
258
260
  const r = Number.isFinite(radius) ? Math.max(0, radius) : 0;
259
- const k = _nullishCoalesce(kind, () => ( _optionalChain([corner, 'optionalAccess', _7 => _7.kind])));
261
+ const k = _nullishCoalesce(kind, () => ( _optionalChain([corner, 'optionalAccess', _6 => _6.kind])));
260
262
  if (r <= 0 && !kind) return rest;
261
263
  return { ...rest, corner: { radius: r, ...k && k !== "round" ? { kind: k } : {} } };
262
264
  }
@@ -305,7 +307,7 @@ function sanitizeWidthProfile(points) {
305
307
  return out.map((p, i) => [p, i]).sort((a, b) => a[0].t - b[0].t || a[1] - b[1]).map(([p]) => p);
306
308
  }
307
309
  function isUniformWidthProfile(points) {
308
- return !_optionalChain([points, 'optionalAccess', _8 => _8.length]) || points.every((p) => p.left === 1 && p.right === 1);
310
+ return !_optionalChain([points, 'optionalAccess', _7 => _7.length]) || points.every((p) => p.left === 1 && p.right === 1);
309
311
  }
310
312
  function secant(pts, i, k) {
311
313
  const a = pts[i];
@@ -338,11 +340,11 @@ function interp(pts, t, k) {
338
340
  return Math.max(0, w);
339
341
  }
340
342
  function widthProfileAt(points, t) {
341
- if (!_optionalChain([points, 'optionalAccess', _9 => _9.length])) return { left: 1, right: 1 };
343
+ if (!_optionalChain([points, 'optionalAccess', _8 => _8.length])) return { left: 1, right: 1 };
342
344
  return { left: interp(points, t, "left"), right: interp(points, t, "right") };
343
345
  }
344
346
  function widthProfileMaxScale(points) {
345
- if (!_optionalChain([points, 'optionalAccess', _10 => _10.length])) return 1;
347
+ if (!_optionalChain([points, 'optionalAccess', _9 => _9.length])) return 1;
346
348
  return points.reduce((m, p) => Math.max(m, p.left, p.right), 0);
347
349
  }
348
350
  function widthProfilePreset(id) {
@@ -352,7 +354,7 @@ function widthProfilePreset(id) {
352
354
  function widthProfilePresetId(points) {
353
355
  if (isUniformWidthProfile(points)) return "uniform";
354
356
  const same = (a, b) => a.length === b.length && a.every((p, i) => Math.abs(p.t - b[i].t) < 1e-9 && Math.abs(p.left - b[i].left) < 1e-9 && Math.abs(p.right - b[i].right) < 1e-9);
355
- return _nullishCoalesce(_optionalChain([VECTOR_WIDTH_PRESETS, 'access', _11 => _11.find, 'call', _12 => _12((p) => p.points.length && same(points, p.points)), 'optionalAccess', _13 => _13.id]), () => ( "custom"));
357
+ return _nullishCoalesce(_optionalChain([VECTOR_WIDTH_PRESETS, 'access', _10 => _10.find, 'call', _11 => _11((p) => p.points.length && same(points, p.points)), 'optionalAccess', _12 => _12.id]), () => ( "custom"));
356
358
  }
357
359
  function reverseWidthProfile(points) {
358
360
  return points.map((p) => ({ t: 1 - p.t, left: p.right, right: p.left })).reverse();
@@ -361,12 +363,12 @@ function mirrorWidthProfile(points) {
361
363
  return points.map((p) => ({ t: p.t, left: p.right, right: p.left }));
362
364
  }
363
365
  function editable(points) {
364
- return _optionalChain([points, 'optionalAccess', _14 => _14.length]) ? points.map((p) => ({ ...p })) : [sym(0, 1), sym(1, 1)];
366
+ return _optionalChain([points, 'optionalAccess', _13 => _13.length]) ? points.map((p) => ({ ...p })) : [sym(0, 1), sym(1, 1)];
365
367
  }
366
368
  function insertWidthPoint(points, t, sides2 = {}, options = {}) {
367
369
  const pts = editable(points);
368
370
  const tt = Math.min(Math.max(Number.isFinite(t) ? t : 0, 0), 1);
369
- const here = widthProfileAt(_optionalChain([points, 'optionalAccess', _15 => _15.length]) ? points : null, tt);
371
+ const here = widthProfileAt(_optionalChain([points, 'optionalAccess', _14 => _14.length]) ? points : null, tt);
370
372
  const p = {
371
373
  t: tt,
372
374
  left: _nullishCoalesce(clean(sides2.left, VECTOR_WIDTH_PROFILE_MAX_SCALE), () => ( here.left)),
@@ -437,7 +439,7 @@ function generateWidthProfile(options) {
437
439
  const n = Math.max(8, Math.min(VECTOR_WIDTH_PROFILE_MAX_POINTS * 4, _nullishCoalesce(options.samples, () => ( Math.ceil(32 + cycles * 16)))));
438
440
  const raw = [];
439
441
  for (let i = 0; i <= n; i++) raw.push([i / n, taperWaveFactor(i / n, options.taper, options.wave)]);
440
- const ts = [_optionalChain([options, 'access', _16 => _16.taper, 'optionalAccess', _17 => _17.startLength]), _optionalChain([options, 'access', _18 => _18.taper, 'optionalAccess', _19 => _19.endLength]) !== void 0 ? 1 - options.taper.endLength : void 0];
442
+ const ts = [_optionalChain([options, 'access', _15 => _15.taper, 'optionalAccess', _16 => _16.startLength]), _optionalChain([options, 'access', _17 => _17.taper, 'optionalAccess', _18 => _18.endLength]) !== void 0 ? 1 - options.taper.endLength : void 0];
441
443
  for (const t of ts) if (typeof t === "number" && t > 0 && t < 1) raw.push([t, taperWaveFactor(t, options.taper, options.wave)]);
442
444
  raw.sort((a, b) => a[0] - b[0]);
443
445
  const kept = simplifySamples(raw, _nullishCoalesce(options.tolerance, () => ( 0.01)), VECTOR_WIDTH_PROFILE_MAX_POINTS);
@@ -505,7 +507,7 @@ function flatten(segments, closed, tol) {
505
507
  corner.push(isCorner);
506
508
  };
507
509
  for (const seg of segments) {
508
- const flat = _chunk7EDLVBOOcjs.flattenChain.call(void 0, [seg], tol);
510
+ const flat = _chunkVNYRI265cjs.flattenChain.call(void 0, [seg], tol);
509
511
  if (dist(seg[0], seg[seg.length - 1]) <= 1e-12 && flat.length > 1) flat.push(seg[seg.length - 1]);
510
512
  flat.forEach((p, i) => push(p, i === 0 || i === flat.length - 1));
511
513
  }
@@ -595,7 +597,7 @@ function variableStrokeRings(path, options) {
595
597
  const last = out[out.length - 1];
596
598
  if (!last || dist(last, p) > 1e-12) out.push(p);
597
599
  };
598
- for (const contour of _chunk7EDLVBOOcjs.pathToContours.call(void 0, path)) {
600
+ for (const contour of _chunkVNYRI265cjs.pathToContours.call(void 0, path)) {
599
601
  if (!contour.segments.length) continue;
600
602
  const poly = flatten(contour.segments, contour.closed, Math.min(tol, half) / 4);
601
603
  if (!poly) continue;
@@ -604,7 +606,7 @@ function variableStrokeRings(path, options) {
604
606
  const w = widthProfileAt(options.profile, s / len2);
605
607
  return [w.left * half, w.right * half];
606
608
  };
607
- const intervals = _optionalChain([options, 'access', _20 => _20.dash, 'optionalAccess', _21 => _21.some, 'call', _22 => _22((v2) => v2 > 0)]) ? dashIntervals(options.dash, _nullishCoalesce(options.dashOffset, () => ( 0)), len2) : [[0, len2]];
609
+ const intervals = _optionalChain([options, 'access', _19 => _19.dash, 'optionalAccess', _20 => _20.some, 'call', _21 => _21((v2) => v2 > 0)]) ? dashIntervals(options.dash, _nullishCoalesce(options.dashOffset, () => ( 0)), len2) : [[0, len2]];
608
610
  const whole = intervals.length === 1 && intervals[0][0] <= 0 && intervals[0][1] >= len2;
609
611
  for (const [a, b] of intervals) {
610
612
  const [pa, ia] = at(poly, a);
@@ -721,7 +723,7 @@ function variableStrokeOutline(path, options) {
721
723
  const tol = options.tolerance && options.tolerance > 0 ? options.tolerance : 0.05;
722
724
  let polygons;
723
725
  try {
724
- polygons = _chunk7EDLVBOOcjs.polygonBoolean.call(void 0, "union", [{ rings: pieces, fillRule: "nonzero" }]);
726
+ polygons = _chunkVNYRI265cjs.polygonBoolean.call(void 0, "union", [{ rings: pieces, fillRule: "nonzero" }]);
725
727
  } catch (e2) {
726
728
  return [];
727
729
  }
@@ -729,11 +731,11 @@ function variableStrokeOutline(path, options) {
729
731
  for (const polygon2 of polygons) {
730
732
  for (const ring of polygon2) {
731
733
  if (ring.length < 3) continue;
732
- const cubics = _chunk7EDLVBOOcjs.fitCubics.call(void 0, ring, tol, { closed: true, cornerAngleDeg: 25 });
734
+ const cubics = _chunkVNYRI265cjs.fitCubics.call(void 0, ring, tol, { closed: true, cornerAngleDeg: 25 });
733
735
  if (!cubics.length) continue;
734
736
  out.push({ type: "M", x: cubics[0].p0[0], y: cubics[0].p0[1] });
735
737
  cubics.forEach((c, i) => {
736
- if (_chunk7EDLVBOOcjs.isStraightCubic.call(void 0, c, tol * 0.02)) {
738
+ if (_chunkVNYRI265cjs.isStraightCubic.call(void 0, c, tol * 0.02)) {
737
739
  if (i < cubics.length - 1) out.push({ type: "L", x: c.p3[0], y: c.p3[1] });
738
740
  } else out.push({ type: "C", x1: c.p1[0], y1: c.p1[1], x2: c.p2[0], y2: c.p2[1], x: c.p3[0], y: c.p3[1] });
739
741
  });
@@ -744,17 +746,17 @@ function variableStrokeOutline(path, options) {
744
746
  }
745
747
  function nearestStrokePosition(path, p, only) {
746
748
  let best = null;
747
- _chunk7EDLVBOOcjs.pathToContours.call(void 0, path).forEach((c, ci) => {
749
+ _chunkVNYRI265cjs.pathToContours.call(void 0, path).forEach((c, ci) => {
748
750
  if (!c.segments.length || only !== void 0 && ci !== only) return;
749
- const lengths = c.segments.map((s) => _chunk7EDLVBOOcjs.segmentLength.call(void 0, s));
751
+ const lengths = c.segments.map((s) => _chunkVNYRI265cjs.segmentLength.call(void 0, s));
750
752
  const total = lengths.reduce((a, b) => a + b, 0);
751
753
  if (!(total > 0)) return;
752
754
  let acc = 0;
753
755
  c.segments.forEach((seg, si) => {
754
- const near2 = _chunk7EDLVBOOcjs.segmentNearest.call(void 0, seg, p);
756
+ const near2 = _chunkVNYRI265cjs.segmentNearest.call(void 0, seg, p);
755
757
  if (!best || near2.distance < best.distance) {
756
- const s = acc + _chunk7EDLVBOOcjs.segmentLength.call(void 0, seg, 0, near2.t);
757
- const tan = _chunk7EDLVBOOcjs.segmentTangent.call(void 0, seg, near2.t);
758
+ const s = acc + _chunkVNYRI265cjs.segmentLength.call(void 0, seg, 0, near2.t);
759
+ const tan = _chunkVNYRI265cjs.segmentTangent.call(void 0, seg, near2.t);
758
760
  const pt2 = seg.length === 2 ? lerp(seg[0], seg[1], near2.t) : evalSeg(seg, near2.t);
759
761
  const n = leftNormal([tan[0], tan[1]]);
760
762
  const side = (p[0] - pt2[0]) * n[0] + (p[1] - pt2[1]) * n[1] >= 0 ? "left" : "right";
@@ -771,9 +773,9 @@ function evalSeg(seg, t) {
771
773
  return pts[0];
772
774
  }
773
775
  function strokePositionPoint(path, index, t) {
774
- const c = _chunk7EDLVBOOcjs.pathToContours.call(void 0, path)[index];
775
- if (!_optionalChain([c, 'optionalAccess', _23 => _23.segments, 'access', _24 => _24.length])) return null;
776
- const lengths = c.segments.map((s) => _chunk7EDLVBOOcjs.segmentLength.call(void 0, s));
776
+ const c = _chunkVNYRI265cjs.pathToContours.call(void 0, path)[index];
777
+ if (!_optionalChain([c, 'optionalAccess', _22 => _22.segments, 'access', _23 => _23.length])) return null;
778
+ const lengths = c.segments.map((s) => _chunkVNYRI265cjs.segmentLength.call(void 0, s));
777
779
  const total = lengths.reduce((a, b) => a + b, 0);
778
780
  let want = Math.min(Math.max(t, 0), 1) * total;
779
781
  for (let i = 0; i < c.segments.length; i++) {
@@ -784,11 +786,11 @@ function strokePositionPoint(path, index, t) {
784
786
  const target = Math.min(want, lengths[i]);
785
787
  for (let k = 0; k < 40; k++) {
786
788
  const mid = (lo + hi) / 2;
787
- if (_chunk7EDLVBOOcjs.segmentLength.call(void 0, seg, 0, mid) < target) lo = mid;
789
+ if (_chunkVNYRI265cjs.segmentLength.call(void 0, seg, 0, mid) < target) lo = mid;
788
790
  else hi = mid;
789
791
  }
790
792
  const u = (lo + hi) / 2;
791
- const tan = _chunk7EDLVBOOcjs.segmentTangent.call(void 0, seg, u);
793
+ const tan = _chunkVNYRI265cjs.segmentTangent.call(void 0, seg, u);
792
794
  return { point: evalSeg(seg, u), tangent: [tan[0], tan[1]] };
793
795
  }
794
796
  want -= lengths[i];
@@ -800,7 +802,7 @@ function strokePositionPoint(path, index, t) {
800
802
  var KAPPA = 0.5522847498307936;
801
803
  var NOTCH = 0.7;
802
804
  function isClosedBezierShape(path) {
803
- const contours = _chunk7EDLVBOOcjs.pathToContours.call(void 0, path).filter((c) => c.segments.length > 0);
805
+ const contours = _chunkVNYRI265cjs.pathToContours.call(void 0, path).filter((c) => c.segments.length > 0);
804
806
  return contours.length > 0 && contours.every((c) => c.closed);
805
807
  }
806
808
  function effectiveStrokeAlign(style, closedShape) {
@@ -808,7 +810,7 @@ function effectiveStrokeAlign(style, closedShape) {
808
810
  return closedShape ? a : "center";
809
811
  }
810
812
  function strokeWidthProfileOf(style) {
811
- if (!_optionalChain([style, 'access', _25 => _25.strokeWidthProfile, 'optionalAccess', _26 => _26.length])) return null;
813
+ if (!_optionalChain([style, 'access', _24 => _24.strokeWidthProfile, 'optionalAccess', _25 => _25.length])) return null;
812
814
  const p = sanitizeWidthProfile(style.strokeWidthProfile);
813
815
  return isUniformWidthProfile(p) ? null : p;
814
816
  }
@@ -817,11 +819,11 @@ function hasStrokeExtras(style) {
817
819
  }
818
820
  function vectorStrokeLineArea(parts, style, tolerance) {
819
821
  const profile = strokeWidthProfileOf(style);
820
- const dash = _optionalChain([style, 'access', _27 => _27.strokeDasharray, 'optionalAccess', _28 => _28.length]) ? { dash: style.strokeDasharray } : {};
822
+ const dash = _optionalChain([style, 'access', _26 => _26.strokeDasharray, 'optionalAccess', _27 => _27.length]) ? { dash: style.strokeDasharray } : {};
821
823
  const join = _nullishCoalesce(style.strokeLinejoin, () => ( "miter"));
822
824
  const cap = _nullishCoalesce(style.strokeLinecap, () => ( "butt"));
823
825
  if (profile) return variableStrokeOutline(parts.line, { width: parts.drawWidth, profile, join, cap, ...dash, ...tolerance ? { tolerance } : {} });
824
- return _chunk7EDLVBOOcjs.outlineStroke.call(void 0, parts.line, { width: parts.drawWidth, join, cap, ...dash, ...tolerance ? { tolerance } : {} });
826
+ return _chunkVNYRI265cjs.outlineStroke.call(void 0, parts.line, { width: parts.drawWidth, join, cap, ...dash, ...tolerance ? { tolerance } : {} });
825
827
  }
826
828
  var capExtent = (style, width) => style.strokeLinecap === "round" || style.strokeLinecap === "square" ? width / 2 : 0;
827
829
  function arrowheadWeight(style, end) {
@@ -898,16 +900,16 @@ function arrowheadPath(kind, tip, dir, hw) {
898
900
  }
899
901
  }
900
902
  var toVec = (p) => ({ x: p[0], y: p[1] });
901
- var segLen = (s) => _chunk7EDLVBOOcjs.segmentLength.call(void 0, s);
903
+ var segLen = (s) => _chunkVNYRI265cjs.segmentLength.call(void 0, s);
902
904
  function endOf(segs, atStart) {
903
905
  const long = (s2) => segLen(s2) > 1e-9;
904
906
  if (atStart) {
905
907
  const s2 = _nullishCoalesce(segs.find(long), () => ( segs[0]));
906
- const t2 = _chunk7EDLVBOOcjs.segmentTangent.call(void 0, s2, 0);
908
+ const t2 = _chunkVNYRI265cjs.segmentTangent.call(void 0, s2, 0);
907
909
  return { p: toVec(segs[0][0]), out: v(-t2[0], -t2[1]) };
908
910
  }
909
911
  const s = _nullishCoalesce([...segs].reverse().find(long), () => ( segs[segs.length - 1]));
910
- const t = _chunk7EDLVBOOcjs.segmentTangent.call(void 0, s, 1);
912
+ const t = _chunkVNYRI265cjs.segmentTangent.call(void 0, s, 1);
911
913
  const last = segs[segs.length - 1];
912
914
  return { p: toVec(last[last.length - 1]), out: v(t[0], t[1]) };
913
915
  }
@@ -918,7 +920,7 @@ function pointAlong(segs, fromStart, dist4) {
918
920
  const l = segLen(s);
919
921
  if (acc + l >= dist4) {
920
922
  const want = fromStart ? dist4 - acc : l - (dist4 - acc);
921
- const pts = _chunk7EDLVBOOcjs.trimSegments.call(void 0, [s], 0, want);
923
+ const pts = _chunkVNYRI265cjs.trimSegments.call(void 0, [s], 0, want);
922
924
  const p = pts.length ? pts[0][pts[0].length - 1] : s[0];
923
925
  return toVec(p);
924
926
  }
@@ -928,7 +930,7 @@ function pointAlong(segs, fromStart, dist4) {
928
930
  }
929
931
  function vectorStrokeParts(path, style) {
930
932
  const width = _nullishCoalesce(style.strokeWidth, () => ( 1));
931
- const contours = _chunk7EDLVBOOcjs.pathToContours.call(void 0, path).filter((c) => c.segments.length > 0);
933
+ const contours = _chunkVNYRI265cjs.pathToContours.call(void 0, path).filter((c) => c.segments.length > 0);
932
934
  const closedShape = contours.length > 0 && contours.every((c) => c.closed);
933
935
  const align = effectiveStrokeAlign(style, closedShape);
934
936
  const drawWidth = align === "center" ? width : width * 2;
@@ -968,26 +970,26 @@ function vectorStrokeParts(path, style) {
968
970
  if (!s0 && !s1) return c;
969
971
  const lengths = c.segments.map(segLen);
970
972
  const total = lengths.reduce((a, b) => a + b, 0);
971
- return { closed: false, segments: total - s1 > s0 ? _chunk7EDLVBOOcjs.trimSegments.call(void 0, c.segments, s0, total - s1, lengths) : [] };
973
+ return { closed: false, segments: total - s1 > s0 ? _chunkVNYRI265cjs.trimSegments.call(void 0, c.segments, s0, total - s1, lengths) : [] };
972
974
  });
973
- return { align, line: _chunk7EDLVBOOcjs.contoursToPath.call(void 0, trimmed), drawWidth, heads };
975
+ return { align, line: _chunkVNYRI265cjs.contoursToPath.call(void 0, trimmed), drawWidth, heads };
974
976
  }
975
977
  function vectorStrokeOutlinePath(path, style) {
976
978
  const parts = vectorStrokeParts(path, style);
977
979
  const stroke = vectorStrokeLineArea(parts, style);
978
980
  const fill = { path, fillRule: _nullishCoalesce(style.fillRule, () => ( "nonzero")) };
979
981
  let area = stroke;
980
- if (parts.align === "inside") area = _chunk7EDLVBOOcjs.pathBoolean.call(void 0, "intersection", [stroke, fill]).path;
981
- else if (parts.align === "outside") area = _chunk7EDLVBOOcjs.pathBoolean.call(void 0, "difference", [stroke, fill]).path;
982
+ if (parts.align === "inside") area = _chunkVNYRI265cjs.pathBoolean.call(void 0, "intersection", [stroke, fill]).path;
983
+ else if (parts.align === "outside") area = _chunkVNYRI265cjs.pathBoolean.call(void 0, "difference", [stroke, fill]).path;
982
984
  if (!parts.heads.length) return area;
983
- return _chunk7EDLVBOOcjs.pathBoolean.call(void 0, "union", [area, ...parts.heads.map((h) => h.path)]).path;
985
+ return _chunkVNYRI265cjs.pathBoolean.call(void 0, "union", [area, ...parts.heads.map((h) => h.path)]).path;
984
986
  }
985
987
  function hitTestVectorStroke(path, p, style, tolerance = 0) {
986
988
  const parts = vectorStrokeParts(path, style);
987
989
  const point = [p.x, p.y];
988
990
  const width = _nullishCoalesce(style.strokeWidth, () => ( 1));
989
991
  for (const h of parts.heads) {
990
- if (_chunk7EDLVBOOcjs.pointInBezierPath.call(void 0, h.path, point) || tolerance > 0 && _chunk7EDLVBOOcjs.distanceToBezierPath.call(void 0, h.path, point) <= tolerance) return true;
992
+ if (_chunkVNYRI265cjs.pointInBezierPath.call(void 0, h.path, point) || tolerance > 0 && _chunkVNYRI265cjs.distanceToBezierPath.call(void 0, h.path, point) <= tolerance) return true;
991
993
  }
992
994
  if (!parts.line.length) return false;
993
995
  const profile = strokeWidthProfileOf(style);
@@ -1005,13 +1007,13 @@ function hitTestVectorStroke(path, p, style, tolerance = 0) {
1005
1007
  reach = Math.max(reach, width / 2 * (w.left + w.right) / 2);
1006
1008
  }
1007
1009
  } else {
1008
- d = _chunk7EDLVBOOcjs.distanceToBezierPath.call(void 0, parts.line, point);
1010
+ d = _chunkVNYRI265cjs.distanceToBezierPath.call(void 0, parts.line, point);
1009
1011
  if (parts.align !== "center") reach = width;
1010
1012
  }
1011
1013
  if (parts.align === "center") return d <= reach + tolerance;
1012
1014
  if (d > reach + tolerance) return false;
1013
1015
  if (d <= tolerance) return true;
1014
- const inside = _chunk7EDLVBOOcjs.pointInBezierPath.call(void 0, path, point, _nullishCoalesce(style.fillRule, () => ( "nonzero")));
1016
+ const inside = _chunkVNYRI265cjs.pointInBezierPath.call(void 0, path, point, _nullishCoalesce(style.fillRule, () => ( "nonzero")));
1015
1017
  return parts.align === "inside" ? inside : !inside;
1016
1018
  }
1017
1019
  function vectorStrokeReach(style) {
@@ -1087,7 +1089,7 @@ function vectorNodeToBezier(node) {
1087
1089
  }
1088
1090
  function vectorPathData(input, precision = 3) {
1089
1091
  const subpaths = Array.isArray(input) ? input : input.subpaths;
1090
- return _chunk7EDLVBOOcjs.bezierPathToSvg.call(void 0, subpathsToBezier(subpaths), { precision });
1092
+ return _chunkVNYRI265cjs.bezierPathToSvg.call(void 0, subpathsToBezier(subpaths), { precision });
1091
1093
  }
1092
1094
  function inferAnchorType(a) {
1093
1095
  if (isOnAnchor(a, a.in) || isOnAnchor(a, a.out)) return "corner";
@@ -1103,7 +1105,7 @@ function inferAnchorType(a) {
1103
1105
  return Math.abs(li - lo) <= 1e-3 * Math.max(li, lo) ? "symmetric" : "smooth";
1104
1106
  }
1105
1107
  function bezierToSubpaths(input) {
1106
- const path = _chunk7EDLVBOOcjs.toBezierPath.call(void 0, input);
1108
+ const path = _chunkVNYRI265cjs.toBezierPath.call(void 0, input);
1107
1109
  const out = [];
1108
1110
  let current = null;
1109
1111
  const last = () => current.anchors[current.anchors.length - 1];
@@ -1200,14 +1202,14 @@ function nodeMatrix(node) {
1200
1202
  function vectorPathWorldBezier(node, parent = IDENTITY_MATRIX) {
1201
1203
  const m = multiplyMatrices(nodeMatrix(node), parent);
1202
1204
  const path = subpathsToBezier(node.subpaths);
1203
- return isIdentityMatrix(m) ? path : _chunk7EDLVBOOcjs.transformBezierPath.call(void 0, path, m);
1205
+ return isIdentityMatrix(m) ? path : _chunkVNYRI265cjs.transformBezierPath.call(void 0, path, m);
1204
1206
  }
1205
1207
  function vectorNodeBounds(node, parent = IDENTITY_MATRIX) {
1206
1208
  if (node.type === "group") {
1207
1209
  const m = multiplyMatrices(nodeMatrix(node), parent);
1208
1210
  return unionBounds(node.children.map((c) => vectorNodeBounds(c, m)));
1209
1211
  }
1210
- const b = _chunk7EDLVBOOcjs.bezierPathBounds.call(void 0, vectorPathWorldBezier(node, parent));
1212
+ const b = _chunkVNYRI265cjs.bezierPathBounds.call(void 0, vectorPathWorldBezier(node, parent));
1211
1213
  if (!b) return null;
1212
1214
  return { x: b.minX, y: b.minY, width: b.maxX - b.minX, height: b.maxY - b.minY };
1213
1215
  }
@@ -1241,9 +1243,9 @@ function hitTestVectorNode(node, p, tolerance = 0, parent = IDENTITY_MATRIX) {
1241
1243
  const path = vectorPathWorldBezier(node, parent);
1242
1244
  if (path.length === 0) return false;
1243
1245
  const point = [p.x, p.y];
1244
- if (hasPaint(node.fill) && _chunk7EDLVBOOcjs.pointInBezierPath.call(void 0, path, point, _nullishCoalesce(node.fillRule, () => ( "nonzero")))) return true;
1246
+ if (hasPaint(node.fill) && _chunkVNYRI265cjs.pointInBezierPath.call(void 0, path, point, _nullishCoalesce(node.fillRule, () => ( "nonzero")))) return true;
1245
1247
  if (hasPaint(node.stroke)) return hitTestVectorStroke(path, p, node, tolerance);
1246
- return _chunk7EDLVBOOcjs.distanceToBezierPath.call(void 0, path, point) <= tolerance;
1248
+ return _chunkVNYRI265cjs.distanceToBezierPath.call(void 0, path, point) <= tolerance;
1247
1249
  }
1248
1250
  function vectorStrokeOutline(node, parent = IDENTITY_MATRIX) {
1249
1251
  if (!hasPaint(node.stroke) || !((_nullishCoalesce(node.strokeWidth, () => ( 1))) > 0)) return [];
@@ -1263,9 +1265,9 @@ function nearestSegment(node, p) {
1263
1265
  const count = subpathSegmentCount(sp);
1264
1266
  for (let i = 0; i < count; i++) {
1265
1267
  const seg = subpathSegment(sp, i);
1266
- const hit = _chunk7EDLVBOOcjs.segmentNearest.call(void 0, seg, [p.x, p.y]);
1268
+ const hit = _chunkVNYRI265cjs.segmentNearest.call(void 0, seg, [p.x, p.y]);
1267
1269
  if (!best || hit.distance < best.distance) {
1268
- const pt2 = _chunk7EDLVBOOcjs.segmentPoint.call(void 0, seg, hit.t);
1270
+ const pt2 = _chunkVNYRI265cjs.segmentPoint.call(void 0, seg, hit.t);
1269
1271
  best = { subpath: s, segment: i, t: hit.t, point: { x: pt2[0], y: pt2[1] }, distance: hit.distance };
1270
1272
  }
1271
1273
  }
@@ -1325,7 +1327,7 @@ function bakeIntoGeometry(node, m) {
1325
1327
  if (isIdentityMatrix(m)) return node;
1326
1328
  if (node.type === "group") return { ...node, children: node.children.map((c) => transformVectorNode(c, m)) };
1327
1329
  const path = node;
1328
- const mirrored = m[0] * m[3] - m[1] * m[2] < 0 && _optionalChain([path, 'access', _29 => _29.strokeWidthProfile, 'optionalAccess', _30 => _30.length]);
1330
+ const mirrored = m[0] * m[3] - m[1] * m[2] < 0 && _optionalChain([path, 'access', _28 => _28.strokeWidthProfile, 'optionalAccess', _29 => _29.length]);
1329
1331
  return {
1330
1332
  ...path,
1331
1333
  ...mirrored ? { strokeWidthProfile: mirrorWidthProfile(path.strokeWidthProfile) } : {},
@@ -1439,7 +1441,7 @@ function insertAnchor(sp, segment, t) {
1439
1441
  const ia = segment;
1440
1442
  const ib = (segment + 1) % n;
1441
1443
  const seg = subpathSegment(sp, segment);
1442
- const [left, right] = _chunk7EDLVBOOcjs.splitSegment.call(void 0, seg, t);
1444
+ const [left, right] = _chunkVNYRI265cjs.splitSegment.call(void 0, seg, t);
1443
1445
  const mid = left[left.length - 1];
1444
1446
  const anchor = { x: mid[0], y: mid[1] };
1445
1447
  if (seg.length === 4) {
@@ -1535,7 +1537,7 @@ function vectorCornersAttribute(subpaths, precision = 3) {
1535
1537
  subpaths.forEach(
1536
1538
  (sp, s) => sp.anchors.forEach((a, i) => {
1537
1539
  if (!a.corner || !(a.corner.radius > 0)) return;
1538
- out.push(`${s}.${i}:${_chunk7EDLVBOOcjs.formatNumber.call(void 0, a.corner.radius, precision)}${a.corner.kind && a.corner.kind !== "round" ? `:${a.corner.kind}` : ""}`);
1540
+ out.push(`${s}.${i}:${_chunkVNYRI265cjs.formatNumber.call(void 0, a.corner.radius, precision)}${a.corner.kind && a.corner.kind !== "round" ? `:${a.corner.kind}` : ""}`);
1539
1541
  })
1540
1542
  );
1541
1543
  return out.join(" ");
@@ -1544,7 +1546,7 @@ function applyVectorCornersAttribute(subpaths, value) {
1544
1546
  for (const item of value.trim().split(/\s+/)) {
1545
1547
  const m = /^(\d+)\.(\d+):([\d.eE+-]+)(?::([a-z]+))?$/.exec(item);
1546
1548
  if (!m) continue;
1547
- const a = _optionalChain([subpaths, 'access', _31 => _31[+m[1]], 'optionalAccess', _32 => _32.anchors, 'access', _33 => _33[+m[2]]]);
1549
+ const a = _optionalChain([subpaths, 'access', _30 => _30[+m[1]], 'optionalAccess', _31 => _31.anchors, 'access', _32 => _32[+m[2]]]);
1548
1550
  const radius = parseFloat(m[3]);
1549
1551
  if (!a || !(radius > 0)) continue;
1550
1552
  const kind = VECTOR_CORNER_KINDS.includes(m[4]) ? m[4] : void 0;
@@ -1556,7 +1558,7 @@ var escapeAttr = (value) => value.replace(/&/g, "&amp;").replace(/"/g, "&quot;")
1556
1558
  function vectorPaintToSvg(paint, gradientId) {
1557
1559
  if (!hasPaint(paint)) return { value: "none", gradient: null };
1558
1560
  if (typeof paint === "string") return { value: paint, gradient: null };
1559
- return { value: `url(#${gradientId})`, gradient: _chunk7EDLVBOOcjs.gradientToSvgDef.call(void 0, paint, gradientId) };
1561
+ return { value: `url(#${gradientId})`, gradient: _chunkVNYRI265cjs.gradientToSvgDef.call(void 0, paint, gradientId) };
1560
1562
  }
1561
1563
  var partsCache = /* @__PURE__ */ new WeakMap();
1562
1564
  function vectorStrokeSvgParts(node, clipId, precision = 3) {
@@ -1574,22 +1576,22 @@ function computeStrokeSvgParts(node, clipId, precision) {
1574
1576
  if (parts.align === "center" && !parts.heads.length && !profiled) return void 0;
1575
1577
  let clip = null;
1576
1578
  if (parts.align !== "center") {
1577
- const b = _chunk7EDLVBOOcjs.bezierPathBounds.call(void 0, path);
1579
+ const b = _chunkVNYRI265cjs.bezierPathBounds.call(void 0, path);
1578
1580
  const pad = vectorStrokeReach(node) + 1;
1579
1581
  const bounds = b ? { x: round2(b.minX - pad), y: round2(b.minY - pad), width: round2(b.maxX - b.minX + 2 * pad), height: round2(b.maxY - b.minY + 2 * pad) } : { x: 0, y: 0, width: 0, height: 0 };
1580
1582
  clip = { kind: parts.align === "inside" ? "clip" : "mask", id: clipId, bounds };
1581
1583
  }
1582
1584
  return {
1583
1585
  align: parts.align,
1584
- d: _chunk7EDLVBOOcjs.bezierPathToSvg.call(void 0, parts.line, { precision }),
1586
+ d: _chunkVNYRI265cjs.bezierPathToSvg.call(void 0, parts.line, { precision }),
1585
1587
  width: parts.drawWidth,
1586
- ...profiled && (_nullishCoalesce(node.strokeWidth, () => ( 1))) > 0 ? { outline: _chunk7EDLVBOOcjs.bezierPathToSvg.call(void 0, vectorStrokeLineArea(parts, node), { precision }) } : {},
1588
+ ...profiled && (_nullishCoalesce(node.strokeWidth, () => ( 1))) > 0 ? { outline: _chunkVNYRI265cjs.bezierPathToSvg.call(void 0, vectorStrokeLineArea(parts, node), { precision }) } : {},
1587
1589
  clip,
1588
- heads: parts.heads.map((h) => _chunk7EDLVBOOcjs.bezierPathToSvg.call(void 0, h.path, { precision }))
1590
+ heads: parts.heads.map((h) => _chunkVNYRI265cjs.bezierPathToSvg.call(void 0, h.path, { precision }))
1589
1591
  };
1590
1592
  }
1591
1593
  function widthProfileToAttribute(points, precision = 4) {
1592
- return points.map((p) => [p.t, p.left, p.right].map((n) => _chunk7EDLVBOOcjs.formatNumber.call(void 0, n, precision)).join(",")).join(";");
1594
+ return points.map((p) => [p.t, p.left, p.right].map((n) => _chunkVNYRI265cjs.formatNumber.call(void 0, n, precision)).join(",")).join(";");
1593
1595
  }
1594
1596
  function widthProfileFromAttribute(value) {
1595
1597
  if (!value) return [];
@@ -1613,11 +1615,11 @@ function vectorDocumentToSvg(doc, options = {}) {
1613
1615
  const pretty = options.pretty !== false;
1614
1616
  const defs = [];
1615
1617
  const lines = [];
1616
- const num = (n) => _chunk7EDLVBOOcjs.formatNumber.call(void 0, n, precision);
1618
+ const num = (n) => _chunkVNYRI265cjs.formatNumber.call(void 0, n, precision);
1617
1619
  const indent = (depth) => pretty ? " ".repeat(depth) : "";
1618
1620
  const common = (node) => {
1619
1621
  let out2 = ` id="${escapeAttr(node.id)}"`;
1620
- if (node.transform) out2 += ` transform="matrix(${node.transform.map((n) => _chunk7EDLVBOOcjs.formatNumber.call(void 0, n, 6)).join(" ")})"`;
1622
+ if (node.transform) out2 += ` transform="matrix(${node.transform.map((n) => _chunkVNYRI265cjs.formatNumber.call(void 0, n, 6)).join(" ")})"`;
1621
1623
  if (node.opacity !== void 0 && node.opacity < 1) out2 += ` opacity="${num(node.opacity)}"`;
1622
1624
  if (node.visible === false) out2 += ` display="none"`;
1623
1625
  return out2;
@@ -1636,13 +1638,13 @@ function vectorDocumentToSvg(doc, options = {}) {
1636
1638
  if (stroke.gradient) defs.push(gradientMarkup(stroke.gradient));
1637
1639
  const d = vectorPathData(node, precision);
1638
1640
  const corners2 = vectorCornersAttribute(node.subpaths, precision);
1639
- const live = corners2 ? ` data-vector-d="${_chunk7EDLVBOOcjs.bezierPathToSvg.call(void 0, subpathsToBezier(node.subpaths, { corners: false }), { precision })}" data-vector-corners="${corners2}"` : "";
1641
+ const live = corners2 ? ` data-vector-d="${_chunkVNYRI265cjs.bezierPathToSvg.call(void 0, subpathsToBezier(node.subpaths, { corners: false }), { precision })}" data-vector-corners="${corners2}"` : "";
1640
1642
  const fillAttrs = ` fill="${escapeAttr(fill.value)}"${node.fillRule === "evenodd" ? ` fill-rule="evenodd"` : ""}`;
1641
1643
  const lineAttrs = (width) => {
1642
1644
  let out2 = ` stroke="${escapeAttr(stroke.value)}" stroke-width="${num(width)}"`;
1643
1645
  if (node.strokeLinecap && node.strokeLinecap !== "butt") out2 += ` stroke-linecap="${node.strokeLinecap}"`;
1644
1646
  if (node.strokeLinejoin && node.strokeLinejoin !== "miter") out2 += ` stroke-linejoin="${node.strokeLinejoin}"`;
1645
- if (_optionalChain([node, 'access', _34 => _34.strokeDasharray, 'optionalAccess', _35 => _35.length])) out2 += ` stroke-dasharray="${node.strokeDasharray.map(num).join(" ")}"`;
1647
+ if (_optionalChain([node, 'access', _33 => _33.strokeDasharray, 'optionalAccess', _34 => _34.length])) out2 += ` stroke-dasharray="${node.strokeDasharray.map(num).join(" ")}"`;
1646
1648
  return out2;
1647
1649
  };
1648
1650
  const parts = stroke.value !== "none" ? vectorStrokeSvgParts(node, `${prefix}clip-${node.id}`, precision) : void 0;
@@ -1662,12 +1664,12 @@ function vectorDocumentToSvg(doc, options = {}) {
1662
1664
  data += ` data-vector-width-profile="${widthProfileToAttribute(profile)}"`;
1663
1665
  if (node.strokeLinecap && node.strokeLinecap !== "butt") data += ` data-vector-stroke-linecap="${node.strokeLinecap}"`;
1664
1666
  if (node.strokeLinejoin && node.strokeLinejoin !== "miter") data += ` data-vector-stroke-linejoin="${node.strokeLinejoin}"`;
1665
- if (_optionalChain([node, 'access', _36 => _36.strokeDasharray, 'optionalAccess', _37 => _37.length])) data += ` data-vector-stroke-dasharray="${node.strokeDasharray.map(num).join(" ")}"`;
1667
+ if (_optionalChain([node, 'access', _35 => _35.strokeDasharray, 'optionalAccess', _36 => _36.length])) data += ` data-vector-stroke-dasharray="${node.strokeDasharray.map(num).join(" ")}"`;
1666
1668
  }
1667
1669
  lines.push(`${indent(depth)}<g${common(node)}${data}>`);
1668
1670
  lines.push(`${indent(depth + 1)}<path data-vector-part="fill" d="${d}"${fillAttrs}${live}/>`);
1669
1671
  if (options.strokes === "outline") {
1670
- const area = _chunk7EDLVBOOcjs.bezierPathToSvg.call(void 0, vectorStrokeOutlinePath(subpathsToBezier(node.subpaths), node), { precision });
1672
+ const area = _chunkVNYRI265cjs.bezierPathToSvg.call(void 0, vectorStrokeOutlinePath(subpathsToBezier(node.subpaths), node), { precision });
1671
1673
  lines.push(`${indent(depth + 1)}<path data-vector-part="stroke-outline" d="${area}" fill="${escapeAttr(stroke.value)}"/>`);
1672
1674
  } else {
1673
1675
  let clip = "";
@@ -1831,7 +1833,7 @@ function resolveGradient(id, raw, seen = /* @__PURE__ */ new Set()) {
1831
1833
  seen.add(id);
1832
1834
  let stops = readStops(el);
1833
1835
  const href = _nullishCoalesce(el.attrs.href, () => ( el.attrs["xlink:href"]));
1834
- if (!stops.length && _optionalChain([href, 'optionalAccess', _38 => _38.startsWith, 'call', _39 => _39("#")])) stops = _nullishCoalesce(_optionalChain([resolveGradient, 'call', _40 => _40(href.slice(1), raw, seen), 'optionalAccess', _41 => _41.stops]), () => ( []));
1836
+ if (!stops.length && _optionalChain([href, 'optionalAccess', _37 => _37.startsWith, 'call', _38 => _38("#")])) stops = _nullishCoalesce(_optionalChain([resolveGradient, 'call', _39 => _39(href.slice(1), raw, seen), 'optionalAccess', _40 => _40.stops]), () => ( []));
1835
1837
  if (!stops.length) return null;
1836
1838
  if (el.name === "radialGradient") {
1837
1839
  return { type: "radial", cx: fraction(el.attrs.cx, 0.5), cy: fraction(el.attrs.cy, 0.5), r: fraction(el.attrs.r, 0.5), stops };
@@ -1935,7 +1937,7 @@ function parseVectorSvg(svg, options = {}) {
1935
1937
  const part = (name) => g.children.find((c) => c.name === "path" && c.attrs["data-vector-part"] === name);
1936
1938
  const fillEl = part("fill");
1937
1939
  const subpaths = fillEl ? shapeOf(fillEl) : null;
1938
- if (!fillEl || !_optionalChain([subpaths, 'optionalAccess', _42 => _42.length])) return null;
1940
+ if (!fillEl || !_optionalChain([subpaths, 'optionalAccess', _41 => _41.length])) return null;
1939
1941
  const a = g.attrs;
1940
1942
  const fs = readStyle(fillEl, style);
1941
1943
  const strokeEl = part("stroke");
@@ -1972,7 +1974,7 @@ function parseVectorSvg(svg, options = {}) {
1972
1974
  ...profile.length ? { strokeWidthProfile: profile } : {},
1973
1975
  ...keptCap ? { strokeLinecap: keptCap } : {},
1974
1976
  ...keptJoin ? { strokeLinejoin: keptJoin } : {},
1975
- ..._optionalChain([keptDash, 'optionalAccess', _43 => _43.length]) ? { strokeDasharray: keptDash } : {}
1977
+ ..._optionalChain([keptDash, 'optionalAccess', _42 => _42.length]) ? { strokeDasharray: keptDash } : {}
1976
1978
  };
1977
1979
  return placed(node, m);
1978
1980
  };
@@ -2026,7 +2028,7 @@ function parseVectorSvg(svg, options = {}) {
2026
2028
  // src/vector/snap.ts
2027
2029
  var VECTOR_CONSTRUCTION_ANGLES = [0, 45, 90, 135];
2028
2030
  function constrainToLeave(leave, p) {
2029
- if (!_optionalChain([leave, 'optionalAccess', _44 => _44.constrain])) return p;
2031
+ if (!_optionalChain([leave, 'optionalAccess', _43 => _43.constrain])) return p;
2030
2032
  const dx = p.x - leave.at.x;
2031
2033
  const dy = p.y - leave.at.y;
2032
2034
  switch (leave.constrain) {
@@ -2137,7 +2139,7 @@ var VectorSnapTargets = (_class = class _VectorSnapTargets {
2137
2139
  moving.set(r.nodeId, set);
2138
2140
  }
2139
2141
  const t = _VectorSnapTargets.collect(doc, new Set(moving.keys()), "segments", false);
2140
- t.pushPaths(doc, new Set(moving.keys()), (id, s, i) => !!_optionalChain([moving, 'access', _45 => _45.get, 'call', _46 => _46(id), 'optionalAccess', _47 => _47.has, 'call', _48 => _48(`${s}:${i}`)]), true);
2142
+ t.pushPaths(doc, new Set(moving.keys()), (id, s, i) => !!_optionalChain([moving, 'access', _44 => _44.get, 'call', _45 => _45(id), 'optionalAccess', _46 => _46.has, 'call', _47 => _47(`${s}:${i}`)]), true);
2141
2143
  return t.index();
2142
2144
  }
2143
2145
  /**
@@ -2255,7 +2257,7 @@ var VectorSnapTargets = (_class = class _VectorSnapTargets {
2255
2257
  }
2256
2258
  const b = vectorNodeBounds(n, parent);
2257
2259
  const f = nodeFrame(n, parent, b);
2258
- if (b) self.pushRect(b, "edge", _nullishCoalesce(_optionalChain([f, 'optionalAccess', _49 => _49.centre]), () => ( null)));
2260
+ if (b) self.pushRect(b, "edge", _nullishCoalesce(_optionalChain([f, 'optionalAccess', _48 => _48.centre]), () => ( null)));
2259
2261
  }
2260
2262
  };
2261
2263
  visit(doc.nodes, IDENTITY_MATRIX);
@@ -2300,7 +2302,7 @@ var VectorSnapTargets = (_class = class _VectorSnapTargets {
2300
2302
  lines: lines2,
2301
2303
  labels: [this.label(q, kind)]
2302
2304
  });
2303
- if (_optionalChain([leave, 'optionalAccess', _50 => _50.constrain])) {
2305
+ if (_optionalChain([leave, 'optionalAccess', _49 => _49.constrain])) {
2304
2306
  const q = constrainToLeave(leave, p);
2305
2307
  const hit = this.slide(leave.at, { x: q.x - leave.at.x, y: q.y - leave.at.y }, q, tol, true);
2306
2308
  return hit ? { point: hit.point, x: true, y: true, ...this.linedUp(hit.point, hit.from) } : none(q);
@@ -2316,7 +2318,7 @@ var VectorSnapTargets = (_class = class _VectorSnapTargets {
2316
2318
  }
2317
2319
  const on = this.onSegment(near2);
2318
2320
  if (on) return at2(on, "path");
2319
- if (_optionalChain([leave, 'optionalAccess', _51 => _51.angles, 'optionalAccess', _52 => _52.length])) {
2321
+ if (_optionalChain([leave, 'optionalAccess', _50 => _50.angles, 'optionalAccess', _51 => _51.length])) {
2320
2322
  const c = construction(leave, p, tol);
2321
2323
  if (c) {
2322
2324
  const hit = this.slide(leave.at, c.dir, c.point, tol, false);
@@ -2392,13 +2394,13 @@ var VectorSnapTargets = (_class = class _VectorSnapTargets {
2392
2394
  const pt2 = toPoint(p);
2393
2395
  for (const s of this.segments) {
2394
2396
  if (p.x < s.minX - tol || p.x > s.maxX + tol || p.y < s.minY - tol || p.y > s.maxY + tol) continue;
2395
- const hit = _chunk7EDLVBOOcjs.segmentNearest.call(void 0, s.seg, pt2);
2397
+ const hit = _chunkVNYRI265cjs.segmentNearest.call(void 0, s.seg, pt2);
2396
2398
  if (hit.distance <= tol) out.push({ seg: s.seg, t: hit.t, distance: hit.distance });
2397
2399
  }
2398
2400
  return out.sort((a, b) => a.distance - b.distance);
2399
2401
  }
2400
2402
  onSegment(near2) {
2401
- return near2.length ? toVec2(_chunk7EDLVBOOcjs.segmentPoint.call(void 0, near2[0].seg, near2[0].t)) : null;
2403
+ return near2.length ? toVec2(_chunkVNYRI265cjs.segmentPoint.call(void 0, near2[0].seg, near2[0].t)) : null;
2402
2404
  }
2403
2405
  /** Where two of the target segments near `p` cross, the crossing nearest `p` within `tol`. */
2404
2406
  crossing(near2, p, tol) {
@@ -2407,7 +2409,7 @@ var VectorSnapTargets = (_class = class _VectorSnapTargets {
2407
2409
  let bestD = Infinity;
2408
2410
  for (let i = 0; i < list.length; i++) {
2409
2411
  for (let j = i + 1; j < list.length; j++) {
2410
- for (const hit of _chunk7EDLVBOOcjs.segmentIntersections.call(void 0, list[i].seg, list[j].seg)) {
2412
+ for (const hit of _chunkVNYRI265cjs.segmentIntersections.call(void 0, list[i].seg, list[j].seg)) {
2411
2413
  const q = toVec2(hit.point);
2412
2414
  const d = distance(q, p);
2413
2415
  if (d <= tol && d < bestD) {
@@ -2446,7 +2448,7 @@ var VectorSnapTargets = (_class = class _VectorSnapTargets {
2446
2448
  * with nothing spaces the box evenly in its row or column. Returns the correction and guides.
2447
2449
  */
2448
2450
  snapRect(r, tol, options = {}) {
2449
- const axes = { x: _optionalChain([options, 'access', _53 => _53.axes, 'optionalAccess', _54 => _54.x]) !== false, y: _optionalChain([options, 'access', _55 => _55.axes, 'optionalAccess', _56 => _56.y]) !== false };
2451
+ const axes = { x: _optionalChain([options, 'access', _52 => _52.axes, 'optionalAccess', _53 => _53.x]) !== false, y: _optionalChain([options, 'access', _54 => _54.axes, 'optionalAccess', _55 => _55.y]) !== false };
2450
2452
  const nearest = (lines, values) => {
2451
2453
  let best = null;
2452
2454
  for (const v2 of values) for (const l of linesNear(lines, v2, tol)) if (!best || Math.abs(l.v - v2) < Math.abs(best.d)) best = { d: l.v - v2, from: l.from };
@@ -2454,7 +2456,7 @@ var VectorSnapTargets = (_class = class _VectorSnapTargets {
2454
2456
  };
2455
2457
  const bx = axes.x ? nearest(this.xs, [r.x, r.x + r.width / 2, r.x + r.width]) : null;
2456
2458
  const by = axes.y ? nearest(this.ys, [r.y, r.y + r.height / 2, r.y + r.height]) : null;
2457
- const out = { dx: _nullishCoalesce(_optionalChain([bx, 'optionalAccess', _57 => _57.d]), () => ( 0)), dy: _nullishCoalesce(_optionalChain([by, 'optionalAccess', _58 => _58.d]), () => ( 0)), x: !!bx, y: !!by, lines: [], labels: [] };
2459
+ const out = { dx: _nullishCoalesce(_optionalChain([bx, 'optionalAccess', _56 => _56.d]), () => ( 0)), dy: _nullishCoalesce(_optionalChain([by, 'optionalAccess', _57 => _57.d]), () => ( 0)), x: !!bx, y: !!by, lines: [], labels: [] };
2458
2460
  const done = { ...r, x: r.x + out.dx, y: r.y + out.dy };
2459
2461
  if (bx) {
2460
2462
  const x = bx.from.x;
@@ -2577,9 +2579,9 @@ var VectorSnapTargets = (_class = class _VectorSnapTargets {
2577
2579
  const on = this.nearestPoint(p, tol);
2578
2580
  const tries = [];
2579
2581
  if (on) tries.push({ tx: on.p.x, ty: on.p.y, s: { hx: null, hy: null, on } });
2580
- tries.push({ tx: _nullishCoalesce(_optionalChain([hx, 'optionalAccess', _59 => _59.v]), () => ( null)), ty: _nullishCoalesce(_optionalChain([hy, 'optionalAccess', _60 => _60.v]), () => ( null)), s: { hx, hy, on: null } });
2581
- tries.push({ tx: _nullishCoalesce(_optionalChain([hx, 'optionalAccess', _61 => _61.v]), () => ( null)), ty: null, s: { hx, hy: null, on: null } });
2582
- tries.push({ tx: null, ty: _nullishCoalesce(_optionalChain([hy, 'optionalAccess', _62 => _62.v]), () => ( null)), s: { hx: null, hy, on: null } });
2582
+ tries.push({ tx: _nullishCoalesce(_optionalChain([hx, 'optionalAccess', _58 => _58.v]), () => ( null)), ty: _nullishCoalesce(_optionalChain([hy, 'optionalAccess', _59 => _59.v]), () => ( null)), s: { hx, hy, on: null } });
2583
+ tries.push({ tx: _nullishCoalesce(_optionalChain([hx, 'optionalAccess', _60 => _60.v]), () => ( null)), ty: null, s: { hx, hy: null, on: null } });
2584
+ tries.push({ tx: null, ty: _nullishCoalesce(_optionalChain([hy, 'optionalAccess', _61 => _61.v]), () => ( null)), s: { hx: null, hy, on: null } });
2583
2585
  for (const { tx, ty, s } of tries) {
2584
2586
  if (tx === null && ty === null) continue;
2585
2587
  const q = applyMatrix(toLocal, { x: _nullishCoalesce(tx, () => ( p.x)), y: _nullishCoalesce(ty, () => ( p.y)) });
@@ -2729,15 +2731,15 @@ var crossCondition = (r, d) => r[0] * d[1] - r[1] * d[0];
2729
2731
  function solveOnSegment(seg, base, cond) {
2730
2732
  const b = [base.x, base.y];
2731
2733
  const g = (t) => {
2732
- const p = _chunk7EDLVBOOcjs.segmentPoint.call(void 0, seg, t);
2733
- return cond([p[0] - b[0], p[1] - b[1]], _chunk7EDLVBOOcjs.segmentDerivative.call(void 0, seg, t));
2734
+ const p = _chunkVNYRI265cjs.segmentPoint.call(void 0, seg, t);
2735
+ return cond([p[0] - b[0], p[1] - b[1]], _chunkVNYRI265cjs.segmentDerivative.call(void 0, seg, t));
2734
2736
  };
2735
2737
  const vals = [];
2736
2738
  let scale = 0;
2737
2739
  for (let i = 0; i <= CURVE_SAMPLES; i++) {
2738
2740
  const t = i / CURVE_SAMPLES;
2739
- const p = _chunk7EDLVBOOcjs.segmentPoint.call(void 0, seg, t);
2740
- const d = _chunk7EDLVBOOcjs.segmentDerivative.call(void 0, seg, t);
2741
+ const p = _chunkVNYRI265cjs.segmentPoint.call(void 0, seg, t);
2742
+ const d = _chunkVNYRI265cjs.segmentDerivative.call(void 0, seg, t);
2741
2743
  const r = [p[0] - b[0], p[1] - b[1]];
2742
2744
  vals.push(cond(r, d));
2743
2745
  scale = Math.max(scale, Math.hypot(r[0], r[1]) * Math.hypot(d[0], d[1]));
@@ -2764,8 +2766,8 @@ function solveOnSegment(seg, base, cond) {
2764
2766
  } else hi = m;
2765
2767
  }
2766
2768
  const t = (lo + hi) / 2;
2767
- const p = _chunk7EDLVBOOcjs.segmentPoint.call(void 0, seg, t);
2768
- const dv = _chunk7EDLVBOOcjs.segmentDerivative.call(void 0, seg, t);
2769
+ const p = _chunkVNYRI265cjs.segmentPoint.call(void 0, seg, t);
2770
+ const dv = _chunkVNYRI265cjs.segmentDerivative.call(void 0, seg, t);
2769
2771
  const r = Math.hypot(p[0] - b[0], p[1] - b[1]);
2770
2772
  const dl = Math.hypot(dv[0], dv[1]);
2771
2773
  if (!(r > 1e-9 && dl > 0) || Math.abs(cond([p[0] - b[0], p[1] - b[1]], dv)) > 1e-6 * r * dl) continue;
@@ -2802,7 +2804,7 @@ function endTangent(c) {
2802
2804
  return [1, 0];
2803
2805
  }
2804
2806
  function sample(c, n, out, withStart) {
2805
- for (let i = withStart ? 0 : 1; i <= n; i++) out.push(_chunk7EDLVBOOcjs.segmentPoint.call(void 0, c, i / n));
2807
+ for (let i = withStart ? 0 : 1; i <= n; i++) out.push(_chunkVNYRI265cjs.segmentPoint.call(void 0, c, i / n));
2806
2808
  }
2807
2809
  var onAnchor2 = (a, h) => !h || Math.abs(h.x - a.x) < EPS3 && Math.abs(h.y - a.y) < EPS3;
2808
2810
  function tidy(a, keepType = true) {
@@ -2848,7 +2850,7 @@ function fitAcross(pts, N, t0, t1) {
2848
2850
  const u = [];
2849
2851
  for (let i = 0; i <= N; i++) u.push(k * i / N);
2850
2852
  for (let i = 1; i <= N; i++) u.push(k + (1 - k) * i / N);
2851
- return _chunk7EDLVBOOcjs.fitCubicWithTangents.call(void 0, pts, u, t0, t1);
2853
+ return _chunkVNYRI265cjs.fitCubicWithTangents.call(void 0, pts, u, t0, t1);
2852
2854
  };
2853
2855
  return goldenMin(fit, 0, 1);
2854
2856
  }
@@ -2908,7 +2910,7 @@ function bendSegment(sp, segment, t, p) {
2908
2910
  return { anchors, closed: sp.closed };
2909
2911
  }
2910
2912
  function subpathPointAt(sp, segment, t) {
2911
- const [x, y] = _chunk7EDLVBOOcjs.segmentPoint.call(void 0, subpathSegment(sp, segment), t);
2913
+ const [x, y] = _chunkVNYRI265cjs.segmentPoint.call(void 0, subpathSegment(sp, segment), t);
2912
2914
  return { x, y };
2913
2915
  }
2914
2916
  function curvatureMoveAnchor(sp, index, q) {
@@ -3169,12 +3171,12 @@ function removeRedundantPoints(sp, tolerance) {
3169
3171
  }
3170
3172
 
3171
3173
  // src/vector/pathCut.ts
3172
- var loopArea = (l) => _chunk7EDLVBOOcjs.contourSignedArea.call(void 0, l.segs);
3174
+ var loopArea = (l) => _chunkVNYRI265cjs.contourSignedArea.call(void 0, l.segs);
3173
3175
  function loopSample(l) {
3174
3176
  const k = l.chord.findIndex((c) => !c);
3175
- return _chunk7EDLVBOOcjs.segmentPoint.call(void 0, l.segs[k >= 0 ? k : 0], 0.5);
3177
+ return _chunkVNYRI265cjs.segmentPoint.call(void 0, l.segs[k >= 0 ? k : 0], 0.5);
3176
3178
  }
3177
- var contains2 = (l, p) => _chunk7EDLVBOOcjs.windingNumber.call(void 0, [l.segs], p) !== 0;
3179
+ var contains2 = (l, p) => _chunkVNYRI265cjs.windingNumber.call(void 0, [l.segs], p) !== 0;
3178
3180
  function groupFaces(loops) {
3179
3181
  const usable2 = loops.filter((l) => l.segs.length && Math.abs(loopArea(l)) > 1e-12);
3180
3182
  if (!usable2.length) return [];
@@ -3190,12 +3192,12 @@ function groupFaces(loops) {
3190
3192
  return outers.reverse().map((o) => faces.get(o));
3191
3193
  }
3192
3194
  function faceToPath(face) {
3193
- return _chunk7EDLVBOOcjs.contoursToPath.call(void 0, face.loops.map((l) => ({ segments: l.segs, closed: true })));
3195
+ return _chunkVNYRI265cjs.contoursToPath.call(void 0, face.loops.map((l) => ({ segments: l.segs, closed: true })));
3194
3196
  }
3195
3197
  function facesOf(path, fillRule) {
3196
- const normalized = _chunk7EDLVBOOcjs.normalizeBezierPath.call(void 0, path, fillRule);
3197
- const loops = _chunk7EDLVBOOcjs.pathToContours.call(void 0, normalized).map((c) => {
3198
- const segs = _chunk7EDLVBOOcjs.closeContour.call(void 0, c, true).map((s) => s.slice());
3198
+ const normalized = _chunkVNYRI265cjs.normalizeBezierPath.call(void 0, path, fillRule);
3199
+ const loops = _chunkVNYRI265cjs.pathToContours.call(void 0, normalized).map((c) => {
3200
+ const segs = _chunkVNYRI265cjs.closeContour.call(void 0, c, true).map((s) => s.slice());
3199
3201
  return { segs, chord: segs.map(() => false) };
3200
3202
  });
3201
3203
  return groupFaces(loops);
@@ -3265,7 +3267,7 @@ function lineHits(p, q, seg) {
3265
3267
  const scale = Math.sqrt(len2) * Math.max(1, ...seg.map((pt2) => Math.abs(pt2[0]) + Math.abs(pt2[1])));
3266
3268
  const out = [];
3267
3269
  for (const t of rootsInUnit(...coeffs, scale)) {
3268
- const point = _chunk7EDLVBOOcjs.segmentPoint.call(void 0, seg, t);
3270
+ const point = _chunkVNYRI265cjs.segmentPoint.call(void 0, seg, t);
3269
3271
  const s = ((point[0] - p[0]) * dx + (point[1] - p[1]) * dy) / len2;
3270
3272
  if (s >= -1e-9 && s <= 1 + 1e-9) out.push({ s: Math.min(1, Math.max(0, s)), t, point });
3271
3273
  }
@@ -3278,7 +3280,7 @@ function arc(l, a, b, eps) {
3278
3280
  const segs = [];
3279
3281
  const chord = [];
3280
3282
  const push = (k, t0, t1) => {
3281
- const piece = t0 <= 0 && t1 >= 1 ? l.segs[k].slice() : _chunk7EDLVBOOcjs.subSegment.call(void 0, l.segs[k], t0, t1);
3283
+ const piece = t0 <= 0 && t1 >= 1 ? l.segs[k].slice() : _chunkVNYRI265cjs.subSegment.call(void 0, l.segs[k], t0, t1);
3282
3284
  if (!degenerate(piece, eps)) {
3283
3285
  segs.push(piece);
3284
3286
  chord.push(l.chord[k]);
@@ -3303,7 +3305,7 @@ function knifePath(path, fillRule, knife) {
3303
3305
  if (pts.length < 2) return null;
3304
3306
  let faces = facesOf(path, fillRule);
3305
3307
  if (!faces.length) return null;
3306
- const b = _chunk7EDLVBOOcjs.bezierPathBounds.call(void 0, path);
3308
+ const b = _chunkVNYRI265cjs.bezierPathBounds.call(void 0, path);
3307
3309
  const size = b ? Math.max(b.maxX - b.minX, b.maxY - b.minY, 1) : 1;
3308
3310
  const eps = size * 1e-9;
3309
3311
  let cursor = -Infinity;
@@ -3317,7 +3319,7 @@ function knifePath(path, fillRule, knife) {
3317
3319
  const kb = { minX: Math.min(pts[m][0], pts[m + 1][0]), maxX: Math.max(pts[m][0], pts[m + 1][0]), minY: Math.min(pts[m][1], pts[m + 1][1]), maxY: Math.max(pts[m][1], pts[m + 1][1]) };
3318
3320
  face2.loops.forEach(
3319
3321
  (l, li) => l.segs.forEach((seg, si) => {
3320
- const sb = _chunk7EDLVBOOcjs.segmentBounds.call(void 0, seg);
3322
+ const sb = _chunkVNYRI265cjs.segmentBounds.call(void 0, seg);
3321
3323
  if (sb.maxX < kb.minX - eps || sb.minX > kb.maxX + eps || sb.maxY < kb.minY - eps || sb.minY > kb.maxY + eps) return;
3322
3324
  for (const h of lineHits(pts[m], pts[m + 1], seg)) {
3323
3325
  const s = m + h.s;
@@ -3332,7 +3334,7 @@ function knifePath(path, fillRule, knife) {
3332
3334
  const m = Math.min(pts.length - 2, Math.floor(s));
3333
3335
  const u = s - m;
3334
3336
  const q = [pts[m][0] + (pts[m + 1][0] - pts[m][0]) * u, pts[m][1] + (pts[m + 1][1] - pts[m][1]) * u];
3335
- return _chunk7EDLVBOOcjs.windingNumber.call(void 0, face2.loops.map((l) => l.segs), q) !== 0;
3337
+ return _chunkVNYRI265cjs.windingNumber.call(void 0, face2.loops.map((l) => l.segs), q) !== 0;
3336
3338
  };
3337
3339
  for (let i = 0; i < unique.length - 1; i++) {
3338
3340
  const from2 = unique[i];
@@ -3392,33 +3394,33 @@ function eraserRegion(points, width) {
3392
3394
  ];
3393
3395
  }
3394
3396
  const line2 = [{ type: "M", x: pts[0][0], y: pts[0][1] }, ...pts.slice(1).map((p) => ({ type: "L", x: p[0], y: p[1] }))];
3395
- return _chunk7EDLVBOOcjs.outlineStroke.call(void 0, line2, { width, cap: "round", join: "round" });
3397
+ return _chunkVNYRI265cjs.outlineStroke.call(void 0, line2, { width, cap: "round", join: "round" });
3396
3398
  }
3397
3399
  function eraseFromFill(path, fillRule, region) {
3398
- const overlap = _chunk7EDLVBOOcjs.pathBoolean.call(void 0, "intersection", [{ path, fillRule }, { path: region }]).path;
3399
- if (!_chunk7EDLVBOOcjs.pathToContours.call(void 0, overlap).some((c) => Math.abs(_chunk7EDLVBOOcjs.contourSignedArea.call(void 0, _chunk7EDLVBOOcjs.closeContour.call(void 0, c, true))) > 1e-9)) return null;
3400
- const rest = _chunk7EDLVBOOcjs.pathBoolean.call(void 0, "difference", [{ path, fillRule }, { path: region }]).path;
3400
+ const overlap = _chunkVNYRI265cjs.pathBoolean.call(void 0, "intersection", [{ path, fillRule }, { path: region }]).path;
3401
+ if (!_chunkVNYRI265cjs.pathToContours.call(void 0, overlap).some((c) => Math.abs(_chunkVNYRI265cjs.contourSignedArea.call(void 0, _chunkVNYRI265cjs.closeContour.call(void 0, c, true))) > 1e-9)) return null;
3402
+ const rest = _chunkVNYRI265cjs.pathBoolean.call(void 0, "difference", [{ path, fillRule }, { path: region }]).path;
3401
3403
  return splitIntoFaces(rest);
3402
3404
  }
3403
3405
  function eraseFromOutline(sp, region) {
3404
- const regionSegs = _chunk7EDLVBOOcjs.pathToContours.call(void 0, region).flatMap((c) => _chunk7EDLVBOOcjs.closeContour.call(void 0, c, true));
3406
+ const regionSegs = _chunkVNYRI265cjs.pathToContours.call(void 0, region).flatMap((c) => _chunkVNYRI265cjs.closeContour.call(void 0, c, true));
3405
3407
  if (!regionSegs.length) return null;
3406
- const rb = _chunk7EDLVBOOcjs.bezierPathBounds.call(void 0, region);
3408
+ const rb = _chunkVNYRI265cjs.bezierPathBounds.call(void 0, region);
3407
3409
  const count = subpathSegmentCount(sp);
3408
3410
  if (!rb || count === 0) return null;
3409
- const removed = (p) => _chunk7EDLVBOOcjs.pointInBezierPath.call(void 0, region, p, "nonzero");
3411
+ const removed = (p) => _chunkVNYRI265cjs.pointInBezierPath.call(void 0, region, p, "nonzero");
3410
3412
  const runs = [];
3411
3413
  let cur = [];
3412
3414
  let any = false;
3413
3415
  for (let i = 0; i < count; i++) {
3414
3416
  const seg = subpathSegment(sp, i);
3415
- const sb = _chunk7EDLVBOOcjs.segmentBounds.call(void 0, seg);
3417
+ const sb = _chunkVNYRI265cjs.segmentBounds.call(void 0, seg);
3416
3418
  const ts = [0, 1];
3417
3419
  if (!(sb.maxX < rb.minX || sb.minX > rb.maxX || sb.maxY < rb.minY || sb.minY > rb.maxY)) {
3418
3420
  for (const r of regionSegs) {
3419
- const b = _chunk7EDLVBOOcjs.segmentBounds.call(void 0, r);
3421
+ const b = _chunkVNYRI265cjs.segmentBounds.call(void 0, r);
3420
3422
  if (b.maxX < sb.minX || b.minX > sb.maxX || b.maxY < sb.minY || b.minY > sb.maxY) continue;
3421
- for (const hit of _chunk7EDLVBOOcjs.segmentIntersections.call(void 0, seg, r)) if (hit.ta > 1e-9 && hit.ta < 1 - 1e-9) ts.push(hit.ta);
3423
+ for (const hit of _chunkVNYRI265cjs.segmentIntersections.call(void 0, seg, r)) if (hit.ta > 1e-9 && hit.ta < 1 - 1e-9) ts.push(hit.ta);
3422
3424
  }
3423
3425
  }
3424
3426
  ts.sort((a, b) => a - b);
@@ -3426,7 +3428,7 @@ function eraseFromOutline(sp, region) {
3426
3428
  const t0 = ts[k];
3427
3429
  const t1 = ts[k + 1];
3428
3430
  if (t1 - t0 < 1e-9) continue;
3429
- if (removed(_chunk7EDLVBOOcjs.segmentPoint.call(void 0, seg, (t0 + t1) / 2))) {
3431
+ if (removed(_chunkVNYRI265cjs.segmentPoint.call(void 0, seg, (t0 + t1) / 2))) {
3430
3432
  any = true;
3431
3433
  if (cur.length) runs.push(cur);
3432
3434
  cur = [];
@@ -3445,7 +3447,7 @@ function eraseFromOutline(sp, region) {
3445
3447
  for (const run of runs) {
3446
3448
  const anchors = [];
3447
3449
  for (const { seg, t0, t1 } of run) {
3448
- const c = _chunk7EDLVBOOcjs.subSegment.call(void 0, subpathSegment(sp, seg), t0, t1);
3450
+ const c = _chunkVNYRI265cjs.subSegment.call(void 0, subpathSegment(sp, seg), t0, t1);
3449
3451
  const line2 = c.length === 2;
3450
3452
  const start = c[0];
3451
3453
  const end = c[c.length - 1];
@@ -3753,14 +3755,14 @@ function worldOf(entry, subpaths) {
3753
3755
  return vectorPathWorldBezier({ ...entry.node, subpaths }, entry.parent);
3754
3756
  }
3755
3757
  function subpathEnclosesArea(sp) {
3756
- const contour = _chunk7EDLVBOOcjs.pathToContours.call(void 0, subpathsToBezier([{ ...sp, closed: true }]))[0];
3758
+ const contour = _chunkVNYRI265cjs.pathToContours.call(void 0, subpathsToBezier([{ ...sp, closed: true }]))[0];
3757
3759
  if (!contour) return false;
3758
- const segs = _chunk7EDLVBOOcjs.closeContour.call(void 0, contour, true);
3759
- const b = _chunk7EDLVBOOcjs.bezierPathBounds.call(void 0, _chunk7EDLVBOOcjs.contoursToPath.call(void 0, [{ segments: segs, closed: true }]));
3760
+ const segs = _chunkVNYRI265cjs.closeContour.call(void 0, contour, true);
3761
+ const b = _chunkVNYRI265cjs.bezierPathBounds.call(void 0, _chunkVNYRI265cjs.contoursToPath.call(void 0, [{ segments: segs, closed: true }]));
3760
3762
  if (!b) return false;
3761
3763
  const w = b.maxX - b.minX;
3762
3764
  const h = b.maxY - b.minY;
3763
- return Math.abs(_chunk7EDLVBOOcjs.contourSignedArea.call(void 0, segs)) > 1e-9 * (w * w + h * h);
3765
+ return Math.abs(_chunkVNYRI265cjs.contourSignedArea.call(void 0, segs)) > 1e-9 * (w * w + h * h);
3764
3766
  }
3765
3767
  var paintKey = (paint) => typeof paint === "string" ? paint.trim().toLowerCase() : JSON.stringify(_nullishCoalesce(paint, () => ( null)));
3766
3768
  function vectorPathfinderShape(entry, op) {
@@ -3813,31 +3815,50 @@ function vectorShapeBuilderMap(entries) {
3813
3815
  lines.push(!subpaths.some((s) => s.closed));
3814
3816
  return { path: worldOf(entry, subpaths), fillRule: _nullishCoalesce(entry.node.fillRule, () => ( "nonzero")) };
3815
3817
  });
3816
- const map = _chunk7EDLVBOOcjs.PlanarMap.build(inputs);
3818
+ const map = _chunkVNYRI265cjs.PlanarMap.build(inputs);
3817
3819
  if (!map) return null;
3818
- const pieces = map.chains().filter((c) => lines[c.source] && !c.closed).map((c) => {
3819
- const path = _chunk7EDLVBOOcjs.contoursToPath.call(void 0, [{ segments: c.segments, closed: false }]);
3820
- return { path, segments: c.segments, source: c.source, bounds: _chunk7EDLVBOOcjs.bezierPathBounds.call(void 0, path) };
3820
+ let chains = null;
3821
+ const runs = (line2) => (chains ??= map.chains()).filter((c) => lines[c.source] === line2 && !(line2 && c.closed)).map((c) => {
3822
+ const path = _chunkVNYRI265cjs.contoursToPath.call(void 0, [{ segments: c.segments, closed: c.closed }]);
3823
+ return { path, segments: c.segments, closed: c.closed, source: c.source, bounds: _chunkVNYRI265cjs.bezierPathBounds.call(void 0, path) };
3821
3824
  });
3822
- return { entries: [...entries], map, lines, pieces };
3825
+ const pieces = lines.some(Boolean) ? runs(true) : [];
3826
+ let edges = null;
3827
+ let size = 0;
3828
+ for (const input of inputs) {
3829
+ const b = _chunkVNYRI265cjs.bezierPathBounds.call(void 0, input.path);
3830
+ if (b) size = Math.max(size, b.maxX - b.minX, b.maxY - b.minY);
3831
+ }
3832
+ return {
3833
+ entries: [...entries],
3834
+ map,
3835
+ lines,
3836
+ pieces,
3837
+ get edges() {
3838
+ return edges ??= runs(false);
3839
+ },
3840
+ tolerance: 0.2 * Math.max(size / 2e3, 0.25)
3841
+ };
3823
3842
  }
3824
- function vectorShapeBuilderHit(m, p, lineTolerance = null) {
3843
+ function pieceNear(pieces, p, tol) {
3825
3844
  const point = [p.x, p.y];
3845
+ let best = null;
3846
+ pieces.forEach((piece, index) => {
3847
+ const b = piece.bounds;
3848
+ if (p.x < b.minX - tol || p.x > b.maxX + tol || p.y < b.minY - tol || p.y > b.maxY + tol) return;
3849
+ const d = _chunkVNYRI265cjs.distanceToBezierPath.call(void 0, piece.path, point);
3850
+ if (d <= tol && (!best || d < best.d)) best = { index, d };
3851
+ });
3852
+ return best;
3853
+ }
3854
+ function vectorShapeBuilderHit(m, p, lineTolerance = null) {
3826
3855
  if (lineTolerance !== null && lineTolerance > 0) {
3827
- let best = -1;
3828
- let bestD = lineTolerance;
3829
- m.pieces.forEach((piece, i) => {
3830
- const b = piece.bounds;
3831
- if (p.x < b.minX - bestD || p.x > b.maxX + bestD || p.y < b.minY - bestD || p.y > b.maxY + bestD) return;
3832
- const d = _chunk7EDLVBOOcjs.distanceToBezierPath.call(void 0, piece.path, point);
3833
- if (d <= bestD) {
3834
- best = i;
3835
- bestD = d;
3836
- }
3837
- });
3838
- if (best >= 0) return { line: best };
3856
+ const line2 = pieceNear(m.pieces, p, lineTolerance);
3857
+ const edge = pieceNear(m.edges, p, lineTolerance);
3858
+ if (edge && (!line2 || edge.d < line2.d)) return { edge: edge.index };
3859
+ if (line2) return { line: line2.index };
3839
3860
  }
3840
- const face = m.map.faceAt(point);
3861
+ const face = m.map.faceAt([p.x, p.y]);
3841
3862
  return face >= 0 ? { face } : null;
3842
3863
  }
3843
3864
  function samplePolyline(points, step) {
@@ -3855,25 +3876,31 @@ function samplePolyline(points, step) {
3855
3876
  }
3856
3877
  function addBuilderHit(touched, hit) {
3857
3878
  if (!hit) return false;
3858
- const [list, i] = "face" in hit ? [touched.faces, hit.face] : [touched.lines, hit.line];
3879
+ const [list, i] = "face" in hit ? [touched.faces, hit.face] : "line" in hit ? [touched.lines, hit.line] : [touched.edges, hit.edge];
3859
3880
  if (list.includes(i)) return false;
3860
3881
  list.push(i);
3861
3882
  return true;
3862
3883
  }
3863
3884
  function sides(m, piece) {
3864
3885
  const seg = piece.segments[Math.floor(piece.segments.length / 2)];
3865
- const mid = _chunk7EDLVBOOcjs.segmentPoint.call(void 0, seg, 0.5);
3866
- const t = _chunk7EDLVBOOcjs.segmentTangent.call(void 0, seg, 0.5);
3886
+ const mid = _chunkVNYRI265cjs.segmentPoint.call(void 0, seg, 0.5);
3887
+ const t = _chunkVNYRI265cjs.segmentTangent.call(void 0, seg, 0.5);
3867
3888
  const chord = Math.hypot(seg[seg.length - 1][0] - seg[0][0], seg[seg.length - 1][1] - seg[0][1]);
3868
3889
  const off = Math.max(1e-6, Math.min(0.05, 0.05 * chord));
3869
3890
  return [m.map.faceAt([mid[0] - t[1] * off, mid[1] + t[0] * off]), m.map.faceAt([mid[0] + t[1] * off, mid[1] - t[0] * off])];
3870
3891
  }
3892
+ function vectorBuilderErasedEdges(m, touched) {
3893
+ if (!touched.edges.length) return [];
3894
+ const faces = new Set(touched.faces);
3895
+ return touched.edges.filter((k) => m.edges[k] && !sides(m, m.edges[k]).some((f) => f >= 0 && faces.has(f)));
3896
+ }
3871
3897
  function planShapeBuilder(m, touched, erase) {
3872
3898
  const replace = /* @__PURE__ */ new Map();
3873
3899
  const picked = new Set(touched.faces);
3874
3900
  const faces = m.map.faces;
3875
3901
  const sourcesOf = faces.map((_, i) => m.map.faceSources(i));
3876
- m.entries.forEach((_, i) => {
3902
+ const cuts = erase ? vectorBuilderErasedEdges(m, touched).map((k) => m.edges[k]) : [];
3903
+ m.entries.forEach((entry, i) => {
3877
3904
  if (m.lines[i]) {
3878
3905
  const own = m.pieces.flatMap((piece, k) => piece.source === i ? [k] : []);
3879
3906
  const keep = own.filter((k) => !touched.lines.includes(k) && !sides(m, m.pieces[k]).every((f) => f >= 0 && picked.has(f)));
@@ -3881,10 +3908,24 @@ function planShapeBuilder(m, touched, erase) {
3881
3908
  replace.set(i, keep.length ? { kind: "pieces", paths: keep.map((k) => m.pieces[k].path) } : null);
3882
3909
  return;
3883
3910
  }
3884
- if (!touched.faces.some((f) => sourcesOf[f].includes(i))) return;
3885
- const kept = faces.flatMap((_2, f) => sourcesOf[f].includes(i) && !picked.has(f) ? [f] : []);
3886
- const rest = kept.length ? m.map.merge(kept) : [];
3887
- replace.set(i, rest.length ? { kind: "fill", path: rest } : null);
3911
+ const inUnion = touched.faces.some((f) => sourcesOf[f].includes(i));
3912
+ if (!inUnion && !cuts.length) return;
3913
+ let rest;
3914
+ if (inUnion) {
3915
+ const kept = faces.flatMap((_, f) => sourcesOf[f].includes(i) && !picked.has(f) ? [f] : []);
3916
+ rest = kept.length ? m.map.merge(kept) : [];
3917
+ } else rest = worldOf(entry, entry.node.subpaths.filter(usable));
3918
+ const fillCloses = hasPaint(entry.node.fill);
3919
+ let cut = false;
3920
+ for (const piece of cuts) {
3921
+ const r = rest.length ? _chunkVNYRI265cjs.cutOutPiece.call(void 0, rest, piece, fillCloses, m.tolerance) : null;
3922
+ if (r) {
3923
+ rest = r;
3924
+ cut = true;
3925
+ }
3926
+ }
3927
+ if (!inUnion && !cut) return;
3928
+ replace.set(i, rest.length ? { kind: inUnion ? "fill" : "outline", path: rest } : null);
3888
3929
  });
3889
3930
  let merged = null;
3890
3931
  if (!erase && touched.faces.length) {
@@ -3898,7 +3939,7 @@ function planShapeBuilder(m, touched, erase) {
3898
3939
  }
3899
3940
  function vectorFillMap(doc, gap = 0) {
3900
3941
  const entries = vectorPathEntries(doc, null, { locked: true });
3901
- return _chunk7EDLVBOOcjs.PlanarMap.build(
3942
+ return _chunkVNYRI265cjs.PlanarMap.build(
3902
3943
  entries.map((e) => ({ path: worldOf(e, e.node.subpaths.filter(usable)), fills: false })),
3903
3944
  { gap, maxSegments: 2e4 }
3904
3945
  );
@@ -3960,7 +4001,7 @@ function getEditablePathIds(state) {
3960
4001
  }
3961
4002
  }
3962
4003
  }
3963
- return [...ids].filter((id) => _optionalChain([findVectorNode, 'call', _63 => _63(state.document.nodes, id), 'optionalAccess', _64 => _64.type]) === "path");
4004
+ return [...ids].filter((id) => _optionalChain([findVectorNode, 'call', _62 => _62(state.document.nodes, id), 'optionalAccess', _63 => _63.type]) === "path");
3964
4005
  }
3965
4006
  function getVisibleAnchors(state) {
3966
4007
  const out = [];
@@ -3975,7 +4016,7 @@ function getVisibleHandles(state) {
3975
4016
  const seen = /* @__PURE__ */ new Set();
3976
4017
  const push = (node, s, i, handle) => {
3977
4018
  const sp = node.subpaths[s];
3978
- const a = _optionalChain([sp, 'optionalAccess', _65 => _65.anchors, 'access', _66 => _66[i]]);
4019
+ const a = _optionalChain([sp, 'optionalAccess', _64 => _64.anchors, 'access', _65 => _65[i]]);
3979
4020
  if (!a || !a[handle]) return;
3980
4021
  const key = `${node.id}:${s}:${i}:${handle}`;
3981
4022
  if (seen.has(key)) return;
@@ -3984,8 +4025,8 @@ function getVisibleHandles(state) {
3984
4025
  };
3985
4026
  if (state.tool === "pen" && state.pen) {
3986
4027
  const node = findVectorNode(state.document.nodes, state.pen.nodeId);
3987
- const sp = _optionalChain([node, 'optionalAccess', _67 => _67.type]) === "path" ? node.subpaths[state.pen.subpath] : void 0;
3988
- if (_optionalChain([node, 'optionalAccess', _68 => _68.type]) === "path" && sp) {
4028
+ const sp = _optionalChain([node, 'optionalAccess', _66 => _66.type]) === "path" ? node.subpaths[state.pen.subpath] : void 0;
4029
+ if (_optionalChain([node, 'optionalAccess', _67 => _67.type]) === "path" && sp) {
3989
4030
  const last = sp.anchors.length - 1;
3990
4031
  push(node, state.pen.subpath, last, "in");
3991
4032
  push(node, state.pen.subpath, last, "out");
@@ -4023,11 +4064,11 @@ function getVectorCornerWidgets(state) {
4023
4064
  const side = Math.min(c.lu, c.lv);
4024
4065
  if (side * zoom < 3 * VECTOR_CORNER_WIDGET_INSET) continue;
4025
4066
  const a = node.subpaths[c.subpath].anchors[c.index];
4026
- const radius = _nullishCoalesce(_optionalChain([a, 'access', _69 => _69.corner, 'optionalAccess', _70 => _70.radius]), () => ( 0));
4067
+ const radius = _nullishCoalesce(_optionalChain([a, 'access', _68 => _68.corner, 'optionalAccess', _69 => _69.radius]), () => ( 0));
4027
4068
  const drawn = fitCornerRadius(c, radius);
4028
4069
  const k = Math.min(Math.max(drawn / c.sin, VECTOR_CORNER_WIDGET_INSET / (zoom * Math.sqrt(1 + c.cos))), side / 2);
4029
4070
  const p = applyMatrix(m, cornerBisectorPoint(c, k));
4030
- out.push({ ref: { nodeId: id, subpath: c.subpath, index: c.index }, x: p.x, y: p.y, radius, drawnRadius: drawn, kind: _nullishCoalesce(_optionalChain([a, 'access', _71 => _71.corner, 'optionalAccess', _72 => _72.kind]), () => ( "round")), corner: c });
4071
+ out.push({ ref: { nodeId: id, subpath: c.subpath, index: c.index }, x: p.x, y: p.y, radius, drawnRadius: drawn, kind: _nullishCoalesce(_optionalChain([a, 'access', _70 => _70.corner, 'optionalAccess', _71 => _71.kind]), () => ( "round")), corner: c });
4031
4072
  }
4032
4073
  }
4033
4074
  return out;
@@ -4044,13 +4085,13 @@ function getVectorWidthHandles(state) {
4044
4085
  const n = findVectorNode(state.document.nodes, id);
4045
4086
  if (n) for (const p of collectPathNodes(n)) ids.add(p.id);
4046
4087
  }
4047
- if (_optionalChain([state, 'access', _73 => _73.hover, 'optionalAccess', _74 => _74.nodeId])) ids.add(state.hover.nodeId);
4048
- if (_optionalChain([state, 'access', _75 => _75.interaction, 'optionalAccess', _76 => _76.type]) === "width") ids.add(state.interaction.ref.nodeId);
4088
+ if (_optionalChain([state, 'access', _72 => _72.hover, 'optionalAccess', _73 => _73.nodeId])) ids.add(state.hover.nodeId);
4089
+ if (_optionalChain([state, 'access', _74 => _74.interaction, 'optionalAccess', _75 => _75.type]) === "width") ids.add(state.interaction.ref.nodeId);
4049
4090
  if (state.selectedWidthPoint) ids.add(state.selectedWidthPoint.nodeId);
4050
4091
  const out = [];
4051
4092
  for (const id of ids) {
4052
4093
  const node = findVectorNode(state.document.nodes, id);
4053
- if (_optionalChain([node, 'optionalAccess', _77 => _77.type]) !== "path" || node.visible === false || !_optionalChain([node, 'access', _78 => _78.strokeWidthProfile, 'optionalAccess', _79 => _79.length])) continue;
4094
+ if (_optionalChain([node, 'optionalAccess', _76 => _76.type]) !== "path" || node.visible === false || !_optionalChain([node, 'access', _77 => _77.strokeWidthProfile, 'optionalAccess', _78 => _78.length])) continue;
4054
4095
  const g = vectorStrokeWidthGeometry(node);
4055
4096
  if (!g) continue;
4056
4097
  const profile = sanitizeWidthProfile(node.strokeWidthProfile);
@@ -4084,7 +4125,7 @@ function getVectorWidthHandles(state) {
4084
4125
  }
4085
4126
  function getAnchor(doc, ref) {
4086
4127
  const node = findVectorNode(doc.nodes, ref.nodeId);
4087
- return _optionalChain([node, 'optionalAccess', _80 => _80.type]) === "path" ? _optionalChain([node, 'access', _81 => _81.subpaths, 'access', _82 => _82[ref.subpath], 'optionalAccess', _83 => _83.anchors, 'access', _84 => _84[ref.index]]) : void 0;
4128
+ return _optionalChain([node, 'optionalAccess', _79 => _79.type]) === "path" ? _optionalChain([node, 'access', _80 => _80.subpaths, 'access', _81 => _81[ref.subpath], 'optionalAccess', _82 => _82.anchors, 'access', _83 => _83[ref.index]]) : void 0;
4088
4129
  }
4089
4130
  function getAnchorWorld(doc, ref) {
4090
4131
  const a = getAnchor(doc, ref);
@@ -4383,7 +4424,7 @@ var VectorEditorController = (_class3 = class {
4383
4424
  notify(docChanged = false) {
4384
4425
  this.revision++;
4385
4426
  this.state = this.computeState();
4386
- if (docChanged) _optionalChain([this, 'access', _85 => _85.onChange, 'optionalCall', _86 => _86(this.doc)]);
4427
+ if (docChanged) _optionalChain([this, 'access', _84 => _84.onChange, 'optionalCall', _85 => _85(this.doc)]);
4387
4428
  const state = this.state;
4388
4429
  this.listeners.forEach((listener) => {
4389
4430
  try {
@@ -4413,26 +4454,26 @@ var VectorEditorController = (_class3 = class {
4413
4454
  return applyMatrix(invertMatrix(this.worldOf(id, doc)), p);
4414
4455
  }
4415
4456
  cursorFor() {
4416
- if (_optionalChain([this, 'access', _87 => _87.drag, 'optionalAccess', _88 => _88.kind]) === "pan" || this.spaceHeld) return this.drag ? "grabbing" : "grab";
4417
- if (_optionalChain([this, 'access', _89 => _89.drag, 'optionalAccess', _90 => _90.kind]) === "rotate") return "grabbing";
4418
- if (_optionalChain([this, 'access', _91 => _91.drag, 'optionalAccess', _92 => _92.kind]) === "move") return "move";
4457
+ if (_optionalChain([this, 'access', _86 => _86.drag, 'optionalAccess', _87 => _87.kind]) === "pan" || this.spaceHeld) return this.drag ? "grabbing" : "grab";
4458
+ if (_optionalChain([this, 'access', _88 => _88.drag, 'optionalAccess', _89 => _89.kind]) === "rotate") return "grabbing";
4459
+ if (_optionalChain([this, 'access', _90 => _90.drag, 'optionalAccess', _91 => _91.kind]) === "move") return "move";
4419
4460
  const h = this.hover;
4420
4461
  switch (this.tool) {
4421
4462
  case "select":
4422
- if (_optionalChain([h, 'optionalAccess', _93 => _93.transformHandle])) return vectorResizeCursor(h.transformHandle, _nullishCoalesce(_optionalChain([this, 'access', _94 => _94.frameOf, 'call', _95 => _95(this.selectedRoots()), 'optionalAccess', _96 => _96.angle]), () => ( 0)));
4423
- return _optionalChain([h, 'optionalAccess', _97 => _97.nodeId]) ? "move" : "default";
4463
+ if (_optionalChain([h, 'optionalAccess', _92 => _92.transformHandle])) return vectorResizeCursor(h.transformHandle, _nullishCoalesce(_optionalChain([this, 'access', _93 => _93.frameOf, 'call', _94 => _94(this.selectedRoots()), 'optionalAccess', _95 => _95.angle]), () => ( 0)));
4464
+ return _optionalChain([h, 'optionalAccess', _96 => _96.nodeId]) ? "move" : "default";
4424
4465
  case "direct":
4425
- if (_optionalChain([h, 'optionalAccess', _98 => _98.anchor]) || _optionalChain([h, 'optionalAccess', _99 => _99.handle]) || _optionalChain([h, 'optionalAccess', _100 => _100.corner])) return "pointer";
4426
- if (_optionalChain([h, 'optionalAccess', _101 => _101.segment])) return "copy";
4427
- return _optionalChain([h, 'optionalAccess', _102 => _102.nodeId]) ? "move" : "default";
4466
+ if (_optionalChain([h, 'optionalAccess', _97 => _97.anchor]) || _optionalChain([h, 'optionalAccess', _98 => _98.handle]) || _optionalChain([h, 'optionalAccess', _99 => _99.corner])) return "pointer";
4467
+ if (_optionalChain([h, 'optionalAccess', _100 => _100.segment])) return "copy";
4468
+ return _optionalChain([h, 'optionalAccess', _101 => _101.nodeId]) ? "move" : "default";
4428
4469
  case "pen":
4429
- return _optionalChain([h, 'optionalAccess', _103 => _103.anchor]) ? "pointer" : "crosshair";
4470
+ return _optionalChain([h, 'optionalAccess', _102 => _102.anchor]) ? "pointer" : "crosshair";
4430
4471
  case "width":
4431
- if (_optionalChain([this, 'access', _104 => _104.drag, 'optionalAccess', _105 => _105.kind]) === "width") return this.drag.mode === "move" ? "grabbing" : "ew-resize";
4432
- if (_optionalChain([h, 'optionalAccess', _106 => _106.widthPoint])) return h.widthPoint.part === "center" ? "grab" : "ew-resize";
4433
- return _optionalChain([h, 'optionalAccess', _107 => _107.strokeSpot]) ? "copy" : "default";
4472
+ if (_optionalChain([this, 'access', _103 => _103.drag, 'optionalAccess', _104 => _104.kind]) === "width") return this.drag.mode === "move" ? "grabbing" : "ew-resize";
4473
+ if (_optionalChain([h, 'optionalAccess', _105 => _105.widthPoint])) return h.widthPoint.part === "center" ? "grab" : "ew-resize";
4474
+ return _optionalChain([h, 'optionalAccess', _106 => _106.strokeSpot]) ? "copy" : "default";
4434
4475
  case "shapeBuilder":
4435
- if (!_optionalChain([this, 'access', _108 => _108.builderPreview, 'optionalAccess', _109 => _109.faces, 'access', _110 => _110.length]) && !_optionalChain([this, 'access', _111 => _111.builderPreview, 'optionalAccess', _112 => _112.lines, 'access', _113 => _113.length])) return "crosshair";
4476
+ if (!_optionalChain([this, 'access', _107 => _107.builderPreview, 'optionalAccess', _108 => _108.faces, 'access', _109 => _109.length]) && !_optionalChain([this, 'access', _110 => _110.builderPreview, 'optionalAccess', _111 => _111.lines, 'access', _112 => _112.length])) return "crosshair";
4436
4477
  return this.builderPreview.mode === "erase" ? "not-allowed" : "cell";
4437
4478
  case "paintBucket":
4438
4479
  return this.builderPreview ? "cell" : "crosshair";
@@ -4455,7 +4496,7 @@ var VectorEditorController = (_class3 = class {
4455
4496
  this.selection = s.selection.filter((id) => this.getNode(id));
4456
4497
  this.anchors = s.anchors.filter((r) => getAnchor(this.doc, r));
4457
4498
  this.editingId = s.editingId && this.getNode(s.editingId) ? s.editingId : null;
4458
- this.pen = s.pen && _optionalChain([this, 'access', _114 => _114.getNode, 'call', _115 => _115(s.pen.nodeId), 'optionalAccess', _116 => _116.subpaths, 'optionalAccess', _117 => _117[s.pen.subpath]]) ? s.pen : null;
4499
+ this.pen = s.pen && _optionalChain([this, 'access', _113 => _113.getNode, 'call', _114 => _114(s.pen.nodeId), 'optionalAccess', _115 => _115.subpaths, 'optionalAccess', _116 => _116[s.pen.subpath]]) ? s.pen : null;
4459
4500
  } finally {
4460
4501
  this.applying = false;
4461
4502
  }
@@ -4622,7 +4663,7 @@ var VectorEditorController = (_class3 = class {
4622
4663
  if (res.kind) {
4623
4664
  this.snappedToObject = true;
4624
4665
  this.setGuides(res);
4625
- return _optionalChain([leave, 'optionalAccess', _118 => _118.constrain]) ? res.point : { x: res.x ? res.point.x : this.gridValue(res.point.x), y: res.y ? res.point.y : this.gridValue(res.point.y) };
4666
+ return _optionalChain([leave, 'optionalAccess', _117 => _117.constrain]) ? res.point : { x: res.x ? res.point.x : this.gridValue(res.point.x), y: res.y ? res.point.y : this.gridValue(res.point.y) };
4626
4667
  }
4627
4668
  }
4628
4669
  this.setGuides(null);
@@ -4640,14 +4681,14 @@ var VectorEditorController = (_class3 = class {
4640
4681
  /** Where the pointer at `p` would place a point with the pen or a shape tool (and the guides showing why). */
4641
4682
  hoverSnap(p, input) {
4642
4683
  if (this.tool === "pen") {
4643
- const sp = this.pen ? _optionalChain([this, 'access', _119 => _119.getNode, 'call', _120 => _120(this.pen.nodeId), 'optionalAccess', _121 => _121.subpaths, 'access', _122 => _122[this.pen.subpath]]) : void 0;
4644
- if (this.pen && sp && _optionalChain([this, 'access', _123 => _123.hover, 'optionalAccess', _124 => _124.anchor])) {
4684
+ const sp = this.pen ? _optionalChain([this, 'access', _118 => _118.getNode, 'call', _119 => _119(this.pen.nodeId), 'optionalAccess', _120 => _120.subpaths, 'access', _121 => _121[this.pen.subpath]]) : void 0;
4685
+ if (this.pen && sp && _optionalChain([this, 'access', _122 => _122.hover, 'optionalAccess', _123 => _123.anchor])) {
4645
4686
  this.setGuides(null);
4646
4687
  return p;
4647
4688
  }
4648
4689
  const last = this.pen && sp ? getAnchorWorld(this.doc, { nodeId: this.pen.nodeId, subpath: this.pen.subpath, index: sp.anchors.length - 1 }) : void 0;
4649
4690
  const leave = last ? { at: { x: last.x, y: last.y }, constrain: input.shift ? "angle" : null } : null;
4650
- return this.snapDrawn(p, leave, input, () => this.drawingTargets(_nullishCoalesce(_optionalChain([this, 'access', _125 => _125.pen, 'optionalAccess', _126 => _126.nodeId]), () => ( null))));
4691
+ return this.snapDrawn(p, leave, input, () => this.drawingTargets(_nullishCoalesce(_optionalChain([this, 'access', _124 => _124.pen, 'optionalAccess', _125 => _125.nodeId]), () => ( null))));
4651
4692
  }
4652
4693
  if (SHAPE_TOOLS.has(this.tool)) return this.snapDrawn(p, null, input, () => this.drawingTargets(null));
4653
4694
  this.setGuides(null);
@@ -4795,7 +4836,7 @@ var VectorEditorController = (_class3 = class {
4795
4836
  if (d.fillRule) out.fillRule = d.fillRule;
4796
4837
  if (d.strokeAlign && d.strokeAlign !== "center") out.strokeAlign = d.strokeAlign;
4797
4838
  for (const key of ["startArrow", "endArrow", "arrowAlign", "startArrowScale", "endArrowScale"]) if (d[key]) out[key] = d[key];
4798
- if (_optionalChain([d, 'access', _127 => _127.strokeWidthProfile, 'optionalAccess', _128 => _128.length])) out.strokeWidthProfile = d.strokeWidthProfile.map((p) => ({ ...p }));
4839
+ if (_optionalChain([d, 'access', _126 => _126.strokeWidthProfile, 'optionalAccess', _127 => _127.length])) out.strokeWidthProfile = d.strokeWidthProfile.map((p) => ({ ...p }));
4799
4840
  return out;
4800
4841
  }
4801
4842
  /** Merges `patch` into a node (paths take style and geometry; groups name / visibility / opacity). */
@@ -4843,7 +4884,7 @@ var VectorEditorController = (_class3 = class {
4843
4884
  /** Removes one width point of a path's profile (the width tool's Delete). */
4844
4885
  removeWidthPoint(ref) {
4845
4886
  const node = this.getNode(ref.nodeId);
4846
- if (_optionalChain([node, 'optionalAccess', _129 => _129.type]) !== "path" || !_optionalChain([node, 'access', _130 => _130.strokeWidthProfile, 'optionalAccess', _131 => _131[ref.index]])) return { ok: false, message: "There is no such width point." };
4887
+ if (_optionalChain([node, 'optionalAccess', _128 => _128.type]) !== "path" || !_optionalChain([node, 'access', _129 => _129.strokeWidthProfile, 'optionalAccess', _130 => _130[ref.index]])) return { ok: false, message: "There is no such width point." };
4847
4888
  const rest = removeWidthPoints(sanitizeWidthProfile(node.strokeWidthProfile), [ref.index]);
4848
4889
  this.widthPoint = null;
4849
4890
  this.change("Delete Width Point", () => this.replaceNode(node.id, withStyle(node, { strokeWidthProfile: rest.length ? rest : null })));
@@ -4868,7 +4909,7 @@ var VectorEditorController = (_class3 = class {
4868
4909
  const refs = this.cornerTargets(options);
4869
4910
  if (!refs.length) return { ok: false, message: "Nothing is selected." };
4870
4911
  this.change("Corner Kind", () => {
4871
- this.doc = this.updateAnchors(this.doc, refs, (a) => setAnchorCorner(a, _nullishCoalesce(_optionalChain([a, 'access', _132 => _132.corner, 'optionalAccess', _133 => _133.radius]), () => ( 0)), kind));
4912
+ this.doc = this.updateAnchors(this.doc, refs, (a) => setAnchorCorner(a, _nullishCoalesce(_optionalChain([a, 'access', _131 => _131.corner, 'optionalAccess', _132 => _132.radius]), () => ( 0)), kind));
4872
4913
  });
4873
4914
  return { ok: true };
4874
4915
  }
@@ -5007,10 +5048,10 @@ var VectorEditorController = (_class3 = class {
5007
5048
  return this.selection.filter((id) => {
5008
5049
  let covered = false;
5009
5050
  const loc = locateVectorNode(this.doc.nodes, id);
5010
- let parent = _nullishCoalesce(_optionalChain([loc, 'optionalAccess', _134 => _134.parent]), () => ( null));
5051
+ let parent = _nullishCoalesce(_optionalChain([loc, 'optionalAccess', _133 => _133.parent]), () => ( null));
5011
5052
  while (parent) {
5012
5053
  if (this.selection.includes(parent.id)) covered = true;
5013
- parent = _nullishCoalesce(_optionalChain([locateVectorNode, 'call', _135 => _135(this.doc.nodes, parent.id), 'optionalAccess', _136 => _136.parent]), () => ( null));
5054
+ parent = _nullishCoalesce(_optionalChain([locateVectorNode, 'call', _134 => _134(this.doc.nodes, parent.id), 'optionalAccess', _135 => _135.parent]), () => ( null));
5014
5055
  }
5015
5056
  return !covered;
5016
5057
  });
@@ -5193,8 +5234,8 @@ var VectorEditorController = (_class3 = class {
5193
5234
  if (!ids.length) return null;
5194
5235
  const locs = ids.map((id2) => locateVectorNode(this.doc.nodes, id2));
5195
5236
  if (locs.some((l) => !l)) return null;
5196
- const parent = _nullishCoalesce(_optionalChain([locs, 'access', _137 => _137[0], 'access', _138 => _138.parent, 'optionalAccess', _139 => _139.id]), () => ( null));
5197
- if (locs.some((l) => (_nullishCoalesce(_optionalChain([l, 'access', _140 => _140.parent, 'optionalAccess', _141 => _141.id]), () => ( null))) !== parent)) return null;
5237
+ const parent = _nullishCoalesce(_optionalChain([locs, 'access', _136 => _136[0], 'access', _137 => _137.parent, 'optionalAccess', _138 => _138.id]), () => ( null));
5238
+ if (locs.some((l) => (_nullishCoalesce(_optionalChain([l, 'access', _139 => _139.parent, 'optionalAccess', _140 => _140.id]), () => ( null))) !== parent)) return null;
5198
5239
  const id = this.newId();
5199
5240
  this.change("Group", () => {
5200
5241
  const set = new Set(ids);
@@ -5217,7 +5258,7 @@ var VectorEditorController = (_class3 = class {
5217
5258
  }
5218
5259
  /** Replaces selected groups with their children. */
5219
5260
  ungroup(options = {}) {
5220
- const groups = (_nullishCoalesce(options.ids, () => ( this.selection))).map((id) => this.getNode(id)).filter((n) => _optionalChain([n, 'optionalAccess', _142 => _142.type]) === "group");
5261
+ const groups = (_nullishCoalesce(options.ids, () => ( this.selection))).map((id) => this.getNode(id)).filter((n) => _optionalChain([n, 'optionalAccess', _141 => _141.type]) === "group");
5221
5262
  if (!groups.length) return { ok: false, message: "Select a group to ungroup." };
5222
5263
  const set = new Set(groups.map((g) => g.id));
5223
5264
  this.change("Ungroup", () => {
@@ -5277,7 +5318,7 @@ var VectorEditorController = (_class3 = class {
5277
5318
  });
5278
5319
  const paths = [...new Set(order)].map((id2) => this.getNode(id2));
5279
5320
  if (paths.length < 2) return null;
5280
- const result = _chunk7EDLVBOOcjs.pathBoolean.call(void 0,
5321
+ const result = _chunkVNYRI265cjs.pathBoolean.call(void 0,
5281
5322
  BOOLEAN_OPS[op],
5282
5323
  paths.map((p) => ({
5283
5324
  path: vectorPathWorldBezier(
@@ -5327,11 +5368,11 @@ var VectorEditorController = (_class3 = class {
5327
5368
  /** A document-space path mapped into the parent space of node `id`. */
5328
5369
  intoParentSpace(id, path) {
5329
5370
  const parent = _nullishCoalesce(vectorParentMatrix(this.doc.nodes, id), () => ( IDENTITY_MATRIX));
5330
- return isRoot(parent) ? path : _chunk7EDLVBOOcjs.transformBezierPath.call(void 0, path, invertMatrix(parent));
5371
+ return isRoot(parent) ? path : _chunkVNYRI265cjs.transformBezierPath.call(void 0, path, invertMatrix(parent));
5331
5372
  }
5332
5373
  /** Splits selected compound paths into one path per subpath. */
5333
5374
  breakApart(options = {}) {
5334
- const paths = (_nullishCoalesce(options.ids, () => ( this.selection))).map((id) => this.getNode(id)).filter((n) => _optionalChain([n, 'optionalAccess', _143 => _143.type]) === "path" && n.subpaths.length > 1);
5375
+ const paths = (_nullishCoalesce(options.ids, () => ( this.selection))).map((id) => this.getNode(id)).filter((n) => _optionalChain([n, 'optionalAccess', _142 => _142.type]) === "path" && n.subpaths.length > 1);
5335
5376
  if (!paths.length) return { ok: false, message: "Select a compound path to break apart." };
5336
5377
  const created = [];
5337
5378
  const set = new Set(paths.map((p) => p.id));
@@ -5366,7 +5407,7 @@ var VectorEditorController = (_class3 = class {
5366
5407
  const entries = vectorPathEntries(this.doc, roots);
5367
5408
  if (entries.length < (op === "divide" || op === "outline" ? 1 : 2)) return [];
5368
5409
  const shapes = entries.map((e) => vectorPathfinderShape(e, op));
5369
- const result = _chunk7EDLVBOOcjs.pathfinder.call(void 0, op, shapes);
5410
+ const result = _chunkVNYRI265cjs.pathfinder.call(void 0, op, shapes);
5370
5411
  if (result.error || !result.pieces.length) return [];
5371
5412
  const last = entries[entries.length - 1].node.id;
5372
5413
  const topRoot = _nullishCoalesce([...roots].reverse().find((r) => {
@@ -5397,7 +5438,7 @@ var VectorEditorController = (_class3 = class {
5397
5438
  shapeBuilderMap(ids) {
5398
5439
  const roots = _nullishCoalesce(ids, () => ( this.selectedRoots()));
5399
5440
  const key = roots.join("\0");
5400
- if (_optionalChain([this, 'access', _144 => _144.builderCache, 'optionalAccess', _145 => _145.doc]) === this.doc && this.builderCache.key === key) return this.builderCache.map;
5441
+ if (_optionalChain([this, 'access', _143 => _143.builderCache, 'optionalAccess', _144 => _144.doc]) === this.doc && this.builderCache.key === key) return this.builderCache.map;
5401
5442
  const entries = roots.length ? vectorPathEntries(this.doc, roots) : [];
5402
5443
  const map = entries.length ? vectorShapeBuilderMap(entries) : null;
5403
5444
  this.builderCache = { doc: this.doc, key, map };
@@ -5411,7 +5452,7 @@ var VectorEditorController = (_class3 = class {
5411
5452
  const p = m.map.faceInterior(index);
5412
5453
  return {
5413
5454
  index,
5414
- d: _chunk7EDLVBOOcjs.bezierPathToSvg.call(void 0, f.path, { precision: 3 }),
5455
+ d: _chunkVNYRI265cjs.bezierPathToSvg.call(void 0, f.path, { precision: 3 }),
5415
5456
  area: f.area,
5416
5457
  sources: m.map.faceSources(index).map((i) => m.entries[i].node.id),
5417
5458
  point: p ? { x: p[0], y: p[1] } : null
@@ -5426,20 +5467,23 @@ var VectorEditorController = (_class3 = class {
5426
5467
  * Shape Builder gesture along `points` (document units; one point is a click) over the faces
5427
5468
  * the selected (or given) paths make. Merges the faces touched into one shape styled like the
5428
5469
  * top-most shape over the first face (the current fill for a face only outlines enclose);
5429
- * with `erase` deletes them, and the pieces of unfilled open paths within `tolerance`. Every
5430
- * shape covering a touched face loses that area. One undo step.
5470
+ * with `erase` deletes them, the pieces of unfilled open paths and the edges of other outlines
5471
+ * (cut where paths meet) within `tolerance`: a deleted edge opens a closed subpath there,
5472
+ * splits an open one or takes a subpath it runs all the way round, and edges bounding a face
5473
+ * deleted in the same gesture go with the face. Every shape covering a touched face loses
5474
+ * that area; paths keep their own transforms. One undo step.
5431
5475
  */
5432
5476
  shapeBuilder(points, options = {}) {
5433
- const none = (message) => ({ ok: false, message, merged: null, faces: 0, lines: 0 });
5477
+ const none = (message) => ({ ok: false, message, merged: null, faces: 0, lines: 0, edges: 0 });
5434
5478
  if (!points.length || !points.every((p) => Number.isFinite(p.x) && Number.isFinite(p.y))) return none("Give the points of the gesture.");
5435
5479
  const m = this.shapeBuilderMap(options.ids);
5436
5480
  if (!m) return none("Select paths that make faces.");
5437
5481
  const erase = !!options.erase;
5438
5482
  const tol = erase ? _nullishCoalesce(options.tolerance, () => ( this.builderLineTolerance())) : null;
5439
- const touched = { faces: [], lines: [] };
5483
+ const touched = { faces: [], lines: [], edges: [] };
5440
5484
  const size = m.map.faces.reduce((s, f) => Math.max(s, f.bounds.maxX - f.bounds.minX, f.bounds.maxY - f.bounds.minY), 1);
5441
5485
  for (const p of samplePolyline(points, Math.max(size / 2e3, 0.25 / this.viewport.zoom))) addBuilderHit(touched, vectorShapeBuilderHit(m, p, tol));
5442
- if (!touched.faces.length && !touched.lines.length) return none("There is no face under the pointer.");
5486
+ if (!touched.faces.length && !touched.lines.length && !touched.edges.length) return none("There is no face under the pointer.");
5443
5487
  return this.applyShapeBuilder(m, touched, erase);
5444
5488
  }
5445
5489
  applyShapeBuilder(m, touched, erase) {
@@ -5450,11 +5494,12 @@ var VectorEditorController = (_class3 = class {
5450
5494
  let nodes = this.doc.nodes;
5451
5495
  m.entries.forEach((entry, i) => {
5452
5496
  const node = entry.node;
5453
- const toLocal = (path) => _chunk7EDLVBOOcjs.transformBezierPath.call(void 0, path, invertMatrix(multiplyMatrices(nodeMatrix(node), entry.parent)));
5497
+ const toLocal = (path) => _chunkVNYRI265cjs.transformBezierPath.call(void 0, path, invertMatrix(multiplyMatrices(nodeMatrix(node), entry.parent)));
5454
5498
  const list = [];
5455
5499
  const r = plan.replace.get(i);
5456
5500
  if (r === void 0) list.push(node);
5457
- else if (_optionalChain([r, 'optionalAccess', _146 => _146.kind]) === "fill") list.push({ ...node, fillRule: "nonzero", subpaths: bezierToSubpaths(toLocal(r.path)) });
5501
+ else if (_optionalChain([r, 'optionalAccess', _145 => _145.kind]) === "fill") list.push({ ...node, fillRule: "nonzero", subpaths: bezierToSubpaths(toLocal(r.path)) });
5502
+ else if (_optionalChain([r, 'optionalAccess', _146 => _146.kind]) === "outline") list.push({ ...node, subpaths: bezierToSubpaths(toLocal(r.path)) });
5458
5503
  else if (_optionalChain([r, 'optionalAccess', _147 => _147.kind]) === "pieces") {
5459
5504
  r.paths.forEach(
5460
5505
  (path, k) => list.push({ ...node, id: k === 0 ? node.id : this.newId(), subpaths: bezierToSubpaths(toLocal(path)).map((sp) => ({ ...sp, closed: false })) })
@@ -5485,7 +5530,7 @@ var VectorEditorController = (_class3 = class {
5485
5530
  this.editingId = null;
5486
5531
  });
5487
5532
  this.builderCache = null;
5488
- return { ok: true, merged: mergedId, faces: touched.faces.length, lines: touched.lines.length };
5533
+ return { ok: true, merged: mergedId, faces: touched.faces.length, lines: touched.lines.length, edges: erase ? vectorBuilderErasedEdges(m, touched).length : 0 };
5489
5534
  }
5490
5535
  /** The paint bucket's map of the visible outlines, cached per document and gap. */
5491
5536
  fillMap(gap) {
@@ -5531,7 +5576,7 @@ var VectorEditorController = (_class3 = class {
5531
5576
  hoverBuilder(p, alt) {
5532
5577
  if (this.tool === "paintBucket") {
5533
5578
  const region = _nullishCoalesce(_optionalChain([this, 'access', _155 => _155.fillMap, 'call', _156 => _156(this.editing.fillGap), 'optionalAccess', _157 => _157.regionAt, 'call', _158 => _158([p.x, p.y])]), () => ( null));
5534
- const key2 = region ? _chunk7EDLVBOOcjs.bezierPathToSvg.call(void 0, region, { precision: 2 }) : null;
5579
+ const key2 = region ? _chunkVNYRI265cjs.bezierPathToSvg.call(void 0, region, { precision: 2 }) : null;
5535
5580
  if (key2 === this.builderHoverKey) return false;
5536
5581
  this.builderHoverKey = key2;
5537
5582
  this.builderPreview = region ? { mode: "fill", faces: [region], lines: [], trail: null } : null;
@@ -5542,7 +5587,9 @@ var VectorEditorController = (_class3 = class {
5542
5587
  const key = hit ? `${alt ? "erase" : "merge"}:${JSON.stringify(hit)}` : null;
5543
5588
  if (key === this.builderHoverKey) return false;
5544
5589
  this.builderHoverKey = key;
5545
- this.builderPreview = hit && m ? this.builderPreviewOf(m, "face" in hit ? { faces: [hit.face], lines: [] } : { faces: [], lines: [hit.line] }, alt, null) : null;
5590
+ const touched = { faces: [], lines: [], edges: [] };
5591
+ addBuilderHit(touched, hit);
5592
+ this.builderPreview = hit && m ? this.builderPreviewOf(m, touched, alt, null) : null;
5546
5593
  return true;
5547
5594
  }
5548
5595
  builderPreviewOf(m, touched, erase, trail) {
@@ -5550,7 +5597,8 @@ var VectorEditorController = (_class3 = class {
5550
5597
  return {
5551
5598
  mode: erase ? "erase" : "merge",
5552
5599
  faces: touched.faces.map((f) => faces[f].path),
5553
- lines: touched.lines.map((k) => m.pieces[k].path),
5600
+ // Edges bounding a face touched too go with the face, so they are not shown apart.
5601
+ lines: [...touched.lines.map((k) => m.pieces[k].path), ...erase ? vectorBuilderErasedEdges(m, touched).map((k) => m.edges[k].path) : []],
5554
5602
  trail
5555
5603
  };
5556
5604
  }
@@ -5566,7 +5614,7 @@ var VectorEditorController = (_class3 = class {
5566
5614
  const m = this.selectedRoots().length ? this.shapeBuilderMap() : null;
5567
5615
  if (!m) return;
5568
5616
  const erase = !!input.alt;
5569
- const touched = { faces: [], lines: [] };
5617
+ const touched = { faces: [], lines: [], edges: [] };
5570
5618
  addBuilderHit(touched, vectorShapeBuilderHit(m, p, erase ? this.builderLineTolerance() : null));
5571
5619
  this.drag = { kind: "builder", erase, points: [p], touched, map: m };
5572
5620
  this.interaction = { type: "builder", mode: erase ? "erase" : "merge", points: [p] };
@@ -5586,7 +5634,7 @@ var VectorEditorController = (_class3 = class {
5586
5634
  upBuilder(drag) {
5587
5635
  this.builderPreview = null;
5588
5636
  this.builderHoverKey = null;
5589
- if (!drag.touched.faces.length && !drag.touched.lines.length) {
5637
+ if (!drag.touched.faces.length && !drag.touched.lines.length && !drag.touched.edges.length) {
5590
5638
  this.notify();
5591
5639
  return;
5592
5640
  }
@@ -5999,10 +6047,10 @@ var VectorEditorController = (_class3 = class {
5999
6047
  const region = eraserRegion(pts, width);
6000
6048
  if (!region.length) return [];
6001
6049
  const plan = [];
6002
- const rb = _chunk7EDLVBOOcjs.bezierPathBounds.call(void 0, region);
6050
+ const rb = _chunkVNYRI265cjs.bezierPathBounds.call(void 0, region);
6003
6051
  const reach = rb ? [{ x: rb.minX, y: rb.minY }, { x: rb.maxX, y: rb.maxY }] : points;
6004
6052
  for (const node of this.strokeTargets(reach, options.ids, 0)) {
6005
- const local = _chunk7EDLVBOOcjs.transformBezierPath.call(void 0, region, invertMatrix(this.worldOf(node.id)));
6053
+ const local = _chunkVNYRI265cjs.transformBezierPath.call(void 0, region, invertMatrix(this.worldOf(node.id)));
6006
6054
  const live = node.subpaths.filter((sp) => sp.anchors.length > 1);
6007
6055
  if (!live.length) continue;
6008
6056
  if (hasPaint(node.fill) && live.every((sp) => sp.closed)) {
@@ -7056,7 +7104,7 @@ var VectorEditorController = (_class3 = class {
7056
7104
  this.selection = [drag.nodeId];
7057
7105
  return this.commit(`Draw ${inkShapeLabel(shape)}`, drag.before);
7058
7106
  }
7059
- const fitted = _chunk7EDLVBOOcjs.fitCubics.call(void 0, drag.points, 1.5 / this.viewport.zoom, { cornerAngleDeg: 60 });
7107
+ const fitted = _chunkVNYRI265cjs.fitCubics.call(void 0, drag.points, 1.5 / this.viewport.zoom, { cornerAngleDeg: 60 });
7060
7108
  const anchors = [];
7061
7109
  for (const c of fitted) {
7062
7110
  if (!anchors.length) anchors.push({ x: c.p0[0], y: c.p0[1] });
@@ -7323,6 +7371,7 @@ function pencilPressureProfile(points, pressures) {
7323
7371
  // src/vector/render.ts
7324
7372
  var fmt = (n) => Math.round(n * 100) / 100;
7325
7373
  var fmtMatrix = (m) => `matrix(${m.map((n) => Math.round(n * 1e6) / 1e6).join(" ")})`;
7374
+ var VECTOR_BUILDER_HATCH_GAP = 6;
7326
7375
  function renderNode(node, defs, idPrefix) {
7327
7376
  if (node.visible === false) return null;
7328
7377
  if (node.type === "group") {
@@ -7369,7 +7418,7 @@ function screenOutline(state, node) {
7369
7418
  const v2 = state.viewport;
7370
7419
  const view = [v2.zoom, 0, 0, v2.zoom, v2.x, v2.y];
7371
7420
  const parent = _nullishCoalesce(vectorParentMatrix(state.document.nodes, node.id), () => ( IDENTITY_MATRIX));
7372
- return collectWithMatrix(node, parent).map(({ path, parent: m }) => _chunk7EDLVBOOcjs.bezierPathToSvg.call(void 0, _chunk7EDLVBOOcjs.transformBezierPath.call(void 0, vectorPathWorldBezier(path, m), view), { precision: 2 })).join(" ");
7421
+ return collectWithMatrix(node, parent).map(({ path, parent: m }) => _chunkVNYRI265cjs.bezierPathToSvg.call(void 0, _chunkVNYRI265cjs.transformBezierPath.call(void 0, vectorPathWorldBezier(path, m), view), { precision: 2 })).join(" ");
7373
7422
  }
7374
7423
  function collectWithMatrix(node, parent) {
7375
7424
  if (node.type === "path") return [{ path: node, parent }];
@@ -7501,9 +7550,17 @@ function getVectorOverlayRenderData(state) {
7501
7550
  if (state.builder) {
7502
7551
  const v2 = state.viewport;
7503
7552
  const view = [v2.zoom, 0, 0, v2.zoom, v2.x, v2.y];
7504
- const d = (path) => _chunk7EDLVBOOcjs.bezierPathToSvg.call(void 0, _chunk7EDLVBOOcjs.transformBezierPath.call(void 0, path, view), { precision: 2 });
7553
+ const svg = (path) => _chunkVNYRI265cjs.bezierPathToSvg.call(void 0, path, { precision: 2 });
7554
+ const screen = state.builder.faces.map((f) => _chunkVNYRI265cjs.transformBezierPath.call(void 0, f, view));
7555
+ const hatch = state.builder.mode !== "fill";
7505
7556
  const trail = state.builder.trail && state.builder.trail.length > 1 ? state.builder.trail.map((q, i) => `${i ? "L" : "M"}${sc(q).x} ${sc(q).y}`).join("") : null;
7506
- builder = { mode: state.builder.mode, faces: state.builder.faces.map(d), lines: state.builder.lines.map(d), trail };
7557
+ builder = {
7558
+ mode: state.builder.mode,
7559
+ faces: screen.map(svg),
7560
+ hatches: screen.map((f) => hatch ? svg(_chunkVNYRI265cjs.hatchPath.call(void 0, f, { gap: VECTOR_BUILDER_HATCH_GAP })) : ""),
7561
+ lines: state.builder.lines.map((l) => svg(_chunkVNYRI265cjs.transformBezierPath.call(void 0, l, view))),
7562
+ trail
7563
+ };
7507
7564
  if (state.builder.mode !== "fill" && _optionalChain([it, 'optionalAccess', _239 => _239.type]) === "builder") {
7508
7565
  const n = state.builder.faces.length;
7509
7566
  status = state.builder.mode === "erase" ? `Delete ${n} ${n === 1 ? "face" : "faces"}` : `Merge ${n} ${n === 1 ? "face" : "faces"}`;
@@ -7530,7 +7587,9 @@ var VECTOR_OVERLAY_THEME = {
7530
7587
  builderFill: "rgba(14, 165, 233, 0.22)",
7531
7588
  /** Shape Builder faces and line pieces an Alt gesture deletes. */
7532
7589
  builderErase: "#ef4444",
7533
- builderEraseFill: "rgba(239, 68, 68, 0.22)"
7590
+ builderEraseFill: "rgba(239, 68, 68, 0.22)",
7591
+ /** Opacity of the hatch lines over Shape Builder faces (drawn in the face's outline colour). */
7592
+ builderHatchOpacity: 0.6
7534
7593
  };
7535
7594
  function vectorDiamondPath(x, y, r = VECTOR_OVERLAY_THEME.widthPointSize) {
7536
7595
  return `M${fmt(x)} ${fmt(y - r)}L${fmt(x + r)} ${fmt(y)}L${fmt(x)} ${fmt(y + r)}L${fmt(x - r)} ${fmt(y)}Z`;
@@ -8006,7 +8065,7 @@ function createVectorCommands(controller, options = {}) {
8006
8065
  id: `${prefix}shapeBuilder`,
8007
8066
  label: "Shape Builder",
8008
8067
  keywords: ["merge faces", "build shape", "combine regions", "delete region"],
8009
- description: "Shape Builder gesture over the faces of the given paths: `points` is the pointer path in document units (one point is a click; [[x, y], \u2026]; use the points from shapeBuilderFaces). Merges the faces it touches into one shape, or with `erase: true` deletes them and the pieces of unfilled open paths within `tolerance`. Shapes covering those faces lose that area.",
8068
+ description: "Shape Builder gesture over the faces of the given paths: `points` is the pointer path in document units (one point is a click; [[x, y], \u2026]; use the points from shapeBuilderFaces). Merges the faces it touches into one shape, or with `erase: true` deletes them, the pieces of unfilled open paths and the edges of other outlines (cut where paths meet) within `tolerance`; a deleted edge opens its path there, and edges bounding a deleted face go with it. Shapes covering those faces lose that area. Returns the counts of faces, line pieces and edges.",
8010
8069
  params: {
8011
8070
  type: "object",
8012
8071
  properties: { points: POINTS, erase: { type: "boolean" }, tolerance: { type: "number", minimum: 0 }, ids: IDS },
@@ -8016,7 +8075,7 @@ function createVectorCommands(controller, options = {}) {
8016
8075
  run: (_ctx, params) => {
8017
8076
  const result = controller.shapeBuilder(params.points.map(([x, y]) => ({ x, y })), { ids: ids(params), erase: params.erase, tolerance: params.tolerance });
8018
8077
  check(result);
8019
- return { merged: result.merged, faces: result.faces, lines: result.lines };
8078
+ return { merged: result.merged, faces: result.faces, lines: result.lines, edges: result.edges };
8020
8079
  }
8021
8080
  },
8022
8081
  {
@@ -8518,5 +8577,7 @@ function createVectorCommands(controller, options = {}) {
8518
8577
 
8519
8578
 
8520
8579
 
8521
- exports.DEFAULT_VECTOR_PATH_EDIT = DEFAULT_VECTOR_PATH_EDIT; exports.DEFAULT_VECTOR_SNAP = DEFAULT_VECTOR_SNAP; exports.IDENTITY_MATRIX = IDENTITY_MATRIX; exports.KAPPA = KAPPA2; exports.LazyMouse = LazyMouse; exports.VECTOR_ARROWHEADS = VECTOR_ARROWHEADS; exports.VECTOR_ARROWHEAD_LABELS = VECTOR_ARROWHEAD_LABELS; exports.VECTOR_CLIPBOARD_TYPE = VECTOR_CLIPBOARD_TYPE; exports.VECTOR_CONSTRUCTION_ANGLES = VECTOR_CONSTRUCTION_ANGLES; exports.VECTOR_CORNER_KINDS = VECTOR_CORNER_KINDS; exports.VECTOR_CORNER_KIND_LABELS = VECTOR_CORNER_KIND_LABELS; exports.VECTOR_CORNER_WIDGET_INSET = VECTOR_CORNER_WIDGET_INSET; exports.VECTOR_EDIT_TOGGLES = VECTOR_EDIT_TOGGLES; exports.VECTOR_FILL_GAP = VECTOR_FILL_GAP; exports.VECTOR_INK_MAX_CORNERS = VECTOR_INK_MAX_CORNERS; exports.VECTOR_OVERLAY_THEME = VECTOR_OVERLAY_THEME; exports.VECTOR_PATHFINDER_ACTIONS = VECTOR_PATHFINDER_ACTIONS; exports.VECTOR_PATHFINDER_LABELS = VECTOR_PATHFINDER_LABELS; exports.VECTOR_PATHFINDER_OPERATIONS = VECTOR_PATHFINDER_OPERATIONS; exports.VECTOR_PATH_ACTIONS = VECTOR_PATH_ACTIONS; exports.VECTOR_PENCIL_STRING_PX = VECTOR_PENCIL_STRING_PX; exports.VECTOR_PRESSURE_NOMINAL = VECTOR_PRESSURE_NOMINAL; exports.VECTOR_ROTATE_HANDLE_OFFSET = VECTOR_ROTATE_HANDLE_OFFSET; exports.VECTOR_STROKE_ALIGN_LABELS = VECTOR_STROKE_ALIGN_LABELS; exports.VECTOR_STYLE_KEYS = VECTOR_STYLE_KEYS; exports.VECTOR_TOOLS = VECTOR_TOOLS; exports.VECTOR_TOOL_GLYPHS = VECTOR_TOOL_GLYPHS; exports.VECTOR_TOOL_SHORTCUTS = VECTOR_TOOL_SHORTCUTS; exports.VECTOR_TRANSFORM_HANDLES = VECTOR_TRANSFORM_HANDLES; exports.VECTOR_WIDTH_PRESETS = VECTOR_WIDTH_PRESETS; exports.VECTOR_WIDTH_PRESET_IDS = VECTOR_WIDTH_PRESET_IDS; exports.VECTOR_WIDTH_PROFILE_MAX_POINTS = VECTOR_WIDTH_PROFILE_MAX_POINTS; exports.VECTOR_WIDTH_PROFILE_MAX_SCALE = VECTOR_WIDTH_PROFILE_MAX_SCALE; exports.VECTOR_WIDTH_SAME_T = VECTOR_WIDTH_SAME_T; exports.VectorEditorController = VectorEditorController; exports.VectorSnapTargets = VectorSnapTargets; exports.addBuilderHit = addBuilderHit; exports.applyMatrix = applyMatrix; exports.applyMatrixLinear = applyMatrixLinear; exports.applyVectorCornersAttribute = applyVectorCornersAttribute; exports.arrowheadInset = arrowheadInset; exports.arrowheadPath = arrowheadPath; exports.arrowheadWeight = arrowheadWeight; exports.bendSegment = bendSegment; exports.bezierToSubpaths = bezierToSubpaths; exports.boundsFromPoints = boundsFromPoints; exports.boundsIntersect = boundsIntersect; exports.cloneAnchor = cloneAnchor; exports.cloneSubpath = cloneSubpath; exports.cloneVectorDocument = cloneVectorDocument; exports.cloneVectorNode = cloneVectorNode; exports.collectPathNodes = collectPathNodes; exports.constrainToLeave = constrainToLeave; exports.convertAnchor = convertAnchor; exports.cornerBisectorPoint = cornerBisectorPoint; exports.cornerRadiusChange = cornerRadiusChange; exports.cornerSetback = cornerSetback; exports.createVectorCommands = createVectorCommands; exports.curvatureMoveAnchor = curvatureMoveAnchor; exports.cutSubpathAt = cutSubpathAt; exports.dashIntervals = dashIntervals; exports.decomposeRigid = decomposeRigid; exports.effectiveStrokeAlign = effectiveStrokeAlign; exports.ellipseSubpath = ellipseSubpath; exports.eraseFromFill = eraseFromFill; exports.eraseFromOutline = eraseFromOutline; exports.eraserRegion = eraserRegion; exports.expandVectorCorners = expandVectorCorners; exports.expandVectorCornersOf = expandVectorCornersOf; exports.findVectorNode = findVectorNode; exports.fitCornerRadius = fitCornerRadius; exports.generateWidthProfile = generateWidthProfile; exports.getAnchor = getAnchor; exports.getAnchorWorld = getAnchorWorld; exports.getEditablePathIds = getEditablePathIds; exports.getTransformHandlePositions = getTransformHandlePositions; exports.getVectorCornerWidgets = getVectorCornerWidgets; exports.getVectorOverlayRenderData = getVectorOverlayRenderData; exports.getVectorSceneRenderData = getVectorSceneRenderData; exports.getVectorSelectionBoxGeometry = getVectorSelectionBoxGeometry; exports.getVectorSelectionFrame = getVectorSelectionFrame; exports.getVectorSelectionStyle = getVectorSelectionStyle; exports.getVectorWidthHandles = getVectorWidthHandles; exports.getVisibleAnchors = getVisibleAnchors; exports.getVisibleHandles = getVisibleHandles; exports.hasPaint = hasPaint; exports.hasStrokeExtras = hasStrokeExtras; exports.hasVectorCorners = hasVectorCorners; exports.hitTestVectorNode = hitTestVectorNode; exports.hitTestVectorNodes = hitTestVectorNodes; exports.hitTestVectorStroke = hitTestVectorStroke; exports.inferAnchorType = inferAnchorType; exports.insertAnchor = insertAnchor; exports.insertWidthPoint = insertWidthPoint; exports.invertMatrix = invertMatrix; exports.isClosedBezierShape = isClosedBezierShape; exports.isIdentityMatrix = isIdentityMatrix; exports.isUniformWidthProfile = isUniformWidthProfile; exports.isVectorTextTarget = isVectorTextTarget; exports.joinSubpaths = joinSubpaths; exports.knifePath = knifePath; exports.lineSubpath = lineSubpath; exports.locateVectorNode = locateVectorNode; exports.matrixRotation = matrixRotation; exports.mirrorWidthProfile = mirrorWidthProfile; exports.moveAnchorHandle = moveAnchorHandle; exports.multiplyMatrices = multiplyMatrices; exports.nearestSegment = nearestSegment; exports.nearestStrokePosition = nearestStrokePosition; exports.nextVectorCornerKind = nextVectorCornerKind; exports.nodeMatrix = nodeMatrix; exports.parseSvgTransform = parseSvgTransform; exports.parseVectorSvg = parseVectorSvg; exports.planShapeBuilder = planShapeBuilder; exports.polygonSubpath = polygonSubpath; exports.polylineBounds = polylineBounds; exports.pressureWidthProfile = pressureWidthProfile; exports.recognizeInkShape = recognizeInkShape; exports.rectSubpath = rectSubpath; exports.removeAnchorKeepingShape = removeAnchorKeepingShape; exports.removeAnchors = removeAnchors; exports.removeAnchorsKeepingShape = removeAnchorsKeepingShape; exports.removeRedundantPoints = removeRedundantPoints; exports.removeWidthPoints = removeWidthPoints; exports.reverseSubpath = reverseSubpath; exports.reverseWidthProfile = reverseWidthProfile; exports.rotateMatrix = rotateMatrix; exports.roundSubpaths = roundSubpaths; exports.samplePolyline = samplePolyline; exports.sanitizeWidthProfile = sanitizeWidthProfile; exports.scaleFor = scaleFor; exports.scaleMatrix = scaleMatrix; exports.setAnchorCorner = setAnchorCorner; exports.setSubpathCorners = setSubpathCorners; exports.setWidthPoint = setWidthPoint; exports.simplifyPolyline = simplifyPolyline; exports.smoothSubpath = smoothSubpath; exports.splitIntoFaces = splitIntoFaces; exports.splitSubpathAt = splitSubpathAt; exports.starSubpath = starSubpath; exports.strokePositionPoint = strokePositionPoint; exports.strokeWidthProfileOf = strokeWidthProfileOf; exports.subpathEnclosesArea = subpathEnclosesArea; exports.subpathPointAt = subpathPointAt; exports.subpathSegment = subpathSegment; exports.subpathSegmentCount = subpathSegmentCount; exports.subpathsToBezier = subpathsToBezier; exports.taperWaveFactor = taperWaveFactor; exports.toVectorKeyInput = toVectorKeyInput; exports.toVectorModifiers = toVectorModifiers; exports.toVectorPointerInput = toVectorPointerInput; exports.transformVectorNode = transformVectorNode; exports.translateAnchor = translateAnchor; exports.translateMatrix = translateMatrix; exports.unionBounds = unionBounds; exports.variableStrokeOutline = variableStrokeOutline; exports.variableStrokeRings = variableStrokeRings; exports.vectorCornerAt = vectorCornerAt; exports.vectorCorners = vectorCorners; exports.vectorCornersAttribute = vectorCornersAttribute; exports.vectorDiamondPath = vectorDiamondPath; exports.vectorDocumentToSvg = vectorDocumentToSvg; exports.vectorFillMap = vectorFillMap; exports.vectorInkShapeName = vectorInkShapeName; exports.vectorNodeBounds = vectorNodeBounds; exports.vectorNodeRotation = vectorNodeRotation; exports.vectorNodeToBezier = vectorNodeToBezier; exports.vectorPaintToHex = vectorPaintToHex; exports.vectorPaintToSvg = vectorPaintToSvg; exports.vectorParentMatrix = vectorParentMatrix; exports.vectorPathData = vectorPathData; exports.vectorPathEntries = vectorPathEntries; exports.vectorPathWorldBezier = vectorPathWorldBezier; exports.vectorPathfinderShape = vectorPathfinderShape; exports.vectorResizeCursor = vectorResizeCursor; exports.vectorResultStyle = vectorResultStyle; exports.vectorShapeBuilderHit = vectorShapeBuilderHit; exports.vectorShapeBuilderMap = vectorShapeBuilderMap; exports.vectorStrokeLineArea = vectorStrokeLineArea; exports.vectorStrokeOutline = vectorStrokeOutline; exports.vectorStrokeOutlinePath = vectorStrokeOutlinePath; exports.vectorStrokeParts = vectorStrokeParts; exports.vectorStrokeReach = vectorStrokeReach; exports.vectorStrokeSvgParts = vectorStrokeSvgParts; exports.vectorStrokeWidthGeometry = vectorStrokeWidthGeometry; exports.vectorToolLabel = vectorToolLabel; exports.vectorWorldMatrix = vectorWorldMatrix; exports.walkVectorNodes = walkVectorNodes; exports.widthProfileAt = widthProfileAt; exports.widthProfileFromAttribute = widthProfileFromAttribute; exports.widthProfileMaxScale = widthProfileMaxScale; exports.widthProfilePreset = widthProfilePreset; exports.widthProfilePresetId = widthProfilePresetId; exports.widthProfileToAttribute = widthProfileToAttribute;
8580
+
8581
+
8582
+ exports.DEFAULT_VECTOR_PATH_EDIT = DEFAULT_VECTOR_PATH_EDIT; exports.DEFAULT_VECTOR_SNAP = DEFAULT_VECTOR_SNAP; exports.IDENTITY_MATRIX = IDENTITY_MATRIX; exports.KAPPA = KAPPA2; exports.LazyMouse = LazyMouse; exports.VECTOR_ARROWHEADS = VECTOR_ARROWHEADS; exports.VECTOR_ARROWHEAD_LABELS = VECTOR_ARROWHEAD_LABELS; exports.VECTOR_BUILDER_HATCH_GAP = VECTOR_BUILDER_HATCH_GAP; exports.VECTOR_CLIPBOARD_TYPE = VECTOR_CLIPBOARD_TYPE; exports.VECTOR_CONSTRUCTION_ANGLES = VECTOR_CONSTRUCTION_ANGLES; exports.VECTOR_CORNER_KINDS = VECTOR_CORNER_KINDS; exports.VECTOR_CORNER_KIND_LABELS = VECTOR_CORNER_KIND_LABELS; exports.VECTOR_CORNER_WIDGET_INSET = VECTOR_CORNER_WIDGET_INSET; exports.VECTOR_EDIT_TOGGLES = VECTOR_EDIT_TOGGLES; exports.VECTOR_FILL_GAP = VECTOR_FILL_GAP; exports.VECTOR_INK_MAX_CORNERS = VECTOR_INK_MAX_CORNERS; exports.VECTOR_OVERLAY_THEME = VECTOR_OVERLAY_THEME; exports.VECTOR_PATHFINDER_ACTIONS = VECTOR_PATHFINDER_ACTIONS; exports.VECTOR_PATHFINDER_LABELS = VECTOR_PATHFINDER_LABELS; exports.VECTOR_PATHFINDER_OPERATIONS = VECTOR_PATHFINDER_OPERATIONS; exports.VECTOR_PATH_ACTIONS = VECTOR_PATH_ACTIONS; exports.VECTOR_PENCIL_STRING_PX = VECTOR_PENCIL_STRING_PX; exports.VECTOR_PRESSURE_NOMINAL = VECTOR_PRESSURE_NOMINAL; exports.VECTOR_ROTATE_HANDLE_OFFSET = VECTOR_ROTATE_HANDLE_OFFSET; exports.VECTOR_STROKE_ALIGN_LABELS = VECTOR_STROKE_ALIGN_LABELS; exports.VECTOR_STYLE_KEYS = VECTOR_STYLE_KEYS; exports.VECTOR_TOOLS = VECTOR_TOOLS; exports.VECTOR_TOOL_GLYPHS = VECTOR_TOOL_GLYPHS; exports.VECTOR_TOOL_SHORTCUTS = VECTOR_TOOL_SHORTCUTS; exports.VECTOR_TRANSFORM_HANDLES = VECTOR_TRANSFORM_HANDLES; exports.VECTOR_WIDTH_PRESETS = VECTOR_WIDTH_PRESETS; exports.VECTOR_WIDTH_PRESET_IDS = VECTOR_WIDTH_PRESET_IDS; exports.VECTOR_WIDTH_PROFILE_MAX_POINTS = VECTOR_WIDTH_PROFILE_MAX_POINTS; exports.VECTOR_WIDTH_PROFILE_MAX_SCALE = VECTOR_WIDTH_PROFILE_MAX_SCALE; exports.VECTOR_WIDTH_SAME_T = VECTOR_WIDTH_SAME_T; exports.VectorEditorController = VectorEditorController; exports.VectorSnapTargets = VectorSnapTargets; exports.addBuilderHit = addBuilderHit; exports.applyMatrix = applyMatrix; exports.applyMatrixLinear = applyMatrixLinear; exports.applyVectorCornersAttribute = applyVectorCornersAttribute; exports.arrowheadInset = arrowheadInset; exports.arrowheadPath = arrowheadPath; exports.arrowheadWeight = arrowheadWeight; exports.bendSegment = bendSegment; exports.bezierToSubpaths = bezierToSubpaths; exports.boundsFromPoints = boundsFromPoints; exports.boundsIntersect = boundsIntersect; exports.cloneAnchor = cloneAnchor; exports.cloneSubpath = cloneSubpath; exports.cloneVectorDocument = cloneVectorDocument; exports.cloneVectorNode = cloneVectorNode; exports.collectPathNodes = collectPathNodes; exports.constrainToLeave = constrainToLeave; exports.convertAnchor = convertAnchor; exports.cornerBisectorPoint = cornerBisectorPoint; exports.cornerRadiusChange = cornerRadiusChange; exports.cornerSetback = cornerSetback; exports.createVectorCommands = createVectorCommands; exports.curvatureMoveAnchor = curvatureMoveAnchor; exports.cutSubpathAt = cutSubpathAt; exports.dashIntervals = dashIntervals; exports.decomposeRigid = decomposeRigid; exports.effectiveStrokeAlign = effectiveStrokeAlign; exports.ellipseSubpath = ellipseSubpath; exports.eraseFromFill = eraseFromFill; exports.eraseFromOutline = eraseFromOutline; exports.eraserRegion = eraserRegion; exports.expandVectorCorners = expandVectorCorners; exports.expandVectorCornersOf = expandVectorCornersOf; exports.findVectorNode = findVectorNode; exports.fitCornerRadius = fitCornerRadius; exports.generateWidthProfile = generateWidthProfile; exports.getAnchor = getAnchor; exports.getAnchorWorld = getAnchorWorld; exports.getEditablePathIds = getEditablePathIds; exports.getTransformHandlePositions = getTransformHandlePositions; exports.getVectorCornerWidgets = getVectorCornerWidgets; exports.getVectorOverlayRenderData = getVectorOverlayRenderData; exports.getVectorSceneRenderData = getVectorSceneRenderData; exports.getVectorSelectionBoxGeometry = getVectorSelectionBoxGeometry; exports.getVectorSelectionFrame = getVectorSelectionFrame; exports.getVectorSelectionStyle = getVectorSelectionStyle; exports.getVectorWidthHandles = getVectorWidthHandles; exports.getVisibleAnchors = getVisibleAnchors; exports.getVisibleHandles = getVisibleHandles; exports.hasPaint = hasPaint; exports.hasStrokeExtras = hasStrokeExtras; exports.hasVectorCorners = hasVectorCorners; exports.hitTestVectorNode = hitTestVectorNode; exports.hitTestVectorNodes = hitTestVectorNodes; exports.hitTestVectorStroke = hitTestVectorStroke; exports.inferAnchorType = inferAnchorType; exports.insertAnchor = insertAnchor; exports.insertWidthPoint = insertWidthPoint; exports.invertMatrix = invertMatrix; exports.isClosedBezierShape = isClosedBezierShape; exports.isIdentityMatrix = isIdentityMatrix; exports.isUniformWidthProfile = isUniformWidthProfile; exports.isVectorTextTarget = isVectorTextTarget; exports.joinSubpaths = joinSubpaths; exports.knifePath = knifePath; exports.lineSubpath = lineSubpath; exports.locateVectorNode = locateVectorNode; exports.matrixRotation = matrixRotation; exports.mirrorWidthProfile = mirrorWidthProfile; exports.moveAnchorHandle = moveAnchorHandle; exports.multiplyMatrices = multiplyMatrices; exports.nearestSegment = nearestSegment; exports.nearestStrokePosition = nearestStrokePosition; exports.nextVectorCornerKind = nextVectorCornerKind; exports.nodeMatrix = nodeMatrix; exports.parseSvgTransform = parseSvgTransform; exports.parseVectorSvg = parseVectorSvg; exports.planShapeBuilder = planShapeBuilder; exports.polygonSubpath = polygonSubpath; exports.polylineBounds = polylineBounds; exports.pressureWidthProfile = pressureWidthProfile; exports.recognizeInkShape = recognizeInkShape; exports.rectSubpath = rectSubpath; exports.removeAnchorKeepingShape = removeAnchorKeepingShape; exports.removeAnchors = removeAnchors; exports.removeAnchorsKeepingShape = removeAnchorsKeepingShape; exports.removeRedundantPoints = removeRedundantPoints; exports.removeWidthPoints = removeWidthPoints; exports.reverseSubpath = reverseSubpath; exports.reverseWidthProfile = reverseWidthProfile; exports.rotateMatrix = rotateMatrix; exports.roundSubpaths = roundSubpaths; exports.samplePolyline = samplePolyline; exports.sanitizeWidthProfile = sanitizeWidthProfile; exports.scaleFor = scaleFor; exports.scaleMatrix = scaleMatrix; exports.setAnchorCorner = setAnchorCorner; exports.setSubpathCorners = setSubpathCorners; exports.setWidthPoint = setWidthPoint; exports.simplifyPolyline = simplifyPolyline; exports.smoothSubpath = smoothSubpath; exports.splitIntoFaces = splitIntoFaces; exports.splitSubpathAt = splitSubpathAt; exports.starSubpath = starSubpath; exports.strokePositionPoint = strokePositionPoint; exports.strokeWidthProfileOf = strokeWidthProfileOf; exports.subpathEnclosesArea = subpathEnclosesArea; exports.subpathPointAt = subpathPointAt; exports.subpathSegment = subpathSegment; exports.subpathSegmentCount = subpathSegmentCount; exports.subpathsToBezier = subpathsToBezier; exports.taperWaveFactor = taperWaveFactor; exports.toVectorKeyInput = toVectorKeyInput; exports.toVectorModifiers = toVectorModifiers; exports.toVectorPointerInput = toVectorPointerInput; exports.transformVectorNode = transformVectorNode; exports.translateAnchor = translateAnchor; exports.translateMatrix = translateMatrix; exports.unionBounds = unionBounds; exports.variableStrokeOutline = variableStrokeOutline; exports.variableStrokeRings = variableStrokeRings; exports.vectorBuilderErasedEdges = vectorBuilderErasedEdges; exports.vectorCornerAt = vectorCornerAt; exports.vectorCorners = vectorCorners; exports.vectorCornersAttribute = vectorCornersAttribute; exports.vectorDiamondPath = vectorDiamondPath; exports.vectorDocumentToSvg = vectorDocumentToSvg; exports.vectorFillMap = vectorFillMap; exports.vectorInkShapeName = vectorInkShapeName; exports.vectorNodeBounds = vectorNodeBounds; exports.vectorNodeRotation = vectorNodeRotation; exports.vectorNodeToBezier = vectorNodeToBezier; exports.vectorPaintToHex = vectorPaintToHex; exports.vectorPaintToSvg = vectorPaintToSvg; exports.vectorParentMatrix = vectorParentMatrix; exports.vectorPathData = vectorPathData; exports.vectorPathEntries = vectorPathEntries; exports.vectorPathWorldBezier = vectorPathWorldBezier; exports.vectorPathfinderShape = vectorPathfinderShape; exports.vectorResizeCursor = vectorResizeCursor; exports.vectorResultStyle = vectorResultStyle; exports.vectorShapeBuilderHit = vectorShapeBuilderHit; exports.vectorShapeBuilderMap = vectorShapeBuilderMap; exports.vectorStrokeLineArea = vectorStrokeLineArea; exports.vectorStrokeOutline = vectorStrokeOutline; exports.vectorStrokeOutlinePath = vectorStrokeOutlinePath; exports.vectorStrokeParts = vectorStrokeParts; exports.vectorStrokeReach = vectorStrokeReach; exports.vectorStrokeSvgParts = vectorStrokeSvgParts; exports.vectorStrokeWidthGeometry = vectorStrokeWidthGeometry; exports.vectorToolLabel = vectorToolLabel; exports.vectorWorldMatrix = vectorWorldMatrix; exports.walkVectorNodes = walkVectorNodes; exports.widthProfileAt = widthProfileAt; exports.widthProfileFromAttribute = widthProfileFromAttribute; exports.widthProfileMaxScale = widthProfileMaxScale; exports.widthProfilePreset = widthProfilePreset; exports.widthProfilePresetId = widthProfilePresetId; exports.widthProfileToAttribute = widthProfileToAttribute;
8522
8583
  //# sourceMappingURL=index.cjs.map