@pixerate/editor 0.267.0 → 0.268.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 +62 -62
- package/dist/animation-editor/index.js +6 -6
- package/dist/brushes/index.cjs +198 -72
- package/dist/brushes/index.d.cts +4 -3
- package/dist/brushes/index.d.ts +4 -3
- package/dist/brushes/index.js +136 -10
- package/dist/brushes/library.d.cts +27 -1
- package/dist/brushes/library.d.ts +27 -1
- package/dist/brushes/profiles.d.cts +4 -0
- package/dist/brushes/profiles.d.ts +4 -0
- package/dist/brushes/schema.d.cts +4 -0
- package/dist/brushes/schema.d.ts +4 -0
- package/dist/brushes/sources.d.cts +114 -0
- package/dist/brushes/sources.d.ts +114 -0
- package/dist/brushes/types.d.cts +37 -5
- package/dist/brushes/types.d.ts +37 -5
- package/dist/brushes/ui.d.cts +40 -4
- package/dist/brushes/ui.d.ts +40 -4
- package/dist/{brushstrokeRender-NLFPEBGI.js → brushstrokeRender-A727TTNQ.js} +6 -6
- package/dist/{brushstrokeRender-L7JYRR2R.cjs → brushstrokeRender-WR2N5HHY.cjs} +22 -22
- package/dist/canvas/index.cjs +13 -13
- package/dist/canvas/index.js +1 -1
- package/dist/{chunk-J2TNIZ55.cjs → chunk-2WOGXEDX.cjs} +1 -1
- package/dist/{chunk-JGWVZPT6.js → chunk-3XDSNIGF.js} +72 -5
- package/dist/{chunk-EXB2EGBE.cjs → chunk-62MFUHSI.cjs} +16 -16
- package/dist/{chunk-FGJHJIMN.js → chunk-74ODPZLX.js} +10 -10
- package/dist/{chunk-GCVFEPJG.js → chunk-ACTHSQOI.js} +182 -0
- package/dist/{chunk-LHPEG5AU.cjs → chunk-B3G7BKUV.cjs} +90 -90
- package/dist/{chunk-EF7LZAXQ.js → chunk-BAZMCFVL.js} +1 -1
- package/dist/{chunk-HIO6E7LC.cjs → chunk-BPJSI4NT.cjs} +2 -2
- package/dist/{chunk-XVOP3CGQ.cjs → chunk-EU2ZZA6L.cjs} +393 -62
- package/dist/{chunk-YIC6MAJ2.js → chunk-HFY5LG5J.js} +1 -1
- package/dist/{chunk-7UKFXXWL.js → chunk-HVO6XCI4.js} +1 -1
- package/dist/{chunk-OKHKA43L.cjs → chunk-JBB3GDBB.cjs} +330 -216
- package/dist/{chunk-AGNUD5BI.js → chunk-KZI3YWKW.js} +351 -20
- package/dist/{chunk-EYSHTYLG.js → chunk-LETF75CA.js} +1 -1
- package/dist/{chunk-FQPUF2W2.cjs → chunk-NIBFKXMD.cjs} +217 -35
- package/dist/{chunk-G7NHE2VD.cjs → chunk-NPWWSCWT.cjs} +35 -35
- package/dist/{chunk-OSEXT7JL.js → chunk-QNY7BDFP.js} +1 -1
- package/dist/{chunk-PXDIAYB6.cjs → chunk-STLTOISW.cjs} +34 -214
- package/dist/{chunk-4IDUYB45.js → chunk-UVTO3D4E.js} +130 -16
- package/dist/{chunk-TXFWZ5ZJ.js → chunk-W6JDUXP3.js} +4 -184
- package/dist/{chunk-LA5Y4ETA.cjs → chunk-YOVXQHA3.cjs} +23 -23
- package/dist/{chunk-DT4YQUGT.cjs → chunk-YXP6X3SY.cjs} +101 -34
- package/dist/image-editor/index.cjs +851 -851
- package/dist/image-editor/index.js +23 -23
- package/dist/paint/index.cjs +5 -5
- package/dist/paint/index.js +11 -11
- package/dist/paint-editor/brush-library-tools.d.cts +12 -2
- package/dist/paint-editor/brush-library-tools.d.ts +12 -2
- package/dist/paint-editor/brush-model.d.cts +29 -1
- package/dist/paint-editor/brush-model.d.ts +29 -1
- package/dist/paint-editor/brush-source-art.d.cts +32 -0
- package/dist/paint-editor/brush-source-art.d.ts +32 -0
- package/dist/paint-editor/controller.d.cts +6 -1
- package/dist/paint-editor/controller.d.ts +6 -1
- package/dist/paint-editor/dab-stroke.d.cts +2 -0
- package/dist/paint-editor/dab-stroke.d.ts +2 -0
- package/dist/paint-editor/engine.d.cts +11 -2
- package/dist/paint-editor/engine.d.ts +11 -2
- package/dist/paint-editor/index.cjs +576 -481
- package/dist/paint-editor/index.d.cts +3 -1
- package/dist/paint-editor/index.d.ts +3 -1
- package/dist/paint-editor/index.js +127 -32
- package/dist/paint-editor/stamp-tip.d.cts +8 -5
- package/dist/paint-editor/stamp-tip.d.ts +8 -5
- package/dist/paint-editor/thumbnails.d.cts +6 -0
- package/dist/paint-editor/thumbnails.d.ts +6 -0
- package/dist/paint-editor/tip-grain.d.cts +34 -0
- package/dist/paint-editor/tip-grain.d.ts +34 -0
- package/dist/raster/index.cjs +2 -2
- package/dist/raster/index.js +9 -9
- package/dist/vector/index.cjs +1002 -1002
- package/dist/vector/index.js +7 -7
- package/package.json +1 -1
- package/skills/pixerate-brushes/SKILL.md +35 -8
- package/skills/pixerate-brushes-design/SKILL.md +8 -1
- package/skills/pixerate-paint-editor/SKILL.md +6 -0
- package/skills/pixerate-paint-editor/references/brush-facets.md +3 -1
- package/skills/pixerate-paint-sketch-to-finish/SKILL.md +1 -0
package/dist/brushes/index.cjs
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
|
|
11
|
-
var
|
|
11
|
+
var _chunkYXP6X3SYcjs = require('../chunk-YXP6X3SY.cjs');
|
|
12
12
|
require('../chunk-PFHJS4HE.cjs');
|
|
13
13
|
|
|
14
14
|
|
|
@@ -17,7 +17,7 @@ require('../chunk-PFHJS4HE.cjs');
|
|
|
17
17
|
|
|
18
18
|
|
|
19
19
|
|
|
20
|
-
var
|
|
20
|
+
var _chunkBPJSI4NTcjs = require('../chunk-BPJSI4NT.cjs');
|
|
21
21
|
|
|
22
22
|
|
|
23
23
|
|
|
@@ -69,7 +69,29 @@ var _chunkHIO6E7LCcjs = require('../chunk-HIO6E7LC.cjs');
|
|
|
69
69
|
|
|
70
70
|
|
|
71
71
|
|
|
72
|
-
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
var _chunkEU2ZZA6Lcjs = require('../chunk-EU2ZZA6L.cjs');
|
|
73
95
|
|
|
74
96
|
|
|
75
97
|
var _chunkRDFHWAHLcjs = require('../chunk-RDFHWAHL.cjs');
|
|
@@ -80,12 +102,17 @@ require('../chunk-U67EN7GG.cjs');
|
|
|
80
102
|
require('../chunk-WOFXZ3XU.cjs');
|
|
81
103
|
|
|
82
104
|
|
|
83
|
-
var
|
|
105
|
+
var _chunkNIBFKXMDcjs = require('../chunk-NIBFKXMD.cjs');
|
|
84
106
|
require('../chunk-3K6HWEXZ.cjs');
|
|
85
107
|
|
|
86
108
|
|
|
87
109
|
var _chunk2VX55NFMcjs = require('../chunk-2VX55NFM.cjs');
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
var _chunkW5M3J7PVcjs = require('../chunk-W5M3J7PV.cjs');
|
|
88
114
|
require('../chunk-474IQG74.cjs');
|
|
115
|
+
require('../chunk-XFM3OCHU.cjs');
|
|
89
116
|
|
|
90
117
|
|
|
91
118
|
var _chunkMLLTWAXHcjs = require('../chunk-MLLTWAXH.cjs');
|
|
@@ -107,6 +134,9 @@ var RENDER_LABELS = { dot: "Dots", line: "Lines", sequence: "Beads", ribbon: "Ri
|
|
|
107
134
|
var APPLICATOR_LABELS = { brush: "Brush", tube: "Paint tube", knife: "Palette knife", roller: "Roller", gloop: "Gloop pen" };
|
|
108
135
|
var WET_MEDIUM_LABELS = { watercolor: "Watercolour", gouache: "Gouache", oil: "Oil" };
|
|
109
136
|
var STAMP_OPTIONS = _chunkRDFHWAHLcjs.STAMP_KINDS.map((k) => ({ value: `editor:${k}`, label: title(k) }));
|
|
137
|
+
var GRAIN_MODE_LABELS = { texturised: "Texturised (stays put)", moving: "Moving (rolls with the tip)" };
|
|
138
|
+
var FLIP_LABELS = { none: "None", x: "Across", y: "Along", xy: "Both" };
|
|
139
|
+
var DAB_ENGINES = /* @__PURE__ */ new Set(["dab", "eraser", "mixer", "blender", "smudge"]);
|
|
110
140
|
var ARIA = {
|
|
111
141
|
"dynamics.rotation": "Brush rotation",
|
|
112
142
|
"tip.blend": "Brush blend",
|
|
@@ -119,23 +149,25 @@ var ARIA = {
|
|
|
119
149
|
"marks.stampRotation": "Dot rotation",
|
|
120
150
|
"behaviour.wet.medium": "Wet medium",
|
|
121
151
|
"behaviour.thick.applicator": "Impasto tool",
|
|
122
|
-
"light.pressure": "Light follows pressure"
|
|
152
|
+
"light.pressure": "Light follows pressure",
|
|
153
|
+
"tip.grain.source": "Tip grain",
|
|
154
|
+
"dynamics.angleJitter": "Brush rotation jitter"
|
|
123
155
|
};
|
|
124
156
|
var aria = (path, label) => _nullishCoalesce(ARIA[path], () => ( `Brush ${label.toLowerCase()}`));
|
|
125
|
-
function brushEditorSections(brush, profile =
|
|
126
|
-
const resolved =
|
|
127
|
-
const engine =
|
|
128
|
-
const fieldOf = (facet) =>
|
|
129
|
-
const facetOf = (enginePath) => _optionalChain([(_nullishCoalesce(
|
|
157
|
+
function brushEditorSections(brush, profile = _chunkEU2ZZA6Lcjs.PAINT_PROFILE, context = {}) {
|
|
158
|
+
const resolved = _chunkEU2ZZA6Lcjs.resolveBrush.call(void 0, brush);
|
|
159
|
+
const engine = _chunkEU2ZZA6Lcjs.resolveEngine.call(void 0, brush);
|
|
160
|
+
const fieldOf = (facet) => _chunkEU2ZZA6Lcjs.BRUSH_FIELDS.find((f) => f.facet === facet && f.engines.includes(engine));
|
|
161
|
+
const facetOf = (enginePath) => _optionalChain([(_nullishCoalesce(_chunkEU2ZZA6Lcjs.BRUSH_FIELDS.find((f) => f.engine === enginePath && f.engines.includes(engine)), () => ( _chunkEU2ZZA6Lcjs.BRUSH_FIELDS.find((f) => f.engine === enginePath)))), 'optionalAccess', _ => _.facet]);
|
|
130
162
|
const value = (path) => {
|
|
131
|
-
const own =
|
|
163
|
+
const own = _chunkEU2ZZA6Lcjs.getPath.call(void 0, brush, path);
|
|
132
164
|
if (own !== void 0) return own;
|
|
133
165
|
const field = fieldOf(path);
|
|
134
166
|
if (!field) return void 0;
|
|
135
|
-
const v =
|
|
167
|
+
const v = _chunkEU2ZZA6Lcjs.getPath.call(void 0, resolved, field.engine);
|
|
136
168
|
return field.map ? field.map.toFacet(v) : v;
|
|
137
169
|
};
|
|
138
|
-
const issues =
|
|
170
|
+
const issues = _chunkEU2ZZA6Lcjs.checkBrush.call(void 0, brush, profile).issues;
|
|
139
171
|
const warned = new Map(issues.filter((i) => i.severity === "warning").map((i) => [i.facet, i.reason]));
|
|
140
172
|
const refused = new Set(issues.filter((i) => i.severity === "error").map((i) => i.facet));
|
|
141
173
|
const full = (s) => s === "full";
|
|
@@ -148,7 +180,7 @@ function brushEditorSections(brush, profile = _chunkXVOP3CGQcjs.PAINT_PROFILE) {
|
|
|
148
180
|
const slider = (c, path = facetOf(c.path)) => {
|
|
149
181
|
if (!path) return null;
|
|
150
182
|
const v = value(path);
|
|
151
|
-
return withNote({ kind: "slider", path, label: c.label, ariaLabel: aria(path, c.label), min: c.min, max: path === "tip.size" ? Math.min(c.max,
|
|
183
|
+
return withNote({ kind: "slider", path, label: c.label, ariaLabel: aria(path, c.label), min: c.min, max: path === "tip.size" ? Math.min(c.max, _chunkNIBFKXMDcjs.MAX_BRUSH_SIZE) : c.max, step: c.step, value: typeof v === "number" ? v : c.min });
|
|
152
184
|
};
|
|
153
185
|
const choice = (path, label, opts, fallback = _nullishCoalesce(_optionalChain([opts, 'access', _5 => _5[0], 'optionalAccess', _6 => _6.value]), () => ( ""))) => withNote({ kind: "choice", path, label, ariaLabel: aria(path, label), options: opts, value: String(_nullishCoalesce(value(path), () => ( fallback))) });
|
|
154
186
|
const toggle = (path, label) => withNote({ kind: "toggle", path, label, ariaLabel: aria(path, label), value: Boolean(value(path)) });
|
|
@@ -160,70 +192,90 @@ function brushEditorSections(brush, profile = _chunkXVOP3CGQcjs.PAINT_PROFILE) {
|
|
|
160
192
|
};
|
|
161
193
|
const isTool = brush.kind === "tool";
|
|
162
194
|
const shape = brush.tip.shape;
|
|
195
|
+
const sourceOptions = (_nullishCoalesce(context.sources, () => ( []))).map((x) => ({ value: _chunkEU2ZZA6Lcjs.brushSourceRef.call(void 0, x.id), label: x.name }));
|
|
163
196
|
const marks = _nullishCoalesce(_optionalChain([brush, 'access', _7 => _7.marks, 'optionalAccess', _8 => _8.kind]), () => ( "continuous"));
|
|
164
197
|
const exchangeFull = full(_optionalChain([brush, 'access', _9 => _9.behaviour, 'optionalAccess', _10 => _10.exchange, 'optionalAccess', _11 => _11.reservoir]) ? profile.reservoir : profile.exchange);
|
|
165
198
|
add("medium", "Medium", [
|
|
166
199
|
profile.kinds.length > 1 && profile.kinds.includes(brush.kind) && choice("kind", "Kind", options(profile.kinds, { mark: "Lays a material", tool: "Works on paint" })),
|
|
167
|
-
!isTool && choice("medium", "Medium", [{ value: "", label: "Any" }, ...options(
|
|
200
|
+
!isTool && choice("medium", "Medium", [{ value: "", label: "Any" }, ...options(_chunkEU2ZZA6Lcjs.BRUSH_MEDIA, MEDIUM_LABELS)], ""),
|
|
168
201
|
!isTool && withNote({ kind: "text", path: "variety", label: "Variety", ariaLabel: "Brush variety", value: _nullishCoalesce(brush.variety, () => ( "")), placeholder: "pencil, oil, highlighter\u2026" }),
|
|
169
202
|
isTool && !!brush.tool && profile.tools.includes(brush.tool) && choice("tool", "Tool", options(profile.tools, TOOL_LABELS))
|
|
170
203
|
]);
|
|
171
|
-
const engineControls =
|
|
172
|
-
const tipSliders =
|
|
204
|
+
const engineControls = _chunkYXP6X3SYcjs.brushEngineControls.call(void 0, resolved);
|
|
205
|
+
const tipSliders = _chunkYXP6X3SYcjs.BRUSH_SLIDERS.filter((c) => c.path.startsWith("tip.") && c.path !== "tip.smoothing");
|
|
173
206
|
add("shape", "Shape", [
|
|
174
207
|
!refused.has("tip.shape") && choice("tip.shape", "Tip", options(profile.tipShapes.filter((s) => !isTool || s !== "stamp"), SHAPE_LABELS)),
|
|
175
208
|
...tipSliders.map((c) => slider(c)),
|
|
176
209
|
engine === "dab" && choice("tip.blend", "Blend", _chunk2VX55NFMcjs.BLEND_MODES.map((m) => ({ value: m.id, label: m.label })), "normal"),
|
|
177
210
|
...shape === "bristle" && engineOk && engineControls ? engineControls.sliders.filter((c) => c.path.startsWith("bristle.")).map((c) => slider(c)) : [],
|
|
178
|
-
shape === "stamp" && engineOk && withNote({ kind: "stamps", path: "tip.stamps", label: "Stamps", ariaLabel: "Brush stamps", value: [..._nullishCoalesce(value("tip.stamps"), () => ( []))], max: marks === "particles" ?
|
|
211
|
+
shape === "stamp" && engineOk && withNote({ kind: "stamps", path: "tip.stamps", label: "Stamps", ariaLabel: "Brush stamps", value: [..._nullishCoalesce(value("tip.stamps"), () => ( []))], max: marks === "particles" ? _chunkEU2ZZA6Lcjs.MAX_DOT_TEXTURES : _chunkEU2ZZA6Lcjs.MAX_STICKER_STAMPS, options: marks === "objects" ? STAMP_OPTIONS : [...STAMP_OPTIONS, ...sourceOptions] })
|
|
179
212
|
]);
|
|
213
|
+
const dabs = DAB_ENGINES.has(engine) && engineOk && shape !== "bristle" && marks !== "particles" && marks !== "objects";
|
|
214
|
+
const grain = brush.tip.grain;
|
|
215
|
+
if (dabs && full(_nullishCoalesce(profile.tipGrain, () => ( "none")))) {
|
|
216
|
+
add("grain", "Tip grain", [
|
|
217
|
+
choice("tip.grain.source", "Texture", [{ value: "", label: "None" }, ...options(_chunkEU2ZZA6Lcjs.TIP_GRAIN_PATTERNS), ...sourceOptions], ""),
|
|
218
|
+
!!grain && choice("tip.grain.mode", "Grain moves", options(_chunkEU2ZZA6Lcjs.BRUSH_GRAIN_MODES, GRAIN_MODE_LABELS), "texturised"),
|
|
219
|
+
!!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)) }),
|
|
220
|
+
!!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)) }),
|
|
221
|
+
!!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)) }),
|
|
222
|
+
!!grain && toggle("tip.grain.invert", "Invert grain")
|
|
223
|
+
]);
|
|
224
|
+
}
|
|
180
225
|
if (!isTool && profile.marks.length > 1 && engineOk) {
|
|
181
226
|
const particles = marks === "particles" && engineControls ? engineControls.sliders.filter((c) => c.path.startsWith("particle.") && c.path !== "particle.waveSpeed") : [];
|
|
182
227
|
const objects = marks === "objects" && engineControls ? engineControls.sliders.filter((c) => c.path.startsWith("sticker.")) : [];
|
|
183
228
|
const render = value("marks.render");
|
|
184
229
|
add("marks", "Marks", [
|
|
185
230
|
choice("marks.kind", "Laid as", options(profile.marks, MARKS_LABELS), "continuous"),
|
|
186
|
-
marks === "particles" && choice("marks.physics", "Particles", options(
|
|
187
|
-
marks === "particles" && choice("marks.render", "Drawn as", options(
|
|
188
|
-
marks === "particles" && render === "ribbon" && choice("marks.ribbonPairs", "Ribbon joins", options(
|
|
189
|
-
marks === "particles" && shape === "stamp" && choice("marks.stampOrder", "Texture order", options(
|
|
190
|
-
marks === "particles" && shape === "stamp" && choice("marks.stampRotation", "Texture turn", options(
|
|
231
|
+
marks === "particles" && choice("marks.physics", "Particles", options(_chunkEU2ZZA6Lcjs.PARTICLE_KINDS, PHYSICS_LABELS)),
|
|
232
|
+
marks === "particles" && choice("marks.render", "Drawn as", options(_chunkEU2ZZA6Lcjs.PARTICLE_RENDERS, RENDER_LABELS)),
|
|
233
|
+
marks === "particles" && render === "ribbon" && choice("marks.ribbonPairs", "Ribbon joins", options(_chunkEU2ZZA6Lcjs.RIBBON_PAIRS, { adjacent: "Neighbours", "first-last": "Outermost" })),
|
|
234
|
+
marks === "particles" && shape === "stamp" && choice("marks.stampOrder", "Texture order", options(_chunkEU2ZZA6Lcjs.DOT_TEXTURE_ORDERS, { sequence: "In turn", random: "Random" })),
|
|
235
|
+
marks === "particles" && shape === "stamp" && choice("marks.stampRotation", "Texture turn", options(_chunkEU2ZZA6Lcjs.DOT_ROTATIONS, { follow: "Follow motion", random: "Random", fixed: "Tip angle" })),
|
|
191
236
|
...particles.map((c) => slider(c)),
|
|
192
237
|
...objects.map((c) => slider(c))
|
|
193
238
|
]);
|
|
194
239
|
}
|
|
195
|
-
const feel =
|
|
240
|
+
const feel = _chunkYXP6X3SYcjs.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)));
|
|
241
|
+
const stampDabs = dabs && shape === "stamp";
|
|
242
|
+
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))) });
|
|
196
243
|
add("feel", "Feel", [
|
|
197
244
|
...feel.map((c) => slider(c)),
|
|
198
245
|
toggle("dynamics.pressureSize", "Pressure \u2192 size"),
|
|
199
246
|
toggle("dynamics.pressureOpacity", "Pressure \u2192 opacity"),
|
|
200
|
-
choice("dynamics.rotation", "Rotation", options(
|
|
247
|
+
choice("dynamics.rotation", "Rotation", options(_chunkEU2ZZA6Lcjs.BRUSH_ROTATIONS, ROTATION_LABELS)),
|
|
248
|
+
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)) }),
|
|
249
|
+
stampDabs && jitter("dynamics.scatter", "Scatter", 4),
|
|
250
|
+
stampDabs && jitter("dynamics.angleJitter", "Rotation jitter"),
|
|
251
|
+
stampDabs && jitter("dynamics.sizeJitter", "Size jitter"),
|
|
252
|
+
stampDabs && choice("dynamics.flip", "Flip", options(_chunkEU2ZZA6Lcjs.BRUSH_FLIPS, FLIP_LABELS), "none")
|
|
201
253
|
]);
|
|
202
254
|
const surfaces = profile.surfaces;
|
|
203
|
-
const engineSliders = (engineOk ? _nullishCoalesce(_optionalChain([engineControls, 'optionalAccess',
|
|
204
|
-
const exchangeOk = (path) => !_optionalChain([path, 'optionalAccess',
|
|
205
|
-
add("behaviour", _nullishCoalesce(_optionalChain([engineControls, 'optionalAccess',
|
|
255
|
+
const engineSliders = (engineOk ? _nullishCoalesce(_optionalChain([engineControls, 'optionalAccess', _14 => _14.sliders]), () => ( [])) : []).filter((c) => !/^(bristle|particle|sticker)\./.test(c.path) && c.path !== "light.amount" && c.path !== "impasto.rim" && c.path !== "impasto.clarity");
|
|
256
|
+
const exchangeOk = (path) => !_optionalChain([path, 'optionalAccess', _15 => _15.startsWith, 'call', _16 => _16("behaviour.exchange")]) || (path.startsWith("behaviour.exchange.reservoir") ? full(profile.reservoir) : exchangeFull);
|
|
257
|
+
add("behaviour", _nullishCoalesce(_optionalChain([engineControls, 'optionalAccess', _17 => _17.title]), () => ( "Behaviour")), [
|
|
206
258
|
!isTool && surfaces.length > 1 && !refused.has("behaviour.surface") && choice("behaviour.surface", "Surface", options(surfaces, SURFACE_LABELS), "dry"),
|
|
207
259
|
full(profile.grain) && slider({ path: "grain", label: "Grain", min: 0, max: 1, step: 0.01 }, "behaviour.grain"),
|
|
208
|
-
engine === "wet" && engineOk && !isTool && choice("behaviour.wet.medium", "Medium", options(
|
|
209
|
-
engine === "impasto" && engineOk && choice("behaviour.thick.applicator", "Tool", options(
|
|
260
|
+
engine === "wet" && engineOk && !isTool && choice("behaviour.wet.medium", "Medium", options(_chunkEU2ZZA6Lcjs.WET_MEDIA, WET_MEDIUM_LABELS), "watercolor"),
|
|
261
|
+
engine === "impasto" && engineOk && choice("behaviour.thick.applicator", "Tool", options(_chunkEU2ZZA6Lcjs.IMPASTO_TOOLS, APPLICATOR_LABELS), "brush"),
|
|
210
262
|
...engineSliders.map((c) => exchangeOk(facetOf(c.path)) ? slider(c) : null),
|
|
211
|
-
engineOk && _optionalChain([engineControls, 'optionalAccess',
|
|
212
|
-
engineOk && _optionalChain([engineControls, 'optionalAccess',
|
|
263
|
+
engineOk && _optionalChain([engineControls, 'optionalAccess', _18 => _18.mixingPath]) && (engine === "wet" || exchangeFull) && fieldOf("behaviour.mixing") && choice("behaviour.mixing", "Mixing", options(["pigment", "rgb"], { pigment: "Pigment", rgb: "RGB" })),
|
|
264
|
+
engineOk && _optionalChain([engineControls, 'optionalAccess', _19 => _19.dirty]) && exchangeFull && fieldOf("behaviour.exchange.dirty") && toggle("behaviour.exchange.dirty", "Dirty brush"),
|
|
213
265
|
engine === "mixer" && engineOk && full(profile.reservoir) && toggle("behaviour.exchange.reservoir.refill", "Load each stroke")
|
|
214
266
|
]);
|
|
215
|
-
if (!isTool && full(profile.light) && engineOk && _optionalChain([engineControls, 'optionalAccess',
|
|
267
|
+
if (!isTool && full(profile.light) && engineOk && _optionalChain([engineControls, 'optionalAccess', _20 => _20.light])) {
|
|
216
268
|
add("light", "Light", [
|
|
217
269
|
slider({ path: "light.amount", label: "Light", min: 0, max: 1, step: 0.01 }),
|
|
218
270
|
toggle("light.pressure", "Light follows pressure"),
|
|
219
271
|
...engine === "impasto" ? [slider({ path: "impasto.rim", label: "Rim", min: 0, max: 1, step: 0.01 }), slider({ path: "impasto.clarity", label: "Clarity", min: 0, max: 1, step: 0.01 })] : [],
|
|
220
|
-
withNote({ kind: "slider", path: "light.spill.radius", label: "Spill", ariaLabel: "Brush light spill", min: 0, max: 128, step: 1, value: _nullishCoalesce(_optionalChain([brush, 'access',
|
|
272
|
+
withNote({ kind: "slider", path: "light.spill.radius", label: "Spill", ariaLabel: "Brush light spill", min: 0, max: 128, step: 1, value: _nullishCoalesce(_optionalChain([brush, 'access', _21 => _21.light, 'optionalAccess', _22 => _22.spill, 'optionalAccess', _23 => _23.radius]), () => ( 24)) }),
|
|
221
273
|
toggle("light.glow", "Suggest a glow")
|
|
222
274
|
]);
|
|
223
275
|
}
|
|
224
276
|
if (full(profile.motion) && engineOk && marks === "particles") add("motion", "Motion", [slider({ path: "particle.waveSpeed", label: "Wave speed", min: 0, max: 1, step: 0.01 })]);
|
|
225
277
|
if (!isTool) {
|
|
226
|
-
const own = _optionalChain([brush, 'access',
|
|
278
|
+
const own = _optionalChain([brush, 'access', _24 => _24.colour, 'optionalAccess', _25 => _25.default]);
|
|
227
279
|
const hex = (c) => typeof c === "string" ? _nullishCoalesce(_chunkJBZRVLXVcjs.brushColourHex.call(void 0, c, "light"), () => ( null)) : null;
|
|
228
280
|
const pair = _chunkMLLTWAXHcjs.isDualColor.call(void 0, own) ? own : null;
|
|
229
281
|
add("colour", "Colour", [
|
|
@@ -233,8 +285,8 @@ function brushEditorSections(brush, profile = _chunkXVOP3CGQcjs.PAINT_PROFILE) {
|
|
|
233
285
|
path: "colour.palette",
|
|
234
286
|
label: "Palette",
|
|
235
287
|
ariaLabel: "Brush palette",
|
|
236
|
-
value: (_nullishCoalesce(_optionalChain([brush, 'access',
|
|
237
|
-
max:
|
|
288
|
+
value: (_nullishCoalesce(_optionalChain([brush, 'access', _26 => _26.colour, 'optionalAccess', _27 => _27.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)] : []),
|
|
289
|
+
max: _chunkEU2ZZA6Lcjs.MAX_BRUSH_PALETTE
|
|
238
290
|
}),
|
|
239
291
|
toggle("colour.own", "Always its own colour")
|
|
240
292
|
]);
|
|
@@ -250,15 +302,19 @@ function hiddenLabel(issue, b) {
|
|
|
250
302
|
case "tip.shape":
|
|
251
303
|
return `a ${b.tip.shape} tip`;
|
|
252
304
|
case "marks":
|
|
253
|
-
return _nullishCoalesce(MARKS_WORDS[_nullishCoalesce(_optionalChain([b, 'access',
|
|
305
|
+
return _nullishCoalesce(MARKS_WORDS[_nullishCoalesce(_optionalChain([b, 'access', _28 => _28.marks, 'optionalAccess', _29 => _29.kind]), () => ( "continuous"))], () => ( "its marks"));
|
|
254
306
|
case "behaviour.surface":
|
|
255
|
-
return `${_nullishCoalesce(_optionalChain([b, 'access',
|
|
307
|
+
return `${_nullishCoalesce(_optionalChain([b, 'access', _30 => _30.behaviour, 'optionalAccess', _31 => _31.surface]), () => ( "dry"))} behaviour`;
|
|
256
308
|
case "behaviour.exchange.reservoir":
|
|
257
309
|
return "a Mixer Brush reservoir";
|
|
258
310
|
case "behaviour.exchange":
|
|
259
311
|
return "paint pick-up";
|
|
260
312
|
case "behaviour.grain":
|
|
261
313
|
return "paper grain";
|
|
314
|
+
case "tip.grain":
|
|
315
|
+
return "tip grain";
|
|
316
|
+
case "dynamics.count":
|
|
317
|
+
return "several dabs per step";
|
|
262
318
|
case "light":
|
|
263
319
|
return "light";
|
|
264
320
|
case "motion":
|
|
@@ -268,15 +324,15 @@ function hiddenLabel(issue, b) {
|
|
|
268
324
|
case "dynamics.tilt":
|
|
269
325
|
return "tilt dynamics";
|
|
270
326
|
case "colour.default":
|
|
271
|
-
return `a ${
|
|
327
|
+
return `a ${_chunkEU2ZZA6Lcjs.brushColourKind.call(void 0, b.colour.default)} default colour`;
|
|
272
328
|
default:
|
|
273
329
|
return null;
|
|
274
330
|
}
|
|
275
331
|
}
|
|
276
332
|
var sentence = (words) => words.length < 2 ? _nullishCoalesce(words[0], () => ( "")) : `${words.slice(0, -1).join(", ")} and ${words.at(-1)}`;
|
|
277
|
-
function brushEditorScope(brush, profile =
|
|
333
|
+
function brushEditorScope(brush, profile = _chunkEU2ZZA6Lcjs.PAINT_PROFILE) {
|
|
278
334
|
const hidden = [];
|
|
279
|
-
for (const issue of
|
|
335
|
+
for (const issue of _chunkEU2ZZA6Lcjs.checkBrush.call(void 0, brush, profile).issues) {
|
|
280
336
|
const label = hiddenLabel(issue, brush);
|
|
281
337
|
if (label && !hidden.some((h) => h.label === label)) hidden.push({ facet: issue.facet, label });
|
|
282
338
|
}
|
|
@@ -289,17 +345,17 @@ function newBrushFor(profile, from, name = "New brush") {
|
|
|
289
345
|
const id = brushIdFromName(name);
|
|
290
346
|
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] } };
|
|
291
347
|
if (from) {
|
|
292
|
-
const stripped =
|
|
348
|
+
const stripped = _chunkEU2ZZA6Lcjs.degrade.call(void 0, from, profile, { ignored: true });
|
|
293
349
|
if (!stripped.issues.length) return { ...stripped.brush, id, name };
|
|
294
350
|
}
|
|
295
351
|
return base;
|
|
296
352
|
}
|
|
297
353
|
async function saveBrushEdit(library, options2) {
|
|
298
354
|
const { original, profile } = options2;
|
|
299
|
-
const check =
|
|
355
|
+
const check = _chunkEU2ZZA6Lcjs.checkBrushEdit.call(void 0, original, options2.brush, profile);
|
|
300
356
|
if (!check.ok) {
|
|
301
357
|
const errors = check.issues.filter((i) => i.severity === "error").map((i) => `${i.facet}: ${i.reason} ${i.fix}`);
|
|
302
|
-
throw new (0,
|
|
358
|
+
throw new (0, _chunkEU2ZZA6Lcjs.BrushLibraryError)("invalid", `${profile.name} can't use this brush: ${errors.join(" ")} Nothing was saved.`);
|
|
303
359
|
}
|
|
304
360
|
const inPlace = !!original && options2.name === void 0 && !library.isBuiltin(original.id) && original.id === options2.brush.id && !!await library.get(original.id);
|
|
305
361
|
let brush = options2.brush;
|
|
@@ -330,18 +386,20 @@ function setBrushEditorValue(brush, path, value) {
|
|
|
330
386
|
next.marks = value === "continuous" ? void 0 : { kind: value };
|
|
331
387
|
if (value !== "continuous" && next.tip.shape === "bristle") next.tip = { ...next.tip, shape: "round", bristle: void 0 };
|
|
332
388
|
if (value === "objects") next.tip = { ...next.tip, shape: "stamp" };
|
|
389
|
+
} else if (path === "tip.grain.source" && (value === void 0 || value === "")) {
|
|
390
|
+
delete next.tip.grain;
|
|
333
391
|
} else if (path === "tip.shape" && value !== "stamp") {
|
|
334
392
|
next.tip = { ...next.tip, shape: value, stamps: void 0 };
|
|
335
393
|
if (value !== "bristle") delete next.tip.bristle;
|
|
336
394
|
} else if (value === void 0 || value === "") {
|
|
337
395
|
const keys = path.split(".");
|
|
338
|
-
const parent =
|
|
396
|
+
const parent = _chunkEU2ZZA6Lcjs.getPath.call(void 0, next, keys.slice(0, -1).join("."));
|
|
339
397
|
if (keys.length === 1) delete next[keys[0]];
|
|
340
398
|
else if (parent) delete parent[keys[keys.length - 1]];
|
|
341
|
-
} else
|
|
399
|
+
} else _chunkEU2ZZA6Lcjs.setPath.call(void 0, next, path, value);
|
|
342
400
|
const problems = [];
|
|
343
401
|
try {
|
|
344
|
-
return { brush:
|
|
402
|
+
return { brush: _chunkEU2ZZA6Lcjs.normalizeBrushSpec.call(void 0, JSON.parse(JSON.stringify(next)), problems), problems };
|
|
345
403
|
} catch (e) {
|
|
346
404
|
return { brush, problems: [e.message] };
|
|
347
405
|
}
|
|
@@ -357,7 +415,7 @@ function brushLibraryGroups(entries, filter = {}) {
|
|
|
357
415
|
const text = words([b.id, b.name, _nullishCoalesce(b.variety, () => ( "")), _nullishCoalesce(b.medium, () => ( "")), _nullishCoalesce(b.tool, () => ( "")), ..._nullishCoalesce(b.tags, () => ( []))].join(" "));
|
|
358
416
|
if (!wanted.every((w) => text.some((t) => t.startsWith(w)))) continue;
|
|
359
417
|
}
|
|
360
|
-
if (filter.profile && !
|
|
418
|
+
if (filter.profile && !_chunkEU2ZZA6Lcjs.checkBrush.call(void 0, b, filter.profile).ok) continue;
|
|
361
419
|
const id = b.kind === "tool" ? "tools" : _nullishCoalesce(b.medium, () => ( "other"));
|
|
362
420
|
let g = groups.get(id);
|
|
363
421
|
if (!g) groups.set(id, g = { id, title: id === "tools" ? "Tools" : id === "other" ? "Other" : MEDIUM_LABELS[id], varieties: [] });
|
|
@@ -369,6 +427,28 @@ function brushLibraryGroups(entries, filter = {}) {
|
|
|
369
427
|
const order = ["dry", "ink", "paint", "spray", "other", "tools"];
|
|
370
428
|
return [...groups.values()].sort((a, b) => order.indexOf(a.id) - order.indexOf(b.id));
|
|
371
429
|
}
|
|
430
|
+
async function imageFileToPngDataUrl(file) {
|
|
431
|
+
const bytes = new Uint8Array(await file.arrayBuffer());
|
|
432
|
+
if (_chunkW5M3J7PVcjs.isPng.call(void 0, bytes)) return `data:image/png;base64,${_chunkW5M3J7PVcjs.bytesToBase64.call(void 0, bytes)}`;
|
|
433
|
+
const g = globalThis;
|
|
434
|
+
if (!g.createImageBitmap || !g.OffscreenCanvas) throw new (0, _chunkEU2ZZA6Lcjs.BrushSourceError)("Only PNG images can be read here; convert the image to PNG.");
|
|
435
|
+
const bitmap = await g.createImageBitmap(file);
|
|
436
|
+
const canvas = new g.OffscreenCanvas(bitmap.width, bitmap.height);
|
|
437
|
+
canvas.getContext("2d").drawImage(bitmap, 0, 0);
|
|
438
|
+
const png = new Uint8Array(await (await canvas.convertToBlob({ type: "image/png" })).arrayBuffer());
|
|
439
|
+
return `data:image/png;base64,${_chunkW5M3J7PVcjs.bytesToBase64.call(void 0, png)}`;
|
|
440
|
+
}
|
|
441
|
+
async function addBrushSourceFromFile(library, file, options2 = {}) {
|
|
442
|
+
const name = (_nullishCoalesce(_nullishCoalesce(options2.name, () => ( _optionalChain([file, 'access', _32 => _32.name, 'optionalAccess', _33 => _33.replace, 'call', _34 => _34(/\.[a-z0-9]+$/i, "")]))), () => ( "Image"))).trim() || "Image";
|
|
443
|
+
const result = await library.addSource({ name, image: await imageFileToPngDataUrl(file), origin: file.name, ...options2.channel ? { channel: options2.channel } : {} });
|
|
444
|
+
return { ...result, ref: _chunkEU2ZZA6Lcjs.brushSourceRef.call(void 0, result.source.id) };
|
|
445
|
+
}
|
|
446
|
+
function withBrushSource(brush, ref, as) {
|
|
447
|
+
if (as === "grain") return setBrushEditorValue(brush, "tip.grain.source", ref);
|
|
448
|
+
const stamp = brush.tip.shape === "stamp" ? { brush, problems: [] } : setBrushEditorValue(brush, "tip.shape", "stamp");
|
|
449
|
+
const r = setBrushEditorValue(stamp.brush, "tip.stamps", [ref]);
|
|
450
|
+
return { brush: r.brush, problems: [...stamp.problems, ...r.problems] };
|
|
451
|
+
}
|
|
372
452
|
|
|
373
453
|
// src/brushes/contract.ts
|
|
374
454
|
var BRUSH_CONTRACT_FORMAT_VERSION = 1;
|
|
@@ -379,11 +459,11 @@ var BRUSH_PROFILE_JSON_SCHEMA = {
|
|
|
379
459
|
properties: {
|
|
380
460
|
id: { type: "string", description: "paint, image, canvas, vector\u2026" },
|
|
381
461
|
name: { type: "string", description: "Display name, used in messages." },
|
|
382
|
-
kinds: { type: "array", items: { type: "string", enum: [...
|
|
383
|
-
tools: { type: "array", items: { type: "string", enum: [...
|
|
384
|
-
tipShapes: { type: "array", items: { type: "string", enum: [...
|
|
385
|
-
marks: { type: "array", items: { type: "string", enum: [...
|
|
386
|
-
surfaces: { type: "array", items: { type: "string", enum: [...
|
|
462
|
+
kinds: { type: "array", items: { type: "string", enum: [..._chunkEU2ZZA6Lcjs.BRUSH_KINDS] }, description: "Brush kinds it has." },
|
|
463
|
+
tools: { type: "array", items: { type: "string", enum: [..._chunkEU2ZZA6Lcjs.BRUSH_TOOLS] }, description: "Tools it has (kind tool)." },
|
|
464
|
+
tipShapes: { type: "array", items: { type: "string", enum: [..._chunkEU2ZZA6Lcjs.BRUSH_TIP_SHAPES] }, description: "Tip shapes it renders." },
|
|
465
|
+
marks: { type: "array", items: { type: "string", enum: [..._chunkEU2ZZA6Lcjs.BRUSH_MARKS_KINDS] }, description: "Marks kinds it renders." },
|
|
466
|
+
surfaces: { type: "array", items: { type: "string", enum: [..._chunkEU2ZZA6Lcjs.BRUSH_SURFACES] }, description: "Surfaces it renders." },
|
|
387
467
|
exchange: { ...SUPPORT, description: "Picking paint up and mixing it in." },
|
|
388
468
|
reservoir: { ...SUPPORT, description: "The Mixer Brush reservoir." },
|
|
389
469
|
grain: { ...SUPPORT, description: "Paper grain response." },
|
|
@@ -391,7 +471,9 @@ var BRUSH_PROFILE_JSON_SCHEMA = {
|
|
|
391
471
|
motion: { ...SUPPORT, description: "Motion after painting." },
|
|
392
472
|
colours: { type: "array", items: { type: "string", enum: ["solid", "dual", "gradient", "effect"] }, description: "Colour kinds a default colour may be." },
|
|
393
473
|
velocity: { ...SUPPORT, description: "Velocity dynamics." },
|
|
394
|
-
tilt: { ...SUPPORT, description: "Tilt dynamics." }
|
|
474
|
+
tilt: { ...SUPPORT, description: "Tilt dynamics." },
|
|
475
|
+
tipGrain: { ...SUPPORT, description: "Texture inside the tip (tip.grain); missing: none." },
|
|
476
|
+
dabCount: { ...SUPPORT, description: "Several dabs per spacing step (dynamics.count); missing: none." }
|
|
395
477
|
},
|
|
396
478
|
required: ["id", "name", "kinds", "tools", "tipShapes", "marks", "surfaces", "exchange", "reservoir", "grain", "light", "motion", "colours", "velocity", "tilt"],
|
|
397
479
|
additionalProperties: false
|
|
@@ -402,13 +484,33 @@ var BRUSH_LIBRARY_FILE_JSON_SCHEMA = {
|
|
|
402
484
|
properties: {
|
|
403
485
|
format: { type: "string", const: "pixerate-brushes", description: 'Always "pixerate-brushes".' },
|
|
404
486
|
version: { type: "integer", const: 2, description: "Always 2." },
|
|
405
|
-
brushes: { type: "array", items: { $ref: "brush.schema.json" }, description: "The brushes, each a facet brush (brush.schema.json)." }
|
|
487
|
+
brushes: { type: "array", items: { $ref: "brush.schema.json" }, description: "The brushes, each a facet brush (brush.schema.json)." },
|
|
488
|
+
sources: {
|
|
489
|
+
type: "array",
|
|
490
|
+
maxItems: _chunkEU2ZZA6Lcjs.MAX_BRUSH_SOURCES,
|
|
491
|
+
description: "The image sources the brushes name (source:<id> in tip.stamps or tip.grain.source), bytes included.",
|
|
492
|
+
items: {
|
|
493
|
+
type: "object",
|
|
494
|
+
description: "An image source: a grey mask, 255 paints (or is a grain peak).",
|
|
495
|
+
properties: {
|
|
496
|
+
id: { type: "string", pattern: _chunkEU2ZZA6Lcjs.BRUSH_ID.source, description: "Source id." },
|
|
497
|
+
name: { type: "string", maxLength: 80, description: "Display name." },
|
|
498
|
+
width: { type: "integer", minimum: 1, maximum: _chunkEU2ZZA6Lcjs.MAX_BRUSH_SOURCE_SIZE, description: "Width in px." },
|
|
499
|
+
height: { type: "integer", minimum: 1, maximum: _chunkEU2ZZA6Lcjs.MAX_BRUSH_SOURCE_SIZE, description: "Height in px." },
|
|
500
|
+
image: { type: "string", pattern: "^data:image/png;base64,", description: "The mask as a greyscale PNG data: URL." },
|
|
501
|
+
licence: { type: "string", maxLength: 2e3, description: "The licence or terms it came with." },
|
|
502
|
+
origin: { type: "string", maxLength: 200, description: "Where it came from (a file or pack name)." }
|
|
503
|
+
},
|
|
504
|
+
required: ["id", "name", "width", "height", "image"],
|
|
505
|
+
additionalProperties: false
|
|
506
|
+
}
|
|
507
|
+
}
|
|
406
508
|
},
|
|
407
509
|
required: ["format", "version", "brushes"],
|
|
408
510
|
additionalProperties: false
|
|
409
511
|
};
|
|
410
512
|
function migrationInputs() {
|
|
411
|
-
const pick = (id) =>
|
|
513
|
+
const pick = (id) => _chunkEU2ZZA6Lcjs.brushToJSON.call(void 0, _chunkEU2ZZA6Lcjs.BUILTIN_BRUSHES.find((b) => b.id === id));
|
|
412
514
|
return [
|
|
413
515
|
{ id: "plain", name: "Plain" },
|
|
414
516
|
pick("pencil-6b"),
|
|
@@ -430,34 +532,34 @@ function migrationInputs() {
|
|
|
430
532
|
function editorSectionFixtures() {
|
|
431
533
|
const ids = ["highlighter", "chalk", "watercolor-wash", "hair-strands", "mixer-brush", "blender", "spray-can"];
|
|
432
534
|
return ids.flatMap(
|
|
433
|
-
(id) => Object.keys(
|
|
434
|
-
const brush =
|
|
435
|
-
return { brush: id, host, sections: brushEditorSections(brush,
|
|
535
|
+
(id) => Object.keys(_chunkEU2ZZA6Lcjs.BRUSH_HOST_PROFILES).map((host) => {
|
|
536
|
+
const brush = _chunkEU2ZZA6Lcjs.BRUSH_PRESETS.find((b) => b.id === id);
|
|
537
|
+
return { brush: id, host, sections: brushEditorSections(brush, _chunkEU2ZZA6Lcjs.BRUSH_HOST_PROFILES[host]) };
|
|
436
538
|
})
|
|
437
539
|
);
|
|
438
540
|
}
|
|
439
541
|
function toolDefinitions() {
|
|
440
|
-
const library =
|
|
441
|
-
const toolsFor = (host) =>
|
|
542
|
+
const library = _chunkEU2ZZA6Lcjs.createBrushLibrary.call(void 0, );
|
|
543
|
+
const toolsFor = (host) => _chunkYXP6X3SYcjs.createBrushLibraryTools.call(void 0, library, { profile: _chunkEU2ZZA6Lcjs.BRUSH_HOST_PROFILES[host], renderPreview: () => ({ data: "", mimeType: "image/png" }) });
|
|
442
544
|
return {
|
|
443
545
|
tools: toolsFor("paint").map((t) => ({ name: t.name, title: t.title, description: t.description, inputSchema: t.inputSchema, annotations: t.annotations })),
|
|
444
|
-
hosts: Object.fromEntries(Object.keys(
|
|
546
|
+
hosts: Object.fromEntries(Object.keys(_chunkEU2ZZA6Lcjs.BRUSH_HOST_PROFILES).map((host) => [host, toolsFor(host).map((t) => t.name)]))
|
|
445
547
|
};
|
|
446
548
|
}
|
|
447
549
|
function brushContracts() {
|
|
448
|
-
const presets =
|
|
449
|
-
const resolved =
|
|
450
|
-
const profiles = Object.values(
|
|
451
|
-
const checks =
|
|
550
|
+
const presets = _chunkEU2ZZA6Lcjs.BRUSH_PRESETS.map((b) => JSON.parse(JSON.stringify(b)));
|
|
551
|
+
const resolved = _chunkEU2ZZA6Lcjs.BRUSH_PRESETS.map((b) => ({ id: b.id, engine: _chunkEU2ZZA6Lcjs.resolveEngine.call(void 0, b), category: _chunkEU2ZZA6Lcjs.resolveCategory.call(void 0, b), brush: _chunkEU2ZZA6Lcjs.brushToJSON.call(void 0, _chunkEU2ZZA6Lcjs.resolveBrush.call(void 0, b)) }));
|
|
552
|
+
const profiles = Object.values(_chunkEU2ZZA6Lcjs.BRUSH_HOST_PROFILES);
|
|
553
|
+
const checks = _chunkEU2ZZA6Lcjs.BRUSH_PRESETS.map((b) => ({
|
|
452
554
|
id: b.id,
|
|
453
555
|
hosts: Object.fromEntries(profiles.map((p) => {
|
|
454
|
-
const c =
|
|
556
|
+
const c = _chunkEU2ZZA6Lcjs.checkBrush.call(void 0, b, p);
|
|
455
557
|
return [p.id, { ok: c.ok, issues: c.issues.map(({ facet, severity }) => ({ facet, severity })) }];
|
|
456
558
|
}))
|
|
457
559
|
}));
|
|
458
|
-
const migrations = migrationInputs().map((input) => ({ input, output:
|
|
560
|
+
const migrations = migrationInputs().map((input) => ({ input, output: _chunkEU2ZZA6Lcjs.migrateBrushV1.call(void 0, input), resolved: _chunkEU2ZZA6Lcjs.brushToJSON.call(void 0, _chunkEU2ZZA6Lcjs.resolveBrush.call(void 0, _chunkEU2ZZA6Lcjs.migrateBrushV1.call(void 0, input))), engine: _chunkEU2ZZA6Lcjs.normalizePaintBrush.call(void 0, input).engine }));
|
|
459
561
|
const files = {
|
|
460
|
-
"brush.schema.json": { $schema: "https://json-schema.org/draft/2020-12/schema", $id: "brush.schema.json", ...
|
|
562
|
+
"brush.schema.json": { $schema: "https://json-schema.org/draft/2020-12/schema", $id: "brush.schema.json", ..._chunkEU2ZZA6Lcjs.BRUSH_JSON_SCHEMA },
|
|
461
563
|
"profile.schema.json": { $schema: "https://json-schema.org/draft/2020-12/schema", $id: "profile.schema.json", ...BRUSH_PROFILE_JSON_SCHEMA },
|
|
462
564
|
"library-file.schema.json": { $schema: "https://json-schema.org/draft/2020-12/schema", $id: "library-file.schema.json", ...BRUSH_LIBRARY_FILE_JSON_SCHEMA },
|
|
463
565
|
"presets.json": presets,
|
|
@@ -471,7 +573,7 @@ function brushContracts() {
|
|
|
471
573
|
files["manifest.json"] = {
|
|
472
574
|
domain: "brushes",
|
|
473
575
|
formatVersion: BRUSH_CONTRACT_FORMAT_VERSION,
|
|
474
|
-
limits: { maxPalette:
|
|
576
|
+
limits: { maxPalette: _chunkEU2ZZA6Lcjs.MAX_BRUSH_PALETTE },
|
|
475
577
|
counts: { presets: presets.length, profiles: profiles.length, migrations: migrations.length, editorSections: files["editor-sections.json"].length },
|
|
476
578
|
files: Object.keys(files).sort()
|
|
477
579
|
};
|
|
@@ -537,4 +639,28 @@ function brushContracts() {
|
|
|
537
639
|
|
|
538
640
|
|
|
539
641
|
|
|
540
|
-
|
|
642
|
+
|
|
643
|
+
|
|
644
|
+
|
|
645
|
+
|
|
646
|
+
|
|
647
|
+
|
|
648
|
+
|
|
649
|
+
|
|
650
|
+
|
|
651
|
+
|
|
652
|
+
|
|
653
|
+
|
|
654
|
+
|
|
655
|
+
|
|
656
|
+
|
|
657
|
+
|
|
658
|
+
|
|
659
|
+
|
|
660
|
+
|
|
661
|
+
|
|
662
|
+
|
|
663
|
+
|
|
664
|
+
|
|
665
|
+
|
|
666
|
+
exports.BRUSH_CONTRACT_FORMAT_VERSION = BRUSH_CONTRACT_FORMAT_VERSION; exports.BRUSH_FACET_SCHEMAS = _chunkEU2ZZA6Lcjs.BRUSH_FACET_SCHEMAS; exports.BRUSH_FLIPS = _chunkEU2ZZA6Lcjs.BRUSH_FLIPS; exports.BRUSH_GRAIN_MODES = _chunkEU2ZZA6Lcjs.BRUSH_GRAIN_MODES; exports.BRUSH_GRAIN_SOURCE_PATTERN = _chunkEU2ZZA6Lcjs.BRUSH_GRAIN_SOURCE_PATTERN; exports.BRUSH_HOST_PROFILES = _chunkEU2ZZA6Lcjs.BRUSH_HOST_PROFILES; exports.BRUSH_JSON_SCHEMA = _chunkEU2ZZA6Lcjs.BRUSH_JSON_SCHEMA; exports.BRUSH_KINDS = _chunkEU2ZZA6Lcjs.BRUSH_KINDS; exports.BRUSH_LIBRARY_FILE_JSON_SCHEMA = BRUSH_LIBRARY_FILE_JSON_SCHEMA; exports.BRUSH_MARKS_KINDS = _chunkEU2ZZA6Lcjs.BRUSH_MARKS_KINDS; exports.BRUSH_MEDIA = _chunkEU2ZZA6Lcjs.BRUSH_MEDIA; exports.BRUSH_PATCH_PROPERTIES = _chunkYXP6X3SYcjs.BRUSH_PATCH_PROPERTIES; exports.BRUSH_PRESETS = _chunkEU2ZZA6Lcjs.BRUSH_PRESETS; exports.BRUSH_PREVIEW_DARK_PAPER = _chunkBPJSI4NTcjs.BRUSH_PREVIEW_DARK_PAPER; exports.BRUSH_PREVIEW_FALLBACKS = _chunkBPJSI4NTcjs.BRUSH_PREVIEW_FALLBACKS; exports.BRUSH_PREVIEW_MIN_CONTRAST = _chunkBPJSI4NTcjs.BRUSH_PREVIEW_MIN_CONTRAST; exports.BRUSH_PROFILE_JSON_SCHEMA = BRUSH_PROFILE_JSON_SCHEMA; exports.BRUSH_SOURCE_CHANNELS = _chunkEU2ZZA6Lcjs.BRUSH_SOURCE_CHANNELS; exports.BRUSH_SOURCE_PROVIDER = _chunkEU2ZZA6Lcjs.BRUSH_SOURCE_PROVIDER; exports.BRUSH_SURFACES = _chunkEU2ZZA6Lcjs.BRUSH_SURFACES; exports.BRUSH_TIP_SHAPES = _chunkEU2ZZA6Lcjs.BRUSH_TIP_SHAPES; exports.BRUSH_TOOLS = _chunkEU2ZZA6Lcjs.BRUSH_TOOLS; exports.BRUSH_UNSET_PROPERTY = _chunkYXP6X3SYcjs.BRUSH_UNSET_PROPERTY; exports.BRUSH_WORD = _chunkEU2ZZA6Lcjs.BRUSH_WORD; exports.BrushLibraryError = _chunkEU2ZZA6Lcjs.BrushLibraryError; exports.BrushSourceError = _chunkEU2ZZA6Lcjs.BrushSourceError; exports.CANVAS_PROFILE = _chunkEU2ZZA6Lcjs.CANVAS_PROFILE; exports.IMAGE_PROFILE = _chunkEU2ZZA6Lcjs.IMAGE_PROFILE; exports.MAX_BRUSH_PALETTE = _chunkEU2ZZA6Lcjs.MAX_BRUSH_PALETTE; exports.MAX_BRUSH_SOURCES = _chunkEU2ZZA6Lcjs.MAX_BRUSH_SOURCES; exports.MAX_BRUSH_SOURCE_INPUT_PIXELS = _chunkEU2ZZA6Lcjs.MAX_BRUSH_SOURCE_INPUT_PIXELS; exports.MAX_BRUSH_SOURCE_SIZE = _chunkEU2ZZA6Lcjs.MAX_BRUSH_SOURCE_SIZE; exports.PAINT_PROFILE = _chunkEU2ZZA6Lcjs.PAINT_PROFILE; exports.TIP_GRAIN_PATTERNS = _chunkEU2ZZA6Lcjs.TIP_GRAIN_PATTERNS; exports.UNSETTABLE_BRUSH_FACETS = _chunkYXP6X3SYcjs.UNSETTABLE_BRUSH_FACETS; exports.VECTOR_PROFILE = _chunkEU2ZZA6Lcjs.VECTOR_PROFILE; exports.WET_BRUSH_TOOLS = _chunkEU2ZZA6Lcjs.WET_BRUSH_TOOLS; exports.addBrushSourceFromFile = addBrushSourceFromFile; exports.brushColourHex = _chunkJBZRVLXVcjs.brushColourHex; exports.brushColourKind = _chunkEU2ZZA6Lcjs.brushColourKind; exports.brushContracts = brushContracts; exports.brushEditorScope = brushEditorScope; exports.brushEditorSections = brushEditorSections; exports.brushIdFromName = brushIdFromName; exports.brushLibraryGroups = brushLibraryGroups; exports.brushPreviewColours = _chunkBPJSI4NTcjs.brushPreviewColours; exports.brushPreviewStrength = _chunkBPJSI4NTcjs.brushPreviewStrength; exports.brushPreviewsOnDark = _chunkBPJSI4NTcjs.brushPreviewsOnDark; exports.brushSourceFromMask = _chunkEU2ZZA6Lcjs.brushSourceFromMask; exports.brushSourceIdFromName = _chunkEU2ZZA6Lcjs.brushSourceIdFromName; exports.brushSourceIdOf = _chunkEU2ZZA6Lcjs.brushSourceIdOf; exports.brushSourceIds = _chunkEU2ZZA6Lcjs.brushSourceIds; exports.brushSourceRef = _chunkEU2ZZA6Lcjs.brushSourceRef; exports.changedBrushPaths = _chunkYXP6X3SYcjs.changedBrushPaths; exports.checkBrush = _chunkEU2ZZA6Lcjs.checkBrush; exports.checkBrushEdit = _chunkEU2ZZA6Lcjs.checkBrushEdit; exports.createBrushLibrary = _chunkEU2ZZA6Lcjs.createBrushLibrary; exports.createBrushLibraryToolProvider = _chunkYXP6X3SYcjs.createBrushLibraryToolProvider; exports.createBrushLibraryTools = _chunkYXP6X3SYcjs.createBrushLibraryTools; exports.decodeBrushSource = _chunkEU2ZZA6Lcjs.decodeBrushSource; exports.degrade = _chunkEU2ZZA6Lcjs.degrade; exports.imageFileToPngDataUrl = imageFileToPngDataUrl; exports.isBrushLibrary = _chunkEU2ZZA6Lcjs.isBrushLibrary; exports.isBrushSourceRef = _chunkEU2ZZA6Lcjs.isBrushSourceRef; exports.listPresets = _chunkEU2ZZA6Lcjs.listPresets; exports.makeBrushSource = _chunkEU2ZZA6Lcjs.makeBrushSource; exports.mergeBrushPatch = _chunkYXP6X3SYcjs.mergeBrushPatch; exports.migrateBrushV1 = _chunkEU2ZZA6Lcjs.migrateBrushV1; exports.newBrushFor = newBrushFor; exports.normalizeBrushSpec = _chunkEU2ZZA6Lcjs.normalizeBrushSpec; exports.parseBrushLibrary = _chunkEU2ZZA6Lcjs.parseBrushLibrary2; exports.parseBrushLibrarySources = _chunkEU2ZZA6Lcjs.parseBrushLibrarySources; exports.readBrushSource = _chunkEU2ZZA6Lcjs.readBrushSource; exports.resolveBrush = _chunkEU2ZZA6Lcjs.resolveBrush; exports.resolveCategory = _chunkEU2ZZA6Lcjs.resolveCategory; exports.resolveEngine = _chunkEU2ZZA6Lcjs.resolveEngine; exports.resolveWetMedium = _chunkEU2ZZA6Lcjs.resolveWetMedium; exports.saveBrushEdit = saveBrushEdit; exports.setBrushEditorValue = setBrushEditorValue; exports.snapshotBrushLibrary = _chunkEU2ZZA6Lcjs.snapshotBrushLibrary; exports.summarizeBrushSource = _chunkEU2ZZA6Lcjs.summarizeBrushSource; exports.withBrushSource = withBrushSource; exports.withKeptIssues = _chunkEU2ZZA6Lcjs.withKeptIssues;
|
package/dist/brushes/index.d.cts
CHANGED
|
@@ -9,7 +9,8 @@
|
|
|
9
9
|
* renderer is bundled.
|
|
10
10
|
*/
|
|
11
11
|
export * from './types.cjs';
|
|
12
|
-
export { BRUSH_FACET_SCHEMAS, BRUSH_JSON_SCHEMA, BRUSH_WORD, MAX_BRUSH_PALETTE } from './schema.cjs';
|
|
12
|
+
export { BRUSH_FACET_SCHEMAS, BRUSH_GRAIN_SOURCE_PATTERN, BRUSH_JSON_SCHEMA, BRUSH_WORD, MAX_BRUSH_PALETTE, TIP_GRAIN_PATTERNS } from './schema.cjs';
|
|
13
|
+
export { BRUSH_SOURCE_CHANNELS, BRUSH_SOURCE_PROVIDER, brushSourceFromMask, brushSourceIdFromName, brushSourceIdOf, brushSourceIds, brushSourceRef, BrushSourceError, decodeBrushSource, isBrushSourceRef, makeBrushSource, MAX_BRUSH_SOURCE_INPUT_PIXELS, MAX_BRUSH_SOURCE_SIZE, MAX_BRUSH_SOURCES, readBrushSource, summarizeBrushSource, type BrushSource, type BrushSourceChannel, type BrushSourceInput, type BrushSourceSummary, type DecodedBrushSource, } from './sources.cjs';
|
|
13
14
|
export { normalizeBrushSpec, WET_BRUSH_TOOLS } from './normalize.cjs';
|
|
14
15
|
export { resolveBrush, resolveCategory, resolveEngine, resolveWetMedium, type ResolveBrushOptions } from './resolve.cjs';
|
|
15
16
|
export { migrateBrushV1 } from './migrate.cjs';
|
|
@@ -18,7 +19,7 @@ export { brushColourHex } from './colour.cjs';
|
|
|
18
19
|
export { BRUSH_PREVIEW_DARK_PAPER, BRUSH_PREVIEW_FALLBACKS, BRUSH_PREVIEW_MIN_CONTRAST, brushPreviewColours, brushPreviewsOnDark, brushPreviewStrength, type BrushPreviewColours, type BrushPreviewColoursOptions } from './preview.cjs';
|
|
19
20
|
export { BRUSH_CONTRACT_FORMAT_VERSION, BRUSH_LIBRARY_FILE_JSON_SCHEMA, BRUSH_PROFILE_JSON_SCHEMA, brushContracts } from './contract.cjs';
|
|
20
21
|
export { BRUSH_HOST_PROFILES, brushColourKind, CANVAS_PROFILE, checkBrush, checkBrushEdit, degrade, withKeptIssues, IMAGE_PROFILE, listPresets, PAINT_PROFILE, VECTOR_PROFILE, type BrushCheck, type BrushEditCheck, type BrushColourKind, type BrushHostProfile, type BrushIssue, type BrushSupport, type DegradedBrush } from './profiles.cjs';
|
|
21
|
-
export { BrushLibraryError, createBrushLibrary, isBrushLibrary, parseBrushLibrary, snapshotBrushLibrary, type BrushFilter, type BrushLibrary, type BrushLibraryEntry, type BrushLibraryErrorCode, type BrushLibraryFile, type BrushLibrarySnapshot, type BrushLibraryOptions, type ImportBrushesResult, type SaveBrushResult, } from './library.cjs';
|
|
22
|
+
export { BrushLibraryError, createBrushLibrary, isBrushLibrary, parseBrushLibrary, parseBrushLibrarySources, type AddBrushSourceResult, snapshotBrushLibrary, type BrushFilter, type BrushLibrary, type BrushLibraryEntry, type BrushLibraryErrorCode, type BrushLibraryFile, type BrushLibrarySnapshot, type BrushLibraryOptions, type ImportBrushesResult, type SaveBrushResult, } from './library.cjs';
|
|
22
23
|
export { BRUSH_PATCH_PROPERTIES, BRUSH_UNSET_PROPERTY, changedBrushPaths, mergeBrushPatch, UNSETTABLE_BRUSH_FACETS, type BrushPatch, type UnsettableBrushFacet } from './patch.cjs';
|
|
23
|
-
export { brushEditorScope, brushEditorSections, brushIdFromName, brushLibraryGroups, newBrushFor, saveBrushEdit, setBrushEditorValue, type BrushEditorHiddenFacet, type BrushEditorScope, type SaveBrushEditOptions, type SaveBrushEditResult, type BrushEditorControl, type BrushEditorSection, type BrushEditorSectionId, type BrushLibraryGroup, } from './ui.cjs';
|
|
24
|
+
export { addBrushSourceFromFile, brushEditorScope, brushEditorSections, imageFileToPngDataUrl, withBrushSource, brushIdFromName, brushLibraryGroups, newBrushFor, saveBrushEdit, setBrushEditorValue, type BrushEditorHiddenFacet, type BrushEditorScope, type SaveBrushEditOptions, type SaveBrushEditResult, type BrushEditorContext, type BrushEditorControl, type BrushEditorSection, type BrushEditorSectionId, type BrushLibraryGroup, } from './ui.cjs';
|
|
24
25
|
export { createBrushLibraryToolProvider, createBrushLibraryTools, type BrushLibraryToolProviderOptions, type BrushPreviewImage, type BrushPreviewRenderer } from './tools.cjs';
|
package/dist/brushes/index.d.ts
CHANGED
|
@@ -9,7 +9,8 @@
|
|
|
9
9
|
* renderer is bundled.
|
|
10
10
|
*/
|
|
11
11
|
export * from './types.js';
|
|
12
|
-
export { BRUSH_FACET_SCHEMAS, BRUSH_JSON_SCHEMA, BRUSH_WORD, MAX_BRUSH_PALETTE } from './schema.js';
|
|
12
|
+
export { BRUSH_FACET_SCHEMAS, BRUSH_GRAIN_SOURCE_PATTERN, BRUSH_JSON_SCHEMA, BRUSH_WORD, MAX_BRUSH_PALETTE, TIP_GRAIN_PATTERNS } from './schema.js';
|
|
13
|
+
export { BRUSH_SOURCE_CHANNELS, BRUSH_SOURCE_PROVIDER, brushSourceFromMask, brushSourceIdFromName, brushSourceIdOf, brushSourceIds, brushSourceRef, BrushSourceError, decodeBrushSource, isBrushSourceRef, makeBrushSource, MAX_BRUSH_SOURCE_INPUT_PIXELS, MAX_BRUSH_SOURCE_SIZE, MAX_BRUSH_SOURCES, readBrushSource, summarizeBrushSource, type BrushSource, type BrushSourceChannel, type BrushSourceInput, type BrushSourceSummary, type DecodedBrushSource, } from './sources.js';
|
|
13
14
|
export { normalizeBrushSpec, WET_BRUSH_TOOLS } from './normalize.js';
|
|
14
15
|
export { resolveBrush, resolveCategory, resolveEngine, resolveWetMedium, type ResolveBrushOptions } from './resolve.js';
|
|
15
16
|
export { migrateBrushV1 } from './migrate.js';
|
|
@@ -18,7 +19,7 @@ export { brushColourHex } from './colour.js';
|
|
|
18
19
|
export { BRUSH_PREVIEW_DARK_PAPER, BRUSH_PREVIEW_FALLBACKS, BRUSH_PREVIEW_MIN_CONTRAST, brushPreviewColours, brushPreviewsOnDark, brushPreviewStrength, type BrushPreviewColours, type BrushPreviewColoursOptions } from './preview.js';
|
|
19
20
|
export { BRUSH_CONTRACT_FORMAT_VERSION, BRUSH_LIBRARY_FILE_JSON_SCHEMA, BRUSH_PROFILE_JSON_SCHEMA, brushContracts } from './contract.js';
|
|
20
21
|
export { BRUSH_HOST_PROFILES, brushColourKind, CANVAS_PROFILE, checkBrush, checkBrushEdit, degrade, withKeptIssues, IMAGE_PROFILE, listPresets, PAINT_PROFILE, VECTOR_PROFILE, type BrushCheck, type BrushEditCheck, type BrushColourKind, type BrushHostProfile, type BrushIssue, type BrushSupport, type DegradedBrush } from './profiles.js';
|
|
21
|
-
export { BrushLibraryError, createBrushLibrary, isBrushLibrary, parseBrushLibrary, snapshotBrushLibrary, type BrushFilter, type BrushLibrary, type BrushLibraryEntry, type BrushLibraryErrorCode, type BrushLibraryFile, type BrushLibrarySnapshot, type BrushLibraryOptions, type ImportBrushesResult, type SaveBrushResult, } from './library.js';
|
|
22
|
+
export { BrushLibraryError, createBrushLibrary, isBrushLibrary, parseBrushLibrary, parseBrushLibrarySources, type AddBrushSourceResult, snapshotBrushLibrary, type BrushFilter, type BrushLibrary, type BrushLibraryEntry, type BrushLibraryErrorCode, type BrushLibraryFile, type BrushLibrarySnapshot, type BrushLibraryOptions, type ImportBrushesResult, type SaveBrushResult, } from './library.js';
|
|
22
23
|
export { BRUSH_PATCH_PROPERTIES, BRUSH_UNSET_PROPERTY, changedBrushPaths, mergeBrushPatch, UNSETTABLE_BRUSH_FACETS, type BrushPatch, type UnsettableBrushFacet } from './patch.js';
|
|
23
|
-
export { brushEditorScope, brushEditorSections, brushIdFromName, brushLibraryGroups, newBrushFor, saveBrushEdit, setBrushEditorValue, type BrushEditorHiddenFacet, type BrushEditorScope, type SaveBrushEditOptions, type SaveBrushEditResult, type BrushEditorControl, type BrushEditorSection, type BrushEditorSectionId, type BrushLibraryGroup, } from './ui.js';
|
|
24
|
+
export { addBrushSourceFromFile, brushEditorScope, brushEditorSections, imageFileToPngDataUrl, withBrushSource, brushIdFromName, brushLibraryGroups, newBrushFor, saveBrushEdit, setBrushEditorValue, type BrushEditorHiddenFacet, type BrushEditorScope, type SaveBrushEditOptions, type SaveBrushEditResult, type BrushEditorContext, type BrushEditorControl, type BrushEditorSection, type BrushEditorSectionId, type BrushLibraryGroup, } from './ui.js';
|
|
24
25
|
export { createBrushLibraryToolProvider, createBrushLibraryTools, type BrushLibraryToolProviderOptions, type BrushPreviewImage, type BrushPreviewRenderer } from './tools.js';
|