@pixerate/editor 0.276.0 → 0.277.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.
- package/dist/animation-editor/index.cjs +59 -59
- package/dist/animation-editor/index.js +3 -3
- package/dist/brushes/index.cjs +69 -67
- package/dist/brushes/index.js +6 -4
- package/dist/brushes/patch.d.cts +4 -4
- package/dist/brushes/patch.d.ts +4 -4
- package/dist/brushes/profiles.d.cts +2 -0
- package/dist/brushes/profiles.d.ts +2 -0
- package/dist/brushes/schema.d.cts +1 -0
- package/dist/brushes/schema.d.ts +1 -0
- package/dist/brushes/types.d.cts +10 -0
- package/dist/brushes/types.d.ts +10 -0
- package/dist/{brushstrokeRender-I6MYFCOU.cjs → brushstrokeRender-7HOMKZNO.cjs} +15 -15
- package/dist/{brushstrokeRender-FK3ASUUJ.js → brushstrokeRender-EIK3625T.js} +3 -3
- package/dist/canvas/index.cjs +13 -13
- package/dist/canvas/index.js +1 -1
- package/dist/{chunk-U26LUXCJ.cjs → chunk-4NZTK7LM.cjs} +35 -35
- package/dist/{chunk-CVBTJVRN.js → chunk-DWPFGWW5.js} +1 -1
- package/dist/{chunk-XMSH66VU.js → chunk-FNIWHSLI.js} +1 -1
- package/dist/{chunk-QNNZA3V5.cjs → chunk-H3EME3S5.cjs} +2 -2
- package/dist/{chunk-4EM5NGCL.js → chunk-HHX7ST6Z.js} +1 -1
- package/dist/{chunk-Q33V5PEF.cjs → chunk-HRUK5TFW.cjs} +73 -12
- package/dist/{chunk-5HR5CSLC.cjs → chunk-JVFGK3DK.cjs} +69 -58
- package/dist/{chunk-JNMNM3SL.js → chunk-LZE2QZCT.js} +1 -1
- package/dist/{chunk-OS6OG7DN.js → chunk-N4MCWQZ7.js} +1 -1
- package/dist/{chunk-IJ6NSWKM.js → chunk-NJLPW4MM.js} +17 -6
- package/dist/{chunk-OY24XRYF.cjs → chunk-PEQWARCP.cjs} +12 -12
- package/dist/{chunk-XVPQNX7O.js → chunk-PPDUCZZV.js} +66 -5
- package/dist/{chunk-X7XBEX3O.cjs → chunk-QBZEC2JJ.cjs} +86 -86
- package/dist/{chunk-GHYJAMMS.js → chunk-ROURHJYT.js} +1 -1
- package/dist/{chunk-ZIE6EJGR.cjs → chunk-VNF7A2JA.cjs} +23 -23
- package/dist/{chunk-ISCAJBPQ.cjs → chunk-WFSYZO5Z.cjs} +1 -1
- package/dist/image-editor/index.cjs +788 -788
- package/dist/image-editor/index.js +4 -4
- package/dist/paint-editor/brush-model.d.cts +15 -1
- package/dist/paint-editor/brush-model.d.ts +15 -1
- package/dist/paint-editor/controller.d.cts +50 -1
- package/dist/paint-editor/controller.d.ts +50 -1
- package/dist/paint-editor/document.d.cts +8 -1
- package/dist/paint-editor/document.d.ts +8 -1
- package/dist/paint-editor/ferro-tools.d.cts +10 -0
- package/dist/paint-editor/ferro-tools.d.ts +10 -0
- package/dist/paint-editor/ferro.d.cts +134 -0
- package/dist/paint-editor/ferro.d.ts +134 -0
- package/dist/paint-editor/index.cjs +1878 -831
- package/dist/paint-editor/index.d.cts +2 -0
- package/dist/paint-editor/index.d.ts +2 -0
- package/dist/paint-editor/index.js +1184 -137
- package/dist/paint-editor/stroke.d.cts +14 -0
- package/dist/paint-editor/stroke.d.ts +14 -0
- package/dist/paint-editor/thick.d.cts +15 -2
- package/dist/paint-editor/thick.d.ts +15 -2
- package/dist/paint-editor/ui.d.cts +2 -0
- package/dist/paint-editor/ui.d.ts +2 -0
- package/dist/vector/index.cjs +998 -998
- package/dist/vector/index.js +4 -4
- package/package.json +1 -1
- package/skills/pixerate-brushes/SKILL.md +1 -0
- package/skills/pixerate-paint-editor/SKILL.md +11 -29
- package/skills/pixerate-paint-editor/references/brush-facets.md +1 -0
- package/skills/pixerate-paint-editor/references/ferrofluid.md +36 -0
package/dist/brushes/index.cjs
CHANGED
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
|
|
19
19
|
|
|
20
20
|
|
|
21
|
-
var
|
|
21
|
+
var _chunkJVFGK3DKcjs = require('../chunk-JVFGK3DK.cjs');
|
|
22
22
|
require('../chunk-PFHJS4HE.cjs');
|
|
23
23
|
|
|
24
24
|
|
|
@@ -27,7 +27,7 @@ require('../chunk-PFHJS4HE.cjs');
|
|
|
27
27
|
|
|
28
28
|
|
|
29
29
|
|
|
30
|
-
var
|
|
30
|
+
var _chunkH3EME3S5cjs = require('../chunk-H3EME3S5.cjs');
|
|
31
31
|
|
|
32
32
|
|
|
33
33
|
|
|
@@ -102,7 +102,7 @@ var _chunkQNNZA3V5cjs = require('../chunk-QNNZA3V5.cjs');
|
|
|
102
102
|
|
|
103
103
|
|
|
104
104
|
|
|
105
|
-
var
|
|
105
|
+
var _chunkHRUK5TFWcjs = require('../chunk-HRUK5TFW.cjs');
|
|
106
106
|
|
|
107
107
|
|
|
108
108
|
var _chunkRDFHWAHLcjs = require('../chunk-RDFHWAHL.cjs');
|
|
@@ -167,20 +167,20 @@ var ARIA = {
|
|
|
167
167
|
"livePatterns.pattern": "Live pattern"
|
|
168
168
|
};
|
|
169
169
|
var aria = (path, label) => _nullishCoalesce(ARIA[path], () => ( `Brush ${label.toLowerCase()}`));
|
|
170
|
-
function brushEditorSections(brush, profile =
|
|
171
|
-
const resolved =
|
|
172
|
-
const engine =
|
|
173
|
-
const fieldOf = (facet) =>
|
|
174
|
-
const facetOf = (enginePath) => _optionalChain([(_nullishCoalesce(
|
|
170
|
+
function brushEditorSections(brush, profile = _chunkHRUK5TFWcjs.PAINT_PROFILE, context = {}) {
|
|
171
|
+
const resolved = _chunkHRUK5TFWcjs.resolveBrush.call(void 0, brush);
|
|
172
|
+
const engine = _chunkHRUK5TFWcjs.resolveEngine.call(void 0, brush);
|
|
173
|
+
const fieldOf = (facet) => _chunkHRUK5TFWcjs.BRUSH_FIELDS.find((f) => f.facet === facet && f.engines.includes(engine));
|
|
174
|
+
const facetOf = (enginePath) => _optionalChain([(_nullishCoalesce(_chunkHRUK5TFWcjs.BRUSH_FIELDS.find((f) => f.engine === enginePath && f.engines.includes(engine)), () => ( _chunkHRUK5TFWcjs.BRUSH_FIELDS.find((f) => f.engine === enginePath)))), 'optionalAccess', _ => _.facet]);
|
|
175
175
|
const value = (path) => {
|
|
176
|
-
const own =
|
|
176
|
+
const own = _chunkHRUK5TFWcjs.getPath.call(void 0, brush, path);
|
|
177
177
|
if (own !== void 0) return own;
|
|
178
178
|
const field = fieldOf(path);
|
|
179
179
|
if (!field) return void 0;
|
|
180
|
-
const v =
|
|
180
|
+
const v = _chunkHRUK5TFWcjs.getPath.call(void 0, resolved, field.engine);
|
|
181
181
|
return field.map ? field.map.toFacet(v) : v;
|
|
182
182
|
};
|
|
183
|
-
const issues =
|
|
183
|
+
const issues = _chunkHRUK5TFWcjs.checkBrush.call(void 0, brush, profile).issues;
|
|
184
184
|
const warned = new Map(issues.filter((i) => i.severity === "warning").map((i) => [i.facet, i.reason]));
|
|
185
185
|
const refused = new Set(issues.filter((i) => i.severity === "error").map((i) => i.facet));
|
|
186
186
|
const full = (s) => s === "full";
|
|
@@ -205,30 +205,30 @@ function brushEditorSections(brush, profile = _chunkQ33V5PEFcjs.PAINT_PROFILE, c
|
|
|
205
205
|
};
|
|
206
206
|
const isTool = brush.kind === "tool";
|
|
207
207
|
const shape = brush.tip.shape;
|
|
208
|
-
const sourceOptions = (_nullishCoalesce(context.sources, () => ( []))).map((x) => ({ value:
|
|
208
|
+
const sourceOptions = (_nullishCoalesce(context.sources, () => ( []))).map((x) => ({ value: _chunkHRUK5TFWcjs.brushSourceRef.call(void 0, x.id), label: x.name }));
|
|
209
209
|
const marks = _nullishCoalesce(_optionalChain([brush, 'access', _7 => _7.marks, 'optionalAccess', _8 => _8.kind]), () => ( "continuous"));
|
|
210
210
|
const exchangeFull = full(_optionalChain([brush, 'access', _9 => _9.behaviour, 'optionalAccess', _10 => _10.exchange, 'optionalAccess', _11 => _11.reservoir]) ? profile.reservoir : profile.exchange);
|
|
211
211
|
add("medium", "Medium", [
|
|
212
212
|
profile.kinds.length > 1 && profile.kinds.includes(brush.kind) && choice("kind", "Kind", options(profile.kinds, { mark: "Lays a material", tool: "Works on paint" })),
|
|
213
|
-
!isTool && choice("medium", "Medium", [{ value: "", label: "Any" }, ...options(
|
|
213
|
+
!isTool && choice("medium", "Medium", [{ value: "", label: "Any" }, ...options(_chunkHRUK5TFWcjs.BRUSH_MEDIA, MEDIUM_LABELS)], ""),
|
|
214
214
|
!isTool && withNote({ kind: "text", path: "variety", label: "Variety", ariaLabel: "Brush variety", value: _nullishCoalesce(brush.variety, () => ( "")), placeholder: "pencil, oil, highlighter\u2026" }),
|
|
215
215
|
isTool && !!brush.tool && profile.tools.includes(brush.tool) && choice("tool", "Tool", options(profile.tools, TOOL_LABELS))
|
|
216
216
|
]);
|
|
217
|
-
const engineControls =
|
|
218
|
-
const tipSliders =
|
|
217
|
+
const engineControls = _chunkJVFGK3DKcjs.brushEngineControls.call(void 0, resolved);
|
|
218
|
+
const tipSliders = _chunkJVFGK3DKcjs.BRUSH_SLIDERS.filter((c) => c.path.startsWith("tip.") && c.path !== "tip.smoothing");
|
|
219
219
|
add("shape", "Shape", [
|
|
220
220
|
!refused.has("tip.shape") && choice("tip.shape", "Tip", options(profile.tipShapes.filter((s) => !isTool || s !== "stamp"), SHAPE_LABELS)),
|
|
221
221
|
...tipSliders.map((c) => slider(c)),
|
|
222
222
|
engine === "dab" && choice("tip.blend", "Blend", _chunk2VX55NFMcjs.BLEND_MODES.map((m) => ({ value: m.id, label: m.label })), "normal"),
|
|
223
223
|
...shape === "bristle" && engineOk && engineControls ? engineControls.sliders.filter((c) => c.path.startsWith("bristle.")).map((c) => slider(c)) : [],
|
|
224
|
-
shape === "stamp" && engineOk && withNote({ kind: "stamps", path: "tip.stamps", label: "Stamps", ariaLabel: "Brush stamps", value: [..._nullishCoalesce(value("tip.stamps"), () => ( []))], max: marks === "particles" ?
|
|
224
|
+
shape === "stamp" && engineOk && withNote({ kind: "stamps", path: "tip.stamps", label: "Stamps", ariaLabel: "Brush stamps", value: [..._nullishCoalesce(value("tip.stamps"), () => ( []))], max: marks === "particles" ? _chunkHRUK5TFWcjs.MAX_DOT_TEXTURES : _chunkHRUK5TFWcjs.MAX_STICKER_STAMPS, options: marks === "objects" ? STAMP_OPTIONS : [...STAMP_OPTIONS, ...sourceOptions] })
|
|
225
225
|
]);
|
|
226
226
|
const dabs = DAB_ENGINES.has(engine) && engineOk && shape !== "bristle" && marks !== "particles" && marks !== "objects";
|
|
227
227
|
const grain = brush.tip.grain;
|
|
228
228
|
if (dabs && full(_nullishCoalesce(profile.tipGrain, () => ( "none")))) {
|
|
229
229
|
add("grain", "Tip grain", [
|
|
230
|
-
choice("tip.grain.source", "Texture", [{ value: "", label: "None" }, ...options(
|
|
231
|
-
!!grain && choice("tip.grain.mode", "Grain moves", options(
|
|
230
|
+
choice("tip.grain.source", "Texture", [{ value: "", label: "None" }, ...options(_chunkHRUK5TFWcjs.TIP_GRAIN_PATTERNS), ...sourceOptions], ""),
|
|
231
|
+
!!grain && choice("tip.grain.mode", "Grain moves", options(_chunkHRUK5TFWcjs.BRUSH_GRAIN_MODES, GRAIN_MODE_LABELS), "texturised"),
|
|
232
232
|
!!grain && withNote({ kind: "slider", path: "tip.grain.scale", label: "Grain scale", ariaLabel: "Brush grain scale", min: 0.1, max: 8, step: 0.05, value: _nullishCoalesce(grain.scale, () => ( 1)) }),
|
|
233
233
|
!!grain && withNote({ kind: "slider", path: "tip.grain.depth", label: "Grain depth", ariaLabel: "Brush grain depth", min: 0, max: 1, step: 0.01, value: _nullishCoalesce(grain.depth, () => ( 0.6)) }),
|
|
234
234
|
!!grain && withNote({ kind: "slider", path: "tip.grain.contrast", label: "Grain contrast", ariaLabel: "Brush grain contrast", min: 0, max: 3, step: 0.05, value: _nullishCoalesce(grain.contrast, () => ( 1)) }),
|
|
@@ -241,28 +241,28 @@ function brushEditorSections(brush, profile = _chunkQ33V5PEFcjs.PAINT_PROFILE, c
|
|
|
241
241
|
const render = value("marks.render");
|
|
242
242
|
add("marks", "Marks", [
|
|
243
243
|
choice("marks.kind", "Laid as", options(profile.marks, MARKS_LABELS), "continuous"),
|
|
244
|
-
marks === "particles" && choice("marks.physics", "Particles", options(
|
|
245
|
-
marks === "particles" && choice("marks.render", "Drawn as", options(
|
|
246
|
-
marks === "particles" && render === "ribbon" && choice("marks.ribbonPairs", "Ribbon joins", options(
|
|
247
|
-
marks === "particles" && shape === "stamp" && choice("marks.stampOrder", "Texture order", options(
|
|
248
|
-
marks === "particles" && shape === "stamp" && choice("marks.stampRotation", "Texture turn", options(
|
|
244
|
+
marks === "particles" && choice("marks.physics", "Particles", options(_chunkHRUK5TFWcjs.PARTICLE_KINDS, PHYSICS_LABELS)),
|
|
245
|
+
marks === "particles" && choice("marks.render", "Drawn as", options(_chunkHRUK5TFWcjs.PARTICLE_RENDERS, RENDER_LABELS)),
|
|
246
|
+
marks === "particles" && render === "ribbon" && choice("marks.ribbonPairs", "Ribbon joins", options(_chunkHRUK5TFWcjs.RIBBON_PAIRS, { adjacent: "Neighbours", "first-last": "Outermost" })),
|
|
247
|
+
marks === "particles" && shape === "stamp" && choice("marks.stampOrder", "Texture order", options(_chunkHRUK5TFWcjs.DOT_TEXTURE_ORDERS, { sequence: "In turn", random: "Random" })),
|
|
248
|
+
marks === "particles" && shape === "stamp" && choice("marks.stampRotation", "Texture turn", options(_chunkHRUK5TFWcjs.DOT_ROTATIONS, { follow: "Follow motion", random: "Random", fixed: "Tip angle" })),
|
|
249
249
|
...particles.map((c) => slider(c)),
|
|
250
250
|
...objects.map((c) => slider(c))
|
|
251
251
|
]);
|
|
252
252
|
}
|
|
253
|
-
const feel =
|
|
253
|
+
const feel = _chunkJVFGK3DKcjs.BRUSH_SLIDERS.filter((c) => ["tip.smoothing", "pressureSmoothing", "dynamics.minSize", "dynamics.tiltSize", "dynamics.velocitySize"].includes(c.path)).filter((c) => !(c.path === "dynamics.tiltSize" && !full(profile.tilt)) && !(c.path === "dynamics.velocitySize" && !full(profile.velocity)));
|
|
254
254
|
const stampDabs = dabs && shape === "stamp";
|
|
255
255
|
const jitter = (path, label, max = 1, step = 0.01) => withNote({ kind: "slider", path, label, ariaLabel: aria(path, label), min: 0, max, step, value: Number(_nullishCoalesce(value(path), () => ( 0))) });
|
|
256
256
|
add("feel", "Feel", [
|
|
257
257
|
...feel.map((c) => slider(c)),
|
|
258
258
|
toggle("dynamics.pressureSize", "Pressure \u2192 size"),
|
|
259
259
|
toggle("dynamics.pressureOpacity", "Pressure \u2192 opacity"),
|
|
260
|
-
choice("dynamics.rotation", "Rotation", options(
|
|
260
|
+
choice("dynamics.rotation", "Rotation", options(_chunkHRUK5TFWcjs.BRUSH_ROTATIONS, ROTATION_LABELS)),
|
|
261
261
|
stampDabs && full(_nullishCoalesce(profile.dabCount, () => ( "none"))) && withNote({ kind: "slider", path: "dynamics.count", label: "Count", ariaLabel: "Brush dab count", min: 1, max: 16, step: 1, value: _nullishCoalesce(_optionalChain([brush, 'access', _12 => _12.dynamics, 'optionalAccess', _13 => _13.count]), () => ( 1)) }),
|
|
262
262
|
stampDabs && jitter("dynamics.scatter", "Scatter", 4),
|
|
263
263
|
stampDabs && jitter("dynamics.angleJitter", "Rotation jitter"),
|
|
264
264
|
stampDabs && jitter("dynamics.sizeJitter", "Size jitter"),
|
|
265
|
-
stampDabs && choice("dynamics.flip", "Flip", options(
|
|
265
|
+
stampDabs && choice("dynamics.flip", "Flip", options(_chunkHRUK5TFWcjs.BRUSH_FLIPS, FLIP_LABELS), "none")
|
|
266
266
|
]);
|
|
267
267
|
const surfaces = profile.surfaces;
|
|
268
268
|
const engineSliders = (engineOk ? _nullishCoalesce(_optionalChain([engineControls, 'optionalAccess', _14 => _14.sliders]), () => ( [])) : []).filter((c) => !/^(bristle|particle|sticker|iridescence)\./.test(c.path) && c.path !== "light.amount" && c.path !== "impasto.rim" && c.path !== "impasto.clarity");
|
|
@@ -270,8 +270,8 @@ function brushEditorSections(brush, profile = _chunkQ33V5PEFcjs.PAINT_PROFILE, c
|
|
|
270
270
|
add("behaviour", _nullishCoalesce(_optionalChain([engineControls, 'optionalAccess', _17 => _17.title]), () => ( "Behaviour")), [
|
|
271
271
|
!isTool && surfaces.length > 1 && !refused.has("behaviour.surface") && choice("behaviour.surface", "Surface", options(surfaces, SURFACE_LABELS), "dry"),
|
|
272
272
|
full(profile.grain) && slider({ path: "grain", label: "Grain", min: 0, max: 1, step: 0.01 }, "behaviour.grain"),
|
|
273
|
-
engine === "wet" && engineOk && !isTool && choice("behaviour.wet.medium", "Medium", options(
|
|
274
|
-
engine === "impasto" && engineOk && choice("behaviour.thick.applicator", "Tool", options(
|
|
273
|
+
engine === "wet" && engineOk && !isTool && choice("behaviour.wet.medium", "Medium", options(_chunkHRUK5TFWcjs.WET_MEDIA, WET_MEDIUM_LABELS), "watercolor"),
|
|
274
|
+
engine === "impasto" && engineOk && choice("behaviour.thick.applicator", "Tool", options(_chunkHRUK5TFWcjs.IMPASTO_TOOLS, APPLICATOR_LABELS), "brush"),
|
|
275
275
|
...engineSliders.map((c) => exchangeOk(facetOf(c.path)) ? slider(c) : null),
|
|
276
276
|
engineOk && _optionalChain([engineControls, 'optionalAccess', _18 => _18.mixingPath]) && (engine === "wet" || exchangeFull) && fieldOf("behaviour.mixing") && choice("behaviour.mixing", "Mixing", options(["pigment", "rgb"], { pigment: "Pigment", rgb: "RGB" })),
|
|
277
277
|
engineOk && _optionalChain([engineControls, 'optionalAccess', _19 => _19.dirty]) && exchangeFull && fieldOf("behaviour.exchange.dirty") && toggle("behaviour.exchange.dirty", "Dirty brush"),
|
|
@@ -313,7 +313,7 @@ function brushEditorSections(brush, profile = _chunkQ33V5PEFcjs.PAINT_PROFILE, c
|
|
|
313
313
|
label: "Palette",
|
|
314
314
|
ariaLabel: "Brush palette",
|
|
315
315
|
value: (_nullishCoalesce(_optionalChain([brush, 'access', _32 => _32.colour, 'optionalAccess', _33 => _33.palette]), () => ( []))).flatMap((c) => _chunkMLLTWAXHcjs.isDualColor.call(void 0, c) ? [{ light: _chunkJBZRVLXVcjs.brushColourHex.call(void 0, c, "light"), dark: _chunkJBZRVLXVcjs.brushColourHex.call(void 0, c, "dark") }] : hex(c) ? [hex(c)] : []),
|
|
316
|
-
max:
|
|
316
|
+
max: _chunkHRUK5TFWcjs.MAX_BRUSH_PALETTE
|
|
317
317
|
}),
|
|
318
318
|
toggle("colour.own", "Always its own colour")
|
|
319
319
|
]);
|
|
@@ -363,15 +363,15 @@ function hiddenLabel(issue, b) {
|
|
|
363
363
|
case "dynamics.tilt":
|
|
364
364
|
return "tilt dynamics";
|
|
365
365
|
case "colour.default":
|
|
366
|
-
return `a ${
|
|
366
|
+
return `a ${_chunkHRUK5TFWcjs.brushColourKind.call(void 0, b.colour.default)} default colour`;
|
|
367
367
|
default:
|
|
368
368
|
return null;
|
|
369
369
|
}
|
|
370
370
|
}
|
|
371
371
|
var sentence = (words) => words.length < 2 ? _nullishCoalesce(words[0], () => ( "")) : `${words.slice(0, -1).join(", ")} and ${words.at(-1)}`;
|
|
372
|
-
function brushEditorScope(brush, profile =
|
|
372
|
+
function brushEditorScope(brush, profile = _chunkHRUK5TFWcjs.PAINT_PROFILE) {
|
|
373
373
|
const hidden = [];
|
|
374
|
-
for (const issue of
|
|
374
|
+
for (const issue of _chunkHRUK5TFWcjs.checkBrush.call(void 0, brush, profile).issues) {
|
|
375
375
|
const label = hiddenLabel(issue, brush);
|
|
376
376
|
if (label && !hidden.some((h) => h.label === label)) hidden.push({ facet: issue.facet, label });
|
|
377
377
|
}
|
|
@@ -384,17 +384,17 @@ function newBrushFor(profile, from, name = "New brush") {
|
|
|
384
384
|
const id = brushIdFromName(name);
|
|
385
385
|
const base = { id, name, kind: profile.kinds.includes("mark") ? "mark" : profile.kinds[0], ...profile.kinds.includes("mark") ? {} : { tool: profile.tools[0] }, tip: { shape: profile.tipShapes.includes("round") ? "round" : profile.tipShapes[0] } };
|
|
386
386
|
if (from) {
|
|
387
|
-
const stripped =
|
|
387
|
+
const stripped = _chunkHRUK5TFWcjs.degrade.call(void 0, from, profile, { ignored: true });
|
|
388
388
|
if (!stripped.issues.length) return { ...stripped.brush, id, name };
|
|
389
389
|
}
|
|
390
390
|
return base;
|
|
391
391
|
}
|
|
392
392
|
async function saveBrushEdit(library, options2) {
|
|
393
393
|
const { original, profile } = options2;
|
|
394
|
-
const check =
|
|
394
|
+
const check = _chunkHRUK5TFWcjs.checkBrushEdit.call(void 0, original, options2.brush, profile);
|
|
395
395
|
if (!check.ok) {
|
|
396
396
|
const errors = check.issues.filter((i) => i.severity === "error").map((i) => `${i.facet}: ${i.reason} ${i.fix}`);
|
|
397
|
-
throw new (0,
|
|
397
|
+
throw new (0, _chunkHRUK5TFWcjs.BrushLibraryError)("invalid", `${profile.name} can't use this brush: ${errors.join(" ")} Nothing was saved.`);
|
|
398
398
|
}
|
|
399
399
|
const inPlace = !!original && options2.name === void 0 && !library.isBuiltin(original.id) && original.id === options2.brush.id && !!await library.get(original.id);
|
|
400
400
|
let brush = options2.brush;
|
|
@@ -421,6 +421,7 @@ function setBrushEditorValue(brush, path, value) {
|
|
|
421
421
|
delete next.iridescence;
|
|
422
422
|
delete next.ghost;
|
|
423
423
|
delete next.mutation;
|
|
424
|
+
delete next.ferro;
|
|
424
425
|
delete next.colour;
|
|
425
426
|
next.tool = _nullishCoalesce(next.tool, () => ( "eraser"));
|
|
426
427
|
if (next.tip.shape === "stamp") next.tip = { shape: "round", ...next.tip.size !== void 0 ? { size: next.tip.size } : {} };
|
|
@@ -442,13 +443,13 @@ function setBrushEditorValue(brush, path, value) {
|
|
|
442
443
|
if (value !== "bristle") delete next.tip.bristle;
|
|
443
444
|
} else if (value === void 0 || value === "") {
|
|
444
445
|
const keys = path.split(".");
|
|
445
|
-
const parent =
|
|
446
|
+
const parent = _chunkHRUK5TFWcjs.getPath.call(void 0, next, keys.slice(0, -1).join("."));
|
|
446
447
|
if (keys.length === 1) delete next[keys[0]];
|
|
447
448
|
else if (parent) delete parent[keys[keys.length - 1]];
|
|
448
|
-
} else
|
|
449
|
+
} else _chunkHRUK5TFWcjs.setPath.call(void 0, next, path, value);
|
|
449
450
|
const problems = [];
|
|
450
451
|
try {
|
|
451
|
-
return { brush:
|
|
452
|
+
return { brush: _chunkHRUK5TFWcjs.normalizeBrushSpec.call(void 0, JSON.parse(JSON.stringify(next)), problems), problems };
|
|
452
453
|
} catch (e) {
|
|
453
454
|
return { brush, problems: [e.message] };
|
|
454
455
|
}
|
|
@@ -464,7 +465,7 @@ function brushLibraryGroups(entries, filter = {}) {
|
|
|
464
465
|
const text = words([b.id, b.name, _nullishCoalesce(b.variety, () => ( "")), _nullishCoalesce(b.medium, () => ( "")), _nullishCoalesce(b.tool, () => ( "")), ..._nullishCoalesce(b.tags, () => ( []))].join(" "));
|
|
465
466
|
if (!wanted.every((w) => text.some((t) => t.startsWith(w)))) continue;
|
|
466
467
|
}
|
|
467
|
-
if (filter.profile && !
|
|
468
|
+
if (filter.profile && !_chunkHRUK5TFWcjs.checkBrush.call(void 0, b, filter.profile).ok) continue;
|
|
468
469
|
const id = b.kind === "tool" ? "tools" : _nullishCoalesce(b.medium, () => ( "other"));
|
|
469
470
|
let g = groups.get(id);
|
|
470
471
|
if (!g) groups.set(id, g = { id, title: id === "tools" ? "Tools" : id === "other" ? "Other" : MEDIUM_LABELS[id], varieties: [] });
|
|
@@ -480,7 +481,7 @@ async function imageFileToPngDataUrl(file) {
|
|
|
480
481
|
const bytes = new Uint8Array(await file.arrayBuffer());
|
|
481
482
|
if (_chunkW5M3J7PVcjs.isPng.call(void 0, bytes)) return `data:image/png;base64,${_chunkW5M3J7PVcjs.bytesToBase64.call(void 0, bytes)}`;
|
|
482
483
|
const g = globalThis;
|
|
483
|
-
if (!g.createImageBitmap || !g.OffscreenCanvas) throw new (0,
|
|
484
|
+
if (!g.createImageBitmap || !g.OffscreenCanvas) throw new (0, _chunkHRUK5TFWcjs.BrushSourceError)("Only PNG images can be read here; convert the image to PNG.");
|
|
484
485
|
const bitmap = await g.createImageBitmap(file);
|
|
485
486
|
const canvas = new g.OffscreenCanvas(bitmap.width, bitmap.height);
|
|
486
487
|
canvas.getContext("2d").drawImage(bitmap, 0, 0);
|
|
@@ -490,7 +491,7 @@ async function imageFileToPngDataUrl(file) {
|
|
|
490
491
|
async function addBrushSourceFromFile(library, file, options2 = {}) {
|
|
491
492
|
const name = (_nullishCoalesce(_nullishCoalesce(options2.name, () => ( _optionalChain([file, 'access', _38 => _38.name, 'optionalAccess', _39 => _39.replace, 'call', _40 => _40(/\.[a-z0-9]+$/i, "")]))), () => ( "Image"))).trim() || "Image";
|
|
492
493
|
const result = await library.addSource({ name, image: await imageFileToPngDataUrl(file), origin: file.name, ...options2.channel ? { channel: options2.channel } : {} });
|
|
493
|
-
return { ...result, ref:
|
|
494
|
+
return { ...result, ref: _chunkHRUK5TFWcjs.brushSourceRef.call(void 0, result.source.id) };
|
|
494
495
|
}
|
|
495
496
|
function withBrushSource(brush, ref, as) {
|
|
496
497
|
if (as === "grain") return setBrushEditorValue(brush, "tip.grain.source", ref);
|
|
@@ -508,11 +509,11 @@ var BRUSH_PROFILE_JSON_SCHEMA = {
|
|
|
508
509
|
properties: {
|
|
509
510
|
id: { type: "string", description: "paint, image, canvas, vector\u2026" },
|
|
510
511
|
name: { type: "string", description: "Display name, used in messages." },
|
|
511
|
-
kinds: { type: "array", items: { type: "string", enum: [...
|
|
512
|
-
tools: { type: "array", items: { type: "string", enum: [...
|
|
513
|
-
tipShapes: { type: "array", items: { type: "string", enum: [...
|
|
514
|
-
marks: { type: "array", items: { type: "string", enum: [...
|
|
515
|
-
surfaces: { type: "array", items: { type: "string", enum: [...
|
|
512
|
+
kinds: { type: "array", items: { type: "string", enum: [..._chunkHRUK5TFWcjs.BRUSH_KINDS] }, description: "Brush kinds it has." },
|
|
513
|
+
tools: { type: "array", items: { type: "string", enum: [..._chunkHRUK5TFWcjs.BRUSH_TOOLS] }, description: "Tools it has (kind tool)." },
|
|
514
|
+
tipShapes: { type: "array", items: { type: "string", enum: [..._chunkHRUK5TFWcjs.BRUSH_TIP_SHAPES] }, description: "Tip shapes it renders." },
|
|
515
|
+
marks: { type: "array", items: { type: "string", enum: [..._chunkHRUK5TFWcjs.BRUSH_MARKS_KINDS] }, description: "Marks kinds it renders." },
|
|
516
|
+
surfaces: { type: "array", items: { type: "string", enum: [..._chunkHRUK5TFWcjs.BRUSH_SURFACES] }, description: "Surfaces it renders." },
|
|
516
517
|
exchange: { ...SUPPORT, description: "Picking paint up and mixing it in." },
|
|
517
518
|
reservoir: { ...SUPPORT, description: "The Mixer Brush reservoir." },
|
|
518
519
|
grain: { ...SUPPORT, description: "Paper grain response." },
|
|
@@ -524,7 +525,8 @@ var BRUSH_PROFILE_JSON_SCHEMA = {
|
|
|
524
525
|
tipGrain: { ...SUPPORT, description: "Texture inside the tip (tip.grain); missing: none." },
|
|
525
526
|
dabCount: { ...SUPPORT, description: "Several dabs per spacing step (dynamics.count); missing: none." },
|
|
526
527
|
livePatterns: { ...SUPPORT, description: "Gray-Scott reaction-diffusion patterns in wet paint (livePatterns); missing: none." },
|
|
527
|
-
iridescence: { ...SUPPORT, description: "Thin-film iridescence (iridescence); missing: none." }
|
|
528
|
+
iridescence: { ...SUPPORT, description: "Thin-film iridescence (iridescence); missing: none." },
|
|
529
|
+
ferro: { ...SUPPORT, description: "Liquid ferrofluid (ferro); missing: none." }
|
|
528
530
|
},
|
|
529
531
|
required: ["id", "name", "kinds", "tools", "tipShapes", "marks", "surfaces", "exchange", "reservoir", "grain", "light", "motion", "colours", "velocity", "tilt"],
|
|
530
532
|
additionalProperties: false
|
|
@@ -538,16 +540,16 @@ var BRUSH_LIBRARY_FILE_JSON_SCHEMA = {
|
|
|
538
540
|
brushes: { type: "array", items: { $ref: "brush.schema.json" }, description: "The brushes, each a facet brush (brush.schema.json)." },
|
|
539
541
|
sources: {
|
|
540
542
|
type: "array",
|
|
541
|
-
maxItems:
|
|
543
|
+
maxItems: _chunkHRUK5TFWcjs.MAX_BRUSH_SOURCES,
|
|
542
544
|
description: "The image sources the brushes name (source:<id> in tip.stamps or tip.grain.source), bytes included.",
|
|
543
545
|
items: {
|
|
544
546
|
type: "object",
|
|
545
547
|
description: "An image source: a grey mask, 255 paints (or is a grain peak).",
|
|
546
548
|
properties: {
|
|
547
|
-
id: { type: "string", pattern:
|
|
549
|
+
id: { type: "string", pattern: _chunkHRUK5TFWcjs.BRUSH_ID.source, description: "Source id." },
|
|
548
550
|
name: { type: "string", maxLength: 80, description: "Display name." },
|
|
549
|
-
width: { type: "integer", minimum: 1, maximum:
|
|
550
|
-
height: { type: "integer", minimum: 1, maximum:
|
|
551
|
+
width: { type: "integer", minimum: 1, maximum: _chunkHRUK5TFWcjs.MAX_BRUSH_SOURCE_SIZE, description: "Width in px." },
|
|
552
|
+
height: { type: "integer", minimum: 1, maximum: _chunkHRUK5TFWcjs.MAX_BRUSH_SOURCE_SIZE, description: "Height in px." },
|
|
551
553
|
image: { type: "string", pattern: "^data:image/png;base64,", description: "The mask as a greyscale PNG data: URL." },
|
|
552
554
|
licence: { type: "string", maxLength: 2e3, description: "The licence or terms it came with." },
|
|
553
555
|
origin: { type: "string", maxLength: 200, description: "Where it came from (a file or pack name)." }
|
|
@@ -561,7 +563,7 @@ var BRUSH_LIBRARY_FILE_JSON_SCHEMA = {
|
|
|
561
563
|
additionalProperties: false
|
|
562
564
|
};
|
|
563
565
|
function migrationInputs() {
|
|
564
|
-
const pick = (id) =>
|
|
566
|
+
const pick = (id) => _chunkHRUK5TFWcjs.brushToJSON.call(void 0, _chunkHRUK5TFWcjs.BUILTIN_BRUSHES.find((b) => b.id === id));
|
|
565
567
|
return [
|
|
566
568
|
{ id: "plain", name: "Plain" },
|
|
567
569
|
pick("pencil-6b"),
|
|
@@ -583,34 +585,34 @@ function migrationInputs() {
|
|
|
583
585
|
function editorSectionFixtures() {
|
|
584
586
|
const ids = ["highlighter", "chalk", "watercolor-wash", "hair-strands", "mixer-brush", "blender", "spray-can"];
|
|
585
587
|
return ids.flatMap(
|
|
586
|
-
(id) => Object.keys(
|
|
587
|
-
const brush =
|
|
588
|
-
return { brush: id, host, sections: brushEditorSections(brush,
|
|
588
|
+
(id) => Object.keys(_chunkHRUK5TFWcjs.BRUSH_HOST_PROFILES).map((host) => {
|
|
589
|
+
const brush = _chunkHRUK5TFWcjs.BRUSH_PRESETS.find((b) => b.id === id);
|
|
590
|
+
return { brush: id, host, sections: brushEditorSections(brush, _chunkHRUK5TFWcjs.BRUSH_HOST_PROFILES[host]) };
|
|
589
591
|
})
|
|
590
592
|
);
|
|
591
593
|
}
|
|
592
594
|
function toolDefinitions() {
|
|
593
|
-
const library =
|
|
594
|
-
const toolsFor = (host) =>
|
|
595
|
+
const library = _chunkHRUK5TFWcjs.createBrushLibrary.call(void 0, );
|
|
596
|
+
const toolsFor = (host) => _chunkJVFGK3DKcjs.createBrushLibraryTools.call(void 0, library, { profile: _chunkHRUK5TFWcjs.BRUSH_HOST_PROFILES[host], renderPreview: () => ({ data: "", mimeType: "image/png" }) });
|
|
595
597
|
return {
|
|
596
598
|
tools: toolsFor("paint").map((t) => ({ name: t.name, title: t.title, description: t.description, inputSchema: t.inputSchema, annotations: t.annotations })),
|
|
597
|
-
hosts: Object.fromEntries(Object.keys(
|
|
599
|
+
hosts: Object.fromEntries(Object.keys(_chunkHRUK5TFWcjs.BRUSH_HOST_PROFILES).map((host) => [host, toolsFor(host).map((t) => t.name)]))
|
|
598
600
|
};
|
|
599
601
|
}
|
|
600
602
|
function brushContracts() {
|
|
601
|
-
const presets =
|
|
602
|
-
const resolved =
|
|
603
|
-
const profiles = Object.values(
|
|
604
|
-
const checks =
|
|
603
|
+
const presets = _chunkHRUK5TFWcjs.BRUSH_PRESETS.map((b) => JSON.parse(JSON.stringify(b)));
|
|
604
|
+
const resolved = _chunkHRUK5TFWcjs.BRUSH_PRESETS.map((b) => ({ id: b.id, engine: _chunkHRUK5TFWcjs.resolveEngine.call(void 0, b), category: _chunkHRUK5TFWcjs.resolveCategory.call(void 0, b), brush: _chunkHRUK5TFWcjs.brushToJSON.call(void 0, _chunkHRUK5TFWcjs.resolveBrush.call(void 0, b)) }));
|
|
605
|
+
const profiles = Object.values(_chunkHRUK5TFWcjs.BRUSH_HOST_PROFILES);
|
|
606
|
+
const checks = _chunkHRUK5TFWcjs.BRUSH_PRESETS.map((b) => ({
|
|
605
607
|
id: b.id,
|
|
606
608
|
hosts: Object.fromEntries(profiles.map((p) => {
|
|
607
|
-
const c =
|
|
609
|
+
const c = _chunkHRUK5TFWcjs.checkBrush.call(void 0, b, p);
|
|
608
610
|
return [p.id, { ok: c.ok, issues: c.issues.map(({ facet, severity }) => ({ facet, severity })) }];
|
|
609
611
|
}))
|
|
610
612
|
}));
|
|
611
|
-
const migrations = migrationInputs().map((input) => ({ input, output:
|
|
613
|
+
const migrations = migrationInputs().map((input) => ({ input, output: _chunkHRUK5TFWcjs.migrateBrushV1.call(void 0, input), resolved: _chunkHRUK5TFWcjs.brushToJSON.call(void 0, _chunkHRUK5TFWcjs.resolveBrush.call(void 0, _chunkHRUK5TFWcjs.migrateBrushV1.call(void 0, input))), engine: _chunkHRUK5TFWcjs.normalizePaintBrush.call(void 0, input).engine }));
|
|
612
614
|
const files = {
|
|
613
|
-
"brush.schema.json": { $schema: "https://json-schema.org/draft/2020-12/schema", $id: "brush.schema.json", ...
|
|
615
|
+
"brush.schema.json": { $schema: "https://json-schema.org/draft/2020-12/schema", $id: "brush.schema.json", ..._chunkHRUK5TFWcjs.BRUSH_JSON_SCHEMA },
|
|
614
616
|
"profile.schema.json": { $schema: "https://json-schema.org/draft/2020-12/schema", $id: "profile.schema.json", ...BRUSH_PROFILE_JSON_SCHEMA },
|
|
615
617
|
"library-file.schema.json": { $schema: "https://json-schema.org/draft/2020-12/schema", $id: "library-file.schema.json", ...BRUSH_LIBRARY_FILE_JSON_SCHEMA },
|
|
616
618
|
"presets.json": presets,
|
|
@@ -624,7 +626,7 @@ function brushContracts() {
|
|
|
624
626
|
files["manifest.json"] = {
|
|
625
627
|
domain: "brushes",
|
|
626
628
|
formatVersion: BRUSH_CONTRACT_FORMAT_VERSION,
|
|
627
|
-
limits: { maxPalette:
|
|
629
|
+
limits: { maxPalette: _chunkHRUK5TFWcjs.MAX_BRUSH_PALETTE },
|
|
628
630
|
counts: { presets: presets.length, profiles: profiles.length, migrations: migrations.length, editorSections: files["editor-sections.json"].length },
|
|
629
631
|
files: Object.keys(files).sort()
|
|
630
632
|
};
|
|
@@ -725,4 +727,4 @@ function brushContracts() {
|
|
|
725
727
|
|
|
726
728
|
|
|
727
729
|
|
|
728
|
-
exports.AbrError =
|
|
730
|
+
exports.AbrError = _chunkJVFGK3DKcjs.AbrError; exports.BRUSH_CONTRACT_FORMAT_VERSION = BRUSH_CONTRACT_FORMAT_VERSION; exports.BRUSH_FACET_SCHEMAS = _chunkHRUK5TFWcjs.BRUSH_FACET_SCHEMAS; exports.BRUSH_FLIPS = _chunkHRUK5TFWcjs.BRUSH_FLIPS; exports.BRUSH_GRAIN_MODES = _chunkHRUK5TFWcjs.BRUSH_GRAIN_MODES; exports.BRUSH_GRAIN_SOURCE_PATTERN = _chunkHRUK5TFWcjs.BRUSH_GRAIN_SOURCE_PATTERN; exports.BRUSH_HOST_PROFILES = _chunkHRUK5TFWcjs.BRUSH_HOST_PROFILES; exports.BRUSH_JSON_SCHEMA = _chunkHRUK5TFWcjs.BRUSH_JSON_SCHEMA; exports.BRUSH_KINDS = _chunkHRUK5TFWcjs.BRUSH_KINDS; exports.BRUSH_LIBRARY_FILE_JSON_SCHEMA = BRUSH_LIBRARY_FILE_JSON_SCHEMA; exports.BRUSH_MARKS_KINDS = _chunkHRUK5TFWcjs.BRUSH_MARKS_KINDS; exports.BRUSH_MEDIA = _chunkHRUK5TFWcjs.BRUSH_MEDIA; exports.BRUSH_PACK_FORMATS = _chunkJVFGK3DKcjs.BRUSH_PACK_FORMATS; exports.BRUSH_PATCH_PROPERTIES = _chunkJVFGK3DKcjs.BRUSH_PATCH_PROPERTIES; exports.BRUSH_PRESETS = _chunkHRUK5TFWcjs.BRUSH_PRESETS; exports.BRUSH_PREVIEW_DARK_PAPER = _chunkH3EME3S5cjs.BRUSH_PREVIEW_DARK_PAPER; exports.BRUSH_PREVIEW_FALLBACKS = _chunkH3EME3S5cjs.BRUSH_PREVIEW_FALLBACKS; exports.BRUSH_PREVIEW_MIN_CONTRAST = _chunkH3EME3S5cjs.BRUSH_PREVIEW_MIN_CONTRAST; exports.BRUSH_PROFILE_JSON_SCHEMA = BRUSH_PROFILE_JSON_SCHEMA; exports.BRUSH_SOURCE_CHANNELS = _chunkHRUK5TFWcjs.BRUSH_SOURCE_CHANNELS; exports.BRUSH_SOURCE_PROVIDER = _chunkHRUK5TFWcjs.BRUSH_SOURCE_PROVIDER; exports.BRUSH_SURFACES = _chunkHRUK5TFWcjs.BRUSH_SURFACES; exports.BRUSH_TIP_SHAPES = _chunkHRUK5TFWcjs.BRUSH_TIP_SHAPES; exports.BRUSH_TOOLS = _chunkHRUK5TFWcjs.BRUSH_TOOLS; exports.BRUSH_UNSET_PROPERTY = _chunkJVFGK3DKcjs.BRUSH_UNSET_PROPERTY; exports.BRUSH_WORD = _chunkHRUK5TFWcjs.BRUSH_WORD; exports.BrushLibraryError = _chunkHRUK5TFWcjs.BrushLibraryError; exports.BrushPackError = _chunkJVFGK3DKcjs.BrushPackError; exports.BrushSourceError = _chunkHRUK5TFWcjs.BrushSourceError; exports.CANVAS_PROFILE = _chunkHRUK5TFWcjs.CANVAS_PROFILE; exports.GHOST_TRIGGERS = _chunkHRUK5TFWcjs.GHOST_TRIGGERS2; exports.IMAGE_PROFILE = _chunkHRUK5TFWcjs.IMAGE_PROFILE; exports.MAX_BRUSH_PACK_BYTES = _chunkJVFGK3DKcjs.MAX_BRUSH_PACK_BYTES; exports.MAX_BRUSH_PALETTE = _chunkHRUK5TFWcjs.MAX_BRUSH_PALETTE; exports.MAX_BRUSH_SOURCES = _chunkHRUK5TFWcjs.MAX_BRUSH_SOURCES; exports.MAX_BRUSH_SOURCE_INPUT_PIXELS = _chunkHRUK5TFWcjs.MAX_BRUSH_SOURCE_INPUT_PIXELS; exports.MAX_BRUSH_SOURCE_SIZE = _chunkHRUK5TFWcjs.MAX_BRUSH_SOURCE_SIZE; exports.MAX_PACK_BRUSHES = _chunkJVFGK3DKcjs.MAX_PACK_BRUSHES; exports.PAINT_PROFILE = _chunkHRUK5TFWcjs.PAINT_PROFILE; exports.TIP_GRAIN_PATTERNS = _chunkHRUK5TFWcjs.TIP_GRAIN_PATTERNS; exports.UNSETTABLE_BRUSH_FACETS = _chunkJVFGK3DKcjs.UNSETTABLE_BRUSH_FACETS; exports.VECTOR_PROFILE = _chunkHRUK5TFWcjs.VECTOR_PROFILE; exports.WET_BRUSH_TOOLS = _chunkHRUK5TFWcjs.WET_BRUSH_TOOLS; exports.addBrushSourceFromFile = addBrushSourceFromFile; exports.brushColourHex = _chunkJBZRVLXVcjs.brushColourHex; exports.brushColourKind = _chunkHRUK5TFWcjs.brushColourKind; exports.brushContracts = brushContracts; exports.brushEditorScope = brushEditorScope; exports.brushEditorSections = brushEditorSections; exports.brushIdFromName = brushIdFromName; exports.brushLibraryGroups = brushLibraryGroups; exports.brushPackFormat = _chunkJVFGK3DKcjs.brushPackFormat; exports.brushPreviewColours = _chunkH3EME3S5cjs.brushPreviewColours; exports.brushPreviewStrength = _chunkH3EME3S5cjs.brushPreviewStrength; exports.brushPreviewsOnDark = _chunkH3EME3S5cjs.brushPreviewsOnDark; exports.brushSourceFromMask = _chunkHRUK5TFWcjs.brushSourceFromMask; exports.brushSourceIdFromName = _chunkHRUK5TFWcjs.brushSourceIdFromName; exports.brushSourceIdOf = _chunkHRUK5TFWcjs.brushSourceIdOf; exports.brushSourceIds = _chunkHRUK5TFWcjs.brushSourceIds; exports.brushSourceRef = _chunkHRUK5TFWcjs.brushSourceRef; exports.changedBrushPaths = _chunkJVFGK3DKcjs.changedBrushPaths; exports.checkBrush = _chunkHRUK5TFWcjs.checkBrush; exports.checkBrushEdit = _chunkHRUK5TFWcjs.checkBrushEdit; exports.createBrushLibrary = _chunkHRUK5TFWcjs.createBrushLibrary; exports.createBrushLibraryToolProvider = _chunkJVFGK3DKcjs.createBrushLibraryToolProvider; exports.createBrushLibraryTools = _chunkJVFGK3DKcjs.createBrushLibraryTools; exports.decodeBrushSource = _chunkHRUK5TFWcjs.decodeBrushSource; exports.degrade = _chunkHRUK5TFWcjs.degrade; exports.imageFileToPngDataUrl = imageFileToPngDataUrl; exports.importBrushFile = _chunkJVFGK3DKcjs.importBrushFile; exports.importBrushPack = _chunkJVFGK3DKcjs.importBrushPack; exports.isBrushLibrary = _chunkHRUK5TFWcjs.isBrushLibrary; exports.isBrushSourceRef = _chunkHRUK5TFWcjs.isBrushSourceRef; exports.listPresets = _chunkHRUK5TFWcjs.listPresets; exports.makeBrushSource = _chunkHRUK5TFWcjs.makeBrushSource; exports.mergeBrushPatch = _chunkJVFGK3DKcjs.mergeBrushPatch; exports.migrateBrushV1 = _chunkHRUK5TFWcjs.migrateBrushV1; exports.newBrushFor = newBrushFor; exports.normalizeBrushSpec = _chunkHRUK5TFWcjs.normalizeBrushSpec; exports.parseBrushLibrary = _chunkHRUK5TFWcjs.parseBrushLibrary2; exports.parseBrushLibrarySources = _chunkHRUK5TFWcjs.parseBrushLibrarySources; exports.readAbr = _chunkJVFGK3DKcjs.readAbr; exports.readBrushPack = _chunkJVFGK3DKcjs.readBrushPack; exports.readBrushSource = _chunkHRUK5TFWcjs.readBrushSource; exports.resolveBrush = _chunkHRUK5TFWcjs.resolveBrush; exports.resolveCategory = _chunkHRUK5TFWcjs.resolveCategory; exports.resolveEngine = _chunkHRUK5TFWcjs.resolveEngine; exports.resolveWetMedium = _chunkHRUK5TFWcjs.resolveWetMedium; exports.saveBrushEdit = saveBrushEdit; exports.setBrushEditorValue = setBrushEditorValue; exports.snapshotBrushLibrary = _chunkHRUK5TFWcjs.snapshotBrushLibrary; exports.summarizeBrushSource = _chunkHRUK5TFWcjs.summarizeBrushSource; exports.withBrushSource = withBrushSource; exports.withKeptIssues = _chunkHRUK5TFWcjs.withKeptIssues;
|
package/dist/brushes/index.js
CHANGED
|
@@ -18,7 +18,7 @@ import {
|
|
|
18
18
|
mergeBrushPatch,
|
|
19
19
|
readAbr,
|
|
20
20
|
readBrushPack
|
|
21
|
-
} from "../chunk-
|
|
21
|
+
} from "../chunk-NJLPW4MM.js";
|
|
22
22
|
import "../chunk-VE6UKYQ2.js";
|
|
23
23
|
import {
|
|
24
24
|
BRUSH_PREVIEW_DARK_PAPER,
|
|
@@ -27,7 +27,7 @@ import {
|
|
|
27
27
|
brushPreviewColours,
|
|
28
28
|
brushPreviewStrength,
|
|
29
29
|
brushPreviewsOnDark
|
|
30
|
-
} from "../chunk-
|
|
30
|
+
} from "../chunk-ROURHJYT.js";
|
|
31
31
|
import {
|
|
32
32
|
BRUSH_FACET_SCHEMAS,
|
|
33
33
|
BRUSH_FIELDS,
|
|
@@ -102,7 +102,7 @@ import {
|
|
|
102
102
|
snapshotBrushLibrary,
|
|
103
103
|
summarizeBrushSource,
|
|
104
104
|
withKeptIssues
|
|
105
|
-
} from "../chunk-
|
|
105
|
+
} from "../chunk-PPDUCZZV.js";
|
|
106
106
|
import {
|
|
107
107
|
STAMP_KINDS
|
|
108
108
|
} from "../chunk-JL6YH5WD.js";
|
|
@@ -421,6 +421,7 @@ function setBrushEditorValue(brush, path, value) {
|
|
|
421
421
|
delete next.iridescence;
|
|
422
422
|
delete next.ghost;
|
|
423
423
|
delete next.mutation;
|
|
424
|
+
delete next.ferro;
|
|
424
425
|
delete next.colour;
|
|
425
426
|
next.tool = next.tool ?? "eraser";
|
|
426
427
|
if (next.tip.shape === "stamp") next.tip = { shape: "round", ...next.tip.size !== void 0 ? { size: next.tip.size } : {} };
|
|
@@ -524,7 +525,8 @@ var BRUSH_PROFILE_JSON_SCHEMA = {
|
|
|
524
525
|
tipGrain: { ...SUPPORT, description: "Texture inside the tip (tip.grain); missing: none." },
|
|
525
526
|
dabCount: { ...SUPPORT, description: "Several dabs per spacing step (dynamics.count); missing: none." },
|
|
526
527
|
livePatterns: { ...SUPPORT, description: "Gray-Scott reaction-diffusion patterns in wet paint (livePatterns); missing: none." },
|
|
527
|
-
iridescence: { ...SUPPORT, description: "Thin-film iridescence (iridescence); missing: none." }
|
|
528
|
+
iridescence: { ...SUPPORT, description: "Thin-film iridescence (iridescence); missing: none." },
|
|
529
|
+
ferro: { ...SUPPORT, description: "Liquid ferrofluid (ferro); missing: none." }
|
|
528
530
|
},
|
|
529
531
|
required: ["id", "name", "kinds", "tools", "tipShapes", "marks", "surfaces", "exchange", "reservoir", "grain", "light", "motion", "colours", "velocity", "tilt"],
|
|
530
532
|
additionalProperties: false
|
package/dist/brushes/patch.d.cts
CHANGED
|
@@ -5,15 +5,15 @@
|
|
|
5
5
|
* means the same everywhere.
|
|
6
6
|
*/
|
|
7
7
|
import type { JsonSchema } from '../tools/schema.cjs';
|
|
8
|
-
import type { Brush } from './types.cjs';
|
|
9
|
-
/** A brush's facets, any of them, as a patch takes them (the tip's `shape` may be left out). */
|
|
8
|
+
import type { Brush, BrushFerro } from './types.cjs';
|
|
9
|
+
/** A brush's facets, any of them, as a patch takes them (the tip's `shape` may be left out, and `ferro` accepts a `0..1` amount shorthand). */
|
|
10
10
|
export type BrushPatch = {
|
|
11
|
-
[K in Exclude<keyof Brush, 'id'>]?: K extends 'tip' ? Partial<Brush['tip']> : Brush[K];
|
|
11
|
+
[K in Exclude<keyof Brush, 'id'>]?: K extends 'tip' ? Partial<Brush['tip']> : K extends 'ferro' ? number | BrushFerro : Brush[K];
|
|
12
12
|
};
|
|
13
13
|
/** The schema of every facet except `id` and `name`, as tool arguments (a patch may leave out `tip.shape`). */
|
|
14
14
|
export declare const BRUSH_PATCH_PROPERTIES: Readonly<Record<string, JsonSchema>>;
|
|
15
15
|
/** The facets a patch can remove (`unset`), back to the engine's defaults. */
|
|
16
|
-
export declare const UNSETTABLE_BRUSH_FACETS: readonly ["description", "tags", "medium", "variety", "marks", "dynamics", "behaviour", "light", "fluorescence", "thermochromic", "iridescence", "ghost", "mutation", "motion", "livePatterns", "colour"];
|
|
16
|
+
export declare const UNSETTABLE_BRUSH_FACETS: readonly ["description", "tags", "medium", "variety", "marks", "dynamics", "behaviour", "light", "fluorescence", "thermochromic", "iridescence", "ghost", "mutation", "ferro", "motion", "livePatterns", "colour"];
|
|
17
17
|
export type UnsettableBrushFacet = (typeof UNSETTABLE_BRUSH_FACETS)[number];
|
|
18
18
|
/** The `unset` argument of tools that take a patch. */
|
|
19
19
|
export declare const BRUSH_UNSET_PROPERTY: JsonSchema;
|
package/dist/brushes/patch.d.ts
CHANGED
|
@@ -5,15 +5,15 @@
|
|
|
5
5
|
* means the same everywhere.
|
|
6
6
|
*/
|
|
7
7
|
import type { JsonSchema } from '../tools/schema.js';
|
|
8
|
-
import type { Brush } from './types.js';
|
|
9
|
-
/** A brush's facets, any of them, as a patch takes them (the tip's `shape` may be left out). */
|
|
8
|
+
import type { Brush, BrushFerro } from './types.js';
|
|
9
|
+
/** A brush's facets, any of them, as a patch takes them (the tip's `shape` may be left out, and `ferro` accepts a `0..1` amount shorthand). */
|
|
10
10
|
export type BrushPatch = {
|
|
11
|
-
[K in Exclude<keyof Brush, 'id'>]?: K extends 'tip' ? Partial<Brush['tip']> : Brush[K];
|
|
11
|
+
[K in Exclude<keyof Brush, 'id'>]?: K extends 'tip' ? Partial<Brush['tip']> : K extends 'ferro' ? number | BrushFerro : Brush[K];
|
|
12
12
|
};
|
|
13
13
|
/** The schema of every facet except `id` and `name`, as tool arguments (a patch may leave out `tip.shape`). */
|
|
14
14
|
export declare const BRUSH_PATCH_PROPERTIES: Readonly<Record<string, JsonSchema>>;
|
|
15
15
|
/** The facets a patch can remove (`unset`), back to the engine's defaults. */
|
|
16
|
-
export declare const UNSETTABLE_BRUSH_FACETS: readonly ["description", "tags", "medium", "variety", "marks", "dynamics", "behaviour", "light", "fluorescence", "thermochromic", "iridescence", "ghost", "mutation", "motion", "livePatterns", "colour"];
|
|
16
|
+
export declare const UNSETTABLE_BRUSH_FACETS: readonly ["description", "tags", "medium", "variety", "marks", "dynamics", "behaviour", "light", "fluorescence", "thermochromic", "iridescence", "ghost", "mutation", "ferro", "motion", "livePatterns", "colour"];
|
|
17
17
|
export type UnsettableBrushFacet = (typeof UNSETTABLE_BRUSH_FACETS)[number];
|
|
18
18
|
/** The `unset` argument of tools that take a patch. */
|
|
19
19
|
export declare const BRUSH_UNSET_PROPERTY: JsonSchema;
|
|
@@ -43,6 +43,8 @@ export interface BrushHostProfile {
|
|
|
43
43
|
livePatterns?: BrushSupport;
|
|
44
44
|
/** Structural colour (`iridescence`); missing: `none`. */
|
|
45
45
|
iridescence?: BrushSupport;
|
|
46
|
+
/** Liquid ferrofluid (`ferro`); missing: `none`. */
|
|
47
|
+
ferro?: BrushSupport;
|
|
46
48
|
}
|
|
47
49
|
export interface BrushIssue {
|
|
48
50
|
/** The facet path the issue is about, e.g. `tip.shape`, `light`, `behaviour.exchange.reservoir`. */
|
|
@@ -43,6 +43,8 @@ export interface BrushHostProfile {
|
|
|
43
43
|
livePatterns?: BrushSupport;
|
|
44
44
|
/** Structural colour (`iridescence`); missing: `none`. */
|
|
45
45
|
iridescence?: BrushSupport;
|
|
46
|
+
/** Liquid ferrofluid (`ferro`); missing: `none`. */
|
|
47
|
+
ferro?: BrushSupport;
|
|
46
48
|
}
|
|
47
49
|
export interface BrushIssue {
|
|
48
50
|
/** The facet path the issue is about, e.g. `tip.shape`, `light`, `behaviour.exchange.reservoir`. */
|
|
@@ -33,6 +33,7 @@ export declare const BRUSH_FACET_SCHEMAS: {
|
|
|
33
33
|
readonly iridescence: JsonSchema;
|
|
34
34
|
readonly ghost: JsonSchema;
|
|
35
35
|
readonly mutation: JsonSchema;
|
|
36
|
+
readonly ferro: JsonSchema;
|
|
36
37
|
readonly motion: JsonSchema;
|
|
37
38
|
readonly livePatterns: JsonSchema;
|
|
38
39
|
readonly colour: JsonSchema;
|
package/dist/brushes/schema.d.ts
CHANGED
|
@@ -33,6 +33,7 @@ export declare const BRUSH_FACET_SCHEMAS: {
|
|
|
33
33
|
readonly iridescence: JsonSchema;
|
|
34
34
|
readonly ghost: JsonSchema;
|
|
35
35
|
readonly mutation: JsonSchema;
|
|
36
|
+
readonly ferro: JsonSchema;
|
|
36
37
|
readonly motion: JsonSchema;
|
|
37
38
|
readonly livePatterns: JsonSchema;
|
|
38
39
|
readonly colour: JsonSchema;
|
package/dist/brushes/types.d.cts
CHANGED
|
@@ -360,6 +360,15 @@ export interface BrushMutation {
|
|
|
360
360
|
/** Seconds the paint takes to sink away once claimed, 0.5..10 (default 2). */
|
|
361
361
|
fade?: number;
|
|
362
362
|
}
|
|
363
|
+
/** Liquid ferrofluid paint that rises into glossy Rosensweig spikes near magnets until cured. */
|
|
364
|
+
export interface BrushFerro {
|
|
365
|
+
/** Ferrofluid per dab, 0..1 (default 0: none). */
|
|
366
|
+
amount?: number;
|
|
367
|
+
/** Capillary wavelength (spike-to-spike spacing) in pixels, 4..64 (default 16). */
|
|
368
|
+
wavelength?: number;
|
|
369
|
+
/** Critical magnetic field |B| threshold where spikes begin to rise, 0.01..0.95 (default 0.12). */
|
|
370
|
+
threshold?: number;
|
|
371
|
+
}
|
|
363
372
|
/** Animation after painting. */
|
|
364
373
|
export interface BrushMotion {
|
|
365
374
|
/** Effect paint keeps playing on stroke layers. */
|
|
@@ -431,6 +440,7 @@ export interface Brush {
|
|
|
431
440
|
iridescence?: BrushIridescence;
|
|
432
441
|
ghost?: BrushGhost;
|
|
433
442
|
mutation?: BrushMutation;
|
|
443
|
+
ferro?: BrushFerro;
|
|
434
444
|
motion?: BrushMotion;
|
|
435
445
|
livePatterns?: BrushLivePatterns;
|
|
436
446
|
colour?: BrushColour;
|
package/dist/brushes/types.d.ts
CHANGED
|
@@ -360,6 +360,15 @@ export interface BrushMutation {
|
|
|
360
360
|
/** Seconds the paint takes to sink away once claimed, 0.5..10 (default 2). */
|
|
361
361
|
fade?: number;
|
|
362
362
|
}
|
|
363
|
+
/** Liquid ferrofluid paint that rises into glossy Rosensweig spikes near magnets until cured. */
|
|
364
|
+
export interface BrushFerro {
|
|
365
|
+
/** Ferrofluid per dab, 0..1 (default 0: none). */
|
|
366
|
+
amount?: number;
|
|
367
|
+
/** Capillary wavelength (spike-to-spike spacing) in pixels, 4..64 (default 16). */
|
|
368
|
+
wavelength?: number;
|
|
369
|
+
/** Critical magnetic field |B| threshold where spikes begin to rise, 0.01..0.95 (default 0.12). */
|
|
370
|
+
threshold?: number;
|
|
371
|
+
}
|
|
363
372
|
/** Animation after painting. */
|
|
364
373
|
export interface BrushMotion {
|
|
365
374
|
/** Effect paint keeps playing on stroke layers. */
|
|
@@ -431,6 +440,7 @@ export interface Brush {
|
|
|
431
440
|
iridescence?: BrushIridescence;
|
|
432
441
|
ghost?: BrushGhost;
|
|
433
442
|
mutation?: BrushMutation;
|
|
443
|
+
ferro?: BrushFerro;
|
|
434
444
|
motion?: BrushMotion;
|
|
435
445
|
livePatterns?: BrushLivePatterns;
|
|
436
446
|
colour?: BrushColour;
|