@pixerate/editor 0.273.0 → 0.275.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (97) hide show
  1. package/dist/animation-editor/index.cjs +60 -60
  2. package/dist/animation-editor/index.js +4 -4
  3. package/dist/brushes/index.cjs +102 -74
  4. package/dist/brushes/index.js +34 -6
  5. package/dist/brushes/patch.d.cts +1 -1
  6. package/dist/brushes/patch.d.ts +1 -1
  7. package/dist/brushes/preview.d.cts +3 -0
  8. package/dist/brushes/preview.d.ts +3 -0
  9. package/dist/brushes/profiles.d.cts +2 -0
  10. package/dist/brushes/profiles.d.ts +2 -0
  11. package/dist/brushes/schema.d.cts +4 -0
  12. package/dist/brushes/schema.d.ts +4 -0
  13. package/dist/brushes/types.d.cts +47 -0
  14. package/dist/brushes/types.d.ts +47 -0
  15. package/dist/{brushstrokeRender-5YBCLFDQ.cjs → brushstrokeRender-2RQL46WB.cjs} +15 -15
  16. package/dist/{brushstrokeRender-DZGFU3J4.js → brushstrokeRender-WGY4DZHF.js} +3 -3
  17. package/dist/canvas/index.cjs +13 -13
  18. package/dist/canvas/index.js +1 -1
  19. package/dist/{chunk-2XDNF73E.js → chunk-43XJC3PP.js} +1 -1
  20. package/dist/{chunk-GHGBIAWQ.cjs → chunk-6QNDGMK7.cjs} +263 -45
  21. package/dist/{chunk-2F3YDXCN.js → chunk-75SYKUOT.js} +1 -1
  22. package/dist/{chunk-M3RZOF3G.cjs → chunk-C6VB7CPY.cjs} +1 -1
  23. package/dist/{chunk-N5IMDAHM.cjs → chunk-DHC4E2DU.cjs} +89 -37
  24. package/dist/{chunk-NAHJV3O6.js → chunk-G5TCMKX5.js} +28 -11
  25. package/dist/{chunk-DZVRH63Y.js → chunk-IEEY5RJV.js} +1 -1
  26. package/dist/{chunk-7W2EQQBP.cjs → chunk-JDXWLCXF.cjs} +6 -6
  27. package/dist/{chunk-N3SKPQEH.js → chunk-LMG57L5A.js} +62 -10
  28. package/dist/{chunk-5HP2VSAS.js → chunk-MSWLJI4G.js} +1 -1
  29. package/dist/{chunk-SNAFFCAX.cjs → chunk-OLZXXAER.cjs} +221 -196
  30. package/dist/{chunk-YJANF2BL.cjs → chunk-RAPNRK4R.cjs} +86 -86
  31. package/dist/{chunk-CLB2I2FU.js → chunk-RJGW3RQS.js} +2 -2
  32. package/dist/{chunk-FXVCB6YG.cjs → chunk-T6KNJVBP.cjs} +35 -35
  33. package/dist/{chunk-ZEI7ZEA4.js → chunk-Y2ISSVPH.js} +34 -9
  34. package/dist/{chunk-3JKCREEU.cjs → chunk-Y354ETAE.cjs} +76 -59
  35. package/dist/{chunk-TNLKFW7D.cjs → chunk-YYZC2EQO.cjs} +23 -23
  36. package/dist/{chunk-UXYCY3HP.js → chunk-ZM7IKQ4X.js} +239 -21
  37. package/dist/image-editor/index.cjs +789 -789
  38. package/dist/image-editor/index.js +5 -5
  39. package/dist/paint/index.cjs +2 -2
  40. package/dist/paint/index.js +1 -1
  41. package/dist/paint/wet/world.d.cts +15 -2
  42. package/dist/paint/wet/world.d.ts +15 -2
  43. package/dist/paint-editor/brush-controls.d.cts +7 -0
  44. package/dist/paint-editor/brush-controls.d.ts +7 -0
  45. package/dist/paint-editor/brush-model.d.cts +59 -1
  46. package/dist/paint-editor/brush-model.d.ts +59 -1
  47. package/dist/paint-editor/collaboration.d.cts +6 -1
  48. package/dist/paint-editor/collaboration.d.ts +6 -1
  49. package/dist/paint-editor/controller.d.cts +199 -1
  50. package/dist/paint-editor/controller.d.ts +199 -1
  51. package/dist/paint-editor/dab-stroke.d.cts +3 -0
  52. package/dist/paint-editor/dab-stroke.d.ts +3 -0
  53. package/dist/paint-editor/document.d.cts +13 -3
  54. package/dist/paint-editor/document.d.ts +13 -3
  55. package/dist/paint-editor/engine.d.cts +3 -0
  56. package/dist/paint-editor/engine.d.ts +3 -0
  57. package/dist/paint-editor/evolution-tools.d.cts +48 -0
  58. package/dist/paint-editor/evolution-tools.d.ts +48 -0
  59. package/dist/paint-editor/evolution.d.cts +175 -0
  60. package/dist/paint-editor/evolution.d.ts +175 -0
  61. package/dist/paint-editor/heat.d.cts +156 -0
  62. package/dist/paint-editor/heat.d.ts +156 -0
  63. package/dist/paint-editor/index.cjs +4905 -1525
  64. package/dist/paint-editor/index.d.cts +5 -0
  65. package/dist/paint-editor/index.d.ts +5 -0
  66. package/dist/paint-editor/index.js +10952 -7572
  67. package/dist/paint-editor/mutation-tools.d.cts +13 -0
  68. package/dist/paint-editor/mutation-tools.d.ts +13 -0
  69. package/dist/paint-editor/mutation.d.cts +67 -0
  70. package/dist/paint-editor/mutation.d.ts +67 -0
  71. package/dist/paint-editor/presence.d.cts +7 -1
  72. package/dist/paint-editor/presence.d.ts +7 -1
  73. package/dist/paint-editor/procedural.d.cts +3 -0
  74. package/dist/paint-editor/procedural.d.ts +3 -0
  75. package/dist/paint-editor/stroke.d.cts +32 -2
  76. package/dist/paint-editor/stroke.d.ts +32 -2
  77. package/dist/paint-editor/thick.d.cts +48 -7
  78. package/dist/paint-editor/thick.d.ts +48 -7
  79. package/dist/paint-editor/ui.d.cts +36 -1
  80. package/dist/paint-editor/ui.d.ts +36 -1
  81. package/dist/paint-editor/wet.d.cts +8 -1
  82. package/dist/paint-editor/wet.d.ts +8 -1
  83. package/dist/vector/index.cjs +999 -999
  84. package/dist/vector/index.js +5 -5
  85. package/package.json +1 -1
  86. package/skills/README.md +1 -0
  87. package/skills/pixerate-brushes/SKILL.md +3 -0
  88. package/skills/pixerate-paint-editor/SKILL.md +36 -53
  89. package/skills/pixerate-paint-editor/references/brush-facets.md +3 -0
  90. package/skills/pixerate-paint-editor/references/mutation.md +25 -0
  91. package/skills/pixerate-paint-editor/references/oils.md +8 -1
  92. package/skills/pixerate-paint-editor/references/smart-inks.md +51 -0
  93. package/skills/pixerate-paint-mutation/SKILL.md +76 -0
  94. package/skills/pixerate-paint-mutation/evals/decline-unanswered.json +58 -0
  95. package/skills/pixerate-paint-mutation/evals/dry-ink-answer.json +74 -0
  96. package/skills/pixerate-paint-mutation/evals/wet-wash-answer.json +76 -0
  97. package/skills/pixerate-paint-oil-impasto/SKILL.md +2 -1
