@pixerate/editor 0.266.2 → 0.267.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (111) hide show
  1. package/dist/agent/index.cjs +2 -2
  2. package/dist/agent/index.js +1 -1
  3. package/dist/animation-editor/controller.d.cts +8 -0
  4. package/dist/animation-editor/controller.d.ts +8 -0
  5. package/dist/animation-editor/effect-tools.d.cts +1 -1
  6. package/dist/animation-editor/effect-tools.d.ts +1 -1
  7. package/dist/animation-editor/index.cjs +172 -105
  8. package/dist/animation-editor/index.js +91 -24
  9. package/dist/brushes/index.cjs +59 -59
  10. package/dist/brushes/index.js +5 -5
  11. package/dist/brushes/profiles.d.cts +6 -1
  12. package/dist/brushes/profiles.d.ts +6 -1
  13. package/dist/{brushstrokeRender-FSUWXUZY.cjs → brushstrokeRender-L7JYRR2R.cjs} +16 -16
  14. package/dist/{brushstrokeRender-KD453OBX.js → brushstrokeRender-NLFPEBGI.js} +4 -4
  15. package/dist/canvas/brushTypes.d.cts +12 -0
  16. package/dist/canvas/brushTypes.d.ts +12 -0
  17. package/dist/canvas/brushstroke.d.cts +1 -1
  18. package/dist/canvas/brushstroke.d.ts +1 -1
  19. package/dist/canvas/drawController.d.cts +19 -4
  20. package/dist/canvas/drawController.d.ts +19 -4
  21. package/dist/canvas/index.cjs +144 -105
  22. package/dist/canvas/index.js +46 -7
  23. package/dist/{chunk-XORJ7UZO.cjs → chunk-3VHH6V67.cjs} +13 -12
  24. package/dist/{chunk-T2LDTEXK.js → chunk-4IDUYB45.js} +2217 -56
  25. package/dist/chunk-7UKFXXWL.js +802 -0
  26. package/dist/chunk-ADMRNWR7.js +340 -0
  27. package/dist/{chunk-CIJBSUM5.js → chunk-AGNUD5BI.js} +2 -2
  28. package/dist/{chunk-WLUVZKVD.cjs → chunk-DT4YQUGT.cjs} +32 -32
  29. package/dist/{chunk-DXYHQ2VN.js → chunk-EF7LZAXQ.js} +1 -1
  30. package/dist/chunk-EXB2EGBE.cjs +802 -0
  31. package/dist/{chunk-4ODRXQRW.js → chunk-EYSHTYLG.js} +1 -1
  32. package/dist/{chunk-R44Y3EFS.js → chunk-FGJHJIMN.js} +8 -336
  33. package/dist/{chunk-AQZQWXEU.cjs → chunk-G7NHE2VD.cjs} +35 -35
  34. package/dist/{chunk-XC6DPRYI.js → chunk-GSTSZPSR.js} +154 -949
  35. package/dist/{chunk-VRK322ZC.cjs → chunk-HIO6E7LC.cjs} +2 -2
  36. package/dist/{chunk-TOID45I2.cjs → chunk-J2TNIZ55.cjs} +1 -1
  37. package/dist/{chunk-YHDHFJUC.cjs → chunk-J5VQYK7T.cjs} +217 -1012
  38. package/dist/{chunk-3C33YTNN.js → chunk-JGWVZPT6.js} +2 -2
  39. package/dist/{chunk-ACFSFUQH.js → chunk-JL6YH5WD.js} +4 -0
  40. package/dist/{chunk-3SBLVGOM.cjs → chunk-LA5Y4ETA.cjs} +23 -23
  41. package/dist/{chunk-MVUQSK5J.cjs → chunk-LHPEG5AU.cjs} +107 -435
  42. package/dist/{chunk-DOZ6F2K2.js → chunk-NSETJI74.js} +3 -2
  43. package/dist/{chunk-XRXFVRGY.cjs → chunk-OKHKA43L.cjs} +2364 -203
  44. package/dist/{chunk-LK4SXL3V.js → chunk-OSEXT7JL.js} +1 -1
  45. package/dist/{chunk-PE6YJMQT.cjs → chunk-PFHJS4HE.cjs} +20 -19
  46. package/dist/{chunk-7KNW3WXZ.cjs → chunk-QEVLRLUN.cjs} +63 -0
  47. package/dist/{chunk-OTN6VB5S.cjs → chunk-RDFHWAHL.cjs} +5 -1
  48. package/dist/{chunk-6JL2D5SG.js → chunk-VE6UKYQ2.js} +3 -2
  49. package/dist/{chunk-RFJZGTHA.cjs → chunk-XVOP3CGQ.cjs} +9 -9
  50. package/dist/{chunk-EZOJBP4D.js → chunk-YIC6MAJ2.js} +1 -1
  51. package/dist/chunk-YZWM6ZIP.cjs +340 -0
  52. package/dist/{chunk-472INMWH.js → chunk-ZA7L5YJB.js} +63 -0
  53. package/dist/commands/builtins.d.cts +12 -1
  54. package/dist/commands/builtins.d.ts +12 -1
  55. package/dist/commands/index.cjs +2 -2
  56. package/dist/commands/index.js +1 -1
  57. package/dist/image-editor/controller.d.cts +1 -1
  58. package/dist/image-editor/controller.d.ts +1 -1
  59. package/dist/image-editor/index.cjs +837 -833
  60. package/dist/image-editor/index.js +105 -101
  61. package/dist/paint/index.cjs +5 -3
  62. package/dist/paint/index.js +46 -44
  63. package/dist/paint-editor/controller.d.cts +5 -3
  64. package/dist/paint-editor/controller.d.ts +5 -3
  65. package/dist/paint-editor/index.cjs +832 -2295
  66. package/dist/paint-editor/index.js +285 -1748
  67. package/dist/paint-editor/path-samples.d.cts +2 -0
  68. package/dist/paint-editor/path-samples.d.ts +2 -0
  69. package/dist/paint-editor/presence.d.cts +20 -1
  70. package/dist/paint-editor/presence.d.ts +20 -1
  71. package/dist/stickers/helpers.d.cts +2 -0
  72. package/dist/stickers/helpers.d.ts +2 -0
  73. package/dist/stickers/index.cjs +41 -35
  74. package/dist/stickers/index.js +22 -16
  75. package/dist/stickers/types.d.cts +4 -2
  76. package/dist/stickers/types.d.ts +4 -2
  77. package/dist/vector/backdrop.d.cts +13 -0
  78. package/dist/vector/backdrop.d.ts +13 -0
  79. package/dist/vector/brushstroke.d.cts +54 -7
  80. package/dist/vector/brushstroke.d.ts +54 -7
  81. package/dist/vector/brushstrokeMedia.d.cts +96 -0
  82. package/dist/vector/brushstrokeMedia.d.ts +96 -0
  83. package/dist/vector/controller.d.cts +17 -3
  84. package/dist/vector/controller.d.ts +17 -3
  85. package/dist/vector/index.cjs +1846 -1386
  86. package/dist/vector/index.d.cts +2 -0
  87. package/dist/vector/index.d.ts +2 -0
  88. package/dist/vector/index.js +517 -57
  89. package/dist/vector/render.d.cts +6 -0
  90. package/dist/vector/render.d.ts +6 -0
  91. package/dist/vector/types.d.cts +14 -0
  92. package/dist/vector/types.d.ts +14 -0
  93. package/package.json +1 -1
  94. package/skills/pixerate-animation-editor/SKILL.md +1 -0
  95. package/skills/pixerate-brushes/SKILL.md +2 -2
  96. package/skills/pixerate-brushes-design/SKILL.md +7 -4
  97. package/skills/pixerate-brushes-design/evals/port-to-vector.json +8 -8
  98. package/skills/pixerate-canvas/SKILL.md +11 -1
  99. package/skills/pixerate-image-editor/SKILL.md +19 -64
  100. package/skills/pixerate-image-editor/references/color-management.md +2 -1
  101. package/skills/pixerate-image-editor/references/free-transform.md +12 -0
  102. package/skills/pixerate-image-editor/references/layer-effects.md +10 -0
  103. package/skills/pixerate-image-editor/references/painting.md +17 -0
  104. package/skills/pixerate-image-editor/references/photoshop-files.md +1 -1
  105. package/skills/pixerate-image-editor/references/shapes-and-type.md +14 -0
  106. package/skills/pixerate-image-editor/references/smart-objects.md +10 -0
  107. package/skills/pixerate-paint-editor/SKILL.md +8 -4
  108. package/skills/pixerate-paint-editor/references/wet-media.md +9 -0
  109. package/skills/pixerate-vector/SKILL.md +16 -6
  110. package/skills/pixerate-vector/references/best-practices.md +1 -0
  111. package/skills/pixerate-vector/references/commands.md +19 -0
@@ -1,879 +1,10 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; } var _class; var _class2; var _class3; var _class4; var _class5; var _class6;
2
-
3
-
4
-
5
-
6
-
7
-
8
- var _chunkBB6TR422cjs = require('./chunk-BB6TR422.cjs');
9
-
10
-
11
-
12
-
13
-
14
-
15
-
16
- var _chunkFQPUF2W2cjs = require('./chunk-FQPUF2W2.cjs');
17
-
18
-
19
-
20
-
21
-
22
-
23
- var _chunk2VX55NFMcjs = require('./chunk-2VX55NFM.cjs');
24
-
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; } var _class; var _class2; var _class3;
25
2
 
26
3
 
27
4
 
28
5
 
29
6
  var _chunk474IQG74cjs = require('./chunk-474IQG74.cjs');
30
7
 
