@pixerate/editor 0.258.0 → 0.260.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/agent/index.cjs +2 -2
- package/dist/agent/index.js +1 -1
- package/dist/animation-editor/index.cjs +61 -59
- package/dist/animation-editor/index.js +5 -3
- package/dist/brushes/contract.d.cts +24 -0
- package/dist/brushes/contract.d.ts +24 -0
- package/dist/brushes/index.cjs +146 -31
- package/dist/brushes/index.d.cts +1 -0
- package/dist/brushes/index.d.ts +1 -0
- package/dist/brushes/index.js +121 -6
- package/dist/{brushstrokeRender-JI4W6F2G.js → brushstrokeRender-25Q5BEY6.js} +17 -7
- package/dist/{brushstrokeRender-MQ6PSDM5.cjs → brushstrokeRender-N6UPZSQS.cjs} +31 -21
- package/dist/canvas/brushTypes.d.cts +5 -0
- package/dist/canvas/brushTypes.d.ts +5 -0
- package/dist/canvas/drawController.d.cts +15 -1
- package/dist/canvas/drawController.d.ts +15 -1
- package/dist/canvas/index.cjs +136 -102
- package/dist/canvas/index.js +35 -1
- package/dist/{chunk-3PPJRMIG.js → chunk-3O47TPGX.js} +197 -18
- package/dist/{chunk-5Q5MLXAD.cjs → chunk-3TQW5MPW.cjs} +23 -23
- package/dist/{chunk-JBBJE76O.cjs → chunk-3ZRNK3RO.cjs} +1138 -85
- package/dist/{chunk-YSGW7VV4.cjs → chunk-43NT242D.cjs} +1401 -228
- package/dist/{chunk-SMTUQWGY.js → chunk-5IW65VQ6.js} +1 -1
- package/dist/{chunk-YQ4PQTBB.js → chunk-6NZL24W4.js} +9 -1
- package/dist/{chunk-O3ZVZSNJ.cjs → chunk-7AUQ2UJ3.cjs} +137 -129
- package/dist/{chunk-4M4E3N6X.js → chunk-CQVTGBQI.js} +1 -1
- package/dist/{chunk-SSFMWJDK.js → chunk-D4TE5JNW.js} +1192 -19
- package/dist/{chunk-AORZ5M5C.js → chunk-EHALWBBD.js} +1 -1
- package/dist/{chunk-6WCQ35GI.cjs → chunk-NHA26O5X.cjs} +2 -2
- package/dist/{chunk-DPYAO5U6.cjs → chunk-PVJMTLPJ.cjs} +197 -18
- package/dist/{chunk-MQGQTKVW.cjs → chunk-PYTJBVW5.cjs} +29 -29
- package/dist/{chunk-IXQZHCOF.js → chunk-QAR2N7HZ.js} +1 -1
- package/dist/{chunk-5P4JEOIV.js → chunk-TMDDMJCR.js} +2 -2
- package/dist/{chunk-RSIKDWOP.cjs → chunk-TZOX7KWV.cjs} +15 -15
- package/dist/{chunk-IPUTIUGQ.cjs → chunk-UVZ7RQOE.cjs} +1 -1
- package/dist/{chunk-A7GJ6BXI.js → chunk-WJ4WQJCC.js} +1062 -9
- package/dist/{chunk-ICTPLVSR.js → chunk-X2EXYY4J.js} +1 -1
- package/dist/{chunk-WQCNC4DK.js → chunk-XC6DPRYI.js} +695 -4
- package/dist/{chunk-KBYB7OWB.cjs → chunk-YHDHFJUC.cjs} +776 -85
- package/dist/{chunk-P3PZ63M3.cjs → chunk-YLUIFXSL.cjs} +35 -35
- package/dist/commands/index.cjs +2 -2
- package/dist/commands/index.js +1 -1
- package/dist/image-editor/index.cjs +1385 -2484
- package/dist/image-editor/index.js +139 -1238
- package/dist/image-editor/selection-worker.cjs +3 -4
- package/dist/image-editor/selection-worker.js +1 -2
- package/dist/paint/index.cjs +3 -5
- package/dist/paint/index.js +40 -42
- package/dist/paint-editor/contract.d.cts +29 -0
- package/dist/paint-editor/contract.d.ts +29 -0
- package/dist/paint-editor/dab-stroke.d.cts +5 -0
- package/dist/paint-editor/dab-stroke.d.ts +5 -0
- package/dist/paint-editor/index.cjs +402 -258
- package/dist/paint-editor/index.d.cts +1 -0
- package/dist/paint-editor/index.d.ts +1 -0
- package/dist/paint-editor/index.js +197 -53
- package/dist/paint-editor/stamp-tip.d.cts +17 -0
- package/dist/paint-editor/stamp-tip.d.ts +17 -0
- package/dist/paint-editor/ui.d.cts +21 -1
- package/dist/paint-editor/ui.d.ts +21 -1
- package/dist/raster/index.cjs +2 -4
- package/dist/raster/index.js +6 -8
- package/dist/vector/brushstroke.d.cts +6 -0
- package/dist/vector/brushstroke.d.ts +6 -0
- package/dist/vector/controller.d.cts +11 -2
- package/dist/vector/controller.d.ts +11 -2
- package/dist/vector/index.cjs +990 -973
- package/dist/vector/index.js +28 -11
- package/package.json +1 -1
- package/skills/pixerate-brushes/SKILL.md +1 -1
- package/skills/pixerate-canvas/SKILL.md +3 -1
- package/skills/pixerate-vector/SKILL.md +2 -2
- package/dist/chunk-2VJAVXLI.js +0 -192
- package/dist/chunk-62Z5WLRA.js +0 -700
- package/dist/chunk-BOHDJJ2O.cjs +0 -192
- package/dist/chunk-NKGB64CW.cjs +0 -700
- package/dist/chunk-SS53NNZO.cjs +0 -1066
- package/dist/chunk-ZNA3IQZF.js +0 -1066
package/dist/brushes/index.cjs
CHANGED
|
@@ -8,12 +8,10 @@
|
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
|
|
11
|
-
var
|
|
11
|
+
var _chunkPYTJBVW5cjs = require('../chunk-PYTJBVW5.cjs');
|
|
12
12
|
require('../chunk-AVTPZO4Z.cjs');
|
|
13
13
|
|
|
14
14
|
|
|
15
|
-
var _chunkLRTR4ASZcjs = require('../chunk-LRTR4ASZ.cjs');
|
|
16
|
-
require('../chunk-A2IS7EHE.cjs');
|
|
17
15
|
|
|
18
16
|
|
|
19
17
|
|
|
@@ -59,10 +57,15 @@ require('../chunk-A2IS7EHE.cjs');
|
|
|
59
57
|
|
|
60
58
|
|
|
61
59
|
|
|
62
|
-
|
|
60
|
+
|
|
61
|
+
var _chunkTZOX7KWVcjs = require('../chunk-TZOX7KWV.cjs');
|
|
63
62
|
|
|
64
63
|
|
|
65
64
|
var _chunkJSDND7DFcjs = require('../chunk-JSDND7DF.cjs');
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
var _chunkLRTR4ASZcjs = require('../chunk-LRTR4ASZ.cjs');
|
|
68
|
+
require('../chunk-A2IS7EHE.cjs');
|
|
66
69
|
require('../chunk-U67EN7GG.cjs');
|
|
67
70
|
require('../chunk-WOFXZ3XU.cjs');
|
|
68
71
|
|
|
@@ -109,20 +112,20 @@ var ARIA = {
|
|
|
109
112
|
"light.pressure": "Light follows pressure"
|
|
110
113
|
};
|
|
111
114
|
var aria = (path, label) => _nullishCoalesce(ARIA[path], () => ( `Brush ${label.toLowerCase()}`));
|
|
112
|
-
function brushEditorSections(brush, profile =
|
|
113
|
-
const resolved =
|
|
114
|
-
const engine =
|
|
115
|
-
const fieldOf = (facet) =>
|
|
116
|
-
const facetOf = (enginePath) => _optionalChain([(_nullishCoalesce(
|
|
115
|
+
function brushEditorSections(brush, profile = _chunkTZOX7KWVcjs.PAINT_PROFILE) {
|
|
116
|
+
const resolved = _chunkTZOX7KWVcjs.resolveBrush.call(void 0, brush);
|
|
117
|
+
const engine = _chunkTZOX7KWVcjs.resolveEngine.call(void 0, brush);
|
|
118
|
+
const fieldOf = (facet) => _chunkTZOX7KWVcjs.BRUSH_FIELDS.find((f) => f.facet === facet && f.engines.includes(engine));
|
|
119
|
+
const facetOf = (enginePath) => _optionalChain([(_nullishCoalesce(_chunkTZOX7KWVcjs.BRUSH_FIELDS.find((f) => f.engine === enginePath && f.engines.includes(engine)), () => ( _chunkTZOX7KWVcjs.BRUSH_FIELDS.find((f) => f.engine === enginePath)))), 'optionalAccess', _ => _.facet]);
|
|
117
120
|
const value = (path) => {
|
|
118
|
-
const own =
|
|
121
|
+
const own = _chunkTZOX7KWVcjs.getPath.call(void 0, brush, path);
|
|
119
122
|
if (own !== void 0) return own;
|
|
120
123
|
const field = fieldOf(path);
|
|
121
124
|
if (!field) return void 0;
|
|
122
|
-
const v =
|
|
125
|
+
const v = _chunkTZOX7KWVcjs.getPath.call(void 0, resolved, field.engine);
|
|
123
126
|
return field.map ? field.map.toFacet(v) : v;
|
|
124
127
|
};
|
|
125
|
-
const warned = new Map(
|
|
128
|
+
const warned = new Map(_chunkTZOX7KWVcjs.checkBrush.call(void 0, brush, profile).issues.filter((i) => i.severity === "warning").map((i) => [i.facet, i.reason]));
|
|
126
129
|
const noteFor = (path) => _optionalChain([[...warned], 'access', _2 => _2.find, 'call', _3 => _3(([facet]) => path === facet || path.startsWith(`${facet}.`)), 'optionalAccess', _4 => _4[1]]);
|
|
127
130
|
const withNote = (c) => {
|
|
128
131
|
const note = noteFor(c.path);
|
|
@@ -146,18 +149,18 @@ function brushEditorSections(brush, profile = _chunkRSIKDWOPcjs.PAINT_PROFILE) {
|
|
|
146
149
|
const marks = _nullishCoalesce(_optionalChain([brush, 'access', _7 => _7.marks, 'optionalAccess', _8 => _8.kind]), () => ( "continuous"));
|
|
147
150
|
add("medium", "Medium", [
|
|
148
151
|
profile.kinds.length > 1 && choice("kind", "Kind", options(profile.kinds, { mark: "Lays a material", tool: "Works on paint" })),
|
|
149
|
-
!isTool && choice("medium", "Medium", [{ value: "", label: "Any" }, ...options(
|
|
152
|
+
!isTool && choice("medium", "Medium", [{ value: "", label: "Any" }, ...options(_chunkTZOX7KWVcjs.BRUSH_MEDIA, MEDIUM_LABELS)], ""),
|
|
150
153
|
!isTool && withNote({ kind: "text", path: "variety", label: "Variety", ariaLabel: "Brush variety", value: _nullishCoalesce(brush.variety, () => ( "")), placeholder: "pencil, oil, highlighter\u2026" }),
|
|
151
154
|
isTool && profile.tools.length > 0 && choice("tool", "Tool", options(profile.tools, TOOL_LABELS))
|
|
152
155
|
]);
|
|
153
|
-
const engineControls =
|
|
154
|
-
const tipSliders =
|
|
156
|
+
const engineControls = _chunkPYTJBVW5cjs.brushEngineControls.call(void 0, resolved);
|
|
157
|
+
const tipSliders = _chunkPYTJBVW5cjs.BRUSH_SLIDERS.filter((c) => c.path.startsWith("tip.") && c.path !== "tip.smoothing");
|
|
155
158
|
add("shape", "Shape", [
|
|
156
159
|
choice("tip.shape", "Tip", options(profile.tipShapes.filter((s) => !isTool || s !== "stamp"), SHAPE_LABELS)),
|
|
157
160
|
...tipSliders.map((c) => slider(c)),
|
|
158
161
|
engine === "dab" && choice("tip.blend", "Blend", _chunk2VX55NFMcjs.BLEND_MODES.map((m) => ({ value: m.id, label: m.label })), "normal"),
|
|
159
162
|
...shape === "bristle" && engineControls ? engineControls.sliders.filter((c) => c.path.startsWith("bristle.")).map((c) => slider(c)) : [],
|
|
160
|
-
shape === "stamp" && withNote({ kind: "stamps", path: "tip.stamps", label: "Stamps", ariaLabel: "Brush stamps", value: [..._nullishCoalesce(value("tip.stamps"), () => ( []))], max: marks === "particles" ?
|
|
163
|
+
shape === "stamp" && withNote({ kind: "stamps", path: "tip.stamps", label: "Stamps", ariaLabel: "Brush stamps", value: [..._nullishCoalesce(value("tip.stamps"), () => ( []))], max: marks === "particles" ? _chunkTZOX7KWVcjs.MAX_DOT_TEXTURES : _chunkTZOX7KWVcjs.MAX_STICKER_STAMPS, options: STAMP_OPTIONS })
|
|
161
164
|
]);
|
|
162
165
|
if (!isTool && profile.marks.length > 1) {
|
|
163
166
|
const particles = marks === "particles" && engineControls ? engineControls.sliders.filter((c) => c.path.startsWith("particle.") && c.path !== "particle.waveSpeed") : [];
|
|
@@ -165,21 +168,21 @@ function brushEditorSections(brush, profile = _chunkRSIKDWOPcjs.PAINT_PROFILE) {
|
|
|
165
168
|
const render = value("marks.render");
|
|
166
169
|
add("marks", "Marks", [
|
|
167
170
|
choice("marks.kind", "Laid as", options(profile.marks, MARKS_LABELS), "continuous"),
|
|
168
|
-
marks === "particles" && choice("marks.physics", "Particles", options(
|
|
169
|
-
marks === "particles" && choice("marks.render", "Drawn as", options(
|
|
170
|
-
marks === "particles" && render === "ribbon" && choice("marks.ribbonPairs", "Ribbon joins", options(
|
|
171
|
-
marks === "particles" && shape === "stamp" && choice("marks.stampOrder", "Texture order", options(
|
|
172
|
-
marks === "particles" && shape === "stamp" && choice("marks.stampRotation", "Texture turn", options(
|
|
171
|
+
marks === "particles" && choice("marks.physics", "Particles", options(_chunkTZOX7KWVcjs.PARTICLE_KINDS, PHYSICS_LABELS)),
|
|
172
|
+
marks === "particles" && choice("marks.render", "Drawn as", options(_chunkTZOX7KWVcjs.PARTICLE_RENDERS, RENDER_LABELS)),
|
|
173
|
+
marks === "particles" && render === "ribbon" && choice("marks.ribbonPairs", "Ribbon joins", options(_chunkTZOX7KWVcjs.RIBBON_PAIRS, { adjacent: "Neighbours", "first-last": "Outermost" })),
|
|
174
|
+
marks === "particles" && shape === "stamp" && choice("marks.stampOrder", "Texture order", options(_chunkTZOX7KWVcjs.DOT_TEXTURE_ORDERS, { sequence: "In turn", random: "Random" })),
|
|
175
|
+
marks === "particles" && shape === "stamp" && choice("marks.stampRotation", "Texture turn", options(_chunkTZOX7KWVcjs.DOT_ROTATIONS, { follow: "Follow motion", random: "Random", fixed: "Tip angle" })),
|
|
173
176
|
...particles.map((c) => slider(c)),
|
|
174
177
|
...objects.map((c) => slider(c))
|
|
175
178
|
]);
|
|
176
179
|
}
|
|
177
|
-
const feel =
|
|
180
|
+
const feel = _chunkPYTJBVW5cjs.BRUSH_SLIDERS.filter((c) => ["tip.smoothing", "pressureSmoothing", "dynamics.minSize", "dynamics.tiltSize", "dynamics.velocitySize"].includes(c.path)).filter((c) => !(c.path === "dynamics.tiltSize" && profile.tilt === "none") && !(c.path === "dynamics.velocitySize" && profile.velocity === "none"));
|
|
178
181
|
add("feel", "Feel", [
|
|
179
182
|
...feel.map((c) => slider(c)),
|
|
180
183
|
toggle("dynamics.pressureSize", "Pressure \u2192 size"),
|
|
181
184
|
toggle("dynamics.pressureOpacity", "Pressure \u2192 opacity"),
|
|
182
|
-
choice("dynamics.rotation", "Rotation", options(
|
|
185
|
+
choice("dynamics.rotation", "Rotation", options(_chunkTZOX7KWVcjs.BRUSH_ROTATIONS, ROTATION_LABELS))
|
|
183
186
|
]);
|
|
184
187
|
const surfaces = profile.surfaces;
|
|
185
188
|
const engineSliders = (_nullishCoalesce(_optionalChain([engineControls, 'optionalAccess', _9 => _9.sliders]), () => ( []))).filter((c) => !/^(bristle|particle|sticker)\./.test(c.path) && c.path !== "light.amount" && c.path !== "impasto.rim" && c.path !== "impasto.clarity");
|
|
@@ -187,8 +190,8 @@ function brushEditorSections(brush, profile = _chunkRSIKDWOPcjs.PAINT_PROFILE) {
|
|
|
187
190
|
add("behaviour", _nullishCoalesce(_optionalChain([engineControls, 'optionalAccess', _12 => _12.title]), () => ( "Behaviour")), [
|
|
188
191
|
!isTool && surfaces.length > 1 && choice("behaviour.surface", "Surface", options(surfaces, SURFACE_LABELS), "dry"),
|
|
189
192
|
profile.grain !== "none" && slider({ path: "grain", label: "Grain", min: 0, max: 1, step: 0.01 }, "behaviour.grain"),
|
|
190
|
-
engine === "wet" && !isTool && choice("behaviour.wet.medium", "Medium", options(
|
|
191
|
-
engine === "impasto" && choice("behaviour.thick.applicator", "Tool", options(
|
|
193
|
+
engine === "wet" && !isTool && choice("behaviour.wet.medium", "Medium", options(_chunkTZOX7KWVcjs.WET_MEDIA, WET_MEDIUM_LABELS), "watercolor"),
|
|
194
|
+
engine === "impasto" && choice("behaviour.thick.applicator", "Tool", options(_chunkTZOX7KWVcjs.IMPASTO_TOOLS, APPLICATOR_LABELS), "brush"),
|
|
192
195
|
...engineSliders.map((c) => exchangeOk(facetOf(c.path)) ? slider(c) : null),
|
|
193
196
|
_optionalChain([engineControls, 'optionalAccess', _13 => _13.mixingPath]) && fieldOf("behaviour.mixing") && choice("behaviour.mixing", "Mixing", options(["pigment", "rgb"], { pigment: "Pigment", rgb: "RGB" })),
|
|
194
197
|
_optionalChain([engineControls, 'optionalAccess', _14 => _14.dirty]) && profile.exchange !== "none" && fieldOf("behaviour.exchange.dirty") && toggle("behaviour.exchange.dirty", "Dirty brush"),
|
|
@@ -216,7 +219,7 @@ function brushEditorSections(brush, profile = _chunkRSIKDWOPcjs.PAINT_PROFILE) {
|
|
|
216
219
|
label: "Palette",
|
|
217
220
|
ariaLabel: "Brush palette",
|
|
218
221
|
value: (_nullishCoalesce(_optionalChain([brush, 'access', _21 => _21.colour, 'optionalAccess', _22 => _22.palette]), () => ( []))).flatMap((c) => _chunkMLLTWAXHcjs.isDualColor.call(void 0, c) ? [{ light: _chunkLRTR4ASZcjs.brushColourHex.call(void 0, c, "light"), dark: _chunkLRTR4ASZcjs.brushColourHex.call(void 0, c, "dark") }] : hex(c) ? [hex(c)] : []),
|
|
219
|
-
max:
|
|
222
|
+
max: _chunkTZOX7KWVcjs.MAX_BRUSH_PALETTE
|
|
220
223
|
}),
|
|
221
224
|
toggle("colour.own", "Always its own colour")
|
|
222
225
|
]);
|
|
@@ -245,13 +248,13 @@ function setBrushEditorValue(brush, path, value) {
|
|
|
245
248
|
if (value !== "bristle") delete next.tip.bristle;
|
|
246
249
|
} else if (value === void 0 || value === "") {
|
|
247
250
|
const keys = path.split(".");
|
|
248
|
-
const parent =
|
|
251
|
+
const parent = _chunkTZOX7KWVcjs.getPath.call(void 0, next, keys.slice(0, -1).join("."));
|
|
249
252
|
if (keys.length === 1) delete next[keys[0]];
|
|
250
253
|
else if (parent) delete parent[keys[keys.length - 1]];
|
|
251
|
-
} else
|
|
254
|
+
} else _chunkTZOX7KWVcjs.setPath.call(void 0, next, path, value);
|
|
252
255
|
const problems = [];
|
|
253
256
|
try {
|
|
254
|
-
return { brush:
|
|
257
|
+
return { brush: _chunkTZOX7KWVcjs.normalizeBrushSpec.call(void 0, JSON.parse(JSON.stringify(next)), problems), problems };
|
|
255
258
|
} catch (e) {
|
|
256
259
|
return { brush, problems: [e.message] };
|
|
257
260
|
}
|
|
@@ -267,7 +270,7 @@ function brushLibraryGroups(entries, filter = {}) {
|
|
|
267
270
|
const text = words([b.id, b.name, _nullishCoalesce(b.variety, () => ( "")), _nullishCoalesce(b.medium, () => ( "")), _nullishCoalesce(b.tool, () => ( "")), ..._nullishCoalesce(b.tags, () => ( []))].join(" "));
|
|
268
271
|
if (!wanted.every((w) => text.some((t) => t.startsWith(w)))) continue;
|
|
269
272
|
}
|
|
270
|
-
if (filter.profile && !
|
|
273
|
+
if (filter.profile && !_chunkTZOX7KWVcjs.checkBrush.call(void 0, b, filter.profile).ok) continue;
|
|
271
274
|
const id = b.kind === "tool" ? "tools" : _nullishCoalesce(b.medium, () => ( "other"));
|
|
272
275
|
let g = groups.get(id);
|
|
273
276
|
if (!g) groups.set(id, g = { id, title: id === "tools" ? "Tools" : id === "other" ? "Other" : MEDIUM_LABELS[id], varieties: [] });
|
|
@@ -280,6 +283,118 @@ function brushLibraryGroups(entries, filter = {}) {
|
|
|
280
283
|
return [...groups.values()].sort((a, b) => order.indexOf(a.id) - order.indexOf(b.id));
|
|
281
284
|
}
|
|
282
285
|
|
|
286
|
+
// src/brushes/contract.ts
|
|
287
|
+
var BRUSH_CONTRACT_FORMAT_VERSION = 1;
|
|
288
|
+
var SUPPORT = { type: "string", enum: ["full", "ignored", "none"], description: "full: rendered; ignored: accepted, painted without it (a warning); none: refused (an error)." };
|
|
289
|
+
var BRUSH_PROFILE_JSON_SCHEMA = {
|
|
290
|
+
type: "object",
|
|
291
|
+
description: "What a host can render (`BrushHostProfile`).",
|
|
292
|
+
properties: {
|
|
293
|
+
id: { type: "string", description: "paint, image, canvas, vector\u2026" },
|
|
294
|
+
name: { type: "string", description: "Display name, used in messages." },
|
|
295
|
+
kinds: { type: "array", items: { type: "string", enum: [..._chunkTZOX7KWVcjs.BRUSH_KINDS] }, description: "Brush kinds it has." },
|
|
296
|
+
tools: { type: "array", items: { type: "string", enum: [..._chunkTZOX7KWVcjs.BRUSH_TOOLS] }, description: "Tools it has (kind tool)." },
|
|
297
|
+
tipShapes: { type: "array", items: { type: "string", enum: [..._chunkTZOX7KWVcjs.BRUSH_TIP_SHAPES] }, description: "Tip shapes it renders." },
|
|
298
|
+
marks: { type: "array", items: { type: "string", enum: [..._chunkTZOX7KWVcjs.BRUSH_MARKS_KINDS] }, description: "Marks kinds it renders." },
|
|
299
|
+
surfaces: { type: "array", items: { type: "string", enum: [..._chunkTZOX7KWVcjs.BRUSH_SURFACES] }, description: "Surfaces it renders." },
|
|
300
|
+
exchange: { ...SUPPORT, description: "Picking paint up and mixing it in." },
|
|
301
|
+
reservoir: { ...SUPPORT, description: "The Mixer Brush reservoir." },
|
|
302
|
+
grain: { ...SUPPORT, description: "Paper grain response." },
|
|
303
|
+
light: { ...SUPPORT, description: "Light paint." },
|
|
304
|
+
motion: { ...SUPPORT, description: "Motion after painting." },
|
|
305
|
+
colours: { type: "array", items: { type: "string", enum: ["solid", "dual", "gradient", "effect"] }, description: "Colour kinds a default colour may be." },
|
|
306
|
+
velocity: { ...SUPPORT, description: "Velocity dynamics." },
|
|
307
|
+
tilt: { ...SUPPORT, description: "Tilt dynamics." }
|
|
308
|
+
},
|
|
309
|
+
required: ["id", "name", "kinds", "tools", "tipShapes", "marks", "surfaces", "exchange", "reservoir", "grain", "light", "motion", "colours", "velocity", "tilt"],
|
|
310
|
+
additionalProperties: false
|
|
311
|
+
};
|
|
312
|
+
var BRUSH_LIBRARY_FILE_JSON_SCHEMA = {
|
|
313
|
+
type: "object",
|
|
314
|
+
description: "A brush library file, as export_brushes writes it. Readers also accept version 1 files (flat engine brushes, migrated) and a bare array of brushes.",
|
|
315
|
+
properties: {
|
|
316
|
+
format: { type: "string", const: "pixerate-brushes", description: 'Always "pixerate-brushes".' },
|
|
317
|
+
version: { type: "integer", const: 2, description: "Always 2." },
|
|
318
|
+
brushes: { type: "array", items: { $ref: "brush.schema.json" }, description: "The brushes, each a facet brush (brush.schema.json)." }
|
|
319
|
+
},
|
|
320
|
+
required: ["format", "version", "brushes"],
|
|
321
|
+
additionalProperties: false
|
|
322
|
+
};
|
|
323
|
+
function migrationInputs() {
|
|
324
|
+
const pick = (id) => _chunkTZOX7KWVcjs.brushToJSON.call(void 0, _chunkTZOX7KWVcjs.BUILTIN_BRUSHES.find((b) => b.id === id));
|
|
325
|
+
return [
|
|
326
|
+
{ id: "plain", name: "Plain" },
|
|
327
|
+
pick("pencil-6b"),
|
|
328
|
+
{ ...pick("soft-pastel"), id: "my-pastel", name: "My pastel", category: "custom", grain: 0.2, tip: { ...pick("soft-pastel").tip, size: 50 } },
|
|
329
|
+
pick("mixer-brush"),
|
|
330
|
+
pick("watercolor-wash"),
|
|
331
|
+
pick("impasto-brush"),
|
|
332
|
+
pick("hair-strands"),
|
|
333
|
+
pick("bristle-round"),
|
|
334
|
+
pick("sticker-stars"),
|
|
335
|
+
pick("rainbow-marker"),
|
|
336
|
+
pick("blender"),
|
|
337
|
+
pick("add-water"),
|
|
338
|
+
pick("spray-can"),
|
|
339
|
+
// Fields an engine never reads are dropped on migration.
|
|
340
|
+
{ ...pick("ink-pen"), id: "ink-with-mixer", name: "Ink with mixer settings", mixer: { wet: 0.9, load: 0.1, mix: 0.9, loadEachStroke: false, cleanEachStroke: false, mixing: "pigment" } }
|
|
341
|
+
];
|
|
342
|
+
}
|
|
343
|
+
function editorSectionFixtures() {
|
|
344
|
+
const ids = ["highlighter", "chalk", "watercolor-wash", "hair-strands", "mixer-brush", "blender", "spray-can"];
|
|
345
|
+
return ids.flatMap(
|
|
346
|
+
(id) => Object.keys(_chunkTZOX7KWVcjs.BRUSH_HOST_PROFILES).map((host) => {
|
|
347
|
+
const brush = _chunkTZOX7KWVcjs.BRUSH_PRESETS.find((b) => b.id === id);
|
|
348
|
+
return { brush: id, host, sections: brushEditorSections(brush, _chunkTZOX7KWVcjs.BRUSH_HOST_PROFILES[host]) };
|
|
349
|
+
})
|
|
350
|
+
);
|
|
351
|
+
}
|
|
352
|
+
function toolDefinitions() {
|
|
353
|
+
const library = _chunkTZOX7KWVcjs.createBrushLibrary.call(void 0, );
|
|
354
|
+
const toolsFor = (host) => _chunkPYTJBVW5cjs.createBrushLibraryTools.call(void 0, library, { profile: _chunkTZOX7KWVcjs.BRUSH_HOST_PROFILES[host], renderPreview: () => ({ data: "", mimeType: "image/png" }) });
|
|
355
|
+
return {
|
|
356
|
+
tools: toolsFor("paint").map((t) => ({ name: t.name, title: t.title, description: t.description, inputSchema: t.inputSchema, annotations: t.annotations })),
|
|
357
|
+
hosts: Object.fromEntries(Object.keys(_chunkTZOX7KWVcjs.BRUSH_HOST_PROFILES).map((host) => [host, toolsFor(host).map((t) => t.name)]))
|
|
358
|
+
};
|
|
359
|
+
}
|
|
360
|
+
function brushContracts() {
|
|
361
|
+
const presets = _chunkTZOX7KWVcjs.BRUSH_PRESETS.map((b) => JSON.parse(JSON.stringify(b)));
|
|
362
|
+
const resolved = _chunkTZOX7KWVcjs.BRUSH_PRESETS.map((b) => ({ id: b.id, engine: _chunkTZOX7KWVcjs.resolveEngine.call(void 0, b), category: _chunkTZOX7KWVcjs.resolveCategory.call(void 0, b), brush: _chunkTZOX7KWVcjs.brushToJSON.call(void 0, _chunkTZOX7KWVcjs.resolveBrush.call(void 0, b)) }));
|
|
363
|
+
const profiles = Object.values(_chunkTZOX7KWVcjs.BRUSH_HOST_PROFILES);
|
|
364
|
+
const checks = _chunkTZOX7KWVcjs.BRUSH_PRESETS.map((b) => ({
|
|
365
|
+
id: b.id,
|
|
366
|
+
hosts: Object.fromEntries(profiles.map((p) => {
|
|
367
|
+
const c = _chunkTZOX7KWVcjs.checkBrush.call(void 0, b, p);
|
|
368
|
+
return [p.id, { ok: c.ok, issues: c.issues.map(({ facet, severity }) => ({ facet, severity })) }];
|
|
369
|
+
}))
|
|
370
|
+
}));
|
|
371
|
+
const migrations = migrationInputs().map((input) => ({ input, output: _chunkTZOX7KWVcjs.migrateBrushV1.call(void 0, input), resolved: _chunkTZOX7KWVcjs.brushToJSON.call(void 0, _chunkTZOX7KWVcjs.resolveBrush.call(void 0, _chunkTZOX7KWVcjs.migrateBrushV1.call(void 0, input))), engine: _chunkTZOX7KWVcjs.normalizePaintBrush.call(void 0, input).engine }));
|
|
372
|
+
const files = {
|
|
373
|
+
"brush.schema.json": { $schema: "https://json-schema.org/draft/2020-12/schema", $id: "brush.schema.json", ..._chunkTZOX7KWVcjs.BRUSH_JSON_SCHEMA },
|
|
374
|
+
"profile.schema.json": { $schema: "https://json-schema.org/draft/2020-12/schema", $id: "profile.schema.json", ...BRUSH_PROFILE_JSON_SCHEMA },
|
|
375
|
+
"library-file.schema.json": { $schema: "https://json-schema.org/draft/2020-12/schema", $id: "library-file.schema.json", ...BRUSH_LIBRARY_FILE_JSON_SCHEMA },
|
|
376
|
+
"presets.json": presets,
|
|
377
|
+
"resolved.json": resolved,
|
|
378
|
+
"profiles.json": profiles,
|
|
379
|
+
"checks.json": checks,
|
|
380
|
+
"migrations.json": migrations,
|
|
381
|
+
"tools.json": toolDefinitions(),
|
|
382
|
+
"editor-sections.json": editorSectionFixtures()
|
|
383
|
+
};
|
|
384
|
+
files["manifest.json"] = {
|
|
385
|
+
domain: "brushes",
|
|
386
|
+
formatVersion: BRUSH_CONTRACT_FORMAT_VERSION,
|
|
387
|
+
limits: { maxPalette: _chunkTZOX7KWVcjs.MAX_BRUSH_PALETTE },
|
|
388
|
+
counts: { presets: presets.length, profiles: profiles.length, migrations: migrations.length, editorSections: files["editor-sections.json"].length },
|
|
389
|
+
files: Object.keys(files).sort()
|
|
390
|
+
};
|
|
391
|
+
return files;
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
|
|
395
|
+
|
|
396
|
+
|
|
397
|
+
|
|
283
398
|
|
|
284
399
|
|
|
285
400
|
|
|
@@ -322,4 +437,4 @@ function brushLibraryGroups(entries, filter = {}) {
|
|
|
322
437
|
|
|
323
438
|
|
|
324
439
|
|
|
325
|
-
exports.BRUSH_FACET_SCHEMAS =
|
|
440
|
+
exports.BRUSH_CONTRACT_FORMAT_VERSION = BRUSH_CONTRACT_FORMAT_VERSION; exports.BRUSH_FACET_SCHEMAS = _chunkTZOX7KWVcjs.BRUSH_FACET_SCHEMAS; exports.BRUSH_HOST_PROFILES = _chunkTZOX7KWVcjs.BRUSH_HOST_PROFILES; exports.BRUSH_JSON_SCHEMA = _chunkTZOX7KWVcjs.BRUSH_JSON_SCHEMA; exports.BRUSH_KINDS = _chunkTZOX7KWVcjs.BRUSH_KINDS; exports.BRUSH_LIBRARY_FILE_JSON_SCHEMA = BRUSH_LIBRARY_FILE_JSON_SCHEMA; exports.BRUSH_MARKS_KINDS = _chunkTZOX7KWVcjs.BRUSH_MARKS_KINDS; exports.BRUSH_MEDIA = _chunkTZOX7KWVcjs.BRUSH_MEDIA; exports.BRUSH_PATCH_PROPERTIES = _chunkPYTJBVW5cjs.BRUSH_PATCH_PROPERTIES; exports.BRUSH_PRESETS = _chunkTZOX7KWVcjs.BRUSH_PRESETS; exports.BRUSH_PROFILE_JSON_SCHEMA = BRUSH_PROFILE_JSON_SCHEMA; exports.BRUSH_SURFACES = _chunkTZOX7KWVcjs.BRUSH_SURFACES; exports.BRUSH_TIP_SHAPES = _chunkTZOX7KWVcjs.BRUSH_TIP_SHAPES; exports.BRUSH_TOOLS = _chunkTZOX7KWVcjs.BRUSH_TOOLS; exports.BRUSH_UNSET_PROPERTY = _chunkPYTJBVW5cjs.BRUSH_UNSET_PROPERTY; exports.BRUSH_WORD = _chunkTZOX7KWVcjs.BRUSH_WORD; exports.BrushLibraryError = _chunkTZOX7KWVcjs.BrushLibraryError; exports.CANVAS_PROFILE = _chunkTZOX7KWVcjs.CANVAS_PROFILE; exports.IMAGE_PROFILE = _chunkTZOX7KWVcjs.IMAGE_PROFILE; exports.MAX_BRUSH_PALETTE = _chunkTZOX7KWVcjs.MAX_BRUSH_PALETTE; exports.PAINT_PROFILE = _chunkTZOX7KWVcjs.PAINT_PROFILE; exports.UNSETTABLE_BRUSH_FACETS = _chunkPYTJBVW5cjs.UNSETTABLE_BRUSH_FACETS; exports.VECTOR_PROFILE = _chunkTZOX7KWVcjs.VECTOR_PROFILE; exports.WET_BRUSH_TOOLS = _chunkTZOX7KWVcjs.WET_BRUSH_TOOLS; exports.brushColourHex = _chunkLRTR4ASZcjs.brushColourHex; exports.brushColourKind = _chunkTZOX7KWVcjs.brushColourKind; exports.brushContracts = brushContracts; exports.brushEditorSections = brushEditorSections; exports.brushLibraryGroups = brushLibraryGroups; exports.changedBrushPaths = _chunkPYTJBVW5cjs.changedBrushPaths; exports.checkBrush = _chunkTZOX7KWVcjs.checkBrush; exports.createBrushLibrary = _chunkTZOX7KWVcjs.createBrushLibrary; exports.createBrushLibraryToolProvider = _chunkPYTJBVW5cjs.createBrushLibraryToolProvider; exports.createBrushLibraryTools = _chunkPYTJBVW5cjs.createBrushLibraryTools; exports.degrade = _chunkTZOX7KWVcjs.degrade; exports.listPresets = _chunkTZOX7KWVcjs.listPresets; exports.mergeBrushPatch = _chunkPYTJBVW5cjs.mergeBrushPatch; exports.migrateBrushV1 = _chunkTZOX7KWVcjs.migrateBrushV1; exports.normalizeBrushSpec = _chunkTZOX7KWVcjs.normalizeBrushSpec; exports.parseBrushLibrary = _chunkTZOX7KWVcjs.parseBrushLibrary2; exports.resolveBrush = _chunkTZOX7KWVcjs.resolveBrush; exports.resolveCategory = _chunkTZOX7KWVcjs.resolveCategory; exports.resolveEngine = _chunkTZOX7KWVcjs.resolveEngine; exports.resolveWetMedium = _chunkTZOX7KWVcjs.resolveWetMedium; exports.setBrushEditorValue = setBrushEditorValue; exports.snapshotBrushLibrary = _chunkTZOX7KWVcjs.snapshotBrushLibrary;
|
package/dist/brushes/index.d.cts
CHANGED
|
@@ -15,6 +15,7 @@ export { resolveBrush, resolveCategory, resolveEngine, resolveWetMedium, type Re
|
|
|
15
15
|
export { migrateBrushV1 } from './migrate.cjs';
|
|
16
16
|
export { BRUSH_PRESETS } from './presets.cjs';
|
|
17
17
|
export { brushColourHex } from './colour.cjs';
|
|
18
|
+
export { BRUSH_CONTRACT_FORMAT_VERSION, BRUSH_LIBRARY_FILE_JSON_SCHEMA, BRUSH_PROFILE_JSON_SCHEMA, brushContracts } from './contract.cjs';
|
|
18
19
|
export { BRUSH_HOST_PROFILES, brushColourKind, CANVAS_PROFILE, checkBrush, degrade, IMAGE_PROFILE, listPresets, PAINT_PROFILE, VECTOR_PROFILE, type BrushCheck, type BrushColourKind, type BrushHostProfile, type BrushIssue, type BrushSupport, type DegradedBrush } from './profiles.cjs';
|
|
19
20
|
export { BrushLibraryError, createBrushLibrary, parseBrushLibrary, snapshotBrushLibrary, type BrushFilter, type BrushLibrary, type BrushLibraryEntry, type BrushLibraryErrorCode, type BrushLibraryFile, type BrushLibrarySnapshot, type BrushLibraryOptions, type ImportBrushesResult, type SaveBrushResult, } from './library.cjs';
|
|
20
21
|
export { BRUSH_PATCH_PROPERTIES, BRUSH_UNSET_PROPERTY, changedBrushPaths, mergeBrushPatch, UNSETTABLE_BRUSH_FACETS, type BrushPatch, type UnsettableBrushFacet } from './patch.cjs';
|
package/dist/brushes/index.d.ts
CHANGED
|
@@ -15,6 +15,7 @@ export { resolveBrush, resolveCategory, resolveEngine, resolveWetMedium, type Re
|
|
|
15
15
|
export { migrateBrushV1 } from './migrate.js';
|
|
16
16
|
export { BRUSH_PRESETS } from './presets.js';
|
|
17
17
|
export { brushColourHex } from './colour.js';
|
|
18
|
+
export { BRUSH_CONTRACT_FORMAT_VERSION, BRUSH_LIBRARY_FILE_JSON_SCHEMA, BRUSH_PROFILE_JSON_SCHEMA, brushContracts } from './contract.js';
|
|
18
19
|
export { BRUSH_HOST_PROFILES, brushColourKind, CANVAS_PROFILE, checkBrush, degrade, IMAGE_PROFILE, listPresets, PAINT_PROFILE, VECTOR_PROFILE, type BrushCheck, type BrushColourKind, type BrushHostProfile, type BrushIssue, type BrushSupport, type DegradedBrush } from './profiles.js';
|
|
19
20
|
export { BrushLibraryError, createBrushLibrary, parseBrushLibrary, snapshotBrushLibrary, type BrushFilter, type BrushLibrary, type BrushLibraryEntry, type BrushLibraryErrorCode, type BrushLibraryFile, type BrushLibrarySnapshot, type BrushLibraryOptions, type ImportBrushesResult, type SaveBrushResult, } from './library.js';
|
|
20
21
|
export { BRUSH_PATCH_PROPERTIES, BRUSH_UNSET_PROPERTY, changedBrushPaths, mergeBrushPatch, UNSETTABLE_BRUSH_FACETS, type BrushPatch, type UnsettableBrushFacet } from './patch.js';
|
package/dist/brushes/index.js
CHANGED
|
@@ -8,12 +8,8 @@ import {
|
|
|
8
8
|
createBrushLibraryToolProvider,
|
|
9
9
|
createBrushLibraryTools,
|
|
10
10
|
mergeBrushPatch
|
|
11
|
-
} from "../chunk-
|
|
11
|
+
} from "../chunk-X2EXYY4J.js";
|
|
12
12
|
import "../chunk-J5UQHWVL.js";
|
|
13
|
-
import {
|
|
14
|
-
brushColourHex
|
|
15
|
-
} from "../chunk-FJBQTZS4.js";
|
|
16
|
-
import "../chunk-3CI7FRMK.js";
|
|
17
13
|
import {
|
|
18
14
|
BRUSH_FACET_SCHEMAS,
|
|
19
15
|
BRUSH_FIELDS,
|
|
@@ -28,6 +24,7 @@ import {
|
|
|
28
24
|
BRUSH_TIP_SHAPES,
|
|
29
25
|
BRUSH_TOOLS,
|
|
30
26
|
BRUSH_WORD,
|
|
27
|
+
BUILTIN_BRUSHES,
|
|
31
28
|
BrushLibraryError,
|
|
32
29
|
CANVAS_PROFILE,
|
|
33
30
|
DOT_ROTATIONS,
|
|
@@ -45,6 +42,7 @@ import {
|
|
|
45
42
|
WET_BRUSH_TOOLS,
|
|
46
43
|
WET_MEDIA,
|
|
47
44
|
brushColourKind,
|
|
45
|
+
brushToJSON,
|
|
48
46
|
checkBrush,
|
|
49
47
|
createBrushLibrary,
|
|
50
48
|
degrade,
|
|
@@ -52,6 +50,7 @@ import {
|
|
|
52
50
|
listPresets,
|
|
53
51
|
migrateBrushV1,
|
|
54
52
|
normalizeBrushSpec,
|
|
53
|
+
normalizePaintBrush,
|
|
55
54
|
parseBrushLibrary2 as parseBrushLibrary,
|
|
56
55
|
resolveBrush,
|
|
57
56
|
resolveCategory,
|
|
@@ -59,10 +58,14 @@ import {
|
|
|
59
58
|
resolveWetMedium,
|
|
60
59
|
setPath,
|
|
61
60
|
snapshotBrushLibrary
|
|
62
|
-
} from "../chunk-
|
|
61
|
+
} from "../chunk-5IW65VQ6.js";
|
|
63
62
|
import {
|
|
64
63
|
STAMP_KINDS
|
|
65
64
|
} from "../chunk-APX63ILU.js";
|
|
65
|
+
import {
|
|
66
|
+
brushColourHex
|
|
67
|
+
} from "../chunk-FJBQTZS4.js";
|
|
68
|
+
import "../chunk-3CI7FRMK.js";
|
|
66
69
|
import "../chunk-SZTI6EER.js";
|
|
67
70
|
import "../chunk-V2ZCJRDM.js";
|
|
68
71
|
import {
|
|
@@ -279,15 +282,126 @@ function brushLibraryGroups(entries, filter = {}) {
|
|
|
279
282
|
const order = ["dry", "ink", "paint", "spray", "other", "tools"];
|
|
280
283
|
return [...groups.values()].sort((a, b) => order.indexOf(a.id) - order.indexOf(b.id));
|
|
281
284
|
}
|
|
285
|
+
|
|
286
|
+
// src/brushes/contract.ts
|
|
287
|
+
var BRUSH_CONTRACT_FORMAT_VERSION = 1;
|
|
288
|
+
var SUPPORT = { type: "string", enum: ["full", "ignored", "none"], description: "full: rendered; ignored: accepted, painted without it (a warning); none: refused (an error)." };
|
|
289
|
+
var BRUSH_PROFILE_JSON_SCHEMA = {
|
|
290
|
+
type: "object",
|
|
291
|
+
description: "What a host can render (`BrushHostProfile`).",
|
|
292
|
+
properties: {
|
|
293
|
+
id: { type: "string", description: "paint, image, canvas, vector\u2026" },
|
|
294
|
+
name: { type: "string", description: "Display name, used in messages." },
|
|
295
|
+
kinds: { type: "array", items: { type: "string", enum: [...BRUSH_KINDS] }, description: "Brush kinds it has." },
|
|
296
|
+
tools: { type: "array", items: { type: "string", enum: [...BRUSH_TOOLS] }, description: "Tools it has (kind tool)." },
|
|
297
|
+
tipShapes: { type: "array", items: { type: "string", enum: [...BRUSH_TIP_SHAPES] }, description: "Tip shapes it renders." },
|
|
298
|
+
marks: { type: "array", items: { type: "string", enum: [...BRUSH_MARKS_KINDS] }, description: "Marks kinds it renders." },
|
|
299
|
+
surfaces: { type: "array", items: { type: "string", enum: [...BRUSH_SURFACES] }, description: "Surfaces it renders." },
|
|
300
|
+
exchange: { ...SUPPORT, description: "Picking paint up and mixing it in." },
|
|
301
|
+
reservoir: { ...SUPPORT, description: "The Mixer Brush reservoir." },
|
|
302
|
+
grain: { ...SUPPORT, description: "Paper grain response." },
|
|
303
|
+
light: { ...SUPPORT, description: "Light paint." },
|
|
304
|
+
motion: { ...SUPPORT, description: "Motion after painting." },
|
|
305
|
+
colours: { type: "array", items: { type: "string", enum: ["solid", "dual", "gradient", "effect"] }, description: "Colour kinds a default colour may be." },
|
|
306
|
+
velocity: { ...SUPPORT, description: "Velocity dynamics." },
|
|
307
|
+
tilt: { ...SUPPORT, description: "Tilt dynamics." }
|
|
308
|
+
},
|
|
309
|
+
required: ["id", "name", "kinds", "tools", "tipShapes", "marks", "surfaces", "exchange", "reservoir", "grain", "light", "motion", "colours", "velocity", "tilt"],
|
|
310
|
+
additionalProperties: false
|
|
311
|
+
};
|
|
312
|
+
var BRUSH_LIBRARY_FILE_JSON_SCHEMA = {
|
|
313
|
+
type: "object",
|
|
314
|
+
description: "A brush library file, as export_brushes writes it. Readers also accept version 1 files (flat engine brushes, migrated) and a bare array of brushes.",
|
|
315
|
+
properties: {
|
|
316
|
+
format: { type: "string", const: "pixerate-brushes", description: 'Always "pixerate-brushes".' },
|
|
317
|
+
version: { type: "integer", const: 2, description: "Always 2." },
|
|
318
|
+
brushes: { type: "array", items: { $ref: "brush.schema.json" }, description: "The brushes, each a facet brush (brush.schema.json)." }
|
|
319
|
+
},
|
|
320
|
+
required: ["format", "version", "brushes"],
|
|
321
|
+
additionalProperties: false
|
|
322
|
+
};
|
|
323
|
+
function migrationInputs() {
|
|
324
|
+
const pick = (id) => brushToJSON(BUILTIN_BRUSHES.find((b) => b.id === id));
|
|
325
|
+
return [
|
|
326
|
+
{ id: "plain", name: "Plain" },
|
|
327
|
+
pick("pencil-6b"),
|
|
328
|
+
{ ...pick("soft-pastel"), id: "my-pastel", name: "My pastel", category: "custom", grain: 0.2, tip: { ...pick("soft-pastel").tip, size: 50 } },
|
|
329
|
+
pick("mixer-brush"),
|
|
330
|
+
pick("watercolor-wash"),
|
|
331
|
+
pick("impasto-brush"),
|
|
332
|
+
pick("hair-strands"),
|
|
333
|
+
pick("bristle-round"),
|
|
334
|
+
pick("sticker-stars"),
|
|
335
|
+
pick("rainbow-marker"),
|
|
336
|
+
pick("blender"),
|
|
337
|
+
pick("add-water"),
|
|
338
|
+
pick("spray-can"),
|
|
339
|
+
// Fields an engine never reads are dropped on migration.
|
|
340
|
+
{ ...pick("ink-pen"), id: "ink-with-mixer", name: "Ink with mixer settings", mixer: { wet: 0.9, load: 0.1, mix: 0.9, loadEachStroke: false, cleanEachStroke: false, mixing: "pigment" } }
|
|
341
|
+
];
|
|
342
|
+
}
|
|
343
|
+
function editorSectionFixtures() {
|
|
344
|
+
const ids = ["highlighter", "chalk", "watercolor-wash", "hair-strands", "mixer-brush", "blender", "spray-can"];
|
|
345
|
+
return ids.flatMap(
|
|
346
|
+
(id) => Object.keys(BRUSH_HOST_PROFILES).map((host) => {
|
|
347
|
+
const brush = BRUSH_PRESETS.find((b) => b.id === id);
|
|
348
|
+
return { brush: id, host, sections: brushEditorSections(brush, BRUSH_HOST_PROFILES[host]) };
|
|
349
|
+
})
|
|
350
|
+
);
|
|
351
|
+
}
|
|
352
|
+
function toolDefinitions() {
|
|
353
|
+
const library = createBrushLibrary();
|
|
354
|
+
const toolsFor = (host) => createBrushLibraryTools(library, { profile: BRUSH_HOST_PROFILES[host], renderPreview: () => ({ data: "", mimeType: "image/png" }) });
|
|
355
|
+
return {
|
|
356
|
+
tools: toolsFor("paint").map((t) => ({ name: t.name, title: t.title, description: t.description, inputSchema: t.inputSchema, annotations: t.annotations })),
|
|
357
|
+
hosts: Object.fromEntries(Object.keys(BRUSH_HOST_PROFILES).map((host) => [host, toolsFor(host).map((t) => t.name)]))
|
|
358
|
+
};
|
|
359
|
+
}
|
|
360
|
+
function brushContracts() {
|
|
361
|
+
const presets = BRUSH_PRESETS.map((b) => JSON.parse(JSON.stringify(b)));
|
|
362
|
+
const resolved = BRUSH_PRESETS.map((b) => ({ id: b.id, engine: resolveEngine(b), category: resolveCategory(b), brush: brushToJSON(resolveBrush(b)) }));
|
|
363
|
+
const profiles = Object.values(BRUSH_HOST_PROFILES);
|
|
364
|
+
const checks = BRUSH_PRESETS.map((b) => ({
|
|
365
|
+
id: b.id,
|
|
366
|
+
hosts: Object.fromEntries(profiles.map((p) => {
|
|
367
|
+
const c = checkBrush(b, p);
|
|
368
|
+
return [p.id, { ok: c.ok, issues: c.issues.map(({ facet, severity }) => ({ facet, severity })) }];
|
|
369
|
+
}))
|
|
370
|
+
}));
|
|
371
|
+
const migrations = migrationInputs().map((input) => ({ input, output: migrateBrushV1(input), resolved: brushToJSON(resolveBrush(migrateBrushV1(input))), engine: normalizePaintBrush(input).engine }));
|
|
372
|
+
const files = {
|
|
373
|
+
"brush.schema.json": { $schema: "https://json-schema.org/draft/2020-12/schema", $id: "brush.schema.json", ...BRUSH_JSON_SCHEMA },
|
|
374
|
+
"profile.schema.json": { $schema: "https://json-schema.org/draft/2020-12/schema", $id: "profile.schema.json", ...BRUSH_PROFILE_JSON_SCHEMA },
|
|
375
|
+
"library-file.schema.json": { $schema: "https://json-schema.org/draft/2020-12/schema", $id: "library-file.schema.json", ...BRUSH_LIBRARY_FILE_JSON_SCHEMA },
|
|
376
|
+
"presets.json": presets,
|
|
377
|
+
"resolved.json": resolved,
|
|
378
|
+
"profiles.json": profiles,
|
|
379
|
+
"checks.json": checks,
|
|
380
|
+
"migrations.json": migrations,
|
|
381
|
+
"tools.json": toolDefinitions(),
|
|
382
|
+
"editor-sections.json": editorSectionFixtures()
|
|
383
|
+
};
|
|
384
|
+
files["manifest.json"] = {
|
|
385
|
+
domain: "brushes",
|
|
386
|
+
formatVersion: BRUSH_CONTRACT_FORMAT_VERSION,
|
|
387
|
+
limits: { maxPalette: MAX_BRUSH_PALETTE },
|
|
388
|
+
counts: { presets: presets.length, profiles: profiles.length, migrations: migrations.length, editorSections: files["editor-sections.json"].length },
|
|
389
|
+
files: Object.keys(files).sort()
|
|
390
|
+
};
|
|
391
|
+
return files;
|
|
392
|
+
}
|
|
282
393
|
export {
|
|
394
|
+
BRUSH_CONTRACT_FORMAT_VERSION,
|
|
283
395
|
BRUSH_FACET_SCHEMAS,
|
|
284
396
|
BRUSH_HOST_PROFILES,
|
|
285
397
|
BRUSH_JSON_SCHEMA,
|
|
286
398
|
BRUSH_KINDS,
|
|
399
|
+
BRUSH_LIBRARY_FILE_JSON_SCHEMA,
|
|
287
400
|
BRUSH_MARKS_KINDS,
|
|
288
401
|
BRUSH_MEDIA,
|
|
289
402
|
BRUSH_PATCH_PROPERTIES,
|
|
290
403
|
BRUSH_PRESETS,
|
|
404
|
+
BRUSH_PROFILE_JSON_SCHEMA,
|
|
291
405
|
BRUSH_SURFACES,
|
|
292
406
|
BRUSH_TIP_SHAPES,
|
|
293
407
|
BRUSH_TOOLS,
|
|
@@ -303,6 +417,7 @@ export {
|
|
|
303
417
|
WET_BRUSH_TOOLS,
|
|
304
418
|
brushColourHex,
|
|
305
419
|
brushColourKind,
|
|
420
|
+
brushContracts,
|
|
306
421
|
brushEditorSections,
|
|
307
422
|
brushLibraryGroups,
|
|
308
423
|
changedBrushPaths,
|
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
pathDataToPolyline
|
|
3
|
-
} from "./chunk-
|
|
4
|
-
import {
|
|
5
|
-
parseCssColor
|
|
6
|
-
} from "./chunk-3CI7FRMK.js";
|
|
3
|
+
} from "./chunk-EHALWBBD.js";
|
|
7
4
|
import {
|
|
8
5
|
BRUSH_PRESETS,
|
|
9
6
|
BUILTIN_BRUSHES,
|
|
@@ -14,13 +11,16 @@ import {
|
|
|
14
11
|
normalizeBrushSpec,
|
|
15
12
|
resolveBrush,
|
|
16
13
|
resolveCategory
|
|
17
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-5IW65VQ6.js";
|
|
18
15
|
import "./chunk-APX63ILU.js";
|
|
19
16
|
import {
|
|
20
17
|
formatNumber,
|
|
21
18
|
getShapeSvg,
|
|
22
19
|
resolveCanvasGradient
|
|
23
20
|
} from "./chunk-PWBZH3FK.js";
|
|
21
|
+
import {
|
|
22
|
+
parseCssColor
|
|
23
|
+
} from "./chunk-3CI7FRMK.js";
|
|
24
24
|
import "./chunk-SZTI6EER.js";
|
|
25
25
|
import "./chunk-V2ZCJRDM.js";
|
|
26
26
|
import {
|
|
@@ -37,6 +37,12 @@ import "./chunk-OTTT5N3K.js";
|
|
|
37
37
|
import "./chunk-IRSTHLQQ.js";
|
|
38
38
|
import "./chunk-HVVR5PZW.js";
|
|
39
39
|
import "./chunk-QGHEDC7B.js";
|
|
40
|
+
import {
|
|
41
|
+
isDualColor
|
|
42
|
+
} from "./chunk-VR6OGHU5.js";
|
|
43
|
+
import "./chunk-JC2SHA4A.js";
|
|
44
|
+
import "./chunk-MHLU6GRJ.js";
|
|
45
|
+
import "./chunk-6ONMQ6WF.js";
|
|
40
46
|
|
|
41
47
|
// src/canvas/brushstrokeRender.ts
|
|
42
48
|
var PRESETS = listPresets(CANVAS_PROFILE).map((spec) => BUILTIN_BRUSHES.find((b) => b.id === spec.id));
|
|
@@ -53,12 +59,16 @@ function readCanvasBrushSpec(spec) {
|
|
|
53
59
|
return brush;
|
|
54
60
|
}
|
|
55
61
|
function listCanvasBrushes(user = []) {
|
|
56
|
-
const
|
|
62
|
+
const colourOf = (spec) => {
|
|
63
|
+
const d = spec.colour?.default;
|
|
64
|
+
return typeof d === "string" || isDualColor(d) ? { defaultColor: d } : {};
|
|
65
|
+
};
|
|
66
|
+
const out = PRESETS.map((b) => ({ id: b.id, name: b.name, category: b.category, size: b.tip.size, builtin: true, ...colourOf(BRUSH_PRESETS.find((p) => p.id === b.id)) }));
|
|
57
67
|
for (const raw of user) {
|
|
58
68
|
try {
|
|
59
69
|
const brush = readCanvasBrushSpec(raw);
|
|
60
70
|
if (out.some((b) => b.id === brush.id)) continue;
|
|
61
|
-
out.push({ id: brush.id, name: brush.name, category: resolveCategory(brush), size: resolveBrush(brush).tip.size, builtin: false, spec: brush });
|
|
71
|
+
out.push({ id: brush.id, name: brush.name, category: resolveCategory(brush), size: resolveBrush(brush).tip.size, builtin: false, spec: brush, ...colourOf(brush) });
|
|
62
72
|
} catch {
|
|
63
73
|
}
|
|
64
74
|
}
|