@pixerate/editor 0.261.0 → 0.262.1

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.
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  parseSkillFrontmatter
3
- } from "./chunk-ABHOYBZD.js";
3
+ } from "./chunk-K4BGRCSH.js";
4
4
  import {
5
5
  readingTime
6
6
  } from "./chunk-EHTX34RE.js";
@@ -596,6 +596,160 @@ function createOriginMiddleware(options) {
596
596
  };
597
597
  }
598
598
 
599
+ // src/tools/conformance.ts
600
+ var ConformanceIds = class {
601
+ toPlaceholder = /* @__PURE__ */ new Map();
602
+ fromPlaceholder = /* @__PURE__ */ new Map();
603
+ /** The placeholder for `id`, assigning the next one when it is new. */
604
+ add(id) {
605
+ let placeholder = this.toPlaceholder.get(id);
606
+ if (!placeholder) {
607
+ placeholder = `@${this.toPlaceholder.size + 1}`;
608
+ this.toPlaceholder.set(id, placeholder);
609
+ this.fromPlaceholder.set(placeholder, id);
610
+ }
611
+ return placeholder;
612
+ }
613
+ placeholder(id) {
614
+ return this.toPlaceholder.get(id);
615
+ }
616
+ /** `text` with every known id in it replaced by its placeholder (longest ids first). */
617
+ replaceWithin(text) {
618
+ const exact = this.toPlaceholder.get(text);
619
+ if (exact) return exact;
620
+ let out = text;
621
+ for (const id of [...this.toPlaceholder.keys()].sort((a, b) => b.length - a.length)) {
622
+ if (out.includes(id)) out = out.split(id).join(this.toPlaceholder.get(id));
623
+ }
624
+ return out;
625
+ }
626
+ /** The real id a placeholder stands for. */
627
+ resolve(placeholder) {
628
+ return this.fromPlaceholder.get(placeholder);
629
+ }
630
+ };
631
+ var PLACEHOLDER = /^@[1-9][0-9]*$/;
632
+ var TIMESTAMP = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?(Z|[+-]\d{2}:\d{2})$/;
633
+ var BASE64 = /^[A-Za-z0-9+/=_-]+$/;
634
+ var CONFORMANCE_BINARY_MIN_LENGTH = 200;
635
+ function isBinary(value) {
636
+ return value.startsWith("data:") || value.length >= CONFORMANCE_BINARY_MIN_LENGTH && BASE64.test(value);
637
+ }
638
+ function sortedKeys(value) {
639
+ return Object.keys(value).sort((a, b) => a < b ? -1 : a > b ? 1 : 0);
640
+ }
641
+ function collectIds(value, ids, isId) {
642
+ if (typeof value === "string") {
643
+ if (isId(value)) ids.add(value);
644
+ return;
645
+ }
646
+ if (Array.isArray(value)) {
647
+ for (const item of value) collectIds(item, ids, isId);
648
+ return;
649
+ }
650
+ if (value && typeof value === "object") {
651
+ for (const k of sortedKeys(value)) {
652
+ if (isId(k)) ids.add(k);
653
+ collectIds(value[k], ids, isId);
654
+ }
655
+ }
656
+ }
657
+ function replaceIds(value, ids) {
658
+ if (typeof value === "string") return isBinary(value) ? "<binary>" : TIMESTAMP.test(value) ? "<time>" : ids.replaceWithin(value);
659
+ if (Array.isArray(value)) return value.map((item) => replaceIds(item, ids));
660
+ if (value && typeof value === "object") {
661
+ const out = {};
662
+ for (const k of sortedKeys(value)) out[ids.replaceWithin(k)] = replaceIds(value[k], ids);
663
+ return out;
664
+ }
665
+ return value;
666
+ }
667
+ function normalizeConformanceValue(value, ids, isGeneratedId = () => false) {
668
+ const json = value === void 0 ? null : JSON.parse(JSON.stringify(value));
669
+ collectIds(json, ids, (v) => !PLACEHOLDER.test(v) && isGeneratedId(v));
670
+ return replaceIds(json, ids);
671
+ }
672
+ function omitConformancePaths(value, paths) {
673
+ let out = value === void 0 ? null : JSON.parse(JSON.stringify(value));
674
+ for (const path of paths) out = omitPath(out, path.split("/").slice(1));
675
+ return out;
676
+ }
677
+ function omitPath(value, parts) {
678
+ if (!value || typeof value !== "object" || parts.length === 0) return value;
679
+ const [head, ...rest] = parts;
680
+ if (Array.isArray(value)) {
681
+ if (head === "*") return value.map((item) => omitPath(item, rest));
682
+ const i = Number(head);
683
+ if (!Number.isInteger(i) || i < 0 || i >= value.length) return value;
684
+ if (rest.length === 0) return value.filter((_, j) => j !== i);
685
+ return value.map((item, j) => j === i ? omitPath(item, rest) : item);
686
+ }
687
+ const object = value;
688
+ const keys = head === "*" ? Object.keys(object) : head in object ? [head] : [];
689
+ for (const key of keys) {
690
+ if (rest.length === 0) delete object[key];
691
+ else object[key] = omitPath(object[key], rest);
692
+ }
693
+ return object;
694
+ }
695
+ function resolveConformanceArguments(value, ids) {
696
+ if (typeof value === "string" && PLACEHOLDER.test(value)) {
697
+ const id = ids.resolve(value);
698
+ if (id === void 0) throw new Error(`Placeholder ${value} is used before any result returned that id.`);
699
+ return id;
700
+ }
701
+ if (Array.isArray(value)) return value.map((item) => resolveConformanceArguments(item, ids));
702
+ if (value && typeof value === "object") {
703
+ const out = {};
704
+ for (const [k, v] of Object.entries(value)) out[k] = resolveConformanceArguments(v, ids);
705
+ return out;
706
+ }
707
+ return value;
708
+ }
709
+ function conformanceResult(result) {
710
+ if (result.isError) {
711
+ const error = result.structuredContent?.error ?? {};
712
+ const value = { code: error.code ?? "tool_failed", message: error.message ?? resultText(result) ?? "", ...error.details !== void 0 ? { details: error.details } : {} };
713
+ return { value: { error: value }, isError: true };
714
+ }
715
+ if (result.structuredContent !== void 0) return { value: result.structuredContent, isError: false };
716
+ const text = resultText(result);
717
+ if (text === void 0) return { value: null, isError: false };
718
+ try {
719
+ return { value: JSON.parse(text), isError: false };
720
+ } catch {
721
+ return { value: text, isError: false };
722
+ }
723
+ }
724
+ function resultText(result) {
725
+ for (const content of result.content) {
726
+ if (content.type === "text" && "text" in content && typeof content.text === "string") return content.text;
727
+ }
728
+ return void 0;
729
+ }
730
+ async function runConformanceScenario(scenario, host) {
731
+ const ids = new ConformanceIds();
732
+ const isId = host.isGeneratedId?.bind(host);
733
+ const outputs = [];
734
+ try {
735
+ for (const step of scenario.steps) {
736
+ const args = resolveConformanceArguments(step.arguments ?? {}, ids);
737
+ const { value, isError } = conformanceResult(await host.callTool(step.tool, args));
738
+ const result = normalizeConformanceValue(value, ids, isId);
739
+ const output = { result: step.ignore ? omitConformancePaths(result, step.ignore) : result, isError };
740
+ if (step.document) output.document = normalizeConformanceValue(host.document(), ids, isId);
741
+ if (step.pixels) {
742
+ const image = host.pixels({ paper: typeof step.pixels === "object" ? step.pixels.paper : void 0 });
743
+ output.pixels = { width: image.width, height: image.height, data: new Uint8Array(image.data.buffer, image.data.byteOffset, image.data.byteLength) };
744
+ }
745
+ outputs.push(output);
746
+ }
747
+ } finally {
748
+ host.dispose?.();
749
+ }
750
+ return outputs;
751
+ }
752
+
599
753
  export {
600
754
  listSkillEvals,
601
755
  imageEvalFixturePixels,
@@ -611,5 +765,12 @@ export {
611
765
  runStyleChecks,
612
766
  renderStyle,
613
767
  createStyleToolProvider,
614
- createOriginMiddleware
768
+ createOriginMiddleware,
769
+ ConformanceIds,
770
+ CONFORMANCE_BINARY_MIN_LENGTH,
771
+ normalizeConformanceValue,
772
+ omitConformancePaths,
773
+ resolveConformanceArguments,
774
+ conformanceResult,
775
+ runConformanceScenario
615
776
  };
@@ -9,7 +9,9 @@
9
9
  * package version, so a release does not change the files.
10
10
  */
11
11
  import type { EffectProvider } from '../effects/types.cjs';
12
+ import type { ConformanceHost } from '../tools/conformance.cjs';
12
13
  import type { JsonSchema } from '../tools/schema.cjs';
14
+ import { type PaintEditorOptions } from './controller.cjs';
13
15
  /** Bumped when a contract file changes shape (not when its data changes). */
14
16
  export declare const PAINT_CONTRACT_FORMAT_VERSION = 1;
15
17
  /**
@@ -27,3 +29,12 @@ export declare const PAINT_DOCUMENT_JSON_SCHEMA: JsonSchema;
27
29
  export declare function paintContracts(options: {
28
30
  effects: EffectProvider;
29
31
  }): Record<string, unknown>;
32
+ /**
33
+ * A fresh paint editor for replaying a conformance scenario (`domains/paint/fixtures`): every paint
34
+ * tool provider in one registry that validates arguments, the saved document (the
35
+ * `pixerate.editor-document` envelope) and the composited pixels. `setup` is the scenario's
36
+ * editor options, such as `{ width, height }`; `effects` is the effect provider the effect tools use.
37
+ */
38
+ export declare function createPaintConformanceHost(setup: PaintEditorOptions, options: {
39
+ effects: EffectProvider;
40
+ }): ConformanceHost;
@@ -9,7 +9,9 @@
9
9
  * package version, so a release does not change the files.
10
10
  */
11
11
  import type { EffectProvider } from '../effects/types.js';
12
+ import type { ConformanceHost } from '../tools/conformance.js';
12
13
  import type { JsonSchema } from '../tools/schema.js';
14
+ import { type PaintEditorOptions } from './controller.js';
13
15
  /** Bumped when a contract file changes shape (not when its data changes). */
14
16
  export declare const PAINT_CONTRACT_FORMAT_VERSION = 1;
15
17
  /**
@@ -27,3 +29,12 @@ export declare const PAINT_DOCUMENT_JSON_SCHEMA: JsonSchema;
27
29
  export declare function paintContracts(options: {
28
30
  effects: EffectProvider;
29
31
  }): Record<string, unknown>;
32
+ /**
33
+ * A fresh paint editor for replaying a conformance scenario (`domains/paint/fixtures`): every paint
34
+ * tool provider in one registry that validates arguments, the saved document (the
35
+ * `pixerate.editor-document` envelope) and the composited pixels. `setup` is the scenario's
36
+ * editor options, such as `{ width, height }`; `effects` is the effect provider the effect tools use.
37
+ */
38
+ export declare function createPaintConformanceHost(setup: PaintEditorOptions, options: {
39
+ effects: EffectProvider;
40
+ }): ConformanceHost;
@@ -21,6 +21,9 @@ var _chunkAVTPZO4Zcjs = require('../chunk-AVTPZO4Z.cjs');
21
21
  var _chunkCBVNCWJMcjs = require('../chunk-CBVNCWJM.cjs');
22
22
 
23
23
 
24
+ var _chunk7TD63DZPcjs = require('../chunk-7TD63DZP.cjs');
25
+
26
+
24
27
 
25
28
 
26
29
 
@@ -279,6 +282,7 @@ require('../chunk-UWEQ55MY.cjs');
279
282
 
280
283
 
281
284
 
285
+
282
286
  var _chunkSJ2CPTQCcjs = require('../chunk-SJ2CPTQC.cjs');
283
287
  require('../chunk-2BSBFBOA.cjs');
284
288
  require('../chunk-4ZC5QJE2.cjs');
@@ -10878,7 +10882,7 @@ function createPaintWetTools(c) {
10878
10882
  {
10879
10883
  name: "get_wet_paint",
10880
10884
  title: "Get the wet paint",
10881
- description: "Reads the wet media: whether any paint is still wet, the simulation clock (steps), whether time is paused, its speed (steps per second), the canvas tilt, the kernel running it (typescript, wasm, wasm-threads with the thread count, and a message when it runs slower than it could, e.g. without cross-origin isolation), and each wet layer: wet cells, where the water is (wetBounds), live tiles, its settings and flow map. Also engine: Engine B, the WebGPU accelerator (mode auto/off, state, reason, adapter, minTiles, activeTiles). Call it after wet strokes to see what is still wet.",
10885
+ description: "Reads the wet media: whether any paint is still wet, the simulation clock (steps), whether time is paused, its speed (steps per second), the canvas tilt, the kernel running it (typescript, wasm, wasm-threads with the thread count, and a message when it runs slower than it could, e.g. without cross-origin isolation), and each wet layer: wet cells, where the water is (wetBounds), live tiles, its settings and flow map. Also engine: Engine B, the GPU accelerator: WebGPU in browsers, Metal in the Swift editors (mode auto/off, state, reason, adapter, minTiles, activeTiles). Call it after wet strokes to see what is still wet.",
10882
10886
  inputSchema: EMPTY2,
10883
10887
  annotations: { title: "Get the wet paint", ...READ3 },
10884
10888
  coordinates: { out: ["layers[].wetBounds", "layers[].flow.center"] },
@@ -11015,7 +11019,7 @@ function createPaintWetTools(c) {
11015
11019
  {
11016
11020
  name: "set_wet_engine",
11017
11021
  title: "Choose the wet-media engine",
11018
- description: 'Lets Engine B, the WebGPU accelerator, run for large wet areas (gpu "auto", the default) or forces the CPU (gpu "off"), and optionally sets minTiles, the wet area at which the GPU takes over. The GPU only shades what is shown: the CPU engine stays the authority, so the painting, drying, saving, export and replay come out the same either way; force the CPU when the display looks wrong or the GPU is busy with other work. Editor setting, not an undo step, not saved with the painting. Returns the engine: mode, state (off, not-started, starting, unavailable, standby, active, failed), reason, adapter, maxTiles, minTiles and activeTiles.',
11022
+ description: 'Lets Engine B, the GPU accelerator (WebGPU in browsers, Metal in the Swift editors), run for large wet areas (gpu "auto", the default) or forces the CPU (gpu "off"), and optionally sets minTiles, the wet area at which the GPU takes over. The GPU only shades what is shown: the CPU engine stays the authority, so the painting, drying, saving, export and replay come out the same either way; force the CPU when the display looks wrong or the GPU is busy with other work. Editor setting, not an undo step, not saved with the painting. Returns the engine: mode, state (off, not-started, starting, unavailable, standby, active, failed), reason, adapter, maxTiles, minTiles and activeTiles.',
11019
11023
  inputSchema: {
11020
11024
  type: "object",
11021
11025
  properties: {
@@ -13446,6 +13450,24 @@ function paintContracts(options) {
13446
13450
  };
13447
13451
  return files;
13448
13452
  }
13453
+ var GENERATED_ID = /^(pl[0-9a-z]{9,}|[a-z]+_[0-9a-z]{8,}_[0-9a-z]+)$/;
13454
+ function createPaintConformanceHost(setup, options) {
13455
+ const controller = new PaintEditorController({ ...setup, wet: { kernel: "typescript", threads: 0, gpu: "off", ...setup.wet } });
13456
+ controller.setEffectsProvider(options.effects);
13457
+ const registry = new (0, _chunk7TD63DZPcjs.ToolRegistry)({ validateArguments: true });
13458
+ registry.register(createPaintEditorToolProvider(controller));
13459
+ registry.register(createPaintEffectsToolProvider(controller));
13460
+ registry.register(createPaintBrushLibraryToolProvider(controller));
13461
+ registry.register(createPaintProposalToolProvider(createPaintProposals({ controller })));
13462
+ return {
13463
+ callTool: (name, args) => registry.callTool(name, args),
13464
+ document: () => _chunkSJ2CPTQCcjs.toEditorDocumentFile.call(void 0, createPaintEditorDocument(controller)),
13465
+ pixels: ({ paper }) => controller.compositePixels({ paper }),
13466
+ isGeneratedId: (value) => GENERATED_ID.test(value),
13467
+ dispose: () => controller.dispose()
13468
+ };
13469
+ }
13470
+
13449
13471
 
13450
13472
 
13451
13473
 
@@ -13809,4 +13831,4 @@ function paintContracts(options) {
13809
13831
 
13810
13832
 
13811
13833
 
13812
- exports.BACKLIGHT_SPILL = BACKLIGHT_SPILL; exports.BLEND_MENU_GROUPS = BLEND_MENU_GROUPS; exports.BLEND_MODES = _chunk2VX55NFMcjs.BLEND_MODES; exports.BRUSH_ID = _chunkTZOX7KWVcjs.BRUSH_ID; exports.BRUSH_ROTATIONS = _chunkTZOX7KWVcjs.BRUSH_ROTATIONS; exports.BRUSH_SLIDERS = _chunkPYTJBVW5cjs.BRUSH_SLIDERS; exports.BUILTIN_BRUSHES = _chunkTZOX7KWVcjs.BUILTIN_BRUSHES; exports.BristleStroke = BristleStroke; exports.DEFAULT_BACKLIGHT_COLOR = DEFAULT_BACKLIGHT_COLOR; exports.DEFAULT_BEHAVIOR = _chunkTZOX7KWVcjs.DEFAULT_BEHAVIOR; exports.DEFAULT_BRISTLE = _chunkTZOX7KWVcjs.DEFAULT_BRISTLE; exports.DEFAULT_BRUSH_ID = _chunkTZOX7KWVcjs.DEFAULT_BRUSH_ID; exports.DEFAULT_DPI = DEFAULT_DPI; exports.DEFAULT_DYNAMICS = _chunkTZOX7KWVcjs.DEFAULT_DYNAMICS; exports.DEFAULT_FLOW = _chunkYHDHFJUCcjs.DEFAULT_FLOW; exports.DEFAULT_IMPASTO = _chunkTZOX7KWVcjs.DEFAULT_IMPASTO; exports.DEFAULT_LIGHT = _chunkTZOX7KWVcjs.DEFAULT_LIGHT; exports.DEFAULT_LIGHTING = DEFAULT_LIGHTING; exports.DEFAULT_MULTI_COLOR = _chunkTZOX7KWVcjs.DEFAULT_MULTI_COLOR; exports.DEFAULT_PAINT_GRADIENT = _chunkFQPUF2W2cjs.DEFAULT_PAINT_GRADIENT; exports.DEFAULT_PAINT_GRADIENT_MAPPING = _chunkFQPUF2W2cjs.DEFAULT_PAINT_GRADIENT_MAPPING; exports.DEFAULT_PAPER = DEFAULT_PAPER; exports.DEFAULT_PARTICLE = _chunkTZOX7KWVcjs.DEFAULT_PARTICLE; exports.DEFAULT_SPRAY = _chunkTZOX7KWVcjs.DEFAULT_SPRAY; exports.DEFAULT_STICKER = _chunkTZOX7KWVcjs.DEFAULT_STICKER; exports.DEFAULT_SWATCHES = DEFAULT_SWATCHES; exports.DEFAULT_VIEW = DEFAULT_VIEW; exports.DEFAULT_WET_BRUSH = _chunkTZOX7KWVcjs.DEFAULT_WET_BRUSH; exports.DEFAULT_WET_PARAMS = _chunkYHDHFJUCcjs.DEFAULT_WET_PARAMS; exports.DOT_ROTATIONS = _chunkTZOX7KWVcjs.DOT_ROTATIONS; exports.DOT_ROTATION_LABELS = DOT_ROTATION_LABELS; exports.DOT_TEXTURE_ORDERS = _chunkTZOX7KWVcjs.DOT_TEXTURE_ORDERS; exports.DOT_TEXTURE_ORDER_LABELS = DOT_TEXTURE_ORDER_LABELS; exports.DryStroke = DryStroke; exports.EFFECT_MAP_REPEATS = EFFECT_MAP_REPEATS; exports.EFFECT_STRIP_HEIGHT = EFFECT_STRIP_HEIGHT; exports.GPU_LEAD = GPU_LEAD; exports.GRAIN_PATTERNS = _chunkPXDIAYB6cjs.GRAIN_PATTERNS; exports.GRAIN_TILE = _chunkPXDIAYB6cjs.GRAIN_TILE; exports.HARMONY_KINDS = _chunkI3Y2Q3PMcjs.HARMONY_KINDS; exports.IDENTITY_AFFINE = IDENTITY_AFFINE; exports.IDENTITY_COPY = IDENTITY_COPY; exports.IMPASTO_TOOLS = _chunkTZOX7KWVcjs.IMPASTO_TOOLS; exports.IMPASTO_TOOL_LABELS = IMPASTO_TOOL_LABELS; exports.LIGHT_SLIDERS = LIGHT_SLIDERS; exports.LIVE_STROKE_ENGINES = LIVE_STROKE_ENGINES; exports.LitCache = LitCache; exports.MAX_BRUSH_SIZE = _chunkFQPUF2W2cjs.MAX_BRUSH_SIZE; exports.MAX_CANVAS_SIDE = MAX_CANVAS_SIDE; exports.MAX_COORDINATE = MAX_COORDINATE; exports.MAX_DOT_TEXTURES = _chunkTZOX7KWVcjs.MAX_DOT_TEXTURES; exports.MAX_IMAGE_SIDE = MAX_IMAGE_SIDE; exports.MAX_LIVE_EFFECT_SOURCES = MAX_LIVE_EFFECT_SOURCES; exports.MAX_PATH_SAMPLES = MAX_PATH_SAMPLES; exports.MAX_STICKER_STAMPS = _chunkTZOX7KWVcjs.MAX_STICKER_STAMPS; exports.MAX_ZOOM = MAX_ZOOM; exports.MIN_CANVAS_SIDE = MIN_CANVAS_SIDE; exports.MIN_ZOOM = MIN_ZOOM; exports.MIXING_PAD_HEIGHT = MIXING_PAD_HEIGHT; exports.MIXING_PAD_WIDTH = MIXING_PAD_WIDTH; exports.MULTI_COLOR_MODES = _chunkTZOX7KWVcjs.MULTI_COLOR_MODES; exports.MixingPad = MixingPad; exports.PAD_SAMPLE_SIZES = PAD_SAMPLE_SIZES; exports.PAINTERLY_BLEND_MODES = _chunk2VX55NFMcjs.PAINTERLY_BLEND_MODES; exports.PAINT_BRUSH_CATEGORIES = _chunkTZOX7KWVcjs.PAINT_BRUSH_CATEGORIES; exports.PAINT_BRUSH_ENGINES = _chunkTZOX7KWVcjs.PAINT_BRUSH_ENGINES; exports.PAINT_COLOR_JSON_SCHEMA = _chunkFQPUF2W2cjs.PAINT_COLOR_JSON_SCHEMA; exports.PAINT_CONTRACT_FORMAT_VERSION = PAINT_CONTRACT_FORMAT_VERSION; exports.PAINT_DOCUMENT_JSON_SCHEMA = PAINT_DOCUMENT_JSON_SCHEMA; exports.PAINT_EFFECT_PLACES = PAINT_EFFECT_PLACES; exports.PAINT_FORMAT = PAINT_FORMAT; exports.PAINT_GRADIENT_FULL_SPEED = _chunkFQPUF2W2cjs.PAINT_GRADIENT_FULL_SPEED; exports.PAINT_GRADIENT_JSON_SCHEMA = _chunkFQPUF2W2cjs.PAINT_GRADIENT_JSON_SCHEMA; exports.PAINT_GRADIENT_KIT = _chunkFQPUF2W2cjs.PAINT_GRADIENT_KIT; exports.PAINT_GRADIENT_MAPPINGS = _chunkFQPUF2W2cjs.PAINT_GRADIENT_MAPPINGS; exports.PAINT_GRADIENT_MAPPING_LABELS = _chunkFQPUF2W2cjs.PAINT_GRADIENT_MAPPING_LABELS; exports.PAINT_GRADIENT_PRESETS = _chunkFQPUF2W2cjs.PAINT_GRADIENT_PRESETS; exports.PAINT_GRADIENT_REPEATS = _chunkFQPUF2W2cjs.PAINT_GRADIENT_REPEATS; exports.PAINT_GRADIENT_REPEAT_LABELS = _chunkFQPUF2W2cjs.PAINT_GRADIENT_REPEAT_LABELS; exports.PAINT_GRADIENT_SPACES = _chunkFQPUF2W2cjs.PAINT_GRADIENT_SPACES; exports.PAINT_GRADIENT_SPACE_LABELS = _chunkFQPUF2W2cjs.PAINT_GRADIENT_SPACE_LABELS; exports.PAINT_SCHEMA_VERSION = PAINT_SCHEMA_VERSION; exports.PAINT_SHORTCUTS = PAINT_SHORTCUTS; exports.PAINT_SOURCE_JSON_SCHEMA = _chunkFQPUF2W2cjs.PAINT_SOURCE_JSON_SCHEMA; exports.PAINT_TARGET = PAINT_TARGET; exports.PAINT_TOOLS = PAINT_TOOLS; exports.PAPER_EFFECT_BLENDS = PAPER_EFFECT_BLENDS; exports.PAPER_EFFECT_NODE_ID = PAPER_EFFECT_NODE_ID; exports.PAPER_FAMILIES = PAPER_FAMILIES; exports.PAPER_LIBRARY = PAPER_LIBRARY; exports.PAPER_NODE_ID = PAPER_NODE_ID; exports.PAPER_SLIDERS = PAPER_SLIDERS; exports.PAPER_TARGET = PAPER_TARGET; exports.PARTICLE_KINDS = _chunkTZOX7KWVcjs.PARTICLE_KINDS; exports.PARTICLE_KIND_LABELS = PARTICLE_KIND_LABELS; exports.PARTICLE_RENDERS = _chunkTZOX7KWVcjs.PARTICLE_RENDERS; exports.PARTICLE_RENDER_LABELS = PARTICLE_RENDER_LABELS; exports.PATH_STROKE_TAPERS = PATH_STROKE_TAPERS; exports.PaintCanvasPresenter = PaintCanvasPresenter; exports.PaintDabStroke = PaintDabStroke; exports.PaintDirector = PaintDirector; exports.PaintDocumentError = PaintDocumentError; exports.PaintEditorController = PaintEditorController; exports.PaintEditorError = PaintEditorError; exports.PaintEffectsRenderer = PaintEffectsRenderer; exports.PaintGesture = PaintGesture; exports.PaintGradientSampler = _chunkFQPUF2W2cjs.PaintGradientSampler; exports.PaintPresence = PaintPresence; exports.PaintSourceError = _chunkFQPUF2W2cjs.PaintSourceError; exports.PaintStrokeSession = PaintStrokeSession; exports.PaintWetLayers = PaintWetLayers; exports.PaperGrain = _chunkPXDIAYB6cjs.PaperGrain; exports.ParticleStroke = ParticleStroke; exports.PenDabWalker = PenDabWalker; exports.PenSmoother = PenSmoother; exports.PerspectiveSnapper = PerspectiveSnapper; exports.RIBBON_PAIRS = _chunkTZOX7KWVcjs.RIBBON_PAIRS; exports.RIBBON_PAIR_LABELS = RIBBON_PAIR_LABELS; exports.SNAP_DECIDE_DISTANCE = SNAP_DECIDE_DISTANCE; exports.STAMP_KINDS = _chunkJSDND7DFcjs.STAMP_KINDS; exports.STAMP_LABELS = STAMP_LABELS; exports.STENCIL_KINDS = STENCIL_KINDS; exports.STENCIL_SHAPES = STENCIL_SHAPES; exports.STICKER_ART_SIZE = STICKER_ART_SIZE; exports.STICKER_SLIDERS = STICKER_SLIDERS; exports.STROKE_SLIDERS = STROKE_SLIDERS; exports.SYMMETRY_MODES = SYMMETRY_MODES; exports.StencilSnapper = StencilSnapper; exports.StickerArtCache = StickerArtCache; exports.StickerBrowser = _chunkRVGP2XLFcjs.StickerBrowser; exports.StickerSpray = StickerSpray; exports.TRACING_NODE_ID = TRACING_NODE_ID; exports.ThickStrokeDriver = ThickStrokeDriver; exports.TileableNoise = _chunk3K6HWEXZcjs.TileableNoise; exports.WET_FLOW_KINDS = _chunkYHDHFJUCcjs.WET_FLOW_KINDS; exports.WET_GPU_MODES = WET_GPU_MODES; exports.WET_GPU_OPTIONS = WET_GPU_OPTIONS; exports.WET_MEDIA = _chunkTZOX7KWVcjs.WET_MEDIA; exports.WET_MEDIUM_LABELS = WET_MEDIUM_LABELS; exports.WET_MEDIUM_PARAMS = WET_MEDIUM_PARAMS; exports.WET_PARAM_KEYS = _chunkYHDHFJUCcjs.WET_PARAM_KEYS; exports.WET_PARAM_SCHEMA = WET_PARAM_SCHEMA; exports.WET_PARAM_SLIDERS = WET_PARAM_SLIDERS; exports.WET_SPEED_SLIDER = WET_SPEED_SLIDER; exports.WET_TILT_SLIDERS = WET_TILT_SLIDERS; exports.WET_TOOLS = _chunkTZOX7KWVcjs.WET_TOOLS; exports.WET_TOOL_LABELS = WET_TOOL_LABELS; exports.WetStrokeDriver = WetStrokeDriver; exports.addPaintGradientStop = _chunkFQPUF2W2cjs.addPaintGradientStop; exports.addPolygonArea = addPolygonArea; exports.affineCopy = affineCopy; exports.applyAffine = applyAffine; exports.backlightOf = backlightOf; exports.brushEngineControls = _chunkPYTJBVW5cjs.brushEngineControls; exports.brushLoadColor = brushLoadColor; exports.brushLoadForStroke = brushLoadForStroke; exports.brushTakesPaint = _chunkTZOX7KWVcjs.brushTakesPaint; exports.brushToJSON = _chunkTZOX7KWVcjs.brushToJSON; exports.buildTimeLapse = buildTimeLapse; exports.checkPaintEffectPlace = checkPaintEffectPlace; exports.clonePaper = clonePaper; exports.colorHarmony = colorHarmony2; exports.composeAffine = composeAffine; exports.contactSheet = contactSheet; exports.createPaintAgentStrokes = createPaintAgentStrokes; exports.createPaintBrushLibraryToolProvider = createPaintBrushLibraryToolProvider; exports.createPaintChangeFeed = createPaintChangeFeed; exports.createPaintCompositor = createPaintCompositor; exports.createPaintDocument = createPaintDocument; exports.createPaintEditorDocument = createPaintEditorDocument; exports.createPaintEditorToolProvider = createPaintEditorToolProvider; exports.createPaintEffectsToolProvider = createPaintEffectsToolProvider; exports.createPaintLayer = createPaintLayer; exports.createPaintProposalToolProvider = createPaintProposalToolProvider; exports.createPaintProposals = createPaintProposals; exports.createPaintReplayTools = createPaintReplayTools; exports.createPaintStickerTools = createPaintStickerTools; exports.createPaintThickTools = createPaintThickTools; exports.createPaintWetTools = createPaintWetTools; exports.decodeImageBlob = decodeImageBlob; exports.defaultGuides = defaultGuides; exports.defaultImageEncoder = defaultImageEncoder; exports.defaultStickerRasterizer = defaultStickerRasterizer; exports.deserializePaintDocument = deserializePaintDocument; exports.deserializePaintDocumentAsync = deserializePaintDocumentAsync; exports.documentExtensions = documentExtensions; exports.documentToScreen = documentToScreen; exports.downloadBytes = downloadBytes; exports.downsampleRgba = downsampleRgba; exports.drawSticker = drawSticker; exports.drawWaterOverlay = drawWaterOverlay; exports.effectDabField = effectDabField; exports.effectLayersToJSON = effectLayersToJSON; exports.effectPaintKey = effectPaintKey; exports.effectPaintSize = effectPaintSize; exports.emptiedLayers = emptiedLayers; exports.emptyThickChannels = emptyThickChannels; exports.fitZoom = fitZoom; exports.grainCatch = _chunkPXDIAYB6cjs.grainCatch; exports.grainHeights = _chunkPXDIAYB6cjs.grainHeights; exports.guideOverlay = guideOverlay; exports.handlePaintShortcut = handlePaintShortcut; exports.hash2 = _chunk3K6HWEXZcjs.hash2; exports.hexToPaintRgb = _chunkFQPUF2W2cjs.hexToPaintRgb; exports.hexToRgb8 = hexToRgb8; exports.hslToRgb = hslToRgb; exports.hsvToRgb = hsvToRgb; exports.hueToWheel = _chunkI3Y2Q3PMcjs.hueToWheel; exports.invertAffine = invertAffine; exports.isBlendMode = _chunk2VX55NFMcjs.isBlendMode; exports.isGradientPaint = _chunkFQPUF2W2cjs.isGradientPaint; exports.isPaintEffectPaint = isPaintEffectPaint; exports.isPainterlyBlendMode = _chunk2VX55NFMcjs.isPainterlyBlendMode; exports.isPalmTouch = isPalmTouch; exports.isWetBrush = _chunkTZOX7KWVcjs.isWetBrush; exports.isWetCapable = _chunkTZOX7KWVcjs.isWetCapable; exports.lightTile = lightTile; exports.lightingKey = lightingKey; exports.liveStrokeBounds = liveStrokeBounds; exports.liveStrokeRefusal = liveStrokeRefusal; exports.mapPenPoint = mapPenPoint; exports.mix32 = _chunk3K6HWEXZcjs.mix32; exports.mixPixels = mixPixels; exports.mixerLoadForStroke = mixerLoadForStroke; exports.mixerTip = mixerTip; exports.multiColorForDab = multiColorForDab; exports.multiColorGradient = multiColorGradient; exports.multiColorPalette = multiColorPalette; exports.multiColorSliders = _chunkPYTJBVW5cjs.multiColorSliders; exports.multiColorToPaint = _chunkTZOX7KWVcjs.multiColorToPaint; exports.newPaintLayerId = newPaintLayerId; exports.nextPaperEffectVersion = nextPaperEffectVersion; exports.normalizeBehavior = _chunkTZOX7KWVcjs.normalizeBehavior; exports.normalizeBristle = _chunkTZOX7KWVcjs.normalizeBristle; exports.normalizeBrushStroke = normalizeBrushStroke; exports.normalizeCanvas = normalizeCanvas; exports.normalizeDynamics = _chunkTZOX7KWVcjs.normalizeDynamics; exports.normalizeFlow = _chunkYHDHFJUCcjs.normalizeFlow; exports.normalizeHexColor = _chunkFQPUF2W2cjs.normalizeHexColor; exports.normalizeImpasto = _chunkTZOX7KWVcjs.normalizeImpasto; exports.normalizeLight = _chunkTZOX7KWVcjs.normalizeLight; exports.normalizeLighting = normalizeLighting; exports.normalizeMultiColor = _chunkTZOX7KWVcjs.normalizeMultiColor; exports.normalizePaintBrush = _chunkTZOX7KWVcjs.normalizePaintBrush; exports.normalizePaper = normalizePaper; exports.normalizeParticle = _chunkTZOX7KWVcjs.normalizeParticle; exports.normalizePerspective = normalizePerspective; exports.normalizeRotation = normalizeRotation; exports.normalizeStencil = normalizeStencil; exports.normalizeStickerSettings = _chunkTZOX7KWVcjs.normalizeStickerSettings; exports.normalizeStickerUpdate = normalizeStickerUpdate; exports.normalizeSymmetry = normalizeSymmetry; exports.normalizeView = normalizeView; exports.normalizeWetBrush = _chunkTZOX7KWVcjs.normalizeWetBrush; exports.normalizeWetParams = _chunkYHDHFJUCcjs.normalizeWetParams; exports.overPixels = overPixels; exports.padSampleRadius = padSampleRadius; exports.paintAgentStrokePoints = paintAgentStrokePoints; exports.paintContracts = paintContracts; exports.paintGradientMappingFor = _chunkFQPUF2W2cjs.paintGradientMappingFor; exports.paintPlaybackPanel = paintPlaybackPanel; exports.paintProposalGhost = paintProposalGhost; exports.paintShortcutFor = paintShortcutFor; exports.paintSourceColor = _chunkFQPUF2W2cjs.paintSourceColor; exports.paintSourceCss = _chunkFQPUF2W2cjs.paintSourceCss; exports.paintToMultiColor = _chunkTZOX7KWVcjs.paintToMultiColor; exports.paperEffectFromJSON = paperEffectFromJSON; exports.paperEffectToJSON = paperEffectToJSON; exports.paperGrain = paperGrain; exports.paperKey = paperKey; exports.paperNode = paperNode; exports.paperPreset = paperPreset; exports.parseBrushLibrary = _chunkTZOX7KWVcjs.parseBrushLibrary; exports.parseHexColor = parseHexColor; exports.parsePaintSource = _chunkFQPUF2W2cjs.parsePaintSource; exports.patchBrushValue = _chunkPYTJBVW5cjs.patchBrushValue; exports.patchPath = patchPath; exports.penOrientation = penOrientation; exports.perspectiveDirections = perspectiveDirections; exports.perspectiveGuideLines = perspectiveGuideLines; exports.planPaintToolPlayback = planPaintToolPlayback; exports.pointerToPenPoint = pointerToPenPoint; exports.quickStencil = quickStencil; exports.rand01 = _chunk3K6HWEXZcjs.rand01; exports.randSigned = _chunk3K6HWEXZcjs.randSigned; exports.readEffectStrokeMap = readEffectStrokeMap; exports.readPaintEffectPaint = readPaintEffectPaint; exports.readPaintEffectSource = readPaintEffectSource; exports.readPaintSource = _chunkFQPUF2W2cjs.readPaintSource; exports.readPath = readPath; exports.readSwatch = readSwatch; exports.reliefInfo = reliefInfo; exports.removePaintGradientStop = _chunkFQPUF2W2cjs.removePaintGradientStop; exports.renderBrushThumbnail = renderBrushThumbnail; exports.renderColorWheel = renderColorWheel; exports.renderPaper = renderPaper; exports.renderStickers = renderStickers; exports.replayFrame = replayFrame; exports.replayItems = replayItems; exports.replayPainting = replayPainting; exports.resolvePaintGradient = _chunkFQPUF2W2cjs.resolvePaintGradient; exports.reversePaintGradient = _chunkFQPUF2W2cjs.reversePaintGradient; exports.rgbToHexColor = rgbToHexColor; exports.rgbToHsl = rgbToHsl; exports.rgbToHsv = rgbToHsv; exports.sampleArt = sampleArt; exports.sampleEffectAt = sampleEffectAt; exports.sampleEffectField = sampleEffectField; exports.samplePath = samplePath; exports.samplePressure = samplePressure; exports.scalePaintGradient = _chunkFQPUF2W2cjs.scalePaintGradient; exports.scaleStencil = scaleStencil; exports.screenToDocument = screenToDocument; exports.seedFromString = _chunk3K6HWEXZcjs.seedFromString; exports.serializePaintDocument = serializePaintDocument; exports.serializePaintDocumentExternal = serializePaintDocumentExternal; exports.solidPaint = _chunkFQPUF2W2cjs.solidPaint; exports.stampCoverage = _chunkJSDND7DFcjs.stampCoverage; exports.standardBlendMode = _chunk2VX55NFMcjs.standardBlendMode; exports.startWetClock = startWetClock; exports.stencilMask = stencilMask; exports.stencilOutline = stencilOutline; exports.stickerAt = stickerAt; exports.stickerRect = stickerRect; exports.stickerRefLabel = stickerRefLabel; exports.stickerStamp = stickerStamp; exports.stickerSurface = stickerSurface; exports.strokeBounds = strokeBounds; exports.strokeDuration = strokeDuration; exports.strokeSchedule = strokeSchedule; exports.strokeToJSON = strokeToJSON; exports.sweepPath = sweepPath; exports.symmetryAxisAngles = symmetryAxisAngles; exports.symmetryAxisSegments = symmetryAxisSegments; exports.symmetryCopies = symmetryCopies; exports.thickFromJSON = thickFromJSON; exports.thickToJSON = thickToJSON; exports.thumbnailStroke = thumbnailStroke; exports.tiltToOrientation = tiltToOrientation; exports.timeLapseVideo = timeLapseVideo; exports.timeLapseZip = timeLapseZip; exports.toStrokePoint = toStrokePoint; exports.toggleDotTexture = toggleDotTexture; exports.toggleStamp = toggleStamp; exports.toggleStickerRef = toggleStickerRef; exports.translateStencil = translateStencil; exports.updatePaintGradientStop = _chunkFQPUF2W2cjs.updatePaintGradientStop; exports.usesPaintExchange = _chunkTZOX7KWVcjs.usesPaintExchange; exports.variationAffine = variationAffine; exports.varyStroke = varyStroke; exports.viewCssTransform = viewCssTransform; exports.viewMatrix = viewMatrix; exports.viewPenToDocument = viewPenToDocument; exports.wetEngineSummary = wetEngineSummary; exports.wetPaperInput = wetPaperInput; exports.wetPigmentOf = wetPigmentOf; exports.wetSupport = _chunkYHDHFJUCcjs.wetSupport; exports.wheelAngle = wheelAngle; exports.wheelPick = wheelPick; exports.wheelPoint = wheelPoint; exports.wheelToHue = _chunkI3Y2Q3PMcjs.wheelToHue; exports.withPaintPlayback = withPaintPlayback;
13834
+ exports.BACKLIGHT_SPILL = BACKLIGHT_SPILL; exports.BLEND_MENU_GROUPS = BLEND_MENU_GROUPS; exports.BLEND_MODES = _chunk2VX55NFMcjs.BLEND_MODES; exports.BRUSH_ID = _chunkTZOX7KWVcjs.BRUSH_ID; exports.BRUSH_ROTATIONS = _chunkTZOX7KWVcjs.BRUSH_ROTATIONS; exports.BRUSH_SLIDERS = _chunkPYTJBVW5cjs.BRUSH_SLIDERS; exports.BUILTIN_BRUSHES = _chunkTZOX7KWVcjs.BUILTIN_BRUSHES; exports.BristleStroke = BristleStroke; exports.DEFAULT_BACKLIGHT_COLOR = DEFAULT_BACKLIGHT_COLOR; exports.DEFAULT_BEHAVIOR = _chunkTZOX7KWVcjs.DEFAULT_BEHAVIOR; exports.DEFAULT_BRISTLE = _chunkTZOX7KWVcjs.DEFAULT_BRISTLE; exports.DEFAULT_BRUSH_ID = _chunkTZOX7KWVcjs.DEFAULT_BRUSH_ID; exports.DEFAULT_DPI = DEFAULT_DPI; exports.DEFAULT_DYNAMICS = _chunkTZOX7KWVcjs.DEFAULT_DYNAMICS; exports.DEFAULT_FLOW = _chunkYHDHFJUCcjs.DEFAULT_FLOW; exports.DEFAULT_IMPASTO = _chunkTZOX7KWVcjs.DEFAULT_IMPASTO; exports.DEFAULT_LIGHT = _chunkTZOX7KWVcjs.DEFAULT_LIGHT; exports.DEFAULT_LIGHTING = DEFAULT_LIGHTING; exports.DEFAULT_MULTI_COLOR = _chunkTZOX7KWVcjs.DEFAULT_MULTI_COLOR; exports.DEFAULT_PAINT_GRADIENT = _chunkFQPUF2W2cjs.DEFAULT_PAINT_GRADIENT; exports.DEFAULT_PAINT_GRADIENT_MAPPING = _chunkFQPUF2W2cjs.DEFAULT_PAINT_GRADIENT_MAPPING; exports.DEFAULT_PAPER = DEFAULT_PAPER; exports.DEFAULT_PARTICLE = _chunkTZOX7KWVcjs.DEFAULT_PARTICLE; exports.DEFAULT_SPRAY = _chunkTZOX7KWVcjs.DEFAULT_SPRAY; exports.DEFAULT_STICKER = _chunkTZOX7KWVcjs.DEFAULT_STICKER; exports.DEFAULT_SWATCHES = DEFAULT_SWATCHES; exports.DEFAULT_VIEW = DEFAULT_VIEW; exports.DEFAULT_WET_BRUSH = _chunkTZOX7KWVcjs.DEFAULT_WET_BRUSH; exports.DEFAULT_WET_PARAMS = _chunkYHDHFJUCcjs.DEFAULT_WET_PARAMS; exports.DOT_ROTATIONS = _chunkTZOX7KWVcjs.DOT_ROTATIONS; exports.DOT_ROTATION_LABELS = DOT_ROTATION_LABELS; exports.DOT_TEXTURE_ORDERS = _chunkTZOX7KWVcjs.DOT_TEXTURE_ORDERS; exports.DOT_TEXTURE_ORDER_LABELS = DOT_TEXTURE_ORDER_LABELS; exports.DryStroke = DryStroke; exports.EFFECT_MAP_REPEATS = EFFECT_MAP_REPEATS; exports.EFFECT_STRIP_HEIGHT = EFFECT_STRIP_HEIGHT; exports.GPU_LEAD = GPU_LEAD; exports.GRAIN_PATTERNS = _chunkPXDIAYB6cjs.GRAIN_PATTERNS; exports.GRAIN_TILE = _chunkPXDIAYB6cjs.GRAIN_TILE; exports.HARMONY_KINDS = _chunkI3Y2Q3PMcjs.HARMONY_KINDS; exports.IDENTITY_AFFINE = IDENTITY_AFFINE; exports.IDENTITY_COPY = IDENTITY_COPY; exports.IMPASTO_TOOLS = _chunkTZOX7KWVcjs.IMPASTO_TOOLS; exports.IMPASTO_TOOL_LABELS = IMPASTO_TOOL_LABELS; exports.LIGHT_SLIDERS = LIGHT_SLIDERS; exports.LIVE_STROKE_ENGINES = LIVE_STROKE_ENGINES; exports.LitCache = LitCache; exports.MAX_BRUSH_SIZE = _chunkFQPUF2W2cjs.MAX_BRUSH_SIZE; exports.MAX_CANVAS_SIDE = MAX_CANVAS_SIDE; exports.MAX_COORDINATE = MAX_COORDINATE; exports.MAX_DOT_TEXTURES = _chunkTZOX7KWVcjs.MAX_DOT_TEXTURES; exports.MAX_IMAGE_SIDE = MAX_IMAGE_SIDE; exports.MAX_LIVE_EFFECT_SOURCES = MAX_LIVE_EFFECT_SOURCES; exports.MAX_PATH_SAMPLES = MAX_PATH_SAMPLES; exports.MAX_STICKER_STAMPS = _chunkTZOX7KWVcjs.MAX_STICKER_STAMPS; exports.MAX_ZOOM = MAX_ZOOM; exports.MIN_CANVAS_SIDE = MIN_CANVAS_SIDE; exports.MIN_ZOOM = MIN_ZOOM; exports.MIXING_PAD_HEIGHT = MIXING_PAD_HEIGHT; exports.MIXING_PAD_WIDTH = MIXING_PAD_WIDTH; exports.MULTI_COLOR_MODES = _chunkTZOX7KWVcjs.MULTI_COLOR_MODES; exports.MixingPad = MixingPad; exports.PAD_SAMPLE_SIZES = PAD_SAMPLE_SIZES; exports.PAINTERLY_BLEND_MODES = _chunk2VX55NFMcjs.PAINTERLY_BLEND_MODES; exports.PAINT_BRUSH_CATEGORIES = _chunkTZOX7KWVcjs.PAINT_BRUSH_CATEGORIES; exports.PAINT_BRUSH_ENGINES = _chunkTZOX7KWVcjs.PAINT_BRUSH_ENGINES; exports.PAINT_COLOR_JSON_SCHEMA = _chunkFQPUF2W2cjs.PAINT_COLOR_JSON_SCHEMA; exports.PAINT_CONTRACT_FORMAT_VERSION = PAINT_CONTRACT_FORMAT_VERSION; exports.PAINT_DOCUMENT_JSON_SCHEMA = PAINT_DOCUMENT_JSON_SCHEMA; exports.PAINT_EFFECT_PLACES = PAINT_EFFECT_PLACES; exports.PAINT_FORMAT = PAINT_FORMAT; exports.PAINT_GRADIENT_FULL_SPEED = _chunkFQPUF2W2cjs.PAINT_GRADIENT_FULL_SPEED; exports.PAINT_GRADIENT_JSON_SCHEMA = _chunkFQPUF2W2cjs.PAINT_GRADIENT_JSON_SCHEMA; exports.PAINT_GRADIENT_KIT = _chunkFQPUF2W2cjs.PAINT_GRADIENT_KIT; exports.PAINT_GRADIENT_MAPPINGS = _chunkFQPUF2W2cjs.PAINT_GRADIENT_MAPPINGS; exports.PAINT_GRADIENT_MAPPING_LABELS = _chunkFQPUF2W2cjs.PAINT_GRADIENT_MAPPING_LABELS; exports.PAINT_GRADIENT_PRESETS = _chunkFQPUF2W2cjs.PAINT_GRADIENT_PRESETS; exports.PAINT_GRADIENT_REPEATS = _chunkFQPUF2W2cjs.PAINT_GRADIENT_REPEATS; exports.PAINT_GRADIENT_REPEAT_LABELS = _chunkFQPUF2W2cjs.PAINT_GRADIENT_REPEAT_LABELS; exports.PAINT_GRADIENT_SPACES = _chunkFQPUF2W2cjs.PAINT_GRADIENT_SPACES; exports.PAINT_GRADIENT_SPACE_LABELS = _chunkFQPUF2W2cjs.PAINT_GRADIENT_SPACE_LABELS; exports.PAINT_SCHEMA_VERSION = PAINT_SCHEMA_VERSION; exports.PAINT_SHORTCUTS = PAINT_SHORTCUTS; exports.PAINT_SOURCE_JSON_SCHEMA = _chunkFQPUF2W2cjs.PAINT_SOURCE_JSON_SCHEMA; exports.PAINT_TARGET = PAINT_TARGET; exports.PAINT_TOOLS = PAINT_TOOLS; exports.PAPER_EFFECT_BLENDS = PAPER_EFFECT_BLENDS; exports.PAPER_EFFECT_NODE_ID = PAPER_EFFECT_NODE_ID; exports.PAPER_FAMILIES = PAPER_FAMILIES; exports.PAPER_LIBRARY = PAPER_LIBRARY; exports.PAPER_NODE_ID = PAPER_NODE_ID; exports.PAPER_SLIDERS = PAPER_SLIDERS; exports.PAPER_TARGET = PAPER_TARGET; exports.PARTICLE_KINDS = _chunkTZOX7KWVcjs.PARTICLE_KINDS; exports.PARTICLE_KIND_LABELS = PARTICLE_KIND_LABELS; exports.PARTICLE_RENDERS = _chunkTZOX7KWVcjs.PARTICLE_RENDERS; exports.PARTICLE_RENDER_LABELS = PARTICLE_RENDER_LABELS; exports.PATH_STROKE_TAPERS = PATH_STROKE_TAPERS; exports.PaintCanvasPresenter = PaintCanvasPresenter; exports.PaintDabStroke = PaintDabStroke; exports.PaintDirector = PaintDirector; exports.PaintDocumentError = PaintDocumentError; exports.PaintEditorController = PaintEditorController; exports.PaintEditorError = PaintEditorError; exports.PaintEffectsRenderer = PaintEffectsRenderer; exports.PaintGesture = PaintGesture; exports.PaintGradientSampler = _chunkFQPUF2W2cjs.PaintGradientSampler; exports.PaintPresence = PaintPresence; exports.PaintSourceError = _chunkFQPUF2W2cjs.PaintSourceError; exports.PaintStrokeSession = PaintStrokeSession; exports.PaintWetLayers = PaintWetLayers; exports.PaperGrain = _chunkPXDIAYB6cjs.PaperGrain; exports.ParticleStroke = ParticleStroke; exports.PenDabWalker = PenDabWalker; exports.PenSmoother = PenSmoother; exports.PerspectiveSnapper = PerspectiveSnapper; exports.RIBBON_PAIRS = _chunkTZOX7KWVcjs.RIBBON_PAIRS; exports.RIBBON_PAIR_LABELS = RIBBON_PAIR_LABELS; exports.SNAP_DECIDE_DISTANCE = SNAP_DECIDE_DISTANCE; exports.STAMP_KINDS = _chunkJSDND7DFcjs.STAMP_KINDS; exports.STAMP_LABELS = STAMP_LABELS; exports.STENCIL_KINDS = STENCIL_KINDS; exports.STENCIL_SHAPES = STENCIL_SHAPES; exports.STICKER_ART_SIZE = STICKER_ART_SIZE; exports.STICKER_SLIDERS = STICKER_SLIDERS; exports.STROKE_SLIDERS = STROKE_SLIDERS; exports.SYMMETRY_MODES = SYMMETRY_MODES; exports.StencilSnapper = StencilSnapper; exports.StickerArtCache = StickerArtCache; exports.StickerBrowser = _chunkRVGP2XLFcjs.StickerBrowser; exports.StickerSpray = StickerSpray; exports.TRACING_NODE_ID = TRACING_NODE_ID; exports.ThickStrokeDriver = ThickStrokeDriver; exports.TileableNoise = _chunk3K6HWEXZcjs.TileableNoise; exports.WET_FLOW_KINDS = _chunkYHDHFJUCcjs.WET_FLOW_KINDS; exports.WET_GPU_MODES = WET_GPU_MODES; exports.WET_GPU_OPTIONS = WET_GPU_OPTIONS; exports.WET_MEDIA = _chunkTZOX7KWVcjs.WET_MEDIA; exports.WET_MEDIUM_LABELS = WET_MEDIUM_LABELS; exports.WET_MEDIUM_PARAMS = WET_MEDIUM_PARAMS; exports.WET_PARAM_KEYS = _chunkYHDHFJUCcjs.WET_PARAM_KEYS; exports.WET_PARAM_SCHEMA = WET_PARAM_SCHEMA; exports.WET_PARAM_SLIDERS = WET_PARAM_SLIDERS; exports.WET_SPEED_SLIDER = WET_SPEED_SLIDER; exports.WET_TILT_SLIDERS = WET_TILT_SLIDERS; exports.WET_TOOLS = _chunkTZOX7KWVcjs.WET_TOOLS; exports.WET_TOOL_LABELS = WET_TOOL_LABELS; exports.WetStrokeDriver = WetStrokeDriver; exports.addPaintGradientStop = _chunkFQPUF2W2cjs.addPaintGradientStop; exports.addPolygonArea = addPolygonArea; exports.affineCopy = affineCopy; exports.applyAffine = applyAffine; exports.backlightOf = backlightOf; exports.brushEngineControls = _chunkPYTJBVW5cjs.brushEngineControls; exports.brushLoadColor = brushLoadColor; exports.brushLoadForStroke = brushLoadForStroke; exports.brushTakesPaint = _chunkTZOX7KWVcjs.brushTakesPaint; exports.brushToJSON = _chunkTZOX7KWVcjs.brushToJSON; exports.buildTimeLapse = buildTimeLapse; exports.checkPaintEffectPlace = checkPaintEffectPlace; exports.clonePaper = clonePaper; exports.colorHarmony = colorHarmony2; exports.composeAffine = composeAffine; exports.contactSheet = contactSheet; exports.createPaintAgentStrokes = createPaintAgentStrokes; exports.createPaintBrushLibraryToolProvider = createPaintBrushLibraryToolProvider; exports.createPaintChangeFeed = createPaintChangeFeed; exports.createPaintCompositor = createPaintCompositor; exports.createPaintConformanceHost = createPaintConformanceHost; exports.createPaintDocument = createPaintDocument; exports.createPaintEditorDocument = createPaintEditorDocument; exports.createPaintEditorToolProvider = createPaintEditorToolProvider; exports.createPaintEffectsToolProvider = createPaintEffectsToolProvider; exports.createPaintLayer = createPaintLayer; exports.createPaintProposalToolProvider = createPaintProposalToolProvider; exports.createPaintProposals = createPaintProposals; exports.createPaintReplayTools = createPaintReplayTools; exports.createPaintStickerTools = createPaintStickerTools; exports.createPaintThickTools = createPaintThickTools; exports.createPaintWetTools = createPaintWetTools; exports.decodeImageBlob = decodeImageBlob; exports.defaultGuides = defaultGuides; exports.defaultImageEncoder = defaultImageEncoder; exports.defaultStickerRasterizer = defaultStickerRasterizer; exports.deserializePaintDocument = deserializePaintDocument; exports.deserializePaintDocumentAsync = deserializePaintDocumentAsync; exports.documentExtensions = documentExtensions; exports.documentToScreen = documentToScreen; exports.downloadBytes = downloadBytes; exports.downsampleRgba = downsampleRgba; exports.drawSticker = drawSticker; exports.drawWaterOverlay = drawWaterOverlay; exports.effectDabField = effectDabField; exports.effectLayersToJSON = effectLayersToJSON; exports.effectPaintKey = effectPaintKey; exports.effectPaintSize = effectPaintSize; exports.emptiedLayers = emptiedLayers; exports.emptyThickChannels = emptyThickChannels; exports.fitZoom = fitZoom; exports.grainCatch = _chunkPXDIAYB6cjs.grainCatch; exports.grainHeights = _chunkPXDIAYB6cjs.grainHeights; exports.guideOverlay = guideOverlay; exports.handlePaintShortcut = handlePaintShortcut; exports.hash2 = _chunk3K6HWEXZcjs.hash2; exports.hexToPaintRgb = _chunkFQPUF2W2cjs.hexToPaintRgb; exports.hexToRgb8 = hexToRgb8; exports.hslToRgb = hslToRgb; exports.hsvToRgb = hsvToRgb; exports.hueToWheel = _chunkI3Y2Q3PMcjs.hueToWheel; exports.invertAffine = invertAffine; exports.isBlendMode = _chunk2VX55NFMcjs.isBlendMode; exports.isGradientPaint = _chunkFQPUF2W2cjs.isGradientPaint; exports.isPaintEffectPaint = isPaintEffectPaint; exports.isPainterlyBlendMode = _chunk2VX55NFMcjs.isPainterlyBlendMode; exports.isPalmTouch = isPalmTouch; exports.isWetBrush = _chunkTZOX7KWVcjs.isWetBrush; exports.isWetCapable = _chunkTZOX7KWVcjs.isWetCapable; exports.lightTile = lightTile; exports.lightingKey = lightingKey; exports.liveStrokeBounds = liveStrokeBounds; exports.liveStrokeRefusal = liveStrokeRefusal; exports.mapPenPoint = mapPenPoint; exports.mix32 = _chunk3K6HWEXZcjs.mix32; exports.mixPixels = mixPixels; exports.mixerLoadForStroke = mixerLoadForStroke; exports.mixerTip = mixerTip; exports.multiColorForDab = multiColorForDab; exports.multiColorGradient = multiColorGradient; exports.multiColorPalette = multiColorPalette; exports.multiColorSliders = _chunkPYTJBVW5cjs.multiColorSliders; exports.multiColorToPaint = _chunkTZOX7KWVcjs.multiColorToPaint; exports.newPaintLayerId = newPaintLayerId; exports.nextPaperEffectVersion = nextPaperEffectVersion; exports.normalizeBehavior = _chunkTZOX7KWVcjs.normalizeBehavior; exports.normalizeBristle = _chunkTZOX7KWVcjs.normalizeBristle; exports.normalizeBrushStroke = normalizeBrushStroke; exports.normalizeCanvas = normalizeCanvas; exports.normalizeDynamics = _chunkTZOX7KWVcjs.normalizeDynamics; exports.normalizeFlow = _chunkYHDHFJUCcjs.normalizeFlow; exports.normalizeHexColor = _chunkFQPUF2W2cjs.normalizeHexColor; exports.normalizeImpasto = _chunkTZOX7KWVcjs.normalizeImpasto; exports.normalizeLight = _chunkTZOX7KWVcjs.normalizeLight; exports.normalizeLighting = normalizeLighting; exports.normalizeMultiColor = _chunkTZOX7KWVcjs.normalizeMultiColor; exports.normalizePaintBrush = _chunkTZOX7KWVcjs.normalizePaintBrush; exports.normalizePaper = normalizePaper; exports.normalizeParticle = _chunkTZOX7KWVcjs.normalizeParticle; exports.normalizePerspective = normalizePerspective; exports.normalizeRotation = normalizeRotation; exports.normalizeStencil = normalizeStencil; exports.normalizeStickerSettings = _chunkTZOX7KWVcjs.normalizeStickerSettings; exports.normalizeStickerUpdate = normalizeStickerUpdate; exports.normalizeSymmetry = normalizeSymmetry; exports.normalizeView = normalizeView; exports.normalizeWetBrush = _chunkTZOX7KWVcjs.normalizeWetBrush; exports.normalizeWetParams = _chunkYHDHFJUCcjs.normalizeWetParams; exports.overPixels = overPixels; exports.padSampleRadius = padSampleRadius; exports.paintAgentStrokePoints = paintAgentStrokePoints; exports.paintContracts = paintContracts; exports.paintGradientMappingFor = _chunkFQPUF2W2cjs.paintGradientMappingFor; exports.paintPlaybackPanel = paintPlaybackPanel; exports.paintProposalGhost = paintProposalGhost; exports.paintShortcutFor = paintShortcutFor; exports.paintSourceColor = _chunkFQPUF2W2cjs.paintSourceColor; exports.paintSourceCss = _chunkFQPUF2W2cjs.paintSourceCss; exports.paintToMultiColor = _chunkTZOX7KWVcjs.paintToMultiColor; exports.paperEffectFromJSON = paperEffectFromJSON; exports.paperEffectToJSON = paperEffectToJSON; exports.paperGrain = paperGrain; exports.paperKey = paperKey; exports.paperNode = paperNode; exports.paperPreset = paperPreset; exports.parseBrushLibrary = _chunkTZOX7KWVcjs.parseBrushLibrary; exports.parseHexColor = parseHexColor; exports.parsePaintSource = _chunkFQPUF2W2cjs.parsePaintSource; exports.patchBrushValue = _chunkPYTJBVW5cjs.patchBrushValue; exports.patchPath = patchPath; exports.penOrientation = penOrientation; exports.perspectiveDirections = perspectiveDirections; exports.perspectiveGuideLines = perspectiveGuideLines; exports.planPaintToolPlayback = planPaintToolPlayback; exports.pointerToPenPoint = pointerToPenPoint; exports.quickStencil = quickStencil; exports.rand01 = _chunk3K6HWEXZcjs.rand01; exports.randSigned = _chunk3K6HWEXZcjs.randSigned; exports.readEffectStrokeMap = readEffectStrokeMap; exports.readPaintEffectPaint = readPaintEffectPaint; exports.readPaintEffectSource = readPaintEffectSource; exports.readPaintSource = _chunkFQPUF2W2cjs.readPaintSource; exports.readPath = readPath; exports.readSwatch = readSwatch; exports.reliefInfo = reliefInfo; exports.removePaintGradientStop = _chunkFQPUF2W2cjs.removePaintGradientStop; exports.renderBrushThumbnail = renderBrushThumbnail; exports.renderColorWheel = renderColorWheel; exports.renderPaper = renderPaper; exports.renderStickers = renderStickers; exports.replayFrame = replayFrame; exports.replayItems = replayItems; exports.replayPainting = replayPainting; exports.resolvePaintGradient = _chunkFQPUF2W2cjs.resolvePaintGradient; exports.reversePaintGradient = _chunkFQPUF2W2cjs.reversePaintGradient; exports.rgbToHexColor = rgbToHexColor; exports.rgbToHsl = rgbToHsl; exports.rgbToHsv = rgbToHsv; exports.sampleArt = sampleArt; exports.sampleEffectAt = sampleEffectAt; exports.sampleEffectField = sampleEffectField; exports.samplePath = samplePath; exports.samplePressure = samplePressure; exports.scalePaintGradient = _chunkFQPUF2W2cjs.scalePaintGradient; exports.scaleStencil = scaleStencil; exports.screenToDocument = screenToDocument; exports.seedFromString = _chunk3K6HWEXZcjs.seedFromString; exports.serializePaintDocument = serializePaintDocument; exports.serializePaintDocumentExternal = serializePaintDocumentExternal; exports.solidPaint = _chunkFQPUF2W2cjs.solidPaint; exports.stampCoverage = _chunkJSDND7DFcjs.stampCoverage; exports.standardBlendMode = _chunk2VX55NFMcjs.standardBlendMode; exports.startWetClock = startWetClock; exports.stencilMask = stencilMask; exports.stencilOutline = stencilOutline; exports.stickerAt = stickerAt; exports.stickerRect = stickerRect; exports.stickerRefLabel = stickerRefLabel; exports.stickerStamp = stickerStamp; exports.stickerSurface = stickerSurface; exports.strokeBounds = strokeBounds; exports.strokeDuration = strokeDuration; exports.strokeSchedule = strokeSchedule; exports.strokeToJSON = strokeToJSON; exports.sweepPath = sweepPath; exports.symmetryAxisAngles = symmetryAxisAngles; exports.symmetryAxisSegments = symmetryAxisSegments; exports.symmetryCopies = symmetryCopies; exports.thickFromJSON = thickFromJSON; exports.thickToJSON = thickToJSON; exports.thumbnailStroke = thumbnailStroke; exports.tiltToOrientation = tiltToOrientation; exports.timeLapseVideo = timeLapseVideo; exports.timeLapseZip = timeLapseZip; exports.toStrokePoint = toStrokePoint; exports.toggleDotTexture = toggleDotTexture; exports.toggleStamp = toggleStamp; exports.toggleStickerRef = toggleStickerRef; exports.translateStencil = translateStencil; exports.updatePaintGradientStop = _chunkFQPUF2W2cjs.updatePaintGradientStop; exports.usesPaintExchange = _chunkTZOX7KWVcjs.usesPaintExchange; exports.variationAffine = variationAffine; exports.varyStroke = varyStroke; exports.viewCssTransform = viewCssTransform; exports.viewMatrix = viewMatrix; exports.viewPenToDocument = viewPenToDocument; exports.wetEngineSummary = wetEngineSummary; exports.wetPaperInput = wetPaperInput; exports.wetPigmentOf = wetPigmentOf; exports.wetSupport = _chunkYHDHFJUCcjs.wetSupport; exports.wheelAngle = wheelAngle; exports.wheelPick = wheelPick; exports.wheelPoint = wheelPoint; exports.wheelToHue = _chunkI3Y2Q3PMcjs.wheelToHue; exports.withPaintPlayback = withPaintPlayback;
@@ -58,4 +58,4 @@ export * from './sticker-art.cjs';
58
58
  export * from './collaboration.cjs';
59
59
  export * from './collaboration-tools.cjs';
60
60
  export { samplePath, MAX_PATH_SAMPLES, type PathSampleOptions } from './path-samples.cjs';
61
- export { paintContracts, PAINT_CONTRACT_FORMAT_VERSION, PAINT_DOCUMENT_JSON_SCHEMA } from './contract.cjs';
61
+ export { createPaintConformanceHost, paintContracts, PAINT_CONTRACT_FORMAT_VERSION, PAINT_DOCUMENT_JSON_SCHEMA } from './contract.cjs';
@@ -58,4 +58,4 @@ export * from './sticker-art.js';
58
58
  export * from './collaboration.js';
59
59
  export * from './collaboration-tools.js';
60
60
  export { samplePath, MAX_PATH_SAMPLES, type PathSampleOptions } from './path-samples.js';
61
- export { paintContracts, PAINT_CONTRACT_FORMAT_VERSION, PAINT_DOCUMENT_JSON_SCHEMA } from './contract.js';
61
+ export { createPaintConformanceHost, paintContracts, PAINT_CONTRACT_FORMAT_VERSION, PAINT_DOCUMENT_JSON_SCHEMA } from './contract.js';
@@ -19,6 +19,9 @@ import {
19
19
  import {
20
20
  toVideoFfmpeg
21
21
  } from "../chunk-MWUZCEFT.js";
22
+ import {
23
+ ToolRegistry
24
+ } from "../chunk-K4BGRCSH.js";
22
25
  import {
23
26
  BRUSH_OPTION_CONTROLS,
24
27
  createLayerEffectTools,
@@ -278,7 +281,8 @@ import "../chunk-VDGBHYC7.js";
278
281
  import {
279
282
  EDITOR_DOCUMENT_FORMAT,
280
283
  createEditorAssetRegistry,
281
- defineEditorDocument
284
+ defineEditorDocument,
285
+ toEditorDocumentFile
282
286
  } from "../chunk-XBQX76CT.js";
283
287
  import "../chunk-HF5QZS7Z.js";
284
288
  import "../chunk-M2TPMYJE.js";
@@ -10878,7 +10882,7 @@ function createPaintWetTools(c) {
10878
10882
  {
10879
10883
  name: "get_wet_paint",
10880
10884
  title: "Get the wet paint",
10881
- description: "Reads the wet media: whether any paint is still wet, the simulation clock (steps), whether time is paused, its speed (steps per second), the canvas tilt, the kernel running it (typescript, wasm, wasm-threads with the thread count, and a message when it runs slower than it could, e.g. without cross-origin isolation), and each wet layer: wet cells, where the water is (wetBounds), live tiles, its settings and flow map. Also engine: Engine B, the WebGPU accelerator (mode auto/off, state, reason, adapter, minTiles, activeTiles). Call it after wet strokes to see what is still wet.",
10885
+ description: "Reads the wet media: whether any paint is still wet, the simulation clock (steps), whether time is paused, its speed (steps per second), the canvas tilt, the kernel running it (typescript, wasm, wasm-threads with the thread count, and a message when it runs slower than it could, e.g. without cross-origin isolation), and each wet layer: wet cells, where the water is (wetBounds), live tiles, its settings and flow map. Also engine: Engine B, the GPU accelerator: WebGPU in browsers, Metal in the Swift editors (mode auto/off, state, reason, adapter, minTiles, activeTiles). Call it after wet strokes to see what is still wet.",
10882
10886
  inputSchema: EMPTY2,
10883
10887
  annotations: { title: "Get the wet paint", ...READ3 },
10884
10888
  coordinates: { out: ["layers[].wetBounds", "layers[].flow.center"] },
@@ -11015,7 +11019,7 @@ function createPaintWetTools(c) {
11015
11019
  {
11016
11020
  name: "set_wet_engine",
11017
11021
  title: "Choose the wet-media engine",
11018
- description: 'Lets Engine B, the WebGPU accelerator, run for large wet areas (gpu "auto", the default) or forces the CPU (gpu "off"), and optionally sets minTiles, the wet area at which the GPU takes over. The GPU only shades what is shown: the CPU engine stays the authority, so the painting, drying, saving, export and replay come out the same either way; force the CPU when the display looks wrong or the GPU is busy with other work. Editor setting, not an undo step, not saved with the painting. Returns the engine: mode, state (off, not-started, starting, unavailable, standby, active, failed), reason, adapter, maxTiles, minTiles and activeTiles.',
11022
+ description: 'Lets Engine B, the GPU accelerator (WebGPU in browsers, Metal in the Swift editors), run for large wet areas (gpu "auto", the default) or forces the CPU (gpu "off"), and optionally sets minTiles, the wet area at which the GPU takes over. The GPU only shades what is shown: the CPU engine stays the authority, so the painting, drying, saving, export and replay come out the same either way; force the CPU when the display looks wrong or the GPU is busy with other work. Editor setting, not an undo step, not saved with the painting. Returns the engine: mode, state (off, not-started, starting, unavailable, standby, active, failed), reason, adapter, maxTiles, minTiles and activeTiles.',
11019
11023
  inputSchema: {
11020
11024
  type: "object",
11021
11025
  properties: {
@@ -13446,6 +13450,23 @@ function paintContracts(options) {
13446
13450
  };
13447
13451
  return files;
13448
13452
  }
13453
+ var GENERATED_ID = /^(pl[0-9a-z]{9,}|[a-z]+_[0-9a-z]{8,}_[0-9a-z]+)$/;
13454
+ function createPaintConformanceHost(setup, options) {
13455
+ const controller = new PaintEditorController({ ...setup, wet: { kernel: "typescript", threads: 0, gpu: "off", ...setup.wet } });
13456
+ controller.setEffectsProvider(options.effects);
13457
+ const registry = new ToolRegistry({ validateArguments: true });
13458
+ registry.register(createPaintEditorToolProvider(controller));
13459
+ registry.register(createPaintEffectsToolProvider(controller));
13460
+ registry.register(createPaintBrushLibraryToolProvider(controller));
13461
+ registry.register(createPaintProposalToolProvider(createPaintProposals({ controller })));
13462
+ return {
13463
+ callTool: (name, args) => registry.callTool(name, args),
13464
+ document: () => toEditorDocumentFile(createPaintEditorDocument(controller)),
13465
+ pixels: ({ paper }) => controller.compositePixels({ paper }),
13466
+ isGeneratedId: (value) => GENERATED_ID.test(value),
13467
+ dispose: () => controller.dispose()
13468
+ };
13469
+ }
13449
13470
  export {
13450
13471
  BACKLIGHT_SPILL,
13451
13472
  BLEND_MENU_GROUPS,
@@ -13615,6 +13636,7 @@ export {
13615
13636
  createPaintBrushLibraryToolProvider,
13616
13637
  createPaintChangeFeed,
13617
13638
  createPaintCompositor,
13639
+ createPaintConformanceHost,
13618
13640
  createPaintDocument,
13619
13641
  createPaintEditorDocument,
13620
13642
  createPaintEditorToolProvider,
@@ -0,0 +1,138 @@
1
+ /**
2
+ * Conformance scenarios: a recorded sequence of tool calls with what each one returned, so
3
+ * another implementation of an editor (the Swift port, #533) can replay the same calls and check
4
+ * it gets the same results, documents and pixels. `@pixerate/conformance` holds the scenarios
5
+ * (`domains/<domain>/fixtures/*.json`); `scripts/record-conformance.mjs` records them from this
6
+ * core and a core test replays them.
7
+ *
8
+ * Results are compared after {@link normalizeConformanceValue}: ids an implementation generates
9
+ * (from a clock, say) become `@1`, `@2`, … in the order they are first seen, and binary payloads
10
+ * become `"<binary>"`, so neither the id format nor the PNG encoder is part of the contract. Ids
11
+ * that come from counters or names (`s1`, `pad1`, `ink-pen`) stay as they are. Every implementation applies the same rules (written
12
+ * out in the package README).
13
+ */
14
+ import type { McpToolResult } from './registry.cjs';
15
+ /** One tool call of a scenario and, once recorded, what it returned. */
16
+ export interface ConformanceStep {
17
+ /** Tool name, unprefixed (`paint_stroke`). */
18
+ tool: string;
19
+ /** Arguments. A string `@n` is replaced by the id that `@n` stands for. */
20
+ arguments?: Record<string, unknown>;
21
+ /** Also compare the saved document after this call. */
22
+ document?: boolean;
23
+ /**
24
+ * Also compare the rendered pixels after this call (`paper: false` leaves the paper out;
25
+ * `tolerance` loosens what another implementation is held to for this snapshot).
26
+ */
27
+ pixels?: boolean | {
28
+ paper?: boolean;
29
+ tolerance?: {
30
+ maxDelta?: number;
31
+ meanDelta?: number;
32
+ };
33
+ };
34
+ /**
35
+ * Parts of the result left out of the comparison because they describe this implementation
36
+ * rather than the contract (the wet engine's backend): JSON pointers like `/backend`, where a
37
+ * `*` segment stands for every array element or object member.
38
+ */
39
+ ignore?: string[];
40
+ /** Recorded results, written by the recorder. */
41
+ expect?: ConformanceExpectation;
42
+ }
43
+ export interface ConformanceExpectation {
44
+ /** The normalized `structuredContent`, or `{ error: { code, message, details? } }` for a failed call. */
45
+ result: unknown;
46
+ isError?: true;
47
+ document?: unknown;
48
+ pixels?: ConformancePixels;
49
+ }
50
+ /** A pixel snapshot: the PNG next to the scenario plus how close another implementation must be. */
51
+ export interface ConformancePixels {
52
+ /** PNG file, relative to the scenario file. */
53
+ file: string;
54
+ width: number;
55
+ height: number;
56
+ /** SHA-256 of the RGBA bytes, hex. This core matches it exactly. */
57
+ sha256: string;
58
+ /** Largest difference allowed in any channel of any pixel (0–255). */
59
+ maxDelta: number;
60
+ /** Largest mean difference allowed over all channels. */
61
+ meanDelta: number;
62
+ }
63
+ export interface ConformanceScenario {
64
+ $schema?: string;
65
+ /** Unique kebab-case id within the domain; also the file name. */
66
+ id: string;
67
+ description: string;
68
+ /** Host options, such as the canvas size. */
69
+ setup?: Record<string, unknown>;
70
+ steps: ConformanceStep[];
71
+ /** Reasons an implementation skips the whole scenario, by implementation (`swift`). */
72
+ skip?: Record<string, string>;
73
+ }
74
+ /** What a scenario runs against: a tool registry plus ways to read the document and pixels. */
75
+ export interface ConformanceHost {
76
+ callTool(name: string, args: Record<string, unknown>): Promise<McpToolResult>;
77
+ document(): unknown;
78
+ pixels(options: {
79
+ paper?: boolean;
80
+ }): {
81
+ width: number;
82
+ height: number;
83
+ data: Uint8Array | Uint8ClampedArray;
84
+ };
85
+ /** Whether a string is an id this implementation generated in its own format (default: none). */
86
+ isGeneratedId?(value: string): boolean;
87
+ dispose?(): void;
88
+ }
89
+ /** What one step produced, normalized (pixels are raw RGBA for the caller to hash or encode). */
90
+ export interface ConformanceStepOutput {
91
+ result: unknown;
92
+ isError: boolean;
93
+ document?: unknown;
94
+ pixels?: {
95
+ width: number;
96
+ height: number;
97
+ data: Uint8Array;
98
+ };
99
+ }
100
+ /** Maps real ids to `@n` placeholders and back, across a whole scenario. */
101
+ export declare class ConformanceIds {
102
+ private readonly toPlaceholder;
103
+ private readonly fromPlaceholder;
104
+ /** The placeholder for `id`, assigning the next one when it is new. */
105
+ add(id: string): string;
106
+ placeholder(id: string): string | undefined;
107
+ /** `text` with every known id in it replaced by its placeholder (longest ids first). */
108
+ replaceWithin(text: string): string;
109
+ /** The real id a placeholder stands for. */
110
+ resolve(placeholder: string): string | undefined;
111
+ }
112
+ /** Strings at least this long made only of base64 characters are binary payloads. */
113
+ export declare const CONFORMANCE_BINARY_MIN_LENGTH = 200;
114
+ type IdTest = (value: string) => boolean;
115
+ /**
116
+ * A value as scenarios store it:
117
+ * 1. Every string value or object key the implementation generated as an id (`isGeneratedId`) is
118
+ * numbered `@1`, `@2`, … in the order first seen, walking depth first with object keys sorted
119
+ * (each key before its value); the numbering carries across the scenario's steps.
120
+ * 2. Every known id in a string or object key, whole or inside a longer string (an error message),
121
+ * becomes its placeholder; longer ids are replaced first.
122
+ * 3. A string starting with `data:`, or at least 200 characters of base64, becomes `"<binary>"`.
123
+ * 4. An ISO 8601 date-time string (`2026-11-04T01:06:52.993Z`) becomes `"<time>"`: clocks differ.
124
+ * 5. Object keys are sorted; `undefined` values are dropped (as JSON would).
125
+ */
126
+ export declare function normalizeConformanceValue(value: unknown, ids: ConformanceIds, isGeneratedId?: IdTest): unknown;
127
+ /** `value` without the members at `paths` (`/a/b`, `*` for every element or member). */
128
+ export declare function omitConformancePaths(value: unknown, paths: readonly string[]): unknown;
129
+ /** Arguments with each `@n` placeholder string replaced by the id it stands for. */
130
+ export declare function resolveConformanceArguments(value: unknown, ids: ConformanceIds): unknown;
131
+ /** The comparable part of a tool result: `structuredContent`, or the error's code, message and details. */
132
+ export declare function conformanceResult(result: McpToolResult): {
133
+ value: unknown;
134
+ isError: boolean;
135
+ };
136
+ /** Runs a scenario's calls in order against a fresh host and returns what each step produced. */
137
+ export declare function runConformanceScenario(scenario: ConformanceScenario, host: ConformanceHost): Promise<ConformanceStepOutput[]>;
138
+ export {};