31
- // src/paint/pigment-tools.ts
32
- var HEX = /^#?([0-9a-f]{6})$/i;
33
- function parseHex(value, index) {
34
- const m = typeof value === "string" ? HEX.exec(value.trim()) : null;
35
- if (!m) throw new Error(`colors[${index}].color is ${JSON.stringify(value)}; use #rrggbb, e.g. "#1e40af".`);
36
- const n = parseInt(m[1], 16);
37
- return [(n >> 16 & 255) / 255, (n >> 8 & 255) / 255, (n & 255) / 255];
38
- }
39
- function toHex(rgb) {
40
- return "#" + rgb.map((v) => Math.round(Math.min(1, Math.max(0, v)) * 255).toString(16).padStart(2, "0")).join("");
41
- }
42
- function createPigmentTools() {
43
- const mixColors = {
44
- name: "mix_colors",
45
- title: "Mix colours like paint",
46
- description: "Mixes colours as paint would (model pigment, the default: Kubelka-Munk mixing over reflectance spectra, so blue and yellow make green and white lightens a colour into a tint instead of greying it), or as light on screen (model rgb: the weighted RGB average). Changes nothing. Returns mixed (#rrggbb, by the chosen model), the other model's result for comparison (rgbLerp and pigment), the normalised weights and the model.",
47
- inputSchema: {
48
- type: "object",
49
- properties: {
50
- colors: {
51
- type: "array",
52
- minItems: 1,
53
- maxItems: 16,
54
- description: "The paints to mix (1 to 16).",
55
- items: {
56
- type: "object",
57
- properties: {
58
- color: { type: "string", description: "Paint colour #rrggbb." },
59
- weight: { type: "number", minimum: 0, description: "Parts of this paint, any scale (e.g. 1 and 3 for a 1:3 mix). At least one weight must be above 0." },
60
- strength: {
61
- type: "number",
62
- exclusiveMinimum: 0,
63
- maximum: 100,
64
- description: "Tinting strength (default 1): each part counts as this many, so a strong dark paint (e.g. 4) tints a lot of white."
65
- }
66
- },
67
- required: ["color", "weight"],
68
- additionalProperties: false
69
- }
70
- },
71
- model: {
72
- type: "string",
73
- enum: ["pigment", "rgb"],
74
- description: "pigment (default): mix like paint (Kubelka-Munk), as the pigment blend mode, Mixer Brush and mixing pad do; rgb: average the RGB values, as normal blending and rgb mixing brushes do (strength is ignored)."
75
- }
76
- },
77
- required: ["colors"],
78
- additionalProperties: false
79
- },
80
- annotations: { title: "Mix colours like paint", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
81
- handler: (args) => {
82
- const items = args.colors;
83
- const rgbs = items.map((item, i) => parseHex(item.color, i));
84
- const total = items.reduce((sum, item) => sum + item.weight, 0);
85
- if (!(total > 0)) throw new Error("Every weight is 0; give at least one colour a weight above 0.");
86
- const pigments = rgbs.map((rgb2, i) => _chunk2VX55NFMcjs.createPigment.call(void 0, rgb2, { strength: items[i].strength }));
87
- const mixed = _chunk2VX55NFMcjs.mixPigments.call(void 0, pigments, items.map((item) => item.weight));
88
- const lerp = [0, 1, 2].map((c) => rgbs.reduce((sum, rgb2, i) => sum + rgb2[c] * items[i].weight, 0) / total);
89
- const rgb = args.model === "rgb";
90
- return {
91
- mixed: toHex(rgb ? lerp : mixed),
92
- rgbLerp: toHex(lerp),
93
- pigment: toHex(mixed),
94
- weights: items.map((item) => item.weight / total),
95
- model: rgb ? "rgb" : "kubelka-munk"
96
- };
97
- }
98
- };
99
- return [mixColors];
100
- }
101
-
102
- // src/paint/retouch.ts
103
- var TONE_RANGES = ["shadows", "midtones", "highlights"];
104
- function luma(r, g, b) {
105
- return 0.299 * r + 0.587 * g + 0.114 * b;
106
- }
107
- function dodgeBurnCurve(v, e, range, burn) {
108
- const x = Math.max(0, v);
109
- const k = Math.min(1, Math.max(0, e));
110
- const c = Math.min(1, x);
111
- if (range === "midtones") {
112
- const w2 = Math.min(1, Math.max(0, 4 * x * (1 - x)));
113
- return x + w2 * (Math.pow(c, burn ? 1 + k : 1 / (1 + k)) - x);
114
- }
115
- const w = range === "shadows" ? (1 - c) * (1 - c) : c * c;
116
- return burn ? x - k * w * x : x + k * w * (1 - c);
117
- }
118
- function compressGamut(c, l) {
119
- const L = Math.min(1, Math.max(0, l));
120
- const lo = Math.min(c[0], c[1], c[2]);
121
- const hi = Math.max(c[0], c[1], c[2]);
122
- let t = 1;
123
- if (hi > 1 && hi - L > 1e-9) t = Math.min(t, (1 - L) / (hi - L));
124
- if (lo < 0 && L - lo > 1e-9) t = Math.min(t, L / (L - lo));
125
- for (let i = 0; i < 3; i++) c[i] = L + (c[i] - L) * t;
126
- }
127
- function dodgeBurn(c, e, range, burn, protectTones) {
128
- if (!(e > 0)) return c;
129
- if (protectTones) {
130
- const l = luma(c[0], c[1], c[2]);
131
- const nl = dodgeBurnCurve(l, e, range, burn);
132
- if (l > 1e-6) for (let i = 0; i < 3; i++) c[i] *= nl / l;
133
- else c[0] = c[1] = c[2] = nl;
134
- compressGamut(c, nl);
135
- } else for (let i = 0; i < 3; i++) c[i] = dodgeBurnCurve(c[i], e, range, burn);
136
- return c;
137
- }
138
- function saturationOf(r, g, b) {
139
- const lo = Math.min(r, g, b);
140
- const hi = Math.max(r, g, b);
141
- return hi <= 1e-6 ? 0 : Math.min(1, Math.max(0, (hi - lo) / hi));
142
- }
143
- function sponge(c, amount, saturate, vibrance) {
144
- let a = Math.min(1, Math.max(0, amount));
145
- if (!(a > 0)) return c;
146
- if (vibrance) {
147
- const s = saturationOf(c[0], c[1], c[2]);
148
- a *= saturate ? 1 - s : 0.25 + 0.75 * s;
149
- }
150
- const l = luma(c[0], c[1], c[2]);
151
- const k = saturate ? 1 + a : 1 - a;
152
- for (let i = 0; i < 3; i++) c[i] = l + (c[i] - l) * k;
153
- compressGamut(c, l);
154
- return c;
155
- }
156
- function perDabStrength(e, spacing) {
157
- return 1 - Math.pow(1 - Math.min(1, Math.max(0, e)), Math.min(1, Math.max(0.01, spacing)));
158
- }
159
- var RETOUCH_SAMPLES = ["current", "current-below", "all"];
160
- var SPOT_HEAL_TYPES = ["proximity-match", "content-aware", "smooth"];
161
- var DEFAULT_RETOUCH = {
162
- aligned: true,
163
- sample: "current",
164
- spotType: "proximity-match",
165
- range: "midtones",
166
- exposure: 0.5,
167
- protectTones: true,
168
- spongeMode: "desaturate",
169
- vibrance: true,
170
- strength: 0.5,
171
- historySteps: 0
172
- };
173
- function normalizeRetouch(raw = {}, base = DEFAULT_RETOUCH) {
174
- const unit2 = (v, d) => typeof v === "number" && Number.isFinite(v) ? Math.min(1, Math.max(0, v)) : d;
175
- const bool = (v, d) => typeof v === "boolean" ? v : d;
176
- const pick = (v, all, d) => all.includes(v) ? v : d;
177
- return {
178
- aligned: bool(raw.aligned, base.aligned),
179
- sample: pick(raw.sample, RETOUCH_SAMPLES, base.sample),
180
- spotType: pick(raw.spotType, SPOT_HEAL_TYPES, base.spotType),
181
- range: pick(raw.range, TONE_RANGES, base.range),
182
- exposure: unit2(raw.exposure, base.exposure),
183
- protectTones: bool(raw.protectTones, base.protectTones),
184
- spongeMode: pick(raw.spongeMode, ["desaturate", "saturate"], base.spongeMode),
185
- vibrance: bool(raw.vibrance, base.vibrance),
186
- strength: unit2(raw.strength, base.strength),
187
- historySteps: typeof raw.historySteps === "number" && Number.isFinite(raw.historySteps) ? Math.min(1e3, Math.max(0, Math.round(raw.historySteps))) : base.historySteps
188
- };
189
- }
190
- function boxBlurPixels(data, w, h, n, r) {
191
- if (r < 1) return;
192
- if (n === 4) for (let i = 0; i < data.length; i += 4) for (let c = 0; c < 3; c++) data[i + c] *= data[i + 3] / 255;
193
- const tmp = new Float32Array(data.length);
194
- const k = 1 / (2 * r + 1);
195
- for (let y = 0; y < h; y++) {
196
- for (let x = 0; x < w; x++) {
197
- for (let c = 0; c < n; c++) {
198
- let s = 0;
199
- for (let d = -r; d <= r; d++) s += data[(y * w + Math.min(w - 1, Math.max(0, x + d))) * n + c];
200
- tmp[(y * w + x) * n + c] = s * k;
201
- }
202
- }
203
- }
204
- for (let y = 0; y < h; y++) {
205
- for (let x = 0; x < w; x++) {
206
- for (let c = 0; c < n; c++) {
207
- let s = 0;
208
- for (let d = -r; d <= r; d++) s += tmp[(Math.min(h - 1, Math.max(0, y + d)) * w + x) * n + c];
209
- data[(y * w + x) * n + c] = s * k;
210
- }
211
- }
212
- }
213
- if (n === 4) {
214
- for (let i = 0; i < data.length; i += 4) {
215
- const a = data[i + 3] / 255;
216
- for (let c = 0; c < 3; c++) data[i + c] = a > 0 ? data[i + c] / a : 0;
217
- }
218
- }
219
- }
220
- function retouchFilter(data, w, h, n, kind, radius = 2, amount = 1) {
221
- if (kind === "blur") {
222
- boxBlurPixels(data, w, h, n, radius);
223
- boxBlurPixels(data, w, h, n, radius);
224
- return;
225
- }
226
- const soft = data.slice();
227
- boxBlurPixels(soft, w, h, n, 1);
228
- for (let i = 0; i < data.length; i++) {
229
- if (n === 4 && (i & 3) === 3) continue;
230
- const v = data[i] + amount * (data[i] - soft[i]);
231
- data[i] = v > 0 ? v : 0;
232
- }
233
- }
234
- var IDENTITY_CLONE_TRANSFORM = { scaleX: 1, scaleY: 1, rotate: 0 };
235
- function isIdentityCloneTransform(t) {
236
- return t.scaleX === 1 && t.scaleY === 1 && (t.rotate % 360 + 360) % 360 === 0;
237
- }
238
- function cloneSamplePoint(t, source, anchor, x, y) {
239
- const a = -t.rotate * Math.PI / 180;
240
- const c = Math.cos(a);
241
- const s = Math.sin(a);
242
- const dx = x - anchor.x;
243
- const dy = y - anchor.y;
244
- return [source.x + (c * dx - s * dy) / t.scaleX, source.y + (s * dx + c * dy) / t.scaleY];
245
- }
246
- var TransformedPixelSource = (_class = class {
247
- constructor(inner, map) {;_class.prototype.__init.call(this);
248
- this.inner = inner;
249
- this.map = map;
250
- }
251
-
252
-
253
- __init() {this.px = [0, 0, 0, 0]}
254
- sample(x, y, out) {
255
- const [u, v] = this.map(x, y);
256
- const x0 = Math.floor(u);
257
- const y0 = Math.floor(v);
258
- const fx = u - x0;
259
- const fy = v - y0;
260
- let r = 0;
261
- let g = 0;
262
- let b = 0;
263
- let a = 0;
264
- for (let k = 0; k < 4; k++) {
265
- const w = (k & 1 ? fx : 1 - fx) * (k & 2 ? fy : 1 - fy);
266
- if (w <= 0) continue;
267
- if (!this.inner.sample(x0 + (k & 1), y0 + (k >> 1), this.px)) continue;
268
- const pa = this.px[3] * w;
269
- r += this.px[0] * pa;
270
- g += this.px[1] * pa;
271
- b += this.px[2] * pa;
272
- a += pa;
273
- }
274
- if (!(a > 0)) {
275
- out[0] = out[1] = out[2] = out[3] = 0;
276
- return false;
277
- }
278
- out[0] = r / a;
279
- out[1] = g / a;
280
- out[2] = b / a;
281
- out[3] = a;
282
- return true;
283
- }
284
- }, _class);
285
- var TilePixelSource = (_class2 = class {
286
- constructor(readTile, channels, offset = { x: 0, y: 0 }) {;_class2.prototype.__init2.call(this);_class2.prototype.__init3.call(this);_class2.prototype.__init4.call(this);
287
- this.readTile = readTile;
288
- this.channels = channels;
289
- this.offset = offset;
290
- }
291
-
292
-
293
-
294
- __init2() {this.cache = /* @__PURE__ */ new Map()}
295
- __init3() {this.lastKey = NaN}
296
- __init4() {this.last = null}
297
- sample(x, y, out) {
298
- const lx = x - this.offset.x;
299
- const ly = y - this.offset.y;
300
- const tx = Math.floor(lx / _chunk474IQG74cjs.TILE);
301
- const ty = Math.floor(ly / _chunk474IQG74cjs.TILE);
302
- const key = _chunk474IQG74cjs.tileKey.call(void 0, tx, ty);
303
- if (key !== this.lastKey) {
304
- let t2 = this.cache.get(key);
305
- if (t2 === void 0) {
306
- t2 = this.readTile(tx, ty);
307
- this.cache.set(key, t2);
308
- }
309
- this.last = t2;
310
- this.lastKey = key;
311
- }
312
- const t = this.last;
313
- if (!t) {
314
- out[0] = out[1] = out[2] = out[3] = 0;
315
- return false;
316
- }
317
- const p = (ly - ty * _chunk474IQG74cjs.TILE) * _chunk474IQG74cjs.TILE + (lx - tx * _chunk474IQG74cjs.TILE);
318
- if (this.channels === 1) {
319
- out[0] = out[1] = out[2] = t[p];
320
- out[3] = 255;
321
- return true;
322
- }
323
- const i = p * 4;
324
- out[0] = t[i];
325
- out[1] = t[i + 1];
326
- out[2] = t[i + 2];
327
- out[3] = t[i + 3];
328
- return out[3] > 0;
329
- }
330
- }, _class2);
331
- var RegionPixelSource = class {
332
- constructor(rect, data) {
333
- this.rect = rect;
334
- this.data = data;
335
- }
336
-
337
-
338
- sample(x, y, out) {
339
- const r = this.rect;
340
- const lx = x - r.x;
341
- const ly = y - r.y;
342
- if (lx < 0 || ly < 0 || lx >= r.width || ly >= r.height) {
343
- out[0] = out[1] = out[2] = out[3] = 0;
344
- return false;
345
- }
346
- const i = (ly * r.width + lx) * 4;
347
- out[0] = this.data[i];
348
- out[1] = this.data[i + 1];
349
- out[2] = this.data[i + 2];
350
- out[3] = this.data[i + 3];
351
- return out[3] > 0;
352
- }
353
- };
354
- function readSourceRegion(source, rect, dx = 0, dy = 0) {
355
- const out = new Float32Array(rect.width * rect.height * 4);
356
- const px = [0, 0, 0, 0];
357
- for (let y = 0; y < rect.height; y++) {
358
- for (let x = 0; x < rect.width; x++) {
359
- source.sample(rect.x + x + dx, rect.y + y + dy, px);
360
- const i = (y * rect.width + x) * 4;
361
- out[i] = px[0];
362
- out[i + 1] = px[1];
363
- out[i + 2] = px[2];
364
- out[i + 3] = px[3];
365
- }
366
- }
367
- return out;
368
- }
369
- function applyRetouchToTile(coverage, tileData, channels, tx, ty, paint, s, options = {}) {
370
- const out = (_nullishCoalesce(options.into, () => ( tileData))).slice();
371
- const ox = tx * _chunk474IQG74cjs.TILE + s.offset.x;
372
- const oy = ty * _chunk474IQG74cjs.TILE + s.offset.y;
373
- let x0 = 0;
374
- let y0 = 0;
375
- let x1 = _chunk474IQG74cjs.TILE;
376
- let y1 = _chunk474IQG74cjs.TILE;
377
- if (options.region) {
378
- const r = options.region;
379
- x0 = Math.max(0, Math.floor(r.x) - ox);
380
- y0 = Math.max(0, Math.floor(r.y) - oy);
381
- x1 = Math.min(_chunk474IQG74cjs.TILE, Math.ceil(r.x + r.width) - ox);
382
- y1 = Math.min(_chunk474IQG74cjs.TILE, Math.ceil(r.y + r.height) - oy);
383
- if (x1 <= x0 || y1 <= y0) return out;
384
- if (options.into) {
385
- for (let y = y0; y < y1; y++) out.set(tileData.subarray((y * _chunk474IQG74cjs.TILE + x0) * channels, (y * _chunk474IQG74cjs.TILE + x1) * channels), (y * _chunk474IQG74cjs.TILE + x0) * channels);
386
- }
387
- }
388
- const sel = s.selection;
389
- const blend = _nullishCoalesce(s.blend, () => ( "normal"));
390
- const src = [0, 0, 0, 0];
391
- const rgb = [0, 0, 0];
392
- const cb = [0, 0, 0, 0];
393
- const cs = [0, 0, 0, 0];
394
- let covKey = NaN;
395
- let covTile;
396
- for (let y = y0; y < y1; y++) {
397
- const dy = oy + y;
398
- const cty = Math.floor(dy / _chunk474IQG74cjs.TILE);
399
- for (let x = x0; x < x1; x++) {
400
- const dx = ox + x;
401
- const ctx = Math.floor(dx / _chunk474IQG74cjs.TILE);
402
- const key = _chunk474IQG74cjs.tileKey.call(void 0, ctx, cty);
403
- if (key !== covKey) {
404
- covKey = key;
405
- covTile = coverage.tiles.get(key);
406
- }
407
- if (!covTile) continue;
408
- const c = covTile[(dy - cty * _chunk474IQG74cjs.TILE) * _chunk474IQG74cjs.TILE + (dx - ctx * _chunk474IQG74cjs.TILE)];
409
- if (c <= 0) continue;
410
- let k = c * s.opacity;
411
- if (sel) {
412
- if (dx < 0 || dy < 0 || dx >= sel.width || dy >= sel.height) continue;
413
- k *= sel.data[dy * sel.width + dx] / 255;
414
- }
415
- if (k > 1) k = 1;
416
- if (k <= 0) continue;
417
- const p = y * _chunk474IQG74cjs.TILE + x;
418
- if (channels === 1) {
419
- const g = out[p];
420
- let t;
421
- if (paint.kind === "tone") {
422
- rgb[0] = rgb[1] = rgb[2] = g / 255;
423
- paint.tone(rgb);
424
- t = luma(rgb[0], rgb[1], rgb[2]) * 255;
425
- } else if (paint.kind === "color") t = paint.color[0];
426
- else {
427
- if (!paint.source.sample(dx + paint.dx, dy + paint.dy, src)) continue;
428
- t = src[0];
429
- k *= src[3] / 255;
430
- }
431
- out[p] = Math.round(g + (t - g) * k);
432
- continue;
433
- }
434
- const i = p * 4;
435
- const a = out[i + 3];
436
- if (paint.kind === "tone") {
437
- if (a === 0) continue;
438
- rgb[0] = out[i] / 255;
439
- rgb[1] = out[i + 1] / 255;
440
- rgb[2] = out[i + 2] / 255;
441
- const r0 = rgb[0];
442
- const g0 = rgb[1];
443
- const b0 = rgb[2];
444
- paint.tone(rgb);
445
- _chunkFQPUF2W2cjs.put255.call(void 0, out, i, r0 + (rgb[0] - r0) * k);
446
- _chunkFQPUF2W2cjs.put255.call(void 0, out, i + 1, g0 + (rgb[1] - g0) * k);
447
- _chunkFQPUF2W2cjs.put255.call(void 0, out, i + 2, b0 + (rgb[2] - b0) * k);
448
- continue;
449
- }
450
- if (s.lockTransparency && a === 0) continue;
451
- if (paint.kind === "color") {
452
- src[0] = paint.color[0];
453
- src[1] = paint.color[1];
454
- src[2] = paint.color[2];
455
- src[3] = paint.color[3];
456
- } else if (!paint.source.sample(dx + paint.dx, dy + paint.dy, src)) continue;
457
- for (let ch = 0; ch < 4; ch++) {
458
- cb[ch] = out[i + ch] / 255;
459
- cs[ch] = src[ch] / 255;
460
- }
461
- const o = _chunk2VX55NFMcjs.blendPixel.call(void 0, blend, cb, cs, k);
462
- _chunkFQPUF2W2cjs.put255.call(void 0, out, i, o[0]);
463
- _chunkFQPUF2W2cjs.put255.call(void 0, out, i + 1, o[1]);
464
- _chunkFQPUF2W2cjs.put255.call(void 0, out, i + 2, o[2]);
465
- if (!s.lockTransparency) _chunkFQPUF2W2cjs.put255.call(void 0, out, i + 3, o[3]);
466
- }
467
- }
468
- return out;
469
- }
470
- function applyToneToDeepTile(coverage, samples, tx, ty, tone, s, options = {}) {
471
- const linear = samples instanceof Float32Array;
472
- const out = (_nullishCoalesce(options.into, () => ( samples))).slice();
473
- const ox = tx * _chunk474IQG74cjs.TILE + s.offset.x;
474
- const oy = ty * _chunk474IQG74cjs.TILE + s.offset.y;
475
- let x0 = 0;
476
- let y0 = 0;
477
- let x1 = _chunk474IQG74cjs.TILE;
478
- let y1 = _chunk474IQG74cjs.TILE;
479
- if (options.region) {
480
- const r = options.region;
481
- x0 = Math.max(0, Math.floor(r.x) - ox);
482
- y0 = Math.max(0, Math.floor(r.y) - oy);
483
- x1 = Math.min(_chunk474IQG74cjs.TILE, Math.ceil(r.x + r.width) - ox);
484
- y1 = Math.min(_chunk474IQG74cjs.TILE, Math.ceil(r.y + r.height) - oy);
485
- if (x1 <= x0 || y1 <= y0) return out;
486
- if (options.into) for (let y = y0; y < y1; y++) out.set(samples.subarray((y * _chunk474IQG74cjs.TILE + x0) * 4, (y * _chunk474IQG74cjs.TILE + x1) * 4), (y * _chunk474IQG74cjs.TILE + x0) * 4);
487
- }
488
- const sel = s.selection;
489
- const rgb = [0, 0, 0];
490
- const before = [0, 0, 0];
491
- const excess = [0, 0, 0];
492
- let covKey = NaN;
493
- let covTile;
494
- for (let y = y0; y < y1; y++) {
495
- const dy = oy + y;
496
- const cty = Math.floor(dy / _chunk474IQG74cjs.TILE);
497
- for (let x = x0; x < x1; x++) {
498
- const dx = ox + x;
499
- const ctx = Math.floor(dx / _chunk474IQG74cjs.TILE);
500
- const key = _chunk474IQG74cjs.tileKey.call(void 0, ctx, cty);
501
- if (key !== covKey) {
502
- covKey = key;
503
- covTile = coverage.tiles.get(key);
504
- }
505
- if (!covTile) continue;
506
- const c = covTile[(dy - cty * _chunk474IQG74cjs.TILE) * _chunk474IQG74cjs.TILE + (dx - ctx * _chunk474IQG74cjs.TILE)];
507
- if (c <= 0) continue;
508
- let k = c * s.opacity;
509
- if (sel) {
510
- if (dx < 0 || dy < 0 || dx >= sel.width || dy >= sel.height) continue;
511
- k *= sel.data[dy * sel.width + dx] / 255;
512
- }
513
- if (k > 1) k = 1;
514
- if (k <= 0) continue;
515
- const i = (y * _chunk474IQG74cjs.TILE + x) * 4;
516
- if (out[i + 3] === 0) continue;
517
- for (let ch = 0; ch < 3; ch++) {
518
- const v = out[i + ch];
519
- if (linear) {
520
- excess[ch] = v > 1 ? v - 1 : 0;
521
- rgb[ch] = _chunk2VX55NFMcjs.srgbEncode.call(void 0, v > 1 ? 1 : v < 0 ? 0 : v);
522
- } else rgb[ch] = v / 65535;
523
- before[ch] = rgb[ch];
524
- }
525
- tone(rgb);
526
- for (let ch = 0; ch < 3; ch++) {
527
- const e = before[ch] + (rgb[ch] - before[ch]) * k;
528
- if (linear) out[i + ch] = _chunk2VX55NFMcjs.srgbDecode.call(void 0, e) + excess[ch];
529
- else out[i + ch] = e <= 0 ? 0 : e >= 1 ? 65535 : Math.round(e * 65535);
530
- }
531
- }
532
- }
533
- return out;
534
- }
535
- function toneOf(tool, settings) {
536
- const burn = tool === "burn";
537
- return (rgb) => {
538
- dodgeBurn(rgb, settings.exposure, settings.range, burn, settings.protectTones);
539
- };
540
- }
541
- function healPixels(w, h, src, dst, mask) {
542
- const out = new Float32Array(dst);
543
- const bb = _chunkBB6TR422cjs.maskBounds.call(void 0, w, h, mask);
544
- if (!bb) return out;
545
- const x0 = Math.max(0, bb[0] - 1);
546
- const y0 = Math.max(0, bb[1] - 1);
547
- const x1 = Math.min(w, bb[2] + 1);
548
- const y1 = Math.min(h, bb[3] + 1);
549
- const rw = x1 - x0;
550
- const rh = y1 - y0;
551
- const s = new Float32Array(rw * rh * 4);
552
- const d = new Float32Array(rw * rh * 4);
553
- const m = new Uint8Array(rw * rh);
554
- for (let y = 0; y < rh; y++) {
555
- for (let x = 0; x < rw; x++) {
556
- const gi = (y + y0) * w + x + x0;
557
- const li = y * rw + x;
558
- m[li] = mask[gi] ? 1 : 0;
559
- for (let c = 0; c < 4; c++) {
560
- s[li * 4 + c] = src[gi * 4 + c];
561
- d[li * 4 + c] = dst[gi * 4 + c];
562
- }
563
- }
564
- }
565
- const healed = _chunkBB6TR422cjs.seamlessClone.call(void 0, rw, rh, 4, s, d, m);
566
- for (let y = 0; y < rh; y++) {
567
- for (let x = 0; x < rw; x++) {
568
- const gi = ((y + y0) * w + x + x0) * 4;
569
- const li = (y * rw + x) * 4;
570
- for (let c = 0; c < 4; c++) out[gi + c] = Math.min(255, Math.max(0, healed[li + c]));
571
- }
572
- }
573
- return out;
574
- }
575
- function spotHealPixels(w, h, img, hole, size, type, onOffset) {
576
- const domain = _chunkBB6TR422cjs.dilateMask.call(void 0, w, h, hole, 2);
577
- const healMask = _chunkBB6TR422cjs.dilateMask.call(void 0, w, h, hole, 1);
578
- let filled = null;
579
- let bestFound = null;
580
- if (type === "proximity-match") {
581
- const ring = Math.min(16, Math.max(3, Math.floor(size / 8)));
582
- const off2 = _chunkBB6TR422cjs.bestOffset.call(void 0, w, h, 4, img, domain, ring, Math.floor(Math.max(w, h) / 2));
583
- if (off2) {
584
- bestFound = off2;
585
- filled = new Float32Array(img);
586
- const [ddx, ddy] = off2;
587
- for (let i = 0; i < w * h; i++) {
588
- if (!domain[i]) continue;
589
- const x = i % w + ddx;
590
- const y = Math.floor(i / w) + ddy;
591
- const j = (y * w + x) * 4;
592
- for (let c = 0; c < 4; c++) filled[i * 4 + c] = img[j + c];
593
- }
594
- }
595
- }
596
- _optionalChain([onOffset, 'optionalCall', _ => _(filled ? bestFound : null)]);
597
- if (!filled && type === "content-aware") filled = _chunkBB6TR422cjs.contentAwareFill.call(void 0, w, h, 4, img, domain);
598
- if (!filled) filled = _chunkBB6TR422cjs.membraneFill.call(void 0, w, h, 4, img, domain);
599
- return healPixels(w, h, filled, img, healMask);
600
- }
601
- function spotHealWindow(bounds, canvas) {
602
- const g = Math.max(8, Math.ceil(Math.max(bounds.width, bounds.height)));
603
- const x0 = Math.max(0, bounds.x - g);
604
- const y0 = Math.max(0, bounds.y - g);
605
- const x1 = Math.min(canvas.width, bounds.x + bounds.width + g);
606
- const y1 = Math.min(canvas.height, bounds.y + bounds.height + g);
607
- return { x: x0, y: y0, width: Math.max(0, x1 - x0), height: Math.max(0, y1 - y0) };
608
- }
609
- var RetouchDabStroke = (_class3 = class {
610
- constructor(brush, target, effect) {;_class3.prototype.__init5.call(this);_class3.prototype.__init6.call(this);_class3.prototype.__init7.call(this);_class3.prototype.__init8.call(this);
611
- this.brush = brush;
612
- this.effect = effect;
613
- this.walker = new (0, _chunkFQPUF2W2cjs.DabWalker)(brush);
614
- this.medium = new (0, _chunkFQPUF2W2cjs.TileMedium)(target);
615
- }
616
-
617
-
618
- __init5() {this.dabCount = 0}
619
- __init6() {this.bounds = null}
620
-
621
-
622
- __init7() {this.smoothPos = null}
623
- __init8() {this.buf = new Float32Array(0)}
624
- push(points) {
625
- const dabs = [];
626
- for (const p of points) this.walker.push(this.smooth(p), dabs);
627
- return this.paint(dabs);
628
- }
629
- finish(last) {
630
- const dabs = [];
631
- if (last && this.smoothPos && (this.smoothPos.x !== last.x || this.smoothPos.y !== last.y)) this.walker.push(last, dabs);
632
- this.walker.finish(dabs);
633
- return this.paint(dabs);
634
- }
635
- smooth(p) {
636
- const a = 1 - Math.min(0.95, Math.max(0, this.brush.smoothing));
637
- const cur = this.smoothPos;
638
- const n = cur && a < 1 ? { ...p, x: cur.x + (p.x - cur.x) * a, y: cur.y + (p.y - cur.y) * a } : p;
639
- this.smoothPos = n;
640
- return n;
641
- }
642
- paint(dabs) {
643
- const rects = [];
644
- for (const d of dabs) {
645
- const rect = _chunkFQPUF2W2cjs.dabRect.call(void 0, d, this.brush.hardness);
646
- const n = rect.width * rect.height;
647
- if (this.buf.length < n) this.buf = new Float32Array(n);
648
- const cov = this.buf.subarray(0, n);
649
- _chunkFQPUF2W2cjs.rasterizeDab.call(void 0, { ...d, alpha: 1 }, this.brush.hardness, rect, cov);
650
- this.medium.reset();
651
- this.effect(this.medium, d, rect, cov);
652
- rects.push(rect);
653
- this.bounds = unionRect(this.bounds, rect);
654
- this.dabCount++;
655
- }
656
- return rects;
657
- }
658
- }, _class3);
659
- function smudgeEffect(brush, strength, mixing = "rgb") {
660
- const s = Math.min(1, Math.max(0, strength));
661
- const tip = new (0, _chunkFQPUF2W2cjs.SmudgeTip)({ strength: s, length: s, mixing }, brush.size);
662
- return (medium, d, rect, cov) => tip.dab(medium, { x: d.x, y: d.y, radius: d.radius, opacity: d.opacity * d.alpha }, rect, cov);
663
- }
664
- function spongeEffect(brush, saturate, vibrance) {
665
- const rgb = [0, 0, 0];
666
- return (medium, d, rect, cov) => {
667
- const w = rect.width;
668
- for (let yy = 0; yy < rect.height; yy++) {
669
- for (let xx = 0; xx < w; xx++) {
670
- const cv = cov[yy * w + xx];
671
- if (cv <= 0) continue;
672
- const dx = rect.x + xx;
673
- const dy = rect.y + yy;
674
- const k = perDabStrength(cv * d.alpha * d.opacity * 0.5, brush.spacing) * medium.selectionAt(dx, dy);
675
- if (k <= 0) continue;
676
- const ri = medium.locate(dx, dy, false);
677
- if (ri < 0 || medium.pixels[ri + 3] === 0) continue;
678
- const i = medium.locate(dx, dy, true);
679
- const px = medium.pixels;
680
- rgb[0] = px[i] / 255;
681
- rgb[1] = px[i + 1] / 255;
682
- rgb[2] = px[i + 2] / 255;
683
- sponge(rgb, k, saturate, vibrance);
684
- _chunkFQPUF2W2cjs.put255.call(void 0, px, i, rgb[0]);
685
- _chunkFQPUF2W2cjs.put255.call(void 0, px, i + 1, rgb[1]);
686
- _chunkFQPUF2W2cjs.put255.call(void 0, px, i + 2, rgb[2]);
687
- }
688
- }
689
- };
690
- }
691
- function rgbaViewOfGrey(target) {
692
- const views = /* @__PURE__ */ new Map();
693
- const dirty = /* @__PURE__ */ new Map();
694
- const expand = (g) => {
695
- const out = new Uint8ClampedArray(g.length * 4);
696
- for (let i = 0; i < g.length; i++) {
697
- out[i * 4] = out[i * 4 + 1] = out[i * 4 + 2] = g[i];
698
- out[i * 4 + 3] = 255;
699
- }
700
- return out;
701
- };
702
- const view = {
703
- offset: target.offset,
704
- lockTransparency: true,
705
- selection: target.selection,
706
- readTile: (tx, ty) => {
707
- const key = _chunk474IQG74cjs.tileKey.call(void 0, tx, ty);
708
- let v = views.get(key);
709
- if (!v) {
710
- v = expand(_nullishCoalesce(target.readTile(tx, ty), () => ( new Uint8ClampedArray(_chunk474IQG74cjs.TILE * _chunk474IQG74cjs.TILE))));
711
- views.set(key, v);
712
- }
713
- return v;
714
- },
715
- writeTile: (tx, ty) => {
716
- const key = _chunk474IQG74cjs.tileKey.call(void 0, tx, ty);
717
- let v = views.get(key);
718
- if (!v) {
719
- v = expand(_nullishCoalesce(target.readTile(tx, ty), () => ( new Uint8ClampedArray(_chunk474IQG74cjs.TILE * _chunk474IQG74cjs.TILE))));
720
- views.set(key, v);
721
- }
722
- dirty.set(key, { tx, ty, data: v });
723
- return v;
724
- }
725
- };
726
- return {
727
- target: view,
728
- flush: () => {
729
- for (const { tx, ty, data } of dirty.values()) {
730
- const g = target.writeTile(tx, ty);
731
- for (let i = 0; i < g.length; i++) g[i] = data[i * 4];
732
- }
733
- dirty.clear();
734
- }
735
- };
736
- }
737
- function unionRect(a, b) {
738
- if (!a) return { ...b };
739
- const x = Math.min(a.x, b.x);
740
- const y = Math.min(a.y, b.y);
741
- 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 };
742
- }
743
-
744
- // src/paint/wet/model.ts
745
- var WET_TILE = 256;
746
- var SLOT_SIDE = 258;
747
- var PLANE = SLOT_SIDE * SLOT_SIDE;
748
- var PLANE_BYTES = PLANE * 4;
749
- var SET_PLANES = 19;
750
- var P_RHO = 9;
751
- var P_UX = 10;
752
- var P_UY = 11;
753
- var P_SW = 12;
754
- var P_P0 = 13;
755
- var P_L = P_P0 + 4;
756
- var P_EDGE = 18;
757
- var P_D0 = 2 * SET_PLANES;
758
- var P_DL = P_D0 + 4;
759
- var P_H = P_D0 + 5;
760
- var P_FX = P_H + 1;
761
- var P_FY = P_H + 2;
762
- var SLOT_PLANES = P_FY + 1;
763
- var SLOT_BYTES = SLOT_PLANES * PLANE_BYTES;
764
- var PIGMENT_CHANNELS = 4;
765
- var MASS_CHANNELS = 5;
766
- var EX = [0, 1, 0, -1, 0, 1, -1, -1, 1];
767
- var EY = [0, 0, 1, 0, -1, 1, 1, -1, -1];
768
- var OPP = [0, 3, 4, 1, 2, 7, 8, 5, 6];
769
- var W9 = [4 / 9, 1 / 9, 1 / 9, 1 / 9, 1 / 9, 1 / 36, 1 / 36, 1 / 36, 1 / 36];
770
- var DRY_EPS = 1e-3;
771
- var U_MAX = 0.25;
772
- var STRIP = 64;
773
- var MAX_BATCH = 32;
774
- var FREE_INTERVAL = 32;
775
- var FLAG_ALIVE = 1;
776
- var FLAG_LEFT = 2;
777
- var FLAG_RIGHT = 4;
778
- var FLAG_TOP = 8;
779
- var FLAG_BOTTOM = 16;
780
- var FLAG_WET = 32;
781
- var PARAM_FLOATS = 32;
782
- var PARAM = {
783
- omega: 0,
784
- tau: 1,
785
- evap: 2,
786
- edgeEvap: 3,
787
- // times the edge field
788
- mobility: 4,
789
- // half the pigment mobility (the face flux uses the sum of two velocities)
790
- depRate: 5,
791
- pickup: 6,
792
- absorption: 7,
793
- invCap: 8,
794
- blockScale: 9,
795
- rough: 10,
796
- pinT: 11,
797
- gx: 12,
798
- gy: 13,
799
- flowK: 14,
800
- granulation: 15,
801
- edgeDep: 16,
802
- // times the edge field
803
- bloom: 17,
804
- paperEvap: 18,
805
- hasFlow: 19,
806
- bleed: 20
807
- };
808
- var DEFAULT_WET_PARAMS = {
809
- viscosity: 0.3,
810
- evaporation: 0.45,
811
- edgeDarkening: 0.5,
812
- pigmentWeight: 0.3,
813
- granulation: 0.4,
814
- pickup: 0.2,
815
- fixture: 0.2,
816
- bloom: 0.4,
817
- bleed: 0.3
818
- };
819
- var WET_PARAM_KEYS = Object.keys(DEFAULT_WET_PARAMS);
820
- var DEFAULT_WET_PAPER = { absorption: 0.7, permeability: 0.5, roughness: 0.6 };
821
- var FLAT = { angle: 0, direction: 0 };
822
- var unit = (v, d) => typeof v === "number" && Number.isFinite(v) ? Math.min(1, Math.max(0, v)) : d;
823
- function normalizeWetParams(raw = {}, base = DEFAULT_WET_PARAMS) {
824
- const out = {};
825
- for (const k of WET_PARAM_KEYS) out[k] = unit(raw[k], base[k]);
826
- return out;
827
- }
828
- function normalizeTilt(raw = {}, base = FLAT) {
829
- const angle = typeof raw.angle === "number" && Number.isFinite(raw.angle) ? Math.min(90, Math.max(0, raw.angle)) : base.angle;
830
- let direction = typeof raw.direction === "number" && Number.isFinite(raw.direction) ? raw.direction : base.direction;
831
- direction = (direction % 360 + 360) % 360;
832
- return { angle, direction };
833
- }
834
- function latticeViscosity(v) {
835
- return 0.02 * Math.pow(75, v);
836
- }
837
- var PAPER_CAPACITY = 0.08;
838
- var MAX_TILT_ACCEL = 0.025;
839
- function packWetParams(params, paper, tilt, flowStrength, out = new Float32Array(PARAM_FLOATS)) {
840
- const nu = latticeViscosity(params.viscosity);
841
- const tau = 3 * nu + 0.5;
842
- const g = MAX_TILT_ACCEL * Math.sin(tilt.angle * Math.PI / 180);
843
- const dir = tilt.direction * Math.PI / 180;
844
- out.fill(0);
845
- out[PARAM.omega] = 1 / tau;
846
- out[PARAM.tau] = tau;
847
- out[PARAM.evap] = 1e-3 * params.evaporation * params.evaporation;
848
- out[PARAM.edgeEvap] = params.edgeDarkening * 12;
849
- out[PARAM.mobility] = 0.5 * (1 - 0.5 * params.pigmentWeight);
850
- out[PARAM.depRate] = 0.019 * params.fixture * (0.5 + params.pigmentWeight);
851
- out[PARAM.pickup] = 0.01 * params.pickup;
852
- out[PARAM.absorption] = 15e-4 * paper.absorption;
853
- out[PARAM.invCap] = 1 / PAPER_CAPACITY;
854
- out[PARAM.blockScale] = 0.05 * (1 - paper.permeability);
855
- out[PARAM.rough] = 0.15 * paper.roughness;
856
- out[PARAM.pinT] = 0.2;
857
- out[PARAM.gx] = -g * Math.sin(dir);
858
- out[PARAM.gy] = g * Math.cos(dir);
859
- out[PARAM.flowK] = flowStrength;
860
- out[PARAM.granulation] = 1.2 * params.granulation * paper.roughness;
861
- out[PARAM.edgeDep] = params.edgeDarkening * 3;
862
- out[PARAM.bloom] = 60 * params.bloom;
863
- out[PARAM.paperEvap] = 5e-4 * params.evaporation * params.evaporation;
864
- out[PARAM.hasFlow] = flowStrength !== 0 ? 1 : 0;
865
- out[PARAM.bleed] = 0.05 * params.bleed;
866
- return out;
867
- }
868
- function edgeBits(lx, ly) {
869
- let b = 0;
870
- if (lx < STRIP) b |= FLAG_LEFT;
871
- if (lx >= WET_TILE - STRIP) b |= FLAG_RIGHT;
872
- if (ly < STRIP) b |= FLAG_TOP;
873
- if (ly >= WET_TILE - STRIP) b |= FLAG_BOTTOM;
874
- return b;
875
- }
876
-
877
8
  // src/paint/wet/film.ts