@@ -27,7 +27,7 @@ var _chunkPFHJS4HEcjs = require('./chunk-PFHJS4HE.cjs');
27
27
 
28
28
 
29
29
 
30
- var _chunkGHGBIAWQcjs = require('./chunk-GHGBIAWQ.cjs');
30
+ var _chunk6QNDGMK7cjs = require('./chunk-6QNDGMK7.cjs');
31
31
 
32
32
 
33
33
  var _chunkW5M3J7PVcjs = require('./chunk-W5M3J7PV.cjs');
@@ -38,13 +38,13 @@ var _chunkXFM3OCHUcjs = require('./chunk-XFM3OCHU.cjs');
38
38
  // src/brushes/patch.ts
39
39
  var isObject = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
40
40
  var copy = (v) => JSON.parse(JSON.stringify(v));
41
- var FACETS = _chunkGHGBIAWQcjs.BRUSH_JSON_SCHEMA.properties;
41
+ var FACETS = _chunk6QNDGMK7cjs.BRUSH_JSON_SCHEMA.properties;
42
42
  var BRUSH_PATCH_PROPERTIES = (() => {
43
43
  const { id: _id, name: _name, ...rest } = FACETS;
44
44
  const { required: _r, ...tip } = rest.tip;
45
45
  return { ...rest, tip: { ...tip, description: `${tip.description} In a patch, shape may be left out to keep it.` } };
46
46
  })();
