@pixerate/editor 0.257.0 → 0.258.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.
@@ -3055,7 +3055,8 @@ var PaintStrokeSession = (_class12 = class _PaintStrokeSession {
3055
3055
  if (filter) points = points.map(filter);
3056
3056
  for (const p of points) this.points.push(p);
3057
3057
  this.lastRaw = points[points.length - 1];
3058
- _optionalChain([this, 'access', _66 => _66.lightTwin, 'optionalAccess', _67 => _67.push, 'call', _68 => _68(points)]);
3058
+ _optionalChain([this, 'access', _66 => _66.host, 'access', _67 => _67.sampled, 'optionalCall', _68 => _68(this, points)]);
3059
+ _optionalChain([this, 'access', _69 => _69.lightTwin, 'optionalAccess', _70 => _70.push, 'call', _71 => _71(points)]);
3059
3060
  if (this.wetDriver) {
3060
3061
  this.wetUpdate(this.wetDriver.push(points));
3061
3062
  return;
@@ -3068,7 +3069,7 @@ var PaintStrokeSession = (_class12 = class _PaintStrokeSession {
3068
3069
  }
3069
3070
  /** Impasto strokes: the layer's thick-paint channels with the stroke so far. */
3070
3071
  thickChannels() {
3071
- return _nullishCoalesce(_optionalChain([this, 'access', _69 => _69.thickDriver, 'optionalAccess', _70 => _70.channels, 'call', _71 => _71()]), () => ( null));
3072
+ return _nullishCoalesce(_optionalChain([this, 'access', _72 => _72.thickDriver, 'optionalAccess', _73 => _73.channels, 'call', _74 => _74()]), () => ( null));
3072
3073
  }
3073
3074
  /** Shows a wet stroke's progress (the wet layer's display). */
3074
3075
  wetUpdate(rects) {
@@ -3114,8 +3115,8 @@ var PaintStrokeSession = (_class12 = class _PaintStrokeSession {
3114
3115
  }
3115
3116
  }
3116
3117
  for (const [key, { tx, ty, r }] of regions) {
3117
- const src = _nullishCoalesce(_optionalChain([this, 'access', _72 => _72.base, 'access', _73 => _73.tiles, 'access', _74 => _74.get, 'call', _75 => _75(key), 'optionalAccess', _76 => _76.data]), () => ( defaultTile(this.base)));
3118
- const prev = this.touched.has(key) ? _optionalChain([this, 'access', _77 => _77.live, 'access', _78 => _78.get, 'call', _79 => _79(key), 'optionalAccess', _80 => _80.data]) : void 0;
3118
+ const src = _nullishCoalesce(_optionalChain([this, 'access', _75 => _75.base, 'access', _76 => _76.tiles, 'access', _77 => _77.get, 'call', _78 => _78(key), 'optionalAccess', _79 => _79.data]), () => ( defaultTile(this.base)));
3119
+ const prev = this.touched.has(key) ? _optionalChain([this, 'access', _80 => _80.live, 'access', _81 => _81.get, 'call', _82 => _82(key), 'optionalAccess', _83 => _83.data]) : void 0;
3119
3120
  this.touched.add(key);
3120
3121
  const data = _chunkFQPUF2W2cjs.applyStrokeToTile.call(void 0, this.dry.coverage, src, ch, tx, ty, this.apply, prev ? { into: prev, region: r } : {});
3121
3122
  this.live.set(key, { data, uniform: null });
@@ -3137,7 +3138,7 @@ var PaintStrokeSession = (_class12 = class _PaintStrokeSession {
3137
3138
  }
3138
3139
  this.update(this.dry ? this.dry.finish() : this.thickDriver ? this.thickDriver.finish() : this.stickerSpray ? this.stickerSpray.finish() : this.wet.finish());
3139
3140
  this.closed = true;
3140
- if (_optionalChain([this, 'access', _81 => _81.lightTwin, 'optionalAccess', _82 => _82.open])) this.lightTwin.end();
3141
+ if (_optionalChain([this, 'access', _84 => _84.lightTwin, 'optionalAccess', _85 => _85.open])) this.lightTwin.end();
3141
3142
  const ch = this.base.channels;
3142
3143
  const tiles = new Map(this.base.tiles);
3143
3144
  let changed = false;
@@ -3152,8 +3153,8 @@ var PaintStrokeSession = (_class12 = class _PaintStrokeSession {
3152
3153
  const surface = changed ? new (0, _chunk474IQG74cjs.TiledSurface)(ch, tiles, this.base.defaultValue) : null;
3153
3154
  const dabs = this.dry ? this.dry.dabCount : this.thickDriver ? this.thickDriver.dabCount : this.stickerSpray ? this.stickerSpray.dabCount : this.wet.dabCount;
3154
3155
  this.result = { layerId: this.layerId, bounds: changed ? this.bounds : null, dabs, strokeId: null };
3155
- if (_optionalChain([this, 'access', _83 => _83.stickerSpray, 'optionalAccess', _84 => _84.skipped, 'access', _85 => _85.size])) this.result.skippedStickers = [...this.stickerSpray.skipped];
3156
- const carried = _nullishCoalesce(_optionalChain([this, 'access', _86 => _86.wet, 'optionalAccess', _87 => _87.load]), () => ( _optionalChain([this, 'access', _88 => _88.thickDriver, 'optionalAccess', _89 => _89.load])));
3156
+ if (_optionalChain([this, 'access', _86 => _86.stickerSpray, 'optionalAccess', _87 => _87.skipped, 'access', _88 => _88.size])) this.result.skippedStickers = [...this.stickerSpray.skipped];
3157
+ const carried = _nullishCoalesce(_optionalChain([this, 'access', _89 => _89.wet, 'optionalAccess', _90 => _90.load]), () => ( _optionalChain([this, 'access', _91 => _91.thickDriver, 'optionalAccess', _92 => _92.load])));
3157
3158
  if (carried) this.result.mixerLoad = this.init.brush.behavior.dirty ? carried : _chunkFQPUF2W2cjs.cleanMixer.call(void 0, carried);
3158
3159
  this.host.commit(this, surface, false);
3159
3160
  return this.result;
@@ -3162,7 +3163,7 @@ var PaintStrokeSession = (_class12 = class _PaintStrokeSession {
3162
3163
  cancel() {
3163
3164
  if (this.closed) return;
3164
3165
  this.closed = true;
3165
- if (_optionalChain([this, 'access', _90 => _90.lightTwin, 'optionalAccess', _91 => _91.open])) this.lightTwin.cancel();
3166
+ if (_optionalChain([this, 'access', _93 => _93.lightTwin, 'optionalAccess', _94 => _94.open])) this.lightTwin.cancel();
3166
3167
  this.lightResult = null;
3167
3168
  this.host.commit(this, null, true);
3168
3169
  }
@@ -3194,36 +3195,36 @@ var STENCIL_SHAPES = ["rect", "ellipse", "polygon"];
3194
3195
  var finite = (v) => typeof v === "number" && Number.isFinite(v);
3195
3196
  var pt = (p) => p && finite(p.x) && finite(p.y) ? { x: p.x, y: p.y } : void 0;
3196
3197
  function normalizeStencil(raw, id, base) {
3197
- const kind = STENCIL_KINDS.includes(raw.kind) ? raw.kind : _optionalChain([base, 'optionalAccess', _92 => _92.kind]);
3198
+ const kind = STENCIL_KINDS.includes(raw.kind) ? raw.kind : _optionalChain([base, 'optionalAccess', _95 => _95.kind]);
3198
3199
  if (!kind) throw new Error(`kind ${JSON.stringify(raw.kind)} is not a stencil; use ${STENCIL_KINDS.join(", ")}.`);
3199
3200
  const s = {
3200
3201
  id,
3201
3202
  kind,
3202
- mode: raw.mode === "guide" || raw.mode === "mask" ? raw.mode : _nullishCoalesce(_optionalChain([base, 'optionalAccess', _93 => _93.mode]), () => ( (kind === "ruler" || kind === "arc" ? "guide" : "mask"))),
3203
- enabled: typeof raw.enabled === "boolean" ? raw.enabled : _nullishCoalesce(_optionalChain([base, 'optionalAccess', _94 => _94.enabled]), () => ( true)),
3204
- invert: typeof raw.invert === "boolean" ? raw.invert : _nullishCoalesce(_optionalChain([base, 'optionalAccess', _95 => _95.invert]), () => ( false)),
3205
- snap: finite(raw.snap) ? Math.min(400, Math.max(1, raw.snap)) : _nullishCoalesce(_optionalChain([base, 'optionalAccess', _96 => _96.snap]), () => ( 40)),
3206
- feather: finite(raw.feather) ? Math.min(100, Math.max(0, raw.feather)) : _nullishCoalesce(_optionalChain([base, 'optionalAccess', _97 => _97.feather]), () => ( 1))
3203
+ mode: raw.mode === "guide" || raw.mode === "mask" ? raw.mode : _nullishCoalesce(_optionalChain([base, 'optionalAccess', _96 => _96.mode]), () => ( (kind === "ruler" || kind === "arc" ? "guide" : "mask"))),
3204
+ enabled: typeof raw.enabled === "boolean" ? raw.enabled : _nullishCoalesce(_optionalChain([base, 'optionalAccess', _97 => _97.enabled]), () => ( true)),
3205
+ invert: typeof raw.invert === "boolean" ? raw.invert : _nullishCoalesce(_optionalChain([base, 'optionalAccess', _98 => _98.invert]), () => ( false)),
3206
+ snap: finite(raw.snap) ? Math.min(400, Math.max(1, raw.snap)) : _nullishCoalesce(_optionalChain([base, 'optionalAccess', _99 => _99.snap]), () => ( 40)),
3207
+ feather: finite(raw.feather) ? Math.min(100, Math.max(0, raw.feather)) : _nullishCoalesce(_optionalChain([base, 'optionalAccess', _100 => _100.feather]), () => ( 1))
3207
3208
  };
3208
3209
  if (kind === "ruler" || kind === "line") {
3209
- s.from = _nullishCoalesce(pt(raw.from), () => ( _optionalChain([base, 'optionalAccess', _98 => _98.from])));
3210
- s.to = _nullishCoalesce(pt(raw.to), () => ( _optionalChain([base, 'optionalAccess', _99 => _99.to])));
3210
+ s.from = _nullishCoalesce(pt(raw.from), () => ( _optionalChain([base, 'optionalAccess', _101 => _101.from])));
3211
+ s.to = _nullishCoalesce(pt(raw.to), () => ( _optionalChain([base, 'optionalAccess', _102 => _102.to])));
3211
3212
  if (!s.from || !s.to) throw new Error(`A ${kind} needs from and to points ({x, y} in document pixels).`);
3212
3213
  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.`);
3213
3214
  } else if (kind === "arc") {
3214
- s.center = _nullishCoalesce(pt(raw.center), () => ( _optionalChain([base, 'optionalAccess', _100 => _100.center])));
3215
- s.radius = finite(raw.radius) ? raw.radius : _optionalChain([base, 'optionalAccess', _101 => _101.radius]);
3215
+ s.center = _nullishCoalesce(pt(raw.center), () => ( _optionalChain([base, 'optionalAccess', _103 => _103.center])));
3216
+ s.radius = finite(raw.radius) ? raw.radius : _optionalChain([base, 'optionalAccess', _104 => _104.radius]);
3216
3217
  if (!s.center || !(s.radius > 0)) throw new Error("An arc needs a center ({x, y}) and a radius above 0.");
3217
- s.startAngle = finite(raw.startAngle) ? raw.startAngle : _nullishCoalesce(_optionalChain([base, 'optionalAccess', _102 => _102.startAngle]), () => ( 0));
3218
- s.endAngle = finite(raw.endAngle) ? raw.endAngle : _nullishCoalesce(_optionalChain([base, 'optionalAccess', _103 => _103.endAngle]), () => ( 360));
3218
+ s.startAngle = finite(raw.startAngle) ? raw.startAngle : _nullishCoalesce(_optionalChain([base, 'optionalAccess', _105 => _105.startAngle]), () => ( 0));
3219
+ s.endAngle = finite(raw.endAngle) ? raw.endAngle : _nullishCoalesce(_optionalChain([base, 'optionalAccess', _106 => _106.endAngle]), () => ( 360));
3219
3220
  } else {
3220
- s.shape = STENCIL_SHAPES.includes(raw.shape) ? raw.shape : _nullishCoalesce(_optionalChain([base, 'optionalAccess', _104 => _104.shape]), () => ( "rect"));
3221
+ s.shape = STENCIL_SHAPES.includes(raw.shape) ? raw.shape : _nullishCoalesce(_optionalChain([base, 'optionalAccess', _107 => _107.shape]), () => ( "rect"));
3221
3222
  if (s.shape === "polygon") {
3222
- const pts = Array.isArray(raw.points) ? raw.points.map(pt).filter((p) => Boolean(p)) : _optionalChain([base, 'optionalAccess', _105 => _105.points]);
3223
+ const pts = Array.isArray(raw.points) ? raw.points.map(pt).filter((p) => Boolean(p)) : _optionalChain([base, 'optionalAccess', _108 => _108.points]);
3223
3224
  if (!pts || pts.length < 3) throw new Error("A polygon stencil needs at least 3 points.");
3224
3225
  s.points = pts;
3225
3226
  } else {
3226
- const r = _nullishCoalesce(raw.rect, () => ( _optionalChain([base, 'optionalAccess', _106 => _106.rect])));
3227
+ const r = _nullishCoalesce(raw.rect, () => ( _optionalChain([base, 'optionalAccess', _109 => _109.rect])));
3227
3228
  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.`);
3228
3229
  s.rect = { x: r.x, y: r.y, width: r.width, height: r.height };
3229
3230
  }
@@ -3305,7 +3306,7 @@ var StencilSnapper = class {
3305
3306
  const { distance } = nearestOnStencil(s, p);
3306
3307
  if (distance <= s.snap && (!best || distance < best.d)) best = { s, d: distance };
3307
3308
  }
3308
- this.guide = _nullishCoalesce(_optionalChain([best, 'optionalAccess', _107 => _107.s]), () => ( null));
3309
+ this.guide = _nullishCoalesce(_optionalChain([best, 'optionalAccess', _110 => _110.s]), () => ( null));
3309
3310
  }
3310
3311
  if (!this.guide) return p;
3311
3312
  const q = nearestOnStencil(this.guide, p).point;
@@ -3478,7 +3479,7 @@ function normalizeBrushStroke(raw) {
3478
3479
  const st = [];
3479
3480
  for (const raw2 of r.stencils) {
3480
3481
  try {
3481
- st.push(normalizeStencil(raw2, typeof _optionalChain([raw2, 'optionalAccess', _108 => _108.id]) === "string" ? raw2.id : "stencil"));
3482
+ st.push(normalizeStencil(raw2, typeof _optionalChain([raw2, 'optionalAccess', _111 => _111.id]) === "string" ? raw2.id : "stencil"));
3482
3483
  } catch (e6) {
3483
3484
  }
3484
3485
  }
@@ -3526,9 +3527,9 @@ function varyStroke(stroke, m, v) {
3526
3527
  });
3527
3528
  const brush = s !== 1 ? _chunkRSIKDWOPcjs.normalizePaintBrush.call(void 0, { ...stroke.brush, tip: { ...stroke.brush.tip, size: stroke.brush.tip.size * s } }) : stroke.brush;
3528
3529
  const out = { ...stroke, brush, points };
3529
- if (_optionalChain([stroke, 'access', _109 => _109.paint, 'optionalAccess', _110 => _110.type]) === "gradient" && s !== 1) out.paint = _chunkFQPUF2W2cjs.scalePaintGradient.call(void 0, stroke.paint, s);
3530
- if (_optionalChain([stroke, 'access', _111 => _111.paint, 'optionalAccess', _112 => _112.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))) } };
3531
- if (_optionalChain([stroke, 'access', _113 => _113.copies, 'optionalAccess', _114 => _114.length])) {
3530
+ if (_optionalChain([stroke, 'access', _112 => _112.paint, 'optionalAccess', _113 => _113.type]) === "gradient" && s !== 1) out.paint = _chunkFQPUF2W2cjs.scalePaintGradient.call(void 0, stroke.paint, s);
3531
+ if (_optionalChain([stroke, 'access', _114 => _114.paint, 'optionalAccess', _115 => _115.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))) } };
3532
+ if (_optionalChain([stroke, 'access', _116 => _116.copies, 'optionalAccess', _117 => _117.length])) {
3532
3533
  const inv = invertAffine(m);
3533
3534
  out.copies = stroke.copies.map((c) => composeAffine(m, composeAffine(c, inv)));
3534
3535
  }
@@ -3547,7 +3548,7 @@ var paperNodes = /* @__PURE__ */ new WeakMap();
3547
3548
  function paperNode(paper, light) {
3548
3549
  let n = paperNodes.get(paper);
3549
3550
  const metal = (_nullishCoalesce(paper.metallic, () => ( 0))) > 0;
3550
- if (!n || metal && (_optionalChain([n, 'access', _115 => _115.light, 'optionalAccess', _116 => _116.azimuth]) !== _optionalChain([light, 'optionalAccess', _117 => _117.azimuth]) || _optionalChain([n, 'access', _118 => _118.light, 'optionalAccess', _119 => _119.elevation]) !== _optionalChain([light, 'optionalAccess', _120 => _120.elevation]))) {
3551
+ if (!n || metal && (_optionalChain([n, 'access', _118 => _118.light, 'optionalAccess', _119 => _119.azimuth]) !== _optionalChain([light, 'optionalAccess', _120 => _120.azimuth]) || _optionalChain([n, 'access', _121 => _121.light, 'optionalAccess', _122 => _122.elevation]) !== _optionalChain([light, 'optionalAccess', _123 => _123.elevation]))) {
3551
3552
  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 } } : {} };
3552
3553
  paperNodes.set(paper, n);
3553
3554
  }
@@ -3668,8 +3669,8 @@ function header(state, options) {
3668
3669
  if (options.swatches !== void 0) out.swatches = JSON.parse(JSON.stringify(options.swatches));
3669
3670
  if (options.mixingPad !== void 0) out.mixingPad = JSON.parse(JSON.stringify(options.mixingPad));
3670
3671
  if (options.wet !== void 0) out.wet = JSON.parse(JSON.stringify(options.wet));
3671
- if (_optionalChain([state, 'access', _121 => _121.wetEvents, 'optionalAccess', _122 => _122.length])) out.wetEvents = JSON.parse(JSON.stringify(state.wetEvents));
3672
- if (_optionalChain([state, 'access', _123 => _123.paintEvents, 'optionalAccess', _124 => _124.length])) out.paintEvents = JSON.parse(JSON.stringify(state.paintEvents));
3672
+ if (_optionalChain([state, 'access', _124 => _124.wetEvents, 'optionalAccess', _125 => _125.length])) out.wetEvents = JSON.parse(JSON.stringify(state.wetEvents));
3673
+ if (_optionalChain([state, 'access', _126 => _126.paintEvents, 'optionalAccess', _127 => _127.length])) out.paintEvents = JSON.parse(JSON.stringify(state.paintEvents));
3673
3674
  if (state.origin && (state.origin.x || state.origin.y)) out.origin = { ...state.origin };
3674
3675
  return out;
3675
3676
  }
@@ -3686,7 +3687,7 @@ function paintLayersOnly(layers, problems) {
3686
3687
  for (const l of layers) {
3687
3688
  if (l.type === "pixel") {
3688
3689
  const { filters, source, ...rest } = l;
3689
- if (_optionalChain([filters, 'optionalAccess', _125 => _125.length])) problems.push(`Layer "${l.name}": its filters are an image editor feature and were dropped.`);
3690
+ if (_optionalChain([filters, 'optionalAccess', _128 => _128.length])) problems.push(`Layer "${l.name}": its filters are an image editor feature and were dropped.`);
3690
3691
  if (source) problems.push(`Layer "${l.name}" refers to an image editor source image; it loads empty.`);
3691
3692
  out.push(rest);
3692
3693
  } else if (l.type === "group") out.push({ ...l, children: paintLayersOnly(l.children, problems) });
@@ -3717,7 +3718,7 @@ function deserializePaintDocument(raw) {
3717
3718
  const assets = r.assets && typeof r.assets === "object" ? r.assets : {};
3718
3719
  const layers = paintLayersOnly(_chunkYSGW7VV4cjs.deserializeLayers.call(void 0, r.layers, { assets, problems }), problems);
3719
3720
  const wanted = typeof r.activeLayerId === "string" ? r.activeLayerId : null;
3720
- const activeLayerId = wanted && _chunkDPYAO5U6cjs.findLayer.call(void 0, layers, wanted) ? wanted : _nullishCoalesce(_optionalChain([_chunkDPYAO5U6cjs.flattenLayers.call(void 0, layers), 'access', _126 => _126.filter, 'call', _127 => _127((l) => l.type === "pixel"), 'access', _128 => _128.pop, 'call', _129 => _129(), 'optionalAccess', _130 => _130.id]), () => ( null));
3721
+ const activeLayerId = wanted && _chunkDPYAO5U6cjs.findLayer.call(void 0, layers, wanted) ? wanted : _nullishCoalesce(_optionalChain([_chunkDPYAO5U6cjs.flattenLayers.call(void 0, layers), 'access', _129 => _129.filter, 'call', _130 => _130((l) => l.type === "pixel"), 'access', _131 => _131.pop, 'call', _132 => _132(), 'optionalAccess', _133 => _133.id]), () => ( null));
3721
3722
  const wetEvents = Array.isArray(r.wetEvents) ? r.wetEvents.filter((e) => e && typeof e === "object" && Number.isInteger(e.clock) && typeof e.kind === "string") : [];
3722
3723
  const state = { canvas, paper, layers, activeLayerId, strokes: readStrokes(r.strokes, problems) };
3723
3724
  if (wetEvents.length) state.wetEvents = wetEvents;
@@ -3862,7 +3863,7 @@ async function decodeImageBlob(blob) {
3862
3863
  if (!ctx) throw new Error("No 2D context to decode with.");
3863
3864
  ctx.drawImage(bitmap, 0, 0);
3864
3865
  const data = new Uint8ClampedArray(ctx.getImageData(0, 0, bitmap.width, bitmap.height).data);
3865
- _optionalChain([bitmap, 'access', _131 => _131.close, 'optionalCall', _132 => _132()]);
3866
+ _optionalChain([bitmap, 'access', _134 => _134.close, 'optionalCall', _135 => _135()]);
3866
3867
  return { width: bitmap.width, height: bitmap.height, data };
3867
3868
  }
3868
3869
  function downloadBytes(bytes, fileName, mimeType) {
@@ -3950,7 +3951,7 @@ var WetStrokeDriver = (_class13 = class {
3950
3951
 
3951
3952
  /** What copy 0's brush carries after the dabs so far. */
3952
3953
  get load() {
3953
- return _nullishCoalesce(_optionalChain([this, 'access', _133 => _133.states, 'access', _134 => _134[0], 'access', _135 => _135.exchange, 'optionalAccess', _136 => _136.load]), () => ( null));
3954
+ return _nullishCoalesce(_optionalChain([this, 'access', _136 => _136.states, 'access', _137 => _137[0], 'access', _138 => _138.exchange, 'optionalAccess', _139 => _139.load]), () => ( null));
3954
3955
  }
3955
3956
  /** Whether every point (and the end) has been applied. */
3956
3957
  get done() {
@@ -4169,8 +4170,8 @@ var PaintWetLayers = (_class14 = class {
4169
4170
  if (mode === this.gpuMode) return this.engineInfo();
4170
4171
  this.gpuMode = mode;
4171
4172
  if (mode === "off") {
4172
- _optionalChain([this, 'access', _137 => _137.world, 'optionalAccess', _138 => _138.attachGpu, 'call', _139 => _139(null)]);
4173
- _optionalChain([this, 'access', _140 => _140.gpu, 'optionalAccess', _141 => _141.destroy, 'call', _142 => _142()]);
4173
+ _optionalChain([this, 'access', _140 => _140.world, 'optionalAccess', _141 => _141.attachGpu, 'call', _142 => _142(null)]);
4174
+ _optionalChain([this, 'access', _143 => _143.gpu, 'optionalAccess', _144 => _144.destroy, 'call', _145 => _145()]);
4174
4175
  this.gpu = null;
4175
4176
  this.gpuSupport = null;
4176
4177
  } else if (this.world) this.startGpu();
@@ -4178,13 +4179,13 @@ var PaintWetLayers = (_class14 = class {
4178
4179
  }
4179
4180
  engineInfo() {
4180
4181
  const w = this.world;
4181
- const base = { mode: this.gpuMode, adapter: _nullishCoalesce(_optionalChain([this, 'access', _143 => _143.gpuSupport, 'optionalAccess', _144 => _144.adapter]), () => ( null)), maxTiles: _nullishCoalesce(_optionalChain([this, 'access', _145 => _145.gpuSupport, 'optionalAccess', _146 => _146.maxSlots]), () => ( 0)), minTiles: this.gpuMinTiles, activeTiles: _nullishCoalesce(_optionalChain([w, 'optionalAccess', _147 => _147.activeTiles, 'call', _148 => _148()]), () => ( 0)), cpu: this.backend() };
4182
+ const base = { mode: this.gpuMode, adapter: _nullishCoalesce(_optionalChain([this, 'access', _146 => _146.gpuSupport, 'optionalAccess', _147 => _147.adapter]), () => ( null)), maxTiles: _nullishCoalesce(_optionalChain([this, 'access', _148 => _148.gpuSupport, 'optionalAccess', _149 => _149.maxSlots]), () => ( 0)), minTiles: this.gpuMinTiles, activeTiles: _nullishCoalesce(_optionalChain([w, 'optionalAccess', _150 => _150.activeTiles, 'call', _151 => _151()]), () => ( 0)), cpu: this.backend() };
4182
4183
  if (this.gpuMode === "off") return { ...base, state: "off", reason: "Forced to the CPU." };
4183
4184
  if (this.gpuStarting) return { ...base, state: "starting", reason: null };
4184
- if (_optionalChain([w, 'optionalAccess', _149 => _149.gpuError])) return { ...base, state: "failed", reason: w.gpuError };
4185
+ if (_optionalChain([w, 'optionalAccess', _152 => _152.gpuError])) return { ...base, state: "failed", reason: w.gpuError };
4185
4186
  if (this.gpuSupport && !this.gpuSupport.supported) return { ...base, state: "unavailable", reason: this.gpuSupport.reason };
4186
4187
  if (!this.gpu) return { ...base, state: "not-started", reason: "Starts with the first wet stroke." };
4187
- if (_optionalChain([w, 'optionalAccess', _150 => _150.gpuActive])) return { ...base, state: "active", reason: null };
4188
+ if (_optionalChain([w, 'optionalAccess', _153 => _153.gpuActive])) return { ...base, state: "active", reason: null };
4188
4189
  return { ...base, state: "standby", reason: `The GPU takes over at ${this.gpuMinTiles} wet tiles (256 px).` };
4189
4190
  }
4190
4191
  /** The world (made on first use, at the canvas size). */
@@ -4223,13 +4224,13 @@ var PaintWetLayers = (_class14 = class {
4223
4224
  if (!this.canExtend(left, top)) throw new Error("Wet paint only moves by whole 256 px tiles, between strokes.");
4224
4225
  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 } } });
4225
4226
  const old = this.world;
4226
- const snap = _optionalChain([old, 'optionalAccess', _151 => _151.laneIds, 'call', _152 => _152(), 'access', _153 => _153.length]) ? old.snapshot() : null;
4227
+ const snap = _optionalChain([old, 'optionalAccess', _154 => _154.laneIds, 'call', _155 => _155(), 'access', _156 => _156.length]) ? old.snapshot() : null;
4227
4228
  this.dropWorld();
4228
4229
  this.lastTick = null;
4229
4230
  this.stepsOwed = 0;
4230
4231
  if (!old || !snap) return;
4231
4232
  const moved = _chunkKBYB7OWBcjs.moveWetSnapshot.call(void 0, snap, old, { width, height }, left, top, (l) => {
4232
- const flow = _optionalChain([this, 'access', _154 => _154.settings, 'access', _155 => _155.get, 'call', _156 => _156(l.id), 'optionalAccess', _157 => _157.flow]);
4233
+ const flow = _optionalChain([this, 'access', _157 => _157.settings, 'access', _158 => _158.get, 'call', _159 => _159(l.id), 'optionalAccess', _160 => _160.flow]);
4233
4234
  return {
4234
4235
  base: _chunk474IQG74cjs.translateSurface.call(void 0, l.base, left, top),
4235
4236
  ...l.light ? { light: _chunk474IQG74cjs.translateSurface.call(void 0, l.light, left, top) } : {},
@@ -4248,11 +4249,11 @@ var PaintWetLayers = (_class14 = class {
4248
4249
  }
4249
4250
  /** Layers holding a wet layer (wet or drying). */
4250
4251
  wetLayerIds() {
4251
- return _nullishCoalesce(_optionalChain([this, 'access', _158 => _158.world, 'optionalAccess', _159 => _159.laneIds, 'call', _160 => _160()]), () => ( []));
4252
+ return _nullishCoalesce(_optionalChain([this, 'access', _161 => _161.world, 'optionalAccess', _162 => _162.laneIds, 'call', _163 => _163()]), () => ( []));
4252
4253
  }
4253
4254
  /** Whether a batch is running (edits wait). */
4254
4255
  get busy() {
4255
- return Boolean(_optionalChain([this, 'access', _161 => _161.world, 'optionalAccess', _162 => _162.busy]));
4256
+ return Boolean(_optionalChain([this, 'access', _164 => _164.world, 'optionalAccess', _165 => _165.busy]));
4256
4257
  }
4257
4258
  /** Resolves when no batch is running. */
4258
4259
  async idle() {
@@ -4281,13 +4282,13 @@ var PaintWetLayers = (_class14 = class {
4281
4282
  setParams(layerId, update) {
4282
4283
  const s = this.settingsOf(layerId);
4283
4284
  s.params = _chunkKBYB7OWBcjs.normalizeWetParams.call(void 0, update, s.params);
4284
- if (_optionalChain([this, 'access', _163 => _163.world, 'optionalAccess', _164 => _164.hasLane, 'call', _165 => _165(layerId)])) this.world.setParams(layerId, s.params);
4285
+ if (_optionalChain([this, 'access', _166 => _166.world, 'optionalAccess', _167 => _167.hasLane, 'call', _168 => _168(layerId)])) this.world.setParams(layerId, s.params);
4285
4286
  return { ...s.params };
4286
4287
  }
4287
4288
  setFlow(layerId, update) {
4288
4289
  const s = this.settingsOf(layerId);
4289
4290
  s.flow = _chunkKBYB7OWBcjs.normalizeFlow.call(void 0, update, s.flow);
4290
- if (_optionalChain([this, 'access', _166 => _166.world, 'optionalAccess', _167 => _167.hasLane, 'call', _168 => _168(layerId)])) {
4291
+ if (_optionalChain([this, 'access', _169 => _169.world, 'optionalAccess', _170 => _170.hasLane, 'call', _171 => _171(layerId)])) {
4291
4292
  const { width, height } = this.host.canvas();
4292
4293
  this.world.setFlow(layerId, _chunkKBYB7OWBcjs.flowField.call(void 0, s.flow, width, height), s.flow.strength);
4293
4294
  }
@@ -4295,29 +4296,29 @@ var PaintWetLayers = (_class14 = class {
4295
4296
  }
4296
4297
  setTilt(update) {
4297
4298
  this.tilt = _chunkKBYB7OWBcjs.normalizeTilt.call(void 0, update, this.tilt);
4298
- _optionalChain([this, 'access', _169 => _169.world, 'optionalAccess', _170 => _170.setTilt, 'call', _171 => _171(this.tilt)]);
4299
+ _optionalChain([this, 'access', _172 => _172.world, 'optionalAccess', _173 => _173.setTilt, 'call', _174 => _174(this.tilt)]);
4299
4300
  return { ...this.tilt };
4300
4301
  }
4301
4302
  /** The paper changed. */
4302
4303
  paperChanged() {
4303
- _optionalChain([this, 'access', _172 => _172.world, 'optionalAccess', _173 => _173.setPaper, 'call', _174 => _174(wetPaperInput(this.host.paper()))]);
4304
+ _optionalChain([this, 'access', _175 => _175.world, 'optionalAccess', _176 => _176.setPaper, 'call', _177 => _177(wetPaperInput(this.host.paper()))]);
4304
4305
  }
4305
4306
  /** A layer as tools describe it. */
4306
4307
  info(layerId) {
4307
4308
  const s = this.settingsOf(layerId);
4308
- const st = _optionalChain([this, 'access', _175 => _175.world, 'optionalAccess', _176 => _176.hasLane, 'call', _177 => _177(layerId)]) ? this.world.stats(layerId) : null;
4309
+ const st = _optionalChain([this, 'access', _178 => _178.world, 'optionalAccess', _179 => _179.hasLane, 'call', _180 => _180(layerId)]) ? this.world.stats(layerId) : null;
4309
4310
  return {
4310
4311
  layerId,
4311
4312
  wet: Boolean(st && st.wetCells > 0),
4312
- wetCells: _nullishCoalesce(_optionalChain([st, 'optionalAccess', _178 => _178.wetCells]), () => ( 0)),
4313
- wetBounds: _nullishCoalesce(_optionalChain([st, 'optionalAccess', _179 => _179.wetBounds]), () => ( null)),
4314
- activeTiles: _nullishCoalesce(_optionalChain([st, 'optionalAccess', _180 => _180.activeTiles]), () => ( 0)),
4313
+ wetCells: _nullishCoalesce(_optionalChain([st, 'optionalAccess', _181 => _181.wetCells]), () => ( 0)),
4314
+ wetBounds: _nullishCoalesce(_optionalChain([st, 'optionalAccess', _182 => _182.wetBounds]), () => ( null)),
4315
+ activeTiles: _nullishCoalesce(_optionalChain([st, 'optionalAccess', _183 => _183.activeTiles]), () => ( 0)),
4315
4316
  params: { ...s.params },
4316
4317
  flow: { ...s.flow }
4317
4318
  };
4318
4319
  }
4319
4320
  backend() {
4320
- return _nullishCoalesce(_optionalChain([this, 'access', _181 => _181.world, 'optionalAccess', _182 => _182.backend, 'call', _183 => _183()]), () => ( null));
4321
+ return _nullishCoalesce(_optionalChain([this, 'access', _184 => _184.world, 'optionalAccess', _185 => _185.backend, 'call', _186 => _186()]), () => ( null));
4321
4322
  }
4322
4323
  /** Shows the current wet pixels (at most `maxTiles` reshaded per layer). */
4323
4324
  syncDisplays(maxTiles = Infinity) {
@@ -4366,7 +4367,7 @@ var PaintWetLayers = (_class14 = class {
4366
4367
  const w = this.world;
4367
4368
  if (!w) return;
4368
4369
  for (const id of w.laneIds()) {
4369
- if (w.isActive(id) || _optionalChain([this, 'access', _184 => _184.driver, 'optionalAccess', _185 => _185.init, 'access', _186 => _186.laneId]) === id) continue;
4370
+ if (w.isActive(id) || _optionalChain([this, 'access', _187 => _187.driver, 'optionalAccess', _188 => _188.init, 'access', _189 => _189.laneId]) === id) continue;
4370
4371
  const base = w.getBase(id);
4371
4372
  const light = w.isLit(id) ? w.getLight(id) : null;
4372
4373
  w.removeLane(id);
@@ -4448,7 +4449,7 @@ var PaintWetLayers = (_class14 = class {
4448
4449
  if (!d || !this.world) return;
4449
4450
  const rects = d.flush();
4450
4451
  if (rects.length) this.syncDisplays(DISPLAY_TILES_PER_TICK);
4451
- if (d.done) _optionalChain([this, 'access', _187 => _187.onDriverDone, 'optionalCall', _188 => _188(d)]);
4452
+ if (d.done) _optionalChain([this, 'access', _190 => _190.onDriverDone, 'optionalCall', _191 => _191(d)]);
4452
4453
  }
4453
4454
  /** Called when a live stroke that ended mid-batch has finished applying. */
4454
4455
  __init103() {this.onDriverDone = null}
@@ -4492,13 +4493,13 @@ var PaintWetLayers = (_class14 = class {
4492
4493
  /** The layer's light paint with all its wet paint dried (`null` without a wet layer or light), without changing anything. */
4493
4494
  bakedLight(layerId) {
4494
4495
  const w = this.world;
4495
- if (!_optionalChain([w, 'optionalAccess', _189 => _189.hasLane, 'call', _190 => _190(layerId)]) || !w.isLit(layerId)) return null;
4496
+ if (!_optionalChain([w, 'optionalAccess', _192 => _192.hasLane, 'call', _193 => _193(layerId)]) || !w.isLit(layerId)) return null;
4496
4497
  return w.bakedLight(layerId);
4497
4498
  }
4498
4499
  /** The layer's pixels with all its wet paint dried (deterministic), without changing anything. */
4499
4500
  bakedSurface(layerId) {
4500
4501
  const w = this.world;
4501
- if (!_optionalChain([w, 'optionalAccess', _191 => _191.hasLane, 'call', _192 => _192(layerId)])) return null;
4502
+ if (!_optionalChain([w, 'optionalAccess', _194 => _194.hasLane, 'call', _195 => _195(layerId)])) return null;
4502
4503
  return w.bakedSurface(layerId);
4503
4504
  }
4504
4505
  /** A snapshot of the world for undo (`null` when there is none). */
@@ -4519,13 +4520,13 @@ var PaintWetLayers = (_class14 = class {
4519
4520
  this.syncDisplays();
4520
4521
  }
4521
4522
  dropWorld() {
4522
- _optionalChain([this, 'access', _193 => _193.world, 'optionalAccess', _194 => _194.destroy, 'call', _195 => _195()]);
4523
+ _optionalChain([this, 'access', _196 => _196.world, 'optionalAccess', _197 => _197.destroy, 'call', _198 => _198()]);
4523
4524
  this.world = null;
4524
4525
  this.driver = null;
4525
4526
  }
4526
4527
  /** Forgets everything wet (a new canvas, a resize, opening a document). */
4527
4528
  reset() {
4528
- _optionalChain([this, 'access', _196 => _196.world, 'optionalAccess', _197 => _197.destroy, 'call', _198 => _198()]);
4529
+ _optionalChain([this, 'access', _199 => _199.world, 'optionalAccess', _200 => _200.destroy, 'call', _201 => _201()]);
4529
4530
  this.world = null;
4530
4531
  this.driver = null;
4531
4532
  this.settings.clear();
@@ -4555,9 +4556,9 @@ var PaintWetLayers = (_class14 = class {
4555
4556
  return out;
4556
4557
  }
4557
4558
  destroy() {
4558
- _optionalChain([this, 'access', _199 => _199.world, 'optionalAccess', _200 => _200.destroy, 'call', _201 => _201()]);
4559
+ _optionalChain([this, 'access', _202 => _202.world, 'optionalAccess', _203 => _203.destroy, 'call', _204 => _204()]);
4559
4560
  this.world = null;
4560
- _optionalChain([this, 'access', _202 => _202.gpu, 'optionalAccess', _203 => _203.destroy, 'call', _204 => _204()]);
4561
+ _optionalChain([this, 'access', _205 => _205.gpu, 'optionalAccess', _206 => _206.destroy, 'call', _207 => _207()]);
4561
4562
  this.gpu = null;
4562
4563
  }
4563
4564
  }, _class14);
@@ -4570,7 +4571,7 @@ function wetPigmentOf(hex2, body) {
4570
4571
  var thumbWorld = null;
4571
4572
  function paintWetTestStroke(brush, paper, color, width, height) {
4572
4573
  if (!thumbWorld || thumbWorld.width !== width || thumbWorld.height !== height) {
4573
- _optionalChain([thumbWorld, 'optionalAccess', _205 => _205.destroy, 'call', _206 => _206()]);
4574
+ _optionalChain([thumbWorld, 'optionalAccess', _208 => _208.destroy, 'call', _209 => _209()]);
4574
4575
  thumbWorld = new (0, _chunkKBYB7OWBcjs.WetWorld)(width, height, wetPaperInput(paper), { kernel: "typescript", threads: 0 });
4575
4576
  } else thumbWorld.setPaper(wetPaperInput(paper));
4576
4577
  const w = thumbWorld;
@@ -4915,11 +4916,11 @@ function readSwatch(raw) {
4915
4916
  if (!raw || typeof raw !== "object") return null;
4916
4917
  const r = raw;
4917
4918
  const g = _chunkFQPUF2W2cjs.readPaintSource.call(void 0, r.paint);
4918
- const color = typeof r.color === "string" && /^#[0-9a-f]{6}$/i.test(r.color) ? r.color.toLowerCase() : _optionalChain([g, 'optionalAccess', _207 => _207.type]) === "gradient" ? _chunkFQPUF2W2cjs.paintSourceColor.call(void 0, g) : null;
4919
+ const color = typeof r.color === "string" && /^#[0-9a-f]{6}$/i.test(r.color) ? r.color.toLowerCase() : _optionalChain([g, 'optionalAccess', _210 => _210.type]) === "gradient" ? _chunkFQPUF2W2cjs.paintSourceColor.call(void 0, g) : null;
4919
4920
  if (!color) return null;
4920
4921
  const out = { color };
4921
4922
  if (typeof r.name === "string" && r.name.trim()) out.name = r.name.trim().slice(0, 80);
4922
- if (_optionalChain([g, 'optionalAccess', _208 => _208.type]) === "gradient") out.paint = g;
4923
+ if (_optionalChain([g, 'optionalAccess', _211 => _211.type]) === "gradient") out.paint = g;
4923
4924
  return out;
4924
4925
  }
4925
4926
  var DEFAULT_SWATCHES = [
@@ -5106,7 +5107,7 @@ var MixingPad = (_class16 = class {constructor() { _class16.prototype.__init106.
5106
5107
  }
5107
5108
  /** Replaces the pad with a PNG (data URL or base64) of the pad's size, as `toPng` writes. */
5108
5109
  fromPng(png) {
5109
- const bytes = png.startsWith("data:") ? _optionalChain([_chunkW5M3J7PVcjs.parseDataUrl.call(void 0, png), 'optionalAccess', _209 => _209.bytes]) : _chunkW5M3J7PVcjs.base64ToBytes.call(void 0, png);
5110
+ const bytes = png.startsWith("data:") ? _optionalChain([_chunkW5M3J7PVcjs.parseDataUrl.call(void 0, png), 'optionalAccess', _212 => _212.bytes]) : _chunkW5M3J7PVcjs.base64ToBytes.call(void 0, png);
5110
5111
  if (!bytes || !_chunkW5M3J7PVcjs.isPng.call(void 0, bytes)) throw new Error("The pad image is not a PNG data URL or base64 PNG.");
5111
5112
  const img = _chunkW5M3J7PVcjs.decodePng.call(void 0, bytes);
5112
5113
  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}.`);
@@ -5165,20 +5166,20 @@ function brushSpecOf(next, from) {
5165
5166
  const plain = _chunkRSIKDWOPcjs.migrateBrushV1.call(void 0, next);
5166
5167
  const out = copyJSON(plain);
5167
5168
  if (from.description) out.description = from.description;
5168
- if (_optionalChain([from, 'access', _210 => _210.tags, 'optionalAccess', _211 => _211.length])) out.tags = [...from.tags];
5169
+ if (_optionalChain([from, 'access', _213 => _213.tags, 'optionalAccess', _214 => _214.length])) out.tags = [...from.tags];
5169
5170
  if (out.kind === "mark" && from.kind === "mark") {
5170
5171
  if (from.medium) out.medium = from.medium;
5171
5172
  if (from.variety) out.variety = from.variety;
5172
5173
  }
5173
5174
  const colour = { ..._nullishCoalesce(from.colour, () => ( {})) };
5174
- if (_optionalChain([plain, 'access', _212 => _212.colour, 'optionalAccess', _213 => _213.default]) !== void 0) colour.default = plain.colour.default;
5175
+ if (_optionalChain([plain, 'access', _215 => _215.colour, 'optionalAccess', _216 => _216.default]) !== void 0) colour.default = plain.colour.default;
5175
5176
  else if (isObject(colour.default) && colour.default.type === "gradient") delete colour.default;
5176
5177
  if (Object.keys(colour).length) out.colour = copyJSON(colour);
5177
5178
  else delete out.colour;
5178
- if ((_nullishCoalesce(_optionalChain([out, 'access', _214 => _214.light, 'optionalAccess', _215 => _215.amount]), () => ( 0))) > 0 && (_optionalChain([from, 'access', _216 => _216.light, 'optionalAccess', _217 => _217.spill]) || _optionalChain([from, 'access', _218 => _218.light, 'optionalAccess', _219 => _219.glow]) !== void 0)) {
5179
+ if ((_nullishCoalesce(_optionalChain([out, 'access', _217 => _217.light, 'optionalAccess', _218 => _218.amount]), () => ( 0))) > 0 && (_optionalChain([from, 'access', _219 => _219.light, 'optionalAccess', _220 => _220.spill]) || _optionalChain([from, 'access', _221 => _221.light, 'optionalAccess', _222 => _222.glow]) !== void 0)) {
5179
5180
  out.light = { ...out.light, ...from.light.spill ? { spill: { ...from.light.spill } } : {}, ...from.light.glow !== void 0 ? { glow: from.light.glow } : {} };
5180
5181
  }
5181
- if (_optionalChain([from, 'access', _220 => _220.motion, 'optionalAccess', _221 => _221.live]) !== void 0 || _optionalChain([from, 'access', _222 => _222.motion, 'optionalAccess', _223 => _223.fps]) !== void 0) {
5182
+ if (_optionalChain([from, 'access', _223 => _223.motion, 'optionalAccess', _224 => _224.live]) !== void 0 || _optionalChain([from, 'access', _225 => _225.motion, 'optionalAccess', _226 => _226.fps]) !== void 0) {
5182
5183
  out.motion = { ..._nullishCoalesce(out.motion, () => ( {})), ...from.motion.live !== void 0 ? { live: from.motion.live } : {}, ...from.motion.fps !== void 0 ? { fps: from.motion.fps } : {} };
5183
5184
  }
5184
5185
  try {
@@ -5301,8 +5302,8 @@ var BacklightCache = (_class17 = class {constructor() { _class17.prototype.__ini
5301
5302
  refs.length = 0;
5302
5303
  for (const l of layers) {
5303
5304
  tilesUnder(l.surface, rect, l.offset, refs);
5304
- tilesUnder(_optionalChain([l, 'access', _224 => _224.thick, 'optionalAccess', _225 => _225.height]), rect, l.offset, refs);
5305
- tilesUnder(_optionalChain([l, 'access', _226 => _226.thick, 'optionalAccess', _227 => _227.material]), rect, l.offset, refs);
5305
+ tilesUnder(_optionalChain([l, 'access', _227 => _227.thick, 'optionalAccess', _228 => _228.height]), rect, l.offset, refs);
5306
+ tilesUnder(_optionalChain([l, 'access', _229 => _229.thick, 'optionalAccess', _230 => _230.material]), rect, l.offset, refs);
5306
5307
  }
5307
5308
  const k = _chunk474IQG74cjs.tileKey.call(void 0, tx, ty);
5308
5309
  let r = this.tiles.get(k);
@@ -5396,8 +5397,8 @@ function computeTile(paper, grain, amount, rect, layers) {
5396
5397
  const lr = { x: rect.x - l.offset.x, y: rect.y - l.offset.y, width: rect.width, height: rect.height };
5397
5398
  if (!l.surface.tiles.size) continue;
5398
5399
  const px = _chunk474IQG74cjs.readRegion.call(void 0, l.surface, lr);
5399
- const h = _optionalChain([l, 'access', _228 => _228.thick, 'optionalAccess', _229 => _229.height, 'access', _230 => _230.tiles, 'access', _231 => _231.size]) ? _chunk474IQG74cjs.readRegion.call(void 0, l.thick.height, lr) : null;
5400
- const m = h && _optionalChain([l, 'access', _232 => _232.thick, 'optionalAccess', _233 => _233.material, 'access', _234 => _234.tiles, 'access', _235 => _235.size]) ? _chunk474IQG74cjs.readRegion.call(void 0, l.thick.material, lr) : null;
5400
+ const h = _optionalChain([l, 'access', _231 => _231.thick, 'optionalAccess', _232 => _232.height, 'access', _233 => _233.tiles, 'access', _234 => _234.size]) ? _chunk474IQG74cjs.readRegion.call(void 0, l.thick.height, lr) : null;
5401
+ const m = h && _optionalChain([l, 'access', _235 => _235.thick, 'optionalAccess', _236 => _236.material, 'access', _237 => _237.tiles, 'access', _238 => _238.size]) ? _chunk474IQG74cjs.readRegion.call(void 0, l.thick.material, lr) : null;
5401
5402
  const op = l.opacity;
5402
5403
  for (let i = 0; i < n; i++) {
5403
5404
  const a8 = px[i * 4 + 3];
@@ -5472,7 +5473,7 @@ async function replayPainting(source, target, options = {}) {
5472
5473
  const maxStrokes = _nullishCoalesce(options.strokes, () => ( source.strokes.length));
5473
5474
  const chunk = Math.max(1, _nullishCoalesce(options.wetChunk, () => ( 0))) || Infinity;
5474
5475
  let strokes = 0;
5475
- await target.prepareEffectPaints(source.strokes.slice(0, maxStrokes).flatMap((st) => _optionalChain([st, 'access', _236 => _236.paint, 'optionalAccess', _237 => _237.type]) === "effect" ? [st.paint] : []));
5476
+ await target.prepareEffectPaints(source.strokes.slice(0, maxStrokes).flatMap((st) => _optionalChain([st, 'access', _239 => _239.paint, 'optionalAccess', _240 => _240.type]) === "effect" ? [st.paint] : []));
5476
5477
  const advanceTo = async (clock) => {
5477
5478
  const now = target.getState().wet.clock;
5478
5479
  let left = clock - now;
@@ -5480,7 +5481,7 @@ async function replayPainting(source, target, options = {}) {
5480
5481
  const n = Math.min(left, chunk);
5481
5482
  await target.advanceWet({ steps: n });
5482
5483
  left -= n;
5483
- if (Number.isFinite(chunk)) await _optionalChain([options, 'access', _238 => _238.onWetSteps, 'optionalCall', _239 => _239(target.getState().wet.clock)]);
5484
+ if (Number.isFinite(chunk)) await _optionalChain([options, 'access', _241 => _241.onWetSteps, 'optionalCall', _242 => _242(target.getState().wet.clock)]);
5484
5485
  }
5485
5486
  };
5486
5487
  const sr = (r) => ({ x: r.x * s, y: r.y * s, width: r.width * s, height: r.height * s });
@@ -5493,14 +5494,14 @@ async function replayPainting(source, target, options = {}) {
5493
5494
  else if (e.kind === "clear") target.clearLayer(e.layerId);
5494
5495
  else if (e.kind === "live-strokes") {
5495
5496
  const d = e.data;
5496
- if (_optionalChain([d, 'optionalAccess', _240 => _240.rasterized])) target.replaceLiveStrokes(e.layerId, null);
5497
+ if (_optionalChain([d, 'optionalAccess', _243 => _243.rasterized])) target.replaceLiveStrokes(e.layerId, null);
5497
5498
  else {
5498
- const list = (_nullishCoalesce(_optionalChain([d, 'optionalAccess', _241 => _241.strokes]), () => ( []))).map((st2) => s === 1 ? st2 : { ...varyStroke(st2, scaleM, { scale: s }), ...st2.stencils ? { stencils: st2.stencils.map((x) => scaleStencil(x, s)) } : {} });
5499
- await target.prepareEffectPaints(list.flatMap((st2) => _optionalChain([st2, 'access', _242 => _242.paint, 'optionalAccess', _243 => _243.type]) === "effect" ? [st2.paint] : []));
5499
+ const list = (_nullishCoalesce(_optionalChain([d, 'optionalAccess', _244 => _244.strokes]), () => ( []))).map((st2) => s === 1 ? st2 : { ...varyStroke(st2, scaleM, { scale: s }), ...st2.stencils ? { stencils: st2.stencils.map((x) => scaleStencil(x, s)) } : {} });
5500
+ await target.prepareEffectPaints(list.flatMap((st2) => _optionalChain([st2, 'access', _245 => _245.paint, 'optionalAccess', _246 => _246.type]) === "effect" ? [st2.paint] : []));
5500
5501
  target.replaceLiveStrokes(e.layerId, list);
5501
5502
  }
5502
5503
  } else if (e.kind === "stickers") {
5503
- const list = (_nullishCoalesce(_optionalChain([e, 'access', _244 => _244.data, 'optionalAccess', _245 => _245.stickers]), () => ( []))).map((x) => s === 1 ? x : { ...x, x: x.x * s, y: x.y * s, size: x.size * s });
5504
+ const list = (_nullishCoalesce(_optionalChain([e, 'access', _247 => _247.data, 'optionalAccess', _248 => _248.stickers]), () => ( []))).map((x) => s === 1 ? x : { ...x, x: x.x * s, y: x.y * s, size: x.size * s });
5504
5505
  target.replaceStickers(e.layerId, list);
5505
5506
  } else target.flattenRelief(e.layerId);
5506
5507
  continue;
@@ -5513,8 +5514,8 @@ async function replayPainting(source, target, options = {}) {
5513
5514
  switch (e.kind) {
5514
5515
  case "dry": {
5515
5516
  const rect = e.data;
5516
- const ids = _optionalChain([e, 'access', _246 => _246.layerId, 'optionalAccess', _247 => _247.split, 'call', _248 => _248(","), 'access', _249 => _249.filter, 'call', _250 => _250(Boolean)]);
5517
- if (_optionalChain([ids, 'optionalAccess', _251 => _251.length])) for (const id of ids) target.dryPaint({ layerId: id, rect: rect ? sr(rect) : void 0 });
5517
+ const ids = _optionalChain([e, 'access', _249 => _249.layerId, 'optionalAccess', _250 => _250.split, 'call', _251 => _251(","), 'access', _252 => _252.filter, 'call', _253 => _253(Boolean)]);
5518
+ if (_optionalChain([ids, 'optionalAccess', _254 => _254.length])) for (const id of ids) target.dryPaint({ layerId: id, rect: rect ? sr(rect) : void 0 });
5518
5519
  else target.dryPaint({ rect: rect ? sr(rect) : void 0 });
5519
5520
  break;
5520
5521
  }
@@ -5545,7 +5546,7 @@ async function replayPainting(source, target, options = {}) {
5545
5546
  strokes++;
5546
5547
  if (!target.getLayer(st.layerId)) continue;
5547
5548
  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)) };
5548
- if (st.brush.engine === "wet" && _optionalChain([st, 'access', _252 => _252.steps, 'optionalAccess', _253 => _253.length]) === st.points.length) {
5549
+ if (st.brush.engine === "wet" && _optionalChain([st, 'access', _255 => _255.steps, 'optionalAccess', _256 => _256.length]) === st.points.length) {
5549
5550
  await target.wetIdle();
5550
5551
  await advanceTo(st.steps[0]);
5551
5552
  const session = target.beginStroke({ ...init, start: st.points[0] });
@@ -5565,7 +5566,7 @@ async function replayPainting(source, target, options = {}) {
5565
5566
  await target.wetIdle();
5566
5567
  target.paintStroke({ ...init, points: st.points });
5567
5568
  }
5568
- await _optionalChain([options, 'access', _254 => _254.onStroke, 'optionalCall', _255 => _255(strokes)]);
5569
+ await _optionalChain([options, 'access', _257 => _257.onStroke, 'optionalCall', _258 => _258(strokes)]);
5569
5570
  }
5570
5571
  void IDENTITY_AFFINE;
5571
5572
  }
@@ -5610,7 +5611,7 @@ async function buildTimeLapse(source, target, options = {}) {
5610
5611
  wetChunk: wetEvery > 0 ? wetEvery : 0,
5611
5612
  onStroke: (i) => {
5612
5613
  if (i % perFrame === 0 || i === total) shoot(i);
5613
- _optionalChain([options, 'access', _256 => _256.onProgress, 'optionalCall', _257 => _257(total ? i / total : 1)]);
5614
+ _optionalChain([options, 'access', _259 => _259.onProgress, 'optionalCall', _260 => _260(total ? i / total : 1)]);
5614
5615
  },
5615
5616
  onWetSteps: wetEvery > 0 ? () => shoot(-1) : void 0
5616
5617
  });
@@ -5813,7 +5814,7 @@ function unionRect(a, b) {
5813
5814
  const y = Math.min(a.y, b.y);
5814
5815
  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 };
5815
5816
  }
5816
- var isPixelLayer = (l) => _optionalChain([l, 'optionalAccess', _258 => _258.type]) === "pixel";
5817
+ var isPixelLayer = (l) => _optionalChain([l, 'optionalAccess', _261 => _261.type]) === "pixel";
5817
5818
  var PaintEditorController = (_class19 = class _PaintEditorController {
5818
5819
 
5819
5820
  __init117() {this.extensions = {}}
@@ -5854,67 +5855,68 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
5854
5855
 
5855
5856
  __init134() {this.listeners = /* @__PURE__ */ new Set()}
5856
5857
  __init135() {this.commitListeners = /* @__PURE__ */ new Set()}
5858
+ __init136() {this.sampleListeners = /* @__PURE__ */ new Set()}
5857
5859
  /** Origins set by `withOrigin`, innermost last. */
5858
- __init136() {this.origins = []}
5860
+ __init137() {this.origins = []}
5859
5861
  /** `group` in progress: commits fold into one step, recorded when it ends. */
5860
- __init137() {this.grouping = null}
5862
+ __init138() {this.grouping = null}
5861
5863
  /** `previewPaint` in progress: nothing is emitted or recorded. */
5862
- __init138() {this.previewing = false}
5863
- __init139() {this.version = 0}
5864
- __init140() {this.cached = null}
5865
- __init141() {this.session = null}
5866
- __init142() {this.live = null}
5867
- __init143() {this.liveLayers = null}
5868
- __init144() {this.dirty = "all"}
5869
- __init145() {this.seedCounter = 1}
5870
- __init146() {this.strokeCounter = 1}
5864
+ __init139() {this.previewing = false}
5865
+ __init140() {this.version = 0}
5866
+ __init141() {this.cached = null}
5867
+ __init142() {this.session = null}
5868
+ __init143() {this.live = null}
5869
+ __init144() {this.liveLayers = null}
5870
+ __init145() {this.dirty = "all"}
5871
+ __init146() {this.seedCounter = 1}
5872
+ __init147() {this.strokeCounter = 1}
5871
5873
  /** Light paint: each layer's spill settings (saved with the document, not undo steps; missing = the defaults). */
5872
- __init147() {this.lightSpills = {}}
5873
- __init148() {this.lightCaches = /* @__PURE__ */ new Map()}
5874
+ __init148() {this.lightSpills = {}}
5875
+ __init149() {this.lightCaches = /* @__PURE__ */ new Map()}
5874
5876
  /** Backlit paper: the light through the paint as drawn (live strokes too), and as committed (its spill). */
5875
- __init149() {this.backlightView = new BacklightCache()}
5876
- __init150() {this.backlightCommitted = new BacklightCache()}
5877
+ __init150() {this.backlightView = new BacklightCache()}
5878
+ __init151() {this.backlightCommitted = new BacklightCache()}
5877
5879
  /** Live effect paint: playing and the frame rate cap (editor state), and the time the view shows. */
5878
- __init151() {this.effectPlaybackState = { playing: true, fps: 30 }}
5879
- __init152() {this.effectTime = 0}
5880
+ __init152() {this.effectPlaybackState = { playing: true, fps: 30 }}
5881
+ __init153() {this.effectTime = 0}
5880
5882
  /** While a frame is drawn: the time live effect strokes are drawn at (else their own time). */
5881
- __init153() {this.liveEffectAt = null}
5883
+ __init154() {this.liveEffectAt = null}
5882
5884
  /** The view's stroke layers at `effectTime`, each with the document surface it was drawn from (stale once that changes). */
5883
- __init154() {this.animatedLayers = /* @__PURE__ */ new Map()}
5885
+ __init155() {this.animatedLayers = /* @__PURE__ */ new Map()}
5884
5886
  /** `renderAnimationFrame` / `withEffectTime`: layer surfaces at another time, for one render. */
5885
- __init155() {this.frameOverride = null}
5887
+ __init156() {this.frameOverride = null}
5886
5888
  /** The area each stroke painted (document pixels; `null`: nothing), learnt as it is painted or drawn, so a stroke layer edit redraws only where it changes (see `drawLiveStrokes`). */
5887
- __init156() {this.paintedBounds = /* @__PURE__ */ new WeakMap()}
5889
+ __init157() {this.paintedBounds = /* @__PURE__ */ new WeakMap()}
5888
5890
 
5889
- __init157() {this.swatches = DEFAULT_SWATCHES.map((s) => ({ ...s }))}
5890
- __init158() {this.pad = new MixingPad()}
5891
- __init159() {this.savedPads = []}
5892
- __init160() {this.nextPadId = 1}
5893
- __init161() {this.tracingVersion = 1}
5894
- __init162() {this.tracingCache = null}
5895
- __init163() {this.imagePixels = /* @__PURE__ */ new Map()}
5896
- __init164() {this.nextReferenceId = 1}
5897
- __init165() {this.viewCompositor = createPaintCompositor()}
5898
- __init166() {this.exportCompositor = createPaintCompositor()}
5891
+ __init158() {this.swatches = DEFAULT_SWATCHES.map((s) => ({ ...s }))}
5892
+ __init159() {this.pad = new MixingPad()}
5893
+ __init160() {this.savedPads = []}
5894
+ __init161() {this.nextPadId = 1}
5895
+ __init162() {this.tracingVersion = 1}
5896
+ __init163() {this.tracingCache = null}
5897
+ __init164() {this.imagePixels = /* @__PURE__ */ new Map()}
5898
+ __init165() {this.nextReferenceId = 1}
5899
+ __init166() {this.viewCompositor = createPaintCompositor()}
5900
+ __init167() {this.exportCompositor = createPaintCompositor()}
5899
5901
  /** Wet media: the simulation, its settings and time. */
5900
5902
 
5901
5903
 
5902
5904
  /** Where the light comes from for thick paint (saved with the document, not undo steps). */
5903
- __init167() {this.lighting = { ...DEFAULT_LIGHTING }}
5904
- __init168() {this.litCaches = /* @__PURE__ */ new Map()}
5905
+ __init168() {this.lighting = { ...DEFAULT_LIGHTING }}
5906
+ __init169() {this.litCaches = /* @__PURE__ */ new Map()}
5905
5907
  /** The live impasto stroke's channels. */
5906
- __init169() {this.liveThick = null}
5908
+ __init170() {this.liveThick = null}
5907
5909
  /** Set while an operation that changes wet paint runs: the simulation before it (for undo). */
5908
- __init170() {this.wetOp = null}
5910
+ __init171() {this.wetOp = null}
5909
5911
  /** The effects provider slot (see `setEffectsProvider`). */
5910
- __init171() {this.effects = new (0, _chunkL2JTLW6Bcjs.EffectsSlot)()}
5912
+ __init172() {this.effects = new (0, _chunkL2JTLW6Bcjs.EffectsSlot)()}
5911
5913
  /** The sticker library slot (see `setStickersProvider`). */
5912
- __init172() {this.stickers = new (0, _chunkJSDND7DFcjs.StickersSlot)(_chunkRVGP2XLFcjs.editorStickers.call(void 0, ))}
5913
- __init173() {this.stickerArt = new StickerArtCache()}
5914
+ __init173() {this.stickers = new (0, _chunkJSDND7DFcjs.StickersSlot)(_chunkRVGP2XLFcjs.editorStickers.call(void 0, ))}
5915
+ __init174() {this.stickerArt = new StickerArtCache()}
5914
5916
 
5915
- __init174() {this.effectsRenderer = new PaintEffectsRenderer()}
5916
- __init175() {this.paperEffectNodeCache = null}
5917
- constructor(options = {}) {;_class19.prototype.__init117.call(this);_class19.prototype.__init118.call(this);_class19.prototype.__init119.call(this);_class19.prototype.__init120.call(this);_class19.prototype.__init121.call(this);_class19.prototype.__init122.call(this);_class19.prototype.__init123.call(this);_class19.prototype.__init124.call(this);_class19.prototype.__init125.call(this);_class19.prototype.__init126.call(this);_class19.prototype.__init127.call(this);_class19.prototype.__init128.call(this);_class19.prototype.__init129.call(this);_class19.prototype.__init130.call(this);_class19.prototype.__init131.call(this);_class19.prototype.__init132.call(this);_class19.prototype.__init133.call(this);_class19.prototype.__init134.call(this);_class19.prototype.__init135.call(this);_class19.prototype.__init136.call(this);_class19.prototype.__init137.call(this);_class19.prototype.__init138.call(this);_class19.prototype.__init139.call(this);_class19.prototype.__init140.call(this);_class19.prototype.__init141.call(this);_class19.prototype.__init142.call(this);_class19.prototype.__init143.call(this);_class19.prototype.__init144.call(this);_class19.prototype.__init145.call(this);_class19.prototype.__init146.call(this);_class19.prototype.__init147.call(this);_class19.prototype.__init148.call(this);_class19.prototype.__init149.call(this);_class19.prototype.__init150.call(this);_class19.prototype.__init151.call(this);_class19.prototype.__init152.call(this);_class19.prototype.__init153.call(this);_class19.prototype.__init154.call(this);_class19.prototype.__init155.call(this);_class19.prototype.__init156.call(this);_class19.prototype.__init157.call(this);_class19.prototype.__init158.call(this);_class19.prototype.__init159.call(this);_class19.prototype.__init160.call(this);_class19.prototype.__init161.call(this);_class19.prototype.__init162.call(this);_class19.prototype.__init163.call(this);_class19.prototype.__init164.call(this);_class19.prototype.__init165.call(this);_class19.prototype.__init166.call(this);_class19.prototype.__init167.call(this);_class19.prototype.__init168.call(this);_class19.prototype.__init169.call(this);_class19.prototype.__init170.call(this);_class19.prototype.__init171.call(this);_class19.prototype.__init172.call(this);_class19.prototype.__init173.call(this);_class19.prototype.__init174.call(this);_class19.prototype.__init175.call(this);_class19.prototype.__init176.call(this);_class19.prototype.__init177.call(this);_class19.prototype.__init178.call(this);_class19.prototype.__init179.call(this);_class19.prototype.__init180.call(this);_class19.prototype.__init181.call(this);
5917
+ __init175() {this.effectsRenderer = new PaintEffectsRenderer()}
5918
+ __init176() {this.paperEffectNodeCache = null}
5919
+ constructor(options = {}) {;_class19.prototype.__init117.call(this);_class19.prototype.__init118.call(this);_class19.prototype.__init119.call(this);_class19.prototype.__init120.call(this);_class19.prototype.__init121.call(this);_class19.prototype.__init122.call(this);_class19.prototype.__init123.call(this);_class19.prototype.__init124.call(this);_class19.prototype.__init125.call(this);_class19.prototype.__init126.call(this);_class19.prototype.__init127.call(this);_class19.prototype.__init128.call(this);_class19.prototype.__init129.call(this);_class19.prototype.__init130.call(this);_class19.prototype.__init131.call(this);_class19.prototype.__init132.call(this);_class19.prototype.__init133.call(this);_class19.prototype.__init134.call(this);_class19.prototype.__init135.call(this);_class19.prototype.__init136.call(this);_class19.prototype.__init137.call(this);_class19.prototype.__init138.call(this);_class19.prototype.__init139.call(this);_class19.prototype.__init140.call(this);_class19.prototype.__init141.call(this);_class19.prototype.__init142.call(this);_class19.prototype.__init143.call(this);_class19.prototype.__init144.call(this);_class19.prototype.__init145.call(this);_class19.prototype.__init146.call(this);_class19.prototype.__init147.call(this);_class19.prototype.__init148.call(this);_class19.prototype.__init149.call(this);_class19.prototype.__init150.call(this);_class19.prototype.__init151.call(this);_class19.prototype.__init152.call(this);_class19.prototype.__init153.call(this);_class19.prototype.__init154.call(this);_class19.prototype.__init155.call(this);_class19.prototype.__init156.call(this);_class19.prototype.__init157.call(this);_class19.prototype.__init158.call(this);_class19.prototype.__init159.call(this);_class19.prototype.__init160.call(this);_class19.prototype.__init161.call(this);_class19.prototype.__init162.call(this);_class19.prototype.__init163.call(this);_class19.prototype.__init164.call(this);_class19.prototype.__init165.call(this);_class19.prototype.__init166.call(this);_class19.prototype.__init167.call(this);_class19.prototype.__init168.call(this);_class19.prototype.__init169.call(this);_class19.prototype.__init170.call(this);_class19.prototype.__init171.call(this);_class19.prototype.__init172.call(this);_class19.prototype.__init173.call(this);_class19.prototype.__init174.call(this);_class19.prototype.__init175.call(this);_class19.prototype.__init176.call(this);_class19.prototype.__init177.call(this);_class19.prototype.__init178.call(this);_class19.prototype.__init179.call(this);_class19.prototype.__init180.call(this);_class19.prototype.__init181.call(this);_class19.prototype.__init182.call(this);
5918
5920
  this.historyLimit = Math.max(1, _nullishCoalesce(options.historyLimit, () => ( 200)));
5919
5921
  this.rasterizeSticker = _nullishCoalesce(options.rasterizeSticker, () => ( defaultStickerRasterizer));
5920
5922
  if (options.stickers) this.stickers.set(options.stickers);
@@ -5941,7 +5943,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
5941
5943
  canvas: () => this.doc.canvas,
5942
5944
  paper: () => this.doc.paper,
5943
5945
  layerSurface: (id) => {
5944
- const l = _optionalChain([_chunkDPYAO5U6cjs.findLayer.call(void 0, this.doc.layers, id), 'optionalAccess', _259 => _259.layer]);
5946
+ const l = _optionalChain([_chunkDPYAO5U6cjs.findLayer.call(void 0, this.doc.layers, id), 'optionalAccess', _262 => _262.layer]);
5945
5947
  return isPixelLayer(l) ? l.surface : null;
5946
5948
  },
5947
5949
  updateSurfaces: (surfaces, rects) => {
@@ -5950,7 +5952,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
5950
5952
  this.doc = { ...this.doc, layers };
5951
5953
  this.emit(rects.length ? rects : "all");
5952
5954
  },
5953
- layerLight: (id) => _nullishCoalesce(_optionalChain([this, 'access', _260 => _260.doc, 'access', _261 => _261.light, 'optionalAccess', _262 => _262[id]]), () => ( null)),
5955
+ layerLight: (id) => _nullishCoalesce(_optionalChain([this, 'access', _263 => _263.doc, 'access', _264 => _264.light, 'optionalAccess', _265 => _265[id]]), () => ( null)),
5954
5956
  updateLights: (lights) => {
5955
5957
  let light = this.doc.light;
5956
5958
  for (const [id, surface] of lights) if (_chunkDPYAO5U6cjs.findLayer.call(void 0, this.doc.layers, id)) light = withLayerLight(light, id, surface);
@@ -5961,13 +5963,34 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
5961
5963
  },
5962
5964
  options.wet
5963
5965
  );
5964
- this.wet.onDriverDone = () => _optionalChain([this, 'access', _263 => _263.session, 'optionalAccess', _264 => _264.completeWetEnd, 'call', _265 => _265()]);
5966
+ this.wet.onDriverDone = () => _optionalChain([this, 'access', _266 => _266.session, 'optionalAccess', _267 => _267.completeWetEnd, 'call', _268 => _268()]);
5965
5967
  }
5966
5968
  // --- State and events ----------------------------------------------------------
5967
5969
  subscribe(listener) {
5968
5970
  this.listeners.add(listener);
5969
5971
  return () => this.listeners.delete(listener);
5970
5972
  }
5973
+ /**
5974
+ * Hears the user's live strokes as they are painted (`beginStroke` sessions, not strokes painted
5975
+ * from data): when the pen goes down, each batch of samples, and the end or cancel. For agents
5976
+ * that paint along in real time. Returns an unsubscribe function.
5977
+ */
5978
+ onStrokeSample(listener) {
5979
+ this.sampleListeners.add(listener);
5980
+ return () => {
5981
+ this.sampleListeners.delete(listener);
5982
+ };
5983
+ }
5984
+ notifySample(phase, session, added = [], strokeId) {
5985
+ if (!this.sampleListeners.size || this.previewing) return;
5986
+ const sample = { phase, layerId: session.layerId, brush: session.init.brush, color: session.init.colorHex, points: session.points, added, ...strokeId !== void 0 ? { strokeId } : {} };
5987
+ for (const l of [...this.sampleListeners]) l(sample);
5988
+ }
5989
+ /** The stroke being painted now, or `null`: its layer, brush, colour and samples so far. */
5990
+ getLiveStroke() {
5991
+ const s = this.session;
5992
+ return s ? { layerId: s.layerId, brushId: s.init.brush.id, brushName: s.init.brush.name, color: s.init.colorHex, points: s.points } : null;
5993
+ }
5971
5994
  /** Hears each undo step recorded, merged, undone or redone, with who made it. Returns an unsubscribe function. */
5972
5995
  onCommit(listener) {
5973
5996
  this.commitListeners.add(listener);
@@ -6064,7 +6087,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
6064
6087
  if (placement.bottom) this.moveLayer(layer.id, 0, null);
6065
6088
  fn(layer.id);
6066
6089
  if (this.wetOp || this.pendingWetEvents.length) throw new PaintEditorError("Wet paint can't be previewed; suggest it with a dry brush.");
6067
- const found = _optionalChain([_chunkDPYAO5U6cjs.findLayer.call(void 0, this.doc.layers, layer.id), 'optionalAccess', _266 => _266.layer]);
6090
+ const found = _optionalChain([_chunkDPYAO5U6cjs.findLayer.call(void 0, this.doc.layers, layer.id), 'optionalAccess', _269 => _269.layer]);
6068
6091
  const surface = found && isPixelLayer(found) ? found.surface : null;
6069
6092
  const bounds = surface ? _chunk474IQG74cjs.contentBounds.call(void 0, surface) : null;
6070
6093
  const box = bounds ? clipToCanvas(bounds, this.doc.canvas) : null;
@@ -6117,8 +6140,8 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
6117
6140
  selectedSticker: this.selectedSticker,
6118
6141
  canUndo: this.undoStack.length > 0 && !this.session,
6119
6142
  canRedo: this.redoStack.length > 0 && !this.session,
6120
- undoLabel: _nullishCoalesce(_optionalChain([last, 'optionalAccess', _267 => _267.label]), () => ( null)),
6121
- redoLabel: _nullishCoalesce(_optionalChain([next, 'optionalAccess', _268 => _268.label]), () => ( null)),
6143
+ undoLabel: _nullishCoalesce(_optionalChain([last, 'optionalAccess', _270 => _270.label]), () => ( null)),
6144
+ redoLabel: _nullishCoalesce(_optionalChain([next, 'optionalAccess', _271 => _271.label]), () => ( null)),
6122
6145
  guides: this.guides,
6123
6146
  swatches: this.swatches,
6124
6147
  mixingPadVersion: this.pad.version,
@@ -6131,10 +6154,10 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
6131
6154
  overlay: this.wet.overlay,
6132
6155
  instantDry: this.wet.instantDry,
6133
6156
  speed: this.wet.speed,
6134
- clock: _nullishCoalesce(_optionalChain([this, 'access', _269 => _269.wet, 'access', _270 => _270.world, 'optionalAccess', _271 => _271.clock]), () => ( 0)),
6157
+ clock: _nullishCoalesce(_optionalChain([this, 'access', _272 => _272.wet, 'access', _273 => _273.world, 'optionalAccess', _274 => _274.clock]), () => ( 0)),
6135
6158
  tilt: { ...this.wet.tilt },
6136
6159
  gpu: this.wet.gpuMode,
6137
- gpuActive: Boolean(_optionalChain([this, 'access', _272 => _272.wet, 'access', _273 => _273.world, 'optionalAccess', _274 => _274.gpuActive]))
6160
+ gpuActive: Boolean(_optionalChain([this, 'access', _275 => _275.wet, 'access', _276 => _276.world, 'optionalAccess', _277 => _277.gpuActive]))
6138
6161
  },
6139
6162
  version: this.version
6140
6163
  };
@@ -6153,7 +6176,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
6153
6176
  return d;
6154
6177
  }
6155
6178
  // --- History -------------------------------------------------------------------
6156
- __init176() {this.docRevision = 0}
6179
+ __init177() {this.docRevision = 0}
6157
6180
  /**
6158
6181
  * Bumped on every change to the painting (a committed or amended step, undo, redo, opening a
6159
6182
  * document), not on wet-paint frames or view changes. `createPaintEditorDocument` uses it.
@@ -6244,9 +6267,9 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
6244
6267
  return wetIds;
6245
6268
  }
6246
6269
  /** Records a wet event (for replays) in the document being built. */
6247
- __init177() {this.pendingWetEvents = []}
6270
+ __init178() {this.pendingWetEvents = []}
6248
6271
  logWet(e) {
6249
- this.pendingWetEvents.push({ clock: _nullishCoalesce(_optionalChain([this, 'access', _275 => _275.wet, 'access', _276 => _276.world, 'optionalAccess', _277 => _277.clock]), () => ( 0)), at: this.doc.strokes.length, ...e });
6272
+ this.pendingWetEvents.push({ clock: _nullishCoalesce(_optionalChain([this, 'access', _278 => _278.wet, 'access', _279 => _279.world, 'optionalAccess', _280 => _280.clock]), () => ( 0)), at: this.doc.strokes.length, ...e });
6250
6273
  }
6251
6274
  /** The document with a paint event appended (for replays). */
6252
6275
  withPaintEvent(doc, e) {
@@ -6392,7 +6415,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
6392
6415
  }
6393
6416
  let next = { ...shiftDocument(this.withWetEvents(this.doc), left, top), canvas: { ...was, width, height } };
6394
6417
  for (const id of keptWet) {
6395
- const l = _optionalChain([_chunkDPYAO5U6cjs.findLayer.call(void 0, next.layers, id), 'optionalAccess', _278 => _278.layer]);
6418
+ const l = _optionalChain([_chunkDPYAO5U6cjs.findLayer.call(void 0, next.layers, id), 'optionalAccess', _281 => _281.layer]);
6396
6419
  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 } })) };
6397
6420
  }
6398
6421
  if (this.wet.world) {
@@ -6436,7 +6459,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
6436
6459
  }
6437
6460
  // --- Layers --------------------------------------------------------------------
6438
6461
  getLayer(id) {
6439
- return _optionalChain([_chunkDPYAO5U6cjs.findLayer.call(void 0, this.doc.layers, id), 'optionalAccess', _279 => _279.layer]);
6462
+ return _optionalChain([_chunkDPYAO5U6cjs.findLayer.call(void 0, this.doc.layers, id), 'optionalAccess', _282 => _282.layer]);
6440
6463
  }
6441
6464
  /** The active pixel layer (or `undefined`). */
6442
6465
  getActiveLayer() {
@@ -6455,7 +6478,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
6455
6478
  walk(this.doc.layers, null, 0);
6456
6479
  return out;
6457
6480
  }
6458
- describeLayer(l, parentId = _nullishCoalesce(_optionalChain([_chunkDPYAO5U6cjs.findLayer.call(void 0, this.doc.layers, l.id), 'optionalAccess', _280 => _280.parent, 'optionalAccess', _281 => _281.id]), () => ( null)), depth = _nullishCoalesce(_optionalChain([_chunkDPYAO5U6cjs.findLayer.call(void 0, this.doc.layers, l.id), 'optionalAccess', _282 => _282.path, 'access', _283 => _283.length]), () => ( 0))) {
6481
+ describeLayer(l, parentId = _nullishCoalesce(_optionalChain([_chunkDPYAO5U6cjs.findLayer.call(void 0, this.doc.layers, l.id), 'optionalAccess', _283 => _283.parent, 'optionalAccess', _284 => _284.id]), () => ( null)), depth = _nullishCoalesce(_optionalChain([_chunkDPYAO5U6cjs.findLayer.call(void 0, this.doc.layers, l.id), 'optionalAccess', _285 => _285.path, 'access', _286 => _286.length]), () => ( 0))) {
6459
6482
  let bounds = null;
6460
6483
  if (l.type === "pixel") {
6461
6484
  const b = _chunk474IQG74cjs.contentBounds.call(void 0, l.surface);
@@ -6472,8 +6495,8 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
6472
6495
  locks: { ..._nullishCoalesce(l.locks, () => ( {})) },
6473
6496
  active: l.id === this.doc.activeLayerId,
6474
6497
  bounds,
6475
- ..._optionalChain([this, 'access', _284 => _284.doc, 'access', _285 => _285.liveStrokes, 'optionalAccess', _286 => _286[l.id]]) ? { liveStrokes: this.doc.liveStrokes[l.id].length } : {},
6476
- ..._optionalChain([l, 'access', _287 => _287.effects, 'optionalAccess', _288 => _288.items, 'access', _289 => _289.length]) ? { effects: l.effects.items.length } : {},
6498
+ ..._optionalChain([this, 'access', _287 => _287.doc, 'access', _288 => _288.liveStrokes, 'optionalAccess', _289 => _289[l.id]]) ? { liveStrokes: this.doc.liveStrokes[l.id].length } : {},
6499
+ ..._optionalChain([l, 'access', _290 => _290.effects, 'optionalAccess', _291 => _291.items, 'access', _292 => _292.length]) ? { effects: l.effects.items.length } : {},
6477
6500
  parentId,
6478
6501
  depth
6479
6502
  };
@@ -6505,7 +6528,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
6505
6528
  this.requireIdle("adding a layer");
6506
6529
  const count = _chunkDPYAO5U6cjs.flattenLayers.call(void 0, this.doc.layers).length;
6507
6530
  const type = _nullishCoalesce(options.type, () => ( "pixel"));
6508
- const name = _optionalChain([options, 'access', _290 => _290.name, 'optionalAccess', _291 => _291.trim, 'call', _292 => _292()]) || (type === "group" ? `Group ${count + 1}` : type === "strokes" ? `Strokes ${count + 1}` : `Layer ${count + 1}`);
6531
+ const name = _optionalChain([options, 'access', _293 => _293.name, 'optionalAccess', _294 => _294.trim, 'call', _295 => _295()]) || (type === "group" ? `Group ${count + 1}` : type === "strokes" ? `Strokes ${count + 1}` : `Layer ${count + 1}`);
6509
6532
  const layer = type === "group" ? { type: "group", id: newPaintLayerId(), name, visible: true, opacity: 1, blend: "pass-through", children: [] } : createPaintLayer(name);
6510
6533
  let parentId = null;
6511
6534
  let index;
@@ -6517,7 +6540,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
6517
6540
  } else if (above) {
6518
6541
  const loc = _chunkDPYAO5U6cjs.findLayer.call(void 0, this.doc.layers, above);
6519
6542
  if (!loc) throw new PaintEditorError(`Unknown layer "${above}". Call list_layers for the ids.`);
6520
- parentId = _nullishCoalesce(_optionalChain([loc, 'access', _293 => _293.parent, 'optionalAccess', _294 => _294.id]), () => ( null));
6543
+ parentId = _nullishCoalesce(_optionalChain([loc, 'access', _296 => _296.parent, 'optionalAccess', _297 => _297.id]), () => ( null));
6521
6544
  index = loc.index + 1;
6522
6545
  }
6523
6546
  const layers = _chunkDPYAO5U6cjs.insertLayer.call(void 0, this.doc.layers, layer, parentId, index);
@@ -6623,7 +6646,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
6623
6646
  }
6624
6647
  requireEffect(id, effectId) {
6625
6648
  const l = this.requireLayer(id);
6626
- const items = _nullishCoalesce(_optionalChain([l, 'access', _295 => _295.effects, 'optionalAccess', _296 => _296.items]), () => ( []));
6649
+ const items = _nullishCoalesce(_optionalChain([l, 'access', _298 => _298.effects, 'optionalAccess', _299 => _299.items]), () => ( []));
6627
6650
  const i = items.findIndex((e) => e.id === effectId);
6628
6651
  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.`);
6629
6652
  return i;
@@ -6646,7 +6669,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
6646
6669
  }
6647
6670
  const layers = _chunkDPYAO5U6cjs.mapLayer.call(void 0, this.doc.layers, id, () => null);
6648
6671
  let active = this.doc.activeLayerId;
6649
- if (active && !_chunkDPYAO5U6cjs.findLayer.call(void 0, layers, active)) active = _nullishCoalesce(_optionalChain([_chunkDPYAO5U6cjs.flattenLayers.call(void 0, layers), 'access', _297 => _297.filter, 'call', _298 => _298((x) => x.type === "pixel"), 'access', _299 => _299.pop, 'call', _300 => _300(), 'optionalAccess', _301 => _301.id]), () => ( null));
6672
+ if (active && !_chunkDPYAO5U6cjs.findLayer.call(void 0, layers, active)) active = _nullishCoalesce(_optionalChain([_chunkDPYAO5U6cjs.flattenLayers.call(void 0, layers), 'access', _300 => _300.filter, 'call', _301 => _301((x) => x.type === "pixel"), 'access', _302 => _302.pop, 'call', _303 => _303(), 'optionalAccess', _304 => _304.id]), () => ( null));
6650
6673
  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)) });
6651
6674
  return { removed: id, activeLayerId: active };
6652
6675
  }
@@ -6672,7 +6695,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
6672
6695
  return l.type === "group" ? { ...l, id: id2, children: l.children.map(copy) } : { ...l, id: id2 };
6673
6696
  };
6674
6697
  const dup = { ...copy(loc.layer), name: `${loc.layer.name} copy` };
6675
- const layers = _chunkDPYAO5U6cjs.insertLayer.call(void 0, this.doc.layers, dup, _nullishCoalesce(_optionalChain([loc, 'access', _302 => _302.parent, 'optionalAccess', _303 => _303.id]), () => ( null)), loc.index + 1);
6698
+ const layers = _chunkDPYAO5U6cjs.insertLayer.call(void 0, this.doc.layers, dup, _nullishCoalesce(_optionalChain([loc, 'access', _305 => _305.parent, 'optionalAccess', _306 => _306.id]), () => ( null)), loc.index + 1);
6676
6699
  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 } : {} }));
6677
6700
  return this.describeLayer(dup);
6678
6701
  }
@@ -6681,7 +6704,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
6681
6704
  this.requireIdle("moving a layer");
6682
6705
  const loc = _chunkDPYAO5U6cjs.findLayer.call(void 0, this.doc.layers, id);
6683
6706
  if (!loc) throw new PaintEditorError(`Unknown layer "${id}". Call list_layers for the ids.`);
6684
- const target = parentId === void 0 ? _nullishCoalesce(_optionalChain([loc, 'access', _304 => _304.parent, 'optionalAccess', _305 => _305.id]), () => ( null)) : parentId;
6707
+ const target = parentId === void 0 ? _nullishCoalesce(_optionalChain([loc, 'access', _307 => _307.parent, 'optionalAccess', _308 => _308.id]), () => ( null)) : parentId;
6685
6708
  if (target) {
6686
6709
  const g = this.requireLayer(target);
6687
6710
  if (g.type !== "group") throw new PaintEditorError(`Layer "${g.name}" is not a group; pass a group id as parentId.`);
@@ -6700,7 +6723,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
6700
6723
  const pre = _chunkDPYAO5U6cjs.findLayer.call(void 0, this.doc.layers, id);
6701
6724
  if (pre) {
6702
6725
  const sib = pre.parent ? pre.parent.children : this.doc.layers;
6703
- this.dryLayersFirst([id, _optionalChain([sib, 'access', _306 => _306[pre.index - 1], 'optionalAccess', _307 => _307.id])].filter((x) => Boolean(x)));
6726
+ this.dryLayersFirst([id, _optionalChain([sib, 'access', _309 => _309[pre.index - 1], 'optionalAccess', _310 => _310.id])].filter((x) => Boolean(x)));
6704
6727
  }
6705
6728
  const loc = _chunkDPYAO5U6cjs.findLayer.call(void 0, this.doc.layers, id);
6706
6729
  if (!loc) throw new PaintEditorError(`Unknown layer "${id}". Call list_layers for the ids.`);
@@ -6720,7 +6743,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
6720
6743
  const merged = { ...below, surface, offset: { x: 0, y: 0 } };
6721
6744
  const layers = _chunkDPYAO5U6cjs.mapLayer.call(void 0, _chunkDPYAO5U6cjs.mapLayer.call(void 0, this.doc.layers, upper.id, () => null), below.id, () => merged);
6722
6745
  const toDoc = (t, l) => t ? _chunk474IQG74cjs.translateSurface.call(void 0, t, l.offset.x, l.offset.y) : void 0;
6723
- const mergedLight = _optionalChain([this, 'access', _308 => _308.doc, 'access', _309 => _309.light, 'optionalAccess', _310 => _310[upper.id]]) || _optionalChain([this, 'access', _311 => _311.doc, 'access', _312 => _312.light, 'optionalAccess', _313 => _313[below.id]]) ? mergeLight(toDoc(_optionalChain([this, 'access', _314 => _314.doc, 'access', _315 => _315.light, 'optionalAccess', _316 => _316[below.id]]), below), upper.visible ? toDoc(_optionalChain([this, 'access', _317 => _317.doc, 'access', _318 => _318.light, 'optionalAccess', _319 => _319[upper.id]]), upper) : void 0, _chunk474IQG74cjs.translateSurface.call(void 0, upper.surface, upper.offset.x, upper.offset.y)) : void 0;
6746
+ const mergedLight = _optionalChain([this, 'access', _311 => _311.doc, 'access', _312 => _312.light, 'optionalAccess', _313 => _313[upper.id]]) || _optionalChain([this, 'access', _314 => _314.doc, 'access', _315 => _315.light, 'optionalAccess', _316 => _316[below.id]]) ? mergeLight(toDoc(_optionalChain([this, 'access', _317 => _317.doc, 'access', _318 => _318.light, 'optionalAccess', _319 => _319[below.id]]), below), upper.visible ? toDoc(_optionalChain([this, 'access', _320 => _320.doc, 'access', _321 => _321.light, 'optionalAccess', _322 => _322[upper.id]]), upper) : void 0, _chunk474IQG74cjs.translateSurface.call(void 0, upper.surface, upper.offset.x, upper.offset.y)) : void 0;
6724
6747
  const lightAfter = _nullishCoalesce(this.lightWithout([upper.id, below.id]).light, () => ( (this.doc.light ? { ...this.doc.light } : void 0)));
6725
6748
  const light = mergedLight ? { ..._nullishCoalesce(lightAfter, () => ( {})), [below.id]: mergedLight } : lightAfter;
6726
6749
  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 } : {} }));
@@ -6735,7 +6758,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
6735
6758
  this.wet.world.removeLane(l.id);
6736
6759
  }
6737
6760
  const bounds = this.describeLayer(l).bounds;
6738
- 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', _320 => _320.doc, 'access', _321 => _321.liveStrokes, 'optionalAccess', _322 => _322[l.id]]) ? { liveStrokes: { ...this.doc.liveStrokes, [l.id]: [] } } : {}, ...this.lightWithout([l.id]) }, { kind: "clear", layerId: l.id }));
6761
+ 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', _323 => _323.doc, 'access', _324 => _324.liveStrokes, 'optionalAccess', _325 => _325[l.id]]) ? { liveStrokes: { ...this.doc.liveStrokes, [l.id]: [] } } : {}, ...this.lightWithout([l.id]) }, { kind: "clear", layerId: l.id }));
6739
6762
  return { layerId: l.id, bounds };
6740
6763
  }
6741
6764
  /**
@@ -6745,8 +6768,8 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
6745
6768
  fillLayer(options = {}) {
6746
6769
  this.requireIdle("filling");
6747
6770
  const fillTarget = this.paintTarget(options.layerId, "fill");
6748
- if (_optionalChain([this, 'access', _323 => _323.doc, 'access', _324 => _324.stickers, 'optionalAccess', _325 => _325[fillTarget.id], 'optionalAccess', _326 => _326.length])) throw new PaintEditorError(`Layer "${fillTarget.name}" is a sticker layer; fill another layer (add_layer).`);
6749
- if (_optionalChain([this, 'access', _327 => _327.doc, 'access', _328 => _328.liveStrokes, 'optionalAccess', _329 => _329[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).`);
6771
+ if (_optionalChain([this, 'access', _326 => _326.doc, 'access', _327 => _327.stickers, 'optionalAccess', _328 => _328[fillTarget.id], 'optionalAccess', _329 => _329.length])) throw new PaintEditorError(`Layer "${fillTarget.name}" is a sticker layer; fill another layer (add_layer).`);
6772
+ if (_optionalChain([this, 'access', _330 => _330.doc, 'access', _331 => _331.liveStrokes, 'optionalAccess', _332 => _332[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).`);
6750
6773
  this.dryLayersFirst([_nullishCoalesce(_nullishCoalesce(options.layerId, () => ( this.doc.activeLayerId)), () => ( ""))]);
6751
6774
  const l = this.paintTarget(options.layerId, "fill");
6752
6775
  const color = options.color === void 0 ? this.color : parseColor(options.color);
@@ -6779,7 +6802,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
6779
6802
  offset: l.offset
6780
6803
  };
6781
6804
  const surface = this.applyCoverage(l, coverage, rect, apply);
6782
- const lit = _optionalChain([this, 'access', _330 => _330.doc, 'access', _331 => _331.light, 'optionalAccess', _332 => _332[l.id]]);
6805
+ const lit = _optionalChain([this, 'access', _333 => _333.doc, 'access', _334 => _334.light, 'optionalAccess', _335 => _335[l.id]]);
6783
6806
  const light = lit ? withLayerLight(this.doc.light, l.id, scaleLight(lit, 1 - opacity)) : void 0;
6784
6807
  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 } }));
6785
6808
  return { layerId: l.id, bounds: rect };
@@ -6789,7 +6812,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
6789
6812
  const tiles = new Map(base.tiles);
6790
6813
  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 })) {
6791
6814
  const key = _chunk474IQG74cjs.tileKey.call(void 0, tx, ty);
6792
- const src = _nullishCoalesce(_optionalChain([base, 'access', _333 => _333.tiles, 'access', _334 => _334.get, 'call', _335 => _335(key), 'optionalAccess', _336 => _336.data]), () => ( new Uint8ClampedArray(_chunk474IQG74cjs.TILE * _chunk474IQG74cjs.TILE * 4)));
6815
+ const src = _nullishCoalesce(_optionalChain([base, 'access', _336 => _336.tiles, 'access', _337 => _337.get, 'call', _338 => _338(key), 'optionalAccess', _339 => _339.data]), () => ( new Uint8ClampedArray(_chunk474IQG74cjs.TILE * _chunk474IQG74cjs.TILE * 4)));
6793
6816
  const tile = _chunk474IQG74cjs.finishTile.call(void 0, _chunkFQPUF2W2cjs.applyStrokeToTile.call(void 0, coverage, src, 4, tx, ty, apply), 4, 0);
6794
6817
  if (tile) tiles.set(key, tile);
6795
6818
  else tiles.delete(key);
@@ -6822,7 +6845,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
6822
6845
  }
6823
6846
  /** The effect a layer is drawn from, or `undefined` for other layers. */
6824
6847
  getEffectLayer(layerId) {
6825
- return _chunkDPYAO5U6cjs.findLayer.call(void 0, this.doc.layers, layerId) ? _optionalChain([this, 'access', _337 => _337.doc, 'access', _338 => _338.effectLayers, 'optionalAccess', _339 => _339[layerId]]) : void 0;
6848
+ return _chunkDPYAO5U6cjs.findLayer.call(void 0, this.doc.layers, layerId) ? _optionalChain([this, 'access', _340 => _340.doc, 'access', _341 => _341.effectLayers, 'optionalAccess', _342 => _342[layerId]]) : void 0;
6826
6849
  }
6827
6850
  /** The effect paper (without its pixels), or `null`. */
6828
6851
  getPaperEffect() {
@@ -6859,8 +6882,8 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
6859
6882
  /** A pixel layer that takes effect pixels: unlocked, visible, no sticker layer, no wet paint. */
6860
6883
  effectTarget(layerId, what) {
6861
6884
  const l = this.paintTarget(layerId, what);
6862
- if (_optionalChain([this, 'access', _340 => _340.doc, 'access', _341 => _341.stickers, 'optionalAccess', _342 => _342[l.id], 'optionalAccess', _343 => _343.length])) throw new PaintEditorError(`Layer "${l.name}" is a sticker layer; ${what} another layer (add_layer).`);
6863
- if (_optionalChain([this, 'access', _344 => _344.doc, 'access', _345 => _345.liveStrokes, 'optionalAccess', _346 => _346[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).`);
6885
+ if (_optionalChain([this, 'access', _343 => _343.doc, 'access', _344 => _344.stickers, 'optionalAccess', _345 => _345[l.id], 'optionalAccess', _346 => _346.length])) throw new PaintEditorError(`Layer "${l.name}" is a sticker layer; ${what} another layer (add_layer).`);
6886
+ if (_optionalChain([this, 'access', _347 => _347.doc, 'access', _348 => _348.liveStrokes, 'optionalAccess', _349 => _349[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).`);
6864
6887
  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.`);
6865
6888
  return l;
6866
6889
  }
@@ -6899,8 +6922,8 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
6899
6922
  const was = this.doc.paperEffect;
6900
6923
  const paperEffect = {
6901
6924
  ...this.sourceOf(d, values, options.time),
6902
- opacity: _nullishCoalesce(_nullishCoalesce(options.opacity, () => ( _optionalChain([was, 'optionalAccess', _347 => _347.opacity]))), () => ( 1)),
6903
- blend: _nullishCoalesce(_nullishCoalesce(options.blend, () => ( _optionalChain([was, 'optionalAccess', _348 => _348.blend]))), () => ( "multiply")),
6925
+ opacity: _nullishCoalesce(_nullishCoalesce(options.opacity, () => ( _optionalChain([was, 'optionalAccess', _350 => _350.opacity]))), () => ( 1)),
6926
+ blend: _nullishCoalesce(_nullishCoalesce(options.blend, () => ( _optionalChain([was, 'optionalAccess', _351 => _351.blend]))), () => ( "multiply")),
6904
6927
  image: { width: pixels.width, height: pixels.height, data: new Uint8ClampedArray(pixels.data) },
6905
6928
  version: nextPaperEffectVersion()
6906
6929
  };
@@ -6953,8 +6976,8 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
6953
6976
  const above = _nullishCoalesce(options.aboveId, () => ( this.doc.activeLayerId));
6954
6977
  const loc = above ? _chunkDPYAO5U6cjs.findLayer.call(void 0, this.doc.layers, above) : null;
6955
6978
  if (options.aboveId !== void 0 && !loc) throw new PaintEditorError(`Layer "${options.aboveId}" was removed while the effect rendered.`);
6956
- const layer = { ...createPaintLayer(_optionalChain([options, 'access', _349 => _349.name, 'optionalAccess', _350 => _350.trim, 'call', _351 => _351()]) || d.name), surface: _chunk474IQG74cjs.surfaceFromPixels.call(void 0, pixels, 4), opacity: _nullishCoalesce(options.opacity, () => ( 1)), blend: _nullishCoalesce(options.blend, () => ( "normal")) };
6957
- const layers = _chunkDPYAO5U6cjs.insertLayer.call(void 0, this.doc.layers, layer, _nullishCoalesce(_optionalChain([loc, 'optionalAccess', _352 => _352.parent, 'optionalAccess', _353 => _353.id]), () => ( null)), loc ? loc.index + 1 : void 0);
6979
+ const layer = { ...createPaintLayer(_optionalChain([options, 'access', _352 => _352.name, 'optionalAccess', _353 => _353.trim, 'call', _354 => _354()]) || d.name), surface: _chunk474IQG74cjs.surfaceFromPixels.call(void 0, pixels, 4), opacity: _nullishCoalesce(options.opacity, () => ( 1)), blend: _nullishCoalesce(options.blend, () => ( "normal")) };
6980
+ const layers = _chunkDPYAO5U6cjs.insertLayer.call(void 0, this.doc.layers, layer, _nullishCoalesce(_optionalChain([loc, 'optionalAccess', _355 => _355.parent, 'optionalAccess', _356 => _356.id]), () => ( null)), loc ? loc.index + 1 : void 0);
6958
6981
  const source = this.sourceOf(d, values, options.time);
6959
6982
  this.commit("Add effect layer", { ...this.doc, layers, activeLayerId: layer.id, effectLayers: { ..._nullishCoalesce(this.doc.effectLayers, () => ( {})), [layer.id]: source } });
6960
6983
  return { layer: this.describeLayer(layer), source };
@@ -7107,7 +7130,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
7107
7130
  /** Renders the effect paints of recorded strokes (default all of them) before a replay. */
7108
7131
  async prepareStrokeEffects(strokeIds) {
7109
7132
  const ids = strokeIds ? new Set(strokeIds) : null;
7110
- const paints2 = this.doc.strokes.filter((s) => (!ids || ids.has(s.id)) && _optionalChain([s, 'access', _354 => _354.paint, 'optionalAccess', _355 => _355.type]) === "effect").map((s) => s.paint);
7133
+ const paints2 = this.doc.strokes.filter((s) => (!ids || ids.has(s.id)) && _optionalChain([s, 'access', _357 => _357.paint, 'optionalAccess', _358 => _358.type]) === "effect").map((s) => s.paint);
7111
7134
  await this.prepareEffectPaints(paints2);
7112
7135
  }
7113
7136
  /** A small preview of the effect paint (a PNG data URL `size` px wide), or `null` without a rendered one. */
@@ -7170,14 +7193,14 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
7170
7193
  const before = _chunk474IQG74cjs.readRegion.call(void 0, l.surface, rect);
7171
7194
  const inputs = { source: { width: rect.width, height: rect.height, data: before } };
7172
7195
  const heightInput = d.inputs.find((i) => i.kind === "image" && /^(height|depth|relief)$/i.test(i.name));
7173
- const relief = _optionalChain([this, 'access', _356 => _356.doc, 'access', _357 => _357.thick, 'optionalAccess', _358 => _358[l.id]]);
7196
+ const relief = _optionalChain([this, 'access', _359 => _359.doc, 'access', _360 => _360.thick, 'optionalAccess', _361 => _361[l.id]]);
7174
7197
  if (heightInput && relief) {
7175
7198
  const h = _chunk474IQG74cjs.readRegion.call(void 0, relief.height, rect);
7176
7199
  const rgba = new Uint8ClampedArray(rect.width * rect.height * 4);
7177
7200
  for (let i = 0; i < h.length; i++) rgba.set([h[i], h[i], h[i], 255], i * 4);
7178
7201
  inputs[heightInput.name] = { width: rect.width, height: rect.height, data: rgba };
7179
7202
  }
7180
- const sourceInput = _nullishCoalesce(_optionalChain([d, 'access', _359 => _359.inputs, 'access', _360 => _360.find, 'call', _361 => _361((i) => i.kind === "image" && i.name !== _optionalChain([heightInput, 'optionalAccess', _362 => _362.name])), 'optionalAccess', _363 => _363.name]), () => ( "source"));
7203
+ const sourceInput = _nullishCoalesce(_optionalChain([d, 'access', _362 => _362.inputs, 'access', _363 => _363.find, 'call', _364 => _364((i) => i.kind === "image" && i.name !== _optionalChain([heightInput, 'optionalAccess', _365 => _365.name])), 'optionalAccess', _366 => _366.name]), () => ( "source"));
7181
7204
  if (sourceInput !== "source") {
7182
7205
  inputs[sourceInput] = inputs.source;
7183
7206
  delete inputs.source;
@@ -7193,7 +7216,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
7193
7216
  return this.brushEntries.find((e) => e.brush.id === id);
7194
7217
  }
7195
7218
  findBrush(id) {
7196
- return _optionalChain([this, 'access', _364 => _364.findEntry, 'call', _365 => _365(id), 'optionalAccess', _366 => _366.brush]);
7219
+ return _optionalChain([this, 'access', _367 => _367.findEntry, 'call', _368 => _368(id), 'optionalAccess', _369 => _369.brush]);
7197
7220
  }
7198
7221
  requireEntry(id) {
7199
7222
  const e = this.findEntry(id);
@@ -7227,7 +7250,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
7227
7250
  }
7228
7251
  /** A library brush by id as stored (its facets), or without an id the active brush as edited. */
7229
7252
  getBrushSpec(id) {
7230
- const spec = id === void 0 ? this.brushSpec : _optionalChain([this, 'access', _367 => _367.findEntry, 'call', _368 => _368(id), 'optionalAccess', _369 => _369.spec]);
7253
+ const spec = id === void 0 ? this.brushSpec : _optionalChain([this, 'access', _370 => _370.findEntry, 'call', _371 => _371(id), 'optionalAccess', _372 => _372.spec]);
7231
7254
  return spec ? copyJSON(spec) : void 0;
7232
7255
  }
7233
7256
  /**
@@ -7259,8 +7282,8 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
7259
7282
  const base = copyJSON(entry ? entry.spec : this.brushSpec);
7260
7283
  for (const k of unset) delete base[k];
7261
7284
  const spec = this.readBrushPatch(base, patch, problems);
7262
- if (entry || _optionalChain([patch, 'access', _370 => _370.colour, 'optionalAccess', _371 => _371.default]) !== void 0) this.takeBrushColour(spec);
7263
- this.useBrush(unchanged && entry ? entry.brush : _chunkRSIKDWOPcjs.resolveBrush.call(void 0, spec), spec, unchanged && _optionalChain([entry, 'optionalAccess', _372 => _372.builtin]) === true);
7285
+ if (entry || _optionalChain([patch, 'access', _373 => _373.colour, 'optionalAccess', _374 => _374.default]) !== void 0) this.takeBrushColour(spec);
7286
+ this.useBrush(unchanged && entry ? entry.brush : _chunkRSIKDWOPcjs.resolveBrush.call(void 0, spec), spec, unchanged && _optionalChain([entry, 'optionalAccess', _375 => _375.builtin]) === true);
7264
7287
  return { brush: this.brush, spec: copyJSON(this.brushSpec), problems };
7265
7288
  }
7266
7289
  /**
@@ -7270,7 +7293,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
7270
7293
  */
7271
7294
  setBrushSpec(spec) {
7272
7295
  const problems = [];
7273
- const paint = _optionalChain([spec, 'access', _373 => _373.colour, 'optionalAccess', _374 => _374.default]);
7296
+ const paint = _optionalChain([spec, 'access', _376 => _376.colour, 'optionalAccess', _377 => _377.default]);
7274
7297
  if (paint && typeof paint === "object" && "type" in paint && paint.type === "gradient") this.readStrokePaint(paint);
7275
7298
  let next;
7276
7299
  try {
@@ -7293,7 +7316,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
7293
7316
  }
7294
7317
  readBrushPatch(base, patch, problems) {
7295
7318
  const { id: _id, name, ...rest } = patch;
7296
- const paint = _optionalChain([rest, 'access', _375 => _375.colour, 'optionalAccess', _376 => _376.default]);
7319
+ const paint = _optionalChain([rest, 'access', _378 => _378.colour, 'optionalAccess', _379 => _379.default]);
7297
7320
  if (paint && typeof paint === "object" && "type" in paint && paint.type === "gradient") this.readStrokePaint(paint);
7298
7321
  try {
7299
7322
  return _chunkRSIKDWOPcjs.normalizeBrushSpec.call(void 0, _chunkMQGQTKVWcjs.mergeBrushPatch.call(void 0, base, { ...rest, ...name !== void 0 ? { name } : {} }), problems);
@@ -7356,9 +7379,9 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
7356
7379
  }
7357
7380
  // --- Colour --------------------------------------------------------------------
7358
7381
 
7359
- __init178() {this.colorLocked = false}
7382
+ __init179() {this.colorLocked = false}
7360
7383
  /** The brush default colour the paint colour came from (resolved again when the scheme changes), or `null`. */
7361
- __init179() {this.brushColour = null}
7384
+ __init180() {this.brushColour = null}
7362
7385
  /**
7363
7386
  * The host's colour scheme: a paint colour that came from a brush's light / dark default
7364
7387
  * resolves to the new side. Editor state, not an undo step.
@@ -7384,7 +7407,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
7384
7407
  */
7385
7408
  takeBrushColour(spec) {
7386
7409
  if (this.colorLocked) return;
7387
- const d = _optionalChain([spec, 'access', _377 => _377.colour, 'optionalAccess', _378 => _378.default]);
7410
+ const d = _optionalChain([spec, 'access', _380 => _380.colour, 'optionalAccess', _381 => _381.default]);
7388
7411
  const hex2 = d !== void 0 ? _chunkLRTR4ASZcjs.brushColourHex.call(void 0, d, this.colorScheme) : null;
7389
7412
  if (!hex2) return;
7390
7413
  this.color = hex2;
@@ -7395,8 +7418,8 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
7395
7418
  }
7396
7419
  /** A brush that always paints its own colour (`colour.own`): that colour, resolved for the scheme now; else `null`. */
7397
7420
  ownColour(brushId) {
7398
- const spec = brushId !== void 0 ? _optionalChain([this, 'access', _379 => _379.findEntry, 'call', _380 => _380(brushId), 'optionalAccess', _381 => _381.spec]) : this.brushSpec;
7399
- const d = _optionalChain([spec, 'optionalAccess', _382 => _382.colour, 'optionalAccess', _383 => _383.own]) ? spec.colour.default : void 0;
7421
+ const spec = brushId !== void 0 ? _optionalChain([this, 'access', _382 => _382.findEntry, 'call', _383 => _383(brushId), 'optionalAccess', _384 => _384.spec]) : this.brushSpec;
7422
+ const d = _optionalChain([spec, 'optionalAccess', _385 => _385.colour, 'optionalAccess', _386 => _386.own]) ? spec.colour.default : void 0;
7400
7423
  return d !== void 0 ? _chunkLRTR4ASZcjs.brushColourHex.call(void 0, d, this.colorScheme) : null;
7401
7424
  }
7402
7425
  /** Sets the paint colour (and goes back to one colour from gradient paint). */
@@ -7554,18 +7577,18 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
7554
7577
  if (brush.light.amount > 0) {
7555
7578
  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 (glow-gel, neon-marker; list_brush_presets lists them), or set light.amount to 0 (set_brush).`);
7556
7579
  }
7557
- if (_optionalChain([doc, 'access', _384 => _384.liveStrokes, 'optionalAccess', _385 => _385[layer.id]])) {
7580
+ if (_optionalChain([doc, 'access', _387 => _387.liveStrokes, 'optionalAccess', _388 => _388[layer.id]])) {
7558
7581
  const why = liveStrokeRefusal(brush);
7559
7582
  if (why) throw new PaintEditorError(`Layer "${layer.name}" is a stroke layer. ${why}`);
7560
7583
  }
7561
- if (_optionalChain([doc, 'access', _386 => _386.liveStrokes, 'optionalAccess', _387 => _387[layer.id]]) && _optionalChain([effect, 'optionalAccess', _388 => _388.source, 'access', _389 => _389.live])) {
7584
+ if (_optionalChain([doc, 'access', _389 => _389.liveStrokes, 'optionalAccess', _390 => _390[layer.id]]) && _optionalChain([effect, 'optionalAccess', _391 => _391.source, 'access', _392 => _392.live])) {
7562
7585
  const key = effectPaintKey(effect.source);
7563
7586
  const { sources } = this.liveEffects(doc);
7564
7587
  if (!sources.some((p) => effectPaintKey(p) === key) && sources.length >= MAX_LIVE_EFFECT_SOURCES) {
7565
7588
  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.`);
7566
7589
  }
7567
7590
  }
7568
- const stickerLayer = Boolean(_optionalChain([doc, 'access', _390 => _390.stickers, 'optionalAccess', _391 => _391[layer.id], 'optionalAccess', _392 => _392.length]));
7591
+ const stickerLayer = Boolean(_optionalChain([doc, 'access', _393 => _393.stickers, 'optionalAccess', _394 => _394[layer.id], 'optionalAccess', _395 => _395.length]));
7569
7592
  if (brush.engine === "sticker") {
7570
7593
  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.`);
7571
7594
  } else if (stickerLayer) {
@@ -7605,7 +7628,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
7605
7628
  copies: [IDENTITY_AFFINE, ...copiesW].map(affineCopy),
7606
7629
  mask: init.maskStencils ? this.stencilSelection(init.maskStencils) : init.stencils !== false ? this.stencilSelection() : null,
7607
7630
  paint: effect ? null : wetGradient,
7608
- effect: _nullishCoalesce(_optionalChain([effect, 'optionalAccess', _393 => _393.pixels]), () => ( null))
7631
+ effect: _nullishCoalesce(_optionalChain([effect, 'optionalAccess', _396 => _396.pixels]), () => ( null))
7609
7632
  });
7610
7633
  init = { ...init, seed: seedW, load };
7611
7634
  wet = { driver, surface: () => world.display(id).surface };
@@ -7616,7 +7639,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
7616
7639
  }
7617
7640
  let color = init.color === void 0 ? _nullishCoalesce(this.ownColour(init.brushId), () => ( this.color)) : parseColor(init.color);
7618
7641
  const tracing = this.guides.tracing;
7619
- if (init.color === void 0 && init.start && _optionalChain([tracing, 'optionalAccess', _394 => _394.visible]) && tracing.sampleColors) color = _nullishCoalesce(this.sampleTracingColor(init.start.x, init.start.y), () => ( color));
7642
+ if (init.color === void 0 && init.start && _optionalChain([tracing, 'optionalAccess', _397 => _397.visible]) && tracing.sampleColors) color = _nullishCoalesce(this.sampleTracingColor(init.start.x, init.start.y), () => ( color));
7620
7643
  const perspective = this.guides.perspective;
7621
7644
  const snapper = init.snapToPerspective && perspective.enabled && perspective.snap ? new PerspectiveSnapper(perspective) : null;
7622
7645
  const useStencils = init.stencils !== false;
@@ -7649,9 +7672,9 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
7649
7672
  mixerLoad: _nullishCoalesce(init.load, () => ( brushLoadForStroke(brush, this.mixerLoad, [rgba[0] / 255, rgba[1] / 255, rgba[2] / 255]))),
7650
7673
  secondary: rgbaOf(this.secondaryColor),
7651
7674
  wet,
7652
- thick: brush.engine === "impasto" ? { channels: _nullishCoalesce(_optionalChain([doc, 'access', _395 => _395.thick, 'optionalAccess', _396 => _396[layer.id]]), () => ( emptyThickChannels())) } : void 0,
7675
+ thick: brush.engine === "impasto" ? { channels: _nullishCoalesce(_optionalChain([doc, 'access', _398 => _398.thick, 'optionalAccess', _399 => _399[layer.id]]), () => ( emptyThickChannels())) } : void 0,
7653
7676
  // Light paint: a twin of the stroke paints the light channel (laying, dimming, moving light).
7654
- light: !wet && brush.engine !== "sticker" && (brush.light.amount > 0 || _optionalChain([doc, 'access', _397 => _397.light, 'optionalAccess', _398 => _398[layer.id]])) ? { surface: _nullishCoalesce(_optionalChain([doc, 'access', _399 => _399.light, 'optionalAccess', _400 => _400[layer.id]]), () => ( emptyLight())) } : null,
7677
+ light: !wet && brush.engine !== "sticker" && (brush.light.amount > 0 || _optionalChain([doc, 'access', _400 => _400.light, 'optionalAccess', _401 => _401[layer.id]])) ? { surface: _nullishCoalesce(_optionalChain([doc, 'access', _402 => _402.light, 'optionalAccess', _403 => _403[layer.id]]), () => ( emptyLight())) } : null,
7655
7678
  sticker: brush.engine === "sticker" ? { nextId: this.nextStickerNumber(doc), art: this.stickerArt.get } : void 0,
7656
7679
  stampArt: this.stickerArt.get,
7657
7680
  paint: effect ? null : this.strokeGradient(init, brush, color),
@@ -7691,15 +7714,16 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
7691
7714
  const before = this.doc;
7692
7715
  const host = {
7693
7716
  update: (layerId, surface, rects) => {
7694
- if (_optionalChain([this, 'access', _401 => _401.session, 'optionalAccess', _402 => _402.init, 'access', _403 => _403.wet])) {
7717
+ if (_optionalChain([this, 'access', _404 => _404.session, 'optionalAccess', _405 => _405.init, 'access', _406 => _406.wet])) {
7695
7718
  this.wet.syncDisplays();
7696
7719
  return;
7697
7720
  }
7698
7721
  this.live = { layerId, surface };
7699
- const ch = _optionalChain([this, 'access', _404 => _404.session, 'optionalAccess', _405 => _405.thickChannels, 'call', _406 => _406()]);
7722
+ const ch = _optionalChain([this, 'access', _407 => _407.session, 'optionalAccess', _408 => _408.thickChannels, 'call', _409 => _409()]);
7700
7723
  this.liveThick = ch ? { layerId, channels: ch } : null;
7701
7724
  this.emit(rects);
7702
7725
  },
7726
+ sampled: (s, points) => this.notifySample("points", s, points),
7703
7727
  commit: (s, surface, cancelled) => {
7704
7728
  this.session = null;
7705
7729
  this.live = null;
@@ -7708,7 +7732,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
7708
7732
  const wetStroke = Boolean(s.init.wet);
7709
7733
  if (wetStroke) this.wet.driver = null;
7710
7734
  const brush = s.init.brush;
7711
- if (!cancelled && _optionalChain([s, 'access', _407 => _407.result, 'optionalAccess', _408 => _408.mixerLoad])) this.keepLoad(brush, s.result.mixerLoad);
7735
+ if (!cancelled && _optionalChain([s, 'access', _410 => _410.result, 'optionalAccess', _411 => _411.mixerLoad])) this.keepLoad(brush, s.result.mixerLoad);
7712
7736
  if (cancelled || !surface) {
7713
7737
  if (this.wetOp) {
7714
7738
  const snap = this.wetOp.before;
@@ -7719,11 +7743,12 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
7719
7743
  this.wet.syncDisplays();
7720
7744
  }
7721
7745
  this.emit();
7746
+ this.notifySample(cancelled ? "cancel" : "end", s, [], cancelled ? void 0 : null);
7722
7747
  return;
7723
7748
  }
7724
7749
  const stroke = this.record(s);
7725
7750
  s.result.strokeId = stroke.id;
7726
- this.paintedBounds.set(stroke, _nullishCoalesce(_optionalChain([s, 'access', _409 => _409.result, 'optionalAccess', _410 => _410.bounds]), () => ( null)));
7751
+ this.paintedBounds.set(stroke, _nullishCoalesce(_optionalChain([s, 'access', _412 => _412.result, 'optionalAccess', _413 => _413.bounds]), () => ( null)));
7727
7752
  if (wetStroke && this.wet.instantDry) {
7728
7753
  this.wet.dry(s.layerId);
7729
7754
  this.logWet({ kind: "dry", layerId: s.layerId, at: this.doc.strokes.length + 1 });
@@ -7734,10 +7759,11 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
7734
7759
  const ch = s.thickChannels();
7735
7760
  const thick = ch ? { ..._nullishCoalesce(this.doc.thick, () => ( {})), [l.id]: ch } : this.doc.thick;
7736
7761
  const sprayed = s.stickers();
7737
- const stickers = sprayed ? { ..._nullishCoalesce(this.doc.stickers, () => ( {})), [l.id]: [..._nullishCoalesce(_optionalChain([this, 'access', _411 => _411.doc, 'access', _412 => _412.stickers, 'optionalAccess', _413 => _413[l.id]]), () => ( [])), ...sprayed] } : this.doc.stickers;
7738
- const wetLight = wetStroke && _optionalChain([this, 'access', _414 => _414.wet, 'access', _415 => _415.world, 'optionalAccess', _416 => _416.hasLane, 'call', _417 => _417(l.id)]) ? this.wet.world.lightDisplay(l.id) : null;
7762
+ const stickers = sprayed ? { ..._nullishCoalesce(this.doc.stickers, () => ( {})), [l.id]: [..._nullishCoalesce(_optionalChain([this, 'access', _414 => _414.doc, 'access', _415 => _415.stickers, 'optionalAccess', _416 => _416[l.id]]), () => ( [])), ...sprayed] } : this.doc.stickers;
7763
+ const wetLight = wetStroke && _optionalChain([this, 'access', _417 => _417.wet, 'access', _418 => _418.world, 'optionalAccess', _419 => _419.hasLane, 'call', _420 => _420(l.id)]) ? this.wet.world.lightDisplay(l.id) : null;
7739
7764
  const light = withLayerLight(this.doc.light, l.id, _nullishCoalesce(s.lightChannel(), () => ( wetLight)));
7740
7765
  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);
7766
+ this.notifySample("end", s, [], stroke.id);
7741
7767
  }
7742
7768
  };
7743
7769
  let session;
@@ -7749,6 +7775,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
7749
7775
  }
7750
7776
  this.session = session;
7751
7777
  this.emit([]);
7778
+ this.notifySample("begin", session);
7752
7779
  return session;
7753
7780
  }
7754
7781
  /** The current live stroke, if any. */
@@ -7765,18 +7792,18 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
7765
7792
  if (cancelled || !surface) return;
7766
7793
  const stroke = this.record(s);
7767
7794
  s.result.strokeId = stroke.id;
7768
- this.paintedBounds.set(stroke, _nullishCoalesce(_optionalChain([s, 'access', _418 => _418.result, 'optionalAccess', _419 => _419.bounds]), () => ( null)));
7795
+ this.paintedBounds.set(stroke, _nullishCoalesce(_optionalChain([s, 'access', _421 => _421.result, 'optionalAccess', _422 => _422.bounds]), () => ( null)));
7769
7796
  const l = _chunkDPYAO5U6cjs.findLayer.call(void 0, out.layers, s.layerId).layer;
7770
7797
  const offset = s.init.wet ? { x: 0, y: 0 } : l.offset;
7771
7798
  const ch = s.thickChannels();
7772
7799
  const sprayed = s.stickers();
7773
- const lit = _nullishCoalesce(s.lightChannel(), () => ( (s.init.wet && _optionalChain([this, 'access', _420 => _420.wet, 'access', _421 => _421.world, 'optionalAccess', _422 => _422.hasLane, 'call', _423 => _423(l.id)]) ? this.wet.world.lightDisplay(l.id) : null)));
7800
+ const lit = _nullishCoalesce(s.lightChannel(), () => ( (s.init.wet && _optionalChain([this, 'access', _423 => _423.wet, 'access', _424 => _424.world, 'optionalAccess', _425 => _425.hasLane, 'call', _426 => _426(l.id)]) ? this.wet.world.lightDisplay(l.id) : null)));
7774
7801
  out = withLiveStroke({
7775
7802
  ...out,
7776
7803
  layers: _chunkDPYAO5U6cjs.mapLayer.call(void 0, out.layers, l.id, () => ({ ...l, surface, offset })),
7777
7804
  strokes: [...out.strokes, stroke],
7778
7805
  ...ch ? { thick: { ..._nullishCoalesce(out.thick, () => ( {})), [l.id]: ch } } : {},
7779
- ...sprayed ? { stickers: { ..._nullishCoalesce(out.stickers, () => ( {})), [l.id]: [..._nullishCoalesce(_optionalChain([out, 'access', _424 => _424.stickers, 'optionalAccess', _425 => _425[l.id]]), () => ( [])), ...sprayed] } } : {},
7806
+ ...sprayed ? { stickers: { ..._nullishCoalesce(out.stickers, () => ( {})), [l.id]: [..._nullishCoalesce(_optionalChain([out, 'access', _427 => _427.stickers, 'optionalAccess', _428 => _428[l.id]]), () => ( [])), ...sprayed] } } : {},
7780
7807
  ...lit ? { light: withLayerLight(out.light, l.id, lit) } : {}
7781
7808
  }, stroke);
7782
7809
  }
@@ -7835,7 +7862,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
7835
7862
  */
7836
7863
  replayStrokes(options) {
7837
7864
  this.requireIdle("replaying");
7838
- if (!_optionalChain([options, 'access', _426 => _426.strokeIds, 'optionalAccess', _427 => _427.length])) throw new PaintEditorError("strokeIds is empty; pass ids from list_strokes.");
7865
+ if (!_optionalChain([options, 'access', _429 => _429.strokeIds, 'optionalAccess', _430 => _430.length])) throw new PaintEditorError("strokeIds is empty; pass ids from list_strokes.");
7839
7866
  const strokes = options.strokeIds.map((id) => {
7840
7867
  const s = this.doc.strokes.find((x) => x.id === id);
7841
7868
  if (!s) throw new PaintEditorError(`Unknown stroke "${id}". Call list_strokes for the ids.`);
@@ -7849,7 +7876,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
7849
7876
  if (options.layerId !== void 0) this.paintTarget(options.layerId, "replay onto");
7850
7877
  if (options.color === void 0) {
7851
7878
  for (const s of strokes) {
7852
- if (_optionalChain([s, 'access', _428 => _428.paint, 'optionalAccess', _429 => _429.type]) === "effect" && !this.effectPaintImage(s.paint)) {
7879
+ if (_optionalChain([s, 'access', _431 => _431.paint, 'optionalAccess', _432 => _432.type]) === "effect" && !this.effectPaintImage(s.paint)) {
7853
7880
  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.`);
7854
7881
  }
7855
7882
  }
@@ -7907,7 +7934,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
7907
7934
  /** A layer's light paint: whether it has any, where (document pixels), its brightest value 0..255, and its spill. */
7908
7935
  lightOf(layerId) {
7909
7936
  const l = this.wetLayer(layerId, "read the light of");
7910
- const info = lightInfo(_optionalChain([this, 'access', _430 => _430.doc, 'access', _431 => _431.light, 'optionalAccess', _432 => _432[l.id]]));
7937
+ const info = lightInfo(_optionalChain([this, 'access', _433 => _433.doc, 'access', _434 => _434.light, 'optionalAccess', _435 => _435[l.id]]));
7911
7938
  const bounds = info.bounds ? { ...info.bounds, x: info.bounds.x + l.offset.x, y: info.bounds.y + l.offset.y } : null;
7912
7939
  return { layerId: l.id, hasLight: info.peak > 0, bounds, peak: info.peak, spill: { ...this.lightSpillOf(l.id) } };
7913
7940
  }
@@ -7958,7 +7985,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
7958
7985
  const id = _nullishCoalesce(layerId, () => ( this.doc.activeLayerId));
7959
7986
  if (!id) return null;
7960
7987
  this.requireLayer(id);
7961
- const ch = _optionalChain([this, 'access', _433 => _433.doc, 'access', _434 => _434.thick, 'optionalAccess', _435 => _435[id]]);
7988
+ const ch = _optionalChain([this, 'access', _436 => _436.doc, 'access', _437 => _437.thick, 'optionalAccess', _438 => _438[id]]);
7962
7989
  if (!ch) return null;
7963
7990
  const r = reliefInfo(ch);
7964
7991
  return { layerId: id, bounds: r.bounds, maxHeight: r.maxHeight };
@@ -8068,7 +8095,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8068
8095
  wetState() {
8069
8096
  const st = this.getState().wet;
8070
8097
  const backend = this.wet.backend();
8071
- return { ...st, layers: this.wet.wetLayerIds().map((id) => this.wet.info(id)), backend, message: _nullishCoalesce(_optionalChain([backend, 'optionalAccess', _436 => _436.message]), () => ( _chunkKBYB7OWBcjs.wetSupport.call(void 0, ).message)), engine: this.wet.engineInfo() };
8098
+ return { ...st, layers: this.wet.wetLayerIds().map((id) => this.wet.info(id)), backend, message: _nullishCoalesce(_optionalChain([backend, 'optionalAccess', _439 => _439.message]), () => ( _chunkKBYB7OWBcjs.wetSupport.call(void 0, ).message)), engine: this.wet.engineInfo() };
8072
8099
  }
8073
8100
  /**
8074
8101
  * Engine B, the WebGPU accelerator for large wet areas: whether it may run, its state (`off`,
@@ -8153,7 +8180,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8153
8180
  }
8154
8181
  /** Records a settings change as a wet event (not an undo step). */
8155
8182
  recordWetSetting(e) {
8156
- this.doc = { ...this.doc, wetEvents: [..._nullishCoalesce(this.doc.wetEvents, () => ( [])), { clock: _nullishCoalesce(_optionalChain([this, 'access', _437 => _437.wet, 'access', _438 => _438.world, 'optionalAccess', _439 => _439.clock]), () => ( 0)), at: this.doc.strokes.length, ...e }] };
8183
+ this.doc = { ...this.doc, wetEvents: [..._nullishCoalesce(this.doc.wetEvents, () => ( [])), { clock: _nullishCoalesce(_optionalChain([this, 'access', _440 => _440.wet, 'access', _441 => _441.world, 'optionalAccess', _442 => _442.clock]), () => ( 0)), at: this.doc.strokes.length, ...e }] };
8157
8184
  }
8158
8185
  /** Changes a layer's wet settings (viscosity, evaporation, granulation…). Editor settings saved with the document, not an undo step. */
8159
8186
  setWetParams(layerId, update) {
@@ -8222,7 +8249,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8222
8249
  if (override) return Array.from(override).reduce((ls, [id, surface]) => _chunkDPYAO5U6cjs.mapLayer.call(void 0, ls, id, (l) => ({ ...l, surface })), this.doc.layers);
8223
8250
  const live = this.live;
8224
8251
  if (!live) return this.animatedView();
8225
- if (_optionalChain([this, 'access', _440 => _440.liveLayers, 'optionalAccess', _441 => _441.key]) === live.surface) return this.liveLayers.layers;
8252
+ if (_optionalChain([this, 'access', _443 => _443.liveLayers, 'optionalAccess', _444 => _444.key]) === live.surface) return this.liveLayers.layers;
8226
8253
  const layers = _chunkDPYAO5U6cjs.mapLayer.call(void 0, this.doc.layers, live.layerId, (l) => ({ ...l, surface: live.surface }));
8227
8254
  this.liveLayers = { key: live.surface, layers };
8228
8255
  return layers;
@@ -8245,7 +8272,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8245
8272
  tracingNode(t) {
8246
8273
  const { width, height } = this.doc.canvas;
8247
8274
  const key = this.tracingVersion * 100003 + width * 7 + height;
8248
- if (_optionalChain([this, 'access', _442 => _442.tracingCache, 'optionalAccess', _443 => _443.key]) === key && this.tracingCache.node.opacity === t.opacity) return this.tracingCache.node;
8275
+ if (_optionalChain([this, 'access', _445 => _445.tracingCache, 'optionalAccess', _446 => _446.key]) === key && this.tracingCache.node.opacity === t.opacity) return this.tracingCache.node;
8249
8276
  const src = _nullishCoalesce(this.imagePixels.get(t.src), () => ( this.decodeImage(t.src)));
8250
8277
  const image = resampleInto(src, t.rect, width, height);
8251
8278
  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 };
@@ -8272,8 +8299,8 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8272
8299
  let out = layers;
8273
8300
  const ids = /* @__PURE__ */ new Set([...Object.keys(_nullishCoalesce(thick, () => ( {}))), ...live ? [live.layerId] : []]);
8274
8301
  for (const id of ids) {
8275
- const ch = _optionalChain([live, 'optionalAccess', _444 => _444.layerId]) === id ? live.channels : _optionalChain([thick, 'optionalAccess', _445 => _445[id]]);
8276
- const l = ch && _optionalChain([_chunkDPYAO5U6cjs.findLayer.call(void 0, out, id), 'optionalAccess', _446 => _446.layer]);
8302
+ const ch = _optionalChain([live, 'optionalAccess', _447 => _447.layerId]) === id ? live.channels : _optionalChain([thick, 'optionalAccess', _448 => _448[id]]);
8303
+ const l = ch && _optionalChain([_chunkDPYAO5U6cjs.findLayer.call(void 0, out, id), 'optionalAccess', _449 => _449.layer]);
8277
8304
  if (!ch || !isPixelLayer(l)) continue;
8278
8305
  let cache = this.litCaches.get(id);
8279
8306
  if (!cache) this.litCaches.set(id, cache = new LitCache());
@@ -8293,13 +8320,13 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8293
8320
  if (!ids.size) return layers;
8294
8321
  let out = layers;
8295
8322
  for (const id of ids) {
8296
- const l = _optionalChain([_chunkDPYAO5U6cjs.findLayer.call(void 0, out, id), 'optionalAccess', _447 => _447.layer]);
8323
+ const l = _optionalChain([_chunkDPYAO5U6cjs.findLayer.call(void 0, out, id), 'optionalAccess', _450 => _450.layer]);
8297
8324
  if (!isPixelLayer(l)) continue;
8298
8325
  let cache = this.lightCaches.get(id);
8299
8326
  if (!cache) this.lightCaches.set(id, cache = new LightCache());
8300
- const glowed = cache.glow(l.surface, light[id], _optionalChain([this, 'access', _448 => _448.liveThick, 'optionalAccess', _449 => _449.layerId]) === id ? this.liveThick.channels : _optionalChain([this, 'access', _450 => _450.doc, 'access', _451 => _451.thick, 'optionalAccess', _452 => _452[id]]));
8327
+ const glowed = cache.glow(l.surface, light[id], _optionalChain([this, 'access', _451 => _451.liveThick, 'optionalAccess', _452 => _452.layerId]) === id ? this.liveThick.channels : _optionalChain([this, 'access', _453 => _453.doc, 'access', _454 => _454.thick, 'optionalAccess', _455 => _455[id]]));
8301
8328
  if (glowed !== l.surface) out = _chunkDPYAO5U6cjs.mapLayer.call(void 0, out, id, () => ({ ...l, surface: glowed }));
8302
- const committed = _optionalChain([_chunkDPYAO5U6cjs.findLayer.call(void 0, this.doc.layers, id), 'optionalAccess', _453 => _453.layer]);
8329
+ const committed = _optionalChain([_chunkDPYAO5U6cjs.findLayer.call(void 0, this.doc.layers, id), 'optionalAccess', _456 => _456.layer]);
8303
8330
  const spill = light[id] && isPixelLayer(committed) ? cache.spill(committed.surface, light[id], this.lightSpillOf(id)) : null;
8304
8331
  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 } });
8305
8332
  }
@@ -8311,7 +8338,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8311
8338
  if (!l.visible) continue;
8312
8339
  if (l.type === "group") this.backlitLayers(l.children, committed, opacity * l.opacity, out);
8313
8340
  else if (isPixelLayer(l)) {
8314
- const thick = !committed && _optionalChain([this, 'access', _454 => _454.liveThick, 'optionalAccess', _455 => _455.layerId]) === l.id ? this.liveThick.channels : _optionalChain([this, 'access', _456 => _456.doc, 'access', _457 => _457.thick, 'optionalAccess', _458 => _458[l.id]]);
8341
+ const thick = !committed && _optionalChain([this, 'access', _457 => _457.liveThick, 'optionalAccess', _458 => _458.layerId]) === l.id ? this.liveThick.channels : _optionalChain([this, 'access', _459 => _459.doc, 'access', _460 => _460.thick, 'optionalAccess', _461 => _461[l.id]]);
8315
8342
  out.push({ surface: l.surface, offset: l.offset, opacity: opacity * l.opacity, ...thick ? { thick } : {} });
8316
8343
  }
8317
8344
  }
@@ -8340,7 +8367,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8340
8367
  if (backlight) layers = [...layers, backlight];
8341
8368
  if (options.layerIds) {
8342
8369
  const picked = [];
8343
- for (const id of options.layerIds) picked.push(_nullishCoalesce(_optionalChain([_chunkDPYAO5U6cjs.findLayer.call(void 0, layers, id), 'optionalAccess', _459 => _459.layer]), () => ( this.requireLayer(id))));
8370
+ for (const id of options.layerIds) picked.push(_nullishCoalesce(_optionalChain([_chunkDPYAO5U6cjs.findLayer.call(void 0, layers, id), 'optionalAccess', _462 => _462.layer]), () => ( this.requireLayer(id))));
8344
8371
  layers = picked.map((l) => ({ ...l, visible: true }));
8345
8372
  }
8346
8373
  const under = options.paper === false ? [] : [paperNode(this.doc.paper, this.lighting)];
@@ -8356,7 +8383,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8356
8383
  */
8357
8384
  compositeTiles(rect, onTile, options = {}) {
8358
8385
  const dirty = options.dirty === "all" ? void 0 : options.dirty;
8359
- this.viewCompositor.compositeTiles(this.renderLayers({ paper: options.paper }, true), rect, this.sources(), onTile, { dirty, checkpointLayerId: _nullishCoalesce(_optionalChain([this, 'access', _460 => _460.live, 'optionalAccess', _461 => _461.layerId]), () => ( this.doc.activeLayerId)) });
8386
+ this.viewCompositor.compositeTiles(this.renderLayers({ paper: options.paper }, true), rect, this.sources(), onTile, { dirty, checkpointLayerId: _nullishCoalesce(_optionalChain([this, 'access', _463 => _463.live, 'optionalAccess', _464 => _464.layerId]), () => ( this.doc.activeLayerId)) });
8360
8387
  }
8361
8388
  /** The canvas as canvas-sized RGBA (paper included by default). */
8362
8389
  compositePixels(options = {}) {
@@ -8435,7 +8462,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8435
8462
  const spills = Object.fromEntries(Object.entries(this.lightSpills).filter(([id]) => _chunkDPYAO5U6cjs.findLayer.call(void 0, this.doc.layers, id)));
8436
8463
  if (Object.keys(spills).length) ext.lightSpill = spills;
8437
8464
  else delete ext.lightSpill;
8438
- const effectLayers = effectLayersToJSON(_nullishCoalesce(this.doc.effectLayers, () => ( {})), (id) => isPixelLayer(_optionalChain([_chunkDPYAO5U6cjs.findLayer.call(void 0, this.doc.layers, id), 'optionalAccess', _462 => _462.layer])));
8465
+ const effectLayers = effectLayersToJSON(_nullishCoalesce(this.doc.effectLayers, () => ( {})), (id) => isPixelLayer(_optionalChain([_chunkDPYAO5U6cjs.findLayer.call(void 0, this.doc.layers, id), 'optionalAccess', _465 => _465.layer])));
8439
8466
  if (effectLayers) ext.effectLayers = effectLayers;
8440
8467
  else delete ext.effectLayers;
8441
8468
  if (this.doc.paperEffect) ext.paperEffect = paperEffectToJSON(this.doc.paperEffect);
@@ -8471,7 +8498,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8471
8498
  if (ext.liveStrokes && typeof ext.liveStrokes === "object") {
8472
8499
  const liveStrokes = {};
8473
8500
  for (const [id, list] of Object.entries(ext.liveStrokes)) {
8474
- if (!isPixelLayer(_optionalChain([_chunkDPYAO5U6cjs.findLayer.call(void 0, state.layers, id), 'optionalAccess', _463 => _463.layer])) || !Array.isArray(list)) continue;
8501
+ if (!isPixelLayer(_optionalChain([_chunkDPYAO5U6cjs.findLayer.call(void 0, state.layers, id), 'optionalAccess', _466 => _466.layer])) || !Array.isArray(list)) continue;
8475
8502
  const ok = list.map(normalizeBrushStroke).filter((x) => x !== null).map((x) => ({ ...x, layerId: id }));
8476
8503
  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).`);
8477
8504
  liveStrokes[id] = ok;
@@ -8481,7 +8508,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8481
8508
  if (ext.effectLayers && typeof ext.effectLayers === "object") {
8482
8509
  const effectLayers = {};
8483
8510
  for (const [id, v] of Object.entries(ext.effectLayers)) {
8484
- if (!isPixelLayer(_optionalChain([_chunkDPYAO5U6cjs.findLayer.call(void 0, state.layers, id), 'optionalAccess', _464 => _464.layer]))) continue;
8511
+ if (!isPixelLayer(_optionalChain([_chunkDPYAO5U6cjs.findLayer.call(void 0, state.layers, id), 'optionalAccess', _467 => _467.layer]))) continue;
8485
8512
  const source = readPaintEffectSource(v);
8486
8513
  if (source) effectLayers[id] = source;
8487
8514
  else problems.push(`The effect of layer "${id}" could not be read; it loads as a plain layer.`);
@@ -8509,7 +8536,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8509
8536
  if (ext.light && typeof ext.light === "object") {
8510
8537
  const light = {};
8511
8538
  for (const [id, v] of Object.entries(ext.light)) {
8512
- if (!isPixelLayer(_optionalChain([_chunkDPYAO5U6cjs.findLayer.call(void 0, state.layers, id), 'optionalAccess', _465 => _465.layer]))) continue;
8539
+ if (!isPixelLayer(_optionalChain([_chunkDPYAO5U6cjs.findLayer.call(void 0, state.layers, id), 'optionalAccess', _468 => _468.layer]))) continue;
8513
8540
  try {
8514
8541
  light[id] = lightFromJSON(v);
8515
8542
  } catch (e) {
@@ -8545,7 +8572,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8545
8572
  this.readGuides(loaded.guides, loaded.state, loaded.problems);
8546
8573
  if (Array.isArray(loaded.swatches)) this.swatches = loaded.swatches.map(readSwatch).filter((x) => x !== null);
8547
8574
  for (const s of loaded.state.strokes) {
8548
- const n = Number(_nullishCoalesce(_optionalChain([/^s(\d+)$/, 'access', _466 => _466.exec, 'call', _467 => _467(s.id), 'optionalAccess', _468 => _468[1]]), () => ( 0)));
8575
+ const n = Number(_nullishCoalesce(_optionalChain([/^s(\d+)$/, 'access', _469 => _469.exec, 'call', _470 => _470(s.id), 'optionalAccess', _471 => _471[1]]), () => ( 0)));
8549
8576
  if (n >= this.strokeCounter) this.strokeCounter = n + 1;
8550
8577
  }
8551
8578
  this.undoStack = [];
@@ -8553,7 +8580,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8553
8580
  this.doc = this.readThick(loaded.state, loaded.extensions, loaded.problems);
8554
8581
  for (const list of Object.values(_nullishCoalesce(this.doc.liveStrokes, () => ( {})))) {
8555
8582
  for (const s of list) {
8556
- const n = Number(_nullishCoalesce(_optionalChain([/^s(\d+)$/, 'access', _469 => _469.exec, 'call', _470 => _470(s.id), 'optionalAccess', _471 => _471[1]]), () => ( 0)));
8583
+ const n = Number(_nullishCoalesce(_optionalChain([/^s(\d+)$/, 'access', _472 => _472.exec, 'call', _473 => _473(s.id), 'optionalAccess', _474 => _474[1]]), () => ( 0)));
8557
8584
  if (n >= this.strokeCounter) this.strokeCounter = n + 1;
8558
8585
  }
8559
8586
  }
@@ -8652,8 +8679,8 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8652
8679
  const layers = toStandard(dried);
8653
8680
  const result = _chunkYSGW7VV4cjs.exportPsd.call(void 0, { width, height, layers: [paperLayer, ...layers], merged, resolution: dpi });
8654
8681
  for (const [mode, names] of changed) {
8655
- const label = _nullishCoalesce(_optionalChain([_chunk2VX55NFMcjs.BLEND_MODES, 'access', _472 => _472.find, 'call', _473 => _473((m) => m.id === mode), 'optionalAccess', _474 => _474.label]), () => ( mode));
8656
- const std = _nullishCoalesce(_optionalChain([_chunk2VX55NFMcjs.BLEND_MODES, 'access', _475 => _475.find, 'call', _476 => _476((m) => m.id === _chunk2VX55NFMcjs.standardBlendMode.call(void 0, mode)), 'optionalAccess', _477 => _477.label]), () => ( _chunk2VX55NFMcjs.standardBlendMode.call(void 0, mode)));
8682
+ const label = _nullishCoalesce(_optionalChain([_chunk2VX55NFMcjs.BLEND_MODES, 'access', _475 => _475.find, 'call', _476 => _476((m) => m.id === mode), 'optionalAccess', _477 => _477.label]), () => ( mode));
8683
+ const std = _nullishCoalesce(_optionalChain([_chunk2VX55NFMcjs.BLEND_MODES, 'access', _478 => _478.find, 'call', _479 => _479((m) => m.id === _chunk2VX55NFMcjs.standardBlendMode.call(void 0, mode)), 'optionalAccess', _480 => _480.label]), () => ( _chunk2VX55NFMcjs.standardBlendMode.call(void 0, mode)));
8657
8684
  const list = names.map((n) => `"${n}"`).join(", ");
8658
8685
  const one = names.length === 1;
8659
8686
  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).`);
@@ -8775,7 +8802,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8775
8802
  const { src, pixels } = this.importImage(options, "The reference image");
8776
8803
  const ref2 = {
8777
8804
  id: `ref${this.nextReferenceId++}`,
8778
- name: _optionalChain([options, 'access', _478 => _478.name, 'optionalAccess', _479 => _479.trim, 'call', _480 => _480()]) || `Reference ${this.guides.references.length + 1}`,
8805
+ name: _optionalChain([options, 'access', _481 => _481.name, 'optionalAccess', _482 => _482.trim, 'call', _483 => _483()]) || `Reference ${this.guides.references.length + 1}`,
8779
8806
  src,
8780
8807
  width: pixels.width,
8781
8808
  height: pixels.height,
@@ -8854,7 +8881,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8854
8881
  try {
8855
8882
  const px = this.decodeImage(ref2.src, `Reference "${ref2.name}"`);
8856
8883
  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 });
8857
- const n = Number(_nullishCoalesce(_optionalChain([/^ref(\d+)$/, 'access', _481 => _481.exec, 'call', _482 => _482(ref2.id), 'optionalAccess', _483 => _483[1]]), () => ( 0)));
8884
+ const n = Number(_nullishCoalesce(_optionalChain([/^ref(\d+)$/, 'access', _484 => _484.exec, 'call', _485 => _485(ref2.id), 'optionalAccess', _486 => _486[1]]), () => ( 0)));
8858
8885
  if (n >= this.nextReferenceId) this.nextReferenceId = n + 1;
8859
8886
  } catch (e) {
8860
8887
  problems.push(e.message);
@@ -8865,7 +8892,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8865
8892
  guides.stencils = [];
8866
8893
  r.stencils.forEach((raw2, i) => {
8867
8894
  try {
8868
- const id = typeof _optionalChain([raw2, 'optionalAccess', _484 => _484.id]) === "string" && /^stencil\d+$/.test(raw2.id) ? raw2.id : `stencil${this.nextStencilId}`;
8895
+ const id = typeof _optionalChain([raw2, 'optionalAccess', _487 => _487.id]) === "string" && /^stencil\d+$/.test(raw2.id) ? raw2.id : `stencil${this.nextStencilId}`;
8869
8896
  guides.stencils.push(normalizeStencil(raw2, id));
8870
8897
  const n = Number(id.slice(7));
8871
8898
  if (n >= this.nextStencilId) this.nextStencilId = n + 1;
@@ -8888,12 +8915,12 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8888
8915
  /** The next free sticker number (ids `st<n>` are unique across the document). */
8889
8916
  nextStickerNumber(doc = this.doc) {
8890
8917
  let n = 0;
8891
- for (const list of Object.values(_nullishCoalesce(doc.stickers, () => ( {})))) for (const st of list) n = Math.max(n, Number(_nullishCoalesce(_optionalChain([/^st(\d+)$/, 'access', _485 => _485.exec, 'call', _486 => _486(st.id), 'optionalAccess', _487 => _487[1]]), () => ( 0))));
8918
+ for (const list of Object.values(_nullishCoalesce(doc.stickers, () => ( {})))) for (const st of list) n = Math.max(n, Number(_nullishCoalesce(_optionalChain([/^st(\d+)$/, 'access', _488 => _488.exec, 'call', _489 => _489(st.id), 'optionalAccess', _490 => _490[1]]), () => ( 0))));
8892
8919
  return n + 1;
8893
8920
  }
8894
8921
  stickerLayer(layerId) {
8895
8922
  const l = this.wetLayer(layerId, "edit the stickers of");
8896
- const stickers = _optionalChain([this, 'access', _488 => _488.doc, 'access', _489 => _489.stickers, 'optionalAccess', _490 => _490[l.id]]);
8923
+ const stickers = _optionalChain([this, 'access', _491 => _491.doc, 'access', _492 => _492.stickers, 'optionalAccess', _493 => _493[l.id]]);
8897
8924
  if (!stickers) throw new PaintEditorError(`Layer "${l.name}" has no stickers; spray some with a sticker brush (sticker-stars; list_brush_presets lists them).`);
8898
8925
  return { layer: l, stickers };
8899
8926
  }
@@ -8952,7 +8979,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8952
8979
  const id = _nullishCoalesce(layerId, () => ( this.doc.activeLayerId));
8953
8980
  if (!id) return [];
8954
8981
  this.requireLayer(id);
8955
- return (_nullishCoalesce(_optionalChain([this, 'access', _491 => _491.doc, 'access', _492 => _492.stickers, 'optionalAccess', _493 => _493[id]]), () => ( []))).map((s) => ({ ...s }));
8982
+ return (_nullishCoalesce(_optionalChain([this, 'access', _494 => _494.doc, 'access', _495 => _495.stickers, 'optionalAccess', _496 => _496[id]]), () => ( []))).map((s) => ({ ...s }));
8956
8983
  }
8957
8984
  /**
8958
8985
  * Replaces a layer's stickers and redraws its pixels from them (one undo step). With `dirty`,
@@ -8973,7 +9000,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8973
9000
  }
8974
9001
  /** The document from before the sticker preview on screen, or `null` when none is (anything else changed the document since). */
8975
9002
  previewBase() {
8976
- return _optionalChain([this, 'access', _494 => _494.stickerPreview, 'optionalAccess', _495 => _495.shown]) === this.doc ? this.stickerPreview.base : null;
9003
+ return _optionalChain([this, 'access', _497 => _497.stickerPreview, 'optionalAccess', _498 => _498.shown]) === this.doc ? this.stickerPreview.base : null;
8977
9004
  }
8978
9005
  readStickerUpdate(update) {
8979
9006
  try {
@@ -8988,7 +9015,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
8988
9015
  const id = _nullishCoalesce(layerId, () => ( this.doc.activeLayerId));
8989
9016
  if (!id) return null;
8990
9017
  this.requireLayer(id);
8991
- const hit = stickerAt(_nullishCoalesce(_optionalChain([this, 'access', _496 => _496.doc, 'access', _497 => _497.stickers, 'optionalAccess', _498 => _498[id]]), () => ( [])), x, y, this.stickerArt.get);
9018
+ const hit = stickerAt(_nullishCoalesce(_optionalChain([this, 'access', _499 => _499.doc, 'access', _500 => _500.stickers, 'optionalAccess', _501 => _501[id]]), () => ( [])), x, y, this.stickerArt.get);
8992
9019
  return hit ? { ...hit } : null;
8993
9020
  }
8994
9021
  /** Picks a sticker for the panel and canvas (`null` for none). Editor state, not an undo step. */
@@ -9044,8 +9071,8 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
9044
9071
  const layer = this.wetLayer(layerId, "add stickers to");
9045
9072
  if (!input.length) throw new PaintEditorError("Pass at least one sticker (ref, x, y).");
9046
9073
  if (input.length > MAX_ADD_STICKERS) throw new PaintEditorError(`At most ${MAX_ADD_STICKERS} stickers per call; split them over several calls.`);
9047
- const existing = _optionalChain([this, 'access', _499 => _499.doc, 'access', _500 => _500.stickers, 'optionalAccess', _501 => _501[layer.id]]);
9048
- if (!_optionalChain([existing, 'optionalAccess', _502 => _502.length])) {
9074
+ const existing = _optionalChain([this, 'access', _502 => _502.doc, 'access', _503 => _503.stickers, 'optionalAccess', _504 => _504[layer.id]]);
9075
+ if (!_optionalChain([existing, 'optionalAccess', _505 => _505.length])) {
9049
9076
  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.`);
9050
9077
  }
9051
9078
  let n = this.nextStickerNumber();
@@ -9062,7 +9089,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
9062
9089
  const id = n++;
9063
9090
  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 };
9064
9091
  });
9065
- this.commitStickers("Add stickers", layer, [..._nullishCoalesce(existing, () => ( [])), ...added], _optionalChain([existing, 'optionalAccess', _503 => _503.length]) ? added.map(stickerRect) : void 0);
9092
+ this.commitStickers("Add stickers", layer, [..._nullishCoalesce(existing, () => ( [])), ...added], _optionalChain([existing, 'optionalAccess', _506 => _506.length]) ? added.map(stickerRect) : void 0);
9066
9093
  return added.map((s) => ({ ...s }));
9067
9094
  }
9068
9095
  /** Brings stickers to the top (`front`) or bottom of their layer (one undo step). */
@@ -9101,20 +9128,20 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
9101
9128
  }
9102
9129
  liveStrokeLayer(layerId, what) {
9103
9130
  const l = this.wetLayer(layerId, what);
9104
- const strokes = _optionalChain([this, 'access', _504 => _504.doc, 'access', _505 => _505.liveStrokes, 'optionalAccess', _506 => _506[l.id]]);
9131
+ const strokes = _optionalChain([this, 'access', _507 => _507.doc, 'access', _508 => _508.liveStrokes, 'optionalAccess', _509 => _509[l.id]]);
9105
9132
  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.`);
9106
9133
  return { layer: l, strokes };
9107
9134
  }
9108
9135
  /** Whether a layer is a live stroke layer. */
9109
9136
  isLiveStrokeLayer(layerId) {
9110
- return Boolean(_optionalChain([this, 'access', _507 => _507.doc, 'access', _508 => _508.liveStrokes, 'optionalAccess', _509 => _509[layerId]]));
9137
+ return Boolean(_optionalChain([this, 'access', _510 => _510.doc, 'access', _511 => _511.liveStrokes, 'optionalAccess', _512 => _512[layerId]]));
9111
9138
  }
9112
9139
  /** Makes an empty pixel layer a live stroke layer (one undo step). */
9113
9140
  convertToLiveStrokes(layerId) {
9114
9141
  this.requireIdle("converting a layer");
9115
9142
  const l = this.paintTarget(layerId, "convert");
9116
- if (_optionalChain([this, 'access', _510 => _510.doc, 'access', _511 => _511.liveStrokes, 'optionalAccess', _512 => _512[l.id]])) return this.describeLayer(l);
9117
- if (_optionalChain([this, 'access', _513 => _513.doc, 'access', _514 => _514.stickers, 'optionalAccess', _515 => _515[l.id], 'optionalAccess', _516 => _516.length])) throw new PaintEditorError(`Layer "${l.name}" is a sticker layer; add a stroke layer instead (add_layer {type: "strokes"}).`);
9143
+ if (_optionalChain([this, 'access', _513 => _513.doc, 'access', _514 => _514.liveStrokes, 'optionalAccess', _515 => _515[l.id]])) return this.describeLayer(l);
9144
+ if (_optionalChain([this, 'access', _516 => _516.doc, 'access', _517 => _517.stickers, 'optionalAccess', _518 => _518[l.id], 'optionalAccess', _519 => _519.length])) throw new PaintEditorError(`Layer "${l.name}" is a sticker layer; add a stroke layer instead (add_layer {type: "strokes"}).`);
9118
9145
  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"}).`);
9119
9146
  this.commit("Convert to stroke layer", { ...this.doc, liveStrokes: { ..._nullishCoalesce(this.doc.liveStrokes, () => ( {})), [l.id]: [] } });
9120
9147
  return this.describeLayer(this.getLayer(l.id));
@@ -9127,7 +9154,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
9127
9154
  findLiveStroke(id) {
9128
9155
  for (const [layerId, strokes] of Object.entries(_nullishCoalesce(this.doc.liveStrokes, () => ( {})))) {
9129
9156
  const index = strokes.findIndex((x) => x.id === id);
9130
- const layer = _optionalChain([_chunkDPYAO5U6cjs.findLayer.call(void 0, this.doc.layers, layerId), 'optionalAccess', _517 => _517.layer]);
9157
+ const layer = _optionalChain([_chunkDPYAO5U6cjs.findLayer.call(void 0, this.doc.layers, layerId), 'optionalAccess', _520 => _520.layer]);
9131
9158
  if (index >= 0 && isPixelLayer(layer)) return { layer, strokes, index };
9132
9159
  }
9133
9160
  const baked = this.doc.strokes.some((x) => x.id === id);
@@ -9222,9 +9249,9 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
9222
9249
  const layers = /* @__PURE__ */ new Map();
9223
9250
  for (const f of found) layers.set(f.layer.id, f.layer);
9224
9251
  for (const [layerId, layer] of layers) {
9225
- const gone = (_nullishCoalesce(_optionalChain([doc, 'access', _518 => _518.liveStrokes, 'optionalAccess', _519 => _519[layerId]]), () => ( []))).filter((x) => ids.includes(x.id));
9252
+ const gone = (_nullishCoalesce(_optionalChain([doc, 'access', _521 => _521.liveStrokes, 'optionalAccess', _522 => _522[layerId]]), () => ( []))).filter((x) => ids.includes(x.id));
9226
9253
  for (const x of gone) bounds = unionRect(bounds, this.strokeArea(x));
9227
- doc = this.withLiveStrokes(doc, layer, (_nullishCoalesce(_optionalChain([doc, 'access', _520 => _520.liveStrokes, 'optionalAccess', _521 => _521[layerId]]), () => ( []))).filter((x) => !ids.includes(x.id)), this.strokeAreas(gone));
9254
+ doc = this.withLiveStrokes(doc, layer, (_nullishCoalesce(_optionalChain([doc, 'access', _523 => _523.liveStrokes, 'optionalAccess', _524 => _524[layerId]]), () => ( []))).filter((x) => !ids.includes(x.id)), this.strokeAreas(gone));
9228
9255
  }
9229
9256
  this.commit(ids.length === 1 ? "Remove stroke" : "Remove strokes", doc);
9230
9257
  return { removed: [...ids], bounds };
@@ -9292,7 +9319,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
9292
9319
  }
9293
9320
  withLiveStrokes(doc, layer, list, dirty) {
9294
9321
  if (_chunkDPYAO5U6cjs.isLayerLocked.call(void 0, layer, "pixels")) throw new PaintEditorError(`Layer "${layer.name}" has its pixels locked; unlock it (update_layer locks) first.`);
9295
- const current = _optionalChain([_chunkDPYAO5U6cjs.findLayer.call(void 0, doc.layers, layer.id), 'optionalAccess', _522 => _522.layer]);
9322
+ const current = _optionalChain([_chunkDPYAO5U6cjs.findLayer.call(void 0, doc.layers, layer.id), 'optionalAccess', _525 => _525.layer]);
9296
9323
  const surface = this.drawLiveStrokes(_nullishCoalesce(current, () => ( layer)), list, dirty);
9297
9324
  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] } };
9298
9325
  return this.withPaintEvent(next, { kind: "live-strokes", layerId: layer.id, data: { strokes: list.map((x) => JSON.parse(JSON.stringify(x))) } });
@@ -9370,7 +9397,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
9370
9397
  if (!this.animatedLayers.size) return this.doc.layers;
9371
9398
  let layers = this.doc.layers;
9372
9399
  for (const [id, a] of this.animatedLayers) {
9373
- const l = _optionalChain([_chunkDPYAO5U6cjs.findLayer.call(void 0, layers, id), 'optionalAccess', _523 => _523.layer]);
9400
+ const l = _optionalChain([_chunkDPYAO5U6cjs.findLayer.call(void 0, layers, id), 'optionalAccess', _526 => _526.layer]);
9374
9401
  if (isPixelLayer(l) && l.surface === a.base) layers = _chunkDPYAO5U6cjs.mapLayer.call(void 0, layers, id, () => ({ ...l, surface: a.surface }));
9375
9402
  }
9376
9403
  return layers;
@@ -9380,7 +9407,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
9380
9407
  const layers = [];
9381
9408
  const sources = /* @__PURE__ */ new Map();
9382
9409
  for (const [id, strokes] of Object.entries(_nullishCoalesce(doc.liveStrokes, () => ( {})))) {
9383
- const layer = _optionalChain([_chunkDPYAO5U6cjs.findLayer.call(void 0, doc.layers, id), 'optionalAccess', _524 => _524.layer]);
9410
+ const layer = _optionalChain([_chunkDPYAO5U6cjs.findLayer.call(void 0, doc.layers, id), 'optionalAccess', _527 => _527.layer]);
9384
9411
  const live = strokes.filter(isLiveEffect);
9385
9412
  if (!isPixelLayer(layer) || !live.length) continue;
9386
9413
  layers.push({ layer, strokes });
@@ -9505,13 +9532,13 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
9505
9532
  return this.withEffectTime(time, () => this.compositePixels(options));
9506
9533
  }
9507
9534
  // --- Stencils --------------------------------------------------------------------
9508
- __init180() {this.stencilCache = null}
9509
- __init181() {this.nextStencilId = 1}
9535
+ __init181() {this.stencilCache = null}
9536
+ __init182() {this.nextStencilId = 1}
9510
9537
  /** The mask stencils' coverage over the canvas (cached), or `null` when none masks. */
9511
9538
  stencilSelection(stencils = this.guides.stencils) {
9512
9539
  const { width, height } = this.doc.canvas;
9513
9540
  const size = `${width}x${height}`;
9514
- if (_optionalChain([this, 'access', _525 => _525.stencilCache, 'optionalAccess', _526 => _526.key]) === stencils && this.stencilCache.size === size) return this.stencilCache.mask;
9541
+ if (_optionalChain([this, 'access', _528 => _528.stencilCache, 'optionalAccess', _529 => _529.key]) === stencils && this.stencilCache.size === size) return this.stencilCache.mask;
9515
9542
  const mask = stencilMask(stencils, width, height);
9516
9543
  this.stencilCache = { key: stencils, size, mask };
9517
9544
  return mask;
@@ -9573,7 +9600,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
9573
9600
  makeSwatch(color, name) {
9574
9601
  const p = typeof color === "string" ? { type: "color", color: parseColor(color) } : this.readStrokePaint(color);
9575
9602
  const out = { color: _chunkFQPUF2W2cjs.paintSourceColor.call(void 0, p, { paint: this.color, secondary: this.secondaryColor }) };
9576
- if (_optionalChain([name, 'optionalAccess', _527 => _527.trim, 'call', _528 => _528()])) out.name = name.trim();
9603
+ if (_optionalChain([name, 'optionalAccess', _530 => _530.trim, 'call', _531 => _531()])) out.name = name.trim();
9577
9604
  if (p.type === "gradient") out.paint = p;
9578
9605
  return out;
9579
9606
  }
@@ -9625,7 +9652,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
9625
9652
  * mix becomes the paint colour. Returns the mixed colour and the pile's bounds.
9626
9653
  */
9627
9654
  mixOnPad(paints2, options = {}) {
9628
- const parsed = (_nullishCoalesce(paints2, () => ( []))).map((p, i) => ({ color: parseColor(_optionalChain([p, 'optionalAccess', _529 => _529.color]), `paints[${i}].color`), parts: _optionalChain([p, 'optionalAccess', _530 => _530.parts]) }));
9655
+ const parsed = (_nullishCoalesce(paints2, () => ( []))).map((p, i) => ({ color: parseColor(_optionalChain([p, 'optionalAccess', _532 => _532.color]), `paints[${i}].color`), parts: _optionalChain([p, 'optionalAccess', _533 => _533.parts]) }));
9629
9656
  let r;
9630
9657
  try {
9631
9658
  r = this.pad.mix(parsed, options);
@@ -9714,7 +9741,7 @@ var PaintEditorController = (_class19 = class _PaintEditorController {
9714
9741
  }
9715
9742
  /** A layer's tile surface (live while stroking), for thumbnails. */
9716
9743
  layerSurface(id) {
9717
- const l = _optionalChain([_chunkDPYAO5U6cjs.findLayer.call(void 0, this.currentLayers(), id), 'optionalAccess', _531 => _531.layer]);
9744
+ const l = _optionalChain([_chunkDPYAO5U6cjs.findLayer.call(void 0, this.currentLayers(), id), 'optionalAccess', _534 => _534.layer]);
9718
9745
  return isPixelLayer(l) ? l.surface : null;
9719
9746
  }
9720
9747
  }, _class19.__initStatic(), _class19);
@@ -9736,7 +9763,7 @@ function insertAfter(layers, id, node) {
9736
9763
  return layers.map((l) => l.type === "group" ? { ...l, children: insertAfter(l.children, id, node) } : l);
9737
9764
  }
9738
9765
  function isLiveEffect(s) {
9739
- return _optionalChain([s, 'access', _532 => _532.paint, 'optionalAccess', _533 => _533.type]) === "effect" && s.paint.live === true;
9766
+ return _optionalChain([s, 'access', _535 => _535.paint, 'optionalAccess', _536 => _536.type]) === "effect" && s.paint.live === true;
9740
9767
  }
9741
9768
  function framePaint(p, t) {
9742
9769
  return { ...p, time: p.time + t };
@@ -9761,7 +9788,7 @@ function clipRect(r, width, height) {
9761
9788
  return x1 > x0 && y1 > y0 ? { x: x0, y: y0, width: x1 - x0, height: y1 - y0 } : null;
9762
9789
  }
9763
9790
  function withLiveStroke(doc, stroke) {
9764
- const list = _optionalChain([doc, 'access', _534 => _534.liveStrokes, 'optionalAccess', _535 => _535[stroke.layerId]]);
9791
+ const list = _optionalChain([doc, 'access', _537 => _537.liveStrokes, 'optionalAccess', _538 => _538[stroke.layerId]]);
9765
9792
  return list ? { ...doc, liveStrokes: { ...doc.liveStrokes, [stroke.layerId]: [...list, stroke] } } : doc;
9766
9793
  }
9767
9794
  function shiftDocument(doc, dx, dy) {
@@ -9788,9 +9815,9 @@ function shiftDocument(doc, dx, dy) {
9788
9815
  if (doc.liveStrokes) out.liveStrokes = Object.fromEntries(Object.entries(doc.liveStrokes).map(([id, list]) => [id, list.map(moveStroke)]));
9789
9816
  if (doc.paintEvents) {
9790
9817
  out.paintEvents = doc.paintEvents.map((e) => {
9791
- const list = e.kind === "stickers" ? _optionalChain([e, 'access', _536 => _536.data, 'optionalAccess', _537 => _537.stickers]) : void 0;
9818
+ const list = e.kind === "stickers" ? _optionalChain([e, 'access', _539 => _539.data, 'optionalAccess', _540 => _540.stickers]) : void 0;
9792
9819
  if (list) return { ...e, data: { ...e.data, stickers: moveStickers(list) } };
9793
- const strokes = e.kind === "live-strokes" ? _optionalChain([e, 'access', _538 => _538.data, 'optionalAccess', _539 => _539.strokes]) : void 0;
9820
+ const strokes = e.kind === "live-strokes" ? _optionalChain([e, 'access', _541 => _541.data, 'optionalAccess', _542 => _542.strokes]) : void 0;
9794
9821
  return strokes ? { ...e, data: { ...e.data, strokes: strokes.map(moveStroke) } } : e;
9795
9822
  });
9796
9823
  }
@@ -9879,8 +9906,8 @@ function strokeSchedule(points) {
9879
9906
  return total > 0 ? acc.map((d) => d / total) : points.map(() => 1);
9880
9907
  }
9881
9908
  function strokeDuration(points, max = 1800) {
9882
- const t0 = _optionalChain([points, 'access', _540 => _540[0], 'optionalAccess', _541 => _541.t]);
9883
- const t1 = _optionalChain([points, 'access', _542 => _542[points.length - 1], 'optionalAccess', _543 => _543.t]);
9909
+ const t0 = _optionalChain([points, 'access', _543 => _543[0], 'optionalAccess', _544 => _544.t]);
9910
+ const t1 = _optionalChain([points, 'access', _545 => _545[points.length - 1], 'optionalAccess', _546 => _546.t]);
9884
9911
  let ms;
9885
9912
  if (points.every((p) => Number.isFinite(p.t)) && t1 > t0) ms = t1 - t0;
9886
9913
  else {
@@ -9934,7 +9961,7 @@ var PaintDirector = class {
9934
9961
  }
9935
9962
  where(id) {
9936
9963
  const a = this.presence.get(id);
9937
- return { x: _nullishCoalesce(_optionalChain([a, 'optionalAccess', _544 => _544.x]), () => ( 0)), y: _nullishCoalesce(_optionalChain([a, 'optionalAccess', _545 => _545.y]), () => ( 0)) };
9964
+ return { x: _nullishCoalesce(_optionalChain([a, 'optionalAccess', _547 => _547.x]), () => ( 0)), y: _nullishCoalesce(_optionalChain([a, 'optionalAccess', _548 => _548.y]), () => ( 0)) };
9938
9965
  }
9939
9966
  /** Glides to `to`; an actor that just appeared starts there instead of the corner. */
9940
9967
  async glide(id, to, ms = 380) {
@@ -9981,8 +10008,8 @@ var PaintDirector = class {
9981
10008
  }
9982
10009
  case "replay": {
9983
10010
  await this.say(id, command.note, 500);
9984
- const source = c.getStrokes().filter((s) => _optionalChain([command, 'access', _546 => _546.replay, 'access', _547 => _547.strokeIds, 'optionalAccess', _548 => _548.includes, 'call', _549 => _549(s.id)]));
9985
- const first = _optionalChain([source, 'access', _550 => _550[0], 'optionalAccess', _551 => _551.points, 'access', _552 => _552[0]]);
10011
+ const source = c.getStrokes().filter((s) => _optionalChain([command, 'access', _549 => _549.replay, 'access', _550 => _550.strokeIds, 'optionalAccess', _551 => _551.includes, 'call', _552 => _552(s.id)]));
10012
+ const first = _optionalChain([source, 'access', _553 => _553[0], 'optionalAccess', _554 => _554.points, 'access', _555 => _555[0]]);
9986
10013
  if (first) await this.glide(id, first);
9987
10014
  const result = c.replayStrokes(command.replay);
9988
10015
  if (result.bounds) await this.glide(id, centre(result.bounds), 520);
@@ -11419,7 +11446,7 @@ function createPaintEditorToolProvider(controller, options = {}) {
11419
11446
  inputSchema: { type: "object", properties: { id: { type: "string", description: "Brush id from list_brush_presets to start from (default the active brush)." }, name: { type: "string", minLength: 1, maxLength: 80, description: "Display name." }, ..._chunkMQGQTKVWcjs.BRUSH_PATCH_PROPERTIES, unset: _chunkMQGQTKVWcjs.BRUSH_UNSET_PROPERTY }, additionalProperties: false },
11420
11447
  annotations: { title: "Set the brush", ...SET4 },
11421
11448
  handler: async ({ id, unset, ...patch }) => {
11422
- const stamps = _optionalChain([patch, 'access', _553 => _553.tip, 'optionalAccess', _554 => _554.stamps]);
11449
+ const stamps = _optionalChain([patch, 'access', _556 => _556.tip, 'optionalAccess', _557 => _557.stamps]);
11423
11450
  if (stamps) await c.prepareStickers(stamps);
11424
11451
  const r = c.setBrushFacets(patch, id, unset);
11425
11452
  return { brush: r.spec, engine: r.brush.engine, problems: r.problems };
@@ -11536,6 +11563,23 @@ function createPaintEditorToolProvider(controller, options = {}) {
11536
11563
  return r.mixerLoad ? { ...r, mixerLoad: loadResult(r.mixerLoad) } : r;
11537
11564
  }
11538
11565
  });
11566
+ add({
11567
+ name: "get_live_stroke",
11568
+ title: "Get the stroke being painted",
11569
+ description: "Reads the stroke the user is painting right now, if any: its layer, brush id and name, colour, and the pen samples so far (document pixels; at most the last `limit`). Returns live: false when no stroke is in progress. For agents that paint along with the user: hosts stream the same samples to them live (onStrokeSample); this is a snapshot.",
11570
+ inputSchema: {
11571
+ type: "object",
11572
+ properties: { limit: { type: "integer", minimum: 1, maximum: 5e3, description: "Most recent samples to return (default 500)." } },
11573
+ additionalProperties: false
11574
+ },
11575
+ annotations: { title: "Get the stroke being painted", ...READ6 },
11576
+ handler: (args) => {
11577
+ const live = c.getLiveStroke();
11578
+ if (!live) return { live: false };
11579
+ const limit = _nullishCoalesce(args.limit, () => ( 500));
11580
+ return { live: true, layerId: live.layerId, brushId: live.brushId, brushName: live.brushName, color: live.color, total: live.points.length, points: live.points.slice(-limit) };
11581
+ }
11582
+ });
11539
11583
  add({
11540
11584
  name: "list_strokes",
11541
11585
  title: "List recorded strokes",
@@ -11562,7 +11606,7 @@ function createPaintEditorToolProvider(controller, options = {}) {
11562
11606
  if (ids) {
11563
11607
  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.`);
11564
11608
  }
11565
- return { total: all.length, strokes: picked.map((s) => strokeSummary(s, Boolean(ids), live ? true : liveIds.has(s.id) && _optionalChain([c, 'access', _555 => _555.document, 'access', _556 => _556.liveStrokes, 'optionalAccess', _557 => _557[s.layerId], 'optionalAccess', _558 => _558.includes, 'call', _559 => _559(s)]) === true)) };
11609
+ return { total: all.length, strokes: picked.map((s) => strokeSummary(s, Boolean(ids), live ? true : liveIds.has(s.id) && _optionalChain([c, 'access', _558 => _558.document, 'access', _559 => _559.liveStrokes, 'optionalAccess', _560 => _560[s.layerId], 'optionalAccess', _561 => _561.includes, 'call', _562 => _562(s)]) === true)) };
11566
11610
  }
11567
11611
  });
11568
11612
  add({
@@ -11871,16 +11915,16 @@ function createPaintEditorToolProvider(controller, options = {}) {
11871
11915
  }
11872
11916
  function hostTool({ coordinates, ...tool }, { origin, onChange }) {
11873
11917
  if (!origin && !onChange) return tool;
11874
- const write = !_optionalChain([tool, 'access', _560 => _560.annotations, 'optionalAccess', _561 => _561.readOnlyHint]);
11918
+ const write = !_optionalChain([tool, 'access', _563 => _563.annotations, 'optionalAccess', _564 => _564.readOnlyHint]);
11875
11919
  const done = (result) => {
11876
- if (write) _optionalChain([onChange, 'optionalCall', _562 => _562({ tool: tool.name })]);
11877
- return origin && _optionalChain([coordinates, 'optionalAccess', _563 => _563.out]) ? fromDocument(result, coordinates.out, origin) : result;
11920
+ if (write) _optionalChain([onChange, 'optionalCall', _565 => _565({ tool: tool.name })]);
11921
+ return origin && _optionalChain([coordinates, 'optionalAccess', _566 => _566.out]) ? fromDocument(result, coordinates.out, origin) : result;
11878
11922
  };
11879
11923
  return {
11880
11924
  ...tool,
11881
11925
  ...origin ? { description: hostedText(_nullishCoalesce(tool.description, () => ( ""))), inputSchema: hostedSchema(tool.inputSchema) } : {},
11882
11926
  handler: (args, context) => {
11883
- const r = tool.handler(origin && _optionalChain([coordinates, 'optionalAccess', _564 => _564.in]) ? toDocument(args, coordinates.in, origin) : args, context);
11927
+ const r = tool.handler(origin && _optionalChain([coordinates, 'optionalAccess', _567 => _567.in]) ? toDocument(args, coordinates.in, origin) : args, context);
11884
11928
  return r instanceof Promise ? r.then(done) : done(r);
11885
11929
  }
11886
11930
  };
@@ -11897,7 +11941,7 @@ function strokeSummary(s, withPoints, live) {
11897
11941
  color: s.color,
11898
11942
  points: withPoints ? s.points : s.points.length,
11899
11943
  seed: s.seed,
11900
- copies: _nullishCoalesce(_optionalChain([s, 'access', _565 => _565.copies, 'optionalAccess', _566 => _566.length]), () => ( 0)),
11944
+ copies: _nullishCoalesce(_optionalChain([s, 'access', _568 => _568.copies, 'optionalAccess', _569 => _569.length]), () => ( 0)),
11901
11945
  live,
11902
11946
  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) }
11903
11947
  };
@@ -11926,20 +11970,20 @@ var PAINT_TOOLS = [
11926
11970
  { id: "rotate", label: "Rotate view", key: "r" }
11927
11971
  ];
11928
11972
  var PaintGesture = (_class20 = class {
11929
- constructor(controller, box) {;_class20.prototype.__init182.call(this);_class20.prototype.__init183.call(this);_class20.prototype.__init184.call(this);_class20.prototype.__init185.call(this);_class20.prototype.__init186.call(this);_class20.prototype.__init187.call(this);
11973
+ constructor(controller, box) {;_class20.prototype.__init183.call(this);_class20.prototype.__init184.call(this);_class20.prototype.__init185.call(this);_class20.prototype.__init186.call(this);_class20.prototype.__init187.call(this);_class20.prototype.__init188.call(this);
11930
11974
  this.controller = controller;
11931
11975
  this.box = box;
11932
11976
  }
11933
11977
 
11934
11978
 
11935
- __init182() {this.tool = "brush"}
11979
+ __init183() {this.tool = "brush"}
11936
11980
  /** The last refusal (a hidden or locked layer), for the editor to show. */
11937
- __init183() {this.error = null}
11981
+ __init184() {this.error = null}
11938
11982
  /** The predicted tail of the current stroke in document pixels (draw it as a thin preview). */
11939
- __init184() {this.predicted = []}
11940
- __init185() {this.mode = null}
11941
- __init186() {this.penAt = null}
11942
- __init187() {this.penDown = false}
11983
+ __init185() {this.predicted = []}
11984
+ __init186() {this.mode = null}
11985
+ __init187() {this.penAt = null}
11986
+ __init188() {this.penDown = false}
11943
11987
  doc(e) {
11944
11988
  const b = this.box();
11945
11989
  const s = this.controller.getState();
@@ -11995,13 +12039,13 @@ var PaintGesture = (_class20 = class {
11995
12039
  const p = this.doc(e);
11996
12040
  const s = this.controller.getState();
11997
12041
  const layerId = s.document.activeLayerId;
11998
- if (!layerId || !_optionalChain([s, 'access', _567 => _567.document, 'access', _568 => _568.liveStrokes, 'optionalAccess', _569 => _569[layerId]])) {
12042
+ if (!layerId || !_optionalChain([s, 'access', _570 => _570.document, 'access', _571 => _571.liveStrokes, 'optionalAccess', _572 => _572[layerId]])) {
11999
12043
  this.error = "Pick a stroke layer in the Layers panel (or add one) to select its strokes.";
12000
12044
  return false;
12001
12045
  }
12002
12046
  try {
12003
12047
  const hit = this.controller.liveStrokeAt(layerId, p.x, p.y);
12004
- this.controller.selectStroke(_nullishCoalesce(_optionalChain([hit, 'optionalAccess', _570 => _570.id]), () => ( null)));
12048
+ this.controller.selectStroke(_nullishCoalesce(_optionalChain([hit, 'optionalAccess', _573 => _573.id]), () => ( null)));
12005
12049
  if (!hit) return false;
12006
12050
  this.mode = { kind: "move-stroke", pointerId: e.pointerId, id: hit.id, from: p, to: p };
12007
12051
  return true;
@@ -12013,7 +12057,7 @@ var PaintGesture = (_class20 = class {
12013
12057
  /** While a stroke is dragged: how far it has moved (document pixels), to draw its outline there. */
12014
12058
  get strokeDrag() {
12015
12059
  const m = this.mode;
12016
- return _optionalChain([m, 'optionalAccess', _571 => _571.kind]) === "move-stroke" ? { id: m.id, dx: m.to.x - m.from.x, dy: m.to.y - m.from.y } : null;
12060
+ return _optionalChain([m, 'optionalAccess', _574 => _574.kind]) === "move-stroke" ? { id: m.id, dx: m.to.x - m.from.x, dy: m.to.y - m.from.y } : null;
12017
12061
  }
12018
12062
  /**
12019
12063
  * The Stickers tool: pressing a sticker picks it and dragging moves it (one undo step at the
@@ -12087,7 +12131,7 @@ var PaintGesture = (_class20 = class {
12087
12131
  if (!m || m.pointerId !== e.pointerId) return;
12088
12132
  this.mode = null;
12089
12133
  this.predicted = [];
12090
- if (m.kind === "stroke") _optionalChain([this, 'access', _572 => _572.controller, 'access', _573 => _573.activeStroke, 'optionalAccess', _574 => _574.end, 'call', _575 => _575()]);
12134
+ if (m.kind === "stroke") _optionalChain([this, 'access', _575 => _575.controller, 'access', _576 => _576.activeStroke, 'optionalAccess', _577 => _577.end, 'call', _578 => _578()]);
12091
12135
  if (m.kind === "move-stroke") {
12092
12136
  const dx = Math.round((this.doc(e).x - m.from.x) * 100) / 100;
12093
12137
  const dy = Math.round((this.doc(e).y - m.from.y) * 100) / 100;
@@ -12111,8 +12155,8 @@ var PaintGesture = (_class20 = class {
12111
12155
  cancel() {
12112
12156
  this.penDown = false;
12113
12157
  this.predicted = [];
12114
- if (_optionalChain([this, 'access', _576 => _576.mode, 'optionalAccess', _577 => _577.kind]) === "stroke") _optionalChain([this, 'access', _578 => _578.controller, 'access', _579 => _579.activeStroke, 'optionalAccess', _580 => _580.cancel, 'call', _581 => _581()]);
12115
- if (_optionalChain([this, 'access', _582 => _582.mode, 'optionalAccess', _583 => _583.kind]) === "sticker") this.controller.cancelStickerPreview();
12158
+ if (_optionalChain([this, 'access', _579 => _579.mode, 'optionalAccess', _580 => _580.kind]) === "stroke") _optionalChain([this, 'access', _581 => _581.controller, 'access', _582 => _582.activeStroke, 'optionalAccess', _583 => _583.cancel, 'call', _584 => _584()]);
12159
+ if (_optionalChain([this, 'access', _585 => _585.mode, 'optionalAccess', _586 => _586.kind]) === "sticker") this.controller.cancelStickerPreview();
12116
12160
  this.mode = null;
12117
12161
  }
12118
12162
  get active() {
@@ -12174,13 +12218,13 @@ function handlePaintShortcut(controller, gesture, e) {
12174
12218
  return false;
12175
12219
  }
12176
12220
  var PaintCanvasPresenter = (_class21 = class {
12177
- constructor(controller) {;_class21.prototype.__init188.call(this);_class21.prototype.__init189.call(this);_class21.prototype.__init190.call(this);
12221
+ constructor(controller) {;_class21.prototype.__init189.call(this);_class21.prototype.__init190.call(this);_class21.prototype.__init191.call(this);
12178
12222
  this.controller = controller;
12179
12223
  }
12180
12224
 
12181
- __init188() {this.uploaded = /* @__PURE__ */ new Map()}
12182
- __init189() {this.scratch = null}
12183
- __init190() {this.size = ""}
12225
+ __init189() {this.uploaded = /* @__PURE__ */ new Map()}
12226
+ __init190() {this.scratch = null}
12227
+ __init191() {this.size = ""}
12184
12228
  /** Draws what changed into `ctx` (a canvas the size of the document); returns the tiles drawn. */
12185
12229
  render(ctx) {
12186
12230
  const { width, height } = this.controller.document.canvas;
@@ -12212,7 +12256,7 @@ function guideOverlay(controller, drag) {
12212
12256
  const size = s.document.canvas;
12213
12257
  const out = [];
12214
12258
  const layerId = s.document.activeLayerId;
12215
- const strokePicked = layerId && s.selectedStroke ? _optionalChain([s, 'access', _584 => _584.document, 'access', _585 => _585.liveStrokes, 'optionalAccess', _586 => _586[layerId], 'optionalAccess', _587 => _587.some, 'call', _588 => _588((x) => x.id === s.selectedStroke)]) : false;
12259
+ const strokePicked = layerId && s.selectedStroke ? _optionalChain([s, 'access', _587 => _587.document, 'access', _588 => _588.liveStrokes, 'optionalAccess', _589 => _589[layerId], 'optionalAccess', _590 => _590.some, 'call', _591 => _591((x) => x.id === s.selectedStroke)]) : false;
12216
12260
  const area = strokePicked ? controller.liveStrokeArea(s.selectedStroke) : null;
12217
12261
  if (area) {
12218
12262
  const dx = drag && drag.id === s.selectedStroke ? drag.dx : 0;
@@ -12225,7 +12269,7 @@ function guideOverlay(controller, drag) {
12225
12269
  ];
12226
12270
  for (let i = 0; i < 4; i++) out.push({ from: box[i], to: box[(i + 1) % 4], kind: "stroke" });
12227
12271
  }
12228
- const picked = layerId && s.selectedSticker ? _optionalChain([s, 'access', _589 => _589.document, 'access', _590 => _590.stickers, 'optionalAccess', _591 => _591[layerId], 'optionalAccess', _592 => _592.find, 'call', _593 => _593((x) => x.id === s.selectedSticker)]) : void 0;
12272
+ const picked = layerId && s.selectedSticker ? _optionalChain([s, 'access', _592 => _592.document, 'access', _593 => _593.stickers, 'optionalAccess', _594 => _594[layerId], 'optionalAccess', _595 => _595.find, 'call', _596 => _596((x) => x.id === s.selectedSticker)]) : void 0;
12229
12273
  if (picked) {
12230
12274
  const r = picked.size / 2 + 2;
12231
12275
  const a = picked.rotation * Math.PI / 180;
@@ -12255,7 +12299,7 @@ var PAPER_SLIDERS = [
12255
12299
  ];
12256
12300
  function readPath(obj, path) {
12257
12301
  let v = obj;
12258
- for (const k of path.split(".")) v = _optionalChain([v, 'optionalAccess', _594 => _594[k]]);
12302
+ for (const k of path.split(".")) v = _optionalChain([v, 'optionalAccess', _597 => _597[k]]);
12259
12303
  return typeof v === "number" ? v : 0;
12260
12304
  }
12261
12305
  function patchPath(obj, path, value) {
@@ -12371,7 +12415,7 @@ function startWetClock(controller, frame, cancel) {
12371
12415
  id = raf(loop);
12372
12416
  return () => {
12373
12417
  stopped = true;
12374
- _optionalChain([caf, 'optionalCall', _595 => _595(id)]);
12418
+ _optionalChain([caf, 'optionalCall', _598 => _598(id)]);
12375
12419
  };
12376
12420
  }
12377
12421
  function drawWaterOverlay(controller, ctx) {
@@ -12723,7 +12767,7 @@ function createPaintChangeFeed(controller, options = {}) {
12723
12767
  const doc = state.document;
12724
12768
  const layers = /* @__PURE__ */ new Map();
12725
12769
  for (const l of controller.listLayers()) layers.set(l.id, { name: l.name, visible: l.visible, opacity: l.opacity, blend: l.blend });
12726
- return { doc, strokes: new Map(doc.strokes.map((s) => [s.id, s])), events: _nullishCoalesce(_optionalChain([doc, 'access', _596 => _596.paintEvents, 'optionalAccess', _597 => _597.length]), () => ( 0)), layers, stroking: state.stroking };
12770
+ return { doc, strokes: new Map(doc.strokes.map((s) => [s.id, s])), events: _nullishCoalesce(_optionalChain([doc, 'access', _599 => _599.paintEvents, 'optionalAccess', _600 => _600.length]), () => ( 0)), layers, stroking: state.stroking };
12727
12771
  };
12728
12772
  let last = take();
12729
12773
  const check = () => {
@@ -12754,7 +12798,7 @@ function createPaintChangeFeed(controller, options = {}) {
12754
12798
  if (edited) pending = void 0;
12755
12799
  const change = {
12756
12800
  seq: ++seq,
12757
- origin: _nullishCoalesce(_optionalChain([commit, 'optionalAccess', _598 => _598.origin]), () => ( "user")),
12801
+ origin: _nullishCoalesce(_optionalChain([commit, 'optionalAccess', _601 => _601.origin]), () => ( "user")),
12758
12802
  ...commit ? { commit } : {},
12759
12803
  addedStrokes,
12760
12804
  removedStrokes,
@@ -12821,7 +12865,7 @@ function createPaintProposals(options) {
12821
12865
  };
12822
12866
  const strokeIds = () => new Set(controller.getStrokes().map((s) => s.id));
12823
12867
  const validate = (input) => {
12824
- if (!_optionalChain([input, 'access', _599 => _599.title, 'optionalAccess', _600 => _600.trim, 'call', _601 => _601()])) throw new PaintEditorError("A proposal needs a title: what it adds, in a few words.");
12868
+ if (!_optionalChain([input, 'access', _602 => _602.title, 'optionalAccess', _603 => _603.trim, 'call', _604 => _604()])) throw new PaintEditorError("A proposal needs a title: what it adds, in a few words.");
12825
12869
  if (!Array.isArray(input.ops) || !input.ops.length) throw new PaintEditorError("A proposal needs at least one op (stroke, wash or echo).");
12826
12870
  const place = _nullishCoalesce(input.place, () => ( "top"));
12827
12871
  if (place === "above") {
@@ -12833,7 +12877,7 @@ function createPaintProposals(options) {
12833
12877
  input.ops.forEach((op, i) => {
12834
12878
  const at = `ops[${i}]`;
12835
12879
  if (op.kind === "stroke") {
12836
- if (!_optionalChain([op, 'access', _602 => _602.points, 'optionalAccess', _603 => _603.length])) throw new PaintEditorError(`${at}: a stroke needs points in document pixels.`);
12880
+ if (!_optionalChain([op, 'access', _605 => _605.points, 'optionalAccess', _606 => _606.length])) throw new PaintEditorError(`${at}: a stroke needs points in document pixels.`);
12837
12881
  points += op.points.length;
12838
12882
  if (op.color !== void 0 && !HEX4.test(op.color)) throw new PaintEditorError(`${at}: color "${op.color}" is not #rrggbb.`);
12839
12883
  const brush = op.brushId ? controller.getBrush(op.brushId) : controller.getState().brush;
@@ -12845,7 +12889,7 @@ function createPaintProposals(options) {
12845
12889
  if (!HEX4.test(_nullishCoalesce(op.color, () => ( "")))) throw new PaintEditorError(`${at}: a wash needs color as #rrggbb.`);
12846
12890
  if (op.opacity !== void 0 && !(op.opacity > 0 && op.opacity <= 1)) throw new PaintEditorError(`${at}: opacity must be in (0, 1].`);
12847
12891
  } else if (op.kind === "echo") {
12848
- if (!_optionalChain([op, 'access', _604 => _604.strokeIds, 'optionalAccess', _605 => _605.length])) throw new PaintEditorError(`${at}: an echo needs strokeIds (list_strokes).`);
12892
+ if (!_optionalChain([op, 'access', _607 => _607.strokeIds, 'optionalAccess', _608 => _608.length])) throw new PaintEditorError(`${at}: an echo needs strokeIds (list_strokes).`);
12849
12893
  const unknown = op.strokeIds.filter((id) => !known.has(id));
12850
12894
  if (unknown.length) throw new PaintEditorError(`${at}: unknown stroke ${unknown.map((u) => `"${u}"`).join(", ")}. Call list_strokes for the ids.`);
12851
12895
  if (op.color !== void 0 && !HEX4.test(op.color)) throw new PaintEditorError(`${at}: color "${op.color}" is not #rrggbb.`);
@@ -12894,7 +12938,7 @@ function createPaintProposals(options) {
12894
12938
  ...input.layerId ? { layerId: input.layerId } : {},
12895
12939
  ...input.layerName ? { layerName: input.layerName } : {}
12896
12940
  });
12897
- const topLayerId = () => _optionalChain([controller, 'access', _606 => _606.listLayers, 'call', _607 => _607(), 'access', _608 => _608.find, 'call', _609 => _609((l) => l.parentId === null), 'optionalAccess', _610 => _610.id]);
12941
+ const topLayerId = () => _optionalChain([controller, 'access', _609 => _609.listLayers, 'call', _610 => _610(), 'access', _611 => _611.find, 'call', _612 => _612((l) => l.parentId === null), 'optionalAccess', _613 => _613.id]);
12898
12942
  return {
12899
12943
  getState: () => state,
12900
12944
  subscribe(listener) {
@@ -12967,6 +13011,37 @@ function paintProposalGhost(proposal) {
12967
13011
  if (!b || !b.width || !b.height || proposal.ghost.length !== b.width * b.height * 4) return null;
12968
13012
  return { x: b.x, y: b.y, width: b.width, height: b.height, data: proposal.ghost };
12969
13013
  }
13014
+ function createPaintAgentStrokes() {
13015
+ let state = { strokes: [] };
13016
+ const listeners = /* @__PURE__ */ new Set();
13017
+ const set = (strokes) => {
13018
+ state = { strokes };
13019
+ listeners.forEach((l) => l(state));
13020
+ };
13021
+ return {
13022
+ getState: () => state,
13023
+ subscribe(listener) {
13024
+ listeners.add(listener);
13025
+ return () => {
13026
+ listeners.delete(listener);
13027
+ };
13028
+ },
13029
+ set(stroke) {
13030
+ const i = state.strokes.findIndex((s) => s.id === stroke.id);
13031
+ set(i < 0 ? [...state.strokes, stroke] : state.strokes.map((s, j) => j === i ? stroke : s));
13032
+ },
13033
+ remove(id) {
13034
+ if (state.strokes.some((s) => s.id === id)) set(state.strokes.filter((s) => s.id !== id));
13035
+ },
13036
+ clear(origin) {
13037
+ const keep = origin ? state.strokes.filter((s) => s.origin !== origin) : [];
13038
+ if (keep.length !== state.strokes.length) set(keep);
13039
+ }
13040
+ };
13041
+ }
13042
+ function paintAgentStrokePoints(stroke) {
13043
+ return stroke.points.map((p) => `${Math.round(p.x * 10) / 10},${Math.round(p.y * 10) / 10}`).join(" ");
13044
+ }
12970
13045
 
12971
13046
  // src/paint-editor/collaboration-tools.ts
12972
13047
  var READ7 = { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false };
@@ -13050,7 +13125,7 @@ function createPaintProposalToolProvider(proposals, options = {}) {
13050
13125
  },
13051
13126
  annotations: { title: "Propose paint", ...WRITE6 },
13052
13127
  handler: (args, context) => {
13053
- const origin = _optionalChain([context, 'access', _611 => _611.actor, 'optionalAccess', _612 => _612.id]) ? `agent:${context.actor.id}` : options.fallbackOrigin;
13128
+ const origin = _optionalChain([context, 'access', _614 => _614.actor, 'optionalAccess', _615 => _615.id]) ? `agent:${context.actor.id}` : options.fallbackOrigin;
13054
13129
  const proposal = proposals.propose({ ...args, ...origin ? { origin } : {} });
13055
13130
  const { id: _id, missing: _missing, createdAt: _createdAt, ...rest } = describe(proposal);
13056
13131
  return { proposalId: proposal.id, ...rest };
@@ -13449,4 +13524,6 @@ function createPaintProposalToolProvider(proposals, options = {}) {
13449
13524
 
13450
13525
 
13451
13526
 
13452
- exports.BACKLIGHT_SPILL = BACKLIGHT_SPILL; exports.BLEND_MENU_GROUPS = BLEND_MENU_GROUPS; exports.BLEND_MODES = _chunk2VX55NFMcjs.BLEND_MODES; exports.BRUSH_ID = _chunkRSIKDWOPcjs.BRUSH_ID; exports.BRUSH_ROTATIONS = _chunkRSIKDWOPcjs.BRUSH_ROTATIONS; exports.BRUSH_SLIDERS = _chunkMQGQTKVWcjs.BRUSH_SLIDERS; exports.BUILTIN_BRUSHES = _chunkRSIKDWOPcjs.BUILTIN_BRUSHES; exports.BristleStroke = BristleStroke; exports.DEFAULT_BACKLIGHT_COLOR = DEFAULT_BACKLIGHT_COLOR; exports.DEFAULT_BEHAVIOR = _chunkRSIKDWOPcjs.DEFAULT_BEHAVIOR; exports.DEFAULT_BRISTLE = _chunkRSIKDWOPcjs.DEFAULT_BRISTLE; exports.DEFAULT_BRUSH_ID = _chunkRSIKDWOPcjs.DEFAULT_BRUSH_ID; exports.DEFAULT_DPI = DEFAULT_DPI; exports.DEFAULT_DYNAMICS = _chunkRSIKDWOPcjs.DEFAULT_DYNAMICS; exports.DEFAULT_FLOW = _chunkKBYB7OWBcjs.DEFAULT_FLOW; exports.DEFAULT_IMPASTO = _chunkRSIKDWOPcjs.DEFAULT_IMPASTO; exports.DEFAULT_LIGHT = _chunkRSIKDWOPcjs.DEFAULT_LIGHT; exports.DEFAULT_LIGHTING = DEFAULT_LIGHTING; exports.DEFAULT_MULTI_COLOR = _chunkRSIKDWOPcjs.DEFAULT_MULTI_COLOR; exports.DEFAULT_PAINT_GRADIENT = _chunkFQPUF2W2cjs.DEFAULT_PAINT_GRADIENT; exports.DEFAULT_PAINT_GRADIENT_MAPPING = _chunkFQPUF2W2cjs.DEFAULT_PAINT_GRADIENT_MAPPING; exports.DEFAULT_PAPER = DEFAULT_PAPER; exports.DEFAULT_PARTICLE = _chunkRSIKDWOPcjs.DEFAULT_PARTICLE; exports.DEFAULT_SPRAY = _chunkRSIKDWOPcjs.DEFAULT_SPRAY; exports.DEFAULT_STICKER = _chunkRSIKDWOPcjs.DEFAULT_STICKER; exports.DEFAULT_SWATCHES = DEFAULT_SWATCHES; exports.DEFAULT_VIEW = DEFAULT_VIEW; exports.DEFAULT_WET_BRUSH = _chunkRSIKDWOPcjs.DEFAULT_WET_BRUSH; exports.DEFAULT_WET_PARAMS = _chunkKBYB7OWBcjs.DEFAULT_WET_PARAMS; exports.DOT_ROTATIONS = _chunkRSIKDWOPcjs.DOT_ROTATIONS; exports.DOT_ROTATION_LABELS = DOT_ROTATION_LABELS; exports.DOT_TEXTURE_ORDERS = _chunkRSIKDWOPcjs.DOT_TEXTURE_ORDERS; exports.DOT_TEXTURE_ORDER_LABELS = DOT_TEXTURE_ORDER_LABELS; exports.DryStroke = DryStroke; exports.EFFECT_MAP_REPEATS = EFFECT_MAP_REPEATS; exports.EFFECT_STRIP_HEIGHT = EFFECT_STRIP_HEIGHT; exports.GPU_LEAD = GPU_LEAD; exports.GRAIN_PATTERNS = _chunkPXDIAYB6cjs.GRAIN_PATTERNS; exports.GRAIN_TILE = _chunkPXDIAYB6cjs.GRAIN_TILE; exports.HARMONY_KINDS = _chunkI3Y2Q3PMcjs.HARMONY_KINDS; exports.IDENTITY_AFFINE = IDENTITY_AFFINE; exports.IDENTITY_COPY = IDENTITY_COPY; exports.IMPASTO_TOOLS = _chunkRSIKDWOPcjs.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 = _chunkFQPUF2W2cjs.MAX_BRUSH_SIZE; exports.MAX_CANVAS_SIDE = MAX_CANVAS_SIDE; exports.MAX_COORDINATE = MAX_COORDINATE; exports.MAX_DOT_TEXTURES = _chunkRSIKDWOPcjs.MAX_DOT_TEXTURES; exports.MAX_IMAGE_SIDE = MAX_IMAGE_SIDE; exports.MAX_LIVE_EFFECT_SOURCES = MAX_LIVE_EFFECT_SOURCES; exports.MAX_STICKER_STAMPS = _chunkRSIKDWOPcjs.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 = _chunkRSIKDWOPcjs.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 = _chunkRSIKDWOPcjs.PAINT_BRUSH_CATEGORIES; exports.PAINT_BRUSH_ENGINES = _chunkRSIKDWOPcjs.PAINT_BRUSH_ENGINES; exports.PAINT_COLOR_JSON_SCHEMA = _chunkFQPUF2W2cjs.PAINT_COLOR_JSON_SCHEMA; exports.PAINT_EFFECT_PLACES = PAINT_EFFECT_PLACES; exports.PAINT_FORMAT = PAINT_FORMAT; exports.PAINT_GRADIENT_FULL_SPEED = _chunkFQPUF2W2cjs.PAINT_GRADIENT_FULL_SPEED; exports.PAINT_GRADIENT_JSON_SCHEMA = _chunkFQPUF2W2cjs.PAINT_GRADIENT_JSON_SCHEMA; exports.PAINT_GRADIENT_KIT = _chunkFQPUF2W2cjs.PAINT_GRADIENT_KIT; exports.PAINT_GRADIENT_MAPPINGS = _chunkFQPUF2W2cjs.PAINT_GRADIENT_MAPPINGS; exports.PAINT_GRADIENT_MAPPING_LABELS = _chunkFQPUF2W2cjs.PAINT_GRADIENT_MAPPING_LABELS; exports.PAINT_GRADIENT_PRESETS = _chunkFQPUF2W2cjs.PAINT_GRADIENT_PRESETS; exports.PAINT_GRADIENT_REPEATS = _chunkFQPUF2W2cjs.PAINT_GRADIENT_REPEATS; exports.PAINT_GRADIENT_REPEAT_LABELS = _chunkFQPUF2W2cjs.PAINT_GRADIENT_REPEAT_LABELS; exports.PAINT_GRADIENT_SPACES = _chunkFQPUF2W2cjs.PAINT_GRADIENT_SPACES; exports.PAINT_GRADIENT_SPACE_LABELS = _chunkFQPUF2W2cjs.PAINT_GRADIENT_SPACE_LABELS; exports.PAINT_SCHEMA_VERSION = PAINT_SCHEMA_VERSION; exports.PAINT_SOURCE_JSON_SCHEMA = _chunkFQPUF2W2cjs.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 = PAPER_FAMILIES; exports.PAPER_LIBRARY = PAPER_LIBRARY; exports.PAPER_NODE_ID = PAPER_NODE_ID; exports.PAPER_SLIDERS = PAPER_SLIDERS; exports.PAPER_TARGET = PAPER_TARGET; exports.PARTICLE_KINDS = _chunkRSIKDWOPcjs.PARTICLE_KINDS; exports.PARTICLE_KIND_LABELS = PARTICLE_KIND_LABELS; exports.PARTICLE_RENDERS = _chunkRSIKDWOPcjs.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 = _chunkFQPUF2W2cjs.PaintGradientSampler; exports.PaintPresence = PaintPresence; exports.PaintSourceError = _chunkFQPUF2W2cjs.PaintSourceError; exports.PaintStrokeSession = PaintStrokeSession; exports.PaintWetLayers = PaintWetLayers; exports.PaperGrain = _chunkPXDIAYB6cjs.PaperGrain; exports.ParticleStroke = ParticleStroke; exports.PenDabWalker = PenDabWalker; exports.PenSmoother = PenSmoother; exports.PerspectiveSnapper = PerspectiveSnapper; exports.RIBBON_PAIRS = _chunkRSIKDWOPcjs.RIBBON_PAIRS; exports.RIBBON_PAIR_LABELS = RIBBON_PAIR_LABELS; exports.SNAP_DECIDE_DISTANCE = SNAP_DECIDE_DISTANCE; exports.STAMP_KINDS = _chunkJSDND7DFcjs.STAMP_KINDS; exports.STAMP_LABELS = STAMP_LABELS; exports.STENCIL_KINDS = STENCIL_KINDS; exports.STENCIL_SHAPES = STENCIL_SHAPES; exports.STICKER_ART_SIZE = STICKER_ART_SIZE; exports.STICKER_SLIDERS = STICKER_SLIDERS; exports.STROKE_SLIDERS = STROKE_SLIDERS; exports.SYMMETRY_MODES = SYMMETRY_MODES; exports.StencilSnapper = StencilSnapper; exports.StickerArtCache = StickerArtCache; exports.StickerBrowser = _chunkRVGP2XLFcjs.StickerBrowser; exports.StickerSpray = 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 = _chunkRSIKDWOPcjs.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 = _chunkRSIKDWOPcjs.WET_TOOLS; exports.WET_TOOL_LABELS = WET_TOOL_LABELS; exports.WetStrokeDriver = WetStrokeDriver; exports.addPaintGradientStop = _chunkFQPUF2W2cjs.addPaintGradientStop; exports.addPolygonArea = addPolygonArea; exports.affineCopy = affineCopy; exports.applyAffine = applyAffine; exports.backlightOf = backlightOf; exports.brushEngineControls = _chunkMQGQTKVWcjs.brushEngineControls; exports.brushLoadColor = brushLoadColor; exports.brushLoadForStroke = brushLoadForStroke; exports.brushTakesPaint = _chunkRSIKDWOPcjs.brushTakesPaint; exports.brushToJSON = _chunkRSIKDWOPcjs.brushToJSON; exports.buildTimeLapse = buildTimeLapse; exports.checkPaintEffectPlace = checkPaintEffectPlace; exports.clonePaper = clonePaper; exports.colorHarmony = colorHarmony2; exports.composeAffine = composeAffine; exports.contactSheet = contactSheet; exports.createPaintBrushLibraryToolProvider = createPaintBrushLibraryToolProvider; exports.createPaintChangeFeed = createPaintChangeFeed; exports.createPaintCompositor = createPaintCompositor; exports.createPaintDocument = createPaintDocument; exports.createPaintEditorDocument = createPaintEditorDocument; exports.createPaintEditorToolProvider = createPaintEditorToolProvider; exports.createPaintEffectsToolProvider = createPaintEffectsToolProvider; exports.createPaintLayer = createPaintLayer; exports.createPaintProposalToolProvider = createPaintProposalToolProvider; exports.createPaintProposals = createPaintProposals; exports.createPaintReplayTools = createPaintReplayTools; exports.createPaintStickerTools = createPaintStickerTools; exports.createPaintThickTools = createPaintThickTools; exports.createPaintWetTools = createPaintWetTools; exports.decodeImageBlob = decodeImageBlob; exports.defaultGuides = defaultGuides; exports.defaultImageEncoder = defaultImageEncoder; exports.defaultStickerRasterizer = defaultStickerRasterizer; exports.deserializePaintDocument = deserializePaintDocument; exports.deserializePaintDocumentAsync = deserializePaintDocumentAsync; exports.documentExtensions = documentExtensions; exports.documentToScreen = documentToScreen; exports.downloadBytes = downloadBytes; exports.downsampleRgba = downsampleRgba; exports.drawSticker = drawSticker; exports.drawWaterOverlay = drawWaterOverlay; exports.effectDabField = effectDabField; exports.effectLayersToJSON = effectLayersToJSON; exports.effectPaintKey = effectPaintKey; exports.effectPaintSize = effectPaintSize; exports.emptiedLayers = emptiedLayers; exports.emptyThickChannels = emptyThickChannels; exports.fitZoom = fitZoom; exports.grainCatch = _chunkPXDIAYB6cjs.grainCatch; exports.grainHeights = _chunkPXDIAYB6cjs.grainHeights; exports.guideOverlay = guideOverlay; exports.handlePaintShortcut = handlePaintShortcut; exports.hash2 = _chunk3K6HWEXZcjs.hash2; exports.hexToPaintRgb = _chunkFQPUF2W2cjs.hexToPaintRgb; exports.hexToRgb8 = hexToRgb8; exports.hslToRgb = hslToRgb; exports.hsvToRgb = hsvToRgb; exports.hueToWheel = _chunkI3Y2Q3PMcjs.hueToWheel; exports.invertAffine = invertAffine; exports.isBlendMode = _chunk2VX55NFMcjs.isBlendMode; exports.isGradientPaint = _chunkFQPUF2W2cjs.isGradientPaint; exports.isPaintEffectPaint = isPaintEffectPaint; exports.isPainterlyBlendMode = _chunk2VX55NFMcjs.isPainterlyBlendMode; exports.isPalmTouch = isPalmTouch; exports.isWetBrush = _chunkRSIKDWOPcjs.isWetBrush; exports.isWetCapable = _chunkRSIKDWOPcjs.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 = mixerTip; exports.multiColorForDab = multiColorForDab; exports.multiColorGradient = multiColorGradient; exports.multiColorPalette = multiColorPalette; exports.multiColorSliders = _chunkMQGQTKVWcjs.multiColorSliders; exports.multiColorToPaint = _chunkRSIKDWOPcjs.multiColorToPaint; exports.newPaintLayerId = newPaintLayerId; exports.nextPaperEffectVersion = nextPaperEffectVersion; exports.normalizeBehavior = _chunkRSIKDWOPcjs.normalizeBehavior; exports.normalizeBristle = _chunkRSIKDWOPcjs.normalizeBristle; exports.normalizeBrushStroke = normalizeBrushStroke; exports.normalizeCanvas = normalizeCanvas; exports.normalizeDynamics = _chunkRSIKDWOPcjs.normalizeDynamics; exports.normalizeFlow = _chunkKBYB7OWBcjs.normalizeFlow; exports.normalizeHexColor = _chunkFQPUF2W2cjs.normalizeHexColor; exports.normalizeImpasto = _chunkRSIKDWOPcjs.normalizeImpasto; exports.normalizeLight = _chunkRSIKDWOPcjs.normalizeLight; exports.normalizeLighting = normalizeLighting; exports.normalizeMultiColor = _chunkRSIKDWOPcjs.normalizeMultiColor; exports.normalizePaintBrush = _chunkRSIKDWOPcjs.normalizePaintBrush; exports.normalizePaper = normalizePaper; exports.normalizeParticle = _chunkRSIKDWOPcjs.normalizeParticle; exports.normalizePerspective = normalizePerspective; exports.normalizeRotation = normalizeRotation; exports.normalizeStencil = normalizeStencil; exports.normalizeStickerSettings = _chunkRSIKDWOPcjs.normalizeStickerSettings; exports.normalizeStickerUpdate = normalizeStickerUpdate; exports.normalizeSymmetry = normalizeSymmetry; exports.normalizeView = normalizeView; exports.normalizeWetBrush = _chunkRSIKDWOPcjs.normalizeWetBrush; exports.normalizeWetParams = _chunkKBYB7OWBcjs.normalizeWetParams; exports.overPixels = overPixels; exports.padSampleRadius = padSampleRadius; exports.paintGradientMappingFor = _chunkFQPUF2W2cjs.paintGradientMappingFor; exports.paintPlaybackPanel = paintPlaybackPanel; exports.paintProposalGhost = paintProposalGhost; exports.paintSourceColor = _chunkFQPUF2W2cjs.paintSourceColor; exports.paintSourceCss = _chunkFQPUF2W2cjs.paintSourceCss; exports.paintToMultiColor = _chunkRSIKDWOPcjs.paintToMultiColor; exports.paperEffectFromJSON = paperEffectFromJSON; exports.paperEffectToJSON = paperEffectToJSON; exports.paperGrain = paperGrain; exports.paperKey = paperKey; exports.paperNode = paperNode; exports.paperPreset = paperPreset; exports.parseBrushLibrary = _chunkRSIKDWOPcjs.parseBrushLibrary; exports.parseHexColor = parseHexColor; exports.parsePaintSource = _chunkFQPUF2W2cjs.parsePaintSource; exports.patchBrushValue = _chunkMQGQTKVWcjs.patchBrushValue; exports.patchPath = patchPath; exports.penOrientation = 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 = readEffectStrokeMap; exports.readPaintEffectPaint = readPaintEffectPaint; exports.readPaintEffectSource = readPaintEffectSource; exports.readPaintSource = _chunkFQPUF2W2cjs.readPaintSource; exports.readPath = readPath; exports.readSwatch = readSwatch; exports.reliefInfo = reliefInfo; exports.removePaintGradientStop = _chunkFQPUF2W2cjs.removePaintGradientStop; exports.renderBrushThumbnail = renderBrushThumbnail; exports.renderColorWheel = renderColorWheel; exports.renderPaper = renderPaper; exports.renderStickers = renderStickers; exports.replayFrame = replayFrame; exports.replayItems = replayItems; exports.replayPainting = replayPainting; exports.resolvePaintGradient = _chunkFQPUF2W2cjs.resolvePaintGradient; exports.reversePaintGradient = _chunkFQPUF2W2cjs.reversePaintGradient; exports.rgbToHexColor = rgbToHexColor; exports.rgbToHsl = rgbToHsl; exports.rgbToHsv = rgbToHsv; exports.sampleArt = sampleArt; exports.sampleEffectAt = sampleEffectAt; exports.sampleEffectField = sampleEffectField; exports.samplePressure = samplePressure; exports.scalePaintGradient = _chunkFQPUF2W2cjs.scalePaintGradient; exports.scaleStencil = scaleStencil; exports.screenToDocument = screenToDocument; exports.seedFromString = _chunk3K6HWEXZcjs.seedFromString; exports.serializePaintDocument = serializePaintDocument; exports.serializePaintDocumentExternal = serializePaintDocumentExternal; exports.solidPaint = _chunkFQPUF2W2cjs.solidPaint; exports.stampCoverage = _chunkJSDND7DFcjs.stampCoverage; exports.standardBlendMode = _chunk2VX55NFMcjs.standardBlendMode; exports.startWetClock = startWetClock; exports.stencilMask = stencilMask; exports.stencilOutline = stencilOutline; exports.stickerAt = stickerAt; exports.stickerRect = stickerRect; exports.stickerRefLabel = stickerRefLabel; exports.stickerStamp = stickerStamp; exports.stickerSurface = stickerSurface; exports.strokeBounds = strokeBounds; exports.strokeDuration = strokeDuration; exports.strokeSchedule = strokeSchedule; exports.strokeToJSON = strokeToJSON; exports.sweepPath = sweepPath; exports.symmetryAxisAngles = symmetryAxisAngles; exports.symmetryAxisSegments = symmetryAxisSegments; exports.symmetryCopies = symmetryCopies; exports.thickFromJSON = thickFromJSON; exports.thickToJSON = thickToJSON; exports.thumbnailStroke = thumbnailStroke; exports.tiltToOrientation = tiltToOrientation; exports.timeLapseVideo = timeLapseVideo; exports.timeLapseZip = timeLapseZip; exports.toStrokePoint = toStrokePoint; exports.toggleDotTexture = toggleDotTexture; exports.toggleStamp = toggleStamp; exports.toggleStickerRef = toggleStickerRef; exports.translateStencil = translateStencil; exports.updatePaintGradientStop = _chunkFQPUF2W2cjs.updatePaintGradientStop; exports.usesPaintExchange = _chunkRSIKDWOPcjs.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 = _chunkI3Y2Q3PMcjs.wheelToHue; exports.withPaintPlayback = withPaintPlayback;
13527
+
13528
+
13529
+ exports.BACKLIGHT_SPILL = BACKLIGHT_SPILL; exports.BLEND_MENU_GROUPS = BLEND_MENU_GROUPS; exports.BLEND_MODES = _chunk2VX55NFMcjs.BLEND_MODES; exports.BRUSH_ID = _chunkRSIKDWOPcjs.BRUSH_ID; exports.BRUSH_ROTATIONS = _chunkRSIKDWOPcjs.BRUSH_ROTATIONS; exports.BRUSH_SLIDERS = _chunkMQGQTKVWcjs.BRUSH_SLIDERS; exports.BUILTIN_BRUSHES = _chunkRSIKDWOPcjs.BUILTIN_BRUSHES; exports.BristleStroke = BristleStroke; exports.DEFAULT_BACKLIGHT_COLOR = DEFAULT_BACKLIGHT_COLOR; exports.DEFAULT_BEHAVIOR = _chunkRSIKDWOPcjs.DEFAULT_BEHAVIOR; exports.DEFAULT_BRISTLE = _chunkRSIKDWOPcjs.DEFAULT_BRISTLE; exports.DEFAULT_BRUSH_ID = _chunkRSIKDWOPcjs.DEFAULT_BRUSH_ID; exports.DEFAULT_DPI = DEFAULT_DPI; exports.DEFAULT_DYNAMICS = _chunkRSIKDWOPcjs.DEFAULT_DYNAMICS; exports.DEFAULT_FLOW = _chunkKBYB7OWBcjs.DEFAULT_FLOW; exports.DEFAULT_IMPASTO = _chunkRSIKDWOPcjs.DEFAULT_IMPASTO; exports.DEFAULT_LIGHT = _chunkRSIKDWOPcjs.DEFAULT_LIGHT; exports.DEFAULT_LIGHTING = DEFAULT_LIGHTING; exports.DEFAULT_MULTI_COLOR = _chunkRSIKDWOPcjs.DEFAULT_MULTI_COLOR; exports.DEFAULT_PAINT_GRADIENT = _chunkFQPUF2W2cjs.DEFAULT_PAINT_GRADIENT; exports.DEFAULT_PAINT_GRADIENT_MAPPING = _chunkFQPUF2W2cjs.DEFAULT_PAINT_GRADIENT_MAPPING; exports.DEFAULT_PAPER = DEFAULT_PAPER; exports.DEFAULT_PARTICLE = _chunkRSIKDWOPcjs.DEFAULT_PARTICLE; exports.DEFAULT_SPRAY = _chunkRSIKDWOPcjs.DEFAULT_SPRAY; exports.DEFAULT_STICKER = _chunkRSIKDWOPcjs.DEFAULT_STICKER; exports.DEFAULT_SWATCHES = DEFAULT_SWATCHES; exports.DEFAULT_VIEW = DEFAULT_VIEW; exports.DEFAULT_WET_BRUSH = _chunkRSIKDWOPcjs.DEFAULT_WET_BRUSH; exports.DEFAULT_WET_PARAMS = _chunkKBYB7OWBcjs.DEFAULT_WET_PARAMS; exports.DOT_ROTATIONS = _chunkRSIKDWOPcjs.DOT_ROTATIONS; exports.DOT_ROTATION_LABELS = DOT_ROTATION_LABELS; exports.DOT_TEXTURE_ORDERS = _chunkRSIKDWOPcjs.DOT_TEXTURE_ORDERS; exports.DOT_TEXTURE_ORDER_LABELS = DOT_TEXTURE_ORDER_LABELS; exports.DryStroke = DryStroke; exports.EFFECT_MAP_REPEATS = EFFECT_MAP_REPEATS; exports.EFFECT_STRIP_HEIGHT = EFFECT_STRIP_HEIGHT; exports.GPU_LEAD = GPU_LEAD; exports.GRAIN_PATTERNS = _chunkPXDIAYB6cjs.GRAIN_PATTERNS; exports.GRAIN_TILE = _chunkPXDIAYB6cjs.GRAIN_TILE; exports.HARMONY_KINDS = _chunkI3Y2Q3PMcjs.HARMONY_KINDS; exports.IDENTITY_AFFINE = IDENTITY_AFFINE; exports.IDENTITY_COPY = IDENTITY_COPY; exports.IMPASTO_TOOLS = _chunkRSIKDWOPcjs.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 = _chunkFQPUF2W2cjs.MAX_BRUSH_SIZE; exports.MAX_CANVAS_SIDE = MAX_CANVAS_SIDE; exports.MAX_COORDINATE = MAX_COORDINATE; exports.MAX_DOT_TEXTURES = _chunkRSIKDWOPcjs.MAX_DOT_TEXTURES; exports.MAX_IMAGE_SIDE = MAX_IMAGE_SIDE; exports.MAX_LIVE_EFFECT_SOURCES = MAX_LIVE_EFFECT_SOURCES; exports.MAX_STICKER_STAMPS = _chunkRSIKDWOPcjs.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 = _chunkRSIKDWOPcjs.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 = _chunkRSIKDWOPcjs.PAINT_BRUSH_CATEGORIES; exports.PAINT_BRUSH_ENGINES = _chunkRSIKDWOPcjs.PAINT_BRUSH_ENGINES; exports.PAINT_COLOR_JSON_SCHEMA = _chunkFQPUF2W2cjs.PAINT_COLOR_JSON_SCHEMA; exports.PAINT_EFFECT_PLACES = PAINT_EFFECT_PLACES; exports.PAINT_FORMAT = PAINT_FORMAT; exports.PAINT_GRADIENT_FULL_SPEED = _chunkFQPUF2W2cjs.PAINT_GRADIENT_FULL_SPEED; exports.PAINT_GRADIENT_JSON_SCHEMA = _chunkFQPUF2W2cjs.PAINT_GRADIENT_JSON_SCHEMA; exports.PAINT_GRADIENT_KIT = _chunkFQPUF2W2cjs.PAINT_GRADIENT_KIT; exports.PAINT_GRADIENT_MAPPINGS = _chunkFQPUF2W2cjs.PAINT_GRADIENT_MAPPINGS; exports.PAINT_GRADIENT_MAPPING_LABELS = _chunkFQPUF2W2cjs.PAINT_GRADIENT_MAPPING_LABELS; exports.PAINT_GRADIENT_PRESETS = _chunkFQPUF2W2cjs.PAINT_GRADIENT_PRESETS; exports.PAINT_GRADIENT_REPEATS = _chunkFQPUF2W2cjs.PAINT_GRADIENT_REPEATS; exports.PAINT_GRADIENT_REPEAT_LABELS = _chunkFQPUF2W2cjs.PAINT_GRADIENT_REPEAT_LABELS; exports.PAINT_GRADIENT_SPACES = _chunkFQPUF2W2cjs.PAINT_GRADIENT_SPACES; exports.PAINT_GRADIENT_SPACE_LABELS = _chunkFQPUF2W2cjs.PAINT_GRADIENT_SPACE_LABELS; exports.PAINT_SCHEMA_VERSION = PAINT_SCHEMA_VERSION; exports.PAINT_SOURCE_JSON_SCHEMA = _chunkFQPUF2W2cjs.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 = PAPER_FAMILIES; exports.PAPER_LIBRARY = PAPER_LIBRARY; exports.PAPER_NODE_ID = PAPER_NODE_ID; exports.PAPER_SLIDERS = PAPER_SLIDERS; exports.PAPER_TARGET = PAPER_TARGET; exports.PARTICLE_KINDS = _chunkRSIKDWOPcjs.PARTICLE_KINDS; exports.PARTICLE_KIND_LABELS = PARTICLE_KIND_LABELS; exports.PARTICLE_RENDERS = _chunkRSIKDWOPcjs.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 = _chunkFQPUF2W2cjs.PaintGradientSampler; exports.PaintPresence = PaintPresence; exports.PaintSourceError = _chunkFQPUF2W2cjs.PaintSourceError; exports.PaintStrokeSession = PaintStrokeSession; exports.PaintWetLayers = PaintWetLayers; exports.PaperGrain = _chunkPXDIAYB6cjs.PaperGrain; exports.ParticleStroke = ParticleStroke; exports.PenDabWalker = PenDabWalker; exports.PenSmoother = PenSmoother; exports.PerspectiveSnapper = PerspectiveSnapper; exports.RIBBON_PAIRS = _chunkRSIKDWOPcjs.RIBBON_PAIRS; exports.RIBBON_PAIR_LABELS = RIBBON_PAIR_LABELS; exports.SNAP_DECIDE_DISTANCE = SNAP_DECIDE_DISTANCE; exports.STAMP_KINDS = _chunkJSDND7DFcjs.STAMP_KINDS; exports.STAMP_LABELS = STAMP_LABELS; exports.STENCIL_KINDS = STENCIL_KINDS; exports.STENCIL_SHAPES = STENCIL_SHAPES; exports.STICKER_ART_SIZE = STICKER_ART_SIZE; exports.STICKER_SLIDERS = STICKER_SLIDERS; exports.STROKE_SLIDERS = STROKE_SLIDERS; exports.SYMMETRY_MODES = SYMMETRY_MODES; exports.StencilSnapper = StencilSnapper; exports.StickerArtCache = StickerArtCache; exports.StickerBrowser = _chunkRVGP2XLFcjs.StickerBrowser; exports.StickerSpray = 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 = _chunkRSIKDWOPcjs.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 = _chunkRSIKDWOPcjs.WET_TOOLS; exports.WET_TOOL_LABELS = WET_TOOL_LABELS; exports.WetStrokeDriver = WetStrokeDriver; exports.addPaintGradientStop = _chunkFQPUF2W2cjs.addPaintGradientStop; exports.addPolygonArea = addPolygonArea; exports.affineCopy = affineCopy; exports.applyAffine = applyAffine; exports.backlightOf = backlightOf; exports.brushEngineControls = _chunkMQGQTKVWcjs.brushEngineControls; exports.brushLoadColor = brushLoadColor; exports.brushLoadForStroke = brushLoadForStroke; exports.brushTakesPaint = _chunkRSIKDWOPcjs.brushTakesPaint; exports.brushToJSON = _chunkRSIKDWOPcjs.brushToJSON; exports.buildTimeLapse = buildTimeLapse; exports.checkPaintEffectPlace = checkPaintEffectPlace; exports.clonePaper = clonePaper; exports.colorHarmony = colorHarmony2; exports.composeAffine = composeAffine; exports.contactSheet = contactSheet; exports.createPaintAgentStrokes = createPaintAgentStrokes; exports.createPaintBrushLibraryToolProvider = createPaintBrushLibraryToolProvider; exports.createPaintChangeFeed = createPaintChangeFeed; exports.createPaintCompositor = createPaintCompositor; exports.createPaintDocument = createPaintDocument; exports.createPaintEditorDocument = createPaintEditorDocument; exports.createPaintEditorToolProvider = createPaintEditorToolProvider; exports.createPaintEffectsToolProvider = createPaintEffectsToolProvider; exports.createPaintLayer = createPaintLayer; exports.createPaintProposalToolProvider = createPaintProposalToolProvider; exports.createPaintProposals = createPaintProposals; exports.createPaintReplayTools = createPaintReplayTools; exports.createPaintStickerTools = createPaintStickerTools; exports.createPaintThickTools = createPaintThickTools; exports.createPaintWetTools = createPaintWetTools; exports.decodeImageBlob = decodeImageBlob; exports.defaultGuides = defaultGuides; exports.defaultImageEncoder = defaultImageEncoder; exports.defaultStickerRasterizer = defaultStickerRasterizer; exports.deserializePaintDocument = deserializePaintDocument; exports.deserializePaintDocumentAsync = deserializePaintDocumentAsync; exports.documentExtensions = documentExtensions; exports.documentToScreen = documentToScreen; exports.downloadBytes = downloadBytes; exports.downsampleRgba = downsampleRgba; exports.drawSticker = drawSticker; exports.drawWaterOverlay = drawWaterOverlay; exports.effectDabField = effectDabField; exports.effectLayersToJSON = effectLayersToJSON; exports.effectPaintKey = effectPaintKey; exports.effectPaintSize = effectPaintSize; exports.emptiedLayers = emptiedLayers; exports.emptyThickChannels = emptyThickChannels; exports.fitZoom = fitZoom; exports.grainCatch = _chunkPXDIAYB6cjs.grainCatch; exports.grainHeights = _chunkPXDIAYB6cjs.grainHeights; exports.guideOverlay = guideOverlay; exports.handlePaintShortcut = handlePaintShortcut; exports.hash2 = _chunk3K6HWEXZcjs.hash2; exports.hexToPaintRgb = _chunkFQPUF2W2cjs.hexToPaintRgb; exports.hexToRgb8 = hexToRgb8; exports.hslToRgb = hslToRgb; exports.hsvToRgb = hsvToRgb; exports.hueToWheel = _chunkI3Y2Q3PMcjs.hueToWheel; exports.invertAffine = invertAffine; exports.isBlendMode = _chunk2VX55NFMcjs.isBlendMode; exports.isGradientPaint = _chunkFQPUF2W2cjs.isGradientPaint; exports.isPaintEffectPaint = isPaintEffectPaint; exports.isPainterlyBlendMode = _chunk2VX55NFMcjs.isPainterlyBlendMode; exports.isPalmTouch = isPalmTouch; exports.isWetBrush = _chunkRSIKDWOPcjs.isWetBrush; exports.isWetCapable = _chunkRSIKDWOPcjs.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 = mixerTip; exports.multiColorForDab = multiColorForDab; exports.multiColorGradient = multiColorGradient; exports.multiColorPalette = multiColorPalette; exports.multiColorSliders = _chunkMQGQTKVWcjs.multiColorSliders; exports.multiColorToPaint = _chunkRSIKDWOPcjs.multiColorToPaint; exports.newPaintLayerId = newPaintLayerId; exports.nextPaperEffectVersion = nextPaperEffectVersion; exports.normalizeBehavior = _chunkRSIKDWOPcjs.normalizeBehavior; exports.normalizeBristle = _chunkRSIKDWOPcjs.normalizeBristle; exports.normalizeBrushStroke = normalizeBrushStroke; exports.normalizeCanvas = normalizeCanvas; exports.normalizeDynamics = _chunkRSIKDWOPcjs.normalizeDynamics; exports.normalizeFlow = _chunkKBYB7OWBcjs.normalizeFlow; exports.normalizeHexColor = _chunkFQPUF2W2cjs.normalizeHexColor; exports.normalizeImpasto = _chunkRSIKDWOPcjs.normalizeImpasto; exports.normalizeLight = _chunkRSIKDWOPcjs.normalizeLight; exports.normalizeLighting = normalizeLighting; exports.normalizeMultiColor = _chunkRSIKDWOPcjs.normalizeMultiColor; exports.normalizePaintBrush = _chunkRSIKDWOPcjs.normalizePaintBrush; exports.normalizePaper = normalizePaper; exports.normalizeParticle = _chunkRSIKDWOPcjs.normalizeParticle; exports.normalizePerspective = normalizePerspective; exports.normalizeRotation = normalizeRotation; exports.normalizeStencil = normalizeStencil; exports.normalizeStickerSettings = _chunkRSIKDWOPcjs.normalizeStickerSettings; exports.normalizeStickerUpdate = normalizeStickerUpdate; exports.normalizeSymmetry = normalizeSymmetry; exports.normalizeView = normalizeView; exports.normalizeWetBrush = _chunkRSIKDWOPcjs.normalizeWetBrush; exports.normalizeWetParams = _chunkKBYB7OWBcjs.normalizeWetParams; exports.overPixels = overPixels; exports.padSampleRadius = padSampleRadius; exports.paintAgentStrokePoints = paintAgentStrokePoints; exports.paintGradientMappingFor = _chunkFQPUF2W2cjs.paintGradientMappingFor; exports.paintPlaybackPanel = paintPlaybackPanel; exports.paintProposalGhost = paintProposalGhost; exports.paintSourceColor = _chunkFQPUF2W2cjs.paintSourceColor; exports.paintSourceCss = _chunkFQPUF2W2cjs.paintSourceCss; exports.paintToMultiColor = _chunkRSIKDWOPcjs.paintToMultiColor; exports.paperEffectFromJSON = paperEffectFromJSON; exports.paperEffectToJSON = paperEffectToJSON; exports.paperGrain = paperGrain; exports.paperKey = paperKey; exports.paperNode = paperNode; exports.paperPreset = paperPreset; exports.parseBrushLibrary = _chunkRSIKDWOPcjs.parseBrushLibrary; exports.parseHexColor = parseHexColor; exports.parsePaintSource = _chunkFQPUF2W2cjs.parsePaintSource; exports.patchBrushValue = _chunkMQGQTKVWcjs.patchBrushValue; exports.patchPath = patchPath; exports.penOrientation = 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 = readEffectStrokeMap; exports.readPaintEffectPaint = readPaintEffectPaint; exports.readPaintEffectSource = readPaintEffectSource; exports.readPaintSource = _chunkFQPUF2W2cjs.readPaintSource; exports.readPath = readPath; exports.readSwatch = readSwatch; exports.reliefInfo = reliefInfo; exports.removePaintGradientStop = _chunkFQPUF2W2cjs.removePaintGradientStop; exports.renderBrushThumbnail = renderBrushThumbnail; exports.renderColorWheel = renderColorWheel; exports.renderPaper = renderPaper; exports.renderStickers = renderStickers; exports.replayFrame = replayFrame; exports.replayItems = replayItems; exports.replayPainting = replayPainting; exports.resolvePaintGradient = _chunkFQPUF2W2cjs.resolvePaintGradient; exports.reversePaintGradient = _chunkFQPUF2W2cjs.reversePaintGradient; exports.rgbToHexColor = rgbToHexColor; exports.rgbToHsl = rgbToHsl; exports.rgbToHsv = rgbToHsv; exports.sampleArt = sampleArt; exports.sampleEffectAt = sampleEffectAt; exports.sampleEffectField = sampleEffectField; exports.samplePressure = samplePressure; exports.scalePaintGradient = _chunkFQPUF2W2cjs.scalePaintGradient; exports.scaleStencil = scaleStencil; exports.screenToDocument = screenToDocument; exports.seedFromString = _chunk3K6HWEXZcjs.seedFromString; exports.serializePaintDocument = serializePaintDocument; exports.serializePaintDocumentExternal = serializePaintDocumentExternal; exports.solidPaint = _chunkFQPUF2W2cjs.solidPaint; exports.stampCoverage = _chunkJSDND7DFcjs.stampCoverage; exports.standardBlendMode = _chunk2VX55NFMcjs.standardBlendMode; exports.startWetClock = startWetClock; exports.stencilMask = stencilMask; exports.stencilOutline = stencilOutline; exports.stickerAt = stickerAt; exports.stickerRect = stickerRect; exports.stickerRefLabel = stickerRefLabel; exports.stickerStamp = stickerStamp; exports.stickerSurface = stickerSurface; exports.strokeBounds = strokeBounds; exports.strokeDuration = strokeDuration; exports.strokeSchedule = strokeSchedule; exports.strokeToJSON = strokeToJSON; exports.sweepPath = sweepPath; exports.symmetryAxisAngles = symmetryAxisAngles; exports.symmetryAxisSegments = symmetryAxisSegments; exports.symmetryCopies = symmetryCopies; exports.thickFromJSON = thickFromJSON; exports.thickToJSON = thickToJSON; exports.thumbnailStroke = thumbnailStroke; exports.tiltToOrientation = tiltToOrientation; exports.timeLapseVideo = timeLapseVideo; exports.timeLapseZip = timeLapseZip; exports.toStrokePoint = toStrokePoint; exports.toggleDotTexture = toggleDotTexture; exports.toggleStamp = toggleStamp; exports.toggleStickerRef = toggleStickerRef; exports.translateStencil = translateStencil; exports.updatePaintGradientStop = _chunkFQPUF2W2cjs.updatePaintGradientStop; exports.usesPaintExchange = _chunkRSIKDWOPcjs.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 = _chunkI3Y2Q3PMcjs.wheelToHue; exports.withPaintPlayback = withPaintPlayback;