878
9
  var PIGMENT_UNIT = 0.25;
879
10
  var HIDE = 1.5;
@@ -1200,6 +331,139 @@ function shadeLightTile(f, plane, side, d, p, dl, pl, src, out, w, h) {
1200
331
  return any;
1201
332
  }
1202
333
 
334
+ // src/paint/wet/model.ts
335
+ var WET_TILE = 256;
336
+ var SLOT_SIDE = 258;
337
+ var PLANE = SLOT_SIDE * SLOT_SIDE;
338
+ var PLANE_BYTES = PLANE * 4;
339
+ var SET_PLANES = 19;
340
+ var P_RHO = 9;
341
+ var P_UX = 10;
342
+ var P_UY = 11;
343
+ var P_SW = 12;
344
+ var P_P0 = 13;
345
+ var P_L = P_P0 + 4;
346
+ var P_EDGE = 18;
347
+ var P_D0 = 2 * SET_PLANES;
348
+ var P_DL = P_D0 + 4;
349
+ var P_H = P_D0 + 5;
350
+ var P_FX = P_H + 1;
351
+ var P_FY = P_H + 2;
352
+ var SLOT_PLANES = P_FY + 1;
353
+ var SLOT_BYTES = SLOT_PLANES * PLANE_BYTES;
354
+ var PIGMENT_CHANNELS = 4;
355
+ var MASS_CHANNELS = 5;
356
+ var EX = [0, 1, 0, -1, 0, 1, -1, -1, 1];
357
+ var EY = [0, 0, 1, 0, -1, 1, 1, -1, -1];
358
+ var OPP = [0, 3, 4, 1, 2, 7, 8, 5, 6];
359
+ var W9 = [4 / 9, 1 / 9, 1 / 9, 1 / 9, 1 / 9, 1 / 36, 1 / 36, 1 / 36, 1 / 36];
360
+ var DRY_EPS = 1e-3;
361
+ var U_MAX = 0.25;
362
+ var STRIP = 64;
363
+ var MAX_BATCH = 32;
364
+ var FREE_INTERVAL = 32;
365
+ var FLAG_ALIVE = 1;
366
+ var FLAG_LEFT = 2;
367
+ var FLAG_RIGHT = 4;
368
+ var FLAG_TOP = 8;
369
+ var FLAG_BOTTOM = 16;
370
+ var FLAG_WET = 32;
371
+ var PARAM_FLOATS = 32;
372
+ var PARAM = {
373
+ omega: 0,
374
+ tau: 1,
375
+ evap: 2,
376
+ edgeEvap: 3,
377
+ // times the edge field
378
+ mobility: 4,
379
+ // half the pigment mobility (the face flux uses the sum of two velocities)
380
+ depRate: 5,
381
+ pickup: 6,
382
+ absorption: 7,
383
+ invCap: 8,
384
+ blockScale: 9,
385
+ rough: 10,
386
+ pinT: 11,
387
+ gx: 12,
388
+ gy: 13,
389
+ flowK: 14,
390
+ granulation: 15,
391
+ edgeDep: 16,
392
+ // times the edge field
393
+ bloom: 17,
394
+ paperEvap: 18,
395
+ hasFlow: 19,
396
+ bleed: 20
397
+ };
398
+ var DEFAULT_WET_PARAMS = {
399
+ viscosity: 0.3,
400
+ evaporation: 0.45,
401
+ edgeDarkening: 0.5,
402
+ pigmentWeight: 0.3,
403
+ granulation: 0.4,
404
+ pickup: 0.2,
405
+ fixture: 0.2,
406
+ bloom: 0.4,
407
+ bleed: 0.3
408
+ };
409
+ var WET_PARAM_KEYS = Object.keys(DEFAULT_WET_PARAMS);
410
+ var DEFAULT_WET_PAPER = { absorption: 0.7, permeability: 0.5, roughness: 0.6 };
411
+ var FLAT = { angle: 0, direction: 0 };
412
+ var unit = (v, d) => typeof v === "number" && Number.isFinite(v) ? Math.min(1, Math.max(0, v)) : d;
413
+ function normalizeWetParams(raw = {}, base = DEFAULT_WET_PARAMS) {
414
+ const out = {};
415
+ for (const k of WET_PARAM_KEYS) out[k] = unit(raw[k], base[k]);
416
+ return out;
417
+ }
418
+ function normalizeTilt(raw = {}, base = FLAT) {
419
+ const angle = typeof raw.angle === "number" && Number.isFinite(raw.angle) ? Math.min(90, Math.max(0, raw.angle)) : base.angle;
420
+ let direction = typeof raw.direction === "number" && Number.isFinite(raw.direction) ? raw.direction : base.direction;
421
+ direction = (direction % 360 + 360) % 360;
422
+ return { angle, direction };
423
+ }
424
+ function latticeViscosity(v) {
425
+ return 0.02 * Math.pow(75, v);
426
+ }
427
+ var PAPER_CAPACITY = 0.08;
428
+ var MAX_TILT_ACCEL = 0.025;
429
+ function packWetParams(params, paper, tilt, flowStrength, out = new Float32Array(PARAM_FLOATS)) {
430
+ const nu = latticeViscosity(params.viscosity);
431
+ const tau = 3 * nu + 0.5;
432
+ const g = MAX_TILT_ACCEL * Math.sin(tilt.angle * Math.PI / 180);
433
+ const dir = tilt.direction * Math.PI / 180;
434
+ out.fill(0);
435
+ out[PARAM.omega] = 1 / tau;
436
+ out[PARAM.tau] = tau;
437
+ out[PARAM.evap] = 1e-3 * params.evaporation * params.evaporation;
438
+ out[PARAM.edgeEvap] = params.edgeDarkening * 12;
439
+ out[PARAM.mobility] = 0.5 * (1 - 0.5 * params.pigmentWeight);
440
+ out[PARAM.depRate] = 0.019 * params.fixture * (0.5 + params.pigmentWeight);
441
+ out[PARAM.pickup] = 0.01 * params.pickup;
442
+ out[PARAM.absorption] = 15e-4 * paper.absorption;
443
+ out[PARAM.invCap] = 1 / PAPER_CAPACITY;
444
+ out[PARAM.blockScale] = 0.05 * (1 - paper.permeability);
445
+ out[PARAM.rough] = 0.15 * paper.roughness;
446
+ out[PARAM.pinT] = 0.2;
447
+ out[PARAM.gx] = -g * Math.sin(dir);
448
+ out[PARAM.gy] = g * Math.cos(dir);
449
+ out[PARAM.flowK] = flowStrength;
450
+ out[PARAM.granulation] = 1.2 * params.granulation * paper.roughness;
451
+ out[PARAM.edgeDep] = params.edgeDarkening * 3;
452
+ out[PARAM.bloom] = 60 * params.bloom;
453
+ out[PARAM.paperEvap] = 5e-4 * params.evaporation * params.evaporation;
454
+ out[PARAM.hasFlow] = flowStrength !== 0 ? 1 : 0;
455
+ out[PARAM.bleed] = 0.05 * params.bleed;
456
+ return out;
457
+ }
458
+ function edgeBits(lx, ly) {
459
+ let b = 0;
460
+ if (lx < STRIP) b |= FLAG_LEFT;
461
+ if (lx >= WET_TILE - STRIP) b |= FLAG_RIGHT;
462
+ if (ly < STRIP) b |= FLAG_TOP;
463
+ if (ly >= WET_TILE - STRIP) b |= FLAG_BOTTOM;
464
+ return b;
465
+ }
466
+
1203
467
  // src/paint/wet/kernel.ts