47
- var UNSETTABLE_BRUSH_FACETS = ["description", "tags", "medium", "variety", "marks", "dynamics", "behaviour", "light", "ghost", "motion", "colour"];
47
+ var UNSETTABLE_BRUSH_FACETS = ["description", "tags", "medium", "variety", "marks", "dynamics", "behaviour", "light", "fluorescence", "thermochromic", "iridescence", "ghost", "mutation", "motion", "colour"];
48
48
  var BRUSH_UNSET_PROPERTY = {
49
49
  type: "array",
50
50
  minItems: 1,
@@ -557,7 +557,7 @@ function idMaker(prefix) {
557
557
  return (name) => {
558
558
  const base = `${prefix}-${slug(name, 20) || "brush"}`.slice(0, 58).replace(/-+$/, "");
559
559
  let id = base;
560
- for (let n = 2; used.has(id) || !_chunkGHGBIAWQcjs.BRUSH_ID.test(id); n++) id = `${base}-${n}`;
560
+ for (let n = 2; used.has(id) || !_chunk6QNDGMK7cjs.BRUSH_ID.test(id); n++) id = `${base}-${n}`;
561
561
  used.add(id);
562
562
  return id;
563
563
  };
@@ -582,9 +582,9 @@ function readAbrPack(bytes, name, prefix, licence, pack) {
582
582
  return;
583
583
  }
584
584
  try {
585
- const source = _chunkGHGBIAWQcjs.brushSourceFromMask.call(void 0, { id: `${brushId}-shape`, name: label, licence, origin: `${name}.abr` }, tip.width, tip.height, tip.mask);
585
+ const source = _chunk6QNDGMK7cjs.brushSourceFromMask.call(void 0, { id: `${brushId}-shape`, name: label, licence, origin: `${name}.abr` }, tip.width, tip.height, tip.mask);
586
586
  pack.sources.push(source);
587
- pack.brushes.push({ ...base, tip: { shape: "stamp", size: clamp2(Math.max(tip.width, tip.height), 1, 2500), spacing: _nullishCoalesce(tip.spacing, () => ( 0.25)), stamps: [_chunkGHGBIAWQcjs.brushSourceRef.call(void 0, source.id)] } });
587
+ pack.brushes.push({ ...base, tip: { shape: "stamp", size: clamp2(Math.max(tip.width, tip.height), 1, 2500), spacing: _nullishCoalesce(tip.spacing, () => ( 0.25)), stamps: [_chunk6QNDGMK7cjs.brushSourceRef.call(void 0, source.id)] } });
588
588
  } catch (e) {
589
589
  pack.unsupported.push(`"${label}": ${e.message}`);
590
590
  }
@@ -626,7 +626,7 @@ function readProcreatePack(bytes, name, prefix, licence, pack) {
626
626
  const e = byName.get(`${dir}${file}`);
627
627
  if (!e) return null;
628
628
  try {
629
- const s = _chunkGHGBIAWQcjs.makeBrushSource.call(void 0, { id: `${brushId}-${kind}`, name: `${label} ${kind}`, image: e.read(), channel: "lightness", licence: [licence, terms].filter(Boolean).join("\n\n") || void 0, origin: `${where}/${file}` });
629
+ const s = _chunk6QNDGMK7cjs.makeBrushSource.call(void 0, { id: `${brushId}-${kind}`, name: `${label} ${kind}`, image: e.read(), channel: "lightness", licence: [licence, terms].filter(Boolean).join("\n\n") || void 0, origin: `${where}/${file}` });
630
630
  pack.sources.push(s);
631
631
  return s;
632
632
  } catch (err) {
@@ -647,8 +647,8 @@ function readProcreatePack(bytes, name, prefix, licence, pack) {
647
647
  shape: shape ? "stamp" : "round",
648
648
  size: 40,
649
649
  ...plot !== void 0 ? { spacing: plot } : {},
650
- ...shape ? { stamps: [_chunkGHGBIAWQcjs.brushSourceRef.call(void 0, shape.id)] } : {},
651
- ...grain ? { grain: { source: _chunkGHGBIAWQcjs.brushSourceRef.call(void 0, grain.id), mode: "moving" } } : {}
650
+ ...shape ? { stamps: [_chunk6QNDGMK7cjs.brushSourceRef.call(void 0, shape.id)] } : {},
651
+ ...grain ? { grain: { source: _chunk6QNDGMK7cjs.brushSourceRef.call(void 0, grain.id), mode: "moving" } } : {}
652
652
  }
653
653
  });
654
654
  if (!settings) pack.unsupported.push(`"${label}": its Brush.archive could not be read; the brush takes its name from the file and default settings.`);
@@ -702,17 +702,17 @@ async function importBrushFile(library, file, options = {}) {
702
702
  // src/brushes/tools.ts
703
703
  var READ = { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false };
704
704
  var WRITE = { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false };
705
- var FACETS2 = _chunkGHGBIAWQcjs.BRUSH_JSON_SCHEMA.properties;
705
+ var FACETS2 = _chunk6QNDGMK7cjs.BRUSH_JSON_SCHEMA.properties;
706
706
  var ID = { type: "string", pattern: String(FACETS2.id.pattern), description: "Brush id from list_brush_presets (lowercase letters, digits and dashes)." };
707
707
  var FACET_PROPS = BRUSH_PATCH_PROPERTIES;
708
- var HOSTS = Object.keys(_chunkGHGBIAWQcjs.BRUSH_HOST_PROFILES);
708
+ var HOSTS = Object.keys(_chunk6QNDGMK7cjs.BRUSH_HOST_PROFILES);
709
709
  var copy2 = (v) => JSON.parse(JSON.stringify(v));
710
710
  var merge = mergeBrushPatch;
711
711
  var changedPaths = changedBrushPaths;
712
712
  function summary(entry, profile, withCheck) {
713
713
  const b = entry.brush;
714
- const engine = _chunkGHGBIAWQcjs.resolveEngine.call(void 0, b);
715
- const check = withCheck ? _chunkGHGBIAWQcjs.checkBrush.call(void 0, b, profile) : null;
714
+ const engine = _chunk6QNDGMK7cjs.resolveEngine.call(void 0, b);
715
+ const check = withCheck ? _chunk6QNDGMK7cjs.checkBrush.call(void 0, b, profile) : null;
716
716
  return {
717
717
  id: b.id,
718
718
  name: b.name,
@@ -721,7 +721,7 @@ function summary(entry, profile, withCheck) {
721
721
  ...b.medium ? { medium: b.medium } : {},
722
722
  ...b.variety ? { variety: b.variety } : {},
723
723
  ...b.tool ? { tool: b.tool } : {},
724
- category: _chunkGHGBIAWQcjs.resolveCategory.call(void 0, b, engine),
724
+ category: _chunk6QNDGMK7cjs.resolveCategory.call(void 0, b, engine),
725
725
  engine,
726
726
  tip: b.tip.shape,
727
727
  ...b.tip.size !== void 0 ? { size: b.tip.size } : {},
@@ -735,33 +735,33 @@ function summary(entry, profile, withCheck) {
735
735
  var refusal = (check, host) => `${host.name} can't use this brush: ${check.issues.filter((i) => i.severity === "error").map((i) => `${i.facet}: ${i.reason} ${i.fix}`).join(" ")} (check_brush lists every issue; nothing was saved.)`;
736
736
  var warnings = (check) => check.issues.filter((i) => i.severity === "warning");
737
737
  function createBrushLibraryTools(library, options = {}) {
738
- const profile = _nullishCoalesce(options.profile, () => ( _chunkGHGBIAWQcjs.PAINT_PROFILE));
738
+ const profile = _nullishCoalesce(options.profile, () => ( _chunk6QNDGMK7cjs.PAINT_PROFILE));
739
739
  const hostOf = (id) => {
740
740
  if (id === void 0) return profile;
741
- const p = _chunkGHGBIAWQcjs.BRUSH_HOST_PROFILES[id];
742
- if (!p) throw new (0, _chunkGHGBIAWQcjs.BrushLibraryError)("invalid", `No host "${id}"; use one of: ${HOSTS.join(", ")}.`);
741
+ const p = _chunk6QNDGMK7cjs.BRUSH_HOST_PROFILES[id];
742
+ if (!p) throw new (0, _chunk6QNDGMK7cjs.BrushLibraryError)("invalid", `No host "${id}"; use one of: ${HOSTS.join(", ")}.`);
743
743
  return p;
744
744
  };
745
745
  const entry = async (id) => {
746
746
  const found = await library.get(id);
747
747
  if (found) return found;
748
748
  const ids = (await library.list()).map((e) => e.brush.id);
749
- throw new (0, _chunkGHGBIAWQcjs.BrushLibraryError)("unknown_brush", `No brush "${id}". ${_chunkGHGBIAWQcjs.closest.call(void 0, id, ids)}list_brush_presets lists them.`);
749
+ throw new (0, _chunk6QNDGMK7cjs.BrushLibraryError)("unknown_brush", `No brush "${id}". ${_chunk6QNDGMK7cjs.closest.call(void 0, id, ids)}list_brush_presets lists them.`);
750
750
  };
751
751
  const checkFor = async (brush, p) => {
752
- const check2 = _chunkGHGBIAWQcjs.checkBrush.call(void 0, brush, p);
752
+ const check2 = _chunk6QNDGMK7cjs.checkBrush.call(void 0, brush, p);
753
753
  const issues = [...check2.issues];
754
754
  const refs = [...(_nullishCoalesce(brush.tip.stamps, () => ( []))).map((r) => ["tip.stamps", r]), ...brush.tip.grain ? [["tip.grain.source", brush.tip.grain.source]] : []];
755
755
  for (const [facet, ref] of refs) {
756
- const id = _chunkGHGBIAWQcjs.brushSourceIdOf.call(void 0, ref);
756
+ const id = _chunk6QNDGMK7cjs.brushSourceIdOf.call(void 0, ref);
757
757
  if (id === null || await library.getSource(id)) continue;
758
758
  const ids = (await library.listSources()).map((x) => x.id);
759
- issues.push({ facet, severity: "error", reason: `There is no image source "${id}" in the brush library. ${_chunkGHGBIAWQcjs.closest.call(void 0, id, ids)}`.trim(), fix: "Add it with add_brush_source, or use a ref list_brush_sources lists." });
759
+ issues.push({ facet, severity: "error", reason: `There is no image source "${id}" in the brush library. ${_chunk6QNDGMK7cjs.closest.call(void 0, id, ids)}`.trim(), fix: "Add it with add_brush_source, or use a ref list_brush_sources lists." });
760
760
  }
761
761
  const provider = _optionalChain([options, 'access', _24 => _24.stickers, 'optionalCall', _25 => _25()]);
762
762
  if (!provider || brush.tip.shape !== "stamp") return { ok: !issues.some((i) => i.severity === "error"), issues };
763
763
  for (const ref of _nullishCoalesce(brush.tip.stamps, () => ( []))) {
764
- if (ref.startsWith("editor:") || _chunkGHGBIAWQcjs.isBrushSourceRef.call(void 0, ref)) continue;
764
+ if (ref.startsWith("editor:") || _chunk6QNDGMK7cjs.isBrushSourceRef.call(void 0, ref)) continue;
765
765
  try {
766
766
  await _chunkPFHJS4HEcjs.describeStickerRef.call(void 0, provider, ref);
767
767
  } catch (e) {
@@ -774,12 +774,12 @@ function createBrushLibraryTools(library, options = {}) {
774
774
  const problems = [];
775
775
  let brush;
776
776
  try {
777
- brush = _chunkGHGBIAWQcjs.normalizeBrushSpec.call(void 0, raw, problems);
777
+ brush = _chunk6QNDGMK7cjs.normalizeBrushSpec.call(void 0, raw, problems);
778
778
  } catch (e) {
779
- throw new (0, _chunkGHGBIAWQcjs.BrushLibraryError)("invalid", e.message);
779
+ throw new (0, _chunk6QNDGMK7cjs.BrushLibraryError)("invalid", e.message);
780
780
  }
781
- const check2 = _chunkGHGBIAWQcjs.withKeptIssues.call(void 0, await checkFor(brush, profile), original ? await checkFor(original, profile) : null);
782
- if (!check2.ok) throw new (0, _chunkGHGBIAWQcjs.BrushLibraryError)("invalid", refusal(check2, profile));
781
+ const check2 = _chunk6QNDGMK7cjs.withKeptIssues.call(void 0, await checkFor(brush, profile), original ? await checkFor(original, profile) : null);
782
+ if (!check2.ok) throw new (0, _chunk6QNDGMK7cjs.BrushLibraryError)("invalid", refusal(check2, profile));
783
783
  const saved = await library.save(brush, { overwrite });
784
784
  return { ...saved, problems, check: check2 };
785
785
  };
@@ -790,10 +790,10 @@ function createBrushLibraryTools(library, options = {}) {
790
790
  inputSchema: {
791
791
  type: "object",
792
792
  properties: {
793
- kind: { type: "string", enum: [..._chunkGHGBIAWQcjs.BRUSH_KINDS], description: "mark (lays a material) or tool (works on paint already down)." },
794
- medium: { type: "string", enum: [..._chunkGHGBIAWQcjs.BRUSH_MEDIA], description: "Marks laying this medium." },
793
+ kind: { type: "string", enum: [..._chunk6QNDGMK7cjs.BRUSH_KINDS], description: "mark (lays a material) or tool (works on paint already down)." },
794
+ medium: { type: "string", enum: [..._chunk6QNDGMK7cjs.BRUSH_MEDIA], description: "Marks laying this medium." },
795
795
  variety: { type: "string", maxLength: 40, description: "This variety (oil, watercolor, pencil, highlighter\u2026)." },
796
- tool: { type: "string", enum: [..._chunkGHGBIAWQcjs.BRUSH_TOOLS], description: "Tools that do this." },
796
+ tool: { type: "string", enum: [..._chunk6QNDGMK7cjs.BRUSH_TOOLS], description: "Tools that do this." },
797
797
  tag: { type: "string", maxLength: 40, description: "Brushes with this tag." },
798
798
  text: { type: "string", maxLength: 200, description: "Words in the id, name, description, variety or tags (each word must match the start of one)." },
799
799
  source: { type: "string", enum: ["all", "builtin", "user"], description: "all (default), builtin presets only, or user (saved) brushes only." },
@@ -820,8 +820,8 @@ function createBrushLibraryTools(library, options = {}) {
820
820
  annotations: { title: "Describe a brush", ...READ },
821
821
  handler: async ({ id }) => {
822
822
  const e = await entry(id);
823
- const engine = _chunkGHGBIAWQcjs.resolveEngine.call(void 0, e.brush);
824
- return { brush: e.brush, builtin: e.builtin, engine, category: _chunkGHGBIAWQcjs.resolveCategory.call(void 0, e.brush, engine), check: await checkFor(e.brush, profile) };
823
+ const engine = _chunk6QNDGMK7cjs.resolveEngine.call(void 0, e.brush);
824
+ return { brush: e.brush, builtin: e.builtin, engine, category: _chunk6QNDGMK7cjs.resolveCategory.call(void 0, e.brush, engine), check: await checkFor(e.brush, profile) };
825
825
  }
826
826
  };
827
827
  const check = {
@@ -839,20 +839,20 @@ function createBrushLibraryTools(library, options = {}) {
839
839
  },
840
840
  annotations: { title: "Check a brush for a host", ...READ },
841
841
  handler: async ({ id, brush, host }) => {
842
- if (id === void 0 === (brush === void 0)) throw new (0, _chunkGHGBIAWQcjs.BrushLibraryError)("invalid", "Give either id (a library brush) or brush (a spec), not both or neither.");
842
+ if (id === void 0 === (brush === void 0)) throw new (0, _chunk6QNDGMK7cjs.BrushLibraryError)("invalid", "Give either id (a library brush) or brush (a spec), not both or neither.");
843
843
  const p = hostOf(host);
844
844
  let b;
845
845
  const problems = [];
846
846
  if (id !== void 0) b = (await entry(id)).brush;
847
847
  else {
848
848
  try {
849
- b = _chunkGHGBIAWQcjs.normalizeBrushSpec.call(void 0, brush, problems);
849
+ b = _chunk6QNDGMK7cjs.normalizeBrushSpec.call(void 0, brush, problems);
850
850
  } catch (e) {
851
- throw new (0, _chunkGHGBIAWQcjs.BrushLibraryError)("invalid", e.message);
851
+ throw new (0, _chunk6QNDGMK7cjs.BrushLibraryError)("invalid", e.message);
852
852
  }
853
853
  }
854
854
  const result = await checkFor(b, p);
855
- return { host: p.id, ...result, ...problems.length ? { problems } : {}, ...!result.ok ? { degraded: _chunkGHGBIAWQcjs.degrade.call(void 0, b, p) } : {} };
855
+ return { host: p.id, ...result, ...problems.length ? { problems } : {}, ...!result.ok ? { degraded: _chunk6QNDGMK7cjs.degrade.call(void 0, b, p) } : {} };
856
856
  }
857
857
  };
858
858
  const exportTool = {
@@ -887,7 +887,7 @@ function createBrushLibraryTools(library, options = {}) {
887
887
  });
888
888
  const start = _nullishCoalesce(offset, () => ( 0));
889
889
  const page = found.slice(start, start + (_nullishCoalesce(limit, () => ( 100))));
890
- return { total: found.length, sources: page.map((x) => ({ ..._chunkGHGBIAWQcjs.summarizeBrushSource.call(void 0, x), usedBy: brushes.filter((b) => _chunkGHGBIAWQcjs.brushSourceIds.call(void 0, b).includes(x.id)).map((b) => b.id) })) };
890
+ return { total: found.length, sources: page.map((x) => ({ ..._chunk6QNDGMK7cjs.summarizeBrushSource.call(void 0, x), usedBy: brushes.filter((b) => _chunk6QNDGMK7cjs.brushSourceIds.call(void 0, b).includes(x.id)).map((b) => b.id) })) };
891
891
  }
892
892
  };
893
893
  const tools = [list, describe, check, exportTool, listSources];
@@ -938,12 +938,12 @@ function createBrushLibraryTools(library, options = {}) {
938
938
  },
939
939
  annotations: { title: "Save a new brush", ...WRITE },
940
940
  handler: async ({ basedOn, ...spec }) => {
941
- if (library.isBuiltin(spec.id)) throw new (0, _chunkGHGBIAWQcjs.BrushLibraryError)("builtin", `"${spec.id}" is a built-in brush id; pick another id (or basedOn "${spec.id}" with a new id).`);
942
- if (await library.get(spec.id)) throw new (0, _chunkGHGBIAWQcjs.BrushLibraryError)("exists", `A brush "${spec.id}" exists already; pick another id, or change it with update_brush.`);
941
+ if (library.isBuiltin(spec.id)) throw new (0, _chunk6QNDGMK7cjs.BrushLibraryError)("builtin", `"${spec.id}" is a built-in brush id; pick another id (or basedOn "${spec.id}" with a new id).`);
942
+ if (await library.get(spec.id)) throw new (0, _chunk6QNDGMK7cjs.BrushLibraryError)("exists", `A brush "${spec.id}" exists already; pick another id, or change it with update_brush.`);
943
943
  const base = basedOn !== void 0 ? (await entry(basedOn)).brush : void 0;
944
944
  const raw = base ? merge(base, spec) : spec;
945
945
  const saved = await store(raw, false);
946
- return { id: saved.brush.id, brush: saved.brush, engine: _chunkGHGBIAWQcjs.resolveEngine.call(void 0, saved.brush), problems: saved.problems, warnings: warnings(saved.check) };
946
+ return { id: saved.brush.id, brush: saved.brush, engine: _chunk6QNDGMK7cjs.resolveEngine.call(void 0, saved.brush), problems: saved.problems, warnings: warnings(saved.check) };
947
947
  }
948
948
  },
949
949
  {
@@ -964,7 +964,7 @@ function createBrushLibraryTools(library, options = {}) {
964
964
  annotations: { title: "Update a brush", ...WRITE, idempotentHint: true },
965
965
  handler: async ({ id, unset, ...patch }) => {
966
966
  const e = await entry(id);
967
- if (e.builtin) throw new (0, _chunkGHGBIAWQcjs.BrushLibraryError)("builtin", `"${id}" is a built-in brush and can't be changed; duplicate_brush makes a copy you can change.`);
967
+ if (e.builtin) throw new (0, _chunk6QNDGMK7cjs.BrushLibraryError)("builtin", `"${id}" is a built-in brush and can't be changed; duplicate_brush makes a copy you can change.`);
968
968
  const base = copy2(e.brush);
969
969
  for (const k of _nullishCoalesce(unset, () => ( []))) delete base[k];
970
970
  const saved = await store(merge(base, { ...patch, id }), true, e.brush);
@@ -974,14 +974,14 @@ function createBrushLibraryTools(library, options = {}) {
974
974
  {
975
975
  name: "add_brush_source",
976
976
  title: "Add a brush image source",
977
- description: `Adds an image to the brush library as a source for image tips and image grain (as Procreate's shape and grain sources). The image is a PNG data: URL; the marks are read from its transparency, its dark parts (a scan of marks on paper) or its light parts (white on black), as channel says, and kept as a grey mask at most ${_chunkGHGBIAWQcjs.MAX_BRUSH_SOURCE_SIZE} px on a side. Returns id, ref (source:<id>), the stored source's width and height, problems (the channel auto picked, scaling) and replaced. Then make the brush: create_brush or update_brush with tip { shape: "stamp", stamps: [ref] } for an image tip, or tip.grain { source: ref } for grain. A taken id is refused unless overwrite.`,
977
+ description: `Adds an image to the brush library as a source for image tips and image grain (as Procreate's shape and grain sources). The image is a PNG data: URL; the marks are read from its transparency, its dark parts (a scan of marks on paper) or its light parts (white on black), as channel says, and kept as a grey mask at most ${_chunk6QNDGMK7cjs.MAX_BRUSH_SOURCE_SIZE} px on a side. Returns id, ref (source:<id>), the stored source's width and height, problems (the channel auto picked, scaling) and replaced. Then make the brush: create_brush or update_brush with tip { shape: "stamp", stamps: [ref] } for an image tip, or tip.grain { source: ref } for grain. A taken id is refused unless overwrite.`,
978
978
  inputSchema: {
979
979
  type: "object",
980
980
  properties: {
981
981
  name: { type: "string", minLength: 1, maxLength: 80, description: 'Display name, e.g. "Charcoal scan".' },
982
- image: { type: "string", pattern: "^data:image/png;base64,", maxLength: 4e7, description: `The image: a PNG data: URL, at most ${_chunkGHGBIAWQcjs.MAX_BRUSH_SOURCE_INPUT_PIXELS} pixels; larger than ${_chunkGHGBIAWQcjs.MAX_BRUSH_SOURCE_SIZE} px it is scaled down.` },
982
+ image: { type: "string", pattern: "^data:image/png;base64,", maxLength: 4e7, description: `The image: a PNG data: URL, at most ${_chunk6QNDGMK7cjs.MAX_BRUSH_SOURCE_INPUT_PIXELS} pixels; larger than ${_chunk6QNDGMK7cjs.MAX_BRUSH_SOURCE_SIZE} px it is scaled down.` },
983
983
  id: { type: "string", pattern: String(FACETS2.id.pattern), description: "The source id (default: from the name, made unique): lowercase letters, digits and dashes." },
984
- channel: { type: "string", enum: [..._chunkGHGBIAWQcjs.BRUSH_SOURCE_CHANNELS], description: "Where the marks are: auto (default: the transparency when the image has any, else the dark parts), alpha, darkness (dark marks on light paper) or lightness (light marks on black)." },
984
+ channel: { type: "string", enum: [..._chunk6QNDGMK7cjs.BRUSH_SOURCE_CHANNELS], description: "Where the marks are: auto (default: the transparency when the image has any, else the dark parts), alpha, darkness (dark marks on light paper) or lightness (light marks on black)." },
985
985
  invert: { type: "boolean", description: "Swap painted and empty parts (default false)." },
986
986
  licence: { type: "string", maxLength: 2e3, description: "The licence or terms the image came with, kept with the source." },
987
987
  origin: { type: "string", maxLength: 200, description: "Where it came from: a file name, a pack or a URL." },
@@ -993,7 +993,7 @@ function createBrushLibraryTools(library, options = {}) {
993
993
  annotations: { title: "Add a brush image source", ...WRITE },
994
994
  handler: async ({ overwrite, ...input }) => {
995
995
  const r = await library.addSource(input, { overwrite: !!overwrite });
996
- return { id: r.source.id, ref: _chunkGHGBIAWQcjs.brushSourceRef.call(void 0, r.source.id), width: r.source.width, height: r.source.height, problems: r.problems, replaced: r.replaced };
996
+ return { id: r.source.id, ref: _chunk6QNDGMK7cjs.brushSourceRef.call(void 0, r.source.id), width: r.source.width, height: r.source.height, problems: r.problems, replaced: r.replaced };
997
997
  }
998
998
  },
999
999
  {
@@ -1067,24 +1067,24 @@ function createBrushLibraryTools(library, options = {}) {
1067
1067
  try {
1068
1068
  bytes = _chunkW5M3J7PVcjs.base64ToBytes.call(void 0, file.replace(/^data:[^,]*,/, ""));
1069
1069
  } catch (e6) {
1070
- throw new (0, _chunkGHGBIAWQcjs.BrushLibraryError)("invalid", "file is not base64: pass the pack's bytes as base64 (a data: URL works too).");
1070
+ throw new (0, _chunk6QNDGMK7cjs.BrushLibraryError)("invalid", "file is not base64: pass the pack's bytes as base64 (a data: URL works too).");
1071
1071
  }
1072
1072
  let r;
1073
1073
  try {
1074
1074
  r = await importBrushPack(library, bytes, { fileName, ...format ? { format } : {}, ...prefix ? { prefix } : {}, ...licence ? { licence } : {}, overwrite: !!overwrite });
1075
1075
  } catch (e) {
1076
- if (e instanceof _chunkGHGBIAWQcjs.BrushLibraryError) throw e;
1077
- throw new (0, _chunkGHGBIAWQcjs.BrushLibraryError)("invalid", `${e.message} Nothing was imported.`);
1076
+ if (e instanceof _chunk6QNDGMK7cjs.BrushLibraryError) throw e;
1077
+ throw new (0, _chunk6QNDGMK7cjs.BrushLibraryError)("invalid", `${e.message} Nothing was imported.`);
1078
1078
  }
1079
1079
  const entries = await Promise.all(r.brushes.map((b) => library.get(b.id)));
1080
- return { ...r, brushes: r.brushes.map((b, i) => ({ ...b, renderable: entries[i] ? _chunkGHGBIAWQcjs.checkBrush.call(void 0, entries[i].brush, profile).ok : false })) };
1080
+ return { ...r, brushes: r.brushes.map((b, i) => ({ ...b, renderable: entries[i] ? _chunk6QNDGMK7cjs.checkBrush.call(void 0, entries[i].brush, profile).ok : false })) };
1081
1081
  }
1082
1082
  }
1083
1083
  );
1084
1084
  return tools;
1085
1085
  }
1086
1086
  function createBrushLibraryToolProvider(library, options = {}) {
1087
- const profile = _nullishCoalesce(options.profile, () => ( _chunkGHGBIAWQcjs.PAINT_PROFILE));
1087
+ const profile = _nullishCoalesce(options.profile, () => ( _chunk6QNDGMK7cjs.PAINT_PROFILE));
1088
1088
  const tools = createBrushLibraryTools(library, options);
1089
1089
  return {
1090
1090
  id: _nullishCoalesce(options.id, () => ( "brushes")),
@@ -1113,6 +1113,11 @@ var BRUSH_SLIDERS = [
1113
1113
  { path: "dynamics.velocitySize", label: "Speed size", min: -1, max: 1, step: 0.01 }
1114
1114
  ];
1115
1115
  var LIGHT_SLIDER = { path: "light.amount", label: "Light", min: 0, max: 1, step: 0.01 };
1116
+ var IRIDESCENCE_SLIDERS = [
1117
+ { path: "iridescence.thickness", label: "Film thickness (nm)", min: 100, max: 1e3, step: 5 },
1118
+ { path: "iridescence.pressureToThickness", label: "Pressure \u2192 thickness", min: 0, max: 1, step: 0.01 },
1119
+ { path: "iridescence.ior", label: "Refractive index", min: 1.2, max: 2, step: 0.01 }
1120
+ ];
1116
1121
  var PICKUP_SLIDERS = [
1117
1122
  { path: "behavior.pickup", label: "Pick-up", min: 0, max: 1, step: 0.01 },
1118
1123
  { path: "behavior.mix", label: "Mix", min: 0, max: 1, step: 0.01 }
@@ -1121,12 +1126,22 @@ var GHOST_SLIDERS = [
1121
1126
  { path: "ghost.linger", label: "Linger", min: 0.5, max: 60, step: 0.5 },
1122
1127
  { path: "ghost.smear", label: "Smear", min: 0, max: 1, step: 0.01 }
1123
1128
  ];
1129
+ var MUTATION_SLIDERS = [
1130
+ { path: "mutation.settle", label: "Settle", min: 0.5, max: 10, step: 0.5 },
1131
+ { path: "mutation.patience", label: "Patience", min: 5, max: 300, step: 5 },
1132
+ { path: "mutation.fade", label: "Fade", min: 0.5, max: 10, step: 0.5 }
1133
+ ];
1124
1134
  function brushEngineControls(brush) {
1125
1135
  const c = engineControls(brush);
1126
- const wetPaint = brush.engine === "wet" && _optionalChain([brush, 'access', _28 => _28.wet, 'optionalAccess', _29 => _29.tool]) === "paint" && !brush.ghost;
1127
- if (!c || !(wetPaint || ["dab", "mixer", "particle", "bristle", "impasto"].includes(brush.engine))) return c;
1136
+ if (!c) return null;
1137
+ const mut = brush.mutation ? MUTATION_SLIDERS : [];
1138
+ const wetPaint = brush.engine === "wet" && _optionalChain([brush, 'access', _28 => _28.wet, 'optionalAccess', _29 => _29.tool]) === "paint" && !brush.ghost && !brush.mutation;
1139
+ if (!(wetPaint || ["dab", "mixer", "particle", "bristle", "impasto"].includes(brush.engine))) {
1140
+ return mut.length ? { ...c, sliders: [...c.sliders, ...mut] } : c;
1141
+ }
1128
1142
  const extra = brush.engine === "impasto" ? [{ path: "impasto.rim", label: "Rim", min: 0, max: 1, step: 0.01 }, { path: "impasto.clarity", label: "Clarity", min: 0, max: 1, step: 0.01 }] : [];
1129
- return { ...c, sliders: [...c.sliders, LIGHT_SLIDER, ...extra], light: true };
1143
+ const film = brush.iridescence ? IRIDESCENCE_SLIDERS : [];
1144
+ return { ...c, sliders: [...c.sliders, ...mut, LIGHT_SLIDER, ...extra, ...film], light: true, iridescence: true };
1130
1145
  }
1131
1146
  function engineControls(brush) {
1132
1147
  switch (brush.engine) {
@@ -1197,17 +1212,17 @@ function engineControls(brush) {
1197
1212
  { path: "impasto.load", label: "Load", min: 0, max: 1, step: 0.01 },
1198
1213
  { path: "impasto.thinner", label: "Thinner", min: 0, max: 1, step: 0.01 },
1199
1214
  { path: "impasto.drag", label: "Drag", min: 0, max: 1, step: 0.01 },
1200
- ...PICKUP_SLIDERS
1215
+ ...brush.mutation ? [] : PICKUP_SLIDERS
1201
1216
  ],
1202
1217
  mixingPath: "behavior.mixing",
1203
- dirty: true,
1218
+ dirty: !brush.mutation,
1204
1219
  multicolor: false,
1205
- load: true,
1220
+ load: !brush.mutation,
1206
1221
  impastoTool: true
1207
1222
  };
1208
1223
  case "wet": {
1209
1224
  const tool = _nullishCoalesce(_optionalChain([brush, 'access', _30 => _30.wet, 'optionalAccess', _31 => _31.tool]), () => ( "paint"));
1210
- const ghost = tool === "paint" && Boolean(brush.ghost);
1225
+ const ghost = tool === "paint" && (Boolean(brush.ghost) || Boolean(brush.mutation));
1211
1226
  const sliders = tool === "paint" ? [
1212
1227
  { path: "wet.water", label: "Water", min: 0, max: 1, step: 0.01 },
1213
1228
  { path: "wet.pigment", label: "Pigment", min: 0, max: 1, step: 0.01 },
@@ -1215,7 +1230,7 @@ function engineControls(brush) {
1215
1230
  { path: "wet.rewet", label: "Re-wet", min: 0, max: 1, step: 0.01 },
1216
1231
  { path: "wet.load", label: "Load", min: 0, max: 1, step: 0.01 },
1217
1232
  { path: "wet.thinner", label: "Thinner", min: 0, max: 1, step: 0.01 },
1218
- ...ghost ? GHOST_SLIDERS : PICKUP_SLIDERS
1233
+ ...brush.mutation ? [{ path: "ghost.smear", label: "Smear", min: 0, max: 1, step: 0.01 }] : ghost ? GHOST_SLIDERS : PICKUP_SLIDERS
1219
1234
  ] : tool === "water" ? [
1220
1235
  { path: "wet.water", label: "Water", min: 0, max: 1, step: 0.01 },
1221
1236
  { path: "wet.rewet", label: "Re-wet", min: 0, max: 1, step: 0.01 }
@@ -1249,7 +1264,7 @@ function engineControls(brush) {
1249
1264
  case "mixer":
1250
1265
  return { title: "Mixer Brush", sliders: [...PICKUP_SLIDERS, { path: "mixer.load", label: "Load", min: 0, max: 1, step: 0.01 }], mixingPath: "behavior.mixing", dirty: true, multicolor: true, load: true };
1251
1266
  case "dab":
1252
- return { title: "Paint behaviour", sliders: PICKUP_SLIDERS, mixingPath: "behavior.mixing", dirty: true, multicolor: true, load: true };
1267
+ return { title: "Paint behaviour", sliders: brush.mutation ? [] : PICKUP_SLIDERS, mixingPath: "behavior.mixing", dirty: !brush.mutation, multicolor: !brush.mutation, load: !brush.mutation };
1253
1268
  default:
1254
1269
  return null;
1255
1270
  }
@@ -1293,4 +1308,6 @@ function patchBrushValue(brush, path, value) {
1293
1308
 
1294
1309
 
1295
1310
 
1296
- exports.BRUSH_PATCH_PROPERTIES = BRUSH_PATCH_PROPERTIES; exports.UNSETTABLE_BRUSH_FACETS = UNSETTABLE_BRUSH_FACETS; exports.BRUSH_UNSET_PROPERTY = BRUSH_UNSET_PROPERTY; exports.mergeBrushPatch = mergeBrushPatch; exports.changedBrushPaths = changedBrushPaths; exports.AbrError = AbrError; exports.readAbr = readAbr; exports.BRUSH_PACK_FORMATS = BRUSH_PACK_FORMATS; exports.MAX_BRUSH_PACK_BYTES = MAX_BRUSH_PACK_BYTES; exports.MAX_PACK_BRUSHES = MAX_PACK_BRUSHES; exports.BrushPackError = BrushPackError; exports.brushPackFormat = brushPackFormat; exports.readBrushPack = readBrushPack; exports.importBrushPack = importBrushPack; exports.importBrushFile = importBrushFile; exports.createBrushLibraryTools = createBrushLibraryTools; exports.createBrushLibraryToolProvider = createBrushLibraryToolProvider; exports.BRUSH_SLIDERS = BRUSH_SLIDERS; exports.GHOST_SLIDERS = GHOST_SLIDERS; exports.brushEngineControls = brushEngineControls; exports.multiColorSliders = multiColorSliders; exports.patchBrushValue = patchBrushValue;
1311
+
1312
+
1313
+ exports.BRUSH_PATCH_PROPERTIES = BRUSH_PATCH_PROPERTIES; exports.UNSETTABLE_BRUSH_FACETS = UNSETTABLE_BRUSH_FACETS; exports.BRUSH_UNSET_PROPERTY = BRUSH_UNSET_PROPERTY; exports.mergeBrushPatch = mergeBrushPatch; exports.changedBrushPaths = changedBrushPaths; exports.AbrError = AbrError; exports.readAbr = readAbr; exports.BRUSH_PACK_FORMATS = BRUSH_PACK_FORMATS; exports.MAX_BRUSH_PACK_BYTES = MAX_BRUSH_PACK_BYTES; exports.MAX_PACK_BRUSHES = MAX_PACK_BRUSHES; exports.BrushPackError = BrushPackError; exports.brushPackFormat = brushPackFormat; exports.readBrushPack = readBrushPack; exports.importBrushPack = importBrushPack; exports.importBrushFile = importBrushFile; exports.createBrushLibraryTools = createBrushLibraryTools; exports.createBrushLibraryToolProvider = createBrushLibraryToolProvider; exports.BRUSH_SLIDERS = BRUSH_SLIDERS; exports.IRIDESCENCE_SLIDERS = IRIDESCENCE_SLIDERS; exports.GHOST_SLIDERS = GHOST_SLIDERS; exports.MUTATION_SLIDERS = MUTATION_SLIDERS; exports.brushEngineControls = brushEngineControls; exports.multiColorSliders = multiColorSliders; exports.patchBrushValue = patchBrushValue;
@@ -5,7 +5,7 @@
5
5
 
6
6
 
7
7
 
8
- var _chunkSNAFFCAXcjs = require('./chunk-SNAFFCAX.cjs');
8
+ var _chunkOLZXXAERcjs = require('./chunk-OLZXXAER.cjs');
9
9
 
10
10
 
11
11
  var _chunkGF2RBSDMcjs = require('./chunk-GF2RBSDM.cjs');
@@ -1361,12 +1361,12 @@ var unit = (x, y) => {
1361
1361
  return l > 1e-12 && Number.isFinite(l) ? [x / l, y / l] : null;
1362
1362
  };
1363
1363
  function cubicOf(sp, i) {
1364
- const s = _chunkSNAFFCAXcjs.subpathSegment.call(void 0, sp, i);
1364
+ const s = _chunkOLZXXAERcjs.subpathSegment.call(void 0, sp, i);
1365
1365
  if (s.length === 4) return s;
1366
1366
  const [a, b] = s;
1367
1367
  return [a, [a[0] + (b[0] - a[0]) / 3, a[1] + (b[1] - a[1]) / 3], [a[0] + 2 * (b[0] - a[0]) / 3, a[1] + 2 * (b[1] - a[1]) / 3], b];
1368
1368
  }
1369
- var isLine = (sp, i) => _chunkSNAFFCAXcjs.subpathSegment.call(void 0, sp, i).length === 2;
1369
+ var isLine = (sp, i) => _chunkOLZXXAERcjs.subpathSegment.call(void 0, sp, i).length === 2;
1370
1370
  function startTangent(c) {
1371
1371
  for (let k = 1; k < 4; k++) {
1372
1372
  const u = unit(c[k][0] - c[0][0], c[k][1] - c[0][1]);
@@ -1386,10 +1386,10 @@ function sample(c, n, out, withStart) {
1386
1386
  }
1387
1387
  var onAnchor = (a, h) => !h || Math.abs(h.x - a.x) < EPS && Math.abs(h.y - a.y) < EPS;
1388
1388
  function tidy(a, keepType = true) {
1389
- const next = _chunkSNAFFCAXcjs.cloneAnchor.call(void 0, a);
1389
+ const next = _chunkOLZXXAERcjs.cloneAnchor.call(void 0, a);
1390
1390
  if (onAnchor(next, next.in)) delete next.in;
1391
1391
  if (onAnchor(next, next.out)) delete next.out;
1392
- const shown = _chunkSNAFFCAXcjs.inferAnchorType.call(void 0, next);
1392
+ const shown = _chunkOLZXXAERcjs.inferAnchorType.call(void 0, next);
1393
1393
  const type = keepType && a.type ? a.type === "symmetric" && shown !== "symmetric" ? shown === "corner" ? "corner" : "smooth" : a.type === "smooth" && shown === "corner" ? "corner" : a.type : shown;
1394
1394
  if (type === "corner") delete next.type;
1395
1395
  else next.type = type;
@@ -1433,7 +1433,7 @@ function fitAcross(pts, N, t0, t1) {
1433
1433
  return goldenMin(fit, 0, 1);
1434
1434
  }
1435
1435
  function removeAnchorKeepingShape(sp, index) {
1436
- const anchors = sp.anchors.map(_chunkSNAFFCAXcjs.cloneAnchor);
1436
+ const anchors = sp.anchors.map(_chunkOLZXXAERcjs.cloneAnchor);
1437
1437
  const n = anchors.length;
1438
1438
  if (index < 0 || index >= n) return { anchors, closed: sp.closed };
1439
1439
  if ((sp.closed || index > 0 && index < n - 1) && n >= 3) {
@@ -1467,12 +1467,12 @@ function removeAnchorKeepingShape(sp, index) {
1467
1467
  }
1468
1468
  function removeAnchorsKeepingShape(sp, indices) {
1469
1469
  const order = [...new Set(indices)].filter((i) => i >= 0 && i < sp.anchors.length).sort((a, b) => b - a);
1470
- return order.reduce((acc, i) => removeAnchorKeepingShape(acc, i), { anchors: sp.anchors.map(_chunkSNAFFCAXcjs.cloneAnchor), closed: sp.closed });
1470
+ return order.reduce((acc, i) => removeAnchorKeepingShape(acc, i), { anchors: sp.anchors.map(_chunkOLZXXAERcjs.cloneAnchor), closed: sp.closed });
1471
1471
  }
1472
1472
  function bendSegment(sp, segment, t, p) {
1473
- const anchors = sp.anchors.map(_chunkSNAFFCAXcjs.cloneAnchor);
1473
+ const anchors = sp.anchors.map(_chunkOLZXXAERcjs.cloneAnchor);
1474
1474
  const n = anchors.length;
1475
- if (segment < 0 || segment >= _chunkSNAFFCAXcjs.subpathSegmentCount.call(void 0, sp) || !Number.isFinite(t) || !Number.isFinite(p.x) || !Number.isFinite(p.y)) return { anchors, closed: sp.closed };
1475
+ if (segment < 0 || segment >= _chunkOLZXXAERcjs.subpathSegmentCount.call(void 0, sp) || !Number.isFinite(t) || !Number.isFinite(p.x) || !Number.isFinite(p.y)) return { anchors, closed: sp.closed };
1476
1476
  const tc = Math.min(0.95, Math.max(0.05, t));
1477
1477
  const ia = segment;
1478
1478
  const ib = (segment + 1) % n;
@@ -1483,16 +1483,16 @@ function bendSegment(sp, segment, t, p) {
1483
1483
  const oy = (p.y - (a.y + (b.y - a.y) * tc)) / k;
1484
1484
  const c1 = { x: a.x + (b.x - a.x) / 3 + ox, y: a.y + (b.y - a.y) / 3 + oy };
1485
1485
  const c2 = { x: b.x + (a.x - b.x) / 3 + ox, y: b.y + (a.y - b.y) / 3 + oy };
1486
- anchors[ia] = _chunkSNAFFCAXcjs.moveAnchorHandle.call(void 0, a, "out", c1);
1487
- anchors[ib] = _chunkSNAFFCAXcjs.moveAnchorHandle.call(void 0, b, "in", c2);
1486
+ anchors[ia] = _chunkOLZXXAERcjs.moveAnchorHandle.call(void 0, a, "out", c1);
1487
+ anchors[ib] = _chunkOLZXXAERcjs.moveAnchorHandle.call(void 0, b, "in", c2);
1488
1488
  return { anchors, closed: sp.closed };
1489
1489
  }
1490
1490
  function subpathPointAt(sp, segment, t) {
1491
- const [x, y] = _chunkGF2RBSDMcjs.segmentPoint.call(void 0, _chunkSNAFFCAXcjs.subpathSegment.call(void 0, sp, segment), t);
1491
+ const [x, y] = _chunkGF2RBSDMcjs.segmentPoint.call(void 0, _chunkOLZXXAERcjs.subpathSegment.call(void 0, sp, segment), t);
1492
1492
  return { x, y };
1493
1493
  }
1494
1494
  function curvatureMoveAnchor(sp, index, q) {
1495
- const anchors = sp.anchors.map(_chunkSNAFFCAXcjs.cloneAnchor);
1495
+ const anchors = sp.anchors.map(_chunkOLZXXAERcjs.cloneAnchor);
1496
1496
  const a = sp.anchors[index];
1497
1497
  if (!a) return { anchors, closed: sp.closed };
1498
1498
  const own = [
@@ -1538,7 +1538,7 @@ function curvatureMoveAnchor(sp, index, q) {
1538
1538
  function cutSubpathAt(sp, at) {
1539
1539
  const n = sp.anchors.length;
1540
1540
  const cuts = [...new Set(at)].filter((i) => Number.isInteger(i) && i >= 0 && i < n && (sp.closed || i > 0 && i < n - 1)).sort((a, b) => a - b);
1541
- if (!cuts.length || n < 2) return [{ anchors: sp.anchors.map(_chunkSNAFFCAXcjs.cloneAnchor), closed: sp.closed }];
1541
+ if (!cuts.length || n < 2) return [{ anchors: sp.anchors.map(_chunkOLZXXAERcjs.cloneAnchor), closed: sp.closed }];
1542
1542
  const first = cuts[0];
1543
1543
  const run = sp.closed ? Array.from({ length: n + 1 }, (_, i) => sp.anchors[(first + i) % n]) : sp.anchors;
1544
1544
  const cutSet = new Set(sp.closed ? [...cuts.map((c) => (c - first + n) % n), n] : cuts);
@@ -1546,7 +1546,7 @@ function cutSubpathAt(sp, at) {
1546
1546
  let cur = [];
1547
1547
  run.forEach((a, i) => {
1548
1548
  if (!cutSet.has(i)) {
1549
- cur.push(_chunkSNAFFCAXcjs.cloneAnchor.call(void 0, a));
1549
+ cur.push(_chunkOLZXXAERcjs.cloneAnchor.call(void 0, a));
1550
1550
  return;
1551
1551
  }
1552
1552
  if (cur.length) {
@@ -1561,10 +1561,10 @@ function cutSubpathAt(sp, at) {
1561
1561
  }
1562
1562
  function splitSubpathAt(sp, segment, t, endTolerance = 1e-6) {
1563
1563
  const n = sp.anchors.length;
1564
- if (segment < 0 || segment >= _chunkSNAFFCAXcjs.subpathSegmentCount.call(void 0, sp)) return [{ anchors: sp.anchors.map(_chunkSNAFFCAXcjs.cloneAnchor), closed: sp.closed }];
1564
+ if (segment < 0 || segment >= _chunkOLZXXAERcjs.subpathSegmentCount.call(void 0, sp)) return [{ anchors: sp.anchors.map(_chunkOLZXXAERcjs.cloneAnchor), closed: sp.closed }];
1565
1565
  if (t <= endTolerance) return cutSubpathAt(sp, [segment]);
1566
1566
  if (t >= 1 - endTolerance) return cutSubpathAt(sp, [(segment + 1) % n]);
1567
- const { subpath, index } = _chunkSNAFFCAXcjs.insertAnchor.call(void 0, sp, segment, t);
1567
+ const { subpath, index } = _chunkOLZXXAERcjs.insertAnchor.call(void 0, sp, segment, t);
1568
1568
  return cutSubpathAt(subpath, [index]);
1569
1569
  }
1570
1570
  var endOf = (sp, last) => sp.anchors[last ? sp.anchors.length - 1 : 0];
@@ -1587,7 +1587,7 @@ function joinSubpaths(subpaths, tolerance) {
1587
1587
  const closed = [];
1588
1588
  let open = [];
1589
1589
  for (const sp of subpaths) {
1590
- const copy = { anchors: sp.anchors.map(_chunkSNAFFCAXcjs.cloneAnchor), closed: sp.closed };
1590
+ const copy = { anchors: sp.anchors.map(_chunkOLZXXAERcjs.cloneAnchor), closed: sp.closed };
1591
1591
  if (sp.closed || sp.anchors.length < 2) {
1592
1592
  if (sp.anchors.length) closed.push(copy);
1593
1593
  } else open.push(copy);
@@ -1642,7 +1642,7 @@ function smoothSubpath(sp, amount = 1, only) {
1642
1642
  const t = Math.min(1, Math.max(0, amount));
1643
1643
  const orig = sp.anchors;
1644
1644
  const n = orig.length;
1645
- const anchors = orig.map(_chunkSNAFFCAXcjs.cloneAnchor);
1645
+ const anchors = orig.map(_chunkOLZXXAERcjs.cloneAnchor);
1646
1646
  if (n < 3 || t === 0) return { anchors, closed: sp.closed };
1647
1647
  for (let i = 0; i < n; i++) {
1648
1648
  if (!sp.closed && (i === 0 || i === n - 1)) continue;
@@ -1671,8 +1671,8 @@ function smoothSubpath(sp, amount = 1, only) {
1671
1671
  }
1672
1672
  function segsOf(sp) {
1673
1673
  const out = [];
1674
- for (let i = 0; i < _chunkSNAFFCAXcjs.subpathSegmentCount.call(void 0, sp); i++) {
1675
- const s = _chunkSNAFFCAXcjs.subpathSegment.call(void 0, sp, i);
1674
+ for (let i = 0; i < _chunkOLZXXAERcjs.subpathSegmentCount.call(void 0, sp); i++) {
1675
+ const s = _chunkOLZXXAERcjs.subpathSegment.call(void 0, sp, i);
1676
1676
  out.push(s.length === 2 ? { c: s, line: true } : { c: s, line: false });
1677
1677
  }
1678
1678
  return out;
@@ -1729,7 +1729,7 @@ function removeRedundantPoints(sp, tolerance) {
1729
1729
  const tol = Math.max(tolerance, 1e-9);
1730
1730
  const types = new Map(sp.anchors.filter((a) => a.type).map((a) => [`${a.x},${a.y}`, a.type]));
1731
1731
  const segs = segsOf(sp).filter((s) => !isZeroSeg(s));
1732
- if (!segs.length) return { anchors: sp.anchors.map(_chunkSNAFFCAXcjs.cloneAnchor), closed: sp.closed };
1732
+ if (!segs.length) return { anchors: sp.anchors.map(_chunkOLZXXAERcjs.cloneAnchor), closed: sp.closed };
1733
1733
  const minSegs = sp.closed ? 2 : 1;
1734
1734
  let changed = true;
1735
1735
  while (changed && segs.length > minSegs) {
@@ -1747,7 +1747,7 @@ function removeRedundantPoints(sp, tolerance) {
1747
1747
  break;
1748
1748
  }
1749
1749
  }
1750
- return _nullishCoalesce(segsToSubpath(segs, sp.closed, types), () => ( { anchors: sp.anchors.map(_chunkSNAFFCAXcjs.cloneAnchor), closed: sp.closed }));
1750
+ return _nullishCoalesce(segsToSubpath(segs, sp.closed, types), () => ( { anchors: sp.anchors.map(_chunkOLZXXAERcjs.cloneAnchor), closed: sp.closed }));
1751
1751
  }
1752
1752
 
1753
1753