@pixerate/editor 0.262.0 → 0.263.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 +60 -60
- package/dist/animation-editor/index.js +4 -4
- package/dist/brushes/index.cjs +52 -52
- package/dist/brushes/index.js +4 -4
- package/dist/{brushstrokeRender-N6UPZSQS.cjs → brushstrokeRender-2GBME4XD.cjs} +13 -13
- package/dist/{brushstrokeRender-25Q5BEY6.js → brushstrokeRender-S5DABANG.js} +3 -3
- package/dist/canvas/index.cjs +15 -14
- package/dist/canvas/index.js +3 -2
- package/dist/canvas/stickers.d.cts +5 -1
- package/dist/canvas/stickers.d.ts +5 -1
- package/dist/{chunk-6NZL24W4.js → chunk-34HIZXFX.js} +1 -1
- package/dist/{chunk-UVZ7RQOE.cjs → chunk-4E6BGHWN.cjs} +1 -1
- package/dist/{chunk-J5UQHWVL.js → chunk-6JL2D5SG.js} +27 -15
- package/dist/{chunk-QAR2N7HZ.js → chunk-6XX7E7O2.js} +1 -1
- package/dist/{chunk-3TQW5MPW.cjs → chunk-73QFSPDG.cjs} +23 -23
- package/dist/{chunk-APX63ILU.js → chunk-ACFSFUQH.js} +31 -0
- package/dist/{chunk-X2EXYY4J.js → chunk-CNLO6E2K.js} +2 -2
- package/dist/{chunk-F7CPSRLN.js → chunk-DOZ6F2K2.js} +12 -4
- package/dist/{chunk-CQVTGBQI.js → chunk-JGI4PZWO.js} +1 -1
- package/dist/{chunk-EHALWBBD.js → chunk-LG6MEEV7.js} +1 -1
- package/dist/{chunk-7AUQ2UJ3.cjs → chunk-LWHUU6A6.cjs} +10 -10
- package/dist/{chunk-JSDND7DF.cjs → chunk-OTN6VB5S.cjs} +32 -1
- package/dist/{chunk-5IW65VQ6.js → chunk-P5343XZO.js} +1 -1
- package/dist/{chunk-AVTPZO4Z.cjs → chunk-PE6YJMQT.cjs} +37 -25
- package/dist/{chunk-D4TE5JNW.js → chunk-QW7LKWKE.js} +1 -1
- package/dist/{chunk-YLUIFXSL.cjs → chunk-TIHW7CUY.cjs} +35 -35
- package/dist/{chunk-PYTJBVW5.cjs → chunk-TILEUVRO.cjs} +31 -31
- package/dist/{chunk-RVGP2XLF.cjs → chunk-XORJ7UZO.cjs} +21 -13
- package/dist/{chunk-43NT242D.cjs → chunk-XQW6R7VW.cjs} +86 -86
- package/dist/{chunk-TZOX7KWV.cjs → chunk-ZBACQHW3.cjs} +8 -8
- package/dist/image-editor/index.cjs +789 -788
- package/dist/image-editor/index.js +7 -6
- package/dist/image-editor/stickers.d.cts +7 -2
- package/dist/image-editor/stickers.d.ts +7 -2
- package/dist/paint-editor/controller.d.cts +7 -2
- package/dist/paint-editor/controller.d.ts +7 -2
- package/dist/paint-editor/index.cjs +576 -523
- package/dist/paint-editor/index.js +99 -46
- package/dist/paint-editor/sticker-art.d.cts +20 -10
- package/dist/paint-editor/sticker-art.d.ts +20 -10
- package/dist/paint-editor/stickers.d.cts +8 -1
- package/dist/paint-editor/stickers.d.ts +8 -1
- package/dist/paint-editor/stroke.d.cts +2 -0
- package/dist/paint-editor/stroke.d.ts +2 -0
- package/dist/stickers/browser.d.cts +10 -3
- package/dist/stickers/browser.d.ts +10 -3
- package/dist/stickers/combine.d.cts +2 -0
- package/dist/stickers/combine.d.ts +2 -0
- package/dist/stickers/conformance.d.cts +1 -1
- package/dist/stickers/conformance.d.ts +1 -1
- package/dist/stickers/errors.d.cts +1 -1
- package/dist/stickers/errors.d.ts +1 -1
- package/dist/stickers/fake.d.cts +4 -2
- package/dist/stickers/fake.d.ts +4 -2
- package/dist/stickers/helpers.d.cts +16 -2
- package/dist/stickers/helpers.d.ts +16 -2
- package/dist/stickers/index.cjs +116 -29
- package/dist/stickers/index.js +106 -19
- package/dist/stickers/tools.d.cts +9 -2
- package/dist/stickers/tools.d.ts +9 -2
- package/dist/stickers/types.d.cts +32 -5
- package/dist/stickers/types.d.ts +32 -5
- package/dist/vector/index.cjs +972 -971
- package/dist/vector/index.js +7 -6
- package/dist/vector/stickers.d.cts +7 -2
- package/dist/vector/stickers.d.ts +7 -2
- package/package.json +1 -1
- package/skills/pixerate-paint-editor/SKILL.md +1 -1
- package/skills/pixerate-stickers/SKILL.md +20 -9
package/dist/stickers/index.js
CHANGED
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
editorStickers,
|
|
4
4
|
stampOutline,
|
|
5
5
|
stampPixels
|
|
6
|
-
} from "../chunk-
|
|
6
|
+
} from "../chunk-DOZ6F2K2.js";
|
|
7
7
|
import {
|
|
8
8
|
createInsertStickerTool,
|
|
9
9
|
createStickerToolProvider,
|
|
@@ -11,23 +11,28 @@ import {
|
|
|
11
11
|
describeStickerRef,
|
|
12
12
|
insertSticker,
|
|
13
13
|
stickerForAgent
|
|
14
|
-
} from "../chunk-
|
|
14
|
+
} from "../chunk-6JL2D5SG.js";
|
|
15
15
|
import {
|
|
16
16
|
DEFAULT_STICKER_PAGE,
|
|
17
17
|
EDITOR_STICKERS_ID,
|
|
18
18
|
MAX_STICKER_PAGE,
|
|
19
19
|
STAMP_KINDS,
|
|
20
|
+
STICKER_VARIANTS,
|
|
20
21
|
StickersSlot,
|
|
21
22
|
checkStickerSearchOptions,
|
|
23
|
+
checkStickerVariant,
|
|
22
24
|
closestStickerRefs,
|
|
23
25
|
editorStampOf,
|
|
24
26
|
normalizeStickerRef,
|
|
25
27
|
parseStickerRef,
|
|
26
28
|
stampCoverage,
|
|
29
|
+
stickerCollections,
|
|
27
30
|
stickerIdFor,
|
|
28
31
|
stickerPage,
|
|
29
|
-
stickerRefOf
|
|
30
|
-
|
|
32
|
+
stickerRefOf,
|
|
33
|
+
stickerVariantFor,
|
|
34
|
+
stickerVariantsOf
|
|
35
|
+
} from "../chunk-ACFSFUQH.js";
|
|
31
36
|
import {
|
|
32
37
|
StickerError
|
|
33
38
|
} from "../chunk-SZTI6EER.js";
|
|
@@ -39,11 +44,17 @@ import "../chunk-QGHEDC7B.js";
|
|
|
39
44
|
|
|
40
45
|
// src/stickers/fake.ts
|
|
41
46
|
var CATALOGUE = [
|
|
42
|
-
...["sun", "moon", "cloud", "rain", "snow", "wind"].map((w, i) => ({ id: `weather-${w}`, name: w[0].toUpperCase() + w.slice(1), category: "weather", tags: ["weather", w], shape: "badge", colours: [["#f59e0b", "#64748b", "#94a3b8", "#2563eb", "#e0f2fe", "#14b8a6"][i], "#ffffff"], commercial: true })),
|
|
43
|
-
...["apple", "pear", "cherry", "lemon", "grape"].map((f, i) => ({ id: `fruit-${f}`, name: f[0].toUpperCase() + f.slice(1), category: "food", tags: ["fruit", f], shape: "tile", colours: [["#dc2626", "#84cc16", "#be123c", "#facc15", "#7c3aed"][i], "#166534"], commercial: true })),
|
|
44
|
-
...["new", "sale", "hot", "free"].map((b, i) => ({ id: `badge-${b}`, name: `${b[0].toUpperCase() + b.slice(1)} badge`, category: "badges", tags: ["badge", "label", b], shape: "badge", colours: [["#16a34a", "#dc2626", "#ea580c", "#0891b2"][i], "#ffffff"], commercial: true })),
|
|
47
|
+
...["sun", "moon", "cloud", "rain", "snow", "wind"].map((w, i) => ({ id: `weather-${w}`, name: w[0].toUpperCase() + w.slice(1), category: "weather", tags: ["weather", w], shape: "badge", colours: [["#f59e0b", "#64748b", "#94a3b8", "#2563eb", "#e0f2fe", "#14b8a6"][i], "#ffffff"], commercial: true, collection: "outdoors", aiGenerated: true })),
|
|
48
|
+
...["apple", "pear", "cherry", "lemon", "grape"].map((f, i) => ({ id: `fruit-${f}`, name: f[0].toUpperCase() + f.slice(1), category: "food", tags: ["fruit", f], shape: "tile", colours: [["#dc2626", "#84cc16", "#be123c", "#facc15", "#7c3aed"][i], "#166534"], commercial: true, collection: "kitchen" })),
|
|
49
|
+
...["new", "sale", "hot", "free"].map((b, i) => ({ id: `badge-${b}`, name: `${b[0].toUpperCase() + b.slice(1)} badge`, category: "badges", tags: ["badge", "label", b], shape: "badge", colours: [["#16a34a", "#dc2626", "#ea580c", "#0891b2"][i], "#ffffff"], commercial: true, collection: "shop" })),
|
|
45
50
|
{ id: "art-sketch", name: "Sketch", category: "art", tags: ["drawing", "non-commercial"], shape: "tile", colours: ["#1f2937", "#fde68a"], commercial: false }
|
|
46
51
|
];
|
|
52
|
+
var COLLECTIONS = {
|
|
53
|
+
outdoors: { name: "Outdoors", description: "Weather, AI-generated." },
|
|
54
|
+
kitchen: { name: "Kitchen", description: "Fruit tiles with dark variants." },
|
|
55
|
+
shop: { name: "Shop", description: "Tintable sale badges." }
|
|
56
|
+
};
|
|
57
|
+
var DARK_TOP = "#f8fafc";
|
|
47
58
|
var W = 120;
|
|
48
59
|
var H = 120;
|
|
49
60
|
function summaryOf(s) {
|
|
@@ -57,16 +68,22 @@ function summaryOf(s) {
|
|
|
57
68
|
height: H,
|
|
58
69
|
formats: ["svg", "png"],
|
|
59
70
|
licence: s.commercial ? { spdx: "CC0-1.0", name: "CC0 1.0", commercial: true } : { spdx: "CC-BY-NC-4.0", name: "CC BY-NC 4.0", attribution: "Fake Artist", commercial: false },
|
|
60
|
-
tintable: s.shape === "badge"
|
|
71
|
+
tintable: s.shape === "badge",
|
|
72
|
+
...s.shape === "tile" ? { variants: ["light", "dark"] } : {},
|
|
73
|
+
...s.collection ? { collection: s.collection } : {},
|
|
74
|
+
...s.aiGenerated ? { aiGenerated: true } : {}
|
|
61
75
|
};
|
|
62
76
|
}
|
|
63
|
-
|
|
77
|
+
var tileColours = (s, variant) => variant === "dark" ? [s.colours[0], DARK_TOP] : s.colours;
|
|
78
|
+
function svgOf(s, fill, variant) {
|
|
64
79
|
if (s.shape === "badge") {
|
|
65
80
|
return `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${W} ${H}" width="${W}" height="${H}"><path fill="${fill}" fill-rule="evenodd" d="M60 6A54 54 0 1 1 59.9 6ZM45 45H75V75H45Z"/></svg>`;
|
|
66
81
|
}
|
|
67
|
-
|
|
82
|
+
const [bottom, top] = tileColours(s, variant);
|
|
83
|
+
return `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${W} ${H}" width="${W}" height="${H}"><rect x="10" y="10" width="100" height="100" fill="${bottom}"/><rect x="10" y="10" width="100" height="50" fill="${top}"/></svg>`;
|
|
68
84
|
}
|
|
69
|
-
function pixelsOf(s, size, fill) {
|
|
85
|
+
function pixelsOf(s, size, fill, variant) {
|
|
86
|
+
const [bottom, top] = tileColours(s, variant);
|
|
70
87
|
const out = new Uint8ClampedArray(size * size * 4);
|
|
71
88
|
const hex = (c) => [parseInt(c.slice(1, 3), 16), parseInt(c.slice(3, 5), 16), parseInt(c.slice(5, 7), 16)];
|
|
72
89
|
for (let y = 0; y < size; y++) {
|
|
@@ -78,7 +95,7 @@ function pixelsOf(s, size, fill) {
|
|
|
78
95
|
const inDisc = Math.hypot(u - 60, v - 60) <= 54;
|
|
79
96
|
const inNotch = u >= 45 && u <= 75 && v >= 45 && v <= 75;
|
|
80
97
|
if (inDisc && !inNotch) rgb = hex(fill);
|
|
81
|
-
} else if (u >= 10 && u <= 110 && v >= 10 && v <= 110) rgb = hex(v < 60 ?
|
|
98
|
+
} else if (u >= 10 && u <= 110 && v >= 10 && v <= 110) rgb = hex(v < 60 ? top : bottom);
|
|
82
99
|
if (!rgb) continue;
|
|
83
100
|
const i = (y * size + x) * 4;
|
|
84
101
|
out[i] = rgb[0];
|
|
@@ -104,19 +121,21 @@ function createFakeStickerProvider(options = {}) {
|
|
|
104
121
|
if (!s) return void 0;
|
|
105
122
|
return { ...summaryOf(s), silhouette: s.shape === "badge" ? "M60 6A54 54 0 1 1 59.9 6Z" : "M10 10H110V110H10Z", colours: s.shape === "badge" ? [s.colours[0]] : [...s.colours] };
|
|
106
123
|
},
|
|
124
|
+
listCollections: () => stickerCollections(summaries, COLLECTIONS),
|
|
107
125
|
categories: () => [...new Set(CATALOGUE.map((s) => s.category))].map((c) => ({ id: c, name: c, count: CATALOGUE.filter((s) => s.category === c).length })),
|
|
108
126
|
async load(id, o = {}) {
|
|
109
127
|
if (options.loadDelayMs) await new Promise((r) => setTimeout(r, options.loadDelayMs));
|
|
110
128
|
const s = find(id);
|
|
111
129
|
if (!s) throw new StickerError("unknown_sticker", `No fake sticker "${id}".`);
|
|
112
130
|
if (options.failIds?.includes(id)) throw new StickerError("load_failed", `The fake sticker "${id}" failed to load (failIds).`);
|
|
131
|
+
const variant = checkStickerVariant(summaryOf(s), o.variant);
|
|
113
132
|
const fill = s.shape === "badge" && o.colour ? o.colour.toLowerCase() : s.colours[0];
|
|
114
133
|
if (o.format === "png") {
|
|
115
134
|
const size = o.size ?? 128;
|
|
116
135
|
if (!(Number.isInteger(size) && size >= 8 && size <= 512)) throw new StickerError("invalid_argument", `size must be 8..512 px, got ${size}.`);
|
|
117
|
-
return { kind: "image", url: pngDataUrl(size, size, pixelsOf(s, size, fill)), width: size, height: size };
|
|
136
|
+
return { kind: "image", url: pngDataUrl(size, size, pixelsOf(s, size, fill, variant)), width: size, height: size };
|
|
118
137
|
}
|
|
119
|
-
return { kind: "svg", svg: svgOf(s, fill) };
|
|
138
|
+
return { kind: "svg", svg: svgOf(s, fill, variant) };
|
|
120
139
|
}
|
|
121
140
|
};
|
|
122
141
|
}
|
|
@@ -133,10 +152,18 @@ function combineStickerProviders(providers, options = {}) {
|
|
|
133
152
|
if (!p) throw new StickerError("unknown_provider", `No sticker provider "${provider}"; the providers are ${ids.join(", ") || "none"}.`);
|
|
134
153
|
return { p, id };
|
|
135
154
|
};
|
|
136
|
-
const
|
|
155
|
+
const collectionOf = (p, c) => p.namespaced ? c : `${p.id}:${c}`;
|
|
156
|
+
const prefix = (p, s) => ({ ...s, id: stickerRefOf(p, s.id), ...s.collection ? { collection: collectionOf(p, s.collection) } : {} });
|
|
157
|
+
const collectionOwner = (c) => {
|
|
158
|
+
const i = c.indexOf(":");
|
|
159
|
+
const p = i > 0 ? byId.get(c.slice(0, i)) : void 0;
|
|
160
|
+
if (!p) throw new StickerError("invalid_argument", `No collection "${c}"; collections here are "provider:collection" (listCollections lists them).`);
|
|
161
|
+
return { p, collection: p.namespaced ? c : c.slice(i + 1) };
|
|
162
|
+
};
|
|
137
163
|
const page = async (query, o = {}) => {
|
|
138
|
-
const { after, limit = DEFAULT_STICKER_PAGE, ...filters } = o;
|
|
164
|
+
const { after, limit = DEFAULT_STICKER_PAGE, collection, ...filters } = o;
|
|
139
165
|
checkStickerSearchOptions({ limit });
|
|
166
|
+
const only = collection !== void 0 ? collectionOwner(collection) : null;
|
|
140
167
|
let i = 0;
|
|
141
168
|
let inner;
|
|
142
169
|
if (after !== void 0) {
|
|
@@ -145,7 +172,11 @@ function combineStickerProviders(providers, options = {}) {
|
|
|
145
172
|
i = Number(m[1]);
|
|
146
173
|
inner = m[2] || void 0;
|
|
147
174
|
}
|
|
148
|
-
const get = (p, opts) =>
|
|
175
|
+
const get = async (p, opts) => {
|
|
176
|
+
if (only && only.p !== p) return { items: [], total: 0 };
|
|
177
|
+
const withCollection = only ? { ...opts, collection: only.collection } : opts;
|
|
178
|
+
return query === null ? p.list(withCollection) : p.search(query, withCollection);
|
|
179
|
+
};
|
|
149
180
|
let total = 0;
|
|
150
181
|
for (const p of providers) total += (await get(p, { ...filters, limit: 1 })).total;
|
|
151
182
|
const items = [];
|
|
@@ -185,7 +216,7 @@ function combineStickerProviders(providers, options = {}) {
|
|
|
185
216
|
return void 0;
|
|
186
217
|
}
|
|
187
218
|
const d = await o.p.describe(o.id);
|
|
188
|
-
return d ?
|
|
219
|
+
return d ? prefix(o.p, d) : void 0;
|
|
189
220
|
},
|
|
190
221
|
async load(ref, o) {
|
|
191
222
|
const { p, id } = owner(ref);
|
|
@@ -200,6 +231,11 @@ function combineStickerProviders(providers, options = {}) {
|
|
|
200
231
|
}
|
|
201
232
|
}
|
|
202
233
|
return [...counts.values()];
|
|
234
|
+
},
|
|
235
|
+
async listCollections() {
|
|
236
|
+
const out = [];
|
|
237
|
+
for (const p of providers) for (const c of await p.listCollections?.() ?? []) out.push({ ...c, id: collectionOf(p, c.id) });
|
|
238
|
+
return out;
|
|
203
239
|
}
|
|
204
240
|
};
|
|
205
241
|
}
|
|
@@ -220,6 +256,14 @@ function checkSummary(s, provider, issues) {
|
|
|
220
256
|
if (typeof s.licence?.commercial !== "boolean") at("licence.commercial is not a boolean");
|
|
221
257
|
if (typeof s.tintable !== "boolean") at("tintable is not a boolean");
|
|
222
258
|
if (s.thumbnail !== void 0 && !/^(data:|https:)/.test(s.thumbnail)) at("thumbnail must be a data: or https: URL");
|
|
259
|
+
if (s.aiGenerated !== void 0 && typeof s.aiGenerated !== "boolean") at("aiGenerated must be a boolean when present");
|
|
260
|
+
if (s.variants !== void 0) {
|
|
261
|
+
const v = s.variants;
|
|
262
|
+
if (!Array.isArray(v) || v.some((x) => x !== "light" && x !== "dark") || new Set(v).size !== v.length) at("variants must list light and / or dark, each once");
|
|
263
|
+
else if (!v.includes("light")) at("variants must include light (every sticker has its light art)");
|
|
264
|
+
}
|
|
265
|
+
if (s.collection !== void 0 && (typeof s.collection !== "string" || !s.collection)) at("collection must be a non-empty string when present");
|
|
266
|
+
if (s.collection !== void 0 && !provider.listCollections) at(`is in collection "${s.collection}" but the provider has no listCollections()`);
|
|
223
267
|
}
|
|
224
268
|
async function checkStickerProvider(provider, options = {}) {
|
|
225
269
|
const issues = [];
|
|
@@ -278,6 +322,26 @@ async function checkStickerProvider(provider, options = {}) {
|
|
|
278
322
|
if (d?.colours?.some((c) => !HEX.test(c))) top(`describe("${first.id}").colours must be #rrggbb`);
|
|
279
323
|
}
|
|
280
324
|
if (await provider.describe("__no_such_sticker__") !== void 0) top("describe of an unknown id returned a sticker");
|
|
325
|
+
if (provider.listCollections) {
|
|
326
|
+
try {
|
|
327
|
+
const collections = await provider.listCollections();
|
|
328
|
+
const known = /* @__PURE__ */ new Set();
|
|
329
|
+
for (const c of collections) {
|
|
330
|
+
if (typeof c?.id !== "string" || !c.id || typeof c.name !== "string" || !c.name || !(Number.isInteger(c.count) && c.count >= 0)) {
|
|
331
|
+
top(`listCollections() returned ${JSON.stringify(c)}; each needs id, name and a count`);
|
|
332
|
+
continue;
|
|
333
|
+
}
|
|
334
|
+
if (known.has(c.id)) top(`listCollections() lists "${c.id}" twice`);
|
|
335
|
+
known.add(c.id);
|
|
336
|
+
const page = await provider.list({ collection: c.id, limit: 100 });
|
|
337
|
+
if (page.total !== c.count) top(`collection "${c.id}" says count ${c.count} but list({ collection }) has ${page.total}`);
|
|
338
|
+
if (page.items.some((x) => x.collection !== c.id)) top(`list({ collection: "${c.id}" }) returned stickers of other collections`);
|
|
339
|
+
}
|
|
340
|
+
for (const x of all) if (x.collection !== void 0 && !known.has(x.collection)) issues.push({ stickerId: x.id, message: `collection "${x.collection}" is not in listCollections()` });
|
|
341
|
+
} catch (e) {
|
|
342
|
+
top(`listCollections() rejected: ${e.message}`);
|
|
343
|
+
}
|
|
344
|
+
}
|
|
281
345
|
let rejected = false;
|
|
282
346
|
try {
|
|
283
347
|
await provider.load("__no_such_sticker__");
|
|
@@ -296,6 +360,24 @@ async function checkStickerProvider(provider, options = {}) {
|
|
|
296
360
|
}
|
|
297
361
|
}
|
|
298
362
|
}
|
|
363
|
+
const dark = all.find((s) => s.variants?.includes("dark"));
|
|
364
|
+
if (dark) {
|
|
365
|
+
try {
|
|
366
|
+
await provider.load(dark.id, { format: dark.formats[0], variant: "dark", size: 32 });
|
|
367
|
+
} catch (e) {
|
|
368
|
+
issues.push({ stickerId: dark.id, message: `load({ variant: "dark" }) rejected for a sticker that lists it: ${e.message}` });
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
const lightOnly = all.find((s) => !s.variants?.includes("dark"));
|
|
372
|
+
if (lightOnly) {
|
|
373
|
+
let refused = false;
|
|
374
|
+
try {
|
|
375
|
+
await provider.load(lightOnly.id, { format: lightOnly.formats[0], variant: "dark", size: 32 });
|
|
376
|
+
} catch {
|
|
377
|
+
refused = true;
|
|
378
|
+
}
|
|
379
|
+
if (!refused) issues.push({ stickerId: lightOnly.id, message: 'load({ variant: "dark" }) did not reject for a sticker without a dark variant (checkStickerVariant does it)' });
|
|
380
|
+
}
|
|
299
381
|
const tintable = all.find((s) => s.tintable);
|
|
300
382
|
if (tintable) {
|
|
301
383
|
try {
|
|
@@ -312,11 +394,13 @@ export {
|
|
|
312
394
|
EDITOR_STICKERS_ID,
|
|
313
395
|
MAX_STICKER_PAGE,
|
|
314
396
|
STAMP_KINDS,
|
|
397
|
+
STICKER_VARIANTS,
|
|
315
398
|
StickerBrowser,
|
|
316
399
|
StickerError,
|
|
317
400
|
StickersSlot,
|
|
318
401
|
checkStickerProvider,
|
|
319
402
|
checkStickerSearchOptions,
|
|
403
|
+
checkStickerVariant,
|
|
320
404
|
closestStickerRefs,
|
|
321
405
|
combineStickerProviders,
|
|
322
406
|
createFakeStickerProvider,
|
|
@@ -332,8 +416,11 @@ export {
|
|
|
332
416
|
stampCoverage,
|
|
333
417
|
stampOutline,
|
|
334
418
|
stampPixels,
|
|
419
|
+
stickerCollections,
|
|
335
420
|
stickerForAgent,
|
|
336
421
|
stickerIdFor,
|
|
337
422
|
stickerPage,
|
|
338
|
-
stickerRefOf
|
|
423
|
+
stickerRefOf,
|
|
424
|
+
stickerVariantFor,
|
|
425
|
+
stickerVariantsOf
|
|
339
426
|
};
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* stickers. Refusals name the valid choices.
|
|
5
5
|
*/
|
|
6
6
|
import type { AgentTool, AgentToolProvider } from '../tools/registry.cjs';
|
|
7
|
-
import type
|
|
7
|
+
import { type MaybePromise, type StickerAsset, type StickerDescription, type StickerFormat, type StickerProvider, type StickerRef, type StickerSummary, type StickerVariant } from './types.cjs';
|
|
8
8
|
/** Where and how big an inserted sticker goes, with its art. */
|
|
9
9
|
export interface StickerPlacement {
|
|
10
10
|
ref: StickerRef;
|
|
@@ -18,6 +18,8 @@ export interface StickerPlacement {
|
|
|
18
18
|
height: number;
|
|
19
19
|
/** #rrggbb it was tinted to, when tintable and asked for. */
|
|
20
20
|
colour?: string;
|
|
21
|
+
/** The variant its art is (`dark` for a dark background, when the sticker has it). */
|
|
22
|
+
variant: StickerVariant;
|
|
21
23
|
}
|
|
22
24
|
/**
|
|
23
25
|
* An editor that can take an inserted sticker (`insert_sticker`): the vector editor (editable
|
|
@@ -33,6 +35,8 @@ export interface StickerInsertHost {
|
|
|
33
35
|
x: number;
|
|
34
36
|
y: number;
|
|
35
37
|
};
|
|
38
|
+
/** The background is dark (a dark canvas or theme): stickers with a dark variant use it unless the call names one. */
|
|
39
|
+
dark?(): boolean;
|
|
36
40
|
/** Adds the sticker as one undo step; returns what it made (its id at least) for later tools. */
|
|
37
41
|
insert(placement: StickerPlacement): MaybePromise<{
|
|
38
42
|
id: string;
|
|
@@ -57,7 +61,8 @@ export declare function createStickerTools(options: StickerToolsOptions): AgentT
|
|
|
57
61
|
* Puts one sticker into an editor through its host (the panels and `insert_sticker` both use it):
|
|
58
62
|
* checks the ref, loads the art in the host's format, tinted when asked and tintable, and places
|
|
59
63
|
* it centred at (`x`, `y`) (default the host's centre), `width` wide (default its natural width).
|
|
60
|
-
*
|
|
64
|
+
* The art is the `variant` asked for, else the dark one when the host's background is dark and
|
|
65
|
+
* the sticker has it. Returns what the host made, the ref, the size, the variant and the licence.
|
|
61
66
|
*/
|
|
62
67
|
export declare function insertSticker(provider: StickerProvider, host: StickerInsertHost, options: {
|
|
63
68
|
ref: StickerRef;
|
|
@@ -65,11 +70,13 @@ export declare function insertSticker(provider: StickerProvider, host: StickerIn
|
|
|
65
70
|
y?: number;
|
|
66
71
|
width?: number;
|
|
67
72
|
color?: string;
|
|
73
|
+
variant?: StickerVariant;
|
|
68
74
|
}): Promise<{
|
|
69
75
|
id: string;
|
|
70
76
|
ref: StickerRef;
|
|
71
77
|
width: number;
|
|
72
78
|
height: number;
|
|
79
|
+
variant: StickerVariant;
|
|
73
80
|
licence: StickerDescription['licence'];
|
|
74
81
|
} & Record<string, unknown>>;
|
|
75
82
|
/** `insert_sticker`: one sticker by ref into an editor, at a place and size, as one undo step. */
|
package/dist/stickers/tools.d.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* stickers. Refusals name the valid choices.
|
|
5
5
|
*/
|
|
6
6
|
import type { AgentTool, AgentToolProvider } from '../tools/registry.js';
|
|
7
|
-
import type
|
|
7
|
+
import { type MaybePromise, type StickerAsset, type StickerDescription, type StickerFormat, type StickerProvider, type StickerRef, type StickerSummary, type StickerVariant } from './types.js';
|
|
8
8
|
/** Where and how big an inserted sticker goes, with its art. */
|
|
9
9
|
export interface StickerPlacement {
|
|
10
10
|
ref: StickerRef;
|
|
@@ -18,6 +18,8 @@ export interface StickerPlacement {
|
|
|
18
18
|
height: number;
|
|
19
19
|
/** #rrggbb it was tinted to, when tintable and asked for. */
|
|
20
20
|
colour?: string;
|
|
21
|
+
/** The variant its art is (`dark` for a dark background, when the sticker has it). */
|
|
22
|
+
variant: StickerVariant;
|
|
21
23
|
}
|
|
22
24
|
/**
|
|
23
25
|
* An editor that can take an inserted sticker (`insert_sticker`): the vector editor (editable
|
|
@@ -33,6 +35,8 @@ export interface StickerInsertHost {
|
|
|
33
35
|
x: number;
|
|
34
36
|
y: number;
|
|
35
37
|
};
|
|
38
|
+
/** The background is dark (a dark canvas or theme): stickers with a dark variant use it unless the call names one. */
|
|
39
|
+
dark?(): boolean;
|
|
36
40
|
/** Adds the sticker as one undo step; returns what it made (its id at least) for later tools. */
|
|
37
41
|
insert(placement: StickerPlacement): MaybePromise<{
|
|
38
42
|
id: string;
|
|
@@ -57,7 +61,8 @@ export declare function createStickerTools(options: StickerToolsOptions): AgentT
|
|
|
57
61
|
* Puts one sticker into an editor through its host (the panels and `insert_sticker` both use it):
|
|
58
62
|
* checks the ref, loads the art in the host's format, tinted when asked and tintable, and places
|
|
59
63
|
* it centred at (`x`, `y`) (default the host's centre), `width` wide (default its natural width).
|
|
60
|
-
*
|
|
64
|
+
* The art is the `variant` asked for, else the dark one when the host's background is dark and
|
|
65
|
+
* the sticker has it. Returns what the host made, the ref, the size, the variant and the licence.
|
|
61
66
|
*/
|
|
62
67
|
export declare function insertSticker(provider: StickerProvider, host: StickerInsertHost, options: {
|
|
63
68
|
ref: StickerRef;
|
|
@@ -65,11 +70,13 @@ export declare function insertSticker(provider: StickerProvider, host: StickerIn
|
|
|
65
70
|
y?: number;
|
|
66
71
|
width?: number;
|
|
67
72
|
color?: string;
|
|
73
|
+
variant?: StickerVariant;
|
|
68
74
|
}): Promise<{
|
|
69
75
|
id: string;
|
|
70
76
|
ref: StickerRef;
|
|
71
77
|
width: number;
|
|
72
78
|
height: number;
|
|
79
|
+
variant: StickerVariant;
|
|
73
80
|
licence: StickerDescription['licence'];
|
|
74
81
|
} & Record<string, unknown>>;
|
|
75
82
|
/** `insert_sticker`: one sticker by ref into an editor, at a place and size, as one undo step. */
|
|
@@ -20,6 +20,22 @@ export interface StickerLicence {
|
|
|
20
20
|
commercial: boolean;
|
|
21
21
|
}
|
|
22
22
|
export type StickerFormat = 'svg' | 'png';
|
|
23
|
+
/**
|
|
24
|
+
* A version of a sticker drawn for a light or a dark background: the same subject, pose and size.
|
|
25
|
+
* `light` is the default art every sticker has.
|
|
26
|
+
*/
|
|
27
|
+
export type StickerVariant = 'light' | 'dark';
|
|
28
|
+
/** The variants there are, in order. */
|
|
29
|
+
export declare const STICKER_VARIANTS: readonly StickerVariant[];
|
|
30
|
+
/** A themed set of stickers within one provider (one per brand, say). */
|
|
31
|
+
export interface StickerCollection {
|
|
32
|
+
/** Unique within the provider; what `StickerSummary.collection` and `StickerSearchOptions.collection` name. */
|
|
33
|
+
id: string;
|
|
34
|
+
name: string;
|
|
35
|
+
description?: string;
|
|
36
|
+
/** How many stickers it holds. */
|
|
37
|
+
count: number;
|
|
38
|
+
}
|
|
23
39
|
/** A sticker in a list or search result. */
|
|
24
40
|
export interface StickerSummary {
|
|
25
41
|
/** The provider's id (no `:` needed; `combineStickerProviders` prefixes its own). */
|
|
@@ -38,6 +54,15 @@ export interface StickerSummary {
|
|
|
38
54
|
licence: StickerLicence;
|
|
39
55
|
/** Flat, single-colour art: `load(id, { colour })` recolours it (the paint editor's spray colours it). */
|
|
40
56
|
tintable: boolean;
|
|
57
|
+
/** The art was made by an AI model (absent: not said), so pickers and agents can label it. */
|
|
58
|
+
aiGenerated?: boolean;
|
|
59
|
+
/**
|
|
60
|
+
* The variants `load(id, { variant })` returns, always with `light` (absent: only `light`), so a
|
|
61
|
+
* picker or brush can pick the dark one for a dark background without calling `describe` first.
|
|
62
|
+
*/
|
|
63
|
+
variants?: StickerVariant[];
|
|
64
|
+
/** The collection it belongs to (`listCollections`), when the provider groups its stickers. */
|
|
65
|
+
collection?: string;
|
|
41
66
|
}
|
|
42
67
|
/** Everything about one sticker. */
|
|
43
68
|
export interface StickerDescription extends StickerSummary {
|
|
@@ -45,10 +70,6 @@ export interface StickerDescription extends StickerSummary {
|
|
|
45
70
|
silhouette?: string;
|
|
46
71
|
/** Dominant colours #rrggbb, for matching and recolouring. */
|
|
47
72
|
colours?: string[];
|
|
48
|
-
variants?: {
|
|
49
|
-
id: string;
|
|
50
|
-
name: string;
|
|
51
|
-
}[];
|
|
52
73
|
}
|
|
53
74
|
/** A sticker's art. */
|
|
54
75
|
export type StickerAsset = {
|
|
@@ -72,6 +93,8 @@ export interface StickerPage {
|
|
|
72
93
|
}
|
|
73
94
|
export interface StickerSearchOptions {
|
|
74
95
|
category?: string;
|
|
96
|
+
/** Only stickers of this collection (`listCollections`). */
|
|
97
|
+
collection?: string;
|
|
75
98
|
/** Every tag must match. */
|
|
76
99
|
tags?: string[];
|
|
77
100
|
/** Page size (providers cap it; 1..100, default 24). */
|
|
@@ -88,6 +111,8 @@ export interface StickerLoadOptions {
|
|
|
88
111
|
size?: number;
|
|
89
112
|
/** #rrggbb: recolour a tintable sticker. */
|
|
90
113
|
colour?: string;
|
|
114
|
+
/** The art for a light (default) or dark background; one the sticker doesn't list is refused, naming the ones it has. */
|
|
115
|
+
variant?: StickerVariant;
|
|
91
116
|
}
|
|
92
117
|
export interface StickerProviderCapabilities {
|
|
93
118
|
supportsSearch: boolean;
|
|
@@ -110,7 +135,7 @@ export interface StickerProvider {
|
|
|
110
135
|
search(query: string, options?: StickerSearchOptions): MaybePromise<StickerPage>;
|
|
111
136
|
/** A sticker by id, or `undefined`. */
|
|
112
137
|
describe(id: string): MaybePromise<StickerDescription | undefined>;
|
|
113
|
-
/** The art; rejects with a `StickerError` (`unknown_sticker`, `unsupported_format`) when it can't. */
|
|
138
|
+
/** The art; rejects with a `StickerError` (`unknown_sticker`, `unsupported_format`, `unsupported_variant`) when it can't. */
|
|
114
139
|
load(id: string, options?: StickerLoadOptions): MaybePromise<StickerAsset>;
|
|
115
140
|
/** Categories with counts, when the provider knows them. */
|
|
116
141
|
categories?(): MaybePromise<Array<{
|
|
@@ -118,6 +143,8 @@ export interface StickerProvider {
|
|
|
118
143
|
name: string;
|
|
119
144
|
count: number;
|
|
120
145
|
}>>;
|
|
146
|
+
/** Its collections with counts, when it groups its stickers. Ids stay unique across collections, so `load(id)` needs none. */
|
|
147
|
+
listCollections?(): MaybePromise<StickerCollection[]>;
|
|
121
148
|
}
|
|
122
149
|
/** `provider:id`, the name of a sticker across providers. A bare editor stamp (`"star"`) means `editor:star`. */
|
|
123
150
|
export type StickerRef = string;
|
package/dist/stickers/types.d.ts
CHANGED
|
@@ -20,6 +20,22 @@ export interface StickerLicence {
|
|
|
20
20
|
commercial: boolean;
|
|
21
21
|
}
|
|
22
22
|
export type StickerFormat = 'svg' | 'png';
|
|
23
|
+
/**
|
|
24
|
+
* A version of a sticker drawn for a light or a dark background: the same subject, pose and size.
|
|
25
|
+
* `light` is the default art every sticker has.
|
|
26
|
+
*/
|
|
27
|
+
export type StickerVariant = 'light' | 'dark';
|
|
28
|
+
/** The variants there are, in order. */
|
|
29
|
+
export declare const STICKER_VARIANTS: readonly StickerVariant[];
|
|
30
|
+
/** A themed set of stickers within one provider (one per brand, say). */
|
|
31
|
+
export interface StickerCollection {
|
|
32
|
+
/** Unique within the provider; what `StickerSummary.collection` and `StickerSearchOptions.collection` name. */
|
|
33
|
+
id: string;
|
|
34
|
+
name: string;
|
|
35
|
+
description?: string;
|
|
36
|
+
/** How many stickers it holds. */
|
|
37
|
+
count: number;
|
|
38
|
+
}
|
|
23
39
|
/** A sticker in a list or search result. */
|
|
24
40
|
export interface StickerSummary {
|
|
25
41
|
/** The provider's id (no `:` needed; `combineStickerProviders` prefixes its own). */
|
|
@@ -38,6 +54,15 @@ export interface StickerSummary {
|
|
|
38
54
|
licence: StickerLicence;
|
|
39
55
|
/** Flat, single-colour art: `load(id, { colour })` recolours it (the paint editor's spray colours it). */
|
|
40
56
|
tintable: boolean;
|
|
57
|
+
/** The art was made by an AI model (absent: not said), so pickers and agents can label it. */
|
|
58
|
+
aiGenerated?: boolean;
|
|
59
|
+
/**
|
|
60
|
+
* The variants `load(id, { variant })` returns, always with `light` (absent: only `light`), so a
|
|
61
|
+
* picker or brush can pick the dark one for a dark background without calling `describe` first.
|
|
62
|
+
*/
|
|
63
|
+
variants?: StickerVariant[];
|
|
64
|
+
/** The collection it belongs to (`listCollections`), when the provider groups its stickers. */
|
|
65
|
+
collection?: string;
|
|
41
66
|
}
|
|
42
67
|
/** Everything about one sticker. */
|
|
43
68
|
export interface StickerDescription extends StickerSummary {
|
|
@@ -45,10 +70,6 @@ export interface StickerDescription extends StickerSummary {
|
|
|
45
70
|
silhouette?: string;
|
|
46
71
|
/** Dominant colours #rrggbb, for matching and recolouring. */
|
|
47
72
|
colours?: string[];
|
|
48
|
-
variants?: {
|
|
49
|
-
id: string;
|
|
50
|
-
name: string;
|
|
51
|
-
}[];
|
|
52
73
|
}
|
|
53
74
|
/** A sticker's art. */
|
|
54
75
|
export type StickerAsset = {
|
|
@@ -72,6 +93,8 @@ export interface StickerPage {
|
|
|
72
93
|
}
|
|
73
94
|
export interface StickerSearchOptions {
|
|
74
95
|
category?: string;
|
|
96
|
+
/** Only stickers of this collection (`listCollections`). */
|
|
97
|
+
collection?: string;
|
|
75
98
|
/** Every tag must match. */
|
|
76
99
|
tags?: string[];
|
|
77
100
|
/** Page size (providers cap it; 1..100, default 24). */
|
|
@@ -88,6 +111,8 @@ export interface StickerLoadOptions {
|
|
|
88
111
|
size?: number;
|
|
89
112
|
/** #rrggbb: recolour a tintable sticker. */
|
|
90
113
|
colour?: string;
|
|
114
|
+
/** The art for a light (default) or dark background; one the sticker doesn't list is refused, naming the ones it has. */
|
|
115
|
+
variant?: StickerVariant;
|
|
91
116
|
}
|
|
92
117
|
export interface StickerProviderCapabilities {
|
|
93
118
|
supportsSearch: boolean;
|
|
@@ -110,7 +135,7 @@ export interface StickerProvider {
|
|
|
110
135
|
search(query: string, options?: StickerSearchOptions): MaybePromise<StickerPage>;
|
|
111
136
|
/** A sticker by id, or `undefined`. */
|
|
112
137
|
describe(id: string): MaybePromise<StickerDescription | undefined>;
|
|
113
|
-
/** The art; rejects with a `StickerError` (`unknown_sticker`, `unsupported_format`) when it can't. */
|
|
138
|
+
/** The art; rejects with a `StickerError` (`unknown_sticker`, `unsupported_format`, `unsupported_variant`) when it can't. */
|
|
114
139
|
load(id: string, options?: StickerLoadOptions): MaybePromise<StickerAsset>;
|
|
115
140
|
/** Categories with counts, when the provider knows them. */
|
|
116
141
|
categories?(): MaybePromise<Array<{
|
|
@@ -118,6 +143,8 @@ export interface StickerProvider {
|
|
|
118
143
|
name: string;
|
|
119
144
|
count: number;
|
|
120
145
|
}>>;
|
|
146
|
+
/** Its collections with counts, when it groups its stickers. Ids stay unique across collections, so `load(id)` needs none. */
|
|
147
|
+
listCollections?(): MaybePromise<StickerCollection[]>;
|
|
121
148
|
}
|
|
122
149
|
/** `provider:id`, the name of a sticker across providers. A bare editor stamp (`"star"`) means `editor:star`. */
|
|
123
150
|
export type StickerRef = string;
|