@pixerate/editor 0.266.1 → 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 (117) hide show
  1. package/dist/agent/index.cjs +8 -4
  2. package/dist/agent/index.js +6 -2
  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-ZQI3WUPP.js → chunk-QCLY5SFS.js} +12 -0
  47. package/dist/{chunk-7KNW3WXZ.cjs → chunk-QEVLRLUN.cjs} +63 -0
  48. package/dist/{chunk-OTN6VB5S.cjs → chunk-RDFHWAHL.cjs} +5 -1
  49. package/dist/{chunk-6JL2D5SG.js → chunk-VE6UKYQ2.js} +3 -2
  50. package/dist/{chunk-RFJZGTHA.cjs → chunk-XVOP3CGQ.cjs} +9 -9
  51. package/dist/{chunk-EZOJBP4D.js → chunk-YIC6MAJ2.js} +1 -1
  52. package/dist/chunk-YZWM6ZIP.cjs +340 -0
  53. package/dist/{chunk-472INMWH.js → chunk-ZA7L5YJB.js} +63 -0
  54. package/dist/{chunk-YBC3RKT2.cjs → chunk-ZGXJ7BTR.cjs} +13 -1
  55. package/dist/commands/builtins.d.cts +12 -1
  56. package/dist/commands/builtins.d.ts +12 -1
  57. package/dist/commands/index.cjs +2 -2
  58. package/dist/commands/index.js +1 -1
  59. package/dist/image-editor/controller.d.cts +1 -1
  60. package/dist/image-editor/controller.d.ts +1 -1
  61. package/dist/image-editor/index.cjs +837 -833
  62. package/dist/image-editor/index.js +105 -101
  63. package/dist/paint/index.cjs +5 -3
  64. package/dist/paint/index.js +46 -44
  65. package/dist/paint-editor/controller.d.cts +5 -3
  66. package/dist/paint-editor/controller.d.ts +5 -3
  67. package/dist/paint-editor/index.cjs +832 -2295
  68. package/dist/paint-editor/index.js +285 -1748
  69. package/dist/paint-editor/path-samples.d.cts +2 -0
  70. package/dist/paint-editor/path-samples.d.ts +2 -0
  71. package/dist/paint-editor/presence.d.cts +20 -1
  72. package/dist/paint-editor/presence.d.ts +20 -1
  73. package/dist/stickers/helpers.d.cts +2 -0
  74. package/dist/stickers/helpers.d.ts +2 -0
  75. package/dist/stickers/index.cjs +41 -35
  76. package/dist/stickers/index.js +22 -16
  77. package/dist/stickers/types.d.cts +4 -2
  78. package/dist/stickers/types.d.ts +4 -2
  79. package/dist/tools/conformance.d.cts +8 -0
  80. package/dist/tools/conformance.d.ts +8 -0
  81. package/dist/tools/index.cjs +6 -2
  82. package/dist/tools/index.js +5 -1
  83. package/dist/vector/backdrop.d.cts +13 -0
  84. package/dist/vector/backdrop.d.ts +13 -0
  85. package/dist/vector/brushstroke.d.cts +54 -7
  86. package/dist/vector/brushstroke.d.ts +54 -7
  87. package/dist/vector/brushstrokeMedia.d.cts +96 -0
  88. package/dist/vector/brushstrokeMedia.d.ts +96 -0
  89. package/dist/vector/controller.d.cts +17 -3
  90. package/dist/vector/controller.d.ts +17 -3
  91. package/dist/vector/index.cjs +1846 -1386
  92. package/dist/vector/index.d.cts +2 -0
  93. package/dist/vector/index.d.ts +2 -0
  94. package/dist/vector/index.js +517 -57
  95. package/dist/vector/render.d.cts +6 -0
  96. package/dist/vector/render.d.ts +6 -0
  97. package/dist/vector/types.d.cts +14 -0
  98. package/dist/vector/types.d.ts +14 -0
  99. package/package.json +1 -1
  100. package/skills/pixerate-animation-editor/SKILL.md +1 -0
  101. package/skills/pixerate-brushes/SKILL.md +2 -2
  102. package/skills/pixerate-brushes-design/SKILL.md +7 -4
  103. package/skills/pixerate-brushes-design/evals/port-to-vector.json +8 -8
  104. package/skills/pixerate-canvas/SKILL.md +11 -1
  105. package/skills/pixerate-image-editor/SKILL.md +19 -64
  106. package/skills/pixerate-image-editor/references/color-management.md +2 -1
  107. package/skills/pixerate-image-editor/references/free-transform.md +12 -0
  108. package/skills/pixerate-image-editor/references/layer-effects.md +10 -0
  109. package/skills/pixerate-image-editor/references/painting.md +17 -0
  110. package/skills/pixerate-image-editor/references/photoshop-files.md +1 -1
  111. package/skills/pixerate-image-editor/references/shapes-and-type.md +14 -0
  112. package/skills/pixerate-image-editor/references/smart-objects.md +10 -0
  113. package/skills/pixerate-paint-editor/SKILL.md +8 -4
  114. package/skills/pixerate-paint-editor/references/wet-media.md +9 -0
  115. package/skills/pixerate-vector/SKILL.md +16 -6
  116. package/skills/pixerate-vector/references/best-practices.md +1 -0
  117. package/skills/pixerate-vector/references/commands.md +19 -0