1204
468
  var F = Math.fround;
1205
469
  var S = SLOT_SIDE;
@@ -1437,7 +701,7 @@ function wetSupport(simd = _nullishCoalesce(simdCache, () => ( typeof WebAssembl
1437
701
  const g = globalThis;
1438
702
  const sharedMemory = canShareMemory();
1439
703
  const workers = typeof g.Worker === "function" && typeof Blob === "function" && typeof URL !== "undefined" && typeof URL.createObjectURL === "function";
1440
- const cores = Math.max(1, Math.floor(_nullishCoalesce(_optionalChain([g, 'access', _2 => _2.navigator, 'optionalAccess', _3 => _3.hardwareConcurrency]), () => ( 1))));
704
+ const cores = Math.max(1, Math.floor(_nullishCoalesce(_optionalChain([g, 'access', _ => _.navigator, 'optionalAccess', _2 => _2.hardwareConcurrency]), () => ( 1))));
1441
705
  let message = null;
1442
706
  if (!simd) message = "This browser has no WebAssembly SIMD, so wet paint runs in plain JavaScript: it flows much more slowly (the results are the same).";
1443
707
  else if (workers && !sharedMemory)
@@ -1541,8 +805,8 @@ var WetWorkerPool = class _WetWorkerPool {
1541
805
  ready.push(
1542
806
  new Promise((resolve, reject) => {
1543
807
  w.onmessage = (e) => {
1544
- if (_optionalChain([e, 'access', _4 => _4.data, 'optionalAccess', _5 => _5.type]) === "ready") resolve();
1545
- else if (_optionalChain([e, 'access', _6 => _6.data, 'optionalAccess', _7 => _7.type]) === "error") reject(new Error(e.data.message));
808
+ if (_optionalChain([e, 'access', _3 => _3.data, 'optionalAccess', _4 => _4.type]) === "ready") resolve();
809
+ else if (_optionalChain([e, 'access', _5 => _5.data, 'optionalAccess', _6 => _6.type]) === "error") reject(new Error(e.data.message));
1546
810
  };
1547
811
  w.onerror = (e) => reject(new Error(e.message || "The wet-media worker failed to start."));
1548
812
  })
@@ -1564,8 +828,8 @@ var WetWorkerPool = class _WetWorkerPool {
1564
828
  this.workers.map(
1565
829
  (w, i) => new Promise((resolve, reject) => {
1566
830
  w.onmessage = (e) => {
1567
- if (_optionalChain([e, 'access', _8 => _8.data, 'optionalAccess', _9 => _9.type]) === "done") resolve();
1568
- else if (_optionalChain([e, 'access', _10 => _10.data, 'optionalAccess', _11 => _11.type]) === "error") reject(new Error(e.data.message));
831
+ if (_optionalChain([e, 'access', _7 => _7.data, 'optionalAccess', _8 => _8.type]) === "done") resolve();
832
+ else if (_optionalChain([e, 'access', _9 => _9.data, 'optionalAccess', _10 => _10.type]) === "error") reject(new Error(e.data.message));
1569
833
  };
1570
834
  w.postMessage({ type: "run", steps, workers: n, id: i });
1571
835
  })
@@ -1612,53 +876,53 @@ function makeLayout(width, height) {
1612
876
  function quantizeHeight(v) {
1613
877
  return Math.round(Math.min(1, Math.max(0, v)) * 65536) / 65536;
1614
878
  }
1615
- var WetWorld = (_class4 = class {
879
+ var WetWorld = (_class = class {
1616
880
 
1617
881
 
1618
882
 
1619
883
  /** Steps simulated so far. */
1620
- __init9() {this.clock = 0}
884
+ __init() {this.clock = 0}
1621
885
  /** Messages for the user (slots ran out, a backend failed). */
1622
- __init10() {this.warnings = []}
886
+ __init2() {this.warnings = []}
1623
887
 
1624
888
 
1625
889
 
1626
890
 
1627
891
 
1628
- __init11() {this.slotCount = 0}
1629
- __init12() {this.freeSlots = []}
1630
- __init13() {this.active = []}
1631
- __init14() {this.parity = 0}
1632
- __init15() {this.lanes = new Array(MAX_WET_LANES).fill(null)}
1633
- __init16() {this.tilt = { ...FLAT }}
892
+ __init3() {this.slotCount = 0}
893
+ __init4() {this.freeSlots = []}
894
+ __init5() {this.active = []}
895
+ __init6() {this.parity = 0}
896
+ __init7() {this.lanes = new Array(MAX_WET_LANES).fill(null)}
897
+ __init8() {this.tilt = { ...FLAT }}
1634
898
 
1635
- __init17() {this.paperBytes = new Uint8Array(3)}
1636
- __init18() {this.kind = "typescript"}
1637
- __init19() {this.wasm = null}
1638
- __init20() {this.pool = null}
1639
- __init21() {this.busyFlag = false}
1640
- __init22() {this.destroyed = false}
899
+ __init9() {this.paperBytes = new Uint8Array(3)}
900
+ __init10() {this.kind = "typescript"}
901
+ __init11() {this.wasm = null}
902
+ __init12() {this.pool = null}
903
+ __init13() {this.busyFlag = false}
904
+ __init14() {this.destroyed = false}
1641
905
 
1642
- __init23() {this.prm = new Float32Array(PARAM_FLOATS)}
906
+ __init15() {this.prm = new Float32Array(PARAM_FLOATS)}
1643
907
  // Engine B: the GPU mirror (see `attachGpu`).
1644
- __init24() {this.gpu = null}
908
+ __init16() {this.gpu = null}
1645
909
  /** Live tiles at which the GPU takes over the display (default 16: a fully wet 1024² canvas). */
1646
- __init25() {this.gpuMinTiles = 16}
1647
- __init26() {this.gpuLive = false}
1648
- __init27() {this.gpuFailure = null}
910
+ __init17() {this.gpuMinTiles = 16}
911
+ __init18() {this.gpuLive = false}
912
+ __init19() {this.gpuFailure = null}
1649
913
  /** Slot → rows (1..256, inclusive) to upload; `[0, 257]` means the whole slot. */
1650
- __init28() {this.gpuDirty = /* @__PURE__ */ new Map()}
1651
- __init29() {this.gpuParamsDirty = true}
914
+ __init20() {this.gpuDirty = /* @__PURE__ */ new Map()}
915
+ __init21() {this.gpuParamsDirty = true}
1652
916
  /**
1653
917
  * Lead mode (between strokes): a batch is not sent to the GPU all at once; `gpuLead` steps it
1654
918
  * frame by frame while the CPU works through it, so the display moves on before the CPU is done.
1655
919
  */
1656
- __init30() {this.gpuLeadMode = false}
920
+ __init22() {this.gpuLeadMode = false}
1657
921
  /** The batch the GPU is working through in lead mode. */
1658
- __init31() {this.gpuPlan = null}
922
+ __init23() {this.gpuPlan = null}
1659
923
  /** Resolves when the fastest available kernel is running (it may stay `typescript`). */
1660
924
 
1661
- constructor(width, height, paper, options = {}) {;_class4.prototype.__init9.call(this);_class4.prototype.__init10.call(this);_class4.prototype.__init11.call(this);_class4.prototype.__init12.call(this);_class4.prototype.__init13.call(this);_class4.prototype.__init14.call(this);_class4.prototype.__init15.call(this);_class4.prototype.__init16.call(this);_class4.prototype.__init17.call(this);_class4.prototype.__init18.call(this);_class4.prototype.__init19.call(this);_class4.prototype.__init20.call(this);_class4.prototype.__init21.call(this);_class4.prototype.__init22.call(this);_class4.prototype.__init23.call(this);_class4.prototype.__init24.call(this);_class4.prototype.__init25.call(this);_class4.prototype.__init26.call(this);_class4.prototype.__init27.call(this);_class4.prototype.__init28.call(this);_class4.prototype.__init29.call(this);_class4.prototype.__init30.call(this);_class4.prototype.__init31.call(this);
925
+ constructor(width, height, paper, options = {}) {;_class.prototype.__init.call(this);_class.prototype.__init2.call(this);_class.prototype.__init3.call(this);_class.prototype.__init4.call(this);_class.prototype.__init5.call(this);_class.prototype.__init6.call(this);_class.prototype.__init7.call(this);_class.prototype.__init8.call(this);_class.prototype.__init9.call(this);_class.prototype.__init10.call(this);_class.prototype.__init11.call(this);_class.prototype.__init12.call(this);_class.prototype.__init13.call(this);_class.prototype.__init14.call(this);_class.prototype.__init15.call(this);_class.prototype.__init16.call(this);_class.prototype.__init17.call(this);_class.prototype.__init18.call(this);_class.prototype.__init19.call(this);_class.prototype.__init20.call(this);_class.prototype.__init21.call(this);_class.prototype.__init22.call(this);_class.prototype.__init23.call(this);
1662
926
  if (!(width >= 1 && height >= 1 && width <= 16384 && height <= 16384)) throw new WetWorldError(`A wet canvas must be 1..16384 pixels per side, not ${width}\xD7${height}.`);
1663
927
  this.width = Math.round(width);
1664
928
  this.height = Math.round(height);
@@ -1713,7 +977,7 @@ var WetWorld = (_class4 = class {
1713
977
  }
1714
978
  /** The kernel in use and why it is not faster. */
1715
979
  backend() {
1716
- const threads = _nullishCoalesce(_optionalChain([this, 'access', _12 => _12.pool, 'optionalAccess', _13 => _13.size]), () => ( 1));
980
+ const threads = _nullishCoalesce(_optionalChain([this, 'access', _11 => _11.pool, 'optionalAccess', _12 => _12.size]), () => ( 1));
1717
981
  let message = this.support.message;
1718
982
  if (this.kind === "typescript" && !message) message = this.wasm ? null : "Wet paint runs in plain JavaScript until the WebAssembly kernel has loaded.";
1719
983
  if (this.kind === "wasm-threads") message = null;
@@ -1725,17 +989,17 @@ var WetWorld = (_class4 = class {
1725
989
  }
1726
990
  destroy() {
1727
991
  this.destroyed = true;
1728
- _optionalChain([this, 'access', _14 => _14.pool, 'optionalAccess', _15 => _15.destroy, 'call', _16 => _16()]);
992
+ _optionalChain([this, 'access', _13 => _13.pool, 'optionalAccess', _14 => _14.destroy, 'call', _15 => _15()]);
1729
993
  this.pool = null;
1730
994
  }
1731
995
  // --- Lanes ---------------------------------------------------------------------
1732
996
  laneOf(id) {
1733
- const l = this.lanes.find((x) => _optionalChain([x, 'optionalAccess', _17 => _17.id]) === id);
997
+ const l = this.lanes.find((x) => _optionalChain([x, 'optionalAccess', _16 => _16.id]) === id);
1734
998
  if (!l) throw new WetWorldError(`There is no wet layer "${id}".`);
1735
999
  return l;
1736
1000
  }
1737
1001
  hasLane(id) {
1738
- return this.lanes.some((x) => _optionalChain([x, 'optionalAccess', _18 => _18.id]) === id);
1002
+ return this.lanes.some((x) => _optionalChain([x, 'optionalAccess', _17 => _17.id]) === id);
1739
1003
  }
1740
1004
  laneIds() {
1741
1005
  return this.lanes.filter((l) => Boolean(l)).map((l) => l.id);
@@ -1743,7 +1007,7 @@ var WetWorld = (_class4 = class {
1743
1007
  /** Adds a wet layer (or returns it). Throws when `MAX_WET_LANES` are in use. */
1744
1008
  ensureLane(id, options = {}) {
1745
1009
  this.requireIdle();
1746
- const existing = this.lanes.find((x) => _optionalChain([x, 'optionalAccess', _19 => _19.id]) === id);
1010
+ const existing = this.lanes.find((x) => _optionalChain([x, 'optionalAccess', _18 => _18.id]) === id);
1747
1011
  if (existing) {
1748
1012
  if (options.params) this.setParams(id, options.params);
1749
1013
  if (options.base) this.setBase(id, options.base);
@@ -2437,7 +1701,7 @@ var WetWorld = (_class4 = class {
2437
1701
  if (!(a > 0)) return;
2438
1702
  const key = _chunk474IQG74cjs.tileKey.call(void 0, x >> 8, y >> 8);
2439
1703
  const li = (y & 255) * _chunk474IQG74cjs.TILE + (x & 255);
2440
- let lt = _optionalChain([lightTiles, 'optionalAccess', _20 => _20.get, 'call', _21 => _21(key)]);
1704
+ let lt = _optionalChain([lightTiles, 'optionalAccess', _19 => _19.get, 'call', _20 => _20(key)]);
2441
1705
  if (lt && (_nullishCoalesce(lt.uniform, () => ( 1))) !== 0) {
2442
1706
  if (!lightWritten.has(key)) {
2443
1707
  const data = lt.data.length ? new Uint8ClampedArray(lt.data) : new Uint8ClampedArray(_chunk474IQG74cjs.TILE * _chunk474IQG74cjs.TILE).fill(_nullishCoalesce(lt.uniform, () => ( 0)));
@@ -2510,7 +1774,7 @@ var WetWorld = (_class4 = class {
2510
1774
  if (x1 <= x0 || y1 <= y0) continue;
2511
1775
  const whole = x0 === tr.x && y0 === tr.y && x1 >= Math.min(tr.x + WET_TILE, this.width) && y1 >= Math.min(tr.y + WET_TILE, this.height);
2512
1776
  if (whole) {
2513
- if (this.bakeKey(key, true)) bounds = unionRect2(bounds, { x: tr.x, y: tr.y, width: Math.min(WET_TILE, this.width - tr.x), height: Math.min(WET_TILE, this.height - tr.y) });
1777
+ if (this.bakeKey(key, true)) bounds = unionRect(bounds, { x: tr.x, y: tr.y, width: Math.min(WET_TILE, this.width - tr.x), height: Math.min(WET_TILE, this.height - tr.y) });
2514
1778
  this.free(key);
2515
1779
  continue;
2516
1780
  }
@@ -2530,7 +1794,7 @@ var WetWorld = (_class4 = class {
2530
1794
  f[c + P_SW * PLANE] = 0;
2531
1795
  }
2532
1796
  }
2533
- bounds = unionRect2(bounds, { x: x0, y: y0, width: x1 - x0, height: y1 - y0 });
1797
+ bounds = unionRect(bounds, { x: x0, y: y0, width: x1 - x0, height: y1 - y0 });
2534
1798
  this.markEdited(lane, x0, y0, x1, y1);
2535
1799
  }
2536
1800
  this.syncList();
@@ -2558,7 +1822,7 @@ var WetWorld = (_class4 = class {
2558
1822
  lightChanged = true;
2559
1823
  }
2560
1824
  }
2561
- const src = _nullishCoalesce(_optionalChain([lane, 'access', _22 => _22.base, 'access', _23 => _23.tiles, 'access', _24 => _24.get, 'call', _25 => _25(tk), 'optionalAccess', _26 => _26.data]), () => ( null));
1825
+ const src = _nullishCoalesce(_optionalChain([lane, 'access', _21 => _21.base, 'access', _22 => _22.tiles, 'access', _23 => _23.get, 'call', _24 => _24(tk), 'optionalAccess', _25 => _25.data]), () => ( null));
2562
1826
  const out = this.shadeSlot(key, src, all ? "bake-all" : "bake");
2563
1827
  if (!out) return lightChanged;
2564
1828
  const tiles = new Map(lane.base.tiles);
@@ -2621,7 +1885,7 @@ var WetWorld = (_class4 = class {
2621
1885
  for (const key of this.active) {
2622
1886
  if (this.laneIndexOf(key) !== lane.index) continue;
2623
1887
  const tk = this.tileKeyOf(key);
2624
- const out = this.shadeSlot(key, _nullishCoalesce(_optionalChain([lane, 'access', _27 => _27.base, 'access', _28 => _28.tiles, 'access', _29 => _29.get, 'call', _30 => _30(tk), 'optionalAccess', _31 => _31.data]), () => ( null)), "bake-all");
1888
+ const out = this.shadeSlot(key, _nullishCoalesce(_optionalChain([lane, 'access', _26 => _26.base, 'access', _27 => _27.tiles, 'access', _28 => _28.get, 'call', _29 => _29(tk), 'optionalAccess', _30 => _30.data]), () => ( null)), "bake-all");
2625
1889
  if (!out) continue;
2626
1890
  const t = _chunk474IQG74cjs.finishTile.call(void 0, out, 4, 0);
2627
1891
  if (t) tiles.set(tk, t);
@@ -2744,14 +2008,14 @@ var WetWorld = (_class4 = class {
2744
2008
  display(id, maxTiles = Infinity) {
2745
2009
  const lane = this.laneOf(id);
2746
2010
  const keys = this.active.filter((k) => this.laneIndexOf(k) === lane.index);
2747
- const stale = keys.filter((k) => _optionalChain([lane, 'access', _32 => _32.shaded, 'access', _33 => _33.get, 'call', _34 => _34(this.tileKeyOf(k)), 'optionalAccess', _35 => _35.stamp]) !== lane.stamp);
2748
- stale.sort((a, b) => Number(lane.urgent.has(this.tileKeyOf(b))) - Number(lane.urgent.has(this.tileKeyOf(a))) || (_nullishCoalesce(_optionalChain([lane, 'access', _36 => _36.shaded, 'access', _37 => _37.get, 'call', _38 => _38(this.tileKeyOf(a)), 'optionalAccess', _39 => _39.stamp]), () => ( 0))) - (_nullishCoalesce(_optionalChain([lane, 'access', _40 => _40.shaded, 'access', _41 => _41.get, 'call', _42 => _42(this.tileKeyOf(b)), 'optionalAccess', _43 => _43.stamp]), () => ( 0))));
2011
+ const stale = keys.filter((k) => _optionalChain([lane, 'access', _31 => _31.shaded, 'access', _32 => _32.get, 'call', _33 => _33(this.tileKeyOf(k)), 'optionalAccess', _34 => _34.stamp]) !== lane.stamp);
2012
+ stale.sort((a, b) => Number(lane.urgent.has(this.tileKeyOf(b))) - Number(lane.urgent.has(this.tileKeyOf(a))) || (_nullishCoalesce(_optionalChain([lane, 'access', _35 => _35.shaded, 'access', _36 => _36.get, 'call', _37 => _37(this.tileKeyOf(a)), 'optionalAccess', _38 => _38.stamp]), () => ( 0))) - (_nullishCoalesce(_optionalChain([lane, 'access', _39 => _39.shaded, 'access', _40 => _40.get, 'call', _41 => _41(this.tileKeyOf(b)), 'optionalAccess', _42 => _42.stamp]), () => ( 0))));
2749
2013
  const changed = [];
2750
2014
  let done = 0;
2751
2015
  for (const key of stale) {
2752
2016
  if (done >= maxTiles) break;
2753
2017
  const tk = this.tileKeyOf(key);
2754
- const src = _nullishCoalesce(_optionalChain([lane, 'access', _44 => _44.base, 'access', _45 => _45.tiles, 'access', _46 => _46.get, 'call', _47 => _47(tk), 'optionalAccess', _48 => _48.data]), () => ( null));
2018
+ const src = _nullishCoalesce(_optionalChain([lane, 'access', _43 => _43.base, 'access', _44 => _44.tiles, 'access', _45 => _45.get, 'call', _46 => _46(tk), 'optionalAccess', _47 => _47.data]), () => ( null));
2755
2019
  const out = this.shadeSlot(key, src, "display");
2756
2020
  const tile = out ? _chunk474IQG74cjs.finishTile.call(void 0, out, 4, 0) : _nullishCoalesce(lane.base.tiles.get(tk), () => ( null));
2757
2021
  lane.shaded.set(tk, { stamp: lane.stamp, tile: _nullishCoalesce(tile, () => ( { data: new Uint8ClampedArray(0), uniform: 0 })) });
@@ -2788,7 +2052,7 @@ var WetWorld = (_class4 = class {
2788
2052
  for (const key2 of keys) {
2789
2053
  const tk = this.tileKeyOf(key2);
2790
2054
  live.add(tk);
2791
- if (_optionalChain([lane, 'access', _49 => _49.lightShaded, 'access', _50 => _50.get, 'call', _51 => _51(tk), 'optionalAccess', _52 => _52.stamp]) === lane.stamp) continue;
2055
+ if (_optionalChain([lane, 'access', _48 => _48.lightShaded, 'access', _49 => _49.get, 'call', _50 => _50(tk), 'optionalAccess', _51 => _51.stamp]) === lane.stamp) continue;
2792
2056
  const src = _nullishCoalesce(lane.light.tiles.get(tk), () => ( null));
2793
2057
  const out = this.shadeLightSlot(key2, src, "display");
2794
2058
  lane.lightShaded.set(tk, { stamp: lane.stamp, tile: out ? _chunk474IQG74cjs.finishTile.call(void 0, out, 1, 0) : src });
@@ -2986,7 +2250,7 @@ var WetWorld = (_class4 = class {
2986
2250
  if (!this.gpu || this.busyFlag && !plan || !plan && !this.gpuDecide()) return { ...this.display(id, maxCpuTiles), gpu: false };
2987
2251
  const lane = this.laneOf(id);
2988
2252
  const keys = this.active.filter((k) => this.laneIndexOf(k) === lane.index);
2989
- const stale = plan ? keys : keys.filter((k) => _optionalChain([lane, 'access', _53 => _53.shaded, 'access', _54 => _54.get, 'call', _55 => _55(this.tileKeyOf(k)), 'optionalAccess', _56 => _56.stamp]) !== lane.stamp);
2253
+ const stale = plan ? keys : keys.filter((k) => _optionalChain([lane, 'access', _52 => _52.shaded, 'access', _53 => _53.get, 'call', _54 => _54(this.tileKeyOf(k)), 'optionalAccess', _55 => _55.stamp]) !== lane.stamp);
2990
2254
  if (!stale.length) return { ...this.display(id, 0), gpu: true };
2991
2255
  let tiles;
2992
2256
  const stamp = lane.stamp;
@@ -2994,7 +2258,7 @@ var WetWorld = (_class4 = class {
2994
2258
  try {
2995
2259
  if (!plan) this.gpuSync();
2996
2260
  const parity = plan ? plan.parity + plan.done & 1 : this.parity;
2997
- tiles = await this.gpu.shade(this.gpuJobs(stale), parity, stale.map((k) => _nullishCoalesce(_optionalChain([base, 'access', _57 => _57.tiles, 'access', _58 => _58.get, 'call', _59 => _59(this.tileKeyOf(k)), 'optionalAccess', _60 => _60.data]), () => ( null))), [this.paperBytes[0], this.paperBytes[1], this.paperBytes[2]]);
2261
+ tiles = await this.gpu.shade(this.gpuJobs(stale), parity, stale.map((k) => _nullishCoalesce(_optionalChain([base, 'access', _56 => _56.tiles, 'access', _57 => _57.get, 'call', _58 => _58(this.tileKeyOf(k)), 'optionalAccess', _59 => _59.data]), () => ( null))), [this.paperBytes[0], this.paperBytes[1], this.paperBytes[2]]);
2998
2262
  } catch (e) {
2999
2263
  this.gpuStop(`Wet paint stopped using the GPU (${e.message}).`);
3000
2264
  return { ...this.display(id, maxCpuTiles), gpu: false };
@@ -3076,7 +2340,7 @@ var WetWorld = (_class4 = class {
3076
2340
  const slot = this.slotOf(lane.index * this.layout.perLane + ty * this.layout.tilesX + tx);
3077
2341
  return slot < 0 ? -1 : this.slotBase(slot);
3078
2342
  }
3079
- }, _class4);
2343
+ }, _class);
3080
2344
  function moveWetSnapshot(snap, from, to, dx, dy, lane = () => ({})) {
3081
2345
  if (!Number.isInteger(dx / WET_TILE) || !Number.isInteger(dy / WET_TILE)) throw new WetWorldError(`Wet paint moves by whole ${WET_TILE} px tiles, not (${dx}, ${dy}).`);
3082
2346
  const a = makeLayout(from.width, from.height);
@@ -3100,7 +2364,7 @@ function moveWetSnapshot(snap, from, to, dx, dy, lane = () => ({})) {
3100
2364
  });
3101
2365
  return { clock: snap.clock, tilt: { ...snap.tilt }, lanes, slots, bytes };
3102
2366
  }
3103
- function unionRect2(a, b) {
2367
+ function unionRect(a, b) {
3104
2368
  if (!a) return { ...b };
3105
2369
  const x = Math.min(a.x, b.x);
3106
2370
  const y = Math.min(a.y, b.y);
@@ -3173,8 +2437,8 @@ function normalizeFlow(raw = {}, base = DEFAULT_FLOW) {
3173
2437
  }
3174
2438
  function flowField(spec, width, height) {
3175
2439
  const k = FLOW_ACCEL;
3176
- const cx = _nullishCoalesce(_optionalChain([spec, 'access', _61 => _61.center, 'optionalAccess', _62 => _62.x]), () => ( width / 2));
3177
- const cy = _nullishCoalesce(_optionalChain([spec, 'access', _63 => _63.center, 'optionalAccess', _64 => _64.y]), () => ( height / 2));
2440
+ const cx = _nullishCoalesce(_optionalChain([spec, 'access', _60 => _60.center, 'optionalAccess', _61 => _61.x]), () => ( width / 2));
2441
+ const cy = _nullishCoalesce(_optionalChain([spec, 'access', _62 => _62.center, 'optionalAccess', _63 => _63.y]), () => ( height / 2));
3178
2442
  const r0 = Math.max(width, height) / 2;
3179
2443
  switch (spec.kind) {
3180
2444
  case "none":
@@ -3206,8 +2470,8 @@ function flowField(spec, width, height) {
3206
2470
 
3207
2471
  // src/paint/wet/medium.ts
3208
2472
  var SAMPLE_K = 3;
3209
- var WetMedium = (_class5 = class {
3210
- constructor(world, laneId, options) {;_class5.prototype.__init32.call(this);
2473
+ var WetMedium = (_class2 = class {
2474
+ constructor(world, laneId, options) {;_class2.prototype.__init24.call(this);
3211
2475
  this.world = world;
3212
2476
  this.laneId = laneId;
3213
2477
  this.options = options;
@@ -3215,7 +2479,7 @@ var WetMedium = (_class5 = class {
3215
2479
 
3216
2480
 
3217
2481
 
3218
- __init32() {this.pig = new Float64Array(4)}
2482
+ __init24() {this.pig = new Float64Array(4)}
3219
2483
  sample(rect, cov) {
3220
2484
  const s = this.world.sample(this.laneId, rect, cov);
3221
2485
  if (!(s.wet > 0) || !(s.weight > 0)) return null;
@@ -3248,7 +2512,7 @@ var WetMedium = (_class5 = class {
3248
2512
  const pig = [0, 1, 2, 3].map((q) => this.pig[q] * mass * dep);
3249
2513
  this.world.paint(this.laneId, rect, cov, water * dep, mass > 0 ? pig : null, null, light);
3250
2514
  }
3251
- }, _class5);
2515
+ }, _class2);
3252
2516
 
3253
2517
  // src/paint/wet/gpu-kernels.ts
3254
2518
  var GPU_JOB_WORDS = 16;
@@ -3637,7 +2901,7 @@ var UNIFORM = 64;
3637
2901
  var STORAGE = 128;
3638
2902
  function findWebGpu() {
3639
2903
  const nav = globalThis.navigator;
3640
- return _nullishCoalesce(_optionalChain([nav, 'optionalAccess', _65 => _65.gpu]), () => ( null));
2904
+ return _nullishCoalesce(_optionalChain([nav, 'optionalAccess', _64 => _64.gpu]), () => ( null));
3641
2905
  }
3642
2906
  async function createWetGpuEngine(gpu = findWebGpu()) {
3643
2907
  const no = (reason, adapter2 = null) => ({ engine: null, support: { supported: false, reason, adapter: adapter2, maxSlots: 0 } });
@@ -3649,7 +2913,7 @@ async function createWetGpuEngine(gpu = findWebGpu()) {
3649
2913
  return no(`WebGPU gave no adapter (${e.message}); wet paint runs on the CPU.`);
3650
2914
  }
3651
2915
  if (!adapter) return no("WebGPU gave no adapter (the GPU may be blocklisted); wet paint runs on the CPU.");
3652
- const name = [_optionalChain([adapter, 'access', _66 => _66.info, 'optionalAccess', _67 => _67.vendor]), _optionalChain([adapter, 'access', _68 => _68.info, 'optionalAccess', _69 => _69.architecture])].filter(Boolean).join(" ") || null;
2916
+ const name = [_optionalChain([adapter, 'access', _65 => _65.info, 'optionalAccess', _66 => _66.vendor]), _optionalChain([adapter, 'access', _67 => _67.info, 'optionalAccess', _68 => _68.architecture])].filter(Boolean).join(" ") || null;
3653
2917
  const binding = Math.min(_nullishCoalesce(adapter.limits.maxStorageBufferBindingSize, () => ( 0)), _nullishCoalesce(adapter.limits.maxBufferSize, () => ( 0)));
3654
2918
  const maxSlots = Math.min(MAX_WET_SLOTS, Math.floor(binding / SLOT_BYTES));
3655
2919
  if (maxSlots < 4) return no(`The GPU's storage buffers hold ${Math.max(0, maxSlots)} wet tiles; at least 4 are needed. Wet paint runs on the CPU.`, name);
@@ -3669,32 +2933,32 @@ async function createWetGpuEngine(gpu = findWebGpu()) {
3669
2933
  const engine = await WetGpuEngine.start(device, maxSlots, name);
3670
2934
  return { engine, support: { supported: true, reason: null, adapter: name, maxSlots } };
3671
2935
  } catch (e) {
3672
- _optionalChain([device, 'access', _70 => _70.destroy, 'optionalCall', _71 => _71()]);
2936
+ _optionalChain([device, 'access', _69 => _69.destroy, 'optionalCall', _70 => _70()]);
3673
2937
  return no(`The wet-media shaders did not compile on this GPU (${e.message}); wet paint runs on the CPU.`, name);
3674
2938
  }
3675
2939
  }
3676
2940
  async function wetGpuSupport(gpu = findWebGpu()) {
3677
2941
  const { engine, support } = await createWetGpuEngine(gpu);
3678
- _optionalChain([engine, 'optionalAccess', _72 => _72.destroy, 'call', _73 => _73()]);
2942
+ _optionalChain([engine, 'optionalAccess', _71 => _71.destroy, 'call', _72 => _72()]);
3679
2943
  return support;
3680
2944
  }
3681
2945
  async function pipeline(device, code, label) {
3682
- _optionalChain([device, 'access', _74 => _74.pushErrorScope, 'optionalCall', _75 => _75("validation")]);
2946
+ _optionalChain([device, 'access', _73 => _73.pushErrorScope, 'optionalCall', _74 => _74("validation")]);
3683
2947
  const module = device.createShaderModule({ code, label });
3684
- const info = await _optionalChain([module, 'access', _76 => _76.getCompilationInfo, 'optionalCall', _77 => _77()]);
3685
- const errors = _nullishCoalesce(_optionalChain([info, 'optionalAccess', _78 => _78.messages, 'access', _79 => _79.filter, 'call', _80 => _80((m) => m.type === "error")]), () => ( []));
2948
+ const info = await _optionalChain([module, 'access', _75 => _75.getCompilationInfo, 'optionalCall', _76 => _76()]);
2949
+ const errors = _nullishCoalesce(_optionalChain([info, 'optionalAccess', _77 => _77.messages, 'access', _78 => _78.filter, 'call', _79 => _79((m) => m.type === "error")]), () => ( []));
3686
2950
  if (errors.length) {
3687
- await _optionalChain([device, 'access', _81 => _81.popErrorScope, 'optionalCall', _82 => _82()]);
2951
+ await _optionalChain([device, 'access', _80 => _80.popErrorScope, 'optionalCall', _81 => _81()]);
3688
2952
  throw new Error(`${label}: ${errors.map((m) => `line ${m.lineNum}: ${m.message}`).join("; ")}`);
3689
2953
  }
3690
2954
  const desc = { layout: "auto", compute: { module, entryPoint: "main" }, label };
3691
2955
  const p = device.createComputePipelineAsync ? await device.createComputePipelineAsync(desc) : device.createComputePipeline(desc);
3692
- const err = await _optionalChain([device, 'access', _83 => _83.popErrorScope, 'optionalCall', _84 => _84()]);
2956
+ const err = await _optionalChain([device, 'access', _82 => _82.popErrorScope, 'optionalCall', _83 => _83()]);
3693
2957
  if (err) throw new Error(`${label}: ${err.message}`);
3694
2958
  return p;
3695
2959
  }
3696
- var WetGpuEngine = (_class6 = class _WetGpuEngine {
3697
- constructor(device, maxSlots, adapter, stepPipe, haloPipe, shadePipe) {;_class6.prototype.__init33.call(this);_class6.prototype.__init34.call(this);_class6.prototype.__init35.call(this);_class6.prototype.__init36.call(this);_class6.prototype.__init37.call(this);_class6.prototype.__init38.call(this);_class6.prototype.__init39.call(this);_class6.prototype.__init40.call(this);_class6.prototype.__init41.call(this);
2960
+ var WetGpuEngine = (_class3 = class _WetGpuEngine {
2961
+ constructor(device, maxSlots, adapter, stepPipe, haloPipe, shadePipe) {;_class3.prototype.__init25.call(this);_class3.prototype.__init26.call(this);_class3.prototype.__init27.call(this);_class3.prototype.__init28.call(this);_class3.prototype.__init29.call(this);_class3.prototype.__init30.call(this);_class3.prototype.__init31.call(this);_class3.prototype.__init32.call(this);_class3.prototype.__init33.call(this);
3698
2962
  this.device = device;
3699
2963
  this.maxSlots = maxSlots;
3700
2964
  this.adapter = adapter;
@@ -3715,8 +2979,8 @@ var WetGpuEngine = (_class6 = class _WetGpuEngine {
3715
2979
  return b;
3716
2980
  });
3717
2981
  this.shadeUni = d.createBuffer({ size: 16, usage: UNIFORM | COPY_DST, label: "wet shade" });
3718
- void _optionalChain([device, 'access', _85 => _85.lost, 'optionalAccess', _86 => _86.then, 'call', _87 => _87((info) => {
3719
- this.lostReason = _optionalChain([info, 'optionalAccess', _88 => _88.message]) || _optionalChain([info, 'optionalAccess', _89 => _89.reason]) || "the GPU device was lost";
2982
+ void _optionalChain([device, 'access', _84 => _84.lost, 'optionalAccess', _85 => _85.then, 'call', _86 => _86((info) => {
2983
+ this.lostReason = _optionalChain([info, 'optionalAccess', _87 => _87.message]) || _optionalChain([info, 'optionalAccess', _88 => _88.reason]) || "the GPU device was lost";
3720
2984
  })]);
3721
2985
  }
3722
2986
 
@@ -3726,23 +2990,23 @@ var WetGpuEngine = (_class6 = class _WetGpuEngine {
3726
2990
 
3727
2991
 
3728
2992
  /** Steps run on the GPU so far (for stats). */
3729
- __init33() {this.steps = 0}
2993
+ __init25() {this.steps = 0}
3730
2994
  /** Set once the device is lost; the engine does nothing after that. */
3731
- __init34() {this.lostReason = null}
2995
+ __init26() {this.lostReason = null}
3732
2996
 
3733
- __init35() {this.slots = 0}
2997
+ __init27() {this.slots = 0}
3734
2998
 
3735
2999
 
3736
- __init36() {this.jobCap = 0}
3000
+ __init28() {this.jobCap = 0}
3737
3001
 
3738
3002
 
3739
3003
 
3740
3004
 
3741
- __init37() {this.srcTiles = null}
3742
- __init38() {this.outTiles = null}
3743
- __init39() {this.outRead = null}
3744
- __init40() {this.tileCap = 0}
3745
- __init41() {this.groups = null}
3005
+ __init29() {this.srcTiles = null}
3006
+ __init30() {this.outTiles = null}
3007
+ __init31() {this.outRead = null}
3008
+ __init32() {this.tileCap = 0}
3009
+ __init33() {this.groups = null}
3746
3010
  /** @internal Compiles the kernels; use `createWetGpuEngine`. */
3747
3011
  static async start(device, maxSlots, adapter) {
3748
3012
  const [step, halo, shade] = await Promise.all([pipeline(device, WGSL_STEP, "wet step"), pipeline(device, WGSL_HALO, "wet halo"), pipeline(device, WGSL_SHADE, "wet shade")]);
@@ -3750,7 +3014,7 @@ var WetGpuEngine = (_class6 = class _WetGpuEngine {
3750
3014
  }
3751
3015
  /** Bytes of GPU memory in use. */
3752
3016
  memoryBytes() {
3753
- return this.state.size + this.jobs.size + (_nullishCoalesce(_optionalChain([this, 'access', _90 => _90.srcTiles, 'optionalAccess', _91 => _91.size]), () => ( 0))) + (_nullishCoalesce(_optionalChain([this, 'access', _92 => _92.outTiles, 'optionalAccess', _93 => _93.size]), () => ( 0))) * 2;
3017
+ return this.state.size + this.jobs.size + (_nullishCoalesce(_optionalChain([this, 'access', _89 => _89.srcTiles, 'optionalAccess', _90 => _90.size]), () => ( 0))) + (_nullishCoalesce(_optionalChain([this, 'access', _91 => _91.outTiles, 'optionalAccess', _92 => _92.size]), () => ( 0))) * 2;
3754
3018
  }
3755
3019
  /** Slots the state buffer holds now. */
3756
3020
  get capacity() {
@@ -3899,9 +3163,9 @@ var WetGpuEngine = (_class6 = class _WetGpuEngine {
3899
3163
  const d = this.device;
3900
3164
  const tileBytes = TILE_WORDS * 4;
3901
3165
  if (n > this.tileCap || !this.outTiles || !this.outRead || !this.srcTiles) {
3902
- _optionalChain([this, 'access', _94 => _94.srcTiles, 'optionalAccess', _95 => _95.destroy, 'call', _96 => _96()]);
3903
- _optionalChain([this, 'access', _97 => _97.outTiles, 'optionalAccess', _98 => _98.destroy, 'call', _99 => _99()]);
3904
- _optionalChain([this, 'access', _100 => _100.outRead, 'optionalAccess', _101 => _101.destroy, 'call', _102 => _102()]);
3166
+ _optionalChain([this, 'access', _93 => _93.srcTiles, 'optionalAccess', _94 => _94.destroy, 'call', _95 => _95()]);
3167
+ _optionalChain([this, 'access', _96 => _96.outTiles, 'optionalAccess', _97 => _97.destroy, 'call', _98 => _98()]);
3168
+ _optionalChain([this, 'access', _99 => _99.outRead, 'optionalAccess', _100 => _100.destroy, 'call', _101 => _101()]);
3905
3169
  this.tileCap = Math.max(n, this.tileCap * 2, 4);
3906
3170
  this.srcTiles = d.createBuffer({ size: this.tileCap * tileBytes, usage: STORAGE | COPY_DST, label: "wet base tiles" });
3907
3171
  this.outTiles = d.createBuffer({ size: this.tileCap * tileBytes, usage: STORAGE | COPY_SRC, label: "wet shaded tiles" });
@@ -3955,69 +3219,10 @@ var WetGpuEngine = (_class6 = class _WetGpuEngine {
3955
3219
  return this.device.queue.onSubmittedWorkDone();
3956
3220
  }
3957
3221
  destroy() {
3958
- for (const b of [this.state, this.params, this.jobs, this.flags, this.flagsRead, ...this.uni, this.shadeUni, this.srcTiles, this.outTiles, this.outRead]) _optionalChain([b, 'optionalAccess', _103 => _103.destroy, 'call', _104 => _104()]);
3222
+ for (const b of [this.state, this.params, this.jobs, this.flags, this.flagsRead, ...this.uni, this.shadeUni, this.srcTiles, this.outTiles, this.outRead]) _optionalChain([b, 'optionalAccess', _102 => _102.destroy, 'call', _103 => _103()]);
3959
3223
  this.device.destroy();
3960
3224
  }
3961
- }, _class6);
3962
-
3963
- // src/paint/pointer.ts
3964
- function pointerPressure(e) {
3965
- if (e.pointerType === "pen" && typeof e.pressure === "number" && e.pressure > 0) return Math.min(1, e.pressure);
3966
- return 1;
3967
- }
3968
- function pointerStrokeSample(e, toPoint) {
3969
- const p = toPoint(e.clientX, e.clientY);
3970
- const s = { x: p.x, y: p.y, pressure: pointerPressure(e) };
3971
- if (typeof e.timeStamp === "number" && Number.isFinite(e.timeStamp)) s.t = e.timeStamp;
3972
- if (e.pointerType === "pen") {
3973
- if (typeof e.altitudeAngle === "number" && e.altitudeAngle < Math.PI / 2 - 1e-6) {
3974
- s.altitude = e.altitudeAngle;
3975
- s.azimuth = _nullishCoalesce(e.azimuthAngle, () => ( 0));
3976
- } else if (e.tiltX || e.tiltY) {
3977
- s.tiltX = _nullishCoalesce(e.tiltX, () => ( 0));
3978
- s.tiltY = _nullishCoalesce(e.tiltY, () => ( 0));
3979
- }
3980
- }
3981
- return s;
3982
- }
3983
- function pointerStrokeSamples(e, toPoint) {
3984
- const events = _nullishCoalesce(_optionalChain([e, 'access', _105 => _105.getCoalescedEvents, 'optionalCall', _106 => _106()]), () => ( []));
3985
- return (events.length ? events : [e]).map((ev) => pointerStrokeSample(ev, toPoint));
3986
- }
3987
-
3988
-
3989
-
3990
-
3991
-
3992
-
3993
-
3994
-
3995
-
3996
-
3997
-
3998
-
3999
-
4000
-
4001
-
4002
-
4003
-
4004
-
4005
-
4006
-
4007
-
4008
-
4009
-
4010
-
4011
-
4012
-
4013
-
4014
-
4015
-
4016
-
4017
-
4018
-
4019
-
4020
-
3225
+ }, _class3);
4021
3226
 
4022
3227
 
4023
3228
 
@@ -4110,4 +3315,4 @@ function pointerStrokeSamples(e, toPoint) {
4110
3315
 
4111
3316
 
4112
3317
 
4113
- exports.createPigmentTools = createPigmentTools; exports.TONE_RANGES = TONE_RANGES; exports.luma = luma; exports.dodgeBurnCurve = dodgeBurnCurve; exports.dodgeBurn = dodgeBurn; exports.saturationOf = saturationOf; exports.sponge = sponge; exports.perDabStrength = perDabStrength; exports.RETOUCH_SAMPLES = RETOUCH_SAMPLES; exports.SPOT_HEAL_TYPES = SPOT_HEAL_TYPES; exports.DEFAULT_RETOUCH = DEFAULT_RETOUCH; exports.normalizeRetouch = normalizeRetouch; exports.boxBlurPixels = boxBlurPixels; exports.retouchFilter = retouchFilter; exports.IDENTITY_CLONE_TRANSFORM = IDENTITY_CLONE_TRANSFORM; exports.isIdentityCloneTransform = isIdentityCloneTransform; exports.cloneSamplePoint = cloneSamplePoint; exports.TransformedPixelSource = TransformedPixelSource; exports.TilePixelSource = TilePixelSource; exports.RegionPixelSource = RegionPixelSource; exports.readSourceRegion = readSourceRegion; exports.applyRetouchToTile = applyRetouchToTile; exports.applyToneToDeepTile = applyToneToDeepTile; exports.toneOf = toneOf; exports.healPixels = healPixels; exports.spotHealPixels = spotHealPixels; exports.spotHealWindow = spotHealWindow; exports.RetouchDabStroke = RetouchDabStroke; exports.smudgeEffect = smudgeEffect; exports.spongeEffect = spongeEffect; exports.rgbaViewOfGrey = rgbaViewOfGrey; exports.WET_TILE = WET_TILE; exports.SLOT_SIDE = SLOT_SIDE; exports.PLANE = PLANE; exports.PLANE_BYTES = PLANE_BYTES; exports.SET_PLANES = SET_PLANES; exports.P_RHO = P_RHO; exports.P_UX = P_UX; exports.P_UY = P_UY; exports.P_SW = P_SW; exports.P_P0 = P_P0; exports.P_L = P_L; exports.P_EDGE = P_EDGE; exports.P_D0 = P_D0; exports.P_DL = P_DL; exports.P_H = P_H; exports.P_FX = P_FX; exports.P_FY = P_FY; exports.SLOT_PLANES = SLOT_PLANES; exports.SLOT_BYTES = SLOT_BYTES; exports.PIGMENT_CHANNELS = PIGMENT_CHANNELS; exports.MASS_CHANNELS = MASS_CHANNELS; exports.EX = EX; exports.EY = EY; exports.OPP = OPP; exports.W9 = W9; exports.DRY_EPS = DRY_EPS; exports.U_MAX = U_MAX; exports.STRIP = STRIP; exports.MAX_BATCH = MAX_BATCH; exports.FREE_INTERVAL = FREE_INTERVAL; exports.FLAG_ALIVE = FLAG_ALIVE; exports.FLAG_LEFT = FLAG_LEFT; exports.FLAG_RIGHT = FLAG_RIGHT; exports.FLAG_TOP = FLAG_TOP; exports.FLAG_BOTTOM = FLAG_BOTTOM; exports.FLAG_WET = FLAG_WET; exports.PARAM_FLOATS = PARAM_FLOATS; exports.PARAM = PARAM; exports.DEFAULT_WET_PARAMS = DEFAULT_WET_PARAMS; exports.WET_PARAM_KEYS = WET_PARAM_KEYS; exports.DEFAULT_WET_PAPER = DEFAULT_WET_PAPER; exports.FLAT = FLAT; exports.normalizeWetParams = normalizeWetParams; exports.normalizeTilt = normalizeTilt; exports.latticeViscosity = latticeViscosity; exports.PAPER_CAPACITY = PAPER_CAPACITY; exports.MAX_TILT_ACCEL = MAX_TILT_ACCEL; exports.packWetParams = packWetParams; exports.edgeBits = edgeBits; exports.PIGMENT_UNIT = PIGMENT_UNIT; exports.HIDE = HIDE; exports.BODY_SCATTER = BODY_SCATTER; exports.dexp = dexp; exports.dlog = dlog; exports.dpow = dpow; exports.SRGB_TO_LINEAR = SRGB_TO_LINEAR; exports.srgbByteToLinear = srgbByteToLinear; exports.linearToSrgb8 = linearToSrgb8; exports.pigmentOf = pigmentOf; exports.expNeg = expNeg; exports.filmReflectance = filmReflectance; exports.pigmentColor = pigmentColor; exports.filmPixel = filmPixel; exports.pixelPigment = pixelPigment; exports.shadeTile = shadeTile; exports.shadeLightTile = shadeLightTile; exports.stepSlotTs = stepSlotTs; exports.loadWetKernel = loadWetKernel; exports.canShareMemory = canShareMemory; exports.wetSimdSupported = wetSimdSupported; exports.wetSupport = wetSupport; exports.WetWorkerPool = WetWorkerPool; exports.MAX_WET_LANES = MAX_WET_LANES; exports.MAX_WET_SLOTS = MAX_WET_SLOTS; exports.WetWorldError = WetWorldError; exports.WetWorld = WetWorld; exports.moveWetSnapshot = moveWetSnapshot; exports.WET_FLOW_KINDS = WET_FLOW_KINDS; exports.DEFAULT_FLOW = DEFAULT_FLOW; exports.dsincos = dsincos; exports.normalizeFlow = normalizeFlow; exports.flowField = flowField; exports.WetMedium = WetMedium; exports.WGSL_STEP = WGSL_STEP; exports.WGSL_HALO = WGSL_HALO; exports.WGSL_SHADE = WGSL_SHADE; exports.findWebGpu = findWebGpu; exports.createWetGpuEngine = createWetGpuEngine; exports.wetGpuSupport = wetGpuSupport; exports.WetGpuEngine = WetGpuEngine; exports.pointerPressure = pointerPressure; exports.pointerStrokeSample = pointerStrokeSample; exports.pointerStrokeSamples = pointerStrokeSamples;
3318
+ exports.PIGMENT_UNIT = PIGMENT_UNIT; exports.HIDE = HIDE; exports.BODY_SCATTER = BODY_SCATTER; exports.dexp = dexp; exports.dlog = dlog; exports.dpow = dpow; exports.SRGB_TO_LINEAR = SRGB_TO_LINEAR; exports.srgbByteToLinear = srgbByteToLinear; exports.linearToSrgb8 = linearToSrgb8; exports.pigmentOf = pigmentOf; exports.expNeg = expNeg; exports.filmReflectance = filmReflectance; exports.pigmentColor = pigmentColor; exports.filmPixel = filmPixel; exports.pixelPigment = pixelPigment; exports.shadeTile = shadeTile; exports.shadeLightTile = shadeLightTile; exports.WET_TILE = WET_TILE; exports.SLOT_SIDE = SLOT_SIDE; exports.PLANE = PLANE; exports.PLANE_BYTES = PLANE_BYTES; exports.SET_PLANES = SET_PLANES; exports.P_RHO = P_RHO; exports.P_UX = P_UX; exports.P_UY = P_UY; exports.P_SW = P_SW; exports.P_P0 = P_P0; exports.P_L = P_L; exports.P_EDGE = P_EDGE; exports.P_D0 = P_D0; exports.P_DL = P_DL; exports.P_H = P_H; exports.P_FX = P_FX; exports.P_FY = P_FY; exports.SLOT_PLANES = SLOT_PLANES; exports.SLOT_BYTES = SLOT_BYTES; exports.PIGMENT_CHANNELS = PIGMENT_CHANNELS; exports.MASS_CHANNELS = MASS_CHANNELS; exports.EX = EX; exports.EY = EY; exports.OPP = OPP; exports.W9 = W9; exports.DRY_EPS = DRY_EPS; exports.U_MAX = U_MAX; exports.STRIP = STRIP; exports.MAX_BATCH = MAX_BATCH; exports.FREE_INTERVAL = FREE_INTERVAL; exports.FLAG_ALIVE = FLAG_ALIVE; exports.FLAG_LEFT = FLAG_LEFT; exports.FLAG_RIGHT = FLAG_RIGHT; exports.FLAG_TOP = FLAG_TOP; exports.FLAG_BOTTOM = FLAG_BOTTOM; exports.FLAG_WET = FLAG_WET; exports.PARAM_FLOATS = PARAM_FLOATS; exports.PARAM = PARAM; exports.DEFAULT_WET_PARAMS = DEFAULT_WET_PARAMS; exports.WET_PARAM_KEYS = WET_PARAM_KEYS; exports.DEFAULT_WET_PAPER = DEFAULT_WET_PAPER; exports.FLAT = FLAT; exports.normalizeWetParams = normalizeWetParams; exports.normalizeTilt = normalizeTilt; exports.latticeViscosity = latticeViscosity; exports.PAPER_CAPACITY = PAPER_CAPACITY; exports.MAX_TILT_ACCEL = MAX_TILT_ACCEL; exports.packWetParams = packWetParams; exports.edgeBits = edgeBits; exports.stepSlotTs = stepSlotTs; exports.loadWetKernel = loadWetKernel; exports.canShareMemory = canShareMemory; exports.wetSimdSupported = wetSimdSupported; exports.wetSupport = wetSupport; exports.WetWorkerPool = WetWorkerPool; exports.MAX_WET_LANES = MAX_WET_LANES; exports.MAX_WET_SLOTS = MAX_WET_SLOTS; exports.WetWorldError = WetWorldError; exports.WetWorld = WetWorld; exports.moveWetSnapshot = moveWetSnapshot; exports.WET_FLOW_KINDS = WET_FLOW_KINDS; exports.DEFAULT_FLOW = DEFAULT_FLOW; exports.dsincos = dsincos; exports.normalizeFlow = normalizeFlow; exports.flowField = flowField; exports.WetMedium = WetMedium; exports.WGSL_STEP = WGSL_STEP; exports.WGSL_HALO = WGSL_HALO; exports.WGSL_SHADE = WGSL_SHADE; exports.findWebGpu = findWebGpu; exports.createWetGpuEngine = createWetGpuEngine; exports.wetGpuSupport = wetGpuSupport; exports.WetGpuEngine = WetGpuEngine;