@pixerate/editor 0.248.0 → 0.249.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 (89) hide show
  1. package/README.md +1 -0
  2. package/dist/animation-editor/index.cjs +64 -61
  3. package/dist/animation-editor/index.js +8 -5
  4. package/dist/{brushstrokeRender-DTDPFBLC.cjs → brushstrokeRender-GCKK7V2I.cjs} +14 -11
  5. package/dist/{brushstrokeRender-QLCXROJK.js → brushstrokeRender-T3JZST44.js} +7 -4
  6. package/dist/canvas/index.cjs +8 -8
  7. package/dist/canvas/index.js +1 -1
  8. package/dist/{chunk-IBDU6EGZ.cjs → chunk-2SMMZDMG.cjs} +35 -35
  9. package/dist/{chunk-SC2RZ5EF.js → chunk-2VJAVXLI.js} +2 -2
  10. package/dist/{chunk-OLNIPTB3.cjs → chunk-2VX55NFM.cjs} +1 -320
  11. package/dist/chunk-3K6HWEXZ.cjs +92 -0
  12. package/dist/{chunk-UOOK7HTX.js → chunk-3PPJRMIG.js} +1 -1
  13. package/dist/chunk-4D6KP5BV.js +92 -0
  14. package/dist/chunk-5RH3VXAK.js +269 -0
  15. package/dist/{chunk-NZ3O3A5C.js → chunk-6BIDVPED.js} +1 -1
  16. package/dist/{chunk-2ONK3ERD.cjs → chunk-75K3W4D6.cjs} +20 -20
  17. package/dist/{chunk-7T7JWTVE.cjs → chunk-BOHDJJ2O.cjs} +8 -8
  18. package/dist/{chunk-2PBZBRP5.js → chunk-D5KGAO4Z.js} +10 -92
  19. package/dist/{chunk-5GLYUSNT.js → chunk-DOIU7VJG.js} +1 -1
  20. package/dist/{chunk-HB4ICNNA.cjs → chunk-DPYAO5U6.cjs} +42 -42
  21. package/dist/chunk-EJLRBS5Q.js +301 -0
  22. package/dist/{chunk-6G6ZDDDB.cjs → chunk-H4AOUUBE.cjs} +301 -149
  23. package/dist/{chunk-PQ3H2AAN.cjs → chunk-I7NJPHWV.cjs} +122 -204
  24. package/dist/{chunk-L6REDLNB.cjs → chunk-IOFVM3L3.cjs} +7 -7
  25. package/dist/{chunk-42TWUPNJ.js → chunk-IRSTHLQQ.js} +1 -320
  26. package/dist/{chunk-VNBUDVD4.js → chunk-J7T5QZ45.js} +226 -74
  27. package/dist/{chunk-VMROIWLL.cjs → chunk-KBYB7OWB.cjs} +3 -3
  28. package/dist/{chunk-TPWB4Y6L.cjs → chunk-KYX7NZ5V.cjs} +1 -1
  29. package/dist/chunk-LJRCU3BJ.cjs +301 -0
  30. package/dist/{chunk-WVS5KQDH.cjs → chunk-LP2MCSBE.cjs} +246 -244
  31. package/dist/{chunk-XNRBMYNB.js → chunk-O75V4ZS3.js} +1 -1
  32. package/dist/chunk-OTTT5N3K.js +322 -0
  33. package/dist/{chunk-Q2HA52V4.js → chunk-PZP2SZIZ.js} +2 -2
  34. package/dist/{chunk-ZFSLEOSQ.js → chunk-UBRJOIR5.js} +11 -9
  35. package/dist/chunk-W5M3J7PV.cjs +322 -0
  36. package/dist/{chunk-4P6H35HU.js → chunk-WA44NKPF.js} +2 -2
  37. package/dist/{chunk-XWTRATIM.cjs → chunk-WLJZZHUZ.cjs} +23 -23
  38. package/dist/{chunk-P3NIPIKS.js → chunk-WQCNC4DK.js} +1 -1
  39. package/dist/chunk-ZEYMKDYS.cjs +269 -0
  40. package/dist/image-editor/index.cjs +1055 -1050
  41. package/dist/image-editor/index.js +28 -23
  42. package/dist/paint/index.cjs +8 -5
  43. package/dist/paint/index.js +13 -10
  44. package/dist/paint-editor/controller.d.cts +37 -1
  45. package/dist/paint-editor/controller.d.ts +37 -1
  46. package/dist/paint-editor/index.cjs +745 -602
  47. package/dist/paint-editor/index.d.cts +3 -0
  48. package/dist/paint-editor/index.d.ts +3 -0
  49. package/dist/paint-editor/index.js +184 -41
  50. package/dist/paint-editor/sticker-art.d.cts +55 -0
  51. package/dist/paint-editor/sticker-art.d.ts +55 -0
  52. package/dist/paint-editor/stickers.d.cts +30 -17
  53. package/dist/paint-editor/stickers.d.ts +30 -17
  54. package/dist/paint-editor/stroke.d.cts +4 -0
  55. package/dist/paint-editor/stroke.d.ts +4 -0
  56. package/dist/paint-editor/ui.d.cts +10 -2
  57. package/dist/paint-editor/ui.d.ts +10 -2
  58. package/dist/raster/index.cjs +6 -4
  59. package/dist/raster/index.js +12 -10
  60. package/dist/stickers/browser.d.cts +48 -0
  61. package/dist/stickers/browser.d.ts +48 -0
  62. package/dist/stickers/combine.d.cts +10 -0
  63. package/dist/stickers/combine.d.ts +10 -0
  64. package/dist/stickers/conformance.d.cts +18 -0
  65. package/dist/stickers/conformance.d.ts +18 -0
  66. package/dist/stickers/editor.d.cts +14 -0
  67. package/dist/stickers/editor.d.ts +14 -0
  68. package/dist/stickers/errors.d.cts +6 -0
  69. package/dist/stickers/errors.d.ts +6 -0
  70. package/dist/stickers/fake.d.cts +16 -0
  71. package/dist/stickers/fake.d.ts +16 -0
  72. package/dist/stickers/helpers.d.cts +51 -0
  73. package/dist/stickers/helpers.d.ts +51 -0
  74. package/dist/stickers/index.cjs +331 -0
  75. package/dist/stickers/index.d.cts +16 -0
  76. package/dist/stickers/index.d.ts +16 -0
  77. package/dist/stickers/index.js +331 -0
  78. package/dist/stickers/stamps.d.cts +13 -0
  79. package/dist/stickers/stamps.d.ts +13 -0
  80. package/dist/stickers/tools.d.cts +25 -0
  81. package/dist/stickers/tools.d.ts +25 -0
  82. package/dist/stickers/types.d.cts +123 -0
  83. package/dist/stickers/types.d.ts +123 -0
  84. package/dist/vector/index.cjs +978 -975
  85. package/dist/vector/index.js +9 -6
  86. package/package.json +11 -1
  87. package/skills/README.md +1 -0
  88. package/skills/pixerate-paint-editor/SKILL.md +8 -5
  89. package/skills/pixerate-stickers/SKILL.md +45 -0
@@ -1,5 +1,9 @@
1
1
  "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; } var _class; var _class2; var _class3; var _class4; var _class5; var _class6; var _class7; var _class8; var _class9; var _class10; var _class11; var _class12; var _class13; var _class14;
2
2
 
3
+
4
+ var _chunkLJRCU3BJcjs = require('../chunk-LJRCU3BJ.cjs');
5
+
6
+
3
7
  var _chunkXNZFVYC2cjs = require('../chunk-XNZFVYC2.cjs');
4
8
 
5
9
 
@@ -8,7 +12,7 @@ var _chunkXNZFVYC2cjs = require('../chunk-XNZFVYC2.cjs');
8
12
 
9
13
 
10
14
 
11
- var _chunkWVS5KQDHcjs = require('../chunk-WVS5KQDH.cjs');
15
+ var _chunkLP2MCSBEcjs = require('../chunk-LP2MCSBE.cjs');
12
16
  require('../chunk-A2IS7EHE.cjs');
13
17
  require('../chunk-SS53NNZO.cjs');
14
18
 
@@ -26,7 +30,7 @@ require('../chunk-SS53NNZO.cjs');
26
30
 
27
31
 
28
32
 
29
- var _chunkHB4ICNNAcjs = require('../chunk-HB4ICNNA.cjs');
33
+ var _chunkDPYAO5U6cjs = require('../chunk-DPYAO5U6.cjs');
30
34
  require('../chunk-QT26RHKK.cjs');
31
35
  require('../chunk-K6PXS6DO.cjs');
32
36
 
@@ -53,7 +57,7 @@ require('../chunk-K6PXS6DO.cjs');
53
57
 
54
58
 
55
59
 
56
- var _chunkVMROIWLLcjs = require('../chunk-VMROIWLL.cjs');
60
+ var _chunkKBYB7OWBcjs = require('../chunk-KBYB7OWB.cjs');
57
61
  require('../chunk-BROJYMWU.cjs');
58
62
 
59
63
 
@@ -64,7 +68,12 @@ var _chunkJLWLX52Lcjs = require('../chunk-JLWLX52L.cjs');
64
68
 
65
69
 
66
70
  var _chunkK7ENM55Pcjs = require('../chunk-K7ENM55P.cjs');
67
- require('../chunk-L6REDLNB.cjs');
71
+ require('../chunk-IOFVM3L3.cjs');
72
+
73
+
74
+
75
+
76
+
68
77
 
69
78
 
70
79
 
@@ -146,8 +155,15 @@ require('../chunk-L6REDLNB.cjs');
146
155
 
147
156
 
148
157
 
158
+ var _chunkH4AOUUBEcjs = require('../chunk-H4AOUUBE.cjs');
149
159
 
150
- var _chunk6G6ZDDDBcjs = require('../chunk-6G6ZDDDB.cjs');
160
+
161
+
162
+
163
+
164
+
165
+
166
+ var _chunkZEYMKDYScjs = require('../chunk-ZEYMKDYS.cjs');
151
167
  require('../chunk-CVFAAZXE.cjs');
152
168
  require('../chunk-GF2RBSDM.cjs');
153
169
  require('../chunk-NM3G4VQT.cjs');
@@ -214,13 +230,15 @@ require('../chunk-WOFXZ3XU.cjs');
214
230
 
215
231
 
216
232
 
233
+ var _chunkI7NJPHWVcjs = require('../chunk-I7NJPHWV.cjs');
217
234
 
218
235
 
219
236
 
220
237
 
221
238
 
222
239
 
223
- var _chunkPQ3H2AANcjs = require('../chunk-PQ3H2AAN.cjs');
240
+
241
+ var _chunk3K6HWEXZcjs = require('../chunk-3K6HWEXZ.cjs');
224
242
  require('../chunk-YQGCPL5X.cjs');
225
243
 
226
244
 
@@ -230,6 +248,8 @@ require('../chunk-YQGCPL5X.cjs');
230
248
 
231
249
 
232
250
 
251
+ var _chunk2VX55NFMcjs = require('../chunk-2VX55NFM.cjs');
252
+
233
253
 
234
254
 
235
255
 
@@ -237,7 +257,7 @@ require('../chunk-YQGCPL5X.cjs');
237
257
 
238
258
 
239
259
 
240
- var _chunkOLNIPTB3cjs = require('../chunk-OLNIPTB3.cjs');
260
+ var _chunkW5M3J7PVcjs = require('../chunk-W5M3J7PV.cjs');
241
261
 
242
262
 
243
263
 
@@ -309,7 +329,7 @@ function normalizeCanvas(raw) {
309
329
  function createPaintDocument(options = {}) {
310
330
  const canvas = normalizeCanvas({ width: _nullishCoalesce(options.width, () => ( 2048)), height: _nullishCoalesce(options.height, () => ( 1536)), dpi: options.dpi });
311
331
  const layer = createPaintLayer("Layer 1");
312
- return { canvas, paper: _chunk6G6ZDDDBcjs.normalizePaper.call(void 0, _nullishCoalesce(options.paper, () => ( {}))), layers: [layer], activeLayerId: layer.id, strokes: [] };
332
+ return { canvas, paper: _chunkH4AOUUBEcjs.normalizePaper.call(void 0, _nullishCoalesce(options.paper, () => ( {}))), layers: [layer], activeLayerId: layer.id, strokes: [] };
313
333
  }
314
334
 
315
335
  // src/paint-editor/dab-stroke.ts
@@ -334,7 +354,7 @@ function mixRgb(a, b, t, mixing) {
334
354
  if (mixing === "pigment") {
335
355
  const o = [0, 0, 0];
336
356
  const q = (v) => Math.round(Math.min(1, Math.max(0, v)) * 255);
337
- _chunkOLNIPTB3cjs.mixPigment8.call(void 0, q(a[0]), q(a[1]), q(a[2]), q(b[0]), q(b[1]), q(b[2]), t, o);
357
+ _chunk2VX55NFMcjs.mixPigment8.call(void 0, q(a[0]), q(a[1]), q(a[2]), q(b[0]), q(b[1]), q(b[2]), t, o);
338
358
  return [o[0], o[1], o[2]];
339
359
  }
340
360
  return [a[0] + (b[0] - a[0]) * t, a[1] + (b[1] - a[1]) * t, a[2] + (b[2] - a[2]) * t];
@@ -353,7 +373,7 @@ function multiColorForDab(mc, palette, index, seed, mixing) {
353
373
  const n = palette.length;
354
374
  if (mc.order === "random") {
355
375
  const run = Math.floor(index / mc.length);
356
- return [...palette[Math.min(n - 1, Math.floor(_chunkPQ3H2AANcjs.rand01.call(void 0, seed, run, 11) * n))]];
376
+ return [...palette[Math.min(n - 1, Math.floor(_chunk3K6HWEXZcjs.rand01.call(void 0, seed, run, 11) * n))]];
357
377
  }
358
378
  const f = index / mc.length % n;
359
379
  const i = Math.floor(f);
@@ -363,24 +383,24 @@ var PaintDabStroke = (_class = class {
363
383
  constructor(brush, options) {;_class.prototype.__init.call(this);_class.prototype.__init2.call(this);_class.prototype.__init3.call(this);_class.prototype.__init4.call(this);_class.prototype.__init5.call(this);_class.prototype.__init6.call(this);_class.prototype.__init7.call(this);_class.prototype.__init8.call(this);_class.prototype.__init9.call(this);_class.prototype.__init10.call(this);
364
384
  this.brush = brush;
365
385
  this.options = options;
366
- this.smoother = new (0, _chunk6G6ZDDDBcjs.PenSmoother)(brush.tip.smoothing, brush.pressureSmoothing);
367
- this.copies = _optionalChain([options, 'access', _2 => _2.copies, 'optionalAccess', _3 => _3.length]) ? options.copies : [_chunk6G6ZDDDBcjs.IDENTITY_COPY];
386
+ this.smoother = new (0, _chunkH4AOUUBEcjs.PenSmoother)(brush.tip.smoothing, brush.pressureSmoothing);
387
+ this.copies = _optionalChain([options, 'access', _2 => _2.copies, 'optionalAccess', _3 => _3.length]) ? options.copies : [_chunkH4AOUUBEcjs.IDENTITY_COPY];
368
388
  const exchanging = brush.engine === "mixer" || brush.engine === "dab";
369
- const rates = brush.engine === "mixer" ? _chunkPQ3H2AANcjs.mixerRates.call(void 0, brush.mixer) : _chunkPQ3H2AANcjs.exchangeRates.call(void 0, brush.behavior.pickup, brush.behavior.mix, 1, brush.behavior.mixing);
389
+ const rates = brush.engine === "mixer" ? _chunkI7NJPHWVcjs.mixerRates.call(void 0, brush.mixer) : _chunkI7NJPHWVcjs.exchangeRates.call(void 0, brush.behavior.pickup, brush.behavior.mix, 1, brush.behavior.mixing);
370
390
  this.mixing = brush.engine === "mixer" ? brush.mixer.mixing : brush.behavior.mixing;
371
391
  this.states = this.copies.map((c, i) => ({
372
- walker: new (0, _chunk6G6ZDDDBcjs.PenDabWalker)(brush, (_nullishCoalesce(options.seed, () => ( 0))) + i * 7919 | 0, c.linear),
373
- exchange: exchanging ? new (0, _chunkPQ3H2AANcjs.PaintExchange)(rates, options.load) : null,
374
- smudge: brush.engine === "smudge" ? new (0, _chunkPQ3H2AANcjs.SmudgeTip)(brush.smudge, brush.tip.size * (1 + brush.dynamics.tiltSize * 1.5)) : null
392
+ walker: new (0, _chunkH4AOUUBEcjs.PenDabWalker)(brush, (_nullishCoalesce(options.seed, () => ( 0))) + i * 7919 | 0, c.linear),
393
+ exchange: exchanging ? new (0, _chunkI7NJPHWVcjs.PaintExchange)(rates, options.load) : null,
394
+ smudge: brush.engine === "smudge" ? new (0, _chunkI7NJPHWVcjs.SmudgeTip)(brush.smudge, brush.tip.size * (1 + brush.dynamics.tiltSize * 1.5)) : null
375
395
  }));
376
- this.medium = new (0, _chunkPQ3H2AANcjs.TileMedium)(options.target, brush.engine === "dab" ? { blend: brush.tip.blend } : {});
396
+ this.medium = new (0, _chunkI7NJPHWVcjs.TileMedium)(options.target, brush.engine === "dab" ? { blend: brush.tip.blend } : {});
377
397
  this.depth = options.grain && !options.grain.flat ? Math.min(1, Math.max(0, options.paperDepth * brush.grain)) : 0;
378
- this.coverage = brush.engine === "dab" ? new (0, _chunkPQ3H2AANcjs.CoverageMap)() : null;
379
- this.sampler = exchanging && options.paint ? new (0, _chunkPQ3H2AANcjs.PaintGradientSampler)(options.paint, _nullishCoalesce(options.seed, () => ( 0))) : null;
398
+ this.coverage = brush.engine === "dab" ? new (0, _chunkI7NJPHWVcjs.CoverageMap)() : null;
399
+ this.sampler = exchanging && options.paint ? new (0, _chunkI7NJPHWVcjs.PaintGradientSampler)(options.paint, _nullishCoalesce(options.seed, () => ( 0))) : null;
380
400
  const table = _optionalChain([this, 'access', _4 => _4.sampler, 'optionalAccess', _5 => _5.acrossTip]) ? this.sampler.tipTable(GRADIENT_STEPS) : null;
381
401
  this.gradient = table ? table.map((e) => e.rgb) : null;
382
402
  this.gradientAlpha = table && table.some((e) => e.alpha < 1) ? table.map((e) => e.alpha) : null;
383
- this.scratch = brush.engine === "blender" ? _chunkPQ3H2AANcjs.createBlenderScratch.call(void 0, ) : null;
403
+ this.scratch = brush.engine === "blender" ? _chunkI7NJPHWVcjs.createBlenderScratch.call(void 0, ) : null;
384
404
  }
385
405
 
386
406
 
@@ -439,7 +459,7 @@ var PaintDabStroke = (_class = class {
439
459
  }
440
460
  paintDabs(copy, dabs, rects) {
441
461
  for (const d of dabs) {
442
- const rect = _chunkPQ3H2AANcjs.dabRect.call(void 0, d, this.brush.tip.hardness);
462
+ const rect = _chunkI7NJPHWVcjs.dabRect.call(void 0, d, this.brush.tip.hardness);
443
463
  if (rect.width <= 0 || rect.height <= 0) continue;
444
464
  this.dab(copy, d, rect);
445
465
  rects.push(rect);
@@ -455,13 +475,13 @@ var PaintDabStroke = (_class = class {
455
475
  }
456
476
  const tip = this.tip.subarray(0, n);
457
477
  tip.fill(0);
458
- _chunkPQ3H2AANcjs.rasterizeDab.call(void 0, { ...d, alpha: 1 }, this.brush.tip.hardness, rect, tip);
478
+ _chunkI7NJPHWVcjs.rasterizeDab.call(void 0, { ...d, alpha: 1 }, this.brush.tip.hardness, rect, tip);
459
479
  if (!(this.depth > 0 && this.options.grain)) return { tip, cov: tip };
460
480
  const cov = this.cov.subarray(0, n);
461
481
  const grain = this.options.grain;
462
482
  for (let yy = 0, k = 0; yy < rect.height; yy++) {
463
483
  const y = rect.y + yy + 0.5;
464
- for (let xx = 0; xx < rect.width; xx++, k++) cov[k] = tip[k] > 0 ? tip[k] * _chunkPQ3H2AANcjs.grainCatch.call(void 0, grain.at(rect.x + xx + 0.5, y), this.depth, d.pressure) : 0;
484
+ for (let xx = 0; xx < rect.width; xx++, k++) cov[k] = tip[k] > 0 ? tip[k] * _chunkI7NJPHWVcjs.grainCatch.call(void 0, grain.at(rect.x + xx + 0.5, y), this.depth, d.pressure) : 0;
465
485
  }
466
486
  return { tip, cov };
467
487
  }
@@ -470,7 +490,7 @@ var PaintDabStroke = (_class = class {
470
490
  const { tip, cov } = this.rasterize(d, rect);
471
491
  const st = this.states[copy];
472
492
  if (brush.engine === "blender") {
473
- _chunkPQ3H2AANcjs.blenderDab.call(void 0, this.medium, rect, cov, d.opacity * d.alpha * brush.tip.opacity, d.radius, brush.blender, this.scratch);
493
+ _chunkI7NJPHWVcjs.blenderDab.call(void 0, this.medium, rect, cov, d.opacity * d.alpha * brush.tip.opacity, d.radius, brush.blender, this.scratch);
474
494
  return;
475
495
  }
476
496
  if (brush.engine === "smudge") {
@@ -482,7 +502,7 @@ var PaintDabStroke = (_class = class {
482
502
  let flow = 1;
483
503
  if (this.options.effect) {
484
504
  const rgb = [0, 0, 0];
485
- flow = _chunk6G6ZDDDBcjs.sampleEffectAt.call(void 0, this.options.effect, d.x, d.y, rgb, d);
505
+ flow = _chunkH4AOUUBEcjs.sampleEffectAt.call(void 0, this.options.effect, d.x, d.y, rgb, d);
486
506
  ex.setReservoirColor(rgb[0], rgb[1], rgb[2]);
487
507
  } else if (this.sampler && !this.gradient) {
488
508
  const g = this.sampler.dab(d, this.sample);
@@ -650,10 +670,10 @@ function lightTile(color, height, heightAround, material, light) {
650
670
  const nh = Math.max(0, nx * hx + ny * hy + nz * hz);
651
671
  const spec = Math.max(0, Math.pow(nh, shininess) - Math.pow(hz, shininess)) * (0.25 + 0.75 * gloss) * light.relief;
652
672
  for (let c = 0; c < 3; c++) {
653
- const a = _chunkVMROIWLLcjs.SRGB_TO_LINEAR[color[i + c]];
673
+ const a = _chunkKBYB7OWBcjs.SRGB_TO_LINEAR[color[i + c]];
654
674
  const tint = metal * a + (1 - metal);
655
675
  const v = a * shade * (1 - 0.35 * metal) + spec * tint * (1 + metal);
656
- out[i + c] = _chunkVMROIWLLcjs.linearToSrgb8.call(void 0, v);
676
+ out[i + c] = _chunkKBYB7OWBcjs.linearToSrgb8.call(void 0, v);
657
677
  }
658
678
  }
659
679
  }
@@ -713,19 +733,19 @@ var ThickStrokeDriver = (_class3 = class {
713
733
  constructor(init) {;_class3.prototype.__init12.call(this);_class3.prototype.__init13.call(this);_class3.prototype.__init14.call(this);_class3.prototype.__init15.call(this);_class3.prototype.__init16.call(this);_class3.prototype.__init17.call(this);_class3.prototype.__init18.call(this);_class3.prototype.__init19.call(this);_class3.prototype.__init20.call(this);_class3.prototype.__init21.call(this);
714
734
  this.init = init;
715
735
  const b = init.brush;
716
- this.smoother = new (0, _chunk6G6ZDDDBcjs.PenSmoother)(b.tip.smoothing, b.pressureSmoothing);
717
- const copies = init.copies.length ? init.copies : [_chunk6G6ZDDDBcjs.IDENTITY_COPY];
736
+ this.smoother = new (0, _chunkH4AOUUBEcjs.PenSmoother)(b.tip.smoothing, b.pressureSmoothing);
737
+ const copies = init.copies.length ? init.copies : [_chunkH4AOUUBEcjs.IDENTITY_COPY];
718
738
  this.copies = copies;
719
- const rates = _chunkPQ3H2AANcjs.exchangeRates.call(void 0, b.behavior.pickup, b.behavior.mix, 1, b.behavior.mixing);
739
+ const rates = _chunkI7NJPHWVcjs.exchangeRates.call(void 0, b.behavior.pickup, b.behavior.mix, 1, b.behavior.mixing);
720
740
  this.states = copies.map((c, i) => ({
721
- walker: new (0, _chunk6G6ZDDDBcjs.PenDabWalker)(b, init.seed + i * 7919 | 0, c.linear),
722
- exchange: new (0, _chunkPQ3H2AANcjs.PaintExchange)(rates, init.load),
723
- smudge: b.impasto.tool === "knife" ? new (0, _chunkPQ3H2AANcjs.SmudgeTip)({ strength: 0.85, length: 0.6 + 0.38 * b.impasto.drag, mixing: b.behavior.mixing }, b.tip.size * 1.2) : null,
741
+ walker: new (0, _chunkH4AOUUBEcjs.PenDabWalker)(b, init.seed + i * 7919 | 0, c.linear),
742
+ exchange: new (0, _chunkI7NJPHWVcjs.PaintExchange)(rates, init.load),
743
+ smudge: b.impasto.tool === "knife" ? new (0, _chunkI7NJPHWVcjs.SmudgeTip)({ strength: 0.85, length: 0.6 + 0.38 * b.impasto.drag, mixing: b.behavior.mixing }, b.tip.size * 1.2) : null,
724
744
  carried: null,
725
745
  amount: 1
726
746
  }));
727
- this.medium = new (0, _chunkPQ3H2AANcjs.TileMedium)(init.target, {});
728
- this.sampler = init.paint ? new (0, _chunkPQ3H2AANcjs.PaintGradientSampler)(init.paint.map.by === "across-tip" ? { ...init.paint, map: { by: "distance", length: 300, repeat: "mirror" } } : init.paint, init.seed) : null;
747
+ this.medium = new (0, _chunkI7NJPHWVcjs.TileMedium)(init.target, {});
748
+ this.sampler = init.paint ? new (0, _chunkI7NJPHWVcjs.PaintGradientSampler)(init.paint.map.by === "across-tip" ? { ...init.paint, map: { by: "distance", length: 300, repeat: "mirror" } } : init.paint, init.seed) : null;
729
749
  }
730
750
 
731
751
  __init12() {this.dabCount = 0}
@@ -822,7 +842,7 @@ var ThickStrokeDriver = (_class3 = class {
822
842
  }
823
843
  applyDabs(copy, dabs, rects) {
824
844
  for (const d of dabs) {
825
- const rect = _chunkPQ3H2AANcjs.dabRect.call(void 0, d, this.init.brush.tip.hardness);
845
+ const rect = _chunkI7NJPHWVcjs.dabRect.call(void 0, d, this.init.brush.tip.hardness);
826
846
  if (rect.width <= 0 || rect.height <= 0) continue;
827
847
  this.dab(copy, d, rect);
828
848
  rects.push(rect);
@@ -837,7 +857,7 @@ var ThickStrokeDriver = (_class3 = class {
837
857
  const n = rect.width * rect.height;
838
858
  if (this.tip.length < n) this.tip = new Float32Array(n);
839
859
  const tip = this.tip.subarray(0, n);
840
- _chunkPQ3H2AANcjs.rasterizeDab.call(void 0, { ...d, alpha: 1 }, b.tip.hardness, rect, tip);
860
+ _chunkI7NJPHWVcjs.rasterizeDab.call(void 0, { ...d, alpha: 1 }, b.tip.hardness, rect, tip);
841
861
  const sel = this.init.target.selection;
842
862
  if (sel) {
843
863
  for (let yy = 0, p = 0; yy < rect.height; yy++)
@@ -864,7 +884,7 @@ var ThickStrokeDriver = (_class3 = class {
864
884
  let flow = 1;
865
885
  const effect = this.init.effect;
866
886
  if (effect) {
867
- _chunk6G6ZDDDBcjs.sampleEffectAt.call(void 0, effect, d.x, d.y, this.centre, d);
887
+ _chunkH4AOUUBEcjs.sampleEffectAt.call(void 0, effect, d.x, d.y, this.centre, d);
868
888
  ex.setReservoirColor(this.centre[0], this.centre[1], this.centre[2]);
869
889
  } else if (this.sampler) {
870
890
  const g = this.sampler.dab(d, this.sample);
@@ -881,7 +901,7 @@ var ThickStrokeDriver = (_class3 = class {
881
901
  let field = null;
882
902
  if (effect) {
883
903
  field = new Float32Array(n * 3);
884
- _chunk6G6ZDDDBcjs.effectDabField.call(void 0, effect, rect, cov, this.centre, this.paint, field, 0, d);
904
+ _chunkH4AOUUBEcjs.effectDabField.call(void 0, effect, rect, cov, this.centre, this.paint, field, 0, d);
885
905
  }
886
906
  this.medium.deposit(rect, cov, dep, this.paint, ex.paintPigment, field);
887
907
  }
@@ -900,7 +920,7 @@ var ThickStrokeDriver = (_class3 = class {
900
920
  const full2 = 255 * thick * k;
901
921
  switch (im.tool) {
902
922
  case "brush": {
903
- const ridge = 0.6 + 0.4 * Math.sin(u * 9 + _chunkPQ3H2AANcjs.hash2.call(void 0, Math.round(u * 6), 3, seed) * 6.28) + 0.15 * (_chunkPQ3H2AANcjs.hash2.call(void 0, lx, ly, seed) - 0.5);
923
+ const ridge = 0.6 + 0.4 * Math.sin(u * 9 + _chunk3K6HWEXZcjs.hash2.call(void 0, Math.round(u * 6), 3, seed) * 6.28) + 0.15 * (_chunk3K6HWEXZcjs.hash2.call(void 0, lx, ly, seed) - 0.5);
904
924
  const target = full2 * c * ridge;
905
925
  h = Math.max(h0 * (1 - 0.25 * c * im.drag), Math.min(255, h0 * 0.35 + target));
906
926
  break;
@@ -916,7 +936,7 @@ var ThickStrokeDriver = (_class3 = class {
916
936
  break;
917
937
  }
918
938
  case "roller": {
919
- const stipple = 0.75 + 0.5 * _chunkPQ3H2AANcjs.hash2.call(void 0, lx >> 1, ly >> 1, seed);
939
+ const stipple = 0.75 + 0.5 * _chunk3K6HWEXZcjs.hash2.call(void 0, lx >> 1, ly >> 1, seed);
920
940
  h = h0 + (Math.min(255, full2 * 0.6 * stipple) - h0) * Math.min(1, c * 1.5);
921
941
  break;
922
942
  }
@@ -988,15 +1008,15 @@ function reliefInfo(ch) {
988
1008
  function thickToJSON(ch) {
989
1009
  const b = ch.height.bounds;
990
1010
  if (!b) return null;
991
- return { rect: { ...b }, height: _chunkOLNIPTB3cjs.pngDataUrl.call(void 0, b.width, b.height, _chunk474IQG74cjs.readRegion.call(void 0, ch.height, b), 1), material: _chunkOLNIPTB3cjs.pngDataUrl.call(void 0, b.width, b.height, _chunk474IQG74cjs.readRegion.call(void 0, ch.material, b), 4) };
1011
+ return { rect: { ...b }, height: _chunkW5M3J7PVcjs.pngDataUrl.call(void 0, b.width, b.height, _chunk474IQG74cjs.readRegion.call(void 0, ch.height, b), 1), material: _chunkW5M3J7PVcjs.pngDataUrl.call(void 0, b.width, b.height, _chunk474IQG74cjs.readRegion.call(void 0, ch.material, b), 4) };
992
1012
  }
993
1013
  function thickFromJSON(raw) {
994
1014
  const r = raw;
995
1015
  if (!r || typeof r !== "object" || !r.rect || typeof r.height !== "string" || typeof r.material !== "string") throw new Error("not saved thick-paint channels");
996
1016
  const decode = (url, gray) => {
997
- const parsed = _chunkOLNIPTB3cjs.parseDataUrl.call(void 0, url);
1017
+ const parsed = _chunkW5M3J7PVcjs.parseDataUrl.call(void 0, url);
998
1018
  if (!parsed) throw new Error("a channel is not a PNG data URL");
999
- return _chunkOLNIPTB3cjs.decodePng.call(void 0, parsed.bytes, { keepGray: gray });
1019
+ return _chunkW5M3J7PVcjs.decodePng.call(void 0, parsed.bytes, { keepGray: gray });
1000
1020
  };
1001
1021
  const h = decode(r.height, true);
1002
1022
  const m = decode(r.material, false);
@@ -1058,7 +1078,7 @@ function shadowToLight(shadow) {
1058
1078
  return new (0, _chunk474IQG74cjs.TiledSurface)(1, tiles, 0);
1059
1079
  }
1060
1080
  function lightTwinBrush(brush) {
1061
- return _chunk6G6ZDDDBcjs.normalizePaintBrush.call(void 0,
1081
+ return _chunkH4AOUUBEcjs.normalizePaintBrush.call(void 0,
1062
1082
  {
1063
1083
  tip: { ...brush.tip, blend: "normal", pressureOpacity: brush.tip.pressureOpacity || brush.light.pressure },
1064
1084
  behavior: { ...brush.behavior, mixing: "rgb" },
@@ -1250,14 +1270,14 @@ function boxBlur(p, w, h, r) {
1250
1270
  function lightToJSON(light) {
1251
1271
  const b = lightInfo(light).bounds;
1252
1272
  if (!b) return null;
1253
- return { rect: { ...b }, light: _chunkOLNIPTB3cjs.pngDataUrl.call(void 0, b.width, b.height, _chunk474IQG74cjs.readRegion.call(void 0, light, b), 1) };
1273
+ return { rect: { ...b }, light: _chunkW5M3J7PVcjs.pngDataUrl.call(void 0, b.width, b.height, _chunk474IQG74cjs.readRegion.call(void 0, light, b), 1) };
1254
1274
  }
1255
1275
  function lightFromJSON(raw) {
1256
1276
  const r = raw;
1257
1277
  if (!r || typeof r !== "object" || !r.rect || typeof r.light !== "string") throw new Error("not a saved light channel");
1258
- const parsed = _chunkOLNIPTB3cjs.parseDataUrl.call(void 0, r.light);
1278
+ const parsed = _chunkW5M3J7PVcjs.parseDataUrl.call(void 0, r.light);
1259
1279
  if (!parsed) throw new Error("the light is not a PNG data URL");
1260
- const img = _chunkOLNIPTB3cjs.decodePng.call(void 0, parsed.bytes, { keepGray: true });
1280
+ const img = _chunkW5M3J7PVcjs.decodePng.call(void 0, parsed.bytes, { keepGray: true });
1261
1281
  const data = img.channels === 1 ? img.data : Uint8ClampedArray.from({ length: img.width * img.height }, (_, i) => img.data[i * 4]);
1262
1282
  return _chunk474IQG74cjs.surfaceFromPixels.call(void 0, { width: img.width, height: img.height, data }, 1, r.rect.x, r.rect.y);
1263
1283
  }
@@ -1288,7 +1308,7 @@ var PaintStrokeSession = (_class5 = class _PaintStrokeSession {
1288
1308
  this.layerId = init.layerId;
1289
1309
  this.base = init.surface;
1290
1310
  this.live = new Map(this.base.tiles);
1291
- this.copies = init.copies.length ? init.copies : [_chunk6G6ZDDDBcjs.IDENTITY_COPY];
1311
+ this.copies = init.copies.length ? init.copies : [_chunkH4AOUUBEcjs.IDENTITY_COPY];
1292
1312
  const brush = init.brush;
1293
1313
  if (init.wet) this.wetDriver = init.wet.driver;
1294
1314
  if (init.light && !init.wet && !init.sticker) this.lightTwin = this.makeLightTwin(init.light.surface);
@@ -1305,11 +1325,11 @@ var PaintStrokeSession = (_class5 = class _PaintStrokeSession {
1305
1325
  };
1306
1326
  if (this.wetDriver) {
1307
1327
  } else if (init.sticker) {
1308
- this.stickerSpray = new (0, _chunk6G6ZDDDBcjs.StickerSpray)({ brush, target: this.tileTarget(), color: init.colorHex, seed: init.seed, copies: this.copies, nextId: init.sticker.nextId, paint: _nullishCoalesce(init.paint, () => ( null)), effect });
1328
+ this.stickerSpray = new (0, _chunkH4AOUUBEcjs.StickerSpray)({ brush, target: this.tileTarget(), color: init.colorHex, seed: init.seed, copies: this.copies, nextId: init.sticker.nextId, paint: _nullishCoalesce(init.paint, () => ( null)), effect, art: init.sticker.art });
1309
1329
  } else if (init.thick) {
1310
1330
  const rgb = (c) => [c[0] / 255, c[1] / 255, c[2] / 255];
1311
1331
  this.thickDriver = new ThickStrokeDriver({ brush, target: this.tileTarget(), channels: init.thick.channels, color: rgb(init.color), load: init.mixerLoad, seed: init.seed, copies: this.copies, paint: _nullishCoalesce(init.paint, () => ( null)), effect });
1312
- } else if (brush.engine === "mixer" || brush.engine === "blender" || brush.engine === "smudge" || _chunk6G6ZDDDBcjs.usesPaintExchange.call(void 0, brush, Boolean(init.paint))) {
1332
+ } else if (brush.engine === "mixer" || brush.engine === "blender" || brush.engine === "smudge" || _chunkH4AOUUBEcjs.usesPaintExchange.call(void 0, brush, Boolean(init.paint))) {
1313
1333
  const rgb = (c) => [c[0] / 255, c[1] / 255, c[2] / 255];
1314
1334
  this.wet = new PaintDabStroke(brush, {
1315
1335
  target: this.tileTarget(),
@@ -1325,7 +1345,7 @@ var PaintStrokeSession = (_class5 = class _PaintStrokeSession {
1325
1345
  });
1326
1346
  } else {
1327
1347
  const opts = { grain: init.grain, paperDepth: init.paperDepth, seed: init.seed, copies: this.copies, paint: _nullishCoalesce(init.paint, () => ( null)), effect };
1328
- this.dry = brush.engine === "particle" ? new (0, _chunk6G6ZDDDBcjs.ParticleStroke)(brush, opts) : brush.engine === "bristle" ? new (0, _chunk6G6ZDDDBcjs.BristleStroke)(brush, opts) : new (0, _chunk6G6ZDDDBcjs.DryStroke)(brush, opts);
1348
+ this.dry = brush.engine === "particle" ? new (0, _chunkH4AOUUBEcjs.ParticleStroke)(brush, opts) : brush.engine === "bristle" ? new (0, _chunkH4AOUUBEcjs.BristleStroke)(brush, opts) : new (0, _chunkH4AOUUBEcjs.DryStroke)(brush, opts);
1329
1349
  }
1330
1350
  }
1331
1351
 
@@ -1454,7 +1474,7 @@ var PaintStrokeSession = (_class5 = class _PaintStrokeSession {
1454
1474
  const changed = d.dabCount > 0;
1455
1475
  this.result = { layerId: this.layerId, bounds: changed ? d.bounds : null, dabs: d.dabCount, strokeId: null, wet: true };
1456
1476
  const carried = d.load;
1457
- if (carried) this.result.mixerLoad = this.init.brush.behavior.dirty ? carried : _chunkPQ3H2AANcjs.cleanMixer.call(void 0, carried);
1477
+ if (carried) this.result.mixerLoad = this.init.brush.behavior.dirty ? carried : _chunkI7NJPHWVcjs.cleanMixer.call(void 0, carried);
1458
1478
  this.host.commit(this, changed ? this.init.wet.surface() : null, false);
1459
1479
  }
1460
1480
  update(rects) {
@@ -1480,7 +1500,7 @@ var PaintStrokeSession = (_class5 = class _PaintStrokeSession {
1480
1500
  const src = _nullishCoalesce(_optionalChain([this, 'access', _53 => _53.base, 'access', _54 => _54.tiles, 'access', _55 => _55.get, 'call', _56 => _56(key), 'optionalAccess', _57 => _57.data]), () => ( defaultTile(this.base)));
1481
1501
  const prev = this.touched.has(key) ? _optionalChain([this, 'access', _58 => _58.live, 'access', _59 => _59.get, 'call', _60 => _60(key), 'optionalAccess', _61 => _61.data]) : void 0;
1482
1502
  this.touched.add(key);
1483
- const data = _chunkPQ3H2AANcjs.applyStrokeToTile.call(void 0, this.dry.coverage, src, ch, tx, ty, this.apply, prev ? { into: prev, region: r } : {});
1503
+ const data = _chunkI7NJPHWVcjs.applyStrokeToTile.call(void 0, this.dry.coverage, src, ch, tx, ty, this.apply, prev ? { into: prev, region: r } : {});
1484
1504
  this.live.set(key, { data, uniform: null });
1485
1505
  }
1486
1506
  this.host.update(this.layerId, new (0, _chunk474IQG74cjs.TiledSurface)(ch, new Map(this.live), this.base.defaultValue), rects);
@@ -1515,8 +1535,9 @@ var PaintStrokeSession = (_class5 = class _PaintStrokeSession {
1515
1535
  const surface = changed ? new (0, _chunk474IQG74cjs.TiledSurface)(ch, tiles, this.base.defaultValue) : null;
1516
1536
  const dabs = this.dry ? this.dry.dabCount : this.thickDriver ? this.thickDriver.dabCount : this.stickerSpray ? this.stickerSpray.dabCount : this.wet.dabCount;
1517
1537
  this.result = { layerId: this.layerId, bounds: changed ? this.bounds : null, dabs, strokeId: null };
1518
- const carried = _nullishCoalesce(_optionalChain([this, 'access', _64 => _64.wet, 'optionalAccess', _65 => _65.load]), () => ( _optionalChain([this, 'access', _66 => _66.thickDriver, 'optionalAccess', _67 => _67.load])));
1519
- if (carried) this.result.mixerLoad = this.init.brush.behavior.dirty ? carried : _chunkPQ3H2AANcjs.cleanMixer.call(void 0, carried);
1538
+ if (_optionalChain([this, 'access', _64 => _64.stickerSpray, 'optionalAccess', _65 => _65.skipped, 'access', _66 => _66.size])) this.result.skippedStickers = [...this.stickerSpray.skipped];
1539
+ const carried = _nullishCoalesce(_optionalChain([this, 'access', _67 => _67.wet, 'optionalAccess', _68 => _68.load]), () => ( _optionalChain([this, 'access', _69 => _69.thickDriver, 'optionalAccess', _70 => _70.load])));
1540
+ if (carried) this.result.mixerLoad = this.init.brush.behavior.dirty ? carried : _chunkI7NJPHWVcjs.cleanMixer.call(void 0, carried);
1520
1541
  this.host.commit(this, surface, false);
1521
1542
  return this.result;
1522
1543
  }
@@ -1524,7 +1545,7 @@ var PaintStrokeSession = (_class5 = class _PaintStrokeSession {
1524
1545
  cancel() {
1525
1546
  if (this.closed) return;
1526
1547
  this.closed = true;
1527
- if (_optionalChain([this, 'access', _68 => _68.lightTwin, 'optionalAccess', _69 => _69.open])) this.lightTwin.cancel();
1548
+ if (_optionalChain([this, 'access', _71 => _71.lightTwin, 'optionalAccess', _72 => _72.open])) this.lightTwin.cancel();
1528
1549
  this.lightResult = null;
1529
1550
  this.host.commit(this, null, true);
1530
1551
  }
@@ -1539,15 +1560,15 @@ function greyPixels(data, grey) {
1539
1560
  }
1540
1561
  function mixerLoadForStroke(brush, current, color) {
1541
1562
  if (!brush.loadsColor) return { reservoir: null, amount: 0, pickup: brush.mixer.cleanEachStroke ? null : current.pickup };
1542
- if (brush.mixer.loadEachStroke || !current.reservoir) return _chunkPQ3H2AANcjs.loadMixer.call(void 0, current, color);
1563
+ if (brush.mixer.loadEachStroke || !current.reservoir) return _chunkI7NJPHWVcjs.loadMixer.call(void 0, current, color);
1543
1564
  return current;
1544
1565
  }
1545
1566
  function brushLoadForStroke(brush, current, color) {
1546
1567
  if (brush.engine === "mixer") return mixerLoadForStroke(brush, current, color);
1547
1568
  if (brush.engine === "impasto") return { reservoir: [color[0], color[1], color[2]], amount: 1, pickup: brush.behavior.dirty ? current.pickup : null };
1548
- if (brush.engine === "wet") return brush.wet.tool === "paint" ? { reservoir: [color[0], color[1], color[2]], amount: 1, pickup: brush.behavior.dirty ? current.pickup : null } : _chunkPQ3H2AANcjs.EMPTY_MIXER_LOAD;
1549
- if (_chunk6G6ZDDDBcjs.usesPaintExchange.call(void 0, brush)) return { reservoir: [color[0], color[1], color[2]], amount: 1, pickup: brush.behavior.dirty ? current.pickup : null };
1550
- return _chunkPQ3H2AANcjs.EMPTY_MIXER_LOAD;
1569
+ if (brush.engine === "wet") return brush.wet.tool === "paint" ? { reservoir: [color[0], color[1], color[2]], amount: 1, pickup: brush.behavior.dirty ? current.pickup : null } : _chunkI7NJPHWVcjs.EMPTY_MIXER_LOAD;
1570
+ if (_chunkH4AOUUBEcjs.usesPaintExchange.call(void 0, brush)) return { reservoir: [color[0], color[1], color[2]], amount: 1, pickup: brush.behavior.dirty ? current.pickup : null };
1571
+ return _chunkI7NJPHWVcjs.EMPTY_MIXER_LOAD;
1551
1572
  }
1552
1573
 
1553
1574
  // src/paint-editor/stencils.ts
@@ -1556,36 +1577,36 @@ var STENCIL_SHAPES = ["rect", "ellipse", "polygon"];
1556
1577
  var finite = (v) => typeof v === "number" && Number.isFinite(v);
1557
1578
  var pt = (p) => p && finite(p.x) && finite(p.y) ? { x: p.x, y: p.y } : void 0;
1558
1579
  function normalizeStencil(raw, id, base) {
1559
- const kind = STENCIL_KINDS.includes(raw.kind) ? raw.kind : _optionalChain([base, 'optionalAccess', _70 => _70.kind]);
1580
+ const kind = STENCIL_KINDS.includes(raw.kind) ? raw.kind : _optionalChain([base, 'optionalAccess', _73 => _73.kind]);
1560
1581
  if (!kind) throw new Error(`kind ${JSON.stringify(raw.kind)} is not a stencil; use ${STENCIL_KINDS.join(", ")}.`);
1561
1582
  const s = {
1562
1583
  id,
1563
1584
  kind,
1564
- mode: raw.mode === "guide" || raw.mode === "mask" ? raw.mode : _nullishCoalesce(_optionalChain([base, 'optionalAccess', _71 => _71.mode]), () => ( (kind === "ruler" || kind === "arc" ? "guide" : "mask"))),
1565
- enabled: typeof raw.enabled === "boolean" ? raw.enabled : _nullishCoalesce(_optionalChain([base, 'optionalAccess', _72 => _72.enabled]), () => ( true)),
1566
- invert: typeof raw.invert === "boolean" ? raw.invert : _nullishCoalesce(_optionalChain([base, 'optionalAccess', _73 => _73.invert]), () => ( false)),
1567
- snap: finite(raw.snap) ? Math.min(400, Math.max(1, raw.snap)) : _nullishCoalesce(_optionalChain([base, 'optionalAccess', _74 => _74.snap]), () => ( 40)),
1568
- feather: finite(raw.feather) ? Math.min(100, Math.max(0, raw.feather)) : _nullishCoalesce(_optionalChain([base, 'optionalAccess', _75 => _75.feather]), () => ( 1))
1585
+ mode: raw.mode === "guide" || raw.mode === "mask" ? raw.mode : _nullishCoalesce(_optionalChain([base, 'optionalAccess', _74 => _74.mode]), () => ( (kind === "ruler" || kind === "arc" ? "guide" : "mask"))),
1586
+ enabled: typeof raw.enabled === "boolean" ? raw.enabled : _nullishCoalesce(_optionalChain([base, 'optionalAccess', _75 => _75.enabled]), () => ( true)),
1587
+ invert: typeof raw.invert === "boolean" ? raw.invert : _nullishCoalesce(_optionalChain([base, 'optionalAccess', _76 => _76.invert]), () => ( false)),
1588
+ snap: finite(raw.snap) ? Math.min(400, Math.max(1, raw.snap)) : _nullishCoalesce(_optionalChain([base, 'optionalAccess', _77 => _77.snap]), () => ( 40)),
1589
+ feather: finite(raw.feather) ? Math.min(100, Math.max(0, raw.feather)) : _nullishCoalesce(_optionalChain([base, 'optionalAccess', _78 => _78.feather]), () => ( 1))
1569
1590
  };
1570
1591
  if (kind === "ruler" || kind === "line") {
1571
- s.from = _nullishCoalesce(pt(raw.from), () => ( _optionalChain([base, 'optionalAccess', _76 => _76.from])));
1572
- s.to = _nullishCoalesce(pt(raw.to), () => ( _optionalChain([base, 'optionalAccess', _77 => _77.to])));
1592
+ s.from = _nullishCoalesce(pt(raw.from), () => ( _optionalChain([base, 'optionalAccess', _79 => _79.from])));
1593
+ s.to = _nullishCoalesce(pt(raw.to), () => ( _optionalChain([base, 'optionalAccess', _80 => _80.to])));
1573
1594
  if (!s.from || !s.to) throw new Error(`A ${kind} needs from and to points ({x, y} in document pixels).`);
1574
1595
  if (Math.hypot(s.to.x - s.from.x, s.to.y - s.from.y) < 1) throw new Error(`A ${kind}'s from and to must be at least 1 px apart.`);
1575
1596
  } else if (kind === "arc") {
1576
- s.center = _nullishCoalesce(pt(raw.center), () => ( _optionalChain([base, 'optionalAccess', _78 => _78.center])));
1577
- s.radius = finite(raw.radius) ? raw.radius : _optionalChain([base, 'optionalAccess', _79 => _79.radius]);
1597
+ s.center = _nullishCoalesce(pt(raw.center), () => ( _optionalChain([base, 'optionalAccess', _81 => _81.center])));
1598
+ s.radius = finite(raw.radius) ? raw.radius : _optionalChain([base, 'optionalAccess', _82 => _82.radius]);
1578
1599
  if (!s.center || !(s.radius > 0)) throw new Error("An arc needs a center ({x, y}) and a radius above 0.");
1579
- s.startAngle = finite(raw.startAngle) ? raw.startAngle : _nullishCoalesce(_optionalChain([base, 'optionalAccess', _80 => _80.startAngle]), () => ( 0));
1580
- s.endAngle = finite(raw.endAngle) ? raw.endAngle : _nullishCoalesce(_optionalChain([base, 'optionalAccess', _81 => _81.endAngle]), () => ( 360));
1600
+ s.startAngle = finite(raw.startAngle) ? raw.startAngle : _nullishCoalesce(_optionalChain([base, 'optionalAccess', _83 => _83.startAngle]), () => ( 0));
1601
+ s.endAngle = finite(raw.endAngle) ? raw.endAngle : _nullishCoalesce(_optionalChain([base, 'optionalAccess', _84 => _84.endAngle]), () => ( 360));
1581
1602
  } else {
1582
- s.shape = STENCIL_SHAPES.includes(raw.shape) ? raw.shape : _nullishCoalesce(_optionalChain([base, 'optionalAccess', _82 => _82.shape]), () => ( "rect"));
1603
+ s.shape = STENCIL_SHAPES.includes(raw.shape) ? raw.shape : _nullishCoalesce(_optionalChain([base, 'optionalAccess', _85 => _85.shape]), () => ( "rect"));
1583
1604
  if (s.shape === "polygon") {
1584
- const pts = Array.isArray(raw.points) ? raw.points.map(pt).filter((p) => Boolean(p)) : _optionalChain([base, 'optionalAccess', _83 => _83.points]);
1605
+ const pts = Array.isArray(raw.points) ? raw.points.map(pt).filter((p) => Boolean(p)) : _optionalChain([base, 'optionalAccess', _86 => _86.points]);
1585
1606
  if (!pts || pts.length < 3) throw new Error("A polygon stencil needs at least 3 points.");
1586
1607
  s.points = pts;
1587
1608
  } else {
1588
- const r = _nullishCoalesce(raw.rect, () => ( _optionalChain([base, 'optionalAccess', _84 => _84.rect])));
1609
+ const r = _nullishCoalesce(raw.rect, () => ( _optionalChain([base, 'optionalAccess', _87 => _87.rect])));
1589
1610
  if (!r || !finite(r.x) || !finite(r.y) || !(r.width > 0) || !(r.height > 0)) throw new Error(`A ${s.shape} stencil needs rect {x, y, width, height} with a width and height above 0.`);
1590
1611
  s.rect = { x: r.x, y: r.y, width: r.width, height: r.height };
1591
1612
  }
@@ -1667,7 +1688,7 @@ var StencilSnapper = class {
1667
1688
  const { distance } = nearestOnStencil(s, p);
1668
1689
  if (distance <= s.snap && (!best || distance < best.d)) best = { s, d: distance };
1669
1690
  }
1670
- this.guide = _nullishCoalesce(_optionalChain([best, 'optionalAccess', _85 => _85.s]), () => ( null));
1691
+ this.guide = _nullishCoalesce(_optionalChain([best, 'optionalAccess', _88 => _88.s]), () => ( null));
1671
1692
  }
1672
1693
  if (!this.guide) return p;
1673
1694
  const q = nearestOnStencil(this.guide, p).point;
@@ -1814,7 +1835,7 @@ function normalizeBrushStroke(raw) {
1814
1835
  const out = {
1815
1836
  id: r.id,
1816
1837
  layerId: r.layerId,
1817
- brush: _chunk6G6ZDDDBcjs.normalizePaintBrush.call(void 0, _nullishCoalesce(r.brush, () => ( {}))),
1838
+ brush: _chunkH4AOUUBEcjs.normalizePaintBrush.call(void 0, _nullishCoalesce(r.brush, () => ( {}))),
1818
1839
  color: typeof r.color === "string" && /^#[0-9a-f]{6}$/i.test(r.color) ? r.color.toLowerCase() : "#000000",
1819
1840
  points,
1820
1841
  seed: finite2(r.seed) ? r.seed | 0 : 0
@@ -1827,14 +1848,14 @@ function normalizeBrushStroke(raw) {
1827
1848
  const st = [];
1828
1849
  for (const raw2 of r.stencils) {
1829
1850
  try {
1830
- st.push(normalizeStencil(raw2, typeof _optionalChain([raw2, 'optionalAccess', _86 => _86.id]) === "string" ? raw2.id : "stencil"));
1851
+ st.push(normalizeStencil(raw2, typeof _optionalChain([raw2, 'optionalAccess', _89 => _89.id]) === "string" ? raw2.id : "stencil"));
1831
1852
  } catch (e2) {
1832
1853
  }
1833
1854
  }
1834
1855
  if (st.length) out.stencils = st;
1835
1856
  }
1836
- const effect = _chunk6G6ZDDDBcjs.readPaintEffectPaint.call(void 0, r.paint);
1837
- const paint = effect ? null : _chunkPQ3H2AANcjs.readPaintSource.call(void 0, r.paint);
1857
+ const effect = _chunkH4AOUUBEcjs.readPaintEffectPaint.call(void 0, r.paint);
1858
+ const paint = effect ? null : _chunkI7NJPHWVcjs.readPaintSource.call(void 0, r.paint);
1838
1859
  if (effect) out.paint = effect;
1839
1860
  else if (paint && paint.type === "gradient") out.paint = paint;
1840
1861
  if (Array.isArray(r.steps) && r.steps.length === points.length && r.steps.every((v) => Number.isInteger(v) && v >= 0)) out.steps = [...r.steps];
@@ -1873,11 +1894,11 @@ function varyStroke(stroke, m, v) {
1873
1894
  if (ps !== 1) q.pressure = Math.min(1, Math.max(0, (_nullishCoalesce(p.pressure, () => ( 1))) * ps));
1874
1895
  return q;
1875
1896
  });
1876
- const brush = s !== 1 ? _chunk6G6ZDDDBcjs.normalizePaintBrush.call(void 0, { ...stroke.brush, tip: { ...stroke.brush.tip, size: stroke.brush.tip.size * s } }) : stroke.brush;
1897
+ const brush = s !== 1 ? _chunkH4AOUUBEcjs.normalizePaintBrush.call(void 0, { ...stroke.brush, tip: { ...stroke.brush.tip, size: stroke.brush.tip.size * s } }) : stroke.brush;
1877
1898
  const out = { ...stroke, brush, points };
1878
- if (_optionalChain([stroke, 'access', _87 => _87.paint, 'optionalAccess', _88 => _88.type]) === "gradient" && s !== 1) out.paint = _chunkPQ3H2AANcjs.scalePaintGradient.call(void 0, stroke.paint, s);
1879
- if (_optionalChain([stroke, 'access', _89 => _89.paint, 'optionalAccess', _90 => _90.type]) === "effect" && stroke.paint.map && s !== 1) out.paint = { ...stroke.paint, map: { ...stroke.paint.map, length: Math.min(4096, Math.max(16, Math.round(stroke.paint.map.length * s))) } };
1880
- if (_optionalChain([stroke, 'access', _91 => _91.copies, 'optionalAccess', _92 => _92.length])) {
1899
+ if (_optionalChain([stroke, 'access', _90 => _90.paint, 'optionalAccess', _91 => _91.type]) === "gradient" && s !== 1) out.paint = _chunkI7NJPHWVcjs.scalePaintGradient.call(void 0, stroke.paint, s);
1900
+ if (_optionalChain([stroke, 'access', _92 => _92.paint, 'optionalAccess', _93 => _93.type]) === "effect" && stroke.paint.map && s !== 1) out.paint = { ...stroke.paint, map: { ...stroke.paint.map, length: Math.min(4096, Math.max(16, Math.round(stroke.paint.map.length * s))) } };
1901
+ if (_optionalChain([stroke, 'access', _94 => _94.copies, 'optionalAccess', _95 => _95.length])) {
1881
1902
  const inv = invertAffine(m);
1882
1903
  out.copies = stroke.copies.map((c) => composeAffine(m, composeAffine(c, inv)));
1883
1904
  }
@@ -1896,7 +1917,7 @@ var paperNodes = /* @__PURE__ */ new WeakMap();
1896
1917
  function paperNode(paper, light) {
1897
1918
  let n = paperNodes.get(paper);
1898
1919
  const metal = (_nullishCoalesce(paper.metallic, () => ( 0))) > 0;
1899
- if (!n || metal && (_optionalChain([n, 'access', _93 => _93.light, 'optionalAccess', _94 => _94.azimuth]) !== _optionalChain([light, 'optionalAccess', _95 => _95.azimuth]) || _optionalChain([n, 'access', _96 => _96.light, 'optionalAccess', _97 => _97.elevation]) !== _optionalChain([light, 'optionalAccess', _98 => _98.elevation]))) {
1920
+ if (!n || metal && (_optionalChain([n, 'access', _96 => _96.light, 'optionalAccess', _97 => _97.azimuth]) !== _optionalChain([light, 'optionalAccess', _98 => _98.azimuth]) || _optionalChain([n, 'access', _99 => _99.light, 'optionalAccess', _100 => _100.elevation]) !== _optionalChain([light, 'optionalAccess', _101 => _101.elevation]))) {
1900
1921
  n = { type: "paper", id: PAPER_NODE_ID, name: "Paper", visible: true, opacity: 1, blend: "normal", paper, ...metal && light ? { light: { azimuth: light.azimuth, elevation: light.elevation } } : {} };
1901
1922
  paperNodes.set(paper, n);
1902
1923
  }
@@ -1908,7 +1929,7 @@ function paperGrain(paper) {
1908
1929
  const key = JSON.stringify([paper.pattern, paper.seed, paper.scale, paper.tiling, paper.dry, _nullishCoalesce(paper.offset, () => ( null))]);
1909
1930
  let g = grainCache.get(key);
1910
1931
  if (!g) {
1911
- g = new (0, _chunkPQ3H2AANcjs.PaperGrain)(paper, "dry");
1932
+ g = new (0, _chunkI7NJPHWVcjs.PaperGrain)(paper, "dry");
1912
1933
  if (grainCache.size > 16) grainCache.delete(grainCache.keys().next().value);
1913
1934
  grainCache.set(key, g);
1914
1935
  }
@@ -1918,7 +1939,7 @@ function paperTile(paper, r, light) {
1918
1939
  const key = `${paperKey(paper, light)}|${r.x},${r.y},${r.width},${r.height}`;
1919
1940
  let t = tileCache.get(key);
1920
1941
  if (!t) {
1921
- t = _chunk6G6ZDDDBcjs.renderPaper.call(void 0, paper, r, paperGrain(paper), light);
1942
+ t = _chunkH4AOUUBEcjs.renderPaper.call(void 0, paper, r, paperGrain(paper), light);
1922
1943
  if (tileCache.size > 512) tileCache.delete(tileCache.keys().next().value);
1923
1944
  tileCache.set(key, t);
1924
1945
  }
@@ -1947,7 +1968,7 @@ var PROFILE = {
1947
1968
  }
1948
1969
  };
1949
1970
  function createPaintCompositor() {
1950
- return new (0, _chunkHB4ICNNAcjs.RasterCompositor)(PROFILE);
1971
+ return new (0, _chunkDPYAO5U6cjs.RasterCompositor)(PROFILE);
1951
1972
  }
1952
1973
  function downsampleRgba(data, width, height, tw, th) {
1953
1974
  tw = Math.max(1, Math.round(tw));
@@ -2017,17 +2038,17 @@ function header(state, options) {
2017
2038
  if (options.swatches !== void 0) out.swatches = JSON.parse(JSON.stringify(options.swatches));
2018
2039
  if (options.mixingPad !== void 0) out.mixingPad = JSON.parse(JSON.stringify(options.mixingPad));
2019
2040
  if (options.wet !== void 0) out.wet = JSON.parse(JSON.stringify(options.wet));
2020
- if (_optionalChain([state, 'access', _99 => _99.wetEvents, 'optionalAccess', _100 => _100.length])) out.wetEvents = JSON.parse(JSON.stringify(state.wetEvents));
2021
- if (_optionalChain([state, 'access', _101 => _101.paintEvents, 'optionalAccess', _102 => _102.length])) out.paintEvents = JSON.parse(JSON.stringify(state.paintEvents));
2041
+ if (_optionalChain([state, 'access', _102 => _102.wetEvents, 'optionalAccess', _103 => _103.length])) out.wetEvents = JSON.parse(JSON.stringify(state.wetEvents));
2042
+ if (_optionalChain([state, 'access', _104 => _104.paintEvents, 'optionalAccess', _105 => _105.length])) out.paintEvents = JSON.parse(JSON.stringify(state.paintEvents));
2022
2043
  if (state.origin && (state.origin.x || state.origin.y)) out.origin = { ...state.origin };
2023
2044
  return out;
2024
2045
  }
2025
2046
  function serializePaintDocument(state, options = {}) {
2026
- const { layers, assets } = _chunkWVS5KQDHcjs.serializeLayers.call(void 0, state.layers);
2047
+ const { layers, assets } = _chunkLP2MCSBEcjs.serializeLayers.call(void 0, state.layers);
2027
2048
  return { ...header(state, options), layers, assets };
2028
2049
  }
2029
2050
  async function serializePaintDocumentExternal(state, store, options = {}) {
2030
- const { layers, assets } = await _chunkWVS5KQDHcjs.serializeLayersExternal.call(void 0, state.layers, store);
2051
+ const { layers, assets } = await _chunkLP2MCSBEcjs.serializeLayersExternal.call(void 0, state.layers, store);
2031
2052
  return { ...header(state, options), layers, assets };
2032
2053
  }
2033
2054
  function paintLayersOnly(layers, problems) {
@@ -2035,7 +2056,7 @@ function paintLayersOnly(layers, problems) {
2035
2056
  for (const l of layers) {
2036
2057
  if (l.type === "pixel") {
2037
2058
  const { filters, source, ...rest } = l;
2038
- if (_optionalChain([filters, 'optionalAccess', _103 => _103.length])) problems.push(`Layer "${l.name}": its filters are an image editor feature and were dropped.`);
2059
+ if (_optionalChain([filters, 'optionalAccess', _106 => _106.length])) problems.push(`Layer "${l.name}": its filters are an image editor feature and were dropped.`);
2039
2060
  if (source) problems.push(`Layer "${l.name}" refers to an image editor source image; it loads empty.`);
2040
2061
  out.push(rest);
2041
2062
  } else if (l.type === "group") out.push({ ...l, children: paintLayersOnly(l.children, problems) });
@@ -2062,11 +2083,11 @@ function deserializePaintDocument(raw) {
2062
2083
  }
2063
2084
  const problems = [];
2064
2085
  const canvas = normalizeCanvas({ width: r.width, height: r.height, dpi: _nullishCoalesce(r.dpi, () => ( void 0)) });
2065
- const paper = _chunk6G6ZDDDBcjs.normalizePaper.call(void 0, _nullishCoalesce(r.paper, () => ( {})));
2086
+ const paper = _chunkH4AOUUBEcjs.normalizePaper.call(void 0, _nullishCoalesce(r.paper, () => ( {})));
2066
2087
  const assets = r.assets && typeof r.assets === "object" ? r.assets : {};
2067
- const layers = paintLayersOnly(_chunkWVS5KQDHcjs.deserializeLayers.call(void 0, r.layers, { assets, problems }), problems);
2088
+ const layers = paintLayersOnly(_chunkLP2MCSBEcjs.deserializeLayers.call(void 0, r.layers, { assets, problems }), problems);
2068
2089
  const wanted = typeof r.activeLayerId === "string" ? r.activeLayerId : null;
2069
- const activeLayerId = wanted && _chunkHB4ICNNAcjs.findLayer.call(void 0, layers, wanted) ? wanted : _nullishCoalesce(_optionalChain([_chunkHB4ICNNAcjs.flattenLayers.call(void 0, layers), 'access', _104 => _104.filter, 'call', _105 => _105((l) => l.type === "pixel"), 'access', _106 => _106.pop, 'call', _107 => _107(), 'optionalAccess', _108 => _108.id]), () => ( null));
2090
+ const activeLayerId = wanted && _chunkDPYAO5U6cjs.findLayer.call(void 0, layers, wanted) ? wanted : _nullishCoalesce(_optionalChain([_chunkDPYAO5U6cjs.flattenLayers.call(void 0, layers), 'access', _107 => _107.filter, 'call', _108 => _108((l) => l.type === "pixel"), 'access', _109 => _109.pop, 'call', _110 => _110(), 'optionalAccess', _111 => _111.id]), () => ( null));
2070
2091
  const wetEvents = Array.isArray(r.wetEvents) ? r.wetEvents.filter((e) => e && typeof e === "object" && Number.isInteger(e.clock) && typeof e.kind === "string") : [];
2071
2092
  const state = { canvas, paper, layers, activeLayerId, strokes: readStrokes(r.strokes, problems) };
2072
2093
  if (wetEvents.length) state.wetEvents = wetEvents;
@@ -2080,7 +2101,7 @@ async function deserializePaintDocumentAsync(raw, store) {
2080
2101
  if (!raw || typeof raw !== "object") throw new Error("Not a paint document: expected a JSON object.");
2081
2102
  const r = raw;
2082
2103
  const problems = [];
2083
- const assets = await _chunkWVS5KQDHcjs.resolveExternalAssets.call(void 0, _nullishCoalesce(r.assets, () => ( {})), store, problems);
2104
+ const assets = await _chunkLP2MCSBEcjs.resolveExternalAssets.call(void 0, _nullishCoalesce(r.assets, () => ( {})), store, problems);
2084
2105
  const loaded = deserializePaintDocument({ ...r, assets });
2085
2106
  return { ...loaded, problems: [...problems, ...loaded.problems] };
2086
2107
  }
@@ -2157,13 +2178,13 @@ function viewPenToDocument(view, p) {
2157
2178
 
2158
2179
  // src/paint-editor/input.ts
2159
2180
  function samplePressure(e) {
2160
- return _chunkVMROIWLLcjs.pointerPressure.call(void 0, e);
2181
+ return _chunkKBYB7OWBcjs.pointerPressure.call(void 0, e);
2161
2182
  }
2162
2183
  function pointerToPenPoint(e, x, y, view) {
2163
2184
  const p = { x, y, pressure: samplePressure(e) };
2164
2185
  if (typeof e.timeStamp === "number" && Number.isFinite(e.timeStamp)) p.t = e.timeStamp;
2165
2186
  if (e.pointerType !== "pen") return p;
2166
- const o = _chunk6G6ZDDDBcjs.penOrientation.call(void 0, {
2187
+ const o = _chunkH4AOUUBEcjs.penOrientation.call(void 0, {
2167
2188
  x,
2168
2189
  y,
2169
2190
  altitude: typeof e.altitudeAngle === "number" ? e.altitudeAngle : void 0,
@@ -2211,7 +2232,7 @@ async function decodeImageBlob(blob) {
2211
2232
  if (!ctx) throw new Error("No 2D context to decode with.");
2212
2233
  ctx.drawImage(bitmap, 0, 0);
2213
2234
  const data = new Uint8ClampedArray(ctx.getImageData(0, 0, bitmap.width, bitmap.height).data);
2214
- _optionalChain([bitmap, 'access', _109 => _109.close, 'optionalCall', _110 => _110()]);
2235
+ _optionalChain([bitmap, 'access', _112 => _112.close, 'optionalCall', _113 => _113()]);
2215
2236
  return { width: bitmap.width, height: bitmap.height, data };
2216
2237
  }
2217
2238
  function downloadBytes(bytes, fileName, mimeType) {
@@ -2227,7 +2248,7 @@ function downloadBytes(bytes, fileName, mimeType) {
2227
2248
 
2228
2249
  // src/paint-editor/wet.ts
2229
2250
  var STROKE_WATER = 0.9;
2230
- var STROKE_MASS = _chunkVMROIWLLcjs.PIGMENT_UNIT * 2.5;
2251
+ var STROKE_MASS = _chunkKBYB7OWBcjs.PIGMENT_UNIT * 2.5;
2231
2252
  var STROKE_LIGHT = 1.5;
2232
2253
  var COVERAGE_STEPS = 4096;
2233
2254
  function union2(a, b) {
@@ -2237,13 +2258,13 @@ function union2(a, b) {
2237
2258
  return { x, y, width: Math.max(a.x + a.width, b.x + b.width) - x, height: Math.max(a.y + a.height, b.y + b.height) - y };
2238
2259
  }
2239
2260
  function wetPaperInput(paper) {
2240
- const grain = new (0, _chunkPQ3H2AANcjs.PaperGrain)(paper, "wet");
2261
+ const grain = new (0, _chunkI7NJPHWVcjs.PaperGrain)(paper, "wet");
2241
2262
  const flat = grain.flat;
2242
2263
  return {
2243
2264
  absorption: paper.absorption,
2244
2265
  permeability: paper.permeability,
2245
2266
  roughness: flat ? 0 : paper.roughness,
2246
- color: _chunk6G6ZDDDBcjs.hexToRgb8.call(void 0, paper.color),
2267
+ color: _chunkH4AOUUBEcjs.hexToRgb8.call(void 0, paper.color),
2247
2268
  heightAt: flat ? () => 0.5 : (x, y) => grain.at(x, y)
2248
2269
  };
2249
2270
  }
@@ -2251,29 +2272,29 @@ var WetStrokeDriver = (_class6 = class {
2251
2272
  constructor(init) {;_class6.prototype.__init40.call(this);_class6.prototype.__init41.call(this);_class6.prototype.__init42.call(this);_class6.prototype.__init43.call(this);_class6.prototype.__init44.call(this);_class6.prototype.__init45.call(this);_class6.prototype.__init46.call(this);_class6.prototype.__init47.call(this);_class6.prototype.__init48.call(this);_class6.prototype.__init49.call(this);_class6.prototype.__init50.call(this);_class6.prototype.__init51.call(this);_class6.prototype.__init52.call(this);
2252
2273
  this.init = init;
2253
2274
  const brush = init.brush;
2254
- this.smoother = new (0, _chunk6G6ZDDDBcjs.PenSmoother)(brush.tip.smoothing, brush.pressureSmoothing);
2255
- const copies = init.copies.length ? init.copies : [_chunk6G6ZDDDBcjs.IDENTITY_COPY];
2275
+ this.smoother = new (0, _chunkH4AOUUBEcjs.PenSmoother)(brush.tip.smoothing, brush.pressureSmoothing);
2276
+ const copies = init.copies.length ? init.copies : [_chunkH4AOUUBEcjs.IDENTITY_COPY];
2256
2277
  const wet = brush.wet;
2257
2278
  const spacing = Math.max(0.02, brush.tip.spacing);
2258
2279
  const perDab = Math.min(1, spacing * 1.2);
2259
2280
  const thin = wet.thinner;
2260
- this.medium = new (0, _chunkVMROIWLLcjs.WetMedium)(init.world, init.laneId, {
2281
+ this.medium = new (0, _chunkKBYB7OWBcjs.WetMedium)(init.world, init.laneId, {
2261
2282
  water: STROKE_WATER * Math.min(1, wet.water * (1 + thin)) * perDab,
2262
2283
  mass: STROKE_MASS * wet.pigment * (1 - 0.6 * thin) * perDab,
2263
2284
  body: wet.body * (1 - thin),
2264
2285
  light: 0
2265
2286
  });
2266
2287
  this.lightBase = wet.tool === "paint" ? STROKE_LIGHT * brush.light.amount * (1 - 0.6 * thin) * perDab : 0;
2267
- const rates = _chunkPQ3H2AANcjs.exchangeRates.call(void 0, brush.behavior.pickup, brush.behavior.mix, wet.load, brush.behavior.mixing);
2288
+ const rates = _chunkI7NJPHWVcjs.exchangeRates.call(void 0, brush.behavior.pickup, brush.behavior.mix, wet.load, brush.behavior.mixing);
2268
2289
  this.states = copies.map((c, i) => ({
2269
- walker: new (0, _chunk6G6ZDDDBcjs.PenDabWalker)(brush, init.seed + i * 7919 | 0, c.linear),
2270
- exchange: wet.tool === "paint" ? new (0, _chunkPQ3H2AANcjs.PaintExchange)(rates, init.load) : null,
2290
+ walker: new (0, _chunkH4AOUUBEcjs.PenDabWalker)(brush, init.seed + i * 7919 | 0, c.linear),
2291
+ exchange: wet.tool === "paint" ? new (0, _chunkI7NJPHWVcjs.PaintExchange)(rates, init.load) : null,
2271
2292
  last: null
2272
2293
  }));
2273
2294
  this.copies = copies;
2274
2295
  this.depth = init.grain && !init.grain.flat ? Math.min(1, Math.max(0, init.paperDepth * brush.grain)) : 0;
2275
2296
  const g = _nullishCoalesce(init.paint, () => ( null));
2276
- this.sampler = g ? new (0, _chunkPQ3H2AANcjs.PaintGradientSampler)(g.map.by === "across-tip" ? { ...g, map: { by: "distance", length: 300, repeat: "mirror" } } : g, init.seed) : null;
2297
+ this.sampler = g ? new (0, _chunkI7NJPHWVcjs.PaintGradientSampler)(g.map.by === "across-tip" ? { ...g, map: { by: "distance", length: 300, repeat: "mirror" } } : g, init.seed) : null;
2277
2298
  }
2278
2299
 
2279
2300
  __init40() {this.dabCount = 0}
@@ -2299,7 +2320,7 @@ var WetStrokeDriver = (_class6 = class {
2299
2320
 
2300
2321
  /** What copy 0's brush carries after the dabs so far. */
2301
2322
  get load() {
2302
- return _nullishCoalesce(_optionalChain([this, 'access', _111 => _111.states, 'access', _112 => _112[0], 'access', _113 => _113.exchange, 'optionalAccess', _114 => _114.load]), () => ( null));
2323
+ return _nullishCoalesce(_optionalChain([this, 'access', _114 => _114.states, 'access', _115 => _115[0], 'access', _116 => _116.exchange, 'optionalAccess', _117 => _117.load]), () => ( null));
2303
2324
  }
2304
2325
  /** Whether every point (and the end) has been applied. */
2305
2326
  get done() {
@@ -2347,7 +2368,7 @@ var WetStrokeDriver = (_class6 = class {
2347
2368
  }
2348
2369
  applyDabs(copy, dabs, rects) {
2349
2370
  for (const d of dabs) {
2350
- const rect = _chunkPQ3H2AANcjs.dabRect.call(void 0, d, this.init.brush.tip.hardness);
2371
+ const rect = _chunkI7NJPHWVcjs.dabRect.call(void 0, d, this.init.brush.tip.hardness);
2351
2372
  if (rect.width <= 0 || rect.height <= 0) continue;
2352
2373
  this.dab(copy, d, rect);
2353
2374
  rects.push(rect);
@@ -2364,7 +2385,7 @@ var WetStrokeDriver = (_class6 = class {
2364
2385
  const tip = this.tip.subarray(0, n);
2365
2386
  const cov = this.cov.subarray(0, n);
2366
2387
  tip.fill(0);
2367
- _chunkPQ3H2AANcjs.rasterizeDab.call(void 0, { ...d, alpha: 1 }, this.init.brush.tip.hardness, rect, tip);
2388
+ _chunkI7NJPHWVcjs.rasterizeDab.call(void 0, { ...d, alpha: 1 }, this.init.brush.tip.hardness, rect, tip);
2368
2389
  const grain = this.depth > 0 ? this.init.grain : null;
2369
2390
  const mask = this.init.mask;
2370
2391
  for (let yy = 0, k = 0; yy < rect.height; yy++) {
@@ -2375,7 +2396,7 @@ var WetStrokeDriver = (_class6 = class {
2375
2396
  tip[k] *= mx >= 0 && my >= 0 && mx < mask.width && my < mask.height ? mask.data[my * mask.width + mx] / 255 : 0;
2376
2397
  }
2377
2398
  let v = tip[k];
2378
- if (v > 0 && grain) v *= _chunkPQ3H2AANcjs.grainCatch.call(void 0, grain.at(rect.x + xx + 0.5, rect.y + yy + 0.5), this.depth, d.pressure);
2399
+ if (v > 0 && grain) v *= _chunkI7NJPHWVcjs.grainCatch.call(void 0, grain.at(rect.x + xx + 0.5, rect.y + yy + 0.5), this.depth, d.pressure);
2379
2400
  tip[k] = Math.round(tip[k] * COVERAGE_STEPS) / COVERAGE_STEPS;
2380
2401
  cov[k] = Math.round(v * COVERAGE_STEPS) / COVERAGE_STEPS;
2381
2402
  }
@@ -2396,7 +2417,7 @@ var WetStrokeDriver = (_class6 = class {
2396
2417
  let flow = 1;
2397
2418
  const effect = this.init.effect;
2398
2419
  if (effect) {
2399
- _chunk6G6ZDDDBcjs.sampleEffectAt.call(void 0, effect, d.x, d.y, this.centre, d);
2420
+ _chunkH4AOUUBEcjs.sampleEffectAt.call(void 0, effect, d.x, d.y, this.centre, d);
2400
2421
  ex.setReservoirColor(this.centre[0], this.centre[1], this.centre[2]);
2401
2422
  } else if (this.sampler) {
2402
2423
  const g = this.sampler.dab(d, this.sample);
@@ -2408,7 +2429,7 @@ var WetStrokeDriver = (_class6 = class {
2408
2429
  if (total > 0 && flow > 0 && effect) {
2409
2430
  const ec = cov.slice();
2410
2431
  const field = new Float32Array(ec.length * 3);
2411
- _chunk6G6ZDDDBcjs.effectDabField.call(void 0, effect, rect, ec, this.centre, this.paint, field, COVERAGE_STEPS, d);
2432
+ _chunkH4AOUUBEcjs.effectDabField.call(void 0, effect, rect, ec, this.centre, this.paint, field, COVERAGE_STEPS, d);
2412
2433
  this.medium.deposit(rect, ec, Math.min(1, total) * k, this.paint, null, field);
2413
2434
  } else if (total > 0 && flow > 0) this.medium.deposit(rect, cov, Math.min(1, total) * k * flow, this.paint, null);
2414
2435
  else world.paint(laneId, rect, cov, this.medium.options.water * k, null);
@@ -2463,7 +2484,7 @@ var PaintWetLayers = (_class7 = class {
2463
2484
 
2464
2485
 
2465
2486
  __init53() {this.world = null}
2466
- __init54() {this.tilt = { ..._chunkVMROIWLLcjs.FLAT }}
2487
+ __init54() {this.tilt = { ..._chunkKBYB7OWBcjs.FLAT }}
2467
2488
  __init55() {this.settings = /* @__PURE__ */ new Map()}
2468
2489
  __init56() {this.paused = false}
2469
2490
  /** Wet strokes dry as soon as they end (one undo step with the stroke). */
@@ -2487,8 +2508,8 @@ var PaintWetLayers = (_class7 = class {
2487
2508
  /** Starts the GPU engine for the world (once; it may turn out unavailable). */
2488
2509
  startGpu() {
2489
2510
  if (this.gpuMode === "off" || this.gpu || this.gpuStarting || this.gpuSupport) return;
2490
- const provider = this.options.gpuProvider === void 0 ? _chunkVMROIWLLcjs.findWebGpu.call(void 0, ) : this.options.gpuProvider;
2491
- this.gpuStarting = _chunkVMROIWLLcjs.createWetGpuEngine.call(void 0, provider).then(({ engine, support }) => {
2511
+ const provider = this.options.gpuProvider === void 0 ? _chunkKBYB7OWBcjs.findWebGpu.call(void 0, ) : this.options.gpuProvider;
2512
+ this.gpuStarting = _chunkKBYB7OWBcjs.createWetGpuEngine.call(void 0, provider).then(({ engine, support }) => {
2492
2513
  this.gpuSupport = support;
2493
2514
  if (!engine) return;
2494
2515
  if (this.gpuMode === "off" || !this.world) {
@@ -2518,8 +2539,8 @@ var PaintWetLayers = (_class7 = class {
2518
2539
  if (mode === this.gpuMode) return this.engineInfo();
2519
2540
  this.gpuMode = mode;
2520
2541
  if (mode === "off") {
2521
- _optionalChain([this, 'access', _115 => _115.world, 'optionalAccess', _116 => _116.attachGpu, 'call', _117 => _117(null)]);
2522
- _optionalChain([this, 'access', _118 => _118.gpu, 'optionalAccess', _119 => _119.destroy, 'call', _120 => _120()]);
2542
+ _optionalChain([this, 'access', _118 => _118.world, 'optionalAccess', _119 => _119.attachGpu, 'call', _120 => _120(null)]);
2543
+ _optionalChain([this, 'access', _121 => _121.gpu, 'optionalAccess', _122 => _122.destroy, 'call', _123 => _123()]);
2523
2544
  this.gpu = null;
2524
2545
  this.gpuSupport = null;
2525
2546
  } else if (this.world) this.startGpu();
@@ -2527,13 +2548,13 @@ var PaintWetLayers = (_class7 = class {
2527
2548
  }
2528
2549
  engineInfo() {
2529
2550
  const w = this.world;
2530
- const base = { mode: this.gpuMode, adapter: _nullishCoalesce(_optionalChain([this, 'access', _121 => _121.gpuSupport, 'optionalAccess', _122 => _122.adapter]), () => ( null)), maxTiles: _nullishCoalesce(_optionalChain([this, 'access', _123 => _123.gpuSupport, 'optionalAccess', _124 => _124.maxSlots]), () => ( 0)), minTiles: this.gpuMinTiles, activeTiles: _nullishCoalesce(_optionalChain([w, 'optionalAccess', _125 => _125.activeTiles, 'call', _126 => _126()]), () => ( 0)), cpu: this.backend() };
2551
+ const base = { mode: this.gpuMode, adapter: _nullishCoalesce(_optionalChain([this, 'access', _124 => _124.gpuSupport, 'optionalAccess', _125 => _125.adapter]), () => ( null)), maxTiles: _nullishCoalesce(_optionalChain([this, 'access', _126 => _126.gpuSupport, 'optionalAccess', _127 => _127.maxSlots]), () => ( 0)), minTiles: this.gpuMinTiles, activeTiles: _nullishCoalesce(_optionalChain([w, 'optionalAccess', _128 => _128.activeTiles, 'call', _129 => _129()]), () => ( 0)), cpu: this.backend() };
2531
2552
  if (this.gpuMode === "off") return { ...base, state: "off", reason: "Forced to the CPU." };
2532
2553
  if (this.gpuStarting) return { ...base, state: "starting", reason: null };
2533
- if (_optionalChain([w, 'optionalAccess', _127 => _127.gpuError])) return { ...base, state: "failed", reason: w.gpuError };
2554
+ if (_optionalChain([w, 'optionalAccess', _130 => _130.gpuError])) return { ...base, state: "failed", reason: w.gpuError };
2534
2555
  if (this.gpuSupport && !this.gpuSupport.supported) return { ...base, state: "unavailable", reason: this.gpuSupport.reason };
2535
2556
  if (!this.gpu) return { ...base, state: "not-started", reason: "Starts with the first wet stroke." };
2536
- if (_optionalChain([w, 'optionalAccess', _128 => _128.gpuActive])) return { ...base, state: "active", reason: null };
2557
+ if (_optionalChain([w, 'optionalAccess', _131 => _131.gpuActive])) return { ...base, state: "active", reason: null };
2537
2558
  return { ...base, state: "standby", reason: `The GPU takes over at ${this.gpuMinTiles} wet tiles (256 px).` };
2538
2559
  }
2539
2560
  /** The world (made on first use, at the canvas size). */
@@ -2547,7 +2568,7 @@ var PaintWetLayers = (_class7 = class {
2547
2568
  return this.world;
2548
2569
  }
2549
2570
  makeWorld(width, height, paper) {
2550
- const world = new (0, _chunkVMROIWLLcjs.WetWorld)(width, height, wetPaperInput(paper), { kernel: this.options.kernel, threads: this.options.threads });
2571
+ const world = new (0, _chunkKBYB7OWBcjs.WetWorld)(width, height, wetPaperInput(paper), { kernel: this.options.kernel, threads: this.options.threads });
2551
2572
  world.setTilt(this.tilt);
2552
2573
  world.gpuMinTiles = this.gpuMinTiles;
2553
2574
  if (this.gpu) world.attachGpu(this.gpu);
@@ -2559,7 +2580,7 @@ var PaintWetLayers = (_class7 = class {
2559
2580
  * sides: the shift has to be whole wet tiles (256 px), and no wet stroke may be live.
2560
2581
  */
2561
2582
  canExtend(left, top) {
2562
- return left % _chunkVMROIWLLcjs.WET_TILE === 0 && top % _chunkVMROIWLLcjs.WET_TILE === 0 && !this.driver;
2583
+ return left % _chunkKBYB7OWBcjs.WET_TILE === 0 && top % _chunkKBYB7OWBcjs.WET_TILE === 0 && !this.driver;
2563
2584
  }
2564
2585
  /**
2565
2586
  * Keeps the wet paint while the canvas grows to `width`×`height` by `left` / `top` on those
@@ -2572,17 +2593,17 @@ var PaintWetLayers = (_class7 = class {
2572
2593
  if (!this.canExtend(left, top)) throw new Error("Wet paint only moves by whole 256 px tiles, between strokes.");
2573
2594
  for (const [id, s] of this.settings) if (s.flow.center) this.settings.set(id, { ...s, flow: { ...s.flow, center: { x: s.flow.center.x + left, y: s.flow.center.y + top } } });
2574
2595
  const old = this.world;
2575
- const snap = _optionalChain([old, 'optionalAccess', _129 => _129.laneIds, 'call', _130 => _130(), 'access', _131 => _131.length]) ? old.snapshot() : null;
2596
+ const snap = _optionalChain([old, 'optionalAccess', _132 => _132.laneIds, 'call', _133 => _133(), 'access', _134 => _134.length]) ? old.snapshot() : null;
2576
2597
  this.dropWorld();
2577
2598
  this.lastTick = null;
2578
2599
  this.stepsOwed = 0;
2579
2600
  if (!old || !snap) return;
2580
- const moved = _chunkVMROIWLLcjs.moveWetSnapshot.call(void 0, snap, old, { width, height }, left, top, (l) => {
2581
- const flow = _optionalChain([this, 'access', _132 => _132.settings, 'access', _133 => _133.get, 'call', _134 => _134(l.id), 'optionalAccess', _135 => _135.flow]);
2601
+ const moved = _chunkKBYB7OWBcjs.moveWetSnapshot.call(void 0, snap, old, { width, height }, left, top, (l) => {
2602
+ const flow = _optionalChain([this, 'access', _135 => _135.settings, 'access', _136 => _136.get, 'call', _137 => _137(l.id), 'optionalAccess', _138 => _138.flow]);
2582
2603
  return {
2583
2604
  base: _chunk474IQG74cjs.translateSurface.call(void 0, l.base, left, top),
2584
2605
  ...l.light ? { light: _chunk474IQG74cjs.translateSurface.call(void 0, l.light, left, top) } : {},
2585
- flow: l.flow && flow && flow.kind !== "none" ? _chunkVMROIWLLcjs.flowField.call(void 0, flow, width, height) : l.flow
2606
+ flow: l.flow && flow && flow.kind !== "none" ? _chunkKBYB7OWBcjs.flowField.call(void 0, flow, width, height) : l.flow
2586
2607
  };
2587
2608
  });
2588
2609
  this.world = this.makeWorld(width, height, paper);
@@ -2597,11 +2618,11 @@ var PaintWetLayers = (_class7 = class {
2597
2618
  }
2598
2619
  /** Layers holding a wet layer (wet or drying). */
2599
2620
  wetLayerIds() {
2600
- return _nullishCoalesce(_optionalChain([this, 'access', _136 => _136.world, 'optionalAccess', _137 => _137.laneIds, 'call', _138 => _138()]), () => ( []));
2621
+ return _nullishCoalesce(_optionalChain([this, 'access', _139 => _139.world, 'optionalAccess', _140 => _140.laneIds, 'call', _141 => _141()]), () => ( []));
2601
2622
  }
2602
2623
  /** Whether a batch is running (edits wait). */
2603
2624
  get busy() {
2604
- return Boolean(_optionalChain([this, 'access', _139 => _139.world, 'optionalAccess', _140 => _140.busy]));
2625
+ return Boolean(_optionalChain([this, 'access', _142 => _142.world, 'optionalAccess', _143 => _143.busy]));
2605
2626
  }
2606
2627
  /** Resolves when no batch is running. */
2607
2628
  async idle() {
@@ -2610,7 +2631,7 @@ var PaintWetLayers = (_class7 = class {
2610
2631
  settingsOf(layerId, medium = "watercolor") {
2611
2632
  let s = this.settings.get(layerId);
2612
2633
  if (!s) {
2613
- s = { params: _chunkVMROIWLLcjs.normalizeWetParams.call(void 0, WET_MEDIUM_PARAMS[medium], _chunkVMROIWLLcjs.DEFAULT_WET_PARAMS), flow: { ..._chunkVMROIWLLcjs.DEFAULT_FLOW } };
2634
+ s = { params: _chunkKBYB7OWBcjs.normalizeWetParams.call(void 0, WET_MEDIUM_PARAMS[medium], _chunkKBYB7OWBcjs.DEFAULT_WET_PARAMS), flow: { ..._chunkKBYB7OWBcjs.DEFAULT_FLOW } };
2614
2635
  this.settings.set(layerId, s);
2615
2636
  }
2616
2637
  return s;
@@ -2623,50 +2644,50 @@ var PaintWetLayers = (_class7 = class {
2623
2644
  const s = this.settingsOf(layerId, medium);
2624
2645
  w.ensureLane(layerId, { params: s.params, base, light: this.host.layerLight(layerId) });
2625
2646
  const { width, height } = this.host.canvas();
2626
- if (s.flow.kind !== "none") w.setFlow(layerId, _chunkVMROIWLLcjs.flowField.call(void 0, s.flow, width, height), s.flow.strength);
2647
+ if (s.flow.kind !== "none") w.setFlow(layerId, _chunkKBYB7OWBcjs.flowField.call(void 0, s.flow, width, height), s.flow.strength);
2627
2648
  }
2628
2649
  return w;
2629
2650
  }
2630
2651
  setParams(layerId, update) {
2631
2652
  const s = this.settingsOf(layerId);
2632
- s.params = _chunkVMROIWLLcjs.normalizeWetParams.call(void 0, update, s.params);
2633
- if (_optionalChain([this, 'access', _141 => _141.world, 'optionalAccess', _142 => _142.hasLane, 'call', _143 => _143(layerId)])) this.world.setParams(layerId, s.params);
2653
+ s.params = _chunkKBYB7OWBcjs.normalizeWetParams.call(void 0, update, s.params);
2654
+ if (_optionalChain([this, 'access', _144 => _144.world, 'optionalAccess', _145 => _145.hasLane, 'call', _146 => _146(layerId)])) this.world.setParams(layerId, s.params);
2634
2655
  return { ...s.params };
2635
2656
  }
2636
2657
  setFlow(layerId, update) {
2637
2658
  const s = this.settingsOf(layerId);
2638
- s.flow = _chunkVMROIWLLcjs.normalizeFlow.call(void 0, update, s.flow);
2639
- if (_optionalChain([this, 'access', _144 => _144.world, 'optionalAccess', _145 => _145.hasLane, 'call', _146 => _146(layerId)])) {
2659
+ s.flow = _chunkKBYB7OWBcjs.normalizeFlow.call(void 0, update, s.flow);
2660
+ if (_optionalChain([this, 'access', _147 => _147.world, 'optionalAccess', _148 => _148.hasLane, 'call', _149 => _149(layerId)])) {
2640
2661
  const { width, height } = this.host.canvas();
2641
- this.world.setFlow(layerId, _chunkVMROIWLLcjs.flowField.call(void 0, s.flow, width, height), s.flow.strength);
2662
+ this.world.setFlow(layerId, _chunkKBYB7OWBcjs.flowField.call(void 0, s.flow, width, height), s.flow.strength);
2642
2663
  }
2643
2664
  return { ...s.flow };
2644
2665
  }
2645
2666
  setTilt(update) {
2646
- this.tilt = _chunkVMROIWLLcjs.normalizeTilt.call(void 0, update, this.tilt);
2647
- _optionalChain([this, 'access', _147 => _147.world, 'optionalAccess', _148 => _148.setTilt, 'call', _149 => _149(this.tilt)]);
2667
+ this.tilt = _chunkKBYB7OWBcjs.normalizeTilt.call(void 0, update, this.tilt);
2668
+ _optionalChain([this, 'access', _150 => _150.world, 'optionalAccess', _151 => _151.setTilt, 'call', _152 => _152(this.tilt)]);
2648
2669
  return { ...this.tilt };
2649
2670
  }
2650
2671
  /** The paper changed. */
2651
2672
  paperChanged() {
2652
- _optionalChain([this, 'access', _150 => _150.world, 'optionalAccess', _151 => _151.setPaper, 'call', _152 => _152(wetPaperInput(this.host.paper()))]);
2673
+ _optionalChain([this, 'access', _153 => _153.world, 'optionalAccess', _154 => _154.setPaper, 'call', _155 => _155(wetPaperInput(this.host.paper()))]);
2653
2674
  }
2654
2675
  /** A layer as tools describe it. */
2655
2676
  info(layerId) {
2656
2677
  const s = this.settingsOf(layerId);
2657
- const st = _optionalChain([this, 'access', _153 => _153.world, 'optionalAccess', _154 => _154.hasLane, 'call', _155 => _155(layerId)]) ? this.world.stats(layerId) : null;
2678
+ const st = _optionalChain([this, 'access', _156 => _156.world, 'optionalAccess', _157 => _157.hasLane, 'call', _158 => _158(layerId)]) ? this.world.stats(layerId) : null;
2658
2679
  return {
2659
2680
  layerId,
2660
2681
  wet: Boolean(st && st.wetCells > 0),
2661
- wetCells: _nullishCoalesce(_optionalChain([st, 'optionalAccess', _156 => _156.wetCells]), () => ( 0)),
2662
- wetBounds: _nullishCoalesce(_optionalChain([st, 'optionalAccess', _157 => _157.wetBounds]), () => ( null)),
2663
- activeTiles: _nullishCoalesce(_optionalChain([st, 'optionalAccess', _158 => _158.activeTiles]), () => ( 0)),
2682
+ wetCells: _nullishCoalesce(_optionalChain([st, 'optionalAccess', _159 => _159.wetCells]), () => ( 0)),
2683
+ wetBounds: _nullishCoalesce(_optionalChain([st, 'optionalAccess', _160 => _160.wetBounds]), () => ( null)),
2684
+ activeTiles: _nullishCoalesce(_optionalChain([st, 'optionalAccess', _161 => _161.activeTiles]), () => ( 0)),
2664
2685
  params: { ...s.params },
2665
2686
  flow: { ...s.flow }
2666
2687
  };
2667
2688
  }
2668
2689
  backend() {
2669
- return _nullishCoalesce(_optionalChain([this, 'access', _159 => _159.world, 'optionalAccess', _160 => _160.backend, 'call', _161 => _161()]), () => ( null));
2690
+ return _nullishCoalesce(_optionalChain([this, 'access', _162 => _162.world, 'optionalAccess', _163 => _163.backend, 'call', _164 => _164()]), () => ( null));
2670
2691
  }
2671
2692
  /** Shows the current wet pixels (at most `maxTiles` reshaded per layer). */
2672
2693
  syncDisplays(maxTiles = Infinity) {
@@ -2715,7 +2736,7 @@ var PaintWetLayers = (_class7 = class {
2715
2736
  const w = this.world;
2716
2737
  if (!w) return;
2717
2738
  for (const id of w.laneIds()) {
2718
- if (w.isActive(id) || _optionalChain([this, 'access', _162 => _162.driver, 'optionalAccess', _163 => _163.init, 'access', _164 => _164.laneId]) === id) continue;
2739
+ if (w.isActive(id) || _optionalChain([this, 'access', _165 => _165.driver, 'optionalAccess', _166 => _166.init, 'access', _167 => _167.laneId]) === id) continue;
2719
2740
  const base = w.getBase(id);
2720
2741
  const light = w.isLit(id) ? w.getLight(id) : null;
2721
2742
  w.removeLane(id);
@@ -2797,7 +2818,7 @@ var PaintWetLayers = (_class7 = class {
2797
2818
  if (!d || !this.world) return;
2798
2819
  const rects = d.flush();
2799
2820
  if (rects.length) this.syncDisplays(DISPLAY_TILES_PER_TICK);
2800
- if (d.done) _optionalChain([this, 'access', _165 => _165.onDriverDone, 'optionalCall', _166 => _166(d)]);
2821
+ if (d.done) _optionalChain([this, 'access', _168 => _168.onDriverDone, 'optionalCall', _169 => _169(d)]);
2801
2822
  }
2802
2823
  /** Called when a live stroke that ended mid-batch has finished applying. */
2803
2824
  __init68() {this.onDriverDone = null}
@@ -2841,13 +2862,13 @@ var PaintWetLayers = (_class7 = class {
2841
2862
  /** The layer's light paint with all its wet paint dried (`null` without a wet layer or light), without changing anything. */
2842
2863
  bakedLight(layerId) {
2843
2864
  const w = this.world;
2844
- if (!_optionalChain([w, 'optionalAccess', _167 => _167.hasLane, 'call', _168 => _168(layerId)]) || !w.isLit(layerId)) return null;
2865
+ if (!_optionalChain([w, 'optionalAccess', _170 => _170.hasLane, 'call', _171 => _171(layerId)]) || !w.isLit(layerId)) return null;
2845
2866
  return w.bakedLight(layerId);
2846
2867
  }
2847
2868
  /** The layer's pixels with all its wet paint dried (deterministic), without changing anything. */
2848
2869
  bakedSurface(layerId) {
2849
2870
  const w = this.world;
2850
- if (!_optionalChain([w, 'optionalAccess', _169 => _169.hasLane, 'call', _170 => _170(layerId)])) return null;
2871
+ if (!_optionalChain([w, 'optionalAccess', _172 => _172.hasLane, 'call', _173 => _173(layerId)])) return null;
2851
2872
  return w.bakedSurface(layerId);
2852
2873
  }
2853
2874
  /** A snapshot of the world for undo (`null` when there is none). */
@@ -2868,13 +2889,13 @@ var PaintWetLayers = (_class7 = class {
2868
2889
  this.syncDisplays();
2869
2890
  }
2870
2891
  dropWorld() {
2871
- _optionalChain([this, 'access', _171 => _171.world, 'optionalAccess', _172 => _172.destroy, 'call', _173 => _173()]);
2892
+ _optionalChain([this, 'access', _174 => _174.world, 'optionalAccess', _175 => _175.destroy, 'call', _176 => _176()]);
2872
2893
  this.world = null;
2873
2894
  this.driver = null;
2874
2895
  }
2875
2896
  /** Forgets everything wet (a new canvas, a resize, opening a document). */
2876
2897
  reset() {
2877
- _optionalChain([this, 'access', _174 => _174.world, 'optionalAccess', _175 => _175.destroy, 'call', _176 => _176()]);
2898
+ _optionalChain([this, 'access', _177 => _177.world, 'optionalAccess', _178 => _178.destroy, 'call', _179 => _179()]);
2878
2899
  this.world = null;
2879
2900
  this.driver = null;
2880
2901
  this.settings.clear();
@@ -2904,44 +2925,44 @@ var PaintWetLayers = (_class7 = class {
2904
2925
  return out;
2905
2926
  }
2906
2927
  destroy() {
2907
- _optionalChain([this, 'access', _177 => _177.world, 'optionalAccess', _178 => _178.destroy, 'call', _179 => _179()]);
2928
+ _optionalChain([this, 'access', _180 => _180.world, 'optionalAccess', _181 => _181.destroy, 'call', _182 => _182()]);
2908
2929
  this.world = null;
2909
- _optionalChain([this, 'access', _180 => _180.gpu, 'optionalAccess', _181 => _181.destroy, 'call', _182 => _182()]);
2930
+ _optionalChain([this, 'access', _183 => _183.gpu, 'optionalAccess', _184 => _184.destroy, 'call', _185 => _185()]);
2910
2931
  this.gpu = null;
2911
2932
  }
2912
2933
  }, _class7);
2913
2934
  function wetPigmentOf(hex, body) {
2914
- const [r, g, b] = _chunk6G6ZDDDBcjs.hexToRgb8.call(void 0, hex);
2915
- return Array.from(_chunkVMROIWLLcjs.pigmentOf.call(void 0, [r / 255, g / 255, b / 255], body));
2935
+ const [r, g, b] = _chunkH4AOUUBEcjs.hexToRgb8.call(void 0, hex);
2936
+ return Array.from(_chunkKBYB7OWBcjs.pigmentOf.call(void 0, [r / 255, g / 255, b / 255], body));
2916
2937
  }
2917
2938
 
2918
2939
  // src/paint-editor/thumbnails.ts
2919
2940
  var thumbWorld = null;
2920
2941
  function paintWetTestStroke(brush, paper, color, width, height) {
2921
2942
  if (!thumbWorld || thumbWorld.width !== width || thumbWorld.height !== height) {
2922
- _optionalChain([thumbWorld, 'optionalAccess', _183 => _183.destroy, 'call', _184 => _184()]);
2923
- thumbWorld = new (0, _chunkVMROIWLLcjs.WetWorld)(width, height, wetPaperInput(paper), { kernel: "typescript", threads: 0 });
2943
+ _optionalChain([thumbWorld, 'optionalAccess', _186 => _186.destroy, 'call', _187 => _187()]);
2944
+ thumbWorld = new (0, _chunkKBYB7OWBcjs.WetWorld)(width, height, wetPaperInput(paper), { kernel: "typescript", threads: 0 });
2924
2945
  } else thumbWorld.setPaper(wetPaperInput(paper));
2925
2946
  const w = thumbWorld;
2926
2947
  if (w.hasLane("thumb")) w.removeLane("thumb");
2927
2948
  w.ensureLane("thumb");
2928
- const [r, g, b] = _chunk6G6ZDDDBcjs.hexToRgb8.call(void 0, color);
2949
+ const [r, g, b] = _chunkH4AOUUBEcjs.hexToRgb8.call(void 0, color);
2929
2950
  if (brush.wet.tool !== "paint" && brush.wet.tool !== "water") {
2930
2951
  const half = Math.ceil(height / 2);
2931
- w.paint("thumb", { x: 0, y: 0, width, height: half }, null, 0.4, Array.from(_chunkVMROIWLLcjs.pigmentOf.call(void 0, [r / 255, g / 255, b / 255], 0), (v) => v * 0.05));
2932
- w.paint("thumb", { x: 0, y: half, width, height: height - half }, null, 0.4, Array.from(_chunkVMROIWLLcjs.pigmentOf.call(void 0, [232 / 255, 196 / 255, 64 / 255], 0), (v) => v * 0.05));
2952
+ w.paint("thumb", { x: 0, y: 0, width, height: half }, null, 0.4, Array.from(_chunkKBYB7OWBcjs.pigmentOf.call(void 0, [r / 255, g / 255, b / 255], 0), (v) => v * 0.05));
2953
+ w.paint("thumb", { x: 0, y: half, width, height: height - half }, null, 0.4, Array.from(_chunkKBYB7OWBcjs.pigmentOf.call(void 0, [232 / 255, 196 / 255, 64 / 255], 0), (v) => v * 0.05));
2933
2954
  }
2934
2955
  const driver = new WetStrokeDriver({
2935
2956
  world: w,
2936
2957
  laneId: "thumb",
2937
2958
  brush,
2938
2959
  color: [r / 255, g / 255, b / 255],
2939
- load: brushLoadForStroke(brush, _chunkPQ3H2AANcjs.EMPTY_MIXER_LOAD, [r / 255, g / 255, b / 255]),
2960
+ load: brushLoadForStroke(brush, _chunkI7NJPHWVcjs.EMPTY_MIXER_LOAD, [r / 255, g / 255, b / 255]),
2940
2961
  grain: paperGrain(paper),
2941
2962
  paperDepth: paper.depth,
2942
- paperColor: _chunk6G6ZDDDBcjs.hexToRgb8.call(void 0, paper.color),
2963
+ paperColor: _chunkH4AOUUBEcjs.hexToRgb8.call(void 0, paper.color),
2943
2964
  seed: 7,
2944
- copies: [_chunk6G6ZDDDBcjs.IDENTITY_COPY]
2965
+ copies: [_chunkH4AOUUBEcjs.IDENTITY_COPY]
2945
2966
  });
2946
2967
  driver.push(thumbnailStroke(width, height));
2947
2968
  driver.finish();
@@ -2961,7 +2982,7 @@ function thumbnailStroke(width, height) {
2961
2982
  return pts;
2962
2983
  }
2963
2984
  function paintTestStroke(surface, brush, paper, color, width, height) {
2964
- const [r, g, b] = _chunk6G6ZDDDBcjs.hexToRgb8.call(void 0, color);
2985
+ const [r, g, b] = _chunkH4AOUUBEcjs.hexToRgb8.call(void 0, color);
2965
2986
  let result = surface;
2966
2987
  let thick = null;
2967
2988
  let light = null;
@@ -2982,14 +3003,14 @@ function paintTestStroke(surface, brush, paper, color, width, height) {
2982
3003
  lockTransparency: false,
2983
3004
  brush,
2984
3005
  color: [r, g, b, 255],
2985
- background: [..._chunk6G6ZDDDBcjs.hexToRgb8.call(void 0, paper.color), 255],
3006
+ background: [..._chunkH4AOUUBEcjs.hexToRgb8.call(void 0, paper.color), 255],
2986
3007
  grain: paperGrain(paper),
2987
3008
  paperDepth: paper.depth,
2988
3009
  seed: 7,
2989
3010
  colorHex: color,
2990
3011
  affineCopies: [],
2991
- copies: [_chunk6G6ZDDDBcjs.IDENTITY_COPY],
2992
- mixerLoad: brushLoadForStroke(brush, _chunkPQ3H2AANcjs.EMPTY_MIXER_LOAD, [r / 255, g / 255, b / 255]),
3012
+ copies: [_chunkH4AOUUBEcjs.IDENTITY_COPY],
3013
+ mixerLoad: brushLoadForStroke(brush, _chunkI7NJPHWVcjs.EMPTY_MIXER_LOAD, [r / 255, g / 255, b / 255]),
2993
3014
  thick: brush.engine === "impasto" ? { channels: emptyThickChannels() } : void 0,
2994
3015
  sticker: brush.engine === "sticker" ? { nextId: 1 } : void 0,
2995
3016
  light: brush.light.amount > 0 && brush.engine !== "wet" && brush.engine !== "sticker" ? { surface: emptyLight() } : null
@@ -3004,8 +3025,8 @@ function renderBrushThumbnail(brush, options) {
3004
3025
  const width = Math.max(16, Math.min(512, Math.round(_nullishCoalesce(options.width, () => ( 160)))));
3005
3026
  const height = Math.max(16, Math.min(512, Math.round(_nullishCoalesce(options.height, () => ( 48)))));
3006
3027
  const maxSize = height * 0.42;
3007
- const b = brush.tip.size > maxSize ? _chunk6G6ZDDDBcjs.normalizePaintBrush.call(void 0, { tip: { ...brush.tip, size: maxSize } }, brush) : brush;
3008
- const rgba = [..._chunk6G6ZDDDBcjs.hexToRgb8.call(void 0, options.color), 255];
3028
+ const b = brush.tip.size > maxSize ? _chunkH4AOUUBEcjs.normalizePaintBrush.call(void 0, { tip: { ...brush.tip, size: maxSize } }, brush) : brush;
3029
+ const rgba = [..._chunkH4AOUUBEcjs.hexToRgb8.call(void 0, options.color), 255];
3009
3030
  let surface = _chunk474IQG74cjs.emptySurface.call(void 0, 4);
3010
3031
  if (b.engine === "eraser") {
3011
3032
  surface = _chunk474IQG74cjs.fillRect.call(void 0, surface, { x: 0, y: 0, width, height }, rgba);
@@ -3263,12 +3284,12 @@ function colorHarmony2(base, kind, options = {}) {
3263
3284
  function readSwatch(raw) {
3264
3285
  if (!raw || typeof raw !== "object") return null;
3265
3286
  const r = raw;
3266
- const g = _chunkPQ3H2AANcjs.readPaintSource.call(void 0, r.paint);
3267
- const color = typeof r.color === "string" && /^#[0-9a-f]{6}$/i.test(r.color) ? r.color.toLowerCase() : _optionalChain([g, 'optionalAccess', _185 => _185.type]) === "gradient" ? _chunkPQ3H2AANcjs.paintSourceColor.call(void 0, g) : null;
3287
+ const g = _chunkI7NJPHWVcjs.readPaintSource.call(void 0, r.paint);
3288
+ const color = typeof r.color === "string" && /^#[0-9a-f]{6}$/i.test(r.color) ? r.color.toLowerCase() : _optionalChain([g, 'optionalAccess', _188 => _188.type]) === "gradient" ? _chunkI7NJPHWVcjs.paintSourceColor.call(void 0, g) : null;
3268
3289
  if (!color) return null;
3269
3290
  const out = { color };
3270
3291
  if (typeof r.name === "string" && r.name.trim()) out.name = r.name.trim().slice(0, 80);
3271
- if (_optionalChain([g, 'optionalAccess', _186 => _186.type]) === "gradient") out.paint = g;
3292
+ if (_optionalChain([g, 'optionalAccess', _189 => _189.type]) === "gradient") out.paint = g;
3272
3293
  return out;
3273
3294
  }
3274
3295
  var DEFAULT_SWATCHES = [
@@ -3287,7 +3308,7 @@ var DEFAULT_SWATCHES = [
3287
3308
  // src/paint-editor/mixing-pad.ts
3288
3309
  var MIXING_PAD_WIDTH = 360;
3289
3310
  var MIXING_PAD_HEIGHT = 220;
3290
- var PAD_PAINT = _chunk6G6ZDDDBcjs.normalizePaintBrush.call(void 0, {
3311
+ var PAD_PAINT = _chunkH4AOUUBEcjs.normalizePaintBrush.call(void 0, {
3291
3312
  id: "pad-paint",
3292
3313
  name: "Pad paint",
3293
3314
  category: "mixer",
@@ -3295,7 +3316,7 @@ var PAD_PAINT = _chunk6G6ZDDDBcjs.normalizePaintBrush.call(void 0, {
3295
3316
  tip: { size: 28, hardness: 0.75, spacing: 0.1, opacity: 1, flow: 0.7, pressureSize: false, pressureOpacity: false },
3296
3317
  mixer: { wet: 0.45, load: 1, mix: 0.4, loadEachStroke: true, cleanEachStroke: true, mixing: "pigment" }
3297
3318
  });
3298
- var PAD_KNIFE = _chunk6G6ZDDDBcjs.normalizePaintBrush.call(void 0, {
3319
+ var PAD_KNIFE = _chunkH4AOUUBEcjs.normalizePaintBrush.call(void 0, {
3299
3320
  id: "pad-knife",
3300
3321
  name: "Palette knife",
3301
3322
  category: "smudge",
@@ -3305,7 +3326,7 @@ var PAD_KNIFE = _chunk6G6ZDDDBcjs.normalizePaintBrush.call(void 0, {
3305
3326
  // A knife drags streaks of paint and folds them into each other, mixing them as pigment.
3306
3327
  smudge: { strength: 0.6, length: 0.8, mixing: "pigment" }
3307
3328
  });
3308
- var PAD_BLOB = _chunk6G6ZDDDBcjs.normalizePaintBrush.call(void 0, {
3329
+ var PAD_BLOB = _chunkH4AOUUBEcjs.normalizePaintBrush.call(void 0, {
3309
3330
  id: "pad-blob",
3310
3331
  name: "Pad blob",
3311
3332
  category: "custom",
@@ -3327,12 +3348,12 @@ var MixingPad = (_class9 = class {constructor() { _class9.prototype.__init71.cal
3327
3348
  }
3328
3349
  }
3329
3350
  let brush = options.tool === "knife" ? PAD_KNIFE : PAD_PAINT;
3330
- if (options.size !== void 0) brush = _chunk6G6ZDDDBcjs.normalizePaintBrush.call(void 0, { tip: { ...brush.tip, size: options.size } }, brush);
3351
+ if (options.size !== void 0) brush = _chunkH4AOUUBEcjs.normalizePaintBrush.call(void 0, { tip: { ...brush.tip, size: options.size } }, brush);
3331
3352
  return this.run(brush, points, options.color);
3332
3353
  }
3333
3354
  /** Paints `points` with `brush` in `color` on the pad. */
3334
3355
  run(brush, points, color) {
3335
- const [r, g, b] = _chunk6G6ZDDDBcjs.hexToRgb8.call(void 0, color);
3356
+ const [r, g, b] = _chunkH4AOUUBEcjs.hexToRgb8.call(void 0, color);
3336
3357
  let result = null;
3337
3358
  const session = new PaintStrokeSession(
3338
3359
  { update: () => {
@@ -3350,8 +3371,8 @@ var MixingPad = (_class9 = class {constructor() { _class9.prototype.__init71.cal
3350
3371
  seed: 1,
3351
3372
  colorHex: color,
3352
3373
  affineCopies: [],
3353
- copies: [_chunk6G6ZDDDBcjs.IDENTITY_COPY],
3354
- mixerLoad: brushLoadForStroke(brush, _chunkPQ3H2AANcjs.EMPTY_MIXER_LOAD, [r / 255, g / 255, b / 255])
3374
+ copies: [_chunkH4AOUUBEcjs.IDENTITY_COPY],
3375
+ mixerLoad: brushLoadForStroke(brush, _chunkI7NJPHWVcjs.EMPTY_MIXER_LOAD, [r / 255, g / 255, b / 255])
3355
3376
  }
3356
3377
  );
3357
3378
  session.push(points);
@@ -3426,10 +3447,10 @@ var MixingPad = (_class9 = class {constructor() { _class9.prototype.__init71.cal
3426
3447
  const off = used.length === 1 ? 0 : 0.45 * R;
3427
3448
  const x = Math.min(cx + R - r, Math.max(cx - R + r, cx + Math.cos(a) * off));
3428
3449
  const y = Math.min(cy + R - r, Math.max(cy - R + r, cy + Math.sin(a) * off));
3429
- const blob = _chunk6G6ZDDDBcjs.normalizePaintBrush.call(void 0, { tip: { ...PAD_BLOB.tip, size: Math.max(2, 2 * r) } }, PAD_BLOB);
3450
+ const blob = _chunkH4AOUUBEcjs.normalizePaintBrush.call(void 0, { tip: { ...PAD_BLOB.tip, size: Math.max(2, 2 * r) } }, PAD_BLOB);
3430
3451
  this.run(blob, [{ x, y }], p.color.toLowerCase());
3431
3452
  });
3432
- const knife = _chunk6G6ZDDDBcjs.normalizePaintBrush.call(void 0, { tip: { ...PAD_KNIFE.tip, size: Math.max(12, R * 0.5) } }, PAD_KNIFE);
3453
+ const knife = _chunkH4AOUUBEcjs.normalizePaintBrush.call(void 0, { tip: { ...PAD_KNIFE.tip, size: Math.max(12, R * 0.5) } }, PAD_KNIFE);
3433
3454
  for (let k = 0; k < passes; k++) {
3434
3455
  const stir = [];
3435
3456
  const turns = 1.6;
@@ -3440,24 +3461,24 @@ var MixingPad = (_class9 = class {constructor() { _class9.prototype.__init71.cal
3440
3461
  }
3441
3462
  this.run(knife, stir, "#000000");
3442
3463
  }
3443
- const mixed = _chunkOLNIPTB3cjs.mixPigments.call(void 0,
3444
- paints.map((p) => _chunk6G6ZDDDBcjs.hexToRgb8.call(void 0, p.color).map((v) => v / 255)),
3464
+ const mixed = _chunk2VX55NFMcjs.mixPigments.call(void 0,
3465
+ paints.map((p) => _chunkH4AOUUBEcjs.hexToRgb8.call(void 0, p.color).map((v) => v / 255)),
3445
3466
  paints.map((p) => p.parts)
3446
3467
  );
3447
- const core = _chunk6G6ZDDDBcjs.normalizePaintBrush.call(void 0, { tip: { ...PAD_BLOB.tip, size: R * 1.1, hardness: 0.55 } }, PAD_BLOB);
3468
+ const core = _chunkH4AOUUBEcjs.normalizePaintBrush.call(void 0, { tip: { ...PAD_BLOB.tip, size: R * 1.1, hardness: 0.55 } }, PAD_BLOB);
3448
3469
  const hex = "#" + mixed.map((v) => Math.round(v * 255).toString(16).padStart(2, "0")).join("");
3449
3470
  this.run(core, [{ x: cx, y: cy }], hex);
3450
3471
  return { color: this.pick(cx, cy, 2), bounds };
3451
3472
  }
3452
3473
  /** The pad's pixels as a PNG data URL (with alpha), for saving. */
3453
3474
  toPng() {
3454
- return _chunkOLNIPTB3cjs.pngDataUrl.call(void 0, this.width, this.height, _chunk474IQG74cjs.readRegion.call(void 0, this.surface, { x: 0, y: 0, width: this.width, height: this.height }));
3475
+ return _chunkW5M3J7PVcjs.pngDataUrl.call(void 0, this.width, this.height, _chunk474IQG74cjs.readRegion.call(void 0, this.surface, { x: 0, y: 0, width: this.width, height: this.height }));
3455
3476
  }
3456
3477
  /** Replaces the pad with a PNG (data URL or base64) of the pad's size, as `toPng` writes. */
3457
3478
  fromPng(png) {
3458
- const bytes = png.startsWith("data:") ? _optionalChain([_chunkOLNIPTB3cjs.parseDataUrl.call(void 0, png), 'optionalAccess', _187 => _187.bytes]) : _chunkOLNIPTB3cjs.base64ToBytes.call(void 0, png);
3459
- if (!bytes || !_chunkOLNIPTB3cjs.isPng.call(void 0, bytes)) throw new Error("The pad image is not a PNG data URL or base64 PNG.");
3460
- const img = _chunkOLNIPTB3cjs.decodePng.call(void 0, bytes);
3479
+ const bytes = png.startsWith("data:") ? _optionalChain([_chunkW5M3J7PVcjs.parseDataUrl.call(void 0, png), 'optionalAccess', _190 => _190.bytes]) : _chunkW5M3J7PVcjs.base64ToBytes.call(void 0, png);
3480
+ if (!bytes || !_chunkW5M3J7PVcjs.isPng.call(void 0, bytes)) throw new Error("The pad image is not a PNG data URL or base64 PNG.");
3481
+ const img = _chunkW5M3J7PVcjs.decodePng.call(void 0, bytes);
3461
3482
  if (img.width !== this.width || img.height !== this.height) throw new Error(`The pad image is ${img.width}\xD7${img.height}; a mixing pad is ${this.width}\xD7${this.height}.`);
3462
3483
  this.surface = _chunk474IQG74cjs.surfaceFromPixels.call(void 0, { width: img.width, height: img.height, data: img.data }, 4);
3463
3484
  this.version++;
@@ -3577,8 +3598,8 @@ var BacklightCache = (_class10 = class {constructor() { _class10.prototype.__ini
3577
3598
  refs.length = 0;
3578
3599
  for (const l of layers) {
3579
3600
  tilesUnder(l.surface, rect, l.offset, refs);
3580
- tilesUnder(_optionalChain([l, 'access', _188 => _188.thick, 'optionalAccess', _189 => _189.height]), rect, l.offset, refs);
3581
- tilesUnder(_optionalChain([l, 'access', _190 => _190.thick, 'optionalAccess', _191 => _191.material]), rect, l.offset, refs);
3601
+ tilesUnder(_optionalChain([l, 'access', _191 => _191.thick, 'optionalAccess', _192 => _192.height]), rect, l.offset, refs);
3602
+ tilesUnder(_optionalChain([l, 'access', _193 => _193.thick, 'optionalAccess', _194 => _194.material]), rect, l.offset, refs);
3582
3603
  }
3583
3604
  const k = _chunk474IQG74cjs.tileKey.call(void 0, tx, ty);
3584
3605
  let r = this.tiles.get(k);
@@ -3650,10 +3671,10 @@ function addTiles(a, b) {
3650
3671
  }
3651
3672
  function computeTile(paper, grain, amount, rect, layers) {
3652
3673
  const n = rect.width * rect.height;
3653
- const [p0, p1, p2] = _chunk6G6ZDDDBcjs.hexToRgb8.call(void 0, paper.color);
3674
+ const [p0, p1, p2] = _chunkH4AOUUBEcjs.hexToRgb8.call(void 0, paper.color);
3654
3675
  const pb = [p0, p1, p2];
3655
3676
  const pl = [Math.max(1e-4, LIN[p0]), Math.max(1e-4, LIN[p1]), Math.max(1e-4, LIN[p2])];
3656
- const [c0, c1, c2] = _chunk6G6ZDDDBcjs.hexToRgb8.call(void 0, _nullishCoalesce(paper.backlightColor, () => ( DEFAULT_BACKLIGHT_COLOR)));
3677
+ const [c0, c1, c2] = _chunkH4AOUUBEcjs.hexToRgb8.call(void 0, _nullishCoalesce(paper.backlightColor, () => ( DEFAULT_BACKLIGHT_COLOR)));
3657
3678
  const t0 = new Float32Array(n).fill(amount * LIN[c0]);
3658
3679
  const t1 = new Float32Array(n).fill(amount * LIN[c1]);
3659
3680
  const t2 = new Float32Array(n).fill(amount * LIN[c2]);
@@ -3672,8 +3693,8 @@ function computeTile(paper, grain, amount, rect, layers) {
3672
3693
  const lr = { x: rect.x - l.offset.x, y: rect.y - l.offset.y, width: rect.width, height: rect.height };
3673
3694
  if (!l.surface.tiles.size) continue;
3674
3695
  const px = _chunk474IQG74cjs.readRegion.call(void 0, l.surface, lr);
3675
- const h = _optionalChain([l, 'access', _192 => _192.thick, 'optionalAccess', _193 => _193.height, 'access', _194 => _194.tiles, 'access', _195 => _195.size]) ? _chunk474IQG74cjs.readRegion.call(void 0, l.thick.height, lr) : null;
3676
- const m = h && _optionalChain([l, 'access', _196 => _196.thick, 'optionalAccess', _197 => _197.material, 'access', _198 => _198.tiles, 'access', _199 => _199.size]) ? _chunk474IQG74cjs.readRegion.call(void 0, l.thick.material, lr) : null;
3696
+ const h = _optionalChain([l, 'access', _195 => _195.thick, 'optionalAccess', _196 => _196.height, 'access', _197 => _197.tiles, 'access', _198 => _198.size]) ? _chunk474IQG74cjs.readRegion.call(void 0, l.thick.height, lr) : null;
3697
+ const m = h && _optionalChain([l, 'access', _199 => _199.thick, 'optionalAccess', _200 => _200.material, 'access', _201 => _201.tiles, 'access', _202 => _202.size]) ? _chunk474IQG74cjs.readRegion.call(void 0, l.thick.material, lr) : null;
3677
3698
  const op = l.opacity;
3678
3699
  for (let i = 0; i < n; i++) {
3679
3700
  const a8 = px[i * 4 + 3];
@@ -3738,7 +3759,7 @@ function replayItems(doc) {
3738
3759
  }
3739
3760
  function emptiedLayers(layers) {
3740
3761
  let out = [...layers];
3741
- for (const l of _chunkHB4ICNNAcjs.flattenLayers.call(void 0, layers)) if (l.type === "pixel") out = _chunkHB4ICNNAcjs.mapLayer.call(void 0, out, l.id, () => ({ ...l, surface: _chunk474IQG74cjs.emptySurface.call(void 0, 4), offset: { x: 0, y: 0 } }));
3762
+ for (const l of _chunkDPYAO5U6cjs.flattenLayers.call(void 0, layers)) if (l.type === "pixel") out = _chunkDPYAO5U6cjs.mapLayer.call(void 0, out, l.id, () => ({ ...l, surface: _chunk474IQG74cjs.emptySurface.call(void 0, 4), offset: { x: 0, y: 0 } }));
3742
3763
  return out;
3743
3764
  }
3744
3765
  async function replayPainting(source, target, options = {}) {
@@ -3748,7 +3769,7 @@ async function replayPainting(source, target, options = {}) {
3748
3769
  const maxStrokes = _nullishCoalesce(options.strokes, () => ( source.strokes.length));
3749
3770
  const chunk = Math.max(1, _nullishCoalesce(options.wetChunk, () => ( 0))) || Infinity;
3750
3771
  let strokes = 0;
3751
- await target.prepareEffectPaints(source.strokes.slice(0, maxStrokes).flatMap((st) => _optionalChain([st, 'access', _200 => _200.paint, 'optionalAccess', _201 => _201.type]) === "effect" ? [st.paint] : []));
3772
+ await target.prepareEffectPaints(source.strokes.slice(0, maxStrokes).flatMap((st) => _optionalChain([st, 'access', _203 => _203.paint, 'optionalAccess', _204 => _204.type]) === "effect" ? [st.paint] : []));
3752
3773
  const advanceTo = async (clock) => {
3753
3774
  const now = target.getState().wet.clock;
3754
3775
  let left = clock - now;
@@ -3756,7 +3777,7 @@ async function replayPainting(source, target, options = {}) {
3756
3777
  const n = Math.min(left, chunk);
3757
3778
  await target.advanceWet({ steps: n });
3758
3779
  left -= n;
3759
- if (Number.isFinite(chunk)) await _optionalChain([options, 'access', _202 => _202.onWetSteps, 'optionalCall', _203 => _203(target.getState().wet.clock)]);
3780
+ if (Number.isFinite(chunk)) await _optionalChain([options, 'access', _205 => _205.onWetSteps, 'optionalCall', _206 => _206(target.getState().wet.clock)]);
3760
3781
  }
3761
3782
  };
3762
3783
  const sr = (r) => ({ x: r.x * s, y: r.y * s, width: r.width * s, height: r.height * s });
@@ -3769,14 +3790,14 @@ async function replayPainting(source, target, options = {}) {
3769
3790
  else if (e.kind === "clear") target.clearLayer(e.layerId);
3770
3791
  else if (e.kind === "live-strokes") {
3771
3792
  const d = e.data;
3772
- if (_optionalChain([d, 'optionalAccess', _204 => _204.rasterized])) target.replaceLiveStrokes(e.layerId, null);
3793
+ if (_optionalChain([d, 'optionalAccess', _207 => _207.rasterized])) target.replaceLiveStrokes(e.layerId, null);
3773
3794
  else {
3774
- const list = (_nullishCoalesce(_optionalChain([d, 'optionalAccess', _205 => _205.strokes]), () => ( []))).map((st2) => s === 1 ? st2 : { ...varyStroke(st2, scaleM, { scale: s }), ...st2.stencils ? { stencils: st2.stencils.map((x) => scaleStencil(x, s)) } : {} });
3775
- await target.prepareEffectPaints(list.flatMap((st2) => _optionalChain([st2, 'access', _206 => _206.paint, 'optionalAccess', _207 => _207.type]) === "effect" ? [st2.paint] : []));
3795
+ const list = (_nullishCoalesce(_optionalChain([d, 'optionalAccess', _208 => _208.strokes]), () => ( []))).map((st2) => s === 1 ? st2 : { ...varyStroke(st2, scaleM, { scale: s }), ...st2.stencils ? { stencils: st2.stencils.map((x) => scaleStencil(x, s)) } : {} });
3796
+ await target.prepareEffectPaints(list.flatMap((st2) => _optionalChain([st2, 'access', _209 => _209.paint, 'optionalAccess', _210 => _210.type]) === "effect" ? [st2.paint] : []));
3776
3797
  target.replaceLiveStrokes(e.layerId, list);
3777
3798
  }
3778
3799
  } else if (e.kind === "stickers") {
3779
- const list = (_nullishCoalesce(_optionalChain([e, 'access', _208 => _208.data, 'optionalAccess', _209 => _209.stickers]), () => ( []))).map((x) => s === 1 ? x : { ...x, x: x.x * s, y: x.y * s, size: x.size * s });
3800
+ const list = (_nullishCoalesce(_optionalChain([e, 'access', _211 => _211.data, 'optionalAccess', _212 => _212.stickers]), () => ( []))).map((x) => s === 1 ? x : { ...x, x: x.x * s, y: x.y * s, size: x.size * s });
3780
3801
  target.replaceStickers(e.layerId, list);
3781
3802
  } else target.flattenRelief(e.layerId);
3782
3803
  continue;
@@ -3789,8 +3810,8 @@ async function replayPainting(source, target, options = {}) {
3789
3810
  switch (e.kind) {
3790
3811
  case "dry": {
3791
3812
  const rect = e.data;
3792
- const ids = _optionalChain([e, 'access', _210 => _210.layerId, 'optionalAccess', _211 => _211.split, 'call', _212 => _212(","), 'access', _213 => _213.filter, 'call', _214 => _214(Boolean)]);
3793
- if (_optionalChain([ids, 'optionalAccess', _215 => _215.length])) for (const id of ids) target.dryPaint({ layerId: id, rect: rect ? sr(rect) : void 0 });
3813
+ const ids = _optionalChain([e, 'access', _213 => _213.layerId, 'optionalAccess', _214 => _214.split, 'call', _215 => _215(","), 'access', _216 => _216.filter, 'call', _217 => _217(Boolean)]);
3814
+ if (_optionalChain([ids, 'optionalAccess', _218 => _218.length])) for (const id of ids) target.dryPaint({ layerId: id, rect: rect ? sr(rect) : void 0 });
3794
3815
  else target.dryPaint({ rect: rect ? sr(rect) : void 0 });
3795
3816
  break;
3796
3817
  }
@@ -3821,7 +3842,7 @@ async function replayPainting(source, target, options = {}) {
3821
3842
  strokes++;
3822
3843
  if (!target.getLayer(st.layerId)) continue;
3823
3844
  const init = { layerId: st.layerId, color: st.color, brush: st.brush, seed: st.seed, copies: _nullishCoalesce(st.copies, () => ( [])), ...st.load ? { load: st.load } : {}, ...st.paint ? { paint: st.paint } : {}, snapToPerspective: false, stencils: false, maskStencils: (_nullishCoalesce(st.stencils, () => ( []))).map((x) => s === 1 ? x : scaleStencil(x, s)) };
3824
- if (st.brush.engine === "wet" && _optionalChain([st, 'access', _216 => _216.steps, 'optionalAccess', _217 => _217.length]) === st.points.length) {
3845
+ if (st.brush.engine === "wet" && _optionalChain([st, 'access', _219 => _219.steps, 'optionalAccess', _220 => _220.length]) === st.points.length) {
3825
3846
  await target.wetIdle();
3826
3847
  await advanceTo(st.steps[0]);
3827
3848
  const session = target.beginStroke({ ...init, start: st.points[0] });
@@ -3841,7 +3862,7 @@ async function replayPainting(source, target, options = {}) {
3841
3862
  await target.wetIdle();
3842
3863
  target.paintStroke({ ...init, points: st.points });
3843
3864
  }
3844
- await _optionalChain([options, 'access', _218 => _218.onStroke, 'optionalCall', _219 => _219(strokes)]);
3865
+ await _optionalChain([options, 'access', _221 => _221.onStroke, 'optionalCall', _222 => _222(strokes)]);
3845
3866
  }
3846
3867
  void IDENTITY_AFFINE;
3847
3868
  }
@@ -3879,14 +3900,14 @@ async function buildTimeLapse(source, target, options = {}) {
3879
3900
  const f = replayFrame(target, maxSide, stroke);
3880
3901
  width = f.width;
3881
3902
  height = f.height;
3882
- frames.push(_chunkOLNIPTB3cjs.encodePng.call(void 0, f.width, f.height, f.data));
3903
+ frames.push(_chunkW5M3J7PVcjs.encodePng.call(void 0, f.width, f.height, f.data));
3883
3904
  };
3884
3905
  shoot(0);
3885
3906
  await replayPainting(source, target, {
3886
3907
  wetChunk: wetEvery > 0 ? wetEvery : 0,
3887
3908
  onStroke: (i) => {
3888
3909
  if (i % perFrame === 0 || i === total) shoot(i);
3889
- _optionalChain([options, 'access', _220 => _220.onProgress, 'optionalCall', _221 => _221(total ? i / total : 1)]);
3910
+ _optionalChain([options, 'access', _223 => _223.onProgress, 'optionalCall', _224 => _224(total ? i / total : 1)]);
3890
3911
  },
3891
3912
  onWetSteps: wetEvery > 0 ? () => shoot(-1) : void 0
3892
3913
  });
@@ -4027,15 +4048,15 @@ function readPaintEffectSource(raw) {
4027
4048
  };
4028
4049
  }
4029
4050
  function paperEffectToJSON(p) {
4030
- return { ...sourceOut(p), opacity: p.opacity, blend: p.blend, png: _chunkOLNIPTB3cjs.pngDataUrl.call(void 0, p.image.width, p.image.height, p.image.data) };
4051
+ return { ...sourceOut(p), opacity: p.opacity, blend: p.blend, png: _chunkW5M3J7PVcjs.pngDataUrl.call(void 0, p.image.width, p.image.height, p.image.data) };
4031
4052
  }
4032
4053
  function paperEffectFromJSON(raw, width, height) {
4033
4054
  const source = readPaintEffectSource(raw);
4034
4055
  if (!source) throw new Error("it is not an effect (effect id and values)");
4035
4056
  const r = raw;
4036
- const parsed = typeof r.png === "string" ? _chunkOLNIPTB3cjs.parseDataUrl.call(void 0, r.png) : null;
4057
+ const parsed = typeof r.png === "string" ? _chunkW5M3J7PVcjs.parseDataUrl.call(void 0, r.png) : null;
4037
4058
  if (!parsed) throw new Error("its pixels are missing");
4038
- const image = _chunkOLNIPTB3cjs.decodePng.call(void 0, parsed.bytes);
4059
+ const image = _chunkW5M3J7PVcjs.decodePng.call(void 0, parsed.bytes);
4039
4060
  if (image.width !== width || image.height !== height) throw new Error(`its pixels are ${image.width}\xD7${image.height}, not the canvas size ${width}\xD7${height}`);
4040
4061
  const opacity = typeof r.opacity === "number" && r.opacity >= 0 && r.opacity <= 1 ? r.opacity : 1;
4041
4062
  const blend = PAPER_EFFECT_BLENDS.includes(r.blend) ? r.blend : "multiply";
@@ -4052,7 +4073,7 @@ function effectGuard(fn) {
4052
4073
  try {
4053
4074
  return fn();
4054
4075
  } catch (e) {
4055
- if (e instanceof _chunkHB4ICNNAcjs.LayerEffectError) throw new PaintEditorError(e.message);
4076
+ if (e instanceof _chunkDPYAO5U6cjs.LayerEffectError) throw new PaintEditorError(e.message);
4056
4077
  throw e;
4057
4078
  }
4058
4079
  }
@@ -4069,7 +4090,7 @@ function parseColor(value, what = "color") {
4069
4090
  return value.trim().toLowerCase();
4070
4091
  }
4071
4092
  function rgbaOf(hex) {
4072
- const [r, g, b] = _chunk6G6ZDDDBcjs.hexToRgb8.call(void 0, hex);
4093
+ const [r, g, b] = _chunkH4AOUUBEcjs.hexToRgb8.call(void 0, hex);
4073
4094
  return [r, g, b, 255];
4074
4095
  }
4075
4096
  function rgbToHex(r, g, b) {
@@ -4082,7 +4103,7 @@ function unionRect(a, b) {
4082
4103
  const y = Math.min(a.y, b.y);
4083
4104
  return { x, y, width: Math.max(a.x + a.width, b.x + b.width) - x, height: Math.max(a.y + a.height, b.y + b.height) - y };
4084
4105
  }
4085
- var isPixelLayer = (l) => _optionalChain([l, 'optionalAccess', _222 => _222.type]) === "pixel";
4106
+ var isPixelLayer = (l) => _optionalChain([l, 'optionalAccess', _225 => _225.type]) === "pixel";
4086
4107
  var PaintEditorController = (_class12 = class _PaintEditorController {
4087
4108
 
4088
4109
  __init82() {this.extensions = {}}
@@ -4104,7 +4125,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
4104
4125
  __init90() {this.paintEpoch = 0}
4105
4126
  /** Rendered effect paints by `effectPaintKey` (most recently used last). */
4106
4127
  __init91() {this.effectPaintPixels = /* @__PURE__ */ new Map()}
4107
- __init92() {this.mixerLoad = _chunkPQ3H2AANcjs.EMPTY_MIXER_LOAD}
4128
+ __init92() {this.mixerLoad = _chunkI7NJPHWVcjs.EMPTY_MIXER_LOAD}
4108
4129
  __init93() {this.view = { ...DEFAULT_VIEW, pan: { ...DEFAULT_VIEW.pan } }}
4109
4130
 
4110
4131
  __init94() {this.selectedStroke = null}
@@ -4161,14 +4182,20 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
4161
4182
  __init129() {this.wetOp = null}
4162
4183
  /** The effects provider slot (see `setEffectsProvider`). */
4163
4184
  __init130() {this.effects = new (0, _chunkGHCSC2WPcjs.EffectsSlot)()}
4164
- __init131() {this.effectsRenderer = new PaintEffectsRenderer()}
4165
- __init132() {this.paperEffectNodeCache = null}
4166
- constructor(options = {}) {;_class12.prototype.__init82.call(this);_class12.prototype.__init83.call(this);_class12.prototype.__init84.call(this);_class12.prototype.__init85.call(this);_class12.prototype.__init86.call(this);_class12.prototype.__init87.call(this);_class12.prototype.__init88.call(this);_class12.prototype.__init89.call(this);_class12.prototype.__init90.call(this);_class12.prototype.__init91.call(this);_class12.prototype.__init92.call(this);_class12.prototype.__init93.call(this);_class12.prototype.__init94.call(this);_class12.prototype.__init95.call(this);_class12.prototype.__init96.call(this);_class12.prototype.__init97.call(this);_class12.prototype.__init98.call(this);_class12.prototype.__init99.call(this);_class12.prototype.__init100.call(this);_class12.prototype.__init101.call(this);_class12.prototype.__init102.call(this);_class12.prototype.__init103.call(this);_class12.prototype.__init104.call(this);_class12.prototype.__init105.call(this);_class12.prototype.__init106.call(this);_class12.prototype.__init107.call(this);_class12.prototype.__init108.call(this);_class12.prototype.__init109.call(this);_class12.prototype.__init110.call(this);_class12.prototype.__init111.call(this);_class12.prototype.__init112.call(this);_class12.prototype.__init113.call(this);_class12.prototype.__init114.call(this);_class12.prototype.__init115.call(this);_class12.prototype.__init116.call(this);_class12.prototype.__init117.call(this);_class12.prototype.__init118.call(this);_class12.prototype.__init119.call(this);_class12.prototype.__init120.call(this);_class12.prototype.__init121.call(this);_class12.prototype.__init122.call(this);_class12.prototype.__init123.call(this);_class12.prototype.__init124.call(this);_class12.prototype.__init125.call(this);_class12.prototype.__init126.call(this);_class12.prototype.__init127.call(this);_class12.prototype.__init128.call(this);_class12.prototype.__init129.call(this);_class12.prototype.__init130.call(this);_class12.prototype.__init131.call(this);_class12.prototype.__init132.call(this);_class12.prototype.__init133.call(this);_class12.prototype.__init134.call(this);_class12.prototype.__init135.call(this);_class12.prototype.__init136.call(this);
4185
+ /** The sticker library slot (see `setStickersProvider`). */
4186
+ __init131() {this.stickers = new (0, _chunkZEYMKDYScjs.StickersSlot)(_chunkLJRCU3BJcjs.editorStickers.call(void 0, ))}
4187
+ __init132() {this.stickerArt = new (0, _chunkH4AOUUBEcjs.StickerArtCache)()}
4188
+
4189
+ __init133() {this.effectsRenderer = new PaintEffectsRenderer()}
4190
+ __init134() {this.paperEffectNodeCache = null}
4191
+ constructor(options = {}) {;_class12.prototype.__init82.call(this);_class12.prototype.__init83.call(this);_class12.prototype.__init84.call(this);_class12.prototype.__init85.call(this);_class12.prototype.__init86.call(this);_class12.prototype.__init87.call(this);_class12.prototype.__init88.call(this);_class12.prototype.__init89.call(this);_class12.prototype.__init90.call(this);_class12.prototype.__init91.call(this);_class12.prototype.__init92.call(this);_class12.prototype.__init93.call(this);_class12.prototype.__init94.call(this);_class12.prototype.__init95.call(this);_class12.prototype.__init96.call(this);_class12.prototype.__init97.call(this);_class12.prototype.__init98.call(this);_class12.prototype.__init99.call(this);_class12.prototype.__init100.call(this);_class12.prototype.__init101.call(this);_class12.prototype.__init102.call(this);_class12.prototype.__init103.call(this);_class12.prototype.__init104.call(this);_class12.prototype.__init105.call(this);_class12.prototype.__init106.call(this);_class12.prototype.__init107.call(this);_class12.prototype.__init108.call(this);_class12.prototype.__init109.call(this);_class12.prototype.__init110.call(this);_class12.prototype.__init111.call(this);_class12.prototype.__init112.call(this);_class12.prototype.__init113.call(this);_class12.prototype.__init114.call(this);_class12.prototype.__init115.call(this);_class12.prototype.__init116.call(this);_class12.prototype.__init117.call(this);_class12.prototype.__init118.call(this);_class12.prototype.__init119.call(this);_class12.prototype.__init120.call(this);_class12.prototype.__init121.call(this);_class12.prototype.__init122.call(this);_class12.prototype.__init123.call(this);_class12.prototype.__init124.call(this);_class12.prototype.__init125.call(this);_class12.prototype.__init126.call(this);_class12.prototype.__init127.call(this);_class12.prototype.__init128.call(this);_class12.prototype.__init129.call(this);_class12.prototype.__init130.call(this);_class12.prototype.__init131.call(this);_class12.prototype.__init132.call(this);_class12.prototype.__init133.call(this);_class12.prototype.__init134.call(this);_class12.prototype.__init135.call(this);_class12.prototype.__init136.call(this);_class12.prototype.__init137.call(this);_class12.prototype.__init138.call(this);
4167
4192
  this.historyLimit = Math.max(1, _nullishCoalesce(options.historyLimit, () => ( 200)));
4193
+ this.rasterizeSticker = _nullishCoalesce(options.rasterizeSticker, () => ( _chunkH4AOUUBEcjs.defaultStickerRasterizer));
4194
+ if (options.stickers) this.stickers.set(options.stickers);
4168
4195
  this.doc = createPaintDocument({ width: options.width, height: options.height, dpi: options.dpi, paper: this.resolvePaper(options.paper) });
4169
- this.userBrushes = (_nullishCoalesce(options.brushes, () => ( []))).map((b) => _chunk6G6ZDDDBcjs.normalizePaintBrush.call(void 0, { ...b, builtin: false }));
4170
- const start = _nullishCoalesce(this.findBrush(_nullishCoalesce(options.brushId, () => ( _chunk6G6ZDDDBcjs.DEFAULT_BRUSH_ID))), () => ( this.findBrush(_chunk6G6ZDDDBcjs.DEFAULT_BRUSH_ID)));
4171
- this.brush = _chunk6G6ZDDDBcjs.normalizePaintBrush.call(void 0, start);
4196
+ this.userBrushes = (_nullishCoalesce(options.brushes, () => ( []))).map((b) => _chunkH4AOUUBEcjs.normalizePaintBrush.call(void 0, { ...b, builtin: false }));
4197
+ const start = _nullishCoalesce(this.findBrush(_nullishCoalesce(options.brushId, () => ( _chunkH4AOUUBEcjs.DEFAULT_BRUSH_ID))), () => ( this.findBrush(_chunkH4AOUUBEcjs.DEFAULT_BRUSH_ID)));
4198
+ this.brush = _chunkH4AOUUBEcjs.normalizePaintBrush.call(void 0, start);
4172
4199
  this.color = options.color ? parseColor(options.color) : "#1f2937";
4173
4200
  this.hand = options.hand === "left" ? "left" : "right";
4174
4201
  this.encodeImage = options.encodeImage;
@@ -4179,19 +4206,19 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
4179
4206
  canvas: () => this.doc.canvas,
4180
4207
  paper: () => this.doc.paper,
4181
4208
  layerSurface: (id) => {
4182
- const l = _optionalChain([_chunkHB4ICNNAcjs.findLayer.call(void 0, this.doc.layers, id), 'optionalAccess', _223 => _223.layer]);
4209
+ const l = _optionalChain([_chunkDPYAO5U6cjs.findLayer.call(void 0, this.doc.layers, id), 'optionalAccess', _226 => _226.layer]);
4183
4210
  return isPixelLayer(l) ? l.surface : null;
4184
4211
  },
4185
4212
  updateSurfaces: (surfaces, rects) => {
4186
4213
  let layers = this.doc.layers;
4187
- for (const [id, surface] of surfaces) if (_chunkHB4ICNNAcjs.findLayer.call(void 0, layers, id)) layers = _chunkHB4ICNNAcjs.mapLayer.call(void 0, layers, id, (l) => ({ ...l, surface }));
4214
+ for (const [id, surface] of surfaces) if (_chunkDPYAO5U6cjs.findLayer.call(void 0, layers, id)) layers = _chunkDPYAO5U6cjs.mapLayer.call(void 0, layers, id, (l) => ({ ...l, surface }));
4188
4215
  this.doc = { ...this.doc, layers };
4189
4216
  this.emit(rects.length ? rects : "all");
4190
4217
  },
4191
- layerLight: (id) => _nullishCoalesce(_optionalChain([this, 'access', _224 => _224.doc, 'access', _225 => _225.light, 'optionalAccess', _226 => _226[id]]), () => ( null)),
4218
+ layerLight: (id) => _nullishCoalesce(_optionalChain([this, 'access', _227 => _227.doc, 'access', _228 => _228.light, 'optionalAccess', _229 => _229[id]]), () => ( null)),
4192
4219
  updateLights: (lights) => {
4193
4220
  let light = this.doc.light;
4194
- for (const [id, surface] of lights) if (_chunkHB4ICNNAcjs.findLayer.call(void 0, this.doc.layers, id)) light = withLayerLight(light, id, surface);
4221
+ for (const [id, surface] of lights) if (_chunkDPYAO5U6cjs.findLayer.call(void 0, this.doc.layers, id)) light = withLayerLight(light, id, surface);
4195
4222
  this.doc = { ...this.doc, ...light ? { light } : {} };
4196
4223
  },
4197
4224
  changed: () => {
@@ -4199,7 +4226,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
4199
4226
  },
4200
4227
  options.wet
4201
4228
  );
4202
- this.wet.onDriverDone = () => _optionalChain([this, 'access', _227 => _227.session, 'optionalAccess', _228 => _228.completeWetEnd, 'call', _229 => _229()]);
4229
+ this.wet.onDriverDone = () => _optionalChain([this, 'access', _230 => _230.session, 'optionalAccess', _231 => _231.completeWetEnd, 'call', _232 => _232()]);
4203
4230
  }
4204
4231
  // --- State and events ----------------------------------------------------------
4205
4232
  subscribe(listener) {
@@ -4221,7 +4248,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
4221
4248
  this.cached = {
4222
4249
  document: this.doc,
4223
4250
  brush: this.brush,
4224
- brushes: this.library ??= [..._chunk6G6ZDDDBcjs.BUILTIN_BRUSHES, ...this.userBrushes],
4251
+ brushes: this.library ??= [..._chunkH4AOUUBEcjs.BUILTIN_BRUSHES, ...this.userBrushes],
4225
4252
  color: this.color,
4226
4253
  secondaryColor: this.secondaryColor,
4227
4254
  paint: _nullishCoalesce(this.gradient, () => ( { type: "color", color: this.color })),
@@ -4235,8 +4262,8 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
4235
4262
  selectedSticker: this.selectedSticker,
4236
4263
  canUndo: this.undoStack.length > 0 && !this.session,
4237
4264
  canRedo: this.redoStack.length > 0 && !this.session,
4238
- undoLabel: _nullishCoalesce(_optionalChain([last, 'optionalAccess', _230 => _230.label]), () => ( null)),
4239
- redoLabel: _nullishCoalesce(_optionalChain([next, 'optionalAccess', _231 => _231.label]), () => ( null)),
4265
+ undoLabel: _nullishCoalesce(_optionalChain([last, 'optionalAccess', _233 => _233.label]), () => ( null)),
4266
+ redoLabel: _nullishCoalesce(_optionalChain([next, 'optionalAccess', _234 => _234.label]), () => ( null)),
4240
4267
  guides: this.guides,
4241
4268
  swatches: this.swatches,
4242
4269
  mixingPadVersion: this.pad.version,
@@ -4249,10 +4276,10 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
4249
4276
  overlay: this.wet.overlay,
4250
4277
  instantDry: this.wet.instantDry,
4251
4278
  speed: this.wet.speed,
4252
- clock: _nullishCoalesce(_optionalChain([this, 'access', _232 => _232.wet, 'access', _233 => _233.world, 'optionalAccess', _234 => _234.clock]), () => ( 0)),
4279
+ clock: _nullishCoalesce(_optionalChain([this, 'access', _235 => _235.wet, 'access', _236 => _236.world, 'optionalAccess', _237 => _237.clock]), () => ( 0)),
4253
4280
  tilt: { ...this.wet.tilt },
4254
4281
  gpu: this.wet.gpuMode,
4255
- gpuActive: Boolean(_optionalChain([this, 'access', _235 => _235.wet, 'access', _236 => _236.world, 'optionalAccess', _237 => _237.gpuActive]))
4282
+ gpuActive: Boolean(_optionalChain([this, 'access', _238 => _238.wet, 'access', _239 => _239.world, 'optionalAccess', _240 => _240.gpuActive]))
4256
4283
  },
4257
4284
  version: this.version
4258
4285
  };
@@ -4271,7 +4298,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
4271
4298
  return d;
4272
4299
  }
4273
4300
  // --- History -------------------------------------------------------------------
4274
- __init133() {this.docRevision = 0}
4301
+ __init135() {this.docRevision = 0}
4275
4302
  /**
4276
4303
  * Bumped on every change to the painting (a committed or amended step, undo, redo, opening a
4277
4304
  * document), not on wet-paint frames or view changes. `createPaintEditorDocument` uses it.
@@ -4354,9 +4381,9 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
4354
4381
  return wetIds;
4355
4382
  }
4356
4383
  /** Records a wet event (for replays) in the document being built. */
4357
- __init134() {this.pendingWetEvents = []}
4384
+ __init136() {this.pendingWetEvents = []}
4358
4385
  logWet(e) {
4359
- this.pendingWetEvents.push({ clock: _nullishCoalesce(_optionalChain([this, 'access', _238 => _238.wet, 'access', _239 => _239.world, 'optionalAccess', _240 => _240.clock]), () => ( 0)), at: this.doc.strokes.length, ...e });
4386
+ this.pendingWetEvents.push({ clock: _nullishCoalesce(_optionalChain([this, 'access', _241 => _241.wet, 'access', _242 => _242.world, 'optionalAccess', _243 => _243.clock]), () => ( 0)), at: this.doc.strokes.length, ...e });
4360
4387
  }
4361
4388
  /** The document with a paint event appended (for replays). */
4362
4389
  withPaintEvent(doc, e) {
@@ -4417,7 +4444,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
4417
4444
  // --- Canvas and paper ----------------------------------------------------------
4418
4445
  resolvePaper(paper) {
4419
4446
  if (typeof paper === "string") {
4420
- const p = _chunk6G6ZDDDBcjs.paperPreset.call(void 0, paper);
4447
+ const p = _chunkH4AOUUBEcjs.paperPreset.call(void 0, paper);
4421
4448
  if (!p) throw new PaintEditorError(`Unknown paper "${paper}". Call list_papers for the ids.`);
4422
4449
  return p;
4423
4450
  }
@@ -4500,8 +4527,8 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
4500
4527
  }
4501
4528
  let next = { ...shiftDocument(this.withWetEvents(this.doc), left, top), canvas: { ...was, width, height } };
4502
4529
  for (const id of keptWet) {
4503
- const l = _optionalChain([_chunkHB4ICNNAcjs.findLayer.call(void 0, next.layers, id), 'optionalAccess', _241 => _241.layer]);
4504
- if (isPixelLayer(l)) next = { ...next, layers: _chunkHB4ICNNAcjs.mapLayer.call(void 0, next.layers, id, () => ({ ...l, surface: _chunk474IQG74cjs.translateSurface.call(void 0, l.surface, l.offset.x, l.offset.y), offset: { x: 0, y: 0 } })) };
4530
+ const l = _optionalChain([_chunkDPYAO5U6cjs.findLayer.call(void 0, next.layers, id), 'optionalAccess', _244 => _244.layer]);
4531
+ if (isPixelLayer(l)) next = { ...next, layers: _chunkDPYAO5U6cjs.mapLayer.call(void 0, next.layers, id, () => ({ ...l, surface: _chunk474IQG74cjs.translateSurface.call(void 0, l.surface, l.offset.x, l.offset.y), offset: { x: 0, y: 0 } })) };
4505
4532
  }
4506
4533
  if (this.wet.world) {
4507
4534
  if (keptWet.length) this.wet.extend(width, height, left, top, next.paper);
@@ -4528,23 +4555,23 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
4528
4555
  this.requireIdle("changing the paper");
4529
4556
  let base = this.doc.paper;
4530
4557
  if (update.preset !== void 0 && update.preset !== this.doc.paper.preset) {
4531
- const p = _chunk6G6ZDDDBcjs.paperPreset.call(void 0, update.preset);
4558
+ const p = _chunkH4AOUUBEcjs.paperPreset.call(void 0, update.preset);
4532
4559
  if (!p) throw new PaintEditorError(`Unknown paper "${update.preset}". Call list_papers for the ids.`);
4533
4560
  base = p;
4534
4561
  }
4535
4562
  const { preset: _p, ...rest } = update;
4536
4563
  if (rest.color !== void 0) parseColor(rest.color, "paper color");
4537
- const paper = _chunk6G6ZDDDBcjs.normalizePaper.call(void 0, { ...rest, preset: base.preset, offset: _nullishCoalesce(rest.offset, () => ( this.doc.paper.offset)) }, base);
4564
+ const paper = _chunkH4AOUUBEcjs.normalizePaper.call(void 0, { ...rest, preset: base.preset, offset: _nullishCoalesce(rest.offset, () => ( this.doc.paper.offset)) }, base);
4538
4565
  const changedKeys = Object.keys(rest).filter((k) => k !== "name");
4539
4566
  if (changedKeys.length && update.preset === void 0) paper.preset = base.preset;
4540
4567
  if (this.wet.world) this.beginWetOp();
4541
4568
  this.commit("Paper", { ...this.doc, paper });
4542
4569
  this.wet.paperChanged();
4543
- return _chunk6G6ZDDDBcjs.clonePaper.call(void 0, paper);
4570
+ return _chunkH4AOUUBEcjs.clonePaper.call(void 0, paper);
4544
4571
  }
4545
4572
  // --- Layers --------------------------------------------------------------------
4546
4573
  getLayer(id) {
4547
- return _optionalChain([_chunkHB4ICNNAcjs.findLayer.call(void 0, this.doc.layers, id), 'optionalAccess', _242 => _242.layer]);
4574
+ return _optionalChain([_chunkDPYAO5U6cjs.findLayer.call(void 0, this.doc.layers, id), 'optionalAccess', _245 => _245.layer]);
4548
4575
  }
4549
4576
  /** The active pixel layer (or `undefined`). */
4550
4577
  getActiveLayer() {
@@ -4563,12 +4590,12 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
4563
4590
  walk(this.doc.layers, null, 0);
4564
4591
  return out;
4565
4592
  }
4566
- describeLayer(l, parentId = _nullishCoalesce(_optionalChain([_chunkHB4ICNNAcjs.findLayer.call(void 0, this.doc.layers, l.id), 'optionalAccess', _243 => _243.parent, 'optionalAccess', _244 => _244.id]), () => ( null)), depth = _nullishCoalesce(_optionalChain([_chunkHB4ICNNAcjs.findLayer.call(void 0, this.doc.layers, l.id), 'optionalAccess', _245 => _245.path, 'access', _246 => _246.length]), () => ( 0))) {
4593
+ describeLayer(l, parentId = _nullishCoalesce(_optionalChain([_chunkDPYAO5U6cjs.findLayer.call(void 0, this.doc.layers, l.id), 'optionalAccess', _246 => _246.parent, 'optionalAccess', _247 => _247.id]), () => ( null)), depth = _nullishCoalesce(_optionalChain([_chunkDPYAO5U6cjs.findLayer.call(void 0, this.doc.layers, l.id), 'optionalAccess', _248 => _248.path, 'access', _249 => _249.length]), () => ( 0))) {
4567
4594
  let bounds = null;
4568
4595
  if (l.type === "pixel") {
4569
4596
  const b = _chunk474IQG74cjs.contentBounds.call(void 0, l.surface);
4570
4597
  bounds = b ? { ...b, x: b.x + l.offset.x, y: b.y + l.offset.y } : null;
4571
- } else for (const c of _chunkHB4ICNNAcjs.flattenLayers.call(void 0, l.children)) if (c.type === "pixel") bounds = unionRect(bounds, this.describeLayer(c, l.id, depth + 1).bounds);
4598
+ } else for (const c of _chunkDPYAO5U6cjs.flattenLayers.call(void 0, l.children)) if (c.type === "pixel") bounds = unionRect(bounds, this.describeLayer(c, l.id, depth + 1).bounds);
4572
4599
  return {
4573
4600
  id: l.id,
4574
4601
  name: l.name,
@@ -4580,8 +4607,8 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
4580
4607
  locks: { ..._nullishCoalesce(l.locks, () => ( {})) },
4581
4608
  active: l.id === this.doc.activeLayerId,
4582
4609
  bounds,
4583
- ..._optionalChain([this, 'access', _247 => _247.doc, 'access', _248 => _248.liveStrokes, 'optionalAccess', _249 => _249[l.id]]) ? { liveStrokes: this.doc.liveStrokes[l.id].length } : {},
4584
- ..._optionalChain([l, 'access', _250 => _250.effects, 'optionalAccess', _251 => _251.items, 'access', _252 => _252.length]) ? { effects: l.effects.items.length } : {},
4610
+ ..._optionalChain([this, 'access', _250 => _250.doc, 'access', _251 => _251.liveStrokes, 'optionalAccess', _252 => _252[l.id]]) ? { liveStrokes: this.doc.liveStrokes[l.id].length } : {},
4611
+ ..._optionalChain([l, 'access', _253 => _253.effects, 'optionalAccess', _254 => _254.items, 'access', _255 => _255.length]) ? { effects: l.effects.items.length } : {},
4585
4612
  parentId,
4586
4613
  depth
4587
4614
  };
@@ -4597,7 +4624,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
4597
4624
  if (!id) throw new PaintEditorError(`There is no active layer to ${what}; add one with add_layer.`);
4598
4625
  const l = this.requireLayer(id);
4599
4626
  if (!isPixelLayer(l)) throw new PaintEditorError(`Layer "${l.name}" is a group; ${what} a pixel layer inside it.`);
4600
- if (_chunkHB4ICNNAcjs.isLayerLocked.call(void 0, l, "pixels")) throw new PaintEditorError(`Layer "${l.name}" has its pixels locked; unlock it (update_layer locks) before you ${what} it.`);
4627
+ if (_chunkDPYAO5U6cjs.isLayerLocked.call(void 0, l, "pixels")) throw new PaintEditorError(`Layer "${l.name}" has its pixels locked; unlock it (update_layer locks) before you ${what} it.`);
4601
4628
  if (!l.visible) throw new PaintEditorError(`Layer "${l.name}" is hidden; show it (update_layer visible true) before you ${what} it.`);
4602
4629
  return l;
4603
4630
  }
@@ -4611,9 +4638,9 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
4611
4638
  /** Adds a layer above the active one: `pixel` (default), `group`, or `strokes`, a live stroke layer whose strokes stay editable. */
4612
4639
  addLayer(options = {}) {
4613
4640
  this.requireIdle("adding a layer");
4614
- const count = _chunkHB4ICNNAcjs.flattenLayers.call(void 0, this.doc.layers).length;
4641
+ const count = _chunkDPYAO5U6cjs.flattenLayers.call(void 0, this.doc.layers).length;
4615
4642
  const type = _nullishCoalesce(options.type, () => ( "pixel"));
4616
- const name = _optionalChain([options, 'access', _253 => _253.name, 'optionalAccess', _254 => _254.trim, 'call', _255 => _255()]) || (type === "group" ? `Group ${count + 1}` : type === "strokes" ? `Strokes ${count + 1}` : `Layer ${count + 1}`);
4643
+ const name = _optionalChain([options, 'access', _256 => _256.name, 'optionalAccess', _257 => _257.trim, 'call', _258 => _258()]) || (type === "group" ? `Group ${count + 1}` : type === "strokes" ? `Strokes ${count + 1}` : `Layer ${count + 1}`);
4617
4644
  const layer = type === "group" ? { type: "group", id: newPaintLayerId(), name, visible: true, opacity: 1, blend: "pass-through", children: [] } : createPaintLayer(name);
4618
4645
  let parentId = null;
4619
4646
  let index;
@@ -4623,12 +4650,12 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
4623
4650
  if (g.type !== "group") throw new PaintEditorError(`Layer "${g.name}" is not a group; pass a group id as parentId.`);
4624
4651
  parentId = g.id;
4625
4652
  } else if (above) {
4626
- const loc = _chunkHB4ICNNAcjs.findLayer.call(void 0, this.doc.layers, above);
4653
+ const loc = _chunkDPYAO5U6cjs.findLayer.call(void 0, this.doc.layers, above);
4627
4654
  if (!loc) throw new PaintEditorError(`Unknown layer "${above}". Call list_layers for the ids.`);
4628
- parentId = _nullishCoalesce(_optionalChain([loc, 'access', _256 => _256.parent, 'optionalAccess', _257 => _257.id]), () => ( null));
4655
+ parentId = _nullishCoalesce(_optionalChain([loc, 'access', _259 => _259.parent, 'optionalAccess', _260 => _260.id]), () => ( null));
4629
4656
  index = loc.index + 1;
4630
4657
  }
4631
- const layers = _chunkHB4ICNNAcjs.insertLayer.call(void 0, this.doc.layers, layer, parentId, index);
4658
+ const layers = _chunkDPYAO5U6cjs.insertLayer.call(void 0, this.doc.layers, layer, parentId, index);
4632
4659
  const live = type === "strokes" ? { liveStrokes: { ..._nullishCoalesce(this.doc.liveStrokes, () => ( {})), [layer.id]: [] } } : {};
4633
4660
  this.commit(type === "group" ? "Add group" : type === "strokes" ? "Add stroke layer" : "Add layer", { ...this.doc, layers, activeLayerId: layer.id, ...live });
4634
4661
  return this.describeLayer(layer);
@@ -4636,9 +4663,9 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
4636
4663
  updateLayer(id, update) {
4637
4664
  this.requireIdle("changing a layer");
4638
4665
  const l = this.requireLayer(id);
4639
- if (_chunkHB4ICNNAcjs.isLayerLocked.call(void 0, l, "all") && Object.keys(update).some((k) => k !== "locks")) throw new PaintEditorError(`Layer "${l.name}" is fully locked; unlock it first (locks {all: false}).`);
4666
+ if (_chunkDPYAO5U6cjs.isLayerLocked.call(void 0, l, "all") && Object.keys(update).some((k) => k !== "locks")) throw new PaintEditorError(`Layer "${l.name}" is fully locked; unlock it first (locks {all: false}).`);
4640
4667
  if (update.opacity !== void 0 && !(update.opacity >= 0 && update.opacity <= 1)) throw new PaintEditorError(`opacity ${update.opacity} is out of range; use 0..1.`);
4641
- if (update.blend !== void 0 && !_chunkOLNIPTB3cjs.isBlendMode.call(void 0, update.blend) && !(l.type === "group" && update.blend === "pass-through")) {
4668
+ if (update.blend !== void 0 && !_chunk2VX55NFMcjs.isBlendMode.call(void 0, update.blend) && !(l.type === "group" && update.blend === "pass-through")) {
4642
4669
  throw new PaintEditorError(`Unknown blend mode "${update.blend}". Call get_canvas_info for the blend modes.`);
4643
4670
  }
4644
4671
  if (update.name !== void 0 && !update.name.trim()) throw new PaintEditorError("name is empty; give the layer a name.");
@@ -4652,7 +4679,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
4652
4679
  const locks = { ..._nullishCoalesce(l.locks, () => ( {})), ...update.locks };
4653
4680
  next.locks = Object.values(locks).some(Boolean) ? locks : void 0;
4654
4681
  }
4655
- this.commit("Layer properties", { ...this.doc, layers: _chunkHB4ICNNAcjs.mapLayer.call(void 0, this.doc.layers, id, () => next) });
4682
+ this.commit("Layer properties", { ...this.doc, layers: _chunkDPYAO5U6cjs.mapLayer.call(void 0, this.doc.layers, id, () => next) });
4656
4683
  return this.describeLayer(next);
4657
4684
  }
4658
4685
  // --- Layer effects (layer styles) ---------------------------------------------
@@ -4667,17 +4694,17 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
4667
4694
  * layer's pixels when it is composited, so it follows later painting. One undo step.
4668
4695
  */
4669
4696
  addLayerEffect(id, kind, settings = {}, index) {
4670
- if (!_chunkHB4ICNNAcjs.isLayerEffectKind.call(void 0, kind)) throw new PaintEditorError(`Unknown effect kind "${String(kind)}". Kinds: ${_chunkHB4ICNNAcjs.LAYER_EFFECT_KINDS.join(", ")}.`);
4697
+ if (!_chunkDPYAO5U6cjs.isLayerEffectKind.call(void 0, kind)) throw new PaintEditorError(`Unknown effect kind "${String(kind)}". Kinds: ${_chunkDPYAO5U6cjs.LAYER_EFFECT_KINDS.join(", ")}.`);
4671
4698
  const current = _nullishCoalesce(this.effectsLayer(id, "add effects").effects, () => ( { enabled: true, items: [] }));
4672
4699
  const ids = new Set(current.items.map((e) => e.id));
4673
- let effectId = _chunkHB4ICNNAcjs.newEffectId.call(void 0, );
4674
- while (ids.has(effectId)) effectId = _chunkHB4ICNNAcjs.newEffectId.call(void 0, );
4700
+ let effectId = _chunkDPYAO5U6cjs.newEffectId.call(void 0, );
4701
+ while (ids.has(effectId)) effectId = _chunkDPYAO5U6cjs.newEffectId.call(void 0, );
4675
4702
  const { id: _id, kind: _kind, ...rest } = settings;
4676
- const effect = effectGuard(() => _chunkHB4ICNNAcjs.mergeLayerEffect.call(void 0, _chunkHB4ICNNAcjs.defaultLayerEffect.call(void 0, kind, effectId), rest));
4703
+ const effect = effectGuard(() => _chunkDPYAO5U6cjs.mergeLayerEffect.call(void 0, _chunkDPYAO5U6cjs.defaultLayerEffect.call(void 0, kind, effectId), rest));
4677
4704
  const items = [...current.items];
4678
4705
  const at = index === void 0 ? items.length : Math.max(0, Math.min(items.length, Math.floor(index)));
4679
4706
  items.splice(at, 0, effect);
4680
- this.writeLayerEffects(id, { ...current, items }, `Add ${_chunkHB4ICNNAcjs.layerEffectLabel.call(void 0, kind)}`, true);
4707
+ this.writeLayerEffects(id, { ...current, items }, `Add ${_chunkDPYAO5U6cjs.layerEffectLabel.call(void 0, kind)}`, true);
4681
4708
  return { effect, effects: this.getLayerEffects(id) };
4682
4709
  }
4683
4710
  /**
@@ -4689,15 +4716,15 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
4689
4716
  const current = this.effectsLayer(id, "change its effects").effects;
4690
4717
  const i = this.requireEffect(id, effectId);
4691
4718
  const items = [...current.items];
4692
- items[i] = effectGuard(() => _chunkHB4ICNNAcjs.mergeLayerEffect.call(void 0, items[i], changes));
4693
- this.writeLayerEffects(id, { ...current, items }, `Change ${_chunkHB4ICNNAcjs.layerEffectLabel.call(void 0, items[i].kind)}`, commitToHistory);
4719
+ items[i] = effectGuard(() => _chunkDPYAO5U6cjs.mergeLayerEffect.call(void 0, items[i], changes));
4720
+ this.writeLayerEffects(id, { ...current, items }, `Change ${_chunkDPYAO5U6cjs.layerEffectLabel.call(void 0, items[i].kind)}`, commitToHistory);
4694
4721
  return this.getLayerEffects(id);
4695
4722
  }
4696
4723
  /** Removes one effect (one undo step). Returns the layer's remaining effects. */
4697
4724
  removeLayerEffect(id, effectId) {
4698
4725
  const current = this.effectsLayer(id, "change its effects").effects;
4699
4726
  const i = this.requireEffect(id, effectId);
4700
- this.writeLayerEffects(id, { ...current, items: current.items.filter((e) => e.id !== effectId) }, `Remove ${_chunkHB4ICNNAcjs.layerEffectLabel.call(void 0, current.items[i].kind)}`, true);
4727
+ this.writeLayerEffects(id, { ...current, items: current.items.filter((e) => e.id !== effectId) }, `Remove ${_chunkDPYAO5U6cjs.layerEffectLabel.call(void 0, current.items[i].kind)}`, true);
4701
4728
  return this.getLayerEffects(id);
4702
4729
  }
4703
4730
  /** Turns all of a layer's effects on or off and, when given, sets Scale Effects (0.01..10). One undo step. */
@@ -4715,7 +4742,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
4715
4742
  /** Replaces a layer's effects, validated (`null` removes them). One undo step. Returns the effects. */
4716
4743
  setLayerEffects(id, effects, commitToHistory = true) {
4717
4744
  this.effectsLayer(id, "change its effects");
4718
- if (effects) effectGuard(() => _chunkHB4ICNNAcjs.validateLayerEffects.call(void 0, effects));
4745
+ if (effects) effectGuard(() => _chunkDPYAO5U6cjs.validateLayerEffects.call(void 0, effects));
4719
4746
  this.writeLayerEffects(id, effects, "Layer effects", commitToHistory);
4720
4747
  return this.getLayerEffects(id);
4721
4748
  }
@@ -4726,12 +4753,12 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
4726
4753
  effectsLayer(id, action) {
4727
4754
  this.requireIdle("changing layer effects");
4728
4755
  const l = this.requireLayer(id);
4729
- if (_chunkHB4ICNNAcjs.isLayerLocked.call(void 0, l, "all")) throw new PaintEditorError(`Layer "${l.name}" is fully locked, so it can't ${action}; unlock it first (locks {all: false}).`);
4756
+ if (_chunkDPYAO5U6cjs.isLayerLocked.call(void 0, l, "all")) throw new PaintEditorError(`Layer "${l.name}" is fully locked, so it can't ${action}; unlock it first (locks {all: false}).`);
4730
4757
  return l;
4731
4758
  }
4732
4759
  requireEffect(id, effectId) {
4733
4760
  const l = this.requireLayer(id);
4734
- const items = _nullishCoalesce(_optionalChain([l, 'access', _258 => _258.effects, 'optionalAccess', _259 => _259.items]), () => ( []));
4761
+ const items = _nullishCoalesce(_optionalChain([l, 'access', _261 => _261.effects, 'optionalAccess', _262 => _262.items]), () => ( []));
4735
4762
  const i = items.findIndex((e) => e.id === effectId);
4736
4763
  if (i === -1) throw new PaintEditorError(`Layer "${l.name}" has no effect "${effectId}". Effects: ${items.map((e) => `${e.id} (${e.kind})`).join(", ") || "none"}; call list_layer_effects.`);
4737
4764
  return i;
@@ -4741,30 +4768,30 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
4741
4768
  const next = { ...this.requireLayer(id) };
4742
4769
  if (effects && (effects.items.length || effects.psd || effects.scale !== void 0 || !effects.enabled)) next.effects = effects;
4743
4770
  else delete next.effects;
4744
- this.commitOrAmend(label, { ...this.doc, layers: _chunkHB4ICNNAcjs.mapLayer.call(void 0, this.doc.layers, id, () => next) }, commitToHistory);
4771
+ this.commitOrAmend(label, { ...this.doc, layers: _chunkDPYAO5U6cjs.mapLayer.call(void 0, this.doc.layers, id, () => next) }, commitToHistory);
4745
4772
  }
4746
4773
  removeLayer(id) {
4747
4774
  this.requireIdle("removing a layer");
4748
4775
  const l = this.requireLayer(id);
4749
- if (_chunkHB4ICNNAcjs.isLayerLocked.call(void 0, l, "all")) throw new PaintEditorError(`Layer "${l.name}" is fully locked; unlock it before removing it.`);
4750
- const wetIds = this.wet.wetLayerIds().filter((x) => x === id || l.type === "group" && _chunkHB4ICNNAcjs.findLayer.call(void 0, l.children, x));
4776
+ if (_chunkDPYAO5U6cjs.isLayerLocked.call(void 0, l, "all")) throw new PaintEditorError(`Layer "${l.name}" is fully locked; unlock it before removing it.`);
4777
+ const wetIds = this.wet.wetLayerIds().filter((x) => x === id || l.type === "group" && _chunkDPYAO5U6cjs.findLayer.call(void 0, l.children, x));
4751
4778
  if (wetIds.length) {
4752
4779
  this.beginWetOp();
4753
4780
  for (const x of wetIds) this.wet.world.removeLane(x);
4754
4781
  }
4755
- const layers = _chunkHB4ICNNAcjs.mapLayer.call(void 0, this.doc.layers, id, () => null);
4782
+ const layers = _chunkDPYAO5U6cjs.mapLayer.call(void 0, this.doc.layers, id, () => null);
4756
4783
  let active = this.doc.activeLayerId;
4757
- if (active && !_chunkHB4ICNNAcjs.findLayer.call(void 0, layers, active)) active = _nullishCoalesce(_optionalChain([_chunkHB4ICNNAcjs.flattenLayers.call(void 0, layers), 'access', _260 => _260.filter, 'call', _261 => _261((x) => x.type === "pixel"), 'access', _262 => _262.pop, 'call', _263 => _263(), 'optionalAccess', _264 => _264.id]), () => ( null));
4758
- this.commit("Remove layer", { ...this.doc, layers, activeLayerId: active, ...this.thickWithout(_chunkHB4ICNNAcjs.flattenLayers.call(void 0, [l]).map((x) => x.id)), ...this.stickersWithout(_chunkHB4ICNNAcjs.flattenLayers.call(void 0, [l]).map((x) => x.id)), ...this.liveStrokesWithout(_chunkHB4ICNNAcjs.flattenLayers.call(void 0, [l]).map((x) => x.id)), ...this.lightWithout(_chunkHB4ICNNAcjs.flattenLayers.call(void 0, [l]).map((x) => x.id)) });
4784
+ if (active && !_chunkDPYAO5U6cjs.findLayer.call(void 0, layers, active)) active = _nullishCoalesce(_optionalChain([_chunkDPYAO5U6cjs.flattenLayers.call(void 0, layers), 'access', _263 => _263.filter, 'call', _264 => _264((x) => x.type === "pixel"), 'access', _265 => _265.pop, 'call', _266 => _266(), 'optionalAccess', _267 => _267.id]), () => ( null));
4785
+ this.commit("Remove layer", { ...this.doc, layers, activeLayerId: active, ...this.thickWithout(_chunkDPYAO5U6cjs.flattenLayers.call(void 0, [l]).map((x) => x.id)), ...this.stickersWithout(_chunkDPYAO5U6cjs.flattenLayers.call(void 0, [l]).map((x) => x.id)), ...this.liveStrokesWithout(_chunkDPYAO5U6cjs.flattenLayers.call(void 0, [l]).map((x) => x.id)), ...this.lightWithout(_chunkDPYAO5U6cjs.flattenLayers.call(void 0, [l]).map((x) => x.id)) });
4759
4786
  return { removed: id, activeLayerId: active };
4760
4787
  }
4761
4788
  duplicateLayer(id) {
4762
4789
  this.requireIdle("duplicating a layer");
4763
- if (_chunkHB4ICNNAcjs.findLayer.call(void 0, this.doc.layers, id)) {
4790
+ if (_chunkDPYAO5U6cjs.findLayer.call(void 0, this.doc.layers, id)) {
4764
4791
  const inside = (l) => l.type === "group" ? l.children.flatMap(inside) : [l.id];
4765
- this.dryLayersFirst(inside(_chunkHB4ICNNAcjs.findLayer.call(void 0, this.doc.layers, id).layer));
4792
+ this.dryLayersFirst(inside(_chunkDPYAO5U6cjs.findLayer.call(void 0, this.doc.layers, id).layer));
4766
4793
  }
4767
- const loc = _chunkHB4ICNNAcjs.findLayer.call(void 0, this.doc.layers, id);
4794
+ const loc = _chunkDPYAO5U6cjs.findLayer.call(void 0, this.doc.layers, id);
4768
4795
  if (!loc) throw new PaintEditorError(`Unknown layer "${id}". Call list_layers for the ids.`);
4769
4796
  const thick = { ..._nullishCoalesce(this.doc.thick, () => ( {})) };
4770
4797
  const stickers = { ..._nullishCoalesce(this.doc.stickers, () => ( {})) };
@@ -4780,43 +4807,43 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
4780
4807
  return l.type === "group" ? { ...l, id: id2, children: l.children.map(copy) } : { ...l, id: id2 };
4781
4808
  };
4782
4809
  const dup = { ...copy(loc.layer), name: `${loc.layer.name} copy` };
4783
- const layers = _chunkHB4ICNNAcjs.insertLayer.call(void 0, this.doc.layers, dup, _nullishCoalesce(_optionalChain([loc, 'access', _265 => _265.parent, 'optionalAccess', _266 => _266.id]), () => ( null)), loc.index + 1);
4810
+ const layers = _chunkDPYAO5U6cjs.insertLayer.call(void 0, this.doc.layers, dup, _nullishCoalesce(_optionalChain([loc, 'access', _268 => _268.parent, 'optionalAccess', _269 => _269.id]), () => ( null)), loc.index + 1);
4784
4811
  this.commit("Duplicate layer", this.withWetEvents({ ...this.doc, layers, activeLayerId: dup.id, ...this.doc.thick ? { thick } : {}, ...this.doc.stickers ? { stickers } : {}, ...this.doc.liveStrokes ? { liveStrokes } : {}, ...this.doc.light ? { light } : {} }));
4785
4812
  return this.describeLayer(dup);
4786
4813
  }
4787
4814
  /** Moves a layer to `index` (0 = bottom) within `parentId` (default its own parent; `null` = top level). */
4788
4815
  moveLayer(id, index, parentId) {
4789
4816
  this.requireIdle("moving a layer");
4790
- const loc = _chunkHB4ICNNAcjs.findLayer.call(void 0, this.doc.layers, id);
4817
+ const loc = _chunkDPYAO5U6cjs.findLayer.call(void 0, this.doc.layers, id);
4791
4818
  if (!loc) throw new PaintEditorError(`Unknown layer "${id}". Call list_layers for the ids.`);
4792
- const target = parentId === void 0 ? _nullishCoalesce(_optionalChain([loc, 'access', _267 => _267.parent, 'optionalAccess', _268 => _268.id]), () => ( null)) : parentId;
4819
+ const target = parentId === void 0 ? _nullishCoalesce(_optionalChain([loc, 'access', _270 => _270.parent, 'optionalAccess', _271 => _271.id]), () => ( null)) : parentId;
4793
4820
  if (target) {
4794
4821
  const g = this.requireLayer(target);
4795
4822
  if (g.type !== "group") throw new PaintEditorError(`Layer "${g.name}" is not a group; pass a group id as parentId.`);
4796
- if (target === id || loc.layer.type === "group" && _chunkHB4ICNNAcjs.findLayer.call(void 0, loc.layer.children, target)) throw new PaintEditorError("A group cannot move into itself.");
4823
+ if (target === id || loc.layer.type === "group" && _chunkDPYAO5U6cjs.findLayer.call(void 0, loc.layer.children, target)) throw new PaintEditorError("A group cannot move into itself.");
4797
4824
  }
4798
- const without = _chunkHB4ICNNAcjs.mapLayer.call(void 0, this.doc.layers, id, () => null);
4799
- const siblings = target ? _chunkHB4ICNNAcjs.findLayer.call(void 0, without, target).layer.children : without;
4825
+ const without = _chunkDPYAO5U6cjs.mapLayer.call(void 0, this.doc.layers, id, () => null);
4826
+ const siblings = target ? _chunkDPYAO5U6cjs.findLayer.call(void 0, without, target).layer.children : without;
4800
4827
  if (!Number.isInteger(index) || index < 0 || index > siblings.length) throw new PaintEditorError(`index ${index} is out of range; use 0..${siblings.length} (0 is the bottom).`);
4801
- const layers = _chunkHB4ICNNAcjs.insertLayer.call(void 0, without, loc.layer, target, index);
4828
+ const layers = _chunkDPYAO5U6cjs.insertLayer.call(void 0, without, loc.layer, target, index);
4802
4829
  this.commit("Move layer", { ...this.doc, layers });
4803
4830
  return this.describeLayer(loc.layer);
4804
4831
  }
4805
4832
  /** Merges a pixel layer into the pixel layer below it (keeping the lower one's settings). */
4806
4833
  mergeDown(id) {
4807
4834
  this.requireIdle("merging");
4808
- const pre = _chunkHB4ICNNAcjs.findLayer.call(void 0, this.doc.layers, id);
4835
+ const pre = _chunkDPYAO5U6cjs.findLayer.call(void 0, this.doc.layers, id);
4809
4836
  if (pre) {
4810
4837
  const sib = pre.parent ? pre.parent.children : this.doc.layers;
4811
- this.dryLayersFirst([id, _optionalChain([sib, 'access', _269 => _269[pre.index - 1], 'optionalAccess', _270 => _270.id])].filter((x) => Boolean(x)));
4838
+ this.dryLayersFirst([id, _optionalChain([sib, 'access', _272 => _272[pre.index - 1], 'optionalAccess', _273 => _273.id])].filter((x) => Boolean(x)));
4812
4839
  }
4813
- const loc = _chunkHB4ICNNAcjs.findLayer.call(void 0, this.doc.layers, id);
4840
+ const loc = _chunkDPYAO5U6cjs.findLayer.call(void 0, this.doc.layers, id);
4814
4841
  if (!loc) throw new PaintEditorError(`Unknown layer "${id}". Call list_layers for the ids.`);
4815
4842
  const siblings = loc.parent ? loc.parent.children : this.doc.layers;
4816
4843
  const below = siblings[loc.index - 1];
4817
4844
  const upper = loc.layer;
4818
4845
  if (!isPixelLayer(upper) || !isPixelLayer(below)) throw new PaintEditorError("Merge down needs a pixel layer directly above another pixel layer in the same group.");
4819
- if (_chunkHB4ICNNAcjs.isLayerLocked.call(void 0, below, "pixels")) throw new PaintEditorError(`Layer "${below.name}" has its pixels locked; unlock it to merge into it.`);
4846
+ if (_chunkDPYAO5U6cjs.isLayerLocked.call(void 0, below, "pixels")) throw new PaintEditorError(`Layer "${below.name}" has its pixels locked; unlock it to merge into it.`);
4820
4847
  const rect = unionRect(this.describeLayer(below).bounds, this.describeLayer(upper).bounds);
4821
4848
  let surface = _chunk474IQG74cjs.emptySurface.call(void 0, 4);
4822
4849
  if (rect) {
@@ -4826,9 +4853,9 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
4826
4853
  surface = _chunk474IQG74cjs.surfaceFromPixels.call(void 0, { width: rect.width, height: rect.height, data: px }, 4, rect.x, rect.y);
4827
4854
  }
4828
4855
  const merged = { ...below, surface, offset: { x: 0, y: 0 } };
4829
- const layers = _chunkHB4ICNNAcjs.mapLayer.call(void 0, _chunkHB4ICNNAcjs.mapLayer.call(void 0, this.doc.layers, upper.id, () => null), below.id, () => merged);
4856
+ const layers = _chunkDPYAO5U6cjs.mapLayer.call(void 0, _chunkDPYAO5U6cjs.mapLayer.call(void 0, this.doc.layers, upper.id, () => null), below.id, () => merged);
4830
4857
  const toDoc = (t, l) => t ? _chunk474IQG74cjs.translateSurface.call(void 0, t, l.offset.x, l.offset.y) : void 0;
4831
- const mergedLight = _optionalChain([this, 'access', _271 => _271.doc, 'access', _272 => _272.light, 'optionalAccess', _273 => _273[upper.id]]) || _optionalChain([this, 'access', _274 => _274.doc, 'access', _275 => _275.light, 'optionalAccess', _276 => _276[below.id]]) ? mergeLight(toDoc(_optionalChain([this, 'access', _277 => _277.doc, 'access', _278 => _278.light, 'optionalAccess', _279 => _279[below.id]]), below), upper.visible ? toDoc(_optionalChain([this, 'access', _280 => _280.doc, 'access', _281 => _281.light, 'optionalAccess', _282 => _282[upper.id]]), upper) : void 0, _chunk474IQG74cjs.translateSurface.call(void 0, upper.surface, upper.offset.x, upper.offset.y)) : void 0;
4858
+ const mergedLight = _optionalChain([this, 'access', _274 => _274.doc, 'access', _275 => _275.light, 'optionalAccess', _276 => _276[upper.id]]) || _optionalChain([this, 'access', _277 => _277.doc, 'access', _278 => _278.light, 'optionalAccess', _279 => _279[below.id]]) ? mergeLight(toDoc(_optionalChain([this, 'access', _280 => _280.doc, 'access', _281 => _281.light, 'optionalAccess', _282 => _282[below.id]]), below), upper.visible ? toDoc(_optionalChain([this, 'access', _283 => _283.doc, 'access', _284 => _284.light, 'optionalAccess', _285 => _285[upper.id]]), upper) : void 0, _chunk474IQG74cjs.translateSurface.call(void 0, upper.surface, upper.offset.x, upper.offset.y)) : void 0;
4832
4859
  const lightAfter = _nullishCoalesce(this.lightWithout([upper.id, below.id]).light, () => ( (this.doc.light ? { ...this.doc.light } : void 0)));
4833
4860
  const light = mergedLight ? { ..._nullishCoalesce(lightAfter, () => ( {})), [below.id]: mergedLight } : lightAfter;
4834
4861
  this.commit("Merge down", this.withWetEvents({ ...this.doc, layers, activeLayerId: below.id, ...this.thickWithout([upper.id]), ...this.stickersWithout([upper.id, below.id]), ...this.liveStrokesWithout([upper.id, below.id]), ...light ? { light } : {} }));
@@ -4843,7 +4870,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
4843
4870
  this.wet.world.removeLane(l.id);
4844
4871
  }
4845
4872
  const bounds = this.describeLayer(l).bounds;
4846
- this.commit("Clear layer", this.withPaintEvent({ ...this.doc, layers: _chunkHB4ICNNAcjs.mapLayer.call(void 0, this.doc.layers, l.id, () => ({ ...l, surface: _chunk474IQG74cjs.emptySurface.call(void 0, 4) })), ...this.thickWithout([l.id]), ...this.stickersWithout([l.id]), ..._optionalChain([this, 'access', _283 => _283.doc, 'access', _284 => _284.liveStrokes, 'optionalAccess', _285 => _285[l.id]]) ? { liveStrokes: { ...this.doc.liveStrokes, [l.id]: [] } } : {}, ...this.lightWithout([l.id]) }, { kind: "clear", layerId: l.id }));
4873
+ this.commit("Clear layer", this.withPaintEvent({ ...this.doc, layers: _chunkDPYAO5U6cjs.mapLayer.call(void 0, this.doc.layers, l.id, () => ({ ...l, surface: _chunk474IQG74cjs.emptySurface.call(void 0, 4) })), ...this.thickWithout([l.id]), ...this.stickersWithout([l.id]), ..._optionalChain([this, 'access', _286 => _286.doc, 'access', _287 => _287.liveStrokes, 'optionalAccess', _288 => _288[l.id]]) ? { liveStrokes: { ...this.doc.liveStrokes, [l.id]: [] } } : {}, ...this.lightWithout([l.id]) }, { kind: "clear", layerId: l.id }));
4847
4874
  return { layerId: l.id, bounds };
4848
4875
  }
4849
4876
  /**
@@ -4853,8 +4880,8 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
4853
4880
  fillLayer(options = {}) {
4854
4881
  this.requireIdle("filling");
4855
4882
  const fillTarget = this.paintTarget(options.layerId, "fill");
4856
- if (_optionalChain([this, 'access', _286 => _286.doc, 'access', _287 => _287.stickers, 'optionalAccess', _288 => _288[fillTarget.id], 'optionalAccess', _289 => _289.length])) throw new PaintEditorError(`Layer "${fillTarget.name}" is a sticker layer; fill another layer (add_layer).`);
4857
- if (_optionalChain([this, 'access', _290 => _290.doc, 'access', _291 => _291.liveStrokes, 'optionalAccess', _292 => _292[fillTarget.id]])) throw new PaintEditorError(`Layer "${fillTarget.name}" is a stroke layer (its pixels are drawn from its strokes); fill another layer (add_layer), or rasterize it first (rasterize_stroke_layer).`);
4883
+ if (_optionalChain([this, 'access', _289 => _289.doc, 'access', _290 => _290.stickers, 'optionalAccess', _291 => _291[fillTarget.id], 'optionalAccess', _292 => _292.length])) throw new PaintEditorError(`Layer "${fillTarget.name}" is a sticker layer; fill another layer (add_layer).`);
4884
+ if (_optionalChain([this, 'access', _293 => _293.doc, 'access', _294 => _294.liveStrokes, 'optionalAccess', _295 => _295[fillTarget.id]])) throw new PaintEditorError(`Layer "${fillTarget.name}" is a stroke layer (its pixels are drawn from its strokes); fill another layer (add_layer), or rasterize it first (rasterize_stroke_layer).`);
4858
4885
  this.dryLayersFirst([_nullishCoalesce(_nullishCoalesce(options.layerId, () => ( this.doc.activeLayerId)), () => ( ""))]);
4859
4886
  const l = this.paintTarget(options.layerId, "fill");
4860
4887
  const color = options.color === void 0 ? this.color : parseColor(options.color);
@@ -4864,16 +4891,16 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
4864
4891
  if (!(grainAmount >= 0 && grainAmount <= 1)) throw new PaintEditorError(`grain ${grainAmount} is out of range; use 0..1.`);
4865
4892
  const pressure = _nullishCoalesce(options.pressure, () => ( 0.5));
4866
4893
  const blend = _nullishCoalesce(options.blend, () => ( "normal"));
4867
- if (!_chunkOLNIPTB3cjs.isBlendMode.call(void 0, blend)) throw new PaintEditorError(`Unknown blend mode "${blend}".`);
4894
+ if (!_chunk2VX55NFMcjs.isBlendMode.call(void 0, blend)) throw new PaintEditorError(`Unknown blend mode "${blend}".`);
4868
4895
  const { width, height } = this.doc.canvas;
4869
4896
  const rect = { x: 0, y: 0, width, height };
4870
- const coverage = new (0, _chunkPQ3H2AANcjs.CoverageMap)();
4897
+ const coverage = new (0, _chunkI7NJPHWVcjs.CoverageMap)();
4871
4898
  const depth = grainAmount * this.doc.paper.depth;
4872
4899
  const grain = depth > 0 ? paperGrain(this.doc.paper) : null;
4873
4900
  for (const { tx, ty } of _chunk474IQG74cjs.tilesInRect.call(void 0, rect)) {
4874
4901
  const r = { x: tx * _chunk474IQG74cjs.TILE, y: ty * _chunk474IQG74cjs.TILE, width: Math.min(_chunk474IQG74cjs.TILE, width - tx * _chunk474IQG74cjs.TILE), height: Math.min(_chunk474IQG74cjs.TILE, height - ty * _chunk474IQG74cjs.TILE) };
4875
4902
  const vals = new Float32Array(r.width * r.height);
4876
- for (let y = 0, k = 0; y < r.height; y++) for (let x = 0; x < r.width; x++, k++) vals[k] = grain ? _chunkPQ3H2AANcjs.grainCatch.call(void 0, grain.at(r.x + x + 0.5, r.y + y + 0.5), depth, pressure) : 1;
4903
+ for (let y = 0, k = 0; y < r.height; y++) for (let x = 0; x < r.width; x++, k++) vals[k] = grain ? _chunkI7NJPHWVcjs.grainCatch.call(void 0, grain.at(r.x + x + 0.5, r.y + y + 0.5), depth, pressure) : 1;
4877
4904
  coverage.accumulate(r, vals, 1);
4878
4905
  }
4879
4906
  const apply = {
@@ -4882,14 +4909,14 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
4882
4909
  background: rgbaOf(this.doc.paper.color),
4883
4910
  opacity,
4884
4911
  blend,
4885
- lockTransparency: _chunkHB4ICNNAcjs.isLayerLocked.call(void 0, l, "transparency"),
4912
+ lockTransparency: _chunkDPYAO5U6cjs.isLayerLocked.call(void 0, l, "transparency"),
4886
4913
  selection: null,
4887
4914
  offset: l.offset
4888
4915
  };
4889
4916
  const surface = this.applyCoverage(l, coverage, rect, apply);
4890
- const lit = _optionalChain([this, 'access', _293 => _293.doc, 'access', _294 => _294.light, 'optionalAccess', _295 => _295[l.id]]);
4917
+ const lit = _optionalChain([this, 'access', _296 => _296.doc, 'access', _297 => _297.light, 'optionalAccess', _298 => _298[l.id]]);
4891
4918
  const light = lit ? withLayerLight(this.doc.light, l.id, scaleLight(lit, 1 - opacity)) : void 0;
4892
- this.commit("Fill layer", this.withPaintEvent(this.withWetEvents({ ...this.doc, layers: _chunkHB4ICNNAcjs.mapLayer.call(void 0, this.doc.layers, l.id, () => ({ ...l, surface })), ...light ? { light } : {} }), { kind: "fill", layerId: l.id, data: { color, opacity, grain: grainAmount, pressure, blend } }));
4919
+ this.commit("Fill layer", this.withPaintEvent(this.withWetEvents({ ...this.doc, layers: _chunkDPYAO5U6cjs.mapLayer.call(void 0, this.doc.layers, l.id, () => ({ ...l, surface })), ...light ? { light } : {} }), { kind: "fill", layerId: l.id, data: { color, opacity, grain: grainAmount, pressure, blend } }));
4893
4920
  return { layerId: l.id, bounds: rect };
4894
4921
  }
4895
4922
  applyCoverage(l, coverage, rect, apply) {
@@ -4897,8 +4924,8 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
4897
4924
  const tiles = new Map(base.tiles);
4898
4925
  for (const { tx, ty } of _chunk474IQG74cjs.tilesInRect.call(void 0, { x: rect.x - l.offset.x, y: rect.y - l.offset.y, width: rect.width, height: rect.height })) {
4899
4926
  const key = _chunk474IQG74cjs.tileKey.call(void 0, tx, ty);
4900
- const src = _nullishCoalesce(_optionalChain([base, 'access', _296 => _296.tiles, 'access', _297 => _297.get, 'call', _298 => _298(key), 'optionalAccess', _299 => _299.data]), () => ( new Uint8ClampedArray(_chunk474IQG74cjs.TILE * _chunk474IQG74cjs.TILE * 4)));
4901
- const tile = _chunk474IQG74cjs.finishTile.call(void 0, _chunkPQ3H2AANcjs.applyStrokeToTile.call(void 0, coverage, src, 4, tx, ty, apply), 4, 0);
4927
+ const src = _nullishCoalesce(_optionalChain([base, 'access', _299 => _299.tiles, 'access', _300 => _300.get, 'call', _301 => _301(key), 'optionalAccess', _302 => _302.data]), () => ( new Uint8ClampedArray(_chunk474IQG74cjs.TILE * _chunk474IQG74cjs.TILE * 4)));
4928
+ const tile = _chunk474IQG74cjs.finishTile.call(void 0, _chunkI7NJPHWVcjs.applyStrokeToTile.call(void 0, coverage, src, 4, tx, ty, apply), 4, 0);
4902
4929
  if (tile) tiles.set(key, tile);
4903
4930
  else tiles.delete(key);
4904
4931
  }
@@ -4930,7 +4957,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
4930
4957
  }
4931
4958
  /** The effect a layer is drawn from, or `undefined` for other layers. */
4932
4959
  getEffectLayer(layerId) {
4933
- return _chunkHB4ICNNAcjs.findLayer.call(void 0, this.doc.layers, layerId) ? _optionalChain([this, 'access', _300 => _300.doc, 'access', _301 => _301.effectLayers, 'optionalAccess', _302 => _302[layerId]]) : void 0;
4960
+ return _chunkDPYAO5U6cjs.findLayer.call(void 0, this.doc.layers, layerId) ? _optionalChain([this, 'access', _303 => _303.doc, 'access', _304 => _304.effectLayers, 'optionalAccess', _305 => _305[layerId]]) : void 0;
4934
4961
  }
4935
4962
  /** The effect paper (without its pixels), or `null`. */
4936
4963
  getPaperEffect() {
@@ -4967,8 +4994,8 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
4967
4994
  /** A pixel layer that takes effect pixels: unlocked, visible, no sticker layer, no wet paint. */
4968
4995
  effectTarget(layerId, what) {
4969
4996
  const l = this.paintTarget(layerId, what);
4970
- if (_optionalChain([this, 'access', _303 => _303.doc, 'access', _304 => _304.stickers, 'optionalAccess', _305 => _305[l.id], 'optionalAccess', _306 => _306.length])) throw new PaintEditorError(`Layer "${l.name}" is a sticker layer; ${what} another layer (add_layer).`);
4971
- if (_optionalChain([this, 'access', _307 => _307.doc, 'access', _308 => _308.liveStrokes, 'optionalAccess', _309 => _309[l.id]])) throw new PaintEditorError(`Layer "${l.name}" is a stroke layer (its pixels are drawn from its strokes); ${what} another layer (add_layer), or rasterize it first (rasterize_stroke_layer).`);
4997
+ if (_optionalChain([this, 'access', _306 => _306.doc, 'access', _307 => _307.stickers, 'optionalAccess', _308 => _308[l.id], 'optionalAccess', _309 => _309.length])) throw new PaintEditorError(`Layer "${l.name}" is a sticker layer; ${what} another layer (add_layer).`);
4998
+ if (_optionalChain([this, 'access', _310 => _310.doc, 'access', _311 => _311.liveStrokes, 'optionalAccess', _312 => _312[l.id]])) throw new PaintEditorError(`Layer "${l.name}" is a stroke layer (its pixels are drawn from its strokes); ${what} another layer (add_layer), or rasterize it first (rasterize_stroke_layer).`);
4972
4999
  if (this.wet.wetLayerIds().includes(l.id)) throw new PaintEditorError(`Layer "${l.name}" holds wet paint; effects go on dried paint, so dry it first (dry_paint) and try again.`);
4973
5000
  return l;
4974
5001
  }
@@ -5007,8 +5034,8 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
5007
5034
  const was = this.doc.paperEffect;
5008
5035
  const paperEffect = {
5009
5036
  ...this.sourceOf(d, values, options.time),
5010
- opacity: _nullishCoalesce(_nullishCoalesce(options.opacity, () => ( _optionalChain([was, 'optionalAccess', _310 => _310.opacity]))), () => ( 1)),
5011
- blend: _nullishCoalesce(_nullishCoalesce(options.blend, () => ( _optionalChain([was, 'optionalAccess', _311 => _311.blend]))), () => ( "multiply")),
5037
+ opacity: _nullishCoalesce(_nullishCoalesce(options.opacity, () => ( _optionalChain([was, 'optionalAccess', _313 => _313.opacity]))), () => ( 1)),
5038
+ blend: _nullishCoalesce(_nullishCoalesce(options.blend, () => ( _optionalChain([was, 'optionalAccess', _314 => _314.blend]))), () => ( "multiply")),
5012
5039
  image: { width: pixels.width, height: pixels.height, data: new Uint8ClampedArray(pixels.data) },
5013
5040
  version: nextPaperEffectVersion()
5014
5041
  };
@@ -5052,17 +5079,17 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
5052
5079
  this.requireIdle("adding a layer");
5053
5080
  this.checkOpacity(options.opacity);
5054
5081
  this.checkTime(options.time);
5055
- if (options.blend !== void 0 && !_chunkOLNIPTB3cjs.isBlendMode.call(void 0, options.blend)) throw new PaintEditorError(`Unknown blend mode "${options.blend}". Call get_canvas_info for the blend modes.`);
5082
+ if (options.blend !== void 0 && !_chunk2VX55NFMcjs.isBlendMode.call(void 0, options.blend)) throw new PaintEditorError(`Unknown blend mode "${options.blend}". Call get_canvas_info for the blend modes.`);
5056
5083
  if (options.aboveId !== void 0) this.requireLayer(options.aboveId);
5057
5084
  const d = await this.describeEffect(effect, "layer");
5058
5085
  const values = this.effectValues(d, { ...d.defaults }, options.values);
5059
5086
  const pixels = await this.renderEffectCanvas(d, values, options.time);
5060
5087
  this.requireIdle("adding a layer");
5061
5088
  const above = _nullishCoalesce(options.aboveId, () => ( this.doc.activeLayerId));
5062
- const loc = above ? _chunkHB4ICNNAcjs.findLayer.call(void 0, this.doc.layers, above) : null;
5089
+ const loc = above ? _chunkDPYAO5U6cjs.findLayer.call(void 0, this.doc.layers, above) : null;
5063
5090
  if (options.aboveId !== void 0 && !loc) throw new PaintEditorError(`Layer "${options.aboveId}" was removed while the effect rendered.`);
5064
- const layer = { ...createPaintLayer(_optionalChain([options, 'access', _312 => _312.name, 'optionalAccess', _313 => _313.trim, 'call', _314 => _314()]) || d.name), surface: _chunk474IQG74cjs.surfaceFromPixels.call(void 0, pixels, 4), opacity: _nullishCoalesce(options.opacity, () => ( 1)), blend: _nullishCoalesce(options.blend, () => ( "normal")) };
5065
- const layers = _chunkHB4ICNNAcjs.insertLayer.call(void 0, this.doc.layers, layer, _nullishCoalesce(_optionalChain([loc, 'optionalAccess', _315 => _315.parent, 'optionalAccess', _316 => _316.id]), () => ( null)), loc ? loc.index + 1 : void 0);
5091
+ const layer = { ...createPaintLayer(_optionalChain([options, 'access', _315 => _315.name, 'optionalAccess', _316 => _316.trim, 'call', _317 => _317()]) || d.name), surface: _chunk474IQG74cjs.surfaceFromPixels.call(void 0, pixels, 4), opacity: _nullishCoalesce(options.opacity, () => ( 1)), blend: _nullishCoalesce(options.blend, () => ( "normal")) };
5092
+ const layers = _chunkDPYAO5U6cjs.insertLayer.call(void 0, this.doc.layers, layer, _nullishCoalesce(_optionalChain([loc, 'optionalAccess', _318 => _318.parent, 'optionalAccess', _319 => _319.id]), () => ( null)), loc ? loc.index + 1 : void 0);
5066
5093
  const source = this.sourceOf(d, values, options.time);
5067
5094
  this.commit("Add effect layer", { ...this.doc, layers, activeLayerId: layer.id, effectLayers: { ..._nullishCoalesce(this.doc.effectLayers, () => ( {})), [layer.id]: source } });
5068
5095
  return { layer: this.describeLayer(layer), source };
@@ -5086,7 +5113,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
5086
5113
  this.requireIdle("changing an effect layer");
5087
5114
  if (!isPixelLayer(now)) throw new PaintEditorError(`Layer "${l.name}" was removed while the effect rendered.`);
5088
5115
  const source = this.sourceOf(d, values, time);
5089
- this.commitOrAmend("Effect layer", { ...this.doc, layers: _chunkHB4ICNNAcjs.mapLayer.call(void 0, this.doc.layers, l.id, () => ({ ...now, surface: _chunk474IQG74cjs.surfaceFromPixels.call(void 0, pixels, 4), offset: { x: 0, y: 0 } })), effectLayers: { ..._nullishCoalesce(this.doc.effectLayers, () => ( {})), [l.id]: source } }, commitToHistory);
5116
+ this.commitOrAmend("Effect layer", { ...this.doc, layers: _chunkDPYAO5U6cjs.mapLayer.call(void 0, this.doc.layers, l.id, () => ({ ...now, surface: _chunk474IQG74cjs.surfaceFromPixels.call(void 0, pixels, 4), offset: { x: 0, y: 0 } })), effectLayers: { ..._nullishCoalesce(this.doc.effectLayers, () => ( {})), [l.id]: source } }, commitToHistory);
5090
5117
  return source;
5091
5118
  }
5092
5119
  /** Turns an effect layer into a plain pixel layer, keeping its pixels (one undo step). */
@@ -5114,9 +5141,9 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
5114
5141
  const rect = this.canvasRectOf(now);
5115
5142
  const before = _chunk474IQG74cjs.readRegion.call(void 0, now.surface, rect);
5116
5143
  let after = overPixels(before, pixels.data, _nullishCoalesce(options.opacity, () => ( 1)));
5117
- if (options.lockTransparency || _chunkHB4ICNNAcjs.isLayerLocked.call(void 0, now, "transparency")) after = mixPixels(before, after, 1);
5144
+ if (options.lockTransparency || _chunkDPYAO5U6cjs.isLayerLocked.call(void 0, now, "transparency")) after = mixPixels(before, after, 1);
5118
5145
  const surface = _chunk474IQG74cjs.writeRegion.call(void 0, now.surface, rect, after);
5119
- this.commit("Effect fill", { ...this.doc, layers: _chunkHB4ICNNAcjs.mapLayer.call(void 0, this.doc.layers, now.id, () => ({ ...now, surface })) });
5146
+ this.commit("Effect fill", { ...this.doc, layers: _chunkDPYAO5U6cjs.mapLayer.call(void 0, this.doc.layers, now.id, () => ({ ...now, surface })) });
5120
5147
  return { layerId: now.id, source: this.sourceOf(d, values, options.time) };
5121
5148
  }
5122
5149
  // --- Effect paint ----------------------------------------------------------------
@@ -5140,7 +5167,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
5140
5167
  this.checkTime(source.time);
5141
5168
  let map;
5142
5169
  try {
5143
- map = _chunk6G6ZDDDBcjs.readEffectStrokeMap.call(void 0, source.map);
5170
+ map = _chunkH4AOUUBEcjs.readEffectStrokeMap.call(void 0, source.map);
5144
5171
  } catch (e) {
5145
5172
  throw new PaintEditorError(e.message);
5146
5173
  }
@@ -5171,9 +5198,9 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
5171
5198
  }
5172
5199
  /** The rendered pixels of an effect paint at the current canvas size, or `null` when it has not been rendered. */
5173
5200
  effectPaintImage(p) {
5174
- const key = _chunk6G6ZDDDBcjs.effectPaintKey.call(void 0, p);
5201
+ const key = _chunkH4AOUUBEcjs.effectPaintKey.call(void 0, p);
5175
5202
  const img = this.effectPaintPixels.get(key);
5176
- const size = _chunk6G6ZDDDBcjs.effectPaintSize.call(void 0, p, this.doc.canvas);
5203
+ const size = _chunkH4AOUUBEcjs.effectPaintSize.call(void 0, p, this.doc.canvas);
5177
5204
  if (!img || img.width !== size.width || img.height !== size.height) return null;
5178
5205
  this.effectPaintPixels.delete(key);
5179
5206
  this.effectPaintPixels.set(key, img);
@@ -5187,7 +5214,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
5187
5214
  const what = `the effect "${p.effect}"${p.provider ? ` from provider "${p.provider}"` : ""}`;
5188
5215
  if (!provider) throw new PaintEditorError(`Effect paint needs ${what}, but no effects provider is registered; register it (setEffectsProvider) and try again.`);
5189
5216
  if (p.provider && provider.id !== p.provider) throw new PaintEditorError(`Effect paint needs ${what}, but the registered provider is "${provider.id}"; register "${p.provider}" (setEffectsProvider) and try again.`);
5190
- const { width, height } = _chunk6G6ZDDDBcjs.effectPaintSize.call(void 0, p, this.doc.canvas);
5217
+ const { width, height } = _chunkH4AOUUBEcjs.effectPaintSize.call(void 0, p, this.doc.canvas);
5191
5218
  let pixels;
5192
5219
  try {
5193
5220
  pixels = await this.effectsRenderer.render(provider, p.effect, { width, height }, { time: p.time, values: p.values });
@@ -5195,7 +5222,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
5195
5222
  throw new PaintEditorError(`Effect paint could not render ${what}: ${e instanceof Error ? e.message : String(e)}`);
5196
5223
  }
5197
5224
  const img = { width, height, data: new Uint8ClampedArray(pixels.data), ...p.map ? { map: p.map } : {} };
5198
- this.effectPaintPixels.set(_chunk6G6ZDDDBcjs.effectPaintKey.call(void 0, p), img);
5225
+ this.effectPaintPixels.set(_chunkH4AOUUBEcjs.effectPaintKey.call(void 0, p), img);
5199
5226
  while (this.effectPaintPixels.size > _PaintEditorController.EFFECT_PAINT_CACHE) this.effectPaintPixels.delete(this.effectPaintPixels.keys().next().value);
5200
5227
  return img;
5201
5228
  }
@@ -5206,7 +5233,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
5206
5233
  async prepareEffectPaints(paints) {
5207
5234
  const seen = /* @__PURE__ */ new Set();
5208
5235
  for (const p of paints) {
5209
- const key = _chunk6G6ZDDDBcjs.effectPaintKey.call(void 0, p);
5236
+ const key = _chunkH4AOUUBEcjs.effectPaintKey.call(void 0, p);
5210
5237
  if (seen.has(key)) continue;
5211
5238
  seen.add(key);
5212
5239
  await this.renderEffectPaint(p);
@@ -5215,7 +5242,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
5215
5242
  /** Renders the effect paints of recorded strokes (default all of them) before a replay. */
5216
5243
  async prepareStrokeEffects(strokeIds) {
5217
5244
  const ids = strokeIds ? new Set(strokeIds) : null;
5218
- const paints = this.doc.strokes.filter((s) => (!ids || ids.has(s.id)) && _optionalChain([s, 'access', _317 => _317.paint, 'optionalAccess', _318 => _318.type]) === "effect").map((s) => s.paint);
5245
+ const paints = this.doc.strokes.filter((s) => (!ids || ids.has(s.id)) && _optionalChain([s, 'access', _320 => _320.paint, 'optionalAccess', _321 => _321.type]) === "effect").map((s) => s.paint);
5219
5246
  await this.prepareEffectPaints(paints);
5220
5247
  }
5221
5248
  /** A small preview of the effect paint (a PNG data URL `size` px wide), or `null` without a rendered one. */
@@ -5235,7 +5262,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
5235
5262
  for (let c = 0; c < 4; c++) out[o + c] = img.data[i + c];
5236
5263
  }
5237
5264
  }
5238
- return _chunkOLNIPTB3cjs.pngDataUrl.call(void 0, w, h, out);
5265
+ return _chunkW5M3J7PVcjs.pngDataUrl.call(void 0, w, h, out);
5239
5266
  }
5240
5267
  /**
5241
5268
  * The effect paint a stroke paints with and its pixels, or `null`: the stroke's own effect
@@ -5244,11 +5271,11 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
5244
5271
  * its pixels are not rendered.
5245
5272
  */
5246
5273
  strokeEffect(init, brush) {
5247
- if (!_chunk6G6ZDDDBcjs.brushTakesPaint.call(void 0, brush)) return null;
5274
+ if (!_chunkH4AOUUBEcjs.brushTakesPaint.call(void 0, brush)) return null;
5248
5275
  let source = null;
5249
5276
  if (init.paint !== void 0) {
5250
- if (!_chunk6G6ZDDDBcjs.isPaintEffectPaint.call(void 0, init.paint)) return null;
5251
- source = _chunk6G6ZDDDBcjs.readPaintEffectPaint.call(void 0, init.paint);
5277
+ if (!_chunkH4AOUUBEcjs.isPaintEffectPaint.call(void 0, init.paint)) return null;
5278
+ source = _chunkH4AOUUBEcjs.readPaintEffectPaint.call(void 0, init.paint);
5252
5279
  if (!source) throw new PaintEditorError("The stroke's effect paint needs an effect id and values (getEffectPaint returns one).");
5253
5280
  } else if (init.color === void 0 && !brush.paint) {
5254
5281
  if (this.effectPaintPending) throw new PaintEditorError(`The effect paint "${this.effectPaintPending.effect}" is still rendering; wait for set_effect_paint to finish, then paint.`);
@@ -5278,14 +5305,14 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
5278
5305
  const before = _chunk474IQG74cjs.readRegion.call(void 0, l.surface, rect);
5279
5306
  const inputs = { source: { width: rect.width, height: rect.height, data: before } };
5280
5307
  const heightInput = d.inputs.find((i) => i.kind === "image" && /^(height|depth|relief)$/i.test(i.name));
5281
- const relief = _optionalChain([this, 'access', _319 => _319.doc, 'access', _320 => _320.thick, 'optionalAccess', _321 => _321[l.id]]);
5308
+ const relief = _optionalChain([this, 'access', _322 => _322.doc, 'access', _323 => _323.thick, 'optionalAccess', _324 => _324[l.id]]);
5282
5309
  if (heightInput && relief) {
5283
5310
  const h = _chunk474IQG74cjs.readRegion.call(void 0, relief.height, rect);
5284
5311
  const rgba = new Uint8ClampedArray(rect.width * rect.height * 4);
5285
5312
  for (let i = 0; i < h.length; i++) rgba.set([h[i], h[i], h[i], 255], i * 4);
5286
5313
  inputs[heightInput.name] = { width: rect.width, height: rect.height, data: rgba };
5287
5314
  }
5288
- const sourceInput = _nullishCoalesce(_optionalChain([d, 'access', _322 => _322.inputs, 'access', _323 => _323.find, 'call', _324 => _324((i) => i.kind === "image" && i.name !== _optionalChain([heightInput, 'optionalAccess', _325 => _325.name])), 'optionalAccess', _326 => _326.name]), () => ( "source"));
5315
+ const sourceInput = _nullishCoalesce(_optionalChain([d, 'access', _325 => _325.inputs, 'access', _326 => _326.find, 'call', _327 => _327((i) => i.kind === "image" && i.name !== _optionalChain([heightInput, 'optionalAccess', _328 => _328.name])), 'optionalAccess', _329 => _329.name]), () => ( "source"));
5289
5316
  if (sourceInput !== "source") {
5290
5317
  inputs[sourceInput] = inputs.source;
5291
5318
  delete inputs.source;
@@ -5293,17 +5320,17 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
5293
5320
  const out = await this.effectsRenderer.render(this.effects.require(), d.id, { width: rect.width, height: rect.height }, { time: _nullishCoalesce(options.time, () => ( 0)), values, inputs });
5294
5321
  const now = this.sameLayerAfterRender(l);
5295
5322
  const surface = _chunk474IQG74cjs.writeRegion.call(void 0, now.surface, rect, mixPixels(before, out.data, amount));
5296
- this.commit("Light effect", { ...this.doc, layers: _chunkHB4ICNNAcjs.mapLayer.call(void 0, this.doc.layers, now.id, () => ({ ...now, surface })) });
5323
+ this.commit("Light effect", { ...this.doc, layers: _chunkDPYAO5U6cjs.mapLayer.call(void 0, this.doc.layers, now.id, () => ({ ...now, surface })) });
5297
5324
  return { layerId: now.id, source: this.sourceOf(d, values, options.time), amount };
5298
5325
  }
5299
5326
  // --- Brushes -------------------------------------------------------------------
5300
5327
  findBrush(id) {
5301
- return _nullishCoalesce(_chunk6G6ZDDDBcjs.BUILTIN_BRUSHES.find((b) => b.id === id), () => ( this.userBrushes.find((b) => b.id === id)));
5328
+ return _nullishCoalesce(_chunkH4AOUUBEcjs.BUILTIN_BRUSHES.find((b) => b.id === id), () => ( this.userBrushes.find((b) => b.id === id)));
5302
5329
  }
5303
5330
  /** A library brush by id (`undefined` when unknown). */
5304
5331
  getBrush(id) {
5305
5332
  const b = this.findBrush(id);
5306
- return b ? _chunk6G6ZDDDBcjs.normalizePaintBrush.call(void 0, b, b) : void 0;
5333
+ return b ? _chunkH4AOUUBEcjs.normalizePaintBrush.call(void 0, b, b) : void 0;
5307
5334
  }
5308
5335
  requireBrush(id) {
5309
5336
  const b = this.findBrush(id);
@@ -5318,19 +5345,20 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
5318
5345
  const { id, ...changes } = update;
5319
5346
  const base = id !== void 0 ? this.requireBrush(id) : this.brush;
5320
5347
  if (changes.paint !== void 0 && changes.paint !== null) this.readStrokePaint(changes.paint);
5321
- const next = _chunk6G6ZDDDBcjs.normalizePaintBrush.call(void 0, { ...changes, id: base.id }, base);
5348
+ const next = _chunkH4AOUUBEcjs.normalizePaintBrush.call(void 0, { ...changes, id: base.id }, base);
5322
5349
  if (base.builtin && !Object.keys(changes).length) next.builtin = true;
5323
5350
  else delete next.builtin;
5324
5351
  this.brush = next;
5325
5352
  this.emit([]);
5353
+ if (next.engine === "sticker" && next.sticker.stamps.some((r) => !_chunkZEYMKDYScjs.editorStampOf.call(void 0, r))) void this.prepareStickers(next.sticker.stamps).catch(() => this.emit([]));
5326
5354
  return this.brush;
5327
5355
  }
5328
5356
  /** Saves the active brush (or `brush`) into the user library under `id` / `name`. */
5329
5357
  saveBrush(options) {
5330
- if (!_chunk6G6ZDDDBcjs.BRUSH_ID.test(options.id)) throw new PaintEditorError(`Brush id "${options.id}" is invalid; use lowercase letters, digits and dashes (e.g. "my-pencil").`);
5331
- if (_chunk6G6ZDDDBcjs.BUILTIN_BRUSHES.some((b) => b.id === options.id)) throw new PaintEditorError(`"${options.id}" is a built-in brush; save under another id.`);
5332
- const source = options.brush ? _chunk6G6ZDDDBcjs.normalizePaintBrush.call(void 0, options.brush, this.brush) : this.brush;
5333
- const saved = _chunk6G6ZDDDBcjs.normalizePaintBrush.call(void 0, { ...source, id: options.id, name: _nullishCoalesce(options.name, () => ( source.name)) });
5358
+ if (!_chunkH4AOUUBEcjs.BRUSH_ID.test(options.id)) throw new PaintEditorError(`Brush id "${options.id}" is invalid; use lowercase letters, digits and dashes (e.g. "my-pencil").`);
5359
+ if (_chunkH4AOUUBEcjs.BUILTIN_BRUSHES.some((b) => b.id === options.id)) throw new PaintEditorError(`"${options.id}" is a built-in brush; save under another id.`);
5360
+ const source = options.brush ? _chunkH4AOUUBEcjs.normalizePaintBrush.call(void 0, options.brush, this.brush) : this.brush;
5361
+ const saved = _chunkH4AOUUBEcjs.normalizePaintBrush.call(void 0, { ...source, id: options.id, name: _nullishCoalesce(options.name, () => ( source.name)) });
5334
5362
  delete saved.builtin;
5335
5363
  const i = this.userBrushes.findIndex((b) => b.id === options.id);
5336
5364
  if (i >= 0) this.userBrushes[i] = saved;
@@ -5340,7 +5368,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
5340
5368
  return saved;
5341
5369
  }
5342
5370
  removeBrush(id) {
5343
- if (_chunk6G6ZDDDBcjs.BUILTIN_BRUSHES.some((b) => b.id === id)) throw new PaintEditorError(`"${id}" is a built-in brush and cannot be removed.`);
5371
+ if (_chunkH4AOUUBEcjs.BUILTIN_BRUSHES.some((b) => b.id === id)) throw new PaintEditorError(`"${id}" is a built-in brush and cannot be removed.`);
5344
5372
  const i = this.userBrushes.findIndex((b) => b.id === id);
5345
5373
  if (i < 0) throw new PaintEditorError(`Unknown brush "${id}". Call list_brushes for the ids.`);
5346
5374
  this.userBrushes.splice(i, 1);
@@ -5349,12 +5377,12 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
5349
5377
  }
5350
5378
  /** The user's saved brushes. */
5351
5379
  getUserBrushes() {
5352
- return this.userBrushes.map((b) => _chunk6G6ZDDDBcjs.normalizePaintBrush.call(void 0, b, b));
5380
+ return this.userBrushes.map((b) => _chunkH4AOUUBEcjs.normalizePaintBrush.call(void 0, b, b));
5353
5381
  }
5354
5382
  /** A brush library file of the given brushes (default: the user's brushes). */
5355
5383
  exportBrushes(ids) {
5356
5384
  const list = ids ? ids.map((id) => this.requireBrush(id)) : this.userBrushes;
5357
- return { format: "pixerate-brushes", version: 1, brushes: list.map(_chunk6G6ZDDDBcjs.brushToJSON) };
5385
+ return { format: "pixerate-brushes", version: 1, brushes: list.map(_chunkH4AOUUBEcjs.brushToJSON) };
5358
5386
  }
5359
5387
  /**
5360
5388
  * Adds the brushes of a library file to the user library. A brush whose id is taken is skipped
@@ -5364,14 +5392,14 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
5364
5392
  const problems = [];
5365
5393
  let list;
5366
5394
  try {
5367
- list = _chunk6G6ZDDDBcjs.parseBrushLibrary.call(void 0, file, problems);
5395
+ list = _chunkH4AOUUBEcjs.parseBrushLibrary.call(void 0, file, problems);
5368
5396
  } catch (e) {
5369
5397
  throw new PaintEditorError(e.message);
5370
5398
  }
5371
5399
  const added = [];
5372
5400
  const skipped = [];
5373
5401
  for (const b of list) {
5374
- if (_chunk6G6ZDDDBcjs.BUILTIN_BRUSHES.some((x) => x.id === b.id)) {
5402
+ if (_chunkH4AOUUBEcjs.BUILTIN_BRUSHES.some((x) => x.id === b.id)) {
5375
5403
  skipped.push(b.id);
5376
5404
  problems.push(`"${b.id}" is a built-in brush id; rename it to import it.`);
5377
5405
  continue;
@@ -5415,9 +5443,9 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
5415
5443
  setPaint(paint) {
5416
5444
  let p;
5417
5445
  try {
5418
- p = _chunkPQ3H2AANcjs.parsePaintSource.call(void 0, paint);
5446
+ p = _chunkI7NJPHWVcjs.parsePaintSource.call(void 0, paint);
5419
5447
  } catch (e) {
5420
- if (e instanceof _chunkPQ3H2AANcjs.PaintSourceError) throw new PaintEditorError(e.message);
5448
+ if (e instanceof _chunkI7NJPHWVcjs.PaintSourceError) throw new PaintEditorError(e.message);
5421
5449
  throw e;
5422
5450
  }
5423
5451
  if (p.type === "color") {
@@ -5436,20 +5464,20 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
5436
5464
  * brush's gradient, else the editor's gradient paint. Erasers, blenders and smudges take none.
5437
5465
  */
5438
5466
  strokeGradient(init, brush, color) {
5439
- if (!_chunk6G6ZDDDBcjs.brushTakesPaint.call(void 0, brush)) return null;
5467
+ if (!_chunkH4AOUUBEcjs.brushTakesPaint.call(void 0, brush)) return null;
5440
5468
  let g = null;
5441
5469
  if (init.paint !== void 0) {
5442
- if (_chunk6G6ZDDDBcjs.isPaintEffectPaint.call(void 0, init.paint)) return null;
5470
+ if (_chunkH4AOUUBEcjs.isPaintEffectPaint.call(void 0, init.paint)) return null;
5443
5471
  const p = this.readStrokePaint(init.paint);
5444
5472
  g = p.type === "gradient" ? p : null;
5445
5473
  } else g = _nullishCoalesce(brush.paint, () => ( (init.color === void 0 ? this.gradient : null)));
5446
- return g ? _chunkPQ3H2AANcjs.resolvePaintGradient.call(void 0, g, { paint: color, secondary: this.secondaryColor }) : null;
5474
+ return g ? _chunkI7NJPHWVcjs.resolvePaintGradient.call(void 0, g, { paint: color, secondary: this.secondaryColor }) : null;
5447
5475
  }
5448
5476
  readStrokePaint(raw) {
5449
5477
  try {
5450
- return _chunkPQ3H2AANcjs.parsePaintSource.call(void 0, raw);
5478
+ return _chunkI7NJPHWVcjs.parsePaintSource.call(void 0, raw);
5451
5479
  } catch (e) {
5452
- if (e instanceof _chunkPQ3H2AANcjs.PaintSourceError) throw new PaintEditorError(e.message);
5480
+ if (e instanceof _chunkI7NJPHWVcjs.PaintSourceError) throw new PaintEditorError(e.message);
5453
5481
  throw e;
5454
5482
  }
5455
5483
  }
@@ -5483,14 +5511,14 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
5483
5511
  // --- Mixer Brush ---------------------------------------------------------------
5484
5512
  /** Fills the Mixer Brush reservoir with a colour (default the editor colour). */
5485
5513
  loadMixerBrush(color) {
5486
- const [r, g, b] = _chunk6G6ZDDDBcjs.hexToRgb8.call(void 0, color === void 0 ? this.color : parseColor(color));
5487
- this.mixerLoad = _chunkPQ3H2AANcjs.loadMixer.call(void 0, this.mixerLoad, [r / 255, g / 255, b / 255]);
5514
+ const [r, g, b] = _chunkH4AOUUBEcjs.hexToRgb8.call(void 0, color === void 0 ? this.color : parseColor(color));
5515
+ this.mixerLoad = _chunkI7NJPHWVcjs.loadMixer.call(void 0, this.mixerLoad, [r / 255, g / 255, b / 255]);
5488
5516
  this.emit([]);
5489
5517
  return this.mixerLoad;
5490
5518
  }
5491
5519
  /** Empties the pickup well (and with `emptyReservoir` the loaded paint too). */
5492
5520
  cleanMixerBrush(emptyReservoir = false) {
5493
- this.mixerLoad = emptyReservoir ? _chunkPQ3H2AANcjs.EMPTY_MIXER_LOAD : _chunkPQ3H2AANcjs.cleanMixer.call(void 0, this.mixerLoad);
5521
+ this.mixerLoad = emptyReservoir ? _chunkI7NJPHWVcjs.EMPTY_MIXER_LOAD : _chunkI7NJPHWVcjs.cleanMixer.call(void 0, this.mixerLoad);
5494
5522
  this.emit([]);
5495
5523
  return this.mixerLoad;
5496
5524
  }
@@ -5513,7 +5541,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
5513
5541
  // --- Strokes -------------------------------------------------------------------
5514
5542
  strokeBrush(init) {
5515
5543
  let brush = init.brushId !== void 0 ? this.requireBrush(init.brushId) : this.brush;
5516
- if (init.brush) brush = _chunk6G6ZDDDBcjs.normalizePaintBrush.call(void 0, { ...init.brush, id: brush.id }, brush);
5544
+ if (init.brush) brush = _chunkH4AOUUBEcjs.normalizePaintBrush.call(void 0, { ...init.brush, id: brush.id }, brush);
5517
5545
  return brush;
5518
5546
  }
5519
5547
  /**
@@ -5529,7 +5557,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
5529
5557
  return symmetryCopies(this.guides.symmetry);
5530
5558
  }
5531
5559
  sessionFor(doc, init, host) {
5532
- if (init.paint !== void 0 && !_chunk6G6ZDDDBcjs.isPaintEffectPaint.call(void 0, init.paint)) {
5560
+ if (init.paint !== void 0 && !_chunkH4AOUUBEcjs.isPaintEffectPaint.call(void 0, init.paint)) {
5533
5561
  const p = this.readStrokePaint(init.paint);
5534
5562
  if (p.type === "color") init = { ...init, color: p.color, paint: void 0 };
5535
5563
  else init = { ...init, paint: p };
@@ -5537,11 +5565,11 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
5537
5565
  let layer = (() => {
5538
5566
  const id = _nullishCoalesce(init.layerId, () => ( doc.activeLayerId));
5539
5567
  if (!id) throw new PaintEditorError("There is no active layer to paint on; add one with add_layer.");
5540
- const loc = _chunkHB4ICNNAcjs.findLayer.call(void 0, doc.layers, id);
5568
+ const loc = _chunkDPYAO5U6cjs.findLayer.call(void 0, doc.layers, id);
5541
5569
  if (!loc) throw new PaintEditorError(`Unknown layer "${id}". Call list_layers for the ids.`);
5542
5570
  const l = loc.layer;
5543
5571
  if (!isPixelLayer(l)) throw new PaintEditorError(`Layer "${l.name}" is a group; paint on a pixel layer inside it.`);
5544
- if (_chunkHB4ICNNAcjs.isLayerLocked.call(void 0, l, "pixels")) throw new PaintEditorError(`Layer "${l.name}" has its pixels locked; unlock it (update_layer locks) to paint on it.`);
5572
+ if (_chunkDPYAO5U6cjs.isLayerLocked.call(void 0, l, "pixels")) throw new PaintEditorError(`Layer "${l.name}" has its pixels locked; unlock it (update_layer locks) to paint on it.`);
5545
5573
  if (!l.visible) throw new PaintEditorError(`Layer "${l.name}" is hidden; show it (update_layer visible true) to paint on it.`);
5546
5574
  return l;
5547
5575
  })();
@@ -5550,43 +5578,43 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
5550
5578
  if (brush.light.amount > 0) {
5551
5579
  if (brush.engine === "sticker") throw new PaintEditorError(`The ${brush.name} brush sprays stickers, which don't take light yet; paint light with a dab or particle light brush (list_brushes category light), or set light.amount to 0 (set_brush).`);
5552
5580
  }
5553
- if (_optionalChain([doc, 'access', _327 => _327.liveStrokes, 'optionalAccess', _328 => _328[layer.id]])) {
5581
+ if (_optionalChain([doc, 'access', _330 => _330.liveStrokes, 'optionalAccess', _331 => _331[layer.id]])) {
5554
5582
  const why = liveStrokeRefusal(brush);
5555
5583
  if (why) throw new PaintEditorError(`Layer "${layer.name}" is a stroke layer. ${why}`);
5556
5584
  }
5557
- if (_optionalChain([doc, 'access', _329 => _329.liveStrokes, 'optionalAccess', _330 => _330[layer.id]]) && _optionalChain([effect, 'optionalAccess', _331 => _331.source, 'access', _332 => _332.live])) {
5558
- const key = _chunk6G6ZDDDBcjs.effectPaintKey.call(void 0, effect.source);
5585
+ if (_optionalChain([doc, 'access', _332 => _332.liveStrokes, 'optionalAccess', _333 => _333[layer.id]]) && _optionalChain([effect, 'optionalAccess', _334 => _334.source, 'access', _335 => _335.live])) {
5586
+ const key = _chunkH4AOUUBEcjs.effectPaintKey.call(void 0, effect.source);
5559
5587
  const { sources } = this.liveEffects(doc);
5560
- if (!sources.some((p) => _chunk6G6ZDDDBcjs.effectPaintKey.call(void 0, p) === key) && sources.length >= MAX_LIVE_EFFECT_SOURCES) {
5588
+ if (!sources.some((p) => _chunkH4AOUUBEcjs.effectPaintKey.call(void 0, p) === key) && sources.length >= MAX_LIVE_EFFECT_SOURCES) {
5561
5589
  throw new PaintEditorError(`The painting already plays ${MAX_LIVE_EFFECT_SOURCES} live effects, the most it can; paint with one of them, or set_effect_paint with live false to bake this one.`);
5562
5590
  }
5563
5591
  }
5564
- const stickerLayer = Boolean(_optionalChain([doc, 'access', _333 => _333.stickers, 'optionalAccess', _334 => _334[layer.id], 'optionalAccess', _335 => _335.length]));
5592
+ const stickerLayer = Boolean(_optionalChain([doc, 'access', _336 => _336.stickers, 'optionalAccess', _337 => _337[layer.id], 'optionalAccess', _338 => _338.length]));
5565
5593
  if (brush.engine === "sticker") {
5566
5594
  if (!stickerLayer && _chunk474IQG74cjs.contentBounds.call(void 0, layer.surface)) throw new PaintEditorError(`Layer "${layer.name}" already has paint; spray stickers onto an empty layer (add_layer) so they stay editable.`);
5567
5595
  } else if (stickerLayer) {
5568
5596
  throw new PaintEditorError(`Layer "${layer.name}" is a sticker layer (its pixels are drawn from its stickers); paint on another layer (add_layer).`);
5569
5597
  }
5570
5598
  let wet;
5571
- if (_chunk6G6ZDDDBcjs.isWetBrush.call(void 0, brush)) {
5599
+ if (_chunkH4AOUUBEcjs.isWetBrush.call(void 0, brush)) {
5572
5600
  this.requireWetIdle("painting");
5573
5601
  if (layer.offset.x || layer.offset.y) {
5574
5602
  const moved = { ...layer, surface: _chunk474IQG74cjs.translateSurface.call(void 0, layer.surface, layer.offset.x, layer.offset.y), offset: { x: 0, y: 0 } };
5575
- this.doc = { ...this.doc, layers: _chunkHB4ICNNAcjs.mapLayer.call(void 0, this.doc.layers, layer.id, () => moved) };
5576
- if (doc !== this.doc) doc = { ...doc, layers: _chunkHB4ICNNAcjs.mapLayer.call(void 0, doc.layers, layer.id, () => moved) };
5603
+ this.doc = { ...this.doc, layers: _chunkDPYAO5U6cjs.mapLayer.call(void 0, this.doc.layers, layer.id, () => moved) };
5604
+ if (doc !== this.doc) doc = { ...doc, layers: _chunkDPYAO5U6cjs.mapLayer.call(void 0, doc.layers, layer.id, () => moved) };
5577
5605
  layer = moved;
5578
5606
  }
5579
- if (!this.wet.wetLayerIds().includes(layer.id) && this.wet.wetLayerIds().length >= _chunkVMROIWLLcjs.MAX_WET_LANES) {
5580
- throw new PaintEditorError(`At most ${_chunkVMROIWLLcjs.MAX_WET_LANES} layers can hold wet paint at once; dry one first (dry_paint).`);
5607
+ if (!this.wet.wetLayerIds().includes(layer.id) && this.wet.wetLayerIds().length >= _chunkKBYB7OWBcjs.MAX_WET_LANES) {
5608
+ throw new PaintEditorError(`At most ${_chunkKBYB7OWBcjs.MAX_WET_LANES} layers can hold wet paint at once; dry one first (dry_paint).`);
5581
5609
  }
5582
5610
  this.beginWetOp();
5583
5611
  const world = this.wet.ensureLane(layer.id, brush.wet.medium);
5584
5612
  const id = layer.id;
5585
5613
  const wetColor = init.color === void 0 ? this.color : parseColor(init.color);
5586
- const [r, g, b] = _chunk6G6ZDDDBcjs.hexToRgb8.call(void 0, wetColor);
5614
+ const [r, g, b] = _chunkH4AOUUBEcjs.hexToRgb8.call(void 0, wetColor);
5587
5615
  const wetGradient = this.strokeGradient(init, brush, wetColor);
5588
5616
  const load = _nullishCoalesce(init.load, () => ( brushLoadForStroke(brush, this.mixerLoad, [r / 255, g / 255, b / 255])));
5589
- const seedW = _nullishCoalesce(init.seed, () => ( _chunkPQ3H2AANcjs.mix32.call(void 0, this.seedCounter * 2654435761 >>> 0) & 2147483647));
5617
+ const seedW = _nullishCoalesce(init.seed, () => ( _chunk3K6HWEXZcjs.mix32.call(void 0, this.seedCounter * 2654435761 >>> 0) & 2147483647));
5590
5618
  const copiesW = (_nullishCoalesce(init.copies, () => ( this.strokeCopies()))).filter((m) => m.some((v, i) => v !== IDENTITY_AFFINE[i]));
5591
5619
  const driver = new WetStrokeDriver({
5592
5620
  world,
@@ -5596,23 +5624,23 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
5596
5624
  load,
5597
5625
  grain: paperGrain(doc.paper),
5598
5626
  paperDepth: doc.paper.depth,
5599
- paperColor: _chunk6G6ZDDDBcjs.hexToRgb8.call(void 0, doc.paper.color),
5627
+ paperColor: _chunkH4AOUUBEcjs.hexToRgb8.call(void 0, doc.paper.color),
5600
5628
  seed: seedW,
5601
5629
  copies: [IDENTITY_AFFINE, ...copiesW].map(affineCopy),
5602
5630
  mask: init.maskStencils ? this.stencilSelection(init.maskStencils) : init.stencils !== false ? this.stencilSelection() : null,
5603
5631
  paint: effect ? null : wetGradient,
5604
- effect: _nullishCoalesce(_optionalChain([effect, 'optionalAccess', _336 => _336.pixels]), () => ( null))
5632
+ effect: _nullishCoalesce(_optionalChain([effect, 'optionalAccess', _339 => _339.pixels]), () => ( null))
5605
5633
  });
5606
5634
  init = { ...init, seed: seedW, load };
5607
5635
  wet = { driver, surface: () => world.display(id).surface };
5608
5636
  } else if (this.wet.wetLayerIds().includes(layer.id)) {
5609
5637
  this.dryLayersFirst([layer.id]);
5610
- const dried = _chunkHB4ICNNAcjs.findLayer.call(void 0, this.doc.layers, layer.id).layer;
5638
+ const dried = _chunkDPYAO5U6cjs.findLayer.call(void 0, this.doc.layers, layer.id).layer;
5611
5639
  layer = dried;
5612
5640
  }
5613
5641
  let color = init.color === void 0 ? this.color : parseColor(init.color);
5614
5642
  const tracing = this.guides.tracing;
5615
- if (init.color === void 0 && init.start && _optionalChain([tracing, 'optionalAccess', _337 => _337.visible]) && tracing.sampleColors) color = _nullishCoalesce(this.sampleTracingColor(init.start.x, init.start.y), () => ( color));
5643
+ if (init.color === void 0 && init.start && _optionalChain([tracing, 'optionalAccess', _340 => _340.visible]) && tracing.sampleColors) color = _nullishCoalesce(this.sampleTracingColor(init.start.x, init.start.y), () => ( color));
5616
5644
  const perspective = this.guides.perspective;
5617
5645
  const snapper = init.snapToPerspective && perspective.enabled && perspective.snap ? new PerspectiveSnapper(perspective) : null;
5618
5646
  const useStencils = init.stencils !== false;
@@ -5624,13 +5652,13 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
5624
5652
  const selection = brush.engine === "sticker" ? null : init.maskStencils ? this.stencilSelection(init.maskStencils) : useStencils ? this.stencilSelection() : null;
5625
5653
  const inputFilter = snapper || stencilSnapper ? (p) => stencilSnapper ? stencilSnapper.snap(snapper ? snapper.snap(p) : p) : snapper.snap(p) : void 0;
5626
5654
  const rgba = rgbaOf(color);
5627
- const seed = _nullishCoalesce(init.seed, () => ( _chunkPQ3H2AANcjs.mix32.call(void 0, this.seedCounter++ * 2654435761 >>> 0) & 2147483647));
5655
+ const seed = _nullishCoalesce(init.seed, () => ( _chunk3K6HWEXZcjs.mix32.call(void 0, this.seedCounter++ * 2654435761 >>> 0) & 2147483647));
5628
5656
  const copies = (_nullishCoalesce(init.copies, () => ( this.strokeCopies()))).filter((m) => m.some((v, i) => v !== IDENTITY_AFFINE[i]));
5629
5657
  const session = new PaintStrokeSession(host, {
5630
5658
  layerId: layer.id,
5631
5659
  surface: layer.surface,
5632
5660
  offset: layer.offset,
5633
- lockTransparency: _chunkHB4ICNNAcjs.isLayerLocked.call(void 0, layer, "transparency"),
5661
+ lockTransparency: _chunkDPYAO5U6cjs.isLayerLocked.call(void 0, layer, "transparency"),
5634
5662
  brush,
5635
5663
  color: rgba,
5636
5664
  background: rgbaOf(doc.paper.color),
@@ -5645,10 +5673,10 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
5645
5673
  mixerLoad: _nullishCoalesce(init.load, () => ( brushLoadForStroke(brush, this.mixerLoad, [rgba[0] / 255, rgba[1] / 255, rgba[2] / 255]))),
5646
5674
  secondary: rgbaOf(this.secondaryColor),
5647
5675
  wet,
5648
- thick: brush.engine === "impasto" ? { channels: _nullishCoalesce(_optionalChain([doc, 'access', _338 => _338.thick, 'optionalAccess', _339 => _339[layer.id]]), () => ( emptyThickChannels())) } : void 0,
5676
+ thick: brush.engine === "impasto" ? { channels: _nullishCoalesce(_optionalChain([doc, 'access', _341 => _341.thick, 'optionalAccess', _342 => _342[layer.id]]), () => ( emptyThickChannels())) } : void 0,
5649
5677
  // Light paint: a twin of the stroke paints the light channel (laying, dimming, moving light).
5650
- light: !wet && brush.engine !== "sticker" && (brush.light.amount > 0 || _optionalChain([doc, 'access', _340 => _340.light, 'optionalAccess', _341 => _341[layer.id]])) ? { surface: _nullishCoalesce(_optionalChain([doc, 'access', _342 => _342.light, 'optionalAccess', _343 => _343[layer.id]]), () => ( emptyLight())) } : null,
5651
- sticker: brush.engine === "sticker" ? { nextId: this.nextStickerNumber(doc) } : void 0,
5678
+ light: !wet && brush.engine !== "sticker" && (brush.light.amount > 0 || _optionalChain([doc, 'access', _343 => _343.light, 'optionalAccess', _344 => _344[layer.id]])) ? { surface: _nullishCoalesce(_optionalChain([doc, 'access', _345 => _345.light, 'optionalAccess', _346 => _346[layer.id]]), () => ( emptyLight())) } : null,
5679
+ sticker: brush.engine === "sticker" ? { nextId: this.nextStickerNumber(doc), art: this.stickerArt.get } : void 0,
5652
5680
  paint: effect ? null : this.strokeGradient(init, brush, color),
5653
5681
  effect
5654
5682
  });
@@ -5661,7 +5689,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
5661
5689
  const stroke = {
5662
5690
  id: `s${this.strokeCounter++}`,
5663
5691
  layerId: session.layerId,
5664
- brush: _chunk6G6ZDDDBcjs.brushToJSON.call(void 0, init.brush),
5692
+ brush: _chunkH4AOUUBEcjs.brushToJSON.call(void 0, init.brush),
5665
5693
  color: init.colorHex,
5666
5694
  points: session.points.map((p) => ({ ...p })),
5667
5695
  seed: init.seed
@@ -5686,12 +5714,12 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
5686
5714
  const before = this.doc;
5687
5715
  const host = {
5688
5716
  update: (layerId, surface, rects) => {
5689
- if (_optionalChain([this, 'access', _344 => _344.session, 'optionalAccess', _345 => _345.init, 'access', _346 => _346.wet])) {
5717
+ if (_optionalChain([this, 'access', _347 => _347.session, 'optionalAccess', _348 => _348.init, 'access', _349 => _349.wet])) {
5690
5718
  this.wet.syncDisplays();
5691
5719
  return;
5692
5720
  }
5693
5721
  this.live = { layerId, surface };
5694
- const ch = _optionalChain([this, 'access', _347 => _347.session, 'optionalAccess', _348 => _348.thickChannels, 'call', _349 => _349()]);
5722
+ const ch = _optionalChain([this, 'access', _350 => _350.session, 'optionalAccess', _351 => _351.thickChannels, 'call', _352 => _352()]);
5695
5723
  this.liveThick = ch ? { layerId, channels: ch } : null;
5696
5724
  this.emit(rects);
5697
5725
  },
@@ -5703,7 +5731,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
5703
5731
  const wetStroke = Boolean(s.init.wet);
5704
5732
  if (wetStroke) this.wet.driver = null;
5705
5733
  const brush = s.init.brush;
5706
- if (!cancelled && _optionalChain([s, 'access', _350 => _350.result, 'optionalAccess', _351 => _351.mixerLoad])) this.keepLoad(brush, s.result.mixerLoad);
5734
+ if (!cancelled && _optionalChain([s, 'access', _353 => _353.result, 'optionalAccess', _354 => _354.mixerLoad])) this.keepLoad(brush, s.result.mixerLoad);
5707
5735
  if (cancelled || !surface) {
5708
5736
  if (this.wetOp) {
5709
5737
  const snap = this.wetOp.before;
@@ -5718,7 +5746,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
5718
5746
  }
5719
5747
  const stroke = this.record(s);
5720
5748
  s.result.strokeId = stroke.id;
5721
- this.paintedBounds.set(stroke, _nullishCoalesce(_optionalChain([s, 'access', _352 => _352.result, 'optionalAccess', _353 => _353.bounds]), () => ( null)));
5749
+ this.paintedBounds.set(stroke, _nullishCoalesce(_optionalChain([s, 'access', _355 => _355.result, 'optionalAccess', _356 => _356.bounds]), () => ( null)));
5722
5750
  if (wetStroke && this.wet.instantDry) {
5723
5751
  this.wet.dry(s.layerId);
5724
5752
  this.logWet({ kind: "dry", layerId: s.layerId, at: this.doc.strokes.length + 1 });
@@ -5729,10 +5757,10 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
5729
5757
  const ch = s.thickChannels();
5730
5758
  const thick = ch ? { ..._nullishCoalesce(this.doc.thick, () => ( {})), [l.id]: ch } : this.doc.thick;
5731
5759
  const sprayed = s.stickers();
5732
- const stickers = sprayed ? { ..._nullishCoalesce(this.doc.stickers, () => ( {})), [l.id]: [..._nullishCoalesce(_optionalChain([this, 'access', _354 => _354.doc, 'access', _355 => _355.stickers, 'optionalAccess', _356 => _356[l.id]]), () => ( [])), ...sprayed] } : this.doc.stickers;
5733
- const wetLight = wetStroke && _optionalChain([this, 'access', _357 => _357.wet, 'access', _358 => _358.world, 'optionalAccess', _359 => _359.hasLane, 'call', _360 => _360(l.id)]) ? this.wet.world.lightDisplay(l.id) : null;
5760
+ const stickers = sprayed ? { ..._nullishCoalesce(this.doc.stickers, () => ( {})), [l.id]: [..._nullishCoalesce(_optionalChain([this, 'access', _357 => _357.doc, 'access', _358 => _358.stickers, 'optionalAccess', _359 => _359[l.id]]), () => ( [])), ...sprayed] } : this.doc.stickers;
5761
+ const wetLight = wetStroke && _optionalChain([this, 'access', _360 => _360.wet, 'access', _361 => _361.world, 'optionalAccess', _362 => _362.hasLane, 'call', _363 => _363(l.id)]) ? this.wet.world.lightDisplay(l.id) : null;
5734
5762
  const light = withLayerLight(this.doc.light, l.id, _nullishCoalesce(s.lightChannel(), () => ( wetLight)));
5735
- this.commit(`${brush.name} stroke`, this.withWetEvents(withLiveStroke({ ...this.doc, layers: _chunkHB4ICNNAcjs.mapLayer.call(void 0, this.doc.layers, l.id, () => ({ ...l, surface })), strokes: [...this.doc.strokes, stroke], ...thick ? { thick } : {}, ...stickers ? { stickers } : {}, ...light ? { light } : {} }, stroke)), wetStroke ? before : this.doc);
5763
+ this.commit(`${brush.name} stroke`, this.withWetEvents(withLiveStroke({ ...this.doc, layers: _chunkDPYAO5U6cjs.mapLayer.call(void 0, this.doc.layers, l.id, () => ({ ...l, surface })), strokes: [...this.doc.strokes, stroke], ...thick ? { thick } : {}, ...stickers ? { stickers } : {}, ...light ? { light } : {} }, stroke)), wetStroke ? before : this.doc);
5736
5764
  }
5737
5765
  };
5738
5766
  let session;
@@ -5760,18 +5788,18 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
5760
5788
  if (cancelled || !surface) return;
5761
5789
  const stroke = this.record(s);
5762
5790
  s.result.strokeId = stroke.id;
5763
- this.paintedBounds.set(stroke, _nullishCoalesce(_optionalChain([s, 'access', _361 => _361.result, 'optionalAccess', _362 => _362.bounds]), () => ( null)));
5764
- const l = _chunkHB4ICNNAcjs.findLayer.call(void 0, out.layers, s.layerId).layer;
5791
+ this.paintedBounds.set(stroke, _nullishCoalesce(_optionalChain([s, 'access', _364 => _364.result, 'optionalAccess', _365 => _365.bounds]), () => ( null)));
5792
+ const l = _chunkDPYAO5U6cjs.findLayer.call(void 0, out.layers, s.layerId).layer;
5765
5793
  const offset = s.init.wet ? { x: 0, y: 0 } : l.offset;
5766
5794
  const ch = s.thickChannels();
5767
5795
  const sprayed = s.stickers();
5768
- const lit = _nullishCoalesce(s.lightChannel(), () => ( (s.init.wet && _optionalChain([this, 'access', _363 => _363.wet, 'access', _364 => _364.world, 'optionalAccess', _365 => _365.hasLane, 'call', _366 => _366(l.id)]) ? this.wet.world.lightDisplay(l.id) : null)));
5796
+ const lit = _nullishCoalesce(s.lightChannel(), () => ( (s.init.wet && _optionalChain([this, 'access', _366 => _366.wet, 'access', _367 => _367.world, 'optionalAccess', _368 => _368.hasLane, 'call', _369 => _369(l.id)]) ? this.wet.world.lightDisplay(l.id) : null)));
5769
5797
  out = withLiveStroke({
5770
5798
  ...out,
5771
- layers: _chunkHB4ICNNAcjs.mapLayer.call(void 0, out.layers, l.id, () => ({ ...l, surface, offset })),
5799
+ layers: _chunkDPYAO5U6cjs.mapLayer.call(void 0, out.layers, l.id, () => ({ ...l, surface, offset })),
5772
5800
  strokes: [...out.strokes, stroke],
5773
5801
  ...ch ? { thick: { ..._nullishCoalesce(out.thick, () => ( {})), [l.id]: ch } } : {},
5774
- ...sprayed ? { stickers: { ..._nullishCoalesce(out.stickers, () => ( {})), [l.id]: [..._nullishCoalesce(_optionalChain([out, 'access', _367 => _367.stickers, 'optionalAccess', _368 => _368[l.id]]), () => ( [])), ...sprayed] } } : {},
5802
+ ...sprayed ? { stickers: { ..._nullishCoalesce(out.stickers, () => ( {})), [l.id]: [..._nullishCoalesce(_optionalChain([out, 'access', _370 => _370.stickers, 'optionalAccess', _371 => _371[l.id]]), () => ( [])), ...sprayed] } } : {},
5775
5803
  ...lit ? { light: withLayerLight(out.light, l.id, lit) } : {}
5776
5804
  }, stroke);
5777
5805
  }
@@ -5784,8 +5812,8 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
5784
5812
  if (this.wet.instantDry && result.strokeId) {
5785
5813
  this.wet.dry(session.layerId);
5786
5814
  this.logWet({ kind: "dry", layerId: session.layerId, at: out.strokes.length });
5787
- const dried = _chunkHB4ICNNAcjs.findLayer.call(void 0, this.doc.layers, session.layerId).layer.surface;
5788
- out = { ...out, layers: _chunkHB4ICNNAcjs.mapLayer.call(void 0, out.layers, session.layerId, (l) => ({ ...l, surface: dried })) };
5815
+ const dried = _chunkDPYAO5U6cjs.findLayer.call(void 0, this.doc.layers, session.layerId).layer.surface;
5816
+ out = { ...out, layers: _chunkDPYAO5U6cjs.mapLayer.call(void 0, out.layers, session.layerId, (l) => ({ ...l, surface: dried })) };
5789
5817
  }
5790
5818
  result.wet = this.wet.isWet(session.layerId);
5791
5819
  }
@@ -5830,7 +5858,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
5830
5858
  */
5831
5859
  replayStrokes(options) {
5832
5860
  this.requireIdle("replaying");
5833
- if (!_optionalChain([options, 'access', _369 => _369.strokeIds, 'optionalAccess', _370 => _370.length])) throw new PaintEditorError("strokeIds is empty; pass ids from list_strokes.");
5861
+ if (!_optionalChain([options, 'access', _372 => _372.strokeIds, 'optionalAccess', _373 => _373.length])) throw new PaintEditorError("strokeIds is empty; pass ids from list_strokes.");
5834
5862
  const strokes = options.strokeIds.map((id) => {
5835
5863
  const s = this.doc.strokes.find((x) => x.id === id);
5836
5864
  if (!s) throw new PaintEditorError(`Unknown stroke "${id}". Call list_strokes for the ids.`);
@@ -5844,7 +5872,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
5844
5872
  if (options.layerId !== void 0) this.paintTarget(options.layerId, "replay onto");
5845
5873
  if (options.color === void 0) {
5846
5874
  for (const s of strokes) {
5847
- if (_optionalChain([s, 'access', _371 => _371.paint, 'optionalAccess', _372 => _372.type]) === "effect" && !this.effectPaintImage(s.paint)) {
5875
+ if (_optionalChain([s, 'access', _374 => _374.paint, 'optionalAccess', _375 => _375.type]) === "effect" && !this.effectPaintImage(s.paint)) {
5848
5876
  throw new PaintEditorError(`Stroke "${s.id}" paints with the effect "${s.paint.effect}"${s.paint.provider ? ` from provider "${s.paint.provider}"` : ""}, which is not rendered in this editor; render it first (prepareStrokeEffects; the replay_strokes tool does this) or recolour the replay with color.`);
5849
5877
  }
5850
5878
  }
@@ -5867,13 +5895,13 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
5867
5895
  let brush = v.brush;
5868
5896
  if (options.brushId !== void 0) {
5869
5897
  const b = this.requireBrush(options.brushId);
5870
- brush = _chunk6G6ZDDDBcjs.normalizePaintBrush.call(void 0, { tip: { ...b.tip, size: b.tip.size * (v.brush.tip.size / s.brush.tip.size) } }, b);
5898
+ brush = _chunkH4AOUUBEcjs.normalizePaintBrush.call(void 0, { tip: { ...b.tip, size: b.tip.size * (v.brush.tip.size / s.brush.tip.size) } }, b);
5871
5899
  }
5872
5900
  const layerId = _nullishCoalesce(options.layerId, () => ( s.layerId));
5873
- if (!_chunkHB4ICNNAcjs.findLayer.call(void 0, doc.layers, layerId)) throw new PaintEditorError(`Stroke "${s.id}" was painted on layer "${layerId}", which no longer exists; pass layerId to replay it elsewhere.`);
5901
+ if (!_chunkDPYAO5U6cjs.findLayer.call(void 0, doc.layers, layerId)) throw new PaintEditorError(`Stroke "${s.id}" was painted on layer "${layerId}", which no longer exists; pass layerId to replay it elsewhere.`);
5874
5902
  let load = s.load;
5875
5903
  if (load && options.color !== void 0 && load.reservoir) {
5876
- const [r, g, b] = _chunk6G6ZDDDBcjs.hexToRgb8.call(void 0, options.color);
5904
+ const [r, g, b] = _chunkH4AOUUBEcjs.hexToRgb8.call(void 0, options.color);
5877
5905
  load = { ...load, reservoir: [r / 255, g / 255, b / 255] };
5878
5906
  }
5879
5907
  const paint = v.paint && options.color === void 0 ? { paint: v.paint } : {};
@@ -5902,7 +5930,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
5902
5930
  /** A layer's light paint: whether it has any, where (document pixels), its brightest value 0..255, and its spill. */
5903
5931
  lightOf(layerId) {
5904
5932
  const l = this.wetLayer(layerId, "read the light of");
5905
- const info = lightInfo(_optionalChain([this, 'access', _373 => _373.doc, 'access', _374 => _374.light, 'optionalAccess', _375 => _375[l.id]]));
5933
+ const info = lightInfo(_optionalChain([this, 'access', _376 => _376.doc, 'access', _377 => _377.light, 'optionalAccess', _378 => _378[l.id]]));
5906
5934
  const bounds = info.bounds ? { ...info.bounds, x: info.bounds.x + l.offset.x, y: info.bounds.y + l.offset.y } : null;
5907
5935
  return { layerId: l.id, hasLight: info.peak > 0, bounds, peak: info.peak, spill: { ...this.lightSpillOf(l.id) } };
5908
5936
  }
@@ -5953,7 +5981,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
5953
5981
  const id = _nullishCoalesce(layerId, () => ( this.doc.activeLayerId));
5954
5982
  if (!id) return null;
5955
5983
  this.requireLayer(id);
5956
- const ch = _optionalChain([this, 'access', _376 => _376.doc, 'access', _377 => _377.thick, 'optionalAccess', _378 => _378[id]]);
5984
+ const ch = _optionalChain([this, 'access', _379 => _379.doc, 'access', _380 => _380.thick, 'optionalAccess', _381 => _381[id]]);
5957
5985
  if (!ch) return null;
5958
5986
  const r = reliefInfo(ch);
5959
5987
  return { layerId: id, bounds: r.bounds, maxHeight: r.maxHeight };
@@ -6008,7 +6036,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
6008
6036
  /** `renderHighRes` as PNG bytes. */
6009
6037
  async exportHighResPng(options) {
6010
6038
  const img = await this.renderHighRes(options);
6011
- return _chunkOLNIPTB3cjs.encodePng.call(void 0, img.width, img.height, img.data);
6039
+ return _chunkW5M3J7PVcjs.encodePng.call(void 0, img.width, img.height, img.data);
6012
6040
  }
6013
6041
  async renderHighRes(options) {
6014
6042
  const target = this.createReplayTarget(options.scale);
@@ -6061,7 +6089,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
6061
6089
  wetState() {
6062
6090
  const st = this.getState().wet;
6063
6091
  const backend = this.wet.backend();
6064
- return { ...st, layers: this.wet.wetLayerIds().map((id) => this.wet.info(id)), backend, message: _nullishCoalesce(_optionalChain([backend, 'optionalAccess', _379 => _379.message]), () => ( _chunkVMROIWLLcjs.wetSupport.call(void 0, ).message)), engine: this.wet.engineInfo() };
6092
+ return { ...st, layers: this.wet.wetLayerIds().map((id) => this.wet.info(id)), backend, message: _nullishCoalesce(_optionalChain([backend, 'optionalAccess', _382 => _382.message]), () => ( _chunkKBYB7OWBcjs.wetSupport.call(void 0, ).message)), engine: this.wet.engineInfo() };
6065
6093
  }
6066
6094
  /**
6067
6095
  * Engine B, the WebGPU accelerator for large wet areas: whether it may run, its state (`off`,
@@ -6130,11 +6158,11 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
6130
6158
  wetPaper(options = {}) {
6131
6159
  this.requireIdle("wetting the paper");
6132
6160
  const l = this.wetLayer(options.layerId, "wet the paper of");
6133
- if (_chunkHB4ICNNAcjs.isLayerLocked.call(void 0, l, "pixels")) throw new PaintEditorError(`Layer "${l.name}" has its pixels locked; unlock it first.`);
6161
+ if (_chunkDPYAO5U6cjs.isLayerLocked.call(void 0, l, "pixels")) throw new PaintEditorError(`Layer "${l.name}" has its pixels locked; unlock it first.`);
6134
6162
  const amount = _nullishCoalesce(options.amount, () => ( 1));
6135
6163
  if (!(amount > 0 && amount <= 1)) throw new PaintEditorError(`amount ${amount} is out of range; use above 0 up to 1.`);
6136
6164
  const rect = _nullishCoalesce(this.checkRect(options.rect), () => ( { x: 0, y: 0, width: this.doc.canvas.width, height: this.doc.canvas.height }));
6137
- if (!this.wet.wetLayerIds().includes(l.id) && this.wet.wetLayerIds().length >= _chunkVMROIWLLcjs.MAX_WET_LANES) throw new PaintEditorError(`At most ${_chunkVMROIWLLcjs.MAX_WET_LANES} layers can hold wet paint at once; dry one first (dry_paint).`);
6165
+ if (!this.wet.wetLayerIds().includes(l.id) && this.wet.wetLayerIds().length >= _chunkKBYB7OWBcjs.MAX_WET_LANES) throw new PaintEditorError(`At most ${_chunkKBYB7OWBcjs.MAX_WET_LANES} layers can hold wet paint at once; dry one first (dry_paint).`);
6138
6166
  const before = this.doc;
6139
6167
  this.beginWetOp();
6140
6168
  const world = this.wet.ensureLane(l.id);
@@ -6146,7 +6174,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
6146
6174
  }
6147
6175
  /** Records a settings change as a wet event (not an undo step). */
6148
6176
  recordWetSetting(e) {
6149
- this.doc = { ...this.doc, wetEvents: [..._nullishCoalesce(this.doc.wetEvents, () => ( [])), { clock: _nullishCoalesce(_optionalChain([this, 'access', _380 => _380.wet, 'access', _381 => _381.world, 'optionalAccess', _382 => _382.clock]), () => ( 0)), at: this.doc.strokes.length, ...e }] };
6177
+ this.doc = { ...this.doc, wetEvents: [..._nullishCoalesce(this.doc.wetEvents, () => ( [])), { clock: _nullishCoalesce(_optionalChain([this, 'access', _383 => _383.wet, 'access', _384 => _384.world, 'optionalAccess', _385 => _385.clock]), () => ( 0)), at: this.doc.strokes.length, ...e }] };
6150
6178
  }
6151
6179
  /** Changes a layer's wet settings (viscosity, evaporation, granulation…). Editor settings saved with the document, not an undo step. */
6152
6180
  setWetParams(layerId, update) {
@@ -6212,11 +6240,11 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
6212
6240
  /** The layers with the live stroke's surface in place. */
6213
6241
  currentLayers() {
6214
6242
  const override = this.frameOverride;
6215
- if (override) return Array.from(override).reduce((ls, [id, surface]) => _chunkHB4ICNNAcjs.mapLayer.call(void 0, ls, id, (l) => ({ ...l, surface })), this.doc.layers);
6243
+ if (override) return Array.from(override).reduce((ls, [id, surface]) => _chunkDPYAO5U6cjs.mapLayer.call(void 0, ls, id, (l) => ({ ...l, surface })), this.doc.layers);
6216
6244
  const live = this.live;
6217
6245
  if (!live) return this.animatedView();
6218
- if (_optionalChain([this, 'access', _383 => _383.liveLayers, 'optionalAccess', _384 => _384.key]) === live.surface) return this.liveLayers.layers;
6219
- const layers = _chunkHB4ICNNAcjs.mapLayer.call(void 0, this.doc.layers, live.layerId, (l) => ({ ...l, surface: live.surface }));
6246
+ if (_optionalChain([this, 'access', _386 => _386.liveLayers, 'optionalAccess', _387 => _387.key]) === live.surface) return this.liveLayers.layers;
6247
+ const layers = _chunkDPYAO5U6cjs.mapLayer.call(void 0, this.doc.layers, live.layerId, (l) => ({ ...l, surface: live.surface }));
6220
6248
  this.liveLayers = { key: live.surface, layers };
6221
6249
  return layers;
6222
6250
  }
@@ -6238,7 +6266,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
6238
6266
  tracingNode(t) {
6239
6267
  const { width, height } = this.doc.canvas;
6240
6268
  const key = this.tracingVersion * 100003 + width * 7 + height;
6241
- if (_optionalChain([this, 'access', _385 => _385.tracingCache, 'optionalAccess', _386 => _386.key]) === key && this.tracingCache.node.opacity === t.opacity) return this.tracingCache.node;
6269
+ if (_optionalChain([this, 'access', _388 => _388.tracingCache, 'optionalAccess', _389 => _389.key]) === key && this.tracingCache.node.opacity === t.opacity) return this.tracingCache.node;
6242
6270
  const src = _nullishCoalesce(this.imagePixels.get(t.src), () => ( this.decodeImage(t.src)));
6243
6271
  const image = resampleInto(src, t.rect, width, height);
6244
6272
  const node = { type: "image", id: TRACING_NODE_ID, name: "Tracing", visible: true, opacity: t.opacity, blend: "normal", image, version: key + Math.round(t.opacity * 1e3) / 1e4 };
@@ -6253,7 +6281,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
6253
6281
  let out = layers;
6254
6282
  for (const id of ids) {
6255
6283
  const baked = this.wet.bakedSurface(id);
6256
- if (baked && _chunkHB4ICNNAcjs.findLayer.call(void 0, out, id)) out = _chunkHB4ICNNAcjs.mapLayer.call(void 0, out, id, (l) => ({ ...l, surface: baked }));
6284
+ if (baked && _chunkDPYAO5U6cjs.findLayer.call(void 0, out, id)) out = _chunkDPYAO5U6cjs.mapLayer.call(void 0, out, id, (l) => ({ ...l, surface: baked }));
6257
6285
  }
6258
6286
  return out;
6259
6287
  }
@@ -6265,13 +6293,13 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
6265
6293
  let out = layers;
6266
6294
  const ids = /* @__PURE__ */ new Set([...Object.keys(_nullishCoalesce(thick, () => ( {}))), ...live ? [live.layerId] : []]);
6267
6295
  for (const id of ids) {
6268
- const ch = _optionalChain([live, 'optionalAccess', _387 => _387.layerId]) === id ? live.channels : _optionalChain([thick, 'optionalAccess', _388 => _388[id]]);
6269
- const l = ch && _optionalChain([_chunkHB4ICNNAcjs.findLayer.call(void 0, out, id), 'optionalAccess', _389 => _389.layer]);
6296
+ const ch = _optionalChain([live, 'optionalAccess', _390 => _390.layerId]) === id ? live.channels : _optionalChain([thick, 'optionalAccess', _391 => _391[id]]);
6297
+ const l = ch && _optionalChain([_chunkDPYAO5U6cjs.findLayer.call(void 0, out, id), 'optionalAccess', _392 => _392.layer]);
6270
6298
  if (!ch || !isPixelLayer(l)) continue;
6271
6299
  let cache = this.litCaches.get(id);
6272
6300
  if (!cache) this.litCaches.set(id, cache = new LitCache());
6273
6301
  const lit = cache.lit(l.surface, ch, this.lighting);
6274
- if (lit !== l.surface) out = _chunkHB4ICNNAcjs.mapLayer.call(void 0, out, id, () => ({ ...l, surface: lit }));
6302
+ if (lit !== l.surface) out = _chunkDPYAO5U6cjs.mapLayer.call(void 0, out, id, () => ({ ...l, surface: lit }));
6275
6303
  }
6276
6304
  return out;
6277
6305
  }
@@ -6286,13 +6314,13 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
6286
6314
  if (!ids.size) return layers;
6287
6315
  let out = layers;
6288
6316
  for (const id of ids) {
6289
- const l = _optionalChain([_chunkHB4ICNNAcjs.findLayer.call(void 0, out, id), 'optionalAccess', _390 => _390.layer]);
6317
+ const l = _optionalChain([_chunkDPYAO5U6cjs.findLayer.call(void 0, out, id), 'optionalAccess', _393 => _393.layer]);
6290
6318
  if (!isPixelLayer(l)) continue;
6291
6319
  let cache = this.lightCaches.get(id);
6292
6320
  if (!cache) this.lightCaches.set(id, cache = new LightCache());
6293
- const glowed = cache.glow(l.surface, light[id], _optionalChain([this, 'access', _391 => _391.liveThick, 'optionalAccess', _392 => _392.layerId]) === id ? this.liveThick.channels : _optionalChain([this, 'access', _393 => _393.doc, 'access', _394 => _394.thick, 'optionalAccess', _395 => _395[id]]));
6294
- if (glowed !== l.surface) out = _chunkHB4ICNNAcjs.mapLayer.call(void 0, out, id, () => ({ ...l, surface: glowed }));
6295
- const committed = _optionalChain([_chunkHB4ICNNAcjs.findLayer.call(void 0, this.doc.layers, id), 'optionalAccess', _396 => _396.layer]);
6321
+ const glowed = cache.glow(l.surface, light[id], _optionalChain([this, 'access', _394 => _394.liveThick, 'optionalAccess', _395 => _395.layerId]) === id ? this.liveThick.channels : _optionalChain([this, 'access', _396 => _396.doc, 'access', _397 => _397.thick, 'optionalAccess', _398 => _398[id]]));
6322
+ if (glowed !== l.surface) out = _chunkDPYAO5U6cjs.mapLayer.call(void 0, out, id, () => ({ ...l, surface: glowed }));
6323
+ const committed = _optionalChain([_chunkDPYAO5U6cjs.findLayer.call(void 0, this.doc.layers, id), 'optionalAccess', _399 => _399.layer]);
6296
6324
  const spill = light[id] && isPixelLayer(committed) ? cache.spill(committed.surface, light[id], this.lightSpillOf(id)) : null;
6297
6325
  if (spill) out = insertAfter(out, id, { type: "pixel", id: `${id}${SPILL_SUFFIX}`, name: `${l.name} light`, visible: l.visible, opacity: l.opacity, blend: "linear-dodge", surface: spill, offset: { ...l.offset } });
6298
6326
  }
@@ -6304,7 +6332,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
6304
6332
  if (!l.visible) continue;
6305
6333
  if (l.type === "group") this.backlitLayers(l.children, committed, opacity * l.opacity, out);
6306
6334
  else if (isPixelLayer(l)) {
6307
- const thick = !committed && _optionalChain([this, 'access', _397 => _397.liveThick, 'optionalAccess', _398 => _398.layerId]) === l.id ? this.liveThick.channels : _optionalChain([this, 'access', _399 => _399.doc, 'access', _400 => _400.thick, 'optionalAccess', _401 => _401[l.id]]);
6335
+ const thick = !committed && _optionalChain([this, 'access', _400 => _400.liveThick, 'optionalAccess', _401 => _401.layerId]) === l.id ? this.liveThick.channels : _optionalChain([this, 'access', _402 => _402.doc, 'access', _403 => _403.thick, 'optionalAccess', _404 => _404[l.id]]);
6308
6336
  out.push({ surface: l.surface, offset: l.offset, opacity: opacity * l.opacity, ...thick ? { thick } : {} });
6309
6337
  }
6310
6338
  }
@@ -6333,7 +6361,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
6333
6361
  if (backlight) layers = [...layers, backlight];
6334
6362
  if (options.layerIds) {
6335
6363
  const picked = [];
6336
- for (const id of options.layerIds) picked.push(_nullishCoalesce(_optionalChain([_chunkHB4ICNNAcjs.findLayer.call(void 0, layers, id), 'optionalAccess', _402 => _402.layer]), () => ( this.requireLayer(id))));
6364
+ for (const id of options.layerIds) picked.push(_nullishCoalesce(_optionalChain([_chunkDPYAO5U6cjs.findLayer.call(void 0, layers, id), 'optionalAccess', _405 => _405.layer]), () => ( this.requireLayer(id))));
6337
6365
  layers = picked.map((l) => ({ ...l, visible: true }));
6338
6366
  }
6339
6367
  const under = options.paper === false ? [] : [paperNode(this.doc.paper, this.lighting)];
@@ -6349,7 +6377,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
6349
6377
  */
6350
6378
  compositeTiles(rect, onTile, options = {}) {
6351
6379
  const dirty = options.dirty === "all" ? void 0 : options.dirty;
6352
- this.viewCompositor.compositeTiles(this.renderLayers({ paper: options.paper }, true), rect, this.sources(), onTile, { dirty, checkpointLayerId: _nullishCoalesce(_optionalChain([this, 'access', _403 => _403.live, 'optionalAccess', _404 => _404.layerId]), () => ( this.doc.activeLayerId)) });
6380
+ this.viewCompositor.compositeTiles(this.renderLayers({ paper: options.paper }, true), rect, this.sources(), onTile, { dirty, checkpointLayerId: _nullishCoalesce(_optionalChain([this, 'access', _406 => _406.live, 'optionalAccess', _407 => _407.layerId]), () => ( this.doc.activeLayerId)) });
6353
6381
  }
6354
6382
  /** The canvas as canvas-sized RGBA (paper included by default). */
6355
6383
  compositePixels(options = {}) {
@@ -6377,7 +6405,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
6377
6405
  /** Wet settings saved with the document (`null` when they are all defaults). */
6378
6406
  wetJSON() {
6379
6407
  const layers = {};
6380
- for (const [id, set] of this.wet.settings) if (_chunkHB4ICNNAcjs.findLayer.call(void 0, this.doc.layers, id)) layers[id] = { params: { ...set.params }, flow: { ...set.flow } };
6408
+ for (const [id, set] of this.wet.settings) if (_chunkDPYAO5U6cjs.findLayer.call(void 0, this.doc.layers, id)) layers[id] = { params: { ...set.params }, flow: { ...set.flow } };
6381
6409
  const flat = this.wet.tilt.angle === 0;
6382
6410
  if (!Object.keys(layers).length && flat) return void 0;
6383
6411
  return { tilt: { ...this.wet.tilt }, layers };
@@ -6386,7 +6414,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
6386
6414
  this.wet.reset();
6387
6415
  if (!raw || typeof raw !== "object") return;
6388
6416
  const r = raw;
6389
- this.wet.setTilt(_chunkVMROIWLLcjs.normalizeTilt.call(void 0, _nullishCoalesce(r.tilt, () => ( {}))));
6417
+ this.wet.setTilt(_chunkKBYB7OWBcjs.normalizeTilt.call(void 0, _nullishCoalesce(r.tilt, () => ( {}))));
6390
6418
  if (r.layers && typeof r.layers === "object") {
6391
6419
  for (const [id, v] of Object.entries(r.layers)) {
6392
6420
  if (!v || typeof v !== "object") {
@@ -6394,7 +6422,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
6394
6422
  continue;
6395
6423
  }
6396
6424
  const x = v;
6397
- this.wet.settings.set(id, { params: _chunkVMROIWLLcjs.normalizeWetParams.call(void 0, _nullishCoalesce(x.params, () => ( {}))), flow: _chunkVMROIWLLcjs.normalizeFlow.call(void 0, _nullishCoalesce(x.flow, () => ( {}))) });
6425
+ this.wet.settings.set(id, { params: _chunkKBYB7OWBcjs.normalizeWetParams.call(void 0, _nullishCoalesce(x.params, () => ( {}))), flow: _chunkKBYB7OWBcjs.normalizeFlow.call(void 0, _nullishCoalesce(x.flow, () => ( {}))) });
6398
6426
  }
6399
6427
  }
6400
6428
  }
@@ -6403,32 +6431,32 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
6403
6431
  const ext = { ...this.extensions };
6404
6432
  const channels = {};
6405
6433
  for (const [id, ch] of Object.entries(_nullishCoalesce(this.doc.thick, () => ( {})))) {
6406
- if (!_chunkHB4ICNNAcjs.findLayer.call(void 0, this.doc.layers, id)) continue;
6434
+ if (!_chunkDPYAO5U6cjs.findLayer.call(void 0, this.doc.layers, id)) continue;
6407
6435
  const saved = thickToJSON(ch);
6408
6436
  if (saved) channels[id] = saved;
6409
6437
  }
6410
6438
  if (Object.keys(channels).length) ext.layerChannels = channels;
6411
6439
  else delete ext.layerChannels;
6412
6440
  const stickers = {};
6413
- for (const [id, list] of Object.entries(_nullishCoalesce(this.doc.stickers, () => ( {})))) if (list.length && _chunkHB4ICNNAcjs.findLayer.call(void 0, this.doc.layers, id)) stickers[id] = list.map((x) => ({ ...x }));
6441
+ for (const [id, list] of Object.entries(_nullishCoalesce(this.doc.stickers, () => ( {})))) if (list.length && _chunkDPYAO5U6cjs.findLayer.call(void 0, this.doc.layers, id)) stickers[id] = list.map((x) => ({ ...x }));
6414
6442
  if (Object.keys(stickers).length) ext.stickers = stickers;
6415
6443
  else delete ext.stickers;
6416
6444
  const liveStrokes = {};
6417
- for (const [id, list] of Object.entries(_nullishCoalesce(this.doc.liveStrokes, () => ( {})))) if (_chunkHB4ICNNAcjs.findLayer.call(void 0, this.doc.layers, id)) liveStrokes[id] = list.map((x) => JSON.parse(JSON.stringify(x)));
6445
+ for (const [id, list] of Object.entries(_nullishCoalesce(this.doc.liveStrokes, () => ( {})))) if (_chunkDPYAO5U6cjs.findLayer.call(void 0, this.doc.layers, id)) liveStrokes[id] = list.map((x) => JSON.parse(JSON.stringify(x)));
6418
6446
  if (Object.keys(liveStrokes).length) ext.liveStrokes = liveStrokes;
6419
6447
  else delete ext.liveStrokes;
6420
6448
  const light = {};
6421
6449
  for (const [id, t] of Object.entries(_nullishCoalesce(this.doc.light, () => ( {})))) {
6422
- if (!_chunkHB4ICNNAcjs.findLayer.call(void 0, this.doc.layers, id)) continue;
6450
+ if (!_chunkDPYAO5U6cjs.findLayer.call(void 0, this.doc.layers, id)) continue;
6423
6451
  const saved = lightToJSON(_nullishCoalesce(this.wet.bakedLight(id), () => ( t)));
6424
6452
  if (saved) light[id] = saved;
6425
6453
  }
6426
6454
  if (Object.keys(light).length) ext.light = light;
6427
6455
  else delete ext.light;
6428
- const spills = Object.fromEntries(Object.entries(this.lightSpills).filter(([id]) => _chunkHB4ICNNAcjs.findLayer.call(void 0, this.doc.layers, id)));
6456
+ const spills = Object.fromEntries(Object.entries(this.lightSpills).filter(([id]) => _chunkDPYAO5U6cjs.findLayer.call(void 0, this.doc.layers, id)));
6429
6457
  if (Object.keys(spills).length) ext.lightSpill = spills;
6430
6458
  else delete ext.lightSpill;
6431
- const effectLayers = effectLayersToJSON(_nullishCoalesce(this.doc.effectLayers, () => ( {})), (id) => isPixelLayer(_optionalChain([_chunkHB4ICNNAcjs.findLayer.call(void 0, this.doc.layers, id), 'optionalAccess', _405 => _405.layer])));
6459
+ const effectLayers = effectLayersToJSON(_nullishCoalesce(this.doc.effectLayers, () => ( {})), (id) => isPixelLayer(_optionalChain([_chunkDPYAO5U6cjs.findLayer.call(void 0, this.doc.layers, id), 'optionalAccess', _408 => _408.layer])));
6432
6460
  if (effectLayers) ext.effectLayers = effectLayers;
6433
6461
  else delete ext.effectLayers;
6434
6462
  if (this.doc.paperEffect) ext.paperEffect = paperEffectToJSON(this.doc.paperEffect);
@@ -6444,17 +6472,27 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
6444
6472
  if (ext.stickers && typeof ext.stickers === "object") {
6445
6473
  const stickers = {};
6446
6474
  for (const [id, list] of Object.entries(ext.stickers)) {
6447
- if (!_chunkHB4ICNNAcjs.findLayer.call(void 0, state.layers, id) || !Array.isArray(list)) continue;
6448
- const ok = list.filter((x) => x && typeof x.id === "string" && _chunk6G6ZDDDBcjs.STAMP_KINDS.includes(x.stamp) && Number.isFinite(x.x) && Number.isFinite(x.y) && x.size > 0);
6475
+ if (!_chunkDPYAO5U6cjs.findLayer.call(void 0, state.layers, id) || !Array.isArray(list)) continue;
6476
+ const ok = list.flatMap((x) => {
6477
+ if (!x || typeof x.id !== "string" || !Number.isFinite(x.x) || !Number.isFinite(x.y) || !(x.size > 0)) return [];
6478
+ try {
6479
+ const ref2 = _chunkZEYMKDYScjs.normalizeStickerRef.call(void 0, _nullishCoalesce(x.ref, () => ( x.stamp)));
6480
+ const stamp = _chunkZEYMKDYScjs.editorStampOf.call(void 0, ref2);
6481
+ const { stamp: _old, ...rest } = x;
6482
+ return [{ ...rest, ref: ref2, ...stamp ? { stamp } : {} }];
6483
+ } catch (e4) {
6484
+ return [];
6485
+ }
6486
+ });
6449
6487
  if (ok.length !== list.length) problems.push(`Some stickers of layer "${id}" could not be read; they were dropped.`);
6450
- stickers[id] = ok.map((x) => ({ ...x }));
6488
+ stickers[id] = ok;
6451
6489
  }
6452
6490
  if (Object.keys(stickers).length) state = { ...state, stickers };
6453
6491
  }
6454
6492
  if (ext.liveStrokes && typeof ext.liveStrokes === "object") {
6455
6493
  const liveStrokes = {};
6456
6494
  for (const [id, list] of Object.entries(ext.liveStrokes)) {
6457
- if (!isPixelLayer(_optionalChain([_chunkHB4ICNNAcjs.findLayer.call(void 0, state.layers, id), 'optionalAccess', _406 => _406.layer])) || !Array.isArray(list)) continue;
6495
+ if (!isPixelLayer(_optionalChain([_chunkDPYAO5U6cjs.findLayer.call(void 0, state.layers, id), 'optionalAccess', _409 => _409.layer])) || !Array.isArray(list)) continue;
6458
6496
  const ok = list.map(normalizeBrushStroke).filter((x) => x !== null).map((x) => ({ ...x, layerId: id }));
6459
6497
  if (ok.length !== list.length) problems.push(`Some strokes of stroke layer "${id}" could not be read; they were dropped (the layer's pixels are kept until a stroke is edited).`);
6460
6498
  liveStrokes[id] = ok;
@@ -6464,7 +6502,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
6464
6502
  if (ext.effectLayers && typeof ext.effectLayers === "object") {
6465
6503
  const effectLayers = {};
6466
6504
  for (const [id, v] of Object.entries(ext.effectLayers)) {
6467
- if (!isPixelLayer(_optionalChain([_chunkHB4ICNNAcjs.findLayer.call(void 0, state.layers, id), 'optionalAccess', _407 => _407.layer]))) continue;
6505
+ if (!isPixelLayer(_optionalChain([_chunkDPYAO5U6cjs.findLayer.call(void 0, state.layers, id), 'optionalAccess', _410 => _410.layer]))) continue;
6468
6506
  const source = readPaintEffectSource(v);
6469
6507
  if (source) effectLayers[id] = source;
6470
6508
  else problems.push(`The effect of layer "${id}" could not be read; it loads as a plain layer.`);
@@ -6483,8 +6521,8 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
6483
6521
  if (ext.lightSpill && typeof ext.lightSpill === "object") {
6484
6522
  for (const [id, v] of Object.entries(ext.lightSpill)) {
6485
6523
  try {
6486
- if (_chunkHB4ICNNAcjs.findLayer.call(void 0, state.layers, id)) this.lightSpills[id] = normalizeLightSpill(_nullishCoalesce(v, () => ( {})));
6487
- } catch (e4) {
6524
+ if (_chunkDPYAO5U6cjs.findLayer.call(void 0, state.layers, id)) this.lightSpills[id] = normalizeLightSpill(_nullishCoalesce(v, () => ( {})));
6525
+ } catch (e5) {
6488
6526
  problems.push(`The light spill of layer "${id}" could not be read; it takes the defaults.`);
6489
6527
  }
6490
6528
  }
@@ -6492,7 +6530,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
6492
6530
  if (ext.light && typeof ext.light === "object") {
6493
6531
  const light = {};
6494
6532
  for (const [id, v] of Object.entries(ext.light)) {
6495
- if (!isPixelLayer(_optionalChain([_chunkHB4ICNNAcjs.findLayer.call(void 0, state.layers, id), 'optionalAccess', _408 => _408.layer]))) continue;
6533
+ if (!isPixelLayer(_optionalChain([_chunkDPYAO5U6cjs.findLayer.call(void 0, state.layers, id), 'optionalAccess', _411 => _411.layer]))) continue;
6496
6534
  try {
6497
6535
  light[id] = lightFromJSON(v);
6498
6536
  } catch (e) {
@@ -6505,7 +6543,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
6505
6543
  if (!raw || typeof raw !== "object") return state;
6506
6544
  const thick = {};
6507
6545
  for (const [id, v] of Object.entries(raw)) {
6508
- if (!_chunkHB4ICNNAcjs.findLayer.call(void 0, state.layers, id)) continue;
6546
+ if (!_chunkDPYAO5U6cjs.findLayer.call(void 0, state.layers, id)) continue;
6509
6547
  try {
6510
6548
  thick[id] = thickFromJSON(v);
6511
6549
  } catch (e) {
@@ -6528,7 +6566,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
6528
6566
  this.readGuides(loaded.guides, loaded.state, loaded.problems);
6529
6567
  if (Array.isArray(loaded.swatches)) this.swatches = loaded.swatches.map(readSwatch).filter((x) => x !== null);
6530
6568
  for (const s of loaded.state.strokes) {
6531
- const n = Number(_nullishCoalesce(_optionalChain([/^s(\d+)$/, 'access', _409 => _409.exec, 'call', _410 => _410(s.id), 'optionalAccess', _411 => _411[1]]), () => ( 0)));
6569
+ const n = Number(_nullishCoalesce(_optionalChain([/^s(\d+)$/, 'access', _412 => _412.exec, 'call', _413 => _413(s.id), 'optionalAccess', _414 => _414[1]]), () => ( 0)));
6532
6570
  if (n >= this.strokeCounter) this.strokeCounter = n + 1;
6533
6571
  }
6534
6572
  this.undoStack = [];
@@ -6536,7 +6574,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
6536
6574
  this.doc = this.readThick(loaded.state, loaded.extensions, loaded.problems);
6537
6575
  for (const list of Object.values(_nullishCoalesce(this.doc.liveStrokes, () => ( {})))) {
6538
6576
  for (const s of list) {
6539
- const n = Number(_nullishCoalesce(_optionalChain([/^s(\d+)$/, 'access', _412 => _412.exec, 'call', _413 => _413(s.id), 'optionalAccess', _414 => _414[1]]), () => ( 0)));
6577
+ const n = Number(_nullishCoalesce(_optionalChain([/^s(\d+)$/, 'access', _415 => _415.exec, 'call', _416 => _416(s.id), 'optionalAccess', _417 => _417[1]]), () => ( 0)));
6540
6578
  if (n >= this.strokeCounter) this.strokeCounter = n + 1;
6541
6579
  }
6542
6580
  }
@@ -6551,6 +6589,8 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
6551
6589
  delete this.extensions.paperEffect;
6552
6590
  this.viewCompositor.clear();
6553
6591
  this.emit();
6592
+ const refs = Object.values(_nullishCoalesce(this.doc.stickers, () => ( {}))).flatMap((list) => list.map((x) => x.ref));
6593
+ if (refs.some((r) => !_chunkZEYMKDYScjs.editorStampOf.call(void 0, r))) void this.prepareStickers(refs).catch(() => this.emit([]));
6554
6594
  return loaded.problems;
6555
6595
  }
6556
6596
  /** Opens a saved document (clears the history). Returns what could not be read. */
@@ -6574,7 +6614,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
6574
6614
  /** The canvas as PNG bytes (paper included by default; `scale` below 1 shrinks it). */
6575
6615
  exportPng(options = {}) {
6576
6616
  const img = this.scaled(options);
6577
- return _chunkOLNIPTB3cjs.encodePng.call(void 0, img.width, img.height, img.data);
6617
+ return _chunkW5M3J7PVcjs.encodePng.call(void 0, img.width, img.height, img.data);
6578
6618
  }
6579
6619
  scaled(options) {
6580
6620
  const full2 = this.compositePixels(options);
@@ -6625,16 +6665,16 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
6625
6665
  const merged = this.compositePixels({ paper: true }).data;
6626
6666
  const changed = /* @__PURE__ */ new Map();
6627
6667
  const toStandard = (layers2) => layers2.map((l) => {
6628
- const blend = l.blend === "pass-through" ? l.blend : _chunkOLNIPTB3cjs.standardBlendMode.call(void 0, l.blend);
6668
+ const blend = l.blend === "pass-through" ? l.blend : _chunk2VX55NFMcjs.standardBlendMode.call(void 0, l.blend);
6629
6669
  if (blend !== l.blend) changed.set(l.blend, [..._nullishCoalesce(changed.get(l.blend), () => ( [])), l.name]);
6630
6670
  const next = blend === l.blend ? l : { ...l, blend };
6631
6671
  return next.type === "group" ? { ...next, children: toStandard(next.children) } : next;
6632
6672
  });
6633
6673
  const layers = toStandard(dried);
6634
- const result = _chunkWVS5KQDHcjs.exportPsd.call(void 0, { width, height, layers: [paperLayer, ...layers], merged, resolution: dpi });
6674
+ const result = _chunkLP2MCSBEcjs.exportPsd.call(void 0, { width, height, layers: [paperLayer, ...layers], merged, resolution: dpi });
6635
6675
  for (const [mode, names] of changed) {
6636
- const label = _nullishCoalesce(_optionalChain([_chunkOLNIPTB3cjs.BLEND_MODES, 'access', _415 => _415.find, 'call', _416 => _416((m) => m.id === mode), 'optionalAccess', _417 => _417.label]), () => ( mode));
6637
- const std = _nullishCoalesce(_optionalChain([_chunkOLNIPTB3cjs.BLEND_MODES, 'access', _418 => _418.find, 'call', _419 => _419((m) => m.id === _chunkOLNIPTB3cjs.standardBlendMode.call(void 0, mode)), 'optionalAccess', _420 => _420.label]), () => ( _chunkOLNIPTB3cjs.standardBlendMode.call(void 0, mode)));
6676
+ const label = _nullishCoalesce(_optionalChain([_chunk2VX55NFMcjs.BLEND_MODES, 'access', _418 => _418.find, 'call', _419 => _419((m) => m.id === mode), 'optionalAccess', _420 => _420.label]), () => ( mode));
6677
+ const std = _nullishCoalesce(_optionalChain([_chunk2VX55NFMcjs.BLEND_MODES, 'access', _421 => _421.find, 'call', _422 => _422((m) => m.id === _chunk2VX55NFMcjs.standardBlendMode.call(void 0, mode)), 'optionalAccess', _423 => _423.label]), () => ( _chunk2VX55NFMcjs.standardBlendMode.call(void 0, mode)));
6638
6678
  const list = names.map((n) => `"${n}"`).join(", ");
6639
6679
  const one = names.length === 1;
6640
6680
  result.warnings.push(`${label} blending has no PSD equivalent; ${list} ${one ? "was" : "were"} written as ${std}, the nearest Photoshop mode, so ${one ? "it looks" : "they look"} different in Photoshop (the merged image is exact).`);
@@ -6650,7 +6690,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
6650
6690
  /** `render_preview` as a base64 PNG. */
6651
6691
  previewPngBase64(options = {}) {
6652
6692
  const img = this.renderPreview(options);
6653
- return { data: _chunkOLNIPTB3cjs.bytesToBase64.call(void 0, _chunkOLNIPTB3cjs.encodePng.call(void 0, img.width, img.height, img.data)), width: img.width, height: img.height };
6693
+ return { data: _chunkW5M3J7PVcjs.bytesToBase64.call(void 0, _chunkW5M3J7PVcjs.encodePng.call(void 0, img.width, img.height, img.data)), width: img.width, height: img.height };
6654
6694
  }
6655
6695
  // --- Guides --------------------------------------------------------------------
6656
6696
  setGuides(next) {
@@ -6688,17 +6728,17 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
6688
6728
  pixels = this.decodeImage(input.png.trim().startsWith("data:") ? input.png.trim() : `data:image/png;base64,${input.png.trim()}`, what);
6689
6729
  } else throw new PaintEditorError(`${what}: pass png (a PNG as base64 or a data URL) or pixels.`);
6690
6730
  if (pixels.width > MAX_IMAGE_SIDE || pixels.height > MAX_IMAGE_SIDE) throw new PaintEditorError(`${what} is ${pixels.width}\xD7${pixels.height}; the limit is ${MAX_IMAGE_SIDE} px per side.`);
6691
- const src = _chunkOLNIPTB3cjs.pngDataUrl.call(void 0, pixels.width, pixels.height, pixels.data);
6731
+ const src = _chunkW5M3J7PVcjs.pngDataUrl.call(void 0, pixels.width, pixels.height, pixels.data);
6692
6732
  this.imagePixels.set(src, pixels);
6693
6733
  return { src, pixels };
6694
6734
  }
6695
6735
  decodeImage(src, what = "Image") {
6696
6736
  const cached = this.imagePixels.get(src);
6697
6737
  if (cached) return cached;
6698
- const parsed = _chunkOLNIPTB3cjs.parseDataUrl.call(void 0, src);
6738
+ const parsed = _chunkW5M3J7PVcjs.parseDataUrl.call(void 0, src);
6699
6739
  if (!parsed) throw new PaintEditorError(`${what} is not a data URL or base64 PNG.`);
6700
6740
  try {
6701
- const png = _chunkOLNIPTB3cjs.decodePng.call(void 0, parsed.bytes);
6741
+ const png = _chunkW5M3J7PVcjs.decodePng.call(void 0, parsed.bytes);
6702
6742
  const px = { width: png.width, height: png.height, data: png.data };
6703
6743
  this.imagePixels.set(src, px);
6704
6744
  return px;
@@ -6756,7 +6796,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
6756
6796
  const { src, pixels } = this.importImage(options, "The reference image");
6757
6797
  const ref2 = {
6758
6798
  id: `ref${this.nextReferenceId++}`,
6759
- name: _optionalChain([options, 'access', _421 => _421.name, 'optionalAccess', _422 => _422.trim, 'call', _423 => _423()]) || `Reference ${this.guides.references.length + 1}`,
6799
+ name: _optionalChain([options, 'access', _424 => _424.name, 'optionalAccess', _425 => _425.trim, 'call', _426 => _426()]) || `Reference ${this.guides.references.length + 1}`,
6760
6800
  src,
6761
6801
  width: pixels.width,
6762
6802
  height: pixels.height,
@@ -6835,7 +6875,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
6835
6875
  try {
6836
6876
  const px = this.decodeImage(ref2.src, `Reference "${ref2.name}"`);
6837
6877
  guides.references.push({ id: ref2.id, name: String(_nullishCoalesce(ref2.name, () => ( ref2.id))), src: ref2.src, width: px.width, height: px.height, x: Number(ref2.x) || 0, y: Number(ref2.y) || 0, displayWidth: Number(ref2.displayWidth) || 240, visible: ref2.visible !== false });
6838
- const n = Number(_nullishCoalesce(_optionalChain([/^ref(\d+)$/, 'access', _424 => _424.exec, 'call', _425 => _425(ref2.id), 'optionalAccess', _426 => _426[1]]), () => ( 0)));
6878
+ const n = Number(_nullishCoalesce(_optionalChain([/^ref(\d+)$/, 'access', _427 => _427.exec, 'call', _428 => _428(ref2.id), 'optionalAccess', _429 => _429[1]]), () => ( 0)));
6839
6879
  if (n >= this.nextReferenceId) this.nextReferenceId = n + 1;
6840
6880
  } catch (e) {
6841
6881
  problems.push(e.message);
@@ -6846,7 +6886,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
6846
6886
  guides.stencils = [];
6847
6887
  r.stencils.forEach((raw2, i) => {
6848
6888
  try {
6849
- const id = typeof _optionalChain([raw2, 'optionalAccess', _427 => _427.id]) === "string" && /^stencil\d+$/.test(raw2.id) ? raw2.id : `stencil${this.nextStencilId}`;
6889
+ const id = typeof _optionalChain([raw2, 'optionalAccess', _430 => _430.id]) === "string" && /^stencil\d+$/.test(raw2.id) ? raw2.id : `stencil${this.nextStencilId}`;
6850
6890
  guides.stencils.push(normalizeStencil(raw2, id));
6851
6891
  const n = Number(id.slice(7));
6852
6892
  if (n >= this.nextStencilId) this.nextStencilId = n + 1;
@@ -6869,45 +6909,96 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
6869
6909
  /** The next free sticker number (ids `st<n>` are unique across the document). */
6870
6910
  nextStickerNumber(doc = this.doc) {
6871
6911
  let n = 0;
6872
- for (const list of Object.values(_nullishCoalesce(doc.stickers, () => ( {})))) for (const st of list) n = Math.max(n, Number(_nullishCoalesce(_optionalChain([/^st(\d+)$/, 'access', _428 => _428.exec, 'call', _429 => _429(st.id), 'optionalAccess', _430 => _430[1]]), () => ( 0))));
6912
+ for (const list of Object.values(_nullishCoalesce(doc.stickers, () => ( {})))) for (const st of list) n = Math.max(n, Number(_nullishCoalesce(_optionalChain([/^st(\d+)$/, 'access', _431 => _431.exec, 'call', _432 => _432(st.id), 'optionalAccess', _433 => _433[1]]), () => ( 0))));
6873
6913
  return n + 1;
6874
6914
  }
6875
6915
  stickerLayer(layerId) {
6876
6916
  const l = this.wetLayer(layerId, "edit the stickers of");
6877
- const stickers = _optionalChain([this, 'access', _431 => _431.doc, 'access', _432 => _432.stickers, 'optionalAccess', _433 => _433[l.id]]);
6917
+ const stickers = _optionalChain([this, 'access', _434 => _434.doc, 'access', _435 => _435.stickers, 'optionalAccess', _436 => _436[l.id]]);
6878
6918
  if (!stickers) throw new PaintEditorError(`Layer "${l.name}" has no stickers; spray some with a sticker brush (list_brushes category sticker).`);
6879
6919
  return { layer: l, stickers };
6880
6920
  }
6921
+ // --- The sticker library ---------------------------------------------------------
6922
+ /** The sticker library: the editor's own stamps unless a host set its own. */
6923
+ get stickersProvider() {
6924
+ return this.stickers.provider;
6925
+ }
6926
+ /**
6927
+ * Sets the sticker library (`null` goes back to the editor's own stamps, `editorStickers()`);
6928
+ * to offer both, pass `combineStickerProviders([editorStickers(), yours])`. Loaded art is
6929
+ * forgotten. Not an edit: no undo step.
6930
+ */
6931
+ setStickersProvider(provider) {
6932
+ if ((_nullishCoalesce(provider, () => ( this.stickers.fallback))) === this.stickers.provider) return;
6933
+ this.stickers.set(provider);
6934
+ this.stickerArt.clear();
6935
+ this.emit([]);
6936
+ }
6937
+ /**
6938
+ * Loads the art of `refs` (provider stickers; editor stamps need none) so sprays and placements
6939
+ * can draw them. Rejects with a `PaintEditorError` naming an unknown ref and the closest known
6940
+ * ones, or a sticker whose art failed. Emits when art arrives, so views redraw.
6941
+ */
6942
+ async prepareStickers(refs) {
6943
+ const list = [...new Set(refs.map((r) => this.readStickerRef(r)))].filter((r) => !_chunkZEYMKDYScjs.editorStampOf.call(void 0, r));
6944
+ try {
6945
+ await Promise.all(list.map((r) => this.stickerArt.ensure(this.stickers.provider, r, this.rasterizeSticker)));
6946
+ } catch (e) {
6947
+ throw new PaintEditorError(e instanceof Error ? e.message : String(e));
6948
+ } finally {
6949
+ if (list.length) this.emit([]);
6950
+ }
6951
+ }
6952
+ /** Whether a sticker's art is ready to draw: `ready` (always for editor stamps), `loading`, `failed` (with why) or `none`. */
6953
+ stickerArtStatus(ref2) {
6954
+ return this.stickerArt.status(this.readStickerRef(ref2));
6955
+ }
6956
+ readStickerRef(ref2) {
6957
+ try {
6958
+ return _chunkZEYMKDYScjs.normalizeStickerRef.call(void 0, ref2);
6959
+ } catch (e) {
6960
+ throw new PaintEditorError(e.message);
6961
+ }
6962
+ }
6963
+ /** Refuses to redraw stickers whose art has not loaded (they would vanish), naming them and what to call. */
6964
+ requireStickerArt(stickers) {
6965
+ const missing = [...new Set(stickers.filter((s) => !_chunkH4AOUUBEcjs.stickerStamp.call(void 0, s) && !this.stickerArt.get(s.ref)).map((s) => s.ref))];
6966
+ if (missing.length) {
6967
+ for (const r of missing) void this.stickerArt.ensure(this.stickers.provider, r, this.rasterizeSticker).then(() => this.emit([]), () => this.emit([]));
6968
+ throw new PaintEditorError(`The art for ${missing.map((r) => `"${r}"`).join(", ")} has not loaded yet; it is loading now (prepareStickers), so try again when it has.`);
6969
+ }
6970
+ }
6881
6971
  /** A layer's stickers, bottom first. */
6882
6972
  listStickers(layerId) {
6883
6973
  const id = _nullishCoalesce(layerId, () => ( this.doc.activeLayerId));
6884
6974
  if (!id) return [];
6885
6975
  this.requireLayer(id);
6886
- return (_nullishCoalesce(_optionalChain([this, 'access', _434 => _434.doc, 'access', _435 => _435.stickers, 'optionalAccess', _436 => _436[id]]), () => ( []))).map((s) => ({ ...s }));
6976
+ return (_nullishCoalesce(_optionalChain([this, 'access', _437 => _437.doc, 'access', _438 => _438.stickers, 'optionalAccess', _439 => _439[id]]), () => ( []))).map((s) => ({ ...s }));
6887
6977
  }
6888
6978
  /**
6889
6979
  * Replaces a layer's stickers and redraws its pixels from them (one undo step). With `dirty`,
6890
6980
  * only the tiles under those rects are redrawn.
6891
6981
  */
6892
6982
  commitStickers(label, layer, stickers, dirty) {
6893
- if (_chunkHB4ICNNAcjs.isLayerLocked.call(void 0, layer, "pixels")) throw new PaintEditorError(`Layer "${layer.name}" has its pixels locked; unlock it first.`);
6983
+ if (_chunkDPYAO5U6cjs.isLayerLocked.call(void 0, layer, "pixels")) throw new PaintEditorError(`Layer "${layer.name}" has its pixels locked; unlock it first.`);
6984
+ this.requireStickerArt(stickers);
6894
6985
  const before = _nullishCoalesce(this.previewBase(), () => ( this.doc));
6895
6986
  this.stickerPreview = null;
6896
6987
  const surface = this.redrawStickers(layer, stickers, dirty);
6897
- const doc = { ...this.doc, layers: _chunkHB4ICNNAcjs.mapLayer.call(void 0, this.doc.layers, layer.id, () => ({ ...layer, surface, offset: { x: 0, y: 0 } })), stickers: { ..._nullishCoalesce(this.doc.stickers, () => ( {})), [layer.id]: stickers } };
6988
+ const doc = { ...this.doc, layers: _chunkDPYAO5U6cjs.mapLayer.call(void 0, this.doc.layers, layer.id, () => ({ ...layer, surface, offset: { x: 0, y: 0 } })), stickers: { ..._nullishCoalesce(this.doc.stickers, () => ( {})), [layer.id]: stickers } };
6898
6989
  this.commit(label, this.withPaintEvent(doc, { kind: "stickers", layerId: layer.id, data: { stickers: stickers.map((s) => ({ ...s })) } }), before);
6899
6990
  }
6900
6991
  redrawStickers(layer, stickers, dirty) {
6901
6992
  const partial = dirty && !layer.offset.x && !layer.offset.y;
6902
- return partial ? _chunk6G6ZDDDBcjs.stickerSurface.call(void 0, stickers, layer.surface, dirty) : _chunk6G6ZDDDBcjs.stickerSurface.call(void 0, stickers);
6993
+ return partial ? _chunkH4AOUUBEcjs.stickerSurface.call(void 0, stickers, layer.surface, dirty, this.stickerArt.get) : _chunkH4AOUUBEcjs.stickerSurface.call(void 0, stickers, void 0, void 0, this.stickerArt.get);
6903
6994
  }
6904
6995
  /** The document from before the sticker preview on screen, or `null` when none is (anything else changed the document since). */
6905
6996
  previewBase() {
6906
- return _optionalChain([this, 'access', _437 => _437.stickerPreview, 'optionalAccess', _438 => _438.shown]) === this.doc ? this.stickerPreview.base : null;
6997
+ return _optionalChain([this, 'access', _440 => _440.stickerPreview, 'optionalAccess', _441 => _441.shown]) === this.doc ? this.stickerPreview.base : null;
6907
6998
  }
6908
6999
  readStickerUpdate(update) {
6909
7000
  try {
6910
- return _chunk6G6ZDDDBcjs.normalizeStickerUpdate.call(void 0, update);
7001
+ return _chunkH4AOUUBEcjs.normalizeStickerUpdate.call(void 0, update);
6911
7002
  } catch (e) {
6912
7003
  throw new PaintEditorError(e.message);
6913
7004
  }
@@ -6918,7 +7009,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
6918
7009
  const id = _nullishCoalesce(layerId, () => ( this.doc.activeLayerId));
6919
7010
  if (!id) return null;
6920
7011
  this.requireLayer(id);
6921
- const hit = _chunk6G6ZDDDBcjs.stickerAt.call(void 0, _nullishCoalesce(_optionalChain([this, 'access', _439 => _439.doc, 'access', _440 => _440.stickers, 'optionalAccess', _441 => _441[id]]), () => ( [])), x, y);
7012
+ const hit = _chunkH4AOUUBEcjs.stickerAt.call(void 0, _nullishCoalesce(_optionalChain([this, 'access', _442 => _442.doc, 'access', _443 => _443.stickers, 'optionalAccess', _444 => _444[id]]), () => ( [])), x, y, this.stickerArt.get);
6922
7013
  return hit ? { ...hit } : null;
6923
7014
  }
6924
7015
  /** Picks a sticker for the panel and canvas (`null` for none). Editor state, not an undo step. */
@@ -6934,15 +7025,15 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
6934
7025
  */
6935
7026
  previewSticker(layerId, id, update) {
6936
7027
  const { layer, stickers } = this.stickerLayer(layerId);
6937
- if (_chunkHB4ICNNAcjs.isLayerLocked.call(void 0, layer, "pixels")) throw new PaintEditorError(`Layer "${layer.name}" has its pixels locked; unlock it first.`);
7028
+ if (_chunkDPYAO5U6cjs.isLayerLocked.call(void 0, layer, "pixels")) throw new PaintEditorError(`Layer "${layer.name}" has its pixels locked; unlock it first.`);
6938
7029
  const i = stickers.findIndex((s) => s.id === id);
6939
7030
  if (i < 0) throw new PaintEditorError(`Layer "${layer.name}" has no sticker "${id}". Call list_stickers for the ids.`);
6940
7031
  const next = { ...stickers[i], ...this.readStickerUpdate(update) };
6941
7032
  const list = stickers.map((s, j) => j === i ? next : s);
6942
- const dirty = [_chunk6G6ZDDDBcjs.stickerRect.call(void 0, stickers[i]), _chunk6G6ZDDDBcjs.stickerRect.call(void 0, next)];
7033
+ const dirty = [_chunkH4AOUUBEcjs.stickerRect.call(void 0, stickers[i]), _chunkH4AOUUBEcjs.stickerRect.call(void 0, next)];
6943
7034
  const base = _nullishCoalesce(this.previewBase(), () => ( this.doc));
6944
7035
  const surface = this.redrawStickers(layer, list, dirty);
6945
- this.doc = { ...this.doc, layers: _chunkHB4ICNNAcjs.mapLayer.call(void 0, this.doc.layers, layer.id, () => ({ ...layer, surface, offset: { x: 0, y: 0 } })), stickers: { ..._nullishCoalesce(this.doc.stickers, () => ( {})), [layer.id]: list } };
7036
+ this.doc = { ...this.doc, layers: _chunkDPYAO5U6cjs.mapLayer.call(void 0, this.doc.layers, layer.id, () => ({ ...layer, surface, offset: { x: 0, y: 0 } })), stickers: { ..._nullishCoalesce(this.doc.stickers, () => ( {})), [layer.id]: list } };
6946
7037
  this.stickerPreview = { base, shown: this.doc };
6947
7038
  this.emit(dirty);
6948
7039
  return { ...next };
@@ -6962,7 +7053,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
6962
7053
  if (i < 0) throw new PaintEditorError(`Layer "${layer.name}" has no sticker "${id}". Call list_stickers for the ids.`);
6963
7054
  const u = this.readStickerUpdate(update);
6964
7055
  const next = { ...stickers[i], ...u };
6965
- this.commitStickers("Edit sticker", layer, stickers.map((s, j) => j === i ? next : s), [_chunk6G6ZDDDBcjs.stickerRect.call(void 0, stickers[i]), _chunk6G6ZDDDBcjs.stickerRect.call(void 0, next)]);
7056
+ this.commitStickers("Edit sticker", layer, stickers.map((s, j) => j === i ? next : s), [_chunkH4AOUUBEcjs.stickerRect.call(void 0, stickers[i]), _chunkH4AOUUBEcjs.stickerRect.call(void 0, next)]);
6966
7057
  return { ...next };
6967
7058
  }
6968
7059
  /**
@@ -6972,15 +7063,16 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
6972
7063
  */
6973
7064
  addStickers(layerId, input) {
6974
7065
  const layer = this.wetLayer(layerId, "add stickers to");
6975
- if (!input.length) throw new PaintEditorError("Pass at least one sticker (stamp, x, y).");
7066
+ if (!input.length) throw new PaintEditorError("Pass at least one sticker (ref, x, y).");
6976
7067
  if (input.length > MAX_ADD_STICKERS) throw new PaintEditorError(`At most ${MAX_ADD_STICKERS} stickers per call; split them over several calls.`);
6977
- const existing = _optionalChain([this, 'access', _442 => _442.doc, 'access', _443 => _443.stickers, 'optionalAccess', _444 => _444[layer.id]]);
6978
- if (!_optionalChain([existing, 'optionalAccess', _445 => _445.length])) {
7068
+ const existing = _optionalChain([this, 'access', _445 => _445.doc, 'access', _446 => _446.stickers, 'optionalAccess', _447 => _447[layer.id]]);
7069
+ if (!_optionalChain([existing, 'optionalAccess', _448 => _448.length])) {
6979
7070
  if (this.wet.wetLayerIds().includes(layer.id) || _chunk474IQG74cjs.contentBounds.call(void 0, layer.surface)) throw new PaintEditorError(`Layer "${layer.name}" already has paint; add stickers to an empty layer (add_layer) or a sticker layer so they stay editable.`);
6980
7071
  }
6981
7072
  let n = this.nextStickerNumber();
6982
7073
  const added = input.map((raw, i) => {
6983
- for (const k of ["stamp", "x", "y"]) if (raw[k] === void 0) throw new PaintEditorError(`Sticker ${i} needs ${k}.`);
7074
+ if (raw.ref === void 0 && raw.stamp === void 0) throw new PaintEditorError(`Sticker ${i} needs ref (a sticker ref from find_stickers, e.g. "editor:star").`);
7075
+ for (const k of ["x", "y"]) if (raw[k] === void 0) throw new PaintEditorError(`Sticker ${i} needs ${k}.`);
6984
7076
  let u;
6985
7077
  try {
6986
7078
  u = this.readStickerUpdate(raw);
@@ -6989,9 +7081,9 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
6989
7081
  }
6990
7082
  if (raw.seed !== void 0 && !Number.isInteger(raw.seed)) throw new PaintEditorError(`Sticker ${i}: seed must be a whole number.`);
6991
7083
  const id = n++;
6992
- return { id: `st${id}`, size: 48, rotation: 0, color: this.color, opacity: 1, seed: _nullishCoalesce(raw.seed, () => ( _chunkPQ3H2AANcjs.mix32.call(void 0, id * 2654435761 >>> 0) & 2147483647)), ...u };
7084
+ return { id: `st${id}`, size: 48, rotation: 0, color: this.color, opacity: 1, seed: _nullishCoalesce(raw.seed, () => ( _chunk3K6HWEXZcjs.mix32.call(void 0, id * 2654435761 >>> 0) & 2147483647)), ...u };
6993
7085
  });
6994
- this.commitStickers("Add stickers", layer, [..._nullishCoalesce(existing, () => ( [])), ...added], _optionalChain([existing, 'optionalAccess', _446 => _446.length]) ? added.map(_chunk6G6ZDDDBcjs.stickerRect) : void 0);
7086
+ this.commitStickers("Add stickers", layer, [..._nullishCoalesce(existing, () => ( [])), ...added], _optionalChain([existing, 'optionalAccess', _449 => _449.length]) ? added.map(_chunkH4AOUUBEcjs.stickerRect) : void 0);
6995
7087
  return added.map((s) => ({ ...s }));
6996
7088
  }
6997
7089
  /** Brings stickers to the top (`front`) or bottom of their layer (one undo step). */
@@ -7001,7 +7093,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
7001
7093
  const picked = stickers.filter((s) => ids.includes(s.id));
7002
7094
  const rest = stickers.filter((s) => !ids.includes(s.id));
7003
7095
  const next = to === "front" ? [...rest, ...picked] : [...picked, ...rest];
7004
- this.commitStickers("Arrange stickers", layer, next, picked.map(_chunk6G6ZDDDBcjs.stickerRect));
7096
+ this.commitStickers("Arrange stickers", layer, next, picked.map(_chunkH4AOUUBEcjs.stickerRect));
7005
7097
  return next.map((s) => s.id);
7006
7098
  }
7007
7099
  /** Deletes stickers (`ids`, or all of them on the layer) (one undo step). Returns the ids removed. */
@@ -7011,7 +7103,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
7011
7103
  for (const id of ids) if (!stickers.some((s) => s.id === id)) throw new PaintEditorError(`Layer "${layer.name}" has no sticker "${id}". Call list_stickers for the ids.`);
7012
7104
  }
7013
7105
  const removed = ids ? [...ids] : stickers.map((s) => s.id);
7014
- this.commitStickers("Remove stickers", layer, stickers.filter((s) => !removed.includes(s.id)), ids ? stickers.filter((s) => removed.includes(s.id)).map(_chunk6G6ZDDDBcjs.stickerRect) : void 0);
7106
+ this.commitStickers("Remove stickers", layer, stickers.filter((s) => !removed.includes(s.id)), ids ? stickers.filter((s) => removed.includes(s.id)).map(_chunkH4AOUUBEcjs.stickerRect) : void 0);
7015
7107
  return removed;
7016
7108
  }
7017
7109
  /** Sets a layer's stickers (replays). */
@@ -7030,20 +7122,20 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
7030
7122
  }
7031
7123
  liveStrokeLayer(layerId, what) {
7032
7124
  const l = this.wetLayer(layerId, what);
7033
- const strokes = _optionalChain([this, 'access', _447 => _447.doc, 'access', _448 => _448.liveStrokes, 'optionalAccess', _449 => _449[l.id]]);
7125
+ const strokes = _optionalChain([this, 'access', _450 => _450.doc, 'access', _451 => _451.liveStrokes, 'optionalAccess', _452 => _452[l.id]]);
7034
7126
  if (!strokes) throw new PaintEditorError(`Layer "${l.name}" is not a stroke layer; add one with add_layer {type: "strokes"} (or convert_to_stroke_layer on an empty layer), then paint on it.`);
7035
7127
  return { layer: l, strokes };
7036
7128
  }
7037
7129
  /** Whether a layer is a live stroke layer. */
7038
7130
  isLiveStrokeLayer(layerId) {
7039
- return Boolean(_optionalChain([this, 'access', _450 => _450.doc, 'access', _451 => _451.liveStrokes, 'optionalAccess', _452 => _452[layerId]]));
7131
+ return Boolean(_optionalChain([this, 'access', _453 => _453.doc, 'access', _454 => _454.liveStrokes, 'optionalAccess', _455 => _455[layerId]]));
7040
7132
  }
7041
7133
  /** Makes an empty pixel layer a live stroke layer (one undo step). */
7042
7134
  convertToLiveStrokes(layerId) {
7043
7135
  this.requireIdle("converting a layer");
7044
7136
  const l = this.paintTarget(layerId, "convert");
7045
- if (_optionalChain([this, 'access', _453 => _453.doc, 'access', _454 => _454.liveStrokes, 'optionalAccess', _455 => _455[l.id]])) return this.describeLayer(l);
7046
- if (_optionalChain([this, 'access', _456 => _456.doc, 'access', _457 => _457.stickers, 'optionalAccess', _458 => _458[l.id], 'optionalAccess', _459 => _459.length])) throw new PaintEditorError(`Layer "${l.name}" is a sticker layer; add a stroke layer instead (add_layer {type: "strokes"}).`);
7137
+ if (_optionalChain([this, 'access', _456 => _456.doc, 'access', _457 => _457.liveStrokes, 'optionalAccess', _458 => _458[l.id]])) return this.describeLayer(l);
7138
+ if (_optionalChain([this, 'access', _459 => _459.doc, 'access', _460 => _460.stickers, 'optionalAccess', _461 => _461[l.id], 'optionalAccess', _462 => _462.length])) throw new PaintEditorError(`Layer "${l.name}" is a sticker layer; add a stroke layer instead (add_layer {type: "strokes"}).`);
7047
7139
  if (_chunk474IQG74cjs.contentBounds.call(void 0, l.surface) || this.wet.wetLayerIds().includes(l.id)) throw new PaintEditorError(`Layer "${l.name}" already has paint, which isn't kept as strokes; convert an empty layer or add a stroke layer (add_layer {type: "strokes"}).`);
7048
7140
  this.commit("Convert to stroke layer", { ...this.doc, liveStrokes: { ..._nullishCoalesce(this.doc.liveStrokes, () => ( {})), [l.id]: [] } });
7049
7141
  return this.describeLayer(this.getLayer(l.id));
@@ -7056,7 +7148,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
7056
7148
  findLiveStroke(id) {
7057
7149
  for (const [layerId, strokes] of Object.entries(_nullishCoalesce(this.doc.liveStrokes, () => ( {})))) {
7058
7150
  const index = strokes.findIndex((x) => x.id === id);
7059
- const layer = _optionalChain([_chunkHB4ICNNAcjs.findLayer.call(void 0, this.doc.layers, layerId), 'optionalAccess', _460 => _460.layer]);
7151
+ const layer = _optionalChain([_chunkDPYAO5U6cjs.findLayer.call(void 0, this.doc.layers, layerId), 'optionalAccess', _463 => _463.layer]);
7060
7152
  if (index >= 0 && isPixelLayer(layer)) return { layer, strokes, index };
7061
7153
  }
7062
7154
  const baked = this.doc.strokes.some((x) => x.id === id);
@@ -7076,15 +7168,15 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
7076
7168
  let brush = was.brush;
7077
7169
  if (update.brushId !== void 0) {
7078
7170
  const b = this.requireBrush(update.brushId);
7079
- brush = _chunk6G6ZDDDBcjs.normalizePaintBrush.call(void 0, { tip: { ...b.tip, size: was.brush.tip.size } }, b);
7171
+ brush = _chunkH4AOUUBEcjs.normalizePaintBrush.call(void 0, { tip: { ...b.tip, size: was.brush.tip.size } }, b);
7080
7172
  }
7081
7173
  if (update.brush !== void 0) {
7082
7174
  if (!update.brush || typeof update.brush !== "object") throw new PaintEditorError("brush must be an object of brush settings (as set_brush takes).");
7083
- brush = _chunk6G6ZDDDBcjs.normalizePaintBrush.call(void 0, { ...update.brush, id: brush.id }, brush);
7175
+ brush = _chunkH4AOUUBEcjs.normalizePaintBrush.call(void 0, { ...update.brush, id: brush.id }, brush);
7084
7176
  }
7085
7177
  const why = liveStrokeRefusal(brush);
7086
7178
  if (why) throw new PaintEditorError(why);
7087
- const next = { ...was, brush: _chunk6G6ZDDDBcjs.brushToJSON.call(void 0, brush) };
7179
+ const next = { ...was, brush: _chunkH4AOUUBEcjs.brushToJSON.call(void 0, brush) };
7088
7180
  if (update.seed !== void 0) {
7089
7181
  if (!Number.isInteger(update.seed) || update.seed < 0) throw new PaintEditorError(`seed ${update.seed} must be a whole number of 0 or more.`);
7090
7182
  next.seed = update.seed;
@@ -7095,7 +7187,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
7095
7187
  }
7096
7188
  if (update.paint !== void 0) {
7097
7189
  if (update.paint === null) delete next.paint;
7098
- else if (_chunk6G6ZDDDBcjs.isPaintEffectPaint.call(void 0, update.paint)) {
7190
+ else if (_chunkH4AOUUBEcjs.isPaintEffectPaint.call(void 0, update.paint)) {
7099
7191
  if (!this.effectPaintImage(update.paint)) throw new PaintEditorError(`The effect "${update.paint.effect}" is not rendered yet; render it first (prepareEffectPaints; the update_stroke tool does this).`);
7100
7192
  next.paint = JSON.parse(JSON.stringify(update.paint));
7101
7193
  } else {
@@ -7106,8 +7198,8 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
7106
7198
  } else next.paint = JSON.parse(JSON.stringify(p));
7107
7199
  }
7108
7200
  }
7109
- const rgb = _chunk6G6ZDDDBcjs.hexToRgb8.call(void 0, next.color).map((v) => v / 255);
7110
- const load = brushLoadForStroke(brush, _chunkPQ3H2AANcjs.EMPTY_MIXER_LOAD, rgb);
7201
+ const rgb = _chunkH4AOUUBEcjs.hexToRgb8.call(void 0, next.color).map((v) => v / 255);
7202
+ const load = brushLoadForStroke(brush, _chunkI7NJPHWVcjs.EMPTY_MIXER_LOAD, rgb);
7111
7203
  if (load.reservoir || load.pickup) next.load = load;
7112
7204
  else delete next.load;
7113
7205
  const list = strokes.map((x, i) => i === index ? next : x);
@@ -7151,9 +7243,9 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
7151
7243
  const layers = /* @__PURE__ */ new Map();
7152
7244
  for (const f of found) layers.set(f.layer.id, f.layer);
7153
7245
  for (const [layerId, layer] of layers) {
7154
- const gone = (_nullishCoalesce(_optionalChain([doc, 'access', _461 => _461.liveStrokes, 'optionalAccess', _462 => _462[layerId]]), () => ( []))).filter((x) => ids.includes(x.id));
7246
+ const gone = (_nullishCoalesce(_optionalChain([doc, 'access', _464 => _464.liveStrokes, 'optionalAccess', _465 => _465[layerId]]), () => ( []))).filter((x) => ids.includes(x.id));
7155
7247
  for (const x of gone) bounds = unionRect(bounds, this.strokeArea(x));
7156
- doc = this.withLiveStrokes(doc, layer, (_nullishCoalesce(_optionalChain([doc, 'access', _463 => _463.liveStrokes, 'optionalAccess', _464 => _464[layerId]]), () => ( []))).filter((x) => !ids.includes(x.id)), this.strokeAreas(gone));
7248
+ doc = this.withLiveStrokes(doc, layer, (_nullishCoalesce(_optionalChain([doc, 'access', _466 => _466.liveStrokes, 'optionalAccess', _467 => _467[layerId]]), () => ( []))).filter((x) => !ids.includes(x.id)), this.strokeAreas(gone));
7157
7249
  }
7158
7250
  this.commit(ids.length === 1 ? "Remove stroke" : "Remove strokes", doc);
7159
7251
  return { removed: [...ids], bounds };
@@ -7220,10 +7312,10 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
7220
7312
  this.commit(label, this.withLiveStrokes(this.doc, layer, list, dirty));
7221
7313
  }
7222
7314
  withLiveStrokes(doc, layer, list, dirty) {
7223
- if (_chunkHB4ICNNAcjs.isLayerLocked.call(void 0, layer, "pixels")) throw new PaintEditorError(`Layer "${layer.name}" has its pixels locked; unlock it (update_layer locks) first.`);
7224
- const current = _optionalChain([_chunkHB4ICNNAcjs.findLayer.call(void 0, doc.layers, layer.id), 'optionalAccess', _465 => _465.layer]);
7315
+ if (_chunkDPYAO5U6cjs.isLayerLocked.call(void 0, layer, "pixels")) throw new PaintEditorError(`Layer "${layer.name}" has its pixels locked; unlock it (update_layer locks) first.`);
7316
+ const current = _optionalChain([_chunkDPYAO5U6cjs.findLayer.call(void 0, doc.layers, layer.id), 'optionalAccess', _468 => _468.layer]);
7225
7317
  const surface = this.drawLiveStrokes(_nullishCoalesce(current, () => ( layer)), list, dirty);
7226
- const next = { ...doc, layers: _chunkHB4ICNNAcjs.mapLayer.call(void 0, doc.layers, layer.id, (l) => ({ ...l, surface, offset: { x: 0, y: 0 } })), liveStrokes: { ..._nullishCoalesce(doc.liveStrokes, () => ( {})), [layer.id]: [...list] } };
7318
+ const next = { ...doc, layers: _chunkDPYAO5U6cjs.mapLayer.call(void 0, doc.layers, layer.id, (l) => ({ ...l, surface, offset: { x: 0, y: 0 } })), liveStrokes: { ..._nullishCoalesce(doc.liveStrokes, () => ( {})), [layer.id]: [...list] } };
7227
7319
  return this.withPaintEvent(next, { kind: "live-strokes", layerId: layer.id, data: { strokes: list.map((x) => JSON.parse(JSON.stringify(x))) } });
7228
7320
  }
7229
7321
  /** Where a stroke painted (document pixels): as learnt when it was painted or drawn, else an estimate from its points and brush. */
@@ -7252,7 +7344,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
7252
7344
  };
7253
7345
  const paint = st.paint && this.liveEffectAt !== null && isLiveEffect(st) ? framePaint(st.paint, this.liveEffectAt) : st.paint;
7254
7346
  const init = { layerId: plain.id, color: st.color, brush: st.brush, seed: st.seed, copies: _nullishCoalesce(st.copies, () => ( [])), ...st.load ? { load: st.load } : {}, ...paint ? { paint } : {}, snapToPerspective: false, stencils: false, maskStencils: _nullishCoalesce(st.stencils, () => ( [])) };
7255
- const session = this.sessionFor({ ...doc, layers: _chunkHB4ICNNAcjs.mapLayer.call(void 0, doc.layers, plain.id, () => ({ ...plain, surface })) }, init, host);
7347
+ const session = this.sessionFor({ ...doc, layers: _chunkDPYAO5U6cjs.mapLayer.call(void 0, doc.layers, plain.id, () => ({ ...plain, surface })) }, init, host);
7256
7348
  session.push(st.points);
7257
7349
  const result = session.end();
7258
7350
  const had = this.paintedBounds.get(st);
@@ -7299,8 +7391,8 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
7299
7391
  if (!this.animatedLayers.size) return this.doc.layers;
7300
7392
  let layers = this.doc.layers;
7301
7393
  for (const [id, a] of this.animatedLayers) {
7302
- const l = _optionalChain([_chunkHB4ICNNAcjs.findLayer.call(void 0, layers, id), 'optionalAccess', _466 => _466.layer]);
7303
- if (isPixelLayer(l) && l.surface === a.base) layers = _chunkHB4ICNNAcjs.mapLayer.call(void 0, layers, id, () => ({ ...l, surface: a.surface }));
7394
+ const l = _optionalChain([_chunkDPYAO5U6cjs.findLayer.call(void 0, layers, id), 'optionalAccess', _469 => _469.layer]);
7395
+ if (isPixelLayer(l) && l.surface === a.base) layers = _chunkDPYAO5U6cjs.mapLayer.call(void 0, layers, id, () => ({ ...l, surface: a.surface }));
7304
7396
  }
7305
7397
  return layers;
7306
7398
  }
@@ -7309,11 +7401,11 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
7309
7401
  const layers = [];
7310
7402
  const sources = /* @__PURE__ */ new Map();
7311
7403
  for (const [id, strokes] of Object.entries(_nullishCoalesce(doc.liveStrokes, () => ( {})))) {
7312
- const layer = _optionalChain([_chunkHB4ICNNAcjs.findLayer.call(void 0, doc.layers, id), 'optionalAccess', _467 => _467.layer]);
7404
+ const layer = _optionalChain([_chunkDPYAO5U6cjs.findLayer.call(void 0, doc.layers, id), 'optionalAccess', _470 => _470.layer]);
7313
7405
  const live = strokes.filter(isLiveEffect);
7314
7406
  if (!isPixelLayer(layer) || !live.length) continue;
7315
7407
  layers.push({ layer, strokes });
7316
- for (const st of live) sources.set(_chunk6G6ZDDDBcjs.effectPaintKey.call(void 0, st.paint), st.paint);
7408
+ for (const st of live) sources.set(_chunkH4AOUUBEcjs.effectPaintKey.call(void 0, st.paint), st.paint);
7317
7409
  }
7318
7410
  return { layers, sources: [...sources.values()] };
7319
7411
  }
@@ -7434,13 +7526,13 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
7434
7526
  return this.withEffectTime(time, () => this.compositePixels(options));
7435
7527
  }
7436
7528
  // --- Stencils --------------------------------------------------------------------
7437
- __init135() {this.stencilCache = null}
7438
- __init136() {this.nextStencilId = 1}
7529
+ __init137() {this.stencilCache = null}
7530
+ __init138() {this.nextStencilId = 1}
7439
7531
  /** The mask stencils' coverage over the canvas (cached), or `null` when none masks. */
7440
7532
  stencilSelection(stencils = this.guides.stencils) {
7441
7533
  const { width, height } = this.doc.canvas;
7442
7534
  const size = `${width}x${height}`;
7443
- if (_optionalChain([this, 'access', _468 => _468.stencilCache, 'optionalAccess', _469 => _469.key]) === stencils && this.stencilCache.size === size) return this.stencilCache.mask;
7535
+ if (_optionalChain([this, 'access', _471 => _471.stencilCache, 'optionalAccess', _472 => _472.key]) === stencils && this.stencilCache.size === size) return this.stencilCache.mask;
7444
7536
  const mask = stencilMask(stencils, width, height);
7445
7537
  this.stencilCache = { key: stencils, size, mask };
7446
7538
  return mask;
@@ -7501,8 +7593,8 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
7501
7593
  }
7502
7594
  makeSwatch(color, name) {
7503
7595
  const p = typeof color === "string" ? { type: "color", color: parseColor(color) } : this.readStrokePaint(color);
7504
- const out = { color: _chunkPQ3H2AANcjs.paintSourceColor.call(void 0, p, { paint: this.color, secondary: this.secondaryColor }) };
7505
- if (_optionalChain([name, 'optionalAccess', _470 => _470.trim, 'call', _471 => _471()])) out.name = name.trim();
7596
+ const out = { color: _chunkI7NJPHWVcjs.paintSourceColor.call(void 0, p, { paint: this.color, secondary: this.secondaryColor }) };
7597
+ if (_optionalChain([name, 'optionalAccess', _473 => _473.trim, 'call', _474 => _474()])) out.name = name.trim();
7506
7598
  if (p.type === "gradient") out.paint = p;
7507
7599
  return out;
7508
7600
  }
@@ -7554,7 +7646,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
7554
7646
  * mix becomes the paint colour. Returns the mixed colour and the pile's bounds.
7555
7647
  */
7556
7648
  mixOnPad(paints, options = {}) {
7557
- const parsed = (_nullishCoalesce(paints, () => ( []))).map((p, i) => ({ color: parseColor(_optionalChain([p, 'optionalAccess', _472 => _472.color]), `paints[${i}].color`), parts: _optionalChain([p, 'optionalAccess', _473 => _473.parts]) }));
7649
+ const parsed = (_nullishCoalesce(paints, () => ( []))).map((p, i) => ({ color: parseColor(_optionalChain([p, 'optionalAccess', _475 => _475.color]), `paints[${i}].color`), parts: _optionalChain([p, 'optionalAccess', _476 => _476.parts]) }));
7558
7650
  let r;
7559
7651
  try {
7560
7652
  r = this.pad.mix(parsed, options);
@@ -7643,7 +7735,7 @@ var PaintEditorController = (_class12 = class _PaintEditorController {
7643
7735
  }
7644
7736
  /** A layer's tile surface (live while stroking), for thumbnails. */
7645
7737
  layerSurface(id) {
7646
- const l = _optionalChain([_chunkHB4ICNNAcjs.findLayer.call(void 0, this.currentLayers(), id), 'optionalAccess', _474 => _474.layer]);
7738
+ const l = _optionalChain([_chunkDPYAO5U6cjs.findLayer.call(void 0, this.currentLayers(), id), 'optionalAccess', _477 => _477.layer]);
7647
7739
  return isPixelLayer(l) ? l.surface : null;
7648
7740
  }
7649
7741
  }, _class12.__initStatic(), _class12);
@@ -7665,7 +7757,7 @@ function insertAfter(layers, id, node) {
7665
7757
  return layers.map((l) => l.type === "group" ? { ...l, children: insertAfter(l.children, id, node) } : l);
7666
7758
  }
7667
7759
  function isLiveEffect(s) {
7668
- return _optionalChain([s, 'access', _475 => _475.paint, 'optionalAccess', _476 => _476.type]) === "effect" && s.paint.live === true;
7760
+ return _optionalChain([s, 'access', _478 => _478.paint, 'optionalAccess', _479 => _479.type]) === "effect" && s.paint.live === true;
7669
7761
  }
7670
7762
  function framePaint(p, t) {
7671
7763
  return { ...p, time: p.time + t };
@@ -7690,13 +7782,13 @@ function clipRect(r, width, height) {
7690
7782
  return x1 > x0 && y1 > y0 ? { x: x0, y: y0, width: x1 - x0, height: y1 - y0 } : null;
7691
7783
  }
7692
7784
  function withLiveStroke(doc, stroke) {
7693
- const list = _optionalChain([doc, 'access', _477 => _477.liveStrokes, 'optionalAccess', _478 => _478[stroke.layerId]]);
7785
+ const list = _optionalChain([doc, 'access', _480 => _480.liveStrokes, 'optionalAccess', _481 => _481[stroke.layerId]]);
7694
7786
  return list ? { ...doc, liveStrokes: { ...doc.liveStrokes, [stroke.layerId]: [...list, stroke] } } : doc;
7695
7787
  }
7696
7788
  function shiftDocument(doc, dx, dy) {
7697
7789
  if (!dx && !dy) return doc;
7698
7790
  let layers = doc.layers;
7699
- for (const l of _chunkHB4ICNNAcjs.flattenLayers.call(void 0, doc.layers)) if (l.type === "pixel") layers = _chunkHB4ICNNAcjs.mapLayer.call(void 0, layers, l.id, () => ({ ...l, offset: movePoint(l.offset, dx, dy) }));
7791
+ for (const l of _chunkDPYAO5U6cjs.flattenLayers.call(void 0, doc.layers)) if (l.type === "pixel") layers = _chunkDPYAO5U6cjs.mapLayer.call(void 0, layers, l.id, () => ({ ...l, offset: movePoint(l.offset, dx, dy) }));
7700
7792
  const m = [1, 0, 0, 1, dx, dy];
7701
7793
  const moveStickers = (list) => list.map((s) => ({ ...s, x: Math.round((s.x + dx) * 100) / 100, y: Math.round((s.y + dy) * 100) / 100 }));
7702
7794
  const out = {
@@ -7717,9 +7809,9 @@ function shiftDocument(doc, dx, dy) {
7717
7809
  if (doc.liveStrokes) out.liveStrokes = Object.fromEntries(Object.entries(doc.liveStrokes).map(([id, list]) => [id, list.map(moveStroke)]));
7718
7810
  if (doc.paintEvents) {
7719
7811
  out.paintEvents = doc.paintEvents.map((e) => {
7720
- const list = e.kind === "stickers" ? _optionalChain([e, 'access', _479 => _479.data, 'optionalAccess', _480 => _480.stickers]) : void 0;
7812
+ const list = e.kind === "stickers" ? _optionalChain([e, 'access', _482 => _482.data, 'optionalAccess', _483 => _483.stickers]) : void 0;
7721
7813
  if (list) return { ...e, data: { ...e.data, stickers: moveStickers(list) } };
7722
- const strokes = e.kind === "live-strokes" ? _optionalChain([e, 'access', _481 => _481.data, 'optionalAccess', _482 => _482.strokes]) : void 0;
7814
+ const strokes = e.kind === "live-strokes" ? _optionalChain([e, 'access', _484 => _484.data, 'optionalAccess', _485 => _485.strokes]) : void 0;
7723
7815
  return strokes ? { ...e, data: { ...e.data, strokes: strokes.map(moveStroke) } } : e;
7724
7816
  });
7725
7817
  }
@@ -7801,8 +7893,8 @@ function strokeSchedule(points) {
7801
7893
  return total > 0 ? acc.map((d) => d / total) : points.map(() => 1);
7802
7894
  }
7803
7895
  function strokeDuration(points, max = 1800) {
7804
- const t0 = _optionalChain([points, 'access', _483 => _483[0], 'optionalAccess', _484 => _484.t]);
7805
- const t1 = _optionalChain([points, 'access', _485 => _485[points.length - 1], 'optionalAccess', _486 => _486.t]);
7896
+ const t0 = _optionalChain([points, 'access', _486 => _486[0], 'optionalAccess', _487 => _487.t]);
7897
+ const t1 = _optionalChain([points, 'access', _488 => _488[points.length - 1], 'optionalAccess', _489 => _489.t]);
7806
7898
  let ms;
7807
7899
  if (points.every((p) => Number.isFinite(p.t)) && t1 > t0) ms = t1 - t0;
7808
7900
  else {
@@ -7856,7 +7948,7 @@ var PaintDirector = class {
7856
7948
  }
7857
7949
  where(id) {
7858
7950
  const a = this.presence.get(id);
7859
- return { x: _nullishCoalesce(_optionalChain([a, 'optionalAccess', _487 => _487.x]), () => ( 0)), y: _nullishCoalesce(_optionalChain([a, 'optionalAccess', _488 => _488.y]), () => ( 0)) };
7951
+ return { x: _nullishCoalesce(_optionalChain([a, 'optionalAccess', _490 => _490.x]), () => ( 0)), y: _nullishCoalesce(_optionalChain([a, 'optionalAccess', _491 => _491.y]), () => ( 0)) };
7860
7952
  }
7861
7953
  /** Glides to `to`; an actor that just appeared starts there instead of the corner. */
7862
7954
  async glide(id, to, ms = 380) {
@@ -7903,8 +7995,8 @@ var PaintDirector = class {
7903
7995
  }
7904
7996
  case "replay": {
7905
7997
  await this.say(id, command.note, 500);
7906
- const source = c.getStrokes().filter((s) => _optionalChain([command, 'access', _489 => _489.replay, 'access', _490 => _490.strokeIds, 'optionalAccess', _491 => _491.includes, 'call', _492 => _492(s.id)]));
7907
- const first = _optionalChain([source, 'access', _493 => _493[0], 'optionalAccess', _494 => _494.points, 'access', _495 => _495[0]]);
7998
+ const source = c.getStrokes().filter((s) => _optionalChain([command, 'access', _492 => _492.replay, 'access', _493 => _493.strokeIds, 'optionalAccess', _494 => _494.includes, 'call', _495 => _495(s.id)]));
7999
+ const first = _optionalChain([source, 'access', _496 => _496[0], 'optionalAccess', _497 => _497.points, 'access', _498 => _498[0]]);
7908
8000
  if (first) await this.glide(id, first);
7909
8001
  const result = c.replayStrokes(command.replay);
7910
8002
  if (result.bounds) await this.glide(id, centre(result.bounds), 520);
@@ -8045,7 +8137,7 @@ function createPaintStickerTools(c) {
8045
8137
  {
8046
8138
  name: "list_stickers",
8047
8139
  title: "List stickers",
8048
- description: "Lists a layer\u2019s stickers bottom first: id, stamp, x, y (centre, document pixels), size (diameter px), rotation (degrees clockwise), color, opacity. Empty for a layer without stickers. Changes nothing.",
8140
+ description: "Lists a layer\u2019s stickers bottom first: id, ref (provider:id; stamp too for the editor\u2019s own), x, y (centre, document pixels), size (diameter px), rotation (degrees clockwise), color, opacity. Empty for a layer without stickers. Changes nothing.",
8049
8141
  inputSchema: { type: "object", properties: { layerId: LAYER_ID }, additionalProperties: false },
8050
8142
  annotations: { title: "List stickers", ...READ },
8051
8143
  coordinates: { out: ["stickers[]"] },
@@ -8072,7 +8164,7 @@ function createPaintStickerTools(c) {
8072
8164
  {
8073
8165
  name: "add_stickers",
8074
8166
  title: "Place stickers",
8075
- description: "Places stickers exactly where you say, on top of a sticker layer or onto an empty layer (which becomes a sticker layer). Use it for deliberate placement; spray with paint_stroke and a sticker brush for a random scatter. One undo step. Returns the new stickers with their ids, for update_sticker, arrange_stickers and remove_stickers.",
8167
+ description: "Places stickers exactly where you say, on top of a sticker layer or onto an empty layer (which becomes a sticker layer): any sticker from the sticker library by ref (find_stickers), its art loaded first; tintable ones take color. Use it for deliberate placement; spray with paint_stroke and a sticker brush for a random scatter. An unknown ref is refused with the closest ones. One undo step. Returns the new stickers with their ids, for update_sticker, arrange_stickers and remove_stickers.",
8076
8168
  inputSchema: {
8077
8169
  type: "object",
8078
8170
  properties: {
@@ -8085,7 +8177,8 @@ function createPaintStickerTools(c) {
8085
8177
  items: {
8086
8178
  type: "object",
8087
8179
  properties: {
8088
- stamp: { type: "string", enum: [..._chunk6G6ZDDDBcjs.STAMP_KINDS], description: "The stamp." },
8180
+ ref: { type: "string", minLength: 1, description: "The sticker: a ref provider:id from find_stickers (e.g. editor:star). Give ref or stamp." },
8181
+ stamp: { type: "string", enum: [..._chunkZEYMKDYScjs.STAMP_KINDS], description: "Older form: an editor stamp (same as ref editor:<stamp>)." },
8089
8182
  x: { type: "number", description: "Centre x in document pixels." },
8090
8183
  y: { type: "number", description: "Centre y in document pixels." },
8091
8184
  size: { type: "number", minimum: 2, maximum: 2048, description: "Diameter in pixels (default 48)." },
@@ -8094,7 +8187,7 @@ function createPaintStickerTools(c) {
8094
8187
  opacity: { type: "number", minimum: 0, maximum: 1, description: "Opacity 0..1 (default 1)." },
8095
8188
  seed: { type: "integer", minimum: 0, description: "Texture seed (default from the new id); splat and confetti shapes vary with it." }
8096
8189
  },
8097
- required: ["stamp", "x", "y"],
8190
+ required: ["x", "y"],
8098
8191
  additionalProperties: false
8099
8192
  }
8100
8193
  }
@@ -8104,7 +8197,14 @@ function createPaintStickerTools(c) {
8104
8197
  },
8105
8198
  annotations: { title: "Place stickers", ...WRITE },
8106
8199
  coordinates: { in: ["stickers[]"], out: ["stickers[]"] },
8107
- handler: ({ layerId, stickers }) => ({ layerId: _nullishCoalesce(layerId, () => ( c.document.activeLayerId)), stickers: c.addStickers(layerId, stickers) })
8200
+ handler: async ({ layerId, stickers }) => {
8201
+ const list = stickers;
8202
+ list.forEach((x, i) => {
8203
+ if (x.ref === void 0 && x.stamp === void 0) throw new Error(`Sticker ${i} needs ref (a sticker ref from find_stickers, e.g. "editor:star").`);
8204
+ });
8205
+ await c.prepareStickers(list.map((x) => _nullishCoalesce(x.ref, () => ( `editor:${x.stamp}`))));
8206
+ return { layerId: _nullishCoalesce(layerId, () => ( c.document.activeLayerId)), stickers: c.addStickers(layerId, list) };
8207
+ }
8108
8208
  },
8109
8209
  {
8110
8210
  name: "update_sticker",
@@ -8115,7 +8215,8 @@ function createPaintStickerTools(c) {
8115
8215
  properties: {
8116
8216
  layerId: LAYER_ID,
8117
8217
  id: { type: "string", description: "Sticker id from list_stickers." },
8118
- stamp: { type: "string", enum: [..._chunk6G6ZDDDBcjs.STAMP_KINDS], description: "Another stamp." },
8218
+ ref: { type: "string", minLength: 1, description: "Another sticker: a ref provider:id from find_stickers." },
8219
+ stamp: { type: "string", enum: [..._chunkZEYMKDYScjs.STAMP_KINDS], description: "Older form: another editor stamp (same as ref editor:<stamp>)." },
8119
8220
  x: { type: "number", description: "Centre x in document pixels." },
8120
8221
  y: { type: "number", description: "Centre y in document pixels." },
8121
8222
  size: { type: "number", minimum: 2, maximum: 2048, description: "Diameter in pixels." },
@@ -8128,7 +8229,11 @@ function createPaintStickerTools(c) {
8128
8229
  },
8129
8230
  annotations: { title: "Change a sticker", ...WRITE },
8130
8231
  coordinates: { in: [""], out: [""] },
8131
- handler: ({ layerId, id, ...update }) => c.updateSticker(layerId, id, update)
8232
+ handler: async ({ layerId, id, ...update }) => {
8233
+ const refs = c.listStickers(layerId).map((s) => s.ref);
8234
+ await c.prepareStickers(update.ref ? [...refs, update.ref] : refs);
8235
+ return c.updateSticker(layerId, id, update);
8236
+ }
8132
8237
  },
8133
8238
  {
8134
8239
  name: "arrange_stickers",
@@ -8145,7 +8250,10 @@ function createPaintStickerTools(c) {
8145
8250
  additionalProperties: false
8146
8251
  },
8147
8252
  annotations: { title: "Bring stickers forward or back", ...WRITE },
8148
- handler: ({ layerId, ids, to }) => ({ order: c.arrangeStickers(layerId, ids, to) })
8253
+ handler: async ({ layerId, ids, to }) => {
8254
+ await c.prepareStickers(c.listStickers(layerId).map((s) => s.ref));
8255
+ return { order: c.arrangeStickers(layerId, ids, to) };
8256
+ }
8149
8257
  },
8150
8258
  {
8151
8259
  name: "remove_stickers",
@@ -8153,7 +8261,10 @@ function createPaintStickerTools(c) {
8153
8261
  description: "Deletes stickers by id, or every sticker on the layer when ids is missing. One undo step. Returns the ids removed.",
8154
8262
  inputSchema: { type: "object", properties: { layerId: LAYER_ID, ids: { type: "array", items: { type: "string", description: "Sticker id." }, description: "Sticker ids (default all)." } }, additionalProperties: false },
8155
8263
  annotations: { title: "Delete stickers", ...DESTRUCTIVE },
8156
- handler: ({ layerId, ids }) => ({ removed: c.removeStickers(layerId, ids) })
8264
+ handler: async ({ layerId, ids }) => {
8265
+ await c.prepareStickers(c.listStickers(layerId).map((s) => s.ref));
8266
+ return { removed: c.removeStickers(layerId, ids) };
8267
+ }
8157
8268
  }
8158
8269
  ];
8159
8270
  }
@@ -8419,7 +8530,7 @@ function createPaintGuideTools(c) {
8419
8530
  type: "object",
8420
8531
  properties: {
8421
8532
  color: { ...COLOR2, description: "A colour #rrggbb." },
8422
- paint: { ..._chunkPQ3H2AANcjs.PAINT_SOURCE_JSON_SCHEMA, description: "Gradient paint (or a colour) for the swatch, instead of color." },
8533
+ paint: { ..._chunkI7NJPHWVcjs.PAINT_SOURCE_JSON_SCHEMA, description: "Gradient paint (or a colour) for the swatch, instead of color." },
8423
8534
  name: { type: "string", minLength: 1, description: "Optional name." }
8424
8535
  },
8425
8536
  additionalProperties: false
@@ -8573,7 +8684,7 @@ function createPaintGuideTools(c) {
8573
8684
  const pad = c.mixingPad;
8574
8685
  return {
8575
8686
  content: [
8576
- { type: "image", data: _chunkOLNIPTB3cjs.bytesToBase64.call(void 0, _chunkOLNIPTB3cjs.encodePng.call(void 0, pad.width, pad.height, pad.pixels())), mimeType: "image/png" },
8687
+ { type: "image", data: _chunkW5M3J7PVcjs.bytesToBase64.call(void 0, _chunkW5M3J7PVcjs.encodePng.call(void 0, pad.width, pad.height, pad.pixels())), mimeType: "image/png" },
8577
8688
  { type: "text", text: `Mixing pad ${pad.width}\xD7${pad.height}` }
8578
8689
  ]
8579
8690
  };
@@ -8715,7 +8826,7 @@ function createPaintWetTools(c) {
8715
8826
  type: "object",
8716
8827
  properties: {
8717
8828
  layerId: LAYER_ID2,
8718
- kind: { type: "string", enum: [..._chunkVMROIWLLcjs.WET_FLOW_KINDS], description: "none, linear, swirl, radial or turbulent." },
8829
+ kind: { type: "string", enum: [..._chunkKBYB7OWBcjs.WET_FLOW_KINDS], description: "none, linear, swirl, radial or turbulent." },
8719
8830
  strength: UNIT("How hard it pushes, 0..1 (1 is about a 25\xB0 tilt; default 0.5)."),
8720
8831
  angle: { type: "number", minimum: -360, maximum: 360, description: "linear: direction in degrees clockwise from canvas down (default 0)." },
8721
8832
  center: {
@@ -8914,7 +9025,7 @@ function createPaintReplayTools(c) {
8914
9025
  await c.wetIdle();
8915
9026
  const tl = await c.timeLapse({ frames: a.frames, fps: a.fps, maxSide: a.maxSide, wetStepsPerFrame: a.wetStepsPerFrame, holdMs: a.holdMs });
8916
9027
  const pick = [0, Math.floor(tl.frames.length / 3), Math.floor(2 * tl.frames.length / 3), tl.frames.length - 1].filter((v, i, arr) => arr.indexOf(v) === i);
8917
- const sheet = contactSheet(pick.map((i) => _chunkOLNIPTB3cjs.decodePng.call(void 0, tl.frames[i])), pick.length, 160);
9028
+ const sheet = contactSheet(pick.map((i) => _chunkW5M3J7PVcjs.decodePng.call(void 0, tl.frames[i])), pick.length, 160);
8918
9029
  const info = {
8919
9030
  frames: tl.frames.length,
8920
9031
  fps: tl.fps,
@@ -8923,9 +9034,9 @@ function createPaintReplayTools(c) {
8923
9034
  durationMs: tl.durationMs,
8924
9035
  ffmpeg: tl.ffmpeg.command,
8925
9036
  video: tl.video,
8926
- ...a.includeFrames ? { framesPng: tl.frames.map((f) => _chunkOLNIPTB3cjs.bytesToBase64.call(void 0, f)) } : {}
9037
+ ...a.includeFrames ? { framesPng: tl.frames.map((f) => _chunkW5M3J7PVcjs.bytesToBase64.call(void 0, f)) } : {}
8927
9038
  };
8928
- return { content: [{ type: "image", data: _chunkOLNIPTB3cjs.bytesToBase64.call(void 0, _chunkOLNIPTB3cjs.encodePng.call(void 0, sheet.width, sheet.height, sheet.data)), mimeType: "image/png" }, { type: "text", text: JSON.stringify(info) }] };
9039
+ return { content: [{ type: "image", data: _chunkW5M3J7PVcjs.bytesToBase64.call(void 0, _chunkW5M3J7PVcjs.encodePng.call(void 0, sheet.width, sheet.height, sheet.data)), mimeType: "image/png" }, { type: "text", text: JSON.stringify(info) }] };
8929
9040
  }
8930
9041
  },
8931
9042
  {
@@ -8945,8 +9056,8 @@ function createPaintReplayTools(c) {
8945
9056
  handler: async ({ scale, paper }) => {
8946
9057
  await c.wetIdle();
8947
9058
  const img = await c.renderHighRes({ scale, paper });
8948
- const bytes = _chunkOLNIPTB3cjs.encodePng.call(void 0, img.width, img.height, img.data);
8949
- return { mimeType: "image/png", width: img.width, height: img.height, bytes: bytes.length, data: _chunkOLNIPTB3cjs.bytesToBase64.call(void 0, bytes) };
9059
+ const bytes = _chunkW5M3J7PVcjs.encodePng.call(void 0, img.width, img.height, img.data);
9060
+ return { mimeType: "image/png", width: img.width, height: img.height, bytes: bytes.length, data: _chunkW5M3J7PVcjs.bytesToBase64.call(void 0, bytes) };
8950
9061
  }
8951
9062
  }
8952
9063
  ];
@@ -8964,7 +9075,7 @@ var TIP = {
8964
9075
  type: "object",
8965
9076
  description: "The tip (the shared brush engine). Missing fields keep their current values.",
8966
9077
  properties: {
8967
- size: { type: "number", minimum: 1, maximum: _chunkPQ3H2AANcjs.MAX_BRUSH_SIZE, description: "Diameter in pixels." },
9078
+ size: { type: "number", minimum: 1, maximum: _chunkI7NJPHWVcjs.MAX_BRUSH_SIZE, description: "Diameter in pixels." },
8968
9079
  hardness: { type: "number", minimum: 0, maximum: 1, description: "Edge hardness, 0 (soft) .. 1 (hard)." },
8969
9080
  spacing: { type: "number", minimum: 0.01, maximum: 10, description: "Dab spacing as a fraction of the diameter (0.05 is smooth, 1 is dotted)." },
8970
9081
  angle: { type: "number", minimum: -360, maximum: 360, description: "Tip angle in degrees, counter-clockwise; with rotation stroke or barrel it is added to the stroke direction or pen rotation." },
@@ -8976,7 +9087,7 @@ var TIP = {
8976
9087
  pressureOpacity: { type: "boolean", description: "Pressure scales the opacity." },
8977
9088
  blend: {
8978
9089
  type: "string",
8979
- enum: _chunkOLNIPTB3cjs.BLEND_MODES.map((m) => m.id),
9090
+ enum: _chunk2VX55NFMcjs.BLEND_MODES.map((m) => m.id),
8980
9091
  description: "How paint combines with the layer. pigment mixes it in like real paint (blue into yellow gives green); multiply darkens like marker ink; watercolor glazes like a transparent wash; tint, highlight and shadow recolour, light and shade (see list_blend_modes)."
8981
9092
  }
8982
9093
  },
@@ -9009,11 +9120,11 @@ var MIXER = {
9009
9120
  mix: { type: "number", minimum: 0, maximum: 1, description: "Mix ratio: how far each dab's paint moves from the reservoir towards the picked-up colour." },
9010
9121
  loadEachStroke: { type: "boolean", description: "Refill the reservoir with the colour before each stroke." },
9011
9122
  cleanEachStroke: { type: "boolean", description: "Empty the pickup well after each stroke." },
9012
- mixing: { type: "string", enum: [..._chunkPQ3H2AANcjs.MIXING_MODELS], description: "rgb: RGB averages. pigment: mixes like paint (Kubelka-Munk)." }
9123
+ mixing: { type: "string", enum: [..._chunkI7NJPHWVcjs.MIXING_MODELS], description: "rgb: RGB averages. pigment: mixes like paint (Kubelka-Munk)." }
9013
9124
  },
9014
9125
  additionalProperties: false
9015
9126
  };
9016
- var MIXING = { type: "string", enum: [..._chunkPQ3H2AANcjs.MIXING_MODELS], description: "pigment: mixes like paint (Kubelka-Munk, blue and yellow make green); rgb: straight RGB averages." };
9127
+ var MIXING = { type: "string", enum: [..._chunkI7NJPHWVcjs.MIXING_MODELS], description: "pigment: mixes like paint (Kubelka-Munk, blue and yellow make green); rgb: straight RGB averages." };
9017
9128
  var BEHAVIOR = {
9018
9129
  type: "object",
9019
9130
  description: "How the brush handles paint on the canvas (dab and mixer engines; on a mixer brush pickup, mix, dirty and mixing are its mixer wet, mix, !cleanEachStroke and mixing). Missing fields keep their current values.",
@@ -9026,7 +9137,7 @@ var BEHAVIOR = {
9026
9137
  type: "object",
9027
9138
  description: "Multi-coloured brush (the older form of paint, the brush's own gradient: tip is across-tip, dab is distance in dabs or random). Read back from paint when it has a multi-colour equivalent. Missing fields keep their current values.",
9028
9139
  properties: {
9029
- mode: { type: "string", enum: [..._chunk6G6ZDDDBcjs.MULTI_COLOR_MODES], description: "off; tip: the colours lie side by side across the tip (stripes along the stroke, like a brush loaded with several paints); dab: the colour changes along the stroke." },
9140
+ mode: { type: "string", enum: [..._chunkH4AOUUBEcjs.MULTI_COLOR_MODES], description: "off; tip: the colours lie side by side across the tip (stripes along the stroke, like a brush loaded with several paints); dab: the colour changes along the stroke." },
9030
9141
  colors: { type: "array", maxItems: 8, items: { ...COLOR3 }, description: "2..8 colours #rrggbb; fewer than 2 uses the paint colour and the secondary colour." },
9031
9142
  order: { type: "string", enum: ["sequence", "random"], description: "dab mode: sequence runs through the colours in order, blending between them; random picks one per run of dabs (seeded)." },
9032
9143
  length: { type: "integer", minimum: 1, maximum: 500, description: "dab mode: dabs per colour (default 12)." },
@@ -9039,7 +9150,7 @@ var BEHAVIOR = {
9039
9150
  };
9040
9151
  var BRUSH_PAINT = {
9041
9152
  description: `The brush's own gradient paint, used instead of the editor's paint (null: the editor's paint). It is what the multi-colour settings became; stops may be "paint" / "secondary" for the editor's two colours.`,
9042
- anyOf: [_chunkPQ3H2AANcjs.PAINT_GRADIENT_JSON_SCHEMA, { type: "null", description: "No gradient of its own: the editor's paint." }]
9153
+ anyOf: [_chunkI7NJPHWVcjs.PAINT_GRADIENT_JSON_SCHEMA, { type: "null", description: "No gradient of its own: the editor's paint." }]
9043
9154
  };
9044
9155
  var BLENDER = {
9045
9156
  type: "object",
@@ -9067,10 +9178,10 @@ var WET_BRUSH = {
9067
9178
  properties: {
9068
9179
  tool: {
9069
9180
  type: "string",
9070
- enum: [..._chunk6G6ZDDDBcjs.WET_TOOLS],
9181
+ enum: [..._chunkH4AOUUBEcjs.WET_TOOLS],
9071
9182
  description: "paint: water and pigment (picks up and mixes wet paint by behavior.pickup / mix); water: clear water (with rewet it lifts dried paint); dry: a hair dryer, takes water; blow: pushes the water along the stroke; blend: evens out wet pigment; smudge: drags wet paint; blot: a tissue, takes wet paint up (erase wet)."
9072
9183
  },
9073
- medium: { type: "string", enum: [..._chunk6G6ZDDDBcjs.WET_MEDIA], description: "The medium: watercolor, gouache or oil. A layer takes the medium's wet settings the first time it holds wet paint (oil: thick, barely flows, stays wet long and blends into the wet paint it meets)." },
9184
+ medium: { type: "string", enum: [..._chunkH4AOUUBEcjs.WET_MEDIA], description: "The medium: watercolor, gouache or oil. A layer takes the medium's wet settings the first time it holds wet paint (oil: thick, barely flows, stays wet long and blends into the wet paint it meets)." },
9074
9185
  load: { type: "number", minimum: 0, maximum: 1, description: "Paint loading: 1 never runs out; lower, the brush runs dry along a long stroke (each stroke reloads)." },
9075
9186
  thinner: { type: "number", minimum: 0, maximum: 1, description: "Thinner (water or solvent): more transparent, runnier paint." },
9076
9187
  water: { type: "number", minimum: 0, maximum: 1, description: "Wetness: water laid per stroke, 0.2 a damp brush .. 1 a dripping one." },
@@ -9087,7 +9198,7 @@ var IMPASTO_BRUSH = {
9087
9198
  properties: {
9088
9199
  tool: {
9089
9200
  type: "string",
9090
- enum: [..._chunk6G6ZDDDBcjs.IMPASTO_TOOLS],
9201
+ enum: [..._chunkH4AOUUBEcjs.IMPASTO_TOOLS],
9091
9202
  description: "brush: thick paint with bristle ridges along the stroke; tube: blobs squeezed from the tube; knife: a palette knife that scrapes the relief flat and smears the paint; roller: a flat stippled band; gloop: a thick, glossy, rounded bead."
9092
9203
  },
9093
9204
  thickness: { type: "number", minimum: 0, maximum: 1, description: "How far the paint stands up." },
@@ -9116,12 +9227,12 @@ var PARTICLE_BRUSH = {
9116
9227
  properties: {
9117
9228
  kind: {
9118
9229
  type: "string",
9119
- enum: [..._chunk6G6ZDDDBcjs.PARTICLE_KINDS],
9230
+ enum: [..._chunkH4AOUUBEcjs.PARTICLE_KINDS],
9120
9231
  description: "string: strands of masses on springs dragged behind the pen (hair, fur, wet string); spring: particles on springs to the pen, overshooting and wobbling; orbit: particles circling the pen (curls); flow: particles thrown off the pen into a swirling flow until they fade; elastic: strands whose links keep a rest length, stretching when the pen is fast and snapping back; fuzzy: winding strings, each strand waving out of step with the others (always waves by at least 0.12 of the tip size)."
9121
9232
  },
9122
9233
  render: {
9123
9234
  type: "string",
9124
- enum: [..._chunk6G6ZDDDBcjs.PARTICLE_RENDERS],
9235
+ enum: [..._chunkH4AOUUBEcjs.PARTICLE_RENDERS],
9125
9236
  description: "dot: a mark at each step (round, or dotTextures); line: each particle draws a continuous line; sequence: beads spaced along each path (round, or dotTextures); ribbon: the band between neighbouring particles' paths filled (ribbonFill), with the paths drawn as its edges at the mark size (flame, silk, smoke)."
9126
9237
  },
9127
9238
  count: { type: "integer", minimum: 1, maximum: 64, description: "Particles (flow: how many are thrown per tip of travel)." },
@@ -9134,19 +9245,19 @@ var PARTICLE_BRUSH = {
9134
9245
  life: { type: "number", minimum: 0, maximum: 1, description: "Flow particles: how long they live." },
9135
9246
  interval: { type: "number", minimum: 0, maximum: 1, description: "Sequence: spacing of the beads." },
9136
9247
  ribbonFill: { type: "number", minimum: 0, maximum: 1, description: "Ribbon: opacity of the fill between the paths, relative to their edges (default 0.5; 0 draws only the edges)." },
9137
- ribbonPairs: { type: "string", enum: [..._chunk6G6ZDDDBcjs.RIBBON_PAIRS], description: "Ribbon: adjacent (default) joins each particle to its neighbour around the pen; first-last makes one band between the outermost two." },
9248
+ ribbonPairs: { type: "string", enum: [..._chunkH4AOUUBEcjs.RIBBON_PAIRS], description: "Ribbon: adjacent (default) joins each particle to its neighbour around the pen; first-last makes one band between the outermost two." },
9138
9249
  waveAmplitude: { type: "number", minimum: 0, maximum: 1, description: "Wave: how far each particle's drawn place swings sideways to the stroke, as a fraction of the tip size (default 0: no wave). Works with every kind and render." },
9139
9250
  waveLength: { type: "number", minimum: 4, maximum: 2e3, description: "Wave: wavelength in px of pen travel (default 60)." },
9140
9251
  waveSpeed: { type: "number", minimum: 0, maximum: 1, description: "Wave: how fast the waves run, by stroke time (0 default: they stand still on the path; 1: about four a second, so slow strokes wave more). Strokes without times run at a nominal 0.5 px/ms." },
9141
9252
  wavePhaseJitter: { type: "number", minimum: 0, maximum: 1, description: "Wave: how far out of step the particles' waves are (default 0: all in step, a wavy band; 1: random phases, tangled strands)." },
9142
9253
  dotTextures: {
9143
9254
  type: "array",
9144
- maxItems: _chunk6G6ZDDDBcjs.MAX_DOT_TEXTURES,
9145
- items: { type: "string", enum: [..._chunk6G6ZDDDBcjs.STAMP_KINDS], description: "A stamp." },
9146
- description: `Dot and sequence renders: up to ${_chunk6G6ZDDDBcjs.MAX_DOT_TEXTURES} sticker stamps (list_stickers) drawn instead of round marks; repeats are allowed (they weight the order). Empty (default): round marks.`
9255
+ maxItems: _chunkH4AOUUBEcjs.MAX_DOT_TEXTURES,
9256
+ items: { type: "string", enum: [..._chunkZEYMKDYScjs.STAMP_KINDS], description: "A stamp." },
9257
+ description: `Dot and sequence renders: up to ${_chunkH4AOUUBEcjs.MAX_DOT_TEXTURES} sticker stamps (list_stickers) drawn instead of round marks; repeats are allowed (they weight the order). Empty (default): round marks.`
9147
9258
  },
9148
- dotTextureOrder: { type: "string", enum: [..._chunk6G6ZDDDBcjs.DOT_TEXTURE_ORDERS], description: "Textured dots: sequence (default) uses the stamps in turn; random picks one per dot (seeded, so replays are exact)." },
9149
- dotRotation: { type: "string", enum: [..._chunk6G6ZDDDBcjs.DOT_ROTATIONS], description: "Textured dots: follow turns each with its particle's motion; random (default) turns each at random; fixed uses the tip angle." }
9259
+ dotTextureOrder: { type: "string", enum: [..._chunkH4AOUUBEcjs.DOT_TEXTURE_ORDERS], description: "Textured dots: sequence (default) uses the stamps in turn; random picks one per dot (seeded, so replays are exact)." },
9260
+ dotRotation: { type: "string", enum: [..._chunkH4AOUUBEcjs.DOT_ROTATIONS], description: "Textured dots: follow turns each with its particle's motion; random (default) turns each at random; fixed uses the tip angle." }
9150
9261
  },
9151
9262
  additionalProperties: false
9152
9263
  };
@@ -9167,7 +9278,13 @@ var STICKER_BRUSH = {
9167
9278
  type: "object",
9168
9279
  description: "Sticker engine settings: stamps sprayed along the stroke as editable stickers. Missing fields keep their current values.",
9169
9280
  properties: {
9170
- stamps: { type: "array", minItems: 1, maxItems: 9, items: { type: "string", enum: [..._chunk6G6ZDDDBcjs.STAMP_KINDS], description: "A stamp." }, description: "The stamps to spray (one picked at random per sticker)." },
9281
+ stamps: {
9282
+ type: "array",
9283
+ minItems: 1,
9284
+ maxItems: _chunkH4AOUUBEcjs.MAX_STICKER_STAMPS,
9285
+ items: { type: "string", minLength: 1, description: "A sticker ref provider:id from find_stickers (e.g. editor:star); a bare editor stamp (star) means editor:star." },
9286
+ description: `The stickers to spray, one picked at random per sticker: refs from find_stickers (the editor's own: ${_chunkZEYMKDYScjs.STAMP_KINDS.map((k) => `editor:${k}`).join(", ")}). Each is checked against the sticker library and an unknown ref is refused with the closest ones. A provider's sticker is drawn from its art (tinted to the paint colour when tintable), loaded before the stroke.`
9287
+ },
9171
9288
  density: { type: "number", minimum: 0, maximum: 1, description: "How closely stickers follow each other: about density \xD7 4 stickers per tip diameter of travel (0.25 \u2248 one per diameter, 1 \u2248 four). Default 0.4." },
9172
9289
  sizeJitter: { type: "number", minimum: 0, maximum: 1, description: "Random size change." },
9173
9290
  rotationJitter: { type: "number", minimum: 0, maximum: 1, description: "Random turn as a fraction of \xB1180\xB0." },
@@ -9178,16 +9295,16 @@ var STICKER_BRUSH = {
9178
9295
  };
9179
9296
  var BRUSH_FIELDS = {
9180
9297
  name: { type: "string", minLength: 1, maxLength: 80, description: "Display name." },
9181
- category: { type: "string", enum: [..._chunk6G6ZDDDBcjs.PAINT_BRUSH_CATEGORIES], description: "Library category." },
9298
+ category: { type: "string", enum: [..._chunkH4AOUUBEcjs.PAINT_BRUSH_CATEGORIES], description: "Library category." },
9182
9299
  engine: {
9183
9300
  type: "string",
9184
- enum: [..._chunk6G6ZDDDBcjs.PAINT_BRUSH_ENGINES],
9301
+ enum: [..._chunkH4AOUUBEcjs.PAINT_BRUSH_ENGINES],
9185
9302
  description: "dab: paints dabs (with behavior.pickup or gradient paint it paints dab by dab, lifting and mixing paint); eraser: removes paint; mixer: the Mixer Brush (a reservoir plus picked-up paint); blender: mixes the colours under and near the tip; smudge: drags paint along the stroke; wet: watercolour, gouache, oil and the wet tools on a simulated wet layer (see wet); impasto: thick paint with relief (see impasto); particle: procedural particle brushes (see particle); bristle: a tuft of bristles that bend and splay (see bristle); sticker: sprays editable sticker stamps (see sticker)."
9186
9303
  },
9187
9304
  tip: TIP,
9188
9305
  grain: { type: "number", minimum: 0, maximum: 1, description: "Paper grain response: 0 ignores the grain, 1 catches only its peaks at light pressure (pencil, pastel, charcoal). Multiplied by the paper depth." },
9189
9306
  pressureSmoothing: { type: "number", minimum: 0, maximum: 0.95, description: "Pressure smoothing, separate from the tip position smoothing." },
9190
- rotation: { type: "string", enum: [..._chunk6G6ZDDDBcjs.BRUSH_ROTATIONS], description: "What turns the tip: fixed (tip.angle), stroke (follows the direction of travel) or barrel (the pen barrel rotation, twist)." },
9307
+ rotation: { type: "string", enum: [..._chunkH4AOUUBEcjs.BRUSH_ROTATIONS], description: "What turns the tip: fixed (tip.angle), stroke (follows the direction of travel) or barrel (the pen barrel rotation, twist)." },
9191
9308
  dynamics: DYNAMICS,
9192
9309
  mixer: MIXER,
9193
9310
  loadsColor: { type: "boolean", description: "Mixer engine: load the colour each stroke (false for a mixer that only moves paint)." },
@@ -9239,7 +9356,7 @@ function brushSummary(b) {
9239
9356
  size: b.tip.size,
9240
9357
  grain: b.grain,
9241
9358
  rotation: b.rotation,
9242
- wetCapable: _chunk6G6ZDDDBcjs.isWetCapable.call(void 0, b),
9359
+ wetCapable: _chunkH4AOUUBEcjs.isWetCapable.call(void 0, b),
9243
9360
  pickup: b.behavior.pickup,
9244
9361
  dirty: b.behavior.dirty,
9245
9362
  multicolor: b.behavior.multicolor.mode,
@@ -9286,7 +9403,7 @@ function createPaintEditorToolProvider(controller, options = {}) {
9286
9403
  strokes: d.strokes.length,
9287
9404
  undo: s.undoLabel,
9288
9405
  redo: s.redoLabel,
9289
- blendModes: _chunkOLNIPTB3cjs.BLEND_MODES.map((m) => m.id),
9406
+ blendModes: _chunk2VX55NFMcjs.BLEND_MODES.map((m) => m.id),
9290
9407
  wet: s.wet.wet,
9291
9408
  lighting: c.getLighting()
9292
9409
  };
@@ -9348,9 +9465,9 @@ function createPaintEditorToolProvider(controller, options = {}) {
9348
9465
  inputSchema: EMPTY3,
9349
9466
  annotations: { title: "List papers", ...READ6 },
9350
9467
  handler: () => ({
9351
- papers: _chunk6G6ZDDDBcjs.PAPER_LIBRARY.map((p) => ({ id: p.preset, name: p.name, family: p.family, pattern: p.pattern, color: p.color, depth: p.depth, absorption: p.absorption, permeability: p.permeability, roughness: p.roughness })),
9352
- families: [..._chunk6G6ZDDDBcjs.PAPER_FAMILIES],
9353
- patterns: [..._chunkPQ3H2AANcjs.GRAIN_PATTERNS]
9468
+ papers: _chunkH4AOUUBEcjs.PAPER_LIBRARY.map((p) => ({ id: p.preset, name: p.name, family: p.family, pattern: p.pattern, color: p.color, depth: p.depth, absorption: p.absorption, permeability: p.permeability, roughness: p.roughness })),
9469
+ families: [..._chunkH4AOUUBEcjs.PAPER_FAMILIES],
9470
+ patterns: [..._chunkI7NJPHWVcjs.GRAIN_PATTERNS]
9354
9471
  })
9355
9472
  });
9356
9473
  add({
@@ -9381,7 +9498,7 @@ function createPaintEditorToolProvider(controller, options = {}) {
9381
9498
  depth: { type: "number", minimum: 0, maximum: 1, description: "Grain depth 0..1 (0: brushes ignore the grain)." },
9382
9499
  scale: { type: "number", minimum: 0.25, maximum: 8, description: "Grain scale: 1 natural, 2 twice as coarse." },
9383
9500
  seed: { type: "integer", minimum: 0, description: "Grain seed: another sheet of the same paper." },
9384
- pattern: { type: "string", enum: [..._chunkPQ3H2AANcjs.GRAIN_PATTERNS], description: "Grain pattern." },
9501
+ pattern: { type: "string", enum: [..._chunkI7NJPHWVcjs.GRAIN_PATTERNS], description: "Grain pattern." },
9385
9502
  tiling: { type: "string", enum: ["repeat", "mirror"], description: "How the grain tile repeats (mirror hides seams)." },
9386
9503
  shading: { type: "number", minimum: 0, maximum: 1, description: "How much the grain shades the paper colour." },
9387
9504
  dry: { ...tuning, description: "Height map tuning for dry media." },
@@ -9439,7 +9556,7 @@ function createPaintEditorToolProvider(controller, options = {}) {
9439
9556
  opacity: { type: "number", minimum: 0, maximum: 1, description: "Layer opacity 0..1." },
9440
9557
  blend: {
9441
9558
  type: "string",
9442
- enum: [..._chunkOLNIPTB3cjs.BLEND_MODES.map((m) => m.id), "pass-through"],
9559
+ enum: [..._chunk2VX55NFMcjs.BLEND_MODES.map((m) => m.id), "pass-through"],
9443
9560
  description: "Blend mode (pass-through for groups only). Painterly modes: watercolor (the layer glazes like a transparent wash), tint (recolours keeping lightness), highlight (adds soft coloured light), shadow (shades with ambient fill); see list_blend_modes."
9444
9561
  },
9445
9562
  clipped: { type: "boolean", description: "Clip to the layer below (paint only shows where it has paint)." },
@@ -9469,12 +9586,12 @@ function createPaintEditorToolProvider(controller, options = {}) {
9469
9586
  inputSchema: EMPTY3,
9470
9587
  annotations: { title: "List blend modes", ...READ6 },
9471
9588
  handler: () => ({
9472
- modes: _chunkOLNIPTB3cjs.BLEND_MODES.map((m) => ({
9589
+ modes: _chunk2VX55NFMcjs.BLEND_MODES.map((m) => ({
9473
9590
  id: m.id,
9474
9591
  label: m.label,
9475
9592
  group: m.painterly ? "painterly" : m.id === "pigment" ? "pigment" : "standard",
9476
9593
  ...m.description ? { description: m.description } : {},
9477
- psd: _chunkOLNIPTB3cjs.standardBlendMode.call(void 0, m.id)
9594
+ psd: _chunk2VX55NFMcjs.standardBlendMode.call(void 0, m.id)
9478
9595
  }))
9479
9596
  })
9480
9597
  });
@@ -9546,7 +9663,7 @@ function createPaintEditorToolProvider(controller, options = {}) {
9546
9663
  opacity: { type: "number", minimum: 0, maximum: 1, description: "Opacity 0..1 (default 1)." },
9547
9664
  grain: { type: "number", minimum: 0, maximum: 1, description: "Paper grain response 0..1 (default 0: flat)." },
9548
9665
  pressure: { type: "number", minimum: 0, maximum: 1, description: "With grain: how far into the valleys, 0..1 (default 0.5)." },
9549
- blend: { type: "string", enum: _chunkOLNIPTB3cjs.BLEND_MODES.map((m) => m.id), description: "Blend mode (default normal; pigment mixes like paint, watercolor glazes; see list_blend_modes)." }
9666
+ blend: { type: "string", enum: _chunk2VX55NFMcjs.BLEND_MODES.map((m) => m.id), description: "Blend mode (default normal; pigment mixes like paint, watercolor glazes; see list_blend_modes)." }
9550
9667
  },
9551
9668
  additionalProperties: false
9552
9669
  },
@@ -9571,7 +9688,7 @@ function createPaintEditorToolProvider(controller, options = {}) {
9571
9688
  annotations: { title: "List brushes", ...READ6 },
9572
9689
  handler: () => {
9573
9690
  const s = c.getState();
9574
- return { activeBrushId: s.brush.id, activeEdited: !s.brush.builtin && Boolean(_optionalChain([c, 'access', _496 => _496.getBrush, 'call', _497 => _497(s.brush.id), 'optionalAccess', _498 => _498.builtin])), brushes: s.brushes.map(brushSummary) };
9691
+ return { activeBrushId: s.brush.id, activeEdited: !s.brush.builtin && Boolean(_optionalChain([c, 'access', _499 => _499.getBrush, 'call', _500 => _500(s.brush.id), 'optionalAccess', _501 => _501.builtin])), brushes: s.brushes.map(brushSummary) };
9575
9692
  }
9576
9693
  });
9577
9694
  add({
@@ -9582,10 +9699,10 @@ function createPaintEditorToolProvider(controller, options = {}) {
9582
9699
  annotations: { title: "Get a brush", ...READ6 },
9583
9700
  handler: ({ id }) => {
9584
9701
  const st = c.getState();
9585
- if (id === void 0) return { ..._chunk6G6ZDDDBcjs.brushToJSON.call(void 0, st.brush), strokePaint: _nullishCoalesce(st.brush.paint, () => ( st.paint)) };
9702
+ if (id === void 0) return { ..._chunkH4AOUUBEcjs.brushToJSON.call(void 0, st.brush), strokePaint: _nullishCoalesce(st.brush.paint, () => ( st.paint)) };
9586
9703
  const b = c.getBrush(id);
9587
9704
  if (!b) throw new Error(`Unknown brush "${id}". Call list_brushes for the ids.`);
9588
- return { ..._chunk6G6ZDDDBcjs.brushToJSON.call(void 0, b), builtin: Boolean(b.builtin), strokePaint: _nullishCoalesce(b.paint, () => ( st.paint)) };
9705
+ return { ..._chunkH4AOUUBEcjs.brushToJSON.call(void 0, b), builtin: Boolean(b.builtin), strokePaint: _nullishCoalesce(b.paint, () => ( st.paint)) };
9589
9706
  }
9590
9707
  });
9591
9708
  add({
@@ -9594,7 +9711,11 @@ function createPaintEditorToolProvider(controller, options = {}) {
9594
9711
  description: "Chooses the active brush (id) and / or changes its settings; strokes without a brush use it. Editor state, not an undo step. Changes stay on the active brush until save_brush stores them. Returns the active brush.",
9595
9712
  inputSchema: { type: "object", properties: { id: { type: "string", description: "Brush id from list_brushes to start from." }, ...BRUSH_FIELDS }, additionalProperties: false },
9596
9713
  annotations: { title: "Set the brush", ...SET4 },
9597
- handler: (a) => _chunk6G6ZDDDBcjs.brushToJSON.call(void 0, c.setBrush(a))
9714
+ handler: async (a) => {
9715
+ const stamps = _optionalChain([a, 'access', _502 => _502.sticker, 'optionalAccess', _503 => _503.stamps]);
9716
+ if (stamps) await c.prepareStickers(stamps);
9717
+ return _chunkH4AOUUBEcjs.brushToJSON.call(void 0, c.setBrush(a));
9718
+ }
9598
9719
  });
9599
9720
  add({
9600
9721
  name: "save_brush",
@@ -9610,7 +9731,7 @@ function createPaintEditorToolProvider(controller, options = {}) {
9610
9731
  additionalProperties: false
9611
9732
  },
9612
9733
  annotations: { title: "Save a brush", ...SET4 },
9613
- handler: ({ id, name }) => _chunk6G6ZDDDBcjs.brushToJSON.call(void 0, c.saveBrush({ id, name }))
9734
+ handler: ({ id, name }) => _chunkH4AOUUBEcjs.brushToJSON.call(void 0, c.saveBrush({ id, name }))
9614
9735
  });
9615
9736
  add({
9616
9737
  name: "remove_brush",
@@ -9670,7 +9791,7 @@ function createPaintEditorToolProvider(controller, options = {}) {
9670
9791
  const t = c.brushThumbnail(_nullishCoalesce(id, () => ( c.getState().brush.id)), { width, height, color });
9671
9792
  return {
9672
9793
  content: [
9673
- { type: "image", data: _chunkOLNIPTB3cjs.bytesToBase64.call(void 0, _chunkOLNIPTB3cjs.encodePng.call(void 0, t.width, t.height, t.data)), mimeType: "image/png" },
9794
+ { type: "image", data: _chunkW5M3J7PVcjs.bytesToBase64.call(void 0, _chunkW5M3J7PVcjs.encodePng.call(void 0, t.width, t.height, t.data)), mimeType: "image/png" },
9674
9795
  { type: "text", text: `Brush ${_nullishCoalesce(id, () => ( c.getState().brush.id))} ${t.width}\xD7${t.height}` }
9675
9796
  ]
9676
9797
  };
@@ -9697,7 +9818,7 @@ function createPaintEditorToolProvider(controller, options = {}) {
9697
9818
  name: "set_paint",
9698
9819
  title: "Set the paint (colour or gradient)",
9699
9820
  description: 'Sets what strokes paint with: one colour, or gradient paint that changes colour as the stroke goes. Gradient paint: 2..16 stops sorted by offset (#rrggbb, or "paint" / "secondary" for the two editor colours), space pigment (default: mixes like paint) / oklab / srgb, and map: distance (default: the colour changes as the stroke is dragged out, 300 px then mirrored back), pressure, tilt, velocity, direction, time, across-tip or random. Every stroking brush samples it per dab (dab, mixer, watercolour and gouache, oil and impasto, particle, bristle, sticker); erasers, blenders and smudges ignore it, and a brush with its own gradient (get_brush paint) paints that instead. It also ends effect paint (set_effect_paint); set_color goes back to one colour. Editor state, not an undo step. Returns paint, color and secondaryColor.',
9700
- inputSchema: { type: "object", properties: { paint: _chunkPQ3H2AANcjs.PAINT_SOURCE_JSON_SCHEMA }, required: ["paint"], additionalProperties: false },
9821
+ inputSchema: { type: "object", properties: { paint: _chunkI7NJPHWVcjs.PAINT_SOURCE_JSON_SCHEMA }, required: ["paint"], additionalProperties: false },
9701
9822
  annotations: { title: "Set the paint (colour or gradient)", ...SET4 },
9702
9823
  handler: ({ paint }) => {
9703
9824
  const p = c.setPaint(paint);
@@ -9759,7 +9880,7 @@ function createPaintEditorToolProvider(controller, options = {}) {
9759
9880
  brushId: { type: "string", description: "Brush id from list_brushes (default the active brush)." },
9760
9881
  brush: { type: "object", description: "Brush changes for this stroke only.", properties: BRUSH_FIELDS, additionalProperties: false },
9761
9882
  color: { ...COLOR3, description: "Paint colour #rrggbb (default the paint colour)." },
9762
- paint: { ..._chunkPQ3H2AANcjs.PAINT_SOURCE_JSON_SCHEMA, description: "What this stroke paints with instead of the editor's paint: a colour, or gradient paint that changes colour as the stroke goes (by distance, pressure, tilt, speed, direction, time, across the tip or at random). Wins over the brush's own gradient." },
9883
+ paint: { ..._chunkI7NJPHWVcjs.PAINT_SOURCE_JSON_SCHEMA, description: "What this stroke paints with instead of the editor's paint: a colour, or gradient paint that changes colour as the stroke goes (by distance, pressure, tilt, speed, direction, time, across the tip or at random). Wins over the brush's own gradient." },
9763
9884
  seed: { type: "integer", minimum: 0, description: "Jitter seed (default a new one); the same seed and points give the same marks." },
9764
9885
  snapToPerspective: { type: "boolean", description: "Snap the points to the perspective guide, as a pen stroke would (default false)." }
9765
9886
  },
@@ -9770,6 +9891,9 @@ function createPaintEditorToolProvider(controller, options = {}) {
9770
9891
  coordinates: { in: ["points[]"], out: ["bounds"] },
9771
9892
  handler: async (a) => {
9772
9893
  await c.wetIdle();
9894
+ const base = a.brushId ? c.getBrush(a.brushId) : c.getState().brush;
9895
+ const over = a.brush;
9896
+ if ((_nullishCoalesce(_optionalChain([over, 'optionalAccess', _504 => _504.engine]), () => ( _optionalChain([base, 'optionalAccess', _505 => _505.engine])))) === "sticker") await c.prepareStickers(_nullishCoalesce(_nullishCoalesce(_optionalChain([over, 'optionalAccess', _506 => _506.sticker, 'optionalAccess', _507 => _507.stamps]), () => ( _optionalChain([base, 'optionalAccess', _508 => _508.sticker, 'access', _509 => _509.stamps]))), () => ( [])));
9773
9897
  const stroke = { points: a.points, layerId: a.layerId, brushId: a.brushId, brush: a.brush, color: a.color, paint: a.paint, seed: a.seed, snapToPerspective: a.snapToPerspective };
9774
9898
  const r = await act({ kind: "stroke", stroke }, () => c.paintStroke(stroke));
9775
9899
  return r.mixerLoad ? { ...r, mixerLoad: loadResult(r.mixerLoad) } : r;
@@ -9801,7 +9925,7 @@ function createPaintEditorToolProvider(controller, options = {}) {
9801
9925
  if (ids) {
9802
9926
  for (const id of ids) if (!all.some((s) => s.id === id)) throw new Error(`Unknown stroke "${id}". Call list_strokes without ids for the ids.`);
9803
9927
  }
9804
- return { total: all.length, strokes: picked.map((s) => strokeSummary(s, Boolean(ids), live ? true : liveIds.has(s.id) && _optionalChain([c, 'access', _499 => _499.document, 'access', _500 => _500.liveStrokes, 'optionalAccess', _501 => _501[s.layerId], 'optionalAccess', _502 => _502.includes, 'call', _503 => _503(s)]) === true)) };
9928
+ return { total: all.length, strokes: picked.map((s) => strokeSummary(s, Boolean(ids), live ? true : liveIds.has(s.id) && _optionalChain([c, 'access', _510 => _510.document, 'access', _511 => _511.liveStrokes, 'optionalAccess', _512 => _512[s.layerId], 'optionalAccess', _513 => _513.includes, 'call', _514 => _514(s)]) === true)) };
9805
9929
  }
9806
9930
  });
9807
9931
  add({
@@ -9836,7 +9960,7 @@ function createPaintEditorToolProvider(controller, options = {}) {
9836
9960
  brushId: { type: "string", description: "Brush preset id from list_brushes; the stroke keeps its size." },
9837
9961
  brush: { type: "object", properties: BRUSH_FIELDS, additionalProperties: false, description: "Brush settings to change on top of brushId or the stroke\u2019s brush; missing fields keep their values." },
9838
9962
  color: { type: "string", pattern: "^#[0-9a-fA-F]{6}$", description: "New colour #rrggbb (replaces gradient paint)." },
9839
- paint: { anyOf: [_chunkPQ3H2AANcjs.PAINT_SOURCE_JSON_SCHEMA, { type: "null", description: "Back to the stroke\u2019s plain colour." }], description: "A colour or gradient paint for the stroke; null drops its gradient." },
9963
+ paint: { anyOf: [_chunkI7NJPHWVcjs.PAINT_SOURCE_JSON_SCHEMA, { type: "null", description: "Back to the stroke\u2019s plain colour." }], description: "A colour or gradient paint for the stroke; null drops its gradient." },
9840
9964
  seed: { type: "integer", minimum: 0, description: "Another jitter seed: particles, scatter and texture fall differently." }
9841
9965
  },
9842
9966
  required: ["id"],
@@ -10058,7 +10182,7 @@ function createPaintEditorToolProvider(controller, options = {}) {
10058
10182
  handler: async ({ format, quality, scale, paper, time }) => {
10059
10183
  const run = () => c.exportImage({ format, quality, scale, paper });
10060
10184
  const bytes = time === void 0 ? await run() : await c.withEffectTime(time, run);
10061
- return { mimeType: _nullishCoalesce(format, () => ( "image/png")), bytes: bytes.length, data: _chunkOLNIPTB3cjs.bytesToBase64.call(void 0, bytes) };
10185
+ return { mimeType: _nullishCoalesce(format, () => ( "image/png")), bytes: bytes.length, data: _chunkW5M3J7PVcjs.bytesToBase64.call(void 0, bytes) };
10062
10186
  }
10063
10187
  });
10064
10188
  add({
@@ -10069,7 +10193,7 @@ function createPaintEditorToolProvider(controller, options = {}) {
10069
10193
  annotations: { title: "Export as PSD", ...READ6 },
10070
10194
  handler: async ({ time }) => {
10071
10195
  const r = time === void 0 ? c.exportPsd() : await c.withEffectTime(time, () => c.exportPsd());
10072
- return { data: _chunkOLNIPTB3cjs.bytesToBase64.call(void 0, r.bytes), bytes: r.bytes.length, psb: r.psb, warnings: r.warnings };
10196
+ return { data: _chunkW5M3J7PVcjs.bytesToBase64.call(void 0, r.bytes), bytes: r.bytes.length, psb: r.psb, warnings: r.warnings };
10073
10197
  }
10074
10198
  });
10075
10199
  tools.push(...createPaintGuideTools(c));
@@ -10077,9 +10201,10 @@ function createPaintEditorToolProvider(controller, options = {}) {
10077
10201
  tools.push(...createPaintThickTools(c));
10078
10202
  tools.push(...createPaintReplayTools(c));
10079
10203
  tools.push(...createPaintStickerTools(c));
10080
- tools.push(..._chunkVMROIWLLcjs.createPigmentTools.call(void 0, ));
10204
+ tools.push(..._chunkKBYB7OWBcjs.createPigmentTools.call(void 0, ));
10205
+ tools.push(..._chunkZEYMKDYScjs.createStickerTools.call(void 0, { provider: () => c.stickersProvider }));
10081
10206
  tools.push(
10082
- ..._chunkWVS5KQDHcjs.createLayerEffectTools.call(void 0,
10207
+ ..._chunkLP2MCSBEcjs.createLayerEffectTools.call(void 0,
10083
10208
  {
10084
10209
  requireLayer: (id) => void c.getLayerEffects(id),
10085
10210
  getLayerEffects: (id) => c.getLayerEffects(id),
@@ -10104,16 +10229,16 @@ function createPaintEditorToolProvider(controller, options = {}) {
10104
10229
  }
10105
10230
  function hostTool({ coordinates, ...tool }, { origin, onChange }) {
10106
10231
  if (!origin && !onChange) return tool;
10107
- const write = !_optionalChain([tool, 'access', _504 => _504.annotations, 'optionalAccess', _505 => _505.readOnlyHint]);
10232
+ const write = !_optionalChain([tool, 'access', _515 => _515.annotations, 'optionalAccess', _516 => _516.readOnlyHint]);
10108
10233
  const done = (result) => {
10109
- if (write) _optionalChain([onChange, 'optionalCall', _506 => _506({ tool: tool.name })]);
10110
- return origin && _optionalChain([coordinates, 'optionalAccess', _507 => _507.out]) ? fromDocument(result, coordinates.out, origin) : result;
10234
+ if (write) _optionalChain([onChange, 'optionalCall', _517 => _517({ tool: tool.name })]);
10235
+ return origin && _optionalChain([coordinates, 'optionalAccess', _518 => _518.out]) ? fromDocument(result, coordinates.out, origin) : result;
10111
10236
  };
10112
10237
  return {
10113
10238
  ...tool,
10114
10239
  ...origin ? { description: hostedText(_nullishCoalesce(tool.description, () => ( ""))), inputSchema: hostedSchema(tool.inputSchema) } : {},
10115
10240
  handler: (args, context) => {
10116
- const r = tool.handler(origin && _optionalChain([coordinates, 'optionalAccess', _508 => _508.in]) ? toDocument(args, coordinates.in, origin) : args, context);
10241
+ const r = tool.handler(origin && _optionalChain([coordinates, 'optionalAccess', _519 => _519.in]) ? toDocument(args, coordinates.in, origin) : args, context);
10117
10242
  return r instanceof Promise ? r.then(done) : done(r);
10118
10243
  }
10119
10244
  };
@@ -10130,7 +10255,7 @@ function strokeSummary(s, withPoints, live) {
10130
10255
  color: s.color,
10131
10256
  points: withPoints ? s.points : s.points.length,
10132
10257
  seed: s.seed,
10133
- copies: _nullishCoalesce(_optionalChain([s, 'access', _509 => _509.copies, 'optionalAccess', _510 => _510.length]), () => ( 0)),
10258
+ copies: _nullishCoalesce(_optionalChain([s, 'access', _520 => _520.copies, 'optionalAccess', _521 => _521.length]), () => ( 0)),
10134
10259
  live,
10135
10260
  bounds: { x: Math.floor(Math.min(...xs) - pad), y: Math.floor(Math.min(...ys) - pad), width: Math.ceil(Math.max(...xs) - Math.min(...xs) + 2 * pad), height: Math.ceil(Math.max(...ys) - Math.min(...ys) + 2 * pad) }
10136
10261
  };
@@ -10146,20 +10271,20 @@ var PAINT_TOOLS = [
10146
10271
  { id: "rotate", label: "Rotate view", key: "r" }
10147
10272
  ];
10148
10273
  var PaintGesture = (_class13 = class {
10149
- constructor(controller, box) {;_class13.prototype.__init137.call(this);_class13.prototype.__init138.call(this);_class13.prototype.__init139.call(this);_class13.prototype.__init140.call(this);_class13.prototype.__init141.call(this);_class13.prototype.__init142.call(this);
10274
+ constructor(controller, box) {;_class13.prototype.__init139.call(this);_class13.prototype.__init140.call(this);_class13.prototype.__init141.call(this);_class13.prototype.__init142.call(this);_class13.prototype.__init143.call(this);_class13.prototype.__init144.call(this);
10150
10275
  this.controller = controller;
10151
10276
  this.box = box;
10152
10277
  }
10153
10278
 
10154
10279
 
10155
- __init137() {this.tool = "brush"}
10280
+ __init139() {this.tool = "brush"}
10156
10281
  /** The last refusal (a hidden or locked layer), for the editor to show. */
10157
- __init138() {this.error = null}
10282
+ __init140() {this.error = null}
10158
10283
  /** The predicted tail of the current stroke in document pixels (draw it as a thin preview). */
10159
- __init139() {this.predicted = []}
10160
- __init140() {this.mode = null}
10161
- __init141() {this.penAt = null}
10162
- __init142() {this.penDown = false}
10284
+ __init141() {this.predicted = []}
10285
+ __init142() {this.mode = null}
10286
+ __init143() {this.penAt = null}
10287
+ __init144() {this.penDown = false}
10163
10288
  doc(e) {
10164
10289
  const b = this.box();
10165
10290
  const s = this.controller.getState();
@@ -10215,13 +10340,13 @@ var PaintGesture = (_class13 = class {
10215
10340
  const p = this.doc(e);
10216
10341
  const s = this.controller.getState();
10217
10342
  const layerId = s.document.activeLayerId;
10218
- if (!layerId || !_optionalChain([s, 'access', _511 => _511.document, 'access', _512 => _512.liveStrokes, 'optionalAccess', _513 => _513[layerId]])) {
10343
+ if (!layerId || !_optionalChain([s, 'access', _522 => _522.document, 'access', _523 => _523.liveStrokes, 'optionalAccess', _524 => _524[layerId]])) {
10219
10344
  this.error = "Pick a stroke layer in the Layers panel (or add one) to select its strokes.";
10220
10345
  return false;
10221
10346
  }
10222
10347
  try {
10223
10348
  const hit = this.controller.liveStrokeAt(layerId, p.x, p.y);
10224
- this.controller.selectStroke(_nullishCoalesce(_optionalChain([hit, 'optionalAccess', _514 => _514.id]), () => ( null)));
10349
+ this.controller.selectStroke(_nullishCoalesce(_optionalChain([hit, 'optionalAccess', _525 => _525.id]), () => ( null)));
10225
10350
  if (!hit) return false;
10226
10351
  this.mode = { kind: "move-stroke", pointerId: e.pointerId, id: hit.id, from: p, to: p };
10227
10352
  return true;
@@ -10233,7 +10358,7 @@ var PaintGesture = (_class13 = class {
10233
10358
  /** While a stroke is dragged: how far it has moved (document pixels), to draw its outline there. */
10234
10359
  get strokeDrag() {
10235
10360
  const m = this.mode;
10236
- return _optionalChain([m, 'optionalAccess', _515 => _515.kind]) === "move-stroke" ? { id: m.id, dx: m.to.x - m.from.x, dy: m.to.y - m.from.y } : null;
10361
+ return _optionalChain([m, 'optionalAccess', _526 => _526.kind]) === "move-stroke" ? { id: m.id, dx: m.to.x - m.from.x, dy: m.to.y - m.from.y } : null;
10237
10362
  }
10238
10363
  /**
10239
10364
  * The Stickers tool: pressing a sticker picks it and dragging moves it (one undo step at the
@@ -10251,7 +10376,7 @@ var PaintGesture = (_class13 = class {
10251
10376
  }
10252
10377
  const brush = this.controller.getState().brush;
10253
10378
  const size = Math.min(2048, Math.max(2, Math.round(brush.tip.size)));
10254
- const [added] = this.controller.addStickers(void 0, [{ stamp: _nullishCoalesce(brush.sticker.stamps[0], () => ( "star")), x: round2(p.x), y: round2(p.y), size }]);
10379
+ const [added] = this.controller.addStickers(void 0, [{ ref: _nullishCoalesce(brush.sticker.stamps[0], () => ( "editor:star")), x: round2(p.x), y: round2(p.y), size }]);
10255
10380
  this.controller.selectSticker(added.id);
10256
10381
  } catch (err) {
10257
10382
  this.error = err instanceof Error ? err.message : String(err);
@@ -10307,7 +10432,7 @@ var PaintGesture = (_class13 = class {
10307
10432
  if (!m || m.pointerId !== e.pointerId) return;
10308
10433
  this.mode = null;
10309
10434
  this.predicted = [];
10310
- if (m.kind === "stroke") _optionalChain([this, 'access', _516 => _516.controller, 'access', _517 => _517.activeStroke, 'optionalAccess', _518 => _518.end, 'call', _519 => _519()]);
10435
+ if (m.kind === "stroke") _optionalChain([this, 'access', _527 => _527.controller, 'access', _528 => _528.activeStroke, 'optionalAccess', _529 => _529.end, 'call', _530 => _530()]);
10311
10436
  if (m.kind === "move-stroke") {
10312
10437
  const dx = Math.round((this.doc(e).x - m.from.x) * 100) / 100;
10313
10438
  const dy = Math.round((this.doc(e).y - m.from.y) * 100) / 100;
@@ -10331,8 +10456,8 @@ var PaintGesture = (_class13 = class {
10331
10456
  cancel() {
10332
10457
  this.penDown = false;
10333
10458
  this.predicted = [];
10334
- if (_optionalChain([this, 'access', _520 => _520.mode, 'optionalAccess', _521 => _521.kind]) === "stroke") _optionalChain([this, 'access', _522 => _522.controller, 'access', _523 => _523.activeStroke, 'optionalAccess', _524 => _524.cancel, 'call', _525 => _525()]);
10335
- if (_optionalChain([this, 'access', _526 => _526.mode, 'optionalAccess', _527 => _527.kind]) === "sticker") this.controller.cancelStickerPreview();
10459
+ if (_optionalChain([this, 'access', _531 => _531.mode, 'optionalAccess', _532 => _532.kind]) === "stroke") _optionalChain([this, 'access', _533 => _533.controller, 'access', _534 => _534.activeStroke, 'optionalAccess', _535 => _535.cancel, 'call', _536 => _536()]);
10460
+ if (_optionalChain([this, 'access', _537 => _537.mode, 'optionalAccess', _538 => _538.kind]) === "sticker") this.controller.cancelStickerPreview();
10336
10461
  this.mode = null;
10337
10462
  }
10338
10463
  get active() {
@@ -10394,13 +10519,13 @@ function handlePaintShortcut(controller, gesture, e) {
10394
10519
  return false;
10395
10520
  }
10396
10521
  var PaintCanvasPresenter = (_class14 = class {
10397
- constructor(controller) {;_class14.prototype.__init143.call(this);_class14.prototype.__init144.call(this);_class14.prototype.__init145.call(this);
10522
+ constructor(controller) {;_class14.prototype.__init145.call(this);_class14.prototype.__init146.call(this);_class14.prototype.__init147.call(this);
10398
10523
  this.controller = controller;
10399
10524
  }
10400
10525
 
10401
- __init143() {this.uploaded = /* @__PURE__ */ new Map()}
10402
- __init144() {this.scratch = null}
10403
- __init145() {this.size = ""}
10526
+ __init145() {this.uploaded = /* @__PURE__ */ new Map()}
10527
+ __init146() {this.scratch = null}
10528
+ __init147() {this.size = ""}
10404
10529
  /** Draws what changed into `ctx` (a canvas the size of the document); returns the tiles drawn. */
10405
10530
  render(ctx) {
10406
10531
  const { width, height } = this.controller.document.canvas;
@@ -10432,7 +10557,7 @@ function guideOverlay(controller, drag) {
10432
10557
  const size = s.document.canvas;
10433
10558
  const out = [];
10434
10559
  const layerId = s.document.activeLayerId;
10435
- const strokePicked = layerId && s.selectedStroke ? _optionalChain([s, 'access', _528 => _528.document, 'access', _529 => _529.liveStrokes, 'optionalAccess', _530 => _530[layerId], 'optionalAccess', _531 => _531.some, 'call', _532 => _532((x) => x.id === s.selectedStroke)]) : false;
10560
+ const strokePicked = layerId && s.selectedStroke ? _optionalChain([s, 'access', _539 => _539.document, 'access', _540 => _540.liveStrokes, 'optionalAccess', _541 => _541[layerId], 'optionalAccess', _542 => _542.some, 'call', _543 => _543((x) => x.id === s.selectedStroke)]) : false;
10436
10561
  const area = strokePicked ? controller.liveStrokeArea(s.selectedStroke) : null;
10437
10562
  if (area) {
10438
10563
  const dx = drag && drag.id === s.selectedStroke ? drag.dx : 0;
@@ -10445,7 +10570,7 @@ function guideOverlay(controller, drag) {
10445
10570
  ];
10446
10571
  for (let i = 0; i < 4; i++) out.push({ from: box[i], to: box[(i + 1) % 4], kind: "stroke" });
10447
10572
  }
10448
- const picked = layerId && s.selectedSticker ? _optionalChain([s, 'access', _533 => _533.document, 'access', _534 => _534.stickers, 'optionalAccess', _535 => _535[layerId], 'optionalAccess', _536 => _536.find, 'call', _537 => _537((x) => x.id === s.selectedSticker)]) : void 0;
10573
+ const picked = layerId && s.selectedSticker ? _optionalChain([s, 'access', _544 => _544.document, 'access', _545 => _545.stickers, 'optionalAccess', _546 => _546[layerId], 'optionalAccess', _547 => _547.find, 'call', _548 => _548((x) => x.id === s.selectedSticker)]) : void 0;
10449
10574
  if (picked) {
10450
10575
  const r = picked.size / 2 + 2;
10451
10576
  const a = picked.rotation * Math.PI / 180;
@@ -10490,7 +10615,7 @@ var PAPER_SLIDERS = [
10490
10615
  ];
10491
10616
  function readPath(obj, path) {
10492
10617
  let v = obj;
10493
- for (const k of path.split(".")) v = _optionalChain([v, 'optionalAccess', _538 => _538[k]]);
10618
+ for (const k of path.split(".")) v = _optionalChain([v, 'optionalAccess', _549 => _549[k]]);
10494
10619
  return typeof v === "number" ? v : 0;
10495
10620
  }
10496
10621
  function patchPath(obj, path, value) {
@@ -10532,8 +10657,8 @@ function wheelPick(dx, dy, wheel, color) {
10532
10657
  return rgbToHexColor(nr, ng, nb);
10533
10658
  }
10534
10659
  var BLEND_MENU_GROUPS = [
10535
- { label: "Standard", modes: _chunkOLNIPTB3cjs.BLEND_MODES.filter((m) => !m.painterly && m.id !== "pigment") },
10536
- { label: "Paint", modes: _chunkOLNIPTB3cjs.BLEND_MODES.filter((m) => m.painterly || m.id === "pigment") }
10660
+ { label: "Standard", modes: _chunk2VX55NFMcjs.BLEND_MODES.filter((m) => !m.painterly && m.id !== "pigment") },
10661
+ { label: "Paint", modes: _chunk2VX55NFMcjs.BLEND_MODES.filter((m) => m.painterly || m.id === "pigment") }
10537
10662
  ];
10538
10663
  var LIGHT_SLIDER = { path: "light.amount", label: "Light", min: 0, max: 1, step: 0.01 };
10539
10664
  var PICKUP_SLIDERS = [
@@ -10542,7 +10667,7 @@ var PICKUP_SLIDERS = [
10542
10667
  ];
10543
10668
  function brushEngineControls(brush) {
10544
10669
  const c = engineControls(brush);
10545
- const wetPaint = brush.engine === "wet" && _optionalChain([brush, 'access', _539 => _539.wet, 'optionalAccess', _540 => _540.tool]) === "paint";
10670
+ const wetPaint = brush.engine === "wet" && _optionalChain([brush, 'access', _550 => _550.wet, 'optionalAccess', _551 => _551.tool]) === "paint";
10546
10671
  if (!c || !(wetPaint || ["dab", "mixer", "particle", "bristle", "impasto"].includes(brush.engine))) return c;
10547
10672
  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 }] : [];
10548
10673
  return { ...c, sliders: [...c.sliders, LIGHT_SLIDER, ...extra], light: true };
@@ -10625,7 +10750,7 @@ function engineControls(brush) {
10625
10750
  impastoTool: true
10626
10751
  };
10627
10752
  case "wet": {
10628
- const tool = _nullishCoalesce(_optionalChain([brush, 'access', _541 => _541.wet, 'optionalAccess', _542 => _542.tool]), () => ( "paint"));
10753
+ const tool = _nullishCoalesce(_optionalChain([brush, 'access', _552 => _552.wet, 'optionalAccess', _553 => _553.tool]), () => ( "paint"));
10629
10754
  const sliders = tool === "paint" ? [
10630
10755
  { path: "wet.water", label: "Water", min: 0, max: 1, step: 0.01 },
10631
10756
  { path: "wet.pigment", label: "Pigment", min: 0, max: 1, step: 0.01 },
@@ -10758,7 +10883,7 @@ function startWetClock(controller, frame, cancel) {
10758
10883
  id = raf(loop);
10759
10884
  return () => {
10760
10885
  stopped = true;
10761
- _optionalChain([caf, 'optionalCall', _543 => _543(id)]);
10886
+ _optionalChain([caf, 'optionalCall', _554 => _554(id)]);
10762
10887
  };
10763
10888
  }
10764
10889
  function drawWaterOverlay(controller, ctx) {
@@ -10787,13 +10912,22 @@ var RIBBON_PAIR_LABELS = { adjacent: "Neighbours", "first-last": "Outermost" };
10787
10912
  var DOT_TEXTURE_ORDER_LABELS = { sequence: "In turn", random: "Random" };
10788
10913
  var DOT_ROTATION_LABELS = { follow: "Follow motion", random: "Random", fixed: "Tip angle" };
10789
10914
  var STAMP_LABELS = { dot: "Dot", star: "Star", heart: "Heart", leaf: "Leaf", flower: "Flower", confetti: "Confetti", splat: "Splat", sparkle: "Sparkle", ring: "Ring" };
10915
+ function toggleStickerRef(refs, ref2) {
10916
+ if (refs.includes(ref2)) return refs.length > 1 ? refs.filter((r) => r !== ref2) : [...refs];
10917
+ return refs.length < _chunkH4AOUUBEcjs.MAX_STICKER_STAMPS ? [...refs, ref2] : [...refs];
10918
+ }
10919
+ function stickerRefLabel(ref2) {
10920
+ const stamp = ref2.startsWith("editor:") ? ref2.slice(7) : null;
10921
+ if (stamp && STAMP_LABELS[stamp]) return STAMP_LABELS[stamp];
10922
+ return ref2.slice(ref2.indexOf(":") + 1);
10923
+ }
10790
10924
  function toggleStamp(stamps, stamp) {
10791
10925
  const next = stamps.includes(stamp) ? stamps.filter((s) => s !== stamp) : [...stamps, stamp];
10792
10926
  return next.length ? next : [stamp];
10793
10927
  }
10794
10928
  function toggleDotTexture(textures, stamp) {
10795
10929
  if (textures.includes(stamp)) return textures.filter((s) => s !== stamp);
10796
- return textures.length < _chunk6G6ZDDDBcjs.MAX_DOT_TEXTURES ? [...textures, stamp] : [...textures];
10930
+ return textures.length < _chunkH4AOUUBEcjs.MAX_DOT_TEXTURES ? [...textures, stamp] : [...textures];
10797
10931
  }
10798
10932
  var STROKE_SLIDERS = [
10799
10933
  { path: "tip.size", label: "Size", min: 1, max: 400, step: 1 },
@@ -11018,7 +11152,7 @@ function createPaintEffectsToolProvider(controller, options = {}) {
11018
11152
  name: { type: "string", minLength: 1, description: "The layer name (default: the effect's name)." },
11019
11153
  aboveId: { type: "string", minLength: 1, description: "Put it directly above this layer (default: above the active layer, else on top)." },
11020
11154
  opacity: { type: "number", minimum: 0, maximum: 1, description: "Layer opacity 0\u20131 (default 1)." },
11021
- blend: { type: "string", enum: _chunkOLNIPTB3cjs.BLEND_MODES.map((m) => m.id), description: "Layer blend mode (default normal); screen or linear-dodge for light, multiply for textures." },
11155
+ blend: { type: "string", enum: _chunk2VX55NFMcjs.BLEND_MODES.map((m) => m.id), description: "Layer blend mode (default normal); screen or linear-dodge for light, multiply for textures." },
11022
11156
  time: { type: "number", minimum: 0, description: "Which moment of an animated effect to draw, in ms (default 0)." }
11023
11157
  },
11024
11158
  required: ["effect"],
@@ -11425,4 +11559,13 @@ function createPaintEditorDocument(controller, options = {}) {
11425
11559
 
11426
11560
 
11427
11561
 
11428
- exports.BACKLIGHT_SPILL = BACKLIGHT_SPILL; exports.BLEND_MENU_GROUPS = BLEND_MENU_GROUPS; exports.BLEND_MODES = _chunkOLNIPTB3cjs.BLEND_MODES; exports.BRUSH_ID = _chunk6G6ZDDDBcjs.BRUSH_ID; exports.BRUSH_ROTATIONS = _chunk6G6ZDDDBcjs.BRUSH_ROTATIONS; exports.BRUSH_SLIDERS = BRUSH_SLIDERS; exports.BUILTIN_BRUSHES = _chunk6G6ZDDDBcjs.BUILTIN_BRUSHES; exports.BristleStroke = _chunk6G6ZDDDBcjs.BristleStroke; exports.DEFAULT_BACKLIGHT_COLOR = DEFAULT_BACKLIGHT_COLOR; exports.DEFAULT_BEHAVIOR = _chunk6G6ZDDDBcjs.DEFAULT_BEHAVIOR; exports.DEFAULT_BRISTLE = _chunk6G6ZDDDBcjs.DEFAULT_BRISTLE; exports.DEFAULT_BRUSH_ID = _chunk6G6ZDDDBcjs.DEFAULT_BRUSH_ID; exports.DEFAULT_DPI = DEFAULT_DPI; exports.DEFAULT_DYNAMICS = _chunk6G6ZDDDBcjs.DEFAULT_DYNAMICS; exports.DEFAULT_FLOW = _chunkVMROIWLLcjs.DEFAULT_FLOW; exports.DEFAULT_IMPASTO = _chunk6G6ZDDDBcjs.DEFAULT_IMPASTO; exports.DEFAULT_LIGHT = _chunk6G6ZDDDBcjs.DEFAULT_LIGHT; exports.DEFAULT_LIGHTING = DEFAULT_LIGHTING; exports.DEFAULT_MULTI_COLOR = _chunk6G6ZDDDBcjs.DEFAULT_MULTI_COLOR; exports.DEFAULT_PAINT_GRADIENT = _chunkPQ3H2AANcjs.DEFAULT_PAINT_GRADIENT; exports.DEFAULT_PAINT_GRADIENT_MAPPING = _chunkPQ3H2AANcjs.DEFAULT_PAINT_GRADIENT_MAPPING; exports.DEFAULT_PAPER = _chunk6G6ZDDDBcjs.DEFAULT_PAPER; exports.DEFAULT_PARTICLE = _chunk6G6ZDDDBcjs.DEFAULT_PARTICLE; exports.DEFAULT_STICKER = _chunk6G6ZDDDBcjs.DEFAULT_STICKER; exports.DEFAULT_SWATCHES = DEFAULT_SWATCHES; exports.DEFAULT_VIEW = DEFAULT_VIEW; exports.DEFAULT_WET_BRUSH = _chunk6G6ZDDDBcjs.DEFAULT_WET_BRUSH; exports.DEFAULT_WET_PARAMS = _chunkVMROIWLLcjs.DEFAULT_WET_PARAMS; exports.DOT_ROTATIONS = _chunk6G6ZDDDBcjs.DOT_ROTATIONS; exports.DOT_ROTATION_LABELS = DOT_ROTATION_LABELS; exports.DOT_TEXTURE_ORDERS = _chunk6G6ZDDDBcjs.DOT_TEXTURE_ORDERS; exports.DOT_TEXTURE_ORDER_LABELS = DOT_TEXTURE_ORDER_LABELS; exports.DryStroke = _chunk6G6ZDDDBcjs.DryStroke; exports.EFFECT_MAP_REPEATS = _chunk6G6ZDDDBcjs.EFFECT_MAP_REPEATS; exports.EFFECT_STRIP_HEIGHT = _chunk6G6ZDDDBcjs.EFFECT_STRIP_HEIGHT; exports.GPU_LEAD = GPU_LEAD; exports.GRAIN_PATTERNS = _chunkPQ3H2AANcjs.GRAIN_PATTERNS; exports.GRAIN_TILE = _chunkPQ3H2AANcjs.GRAIN_TILE; exports.HARMONY_KINDS = _chunk7PT4RJL5cjs.HARMONY_KINDS; exports.IDENTITY_AFFINE = IDENTITY_AFFINE; exports.IDENTITY_COPY = _chunk6G6ZDDDBcjs.IDENTITY_COPY; exports.IMPASTO_TOOLS = _chunk6G6ZDDDBcjs.IMPASTO_TOOLS; exports.IMPASTO_TOOL_LABELS = IMPASTO_TOOL_LABELS; exports.LIGHT_SLIDERS = LIGHT_SLIDERS; exports.LIVE_STROKE_ENGINES = LIVE_STROKE_ENGINES; exports.LitCache = LitCache; exports.MAX_BRUSH_SIZE = _chunkPQ3H2AANcjs.MAX_BRUSH_SIZE; exports.MAX_CANVAS_SIDE = MAX_CANVAS_SIDE; exports.MAX_COORDINATE = MAX_COORDINATE; exports.MAX_DOT_TEXTURES = _chunk6G6ZDDDBcjs.MAX_DOT_TEXTURES; exports.MAX_IMAGE_SIDE = MAX_IMAGE_SIDE; exports.MAX_LIVE_EFFECT_SOURCES = MAX_LIVE_EFFECT_SOURCES; exports.MAX_ZOOM = MAX_ZOOM; exports.MIN_CANVAS_SIDE = MIN_CANVAS_SIDE; exports.MIN_ZOOM = MIN_ZOOM; exports.MIXING_PAD_HEIGHT = MIXING_PAD_HEIGHT; exports.MIXING_PAD_WIDTH = MIXING_PAD_WIDTH; exports.MULTI_COLOR_MODES = _chunk6G6ZDDDBcjs.MULTI_COLOR_MODES; exports.MixingPad = MixingPad; exports.PAD_SAMPLE_SIZES = PAD_SAMPLE_SIZES; exports.PAINTERLY_BLEND_MODES = _chunkOLNIPTB3cjs.PAINTERLY_BLEND_MODES; exports.PAINT_BRUSH_CATEGORIES = _chunk6G6ZDDDBcjs.PAINT_BRUSH_CATEGORIES; exports.PAINT_BRUSH_ENGINES = _chunk6G6ZDDDBcjs.PAINT_BRUSH_ENGINES; exports.PAINT_COLOR_JSON_SCHEMA = _chunkPQ3H2AANcjs.PAINT_COLOR_JSON_SCHEMA; exports.PAINT_EFFECT_PLACES = PAINT_EFFECT_PLACES; exports.PAINT_FORMAT = PAINT_FORMAT; exports.PAINT_GRADIENT_FULL_SPEED = _chunkPQ3H2AANcjs.PAINT_GRADIENT_FULL_SPEED; exports.PAINT_GRADIENT_JSON_SCHEMA = _chunkPQ3H2AANcjs.PAINT_GRADIENT_JSON_SCHEMA; exports.PAINT_GRADIENT_KIT = _chunkPQ3H2AANcjs.PAINT_GRADIENT_KIT; exports.PAINT_GRADIENT_MAPPINGS = _chunkPQ3H2AANcjs.PAINT_GRADIENT_MAPPINGS; exports.PAINT_GRADIENT_MAPPING_LABELS = _chunkPQ3H2AANcjs.PAINT_GRADIENT_MAPPING_LABELS; exports.PAINT_GRADIENT_PRESETS = _chunkPQ3H2AANcjs.PAINT_GRADIENT_PRESETS; exports.PAINT_GRADIENT_REPEATS = _chunkPQ3H2AANcjs.PAINT_GRADIENT_REPEATS; exports.PAINT_GRADIENT_REPEAT_LABELS = _chunkPQ3H2AANcjs.PAINT_GRADIENT_REPEAT_LABELS; exports.PAINT_GRADIENT_SPACES = _chunkPQ3H2AANcjs.PAINT_GRADIENT_SPACES; exports.PAINT_GRADIENT_SPACE_LABELS = _chunkPQ3H2AANcjs.PAINT_GRADIENT_SPACE_LABELS; exports.PAINT_SCHEMA_VERSION = PAINT_SCHEMA_VERSION; exports.PAINT_SOURCE_JSON_SCHEMA = _chunkPQ3H2AANcjs.PAINT_SOURCE_JSON_SCHEMA; exports.PAINT_TARGET = PAINT_TARGET; exports.PAINT_TOOLS = PAINT_TOOLS; exports.PAPER_EFFECT_BLENDS = PAPER_EFFECT_BLENDS; exports.PAPER_EFFECT_NODE_ID = PAPER_EFFECT_NODE_ID; exports.PAPER_FAMILIES = _chunk6G6ZDDDBcjs.PAPER_FAMILIES; exports.PAPER_LIBRARY = _chunk6G6ZDDDBcjs.PAPER_LIBRARY; exports.PAPER_NODE_ID = PAPER_NODE_ID; exports.PAPER_SLIDERS = PAPER_SLIDERS; exports.PAPER_TARGET = PAPER_TARGET; exports.PARTICLE_KINDS = _chunk6G6ZDDDBcjs.PARTICLE_KINDS; exports.PARTICLE_KIND_LABELS = PARTICLE_KIND_LABELS; exports.PARTICLE_RENDERS = _chunk6G6ZDDDBcjs.PARTICLE_RENDERS; exports.PARTICLE_RENDER_LABELS = PARTICLE_RENDER_LABELS; exports.PaintCanvasPresenter = PaintCanvasPresenter; exports.PaintDabStroke = PaintDabStroke; exports.PaintDirector = PaintDirector; exports.PaintDocumentError = PaintDocumentError; exports.PaintEditorController = PaintEditorController; exports.PaintEditorError = PaintEditorError; exports.PaintEffectsRenderer = PaintEffectsRenderer; exports.PaintGesture = PaintGesture; exports.PaintGradientSampler = _chunkPQ3H2AANcjs.PaintGradientSampler; exports.PaintPresence = PaintPresence; exports.PaintSourceError = _chunkPQ3H2AANcjs.PaintSourceError; exports.PaintStrokeSession = PaintStrokeSession; exports.PaintWetLayers = PaintWetLayers; exports.PaperGrain = _chunkPQ3H2AANcjs.PaperGrain; exports.ParticleStroke = _chunk6G6ZDDDBcjs.ParticleStroke; exports.PenDabWalker = _chunk6G6ZDDDBcjs.PenDabWalker; exports.PenSmoother = _chunk6G6ZDDDBcjs.PenSmoother; exports.PerspectiveSnapper = PerspectiveSnapper; exports.RIBBON_PAIRS = _chunk6G6ZDDDBcjs.RIBBON_PAIRS; exports.RIBBON_PAIR_LABELS = RIBBON_PAIR_LABELS; exports.SNAP_DECIDE_DISTANCE = SNAP_DECIDE_DISTANCE; exports.STAMP_KINDS = _chunk6G6ZDDDBcjs.STAMP_KINDS; exports.STAMP_LABELS = STAMP_LABELS; exports.STENCIL_KINDS = STENCIL_KINDS; exports.STENCIL_SHAPES = STENCIL_SHAPES; exports.STICKER_SLIDERS = STICKER_SLIDERS; exports.STROKE_SLIDERS = STROKE_SLIDERS; exports.SYMMETRY_MODES = SYMMETRY_MODES; exports.StencilSnapper = StencilSnapper; exports.StickerSpray = _chunk6G6ZDDDBcjs.StickerSpray; exports.TRACING_NODE_ID = TRACING_NODE_ID; exports.ThickStrokeDriver = ThickStrokeDriver; exports.TileableNoise = _chunkPQ3H2AANcjs.TileableNoise; exports.WET_FLOW_KINDS = _chunkVMROIWLLcjs.WET_FLOW_KINDS; exports.WET_GPU_MODES = WET_GPU_MODES; exports.WET_GPU_OPTIONS = WET_GPU_OPTIONS; exports.WET_MEDIA = _chunk6G6ZDDDBcjs.WET_MEDIA; exports.WET_MEDIUM_LABELS = WET_MEDIUM_LABELS; exports.WET_MEDIUM_PARAMS = WET_MEDIUM_PARAMS; exports.WET_PARAM_KEYS = _chunkVMROIWLLcjs.WET_PARAM_KEYS; exports.WET_PARAM_SCHEMA = WET_PARAM_SCHEMA; exports.WET_PARAM_SLIDERS = WET_PARAM_SLIDERS; exports.WET_SPEED_SLIDER = WET_SPEED_SLIDER; exports.WET_TILT_SLIDERS = WET_TILT_SLIDERS; exports.WET_TOOLS = _chunk6G6ZDDDBcjs.WET_TOOLS; exports.WET_TOOL_LABELS = WET_TOOL_LABELS; exports.WetStrokeDriver = WetStrokeDriver; exports.addPaintGradientStop = _chunkPQ3H2AANcjs.addPaintGradientStop; exports.addPolygonArea = _chunk6G6ZDDDBcjs.addPolygonArea; exports.affineCopy = affineCopy; exports.applyAffine = applyAffine; exports.backlightOf = backlightOf; exports.brushEngineControls = brushEngineControls; exports.brushLoadColor = brushLoadColor; exports.brushLoadForStroke = brushLoadForStroke; exports.brushTakesPaint = _chunk6G6ZDDDBcjs.brushTakesPaint; exports.brushToJSON = _chunk6G6ZDDDBcjs.brushToJSON; exports.buildTimeLapse = buildTimeLapse; exports.checkPaintEffectPlace = checkPaintEffectPlace; exports.clonePaper = _chunk6G6ZDDDBcjs.clonePaper; exports.colorHarmony = colorHarmony2; exports.composeAffine = composeAffine; exports.contactSheet = contactSheet; exports.createPaintCompositor = createPaintCompositor; exports.createPaintDocument = createPaintDocument; exports.createPaintEditorDocument = createPaintEditorDocument; exports.createPaintEditorToolProvider = createPaintEditorToolProvider; exports.createPaintEffectsToolProvider = createPaintEffectsToolProvider; exports.createPaintLayer = createPaintLayer; exports.createPaintReplayTools = createPaintReplayTools; exports.createPaintStickerTools = createPaintStickerTools; exports.createPaintThickTools = createPaintThickTools; exports.createPaintWetTools = createPaintWetTools; exports.decodeImageBlob = decodeImageBlob; exports.defaultGuides = defaultGuides; exports.defaultImageEncoder = defaultImageEncoder; exports.deserializePaintDocument = deserializePaintDocument; exports.deserializePaintDocumentAsync = deserializePaintDocumentAsync; exports.documentExtensions = documentExtensions; exports.documentToScreen = documentToScreen; exports.downloadBytes = downloadBytes; exports.downsampleRgba = downsampleRgba; exports.drawSticker = _chunk6G6ZDDDBcjs.drawSticker; exports.drawWaterOverlay = drawWaterOverlay; exports.effectDabField = _chunk6G6ZDDDBcjs.effectDabField; exports.effectLayersToJSON = effectLayersToJSON; exports.effectPaintKey = _chunk6G6ZDDDBcjs.effectPaintKey; exports.effectPaintSize = _chunk6G6ZDDDBcjs.effectPaintSize; exports.emptiedLayers = emptiedLayers; exports.emptyThickChannels = emptyThickChannels; exports.fitZoom = fitZoom; exports.grainCatch = _chunkPQ3H2AANcjs.grainCatch; exports.grainHeights = _chunkPQ3H2AANcjs.grainHeights; exports.guideOverlay = guideOverlay; exports.handlePaintShortcut = handlePaintShortcut; exports.hash2 = _chunkPQ3H2AANcjs.hash2; exports.hexToPaintRgb = _chunkPQ3H2AANcjs.hexToPaintRgb; exports.hexToRgb8 = _chunk6G6ZDDDBcjs.hexToRgb8; exports.hslToRgb = hslToRgb; exports.hsvToRgb = hsvToRgb; exports.hueToWheel = _chunk7PT4RJL5cjs.hueToWheel; exports.invertAffine = invertAffine; exports.isBlendMode = _chunkOLNIPTB3cjs.isBlendMode; exports.isGradientPaint = _chunkPQ3H2AANcjs.isGradientPaint; exports.isPaintEffectPaint = _chunk6G6ZDDDBcjs.isPaintEffectPaint; exports.isPainterlyBlendMode = _chunkOLNIPTB3cjs.isPainterlyBlendMode; exports.isPalmTouch = isPalmTouch; exports.isWetBrush = _chunk6G6ZDDDBcjs.isWetBrush; exports.isWetCapable = _chunk6G6ZDDDBcjs.isWetCapable; exports.lightTile = lightTile; exports.lightingKey = lightingKey; exports.liveStrokeBounds = liveStrokeBounds; exports.liveStrokeRefusal = liveStrokeRefusal; exports.mapPenPoint = mapPenPoint; exports.mix32 = _chunkPQ3H2AANcjs.mix32; exports.mixPixels = mixPixels; exports.mixerLoadForStroke = mixerLoadForStroke; exports.mixerTip = _chunk6G6ZDDDBcjs.mixerTip; exports.multiColorForDab = multiColorForDab; exports.multiColorGradient = multiColorGradient; exports.multiColorPalette = multiColorPalette; exports.multiColorSliders = multiColorSliders; exports.multiColorToPaint = _chunk6G6ZDDDBcjs.multiColorToPaint; exports.newPaintLayerId = newPaintLayerId; exports.nextPaperEffectVersion = nextPaperEffectVersion; exports.normalizeBehavior = _chunk6G6ZDDDBcjs.normalizeBehavior; exports.normalizeBristle = _chunk6G6ZDDDBcjs.normalizeBristle; exports.normalizeBrushStroke = normalizeBrushStroke; exports.normalizeCanvas = normalizeCanvas; exports.normalizeDynamics = _chunk6G6ZDDDBcjs.normalizeDynamics; exports.normalizeFlow = _chunkVMROIWLLcjs.normalizeFlow; exports.normalizeHexColor = _chunkPQ3H2AANcjs.normalizeHexColor; exports.normalizeImpasto = _chunk6G6ZDDDBcjs.normalizeImpasto; exports.normalizeLight = _chunk6G6ZDDDBcjs.normalizeLight; exports.normalizeLighting = normalizeLighting; exports.normalizeMultiColor = _chunk6G6ZDDDBcjs.normalizeMultiColor; exports.normalizePaintBrush = _chunk6G6ZDDDBcjs.normalizePaintBrush; exports.normalizePaper = _chunk6G6ZDDDBcjs.normalizePaper; exports.normalizeParticle = _chunk6G6ZDDDBcjs.normalizeParticle; exports.normalizePerspective = normalizePerspective; exports.normalizeRotation = normalizeRotation; exports.normalizeStencil = normalizeStencil; exports.normalizeStickerSettings = _chunk6G6ZDDDBcjs.normalizeStickerSettings; exports.normalizeStickerUpdate = _chunk6G6ZDDDBcjs.normalizeStickerUpdate; exports.normalizeSymmetry = normalizeSymmetry; exports.normalizeView = normalizeView; exports.normalizeWetBrush = _chunk6G6ZDDDBcjs.normalizeWetBrush; exports.normalizeWetParams = _chunkVMROIWLLcjs.normalizeWetParams; exports.overPixels = overPixels; exports.padSampleRadius = padSampleRadius; exports.paintGradientMappingFor = _chunkPQ3H2AANcjs.paintGradientMappingFor; exports.paintPlaybackPanel = paintPlaybackPanel; exports.paintSourceColor = _chunkPQ3H2AANcjs.paintSourceColor; exports.paintSourceCss = _chunkPQ3H2AANcjs.paintSourceCss; exports.paintToMultiColor = _chunk6G6ZDDDBcjs.paintToMultiColor; exports.paperEffectFromJSON = paperEffectFromJSON; exports.paperEffectToJSON = paperEffectToJSON; exports.paperGrain = paperGrain; exports.paperKey = paperKey; exports.paperNode = paperNode; exports.paperPreset = _chunk6G6ZDDDBcjs.paperPreset; exports.parseBrushLibrary = _chunk6G6ZDDDBcjs.parseBrushLibrary; exports.parseHexColor = parseHexColor; exports.parsePaintSource = _chunkPQ3H2AANcjs.parsePaintSource; exports.patchBrushValue = patchBrushValue; exports.patchPath = patchPath; exports.penOrientation = _chunk6G6ZDDDBcjs.penOrientation; exports.perspectiveDirections = perspectiveDirections; exports.perspectiveGuideLines = perspectiveGuideLines; exports.planPaintToolPlayback = planPaintToolPlayback; exports.pointerToPenPoint = pointerToPenPoint; exports.quickStencil = quickStencil; exports.rand01 = _chunkPQ3H2AANcjs.rand01; exports.randSigned = _chunkPQ3H2AANcjs.randSigned; exports.readEffectStrokeMap = _chunk6G6ZDDDBcjs.readEffectStrokeMap; exports.readPaintEffectPaint = _chunk6G6ZDDDBcjs.readPaintEffectPaint; exports.readPaintEffectSource = readPaintEffectSource; exports.readPaintSource = _chunkPQ3H2AANcjs.readPaintSource; exports.readPath = readPath; exports.readSwatch = readSwatch; exports.reliefInfo = reliefInfo; exports.removePaintGradientStop = _chunkPQ3H2AANcjs.removePaintGradientStop; exports.renderBrushThumbnail = renderBrushThumbnail; exports.renderColorWheel = renderColorWheel; exports.renderPaper = _chunk6G6ZDDDBcjs.renderPaper; exports.renderStickers = _chunk6G6ZDDDBcjs.renderStickers; exports.replayFrame = replayFrame; exports.replayItems = replayItems; exports.replayPainting = replayPainting; exports.resolvePaintGradient = _chunkPQ3H2AANcjs.resolvePaintGradient; exports.reversePaintGradient = _chunkPQ3H2AANcjs.reversePaintGradient; exports.rgbToHexColor = rgbToHexColor; exports.rgbToHsl = rgbToHsl; exports.rgbToHsv = rgbToHsv; exports.sampleEffectAt = _chunk6G6ZDDDBcjs.sampleEffectAt; exports.sampleEffectField = _chunk6G6ZDDDBcjs.sampleEffectField; exports.samplePressure = samplePressure; exports.scalePaintGradient = _chunkPQ3H2AANcjs.scalePaintGradient; exports.scaleStencil = scaleStencil; exports.screenToDocument = screenToDocument; exports.seedFromString = _chunkPQ3H2AANcjs.seedFromString; exports.serializePaintDocument = serializePaintDocument; exports.serializePaintDocumentExternal = serializePaintDocumentExternal; exports.solidPaint = _chunkPQ3H2AANcjs.solidPaint; exports.stampCoverage = _chunk6G6ZDDDBcjs.stampCoverage; exports.standardBlendMode = _chunkOLNIPTB3cjs.standardBlendMode; exports.startWetClock = startWetClock; exports.stencilMask = stencilMask; exports.stencilOutline = stencilOutline; exports.stickerAt = _chunk6G6ZDDDBcjs.stickerAt; exports.stickerRect = _chunk6G6ZDDDBcjs.stickerRect; exports.stickerSurface = _chunk6G6ZDDDBcjs.stickerSurface; exports.strokeBounds = strokeBounds; exports.strokeDuration = strokeDuration; exports.strokeSchedule = strokeSchedule; exports.sweepPath = sweepPath; exports.symmetryAxisAngles = symmetryAxisAngles; exports.symmetryAxisSegments = symmetryAxisSegments; exports.symmetryCopies = symmetryCopies; exports.thickFromJSON = thickFromJSON; exports.thickToJSON = thickToJSON; exports.thumbnailStroke = thumbnailStroke; exports.tiltToOrientation = _chunk6G6ZDDDBcjs.tiltToOrientation; exports.timeLapseVideo = timeLapseVideo; exports.timeLapseZip = timeLapseZip; exports.toStrokePoint = _chunk6G6ZDDDBcjs.toStrokePoint; exports.toggleDotTexture = toggleDotTexture; exports.toggleStamp = toggleStamp; exports.translateStencil = translateStencil; exports.updatePaintGradientStop = _chunkPQ3H2AANcjs.updatePaintGradientStop; exports.usesPaintExchange = _chunk6G6ZDDDBcjs.usesPaintExchange; exports.variationAffine = variationAffine; exports.varyStroke = varyStroke; exports.viewCssTransform = viewCssTransform; exports.viewMatrix = viewMatrix; exports.viewPenToDocument = viewPenToDocument; exports.wetEngineSummary = wetEngineSummary; exports.wetPaperInput = wetPaperInput; exports.wetPigmentOf = wetPigmentOf; exports.wetSupport = _chunkVMROIWLLcjs.wetSupport; exports.wheelAngle = wheelAngle; exports.wheelPick = wheelPick; exports.wheelPoint = wheelPoint; exports.wheelToHue = _chunk7PT4RJL5cjs.wheelToHue; exports.withPaintPlayback = withPaintPlayback;
11562
+
11563
+
11564
+
11565
+
11566
+
11567
+
11568
+
11569
+
11570
+
11571
+ exports.BACKLIGHT_SPILL = BACKLIGHT_SPILL; exports.BLEND_MENU_GROUPS = BLEND_MENU_GROUPS; exports.BLEND_MODES = _chunk2VX55NFMcjs.BLEND_MODES; exports.BRUSH_ID = _chunkH4AOUUBEcjs.BRUSH_ID; exports.BRUSH_ROTATIONS = _chunkH4AOUUBEcjs.BRUSH_ROTATIONS; exports.BRUSH_SLIDERS = BRUSH_SLIDERS; exports.BUILTIN_BRUSHES = _chunkH4AOUUBEcjs.BUILTIN_BRUSHES; exports.BristleStroke = _chunkH4AOUUBEcjs.BristleStroke; exports.DEFAULT_BACKLIGHT_COLOR = DEFAULT_BACKLIGHT_COLOR; exports.DEFAULT_BEHAVIOR = _chunkH4AOUUBEcjs.DEFAULT_BEHAVIOR; exports.DEFAULT_BRISTLE = _chunkH4AOUUBEcjs.DEFAULT_BRISTLE; exports.DEFAULT_BRUSH_ID = _chunkH4AOUUBEcjs.DEFAULT_BRUSH_ID; exports.DEFAULT_DPI = DEFAULT_DPI; exports.DEFAULT_DYNAMICS = _chunkH4AOUUBEcjs.DEFAULT_DYNAMICS; exports.DEFAULT_FLOW = _chunkKBYB7OWBcjs.DEFAULT_FLOW; exports.DEFAULT_IMPASTO = _chunkH4AOUUBEcjs.DEFAULT_IMPASTO; exports.DEFAULT_LIGHT = _chunkH4AOUUBEcjs.DEFAULT_LIGHT; exports.DEFAULT_LIGHTING = DEFAULT_LIGHTING; exports.DEFAULT_MULTI_COLOR = _chunkH4AOUUBEcjs.DEFAULT_MULTI_COLOR; exports.DEFAULT_PAINT_GRADIENT = _chunkI7NJPHWVcjs.DEFAULT_PAINT_GRADIENT; exports.DEFAULT_PAINT_GRADIENT_MAPPING = _chunkI7NJPHWVcjs.DEFAULT_PAINT_GRADIENT_MAPPING; exports.DEFAULT_PAPER = _chunkH4AOUUBEcjs.DEFAULT_PAPER; exports.DEFAULT_PARTICLE = _chunkH4AOUUBEcjs.DEFAULT_PARTICLE; exports.DEFAULT_STICKER = _chunkH4AOUUBEcjs.DEFAULT_STICKER; exports.DEFAULT_SWATCHES = DEFAULT_SWATCHES; exports.DEFAULT_VIEW = DEFAULT_VIEW; exports.DEFAULT_WET_BRUSH = _chunkH4AOUUBEcjs.DEFAULT_WET_BRUSH; exports.DEFAULT_WET_PARAMS = _chunkKBYB7OWBcjs.DEFAULT_WET_PARAMS; exports.DOT_ROTATIONS = _chunkH4AOUUBEcjs.DOT_ROTATIONS; exports.DOT_ROTATION_LABELS = DOT_ROTATION_LABELS; exports.DOT_TEXTURE_ORDERS = _chunkH4AOUUBEcjs.DOT_TEXTURE_ORDERS; exports.DOT_TEXTURE_ORDER_LABELS = DOT_TEXTURE_ORDER_LABELS; exports.DryStroke = _chunkH4AOUUBEcjs.DryStroke; exports.EFFECT_MAP_REPEATS = _chunkH4AOUUBEcjs.EFFECT_MAP_REPEATS; exports.EFFECT_STRIP_HEIGHT = _chunkH4AOUUBEcjs.EFFECT_STRIP_HEIGHT; exports.GPU_LEAD = GPU_LEAD; exports.GRAIN_PATTERNS = _chunkI7NJPHWVcjs.GRAIN_PATTERNS; exports.GRAIN_TILE = _chunkI7NJPHWVcjs.GRAIN_TILE; exports.HARMONY_KINDS = _chunk7PT4RJL5cjs.HARMONY_KINDS; exports.IDENTITY_AFFINE = IDENTITY_AFFINE; exports.IDENTITY_COPY = _chunkH4AOUUBEcjs.IDENTITY_COPY; exports.IMPASTO_TOOLS = _chunkH4AOUUBEcjs.IMPASTO_TOOLS; exports.IMPASTO_TOOL_LABELS = IMPASTO_TOOL_LABELS; exports.LIGHT_SLIDERS = LIGHT_SLIDERS; exports.LIVE_STROKE_ENGINES = LIVE_STROKE_ENGINES; exports.LitCache = LitCache; exports.MAX_BRUSH_SIZE = _chunkI7NJPHWVcjs.MAX_BRUSH_SIZE; exports.MAX_CANVAS_SIDE = MAX_CANVAS_SIDE; exports.MAX_COORDINATE = MAX_COORDINATE; exports.MAX_DOT_TEXTURES = _chunkH4AOUUBEcjs.MAX_DOT_TEXTURES; exports.MAX_IMAGE_SIDE = MAX_IMAGE_SIDE; exports.MAX_LIVE_EFFECT_SOURCES = MAX_LIVE_EFFECT_SOURCES; exports.MAX_STICKER_STAMPS = _chunkH4AOUUBEcjs.MAX_STICKER_STAMPS; exports.MAX_ZOOM = MAX_ZOOM; exports.MIN_CANVAS_SIDE = MIN_CANVAS_SIDE; exports.MIN_ZOOM = MIN_ZOOM; exports.MIXING_PAD_HEIGHT = MIXING_PAD_HEIGHT; exports.MIXING_PAD_WIDTH = MIXING_PAD_WIDTH; exports.MULTI_COLOR_MODES = _chunkH4AOUUBEcjs.MULTI_COLOR_MODES; exports.MixingPad = MixingPad; exports.PAD_SAMPLE_SIZES = PAD_SAMPLE_SIZES; exports.PAINTERLY_BLEND_MODES = _chunk2VX55NFMcjs.PAINTERLY_BLEND_MODES; exports.PAINT_BRUSH_CATEGORIES = _chunkH4AOUUBEcjs.PAINT_BRUSH_CATEGORIES; exports.PAINT_BRUSH_ENGINES = _chunkH4AOUUBEcjs.PAINT_BRUSH_ENGINES; exports.PAINT_COLOR_JSON_SCHEMA = _chunkI7NJPHWVcjs.PAINT_COLOR_JSON_SCHEMA; exports.PAINT_EFFECT_PLACES = PAINT_EFFECT_PLACES; exports.PAINT_FORMAT = PAINT_FORMAT; exports.PAINT_GRADIENT_FULL_SPEED = _chunkI7NJPHWVcjs.PAINT_GRADIENT_FULL_SPEED; exports.PAINT_GRADIENT_JSON_SCHEMA = _chunkI7NJPHWVcjs.PAINT_GRADIENT_JSON_SCHEMA; exports.PAINT_GRADIENT_KIT = _chunkI7NJPHWVcjs.PAINT_GRADIENT_KIT; exports.PAINT_GRADIENT_MAPPINGS = _chunkI7NJPHWVcjs.PAINT_GRADIENT_MAPPINGS; exports.PAINT_GRADIENT_MAPPING_LABELS = _chunkI7NJPHWVcjs.PAINT_GRADIENT_MAPPING_LABELS; exports.PAINT_GRADIENT_PRESETS = _chunkI7NJPHWVcjs.PAINT_GRADIENT_PRESETS; exports.PAINT_GRADIENT_REPEATS = _chunkI7NJPHWVcjs.PAINT_GRADIENT_REPEATS; exports.PAINT_GRADIENT_REPEAT_LABELS = _chunkI7NJPHWVcjs.PAINT_GRADIENT_REPEAT_LABELS; exports.PAINT_GRADIENT_SPACES = _chunkI7NJPHWVcjs.PAINT_GRADIENT_SPACES; exports.PAINT_GRADIENT_SPACE_LABELS = _chunkI7NJPHWVcjs.PAINT_GRADIENT_SPACE_LABELS; exports.PAINT_SCHEMA_VERSION = PAINT_SCHEMA_VERSION; exports.PAINT_SOURCE_JSON_SCHEMA = _chunkI7NJPHWVcjs.PAINT_SOURCE_JSON_SCHEMA; exports.PAINT_TARGET = PAINT_TARGET; exports.PAINT_TOOLS = PAINT_TOOLS; exports.PAPER_EFFECT_BLENDS = PAPER_EFFECT_BLENDS; exports.PAPER_EFFECT_NODE_ID = PAPER_EFFECT_NODE_ID; exports.PAPER_FAMILIES = _chunkH4AOUUBEcjs.PAPER_FAMILIES; exports.PAPER_LIBRARY = _chunkH4AOUUBEcjs.PAPER_LIBRARY; exports.PAPER_NODE_ID = PAPER_NODE_ID; exports.PAPER_SLIDERS = PAPER_SLIDERS; exports.PAPER_TARGET = PAPER_TARGET; exports.PARTICLE_KINDS = _chunkH4AOUUBEcjs.PARTICLE_KINDS; exports.PARTICLE_KIND_LABELS = PARTICLE_KIND_LABELS; exports.PARTICLE_RENDERS = _chunkH4AOUUBEcjs.PARTICLE_RENDERS; exports.PARTICLE_RENDER_LABELS = PARTICLE_RENDER_LABELS; exports.PaintCanvasPresenter = PaintCanvasPresenter; exports.PaintDabStroke = PaintDabStroke; exports.PaintDirector = PaintDirector; exports.PaintDocumentError = PaintDocumentError; exports.PaintEditorController = PaintEditorController; exports.PaintEditorError = PaintEditorError; exports.PaintEffectsRenderer = PaintEffectsRenderer; exports.PaintGesture = PaintGesture; exports.PaintGradientSampler = _chunkI7NJPHWVcjs.PaintGradientSampler; exports.PaintPresence = PaintPresence; exports.PaintSourceError = _chunkI7NJPHWVcjs.PaintSourceError; exports.PaintStrokeSession = PaintStrokeSession; exports.PaintWetLayers = PaintWetLayers; exports.PaperGrain = _chunkI7NJPHWVcjs.PaperGrain; exports.ParticleStroke = _chunkH4AOUUBEcjs.ParticleStroke; exports.PenDabWalker = _chunkH4AOUUBEcjs.PenDabWalker; exports.PenSmoother = _chunkH4AOUUBEcjs.PenSmoother; exports.PerspectiveSnapper = PerspectiveSnapper; exports.RIBBON_PAIRS = _chunkH4AOUUBEcjs.RIBBON_PAIRS; exports.RIBBON_PAIR_LABELS = RIBBON_PAIR_LABELS; exports.SNAP_DECIDE_DISTANCE = SNAP_DECIDE_DISTANCE; exports.STAMP_KINDS = _chunkZEYMKDYScjs.STAMP_KINDS; exports.STAMP_LABELS = STAMP_LABELS; exports.STENCIL_KINDS = STENCIL_KINDS; exports.STENCIL_SHAPES = STENCIL_SHAPES; exports.STICKER_ART_SIZE = _chunkH4AOUUBEcjs.STICKER_ART_SIZE; exports.STICKER_SLIDERS = STICKER_SLIDERS; exports.STROKE_SLIDERS = STROKE_SLIDERS; exports.SYMMETRY_MODES = SYMMETRY_MODES; exports.StencilSnapper = StencilSnapper; exports.StickerArtCache = _chunkH4AOUUBEcjs.StickerArtCache; exports.StickerBrowser = _chunkLJRCU3BJcjs.StickerBrowser; exports.StickerSpray = _chunkH4AOUUBEcjs.StickerSpray; exports.TRACING_NODE_ID = TRACING_NODE_ID; exports.ThickStrokeDriver = ThickStrokeDriver; exports.TileableNoise = _chunk3K6HWEXZcjs.TileableNoise; exports.WET_FLOW_KINDS = _chunkKBYB7OWBcjs.WET_FLOW_KINDS; exports.WET_GPU_MODES = WET_GPU_MODES; exports.WET_GPU_OPTIONS = WET_GPU_OPTIONS; exports.WET_MEDIA = _chunkH4AOUUBEcjs.WET_MEDIA; exports.WET_MEDIUM_LABELS = WET_MEDIUM_LABELS; exports.WET_MEDIUM_PARAMS = WET_MEDIUM_PARAMS; exports.WET_PARAM_KEYS = _chunkKBYB7OWBcjs.WET_PARAM_KEYS; exports.WET_PARAM_SCHEMA = WET_PARAM_SCHEMA; exports.WET_PARAM_SLIDERS = WET_PARAM_SLIDERS; exports.WET_SPEED_SLIDER = WET_SPEED_SLIDER; exports.WET_TILT_SLIDERS = WET_TILT_SLIDERS; exports.WET_TOOLS = _chunkH4AOUUBEcjs.WET_TOOLS; exports.WET_TOOL_LABELS = WET_TOOL_LABELS; exports.WetStrokeDriver = WetStrokeDriver; exports.addPaintGradientStop = _chunkI7NJPHWVcjs.addPaintGradientStop; exports.addPolygonArea = _chunkH4AOUUBEcjs.addPolygonArea; exports.affineCopy = affineCopy; exports.applyAffine = applyAffine; exports.backlightOf = backlightOf; exports.brushEngineControls = brushEngineControls; exports.brushLoadColor = brushLoadColor; exports.brushLoadForStroke = brushLoadForStroke; exports.brushTakesPaint = _chunkH4AOUUBEcjs.brushTakesPaint; exports.brushToJSON = _chunkH4AOUUBEcjs.brushToJSON; exports.buildTimeLapse = buildTimeLapse; exports.checkPaintEffectPlace = checkPaintEffectPlace; exports.clonePaper = _chunkH4AOUUBEcjs.clonePaper; exports.colorHarmony = colorHarmony2; exports.composeAffine = composeAffine; exports.contactSheet = contactSheet; exports.createPaintCompositor = createPaintCompositor; exports.createPaintDocument = createPaintDocument; exports.createPaintEditorDocument = createPaintEditorDocument; exports.createPaintEditorToolProvider = createPaintEditorToolProvider; exports.createPaintEffectsToolProvider = createPaintEffectsToolProvider; exports.createPaintLayer = createPaintLayer; exports.createPaintReplayTools = createPaintReplayTools; exports.createPaintStickerTools = createPaintStickerTools; exports.createPaintThickTools = createPaintThickTools; exports.createPaintWetTools = createPaintWetTools; exports.decodeImageBlob = decodeImageBlob; exports.defaultGuides = defaultGuides; exports.defaultImageEncoder = defaultImageEncoder; exports.defaultStickerRasterizer = _chunkH4AOUUBEcjs.defaultStickerRasterizer; exports.deserializePaintDocument = deserializePaintDocument; exports.deserializePaintDocumentAsync = deserializePaintDocumentAsync; exports.documentExtensions = documentExtensions; exports.documentToScreen = documentToScreen; exports.downloadBytes = downloadBytes; exports.downsampleRgba = downsampleRgba; exports.drawSticker = _chunkH4AOUUBEcjs.drawSticker; exports.drawWaterOverlay = drawWaterOverlay; exports.effectDabField = _chunkH4AOUUBEcjs.effectDabField; exports.effectLayersToJSON = effectLayersToJSON; exports.effectPaintKey = _chunkH4AOUUBEcjs.effectPaintKey; exports.effectPaintSize = _chunkH4AOUUBEcjs.effectPaintSize; exports.emptiedLayers = emptiedLayers; exports.emptyThickChannels = emptyThickChannels; exports.fitZoom = fitZoom; exports.grainCatch = _chunkI7NJPHWVcjs.grainCatch; exports.grainHeights = _chunkI7NJPHWVcjs.grainHeights; exports.guideOverlay = guideOverlay; exports.handlePaintShortcut = handlePaintShortcut; exports.hash2 = _chunk3K6HWEXZcjs.hash2; exports.hexToPaintRgb = _chunkI7NJPHWVcjs.hexToPaintRgb; exports.hexToRgb8 = _chunkH4AOUUBEcjs.hexToRgb8; exports.hslToRgb = hslToRgb; exports.hsvToRgb = hsvToRgb; exports.hueToWheel = _chunk7PT4RJL5cjs.hueToWheel; exports.invertAffine = invertAffine; exports.isBlendMode = _chunk2VX55NFMcjs.isBlendMode; exports.isGradientPaint = _chunkI7NJPHWVcjs.isGradientPaint; exports.isPaintEffectPaint = _chunkH4AOUUBEcjs.isPaintEffectPaint; exports.isPainterlyBlendMode = _chunk2VX55NFMcjs.isPainterlyBlendMode; exports.isPalmTouch = isPalmTouch; exports.isWetBrush = _chunkH4AOUUBEcjs.isWetBrush; exports.isWetCapable = _chunkH4AOUUBEcjs.isWetCapable; exports.lightTile = lightTile; exports.lightingKey = lightingKey; exports.liveStrokeBounds = liveStrokeBounds; exports.liveStrokeRefusal = liveStrokeRefusal; exports.mapPenPoint = mapPenPoint; exports.mix32 = _chunk3K6HWEXZcjs.mix32; exports.mixPixels = mixPixels; exports.mixerLoadForStroke = mixerLoadForStroke; exports.mixerTip = _chunkH4AOUUBEcjs.mixerTip; exports.multiColorForDab = multiColorForDab; exports.multiColorGradient = multiColorGradient; exports.multiColorPalette = multiColorPalette; exports.multiColorSliders = multiColorSliders; exports.multiColorToPaint = _chunkH4AOUUBEcjs.multiColorToPaint; exports.newPaintLayerId = newPaintLayerId; exports.nextPaperEffectVersion = nextPaperEffectVersion; exports.normalizeBehavior = _chunkH4AOUUBEcjs.normalizeBehavior; exports.normalizeBristle = _chunkH4AOUUBEcjs.normalizeBristle; exports.normalizeBrushStroke = normalizeBrushStroke; exports.normalizeCanvas = normalizeCanvas; exports.normalizeDynamics = _chunkH4AOUUBEcjs.normalizeDynamics; exports.normalizeFlow = _chunkKBYB7OWBcjs.normalizeFlow; exports.normalizeHexColor = _chunkI7NJPHWVcjs.normalizeHexColor; exports.normalizeImpasto = _chunkH4AOUUBEcjs.normalizeImpasto; exports.normalizeLight = _chunkH4AOUUBEcjs.normalizeLight; exports.normalizeLighting = normalizeLighting; exports.normalizeMultiColor = _chunkH4AOUUBEcjs.normalizeMultiColor; exports.normalizePaintBrush = _chunkH4AOUUBEcjs.normalizePaintBrush; exports.normalizePaper = _chunkH4AOUUBEcjs.normalizePaper; exports.normalizeParticle = _chunkH4AOUUBEcjs.normalizeParticle; exports.normalizePerspective = normalizePerspective; exports.normalizeRotation = normalizeRotation; exports.normalizeStencil = normalizeStencil; exports.normalizeStickerSettings = _chunkH4AOUUBEcjs.normalizeStickerSettings; exports.normalizeStickerUpdate = _chunkH4AOUUBEcjs.normalizeStickerUpdate; exports.normalizeSymmetry = normalizeSymmetry; exports.normalizeView = normalizeView; exports.normalizeWetBrush = _chunkH4AOUUBEcjs.normalizeWetBrush; exports.normalizeWetParams = _chunkKBYB7OWBcjs.normalizeWetParams; exports.overPixels = overPixels; exports.padSampleRadius = padSampleRadius; exports.paintGradientMappingFor = _chunkI7NJPHWVcjs.paintGradientMappingFor; exports.paintPlaybackPanel = paintPlaybackPanel; exports.paintSourceColor = _chunkI7NJPHWVcjs.paintSourceColor; exports.paintSourceCss = _chunkI7NJPHWVcjs.paintSourceCss; exports.paintToMultiColor = _chunkH4AOUUBEcjs.paintToMultiColor; exports.paperEffectFromJSON = paperEffectFromJSON; exports.paperEffectToJSON = paperEffectToJSON; exports.paperGrain = paperGrain; exports.paperKey = paperKey; exports.paperNode = paperNode; exports.paperPreset = _chunkH4AOUUBEcjs.paperPreset; exports.parseBrushLibrary = _chunkH4AOUUBEcjs.parseBrushLibrary; exports.parseHexColor = parseHexColor; exports.parsePaintSource = _chunkI7NJPHWVcjs.parsePaintSource; exports.patchBrushValue = patchBrushValue; exports.patchPath = patchPath; exports.penOrientation = _chunkH4AOUUBEcjs.penOrientation; exports.perspectiveDirections = perspectiveDirections; exports.perspectiveGuideLines = perspectiveGuideLines; exports.planPaintToolPlayback = planPaintToolPlayback; exports.pointerToPenPoint = pointerToPenPoint; exports.quickStencil = quickStencil; exports.rand01 = _chunk3K6HWEXZcjs.rand01; exports.randSigned = _chunk3K6HWEXZcjs.randSigned; exports.readEffectStrokeMap = _chunkH4AOUUBEcjs.readEffectStrokeMap; exports.readPaintEffectPaint = _chunkH4AOUUBEcjs.readPaintEffectPaint; exports.readPaintEffectSource = readPaintEffectSource; exports.readPaintSource = _chunkI7NJPHWVcjs.readPaintSource; exports.readPath = readPath; exports.readSwatch = readSwatch; exports.reliefInfo = reliefInfo; exports.removePaintGradientStop = _chunkI7NJPHWVcjs.removePaintGradientStop; exports.renderBrushThumbnail = renderBrushThumbnail; exports.renderColorWheel = renderColorWheel; exports.renderPaper = _chunkH4AOUUBEcjs.renderPaper; exports.renderStickers = _chunkH4AOUUBEcjs.renderStickers; exports.replayFrame = replayFrame; exports.replayItems = replayItems; exports.replayPainting = replayPainting; exports.resolvePaintGradient = _chunkI7NJPHWVcjs.resolvePaintGradient; exports.reversePaintGradient = _chunkI7NJPHWVcjs.reversePaintGradient; exports.rgbToHexColor = rgbToHexColor; exports.rgbToHsl = rgbToHsl; exports.rgbToHsv = rgbToHsv; exports.sampleArt = _chunkH4AOUUBEcjs.sampleArt; exports.sampleEffectAt = _chunkH4AOUUBEcjs.sampleEffectAt; exports.sampleEffectField = _chunkH4AOUUBEcjs.sampleEffectField; exports.samplePressure = samplePressure; exports.scalePaintGradient = _chunkI7NJPHWVcjs.scalePaintGradient; exports.scaleStencil = scaleStencil; exports.screenToDocument = screenToDocument; exports.seedFromString = _chunk3K6HWEXZcjs.seedFromString; exports.serializePaintDocument = serializePaintDocument; exports.serializePaintDocumentExternal = serializePaintDocumentExternal; exports.solidPaint = _chunkI7NJPHWVcjs.solidPaint; exports.stampCoverage = _chunkZEYMKDYScjs.stampCoverage; exports.standardBlendMode = _chunk2VX55NFMcjs.standardBlendMode; exports.startWetClock = startWetClock; exports.stencilMask = stencilMask; exports.stencilOutline = stencilOutline; exports.stickerAt = _chunkH4AOUUBEcjs.stickerAt; exports.stickerRect = _chunkH4AOUUBEcjs.stickerRect; exports.stickerRefLabel = stickerRefLabel; exports.stickerStamp = _chunkH4AOUUBEcjs.stickerStamp; exports.stickerSurface = _chunkH4AOUUBEcjs.stickerSurface; exports.strokeBounds = strokeBounds; exports.strokeDuration = strokeDuration; exports.strokeSchedule = strokeSchedule; exports.sweepPath = sweepPath; exports.symmetryAxisAngles = symmetryAxisAngles; exports.symmetryAxisSegments = symmetryAxisSegments; exports.symmetryCopies = symmetryCopies; exports.thickFromJSON = thickFromJSON; exports.thickToJSON = thickToJSON; exports.thumbnailStroke = thumbnailStroke; exports.tiltToOrientation = _chunkH4AOUUBEcjs.tiltToOrientation; exports.timeLapseVideo = timeLapseVideo; exports.timeLapseZip = timeLapseZip; exports.toStrokePoint = _chunkH4AOUUBEcjs.toStrokePoint; exports.toggleDotTexture = toggleDotTexture; exports.toggleStamp = toggleStamp; exports.toggleStickerRef = toggleStickerRef; exports.translateStencil = translateStencil; exports.updatePaintGradientStop = _chunkI7NJPHWVcjs.updatePaintGradientStop; exports.usesPaintExchange = _chunkH4AOUUBEcjs.usesPaintExchange; exports.variationAffine = variationAffine; exports.varyStroke = varyStroke; exports.viewCssTransform = viewCssTransform; exports.viewMatrix = viewMatrix; exports.viewPenToDocument = viewPenToDocument; exports.wetEngineSummary = wetEngineSummary; exports.wetPaperInput = wetPaperInput; exports.wetPigmentOf = wetPigmentOf; exports.wetSupport = _chunkKBYB7OWBcjs.wetSupport; exports.wheelAngle = wheelAngle; exports.wheelPick = wheelPick; exports.wheelPoint = wheelPoint; exports.wheelToHue = _chunk7PT4RJL5cjs.wheelToHue; exports.withPaintPlayback = withPaintPlayback;