@@ -0,0 +1,340 @@
1
+ // src/image-editor/layers/vector-raster.ts
2
+ var FLATNESS = 0.01;
3
+ function flattenPath(path, tolerance = FLATNESS) {
4
+ const out = [];
5
+ let pts = [];
6
+ let cx = 0;
7
+ let cy = 0;
8
+ let sx = 0;
9
+ let sy = 0;
10
+ const flush = () => {
11
+ if (pts.length >= 6) out.push(Float64Array.from(pts));
12
+ pts = [];
13
+ };
14
+ const steps = (dd, degree) => Math.max(1, Math.min(1024, Math.ceil(Math.sqrt(degree * (degree - 1) * dd / (8 * tolerance)))));
15
+ for (const c of path) {
16
+ switch (c.type) {
17
+ case "M":
18
+ flush();
19
+ cx = sx = c.x;
20
+ cy = sy = c.y;
21
+ pts.push(cx, cy);
22
+ break;
23
+ case "L":
24
+ if (!pts.length) pts.push(cx, cy);
25
+ cx = c.x;
26
+ cy = c.y;
27
+ pts.push(cx, cy);
28
+ break;
29
+ case "Q": {
30
+ if (!pts.length) pts.push(cx, cy);
31
+ const n = steps(Math.hypot(cx - 2 * c.x1 + c.x, cy - 2 * c.y1 + c.y), 2);
32
+ for (let k = 1; k <= n; k++) {
33
+ const t = k / n;
34
+ const u = 1 - t;
35
+ pts.push(u * u * cx + 2 * u * t * c.x1 + t * t * c.x, u * u * cy + 2 * u * t * c.y1 + t * t * c.y);
36
+ }
37
+ cx = c.x;
38
+ cy = c.y;
39
+ break;
40
+ }
41
+ case "C": {
42
+ if (!pts.length) pts.push(cx, cy);
43
+ const dd = Math.max(Math.hypot(cx - 2 * c.x1 + c.x2, cy - 2 * c.y1 + c.y2), Math.hypot(c.x1 - 2 * c.x2 + c.x, c.y1 - 2 * c.y2 + c.y));
44
+ const n = steps(dd, 3);
45
+ for (let k = 1; k <= n; k++) {
46
+ const t = k / n;
47
+ const u = 1 - t;
48
+ const a = u * u * u;
49
+ const b = 3 * u * u * t;
50
+ const d = 3 * u * t * t;
51
+ const e = t * t * t;
52
+ pts.push(a * cx + b * c.x1 + d * c.x2 + e * c.x, a * cy + b * c.y1 + d * c.y2 + e * c.y);
53
+ }
54
+ cx = c.x;
55
+ cy = c.y;
56
+ break;
57
+ }
58
+ case "Z":
59
+ flush();
60
+ cx = sx;
61
+ cy = sy;
62
+ break;
63
+ }
64
+ }
65
+ flush();
66
+ return out.filter((p) => p.every(Number.isFinite));
67
+ }
68
+ function flatBounds(flat) {
69
+ let x0 = Infinity;
70
+ let y0 = Infinity;
71
+ let x1 = -Infinity;
72
+ let y1 = -Infinity;
73
+ for (const p of flat) {
74
+ for (let i = 0; i < p.length; i += 2) {
75
+ if (p[i] < x0) x0 = p[i];
76
+ if (p[i] > x1) x1 = p[i];
77
+ if (p[i + 1] < y0) y0 = p[i + 1];
78
+ if (p[i + 1] > y1) y1 = p[i + 1];
79
+ }
80
+ }
81
+ if (x0 === Infinity) return null;
82
+ const x = Math.floor(x0);
83
+ const y = Math.floor(y0);
84
+ return { x, y, width: Math.ceil(x1) - x, height: Math.ceil(y1) - y };
85
+ }
86
+ function drawLine(a, w, h, x0, y0, x1, y1) {
87
+ if (y0 === y1) return;
88
+ let dir = 1;
89
+ if (y0 > y1) {
90
+ dir = -1;
91
+ let t = x0;
92
+ x0 = x1;
93
+ x1 = t;
94
+ t = y0;
95
+ y0 = y1;
96
+ y1 = t;
97
+ }
98
+ if (y1 <= 0 || y0 >= h) return;
99
+ const dxdy = (x1 - x0) / (y1 - y0);
100
+ let x = x0;
101
+ if (y0 < 0) x -= y0 * dxdy;
102
+ const rowStart = Math.max(0, Math.floor(y0));
103
+ const rowEnd = Math.min(h, Math.ceil(y1));
104
+ for (let y = rowStart; y < rowEnd; y++) {
105
+ const line = y * w;
106
+ const dy = Math.min(y + 1, y1) - Math.max(y, y0);
107
+ const xnext = x + dxdy * dy;
108
+ const d = dy * dir;
109
+ const xa = x < xnext ? x : xnext;
110
+ const xb = x < xnext ? xnext : x;
111
+ const xaFloor = Math.floor(xa);
112
+ const xai = xaFloor;
113
+ const xbCeil = Math.ceil(xb);
114
+ const xbi = xbCeil;
115
+ if (xbi <= xai + 1) {
116
+ const xmf = 0.5 * (x + xnext) - xaFloor;
117
+ a[line + xai] += d - d * xmf;
118
+ a[line + xai + 1] += d * xmf;
119
+ } else {
120
+ const s = 1 / (xb - xa);
121
+ const xaf = xa - xaFloor;
122
+ const a0 = 0.5 * s * (1 - xaf) * (1 - xaf);
123
+ const xbf = xb - xbCeil + 1;
124
+ const am = 0.5 * s * xbf * xbf;
125
+ a[line + xai] += d * a0;
126
+ if (xbi === xai + 2) a[line + xai + 1] += d * (1 - a0 - am);
127
+ else {
128
+ const a1 = s * (1.5 - xaf);
129
+ a[line + xai + 1] += d * (a1 - a0);
130
+ for (let xi = xai + 2; xi < xbi - 1; xi++) a[line + xi] += d * s;
131
+ const a2 = a1 + (xbi - xai - 3) * s;
132
+ a[line + xbi - 1] += d * (1 - a2 - am);
133
+ }
134
+ a[line + xbi] += d * am;
135
+ }
136
+ x = xnext;
137
+ }
138
+ }
139
+ function drawClippedLine(a, w, h, x0, y0, x1, y1) {
140
+ if (y0 === y1) return;
141
+ if (y0 <= 0 && y1 <= 0 || y0 >= h && y1 >= h) return;
142
+ if (x0 >= 0 && x0 <= w && x1 >= 0 && x1 <= w) return drawLine(a, w, h, x0, y0, x1, y1);
143
+ const ts = [0, 1];
144
+ const dx = x1 - x0;
145
+ if (dx !== 0) {
146
+ for (const edge of [0, w]) {
147
+ const t = (edge - x0) / dx;
148
+ if (t > 0 && t < 1) ts.push(t);
149
+ }
150
+ }
151
+ ts.sort((p, q) => p - q);
152
+ const clamp = (v) => v < 0 ? 0 : v > w ? w : v;
153
+ for (let i = 0; i + 1 < ts.length; i++) {
154
+ const ta = ts[i];
155
+ const tb = ts[i + 1];
156
+ drawLine(a, w, h, clamp(x0 + dx * ta), y0 + (y1 - y0) * ta, clamp(x0 + dx * tb), y0 + (y1 - y0) * tb);
157
+ }
158
+ }
159
+ function ruleCoverage(v, rule) {
160
+ const m = v < 0 ? -v : v;
161
+ if (rule === "nonzero") return m >= 1 ? 1 : m;
162
+ const f = m % 2;
163
+ return f > 1 ? 2 - f : f;
164
+ }
165
+ function rasterizeCoverage(flat, rect, rule = "nonzero") {
166
+ const w = rect.width;
167
+ const h = rect.height;
168
+ if (w <= 0 || h <= 0 || !flat.length) return null;
169
+ const a = new Float64Array(w * h + w + 4);
170
+ const ox = rect.x;
171
+ const oy = rect.y;
172
+ let touched = false;
173
+ for (const p of flat) {
174
+ const n = p.length;
175
+ for (let i = 0; i < n; i += 2) {
176
+ const j = i + 2 < n ? i + 2 : 0;
177
+ const ya = p[i + 1] - oy;
178
+ const yb = p[j + 1] - oy;
179
+ if (ya <= 0 && yb <= 0 || ya >= h && yb >= h || ya === yb) continue;
180
+ drawClippedLine(a, w, h, p[i] - ox, ya, p[j] - ox, yb);
181
+ touched = true;
182
+ }
183
+ }
184
+ if (!touched) return null;
185
+ const out = new Float32Array(w * h);
186
+ let acc = 0;
187
+ let any = false;
188
+ for (let i = 0; i < out.length; i++) {
189
+ acc += a[i];
190
+ const c = ruleCoverage(acc, rule);
191
+ if (c > 1e-6) {
192
+ out[i] = c;
193
+ any = true;
194
+ }
195
+ }
196
+ return any ? out : null;
197
+ }
198
+ var SUB_ROWS = 16;
199
+ function rasterizeCoverageSampled(flat, rect, rule = "nonzero") {
200
+ const w = rect.width;
201
+ const h = rect.height;
202
+ if (w <= 0 || h <= 0 || !flat.length) return null;
203
+ let n = 0;
204
+ for (const p of flat) n += p.length >> 1;
205
+ const ey0 = new Float64Array(n);
206
+ const ey1 = new Float64Array(n);
207
+ const ex0 = new Float64Array(n);
208
+ const eslope = new Float64Array(n);
209
+ const edir = new Int8Array(n);
210
+ let count = 0;
211
+ for (const p of flat) {
212
+ const len = p.length;
213
+ for (let i = 0; i < len; i += 2) {
214
+ const j = i + 2 < len ? i + 2 : 0;
215
+ let xa = p[i] - rect.x;
216
+ let ya = p[i + 1] - rect.y;
217
+ let xb = p[j] - rect.x;
218
+ let yb = p[j + 1] - rect.y;
219
+ if (ya === yb) continue;
220
+ let dir = 1;
221
+ if (ya > yb) {
222
+ dir = -1;
223
+ let t = xa;
224
+ xa = xb;
225
+ xb = t;
226
+ t = ya;
227
+ ya = yb;
228
+ yb = t;
229
+ }
230
+ if (yb <= 0 || ya >= h) continue;
231
+ ey0[count] = ya;
232
+ ey1[count] = yb;
233
+ ex0[count] = xa;
234
+ eslope[count] = (xb - xa) / (yb - ya);
235
+ edir[count] = dir;
236
+ count++;
237
+ }
238
+ }
239
+ if (!count) return null;
240
+ const order = Array.from({ length: count }, (_, i) => i).sort((a, b) => ey0[a] - ey0[b]);
241
+ const out = new Float32Array(w * h);
242
+ const diff = new Float32Array(w + 1);
243
+ let active = [];
244
+ let next = 0;
245
+ const xs = [];
246
+ const ds = [];
247
+ const idx = [];
248
+ const f = 1 / SUB_ROWS;
249
+ let any = false;
250
+ const firstRow = Math.max(0, Math.floor(ey0[order[0]]));
251
+ for (let y = firstRow; y < h; y++) {
252
+ if (next >= count && !active.length) break;
253
+ const row = y * w;
254
+ let rowTouched = false;
255
+ for (let s = 0; s < SUB_ROWS; s++) {
256
+ const sy = y + (s + 0.5) * f;
257
+ while (next < count && ey0[order[next]] <= sy) active.push(order[next++]);
258
+ if (!active.length) continue;
259
+ active = active.filter((e) => ey1[e] > sy);
260
+ xs.length = 0;
261
+ ds.length = 0;
262
+ idx.length = 0;
263
+ for (const e of active) {
264
+ if (ey0[e] > sy) continue;
265
+ idx.push(xs.length);
266
+ xs.push(ex0[e] + (sy - ey0[e]) * eslope[e]);
267
+ ds.push(edir[e]);
268
+ }
269
+ if (xs.length < 2) continue;
270
+ idx.sort((a, b) => xs[a] - xs[b]);
271
+ let wind = 0;
272
+ for (let k = 0; k + 1 < idx.length; k++) {
273
+ wind += ds[idx[k]];
274
+ const inside = rule === "nonzero" ? wind !== 0 : (wind & 1) !== 0;
275
+ if (!inside) continue;
276
+ let xa = xs[idx[k]];
277
+ let xb = xs[idx[k + 1]];
278
+ if (xb <= 0 || xa >= w || xb <= xa) continue;
279
+ if (xa < 0) xa = 0;
280
+ if (xb > w) xb = w;
281
+ const ia = Math.floor(xa);
282
+ const ib = Math.floor(xb);
283
+ rowTouched = true;
284
+ if (ia === ib) {
285
+ out[row + ia] += (xb - xa) * f;
286
+ continue;
287
+ }
288
+ out[row + ia] += (ia + 1 - xa) * f;
289
+ diff[ia + 1] += f;
290
+ diff[ib] -= f;
291
+ if (ib < w) out[row + ib] += (xb - ib) * f;
292
+ }
293
+ }
294
+ if (!rowTouched) continue;
295
+ let run = 0;
296
+ for (let x = 0; x < w; x++) {
297
+ run += diff[x];
298
+ diff[x] = 0;
299
+ const v = out[row + x] + run;
300
+ out[row + x] = v > 1 ? 1 : v < 1e-6 ? 0 : v;
301
+ if (out[row + x] > 0) any = true;
302
+ }
303
+ diff[w] = 0;
304
+ }
305
+ return any ? out : null;
306
+ }
307
+ function combineCoverage(a, b, op, n) {
308
+ if (op === "combine") {
309
+ if (!a) return b;
310
+ if (!b) return a;
311
+ const out2 = new Float32Array(n);
312
+ for (let i = 0; i < n; i++) out2[i] = a[i] + b[i] - a[i] * b[i];
313
+ return out2;
314
+ }
315
+ if (op === "subtract") {
316
+ if (!a || !b) return a;
317
+ const out2 = new Float32Array(n);
318
+ for (let i = 0; i < n; i++) out2[i] = a[i] * (1 - b[i]);
319
+ return out2;
320
+ }
321
+ if (op === "intersect") {
322
+ if (!a || !b) return null;
323
+ const out2 = new Float32Array(n);
324
+ for (let i = 0; i < n; i++) out2[i] = a[i] * b[i];
325
+ return out2;
326
+ }
327
+ if (!a) return b;
328
+ if (!b) return a;
329
+ const out = new Float32Array(n);
330
+ for (let i = 0; i < n; i++) out[i] = a[i] + b[i] - 2 * a[i] * b[i];
331
+ return out;
332
+ }
333
+
334
+ export {
335
+ flattenPath,
336
+ flatBounds,
337
+ rasterizeCoverage,
338
+ rasterizeCoverageSampled,
339
+ combineCoverage
340
+ };
@@ -2,7 +2,7 @@ import {
2
2
  STAMP_KINDS,
3
3
  editorStampOf,
4
4
  normalizeStickerRef
5
- } from "./chunk-ACFSFUQH.js";
5
+ } from "./chunk-JL6YH5WD.js";
6
6
  import {
7
7
  validateJsonSchema
8
8
  } from "./chunk-V2ZCJRDM.js";
