@pixerate/editor 0.262.1 → 0.264.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 +158 -71
- package/dist/brushes/index.d.cts +3 -3
- package/dist/brushes/index.d.ts +3 -3
- package/dist/brushes/index.js +113 -26
- package/dist/brushes/library.d.cts +2 -0
- package/dist/brushes/library.d.ts +2 -0
- package/dist/brushes/profiles.d.cts +21 -2
- package/dist/brushes/profiles.d.ts +21 -2
- package/dist/brushes/ui.d.cts +57 -4
- package/dist/brushes/ui.d.ts +57 -4
- package/dist/{brushstrokeRender-25Q5BEY6.js → brushstrokeRender-3MOI7PH4.js} +3 -3
- package/dist/{brushstrokeRender-N6UPZSQS.cjs → brushstrokeRender-SMMPIJF2.cjs} +13 -13
- 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-X2EXYY4J.js → chunk-4OJC4MCD.js} +9 -8
- package/dist/{chunk-J5UQHWVL.js → chunk-6JL2D5SG.js} +27 -15
- package/dist/{chunk-APX63ILU.js → chunk-ACFSFUQH.js} +31 -0
- package/dist/{chunk-TZOX7KWV.cjs → chunk-BY5EBP26.cjs} +35 -14
- package/dist/{chunk-CQVTGBQI.js → chunk-CECCP2V7.js} +1 -1
- package/dist/{chunk-F7CPSRLN.js → chunk-DOZ6F2K2.js} +12 -4
- package/dist/{chunk-5IW65VQ6.js → chunk-EE7SAYBF.js} +24 -3
- package/dist/{chunk-PYTJBVW5.cjs → chunk-F3KKR6DD.cjs} +37 -36
- package/dist/{chunk-YLUIFXSL.cjs → chunk-FQC5TDB6.cjs} +35 -35
- package/dist/{chunk-UVZ7RQOE.cjs → chunk-G5ADO47G.cjs} +1 -1
- package/dist/{chunk-D4TE5JNW.js → chunk-HAUDEVMC.js} +1 -1
- package/dist/{chunk-EHALWBBD.js → chunk-JEML4FSA.js} +1 -1
- package/dist/{chunk-43NT242D.cjs → chunk-KXNZNOEF.cjs} +86 -86
- package/dist/{chunk-JSDND7DF.cjs → chunk-OTN6VB5S.cjs} +32 -1
- package/dist/{chunk-AVTPZO4Z.cjs → chunk-PE6YJMQT.cjs} +37 -25
- package/dist/{chunk-QAR2N7HZ.js → chunk-ROBSFJ6F.js} +1 -1
- package/dist/{chunk-7AUQ2UJ3.cjs → chunk-USJX5SW4.cjs} +10 -10
- package/dist/{chunk-3TQW5MPW.cjs → chunk-V7MJ4HIN.cjs} +23 -23
- package/dist/{chunk-6NZL24W4.js → chunk-WWI6FLH2.js} +1 -1
- package/dist/{chunk-RVGP2XLF.cjs → chunk-XORJ7UZO.cjs} +21 -13
- package/dist/image-editor/controller.d.cts +3 -0
- package/dist/image-editor/controller.d.ts +3 -0
- package/dist/image-editor/index.cjs +792 -788
- package/dist/image-editor/index.js +10 -6
- package/dist/image-editor/stickers.d.cts +7 -2
- package/dist/image-editor/stickers.d.ts +7 -2
- package/dist/image-editor/types.d.cts +7 -0
- package/dist/image-editor/types.d.ts +7 -0
- package/dist/paint-editor/brush-library-tools.d.cts +8 -1
- package/dist/paint-editor/brush-library-tools.d.ts +8 -1
- package/dist/paint-editor/controller.d.cts +7 -2
- package/dist/paint-editor/controller.d.ts +7 -2
- package/dist/paint-editor/index.cjs +581 -524
- package/dist/paint-editor/index.d.cts +1 -1
- package/dist/paint-editor/index.d.ts +1 -1
- package/dist/paint-editor/index.js +105 -48
- 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/controller.d.cts +13 -0
- package/dist/vector/controller.d.ts +13 -0
- package/dist/vector/index.cjs +1218 -1207
- package/dist/vector/index.js +19 -8
- package/dist/vector/stickers.d.cts +7 -2
- package/dist/vector/stickers.d.ts +7 -2
- package/package.json +1 -1
- package/skills/pixerate-brushes/SKILL.md +11 -3
- package/skills/pixerate-brushes-design/SKILL.md +1 -0
- package/skills/pixerate-stickers/SKILL.md +20 -9
- package/skills/pixerate-vector/SKILL.md +1 -1
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* `StickerBrowser`: the state behind a sticker picker, shared by the React and Svelte pickers. It
|
|
3
|
-
* searches or lists the provider a page at a time (search words, category), keeps the
|
|
4
|
-
* has loaded
|
|
3
|
+
* searches or lists the provider a page at a time (search words, category, collection), keeps the
|
|
4
|
+
* pages it has loaded, its categories and collections, and tells listeners when anything changes.
|
|
5
|
+
* UI-agnostic.
|
|
5
6
|
*/
|
|
6
|
-
import type { StickerProvider, StickerRef, StickerSummary } from './types.js';
|
|
7
|
+
import type { StickerCollection, StickerProvider, StickerRef, StickerSummary } from './types.js';
|
|
7
8
|
export interface StickerBrowserItem extends StickerSummary {
|
|
8
9
|
ref: StickerRef;
|
|
9
10
|
}
|
|
@@ -11,6 +12,8 @@ export interface StickerBrowserState {
|
|
|
11
12
|
query: string;
|
|
12
13
|
/** `''` for every category. */
|
|
13
14
|
category: string;
|
|
15
|
+
/** `''` for every collection. */
|
|
16
|
+
collection: string;
|
|
14
17
|
items: StickerBrowserItem[];
|
|
15
18
|
total: number;
|
|
16
19
|
/** More pages to load (`more()`). */
|
|
@@ -22,6 +25,8 @@ export interface StickerBrowserState {
|
|
|
22
25
|
name: string;
|
|
23
26
|
count: number;
|
|
24
27
|
}>;
|
|
28
|
+
/** The provider's collections (empty when it has none). */
|
|
29
|
+
collections: StickerCollection[];
|
|
25
30
|
/** The provider's name. */
|
|
26
31
|
provider: string;
|
|
27
32
|
}
|
|
@@ -42,6 +47,8 @@ export declare class StickerBrowser {
|
|
|
42
47
|
setQuery(query: string): Promise<void>;
|
|
43
48
|
/** Shows one category (`''` for all) from the first page. */
|
|
44
49
|
setCategory(category: string): Promise<void>;
|
|
50
|
+
/** Shows one collection (`''` for all) from the first page. */
|
|
51
|
+
setCollection(collection: string): Promise<void>;
|
|
45
52
|
/** Loads the next page onto the list. */
|
|
46
53
|
more(): Promise<void>;
|
|
47
54
|
private page;
|
|
@@ -3,6 +3,8 @@ import type { StickerProvider } from './types.cjs';
|
|
|
3
3
|
* One provider over several, in order. Its ids are refs (`provider:id`, `namespaced`), so the
|
|
4
4
|
* same id from two libraries stays two stickers. Pages run through the providers in turn; the
|
|
5
5
|
* cursor is `<provider index>|<that provider's cursor>`. Capabilities are what any of them offers.
|
|
6
|
+
* Collections are namespaced the same way (`provider:collection`), so a picker can tell a
|
|
7
|
+
* provider's collections apart from another provider's.
|
|
6
8
|
*/
|
|
7
9
|
export declare function combineStickerProviders(providers: readonly StickerProvider[], options?: {
|
|
8
10
|
id?: string;
|
|
@@ -3,6 +3,8 @@ import type { StickerProvider } from './types.js';
|
|
|
3
3
|
* One provider over several, in order. Its ids are refs (`provider:id`, `namespaced`), so the
|
|
4
4
|
* same id from two libraries stays two stickers. Pages run through the providers in turn; the
|
|
5
5
|
* cursor is `<provider index>|<that provider's cursor>`. Capabilities are what any of them offers.
|
|
6
|
+
* Collections are namespaced the same way (`provider:collection`), so a picker can tell a
|
|
7
|
+
* provider's collections apart from another provider's.
|
|
6
8
|
*/
|
|
7
9
|
export declare function combineStickerProviders(providers: readonly StickerProvider[], options?: {
|
|
8
10
|
id?: string;
|
|
@@ -13,6 +13,6 @@ export interface StickerConformanceOptions {
|
|
|
13
13
|
/**
|
|
14
14
|
* Checks a sticker provider against the contract: capabilities, every listed sticker (walking the
|
|
15
15
|
* pages), search and list agreeing, paging limits, describe and load for known and unknown ids,
|
|
16
|
-
* and tinting. Returns the problems found (empty when it conforms).
|
|
16
|
+
* collections, light / dark variants and tinting. Returns the problems found (empty when it conforms).
|
|
17
17
|
*/
|
|
18
18
|
export declare function checkStickerProvider(provider: StickerProvider, options?: StickerConformanceOptions): Promise<StickerConformanceIssue[]>;
|
|
@@ -13,6 +13,6 @@ export interface StickerConformanceOptions {
|
|
|
13
13
|
/**
|
|
14
14
|
* Checks a sticker provider against the contract: capabilities, every listed sticker (walking the
|
|
15
15
|
* pages), search and list agreeing, paging limits, describe and load for known and unknown ids,
|
|
16
|
-
* and tinting. Returns the problems found (empty when it conforms).
|
|
16
|
+
* collections, light / dark variants and tinting. Returns the problems found (empty when it conforms).
|
|
17
17
|
*/
|
|
18
18
|
export declare function checkStickerProvider(provider: StickerProvider, options?: StickerConformanceOptions): Promise<StickerConformanceIssue[]>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type StickerErrorCode = 'unknown_sticker' | 'unknown_provider' | 'unsupported_format' | 'no_provider' | 'load_failed' | 'invalid_argument';
|
|
1
|
+
export type StickerErrorCode = 'unknown_sticker' | 'unknown_provider' | 'unsupported_format' | 'unsupported_variant' | 'no_provider' | 'load_failed' | 'invalid_argument';
|
|
2
2
|
/** A refusal from a sticker provider or the sticker tools. The message says what to do instead. */
|
|
3
3
|
export declare class StickerError extends Error {
|
|
4
4
|
readonly code: StickerErrorCode;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type StickerErrorCode = 'unknown_sticker' | 'unknown_provider' | 'unsupported_format' | 'no_provider' | 'load_failed' | 'invalid_argument';
|
|
1
|
+
export type StickerErrorCode = 'unknown_sticker' | 'unknown_provider' | 'unsupported_format' | 'unsupported_variant' | 'no_provider' | 'load_failed' | 'invalid_argument';
|
|
2
2
|
/** A refusal from a sticker provider or the sticker tools. The message says what to do instead. */
|
|
3
3
|
export declare class StickerError extends Error {
|
|
4
4
|
readonly code: StickerErrorCode;
|
package/dist/stickers/fake.d.cts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* `createFakeStickerProvider()`: a small, deterministic sticker library for tests and demos (id
|
|
3
|
-
* `fake`). Flat badges are tintable; two-colour tiles are not
|
|
4
|
-
*
|
|
3
|
+
* `fake`). Flat badges are tintable; two-colour tiles are not, and have a dark variant (a pale top
|
|
4
|
+
* half); one sticker is for non-commercial use only; the weather set is AI-generated. Stickers are
|
|
5
|
+
* in collections (`outdoors`, `kitchen`, `shop`) but the sketch, which is in none. Art is a
|
|
6
|
+
* generated SVG and a PNG drawn to the same design, so it works in Node.
|
|
5
7
|
*/
|
|
6
8
|
import type { StickerProvider } from './types.cjs';
|
|
7
9
|
export interface FakeStickerProviderOptions {
|
package/dist/stickers/fake.d.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* `createFakeStickerProvider()`: a small, deterministic sticker library for tests and demos (id
|
|
3
|
-
* `fake`). Flat badges are tintable; two-colour tiles are not
|
|
4
|
-
*
|
|
3
|
+
* `fake`). Flat badges are tintable; two-colour tiles are not, and have a dark variant (a pale top
|
|
4
|
+
* half); one sticker is for non-commercial use only; the weather set is AI-generated. Stickers are
|
|
5
|
+
* in collections (`outdoors`, `kitchen`, `shop`) but the sketch, which is in none. Art is a
|
|
6
|
+
* generated SVG and a PNG drawn to the same design, so it works in Node.
|
|
5
7
|
*/
|
|
6
8
|
import type { StickerProvider } from './types.js';
|
|
7
9
|
export interface FakeStickerProviderOptions {
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* catalogue, `provider:id` refs, and the slot an editor keeps its provider in.
|
|
4
4
|
*/
|
|
5
5
|
import { type StampKind } from './stamps.cjs';
|
|
6
|
-
import type
|
|
6
|
+
import { type StickerCollection, type StickerPage, type StickerProvider, type StickerRef, type StickerSearchOptions, type StickerSummary, type StickerVariant } from './types.cjs';
|
|
7
7
|
/** Default and largest page size. */
|
|
8
8
|
export declare const DEFAULT_STICKER_PAGE = 24;
|
|
9
9
|
export declare const MAX_STICKER_PAGE = 100;
|
|
@@ -12,11 +12,25 @@ export declare const EDITOR_STICKERS_ID = "editor";
|
|
|
12
12
|
/** Checks search options, throwing a `StickerError` that names the bad one. */
|
|
13
13
|
export declare function checkStickerSearchOptions(options?: StickerSearchOptions): void;
|
|
14
14
|
/**
|
|
15
|
-
* One page of `items` filtered by `options` (category, every tag, commercial licence) and, when
|
|
15
|
+
* One page of `items` filtered by `options` (category, collection, every tag, commercial licence) and, when
|
|
16
16
|
* `query` has words, by every word appearing in the name, tags, category or description. Cursors
|
|
17
17
|
* are offsets as strings.
|
|
18
18
|
*/
|
|
19
19
|
export declare function stickerPage(items: readonly StickerSummary[], options?: StickerSearchOptions, query?: string): StickerPage;
|
|
20
|
+
/** The variants a sticker has (`light` always, first). */
|
|
21
|
+
export declare function stickerVariantsOf(s: Pick<StickerSummary, 'variants'>): StickerVariant[];
|
|
22
|
+
/**
|
|
23
|
+
* Checks `load`'s variant against the sticker's, throwing an `unsupported_variant` `StickerError`
|
|
24
|
+
* that names the ones it has. Providers call it at the top of `load`; returns the variant to draw.
|
|
25
|
+
*/
|
|
26
|
+
export declare function checkStickerVariant(s: Pick<StickerSummary, 'id' | 'variants'>, variant: StickerVariant | undefined): StickerVariant;
|
|
27
|
+
/** The variant to show on a dark or light background: `dark` when the background is dark and the sticker has it, else `light`. */
|
|
28
|
+
export declare function stickerVariantFor(s: Pick<StickerSummary, 'variants'>, dark: boolean): StickerVariant;
|
|
29
|
+
/** The collections of an in-memory catalogue with their counts, in first-seen order; `names` gives names and descriptions by id. */
|
|
30
|
+
export declare function stickerCollections(items: readonly StickerSummary[], names?: Record<string, {
|
|
31
|
+
name: string;
|
|
32
|
+
description?: string;
|
|
33
|
+
}>): StickerCollection[];
|
|
20
34
|
/** A ref split into provider and id. A bare editor stamp (`"star"`) is `editor:star`; any other bare id is refused. */
|
|
21
35
|
export declare function parseStickerRef(ref: StickerRef): {
|
|
22
36
|
provider: string;
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* catalogue, `provider:id` refs, and the slot an editor keeps its provider in.
|
|
4
4
|
*/
|
|
5
5
|
import { type StampKind } from './stamps.js';
|
|
6
|
-
import type
|
|
6
|
+
import { type StickerCollection, type StickerPage, type StickerProvider, type StickerRef, type StickerSearchOptions, type StickerSummary, type StickerVariant } from './types.js';
|
|
7
7
|
/** Default and largest page size. */
|
|
8
8
|
export declare const DEFAULT_STICKER_PAGE = 24;
|
|
9
9
|
export declare const MAX_STICKER_PAGE = 100;
|
|
@@ -12,11 +12,25 @@ export declare const EDITOR_STICKERS_ID = "editor";
|
|
|
12
12
|
/** Checks search options, throwing a `StickerError` that names the bad one. */
|
|
13
13
|
export declare function checkStickerSearchOptions(options?: StickerSearchOptions): void;
|
|
14
14
|
/**
|
|
15
|
-
* One page of `items` filtered by `options` (category, every tag, commercial licence) and, when
|
|
15
|
+
* One page of `items` filtered by `options` (category, collection, every tag, commercial licence) and, when
|
|
16
16
|
* `query` has words, by every word appearing in the name, tags, category or description. Cursors
|
|
17
17
|
* are offsets as strings.
|
|
18
18
|
*/
|
|
19
19
|
export declare function stickerPage(items: readonly StickerSummary[], options?: StickerSearchOptions, query?: string): StickerPage;
|
|
20
|
+
/** The variants a sticker has (`light` always, first). */
|
|
21
|
+
export declare function stickerVariantsOf(s: Pick<StickerSummary, 'variants'>): StickerVariant[];
|
|
22
|
+
/**
|
|
23
|
+
* Checks `load`'s variant against the sticker's, throwing an `unsupported_variant` `StickerError`
|
|
24
|
+
* that names the ones it has. Providers call it at the top of `load`; returns the variant to draw.
|
|
25
|
+
*/
|
|
26
|
+
export declare function checkStickerVariant(s: Pick<StickerSummary, 'id' | 'variants'>, variant: StickerVariant | undefined): StickerVariant;
|
|
27
|
+
/** The variant to show on a dark or light background: `dark` when the background is dark and the sticker has it, else `light`. */
|
|
28
|
+
export declare function stickerVariantFor(s: Pick<StickerSummary, 'variants'>, dark: boolean): StickerVariant;
|
|
29
|
+
/** The collections of an in-memory catalogue with their counts, in first-seen order; `names` gives names and descriptions by id. */
|
|
30
|
+
export declare function stickerCollections(items: readonly StickerSummary[], names?: Record<string, {
|
|
31
|
+
name: string;
|
|
32
|
+
description?: string;
|
|
33
|
+
}>): StickerCollection[];
|
|
20
34
|
/** A ref split into provider and id. A bare editor stamp (`"star"`) is `editor:star`; any other bare id is refused. */
|
|
21
35
|
export declare function parseStickerRef(ref: StickerRef): {
|
|
22
36
|
provider: string;
|
package/dist/stickers/index.cjs
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
var
|
|
6
|
+
var _chunkXORJ7UZOcjs = require('../chunk-XORJ7UZO.cjs');
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
|
|
@@ -11,7 +11,7 @@ var _chunkRVGP2XLFcjs = require('../chunk-RVGP2XLF.cjs');
|
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
|
|
14
|
-
var
|
|
14
|
+
var _chunkPE6YJMQTcjs = require('../chunk-PE6YJMQT.cjs');
|
|
15
15
|
|
|
16
16
|
|
|
17
17
|
|
|
@@ -27,7 +27,12 @@ var _chunkAVTPZO4Zcjs = require('../chunk-AVTPZO4Z.cjs');
|
|
|
27
27
|
|
|
28
28
|
|
|
29
29
|
|
|
30
|
-
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
var _chunkOTN6VB5Scjs = require('../chunk-OTN6VB5S.cjs');
|
|
31
36
|
|
|
32
37
|
|
|
33
38
|
var _chunkU67EN7GGcjs = require('../chunk-U67EN7GG.cjs');
|
|
@@ -39,11 +44,17 @@ require('../chunk-XFM3OCHU.cjs');
|
|
|
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];
|
|
@@ -97,26 +114,28 @@ function createFakeStickerProvider(options = {}) {
|
|
|
97
114
|
name: "Fake stickers",
|
|
98
115
|
version: "1",
|
|
99
116
|
capabilities: { supportsSearch: true, supportsSvg: true, supportsRaster: true, maxSize: 512 },
|
|
100
|
-
list: (o) =>
|
|
101
|
-
search: (q, o) =>
|
|
117
|
+
list: (o) => _chunkOTN6VB5Scjs.stickerPage.call(void 0, summaries, o),
|
|
118
|
+
search: (q, o) => _chunkOTN6VB5Scjs.stickerPage.call(void 0, summaries, o, q),
|
|
102
119
|
describe(id) {
|
|
103
120
|
const s = find(id);
|
|
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: () => _chunkOTN6VB5Scjs.stickerCollections.call(void 0, 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 (0, _chunkU67EN7GGcjs.StickerError)("unknown_sticker", `No fake sticker "${id}".`);
|
|
112
130
|
if (_optionalChain([options, 'access', _ => _.failIds, 'optionalAccess', _2 => _2.includes, 'call', _3 => _3(id)])) throw new (0, _chunkU67EN7GGcjs.StickerError)("load_failed", `The fake sticker "${id}" failed to load (failIds).`);
|
|
131
|
+
const variant = _chunkOTN6VB5Scjs.checkStickerVariant.call(void 0, 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 = _nullishCoalesce(o.size, () => ( 128));
|
|
116
135
|
if (!(Number.isInteger(size) && size >= 8 && size <= 512)) throw new (0, _chunkU67EN7GGcjs.StickerError)("invalid_argument", `size must be 8..512 px, got ${size}.`);
|
|
117
|
-
return { kind: "image", url: _chunkW5M3J7PVcjs.pngDataUrl.call(void 0, size, size, pixelsOf(s, size, fill)), width: size, height: size };
|
|
136
|
+
return { kind: "image", url: _chunkW5M3J7PVcjs.pngDataUrl.call(void 0, 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
|
}
|
|
@@ -128,15 +147,23 @@ function combineStickerProviders(providers, options = {}) {
|
|
|
128
147
|
if (dup) throw new (0, _chunkU67EN7GGcjs.StickerError)("invalid_argument", `Two sticker providers have the id "${dup}"; give each a unique id.`);
|
|
129
148
|
const byId = new Map(providers.map((p) => [p.id, p]));
|
|
130
149
|
const owner = (ref) => {
|
|
131
|
-
const { provider, id } =
|
|
150
|
+
const { provider, id } = _chunkOTN6VB5Scjs.parseStickerRef.call(void 0, ref);
|
|
132
151
|
const p = byId.get(provider);
|
|
133
152
|
if (!p) throw new (0, _chunkU67EN7GGcjs.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: _chunkOTN6VB5Scjs.stickerRefOf.call(void 0, 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 (0, _chunkU67EN7GGcjs.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 =
|
|
139
|
-
|
|
164
|
+
const { after, limit = _chunkOTN6VB5Scjs.DEFAULT_STICKER_PAGE, collection, ...filters } = o;
|
|
165
|
+
_chunkOTN6VB5Scjs.checkStickerSearchOptions.call(void 0, { 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 _asyncNullishCoalesce(await _optionalChain([p, 'access', _8 => _8.listCollections, 'optionalCall', _9 => _9()]), async () => ( []))) out.push({ ...c, id: collectionOf(p, c.id) });
|
|
238
|
+
return out;
|
|
203
239
|
}
|
|
204
240
|
};
|
|
205
241
|
}
|
|
@@ -214,12 +250,20 @@ function checkSummary(s, provider, issues) {
|
|
|
214
250
|
if (typeof s.category !== "string" || !s.category) at("category is missing");
|
|
215
251
|
if (!(s.width > 0 && s.height > 0)) at(`width and height must be positive, got ${s.width} \xD7 ${s.height}`);
|
|
216
252
|
if (!Array.isArray(s.formats) || !s.formats.length || s.formats.some((f) => f !== "svg" && f !== "png")) at("formats must list svg and / or png");
|
|
217
|
-
if (_optionalChain([s, 'access',
|
|
218
|
-
if (_optionalChain([s, 'access',
|
|
253
|
+
if (_optionalChain([s, 'access', _10 => _10.formats, 'optionalAccess', _11 => _11.includes, 'call', _12 => _12("svg")]) && !provider.capabilities.supportsSvg) at("lists svg but capabilities.supportsSvg is false");
|
|
254
|
+
if (_optionalChain([s, 'access', _13 => _13.formats, 'optionalAccess', _14 => _14.includes, 'call', _15 => _15("png")]) && !provider.capabilities.supportsRaster) at("lists png but capabilities.supportsRaster is false");
|
|
219
255
|
if (!s.licence || typeof s.licence.name !== "string" || !s.licence.name) at("licence.name is missing (every sticker says how it may be used)");
|
|
220
|
-
if (typeof _optionalChain([s, 'access',
|
|
256
|
+
if (typeof _optionalChain([s, 'access', _16 => _16.licence, 'optionalAccess', _17 => _17.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 = [];
|
|
@@ -228,8 +272,8 @@ async function checkStickerProvider(provider, options = {}) {
|
|
|
228
272
|
else if (provider.id.includes(":")) top('provider id contains ":"');
|
|
229
273
|
if (typeof provider.name !== "string" || !provider.name) top("provider has no name");
|
|
230
274
|
const caps = provider.capabilities;
|
|
231
|
-
for (const k of ["supportsSearch", "supportsSvg", "supportsRaster"]) if (typeof _optionalChain([caps, 'optionalAccess',
|
|
232
|
-
if (_optionalChain([caps, 'optionalAccess',
|
|
275
|
+
for (const k of ["supportsSearch", "supportsSvg", "supportsRaster"]) if (typeof _optionalChain([caps, 'optionalAccess', _18 => _18[k]]) !== "boolean") top(`capabilities.${k} is not a boolean`);
|
|
276
|
+
if (_optionalChain([caps, 'optionalAccess', _19 => _19.maxSize]) !== void 0 && !(caps.maxSize > 0)) top("capabilities.maxSize must be positive");
|
|
233
277
|
const all = [];
|
|
234
278
|
const ids = /* @__PURE__ */ new Set();
|
|
235
279
|
let after;
|
|
@@ -242,7 +286,7 @@ async function checkStickerProvider(provider, options = {}) {
|
|
|
242
286
|
top(`list() rejected: ${e.message}`);
|
|
243
287
|
break;
|
|
244
288
|
}
|
|
245
|
-
if (!Array.isArray(_optionalChain([page, 'optionalAccess',
|
|
289
|
+
if (!Array.isArray(_optionalChain([page, 'optionalAccess', _20 => _20.items])) || typeof page.total !== "number") {
|
|
246
290
|
top("list() did not return { items, total }");
|
|
247
291
|
break;
|
|
248
292
|
}
|
|
@@ -275,9 +319,29 @@ async function checkStickerProvider(provider, options = {}) {
|
|
|
275
319
|
const d = await provider.describe(first.id);
|
|
276
320
|
if (!d) top(`describe("${first.id}") returned nothing for a listed sticker`);
|
|
277
321
|
else if (d.id !== first.id) top(`describe("${first.id}") returned id "${d.id}"`);
|
|
278
|
-
if (_optionalChain([d, 'optionalAccess',
|
|
322
|
+
if (_optionalChain([d, 'optionalAccess', _21 => _21.colours, 'optionalAccess', _22 => _22.some, 'call', _23 => _23((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 _optionalChain([c, 'optionalAccess', _24 => _24.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) => _optionalChain([s, 'access', _25 => _25.variants, 'optionalAccess', _26 => _26.includes, 'call', _27 => _27("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) => !_optionalChain([s, 'access', _28 => _28.variants, 'optionalAccess', _29 => _29.includes, 'call', _30 => _30("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 (e4) {
|
|
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 {
|
|
@@ -336,4 +418,9 @@ async function checkStickerProvider(provider, options = {}) {
|
|
|
336
418
|
|
|
337
419
|
|
|
338
420
|
|
|
339
|
-
|
|
421
|
+
|
|
422
|
+
|
|
423
|
+
|
|
424
|
+
|
|
425
|
+
|
|
426
|
+
exports.DEFAULT_STICKER_PAGE = _chunkOTN6VB5Scjs.DEFAULT_STICKER_PAGE; exports.EDITOR_STICKERS_ID = _chunkOTN6VB5Scjs.EDITOR_STICKERS_ID; exports.MAX_STICKER_PAGE = _chunkOTN6VB5Scjs.MAX_STICKER_PAGE; exports.STAMP_KINDS = _chunkOTN6VB5Scjs.STAMP_KINDS; exports.STICKER_VARIANTS = _chunkOTN6VB5Scjs.STICKER_VARIANTS; exports.StickerBrowser = _chunkXORJ7UZOcjs.StickerBrowser; exports.StickerError = _chunkU67EN7GGcjs.StickerError; exports.StickersSlot = _chunkOTN6VB5Scjs.StickersSlot; exports.checkStickerProvider = checkStickerProvider; exports.checkStickerSearchOptions = _chunkOTN6VB5Scjs.checkStickerSearchOptions; exports.checkStickerVariant = _chunkOTN6VB5Scjs.checkStickerVariant; exports.closestStickerRefs = _chunkOTN6VB5Scjs.closestStickerRefs; exports.combineStickerProviders = combineStickerProviders; exports.createFakeStickerProvider = createFakeStickerProvider; exports.createInsertStickerTool = _chunkPE6YJMQTcjs.createInsertStickerTool; exports.createStickerToolProvider = _chunkPE6YJMQTcjs.createStickerToolProvider; exports.createStickerTools = _chunkPE6YJMQTcjs.createStickerTools; exports.describeStickerRef = _chunkPE6YJMQTcjs.describeStickerRef; exports.editorStampOf = _chunkOTN6VB5Scjs.editorStampOf; exports.editorStickers = _chunkXORJ7UZOcjs.editorStickers; exports.insertSticker = _chunkPE6YJMQTcjs.insertSticker; exports.normalizeStickerRef = _chunkOTN6VB5Scjs.normalizeStickerRef; exports.parseStickerRef = _chunkOTN6VB5Scjs.parseStickerRef; exports.stampCoverage = _chunkOTN6VB5Scjs.stampCoverage; exports.stampOutline = _chunkXORJ7UZOcjs.stampOutline; exports.stampPixels = _chunkXORJ7UZOcjs.stampPixels; exports.stickerCollections = _chunkOTN6VB5Scjs.stickerCollections; exports.stickerForAgent = _chunkPE6YJMQTcjs.stickerForAgent; exports.stickerIdFor = _chunkOTN6VB5Scjs.stickerIdFor; exports.stickerPage = _chunkOTN6VB5Scjs.stickerPage; exports.stickerRefOf = _chunkOTN6VB5Scjs.stickerRefOf; exports.stickerVariantFor = _chunkOTN6VB5Scjs.stickerVariantFor; exports.stickerVariantsOf = _chunkOTN6VB5Scjs.stickerVariantsOf;
|