@@ -1886,7 +1886,7 @@ var CANVAS_PROFILE = {
1886
1886
  velocity: "ignored",
1887
1887
  tilt: "full"
1888
1888
  };
1889
- var VECTOR_PROFILE = { ...CANVAS_PROFILE, id: "vector", name: "Vector editor", light: "ignored" };
1889
+ var VECTOR_PROFILE = { ...CANVAS_PROFILE, id: "vector", name: "Vector editor", kinds: ["mark", "tool"], tools: ["blender", "smudge"], surfaces: ["dry", "wet"], reservoir: "full", light: "ignored" };
1890
1890
  var BRUSH_HOST_PROFILES = { paint: PAINT_PROFILE, image: IMAGE_PROFILE, canvas: CANVAS_PROFILE, vector: VECTOR_PROFILE };
1891
1891
  function brushColourKind(paint) {
1892
1892
  if (typeof paint === "string") return "solid";
@@ -1,6 +1,6 @@
1
1
  "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
2
2
 
3
- var _chunkPE6YJMQTcjs = require('./chunk-PE6YJMQT.cjs');
3
+ var _chunkPFHJS4HEcjs = require('./chunk-PFHJS4HE.cjs');
4
4
 
5
5
 
6
6
 
@@ -16,12 +16,12 @@ var _chunkPE6YJMQTcjs = require('./chunk-PE6YJMQT.cjs');
16
16
 
17
17
 
18
18
 
19
- var _chunkRFJZGTHAcjs = require('./chunk-RFJZGTHA.cjs');
19
+ var _chunkXVOP3CGQcjs = require('./chunk-XVOP3CGQ.cjs');
20
20
 
21
21
  // src/brushes/patch.ts
22
22
  var isObject = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
23
23
  var copy = (v) => JSON.parse(JSON.stringify(v));
24
- var FACETS = _chunkRFJZGTHAcjs.BRUSH_JSON_SCHEMA.properties;
24
+ var FACETS = _chunkXVOP3CGQcjs.BRUSH_JSON_SCHEMA.properties;
25
25
  var BRUSH_PATCH_PROPERTIES = (() => {
26
26
  const { id: _id, name: _name, ...rest } = FACETS;
27
27
  const { required: _r, ...tip } = rest.tip;
@@ -53,17 +53,17 @@ function changedBrushPaths(a, b, path = "") {
53
53
  // src/brushes/tools.ts
54
54
  var READ = { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false };
55
55
  var WRITE = { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false };
56
- var FACETS2 = _chunkRFJZGTHAcjs.BRUSH_JSON_SCHEMA.properties;
56
+ var FACETS2 = _chunkXVOP3CGQcjs.BRUSH_JSON_SCHEMA.properties;
57
57
  var ID = { type: "string", pattern: String(FACETS2.id.pattern), description: "Brush id from list_brush_presets (lowercase letters, digits and dashes)." };
58
58
  var FACET_PROPS = BRUSH_PATCH_PROPERTIES;
59
- var HOSTS = Object.keys(_chunkRFJZGTHAcjs.BRUSH_HOST_PROFILES);
59
+ var HOSTS = Object.keys(_chunkXVOP3CGQcjs.BRUSH_HOST_PROFILES);
60
60
  var copy2 = (v) => JSON.parse(JSON.stringify(v));
61
61
  var merge = mergeBrushPatch;
62
62
  var changedPaths = changedBrushPaths;
63
63
  function summary(entry, profile, withCheck) {
64
64
  const b = entry.brush;
65
- const engine = _chunkRFJZGTHAcjs.resolveEngine.call(void 0, b);
66
- const check = withCheck ? _chunkRFJZGTHAcjs.checkBrush.call(void 0, b, profile) : null;
65
+ const engine = _chunkXVOP3CGQcjs.resolveEngine.call(void 0, b);
66
+ const check = withCheck ? _chunkXVOP3CGQcjs.checkBrush.call(void 0, b, profile) : null;
67
67
  return {
68
68
  id: b.id,
69
69
  name: b.name,
@@ -72,7 +72,7 @@ function summary(entry, profile, withCheck) {
72
72
  ...b.medium ? { medium: b.medium } : {},
73
73
  ...b.variety ? { variety: b.variety } : {},
74
74
  ...b.tool ? { tool: b.tool } : {},
75
- category: _chunkRFJZGTHAcjs.resolveCategory.call(void 0, b, engine),
75
+ category: _chunkXVOP3CGQcjs.resolveCategory.call(void 0, b, engine),
76
76
  engine,
77
77
  tip: b.tip.shape,
78
78
  ...b.tip.size !== void 0 ? { size: b.tip.size } : {},
@@ -86,28 +86,28 @@ function summary(entry, profile, withCheck) {
86
86
  var refusal = (check, host) => `${host.name} can't use this brush: ${check.issues.filter((i) => i.severity === "error").map((i) => `${i.facet}: ${i.reason} ${i.fix}`).join(" ")} (check_brush lists every issue; nothing was saved.)`;
87
87
  var warnings = (check) => check.issues.filter((i) => i.severity === "warning");
88
88
  function createBrushLibraryTools(library, options = {}) {
89
- const profile = _nullishCoalesce(options.profile, () => ( _chunkRFJZGTHAcjs.PAINT_PROFILE));
89
+ const profile = _nullishCoalesce(options.profile, () => ( _chunkXVOP3CGQcjs.PAINT_PROFILE));
90
90
  const hostOf = (id) => {
91
91
  if (id === void 0) return profile;
92
- const p = _chunkRFJZGTHAcjs.BRUSH_HOST_PROFILES[id];
93
- if (!p) throw new (0, _chunkRFJZGTHAcjs.BrushLibraryError)("invalid", `No host "${id}"; use one of: ${HOSTS.join(", ")}.`);
92
+ const p = _chunkXVOP3CGQcjs.BRUSH_HOST_PROFILES[id];
93
+ if (!p) throw new (0, _chunkXVOP3CGQcjs.BrushLibraryError)("invalid", `No host "${id}"; use one of: ${HOSTS.join(", ")}.`);
94
94
  return p;
95
95
  };
96
96
  const entry = async (id) => {
97
97
  const found = await library.get(id);
98
98
  if (found) return found;
99
99
  const ids = (await library.list()).map((e) => e.brush.id);
100
- throw new (0, _chunkRFJZGTHAcjs.BrushLibraryError)("unknown_brush", `No brush "${id}". ${_chunkRFJZGTHAcjs.closest.call(void 0, id, ids)}list_brush_presets lists them.`);
100
+ throw new (0, _chunkXVOP3CGQcjs.BrushLibraryError)("unknown_brush", `No brush "${id}". ${_chunkXVOP3CGQcjs.closest.call(void 0, id, ids)}list_brush_presets lists them.`);
101
101
  };
102
102
  const checkFor = async (brush, p) => {
103
- const check2 = _chunkRFJZGTHAcjs.checkBrush.call(void 0, brush, p);
103
+ const check2 = _chunkXVOP3CGQcjs.checkBrush.call(void 0, brush, p);
104
104
  const provider = _optionalChain([options, 'access', _9 => _9.stickers, 'optionalCall', _10 => _10()]);
105
105
  if (!provider || brush.tip.shape !== "stamp") return check2;
106
106
  const issues = [...check2.issues];
107
107
  for (const ref of _nullishCoalesce(brush.tip.stamps, () => ( []))) {
108
108
  if (ref.startsWith("editor:")) continue;
109
109
  try {
110
- await _chunkPE6YJMQTcjs.describeStickerRef.call(void 0, provider, ref);
110
+ await _chunkPFHJS4HEcjs.describeStickerRef.call(void 0, provider, ref);
111
111
  } catch (e) {
112
112
  issues.push({ facet: "tip.stamps", severity: "error", reason: `${p.name} can't load sticker "${ref}": ${e.message}`, fix: "Use a ref from find_stickers, or an editor stamp (editor:star, editor:dot\u2026)." });
113
113
  }
@@ -118,12 +118,12 @@ function createBrushLibraryTools(library, options = {}) {
118
118
  const problems = [];
119
119
  let brush;
120
120
  try {
121
- brush = _chunkRFJZGTHAcjs.normalizeBrushSpec.call(void 0, raw, problems);
121
+ brush = _chunkXVOP3CGQcjs.normalizeBrushSpec.call(void 0, raw, problems);
122
122
  } catch (e) {
123
- throw new (0, _chunkRFJZGTHAcjs.BrushLibraryError)("invalid", e.message);
123
+ throw new (0, _chunkXVOP3CGQcjs.BrushLibraryError)("invalid", e.message);
124
124
  }
125
- const check2 = _chunkRFJZGTHAcjs.withKeptIssues.call(void 0, await checkFor(brush, profile), original ? await checkFor(original, profile) : null);
126
- if (!check2.ok) throw new (0, _chunkRFJZGTHAcjs.BrushLibraryError)("invalid", refusal(check2, profile));
125
+ const check2 = _chunkXVOP3CGQcjs.withKeptIssues.call(void 0, await checkFor(brush, profile), original ? await checkFor(original, profile) : null);
126
+ if (!check2.ok) throw new (0, _chunkXVOP3CGQcjs.BrushLibraryError)("invalid", refusal(check2, profile));
127
127
  const saved = await library.save(brush, { overwrite });
128
128
  return { ...saved, problems, check: check2 };
129
129
  };
@@ -134,10 +134,10 @@ function createBrushLibraryTools(library, options = {}) {
134
134
  inputSchema: {
135
135
  type: "object",
136
136
  properties: {
137
- kind: { type: "string", enum: [..._chunkRFJZGTHAcjs.BRUSH_KINDS], description: "mark (lays a material) or tool (works on paint already down)." },
138
- medium: { type: "string", enum: [..._chunkRFJZGTHAcjs.BRUSH_MEDIA], description: "Marks laying this medium." },
137
+ kind: { type: "string", enum: [..._chunkXVOP3CGQcjs.BRUSH_KINDS], description: "mark (lays a material) or tool (works on paint already down)." },
138
+ medium: { type: "string", enum: [..._chunkXVOP3CGQcjs.BRUSH_MEDIA], description: "Marks laying this medium." },
139
139
  variety: { type: "string", maxLength: 40, description: "This variety (oil, watercolor, pencil, highlighter\u2026)." },
140
- tool: { type: "string", enum: [..._chunkRFJZGTHAcjs.BRUSH_TOOLS], description: "Tools that do this." },
140
+ tool: { type: "string", enum: [..._chunkXVOP3CGQcjs.BRUSH_TOOLS], description: "Tools that do this." },
141
141
  tag: { type: "string", maxLength: 40, description: "Brushes with this tag." },
142
142
  text: { type: "string", maxLength: 200, description: "Words in the id, name, description, variety or tags (each word must match the start of one)." },
143
143
  source: { type: "string", enum: ["all", "builtin", "user"], description: "all (default), builtin presets only, or user (saved) brushes only." },
@@ -164,8 +164,8 @@ function createBrushLibraryTools(library, options = {}) {
164
164
  annotations: { title: "Describe a brush", ...READ },
165
165
  handler: async ({ id }) => {
166
166
  const e = await entry(id);
167
- const engine = _chunkRFJZGTHAcjs.resolveEngine.call(void 0, e.brush);
168
- return { brush: e.brush, builtin: e.builtin, engine, category: _chunkRFJZGTHAcjs.resolveCategory.call(void 0, e.brush, engine), check: await checkFor(e.brush, profile) };
167
+ const engine = _chunkXVOP3CGQcjs.resolveEngine.call(void 0, e.brush);
168
+ return { brush: e.brush, builtin: e.builtin, engine, category: _chunkXVOP3CGQcjs.resolveCategory.call(void 0, e.brush, engine), check: await checkFor(e.brush, profile) };
169
169
  }
170
170
  };
171
171
  const check = {
@@ -183,20 +183,20 @@ function createBrushLibraryTools(library, options = {}) {
183
183
  },
184
184
  annotations: { title: "Check a brush for a host", ...READ },
185
185
  handler: async ({ id, brush, host }) => {
186
- if (id === void 0 === (brush === void 0)) throw new (0, _chunkRFJZGTHAcjs.BrushLibraryError)("invalid", "Give either id (a library brush) or brush (a spec), not both or neither.");
186
+ if (id === void 0 === (brush === void 0)) throw new (0, _chunkXVOP3CGQcjs.BrushLibraryError)("invalid", "Give either id (a library brush) or brush (a spec), not both or neither.");
187
187
  const p = hostOf(host);
188
188
  let b;
189
189
  const problems = [];
190
190
  if (id !== void 0) b = (await entry(id)).brush;
191
191
  else {
192
192
  try {
193
- b = _chunkRFJZGTHAcjs.normalizeBrushSpec.call(void 0, brush, problems);
193
+ b = _chunkXVOP3CGQcjs.normalizeBrushSpec.call(void 0, brush, problems);
194
194
  } catch (e) {
195
- throw new (0, _chunkRFJZGTHAcjs.BrushLibraryError)("invalid", e.message);
195
+ throw new (0, _chunkXVOP3CGQcjs.BrushLibraryError)("invalid", e.message);
196
196
  }
197
197
  }
198
198
  const result = await checkFor(b, p);
199
- return { host: p.id, ...result, ...problems.length ? { problems } : {}, ...!result.ok ? { degraded: _chunkRFJZGTHAcjs.degrade.call(void 0, b, p) } : {} };
199
+ return { host: p.id, ...result, ...problems.length ? { problems } : {}, ...!result.ok ? { degraded: _chunkXVOP3CGQcjs.degrade.call(void 0, b, p) } : {} };
200
200
  }
201
201
  };
202
202
  const exportTool = {
@@ -255,12 +255,12 @@ function createBrushLibraryTools(library, options = {}) {
255
255
  },
256
256
  annotations: { title: "Save a new brush", ...WRITE },
257
257
  handler: async ({ basedOn, ...spec }) => {
258
- if (library.isBuiltin(spec.id)) throw new (0, _chunkRFJZGTHAcjs.BrushLibraryError)("builtin", `"${spec.id}" is a built-in brush id; pick another id (or basedOn "${spec.id}" with a new id).`);
259
- if (await library.get(spec.id)) throw new (0, _chunkRFJZGTHAcjs.BrushLibraryError)("exists", `A brush "${spec.id}" exists already; pick another id, or change it with update_brush.`);
258
+ if (library.isBuiltin(spec.id)) throw new (0, _chunkXVOP3CGQcjs.BrushLibraryError)("builtin", `"${spec.id}" is a built-in brush id; pick another id (or basedOn "${spec.id}" with a new id).`);
259
+ if (await library.get(spec.id)) throw new (0, _chunkXVOP3CGQcjs.BrushLibraryError)("exists", `A brush "${spec.id}" exists already; pick another id, or change it with update_brush.`);
260
260
  const base = basedOn !== void 0 ? (await entry(basedOn)).brush : void 0;
261
261
  const raw = base ? merge(base, spec) : spec;
262
262
  const saved = await store(raw, false);
263
- return { id: saved.brush.id, brush: saved.brush, engine: _chunkRFJZGTHAcjs.resolveEngine.call(void 0, saved.brush), problems: saved.problems, warnings: warnings(saved.check) };
263
+ return { id: saved.brush.id, brush: saved.brush, engine: _chunkXVOP3CGQcjs.resolveEngine.call(void 0, saved.brush), problems: saved.problems, warnings: warnings(saved.check) };
264
264
  }
265
265
  },
266
266
  {
@@ -281,7 +281,7 @@ function createBrushLibraryTools(library, options = {}) {
281
281
  annotations: { title: "Update a brush", ...WRITE, idempotentHint: true },
282
282
  handler: async ({ id, unset, ...patch }) => {
283
283
  const e = await entry(id);
284
- if (e.builtin) throw new (0, _chunkRFJZGTHAcjs.BrushLibraryError)("builtin", `"${id}" is a built-in brush and can't be changed; duplicate_brush makes a copy you can change.`);
284
+ if (e.builtin) throw new (0, _chunkXVOP3CGQcjs.BrushLibraryError)("builtin", `"${id}" is a built-in brush and can't be changed; duplicate_brush makes a copy you can change.`);
285
285
  const base = copy2(e.brush);
286
286
  for (const k of _nullishCoalesce(unset, () => ( []))) delete base[k];
287
287
  const saved = await store(merge(base, { ...patch, id }), true, e.brush);
@@ -340,7 +340,7 @@ function createBrushLibraryTools(library, options = {}) {
340
340
  return tools;
341
341
  }
342
342
  function createBrushLibraryToolProvider(library, options = {}) {
343
- const profile = _nullishCoalesce(options.profile, () => ( _chunkRFJZGTHAcjs.PAINT_PROFILE));
343
+ const profile = _nullishCoalesce(options.profile, () => ( _chunkXVOP3CGQcjs.PAINT_PROFILE));
344
344
  const tools = createBrushLibraryTools(library, options);
345
345
  return {
346
346
  id: _nullishCoalesce(options.id, () => ( "brushes")),
@@ -74,7 +74,7 @@ function profileAlongPolyline(points, values, count = 32) {
74
74
  var round3 = (v) => Math.round(v * 1e3) / 1e3;
75
75
  var loading = null;
76
76
  function loadCanvasBrushstrokeRenderer() {
77
- loading ??= import("./brushstrokeRender-KD453OBX.js").catch((error) => {
77
+ loading ??= import("./brushstrokeRender-NLFPEBGI.js").catch((error) => {
78
78
  loading = null;
79
79
  throw error;
80
80
  });