@pixerate/editor 0.107.0 → 0.109.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/THIRD_PARTY_NOTICES.md +4 -0
- package/dist/animation/index.cjs +5 -5
- package/dist/animation/index.cjs.map +1 -1
- package/dist/animation/index.js +9 -9
- package/dist/animation-editor/index.cjs +59 -59
- package/dist/animation-editor/index.cjs.map +1 -1
- package/dist/animation-editor/index.d.cts +2 -1
- package/dist/animation-editor/index.d.ts +2 -1
- package/dist/animation-editor/index.js +29 -29
- package/dist/canvas/index.cjs +27 -27
- package/dist/canvas/index.cjs.map +1 -1
- package/dist/canvas/index.js +11 -11
- package/dist/{chunk-2FGRTYJN.cjs → chunk-477UVMNR.cjs} +3 -3
- package/dist/{chunk-2FGRTYJN.cjs.map → chunk-477UVMNR.cjs.map} +1 -1
- package/dist/{chunk-T3QZ6S47.cjs → chunk-AZTZRLDI.cjs} +40 -2
- package/dist/chunk-AZTZRLDI.cjs.map +1 -0
- package/dist/{chunk-63EFQCT5.js → chunk-BLWCAQCW.js} +2879 -3362
- package/dist/chunk-BLWCAQCW.js.map +1 -0
- package/dist/{chunk-G4BIYE6R.js → chunk-CFMWALBM.js} +39 -1
- package/dist/chunk-CFMWALBM.js.map +1 -0
- package/dist/{chunk-FRD3FUXI.cjs → chunk-D37BX2ZA.cjs} +2081 -460
- package/dist/chunk-D37BX2ZA.cjs.map +1 -0
- package/dist/chunk-JLYX4V57.cjs +2001 -0
- package/dist/chunk-JLYX4V57.cjs.map +1 -0
- package/dist/chunk-KB2YBCVS.js +2001 -0
- package/dist/chunk-KB2YBCVS.js.map +1 -0
- package/dist/{chunk-SOROZ2BF.js → chunk-RE77QYUF.js} +1938 -317
- package/dist/chunk-RE77QYUF.js.map +1 -0
- package/dist/{chunk-KANRAHTL.cjs → chunk-W3GXSUSQ.cjs} +2830 -3313
- package/dist/chunk-W3GXSUSQ.cjs.map +1 -0
- package/dist/{chunk-JK6M6V7G.js → chunk-Z3YWVUWT.js} +4 -4
- package/dist/{export-a9bnF7Cl.d.ts → export-BLPLaE6Z.d.ts} +417 -16
- package/dist/{export-JGWQEPJn.d.cts → export-DSUc4fQD.d.cts} +417 -16
- package/dist/image-editor/index.cjs +1527 -1001
- package/dist/image-editor/index.cjs.map +1 -1
- package/dist/image-editor/index.d.cts +73 -9
- package/dist/image-editor/index.d.ts +73 -9
- package/dist/image-editor/index.js +814 -288
- package/dist/image-editor/index.js.map +1 -1
- package/dist/paint-editor/index.cjs +252 -64
- package/dist/paint-editor/index.cjs.map +1 -1
- package/dist/paint-editor/index.d.cts +101 -4
- package/dist/paint-editor/index.d.ts +101 -4
- package/dist/paint-editor/index.js +196 -8
- package/dist/paint-editor/index.js.map +1 -1
- package/dist/raster/index.cjs +4 -2
- package/dist/raster/index.cjs.map +1 -1
- package/dist/raster/index.d.cts +3 -129
- package/dist/raster/index.d.ts +3 -129
- package/dist/raster/index.js +3 -1
- package/dist/{compositor-D92URMlm.d.cts → render-C-fO_mes.d.cts} +135 -1
- package/dist/{compositor-Kt_M4ruo.d.ts → render-OLIMk_v0.d.ts} +135 -1
- package/dist/{svg-vme0PLNo.d.ts → svg-D_cfkhlB.d.cts} +6 -608
- package/dist/{svg-Bj1MQFh6.d.cts → svg-wIaKLrU0.d.ts} +6 -608
- package/dist/types-DtL_qLFz.d.ts +630 -0
- package/dist/types-DyQq-WPY.d.cts +630 -0
- package/dist/vector/index.cjs +1080 -1051
- package/dist/vector/index.cjs.map +1 -1
- package/dist/vector/index.d.cts +268 -7
- package/dist/vector/index.d.ts +268 -7
- package/dist/vector/index.js +495 -466
- package/dist/vector/index.js.map +1 -1
- package/dist/video-editor/index.cjs +3 -3
- package/dist/video-editor/index.js +2 -2
- package/package.json +1 -1
- package/skills/pixerate-image-editor/SKILL.md +50 -7
- package/skills/pixerate-vector/SKILL.md +35 -5
- package/dist/chunk-63EFQCT5.js.map +0 -1
- package/dist/chunk-DWGZUSES.cjs +0 -694
- package/dist/chunk-DWGZUSES.cjs.map +0 -1
- package/dist/chunk-FRD3FUXI.cjs.map +0 -1
- package/dist/chunk-G4BIYE6R.js.map +0 -1
- package/dist/chunk-KANRAHTL.cjs.map +0 -1
- package/dist/chunk-KKREERP2.js +0 -694
- package/dist/chunk-KKREERP2.js.map +0 -1
- package/dist/chunk-SOROZ2BF.js.map +0 -1
- package/dist/chunk-T3QZ6S47.cjs.map +0 -1
- /package/dist/{chunk-JK6M6V7G.js.map → chunk-Z3YWVUWT.js.map} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/paint-editor/noise.ts","../../src/paint-editor/paper.ts","../../src/paint-editor/document.ts","../../src/paint-editor/brushes.ts","../../src/paint-editor/engine.ts","../../src/paint-editor/stroke.ts","../../src/paint-editor/strokes.ts","../../src/paint-editor/render.ts","../../src/paint-editor/serialize.ts","../../src/paint-editor/view.ts","../../src/paint-editor/input.ts","../../src/paint-editor/encode.ts","../../src/paint-editor/thumbnails.ts","../../src/paint-editor/guides.ts","../../src/paint-editor/color.ts","../../src/paint-editor/mixing-pad.ts","../../src/paint-editor/controller.ts","../../src/paint-editor/guide-tools.ts","../../src/paint-editor/tools.ts","../../src/paint-editor/ui.ts"],"sourcesContent":["// Portions ported from photocraft/crates/paint/src/procedural.rs and rng.rs (MIT OR Apache-2.0, © ArtCraft Team and contributors). See THIRD_PARTY_NOTICES.md.\n\n/**\n * Seeded, deterministic noise for paper grain and brush jitter (photocraft's counter-based\n * randomness and tileable value noise, on 32-bit integer hashes instead of 64-bit ones so it runs\n * fast in JavaScript). Every value is a pure function of its inputs, so a paper or a stroke\n * regenerates identically on every machine.\n */\n\n/** A 32-bit finaliser (murmur3's `fmix32`). */\nexport function mix32(h: number): number {\n h ^= h >>> 16;\n h = Math.imul(h, 0x85ebca6b);\n h ^= h >>> 13;\n h = Math.imul(h, 0xc2b2ae35);\n h ^= h >>> 16;\n return h >>> 0;\n}\n\n/** Hash of integer coordinates and a salt to [0, 1). */\nexport function hash2(x: number, y: number, salt: number): number {\n const h = mix32((Math.imul(x | 0, 0x27d4eb2d) ^ mix32((y | 0) + Math.imul(salt | 0, 0x165667b1))) >>> 0);\n return h / 4294967296;\n}\n\n/** Uniform in [0, 1) from a seed, an index and a stream (one stream per random quantity). */\nexport function rand01(seed: number, index: number, stream: number): number {\n return hash2(index, stream, seed);\n}\n\n/** Uniform in [-1, 1). */\nexport function randSigned(seed: number, index: number, stream: number): number {\n return rand01(seed, index, stream) * 2 - 1;\n}\n\n/** A seed from a string (FNV-1a, then mixed). */\nexport function seedFromString(text: string): number {\n let h = 0x811c9dc5;\n for (let i = 0; i < text.length; i++) {\n h ^= text.charCodeAt(i);\n h = Math.imul(h, 0x01000193);\n }\n return mix32(h >>> 0);\n}\n\nconst smooth = (t: number) => t * t * (3 - 2 * t);\n\n/** A periodic lattice of `px × py` random values, sampled with smooth interpolation. */\nclass Lattice {\n readonly values: Float32Array;\n constructor(readonly px: number, readonly py: number, salt: number) {\n this.values = new Float32Array(px * py);\n for (let j = 0; j < py; j++) for (let i = 0; i < px; i++) this.values[j * px + i] = hash2(i, j, salt);\n }\n\n /** Value noise at (x, y) in lattice cells; wraps every `px` / `py` cells. */\n at(x: number, y: number): number {\n const { px, py } = this;\n const x0 = Math.floor(x);\n const y0 = Math.floor(y);\n const tx = smooth(x - x0);\n const ty = smooth(y - y0);\n const i0 = ((x0 % px) + px) % px;\n const j0 = ((y0 % py) + py) % py;\n const i1 = (i0 + 1) % px;\n const j1 = (j0 + 1) % py;\n const v = this.values;\n const a = v[j0 * px + i0] + (v[j0 * px + i1] - v[j0 * px + i0]) * tx;\n const b = v[j1 * px + i0] + (v[j1 * px + i1] - v[j1 * px + i0]) * tx;\n return a + (b - a) * ty;\n }\n}\n\n/**\n * Tileable fractal value noise in 0..1 over a `size`-pixel square: `cellsX × cellsY` lattice cells\n * at the base octave (unequal counts give fibres and streaks), doubling per octave, so the result\n * repeats exactly every `size` pixels.\n */\nexport class TileableNoise {\n private readonly octaves: Lattice[] = [];\n\n constructor(readonly size: number, cellsX: number, cellsY: number, octaves: number, salt: number) {\n let cx = Math.max(1, Math.round(cellsX));\n let cy = Math.max(1, Math.round(cellsY));\n for (let o = 0; o < octaves; o++) {\n this.octaves.push(new Lattice(cx, cy, (salt + o * 7919) | 0));\n cx *= 2;\n cy *= 2;\n }\n }\n\n /** Fractal noise at pixel (x, y). */\n at(x: number, y: number): number {\n let sum = 0;\n let amp = 1;\n let norm = 0;\n const u = x / this.size;\n const v = y / this.size;\n for (const l of this.octaves) {\n sum += l.at(u * l.px, v * l.py) * amp;\n norm += amp;\n amp *= 0.5;\n }\n return norm > 0 ? sum / norm : 0.5;\n }\n}\n","/**\n * Paper: a generated grain height map (0 = valley, 1 = peak) that tiles across the canvas, a paper\n * colour, grain depth, and the three properties wet media will read later (absorption,\n * permeability, roughness). Dry media catch the peaks: a light stroke only marks the high grain, a\n * firm one fills the valleys too. Everything is generated from a pattern and a seed, so a paper is\n * a few numbers in the document, never a bitmap, and no third-party texture is bundled.\n */\n\nimport { hash2, TileableNoise } from './noise';\n\n/** Grain generators. Each is our own procedural pattern (no scanned textures). */\nexport type GrainPattern =\n | 'smooth'\n | 'cold-pressed'\n | 'hot-pressed'\n | 'rough'\n | 'vellum'\n | 'laid'\n | 'ingres'\n | 'sanded'\n | 'canvas'\n | 'linen'\n | 'gesso';\n\nexport const GRAIN_PATTERNS: readonly GrainPattern[] = ['smooth', 'cold-pressed', 'hot-pressed', 'rough', 'vellum', 'laid', 'ingres', 'sanded', 'canvas', 'linen', 'gesso'];\n\n/** Paper families, as a library groups them. */\nexport type PaperFamily = 'watercolor' | 'drawing' | 'pastel' | 'canvas' | 'panel' | 'smooth';\n\nexport const PAPER_FAMILIES: readonly PaperFamily[] = ['watercolor', 'drawing', 'pastel', 'canvas', 'panel', 'smooth'];\n\n/** How a height map is tuned for one kind of media. */\nexport interface GrainTuning {\n /** Height contrast around the middle, 0..3 (default 1). */\n contrast: number;\n /** Swap peaks and valleys (default false). */\n invert: boolean;\n}\n\nexport type PaperTiling = 'repeat' | 'mirror';\n\nexport interface PaperSettings {\n /** The library preset this paper started from (`custom` when it matches none). */\n preset: string;\n name: string;\n family: PaperFamily;\n pattern: GrainPattern;\n /** Grain seed: another seed gives another sheet of the same paper. */\n seed: number;\n /** Paper colour #rrggbb. */\n color: string;\n /** Grain scale: 1 is the pattern's natural size, 2 twice as coarse (0.25..8). */\n scale: number;\n /** How the grain tile repeats: `repeat` or `mirror` (alternate tiles flipped, so seams vanish). */\n tiling: PaperTiling;\n /** Grain depth 0..1: how much grain-responsive dry media skip the valleys (0: none). */\n depth: number;\n /** How much the grain shades the paper colour on screen and in exports, 0..1. */\n shading: number;\n /** The height map as dry media read it. */\n dry: GrainTuning;\n /** The height map as wet media will read it (stored now; wet media is a later phase). */\n wet: GrainTuning;\n /** Wet media: how fast the paper takes up water, 0..1. */\n absorption: number;\n /** Wet media: how far water spreads inside the paper, 0..1. */\n permeability: number;\n /** Wet media: how much the grain catches pigment, 0..1. */\n roughness: number;\n}\n\n/** Side of the generated grain tile in pixels (at scale 1). */\nexport const GRAIN_TILE = 256;\n\nconst unit = (v: unknown, d: number) => (typeof v === 'number' && Number.isFinite(v) ? Math.min(1, Math.max(0, v)) : d);\nconst clampNum = (v: unknown, lo: number, hi: number, d: number) => (typeof v === 'number' && Number.isFinite(v) ? Math.min(hi, Math.max(lo, v)) : d);\nconst HEX = /^#[0-9a-f]{6}$/i;\n\ntype PaperPreset = PaperSettings;\n\nconst tuning = (contrast = 1, invert = false): GrainTuning => ({ contrast, invert });\n\nfunction preset(\n id: string,\n name: string,\n family: PaperFamily,\n pattern: GrainPattern,\n color: string,\n o: { depth: number; absorption: number; permeability: number; roughness: number; scale?: number; seed?: number; shading?: number; contrast?: number }\n): PaperPreset {\n return {\n preset: id,\n name,\n family,\n pattern,\n seed: o.seed ?? 1,\n color,\n scale: o.scale ?? 1,\n tiling: 'mirror',\n depth: o.depth,\n shading: o.shading ?? 0.5,\n dry: tuning(o.contrast ?? 1),\n wet: tuning(1),\n absorption: o.absorption,\n permeability: o.permeability,\n roughness: o.roughness,\n };\n}\n\n/** The built-in paper library: generated papers in families. */\nexport const PAPER_LIBRARY: readonly PaperPreset[] = [\n preset('cold-pressed', 'Cold pressed watercolour', 'watercolor', 'cold-pressed', '#f7f3ea', { depth: 0.5, absorption: 0.7, permeability: 0.5, roughness: 0.6 }),\n preset('hot-pressed', 'Hot pressed watercolour', 'watercolor', 'hot-pressed', '#f8f6ef', { depth: 0.25, absorption: 0.55, permeability: 0.4, roughness: 0.25 }),\n preset('rough-watercolor', 'Rough watercolour', 'watercolor', 'rough', '#f5f0e4', { depth: 0.75, absorption: 0.8, permeability: 0.6, roughness: 0.85 }),\n preset('cartridge', 'Cartridge', 'drawing', 'vellum', '#fbfaf6', { depth: 0.3, absorption: 0.4, permeability: 0.3, roughness: 0.35 }),\n preset('laid', 'Laid paper', 'drawing', 'laid', '#f3ecdc', { depth: 0.45, absorption: 0.45, permeability: 0.35, roughness: 0.45 }),\n preset('ingres', 'Charcoal paper', 'drawing', 'ingres', '#ede6d6', { depth: 0.6, absorption: 0.4, permeability: 0.3, roughness: 0.65 }),\n preset('sanded-pastel', 'Sanded pastel paper', 'pastel', 'sanded', '#d8cfc0', { depth: 0.7, absorption: 0.3, permeability: 0.2, roughness: 0.9, shading: 0.35 }),\n preset('pastel-card', 'Grey pastel card', 'pastel', 'sanded', '#9c978e', { depth: 0.55, absorption: 0.3, permeability: 0.2, roughness: 0.75, scale: 1.5, shading: 0.3 }),\n preset('cotton-canvas', 'Cotton canvas', 'canvas', 'canvas', '#efe9dc', { depth: 0.55, absorption: 0.35, permeability: 0.25, roughness: 0.6 }),\n preset('fine-linen', 'Fine linen', 'canvas', 'linen', '#e9e2d2', { depth: 0.45, absorption: 0.3, permeability: 0.25, roughness: 0.5 }),\n preset('gesso', 'Gesso panel', 'panel', 'gesso', '#f6f4ef', { depth: 0.35, absorption: 0.2, permeability: 0.15, roughness: 0.4 }),\n preset('smooth', 'Smooth bristol', 'smooth', 'smooth', '#ffffff', { depth: 0, absorption: 0.3, permeability: 0.2, roughness: 0.05, shading: 0 }),\n];\n\nexport const DEFAULT_PAPER: Readonly<PaperSettings> = PAPER_LIBRARY[0];\n\n/** A paper from the library by id, or `undefined`. */\nexport function paperPreset(id: string): PaperSettings | undefined {\n const p = PAPER_LIBRARY.find((x) => x.preset === id);\n return p ? clonePaper(p) : undefined;\n}\n\nexport function clonePaper(p: PaperSettings): PaperSettings {\n return { ...p, dry: { ...p.dry }, wet: { ...p.wet } };\n}\n\nfunction readTuning(raw: unknown, d: GrainTuning): GrainTuning {\n const r = raw && typeof raw === 'object' ? (raw as Record<string, unknown>) : {};\n return { contrast: clampNum(r.contrast, 0, 3, d.contrast), invert: typeof r.invert === 'boolean' ? r.invert : d.invert };\n}\n\n/**\n * A paper with every field in range. Missing fields come from `base` (default: the library preset\n * named by `raw.preset`, else cold pressed).\n */\nexport function normalizePaper(raw: Partial<PaperSettings> | Record<string, unknown> = {}, base?: PaperSettings): PaperSettings {\n const r = raw as Record<string, unknown>;\n const b = base ?? (typeof r.preset === 'string' ? paperPreset(r.preset) : undefined) ?? clonePaper(DEFAULT_PAPER);\n return {\n preset: typeof r.preset === 'string' && r.preset ? r.preset : b.preset,\n name: typeof r.name === 'string' && r.name.trim() ? r.name.trim() : b.name,\n family: PAPER_FAMILIES.includes(r.family as PaperFamily) ? (r.family as PaperFamily) : b.family,\n pattern: GRAIN_PATTERNS.includes(r.pattern as GrainPattern) ? (r.pattern as GrainPattern) : b.pattern,\n seed: typeof r.seed === 'number' && Number.isFinite(r.seed) ? Math.round(Math.abs(r.seed)) % 2147483647 : b.seed,\n color: typeof r.color === 'string' && HEX.test(r.color) ? r.color.toLowerCase() : b.color,\n scale: clampNum(r.scale, 0.25, 8, b.scale),\n tiling: r.tiling === 'repeat' || r.tiling === 'mirror' ? r.tiling : b.tiling,\n depth: unit(r.depth, b.depth),\n shading: unit(r.shading, b.shading),\n dry: readTuning(r.dry, b.dry),\n wet: readTuning(r.wet, b.wet),\n absorption: unit(r.absorption, b.absorption),\n permeability: unit(r.permeability, b.permeability),\n roughness: unit(r.roughness, b.roughness),\n };\n}\n\n// ---------------------------------------------------------------------------\n// Height maps\n// ---------------------------------------------------------------------------\n\nconst clamp01 = (v: number) => (v < 0 ? 0 : v > 1 ? 1 : v);\n\n/** One pattern's raw height (0..1) at pixel (x, y) of a `n`-pixel tile. */\nfunction patternHeights(pattern: GrainPattern, n: number, seed: number): Float32Array {\n const out = new Float32Array(n * n);\n const salt = Math.imul(seed | 0, 0x9e3779b1) + 17;\n if (pattern === 'smooth') return out.fill(1);\n const noise = (cx: number, cy: number, oct: number, s = 0) => new TileableNoise(n, cx, cy, oct, salt + s);\n const k = n / GRAIN_TILE;\n switch (pattern) {\n case 'cold-pressed': {\n const base = noise(20 * k, 20 * k, 4);\n const fine = noise(64 * k, 64 * k, 2, 3);\n for (let y = 0; y < n; y++)\n for (let x = 0; x < n; x++) out[y * n + x] = clamp01((base.at(x, y) - 0.5) * 1.8 + 0.5 + (fine.at(x, y) - 0.5) * 0.5 + (hash2(x, y, salt) - 0.5) * 0.12);\n break;\n }\n case 'hot-pressed': {\n const base = noise(40 * k, 40 * k, 3);\n for (let y = 0; y < n; y++) for (let x = 0; x < n; x++) out[y * n + x] = clamp01((base.at(x, y) - 0.5) * 1.1 + 0.6 + (hash2(x, y, salt) - 0.5) * 0.08);\n break;\n }\n case 'rough': {\n const base = noise(10 * k, 10 * k, 5);\n const blot = noise(28 * k, 28 * k, 2, 5);\n for (let y = 0; y < n; y++)\n for (let x = 0; x < n; x++) out[y * n + x] = clamp01((base.at(x, y) - 0.5) * 2.4 + 0.5 + (blot.at(x, y) - 0.5) * 0.7 + (hash2(x, y, salt) - 0.5) * 0.15);\n break;\n }\n case 'vellum': {\n const base = noise(40 * k, 40 * k, 3);\n for (let y = 0; y < n; y++) for (let x = 0; x < n; x++) out[y * n + x] = clamp01((base.at(x, y) - 0.5) * 1.6 + 0.55 + (hash2(x, y, salt) - 0.5) * 0.2);\n break;\n }\n case 'laid': {\n // Fine laid lines across, chain lines down every eighth of the tile, a little pulp noise.\n const pulp = noise(32 * k, 32 * k, 3);\n const chain = n / 8;\n for (let y = 0; y < n; y++) {\n const laid = 0.5 + 0.5 * Math.cos((2 * Math.PI * y) / 4);\n for (let x = 0; x < n; x++) {\n const c = Math.abs(((x + 0.5) % chain) - chain / 2) / (chain / 2);\n const chainLine = c > 0.94 ? -0.35 : 0;\n out[y * n + x] = clamp01(0.3 + 0.5 * laid + chainLine + (pulp.at(x, y) - 0.5) * 0.6);\n }\n }\n break;\n }\n case 'ingres': {\n // Long vertical fibres with grit.\n const fibres = noise(64 * k, 12 * k, 3);\n const base = noise(16 * k, 16 * k, 3, 7);\n for (let y = 0; y < n; y++)\n for (let x = 0; x < n; x++) {\n const g = hash2(x, y, salt ^ 0x55);\n out[y * n + x] = clamp01((fibres.at(x, y) - 0.5) * 1.5 + (base.at(x, y) - 0.5) * 0.7 + 0.55 + (g < 0.1 ? -0.3 : 0));\n }\n break;\n }\n case 'sanded': {\n // Fine grit: high-frequency noise and sharp single-pixel pits.\n const grit = noise(96 * k, 96 * k, 2);\n for (let y = 0; y < n; y++)\n for (let x = 0; x < n; x++) {\n const h = hash2(x, y, salt);\n out[y * n + x] = clamp01((grit.at(x, y) - 0.5) * 2.4 + 0.5 + (h - 0.5) * 0.7);\n }\n break;\n }\n case 'canvas':\n case 'linen': {\n // Over / under weave; linen has finer, irregular threads.\n const period = (pattern === 'canvas' ? 8 : 5) * k;\n // An even thread count keeps the over / under alternation seamless across the tile edge.\n const threads = Math.max(2, 2 * Math.round(n / period / 2));\n const p = n / threads;\n const slub = noise(threads, threads, 2, 11);\n for (let y = 0; y < n; y++)\n for (let x = 0; x < n; x++) {\n const fx = (x + 0.5) / p;\n const fy = (y + 0.5) / p;\n const cx = Math.floor(fx);\n const cy = Math.floor(fy);\n const warp = Math.sin(Math.PI * (fx - cx));\n const weft = Math.sin(Math.PI * (fy - cy));\n const top = (cx + cy) % 2 === 0 ? warp : weft;\n const irregular = pattern === 'linen' ? (slub.at(x, y) - 0.5) * 0.5 : 0;\n out[y * n + x] = clamp01(0.2 + 0.7 * top + irregular + (hash2(x, y, salt) - 0.5) * 0.15);\n }\n break;\n }\n case 'gesso': {\n // Brushed gesso: soft horizontal streaks over a fine tooth.\n const streaks = noise(2 * k, 28 * k, 3);\n const tooth = noise(64 * k, 64 * k, 2, 13);\n for (let y = 0; y < n; y++)\n for (let x = 0; x < n; x++) out[y * n + x] = clamp01((streaks.at(x, y) - 0.5) * 1.8 + (tooth.at(x, y) - 0.5) * 0.9 + 0.55);\n break;\n }\n }\n return out;\n}\n\nconst rawCache = new Map<string, Float32Array>();\n\n/** The raw height map of a pattern (`GRAIN_TILE` square, 0..1), generated once per pattern and seed. */\nexport function grainHeights(pattern: GrainPattern, seed: number, size = GRAIN_TILE): Float32Array {\n const key = `${pattern}:${seed}:${size}`;\n let h = rawCache.get(key);\n if (!h) {\n h = patternHeights(pattern, size, seed);\n if (rawCache.size > 32) rawCache.delete(rawCache.keys().next().value as string);\n rawCache.set(key, h);\n }\n return h;\n}\n\n/**\n * A paper's height field over the canvas (document pixels), tuned for one kind of media. Read it\n * with `at(x, y)`: bilinear, tiled by `paper.tiling`, at `paper.scale`.\n */\nexport class PaperGrain {\n readonly size = GRAIN_TILE;\n private readonly heights: Float32Array;\n private readonly scale: number;\n private readonly mirror: boolean;\n readonly flat: boolean;\n\n constructor(paper: PaperSettings, media: 'dry' | 'wet' = 'dry') {\n const raw = grainHeights(paper.pattern, paper.seed);\n const t = paper[media];\n this.flat = paper.pattern === 'smooth';\n if (t.contrast === 1 && !t.invert) this.heights = raw;\n else {\n const out = new Float32Array(raw.length);\n for (let i = 0; i < raw.length; i++) {\n const v = clamp01((raw[i] - 0.5) * t.contrast + 0.5);\n out[i] = t.invert ? 1 - v : v;\n }\n this.heights = out;\n }\n this.scale = paper.scale;\n this.mirror = paper.tiling === 'mirror';\n }\n\n /** Tile cell index for a coordinate in grain pixels (mirrored on odd tiles when mirroring). */\n private wrap(v: number): number {\n const n = this.size;\n if (!this.mirror) return ((v % n) + n) % n;\n const p = ((v % (2 * n)) + 2 * n) % (2 * n);\n return p < n ? p : 2 * n - 1 - p;\n }\n\n /** Height 0..1 at document position (x, y). */\n at(x: number, y: number): number {\n const u = x / this.scale - 0.5;\n const v = y / this.scale - 0.5;\n const x0 = Math.floor(u);\n const y0 = Math.floor(v);\n const fx = u - x0;\n const fy = v - y0;\n const n = this.size;\n const h = this.heights;\n const a = this.wrap(x0);\n const b = this.wrap(x0 + 1);\n const c = this.wrap(y0) * n;\n const d = this.wrap(y0 + 1) * n;\n const top = h[c + a] + (h[c + b] - h[c + a]) * fx;\n const bot = h[d + a] + (h[d + b] - h[d + a]) * fx;\n return top + (bot - top) * fy;\n }\n}\n\n/**\n * How much of a dry dab lands at grain height `h` (0..1): the media catches the peaks first, and\n * pressure pushes it into the valleys. `depth` is the paper's grain depth times the brush's grain\n * response; at 0 everything lands (1).\n */\nexport function grainCatch(h: number, depth: number, pressure: number): number {\n if (depth <= 0) return 1;\n const t = depth * (0.75 - 0.65 * Math.min(1, Math.max(0, pressure)));\n const u = clamp01((h - t + 0.18) / 0.36);\n return 1 - depth + depth * u * u * (3 - 2 * u);\n}\n\n/** `#rrggbb` → [r, g, b] 0..255. */\nexport function hexToRgb8(hex: string): [number, number, number] {\n const n = parseInt(hex.slice(1, 7), 16);\n return [(n >> 16) & 255, (n >> 8) & 255, n & 255];\n}\n\n/**\n * The paper as opaque RGBA over `rect` (document pixels): its colour, darkened in the valleys by\n * `shading`.\n */\nexport function renderPaper(paper: PaperSettings, rect: { x: number; y: number; width: number; height: number }, grain = new PaperGrain(paper)): Uint8ClampedArray {\n const [r, g, b] = hexToRgb8(paper.color);\n const out = new Uint8ClampedArray(rect.width * rect.height * 4);\n const shade = grain.flat ? 0 : paper.shading * 0.16;\n for (let y = 0; y < rect.height; y++) {\n for (let x = 0; x < rect.width; x++) {\n const i = (y * rect.width + x) * 4;\n const k = shade ? 1 - shade * (1 - grain.at(rect.x + x + 0.5, rect.y + y + 0.5)) : 1;\n out[i] = r * k;\n out[i + 1] = g * k;\n out[i + 2] = b * k;\n out[i + 3] = 255;\n }\n }\n return out;\n}\n","/**\n * The paint editor's document: a canvas (size and resolution), a paper, and the shared raster\n * layer stack (`@pixerate/editor/raster`: pixel layers and groups with masks, clipping, locks and\n * blend modes). Layers are immutable and share tiles, so a history entry is a reference to a\n * whole document state.\n *\n * Saved documents are JSON plus PNG assets, through the image editor's layer serializer (so the\n * same layer tree loads in both editors), with the paper as plain settings.\n */\n\nimport type { RasterGroupLayer, RasterLayer, RasterPixelLayer } from '../raster/layers';\nimport { emptySurface } from '../raster/surface';\nimport { normalizePaper, type PaperSettings } from './paper';\nimport type { RecordedStroke } from './strokes';\n\nexport type PaintPixelLayer = RasterPixelLayer;\nexport type PaintGroupLayer = RasterGroupLayer<PaintLayer>;\n/** A layer of the paint editor: the shared stack's pixel layers and groups. */\nexport type PaintLayer = RasterLayer;\n\n/** Canvas size limits (pixels per side). */\nexport const MIN_CANVAS_SIDE = 1;\nexport const MAX_CANVAS_SIDE = 16384;\nexport const DEFAULT_DPI = 300;\n\nexport interface PaintCanvas {\n width: number;\n height: number;\n /** Pixels per inch, for print sizes and PSD resolution (default 300). */\n dpi: number;\n}\n\n/** Everything one undo step restores. */\nexport interface PaintDocumentState {\n canvas: PaintCanvas;\n paper: PaperSettings;\n /** Bottom to top. */\n layers: PaintLayer[];\n activeLayerId: string | null;\n /** Every committed stroke, oldest first (strokes are data: replay, vary, time-lapse later). */\n strokes: RecordedStroke[];\n}\n\nlet nextId = 1;\n\n/** A new layer id, unique in this session. */\nexport function newPaintLayerId(): string {\n return `pl${Date.now().toString(36)}${(nextId++).toString(36)}`;\n}\n\n/** An empty, visible, normal pixel layer. */\nexport function createPaintLayer(name: string, id = newPaintLayerId()): PaintPixelLayer {\n return { type: 'pixel', id, name, visible: true, opacity: 1, blend: 'normal', surface: emptySurface(4), offset: { x: 0, y: 0 } };\n}\n\nexport class PaintDocumentError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'PaintDocumentError';\n }\n}\n\n/** Validates and rounds a canvas size; throws a `PaintDocumentError` that says what is wrong. */\nexport function normalizeCanvas(raw: Partial<PaintCanvas>): PaintCanvas {\n const side = (v: unknown, what: string) => {\n if (typeof v !== 'number' || !Number.isFinite(v)) throw new PaintDocumentError(`${what} must be a number of pixels (${MIN_CANVAS_SIDE}..${MAX_CANVAS_SIDE}).`);\n const n = Math.round(v);\n if (n < MIN_CANVAS_SIDE || n > MAX_CANVAS_SIDE) throw new PaintDocumentError(`${what} ${n} is out of range; use ${MIN_CANVAS_SIDE}..${MAX_CANVAS_SIDE} pixels.`);\n return n;\n };\n const dpi = raw.dpi === undefined ? DEFAULT_DPI : raw.dpi;\n if (typeof dpi !== 'number' || !Number.isFinite(dpi) || dpi < 1 || dpi > 10000) throw new PaintDocumentError(`dpi ${dpi} is out of range; use 1..10000.`);\n return { width: side(raw.width, 'width'), height: side(raw.height, 'height'), dpi: Math.round(dpi * 100) / 100 };\n}\n\n/** A blank document: one empty layer over the paper. */\nexport function createPaintDocument(options: Partial<PaintCanvas> & { paper?: Partial<PaperSettings> } = {}): PaintDocumentState {\n const canvas = normalizeCanvas({ width: options.width ?? 2048, height: options.height ?? 1536, dpi: options.dpi });\n const layer = createPaintLayer('Layer 1');\n return { canvas, paper: normalizePaper(options.paper ?? {}), layers: [layer], activeLayerId: layer.id, strokes: [] };\n}\n","/**\n * Paint editor brushes: the shared engine's tip settings (`@pixerate/editor/paint`) plus what a\n * natural-media brush adds: paper grain response, pen dynamics (pressure, tilt, barrel rotation,\n * velocity), separate pressure smoothing, a rotation mode, jitter, and Mixer Brush settings for\n * the blending brushes. The built-in presets are our own settings; none come from another product.\n */\n\nimport { DEFAULT_BRUSH, MAX_BRUSH_SIZE, normalizeBrush, type BrushSettings } from '../paint/brush';\nimport { DEFAULT_MIXER, normalizeMixer, type MixerSettings } from '../paint/mixer';\n\n/** How a brush makes marks: dabs into a stroke buffer, removing alpha, or the Mixer Brush engine. */\nexport type PaintBrushEngine = 'dab' | 'eraser' | 'mixer';\n\nexport const PAINT_BRUSH_ENGINES: readonly PaintBrushEngine[] = ['dab', 'eraser', 'mixer'];\n\nexport type PaintBrushCategory = 'pencil' | 'pastel' | 'charcoal' | 'airbrush' | 'marker' | 'ink' | 'eraser' | 'blender' | 'smudge' | 'mixer' | 'custom';\n\nexport const PAINT_BRUSH_CATEGORIES: readonly PaintBrushCategory[] = ['pencil', 'pastel', 'charcoal', 'airbrush', 'marker', 'ink', 'eraser', 'blender', 'smudge', 'mixer', 'custom'];\n\n/** What turns the tip: a fixed angle, the direction of the stroke, or the pen's barrel rotation. */\nexport type BrushRotation = 'fixed' | 'stroke' | 'barrel';\n\nexport const BRUSH_ROTATIONS: readonly BrushRotation[] = ['fixed', 'stroke', 'barrel'];\n\n/** Pen dynamics and jitter. Every amount is 0 (off) .. 1 unless noted. */\nexport interface BrushDynamics {\n /** Size at zero pressure as a fraction of the full size, when pressure controls size (default 0). */\n minSize: number;\n /** How much pressure scales flow (default 0). */\n pressureFlow: number;\n /** Laying the pen down widens the tip, up to 2.5× (default 0). */\n tiltSize: number;\n /** Laying the pen down flattens the tip along the tilt direction (default 0). */\n tiltRoundness: number;\n /** Laying the pen down lightens the mark, as when shading with the side of a pencil (default 0). */\n tiltOpacity: number;\n /** -1..1: positive grows the tip when the pen moves fast, negative thins it (default 0). */\n velocitySize: number;\n /** -1..1: positive darkens fast marks, negative lightens them (default 0). */\n velocityOpacity: number;\n /** Random size change per dab (default 0). */\n sizeJitter: number;\n /** Random angle per dab, as a fraction of ±180° (default 0). */\n angleJitter: number;\n /** Random opacity drop per dab (default 0). */\n opacityJitter: number;\n /** Random offset across the stroke in diameters, 0..4 (default 0). */\n scatter: number;\n}\n\nexport const DEFAULT_DYNAMICS: Readonly<BrushDynamics> = {\n minSize: 0,\n pressureFlow: 0,\n tiltSize: 0,\n tiltRoundness: 0,\n tiltOpacity: 0,\n velocitySize: 0,\n velocityOpacity: 0,\n sizeJitter: 0,\n angleJitter: 0,\n opacityJitter: 0,\n scatter: 0,\n};\n\nexport interface PaintBrush {\n /** Library id (lowercase letters, digits and dashes). */\n id: string;\n name: string;\n category: PaintBrushCategory;\n engine: PaintBrushEngine;\n /** The shared engine's tip: size, hardness, spacing, angle, roundness, opacity, flow, position smoothing, pressure to size / opacity, blend. */\n tip: BrushSettings;\n /** How strongly the mark follows the paper grain, 0 (ignores it) .. 1 (catches only the peaks at light pressure). */\n grain: number;\n /** Pressure smoothing 0..0.95, separate from the tip's position smoothing (default 0). */\n pressureSmoothing: number;\n rotation: BrushRotation;\n dynamics: BrushDynamics;\n /** Mixer engine only: the Mixer Brush settings. */\n mixer: MixerSettings;\n /** Mixer engine only: load the current colour each stroke (false: a smudge or blender that only moves paint). */\n loadsColor: boolean;\n /** True for the built-in presets (they cannot be removed or overwritten). */\n builtin?: boolean;\n}\n\nconst unit = (v: unknown, d: number) => (typeof v === 'number' && Number.isFinite(v) ? Math.min(1, Math.max(0, v)) : d);\nconst range = (v: unknown, lo: number, hi: number, d: number) => (typeof v === 'number' && Number.isFinite(v) ? Math.min(hi, Math.max(lo, v)) : d);\n\nexport function normalizeDynamics(raw: Partial<BrushDynamics> = {}, base: BrushDynamics = DEFAULT_DYNAMICS): BrushDynamics {\n return {\n minSize: unit(raw.minSize, base.minSize),\n pressureFlow: unit(raw.pressureFlow, base.pressureFlow),\n tiltSize: unit(raw.tiltSize, base.tiltSize),\n tiltRoundness: unit(raw.tiltRoundness, base.tiltRoundness),\n tiltOpacity: unit(raw.tiltOpacity, base.tiltOpacity),\n velocitySize: range(raw.velocitySize, -1, 1, base.velocitySize),\n velocityOpacity: range(raw.velocityOpacity, -1, 1, base.velocityOpacity),\n sizeJitter: unit(raw.sizeJitter, base.sizeJitter),\n angleJitter: unit(raw.angleJitter, base.angleJitter),\n opacityJitter: unit(raw.opacityJitter, base.opacityJitter),\n scatter: range(raw.scatter, 0, 4, base.scatter),\n };\n}\n\nexport const BRUSH_ID = /^[a-z0-9][a-z0-9-]{0,63}$/;\n\n/** Brush settings to change or read: any subset of a brush, its tip, dynamics and mixer. */\nexport type PaintBrushInput = Partial<Omit<PaintBrush, 'tip' | 'dynamics' | 'mixer'>> & { tip?: Partial<BrushSettings>; dynamics?: Partial<BrushDynamics>; mixer?: Partial<MixerSettings> };\n\n/** A brush with every field in range; missing fields come from `base` (default: a plain round dab brush). */\nexport function normalizePaintBrush(raw: PaintBrushInput = {}, base?: PaintBrush): PaintBrush {\n const b = base ?? BASE_BRUSH;\n const id = typeof raw.id === 'string' && BRUSH_ID.test(raw.id) ? raw.id : b.id;\n return {\n id,\n name: typeof raw.name === 'string' && raw.name.trim() ? raw.name.trim().slice(0, 80) : b.name,\n category: PAINT_BRUSH_CATEGORIES.includes(raw.category as PaintBrushCategory) ? (raw.category as PaintBrushCategory) : b.category,\n engine: PAINT_BRUSH_ENGINES.includes(raw.engine as PaintBrushEngine) ? (raw.engine as PaintBrushEngine) : b.engine,\n tip: normalizeBrush({ ...b.tip, ...(raw.tip ?? {}) }),\n grain: unit(raw.grain, b.grain),\n pressureSmoothing: range(raw.pressureSmoothing, 0, 0.95, b.pressureSmoothing),\n rotation: BRUSH_ROTATIONS.includes(raw.rotation as BrushRotation) ? (raw.rotation as BrushRotation) : b.rotation,\n dynamics: normalizeDynamics(raw.dynamics ?? {}, b.dynamics),\n mixer: normalizeMixer({ ...b.mixer, ...(raw.mixer ?? {}) }),\n loadsColor: typeof raw.loadsColor === 'boolean' ? raw.loadsColor : b.loadsColor,\n ...(raw.builtin ? { builtin: true } : {}),\n };\n}\n\nconst BASE_BRUSH: PaintBrush = {\n id: 'round',\n name: 'Round',\n category: 'custom',\n engine: 'dab',\n tip: { ...DEFAULT_BRUSH },\n grain: 0,\n pressureSmoothing: 0,\n rotation: 'fixed',\n dynamics: { ...DEFAULT_DYNAMICS },\n mixer: { ...DEFAULT_MIXER },\n loadsColor: true,\n};\n\ntype BrushInit = PaintBrushInput & { id: string; name: string; category: PaintBrushCategory };\n\nconst builtin = (init: BrushInit): PaintBrush => ({ ...normalizePaintBrush(init), builtin: true });\n\n/** The built-in brush library. */\nexport const BUILTIN_BRUSHES: readonly PaintBrush[] = [\n builtin({\n id: 'pencil-hb', name: 'HB pencil', category: 'pencil',\n tip: { size: 4, hardness: 0.7, spacing: 0.08, opacity: 0.85, flow: 0.55, smoothing: 0.25, pressureSize: true, pressureOpacity: true },\n grain: 0.85, pressureSmoothing: 0.3,\n dynamics: { minSize: 0.55, tiltSize: 0.9, tiltRoundness: 0.7, tiltOpacity: 0.5 },\n }),\n builtin({\n id: 'pencil-6b', name: '6B pencil', category: 'pencil',\n tip: { size: 7, hardness: 0.55, spacing: 0.07, opacity: 1, flow: 0.75, smoothing: 0.2, pressureSize: true, pressureOpacity: true },\n grain: 0.7, pressureSmoothing: 0.3,\n dynamics: { minSize: 0.5, tiltSize: 1, tiltRoundness: 0.75, tiltOpacity: 0.35 },\n }),\n builtin({\n id: 'soft-pastel', name: 'Soft pastel', category: 'pastel', rotation: 'stroke',\n tip: { size: 32, hardness: 0.55, spacing: 0.05, angle: 90, roundness: 0.55, opacity: 1, flow: 0.7, smoothing: 0.15, pressureSize: false, pressureOpacity: true },\n grain: 1, pressureSmoothing: 0.25,\n dynamics: { sizeJitter: 0.06, angleJitter: 0.02 },\n }),\n builtin({\n id: 'oil-pastel', name: 'Oil pastel', category: 'pastel', rotation: 'stroke',\n tip: { size: 26, hardness: 0.8, spacing: 0.05, angle: 90, roundness: 0.7, opacity: 1, flow: 0.9, smoothing: 0.15, pressureSize: true, pressureOpacity: false, blend: 'pigment' },\n grain: 0.5, pressureSmoothing: 0.25,\n dynamics: { minSize: 0.6 },\n }),\n builtin({\n id: 'charcoal-stick', name: 'Charcoal stick', category: 'charcoal', rotation: 'stroke',\n tip: { size: 26, hardness: 0.4, spacing: 0.05, angle: 90, roundness: 0.35, opacity: 0.95, flow: 0.5, smoothing: 0.15, pressureSize: false, pressureOpacity: true },\n grain: 0.95, pressureSmoothing: 0.2,\n dynamics: { sizeJitter: 0.1, angleJitter: 0.03, tiltSize: 0.6 },\n }),\n builtin({\n id: 'vine-charcoal', name: 'Vine charcoal', category: 'charcoal',\n tip: { size: 10, hardness: 0.3, spacing: 0.06, opacity: 0.75, flow: 0.45, smoothing: 0.2, pressureSize: true, pressureOpacity: true },\n grain: 0.9, pressureSmoothing: 0.2,\n dynamics: { minSize: 0.4, tiltSize: 0.8, tiltRoundness: 0.5, tiltOpacity: 0.3, sizeJitter: 0.08 },\n }),\n builtin({\n id: 'airbrush', name: 'Airbrush', category: 'airbrush',\n tip: { size: 90, hardness: 0, spacing: 0.04, opacity: 1, flow: 0.06, smoothing: 0.3, pressureSize: false, pressureOpacity: false },\n grain: 0, pressureSmoothing: 0.3,\n dynamics: { pressureFlow: 1, tiltSize: 0.5, tiltRoundness: 0.6 },\n }),\n builtin({\n id: 'marker', name: 'Chisel marker', category: 'marker',\n tip: { size: 24, hardness: 0.85, spacing: 0.04, angle: 45, roundness: 0.35, opacity: 0.6, flow: 1, smoothing: 0.3, pressureSize: false, pressureOpacity: false, blend: 'multiply' },\n grain: 0.1,\n }),\n builtin({\n id: 'ink-pen', name: 'Ink pen', category: 'ink',\n tip: { size: 4, hardness: 1, spacing: 0.05, opacity: 1, flow: 1, smoothing: 0.5, pressureSize: true, pressureOpacity: false },\n pressureSmoothing: 0.4,\n dynamics: { minSize: 0.25, velocitySize: -0.45 },\n }),\n builtin({\n id: 'brush-pen', name: 'Brush pen', category: 'ink', rotation: 'stroke',\n tip: { size: 14, hardness: 0.9, spacing: 0.04, roundness: 0.8, opacity: 1, flow: 1, smoothing: 0.5, pressureSize: true, pressureOpacity: false },\n pressureSmoothing: 0.45,\n dynamics: { minSize: 0.05, velocitySize: -0.3 },\n }),\n builtin({\n id: 'eraser-soft', name: 'Soft eraser', category: 'eraser', engine: 'eraser',\n tip: { size: 40, hardness: 0.2, spacing: 0.08, opacity: 1, flow: 0.6, pressureSize: false, pressureOpacity: true },\n }),\n builtin({\n id: 'eraser-hard', name: 'Hard eraser', category: 'eraser', engine: 'eraser',\n tip: { size: 16, hardness: 0.9, spacing: 0.06, opacity: 1, flow: 1, pressureSize: true, pressureOpacity: false },\n grain: 0.3,\n dynamics: { minSize: 0.5 },\n }),\n builtin({\n id: 'blender', name: 'Blender', category: 'blender', engine: 'mixer', loadsColor: false,\n tip: { size: 34, hardness: 0.4, spacing: 0.08, opacity: 1, flow: 0.35, smoothing: 0.2, pressureSize: false, pressureOpacity: true },\n mixer: { wet: 0.7, load: 0, mix: 1, loadEachStroke: false, cleanEachStroke: true, mixing: 'pigment' },\n }),\n builtin({\n id: 'smudge', name: 'Smudge', category: 'smudge', engine: 'mixer', loadsColor: false,\n tip: { size: 26, hardness: 0.6, spacing: 0.06, opacity: 1, flow: 0.8, smoothing: 0.2, pressureSize: false, pressureOpacity: true },\n mixer: { wet: 1, load: 0, mix: 1, loadEachStroke: false, cleanEachStroke: true, mixing: 'rgb' },\n }),\n builtin({\n id: 'mixer-brush', name: 'Mixer Brush', category: 'mixer', engine: 'mixer',\n tip: { size: 30, hardness: 0.7, spacing: 0.1, opacity: 1, flow: 0.5, smoothing: 0.2, pressureSize: true, pressureOpacity: false },\n mixer: { wet: 0.5, load: 0.95, mix: 0.5, loadEachStroke: true, cleanEachStroke: true, mixing: 'pigment' },\n dynamics: { minSize: 0.5 },\n }),\n];\n\nexport const DEFAULT_BRUSH_ID = 'pencil-6b';\n\nexport { MAX_BRUSH_SIZE };\n\n/** A brush as plain JSON (for export, agents and saved libraries): no `builtin` flag. */\nexport function brushToJSON(brush: PaintBrush): Omit<PaintBrush, 'builtin'> {\n const { builtin: _b, ...rest } = brush;\n return JSON.parse(JSON.stringify(rest));\n}\n\n/** The JSON file a brush library exports to and imports from. */\nexport interface BrushLibraryFile {\n format: 'pixerate-brushes';\n version: 1;\n brushes: Array<Omit<PaintBrush, 'builtin'>>;\n}\n\n/**\n * Brushes read from a brush library file (or a bare array of brushes). Each is normalised; ones\n * without a valid id or name are reported in `problems` and skipped.\n */\nexport function parseBrushLibrary(raw: unknown, problems: string[] = []): PaintBrush[] {\n const list = Array.isArray(raw) ? raw : raw && typeof raw === 'object' && Array.isArray((raw as BrushLibraryFile).brushes) ? (raw as BrushLibraryFile).brushes : null;\n if (!list) throw new Error('Not a brush library: expected {\"format\":\"pixerate-brushes\",\"version\":1,\"brushes\":[...]} or an array of brushes.');\n const out: PaintBrush[] = [];\n list.forEach((item, i) => {\n if (!item || typeof item !== 'object') {\n problems.push(`brushes[${i}] is not an object; skipped.`);\n return;\n }\n const r = item as Record<string, unknown>;\n if (typeof r.id !== 'string' || !BRUSH_ID.test(r.id)) {\n problems.push(`brushes[${i}] has no valid id (lowercase letters, digits and dashes); skipped.`);\n return;\n }\n if (typeof r.name !== 'string' || !r.name.trim()) {\n problems.push(`brushes[${i}] (\"${r.id}\") has no name; skipped.`);\n return;\n }\n const { builtin: _b, ...rest } = r;\n out.push(normalizePaintBrush(rest as PaintBrushInput));\n });\n return out;\n}\n","/**\n * The paint editor's dry-media stroke engine, on the shared brush engine (`@pixerate/editor/paint`):\n *\n * - Pen input: pressure, tilt (`tiltX` / `tiltY` or `altitude` / `azimuth`), barrel rotation\n * (`twist`) and time (for velocity). Position and pressure are smoothed separately.\n * - `PenDabWalker` walks the points into the shared `Dab`s at `spacing × diameter`, with every\n * pen channel interpolated, and applies the brush's dynamics, rotation mode and jitter.\n * Jitter is a pure hash of the stroke seed and the dab index, so a stroke replays exactly.\n * - `DryStroke` rasterizes each dab with the shared round tip, multiplies it by how much of it the\n * paper grain catches (`grainCatch`), and builds it up in the shared `CoverageMap`; the session\n * then composites the coverage with the shared `applyStrokeToTile`.\n * - Symmetry: one stroke can paint several copies of its points (mirror and kaleidoscope), each\n * with its own walker, into the same coverage, so the copies are one stroke and one undo step.\n *\n * Pure data in, pixels out: no DOM, no framework.\n */\n\nimport { CoverageMap, dabRect, rasterizeDab, type BrushSettings, type Dab, type StrokePoint } from '../paint/brush';\nimport type { RasterRect } from '../raster/surface';\nimport type { PaintBrush } from './brushes';\nimport { randSigned } from './noise';\nimport { grainCatch, type PaperGrain } from './paper';\n\n/** One pen sample in document pixels. Every channel but x and y is optional. */\nexport interface PenPoint {\n x: number;\n y: number;\n /** 0..1 (missing: 1, a mouse). */\n pressure?: number;\n /** Milliseconds since any fixed origin (for velocity; missing: no velocity dynamics). */\n t?: number;\n /** Pointer Events tilt in degrees, -90..90 (used when `altitude` / `azimuth` are missing). */\n tiltX?: number;\n tiltY?: number;\n /** Radians from the surface: π/2 is upright, 0 lies flat. */\n altitude?: number;\n /** Radians clockwise from the +x axis (screen y points down): where the pen leans. */\n azimuth?: number;\n /** Barrel rotation in degrees clockwise, 0..359. */\n twist?: number;\n}\n\n/** A pen's lean as altitude and azimuth, or `null` when the sample has no tilt. */\nexport function penOrientation(p: PenPoint): { altitude: number; azimuth: number } | null {\n if (typeof p.altitude === 'number' && Number.isFinite(p.altitude)) {\n const altitude = Math.min(Math.PI / 2, Math.max(0, p.altitude));\n const azimuth = typeof p.azimuth === 'number' && Number.isFinite(p.azimuth) ? p.azimuth : 0;\n return { altitude, azimuth };\n }\n const hasX = typeof p.tiltX === 'number' && Number.isFinite(p.tiltX);\n const hasY = typeof p.tiltY === 'number' && Number.isFinite(p.tiltY);\n if (!hasX && !hasY) return null;\n return tiltToOrientation(hasX ? p.tiltX! : 0, hasY ? p.tiltY! : 0);\n}\n\n/** Pointer Events `tiltX` / `tiltY` (degrees) → altitude and azimuth (radians). */\nexport function tiltToOrientation(tiltX: number, tiltY: number): { altitude: number; azimuth: number } {\n const clampT = (v: number) => Math.min(89.999, Math.max(-89.999, v));\n const tx = Math.tan((clampT(tiltX) * Math.PI) / 180);\n const ty = Math.tan((clampT(tiltY) * Math.PI) / 180);\n const r = Math.hypot(tx, ty);\n if (r < 1e-9) return { altitude: Math.PI / 2, azimuth: 0 };\n let azimuth = Math.atan2(ty, tx);\n if (azimuth < 0) azimuth += 2 * Math.PI;\n return { altitude: Math.atan(1 / r), azimuth };\n}\n\nconst pressureOf = (p: PenPoint) => (typeof p.pressure === 'number' && Number.isFinite(p.pressure) ? Math.min(1, Math.max(0, p.pressure)) : 1);\n\n/**\n * Exponential smoothing of position and of pressure, each by its own amount (0..0.95). Feed raw\n * samples; the first sample passes through.\n */\nexport class PenSmoother {\n private pos: { x: number; y: number } | null = null;\n private pressure: number | null = null;\n private readonly a: number;\n private readonly ap: number;\n\n constructor(position: number, pressure: number) {\n this.a = 1 - Math.min(0.95, Math.max(0, position));\n this.ap = 1 - Math.min(0.95, Math.max(0, pressure));\n }\n\n push(p: PenPoint): PenPoint {\n const pr = pressureOf(p);\n if (!this.pos) {\n this.pos = { x: p.x, y: p.y };\n this.pressure = pr;\n return p;\n }\n this.pos = { x: this.pos.x + (p.x - this.pos.x) * this.a, y: this.pos.y + (p.y - this.pos.y) * this.a };\n this.pressure = this.pressure! + (pr - this.pressure!) * this.ap;\n return { ...p, x: this.pos.x, y: this.pos.y, pressure: this.pressure };\n }\n\n /** Where the smoothed position is now (or `null` before the first sample). */\n get position(): { x: number; y: number } | null {\n return this.pos;\n }\n}\n\n/** A linear map of document vectors `[a, b, c, d]`: (x, y) → (a·x + b·y, c·x + d·y). */\nexport type Linear2 = readonly [number, number, number, number];\n\n/** How one copy of a stroke maps the input: a point map and its linear part (for dab angles). */\nexport interface StrokeCopy {\n map(p: PenPoint): PenPoint;\n linear: Linear2;\n}\n\nexport const IDENTITY_COPY: StrokeCopy = { map: (p) => p, linear: [1, 0, 0, 1] };\n\n/** A dab with the pen state it was made at (the shared `Dab` plus pressure for the grain). */\nexport interface PenDab extends Dab {\n pressure: number;\n}\n\nconst enum Stream {\n Size = 1,\n Angle = 2,\n Opacity = 3,\n Scatter = 4,\n}\n\ninterface Sample {\n x: number;\n y: number;\n pressure: number;\n lean: number;\n azimuth: number;\n twist: number | null;\n speed: number | null;\n}\n\n/** Speed (px/ms) at which velocity dynamics reach their full effect. */\nconst FULL_SPEED = 2.5;\n\n/**\n * Walks pen samples into dabs, incrementally (any chunking gives the same dabs). Dab angles are in\n * the shared rasterizer's convention: radians, counter-clockwise with y up.\n */\nexport class PenDabWalker {\n private last: Sample | null = null;\n private nextAt = 0;\n private pendingFirst: Sample | null = null;\n private index = 0;\n private dir = 0;\n private lastT: number | null = null;\n private speed: number | null = null;\n\n constructor(\n readonly brush: PaintBrush,\n private readonly seed = 0,\n private readonly linear: Linear2 = [1, 0, 0, 1]\n ) {}\n\n private sample(p: PenPoint): Sample {\n const o = penOrientation(p);\n let speed: number | null = null;\n if (typeof p.t === 'number' && Number.isFinite(p.t)) {\n if (this.last && this.lastT !== null && p.t > this.lastT) {\n const v = Math.hypot(p.x - this.last.x, p.y - this.last.y) / (p.t - this.lastT);\n this.speed = this.speed === null ? v : this.speed + (v - this.speed) * 0.35;\n }\n this.lastT = p.t;\n speed = this.speed ?? 0;\n }\n return {\n x: p.x,\n y: p.y,\n pressure: pressureOf(p),\n lean: o ? 1 - o.altitude / (Math.PI / 2) : 0,\n azimuth: o ? o.azimuth : 0,\n twist: typeof p.twist === 'number' && Number.isFinite(p.twist) ? p.twist : null,\n speed,\n };\n }\n\n private diameter(s: Sample): number {\n const tip = this.brush.tip;\n const dyn = this.brush.dynamics;\n let d = tip.size;\n if (tip.pressureSize) d *= dyn.minSize + (1 - dyn.minSize) * s.pressure;\n d *= 1 + dyn.tiltSize * s.lean * 1.5;\n if (s.speed !== null && dyn.velocitySize) d *= Math.max(0.05, 1 + dyn.velocitySize * Math.min(1, s.speed / FULL_SPEED) * (dyn.velocitySize < 0 ? 0.85 : 1));\n return d;\n }\n\n private stepLen(s: Sample): number {\n return Math.max(0.5, Math.max(1, this.diameter(s)) * Math.max(0.01, this.brush.tip.spacing));\n }\n\n /** A rasterizer angle (CCW, y up) mapped through this copy's linear part. */\n private mapAngle(theta: number): number {\n const [a, b, c, d] = this.linear;\n if (a === 1 && b === 0 && c === 0 && d === 1) return theta;\n const vx = Math.cos(theta);\n const vy = -Math.sin(theta);\n return Math.atan2(-(c * vx + d * vy), a * vx + b * vy);\n }\n\n private dab(s: Sample): PenDab {\n const { tip, dynamics: dyn, rotation } = this.brush;\n const i = this.index++;\n const seed = this.seed;\n let diameter = this.diameter(s);\n if (dyn.sizeJitter) diameter *= Math.max(0.05, 1 + dyn.sizeJitter * randSigned(seed, i, Stream.Size));\n const base = (tip.angle * Math.PI) / 180;\n let angle: number;\n if (rotation === 'stroke') angle = this.dir + base;\n else if (rotation === 'barrel' && s.twist !== null) angle = this.mapAngle(base - (s.twist * Math.PI) / 180);\n else if (dyn.tiltRoundness > 0 && s.lean > 0.02) angle = this.mapAngle(base - s.azimuth);\n else angle = this.mapAngle(base);\n if (dyn.angleJitter) angle += dyn.angleJitter * Math.PI * randSigned(seed, i, Stream.Angle);\n let opacity = tip.pressureOpacity ? s.pressure : 1;\n opacity *= 1 - dyn.tiltOpacity * s.lean * 0.8;\n if (s.speed !== null && dyn.velocityOpacity) opacity *= Math.max(0, 1 + dyn.velocityOpacity * (Math.min(1, s.speed / FULL_SPEED) - 0.5));\n if (dyn.opacityJitter) opacity *= 1 - dyn.opacityJitter * (randSigned(seed, i, Stream.Opacity) * 0.5 + 0.5);\n const flow = tip.flow * (1 - dyn.pressureFlow + dyn.pressureFlow * s.pressure);\n let { x, y } = s;\n if (dyn.scatter) {\n const off = dyn.scatter * diameter * randSigned(seed, i, Stream.Scatter);\n // Across the stroke: the direction of travel turned a quarter (document y points down).\n x += Math.sin(this.dir) * off;\n y += Math.cos(this.dir) * off;\n }\n return {\n x,\n y,\n radius: Math.max(0.5, diameter / 2),\n alpha: Math.min(1, Math.max(0, flow)),\n opacity: Math.min(1, Math.max(0, opacity)),\n angle,\n roundness: Math.min(1, Math.max(0.01, tip.roundness * (1 - dyn.tiltRoundness * s.lean * 0.8))),\n pressure: s.pressure,\n };\n }\n\n push(p: PenPoint, out: PenDab[]): void {\n const a = this.last;\n const s = this.sample(p);\n if (!a) {\n this.last = s;\n this.pendingFirst = s;\n this.nextAt = this.stepLen(s);\n return;\n }\n const dx = s.x - a.x;\n const dy = s.y - a.y;\n const len = Math.hypot(dx, dy);\n if (len > 1e-9) this.dir = Math.atan2(-dy, dx);\n if (this.pendingFirst) {\n out.push(this.dab(this.pendingFirst));\n this.pendingFirst = null;\n }\n if (len > 1e-9) {\n while (this.nextAt <= len + 1e-9) {\n const f = Math.min(1, this.nextAt / len);\n const lerp = (u: number, v: number) => u + (v - u) * f;\n const q: Sample = {\n x: a.x + dx * f,\n y: a.y + dy * f,\n pressure: lerp(a.pressure, s.pressure),\n lean: lerp(a.lean, s.lean),\n azimuth: lerpAngle(a.azimuth, s.azimuth, f),\n twist: a.twist !== null && s.twist !== null ? lerpDegrees(a.twist, s.twist, f) : s.twist,\n speed: a.speed !== null && s.speed !== null ? lerp(a.speed, s.speed) : s.speed,\n };\n out.push(this.dab(q));\n this.nextAt += this.stepLen(q);\n }\n this.nextAt -= len;\n }\n this.last = s;\n }\n\n finish(out: PenDab[]): void {\n if (this.pendingFirst) {\n out.push(this.dab(this.pendingFirst));\n this.pendingFirst = null;\n }\n }\n}\n\nfunction lerpAngle(a: number, b: number, t: number): number {\n let d = b - a;\n while (d > Math.PI) d -= 2 * Math.PI;\n while (d < -Math.PI) d += 2 * Math.PI;\n return a + d * t;\n}\n\nfunction lerpDegrees(a: number, b: number, t: number): number {\n let d = b - a;\n while (d > 180) d -= 360;\n while (d < -180) d += 360;\n return a + d * t;\n}\n\nexport interface DryStrokeOptions {\n /** The paper's dry height field, or `null` for no grain. */\n grain: PaperGrain | null;\n /** The paper's grain depth, 0..1 (multiplied by the brush's grain response). */\n paperDepth: number;\n /** Jitter seed (record it to replay the stroke exactly). */\n seed?: number;\n /** Copies of the stroke (symmetry); default one identity copy. */\n copies?: readonly StrokeCopy[];\n}\n\n/**\n * One dab-engine stroke (dab and eraser brushes): smoothing, the dab walk of every copy, grain and\n * build-up in a shared coverage map.\n */\nexport class DryStroke {\n readonly coverage = new CoverageMap();\n dabCount = 0;\n private readonly smoother: PenSmoother;\n private readonly walkers: PenDabWalker[];\n private readonly copies: readonly StrokeCopy[];\n private readonly depth: number;\n private buf = new Float32Array(0);\n private lastRaw: PenPoint | null = null;\n private lastFed: PenPoint | null = null;\n\n constructor(readonly brush: PaintBrush, private readonly options: DryStrokeOptions) {\n this.smoother = new PenSmoother(brush.tip.smoothing, brush.pressureSmoothing);\n this.copies = options.copies?.length ? options.copies : [IDENTITY_COPY];\n this.walkers = this.copies.map((c, i) => new PenDabWalker(brush, ((options.seed ?? 0) + i * 7919) | 0, c.linear));\n this.depth = options.grain && !options.grain.flat ? Math.min(1, Math.max(0, options.paperDepth * brush.grain)) : 0;\n }\n\n /** Feeds raw pen samples; returns the document rectangles the new dabs touched. */\n push(points: readonly PenPoint[]): RasterRect[] {\n const dabs: PenDab[] = [];\n for (const raw of points) {\n this.lastRaw = raw;\n const p = this.smoother.push(raw);\n this.lastFed = p;\n this.copies.forEach((c, i) => this.walkers[i].push(c.map(p), dabs));\n }\n return this.paint(dabs);\n }\n\n /** Ends the stroke: the smoothed path catches up with the last raw sample; a single tap paints one dab. */\n finish(): RasterRect[] {\n const dabs: PenDab[] = [];\n const raw = this.lastRaw;\n const fed = this.lastFed;\n if (raw && fed && (raw.x !== fed.x || raw.y !== fed.y)) this.copies.forEach((c, i) => this.walkers[i].push(c.map({ ...raw, pressure: fed.pressure }), dabs));\n for (const w of this.walkers) w.finish(dabs);\n return this.paint(dabs);\n }\n\n private paint(dabs: PenDab[]): RasterRect[] {\n const rects: RasterRect[] = [];\n const hardness = this.brush.tip.hardness;\n const grain = this.options.grain;\n for (const d of dabs) {\n const rect = dabRect(d, hardness);\n const n = rect.width * rect.height;\n if (this.buf.length < n) this.buf = new Float32Array(n);\n const vals = this.buf.subarray(0, n);\n rasterizeDab(d, hardness, rect, vals);\n if (this.depth > 0 && grain) {\n for (let yy = 0, k = 0; yy < rect.height; yy++) {\n const y = rect.y + yy + 0.5;\n for (let xx = 0; xx < rect.width; xx++, k++) {\n if (vals[k] > 0) vals[k] *= grainCatch(grain.at(rect.x + xx + 0.5, y), this.depth, d.pressure);\n }\n }\n }\n this.coverage.accumulate(rect, vals, d.opacity);\n rects.push(rect);\n this.dabCount++;\n }\n return rects;\n }\n}\n\n/** The shared engine's tip for the Mixer Brush engine (it smooths and walks by itself, so smoothing is applied before). */\nexport function mixerTip(brush: PaintBrush): BrushSettings {\n return { ...brush.tip, smoothing: 0, pressureSize: brush.tip.pressureSize };\n}\n\n/** Pen samples → the shared engine's stroke points (pressure only). */\nexport function toStrokePoint(p: PenPoint): StrokePoint {\n return { x: p.x, y: p.y, pressure: pressureOf(p), ...(typeof p.t === 'number' ? { t: p.t } : {}) };\n}\n","/**\n * A live stroke on one pixel layer. Points arrive while the pen moves; the layer shows the stroke\n * so far through a live surface (no history); `end()` commits it as one undo step.\n *\n * - Dab and eraser brushes: the coverage is cumulative, so each update recomposites the touched\n * region from the pre-stroke tile (`applyStrokeToTile` with `into` and `region`).\n * - Mixer engine brushes (Mixer Brush, blender, smudge): dabs read what earlier dabs laid down, so\n * they paint into live tile copies; every tile written since the last update gets a new `Tile`\n * object, because the compositor caches by tile identity.\n */\n\nimport { applyStrokeToTile, type StrokeApply } from '../paint/brush';\nimport { MixerStroke, cleanMixer, loadMixer, type MixerLoad, type MixerTarget } from '../paint/mixer';\nimport { TILE, TiledSurface, finishTile, tileKey, tilesInRect, type RasterRect, type Tile, type TileKey } from '../raster/surface';\nimport type { PaintBrush } from './brushes';\nimport { DryStroke, IDENTITY_COPY, PenSmoother, mixerTip, toStrokePoint, type PenPoint, type StrokeCopy } from './engine';\nimport type { PaperGrain } from './paper';\nimport type { Affine } from './strokes';\n\nexport interface StrokeSessionHost {\n /** Shows the layer's live surface (no history); `rects` are where it changed. */\n update(layerId: string, surface: TiledSurface, rects: RasterRect[]): void;\n /** Ends the stroke: `surface` is the new pixels, or `null` when nothing changed / it was cancelled. */\n commit(session: PaintStrokeSession, surface: TiledSurface | null, cancelled: boolean): void;\n}\n\nexport interface StrokeSessionInit {\n layerId: string;\n surface: TiledSurface;\n offset: { x: number; y: number };\n lockTransparency: boolean;\n brush: PaintBrush;\n /** Paint colour 0..255 RGBA. */\n color: readonly [number, number, number, number];\n /** What the eraser paints on a transparency-locked layer (the paper colour). */\n background: readonly [number, number, number, number];\n grain: PaperGrain | null;\n paperDepth: number;\n seed: number;\n /** The paint colour as #rrggbb (recorded with the stroke). */\n colorHex: string;\n /** The stroke's extra copies as affine maps (recorded with the stroke); `copies` holds all of them as engine copies. */\n affineCopies: readonly Affine[];\n copies: readonly StrokeCopy[];\n /** Applied to each raw sample before it is painted and recorded (perspective snapping). */\n inputFilter?: (p: PenPoint) => PenPoint;\n /** Mixer engine: the brush load at the start of the stroke. */\n mixerLoad: MixerLoad;\n}\n\nexport interface PaintStrokeResult {\n layerId: string;\n /** Document rectangle the stroke touched, or `null` when no pixel changed. */\n bounds: RasterRect | null;\n dabs: number;\n /** Id of the recorded stroke (see `list_strokes` / `replay_strokes`), or `null` when nothing changed. */\n strokeId: string | null;\n /** Mixer engine brushes: what the brush carries after the stroke. */\n mixerLoad?: MixerLoad;\n}\n\nfunction defaultTile(surface: TiledSurface): Uint8ClampedArray {\n const data = new Uint8ClampedArray(TILE * TILE * surface.channels);\n if (surface.defaultValue) data.fill(surface.defaultValue);\n return data;\n}\n\nfunction sameTile(a: Tile | undefined, b: Tile | null): boolean {\n if (!a || !b) return !a && !b;\n if (a === b) return true;\n if (a.uniform !== null || b.uniform !== null) return a.uniform === b.uniform;\n for (let i = 0; i < a.data.length; i++) if (a.data[i] !== b.data[i]) return false;\n return true;\n}\n\nfunction union(a: RasterRect | null, b: RasterRect): RasterRect {\n if (!a) return { ...b };\n const x = Math.min(a.x, b.x);\n const y = Math.min(a.y, b.y);\n return { x, y, width: Math.max(a.x + a.width, b.x + b.width) - x, height: Math.max(a.y + a.height, b.y + b.height) - y };\n}\n\nexport class PaintStrokeSession {\n readonly layerId: string;\n /** The raw input so far (what a replay feeds back in). */\n readonly points: PenPoint[] = [];\n private readonly base: TiledSurface;\n private readonly live: Map<TileKey, Tile>;\n private readonly touched = new Set<TileKey>();\n private readonly fresh = new Set<TileKey>();\n private readonly dry: DryStroke | null = null;\n private readonly mixers: MixerStroke[] = [];\n private readonly mixerSmoother: PenSmoother | null = null;\n private readonly apply: StrokeApply;\n private readonly copies: readonly StrokeCopy[];\n private bounds: RasterRect | null = null;\n private lastRaw: PenPoint | null = null;\n private closed = false;\n result: PaintStrokeResult | null = null;\n\n constructor(private readonly host: StrokeSessionHost, readonly init: StrokeSessionInit) {\n this.layerId = init.layerId;\n this.base = init.surface;\n this.live = new Map(this.base.tiles);\n this.copies = init.copies.length ? init.copies : [IDENTITY_COPY];\n const brush = init.brush;\n this.apply = {\n mode: brush.engine === 'eraser' ? 'erase' : 'paint',\n color: init.color,\n background: init.background,\n opacity: brush.tip.opacity,\n blend: brush.tip.blend,\n lockTransparency: init.lockTransparency,\n selection: null,\n offset: init.offset,\n };\n if (brush.engine === 'mixer') {\n this.mixerSmoother = new PenSmoother(brush.tip.smoothing, brush.pressureSmoothing);\n const load = init.mixerLoad;\n for (let i = 0; i < this.copies.length; i++) this.mixers.push(new MixerStroke(mixerTip(brush), brush.mixer, load, this.mixerTarget()));\n } else {\n this.dry = new DryStroke(brush, { grain: init.grain, paperDepth: init.paperDepth, seed: init.seed, copies: this.copies });\n }\n }\n\n private mixerTarget(): MixerTarget {\n return {\n offset: this.init.offset,\n lockTransparency: this.init.lockTransparency,\n selection: null,\n readTile: (tx, ty) => this.live.get(tileKey(tx, ty))?.data ?? null,\n writeTile: (tx, ty) => {\n const key = tileKey(tx, ty);\n if (!this.touched.has(key)) {\n const src = this.base.tiles.get(key)?.data ?? defaultTile(this.base);\n this.live.set(key, { data: new Uint8ClampedArray(src), uniform: null });\n this.touched.add(key);\n }\n this.fresh.add(key);\n return this.live.get(key)!.data;\n },\n };\n }\n\n get open(): boolean {\n return !this.closed;\n }\n\n /** Adds raw pen samples (document pixels). */\n push(points: readonly PenPoint[]): void {\n if (this.closed || !points.length) return;\n const filter = this.init.inputFilter;\n if (filter) points = points.map(filter);\n for (const p of points) this.points.push(p);\n this.lastRaw = points[points.length - 1];\n if (this.dry) this.update(this.dry.push(points));\n else {\n const rects: RasterRect[] = [];\n for (const raw of points) {\n const p = toStrokePoint(this.mixerSmoother!.push(raw));\n this.copies.forEach((c, i) => rects.push(...this.mixers[i].push([toStrokePoint(c.map(p))])));\n }\n this.update(rects);\n }\n }\n\n private update(rects: RasterRect[]): void {\n if (!rects.length) return;\n for (const r of rects) this.bounds = union(this.bounds, r);\n const ch = this.base.channels;\n if (!this.dry) {\n for (const key of this.fresh) this.live.set(key, { data: this.live.get(key)!.data, uniform: null });\n this.fresh.clear();\n this.host.update(this.layerId, new TiledSurface(ch, new Map(this.live), this.base.defaultValue), rects);\n return;\n }\n const off = this.init.offset;\n const regions = new Map<TileKey, { tx: number; ty: number; r: RasterRect }>();\n for (const r of rects) {\n for (const t of tilesInRect({ x: r.x - off.x, y: r.y - off.y, width: r.width, height: r.height })) {\n const key = tileKey(t.tx, t.ty);\n const cur = regions.get(key);\n regions.set(key, { tx: t.tx, ty: t.ty, r: cur ? union(cur.r, r) : r });\n }\n }\n for (const [key, { tx, ty, r }] of regions) {\n const src = this.base.tiles.get(key)?.data ?? defaultTile(this.base);\n const prev = this.touched.has(key) ? this.live.get(key)?.data : undefined;\n this.touched.add(key);\n const data = applyStrokeToTile(this.dry.coverage, src, ch, tx, ty, this.apply, prev ? { into: prev, region: r } : {});\n this.live.set(key, { data, uniform: null });\n }\n this.host.update(this.layerId, new TiledSurface(ch, new Map(this.live), this.base.defaultValue), rects);\n }\n\n /** Ends the stroke (one undo step) and returns what changed. */\n end(): PaintStrokeResult {\n if (this.closed) throw new Error('This stroke has already ended.');\n if (this.dry) this.update(this.dry.finish());\n else {\n const rects: RasterRect[] = [];\n const last = this.lastRaw ? toStrokePoint(this.lastRaw) : undefined;\n this.copies.forEach((c, i) => rects.push(...this.mixers[i].finish(last ? toStrokePoint(c.map(last)) : undefined)));\n this.update(rects);\n }\n this.closed = true;\n const ch = this.base.channels;\n const tiles = new Map(this.base.tiles);\n let changed = false;\n for (const key of this.touched) {\n const tile = finishTile(this.live.get(key)!.data, ch, this.base.defaultValue);\n const prev = this.base.tiles.get(key);\n if (tile) tiles.set(key, tile);\n else tiles.delete(key);\n if (!sameTile(prev, tile)) changed = true;\n }\n const surface = changed ? new TiledSurface(ch, tiles, this.base.defaultValue) : null;\n const dabs = this.dry ? this.dry.dabCount : this.mixers.reduce((n, m) => n + m.dabCount, 0);\n this.result = { layerId: this.layerId, bounds: changed ? this.bounds : null, dabs, strokeId: null };\n if (this.mixers.length) {\n const brush = this.init.brush;\n let load = this.mixers[0].load;\n if (brush.mixer.cleanEachStroke) load = cleanMixer(load);\n this.result.mixerLoad = load;\n }\n this.host.commit(this, surface, false);\n return this.result;\n }\n\n /** Abandons the stroke and restores the layer. */\n cancel(): void {\n if (this.closed) return;\n this.closed = true;\n this.host.commit(this, null, true);\n }\n}\n\n/** The Mixer Brush load a stroke starts with. */\nexport function mixerLoadForStroke(brush: PaintBrush, current: MixerLoad, color: readonly [number, number, number]): MixerLoad {\n if (!brush.loadsColor) return { reservoir: null, amount: 0, pickup: brush.mixer.cleanEachStroke ? null : current.pickup };\n if (brush.mixer.loadEachStroke || !current.reservoir) return loadMixer(current, color);\n return current;\n}\n","/**\n * Strokes as data. Every committed stroke is recorded with the brush, colour, raw pen samples,\n * jitter seed and symmetry copies it was painted with, so it replays to the same pixels, and can\n * be replayed moved, scaled, rotated, recoloured or with another brush (`replay_strokes`).\n */\n\nimport { normalizePaintBrush, type PaintBrushInput, type PaintBrush } from './brushes';\nimport type { Linear2, PenPoint, StrokeCopy } from './engine';\n\n/** An affine map [a, b, c, d, e, f]: (x, y) → (a·x + b·y + e, c·x + d·y + f). */\nexport type Affine = readonly [number, number, number, number, number, number];\n\nexport const IDENTITY_AFFINE: Affine = [1, 0, 0, 1, 0, 0];\n\nexport interface RecordedStroke {\n id: string;\n layerId: string;\n brush: PaintBrush;\n /** #rrggbb */\n color: string;\n /** Raw pen samples in document pixels, before smoothing. */\n points: PenPoint[];\n seed: number;\n /** Extra copies painted with the stroke (mirror / kaleidoscope), as affine maps of the points. */\n copies?: Affine[];\n}\n\nexport function applyAffine(m: Affine, x: number, y: number): { x: number; y: number } {\n return { x: m[0] * x + m[1] * y + m[4], y: m[2] * x + m[3] * y + m[5] };\n}\n\n/** `a ∘ b` (b first). */\nexport function composeAffine(a: Affine, b: Affine): Affine {\n return [\n a[0] * b[0] + a[1] * b[2],\n a[0] * b[1] + a[1] * b[3],\n a[2] * b[0] + a[3] * b[2],\n a[2] * b[1] + a[3] * b[3],\n a[0] * b[4] + a[1] * b[5] + a[4],\n a[2] * b[4] + a[3] * b[5] + a[5],\n ];\n}\n\nexport function invertAffine(m: Affine): Affine {\n const det = m[0] * m[3] - m[1] * m[2];\n if (Math.abs(det) < 1e-12) throw new Error('The transform is not invertible (scale 0?).');\n const a = m[3] / det;\n const b = -m[1] / det;\n const c = -m[2] / det;\n const d = m[0] / det;\n return [a, b, c, d, -(a * m[4] + b * m[5]), -(c * m[4] + d * m[5])];\n}\n\n/** The pen sample mapped by `m` (tilt and twist are kept: they describe the pen, not the path). */\nexport function mapPenPoint(m: Affine, p: PenPoint): PenPoint {\n const q = applyAffine(m, p.x, p.y);\n return { ...p, x: q.x, y: q.y };\n}\n\n/** An affine copy as the engine's `StrokeCopy`. */\nexport function affineCopy(m: Affine): StrokeCopy {\n const linear: Linear2 = [m[0], m[1], m[2], m[3]];\n return { map: (p) => mapPenPoint(m, p), linear };\n}\n\nconst finite = (v: unknown): v is number => typeof v === 'number' && Number.isFinite(v);\n\nfunction readPoint(raw: unknown): PenPoint | null {\n if (!raw || typeof raw !== 'object') return null;\n const r = raw as Record<string, unknown>;\n if (!finite(r.x) || !finite(r.y)) return null;\n const p: PenPoint = { x: r.x, y: r.y };\n for (const k of ['pressure', 't', 'tiltX', 'tiltY', 'altitude', 'azimuth', 'twist'] as const) if (finite(r[k])) p[k] = r[k] as number;\n return p;\n}\n\nfunction readAffine(raw: unknown): Affine | null {\n return Array.isArray(raw) && raw.length === 6 && raw.every(finite) ? (raw as unknown as Affine) : null;\n}\n\n/** A recorded stroke read from JSON, or `null` when it is not one. */\nexport function normalizeBrushStroke(raw: unknown): RecordedStroke | null {\n if (!raw || typeof raw !== 'object') return null;\n const r = raw as Record<string, unknown>;\n if (typeof r.id !== 'string' || typeof r.layerId !== 'string' || !Array.isArray(r.points)) return null;\n const points = r.points.map(readPoint).filter((p): p is PenPoint => p !== null);\n if (!points.length) return null;\n const out: RecordedStroke = {\n id: r.id,\n layerId: r.layerId,\n brush: normalizePaintBrush((r.brush as PaintBrushInput) ?? {}),\n color: typeof r.color === 'string' && /^#[0-9a-f]{6}$/i.test(r.color) ? r.color.toLowerCase() : '#000000',\n points,\n seed: finite(r.seed) ? r.seed | 0 : 0,\n };\n const copies = Array.isArray(r.copies) ? r.copies.map(readAffine).filter((m): m is Affine => m !== null) : [];\n if (copies.length) out.copies = copies;\n return out;\n}\n\n/** The bounding box of a stroke's points. */\nexport function strokeBounds(points: readonly PenPoint[]): { x: number; y: number; width: number; height: number } {\n let x0 = Infinity;\n let y0 = Infinity;\n let x1 = -Infinity;\n let y1 = -Infinity;\n for (const p of points) {\n if (p.x < x0) x0 = p.x;\n if (p.y < y0) y0 = p.y;\n if (p.x > x1) x1 = p.x;\n if (p.y > y1) y1 = p.y;\n }\n return { x: x0, y: y0, width: x1 - x0, height: y1 - y0 };\n}\n\nexport interface StrokeVariation {\n /** Move by this many document pixels (default 0). */\n dx?: number;\n dy?: number;\n /** Scale about the origin (default 1); brush size scales with it. */\n scale?: number;\n /** Rotate about the origin, degrees clockwise (default 0). */\n rotate?: number;\n /** Mirror horizontally about the origin (default false). */\n flipX?: boolean;\n /** The origin for scale, rotate and flip (default: the centre of the strokes' bounds). */\n origin?: { x: number; y: number };\n /** Multiply every pressure by this (default 1). */\n pressureScale?: number;\n}\n\n/** The affine map of a variation about `origin`. */\nexport function variationAffine(v: StrokeVariation, origin: { x: number; y: number }): Affine {\n const s = v.scale ?? 1;\n const a = ((v.rotate ?? 0) * Math.PI) / 180;\n const cos = Math.cos(a) * s;\n const sin = Math.sin(a) * s;\n const fx = v.flipX ? -1 : 1;\n // Translate to the origin, flip, rotate (clockwise with y down) and scale, translate back, move.\n const linear: Affine = [cos * fx, -sin, sin * fx, cos, 0, 0];\n const toOrigin: Affine = [1, 0, 0, 1, -origin.x, -origin.y];\n const back: Affine = [1, 0, 0, 1, origin.x + (v.dx ?? 0), origin.y + (v.dy ?? 0)];\n return composeAffine(back, composeAffine(linear, toOrigin));\n}\n\n/** A stroke varied by `m` (points mapped; symmetry copies conjugated so they stay symmetric). */\nexport function varyStroke(stroke: RecordedStroke, m: Affine, v: StrokeVariation): RecordedStroke {\n const s = Math.sqrt(Math.abs(m[0] * m[3] - m[1] * m[2]));\n const ps = v.pressureScale ?? 1;\n const points = stroke.points.map((p) => {\n const q = mapPenPoint(m, p);\n if (ps !== 1) q.pressure = Math.min(1, Math.max(0, (p.pressure ?? 1) * ps));\n return q;\n });\n const brush = s !== 1 ? normalizePaintBrush({ ...stroke.brush, tip: { ...stroke.brush.tip, size: stroke.brush.tip.size * s } }) : stroke.brush;\n const out: RecordedStroke = { ...stroke, brush, points };\n if (stroke.copies?.length) {\n const inv = invertAffine(m);\n out.copies = stroke.copies.map((c) => composeAffine(m, composeAffine(c, inv)));\n }\n return out;\n}\n","/**\n * Compositing for the paint editor, on the shared `RasterCompositor`: the paper is a content layer\n * at the bottom of the stack (its tiles are generated from the paper settings), and view-only\n * layers (the tracing image) sit between it and the paint. No compositor of our own.\n */\n\nimport { RasterCompositor, type CompositorLayer, type CompositorProfile, type RasterSources } from '../raster/compositor';\nimport type { RasterRect } from '../raster/surface';\nimport type { PaintLayer } from './document';\nimport { PaperGrain, renderPaper, type PaperSettings } from './paper';\n\n/** The paper as a layer of the compositor (generated, never stored). */\nexport interface PaperNode extends CompositorLayer {\n type: 'paper';\n id: string;\n name: string;\n visible: boolean;\n opacity: number;\n blend: 'normal';\n paper: PaperSettings;\n}\n\n/** A view-only RGBA image under the paint (the tracing image), drawn at its opacity. */\nexport interface ImageNode extends CompositorLayer {\n type: 'image';\n id: string;\n name: string;\n visible: boolean;\n opacity: number;\n blend: 'normal';\n /** Canvas-sized RGBA. */\n image: { width: number; height: number; data: Uint8ClampedArray };\n /** Changes when the pixels change. */\n version: number;\n}\n\nexport type ViewLayer = PaintLayer | PaperNode | ImageNode;\n\nexport const PAPER_NODE_ID = '__paper';\nexport const TRACING_NODE_ID = '__tracing';\n\nexport function paperKey(p: PaperSettings): string {\n return JSON.stringify([p.pattern, p.seed, p.color, p.scale, p.tiling, p.shading, p.dry]);\n}\n\nconst paperNodes = new WeakMap<PaperSettings, PaperNode>();\n\n/** The paper as a compositor layer (one object per paper settings object, so caches hold). */\nexport function paperNode(paper: PaperSettings): PaperNode {\n let n = paperNodes.get(paper);\n if (!n) {\n n = { type: 'paper', id: PAPER_NODE_ID, name: 'Paper', visible: true, opacity: 1, blend: 'normal', paper };\n paperNodes.set(paper, n);\n }\n return n;\n}\n\nconst grainCache = new Map<string, PaperGrain>();\nconst tileCache = new Map<string, Uint8ClampedArray>();\n\n/** The paper's dry height field, built once per settings. */\nexport function paperGrain(paper: PaperSettings): PaperGrain {\n const key = JSON.stringify([paper.pattern, paper.seed, paper.scale, paper.tiling, paper.dry]);\n let g = grainCache.get(key);\n if (!g) {\n g = new PaperGrain(paper, 'dry');\n if (grainCache.size > 16) grainCache.delete(grainCache.keys().next().value as string);\n grainCache.set(key, g);\n }\n return g;\n}\n\nfunction paperTile(paper: PaperSettings, r: RasterRect): Uint8ClampedArray {\n const key = `${paperKey(paper)}|${r.x},${r.y},${r.width},${r.height}`;\n let t = tileCache.get(key);\n if (!t) {\n t = renderPaper(paper, r, paperGrain(paper));\n if (tileCache.size > 512) tileCache.delete(tileCache.keys().next().value as string);\n tileCache.set(key, t);\n }\n return t;\n}\n\nconst PROFILE: CompositorProfile<ViewLayer, RasterSources> = {\n contentTile(layer, r) {\n if (layer.type === 'paper') return paperTile((layer as PaperNode).paper, r);\n if (layer.type === 'image') {\n const { image } = layer as ImageNode;\n const out = new Uint8ClampedArray(r.width * r.height * 4);\n const x0 = Math.max(0, r.x);\n const y0 = Math.max(0, r.y);\n const x1 = Math.min(image.width, r.x + r.width);\n const y1 = Math.min(image.height, r.y + r.height);\n if (x1 <= x0 || y1 <= y0) return null;\n for (let y = y0; y < y1; y++) out.set(image.data.subarray((y * image.width + x0) * 4, (y * image.width + x1) * 4), ((y - r.y) * r.width + (x0 - r.x)) * 4);\n return out;\n }\n return null;\n },\n layerKey(layer) {\n if (layer.type === 'paper') return paperKey((layer as PaperNode).paper);\n if (layer.type === 'image') return (layer as ImageNode).version;\n return undefined;\n },\n};\n\n/** A compositor for paint editor stacks (paper and view-only images included). */\nexport function createPaintCompositor(): RasterCompositor<ViewLayer, RasterSources> {\n return new RasterCompositor<ViewLayer, RasterSources>(PROFILE);\n}\n\n/**\n * Area-averaged downscale of straight-alpha RGBA (colours weighted by alpha). Sizes at or above\n * the source copy it.\n */\nexport function downsampleRgba(data: ArrayLike<number>, width: number, height: number, tw: number, th: number): Uint8ClampedArray {\n tw = Math.max(1, Math.round(tw));\n th = Math.max(1, Math.round(th));\n if (tw >= width && th >= height) return Uint8ClampedArray.from(data as ArrayLike<number>);\n const out = new Uint8ClampedArray(tw * th * 4);\n const sx = width / tw;\n const sy = height / th;\n for (let y = 0; y < th; y++) {\n const y0 = y * sy;\n const y1 = y0 + sy;\n for (let x = 0; x < tw; x++) {\n const x0 = x * sx;\n const x1 = x0 + sx;\n let r = 0;\n let g = 0;\n let b = 0;\n let a = 0;\n let w = 0;\n for (let yy = Math.floor(y0); yy < Math.ceil(y1) && yy < height; yy++) {\n const wy = Math.min(y1, yy + 1) - Math.max(y0, yy);\n for (let xx = Math.floor(x0); xx < Math.ceil(x1) && xx < width; xx++) {\n const wgt = wy * (Math.min(x1, xx + 1) - Math.max(x0, xx));\n const i = (yy * width + xx) * 4;\n const al = data[i + 3] * wgt;\n r += data[i] * al;\n g += data[i + 1] * al;\n b += data[i + 2] * al;\n a += al;\n w += wgt;\n }\n }\n const o = (y * tw + x) * 4;\n if (a > 0) {\n out[o] = r / a;\n out[o + 1] = g / a;\n out[o + 2] = b / a;\n }\n out[o + 3] = w > 0 ? a / w : 0;\n }\n }\n return out;\n}\n","/**\n * Saved paint documents: JSON plus PNG assets. Layers go through the image editor's layer\n * serializer (`serializeLayers` / `deserializeLayers`), so pixel layers and groups are stored the\n * same way in both editors, including external asset stores. The paper is plain settings: it is\n * regenerated on load, never stored as pixels.\n *\n * Forward compatibility: readers keep fields they do not know at the top level (`extensions`) and\n * write them back, so a later version can add per-layer wet state, height or material channels\n * as new assets keyed by layer id without breaking older readers (see `PaintDocumentExtensions`).\n */\n\nimport {\n deserializeLayers,\n resolveExternalAssets,\n serializeLayers,\n serializeLayersExternal,\n type ImageEditorAssetStore,\n type SerializedLayer,\n} from '../image-editor/layers/serialize';\nimport type { ImageLayer } from '../image-editor/layers/model';\nimport { findLayer, flattenLayers } from '../raster/layers';\nimport { normalizeBrushStroke, type RecordedStroke } from './strokes';\nimport { normalizeCanvas, type PaintDocumentState, type PaintLayer } from './document';\nimport { normalizePaper, type PaperSettings } from './paper';\n\nexport const PAINT_FORMAT = 'pixerate-paint' as const;\nexport const PAINT_SCHEMA_VERSION = 1 as const;\n\n/** Where a host keeps layer PNGs outside the JSON (the image editor's asset store contract). */\nexport type PaintAssetStore = ImageEditorAssetStore;\n\n/**\n * Fields a later version adds. Phase 1 writes none of them and keeps any it reads. Planned:\n * `layerChannels: { [layerId]: { height?: asset, material?: asset } }` for impasto and\n * metallic paint. Wet paint is never saved (saving dries it), so there is no wet field.\n */\nexport type PaintDocumentExtensions = Record<string, unknown>;\n\nexport interface SerializedPaintDocument {\n format: typeof PAINT_FORMAT;\n version: typeof PAINT_SCHEMA_VERSION;\n width: number;\n height: number;\n dpi: number;\n paper: PaperSettings;\n /** Bottom to top: pixel layers and groups, as the image editor stores them. */\n layers: SerializedLayer[];\n /** Asset id → PNG data URL (or an external reference). */\n assets: Record<string, string>;\n activeLayerId: string | null;\n /** Recorded strokes (strokes are data), oldest first; missing when saved without them. */\n strokes?: RecordedStroke[];\n /** Everything else (document-level state of later phases), written back as read. */\n [extension: string]: unknown;\n}\n\nconst KNOWN = new Set(['format', 'version', 'width', 'height', 'dpi', 'paper', 'layers', 'assets', 'activeLayerId', 'strokes', 'guides', 'swatches']);\n\n/** Fields of a saved document this version does not read, kept for writing back. */\nexport function documentExtensions(raw: Record<string, unknown>): PaintDocumentExtensions {\n const out: PaintDocumentExtensions = {};\n for (const [k, v] of Object.entries(raw)) if (!KNOWN.has(k)) out[k] = v;\n return out;\n}\n\nexport interface SerializeOptions {\n /** Include the recorded strokes (default true). */\n strokes?: boolean;\n /** Later-phase fields to write as they were read. */\n extensions?: PaintDocumentExtensions;\n /** Painting guides (symmetry, perspective, tracing and reference images as PNG data URLs). */\n guides?: unknown;\n swatches?: unknown;\n}\n\nfunction header(state: PaintDocumentState, options: SerializeOptions): Omit<SerializedPaintDocument, 'layers' | 'assets'> {\n const out: Omit<SerializedPaintDocument, 'layers' | 'assets'> = {\n ...(options.extensions ?? {}),\n format: PAINT_FORMAT,\n version: PAINT_SCHEMA_VERSION,\n width: state.canvas.width,\n height: state.canvas.height,\n dpi: state.canvas.dpi,\n paper: { ...state.paper, dry: { ...state.paper.dry }, wet: { ...state.paper.wet } },\n activeLayerId: state.activeLayerId,\n };\n if (options.strokes !== false && state.strokes.length) out.strokes = JSON.parse(JSON.stringify(state.strokes));\n if (options.guides !== undefined) out.guides = JSON.parse(JSON.stringify(options.guides));\n if (options.swatches !== undefined) out.swatches = JSON.parse(JSON.stringify(options.swatches));\n return out;\n}\n\n/** The document as JSON with inline PNG data URLs. */\nexport function serializePaintDocument(state: PaintDocumentState, options: SerializeOptions = {}): SerializedPaintDocument {\n const { layers, assets } = serializeLayers(state.layers as unknown as ImageLayer[]);\n return { ...header(state, options), layers, assets } as SerializedPaintDocument;\n}\n\n/** The document as JSON with each PNG uploaded to `store` once (by content). */\nexport async function serializePaintDocumentExternal(state: PaintDocumentState, store: PaintAssetStore, options: SerializeOptions = {}): Promise<SerializedPaintDocument> {\n const { layers, assets } = await serializeLayersExternal(state.layers as unknown as ImageLayer[], store);\n return { ...header(state, options), layers, assets } as SerializedPaintDocument;\n}\n\nexport interface LoadedPaintDocument {\n state: PaintDocumentState;\n extensions: PaintDocumentExtensions;\n /** The saved guides and swatches, as stored (the controller validates them). */\n guides?: unknown;\n swatches?: unknown;\n /** What could not be read (the rest still loads). */\n problems: string[];\n}\n\n/** Keeps pixel layers and groups (the paint editor's kinds); reports and drops the rest. */\nfunction paintLayersOnly(layers: ImageLayer[], problems: string[]): PaintLayer[] {\n const out: PaintLayer[] = [];\n for (const l of layers) {\n if (l.type === 'pixel') {\n const { filters, source, ...rest } = l;\n if (filters?.length) problems.push(`Layer \"${l.name}\": its filters are an image editor feature and were dropped.`);\n if (source) problems.push(`Layer \"${l.name}\" refers to an image editor source image; it loads empty.`);\n out.push(rest as PaintLayer);\n } else if (l.type === 'group') out.push({ ...l, children: paintLayersOnly(l.children, problems) } as PaintLayer);\n else problems.push(`Layer \"${l.name}\" is an image editor ${l.type} layer, which the paint editor does not have; it was left out.`);\n }\n return out;\n}\n\nfunction readStrokes(raw: unknown, problems: string[]): RecordedStroke[] {\n if (!Array.isArray(raw)) return [];\n const out: RecordedStroke[] = [];\n raw.forEach((s, i) => {\n const stroke = normalizeBrushStroke(s);\n if (stroke) out.push(stroke);\n else problems.push(`strokes[${i}] is not a recorded stroke; skipped.`);\n });\n return out;\n}\n\n/** Reads a saved document with inline assets. Throws when it is not a paint document at all. */\nexport function deserializePaintDocument(raw: unknown): LoadedPaintDocument {\n if (!raw || typeof raw !== 'object') throw new Error('Not a paint document: expected a JSON object.');\n const r = raw as Record<string, unknown>;\n if (r.format !== PAINT_FORMAT) throw new Error(`Not a paint document: format is ${JSON.stringify(r.format)}, expected \"${PAINT_FORMAT}\".`);\n if (typeof r.version !== 'number' || r.version > PAINT_SCHEMA_VERSION) {\n throw new Error(`Paint document version ${JSON.stringify(r.version)} is newer than this editor reads (${PAINT_SCHEMA_VERSION}); update @pixerate/editor.`);\n }\n const problems: string[] = [];\n const canvas = normalizeCanvas({ width: r.width as number, height: r.height as number, dpi: (r.dpi as number | undefined) ?? undefined });\n const paper = normalizePaper((r.paper as Record<string, unknown>) ?? {});\n const assets = r.assets && typeof r.assets === 'object' ? (r.assets as Record<string, string>) : {};\n const layers = paintLayersOnly(deserializeLayers(r.layers, { assets, problems }), problems);\n const wanted = typeof r.activeLayerId === 'string' ? r.activeLayerId : null;\n const activeLayerId = wanted && findLayer(layers, wanted) ? wanted : (flattenLayers(layers).filter((l) => l.type === 'pixel').pop()?.id ?? null);\n return { state: { canvas, paper, layers, activeLayerId, strokes: readStrokes(r.strokes, problems) }, extensions: documentExtensions(r), guides: r.guides, swatches: r.swatches, problems };\n}\n\n/** Reads a saved document whose assets may be external references in `store`. */\nexport async function deserializePaintDocumentAsync(raw: unknown, store?: PaintAssetStore): Promise<LoadedPaintDocument> {\n if (!raw || typeof raw !== 'object') throw new Error('Not a paint document: expected a JSON object.');\n const r = raw as Record<string, unknown>;\n const problems: string[] = [];\n const assets = await resolveExternalAssets((r.assets as Record<string, string>) ?? {}, store, problems);\n const loaded = deserializePaintDocument({ ...r, assets });\n return { ...loaded, problems: [...problems, ...loaded.problems] };\n}\n","/**\n * The canvas view: zoom, pan, rotation and mirroring. View state only: the pixels never resample,\n * the view maps document pixels to the screen and pointer positions back.\n */\n\nimport type { Affine } from './strokes';\nimport { applyAffine, invertAffine } from './strokes';\n\nexport interface PaintView {\n /** Screen pixels per document pixel (0.02..64, default 1). */\n zoom: number;\n /** Offset of the canvas centre from the viewport centre, in screen pixels. */\n pan: { x: number; y: number };\n /** Rotation in degrees clockwise, -180..180 (default 0). */\n rotation: number;\n /** Mirror the view left to right (default false). */\n mirror: boolean;\n}\n\nexport const MIN_ZOOM = 0.02;\nexport const MAX_ZOOM = 64;\n\nexport const DEFAULT_VIEW: Readonly<PaintView> = { zoom: 1, pan: { x: 0, y: 0 }, rotation: 0, mirror: false };\n\n/** Degrees into -180..180. */\nexport function normalizeRotation(deg: number): number {\n if (!Number.isFinite(deg)) return 0;\n let r = deg % 360;\n if (r > 180) r -= 360;\n if (r <= -180) r += 360;\n return Math.round(r * 1000) / 1000;\n}\n\nexport function normalizeView(raw: Partial<PaintView>, base: PaintView = DEFAULT_VIEW): PaintView {\n const zoom = typeof raw.zoom === 'number' && Number.isFinite(raw.zoom) ? Math.min(MAX_ZOOM, Math.max(MIN_ZOOM, raw.zoom)) : base.zoom;\n const pan = raw.pan && Number.isFinite(raw.pan.x) && Number.isFinite(raw.pan.y) ? { x: raw.pan.x, y: raw.pan.y } : { ...base.pan };\n return {\n zoom,\n pan,\n rotation: typeof raw.rotation === 'number' ? normalizeRotation(raw.rotation) : base.rotation,\n mirror: typeof raw.mirror === 'boolean' ? raw.mirror : base.mirror,\n };\n}\n\n/**\n * Document → screen for a canvas of `canvas` size shown in a viewport of `viewport` size:\n * the canvas centre goes to the viewport centre plus `pan`, then zoom, rotation and mirroring\n * apply about it.\n */\nexport function viewMatrix(view: PaintView, canvas: { width: number; height: number }, viewport: { width: number; height: number }): Affine {\n const a = (view.rotation * Math.PI) / 180;\n const z = view.zoom;\n const m = view.mirror ? -1 : 1;\n const cos = Math.cos(a) * z;\n const sin = Math.sin(a) * z;\n // Screen = C + R(θ) · M · z · (p − c), with y down (clockwise rotation).\n const cx = canvas.width / 2;\n const cy = canvas.height / 2;\n const sx = viewport.width / 2 + view.pan.x;\n const sy = viewport.height / 2 + view.pan.y;\n const A = cos * m;\n const B = -sin;\n const C = sin * m;\n const D = cos;\n return [A, B, C, D, sx - (A * cx + B * cy), sy - (C * cx + D * cy)];\n}\n\n/** Screen position → document position. */\nexport function screenToDocument(view: PaintView, canvas: { width: number; height: number }, viewport: { width: number; height: number }, x: number, y: number): { x: number; y: number } {\n return applyAffine(invertAffine(viewMatrix(view, canvas, viewport)), x, y);\n}\n\n/** Document position → screen position. */\nexport function documentToScreen(view: PaintView, canvas: { width: number; height: number }, viewport: { width: number; height: number }, x: number, y: number): { x: number; y: number } {\n return applyAffine(viewMatrix(view, canvas, viewport), x, y);\n}\n\n/** A CSS `matrix(...)` for an element of the canvas size placed at the viewport's top-left. */\nexport function viewCssTransform(view: PaintView, canvas: { width: number; height: number }, viewport: { width: number; height: number }): string {\n const m = viewMatrix(view, canvas, viewport);\n const f = (v: number) => Math.round(v * 10000) / 10000;\n return `matrix(${f(m[0])}, ${f(m[2])}, ${f(m[1])}, ${f(m[3])}, ${f(m[4])}, ${f(m[5])})`;\n}\n\n/** The zoom that fits the canvas in the viewport (with `margin` screen pixels around it). */\nexport function fitZoom(canvas: { width: number; height: number }, viewport: { width: number; height: number }, margin = 24): number {\n const w = Math.max(1, viewport.width - 2 * margin);\n const h = Math.max(1, viewport.height - 2 * margin);\n return Math.min(MAX_ZOOM, Math.max(MIN_ZOOM, Math.min(w / canvas.width, h / canvas.height)));\n}\n\n/**\n * Pen rotation as the document sees it: a rotated or mirrored view turns the pen's azimuth and\n * barrel rotation too, so a tilted pencil shades the same way on screen however the canvas is turned.\n */\nexport function viewPenToDocument<P extends { azimuth?: number; twist?: number }>(view: PaintView, p: P): P {\n if (!view.rotation && !view.mirror) return p;\n const out = { ...p };\n const r = (view.rotation * Math.PI) / 180;\n if (typeof p.azimuth === 'number') {\n let a = p.azimuth - r;\n if (view.mirror) a = Math.PI - a;\n out.azimuth = ((a % (2 * Math.PI)) + 2 * Math.PI) % (2 * Math.PI);\n }\n if (typeof p.twist === 'number') {\n let t = p.twist - view.rotation;\n if (view.mirror) t = -t;\n out.twist = ((t % 360) + 360) % 360;\n }\n return out;\n}\n","/**\n * Pen input helpers for the bindings: Pointer Events (structurally typed, no DOM import) into\n * `PenPoint`s, palm rejection by hand, and which hand the user draws with. The bindings feed\n * coalesced events into the stroke and draw predicted ones as a throwaway preview.\n */\n\nimport { penOrientation, type PenPoint } from './engine';\nimport { viewPenToDocument, type PaintView } from './view';\n\n/** The Pointer Event fields the paint editor reads. */\nexport interface PointerSample {\n pointerType?: string;\n pressure?: number;\n tiltX?: number;\n tiltY?: number;\n /** Radians (Pointer Events Level 3). */\n altitudeAngle?: number;\n azimuthAngle?: number;\n /** Degrees 0..359. */\n twist?: number;\n timeStamp?: number;\n}\n\n/** Which hand holds the pen: palm rejection ignores touches on that side of it. */\nexport type Hand = 'right' | 'left';\n\n/**\n * Pressure of a pointer sample: pens report it; mice report 0.5 while pressed and pens 0 on\n * `pointerup`, both of which mean \"use full\" (see GOTCHAS).\n */\nexport function samplePressure(e: PointerSample): number {\n if (e.pointerType === 'pen' && typeof e.pressure === 'number' && e.pressure > 0) return Math.min(1, e.pressure);\n return 1;\n}\n\n/**\n * A pointer sample at document position (x, y) as a pen point. Only pens report tilt and twist;\n * a pen's lean and barrel rotation are turned with the view, so marks look the same on screen\n * whatever the canvas rotation and mirroring.\n */\nexport function pointerToPenPoint(e: PointerSample, x: number, y: number, view?: PaintView): PenPoint {\n const p: PenPoint = { x, y, pressure: samplePressure(e) };\n if (typeof e.timeStamp === 'number' && Number.isFinite(e.timeStamp)) p.t = e.timeStamp;\n if (e.pointerType !== 'pen') return p;\n const o = penOrientation({\n x,\n y,\n altitude: typeof e.altitudeAngle === 'number' ? e.altitudeAngle : undefined,\n azimuth: typeof e.azimuthAngle === 'number' ? e.azimuthAngle : undefined,\n tiltX: e.tiltX,\n tiltY: e.tiltY,\n });\n // A pen standing straight up with no tilt reported keeps no orientation (most pens without tilt report 0, 0).\n if (o && o.altitude < Math.PI / 2 - 1e-6) {\n p.altitude = o.altitude;\n p.azimuth = o.azimuth;\n }\n if (typeof e.twist === 'number' && Number.isFinite(e.twist) && e.twist !== 0) p.twist = e.twist;\n return view ? viewPenToDocument(view, p) : p;\n}\n\n/**\n * Palm rejection: whether a touch at `touch` (screen pixels) is probably the drawing hand resting\n * on the screen while the pen is at `pen`. A right hand rests below and to the right of the pen, a\n * left hand below and to the left.\n */\nexport function isPalmTouch(touch: { x: number; y: number }, pen: { x: number; y: number } | null, hand: Hand): boolean {\n if (!pen) return false;\n const dx = touch.x - pen.x;\n const dy = touch.y - pen.y;\n const side = hand === 'right' ? dx : -dx;\n return dy > -40 && side > -40 && Math.hypot(dx, dy) < 600;\n}\n","/**\n * JPEG and WebP encoding. PNG is encoded in pure TypeScript (`encodePng`); the lossy formats need\n * the platform's codecs, so they go through an `OffscreenCanvas` (browsers and Workers) or a host\n * encoder. Nothing is imported: the globals are looked up at call time.\n */\n\nexport type ImageFormat = 'image/png' | 'image/jpeg' | 'image/webp';\n\n/** Encodes straight-alpha RGBA as `format` at `quality` (0..1). */\nexport type ImageEncoder = (image: { width: number; height: number; data: Uint8ClampedArray }, format: 'image/jpeg' | 'image/webp', quality: number) => Promise<Uint8Array>;\n\ninterface CanvasLike {\n getContext(type: '2d'): { putImageData(data: unknown, x: number, y: number): void } | null;\n convertToBlob(options: { type: string; quality: number }): Promise<{ arrayBuffer(): Promise<ArrayBuffer>; type: string }>;\n}\n\n/** An encoder through `OffscreenCanvas`, or `null` where there is none (Node, tests). */\nexport function defaultImageEncoder(): ImageEncoder | null {\n const g = globalThis as unknown as {\n OffscreenCanvas?: new (w: number, h: number) => CanvasLike;\n ImageData?: new (data: Uint8ClampedArray, w: number, h: number) => unknown;\n };\n if (typeof g.OffscreenCanvas !== 'function' || typeof g.ImageData !== 'function') return null;\n const Canvas = g.OffscreenCanvas;\n const Data = g.ImageData;\n return async (image, format, quality) => {\n const canvas = new Canvas(image.width, image.height);\n const ctx = canvas.getContext('2d');\n if (!ctx) throw new Error('No 2D context to encode with.');\n ctx.putImageData(new Data(new Uint8ClampedArray(image.data), image.width, image.height), 0, 0);\n const blob = await canvas.convertToBlob({ type: format, quality });\n if (blob.type !== format) throw new Error(`This browser cannot encode ${format} (it produced ${blob.type || 'nothing'}); export PNG instead.`);\n return new Uint8Array(await blob.arrayBuffer());\n };\n}\n\n/**\n * Decodes an image file (PNG, JPEG, WebP, … whatever the browser reads) into RGBA pixels through\n * `createImageBitmap` and an `OffscreenCanvas`. Browser and Worker only.\n */\nexport async function decodeImageBlob(blob: Blob): Promise<{ width: number; height: number; data: Uint8ClampedArray }> {\n const g = globalThis as unknown as {\n createImageBitmap?: (b: Blob) => Promise<{ width: number; height: number; close?(): void }>;\n OffscreenCanvas?: new (w: number, h: number) => { getContext(type: '2d'): { drawImage(img: unknown, x: number, y: number): void; getImageData(x: number, y: number, w: number, h: number): { data: Uint8ClampedArray } } | null };\n };\n if (typeof g.createImageBitmap !== 'function' || typeof g.OffscreenCanvas !== 'function') throw new Error('Decoding images needs a browser (createImageBitmap and OffscreenCanvas).');\n const bitmap = await g.createImageBitmap(blob);\n const canvas = new g.OffscreenCanvas(bitmap.width, bitmap.height);\n const ctx = canvas.getContext('2d');\n if (!ctx) throw new Error('No 2D context to decode with.');\n ctx.drawImage(bitmap, 0, 0);\n const data = new Uint8ClampedArray(ctx.getImageData(0, 0, bitmap.width, bitmap.height).data);\n bitmap.close?.();\n return { width: bitmap.width, height: bitmap.height, data };\n}\n\n/** Saves bytes as a file through a temporary link. Browser only. */\nexport function downloadBytes(bytes: Uint8Array | string, fileName: string, mimeType: string): void {\n const g = globalThis as unknown as {\n document?: { createElement(tag: 'a'): { href: string; download: string; click(): void } };\n URL?: { createObjectURL(b: Blob): string; revokeObjectURL(u: string): void };\n Blob?: new (parts: unknown[], options: { type: string }) => Blob;\n };\n if (!g.document || !g.URL || !g.Blob) throw new Error('Downloading needs a browser.');\n const url = g.URL.createObjectURL(new g.Blob([bytes], { type: mimeType }));\n const a = g.document.createElement('a');\n a.href = url;\n a.download = fileName;\n a.click();\n setTimeout(() => g.URL!.revokeObjectURL(url), 1000);\n}\n","/**\n * Brush thumbnails: a test stroke (an S-curve with pressure swelling and fading, at a steady\n * speed) painted with the brush on the paper. Brushes that only move paint (blender, smudge) are\n * shown dragged across two bands of colour. Pure TypeScript, so thumbnails render in Node too.\n */\n\nimport { EMPTY_MIXER_LOAD } from '../paint/mixer';\nimport { emptySurface, fillRect, type TiledSurface } from '../raster/surface';\nimport { normalizePaintBrush, type PaintBrush } from './brushes';\nimport type { PenPoint } from './engine';\nimport { IDENTITY_COPY } from './engine';\nimport { hexToRgb8, type PaperSettings } from './paper';\nimport { createPaintCompositor, paperGrain, paperNode, type ViewLayer } from './render';\nimport { mixerLoadForStroke, PaintStrokeSession } from './stroke';\n\nexport interface BrushThumbnail {\n width: number;\n height: number;\n /** RGBA, opaque (the paper is under the stroke). */\n data: Uint8ClampedArray;\n}\n\n/** The test stroke's samples for a `width × height` thumbnail. */\nexport function thumbnailStroke(width: number, height: number): PenPoint[] {\n const pts: PenPoint[] = [];\n const n = 64;\n const mx = width * 0.1;\n const my = height * 0.5;\n for (let i = 0; i <= n; i++) {\n const t = i / n;\n const pressure = t < 0.5 ? 0.15 + 1.7 * t : 1 - 1.4 * (t - 0.5);\n pts.push({ x: mx + (width - 2 * mx) * t, y: my - Math.sin(t * Math.PI * 2) * height * 0.22, pressure, t: i * 12 });\n }\n return pts;\n}\n\n/** Paints the test stroke with `brush` onto `surface`; returns the new pixels. */\nfunction paintTestStroke(surface: TiledSurface, brush: PaintBrush, paper: PaperSettings, color: string, width: number, height: number): TiledSurface {\n const [r, g, b] = hexToRgb8(color);\n let result = surface;\n const session = new PaintStrokeSession(\n { update: () => {}, commit: (_s, s) => (result = s ?? result) },\n {\n layerId: 'thumbnail',\n surface,\n offset: { x: 0, y: 0 },\n lockTransparency: false,\n brush,\n color: [r, g, b, 255],\n background: [...hexToRgb8(paper.color), 255],\n grain: paperGrain(paper),\n paperDepth: paper.depth,\n seed: 7,\n colorHex: color,\n affineCopies: [],\n copies: [IDENTITY_COPY],\n mixerLoad: brush.engine === 'mixer' ? mixerLoadForStroke(brush, EMPTY_MIXER_LOAD, [r / 255, g / 255, b / 255]) : EMPTY_MIXER_LOAD,\n }\n );\n session.push(thumbnailStroke(width, height));\n session.end();\n return result;\n}\n\nexport function renderBrushThumbnail(brush: PaintBrush, options: { paper: PaperSettings; width?: number; height?: number; color: string }): BrushThumbnail {\n const width = Math.max(16, Math.min(512, Math.round(options.width ?? 160)));\n const height = Math.max(16, Math.min(512, Math.round(options.height ?? 48)));\n // Fit the tip in the thumbnail: big brushes are drawn smaller.\n const maxSize = height * 0.42;\n const b = brush.tip.size > maxSize ? normalizePaintBrush({ tip: { ...brush.tip, size: maxSize } }, brush) : brush;\n const rgba = [...hexToRgb8(options.color), 255];\n let surface: TiledSurface = emptySurface(4);\n if (b.engine === 'eraser') {\n // Something to erase: a band of the colour.\n surface = fillRect(surface, { x: 0, y: 0, width, height }, rgba);\n } else if (b.engine === 'mixer' && !b.loadsColor) {\n // Something to move: two bands, the colour over ochre.\n const half = Math.ceil(height / 2);\n surface = fillRect(surface, { x: 0, y: 0, width, height: half }, rgba);\n surface = fillRect(surface, { x: 0, y: half, width, height: height - half }, [232, 196, 64, 255]);\n }\n surface = paintTestStroke(surface, b, options.paper, options.color, width, height);\n const layer: ViewLayer = { type: 'pixel', id: 'thumbnail', name: 'thumbnail', visible: true, opacity: 1, blend: 'normal', surface, offset: { x: 0, y: 0 } };\n const data = createPaintCompositor().composite([paperNode(options.paper), layer], { x: 0, y: 0, width, height }, { width, height });\n return { width, height, data };\n}\n","// Portions ported from photocraft/crates/paint/src/symmetry.rs (MIT OR Apache-2.0, © ArtCraft Team and contributors). See THIRD_PARTY_NOTICES.md.\n\n/**\n * Painting guides: mirror and kaleidoscope symmetry (every stroke paints its reflected or rotated\n * copies as one stroke), perspective guides with one to three vanishing points that strokes snap\n * to, a tracing image under the paint (optionally the source of the stroke colour), and floating\n * reference images to pick colours from. Geometry only: no pixels, no DOM.\n */\n\nimport { composeAffine, type Affine } from './strokes';\n\nexport type SymmetryMode = 'off' | 'vertical' | 'horizontal' | 'dual' | 'diagonal' | 'kaleidoscope';\n\nexport const SYMMETRY_MODES: readonly SymmetryMode[] = ['off', 'vertical', 'horizontal', 'dual', 'diagonal', 'kaleidoscope'];\n\nexport interface SymmetryGuide {\n mode: SymmetryMode;\n /** Centre of the axes in document pixels (default the canvas centre). */\n center: { x: number; y: number };\n /** Turns the axes, degrees clockwise (default 0). */\n rotation: number;\n /** Kaleidoscope: number of segments, 2..32 (default 6). */\n segments: number;\n /** Kaleidoscope: reflect every other segment as well as rotating (default true), like a real kaleidoscope. */\n mirror: boolean;\n}\n\nexport interface Point2 {\n x: number;\n y: number;\n}\n\nexport interface PerspectiveGuide {\n enabled: boolean;\n /** One to three vanishing points in document pixels (they may lie outside the canvas). */\n points: Point2[];\n /** Strokes snap to the guide lines (default true when enabled). */\n snap: boolean;\n}\n\n/** A view-only image under the paint, placed over the canvas. */\nexport interface TracingImage {\n /** PNG or JPEG data URL. */\n src: string;\n /** Natural size of the image in pixels. */\n width: number;\n height: number;\n /** Where it is drawn, in document pixels (default: fitted to the canvas). */\n rect: { x: number; y: number; width: number; height: number };\n /** 0..1 (default 0.35). */\n opacity: number;\n visible: boolean;\n /** Strokes without an explicit colour take the tracing image's colour where they start. */\n sampleColors: boolean;\n}\n\n/** A floating image to look at and pick colours from (shown beside the canvas, never painted). */\nexport interface ReferenceImage {\n id: string;\n name: string;\n src: string;\n width: number;\n height: number;\n /** Where the panel floats over the viewport, in screen pixels, and its displayed width. */\n x: number;\n y: number;\n displayWidth: number;\n visible: boolean;\n}\n\nexport interface PaintGuides {\n symmetry: SymmetryGuide;\n perspective: PerspectiveGuide;\n tracing: TracingImage | null;\n references: ReferenceImage[];\n}\n\nexport function defaultGuides(canvas: { width: number; height: number }): PaintGuides {\n return {\n symmetry: { mode: 'off', center: { x: canvas.width / 2, y: canvas.height / 2 }, rotation: 0, segments: 6, mirror: true },\n perspective: { enabled: false, points: [], snap: true },\n tracing: null,\n references: [],\n };\n}\n\nexport const MAX_COORDINATE = 1_000_000;\nconst finite = (v: unknown): v is number => typeof v === 'number' && Number.isFinite(v);\nconst coord = (v: unknown, d: number) => (finite(v) && Math.abs(v) <= MAX_COORDINATE ? v : d);\n\nexport function normalizeSymmetry(raw: Partial<SymmetryGuide> | Record<string, unknown>, base: SymmetryGuide): SymmetryGuide {\n const r = raw as Record<string, unknown>;\n const c = (r.center ?? {}) as Record<string, unknown>;\n return {\n mode: SYMMETRY_MODES.includes(r.mode as SymmetryMode) ? (r.mode as SymmetryMode) : base.mode,\n center: { x: coord(c.x, base.center.x), y: coord(c.y, base.center.y) },\n rotation: finite(r.rotation) ? ((r.rotation % 360) + 360) % 360 : base.rotation,\n segments: finite(r.segments) ? Math.min(32, Math.max(2, Math.round(r.segments))) : base.segments,\n mirror: typeof r.mirror === 'boolean' ? r.mirror : base.mirror,\n };\n}\n\n/** Reflection across the line through `c` in direction angle `a` (radians, clockwise with y down). */\nfunction reflectAbout(c: Point2, a: number): Affine {\n const dx = Math.cos(a);\n const dy = Math.sin(a);\n // 2·d·dᵀ − I, conjugated by the translation to the centre.\n const m00 = 2 * dx * dx - 1;\n const m01 = 2 * dx * dy;\n const m11 = 2 * dy * dy - 1;\n return [m00, m01, m01, m11, c.x - (m00 * c.x + m01 * c.y), c.y - (m01 * c.x + m11 * c.y)];\n}\n\n/** Rotation by `a` radians (clockwise with y down) about `c`. */\nfunction rotateAbout(c: Point2, a: number): Affine {\n const cos = Math.cos(a);\n const sin = Math.sin(a);\n return [cos, -sin, sin, cos, c.x - (cos * c.x - sin * c.y), c.y - (sin * c.x + cos * c.y)];\n}\n\nconst rad = (deg: number) => (deg * Math.PI) / 180;\n\n/** The axis directions of a mirror mode (radians), as photocraft's `directions`. */\nexport function symmetryAxisAngles(g: SymmetryGuide): number[] {\n if (g.mode === 'off') return [];\n if (g.mode === 'kaleidoscope') return Array.from({ length: g.segments }, (_, k) => rad(g.rotation) + (k * Math.PI) / g.segments);\n const initial = g.mode === 'horizontal' ? 0 : g.mode === 'diagonal' ? 45 : 90;\n const a = rad(initial + g.rotation);\n return g.mode === 'dual' ? [a, a + Math.PI / 2] : [a];\n}\n\n/**\n * The extra copies a stroke paints under the symmetry guide, as affine maps (the stroke itself is\n * not included). Vertical, horizontal and diagonal: one reflection. Dual: two reflections and the\n * point reflection. Kaleidoscope: rotations by 360°/n, and with `mirror` the reflections between them.\n */\nexport function symmetryCopies(g: SymmetryGuide): Affine[] {\n const c = g.center;\n switch (g.mode) {\n case 'off':\n return [];\n case 'vertical':\n case 'horizontal':\n case 'diagonal':\n return symmetryAxisAngles(g).map((a) => reflectAbout(c, a));\n case 'dual': {\n const [a, b] = symmetryAxisAngles(g);\n return [reflectAbout(c, a), reflectAbout(c, b), rotateAbout(c, Math.PI)];\n }\n case 'kaleidoscope': {\n const out: Affine[] = [];\n const n = g.segments;\n for (let k = 1; k < n; k++) out.push(rotateAbout(c, (2 * Math.PI * k) / n));\n if (g.mirror) {\n const first = reflectAbout(c, rad(g.rotation));\n for (let k = 0; k < n; k++) out.push(composeAffine(rotateAbout(c, (2 * Math.PI * k) / n), first));\n }\n return out;\n }\n }\n}\n\n/** The axes clipped to the canvas, for drawing (photocraft's `segments`). */\nexport function symmetryAxisSegments(g: SymmetryGuide, size: { width: number; height: number }): Array<[Point2, Point2]> {\n const out: Array<[Point2, Point2]> = [];\n for (const a of symmetryAxisAngles(g)) {\n const d = [Math.cos(a), Math.sin(a)];\n const origin = [g.center.x, g.center.y];\n const extent = [size.width, size.height];\n let lo = -Infinity;\n let hi = Infinity;\n let ok = true;\n for (let i = 0; i < 2; i++) {\n if (Math.abs(d[i]) < 1e-12) {\n if (origin[i] < 0 || origin[i] > extent[i]) ok = false;\n } else {\n const t0 = -origin[i] / d[i];\n const t1 = (extent[i] - origin[i]) / d[i];\n lo = Math.max(lo, Math.min(t0, t1));\n hi = Math.min(hi, Math.max(t0, t1));\n }\n }\n if (!ok || !Number.isFinite(lo) || !Number.isFinite(hi) || hi < lo) continue;\n out.push([{ x: g.center.x + lo * d[0], y: g.center.y + lo * d[1] }, { x: g.center.x + hi * d[0], y: g.center.y + hi * d[1] }]);\n }\n return out;\n}\n\n// ---------------------------------------------------------------------------\n// Perspective\n// ---------------------------------------------------------------------------\n\nexport function normalizePerspective(raw: Partial<PerspectiveGuide> | Record<string, unknown>, base: PerspectiveGuide): PerspectiveGuide {\n const r = raw as Record<string, unknown>;\n let points = base.points;\n if (Array.isArray(r.points)) {\n if (r.points.length > 3) throw new Error(`A perspective guide has one to three vanishing points; got ${r.points.length}.`);\n points = r.points.map((p, i) => {\n const q = (p ?? {}) as Record<string, unknown>;\n if (!finite(q.x) || !finite(q.y) || Math.abs(q.x) > MAX_COORDINATE || Math.abs(q.y) > MAX_COORDINATE) {\n throw new Error(`points[${i}] needs finite x and y within ±${MAX_COORDINATE} document pixels.`);\n }\n return { x: q.x, y: q.y };\n });\n }\n const enabled = typeof r.enabled === 'boolean' ? r.enabled : base.enabled;\n if (enabled && !points.length) throw new Error('An enabled perspective guide needs at least one vanishing point; pass points.');\n return { enabled, points, snap: typeof r.snap === 'boolean' ? r.snap : base.snap };\n}\n\n/** The line families a perspective guide snaps to at `p`: unit directions. */\nexport function perspectiveDirections(g: PerspectiveGuide, p: Point2): Point2[] {\n const out: Point2[] = [];\n for (const v of g.points) {\n const dx = v.x - p.x;\n const dy = v.y - p.y;\n const len = Math.hypot(dx, dy);\n if (len > 1e-6) out.push({ x: dx / len, y: dy / len });\n }\n // One-point perspective keeps true horizontals and verticals; two-point keeps verticals.\n if (g.points.length <= 2) out.push({ x: 0, y: 1 });\n if (g.points.length <= 1) out.push({ x: 1, y: 0 });\n return out;\n}\n\n/** How far the pen must move before a stroke chooses its perspective line (document pixels). */\nexport const SNAP_DECIDE_DISTANCE = 6;\n\n/**\n * Snaps one stroke to a perspective guide: once the pen has moved `SNAP_DECIDE_DISTANCE` from\n * where it started, the stroke picks the guide line through its start that best matches its\n * direction, and every sample after that is projected onto the line.\n */\nexport class PerspectiveSnapper {\n private start: Point2 | null = null;\n private dir: Point2 | null = null;\n\n constructor(private readonly guide: PerspectiveGuide) {}\n\n /** The line the stroke follows, once chosen. */\n get line(): { from: Point2; direction: Point2 } | null {\n return this.start && this.dir ? { from: this.start, direction: this.dir } : null;\n }\n\n snap<P extends Point2>(p: P): P {\n if (!this.guide.enabled || !this.guide.snap || !this.guide.points.length) return p;\n if (!this.start) {\n this.start = { x: p.x, y: p.y };\n return p;\n }\n const s = this.start;\n if (!this.dir) {\n const dx = p.x - s.x;\n const dy = p.y - s.y;\n const len = Math.hypot(dx, dy);\n if (len < SNAP_DECIDE_DISTANCE) return { ...p, x: s.x, y: s.y };\n let best: Point2 | null = null;\n let bestDot = -1;\n for (const d of perspectiveDirections(this.guide, s)) {\n const dot = Math.abs((dx * d.x + dy * d.y) / len);\n if (dot > bestDot) {\n bestDot = dot;\n best = d;\n }\n }\n this.dir = best;\n if (!best) return p;\n }\n const d = this.dir!;\n const t = (p.x - s.x) * d.x + (p.y - s.y) * d.y;\n return { ...p, x: s.x + d.x * t, y: s.y + d.y * t };\n }\n}\n\n/** Guide lines to draw for a perspective guide: rays from each vanishing point through the canvas. */\nexport function perspectiveGuideLines(g: PerspectiveGuide, size: { width: number; height: number }, count = 12): Array<[Point2, Point2]> {\n const out: Array<[Point2, Point2]> = [];\n const far = Math.hypot(size.width, size.height) * 4;\n for (const v of g.points) {\n // Aim the fan at the canvas: spread around the direction to its centre.\n const cx = size.width / 2 - v.x;\n const cy = size.height / 2 - v.y;\n const inside = v.x >= 0 && v.y >= 0 && v.x <= size.width && v.y <= size.height;\n const mid = Math.atan2(cy, cx);\n const spread = inside ? Math.PI : Math.min(Math.PI, 2 * Math.atan2(Math.hypot(size.width, size.height) / 2, Math.hypot(cx, cy)));\n for (let i = 0; i < count; i++) {\n const a = inside ? (2 * Math.PI * i) / count : mid - spread / 2 + (spread * (i + 0.5)) / count;\n out.push([{ ...v }, { x: v.x + Math.cos(a) * far, y: v.y + Math.sin(a) * far }]);\n }\n }\n return out;\n}\n","/**\n * Colour for painters: hex / RGB / HSV / HSL conversions, a colour wheel that is either the\n * painter's red-yellow-blue wheel (where red's complement is green) or the RGB wheel (where it is\n * cyan), harmonies on it, and swatches.\n */\n\nexport type Rgb255 = [number, number, number];\n\nconst HEX = /^#?([0-9a-f]{6})$/i;\n\nexport function parseHexColor(value: unknown, what = 'color'): Rgb255 {\n const m = typeof value === 'string' ? HEX.exec(value.trim()) : null;\n if (!m) throw new Error(`${what} is ${JSON.stringify(value)}; use #rrggbb, e.g. \"#2a4b8d\".`);\n const n = parseInt(m[1], 16);\n return [(n >> 16) & 255, (n >> 8) & 255, n & 255];\n}\n\nexport function rgbToHexColor(r: number, g: number, b: number): string {\n return '#' + [r, g, b].map((v) => Math.round(Math.min(255, Math.max(0, v))).toString(16).padStart(2, '0')).join('');\n}\n\n/** RGB 0..255 → HSV with h in degrees 0..360, s and v 0..1. */\nexport function rgbToHsv(r: number, g: number, b: number): { h: number; s: number; v: number } {\n const R = r / 255;\n const G = g / 255;\n const B = b / 255;\n const max = Math.max(R, G, B);\n const min = Math.min(R, G, B);\n const d = max - min;\n let h = 0;\n if (d > 0) {\n if (max === R) h = 60 * (((G - B) / d) % 6);\n else if (max === G) h = 60 * ((B - R) / d + 2);\n else h = 60 * ((R - G) / d + 4);\n }\n if (h < 0) h += 360;\n return { h, s: max === 0 ? 0 : d / max, v: max };\n}\n\nexport function hsvToRgb(h: number, s: number, v: number): Rgb255 {\n const hh = (((h % 360) + 360) % 360) / 60;\n const c = v * s;\n const x = c * (1 - Math.abs((hh % 2) - 1));\n const m = v - c;\n const [r, g, b] = hh < 1 ? [c, x, 0] : hh < 2 ? [x, c, 0] : hh < 3 ? [0, c, x] : hh < 4 ? [0, x, c] : hh < 5 ? [x, 0, c] : [c, 0, x];\n return [Math.round((r + m) * 255), Math.round((g + m) * 255), Math.round((b + m) * 255)];\n}\n\n/** RGB 0..255 → HSL with h in degrees, s and l 0..1. */\nexport function rgbToHsl(r: number, g: number, b: number): { h: number; s: number; l: number } {\n const { h } = rgbToHsv(r, g, b);\n const max = Math.max(r, g, b) / 255;\n const min = Math.min(r, g, b) / 255;\n const l = (max + min) / 2;\n const d = max - min;\n return { h, s: d === 0 ? 0 : d / (1 - Math.abs(2 * l - 1)), l };\n}\n\nexport function hslToRgb(h: number, s: number, l: number): Rgb255 {\n const c = (1 - Math.abs(2 * l - 1)) * s;\n const v = l + c / 2;\n return hsvToRgb(h, v === 0 ? 0 : c / v, v);\n}\n\n/** Which wheel hues live on: `ryb` (painter's: red ↔ green complements) or `rgb` (red ↔ cyan). */\nexport type ColorWheel = 'ryb' | 'rgb';\n\n// RYB wheel angle → RGB hue (a piecewise-linear map through red, orange, yellow, green, blue, violet).\nconst RYB_STOPS: ReadonlyArray<[number, number]> = [\n [0, 0],\n [60, 30],\n [120, 60],\n [180, 120],\n [240, 240],\n [300, 280],\n [360, 360],\n];\n\nfunction piecewise(v: number, from: 0 | 1): number {\n const x = ((v % 360) + 360) % 360;\n const to = from === 0 ? 1 : 0;\n for (let i = 1; i < RYB_STOPS.length; i++) {\n const a = RYB_STOPS[i - 1];\n const b = RYB_STOPS[i];\n if (x <= b[from]) return a[to] + ((x - a[from]) / (b[from] - a[from])) * (b[to] - a[to]);\n }\n return x;\n}\n\n/** A wheel angle (degrees) → an RGB hue. */\nexport function wheelToHue(angle: number, wheel: ColorWheel): number {\n return wheel === 'rgb' ? ((angle % 360) + 360) % 360 : piecewise(angle, 0);\n}\n\n/** An RGB hue → its wheel angle (degrees). */\nexport function hueToWheel(hue: number, wheel: ColorWheel): number {\n return wheel === 'rgb' ? ((hue % 360) + 360) % 360 : piecewise(hue, 1);\n}\n\nexport type HarmonyKind = 'complementary' | 'split-complementary' | 'analogous' | 'triadic' | 'tetradic' | 'square' | 'monochromatic';\n\nexport const HARMONY_KINDS: readonly HarmonyKind[] = ['complementary', 'split-complementary', 'analogous', 'triadic', 'tetradic', 'square', 'monochromatic'];\n\nexport interface HarmonyColor {\n color: string;\n /** Position on the wheel, degrees. */\n angle: number;\n}\n\n/**\n * The colours of a harmony around `base`, the base first. Hue-based harmonies keep the base's\n * saturation and value and turn it around the wheel; `analogous` spreads by `spread` degrees\n * (default 30); `monochromatic` keeps the hue and steps the lightness.\n */\nexport function colorHarmony(base: string, kind: HarmonyKind, options: { wheel?: ColorWheel; spread?: number } = {}): HarmonyColor[] {\n const wheel = options.wheel ?? 'ryb';\n const [r, g, b] = parseHexColor(base, 'base');\n const hsv = rgbToHsv(r, g, b);\n const start = hueToWheel(hsv.h, wheel);\n const at = (angle: number): HarmonyColor => {\n const a = ((angle % 360) + 360) % 360;\n const [rr, gg, bb] = hsvToRgb(wheelToHue(a, wheel), hsv.s, hsv.v);\n return { color: rgbToHexColor(rr, gg, bb), angle: Math.round(a * 10) / 10 };\n };\n const spread = options.spread ?? 30;\n const offsets: Record<Exclude<HarmonyKind, 'monochromatic'>, number[]> = {\n complementary: [0, 180],\n 'split-complementary': [0, 180 - spread, 180 + spread],\n analogous: [0, -spread, spread],\n triadic: [0, 120, 240],\n tetradic: [0, 60, 180, 240],\n square: [0, 90, 180, 270],\n };\n if (kind === 'monochromatic') {\n const hsl = rgbToHsl(r, g, b);\n const steps = [0, -0.3, -0.15, 0.15, 0.3];\n return steps.map((d) => {\n const [rr, gg, bb] = d === 0 ? [r, g, b] : hslToRgb(hsl.h, hsl.s, Math.min(0.97, Math.max(0.03, hsl.l + d)));\n return { color: rgbToHexColor(rr, gg, bb), angle: Math.round(start * 10) / 10 };\n });\n }\n return offsets[kind].map((o, i) => (i === 0 ? { color: rgbToHexColor(r, g, b), angle: Math.round(start * 10) / 10 } : at(start + o)));\n}\n\nexport interface Swatch {\n color: string;\n name?: string;\n}\n\n/** A starting palette of our own generic paint colours. */\nexport const DEFAULT_SWATCHES: readonly Swatch[] = [\n { color: '#f7f5ee', name: 'Warm white' },\n { color: '#f3d23a', name: 'Lemon yellow' },\n { color: '#c8912f', name: 'Yellow ochre' },\n { color: '#d23a2a', name: 'Warm red' },\n { color: '#9e1f3d', name: 'Crimson' },\n { color: '#8a4a2b', name: 'Burnt earth' },\n { color: '#2f3f9e', name: 'Deep blue' },\n { color: '#1d6f8f', name: 'Cool blue' },\n { color: '#4f6e2c', name: 'Leaf green' },\n { color: '#25221f', name: 'Warm black' },\n];\n","/**\n * The mixing pad: a small canvas beside the painting to put paint on, smear it with a palette\n * knife and pick the mixed colour from. Paint is laid with the Mixer Brush in pigment mode and the\n * knife is a pigment smudge, so blue and yellow pushed together make green. It is scratch space:\n * not part of the painting and not in its undo history.\n */\n\nimport { EMPTY_MIXER_LOAD } from '../paint/mixer';\nimport { emptySurface, readRegion, type TiledSurface } from '../raster/surface';\nimport { normalizePaintBrush, type PaintBrush } from './brushes';\nimport { IDENTITY_COPY, type PenPoint } from './engine';\nimport { hexToRgb8 } from './paper';\nimport { mixerLoadForStroke, PaintStrokeSession } from './stroke';\n\nexport type MixingPadTool = 'paint' | 'knife';\n\nexport const MIXING_PAD_WIDTH = 360;\nexport const MIXING_PAD_HEIGHT = 220;\n\nconst PAD_PAINT: PaintBrush = normalizePaintBrush({\n id: 'pad-paint',\n name: 'Pad paint',\n category: 'mixer',\n engine: 'mixer',\n tip: { size: 28, hardness: 0.75, spacing: 0.1, opacity: 1, flow: 0.7, pressureSize: false, pressureOpacity: false },\n mixer: { wet: 0.45, load: 1, mix: 0.4, loadEachStroke: true, cleanEachStroke: true, mixing: 'pigment' },\n});\n\nconst PAD_KNIFE: PaintBrush = normalizePaintBrush({\n id: 'pad-knife',\n name: 'Palette knife',\n category: 'smudge',\n engine: 'mixer',\n loadsColor: false,\n tip: { size: 34, hardness: 0.9, spacing: 0.08, roundness: 0.35, angle: 90, opacity: 1, flow: 0.85, pressureSize: false, pressureOpacity: false },\n mixer: { wet: 1, load: 0, mix: 1, loadEachStroke: false, cleanEachStroke: true, mixing: 'pigment' },\n});\n\nexport class MixingPad {\n readonly width = MIXING_PAD_WIDTH;\n readonly height = MIXING_PAD_HEIGHT;\n private surface: TiledSurface = emptySurface(4);\n /** Increments on every change (for redrawing). */\n version = 0;\n\n /** Paints (`paint`, with `color`) or smears (`knife`) through `points` in pad pixels. */\n stroke(points: readonly PenPoint[], options: { tool: MixingPadTool; color: string; size?: number }): { bounds: { x: number; y: number; width: number; height: number } | null } {\n if (!points.length) throw new Error('points is empty; give at least one {x, y} in pad pixels.');\n for (const [i, p] of points.entries()) {\n if (!Number.isFinite(p.x) || !Number.isFinite(p.y) || p.x < 0 || p.y < 0 || p.x > this.width || p.y > this.height) {\n throw new Error(`points[${i}] (${p.x}, ${p.y}) is off the ${this.width}×${this.height} mixing pad.`);\n }\n }\n let brush = options.tool === 'knife' ? PAD_KNIFE : PAD_PAINT;\n if (options.size !== undefined) brush = normalizePaintBrush({ tip: { ...brush.tip, size: options.size } }, brush);\n const [r, g, b] = hexToRgb8(options.color);\n let result: TiledSurface | null = null;\n const session = new PaintStrokeSession(\n { update: () => {}, commit: (_s, s) => (result = s) },\n {\n layerId: 'mixing-pad',\n surface: this.surface,\n offset: { x: 0, y: 0 },\n lockTransparency: false,\n brush,\n color: [r, g, b, 255],\n background: [255, 255, 255, 255],\n grain: null,\n paperDepth: 0,\n seed: 1,\n colorHex: options.color,\n affineCopies: [],\n copies: [IDENTITY_COPY],\n mixerLoad: mixerLoadForStroke(brush, EMPTY_MIXER_LOAD, [r / 255, g / 255, b / 255]),\n }\n );\n session.push(points);\n const res = session.end();\n if (result) {\n this.surface = result;\n this.version++;\n }\n return { bounds: res.bounds };\n }\n\n /** The average colour within `radius` pixels of (x, y), or `null` where the pad is bare. */\n pick(x: number, y: number, radius = 3): string | null {\n if (!(x >= 0 && y >= 0 && x < this.width && y < this.height)) throw new Error(`(${x}, ${y}) is off the ${this.width}×${this.height} mixing pad.`);\n const r = Math.max(0, Math.round(radius));\n const x0 = Math.max(0, Math.floor(x) - r);\n const y0 = Math.max(0, Math.floor(y) - r);\n const x1 = Math.min(this.width, Math.floor(x) + r + 1);\n const y1 = Math.min(this.height, Math.floor(y) + r + 1);\n const px = readRegion(this.surface, { x: x0, y: y0, width: x1 - x0, height: y1 - y0 });\n let R = 0;\n let G = 0;\n let B = 0;\n let A = 0;\n for (let i = 0; i < px.length; i += 4) {\n const a = px[i + 3];\n R += px[i] * a;\n G += px[i + 1] * a;\n B += px[i + 2] * a;\n A += a;\n }\n if (A === 0) return null;\n const hex = (v: number) => Math.round(v / A).toString(16).padStart(2, '0');\n return `#${hex(R)}${hex(G)}${hex(B)}`;\n }\n\n clear(): void {\n this.surface = emptySurface(4);\n this.version++;\n }\n\n /** The pad over white, `width × height` RGBA. */\n pixels(): Uint8ClampedArray {\n const px = readRegion(this.surface, { x: 0, y: 0, width: this.width, height: this.height });\n for (let i = 0; i < px.length; i += 4) {\n const a = px[i + 3] / 255;\n px[i] = Math.round(px[i] * a + 255 * (1 - a));\n px[i + 1] = Math.round(px[i + 1] * a + 255 * (1 - a));\n px[i + 2] = Math.round(px[i + 2] * a + 255 * (1 - a));\n px[i + 3] = 255;\n }\n return px;\n }\n}\n","/**\n * `PaintEditorController`: the natural-media paint editor's state, framework-free.\n *\n * - The document (canvas, paper, the shared raster layer stack, recorded strokes) is immutable\n * and tiled copy-on-write; each undo step is a reference to a whole document state.\n * - Strokes: `beginStroke` gives a live session for pointer input (one undo step at `end`);\n * `paintStroke` paints a whole stroke from data (agents, tests, replays).\n * - The brush, colour, Mixer Brush load, view and hand are editor state, not undo steps.\n * - Rendering goes through the shared compositor with the paper as its bottom layer; exports\n * are PNG (pure TypeScript), JPEG / WebP (through a canvas or a host encoder) and PSD (through\n * the shared PSD writer, with the paper as a pixel layer).\n */\n\nimport { exportPsd, type PsdExportResult } from '../image-editor/psd/export';\nimport type { ImageLayer } from '../image-editor/layers/model';\nimport { applyStrokeToTile, CoverageMap, type StrokeApply } from '../paint/brush';\nimport { cleanMixer, EMPTY_MIXER_LOAD, loadMixer, type MixerLoad } from '../paint/mixer';\nimport { BLEND_MODES, isBlendMode, standardBlendMode, type BlendMode } from '../raster/blend';\nimport { findLayer, flattenLayers, insertLayer, isLayerLocked, mapLayer, type LayerLocks } from '../raster/layers';\nimport { bytesToBase64, decodePng, encodePng, parseDataUrl, pngDataUrl } from '../raster/png';\nimport {\n contentBounds,\n emptySurface,\n readPixel,\n surfaceFromPixels,\n TILE,\n TiledSurface,\n tileKey,\n tilesInRect,\n finishTile,\n type RasterRect,\n type Tile,\n} from '../raster/surface';\nimport { brushToJSON, BUILTIN_BRUSHES, DEFAULT_BRUSH_ID, normalizePaintBrush, type PaintBrushInput, parseBrushLibrary, BRUSH_ID, type BrushLibraryFile, type PaintBrush } from './brushes';\nimport {\n createPaintDocument,\n createPaintLayer,\n newPaintLayerId,\n normalizeCanvas,\n type PaintCanvas,\n type PaintDocumentState,\n type PaintLayer,\n type PaintPixelLayer,\n} from './document';\nimport { defaultImageEncoder, type ImageEncoder, type ImageFormat } from './encode';\nimport type { PenPoint } from './engine';\nimport type { Hand } from './input';\nimport { mix32 } from './noise';\nimport { clonePaper, grainCatch, hexToRgb8, normalizePaper, paperPreset, type PaperSettings } from './paper';\nimport { createPaintCompositor, downsampleRgba, paperGrain, paperNode, TRACING_NODE_ID, type ImageNode, type ViewLayer } from './render';\nimport {\n deserializePaintDocument,\n deserializePaintDocumentAsync,\n serializePaintDocument,\n serializePaintDocumentExternal,\n type PaintAssetStore,\n type PaintDocumentExtensions,\n type SerializedPaintDocument,\n} from './serialize';\nimport { mixerLoadForStroke, PaintStrokeSession, type PaintStrokeResult, type StrokeSessionHost } from './stroke';\nimport { affineCopy, strokeBounds, variationAffine, varyStroke, IDENTITY_AFFINE, type Affine, type RecordedStroke, type StrokeVariation } from './strokes';\nimport { renderBrushThumbnail, type BrushThumbnail } from './thumbnails';\nimport { colorHarmony, DEFAULT_SWATCHES, type ColorWheel, type HarmonyColor, type HarmonyKind, type Swatch } from './color';\nimport {\n defaultGuides,\n normalizePerspective,\n normalizeSymmetry,\n PerspectiveSnapper,\n symmetryCopies,\n type PaintGuides,\n type PerspectiveGuide,\n type ReferenceImage,\n type SymmetryGuide,\n type TracingImage,\n} from './guides';\nimport { MixingPad, type MixingPadTool } from './mixing-pad';\nimport { DEFAULT_VIEW, normalizeView, type PaintView } from './view';\n\n/** A refusal with a message that says what is wrong and how to fix it. */\nexport class PaintEditorError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'PaintEditorError';\n }\n}\n\nexport interface PaintEditorOptions extends Partial<PaintCanvas> {\n /** Paper settings, or a library preset id (default cold pressed). */\n paper?: Partial<PaperSettings> | string;\n /** Active brush id (default `pencil-6b`). */\n brushId?: string;\n /** Saved user brushes to start the library with. */\n brushes?: readonly PaintBrush[];\n /** Paint colour #rrggbb (default #1f2937). */\n color?: string;\n hand?: Hand;\n /** Encodes JPEG / WebP (default: a canvas, when there is one). */\n encodeImage?: ImageEncoder;\n /** Undo steps kept (default 200). */\n historyLimit?: number;\n}\n\nexport interface PaintEditorState {\n document: PaintDocumentState;\n /** The active brush (possibly edited from its preset). */\n brush: PaintBrush;\n /** The brush library: built-in presets, then the user's brushes. */\n brushes: readonly PaintBrush[];\n /** Paint colour #rrggbb. */\n color: string;\n /** The second colour (swap with `swapColors`). */\n secondaryColor: string;\n /** What the Mixer Brush carries between strokes. */\n mixerLoad: MixerLoad;\n view: PaintView;\n hand: Hand;\n canUndo: boolean;\n canRedo: boolean;\n undoLabel: string | null;\n redoLabel: string | null;\n /** Mirror / kaleidoscope, perspective, tracing image and reference images (saved with the document, not undo steps). */\n guides: PaintGuides;\n /** The colour swatches (saved with the document, not undo steps). */\n swatches: readonly Swatch[];\n /** Changes whenever the mixing pad does. */\n mixingPadVersion: number;\n /** A stroke is in progress. */\n stroking: boolean;\n /** Increments on every change. */\n version: number;\n}\n\n/** A layer as tools and panels describe it. */\nexport interface PaintLayerInfo {\n id: string;\n name: string;\n type: 'pixel' | 'group';\n visible: boolean;\n opacity: number;\n blend: string;\n clipped: boolean;\n locks: LayerLocks;\n active: boolean;\n /** Painted content (document pixels), or `null` when empty. */\n bounds: RasterRect | null;\n parentId: string | null;\n depth: number;\n}\n\nexport interface PaintStrokeInit {\n /** Default the active layer. */\n layerId?: string;\n /** Default the editor colour. */\n color?: string;\n /** Default the active brush. */\n brushId?: string;\n /** Changes to the brush for this stroke only. */\n brush?: PaintBrushInput;\n /** Jitter seed (default: a new one per stroke). */\n seed?: number;\n /** Extra copies of the stroke as affine maps (default: the symmetry guide's). */\n copies?: readonly Affine[];\n /** Snap the samples to the perspective guide (default true for `beginStroke`, false for `paintStroke`). */\n snapToPerspective?: boolean;\n /** Where the stroke starts, for taking its colour from the tracing image before the first sample (`beginStroke`). */\n start?: { x: number; y: number };\n}\n\nexport interface LayerUpdate {\n name?: string;\n visible?: boolean;\n opacity?: number;\n blend?: BlendMode;\n clipped?: boolean;\n locks?: LayerLocks;\n}\n\nexport interface FillLayerOptions {\n layerId?: string;\n /** Default the editor colour. */\n color?: string;\n /** 0..1 (default 1). */\n opacity?: number;\n /** Paper grain response 0..1 (default 0: a flat fill); above 0 the fill catches the grain like pastel rubbed across the paper. */\n grain?: number;\n /** With grain: pressure 0..1, how far the fill reaches into the valleys (default 0.5). */\n pressure?: number;\n blend?: BlendMode;\n}\n\nexport interface ReplayOptions extends StrokeVariation {\n /** Recorded stroke ids (see `getStrokes`). */\n strokeIds: readonly string[];\n /** Paint on this layer instead of each stroke's own. */\n layerId?: string;\n /** Recolour (default each stroke's colour). */\n color?: string;\n /** Replay with this brush instead (default each stroke's brush). */\n brushId?: string;\n /** Repeat the variation this many times, each one applied on top of the last (default 1). */\n repeat?: number;\n}\n\nexport interface RenderOptions {\n /** Include the paper (default true); without it the result is transparent where nothing is painted. */\n paper?: boolean;\n /** Only these layers (a group with its children). */\n layerIds?: readonly string[];\n}\n\nexport interface PixelImage {\n width: number;\n height: number;\n data: Uint8ClampedArray;\n}\n\ninterface HistoryEntry {\n label: string;\n before: PaintDocumentState;\n after: PaintDocumentState;\n}\n\nconst HEX = /^#[0-9a-f]{6}$/i;\n\nfunction parseColor(value: unknown, what = 'color'): string {\n if (typeof value !== 'string' || !HEX.test(value.trim())) throw new PaintEditorError(`${what} is ${JSON.stringify(value)}; use #rrggbb, e.g. \"#2a4b8d\".`);\n return value.trim().toLowerCase();\n}\n\nfunction rgbaOf(hex: string): [number, number, number, number] {\n const [r, g, b] = hexToRgb8(hex);\n return [r, g, b, 255];\n}\n\nfunction rgbToHex(r: number, g: number, b: number): string {\n return '#' + [r, g, b].map((v) => Math.round(Math.min(255, Math.max(0, v))).toString(16).padStart(2, '0')).join('');\n}\n\nfunction unionRect(a: RasterRect | null, b: RasterRect | null): RasterRect | null {\n if (!a) return b ? { ...b } : null;\n if (!b) return { ...a };\n const x = Math.min(a.x, b.x);\n const y = Math.min(a.y, b.y);\n return { x, y, width: Math.max(a.x + a.width, b.x + b.width) - x, height: Math.max(a.y + a.height, b.y + b.height) - y };\n}\n\nconst isPixelLayer = (l: PaintLayer | undefined): l is PaintPixelLayer => l?.type === 'pixel';\n\nexport class PaintEditorController {\n private doc: PaintDocumentState;\n private extensions: PaintDocumentExtensions = {};\n private undoStack: HistoryEntry[] = [];\n private redoStack: HistoryEntry[] = [];\n private readonly historyLimit: number;\n private brush: PaintBrush;\n private userBrushes: PaintBrush[];\n private color: string;\n private secondaryColor = '#ffffff';\n private mixerLoad: MixerLoad = EMPTY_MIXER_LOAD;\n private view: PaintView = { ...DEFAULT_VIEW, pan: { ...DEFAULT_VIEW.pan } };\n private hand: Hand;\n private readonly encodeImage: ImageEncoder | undefined;\n private listeners = new Set<() => void>();\n private version = 0;\n private cached: PaintEditorState | null = null;\n private session: PaintStrokeSession | null = null;\n private live: { layerId: string; surface: TiledSurface } | null = null;\n private liveLayers: { key: TiledSurface; layers: PaintLayer[] } | null = null;\n private dirty: RasterRect[] | 'all' = 'all';\n private seedCounter = 1;\n private strokeCounter = 1;\n private guides: PaintGuides;\n private swatches: Swatch[] = DEFAULT_SWATCHES.map((s) => ({ ...s }));\n private readonly pad = new MixingPad();\n private tracingVersion = 1;\n private tracingCache: { key: number; node: ImageNode } | null = null;\n private readonly imagePixels = new Map<string, PixelImage>();\n private nextReferenceId = 1;\n private readonly viewCompositor = createPaintCompositor();\n private readonly exportCompositor = createPaintCompositor();\n\n constructor(options: PaintEditorOptions = {}) {\n this.historyLimit = Math.max(1, options.historyLimit ?? 200);\n this.doc = createPaintDocument({ width: options.width, height: options.height, dpi: options.dpi, paper: this.resolvePaper(options.paper) });\n this.userBrushes = (options.brushes ?? []).map((b) => normalizePaintBrush({ ...b, builtin: false }));\n const start = this.findBrush(options.brushId ?? DEFAULT_BRUSH_ID) ?? this.findBrush(DEFAULT_BRUSH_ID)!;\n this.brush = normalizePaintBrush(start);\n this.color = options.color ? parseColor(options.color) : '#1f2937';\n this.hand = options.hand === 'left' ? 'left' : 'right';\n this.encodeImage = options.encodeImage;\n this.guides = defaultGuides(this.doc.canvas);\n }\n\n // --- State and events ----------------------------------------------------------\n\n subscribe(listener: () => void): () => void {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n\n private emit(dirty: RasterRect[] | 'all' = 'all'): void {\n if (dirty === 'all' || this.dirty === 'all') this.dirty = 'all';\n else this.dirty.push(...dirty);\n this.version++;\n this.cached = null;\n for (const l of [...this.listeners]) l();\n }\n\n /** A snapshot of the editor (the same object until something changes). */\n getState(): PaintEditorState {\n if (this.cached) return this.cached;\n const last = this.undoStack[this.undoStack.length - 1];\n const next = this.redoStack[this.redoStack.length - 1];\n this.cached = {\n document: this.doc,\n brush: this.brush,\n brushes: [...BUILTIN_BRUSHES, ...this.userBrushes],\n color: this.color,\n secondaryColor: this.secondaryColor,\n mixerLoad: this.mixerLoad,\n view: this.view,\n hand: this.hand,\n canUndo: this.undoStack.length > 0 && !this.session,\n canRedo: this.redoStack.length > 0 && !this.session,\n undoLabel: last?.label ?? null,\n redoLabel: next?.label ?? null,\n guides: this.guides,\n swatches: this.swatches,\n mixingPadVersion: this.pad.version,\n stroking: Boolean(this.session),\n version: this.version,\n };\n return this.cached;\n }\n\n get document(): PaintDocumentState {\n return this.doc;\n }\n\n /**\n * Where the rendered stack changed since the last call: rectangles (a stroke's dabs) or `'all'`.\n * The viewport passes it to `compositeTiles` as `dirty`.\n */\n takeDirty(): RasterRect[] | 'all' {\n const d = this.dirty;\n this.dirty = [];\n return d;\n }\n\n // --- History -------------------------------------------------------------------\n\n private requireIdle(what: string): void {\n if (this.session) throw new PaintEditorError(`A stroke is in progress; end or cancel it before ${what}.`);\n }\n\n private commit(label: string, next: PaintDocumentState): void {\n this.undoStack.push({ label, before: this.doc, after: next });\n if (this.undoStack.length > this.historyLimit) this.undoStack.shift();\n this.redoStack = [];\n this.doc = next;\n this.emit();\n }\n\n undo(): string | null {\n this.requireIdle('undoing');\n const e = this.undoStack.pop();\n if (!e) return null;\n this.redoStack.push(e);\n this.doc = e.before;\n this.emit();\n return e.label;\n }\n\n redo(): string | null {\n this.requireIdle('redoing');\n const e = this.redoStack.pop();\n if (!e) return null;\n this.undoStack.push(e);\n this.doc = e.after;\n this.emit();\n return e.label;\n }\n\n /** Labels of the undo steps, oldest first. */\n historyLabels(): { undo: string[]; redo: string[] } {\n return { undo: this.undoStack.map((e) => e.label), redo: this.redoStack.map((e) => e.label).reverse() };\n }\n\n // --- Canvas and paper ----------------------------------------------------------\n\n private resolvePaper(paper: Partial<PaperSettings> | string | undefined): Partial<PaperSettings> {\n if (typeof paper === 'string') {\n const p = paperPreset(paper);\n if (!p) throw new PaintEditorError(`Unknown paper \"${paper}\". Call list_papers for the ids.`);\n return p;\n }\n return paper ?? {};\n }\n\n /** Starts a new canvas: one empty layer over the paper (one undo step; undo brings the old one back). */\n newCanvas(options: Partial<PaintCanvas> & { paper?: Partial<PaperSettings> | string } = {}): PaintDocumentState {\n this.requireIdle('starting a new canvas');\n const next = createPaintDocument({\n width: options.width ?? this.doc.canvas.width,\n height: options.height ?? this.doc.canvas.height,\n dpi: options.dpi ?? this.doc.canvas.dpi,\n paper: options.paper === undefined ? this.doc.paper : this.resolvePaper(options.paper),\n });\n this.extensions = {};\n this.guides = { ...this.guides, symmetry: { ...this.guides.symmetry, center: { x: next.canvas.width / 2, y: next.canvas.height / 2 } }, tracing: null };\n this.tracingVersion++;\n this.commit('New canvas', next);\n return next;\n }\n\n /** Changes the canvas size (keeping the pixels where they are, anchored top-left) or resolution. */\n setCanvas(update: Partial<PaintCanvas>): PaintCanvas {\n this.requireIdle('changing the canvas');\n const canvas = normalizeCanvas({\n width: update.width ?? this.doc.canvas.width,\n height: update.height ?? this.doc.canvas.height,\n dpi: update.dpi ?? this.doc.canvas.dpi,\n });\n this.commit('Canvas size', { ...this.doc, canvas });\n return canvas;\n }\n\n /** Changes the paper: a library preset (`preset`), and / or any of its settings (one undo step). */\n setPaper(update: Partial<PaperSettings> & { preset?: string }): PaperSettings {\n this.requireIdle('changing the paper');\n let base = this.doc.paper;\n if (update.preset !== undefined && update.preset !== this.doc.paper.preset) {\n const p = paperPreset(update.preset);\n if (!p) throw new PaintEditorError(`Unknown paper \"${update.preset}\". Call list_papers for the ids.`);\n base = p;\n }\n const { preset: _p, ...rest } = update;\n if (rest.color !== undefined) parseColor(rest.color, 'paper color');\n const paper = normalizePaper({ ...rest, preset: base.preset }, base);\n const changedKeys = Object.keys(rest).filter((k) => k !== 'name');\n if (changedKeys.length && update.preset === undefined) paper.preset = base.preset;\n this.commit('Paper', { ...this.doc, paper });\n return clonePaper(paper);\n }\n\n // --- Layers --------------------------------------------------------------------\n\n getLayer(id: string): PaintLayer | undefined {\n return findLayer(this.doc.layers, id)?.layer;\n }\n\n /** The active pixel layer (or `undefined`). */\n getActiveLayer(): PaintLayer | undefined {\n return this.doc.activeLayerId ? this.getLayer(this.doc.activeLayerId) : undefined;\n }\n\n /** Every layer, top first, as panels and tools describe them. */\n listLayers(): PaintLayerInfo[] {\n const out: PaintLayerInfo[] = [];\n const walk = (list: readonly PaintLayer[], parentId: string | null, depth: number) => {\n for (let i = list.length - 1; i >= 0; i--) {\n const l = list[i];\n out.push(this.describeLayer(l, parentId, depth));\n if (l.type === 'group') walk(l.children, l.id, depth + 1);\n }\n };\n walk(this.doc.layers, null, 0);\n return out;\n }\n\n describeLayer(l: PaintLayer, parentId: string | null = findLayer(this.doc.layers, l.id)?.parent?.id ?? null, depth = findLayer(this.doc.layers, l.id)?.path.length ?? 0): PaintLayerInfo {\n let bounds: RasterRect | null = null;\n if (l.type === 'pixel') {\n const b = contentBounds(l.surface);\n bounds = b ? { ...b, x: b.x + l.offset.x, y: b.y + l.offset.y } : null;\n } else for (const c of flattenLayers(l.children)) if (c.type === 'pixel') bounds = unionRect(bounds, this.describeLayer(c, l.id, depth + 1).bounds);\n return {\n id: l.id,\n name: l.name,\n type: l.type,\n visible: l.visible,\n opacity: l.opacity,\n blend: l.blend,\n clipped: Boolean(l.clipped),\n locks: { ...(l.locks ?? {}) },\n active: l.id === this.doc.activeLayerId,\n bounds,\n parentId,\n depth,\n };\n }\n\n private requireLayer(id: string): PaintLayer {\n const l = this.getLayer(id);\n if (!l) throw new PaintEditorError(`Unknown layer \"${id}\". Call list_layers for the ids.`);\n return l;\n }\n\n /** The pixel layer a paint operation targets, checked for locks and visibility. */\n private paintTarget(layerId: string | undefined, what: string): PaintPixelLayer {\n const id = layerId ?? this.doc.activeLayerId;\n if (!id) throw new PaintEditorError(`There is no active layer to ${what}; add one with add_layer.`);\n const l = this.requireLayer(id);\n if (!isPixelLayer(l)) throw new PaintEditorError(`Layer \"${l.name}\" is a group; ${what} a pixel layer inside it.`);\n if (isLayerLocked(l, 'pixels')) throw new PaintEditorError(`Layer \"${l.name}\" has its pixels locked; unlock it (update_layer locks) before you ${what} it.`);\n if (!l.visible) throw new PaintEditorError(`Layer \"${l.name}\" is hidden; show it (update_layer visible true) before you ${what} it.`);\n return l;\n }\n\n setActiveLayer(id: string): void {\n this.requireLayer(id);\n if (this.doc.activeLayerId === id) return;\n // Selection of the active layer is editor state, not an undo step: keep the history's documents.\n this.doc = { ...this.doc, activeLayerId: id };\n this.emit();\n }\n\n /** Adds an empty pixel layer or group above `aboveId` (default: the active layer) and makes it active. */\n addLayer(options: { name?: string; type?: 'pixel' | 'group'; aboveId?: string; parentId?: string | null } = {}): PaintLayerInfo {\n this.requireIdle('adding a layer');\n const count = flattenLayers(this.doc.layers).length;\n const type = options.type ?? 'pixel';\n const name = options.name?.trim() || (type === 'group' ? `Group ${count + 1}` : `Layer ${count + 1}`);\n const layer: PaintLayer =\n type === 'group' ? { type: 'group', id: newPaintLayerId(), name, visible: true, opacity: 1, blend: 'pass-through', children: [] } : createPaintLayer(name);\n let parentId: string | null = null;\n let index: number | undefined;\n const above = options.aboveId ?? (options.parentId === undefined ? this.doc.activeLayerId : null);\n if (options.parentId !== undefined && options.parentId !== null) {\n const g = this.requireLayer(options.parentId);\n if (g.type !== 'group') throw new PaintEditorError(`Layer \"${g.name}\" is not a group; pass a group id as parentId.`);\n parentId = g.id;\n } else if (above) {\n const loc = findLayer(this.doc.layers, above);\n if (!loc) throw new PaintEditorError(`Unknown layer \"${above}\". Call list_layers for the ids.`);\n parentId = loc.parent?.id ?? null;\n index = loc.index + 1;\n }\n const layers = insertLayer(this.doc.layers, layer, parentId, index);\n this.commit(type === 'group' ? 'Add group' : 'Add layer', { ...this.doc, layers, activeLayerId: layer.id });\n return this.describeLayer(layer);\n }\n\n updateLayer(id: string, update: LayerUpdate): PaintLayerInfo {\n this.requireIdle('changing a layer');\n const l = this.requireLayer(id);\n if (isLayerLocked(l, 'all') && Object.keys(update).some((k) => k !== 'locks')) throw new PaintEditorError(`Layer \"${l.name}\" is fully locked; unlock it first (locks {all: false}).`);\n if (update.opacity !== undefined && !(update.opacity >= 0 && update.opacity <= 1)) throw new PaintEditorError(`opacity ${update.opacity} is out of range; use 0..1.`);\n if (update.blend !== undefined && !isBlendMode(update.blend) && !(l.type === 'group' && update.blend === 'pass-through')) {\n throw new PaintEditorError(`Unknown blend mode \"${update.blend}\". Call get_canvas_info for the blend modes.`);\n }\n if (update.name !== undefined && !update.name.trim()) throw new PaintEditorError('name is empty; give the layer a name.');\n const next = { ...l } as PaintLayer;\n if (update.name !== undefined) next.name = update.name.trim();\n if (update.visible !== undefined) next.visible = update.visible;\n if (update.opacity !== undefined) next.opacity = update.opacity;\n if (update.blend !== undefined) (next as { blend: string }).blend = update.blend;\n if (update.clipped !== undefined) next.clipped = update.clipped || undefined;\n if (update.locks !== undefined) {\n const locks = { ...(l.locks ?? {}), ...update.locks };\n next.locks = Object.values(locks).some(Boolean) ? locks : undefined;\n }\n this.commit('Layer properties', { ...this.doc, layers: mapLayer(this.doc.layers, id, () => next) });\n return this.describeLayer(next);\n }\n\n removeLayer(id: string): { removed: string; activeLayerId: string | null } {\n this.requireIdle('removing a layer');\n const l = this.requireLayer(id);\n if (isLayerLocked(l, 'all')) throw new PaintEditorError(`Layer \"${l.name}\" is fully locked; unlock it before removing it.`);\n const layers = mapLayer(this.doc.layers, id, () => null);\n let active = this.doc.activeLayerId;\n if (active && !findLayer(layers, active)) active = flattenLayers(layers).filter((x) => x.type === 'pixel').pop()?.id ?? null;\n this.commit('Remove layer', { ...this.doc, layers, activeLayerId: active });\n return { removed: id, activeLayerId: active };\n }\n\n duplicateLayer(id: string): PaintLayerInfo {\n this.requireIdle('duplicating a layer');\n const loc = findLayer(this.doc.layers, id);\n if (!loc) throw new PaintEditorError(`Unknown layer \"${id}\". Call list_layers for the ids.`);\n const copy = (l: PaintLayer): PaintLayer => (l.type === 'group' ? { ...l, id: newPaintLayerId(), children: l.children.map(copy) } : { ...l, id: newPaintLayerId() });\n const dup = { ...copy(loc.layer), name: `${loc.layer.name} copy` };\n const layers = insertLayer(this.doc.layers, dup, loc.parent?.id ?? null, loc.index + 1);\n this.commit('Duplicate layer', { ...this.doc, layers, activeLayerId: dup.id });\n return this.describeLayer(dup);\n }\n\n /** Moves a layer to `index` (0 = bottom) within `parentId` (default its own parent; `null` = top level). */\n moveLayer(id: string, index: number, parentId?: string | null): PaintLayerInfo {\n this.requireIdle('moving a layer');\n const loc = findLayer(this.doc.layers, id);\n if (!loc) throw new PaintEditorError(`Unknown layer \"${id}\". Call list_layers for the ids.`);\n const target = parentId === undefined ? (loc.parent?.id ?? null) : parentId;\n if (target) {\n const g = this.requireLayer(target);\n if (g.type !== 'group') throw new PaintEditorError(`Layer \"${g.name}\" is not a group; pass a group id as parentId.`);\n if (target === id || (loc.layer.type === 'group' && findLayer(loc.layer.children, target))) throw new PaintEditorError('A group cannot move into itself.');\n }\n const without = mapLayer(this.doc.layers, id, () => null);\n const siblings = target ? (findLayer(without, target)!.layer as { children: PaintLayer[] }).children : without;\n if (!Number.isInteger(index) || index < 0 || index > siblings.length) throw new PaintEditorError(`index ${index} is out of range; use 0..${siblings.length} (0 is the bottom).`);\n const layers = insertLayer(without, loc.layer, target, index);\n this.commit('Move layer', { ...this.doc, layers });\n return this.describeLayer(loc.layer);\n }\n\n /** Merges a pixel layer into the pixel layer below it (keeping the lower one's settings). */\n mergeDown(id: string): PaintLayerInfo {\n this.requireIdle('merging');\n const loc = findLayer(this.doc.layers, id);\n if (!loc) throw new PaintEditorError(`Unknown layer \"${id}\". Call list_layers for the ids.`);\n const siblings = loc.parent ? loc.parent.children : this.doc.layers;\n const below = siblings[loc.index - 1];\n const upper = loc.layer;\n if (!isPixelLayer(upper) || !isPixelLayer(below)) throw new PaintEditorError('Merge down needs a pixel layer directly above another pixel layer in the same group.');\n if (isLayerLocked(below, 'pixels')) throw new PaintEditorError(`Layer \"${below.name}\" has its pixels locked; unlock it to merge into it.`);\n const rect = unionRect(this.describeLayer(below).bounds, this.describeLayer(upper).bounds);\n let surface = emptySurface(4);\n if (rect) {\n const base: PaintPixelLayer = { ...below, opacity: 1, blend: 'normal', visible: true, clipped: undefined, mask: undefined };\n const px = createPaintCompositor().composite([base, upper.visible ? upper : { ...upper, opacity: 0 }] as ViewLayer[], rect, this.sources());\n surface = surfaceFromPixels({ width: rect.width, height: rect.height, data: px }, 4, rect.x, rect.y);\n }\n const merged: PaintPixelLayer = { ...below, surface, offset: { x: 0, y: 0 } };\n const layers = mapLayer(mapLayer(this.doc.layers, upper.id, () => null), below.id, () => merged);\n this.commit('Merge down', { ...this.doc, layers, activeLayerId: below.id });\n return this.describeLayer(merged);\n }\n\n /** Removes every pixel of a layer. */\n clearLayer(layerId?: string): { layerId: string; bounds: RasterRect | null } {\n this.requireIdle('clearing');\n const l = this.paintTarget(layerId, 'clear');\n const bounds = this.describeLayer(l).bounds;\n this.commit('Clear layer', { ...this.doc, layers: mapLayer(this.doc.layers, l.id, () => ({ ...l, surface: emptySurface(4) })) });\n return { layerId: l.id, bounds };\n }\n\n /**\n * Fills a layer across the canvas with a colour. With `grain` above 0 the fill follows the paper\n * grain (it catches the peaks, as pastel or charcoal rubbed across the sheet).\n */\n fillLayer(options: FillLayerOptions = {}): { layerId: string; bounds: RasterRect } {\n this.requireIdle('filling');\n const l = this.paintTarget(options.layerId, 'fill');\n const color = options.color === undefined ? this.color : parseColor(options.color);\n const opacity = options.opacity ?? 1;\n if (!(opacity >= 0 && opacity <= 1)) throw new PaintEditorError(`opacity ${opacity} is out of range; use 0..1.`);\n const grainAmount = options.grain ?? 0;\n if (!(grainAmount >= 0 && grainAmount <= 1)) throw new PaintEditorError(`grain ${grainAmount} is out of range; use 0..1.`);\n const pressure = options.pressure ?? 0.5;\n const blend = options.blend ?? 'normal';\n if (!isBlendMode(blend)) throw new PaintEditorError(`Unknown blend mode \"${blend}\".`);\n const { width, height } = this.doc.canvas;\n const rect = { x: 0, y: 0, width, height };\n const coverage = new CoverageMap();\n const depth = grainAmount * this.doc.paper.depth;\n const grain = depth > 0 ? paperGrain(this.doc.paper) : null;\n for (const { tx, ty } of tilesInRect(rect)) {\n const r = { x: tx * TILE, y: ty * TILE, width: Math.min(TILE, width - tx * TILE), height: Math.min(TILE, height - ty * TILE) };\n const vals = new Float32Array(r.width * r.height);\n for (let y = 0, k = 0; y < r.height; y++) for (let x = 0; x < r.width; x++, k++) vals[k] = grain ? grainCatch(grain.at(r.x + x + 0.5, r.y + y + 0.5), depth, pressure) : 1;\n coverage.accumulate(r, vals, 1);\n }\n const apply: StrokeApply = {\n mode: 'paint',\n color: rgbaOf(color),\n background: rgbaOf(this.doc.paper.color),\n opacity,\n blend,\n lockTransparency: isLayerLocked(l, 'transparency'),\n selection: null,\n offset: l.offset,\n };\n const surface = this.applyCoverage(l, coverage, rect, apply);\n this.commit('Fill layer', { ...this.doc, layers: mapLayer(this.doc.layers, l.id, () => ({ ...l, surface })) });\n return { layerId: l.id, bounds: rect };\n }\n\n private applyCoverage(l: PaintPixelLayer, coverage: CoverageMap, rect: RasterRect, apply: StrokeApply): TiledSurface {\n const base = l.surface;\n const tiles = new Map(base.tiles);\n for (const { tx, ty } of tilesInRect({ x: rect.x - l.offset.x, y: rect.y - l.offset.y, width: rect.width, height: rect.height })) {\n const key = tileKey(tx, ty);\n const src = base.tiles.get(key)?.data ?? new Uint8ClampedArray(TILE * TILE * 4);\n const tile = finishTile(applyStrokeToTile(coverage, src, 4, tx, ty, apply), 4, 0);\n if (tile) tiles.set(key, tile);\n else tiles.delete(key);\n }\n return new TiledSurface(4, tiles, 0);\n }\n\n // --- Brushes -------------------------------------------------------------------\n\n private findBrush(id: string): PaintBrush | undefined {\n return BUILTIN_BRUSHES.find((b) => b.id === id) ?? this.userBrushes.find((b) => b.id === id);\n }\n\n /** A library brush by id (`undefined` when unknown). */\n getBrush(id: string): PaintBrush | undefined {\n const b = this.findBrush(id);\n return b ? normalizePaintBrush(b, b) : undefined;\n }\n\n private requireBrush(id: string): PaintBrush {\n const b = this.findBrush(id);\n if (!b) throw new PaintEditorError(`Unknown brush \"${id}\". Call list_brushes for the ids.`);\n return b;\n }\n\n /**\n * Chooses the active brush (`id`: a library brush) and / or changes its settings. Editor state,\n * not an undo step. Returns the active brush.\n */\n setBrush(update: { id?: string } & Omit<PaintBrushInput, 'id'> = {}): PaintBrush {\n const { id, ...changes } = update;\n const base = id !== undefined ? this.requireBrush(id) : this.brush;\n const next = normalizePaintBrush({ ...changes, id: base.id }, base);\n // The active brush is `builtin` only while it is an unchanged built-in preset.\n if (base.builtin && !Object.keys(changes).length) next.builtin = true;\n else delete next.builtin;\n this.brush = next;\n this.emit([]);\n return this.brush;\n }\n\n /** Saves the active brush (or `brush`) into the user library under `id` / `name`. */\n saveBrush(options: { id: string; name?: string; brush?: PaintBrushInput }): PaintBrush {\n if (!BRUSH_ID.test(options.id)) throw new PaintEditorError(`Brush id \"${options.id}\" is invalid; use lowercase letters, digits and dashes (e.g. \"my-pencil\").`);\n if (BUILTIN_BRUSHES.some((b) => b.id === options.id)) throw new PaintEditorError(`\"${options.id}\" is a built-in brush; save under another id.`);\n const source = options.brush ? normalizePaintBrush(options.brush, this.brush) : this.brush;\n const saved = normalizePaintBrush({ ...source, id: options.id, name: options.name ?? source.name });\n delete saved.builtin;\n const i = this.userBrushes.findIndex((b) => b.id === options.id);\n if (i >= 0) this.userBrushes[i] = saved;\n else this.userBrushes.push(saved);\n this.emit([]);\n return saved;\n }\n\n removeBrush(id: string): void {\n if (BUILTIN_BRUSHES.some((b) => b.id === id)) throw new PaintEditorError(`\"${id}\" is a built-in brush and cannot be removed.`);\n const i = this.userBrushes.findIndex((b) => b.id === id);\n if (i < 0) throw new PaintEditorError(`Unknown brush \"${id}\". Call list_brushes for the ids.`);\n this.userBrushes.splice(i, 1);\n this.emit([]);\n }\n\n /** The user's saved brushes. */\n getUserBrushes(): PaintBrush[] {\n return this.userBrushes.map((b) => normalizePaintBrush(b, b));\n }\n\n /** A brush library file of the given brushes (default: the user's brushes). */\n exportBrushes(ids?: readonly string[]): BrushLibraryFile {\n const list = ids ? ids.map((id) => this.requireBrush(id)) : this.userBrushes;\n return { format: 'pixerate-brushes', version: 1, brushes: list.map(brushToJSON) };\n }\n\n /**\n * Adds the brushes of a library file to the user library. A brush whose id is taken is skipped\n * unless `replace` (built-in ids are always skipped). Returns the ids added and the problems.\n */\n importBrushes(file: unknown, options: { replace?: boolean } = {}): { added: string[]; skipped: string[]; problems: string[] } {\n const problems: string[] = [];\n let list: PaintBrush[];\n try {\n list = parseBrushLibrary(file, problems);\n } catch (e) {\n throw new PaintEditorError((e as Error).message);\n }\n const added: string[] = [];\n const skipped: string[] = [];\n for (const b of list) {\n if (BUILTIN_BRUSHES.some((x) => x.id === b.id)) {\n skipped.push(b.id);\n problems.push(`\"${b.id}\" is a built-in brush id; rename it to import it.`);\n continue;\n }\n const i = this.userBrushes.findIndex((x) => x.id === b.id);\n if (i >= 0 && !options.replace) {\n skipped.push(b.id);\n continue;\n }\n if (i >= 0) this.userBrushes[i] = b;\n else this.userBrushes.push(b);\n added.push(b.id);\n }\n if (added.length) this.emit([]);\n return { added, skipped, problems };\n }\n\n /** A thumbnail of a brush: a test stroke on the current paper. */\n brushThumbnail(id: string, options: { width?: number; height?: number; color?: string } = {}): BrushThumbnail {\n const b = id === this.brush.id ? this.brush : this.requireBrush(id);\n return renderBrushThumbnail(b, { paper: this.doc.paper, width: options.width, height: options.height, color: options.color ? parseColor(options.color) : this.color });\n }\n\n // --- Colour --------------------------------------------------------------------\n\n setColor(color: string): string {\n this.color = parseColor(color);\n this.emit([]);\n return this.color;\n }\n\n setSecondaryColor(color: string): string {\n this.secondaryColor = parseColor(color);\n this.emit([]);\n return this.secondaryColor;\n }\n\n swapColors(): void {\n [this.color, this.secondaryColor] = [this.secondaryColor, this.color];\n this.emit([]);\n }\n\n /** The colour at a document pixel: of the composite (paper included) or of one layer. */\n pickColor(x: number, y: number, options: { layerId?: string } = {}): { color: string; alpha: number } {\n const { width, height } = this.doc.canvas;\n const px = Math.floor(x);\n const py = Math.floor(y);\n if (!(px >= 0 && py >= 0 && px < width && py < height)) throw new PaintEditorError(`(${x}, ${y}) is outside the ${width}×${height} canvas.`);\n if (options.layerId !== undefined) {\n const l = this.requireLayer(options.layerId);\n if (!isPixelLayer(l)) throw new PaintEditorError(`Layer \"${l.name}\" is a group; pick from a pixel layer or the composite.`);\n const [r, g, b, a] = readPixel(l.surface, px - l.offset.x, py - l.offset.y);\n return { color: rgbToHex(r, g, b), alpha: Math.round((a / 255) * 1000) / 1000 };\n }\n const d = this.exportCompositor.composite(this.renderLayers({}), { x: px, y: py, width: 1, height: 1 }, this.sources());\n return { color: rgbToHex(d[0], d[1], d[2]), alpha: Math.round((d[3] / 255) * 1000) / 1000 };\n }\n\n // --- Mixer Brush ---------------------------------------------------------------\n\n /** Fills the Mixer Brush reservoir with a colour (default the editor colour). */\n loadMixerBrush(color?: string): MixerLoad {\n const [r, g, b] = hexToRgb8(color === undefined ? this.color : parseColor(color));\n this.mixerLoad = loadMixer(this.mixerLoad, [r / 255, g / 255, b / 255]);\n this.emit([]);\n return this.mixerLoad;\n }\n\n /** Empties the pickup well (and with `emptyReservoir` the loaded paint too). */\n cleanMixerBrush(emptyReservoir = false): MixerLoad {\n this.mixerLoad = emptyReservoir ? EMPTY_MIXER_LOAD : cleanMixer(this.mixerLoad);\n this.emit([]);\n return this.mixerLoad;\n }\n\n // --- View and hand -------------------------------------------------------------\n\n /** Zoom, pan, rotation and mirroring: view state only, the pixels never resample. */\n setView(update: Partial<PaintView>): PaintView {\n this.view = normalizeView(update, this.view);\n this.emit([]);\n return this.view;\n }\n\n resetView(): PaintView {\n return this.setView({ ...DEFAULT_VIEW, pan: { x: 0, y: 0 } });\n }\n\n setHand(hand: Hand): Hand {\n if (hand !== 'left' && hand !== 'right') throw new PaintEditorError(`hand is ${JSON.stringify(hand)}; use \"left\" or \"right\".`);\n this.hand = hand;\n this.emit([]);\n return hand;\n }\n\n // --- Strokes -------------------------------------------------------------------\n\n private strokeBrush(init: PaintStrokeInit): PaintBrush {\n let brush = init.brushId !== undefined ? this.requireBrush(init.brushId) : this.brush;\n if (init.brush) brush = normalizePaintBrush({ ...init.brush, id: brush.id }, brush);\n return brush;\n }\n\n /** Extra copies every new stroke paints (the painting guides add mirror and kaleidoscope copies). */\n protected strokeCopies(): Affine[] {\n return symmetryCopies(this.guides.symmetry);\n }\n\n private sessionFor(doc: PaintDocumentState, init: PaintStrokeInit, host: StrokeSessionHost): PaintStrokeSession {\n const layer = (() => {\n const id = init.layerId ?? doc.activeLayerId;\n if (!id) throw new PaintEditorError('There is no active layer to paint on; add one with add_layer.');\n const loc = findLayer(doc.layers, id);\n if (!loc) throw new PaintEditorError(`Unknown layer \"${id}\". Call list_layers for the ids.`);\n const l = loc.layer;\n if (!isPixelLayer(l)) throw new PaintEditorError(`Layer \"${l.name}\" is a group; paint on a pixel layer inside it.`);\n if (isLayerLocked(l, 'pixels')) throw new PaintEditorError(`Layer \"${l.name}\" has its pixels locked; unlock it (update_layer locks) to paint on it.`);\n if (!l.visible) throw new PaintEditorError(`Layer \"${l.name}\" is hidden; show it (update_layer visible true) to paint on it.`);\n return l;\n })();\n const brush = this.strokeBrush(init);\n let color = init.color === undefined ? this.color : parseColor(init.color);\n const tracing = this.guides.tracing;\n if (init.color === undefined && init.start && tracing?.visible && tracing.sampleColors) color = this.sampleTracingColor(init.start.x, init.start.y) ?? color;\n const perspective = this.guides.perspective;\n const snapper = init.snapToPerspective && perspective.enabled && perspective.snap ? new PerspectiveSnapper(perspective) : null;\n const rgba = rgbaOf(color);\n const seed = init.seed ?? mix32((this.seedCounter++ * 0x9e3779b1) >>> 0) & 0x7fffffff;\n const copies = (init.copies ?? this.strokeCopies()).filter((m) => m.some((v, i) => v !== IDENTITY_AFFINE[i]));\n const session = new PaintStrokeSession(host, {\n layerId: layer.id,\n surface: layer.surface,\n offset: layer.offset,\n lockTransparency: isLayerLocked(layer, 'transparency'),\n brush,\n color: rgba,\n background: rgbaOf(doc.paper.color),\n grain: paperGrain(doc.paper),\n paperDepth: doc.paper.depth,\n seed,\n colorHex: color,\n affineCopies: copies,\n copies: [IDENTITY_AFFINE, ...copies].map(affineCopy),\n inputFilter: snapper ? (p) => snapper.snap(p) : undefined,\n mixerLoad: brush.engine === 'mixer' ? mixerLoadForStroke(brush, this.mixerLoad, [rgba[0] / 255, rgba[1] / 255, rgba[2] / 255]) : EMPTY_MIXER_LOAD,\n });\n return session;\n }\n\n private record(session: PaintStrokeSession): RecordedStroke {\n const init = session.init;\n const stroke: RecordedStroke = {\n id: `s${this.strokeCounter++}`,\n layerId: session.layerId,\n brush: brushToJSON(init.brush) as PaintBrush,\n color: init.colorHex,\n points: session.points.map((p) => ({ ...p })),\n seed: init.seed,\n };\n if (init.affineCopies.length) stroke.copies = init.affineCopies.map((m) => [...m] as unknown as Affine);\n return stroke;\n }\n\n /**\n * Starts a live stroke for pointer input: `push` raw pen samples (document pixels), then `end()`\n * (one undo step) or `cancel()`.\n */\n beginStroke(init: PaintStrokeInit = {}): PaintStrokeSession {\n this.requireIdle('starting another');\n const host: StrokeSessionHost = {\n update: (layerId, surface, rects) => {\n this.live = { layerId, surface };\n this.emit(rects);\n },\n commit: (s, surface, cancelled) => {\n this.session = null;\n this.live = null;\n this.liveLayers = null;\n const brush = s.init.brush;\n if (!cancelled && s.result?.mixerLoad && brush.loadsColor) this.mixerLoad = s.result.mixerLoad;\n if (cancelled || !surface) {\n this.emit();\n return;\n }\n const stroke = this.record(s);\n s.result!.strokeId = stroke.id;\n const l = this.getLayer(s.layerId) as PaintPixelLayer;\n this.commit(`${brush.name} stroke`, { ...this.doc, layers: mapLayer(this.doc.layers, l.id, () => ({ ...l, surface })), strokes: [...this.doc.strokes, stroke] });\n },\n };\n const session = this.sessionFor(this.doc, { snapToPerspective: true, ...init }, host);\n this.session = session;\n this.emit([]);\n return session;\n }\n\n /** The current live stroke, if any. */\n get activeStroke(): PaintStrokeSession | null {\n return this.session;\n }\n\n /** Runs a whole stroke against `doc` without touching the editor; returns the new document. */\n private runStroke(doc: PaintDocumentState, init: PaintStrokeInit, points: readonly PenPoint[]): { doc: PaintDocumentState; result: PaintStrokeResult; brush: PaintBrush } {\n let out = doc;\n const host: StrokeSessionHost = {\n update: () => {},\n commit: (s, surface, cancelled) => {\n if (cancelled || !surface) return;\n const stroke = this.record(s);\n s.result!.strokeId = stroke.id;\n const l = findLayer(out.layers, s.layerId)!.layer as PaintPixelLayer;\n out = { ...out, layers: mapLayer(out.layers, l.id, () => ({ ...l, surface })), strokes: [...out.strokes, stroke] };\n },\n };\n const session = this.sessionFor(doc, init, host);\n session.push(points);\n const result = session.end();\n return { doc: out, result, brush: session.init.brush };\n }\n\n /** Paints one stroke from data (one undo step). */\n paintStroke(init: PaintStrokeInit & { points: readonly PenPoint[] }): PaintStrokeResult {\n this.requireIdle('painting');\n const points = this.checkPoints(init.points);\n const { doc, result, brush } = this.runStroke(this.doc, { ...init, start: init.start ?? points[0] }, points);\n if (result.mixerLoad && brush.loadsColor) this.mixerLoad = result.mixerLoad;\n if (doc !== this.doc) this.commit(`${brush.name} stroke`, doc);\n else this.emit([]);\n return result;\n }\n\n private checkPoints(points: readonly PenPoint[]): PenPoint[] {\n if (!Array.isArray(points) || !points.length) throw new PaintEditorError('points is empty; give at least one {x, y} in document pixels.');\n const out: PenPoint[] = [];\n points.forEach((p, i) => {\n if (!p || !Number.isFinite(p.x) || !Number.isFinite(p.y)) throw new PaintEditorError(`points[${i}] needs finite x and y in document pixels.`);\n if (p.pressure !== undefined && !(p.pressure >= 0 && p.pressure <= 1)) throw new PaintEditorError(`points[${i}].pressure ${p.pressure} is out of range; use 0..1.`);\n out.push(p);\n });\n return out;\n }\n\n /** Every recorded stroke, oldest first. */\n getStrokes(): readonly RecordedStroke[] {\n return this.doc.strokes;\n }\n\n /**\n * Replays recorded strokes, varied (moved, scaled, rotated, flipped, recoloured, with another\n * brush or layer), `repeat` times: all of it one undo step. Returns the new strokes.\n */\n replayStrokes(options: ReplayOptions): { strokeIds: string[]; bounds: RasterRect | null; layerIds: string[] } {\n this.requireIdle('replaying');\n if (!options.strokeIds?.length) throw new PaintEditorError('strokeIds is empty; pass ids from list_strokes.');\n const strokes = options.strokeIds.map((id) => {\n const s = this.doc.strokes.find((x) => x.id === id);\n if (!s) throw new PaintEditorError(`Unknown stroke \"${id}\". Call list_strokes for the ids.`);\n return s;\n });\n const repeat = options.repeat ?? 1;\n if (!Number.isInteger(repeat) || repeat < 1 || repeat > 100) throw new PaintEditorError(`repeat ${repeat} is out of range; use 1..100.`);\n if (options.scale !== undefined && !(options.scale > 0 && options.scale <= 20)) throw new PaintEditorError(`scale ${options.scale} is out of range; use above 0 up to 20.`);\n if (options.color !== undefined) parseColor(options.color);\n if (options.brushId !== undefined) this.requireBrush(options.brushId);\n if (options.layerId !== undefined) this.paintTarget(options.layerId, 'replay onto');\n let origin = options.origin;\n if (!origin) {\n const b = strokeBounds(strokes.flatMap((s) => s.points));\n origin = { x: b.x + b.width / 2, y: b.y + b.height / 2 };\n }\n const step = variationAffine(options, origin);\n let doc = this.doc;\n let bounds: RasterRect | null = null;\n const ids: string[] = [];\n const layerIds = new Set<string>();\n let m: Affine = IDENTITY_AFFINE;\n for (let k = 0; k < repeat; k++) {\n m = [step[0] * m[0] + step[1] * m[2], step[0] * m[1] + step[1] * m[3], step[2] * m[0] + step[3] * m[2], step[2] * m[1] + step[3] * m[3], step[0] * m[4] + step[1] * m[5] + step[4], step[2] * m[4] + step[3] * m[5] + step[5]];\n for (const s of strokes) {\n const v = varyStroke(s, m, options);\n let brush = v.brush;\n if (options.brushId !== undefined) {\n const b = this.requireBrush(options.brushId);\n brush = normalizePaintBrush({ tip: { ...b.tip, size: b.tip.size * (v.brush.tip.size / s.brush.tip.size) } }, b);\n }\n const layerId = options.layerId ?? s.layerId;\n if (!findLayer(doc.layers, layerId)) throw new PaintEditorError(`Stroke \"${s.id}\" was painted on layer \"${layerId}\", which no longer exists; pass layerId to replay it elsewhere.`);\n const run = this.runStroke(doc, { layerId, color: options.color ?? s.color, brush, seed: s.seed, copies: v.copies ?? [] }, v.points);\n doc = run.doc;\n bounds = unionRect(bounds, run.result.bounds);\n if (run.result.strokeId) ids.push(run.result.strokeId);\n layerIds.add(layerId);\n }\n }\n if (doc !== this.doc) this.commit(strokes.length === 1 && repeat === 1 ? 'Replay stroke' : 'Replay strokes', doc);\n return { strokeIds: ids, bounds, layerIds: [...layerIds] };\n }\n\n // --- Rendering -----------------------------------------------------------------\n\n private sources() {\n return { width: this.doc.canvas.width, height: this.doc.canvas.height };\n }\n\n /** The layers with the live stroke's surface in place. */\n private currentLayers(): PaintLayer[] {\n const live = this.live;\n if (!live) return this.doc.layers;\n if (this.liveLayers?.key === live.surface) return this.liveLayers.layers;\n const layers = mapLayer(this.doc.layers, live.layerId, (l) => ({ ...(l as PaintPixelLayer), surface: live.surface }));\n this.liveLayers = { key: live.surface, layers };\n return layers;\n }\n\n /** View-only layers between the paper and the paint (the painting guides add the tracing image). */\n protected underlayLayers(): ViewLayer[] {\n const t = this.guides.tracing;\n if (!t || !t.visible) return [];\n return [this.tracingNode(t)];\n }\n\n /** The tracing image resampled onto the canvas (cached until it or the canvas changes). */\n private tracingNode(t: TracingImage): ImageNode {\n const { width, height } = this.doc.canvas;\n const key = this.tracingVersion * 100003 + width * 7 + height;\n if (this.tracingCache?.key === key && this.tracingCache.node.opacity === t.opacity) return this.tracingCache.node;\n const src = this.imagePixels.get(t.src) ?? this.decodeImage(t.src);\n const image = resampleInto(src, t.rect, width, height);\n const node: ImageNode = { type: 'image', id: TRACING_NODE_ID, name: 'Tracing', visible: true, opacity: t.opacity, blend: 'normal', image, version: key + Math.round(t.opacity * 1000) / 1e4 };\n this.tracingCache = { key, node };\n return node;\n }\n\n private renderLayers(options: RenderOptions, view = false): ViewLayer[] {\n let layers: PaintLayer[] = this.currentLayers();\n if (options.layerIds) {\n const picked: PaintLayer[] = [];\n for (const id of options.layerIds) picked.push(this.requireLayer(id));\n layers = picked.map((l) => ({ ...l, visible: true }) as PaintLayer);\n }\n const under: ViewLayer[] = options.paper === false ? [] : [paperNode(this.doc.paper)];\n if (view) under.push(...this.underlayLayers());\n return [...under, ...layers];\n }\n\n /**\n * Composites the viewport stack (paper, view-only underlays, layers with the live stroke) tile by\n * tile over `rect`, calling `onTile` with each 256 px tile's RGBA (cached: unchanged tiles come back\n * as the same buffer). Pass `takeDirty()` as `dirty`.\n */\n compositeTiles(rect: RasterRect, onTile: (tx: number, ty: number, data: Uint8ClampedArray, changed: boolean) => void, options: { dirty?: RasterRect[] | 'all' } = {}): void {\n const dirty = options.dirty === 'all' ? undefined : options.dirty;\n this.viewCompositor.compositeTiles(this.renderLayers({}, true), rect, this.sources(), onTile, { dirty, checkpointLayerId: this.live?.layerId ?? this.doc.activeLayerId });\n }\n\n /** The canvas as canvas-sized RGBA (paper included by default). */\n compositePixels(options: RenderOptions = {}): PixelImage {\n const { width, height } = this.doc.canvas;\n const data = this.exportCompositor.composite(this.renderLayers(options), { x: 0, y: 0, width, height }, this.sources());\n return { width, height, data };\n }\n\n /** The canvas (or some layers), scaled so the longest side is at most `maxSide`. */\n renderPreview(options: RenderOptions & { maxSide?: number } = {}): PixelImage {\n const full = this.compositePixels(options);\n const side = Math.max(1, Math.round(options.maxSide ?? 512));\n const k = Math.min(1, side / Math.max(full.width, full.height));\n if (k >= 1) return full;\n const w = Math.max(1, Math.round(full.width * k));\n const h = Math.max(1, Math.round(full.height * k));\n return { width: w, height: h, data: downsampleRgba(full.data, full.width, full.height, w, h) };\n }\n\n // --- Save, load and export -------------------------------------------------------\n\n /** The document as JSON with inline PNG assets. */\n toJSON(options: { strokes?: boolean } = {}): SerializedPaintDocument {\n return serializePaintDocument(this.doc, { strokes: options.strokes, extensions: this.extensions, guides: this.guides, swatches: this.swatches });\n }\n\n /** The document as JSON with each PNG stored in `store`. */\n toJSONExternal(store: PaintAssetStore, options: { strokes?: boolean } = {}): Promise<SerializedPaintDocument> {\n return serializePaintDocumentExternal(this.doc, store, { strokes: options.strokes, extensions: this.extensions, guides: this.guides, swatches: this.swatches });\n }\n\n private adopt(loaded: { state: PaintDocumentState; extensions: PaintDocumentExtensions; problems: string[]; guides?: unknown; swatches?: unknown }): string[] {\n this.extensions = loaded.extensions;\n this.readGuides(loaded.guides, loaded.state, loaded.problems);\n if (Array.isArray(loaded.swatches)) {\n this.swatches = loaded.swatches\n .filter((x): x is Swatch => Boolean(x) && typeof (x as Swatch).color === 'string' && /^#[0-9a-f]{6}$/i.test((x as Swatch).color))\n .map((x) => (typeof x.name === 'string' ? { color: x.color.toLowerCase(), name: x.name } : { color: x.color.toLowerCase() }));\n }\n for (const s of loaded.state.strokes) {\n const n = Number(/^s(\\d+)$/.exec(s.id)?.[1] ?? 0);\n if (n >= this.strokeCounter) this.strokeCounter = n + 1;\n }\n this.undoStack = [];\n this.redoStack = [];\n this.doc = loaded.state;\n this.viewCompositor.clear();\n this.emit();\n return loaded.problems;\n }\n\n /** Opens a saved document (clears the history). Returns what could not be read. */\n loadJSON(raw: unknown): string[] {\n this.requireIdle('opening a document');\n try {\n return this.adopt(deserializePaintDocument(raw));\n } catch (e) {\n throw new PaintEditorError((e as Error).message);\n }\n }\n\n /** Opens a saved document whose assets may live in `store`. */\n async loadJSONAsync(raw: unknown, store?: PaintAssetStore): Promise<string[]> {\n this.requireIdle('opening a document');\n try {\n return this.adopt(await deserializePaintDocumentAsync(raw, store));\n } catch (e) {\n throw new PaintEditorError((e as Error).message);\n }\n }\n\n /** The canvas as PNG bytes (paper included by default; `scale` below 1 shrinks it). */\n exportPng(options: RenderOptions & { scale?: number } = {}): Uint8Array {\n const img = this.scaled(options);\n return encodePng(img.width, img.height, img.data);\n }\n\n private scaled(options: RenderOptions & { scale?: number }): PixelImage {\n const full = this.compositePixels(options);\n const s = options.scale ?? 1;\n if (!(s > 0 && s <= 1)) throw new PaintEditorError(`scale ${s} is out of range; use above 0 up to 1 (exports never upscale pixels).`);\n if (s === 1) return full;\n const w = Math.max(1, Math.round(full.width * s));\n const h = Math.max(1, Math.round(full.height * s));\n return { width: w, height: h, data: downsampleRgba(full.data, full.width, full.height, w, h) };\n }\n\n /**\n * The canvas as PNG, JPEG or WebP bytes. JPEG has no alpha, so it always includes the paper.\n * JPEG and WebP need a canvas (a browser or Worker) or the `encodeImage` option.\n */\n async exportImage(options: RenderOptions & { format?: ImageFormat; quality?: number; scale?: number } = {}): Promise<Uint8Array> {\n const format = options.format ?? 'image/png';\n if (format === 'image/png') return this.exportPng(options);\n if (format !== 'image/jpeg' && format !== 'image/webp') throw new PaintEditorError(`format ${JSON.stringify(format)} is not supported; use image/png, image/jpeg or image/webp.`);\n const quality = options.quality ?? 0.92;\n if (!(quality >= 0 && quality <= 1)) throw new PaintEditorError(`quality ${quality} is out of range; use 0..1.`);\n const img = this.scaled({ ...options, paper: format === 'image/jpeg' ? true : options.paper });\n const encode = this.encodeImage ?? defaultImageEncoder();\n if (!encode) throw new PaintEditorError(`${format} needs a canvas to encode and there is none here; pass encodeImage to the controller, or export PNG.`);\n return encode(img, format, quality);\n }\n\n /**\n * The document as an 8-bit RGB PSD through the shared PSD writer: every layer and group, with\n * the paper as a locked \"Paper\" pixel layer at the bottom (it is generated, so PSD gets its\n * pixels), and the composite as the merged image.\n */\n exportPsd(): PsdExportResult {\n const { width, height, dpi } = this.doc.canvas;\n const paperPixels = this.compositePixels({ layerIds: [], paper: true });\n const paperLayer: PaintPixelLayer = {\n type: 'pixel',\n id: 'paper',\n name: 'Paper',\n visible: true,\n opacity: 1,\n blend: 'normal',\n locks: { all: true },\n surface: surfaceFromPixels(paperPixels, 4),\n offset: { x: 0, y: 0 },\n };\n const merged = this.compositePixels({ paper: true }).data;\n // PSD has no pigment or painterly modes: write each as its nearest standard mode and say so.\n const changed = new Map<BlendMode, string[]>();\n const toStandard = (layers: readonly PaintLayer[]): PaintLayer[] =>\n layers.map((l) => {\n const blend = l.blend === 'pass-through' ? l.blend : standardBlendMode(l.blend as BlendMode);\n if (blend !== l.blend) changed.set(l.blend as BlendMode, [...(changed.get(l.blend as BlendMode) ?? []), l.name]);\n const next = blend === l.blend ? l : ({ ...l, blend } as PaintLayer);\n return next.type === 'group' ? { ...next, children: toStandard(next.children) } : next;\n });\n const layers = toStandard(this.doc.layers);\n const result = exportPsd({ width, height, layers: [paperLayer, ...layers] as unknown as ImageLayer[], merged, resolution: dpi });\n for (const [mode, names] of changed) {\n const label = BLEND_MODES.find((m) => m.id === mode)?.label ?? mode;\n const std = BLEND_MODES.find((m) => m.id === standardBlendMode(mode))?.label ?? standardBlendMode(mode);\n const list = names.map((n) => `\"${n}\"`).join(', ');\n const one = names.length === 1;\n result.warnings.push(`${label} blending has no PSD equivalent; ${list} ${one ? 'was' : 'were'} written as ${std}, the nearest Photoshop mode, so ${one ? 'it looks' : 'they look'} different in Photoshop (the merged image is exact).`);\n }\n return result;\n }\n\n /** `render_preview` as a base64 PNG. */\n previewPngBase64(options: RenderOptions & { maxSide?: number } = {}): { data: string; width: number; height: number } {\n const img = this.renderPreview(options);\n return { data: bytesToBase64(encodePng(img.width, img.height, img.data)), width: img.width, height: img.height };\n }\n\n // --- Guides --------------------------------------------------------------------\n\n private setGuides(next: PaintGuides): PaintGuides {\n this.guides = next;\n this.emit('all');\n return next;\n }\n\n /** Mirror and kaleidoscope painting: every new stroke paints its copies too (one stroke, one undo step). */\n setSymmetry(update: Partial<SymmetryGuide>): SymmetryGuide {\n const symmetry = normalizeSymmetry(update, this.guides.symmetry);\n this.setGuides({ ...this.guides, symmetry });\n return symmetry;\n }\n\n /** Perspective guides with one to three vanishing points that pointer strokes snap to. */\n setPerspective(update: Partial<PerspectiveGuide>): PerspectiveGuide {\n let perspective: PerspectiveGuide;\n try {\n perspective = normalizePerspective(update, this.guides.perspective);\n } catch (e) {\n throw new PaintEditorError((e as Error).message);\n }\n this.setGuides({ ...this.guides, perspective });\n return perspective;\n }\n\n /** An image from a PNG (base64 or data URL) or from RGBA pixels, stored as a PNG data URL. */\n private importImage(input: { png?: string; pixels?: PixelImage }, what: string): { src: string; pixels: PixelImage } {\n let pixels: PixelImage;\n if (input.pixels) {\n const { width, height, data } = input.pixels;\n if (!(width > 0 && height > 0 && Number.isInteger(width) && Number.isInteger(height)) || data.length !== width * height * 4) {\n throw new PaintEditorError(`${what}: pixels must be width × height × 4 bytes of RGBA.`);\n }\n pixels = { width, height, data: new Uint8ClampedArray(data) };\n } else if (typeof input.png === 'string' && input.png.trim()) {\n pixels = this.decodeImage(input.png.trim().startsWith('data:') ? input.png.trim() : `data:image/png;base64,${input.png.trim()}`, what);\n } else throw new PaintEditorError(`${what}: pass png (a PNG as base64 or a data URL) or pixels.`);\n if (pixels.width > MAX_IMAGE_SIDE || pixels.height > MAX_IMAGE_SIDE) throw new PaintEditorError(`${what} is ${pixels.width}×${pixels.height}; the limit is ${MAX_IMAGE_SIDE} px per side.`);\n const src = pngDataUrl(pixels.width, pixels.height, pixels.data);\n this.imagePixels.set(src, pixels);\n return { src, pixels };\n }\n\n private decodeImage(src: string, what = 'Image'): PixelImage {\n const cached = this.imagePixels.get(src);\n if (cached) return cached;\n const parsed = parseDataUrl(src);\n if (!parsed) throw new PaintEditorError(`${what} is not a data URL or base64 PNG.`);\n try {\n const png = decodePng(parsed.bytes);\n const px = { width: png.width, height: png.height, data: png.data };\n this.imagePixels.set(src, px);\n return px;\n } catch (e) {\n throw new PaintEditorError(`${what} could not be decoded as a PNG (${(e as Error).message}); decode other formats in the browser and pass pixels.`);\n }\n }\n\n /**\n * Puts an image under the paint to trace over: view only, never in exports. Placed to fit the\n * canvas unless `rect` is given; `sampleColors` makes strokes take their colour from it.\n */\n setTracingImage(options: { png?: string; pixels?: PixelImage; rect?: TracingImage['rect']; opacity?: number; sampleColors?: boolean }): TracingImage {\n const { src, pixels } = this.importImage(options, 'The tracing image');\n const { width, height } = this.doc.canvas;\n const k = Math.min(width / pixels.width, height / pixels.height);\n const fit = { x: (width - pixels.width * k) / 2, y: (height - pixels.height * k) / 2, width: pixels.width * k, height: pixels.height * k };\n const tracing: TracingImage = { src, width: pixels.width, height: pixels.height, rect: fit, opacity: 0.35, visible: true, sampleColors: false };\n return this.updateTracing({ ...options, rect: options.rect ?? fit }, tracing);\n }\n\n /** Changes the tracing image's opacity, visibility, placement or colour sampling. */\n updateTracing(update: Partial<Pick<TracingImage, 'opacity' | 'visible' | 'sampleColors' | 'rect'>>, base = this.guides.tracing): TracingImage {\n if (!base) throw new PaintEditorError('There is no tracing image; set one with set_tracing_image first.');\n if (update.opacity !== undefined && !(update.opacity >= 0 && update.opacity <= 1)) throw new PaintEditorError(`opacity ${update.opacity} is out of range; use 0..1.`);\n if (update.rect && !(update.rect.width > 0 && update.rect.height > 0)) throw new PaintEditorError('rect needs a width and height above 0.');\n const tracing: TracingImage = {\n ...base,\n ...(update.opacity !== undefined ? { opacity: update.opacity } : {}),\n ...(update.visible !== undefined ? { visible: update.visible } : {}),\n ...(update.sampleColors !== undefined ? { sampleColors: update.sampleColors } : {}),\n ...(update.rect ? { rect: { ...update.rect } } : {}),\n };\n if (tracing.src !== base.src || update.rect) this.tracingVersion++;\n if (base !== this.guides.tracing) this.tracingVersion++;\n this.setGuides({ ...this.guides, tracing });\n return tracing;\n }\n\n clearTracingImage(): void {\n this.tracingVersion++;\n this.setGuides({ ...this.guides, tracing: null });\n }\n\n /** The tracing image's colour at a document pixel, or `null` outside it or where it is clear. */\n sampleTracingColor(x: number, y: number): string | null {\n const t = this.guides.tracing;\n if (!t) return null;\n const src = this.decodeImage(t.src);\n const u = Math.floor(((x - t.rect.x) / t.rect.width) * src.width);\n const v = Math.floor(((y - t.rect.y) / t.rect.height) * src.height);\n if (u < 0 || v < 0 || u >= src.width || v >= src.height) return null;\n const i = (v * src.width + u) * 4;\n if (src.data[i + 3] === 0) return null;\n return rgbToHex(src.data[i], src.data[i + 1], src.data[i + 2]);\n }\n\n /** Adds a floating reference image to look at and pick colours from. */\n addReferenceImage(options: { png?: string; pixels?: PixelImage; name?: string; x?: number; y?: number; displayWidth?: number }): ReferenceImage {\n const { src, pixels } = this.importImage(options, 'The reference image');\n const ref: ReferenceImage = {\n id: `ref${this.nextReferenceId++}`,\n name: options.name?.trim() || `Reference ${this.guides.references.length + 1}`,\n src,\n width: pixels.width,\n height: pixels.height,\n x: options.x ?? 16 + this.guides.references.length * 24,\n y: options.y ?? 16 + this.guides.references.length * 24,\n displayWidth: options.displayWidth ?? Math.min(240, pixels.width),\n visible: true,\n };\n this.setGuides({ ...this.guides, references: [...this.guides.references, ref] });\n return ref;\n }\n\n private requireReference(id: string): ReferenceImage {\n const r = this.guides.references.find((x) => x.id === id);\n if (!r) throw new PaintEditorError(`Unknown reference image \"${id}\". Call list_reference_images for the ids.`);\n return r;\n }\n\n /** Moves, resizes, renames, shows or hides a reference image. */\n updateReferenceImage(id: string, update: Partial<Pick<ReferenceImage, 'name' | 'x' | 'y' | 'displayWidth' | 'visible'>>): ReferenceImage {\n const r = this.requireReference(id);\n if (update.displayWidth !== undefined && !(update.displayWidth >= 16 && update.displayWidth <= 4096)) throw new PaintEditorError(`displayWidth ${update.displayWidth} is out of range; use 16..4096.`);\n const next: ReferenceImage = { ...r, ...Object.fromEntries(Object.entries(update).filter(([, v]) => v !== undefined)) };\n this.setGuides({ ...this.guides, references: this.guides.references.map((x) => (x.id === id ? next : x)) });\n return next;\n }\n\n removeReferenceImage(id: string): void {\n this.requireReference(id);\n this.setGuides({ ...this.guides, references: this.guides.references.filter((x) => x.id !== id) });\n }\n\n /** A reference image's pixels (decoded once). */\n referencePixels(id: string): PixelImage {\n return this.decodeImage(this.requireReference(id).src);\n }\n\n /** The colour of a reference image at its pixel (x, y). */\n pickReferenceColor(id: string, x: number, y: number): string {\n const r = this.requireReference(id);\n const px = this.decodeImage(r.src);\n const u = Math.floor(x);\n const v = Math.floor(y);\n if (!(u >= 0 && v >= 0 && u < px.width && v < px.height)) throw new PaintEditorError(`(${x}, ${y}) is outside reference \"${r.name}\" (${px.width}×${px.height}); use its own pixel coordinates.`);\n const i = (v * px.width + u) * 4;\n return rgbToHex(px.data[i], px.data[i + 1], px.data[i + 2]);\n }\n\n private readGuides(raw: unknown, state: PaintDocumentState, problems: string[]): void {\n const base = defaultGuides(state.canvas);\n this.guides = base;\n this.tracingVersion++;\n if (!raw || typeof raw !== 'object') return;\n const r = raw as Record<string, unknown>;\n const guides: PaintGuides = { ...base };\n guides.symmetry = normalizeSymmetry((r.symmetry as Record<string, unknown>) ?? {}, base.symmetry);\n try {\n guides.perspective = normalizePerspective((r.perspective as Record<string, unknown>) ?? {}, base.perspective);\n } catch (e) {\n problems.push(`Perspective guide: ${(e as Error).message}`);\n }\n const t = r.tracing as TracingImage | null | undefined;\n if (t && typeof t.src === 'string') {\n try {\n const px = this.decodeImage(t.src, 'The tracing image');\n guides.tracing = {\n src: t.src,\n width: px.width,\n height: px.height,\n rect: t.rect && t.rect.width > 0 && t.rect.height > 0 ? { ...t.rect } : { x: 0, y: 0, width: state.canvas.width, height: state.canvas.height },\n opacity: typeof t.opacity === 'number' ? Math.min(1, Math.max(0, t.opacity)) : 0.35,\n visible: t.visible !== false,\n sampleColors: t.sampleColors === true,\n };\n } catch (e) {\n problems.push((e as Error).message);\n }\n }\n if (Array.isArray(r.references)) {\n for (const ref of r.references as ReferenceImage[]) {\n if (!ref || typeof ref.src !== 'string' || typeof ref.id !== 'string') continue;\n try {\n const px = this.decodeImage(ref.src, `Reference \"${ref.name}\"`);\n guides.references.push({ id: ref.id, name: String(ref.name ?? ref.id), src: ref.src, width: px.width, height: px.height, x: Number(ref.x) || 0, y: Number(ref.y) || 0, displayWidth: Number(ref.displayWidth) || 240, visible: ref.visible !== false });\n const n = Number(/^ref(\\d+)$/.exec(ref.id)?.[1] ?? 0);\n if (n >= this.nextReferenceId) this.nextReferenceId = n + 1;\n } catch (e) {\n problems.push((e as Error).message);\n }\n }\n }\n this.guides = guides;\n }\n\n // --- Swatches and harmonies ------------------------------------------------------\n\n /** Colour harmonies around a colour (default the paint colour) on the painter's RYB wheel or the RGB wheel. */\n harmony(kind: HarmonyKind, options: { color?: string; wheel?: ColorWheel; spread?: number } = {}): HarmonyColor[] {\n try {\n return colorHarmony(options.color === undefined ? this.color : parseColor(options.color), kind, options);\n } catch (e) {\n throw new PaintEditorError((e as Error).message);\n }\n }\n\n addSwatch(color: string, name?: string): Swatch[] {\n const c = parseColor(color);\n this.swatches = [...this.swatches, name?.trim() ? { color: c, name: name.trim() } : { color: c }];\n this.emit([]);\n return this.swatches;\n }\n\n removeSwatch(index: number): Swatch[] {\n if (!Number.isInteger(index) || index < 0 || index >= this.swatches.length) throw new PaintEditorError(`index ${index} is out of range; there are ${this.swatches.length} swatches (0-based).`);\n this.swatches = this.swatches.filter((_, i) => i !== index);\n this.emit([]);\n return this.swatches;\n }\n\n setSwatches(swatches: readonly Swatch[]): Swatch[] {\n this.swatches = swatches.map((x) => (x.name ? { color: parseColor(x.color), name: x.name } : { color: parseColor(x.color) }));\n this.emit([]);\n return this.swatches;\n }\n\n // --- Mixing pad ------------------------------------------------------------------\n\n get mixingPad(): MixingPad {\n return this.pad;\n }\n\n /** Paints (`paint`) or smears with the palette knife (`knife`) on the mixing pad, in pad pixels. */\n mixingPadStroke(points: readonly PenPoint[], options: { tool?: MixingPadTool; color?: string; size?: number } = {}): { bounds: RasterRect | null } {\n const color = options.color === undefined ? this.color : parseColor(options.color);\n if (options.size !== undefined && !(options.size >= 1 && options.size <= 200)) throw new PaintEditorError(`size ${options.size} is out of range; use 1..200 px.`);\n try {\n const r = this.pad.stroke(points, { tool: options.tool ?? 'paint', color, size: options.size });\n this.emit([]);\n return r;\n } catch (e) {\n throw new PaintEditorError((e as Error).message);\n }\n }\n\n /** Picks the mixed colour on the pad (averaged over `radius` px); with `setColor` it becomes the paint colour. */\n mixingPadPick(x: number, y: number, options: { radius?: number; setColor?: boolean } = {}): string | null {\n let c: string | null;\n try {\n c = this.pad.pick(x, y, options.radius);\n } catch (e) {\n throw new PaintEditorError((e as Error).message);\n }\n if (c && options.setColor) this.setColor(c);\n return c;\n }\n\n clearMixingPad(): void {\n this.pad.clear();\n this.emit([]);\n }\n\n /** A layer's tile surface (live while stroking), for thumbnails. */\n layerSurface(id: string): TiledSurface | null {\n const l = findLayer(this.currentLayers(), id)?.layer;\n return isPixelLayer(l) ? l.surface : null;\n }\n}\n\nexport type { Tile };\n\n/** Largest tracing or reference image side, in pixels. */\nexport const MAX_IMAGE_SIDE = 8192;\n\n/** `src` drawn into `rect` of a `width × height` canvas (bilinear), canvas-sized RGBA. */\nfunction resampleInto(src: PixelImage, rect: { x: number; y: number; width: number; height: number }, width: number, height: number): PixelImage {\n const out = new Uint8ClampedArray(width * height * 4);\n const x0 = Math.max(0, Math.floor(rect.x));\n const y0 = Math.max(0, Math.floor(rect.y));\n const x1 = Math.min(width, Math.ceil(rect.x + rect.width));\n const y1 = Math.min(height, Math.ceil(rect.y + rect.height));\n const sx = src.width / rect.width;\n const sy = src.height / rect.height;\n const d = src.data;\n for (let y = y0; y < y1; y++) {\n const v = Math.min(src.height - 1, Math.max(0, (y + 0.5 - rect.y) * sy - 0.5));\n const j0 = Math.floor(v);\n const j1 = Math.min(src.height - 1, j0 + 1);\n const fy = v - j0;\n for (let x = x0; x < x1; x++) {\n const u = (x + 0.5 - rect.x) * sx - 0.5;\n if (u < -0.5 || u > src.width - 0.5 || (y + 0.5 - rect.y) * sy < 0 || (y + 0.5 - rect.y) * sy > src.height) continue;\n const uc = Math.min(src.width - 1, Math.max(0, u));\n const i0 = Math.floor(uc);\n const i1 = Math.min(src.width - 1, i0 + 1);\n const fx = uc - i0;\n const o = (y * width + x) * 4;\n for (let c = 0; c < 4; c++) {\n const a = d[(j0 * src.width + i0) * 4 + c] + (d[(j0 * src.width + i1) * 4 + c] - d[(j0 * src.width + i0) * 4 + c]) * fx;\n const b = d[(j1 * src.width + i0) * 4 + c] + (d[(j1 * src.width + i1) * 4 + c] - d[(j1 * src.width + i0) * 4 + c]) * fx;\n out[o + c] = a + (b - a) * fy;\n }\n }\n }\n return { width, height, data: out };\n}\n","/**\n * Agent tools for the paint editor's painting guides (symmetry, perspective, tracing and reference\n * images) and colour (harmonies, swatches, the mixing pad). Guides, swatches and the pad are\n * editor state saved with the document (the pad is not saved), not undo steps.\n */\n\nimport type { AgentTool } from '../tools/registry.js';\nimport { bytesToBase64, encodePng } from '../raster/png';\nimport { HARMONY_KINDS } from './color';\nimport type { PaintEditorController } from './controller';\nimport { SYMMETRY_MODES, symmetryCopies, type ReferenceImage, type TracingImage } from './guides';\nimport type { PenPoint } from './engine';\n\nconst READ = { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false } as const;\nconst WRITE = { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false } as const;\nconst SET = { readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: false } as const;\nconst DESTRUCTIVE = { readOnlyHint: false, destructiveHint: true, idempotentHint: false, openWorldHint: false } as const;\nconst EMPTY = { type: 'object', properties: {}, additionalProperties: false } as const;\nconst COLOR = { type: 'string', pattern: '^#[0-9a-fA-F]{6}$', description: 'Colour #rrggbb.' } as const;\nconst POINT = {\n type: 'object',\n properties: { x: { type: 'number', description: 'x in document pixels.' }, y: { type: 'number', description: 'y in document pixels.' } },\n required: ['x', 'y'],\n additionalProperties: false,\n} as const;\nconst RECT = {\n type: 'object',\n description: 'Placement in document pixels.',\n properties: {\n x: { type: 'number', description: 'Left edge.' },\n y: { type: 'number', description: 'Top edge.' },\n width: { type: 'number', exclusiveMinimum: 0, description: 'Width.' },\n height: { type: 'number', exclusiveMinimum: 0, description: 'Height.' },\n },\n required: ['x', 'y', 'width', 'height'],\n additionalProperties: false,\n} as const;\nconst PNG = { type: 'string', minLength: 1, description: 'The image as a PNG, base64 or a data:image/png URL.' } as const;\n\nconst tracingInfo = (t: TracingImage | null) => (t ? { width: t.width, height: t.height, rect: t.rect, opacity: t.opacity, visible: t.visible, sampleColors: t.sampleColors } : null);\nconst refInfo = ({ src: _s, ...r }: ReferenceImage) => r;\n\nexport function createPaintGuideTools(c: PaintEditorController): AgentTool[] {\n const guides = () => c.getState().guides;\n return [\n {\n name: 'get_guides',\n title: 'Get the painting guides',\n description: 'Reads the painting guides: symmetry (mode, centre, rotation, segments, mirror, and how many copies each stroke paints), the perspective guide (vanishing points, snap), the tracing image (size, placement, opacity, visibility, colour sampling) and the reference images.',\n inputSchema: EMPTY,\n annotations: { title: 'Get the painting guides', ...READ },\n handler: () => {\n const g = guides();\n return { symmetry: { ...g.symmetry, copies: symmetryCopies(g.symmetry).length }, perspective: g.perspective, tracing: tracingInfo(g.tracing), references: g.references.map(refInfo) };\n },\n },\n {\n name: 'set_symmetry',\n title: 'Set mirror or kaleidoscope painting',\n description:\n 'Turns symmetry on or off. Every stroke after it also paints its copies, as one stroke and one undo step: vertical, horizontal or diagonal mirror (one copy), dual (four-way), or kaleidoscope with n segments (rotated copies, and with mirror the reflections between them). Editor state, saved with the document. Returns the guide and the number of copies.',\n inputSchema: {\n type: 'object',\n properties: {\n mode: { type: 'string', enum: [...SYMMETRY_MODES], description: 'off, vertical (mirror left / right), horizontal (top / bottom), dual, diagonal or kaleidoscope.' },\n center: { ...POINT, description: 'Centre of the axes in document pixels (default the canvas centre).' },\n rotation: { type: 'number', minimum: -360, maximum: 360, description: 'Turn the axes, degrees clockwise.' },\n segments: { type: 'integer', minimum: 2, maximum: 32, description: 'Kaleidoscope segments (default 6).' },\n mirror: { type: 'boolean', description: 'Kaleidoscope: also reflect alternate segments (default true).' },\n },\n additionalProperties: false,\n },\n annotations: { title: 'Set mirror or kaleidoscope painting', ...SET },\n handler: (a) => {\n const s = c.setSymmetry(a);\n return { ...s, copies: symmetryCopies(s).length };\n },\n },\n {\n name: 'set_perspective_guide',\n title: 'Set the perspective guide',\n description:\n 'Sets one to three vanishing points (document pixels, may be off the canvas). With snap on, pen strokes snap to the line through their start towards a vanishing point (one-point also keeps horizontals and verticals, two-point verticals); for paint_stroke pass snapToPerspective. Editor state, saved with the document. Returns the guide.',\n inputSchema: {\n type: 'object',\n properties: {\n enabled: { type: 'boolean', description: 'Show and use the guide.' },\n points: { type: 'array', minItems: 1, maxItems: 3, items: { ...POINT, description: 'A vanishing point.' }, description: 'The vanishing points.' },\n snap: { type: 'boolean', description: 'Snap strokes to the guide lines (default true).' },\n },\n additionalProperties: false,\n },\n annotations: { title: 'Set the perspective guide', ...SET },\n handler: (a) => c.setPerspective(a),\n },\n {\n name: 'set_tracing_image',\n title: 'Set a tracing image',\n description:\n 'Puts an image under the paint to trace over (view only: never exported), fitted to the canvas unless rect is given, at opacity (default 0.35). With sampleColors, strokes without a colour take the image colour where they start, so painting over it copies its colours. Replaces any tracing image. Returns its size and placement.',\n inputSchema: {\n type: 'object',\n properties: {\n png: PNG,\n rect: RECT,\n opacity: { type: 'number', minimum: 0, maximum: 1, description: 'Opacity 0..1 (default 0.35).' },\n sampleColors: { type: 'boolean', description: 'Strokes take their colour from the image (default false).' },\n },\n required: ['png'],\n additionalProperties: false,\n },\n annotations: { title: 'Set a tracing image', ...WRITE },\n handler: (a) => tracingInfo(c.setTracingImage(a)),\n },\n {\n name: 'update_tracing_image',\n title: 'Change the tracing image',\n description: 'Changes the tracing image opacity, visibility, placement or colour sampling. Returns it.',\n inputSchema: {\n type: 'object',\n properties: {\n opacity: { type: 'number', minimum: 0, maximum: 1, description: 'Opacity 0..1.' },\n visible: { type: 'boolean', description: 'Show or hide it.' },\n sampleColors: { type: 'boolean', description: 'Strokes take their colour from it.' },\n rect: RECT,\n },\n additionalProperties: false,\n },\n annotations: { title: 'Change the tracing image', ...SET },\n handler: (a) => tracingInfo(c.updateTracing(a)),\n },\n {\n name: 'clear_tracing_image',\n title: 'Remove the tracing image',\n description: 'Removes the tracing image. Returns null.',\n inputSchema: EMPTY,\n annotations: { title: 'Remove the tracing image', ...DESTRUCTIVE },\n handler: () => {\n c.clearTracingImage();\n return { tracing: null };\n },\n },\n {\n name: 'add_reference_image',\n title: 'Add a reference image',\n description: 'Adds a floating reference image (shown beside the canvas, never painted) to look at and pick colours from with pick_reference_color. Returns its id, size and placement.',\n inputSchema: {\n type: 'object',\n properties: {\n png: PNG,\n name: { type: 'string', minLength: 1, description: 'Display name.' },\n x: { type: 'number', description: 'Panel left in viewport pixels.' },\n y: { type: 'number', description: 'Panel top in viewport pixels.' },\n displayWidth: { type: 'number', minimum: 16, maximum: 4096, description: 'Panel width in screen pixels (default up to 240).' },\n },\n required: ['png'],\n additionalProperties: false,\n },\n annotations: { title: 'Add a reference image', ...WRITE },\n handler: (a) => refInfo(c.addReferenceImage(a)),\n },\n {\n name: 'list_reference_images',\n title: 'List reference images',\n description: 'Lists the reference images: id, name, size in pixels, panel placement and visibility.',\n inputSchema: EMPTY,\n annotations: { title: 'List reference images', ...READ },\n handler: () => ({ references: guides().references.map(refInfo) }),\n },\n {\n name: 'update_reference_image',\n title: 'Change a reference image',\n description: 'Moves, resizes, renames, shows or hides a reference image panel. Returns it.',\n inputSchema: {\n type: 'object',\n properties: {\n id: { type: 'string', description: 'Reference id from list_reference_images.' },\n name: { type: 'string', minLength: 1, description: 'Display name.' },\n x: { type: 'number', description: 'Panel left in viewport pixels.' },\n y: { type: 'number', description: 'Panel top in viewport pixels.' },\n displayWidth: { type: 'number', minimum: 16, maximum: 4096, description: 'Panel width in screen pixels.' },\n visible: { type: 'boolean', description: 'Show or hide it.' },\n },\n required: ['id'],\n additionalProperties: false,\n },\n annotations: { title: 'Change a reference image', ...SET },\n handler: ({ id, ...u }) => refInfo(c.updateReferenceImage(id, u)),\n },\n {\n name: 'remove_reference_image',\n title: 'Remove a reference image',\n description: 'Removes a reference image. Returns the removed id.',\n inputSchema: { type: 'object', properties: { id: { type: 'string', description: 'Reference id from list_reference_images.' } }, required: ['id'], additionalProperties: false },\n annotations: { title: 'Remove a reference image', ...DESTRUCTIVE },\n handler: ({ id }) => {\n c.removeReferenceImage(id);\n return { removed: id };\n },\n },\n {\n name: 'pick_reference_color',\n title: 'Pick a colour from a reference',\n description: 'Reads the colour of a reference image at its own pixel (x, y). With setColor it becomes the paint colour. Returns #rrggbb.',\n inputSchema: {\n type: 'object',\n properties: {\n id: { type: 'string', description: 'Reference id from list_reference_images.' },\n x: { type: 'number', minimum: 0, description: 'x in the image’s pixels.' },\n y: { type: 'number', minimum: 0, description: 'y in the image’s pixels.' },\n setColor: { type: 'boolean', description: 'Also make it the paint colour (default false).' },\n },\n required: ['id', 'x', 'y'],\n additionalProperties: false,\n },\n annotations: { title: 'Pick a colour from a reference', ...SET },\n handler: ({ id, x, y, setColor }) => {\n const color = c.pickReferenceColor(id, x, y);\n if (setColor) c.setColor(color);\n return { color };\n },\n },\n {\n name: 'color_harmony',\n title: 'Colour harmonies',\n description:\n 'Returns the colours of a harmony around a colour (default the paint colour): complementary, split-complementary, analogous, triadic, tetradic, square or monochromatic, on the painter’s red-yellow-blue wheel (default: red’s complement is green) or the RGB wheel. Changes nothing. Returns the colours with their wheel angles, the base first.',\n inputSchema: {\n type: 'object',\n properties: {\n kind: { type: 'string', enum: [...HARMONY_KINDS], description: 'The harmony.' },\n color: { ...COLOR, description: 'Base colour #rrggbb (default the paint colour).' },\n wheel: { type: 'string', enum: ['ryb', 'rgb'], description: 'ryb (painter’s wheel, default) or rgb.' },\n spread: { type: 'number', minimum: 5, maximum: 90, description: 'Analogous and split-complementary spread in degrees (default 30).' },\n },\n required: ['kind'],\n additionalProperties: false,\n },\n annotations: { title: 'Colour harmonies', ...READ },\n handler: ({ kind, color, wheel, spread }) => ({ kind, wheel: wheel ?? 'ryb', colors: c.harmony(kind, { color, wheel, spread }) }),\n },\n {\n name: 'list_swatches',\n title: 'List swatches',\n description: 'Lists the colour swatches (index, colour, name).',\n inputSchema: EMPTY,\n annotations: { title: 'List swatches', ...READ },\n handler: () => ({ swatches: c.getState().swatches.map((s, index) => ({ index, ...s })) }),\n },\n {\n name: 'add_swatch',\n title: 'Add a swatch',\n description: 'Adds a colour to the swatches (saved with the document). Returns the swatches.',\n inputSchema: {\n type: 'object',\n properties: { color: COLOR, name: { type: 'string', minLength: 1, description: 'Optional name.' } },\n required: ['color'],\n additionalProperties: false,\n },\n annotations: { title: 'Add a swatch', ...WRITE },\n handler: ({ color, name }) => ({ swatches: c.addSwatch(color, name).map((s, index) => ({ index, ...s })) }),\n },\n {\n name: 'remove_swatch',\n title: 'Remove a swatch',\n description: 'Removes a swatch by index (from list_swatches). Returns the swatches.',\n inputSchema: { type: 'object', properties: { index: { type: 'integer', minimum: 0, description: '0-based index.' } }, required: ['index'], additionalProperties: false },\n annotations: { title: 'Remove a swatch', ...DESTRUCTIVE },\n handler: ({ index }) => ({ swatches: c.removeSwatch(index).map((s, i) => ({ index: i, ...s })) }),\n },\n {\n name: 'mixing_pad_stroke',\n title: 'Paint on the mixing pad',\n description:\n 'Paints on the mixing pad (a 360 × 220 scratch canvas, not the painting): tool paint lays down a colour with a pigment Mixer Brush; tool knife smears what is there like a palette knife, mixing it as paint. Points are pad pixels. Not an undo step. Returns the changed bounds; then pick_mixing_pad_color.',\n inputSchema: {\n type: 'object',\n properties: {\n points: {\n type: 'array',\n minItems: 1,\n maxItems: 2000,\n description: 'The path in pad pixels (0..360, 0..220).',\n items: {\n type: 'object',\n properties: { x: { type: 'number', description: 'Pad x.' }, y: { type: 'number', description: 'Pad y.' }, pressure: { type: 'number', minimum: 0, maximum: 1, description: 'Pressure (default 1).' } },\n required: ['x', 'y'],\n additionalProperties: false,\n },\n },\n tool: { type: 'string', enum: ['paint', 'knife'], description: 'paint (default) or knife.' },\n color: { ...COLOR, description: 'Paint colour (default the paint colour; ignored by the knife).' },\n size: { type: 'number', minimum: 1, maximum: 200, description: 'Tool size in pad pixels (default 28 paint, 34 knife).' },\n },\n required: ['points'],\n additionalProperties: false,\n },\n annotations: { title: 'Paint on the mixing pad', ...WRITE },\n handler: ({ points, tool, color, size }) => c.mixingPadStroke(points as PenPoint[], { tool, color, size }),\n },\n {\n name: 'pick_mixing_pad_color',\n title: 'Pick from the mixing pad',\n description: 'Reads the mixed colour on the pad at (x, y), averaged over radius pixels (default 3); with setColor it becomes the paint colour. Returns #rrggbb, or null where the pad is bare.',\n inputSchema: {\n type: 'object',\n properties: {\n x: { type: 'number', minimum: 0, maximum: 360, description: 'Pad x.' },\n y: { type: 'number', minimum: 0, maximum: 220, description: 'Pad y.' },\n radius: { type: 'integer', minimum: 0, maximum: 20, description: 'Averaging radius in pixels (default 3).' },\n setColor: { type: 'boolean', description: 'Also make it the paint colour (default false).' },\n },\n required: ['x', 'y'],\n additionalProperties: false,\n },\n annotations: { title: 'Pick from the mixing pad', ...SET },\n handler: ({ x, y, radius, setColor }) => ({ color: c.mixingPadPick(x, y, { radius, setColor }) }),\n },\n {\n name: 'clear_mixing_pad',\n title: 'Clear the mixing pad',\n description: 'Wipes the mixing pad clean.',\n inputSchema: EMPTY,\n annotations: { title: 'Clear the mixing pad', ...DESTRUCTIVE },\n handler: () => {\n c.clearMixingPad();\n return { cleared: true };\n },\n },\n {\n name: 'render_mixing_pad',\n title: 'Render the mixing pad',\n description: 'Renders the mixing pad as a PNG (360 × 220, over white). Changes nothing.',\n inputSchema: EMPTY,\n annotations: { title: 'Render the mixing pad', ...READ },\n handler: () => {\n const pad = c.mixingPad;\n return {\n content: [\n { type: 'image', data: bytesToBase64(encodePng(pad.width, pad.height, pad.pixels())), mimeType: 'image/png' },\n { type: 'text', text: `Mixing pad ${pad.width}×${pad.height}` },\n ],\n };\n },\n },\n ];\n}\n","/**\n * Agent tools for the paint editor (`createPaintEditorToolProvider`). Strict schemas, every\n * argument described, all four annotations. Each write is one undo step (or editor state, said so)\n * and returns what it changed; ids come from the read tools (`list_layers`, `list_brushes`,\n * `list_papers`, `list_strokes`).\n */\n\nimport type { AgentTool, AgentToolProvider } from '../tools/registry.js';\nimport { createPigmentTools } from '../paint/pigment-tools';\nimport { MIXING_MODELS, type MixerLoad } from '../paint/mixer';\nimport { BLEND_MODES, standardBlendMode, type BlendMode } from '../raster/blend';\nimport { bytesToBase64, encodePng } from '../raster/png';\nimport { BRUSH_ROTATIONS, MAX_BRUSH_SIZE, PAINT_BRUSH_CATEGORIES, PAINT_BRUSH_ENGINES, brushToJSON, type PaintBrush } from './brushes';\nimport { MAX_CANVAS_SIDE } from './document';\nimport type { PaintEditorController } from './controller';\nimport type { PenPoint } from './engine';\nimport { GRAIN_PATTERNS, PAPER_FAMILIES, PAPER_LIBRARY } from './paper';\nimport { MAX_ZOOM, MIN_ZOOM } from './view';\nimport { createPaintGuideTools } from './guide-tools';\n\nconst READ = { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false } as const;\nconst WRITE = { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false } as const;\nconst SET = { readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: false } as const;\nconst DESTRUCTIVE = { readOnlyHint: false, destructiveHint: true, idempotentHint: false, openWorldHint: false } as const;\n\nconst EMPTY = { type: 'object', properties: {}, additionalProperties: false } as const;\nconst COLOR = { type: 'string', pattern: '^#[0-9a-fA-F]{6}$', description: 'Colour #rrggbb, e.g. \"#2a4b8d\".' } as const;\nconst LAYER_ID = { type: 'string', description: 'Layer id from list_layers (default the active layer).' } as const;\n\nexport interface PaintEditorToolProviderOptions {\n /** Provider id (unique per registry). Default `paint-editor`. */\n id?: string;\n /** Always prefix tool names with `<namespace>__`. */\n namespace?: string;\n}\n\nconst TIP = {\n type: 'object',\n description: 'The tip (the shared brush engine). Missing fields keep their current values.',\n properties: {\n size: { type: 'number', minimum: 1, maximum: MAX_BRUSH_SIZE, description: 'Diameter in document pixels.' },\n hardness: { type: 'number', minimum: 0, maximum: 1, description: 'Edge hardness, 0 (soft) .. 1 (hard).' },\n spacing: { type: 'number', minimum: 0.01, maximum: 10, description: 'Dab spacing as a fraction of the diameter (0.05 is smooth, 1 is dotted).' },\n angle: { type: 'number', minimum: -360, maximum: 360, description: 'Tip angle in degrees, counter-clockwise; with rotation stroke or barrel it is added to the stroke direction or pen rotation.' },\n roundness: { type: 'number', minimum: 0.01, maximum: 1, description: 'Tip roundness: 1 round, lower is a flat ellipse (a pastel or chisel tip).' },\n opacity: { type: 'number', minimum: 0, maximum: 1, description: 'Stroke opacity ceiling: overlapping dabs never exceed it.' },\n flow: { type: 'number', minimum: 0, maximum: 1, description: 'Build-up per dab towards the opacity (low flow builds up softly, like an airbrush).' },\n smoothing: { type: 'number', minimum: 0, maximum: 0.95, description: 'Position smoothing of the input, 0..0.95.' },\n pressureSize: { type: 'boolean', description: 'Pressure scales the size (down to dynamics.minSize).' },\n pressureOpacity: { type: 'boolean', description: 'Pressure scales the opacity.' },\n blend: {\n type: 'string',\n enum: BLEND_MODES.map((m) => m.id),\n description: 'How paint combines with the layer. pigment mixes it in like real paint (blue into yellow gives green); multiply darkens like marker ink; watercolor glazes like a transparent wash; tint, highlight and shadow recolour, light and shade (see list_blend_modes).',\n },\n },\n additionalProperties: false,\n} as const;\n\nconst DYNAMICS = {\n type: 'object',\n description: 'Pen dynamics and jitter. Missing fields keep their current values.',\n properties: {\n minSize: { type: 'number', minimum: 0, maximum: 1, description: 'Size at zero pressure as a fraction of the full size (when pressureSize).' },\n pressureFlow: { type: 'number', minimum: 0, maximum: 1, description: 'How much pressure scales flow.' },\n tiltSize: { type: 'number', minimum: 0, maximum: 1, description: 'Laying the pen down widens the tip (up to 2.5×).' },\n tiltRoundness: { type: 'number', minimum: 0, maximum: 1, description: 'Laying the pen down flattens the tip along the tilt (side-of-the-pencil shading).' },\n tiltOpacity: { type: 'number', minimum: 0, maximum: 1, description: 'Laying the pen down lightens the mark.' },\n velocitySize: { type: 'number', minimum: -1, maximum: 1, description: 'Positive grows the tip on fast strokes, negative thins it (needs point times t).' },\n velocityOpacity: { type: 'number', minimum: -1, maximum: 1, description: 'Positive darkens fast marks, negative lightens them (needs point times t).' },\n sizeJitter: { type: 'number', minimum: 0, maximum: 1, description: 'Random size change per dab.' },\n angleJitter: { type: 'number', minimum: 0, maximum: 1, description: 'Random angle per dab, as a fraction of ±180°.' },\n opacityJitter: { type: 'number', minimum: 0, maximum: 1, description: 'Random opacity drop per dab.' },\n scatter: { type: 'number', minimum: 0, maximum: 4, description: 'Random offset across the stroke, in diameters.' },\n },\n additionalProperties: false,\n} as const;\n\nconst MIXER = {\n type: 'object',\n description: 'Mixer engine settings (Mixer Brush, blender, smudge). Missing fields keep their current values.',\n properties: {\n wet: { type: 'number', minimum: 0, maximum: 1, description: 'How much canvas colour each dab picks up, 0 (dry) .. 1.' },\n load: { type: 'number', minimum: 0, maximum: 1, description: 'How much paint the reservoir holds; below 1 it drains per dab, so long strokes run dry.' },\n mix: { type: 'number', minimum: 0, maximum: 1, description: \"How far each dab's paint moves from the reservoir towards the picked-up colour.\" },\n loadEachStroke: { type: 'boolean', description: 'Refill the reservoir with the colour before each stroke.' },\n cleanEachStroke: { type: 'boolean', description: 'Empty the pickup well after each stroke.' },\n mixing: { type: 'string', enum: [...MIXING_MODELS], description: 'rgb: RGB averages. pigment: mixes like paint (Kubelka-Munk).' },\n },\n additionalProperties: false,\n} as const;\n\nconst BRUSH_FIELDS = {\n name: { type: 'string', minLength: 1, maxLength: 80, description: 'Display name.' },\n category: { type: 'string', enum: [...PAINT_BRUSH_CATEGORIES], description: 'Library category.' },\n engine: { type: 'string', enum: [...PAINT_BRUSH_ENGINES], description: 'dab: paints dabs; eraser: removes paint; mixer: picks up and moves paint (Mixer Brush, blender, smudge).' },\n tip: TIP,\n grain: { type: 'number', minimum: 0, maximum: 1, description: 'Paper grain response: 0 ignores the grain, 1 catches only its peaks at light pressure (pencil, pastel, charcoal). Multiplied by the paper depth.' },\n pressureSmoothing: { type: 'number', minimum: 0, maximum: 0.95, description: 'Pressure smoothing, separate from the tip position smoothing.' },\n rotation: { type: 'string', enum: [...BRUSH_ROTATIONS], description: 'What turns the tip: fixed (tip.angle), stroke (follows the direction of travel) or barrel (the pen barrel rotation, twist).' },\n dynamics: DYNAMICS,\n mixer: MIXER,\n loadsColor: { type: 'boolean', description: 'Mixer engine: load the colour each stroke (false for blender and smudge, which only move paint).' },\n} as const;\n\nconst POINTS = {\n type: 'array',\n minItems: 1,\n maxItems: 20000,\n description: 'The path in document pixels (raw samples; the brush smooths them). One point paints one dab.',\n items: {\n type: 'object',\n properties: {\n x: { type: 'number', description: 'Document x in pixels.' },\n y: { type: 'number', description: 'Document y in pixels.' },\n pressure: { type: 'number', minimum: 0, maximum: 1, description: 'Pen pressure 0..1 (default 1).' },\n t: { type: 'number', description: 'Time in milliseconds (optional; drives velocity dynamics, e.g. an ink pen thinning on fast strokes).' },\n tiltX: { type: 'number', minimum: -90, maximum: 90, description: 'Pen tilt in degrees towards +x (Pointer Events tiltX).' },\n tiltY: { type: 'number', minimum: -90, maximum: 90, description: 'Pen tilt in degrees towards +y (Pointer Events tiltY).' },\n altitude: { type: 'number', minimum: 0, maximum: 1.5708, description: 'Pen altitude in radians: 1.5708 upright, 0 lying flat (overrides tiltX / tiltY).' },\n azimuth: { type: 'number', minimum: 0, maximum: 6.2832, description: 'Where the pen leans, radians clockwise from +x (with altitude).' },\n twist: { type: 'number', minimum: 0, maximum: 359, description: 'Barrel rotation in degrees (brushes with rotation barrel).' },\n },\n required: ['x', 'y'],\n additionalProperties: false,\n },\n} as const;\n\nfunction loadResult(load: MixerLoad) {\n const hex = (c: readonly number[] | null) => (c ? '#' + c.map((v) => Math.round(Math.min(1, Math.max(0, v)) * 255).toString(16).padStart(2, '0')).join('') : null);\n return { reservoir: hex(load.reservoir), amount: Math.round(load.amount * 1000) / 1000, pickup: hex(load.pickup) };\n}\n\nfunction brushSummary(b: PaintBrush) {\n return { id: b.id, name: b.name, category: b.category, engine: b.engine, size: b.tip.size, grain: b.grain, rotation: b.rotation, builtin: Boolean(b.builtin) };\n}\n\n/** Agent tools for one paint editor. */\nexport function createPaintEditorToolProvider(controller: PaintEditorController, options: PaintEditorToolProviderOptions = {}): AgentToolProvider {\n const c = controller;\n const tools: AgentTool[] = [];\n const add = (t: AgentTool) => tools.push(t);\n\n // --- Canvas ------------------------------------------------------------------\n\n add({\n name: 'get_canvas_info',\n title: 'Get the canvas',\n description:\n 'Reads the canvas: size in pixels and dpi, the paper (preset, colour, grain depth), the active layer, the active brush id, the paint colour, the view (zoom, rotation, mirror), the hand, how many strokes are recorded, the undo / redo labels, and the blend modes. Call it first.',\n inputSchema: EMPTY,\n annotations: { title: 'Get the canvas', ...READ },\n handler: () => {\n const s = c.getState();\n const d = s.document;\n return {\n width: d.canvas.width,\n height: d.canvas.height,\n dpi: d.canvas.dpi,\n paper: { preset: d.paper.preset, name: d.paper.name, color: d.paper.color, depth: d.paper.depth },\n activeLayerId: d.activeLayerId,\n layerCount: c.listLayers().length,\n brushId: s.brush.id,\n color: s.color,\n secondaryColor: s.secondaryColor,\n view: { zoom: s.view.zoom, rotation: s.view.rotation, mirror: s.view.mirror },\n hand: s.hand,\n strokes: d.strokes.length,\n undo: s.undoLabel,\n redo: s.redoLabel,\n blendModes: BLEND_MODES.map((m) => m.id),\n };\n },\n });\n\n add({\n name: 'new_canvas',\n title: 'Start a new canvas',\n description:\n 'Replaces the document with a blank canvas: one empty layer over the paper. Size and dpi default to the current ones, the paper to the current paper (or a preset id from list_papers). One undo step (undo brings the old painting back). Returns the new size, paper and layer id.',\n inputSchema: {\n type: 'object',\n properties: {\n width: { type: 'integer', minimum: 1, maximum: MAX_CANVAS_SIDE, description: 'Width in pixels (default the current width).' },\n height: { type: 'integer', minimum: 1, maximum: MAX_CANVAS_SIDE, description: 'Height in pixels (default the current height).' },\n dpi: { type: 'number', minimum: 1, maximum: 10000, description: 'Pixels per inch for print sizes and PSD (default the current dpi).' },\n paper: { type: 'string', description: 'Paper preset id from list_papers (default the current paper).' },\n },\n additionalProperties: false,\n },\n annotations: { title: 'Start a new canvas', ...DESTRUCTIVE },\n handler: (a) => {\n const d = c.newCanvas({ width: a.width, height: a.height, dpi: a.dpi, paper: a.paper });\n return { width: d.canvas.width, height: d.canvas.height, dpi: d.canvas.dpi, paper: d.paper.preset, layerId: d.activeLayerId };\n },\n });\n\n add({\n name: 'set_canvas',\n title: 'Resize the canvas',\n description:\n 'Changes the canvas size (pixels stay where they are, anchored at the top-left; anything outside is kept on the layers but not shown) and / or its dpi. One undo step. Returns the canvas.',\n inputSchema: {\n type: 'object',\n properties: {\n width: { type: 'integer', minimum: 1, maximum: MAX_CANVAS_SIDE, description: 'Width in pixels (default unchanged).' },\n height: { type: 'integer', minimum: 1, maximum: MAX_CANVAS_SIDE, description: 'Height in pixels (default unchanged).' },\n dpi: { type: 'number', minimum: 1, maximum: 10000, description: 'Pixels per inch (default unchanged).' },\n },\n additionalProperties: false,\n },\n annotations: { title: 'Resize the canvas', ...SET },\n handler: (a) => c.setCanvas({ width: a.width, height: a.height, dpi: a.dpi }),\n });\n\n // --- Paper -------------------------------------------------------------------\n\n add({\n name: 'list_papers',\n title: 'List papers',\n description:\n 'Lists the built-in paper library (generated grain, no textures): id, name, family, grain pattern, colour, grain depth and the wet-media properties (absorption, permeability, roughness). Use an id with set_paper or new_canvas.',\n inputSchema: EMPTY,\n annotations: { title: 'List papers', ...READ },\n handler: () => ({\n papers: PAPER_LIBRARY.map((p) => ({ id: p.preset, name: p.name, family: p.family, pattern: p.pattern, color: p.color, depth: p.depth, absorption: p.absorption, permeability: p.permeability, roughness: p.roughness })),\n families: [...PAPER_FAMILIES],\n patterns: [...GRAIN_PATTERNS],\n }),\n });\n\n add({\n name: 'get_paper',\n title: 'Get the paper',\n description: 'Reads every setting of the current paper (preset, pattern, seed, colour, scale, tiling, depth, shading, dry and wet tuning, absorption, permeability, roughness).',\n inputSchema: EMPTY,\n annotations: { title: 'Get the paper', ...READ },\n handler: () => JSON.parse(JSON.stringify(c.document.paper)),\n });\n\n const tuning = {\n type: 'object',\n properties: {\n contrast: { type: 'number', minimum: 0, maximum: 3, description: 'Height contrast around the middle (default 1).' },\n invert: { type: 'boolean', description: 'Swap peaks and valleys.' },\n },\n additionalProperties: false,\n } as const;\n\n add({\n name: 'set_paper',\n title: 'Set the paper',\n description:\n 'Changes the paper under the whole painting: a preset from list_papers and / or its settings. Grain depth decides how much grain-responsive brushes (pencil, pastel, charcoal) skip the valleys; changing it re-renders the paper but not strokes already painted. One undo step. Returns the paper.',\n inputSchema: {\n type: 'object',\n properties: {\n preset: { type: 'string', description: 'Paper id from list_papers (its settings, then the other fields here on top).' },\n color: { ...COLOR, description: 'Paper colour #rrggbb.' },\n depth: { type: 'number', minimum: 0, maximum: 1, description: 'Grain depth 0..1 (0: brushes ignore the grain).' },\n scale: { type: 'number', minimum: 0.25, maximum: 8, description: 'Grain scale: 1 natural, 2 twice as coarse.' },\n seed: { type: 'integer', minimum: 0, description: 'Grain seed: another sheet of the same paper.' },\n pattern: { type: 'string', enum: [...GRAIN_PATTERNS], description: 'Grain pattern.' },\n tiling: { type: 'string', enum: ['repeat', 'mirror'], description: 'How the grain tile repeats (mirror hides seams).' },\n shading: { type: 'number', minimum: 0, maximum: 1, description: 'How much the grain shades the paper colour.' },\n dry: { ...tuning, description: 'Height map tuning for dry media.' },\n wet: { ...tuning, description: 'Height map tuning for wet media (stored for later).' },\n absorption: { type: 'number', minimum: 0, maximum: 1, description: 'Wet media: how fast the paper takes water (stored for later).' },\n permeability: { type: 'number', minimum: 0, maximum: 1, description: 'Wet media: how far water spreads in the paper (stored for later).' },\n roughness: { type: 'number', minimum: 0, maximum: 1, description: 'Wet media: how much the grain catches pigment (stored for later).' },\n name: { type: 'string', minLength: 1, description: 'Display name.' },\n },\n additionalProperties: false,\n },\n annotations: { title: 'Set the paper', ...SET },\n handler: (a) => c.setPaper(a),\n });\n\n // --- Layers ------------------------------------------------------------------\n\n add({\n name: 'list_layers',\n title: 'List layers',\n description:\n 'Lists the layers top first: id, name, type (pixel or group), visibility, opacity, blend, clipping, locks, whether it is active, the painted bounds in document pixels (null when empty), parent and depth.',\n inputSchema: EMPTY,\n annotations: { title: 'List layers', ...READ },\n handler: () => ({ layers: c.listLayers(), activeLayerId: c.document.activeLayerId }),\n });\n\n add({\n name: 'add_layer',\n title: 'Add a layer',\n description: 'Adds an empty pixel layer (or a group) above the active layer, or above aboveId, or at the top of parentId; it becomes the active layer. One undo step. Returns the layer.',\n inputSchema: {\n type: 'object',\n properties: {\n name: { type: 'string', minLength: 1, description: 'Layer name (default \"Layer n\").' },\n type: { type: 'string', enum: ['pixel', 'group'], description: 'pixel (default) or group.' },\n aboveId: { type: 'string', description: 'Put it directly above this layer (default the active layer).' },\n parentId: { type: 'string', description: 'Put it at the top of this group instead.' },\n },\n additionalProperties: false,\n },\n annotations: { title: 'Add a layer', ...WRITE },\n handler: (a) => c.addLayer({ name: a.name, type: a.type, aboveId: a.aboveId, parentId: a.parentId }),\n });\n\n add({\n name: 'update_layer',\n title: 'Change a layer',\n description: 'Changes a layer: name, visibility, opacity, blend mode, clipping to the layer below, locks. One undo step. Returns the layer.',\n inputSchema: {\n type: 'object',\n properties: {\n layerId: { type: 'string', description: 'Layer id from list_layers.' },\n name: { type: 'string', minLength: 1, description: 'New name.' },\n visible: { type: 'boolean', description: 'Show or hide.' },\n opacity: { type: 'number', minimum: 0, maximum: 1, description: 'Layer opacity 0..1.' },\n blend: {\n type: 'string',\n enum: [...BLEND_MODES.map((m) => m.id), 'pass-through'],\n description: 'Blend mode (pass-through for groups only). Painterly modes: watercolor (the layer glazes like a transparent wash), tint (recolours keeping lightness), highlight (adds soft coloured light), shadow (shades with ambient fill); see list_blend_modes.',\n },\n clipped: { type: 'boolean', description: 'Clip to the layer below (paint only shows where it has paint).' },\n locks: {\n type: 'object',\n description: 'Locks to change (others keep their values).',\n properties: {\n pixels: { type: 'boolean', description: 'Refuse painting.' },\n transparency: { type: 'boolean', description: 'Paint only where the layer already has paint.' },\n position: { type: 'boolean', description: 'Refuse moving.' },\n all: { type: 'boolean', description: 'All of the above, plus property changes and removal.' },\n },\n additionalProperties: false,\n },\n },\n required: ['layerId'],\n additionalProperties: false,\n },\n annotations: { title: 'Change a layer', ...SET },\n handler: ({ layerId, ...u }) => c.updateLayer(layerId, u as { blend?: BlendMode }),\n });\n\n add({\n name: 'list_blend_modes',\n title: 'List blend modes',\n description:\n 'Lists every layer and brush blend mode: id, label, group (standard Photoshop modes, pigment, or painterly), what the pigment and painterly modes do, and the standard mode PSD export writes in their place. Changes nothing. Read it before choosing a painterly mode for update_layer or a brush tip.',\n inputSchema: EMPTY,\n annotations: { title: 'List blend modes', ...READ },\n handler: () => ({\n modes: BLEND_MODES.map((m) => ({\n id: m.id,\n label: m.label,\n group: m.painterly ? 'painterly' : m.id === 'pigment' ? 'pigment' : 'standard',\n ...(m.description ? { description: m.description } : {}),\n psd: standardBlendMode(m.id),\n })),\n }),\n });\n\n add({\n name: 'set_active_layer',\n title: 'Choose the active layer',\n description: 'Makes a layer active: strokes, fills and clears without a layerId go to it. Editor state, not an undo step. Returns the layer.',\n inputSchema: { type: 'object', properties: { layerId: { type: 'string', description: 'Layer id from list_layers.' } }, required: ['layerId'], additionalProperties: false },\n annotations: { title: 'Choose the active layer', ...SET },\n handler: ({ layerId }) => {\n c.setActiveLayer(layerId);\n return c.describeLayer(c.getLayer(layerId)!);\n },\n });\n\n add({\n name: 'remove_layer',\n title: 'Remove a layer',\n description: 'Removes a layer (a group with its children). One undo step. Returns the removed id and the new active layer.',\n inputSchema: { type: 'object', properties: { layerId: { type: 'string', description: 'Layer id from list_layers.' } }, required: ['layerId'], additionalProperties: false },\n annotations: { title: 'Remove a layer', ...DESTRUCTIVE },\n handler: ({ layerId }) => c.removeLayer(layerId),\n });\n\n add({\n name: 'duplicate_layer',\n title: 'Duplicate a layer',\n description: 'Copies a layer (a group with its children) directly above it; the copy becomes active. One undo step. Returns the copy.',\n inputSchema: { type: 'object', properties: { layerId: { type: 'string', description: 'Layer id from list_layers.' } }, required: ['layerId'], additionalProperties: false },\n annotations: { title: 'Duplicate a layer', ...WRITE },\n handler: ({ layerId }) => c.duplicateLayer(layerId),\n });\n\n add({\n name: 'move_layer',\n title: 'Reorder a layer',\n description: 'Moves a layer to a position in its group or another (0 is the bottom). One undo step. Returns the layer with its new parent.',\n inputSchema: {\n type: 'object',\n properties: {\n layerId: { type: 'string', description: 'Layer id from list_layers.' },\n index: { type: 'integer', minimum: 0, description: 'New position among its siblings, 0 = bottom.' },\n parentId: { type: ['string', 'null'], description: 'Group id to move into, or null for the top level (default its current parent).' },\n },\n required: ['layerId', 'index'],\n additionalProperties: false,\n },\n annotations: { title: 'Reorder a layer', ...WRITE },\n handler: ({ layerId, index, parentId }) => c.moveLayer(layerId, index, parentId),\n });\n\n add({\n name: 'merge_layer_down',\n title: 'Merge a layer down',\n description: 'Merges a pixel layer into the pixel layer directly below it, which keeps its name, opacity and blend. One undo step. Returns the merged layer.',\n inputSchema: { type: 'object', properties: { layerId: { type: 'string', description: 'The upper layer, from list_layers.' } }, required: ['layerId'], additionalProperties: false },\n annotations: { title: 'Merge a layer down', ...DESTRUCTIVE },\n handler: ({ layerId }) => c.mergeDown(layerId),\n });\n\n add({\n name: 'fill_layer',\n title: 'Fill a layer',\n description:\n 'Fills a whole pixel layer with a colour: a flat block-in, or with grain above 0 a fill that follows the paper grain like pastel or charcoal rubbed across the sheet (pressure decides how far it reaches into the valleys). Good for a ground colour or a tonal layer to paint over. One undo step. Returns the layer id and the filled bounds.',\n inputSchema: {\n type: 'object',\n properties: {\n layerId: LAYER_ID,\n color: { ...COLOR, description: 'Fill colour #rrggbb (default the paint colour).' },\n opacity: { type: 'number', minimum: 0, maximum: 1, description: 'Opacity 0..1 (default 1).' },\n grain: { type: 'number', minimum: 0, maximum: 1, description: 'Paper grain response 0..1 (default 0: flat).' },\n pressure: { type: 'number', minimum: 0, maximum: 1, description: 'With grain: how far into the valleys, 0..1 (default 0.5).' },\n blend: { type: 'string', enum: BLEND_MODES.map((m) => m.id), description: 'Blend mode (default normal; pigment mixes like paint, watercolor glazes; see list_blend_modes).' },\n },\n additionalProperties: false,\n },\n annotations: { title: 'Fill a layer', ...WRITE },\n handler: (a) => c.fillLayer(a),\n });\n\n add({\n name: 'clear_layer',\n title: 'Clear a layer',\n description: 'Removes every pixel of a pixel layer. One undo step. Returns the layer id and the bounds that were cleared (null if it was empty).',\n inputSchema: { type: 'object', properties: { layerId: LAYER_ID }, additionalProperties: false },\n annotations: { title: 'Clear a layer', ...DESTRUCTIVE },\n handler: ({ layerId }) => c.clearLayer(layerId),\n });\n\n // --- Brushes -----------------------------------------------------------------\n\n add({\n name: 'list_brushes',\n title: 'List brushes',\n description:\n 'Lists the brush library: built-in dry media (pencils, pastels, charcoal, airbrush, marker, ink, erasers, blender, smudge, Mixer Brush) and saved user brushes, with id, name, category, engine, size, grain response and rotation mode, plus the active brush id.',\n inputSchema: EMPTY,\n annotations: { title: 'List brushes', ...READ },\n handler: () => {\n const s = c.getState();\n return { activeBrushId: s.brush.id, activeEdited: !s.brush.builtin && Boolean(c.getBrush(s.brush.id)?.builtin), brushes: s.brushes.map(brushSummary) };\n },\n });\n\n add({\n name: 'get_brush',\n title: 'Get a brush',\n description: 'Reads every setting of a brush (tip, grain, pressure smoothing, rotation, dynamics, mixer). Without id, the active brush as edited.',\n inputSchema: { type: 'object', properties: { id: { type: 'string', description: 'Brush id from list_brushes (default the active brush).' } }, additionalProperties: false },\n annotations: { title: 'Get a brush', ...READ },\n handler: ({ id }) => {\n if (id === undefined) return brushToJSON(c.getState().brush);\n const b = c.getBrush(id);\n if (!b) throw new Error(`Unknown brush \"${id}\". Call list_brushes for the ids.`);\n return { ...brushToJSON(b), builtin: Boolean(b.builtin) };\n },\n });\n\n add({\n name: 'set_brush',\n title: 'Set the brush',\n description:\n 'Chooses the active brush (id) and / or changes its settings; strokes without a brush use it. Editor state, not an undo step. Changes stay on the active brush until save_brush stores them. Returns the active brush.',\n inputSchema: { type: 'object', properties: { id: { type: 'string', description: 'Brush id from list_brushes to start from.' }, ...BRUSH_FIELDS }, additionalProperties: false },\n annotations: { title: 'Set the brush', ...SET },\n handler: (a) => brushToJSON(c.setBrush(a)),\n });\n\n add({\n name: 'save_brush',\n title: 'Save a brush',\n description: 'Saves the active brush (with its changes) into the user library under a new or existing user id. Built-in ids are refused. Library state, not an undo step. Returns the saved brush.',\n inputSchema: {\n type: 'object',\n properties: {\n id: { type: 'string', pattern: '^[a-z0-9][a-z0-9-]{0,63}$', description: 'Library id: lowercase letters, digits and dashes.' },\n name: { type: 'string', minLength: 1, maxLength: 80, description: 'Display name (default the brush name).' },\n },\n required: ['id'],\n additionalProperties: false,\n },\n annotations: { title: 'Save a brush', ...SET },\n handler: ({ id, name }) => brushToJSON(c.saveBrush({ id, name })),\n });\n\n add({\n name: 'remove_brush',\n title: 'Remove a saved brush',\n description: 'Removes a user brush from the library (built-in brushes cannot be removed). Library state, not an undo step. Returns the removed id.',\n inputSchema: { type: 'object', properties: { id: { type: 'string', description: 'User brush id from list_brushes.' } }, required: ['id'], additionalProperties: false },\n annotations: { title: 'Remove a saved brush', ...DESTRUCTIVE },\n handler: ({ id }) => {\n c.removeBrush(id);\n return { removed: id };\n },\n });\n\n add({\n name: 'export_brushes',\n title: 'Export brushes',\n description: 'Returns a brush library file (JSON: format pixerate-brushes, version 1, brushes) of the given brushes, or of every user brush. Changes nothing.',\n inputSchema: {\n type: 'object',\n properties: { ids: { type: 'array', items: { type: 'string', description: 'Brush id.' }, description: 'Brush ids from list_brushes (default every user brush).' } },\n additionalProperties: false,\n },\n annotations: { title: 'Export brushes', ...READ },\n handler: ({ ids }) => c.exportBrushes(ids),\n });\n\n add({\n name: 'import_brushes',\n title: 'Import brushes',\n description:\n 'Adds the brushes of a brush library file (as export_brushes returns) to the user library. Taken ids are skipped unless replace is true; built-in ids are always skipped. Library state, not an undo step. Returns the ids added and skipped and any problems.',\n inputSchema: {\n type: 'object',\n properties: {\n library: { type: 'object', description: 'The library file: {format: \"pixerate-brushes\", version: 1, brushes: [...]}.' },\n replace: { type: 'boolean', description: 'Replace user brushes with the same id (default false).' },\n },\n required: ['library'],\n additionalProperties: false,\n },\n annotations: { title: 'Import brushes', ...WRITE },\n handler: ({ library, replace }) => c.importBrushes(library, { replace }),\n });\n\n add({\n name: 'render_brush_thumbnail',\n title: 'Render a brush thumbnail',\n description: 'Renders a brush as a PNG: a test stroke (an S-curve swelling and fading in pressure) on the current paper, so you can see what it does before painting. Changes nothing.',\n inputSchema: {\n type: 'object',\n properties: {\n id: { type: 'string', description: 'Brush id from list_brushes (default the active brush).' },\n width: { type: 'integer', minimum: 16, maximum: 512, description: 'Width in pixels (default 160).' },\n height: { type: 'integer', minimum: 16, maximum: 512, description: 'Height in pixels (default 48).' },\n color: { ...COLOR, description: 'Stroke colour (default the paint colour).' },\n },\n additionalProperties: false,\n },\n annotations: { title: 'Render a brush thumbnail', ...READ },\n handler: ({ id, width, height, color }) => {\n const t = c.brushThumbnail(id ?? c.getState().brush.id, { width, height, color });\n return {\n content: [\n { type: 'image', data: bytesToBase64(encodePng(t.width, t.height, t.data)), mimeType: 'image/png' },\n { type: 'text', text: `Brush ${id ?? c.getState().brush.id} ${t.width}×${t.height}` },\n ],\n };\n },\n });\n\n // --- Colour and the Mixer Brush ----------------------------------------------\n\n add({\n name: 'set_color',\n title: 'Set the paint colour',\n description: 'Sets the paint colour (and optionally the second colour) that strokes and fills use by default. Editor state, not an undo step. Returns both colours.',\n inputSchema: {\n type: 'object',\n properties: { color: { ...COLOR, description: 'Paint colour #rrggbb.' }, secondaryColor: { ...COLOR, description: 'Second colour #rrggbb.' } },\n additionalProperties: false,\n },\n annotations: { title: 'Set the paint colour', ...SET },\n handler: ({ color, secondaryColor }) => {\n if (color !== undefined) c.setColor(color);\n if (secondaryColor !== undefined) c.setSecondaryColor(secondaryColor);\n const s = c.getState();\n return { color: s.color, secondaryColor: s.secondaryColor };\n },\n });\n\n add({\n name: 'pick_color',\n title: 'Pick a colour',\n description: 'Reads the colour at a document pixel: of the painting with its paper, or of one layer (with its alpha). Changes nothing. Returns #rrggbb and alpha 0..1.',\n inputSchema: {\n type: 'object',\n properties: {\n x: { type: 'number', description: 'Document x in pixels.' },\n y: { type: 'number', description: 'Document y in pixels.' },\n layerId: { type: 'string', description: 'Pick from this layer only (default the painting as shown).' },\n },\n required: ['x', 'y'],\n additionalProperties: false,\n },\n annotations: { title: 'Pick a colour', ...READ },\n handler: ({ x, y, layerId }) => c.pickColor(x, y, { layerId }),\n });\n\n add({\n name: 'get_mixer_brush',\n title: 'Get the Mixer Brush load',\n description: \"Reads what the Mixer Brush carries between strokes: reservoir #rrggbb or null, amount 0..1 left, pickup #rrggbb or null. Call before painting with mixer-brush when its loadEachStroke is false.\",\n inputSchema: EMPTY,\n annotations: { title: 'Get the Mixer Brush load', ...READ },\n handler: () => loadResult(c.getState().mixerLoad),\n });\n\n add({\n name: 'load_mixer_brush',\n title: 'Load the Mixer Brush',\n description: 'Fills the Mixer Brush reservoir with a colour (amount 1), keeping what it picked up. Editor state, not an undo step. Returns the load.',\n inputSchema: { type: 'object', properties: { color: { ...COLOR, description: 'Colour #rrggbb (default the paint colour).' } }, additionalProperties: false },\n annotations: { title: 'Load the Mixer Brush', ...SET },\n handler: ({ color }) => loadResult(c.loadMixerBrush(color)),\n });\n\n add({\n name: 'clean_mixer_brush',\n title: 'Clean the Mixer Brush',\n description: 'Empties the Mixer Brush pickup well (and with emptyReservoir its paint too). Editor state, not an undo step. Returns the load.',\n inputSchema: { type: 'object', properties: { emptyReservoir: { type: 'boolean', description: 'Also drop the loaded paint (default false).' } }, additionalProperties: false },\n annotations: { title: 'Clean the Mixer Brush', ...SET },\n handler: ({ emptyReservoir }) => loadResult(c.cleanMixerBrush(emptyReservoir === true)),\n });\n\n // --- Painting ----------------------------------------------------------------\n\n add({\n name: 'paint_stroke',\n title: 'Paint a brush stroke',\n description:\n 'Paints one stroke through points (document pixels, with optional pressure, time, tilt and barrel rotation) on a pixel layer with a library brush or the active one, optionally changed for this stroke. Grain-responsive brushes follow the paper; the mixer engine (mixer-brush, blender, smudge) picks up and moves paint already on the layer. The symmetry guide adds its mirror copies; with a tracing image that samples colours, a stroke without color takes the image colour at its first point. One undo step. Returns the layer id, changed bounds, dab count, the recorded strokeId (for replay_strokes) and, for the mixer, its load after the stroke.',\n inputSchema: {\n type: 'object',\n properties: {\n points: POINTS,\n layerId: LAYER_ID,\n brushId: { type: 'string', description: 'Brush id from list_brushes (default the active brush).' },\n brush: { type: 'object', description: 'Brush changes for this stroke only.', properties: BRUSH_FIELDS, additionalProperties: false },\n color: { ...COLOR, description: 'Paint colour #rrggbb (default the paint colour).' },\n seed: { type: 'integer', minimum: 0, description: 'Jitter seed (default a new one); the same seed and points give the same marks.' },\n snapToPerspective: { type: 'boolean', description: 'Snap the points to the perspective guide, as a pen stroke would (default false).' },\n },\n required: ['points'],\n additionalProperties: false,\n },\n annotations: { title: 'Paint a brush stroke', ...WRITE },\n handler: (a) => {\n const r = c.paintStroke({ points: a.points as PenPoint[], layerId: a.layerId, brushId: a.brushId, brush: a.brush, color: a.color, seed: a.seed, snapToPerspective: a.snapToPerspective });\n return r.mixerLoad ? { ...r, mixerLoad: loadResult(r.mixerLoad) } : r;\n },\n });\n\n add({\n name: 'list_strokes',\n title: 'List recorded strokes',\n description:\n 'Lists the recorded strokes, oldest first (every stroke is kept as data): id, layer, brush id and name, colour, point count, bounds and seed. With ids, also the points. Use the ids with replay_strokes.',\n inputSchema: {\n type: 'object',\n properties: {\n ids: { type: 'array', items: { type: 'string', description: 'Stroke id.' }, description: 'Only these strokes, with their points.' },\n last: { type: 'integer', minimum: 1, maximum: 1000, description: 'Only the most recent n strokes (default 100).' },\n },\n additionalProperties: false,\n },\n annotations: { title: 'List recorded strokes', ...READ },\n handler: ({ ids, last }) => {\n const all = c.getStrokes();\n const picked = ids ? all.filter((s) => ids.includes(s.id)) : all.slice(-(last ?? 100));\n if (ids) for (const id of ids) if (!all.some((s) => s.id === id)) throw new Error(`Unknown stroke \"${id}\". Call list_strokes without ids for the ids.`);\n return {\n total: all.length,\n strokes: picked.map((s) => {\n const xs = s.points.map((p) => p.x);\n const ys = s.points.map((p) => p.y);\n const pad = s.brush.tip.size / 2;\n return {\n id: s.id,\n layerId: s.layerId,\n brushId: s.brush.id,\n brushName: s.brush.name,\n color: s.color,\n points: ids ? s.points : s.points.length,\n seed: s.seed,\n copies: s.copies?.length ?? 0,\n bounds: { x: Math.floor(Math.min(...xs) - pad), y: Math.floor(Math.min(...ys) - pad), width: Math.ceil(Math.max(...xs) - Math.min(...xs) + 2 * pad), height: Math.ceil(Math.max(...ys) - Math.min(...ys) + 2 * pad) },\n };\n }),\n };\n },\n });\n\n add({\n name: 'replay_strokes',\n title: 'Replay strokes, varied',\n description:\n 'Paints recorded strokes again, moved, scaled, rotated, flipped, recoloured, with another brush or on another layer, repeat times (each repeat applies the variation again: a row, a fan, a spiral). Strokes replay exactly (same seed). All of it is one undo step. Returns the new stroke ids, the changed bounds and layer ids.',\n inputSchema: {\n type: 'object',\n properties: {\n strokeIds: { type: 'array', minItems: 1, maxItems: 500, items: { type: 'string', description: 'Stroke id.' }, description: 'Stroke ids from list_strokes.' },\n dx: { type: 'number', description: 'Move right by this many pixels per repeat (default 0).' },\n dy: { type: 'number', description: 'Move down by this many pixels per repeat (default 0).' },\n scale: { type: 'number', exclusiveMinimum: 0, maximum: 20, description: 'Scale per repeat about the origin; brush size scales too (default 1).' },\n rotate: { type: 'number', minimum: -360, maximum: 360, description: 'Rotate per repeat about the origin, degrees clockwise (default 0).' },\n flipX: { type: 'boolean', description: 'Mirror left to right about the origin (default false).' },\n origin: {\n type: 'object',\n description: 'Centre for scale, rotate and flip (default the centre of the strokes).',\n properties: { x: { type: 'number', description: 'Document x.' }, y: { type: 'number', description: 'Document y.' } },\n required: ['x', 'y'],\n additionalProperties: false,\n },\n pressureScale: { type: 'number', minimum: 0, maximum: 4, description: 'Multiply every pressure (default 1).' },\n color: { ...COLOR, description: 'Recolour (default each stroke’s colour).' },\n brushId: { type: 'string', description: 'Replay with this brush from list_brushes (default each stroke’s brush).' },\n layerId: { type: 'string', description: 'Paint on this layer (default each stroke’s layer).' },\n repeat: { type: 'integer', minimum: 1, maximum: 100, description: 'How many copies (default 1).' },\n },\n required: ['strokeIds'],\n additionalProperties: false,\n },\n annotations: { title: 'Replay strokes, varied', ...WRITE },\n handler: (a) => c.replayStrokes(a as Parameters<PaintEditorController['replayStrokes']>[0]),\n });\n\n // --- View, hand, history -------------------------------------------------------\n\n add({\n name: 'set_view',\n title: 'Rotate, mirror or zoom the view',\n description: 'Changes the view only (the pixels never resample): zoom, rotation and mirroring, as an artist turns the paper or checks the drawing in a mirror. Editor state, not an undo step. Returns the view.',\n inputSchema: {\n type: 'object',\n properties: {\n zoom: { type: 'number', minimum: MIN_ZOOM, maximum: MAX_ZOOM, description: 'Screen pixels per document pixel.' },\n rotation: { type: 'number', minimum: -360, maximum: 360, description: 'Rotation in degrees clockwise.' },\n mirror: { type: 'boolean', description: 'Mirror left to right.' },\n reset: { type: 'boolean', description: 'Back to 100 %, no rotation, no mirror, centred (applied first).' },\n },\n additionalProperties: false,\n },\n annotations: { title: 'Rotate, mirror or zoom the view', ...SET },\n handler: ({ reset, ...v }) => {\n if (reset) c.resetView();\n return c.setView(v);\n },\n });\n\n add({\n name: 'set_hand',\n title: 'Set the drawing hand',\n description: 'Says which hand holds the pen; palm rejection ignores touches on that side of the pen. Editor state, not an undo step. Returns the hand.',\n inputSchema: { type: 'object', properties: { hand: { type: 'string', enum: ['right', 'left'], description: 'right or left.' } }, required: ['hand'], additionalProperties: false },\n annotations: { title: 'Set the drawing hand', ...SET },\n handler: ({ hand }) => ({ hand: c.setHand(hand) }),\n });\n\n add({\n name: 'undo_paint',\n title: 'Undo',\n description: 'Undoes the last step (a stroke, a fill, a layer or paper change). Returns the label undone (null when there was nothing) and what can be undone and redone next.',\n inputSchema: EMPTY,\n annotations: { title: 'Undo', ...WRITE },\n handler: () => {\n const undone = c.undo();\n const s = c.getState();\n return { undone, nextUndo: s.undoLabel, nextRedo: s.redoLabel };\n },\n });\n\n add({\n name: 'redo_paint',\n title: 'Redo',\n description: 'Redoes the last undone step. Returns the label redone (null when there was nothing) and what can be undone and redone next.',\n inputSchema: EMPTY,\n annotations: { title: 'Redo', ...WRITE },\n handler: () => {\n const redone = c.redo();\n const s = c.getState();\n return { redone, nextUndo: s.undoLabel, nextRedo: s.redoLabel };\n },\n });\n\n // --- Output ------------------------------------------------------------------\n\n add({\n name: 'render_preview',\n title: 'Render a preview',\n description: 'Renders the painting (with its paper unless paper is false) or some layers as a PNG whose longest side is at most maxSide. Changes nothing. Look at it after each block of work.',\n inputSchema: {\n type: 'object',\n properties: {\n maxSide: { type: 'integer', minimum: 16, maximum: 2048, description: 'Longest side in pixels (default 512).' },\n layerIds: { type: 'array', items: { type: 'string', description: 'Layer id.' }, description: 'Only these layers (default all).' },\n paper: { type: 'boolean', description: 'Include the paper (default true).' },\n },\n additionalProperties: false,\n },\n annotations: { title: 'Render a preview', ...READ },\n handler: ({ maxSide, layerIds, paper }) => {\n if (layerIds) for (const id of layerIds) if (!c.getLayer(id)) throw new Error(`Unknown layer \"${id}\". Call list_layers for the ids.`);\n const p = c.previewPngBase64({ maxSide: maxSide ?? 512, layerIds, paper });\n return { content: [{ type: 'image', data: p.data, mimeType: 'image/png' }, { type: 'text', text: `Preview ${p.width}×${p.height}` }] };\n },\n });\n\n add({\n name: 'export_image',\n title: 'Export the painting',\n description: 'Exports the painting as PNG, JPEG or WebP (base64). JPEG always includes the paper; JPEG and WebP need a browser canvas. Changes nothing. Returns the data, its MIME type and size.',\n inputSchema: {\n type: 'object',\n properties: {\n format: { type: 'string', enum: ['image/png', 'image/jpeg', 'image/webp'], description: 'File type (default image/png).' },\n quality: { type: 'number', minimum: 0, maximum: 1, description: 'JPEG / WebP quality 0..1 (default 0.92).' },\n scale: { type: 'number', exclusiveMinimum: 0, maximum: 1, description: 'Shrink by this factor (default 1).' },\n paper: { type: 'boolean', description: 'Include the paper (default true).' },\n },\n additionalProperties: false,\n },\n annotations: { title: 'Export the painting', ...READ },\n handler: async ({ format, quality, scale, paper }) => {\n const bytes = await c.exportImage({ format, quality, scale, paper });\n return { mimeType: format ?? 'image/png', bytes: bytes.length, data: bytesToBase64(bytes) };\n },\n });\n\n add({\n name: 'export_psd',\n title: 'Export as PSD',\n description:\n 'Writes the painting as an 8-bit RGB PSD (PSB above 30000 px) through the shared PSD writer: every layer and group with its opacity, blend, mask and locks, the paper as a locked \"Paper\" pixel layer at the bottom, and the composite as the merged image. Changes nothing. Returns the file as base64, its size, whether it is a PSB, and warnings (pigment and painterly blend modes have no PSD equivalent: they are written as the nearest standard mode, see list_blend_modes).',\n inputSchema: EMPTY,\n annotations: { title: 'Export as PSD', ...READ },\n handler: () => {\n const r = c.exportPsd();\n return { data: bytesToBase64(r.bytes), bytes: r.bytes.length, psb: r.psb, warnings: r.warnings };\n },\n });\n\n add({\n name: 'save_document',\n title: 'Save the document',\n description: 'Returns the document as JSON (format pixerate-paint, version 1): canvas, paper, layers with PNG data URLs, and the recorded strokes unless strokes is false. Changes nothing.',\n inputSchema: { type: 'object', properties: { strokes: { type: 'boolean', description: 'Include the recorded strokes (default true).' } }, additionalProperties: false },\n annotations: { title: 'Save the document', ...READ },\n handler: ({ strokes }) => c.toJSON({ strokes }),\n });\n\n add({\n name: 'open_document',\n title: 'Open a document',\n description: 'Opens a saved paint document (as save_document returns), replacing the painting and clearing the undo history. Returns the canvas, the layers and anything that could not be read.',\n inputSchema: { type: 'object', properties: { document: { type: 'object', description: 'The saved document JSON.' } }, required: ['document'], additionalProperties: false },\n annotations: { title: 'Open a document', ...DESTRUCTIVE },\n handler: ({ document }) => {\n const problems = c.loadJSON(document);\n const d = c.document;\n return { width: d.canvas.width, height: d.canvas.height, layers: c.listLayers(), strokes: d.strokes.length, problems };\n },\n });\n\n tools.push(...createPaintGuideTools(c));\n tools.push(...createPigmentTools());\n\n return { id: options.id ?? 'paint-editor', namespace: options.namespace, tools };\n}\n","/**\n * Framework-free UI logic shared by the React and Svelte paint editors, so both behave the same:\n *\n * - `PaintGesture` turns pointer events (structurally typed, no DOM import) into strokes (with\n * coalesced samples and a predicted tail), colour picks, pans, view rotation and zoom, with palm\n * rejection while a pen is down.\n * - `PaintCanvasPresenter` keeps a document-sized 2D canvas up to date from the compositor,\n * uploading only the tiles that changed.\n * - Guide overlays as line segments, and the slider tables of the brush and paper panels.\n */\n\nimport { BLEND_MODES, type BlendModeInfo } from '../raster/blend';\nimport { TILE, type RasterRect } from '../raster/surface';\nimport type { PaintEditorController } from './controller';\nimport type { PenPoint } from './engine';\nimport { perspectiveGuideLines, symmetryAxisSegments, type Point2 } from './guides';\nimport { isPalmTouch, pointerToPenPoint, type PointerSample } from './input';\nimport { MAX_ZOOM, MIN_ZOOM, screenToDocument } from './view';\nimport { hsvToRgb, parseHexColor, rgbToHexColor, rgbToHsv, wheelToHue, type ColorWheel } from './color';\n\n/** The Pointer Event fields the gesture reads. */\nexport interface PaintPointerEvent extends PointerSample {\n pointerId: number;\n clientX: number;\n clientY: number;\n button?: number;\n buttons?: number;\n shiftKey?: boolean;\n altKey?: boolean;\n ctrlKey?: boolean;\n metaKey?: boolean;\n getCoalescedEvents?(): PaintPointerEvent[];\n getPredictedEvents?(): PaintPointerEvent[];\n}\n\nexport type PaintTool = 'brush' | 'eyedropper' | 'pan' | 'rotate';\n\nexport const PAINT_TOOLS: ReadonlyArray<{ id: PaintTool; label: string; key: string }> = [\n { id: 'brush', label: 'Brush', key: 'b' },\n { id: 'eyedropper', label: 'Eyedropper', key: 'i' },\n { id: 'pan', label: 'Pan', key: 'h' },\n { id: 'rotate', label: 'Rotate view', key: 'r' },\n];\n\n/** Where the viewport element is on screen and how big it is (CSS pixels). */\nexport interface ViewportBox {\n left: number;\n top: number;\n width: number;\n height: number;\n}\n\ntype Mode = { kind: 'stroke'; pointerId: number } | { kind: 'pan'; pointerId: number; x: number; y: number; pan: Point2 } | { kind: 'rotate'; pointerId: number; angle: number; rotation: number } | null;\n\nexport class PaintGesture {\n tool: PaintTool = 'brush';\n /** The last refusal (a hidden or locked layer), for the editor to show. */\n error: string | null = null;\n /** The predicted tail of the current stroke in document pixels (draw it as a thin preview). */\n predicted: PenPoint[] = [];\n private mode: Mode = null;\n private penAt: Point2 | null = null;\n private penDown = false;\n\n constructor(\n private readonly controller: PaintEditorController,\n private readonly box: () => ViewportBox\n ) {}\n\n private doc(e: { clientX: number; clientY: number }): Point2 {\n const b = this.box();\n const s = this.controller.getState();\n return screenToDocument(s.view, s.document.canvas, b, e.clientX - b.left, e.clientY - b.top);\n }\n\n private pen(e: PaintPointerEvent): PenPoint {\n const p = this.doc(e);\n return pointerToPenPoint(e, p.x, p.y, this.controller.getState().view);\n }\n\n /** Pointer down; returns true when the gesture took the pointer (capture it). */\n down(e: PaintPointerEvent): boolean {\n this.error = null;\n if (this.mode) return false;\n if (e.pointerType === 'pen') {\n this.penDown = true;\n this.penAt = { x: e.clientX, y: e.clientY };\n } else if (e.pointerType === 'touch' && (this.penDown || isPalmTouch({ x: e.clientX, y: e.clientY }, this.penAt, this.controller.getState().hand))) {\n return false;\n }\n const middle = e.button === 1;\n const tool = middle ? 'pan' : this.tool;\n if (tool === 'pan') {\n this.mode = { kind: 'pan', pointerId: e.pointerId, x: e.clientX, y: e.clientY, pan: { ...this.controller.getState().view.pan } };\n return true;\n }\n if (tool === 'rotate') {\n const b = this.box();\n this.mode = { kind: 'rotate', pointerId: e.pointerId, angle: Math.atan2(e.clientY - b.top - b.height / 2, e.clientX - b.left - b.width / 2), rotation: this.controller.getState().view.rotation };\n return true;\n }\n if (tool === 'eyedropper' || e.altKey) {\n this.pick(e);\n return false;\n }\n try {\n const p = this.pen(e);\n const session = this.controller.beginStroke({ start: p });\n session.push([p]);\n this.mode = { kind: 'stroke', pointerId: e.pointerId };\n return true;\n } catch (err) {\n this.error = err instanceof Error ? err.message : String(err);\n return false;\n }\n }\n\n private pick(e: PaintPointerEvent): void {\n const p = this.doc(e);\n const { width, height } = this.controller.document.canvas;\n if (p.x < 0 || p.y < 0 || p.x >= width || p.y >= height) return;\n this.controller.setColor(this.controller.pickColor(p.x, p.y).color);\n }\n\n move(e: PaintPointerEvent): void {\n if (e.pointerType === 'pen') this.penAt = { x: e.clientX, y: e.clientY };\n const m = this.mode;\n if (!m || m.pointerId !== e.pointerId) return;\n if (m.kind === 'pan') {\n this.controller.setView({ pan: { x: m.pan.x + e.clientX - m.x, y: m.pan.y + e.clientY - m.y } });\n return;\n }\n if (m.kind === 'rotate') {\n const b = this.box();\n const a = Math.atan2(e.clientY - b.top - b.height / 2, e.clientX - b.left - b.width / 2);\n let r = m.rotation + ((a - m.angle) * 180) / Math.PI;\n if (e.shiftKey) r = Math.round(r / 15) * 15;\n this.controller.setView({ rotation: r });\n return;\n }\n const session = this.controller.activeStroke;\n if (!session) return;\n const events = typeof e.getCoalescedEvents === 'function' ? e.getCoalescedEvents() : [];\n session.push((events.length ? events : [e]).map((ev) => this.pen(ev)));\n const predicted = typeof e.getPredictedEvents === 'function' ? e.getPredictedEvents() : [];\n this.predicted = predicted.map((ev) => this.pen(ev));\n }\n\n up(e: PaintPointerEvent): void {\n if (e.pointerType === 'pen') this.penDown = false;\n const m = this.mode;\n if (!m || m.pointerId !== e.pointerId) return;\n this.mode = null;\n this.predicted = [];\n if (m.kind === 'stroke') this.controller.activeStroke?.end();\n }\n\n cancel(): void {\n this.penDown = false;\n this.predicted = [];\n if (this.mode?.kind === 'stroke') this.controller.activeStroke?.cancel();\n this.mode = null;\n }\n\n get active(): boolean {\n return this.mode !== null;\n }\n\n /** Wheel: zoom about the pointer (Ctrl / pinch or plain wheel), Shift+wheel rotates the view. */\n wheel(e: { clientX: number; clientY: number; deltaY: number; shiftKey?: boolean }): void {\n const s = this.controller.getState();\n if (e.shiftKey) {\n this.controller.setView({ rotation: s.view.rotation + (e.deltaY > 0 ? 5 : -5) });\n return;\n }\n const b = this.box();\n const zoom = Math.min(MAX_ZOOM, Math.max(MIN_ZOOM, s.view.zoom * Math.exp(-e.deltaY * 0.0015)));\n const k = zoom / s.view.zoom;\n // Keep the point under the pointer still: the pan scales about it.\n const px = e.clientX - b.left - b.width / 2;\n const py = e.clientY - b.top - b.height / 2;\n this.controller.setView({ zoom, pan: { x: px - (px - s.view.pan.x) * k, y: py - (py - s.view.pan.y) * k } });\n }\n}\n\n/** Keyboard shortcuts shared by both editors; returns true when it handled the key. */\nexport function handlePaintShortcut(\n controller: PaintEditorController,\n gesture: PaintGesture,\n e: { key: string; ctrlKey?: boolean; metaKey?: boolean; shiftKey?: boolean; target?: unknown }\n): boolean {\n const mod = e.ctrlKey || e.metaKey;\n const key = e.key.toLowerCase();\n if (mod && key === 'z') {\n if (controller.getState().stroking) return true;\n if (e.shiftKey) controller.redo();\n else controller.undo();\n return true;\n }\n if (mod && key === 'y') {\n controller.redo();\n return true;\n }\n if (mod) return false;\n const tool = PAINT_TOOLS.find((t) => t.key === key);\n if (tool) {\n gesture.tool = tool.id;\n return true;\n }\n const brush = controller.getState().brush;\n if (key === '[' || key === ']') {\n const step = Math.max(1, Math.round(brush.tip.size * 0.15));\n controller.setBrush({ tip: { size: Math.max(1, brush.tip.size + (key === ']' ? step : -step)) } });\n return true;\n }\n if (key === 'x') {\n controller.swapColors();\n return true;\n }\n if (key === 'm') {\n controller.setView({ mirror: !controller.getState().view.mirror });\n return true;\n }\n if (key === 'escape') {\n controller.resetView();\n return true;\n }\n return false;\n}\n\n/** The 2D context methods the presenter uses (a `CanvasRenderingContext2D`). */\nexport interface Paint2DContext {\n createImageData(width: number, height: number): { data: Uint8ClampedArray };\n putImageData(image: never, dx: number, dy: number, sx?: number, sy?: number, sw?: number, sh?: number): void;\n}\n\n/** Keeps a document-sized canvas in step with the controller, tile by tile. */\nexport class PaintCanvasPresenter {\n private readonly uploaded = new Map<string, Uint8ClampedArray>();\n private scratch: { data: Uint8ClampedArray } | null = null;\n private size = '';\n\n constructor(private readonly controller: PaintEditorController) {}\n\n /** Draws what changed into `ctx` (a canvas the size of the document); returns the tiles drawn. */\n render(ctx: Paint2DContext): number {\n const { width, height } = this.controller.document.canvas;\n const size = `${width}x${height}`;\n let dirty = this.controller.takeDirty();\n if (size !== this.size) {\n this.size = size;\n this.uploaded.clear();\n dirty = 'all';\n }\n let drawn = 0;\n const rect: RasterRect = { x: 0, y: 0, width, height };\n this.controller.compositeTiles(rect, (tx, ty, data) => {\n const key = `${tx},${ty}`;\n if (this.uploaded.get(key) === data) return;\n this.uploaded.set(key, data);\n if (!this.scratch) this.scratch = ctx.createImageData(TILE, TILE);\n this.scratch.data.set(data);\n const ox = tx * TILE;\n const oy = ty * TILE;\n ctx.putImageData(this.scratch as never, ox, oy, 0, 0, Math.min(TILE, width - ox), Math.min(TILE, height - oy));\n drawn++;\n }, { dirty });\n return drawn;\n }\n}\n\n/** Lines to draw over the canvas for the guides, in document pixels, with a style key. */\nexport function guideOverlay(controller: PaintEditorController): Array<{ from: Point2; to: Point2; kind: 'symmetry' | 'perspective' | 'snap' }> {\n const s = controller.getState();\n const size = s.document.canvas;\n const out: Array<{ from: Point2; to: Point2; kind: 'symmetry' | 'perspective' | 'snap' }> = [];\n for (const [from, to] of symmetryAxisSegments(s.guides.symmetry, size)) out.push({ from, to, kind: 'symmetry' });\n if (s.guides.perspective.enabled) for (const [from, to] of perspectiveGuideLines(s.guides.perspective, size, 16)) out.push({ from, to, kind: 'perspective' });\n return out;\n}\n\n/** One slider of a panel: a path into the brush (or paper) settings. */\nexport interface SliderControl {\n path: string;\n label: string;\n min: number;\n max: number;\n step: number;\n}\n\nexport const BRUSH_SLIDERS: readonly SliderControl[] = [\n { path: 'tip.size', label: 'Size', min: 1, max: 400, step: 1 },\n { path: 'tip.opacity', label: 'Opacity', min: 0, max: 1, step: 0.01 },\n { path: 'tip.flow', label: 'Flow', min: 0, max: 1, step: 0.01 },\n { path: 'tip.hardness', label: 'Hardness', min: 0, max: 1, step: 0.01 },\n { path: 'tip.spacing', label: 'Spacing', min: 0.01, max: 1, step: 0.01 },\n { path: 'tip.roundness', label: 'Roundness', min: 0.05, max: 1, step: 0.01 },\n { path: 'tip.angle', label: 'Angle', min: -180, max: 180, step: 1 },\n { path: 'grain', label: 'Grain', min: 0, max: 1, step: 0.01 },\n { path: 'tip.smoothing', label: 'Smoothing', min: 0, max: 0.95, step: 0.01 },\n { path: 'pressureSmoothing', label: 'Pressure smoothing', min: 0, max: 0.95, step: 0.01 },\n { path: 'dynamics.minSize', label: 'Min size', min: 0, max: 1, step: 0.01 },\n { path: 'dynamics.tiltSize', label: 'Tilt size', min: 0, max: 1, step: 0.01 },\n { path: 'dynamics.velocitySize', label: 'Speed size', min: -1, max: 1, step: 0.01 },\n];\n\nexport const PAPER_SLIDERS: readonly SliderControl[] = [\n { path: 'depth', label: 'Grain depth', min: 0, max: 1, step: 0.01 },\n { path: 'scale', label: 'Grain scale', min: 0.25, max: 8, step: 0.05 },\n { path: 'shading', label: 'Shading', min: 0, max: 1, step: 0.01 },\n { path: 'dry.contrast', label: 'Contrast', min: 0, max: 3, step: 0.05 },\n { path: 'absorption', label: 'Absorption', min: 0, max: 1, step: 0.01 },\n { path: 'permeability', label: 'Permeability', min: 0, max: 1, step: 0.01 },\n { path: 'roughness', label: 'Roughness', min: 0, max: 1, step: 0.01 },\n];\n\n/** Reads `a.b` from an object. */\nexport function readPath(obj: unknown, path: string): number {\n let v: unknown = obj;\n for (const k of path.split('.')) v = (v as Record<string, unknown>)?.[k];\n return typeof v === 'number' ? v : 0;\n}\n\n/** `{a: {b: value}}` for `a.b`, keeping the rest of `obj`'s `a`. */\nexport function patchPath(obj: Record<string, unknown>, path: string, value: number): Record<string, unknown> {\n const [head, ...rest] = path.split('.');\n if (!rest.length) return { [head]: value };\n return { [head]: { ...(obj[head] as Record<string, unknown>), ...patchPath((obj[head] as Record<string, unknown>) ?? {}, rest.join('.'), value) } };\n}\n\n/** The point on a colour wheel of `radius` (centre 0, 0) for a wheel angle in degrees, red at the top. */\nexport function wheelPoint(angle: number, radius: number): Point2 {\n const a = ((angle - 90) * Math.PI) / 180;\n return { x: Math.cos(a) * radius, y: Math.sin(a) * radius };\n}\n\n/** The wheel angle (degrees, red at the top, clockwise) of a point relative to the wheel centre. */\nexport function wheelAngle(x: number, y: number): number {\n return ((Math.atan2(y, x) * 180) / Math.PI + 90 + 360) % 360;\n}\n\n/**\n * A hue ring for a colour wheel, `size × size` RGBA: hues at full saturation and value between\n * `inner` and 1 of the radius, red at the top, laid out on the RYB or RGB wheel.\n */\nexport function renderColorWheel(size: number, wheel: ColorWheel, inner = 0.64): { width: number; height: number; data: Uint8ClampedArray } {\n const data = new Uint8ClampedArray(size * size * 4);\n const r = size / 2;\n for (let y = 0; y < size; y++) {\n for (let x = 0; x < size; x++) {\n const dx = x + 0.5 - r;\n const dy = y + 0.5 - r;\n const d = Math.hypot(dx, dy) / r;\n if (d > 1 || d < inner) continue;\n const [cr, cg, cb] = hsvToRgb(wheelToHue(wheelAngle(dx, dy), wheel), 1, 1);\n const i = (y * size + x) * 4;\n // Anti-aliased edges.\n const edge = Math.min(1, (1 - d) * r, (d - inner) * r);\n data[i] = cr;\n data[i + 1] = cg;\n data[i + 2] = cb;\n data[i + 3] = Math.round(255 * Math.max(0, edge));\n }\n }\n return { width: size, height: size, data };\n}\n\n/** The colour for a click on the wheel ring at (dx, dy) from its centre, keeping `color`'s saturation and value. */\nexport function wheelPick(dx: number, dy: number, wheel: ColorWheel, color: string): string {\n const [r, g, b] = parseHexColor(color);\n const { s, v } = rgbToHsv(r, g, b);\n const [nr, ng, nb] = hsvToRgb(wheelToHue(wheelAngle(dx, dy), wheel), s || 1, v || 1);\n return rgbToHexColor(nr, ng, nb);\n}\n\n/** A group of the blend menu: the Photoshop modes, then pigment and the painterly modes. */\nexport interface BlendMenuGroup {\n label: string;\n modes: readonly BlendModeInfo[];\n}\n\n/**\n * The layer and brush blend menus as groups: the 26 standard modes, then the paint modes\n * (`pigment` and the painterly `watercolor`, `tint`, `highlight`, `shadow`), each with its\n * description as a tooltip. Both bindings render this as `<optgroup>`s.\n */\nexport const BLEND_MENU_GROUPS: readonly BlendMenuGroup[] = [\n { label: 'Standard', modes: BLEND_MODES.filter((m) => !m.painterly && m.id !== 'pigment') },\n { label: 'Paint', modes: BLEND_MODES.filter((m) => m.painterly || m.id === 'pigment') },\n];\n"],"mappings":"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","names":["unit","finite","d","HEX","HEX","layers","READ","WRITE","SET","DESTRUCTIVE","EMPTY","COLOR","tuning"]}
|
|
1
|
+
{"version":3,"sources":["../../src/paint-editor/noise.ts","../../src/paint-editor/paper.ts","../../src/paint-editor/document.ts","../../src/paint-editor/brushes.ts","../../src/paint-editor/engine.ts","../../src/paint-editor/stroke.ts","../../src/paint-editor/strokes.ts","../../src/paint-editor/render.ts","../../src/paint-editor/serialize.ts","../../src/paint-editor/view.ts","../../src/paint-editor/input.ts","../../src/paint-editor/encode.ts","../../src/paint-editor/thumbnails.ts","../../src/paint-editor/guides.ts","../../src/paint-editor/color.ts","../../src/paint-editor/mixing-pad.ts","../../src/paint-editor/controller.ts","../../src/paint-editor/presence.ts","../../src/paint-editor/guide-tools.ts","../../src/paint-editor/tools.ts","../../src/paint-editor/ui.ts"],"sourcesContent":["// Portions ported from photocraft/crates/paint/src/procedural.rs and rng.rs (MIT OR Apache-2.0, © ArtCraft Team and contributors). See THIRD_PARTY_NOTICES.md.\n\n/**\n * Seeded, deterministic noise for paper grain and brush jitter (photocraft's counter-based\n * randomness and tileable value noise, on 32-bit integer hashes instead of 64-bit ones so it runs\n * fast in JavaScript). Every value is a pure function of its inputs, so a paper or a stroke\n * regenerates identically on every machine.\n */\n\n/** A 32-bit finaliser (murmur3's `fmix32`). */\nexport function mix32(h: number): number {\n h ^= h >>> 16;\n h = Math.imul(h, 0x85ebca6b);\n h ^= h >>> 13;\n h = Math.imul(h, 0xc2b2ae35);\n h ^= h >>> 16;\n return h >>> 0;\n}\n\n/** Hash of integer coordinates and a salt to [0, 1). */\nexport function hash2(x: number, y: number, salt: number): number {\n const h = mix32((Math.imul(x | 0, 0x27d4eb2d) ^ mix32((y | 0) + Math.imul(salt | 0, 0x165667b1))) >>> 0);\n return h / 4294967296;\n}\n\n/** Uniform in [0, 1) from a seed, an index and a stream (one stream per random quantity). */\nexport function rand01(seed: number, index: number, stream: number): number {\n return hash2(index, stream, seed);\n}\n\n/** Uniform in [-1, 1). */\nexport function randSigned(seed: number, index: number, stream: number): number {\n return rand01(seed, index, stream) * 2 - 1;\n}\n\n/** A seed from a string (FNV-1a, then mixed). */\nexport function seedFromString(text: string): number {\n let h = 0x811c9dc5;\n for (let i = 0; i < text.length; i++) {\n h ^= text.charCodeAt(i);\n h = Math.imul(h, 0x01000193);\n }\n return mix32(h >>> 0);\n}\n\nconst smooth = (t: number) => t * t * (3 - 2 * t);\n\n/** A periodic lattice of `px × py` random values, sampled with smooth interpolation. */\nclass Lattice {\n readonly values: Float32Array;\n constructor(readonly px: number, readonly py: number, salt: number) {\n this.values = new Float32Array(px * py);\n for (let j = 0; j < py; j++) for (let i = 0; i < px; i++) this.values[j * px + i] = hash2(i, j, salt);\n }\n\n /** Value noise at (x, y) in lattice cells; wraps every `px` / `py` cells. */\n at(x: number, y: number): number {\n const { px, py } = this;\n const x0 = Math.floor(x);\n const y0 = Math.floor(y);\n const tx = smooth(x - x0);\n const ty = smooth(y - y0);\n const i0 = ((x0 % px) + px) % px;\n const j0 = ((y0 % py) + py) % py;\n const i1 = (i0 + 1) % px;\n const j1 = (j0 + 1) % py;\n const v = this.values;\n const a = v[j0 * px + i0] + (v[j0 * px + i1] - v[j0 * px + i0]) * tx;\n const b = v[j1 * px + i0] + (v[j1 * px + i1] - v[j1 * px + i0]) * tx;\n return a + (b - a) * ty;\n }\n}\n\n/**\n * Tileable fractal value noise in 0..1 over a `size`-pixel square: `cellsX × cellsY` lattice cells\n * at the base octave (unequal counts give fibres and streaks), doubling per octave, so the result\n * repeats exactly every `size` pixels.\n */\nexport class TileableNoise {\n private readonly octaves: Lattice[] = [];\n\n constructor(readonly size: number, cellsX: number, cellsY: number, octaves: number, salt: number) {\n let cx = Math.max(1, Math.round(cellsX));\n let cy = Math.max(1, Math.round(cellsY));\n for (let o = 0; o < octaves; o++) {\n this.octaves.push(new Lattice(cx, cy, (salt + o * 7919) | 0));\n cx *= 2;\n cy *= 2;\n }\n }\n\n /** Fractal noise at pixel (x, y). */\n at(x: number, y: number): number {\n let sum = 0;\n let amp = 1;\n let norm = 0;\n const u = x / this.size;\n const v = y / this.size;\n for (const l of this.octaves) {\n sum += l.at(u * l.px, v * l.py) * amp;\n norm += amp;\n amp *= 0.5;\n }\n return norm > 0 ? sum / norm : 0.5;\n }\n}\n","/**\n * Paper: a generated grain height map (0 = valley, 1 = peak) that tiles across the canvas, a paper\n * colour, grain depth, and the three properties wet media will read later (absorption,\n * permeability, roughness). Dry media catch the peaks: a light stroke only marks the high grain, a\n * firm one fills the valleys too. Everything is generated from a pattern and a seed, so a paper is\n * a few numbers in the document, never a bitmap, and no third-party texture is bundled.\n */\n\nimport { hash2, TileableNoise } from './noise';\n\n/** Grain generators. Each is our own procedural pattern (no scanned textures). */\nexport type GrainPattern =\n | 'smooth'\n | 'cold-pressed'\n | 'hot-pressed'\n | 'rough'\n | 'vellum'\n | 'laid'\n | 'ingres'\n | 'sanded'\n | 'canvas'\n | 'linen'\n | 'gesso';\n\nexport const GRAIN_PATTERNS: readonly GrainPattern[] = ['smooth', 'cold-pressed', 'hot-pressed', 'rough', 'vellum', 'laid', 'ingres', 'sanded', 'canvas', 'linen', 'gesso'];\n\n/** Paper families, as a library groups them. */\nexport type PaperFamily = 'watercolor' | 'drawing' | 'pastel' | 'canvas' | 'panel' | 'smooth';\n\nexport const PAPER_FAMILIES: readonly PaperFamily[] = ['watercolor', 'drawing', 'pastel', 'canvas', 'panel', 'smooth'];\n\n/** How a height map is tuned for one kind of media. */\nexport interface GrainTuning {\n /** Height contrast around the middle, 0..3 (default 1). */\n contrast: number;\n /** Swap peaks and valleys (default false). */\n invert: boolean;\n}\n\nexport type PaperTiling = 'repeat' | 'mirror';\n\nexport interface PaperSettings {\n /** The library preset this paper started from (`custom` when it matches none). */\n preset: string;\n name: string;\n family: PaperFamily;\n pattern: GrainPattern;\n /** Grain seed: another seed gives another sheet of the same paper. */\n seed: number;\n /** Paper colour #rrggbb. */\n color: string;\n /** Grain scale: 1 is the pattern's natural size, 2 twice as coarse (0.25..8). */\n scale: number;\n /** How the grain tile repeats: `repeat` or `mirror` (alternate tiles flipped, so seams vanish). */\n tiling: PaperTiling;\n /** Grain depth 0..1: how much grain-responsive dry media skip the valleys (0: none). */\n depth: number;\n /** How much the grain shades the paper colour on screen and in exports, 0..1. */\n shading: number;\n /** The height map as dry media read it. */\n dry: GrainTuning;\n /** The height map as wet media will read it (stored now; wet media is a later phase). */\n wet: GrainTuning;\n /** Wet media: how fast the paper takes up water, 0..1. */\n absorption: number;\n /** Wet media: how far water spreads inside the paper, 0..1. */\n permeability: number;\n /** Wet media: how much the grain catches pigment, 0..1. */\n roughness: number;\n}\n\n/** Side of the generated grain tile in pixels (at scale 1). */\nexport const GRAIN_TILE = 256;\n\nconst unit = (v: unknown, d: number) => (typeof v === 'number' && Number.isFinite(v) ? Math.min(1, Math.max(0, v)) : d);\nconst clampNum = (v: unknown, lo: number, hi: number, d: number) => (typeof v === 'number' && Number.isFinite(v) ? Math.min(hi, Math.max(lo, v)) : d);\nconst HEX = /^#[0-9a-f]{6}$/i;\n\ntype PaperPreset = PaperSettings;\n\nconst tuning = (contrast = 1, invert = false): GrainTuning => ({ contrast, invert });\n\nfunction preset(\n id: string,\n name: string,\n family: PaperFamily,\n pattern: GrainPattern,\n color: string,\n o: { depth: number; absorption: number; permeability: number; roughness: number; scale?: number; seed?: number; shading?: number; contrast?: number }\n): PaperPreset {\n return {\n preset: id,\n name,\n family,\n pattern,\n seed: o.seed ?? 1,\n color,\n scale: o.scale ?? 1,\n tiling: 'mirror',\n depth: o.depth,\n shading: o.shading ?? 0.5,\n dry: tuning(o.contrast ?? 1),\n wet: tuning(1),\n absorption: o.absorption,\n permeability: o.permeability,\n roughness: o.roughness,\n };\n}\n\n/** The built-in paper library: generated papers in families. */\nexport const PAPER_LIBRARY: readonly PaperPreset[] = [\n preset('cold-pressed', 'Cold pressed watercolour', 'watercolor', 'cold-pressed', '#f7f3ea', { depth: 0.5, absorption: 0.7, permeability: 0.5, roughness: 0.6 }),\n preset('hot-pressed', 'Hot pressed watercolour', 'watercolor', 'hot-pressed', '#f8f6ef', { depth: 0.25, absorption: 0.55, permeability: 0.4, roughness: 0.25 }),\n preset('rough-watercolor', 'Rough watercolour', 'watercolor', 'rough', '#f5f0e4', { depth: 0.75, absorption: 0.8, permeability: 0.6, roughness: 0.85 }),\n preset('cartridge', 'Cartridge', 'drawing', 'vellum', '#fbfaf6', { depth: 0.3, absorption: 0.4, permeability: 0.3, roughness: 0.35 }),\n preset('laid', 'Laid paper', 'drawing', 'laid', '#f3ecdc', { depth: 0.45, absorption: 0.45, permeability: 0.35, roughness: 0.45 }),\n preset('ingres', 'Charcoal paper', 'drawing', 'ingres', '#ede6d6', { depth: 0.6, absorption: 0.4, permeability: 0.3, roughness: 0.65 }),\n preset('sanded-pastel', 'Sanded pastel paper', 'pastel', 'sanded', '#d8cfc0', { depth: 0.7, absorption: 0.3, permeability: 0.2, roughness: 0.9, shading: 0.35 }),\n preset('pastel-card', 'Grey pastel card', 'pastel', 'sanded', '#9c978e', { depth: 0.55, absorption: 0.3, permeability: 0.2, roughness: 0.75, scale: 1.5, shading: 0.3 }),\n preset('cotton-canvas', 'Cotton canvas', 'canvas', 'canvas', '#efe9dc', { depth: 0.55, absorption: 0.35, permeability: 0.25, roughness: 0.6 }),\n preset('fine-linen', 'Fine linen', 'canvas', 'linen', '#e9e2d2', { depth: 0.45, absorption: 0.3, permeability: 0.25, roughness: 0.5 }),\n preset('gesso', 'Gesso panel', 'panel', 'gesso', '#f6f4ef', { depth: 0.35, absorption: 0.2, permeability: 0.15, roughness: 0.4 }),\n preset('smooth', 'Smooth bristol', 'smooth', 'smooth', '#ffffff', { depth: 0, absorption: 0.3, permeability: 0.2, roughness: 0.05, shading: 0 }),\n];\n\nexport const DEFAULT_PAPER: Readonly<PaperSettings> = PAPER_LIBRARY[0];\n\n/** A paper from the library by id, or `undefined`. */\nexport function paperPreset(id: string): PaperSettings | undefined {\n const p = PAPER_LIBRARY.find((x) => x.preset === id);\n return p ? clonePaper(p) : undefined;\n}\n\nexport function clonePaper(p: PaperSettings): PaperSettings {\n return { ...p, dry: { ...p.dry }, wet: { ...p.wet } };\n}\n\nfunction readTuning(raw: unknown, d: GrainTuning): GrainTuning {\n const r = raw && typeof raw === 'object' ? (raw as Record<string, unknown>) : {};\n return { contrast: clampNum(r.contrast, 0, 3, d.contrast), invert: typeof r.invert === 'boolean' ? r.invert : d.invert };\n}\n\n/**\n * A paper with every field in range. Missing fields come from `base` (default: the library preset\n * named by `raw.preset`, else cold pressed).\n */\nexport function normalizePaper(raw: Partial<PaperSettings> | Record<string, unknown> = {}, base?: PaperSettings): PaperSettings {\n const r = raw as Record<string, unknown>;\n const b = base ?? (typeof r.preset === 'string' ? paperPreset(r.preset) : undefined) ?? clonePaper(DEFAULT_PAPER);\n return {\n preset: typeof r.preset === 'string' && r.preset ? r.preset : b.preset,\n name: typeof r.name === 'string' && r.name.trim() ? r.name.trim() : b.name,\n family: PAPER_FAMILIES.includes(r.family as PaperFamily) ? (r.family as PaperFamily) : b.family,\n pattern: GRAIN_PATTERNS.includes(r.pattern as GrainPattern) ? (r.pattern as GrainPattern) : b.pattern,\n seed: typeof r.seed === 'number' && Number.isFinite(r.seed) ? Math.round(Math.abs(r.seed)) % 2147483647 : b.seed,\n color: typeof r.color === 'string' && HEX.test(r.color) ? r.color.toLowerCase() : b.color,\n scale: clampNum(r.scale, 0.25, 8, b.scale),\n tiling: r.tiling === 'repeat' || r.tiling === 'mirror' ? r.tiling : b.tiling,\n depth: unit(r.depth, b.depth),\n shading: unit(r.shading, b.shading),\n dry: readTuning(r.dry, b.dry),\n wet: readTuning(r.wet, b.wet),\n absorption: unit(r.absorption, b.absorption),\n permeability: unit(r.permeability, b.permeability),\n roughness: unit(r.roughness, b.roughness),\n };\n}\n\n// ---------------------------------------------------------------------------\n// Height maps\n// ---------------------------------------------------------------------------\n\nconst clamp01 = (v: number) => (v < 0 ? 0 : v > 1 ? 1 : v);\n\n/** One pattern's raw height (0..1) at pixel (x, y) of a `n`-pixel tile. */\nfunction patternHeights(pattern: GrainPattern, n: number, seed: number): Float32Array {\n const out = new Float32Array(n * n);\n const salt = Math.imul(seed | 0, 0x9e3779b1) + 17;\n if (pattern === 'smooth') return out.fill(1);\n const noise = (cx: number, cy: number, oct: number, s = 0) => new TileableNoise(n, cx, cy, oct, salt + s);\n const k = n / GRAIN_TILE;\n switch (pattern) {\n case 'cold-pressed': {\n const base = noise(20 * k, 20 * k, 4);\n const fine = noise(64 * k, 64 * k, 2, 3);\n for (let y = 0; y < n; y++)\n for (let x = 0; x < n; x++) out[y * n + x] = clamp01((base.at(x, y) - 0.5) * 1.8 + 0.5 + (fine.at(x, y) - 0.5) * 0.5 + (hash2(x, y, salt) - 0.5) * 0.12);\n break;\n }\n case 'hot-pressed': {\n const base = noise(40 * k, 40 * k, 3);\n for (let y = 0; y < n; y++) for (let x = 0; x < n; x++) out[y * n + x] = clamp01((base.at(x, y) - 0.5) * 1.1 + 0.6 + (hash2(x, y, salt) - 0.5) * 0.08);\n break;\n }\n case 'rough': {\n const base = noise(10 * k, 10 * k, 5);\n const blot = noise(28 * k, 28 * k, 2, 5);\n for (let y = 0; y < n; y++)\n for (let x = 0; x < n; x++) out[y * n + x] = clamp01((base.at(x, y) - 0.5) * 2.4 + 0.5 + (blot.at(x, y) - 0.5) * 0.7 + (hash2(x, y, salt) - 0.5) * 0.15);\n break;\n }\n case 'vellum': {\n const base = noise(40 * k, 40 * k, 3);\n for (let y = 0; y < n; y++) for (let x = 0; x < n; x++) out[y * n + x] = clamp01((base.at(x, y) - 0.5) * 1.6 + 0.55 + (hash2(x, y, salt) - 0.5) * 0.2);\n break;\n }\n case 'laid': {\n // Fine laid lines across, chain lines down every eighth of the tile, a little pulp noise.\n const pulp = noise(32 * k, 32 * k, 3);\n const chain = n / 8;\n for (let y = 0; y < n; y++) {\n const laid = 0.5 + 0.5 * Math.cos((2 * Math.PI * y) / 4);\n for (let x = 0; x < n; x++) {\n const c = Math.abs(((x + 0.5) % chain) - chain / 2) / (chain / 2);\n const chainLine = c > 0.94 ? -0.35 : 0;\n out[y * n + x] = clamp01(0.3 + 0.5 * laid + chainLine + (pulp.at(x, y) - 0.5) * 0.6);\n }\n }\n break;\n }\n case 'ingres': {\n // Long vertical fibres with grit.\n const fibres = noise(64 * k, 12 * k, 3);\n const base = noise(16 * k, 16 * k, 3, 7);\n for (let y = 0; y < n; y++)\n for (let x = 0; x < n; x++) {\n const g = hash2(x, y, salt ^ 0x55);\n out[y * n + x] = clamp01((fibres.at(x, y) - 0.5) * 1.5 + (base.at(x, y) - 0.5) * 0.7 + 0.55 + (g < 0.1 ? -0.3 : 0));\n }\n break;\n }\n case 'sanded': {\n // Fine grit: high-frequency noise and sharp single-pixel pits.\n const grit = noise(96 * k, 96 * k, 2);\n for (let y = 0; y < n; y++)\n for (let x = 0; x < n; x++) {\n const h = hash2(x, y, salt);\n out[y * n + x] = clamp01((grit.at(x, y) - 0.5) * 2.4 + 0.5 + (h - 0.5) * 0.7);\n }\n break;\n }\n case 'canvas':\n case 'linen': {\n // Over / under weave; linen has finer, irregular threads.\n const period = (pattern === 'canvas' ? 8 : 5) * k;\n // An even thread count keeps the over / under alternation seamless across the tile edge.\n const threads = Math.max(2, 2 * Math.round(n / period / 2));\n const p = n / threads;\n const slub = noise(threads, threads, 2, 11);\n for (let y = 0; y < n; y++)\n for (let x = 0; x < n; x++) {\n const fx = (x + 0.5) / p;\n const fy = (y + 0.5) / p;\n const cx = Math.floor(fx);\n const cy = Math.floor(fy);\n const warp = Math.sin(Math.PI * (fx - cx));\n const weft = Math.sin(Math.PI * (fy - cy));\n const top = (cx + cy) % 2 === 0 ? warp : weft;\n const irregular = pattern === 'linen' ? (slub.at(x, y) - 0.5) * 0.5 : 0;\n out[y * n + x] = clamp01(0.2 + 0.7 * top + irregular + (hash2(x, y, salt) - 0.5) * 0.15);\n }\n break;\n }\n case 'gesso': {\n // Brushed gesso: soft horizontal streaks over a fine tooth.\n const streaks = noise(2 * k, 28 * k, 3);\n const tooth = noise(64 * k, 64 * k, 2, 13);\n for (let y = 0; y < n; y++)\n for (let x = 0; x < n; x++) out[y * n + x] = clamp01((streaks.at(x, y) - 0.5) * 1.8 + (tooth.at(x, y) - 0.5) * 0.9 + 0.55);\n break;\n }\n }\n return out;\n}\n\nconst rawCache = new Map<string, Float32Array>();\n\n/** The raw height map of a pattern (`GRAIN_TILE` square, 0..1), generated once per pattern and seed. */\nexport function grainHeights(pattern: GrainPattern, seed: number, size = GRAIN_TILE): Float32Array {\n const key = `${pattern}:${seed}:${size}`;\n let h = rawCache.get(key);\n if (!h) {\n h = patternHeights(pattern, size, seed);\n if (rawCache.size > 32) rawCache.delete(rawCache.keys().next().value as string);\n rawCache.set(key, h);\n }\n return h;\n}\n\n/**\n * A paper's height field over the canvas (document pixels), tuned for one kind of media. Read it\n * with `at(x, y)`: bilinear, tiled by `paper.tiling`, at `paper.scale`.\n */\nexport class PaperGrain {\n readonly size = GRAIN_TILE;\n private readonly heights: Float32Array;\n private readonly scale: number;\n private readonly mirror: boolean;\n readonly flat: boolean;\n\n constructor(paper: PaperSettings, media: 'dry' | 'wet' = 'dry') {\n const raw = grainHeights(paper.pattern, paper.seed);\n const t = paper[media];\n this.flat = paper.pattern === 'smooth';\n if (t.contrast === 1 && !t.invert) this.heights = raw;\n else {\n const out = new Float32Array(raw.length);\n for (let i = 0; i < raw.length; i++) {\n const v = clamp01((raw[i] - 0.5) * t.contrast + 0.5);\n out[i] = t.invert ? 1 - v : v;\n }\n this.heights = out;\n }\n this.scale = paper.scale;\n this.mirror = paper.tiling === 'mirror';\n }\n\n /** Tile cell index for a coordinate in grain pixels (mirrored on odd tiles when mirroring). */\n private wrap(v: number): number {\n const n = this.size;\n if (!this.mirror) return ((v % n) + n) % n;\n const p = ((v % (2 * n)) + 2 * n) % (2 * n);\n return p < n ? p : 2 * n - 1 - p;\n }\n\n /** Height 0..1 at document position (x, y). */\n at(x: number, y: number): number {\n const u = x / this.scale - 0.5;\n const v = y / this.scale - 0.5;\n const x0 = Math.floor(u);\n const y0 = Math.floor(v);\n const fx = u - x0;\n const fy = v - y0;\n const n = this.size;\n const h = this.heights;\n const a = this.wrap(x0);\n const b = this.wrap(x0 + 1);\n const c = this.wrap(y0) * n;\n const d = this.wrap(y0 + 1) * n;\n const top = h[c + a] + (h[c + b] - h[c + a]) * fx;\n const bot = h[d + a] + (h[d + b] - h[d + a]) * fx;\n return top + (bot - top) * fy;\n }\n}\n\n/**\n * How much of a dry dab lands at grain height `h` (0..1): the media catches the peaks first, and\n * pressure pushes it into the valleys. `depth` is the paper's grain depth times the brush's grain\n * response; at 0 everything lands (1).\n */\nexport function grainCatch(h: number, depth: number, pressure: number): number {\n if (depth <= 0) return 1;\n const t = depth * (0.75 - 0.65 * Math.min(1, Math.max(0, pressure)));\n const u = clamp01((h - t + 0.18) / 0.36);\n return 1 - depth + depth * u * u * (3 - 2 * u);\n}\n\n/** `#rrggbb` → [r, g, b] 0..255. */\nexport function hexToRgb8(hex: string): [number, number, number] {\n const n = parseInt(hex.slice(1, 7), 16);\n return [(n >> 16) & 255, (n >> 8) & 255, n & 255];\n}\n\n/**\n * The paper as opaque RGBA over `rect` (document pixels): its colour, darkened in the valleys by\n * `shading`.\n */\nexport function renderPaper(paper: PaperSettings, rect: { x: number; y: number; width: number; height: number }, grain = new PaperGrain(paper)): Uint8ClampedArray {\n const [r, g, b] = hexToRgb8(paper.color);\n const out = new Uint8ClampedArray(rect.width * rect.height * 4);\n const shade = grain.flat ? 0 : paper.shading * 0.16;\n for (let y = 0; y < rect.height; y++) {\n for (let x = 0; x < rect.width; x++) {\n const i = (y * rect.width + x) * 4;\n const k = shade ? 1 - shade * (1 - grain.at(rect.x + x + 0.5, rect.y + y + 0.5)) : 1;\n out[i] = r * k;\n out[i + 1] = g * k;\n out[i + 2] = b * k;\n out[i + 3] = 255;\n }\n }\n return out;\n}\n","/**\n * The paint editor's document: a canvas (size and resolution), a paper, and the shared raster\n * layer stack (`@pixerate/editor/raster`: pixel layers and groups with masks, clipping, locks and\n * blend modes). Layers are immutable and share tiles, so a history entry is a reference to a\n * whole document state.\n *\n * Saved documents are JSON plus PNG assets, through the image editor's layer serializer (so the\n * same layer tree loads in both editors), with the paper as plain settings.\n */\n\nimport type { RasterGroupLayer, RasterLayer, RasterPixelLayer } from '../raster/layers';\nimport { emptySurface } from '../raster/surface';\nimport { normalizePaper, type PaperSettings } from './paper';\nimport type { RecordedStroke } from './strokes';\n\nexport type PaintPixelLayer = RasterPixelLayer;\nexport type PaintGroupLayer = RasterGroupLayer<PaintLayer>;\n/** A layer of the paint editor: the shared stack's pixel layers and groups. */\nexport type PaintLayer = RasterLayer;\n\n/** Canvas size limits (pixels per side). */\nexport const MIN_CANVAS_SIDE = 1;\nexport const MAX_CANVAS_SIDE = 16384;\nexport const DEFAULT_DPI = 300;\n\nexport interface PaintCanvas {\n width: number;\n height: number;\n /** Pixels per inch, for print sizes and PSD resolution (default 300). */\n dpi: number;\n}\n\n/** Everything one undo step restores. */\nexport interface PaintDocumentState {\n canvas: PaintCanvas;\n paper: PaperSettings;\n /** Bottom to top. */\n layers: PaintLayer[];\n activeLayerId: string | null;\n /** Every committed stroke, oldest first (strokes are data: replay, vary, time-lapse later). */\n strokes: RecordedStroke[];\n}\n\nlet nextId = 1;\n\n/** A new layer id, unique in this session. */\nexport function newPaintLayerId(): string {\n return `pl${Date.now().toString(36)}${(nextId++).toString(36)}`;\n}\n\n/** An empty, visible, normal pixel layer. */\nexport function createPaintLayer(name: string, id = newPaintLayerId()): PaintPixelLayer {\n return { type: 'pixel', id, name, visible: true, opacity: 1, blend: 'normal', surface: emptySurface(4), offset: { x: 0, y: 0 } };\n}\n\nexport class PaintDocumentError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'PaintDocumentError';\n }\n}\n\n/** Validates and rounds a canvas size; throws a `PaintDocumentError` that says what is wrong. */\nexport function normalizeCanvas(raw: Partial<PaintCanvas>): PaintCanvas {\n const side = (v: unknown, what: string) => {\n if (typeof v !== 'number' || !Number.isFinite(v)) throw new PaintDocumentError(`${what} must be a number of pixels (${MIN_CANVAS_SIDE}..${MAX_CANVAS_SIDE}).`);\n const n = Math.round(v);\n if (n < MIN_CANVAS_SIDE || n > MAX_CANVAS_SIDE) throw new PaintDocumentError(`${what} ${n} is out of range; use ${MIN_CANVAS_SIDE}..${MAX_CANVAS_SIDE} pixels.`);\n return n;\n };\n const dpi = raw.dpi === undefined ? DEFAULT_DPI : raw.dpi;\n if (typeof dpi !== 'number' || !Number.isFinite(dpi) || dpi < 1 || dpi > 10000) throw new PaintDocumentError(`dpi ${dpi} is out of range; use 1..10000.`);\n return { width: side(raw.width, 'width'), height: side(raw.height, 'height'), dpi: Math.round(dpi * 100) / 100 };\n}\n\n/** A blank document: one empty layer over the paper. */\nexport function createPaintDocument(options: Partial<PaintCanvas> & { paper?: Partial<PaperSettings> } = {}): PaintDocumentState {\n const canvas = normalizeCanvas({ width: options.width ?? 2048, height: options.height ?? 1536, dpi: options.dpi });\n const layer = createPaintLayer('Layer 1');\n return { canvas, paper: normalizePaper(options.paper ?? {}), layers: [layer], activeLayerId: layer.id, strokes: [] };\n}\n","/**\n * Paint editor brushes: the shared engine's tip settings (`@pixerate/editor/paint`) plus what a\n * natural-media brush adds: paper grain response, pen dynamics (pressure, tilt, barrel rotation,\n * velocity), separate pressure smoothing, a rotation mode, jitter, and Mixer Brush settings for\n * the blending brushes. The built-in presets are our own settings; none come from another product.\n */\n\nimport { DEFAULT_BRUSH, MAX_BRUSH_SIZE, normalizeBrush, type BrushSettings } from '../paint/brush';\nimport { DEFAULT_MIXER, normalizeMixer, type MixerSettings } from '../paint/mixer';\n\n/** How a brush makes marks: dabs into a stroke buffer, removing alpha, or the Mixer Brush engine. */\nexport type PaintBrushEngine = 'dab' | 'eraser' | 'mixer';\n\nexport const PAINT_BRUSH_ENGINES: readonly PaintBrushEngine[] = ['dab', 'eraser', 'mixer'];\n\nexport type PaintBrushCategory = 'pencil' | 'pastel' | 'charcoal' | 'airbrush' | 'marker' | 'ink' | 'eraser' | 'blender' | 'smudge' | 'mixer' | 'custom';\n\nexport const PAINT_BRUSH_CATEGORIES: readonly PaintBrushCategory[] = ['pencil', 'pastel', 'charcoal', 'airbrush', 'marker', 'ink', 'eraser', 'blender', 'smudge', 'mixer', 'custom'];\n\n/** What turns the tip: a fixed angle, the direction of the stroke, or the pen's barrel rotation. */\nexport type BrushRotation = 'fixed' | 'stroke' | 'barrel';\n\nexport const BRUSH_ROTATIONS: readonly BrushRotation[] = ['fixed', 'stroke', 'barrel'];\n\n/** Pen dynamics and jitter. Every amount is 0 (off) .. 1 unless noted. */\nexport interface BrushDynamics {\n /** Size at zero pressure as a fraction of the full size, when pressure controls size (default 0). */\n minSize: number;\n /** How much pressure scales flow (default 0). */\n pressureFlow: number;\n /** Laying the pen down widens the tip, up to 2.5× (default 0). */\n tiltSize: number;\n /** Laying the pen down flattens the tip along the tilt direction (default 0). */\n tiltRoundness: number;\n /** Laying the pen down lightens the mark, as when shading with the side of a pencil (default 0). */\n tiltOpacity: number;\n /** -1..1: positive grows the tip when the pen moves fast, negative thins it (default 0). */\n velocitySize: number;\n /** -1..1: positive darkens fast marks, negative lightens them (default 0). */\n velocityOpacity: number;\n /** Random size change per dab (default 0). */\n sizeJitter: number;\n /** Random angle per dab, as a fraction of ±180° (default 0). */\n angleJitter: number;\n /** Random opacity drop per dab (default 0). */\n opacityJitter: number;\n /** Random offset across the stroke in diameters, 0..4 (default 0). */\n scatter: number;\n}\n\nexport const DEFAULT_DYNAMICS: Readonly<BrushDynamics> = {\n minSize: 0,\n pressureFlow: 0,\n tiltSize: 0,\n tiltRoundness: 0,\n tiltOpacity: 0,\n velocitySize: 0,\n velocityOpacity: 0,\n sizeJitter: 0,\n angleJitter: 0,\n opacityJitter: 0,\n scatter: 0,\n};\n\nexport interface PaintBrush {\n /** Library id (lowercase letters, digits and dashes). */\n id: string;\n name: string;\n category: PaintBrushCategory;\n engine: PaintBrushEngine;\n /** The shared engine's tip: size, hardness, spacing, angle, roundness, opacity, flow, position smoothing, pressure to size / opacity, blend. */\n tip: BrushSettings;\n /** How strongly the mark follows the paper grain, 0 (ignores it) .. 1 (catches only the peaks at light pressure). */\n grain: number;\n /** Pressure smoothing 0..0.95, separate from the tip's position smoothing (default 0). */\n pressureSmoothing: number;\n rotation: BrushRotation;\n dynamics: BrushDynamics;\n /** Mixer engine only: the Mixer Brush settings. */\n mixer: MixerSettings;\n /** Mixer engine only: load the current colour each stroke (false: a smudge or blender that only moves paint). */\n loadsColor: boolean;\n /** True for the built-in presets (they cannot be removed or overwritten). */\n builtin?: boolean;\n}\n\nconst unit = (v: unknown, d: number) => (typeof v === 'number' && Number.isFinite(v) ? Math.min(1, Math.max(0, v)) : d);\nconst range = (v: unknown, lo: number, hi: number, d: number) => (typeof v === 'number' && Number.isFinite(v) ? Math.min(hi, Math.max(lo, v)) : d);\n\nexport function normalizeDynamics(raw: Partial<BrushDynamics> = {}, base: BrushDynamics = DEFAULT_DYNAMICS): BrushDynamics {\n return {\n minSize: unit(raw.minSize, base.minSize),\n pressureFlow: unit(raw.pressureFlow, base.pressureFlow),\n tiltSize: unit(raw.tiltSize, base.tiltSize),\n tiltRoundness: unit(raw.tiltRoundness, base.tiltRoundness),\n tiltOpacity: unit(raw.tiltOpacity, base.tiltOpacity),\n velocitySize: range(raw.velocitySize, -1, 1, base.velocitySize),\n velocityOpacity: range(raw.velocityOpacity, -1, 1, base.velocityOpacity),\n sizeJitter: unit(raw.sizeJitter, base.sizeJitter),\n angleJitter: unit(raw.angleJitter, base.angleJitter),\n opacityJitter: unit(raw.opacityJitter, base.opacityJitter),\n scatter: range(raw.scatter, 0, 4, base.scatter),\n };\n}\n\nexport const BRUSH_ID = /^[a-z0-9][a-z0-9-]{0,63}$/;\n\n/** Brush settings to change or read: any subset of a brush, its tip, dynamics and mixer. */\nexport type PaintBrushInput = Partial<Omit<PaintBrush, 'tip' | 'dynamics' | 'mixer'>> & { tip?: Partial<BrushSettings>; dynamics?: Partial<BrushDynamics>; mixer?: Partial<MixerSettings> };\n\n/** A brush with every field in range; missing fields come from `base` (default: a plain round dab brush). */\nexport function normalizePaintBrush(raw: PaintBrushInput = {}, base?: PaintBrush): PaintBrush {\n const b = base ?? BASE_BRUSH;\n const id = typeof raw.id === 'string' && BRUSH_ID.test(raw.id) ? raw.id : b.id;\n return {\n id,\n name: typeof raw.name === 'string' && raw.name.trim() ? raw.name.trim().slice(0, 80) : b.name,\n category: PAINT_BRUSH_CATEGORIES.includes(raw.category as PaintBrushCategory) ? (raw.category as PaintBrushCategory) : b.category,\n engine: PAINT_BRUSH_ENGINES.includes(raw.engine as PaintBrushEngine) ? (raw.engine as PaintBrushEngine) : b.engine,\n tip: normalizeBrush({ ...b.tip, ...(raw.tip ?? {}) }),\n grain: unit(raw.grain, b.grain),\n pressureSmoothing: range(raw.pressureSmoothing, 0, 0.95, b.pressureSmoothing),\n rotation: BRUSH_ROTATIONS.includes(raw.rotation as BrushRotation) ? (raw.rotation as BrushRotation) : b.rotation,\n dynamics: normalizeDynamics(raw.dynamics ?? {}, b.dynamics),\n mixer: normalizeMixer({ ...b.mixer, ...(raw.mixer ?? {}) }),\n loadsColor: typeof raw.loadsColor === 'boolean' ? raw.loadsColor : b.loadsColor,\n ...(raw.builtin ? { builtin: true } : {}),\n };\n}\n\nconst BASE_BRUSH: PaintBrush = {\n id: 'round',\n name: 'Round',\n category: 'custom',\n engine: 'dab',\n tip: { ...DEFAULT_BRUSH },\n grain: 0,\n pressureSmoothing: 0,\n rotation: 'fixed',\n dynamics: { ...DEFAULT_DYNAMICS },\n mixer: { ...DEFAULT_MIXER },\n loadsColor: true,\n};\n\ntype BrushInit = PaintBrushInput & { id: string; name: string; category: PaintBrushCategory };\n\nconst builtin = (init: BrushInit): PaintBrush => ({ ...normalizePaintBrush(init), builtin: true });\n\n/** The built-in brush library. */\nexport const BUILTIN_BRUSHES: readonly PaintBrush[] = [\n builtin({\n id: 'pencil-hb', name: 'HB pencil', category: 'pencil',\n tip: { size: 4, hardness: 0.7, spacing: 0.08, opacity: 0.85, flow: 0.55, smoothing: 0.25, pressureSize: true, pressureOpacity: true },\n grain: 0.85, pressureSmoothing: 0.3,\n dynamics: { minSize: 0.55, tiltSize: 0.9, tiltRoundness: 0.7, tiltOpacity: 0.5 },\n }),\n builtin({\n id: 'pencil-6b', name: '6B pencil', category: 'pencil',\n tip: { size: 7, hardness: 0.55, spacing: 0.07, opacity: 1, flow: 0.75, smoothing: 0.2, pressureSize: true, pressureOpacity: true },\n grain: 0.7, pressureSmoothing: 0.3,\n dynamics: { minSize: 0.5, tiltSize: 1, tiltRoundness: 0.75, tiltOpacity: 0.35 },\n }),\n builtin({\n id: 'soft-pastel', name: 'Soft pastel', category: 'pastel', rotation: 'stroke',\n tip: { size: 32, hardness: 0.55, spacing: 0.05, angle: 90, roundness: 0.55, opacity: 1, flow: 0.7, smoothing: 0.15, pressureSize: false, pressureOpacity: true },\n grain: 1, pressureSmoothing: 0.25,\n dynamics: { sizeJitter: 0.06, angleJitter: 0.02 },\n }),\n builtin({\n id: 'oil-pastel', name: 'Oil pastel', category: 'pastel', rotation: 'stroke',\n tip: { size: 26, hardness: 0.8, spacing: 0.05, angle: 90, roundness: 0.7, opacity: 1, flow: 0.9, smoothing: 0.15, pressureSize: true, pressureOpacity: false, blend: 'pigment' },\n grain: 0.5, pressureSmoothing: 0.25,\n dynamics: { minSize: 0.6 },\n }),\n builtin({\n id: 'charcoal-stick', name: 'Charcoal stick', category: 'charcoal', rotation: 'stroke',\n tip: { size: 26, hardness: 0.4, spacing: 0.05, angle: 90, roundness: 0.35, opacity: 0.95, flow: 0.5, smoothing: 0.15, pressureSize: false, pressureOpacity: true },\n grain: 0.95, pressureSmoothing: 0.2,\n dynamics: { sizeJitter: 0.1, angleJitter: 0.03, tiltSize: 0.6 },\n }),\n builtin({\n id: 'vine-charcoal', name: 'Vine charcoal', category: 'charcoal',\n tip: { size: 10, hardness: 0.3, spacing: 0.06, opacity: 0.75, flow: 0.45, smoothing: 0.2, pressureSize: true, pressureOpacity: true },\n grain: 0.9, pressureSmoothing: 0.2,\n dynamics: { minSize: 0.4, tiltSize: 0.8, tiltRoundness: 0.5, tiltOpacity: 0.3, sizeJitter: 0.08 },\n }),\n builtin({\n id: 'airbrush', name: 'Airbrush', category: 'airbrush',\n tip: { size: 90, hardness: 0, spacing: 0.04, opacity: 1, flow: 0.06, smoothing: 0.3, pressureSize: false, pressureOpacity: false },\n grain: 0, pressureSmoothing: 0.3,\n dynamics: { pressureFlow: 1, tiltSize: 0.5, tiltRoundness: 0.6 },\n }),\n builtin({\n id: 'marker', name: 'Chisel marker', category: 'marker',\n tip: { size: 24, hardness: 0.85, spacing: 0.04, angle: 45, roundness: 0.35, opacity: 0.6, flow: 1, smoothing: 0.3, pressureSize: false, pressureOpacity: false, blend: 'multiply' },\n grain: 0.1,\n }),\n builtin({\n id: 'ink-pen', name: 'Ink pen', category: 'ink',\n tip: { size: 4, hardness: 1, spacing: 0.05, opacity: 1, flow: 1, smoothing: 0.5, pressureSize: true, pressureOpacity: false },\n pressureSmoothing: 0.4,\n dynamics: { minSize: 0.25, velocitySize: -0.45 },\n }),\n builtin({\n id: 'brush-pen', name: 'Brush pen', category: 'ink', rotation: 'stroke',\n tip: { size: 14, hardness: 0.9, spacing: 0.04, roundness: 0.8, opacity: 1, flow: 1, smoothing: 0.5, pressureSize: true, pressureOpacity: false },\n pressureSmoothing: 0.45,\n dynamics: { minSize: 0.05, velocitySize: -0.3 },\n }),\n builtin({\n id: 'eraser-soft', name: 'Soft eraser', category: 'eraser', engine: 'eraser',\n tip: { size: 40, hardness: 0.2, spacing: 0.08, opacity: 1, flow: 0.6, pressureSize: false, pressureOpacity: true },\n }),\n builtin({\n id: 'eraser-hard', name: 'Hard eraser', category: 'eraser', engine: 'eraser',\n tip: { size: 16, hardness: 0.9, spacing: 0.06, opacity: 1, flow: 1, pressureSize: true, pressureOpacity: false },\n grain: 0.3,\n dynamics: { minSize: 0.5 },\n }),\n builtin({\n id: 'blender', name: 'Blender', category: 'blender', engine: 'mixer', loadsColor: false,\n tip: { size: 34, hardness: 0.4, spacing: 0.08, opacity: 1, flow: 0.35, smoothing: 0.2, pressureSize: false, pressureOpacity: true },\n mixer: { wet: 0.7, load: 0, mix: 1, loadEachStroke: false, cleanEachStroke: true, mixing: 'pigment' },\n }),\n builtin({\n id: 'smudge', name: 'Smudge', category: 'smudge', engine: 'mixer', loadsColor: false,\n tip: { size: 26, hardness: 0.6, spacing: 0.06, opacity: 1, flow: 0.8, smoothing: 0.2, pressureSize: false, pressureOpacity: true },\n mixer: { wet: 1, load: 0, mix: 1, loadEachStroke: false, cleanEachStroke: true, mixing: 'rgb' },\n }),\n builtin({\n id: 'mixer-brush', name: 'Mixer Brush', category: 'mixer', engine: 'mixer',\n tip: { size: 30, hardness: 0.7, spacing: 0.1, opacity: 1, flow: 0.5, smoothing: 0.2, pressureSize: true, pressureOpacity: false },\n mixer: { wet: 0.5, load: 0.95, mix: 0.5, loadEachStroke: true, cleanEachStroke: true, mixing: 'pigment' },\n dynamics: { minSize: 0.5 },\n }),\n];\n\nexport const DEFAULT_BRUSH_ID = 'pencil-6b';\n\nexport { MAX_BRUSH_SIZE };\n\n/** A brush as plain JSON (for export, agents and saved libraries): no `builtin` flag. */\nexport function brushToJSON(brush: PaintBrush): Omit<PaintBrush, 'builtin'> {\n const { builtin: _b, ...rest } = brush;\n return JSON.parse(JSON.stringify(rest));\n}\n\n/** The JSON file a brush library exports to and imports from. */\nexport interface BrushLibraryFile {\n format: 'pixerate-brushes';\n version: 1;\n brushes: Array<Omit<PaintBrush, 'builtin'>>;\n}\n\n/**\n * Brushes read from a brush library file (or a bare array of brushes). Each is normalised; ones\n * without a valid id or name are reported in `problems` and skipped.\n */\nexport function parseBrushLibrary(raw: unknown, problems: string[] = []): PaintBrush[] {\n const list = Array.isArray(raw) ? raw : raw && typeof raw === 'object' && Array.isArray((raw as BrushLibraryFile).brushes) ? (raw as BrushLibraryFile).brushes : null;\n if (!list) throw new Error('Not a brush library: expected {\"format\":\"pixerate-brushes\",\"version\":1,\"brushes\":[...]} or an array of brushes.');\n const out: PaintBrush[] = [];\n list.forEach((item, i) => {\n if (!item || typeof item !== 'object') {\n problems.push(`brushes[${i}] is not an object; skipped.`);\n return;\n }\n const r = item as Record<string, unknown>;\n if (typeof r.id !== 'string' || !BRUSH_ID.test(r.id)) {\n problems.push(`brushes[${i}] has no valid id (lowercase letters, digits and dashes); skipped.`);\n return;\n }\n if (typeof r.name !== 'string' || !r.name.trim()) {\n problems.push(`brushes[${i}] (\"${r.id}\") has no name; skipped.`);\n return;\n }\n const { builtin: _b, ...rest } = r;\n out.push(normalizePaintBrush(rest as PaintBrushInput));\n });\n return out;\n}\n","/**\n * The paint editor's dry-media stroke engine, on the shared brush engine (`@pixerate/editor/paint`):\n *\n * - Pen input: pressure, tilt (`tiltX` / `tiltY` or `altitude` / `azimuth`), barrel rotation\n * (`twist`) and time (for velocity). Position and pressure are smoothed separately.\n * - `PenDabWalker` walks the points into the shared `Dab`s at `spacing × diameter`, with every\n * pen channel interpolated, and applies the brush's dynamics, rotation mode and jitter.\n * Jitter is a pure hash of the stroke seed and the dab index, so a stroke replays exactly.\n * - `DryStroke` rasterizes each dab with the shared round tip, multiplies it by how much of it the\n * paper grain catches (`grainCatch`), and builds it up in the shared `CoverageMap`; the session\n * then composites the coverage with the shared `applyStrokeToTile`.\n * - Symmetry: one stroke can paint several copies of its points (mirror and kaleidoscope), each\n * with its own walker, into the same coverage, so the copies are one stroke and one undo step.\n *\n * Pure data in, pixels out: no DOM, no framework.\n */\n\nimport { CoverageMap, dabRect, rasterizeDab, type BrushSettings, type Dab, type StrokePoint } from '../paint/brush';\nimport type { RasterRect } from '../raster/surface';\nimport type { PaintBrush } from './brushes';\nimport { randSigned } from './noise';\nimport { grainCatch, type PaperGrain } from './paper';\n\n/** One pen sample in document pixels. Every channel but x and y is optional. */\nexport interface PenPoint {\n x: number;\n y: number;\n /** 0..1 (missing: 1, a mouse). */\n pressure?: number;\n /** Milliseconds since any fixed origin (for velocity; missing: no velocity dynamics). */\n t?: number;\n /** Pointer Events tilt in degrees, -90..90 (used when `altitude` / `azimuth` are missing). */\n tiltX?: number;\n tiltY?: number;\n /** Radians from the surface: π/2 is upright, 0 lies flat. */\n altitude?: number;\n /** Radians clockwise from the +x axis (screen y points down): where the pen leans. */\n azimuth?: number;\n /** Barrel rotation in degrees clockwise, 0..359. */\n twist?: number;\n}\n\n/** A pen's lean as altitude and azimuth, or `null` when the sample has no tilt. */\nexport function penOrientation(p: PenPoint): { altitude: number; azimuth: number } | null {\n if (typeof p.altitude === 'number' && Number.isFinite(p.altitude)) {\n const altitude = Math.min(Math.PI / 2, Math.max(0, p.altitude));\n const azimuth = typeof p.azimuth === 'number' && Number.isFinite(p.azimuth) ? p.azimuth : 0;\n return { altitude, azimuth };\n }\n const hasX = typeof p.tiltX === 'number' && Number.isFinite(p.tiltX);\n const hasY = typeof p.tiltY === 'number' && Number.isFinite(p.tiltY);\n if (!hasX && !hasY) return null;\n return tiltToOrientation(hasX ? p.tiltX! : 0, hasY ? p.tiltY! : 0);\n}\n\n/** Pointer Events `tiltX` / `tiltY` (degrees) → altitude and azimuth (radians). */\nexport function tiltToOrientation(tiltX: number, tiltY: number): { altitude: number; azimuth: number } {\n const clampT = (v: number) => Math.min(89.999, Math.max(-89.999, v));\n const tx = Math.tan((clampT(tiltX) * Math.PI) / 180);\n const ty = Math.tan((clampT(tiltY) * Math.PI) / 180);\n const r = Math.hypot(tx, ty);\n if (r < 1e-9) return { altitude: Math.PI / 2, azimuth: 0 };\n let azimuth = Math.atan2(ty, tx);\n if (azimuth < 0) azimuth += 2 * Math.PI;\n return { altitude: Math.atan(1 / r), azimuth };\n}\n\nconst pressureOf = (p: PenPoint) => (typeof p.pressure === 'number' && Number.isFinite(p.pressure) ? Math.min(1, Math.max(0, p.pressure)) : 1);\n\n/**\n * Exponential smoothing of position and of pressure, each by its own amount (0..0.95). Feed raw\n * samples; the first sample passes through.\n */\nexport class PenSmoother {\n private pos: { x: number; y: number } | null = null;\n private pressure: number | null = null;\n private readonly a: number;\n private readonly ap: number;\n\n constructor(position: number, pressure: number) {\n this.a = 1 - Math.min(0.95, Math.max(0, position));\n this.ap = 1 - Math.min(0.95, Math.max(0, pressure));\n }\n\n push(p: PenPoint): PenPoint {\n const pr = pressureOf(p);\n if (!this.pos) {\n this.pos = { x: p.x, y: p.y };\n this.pressure = pr;\n return p;\n }\n this.pos = { x: this.pos.x + (p.x - this.pos.x) * this.a, y: this.pos.y + (p.y - this.pos.y) * this.a };\n this.pressure = this.pressure! + (pr - this.pressure!) * this.ap;\n return { ...p, x: this.pos.x, y: this.pos.y, pressure: this.pressure };\n }\n\n /** Where the smoothed position is now (or `null` before the first sample). */\n get position(): { x: number; y: number } | null {\n return this.pos;\n }\n}\n\n/** A linear map of document vectors `[a, b, c, d]`: (x, y) → (a·x + b·y, c·x + d·y). */\nexport type Linear2 = readonly [number, number, number, number];\n\n/** How one copy of a stroke maps the input: a point map and its linear part (for dab angles). */\nexport interface StrokeCopy {\n map(p: PenPoint): PenPoint;\n linear: Linear2;\n}\n\nexport const IDENTITY_COPY: StrokeCopy = { map: (p) => p, linear: [1, 0, 0, 1] };\n\n/** A dab with the pen state it was made at (the shared `Dab` plus pressure for the grain). */\nexport interface PenDab extends Dab {\n pressure: number;\n}\n\nconst enum Stream {\n Size = 1,\n Angle = 2,\n Opacity = 3,\n Scatter = 4,\n}\n\ninterface Sample {\n x: number;\n y: number;\n pressure: number;\n lean: number;\n azimuth: number;\n twist: number | null;\n speed: number | null;\n}\n\n/** Speed (px/ms) at which velocity dynamics reach their full effect. */\nconst FULL_SPEED = 2.5;\n\n/**\n * Walks pen samples into dabs, incrementally (any chunking gives the same dabs). Dab angles are in\n * the shared rasterizer's convention: radians, counter-clockwise with y up.\n */\nexport class PenDabWalker {\n private last: Sample | null = null;\n private nextAt = 0;\n private pendingFirst: Sample | null = null;\n private index = 0;\n private dir = 0;\n private lastT: number | null = null;\n private speed: number | null = null;\n\n constructor(\n readonly brush: PaintBrush,\n private readonly seed = 0,\n private readonly linear: Linear2 = [1, 0, 0, 1]\n ) {}\n\n private sample(p: PenPoint): Sample {\n const o = penOrientation(p);\n let speed: number | null = null;\n if (typeof p.t === 'number' && Number.isFinite(p.t)) {\n if (this.last && this.lastT !== null && p.t > this.lastT) {\n const v = Math.hypot(p.x - this.last.x, p.y - this.last.y) / (p.t - this.lastT);\n this.speed = this.speed === null ? v : this.speed + (v - this.speed) * 0.35;\n }\n this.lastT = p.t;\n speed = this.speed ?? 0;\n }\n return {\n x: p.x,\n y: p.y,\n pressure: pressureOf(p),\n lean: o ? 1 - o.altitude / (Math.PI / 2) : 0,\n azimuth: o ? o.azimuth : 0,\n twist: typeof p.twist === 'number' && Number.isFinite(p.twist) ? p.twist : null,\n speed,\n };\n }\n\n private diameter(s: Sample): number {\n const tip = this.brush.tip;\n const dyn = this.brush.dynamics;\n let d = tip.size;\n if (tip.pressureSize) d *= dyn.minSize + (1 - dyn.minSize) * s.pressure;\n d *= 1 + dyn.tiltSize * s.lean * 1.5;\n if (s.speed !== null && dyn.velocitySize) d *= Math.max(0.05, 1 + dyn.velocitySize * Math.min(1, s.speed / FULL_SPEED) * (dyn.velocitySize < 0 ? 0.85 : 1));\n return d;\n }\n\n private stepLen(s: Sample): number {\n return Math.max(0.5, Math.max(1, this.diameter(s)) * Math.max(0.01, this.brush.tip.spacing));\n }\n\n /** A rasterizer angle (CCW, y up) mapped through this copy's linear part. */\n private mapAngle(theta: number): number {\n const [a, b, c, d] = this.linear;\n if (a === 1 && b === 0 && c === 0 && d === 1) return theta;\n const vx = Math.cos(theta);\n const vy = -Math.sin(theta);\n return Math.atan2(-(c * vx + d * vy), a * vx + b * vy);\n }\n\n private dab(s: Sample): PenDab {\n const { tip, dynamics: dyn, rotation } = this.brush;\n const i = this.index++;\n const seed = this.seed;\n let diameter = this.diameter(s);\n if (dyn.sizeJitter) diameter *= Math.max(0.05, 1 + dyn.sizeJitter * randSigned(seed, i, Stream.Size));\n const base = (tip.angle * Math.PI) / 180;\n let angle: number;\n if (rotation === 'stroke') angle = this.dir + base;\n else if (rotation === 'barrel' && s.twist !== null) angle = this.mapAngle(base - (s.twist * Math.PI) / 180);\n else if (dyn.tiltRoundness > 0 && s.lean > 0.02) angle = this.mapAngle(base - s.azimuth);\n else angle = this.mapAngle(base);\n if (dyn.angleJitter) angle += dyn.angleJitter * Math.PI * randSigned(seed, i, Stream.Angle);\n let opacity = tip.pressureOpacity ? s.pressure : 1;\n opacity *= 1 - dyn.tiltOpacity * s.lean * 0.8;\n if (s.speed !== null && dyn.velocityOpacity) opacity *= Math.max(0, 1 + dyn.velocityOpacity * (Math.min(1, s.speed / FULL_SPEED) - 0.5));\n if (dyn.opacityJitter) opacity *= 1 - dyn.opacityJitter * (randSigned(seed, i, Stream.Opacity) * 0.5 + 0.5);\n const flow = tip.flow * (1 - dyn.pressureFlow + dyn.pressureFlow * s.pressure);\n let { x, y } = s;\n if (dyn.scatter) {\n const off = dyn.scatter * diameter * randSigned(seed, i, Stream.Scatter);\n // Across the stroke: the direction of travel turned a quarter (document y points down).\n x += Math.sin(this.dir) * off;\n y += Math.cos(this.dir) * off;\n }\n return {\n x,\n y,\n radius: Math.max(0.5, diameter / 2),\n alpha: Math.min(1, Math.max(0, flow)),\n opacity: Math.min(1, Math.max(0, opacity)),\n angle,\n roundness: Math.min(1, Math.max(0.01, tip.roundness * (1 - dyn.tiltRoundness * s.lean * 0.8))),\n pressure: s.pressure,\n };\n }\n\n push(p: PenPoint, out: PenDab[]): void {\n const a = this.last;\n const s = this.sample(p);\n if (!a) {\n this.last = s;\n this.pendingFirst = s;\n this.nextAt = this.stepLen(s);\n return;\n }\n const dx = s.x - a.x;\n const dy = s.y - a.y;\n const len = Math.hypot(dx, dy);\n if (len > 1e-9) this.dir = Math.atan2(-dy, dx);\n if (this.pendingFirst) {\n out.push(this.dab(this.pendingFirst));\n this.pendingFirst = null;\n }\n if (len > 1e-9) {\n while (this.nextAt <= len + 1e-9) {\n const f = Math.min(1, this.nextAt / len);\n const lerp = (u: number, v: number) => u + (v - u) * f;\n const q: Sample = {\n x: a.x + dx * f,\n y: a.y + dy * f,\n pressure: lerp(a.pressure, s.pressure),\n lean: lerp(a.lean, s.lean),\n azimuth: lerpAngle(a.azimuth, s.azimuth, f),\n twist: a.twist !== null && s.twist !== null ? lerpDegrees(a.twist, s.twist, f) : s.twist,\n speed: a.speed !== null && s.speed !== null ? lerp(a.speed, s.speed) : s.speed,\n };\n out.push(this.dab(q));\n this.nextAt += this.stepLen(q);\n }\n this.nextAt -= len;\n }\n this.last = s;\n }\n\n finish(out: PenDab[]): void {\n if (this.pendingFirst) {\n out.push(this.dab(this.pendingFirst));\n this.pendingFirst = null;\n }\n }\n}\n\nfunction lerpAngle(a: number, b: number, t: number): number {\n let d = b - a;\n while (d > Math.PI) d -= 2 * Math.PI;\n while (d < -Math.PI) d += 2 * Math.PI;\n return a + d * t;\n}\n\nfunction lerpDegrees(a: number, b: number, t: number): number {\n let d = b - a;\n while (d > 180) d -= 360;\n while (d < -180) d += 360;\n return a + d * t;\n}\n\nexport interface DryStrokeOptions {\n /** The paper's dry height field, or `null` for no grain. */\n grain: PaperGrain | null;\n /** The paper's grain depth, 0..1 (multiplied by the brush's grain response). */\n paperDepth: number;\n /** Jitter seed (record it to replay the stroke exactly). */\n seed?: number;\n /** Copies of the stroke (symmetry); default one identity copy. */\n copies?: readonly StrokeCopy[];\n}\n\n/**\n * One dab-engine stroke (dab and eraser brushes): smoothing, the dab walk of every copy, grain and\n * build-up in a shared coverage map.\n */\nexport class DryStroke {\n readonly coverage = new CoverageMap();\n dabCount = 0;\n private readonly smoother: PenSmoother;\n private readonly walkers: PenDabWalker[];\n private readonly copies: readonly StrokeCopy[];\n private readonly depth: number;\n private buf = new Float32Array(0);\n private lastRaw: PenPoint | null = null;\n private lastFed: PenPoint | null = null;\n\n constructor(readonly brush: PaintBrush, private readonly options: DryStrokeOptions) {\n this.smoother = new PenSmoother(brush.tip.smoothing, brush.pressureSmoothing);\n this.copies = options.copies?.length ? options.copies : [IDENTITY_COPY];\n this.walkers = this.copies.map((c, i) => new PenDabWalker(brush, ((options.seed ?? 0) + i * 7919) | 0, c.linear));\n this.depth = options.grain && !options.grain.flat ? Math.min(1, Math.max(0, options.paperDepth * brush.grain)) : 0;\n }\n\n /** Feeds raw pen samples; returns the document rectangles the new dabs touched. */\n push(points: readonly PenPoint[]): RasterRect[] {\n const dabs: PenDab[] = [];\n for (const raw of points) {\n this.lastRaw = raw;\n const p = this.smoother.push(raw);\n this.lastFed = p;\n this.copies.forEach((c, i) => this.walkers[i].push(c.map(p), dabs));\n }\n return this.paint(dabs);\n }\n\n /** Ends the stroke: the smoothed path catches up with the last raw sample; a single tap paints one dab. */\n finish(): RasterRect[] {\n const dabs: PenDab[] = [];\n const raw = this.lastRaw;\n const fed = this.lastFed;\n if (raw && fed && (raw.x !== fed.x || raw.y !== fed.y)) this.copies.forEach((c, i) => this.walkers[i].push(c.map({ ...raw, pressure: fed.pressure }), dabs));\n for (const w of this.walkers) w.finish(dabs);\n return this.paint(dabs);\n }\n\n private paint(dabs: PenDab[]): RasterRect[] {\n const rects: RasterRect[] = [];\n const hardness = this.brush.tip.hardness;\n const grain = this.options.grain;\n for (const d of dabs) {\n const rect = dabRect(d, hardness);\n const n = rect.width * rect.height;\n if (this.buf.length < n) this.buf = new Float32Array(n);\n const vals = this.buf.subarray(0, n);\n rasterizeDab(d, hardness, rect, vals);\n if (this.depth > 0 && grain) {\n for (let yy = 0, k = 0; yy < rect.height; yy++) {\n const y = rect.y + yy + 0.5;\n for (let xx = 0; xx < rect.width; xx++, k++) {\n if (vals[k] > 0) vals[k] *= grainCatch(grain.at(rect.x + xx + 0.5, y), this.depth, d.pressure);\n }\n }\n }\n this.coverage.accumulate(rect, vals, d.opacity);\n rects.push(rect);\n this.dabCount++;\n }\n return rects;\n }\n}\n\n/** The shared engine's tip for the Mixer Brush engine (it smooths and walks by itself, so smoothing is applied before). */\nexport function mixerTip(brush: PaintBrush): BrushSettings {\n return { ...brush.tip, smoothing: 0, pressureSize: brush.tip.pressureSize };\n}\n\n/** Pen samples → the shared engine's stroke points (pressure only). */\nexport function toStrokePoint(p: PenPoint): StrokePoint {\n return { x: p.x, y: p.y, pressure: pressureOf(p), ...(typeof p.t === 'number' ? { t: p.t } : {}) };\n}\n","/**\n * A live stroke on one pixel layer. Points arrive while the pen moves; the layer shows the stroke\n * so far through a live surface (no history); `end()` commits it as one undo step.\n *\n * - Dab and eraser brushes: the coverage is cumulative, so each update recomposites the touched\n * region from the pre-stroke tile (`applyStrokeToTile` with `into` and `region`).\n * - Mixer engine brushes (Mixer Brush, blender, smudge): dabs read what earlier dabs laid down, so\n * they paint into live tile copies; every tile written since the last update gets a new `Tile`\n * object, because the compositor caches by tile identity.\n */\n\nimport { applyStrokeToTile, type StrokeApply } from '../paint/brush';\nimport { MixerStroke, cleanMixer, loadMixer, type MixerLoad, type MixerTarget } from '../paint/mixer';\nimport { TILE, TiledSurface, finishTile, tileKey, tilesInRect, type RasterRect, type Tile, type TileKey } from '../raster/surface';\nimport type { PaintBrush } from './brushes';\nimport { DryStroke, IDENTITY_COPY, PenSmoother, mixerTip, toStrokePoint, type PenPoint, type StrokeCopy } from './engine';\nimport type { PaperGrain } from './paper';\nimport type { Affine } from './strokes';\n\nexport interface StrokeSessionHost {\n /** Shows the layer's live surface (no history); `rects` are where it changed. */\n update(layerId: string, surface: TiledSurface, rects: RasterRect[]): void;\n /** Ends the stroke: `surface` is the new pixels, or `null` when nothing changed / it was cancelled. */\n commit(session: PaintStrokeSession, surface: TiledSurface | null, cancelled: boolean): void;\n}\n\nexport interface StrokeSessionInit {\n layerId: string;\n surface: TiledSurface;\n offset: { x: number; y: number };\n lockTransparency: boolean;\n brush: PaintBrush;\n /** Paint colour 0..255 RGBA. */\n color: readonly [number, number, number, number];\n /** What the eraser paints on a transparency-locked layer (the paper colour). */\n background: readonly [number, number, number, number];\n grain: PaperGrain | null;\n paperDepth: number;\n seed: number;\n /** The paint colour as #rrggbb (recorded with the stroke). */\n colorHex: string;\n /** The stroke's extra copies as affine maps (recorded with the stroke); `copies` holds all of them as engine copies. */\n affineCopies: readonly Affine[];\n copies: readonly StrokeCopy[];\n /** Applied to each raw sample before it is painted and recorded (perspective snapping). */\n inputFilter?: (p: PenPoint) => PenPoint;\n /** Mixer engine: the brush load at the start of the stroke. */\n mixerLoad: MixerLoad;\n}\n\nexport interface PaintStrokeResult {\n layerId: string;\n /** Document rectangle the stroke touched, or `null` when no pixel changed. */\n bounds: RasterRect | null;\n dabs: number;\n /** Id of the recorded stroke (see `list_strokes` / `replay_strokes`), or `null` when nothing changed. */\n strokeId: string | null;\n /** Mixer engine brushes: what the brush carries after the stroke. */\n mixerLoad?: MixerLoad;\n}\n\nfunction defaultTile(surface: TiledSurface): Uint8ClampedArray {\n const data = new Uint8ClampedArray(TILE * TILE * surface.channels);\n if (surface.defaultValue) data.fill(surface.defaultValue);\n return data;\n}\n\nfunction sameTile(a: Tile | undefined, b: Tile | null): boolean {\n if (!a || !b) return !a && !b;\n if (a === b) return true;\n if (a.uniform !== null || b.uniform !== null) return a.uniform === b.uniform;\n for (let i = 0; i < a.data.length; i++) if (a.data[i] !== b.data[i]) return false;\n return true;\n}\n\nfunction union(a: RasterRect | null, b: RasterRect): RasterRect {\n if (!a) return { ...b };\n const x = Math.min(a.x, b.x);\n const y = Math.min(a.y, b.y);\n return { x, y, width: Math.max(a.x + a.width, b.x + b.width) - x, height: Math.max(a.y + a.height, b.y + b.height) - y };\n}\n\nexport class PaintStrokeSession {\n readonly layerId: string;\n /** The raw input so far (what a replay feeds back in). */\n readonly points: PenPoint[] = [];\n private readonly base: TiledSurface;\n private readonly live: Map<TileKey, Tile>;\n private readonly touched = new Set<TileKey>();\n private readonly fresh = new Set<TileKey>();\n private readonly dry: DryStroke | null = null;\n private readonly mixers: MixerStroke[] = [];\n private readonly mixerSmoother: PenSmoother | null = null;\n private readonly apply: StrokeApply;\n private readonly copies: readonly StrokeCopy[];\n private bounds: RasterRect | null = null;\n private lastRaw: PenPoint | null = null;\n private closed = false;\n result: PaintStrokeResult | null = null;\n\n constructor(private readonly host: StrokeSessionHost, readonly init: StrokeSessionInit) {\n this.layerId = init.layerId;\n this.base = init.surface;\n this.live = new Map(this.base.tiles);\n this.copies = init.copies.length ? init.copies : [IDENTITY_COPY];\n const brush = init.brush;\n this.apply = {\n mode: brush.engine === 'eraser' ? 'erase' : 'paint',\n color: init.color,\n background: init.background,\n opacity: brush.tip.opacity,\n blend: brush.tip.blend,\n lockTransparency: init.lockTransparency,\n selection: null,\n offset: init.offset,\n };\n if (brush.engine === 'mixer') {\n this.mixerSmoother = new PenSmoother(brush.tip.smoothing, brush.pressureSmoothing);\n const load = init.mixerLoad;\n for (let i = 0; i < this.copies.length; i++) this.mixers.push(new MixerStroke(mixerTip(brush), brush.mixer, load, this.mixerTarget()));\n } else {\n this.dry = new DryStroke(brush, { grain: init.grain, paperDepth: init.paperDepth, seed: init.seed, copies: this.copies });\n }\n }\n\n private mixerTarget(): MixerTarget {\n return {\n offset: this.init.offset,\n lockTransparency: this.init.lockTransparency,\n selection: null,\n readTile: (tx, ty) => this.live.get(tileKey(tx, ty))?.data ?? null,\n writeTile: (tx, ty) => {\n const key = tileKey(tx, ty);\n if (!this.touched.has(key)) {\n const src = this.base.tiles.get(key)?.data ?? defaultTile(this.base);\n this.live.set(key, { data: new Uint8ClampedArray(src), uniform: null });\n this.touched.add(key);\n }\n this.fresh.add(key);\n return this.live.get(key)!.data;\n },\n };\n }\n\n get open(): boolean {\n return !this.closed;\n }\n\n /** Adds raw pen samples (document pixels). */\n push(points: readonly PenPoint[]): void {\n if (this.closed || !points.length) return;\n const filter = this.init.inputFilter;\n if (filter) points = points.map(filter);\n for (const p of points) this.points.push(p);\n this.lastRaw = points[points.length - 1];\n if (this.dry) this.update(this.dry.push(points));\n else {\n const rects: RasterRect[] = [];\n for (const raw of points) {\n const p = toStrokePoint(this.mixerSmoother!.push(raw));\n this.copies.forEach((c, i) => rects.push(...this.mixers[i].push([toStrokePoint(c.map(p))])));\n }\n this.update(rects);\n }\n }\n\n private update(rects: RasterRect[]): void {\n if (!rects.length) return;\n for (const r of rects) this.bounds = union(this.bounds, r);\n const ch = this.base.channels;\n if (!this.dry) {\n for (const key of this.fresh) this.live.set(key, { data: this.live.get(key)!.data, uniform: null });\n this.fresh.clear();\n this.host.update(this.layerId, new TiledSurface(ch, new Map(this.live), this.base.defaultValue), rects);\n return;\n }\n const off = this.init.offset;\n const regions = new Map<TileKey, { tx: number; ty: number; r: RasterRect }>();\n for (const r of rects) {\n for (const t of tilesInRect({ x: r.x - off.x, y: r.y - off.y, width: r.width, height: r.height })) {\n const key = tileKey(t.tx, t.ty);\n const cur = regions.get(key);\n regions.set(key, { tx: t.tx, ty: t.ty, r: cur ? union(cur.r, r) : r });\n }\n }\n for (const [key, { tx, ty, r }] of regions) {\n const src = this.base.tiles.get(key)?.data ?? defaultTile(this.base);\n const prev = this.touched.has(key) ? this.live.get(key)?.data : undefined;\n this.touched.add(key);\n const data = applyStrokeToTile(this.dry.coverage, src, ch, tx, ty, this.apply, prev ? { into: prev, region: r } : {});\n this.live.set(key, { data, uniform: null });\n }\n this.host.update(this.layerId, new TiledSurface(ch, new Map(this.live), this.base.defaultValue), rects);\n }\n\n /** Ends the stroke (one undo step) and returns what changed. */\n end(): PaintStrokeResult {\n if (this.closed) throw new Error('This stroke has already ended.');\n if (this.dry) this.update(this.dry.finish());\n else {\n const rects: RasterRect[] = [];\n const last = this.lastRaw ? toStrokePoint(this.lastRaw) : undefined;\n this.copies.forEach((c, i) => rects.push(...this.mixers[i].finish(last ? toStrokePoint(c.map(last)) : undefined)));\n this.update(rects);\n }\n this.closed = true;\n const ch = this.base.channels;\n const tiles = new Map(this.base.tiles);\n let changed = false;\n for (const key of this.touched) {\n const tile = finishTile(this.live.get(key)!.data, ch, this.base.defaultValue);\n const prev = this.base.tiles.get(key);\n if (tile) tiles.set(key, tile);\n else tiles.delete(key);\n if (!sameTile(prev, tile)) changed = true;\n }\n const surface = changed ? new TiledSurface(ch, tiles, this.base.defaultValue) : null;\n const dabs = this.dry ? this.dry.dabCount : this.mixers.reduce((n, m) => n + m.dabCount, 0);\n this.result = { layerId: this.layerId, bounds: changed ? this.bounds : null, dabs, strokeId: null };\n if (this.mixers.length) {\n const brush = this.init.brush;\n let load = this.mixers[0].load;\n if (brush.mixer.cleanEachStroke) load = cleanMixer(load);\n this.result.mixerLoad = load;\n }\n this.host.commit(this, surface, false);\n return this.result;\n }\n\n /** Abandons the stroke and restores the layer. */\n cancel(): void {\n if (this.closed) return;\n this.closed = true;\n this.host.commit(this, null, true);\n }\n}\n\n/** The Mixer Brush load a stroke starts with. */\nexport function mixerLoadForStroke(brush: PaintBrush, current: MixerLoad, color: readonly [number, number, number]): MixerLoad {\n if (!brush.loadsColor) return { reservoir: null, amount: 0, pickup: brush.mixer.cleanEachStroke ? null : current.pickup };\n if (brush.mixer.loadEachStroke || !current.reservoir) return loadMixer(current, color);\n return current;\n}\n","/**\n * Strokes as data. Every committed stroke is recorded with the brush, colour, raw pen samples,\n * jitter seed and symmetry copies it was painted with, so it replays to the same pixels, and can\n * be replayed moved, scaled, rotated, recoloured or with another brush (`replay_strokes`).\n */\n\nimport { normalizePaintBrush, type PaintBrushInput, type PaintBrush } from './brushes';\nimport type { Linear2, PenPoint, StrokeCopy } from './engine';\n\n/** An affine map [a, b, c, d, e, f]: (x, y) → (a·x + b·y + e, c·x + d·y + f). */\nexport type Affine = readonly [number, number, number, number, number, number];\n\nexport const IDENTITY_AFFINE: Affine = [1, 0, 0, 1, 0, 0];\n\nexport interface RecordedStroke {\n id: string;\n layerId: string;\n brush: PaintBrush;\n /** #rrggbb */\n color: string;\n /** Raw pen samples in document pixels, before smoothing. */\n points: PenPoint[];\n seed: number;\n /** Extra copies painted with the stroke (mirror / kaleidoscope), as affine maps of the points. */\n copies?: Affine[];\n}\n\nexport function applyAffine(m: Affine, x: number, y: number): { x: number; y: number } {\n return { x: m[0] * x + m[1] * y + m[4], y: m[2] * x + m[3] * y + m[5] };\n}\n\n/** `a ∘ b` (b first). */\nexport function composeAffine(a: Affine, b: Affine): Affine {\n return [\n a[0] * b[0] + a[1] * b[2],\n a[0] * b[1] + a[1] * b[3],\n a[2] * b[0] + a[3] * b[2],\n a[2] * b[1] + a[3] * b[3],\n a[0] * b[4] + a[1] * b[5] + a[4],\n a[2] * b[4] + a[3] * b[5] + a[5],\n ];\n}\n\nexport function invertAffine(m: Affine): Affine {\n const det = m[0] * m[3] - m[1] * m[2];\n if (Math.abs(det) < 1e-12) throw new Error('The transform is not invertible (scale 0?).');\n const a = m[3] / det;\n const b = -m[1] / det;\n const c = -m[2] / det;\n const d = m[0] / det;\n return [a, b, c, d, -(a * m[4] + b * m[5]), -(c * m[4] + d * m[5])];\n}\n\n/** The pen sample mapped by `m` (tilt and twist are kept: they describe the pen, not the path). */\nexport function mapPenPoint(m: Affine, p: PenPoint): PenPoint {\n const q = applyAffine(m, p.x, p.y);\n return { ...p, x: q.x, y: q.y };\n}\n\n/** An affine copy as the engine's `StrokeCopy`. */\nexport function affineCopy(m: Affine): StrokeCopy {\n const linear: Linear2 = [m[0], m[1], m[2], m[3]];\n return { map: (p) => mapPenPoint(m, p), linear };\n}\n\nconst finite = (v: unknown): v is number => typeof v === 'number' && Number.isFinite(v);\n\nfunction readPoint(raw: unknown): PenPoint | null {\n if (!raw || typeof raw !== 'object') return null;\n const r = raw as Record<string, unknown>;\n if (!finite(r.x) || !finite(r.y)) return null;\n const p: PenPoint = { x: r.x, y: r.y };\n for (const k of ['pressure', 't', 'tiltX', 'tiltY', 'altitude', 'azimuth', 'twist'] as const) if (finite(r[k])) p[k] = r[k] as number;\n return p;\n}\n\nfunction readAffine(raw: unknown): Affine | null {\n return Array.isArray(raw) && raw.length === 6 && raw.every(finite) ? (raw as unknown as Affine) : null;\n}\n\n/** A recorded stroke read from JSON, or `null` when it is not one. */\nexport function normalizeBrushStroke(raw: unknown): RecordedStroke | null {\n if (!raw || typeof raw !== 'object') return null;\n const r = raw as Record<string, unknown>;\n if (typeof r.id !== 'string' || typeof r.layerId !== 'string' || !Array.isArray(r.points)) return null;\n const points = r.points.map(readPoint).filter((p): p is PenPoint => p !== null);\n if (!points.length) return null;\n const out: RecordedStroke = {\n id: r.id,\n layerId: r.layerId,\n brush: normalizePaintBrush((r.brush as PaintBrushInput) ?? {}),\n color: typeof r.color === 'string' && /^#[0-9a-f]{6}$/i.test(r.color) ? r.color.toLowerCase() : '#000000',\n points,\n seed: finite(r.seed) ? r.seed | 0 : 0,\n };\n const copies = Array.isArray(r.copies) ? r.copies.map(readAffine).filter((m): m is Affine => m !== null) : [];\n if (copies.length) out.copies = copies;\n return out;\n}\n\n/** The bounding box of a stroke's points. */\nexport function strokeBounds(points: readonly PenPoint[]): { x: number; y: number; width: number; height: number } {\n let x0 = Infinity;\n let y0 = Infinity;\n let x1 = -Infinity;\n let y1 = -Infinity;\n for (const p of points) {\n if (p.x < x0) x0 = p.x;\n if (p.y < y0) y0 = p.y;\n if (p.x > x1) x1 = p.x;\n if (p.y > y1) y1 = p.y;\n }\n return { x: x0, y: y0, width: x1 - x0, height: y1 - y0 };\n}\n\nexport interface StrokeVariation {\n /** Move by this many document pixels (default 0). */\n dx?: number;\n dy?: number;\n /** Scale about the origin (default 1); brush size scales with it. */\n scale?: number;\n /** Rotate about the origin, degrees clockwise (default 0). */\n rotate?: number;\n /** Mirror horizontally about the origin (default false). */\n flipX?: boolean;\n /** The origin for scale, rotate and flip (default: the centre of the strokes' bounds). */\n origin?: { x: number; y: number };\n /** Multiply every pressure by this (default 1). */\n pressureScale?: number;\n}\n\n/** The affine map of a variation about `origin`. */\nexport function variationAffine(v: StrokeVariation, origin: { x: number; y: number }): Affine {\n const s = v.scale ?? 1;\n const a = ((v.rotate ?? 0) * Math.PI) / 180;\n const cos = Math.cos(a) * s;\n const sin = Math.sin(a) * s;\n const fx = v.flipX ? -1 : 1;\n // Translate to the origin, flip, rotate (clockwise with y down) and scale, translate back, move.\n const linear: Affine = [cos * fx, -sin, sin * fx, cos, 0, 0];\n const toOrigin: Affine = [1, 0, 0, 1, -origin.x, -origin.y];\n const back: Affine = [1, 0, 0, 1, origin.x + (v.dx ?? 0), origin.y + (v.dy ?? 0)];\n return composeAffine(back, composeAffine(linear, toOrigin));\n}\n\n/** A stroke varied by `m` (points mapped; symmetry copies conjugated so they stay symmetric). */\nexport function varyStroke(stroke: RecordedStroke, m: Affine, v: StrokeVariation): RecordedStroke {\n const s = Math.sqrt(Math.abs(m[0] * m[3] - m[1] * m[2]));\n const ps = v.pressureScale ?? 1;\n const points = stroke.points.map((p) => {\n const q = mapPenPoint(m, p);\n if (ps !== 1) q.pressure = Math.min(1, Math.max(0, (p.pressure ?? 1) * ps));\n return q;\n });\n const brush = s !== 1 ? normalizePaintBrush({ ...stroke.brush, tip: { ...stroke.brush.tip, size: stroke.brush.tip.size * s } }) : stroke.brush;\n const out: RecordedStroke = { ...stroke, brush, points };\n if (stroke.copies?.length) {\n const inv = invertAffine(m);\n out.copies = stroke.copies.map((c) => composeAffine(m, composeAffine(c, inv)));\n }\n return out;\n}\n","/**\n * Compositing for the paint editor, on the shared `RasterCompositor`: the paper is a content layer\n * at the bottom of the stack (its tiles are generated from the paper settings), and view-only\n * layers (the tracing image) sit between it and the paint. No compositor of our own.\n */\n\nimport { RasterCompositor, type CompositorLayer, type CompositorProfile, type RasterSources } from '../raster/compositor';\nimport type { RasterRect } from '../raster/surface';\nimport type { PaintLayer } from './document';\nimport { PaperGrain, renderPaper, type PaperSettings } from './paper';\n\n/** The paper as a layer of the compositor (generated, never stored). */\nexport interface PaperNode extends CompositorLayer {\n type: 'paper';\n id: string;\n name: string;\n visible: boolean;\n opacity: number;\n blend: 'normal';\n paper: PaperSettings;\n}\n\n/** A view-only RGBA image under the paint (the tracing image), drawn at its opacity. */\nexport interface ImageNode extends CompositorLayer {\n type: 'image';\n id: string;\n name: string;\n visible: boolean;\n opacity: number;\n blend: 'normal';\n /** Canvas-sized RGBA. */\n image: { width: number; height: number; data: Uint8ClampedArray };\n /** Changes when the pixels change. */\n version: number;\n}\n\nexport type ViewLayer = PaintLayer | PaperNode | ImageNode;\n\nexport const PAPER_NODE_ID = '__paper';\nexport const TRACING_NODE_ID = '__tracing';\n\nexport function paperKey(p: PaperSettings): string {\n return JSON.stringify([p.pattern, p.seed, p.color, p.scale, p.tiling, p.shading, p.dry]);\n}\n\nconst paperNodes = new WeakMap<PaperSettings, PaperNode>();\n\n/** The paper as a compositor layer (one object per paper settings object, so caches hold). */\nexport function paperNode(paper: PaperSettings): PaperNode {\n let n = paperNodes.get(paper);\n if (!n) {\n n = { type: 'paper', id: PAPER_NODE_ID, name: 'Paper', visible: true, opacity: 1, blend: 'normal', paper };\n paperNodes.set(paper, n);\n }\n return n;\n}\n\nconst grainCache = new Map<string, PaperGrain>();\nconst tileCache = new Map<string, Uint8ClampedArray>();\n\n/** The paper's dry height field, built once per settings. */\nexport function paperGrain(paper: PaperSettings): PaperGrain {\n const key = JSON.stringify([paper.pattern, paper.seed, paper.scale, paper.tiling, paper.dry]);\n let g = grainCache.get(key);\n if (!g) {\n g = new PaperGrain(paper, 'dry');\n if (grainCache.size > 16) grainCache.delete(grainCache.keys().next().value as string);\n grainCache.set(key, g);\n }\n return g;\n}\n\nfunction paperTile(paper: PaperSettings, r: RasterRect): Uint8ClampedArray {\n const key = `${paperKey(paper)}|${r.x},${r.y},${r.width},${r.height}`;\n let t = tileCache.get(key);\n if (!t) {\n t = renderPaper(paper, r, paperGrain(paper));\n if (tileCache.size > 512) tileCache.delete(tileCache.keys().next().value as string);\n tileCache.set(key, t);\n }\n return t;\n}\n\nconst PROFILE: CompositorProfile<ViewLayer, RasterSources> = {\n contentTile(layer, r) {\n if (layer.type === 'paper') return paperTile((layer as PaperNode).paper, r);\n if (layer.type === 'image') {\n const { image } = layer as ImageNode;\n const out = new Uint8ClampedArray(r.width * r.height * 4);\n const x0 = Math.max(0, r.x);\n const y0 = Math.max(0, r.y);\n const x1 = Math.min(image.width, r.x + r.width);\n const y1 = Math.min(image.height, r.y + r.height);\n if (x1 <= x0 || y1 <= y0) return null;\n for (let y = y0; y < y1; y++) out.set(image.data.subarray((y * image.width + x0) * 4, (y * image.width + x1) * 4), ((y - r.y) * r.width + (x0 - r.x)) * 4);\n return out;\n }\n return null;\n },\n layerKey(layer) {\n if (layer.type === 'paper') return paperKey((layer as PaperNode).paper);\n if (layer.type === 'image') return (layer as ImageNode).version;\n return undefined;\n },\n};\n\n/** A compositor for paint editor stacks (paper and view-only images included). */\nexport function createPaintCompositor(): RasterCompositor<ViewLayer, RasterSources> {\n return new RasterCompositor<ViewLayer, RasterSources>(PROFILE);\n}\n\n/**\n * Area-averaged downscale of straight-alpha RGBA (colours weighted by alpha). Sizes at or above\n * the source copy it.\n */\nexport function downsampleRgba(data: ArrayLike<number>, width: number, height: number, tw: number, th: number): Uint8ClampedArray {\n tw = Math.max(1, Math.round(tw));\n th = Math.max(1, Math.round(th));\n if (tw >= width && th >= height) return Uint8ClampedArray.from(data as ArrayLike<number>);\n const out = new Uint8ClampedArray(tw * th * 4);\n const sx = width / tw;\n const sy = height / th;\n for (let y = 0; y < th; y++) {\n const y0 = y * sy;\n const y1 = y0 + sy;\n for (let x = 0; x < tw; x++) {\n const x0 = x * sx;\n const x1 = x0 + sx;\n let r = 0;\n let g = 0;\n let b = 0;\n let a = 0;\n let w = 0;\n for (let yy = Math.floor(y0); yy < Math.ceil(y1) && yy < height; yy++) {\n const wy = Math.min(y1, yy + 1) - Math.max(y0, yy);\n for (let xx = Math.floor(x0); xx < Math.ceil(x1) && xx < width; xx++) {\n const wgt = wy * (Math.min(x1, xx + 1) - Math.max(x0, xx));\n const i = (yy * width + xx) * 4;\n const al = data[i + 3] * wgt;\n r += data[i] * al;\n g += data[i + 1] * al;\n b += data[i + 2] * al;\n a += al;\n w += wgt;\n }\n }\n const o = (y * tw + x) * 4;\n if (a > 0) {\n out[o] = r / a;\n out[o + 1] = g / a;\n out[o + 2] = b / a;\n }\n out[o + 3] = w > 0 ? a / w : 0;\n }\n }\n return out;\n}\n","/**\n * Saved paint documents: JSON plus PNG assets. Layers go through the image editor's layer\n * serializer (`serializeLayers` / `deserializeLayers`), so pixel layers and groups are stored the\n * same way in both editors, including external asset stores. The paper is plain settings: it is\n * regenerated on load, never stored as pixels.\n *\n * Forward compatibility: readers keep fields they do not know at the top level (`extensions`) and\n * write them back, so a later version can add per-layer wet state, height or material channels\n * as new assets keyed by layer id without breaking older readers (see `PaintDocumentExtensions`).\n */\n\nimport {\n deserializeLayers,\n resolveExternalAssets,\n serializeLayers,\n serializeLayersExternal,\n type ImageEditorAssetStore,\n type SerializedLayer,\n} from '../image-editor/layers/serialize';\nimport type { ImageLayer } from '../image-editor/layers/model';\nimport { findLayer, flattenLayers } from '../raster/layers';\nimport { normalizeBrushStroke, type RecordedStroke } from './strokes';\nimport { normalizeCanvas, type PaintDocumentState, type PaintLayer } from './document';\nimport { normalizePaper, type PaperSettings } from './paper';\n\nexport const PAINT_FORMAT = 'pixerate-paint' as const;\nexport const PAINT_SCHEMA_VERSION = 1 as const;\n\n/** Where a host keeps layer PNGs outside the JSON (the image editor's asset store contract). */\nexport type PaintAssetStore = ImageEditorAssetStore;\n\n/**\n * Fields a later version adds. Phase 1 writes none of them and keeps any it reads. Planned:\n * `layerChannels: { [layerId]: { height?: asset, material?: asset } }` for impasto and\n * metallic paint. Wet paint is never saved (saving dries it), so there is no wet field.\n */\nexport type PaintDocumentExtensions = Record<string, unknown>;\n\nexport interface SerializedPaintDocument {\n format: typeof PAINT_FORMAT;\n version: typeof PAINT_SCHEMA_VERSION;\n width: number;\n height: number;\n dpi: number;\n paper: PaperSettings;\n /** Bottom to top: pixel layers and groups, as the image editor stores them. */\n layers: SerializedLayer[];\n /** Asset id → PNG data URL (or an external reference). */\n assets: Record<string, string>;\n activeLayerId: string | null;\n /** Recorded strokes (strokes are data), oldest first; missing when saved without them. */\n strokes?: RecordedStroke[];\n /** Everything else (document-level state of later phases), written back as read. */\n [extension: string]: unknown;\n}\n\nconst KNOWN = new Set(['format', 'version', 'width', 'height', 'dpi', 'paper', 'layers', 'assets', 'activeLayerId', 'strokes', 'guides', 'swatches']);\n\n/** Fields of a saved document this version does not read, kept for writing back. */\nexport function documentExtensions(raw: Record<string, unknown>): PaintDocumentExtensions {\n const out: PaintDocumentExtensions = {};\n for (const [k, v] of Object.entries(raw)) if (!KNOWN.has(k)) out[k] = v;\n return out;\n}\n\nexport interface SerializeOptions {\n /** Include the recorded strokes (default true). */\n strokes?: boolean;\n /** Later-phase fields to write as they were read. */\n extensions?: PaintDocumentExtensions;\n /** Painting guides (symmetry, perspective, tracing and reference images as PNG data URLs). */\n guides?: unknown;\n swatches?: unknown;\n}\n\nfunction header(state: PaintDocumentState, options: SerializeOptions): Omit<SerializedPaintDocument, 'layers' | 'assets'> {\n const out: Omit<SerializedPaintDocument, 'layers' | 'assets'> = {\n ...(options.extensions ?? {}),\n format: PAINT_FORMAT,\n version: PAINT_SCHEMA_VERSION,\n width: state.canvas.width,\n height: state.canvas.height,\n dpi: state.canvas.dpi,\n paper: { ...state.paper, dry: { ...state.paper.dry }, wet: { ...state.paper.wet } },\n activeLayerId: state.activeLayerId,\n };\n if (options.strokes !== false && state.strokes.length) out.strokes = JSON.parse(JSON.stringify(state.strokes));\n if (options.guides !== undefined) out.guides = JSON.parse(JSON.stringify(options.guides));\n if (options.swatches !== undefined) out.swatches = JSON.parse(JSON.stringify(options.swatches));\n return out;\n}\n\n/** The document as JSON with inline PNG data URLs. */\nexport function serializePaintDocument(state: PaintDocumentState, options: SerializeOptions = {}): SerializedPaintDocument {\n const { layers, assets } = serializeLayers(state.layers as unknown as ImageLayer[]);\n return { ...header(state, options), layers, assets } as SerializedPaintDocument;\n}\n\n/** The document as JSON with each PNG uploaded to `store` once (by content). */\nexport async function serializePaintDocumentExternal(state: PaintDocumentState, store: PaintAssetStore, options: SerializeOptions = {}): Promise<SerializedPaintDocument> {\n const { layers, assets } = await serializeLayersExternal(state.layers as unknown as ImageLayer[], store);\n return { ...header(state, options), layers, assets } as SerializedPaintDocument;\n}\n\nexport interface LoadedPaintDocument {\n state: PaintDocumentState;\n extensions: PaintDocumentExtensions;\n /** The saved guides and swatches, as stored (the controller validates them). */\n guides?: unknown;\n swatches?: unknown;\n /** What could not be read (the rest still loads). */\n problems: string[];\n}\n\n/** Keeps pixel layers and groups (the paint editor's kinds); reports and drops the rest. */\nfunction paintLayersOnly(layers: ImageLayer[], problems: string[]): PaintLayer[] {\n const out: PaintLayer[] = [];\n for (const l of layers) {\n if (l.type === 'pixel') {\n const { filters, source, ...rest } = l;\n if (filters?.length) problems.push(`Layer \"${l.name}\": its filters are an image editor feature and were dropped.`);\n if (source) problems.push(`Layer \"${l.name}\" refers to an image editor source image; it loads empty.`);\n out.push(rest as PaintLayer);\n } else if (l.type === 'group') out.push({ ...l, children: paintLayersOnly(l.children, problems) } as PaintLayer);\n else problems.push(`Layer \"${l.name}\" is an image editor ${l.type} layer, which the paint editor does not have; it was left out.`);\n }\n return out;\n}\n\nfunction readStrokes(raw: unknown, problems: string[]): RecordedStroke[] {\n if (!Array.isArray(raw)) return [];\n const out: RecordedStroke[] = [];\n raw.forEach((s, i) => {\n const stroke = normalizeBrushStroke(s);\n if (stroke) out.push(stroke);\n else problems.push(`strokes[${i}] is not a recorded stroke; skipped.`);\n });\n return out;\n}\n\n/** Reads a saved document with inline assets. Throws when it is not a paint document at all. */\nexport function deserializePaintDocument(raw: unknown): LoadedPaintDocument {\n if (!raw || typeof raw !== 'object') throw new Error('Not a paint document: expected a JSON object.');\n const r = raw as Record<string, unknown>;\n if (r.format !== PAINT_FORMAT) throw new Error(`Not a paint document: format is ${JSON.stringify(r.format)}, expected \"${PAINT_FORMAT}\".`);\n if (typeof r.version !== 'number' || r.version > PAINT_SCHEMA_VERSION) {\n throw new Error(`Paint document version ${JSON.stringify(r.version)} is newer than this editor reads (${PAINT_SCHEMA_VERSION}); update @pixerate/editor.`);\n }\n const problems: string[] = [];\n const canvas = normalizeCanvas({ width: r.width as number, height: r.height as number, dpi: (r.dpi as number | undefined) ?? undefined });\n const paper = normalizePaper((r.paper as Record<string, unknown>) ?? {});\n const assets = r.assets && typeof r.assets === 'object' ? (r.assets as Record<string, string>) : {};\n const layers = paintLayersOnly(deserializeLayers(r.layers, { assets, problems }), problems);\n const wanted = typeof r.activeLayerId === 'string' ? r.activeLayerId : null;\n const activeLayerId = wanted && findLayer(layers, wanted) ? wanted : (flattenLayers(layers).filter((l) => l.type === 'pixel').pop()?.id ?? null);\n return { state: { canvas, paper, layers, activeLayerId, strokes: readStrokes(r.strokes, problems) }, extensions: documentExtensions(r), guides: r.guides, swatches: r.swatches, problems };\n}\n\n/** Reads a saved document whose assets may be external references in `store`. */\nexport async function deserializePaintDocumentAsync(raw: unknown, store?: PaintAssetStore): Promise<LoadedPaintDocument> {\n if (!raw || typeof raw !== 'object') throw new Error('Not a paint document: expected a JSON object.');\n const r = raw as Record<string, unknown>;\n const problems: string[] = [];\n const assets = await resolveExternalAssets((r.assets as Record<string, string>) ?? {}, store, problems);\n const loaded = deserializePaintDocument({ ...r, assets });\n return { ...loaded, problems: [...problems, ...loaded.problems] };\n}\n","/**\n * The canvas view: zoom, pan, rotation and mirroring. View state only: the pixels never resample,\n * the view maps document pixels to the screen and pointer positions back.\n */\n\nimport type { Affine } from './strokes';\nimport { applyAffine, invertAffine } from './strokes';\n\nexport interface PaintView {\n /** Screen pixels per document pixel (0.02..64, default 1). */\n zoom: number;\n /** Offset of the canvas centre from the viewport centre, in screen pixels. */\n pan: { x: number; y: number };\n /** Rotation in degrees clockwise, -180..180 (default 0). */\n rotation: number;\n /** Mirror the view left to right (default false). */\n mirror: boolean;\n}\n\nexport const MIN_ZOOM = 0.02;\nexport const MAX_ZOOM = 64;\n\nexport const DEFAULT_VIEW: Readonly<PaintView> = { zoom: 1, pan: { x: 0, y: 0 }, rotation: 0, mirror: false };\n\n/** Degrees into -180..180. */\nexport function normalizeRotation(deg: number): number {\n if (!Number.isFinite(deg)) return 0;\n let r = deg % 360;\n if (r > 180) r -= 360;\n if (r <= -180) r += 360;\n return Math.round(r * 1000) / 1000;\n}\n\nexport function normalizeView(raw: Partial<PaintView>, base: PaintView = DEFAULT_VIEW): PaintView {\n const zoom = typeof raw.zoom === 'number' && Number.isFinite(raw.zoom) ? Math.min(MAX_ZOOM, Math.max(MIN_ZOOM, raw.zoom)) : base.zoom;\n const pan = raw.pan && Number.isFinite(raw.pan.x) && Number.isFinite(raw.pan.y) ? { x: raw.pan.x, y: raw.pan.y } : { ...base.pan };\n return {\n zoom,\n pan,\n rotation: typeof raw.rotation === 'number' ? normalizeRotation(raw.rotation) : base.rotation,\n mirror: typeof raw.mirror === 'boolean' ? raw.mirror : base.mirror,\n };\n}\n\n/**\n * Document → screen for a canvas of `canvas` size shown in a viewport of `viewport` size:\n * the canvas centre goes to the viewport centre plus `pan`, then zoom, rotation and mirroring\n * apply about it.\n */\nexport function viewMatrix(view: PaintView, canvas: { width: number; height: number }, viewport: { width: number; height: number }): Affine {\n const a = (view.rotation * Math.PI) / 180;\n const z = view.zoom;\n const m = view.mirror ? -1 : 1;\n const cos = Math.cos(a) * z;\n const sin = Math.sin(a) * z;\n // Screen = C + R(θ) · M · z · (p − c), with y down (clockwise rotation).\n const cx = canvas.width / 2;\n const cy = canvas.height / 2;\n const sx = viewport.width / 2 + view.pan.x;\n const sy = viewport.height / 2 + view.pan.y;\n const A = cos * m;\n const B = -sin;\n const C = sin * m;\n const D = cos;\n return [A, B, C, D, sx - (A * cx + B * cy), sy - (C * cx + D * cy)];\n}\n\n/** Screen position → document position. */\nexport function screenToDocument(view: PaintView, canvas: { width: number; height: number }, viewport: { width: number; height: number }, x: number, y: number): { x: number; y: number } {\n return applyAffine(invertAffine(viewMatrix(view, canvas, viewport)), x, y);\n}\n\n/** Document position → screen position. */\nexport function documentToScreen(view: PaintView, canvas: { width: number; height: number }, viewport: { width: number; height: number }, x: number, y: number): { x: number; y: number } {\n return applyAffine(viewMatrix(view, canvas, viewport), x, y);\n}\n\n/** A CSS `matrix(...)` for an element of the canvas size placed at the viewport's top-left. */\nexport function viewCssTransform(view: PaintView, canvas: { width: number; height: number }, viewport: { width: number; height: number }): string {\n const m = viewMatrix(view, canvas, viewport);\n const f = (v: number) => Math.round(v * 10000) / 10000;\n return `matrix(${f(m[0])}, ${f(m[2])}, ${f(m[1])}, ${f(m[3])}, ${f(m[4])}, ${f(m[5])})`;\n}\n\n/** The zoom that fits the canvas in the viewport (with `margin` screen pixels around it). */\nexport function fitZoom(canvas: { width: number; height: number }, viewport: { width: number; height: number }, margin = 24): number {\n const w = Math.max(1, viewport.width - 2 * margin);\n const h = Math.max(1, viewport.height - 2 * margin);\n return Math.min(MAX_ZOOM, Math.max(MIN_ZOOM, Math.min(w / canvas.width, h / canvas.height)));\n}\n\n/**\n * Pen rotation as the document sees it: a rotated or mirrored view turns the pen's azimuth and\n * barrel rotation too, so a tilted pencil shades the same way on screen however the canvas is turned.\n */\nexport function viewPenToDocument<P extends { azimuth?: number; twist?: number }>(view: PaintView, p: P): P {\n if (!view.rotation && !view.mirror) return p;\n const out = { ...p };\n const r = (view.rotation * Math.PI) / 180;\n if (typeof p.azimuth === 'number') {\n let a = p.azimuth - r;\n if (view.mirror) a = Math.PI - a;\n out.azimuth = ((a % (2 * Math.PI)) + 2 * Math.PI) % (2 * Math.PI);\n }\n if (typeof p.twist === 'number') {\n let t = p.twist - view.rotation;\n if (view.mirror) t = -t;\n out.twist = ((t % 360) + 360) % 360;\n }\n return out;\n}\n","/**\n * Pen input helpers for the bindings: Pointer Events (structurally typed, no DOM import) into\n * `PenPoint`s, palm rejection by hand, and which hand the user draws with. The bindings feed\n * coalesced events into the stroke and draw predicted ones as a throwaway preview.\n */\n\nimport { penOrientation, type PenPoint } from './engine';\nimport { viewPenToDocument, type PaintView } from './view';\n\n/** The Pointer Event fields the paint editor reads. */\nexport interface PointerSample {\n pointerType?: string;\n pressure?: number;\n tiltX?: number;\n tiltY?: number;\n /** Radians (Pointer Events Level 3). */\n altitudeAngle?: number;\n azimuthAngle?: number;\n /** Degrees 0..359. */\n twist?: number;\n timeStamp?: number;\n}\n\n/** Which hand holds the pen: palm rejection ignores touches on that side of it. */\nexport type Hand = 'right' | 'left';\n\n/**\n * Pressure of a pointer sample: pens report it; mice report 0.5 while pressed and pens 0 on\n * `pointerup`, both of which mean \"use full\" (see GOTCHAS).\n */\nexport function samplePressure(e: PointerSample): number {\n if (e.pointerType === 'pen' && typeof e.pressure === 'number' && e.pressure > 0) return Math.min(1, e.pressure);\n return 1;\n}\n\n/**\n * A pointer sample at document position (x, y) as a pen point. Only pens report tilt and twist;\n * a pen's lean and barrel rotation are turned with the view, so marks look the same on screen\n * whatever the canvas rotation and mirroring.\n */\nexport function pointerToPenPoint(e: PointerSample, x: number, y: number, view?: PaintView): PenPoint {\n const p: PenPoint = { x, y, pressure: samplePressure(e) };\n if (typeof e.timeStamp === 'number' && Number.isFinite(e.timeStamp)) p.t = e.timeStamp;\n if (e.pointerType !== 'pen') return p;\n const o = penOrientation({\n x,\n y,\n altitude: typeof e.altitudeAngle === 'number' ? e.altitudeAngle : undefined,\n azimuth: typeof e.azimuthAngle === 'number' ? e.azimuthAngle : undefined,\n tiltX: e.tiltX,\n tiltY: e.tiltY,\n });\n // A pen standing straight up with no tilt reported keeps no orientation (most pens without tilt report 0, 0).\n if (o && o.altitude < Math.PI / 2 - 1e-6) {\n p.altitude = o.altitude;\n p.azimuth = o.azimuth;\n }\n if (typeof e.twist === 'number' && Number.isFinite(e.twist) && e.twist !== 0) p.twist = e.twist;\n return view ? viewPenToDocument(view, p) : p;\n}\n\n/**\n * Palm rejection: whether a touch at `touch` (screen pixels) is probably the drawing hand resting\n * on the screen while the pen is at `pen`. A right hand rests below and to the right of the pen, a\n * left hand below and to the left.\n */\nexport function isPalmTouch(touch: { x: number; y: number }, pen: { x: number; y: number } | null, hand: Hand): boolean {\n if (!pen) return false;\n const dx = touch.x - pen.x;\n const dy = touch.y - pen.y;\n const side = hand === 'right' ? dx : -dx;\n return dy > -40 && side > -40 && Math.hypot(dx, dy) < 600;\n}\n","/**\n * JPEG and WebP encoding. PNG is encoded in pure TypeScript (`encodePng`); the lossy formats need\n * the platform's codecs, so they go through an `OffscreenCanvas` (browsers and Workers) or a host\n * encoder. Nothing is imported: the globals are looked up at call time.\n */\n\nexport type ImageFormat = 'image/png' | 'image/jpeg' | 'image/webp';\n\n/** Encodes straight-alpha RGBA as `format` at `quality` (0..1). */\nexport type ImageEncoder = (image: { width: number; height: number; data: Uint8ClampedArray }, format: 'image/jpeg' | 'image/webp', quality: number) => Promise<Uint8Array>;\n\ninterface CanvasLike {\n getContext(type: '2d'): { putImageData(data: unknown, x: number, y: number): void } | null;\n convertToBlob(options: { type: string; quality: number }): Promise<{ arrayBuffer(): Promise<ArrayBuffer>; type: string }>;\n}\n\n/** An encoder through `OffscreenCanvas`, or `null` where there is none (Node, tests). */\nexport function defaultImageEncoder(): ImageEncoder | null {\n const g = globalThis as unknown as {\n OffscreenCanvas?: new (w: number, h: number) => CanvasLike;\n ImageData?: new (data: Uint8ClampedArray, w: number, h: number) => unknown;\n };\n if (typeof g.OffscreenCanvas !== 'function' || typeof g.ImageData !== 'function') return null;\n const Canvas = g.OffscreenCanvas;\n const Data = g.ImageData;\n return async (image, format, quality) => {\n const canvas = new Canvas(image.width, image.height);\n const ctx = canvas.getContext('2d');\n if (!ctx) throw new Error('No 2D context to encode with.');\n ctx.putImageData(new Data(new Uint8ClampedArray(image.data), image.width, image.height), 0, 0);\n const blob = await canvas.convertToBlob({ type: format, quality });\n if (blob.type !== format) throw new Error(`This browser cannot encode ${format} (it produced ${blob.type || 'nothing'}); export PNG instead.`);\n return new Uint8Array(await blob.arrayBuffer());\n };\n}\n\n/**\n * Decodes an image file (PNG, JPEG, WebP, … whatever the browser reads) into RGBA pixels through\n * `createImageBitmap` and an `OffscreenCanvas`. Browser and Worker only.\n */\nexport async function decodeImageBlob(blob: Blob): Promise<{ width: number; height: number; data: Uint8ClampedArray }> {\n const g = globalThis as unknown as {\n createImageBitmap?: (b: Blob) => Promise<{ width: number; height: number; close?(): void }>;\n OffscreenCanvas?: new (w: number, h: number) => { getContext(type: '2d'): { drawImage(img: unknown, x: number, y: number): void; getImageData(x: number, y: number, w: number, h: number): { data: Uint8ClampedArray } } | null };\n };\n if (typeof g.createImageBitmap !== 'function' || typeof g.OffscreenCanvas !== 'function') throw new Error('Decoding images needs a browser (createImageBitmap and OffscreenCanvas).');\n const bitmap = await g.createImageBitmap(blob);\n const canvas = new g.OffscreenCanvas(bitmap.width, bitmap.height);\n const ctx = canvas.getContext('2d');\n if (!ctx) throw new Error('No 2D context to decode with.');\n ctx.drawImage(bitmap, 0, 0);\n const data = new Uint8ClampedArray(ctx.getImageData(0, 0, bitmap.width, bitmap.height).data);\n bitmap.close?.();\n return { width: bitmap.width, height: bitmap.height, data };\n}\n\n/** Saves bytes as a file through a temporary link. Browser only. */\nexport function downloadBytes(bytes: Uint8Array | string, fileName: string, mimeType: string): void {\n const g = globalThis as unknown as {\n document?: { createElement(tag: 'a'): { href: string; download: string; click(): void } };\n URL?: { createObjectURL(b: Blob): string; revokeObjectURL(u: string): void };\n Blob?: new (parts: unknown[], options: { type: string }) => Blob;\n };\n if (!g.document || !g.URL || !g.Blob) throw new Error('Downloading needs a browser.');\n const url = g.URL.createObjectURL(new g.Blob([bytes], { type: mimeType }));\n const a = g.document.createElement('a');\n a.href = url;\n a.download = fileName;\n a.click();\n setTimeout(() => g.URL!.revokeObjectURL(url), 1000);\n}\n","/**\n * Brush thumbnails: a test stroke (an S-curve with pressure swelling and fading, at a steady\n * speed) painted with the brush on the paper. Brushes that only move paint (blender, smudge) are\n * shown dragged across two bands of colour. Pure TypeScript, so thumbnails render in Node too.\n */\n\nimport { EMPTY_MIXER_LOAD } from '../paint/mixer';\nimport { emptySurface, fillRect, type TiledSurface } from '../raster/surface';\nimport { normalizePaintBrush, type PaintBrush } from './brushes';\nimport type { PenPoint } from './engine';\nimport { IDENTITY_COPY } from './engine';\nimport { hexToRgb8, type PaperSettings } from './paper';\nimport { createPaintCompositor, paperGrain, paperNode, type ViewLayer } from './render';\nimport { mixerLoadForStroke, PaintStrokeSession } from './stroke';\n\nexport interface BrushThumbnail {\n width: number;\n height: number;\n /** RGBA, opaque (the paper is under the stroke). */\n data: Uint8ClampedArray;\n}\n\n/** The test stroke's samples for a `width × height` thumbnail. */\nexport function thumbnailStroke(width: number, height: number): PenPoint[] {\n const pts: PenPoint[] = [];\n const n = 64;\n const mx = width * 0.1;\n const my = height * 0.5;\n for (let i = 0; i <= n; i++) {\n const t = i / n;\n const pressure = t < 0.5 ? 0.15 + 1.7 * t : 1 - 1.4 * (t - 0.5);\n pts.push({ x: mx + (width - 2 * mx) * t, y: my - Math.sin(t * Math.PI * 2) * height * 0.22, pressure, t: i * 12 });\n }\n return pts;\n}\n\n/** Paints the test stroke with `brush` onto `surface`; returns the new pixels. */\nfunction paintTestStroke(surface: TiledSurface, brush: PaintBrush, paper: PaperSettings, color: string, width: number, height: number): TiledSurface {\n const [r, g, b] = hexToRgb8(color);\n let result = surface;\n const session = new PaintStrokeSession(\n { update: () => {}, commit: (_s, s) => (result = s ?? result) },\n {\n layerId: 'thumbnail',\n surface,\n offset: { x: 0, y: 0 },\n lockTransparency: false,\n brush,\n color: [r, g, b, 255],\n background: [...hexToRgb8(paper.color), 255],\n grain: paperGrain(paper),\n paperDepth: paper.depth,\n seed: 7,\n colorHex: color,\n affineCopies: [],\n copies: [IDENTITY_COPY],\n mixerLoad: brush.engine === 'mixer' ? mixerLoadForStroke(brush, EMPTY_MIXER_LOAD, [r / 255, g / 255, b / 255]) : EMPTY_MIXER_LOAD,\n }\n );\n session.push(thumbnailStroke(width, height));\n session.end();\n return result;\n}\n\nexport function renderBrushThumbnail(brush: PaintBrush, options: { paper: PaperSettings; width?: number; height?: number; color: string }): BrushThumbnail {\n const width = Math.max(16, Math.min(512, Math.round(options.width ?? 160)));\n const height = Math.max(16, Math.min(512, Math.round(options.height ?? 48)));\n // Fit the tip in the thumbnail: big brushes are drawn smaller.\n const maxSize = height * 0.42;\n const b = brush.tip.size > maxSize ? normalizePaintBrush({ tip: { ...brush.tip, size: maxSize } }, brush) : brush;\n const rgba = [...hexToRgb8(options.color), 255];\n let surface: TiledSurface = emptySurface(4);\n if (b.engine === 'eraser') {\n // Something to erase: a band of the colour.\n surface = fillRect(surface, { x: 0, y: 0, width, height }, rgba);\n } else if (b.engine === 'mixer' && !b.loadsColor) {\n // Something to move: two bands, the colour over ochre.\n const half = Math.ceil(height / 2);\n surface = fillRect(surface, { x: 0, y: 0, width, height: half }, rgba);\n surface = fillRect(surface, { x: 0, y: half, width, height: height - half }, [232, 196, 64, 255]);\n }\n surface = paintTestStroke(surface, b, options.paper, options.color, width, height);\n const layer: ViewLayer = { type: 'pixel', id: 'thumbnail', name: 'thumbnail', visible: true, opacity: 1, blend: 'normal', surface, offset: { x: 0, y: 0 } };\n const data = createPaintCompositor().composite([paperNode(options.paper), layer], { x: 0, y: 0, width, height }, { width, height });\n return { width, height, data };\n}\n","// Portions ported from photocraft/crates/paint/src/symmetry.rs (MIT OR Apache-2.0, © ArtCraft Team and contributors). See THIRD_PARTY_NOTICES.md.\n\n/**\n * Painting guides: mirror and kaleidoscope symmetry (every stroke paints its reflected or rotated\n * copies as one stroke), perspective guides with one to three vanishing points that strokes snap\n * to, a tracing image under the paint (optionally the source of the stroke colour), and floating\n * reference images to pick colours from. Geometry only: no pixels, no DOM.\n */\n\nimport { composeAffine, type Affine } from './strokes';\n\nexport type SymmetryMode = 'off' | 'vertical' | 'horizontal' | 'dual' | 'diagonal' | 'kaleidoscope';\n\nexport const SYMMETRY_MODES: readonly SymmetryMode[] = ['off', 'vertical', 'horizontal', 'dual', 'diagonal', 'kaleidoscope'];\n\nexport interface SymmetryGuide {\n mode: SymmetryMode;\n /** Centre of the axes in document pixels (default the canvas centre). */\n center: { x: number; y: number };\n /** Turns the axes, degrees clockwise (default 0). */\n rotation: number;\n /** Kaleidoscope: number of segments, 2..32 (default 6). */\n segments: number;\n /** Kaleidoscope: reflect every other segment as well as rotating (default true), like a real kaleidoscope. */\n mirror: boolean;\n}\n\nexport interface Point2 {\n x: number;\n y: number;\n}\n\nexport interface PerspectiveGuide {\n enabled: boolean;\n /** One to three vanishing points in document pixels (they may lie outside the canvas). */\n points: Point2[];\n /** Strokes snap to the guide lines (default true when enabled). */\n snap: boolean;\n}\n\n/** A view-only image under the paint, placed over the canvas. */\nexport interface TracingImage {\n /** PNG or JPEG data URL. */\n src: string;\n /** Natural size of the image in pixels. */\n width: number;\n height: number;\n /** Where it is drawn, in document pixels (default: fitted to the canvas). */\n rect: { x: number; y: number; width: number; height: number };\n /** 0..1 (default 0.35). */\n opacity: number;\n visible: boolean;\n /** Strokes without an explicit colour take the tracing image's colour where they start. */\n sampleColors: boolean;\n}\n\n/** A floating image to look at and pick colours from (shown beside the canvas, never painted). */\nexport interface ReferenceImage {\n id: string;\n name: string;\n src: string;\n width: number;\n height: number;\n /** Where the panel floats over the viewport, in screen pixels, and its displayed width. */\n x: number;\n y: number;\n displayWidth: number;\n visible: boolean;\n}\n\nexport interface PaintGuides {\n symmetry: SymmetryGuide;\n perspective: PerspectiveGuide;\n tracing: TracingImage | null;\n references: ReferenceImage[];\n}\n\nexport function defaultGuides(canvas: { width: number; height: number }): PaintGuides {\n return {\n symmetry: { mode: 'off', center: { x: canvas.width / 2, y: canvas.height / 2 }, rotation: 0, segments: 6, mirror: true },\n perspective: { enabled: false, points: [], snap: true },\n tracing: null,\n references: [],\n };\n}\n\nexport const MAX_COORDINATE = 1_000_000;\nconst finite = (v: unknown): v is number => typeof v === 'number' && Number.isFinite(v);\nconst coord = (v: unknown, d: number) => (finite(v) && Math.abs(v) <= MAX_COORDINATE ? v : d);\n\nexport function normalizeSymmetry(raw: Partial<SymmetryGuide> | Record<string, unknown>, base: SymmetryGuide): SymmetryGuide {\n const r = raw as Record<string, unknown>;\n const c = (r.center ?? {}) as Record<string, unknown>;\n return {\n mode: SYMMETRY_MODES.includes(r.mode as SymmetryMode) ? (r.mode as SymmetryMode) : base.mode,\n center: { x: coord(c.x, base.center.x), y: coord(c.y, base.center.y) },\n rotation: finite(r.rotation) ? ((r.rotation % 360) + 360) % 360 : base.rotation,\n segments: finite(r.segments) ? Math.min(32, Math.max(2, Math.round(r.segments))) : base.segments,\n mirror: typeof r.mirror === 'boolean' ? r.mirror : base.mirror,\n };\n}\n\n/** Reflection across the line through `c` in direction angle `a` (radians, clockwise with y down). */\nfunction reflectAbout(c: Point2, a: number): Affine {\n const dx = Math.cos(a);\n const dy = Math.sin(a);\n // 2·d·dᵀ − I, conjugated by the translation to the centre.\n const m00 = 2 * dx * dx - 1;\n const m01 = 2 * dx * dy;\n const m11 = 2 * dy * dy - 1;\n return [m00, m01, m01, m11, c.x - (m00 * c.x + m01 * c.y), c.y - (m01 * c.x + m11 * c.y)];\n}\n\n/** Rotation by `a` radians (clockwise with y down) about `c`. */\nfunction rotateAbout(c: Point2, a: number): Affine {\n const cos = Math.cos(a);\n const sin = Math.sin(a);\n return [cos, -sin, sin, cos, c.x - (cos * c.x - sin * c.y), c.y - (sin * c.x + cos * c.y)];\n}\n\nconst rad = (deg: number) => (deg * Math.PI) / 180;\n\n/** The axis directions of a mirror mode (radians), as photocraft's `directions`. */\nexport function symmetryAxisAngles(g: SymmetryGuide): number[] {\n if (g.mode === 'off') return [];\n if (g.mode === 'kaleidoscope') return Array.from({ length: g.segments }, (_, k) => rad(g.rotation) + (k * Math.PI) / g.segments);\n const initial = g.mode === 'horizontal' ? 0 : g.mode === 'diagonal' ? 45 : 90;\n const a = rad(initial + g.rotation);\n return g.mode === 'dual' ? [a, a + Math.PI / 2] : [a];\n}\n\n/**\n * The extra copies a stroke paints under the symmetry guide, as affine maps (the stroke itself is\n * not included). Vertical, horizontal and diagonal: one reflection. Dual: two reflections and the\n * point reflection. Kaleidoscope: rotations by 360°/n, and with `mirror` the reflections between them.\n */\nexport function symmetryCopies(g: SymmetryGuide): Affine[] {\n const c = g.center;\n switch (g.mode) {\n case 'off':\n return [];\n case 'vertical':\n case 'horizontal':\n case 'diagonal':\n return symmetryAxisAngles(g).map((a) => reflectAbout(c, a));\n case 'dual': {\n const [a, b] = symmetryAxisAngles(g);\n return [reflectAbout(c, a), reflectAbout(c, b), rotateAbout(c, Math.PI)];\n }\n case 'kaleidoscope': {\n const out: Affine[] = [];\n const n = g.segments;\n for (let k = 1; k < n; k++) out.push(rotateAbout(c, (2 * Math.PI * k) / n));\n if (g.mirror) {\n const first = reflectAbout(c, rad(g.rotation));\n for (let k = 0; k < n; k++) out.push(composeAffine(rotateAbout(c, (2 * Math.PI * k) / n), first));\n }\n return out;\n }\n }\n}\n\n/** The axes clipped to the canvas, for drawing (photocraft's `segments`). */\nexport function symmetryAxisSegments(g: SymmetryGuide, size: { width: number; height: number }): Array<[Point2, Point2]> {\n const out: Array<[Point2, Point2]> = [];\n for (const a of symmetryAxisAngles(g)) {\n const d = [Math.cos(a), Math.sin(a)];\n const origin = [g.center.x, g.center.y];\n const extent = [size.width, size.height];\n let lo = -Infinity;\n let hi = Infinity;\n let ok = true;\n for (let i = 0; i < 2; i++) {\n if (Math.abs(d[i]) < 1e-12) {\n if (origin[i] < 0 || origin[i] > extent[i]) ok = false;\n } else {\n const t0 = -origin[i] / d[i];\n const t1 = (extent[i] - origin[i]) / d[i];\n lo = Math.max(lo, Math.min(t0, t1));\n hi = Math.min(hi, Math.max(t0, t1));\n }\n }\n if (!ok || !Number.isFinite(lo) || !Number.isFinite(hi) || hi < lo) continue;\n out.push([{ x: g.center.x + lo * d[0], y: g.center.y + lo * d[1] }, { x: g.center.x + hi * d[0], y: g.center.y + hi * d[1] }]);\n }\n return out;\n}\n\n// ---------------------------------------------------------------------------\n// Perspective\n// ---------------------------------------------------------------------------\n\nexport function normalizePerspective(raw: Partial<PerspectiveGuide> | Record<string, unknown>, base: PerspectiveGuide): PerspectiveGuide {\n const r = raw as Record<string, unknown>;\n let points = base.points;\n if (Array.isArray(r.points)) {\n if (r.points.length > 3) throw new Error(`A perspective guide has one to three vanishing points; got ${r.points.length}.`);\n points = r.points.map((p, i) => {\n const q = (p ?? {}) as Record<string, unknown>;\n if (!finite(q.x) || !finite(q.y) || Math.abs(q.x) > MAX_COORDINATE || Math.abs(q.y) > MAX_COORDINATE) {\n throw new Error(`points[${i}] needs finite x and y within ±${MAX_COORDINATE} document pixels.`);\n }\n return { x: q.x, y: q.y };\n });\n }\n const enabled = typeof r.enabled === 'boolean' ? r.enabled : base.enabled;\n if (enabled && !points.length) throw new Error('An enabled perspective guide needs at least one vanishing point; pass points.');\n return { enabled, points, snap: typeof r.snap === 'boolean' ? r.snap : base.snap };\n}\n\n/** The line families a perspective guide snaps to at `p`: unit directions. */\nexport function perspectiveDirections(g: PerspectiveGuide, p: Point2): Point2[] {\n const out: Point2[] = [];\n for (const v of g.points) {\n const dx = v.x - p.x;\n const dy = v.y - p.y;\n const len = Math.hypot(dx, dy);\n if (len > 1e-6) out.push({ x: dx / len, y: dy / len });\n }\n // One-point perspective keeps true horizontals and verticals; two-point keeps verticals.\n if (g.points.length <= 2) out.push({ x: 0, y: 1 });\n if (g.points.length <= 1) out.push({ x: 1, y: 0 });\n return out;\n}\n\n/** How far the pen must move before a stroke chooses its perspective line (document pixels). */\nexport const SNAP_DECIDE_DISTANCE = 6;\n\n/**\n * Snaps one stroke to a perspective guide: once the pen has moved `SNAP_DECIDE_DISTANCE` from\n * where it started, the stroke picks the guide line through its start that best matches its\n * direction, and every sample after that is projected onto the line.\n */\nexport class PerspectiveSnapper {\n private start: Point2 | null = null;\n private dir: Point2 | null = null;\n\n constructor(private readonly guide: PerspectiveGuide) {}\n\n /** The line the stroke follows, once chosen. */\n get line(): { from: Point2; direction: Point2 } | null {\n return this.start && this.dir ? { from: this.start, direction: this.dir } : null;\n }\n\n snap<P extends Point2>(p: P): P {\n if (!this.guide.enabled || !this.guide.snap || !this.guide.points.length) return p;\n if (!this.start) {\n this.start = { x: p.x, y: p.y };\n return p;\n }\n const s = this.start;\n if (!this.dir) {\n const dx = p.x - s.x;\n const dy = p.y - s.y;\n const len = Math.hypot(dx, dy);\n if (len < SNAP_DECIDE_DISTANCE) return { ...p, x: s.x, y: s.y };\n let best: Point2 | null = null;\n let bestDot = -1;\n for (const d of perspectiveDirections(this.guide, s)) {\n const dot = Math.abs((dx * d.x + dy * d.y) / len);\n if (dot > bestDot) {\n bestDot = dot;\n best = d;\n }\n }\n this.dir = best;\n if (!best) return p;\n }\n const d = this.dir!;\n const t = (p.x - s.x) * d.x + (p.y - s.y) * d.y;\n return { ...p, x: s.x + d.x * t, y: s.y + d.y * t };\n }\n}\n\n/** Guide lines to draw for a perspective guide: rays from each vanishing point through the canvas. */\nexport function perspectiveGuideLines(g: PerspectiveGuide, size: { width: number; height: number }, count = 12): Array<[Point2, Point2]> {\n const out: Array<[Point2, Point2]> = [];\n const far = Math.hypot(size.width, size.height) * 4;\n for (const v of g.points) {\n // Aim the fan at the canvas: spread around the direction to its centre.\n const cx = size.width / 2 - v.x;\n const cy = size.height / 2 - v.y;\n const inside = v.x >= 0 && v.y >= 0 && v.x <= size.width && v.y <= size.height;\n const mid = Math.atan2(cy, cx);\n const spread = inside ? Math.PI : Math.min(Math.PI, 2 * Math.atan2(Math.hypot(size.width, size.height) / 2, Math.hypot(cx, cy)));\n for (let i = 0; i < count; i++) {\n const a = inside ? (2 * Math.PI * i) / count : mid - spread / 2 + (spread * (i + 0.5)) / count;\n out.push([{ ...v }, { x: v.x + Math.cos(a) * far, y: v.y + Math.sin(a) * far }]);\n }\n }\n return out;\n}\n","/**\n * Colour for painters: hex / RGB / HSV / HSL conversions, a colour wheel that is either the\n * painter's red-yellow-blue wheel (where red's complement is green) or the RGB wheel (where it is\n * cyan), harmonies on it, and swatches.\n */\n\nexport type Rgb255 = [number, number, number];\n\nconst HEX = /^#?([0-9a-f]{6})$/i;\n\nexport function parseHexColor(value: unknown, what = 'color'): Rgb255 {\n const m = typeof value === 'string' ? HEX.exec(value.trim()) : null;\n if (!m) throw new Error(`${what} is ${JSON.stringify(value)}; use #rrggbb, e.g. \"#2a4b8d\".`);\n const n = parseInt(m[1], 16);\n return [(n >> 16) & 255, (n >> 8) & 255, n & 255];\n}\n\nexport function rgbToHexColor(r: number, g: number, b: number): string {\n return '#' + [r, g, b].map((v) => Math.round(Math.min(255, Math.max(0, v))).toString(16).padStart(2, '0')).join('');\n}\n\n/** RGB 0..255 → HSV with h in degrees 0..360, s and v 0..1. */\nexport function rgbToHsv(r: number, g: number, b: number): { h: number; s: number; v: number } {\n const R = r / 255;\n const G = g / 255;\n const B = b / 255;\n const max = Math.max(R, G, B);\n const min = Math.min(R, G, B);\n const d = max - min;\n let h = 0;\n if (d > 0) {\n if (max === R) h = 60 * (((G - B) / d) % 6);\n else if (max === G) h = 60 * ((B - R) / d + 2);\n else h = 60 * ((R - G) / d + 4);\n }\n if (h < 0) h += 360;\n return { h, s: max === 0 ? 0 : d / max, v: max };\n}\n\nexport function hsvToRgb(h: number, s: number, v: number): Rgb255 {\n const hh = (((h % 360) + 360) % 360) / 60;\n const c = v * s;\n const x = c * (1 - Math.abs((hh % 2) - 1));\n const m = v - c;\n const [r, g, b] = hh < 1 ? [c, x, 0] : hh < 2 ? [x, c, 0] : hh < 3 ? [0, c, x] : hh < 4 ? [0, x, c] : hh < 5 ? [x, 0, c] : [c, 0, x];\n return [Math.round((r + m) * 255), Math.round((g + m) * 255), Math.round((b + m) * 255)];\n}\n\n/** RGB 0..255 → HSL with h in degrees, s and l 0..1. */\nexport function rgbToHsl(r: number, g: number, b: number): { h: number; s: number; l: number } {\n const { h } = rgbToHsv(r, g, b);\n const max = Math.max(r, g, b) / 255;\n const min = Math.min(r, g, b) / 255;\n const l = (max + min) / 2;\n const d = max - min;\n return { h, s: d === 0 ? 0 : d / (1 - Math.abs(2 * l - 1)), l };\n}\n\nexport function hslToRgb(h: number, s: number, l: number): Rgb255 {\n const c = (1 - Math.abs(2 * l - 1)) * s;\n const v = l + c / 2;\n return hsvToRgb(h, v === 0 ? 0 : c / v, v);\n}\n\n/** Which wheel hues live on: `ryb` (painter's: red ↔ green complements) or `rgb` (red ↔ cyan). */\nexport type ColorWheel = 'ryb' | 'rgb';\n\n// RYB wheel angle → RGB hue (a piecewise-linear map through red, orange, yellow, green, blue, violet).\nconst RYB_STOPS: ReadonlyArray<[number, number]> = [\n [0, 0],\n [60, 30],\n [120, 60],\n [180, 120],\n [240, 240],\n [300, 280],\n [360, 360],\n];\n\nfunction piecewise(v: number, from: 0 | 1): number {\n const x = ((v % 360) + 360) % 360;\n const to = from === 0 ? 1 : 0;\n for (let i = 1; i < RYB_STOPS.length; i++) {\n const a = RYB_STOPS[i - 1];\n const b = RYB_STOPS[i];\n if (x <= b[from]) return a[to] + ((x - a[from]) / (b[from] - a[from])) * (b[to] - a[to]);\n }\n return x;\n}\n\n/** A wheel angle (degrees) → an RGB hue. */\nexport function wheelToHue(angle: number, wheel: ColorWheel): number {\n return wheel === 'rgb' ? ((angle % 360) + 360) % 360 : piecewise(angle, 0);\n}\n\n/** An RGB hue → its wheel angle (degrees). */\nexport function hueToWheel(hue: number, wheel: ColorWheel): number {\n return wheel === 'rgb' ? ((hue % 360) + 360) % 360 : piecewise(hue, 1);\n}\n\nexport type HarmonyKind = 'complementary' | 'split-complementary' | 'analogous' | 'triadic' | 'tetradic' | 'square' | 'monochromatic';\n\nexport const HARMONY_KINDS: readonly HarmonyKind[] = ['complementary', 'split-complementary', 'analogous', 'triadic', 'tetradic', 'square', 'monochromatic'];\n\nexport interface HarmonyColor {\n color: string;\n /** Position on the wheel, degrees. */\n angle: number;\n}\n\n/**\n * The colours of a harmony around `base`, the base first. Hue-based harmonies keep the base's\n * saturation and value and turn it around the wheel; `analogous` spreads by `spread` degrees\n * (default 30); `monochromatic` keeps the hue and steps the lightness.\n */\nexport function colorHarmony(base: string, kind: HarmonyKind, options: { wheel?: ColorWheel; spread?: number } = {}): HarmonyColor[] {\n const wheel = options.wheel ?? 'ryb';\n const [r, g, b] = parseHexColor(base, 'base');\n const hsv = rgbToHsv(r, g, b);\n const start = hueToWheel(hsv.h, wheel);\n const at = (angle: number): HarmonyColor => {\n const a = ((angle % 360) + 360) % 360;\n const [rr, gg, bb] = hsvToRgb(wheelToHue(a, wheel), hsv.s, hsv.v);\n return { color: rgbToHexColor(rr, gg, bb), angle: Math.round(a * 10) / 10 };\n };\n const spread = options.spread ?? 30;\n const offsets: Record<Exclude<HarmonyKind, 'monochromatic'>, number[]> = {\n complementary: [0, 180],\n 'split-complementary': [0, 180 - spread, 180 + spread],\n analogous: [0, -spread, spread],\n triadic: [0, 120, 240],\n tetradic: [0, 60, 180, 240],\n square: [0, 90, 180, 270],\n };\n if (kind === 'monochromatic') {\n const hsl = rgbToHsl(r, g, b);\n const steps = [0, -0.3, -0.15, 0.15, 0.3];\n return steps.map((d) => {\n const [rr, gg, bb] = d === 0 ? [r, g, b] : hslToRgb(hsl.h, hsl.s, Math.min(0.97, Math.max(0.03, hsl.l + d)));\n return { color: rgbToHexColor(rr, gg, bb), angle: Math.round(start * 10) / 10 };\n });\n }\n return offsets[kind].map((o, i) => (i === 0 ? { color: rgbToHexColor(r, g, b), angle: Math.round(start * 10) / 10 } : at(start + o)));\n}\n\nexport interface Swatch {\n color: string;\n name?: string;\n}\n\n/** A starting palette of our own generic paint colours. */\nexport const DEFAULT_SWATCHES: readonly Swatch[] = [\n { color: '#f7f5ee', name: 'Warm white' },\n { color: '#f3d23a', name: 'Lemon yellow' },\n { color: '#c8912f', name: 'Yellow ochre' },\n { color: '#d23a2a', name: 'Warm red' },\n { color: '#9e1f3d', name: 'Crimson' },\n { color: '#8a4a2b', name: 'Burnt earth' },\n { color: '#2f3f9e', name: 'Deep blue' },\n { color: '#1d6f8f', name: 'Cool blue' },\n { color: '#4f6e2c', name: 'Leaf green' },\n { color: '#25221f', name: 'Warm black' },\n];\n","/**\n * The mixing pad: a small canvas beside the painting to put paint on, smear it with a palette\n * knife and pick the mixed colour from. Paint is laid with the Mixer Brush in pigment mode and the\n * knife is a pigment smudge, so blue and yellow pushed together make green. It is scratch space:\n * not part of the painting and not in its undo history.\n */\n\nimport { EMPTY_MIXER_LOAD } from '../paint/mixer';\nimport { emptySurface, readRegion, type TiledSurface } from '../raster/surface';\nimport { normalizePaintBrush, type PaintBrush } from './brushes';\nimport { IDENTITY_COPY, type PenPoint } from './engine';\nimport { hexToRgb8 } from './paper';\nimport { mixerLoadForStroke, PaintStrokeSession } from './stroke';\n\nexport type MixingPadTool = 'paint' | 'knife';\n\nexport const MIXING_PAD_WIDTH = 360;\nexport const MIXING_PAD_HEIGHT = 220;\n\nconst PAD_PAINT: PaintBrush = normalizePaintBrush({\n id: 'pad-paint',\n name: 'Pad paint',\n category: 'mixer',\n engine: 'mixer',\n tip: { size: 28, hardness: 0.75, spacing: 0.1, opacity: 1, flow: 0.7, pressureSize: false, pressureOpacity: false },\n mixer: { wet: 0.45, load: 1, mix: 0.4, loadEachStroke: true, cleanEachStroke: true, mixing: 'pigment' },\n});\n\nconst PAD_KNIFE: PaintBrush = normalizePaintBrush({\n id: 'pad-knife',\n name: 'Palette knife',\n category: 'smudge',\n engine: 'mixer',\n loadsColor: false,\n tip: { size: 34, hardness: 0.9, spacing: 0.08, roundness: 0.35, angle: 90, opacity: 1, flow: 0.85, pressureSize: false, pressureOpacity: false },\n mixer: { wet: 1, load: 0, mix: 1, loadEachStroke: false, cleanEachStroke: true, mixing: 'pigment' },\n});\n\nexport class MixingPad {\n readonly width = MIXING_PAD_WIDTH;\n readonly height = MIXING_PAD_HEIGHT;\n private surface: TiledSurface = emptySurface(4);\n /** Increments on every change (for redrawing). */\n version = 0;\n\n /** Paints (`paint`, with `color`) or smears (`knife`) through `points` in pad pixels. */\n stroke(points: readonly PenPoint[], options: { tool: MixingPadTool; color: string; size?: number }): { bounds: { x: number; y: number; width: number; height: number } | null } {\n if (!points.length) throw new Error('points is empty; give at least one {x, y} in pad pixels.');\n for (const [i, p] of points.entries()) {\n if (!Number.isFinite(p.x) || !Number.isFinite(p.y) || p.x < 0 || p.y < 0 || p.x > this.width || p.y > this.height) {\n throw new Error(`points[${i}] (${p.x}, ${p.y}) is off the ${this.width}×${this.height} mixing pad.`);\n }\n }\n let brush = options.tool === 'knife' ? PAD_KNIFE : PAD_PAINT;\n if (options.size !== undefined) brush = normalizePaintBrush({ tip: { ...brush.tip, size: options.size } }, brush);\n const [r, g, b] = hexToRgb8(options.color);\n let result: TiledSurface | null = null;\n const session = new PaintStrokeSession(\n { update: () => {}, commit: (_s, s) => (result = s) },\n {\n layerId: 'mixing-pad',\n surface: this.surface,\n offset: { x: 0, y: 0 },\n lockTransparency: false,\n brush,\n color: [r, g, b, 255],\n background: [255, 255, 255, 255],\n grain: null,\n paperDepth: 0,\n seed: 1,\n colorHex: options.color,\n affineCopies: [],\n copies: [IDENTITY_COPY],\n mixerLoad: mixerLoadForStroke(brush, EMPTY_MIXER_LOAD, [r / 255, g / 255, b / 255]),\n }\n );\n session.push(points);\n const res = session.end();\n if (result) {\n this.surface = result;\n this.version++;\n }\n return { bounds: res.bounds };\n }\n\n /** The average colour within `radius` pixels of (x, y), or `null` where the pad is bare. */\n pick(x: number, y: number, radius = 3): string | null {\n if (!(x >= 0 && y >= 0 && x < this.width && y < this.height)) throw new Error(`(${x}, ${y}) is off the ${this.width}×${this.height} mixing pad.`);\n const r = Math.max(0, Math.round(radius));\n const x0 = Math.max(0, Math.floor(x) - r);\n const y0 = Math.max(0, Math.floor(y) - r);\n const x1 = Math.min(this.width, Math.floor(x) + r + 1);\n const y1 = Math.min(this.height, Math.floor(y) + r + 1);\n const px = readRegion(this.surface, { x: x0, y: y0, width: x1 - x0, height: y1 - y0 });\n let R = 0;\n let G = 0;\n let B = 0;\n let A = 0;\n for (let i = 0; i < px.length; i += 4) {\n const a = px[i + 3];\n R += px[i] * a;\n G += px[i + 1] * a;\n B += px[i + 2] * a;\n A += a;\n }\n if (A === 0) return null;\n const hex = (v: number) => Math.round(v / A).toString(16).padStart(2, '0');\n return `#${hex(R)}${hex(G)}${hex(B)}`;\n }\n\n clear(): void {\n this.surface = emptySurface(4);\n this.version++;\n }\n\n /** The pad over white, `width × height` RGBA. */\n pixels(): Uint8ClampedArray {\n const px = readRegion(this.surface, { x: 0, y: 0, width: this.width, height: this.height });\n for (let i = 0; i < px.length; i += 4) {\n const a = px[i + 3] / 255;\n px[i] = Math.round(px[i] * a + 255 * (1 - a));\n px[i + 1] = Math.round(px[i + 1] * a + 255 * (1 - a));\n px[i + 2] = Math.round(px[i + 2] * a + 255 * (1 - a));\n px[i + 3] = 255;\n }\n return px;\n }\n}\n","/**\n * `PaintEditorController`: the natural-media paint editor's state, framework-free.\n *\n * - The document (canvas, paper, the shared raster layer stack, recorded strokes) is immutable\n * and tiled copy-on-write; each undo step is a reference to a whole document state.\n * - Strokes: `beginStroke` gives a live session for pointer input (one undo step at `end`);\n * `paintStroke` paints a whole stroke from data (agents, tests, replays).\n * - The brush, colour, Mixer Brush load, view and hand are editor state, not undo steps.\n * - Rendering goes through the shared compositor with the paper as its bottom layer; exports\n * are PNG (pure TypeScript), JPEG / WebP (through a canvas or a host encoder) and PSD (through\n * the shared PSD writer, with the paper as a pixel layer).\n */\n\nimport { exportPsd, type PsdExportResult } from '../image-editor/psd/export';\nimport type { ImageLayer } from '../image-editor/layers/model';\nimport { applyStrokeToTile, CoverageMap, type StrokeApply } from '../paint/brush';\nimport { cleanMixer, EMPTY_MIXER_LOAD, loadMixer, type MixerLoad } from '../paint/mixer';\nimport { BLEND_MODES, isBlendMode, standardBlendMode, type BlendMode } from '../raster/blend';\nimport { findLayer, flattenLayers, insertLayer, isLayerLocked, mapLayer, type LayerLocks } from '../raster/layers';\nimport { bytesToBase64, decodePng, encodePng, parseDataUrl, pngDataUrl } from '../raster/png';\nimport {\n contentBounds,\n emptySurface,\n readPixel,\n surfaceFromPixels,\n TILE,\n TiledSurface,\n tileKey,\n tilesInRect,\n finishTile,\n type RasterRect,\n type Tile,\n} from '../raster/surface';\nimport { brushToJSON, BUILTIN_BRUSHES, DEFAULT_BRUSH_ID, normalizePaintBrush, type PaintBrushInput, parseBrushLibrary, BRUSH_ID, type BrushLibraryFile, type PaintBrush } from './brushes';\nimport {\n createPaintDocument,\n createPaintLayer,\n newPaintLayerId,\n normalizeCanvas,\n type PaintCanvas,\n type PaintDocumentState,\n type PaintLayer,\n type PaintPixelLayer,\n} from './document';\nimport { defaultImageEncoder, type ImageEncoder, type ImageFormat } from './encode';\nimport type { PenPoint } from './engine';\nimport type { Hand } from './input';\nimport { mix32 } from './noise';\nimport { clonePaper, grainCatch, hexToRgb8, normalizePaper, paperPreset, type PaperSettings } from './paper';\nimport { createPaintCompositor, downsampleRgba, paperGrain, paperNode, TRACING_NODE_ID, type ImageNode, type ViewLayer } from './render';\nimport {\n deserializePaintDocument,\n deserializePaintDocumentAsync,\n serializePaintDocument,\n serializePaintDocumentExternal,\n type PaintAssetStore,\n type PaintDocumentExtensions,\n type SerializedPaintDocument,\n} from './serialize';\nimport { mixerLoadForStroke, PaintStrokeSession, type PaintStrokeResult, type StrokeSessionHost } from './stroke';\nimport { affineCopy, strokeBounds, variationAffine, varyStroke, IDENTITY_AFFINE, type Affine, type RecordedStroke, type StrokeVariation } from './strokes';\nimport { renderBrushThumbnail, type BrushThumbnail } from './thumbnails';\nimport { colorHarmony, DEFAULT_SWATCHES, type ColorWheel, type HarmonyColor, type HarmonyKind, type Swatch } from './color';\nimport {\n defaultGuides,\n normalizePerspective,\n normalizeSymmetry,\n PerspectiveSnapper,\n symmetryCopies,\n type PaintGuides,\n type PerspectiveGuide,\n type ReferenceImage,\n type SymmetryGuide,\n type TracingImage,\n} from './guides';\nimport { MixingPad, type MixingPadTool } from './mixing-pad';\nimport { DEFAULT_VIEW, normalizeView, type PaintView } from './view';\n\n/** A refusal with a message that says what is wrong and how to fix it. */\nexport class PaintEditorError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'PaintEditorError';\n }\n}\n\nexport interface PaintEditorOptions extends Partial<PaintCanvas> {\n /** Paper settings, or a library preset id (default cold pressed). */\n paper?: Partial<PaperSettings> | string;\n /** Active brush id (default `pencil-6b`). */\n brushId?: string;\n /** Saved user brushes to start the library with. */\n brushes?: readonly PaintBrush[];\n /** Paint colour #rrggbb (default #1f2937). */\n color?: string;\n hand?: Hand;\n /** Encodes JPEG / WebP (default: a canvas, when there is one). */\n encodeImage?: ImageEncoder;\n /** Undo steps kept (default 200). */\n historyLimit?: number;\n}\n\nexport interface PaintEditorState {\n document: PaintDocumentState;\n /** The active brush (possibly edited from its preset). */\n brush: PaintBrush;\n /** The brush library: built-in presets, then the user's brushes. */\n brushes: readonly PaintBrush[];\n /** Paint colour #rrggbb. */\n color: string;\n /** The second colour (swap with `swapColors`). */\n secondaryColor: string;\n /** What the Mixer Brush carries between strokes. */\n mixerLoad: MixerLoad;\n view: PaintView;\n hand: Hand;\n canUndo: boolean;\n canRedo: boolean;\n undoLabel: string | null;\n redoLabel: string | null;\n /** Mirror / kaleidoscope, perspective, tracing image and reference images (saved with the document, not undo steps). */\n guides: PaintGuides;\n /** The colour swatches (saved with the document, not undo steps). */\n swatches: readonly Swatch[];\n /** Changes whenever the mixing pad does. */\n mixingPadVersion: number;\n /** A stroke is in progress. */\n stroking: boolean;\n /** Increments on every change. */\n version: number;\n}\n\n/** A layer as tools and panels describe it. */\nexport interface PaintLayerInfo {\n id: string;\n name: string;\n type: 'pixel' | 'group';\n visible: boolean;\n opacity: number;\n blend: string;\n clipped: boolean;\n locks: LayerLocks;\n active: boolean;\n /** Painted content (document pixels), or `null` when empty. */\n bounds: RasterRect | null;\n parentId: string | null;\n depth: number;\n}\n\nexport interface PaintStrokeInit {\n /** Default the active layer. */\n layerId?: string;\n /** Default the editor colour. */\n color?: string;\n /** Default the active brush. */\n brushId?: string;\n /** Changes to the brush for this stroke only. */\n brush?: PaintBrushInput;\n /** Jitter seed (default: a new one per stroke). */\n seed?: number;\n /** Extra copies of the stroke as affine maps (default: the symmetry guide's). */\n copies?: readonly Affine[];\n /** Snap the samples to the perspective guide (default true for `beginStroke`, false for `paintStroke`). */\n snapToPerspective?: boolean;\n /** Where the stroke starts, for taking its colour from the tracing image before the first sample (`beginStroke`). */\n start?: { x: number; y: number };\n}\n\nexport interface LayerUpdate {\n name?: string;\n visible?: boolean;\n opacity?: number;\n blend?: BlendMode;\n clipped?: boolean;\n locks?: LayerLocks;\n}\n\nexport interface FillLayerOptions {\n layerId?: string;\n /** Default the editor colour. */\n color?: string;\n /** 0..1 (default 1). */\n opacity?: number;\n /** Paper grain response 0..1 (default 0: a flat fill); above 0 the fill catches the grain like pastel rubbed across the paper. */\n grain?: number;\n /** With grain: pressure 0..1, how far the fill reaches into the valleys (default 0.5). */\n pressure?: number;\n blend?: BlendMode;\n}\n\nexport interface ReplayOptions extends StrokeVariation {\n /** Recorded stroke ids (see `getStrokes`). */\n strokeIds: readonly string[];\n /** Paint on this layer instead of each stroke's own. */\n layerId?: string;\n /** Recolour (default each stroke's colour). */\n color?: string;\n /** Replay with this brush instead (default each stroke's brush). */\n brushId?: string;\n /** Repeat the variation this many times, each one applied on top of the last (default 1). */\n repeat?: number;\n}\n\nexport interface RenderOptions {\n /** Include the paper (default true); without it the result is transparent where nothing is painted. */\n paper?: boolean;\n /** Only these layers (a group with its children). */\n layerIds?: readonly string[];\n}\n\nexport interface PixelImage {\n width: number;\n height: number;\n data: Uint8ClampedArray;\n}\n\ninterface HistoryEntry {\n label: string;\n before: PaintDocumentState;\n after: PaintDocumentState;\n}\n\nconst HEX = /^#[0-9a-f]{6}$/i;\n\nfunction parseColor(value: unknown, what = 'color'): string {\n if (typeof value !== 'string' || !HEX.test(value.trim())) throw new PaintEditorError(`${what} is ${JSON.stringify(value)}; use #rrggbb, e.g. \"#2a4b8d\".`);\n return value.trim().toLowerCase();\n}\n\nfunction rgbaOf(hex: string): [number, number, number, number] {\n const [r, g, b] = hexToRgb8(hex);\n return [r, g, b, 255];\n}\n\nfunction rgbToHex(r: number, g: number, b: number): string {\n return '#' + [r, g, b].map((v) => Math.round(Math.min(255, Math.max(0, v))).toString(16).padStart(2, '0')).join('');\n}\n\nfunction unionRect(a: RasterRect | null, b: RasterRect | null): RasterRect | null {\n if (!a) return b ? { ...b } : null;\n if (!b) return { ...a };\n const x = Math.min(a.x, b.x);\n const y = Math.min(a.y, b.y);\n return { x, y, width: Math.max(a.x + a.width, b.x + b.width) - x, height: Math.max(a.y + a.height, b.y + b.height) - y };\n}\n\nconst isPixelLayer = (l: PaintLayer | undefined): l is PaintPixelLayer => l?.type === 'pixel';\n\nexport class PaintEditorController {\n private doc: PaintDocumentState;\n private extensions: PaintDocumentExtensions = {};\n private undoStack: HistoryEntry[] = [];\n private redoStack: HistoryEntry[] = [];\n private readonly historyLimit: number;\n private brush: PaintBrush;\n private userBrushes: PaintBrush[];\n private color: string;\n private secondaryColor = '#ffffff';\n private mixerLoad: MixerLoad = EMPTY_MIXER_LOAD;\n private view: PaintView = { ...DEFAULT_VIEW, pan: { ...DEFAULT_VIEW.pan } };\n private hand: Hand;\n private readonly encodeImage: ImageEncoder | undefined;\n private listeners = new Set<() => void>();\n private version = 0;\n private cached: PaintEditorState | null = null;\n private session: PaintStrokeSession | null = null;\n private live: { layerId: string; surface: TiledSurface } | null = null;\n private liveLayers: { key: TiledSurface; layers: PaintLayer[] } | null = null;\n private dirty: RasterRect[] | 'all' = 'all';\n private seedCounter = 1;\n private strokeCounter = 1;\n private guides: PaintGuides;\n private swatches: Swatch[] = DEFAULT_SWATCHES.map((s) => ({ ...s }));\n private readonly pad = new MixingPad();\n private tracingVersion = 1;\n private tracingCache: { key: number; node: ImageNode } | null = null;\n private readonly imagePixels = new Map<string, PixelImage>();\n private nextReferenceId = 1;\n private readonly viewCompositor = createPaintCompositor();\n private readonly exportCompositor = createPaintCompositor();\n\n constructor(options: PaintEditorOptions = {}) {\n this.historyLimit = Math.max(1, options.historyLimit ?? 200);\n this.doc = createPaintDocument({ width: options.width, height: options.height, dpi: options.dpi, paper: this.resolvePaper(options.paper) });\n this.userBrushes = (options.brushes ?? []).map((b) => normalizePaintBrush({ ...b, builtin: false }));\n const start = this.findBrush(options.brushId ?? DEFAULT_BRUSH_ID) ?? this.findBrush(DEFAULT_BRUSH_ID)!;\n this.brush = normalizePaintBrush(start);\n this.color = options.color ? parseColor(options.color) : '#1f2937';\n this.hand = options.hand === 'left' ? 'left' : 'right';\n this.encodeImage = options.encodeImage;\n this.guides = defaultGuides(this.doc.canvas);\n }\n\n // --- State and events ----------------------------------------------------------\n\n subscribe(listener: () => void): () => void {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n\n private emit(dirty: RasterRect[] | 'all' = 'all'): void {\n if (dirty === 'all' || this.dirty === 'all') this.dirty = 'all';\n else this.dirty.push(...dirty);\n this.version++;\n this.cached = null;\n for (const l of [...this.listeners]) l();\n }\n\n /** A snapshot of the editor (the same object until something changes). */\n getState(): PaintEditorState {\n if (this.cached) return this.cached;\n const last = this.undoStack[this.undoStack.length - 1];\n const next = this.redoStack[this.redoStack.length - 1];\n this.cached = {\n document: this.doc,\n brush: this.brush,\n brushes: [...BUILTIN_BRUSHES, ...this.userBrushes],\n color: this.color,\n secondaryColor: this.secondaryColor,\n mixerLoad: this.mixerLoad,\n view: this.view,\n hand: this.hand,\n canUndo: this.undoStack.length > 0 && !this.session,\n canRedo: this.redoStack.length > 0 && !this.session,\n undoLabel: last?.label ?? null,\n redoLabel: next?.label ?? null,\n guides: this.guides,\n swatches: this.swatches,\n mixingPadVersion: this.pad.version,\n stroking: Boolean(this.session),\n version: this.version,\n };\n return this.cached;\n }\n\n get document(): PaintDocumentState {\n return this.doc;\n }\n\n /**\n * Where the rendered stack changed since the last call: rectangles (a stroke's dabs) or `'all'`.\n * The viewport passes it to `compositeTiles` as `dirty`.\n */\n takeDirty(): RasterRect[] | 'all' {\n const d = this.dirty;\n this.dirty = [];\n return d;\n }\n\n // --- History -------------------------------------------------------------------\n\n private requireIdle(what: string): void {\n if (this.session) throw new PaintEditorError(`A stroke is in progress; end or cancel it before ${what}.`);\n }\n\n private commit(label: string, next: PaintDocumentState): void {\n this.undoStack.push({ label, before: this.doc, after: next });\n if (this.undoStack.length > this.historyLimit) this.undoStack.shift();\n this.redoStack = [];\n this.doc = next;\n this.emit();\n }\n\n undo(): string | null {\n this.requireIdle('undoing');\n const e = this.undoStack.pop();\n if (!e) return null;\n this.redoStack.push(e);\n this.doc = e.before;\n this.emit();\n return e.label;\n }\n\n redo(): string | null {\n this.requireIdle('redoing');\n const e = this.redoStack.pop();\n if (!e) return null;\n this.undoStack.push(e);\n this.doc = e.after;\n this.emit();\n return e.label;\n }\n\n /** Labels of the undo steps, oldest first. */\n historyLabels(): { undo: string[]; redo: string[] } {\n return { undo: this.undoStack.map((e) => e.label), redo: this.redoStack.map((e) => e.label).reverse() };\n }\n\n // --- Canvas and paper ----------------------------------------------------------\n\n private resolvePaper(paper: Partial<PaperSettings> | string | undefined): Partial<PaperSettings> {\n if (typeof paper === 'string') {\n const p = paperPreset(paper);\n if (!p) throw new PaintEditorError(`Unknown paper \"${paper}\". Call list_papers for the ids.`);\n return p;\n }\n return paper ?? {};\n }\n\n /** Starts a new canvas: one empty layer over the paper (one undo step; undo brings the old one back). */\n newCanvas(options: Partial<PaintCanvas> & { paper?: Partial<PaperSettings> | string } = {}): PaintDocumentState {\n this.requireIdle('starting a new canvas');\n const next = createPaintDocument({\n width: options.width ?? this.doc.canvas.width,\n height: options.height ?? this.doc.canvas.height,\n dpi: options.dpi ?? this.doc.canvas.dpi,\n paper: options.paper === undefined ? this.doc.paper : this.resolvePaper(options.paper),\n });\n this.extensions = {};\n this.guides = { ...this.guides, symmetry: { ...this.guides.symmetry, center: { x: next.canvas.width / 2, y: next.canvas.height / 2 } }, tracing: null };\n this.tracingVersion++;\n this.commit('New canvas', next);\n return next;\n }\n\n /** Changes the canvas size (keeping the pixels where they are, anchored top-left) or resolution. */\n setCanvas(update: Partial<PaintCanvas>): PaintCanvas {\n this.requireIdle('changing the canvas');\n const canvas = normalizeCanvas({\n width: update.width ?? this.doc.canvas.width,\n height: update.height ?? this.doc.canvas.height,\n dpi: update.dpi ?? this.doc.canvas.dpi,\n });\n this.commit('Canvas size', { ...this.doc, canvas });\n return canvas;\n }\n\n /** Changes the paper: a library preset (`preset`), and / or any of its settings (one undo step). */\n setPaper(update: Partial<PaperSettings> & { preset?: string }): PaperSettings {\n this.requireIdle('changing the paper');\n let base = this.doc.paper;\n if (update.preset !== undefined && update.preset !== this.doc.paper.preset) {\n const p = paperPreset(update.preset);\n if (!p) throw new PaintEditorError(`Unknown paper \"${update.preset}\". Call list_papers for the ids.`);\n base = p;\n }\n const { preset: _p, ...rest } = update;\n if (rest.color !== undefined) parseColor(rest.color, 'paper color');\n const paper = normalizePaper({ ...rest, preset: base.preset }, base);\n const changedKeys = Object.keys(rest).filter((k) => k !== 'name');\n if (changedKeys.length && update.preset === undefined) paper.preset = base.preset;\n this.commit('Paper', { ...this.doc, paper });\n return clonePaper(paper);\n }\n\n // --- Layers --------------------------------------------------------------------\n\n getLayer(id: string): PaintLayer | undefined {\n return findLayer(this.doc.layers, id)?.layer;\n }\n\n /** The active pixel layer (or `undefined`). */\n getActiveLayer(): PaintLayer | undefined {\n return this.doc.activeLayerId ? this.getLayer(this.doc.activeLayerId) : undefined;\n }\n\n /** Every layer, top first, as panels and tools describe them. */\n listLayers(): PaintLayerInfo[] {\n const out: PaintLayerInfo[] = [];\n const walk = (list: readonly PaintLayer[], parentId: string | null, depth: number) => {\n for (let i = list.length - 1; i >= 0; i--) {\n const l = list[i];\n out.push(this.describeLayer(l, parentId, depth));\n if (l.type === 'group') walk(l.children, l.id, depth + 1);\n }\n };\n walk(this.doc.layers, null, 0);\n return out;\n }\n\n describeLayer(l: PaintLayer, parentId: string | null = findLayer(this.doc.layers, l.id)?.parent?.id ?? null, depth = findLayer(this.doc.layers, l.id)?.path.length ?? 0): PaintLayerInfo {\n let bounds: RasterRect | null = null;\n if (l.type === 'pixel') {\n const b = contentBounds(l.surface);\n bounds = b ? { ...b, x: b.x + l.offset.x, y: b.y + l.offset.y } : null;\n } else for (const c of flattenLayers(l.children)) if (c.type === 'pixel') bounds = unionRect(bounds, this.describeLayer(c, l.id, depth + 1).bounds);\n return {\n id: l.id,\n name: l.name,\n type: l.type,\n visible: l.visible,\n opacity: l.opacity,\n blend: l.blend,\n clipped: Boolean(l.clipped),\n locks: { ...(l.locks ?? {}) },\n active: l.id === this.doc.activeLayerId,\n bounds,\n parentId,\n depth,\n };\n }\n\n private requireLayer(id: string): PaintLayer {\n const l = this.getLayer(id);\n if (!l) throw new PaintEditorError(`Unknown layer \"${id}\". Call list_layers for the ids.`);\n return l;\n }\n\n /** The pixel layer a paint operation targets, checked for locks and visibility. */\n private paintTarget(layerId: string | undefined, what: string): PaintPixelLayer {\n const id = layerId ?? this.doc.activeLayerId;\n if (!id) throw new PaintEditorError(`There is no active layer to ${what}; add one with add_layer.`);\n const l = this.requireLayer(id);\n if (!isPixelLayer(l)) throw new PaintEditorError(`Layer \"${l.name}\" is a group; ${what} a pixel layer inside it.`);\n if (isLayerLocked(l, 'pixels')) throw new PaintEditorError(`Layer \"${l.name}\" has its pixels locked; unlock it (update_layer locks) before you ${what} it.`);\n if (!l.visible) throw new PaintEditorError(`Layer \"${l.name}\" is hidden; show it (update_layer visible true) before you ${what} it.`);\n return l;\n }\n\n setActiveLayer(id: string): void {\n this.requireLayer(id);\n if (this.doc.activeLayerId === id) return;\n // Selection of the active layer is editor state, not an undo step: keep the history's documents.\n this.doc = { ...this.doc, activeLayerId: id };\n this.emit();\n }\n\n /** Adds an empty pixel layer or group above `aboveId` (default: the active layer) and makes it active. */\n addLayer(options: { name?: string; type?: 'pixel' | 'group'; aboveId?: string; parentId?: string | null } = {}): PaintLayerInfo {\n this.requireIdle('adding a layer');\n const count = flattenLayers(this.doc.layers).length;\n const type = options.type ?? 'pixel';\n const name = options.name?.trim() || (type === 'group' ? `Group ${count + 1}` : `Layer ${count + 1}`);\n const layer: PaintLayer =\n type === 'group' ? { type: 'group', id: newPaintLayerId(), name, visible: true, opacity: 1, blend: 'pass-through', children: [] } : createPaintLayer(name);\n let parentId: string | null = null;\n let index: number | undefined;\n const above = options.aboveId ?? (options.parentId === undefined ? this.doc.activeLayerId : null);\n if (options.parentId !== undefined && options.parentId !== null) {\n const g = this.requireLayer(options.parentId);\n if (g.type !== 'group') throw new PaintEditorError(`Layer \"${g.name}\" is not a group; pass a group id as parentId.`);\n parentId = g.id;\n } else if (above) {\n const loc = findLayer(this.doc.layers, above);\n if (!loc) throw new PaintEditorError(`Unknown layer \"${above}\". Call list_layers for the ids.`);\n parentId = loc.parent?.id ?? null;\n index = loc.index + 1;\n }\n const layers = insertLayer(this.doc.layers, layer, parentId, index);\n this.commit(type === 'group' ? 'Add group' : 'Add layer', { ...this.doc, layers, activeLayerId: layer.id });\n return this.describeLayer(layer);\n }\n\n updateLayer(id: string, update: LayerUpdate): PaintLayerInfo {\n this.requireIdle('changing a layer');\n const l = this.requireLayer(id);\n if (isLayerLocked(l, 'all') && Object.keys(update).some((k) => k !== 'locks')) throw new PaintEditorError(`Layer \"${l.name}\" is fully locked; unlock it first (locks {all: false}).`);\n if (update.opacity !== undefined && !(update.opacity >= 0 && update.opacity <= 1)) throw new PaintEditorError(`opacity ${update.opacity} is out of range; use 0..1.`);\n if (update.blend !== undefined && !isBlendMode(update.blend) && !(l.type === 'group' && update.blend === 'pass-through')) {\n throw new PaintEditorError(`Unknown blend mode \"${update.blend}\". Call get_canvas_info for the blend modes.`);\n }\n if (update.name !== undefined && !update.name.trim()) throw new PaintEditorError('name is empty; give the layer a name.');\n const next = { ...l } as PaintLayer;\n if (update.name !== undefined) next.name = update.name.trim();\n if (update.visible !== undefined) next.visible = update.visible;\n if (update.opacity !== undefined) next.opacity = update.opacity;\n if (update.blend !== undefined) (next as { blend: string }).blend = update.blend;\n if (update.clipped !== undefined) next.clipped = update.clipped || undefined;\n if (update.locks !== undefined) {\n const locks = { ...(l.locks ?? {}), ...update.locks };\n next.locks = Object.values(locks).some(Boolean) ? locks : undefined;\n }\n this.commit('Layer properties', { ...this.doc, layers: mapLayer(this.doc.layers, id, () => next) });\n return this.describeLayer(next);\n }\n\n removeLayer(id: string): { removed: string; activeLayerId: string | null } {\n this.requireIdle('removing a layer');\n const l = this.requireLayer(id);\n if (isLayerLocked(l, 'all')) throw new PaintEditorError(`Layer \"${l.name}\" is fully locked; unlock it before removing it.`);\n const layers = mapLayer(this.doc.layers, id, () => null);\n let active = this.doc.activeLayerId;\n if (active && !findLayer(layers, active)) active = flattenLayers(layers).filter((x) => x.type === 'pixel').pop()?.id ?? null;\n this.commit('Remove layer', { ...this.doc, layers, activeLayerId: active });\n return { removed: id, activeLayerId: active };\n }\n\n duplicateLayer(id: string): PaintLayerInfo {\n this.requireIdle('duplicating a layer');\n const loc = findLayer(this.doc.layers, id);\n if (!loc) throw new PaintEditorError(`Unknown layer \"${id}\". Call list_layers for the ids.`);\n const copy = (l: PaintLayer): PaintLayer => (l.type === 'group' ? { ...l, id: newPaintLayerId(), children: l.children.map(copy) } : { ...l, id: newPaintLayerId() });\n const dup = { ...copy(loc.layer), name: `${loc.layer.name} copy` };\n const layers = insertLayer(this.doc.layers, dup, loc.parent?.id ?? null, loc.index + 1);\n this.commit('Duplicate layer', { ...this.doc, layers, activeLayerId: dup.id });\n return this.describeLayer(dup);\n }\n\n /** Moves a layer to `index` (0 = bottom) within `parentId` (default its own parent; `null` = top level). */\n moveLayer(id: string, index: number, parentId?: string | null): PaintLayerInfo {\n this.requireIdle('moving a layer');\n const loc = findLayer(this.doc.layers, id);\n if (!loc) throw new PaintEditorError(`Unknown layer \"${id}\". Call list_layers for the ids.`);\n const target = parentId === undefined ? (loc.parent?.id ?? null) : parentId;\n if (target) {\n const g = this.requireLayer(target);\n if (g.type !== 'group') throw new PaintEditorError(`Layer \"${g.name}\" is not a group; pass a group id as parentId.`);\n if (target === id || (loc.layer.type === 'group' && findLayer(loc.layer.children, target))) throw new PaintEditorError('A group cannot move into itself.');\n }\n const without = mapLayer(this.doc.layers, id, () => null);\n const siblings = target ? (findLayer(without, target)!.layer as { children: PaintLayer[] }).children : without;\n if (!Number.isInteger(index) || index < 0 || index > siblings.length) throw new PaintEditorError(`index ${index} is out of range; use 0..${siblings.length} (0 is the bottom).`);\n const layers = insertLayer(without, loc.layer, target, index);\n this.commit('Move layer', { ...this.doc, layers });\n return this.describeLayer(loc.layer);\n }\n\n /** Merges a pixel layer into the pixel layer below it (keeping the lower one's settings). */\n mergeDown(id: string): PaintLayerInfo {\n this.requireIdle('merging');\n const loc = findLayer(this.doc.layers, id);\n if (!loc) throw new PaintEditorError(`Unknown layer \"${id}\". Call list_layers for the ids.`);\n const siblings = loc.parent ? loc.parent.children : this.doc.layers;\n const below = siblings[loc.index - 1];\n const upper = loc.layer;\n if (!isPixelLayer(upper) || !isPixelLayer(below)) throw new PaintEditorError('Merge down needs a pixel layer directly above another pixel layer in the same group.');\n if (isLayerLocked(below, 'pixels')) throw new PaintEditorError(`Layer \"${below.name}\" has its pixels locked; unlock it to merge into it.`);\n const rect = unionRect(this.describeLayer(below).bounds, this.describeLayer(upper).bounds);\n let surface = emptySurface(4);\n if (rect) {\n const base: PaintPixelLayer = { ...below, opacity: 1, blend: 'normal', visible: true, clipped: undefined, mask: undefined };\n const px = createPaintCompositor().composite([base, upper.visible ? upper : { ...upper, opacity: 0 }] as ViewLayer[], rect, this.sources());\n surface = surfaceFromPixels({ width: rect.width, height: rect.height, data: px }, 4, rect.x, rect.y);\n }\n const merged: PaintPixelLayer = { ...below, surface, offset: { x: 0, y: 0 } };\n const layers = mapLayer(mapLayer(this.doc.layers, upper.id, () => null), below.id, () => merged);\n this.commit('Merge down', { ...this.doc, layers, activeLayerId: below.id });\n return this.describeLayer(merged);\n }\n\n /** Removes every pixel of a layer. */\n clearLayer(layerId?: string): { layerId: string; bounds: RasterRect | null } {\n this.requireIdle('clearing');\n const l = this.paintTarget(layerId, 'clear');\n const bounds = this.describeLayer(l).bounds;\n this.commit('Clear layer', { ...this.doc, layers: mapLayer(this.doc.layers, l.id, () => ({ ...l, surface: emptySurface(4) })) });\n return { layerId: l.id, bounds };\n }\n\n /**\n * Fills a layer across the canvas with a colour. With `grain` above 0 the fill follows the paper\n * grain (it catches the peaks, as pastel or charcoal rubbed across the sheet).\n */\n fillLayer(options: FillLayerOptions = {}): { layerId: string; bounds: RasterRect } {\n this.requireIdle('filling');\n const l = this.paintTarget(options.layerId, 'fill');\n const color = options.color === undefined ? this.color : parseColor(options.color);\n const opacity = options.opacity ?? 1;\n if (!(opacity >= 0 && opacity <= 1)) throw new PaintEditorError(`opacity ${opacity} is out of range; use 0..1.`);\n const grainAmount = options.grain ?? 0;\n if (!(grainAmount >= 0 && grainAmount <= 1)) throw new PaintEditorError(`grain ${grainAmount} is out of range; use 0..1.`);\n const pressure = options.pressure ?? 0.5;\n const blend = options.blend ?? 'normal';\n if (!isBlendMode(blend)) throw new PaintEditorError(`Unknown blend mode \"${blend}\".`);\n const { width, height } = this.doc.canvas;\n const rect = { x: 0, y: 0, width, height };\n const coverage = new CoverageMap();\n const depth = grainAmount * this.doc.paper.depth;\n const grain = depth > 0 ? paperGrain(this.doc.paper) : null;\n for (const { tx, ty } of tilesInRect(rect)) {\n const r = { x: tx * TILE, y: ty * TILE, width: Math.min(TILE, width - tx * TILE), height: Math.min(TILE, height - ty * TILE) };\n const vals = new Float32Array(r.width * r.height);\n for (let y = 0, k = 0; y < r.height; y++) for (let x = 0; x < r.width; x++, k++) vals[k] = grain ? grainCatch(grain.at(r.x + x + 0.5, r.y + y + 0.5), depth, pressure) : 1;\n coverage.accumulate(r, vals, 1);\n }\n const apply: StrokeApply = {\n mode: 'paint',\n color: rgbaOf(color),\n background: rgbaOf(this.doc.paper.color),\n opacity,\n blend,\n lockTransparency: isLayerLocked(l, 'transparency'),\n selection: null,\n offset: l.offset,\n };\n const surface = this.applyCoverage(l, coverage, rect, apply);\n this.commit('Fill layer', { ...this.doc, layers: mapLayer(this.doc.layers, l.id, () => ({ ...l, surface })) });\n return { layerId: l.id, bounds: rect };\n }\n\n private applyCoverage(l: PaintPixelLayer, coverage: CoverageMap, rect: RasterRect, apply: StrokeApply): TiledSurface {\n const base = l.surface;\n const tiles = new Map(base.tiles);\n for (const { tx, ty } of tilesInRect({ x: rect.x - l.offset.x, y: rect.y - l.offset.y, width: rect.width, height: rect.height })) {\n const key = tileKey(tx, ty);\n const src = base.tiles.get(key)?.data ?? new Uint8ClampedArray(TILE * TILE * 4);\n const tile = finishTile(applyStrokeToTile(coverage, src, 4, tx, ty, apply), 4, 0);\n if (tile) tiles.set(key, tile);\n else tiles.delete(key);\n }\n return new TiledSurface(4, tiles, 0);\n }\n\n // --- Brushes -------------------------------------------------------------------\n\n private findBrush(id: string): PaintBrush | undefined {\n return BUILTIN_BRUSHES.find((b) => b.id === id) ?? this.userBrushes.find((b) => b.id === id);\n }\n\n /** A library brush by id (`undefined` when unknown). */\n getBrush(id: string): PaintBrush | undefined {\n const b = this.findBrush(id);\n return b ? normalizePaintBrush(b, b) : undefined;\n }\n\n private requireBrush(id: string): PaintBrush {\n const b = this.findBrush(id);\n if (!b) throw new PaintEditorError(`Unknown brush \"${id}\". Call list_brushes for the ids.`);\n return b;\n }\n\n /**\n * Chooses the active brush (`id`: a library brush) and / or changes its settings. Editor state,\n * not an undo step. Returns the active brush.\n */\n setBrush(update: { id?: string } & Omit<PaintBrushInput, 'id'> = {}): PaintBrush {\n const { id, ...changes } = update;\n const base = id !== undefined ? this.requireBrush(id) : this.brush;\n const next = normalizePaintBrush({ ...changes, id: base.id }, base);\n // The active brush is `builtin` only while it is an unchanged built-in preset.\n if (base.builtin && !Object.keys(changes).length) next.builtin = true;\n else delete next.builtin;\n this.brush = next;\n this.emit([]);\n return this.brush;\n }\n\n /** Saves the active brush (or `brush`) into the user library under `id` / `name`. */\n saveBrush(options: { id: string; name?: string; brush?: PaintBrushInput }): PaintBrush {\n if (!BRUSH_ID.test(options.id)) throw new PaintEditorError(`Brush id \"${options.id}\" is invalid; use lowercase letters, digits and dashes (e.g. \"my-pencil\").`);\n if (BUILTIN_BRUSHES.some((b) => b.id === options.id)) throw new PaintEditorError(`\"${options.id}\" is a built-in brush; save under another id.`);\n const source = options.brush ? normalizePaintBrush(options.brush, this.brush) : this.brush;\n const saved = normalizePaintBrush({ ...source, id: options.id, name: options.name ?? source.name });\n delete saved.builtin;\n const i = this.userBrushes.findIndex((b) => b.id === options.id);\n if (i >= 0) this.userBrushes[i] = saved;\n else this.userBrushes.push(saved);\n this.emit([]);\n return saved;\n }\n\n removeBrush(id: string): void {\n if (BUILTIN_BRUSHES.some((b) => b.id === id)) throw new PaintEditorError(`\"${id}\" is a built-in brush and cannot be removed.`);\n const i = this.userBrushes.findIndex((b) => b.id === id);\n if (i < 0) throw new PaintEditorError(`Unknown brush \"${id}\". Call list_brushes for the ids.`);\n this.userBrushes.splice(i, 1);\n this.emit([]);\n }\n\n /** The user's saved brushes. */\n getUserBrushes(): PaintBrush[] {\n return this.userBrushes.map((b) => normalizePaintBrush(b, b));\n }\n\n /** A brush library file of the given brushes (default: the user's brushes). */\n exportBrushes(ids?: readonly string[]): BrushLibraryFile {\n const list = ids ? ids.map((id) => this.requireBrush(id)) : this.userBrushes;\n return { format: 'pixerate-brushes', version: 1, brushes: list.map(brushToJSON) };\n }\n\n /**\n * Adds the brushes of a library file to the user library. A brush whose id is taken is skipped\n * unless `replace` (built-in ids are always skipped). Returns the ids added and the problems.\n */\n importBrushes(file: unknown, options: { replace?: boolean } = {}): { added: string[]; skipped: string[]; problems: string[] } {\n const problems: string[] = [];\n let list: PaintBrush[];\n try {\n list = parseBrushLibrary(file, problems);\n } catch (e) {\n throw new PaintEditorError((e as Error).message);\n }\n const added: string[] = [];\n const skipped: string[] = [];\n for (const b of list) {\n if (BUILTIN_BRUSHES.some((x) => x.id === b.id)) {\n skipped.push(b.id);\n problems.push(`\"${b.id}\" is a built-in brush id; rename it to import it.`);\n continue;\n }\n const i = this.userBrushes.findIndex((x) => x.id === b.id);\n if (i >= 0 && !options.replace) {\n skipped.push(b.id);\n continue;\n }\n if (i >= 0) this.userBrushes[i] = b;\n else this.userBrushes.push(b);\n added.push(b.id);\n }\n if (added.length) this.emit([]);\n return { added, skipped, problems };\n }\n\n /** A thumbnail of a brush: a test stroke on the current paper. */\n brushThumbnail(id: string, options: { width?: number; height?: number; color?: string } = {}): BrushThumbnail {\n const b = id === this.brush.id ? this.brush : this.requireBrush(id);\n return renderBrushThumbnail(b, { paper: this.doc.paper, width: options.width, height: options.height, color: options.color ? parseColor(options.color) : this.color });\n }\n\n // --- Colour --------------------------------------------------------------------\n\n setColor(color: string): string {\n this.color = parseColor(color);\n this.emit([]);\n return this.color;\n }\n\n setSecondaryColor(color: string): string {\n this.secondaryColor = parseColor(color);\n this.emit([]);\n return this.secondaryColor;\n }\n\n swapColors(): void {\n [this.color, this.secondaryColor] = [this.secondaryColor, this.color];\n this.emit([]);\n }\n\n /** The colour at a document pixel: of the composite (paper included) or of one layer. */\n pickColor(x: number, y: number, options: { layerId?: string } = {}): { color: string; alpha: number } {\n const { width, height } = this.doc.canvas;\n const px = Math.floor(x);\n const py = Math.floor(y);\n if (!(px >= 0 && py >= 0 && px < width && py < height)) throw new PaintEditorError(`(${x}, ${y}) is outside the ${width}×${height} canvas.`);\n if (options.layerId !== undefined) {\n const l = this.requireLayer(options.layerId);\n if (!isPixelLayer(l)) throw new PaintEditorError(`Layer \"${l.name}\" is a group; pick from a pixel layer or the composite.`);\n const [r, g, b, a] = readPixel(l.surface, px - l.offset.x, py - l.offset.y);\n return { color: rgbToHex(r, g, b), alpha: Math.round((a / 255) * 1000) / 1000 };\n }\n const d = this.exportCompositor.composite(this.renderLayers({}), { x: px, y: py, width: 1, height: 1 }, this.sources());\n return { color: rgbToHex(d[0], d[1], d[2]), alpha: Math.round((d[3] / 255) * 1000) / 1000 };\n }\n\n // --- Mixer Brush ---------------------------------------------------------------\n\n /** Fills the Mixer Brush reservoir with a colour (default the editor colour). */\n loadMixerBrush(color?: string): MixerLoad {\n const [r, g, b] = hexToRgb8(color === undefined ? this.color : parseColor(color));\n this.mixerLoad = loadMixer(this.mixerLoad, [r / 255, g / 255, b / 255]);\n this.emit([]);\n return this.mixerLoad;\n }\n\n /** Empties the pickup well (and with `emptyReservoir` the loaded paint too). */\n cleanMixerBrush(emptyReservoir = false): MixerLoad {\n this.mixerLoad = emptyReservoir ? EMPTY_MIXER_LOAD : cleanMixer(this.mixerLoad);\n this.emit([]);\n return this.mixerLoad;\n }\n\n // --- View and hand -------------------------------------------------------------\n\n /** Zoom, pan, rotation and mirroring: view state only, the pixels never resample. */\n setView(update: Partial<PaintView>): PaintView {\n this.view = normalizeView(update, this.view);\n this.emit([]);\n return this.view;\n }\n\n resetView(): PaintView {\n return this.setView({ ...DEFAULT_VIEW, pan: { x: 0, y: 0 } });\n }\n\n setHand(hand: Hand): Hand {\n if (hand !== 'left' && hand !== 'right') throw new PaintEditorError(`hand is ${JSON.stringify(hand)}; use \"left\" or \"right\".`);\n this.hand = hand;\n this.emit([]);\n return hand;\n }\n\n // --- Strokes -------------------------------------------------------------------\n\n private strokeBrush(init: PaintStrokeInit): PaintBrush {\n let brush = init.brushId !== undefined ? this.requireBrush(init.brushId) : this.brush;\n if (init.brush) brush = normalizePaintBrush({ ...init.brush, id: brush.id }, brush);\n return brush;\n }\n\n /** Extra copies every new stroke paints (the painting guides add mirror and kaleidoscope copies). */\n protected strokeCopies(): Affine[] {\n return symmetryCopies(this.guides.symmetry);\n }\n\n private sessionFor(doc: PaintDocumentState, init: PaintStrokeInit, host: StrokeSessionHost): PaintStrokeSession {\n const layer = (() => {\n const id = init.layerId ?? doc.activeLayerId;\n if (!id) throw new PaintEditorError('There is no active layer to paint on; add one with add_layer.');\n const loc = findLayer(doc.layers, id);\n if (!loc) throw new PaintEditorError(`Unknown layer \"${id}\". Call list_layers for the ids.`);\n const l = loc.layer;\n if (!isPixelLayer(l)) throw new PaintEditorError(`Layer \"${l.name}\" is a group; paint on a pixel layer inside it.`);\n if (isLayerLocked(l, 'pixels')) throw new PaintEditorError(`Layer \"${l.name}\" has its pixels locked; unlock it (update_layer locks) to paint on it.`);\n if (!l.visible) throw new PaintEditorError(`Layer \"${l.name}\" is hidden; show it (update_layer visible true) to paint on it.`);\n return l;\n })();\n const brush = this.strokeBrush(init);\n let color = init.color === undefined ? this.color : parseColor(init.color);\n const tracing = this.guides.tracing;\n if (init.color === undefined && init.start && tracing?.visible && tracing.sampleColors) color = this.sampleTracingColor(init.start.x, init.start.y) ?? color;\n const perspective = this.guides.perspective;\n const snapper = init.snapToPerspective && perspective.enabled && perspective.snap ? new PerspectiveSnapper(perspective) : null;\n const rgba = rgbaOf(color);\n const seed = init.seed ?? mix32((this.seedCounter++ * 0x9e3779b1) >>> 0) & 0x7fffffff;\n const copies = (init.copies ?? this.strokeCopies()).filter((m) => m.some((v, i) => v !== IDENTITY_AFFINE[i]));\n const session = new PaintStrokeSession(host, {\n layerId: layer.id,\n surface: layer.surface,\n offset: layer.offset,\n lockTransparency: isLayerLocked(layer, 'transparency'),\n brush,\n color: rgba,\n background: rgbaOf(doc.paper.color),\n grain: paperGrain(doc.paper),\n paperDepth: doc.paper.depth,\n seed,\n colorHex: color,\n affineCopies: copies,\n copies: [IDENTITY_AFFINE, ...copies].map(affineCopy),\n inputFilter: snapper ? (p) => snapper.snap(p) : undefined,\n mixerLoad: brush.engine === 'mixer' ? mixerLoadForStroke(brush, this.mixerLoad, [rgba[0] / 255, rgba[1] / 255, rgba[2] / 255]) : EMPTY_MIXER_LOAD,\n });\n return session;\n }\n\n private record(session: PaintStrokeSession): RecordedStroke {\n const init = session.init;\n const stroke: RecordedStroke = {\n id: `s${this.strokeCounter++}`,\n layerId: session.layerId,\n brush: brushToJSON(init.brush) as PaintBrush,\n color: init.colorHex,\n points: session.points.map((p) => ({ ...p })),\n seed: init.seed,\n };\n if (init.affineCopies.length) stroke.copies = init.affineCopies.map((m) => [...m] as unknown as Affine);\n return stroke;\n }\n\n /**\n * Starts a live stroke for pointer input: `push` raw pen samples (document pixels), then `end()`\n * (one undo step) or `cancel()`.\n */\n beginStroke(init: PaintStrokeInit = {}): PaintStrokeSession {\n this.requireIdle('starting another');\n const host: StrokeSessionHost = {\n update: (layerId, surface, rects) => {\n this.live = { layerId, surface };\n this.emit(rects);\n },\n commit: (s, surface, cancelled) => {\n this.session = null;\n this.live = null;\n this.liveLayers = null;\n const brush = s.init.brush;\n if (!cancelled && s.result?.mixerLoad && brush.loadsColor) this.mixerLoad = s.result.mixerLoad;\n if (cancelled || !surface) {\n this.emit();\n return;\n }\n const stroke = this.record(s);\n s.result!.strokeId = stroke.id;\n const l = this.getLayer(s.layerId) as PaintPixelLayer;\n this.commit(`${brush.name} stroke`, { ...this.doc, layers: mapLayer(this.doc.layers, l.id, () => ({ ...l, surface })), strokes: [...this.doc.strokes, stroke] });\n },\n };\n const session = this.sessionFor(this.doc, { snapToPerspective: true, ...init }, host);\n this.session = session;\n this.emit([]);\n return session;\n }\n\n /** The current live stroke, if any. */\n get activeStroke(): PaintStrokeSession | null {\n return this.session;\n }\n\n /** Runs a whole stroke against `doc` without touching the editor; returns the new document. */\n private runStroke(doc: PaintDocumentState, init: PaintStrokeInit, points: readonly PenPoint[]): { doc: PaintDocumentState; result: PaintStrokeResult; brush: PaintBrush } {\n let out = doc;\n const host: StrokeSessionHost = {\n update: () => {},\n commit: (s, surface, cancelled) => {\n if (cancelled || !surface) return;\n const stroke = this.record(s);\n s.result!.strokeId = stroke.id;\n const l = findLayer(out.layers, s.layerId)!.layer as PaintPixelLayer;\n out = { ...out, layers: mapLayer(out.layers, l.id, () => ({ ...l, surface })), strokes: [...out.strokes, stroke] };\n },\n };\n const session = this.sessionFor(doc, init, host);\n session.push(points);\n const result = session.end();\n return { doc: out, result, brush: session.init.brush };\n }\n\n /** Paints one stroke from data (one undo step). */\n paintStroke(init: PaintStrokeInit & { points: readonly PenPoint[] }): PaintStrokeResult {\n this.requireIdle('painting');\n const points = this.checkPoints(init.points);\n const { doc, result, brush } = this.runStroke(this.doc, { ...init, start: init.start ?? points[0] }, points);\n if (result.mixerLoad && brush.loadsColor) this.mixerLoad = result.mixerLoad;\n if (doc !== this.doc) this.commit(`${brush.name} stroke`, doc);\n else this.emit([]);\n return result;\n }\n\n /** Checks stroke samples (finite x and y, pressure 0..1) and returns them; throws a sentence naming the bad point. */\n checkPoints(points: readonly PenPoint[]): PenPoint[] {\n if (!Array.isArray(points) || !points.length) throw new PaintEditorError('points is empty; give at least one {x, y} in document pixels.');\n const out: PenPoint[] = [];\n points.forEach((p, i) => {\n if (!p || !Number.isFinite(p.x) || !Number.isFinite(p.y)) throw new PaintEditorError(`points[${i}] needs finite x and y in document pixels.`);\n if (p.pressure !== undefined && !(p.pressure >= 0 && p.pressure <= 1)) throw new PaintEditorError(`points[${i}].pressure ${p.pressure} is out of range; use 0..1.`);\n out.push(p);\n });\n return out;\n }\n\n /** Every recorded stroke, oldest first. */\n getStrokes(): readonly RecordedStroke[] {\n return this.doc.strokes;\n }\n\n /**\n * Replays recorded strokes, varied (moved, scaled, rotated, flipped, recoloured, with another\n * brush or layer), `repeat` times: all of it one undo step. Returns the new strokes.\n */\n replayStrokes(options: ReplayOptions): { strokeIds: string[]; bounds: RasterRect | null; layerIds: string[] } {\n this.requireIdle('replaying');\n if (!options.strokeIds?.length) throw new PaintEditorError('strokeIds is empty; pass ids from list_strokes.');\n const strokes = options.strokeIds.map((id) => {\n const s = this.doc.strokes.find((x) => x.id === id);\n if (!s) throw new PaintEditorError(`Unknown stroke \"${id}\". Call list_strokes for the ids.`);\n return s;\n });\n const repeat = options.repeat ?? 1;\n if (!Number.isInteger(repeat) || repeat < 1 || repeat > 100) throw new PaintEditorError(`repeat ${repeat} is out of range; use 1..100.`);\n if (options.scale !== undefined && !(options.scale > 0 && options.scale <= 20)) throw new PaintEditorError(`scale ${options.scale} is out of range; use above 0 up to 20.`);\n if (options.color !== undefined) parseColor(options.color);\n if (options.brushId !== undefined) this.requireBrush(options.brushId);\n if (options.layerId !== undefined) this.paintTarget(options.layerId, 'replay onto');\n let origin = options.origin;\n if (!origin) {\n const b = strokeBounds(strokes.flatMap((s) => s.points));\n origin = { x: b.x + b.width / 2, y: b.y + b.height / 2 };\n }\n const step = variationAffine(options, origin);\n let doc = this.doc;\n let bounds: RasterRect | null = null;\n const ids: string[] = [];\n const layerIds = new Set<string>();\n let m: Affine = IDENTITY_AFFINE;\n for (let k = 0; k < repeat; k++) {\n m = [step[0] * m[0] + step[1] * m[2], step[0] * m[1] + step[1] * m[3], step[2] * m[0] + step[3] * m[2], step[2] * m[1] + step[3] * m[3], step[0] * m[4] + step[1] * m[5] + step[4], step[2] * m[4] + step[3] * m[5] + step[5]];\n for (const s of strokes) {\n const v = varyStroke(s, m, options);\n let brush = v.brush;\n if (options.brushId !== undefined) {\n const b = this.requireBrush(options.brushId);\n brush = normalizePaintBrush({ tip: { ...b.tip, size: b.tip.size * (v.brush.tip.size / s.brush.tip.size) } }, b);\n }\n const layerId = options.layerId ?? s.layerId;\n if (!findLayer(doc.layers, layerId)) throw new PaintEditorError(`Stroke \"${s.id}\" was painted on layer \"${layerId}\", which no longer exists; pass layerId to replay it elsewhere.`);\n const run = this.runStroke(doc, { layerId, color: options.color ?? s.color, brush, seed: s.seed, copies: v.copies ?? [] }, v.points);\n doc = run.doc;\n bounds = unionRect(bounds, run.result.bounds);\n if (run.result.strokeId) ids.push(run.result.strokeId);\n layerIds.add(layerId);\n }\n }\n if (doc !== this.doc) this.commit(strokes.length === 1 && repeat === 1 ? 'Replay stroke' : 'Replay strokes', doc);\n return { strokeIds: ids, bounds, layerIds: [...layerIds] };\n }\n\n // --- Rendering -----------------------------------------------------------------\n\n private sources() {\n return { width: this.doc.canvas.width, height: this.doc.canvas.height };\n }\n\n /** The layers with the live stroke's surface in place. */\n private currentLayers(): PaintLayer[] {\n const live = this.live;\n if (!live) return this.doc.layers;\n if (this.liveLayers?.key === live.surface) return this.liveLayers.layers;\n const layers = mapLayer(this.doc.layers, live.layerId, (l) => ({ ...(l as PaintPixelLayer), surface: live.surface }));\n this.liveLayers = { key: live.surface, layers };\n return layers;\n }\n\n /** View-only layers between the paper and the paint (the painting guides add the tracing image). */\n protected underlayLayers(): ViewLayer[] {\n const t = this.guides.tracing;\n if (!t || !t.visible) return [];\n return [this.tracingNode(t)];\n }\n\n /** The tracing image resampled onto the canvas (cached until it or the canvas changes). */\n private tracingNode(t: TracingImage): ImageNode {\n const { width, height } = this.doc.canvas;\n const key = this.tracingVersion * 100003 + width * 7 + height;\n if (this.tracingCache?.key === key && this.tracingCache.node.opacity === t.opacity) return this.tracingCache.node;\n const src = this.imagePixels.get(t.src) ?? this.decodeImage(t.src);\n const image = resampleInto(src, t.rect, width, height);\n const node: ImageNode = { type: 'image', id: TRACING_NODE_ID, name: 'Tracing', visible: true, opacity: t.opacity, blend: 'normal', image, version: key + Math.round(t.opacity * 1000) / 1e4 };\n this.tracingCache = { key, node };\n return node;\n }\n\n private renderLayers(options: RenderOptions, view = false): ViewLayer[] {\n let layers: PaintLayer[] = this.currentLayers();\n if (options.layerIds) {\n const picked: PaintLayer[] = [];\n for (const id of options.layerIds) picked.push(this.requireLayer(id));\n layers = picked.map((l) => ({ ...l, visible: true }) as PaintLayer);\n }\n const under: ViewLayer[] = options.paper === false ? [] : [paperNode(this.doc.paper)];\n if (view) under.push(...this.underlayLayers());\n return [...under, ...layers];\n }\n\n /**\n * Composites the viewport stack (paper, view-only underlays, layers with the live stroke) tile by\n * tile over `rect`, calling `onTile` with each 256 px tile's RGBA (cached: unchanged tiles come back\n * as the same buffer). Pass `takeDirty()` as `dirty`.\n */\n compositeTiles(rect: RasterRect, onTile: (tx: number, ty: number, data: Uint8ClampedArray, changed: boolean) => void, options: { dirty?: RasterRect[] | 'all' } = {}): void {\n const dirty = options.dirty === 'all' ? undefined : options.dirty;\n this.viewCompositor.compositeTiles(this.renderLayers({}, true), rect, this.sources(), onTile, { dirty, checkpointLayerId: this.live?.layerId ?? this.doc.activeLayerId });\n }\n\n /** The canvas as canvas-sized RGBA (paper included by default). */\n compositePixels(options: RenderOptions = {}): PixelImage {\n const { width, height } = this.doc.canvas;\n const data = this.exportCompositor.composite(this.renderLayers(options), { x: 0, y: 0, width, height }, this.sources());\n return { width, height, data };\n }\n\n /** The canvas (or some layers), scaled so the longest side is at most `maxSide`. */\n renderPreview(options: RenderOptions & { maxSide?: number } = {}): PixelImage {\n const full = this.compositePixels(options);\n const side = Math.max(1, Math.round(options.maxSide ?? 512));\n const k = Math.min(1, side / Math.max(full.width, full.height));\n if (k >= 1) return full;\n const w = Math.max(1, Math.round(full.width * k));\n const h = Math.max(1, Math.round(full.height * k));\n return { width: w, height: h, data: downsampleRgba(full.data, full.width, full.height, w, h) };\n }\n\n // --- Save, load and export -------------------------------------------------------\n\n /** The document as JSON with inline PNG assets. */\n toJSON(options: { strokes?: boolean } = {}): SerializedPaintDocument {\n return serializePaintDocument(this.doc, { strokes: options.strokes, extensions: this.extensions, guides: this.guides, swatches: this.swatches });\n }\n\n /** The document as JSON with each PNG stored in `store`. */\n toJSONExternal(store: PaintAssetStore, options: { strokes?: boolean } = {}): Promise<SerializedPaintDocument> {\n return serializePaintDocumentExternal(this.doc, store, { strokes: options.strokes, extensions: this.extensions, guides: this.guides, swatches: this.swatches });\n }\n\n private adopt(loaded: { state: PaintDocumentState; extensions: PaintDocumentExtensions; problems: string[]; guides?: unknown; swatches?: unknown }): string[] {\n this.extensions = loaded.extensions;\n this.readGuides(loaded.guides, loaded.state, loaded.problems);\n if (Array.isArray(loaded.swatches)) {\n this.swatches = loaded.swatches\n .filter((x): x is Swatch => Boolean(x) && typeof (x as Swatch).color === 'string' && /^#[0-9a-f]{6}$/i.test((x as Swatch).color))\n .map((x) => (typeof x.name === 'string' ? { color: x.color.toLowerCase(), name: x.name } : { color: x.color.toLowerCase() }));\n }\n for (const s of loaded.state.strokes) {\n const n = Number(/^s(\\d+)$/.exec(s.id)?.[1] ?? 0);\n if (n >= this.strokeCounter) this.strokeCounter = n + 1;\n }\n this.undoStack = [];\n this.redoStack = [];\n this.doc = loaded.state;\n this.viewCompositor.clear();\n this.emit();\n return loaded.problems;\n }\n\n /** Opens a saved document (clears the history). Returns what could not be read. */\n loadJSON(raw: unknown): string[] {\n this.requireIdle('opening a document');\n try {\n return this.adopt(deserializePaintDocument(raw));\n } catch (e) {\n throw new PaintEditorError((e as Error).message);\n }\n }\n\n /** Opens a saved document whose assets may live in `store`. */\n async loadJSONAsync(raw: unknown, store?: PaintAssetStore): Promise<string[]> {\n this.requireIdle('opening a document');\n try {\n return this.adopt(await deserializePaintDocumentAsync(raw, store));\n } catch (e) {\n throw new PaintEditorError((e as Error).message);\n }\n }\n\n /** The canvas as PNG bytes (paper included by default; `scale` below 1 shrinks it). */\n exportPng(options: RenderOptions & { scale?: number } = {}): Uint8Array {\n const img = this.scaled(options);\n return encodePng(img.width, img.height, img.data);\n }\n\n private scaled(options: RenderOptions & { scale?: number }): PixelImage {\n const full = this.compositePixels(options);\n const s = options.scale ?? 1;\n if (!(s > 0 && s <= 1)) throw new PaintEditorError(`scale ${s} is out of range; use above 0 up to 1 (exports never upscale pixels).`);\n if (s === 1) return full;\n const w = Math.max(1, Math.round(full.width * s));\n const h = Math.max(1, Math.round(full.height * s));\n return { width: w, height: h, data: downsampleRgba(full.data, full.width, full.height, w, h) };\n }\n\n /**\n * The canvas as PNG, JPEG or WebP bytes. JPEG has no alpha, so it always includes the paper.\n * JPEG and WebP need a canvas (a browser or Worker) or the `encodeImage` option.\n */\n async exportImage(options: RenderOptions & { format?: ImageFormat; quality?: number; scale?: number } = {}): Promise<Uint8Array> {\n const format = options.format ?? 'image/png';\n if (format === 'image/png') return this.exportPng(options);\n if (format !== 'image/jpeg' && format !== 'image/webp') throw new PaintEditorError(`format ${JSON.stringify(format)} is not supported; use image/png, image/jpeg or image/webp.`);\n const quality = options.quality ?? 0.92;\n if (!(quality >= 0 && quality <= 1)) throw new PaintEditorError(`quality ${quality} is out of range; use 0..1.`);\n const img = this.scaled({ ...options, paper: format === 'image/jpeg' ? true : options.paper });\n const encode = this.encodeImage ?? defaultImageEncoder();\n if (!encode) throw new PaintEditorError(`${format} needs a canvas to encode and there is none here; pass encodeImage to the controller, or export PNG.`);\n return encode(img, format, quality);\n }\n\n /**\n * The document as an 8-bit RGB PSD through the shared PSD writer: every layer and group, with\n * the paper as a locked \"Paper\" pixel layer at the bottom (it is generated, so PSD gets its\n * pixels), and the composite as the merged image.\n */\n exportPsd(): PsdExportResult {\n const { width, height, dpi } = this.doc.canvas;\n const paperPixels = this.compositePixels({ layerIds: [], paper: true });\n const paperLayer: PaintPixelLayer = {\n type: 'pixel',\n id: 'paper',\n name: 'Paper',\n visible: true,\n opacity: 1,\n blend: 'normal',\n locks: { all: true },\n surface: surfaceFromPixels(paperPixels, 4),\n offset: { x: 0, y: 0 },\n };\n const merged = this.compositePixels({ paper: true }).data;\n // PSD has no pigment or painterly modes: write each as its nearest standard mode and say so.\n const changed = new Map<BlendMode, string[]>();\n const toStandard = (layers: readonly PaintLayer[]): PaintLayer[] =>\n layers.map((l) => {\n const blend = l.blend === 'pass-through' ? l.blend : standardBlendMode(l.blend as BlendMode);\n if (blend !== l.blend) changed.set(l.blend as BlendMode, [...(changed.get(l.blend as BlendMode) ?? []), l.name]);\n const next = blend === l.blend ? l : ({ ...l, blend } as PaintLayer);\n return next.type === 'group' ? { ...next, children: toStandard(next.children) } : next;\n });\n const layers = toStandard(this.doc.layers);\n const result = exportPsd({ width, height, layers: [paperLayer, ...layers] as unknown as ImageLayer[], merged, resolution: dpi });\n for (const [mode, names] of changed) {\n const label = BLEND_MODES.find((m) => m.id === mode)?.label ?? mode;\n const std = BLEND_MODES.find((m) => m.id === standardBlendMode(mode))?.label ?? standardBlendMode(mode);\n const list = names.map((n) => `\"${n}\"`).join(', ');\n const one = names.length === 1;\n result.warnings.push(`${label} blending has no PSD equivalent; ${list} ${one ? 'was' : 'were'} written as ${std}, the nearest Photoshop mode, so ${one ? 'it looks' : 'they look'} different in Photoshop (the merged image is exact).`);\n }\n return result;\n }\n\n /** `render_preview` as a base64 PNG. */\n previewPngBase64(options: RenderOptions & { maxSide?: number } = {}): { data: string; width: number; height: number } {\n const img = this.renderPreview(options);\n return { data: bytesToBase64(encodePng(img.width, img.height, img.data)), width: img.width, height: img.height };\n }\n\n // --- Guides --------------------------------------------------------------------\n\n private setGuides(next: PaintGuides): PaintGuides {\n this.guides = next;\n this.emit('all');\n return next;\n }\n\n /** Mirror and kaleidoscope painting: every new stroke paints its copies too (one stroke, one undo step). */\n setSymmetry(update: Partial<SymmetryGuide>): SymmetryGuide {\n const symmetry = normalizeSymmetry(update, this.guides.symmetry);\n this.setGuides({ ...this.guides, symmetry });\n return symmetry;\n }\n\n /** Perspective guides with one to three vanishing points that pointer strokes snap to. */\n setPerspective(update: Partial<PerspectiveGuide>): PerspectiveGuide {\n let perspective: PerspectiveGuide;\n try {\n perspective = normalizePerspective(update, this.guides.perspective);\n } catch (e) {\n throw new PaintEditorError((e as Error).message);\n }\n this.setGuides({ ...this.guides, perspective });\n return perspective;\n }\n\n /** An image from a PNG (base64 or data URL) or from RGBA pixels, stored as a PNG data URL. */\n private importImage(input: { png?: string; pixels?: PixelImage }, what: string): { src: string; pixels: PixelImage } {\n let pixels: PixelImage;\n if (input.pixels) {\n const { width, height, data } = input.pixels;\n if (!(width > 0 && height > 0 && Number.isInteger(width) && Number.isInteger(height)) || data.length !== width * height * 4) {\n throw new PaintEditorError(`${what}: pixels must be width × height × 4 bytes of RGBA.`);\n }\n pixels = { width, height, data: new Uint8ClampedArray(data) };\n } else if (typeof input.png === 'string' && input.png.trim()) {\n pixels = this.decodeImage(input.png.trim().startsWith('data:') ? input.png.trim() : `data:image/png;base64,${input.png.trim()}`, what);\n } else throw new PaintEditorError(`${what}: pass png (a PNG as base64 or a data URL) or pixels.`);\n if (pixels.width > MAX_IMAGE_SIDE || pixels.height > MAX_IMAGE_SIDE) throw new PaintEditorError(`${what} is ${pixels.width}×${pixels.height}; the limit is ${MAX_IMAGE_SIDE} px per side.`);\n const src = pngDataUrl(pixels.width, pixels.height, pixels.data);\n this.imagePixels.set(src, pixels);\n return { src, pixels };\n }\n\n private decodeImage(src: string, what = 'Image'): PixelImage {\n const cached = this.imagePixels.get(src);\n if (cached) return cached;\n const parsed = parseDataUrl(src);\n if (!parsed) throw new PaintEditorError(`${what} is not a data URL or base64 PNG.`);\n try {\n const png = decodePng(parsed.bytes);\n const px = { width: png.width, height: png.height, data: png.data };\n this.imagePixels.set(src, px);\n return px;\n } catch (e) {\n throw new PaintEditorError(`${what} could not be decoded as a PNG (${(e as Error).message}); decode other formats in the browser and pass pixels.`);\n }\n }\n\n /**\n * Puts an image under the paint to trace over: view only, never in exports. Placed to fit the\n * canvas unless `rect` is given; `sampleColors` makes strokes take their colour from it.\n */\n setTracingImage(options: { png?: string; pixels?: PixelImage; rect?: TracingImage['rect']; opacity?: number; sampleColors?: boolean }): TracingImage {\n const { src, pixels } = this.importImage(options, 'The tracing image');\n const { width, height } = this.doc.canvas;\n const k = Math.min(width / pixels.width, height / pixels.height);\n const fit = { x: (width - pixels.width * k) / 2, y: (height - pixels.height * k) / 2, width: pixels.width * k, height: pixels.height * k };\n const tracing: TracingImage = { src, width: pixels.width, height: pixels.height, rect: fit, opacity: 0.35, visible: true, sampleColors: false };\n return this.updateTracing({ ...options, rect: options.rect ?? fit }, tracing);\n }\n\n /** Changes the tracing image's opacity, visibility, placement or colour sampling. */\n updateTracing(update: Partial<Pick<TracingImage, 'opacity' | 'visible' | 'sampleColors' | 'rect'>>, base = this.guides.tracing): TracingImage {\n if (!base) throw new PaintEditorError('There is no tracing image; set one with set_tracing_image first.');\n if (update.opacity !== undefined && !(update.opacity >= 0 && update.opacity <= 1)) throw new PaintEditorError(`opacity ${update.opacity} is out of range; use 0..1.`);\n if (update.rect && !(update.rect.width > 0 && update.rect.height > 0)) throw new PaintEditorError('rect needs a width and height above 0.');\n const tracing: TracingImage = {\n ...base,\n ...(update.opacity !== undefined ? { opacity: update.opacity } : {}),\n ...(update.visible !== undefined ? { visible: update.visible } : {}),\n ...(update.sampleColors !== undefined ? { sampleColors: update.sampleColors } : {}),\n ...(update.rect ? { rect: { ...update.rect } } : {}),\n };\n if (tracing.src !== base.src || update.rect) this.tracingVersion++;\n if (base !== this.guides.tracing) this.tracingVersion++;\n this.setGuides({ ...this.guides, tracing });\n return tracing;\n }\n\n clearTracingImage(): void {\n this.tracingVersion++;\n this.setGuides({ ...this.guides, tracing: null });\n }\n\n /** The tracing image's colour at a document pixel, or `null` outside it or where it is clear. */\n sampleTracingColor(x: number, y: number): string | null {\n const t = this.guides.tracing;\n if (!t) return null;\n const src = this.decodeImage(t.src);\n const u = Math.floor(((x - t.rect.x) / t.rect.width) * src.width);\n const v = Math.floor(((y - t.rect.y) / t.rect.height) * src.height);\n if (u < 0 || v < 0 || u >= src.width || v >= src.height) return null;\n const i = (v * src.width + u) * 4;\n if (src.data[i + 3] === 0) return null;\n return rgbToHex(src.data[i], src.data[i + 1], src.data[i + 2]);\n }\n\n /** Adds a floating reference image to look at and pick colours from. */\n addReferenceImage(options: { png?: string; pixels?: PixelImage; name?: string; x?: number; y?: number; displayWidth?: number }): ReferenceImage {\n const { src, pixels } = this.importImage(options, 'The reference image');\n const ref: ReferenceImage = {\n id: `ref${this.nextReferenceId++}`,\n name: options.name?.trim() || `Reference ${this.guides.references.length + 1}`,\n src,\n width: pixels.width,\n height: pixels.height,\n x: options.x ?? 16 + this.guides.references.length * 24,\n y: options.y ?? 16 + this.guides.references.length * 24,\n displayWidth: options.displayWidth ?? Math.min(240, pixels.width),\n visible: true,\n };\n this.setGuides({ ...this.guides, references: [...this.guides.references, ref] });\n return ref;\n }\n\n private requireReference(id: string): ReferenceImage {\n const r = this.guides.references.find((x) => x.id === id);\n if (!r) throw new PaintEditorError(`Unknown reference image \"${id}\". Call list_reference_images for the ids.`);\n return r;\n }\n\n /** Moves, resizes, renames, shows or hides a reference image. */\n updateReferenceImage(id: string, update: Partial<Pick<ReferenceImage, 'name' | 'x' | 'y' | 'displayWidth' | 'visible'>>): ReferenceImage {\n const r = this.requireReference(id);\n if (update.displayWidth !== undefined && !(update.displayWidth >= 16 && update.displayWidth <= 4096)) throw new PaintEditorError(`displayWidth ${update.displayWidth} is out of range; use 16..4096.`);\n const next: ReferenceImage = { ...r, ...Object.fromEntries(Object.entries(update).filter(([, v]) => v !== undefined)) };\n this.setGuides({ ...this.guides, references: this.guides.references.map((x) => (x.id === id ? next : x)) });\n return next;\n }\n\n removeReferenceImage(id: string): void {\n this.requireReference(id);\n this.setGuides({ ...this.guides, references: this.guides.references.filter((x) => x.id !== id) });\n }\n\n /** A reference image's pixels (decoded once). */\n referencePixels(id: string): PixelImage {\n return this.decodeImage(this.requireReference(id).src);\n }\n\n /** The colour of a reference image at its pixel (x, y). */\n pickReferenceColor(id: string, x: number, y: number): string {\n const r = this.requireReference(id);\n const px = this.decodeImage(r.src);\n const u = Math.floor(x);\n const v = Math.floor(y);\n if (!(u >= 0 && v >= 0 && u < px.width && v < px.height)) throw new PaintEditorError(`(${x}, ${y}) is outside reference \"${r.name}\" (${px.width}×${px.height}); use its own pixel coordinates.`);\n const i = (v * px.width + u) * 4;\n return rgbToHex(px.data[i], px.data[i + 1], px.data[i + 2]);\n }\n\n private readGuides(raw: unknown, state: PaintDocumentState, problems: string[]): void {\n const base = defaultGuides(state.canvas);\n this.guides = base;\n this.tracingVersion++;\n if (!raw || typeof raw !== 'object') return;\n const r = raw as Record<string, unknown>;\n const guides: PaintGuides = { ...base };\n guides.symmetry = normalizeSymmetry((r.symmetry as Record<string, unknown>) ?? {}, base.symmetry);\n try {\n guides.perspective = normalizePerspective((r.perspective as Record<string, unknown>) ?? {}, base.perspective);\n } catch (e) {\n problems.push(`Perspective guide: ${(e as Error).message}`);\n }\n const t = r.tracing as TracingImage | null | undefined;\n if (t && typeof t.src === 'string') {\n try {\n const px = this.decodeImage(t.src, 'The tracing image');\n guides.tracing = {\n src: t.src,\n width: px.width,\n height: px.height,\n rect: t.rect && t.rect.width > 0 && t.rect.height > 0 ? { ...t.rect } : { x: 0, y: 0, width: state.canvas.width, height: state.canvas.height },\n opacity: typeof t.opacity === 'number' ? Math.min(1, Math.max(0, t.opacity)) : 0.35,\n visible: t.visible !== false,\n sampleColors: t.sampleColors === true,\n };\n } catch (e) {\n problems.push((e as Error).message);\n }\n }\n if (Array.isArray(r.references)) {\n for (const ref of r.references as ReferenceImage[]) {\n if (!ref || typeof ref.src !== 'string' || typeof ref.id !== 'string') continue;\n try {\n const px = this.decodeImage(ref.src, `Reference \"${ref.name}\"`);\n guides.references.push({ id: ref.id, name: String(ref.name ?? ref.id), src: ref.src, width: px.width, height: px.height, x: Number(ref.x) || 0, y: Number(ref.y) || 0, displayWidth: Number(ref.displayWidth) || 240, visible: ref.visible !== false });\n const n = Number(/^ref(\\d+)$/.exec(ref.id)?.[1] ?? 0);\n if (n >= this.nextReferenceId) this.nextReferenceId = n + 1;\n } catch (e) {\n problems.push((e as Error).message);\n }\n }\n }\n this.guides = guides;\n }\n\n // --- Swatches and harmonies ------------------------------------------------------\n\n /** Colour harmonies around a colour (default the paint colour) on the painter's RYB wheel or the RGB wheel. */\n harmony(kind: HarmonyKind, options: { color?: string; wheel?: ColorWheel; spread?: number } = {}): HarmonyColor[] {\n try {\n return colorHarmony(options.color === undefined ? this.color : parseColor(options.color), kind, options);\n } catch (e) {\n throw new PaintEditorError((e as Error).message);\n }\n }\n\n addSwatch(color: string, name?: string): Swatch[] {\n const c = parseColor(color);\n this.swatches = [...this.swatches, name?.trim() ? { color: c, name: name.trim() } : { color: c }];\n this.emit([]);\n return this.swatches;\n }\n\n removeSwatch(index: number): Swatch[] {\n if (!Number.isInteger(index) || index < 0 || index >= this.swatches.length) throw new PaintEditorError(`index ${index} is out of range; there are ${this.swatches.length} swatches (0-based).`);\n this.swatches = this.swatches.filter((_, i) => i !== index);\n this.emit([]);\n return this.swatches;\n }\n\n setSwatches(swatches: readonly Swatch[]): Swatch[] {\n this.swatches = swatches.map((x) => (x.name ? { color: parseColor(x.color), name: x.name } : { color: parseColor(x.color) }));\n this.emit([]);\n return this.swatches;\n }\n\n // --- Mixing pad ------------------------------------------------------------------\n\n get mixingPad(): MixingPad {\n return this.pad;\n }\n\n /** Paints (`paint`) or smears with the palette knife (`knife`) on the mixing pad, in pad pixels. */\n mixingPadStroke(points: readonly PenPoint[], options: { tool?: MixingPadTool; color?: string; size?: number } = {}): { bounds: RasterRect | null } {\n const color = options.color === undefined ? this.color : parseColor(options.color);\n if (options.size !== undefined && !(options.size >= 1 && options.size <= 200)) throw new PaintEditorError(`size ${options.size} is out of range; use 1..200 px.`);\n try {\n const r = this.pad.stroke(points, { tool: options.tool ?? 'paint', color, size: options.size });\n this.emit([]);\n return r;\n } catch (e) {\n throw new PaintEditorError((e as Error).message);\n }\n }\n\n /** Picks the mixed colour on the pad (averaged over `radius` px); with `setColor` it becomes the paint colour. */\n mixingPadPick(x: number, y: number, options: { radius?: number; setColor?: boolean } = {}): string | null {\n let c: string | null;\n try {\n c = this.pad.pick(x, y, options.radius);\n } catch (e) {\n throw new PaintEditorError((e as Error).message);\n }\n if (c && options.setColor) this.setColor(c);\n return c;\n }\n\n clearMixingPad(): void {\n this.pad.clear();\n this.emit([]);\n }\n\n /** A layer's tile surface (live while stroking), for thumbnails. */\n layerSurface(id: string): TiledSurface | null {\n const l = findLayer(this.currentLayers(), id)?.layer;\n return isPixelLayer(l) ? l.surface : null;\n }\n}\n\nexport type { Tile };\n\n/** Largest tracing or reference image side, in pixels. */\nexport const MAX_IMAGE_SIDE = 8192;\n\n/** `src` drawn into `rect` of a `width × height` canvas (bilinear), canvas-sized RGBA. */\nfunction resampleInto(src: PixelImage, rect: { x: number; y: number; width: number; height: number }, width: number, height: number): PixelImage {\n const out = new Uint8ClampedArray(width * height * 4);\n const x0 = Math.max(0, Math.floor(rect.x));\n const y0 = Math.max(0, Math.floor(rect.y));\n const x1 = Math.min(width, Math.ceil(rect.x + rect.width));\n const y1 = Math.min(height, Math.ceil(rect.y + rect.height));\n const sx = src.width / rect.width;\n const sy = src.height / rect.height;\n const d = src.data;\n for (let y = y0; y < y1; y++) {\n const v = Math.min(src.height - 1, Math.max(0, (y + 0.5 - rect.y) * sy - 0.5));\n const j0 = Math.floor(v);\n const j1 = Math.min(src.height - 1, j0 + 1);\n const fy = v - j0;\n for (let x = x0; x < x1; x++) {\n const u = (x + 0.5 - rect.x) * sx - 0.5;\n if (u < -0.5 || u > src.width - 0.5 || (y + 0.5 - rect.y) * sy < 0 || (y + 0.5 - rect.y) * sy > src.height) continue;\n const uc = Math.min(src.width - 1, Math.max(0, u));\n const i0 = Math.floor(uc);\n const i1 = Math.min(src.width - 1, i0 + 1);\n const fx = uc - i0;\n const o = (y * width + x) * 4;\n for (let c = 0; c < 4; c++) {\n const a = d[(j0 * src.width + i0) * 4 + c] + (d[(j0 * src.width + i1) * 4 + c] - d[(j0 * src.width + i0) * 4 + c]) * fx;\n const b = d[(j1 * src.width + i0) * 4 + c] + (d[(j1 * src.width + i1) * 4 + c] - d[(j1 * src.width + i0) * 4 + c]) * fx;\n out[o + c] = a + (b - a) * fy;\n }\n }\n }\n return { width, height, data: out };\n}\n","// Agent \"performances\" on the paint canvas, after the chart and diagram directors (see\n// `animation/presence.ts`): a director acts each command out with the agent's cursor in document\n// pixels, so a stroke is painted live along its path (the canvas updates as the dabs land) and\n// commits as one undo step, a fill is rubbed across the sheet, and a replay starts from the strokes\n// it copies. The clock is injectable so performances are repeatable in tests.\nimport {\n PerformanceQueue,\n PresenceStore,\n realPresenceClock,\n tweenPresenceCursor,\n type PresenceActor,\n type PresenceActorInfo,\n type PresenceClock,\n type PresenceState,\n} from '../animation/presence';\nimport type { RasterRect } from '../raster/surface';\nimport type { FillLayerOptions, PaintEditorController, PaintStrokeInit, ReplayOptions } from './controller';\nimport type { PenPoint } from './engine';\nimport type { PaintStrokeResult } from './stroke';\n\nexport type PaintPresenceActor = PresenceActor;\nexport type PaintPresenceState = PresenceState;\n\n/** Cursor positions (document pixels) and notes of agents painting, for an overlay. */\nexport class PaintPresence extends PresenceStore {}\n\n/** What an agent asks for. Each command that paints commits as one undo step. */\nexport type PaintAgentCommand =\n | { kind: 'stroke'; stroke: PaintStrokeInit & { points: readonly PenPoint[] }; note?: string }\n | { kind: 'fill'; fill: FillLayerOptions; note?: string }\n | { kind: 'replay'; replay: ReplayOptions; note?: string }\n | { kind: 'point'; at: { x: number; y: number }; note?: string }\n | { kind: 'say'; text: string };\n\nexport type PaintPerformanceResult =\n | { ok: true; command: PaintAgentCommand; result?: unknown }\n | { ok: false; command: PaintAgentCommand; message: string };\n\nexport interface PaintDirectorOptions {\n clock?: PresenceClock;\n /** 1 = natural speed; 2 = twice as fast. */\n speed?: number;\n /** Hide each actor's cursor this long after its last command (ms, default 1500; 0 keeps it). */\n linger?: number;\n /** Longest a stroke takes to paint at speed 1 (ms, default 1800); longer strokes are sped up. */\n maxStrokeMs?: number;\n}\n\nconst FRAME = 16;\n\n/** Where along a stroke each point is reached, 0..1: by its time `t` when the points have times, else by distance. */\nexport function strokeSchedule(points: readonly PenPoint[]): number[] {\n if (points.length < 2) return points.map(() => 1);\n const t0 = points[0]!.t;\n const t1 = points[points.length - 1]!.t;\n if (points.every((p) => Number.isFinite(p.t)) && (t1 as number) > (t0 as number)) {\n return points.map((p) => Math.min(1, Math.max(0, ((p.t as number) - (t0 as number)) / ((t1 as number) - (t0 as number)))));\n }\n const acc = [0];\n for (let i = 1; i < points.length; i++) acc.push(acc[i - 1]! + Math.hypot(points[i]!.x - points[i - 1]!.x, points[i]!.y - points[i - 1]!.y));\n const total = acc[acc.length - 1]!;\n return total > 0 ? acc.map((d) => d / total) : points.map(() => 1);\n}\n\n/** How long a stroke takes to paint at speed 1 (ms): its recorded duration, else ~1.5 px/ms, between 250 ms and `max`. */\nexport function strokeDuration(points: readonly PenPoint[], max = 1800): number {\n const t0 = points[0]?.t;\n const t1 = points[points.length - 1]?.t;\n let ms: number;\n if (points.every((p) => Number.isFinite(p.t)) && (t1 as number) > (t0 as number)) ms = (t1 as number) - (t0 as number);\n else {\n let length = 0;\n for (let i = 1; i < points.length; i++) length += Math.hypot(points[i]!.x - points[i - 1]!.x, points[i]!.y - points[i - 1]!.y);\n ms = length / 1.5;\n }\n return Math.min(max, Math.max(250, ms));\n}\n\n/** A zig-zag across `rect` (for a fill rubbed over the sheet), `rows` passes from the top. */\nexport function sweepPath(rect: RasterRect, rows = 4): Array<{ x: number; y: number }> {\n const inset = Math.min(rect.width, rect.height) * 0.08;\n const left = rect.x + inset;\n const right = rect.x + rect.width - inset;\n const out: Array<{ x: number; y: number }> = [];\n for (let r = 0; r < rows; r++) {\n const y = rect.y + inset + ((rect.height - 2 * inset) * (r + 0.5)) / rows;\n out.push(r % 2 ? { x: right, y } : { x: left, y }, r % 2 ? { x: left, y } : { x: right, y });\n }\n return out;\n}\n\nconst centre = (r: RasterRect) => ({ x: r.x + r.width / 2, y: r.y + r.height / 2 });\n\n/**\n * Acts out agent commands on a paint canvas: the actor's cursor glides to the stroke's start and\n * paints it live along its points (paced by their times, or evenly), the stroke committing as\n * one undo step; fills are rubbed across the sheet first; replays start from the strokes they\n * copy and end on what they painted. Commands queue per actor. A command that cannot apply (an\n * unknown or locked layer, a stroke the user is still painting) fails with the controller's\n * sentence before anything is painted.\n */\nexport class PaintDirector {\n private readonly clock: PresenceClock;\n private readonly queue: PerformanceQueue;\n\n constructor(\n private readonly controller: PaintEditorController,\n readonly presence: PaintPresence,\n private readonly options: PaintDirectorOptions = {}\n ) {\n this.clock = options.clock ?? realPresenceClock;\n this.queue = new PerformanceQueue(presence, { clock: this.clock, linger: options.linger });\n }\n\n /** Acts out `commands` in order for `actor`. Resolves with one result per command. */\n perform(actor: PresenceActorInfo, commands: readonly PaintAgentCommand[]): Promise<PaintPerformanceResult[]> {\n return this.queue.run(actor, async () => {\n const results: PaintPerformanceResult[] = [];\n for (const command of commands) {\n try {\n results.push({ ok: true, command, result: await this.performOne(actor.id, command) });\n } catch (error) {\n results.push({ ok: false, command, message: error instanceof Error ? error.message : String(error) });\n }\n }\n return results;\n });\n }\n\n private ms(n: number): number {\n return Math.round(n / Math.max(0.1, this.options.speed ?? 1));\n }\n\n private where(id: string) {\n const a = this.presence.get(id);\n return { x: a?.x ?? 0, y: a?.y ?? 0 };\n }\n\n /** Glides to `to`; an actor that just appeared starts there instead of the corner. */\n private async glide(id: string, to: { x: number; y: number }, ms = 380) {\n const a = this.presence.get(id);\n if (!a || (a.x === 0 && a.y === 0)) {\n this.presence.set({ id, x: to.x, y: to.y });\n return;\n }\n await tweenPresenceCursor(this.presence, this.clock, id, this.where(id), to, this.ms(ms));\n }\n\n private async say(id: string, text: string | undefined, ms: number) {\n if (!text) return;\n this.presence.set({ id, message: text });\n await this.clock.wait(this.ms(ms));\n }\n\n private async performOne(id: string, command: PaintAgentCommand): Promise<unknown> {\n const c = this.controller;\n switch (command.kind) {\n case 'say':\n await this.say(id, command.text, 900);\n return undefined;\n case 'point':\n await this.say(id, command.note, 500);\n await this.glide(id, command.at);\n this.presence.set({ id, pressed: true });\n await this.clock.wait(this.ms(110));\n this.presence.set({ id, pressed: false });\n return undefined;\n case 'stroke':\n await this.say(id, command.note, 500);\n return this.stroke(id, command.stroke);\n case 'fill': {\n await this.say(id, command.note, 500);\n const { width, height } = c.getState().document.canvas;\n const path = sweepPath({ x: 0, y: 0, width, height });\n await this.glide(id, path[0]!);\n this.presence.set({ id, pressed: true });\n try {\n for (let i = 1; i < path.length; i++) await tweenPresenceCursor(this.presence, this.clock, id, path[i - 1]!, path[i]!, this.ms(i % 2 ? 260 : 90));\n } finally {\n this.presence.set({ id, pressed: false });\n }\n return c.fillLayer(command.fill);\n }\n case 'replay': {\n await this.say(id, command.note, 500);\n const source = c.getStrokes().filter((s) => command.replay.strokeIds?.includes(s.id));\n const first = source[0]?.points[0];\n if (first) await this.glide(id, first);\n const result = c.replayStrokes(command.replay);\n if (result.bounds) await this.glide(id, centre(result.bounds), 520);\n return result;\n }\n }\n }\n\n /** Paints a stroke live: begins it, pushes its points frame by frame as the cursor reaches them, then ends it (one undo step). */\n private async stroke(id: string, init: PaintStrokeInit & { points: readonly PenPoint[] }): Promise<PaintStrokeResult> {\n const c = this.controller;\n const points = c.checkPoints(init.points);\n const { points: _points, ...rest } = init;\n // Validate the layer and brush (and that nothing else is painting) before moving at all.\n const session = c.beginStroke({ snapToPerspective: false, start: points[0], ...rest });\n try {\n await this.glide(id, points[0]!);\n this.presence.set({ id, pressed: true });\n const at = strokeSchedule(points);\n const duration = this.ms(strokeDuration(points, this.options.maxStrokeMs));\n let next = 0;\n const frames = Math.max(1, Math.round(duration / FRAME));\n for (let f = 1; f <= frames; f++) {\n const t = f / frames;\n const from = next;\n while (next < points.length && at[next]! <= t + 1e-9) next++;\n if (next > from) {\n session.push(points.slice(from, next));\n const p = points[next - 1]!;\n this.presence.set({ id, x: p.x, y: p.y });\n }\n if (f < frames) await this.clock.wait(duration / frames);\n }\n if (next < points.length) session.push(points.slice(next));\n this.presence.set({ id, pressed: false });\n return session.end();\n } catch (error) {\n if (c.activeStroke === session) session.cancel();\n this.presence.set({ id, pressed: false });\n throw error;\n }\n }\n}\n","/**\n * Agent tools for the paint editor's painting guides (symmetry, perspective, tracing and reference\n * images) and colour (harmonies, swatches, the mixing pad). Guides, swatches and the pad are\n * editor state saved with the document (the pad is not saved), not undo steps.\n */\n\nimport type { AgentTool } from '../tools/registry.js';\nimport { bytesToBase64, encodePng } from '../raster/png';\nimport { HARMONY_KINDS } from './color';\nimport type { PaintEditorController } from './controller';\nimport { SYMMETRY_MODES, symmetryCopies, type ReferenceImage, type TracingImage } from './guides';\nimport type { PenPoint } from './engine';\n\nconst READ = { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false } as const;\nconst WRITE = { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false } as const;\nconst SET = { readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: false } as const;\nconst DESTRUCTIVE = { readOnlyHint: false, destructiveHint: true, idempotentHint: false, openWorldHint: false } as const;\nconst EMPTY = { type: 'object', properties: {}, additionalProperties: false } as const;\nconst COLOR = { type: 'string', pattern: '^#[0-9a-fA-F]{6}$', description: 'Colour #rrggbb.' } as const;\nconst POINT = {\n type: 'object',\n properties: { x: { type: 'number', description: 'x in document pixels.' }, y: { type: 'number', description: 'y in document pixels.' } },\n required: ['x', 'y'],\n additionalProperties: false,\n} as const;\nconst RECT = {\n type: 'object',\n description: 'Placement in document pixels.',\n properties: {\n x: { type: 'number', description: 'Left edge.' },\n y: { type: 'number', description: 'Top edge.' },\n width: { type: 'number', exclusiveMinimum: 0, description: 'Width.' },\n height: { type: 'number', exclusiveMinimum: 0, description: 'Height.' },\n },\n required: ['x', 'y', 'width', 'height'],\n additionalProperties: false,\n} as const;\nconst PNG = { type: 'string', minLength: 1, description: 'The image as a PNG, base64 or a data:image/png URL.' } as const;\n\nconst tracingInfo = (t: TracingImage | null) => (t ? { width: t.width, height: t.height, rect: t.rect, opacity: t.opacity, visible: t.visible, sampleColors: t.sampleColors } : null);\nconst refInfo = ({ src: _s, ...r }: ReferenceImage) => r;\n\nexport function createPaintGuideTools(c: PaintEditorController): AgentTool[] {\n const guides = () => c.getState().guides;\n return [\n {\n name: 'get_guides',\n title: 'Get the painting guides',\n description: 'Reads the painting guides: symmetry (mode, centre, rotation, segments, mirror, and how many copies each stroke paints), the perspective guide (vanishing points, snap), the tracing image (size, placement, opacity, visibility, colour sampling) and the reference images.',\n inputSchema: EMPTY,\n annotations: { title: 'Get the painting guides', ...READ },\n handler: () => {\n const g = guides();\n return { symmetry: { ...g.symmetry, copies: symmetryCopies(g.symmetry).length }, perspective: g.perspective, tracing: tracingInfo(g.tracing), references: g.references.map(refInfo) };\n },\n },\n {\n name: 'set_symmetry',\n title: 'Set mirror or kaleidoscope painting',\n description:\n 'Turns symmetry on or off. Every stroke after it also paints its copies, as one stroke and one undo step: vertical, horizontal or diagonal mirror (one copy), dual (four-way), or kaleidoscope with n segments (rotated copies, and with mirror the reflections between them). Editor state, saved with the document. Returns the guide and the number of copies.',\n inputSchema: {\n type: 'object',\n properties: {\n mode: { type: 'string', enum: [...SYMMETRY_MODES], description: 'off, vertical (mirror left / right), horizontal (top / bottom), dual, diagonal or kaleidoscope.' },\n center: { ...POINT, description: 'Centre of the axes in document pixels (default the canvas centre).' },\n rotation: { type: 'number', minimum: -360, maximum: 360, description: 'Turn the axes, degrees clockwise.' },\n segments: { type: 'integer', minimum: 2, maximum: 32, description: 'Kaleidoscope segments (default 6).' },\n mirror: { type: 'boolean', description: 'Kaleidoscope: also reflect alternate segments (default true).' },\n },\n additionalProperties: false,\n },\n annotations: { title: 'Set mirror or kaleidoscope painting', ...SET },\n handler: (a) => {\n const s = c.setSymmetry(a);\n return { ...s, copies: symmetryCopies(s).length };\n },\n },\n {\n name: 'set_perspective_guide',\n title: 'Set the perspective guide',\n description:\n 'Sets one to three vanishing points (document pixels, may be off the canvas). With snap on, pen strokes snap to the line through their start towards a vanishing point (one-point also keeps horizontals and verticals, two-point verticals); for paint_stroke pass snapToPerspective. Editor state, saved with the document. Returns the guide.',\n inputSchema: {\n type: 'object',\n properties: {\n enabled: { type: 'boolean', description: 'Show and use the guide.' },\n points: { type: 'array', minItems: 1, maxItems: 3, items: { ...POINT, description: 'A vanishing point.' }, description: 'The vanishing points.' },\n snap: { type: 'boolean', description: 'Snap strokes to the guide lines (default true).' },\n },\n additionalProperties: false,\n },\n annotations: { title: 'Set the perspective guide', ...SET },\n handler: (a) => c.setPerspective(a),\n },\n {\n name: 'set_tracing_image',\n title: 'Set a tracing image',\n description:\n 'Puts an image under the paint to trace over (view only: never exported), fitted to the canvas unless rect is given, at opacity (default 0.35). With sampleColors, strokes without a colour take the image colour where they start, so painting over it copies its colours. Replaces any tracing image. Returns its size and placement.',\n inputSchema: {\n type: 'object',\n properties: {\n png: PNG,\n rect: RECT,\n opacity: { type: 'number', minimum: 0, maximum: 1, description: 'Opacity 0..1 (default 0.35).' },\n sampleColors: { type: 'boolean', description: 'Strokes take their colour from the image (default false).' },\n },\n required: ['png'],\n additionalProperties: false,\n },\n annotations: { title: 'Set a tracing image', ...WRITE },\n handler: (a) => tracingInfo(c.setTracingImage(a)),\n },\n {\n name: 'update_tracing_image',\n title: 'Change the tracing image',\n description: 'Changes the tracing image opacity, visibility, placement or colour sampling. Returns it.',\n inputSchema: {\n type: 'object',\n properties: {\n opacity: { type: 'number', minimum: 0, maximum: 1, description: 'Opacity 0..1.' },\n visible: { type: 'boolean', description: 'Show or hide it.' },\n sampleColors: { type: 'boolean', description: 'Strokes take their colour from it.' },\n rect: RECT,\n },\n additionalProperties: false,\n },\n annotations: { title: 'Change the tracing image', ...SET },\n handler: (a) => tracingInfo(c.updateTracing(a)),\n },\n {\n name: 'clear_tracing_image',\n title: 'Remove the tracing image',\n description: 'Removes the tracing image. Returns null.',\n inputSchema: EMPTY,\n annotations: { title: 'Remove the tracing image', ...DESTRUCTIVE },\n handler: () => {\n c.clearTracingImage();\n return { tracing: null };\n },\n },\n {\n name: 'add_reference_image',\n title: 'Add a reference image',\n description: 'Adds a floating reference image (shown beside the canvas, never painted) to look at and pick colours from with pick_reference_color. Returns its id, size and placement.',\n inputSchema: {\n type: 'object',\n properties: {\n png: PNG,\n name: { type: 'string', minLength: 1, description: 'Display name.' },\n x: { type: 'number', description: 'Panel left in viewport pixels.' },\n y: { type: 'number', description: 'Panel top in viewport pixels.' },\n displayWidth: { type: 'number', minimum: 16, maximum: 4096, description: 'Panel width in screen pixels (default up to 240).' },\n },\n required: ['png'],\n additionalProperties: false,\n },\n annotations: { title: 'Add a reference image', ...WRITE },\n handler: (a) => refInfo(c.addReferenceImage(a)),\n },\n {\n name: 'list_reference_images',\n title: 'List reference images',\n description: 'Lists the reference images: id, name, size in pixels, panel placement and visibility.',\n inputSchema: EMPTY,\n annotations: { title: 'List reference images', ...READ },\n handler: () => ({ references: guides().references.map(refInfo) }),\n },\n {\n name: 'update_reference_image',\n title: 'Change a reference image',\n description: 'Moves, resizes, renames, shows or hides a reference image panel. Returns it.',\n inputSchema: {\n type: 'object',\n properties: {\n id: { type: 'string', description: 'Reference id from list_reference_images.' },\n name: { type: 'string', minLength: 1, description: 'Display name.' },\n x: { type: 'number', description: 'Panel left in viewport pixels.' },\n y: { type: 'number', description: 'Panel top in viewport pixels.' },\n displayWidth: { type: 'number', minimum: 16, maximum: 4096, description: 'Panel width in screen pixels.' },\n visible: { type: 'boolean', description: 'Show or hide it.' },\n },\n required: ['id'],\n additionalProperties: false,\n },\n annotations: { title: 'Change a reference image', ...SET },\n handler: ({ id, ...u }) => refInfo(c.updateReferenceImage(id, u)),\n },\n {\n name: 'remove_reference_image',\n title: 'Remove a reference image',\n description: 'Removes a reference image. Returns the removed id.',\n inputSchema: { type: 'object', properties: { id: { type: 'string', description: 'Reference id from list_reference_images.' } }, required: ['id'], additionalProperties: false },\n annotations: { title: 'Remove a reference image', ...DESTRUCTIVE },\n handler: ({ id }) => {\n c.removeReferenceImage(id);\n return { removed: id };\n },\n },\n {\n name: 'pick_reference_color',\n title: 'Pick a colour from a reference',\n description: 'Reads the colour of a reference image at its own pixel (x, y). With setColor it becomes the paint colour. Returns #rrggbb.',\n inputSchema: {\n type: 'object',\n properties: {\n id: { type: 'string', description: 'Reference id from list_reference_images.' },\n x: { type: 'number', minimum: 0, description: 'x in the image’s pixels.' },\n y: { type: 'number', minimum: 0, description: 'y in the image’s pixels.' },\n setColor: { type: 'boolean', description: 'Also make it the paint colour (default false).' },\n },\n required: ['id', 'x', 'y'],\n additionalProperties: false,\n },\n annotations: { title: 'Pick a colour from a reference', ...SET },\n handler: ({ id, x, y, setColor }) => {\n const color = c.pickReferenceColor(id, x, y);\n if (setColor) c.setColor(color);\n return { color };\n },\n },\n {\n name: 'color_harmony',\n title: 'Colour harmonies',\n description:\n 'Returns the colours of a harmony around a colour (default the paint colour): complementary, split-complementary, analogous, triadic, tetradic, square or monochromatic, on the painter’s red-yellow-blue wheel (default: red’s complement is green) or the RGB wheel. Changes nothing. Returns the colours with their wheel angles, the base first.',\n inputSchema: {\n type: 'object',\n properties: {\n kind: { type: 'string', enum: [...HARMONY_KINDS], description: 'The harmony.' },\n color: { ...COLOR, description: 'Base colour #rrggbb (default the paint colour).' },\n wheel: { type: 'string', enum: ['ryb', 'rgb'], description: 'ryb (painter’s wheel, default) or rgb.' },\n spread: { type: 'number', minimum: 5, maximum: 90, description: 'Analogous and split-complementary spread in degrees (default 30).' },\n },\n required: ['kind'],\n additionalProperties: false,\n },\n annotations: { title: 'Colour harmonies', ...READ },\n handler: ({ kind, color, wheel, spread }) => ({ kind, wheel: wheel ?? 'ryb', colors: c.harmony(kind, { color, wheel, spread }) }),\n },\n {\n name: 'list_swatches',\n title: 'List swatches',\n description: 'Lists the colour swatches (index, colour, name).',\n inputSchema: EMPTY,\n annotations: { title: 'List swatches', ...READ },\n handler: () => ({ swatches: c.getState().swatches.map((s, index) => ({ index, ...s })) }),\n },\n {\n name: 'add_swatch',\n title: 'Add a swatch',\n description: 'Adds a colour to the swatches (saved with the document). Returns the swatches.',\n inputSchema: {\n type: 'object',\n properties: { color: COLOR, name: { type: 'string', minLength: 1, description: 'Optional name.' } },\n required: ['color'],\n additionalProperties: false,\n },\n annotations: { title: 'Add a swatch', ...WRITE },\n handler: ({ color, name }) => ({ swatches: c.addSwatch(color, name).map((s, index) => ({ index, ...s })) }),\n },\n {\n name: 'remove_swatch',\n title: 'Remove a swatch',\n description: 'Removes a swatch by index (from list_swatches). Returns the swatches.',\n inputSchema: { type: 'object', properties: { index: { type: 'integer', minimum: 0, description: '0-based index.' } }, required: ['index'], additionalProperties: false },\n annotations: { title: 'Remove a swatch', ...DESTRUCTIVE },\n handler: ({ index }) => ({ swatches: c.removeSwatch(index).map((s, i) => ({ index: i, ...s })) }),\n },\n {\n name: 'mixing_pad_stroke',\n title: 'Paint on the mixing pad',\n description:\n 'Paints on the mixing pad (a 360 × 220 scratch canvas, not the painting): tool paint lays down a colour with a pigment Mixer Brush; tool knife smears what is there like a palette knife, mixing it as paint. Points are pad pixels. Not an undo step. Returns the changed bounds; then pick_mixing_pad_color.',\n inputSchema: {\n type: 'object',\n properties: {\n points: {\n type: 'array',\n minItems: 1,\n maxItems: 2000,\n description: 'The path in pad pixels (0..360, 0..220).',\n items: {\n type: 'object',\n properties: { x: { type: 'number', description: 'Pad x.' }, y: { type: 'number', description: 'Pad y.' }, pressure: { type: 'number', minimum: 0, maximum: 1, description: 'Pressure (default 1).' } },\n required: ['x', 'y'],\n additionalProperties: false,\n },\n },\n tool: { type: 'string', enum: ['paint', 'knife'], description: 'paint (default) or knife.' },\n color: { ...COLOR, description: 'Paint colour (default the paint colour; ignored by the knife).' },\n size: { type: 'number', minimum: 1, maximum: 200, description: 'Tool size in pad pixels (default 28 paint, 34 knife).' },\n },\n required: ['points'],\n additionalProperties: false,\n },\n annotations: { title: 'Paint on the mixing pad', ...WRITE },\n handler: ({ points, tool, color, size }) => c.mixingPadStroke(points as PenPoint[], { tool, color, size }),\n },\n {\n name: 'pick_mixing_pad_color',\n title: 'Pick from the mixing pad',\n description: 'Reads the mixed colour on the pad at (x, y), averaged over radius pixels (default 3); with setColor it becomes the paint colour. Returns #rrggbb, or null where the pad is bare.',\n inputSchema: {\n type: 'object',\n properties: {\n x: { type: 'number', minimum: 0, maximum: 360, description: 'Pad x.' },\n y: { type: 'number', minimum: 0, maximum: 220, description: 'Pad y.' },\n radius: { type: 'integer', minimum: 0, maximum: 20, description: 'Averaging radius in pixels (default 3).' },\n setColor: { type: 'boolean', description: 'Also make it the paint colour (default false).' },\n },\n required: ['x', 'y'],\n additionalProperties: false,\n },\n annotations: { title: 'Pick from the mixing pad', ...SET },\n handler: ({ x, y, radius, setColor }) => ({ color: c.mixingPadPick(x, y, { radius, setColor }) }),\n },\n {\n name: 'clear_mixing_pad',\n title: 'Clear the mixing pad',\n description: 'Wipes the mixing pad clean.',\n inputSchema: EMPTY,\n annotations: { title: 'Clear the mixing pad', ...DESTRUCTIVE },\n handler: () => {\n c.clearMixingPad();\n return { cleared: true };\n },\n },\n {\n name: 'render_mixing_pad',\n title: 'Render the mixing pad',\n description: 'Renders the mixing pad as a PNG (360 × 220, over white). Changes nothing.',\n inputSchema: EMPTY,\n annotations: { title: 'Render the mixing pad', ...READ },\n handler: () => {\n const pad = c.mixingPad;\n return {\n content: [\n { type: 'image', data: bytesToBase64(encodePng(pad.width, pad.height, pad.pixels())), mimeType: 'image/png' },\n { type: 'text', text: `Mixing pad ${pad.width}×${pad.height}` },\n ],\n };\n },\n },\n ];\n}\n","/**\n * Agent tools for the paint editor (`createPaintEditorToolProvider`). Strict schemas, every\n * argument described, all four annotations. Each write is one undo step (or editor state, said so)\n * and returns what it changed; ids come from the read tools (`list_layers`, `list_brushes`,\n * `list_papers`, `list_strokes`).\n */\n\nimport type { AgentTool, AgentToolProvider } from '../tools/registry.js';\nimport { createPigmentTools } from '../paint/pigment-tools';\nimport { MIXING_MODELS, type MixerLoad } from '../paint/mixer';\nimport { BLEND_MODES, standardBlendMode, type BlendMode } from '../raster/blend';\nimport { bytesToBase64, encodePng } from '../raster/png';\nimport { BRUSH_ROTATIONS, MAX_BRUSH_SIZE, PAINT_BRUSH_CATEGORIES, PAINT_BRUSH_ENGINES, brushToJSON, type PaintBrush } from './brushes';\nimport { MAX_CANVAS_SIDE } from './document';\nimport type { PaintEditorController } from './controller';\nimport type { PenPoint } from './engine';\nimport { GRAIN_PATTERNS, PAPER_FAMILIES, PAPER_LIBRARY } from './paper';\nimport { MAX_ZOOM, MIN_ZOOM } from './view';\nimport { createPaintGuideTools } from './guide-tools';\nimport type { PaintAgentCommand, PaintDirector } from './presence';\nimport type { PresenceActorInfo } from '../animation/presence';\n\nconst READ = { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false } as const;\nconst WRITE = { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false } as const;\nconst SET = { readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: false } as const;\nconst DESTRUCTIVE = { readOnlyHint: false, destructiveHint: true, idempotentHint: false, openWorldHint: false } as const;\n\nconst EMPTY = { type: 'object', properties: {}, additionalProperties: false } as const;\nconst COLOR = { type: 'string', pattern: '^#[0-9a-fA-F]{6}$', description: 'Colour #rrggbb, e.g. \"#2a4b8d\".' } as const;\nconst LAYER_ID = { type: 'string', description: 'Layer id from list_layers (default the active layer).' } as const;\n\nexport interface PaintEditorToolProviderOptions {\n /** Provider id (unique per registry). Default `paint-editor`. */\n id?: string;\n /** Always prefix tool names with `<namespace>__`. */\n namespace?: string;\n /**\n * Acts out strokes, fills and replays with an agent cursor on the canvas (see `PaintDirector`):\n * strokes paint live along their points. Each call is still one undo step. Without it, they apply at once.\n */\n director?: PaintDirector;\n /** The agent's cursor (default `{ id: 'agent', name: 'Agent' }`). */\n actor?: PresenceActorInfo;\n}\n\nconst TIP = {\n type: 'object',\n description: 'The tip (the shared brush engine). Missing fields keep their current values.',\n properties: {\n size: { type: 'number', minimum: 1, maximum: MAX_BRUSH_SIZE, description: 'Diameter in document pixels.' },\n hardness: { type: 'number', minimum: 0, maximum: 1, description: 'Edge hardness, 0 (soft) .. 1 (hard).' },\n spacing: { type: 'number', minimum: 0.01, maximum: 10, description: 'Dab spacing as a fraction of the diameter (0.05 is smooth, 1 is dotted).' },\n angle: { type: 'number', minimum: -360, maximum: 360, description: 'Tip angle in degrees, counter-clockwise; with rotation stroke or barrel it is added to the stroke direction or pen rotation.' },\n roundness: { type: 'number', minimum: 0.01, maximum: 1, description: 'Tip roundness: 1 round, lower is a flat ellipse (a pastel or chisel tip).' },\n opacity: { type: 'number', minimum: 0, maximum: 1, description: 'Stroke opacity ceiling: overlapping dabs never exceed it.' },\n flow: { type: 'number', minimum: 0, maximum: 1, description: 'Build-up per dab towards the opacity (low flow builds up softly, like an airbrush).' },\n smoothing: { type: 'number', minimum: 0, maximum: 0.95, description: 'Position smoothing of the input, 0..0.95.' },\n pressureSize: { type: 'boolean', description: 'Pressure scales the size (down to dynamics.minSize).' },\n pressureOpacity: { type: 'boolean', description: 'Pressure scales the opacity.' },\n blend: {\n type: 'string',\n enum: BLEND_MODES.map((m) => m.id),\n description: 'How paint combines with the layer. pigment mixes it in like real paint (blue into yellow gives green); multiply darkens like marker ink; watercolor glazes like a transparent wash; tint, highlight and shadow recolour, light and shade (see list_blend_modes).',\n },\n },\n additionalProperties: false,\n} as const;\n\nconst DYNAMICS = {\n type: 'object',\n description: 'Pen dynamics and jitter. Missing fields keep their current values.',\n properties: {\n minSize: { type: 'number', minimum: 0, maximum: 1, description: 'Size at zero pressure as a fraction of the full size (when pressureSize).' },\n pressureFlow: { type: 'number', minimum: 0, maximum: 1, description: 'How much pressure scales flow.' },\n tiltSize: { type: 'number', minimum: 0, maximum: 1, description: 'Laying the pen down widens the tip (up to 2.5×).' },\n tiltRoundness: { type: 'number', minimum: 0, maximum: 1, description: 'Laying the pen down flattens the tip along the tilt (side-of-the-pencil shading).' },\n tiltOpacity: { type: 'number', minimum: 0, maximum: 1, description: 'Laying the pen down lightens the mark.' },\n velocitySize: { type: 'number', minimum: -1, maximum: 1, description: 'Positive grows the tip on fast strokes, negative thins it (needs point times t).' },\n velocityOpacity: { type: 'number', minimum: -1, maximum: 1, description: 'Positive darkens fast marks, negative lightens them (needs point times t).' },\n sizeJitter: { type: 'number', minimum: 0, maximum: 1, description: 'Random size change per dab.' },\n angleJitter: { type: 'number', minimum: 0, maximum: 1, description: 'Random angle per dab, as a fraction of ±180°.' },\n opacityJitter: { type: 'number', minimum: 0, maximum: 1, description: 'Random opacity drop per dab.' },\n scatter: { type: 'number', minimum: 0, maximum: 4, description: 'Random offset across the stroke, in diameters.' },\n },\n additionalProperties: false,\n} as const;\n\nconst MIXER = {\n type: 'object',\n description: 'Mixer engine settings (Mixer Brush, blender, smudge). Missing fields keep their current values.',\n properties: {\n wet: { type: 'number', minimum: 0, maximum: 1, description: 'How much canvas colour each dab picks up, 0 (dry) .. 1.' },\n load: { type: 'number', minimum: 0, maximum: 1, description: 'How much paint the reservoir holds; below 1 it drains per dab, so long strokes run dry.' },\n mix: { type: 'number', minimum: 0, maximum: 1, description: \"How far each dab's paint moves from the reservoir towards the picked-up colour.\" },\n loadEachStroke: { type: 'boolean', description: 'Refill the reservoir with the colour before each stroke.' },\n cleanEachStroke: { type: 'boolean', description: 'Empty the pickup well after each stroke.' },\n mixing: { type: 'string', enum: [...MIXING_MODELS], description: 'rgb: RGB averages. pigment: mixes like paint (Kubelka-Munk).' },\n },\n additionalProperties: false,\n} as const;\n\nconst BRUSH_FIELDS = {\n name: { type: 'string', minLength: 1, maxLength: 80, description: 'Display name.' },\n category: { type: 'string', enum: [...PAINT_BRUSH_CATEGORIES], description: 'Library category.' },\n engine: { type: 'string', enum: [...PAINT_BRUSH_ENGINES], description: 'dab: paints dabs; eraser: removes paint; mixer: picks up and moves paint (Mixer Brush, blender, smudge).' },\n tip: TIP,\n grain: { type: 'number', minimum: 0, maximum: 1, description: 'Paper grain response: 0 ignores the grain, 1 catches only its peaks at light pressure (pencil, pastel, charcoal). Multiplied by the paper depth.' },\n pressureSmoothing: { type: 'number', minimum: 0, maximum: 0.95, description: 'Pressure smoothing, separate from the tip position smoothing.' },\n rotation: { type: 'string', enum: [...BRUSH_ROTATIONS], description: 'What turns the tip: fixed (tip.angle), stroke (follows the direction of travel) or barrel (the pen barrel rotation, twist).' },\n dynamics: DYNAMICS,\n mixer: MIXER,\n loadsColor: { type: 'boolean', description: 'Mixer engine: load the colour each stroke (false for blender and smudge, which only move paint).' },\n} as const;\n\nconst POINTS = {\n type: 'array',\n minItems: 1,\n maxItems: 20000,\n description: 'The path in document pixels (raw samples; the brush smooths them). One point paints one dab.',\n items: {\n type: 'object',\n properties: {\n x: { type: 'number', description: 'Document x in pixels.' },\n y: { type: 'number', description: 'Document y in pixels.' },\n pressure: { type: 'number', minimum: 0, maximum: 1, description: 'Pen pressure 0..1 (default 1).' },\n t: { type: 'number', description: 'Time in milliseconds (optional; drives velocity dynamics, e.g. an ink pen thinning on fast strokes).' },\n tiltX: { type: 'number', minimum: -90, maximum: 90, description: 'Pen tilt in degrees towards +x (Pointer Events tiltX).' },\n tiltY: { type: 'number', minimum: -90, maximum: 90, description: 'Pen tilt in degrees towards +y (Pointer Events tiltY).' },\n altitude: { type: 'number', minimum: 0, maximum: 1.5708, description: 'Pen altitude in radians: 1.5708 upright, 0 lying flat (overrides tiltX / tiltY).' },\n azimuth: { type: 'number', minimum: 0, maximum: 6.2832, description: 'Where the pen leans, radians clockwise from +x (with altitude).' },\n twist: { type: 'number', minimum: 0, maximum: 359, description: 'Barrel rotation in degrees (brushes with rotation barrel).' },\n },\n required: ['x', 'y'],\n additionalProperties: false,\n },\n} as const;\n\nfunction loadResult(load: MixerLoad) {\n const hex = (c: readonly number[] | null) => (c ? '#' + c.map((v) => Math.round(Math.min(1, Math.max(0, v)) * 255).toString(16).padStart(2, '0')).join('') : null);\n return { reservoir: hex(load.reservoir), amount: Math.round(load.amount * 1000) / 1000, pickup: hex(load.pickup) };\n}\n\nfunction brushSummary(b: PaintBrush) {\n return { id: b.id, name: b.name, category: b.category, engine: b.engine, size: b.tip.size, grain: b.grain, rotation: b.rotation, builtin: Boolean(b.builtin) };\n}\n\n/** Agent tools for one paint editor. */\nexport function createPaintEditorToolProvider(controller: PaintEditorController, options: PaintEditorToolProviderOptions = {}): AgentToolProvider {\n const c = controller;\n const tools: AgentTool[] = [];\n const add = (t: AgentTool) => tools.push(t);\n /** Runs `command` through the director when there is one (its error becomes the tool error), else `direct`. */\n const act = async <T>(command: PaintAgentCommand, direct: () => T): Promise<T> => {\n if (!options.director) return direct();\n const [r] = await options.director.perform(options.actor ?? { id: 'agent', name: 'Agent' }, [command]);\n if (!r || !r.ok) throw new Error(r && !r.ok ? r.message : 'The director did not run the command.');\n return r.result as T;\n };\n\n // --- Canvas ------------------------------------------------------------------\n\n add({\n name: 'get_canvas_info',\n title: 'Get the canvas',\n description:\n 'Reads the canvas: size in pixels and dpi, the paper (preset, colour, grain depth), the active layer, the active brush id, the paint colour, the view (zoom, rotation, mirror), the hand, how many strokes are recorded, the undo / redo labels, and the blend modes. Call it first.',\n inputSchema: EMPTY,\n annotations: { title: 'Get the canvas', ...READ },\n handler: () => {\n const s = c.getState();\n const d = s.document;\n return {\n width: d.canvas.width,\n height: d.canvas.height,\n dpi: d.canvas.dpi,\n paper: { preset: d.paper.preset, name: d.paper.name, color: d.paper.color, depth: d.paper.depth },\n activeLayerId: d.activeLayerId,\n layerCount: c.listLayers().length,\n brushId: s.brush.id,\n color: s.color,\n secondaryColor: s.secondaryColor,\n view: { zoom: s.view.zoom, rotation: s.view.rotation, mirror: s.view.mirror },\n hand: s.hand,\n strokes: d.strokes.length,\n undo: s.undoLabel,\n redo: s.redoLabel,\n blendModes: BLEND_MODES.map((m) => m.id),\n };\n },\n });\n\n add({\n name: 'new_canvas',\n title: 'Start a new canvas',\n description:\n 'Replaces the document with a blank canvas: one empty layer over the paper. Size and dpi default to the current ones, the paper to the current paper (or a preset id from list_papers). One undo step (undo brings the old painting back). Returns the new size, paper and layer id.',\n inputSchema: {\n type: 'object',\n properties: {\n width: { type: 'integer', minimum: 1, maximum: MAX_CANVAS_SIDE, description: 'Width in pixels (default the current width).' },\n height: { type: 'integer', minimum: 1, maximum: MAX_CANVAS_SIDE, description: 'Height in pixels (default the current height).' },\n dpi: { type: 'number', minimum: 1, maximum: 10000, description: 'Pixels per inch for print sizes and PSD (default the current dpi).' },\n paper: { type: 'string', description: 'Paper preset id from list_papers (default the current paper).' },\n },\n additionalProperties: false,\n },\n annotations: { title: 'Start a new canvas', ...DESTRUCTIVE },\n handler: (a) => {\n const d = c.newCanvas({ width: a.width, height: a.height, dpi: a.dpi, paper: a.paper });\n return { width: d.canvas.width, height: d.canvas.height, dpi: d.canvas.dpi, paper: d.paper.preset, layerId: d.activeLayerId };\n },\n });\n\n add({\n name: 'set_canvas',\n title: 'Resize the canvas',\n description:\n 'Changes the canvas size (pixels stay where they are, anchored at the top-left; anything outside is kept on the layers but not shown) and / or its dpi. One undo step. Returns the canvas.',\n inputSchema: {\n type: 'object',\n properties: {\n width: { type: 'integer', minimum: 1, maximum: MAX_CANVAS_SIDE, description: 'Width in pixels (default unchanged).' },\n height: { type: 'integer', minimum: 1, maximum: MAX_CANVAS_SIDE, description: 'Height in pixels (default unchanged).' },\n dpi: { type: 'number', minimum: 1, maximum: 10000, description: 'Pixels per inch (default unchanged).' },\n },\n additionalProperties: false,\n },\n annotations: { title: 'Resize the canvas', ...SET },\n handler: (a) => c.setCanvas({ width: a.width, height: a.height, dpi: a.dpi }),\n });\n\n // --- Paper -------------------------------------------------------------------\n\n add({\n name: 'list_papers',\n title: 'List papers',\n description:\n 'Lists the built-in paper library (generated grain, no textures): id, name, family, grain pattern, colour, grain depth and the wet-media properties (absorption, permeability, roughness). Use an id with set_paper or new_canvas.',\n inputSchema: EMPTY,\n annotations: { title: 'List papers', ...READ },\n handler: () => ({\n papers: PAPER_LIBRARY.map((p) => ({ id: p.preset, name: p.name, family: p.family, pattern: p.pattern, color: p.color, depth: p.depth, absorption: p.absorption, permeability: p.permeability, roughness: p.roughness })),\n families: [...PAPER_FAMILIES],\n patterns: [...GRAIN_PATTERNS],\n }),\n });\n\n add({\n name: 'get_paper',\n title: 'Get the paper',\n description: 'Reads every setting of the current paper (preset, pattern, seed, colour, scale, tiling, depth, shading, dry and wet tuning, absorption, permeability, roughness).',\n inputSchema: EMPTY,\n annotations: { title: 'Get the paper', ...READ },\n handler: () => JSON.parse(JSON.stringify(c.document.paper)),\n });\n\n const tuning = {\n type: 'object',\n properties: {\n contrast: { type: 'number', minimum: 0, maximum: 3, description: 'Height contrast around the middle (default 1).' },\n invert: { type: 'boolean', description: 'Swap peaks and valleys.' },\n },\n additionalProperties: false,\n } as const;\n\n add({\n name: 'set_paper',\n title: 'Set the paper',\n description:\n 'Changes the paper under the whole painting: a preset from list_papers and / or its settings. Grain depth decides how much grain-responsive brushes (pencil, pastel, charcoal) skip the valleys; changing it re-renders the paper but not strokes already painted. One undo step. Returns the paper.',\n inputSchema: {\n type: 'object',\n properties: {\n preset: { type: 'string', description: 'Paper id from list_papers (its settings, then the other fields here on top).' },\n color: { ...COLOR, description: 'Paper colour #rrggbb.' },\n depth: { type: 'number', minimum: 0, maximum: 1, description: 'Grain depth 0..1 (0: brushes ignore the grain).' },\n scale: { type: 'number', minimum: 0.25, maximum: 8, description: 'Grain scale: 1 natural, 2 twice as coarse.' },\n seed: { type: 'integer', minimum: 0, description: 'Grain seed: another sheet of the same paper.' },\n pattern: { type: 'string', enum: [...GRAIN_PATTERNS], description: 'Grain pattern.' },\n tiling: { type: 'string', enum: ['repeat', 'mirror'], description: 'How the grain tile repeats (mirror hides seams).' },\n shading: { type: 'number', minimum: 0, maximum: 1, description: 'How much the grain shades the paper colour.' },\n dry: { ...tuning, description: 'Height map tuning for dry media.' },\n wet: { ...tuning, description: 'Height map tuning for wet media (stored for later).' },\n absorption: { type: 'number', minimum: 0, maximum: 1, description: 'Wet media: how fast the paper takes water (stored for later).' },\n permeability: { type: 'number', minimum: 0, maximum: 1, description: 'Wet media: how far water spreads in the paper (stored for later).' },\n roughness: { type: 'number', minimum: 0, maximum: 1, description: 'Wet media: how much the grain catches pigment (stored for later).' },\n name: { type: 'string', minLength: 1, description: 'Display name.' },\n },\n additionalProperties: false,\n },\n annotations: { title: 'Set the paper', ...SET },\n handler: (a) => c.setPaper(a),\n });\n\n // --- Layers ------------------------------------------------------------------\n\n add({\n name: 'list_layers',\n title: 'List layers',\n description:\n 'Lists the layers top first: id, name, type (pixel or group), visibility, opacity, blend, clipping, locks, whether it is active, the painted bounds in document pixels (null when empty), parent and depth.',\n inputSchema: EMPTY,\n annotations: { title: 'List layers', ...READ },\n handler: () => ({ layers: c.listLayers(), activeLayerId: c.document.activeLayerId }),\n });\n\n add({\n name: 'add_layer',\n title: 'Add a layer',\n description: 'Adds an empty pixel layer (or a group) above the active layer, or above aboveId, or at the top of parentId; it becomes the active layer. One undo step. Returns the layer.',\n inputSchema: {\n type: 'object',\n properties: {\n name: { type: 'string', minLength: 1, description: 'Layer name (default \"Layer n\").' },\n type: { type: 'string', enum: ['pixel', 'group'], description: 'pixel (default) or group.' },\n aboveId: { type: 'string', description: 'Put it directly above this layer (default the active layer).' },\n parentId: { type: 'string', description: 'Put it at the top of this group instead.' },\n },\n additionalProperties: false,\n },\n annotations: { title: 'Add a layer', ...WRITE },\n handler: (a) => c.addLayer({ name: a.name, type: a.type, aboveId: a.aboveId, parentId: a.parentId }),\n });\n\n add({\n name: 'update_layer',\n title: 'Change a layer',\n description: 'Changes a layer: name, visibility, opacity, blend mode, clipping to the layer below, locks. One undo step. Returns the layer.',\n inputSchema: {\n type: 'object',\n properties: {\n layerId: { type: 'string', description: 'Layer id from list_layers.' },\n name: { type: 'string', minLength: 1, description: 'New name.' },\n visible: { type: 'boolean', description: 'Show or hide.' },\n opacity: { type: 'number', minimum: 0, maximum: 1, description: 'Layer opacity 0..1.' },\n blend: {\n type: 'string',\n enum: [...BLEND_MODES.map((m) => m.id), 'pass-through'],\n description: 'Blend mode (pass-through for groups only). Painterly modes: watercolor (the layer glazes like a transparent wash), tint (recolours keeping lightness), highlight (adds soft coloured light), shadow (shades with ambient fill); see list_blend_modes.',\n },\n clipped: { type: 'boolean', description: 'Clip to the layer below (paint only shows where it has paint).' },\n locks: {\n type: 'object',\n description: 'Locks to change (others keep their values).',\n properties: {\n pixels: { type: 'boolean', description: 'Refuse painting.' },\n transparency: { type: 'boolean', description: 'Paint only where the layer already has paint.' },\n position: { type: 'boolean', description: 'Refuse moving.' },\n all: { type: 'boolean', description: 'All of the above, plus property changes and removal.' },\n },\n additionalProperties: false,\n },\n },\n required: ['layerId'],\n additionalProperties: false,\n },\n annotations: { title: 'Change a layer', ...SET },\n handler: ({ layerId, ...u }) => c.updateLayer(layerId, u as { blend?: BlendMode }),\n });\n\n add({\n name: 'list_blend_modes',\n title: 'List blend modes',\n description:\n 'Lists every layer and brush blend mode: id, label, group (standard Photoshop modes, pigment, or painterly), what the pigment and painterly modes do, and the standard mode PSD export writes in their place. Changes nothing. Read it before choosing a painterly mode for update_layer or a brush tip.',\n inputSchema: EMPTY,\n annotations: { title: 'List blend modes', ...READ },\n handler: () => ({\n modes: BLEND_MODES.map((m) => ({\n id: m.id,\n label: m.label,\n group: m.painterly ? 'painterly' : m.id === 'pigment' ? 'pigment' : 'standard',\n ...(m.description ? { description: m.description } : {}),\n psd: standardBlendMode(m.id),\n })),\n }),\n });\n\n add({\n name: 'set_active_layer',\n title: 'Choose the active layer',\n description: 'Makes a layer active: strokes, fills and clears without a layerId go to it. Editor state, not an undo step. Returns the layer.',\n inputSchema: { type: 'object', properties: { layerId: { type: 'string', description: 'Layer id from list_layers.' } }, required: ['layerId'], additionalProperties: false },\n annotations: { title: 'Choose the active layer', ...SET },\n handler: ({ layerId }) => {\n c.setActiveLayer(layerId);\n return c.describeLayer(c.getLayer(layerId)!);\n },\n });\n\n add({\n name: 'remove_layer',\n title: 'Remove a layer',\n description: 'Removes a layer (a group with its children). One undo step. Returns the removed id and the new active layer.',\n inputSchema: { type: 'object', properties: { layerId: { type: 'string', description: 'Layer id from list_layers.' } }, required: ['layerId'], additionalProperties: false },\n annotations: { title: 'Remove a layer', ...DESTRUCTIVE },\n handler: ({ layerId }) => c.removeLayer(layerId),\n });\n\n add({\n name: 'duplicate_layer',\n title: 'Duplicate a layer',\n description: 'Copies a layer (a group with its children) directly above it; the copy becomes active. One undo step. Returns the copy.',\n inputSchema: { type: 'object', properties: { layerId: { type: 'string', description: 'Layer id from list_layers.' } }, required: ['layerId'], additionalProperties: false },\n annotations: { title: 'Duplicate a layer', ...WRITE },\n handler: ({ layerId }) => c.duplicateLayer(layerId),\n });\n\n add({\n name: 'move_layer',\n title: 'Reorder a layer',\n description: 'Moves a layer to a position in its group or another (0 is the bottom). One undo step. Returns the layer with its new parent.',\n inputSchema: {\n type: 'object',\n properties: {\n layerId: { type: 'string', description: 'Layer id from list_layers.' },\n index: { type: 'integer', minimum: 0, description: 'New position among its siblings, 0 = bottom.' },\n parentId: { type: ['string', 'null'], description: 'Group id to move into, or null for the top level (default its current parent).' },\n },\n required: ['layerId', 'index'],\n additionalProperties: false,\n },\n annotations: { title: 'Reorder a layer', ...WRITE },\n handler: ({ layerId, index, parentId }) => c.moveLayer(layerId, index, parentId),\n });\n\n add({\n name: 'merge_layer_down',\n title: 'Merge a layer down',\n description: 'Merges a pixel layer into the pixel layer directly below it, which keeps its name, opacity and blend. One undo step. Returns the merged layer.',\n inputSchema: { type: 'object', properties: { layerId: { type: 'string', description: 'The upper layer, from list_layers.' } }, required: ['layerId'], additionalProperties: false },\n annotations: { title: 'Merge a layer down', ...DESTRUCTIVE },\n handler: ({ layerId }) => c.mergeDown(layerId),\n });\n\n add({\n name: 'fill_layer',\n title: 'Fill a layer',\n description:\n 'Fills a whole pixel layer with a colour: a flat block-in, or with grain above 0 a fill that follows the paper grain like pastel or charcoal rubbed across the sheet (pressure decides how far it reaches into the valleys). Good for a ground colour or a tonal layer to paint over. One undo step. Returns the layer id and the filled bounds.',\n inputSchema: {\n type: 'object',\n properties: {\n layerId: LAYER_ID,\n color: { ...COLOR, description: 'Fill colour #rrggbb (default the paint colour).' },\n opacity: { type: 'number', minimum: 0, maximum: 1, description: 'Opacity 0..1 (default 1).' },\n grain: { type: 'number', minimum: 0, maximum: 1, description: 'Paper grain response 0..1 (default 0: flat).' },\n pressure: { type: 'number', minimum: 0, maximum: 1, description: 'With grain: how far into the valleys, 0..1 (default 0.5).' },\n blend: { type: 'string', enum: BLEND_MODES.map((m) => m.id), description: 'Blend mode (default normal; pigment mixes like paint, watercolor glazes; see list_blend_modes).' },\n },\n additionalProperties: false,\n },\n annotations: { title: 'Fill a layer', ...WRITE },\n handler: (a) => act({ kind: 'fill', fill: a }, () => c.fillLayer(a)),\n });\n\n add({\n name: 'clear_layer',\n title: 'Clear a layer',\n description: 'Removes every pixel of a pixel layer. One undo step. Returns the layer id and the bounds that were cleared (null if it was empty).',\n inputSchema: { type: 'object', properties: { layerId: LAYER_ID }, additionalProperties: false },\n annotations: { title: 'Clear a layer', ...DESTRUCTIVE },\n handler: ({ layerId }) => c.clearLayer(layerId),\n });\n\n // --- Brushes -----------------------------------------------------------------\n\n add({\n name: 'list_brushes',\n title: 'List brushes',\n description:\n 'Lists the brush library: built-in dry media (pencils, pastels, charcoal, airbrush, marker, ink, erasers, blender, smudge, Mixer Brush) and saved user brushes, with id, name, category, engine, size, grain response and rotation mode, plus the active brush id.',\n inputSchema: EMPTY,\n annotations: { title: 'List brushes', ...READ },\n handler: () => {\n const s = c.getState();\n return { activeBrushId: s.brush.id, activeEdited: !s.brush.builtin && Boolean(c.getBrush(s.brush.id)?.builtin), brushes: s.brushes.map(brushSummary) };\n },\n });\n\n add({\n name: 'get_brush',\n title: 'Get a brush',\n description: 'Reads every setting of a brush (tip, grain, pressure smoothing, rotation, dynamics, mixer). Without id, the active brush as edited.',\n inputSchema: { type: 'object', properties: { id: { type: 'string', description: 'Brush id from list_brushes (default the active brush).' } }, additionalProperties: false },\n annotations: { title: 'Get a brush', ...READ },\n handler: ({ id }) => {\n if (id === undefined) return brushToJSON(c.getState().brush);\n const b = c.getBrush(id);\n if (!b) throw new Error(`Unknown brush \"${id}\". Call list_brushes for the ids.`);\n return { ...brushToJSON(b), builtin: Boolean(b.builtin) };\n },\n });\n\n add({\n name: 'set_brush',\n title: 'Set the brush',\n description:\n 'Chooses the active brush (id) and / or changes its settings; strokes without a brush use it. Editor state, not an undo step. Changes stay on the active brush until save_brush stores them. Returns the active brush.',\n inputSchema: { type: 'object', properties: { id: { type: 'string', description: 'Brush id from list_brushes to start from.' }, ...BRUSH_FIELDS }, additionalProperties: false },\n annotations: { title: 'Set the brush', ...SET },\n handler: (a) => brushToJSON(c.setBrush(a)),\n });\n\n add({\n name: 'save_brush',\n title: 'Save a brush',\n description: 'Saves the active brush (with its changes) into the user library under a new or existing user id. Built-in ids are refused. Library state, not an undo step. Returns the saved brush.',\n inputSchema: {\n type: 'object',\n properties: {\n id: { type: 'string', pattern: '^[a-z0-9][a-z0-9-]{0,63}$', description: 'Library id: lowercase letters, digits and dashes.' },\n name: { type: 'string', minLength: 1, maxLength: 80, description: 'Display name (default the brush name).' },\n },\n required: ['id'],\n additionalProperties: false,\n },\n annotations: { title: 'Save a brush', ...SET },\n handler: ({ id, name }) => brushToJSON(c.saveBrush({ id, name })),\n });\n\n add({\n name: 'remove_brush',\n title: 'Remove a saved brush',\n description: 'Removes a user brush from the library (built-in brushes cannot be removed). Library state, not an undo step. Returns the removed id.',\n inputSchema: { type: 'object', properties: { id: { type: 'string', description: 'User brush id from list_brushes.' } }, required: ['id'], additionalProperties: false },\n annotations: { title: 'Remove a saved brush', ...DESTRUCTIVE },\n handler: ({ id }) => {\n c.removeBrush(id);\n return { removed: id };\n },\n });\n\n add({\n name: 'export_brushes',\n title: 'Export brushes',\n description: 'Returns a brush library file (JSON: format pixerate-brushes, version 1, brushes) of the given brushes, or of every user brush. Changes nothing.',\n inputSchema: {\n type: 'object',\n properties: { ids: { type: 'array', items: { type: 'string', description: 'Brush id.' }, description: 'Brush ids from list_brushes (default every user brush).' } },\n additionalProperties: false,\n },\n annotations: { title: 'Export brushes', ...READ },\n handler: ({ ids }) => c.exportBrushes(ids),\n });\n\n add({\n name: 'import_brushes',\n title: 'Import brushes',\n description:\n 'Adds the brushes of a brush library file (as export_brushes returns) to the user library. Taken ids are skipped unless replace is true; built-in ids are always skipped. Library state, not an undo step. Returns the ids added and skipped and any problems.',\n inputSchema: {\n type: 'object',\n properties: {\n library: { type: 'object', description: 'The library file: {format: \"pixerate-brushes\", version: 1, brushes: [...]}.' },\n replace: { type: 'boolean', description: 'Replace user brushes with the same id (default false).' },\n },\n required: ['library'],\n additionalProperties: false,\n },\n annotations: { title: 'Import brushes', ...WRITE },\n handler: ({ library, replace }) => c.importBrushes(library, { replace }),\n });\n\n add({\n name: 'render_brush_thumbnail',\n title: 'Render a brush thumbnail',\n description: 'Renders a brush as a PNG: a test stroke (an S-curve swelling and fading in pressure) on the current paper, so you can see what it does before painting. Changes nothing.',\n inputSchema: {\n type: 'object',\n properties: {\n id: { type: 'string', description: 'Brush id from list_brushes (default the active brush).' },\n width: { type: 'integer', minimum: 16, maximum: 512, description: 'Width in pixels (default 160).' },\n height: { type: 'integer', minimum: 16, maximum: 512, description: 'Height in pixels (default 48).' },\n color: { ...COLOR, description: 'Stroke colour (default the paint colour).' },\n },\n additionalProperties: false,\n },\n annotations: { title: 'Render a brush thumbnail', ...READ },\n handler: ({ id, width, height, color }) => {\n const t = c.brushThumbnail(id ?? c.getState().brush.id, { width, height, color });\n return {\n content: [\n { type: 'image', data: bytesToBase64(encodePng(t.width, t.height, t.data)), mimeType: 'image/png' },\n { type: 'text', text: `Brush ${id ?? c.getState().brush.id} ${t.width}×${t.height}` },\n ],\n };\n },\n });\n\n // --- Colour and the Mixer Brush ----------------------------------------------\n\n add({\n name: 'set_color',\n title: 'Set the paint colour',\n description: 'Sets the paint colour (and optionally the second colour) that strokes and fills use by default. Editor state, not an undo step. Returns both colours.',\n inputSchema: {\n type: 'object',\n properties: { color: { ...COLOR, description: 'Paint colour #rrggbb.' }, secondaryColor: { ...COLOR, description: 'Second colour #rrggbb.' } },\n additionalProperties: false,\n },\n annotations: { title: 'Set the paint colour', ...SET },\n handler: ({ color, secondaryColor }) => {\n if (color !== undefined) c.setColor(color);\n if (secondaryColor !== undefined) c.setSecondaryColor(secondaryColor);\n const s = c.getState();\n return { color: s.color, secondaryColor: s.secondaryColor };\n },\n });\n\n add({\n name: 'pick_color',\n title: 'Pick a colour',\n description: 'Reads the colour at a document pixel: of the painting with its paper, or of one layer (with its alpha). Changes nothing. Returns #rrggbb and alpha 0..1.',\n inputSchema: {\n type: 'object',\n properties: {\n x: { type: 'number', description: 'Document x in pixels.' },\n y: { type: 'number', description: 'Document y in pixels.' },\n layerId: { type: 'string', description: 'Pick from this layer only (default the painting as shown).' },\n },\n required: ['x', 'y'],\n additionalProperties: false,\n },\n annotations: { title: 'Pick a colour', ...READ },\n handler: ({ x, y, layerId }) => c.pickColor(x, y, { layerId }),\n });\n\n add({\n name: 'get_mixer_brush',\n title: 'Get the Mixer Brush load',\n description: \"Reads what the Mixer Brush carries between strokes: reservoir #rrggbb or null, amount 0..1 left, pickup #rrggbb or null. Call before painting with mixer-brush when its loadEachStroke is false.\",\n inputSchema: EMPTY,\n annotations: { title: 'Get the Mixer Brush load', ...READ },\n handler: () => loadResult(c.getState().mixerLoad),\n });\n\n add({\n name: 'load_mixer_brush',\n title: 'Load the Mixer Brush',\n description: 'Fills the Mixer Brush reservoir with a colour (amount 1), keeping what it picked up. Editor state, not an undo step. Returns the load.',\n inputSchema: { type: 'object', properties: { color: { ...COLOR, description: 'Colour #rrggbb (default the paint colour).' } }, additionalProperties: false },\n annotations: { title: 'Load the Mixer Brush', ...SET },\n handler: ({ color }) => loadResult(c.loadMixerBrush(color)),\n });\n\n add({\n name: 'clean_mixer_brush',\n title: 'Clean the Mixer Brush',\n description: 'Empties the Mixer Brush pickup well (and with emptyReservoir its paint too). Editor state, not an undo step. Returns the load.',\n inputSchema: { type: 'object', properties: { emptyReservoir: { type: 'boolean', description: 'Also drop the loaded paint (default false).' } }, additionalProperties: false },\n annotations: { title: 'Clean the Mixer Brush', ...SET },\n handler: ({ emptyReservoir }) => loadResult(c.cleanMixerBrush(emptyReservoir === true)),\n });\n\n // --- Painting ----------------------------------------------------------------\n\n add({\n name: 'paint_stroke',\n title: 'Paint a brush stroke',\n description:\n 'Paints one stroke through points (document pixels, with optional pressure, time, tilt and barrel rotation) on a pixel layer with a library brush or the active one, optionally changed for this stroke. Grain-responsive brushes follow the paper; the mixer engine (mixer-brush, blender, smudge) picks up and moves paint already on the layer. The symmetry guide adds its mirror copies; with a tracing image that samples colours, a stroke without color takes the image colour at its first point. With an agent cursor (a director), the stroke is painted live along the points at the pace of their times. One undo step. Returns the layer id, changed bounds, dab count, the recorded strokeId (for replay_strokes) and, for the mixer, its load after the stroke.',\n inputSchema: {\n type: 'object',\n properties: {\n points: POINTS,\n layerId: LAYER_ID,\n brushId: { type: 'string', description: 'Brush id from list_brushes (default the active brush).' },\n brush: { type: 'object', description: 'Brush changes for this stroke only.', properties: BRUSH_FIELDS, additionalProperties: false },\n color: { ...COLOR, description: 'Paint colour #rrggbb (default the paint colour).' },\n seed: { type: 'integer', minimum: 0, description: 'Jitter seed (default a new one); the same seed and points give the same marks.' },\n snapToPerspective: { type: 'boolean', description: 'Snap the points to the perspective guide, as a pen stroke would (default false).' },\n },\n required: ['points'],\n additionalProperties: false,\n },\n annotations: { title: 'Paint a brush stroke', ...WRITE },\n handler: async (a) => {\n const stroke = { points: a.points as PenPoint[], layerId: a.layerId, brushId: a.brushId, brush: a.brush, color: a.color, seed: a.seed, snapToPerspective: a.snapToPerspective };\n const r = await act({ kind: 'stroke', stroke }, () => c.paintStroke(stroke));\n return r.mixerLoad ? { ...r, mixerLoad: loadResult(r.mixerLoad) } : r;\n },\n });\n\n add({\n name: 'list_strokes',\n title: 'List recorded strokes',\n description:\n 'Lists the recorded strokes, oldest first (every stroke is kept as data): id, layer, brush id and name, colour, point count, bounds and seed. With ids, also the points. Use the ids with replay_strokes.',\n inputSchema: {\n type: 'object',\n properties: {\n ids: { type: 'array', items: { type: 'string', description: 'Stroke id.' }, description: 'Only these strokes, with their points.' },\n last: { type: 'integer', minimum: 1, maximum: 1000, description: 'Only the most recent n strokes (default 100).' },\n },\n additionalProperties: false,\n },\n annotations: { title: 'List recorded strokes', ...READ },\n handler: ({ ids, last }) => {\n const all = c.getStrokes();\n const picked = ids ? all.filter((s) => ids.includes(s.id)) : all.slice(-(last ?? 100));\n if (ids) for (const id of ids) if (!all.some((s) => s.id === id)) throw new Error(`Unknown stroke \"${id}\". Call list_strokes without ids for the ids.`);\n return {\n total: all.length,\n strokes: picked.map((s) => {\n const xs = s.points.map((p) => p.x);\n const ys = s.points.map((p) => p.y);\n const pad = s.brush.tip.size / 2;\n return {\n id: s.id,\n layerId: s.layerId,\n brushId: s.brush.id,\n brushName: s.brush.name,\n color: s.color,\n points: ids ? s.points : s.points.length,\n seed: s.seed,\n copies: s.copies?.length ?? 0,\n bounds: { x: Math.floor(Math.min(...xs) - pad), y: Math.floor(Math.min(...ys) - pad), width: Math.ceil(Math.max(...xs) - Math.min(...xs) + 2 * pad), height: Math.ceil(Math.max(...ys) - Math.min(...ys) + 2 * pad) },\n };\n }),\n };\n },\n });\n\n add({\n name: 'replay_strokes',\n title: 'Replay strokes, varied',\n description:\n 'Paints recorded strokes again, moved, scaled, rotated, flipped, recoloured, with another brush or on another layer, repeat times (each repeat applies the variation again: a row, a fan, a spiral). Strokes replay exactly (same seed). All of it is one undo step. Returns the new stroke ids, the changed bounds and layer ids.',\n inputSchema: {\n type: 'object',\n properties: {\n strokeIds: { type: 'array', minItems: 1, maxItems: 500, items: { type: 'string', description: 'Stroke id.' }, description: 'Stroke ids from list_strokes.' },\n dx: { type: 'number', description: 'Move right by this many pixels per repeat (default 0).' },\n dy: { type: 'number', description: 'Move down by this many pixels per repeat (default 0).' },\n scale: { type: 'number', exclusiveMinimum: 0, maximum: 20, description: 'Scale per repeat about the origin; brush size scales too (default 1).' },\n rotate: { type: 'number', minimum: -360, maximum: 360, description: 'Rotate per repeat about the origin, degrees clockwise (default 0).' },\n flipX: { type: 'boolean', description: 'Mirror left to right about the origin (default false).' },\n origin: {\n type: 'object',\n description: 'Centre for scale, rotate and flip (default the centre of the strokes).',\n properties: { x: { type: 'number', description: 'Document x.' }, y: { type: 'number', description: 'Document y.' } },\n required: ['x', 'y'],\n additionalProperties: false,\n },\n pressureScale: { type: 'number', minimum: 0, maximum: 4, description: 'Multiply every pressure (default 1).' },\n color: { ...COLOR, description: 'Recolour (default each stroke’s colour).' },\n brushId: { type: 'string', description: 'Replay with this brush from list_brushes (default each stroke’s brush).' },\n layerId: { type: 'string', description: 'Paint on this layer (default each stroke’s layer).' },\n repeat: { type: 'integer', minimum: 1, maximum: 100, description: 'How many copies (default 1).' },\n },\n required: ['strokeIds'],\n additionalProperties: false,\n },\n annotations: { title: 'Replay strokes, varied', ...WRITE },\n handler: (a) => {\n const replay = a as Parameters<PaintEditorController['replayStrokes']>[0];\n return act({ kind: 'replay', replay }, () => c.replayStrokes(replay));\n },\n });\n\n // --- View, hand, history -------------------------------------------------------\n\n add({\n name: 'set_view',\n title: 'Rotate, mirror or zoom the view',\n description: 'Changes the view only (the pixels never resample): zoom, rotation and mirroring, as an artist turns the paper or checks the drawing in a mirror. Editor state, not an undo step. Returns the view.',\n inputSchema: {\n type: 'object',\n properties: {\n zoom: { type: 'number', minimum: MIN_ZOOM, maximum: MAX_ZOOM, description: 'Screen pixels per document pixel.' },\n rotation: { type: 'number', minimum: -360, maximum: 360, description: 'Rotation in degrees clockwise.' },\n mirror: { type: 'boolean', description: 'Mirror left to right.' },\n reset: { type: 'boolean', description: 'Back to 100 %, no rotation, no mirror, centred (applied first).' },\n },\n additionalProperties: false,\n },\n annotations: { title: 'Rotate, mirror or zoom the view', ...SET },\n handler: ({ reset, ...v }) => {\n if (reset) c.resetView();\n return c.setView(v);\n },\n });\n\n add({\n name: 'set_hand',\n title: 'Set the drawing hand',\n description: 'Says which hand holds the pen; palm rejection ignores touches on that side of the pen. Editor state, not an undo step. Returns the hand.',\n inputSchema: { type: 'object', properties: { hand: { type: 'string', enum: ['right', 'left'], description: 'right or left.' } }, required: ['hand'], additionalProperties: false },\n annotations: { title: 'Set the drawing hand', ...SET },\n handler: ({ hand }) => ({ hand: c.setHand(hand) }),\n });\n\n add({\n name: 'undo_paint',\n title: 'Undo',\n description: 'Undoes the last step (a stroke, a fill, a layer or paper change). Returns the label undone (null when there was nothing) and what can be undone and redone next.',\n inputSchema: EMPTY,\n annotations: { title: 'Undo', ...WRITE },\n handler: () => {\n const undone = c.undo();\n const s = c.getState();\n return { undone, nextUndo: s.undoLabel, nextRedo: s.redoLabel };\n },\n });\n\n add({\n name: 'redo_paint',\n title: 'Redo',\n description: 'Redoes the last undone step. Returns the label redone (null when there was nothing) and what can be undone and redone next.',\n inputSchema: EMPTY,\n annotations: { title: 'Redo', ...WRITE },\n handler: () => {\n const redone = c.redo();\n const s = c.getState();\n return { redone, nextUndo: s.undoLabel, nextRedo: s.redoLabel };\n },\n });\n\n // --- Output ------------------------------------------------------------------\n\n add({\n name: 'render_preview',\n title: 'Render a preview',\n description: 'Renders the painting (with its paper unless paper is false) or some layers as a PNG whose longest side is at most maxSide. Changes nothing. Look at it after each block of work.',\n inputSchema: {\n type: 'object',\n properties: {\n maxSide: { type: 'integer', minimum: 16, maximum: 2048, description: 'Longest side in pixels (default 512).' },\n layerIds: { type: 'array', items: { type: 'string', description: 'Layer id.' }, description: 'Only these layers (default all).' },\n paper: { type: 'boolean', description: 'Include the paper (default true).' },\n },\n additionalProperties: false,\n },\n annotations: { title: 'Render a preview', ...READ },\n handler: ({ maxSide, layerIds, paper }) => {\n if (layerIds) for (const id of layerIds) if (!c.getLayer(id)) throw new Error(`Unknown layer \"${id}\". Call list_layers for the ids.`);\n const p = c.previewPngBase64({ maxSide: maxSide ?? 512, layerIds, paper });\n return { content: [{ type: 'image', data: p.data, mimeType: 'image/png' }, { type: 'text', text: `Preview ${p.width}×${p.height}` }] };\n },\n });\n\n add({\n name: 'export_image',\n title: 'Export the painting',\n description: 'Exports the painting as PNG, JPEG or WebP (base64). JPEG always includes the paper; JPEG and WebP need a browser canvas. Changes nothing. Returns the data, its MIME type and size.',\n inputSchema: {\n type: 'object',\n properties: {\n format: { type: 'string', enum: ['image/png', 'image/jpeg', 'image/webp'], description: 'File type (default image/png).' },\n quality: { type: 'number', minimum: 0, maximum: 1, description: 'JPEG / WebP quality 0..1 (default 0.92).' },\n scale: { type: 'number', exclusiveMinimum: 0, maximum: 1, description: 'Shrink by this factor (default 1).' },\n paper: { type: 'boolean', description: 'Include the paper (default true).' },\n },\n additionalProperties: false,\n },\n annotations: { title: 'Export the painting', ...READ },\n handler: async ({ format, quality, scale, paper }) => {\n const bytes = await c.exportImage({ format, quality, scale, paper });\n return { mimeType: format ?? 'image/png', bytes: bytes.length, data: bytesToBase64(bytes) };\n },\n });\n\n add({\n name: 'export_psd',\n title: 'Export as PSD',\n description:\n 'Writes the painting as an 8-bit RGB PSD (PSB above 30000 px) through the shared PSD writer: every layer and group with its opacity, blend, mask and locks, the paper as a locked \"Paper\" pixel layer at the bottom, and the composite as the merged image. Changes nothing. Returns the file as base64, its size, whether it is a PSB, and warnings (pigment and painterly blend modes have no PSD equivalent: they are written as the nearest standard mode, see list_blend_modes).',\n inputSchema: EMPTY,\n annotations: { title: 'Export as PSD', ...READ },\n handler: () => {\n const r = c.exportPsd();\n return { data: bytesToBase64(r.bytes), bytes: r.bytes.length, psb: r.psb, warnings: r.warnings };\n },\n });\n\n add({\n name: 'save_document',\n title: 'Save the document',\n description: 'Returns the document as JSON (format pixerate-paint, version 1): canvas, paper, layers with PNG data URLs, and the recorded strokes unless strokes is false. Changes nothing.',\n inputSchema: { type: 'object', properties: { strokes: { type: 'boolean', description: 'Include the recorded strokes (default true).' } }, additionalProperties: false },\n annotations: { title: 'Save the document', ...READ },\n handler: ({ strokes }) => c.toJSON({ strokes }),\n });\n\n add({\n name: 'open_document',\n title: 'Open a document',\n description: 'Opens a saved paint document (as save_document returns), replacing the painting and clearing the undo history. Returns the canvas, the layers and anything that could not be read.',\n inputSchema: { type: 'object', properties: { document: { type: 'object', description: 'The saved document JSON.' } }, required: ['document'], additionalProperties: false },\n annotations: { title: 'Open a document', ...DESTRUCTIVE },\n handler: ({ document }) => {\n const problems = c.loadJSON(document);\n const d = c.document;\n return { width: d.canvas.width, height: d.canvas.height, layers: c.listLayers(), strokes: d.strokes.length, problems };\n },\n });\n\n tools.push(...createPaintGuideTools(c));\n tools.push(...createPigmentTools());\n\n return { id: options.id ?? 'paint-editor', namespace: options.namespace, tools };\n}\n","/**\n * Framework-free UI logic shared by the React and Svelte paint editors, so both behave the same:\n *\n * - `PaintGesture` turns pointer events (structurally typed, no DOM import) into strokes (with\n * coalesced samples and a predicted tail), colour picks, pans, view rotation and zoom, with palm\n * rejection while a pen is down.\n * - `PaintCanvasPresenter` keeps a document-sized 2D canvas up to date from the compositor,\n * uploading only the tiles that changed.\n * - Guide overlays as line segments, and the slider tables of the brush and paper panels.\n */\n\nimport { BLEND_MODES, type BlendModeInfo } from '../raster/blend';\nimport { TILE, type RasterRect } from '../raster/surface';\nimport type { PaintEditorController } from './controller';\nimport type { PenPoint } from './engine';\nimport { perspectiveGuideLines, symmetryAxisSegments, type Point2 } from './guides';\nimport { isPalmTouch, pointerToPenPoint, type PointerSample } from './input';\nimport { MAX_ZOOM, MIN_ZOOM, screenToDocument } from './view';\nimport { hsvToRgb, parseHexColor, rgbToHexColor, rgbToHsv, wheelToHue, type ColorWheel } from './color';\n\n/** The Pointer Event fields the gesture reads. */\nexport interface PaintPointerEvent extends PointerSample {\n pointerId: number;\n clientX: number;\n clientY: number;\n button?: number;\n buttons?: number;\n shiftKey?: boolean;\n altKey?: boolean;\n ctrlKey?: boolean;\n metaKey?: boolean;\n getCoalescedEvents?(): PaintPointerEvent[];\n getPredictedEvents?(): PaintPointerEvent[];\n}\n\nexport type PaintTool = 'brush' | 'eyedropper' | 'pan' | 'rotate';\n\nexport const PAINT_TOOLS: ReadonlyArray<{ id: PaintTool; label: string; key: string }> = [\n { id: 'brush', label: 'Brush', key: 'b' },\n { id: 'eyedropper', label: 'Eyedropper', key: 'i' },\n { id: 'pan', label: 'Pan', key: 'h' },\n { id: 'rotate', label: 'Rotate view', key: 'r' },\n];\n\n/** Where the viewport element is on screen and how big it is (CSS pixels). */\nexport interface ViewportBox {\n left: number;\n top: number;\n width: number;\n height: number;\n}\n\ntype Mode = { kind: 'stroke'; pointerId: number } | { kind: 'pan'; pointerId: number; x: number; y: number; pan: Point2 } | { kind: 'rotate'; pointerId: number; angle: number; rotation: number } | null;\n\nexport class PaintGesture {\n tool: PaintTool = 'brush';\n /** The last refusal (a hidden or locked layer), for the editor to show. */\n error: string | null = null;\n /** The predicted tail of the current stroke in document pixels (draw it as a thin preview). */\n predicted: PenPoint[] = [];\n private mode: Mode = null;\n private penAt: Point2 | null = null;\n private penDown = false;\n\n constructor(\n private readonly controller: PaintEditorController,\n private readonly box: () => ViewportBox\n ) {}\n\n private doc(e: { clientX: number; clientY: number }): Point2 {\n const b = this.box();\n const s = this.controller.getState();\n return screenToDocument(s.view, s.document.canvas, b, e.clientX - b.left, e.clientY - b.top);\n }\n\n private pen(e: PaintPointerEvent): PenPoint {\n const p = this.doc(e);\n return pointerToPenPoint(e, p.x, p.y, this.controller.getState().view);\n }\n\n /** Pointer down; returns true when the gesture took the pointer (capture it). */\n down(e: PaintPointerEvent): boolean {\n this.error = null;\n if (this.mode) return false;\n if (e.pointerType === 'pen') {\n this.penDown = true;\n this.penAt = { x: e.clientX, y: e.clientY };\n } else if (e.pointerType === 'touch' && (this.penDown || isPalmTouch({ x: e.clientX, y: e.clientY }, this.penAt, this.controller.getState().hand))) {\n return false;\n }\n const middle = e.button === 1;\n const tool = middle ? 'pan' : this.tool;\n if (tool === 'pan') {\n this.mode = { kind: 'pan', pointerId: e.pointerId, x: e.clientX, y: e.clientY, pan: { ...this.controller.getState().view.pan } };\n return true;\n }\n if (tool === 'rotate') {\n const b = this.box();\n this.mode = { kind: 'rotate', pointerId: e.pointerId, angle: Math.atan2(e.clientY - b.top - b.height / 2, e.clientX - b.left - b.width / 2), rotation: this.controller.getState().view.rotation };\n return true;\n }\n if (tool === 'eyedropper' || e.altKey) {\n this.pick(e);\n return false;\n }\n try {\n const p = this.pen(e);\n const session = this.controller.beginStroke({ start: p });\n session.push([p]);\n this.mode = { kind: 'stroke', pointerId: e.pointerId };\n return true;\n } catch (err) {\n this.error = err instanceof Error ? err.message : String(err);\n return false;\n }\n }\n\n private pick(e: PaintPointerEvent): void {\n const p = this.doc(e);\n const { width, height } = this.controller.document.canvas;\n if (p.x < 0 || p.y < 0 || p.x >= width || p.y >= height) return;\n this.controller.setColor(this.controller.pickColor(p.x, p.y).color);\n }\n\n move(e: PaintPointerEvent): void {\n if (e.pointerType === 'pen') this.penAt = { x: e.clientX, y: e.clientY };\n const m = this.mode;\n if (!m || m.pointerId !== e.pointerId) return;\n if (m.kind === 'pan') {\n this.controller.setView({ pan: { x: m.pan.x + e.clientX - m.x, y: m.pan.y + e.clientY - m.y } });\n return;\n }\n if (m.kind === 'rotate') {\n const b = this.box();\n const a = Math.atan2(e.clientY - b.top - b.height / 2, e.clientX - b.left - b.width / 2);\n let r = m.rotation + ((a - m.angle) * 180) / Math.PI;\n if (e.shiftKey) r = Math.round(r / 15) * 15;\n this.controller.setView({ rotation: r });\n return;\n }\n const session = this.controller.activeStroke;\n if (!session) return;\n const events = typeof e.getCoalescedEvents === 'function' ? e.getCoalescedEvents() : [];\n session.push((events.length ? events : [e]).map((ev) => this.pen(ev)));\n const predicted = typeof e.getPredictedEvents === 'function' ? e.getPredictedEvents() : [];\n this.predicted = predicted.map((ev) => this.pen(ev));\n }\n\n up(e: PaintPointerEvent): void {\n if (e.pointerType === 'pen') this.penDown = false;\n const m = this.mode;\n if (!m || m.pointerId !== e.pointerId) return;\n this.mode = null;\n this.predicted = [];\n if (m.kind === 'stroke') this.controller.activeStroke?.end();\n }\n\n cancel(): void {\n this.penDown = false;\n this.predicted = [];\n if (this.mode?.kind === 'stroke') this.controller.activeStroke?.cancel();\n this.mode = null;\n }\n\n get active(): boolean {\n return this.mode !== null;\n }\n\n /** Wheel: zoom about the pointer (Ctrl / pinch or plain wheel), Shift+wheel rotates the view. */\n wheel(e: { clientX: number; clientY: number; deltaY: number; shiftKey?: boolean }): void {\n const s = this.controller.getState();\n if (e.shiftKey) {\n this.controller.setView({ rotation: s.view.rotation + (e.deltaY > 0 ? 5 : -5) });\n return;\n }\n const b = this.box();\n const zoom = Math.min(MAX_ZOOM, Math.max(MIN_ZOOM, s.view.zoom * Math.exp(-e.deltaY * 0.0015)));\n const k = zoom / s.view.zoom;\n // Keep the point under the pointer still: the pan scales about it.\n const px = e.clientX - b.left - b.width / 2;\n const py = e.clientY - b.top - b.height / 2;\n this.controller.setView({ zoom, pan: { x: px - (px - s.view.pan.x) * k, y: py - (py - s.view.pan.y) * k } });\n }\n}\n\n/** Keyboard shortcuts shared by both editors; returns true when it handled the key. */\nexport function handlePaintShortcut(\n controller: PaintEditorController,\n gesture: PaintGesture,\n e: { key: string; ctrlKey?: boolean; metaKey?: boolean; shiftKey?: boolean; target?: unknown }\n): boolean {\n const mod = e.ctrlKey || e.metaKey;\n const key = e.key.toLowerCase();\n if (mod && key === 'z') {\n if (controller.getState().stroking) return true;\n if (e.shiftKey) controller.redo();\n else controller.undo();\n return true;\n }\n if (mod && key === 'y') {\n controller.redo();\n return true;\n }\n if (mod) return false;\n const tool = PAINT_TOOLS.find((t) => t.key === key);\n if (tool) {\n gesture.tool = tool.id;\n return true;\n }\n const brush = controller.getState().brush;\n if (key === '[' || key === ']') {\n const step = Math.max(1, Math.round(brush.tip.size * 0.15));\n controller.setBrush({ tip: { size: Math.max(1, brush.tip.size + (key === ']' ? step : -step)) } });\n return true;\n }\n if (key === 'x') {\n controller.swapColors();\n return true;\n }\n if (key === 'm') {\n controller.setView({ mirror: !controller.getState().view.mirror });\n return true;\n }\n if (key === 'escape') {\n controller.resetView();\n return true;\n }\n return false;\n}\n\n/** The 2D context methods the presenter uses (a `CanvasRenderingContext2D`). */\nexport interface Paint2DContext {\n createImageData(width: number, height: number): { data: Uint8ClampedArray };\n putImageData(image: never, dx: number, dy: number, sx?: number, sy?: number, sw?: number, sh?: number): void;\n}\n\n/** Keeps a document-sized canvas in step with the controller, tile by tile. */\nexport class PaintCanvasPresenter {\n private readonly uploaded = new Map<string, Uint8ClampedArray>();\n private scratch: { data: Uint8ClampedArray } | null = null;\n private size = '';\n\n constructor(private readonly controller: PaintEditorController) {}\n\n /** Draws what changed into `ctx` (a canvas the size of the document); returns the tiles drawn. */\n render(ctx: Paint2DContext): number {\n const { width, height } = this.controller.document.canvas;\n const size = `${width}x${height}`;\n let dirty = this.controller.takeDirty();\n if (size !== this.size) {\n this.size = size;\n this.uploaded.clear();\n dirty = 'all';\n }\n let drawn = 0;\n const rect: RasterRect = { x: 0, y: 0, width, height };\n this.controller.compositeTiles(rect, (tx, ty, data) => {\n const key = `${tx},${ty}`;\n if (this.uploaded.get(key) === data) return;\n this.uploaded.set(key, data);\n if (!this.scratch) this.scratch = ctx.createImageData(TILE, TILE);\n this.scratch.data.set(data);\n const ox = tx * TILE;\n const oy = ty * TILE;\n ctx.putImageData(this.scratch as never, ox, oy, 0, 0, Math.min(TILE, width - ox), Math.min(TILE, height - oy));\n drawn++;\n }, { dirty });\n return drawn;\n }\n}\n\n/** Lines to draw over the canvas for the guides, in document pixels, with a style key. */\nexport function guideOverlay(controller: PaintEditorController): Array<{ from: Point2; to: Point2; kind: 'symmetry' | 'perspective' | 'snap' }> {\n const s = controller.getState();\n const size = s.document.canvas;\n const out: Array<{ from: Point2; to: Point2; kind: 'symmetry' | 'perspective' | 'snap' }> = [];\n for (const [from, to] of symmetryAxisSegments(s.guides.symmetry, size)) out.push({ from, to, kind: 'symmetry' });\n if (s.guides.perspective.enabled) for (const [from, to] of perspectiveGuideLines(s.guides.perspective, size, 16)) out.push({ from, to, kind: 'perspective' });\n return out;\n}\n\n/** One slider of a panel: a path into the brush (or paper) settings. */\nexport interface SliderControl {\n path: string;\n label: string;\n min: number;\n max: number;\n step: number;\n}\n\nexport const BRUSH_SLIDERS: readonly SliderControl[] = [\n { path: 'tip.size', label: 'Size', min: 1, max: 400, step: 1 },\n { path: 'tip.opacity', label: 'Opacity', min: 0, max: 1, step: 0.01 },\n { path: 'tip.flow', label: 'Flow', min: 0, max: 1, step: 0.01 },\n { path: 'tip.hardness', label: 'Hardness', min: 0, max: 1, step: 0.01 },\n { path: 'tip.spacing', label: 'Spacing', min: 0.01, max: 1, step: 0.01 },\n { path: 'tip.roundness', label: 'Roundness', min: 0.05, max: 1, step: 0.01 },\n { path: 'tip.angle', label: 'Angle', min: -180, max: 180, step: 1 },\n { path: 'grain', label: 'Grain', min: 0, max: 1, step: 0.01 },\n { path: 'tip.smoothing', label: 'Smoothing', min: 0, max: 0.95, step: 0.01 },\n { path: 'pressureSmoothing', label: 'Pressure smoothing', min: 0, max: 0.95, step: 0.01 },\n { path: 'dynamics.minSize', label: 'Min size', min: 0, max: 1, step: 0.01 },\n { path: 'dynamics.tiltSize', label: 'Tilt size', min: 0, max: 1, step: 0.01 },\n { path: 'dynamics.velocitySize', label: 'Speed size', min: -1, max: 1, step: 0.01 },\n];\n\nexport const PAPER_SLIDERS: readonly SliderControl[] = [\n { path: 'depth', label: 'Grain depth', min: 0, max: 1, step: 0.01 },\n { path: 'scale', label: 'Grain scale', min: 0.25, max: 8, step: 0.05 },\n { path: 'shading', label: 'Shading', min: 0, max: 1, step: 0.01 },\n { path: 'dry.contrast', label: 'Contrast', min: 0, max: 3, step: 0.05 },\n { path: 'absorption', label: 'Absorption', min: 0, max: 1, step: 0.01 },\n { path: 'permeability', label: 'Permeability', min: 0, max: 1, step: 0.01 },\n { path: 'roughness', label: 'Roughness', min: 0, max: 1, step: 0.01 },\n];\n\n/** Reads `a.b` from an object. */\nexport function readPath(obj: unknown, path: string): number {\n let v: unknown = obj;\n for (const k of path.split('.')) v = (v as Record<string, unknown>)?.[k];\n return typeof v === 'number' ? v : 0;\n}\n\n/** `{a: {b: value}}` for `a.b`, keeping the rest of `obj`'s `a`. */\nexport function patchPath(obj: Record<string, unknown>, path: string, value: number): Record<string, unknown> {\n const [head, ...rest] = path.split('.');\n if (!rest.length) return { [head]: value };\n return { [head]: { ...(obj[head] as Record<string, unknown>), ...patchPath((obj[head] as Record<string, unknown>) ?? {}, rest.join('.'), value) } };\n}\n\n/** The point on a colour wheel of `radius` (centre 0, 0) for a wheel angle in degrees, red at the top. */\nexport function wheelPoint(angle: number, radius: number): Point2 {\n const a = ((angle - 90) * Math.PI) / 180;\n return { x: Math.cos(a) * radius, y: Math.sin(a) * radius };\n}\n\n/** The wheel angle (degrees, red at the top, clockwise) of a point relative to the wheel centre. */\nexport function wheelAngle(x: number, y: number): number {\n return ((Math.atan2(y, x) * 180) / Math.PI + 90 + 360) % 360;\n}\n\n/**\n * A hue ring for a colour wheel, `size × size` RGBA: hues at full saturation and value between\n * `inner` and 1 of the radius, red at the top, laid out on the RYB or RGB wheel.\n */\nexport function renderColorWheel(size: number, wheel: ColorWheel, inner = 0.64): { width: number; height: number; data: Uint8ClampedArray } {\n const data = new Uint8ClampedArray(size * size * 4);\n const r = size / 2;\n for (let y = 0; y < size; y++) {\n for (let x = 0; x < size; x++) {\n const dx = x + 0.5 - r;\n const dy = y + 0.5 - r;\n const d = Math.hypot(dx, dy) / r;\n if (d > 1 || d < inner) continue;\n const [cr, cg, cb] = hsvToRgb(wheelToHue(wheelAngle(dx, dy), wheel), 1, 1);\n const i = (y * size + x) * 4;\n // Anti-aliased edges.\n const edge = Math.min(1, (1 - d) * r, (d - inner) * r);\n data[i] = cr;\n data[i + 1] = cg;\n data[i + 2] = cb;\n data[i + 3] = Math.round(255 * Math.max(0, edge));\n }\n }\n return { width: size, height: size, data };\n}\n\n/** The colour for a click on the wheel ring at (dx, dy) from its centre, keeping `color`'s saturation and value. */\nexport function wheelPick(dx: number, dy: number, wheel: ColorWheel, color: string): string {\n const [r, g, b] = parseHexColor(color);\n const { s, v } = rgbToHsv(r, g, b);\n const [nr, ng, nb] = hsvToRgb(wheelToHue(wheelAngle(dx, dy), wheel), s || 1, v || 1);\n return rgbToHexColor(nr, ng, nb);\n}\n\n/** A group of the blend menu: the Photoshop modes, then pigment and the painterly modes. */\nexport interface BlendMenuGroup {\n label: string;\n modes: readonly BlendModeInfo[];\n}\n\n/**\n * The layer and brush blend menus as groups: the 26 standard modes, then the paint modes\n * (`pigment` and the painterly `watercolor`, `tint`, `highlight`, `shadow`), each with its\n * description as a tooltip. Both bindings render this as `<optgroup>`s.\n */\nexport const BLEND_MENU_GROUPS: readonly BlendMenuGroup[] = [\n { label: 'Standard', modes: BLEND_MODES.filter((m) => !m.painterly && m.id !== 'pigment') },\n { label: 'Paint', modes: BLEND_MODES.filter((m) => m.painterly || m.id === 'pigment') },\n];\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAUO,SAAS,MAAM,GAAmB;AACvC,OAAK,MAAM;AACX,MAAI,KAAK,KAAK,GAAG,UAAU;AAC3B,OAAK,MAAM;AACX,MAAI,KAAK,KAAK,GAAG,UAAU;AAC3B,OAAK,MAAM;AACX,SAAO,MAAM;AACf;AAGO,SAAS,MAAM,GAAW,GAAW,MAAsB;AAChE,QAAM,IAAI,OAAO,KAAK,KAAK,IAAI,GAAG,SAAU,IAAI,OAAO,IAAI,KAAK,KAAK,KAAK,OAAO,GAAG,SAAU,CAAC,OAAO,CAAC;AACvG,SAAO,IAAI;AACb;AAGO,SAAS,OAAO,MAAc,OAAe,QAAwB;AAC1E,SAAO,MAAM,OAAO,QAAQ,IAAI;AAClC;AAGO,SAAS,WAAW,MAAc,OAAe,QAAwB;AAC9E,SAAO,OAAO,MAAM,OAAO,MAAM,IAAI,IAAI;AAC3C;AAGO,SAAS,eAAe,MAAsB;AACnD,MAAI,IAAI;AACR,WAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,SAAK,KAAK,WAAW,CAAC;AACtB,QAAI,KAAK,KAAK,GAAG,QAAU;AAAA,EAC7B;AACA,SAAO,MAAM,MAAM,CAAC;AACtB;AAEA,IAAM,SAAS,CAAC,MAAc,IAAI,KAAK,IAAI,IAAI;AAG/C,IAAM,UAAN,MAAc;AAAA,EAEZ,YAAqB,IAAqB,IAAY,MAAc;AAA/C;AAAqB;AACxC,SAAK,SAAS,IAAI,aAAa,KAAK,EAAE;AACtC,aAAS,IAAI,GAAG,IAAI,IAAI,IAAK,UAAS,IAAI,GAAG,IAAI,IAAI,IAAK,MAAK,OAAO,IAAI,KAAK,CAAC,IAAI,MAAM,GAAG,GAAG,IAAI;AAAA,EACtG;AAAA,EAHqB;AAAA,EAAqB;AAAA,EADjC;AAAA;AAAA,EAOT,GAAG,GAAW,GAAmB;AAC/B,UAAM,EAAE,IAAI,GAAG,IAAI;AACnB,UAAM,KAAK,KAAK,MAAM,CAAC;AACvB,UAAM,KAAK,KAAK,MAAM,CAAC;AACvB,UAAM,KAAK,OAAO,IAAI,EAAE;AACxB,UAAM,KAAK,OAAO,IAAI,EAAE;AACxB,UAAM,MAAO,KAAK,KAAM,MAAM;AAC9B,UAAM,MAAO,KAAK,KAAM,MAAM;AAC9B,UAAM,MAAM,KAAK,KAAK;AACtB,UAAM,MAAM,KAAK,KAAK;AACtB,UAAM,IAAI,KAAK;AACf,UAAM,IAAI,EAAE,KAAK,KAAK,EAAE,KAAK,EAAE,KAAK,KAAK,EAAE,IAAI,EAAE,KAAK,KAAK,EAAE,KAAK;AAClE,UAAM,IAAI,EAAE,KAAK,KAAK,EAAE,KAAK,EAAE,KAAK,KAAK,EAAE,IAAI,EAAE,KAAK,KAAK,EAAE,KAAK;AAClE,WAAO,KAAK,IAAI,KAAK;AAAA,EACvB;AACF;AAOO,IAAM,gBAAN,MAAoB;AAAA,EAGzB,YAAqB,MAAc,QAAgB,QAAgB,SAAiB,MAAc;AAA7E;AACnB,QAAI,KAAK,KAAK,IAAI,GAAG,KAAK,MAAM,MAAM,CAAC;AACvC,QAAI,KAAK,KAAK,IAAI,GAAG,KAAK,MAAM,MAAM,CAAC;AACvC,aAAS,IAAI,GAAG,IAAI,SAAS,KAAK;AAChC,WAAK,QAAQ,KAAK,IAAI,QAAQ,IAAI,IAAK,OAAO,IAAI,OAAQ,CAAC,CAAC;AAC5D,YAAM;AACN,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EARqB;AAAA,EAFJ,UAAqB,CAAC;AAAA;AAAA,EAavC,GAAG,GAAW,GAAmB;AAC/B,QAAI,MAAM;AACV,QAAI,MAAM;AACV,QAAI,OAAO;AACX,UAAM,IAAI,IAAI,KAAK;AACnB,UAAM,IAAI,IAAI,KAAK;AACnB,eAAW,KAAK,KAAK,SAAS;AAC5B,aAAO,EAAE,GAAG,IAAI,EAAE,IAAI,IAAI,EAAE,EAAE,IAAI;AAClC,cAAQ;AACR,aAAO;AAAA,IACT;AACA,WAAO,OAAO,IAAI,MAAM,OAAO;AAAA,EACjC;AACF;;;ACjFO,IAAM,iBAA0C,CAAC,UAAU,gBAAgB,eAAe,SAAS,UAAU,QAAQ,UAAU,UAAU,UAAU,SAAS,OAAO;AAKnK,IAAM,iBAAyC,CAAC,cAAc,WAAW,UAAU,UAAU,SAAS,QAAQ;AA2C9G,IAAM,aAAa;AAE1B,IAAM,OAAO,CAAC,GAAY,MAAe,OAAO,MAAM,YAAY,OAAO,SAAS,CAAC,IAAI,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,CAAC,CAAC,IAAI;AACrH,IAAM,WAAW,CAAC,GAAY,IAAY,IAAY,MAAe,OAAO,MAAM,YAAY,OAAO,SAAS,CAAC,IAAI,KAAK,IAAI,IAAI,KAAK,IAAI,IAAI,CAAC,CAAC,IAAI;AACnJ,IAAM,MAAM;AAIZ,IAAM,SAAS,CAAC,WAAW,GAAG,SAAS,WAAwB,EAAE,UAAU,OAAO;AAElF,SAAS,OACP,IACA,MACA,QACA,SACA,OACA,GACa;AACb,SAAO;AAAA,IACL,QAAQ;AAAA,IACR;AAAA,IACA;AAAA,IACA;AAAA,IACA,MAAM,EAAE,QAAQ;AAAA,IAChB;AAAA,IACA,OAAO,EAAE,SAAS;AAAA,IAClB,QAAQ;AAAA,IACR,OAAO,EAAE;AAAA,IACT,SAAS,EAAE,WAAW;AAAA,IACtB,KAAK,OAAO,EAAE,YAAY,CAAC;AAAA,IAC3B,KAAK,OAAO,CAAC;AAAA,IACb,YAAY,EAAE;AAAA,IACd,cAAc,EAAE;AAAA,IAChB,WAAW,EAAE;AAAA,EACf;AACF;AAGO,IAAM,gBAAwC;AAAA,EACnD,OAAO,gBAAgB,4BAA4B,cAAc,gBAAgB,WAAW,EAAE,OAAO,KAAK,YAAY,KAAK,cAAc,KAAK,WAAW,IAAI,CAAC;AAAA,EAC9J,OAAO,eAAe,2BAA2B,cAAc,eAAe,WAAW,EAAE,OAAO,MAAM,YAAY,MAAM,cAAc,KAAK,WAAW,KAAK,CAAC;AAAA,EAC9J,OAAO,oBAAoB,qBAAqB,cAAc,SAAS,WAAW,EAAE,OAAO,MAAM,YAAY,KAAK,cAAc,KAAK,WAAW,KAAK,CAAC;AAAA,EACtJ,OAAO,aAAa,aAAa,WAAW,UAAU,WAAW,EAAE,OAAO,KAAK,YAAY,KAAK,cAAc,KAAK,WAAW,KAAK,CAAC;AAAA,EACpI,OAAO,QAAQ,cAAc,WAAW,QAAQ,WAAW,EAAE,OAAO,MAAM,YAAY,MAAM,cAAc,MAAM,WAAW,KAAK,CAAC;AAAA,EACjI,OAAO,UAAU,kBAAkB,WAAW,UAAU,WAAW,EAAE,OAAO,KAAK,YAAY,KAAK,cAAc,KAAK,WAAW,KAAK,CAAC;AAAA,EACtI,OAAO,iBAAiB,uBAAuB,UAAU,UAAU,WAAW,EAAE,OAAO,KAAK,YAAY,KAAK,cAAc,KAAK,WAAW,KAAK,SAAS,KAAK,CAAC;AAAA,EAC/J,OAAO,eAAe,oBAAoB,UAAU,UAAU,WAAW,EAAE,OAAO,MAAM,YAAY,KAAK,cAAc,KAAK,WAAW,MAAM,OAAO,KAAK,SAAS,IAAI,CAAC;AAAA,EACvK,OAAO,iBAAiB,iBAAiB,UAAU,UAAU,WAAW,EAAE,OAAO,MAAM,YAAY,MAAM,cAAc,MAAM,WAAW,IAAI,CAAC;AAAA,EAC7I,OAAO,cAAc,cAAc,UAAU,SAAS,WAAW,EAAE,OAAO,MAAM,YAAY,KAAK,cAAc,MAAM,WAAW,IAAI,CAAC;AAAA,EACrI,OAAO,SAAS,eAAe,SAAS,SAAS,WAAW,EAAE,OAAO,MAAM,YAAY,KAAK,cAAc,MAAM,WAAW,IAAI,CAAC;AAAA,EAChI,OAAO,UAAU,kBAAkB,UAAU,UAAU,WAAW,EAAE,OAAO,GAAG,YAAY,KAAK,cAAc,KAAK,WAAW,MAAM,SAAS,EAAE,CAAC;AACjJ;AAEO,IAAM,gBAAyC,cAAc,CAAC;AAG9D,SAAS,YAAY,IAAuC;AACjE,QAAM,IAAI,cAAc,KAAK,CAAC,MAAM,EAAE,WAAW,EAAE;AACnD,SAAO,IAAI,WAAW,CAAC,IAAI;AAC7B;AAEO,SAAS,WAAW,GAAiC;AAC1D,SAAO,EAAE,GAAG,GAAG,KAAK,EAAE,GAAG,EAAE,IAAI,GAAG,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE;AACtD;AAEA,SAAS,WAAW,KAAc,GAA6B;AAC7D,QAAM,IAAI,OAAO,OAAO,QAAQ,WAAY,MAAkC,CAAC;AAC/E,SAAO,EAAE,UAAU,SAAS,EAAE,UAAU,GAAG,GAAG,EAAE,QAAQ,GAAG,QAAQ,OAAO,EAAE,WAAW,YAAY,EAAE,SAAS,EAAE,OAAO;AACzH;AAMO,SAAS,eAAe,MAAwD,CAAC,GAAG,MAAqC;AAC9H,QAAM,IAAI;AACV,QAAM,IAAI,SAAS,OAAO,EAAE,WAAW,WAAW,YAAY,EAAE,MAAM,IAAI,WAAc,WAAW,aAAa;AAChH,SAAO;AAAA,IACL,QAAQ,OAAO,EAAE,WAAW,YAAY,EAAE,SAAS,EAAE,SAAS,EAAE;AAAA,IAChE,MAAM,OAAO,EAAE,SAAS,YAAY,EAAE,KAAK,KAAK,IAAI,EAAE,KAAK,KAAK,IAAI,EAAE;AAAA,IACtE,QAAQ,eAAe,SAAS,EAAE,MAAqB,IAAK,EAAE,SAAyB,EAAE;AAAA,IACzF,SAAS,eAAe,SAAS,EAAE,OAAuB,IAAK,EAAE,UAA2B,EAAE;AAAA,IAC9F,MAAM,OAAO,EAAE,SAAS,YAAY,OAAO,SAAS,EAAE,IAAI,IAAI,KAAK,MAAM,KAAK,IAAI,EAAE,IAAI,CAAC,IAAI,aAAa,EAAE;AAAA,IAC5G,OAAO,OAAO,EAAE,UAAU,YAAY,IAAI,KAAK,EAAE,KAAK,IAAI,EAAE,MAAM,YAAY,IAAI,EAAE;AAAA,IACpF,OAAO,SAAS,EAAE,OAAO,MAAM,GAAG,EAAE,KAAK;AAAA,IACzC,QAAQ,EAAE,WAAW,YAAY,EAAE,WAAW,WAAW,EAAE,SAAS,EAAE;AAAA,IACtE,OAAO,KAAK,EAAE,OAAO,EAAE,KAAK;AAAA,IAC5B,SAAS,KAAK,EAAE,SAAS,EAAE,OAAO;AAAA,IAClC,KAAK,WAAW,EAAE,KAAK,EAAE,GAAG;AAAA,IAC5B,KAAK,WAAW,EAAE,KAAK,EAAE,GAAG;AAAA,IAC5B,YAAY,KAAK,EAAE,YAAY,EAAE,UAAU;AAAA,IAC3C,cAAc,KAAK,EAAE,cAAc,EAAE,YAAY;AAAA,IACjD,WAAW,KAAK,EAAE,WAAW,EAAE,SAAS;AAAA,EAC1C;AACF;AAMA,IAAM,UAAU,CAAC,MAAe,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI;AAGxD,SAAS,eAAe,SAAuB,GAAW,MAA4B;AACpF,QAAM,MAAM,IAAI,aAAa,IAAI,CAAC;AAClC,QAAM,OAAO,KAAK,KAAK,OAAO,GAAG,UAAU,IAAI;AAC/C,MAAI,YAAY,SAAU,QAAO,IAAI,KAAK,CAAC;AAC3C,QAAM,QAAQ,CAAC,IAAY,IAAY,KAAa,IAAI,MAAM,IAAI,cAAc,GAAG,IAAI,IAAI,KAAK,OAAO,CAAC;AACxG,QAAM,IAAI,IAAI;AACd,UAAQ,SAAS;AAAA,IACf,KAAK,gBAAgB;AACnB,YAAM,OAAO,MAAM,KAAK,GAAG,KAAK,GAAG,CAAC;AACpC,YAAM,OAAO,MAAM,KAAK,GAAG,KAAK,GAAG,GAAG,CAAC;AACvC,eAAS,IAAI,GAAG,IAAI,GAAG;AACrB,iBAAS,IAAI,GAAG,IAAI,GAAG,IAAK,KAAI,IAAI,IAAI,CAAC,IAAI,SAAS,KAAK,GAAG,GAAG,CAAC,IAAI,OAAO,MAAM,OAAO,KAAK,GAAG,GAAG,CAAC,IAAI,OAAO,OAAO,MAAM,GAAG,GAAG,IAAI,IAAI,OAAO,IAAI;AACzJ;AAAA,IACF;AAAA,IACA,KAAK,eAAe;AAClB,YAAM,OAAO,MAAM,KAAK,GAAG,KAAK,GAAG,CAAC;AACpC,eAAS,IAAI,GAAG,IAAI,GAAG,IAAK,UAAS,IAAI,GAAG,IAAI,GAAG,IAAK,KAAI,IAAI,IAAI,CAAC,IAAI,SAAS,KAAK,GAAG,GAAG,CAAC,IAAI,OAAO,MAAM,OAAO,MAAM,GAAG,GAAG,IAAI,IAAI,OAAO,IAAI;AACrJ;AAAA,IACF;AAAA,IACA,KAAK,SAAS;AACZ,YAAM,OAAO,MAAM,KAAK,GAAG,KAAK,GAAG,CAAC;AACpC,YAAM,OAAO,MAAM,KAAK,GAAG,KAAK,GAAG,GAAG,CAAC;AACvC,eAAS,IAAI,GAAG,IAAI,GAAG;AACrB,iBAAS,IAAI,GAAG,IAAI,GAAG,IAAK,KAAI,IAAI,IAAI,CAAC,IAAI,SAAS,KAAK,GAAG,GAAG,CAAC,IAAI,OAAO,MAAM,OAAO,KAAK,GAAG,GAAG,CAAC,IAAI,OAAO,OAAO,MAAM,GAAG,GAAG,IAAI,IAAI,OAAO,IAAI;AACzJ;AAAA,IACF;AAAA,IACA,KAAK,UAAU;AACb,YAAM,OAAO,MAAM,KAAK,GAAG,KAAK,GAAG,CAAC;AACpC,eAAS,IAAI,GAAG,IAAI,GAAG,IAAK,UAAS,IAAI,GAAG,IAAI,GAAG,IAAK,KAAI,IAAI,IAAI,CAAC,IAAI,SAAS,KAAK,GAAG,GAAG,CAAC,IAAI,OAAO,MAAM,QAAQ,MAAM,GAAG,GAAG,IAAI,IAAI,OAAO,GAAG;AACrJ;AAAA,IACF;AAAA,IACA,KAAK,QAAQ;AAEX,YAAM,OAAO,MAAM,KAAK,GAAG,KAAK,GAAG,CAAC;AACpC,YAAM,QAAQ,IAAI;AAClB,eAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,cAAM,OAAO,MAAM,MAAM,KAAK,IAAK,IAAI,KAAK,KAAK,IAAK,CAAC;AACvD,iBAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,gBAAM,IAAI,KAAK,KAAM,IAAI,OAAO,QAAS,QAAQ,CAAC,KAAK,QAAQ;AAC/D,gBAAM,YAAY,IAAI,OAAO,QAAQ;AACrC,cAAI,IAAI,IAAI,CAAC,IAAI,QAAQ,MAAM,MAAM,OAAO,aAAa,KAAK,GAAG,GAAG,CAAC,IAAI,OAAO,GAAG;AAAA,QACrF;AAAA,MACF;AACA;AAAA,IACF;AAAA,IACA,KAAK,UAAU;AAEb,YAAM,SAAS,MAAM,KAAK,GAAG,KAAK,GAAG,CAAC;AACtC,YAAM,OAAO,MAAM,KAAK,GAAG,KAAK,GAAG,GAAG,CAAC;AACvC,eAAS,IAAI,GAAG,IAAI,GAAG;AACrB,iBAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,gBAAM,IAAI,MAAM,GAAG,GAAG,OAAO,EAAI;AACjC,cAAI,IAAI,IAAI,CAAC,IAAI,SAAS,OAAO,GAAG,GAAG,CAAC,IAAI,OAAO,OAAO,KAAK,GAAG,GAAG,CAAC,IAAI,OAAO,MAAM,QAAQ,IAAI,MAAM,OAAO,EAAE;AAAA,QACpH;AACF;AAAA,IACF;AAAA,IACA,KAAK,UAAU;AAEb,YAAM,OAAO,MAAM,KAAK,GAAG,KAAK,GAAG,CAAC;AACpC,eAAS,IAAI,GAAG,IAAI,GAAG;AACrB,iBAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,gBAAM,IAAI,MAAM,GAAG,GAAG,IAAI;AAC1B,cAAI,IAAI,IAAI,CAAC,IAAI,SAAS,KAAK,GAAG,GAAG,CAAC,IAAI,OAAO,MAAM,OAAO,IAAI,OAAO,GAAG;AAAA,QAC9E;AACF;AAAA,IACF;AAAA,IACA,KAAK;AAAA,IACL,KAAK,SAAS;AAEZ,YAAM,UAAU,YAAY,WAAW,IAAI,KAAK;AAEhD,YAAM,UAAU,KAAK,IAAI,GAAG,IAAI,KAAK,MAAM,IAAI,SAAS,CAAC,CAAC;AAC1D,YAAM,IAAI,IAAI;AACd,YAAM,OAAO,MAAM,SAAS,SAAS,GAAG,EAAE;AAC1C,eAAS,IAAI,GAAG,IAAI,GAAG;AACrB,iBAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,gBAAM,MAAM,IAAI,OAAO;AACvB,gBAAM,MAAM,IAAI,OAAO;AACvB,gBAAM,KAAK,KAAK,MAAM,EAAE;AACxB,gBAAM,KAAK,KAAK,MAAM,EAAE;AACxB,gBAAM,OAAO,KAAK,IAAI,KAAK,MAAM,KAAK,GAAG;AACzC,gBAAM,OAAO,KAAK,IAAI,KAAK,MAAM,KAAK,GAAG;AACzC,gBAAM,OAAO,KAAK,MAAM,MAAM,IAAI,OAAO;AACzC,gBAAM,YAAY,YAAY,WAAW,KAAK,GAAG,GAAG,CAAC,IAAI,OAAO,MAAM;AACtE,cAAI,IAAI,IAAI,CAAC,IAAI,QAAQ,MAAM,MAAM,MAAM,aAAa,MAAM,GAAG,GAAG,IAAI,IAAI,OAAO,IAAI;AAAA,QACzF;AACF;AAAA,IACF;AAAA,IACA,KAAK,SAAS;AAEZ,YAAM,UAAU,MAAM,IAAI,GAAG,KAAK,GAAG,CAAC;AACtC,YAAM,QAAQ,MAAM,KAAK,GAAG,KAAK,GAAG,GAAG,EAAE;AACzC,eAAS,IAAI,GAAG,IAAI,GAAG;AACrB,iBAAS,IAAI,GAAG,IAAI,GAAG,IAAK,KAAI,IAAI,IAAI,CAAC,IAAI,SAAS,QAAQ,GAAG,GAAG,CAAC,IAAI,OAAO,OAAO,MAAM,GAAG,GAAG,CAAC,IAAI,OAAO,MAAM,IAAI;AAC3H;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAEA,IAAM,WAAW,oBAAI,IAA0B;AAGxC,SAAS,aAAa,SAAuB,MAAc,OAAO,YAA0B;AACjG,QAAM,MAAM,GAAG,OAAO,IAAI,IAAI,IAAI,IAAI;AACtC,MAAI,IAAI,SAAS,IAAI,GAAG;AACxB,MAAI,CAAC,GAAG;AACN,QAAI,eAAe,SAAS,MAAM,IAAI;AACtC,QAAI,SAAS,OAAO,GAAI,UAAS,OAAO,SAAS,KAAK,EAAE,KAAK,EAAE,KAAe;AAC9E,aAAS,IAAI,KAAK,CAAC;AAAA,EACrB;AACA,SAAO;AACT;AAMO,IAAM,aAAN,MAAiB;AAAA,EACb,OAAO;AAAA,EACC;AAAA,EACA;AAAA,EACA;AAAA,EACR;AAAA,EAET,YAAY,OAAsB,QAAuB,OAAO;AAC9D,UAAM,MAAM,aAAa,MAAM,SAAS,MAAM,IAAI;AAClD,UAAM,IAAI,MAAM,KAAK;AACrB,SAAK,OAAO,MAAM,YAAY;AAC9B,QAAI,EAAE,aAAa,KAAK,CAAC,EAAE,OAAQ,MAAK,UAAU;AAAA,SAC7C;AACH,YAAM,MAAM,IAAI,aAAa,IAAI,MAAM;AACvC,eAAS,IAAI,GAAG,IAAI,IAAI,QAAQ,KAAK;AACnC,cAAM,IAAI,SAAS,IAAI,CAAC,IAAI,OAAO,EAAE,WAAW,GAAG;AACnD,YAAI,CAAC,IAAI,EAAE,SAAS,IAAI,IAAI;AAAA,MAC9B;AACA,WAAK,UAAU;AAAA,IACjB;AACA,SAAK,QAAQ,MAAM;AACnB,SAAK,SAAS,MAAM,WAAW;AAAA,EACjC;AAAA;AAAA,EAGQ,KAAK,GAAmB;AAC9B,UAAM,IAAI,KAAK;AACf,QAAI,CAAC,KAAK,OAAQ,SAAS,IAAI,IAAK,KAAK;AACzC,UAAM,KAAM,KAAK,IAAI,KAAM,IAAI,MAAM,IAAI;AACzC,WAAO,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI;AAAA,EACjC;AAAA;AAAA,EAGA,GAAG,GAAW,GAAmB;AAC/B,UAAM,IAAI,IAAI,KAAK,QAAQ;AAC3B,UAAM,IAAI,IAAI,KAAK,QAAQ;AAC3B,UAAM,KAAK,KAAK,MAAM,CAAC;AACvB,UAAM,KAAK,KAAK,MAAM,CAAC;AACvB,UAAM,KAAK,IAAI;AACf,UAAM,KAAK,IAAI;AACf,UAAM,IAAI,KAAK;AACf,UAAM,IAAI,KAAK;AACf,UAAM,IAAI,KAAK,KAAK,EAAE;AACtB,UAAM,IAAI,KAAK,KAAK,KAAK,CAAC;AAC1B,UAAM,IAAI,KAAK,KAAK,EAAE,IAAI;AAC1B,UAAM,IAAI,KAAK,KAAK,KAAK,CAAC,IAAI;AAC9B,UAAM,MAAM,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK;AAC/C,UAAM,MAAM,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK;AAC/C,WAAO,OAAO,MAAM,OAAO;AAAA,EAC7B;AACF;AAOO,SAAS,WAAW,GAAW,OAAe,UAA0B;AAC7E,MAAI,SAAS,EAAG,QAAO;AACvB,QAAM,IAAI,SAAS,OAAO,OAAO,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,QAAQ,CAAC;AAClE,QAAM,IAAI,SAAS,IAAI,IAAI,QAAQ,IAAI;AACvC,SAAO,IAAI,QAAQ,QAAQ,IAAI,KAAK,IAAI,IAAI;AAC9C;AAGO,SAAS,UAAU,KAAuC;AAC/D,QAAM,IAAI,SAAS,IAAI,MAAM,GAAG,CAAC,GAAG,EAAE;AACtC,SAAO,CAAE,KAAK,KAAM,KAAM,KAAK,IAAK,KAAK,IAAI,GAAG;AAClD;AAMO,SAAS,YAAY,OAAsB,MAA+D,QAAQ,IAAI,WAAW,KAAK,GAAsB;AACjK,QAAM,CAAC,GAAG,GAAG,CAAC,IAAI,UAAU,MAAM,KAAK;AACvC,QAAM,MAAM,IAAI,kBAAkB,KAAK,QAAQ,KAAK,SAAS,CAAC;AAC9D,QAAM,QAAQ,MAAM,OAAO,IAAI,MAAM,UAAU;AAC/C,WAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,aAAS,IAAI,GAAG,IAAI,KAAK,OAAO,KAAK;AACnC,YAAM,KAAK,IAAI,KAAK,QAAQ,KAAK;AACjC,YAAM,IAAI,QAAQ,IAAI,SAAS,IAAI,MAAM,GAAG,KAAK,IAAI,IAAI,KAAK,KAAK,IAAI,IAAI,GAAG,KAAK;AACnF,UAAI,CAAC,IAAI,IAAI;AACb,UAAI,IAAI,CAAC,IAAI,IAAI;AACjB,UAAI,IAAI,CAAC,IAAI,IAAI;AACjB,UAAI,IAAI,CAAC,IAAI;AAAA,IACf;AAAA,EACF;AACA,SAAO;AACT;;;ACzWO,IAAM,kBAAkB;AACxB,IAAM,kBAAkB;AACxB,IAAM,cAAc;AAoB3B,IAAI,SAAS;AAGN,SAAS,kBAA0B;AACxC,SAAO,KAAK,KAAK,IAAI,EAAE,SAAS,EAAE,CAAC,IAAI,UAAU,SAAS,EAAE,CAAC;AAC/D;AAGO,SAAS,iBAAiB,MAAc,KAAK,gBAAgB,GAAoB;AACtF,SAAO,EAAE,MAAM,SAAS,IAAI,MAAM,SAAS,MAAM,SAAS,GAAG,OAAO,UAAU,SAAS,aAAa,CAAC,GAAG,QAAQ,EAAE,GAAG,GAAG,GAAG,EAAE,EAAE;AACjI;AAEO,IAAM,qBAAN,cAAiC,MAAM;AAAA,EAC5C,YAAY,SAAiB;AAC3B,UAAM,OAAO;AACb,SAAK,OAAO;AAAA,EACd;AACF;AAGO,SAAS,gBAAgB,KAAwC;AACtE,QAAM,OAAO,CAAC,GAAY,SAAiB;AACzC,QAAI,OAAO,MAAM,YAAY,CAAC,OAAO,SAAS,CAAC,EAAG,OAAM,IAAI,mBAAmB,GAAG,IAAI,gCAAgC,eAAe,KAAK,eAAe,IAAI;AAC7J,UAAM,IAAI,KAAK,MAAM,CAAC;AACtB,QAAI,IAAI,mBAAmB,IAAI,gBAAiB,OAAM,IAAI,mBAAmB,GAAG,IAAI,IAAI,CAAC,yBAAyB,eAAe,KAAK,eAAe,UAAU;AAC/J,WAAO;AAAA,EACT;AACA,QAAM,MAAM,IAAI,QAAQ,SAAY,cAAc,IAAI;AACtD,MAAI,OAAO,QAAQ,YAAY,CAAC,OAAO,SAAS,GAAG,KAAK,MAAM,KAAK,MAAM,IAAO,OAAM,IAAI,mBAAmB,OAAO,GAAG,iCAAiC;AACxJ,SAAO,EAAE,OAAO,KAAK,IAAI,OAAO,OAAO,GAAG,QAAQ,KAAK,IAAI,QAAQ,QAAQ,GAAG,KAAK,KAAK,MAAM,MAAM,GAAG,IAAI,IAAI;AACjH;AAGO,SAAS,oBAAoB,UAAqE,CAAC,GAAuB;AAC/H,QAAM,SAAS,gBAAgB,EAAE,OAAO,QAAQ,SAAS,MAAM,QAAQ,QAAQ,UAAU,MAAM,KAAK,QAAQ,IAAI,CAAC;AACjH,QAAM,QAAQ,iBAAiB,SAAS;AACxC,SAAO,EAAE,QAAQ,OAAO,eAAe,QAAQ,SAAS,CAAC,CAAC,GAAG,QAAQ,CAAC,KAAK,GAAG,eAAe,MAAM,IAAI,SAAS,CAAC,EAAE;AACrH;;;ACnEO,IAAM,sBAAmD,CAAC,OAAO,UAAU,OAAO;AAIlF,IAAM,yBAAwD,CAAC,UAAU,UAAU,YAAY,YAAY,UAAU,OAAO,UAAU,WAAW,UAAU,SAAS,QAAQ;AAK5K,IAAM,kBAA4C,CAAC,SAAS,UAAU,QAAQ;AA4B9E,IAAM,mBAA4C;AAAA,EACvD,SAAS;AAAA,EACT,cAAc;AAAA,EACd,UAAU;AAAA,EACV,eAAe;AAAA,EACf,aAAa;AAAA,EACb,cAAc;AAAA,EACd,iBAAiB;AAAA,EACjB,YAAY;AAAA,EACZ,aAAa;AAAA,EACb,eAAe;AAAA,EACf,SAAS;AACX;AAwBA,IAAMA,QAAO,CAAC,GAAY,MAAe,OAAO,MAAM,YAAY,OAAO,SAAS,CAAC,IAAI,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,CAAC,CAAC,IAAI;AACrH,IAAM,QAAQ,CAAC,GAAY,IAAY,IAAY,MAAe,OAAO,MAAM,YAAY,OAAO,SAAS,CAAC,IAAI,KAAK,IAAI,IAAI,KAAK,IAAI,IAAI,CAAC,CAAC,IAAI;AAEzI,SAAS,kBAAkB,MAA8B,CAAC,GAAG,OAAsB,kBAAiC;AACzH,SAAO;AAAA,IACL,SAASA,MAAK,IAAI,SAAS,KAAK,OAAO;AAAA,IACvC,cAAcA,MAAK,IAAI,cAAc,KAAK,YAAY;AAAA,IACtD,UAAUA,MAAK,IAAI,UAAU,KAAK,QAAQ;AAAA,IAC1C,eAAeA,MAAK,IAAI,eAAe,KAAK,aAAa;AAAA,IACzD,aAAaA,MAAK,IAAI,aAAa,KAAK,WAAW;AAAA,IACnD,cAAc,MAAM,IAAI,cAAc,IAAI,GAAG,KAAK,YAAY;AAAA,IAC9D,iBAAiB,MAAM,IAAI,iBAAiB,IAAI,GAAG,KAAK,eAAe;AAAA,IACvE,YAAYA,MAAK,IAAI,YAAY,KAAK,UAAU;AAAA,IAChD,aAAaA,MAAK,IAAI,aAAa,KAAK,WAAW;AAAA,IACnD,eAAeA,MAAK,IAAI,eAAe,KAAK,aAAa;AAAA,IACzD,SAAS,MAAM,IAAI,SAAS,GAAG,GAAG,KAAK,OAAO;AAAA,EAChD;AACF;AAEO,IAAM,WAAW;AAMjB,SAAS,oBAAoB,MAAuB,CAAC,GAAG,MAA+B;AAC5F,QAAM,IAAI,QAAQ;AAClB,QAAM,KAAK,OAAO,IAAI,OAAO,YAAY,SAAS,KAAK,IAAI,EAAE,IAAI,IAAI,KAAK,EAAE;AAC5E,SAAO;AAAA,IACL;AAAA,IACA,MAAM,OAAO,IAAI,SAAS,YAAY,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,EAAE,MAAM,GAAG,EAAE,IAAI,EAAE;AAAA,IACzF,UAAU,uBAAuB,SAAS,IAAI,QAA8B,IAAK,IAAI,WAAkC,EAAE;AAAA,IACzH,QAAQ,oBAAoB,SAAS,IAAI,MAA0B,IAAK,IAAI,SAA8B,EAAE;AAAA,IAC5G,KAAK,eAAe,EAAE,GAAG,EAAE,KAAK,GAAI,IAAI,OAAO,CAAC,EAAG,CAAC;AAAA,IACpD,OAAOA,MAAK,IAAI,OAAO,EAAE,KAAK;AAAA,IAC9B,mBAAmB,MAAM,IAAI,mBAAmB,GAAG,MAAM,EAAE,iBAAiB;AAAA,IAC5E,UAAU,gBAAgB,SAAS,IAAI,QAAyB,IAAK,IAAI,WAA6B,EAAE;AAAA,IACxG,UAAU,kBAAkB,IAAI,YAAY,CAAC,GAAG,EAAE,QAAQ;AAAA,IAC1D,OAAO,eAAe,EAAE,GAAG,EAAE,OAAO,GAAI,IAAI,SAAS,CAAC,EAAG,CAAC;AAAA,IAC1D,YAAY,OAAO,IAAI,eAAe,YAAY,IAAI,aAAa,EAAE;AAAA,IACrE,GAAI,IAAI,UAAU,EAAE,SAAS,KAAK,IAAI,CAAC;AAAA,EACzC;AACF;AAEA,IAAM,aAAyB;AAAA,EAC7B,IAAI;AAAA,EACJ,MAAM;AAAA,EACN,UAAU;AAAA,EACV,QAAQ;AAAA,EACR,KAAK,EAAE,GAAG,cAAc;AAAA,EACxB,OAAO;AAAA,EACP,mBAAmB;AAAA,EACnB,UAAU;AAAA,EACV,UAAU,EAAE,GAAG,iBAAiB;AAAA,EAChC,OAAO,EAAE,GAAG,cAAc;AAAA,EAC1B,YAAY;AACd;AAIA,IAAM,UAAU,CAAC,UAAiC,EAAE,GAAG,oBAAoB,IAAI,GAAG,SAAS,KAAK;AAGzF,IAAM,kBAAyC;AAAA,EACpD,QAAQ;AAAA,IACN,IAAI;AAAA,IAAa,MAAM;AAAA,IAAa,UAAU;AAAA,IAC9C,KAAK,EAAE,MAAM,GAAG,UAAU,KAAK,SAAS,MAAM,SAAS,MAAM,MAAM,MAAM,WAAW,MAAM,cAAc,MAAM,iBAAiB,KAAK;AAAA,IACpI,OAAO;AAAA,IAAM,mBAAmB;AAAA,IAChC,UAAU,EAAE,SAAS,MAAM,UAAU,KAAK,eAAe,KAAK,aAAa,IAAI;AAAA,EACjF,CAAC;AAAA,EACD,QAAQ;AAAA,IACN,IAAI;AAAA,IAAa,MAAM;AAAA,IAAa,UAAU;AAAA,IAC9C,KAAK,EAAE,MAAM,GAAG,UAAU,MAAM,SAAS,MAAM,SAAS,GAAG,MAAM,MAAM,WAAW,KAAK,cAAc,MAAM,iBAAiB,KAAK;AAAA,IACjI,OAAO;AAAA,IAAK,mBAAmB;AAAA,IAC/B,UAAU,EAAE,SAAS,KAAK,UAAU,GAAG,eAAe,MAAM,aAAa,KAAK;AAAA,EAChF,CAAC;AAAA,EACD,QAAQ;AAAA,IACN,IAAI;AAAA,IAAe,MAAM;AAAA,IAAe,UAAU;AAAA,IAAU,UAAU;AAAA,IACtE,KAAK,EAAE,MAAM,IAAI,UAAU,MAAM,SAAS,MAAM,OAAO,IAAI,WAAW,MAAM,SAAS,GAAG,MAAM,KAAK,WAAW,MAAM,cAAc,OAAO,iBAAiB,KAAK;AAAA,IAC/J,OAAO;AAAA,IAAG,mBAAmB;AAAA,IAC7B,UAAU,EAAE,YAAY,MAAM,aAAa,KAAK;AAAA,EAClD,CAAC;AAAA,EACD,QAAQ;AAAA,IACN,IAAI;AAAA,IAAc,MAAM;AAAA,IAAc,UAAU;AAAA,IAAU,UAAU;AAAA,IACpE,KAAK,EAAE,MAAM,IAAI,UAAU,KAAK,SAAS,MAAM,OAAO,IAAI,WAAW,KAAK,SAAS,GAAG,MAAM,KAAK,WAAW,MAAM,cAAc,MAAM,iBAAiB,OAAO,OAAO,UAAU;AAAA,IAC/K,OAAO;AAAA,IAAK,mBAAmB;AAAA,IAC/B,UAAU,EAAE,SAAS,IAAI;AAAA,EAC3B,CAAC;AAAA,EACD,QAAQ;AAAA,IACN,IAAI;AAAA,IAAkB,MAAM;AAAA,IAAkB,UAAU;AAAA,IAAY,UAAU;AAAA,IAC9E,KAAK,EAAE,MAAM,IAAI,UAAU,KAAK,SAAS,MAAM,OAAO,IAAI,WAAW,MAAM,SAAS,MAAM,MAAM,KAAK,WAAW,MAAM,cAAc,OAAO,iBAAiB,KAAK;AAAA,IACjK,OAAO;AAAA,IAAM,mBAAmB;AAAA,IAChC,UAAU,EAAE,YAAY,KAAK,aAAa,MAAM,UAAU,IAAI;AAAA,EAChE,CAAC;AAAA,EACD,QAAQ;AAAA,IACN,IAAI;AAAA,IAAiB,MAAM;AAAA,IAAiB,UAAU;AAAA,IACtD,KAAK,EAAE,MAAM,IAAI,UAAU,KAAK,SAAS,MAAM,SAAS,MAAM,MAAM,MAAM,WAAW,KAAK,cAAc,MAAM,iBAAiB,KAAK;AAAA,IACpI,OAAO;AAAA,IAAK,mBAAmB;AAAA,IAC/B,UAAU,EAAE,SAAS,KAAK,UAAU,KAAK,eAAe,KAAK,aAAa,KAAK,YAAY,KAAK;AAAA,EAClG,CAAC;AAAA,EACD,QAAQ;AAAA,IACN,IAAI;AAAA,IAAY,MAAM;AAAA,IAAY,UAAU;AAAA,IAC5C,KAAK,EAAE,MAAM,IAAI,UAAU,GAAG,SAAS,MAAM,SAAS,GAAG,MAAM,MAAM,WAAW,KAAK,cAAc,OAAO,iBAAiB,MAAM;AAAA,IACjI,OAAO;AAAA,IAAG,mBAAmB;AAAA,IAC7B,UAAU,EAAE,cAAc,GAAG,UAAU,KAAK,eAAe,IAAI;AAAA,EACjE,CAAC;AAAA,EACD,QAAQ;AAAA,IACN,IAAI;AAAA,IAAU,MAAM;AAAA,IAAiB,UAAU;AAAA,IAC/C,KAAK,EAAE,MAAM,IAAI,UAAU,MAAM,SAAS,MAAM,OAAO,IAAI,WAAW,MAAM,SAAS,KAAK,MAAM,GAAG,WAAW,KAAK,cAAc,OAAO,iBAAiB,OAAO,OAAO,WAAW;AAAA,IAClL,OAAO;AAAA,EACT,CAAC;AAAA,EACD,QAAQ;AAAA,IACN,IAAI;AAAA,IAAW,MAAM;AAAA,IAAW,UAAU;AAAA,IAC1C,KAAK,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,MAAM,SAAS,GAAG,MAAM,GAAG,WAAW,KAAK,cAAc,MAAM,iBAAiB,MAAM;AAAA,IAC5H,mBAAmB;AAAA,IACnB,UAAU,EAAE,SAAS,MAAM,cAAc,MAAM;AAAA,EACjD,CAAC;AAAA,EACD,QAAQ;AAAA,IACN,IAAI;AAAA,IAAa,MAAM;AAAA,IAAa,UAAU;AAAA,IAAO,UAAU;AAAA,IAC/D,KAAK,EAAE,MAAM,IAAI,UAAU,KAAK,SAAS,MAAM,WAAW,KAAK,SAAS,GAAG,MAAM,GAAG,WAAW,KAAK,cAAc,MAAM,iBAAiB,MAAM;AAAA,IAC/I,mBAAmB;AAAA,IACnB,UAAU,EAAE,SAAS,MAAM,cAAc,KAAK;AAAA,EAChD,CAAC;AAAA,EACD,QAAQ;AAAA,IACN,IAAI;AAAA,IAAe,MAAM;AAAA,IAAe,UAAU;AAAA,IAAU,QAAQ;AAAA,IACpE,KAAK,EAAE,MAAM,IAAI,UAAU,KAAK,SAAS,MAAM,SAAS,GAAG,MAAM,KAAK,cAAc,OAAO,iBAAiB,KAAK;AAAA,EACnH,CAAC;AAAA,EACD,QAAQ;AAAA,IACN,IAAI;AAAA,IAAe,MAAM;AAAA,IAAe,UAAU;AAAA,IAAU,QAAQ;AAAA,IACpE,KAAK,EAAE,MAAM,IAAI,UAAU,KAAK,SAAS,MAAM,SAAS,GAAG,MAAM,GAAG,cAAc,MAAM,iBAAiB,MAAM;AAAA,IAC/G,OAAO;AAAA,IACP,UAAU,EAAE,SAAS,IAAI;AAAA,EAC3B,CAAC;AAAA,EACD,QAAQ;AAAA,IACN,IAAI;AAAA,IAAW,MAAM;AAAA,IAAW,UAAU;AAAA,IAAW,QAAQ;AAAA,IAAS,YAAY;AAAA,IAClF,KAAK,EAAE,MAAM,IAAI,UAAU,KAAK,SAAS,MAAM,SAAS,GAAG,MAAM,MAAM,WAAW,KAAK,cAAc,OAAO,iBAAiB,KAAK;AAAA,IAClI,OAAO,EAAE,KAAK,KAAK,MAAM,GAAG,KAAK,GAAG,gBAAgB,OAAO,iBAAiB,MAAM,QAAQ,UAAU;AAAA,EACtG,CAAC;AAAA,EACD,QAAQ;AAAA,IACN,IAAI;AAAA,IAAU,MAAM;AAAA,IAAU,UAAU;AAAA,IAAU,QAAQ;AAAA,IAAS,YAAY;AAAA,IAC/E,KAAK,EAAE,MAAM,IAAI,UAAU,KAAK,SAAS,MAAM,SAAS,GAAG,MAAM,KAAK,WAAW,KAAK,cAAc,OAAO,iBAAiB,KAAK;AAAA,IACjI,OAAO,EAAE,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,gBAAgB,OAAO,iBAAiB,MAAM,QAAQ,MAAM;AAAA,EAChG,CAAC;AAAA,EACD,QAAQ;AAAA,IACN,IAAI;AAAA,IAAe,MAAM;AAAA,IAAe,UAAU;AAAA,IAAS,QAAQ;AAAA,IACnE,KAAK,EAAE,MAAM,IAAI,UAAU,KAAK,SAAS,KAAK,SAAS,GAAG,MAAM,KAAK,WAAW,KAAK,cAAc,MAAM,iBAAiB,MAAM;AAAA,IAChI,OAAO,EAAE,KAAK,KAAK,MAAM,MAAM,KAAK,KAAK,gBAAgB,MAAM,iBAAiB,MAAM,QAAQ,UAAU;AAAA,IACxG,UAAU,EAAE,SAAS,IAAI;AAAA,EAC3B,CAAC;AACH;AAEO,IAAM,mBAAmB;AAKzB,SAAS,YAAY,OAAgD;AAC1E,QAAM,EAAE,SAAS,IAAI,GAAG,KAAK,IAAI;AACjC,SAAO,KAAK,MAAM,KAAK,UAAU,IAAI,CAAC;AACxC;AAaO,SAAS,kBAAkB,KAAc,WAAqB,CAAC,GAAiB;AACrF,QAAM,OAAO,MAAM,QAAQ,GAAG,IAAI,MAAM,OAAO,OAAO,QAAQ,YAAY,MAAM,QAAS,IAAyB,OAAO,IAAK,IAAyB,UAAU;AACjK,MAAI,CAAC,KAAM,OAAM,IAAI,MAAM,iHAAiH;AAC5I,QAAM,MAAoB,CAAC;AAC3B,OAAK,QAAQ,CAAC,MAAM,MAAM;AACxB,QAAI,CAAC,QAAQ,OAAO,SAAS,UAAU;AACrC,eAAS,KAAK,WAAW,CAAC,8BAA8B;AACxD;AAAA,IACF;AACA,UAAM,IAAI;AACV,QAAI,OAAO,EAAE,OAAO,YAAY,CAAC,SAAS,KAAK,EAAE,EAAE,GAAG;AACpD,eAAS,KAAK,WAAW,CAAC,oEAAoE;AAC9F;AAAA,IACF;AACA,QAAI,OAAO,EAAE,SAAS,YAAY,CAAC,EAAE,KAAK,KAAK,GAAG;AAChD,eAAS,KAAK,WAAW,CAAC,OAAO,EAAE,EAAE,0BAA0B;AAC/D;AAAA,IACF;AACA,UAAM,EAAE,SAAS,IAAI,GAAG,KAAK,IAAI;AACjC,QAAI,KAAK,oBAAoB,IAAuB,CAAC;AAAA,EACvD,CAAC;AACD,SAAO;AACT;;;AC7OO,SAAS,eAAe,GAA2D;AACxF,MAAI,OAAO,EAAE,aAAa,YAAY,OAAO,SAAS,EAAE,QAAQ,GAAG;AACjE,UAAM,WAAW,KAAK,IAAI,KAAK,KAAK,GAAG,KAAK,IAAI,GAAG,EAAE,QAAQ,CAAC;AAC9D,UAAM,UAAU,OAAO,EAAE,YAAY,YAAY,OAAO,SAAS,EAAE,OAAO,IAAI,EAAE,UAAU;AAC1F,WAAO,EAAE,UAAU,QAAQ;AAAA,EAC7B;AACA,QAAM,OAAO,OAAO,EAAE,UAAU,YAAY,OAAO,SAAS,EAAE,KAAK;AACnE,QAAM,OAAO,OAAO,EAAE,UAAU,YAAY,OAAO,SAAS,EAAE,KAAK;AACnE,MAAI,CAAC,QAAQ,CAAC,KAAM,QAAO;AAC3B,SAAO,kBAAkB,OAAO,EAAE,QAAS,GAAG,OAAO,EAAE,QAAS,CAAC;AACnE;AAGO,SAAS,kBAAkB,OAAe,OAAsD;AACrG,QAAM,SAAS,CAAC,MAAc,KAAK,IAAI,QAAQ,KAAK,IAAI,SAAS,CAAC,CAAC;AACnE,QAAM,KAAK,KAAK,IAAK,OAAO,KAAK,IAAI,KAAK,KAAM,GAAG;AACnD,QAAM,KAAK,KAAK,IAAK,OAAO,KAAK,IAAI,KAAK,KAAM,GAAG;AACnD,QAAM,IAAI,KAAK,MAAM,IAAI,EAAE;AAC3B,MAAI,IAAI,KAAM,QAAO,EAAE,UAAU,KAAK,KAAK,GAAG,SAAS,EAAE;AACzD,MAAI,UAAU,KAAK,MAAM,IAAI,EAAE;AAC/B,MAAI,UAAU,EAAG,YAAW,IAAI,KAAK;AACrC,SAAO,EAAE,UAAU,KAAK,KAAK,IAAI,CAAC,GAAG,QAAQ;AAC/C;AAEA,IAAM,aAAa,CAAC,MAAiB,OAAO,EAAE,aAAa,YAAY,OAAO,SAAS,EAAE,QAAQ,IAAI,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,EAAE,QAAQ,CAAC,IAAI;AAMrI,IAAM,cAAN,MAAkB;AAAA,EACf,MAAuC;AAAA,EACvC,WAA0B;AAAA,EACjB;AAAA,EACA;AAAA,EAEjB,YAAY,UAAkB,UAAkB;AAC9C,SAAK,IAAI,IAAI,KAAK,IAAI,MAAM,KAAK,IAAI,GAAG,QAAQ,CAAC;AACjD,SAAK,KAAK,IAAI,KAAK,IAAI,MAAM,KAAK,IAAI,GAAG,QAAQ,CAAC;AAAA,EACpD;AAAA,EAEA,KAAK,GAAuB;AAC1B,UAAM,KAAK,WAAW,CAAC;AACvB,QAAI,CAAC,KAAK,KAAK;AACb,WAAK,MAAM,EAAE,GAAG,EAAE,GAAG,GAAG,EAAE,EAAE;AAC5B,WAAK,WAAW;AAChB,aAAO;AAAA,IACT;AACA,SAAK,MAAM,EAAE,GAAG,KAAK,IAAI,KAAK,EAAE,IAAI,KAAK,IAAI,KAAK,KAAK,GAAG,GAAG,KAAK,IAAI,KAAK,EAAE,IAAI,KAAK,IAAI,KAAK,KAAK,EAAE;AACtG,SAAK,WAAW,KAAK,YAAa,KAAK,KAAK,YAAa,KAAK;AAC9D,WAAO,EAAE,GAAG,GAAG,GAAG,KAAK,IAAI,GAAG,GAAG,KAAK,IAAI,GAAG,UAAU,KAAK,SAAS;AAAA,EACvE;AAAA;AAAA,EAGA,IAAI,WAA4C;AAC9C,WAAO,KAAK;AAAA,EACd;AACF;AAWO,IAAM,gBAA4B,EAAE,KAAK,CAAC,MAAM,GAAG,QAAQ,CAAC,GAAG,GAAG,GAAG,CAAC,EAAE;AAyB/E,IAAM,aAAa;AAMZ,IAAM,eAAN,MAAmB;AAAA,EASxB,YACW,OACQ,OAAO,GACP,SAAkB,CAAC,GAAG,GAAG,GAAG,CAAC,GAC9C;AAHS;AACQ;AACA;AAAA,EAChB;AAAA,EAHQ;AAAA,EACQ;AAAA,EACA;AAAA,EAXX,OAAsB;AAAA,EACtB,SAAS;AAAA,EACT,eAA8B;AAAA,EAC9B,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,QAAuB;AAAA,EACvB,QAAuB;AAAA,EAQvB,OAAO,GAAqB;AAClC,UAAM,IAAI,eAAe,CAAC;AAC1B,QAAI,QAAuB;AAC3B,QAAI,OAAO,EAAE,MAAM,YAAY,OAAO,SAAS,EAAE,CAAC,GAAG;AACnD,UAAI,KAAK,QAAQ,KAAK,UAAU,QAAQ,EAAE,IAAI,KAAK,OAAO;AACxD,cAAM,IAAI,KAAK,MAAM,EAAE,IAAI,KAAK,KAAK,GAAG,EAAE,IAAI,KAAK,KAAK,CAAC,KAAK,EAAE,IAAI,KAAK;AACzE,aAAK,QAAQ,KAAK,UAAU,OAAO,IAAI,KAAK,SAAS,IAAI,KAAK,SAAS;AAAA,MACzE;AACA,WAAK,QAAQ,EAAE;AACf,cAAQ,KAAK,SAAS;AAAA,IACxB;AACA,WAAO;AAAA,MACL,GAAG,EAAE;AAAA,MACL,GAAG,EAAE;AAAA,MACL,UAAU,WAAW,CAAC;AAAA,MACtB,MAAM,IAAI,IAAI,EAAE,YAAY,KAAK,KAAK,KAAK;AAAA,MAC3C,SAAS,IAAI,EAAE,UAAU;AAAA,MACzB,OAAO,OAAO,EAAE,UAAU,YAAY,OAAO,SAAS,EAAE,KAAK,IAAI,EAAE,QAAQ;AAAA,MAC3E;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,SAAS,GAAmB;AAClC,UAAM,MAAM,KAAK,MAAM;AACvB,UAAM,MAAM,KAAK,MAAM;AACvB,QAAI,IAAI,IAAI;AACZ,QAAI,IAAI,aAAc,MAAK,IAAI,WAAW,IAAI,IAAI,WAAW,EAAE;AAC/D,SAAK,IAAI,IAAI,WAAW,EAAE,OAAO;AACjC,QAAI,EAAE,UAAU,QAAQ,IAAI,aAAc,MAAK,KAAK,IAAI,MAAM,IAAI,IAAI,eAAe,KAAK,IAAI,GAAG,EAAE,QAAQ,UAAU,KAAK,IAAI,eAAe,IAAI,OAAO,EAAE;AAC1J,WAAO;AAAA,EACT;AAAA,EAEQ,QAAQ,GAAmB;AACjC,WAAO,KAAK,IAAI,KAAK,KAAK,IAAI,GAAG,KAAK,SAAS,CAAC,CAAC,IAAI,KAAK,IAAI,MAAM,KAAK,MAAM,IAAI,OAAO,CAAC;AAAA,EAC7F;AAAA;AAAA,EAGQ,SAAS,OAAuB;AACtC,UAAM,CAAC,GAAG,GAAG,GAAG,CAAC,IAAI,KAAK;AAC1B,QAAI,MAAM,KAAK,MAAM,KAAK,MAAM,KAAK,MAAM,EAAG,QAAO;AACrD,UAAM,KAAK,KAAK,IAAI,KAAK;AACzB,UAAM,KAAK,CAAC,KAAK,IAAI,KAAK;AAC1B,WAAO,KAAK,MAAM,EAAE,IAAI,KAAK,IAAI,KAAK,IAAI,KAAK,IAAI,EAAE;AAAA,EACvD;AAAA,EAEQ,IAAI,GAAmB;AAC7B,UAAM,EAAE,KAAK,UAAU,KAAK,SAAS,IAAI,KAAK;AAC9C,UAAM,IAAI,KAAK;AACf,UAAM,OAAO,KAAK;AAClB,QAAI,WAAW,KAAK,SAAS,CAAC;AAC9B,QAAI,IAAI,WAAY,aAAY,KAAK,IAAI,MAAM,IAAI,IAAI,aAAa,WAAW,MAAM,GAAG,YAAW,CAAC;AACpG,UAAM,OAAQ,IAAI,QAAQ,KAAK,KAAM;AACrC,QAAI;AACJ,QAAI,aAAa,SAAU,SAAQ,KAAK,MAAM;AAAA,aACrC,aAAa,YAAY,EAAE,UAAU,KAAM,SAAQ,KAAK,SAAS,OAAQ,EAAE,QAAQ,KAAK,KAAM,GAAG;AAAA,aACjG,IAAI,gBAAgB,KAAK,EAAE,OAAO,KAAM,SAAQ,KAAK,SAAS,OAAO,EAAE,OAAO;AAAA,QAClF,SAAQ,KAAK,SAAS,IAAI;AAC/B,QAAI,IAAI,YAAa,UAAS,IAAI,cAAc,KAAK,KAAK,WAAW,MAAM,GAAG,aAAY;AAC1F,QAAI,UAAU,IAAI,kBAAkB,EAAE,WAAW;AACjD,eAAW,IAAI,IAAI,cAAc,EAAE,OAAO;AAC1C,QAAI,EAAE,UAAU,QAAQ,IAAI,gBAAiB,YAAW,KAAK,IAAI,GAAG,IAAI,IAAI,mBAAmB,KAAK,IAAI,GAAG,EAAE,QAAQ,UAAU,IAAI,IAAI;AACvI,QAAI,IAAI,cAAe,YAAW,IAAI,IAAI,iBAAiB,WAAW,MAAM,GAAG,eAAc,IAAI,MAAM;AACvG,UAAM,OAAO,IAAI,QAAQ,IAAI,IAAI,eAAe,IAAI,eAAe,EAAE;AACrE,QAAI,EAAE,GAAG,EAAE,IAAI;AACf,QAAI,IAAI,SAAS;AACf,YAAM,MAAM,IAAI,UAAU,WAAW,WAAW,MAAM,GAAG,eAAc;AAEvE,WAAK,KAAK,IAAI,KAAK,GAAG,IAAI;AAC1B,WAAK,KAAK,IAAI,KAAK,GAAG,IAAI;AAAA,IAC5B;AACA,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA,QAAQ,KAAK,IAAI,KAAK,WAAW,CAAC;AAAA,MAClC,OAAO,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,IAAI,CAAC;AAAA,MACpC,SAAS,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,OAAO,CAAC;AAAA,MACzC;AAAA,MACA,WAAW,KAAK,IAAI,GAAG,KAAK,IAAI,MAAM,IAAI,aAAa,IAAI,IAAI,gBAAgB,EAAE,OAAO,IAAI,CAAC;AAAA,MAC7F,UAAU,EAAE;AAAA,IACd;AAAA,EACF;AAAA,EAEA,KAAK,GAAa,KAAqB;AACrC,UAAM,IAAI,KAAK;AACf,UAAM,IAAI,KAAK,OAAO,CAAC;AACvB,QAAI,CAAC,GAAG;AACN,WAAK,OAAO;AACZ,WAAK,eAAe;AACpB,WAAK,SAAS,KAAK,QAAQ,CAAC;AAC5B;AAAA,IACF;AACA,UAAM,KAAK,EAAE,IAAI,EAAE;AACnB,UAAM,KAAK,EAAE,IAAI,EAAE;AACnB,UAAM,MAAM,KAAK,MAAM,IAAI,EAAE;AAC7B,QAAI,MAAM,KAAM,MAAK,MAAM,KAAK,MAAM,CAAC,IAAI,EAAE;AAC7C,QAAI,KAAK,cAAc;AACrB,UAAI,KAAK,KAAK,IAAI,KAAK,YAAY,CAAC;AACpC,WAAK,eAAe;AAAA,IACtB;AACA,QAAI,MAAM,MAAM;AACd,aAAO,KAAK,UAAU,MAAM,MAAM;AAChC,cAAM,IAAI,KAAK,IAAI,GAAG,KAAK,SAAS,GAAG;AACvC,cAAM,OAAO,CAAC,GAAW,MAAc,KAAK,IAAI,KAAK;AACrD,cAAM,IAAY;AAAA,UAChB,GAAG,EAAE,IAAI,KAAK;AAAA,UACd,GAAG,EAAE,IAAI,KAAK;AAAA,UACd,UAAU,KAAK,EAAE,UAAU,EAAE,QAAQ;AAAA,UACrC,MAAM,KAAK,EAAE,MAAM,EAAE,IAAI;AAAA,UACzB,SAAS,UAAU,EAAE,SAAS,EAAE,SAAS,CAAC;AAAA,UAC1C,OAAO,EAAE,UAAU,QAAQ,EAAE,UAAU,OAAO,YAAY,EAAE,OAAO,EAAE,OAAO,CAAC,IAAI,EAAE;AAAA,UACnF,OAAO,EAAE,UAAU,QAAQ,EAAE,UAAU,OAAO,KAAK,EAAE,OAAO,EAAE,KAAK,IAAI,EAAE;AAAA,QAC3E;AACA,YAAI,KAAK,KAAK,IAAI,CAAC,CAAC;AACpB,aAAK,UAAU,KAAK,QAAQ,CAAC;AAAA,MAC/B;AACA,WAAK,UAAU;AAAA,IACjB;AACA,SAAK,OAAO;AAAA,EACd;AAAA,EAEA,OAAO,KAAqB;AAC1B,QAAI,KAAK,cAAc;AACrB,UAAI,KAAK,KAAK,IAAI,KAAK,YAAY,CAAC;AACpC,WAAK,eAAe;AAAA,IACtB;AAAA,EACF;AACF;AAEA,SAAS,UAAU,GAAW,GAAW,GAAmB;AAC1D,MAAI,IAAI,IAAI;AACZ,SAAO,IAAI,KAAK,GAAI,MAAK,IAAI,KAAK;AAClC,SAAO,IAAI,CAAC,KAAK,GAAI,MAAK,IAAI,KAAK;AACnC,SAAO,IAAI,IAAI;AACjB;AAEA,SAAS,YAAY,GAAW,GAAW,GAAmB;AAC5D,MAAI,IAAI,IAAI;AACZ,SAAO,IAAI,IAAK,MAAK;AACrB,SAAO,IAAI,KAAM,MAAK;AACtB,SAAO,IAAI,IAAI;AACjB;AAiBO,IAAM,YAAN,MAAgB;AAAA,EAWrB,YAAqB,OAAoC,SAA2B;AAA/D;AAAoC;AACvD,SAAK,WAAW,IAAI,YAAY,MAAM,IAAI,WAAW,MAAM,iBAAiB;AAC5E,SAAK,SAAS,QAAQ,QAAQ,SAAS,QAAQ,SAAS,CAAC,aAAa;AACtE,SAAK,UAAU,KAAK,OAAO,IAAI,CAAC,GAAG,MAAM,IAAI,aAAa,QAAS,QAAQ,QAAQ,KAAK,IAAI,OAAQ,GAAG,EAAE,MAAM,CAAC;AAChH,SAAK,QAAQ,QAAQ,SAAS,CAAC,QAAQ,MAAM,OAAO,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,QAAQ,aAAa,MAAM,KAAK,CAAC,IAAI;AAAA,EACnH;AAAA,EALqB;AAAA,EAAoC;AAAA,EAVhD,WAAW,IAAI,YAAY;AAAA,EACpC,WAAW;AAAA,EACM;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACT,MAAM,IAAI,aAAa,CAAC;AAAA,EACxB,UAA2B;AAAA,EAC3B,UAA2B;AAAA;AAAA,EAUnC,KAAK,QAA2C;AAC9C,UAAM,OAAiB,CAAC;AACxB,eAAW,OAAO,QAAQ;AACxB,WAAK,UAAU;AACf,YAAM,IAAI,KAAK,SAAS,KAAK,GAAG;AAChC,WAAK,UAAU;AACf,WAAK,OAAO,QAAQ,CAAC,GAAG,MAAM,KAAK,QAAQ,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,GAAG,IAAI,CAAC;AAAA,IACpE;AACA,WAAO,KAAK,MAAM,IAAI;AAAA,EACxB;AAAA;AAAA,EAGA,SAAuB;AACrB,UAAM,OAAiB,CAAC;AACxB,UAAM,MAAM,KAAK;AACjB,UAAM,MAAM,KAAK;AACjB,QAAI,OAAO,QAAQ,IAAI,MAAM,IAAI,KAAK,IAAI,MAAM,IAAI,GAAI,MAAK,OAAO,QAAQ,CAAC,GAAG,MAAM,KAAK,QAAQ,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,KAAK,UAAU,IAAI,SAAS,CAAC,GAAG,IAAI,CAAC;AAC3J,eAAW,KAAK,KAAK,QAAS,GAAE,OAAO,IAAI;AAC3C,WAAO,KAAK,MAAM,IAAI;AAAA,EACxB;AAAA,EAEQ,MAAM,MAA8B;AAC1C,UAAM,QAAsB,CAAC;AAC7B,UAAM,WAAW,KAAK,MAAM,IAAI;AAChC,UAAM,QAAQ,KAAK,QAAQ;AAC3B,eAAW,KAAK,MAAM;AACpB,YAAM,OAAO,QAAQ,GAAG,QAAQ;AAChC,YAAM,IAAI,KAAK,QAAQ,KAAK;AAC5B,UAAI,KAAK,IAAI,SAAS,EAAG,MAAK,MAAM,IAAI,aAAa,CAAC;AACtD,YAAM,OAAO,KAAK,IAAI,SAAS,GAAG,CAAC;AACnC,mBAAa,GAAG,UAAU,MAAM,IAAI;AACpC,UAAI,KAAK,QAAQ,KAAK,OAAO;AAC3B,iBAAS,KAAK,GAAG,IAAI,GAAG,KAAK,KAAK,QAAQ,MAAM;AAC9C,gBAAM,IAAI,KAAK,IAAI,KAAK;AACxB,mBAAS,KAAK,GAAG,KAAK,KAAK,OAAO,MAAM,KAAK;AAC3C,gBAAI,KAAK,CAAC,IAAI,EAAG,MAAK,CAAC,KAAK,WAAW,MAAM,GAAG,KAAK,IAAI,KAAK,KAAK,CAAC,GAAG,KAAK,OAAO,EAAE,QAAQ;AAAA,UAC/F;AAAA,QACF;AAAA,MACF;AACA,WAAK,SAAS,WAAW,MAAM,MAAM,EAAE,OAAO;AAC9C,YAAM,KAAK,IAAI;AACf,WAAK;AAAA,IACP;AACA,WAAO;AAAA,EACT;AACF;AAGO,SAAS,SAAS,OAAkC;AACzD,SAAO,EAAE,GAAG,MAAM,KAAK,WAAW,GAAG,cAAc,MAAM,IAAI,aAAa;AAC5E;AAGO,SAAS,cAAc,GAA0B;AACtD,SAAO,EAAE,GAAG,EAAE,GAAG,GAAG,EAAE,GAAG,UAAU,WAAW,CAAC,GAAG,GAAI,OAAO,EAAE,MAAM,WAAW,EAAE,GAAG,EAAE,EAAE,IAAI,CAAC,EAAG;AACnG;;;ACvUA,SAAS,YAAY,SAA0C;AAC7D,QAAM,OAAO,IAAI,kBAAkB,OAAO,OAAO,QAAQ,QAAQ;AACjE,MAAI,QAAQ,aAAc,MAAK,KAAK,QAAQ,YAAY;AACxD,SAAO;AACT;AAEA,SAAS,SAAS,GAAqB,GAAyB;AAC9D,MAAI,CAAC,KAAK,CAAC,EAAG,QAAO,CAAC,KAAK,CAAC;AAC5B,MAAI,MAAM,EAAG,QAAO;AACpB,MAAI,EAAE,YAAY,QAAQ,EAAE,YAAY,KAAM,QAAO,EAAE,YAAY,EAAE;AACrE,WAAS,IAAI,GAAG,IAAI,EAAE,KAAK,QAAQ,IAAK,KAAI,EAAE,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,EAAG,QAAO;AAC5E,SAAO;AACT;AAEA,SAAS,MAAM,GAAsB,GAA2B;AAC9D,MAAI,CAAC,EAAG,QAAO,EAAE,GAAG,EAAE;AACtB,QAAM,IAAI,KAAK,IAAI,EAAE,GAAG,EAAE,CAAC;AAC3B,QAAM,IAAI,KAAK,IAAI,EAAE,GAAG,EAAE,CAAC;AAC3B,SAAO,EAAE,GAAG,GAAG,OAAO,KAAK,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,IAAI,GAAG,QAAQ,KAAK,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,IAAI,EAAE;AACzH;AAEO,IAAM,qBAAN,MAAyB;AAAA,EAkB9B,YAA6B,MAAkC,MAAyB;AAA3D;AAAkC;AAC7D,SAAK,UAAU,KAAK;AACpB,SAAK,OAAO,KAAK;AACjB,SAAK,OAAO,IAAI,IAAI,KAAK,KAAK,KAAK;AACnC,SAAK,SAAS,KAAK,OAAO,SAAS,KAAK,SAAS,CAAC,aAAa;AAC/D,UAAM,QAAQ,KAAK;AACnB,SAAK,QAAQ;AAAA,MACX,MAAM,MAAM,WAAW,WAAW,UAAU;AAAA,MAC5C,OAAO,KAAK;AAAA,MACZ,YAAY,KAAK;AAAA,MACjB,SAAS,MAAM,IAAI;AAAA,MACnB,OAAO,MAAM,IAAI;AAAA,MACjB,kBAAkB,KAAK;AAAA,MACvB,WAAW;AAAA,MACX,QAAQ,KAAK;AAAA,IACf;AACA,QAAI,MAAM,WAAW,SAAS;AAC5B,WAAK,gBAAgB,IAAI,YAAY,MAAM,IAAI,WAAW,MAAM,iBAAiB;AACjF,YAAM,OAAO,KAAK;AAClB,eAAS,IAAI,GAAG,IAAI,KAAK,OAAO,QAAQ,IAAK,MAAK,OAAO,KAAK,IAAI,YAAY,SAAS,KAAK,GAAG,MAAM,OAAO,MAAM,KAAK,YAAY,CAAC,CAAC;AAAA,IACvI,OAAO;AACL,WAAK,MAAM,IAAI,UAAU,OAAO,EAAE,OAAO,KAAK,OAAO,YAAY,KAAK,YAAY,MAAM,KAAK,MAAM,QAAQ,KAAK,OAAO,CAAC;AAAA,IAC1H;AAAA,EACF;AAAA,EAvB6B;AAAA,EAAkC;AAAA,EAjBtD;AAAA;AAAA,EAEA,SAAqB,CAAC;AAAA,EACd;AAAA,EACA;AAAA,EACA,UAAU,oBAAI,IAAa;AAAA,EAC3B,QAAQ,oBAAI,IAAa;AAAA,EACzB,MAAwB;AAAA,EACxB,SAAwB,CAAC;AAAA,EACzB,gBAAoC;AAAA,EACpC;AAAA,EACA;AAAA,EACT,SAA4B;AAAA,EAC5B,UAA2B;AAAA,EAC3B,SAAS;AAAA,EACjB,SAAmC;AAAA,EA2B3B,cAA2B;AACjC,WAAO;AAAA,MACL,QAAQ,KAAK,KAAK;AAAA,MAClB,kBAAkB,KAAK,KAAK;AAAA,MAC5B,WAAW;AAAA,MACX,UAAU,CAAC,IAAI,OAAO,KAAK,KAAK,IAAI,QAAQ,IAAI,EAAE,CAAC,GAAG,QAAQ;AAAA,MAC9D,WAAW,CAAC,IAAI,OAAO;AACrB,cAAM,MAAM,QAAQ,IAAI,EAAE;AAC1B,YAAI,CAAC,KAAK,QAAQ,IAAI,GAAG,GAAG;AAC1B,gBAAM,MAAM,KAAK,KAAK,MAAM,IAAI,GAAG,GAAG,QAAQ,YAAY,KAAK,IAAI;AACnE,eAAK,KAAK,IAAI,KAAK,EAAE,MAAM,IAAI,kBAAkB,GAAG,GAAG,SAAS,KAAK,CAAC;AACtE,eAAK,QAAQ,IAAI,GAAG;AAAA,QACtB;AACA,aAAK,MAAM,IAAI,GAAG;AAClB,eAAO,KAAK,KAAK,IAAI,GAAG,EAAG;AAAA,MAC7B;AAAA,IACF;AAAA,EACF;AAAA,EAEA,IAAI,OAAgB;AAClB,WAAO,CAAC,KAAK;AAAA,EACf;AAAA;AAAA,EAGA,KAAK,QAAmC;AACtC,QAAI,KAAK,UAAU,CAAC,OAAO,OAAQ;AACnC,UAAM,SAAS,KAAK,KAAK;AACzB,QAAI,OAAQ,UAAS,OAAO,IAAI,MAAM;AACtC,eAAW,KAAK,OAAQ,MAAK,OAAO,KAAK,CAAC;AAC1C,SAAK,UAAU,OAAO,OAAO,SAAS,CAAC;AACvC,QAAI,KAAK,IAAK,MAAK,OAAO,KAAK,IAAI,KAAK,MAAM,CAAC;AAAA,SAC1C;AACH,YAAM,QAAsB,CAAC;AAC7B,iBAAW,OAAO,QAAQ;AACxB,cAAM,IAAI,cAAc,KAAK,cAAe,KAAK,GAAG,CAAC;AACrD,aAAK,OAAO,QAAQ,CAAC,GAAG,MAAM,MAAM,KAAK,GAAG,KAAK,OAAO,CAAC,EAAE,KAAK,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAAA,MAC7F;AACA,WAAK,OAAO,KAAK;AAAA,IACnB;AAAA,EACF;AAAA,EAEQ,OAAO,OAA2B;AACxC,QAAI,CAAC,MAAM,OAAQ;AACnB,eAAW,KAAK,MAAO,MAAK,SAAS,MAAM,KAAK,QAAQ,CAAC;AACzD,UAAM,KAAK,KAAK,KAAK;AACrB,QAAI,CAAC,KAAK,KAAK;AACb,iBAAW,OAAO,KAAK,MAAO,MAAK,KAAK,IAAI,KAAK,EAAE,MAAM,KAAK,KAAK,IAAI,GAAG,EAAG,MAAM,SAAS,KAAK,CAAC;AAClG,WAAK,MAAM,MAAM;AACjB,WAAK,KAAK,OAAO,KAAK,SAAS,IAAI,aAAa,IAAI,IAAI,IAAI,KAAK,IAAI,GAAG,KAAK,KAAK,YAAY,GAAG,KAAK;AACtG;AAAA,IACF;AACA,UAAM,MAAM,KAAK,KAAK;AACtB,UAAM,UAAU,oBAAI,IAAwD;AAC5E,eAAW,KAAK,OAAO;AACrB,iBAAW,KAAK,YAAY,EAAE,GAAG,EAAE,IAAI,IAAI,GAAG,GAAG,EAAE,IAAI,IAAI,GAAG,OAAO,EAAE,OAAO,QAAQ,EAAE,OAAO,CAAC,GAAG;AACjG,cAAM,MAAM,QAAQ,EAAE,IAAI,EAAE,EAAE;AAC9B,cAAM,MAAM,QAAQ,IAAI,GAAG;AAC3B,gBAAQ,IAAI,KAAK,EAAE,IAAI,EAAE,IAAI,IAAI,EAAE,IAAI,GAAG,MAAM,MAAM,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC;AAAA,MACvE;AAAA,IACF;AACA,eAAW,CAAC,KAAK,EAAE,IAAI,IAAI,EAAE,CAAC,KAAK,SAAS;AAC1C,YAAM,MAAM,KAAK,KAAK,MAAM,IAAI,GAAG,GAAG,QAAQ,YAAY,KAAK,IAAI;AACnE,YAAM,OAAO,KAAK,QAAQ,IAAI,GAAG,IAAI,KAAK,KAAK,IAAI,GAAG,GAAG,OAAO;AAChE,WAAK,QAAQ,IAAI,GAAG;AACpB,YAAM,OAAO,kBAAkB,KAAK,IAAI,UAAU,KAAK,IAAI,IAAI,IAAI,KAAK,OAAO,OAAO,EAAE,MAAM,MAAM,QAAQ,EAAE,IAAI,CAAC,CAAC;AACpH,WAAK,KAAK,IAAI,KAAK,EAAE,MAAM,SAAS,KAAK,CAAC;AAAA,IAC5C;AACA,SAAK,KAAK,OAAO,KAAK,SAAS,IAAI,aAAa,IAAI,IAAI,IAAI,KAAK,IAAI,GAAG,KAAK,KAAK,YAAY,GAAG,KAAK;AAAA,EACxG;AAAA;AAAA,EAGA,MAAyB;AACvB,QAAI,KAAK,OAAQ,OAAM,IAAI,MAAM,gCAAgC;AACjE,QAAI,KAAK,IAAK,MAAK,OAAO,KAAK,IAAI,OAAO,CAAC;AAAA,SACtC;AACH,YAAM,QAAsB,CAAC;AAC7B,YAAM,OAAO,KAAK,UAAU,cAAc,KAAK,OAAO,IAAI;AAC1D,WAAK,OAAO,QAAQ,CAAC,GAAG,MAAM,MAAM,KAAK,GAAG,KAAK,OAAO,CAAC,EAAE,OAAO,OAAO,cAAc,EAAE,IAAI,IAAI,CAAC,IAAI,MAAS,CAAC,CAAC;AACjH,WAAK,OAAO,KAAK;AAAA,IACnB;AACA,SAAK,SAAS;AACd,UAAM,KAAK,KAAK,KAAK;AACrB,UAAM,QAAQ,IAAI,IAAI,KAAK,KAAK,KAAK;AACrC,QAAI,UAAU;AACd,eAAW,OAAO,KAAK,SAAS;AAC9B,YAAM,OAAO,WAAW,KAAK,KAAK,IAAI,GAAG,EAAG,MAAM,IAAI,KAAK,KAAK,YAAY;AAC5E,YAAM,OAAO,KAAK,KAAK,MAAM,IAAI,GAAG;AACpC,UAAI,KAAM,OAAM,IAAI,KAAK,IAAI;AAAA,UACxB,OAAM,OAAO,GAAG;AACrB,UAAI,CAAC,SAAS,MAAM,IAAI,EAAG,WAAU;AAAA,IACvC;AACA,UAAM,UAAU,UAAU,IAAI,aAAa,IAAI,OAAO,KAAK,KAAK,YAAY,IAAI;AAChF,UAAM,OAAO,KAAK,MAAM,KAAK,IAAI,WAAW,KAAK,OAAO,OAAO,CAAC,GAAG,MAAM,IAAI,EAAE,UAAU,CAAC;AAC1F,SAAK,SAAS,EAAE,SAAS,KAAK,SAAS,QAAQ,UAAU,KAAK,SAAS,MAAM,MAAM,UAAU,KAAK;AAClG,QAAI,KAAK,OAAO,QAAQ;AACtB,YAAM,QAAQ,KAAK,KAAK;AACxB,UAAI,OAAO,KAAK,OAAO,CAAC,EAAE;AAC1B,UAAI,MAAM,MAAM,gBAAiB,QAAO,WAAW,IAAI;AACvD,WAAK,OAAO,YAAY;AAAA,IAC1B;AACA,SAAK,KAAK,OAAO,MAAM,SAAS,KAAK;AACrC,WAAO,KAAK;AAAA,EACd;AAAA;AAAA,EAGA,SAAe;AACb,QAAI,KAAK,OAAQ;AACjB,SAAK,SAAS;AACd,SAAK,KAAK,OAAO,MAAM,MAAM,IAAI;AAAA,EACnC;AACF;AAGO,SAAS,mBAAmB,OAAmB,SAAoB,OAAqD;AAC7H,MAAI,CAAC,MAAM,WAAY,QAAO,EAAE,WAAW,MAAM,QAAQ,GAAG,QAAQ,MAAM,MAAM,kBAAkB,OAAO,QAAQ,OAAO;AACxH,MAAI,MAAM,MAAM,kBAAkB,CAAC,QAAQ,UAAW,QAAO,UAAU,SAAS,KAAK;AACrF,SAAO;AACT;;;ACtOO,IAAM,kBAA0B,CAAC,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AAejD,SAAS,YAAY,GAAW,GAAW,GAAqC;AACrF,SAAO,EAAE,GAAG,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC,EAAE;AACxE;AAGO,SAAS,cAAc,GAAW,GAAmB;AAC1D,SAAO;AAAA,IACL,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC;AAAA,IACxB,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC;AAAA,IACxB,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC;AAAA,IACxB,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC;AAAA,IACxB,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC;AAAA,IAC/B,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC;AAAA,EACjC;AACF;AAEO,SAAS,aAAa,GAAmB;AAC9C,QAAM,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC;AACpC,MAAI,KAAK,IAAI,GAAG,IAAI,MAAO,OAAM,IAAI,MAAM,6CAA6C;AACxF,QAAM,IAAI,EAAE,CAAC,IAAI;AACjB,QAAM,IAAI,CAAC,EAAE,CAAC,IAAI;AAClB,QAAM,IAAI,CAAC,EAAE,CAAC,IAAI;AAClB,QAAM,IAAI,EAAE,CAAC,IAAI;AACjB,SAAO,CAAC,GAAG,GAAG,GAAG,GAAG,EAAE,IAAI,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC,EAAE;AACpE;AAGO,SAAS,YAAY,GAAW,GAAuB;AAC5D,QAAM,IAAI,YAAY,GAAG,EAAE,GAAG,EAAE,CAAC;AACjC,SAAO,EAAE,GAAG,GAAG,GAAG,EAAE,GAAG,GAAG,EAAE,EAAE;AAChC;AAGO,SAAS,WAAW,GAAuB;AAChD,QAAM,SAAkB,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC;AAC/C,SAAO,EAAE,KAAK,CAAC,MAAM,YAAY,GAAG,CAAC,GAAG,OAAO;AACjD;AAEA,IAAM,SAAS,CAAC,MAA4B,OAAO,MAAM,YAAY,OAAO,SAAS,CAAC;AAEtF,SAAS,UAAU,KAA+B;AAChD,MAAI,CAAC,OAAO,OAAO,QAAQ,SAAU,QAAO;AAC5C,QAAM,IAAI;AACV,MAAI,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,EAAG,QAAO;AACzC,QAAM,IAAc,EAAE,GAAG,EAAE,GAAG,GAAG,EAAE,EAAE;AACrC,aAAW,KAAK,CAAC,YAAY,KAAK,SAAS,SAAS,YAAY,WAAW,OAAO,EAAY,KAAI,OAAO,EAAE,CAAC,CAAC,EAAG,GAAE,CAAC,IAAI,EAAE,CAAC;AAC1H,SAAO;AACT;AAEA,SAAS,WAAW,KAA6B;AAC/C,SAAO,MAAM,QAAQ,GAAG,KAAK,IAAI,WAAW,KAAK,IAAI,MAAM,MAAM,IAAK,MAA4B;AACpG;AAGO,SAAS,qBAAqB,KAAqC;AACxE,MAAI,CAAC,OAAO,OAAO,QAAQ,SAAU,QAAO;AAC5C,QAAM,IAAI;AACV,MAAI,OAAO,EAAE,OAAO,YAAY,OAAO,EAAE,YAAY,YAAY,CAAC,MAAM,QAAQ,EAAE,MAAM,EAAG,QAAO;AAClG,QAAM,SAAS,EAAE,OAAO,IAAI,SAAS,EAAE,OAAO,CAAC,MAAqB,MAAM,IAAI;AAC9E,MAAI,CAAC,OAAO,OAAQ,QAAO;AAC3B,QAAM,MAAsB;AAAA,IAC1B,IAAI,EAAE;AAAA,IACN,SAAS,EAAE;AAAA,IACX,OAAO,oBAAqB,EAAE,SAA6B,CAAC,CAAC;AAAA,IAC7D,OAAO,OAAO,EAAE,UAAU,YAAY,kBAAkB,KAAK,EAAE,KAAK,IAAI,EAAE,MAAM,YAAY,IAAI;AAAA,IAChG;AAAA,IACA,MAAM,OAAO,EAAE,IAAI,IAAI,EAAE,OAAO,IAAI;AAAA,EACtC;AACA,QAAM,SAAS,MAAM,QAAQ,EAAE,MAAM,IAAI,EAAE,OAAO,IAAI,UAAU,EAAE,OAAO,CAAC,MAAmB,MAAM,IAAI,IAAI,CAAC;AAC5G,MAAI,OAAO,OAAQ,KAAI,SAAS;AAChC,SAAO;AACT;AAGO,SAAS,aAAa,QAAsF;AACjH,MAAI,KAAK;AACT,MAAI,KAAK;AACT,MAAI,KAAK;AACT,MAAI,KAAK;AACT,aAAW,KAAK,QAAQ;AACtB,QAAI,EAAE,IAAI,GAAI,MAAK,EAAE;AACrB,QAAI,EAAE,IAAI,GAAI,MAAK,EAAE;AACrB,QAAI,EAAE,IAAI,GAAI,MAAK,EAAE;AACrB,QAAI,EAAE,IAAI,GAAI,MAAK,EAAE;AAAA,EACvB;AACA,SAAO,EAAE,GAAG,IAAI,GAAG,IAAI,OAAO,KAAK,IAAI,QAAQ,KAAK,GAAG;AACzD;AAmBO,SAAS,gBAAgB,GAAoB,QAA0C;AAC5F,QAAM,IAAI,EAAE,SAAS;AACrB,QAAM,KAAM,EAAE,UAAU,KAAK,KAAK,KAAM;AACxC,QAAM,MAAM,KAAK,IAAI,CAAC,IAAI;AAC1B,QAAM,MAAM,KAAK,IAAI,CAAC,IAAI;AAC1B,QAAM,KAAK,EAAE,QAAQ,KAAK;AAE1B,QAAM,SAAiB,CAAC,MAAM,IAAI,CAAC,KAAK,MAAM,IAAI,KAAK,GAAG,CAAC;AAC3D,QAAM,WAAmB,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,OAAO,GAAG,CAAC,OAAO,CAAC;AAC1D,QAAM,OAAe,CAAC,GAAG,GAAG,GAAG,GAAG,OAAO,KAAK,EAAE,MAAM,IAAI,OAAO,KAAK,EAAE,MAAM,EAAE;AAChF,SAAO,cAAc,MAAM,cAAc,QAAQ,QAAQ,CAAC;AAC5D;AAGO,SAAS,WAAW,QAAwB,GAAW,GAAoC;AAChG,QAAM,IAAI,KAAK,KAAK,KAAK,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;AACvD,QAAM,KAAK,EAAE,iBAAiB;AAC9B,QAAM,SAAS,OAAO,OAAO,IAAI,CAAC,MAAM;AACtC,UAAM,IAAI,YAAY,GAAG,CAAC;AAC1B,QAAI,OAAO,EAAG,GAAE,WAAW,KAAK,IAAI,GAAG,KAAK,IAAI,IAAI,EAAE,YAAY,KAAK,EAAE,CAAC;AAC1E,WAAO;AAAA,EACT,CAAC;AACD,QAAM,QAAQ,MAAM,IAAI,oBAAoB,EAAE,GAAG,OAAO,OAAO,KAAK,EAAE,GAAG,OAAO,MAAM,KAAK,MAAM,OAAO,MAAM,IAAI,OAAO,EAAE,EAAE,CAAC,IAAI,OAAO;AACzI,QAAM,MAAsB,EAAE,GAAG,QAAQ,OAAO,OAAO;AACvD,MAAI,OAAO,QAAQ,QAAQ;AACzB,UAAM,MAAM,aAAa,CAAC;AAC1B,QAAI,SAAS,OAAO,OAAO,IAAI,CAAC,MAAM,cAAc,GAAG,cAAc,GAAG,GAAG,CAAC,CAAC;AAAA,EAC/E;AACA,SAAO;AACT;;;AC3HO,IAAM,gBAAgB;AACtB,IAAM,kBAAkB;AAExB,SAAS,SAAS,GAA0B;AACjD,SAAO,KAAK,UAAU,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,CAAC;AACzF;AAEA,IAAM,aAAa,oBAAI,QAAkC;AAGlD,SAAS,UAAU,OAAiC;AACzD,MAAI,IAAI,WAAW,IAAI,KAAK;AAC5B,MAAI,CAAC,GAAG;AACN,QAAI,EAAE,MAAM,SAAS,IAAI,eAAe,MAAM,SAAS,SAAS,MAAM,SAAS,GAAG,OAAO,UAAU,MAAM;AACzG,eAAW,IAAI,OAAO,CAAC;AAAA,EACzB;AACA,SAAO;AACT;AAEA,IAAM,aAAa,oBAAI,IAAwB;AAC/C,IAAM,YAAY,oBAAI,IAA+B;AAG9C,SAAS,WAAW,OAAkC;AAC3D,QAAM,MAAM,KAAK,UAAU,CAAC,MAAM,SAAS,MAAM,MAAM,MAAM,OAAO,MAAM,QAAQ,MAAM,GAAG,CAAC;AAC5F,MAAI,IAAI,WAAW,IAAI,GAAG;AAC1B,MAAI,CAAC,GAAG;AACN,QAAI,IAAI,WAAW,OAAO,KAAK;AAC/B,QAAI,WAAW,OAAO,GAAI,YAAW,OAAO,WAAW,KAAK,EAAE,KAAK,EAAE,KAAe;AACpF,eAAW,IAAI,KAAK,CAAC;AAAA,EACvB;AACA,SAAO;AACT;AAEA,SAAS,UAAU,OAAsB,GAAkC;AACzE,QAAM,MAAM,GAAG,SAAS,KAAK,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,KAAK,IAAI,EAAE,MAAM;AACnE,MAAI,IAAI,UAAU,IAAI,GAAG;AACzB,MAAI,CAAC,GAAG;AACN,QAAI,YAAY,OAAO,GAAG,WAAW,KAAK,CAAC;AAC3C,QAAI,UAAU,OAAO,IAAK,WAAU,OAAO,UAAU,KAAK,EAAE,KAAK,EAAE,KAAe;AAClF,cAAU,IAAI,KAAK,CAAC;AAAA,EACtB;AACA,SAAO;AACT;AAEA,IAAM,UAAuD;AAAA,EAC3D,YAAY,OAAO,GAAG;AACpB,QAAI,MAAM,SAAS,QAAS,QAAO,UAAW,MAAoB,OAAO,CAAC;AAC1E,QAAI,MAAM,SAAS,SAAS;AAC1B,YAAM,EAAE,MAAM,IAAI;AAClB,YAAM,MAAM,IAAI,kBAAkB,EAAE,QAAQ,EAAE,SAAS,CAAC;AACxD,YAAM,KAAK,KAAK,IAAI,GAAG,EAAE,CAAC;AAC1B,YAAM,KAAK,KAAK,IAAI,GAAG,EAAE,CAAC;AAC1B,YAAM,KAAK,KAAK,IAAI,MAAM,OAAO,EAAE,IAAI,EAAE,KAAK;AAC9C,YAAM,KAAK,KAAK,IAAI,MAAM,QAAQ,EAAE,IAAI,EAAE,MAAM;AAChD,UAAI,MAAM,MAAM,MAAM,GAAI,QAAO;AACjC,eAAS,IAAI,IAAI,IAAI,IAAI,IAAK,KAAI,IAAI,MAAM,KAAK,UAAU,IAAI,MAAM,QAAQ,MAAM,IAAI,IAAI,MAAM,QAAQ,MAAM,CAAC,KAAK,IAAI,EAAE,KAAK,EAAE,SAAS,KAAK,EAAE,MAAM,CAAC;AACzJ,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT;AAAA,EACA,SAAS,OAAO;AACd,QAAI,MAAM,SAAS,QAAS,QAAO,SAAU,MAAoB,KAAK;AACtE,QAAI,MAAM,SAAS,QAAS,QAAQ,MAAoB;AACxD,WAAO;AAAA,EACT;AACF;AAGO,SAAS,wBAAoE;AAClF,SAAO,IAAI,iBAA2C,OAAO;AAC/D;AAMO,SAAS,eAAe,MAAyB,OAAe,QAAgB,IAAY,IAA+B;AAChI,OAAK,KAAK,IAAI,GAAG,KAAK,MAAM,EAAE,CAAC;AAC/B,OAAK,KAAK,IAAI,GAAG,KAAK,MAAM,EAAE,CAAC;AAC/B,MAAI,MAAM,SAAS,MAAM,OAAQ,QAAO,kBAAkB,KAAK,IAAyB;AACxF,QAAM,MAAM,IAAI,kBAAkB,KAAK,KAAK,CAAC;AAC7C,QAAM,KAAK,QAAQ;AACnB,QAAM,KAAK,SAAS;AACpB,WAAS,IAAI,GAAG,IAAI,IAAI,KAAK;AAC3B,UAAM,KAAK,IAAI;AACf,UAAM,KAAK,KAAK;AAChB,aAAS,IAAI,GAAG,IAAI,IAAI,KAAK;AAC3B,YAAM,KAAK,IAAI;AACf,YAAM,KAAK,KAAK;AAChB,UAAI,IAAI;AACR,UAAI,IAAI;AACR,UAAI,IAAI;AACR,UAAI,IAAI;AACR,UAAI,IAAI;AACR,eAAS,KAAK,KAAK,MAAM,EAAE,GAAG,KAAK,KAAK,KAAK,EAAE,KAAK,KAAK,QAAQ,MAAM;AACrE,cAAM,KAAK,KAAK,IAAI,IAAI,KAAK,CAAC,IAAI,KAAK,IAAI,IAAI,EAAE;AACjD,iBAAS,KAAK,KAAK,MAAM,EAAE,GAAG,KAAK,KAAK,KAAK,EAAE,KAAK,KAAK,OAAO,MAAM;AACpE,gBAAM,MAAM,MAAM,KAAK,IAAI,IAAI,KAAK,CAAC,IAAI,KAAK,IAAI,IAAI,EAAE;AACxD,gBAAM,KAAK,KAAK,QAAQ,MAAM;AAC9B,gBAAM,KAAK,KAAK,IAAI,CAAC,IAAI;AACzB,eAAK,KAAK,CAAC,IAAI;AACf,eAAK,KAAK,IAAI,CAAC,IAAI;AACnB,eAAK,KAAK,IAAI,CAAC,IAAI;AACnB,eAAK;AACL,eAAK;AAAA,QACP;AAAA,MACF;AACA,YAAM,KAAK,IAAI,KAAK,KAAK;AACzB,UAAI,IAAI,GAAG;AACT,YAAI,CAAC,IAAI,IAAI;AACb,YAAI,IAAI,CAAC,IAAI,IAAI;AACjB,YAAI,IAAI,CAAC,IAAI,IAAI;AAAA,MACnB;AACA,UAAI,IAAI,CAAC,IAAI,IAAI,IAAI,IAAI,IAAI;AAAA,IAC/B;AAAA,EACF;AACA,SAAO;AACT;;;ACnIO,IAAM,eAAe;AACrB,IAAM,uBAAuB;AA8BpC,IAAM,QAAQ,oBAAI,IAAI,CAAC,UAAU,WAAW,SAAS,UAAU,OAAO,SAAS,UAAU,UAAU,iBAAiB,WAAW,UAAU,UAAU,CAAC;AAG7I,SAAS,mBAAmB,KAAuD;AACxF,QAAM,MAA+B,CAAC;AACtC,aAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,GAAG,EAAG,KAAI,CAAC,MAAM,IAAI,CAAC,EAAG,KAAI,CAAC,IAAI;AACtE,SAAO;AACT;AAYA,SAAS,OAAO,OAA2B,SAA+E;AACxH,QAAM,MAA0D;AAAA,IAC9D,GAAI,QAAQ,cAAc,CAAC;AAAA,IAC3B,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,OAAO,MAAM,OAAO;AAAA,IACpB,QAAQ,MAAM,OAAO;AAAA,IACrB,KAAK,MAAM,OAAO;AAAA,IAClB,OAAO,EAAE,GAAG,MAAM,OAAO,KAAK,EAAE,GAAG,MAAM,MAAM,IAAI,GAAG,KAAK,EAAE,GAAG,MAAM,MAAM,IAAI,EAAE;AAAA,IAClF,eAAe,MAAM;AAAA,EACvB;AACA,MAAI,QAAQ,YAAY,SAAS,MAAM,QAAQ,OAAQ,KAAI,UAAU,KAAK,MAAM,KAAK,UAAU,MAAM,OAAO,CAAC;AAC7G,MAAI,QAAQ,WAAW,OAAW,KAAI,SAAS,KAAK,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC;AACxF,MAAI,QAAQ,aAAa,OAAW,KAAI,WAAW,KAAK,MAAM,KAAK,UAAU,QAAQ,QAAQ,CAAC;AAC9F,SAAO;AACT;AAGO,SAAS,uBAAuB,OAA2B,UAA4B,CAAC,GAA4B;AACzH,QAAM,EAAE,QAAQ,OAAO,IAAI,gBAAgB,MAAM,MAAiC;AAClF,SAAO,EAAE,GAAG,OAAO,OAAO,OAAO,GAAG,QAAQ,OAAO;AACrD;AAGA,eAAsB,+BAA+B,OAA2B,OAAwB,UAA4B,CAAC,GAAqC;AACxK,QAAM,EAAE,QAAQ,OAAO,IAAI,MAAM,wBAAwB,MAAM,QAAmC,KAAK;AACvG,SAAO,EAAE,GAAG,OAAO,OAAO,OAAO,GAAG,QAAQ,OAAO;AACrD;AAaA,SAAS,gBAAgB,QAAsB,UAAkC;AAC/E,QAAM,MAAoB,CAAC;AAC3B,aAAW,KAAK,QAAQ;AACtB,QAAI,EAAE,SAAS,SAAS;AACtB,YAAM,EAAE,SAAS,QAAQ,GAAG,KAAK,IAAI;AACrC,UAAI,SAAS,OAAQ,UAAS,KAAK,UAAU,EAAE,IAAI,8DAA8D;AACjH,UAAI,OAAQ,UAAS,KAAK,UAAU,EAAE,IAAI,2DAA2D;AACrG,UAAI,KAAK,IAAkB;AAAA,IAC7B,WAAW,EAAE,SAAS,QAAS,KAAI,KAAK,EAAE,GAAG,GAAG,UAAU,gBAAgB,EAAE,UAAU,QAAQ,EAAE,CAAe;AAAA,QAC1G,UAAS,KAAK,UAAU,EAAE,IAAI,wBAAwB,EAAE,IAAI,gEAAgE;AAAA,EACnI;AACA,SAAO;AACT;AAEA,SAAS,YAAY,KAAc,UAAsC;AACvE,MAAI,CAAC,MAAM,QAAQ,GAAG,EAAG,QAAO,CAAC;AACjC,QAAM,MAAwB,CAAC;AAC/B,MAAI,QAAQ,CAAC,GAAG,MAAM;AACpB,UAAM,SAAS,qBAAqB,CAAC;AACrC,QAAI,OAAQ,KAAI,KAAK,MAAM;AAAA,QACtB,UAAS,KAAK,WAAW,CAAC,sCAAsC;AAAA,EACvE,CAAC;AACD,SAAO;AACT;AAGO,SAAS,yBAAyB,KAAmC;AAC1E,MAAI,CAAC,OAAO,OAAO,QAAQ,SAAU,OAAM,IAAI,MAAM,+CAA+C;AACpG,QAAM,IAAI;AACV,MAAI,EAAE,WAAW,aAAc,OAAM,IAAI,MAAM,mCAAmC,KAAK,UAAU,EAAE,MAAM,CAAC,eAAe,YAAY,IAAI;AACzI,MAAI,OAAO,EAAE,YAAY,YAAY,EAAE,UAAU,sBAAsB;AACrE,UAAM,IAAI,MAAM,0BAA0B,KAAK,UAAU,EAAE,OAAO,CAAC,qCAAqC,oBAAoB,6BAA6B;AAAA,EAC3J;AACA,QAAM,WAAqB,CAAC;AAC5B,QAAM,SAAS,gBAAgB,EAAE,OAAO,EAAE,OAAiB,QAAQ,EAAE,QAAkB,KAAM,EAAE,OAA8B,OAAU,CAAC;AACxI,QAAM,QAAQ,eAAgB,EAAE,SAAqC,CAAC,CAAC;AACvE,QAAM,SAAS,EAAE,UAAU,OAAO,EAAE,WAAW,WAAY,EAAE,SAAoC,CAAC;AAClG,QAAM,SAAS,gBAAgB,kBAAkB,EAAE,QAAQ,EAAE,QAAQ,SAAS,CAAC,GAAG,QAAQ;AAC1F,QAAM,SAAS,OAAO,EAAE,kBAAkB,WAAW,EAAE,gBAAgB;AACvE,QAAM,gBAAgB,UAAU,UAAU,QAAQ,MAAM,IAAI,SAAU,cAAc,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,SAAS,OAAO,EAAE,IAAI,GAAG,MAAM;AAC3I,SAAO,EAAE,OAAO,EAAE,QAAQ,OAAO,QAAQ,eAAe,SAAS,YAAY,EAAE,SAAS,QAAQ,EAAE,GAAG,YAAY,mBAAmB,CAAC,GAAG,QAAQ,EAAE,QAAQ,UAAU,EAAE,UAAU,SAAS;AAC3L;AAGA,eAAsB,8BAA8B,KAAc,OAAuD;AACvH,MAAI,CAAC,OAAO,OAAO,QAAQ,SAAU,OAAM,IAAI,MAAM,+CAA+C;AACpG,QAAM,IAAI;AACV,QAAM,WAAqB,CAAC;AAC5B,QAAM,SAAS,MAAM,sBAAuB,EAAE,UAAqC,CAAC,GAAG,OAAO,QAAQ;AACtG,QAAM,SAAS,yBAAyB,EAAE,GAAG,GAAG,OAAO,CAAC;AACxD,SAAO,EAAE,GAAG,QAAQ,UAAU,CAAC,GAAG,UAAU,GAAG,OAAO,QAAQ,EAAE;AAClE;;;ACnJO,IAAM,WAAW;AACjB,IAAM,WAAW;AAEjB,IAAM,eAAoC,EAAE,MAAM,GAAG,KAAK,EAAE,GAAG,GAAG,GAAG,EAAE,GAAG,UAAU,GAAG,QAAQ,MAAM;AAGrG,SAAS,kBAAkB,KAAqB;AACrD,MAAI,CAAC,OAAO,SAAS,GAAG,EAAG,QAAO;AAClC,MAAI,IAAI,MAAM;AACd,MAAI,IAAI,IAAK,MAAK;AAClB,MAAI,KAAK,KAAM,MAAK;AACpB,SAAO,KAAK,MAAM,IAAI,GAAI,IAAI;AAChC;AAEO,SAAS,cAAc,KAAyB,OAAkB,cAAyB;AAChG,QAAM,OAAO,OAAO,IAAI,SAAS,YAAY,OAAO,SAAS,IAAI,IAAI,IAAI,KAAK,IAAI,UAAU,KAAK,IAAI,UAAU,IAAI,IAAI,CAAC,IAAI,KAAK;AACjI,QAAM,MAAM,IAAI,OAAO,OAAO,SAAS,IAAI,IAAI,CAAC,KAAK,OAAO,SAAS,IAAI,IAAI,CAAC,IAAI,EAAE,GAAG,IAAI,IAAI,GAAG,GAAG,IAAI,IAAI,EAAE,IAAI,EAAE,GAAG,KAAK,IAAI;AACjI,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,UAAU,OAAO,IAAI,aAAa,WAAW,kBAAkB,IAAI,QAAQ,IAAI,KAAK;AAAA,IACpF,QAAQ,OAAO,IAAI,WAAW,YAAY,IAAI,SAAS,KAAK;AAAA,EAC9D;AACF;AAOO,SAAS,WAAW,MAAiB,QAA2C,UAAqD;AAC1I,QAAM,IAAK,KAAK,WAAW,KAAK,KAAM;AACtC,QAAM,IAAI,KAAK;AACf,QAAM,IAAI,KAAK,SAAS,KAAK;AAC7B,QAAM,MAAM,KAAK,IAAI,CAAC,IAAI;AAC1B,QAAM,MAAM,KAAK,IAAI,CAAC,IAAI;AAE1B,QAAM,KAAK,OAAO,QAAQ;AAC1B,QAAM,KAAK,OAAO,SAAS;AAC3B,QAAM,KAAK,SAAS,QAAQ,IAAI,KAAK,IAAI;AACzC,QAAM,KAAK,SAAS,SAAS,IAAI,KAAK,IAAI;AAC1C,QAAM,IAAI,MAAM;AAChB,QAAM,IAAI,CAAC;AACX,QAAM,IAAI,MAAM;AAChB,QAAM,IAAI;AACV,SAAO,CAAC,GAAG,GAAG,GAAG,GAAG,MAAM,IAAI,KAAK,IAAI,KAAK,MAAM,IAAI,KAAK,IAAI,GAAG;AACpE;AAGO,SAAS,iBAAiB,MAAiB,QAA2C,UAA6C,GAAW,GAAqC;AACxL,SAAO,YAAY,aAAa,WAAW,MAAM,QAAQ,QAAQ,CAAC,GAAG,GAAG,CAAC;AAC3E;AAGO,SAAS,iBAAiB,MAAiB,QAA2C,UAA6C,GAAW,GAAqC;AACxL,SAAO,YAAY,WAAW,MAAM,QAAQ,QAAQ,GAAG,GAAG,CAAC;AAC7D;AAGO,SAAS,iBAAiB,MAAiB,QAA2C,UAAqD;AAChJ,QAAM,IAAI,WAAW,MAAM,QAAQ,QAAQ;AAC3C,QAAM,IAAI,CAAC,MAAc,KAAK,MAAM,IAAI,GAAK,IAAI;AACjD,SAAO,UAAU,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC;AACtF;AAGO,SAAS,QAAQ,QAA2C,UAA6C,SAAS,IAAY;AACnI,QAAM,IAAI,KAAK,IAAI,GAAG,SAAS,QAAQ,IAAI,MAAM;AACjD,QAAM,IAAI,KAAK,IAAI,GAAG,SAAS,SAAS,IAAI,MAAM;AAClD,SAAO,KAAK,IAAI,UAAU,KAAK,IAAI,UAAU,KAAK,IAAI,IAAI,OAAO,OAAO,IAAI,OAAO,MAAM,CAAC,CAAC;AAC7F;AAMO,SAAS,kBAAkE,MAAiB,GAAS;AAC1G,MAAI,CAAC,KAAK,YAAY,CAAC,KAAK,OAAQ,QAAO;AAC3C,QAAM,MAAM,EAAE,GAAG,EAAE;AACnB,QAAM,IAAK,KAAK,WAAW,KAAK,KAAM;AACtC,MAAI,OAAO,EAAE,YAAY,UAAU;AACjC,QAAI,IAAI,EAAE,UAAU;AACpB,QAAI,KAAK,OAAQ,KAAI,KAAK,KAAK;AAC/B,QAAI,WAAY,KAAK,IAAI,KAAK,MAAO,IAAI,KAAK,OAAO,IAAI,KAAK;AAAA,EAChE;AACA,MAAI,OAAO,EAAE,UAAU,UAAU;AAC/B,QAAI,IAAI,EAAE,QAAQ,KAAK;AACvB,QAAI,KAAK,OAAQ,KAAI,CAAC;AACtB,QAAI,SAAU,IAAI,MAAO,OAAO;AAAA,EAClC;AACA,SAAO;AACT;;;AChFO,SAAS,eAAe,GAA0B;AACvD,MAAI,EAAE,gBAAgB,SAAS,OAAO,EAAE,aAAa,YAAY,EAAE,WAAW,EAAG,QAAO,KAAK,IAAI,GAAG,EAAE,QAAQ;AAC9G,SAAO;AACT;AAOO,SAAS,kBAAkB,GAAkB,GAAW,GAAW,MAA4B;AACpG,QAAM,IAAc,EAAE,GAAG,GAAG,UAAU,eAAe,CAAC,EAAE;AACxD,MAAI,OAAO,EAAE,cAAc,YAAY,OAAO,SAAS,EAAE,SAAS,EAAG,GAAE,IAAI,EAAE;AAC7E,MAAI,EAAE,gBAAgB,MAAO,QAAO;AACpC,QAAM,IAAI,eAAe;AAAA,IACvB;AAAA,IACA;AAAA,IACA,UAAU,OAAO,EAAE,kBAAkB,WAAW,EAAE,gBAAgB;AAAA,IAClE,SAAS,OAAO,EAAE,iBAAiB,WAAW,EAAE,eAAe;AAAA,IAC/D,OAAO,EAAE;AAAA,IACT,OAAO,EAAE;AAAA,EACX,CAAC;AAED,MAAI,KAAK,EAAE,WAAW,KAAK,KAAK,IAAI,MAAM;AACxC,MAAE,WAAW,EAAE;AACf,MAAE,UAAU,EAAE;AAAA,EAChB;AACA,MAAI,OAAO,EAAE,UAAU,YAAY,OAAO,SAAS,EAAE,KAAK,KAAK,EAAE,UAAU,EAAG,GAAE,QAAQ,EAAE;AAC1F,SAAO,OAAO,kBAAkB,MAAM,CAAC,IAAI;AAC7C;AAOO,SAAS,YAAY,OAAiC,KAAsC,MAAqB;AACtH,MAAI,CAAC,IAAK,QAAO;AACjB,QAAM,KAAK,MAAM,IAAI,IAAI;AACzB,QAAM,KAAK,MAAM,IAAI,IAAI;AACzB,QAAM,OAAO,SAAS,UAAU,KAAK,CAAC;AACtC,SAAO,KAAK,OAAO,OAAO,OAAO,KAAK,MAAM,IAAI,EAAE,IAAI;AACxD;;;ACvDO,SAAS,sBAA2C;AACzD,QAAM,IAAI;AAIV,MAAI,OAAO,EAAE,oBAAoB,cAAc,OAAO,EAAE,cAAc,WAAY,QAAO;AACzF,QAAM,SAAS,EAAE;AACjB,QAAM,OAAO,EAAE;AACf,SAAO,OAAO,OAAO,QAAQ,YAAY;AACvC,UAAM,SAAS,IAAI,OAAO,MAAM,OAAO,MAAM,MAAM;AACnD,UAAM,MAAM,OAAO,WAAW,IAAI;AAClC,QAAI,CAAC,IAAK,OAAM,IAAI,MAAM,+BAA+B;AACzD,QAAI,aAAa,IAAI,KAAK,IAAI,kBAAkB,MAAM,IAAI,GAAG,MAAM,OAAO,MAAM,MAAM,GAAG,GAAG,CAAC;AAC7F,UAAM,OAAO,MAAM,OAAO,cAAc,EAAE,MAAM,QAAQ,QAAQ,CAAC;AACjE,QAAI,KAAK,SAAS,OAAQ,OAAM,IAAI,MAAM,8BAA8B,MAAM,iBAAiB,KAAK,QAAQ,SAAS,wBAAwB;AAC7I,WAAO,IAAI,WAAW,MAAM,KAAK,YAAY,CAAC;AAAA,EAChD;AACF;AAMA,eAAsB,gBAAgB,MAAiF;AACrH,QAAM,IAAI;AAIV,MAAI,OAAO,EAAE,sBAAsB,cAAc,OAAO,EAAE,oBAAoB,WAAY,OAAM,IAAI,MAAM,0EAA0E;AACpL,QAAM,SAAS,MAAM,EAAE,kBAAkB,IAAI;AAC7C,QAAM,SAAS,IAAI,EAAE,gBAAgB,OAAO,OAAO,OAAO,MAAM;AAChE,QAAM,MAAM,OAAO,WAAW,IAAI;AAClC,MAAI,CAAC,IAAK,OAAM,IAAI,MAAM,+BAA+B;AACzD,MAAI,UAAU,QAAQ,GAAG,CAAC;AAC1B,QAAM,OAAO,IAAI,kBAAkB,IAAI,aAAa,GAAG,GAAG,OAAO,OAAO,OAAO,MAAM,EAAE,IAAI;AAC3F,SAAO,QAAQ;AACf,SAAO,EAAE,OAAO,OAAO,OAAO,QAAQ,OAAO,QAAQ,KAAK;AAC5D;AAGO,SAAS,cAAc,OAA4B,UAAkB,UAAwB;AAClG,QAAM,IAAI;AAKV,MAAI,CAAC,EAAE,YAAY,CAAC,EAAE,OAAO,CAAC,EAAE,KAAM,OAAM,IAAI,MAAM,8BAA8B;AACpF,QAAM,MAAM,EAAE,IAAI,gBAAgB,IAAI,EAAE,KAAK,CAAC,KAAK,GAAG,EAAE,MAAM,SAAS,CAAC,CAAC;AACzE,QAAM,IAAI,EAAE,SAAS,cAAc,GAAG;AACtC,IAAE,OAAO;AACT,IAAE,WAAW;AACb,IAAE,MAAM;AACR,aAAW,MAAM,EAAE,IAAK,gBAAgB,GAAG,GAAG,GAAI;AACpD;;;AC/CO,SAAS,gBAAgB,OAAe,QAA4B;AACzE,QAAM,MAAkB,CAAC;AACzB,QAAM,IAAI;AACV,QAAM,KAAK,QAAQ;AACnB,QAAM,KAAK,SAAS;AACpB,WAAS,IAAI,GAAG,KAAK,GAAG,KAAK;AAC3B,UAAM,IAAI,IAAI;AACd,UAAM,WAAW,IAAI,MAAM,OAAO,MAAM,IAAI,IAAI,OAAO,IAAI;AAC3D,QAAI,KAAK,EAAE,GAAG,MAAM,QAAQ,IAAI,MAAM,GAAG,GAAG,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,CAAC,IAAI,SAAS,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC;AAAA,EACnH;AACA,SAAO;AACT;AAGA,SAAS,gBAAgB,SAAuB,OAAmB,OAAsB,OAAe,OAAe,QAA8B;AACnJ,QAAM,CAAC,GAAG,GAAG,CAAC,IAAI,UAAU,KAAK;AACjC,MAAI,SAAS;AACb,QAAM,UAAU,IAAI;AAAA,IAClB,EAAE,QAAQ,MAAM;AAAA,IAAC,GAAG,QAAQ,CAAC,IAAI,MAAO,SAAS,KAAK,OAAQ;AAAA,IAC9D;AAAA,MACE,SAAS;AAAA,MACT;AAAA,MACA,QAAQ,EAAE,GAAG,GAAG,GAAG,EAAE;AAAA,MACrB,kBAAkB;AAAA,MAClB;AAAA,MACA,OAAO,CAAC,GAAG,GAAG,GAAG,GAAG;AAAA,MACpB,YAAY,CAAC,GAAG,UAAU,MAAM,KAAK,GAAG,GAAG;AAAA,MAC3C,OAAO,WAAW,KAAK;AAAA,MACvB,YAAY,MAAM;AAAA,MAClB,MAAM;AAAA,MACN,UAAU;AAAA,MACV,cAAc,CAAC;AAAA,MACf,QAAQ,CAAC,aAAa;AAAA,MACtB,WAAW,MAAM,WAAW,UAAU,mBAAmB,OAAO,kBAAkB,CAAC,IAAI,KAAK,IAAI,KAAK,IAAI,GAAG,CAAC,IAAI;AAAA,IACnH;AAAA,EACF;AACA,UAAQ,KAAK,gBAAgB,OAAO,MAAM,CAAC;AAC3C,UAAQ,IAAI;AACZ,SAAO;AACT;AAEO,SAAS,qBAAqB,OAAmB,SAAmG;AACzJ,QAAM,QAAQ,KAAK,IAAI,IAAI,KAAK,IAAI,KAAK,KAAK,MAAM,QAAQ,SAAS,GAAG,CAAC,CAAC;AAC1E,QAAM,SAAS,KAAK,IAAI,IAAI,KAAK,IAAI,KAAK,KAAK,MAAM,QAAQ,UAAU,EAAE,CAAC,CAAC;AAE3E,QAAM,UAAU,SAAS;AACzB,QAAM,IAAI,MAAM,IAAI,OAAO,UAAU,oBAAoB,EAAE,KAAK,EAAE,GAAG,MAAM,KAAK,MAAM,QAAQ,EAAE,GAAG,KAAK,IAAI;AAC5G,QAAM,OAAO,CAAC,GAAG,UAAU,QAAQ,KAAK,GAAG,GAAG;AAC9C,MAAI,UAAwB,aAAa,CAAC;AAC1C,MAAI,EAAE,WAAW,UAAU;AAEzB,cAAU,SAAS,SAAS,EAAE,GAAG,GAAG,GAAG,GAAG,OAAO,OAAO,GAAG,IAAI;AAAA,EACjE,WAAW,EAAE,WAAW,WAAW,CAAC,EAAE,YAAY;AAEhD,UAAM,OAAO,KAAK,KAAK,SAAS,CAAC;AACjC,cAAU,SAAS,SAAS,EAAE,GAAG,GAAG,GAAG,GAAG,OAAO,QAAQ,KAAK,GAAG,IAAI;AACrE,cAAU,SAAS,SAAS,EAAE,GAAG,GAAG,GAAG,MAAM,OAAO,QAAQ,SAAS,KAAK,GAAG,CAAC,KAAK,KAAK,IAAI,GAAG,CAAC;AAAA,EAClG;AACA,YAAU,gBAAgB,SAAS,GAAG,QAAQ,OAAO,QAAQ,OAAO,OAAO,MAAM;AACjF,QAAM,QAAmB,EAAE,MAAM,SAAS,IAAI,aAAa,MAAM,aAAa,SAAS,MAAM,SAAS,GAAG,OAAO,UAAU,SAAS,QAAQ,EAAE,GAAG,GAAG,GAAG,EAAE,EAAE;AAC1J,QAAM,OAAO,sBAAsB,EAAE,UAAU,CAAC,UAAU,QAAQ,KAAK,GAAG,KAAK,GAAG,EAAE,GAAG,GAAG,GAAG,GAAG,OAAO,OAAO,GAAG,EAAE,OAAO,OAAO,CAAC;AAClI,SAAO,EAAE,OAAO,QAAQ,KAAK;AAC/B;;;ACxEO,IAAM,iBAA0C,CAAC,OAAO,YAAY,cAAc,QAAQ,YAAY,cAAc;AAgEpH,SAAS,cAAc,QAAwD;AACpF,SAAO;AAAA,IACL,UAAU,EAAE,MAAM,OAAO,QAAQ,EAAE,GAAG,OAAO,QAAQ,GAAG,GAAG,OAAO,SAAS,EAAE,GAAG,UAAU,GAAG,UAAU,GAAG,QAAQ,KAAK;AAAA,IACvH,aAAa,EAAE,SAAS,OAAO,QAAQ,CAAC,GAAG,MAAM,KAAK;AAAA,IACtD,SAAS;AAAA,IACT,YAAY,CAAC;AAAA,EACf;AACF;AAEO,IAAM,iBAAiB;AAC9B,IAAMC,UAAS,CAAC,MAA4B,OAAO,MAAM,YAAY,OAAO,SAAS,CAAC;AACtF,IAAM,QAAQ,CAAC,GAAY,MAAeA,QAAO,CAAC,KAAK,KAAK,IAAI,CAAC,KAAK,iBAAiB,IAAI;AAEpF,SAAS,kBAAkB,KAAuD,MAAoC;AAC3H,QAAM,IAAI;AACV,QAAM,IAAK,EAAE,UAAU,CAAC;AACxB,SAAO;AAAA,IACL,MAAM,eAAe,SAAS,EAAE,IAAoB,IAAK,EAAE,OAAwB,KAAK;AAAA,IACxF,QAAQ,EAAE,GAAG,MAAM,EAAE,GAAG,KAAK,OAAO,CAAC,GAAG,GAAG,MAAM,EAAE,GAAG,KAAK,OAAO,CAAC,EAAE;AAAA,IACrE,UAAUA,QAAO,EAAE,QAAQ,KAAM,EAAE,WAAW,MAAO,OAAO,MAAM,KAAK;AAAA,IACvE,UAAUA,QAAO,EAAE,QAAQ,IAAI,KAAK,IAAI,IAAI,KAAK,IAAI,GAAG,KAAK,MAAM,EAAE,QAAQ,CAAC,CAAC,IAAI,KAAK;AAAA,IACxF,QAAQ,OAAO,EAAE,WAAW,YAAY,EAAE,SAAS,KAAK;AAAA,EAC1D;AACF;AAGA,SAAS,aAAa,GAAW,GAAmB;AAClD,QAAM,KAAK,KAAK,IAAI,CAAC;AACrB,QAAM,KAAK,KAAK,IAAI,CAAC;AAErB,QAAM,MAAM,IAAI,KAAK,KAAK;AAC1B,QAAM,MAAM,IAAI,KAAK;AACrB,QAAM,MAAM,IAAI,KAAK,KAAK;AAC1B,SAAO,CAAC,KAAK,KAAK,KAAK,KAAK,EAAE,KAAK,MAAM,EAAE,IAAI,MAAM,EAAE,IAAI,EAAE,KAAK,MAAM,EAAE,IAAI,MAAM,EAAE,EAAE;AAC1F;AAGA,SAAS,YAAY,GAAW,GAAmB;AACjD,QAAM,MAAM,KAAK,IAAI,CAAC;AACtB,QAAM,MAAM,KAAK,IAAI,CAAC;AACtB,SAAO,CAAC,KAAK,CAAC,KAAK,KAAK,KAAK,EAAE,KAAK,MAAM,EAAE,IAAI,MAAM,EAAE,IAAI,EAAE,KAAK,MAAM,EAAE,IAAI,MAAM,EAAE,EAAE;AAC3F;AAEA,IAAM,MAAM,CAAC,QAAiB,MAAM,KAAK,KAAM;AAGxC,SAAS,mBAAmB,GAA4B;AAC7D,MAAI,EAAE,SAAS,MAAO,QAAO,CAAC;AAC9B,MAAI,EAAE,SAAS,eAAgB,QAAO,MAAM,KAAK,EAAE,QAAQ,EAAE,SAAS,GAAG,CAAC,GAAG,MAAM,IAAI,EAAE,QAAQ,IAAK,IAAI,KAAK,KAAM,EAAE,QAAQ;AAC/H,QAAM,UAAU,EAAE,SAAS,eAAe,IAAI,EAAE,SAAS,aAAa,KAAK;AAC3E,QAAM,IAAI,IAAI,UAAU,EAAE,QAAQ;AAClC,SAAO,EAAE,SAAS,SAAS,CAAC,GAAG,IAAI,KAAK,KAAK,CAAC,IAAI,CAAC,CAAC;AACtD;AAOO,SAAS,eAAe,GAA4B;AACzD,QAAM,IAAI,EAAE;AACZ,UAAQ,EAAE,MAAM;AAAA,IACd,KAAK;AACH,aAAO,CAAC;AAAA,IACV,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AACH,aAAO,mBAAmB,CAAC,EAAE,IAAI,CAAC,MAAM,aAAa,GAAG,CAAC,CAAC;AAAA,IAC5D,KAAK,QAAQ;AACX,YAAM,CAAC,GAAG,CAAC,IAAI,mBAAmB,CAAC;AACnC,aAAO,CAAC,aAAa,GAAG,CAAC,GAAG,aAAa,GAAG,CAAC,GAAG,YAAY,GAAG,KAAK,EAAE,CAAC;AAAA,IACzE;AAAA,IACA,KAAK,gBAAgB;AACnB,YAAM,MAAgB,CAAC;AACvB,YAAM,IAAI,EAAE;AACZ,eAAS,IAAI,GAAG,IAAI,GAAG,IAAK,KAAI,KAAK,YAAY,GAAI,IAAI,KAAK,KAAK,IAAK,CAAC,CAAC;AAC1E,UAAI,EAAE,QAAQ;AACZ,cAAM,QAAQ,aAAa,GAAG,IAAI,EAAE,QAAQ,CAAC;AAC7C,iBAAS,IAAI,GAAG,IAAI,GAAG,IAAK,KAAI,KAAK,cAAc,YAAY,GAAI,IAAI,KAAK,KAAK,IAAK,CAAC,GAAG,KAAK,CAAC;AAAA,MAClG;AACA,aAAO;AAAA,IACT;AAAA,EACF;AACF;AAGO,SAAS,qBAAqB,GAAkB,MAAkE;AACvH,QAAM,MAA+B,CAAC;AACtC,aAAW,KAAK,mBAAmB,CAAC,GAAG;AACrC,UAAM,IAAI,CAAC,KAAK,IAAI,CAAC,GAAG,KAAK,IAAI,CAAC,CAAC;AACnC,UAAM,SAAS,CAAC,EAAE,OAAO,GAAG,EAAE,OAAO,CAAC;AACtC,UAAM,SAAS,CAAC,KAAK,OAAO,KAAK,MAAM;AACvC,QAAI,KAAK;AACT,QAAI,KAAK;AACT,QAAI,KAAK;AACT,aAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,UAAI,KAAK,IAAI,EAAE,CAAC,CAAC,IAAI,OAAO;AAC1B,YAAI,OAAO,CAAC,IAAI,KAAK,OAAO,CAAC,IAAI,OAAO,CAAC,EAAG,MAAK;AAAA,MACnD,OAAO;AACL,cAAM,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;AAC3B,cAAM,MAAM,OAAO,CAAC,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;AACxC,aAAK,KAAK,IAAI,IAAI,KAAK,IAAI,IAAI,EAAE,CAAC;AAClC,aAAK,KAAK,IAAI,IAAI,KAAK,IAAI,IAAI,EAAE,CAAC;AAAA,MACpC;AAAA,IACF;AACA,QAAI,CAAC,MAAM,CAAC,OAAO,SAAS,EAAE,KAAK,CAAC,OAAO,SAAS,EAAE,KAAK,KAAK,GAAI;AACpE,QAAI,KAAK,CAAC,EAAE,GAAG,EAAE,OAAO,IAAI,KAAK,EAAE,CAAC,GAAG,GAAG,EAAE,OAAO,IAAI,KAAK,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,OAAO,IAAI,KAAK,EAAE,CAAC,GAAG,GAAG,EAAE,OAAO,IAAI,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;AAAA,EAC/H;AACA,SAAO;AACT;AAMO,SAAS,qBAAqB,KAA0D,MAA0C;AACvI,QAAM,IAAI;AACV,MAAI,SAAS,KAAK;AAClB,MAAI,MAAM,QAAQ,EAAE,MAAM,GAAG;AAC3B,QAAI,EAAE,OAAO,SAAS,EAAG,OAAM,IAAI,MAAM,8DAA8D,EAAE,OAAO,MAAM,GAAG;AACzH,aAAS,EAAE,OAAO,IAAI,CAAC,GAAG,MAAM;AAC9B,YAAM,IAAK,KAAK,CAAC;AACjB,UAAI,CAACA,QAAO,EAAE,CAAC,KAAK,CAACA,QAAO,EAAE,CAAC,KAAK,KAAK,IAAI,EAAE,CAAC,IAAI,kBAAkB,KAAK,IAAI,EAAE,CAAC,IAAI,gBAAgB;AACpG,cAAM,IAAI,MAAM,UAAU,CAAC,qCAAkC,cAAc,mBAAmB;AAAA,MAChG;AACA,aAAO,EAAE,GAAG,EAAE,GAAG,GAAG,EAAE,EAAE;AAAA,IAC1B,CAAC;AAAA,EACH;AACA,QAAM,UAAU,OAAO,EAAE,YAAY,YAAY,EAAE,UAAU,KAAK;AAClE,MAAI,WAAW,CAAC,OAAO,OAAQ,OAAM,IAAI,MAAM,+EAA+E;AAC9H,SAAO,EAAE,SAAS,QAAQ,MAAM,OAAO,EAAE,SAAS,YAAY,EAAE,OAAO,KAAK,KAAK;AACnF;AAGO,SAAS,sBAAsB,GAAqB,GAAqB;AAC9E,QAAM,MAAgB,CAAC;AACvB,aAAW,KAAK,EAAE,QAAQ;AACxB,UAAM,KAAK,EAAE,IAAI,EAAE;AACnB,UAAM,KAAK,EAAE,IAAI,EAAE;AACnB,UAAM,MAAM,KAAK,MAAM,IAAI,EAAE;AAC7B,QAAI,MAAM,KAAM,KAAI,KAAK,EAAE,GAAG,KAAK,KAAK,GAAG,KAAK,IAAI,CAAC;AAAA,EACvD;AAEA,MAAI,EAAE,OAAO,UAAU,EAAG,KAAI,KAAK,EAAE,GAAG,GAAG,GAAG,EAAE,CAAC;AACjD,MAAI,EAAE,OAAO,UAAU,EAAG,KAAI,KAAK,EAAE,GAAG,GAAG,GAAG,EAAE,CAAC;AACjD,SAAO;AACT;AAGO,IAAM,uBAAuB;AAO7B,IAAM,qBAAN,MAAyB;AAAA,EAI9B,YAA6B,OAAyB;AAAzB;AAAA,EAA0B;AAAA,EAA1B;AAAA,EAHrB,QAAuB;AAAA,EACvB,MAAqB;AAAA;AAAA,EAK7B,IAAI,OAAmD;AACrD,WAAO,KAAK,SAAS,KAAK,MAAM,EAAE,MAAM,KAAK,OAAO,WAAW,KAAK,IAAI,IAAI;AAAA,EAC9E;AAAA,EAEA,KAAuB,GAAS;AAC9B,QAAI,CAAC,KAAK,MAAM,WAAW,CAAC,KAAK,MAAM,QAAQ,CAAC,KAAK,MAAM,OAAO,OAAQ,QAAO;AACjF,QAAI,CAAC,KAAK,OAAO;AACf,WAAK,QAAQ,EAAE,GAAG,EAAE,GAAG,GAAG,EAAE,EAAE;AAC9B,aAAO;AAAA,IACT;AACA,UAAM,IAAI,KAAK;AACf,QAAI,CAAC,KAAK,KAAK;AACb,YAAM,KAAK,EAAE,IAAI,EAAE;AACnB,YAAM,KAAK,EAAE,IAAI,EAAE;AACnB,YAAM,MAAM,KAAK,MAAM,IAAI,EAAE;AAC7B,UAAI,MAAM,qBAAsB,QAAO,EAAE,GAAG,GAAG,GAAG,EAAE,GAAG,GAAG,EAAE,EAAE;AAC9D,UAAI,OAAsB;AAC1B,UAAI,UAAU;AACd,iBAAWC,MAAK,sBAAsB,KAAK,OAAO,CAAC,GAAG;AACpD,cAAM,MAAM,KAAK,KAAK,KAAKA,GAAE,IAAI,KAAKA,GAAE,KAAK,GAAG;AAChD,YAAI,MAAM,SAAS;AACjB,oBAAU;AACV,iBAAOA;AAAA,QACT;AAAA,MACF;AACA,WAAK,MAAM;AACX,UAAI,CAAC,KAAM,QAAO;AAAA,IACpB;AACA,UAAM,IAAI,KAAK;AACf,UAAM,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE;AAC9C,WAAO,EAAE,GAAG,GAAG,GAAG,EAAE,IAAI,EAAE,IAAI,GAAG,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE;AAAA,EACpD;AACF;AAGO,SAAS,sBAAsB,GAAqB,MAAyC,QAAQ,IAA6B;AACvI,QAAM,MAA+B,CAAC;AACtC,QAAM,MAAM,KAAK,MAAM,KAAK,OAAO,KAAK,MAAM,IAAI;AAClD,aAAW,KAAK,EAAE,QAAQ;AAExB,UAAM,KAAK,KAAK,QAAQ,IAAI,EAAE;AAC9B,UAAM,KAAK,KAAK,SAAS,IAAI,EAAE;AAC/B,UAAM,SAAS,EAAE,KAAK,KAAK,EAAE,KAAK,KAAK,EAAE,KAAK,KAAK,SAAS,EAAE,KAAK,KAAK;AACxE,UAAM,MAAM,KAAK,MAAM,IAAI,EAAE;AAC7B,UAAM,SAAS,SAAS,KAAK,KAAK,KAAK,IAAI,KAAK,IAAI,IAAI,KAAK,MAAM,KAAK,MAAM,KAAK,OAAO,KAAK,MAAM,IAAI,GAAG,KAAK,MAAM,IAAI,EAAE,CAAC,CAAC;AAC/H,aAAS,IAAI,GAAG,IAAI,OAAO,KAAK;AAC9B,YAAM,IAAI,SAAU,IAAI,KAAK,KAAK,IAAK,QAAQ,MAAM,SAAS,IAAK,UAAU,IAAI,OAAQ;AACzF,UAAI,KAAK,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,KAAK,IAAI,CAAC,IAAI,KAAK,GAAG,EAAE,IAAI,KAAK,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC;AAAA,IACjF;AAAA,EACF;AACA,SAAO;AACT;;;AC3RA,IAAMC,OAAM;AAEL,SAAS,cAAc,OAAgB,OAAO,SAAiB;AACpE,QAAM,IAAI,OAAO,UAAU,WAAWA,KAAI,KAAK,MAAM,KAAK,CAAC,IAAI;AAC/D,MAAI,CAAC,EAAG,OAAM,IAAI,MAAM,GAAG,IAAI,OAAO,KAAK,UAAU,KAAK,CAAC,gCAAgC;AAC3F,QAAM,IAAI,SAAS,EAAE,CAAC,GAAG,EAAE;AAC3B,SAAO,CAAE,KAAK,KAAM,KAAM,KAAK,IAAK,KAAK,IAAI,GAAG;AAClD;AAEO,SAAS,cAAc,GAAW,GAAW,GAAmB;AACrE,SAAO,MAAM,CAAC,GAAG,GAAG,CAAC,EAAE,IAAI,CAAC,MAAM,KAAK,MAAM,KAAK,IAAI,KAAK,KAAK,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG,CAAC,EAAE,KAAK,EAAE;AACpH;AAGO,SAAS,SAAS,GAAW,GAAW,GAAgD;AAC7F,QAAM,IAAI,IAAI;AACd,QAAM,IAAI,IAAI;AACd,QAAM,IAAI,IAAI;AACd,QAAM,MAAM,KAAK,IAAI,GAAG,GAAG,CAAC;AAC5B,QAAM,MAAM,KAAK,IAAI,GAAG,GAAG,CAAC;AAC5B,QAAM,IAAI,MAAM;AAChB,MAAI,IAAI;AACR,MAAI,IAAI,GAAG;AACT,QAAI,QAAQ,EAAG,KAAI,OAAQ,IAAI,KAAK,IAAK;AAAA,aAChC,QAAQ,EAAG,KAAI,OAAO,IAAI,KAAK,IAAI;AAAA,QACvC,KAAI,OAAO,IAAI,KAAK,IAAI;AAAA,EAC/B;AACA,MAAI,IAAI,EAAG,MAAK;AAChB,SAAO,EAAE,GAAG,GAAG,QAAQ,IAAI,IAAI,IAAI,KAAK,GAAG,IAAI;AACjD;AAEO,SAAS,SAAS,GAAW,GAAW,GAAmB;AAChE,QAAM,MAAQ,IAAI,MAAO,OAAO,MAAO;AACvC,QAAM,IAAI,IAAI;AACd,QAAM,IAAI,KAAK,IAAI,KAAK,IAAK,KAAK,IAAK,CAAC;AACxC,QAAM,IAAI,IAAI;AACd,QAAM,CAAC,GAAG,GAAG,CAAC,IAAI,KAAK,IAAI,CAAC,GAAG,GAAG,CAAC,IAAI,KAAK,IAAI,CAAC,GAAG,GAAG,CAAC,IAAI,KAAK,IAAI,CAAC,GAAG,GAAG,CAAC,IAAI,KAAK,IAAI,CAAC,GAAG,GAAG,CAAC,IAAI,KAAK,IAAI,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC;AACnI,SAAO,CAAC,KAAK,OAAO,IAAI,KAAK,GAAG,GAAG,KAAK,OAAO,IAAI,KAAK,GAAG,GAAG,KAAK,OAAO,IAAI,KAAK,GAAG,CAAC;AACzF;AAGO,SAAS,SAAS,GAAW,GAAW,GAAgD;AAC7F,QAAM,EAAE,EAAE,IAAI,SAAS,GAAG,GAAG,CAAC;AAC9B,QAAM,MAAM,KAAK,IAAI,GAAG,GAAG,CAAC,IAAI;AAChC,QAAM,MAAM,KAAK,IAAI,GAAG,GAAG,CAAC,IAAI;AAChC,QAAM,KAAK,MAAM,OAAO;AACxB,QAAM,IAAI,MAAM;AAChB,SAAO,EAAE,GAAG,GAAG,MAAM,IAAI,IAAI,KAAK,IAAI,KAAK,IAAI,IAAI,IAAI,CAAC,IAAI,EAAE;AAChE;AAEO,SAAS,SAAS,GAAW,GAAW,GAAmB;AAChE,QAAM,KAAK,IAAI,KAAK,IAAI,IAAI,IAAI,CAAC,KAAK;AACtC,QAAM,IAAI,IAAI,IAAI;AAClB,SAAO,SAAS,GAAG,MAAM,IAAI,IAAI,IAAI,GAAG,CAAC;AAC3C;AAMA,IAAM,YAA6C;AAAA,EACjD,CAAC,GAAG,CAAC;AAAA,EACL,CAAC,IAAI,EAAE;AAAA,EACP,CAAC,KAAK,EAAE;AAAA,EACR,CAAC,KAAK,GAAG;AAAA,EACT,CAAC,KAAK,GAAG;AAAA,EACT,CAAC,KAAK,GAAG;AAAA,EACT,CAAC,KAAK,GAAG;AACX;AAEA,SAAS,UAAU,GAAW,MAAqB;AACjD,QAAM,KAAM,IAAI,MAAO,OAAO;AAC9B,QAAM,KAAK,SAAS,IAAI,IAAI;AAC5B,WAAS,IAAI,GAAG,IAAI,UAAU,QAAQ,KAAK;AACzC,UAAM,IAAI,UAAU,IAAI,CAAC;AACzB,UAAM,IAAI,UAAU,CAAC;AACrB,QAAI,KAAK,EAAE,IAAI,EAAG,QAAO,EAAE,EAAE,KAAM,IAAI,EAAE,IAAI,MAAM,EAAE,IAAI,IAAI,EAAE,IAAI,MAAO,EAAE,EAAE,IAAI,EAAE,EAAE;AAAA,EACxF;AACA,SAAO;AACT;AAGO,SAAS,WAAW,OAAe,OAA2B;AACnE,SAAO,UAAU,SAAU,QAAQ,MAAO,OAAO,MAAM,UAAU,OAAO,CAAC;AAC3E;AAGO,SAAS,WAAW,KAAa,OAA2B;AACjE,SAAO,UAAU,SAAU,MAAM,MAAO,OAAO,MAAM,UAAU,KAAK,CAAC;AACvE;AAIO,IAAM,gBAAwC,CAAC,iBAAiB,uBAAuB,aAAa,WAAW,YAAY,UAAU,eAAe;AAapJ,SAAS,aAAa,MAAc,MAAmB,UAAmD,CAAC,GAAmB;AACnI,QAAM,QAAQ,QAAQ,SAAS;AAC/B,QAAM,CAAC,GAAG,GAAG,CAAC,IAAI,cAAc,MAAM,MAAM;AAC5C,QAAM,MAAM,SAAS,GAAG,GAAG,CAAC;AAC5B,QAAM,QAAQ,WAAW,IAAI,GAAG,KAAK;AACrC,QAAM,KAAK,CAAC,UAAgC;AAC1C,UAAM,KAAM,QAAQ,MAAO,OAAO;AAClC,UAAM,CAAC,IAAI,IAAI,EAAE,IAAI,SAAS,WAAW,GAAG,KAAK,GAAG,IAAI,GAAG,IAAI,CAAC;AAChE,WAAO,EAAE,OAAO,cAAc,IAAI,IAAI,EAAE,GAAG,OAAO,KAAK,MAAM,IAAI,EAAE,IAAI,GAAG;AAAA,EAC5E;AACA,QAAM,SAAS,QAAQ,UAAU;AACjC,QAAM,UAAmE;AAAA,IACvE,eAAe,CAAC,GAAG,GAAG;AAAA,IACtB,uBAAuB,CAAC,GAAG,MAAM,QAAQ,MAAM,MAAM;AAAA,IACrD,WAAW,CAAC,GAAG,CAAC,QAAQ,MAAM;AAAA,IAC9B,SAAS,CAAC,GAAG,KAAK,GAAG;AAAA,IACrB,UAAU,CAAC,GAAG,IAAI,KAAK,GAAG;AAAA,IAC1B,QAAQ,CAAC,GAAG,IAAI,KAAK,GAAG;AAAA,EAC1B;AACA,MAAI,SAAS,iBAAiB;AAC5B,UAAM,MAAM,SAAS,GAAG,GAAG,CAAC;AAC5B,UAAM,QAAQ,CAAC,GAAG,MAAM,OAAO,MAAM,GAAG;AACxC,WAAO,MAAM,IAAI,CAAC,MAAM;AACtB,YAAM,CAAC,IAAI,IAAI,EAAE,IAAI,MAAM,IAAI,CAAC,GAAG,GAAG,CAAC,IAAI,SAAS,IAAI,GAAG,IAAI,GAAG,KAAK,IAAI,MAAM,KAAK,IAAI,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC;AAC3G,aAAO,EAAE,OAAO,cAAc,IAAI,IAAI,EAAE,GAAG,OAAO,KAAK,MAAM,QAAQ,EAAE,IAAI,GAAG;AAAA,IAChF,CAAC;AAAA,EACH;AACA,SAAO,QAAQ,IAAI,EAAE,IAAI,CAAC,GAAG,MAAO,MAAM,IAAI,EAAE,OAAO,cAAc,GAAG,GAAG,CAAC,GAAG,OAAO,KAAK,MAAM,QAAQ,EAAE,IAAI,GAAG,IAAI,GAAG,QAAQ,CAAC,CAAE;AACtI;AAQO,IAAM,mBAAsC;AAAA,EACjD,EAAE,OAAO,WAAW,MAAM,aAAa;AAAA,EACvC,EAAE,OAAO,WAAW,MAAM,eAAe;AAAA,EACzC,EAAE,OAAO,WAAW,MAAM,eAAe;AAAA,EACzC,EAAE,OAAO,WAAW,MAAM,WAAW;AAAA,EACrC,EAAE,OAAO,WAAW,MAAM,UAAU;AAAA,EACpC,EAAE,OAAO,WAAW,MAAM,cAAc;AAAA,EACxC,EAAE,OAAO,WAAW,MAAM,YAAY;AAAA,EACtC,EAAE,OAAO,WAAW,MAAM,YAAY;AAAA,EACtC,EAAE,OAAO,WAAW,MAAM,aAAa;AAAA,EACvC,EAAE,OAAO,WAAW,MAAM,aAAa;AACzC;;;ACjJO,IAAM,mBAAmB;AACzB,IAAM,oBAAoB;AAEjC,IAAM,YAAwB,oBAAoB;AAAA,EAChD,IAAI;AAAA,EACJ,MAAM;AAAA,EACN,UAAU;AAAA,EACV,QAAQ;AAAA,EACR,KAAK,EAAE,MAAM,IAAI,UAAU,MAAM,SAAS,KAAK,SAAS,GAAG,MAAM,KAAK,cAAc,OAAO,iBAAiB,MAAM;AAAA,EAClH,OAAO,EAAE,KAAK,MAAM,MAAM,GAAG,KAAK,KAAK,gBAAgB,MAAM,iBAAiB,MAAM,QAAQ,UAAU;AACxG,CAAC;AAED,IAAM,YAAwB,oBAAoB;AAAA,EAChD,IAAI;AAAA,EACJ,MAAM;AAAA,EACN,UAAU;AAAA,EACV,QAAQ;AAAA,EACR,YAAY;AAAA,EACZ,KAAK,EAAE,MAAM,IAAI,UAAU,KAAK,SAAS,MAAM,WAAW,MAAM,OAAO,IAAI,SAAS,GAAG,MAAM,MAAM,cAAc,OAAO,iBAAiB,MAAM;AAAA,EAC/I,OAAO,EAAE,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,gBAAgB,OAAO,iBAAiB,MAAM,QAAQ,UAAU;AACpG,CAAC;AAEM,IAAM,YAAN,MAAgB;AAAA,EACZ,QAAQ;AAAA,EACR,SAAS;AAAA,EACV,UAAwB,aAAa,CAAC;AAAA;AAAA,EAE9C,UAAU;AAAA;AAAA,EAGV,OAAO,QAA6B,SAA4I;AAC9K,QAAI,CAAC,OAAO,OAAQ,OAAM,IAAI,MAAM,0DAA0D;AAC9F,eAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,GAAG;AACrC,UAAI,CAAC,OAAO,SAAS,EAAE,CAAC,KAAK,CAAC,OAAO,SAAS,EAAE,CAAC,KAAK,EAAE,IAAI,KAAK,EAAE,IAAI,KAAK,EAAE,IAAI,KAAK,SAAS,EAAE,IAAI,KAAK,QAAQ;AACjH,cAAM,IAAI,MAAM,UAAU,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC,gBAAgB,KAAK,KAAK,OAAI,KAAK,MAAM,cAAc;AAAA,MACrG;AAAA,IACF;AACA,QAAI,QAAQ,QAAQ,SAAS,UAAU,YAAY;AACnD,QAAI,QAAQ,SAAS,OAAW,SAAQ,oBAAoB,EAAE,KAAK,EAAE,GAAG,MAAM,KAAK,MAAM,QAAQ,KAAK,EAAE,GAAG,KAAK;AAChH,UAAM,CAAC,GAAG,GAAG,CAAC,IAAI,UAAU,QAAQ,KAAK;AACzC,QAAI,SAA8B;AAClC,UAAM,UAAU,IAAI;AAAA,MAClB,EAAE,QAAQ,MAAM;AAAA,MAAC,GAAG,QAAQ,CAAC,IAAI,MAAO,SAAS,EAAG;AAAA,MACpD;AAAA,QACE,SAAS;AAAA,QACT,SAAS,KAAK;AAAA,QACd,QAAQ,EAAE,GAAG,GAAG,GAAG,EAAE;AAAA,QACrB,kBAAkB;AAAA,QAClB;AAAA,QACA,OAAO,CAAC,GAAG,GAAG,GAAG,GAAG;AAAA,QACpB,YAAY,CAAC,KAAK,KAAK,KAAK,GAAG;AAAA,QAC/B,OAAO;AAAA,QACP,YAAY;AAAA,QACZ,MAAM;AAAA,QACN,UAAU,QAAQ;AAAA,QAClB,cAAc,CAAC;AAAA,QACf,QAAQ,CAAC,aAAa;AAAA,QACtB,WAAW,mBAAmB,OAAO,kBAAkB,CAAC,IAAI,KAAK,IAAI,KAAK,IAAI,GAAG,CAAC;AAAA,MACpF;AAAA,IACF;AACA,YAAQ,KAAK,MAAM;AACnB,UAAM,MAAM,QAAQ,IAAI;AACxB,QAAI,QAAQ;AACV,WAAK,UAAU;AACf,WAAK;AAAA,IACP;AACA,WAAO,EAAE,QAAQ,IAAI,OAAO;AAAA,EAC9B;AAAA;AAAA,EAGA,KAAK,GAAW,GAAW,SAAS,GAAkB;AACpD,QAAI,EAAE,KAAK,KAAK,KAAK,KAAK,IAAI,KAAK,SAAS,IAAI,KAAK,QAAS,OAAM,IAAI,MAAM,IAAI,CAAC,KAAK,CAAC,gBAAgB,KAAK,KAAK,OAAI,KAAK,MAAM,cAAc;AAChJ,UAAM,IAAI,KAAK,IAAI,GAAG,KAAK,MAAM,MAAM,CAAC;AACxC,UAAM,KAAK,KAAK,IAAI,GAAG,KAAK,MAAM,CAAC,IAAI,CAAC;AACxC,UAAM,KAAK,KAAK,IAAI,GAAG,KAAK,MAAM,CAAC,IAAI,CAAC;AACxC,UAAM,KAAK,KAAK,IAAI,KAAK,OAAO,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC;AACrD,UAAM,KAAK,KAAK,IAAI,KAAK,QAAQ,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC;AACtD,UAAM,KAAK,WAAW,KAAK,SAAS,EAAE,GAAG,IAAI,GAAG,IAAI,OAAO,KAAK,IAAI,QAAQ,KAAK,GAAG,CAAC;AACrF,QAAI,IAAI;AACR,QAAI,IAAI;AACR,QAAI,IAAI;AACR,QAAI,IAAI;AACR,aAAS,IAAI,GAAG,IAAI,GAAG,QAAQ,KAAK,GAAG;AACrC,YAAM,IAAI,GAAG,IAAI,CAAC;AAClB,WAAK,GAAG,CAAC,IAAI;AACb,WAAK,GAAG,IAAI,CAAC,IAAI;AACjB,WAAK,GAAG,IAAI,CAAC,IAAI;AACjB,WAAK;AAAA,IACP;AACA,QAAI,MAAM,EAAG,QAAO;AACpB,UAAM,MAAM,CAAC,MAAc,KAAK,MAAM,IAAI,CAAC,EAAE,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG;AACzE,WAAO,IAAI,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;AAAA,EACrC;AAAA,EAEA,QAAc;AACZ,SAAK,UAAU,aAAa,CAAC;AAC7B,SAAK;AAAA,EACP;AAAA;AAAA,EAGA,SAA4B;AAC1B,UAAM,KAAK,WAAW,KAAK,SAAS,EAAE,GAAG,GAAG,GAAG,GAAG,OAAO,KAAK,OAAO,QAAQ,KAAK,OAAO,CAAC;AAC1F,aAAS,IAAI,GAAG,IAAI,GAAG,QAAQ,KAAK,GAAG;AACrC,YAAM,IAAI,GAAG,IAAI,CAAC,IAAI;AACtB,SAAG,CAAC,IAAI,KAAK,MAAM,GAAG,CAAC,IAAI,IAAI,OAAO,IAAI,EAAE;AAC5C,SAAG,IAAI,CAAC,IAAI,KAAK,MAAM,GAAG,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,EAAE;AACpD,SAAG,IAAI,CAAC,IAAI,KAAK,MAAM,GAAG,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,EAAE;AACpD,SAAG,IAAI,CAAC,IAAI;AAAA,IACd;AACA,WAAO;AAAA,EACT;AACF;;;AChDO,IAAM,mBAAN,cAA+B,MAAM;AAAA,EAC1C,YAAY,SAAiB;AAC3B,UAAM,OAAO;AACb,SAAK,OAAO;AAAA,EACd;AACF;AA0IA,IAAMC,OAAM;AAEZ,SAAS,WAAW,OAAgB,OAAO,SAAiB;AAC1D,MAAI,OAAO,UAAU,YAAY,CAACA,KAAI,KAAK,MAAM,KAAK,CAAC,EAAG,OAAM,IAAI,iBAAiB,GAAG,IAAI,OAAO,KAAK,UAAU,KAAK,CAAC,gCAAgC;AACxJ,SAAO,MAAM,KAAK,EAAE,YAAY;AAClC;AAEA,SAAS,OAAO,KAA+C;AAC7D,QAAM,CAAC,GAAG,GAAG,CAAC,IAAI,UAAU,GAAG;AAC/B,SAAO,CAAC,GAAG,GAAG,GAAG,GAAG;AACtB;AAEA,SAAS,SAAS,GAAW,GAAW,GAAmB;AACzD,SAAO,MAAM,CAAC,GAAG,GAAG,CAAC,EAAE,IAAI,CAAC,MAAM,KAAK,MAAM,KAAK,IAAI,KAAK,KAAK,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG,CAAC,EAAE,KAAK,EAAE;AACpH;AAEA,SAAS,UAAU,GAAsB,GAAyC;AAChF,MAAI,CAAC,EAAG,QAAO,IAAI,EAAE,GAAG,EAAE,IAAI;AAC9B,MAAI,CAAC,EAAG,QAAO,EAAE,GAAG,EAAE;AACtB,QAAM,IAAI,KAAK,IAAI,EAAE,GAAG,EAAE,CAAC;AAC3B,QAAM,IAAI,KAAK,IAAI,EAAE,GAAG,EAAE,CAAC;AAC3B,SAAO,EAAE,GAAG,GAAG,OAAO,KAAK,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,IAAI,GAAG,QAAQ,KAAK,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,IAAI,EAAE;AACzH;AAEA,IAAM,eAAe,CAAC,MAAoD,GAAG,SAAS;AAE/E,IAAM,wBAAN,MAA4B;AAAA,EACzB;AAAA,EACA,aAAsC,CAAC;AAAA,EACvC,YAA4B,CAAC;AAAA,EAC7B,YAA4B,CAAC;AAAA,EACpB;AAAA,EACT;AAAA,EACA;AAAA,EACA;AAAA,EACA,iBAAiB;AAAA,EACjB,YAAuB;AAAA,EACvB,OAAkB,EAAE,GAAG,cAAc,KAAK,EAAE,GAAG,aAAa,IAAI,EAAE;AAAA,EAClE;AAAA,EACS;AAAA,EACT,YAAY,oBAAI,IAAgB;AAAA,EAChC,UAAU;AAAA,EACV,SAAkC;AAAA,EAClC,UAAqC;AAAA,EACrC,OAA0D;AAAA,EAC1D,aAAiE;AAAA,EACjE,QAA8B;AAAA,EAC9B,cAAc;AAAA,EACd,gBAAgB;AAAA,EAChB;AAAA,EACA,WAAqB,iBAAiB,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,EAAE;AAAA,EAClD,MAAM,IAAI,UAAU;AAAA,EAC7B,iBAAiB;AAAA,EACjB,eAAwD;AAAA,EAC/C,cAAc,oBAAI,IAAwB;AAAA,EACnD,kBAAkB;AAAA,EACT,iBAAiB,sBAAsB;AAAA,EACvC,mBAAmB,sBAAsB;AAAA,EAE1D,YAAY,UAA8B,CAAC,GAAG;AAC5C,SAAK,eAAe,KAAK,IAAI,GAAG,QAAQ,gBAAgB,GAAG;AAC3D,SAAK,MAAM,oBAAoB,EAAE,OAAO,QAAQ,OAAO,QAAQ,QAAQ,QAAQ,KAAK,QAAQ,KAAK,OAAO,KAAK,aAAa,QAAQ,KAAK,EAAE,CAAC;AAC1I,SAAK,eAAe,QAAQ,WAAW,CAAC,GAAG,IAAI,CAAC,MAAM,oBAAoB,EAAE,GAAG,GAAG,SAAS,MAAM,CAAC,CAAC;AACnG,UAAM,QAAQ,KAAK,UAAU,QAAQ,WAAW,gBAAgB,KAAK,KAAK,UAAU,gBAAgB;AACpG,SAAK,QAAQ,oBAAoB,KAAK;AACtC,SAAK,QAAQ,QAAQ,QAAQ,WAAW,QAAQ,KAAK,IAAI;AACzD,SAAK,OAAO,QAAQ,SAAS,SAAS,SAAS;AAC/C,SAAK,cAAc,QAAQ;AAC3B,SAAK,SAAS,cAAc,KAAK,IAAI,MAAM;AAAA,EAC7C;AAAA;AAAA,EAIA,UAAU,UAAkC;AAC1C,SAAK,UAAU,IAAI,QAAQ;AAC3B,WAAO,MAAM,KAAK,UAAU,OAAO,QAAQ;AAAA,EAC7C;AAAA,EAEQ,KAAK,QAA8B,OAAa;AACtD,QAAI,UAAU,SAAS,KAAK,UAAU,MAAO,MAAK,QAAQ;AAAA,QACrD,MAAK,MAAM,KAAK,GAAG,KAAK;AAC7B,SAAK;AACL,SAAK,SAAS;AACd,eAAW,KAAK,CAAC,GAAG,KAAK,SAAS,EAAG,GAAE;AAAA,EACzC;AAAA;AAAA,EAGA,WAA6B;AAC3B,QAAI,KAAK,OAAQ,QAAO,KAAK;AAC7B,UAAM,OAAO,KAAK,UAAU,KAAK,UAAU,SAAS,CAAC;AACrD,UAAM,OAAO,KAAK,UAAU,KAAK,UAAU,SAAS,CAAC;AACrD,SAAK,SAAS;AAAA,MACZ,UAAU,KAAK;AAAA,MACf,OAAO,KAAK;AAAA,MACZ,SAAS,CAAC,GAAG,iBAAiB,GAAG,KAAK,WAAW;AAAA,MACjD,OAAO,KAAK;AAAA,MACZ,gBAAgB,KAAK;AAAA,MACrB,WAAW,KAAK;AAAA,MAChB,MAAM,KAAK;AAAA,MACX,MAAM,KAAK;AAAA,MACX,SAAS,KAAK,UAAU,SAAS,KAAK,CAAC,KAAK;AAAA,MAC5C,SAAS,KAAK,UAAU,SAAS,KAAK,CAAC,KAAK;AAAA,MAC5C,WAAW,MAAM,SAAS;AAAA,MAC1B,WAAW,MAAM,SAAS;AAAA,MAC1B,QAAQ,KAAK;AAAA,MACb,UAAU,KAAK;AAAA,MACf,kBAAkB,KAAK,IAAI;AAAA,MAC3B,UAAU,QAAQ,KAAK,OAAO;AAAA,MAC9B,SAAS,KAAK;AAAA,IAChB;AACA,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,IAAI,WAA+B;AACjC,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,YAAkC;AAChC,UAAM,IAAI,KAAK;AACf,SAAK,QAAQ,CAAC;AACd,WAAO;AAAA,EACT;AAAA;AAAA,EAIQ,YAAY,MAAoB;AACtC,QAAI,KAAK,QAAS,OAAM,IAAI,iBAAiB,oDAAoD,IAAI,GAAG;AAAA,EAC1G;AAAA,EAEQ,OAAO,OAAe,MAAgC;AAC5D,SAAK,UAAU,KAAK,EAAE,OAAO,QAAQ,KAAK,KAAK,OAAO,KAAK,CAAC;AAC5D,QAAI,KAAK,UAAU,SAAS,KAAK,aAAc,MAAK,UAAU,MAAM;AACpE,SAAK,YAAY,CAAC;AAClB,SAAK,MAAM;AACX,SAAK,KAAK;AAAA,EACZ;AAAA,EAEA,OAAsB;AACpB,SAAK,YAAY,SAAS;AAC1B,UAAM,IAAI,KAAK,UAAU,IAAI;AAC7B,QAAI,CAAC,EAAG,QAAO;AACf,SAAK,UAAU,KAAK,CAAC;AACrB,SAAK,MAAM,EAAE;AACb,SAAK,KAAK;AACV,WAAO,EAAE;AAAA,EACX;AAAA,EAEA,OAAsB;AACpB,SAAK,YAAY,SAAS;AAC1B,UAAM,IAAI,KAAK,UAAU,IAAI;AAC7B,QAAI,CAAC,EAAG,QAAO;AACf,SAAK,UAAU,KAAK,CAAC;AACrB,SAAK,MAAM,EAAE;AACb,SAAK,KAAK;AACV,WAAO,EAAE;AAAA,EACX;AAAA;AAAA,EAGA,gBAAoD;AAClD,WAAO,EAAE,MAAM,KAAK,UAAU,IAAI,CAAC,MAAM,EAAE,KAAK,GAAG,MAAM,KAAK,UAAU,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE;AAAA,EACxG;AAAA;AAAA,EAIQ,aAAa,OAA4E;AAC/F,QAAI,OAAO,UAAU,UAAU;AAC7B,YAAM,IAAI,YAAY,KAAK;AAC3B,UAAI,CAAC,EAAG,OAAM,IAAI,iBAAiB,kBAAkB,KAAK,kCAAkC;AAC5F,aAAO;AAAA,IACT;AACA,WAAO,SAAS,CAAC;AAAA,EACnB;AAAA;AAAA,EAGA,UAAU,UAA8E,CAAC,GAAuB;AAC9G,SAAK,YAAY,uBAAuB;AACxC,UAAM,OAAO,oBAAoB;AAAA,MAC/B,OAAO,QAAQ,SAAS,KAAK,IAAI,OAAO;AAAA,MACxC,QAAQ,QAAQ,UAAU,KAAK,IAAI,OAAO;AAAA,MAC1C,KAAK,QAAQ,OAAO,KAAK,IAAI,OAAO;AAAA,MACpC,OAAO,QAAQ,UAAU,SAAY,KAAK,IAAI,QAAQ,KAAK,aAAa,QAAQ,KAAK;AAAA,IACvF,CAAC;AACD,SAAK,aAAa,CAAC;AACnB,SAAK,SAAS,EAAE,GAAG,KAAK,QAAQ,UAAU,EAAE,GAAG,KAAK,OAAO,UAAU,QAAQ,EAAE,GAAG,KAAK,OAAO,QAAQ,GAAG,GAAG,KAAK,OAAO,SAAS,EAAE,EAAE,GAAG,SAAS,KAAK;AACtJ,SAAK;AACL,SAAK,OAAO,cAAc,IAAI;AAC9B,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,UAAU,QAA2C;AACnD,SAAK,YAAY,qBAAqB;AACtC,UAAM,SAAS,gBAAgB;AAAA,MAC7B,OAAO,OAAO,SAAS,KAAK,IAAI,OAAO;AAAA,MACvC,QAAQ,OAAO,UAAU,KAAK,IAAI,OAAO;AAAA,MACzC,KAAK,OAAO,OAAO,KAAK,IAAI,OAAO;AAAA,IACrC,CAAC;AACD,SAAK,OAAO,eAAe,EAAE,GAAG,KAAK,KAAK,OAAO,CAAC;AAClD,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,SAAS,QAAqE;AAC5E,SAAK,YAAY,oBAAoB;AACrC,QAAI,OAAO,KAAK,IAAI;AACpB,QAAI,OAAO,WAAW,UAAa,OAAO,WAAW,KAAK,IAAI,MAAM,QAAQ;AAC1E,YAAM,IAAI,YAAY,OAAO,MAAM;AACnC,UAAI,CAAC,EAAG,OAAM,IAAI,iBAAiB,kBAAkB,OAAO,MAAM,kCAAkC;AACpG,aAAO;AAAA,IACT;AACA,UAAM,EAAE,QAAQ,IAAI,GAAG,KAAK,IAAI;AAChC,QAAI,KAAK,UAAU,OAAW,YAAW,KAAK,OAAO,aAAa;AAClE,UAAM,QAAQ,eAAe,EAAE,GAAG,MAAM,QAAQ,KAAK,OAAO,GAAG,IAAI;AACnE,UAAM,cAAc,OAAO,KAAK,IAAI,EAAE,OAAO,CAAC,MAAM,MAAM,MAAM;AAChE,QAAI,YAAY,UAAU,OAAO,WAAW,OAAW,OAAM,SAAS,KAAK;AAC3E,SAAK,OAAO,SAAS,EAAE,GAAG,KAAK,KAAK,MAAM,CAAC;AAC3C,WAAO,WAAW,KAAK;AAAA,EACzB;AAAA;AAAA,EAIA,SAAS,IAAoC;AAC3C,WAAO,UAAU,KAAK,IAAI,QAAQ,EAAE,GAAG;AAAA,EACzC;AAAA;AAAA,EAGA,iBAAyC;AACvC,WAAO,KAAK,IAAI,gBAAgB,KAAK,SAAS,KAAK,IAAI,aAAa,IAAI;AAAA,EAC1E;AAAA;AAAA,EAGA,aAA+B;AAC7B,UAAM,MAAwB,CAAC;AAC/B,UAAM,OAAO,CAAC,MAA6B,UAAyB,UAAkB;AACpF,eAAS,IAAI,KAAK,SAAS,GAAG,KAAK,GAAG,KAAK;AACzC,cAAM,IAAI,KAAK,CAAC;AAChB,YAAI,KAAK,KAAK,cAAc,GAAG,UAAU,KAAK,CAAC;AAC/C,YAAI,EAAE,SAAS,QAAS,MAAK,EAAE,UAAU,EAAE,IAAI,QAAQ,CAAC;AAAA,MAC1D;AAAA,IACF;AACA,SAAK,KAAK,IAAI,QAAQ,MAAM,CAAC;AAC7B,WAAO;AAAA,EACT;AAAA,EAEA,cAAc,GAAe,WAA0B,UAAU,KAAK,IAAI,QAAQ,EAAE,EAAE,GAAG,QAAQ,MAAM,MAAM,QAAQ,UAAU,KAAK,IAAI,QAAQ,EAAE,EAAE,GAAG,KAAK,UAAU,GAAmB;AACvL,QAAI,SAA4B;AAChC,QAAI,EAAE,SAAS,SAAS;AACtB,YAAM,IAAI,cAAc,EAAE,OAAO;AACjC,eAAS,IAAI,EAAE,GAAG,GAAG,GAAG,EAAE,IAAI,EAAE,OAAO,GAAG,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI;AAAA,IACpE,MAAO,YAAW,KAAK,cAAc,EAAE,QAAQ,EAAG,KAAI,EAAE,SAAS,QAAS,UAAS,UAAU,QAAQ,KAAK,cAAc,GAAG,EAAE,IAAI,QAAQ,CAAC,EAAE,MAAM;AAClJ,WAAO;AAAA,MACL,IAAI,EAAE;AAAA,MACN,MAAM,EAAE;AAAA,MACR,MAAM,EAAE;AAAA,MACR,SAAS,EAAE;AAAA,MACX,SAAS,EAAE;AAAA,MACX,OAAO,EAAE;AAAA,MACT,SAAS,QAAQ,EAAE,OAAO;AAAA,MAC1B,OAAO,EAAE,GAAI,EAAE,SAAS,CAAC,EAAG;AAAA,MAC5B,QAAQ,EAAE,OAAO,KAAK,IAAI;AAAA,MAC1B;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,aAAa,IAAwB;AAC3C,UAAM,IAAI,KAAK,SAAS,EAAE;AAC1B,QAAI,CAAC,EAAG,OAAM,IAAI,iBAAiB,kBAAkB,EAAE,kCAAkC;AACzF,WAAO;AAAA,EACT;AAAA;AAAA,EAGQ,YAAY,SAA6B,MAA+B;AAC9E,UAAM,KAAK,WAAW,KAAK,IAAI;AAC/B,QAAI,CAAC,GAAI,OAAM,IAAI,iBAAiB,+BAA+B,IAAI,2BAA2B;AAClG,UAAM,IAAI,KAAK,aAAa,EAAE;AAC9B,QAAI,CAAC,aAAa,CAAC,EAAG,OAAM,IAAI,iBAAiB,UAAU,EAAE,IAAI,iBAAiB,IAAI,2BAA2B;AACjH,QAAI,cAAc,GAAG,QAAQ,EAAG,OAAM,IAAI,iBAAiB,UAAU,EAAE,IAAI,sEAAsE,IAAI,MAAM;AAC3J,QAAI,CAAC,EAAE,QAAS,OAAM,IAAI,iBAAiB,UAAU,EAAE,IAAI,+DAA+D,IAAI,MAAM;AACpI,WAAO;AAAA,EACT;AAAA,EAEA,eAAe,IAAkB;AAC/B,SAAK,aAAa,EAAE;AACpB,QAAI,KAAK,IAAI,kBAAkB,GAAI;AAEnC,SAAK,MAAM,EAAE,GAAG,KAAK,KAAK,eAAe,GAAG;AAC5C,SAAK,KAAK;AAAA,EACZ;AAAA;AAAA,EAGA,SAAS,UAAmG,CAAC,GAAmB;AAC9H,SAAK,YAAY,gBAAgB;AACjC,UAAM,QAAQ,cAAc,KAAK,IAAI,MAAM,EAAE;AAC7C,UAAM,OAAO,QAAQ,QAAQ;AAC7B,UAAM,OAAO,QAAQ,MAAM,KAAK,MAAM,SAAS,UAAU,SAAS,QAAQ,CAAC,KAAK,SAAS,QAAQ,CAAC;AAClG,UAAM,QACJ,SAAS,UAAU,EAAE,MAAM,SAAS,IAAI,gBAAgB,GAAG,MAAM,SAAS,MAAM,SAAS,GAAG,OAAO,gBAAgB,UAAU,CAAC,EAAE,IAAI,iBAAiB,IAAI;AAC3J,QAAI,WAA0B;AAC9B,QAAI;AACJ,UAAM,QAAQ,QAAQ,YAAY,QAAQ,aAAa,SAAY,KAAK,IAAI,gBAAgB;AAC5F,QAAI,QAAQ,aAAa,UAAa,QAAQ,aAAa,MAAM;AAC/D,YAAM,IAAI,KAAK,aAAa,QAAQ,QAAQ;AAC5C,UAAI,EAAE,SAAS,QAAS,OAAM,IAAI,iBAAiB,UAAU,EAAE,IAAI,gDAAgD;AACnH,iBAAW,EAAE;AAAA,IACf,WAAW,OAAO;AAChB,YAAM,MAAM,UAAU,KAAK,IAAI,QAAQ,KAAK;AAC5C,UAAI,CAAC,IAAK,OAAM,IAAI,iBAAiB,kBAAkB,KAAK,kCAAkC;AAC9F,iBAAW,IAAI,QAAQ,MAAM;AAC7B,cAAQ,IAAI,QAAQ;AAAA,IACtB;AACA,UAAM,SAAS,YAAY,KAAK,IAAI,QAAQ,OAAO,UAAU,KAAK;AAClE,SAAK,OAAO,SAAS,UAAU,cAAc,aAAa,EAAE,GAAG,KAAK,KAAK,QAAQ,eAAe,MAAM,GAAG,CAAC;AAC1G,WAAO,KAAK,cAAc,KAAK;AAAA,EACjC;AAAA,EAEA,YAAY,IAAY,QAAqC;AAC3D,SAAK,YAAY,kBAAkB;AACnC,UAAM,IAAI,KAAK,aAAa,EAAE;AAC9B,QAAI,cAAc,GAAG,KAAK,KAAK,OAAO,KAAK,MAAM,EAAE,KAAK,CAAC,MAAM,MAAM,OAAO,EAAG,OAAM,IAAI,iBAAiB,UAAU,EAAE,IAAI,0DAA0D;AACpL,QAAI,OAAO,YAAY,UAAa,EAAE,OAAO,WAAW,KAAK,OAAO,WAAW,GAAI,OAAM,IAAI,iBAAiB,WAAW,OAAO,OAAO,6BAA6B;AACpK,QAAI,OAAO,UAAU,UAAa,CAAC,YAAY,OAAO,KAAK,KAAK,EAAE,EAAE,SAAS,WAAW,OAAO,UAAU,iBAAiB;AACxH,YAAM,IAAI,iBAAiB,uBAAuB,OAAO,KAAK,8CAA8C;AAAA,IAC9G;AACA,QAAI,OAAO,SAAS,UAAa,CAAC,OAAO,KAAK,KAAK,EAAG,OAAM,IAAI,iBAAiB,uCAAuC;AACxH,UAAM,OAAO,EAAE,GAAG,EAAE;AACpB,QAAI,OAAO,SAAS,OAAW,MAAK,OAAO,OAAO,KAAK,KAAK;AAC5D,QAAI,OAAO,YAAY,OAAW,MAAK,UAAU,OAAO;AACxD,QAAI,OAAO,YAAY,OAAW,MAAK,UAAU,OAAO;AACxD,QAAI,OAAO,UAAU,OAAW,CAAC,KAA2B,QAAQ,OAAO;AAC3E,QAAI,OAAO,YAAY,OAAW,MAAK,UAAU,OAAO,WAAW;AACnE,QAAI,OAAO,UAAU,QAAW;AAC9B,YAAM,QAAQ,EAAE,GAAI,EAAE,SAAS,CAAC,GAAI,GAAG,OAAO,MAAM;AACpD,WAAK,QAAQ,OAAO,OAAO,KAAK,EAAE,KAAK,OAAO,IAAI,QAAQ;AAAA,IAC5D;AACA,SAAK,OAAO,oBAAoB,EAAE,GAAG,KAAK,KAAK,QAAQ,SAAS,KAAK,IAAI,QAAQ,IAAI,MAAM,IAAI,EAAE,CAAC;AAClG,WAAO,KAAK,cAAc,IAAI;AAAA,EAChC;AAAA,EAEA,YAAY,IAA+D;AACzE,SAAK,YAAY,kBAAkB;AACnC,UAAM,IAAI,KAAK,aAAa,EAAE;AAC9B,QAAI,cAAc,GAAG,KAAK,EAAG,OAAM,IAAI,iBAAiB,UAAU,EAAE,IAAI,kDAAkD;AAC1H,UAAM,SAAS,SAAS,KAAK,IAAI,QAAQ,IAAI,MAAM,IAAI;AACvD,QAAI,SAAS,KAAK,IAAI;AACtB,QAAI,UAAU,CAAC,UAAU,QAAQ,MAAM,EAAG,UAAS,cAAc,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,SAAS,OAAO,EAAE,IAAI,GAAG,MAAM;AACxH,SAAK,OAAO,gBAAgB,EAAE,GAAG,KAAK,KAAK,QAAQ,eAAe,OAAO,CAAC;AAC1E,WAAO,EAAE,SAAS,IAAI,eAAe,OAAO;AAAA,EAC9C;AAAA,EAEA,eAAe,IAA4B;AACzC,SAAK,YAAY,qBAAqB;AACtC,UAAM,MAAM,UAAU,KAAK,IAAI,QAAQ,EAAE;AACzC,QAAI,CAAC,IAAK,OAAM,IAAI,iBAAiB,kBAAkB,EAAE,kCAAkC;AAC3F,UAAM,OAAO,CAAC,MAA+B,EAAE,SAAS,UAAU,EAAE,GAAG,GAAG,IAAI,gBAAgB,GAAG,UAAU,EAAE,SAAS,IAAI,IAAI,EAAE,IAAI,EAAE,GAAG,GAAG,IAAI,gBAAgB,EAAE;AAClK,UAAM,MAAM,EAAE,GAAG,KAAK,IAAI,KAAK,GAAG,MAAM,GAAG,IAAI,MAAM,IAAI,QAAQ;AACjE,UAAM,SAAS,YAAY,KAAK,IAAI,QAAQ,KAAK,IAAI,QAAQ,MAAM,MAAM,IAAI,QAAQ,CAAC;AACtF,SAAK,OAAO,mBAAmB,EAAE,GAAG,KAAK,KAAK,QAAQ,eAAe,IAAI,GAAG,CAAC;AAC7E,WAAO,KAAK,cAAc,GAAG;AAAA,EAC/B;AAAA;AAAA,EAGA,UAAU,IAAY,OAAe,UAA0C;AAC7E,SAAK,YAAY,gBAAgB;AACjC,UAAM,MAAM,UAAU,KAAK,IAAI,QAAQ,EAAE;AACzC,QAAI,CAAC,IAAK,OAAM,IAAI,iBAAiB,kBAAkB,EAAE,kCAAkC;AAC3F,UAAM,SAAS,aAAa,SAAa,IAAI,QAAQ,MAAM,OAAQ;AACnE,QAAI,QAAQ;AACV,YAAM,IAAI,KAAK,aAAa,MAAM;AAClC,UAAI,EAAE,SAAS,QAAS,OAAM,IAAI,iBAAiB,UAAU,EAAE,IAAI,gDAAgD;AACnH,UAAI,WAAW,MAAO,IAAI,MAAM,SAAS,WAAW,UAAU,IAAI,MAAM,UAAU,MAAM,EAAI,OAAM,IAAI,iBAAiB,kCAAkC;AAAA,IAC3J;AACA,UAAM,UAAU,SAAS,KAAK,IAAI,QAAQ,IAAI,MAAM,IAAI;AACxD,UAAM,WAAW,SAAU,UAAU,SAAS,MAAM,EAAG,MAAqC,WAAW;AACvG,QAAI,CAAC,OAAO,UAAU,KAAK,KAAK,QAAQ,KAAK,QAAQ,SAAS,OAAQ,OAAM,IAAI,iBAAiB,SAAS,KAAK,4BAA4B,SAAS,MAAM,qBAAqB;AAC/K,UAAM,SAAS,YAAY,SAAS,IAAI,OAAO,QAAQ,KAAK;AAC5D,SAAK,OAAO,cAAc,EAAE,GAAG,KAAK,KAAK,OAAO,CAAC;AACjD,WAAO,KAAK,cAAc,IAAI,KAAK;AAAA,EACrC;AAAA;AAAA,EAGA,UAAU,IAA4B;AACpC,SAAK,YAAY,SAAS;AAC1B,UAAM,MAAM,UAAU,KAAK,IAAI,QAAQ,EAAE;AACzC,QAAI,CAAC,IAAK,OAAM,IAAI,iBAAiB,kBAAkB,EAAE,kCAAkC;AAC3F,UAAM,WAAW,IAAI,SAAS,IAAI,OAAO,WAAW,KAAK,IAAI;AAC7D,UAAM,QAAQ,SAAS,IAAI,QAAQ,CAAC;AACpC,UAAM,QAAQ,IAAI;AAClB,QAAI,CAAC,aAAa,KAAK,KAAK,CAAC,aAAa,KAAK,EAAG,OAAM,IAAI,iBAAiB,sFAAsF;AACnK,QAAI,cAAc,OAAO,QAAQ,EAAG,OAAM,IAAI,iBAAiB,UAAU,MAAM,IAAI,sDAAsD;AACzI,UAAM,OAAO,UAAU,KAAK,cAAc,KAAK,EAAE,QAAQ,KAAK,cAAc,KAAK,EAAE,MAAM;AACzF,QAAI,UAAU,aAAa,CAAC;AAC5B,QAAI,MAAM;AACR,YAAM,OAAwB,EAAE,GAAG,OAAO,SAAS,GAAG,OAAO,UAAU,SAAS,MAAM,SAAS,QAAW,MAAM,OAAU;AAC1H,YAAM,KAAK,sBAAsB,EAAE,UAAU,CAAC,MAAM,MAAM,UAAU,QAAQ,EAAE,GAAG,OAAO,SAAS,EAAE,CAAC,GAAkB,MAAM,KAAK,QAAQ,CAAC;AAC1I,gBAAU,kBAAkB,EAAE,OAAO,KAAK,OAAO,QAAQ,KAAK,QAAQ,MAAM,GAAG,GAAG,GAAG,KAAK,GAAG,KAAK,CAAC;AAAA,IACrG;AACA,UAAM,SAA0B,EAAE,GAAG,OAAO,SAAS,QAAQ,EAAE,GAAG,GAAG,GAAG,EAAE,EAAE;AAC5E,UAAM,SAAS,SAAS,SAAS,KAAK,IAAI,QAAQ,MAAM,IAAI,MAAM,IAAI,GAAG,MAAM,IAAI,MAAM,MAAM;AAC/F,SAAK,OAAO,cAAc,EAAE,GAAG,KAAK,KAAK,QAAQ,eAAe,MAAM,GAAG,CAAC;AAC1E,WAAO,KAAK,cAAc,MAAM;AAAA,EAClC;AAAA;AAAA,EAGA,WAAW,SAAkE;AAC3E,SAAK,YAAY,UAAU;AAC3B,UAAM,IAAI,KAAK,YAAY,SAAS,OAAO;AAC3C,UAAM,SAAS,KAAK,cAAc,CAAC,EAAE;AACrC,SAAK,OAAO,eAAe,EAAE,GAAG,KAAK,KAAK,QAAQ,SAAS,KAAK,IAAI,QAAQ,EAAE,IAAI,OAAO,EAAE,GAAG,GAAG,SAAS,aAAa,CAAC,EAAE,EAAE,EAAE,CAAC;AAC/H,WAAO,EAAE,SAAS,EAAE,IAAI,OAAO;AAAA,EACjC;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,UAAU,UAA4B,CAAC,GAA4C;AACjF,SAAK,YAAY,SAAS;AAC1B,UAAM,IAAI,KAAK,YAAY,QAAQ,SAAS,MAAM;AAClD,UAAM,QAAQ,QAAQ,UAAU,SAAY,KAAK,QAAQ,WAAW,QAAQ,KAAK;AACjF,UAAM,UAAU,QAAQ,WAAW;AACnC,QAAI,EAAE,WAAW,KAAK,WAAW,GAAI,OAAM,IAAI,iBAAiB,WAAW,OAAO,6BAA6B;AAC/G,UAAM,cAAc,QAAQ,SAAS;AACrC,QAAI,EAAE,eAAe,KAAK,eAAe,GAAI,OAAM,IAAI,iBAAiB,SAAS,WAAW,6BAA6B;AACzH,UAAM,WAAW,QAAQ,YAAY;AACrC,UAAM,QAAQ,QAAQ,SAAS;AAC/B,QAAI,CAAC,YAAY,KAAK,EAAG,OAAM,IAAI,iBAAiB,uBAAuB,KAAK,IAAI;AACpF,UAAM,EAAE,OAAO,OAAO,IAAI,KAAK,IAAI;AACnC,UAAM,OAAO,EAAE,GAAG,GAAG,GAAG,GAAG,OAAO,OAAO;AACzC,UAAM,WAAW,IAAI,YAAY;AACjC,UAAM,QAAQ,cAAc,KAAK,IAAI,MAAM;AAC3C,UAAM,QAAQ,QAAQ,IAAI,WAAW,KAAK,IAAI,KAAK,IAAI;AACvD,eAAW,EAAE,IAAI,GAAG,KAAK,YAAY,IAAI,GAAG;AAC1C,YAAM,IAAI,EAAE,GAAG,KAAK,MAAM,GAAG,KAAK,MAAM,OAAO,KAAK,IAAI,MAAM,QAAQ,KAAK,IAAI,GAAG,QAAQ,KAAK,IAAI,MAAM,SAAS,KAAK,IAAI,EAAE;AAC7H,YAAM,OAAO,IAAI,aAAa,EAAE,QAAQ,EAAE,MAAM;AAChD,eAAS,IAAI,GAAG,IAAI,GAAG,IAAI,EAAE,QAAQ,IAAK,UAAS,IAAI,GAAG,IAAI,EAAE,OAAO,KAAK,IAAK,MAAK,CAAC,IAAI,QAAQ,WAAW,MAAM,GAAG,EAAE,IAAI,IAAI,KAAK,EAAE,IAAI,IAAI,GAAG,GAAG,OAAO,QAAQ,IAAI;AACzK,eAAS,WAAW,GAAG,MAAM,CAAC;AAAA,IAChC;AACA,UAAM,QAAqB;AAAA,MACzB,MAAM;AAAA,MACN,OAAO,OAAO,KAAK;AAAA,MACnB,YAAY,OAAO,KAAK,IAAI,MAAM,KAAK;AAAA,MACvC;AAAA,MACA;AAAA,MACA,kBAAkB,cAAc,GAAG,cAAc;AAAA,MACjD,WAAW;AAAA,MACX,QAAQ,EAAE;AAAA,IACZ;AACA,UAAM,UAAU,KAAK,cAAc,GAAG,UAAU,MAAM,KAAK;AAC3D,SAAK,OAAO,cAAc,EAAE,GAAG,KAAK,KAAK,QAAQ,SAAS,KAAK,IAAI,QAAQ,EAAE,IAAI,OAAO,EAAE,GAAG,GAAG,QAAQ,EAAE,EAAE,CAAC;AAC7G,WAAO,EAAE,SAAS,EAAE,IAAI,QAAQ,KAAK;AAAA,EACvC;AAAA,EAEQ,cAAc,GAAoB,UAAuB,MAAkB,OAAkC;AACnH,UAAM,OAAO,EAAE;AACf,UAAM,QAAQ,IAAI,IAAI,KAAK,KAAK;AAChC,eAAW,EAAE,IAAI,GAAG,KAAK,YAAY,EAAE,GAAG,KAAK,IAAI,EAAE,OAAO,GAAG,GAAG,KAAK,IAAI,EAAE,OAAO,GAAG,OAAO,KAAK,OAAO,QAAQ,KAAK,OAAO,CAAC,GAAG;AAChI,YAAM,MAAM,QAAQ,IAAI,EAAE;AAC1B,YAAM,MAAM,KAAK,MAAM,IAAI,GAAG,GAAG,QAAQ,IAAI,kBAAkB,OAAO,OAAO,CAAC;AAC9E,YAAM,OAAO,WAAW,kBAAkB,UAAU,KAAK,GAAG,IAAI,IAAI,KAAK,GAAG,GAAG,CAAC;AAChF,UAAI,KAAM,OAAM,IAAI,KAAK,IAAI;AAAA,UACxB,OAAM,OAAO,GAAG;AAAA,IACvB;AACA,WAAO,IAAI,aAAa,GAAG,OAAO,CAAC;AAAA,EACrC;AAAA;AAAA,EAIQ,UAAU,IAAoC;AACpD,WAAO,gBAAgB,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,KAAK,YAAY,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE;AAAA,EAC7F;AAAA;AAAA,EAGA,SAAS,IAAoC;AAC3C,UAAM,IAAI,KAAK,UAAU,EAAE;AAC3B,WAAO,IAAI,oBAAoB,GAAG,CAAC,IAAI;AAAA,EACzC;AAAA,EAEQ,aAAa,IAAwB;AAC3C,UAAM,IAAI,KAAK,UAAU,EAAE;AAC3B,QAAI,CAAC,EAAG,OAAM,IAAI,iBAAiB,kBAAkB,EAAE,mCAAmC;AAC1F,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,SAAS,SAAwD,CAAC,GAAe;AAC/E,UAAM,EAAE,IAAI,GAAG,QAAQ,IAAI;AAC3B,UAAM,OAAO,OAAO,SAAY,KAAK,aAAa,EAAE,IAAI,KAAK;AAC7D,UAAM,OAAO,oBAAoB,EAAE,GAAG,SAAS,IAAI,KAAK,GAAG,GAAG,IAAI;AAElE,QAAI,KAAK,WAAW,CAAC,OAAO,KAAK,OAAO,EAAE,OAAQ,MAAK,UAAU;AAAA,QAC5D,QAAO,KAAK;AACjB,SAAK,QAAQ;AACb,SAAK,KAAK,CAAC,CAAC;AACZ,WAAO,KAAK;AAAA,EACd;AAAA;AAAA,EAGA,UAAU,SAA6E;AACrF,QAAI,CAAC,SAAS,KAAK,QAAQ,EAAE,EAAG,OAAM,IAAI,iBAAiB,aAAa,QAAQ,EAAE,4EAA4E;AAC9J,QAAI,gBAAgB,KAAK,CAAC,MAAM,EAAE,OAAO,QAAQ,EAAE,EAAG,OAAM,IAAI,iBAAiB,IAAI,QAAQ,EAAE,+CAA+C;AAC9I,UAAM,SAAS,QAAQ,QAAQ,oBAAoB,QAAQ,OAAO,KAAK,KAAK,IAAI,KAAK;AACrF,UAAM,QAAQ,oBAAoB,EAAE,GAAG,QAAQ,IAAI,QAAQ,IAAI,MAAM,QAAQ,QAAQ,OAAO,KAAK,CAAC;AAClG,WAAO,MAAM;AACb,UAAM,IAAI,KAAK,YAAY,UAAU,CAAC,MAAM,EAAE,OAAO,QAAQ,EAAE;AAC/D,QAAI,KAAK,EAAG,MAAK,YAAY,CAAC,IAAI;AAAA,QAC7B,MAAK,YAAY,KAAK,KAAK;AAChC,SAAK,KAAK,CAAC,CAAC;AACZ,WAAO;AAAA,EACT;AAAA,EAEA,YAAY,IAAkB;AAC5B,QAAI,gBAAgB,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,EAAG,OAAM,IAAI,iBAAiB,IAAI,EAAE,8CAA8C;AAC7H,UAAM,IAAI,KAAK,YAAY,UAAU,CAAC,MAAM,EAAE,OAAO,EAAE;AACvD,QAAI,IAAI,EAAG,OAAM,IAAI,iBAAiB,kBAAkB,EAAE,mCAAmC;AAC7F,SAAK,YAAY,OAAO,GAAG,CAAC;AAC5B,SAAK,KAAK,CAAC,CAAC;AAAA,EACd;AAAA;AAAA,EAGA,iBAA+B;AAC7B,WAAO,KAAK,YAAY,IAAI,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC;AAAA,EAC9D;AAAA;AAAA,EAGA,cAAc,KAA2C;AACvD,UAAM,OAAO,MAAM,IAAI,IAAI,CAAC,OAAO,KAAK,aAAa,EAAE,CAAC,IAAI,KAAK;AACjE,WAAO,EAAE,QAAQ,oBAAoB,SAAS,GAAG,SAAS,KAAK,IAAI,WAAW,EAAE;AAAA,EAClF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,cAAc,MAAe,UAAiC,CAAC,GAA+D;AAC5H,UAAM,WAAqB,CAAC;AAC5B,QAAI;AACJ,QAAI;AACF,aAAO,kBAAkB,MAAM,QAAQ;AAAA,IACzC,SAAS,GAAG;AACV,YAAM,IAAI,iBAAkB,EAAY,OAAO;AAAA,IACjD;AACA,UAAM,QAAkB,CAAC;AACzB,UAAM,UAAoB,CAAC;AAC3B,eAAW,KAAK,MAAM;AACpB,UAAI,gBAAgB,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,EAAE,GAAG;AAC9C,gBAAQ,KAAK,EAAE,EAAE;AACjB,iBAAS,KAAK,IAAI,EAAE,EAAE,mDAAmD;AACzE;AAAA,MACF;AACA,YAAM,IAAI,KAAK,YAAY,UAAU,CAAC,MAAM,EAAE,OAAO,EAAE,EAAE;AACzD,UAAI,KAAK,KAAK,CAAC,QAAQ,SAAS;AAC9B,gBAAQ,KAAK,EAAE,EAAE;AACjB;AAAA,MACF;AACA,UAAI,KAAK,EAAG,MAAK,YAAY,CAAC,IAAI;AAAA,UAC7B,MAAK,YAAY,KAAK,CAAC;AAC5B,YAAM,KAAK,EAAE,EAAE;AAAA,IACjB;AACA,QAAI,MAAM,OAAQ,MAAK,KAAK,CAAC,CAAC;AAC9B,WAAO,EAAE,OAAO,SAAS,SAAS;AAAA,EACpC;AAAA;AAAA,EAGA,eAAe,IAAY,UAA+D,CAAC,GAAmB;AAC5G,UAAM,IAAI,OAAO,KAAK,MAAM,KAAK,KAAK,QAAQ,KAAK,aAAa,EAAE;AAClE,WAAO,qBAAqB,GAAG,EAAE,OAAO,KAAK,IAAI,OAAO,OAAO,QAAQ,OAAO,QAAQ,QAAQ,QAAQ,OAAO,QAAQ,QAAQ,WAAW,QAAQ,KAAK,IAAI,KAAK,MAAM,CAAC;AAAA,EACvK;AAAA;AAAA,EAIA,SAAS,OAAuB;AAC9B,SAAK,QAAQ,WAAW,KAAK;AAC7B,SAAK,KAAK,CAAC,CAAC;AACZ,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,kBAAkB,OAAuB;AACvC,SAAK,iBAAiB,WAAW,KAAK;AACtC,SAAK,KAAK,CAAC,CAAC;AACZ,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,aAAmB;AACjB,KAAC,KAAK,OAAO,KAAK,cAAc,IAAI,CAAC,KAAK,gBAAgB,KAAK,KAAK;AACpE,SAAK,KAAK,CAAC,CAAC;AAAA,EACd;AAAA;AAAA,EAGA,UAAU,GAAW,GAAW,UAAgC,CAAC,GAAqC;AACpG,UAAM,EAAE,OAAO,OAAO,IAAI,KAAK,IAAI;AACnC,UAAM,KAAK,KAAK,MAAM,CAAC;AACvB,UAAM,KAAK,KAAK,MAAM,CAAC;AACvB,QAAI,EAAE,MAAM,KAAK,MAAM,KAAK,KAAK,SAAS,KAAK,QAAS,OAAM,IAAI,iBAAiB,IAAI,CAAC,KAAK,CAAC,oBAAoB,KAAK,OAAI,MAAM,UAAU;AAC3I,QAAI,QAAQ,YAAY,QAAW;AACjC,YAAM,IAAI,KAAK,aAAa,QAAQ,OAAO;AAC3C,UAAI,CAAC,aAAa,CAAC,EAAG,OAAM,IAAI,iBAAiB,UAAU,EAAE,IAAI,yDAAyD;AAC1H,YAAM,CAAC,GAAG,GAAG,GAAG,CAAC,IAAI,UAAU,EAAE,SAAS,KAAK,EAAE,OAAO,GAAG,KAAK,EAAE,OAAO,CAAC;AAC1E,aAAO,EAAE,OAAO,SAAS,GAAG,GAAG,CAAC,GAAG,OAAO,KAAK,MAAO,IAAI,MAAO,GAAI,IAAI,IAAK;AAAA,IAChF;AACA,UAAM,IAAI,KAAK,iBAAiB,UAAU,KAAK,aAAa,CAAC,CAAC,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,OAAO,GAAG,QAAQ,EAAE,GAAG,KAAK,QAAQ,CAAC;AACtH,WAAO,EAAE,OAAO,SAAS,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,OAAO,KAAK,MAAO,EAAE,CAAC,IAAI,MAAO,GAAI,IAAI,IAAK;AAAA,EAC5F;AAAA;AAAA;AAAA,EAKA,eAAe,OAA2B;AACxC,UAAM,CAAC,GAAG,GAAG,CAAC,IAAI,UAAU,UAAU,SAAY,KAAK,QAAQ,WAAW,KAAK,CAAC;AAChF,SAAK,YAAY,UAAU,KAAK,WAAW,CAAC,IAAI,KAAK,IAAI,KAAK,IAAI,GAAG,CAAC;AACtE,SAAK,KAAK,CAAC,CAAC;AACZ,WAAO,KAAK;AAAA,EACd;AAAA;AAAA,EAGA,gBAAgB,iBAAiB,OAAkB;AACjD,SAAK,YAAY,iBAAiB,mBAAmB,WAAW,KAAK,SAAS;AAC9E,SAAK,KAAK,CAAC,CAAC;AACZ,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA,EAKA,QAAQ,QAAuC;AAC7C,SAAK,OAAO,cAAc,QAAQ,KAAK,IAAI;AAC3C,SAAK,KAAK,CAAC,CAAC;AACZ,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,YAAuB;AACrB,WAAO,KAAK,QAAQ,EAAE,GAAG,cAAc,KAAK,EAAE,GAAG,GAAG,GAAG,EAAE,EAAE,CAAC;AAAA,EAC9D;AAAA,EAEA,QAAQ,MAAkB;AACxB,QAAI,SAAS,UAAU,SAAS,QAAS,OAAM,IAAI,iBAAiB,WAAW,KAAK,UAAU,IAAI,CAAC,0BAA0B;AAC7H,SAAK,OAAO;AACZ,SAAK,KAAK,CAAC,CAAC;AACZ,WAAO;AAAA,EACT;AAAA;AAAA,EAIQ,YAAY,MAAmC;AACrD,QAAI,QAAQ,KAAK,YAAY,SAAY,KAAK,aAAa,KAAK,OAAO,IAAI,KAAK;AAChF,QAAI,KAAK,MAAO,SAAQ,oBAAoB,EAAE,GAAG,KAAK,OAAO,IAAI,MAAM,GAAG,GAAG,KAAK;AAClF,WAAO;AAAA,EACT;AAAA;AAAA,EAGU,eAAyB;AACjC,WAAO,eAAe,KAAK,OAAO,QAAQ;AAAA,EAC5C;AAAA,EAEQ,WAAW,KAAyB,MAAuB,MAA6C;AAC9G,UAAM,SAAS,MAAM;AACnB,YAAM,KAAK,KAAK,WAAW,IAAI;AAC/B,UAAI,CAAC,GAAI,OAAM,IAAI,iBAAiB,+DAA+D;AACnG,YAAM,MAAM,UAAU,IAAI,QAAQ,EAAE;AACpC,UAAI,CAAC,IAAK,OAAM,IAAI,iBAAiB,kBAAkB,EAAE,kCAAkC;AAC3F,YAAM,IAAI,IAAI;AACd,UAAI,CAAC,aAAa,CAAC,EAAG,OAAM,IAAI,iBAAiB,UAAU,EAAE,IAAI,iDAAiD;AAClH,UAAI,cAAc,GAAG,QAAQ,EAAG,OAAM,IAAI,iBAAiB,UAAU,EAAE,IAAI,yEAAyE;AACpJ,UAAI,CAAC,EAAE,QAAS,OAAM,IAAI,iBAAiB,UAAU,EAAE,IAAI,kEAAkE;AAC7H,aAAO;AAAA,IACT,GAAG;AACH,UAAM,QAAQ,KAAK,YAAY,IAAI;AACnC,QAAI,QAAQ,KAAK,UAAU,SAAY,KAAK,QAAQ,WAAW,KAAK,KAAK;AACzE,UAAM,UAAU,KAAK,OAAO;AAC5B,QAAI,KAAK,UAAU,UAAa,KAAK,SAAS,SAAS,WAAW,QAAQ,aAAc,SAAQ,KAAK,mBAAmB,KAAK,MAAM,GAAG,KAAK,MAAM,CAAC,KAAK;AACvJ,UAAM,cAAc,KAAK,OAAO;AAChC,UAAM,UAAU,KAAK,qBAAqB,YAAY,WAAW,YAAY,OAAO,IAAI,mBAAmB,WAAW,IAAI;AAC1H,UAAM,OAAO,OAAO,KAAK;AACzB,UAAM,OAAO,KAAK,QAAQ,MAAO,KAAK,gBAAgB,eAAgB,CAAC,IAAI;AAC3E,UAAM,UAAU,KAAK,UAAU,KAAK,aAAa,GAAG,OAAO,CAAC,MAAM,EAAE,KAAK,CAAC,GAAG,MAAM,MAAM,gBAAgB,CAAC,CAAC,CAAC;AAC5G,UAAM,UAAU,IAAI,mBAAmB,MAAM;AAAA,MAC3C,SAAS,MAAM;AAAA,MACf,SAAS,MAAM;AAAA,MACf,QAAQ,MAAM;AAAA,MACd,kBAAkB,cAAc,OAAO,cAAc;AAAA,MACrD;AAAA,MACA,OAAO;AAAA,MACP,YAAY,OAAO,IAAI,MAAM,KAAK;AAAA,MAClC,OAAO,WAAW,IAAI,KAAK;AAAA,MAC3B,YAAY,IAAI,MAAM;AAAA,MACtB;AAAA,MACA,UAAU;AAAA,MACV,cAAc;AAAA,MACd,QAAQ,CAAC,iBAAiB,GAAG,MAAM,EAAE,IAAI,UAAU;AAAA,MACnD,aAAa,UAAU,CAAC,MAAM,QAAQ,KAAK,CAAC,IAAI;AAAA,MAChD,WAAW,MAAM,WAAW,UAAU,mBAAmB,OAAO,KAAK,WAAW,CAAC,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC,IAAI,GAAG,CAAC,IAAI;AAAA,IACnI,CAAC;AACD,WAAO;AAAA,EACT;AAAA,EAEQ,OAAO,SAA6C;AAC1D,UAAM,OAAO,QAAQ;AACrB,UAAM,SAAyB;AAAA,MAC7B,IAAI,IAAI,KAAK,eAAe;AAAA,MAC5B,SAAS,QAAQ;AAAA,MACjB,OAAO,YAAY,KAAK,KAAK;AAAA,MAC7B,OAAO,KAAK;AAAA,MACZ,QAAQ,QAAQ,OAAO,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,EAAE;AAAA,MAC5C,MAAM,KAAK;AAAA,IACb;AACA,QAAI,KAAK,aAAa,OAAQ,QAAO,SAAS,KAAK,aAAa,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAsB;AACtG,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,YAAY,OAAwB,CAAC,GAAuB;AAC1D,SAAK,YAAY,kBAAkB;AACnC,UAAM,OAA0B;AAAA,MAC9B,QAAQ,CAAC,SAAS,SAAS,UAAU;AACnC,aAAK,OAAO,EAAE,SAAS,QAAQ;AAC/B,aAAK,KAAK,KAAK;AAAA,MACjB;AAAA,MACA,QAAQ,CAAC,GAAG,SAAS,cAAc;AACjC,aAAK,UAAU;AACf,aAAK,OAAO;AACZ,aAAK,aAAa;AAClB,cAAM,QAAQ,EAAE,KAAK;AACrB,YAAI,CAAC,aAAa,EAAE,QAAQ,aAAa,MAAM,WAAY,MAAK,YAAY,EAAE,OAAO;AACrF,YAAI,aAAa,CAAC,SAAS;AACzB,eAAK,KAAK;AACV;AAAA,QACF;AACA,cAAM,SAAS,KAAK,OAAO,CAAC;AAC5B,UAAE,OAAQ,WAAW,OAAO;AAC5B,cAAM,IAAI,KAAK,SAAS,EAAE,OAAO;AACjC,aAAK,OAAO,GAAG,MAAM,IAAI,WAAW,EAAE,GAAG,KAAK,KAAK,QAAQ,SAAS,KAAK,IAAI,QAAQ,EAAE,IAAI,OAAO,EAAE,GAAG,GAAG,QAAQ,EAAE,GAAG,SAAS,CAAC,GAAG,KAAK,IAAI,SAAS,MAAM,EAAE,CAAC;AAAA,MACjK;AAAA,IACF;AACA,UAAM,UAAU,KAAK,WAAW,KAAK,KAAK,EAAE,mBAAmB,MAAM,GAAG,KAAK,GAAG,IAAI;AACpF,SAAK,UAAU;AACf,SAAK,KAAK,CAAC,CAAC;AACZ,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,IAAI,eAA0C;AAC5C,WAAO,KAAK;AAAA,EACd;AAAA;AAAA,EAGQ,UAAU,KAAyB,MAAuB,QAAwG;AACxK,QAAI,MAAM;AACV,UAAM,OAA0B;AAAA,MAC9B,QAAQ,MAAM;AAAA,MAAC;AAAA,MACf,QAAQ,CAAC,GAAG,SAAS,cAAc;AACjC,YAAI,aAAa,CAAC,QAAS;AAC3B,cAAM,SAAS,KAAK,OAAO,CAAC;AAC5B,UAAE,OAAQ,WAAW,OAAO;AAC5B,cAAM,IAAI,UAAU,IAAI,QAAQ,EAAE,OAAO,EAAG;AAC5C,cAAM,EAAE,GAAG,KAAK,QAAQ,SAAS,IAAI,QAAQ,EAAE,IAAI,OAAO,EAAE,GAAG,GAAG,QAAQ,EAAE,GAAG,SAAS,CAAC,GAAG,IAAI,SAAS,MAAM,EAAE;AAAA,MACnH;AAAA,IACF;AACA,UAAM,UAAU,KAAK,WAAW,KAAK,MAAM,IAAI;AAC/C,YAAQ,KAAK,MAAM;AACnB,UAAM,SAAS,QAAQ,IAAI;AAC3B,WAAO,EAAE,KAAK,KAAK,QAAQ,OAAO,QAAQ,KAAK,MAAM;AAAA,EACvD;AAAA;AAAA,EAGA,YAAY,MAA4E;AACtF,SAAK,YAAY,UAAU;AAC3B,UAAM,SAAS,KAAK,YAAY,KAAK,MAAM;AAC3C,UAAM,EAAE,KAAK,QAAQ,MAAM,IAAI,KAAK,UAAU,KAAK,KAAK,EAAE,GAAG,MAAM,OAAO,KAAK,SAAS,OAAO,CAAC,EAAE,GAAG,MAAM;AAC3G,QAAI,OAAO,aAAa,MAAM,WAAY,MAAK,YAAY,OAAO;AAClE,QAAI,QAAQ,KAAK,IAAK,MAAK,OAAO,GAAG,MAAM,IAAI,WAAW,GAAG;AAAA,QACxD,MAAK,KAAK,CAAC,CAAC;AACjB,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,YAAY,QAAyC;AACnD,QAAI,CAAC,MAAM,QAAQ,MAAM,KAAK,CAAC,OAAO,OAAQ,OAAM,IAAI,iBAAiB,+DAA+D;AACxI,UAAM,MAAkB,CAAC;AACzB,WAAO,QAAQ,CAAC,GAAG,MAAM;AACvB,UAAI,CAAC,KAAK,CAAC,OAAO,SAAS,EAAE,CAAC,KAAK,CAAC,OAAO,SAAS,EAAE,CAAC,EAAG,OAAM,IAAI,iBAAiB,UAAU,CAAC,4CAA4C;AAC5I,UAAI,EAAE,aAAa,UAAa,EAAE,EAAE,YAAY,KAAK,EAAE,YAAY,GAAI,OAAM,IAAI,iBAAiB,UAAU,CAAC,cAAc,EAAE,QAAQ,6BAA6B;AAClK,UAAI,KAAK,CAAC;AAAA,IACZ,CAAC;AACD,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,aAAwC;AACtC,WAAO,KAAK,IAAI;AAAA,EAClB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,cAAc,SAAgG;AAC5G,SAAK,YAAY,WAAW;AAC5B,QAAI,CAAC,QAAQ,WAAW,OAAQ,OAAM,IAAI,iBAAiB,iDAAiD;AAC5G,UAAM,UAAU,QAAQ,UAAU,IAAI,CAAC,OAAO;AAC5C,YAAM,IAAI,KAAK,IAAI,QAAQ,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE;AAClD,UAAI,CAAC,EAAG,OAAM,IAAI,iBAAiB,mBAAmB,EAAE,mCAAmC;AAC3F,aAAO;AAAA,IACT,CAAC;AACD,UAAM,SAAS,QAAQ,UAAU;AACjC,QAAI,CAAC,OAAO,UAAU,MAAM,KAAK,SAAS,KAAK,SAAS,IAAK,OAAM,IAAI,iBAAiB,UAAU,MAAM,+BAA+B;AACvI,QAAI,QAAQ,UAAU,UAAa,EAAE,QAAQ,QAAQ,KAAK,QAAQ,SAAS,IAAK,OAAM,IAAI,iBAAiB,SAAS,QAAQ,KAAK,yCAAyC;AAC1K,QAAI,QAAQ,UAAU,OAAW,YAAW,QAAQ,KAAK;AACzD,QAAI,QAAQ,YAAY,OAAW,MAAK,aAAa,QAAQ,OAAO;AACpE,QAAI,QAAQ,YAAY,OAAW,MAAK,YAAY,QAAQ,SAAS,aAAa;AAClF,QAAI,SAAS,QAAQ;AACrB,QAAI,CAAC,QAAQ;AACX,YAAM,IAAI,aAAa,QAAQ,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;AACvD,eAAS,EAAE,GAAG,EAAE,IAAI,EAAE,QAAQ,GAAG,GAAG,EAAE,IAAI,EAAE,SAAS,EAAE;AAAA,IACzD;AACA,UAAM,OAAO,gBAAgB,SAAS,MAAM;AAC5C,QAAI,MAAM,KAAK;AACf,QAAI,SAA4B;AAChC,UAAM,MAAgB,CAAC;AACvB,UAAM,WAAW,oBAAI,IAAY;AACjC,QAAI,IAAY;AAChB,aAAS,IAAI,GAAG,IAAI,QAAQ,KAAK;AAC/B,UAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,IAAI,KAAK,CAAC,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,IAAI,KAAK,CAAC,CAAC;AAC7N,iBAAW,KAAK,SAAS;AACvB,cAAM,IAAI,WAAW,GAAG,GAAG,OAAO;AAClC,YAAI,QAAQ,EAAE;AACd,YAAI,QAAQ,YAAY,QAAW;AACjC,gBAAM,IAAI,KAAK,aAAa,QAAQ,OAAO;AAC3C,kBAAQ,oBAAoB,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,MAAM,EAAE,IAAI,QAAQ,EAAE,MAAM,IAAI,OAAO,EAAE,MAAM,IAAI,MAAM,EAAE,GAAG,CAAC;AAAA,QAChH;AACA,cAAM,UAAU,QAAQ,WAAW,EAAE;AACrC,YAAI,CAAC,UAAU,IAAI,QAAQ,OAAO,EAAG,OAAM,IAAI,iBAAiB,WAAW,EAAE,EAAE,2BAA2B,OAAO,iEAAiE;AAClL,cAAM,MAAM,KAAK,UAAU,KAAK,EAAE,SAAS,OAAO,QAAQ,SAAS,EAAE,OAAO,OAAO,MAAM,EAAE,MAAM,QAAQ,EAAE,UAAU,CAAC,EAAE,GAAG,EAAE,MAAM;AACnI,cAAM,IAAI;AACV,iBAAS,UAAU,QAAQ,IAAI,OAAO,MAAM;AAC5C,YAAI,IAAI,OAAO,SAAU,KAAI,KAAK,IAAI,OAAO,QAAQ;AACrD,iBAAS,IAAI,OAAO;AAAA,MACtB;AAAA,IACF;AACA,QAAI,QAAQ,KAAK,IAAK,MAAK,OAAO,QAAQ,WAAW,KAAK,WAAW,IAAI,kBAAkB,kBAAkB,GAAG;AAChH,WAAO,EAAE,WAAW,KAAK,QAAQ,UAAU,CAAC,GAAG,QAAQ,EAAE;AAAA,EAC3D;AAAA;AAAA,EAIQ,UAAU;AAChB,WAAO,EAAE,OAAO,KAAK,IAAI,OAAO,OAAO,QAAQ,KAAK,IAAI,OAAO,OAAO;AAAA,EACxE;AAAA;AAAA,EAGQ,gBAA8B;AACpC,UAAM,OAAO,KAAK;AAClB,QAAI,CAAC,KAAM,QAAO,KAAK,IAAI;AAC3B,QAAI,KAAK,YAAY,QAAQ,KAAK,QAAS,QAAO,KAAK,WAAW;AAClE,UAAM,SAAS,SAAS,KAAK,IAAI,QAAQ,KAAK,SAAS,CAAC,OAAO,EAAE,GAAI,GAAuB,SAAS,KAAK,QAAQ,EAAE;AACpH,SAAK,aAAa,EAAE,KAAK,KAAK,SAAS,OAAO;AAC9C,WAAO;AAAA,EACT;AAAA;AAAA,EAGU,iBAA8B;AACtC,UAAM,IAAI,KAAK,OAAO;AACtB,QAAI,CAAC,KAAK,CAAC,EAAE,QAAS,QAAO,CAAC;AAC9B,WAAO,CAAC,KAAK,YAAY,CAAC,CAAC;AAAA,EAC7B;AAAA;AAAA,EAGQ,YAAY,GAA4B;AAC9C,UAAM,EAAE,OAAO,OAAO,IAAI,KAAK,IAAI;AACnC,UAAM,MAAM,KAAK,iBAAiB,SAAS,QAAQ,IAAI;AACvD,QAAI,KAAK,cAAc,QAAQ,OAAO,KAAK,aAAa,KAAK,YAAY,EAAE,QAAS,QAAO,KAAK,aAAa;AAC7G,UAAM,MAAM,KAAK,YAAY,IAAI,EAAE,GAAG,KAAK,KAAK,YAAY,EAAE,GAAG;AACjE,UAAM,QAAQ,aAAa,KAAK,EAAE,MAAM,OAAO,MAAM;AACrD,UAAM,OAAkB,EAAE,MAAM,SAAS,IAAI,iBAAiB,MAAM,WAAW,SAAS,MAAM,SAAS,EAAE,SAAS,OAAO,UAAU,OAAO,SAAS,MAAM,KAAK,MAAM,EAAE,UAAU,GAAI,IAAI,IAAI;AAC5L,SAAK,eAAe,EAAE,KAAK,KAAK;AAChC,WAAO;AAAA,EACT;AAAA,EAEQ,aAAa,SAAwB,OAAO,OAAoB;AACtE,QAAI,SAAuB,KAAK,cAAc;AAC9C,QAAI,QAAQ,UAAU;AACpB,YAAM,SAAuB,CAAC;AAC9B,iBAAW,MAAM,QAAQ,SAAU,QAAO,KAAK,KAAK,aAAa,EAAE,CAAC;AACpE,eAAS,OAAO,IAAI,CAAC,OAAO,EAAE,GAAG,GAAG,SAAS,KAAK,EAAgB;AAAA,IACpE;AACA,UAAM,QAAqB,QAAQ,UAAU,QAAQ,CAAC,IAAI,CAAC,UAAU,KAAK,IAAI,KAAK,CAAC;AACpF,QAAI,KAAM,OAAM,KAAK,GAAG,KAAK,eAAe,CAAC;AAC7C,WAAO,CAAC,GAAG,OAAO,GAAG,MAAM;AAAA,EAC7B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,eAAe,MAAkB,QAAqF,UAA4C,CAAC,GAAS;AAC1K,UAAM,QAAQ,QAAQ,UAAU,QAAQ,SAAY,QAAQ;AAC5D,SAAK,eAAe,eAAe,KAAK,aAAa,CAAC,GAAG,IAAI,GAAG,MAAM,KAAK,QAAQ,GAAG,QAAQ,EAAE,OAAO,mBAAmB,KAAK,MAAM,WAAW,KAAK,IAAI,cAAc,CAAC;AAAA,EAC1K;AAAA;AAAA,EAGA,gBAAgB,UAAyB,CAAC,GAAe;AACvD,UAAM,EAAE,OAAO,OAAO,IAAI,KAAK,IAAI;AACnC,UAAM,OAAO,KAAK,iBAAiB,UAAU,KAAK,aAAa,OAAO,GAAG,EAAE,GAAG,GAAG,GAAG,GAAG,OAAO,OAAO,GAAG,KAAK,QAAQ,CAAC;AACtH,WAAO,EAAE,OAAO,QAAQ,KAAK;AAAA,EAC/B;AAAA;AAAA,EAGA,cAAc,UAAgD,CAAC,GAAe;AAC5E,UAAM,OAAO,KAAK,gBAAgB,OAAO;AACzC,UAAM,OAAO,KAAK,IAAI,GAAG,KAAK,MAAM,QAAQ,WAAW,GAAG,CAAC;AAC3D,UAAM,IAAI,KAAK,IAAI,GAAG,OAAO,KAAK,IAAI,KAAK,OAAO,KAAK,MAAM,CAAC;AAC9D,QAAI,KAAK,EAAG,QAAO;AACnB,UAAM,IAAI,KAAK,IAAI,GAAG,KAAK,MAAM,KAAK,QAAQ,CAAC,CAAC;AAChD,UAAM,IAAI,KAAK,IAAI,GAAG,KAAK,MAAM,KAAK,SAAS,CAAC,CAAC;AACjD,WAAO,EAAE,OAAO,GAAG,QAAQ,GAAG,MAAM,eAAe,KAAK,MAAM,KAAK,OAAO,KAAK,QAAQ,GAAG,CAAC,EAAE;AAAA,EAC/F;AAAA;AAAA;AAAA,EAKA,OAAO,UAAiC,CAAC,GAA4B;AACnE,WAAO,uBAAuB,KAAK,KAAK,EAAE,SAAS,QAAQ,SAAS,YAAY,KAAK,YAAY,QAAQ,KAAK,QAAQ,UAAU,KAAK,SAAS,CAAC;AAAA,EACjJ;AAAA;AAAA,EAGA,eAAe,OAAwB,UAAiC,CAAC,GAAqC;AAC5G,WAAO,+BAA+B,KAAK,KAAK,OAAO,EAAE,SAAS,QAAQ,SAAS,YAAY,KAAK,YAAY,QAAQ,KAAK,QAAQ,UAAU,KAAK,SAAS,CAAC;AAAA,EAChK;AAAA,EAEQ,MAAM,QAAgJ;AAC5J,SAAK,aAAa,OAAO;AACzB,SAAK,WAAW,OAAO,QAAQ,OAAO,OAAO,OAAO,QAAQ;AAC5D,QAAI,MAAM,QAAQ,OAAO,QAAQ,GAAG;AAClC,WAAK,WAAW,OAAO,SACpB,OAAO,CAAC,MAAmB,QAAQ,CAAC,KAAK,OAAQ,EAAa,UAAU,YAAY,kBAAkB,KAAM,EAAa,KAAK,CAAC,EAC/H,IAAI,CAAC,MAAO,OAAO,EAAE,SAAS,WAAW,EAAE,OAAO,EAAE,MAAM,YAAY,GAAG,MAAM,EAAE,KAAK,IAAI,EAAE,OAAO,EAAE,MAAM,YAAY,EAAE,CAAE;AAAA,IAChI;AACA,eAAW,KAAK,OAAO,MAAM,SAAS;AACpC,YAAM,IAAI,OAAO,WAAW,KAAK,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC;AAChD,UAAI,KAAK,KAAK,cAAe,MAAK,gBAAgB,IAAI;AAAA,IACxD;AACA,SAAK,YAAY,CAAC;AAClB,SAAK,YAAY,CAAC;AAClB,SAAK,MAAM,OAAO;AAClB,SAAK,eAAe,MAAM;AAC1B,SAAK,KAAK;AACV,WAAO,OAAO;AAAA,EAChB;AAAA;AAAA,EAGA,SAAS,KAAwB;AAC/B,SAAK,YAAY,oBAAoB;AACrC,QAAI;AACF,aAAO,KAAK,MAAM,yBAAyB,GAAG,CAAC;AAAA,IACjD,SAAS,GAAG;AACV,YAAM,IAAI,iBAAkB,EAAY,OAAO;AAAA,IACjD;AAAA,EACF;AAAA;AAAA,EAGA,MAAM,cAAc,KAAc,OAA4C;AAC5E,SAAK,YAAY,oBAAoB;AACrC,QAAI;AACF,aAAO,KAAK,MAAM,MAAM,8BAA8B,KAAK,KAAK,CAAC;AAAA,IACnE,SAAS,GAAG;AACV,YAAM,IAAI,iBAAkB,EAAY,OAAO;AAAA,IACjD;AAAA,EACF;AAAA;AAAA,EAGA,UAAU,UAA8C,CAAC,GAAe;AACtE,UAAM,MAAM,KAAK,OAAO,OAAO;AAC/B,WAAO,UAAU,IAAI,OAAO,IAAI,QAAQ,IAAI,IAAI;AAAA,EAClD;AAAA,EAEQ,OAAO,SAAyD;AACtE,UAAM,OAAO,KAAK,gBAAgB,OAAO;AACzC,UAAM,IAAI,QAAQ,SAAS;AAC3B,QAAI,EAAE,IAAI,KAAK,KAAK,GAAI,OAAM,IAAI,iBAAiB,SAAS,CAAC,uEAAuE;AACpI,QAAI,MAAM,EAAG,QAAO;AACpB,UAAM,IAAI,KAAK,IAAI,GAAG,KAAK,MAAM,KAAK,QAAQ,CAAC,CAAC;AAChD,UAAM,IAAI,KAAK,IAAI,GAAG,KAAK,MAAM,KAAK,SAAS,CAAC,CAAC;AACjD,WAAO,EAAE,OAAO,GAAG,QAAQ,GAAG,MAAM,eAAe,KAAK,MAAM,KAAK,OAAO,KAAK,QAAQ,GAAG,CAAC,EAAE;AAAA,EAC/F;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,YAAY,UAAsF,CAAC,GAAwB;AAC/H,UAAM,SAAS,QAAQ,UAAU;AACjC,QAAI,WAAW,YAAa,QAAO,KAAK,UAAU,OAAO;AACzD,QAAI,WAAW,gBAAgB,WAAW,aAAc,OAAM,IAAI,iBAAiB,UAAU,KAAK,UAAU,MAAM,CAAC,6DAA6D;AAChL,UAAM,UAAU,QAAQ,WAAW;AACnC,QAAI,EAAE,WAAW,KAAK,WAAW,GAAI,OAAM,IAAI,iBAAiB,WAAW,OAAO,6BAA6B;AAC/G,UAAM,MAAM,KAAK,OAAO,EAAE,GAAG,SAAS,OAAO,WAAW,eAAe,OAAO,QAAQ,MAAM,CAAC;AAC7F,UAAM,SAAS,KAAK,eAAe,oBAAoB;AACvD,QAAI,CAAC,OAAQ,OAAM,IAAI,iBAAiB,GAAG,MAAM,sGAAsG;AACvJ,WAAO,OAAO,KAAK,QAAQ,OAAO;AAAA,EACpC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,YAA6B;AAC3B,UAAM,EAAE,OAAO,QAAQ,IAAI,IAAI,KAAK,IAAI;AACxC,UAAM,cAAc,KAAK,gBAAgB,EAAE,UAAU,CAAC,GAAG,OAAO,KAAK,CAAC;AACtE,UAAM,aAA8B;AAAA,MAClC,MAAM;AAAA,MACN,IAAI;AAAA,MACJ,MAAM;AAAA,MACN,SAAS;AAAA,MACT,SAAS;AAAA,MACT,OAAO;AAAA,MACP,OAAO,EAAE,KAAK,KAAK;AAAA,MACnB,SAAS,kBAAkB,aAAa,CAAC;AAAA,MACzC,QAAQ,EAAE,GAAG,GAAG,GAAG,EAAE;AAAA,IACvB;AACA,UAAM,SAAS,KAAK,gBAAgB,EAAE,OAAO,KAAK,CAAC,EAAE;AAErD,UAAM,UAAU,oBAAI,IAAyB;AAC7C,UAAM,aAAa,CAACC,YAClBA,QAAO,IAAI,CAAC,MAAM;AAChB,YAAM,QAAQ,EAAE,UAAU,iBAAiB,EAAE,QAAQ,kBAAkB,EAAE,KAAkB;AAC3F,UAAI,UAAU,EAAE,MAAO,SAAQ,IAAI,EAAE,OAAoB,CAAC,GAAI,QAAQ,IAAI,EAAE,KAAkB,KAAK,CAAC,GAAI,EAAE,IAAI,CAAC;AAC/G,YAAM,OAAO,UAAU,EAAE,QAAQ,IAAK,EAAE,GAAG,GAAG,MAAM;AACpD,aAAO,KAAK,SAAS,UAAU,EAAE,GAAG,MAAM,UAAU,WAAW,KAAK,QAAQ,EAAE,IAAI;AAAA,IACpF,CAAC;AACH,UAAM,SAAS,WAAW,KAAK,IAAI,MAAM;AACzC,UAAM,SAAS,UAAU,EAAE,OAAO,QAAQ,QAAQ,CAAC,YAAY,GAAG,MAAM,GAA8B,QAAQ,YAAY,IAAI,CAAC;AAC/H,eAAW,CAAC,MAAM,KAAK,KAAK,SAAS;AACnC,YAAM,QAAQ,YAAY,KAAK,CAAC,MAAM,EAAE,OAAO,IAAI,GAAG,SAAS;AAC/D,YAAM,MAAM,YAAY,KAAK,CAAC,MAAM,EAAE,OAAO,kBAAkB,IAAI,CAAC,GAAG,SAAS,kBAAkB,IAAI;AACtG,YAAM,OAAO,MAAM,IAAI,CAAC,MAAM,IAAI,CAAC,GAAG,EAAE,KAAK,IAAI;AACjD,YAAM,MAAM,MAAM,WAAW;AAC7B,aAAO,SAAS,KAAK,GAAG,KAAK,oCAAoC,IAAI,IAAI,MAAM,QAAQ,MAAM,eAAe,GAAG,oCAAoC,MAAM,aAAa,WAAW,sDAAsD;AAAA,IACzO;AACA,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,iBAAiB,UAAgD,CAAC,GAAoD;AACpH,UAAM,MAAM,KAAK,cAAc,OAAO;AACtC,WAAO,EAAE,MAAM,cAAc,UAAU,IAAI,OAAO,IAAI,QAAQ,IAAI,IAAI,CAAC,GAAG,OAAO,IAAI,OAAO,QAAQ,IAAI,OAAO;AAAA,EACjH;AAAA;AAAA,EAIQ,UAAU,MAAgC;AAChD,SAAK,SAAS;AACd,SAAK,KAAK,KAAK;AACf,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,YAAY,QAA+C;AACzD,UAAM,WAAW,kBAAkB,QAAQ,KAAK,OAAO,QAAQ;AAC/D,SAAK,UAAU,EAAE,GAAG,KAAK,QAAQ,SAAS,CAAC;AAC3C,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,eAAe,QAAqD;AAClE,QAAI;AACJ,QAAI;AACF,oBAAc,qBAAqB,QAAQ,KAAK,OAAO,WAAW;AAAA,IACpE,SAAS,GAAG;AACV,YAAM,IAAI,iBAAkB,EAAY,OAAO;AAAA,IACjD;AACA,SAAK,UAAU,EAAE,GAAG,KAAK,QAAQ,YAAY,CAAC;AAC9C,WAAO;AAAA,EACT;AAAA;AAAA,EAGQ,YAAY,OAA8C,MAAmD;AACnH,QAAI;AACJ,QAAI,MAAM,QAAQ;AAChB,YAAM,EAAE,OAAO,QAAQ,KAAK,IAAI,MAAM;AACtC,UAAI,EAAE,QAAQ,KAAK,SAAS,KAAK,OAAO,UAAU,KAAK,KAAK,OAAO,UAAU,MAAM,MAAM,KAAK,WAAW,QAAQ,SAAS,GAAG;AAC3H,cAAM,IAAI,iBAAiB,GAAG,IAAI,0DAAoD;AAAA,MACxF;AACA,eAAS,EAAE,OAAO,QAAQ,MAAM,IAAI,kBAAkB,IAAI,EAAE;AAAA,IAC9D,WAAW,OAAO,MAAM,QAAQ,YAAY,MAAM,IAAI,KAAK,GAAG;AAC5D,eAAS,KAAK,YAAY,MAAM,IAAI,KAAK,EAAE,WAAW,OAAO,IAAI,MAAM,IAAI,KAAK,IAAI,yBAAyB,MAAM,IAAI,KAAK,CAAC,IAAI,IAAI;AAAA,IACvI,MAAO,OAAM,IAAI,iBAAiB,GAAG,IAAI,uDAAuD;AAChG,QAAI,OAAO,QAAQ,kBAAkB,OAAO,SAAS,eAAgB,OAAM,IAAI,iBAAiB,GAAG,IAAI,OAAO,OAAO,KAAK,OAAI,OAAO,MAAM,kBAAkB,cAAc,eAAe;AAC1L,UAAM,MAAM,WAAW,OAAO,OAAO,OAAO,QAAQ,OAAO,IAAI;AAC/D,SAAK,YAAY,IAAI,KAAK,MAAM;AAChC,WAAO,EAAE,KAAK,OAAO;AAAA,EACvB;AAAA,EAEQ,YAAY,KAAa,OAAO,SAAqB;AAC3D,UAAM,SAAS,KAAK,YAAY,IAAI,GAAG;AACvC,QAAI,OAAQ,QAAO;AACnB,UAAM,SAAS,aAAa,GAAG;AAC/B,QAAI,CAAC,OAAQ,OAAM,IAAI,iBAAiB,GAAG,IAAI,mCAAmC;AAClF,QAAI;AACF,YAAM,MAAM,UAAU,OAAO,KAAK;AAClC,YAAM,KAAK,EAAE,OAAO,IAAI,OAAO,QAAQ,IAAI,QAAQ,MAAM,IAAI,KAAK;AAClE,WAAK,YAAY,IAAI,KAAK,EAAE;AAC5B,aAAO;AAAA,IACT,SAAS,GAAG;AACV,YAAM,IAAI,iBAAiB,GAAG,IAAI,mCAAoC,EAAY,OAAO,yDAAyD;AAAA,IACpJ;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,gBAAgB,SAAqI;AACnJ,UAAM,EAAE,KAAK,OAAO,IAAI,KAAK,YAAY,SAAS,mBAAmB;AACrE,UAAM,EAAE,OAAO,OAAO,IAAI,KAAK,IAAI;AACnC,UAAM,IAAI,KAAK,IAAI,QAAQ,OAAO,OAAO,SAAS,OAAO,MAAM;AAC/D,UAAM,MAAM,EAAE,IAAI,QAAQ,OAAO,QAAQ,KAAK,GAAG,IAAI,SAAS,OAAO,SAAS,KAAK,GAAG,OAAO,OAAO,QAAQ,GAAG,QAAQ,OAAO,SAAS,EAAE;AACzI,UAAM,UAAwB,EAAE,KAAK,OAAO,OAAO,OAAO,QAAQ,OAAO,QAAQ,MAAM,KAAK,SAAS,MAAM,SAAS,MAAM,cAAc,MAAM;AAC9I,WAAO,KAAK,cAAc,EAAE,GAAG,SAAS,MAAM,QAAQ,QAAQ,IAAI,GAAG,OAAO;AAAA,EAC9E;AAAA;AAAA,EAGA,cAAc,QAAsF,OAAO,KAAK,OAAO,SAAuB;AAC5I,QAAI,CAAC,KAAM,OAAM,IAAI,iBAAiB,kEAAkE;AACxG,QAAI,OAAO,YAAY,UAAa,EAAE,OAAO,WAAW,KAAK,OAAO,WAAW,GAAI,OAAM,IAAI,iBAAiB,WAAW,OAAO,OAAO,6BAA6B;AACpK,QAAI,OAAO,QAAQ,EAAE,OAAO,KAAK,QAAQ,KAAK,OAAO,KAAK,SAAS,GAAI,OAAM,IAAI,iBAAiB,wCAAwC;AAC1I,UAAM,UAAwB;AAAA,MAC5B,GAAG;AAAA,MACH,GAAI,OAAO,YAAY,SAAY,EAAE,SAAS,OAAO,QAAQ,IAAI,CAAC;AAAA,MAClE,GAAI,OAAO,YAAY,SAAY,EAAE,SAAS,OAAO,QAAQ,IAAI,CAAC;AAAA,MAClE,GAAI,OAAO,iBAAiB,SAAY,EAAE,cAAc,OAAO,aAAa,IAAI,CAAC;AAAA,MACjF,GAAI,OAAO,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,KAAK,EAAE,IAAI,CAAC;AAAA,IACpD;AACA,QAAI,QAAQ,QAAQ,KAAK,OAAO,OAAO,KAAM,MAAK;AAClD,QAAI,SAAS,KAAK,OAAO,QAAS,MAAK;AACvC,SAAK,UAAU,EAAE,GAAG,KAAK,QAAQ,QAAQ,CAAC;AAC1C,WAAO;AAAA,EACT;AAAA,EAEA,oBAA0B;AACxB,SAAK;AACL,SAAK,UAAU,EAAE,GAAG,KAAK,QAAQ,SAAS,KAAK,CAAC;AAAA,EAClD;AAAA;AAAA,EAGA,mBAAmB,GAAW,GAA0B;AACtD,UAAM,IAAI,KAAK,OAAO;AACtB,QAAI,CAAC,EAAG,QAAO;AACf,UAAM,MAAM,KAAK,YAAY,EAAE,GAAG;AAClC,UAAM,IAAI,KAAK,OAAQ,IAAI,EAAE,KAAK,KAAK,EAAE,KAAK,QAAS,IAAI,KAAK;AAChE,UAAM,IAAI,KAAK,OAAQ,IAAI,EAAE,KAAK,KAAK,EAAE,KAAK,SAAU,IAAI,MAAM;AAClE,QAAI,IAAI,KAAK,IAAI,KAAK,KAAK,IAAI,SAAS,KAAK,IAAI,OAAQ,QAAO;AAChE,UAAM,KAAK,IAAI,IAAI,QAAQ,KAAK;AAChC,QAAI,IAAI,KAAK,IAAI,CAAC,MAAM,EAAG,QAAO;AAClC,WAAO,SAAS,IAAI,KAAK,CAAC,GAAG,IAAI,KAAK,IAAI,CAAC,GAAG,IAAI,KAAK,IAAI,CAAC,CAAC;AAAA,EAC/D;AAAA;AAAA,EAGA,kBAAkB,SAA8H;AAC9I,UAAM,EAAE,KAAK,OAAO,IAAI,KAAK,YAAY,SAAS,qBAAqB;AACvE,UAAM,MAAsB;AAAA,MAC1B,IAAI,MAAM,KAAK,iBAAiB;AAAA,MAChC,MAAM,QAAQ,MAAM,KAAK,KAAK,aAAa,KAAK,OAAO,WAAW,SAAS,CAAC;AAAA,MAC5E;AAAA,MACA,OAAO,OAAO;AAAA,MACd,QAAQ,OAAO;AAAA,MACf,GAAG,QAAQ,KAAK,KAAK,KAAK,OAAO,WAAW,SAAS;AAAA,MACrD,GAAG,QAAQ,KAAK,KAAK,KAAK,OAAO,WAAW,SAAS;AAAA,MACrD,cAAc,QAAQ,gBAAgB,KAAK,IAAI,KAAK,OAAO,KAAK;AAAA,MAChE,SAAS;AAAA,IACX;AACA,SAAK,UAAU,EAAE,GAAG,KAAK,QAAQ,YAAY,CAAC,GAAG,KAAK,OAAO,YAAY,GAAG,EAAE,CAAC;AAC/E,WAAO;AAAA,EACT;AAAA,EAEQ,iBAAiB,IAA4B;AACnD,UAAM,IAAI,KAAK,OAAO,WAAW,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE;AACxD,QAAI,CAAC,EAAG,OAAM,IAAI,iBAAiB,4BAA4B,EAAE,4CAA4C;AAC7G,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,qBAAqB,IAAY,QAAwG;AACvI,UAAM,IAAI,KAAK,iBAAiB,EAAE;AAClC,QAAI,OAAO,iBAAiB,UAAa,EAAE,OAAO,gBAAgB,MAAM,OAAO,gBAAgB,MAAO,OAAM,IAAI,iBAAiB,gBAAgB,OAAO,YAAY,iCAAiC;AACrM,UAAM,OAAuB,EAAE,GAAG,GAAG,GAAG,OAAO,YAAY,OAAO,QAAQ,MAAM,EAAE,OAAO,CAAC,CAAC,EAAE,CAAC,MAAM,MAAM,MAAS,CAAC,EAAE;AACtH,SAAK,UAAU,EAAE,GAAG,KAAK,QAAQ,YAAY,KAAK,OAAO,WAAW,IAAI,CAAC,MAAO,EAAE,OAAO,KAAK,OAAO,CAAE,EAAE,CAAC;AAC1G,WAAO;AAAA,EACT;AAAA,EAEA,qBAAqB,IAAkB;AACrC,SAAK,iBAAiB,EAAE;AACxB,SAAK,UAAU,EAAE,GAAG,KAAK,QAAQ,YAAY,KAAK,OAAO,WAAW,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE,EAAE,CAAC;AAAA,EAClG;AAAA;AAAA,EAGA,gBAAgB,IAAwB;AACtC,WAAO,KAAK,YAAY,KAAK,iBAAiB,EAAE,EAAE,GAAG;AAAA,EACvD;AAAA;AAAA,EAGA,mBAAmB,IAAY,GAAW,GAAmB;AAC3D,UAAM,IAAI,KAAK,iBAAiB,EAAE;AAClC,UAAM,KAAK,KAAK,YAAY,EAAE,GAAG;AACjC,UAAM,IAAI,KAAK,MAAM,CAAC;AACtB,UAAM,IAAI,KAAK,MAAM,CAAC;AACtB,QAAI,EAAE,KAAK,KAAK,KAAK,KAAK,IAAI,GAAG,SAAS,IAAI,GAAG,QAAS,OAAM,IAAI,iBAAiB,IAAI,CAAC,KAAK,CAAC,2BAA2B,EAAE,IAAI,MAAM,GAAG,KAAK,OAAI,GAAG,MAAM,mCAAmC;AAC/L,UAAM,KAAK,IAAI,GAAG,QAAQ,KAAK;AAC/B,WAAO,SAAS,GAAG,KAAK,CAAC,GAAG,GAAG,KAAK,IAAI,CAAC,GAAG,GAAG,KAAK,IAAI,CAAC,CAAC;AAAA,EAC5D;AAAA,EAEQ,WAAW,KAAc,OAA2B,UAA0B;AACpF,UAAM,OAAO,cAAc,MAAM,MAAM;AACvC,SAAK,SAAS;AACd,SAAK;AACL,QAAI,CAAC,OAAO,OAAO,QAAQ,SAAU;AACrC,UAAM,IAAI;AACV,UAAM,SAAsB,EAAE,GAAG,KAAK;AACtC,WAAO,WAAW,kBAAmB,EAAE,YAAwC,CAAC,GAAG,KAAK,QAAQ;AAChG,QAAI;AACF,aAAO,cAAc,qBAAsB,EAAE,eAA2C,CAAC,GAAG,KAAK,WAAW;AAAA,IAC9G,SAAS,GAAG;AACV,eAAS,KAAK,sBAAuB,EAAY,OAAO,EAAE;AAAA,IAC5D;AACA,UAAM,IAAI,EAAE;AACZ,QAAI,KAAK,OAAO,EAAE,QAAQ,UAAU;AAClC,UAAI;AACF,cAAM,KAAK,KAAK,YAAY,EAAE,KAAK,mBAAmB;AACtD,eAAO,UAAU;AAAA,UACf,KAAK,EAAE;AAAA,UACP,OAAO,GAAG;AAAA,UACV,QAAQ,GAAG;AAAA,UACX,MAAM,EAAE,QAAQ,EAAE,KAAK,QAAQ,KAAK,EAAE,KAAK,SAAS,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,EAAE,GAAG,GAAG,GAAG,GAAG,OAAO,MAAM,OAAO,OAAO,QAAQ,MAAM,OAAO,OAAO;AAAA,UAC7I,SAAS,OAAO,EAAE,YAAY,WAAW,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,EAAE,OAAO,CAAC,IAAI;AAAA,UAC/E,SAAS,EAAE,YAAY;AAAA,UACvB,cAAc,EAAE,iBAAiB;AAAA,QACnC;AAAA,MACF,SAAS,GAAG;AACV,iBAAS,KAAM,EAAY,OAAO;AAAA,MACpC;AAAA,IACF;AACA,QAAI,MAAM,QAAQ,EAAE,UAAU,GAAG;AAC/B,iBAAW,OAAO,EAAE,YAAgC;AAClD,YAAI,CAAC,OAAO,OAAO,IAAI,QAAQ,YAAY,OAAO,IAAI,OAAO,SAAU;AACvE,YAAI;AACF,gBAAM,KAAK,KAAK,YAAY,IAAI,KAAK,cAAc,IAAI,IAAI,GAAG;AAC9D,iBAAO,WAAW,KAAK,EAAE,IAAI,IAAI,IAAI,MAAM,OAAO,IAAI,QAAQ,IAAI,EAAE,GAAG,KAAK,IAAI,KAAK,OAAO,GAAG,OAAO,QAAQ,GAAG,QAAQ,GAAG,OAAO,IAAI,CAAC,KAAK,GAAG,GAAG,OAAO,IAAI,CAAC,KAAK,GAAG,cAAc,OAAO,IAAI,YAAY,KAAK,KAAK,SAAS,IAAI,YAAY,MAAM,CAAC;AACtP,gBAAM,IAAI,OAAO,aAAa,KAAK,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC;AACpD,cAAI,KAAK,KAAK,gBAAiB,MAAK,kBAAkB,IAAI;AAAA,QAC5D,SAAS,GAAG;AACV,mBAAS,KAAM,EAAY,OAAO;AAAA,QACpC;AAAA,MACF;AAAA,IACF;AACA,SAAK,SAAS;AAAA,EAChB;AAAA;AAAA;AAAA,EAKA,QAAQ,MAAmB,UAAmE,CAAC,GAAmB;AAChH,QAAI;AACF,aAAO,aAAa,QAAQ,UAAU,SAAY,KAAK,QAAQ,WAAW,QAAQ,KAAK,GAAG,MAAM,OAAO;AAAA,IACzG,SAAS,GAAG;AACV,YAAM,IAAI,iBAAkB,EAAY,OAAO;AAAA,IACjD;AAAA,EACF;AAAA,EAEA,UAAU,OAAe,MAAyB;AAChD,UAAM,IAAI,WAAW,KAAK;AAC1B,SAAK,WAAW,CAAC,GAAG,KAAK,UAAU,MAAM,KAAK,IAAI,EAAE,OAAO,GAAG,MAAM,KAAK,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;AAChG,SAAK,KAAK,CAAC,CAAC;AACZ,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,aAAa,OAAyB;AACpC,QAAI,CAAC,OAAO,UAAU,KAAK,KAAK,QAAQ,KAAK,SAAS,KAAK,SAAS,OAAQ,OAAM,IAAI,iBAAiB,SAAS,KAAK,+BAA+B,KAAK,SAAS,MAAM,sBAAsB;AAC9L,SAAK,WAAW,KAAK,SAAS,OAAO,CAAC,GAAG,MAAM,MAAM,KAAK;AAC1D,SAAK,KAAK,CAAC,CAAC;AACZ,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,YAAY,UAAuC;AACjD,SAAK,WAAW,SAAS,IAAI,CAAC,MAAO,EAAE,OAAO,EAAE,OAAO,WAAW,EAAE,KAAK,GAAG,MAAM,EAAE,KAAK,IAAI,EAAE,OAAO,WAAW,EAAE,KAAK,EAAE,CAAE;AAC5H,SAAK,KAAK,CAAC,CAAC;AACZ,WAAO,KAAK;AAAA,EACd;AAAA;AAAA,EAIA,IAAI,YAAuB;AACzB,WAAO,KAAK;AAAA,EACd;AAAA;AAAA,EAGA,gBAAgB,QAA6B,UAAmE,CAAC,GAAkC;AACjJ,UAAM,QAAQ,QAAQ,UAAU,SAAY,KAAK,QAAQ,WAAW,QAAQ,KAAK;AACjF,QAAI,QAAQ,SAAS,UAAa,EAAE,QAAQ,QAAQ,KAAK,QAAQ,QAAQ,KAAM,OAAM,IAAI,iBAAiB,QAAQ,QAAQ,IAAI,kCAAkC;AAChK,QAAI;AACF,YAAM,IAAI,KAAK,IAAI,OAAO,QAAQ,EAAE,MAAM,QAAQ,QAAQ,SAAS,OAAO,MAAM,QAAQ,KAAK,CAAC;AAC9F,WAAK,KAAK,CAAC,CAAC;AACZ,aAAO;AAAA,IACT,SAAS,GAAG;AACV,YAAM,IAAI,iBAAkB,EAAY,OAAO;AAAA,IACjD;AAAA,EACF;AAAA;AAAA,EAGA,cAAc,GAAW,GAAW,UAAmD,CAAC,GAAkB;AACxG,QAAI;AACJ,QAAI;AACF,UAAI,KAAK,IAAI,KAAK,GAAG,GAAG,QAAQ,MAAM;AAAA,IACxC,SAAS,GAAG;AACV,YAAM,IAAI,iBAAkB,EAAY,OAAO;AAAA,IACjD;AACA,QAAI,KAAK,QAAQ,SAAU,MAAK,SAAS,CAAC;AAC1C,WAAO;AAAA,EACT;AAAA,EAEA,iBAAuB;AACrB,SAAK,IAAI,MAAM;AACf,SAAK,KAAK,CAAC,CAAC;AAAA,EACd;AAAA;AAAA,EAGA,aAAa,IAAiC;AAC5C,UAAM,IAAI,UAAU,KAAK,cAAc,GAAG,EAAE,GAAG;AAC/C,WAAO,aAAa,CAAC,IAAI,EAAE,UAAU;AAAA,EACvC;AACF;AAKO,IAAM,iBAAiB;AAG9B,SAAS,aAAa,KAAiB,MAA+D,OAAe,QAA4B;AAC/I,QAAM,MAAM,IAAI,kBAAkB,QAAQ,SAAS,CAAC;AACpD,QAAM,KAAK,KAAK,IAAI,GAAG,KAAK,MAAM,KAAK,CAAC,CAAC;AACzC,QAAM,KAAK,KAAK,IAAI,GAAG,KAAK,MAAM,KAAK,CAAC,CAAC;AACzC,QAAM,KAAK,KAAK,IAAI,OAAO,KAAK,KAAK,KAAK,IAAI,KAAK,KAAK,CAAC;AACzD,QAAM,KAAK,KAAK,IAAI,QAAQ,KAAK,KAAK,KAAK,IAAI,KAAK,MAAM,CAAC;AAC3D,QAAM,KAAK,IAAI,QAAQ,KAAK;AAC5B,QAAM,KAAK,IAAI,SAAS,KAAK;AAC7B,QAAM,IAAI,IAAI;AACd,WAAS,IAAI,IAAI,IAAI,IAAI,KAAK;AAC5B,UAAM,IAAI,KAAK,IAAI,IAAI,SAAS,GAAG,KAAK,IAAI,IAAI,IAAI,MAAM,KAAK,KAAK,KAAK,GAAG,CAAC;AAC7E,UAAM,KAAK,KAAK,MAAM,CAAC;AACvB,UAAM,KAAK,KAAK,IAAI,IAAI,SAAS,GAAG,KAAK,CAAC;AAC1C,UAAM,KAAK,IAAI;AACf,aAAS,IAAI,IAAI,IAAI,IAAI,KAAK;AAC5B,YAAM,KAAK,IAAI,MAAM,KAAK,KAAK,KAAK;AACpC,UAAI,IAAI,QAAQ,IAAI,IAAI,QAAQ,QAAQ,IAAI,MAAM,KAAK,KAAK,KAAK,MAAM,IAAI,MAAM,KAAK,KAAK,KAAK,IAAI,OAAQ;AAC5G,YAAM,KAAK,KAAK,IAAI,IAAI,QAAQ,GAAG,KAAK,IAAI,GAAG,CAAC,CAAC;AACjD,YAAM,KAAK,KAAK,MAAM,EAAE;AACxB,YAAM,KAAK,KAAK,IAAI,IAAI,QAAQ,GAAG,KAAK,CAAC;AACzC,YAAM,KAAK,KAAK;AAChB,YAAM,KAAK,IAAI,QAAQ,KAAK;AAC5B,eAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,cAAM,IAAI,GAAG,KAAK,IAAI,QAAQ,MAAM,IAAI,CAAC,KAAK,GAAG,KAAK,IAAI,QAAQ,MAAM,IAAI,CAAC,IAAI,GAAG,KAAK,IAAI,QAAQ,MAAM,IAAI,CAAC,KAAK;AACrH,cAAM,IAAI,GAAG,KAAK,IAAI,QAAQ,MAAM,IAAI,CAAC,KAAK,GAAG,KAAK,IAAI,QAAQ,MAAM,IAAI,CAAC,IAAI,GAAG,KAAK,IAAI,QAAQ,MAAM,IAAI,CAAC,KAAK;AACrH,YAAI,IAAI,CAAC,IAAI,KAAK,IAAI,KAAK;AAAA,MAC7B;AAAA,IACF;AAAA,EACF;AACA,SAAO,EAAE,OAAO,QAAQ,MAAM,IAAI;AACpC;;;ACxiDO,IAAM,gBAAN,cAA4B,cAAc;AAAC;AAwBlD,IAAM,QAAQ;AAGP,SAAS,eAAe,QAAuC;AACpE,MAAI,OAAO,SAAS,EAAG,QAAO,OAAO,IAAI,MAAM,CAAC;AAChD,QAAM,KAAK,OAAO,CAAC,EAAG;AACtB,QAAM,KAAK,OAAO,OAAO,SAAS,CAAC,EAAG;AACtC,MAAI,OAAO,MAAM,CAAC,MAAM,OAAO,SAAS,EAAE,CAAC,CAAC,KAAM,KAAiB,IAAe;AAChF,WAAO,OAAO,IAAI,CAAC,MAAM,KAAK,IAAI,GAAG,KAAK,IAAI,IAAK,EAAE,IAAgB,OAAmB,KAAiB,GAAc,CAAC,CAAC;AAAA,EAC3H;AACA,QAAM,MAAM,CAAC,CAAC;AACd,WAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,IAAK,KAAI,KAAK,IAAI,IAAI,CAAC,IAAK,KAAK,MAAM,OAAO,CAAC,EAAG,IAAI,OAAO,IAAI,CAAC,EAAG,GAAG,OAAO,CAAC,EAAG,IAAI,OAAO,IAAI,CAAC,EAAG,CAAC,CAAC;AAC3I,QAAM,QAAQ,IAAI,IAAI,SAAS,CAAC;AAChC,SAAO,QAAQ,IAAI,IAAI,IAAI,CAAC,MAAM,IAAI,KAAK,IAAI,OAAO,IAAI,MAAM,CAAC;AACnE;AAGO,SAAS,eAAe,QAA6B,MAAM,MAAc;AAC9E,QAAM,KAAK,OAAO,CAAC,GAAG;AACtB,QAAM,KAAK,OAAO,OAAO,SAAS,CAAC,GAAG;AACtC,MAAI;AACJ,MAAI,OAAO,MAAM,CAAC,MAAM,OAAO,SAAS,EAAE,CAAC,CAAC,KAAM,KAAiB,GAAe,MAAM,KAAiB;AAAA,OACpG;AACH,QAAI,SAAS;AACb,aAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,IAAK,WAAU,KAAK,MAAM,OAAO,CAAC,EAAG,IAAI,OAAO,IAAI,CAAC,EAAG,GAAG,OAAO,CAAC,EAAG,IAAI,OAAO,IAAI,CAAC,EAAG,CAAC;AAC7H,SAAK,SAAS;AAAA,EAChB;AACA,SAAO,KAAK,IAAI,KAAK,KAAK,IAAI,KAAK,EAAE,CAAC;AACxC;AAGO,SAAS,UAAU,MAAkB,OAAO,GAAoC;AACrF,QAAM,QAAQ,KAAK,IAAI,KAAK,OAAO,KAAK,MAAM,IAAI;AAClD,QAAM,OAAO,KAAK,IAAI;AACtB,QAAM,QAAQ,KAAK,IAAI,KAAK,QAAQ;AACpC,QAAM,MAAuC,CAAC;AAC9C,WAAS,IAAI,GAAG,IAAI,MAAM,KAAK;AAC7B,UAAM,IAAI,KAAK,IAAI,SAAU,KAAK,SAAS,IAAI,UAAU,IAAI,OAAQ;AACrE,QAAI,KAAK,IAAI,IAAI,EAAE,GAAG,OAAO,EAAE,IAAI,EAAE,GAAG,MAAM,EAAE,GAAG,IAAI,IAAI,EAAE,GAAG,MAAM,EAAE,IAAI,EAAE,GAAG,OAAO,EAAE,CAAC;AAAA,EAC7F;AACA,SAAO;AACT;AAEA,IAAM,SAAS,CAAC,OAAmB,EAAE,GAAG,EAAE,IAAI,EAAE,QAAQ,GAAG,GAAG,EAAE,IAAI,EAAE,SAAS,EAAE;AAU1E,IAAM,gBAAN,MAAoB;AAAA,EAIzB,YACmB,YACR,UACQ,UAAgC,CAAC,GAClD;AAHiB;AACR;AACQ;AAEjB,SAAK,QAAQ,QAAQ,SAAS;AAC9B,SAAK,QAAQ,IAAI,iBAAiB,UAAU,EAAE,OAAO,KAAK,OAAO,QAAQ,QAAQ,OAAO,CAAC;AAAA,EAC3F;AAAA,EANmB;AAAA,EACR;AAAA,EACQ;AAAA,EANF;AAAA,EACA;AAAA;AAAA,EAYjB,QAAQ,OAA0B,UAA2E;AAC3G,WAAO,KAAK,MAAM,IAAI,OAAO,YAAY;AACvC,YAAM,UAAoC,CAAC;AAC3C,iBAAW,WAAW,UAAU;AAC9B,YAAI;AACF,kBAAQ,KAAK,EAAE,IAAI,MAAM,SAAS,QAAQ,MAAM,KAAK,WAAW,MAAM,IAAI,OAAO,EAAE,CAAC;AAAA,QACtF,SAAS,OAAO;AACd,kBAAQ,KAAK,EAAE,IAAI,OAAO,SAAS,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,EAAE,CAAC;AAAA,QACtG;AAAA,MACF;AACA,aAAO;AAAA,IACT,CAAC;AAAA,EACH;AAAA,EAEQ,GAAG,GAAmB;AAC5B,WAAO,KAAK,MAAM,IAAI,KAAK,IAAI,KAAK,KAAK,QAAQ,SAAS,CAAC,CAAC;AAAA,EAC9D;AAAA,EAEQ,MAAM,IAAY;AACxB,UAAM,IAAI,KAAK,SAAS,IAAI,EAAE;AAC9B,WAAO,EAAE,GAAG,GAAG,KAAK,GAAG,GAAG,GAAG,KAAK,EAAE;AAAA,EACtC;AAAA;AAAA,EAGA,MAAc,MAAM,IAAY,IAA8B,KAAK,KAAK;AACtE,UAAM,IAAI,KAAK,SAAS,IAAI,EAAE;AAC9B,QAAI,CAAC,KAAM,EAAE,MAAM,KAAK,EAAE,MAAM,GAAI;AAClC,WAAK,SAAS,IAAI,EAAE,IAAI,GAAG,GAAG,GAAG,GAAG,GAAG,EAAE,CAAC;AAC1C;AAAA,IACF;AACA,UAAM,oBAAoB,KAAK,UAAU,KAAK,OAAO,IAAI,KAAK,MAAM,EAAE,GAAG,IAAI,KAAK,GAAG,EAAE,CAAC;AAAA,EAC1F;AAAA,EAEA,MAAc,IAAI,IAAY,MAA0B,IAAY;AAClE,QAAI,CAAC,KAAM;AACX,SAAK,SAAS,IAAI,EAAE,IAAI,SAAS,KAAK,CAAC;AACvC,UAAM,KAAK,MAAM,KAAK,KAAK,GAAG,EAAE,CAAC;AAAA,EACnC;AAAA,EAEA,MAAc,WAAW,IAAY,SAA8C;AACjF,UAAM,IAAI,KAAK;AACf,YAAQ,QAAQ,MAAM;AAAA,MACpB,KAAK;AACH,cAAM,KAAK,IAAI,IAAI,QAAQ,MAAM,GAAG;AACpC,eAAO;AAAA,MACT,KAAK;AACH,cAAM,KAAK,IAAI,IAAI,QAAQ,MAAM,GAAG;AACpC,cAAM,KAAK,MAAM,IAAI,QAAQ,EAAE;AAC/B,aAAK,SAAS,IAAI,EAAE,IAAI,SAAS,KAAK,CAAC;AACvC,cAAM,KAAK,MAAM,KAAK,KAAK,GAAG,GAAG,CAAC;AAClC,aAAK,SAAS,IAAI,EAAE,IAAI,SAAS,MAAM,CAAC;AACxC,eAAO;AAAA,MACT,KAAK;AACH,cAAM,KAAK,IAAI,IAAI,QAAQ,MAAM,GAAG;AACpC,eAAO,KAAK,OAAO,IAAI,QAAQ,MAAM;AAAA,MACvC,KAAK,QAAQ;AACX,cAAM,KAAK,IAAI,IAAI,QAAQ,MAAM,GAAG;AACpC,cAAM,EAAE,OAAO,OAAO,IAAI,EAAE,SAAS,EAAE,SAAS;AAChD,cAAM,OAAO,UAAU,EAAE,GAAG,GAAG,GAAG,GAAG,OAAO,OAAO,CAAC;AACpD,cAAM,KAAK,MAAM,IAAI,KAAK,CAAC,CAAE;AAC7B,aAAK,SAAS,IAAI,EAAE,IAAI,SAAS,KAAK,CAAC;AACvC,YAAI;AACF,mBAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,IAAK,OAAM,oBAAoB,KAAK,UAAU,KAAK,OAAO,IAAI,KAAK,IAAI,CAAC,GAAI,KAAK,CAAC,GAAI,KAAK,GAAG,IAAI,IAAI,MAAM,EAAE,CAAC;AAAA,QAClJ,UAAE;AACA,eAAK,SAAS,IAAI,EAAE,IAAI,SAAS,MAAM,CAAC;AAAA,QAC1C;AACA,eAAO,EAAE,UAAU,QAAQ,IAAI;AAAA,MACjC;AAAA,MACA,KAAK,UAAU;AACb,cAAM,KAAK,IAAI,IAAI,QAAQ,MAAM,GAAG;AACpC,cAAM,SAAS,EAAE,WAAW,EAAE,OAAO,CAAC,MAAM,QAAQ,OAAO,WAAW,SAAS,EAAE,EAAE,CAAC;AACpF,cAAM,QAAQ,OAAO,CAAC,GAAG,OAAO,CAAC;AACjC,YAAI,MAAO,OAAM,KAAK,MAAM,IAAI,KAAK;AACrC,cAAM,SAAS,EAAE,cAAc,QAAQ,MAAM;AAC7C,YAAI,OAAO,OAAQ,OAAM,KAAK,MAAM,IAAI,OAAO,OAAO,MAAM,GAAG,GAAG;AAClE,eAAO;AAAA,MACT;AAAA,IACF;AAAA,EACF;AAAA;AAAA,EAGA,MAAc,OAAO,IAAY,MAAqF;AACpH,UAAM,IAAI,KAAK;AACf,UAAM,SAAS,EAAE,YAAY,KAAK,MAAM;AACxC,UAAM,EAAE,QAAQ,SAAS,GAAG,KAAK,IAAI;AAErC,UAAM,UAAU,EAAE,YAAY,EAAE,mBAAmB,OAAO,OAAO,OAAO,CAAC,GAAG,GAAG,KAAK,CAAC;AACrF,QAAI;AACF,YAAM,KAAK,MAAM,IAAI,OAAO,CAAC,CAAE;AAC/B,WAAK,SAAS,IAAI,EAAE,IAAI,SAAS,KAAK,CAAC;AACvC,YAAM,KAAK,eAAe,MAAM;AAChC,YAAM,WAAW,KAAK,GAAG,eAAe,QAAQ,KAAK,QAAQ,WAAW,CAAC;AACzE,UAAI,OAAO;AACX,YAAM,SAAS,KAAK,IAAI,GAAG,KAAK,MAAM,WAAW,KAAK,CAAC;AACvD,eAAS,IAAI,GAAG,KAAK,QAAQ,KAAK;AAChC,cAAM,IAAI,IAAI;AACd,cAAM,OAAO;AACb,eAAO,OAAO,OAAO,UAAU,GAAG,IAAI,KAAM,IAAI,KAAM;AACtD,YAAI,OAAO,MAAM;AACf,kBAAQ,KAAK,OAAO,MAAM,MAAM,IAAI,CAAC;AACrC,gBAAM,IAAI,OAAO,OAAO,CAAC;AACzB,eAAK,SAAS,IAAI,EAAE,IAAI,GAAG,EAAE,GAAG,GAAG,EAAE,EAAE,CAAC;AAAA,QAC1C;AACA,YAAI,IAAI,OAAQ,OAAM,KAAK,MAAM,KAAK,WAAW,MAAM;AAAA,MACzD;AACA,UAAI,OAAO,OAAO,OAAQ,SAAQ,KAAK,OAAO,MAAM,IAAI,CAAC;AACzD,WAAK,SAAS,IAAI,EAAE,IAAI,SAAS,MAAM,CAAC;AACxC,aAAO,QAAQ,IAAI;AAAA,IACrB,SAAS,OAAO;AACd,UAAI,EAAE,iBAAiB,QAAS,SAAQ,OAAO;AAC/C,WAAK,SAAS,IAAI,EAAE,IAAI,SAAS,MAAM,CAAC;AACxC,YAAM;AAAA,IACR;AAAA,EACF;AACF;;;ACxNA,IAAM,OAAO,EAAE,cAAc,MAAM,iBAAiB,OAAO,gBAAgB,MAAM,eAAe,MAAM;AACtG,IAAM,QAAQ,EAAE,cAAc,OAAO,iBAAiB,OAAO,gBAAgB,OAAO,eAAe,MAAM;AACzG,IAAM,MAAM,EAAE,cAAc,OAAO,iBAAiB,OAAO,gBAAgB,MAAM,eAAe,MAAM;AACtG,IAAM,cAAc,EAAE,cAAc,OAAO,iBAAiB,MAAM,gBAAgB,OAAO,eAAe,MAAM;AAC9G,IAAM,QAAQ,EAAE,MAAM,UAAU,YAAY,CAAC,GAAG,sBAAsB,MAAM;AAC5E,IAAM,QAAQ,EAAE,MAAM,UAAU,SAAS,qBAAqB,aAAa,kBAAkB;AAC7F,IAAM,QAAQ;AAAA,EACZ,MAAM;AAAA,EACN,YAAY,EAAE,GAAG,EAAE,MAAM,UAAU,aAAa,wBAAwB,GAAG,GAAG,EAAE,MAAM,UAAU,aAAa,wBAAwB,EAAE;AAAA,EACvI,UAAU,CAAC,KAAK,GAAG;AAAA,EACnB,sBAAsB;AACxB;AACA,IAAM,OAAO;AAAA,EACX,MAAM;AAAA,EACN,aAAa;AAAA,EACb,YAAY;AAAA,IACV,GAAG,EAAE,MAAM,UAAU,aAAa,aAAa;AAAA,IAC/C,GAAG,EAAE,MAAM,UAAU,aAAa,YAAY;AAAA,IAC9C,OAAO,EAAE,MAAM,UAAU,kBAAkB,GAAG,aAAa,SAAS;AAAA,IACpE,QAAQ,EAAE,MAAM,UAAU,kBAAkB,GAAG,aAAa,UAAU;AAAA,EACxE;AAAA,EACA,UAAU,CAAC,KAAK,KAAK,SAAS,QAAQ;AAAA,EACtC,sBAAsB;AACxB;AACA,IAAM,MAAM,EAAE,MAAM,UAAU,WAAW,GAAG,aAAa,sDAAsD;AAE/G,IAAM,cAAc,CAAC,MAA4B,IAAI,EAAE,OAAO,EAAE,OAAO,QAAQ,EAAE,QAAQ,MAAM,EAAE,MAAM,SAAS,EAAE,SAAS,SAAS,EAAE,SAAS,cAAc,EAAE,aAAa,IAAI;AAChL,IAAM,UAAU,CAAC,EAAE,KAAK,IAAI,GAAG,EAAE,MAAsB;AAEhD,SAAS,sBAAsB,GAAuC;AAC3E,QAAM,SAAS,MAAM,EAAE,SAAS,EAAE;AAClC,SAAO;AAAA,IACL;AAAA,MACE,MAAM;AAAA,MACN,OAAO;AAAA,MACP,aAAa;AAAA,MACb,aAAa;AAAA,MACb,aAAa,EAAE,OAAO,2BAA2B,GAAG,KAAK;AAAA,MACzD,SAAS,MAAM;AACb,cAAM,IAAI,OAAO;AACjB,eAAO,EAAE,UAAU,EAAE,GAAG,EAAE,UAAU,QAAQ,eAAe,EAAE,QAAQ,EAAE,OAAO,GAAG,aAAa,EAAE,aAAa,SAAS,YAAY,EAAE,OAAO,GAAG,YAAY,EAAE,WAAW,IAAI,OAAO,EAAE;AAAA,MACtL;AAAA,IACF;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,OAAO;AAAA,MACP,aACE;AAAA,MACF,aAAa;AAAA,QACX,MAAM;AAAA,QACN,YAAY;AAAA,UACV,MAAM,EAAE,MAAM,UAAU,MAAM,CAAC,GAAG,cAAc,GAAG,aAAa,kGAAkG;AAAA,UAClK,QAAQ,EAAE,GAAG,OAAO,aAAa,qEAAqE;AAAA,UACtG,UAAU,EAAE,MAAM,UAAU,SAAS,MAAM,SAAS,KAAK,aAAa,oCAAoC;AAAA,UAC1G,UAAU,EAAE,MAAM,WAAW,SAAS,GAAG,SAAS,IAAI,aAAa,qCAAqC;AAAA,UACxG,QAAQ,EAAE,MAAM,WAAW,aAAa,gEAAgE;AAAA,QAC1G;AAAA,QACA,sBAAsB;AAAA,MACxB;AAAA,MACA,aAAa,EAAE,OAAO,uCAAuC,GAAG,IAAI;AAAA,MACpE,SAAS,CAAC,MAAM;AACd,cAAM,IAAI,EAAE,YAAY,CAAC;AACzB,eAAO,EAAE,GAAG,GAAG,QAAQ,eAAe,CAAC,EAAE,OAAO;AAAA,MAClD;AAAA,IACF;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,OAAO;AAAA,MACP,aACE;AAAA,MACF,aAAa;AAAA,QACX,MAAM;AAAA,QACN,YAAY;AAAA,UACV,SAAS,EAAE,MAAM,WAAW,aAAa,0BAA0B;AAAA,UACnE,QAAQ,EAAE,MAAM,SAAS,UAAU,GAAG,UAAU,GAAG,OAAO,EAAE,GAAG,OAAO,aAAa,qBAAqB,GAAG,aAAa,wBAAwB;AAAA,UAChJ,MAAM,EAAE,MAAM,WAAW,aAAa,kDAAkD;AAAA,QAC1F;AAAA,QACA,sBAAsB;AAAA,MACxB;AAAA,MACA,aAAa,EAAE,OAAO,6BAA6B,GAAG,IAAI;AAAA,MAC1D,SAAS,CAAC,MAAM,EAAE,eAAe,CAAC;AAAA,IACpC;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,OAAO;AAAA,MACP,aACE;AAAA,MACF,aAAa;AAAA,QACX,MAAM;AAAA,QACN,YAAY;AAAA,UACV,KAAK;AAAA,UACL,MAAM;AAAA,UACN,SAAS,EAAE,MAAM,UAAU,SAAS,GAAG,SAAS,GAAG,aAAa,+BAA+B;AAAA,UAC/F,cAAc,EAAE,MAAM,WAAW,aAAa,4DAA4D;AAAA,QAC5G;AAAA,QACA,UAAU,CAAC,KAAK;AAAA,QAChB,sBAAsB;AAAA,MACxB;AAAA,MACA,aAAa,EAAE,OAAO,uBAAuB,GAAG,MAAM;AAAA,MACtD,SAAS,CAAC,MAAM,YAAY,EAAE,gBAAgB,CAAC,CAAC;AAAA,IAClD;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,OAAO;AAAA,MACP,aAAa;AAAA,MACb,aAAa;AAAA,QACX,MAAM;AAAA,QACN,YAAY;AAAA,UACV,SAAS,EAAE,MAAM,UAAU,SAAS,GAAG,SAAS,GAAG,aAAa,gBAAgB;AAAA,UAChF,SAAS,EAAE,MAAM,WAAW,aAAa,mBAAmB;AAAA,UAC5D,cAAc,EAAE,MAAM,WAAW,aAAa,qCAAqC;AAAA,UACnF,MAAM;AAAA,QACR;AAAA,QACA,sBAAsB;AAAA,MACxB;AAAA,MACA,aAAa,EAAE,OAAO,4BAA4B,GAAG,IAAI;AAAA,MACzD,SAAS,CAAC,MAAM,YAAY,EAAE,cAAc,CAAC,CAAC;AAAA,IAChD;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,OAAO;AAAA,MACP,aAAa;AAAA,MACb,aAAa;AAAA,MACb,aAAa,EAAE,OAAO,4BAA4B,GAAG,YAAY;AAAA,MACjE,SAAS,MAAM;AACb,UAAE,kBAAkB;AACpB,eAAO,EAAE,SAAS,KAAK;AAAA,MACzB;AAAA,IACF;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,OAAO;AAAA,MACP,aAAa;AAAA,MACb,aAAa;AAAA,QACX,MAAM;AAAA,QACN,YAAY;AAAA,UACV,KAAK;AAAA,UACL,MAAM,EAAE,MAAM,UAAU,WAAW,GAAG,aAAa,gBAAgB;AAAA,UACnE,GAAG,EAAE,MAAM,UAAU,aAAa,iCAAiC;AAAA,UACnE,GAAG,EAAE,MAAM,UAAU,aAAa,gCAAgC;AAAA,UAClE,cAAc,EAAE,MAAM,UAAU,SAAS,IAAI,SAAS,MAAM,aAAa,oDAAoD;AAAA,QAC/H;AAAA,QACA,UAAU,CAAC,KAAK;AAAA,QAChB,sBAAsB;AAAA,MACxB;AAAA,MACA,aAAa,EAAE,OAAO,yBAAyB,GAAG,MAAM;AAAA,MACxD,SAAS,CAAC,MAAM,QAAQ,EAAE,kBAAkB,CAAC,CAAC;AAAA,IAChD;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,OAAO;AAAA,MACP,aAAa;AAAA,MACb,aAAa;AAAA,MACb,aAAa,EAAE,OAAO,yBAAyB,GAAG,KAAK;AAAA,MACvD,SAAS,OAAO,EAAE,YAAY,OAAO,EAAE,WAAW,IAAI,OAAO,EAAE;AAAA,IACjE;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,OAAO;AAAA,MACP,aAAa;AAAA,MACb,aAAa;AAAA,QACX,MAAM;AAAA,QACN,YAAY;AAAA,UACV,IAAI,EAAE,MAAM,UAAU,aAAa,2CAA2C;AAAA,UAC9E,MAAM,EAAE,MAAM,UAAU,WAAW,GAAG,aAAa,gBAAgB;AAAA,UACnE,GAAG,EAAE,MAAM,UAAU,aAAa,iCAAiC;AAAA,UACnE,GAAG,EAAE,MAAM,UAAU,aAAa,gCAAgC;AAAA,UAClE,cAAc,EAAE,MAAM,UAAU,SAAS,IAAI,SAAS,MAAM,aAAa,gCAAgC;AAAA,UACzG,SAAS,EAAE,MAAM,WAAW,aAAa,mBAAmB;AAAA,QAC9D;AAAA,QACA,UAAU,CAAC,IAAI;AAAA,QACf,sBAAsB;AAAA,MACxB;AAAA,MACA,aAAa,EAAE,OAAO,4BAA4B,GAAG,IAAI;AAAA,MACzD,SAAS,CAAC,EAAE,IAAI,GAAG,EAAE,MAAM,QAAQ,EAAE,qBAAqB,IAAI,CAAC,CAAC;AAAA,IAClE;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,OAAO;AAAA,MACP,aAAa;AAAA,MACb,aAAa,EAAE,MAAM,UAAU,YAAY,EAAE,IAAI,EAAE,MAAM,UAAU,aAAa,2CAA2C,EAAE,GAAG,UAAU,CAAC,IAAI,GAAG,sBAAsB,MAAM;AAAA,MAC9K,aAAa,EAAE,OAAO,4BAA4B,GAAG,YAAY;AAAA,MACjE,SAAS,CAAC,EAAE,GAAG,MAAM;AACnB,UAAE,qBAAqB,EAAE;AACzB,eAAO,EAAE,SAAS,GAAG;AAAA,MACvB;AAAA,IACF;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,OAAO;AAAA,MACP,aAAa;AAAA,MACb,aAAa;AAAA,QACX,MAAM;AAAA,QACN,YAAY;AAAA,UACV,IAAI,EAAE,MAAM,UAAU,aAAa,2CAA2C;AAAA,UAC9E,GAAG,EAAE,MAAM,UAAU,SAAS,GAAG,aAAa,gCAA2B;AAAA,UACzE,GAAG,EAAE,MAAM,UAAU,SAAS,GAAG,aAAa,gCAA2B;AAAA,UACzE,UAAU,EAAE,MAAM,WAAW,aAAa,iDAAiD;AAAA,QAC7F;AAAA,QACA,UAAU,CAAC,MAAM,KAAK,GAAG;AAAA,QACzB,sBAAsB;AAAA,MACxB;AAAA,MACA,aAAa,EAAE,OAAO,kCAAkC,GAAG,IAAI;AAAA,MAC/D,SAAS,CAAC,EAAE,IAAI,GAAG,GAAG,SAAS,MAAM;AACnC,cAAM,QAAQ,EAAE,mBAAmB,IAAI,GAAG,CAAC;AAC3C,YAAI,SAAU,GAAE,SAAS,KAAK;AAC9B,eAAO,EAAE,MAAM;AAAA,MACjB;AAAA,IACF;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,OAAO;AAAA,MACP,aACE;AAAA,MACF,aAAa;AAAA,QACX,MAAM;AAAA,QACN,YAAY;AAAA,UACV,MAAM,EAAE,MAAM,UAAU,MAAM,CAAC,GAAG,aAAa,GAAG,aAAa,eAAe;AAAA,UAC9E,OAAO,EAAE,GAAG,OAAO,aAAa,kDAAkD;AAAA,UAClF,OAAO,EAAE,MAAM,UAAU,MAAM,CAAC,OAAO,KAAK,GAAG,aAAa,8CAAyC;AAAA,UACrG,QAAQ,EAAE,MAAM,UAAU,SAAS,GAAG,SAAS,IAAI,aAAa,oEAAoE;AAAA,QACtI;AAAA,QACA,UAAU,CAAC,MAAM;AAAA,QACjB,sBAAsB;AAAA,MACxB;AAAA,MACA,aAAa,EAAE,OAAO,oBAAoB,GAAG,KAAK;AAAA,MAClD,SAAS,CAAC,EAAE,MAAM,OAAO,OAAO,OAAO,OAAO,EAAE,MAAM,OAAO,SAAS,OAAO,QAAQ,EAAE,QAAQ,MAAM,EAAE,OAAO,OAAO,OAAO,CAAC,EAAE;AAAA,IACjI;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,OAAO;AAAA,MACP,aAAa;AAAA,MACb,aAAa;AAAA,MACb,aAAa,EAAE,OAAO,iBAAiB,GAAG,KAAK;AAAA,MAC/C,SAAS,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,IAAI,CAAC,GAAG,WAAW,EAAE,OAAO,GAAG,EAAE,EAAE,EAAE;AAAA,IACzF;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,OAAO;AAAA,MACP,aAAa;AAAA,MACb,aAAa;AAAA,QACX,MAAM;AAAA,QACN,YAAY,EAAE,OAAO,OAAO,MAAM,EAAE,MAAM,UAAU,WAAW,GAAG,aAAa,iBAAiB,EAAE;AAAA,QAClG,UAAU,CAAC,OAAO;AAAA,QAClB,sBAAsB;AAAA,MACxB;AAAA,MACA,aAAa,EAAE,OAAO,gBAAgB,GAAG,MAAM;AAAA,MAC/C,SAAS,CAAC,EAAE,OAAO,KAAK,OAAO,EAAE,UAAU,EAAE,UAAU,OAAO,IAAI,EAAE,IAAI,CAAC,GAAG,WAAW,EAAE,OAAO,GAAG,EAAE,EAAE,EAAE;AAAA,IAC3G;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,OAAO;AAAA,MACP,aAAa;AAAA,MACb,aAAa,EAAE,MAAM,UAAU,YAAY,EAAE,OAAO,EAAE,MAAM,WAAW,SAAS,GAAG,aAAa,iBAAiB,EAAE,GAAG,UAAU,CAAC,OAAO,GAAG,sBAAsB,MAAM;AAAA,MACvK,aAAa,EAAE,OAAO,mBAAmB,GAAG,YAAY;AAAA,MACxD,SAAS,CAAC,EAAE,MAAM,OAAO,EAAE,UAAU,EAAE,aAAa,KAAK,EAAE,IAAI,CAAC,GAAG,OAAO,EAAE,OAAO,GAAG,GAAG,EAAE,EAAE,EAAE;AAAA,IACjG;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,OAAO;AAAA,MACP,aACE;AAAA,MACF,aAAa;AAAA,QACX,MAAM;AAAA,QACN,YAAY;AAAA,UACV,QAAQ;AAAA,YACN,MAAM;AAAA,YACN,UAAU;AAAA,YACV,UAAU;AAAA,YACV,aAAa;AAAA,YACb,OAAO;AAAA,cACL,MAAM;AAAA,cACN,YAAY,EAAE,GAAG,EAAE,MAAM,UAAU,aAAa,SAAS,GAAG,GAAG,EAAE,MAAM,UAAU,aAAa,SAAS,GAAG,UAAU,EAAE,MAAM,UAAU,SAAS,GAAG,SAAS,GAAG,aAAa,wBAAwB,EAAE;AAAA,cACrM,UAAU,CAAC,KAAK,GAAG;AAAA,cACnB,sBAAsB;AAAA,YACxB;AAAA,UACF;AAAA,UACA,MAAM,EAAE,MAAM,UAAU,MAAM,CAAC,SAAS,OAAO,GAAG,aAAa,4BAA4B;AAAA,UAC3F,OAAO,EAAE,GAAG,OAAO,aAAa,iEAAiE;AAAA,UACjG,MAAM,EAAE,MAAM,UAAU,SAAS,GAAG,SAAS,KAAK,aAAa,wDAAwD;AAAA,QACzH;AAAA,QACA,UAAU,CAAC,QAAQ;AAAA,QACnB,sBAAsB;AAAA,MACxB;AAAA,MACA,aAAa,EAAE,OAAO,2BAA2B,GAAG,MAAM;AAAA,MAC1D,SAAS,CAAC,EAAE,QAAQ,MAAM,OAAO,KAAK,MAAM,EAAE,gBAAgB,QAAsB,EAAE,MAAM,OAAO,KAAK,CAAC;AAAA,IAC3G;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,OAAO;AAAA,MACP,aAAa;AAAA,MACb,aAAa;AAAA,QACX,MAAM;AAAA,QACN,YAAY;AAAA,UACV,GAAG,EAAE,MAAM,UAAU,SAAS,GAAG,SAAS,KAAK,aAAa,SAAS;AAAA,UACrE,GAAG,EAAE,MAAM,UAAU,SAAS,GAAG,SAAS,KAAK,aAAa,SAAS;AAAA,UACrE,QAAQ,EAAE,MAAM,WAAW,SAAS,GAAG,SAAS,IAAI,aAAa,0CAA0C;AAAA,UAC3G,UAAU,EAAE,MAAM,WAAW,aAAa,iDAAiD;AAAA,QAC7F;AAAA,QACA,UAAU,CAAC,KAAK,GAAG;AAAA,QACnB,sBAAsB;AAAA,MACxB;AAAA,MACA,aAAa,EAAE,OAAO,4BAA4B,GAAG,IAAI;AAAA,MACzD,SAAS,CAAC,EAAE,GAAG,GAAG,QAAQ,SAAS,OAAO,EAAE,OAAO,EAAE,cAAc,GAAG,GAAG,EAAE,QAAQ,SAAS,CAAC,EAAE;AAAA,IACjG;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,OAAO;AAAA,MACP,aAAa;AAAA,MACb,aAAa;AAAA,MACb,aAAa,EAAE,OAAO,wBAAwB,GAAG,YAAY;AAAA,MAC7D,SAAS,MAAM;AACb,UAAE,eAAe;AACjB,eAAO,EAAE,SAAS,KAAK;AAAA,MACzB;AAAA,IACF;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,OAAO;AAAA,MACP,aAAa;AAAA,MACb,aAAa;AAAA,MACb,aAAa,EAAE,OAAO,yBAAyB,GAAG,KAAK;AAAA,MACvD,SAAS,MAAM;AACb,cAAM,MAAM,EAAE;AACd,eAAO;AAAA,UACL,SAAS;AAAA,YACP,EAAE,MAAM,SAAS,MAAM,cAAc,UAAU,IAAI,OAAO,IAAI,QAAQ,IAAI,OAAO,CAAC,CAAC,GAAG,UAAU,YAAY;AAAA,YAC5G,EAAE,MAAM,QAAQ,MAAM,cAAc,IAAI,KAAK,OAAI,IAAI,MAAM,GAAG;AAAA,UAChE;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;;;ACpUA,IAAMC,QAAO,EAAE,cAAc,MAAM,iBAAiB,OAAO,gBAAgB,MAAM,eAAe,MAAM;AACtG,IAAMC,SAAQ,EAAE,cAAc,OAAO,iBAAiB,OAAO,gBAAgB,OAAO,eAAe,MAAM;AACzG,IAAMC,OAAM,EAAE,cAAc,OAAO,iBAAiB,OAAO,gBAAgB,MAAM,eAAe,MAAM;AACtG,IAAMC,eAAc,EAAE,cAAc,OAAO,iBAAiB,MAAM,gBAAgB,OAAO,eAAe,MAAM;AAE9G,IAAMC,SAAQ,EAAE,MAAM,UAAU,YAAY,CAAC,GAAG,sBAAsB,MAAM;AAC5E,IAAMC,SAAQ,EAAE,MAAM,UAAU,SAAS,qBAAqB,aAAa,kCAAkC;AAC7G,IAAM,WAAW,EAAE,MAAM,UAAU,aAAa,wDAAwD;AAgBxG,IAAM,MAAM;AAAA,EACV,MAAM;AAAA,EACN,aAAa;AAAA,EACb,YAAY;AAAA,IACV,MAAM,EAAE,MAAM,UAAU,SAAS,GAAG,SAAS,gBAAgB,aAAa,+BAA+B;AAAA,IACzG,UAAU,EAAE,MAAM,UAAU,SAAS,GAAG,SAAS,GAAG,aAAa,uCAAuC;AAAA,IACxG,SAAS,EAAE,MAAM,UAAU,SAAS,MAAM,SAAS,IAAI,aAAa,2EAA2E;AAAA,IAC/I,OAAO,EAAE,MAAM,UAAU,SAAS,MAAM,SAAS,KAAK,aAAa,+HAA+H;AAAA,IAClM,WAAW,EAAE,MAAM,UAAU,SAAS,MAAM,SAAS,GAAG,aAAa,4EAA4E;AAAA,IACjJ,SAAS,EAAE,MAAM,UAAU,SAAS,GAAG,SAAS,GAAG,aAAa,4DAA4D;AAAA,IAC5H,MAAM,EAAE,MAAM,UAAU,SAAS,GAAG,SAAS,GAAG,aAAa,sFAAsF;AAAA,IACnJ,WAAW,EAAE,MAAM,UAAU,SAAS,GAAG,SAAS,MAAM,aAAa,4CAA4C;AAAA,IACjH,cAAc,EAAE,MAAM,WAAW,aAAa,uDAAuD;AAAA,IACrG,iBAAiB,EAAE,MAAM,WAAW,aAAa,+BAA+B;AAAA,IAChF,OAAO;AAAA,MACL,MAAM;AAAA,MACN,MAAM,YAAY,IAAI,CAAC,MAAM,EAAE,EAAE;AAAA,MACjC,aAAa;AAAA,IACf;AAAA,EACF;AAAA,EACA,sBAAsB;AACxB;AAEA,IAAM,WAAW;AAAA,EACf,MAAM;AAAA,EACN,aAAa;AAAA,EACb,YAAY;AAAA,IACV,SAAS,EAAE,MAAM,UAAU,SAAS,GAAG,SAAS,GAAG,aAAa,4EAA4E;AAAA,IAC5I,cAAc,EAAE,MAAM,UAAU,SAAS,GAAG,SAAS,GAAG,aAAa,iCAAiC;AAAA,IACtG,UAAU,EAAE,MAAM,UAAU,SAAS,GAAG,SAAS,GAAG,aAAa,sDAAmD;AAAA,IACpH,eAAe,EAAE,MAAM,UAAU,SAAS,GAAG,SAAS,GAAG,aAAa,oFAAoF;AAAA,IAC1J,aAAa,EAAE,MAAM,UAAU,SAAS,GAAG,SAAS,GAAG,aAAa,yCAAyC;AAAA,IAC7G,cAAc,EAAE,MAAM,UAAU,SAAS,IAAI,SAAS,GAAG,aAAa,mFAAmF;AAAA,IACzJ,iBAAiB,EAAE,MAAM,UAAU,SAAS,IAAI,SAAS,GAAG,aAAa,6EAA6E;AAAA,IACtJ,YAAY,EAAE,MAAM,UAAU,SAAS,GAAG,SAAS,GAAG,aAAa,8BAA8B;AAAA,IACjG,aAAa,EAAE,MAAM,UAAU,SAAS,GAAG,SAAS,GAAG,aAAa,sDAAgD;AAAA,IACpH,eAAe,EAAE,MAAM,UAAU,SAAS,GAAG,SAAS,GAAG,aAAa,+BAA+B;AAAA,IACrG,SAAS,EAAE,MAAM,UAAU,SAAS,GAAG,SAAS,GAAG,aAAa,iDAAiD;AAAA,EACnH;AAAA,EACA,sBAAsB;AACxB;AAEA,IAAM,QAAQ;AAAA,EACZ,MAAM;AAAA,EACN,aAAa;AAAA,EACb,YAAY;AAAA,IACV,KAAK,EAAE,MAAM,UAAU,SAAS,GAAG,SAAS,GAAG,aAAa,0DAA0D;AAAA,IACtH,MAAM,EAAE,MAAM,UAAU,SAAS,GAAG,SAAS,GAAG,aAAa,0FAA0F;AAAA,IACvJ,KAAK,EAAE,MAAM,UAAU,SAAS,GAAG,SAAS,GAAG,aAAa,kFAAkF;AAAA,IAC9I,gBAAgB,EAAE,MAAM,WAAW,aAAa,2DAA2D;AAAA,IAC3G,iBAAiB,EAAE,MAAM,WAAW,aAAa,2CAA2C;AAAA,IAC5F,QAAQ,EAAE,MAAM,UAAU,MAAM,CAAC,GAAG,aAAa,GAAG,aAAa,+DAA+D;AAAA,EAClI;AAAA,EACA,sBAAsB;AACxB;AAEA,IAAM,eAAe;AAAA,EACnB,MAAM,EAAE,MAAM,UAAU,WAAW,GAAG,WAAW,IAAI,aAAa,gBAAgB;AAAA,EAClF,UAAU,EAAE,MAAM,UAAU,MAAM,CAAC,GAAG,sBAAsB,GAAG,aAAa,oBAAoB;AAAA,EAChG,QAAQ,EAAE,MAAM,UAAU,MAAM,CAAC,GAAG,mBAAmB,GAAG,aAAa,2GAA2G;AAAA,EAClL,KAAK;AAAA,EACL,OAAO,EAAE,MAAM,UAAU,SAAS,GAAG,SAAS,GAAG,aAAa,mJAAmJ;AAAA,EACjN,mBAAmB,EAAE,MAAM,UAAU,SAAS,GAAG,SAAS,MAAM,aAAa,gEAAgE;AAAA,EAC7I,UAAU,EAAE,MAAM,UAAU,MAAM,CAAC,GAAG,eAAe,GAAG,aAAa,8HAA8H;AAAA,EACnM,UAAU;AAAA,EACV,OAAO;AAAA,EACP,YAAY,EAAE,MAAM,WAAW,aAAa,mGAAmG;AACjJ;AAEA,IAAM,SAAS;AAAA,EACb,MAAM;AAAA,EACN,UAAU;AAAA,EACV,UAAU;AAAA,EACV,aAAa;AAAA,EACb,OAAO;AAAA,IACL,MAAM;AAAA,IACN,YAAY;AAAA,MACV,GAAG,EAAE,MAAM,UAAU,aAAa,wBAAwB;AAAA,MAC1D,GAAG,EAAE,MAAM,UAAU,aAAa,wBAAwB;AAAA,MAC1D,UAAU,EAAE,MAAM,UAAU,SAAS,GAAG,SAAS,GAAG,aAAa,iCAAiC;AAAA,MAClG,GAAG,EAAE,MAAM,UAAU,aAAa,uGAAuG;AAAA,MACzI,OAAO,EAAE,MAAM,UAAU,SAAS,KAAK,SAAS,IAAI,aAAa,yDAAyD;AAAA,MAC1H,OAAO,EAAE,MAAM,UAAU,SAAS,KAAK,SAAS,IAAI,aAAa,yDAAyD;AAAA,MAC1H,UAAU,EAAE,MAAM,UAAU,SAAS,GAAG,SAAS,QAAQ,aAAa,mFAAmF;AAAA,MACzJ,SAAS,EAAE,MAAM,UAAU,SAAS,GAAG,SAAS,QAAQ,aAAa,kEAAkE;AAAA,MACvI,OAAO,EAAE,MAAM,UAAU,SAAS,GAAG,SAAS,KAAK,aAAa,6DAA6D;AAAA,IAC/H;AAAA,IACA,UAAU,CAAC,KAAK,GAAG;AAAA,IACnB,sBAAsB;AAAA,EACxB;AACF;AAEA,SAAS,WAAW,MAAiB;AACnC,QAAM,MAAM,CAAC,MAAiC,IAAI,MAAM,EAAE,IAAI,CAAC,MAAM,KAAK,MAAM,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,CAAC,CAAC,IAAI,GAAG,EAAE,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG,CAAC,EAAE,KAAK,EAAE,IAAI;AAC7J,SAAO,EAAE,WAAW,IAAI,KAAK,SAAS,GAAG,QAAQ,KAAK,MAAM,KAAK,SAAS,GAAI,IAAI,KAAM,QAAQ,IAAI,KAAK,MAAM,EAAE;AACnH;AAEA,SAAS,aAAa,GAAe;AACnC,SAAO,EAAE,IAAI,EAAE,IAAI,MAAM,EAAE,MAAM,UAAU,EAAE,UAAU,QAAQ,EAAE,QAAQ,MAAM,EAAE,IAAI,MAAM,OAAO,EAAE,OAAO,UAAU,EAAE,UAAU,SAAS,QAAQ,EAAE,OAAO,EAAE;AAC/J;AAGO,SAAS,8BAA8B,YAAmC,UAA0C,CAAC,GAAsB;AAChJ,QAAM,IAAI;AACV,QAAM,QAAqB,CAAC;AAC5B,QAAM,MAAM,CAAC,MAAiB,MAAM,KAAK,CAAC;AAE1C,QAAM,MAAM,OAAU,SAA4B,WAAgC;AAChF,QAAI,CAAC,QAAQ,SAAU,QAAO,OAAO;AACrC,UAAM,CAAC,CAAC,IAAI,MAAM,QAAQ,SAAS,QAAQ,QAAQ,SAAS,EAAE,IAAI,SAAS,MAAM,QAAQ,GAAG,CAAC,OAAO,CAAC;AACrG,QAAI,CAAC,KAAK,CAAC,EAAE,GAAI,OAAM,IAAI,MAAM,KAAK,CAAC,EAAE,KAAK,EAAE,UAAU,uCAAuC;AACjG,WAAO,EAAE;AAAA,EACX;AAIA,MAAI;AAAA,IACF,MAAM;AAAA,IACN,OAAO;AAAA,IACP,aACE;AAAA,IACF,aAAaD;AAAA,IACb,aAAa,EAAE,OAAO,kBAAkB,GAAGJ,MAAK;AAAA,IAChD,SAAS,MAAM;AACb,YAAM,IAAI,EAAE,SAAS;AACrB,YAAM,IAAI,EAAE;AACZ,aAAO;AAAA,QACL,OAAO,EAAE,OAAO;AAAA,QAChB,QAAQ,EAAE,OAAO;AAAA,QACjB,KAAK,EAAE,OAAO;AAAA,QACd,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,MAAM,EAAE,MAAM,MAAM,OAAO,EAAE,MAAM,OAAO,OAAO,EAAE,MAAM,MAAM;AAAA,QAChG,eAAe,EAAE;AAAA,QACjB,YAAY,EAAE,WAAW,EAAE;AAAA,QAC3B,SAAS,EAAE,MAAM;AAAA,QACjB,OAAO,EAAE;AAAA,QACT,gBAAgB,EAAE;AAAA,QAClB,MAAM,EAAE,MAAM,EAAE,KAAK,MAAM,UAAU,EAAE,KAAK,UAAU,QAAQ,EAAE,KAAK,OAAO;AAAA,QAC5E,MAAM,EAAE;AAAA,QACR,SAAS,EAAE,QAAQ;AAAA,QACnB,MAAM,EAAE;AAAA,QACR,MAAM,EAAE;AAAA,QACR,YAAY,YAAY,IAAI,CAAC,MAAM,EAAE,EAAE;AAAA,MACzC;AAAA,IACF;AAAA,EACF,CAAC;AAED,MAAI;AAAA,IACF,MAAM;AAAA,IACN,OAAO;AAAA,IACP,aACE;AAAA,IACF,aAAa;AAAA,MACX,MAAM;AAAA,MACN,YAAY;AAAA,QACV,OAAO,EAAE,MAAM,WAAW,SAAS,GAAG,SAAS,iBAAiB,aAAa,+CAA+C;AAAA,QAC5H,QAAQ,EAAE,MAAM,WAAW,SAAS,GAAG,SAAS,iBAAiB,aAAa,iDAAiD;AAAA,QAC/H,KAAK,EAAE,MAAM,UAAU,SAAS,GAAG,SAAS,KAAO,aAAa,qEAAqE;AAAA,QACrI,OAAO,EAAE,MAAM,UAAU,aAAa,gEAAgE;AAAA,MACxG;AAAA,MACA,sBAAsB;AAAA,IACxB;AAAA,IACA,aAAa,EAAE,OAAO,sBAAsB,GAAGG,aAAY;AAAA,IAC3D,SAAS,CAAC,MAAM;AACd,YAAM,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,QAAQ,EAAE,QAAQ,KAAK,EAAE,KAAK,OAAO,EAAE,MAAM,CAAC;AACtF,aAAO,EAAE,OAAO,EAAE,OAAO,OAAO,QAAQ,EAAE,OAAO,QAAQ,KAAK,EAAE,OAAO,KAAK,OAAO,EAAE,MAAM,QAAQ,SAAS,EAAE,cAAc;AAAA,IAC9H;AAAA,EACF,CAAC;AAED,MAAI;AAAA,IACF,MAAM;AAAA,IACN,OAAO;AAAA,IACP,aACE;AAAA,IACF,aAAa;AAAA,MACX,MAAM;AAAA,MACN,YAAY;AAAA,QACV,OAAO,EAAE,MAAM,WAAW,SAAS,GAAG,SAAS,iBAAiB,aAAa,uCAAuC;AAAA,QACpH,QAAQ,EAAE,MAAM,WAAW,SAAS,GAAG,SAAS,iBAAiB,aAAa,wCAAwC;AAAA,QACtH,KAAK,EAAE,MAAM,UAAU,SAAS,GAAG,SAAS,KAAO,aAAa,uCAAuC;AAAA,MACzG;AAAA,MACA,sBAAsB;AAAA,IACxB;AAAA,IACA,aAAa,EAAE,OAAO,qBAAqB,GAAGD,KAAI;AAAA,IAClD,SAAS,CAAC,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,QAAQ,EAAE,QAAQ,KAAK,EAAE,IAAI,CAAC;AAAA,EAC9E,CAAC;AAID,MAAI;AAAA,IACF,MAAM;AAAA,IACN,OAAO;AAAA,IACP,aACE;AAAA,IACF,aAAaE;AAAA,IACb,aAAa,EAAE,OAAO,eAAe,GAAGJ,MAAK;AAAA,IAC7C,SAAS,OAAO;AAAA,MACd,QAAQ,cAAc,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,QAAQ,MAAM,EAAE,MAAM,QAAQ,EAAE,QAAQ,SAAS,EAAE,SAAS,OAAO,EAAE,OAAO,OAAO,EAAE,OAAO,YAAY,EAAE,YAAY,cAAc,EAAE,cAAc,WAAW,EAAE,UAAU,EAAE;AAAA,MACvN,UAAU,CAAC,GAAG,cAAc;AAAA,MAC5B,UAAU,CAAC,GAAG,cAAc;AAAA,IAC9B;AAAA,EACF,CAAC;AAED,MAAI;AAAA,IACF,MAAM;AAAA,IACN,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAaI;AAAA,IACb,aAAa,EAAE,OAAO,iBAAiB,GAAGJ,MAAK;AAAA,IAC/C,SAAS,MAAM,KAAK,MAAM,KAAK,UAAU,EAAE,SAAS,KAAK,CAAC;AAAA,EAC5D,CAAC;AAED,QAAMM,UAAS;AAAA,IACb,MAAM;AAAA,IACN,YAAY;AAAA,MACV,UAAU,EAAE,MAAM,UAAU,SAAS,GAAG,SAAS,GAAG,aAAa,iDAAiD;AAAA,MAClH,QAAQ,EAAE,MAAM,WAAW,aAAa,0BAA0B;AAAA,IACpE;AAAA,IACA,sBAAsB;AAAA,EACxB;AAEA,MAAI;AAAA,IACF,MAAM;AAAA,IACN,OAAO;AAAA,IACP,aACE;AAAA,IACF,aAAa;AAAA,MACX,MAAM;AAAA,MACN,YAAY;AAAA,QACV,QAAQ,EAAE,MAAM,UAAU,aAAa,+EAA+E;AAAA,QACtH,OAAO,EAAE,GAAGD,QAAO,aAAa,wBAAwB;AAAA,QACxD,OAAO,EAAE,MAAM,UAAU,SAAS,GAAG,SAAS,GAAG,aAAa,kDAAkD;AAAA,QAChH,OAAO,EAAE,MAAM,UAAU,SAAS,MAAM,SAAS,GAAG,aAAa,6CAA6C;AAAA,QAC9G,MAAM,EAAE,MAAM,WAAW,SAAS,GAAG,aAAa,+CAA+C;AAAA,QACjG,SAAS,EAAE,MAAM,UAAU,MAAM,CAAC,GAAG,cAAc,GAAG,aAAa,iBAAiB;AAAA,QACpF,QAAQ,EAAE,MAAM,UAAU,MAAM,CAAC,UAAU,QAAQ,GAAG,aAAa,mDAAmD;AAAA,QACtH,SAAS,EAAE,MAAM,UAAU,SAAS,GAAG,SAAS,GAAG,aAAa,8CAA8C;AAAA,QAC9G,KAAK,EAAE,GAAGC,SAAQ,aAAa,mCAAmC;AAAA,QAClE,KAAK,EAAE,GAAGA,SAAQ,aAAa,sDAAsD;AAAA,QACrF,YAAY,EAAE,MAAM,UAAU,SAAS,GAAG,SAAS,GAAG,aAAa,gEAAgE;AAAA,QACnI,cAAc,EAAE,MAAM,UAAU,SAAS,GAAG,SAAS,GAAG,aAAa,oEAAoE;AAAA,QACzI,WAAW,EAAE,MAAM,UAAU,SAAS,GAAG,SAAS,GAAG,aAAa,oEAAoE;AAAA,QACtI,MAAM,EAAE,MAAM,UAAU,WAAW,GAAG,aAAa,gBAAgB;AAAA,MACrE;AAAA,MACA,sBAAsB;AAAA,IACxB;AAAA,IACA,aAAa,EAAE,OAAO,iBAAiB,GAAGJ,KAAI;AAAA,IAC9C,SAAS,CAAC,MAAM,EAAE,SAAS,CAAC;AAAA,EAC9B,CAAC;AAID,MAAI;AAAA,IACF,MAAM;AAAA,IACN,OAAO;AAAA,IACP,aACE;AAAA,IACF,aAAaE;AAAA,IACb,aAAa,EAAE,OAAO,eAAe,GAAGJ,MAAK;AAAA,IAC7C,SAAS,OAAO,EAAE,QAAQ,EAAE,WAAW,GAAG,eAAe,EAAE,SAAS,cAAc;AAAA,EACpF,CAAC;AAED,MAAI;AAAA,IACF,MAAM;AAAA,IACN,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAa;AAAA,MACX,MAAM;AAAA,MACN,YAAY;AAAA,QACV,MAAM,EAAE,MAAM,UAAU,WAAW,GAAG,aAAa,kCAAkC;AAAA,QACrF,MAAM,EAAE,MAAM,UAAU,MAAM,CAAC,SAAS,OAAO,GAAG,aAAa,4BAA4B;AAAA,QAC3F,SAAS,EAAE,MAAM,UAAU,aAAa,+DAA+D;AAAA,QACvG,UAAU,EAAE,MAAM,UAAU,aAAa,2CAA2C;AAAA,MACtF;AAAA,MACA,sBAAsB;AAAA,IACxB;AAAA,IACA,aAAa,EAAE,OAAO,eAAe,GAAGC,OAAM;AAAA,IAC9C,SAAS,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,MAAM,EAAE,MAAM,SAAS,EAAE,SAAS,UAAU,EAAE,SAAS,CAAC;AAAA,EACrG,CAAC;AAED,MAAI;AAAA,IACF,MAAM;AAAA,IACN,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAa;AAAA,MACX,MAAM;AAAA,MACN,YAAY;AAAA,QACV,SAAS,EAAE,MAAM,UAAU,aAAa,6BAA6B;AAAA,QACrE,MAAM,EAAE,MAAM,UAAU,WAAW,GAAG,aAAa,YAAY;AAAA,QAC/D,SAAS,EAAE,MAAM,WAAW,aAAa,gBAAgB;AAAA,QACzD,SAAS,EAAE,MAAM,UAAU,SAAS,GAAG,SAAS,GAAG,aAAa,sBAAsB;AAAA,QACtF,OAAO;AAAA,UACL,MAAM;AAAA,UACN,MAAM,CAAC,GAAG,YAAY,IAAI,CAAC,MAAM,EAAE,EAAE,GAAG,cAAc;AAAA,UACtD,aAAa;AAAA,QACf;AAAA,QACA,SAAS,EAAE,MAAM,WAAW,aAAa,iEAAiE;AAAA,QAC1G,OAAO;AAAA,UACL,MAAM;AAAA,UACN,aAAa;AAAA,UACb,YAAY;AAAA,YACV,QAAQ,EAAE,MAAM,WAAW,aAAa,mBAAmB;AAAA,YAC3D,cAAc,EAAE,MAAM,WAAW,aAAa,gDAAgD;AAAA,YAC9F,UAAU,EAAE,MAAM,WAAW,aAAa,iBAAiB;AAAA,YAC3D,KAAK,EAAE,MAAM,WAAW,aAAa,uDAAuD;AAAA,UAC9F;AAAA,UACA,sBAAsB;AAAA,QACxB;AAAA,MACF;AAAA,MACA,UAAU,CAAC,SAAS;AAAA,MACpB,sBAAsB;AAAA,IACxB;AAAA,IACA,aAAa,EAAE,OAAO,kBAAkB,GAAGC,KAAI;AAAA,IAC/C,SAAS,CAAC,EAAE,SAAS,GAAG,EAAE,MAAM,EAAE,YAAY,SAAS,CAA0B;AAAA,EACnF,CAAC;AAED,MAAI;AAAA,IACF,MAAM;AAAA,IACN,OAAO;AAAA,IACP,aACE;AAAA,IACF,aAAaE;AAAA,IACb,aAAa,EAAE,OAAO,oBAAoB,GAAGJ,MAAK;AAAA,IAClD,SAAS,OAAO;AAAA,MACd,OAAO,YAAY,IAAI,CAAC,OAAO;AAAA,QAC7B,IAAI,EAAE;AAAA,QACN,OAAO,EAAE;AAAA,QACT,OAAO,EAAE,YAAY,cAAc,EAAE,OAAO,YAAY,YAAY;AAAA,QACpE,GAAI,EAAE,cAAc,EAAE,aAAa,EAAE,YAAY,IAAI,CAAC;AAAA,QACtD,KAAK,kBAAkB,EAAE,EAAE;AAAA,MAC7B,EAAE;AAAA,IACJ;AAAA,EACF,CAAC;AAED,MAAI;AAAA,IACF,MAAM;AAAA,IACN,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAa,EAAE,MAAM,UAAU,YAAY,EAAE,SAAS,EAAE,MAAM,UAAU,aAAa,6BAA6B,EAAE,GAAG,UAAU,CAAC,SAAS,GAAG,sBAAsB,MAAM;AAAA,IAC1K,aAAa,EAAE,OAAO,2BAA2B,GAAGE,KAAI;AAAA,IACxD,SAAS,CAAC,EAAE,QAAQ,MAAM;AACxB,QAAE,eAAe,OAAO;AACxB,aAAO,EAAE,cAAc,EAAE,SAAS,OAAO,CAAE;AAAA,IAC7C;AAAA,EACF,CAAC;AAED,MAAI;AAAA,IACF,MAAM;AAAA,IACN,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAa,EAAE,MAAM,UAAU,YAAY,EAAE,SAAS,EAAE,MAAM,UAAU,aAAa,6BAA6B,EAAE,GAAG,UAAU,CAAC,SAAS,GAAG,sBAAsB,MAAM;AAAA,IAC1K,aAAa,EAAE,OAAO,kBAAkB,GAAGC,aAAY;AAAA,IACvD,SAAS,CAAC,EAAE,QAAQ,MAAM,EAAE,YAAY,OAAO;AAAA,EACjD,CAAC;AAED,MAAI;AAAA,IACF,MAAM;AAAA,IACN,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAa,EAAE,MAAM,UAAU,YAAY,EAAE,SAAS,EAAE,MAAM,UAAU,aAAa,6BAA6B,EAAE,GAAG,UAAU,CAAC,SAAS,GAAG,sBAAsB,MAAM;AAAA,IAC1K,aAAa,EAAE,OAAO,qBAAqB,GAAGF,OAAM;AAAA,IACpD,SAAS,CAAC,EAAE,QAAQ,MAAM,EAAE,eAAe,OAAO;AAAA,EACpD,CAAC;AAED,MAAI;AAAA,IACF,MAAM;AAAA,IACN,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAa;AAAA,MACX,MAAM;AAAA,MACN,YAAY;AAAA,QACV,SAAS,EAAE,MAAM,UAAU,aAAa,6BAA6B;AAAA,QACrE,OAAO,EAAE,MAAM,WAAW,SAAS,GAAG,aAAa,+CAA+C;AAAA,QAClG,UAAU,EAAE,MAAM,CAAC,UAAU,MAAM,GAAG,aAAa,iFAAiF;AAAA,MACtI;AAAA,MACA,UAAU,CAAC,WAAW,OAAO;AAAA,MAC7B,sBAAsB;AAAA,IACxB;AAAA,IACA,aAAa,EAAE,OAAO,mBAAmB,GAAGA,OAAM;AAAA,IAClD,SAAS,CAAC,EAAE,SAAS,OAAO,SAAS,MAAM,EAAE,UAAU,SAAS,OAAO,QAAQ;AAAA,EACjF,CAAC;AAED,MAAI;AAAA,IACF,MAAM;AAAA,IACN,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAa,EAAE,MAAM,UAAU,YAAY,EAAE,SAAS,EAAE,MAAM,UAAU,aAAa,qCAAqC,EAAE,GAAG,UAAU,CAAC,SAAS,GAAG,sBAAsB,MAAM;AAAA,IAClL,aAAa,EAAE,OAAO,sBAAsB,GAAGE,aAAY;AAAA,IAC3D,SAAS,CAAC,EAAE,QAAQ,MAAM,EAAE,UAAU,OAAO;AAAA,EAC/C,CAAC;AAED,MAAI;AAAA,IACF,MAAM;AAAA,IACN,OAAO;AAAA,IACP,aACE;AAAA,IACF,aAAa;AAAA,MACX,MAAM;AAAA,MACN,YAAY;AAAA,QACV,SAAS;AAAA,QACT,OAAO,EAAE,GAAGE,QAAO,aAAa,kDAAkD;AAAA,QAClF,SAAS,EAAE,MAAM,UAAU,SAAS,GAAG,SAAS,GAAG,aAAa,4BAA4B;AAAA,QAC5F,OAAO,EAAE,MAAM,UAAU,SAAS,GAAG,SAAS,GAAG,aAAa,+CAA+C;AAAA,QAC7G,UAAU,EAAE,MAAM,UAAU,SAAS,GAAG,SAAS,GAAG,aAAa,4DAA4D;AAAA,QAC7H,OAAO,EAAE,MAAM,UAAU,MAAM,YAAY,IAAI,CAAC,MAAM,EAAE,EAAE,GAAG,aAAa,kGAAkG;AAAA,MAC9K;AAAA,MACA,sBAAsB;AAAA,IACxB;AAAA,IACA,aAAa,EAAE,OAAO,gBAAgB,GAAGJ,OAAM;AAAA,IAC/C,SAAS,CAAC,MAAM,IAAI,EAAE,MAAM,QAAQ,MAAM,EAAE,GAAG,MAAM,EAAE,UAAU,CAAC,CAAC;AAAA,EACrE,CAAC;AAED,MAAI;AAAA,IACF,MAAM;AAAA,IACN,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAa,EAAE,MAAM,UAAU,YAAY,EAAE,SAAS,SAAS,GAAG,sBAAsB,MAAM;AAAA,IAC9F,aAAa,EAAE,OAAO,iBAAiB,GAAGE,aAAY;AAAA,IACtD,SAAS,CAAC,EAAE,QAAQ,MAAM,EAAE,WAAW,OAAO;AAAA,EAChD,CAAC;AAID,MAAI;AAAA,IACF,MAAM;AAAA,IACN,OAAO;AAAA,IACP,aACE;AAAA,IACF,aAAaC;AAAA,IACb,aAAa,EAAE,OAAO,gBAAgB,GAAGJ,MAAK;AAAA,IAC9C,SAAS,MAAM;AACb,YAAM,IAAI,EAAE,SAAS;AACrB,aAAO,EAAE,eAAe,EAAE,MAAM,IAAI,cAAc,CAAC,EAAE,MAAM,WAAW,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,OAAO,GAAG,SAAS,EAAE,QAAQ,IAAI,YAAY,EAAE;AAAA,IACvJ;AAAA,EACF,CAAC;AAED,MAAI;AAAA,IACF,MAAM;AAAA,IACN,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAa,EAAE,MAAM,UAAU,YAAY,EAAE,IAAI,EAAE,MAAM,UAAU,aAAa,yDAAyD,EAAE,GAAG,sBAAsB,MAAM;AAAA,IAC1K,aAAa,EAAE,OAAO,eAAe,GAAGA,MAAK;AAAA,IAC7C,SAAS,CAAC,EAAE,GAAG,MAAM;AACnB,UAAI,OAAO,OAAW,QAAO,YAAY,EAAE,SAAS,EAAE,KAAK;AAC3D,YAAM,IAAI,EAAE,SAAS,EAAE;AACvB,UAAI,CAAC,EAAG,OAAM,IAAI,MAAM,kBAAkB,EAAE,mCAAmC;AAC/E,aAAO,EAAE,GAAG,YAAY,CAAC,GAAG,SAAS,QAAQ,EAAE,OAAO,EAAE;AAAA,IAC1D;AAAA,EACF,CAAC;AAED,MAAI;AAAA,IACF,MAAM;AAAA,IACN,OAAO;AAAA,IACP,aACE;AAAA,IACF,aAAa,EAAE,MAAM,UAAU,YAAY,EAAE,IAAI,EAAE,MAAM,UAAU,aAAa,4CAA4C,GAAG,GAAG,aAAa,GAAG,sBAAsB,MAAM;AAAA,IAC9K,aAAa,EAAE,OAAO,iBAAiB,GAAGE,KAAI;AAAA,IAC9C,SAAS,CAAC,MAAM,YAAY,EAAE,SAAS,CAAC,CAAC;AAAA,EAC3C,CAAC;AAED,MAAI;AAAA,IACF,MAAM;AAAA,IACN,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAa;AAAA,MACX,MAAM;AAAA,MACN,YAAY;AAAA,QACV,IAAI,EAAE,MAAM,UAAU,SAAS,6BAA6B,aAAa,oDAAoD;AAAA,QAC7H,MAAM,EAAE,MAAM,UAAU,WAAW,GAAG,WAAW,IAAI,aAAa,yCAAyC;AAAA,MAC7G;AAAA,MACA,UAAU,CAAC,IAAI;AAAA,MACf,sBAAsB;AAAA,IACxB;AAAA,IACA,aAAa,EAAE,OAAO,gBAAgB,GAAGA,KAAI;AAAA,IAC7C,SAAS,CAAC,EAAE,IAAI,KAAK,MAAM,YAAY,EAAE,UAAU,EAAE,IAAI,KAAK,CAAC,CAAC;AAAA,EAClE,CAAC;AAED,MAAI;AAAA,IACF,MAAM;AAAA,IACN,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAa,EAAE,MAAM,UAAU,YAAY,EAAE,IAAI,EAAE,MAAM,UAAU,aAAa,mCAAmC,EAAE,GAAG,UAAU,CAAC,IAAI,GAAG,sBAAsB,MAAM;AAAA,IACtK,aAAa,EAAE,OAAO,wBAAwB,GAAGC,aAAY;AAAA,IAC7D,SAAS,CAAC,EAAE,GAAG,MAAM;AACnB,QAAE,YAAY,EAAE;AAChB,aAAO,EAAE,SAAS,GAAG;AAAA,IACvB;AAAA,EACF,CAAC;AAED,MAAI;AAAA,IACF,MAAM;AAAA,IACN,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAa;AAAA,MACX,MAAM;AAAA,MACN,YAAY,EAAE,KAAK,EAAE,MAAM,SAAS,OAAO,EAAE,MAAM,UAAU,aAAa,YAAY,GAAG,aAAa,0DAA0D,EAAE;AAAA,MAClK,sBAAsB;AAAA,IACxB;AAAA,IACA,aAAa,EAAE,OAAO,kBAAkB,GAAGH,MAAK;AAAA,IAChD,SAAS,CAAC,EAAE,IAAI,MAAM,EAAE,cAAc,GAAG;AAAA,EAC3C,CAAC;AAED,MAAI;AAAA,IACF,MAAM;AAAA,IACN,OAAO;AAAA,IACP,aACE;AAAA,IACF,aAAa;AAAA,MACX,MAAM;AAAA,MACN,YAAY;AAAA,QACV,SAAS,EAAE,MAAM,UAAU,aAAa,8EAA8E;AAAA,QACtH,SAAS,EAAE,MAAM,WAAW,aAAa,yDAAyD;AAAA,MACpG;AAAA,MACA,UAAU,CAAC,SAAS;AAAA,MACpB,sBAAsB;AAAA,IACxB;AAAA,IACA,aAAa,EAAE,OAAO,kBAAkB,GAAGC,OAAM;AAAA,IACjD,SAAS,CAAC,EAAE,SAAS,QAAQ,MAAM,EAAE,cAAc,SAAS,EAAE,QAAQ,CAAC;AAAA,EACzE,CAAC;AAED,MAAI;AAAA,IACF,MAAM;AAAA,IACN,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAa;AAAA,MACX,MAAM;AAAA,MACN,YAAY;AAAA,QACV,IAAI,EAAE,MAAM,UAAU,aAAa,yDAAyD;AAAA,QAC5F,OAAO,EAAE,MAAM,WAAW,SAAS,IAAI,SAAS,KAAK,aAAa,iCAAiC;AAAA,QACnG,QAAQ,EAAE,MAAM,WAAW,SAAS,IAAI,SAAS,KAAK,aAAa,iCAAiC;AAAA,QACpG,OAAO,EAAE,GAAGI,QAAO,aAAa,4CAA4C;AAAA,MAC9E;AAAA,MACA,sBAAsB;AAAA,IACxB;AAAA,IACA,aAAa,EAAE,OAAO,4BAA4B,GAAGL,MAAK;AAAA,IAC1D,SAAS,CAAC,EAAE,IAAI,OAAO,QAAQ,MAAM,MAAM;AACzC,YAAM,IAAI,EAAE,eAAe,MAAM,EAAE,SAAS,EAAE,MAAM,IAAI,EAAE,OAAO,QAAQ,MAAM,CAAC;AAChF,aAAO;AAAA,QACL,SAAS;AAAA,UACP,EAAE,MAAM,SAAS,MAAM,cAAc,UAAU,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,GAAG,UAAU,YAAY;AAAA,UAClG,EAAE,MAAM,QAAQ,MAAM,SAAS,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,OAAI,EAAE,MAAM,GAAG;AAAA,QACtF;AAAA,MACF;AAAA,IACF;AAAA,EACF,CAAC;AAID,MAAI;AAAA,IACF,MAAM;AAAA,IACN,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAa;AAAA,MACX,MAAM;AAAA,MACN,YAAY,EAAE,OAAO,EAAE,GAAGK,QAAO,aAAa,wBAAwB,GAAG,gBAAgB,EAAE,GAAGA,QAAO,aAAa,yBAAyB,EAAE;AAAA,MAC7I,sBAAsB;AAAA,IACxB;AAAA,IACA,aAAa,EAAE,OAAO,wBAAwB,GAAGH,KAAI;AAAA,IACrD,SAAS,CAAC,EAAE,OAAO,eAAe,MAAM;AACtC,UAAI,UAAU,OAAW,GAAE,SAAS,KAAK;AACzC,UAAI,mBAAmB,OAAW,GAAE,kBAAkB,cAAc;AACpE,YAAM,IAAI,EAAE,SAAS;AACrB,aAAO,EAAE,OAAO,EAAE,OAAO,gBAAgB,EAAE,eAAe;AAAA,IAC5D;AAAA,EACF,CAAC;AAED,MAAI;AAAA,IACF,MAAM;AAAA,IACN,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAa;AAAA,MACX,MAAM;AAAA,MACN,YAAY;AAAA,QACV,GAAG,EAAE,MAAM,UAAU,aAAa,wBAAwB;AAAA,QAC1D,GAAG,EAAE,MAAM,UAAU,aAAa,wBAAwB;AAAA,QAC1D,SAAS,EAAE,MAAM,UAAU,aAAa,6DAA6D;AAAA,MACvG;AAAA,MACA,UAAU,CAAC,KAAK,GAAG;AAAA,MACnB,sBAAsB;AAAA,IACxB;AAAA,IACA,aAAa,EAAE,OAAO,iBAAiB,GAAGF,MAAK;AAAA,IAC/C,SAAS,CAAC,EAAE,GAAG,GAAG,QAAQ,MAAM,EAAE,UAAU,GAAG,GAAG,EAAE,QAAQ,CAAC;AAAA,EAC/D,CAAC;AAED,MAAI;AAAA,IACF,MAAM;AAAA,IACN,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAaI;AAAA,IACb,aAAa,EAAE,OAAO,4BAA4B,GAAGJ,MAAK;AAAA,IAC1D,SAAS,MAAM,WAAW,EAAE,SAAS,EAAE,SAAS;AAAA,EAClD,CAAC;AAED,MAAI;AAAA,IACF,MAAM;AAAA,IACN,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAa,EAAE,MAAM,UAAU,YAAY,EAAE,OAAO,EAAE,GAAGK,QAAO,aAAa,6CAA6C,EAAE,GAAG,sBAAsB,MAAM;AAAA,IAC3J,aAAa,EAAE,OAAO,wBAAwB,GAAGH,KAAI;AAAA,IACrD,SAAS,CAAC,EAAE,MAAM,MAAM,WAAW,EAAE,eAAe,KAAK,CAAC;AAAA,EAC5D,CAAC;AAED,MAAI;AAAA,IACF,MAAM;AAAA,IACN,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAa,EAAE,MAAM,UAAU,YAAY,EAAE,gBAAgB,EAAE,MAAM,WAAW,aAAa,8CAA8C,EAAE,GAAG,sBAAsB,MAAM;AAAA,IAC5K,aAAa,EAAE,OAAO,yBAAyB,GAAGA,KAAI;AAAA,IACtD,SAAS,CAAC,EAAE,eAAe,MAAM,WAAW,EAAE,gBAAgB,mBAAmB,IAAI,CAAC;AAAA,EACxF,CAAC;AAID,MAAI;AAAA,IACF,MAAM;AAAA,IACN,OAAO;AAAA,IACP,aACE;AAAA,IACF,aAAa;AAAA,MACX,MAAM;AAAA,MACN,YAAY;AAAA,QACV,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,SAAS,EAAE,MAAM,UAAU,aAAa,yDAAyD;AAAA,QACjG,OAAO,EAAE,MAAM,UAAU,aAAa,uCAAuC,YAAY,cAAc,sBAAsB,MAAM;AAAA,QACnI,OAAO,EAAE,GAAGG,QAAO,aAAa,mDAAmD;AAAA,QACnF,MAAM,EAAE,MAAM,WAAW,SAAS,GAAG,aAAa,iFAAiF;AAAA,QACnI,mBAAmB,EAAE,MAAM,WAAW,aAAa,mFAAmF;AAAA,MACxI;AAAA,MACA,UAAU,CAAC,QAAQ;AAAA,MACnB,sBAAsB;AAAA,IACxB;AAAA,IACA,aAAa,EAAE,OAAO,wBAAwB,GAAGJ,OAAM;AAAA,IACvD,SAAS,OAAO,MAAM;AACpB,YAAM,SAAS,EAAE,QAAQ,EAAE,QAAsB,SAAS,EAAE,SAAS,SAAS,EAAE,SAAS,OAAO,EAAE,OAAO,OAAO,EAAE,OAAO,MAAM,EAAE,MAAM,mBAAmB,EAAE,kBAAkB;AAC9K,YAAM,IAAI,MAAM,IAAI,EAAE,MAAM,UAAU,OAAO,GAAG,MAAM,EAAE,YAAY,MAAM,CAAC;AAC3E,aAAO,EAAE,YAAY,EAAE,GAAG,GAAG,WAAW,WAAW,EAAE,SAAS,EAAE,IAAI;AAAA,IACtE;AAAA,EACF,CAAC;AAED,MAAI;AAAA,IACF,MAAM;AAAA,IACN,OAAO;AAAA,IACP,aACE;AAAA,IACF,aAAa;AAAA,MACX,MAAM;AAAA,MACN,YAAY;AAAA,QACV,KAAK,EAAE,MAAM,SAAS,OAAO,EAAE,MAAM,UAAU,aAAa,aAAa,GAAG,aAAa,yCAAyC;AAAA,QAClI,MAAM,EAAE,MAAM,WAAW,SAAS,GAAG,SAAS,KAAM,aAAa,gDAAgD;AAAA,MACnH;AAAA,MACA,sBAAsB;AAAA,IACxB;AAAA,IACA,aAAa,EAAE,OAAO,yBAAyB,GAAGD,MAAK;AAAA,IACvD,SAAS,CAAC,EAAE,KAAK,KAAK,MAAM;AAC1B,YAAM,MAAM,EAAE,WAAW;AACzB,YAAM,SAAS,MAAM,IAAI,OAAO,CAAC,MAAM,IAAI,SAAS,EAAE,EAAE,CAAC,IAAI,IAAI,MAAM,EAAE,QAAQ,IAAI;AACrF,UAAI;AAAK,mBAAW,MAAM,IAAK,KAAI,CAAC,IAAI,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,EAAG,OAAM,IAAI,MAAM,mBAAmB,EAAE,+CAA+C;AAAA;AACtJ,aAAO;AAAA,QACL,OAAO,IAAI;AAAA,QACX,SAAS,OAAO,IAAI,CAAC,MAAM;AACzB,gBAAM,KAAK,EAAE,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC;AAClC,gBAAM,KAAK,EAAE,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC;AAClC,gBAAM,MAAM,EAAE,MAAM,IAAI,OAAO;AAC/B,iBAAO;AAAA,YACL,IAAI,EAAE;AAAA,YACN,SAAS,EAAE;AAAA,YACX,SAAS,EAAE,MAAM;AAAA,YACjB,WAAW,EAAE,MAAM;AAAA,YACnB,OAAO,EAAE;AAAA,YACT,QAAQ,MAAM,EAAE,SAAS,EAAE,OAAO;AAAA,YAClC,MAAM,EAAE;AAAA,YACR,QAAQ,EAAE,QAAQ,UAAU;AAAA,YAC5B,QAAQ,EAAE,GAAG,KAAK,MAAM,KAAK,IAAI,GAAG,EAAE,IAAI,GAAG,GAAG,GAAG,KAAK,MAAM,KAAK,IAAI,GAAG,EAAE,IAAI,GAAG,GAAG,OAAO,KAAK,KAAK,KAAK,IAAI,GAAG,EAAE,IAAI,KAAK,IAAI,GAAG,EAAE,IAAI,IAAI,GAAG,GAAG,QAAQ,KAAK,KAAK,KAAK,IAAI,GAAG,EAAE,IAAI,KAAK,IAAI,GAAG,EAAE,IAAI,IAAI,GAAG,EAAE;AAAA,UACtN;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF,CAAC;AAED,MAAI;AAAA,IACF,MAAM;AAAA,IACN,OAAO;AAAA,IACP,aACE;AAAA,IACF,aAAa;AAAA,MACX,MAAM;AAAA,MACN,YAAY;AAAA,QACV,WAAW,EAAE,MAAM,SAAS,UAAU,GAAG,UAAU,KAAK,OAAO,EAAE,MAAM,UAAU,aAAa,aAAa,GAAG,aAAa,gCAAgC;AAAA,QAC3J,IAAI,EAAE,MAAM,UAAU,aAAa,yDAAyD;AAAA,QAC5F,IAAI,EAAE,MAAM,UAAU,aAAa,wDAAwD;AAAA,QAC3F,OAAO,EAAE,MAAM,UAAU,kBAAkB,GAAG,SAAS,IAAI,aAAa,wEAAwE;AAAA,QAChJ,QAAQ,EAAE,MAAM,UAAU,SAAS,MAAM,SAAS,KAAK,aAAa,qEAAqE;AAAA,QACzI,OAAO,EAAE,MAAM,WAAW,aAAa,yDAAyD;AAAA,QAChG,QAAQ;AAAA,UACN,MAAM;AAAA,UACN,aAAa;AAAA,UACb,YAAY,EAAE,GAAG,EAAE,MAAM,UAAU,aAAa,cAAc,GAAG,GAAG,EAAE,MAAM,UAAU,aAAa,cAAc,EAAE;AAAA,UACnH,UAAU,CAAC,KAAK,GAAG;AAAA,UACnB,sBAAsB;AAAA,QACxB;AAAA,QACA,eAAe,EAAE,MAAM,UAAU,SAAS,GAAG,SAAS,GAAG,aAAa,uCAAuC;AAAA,QAC7G,OAAO,EAAE,GAAGK,QAAO,aAAa,gDAA2C;AAAA,QAC3E,SAAS,EAAE,MAAM,UAAU,aAAa,+EAA0E;AAAA,QAClH,SAAS,EAAE,MAAM,UAAU,aAAa,0DAAqD;AAAA,QAC7F,QAAQ,EAAE,MAAM,WAAW,SAAS,GAAG,SAAS,KAAK,aAAa,+BAA+B;AAAA,MACnG;AAAA,MACA,UAAU,CAAC,WAAW;AAAA,MACtB,sBAAsB;AAAA,IACxB;AAAA,IACA,aAAa,EAAE,OAAO,0BAA0B,GAAGJ,OAAM;AAAA,IACzD,SAAS,CAAC,MAAM;AACd,YAAM,SAAS;AACf,aAAO,IAAI,EAAE,MAAM,UAAU,OAAO,GAAG,MAAM,EAAE,cAAc,MAAM,CAAC;AAAA,IACtE;AAAA,EACF,CAAC;AAID,MAAI;AAAA,IACF,MAAM;AAAA,IACN,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAa;AAAA,MACX,MAAM;AAAA,MACN,YAAY;AAAA,QACV,MAAM,EAAE,MAAM,UAAU,SAAS,UAAU,SAAS,UAAU,aAAa,oCAAoC;AAAA,QAC/G,UAAU,EAAE,MAAM,UAAU,SAAS,MAAM,SAAS,KAAK,aAAa,iCAAiC;AAAA,QACvG,QAAQ,EAAE,MAAM,WAAW,aAAa,wBAAwB;AAAA,QAChE,OAAO,EAAE,MAAM,WAAW,aAAa,kEAAkE;AAAA,MAC3G;AAAA,MACA,sBAAsB;AAAA,IACxB;AAAA,IACA,aAAa,EAAE,OAAO,mCAAmC,GAAGC,KAAI;AAAA,IAChE,SAAS,CAAC,EAAE,OAAO,GAAG,EAAE,MAAM;AAC5B,UAAI,MAAO,GAAE,UAAU;AACvB,aAAO,EAAE,QAAQ,CAAC;AAAA,IACpB;AAAA,EACF,CAAC;AAED,MAAI;AAAA,IACF,MAAM;AAAA,IACN,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAa,EAAE,MAAM,UAAU,YAAY,EAAE,MAAM,EAAE,MAAM,UAAU,MAAM,CAAC,SAAS,MAAM,GAAG,aAAa,iBAAiB,EAAE,GAAG,UAAU,CAAC,MAAM,GAAG,sBAAsB,MAAM;AAAA,IACjL,aAAa,EAAE,OAAO,wBAAwB,GAAGA,KAAI;AAAA,IACrD,SAAS,CAAC,EAAE,KAAK,OAAO,EAAE,MAAM,EAAE,QAAQ,IAAI,EAAE;AAAA,EAClD,CAAC;AAED,MAAI;AAAA,IACF,MAAM;AAAA,IACN,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAaE;AAAA,IACb,aAAa,EAAE,OAAO,QAAQ,GAAGH,OAAM;AAAA,IACvC,SAAS,MAAM;AACb,YAAM,SAAS,EAAE,KAAK;AACtB,YAAM,IAAI,EAAE,SAAS;AACrB,aAAO,EAAE,QAAQ,UAAU,EAAE,WAAW,UAAU,EAAE,UAAU;AAAA,IAChE;AAAA,EACF,CAAC;AAED,MAAI;AAAA,IACF,MAAM;AAAA,IACN,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAaG;AAAA,IACb,aAAa,EAAE,OAAO,QAAQ,GAAGH,OAAM;AAAA,IACvC,SAAS,MAAM;AACb,YAAM,SAAS,EAAE,KAAK;AACtB,YAAM,IAAI,EAAE,SAAS;AACrB,aAAO,EAAE,QAAQ,UAAU,EAAE,WAAW,UAAU,EAAE,UAAU;AAAA,IAChE;AAAA,EACF,CAAC;AAID,MAAI;AAAA,IACF,MAAM;AAAA,IACN,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAa;AAAA,MACX,MAAM;AAAA,MACN,YAAY;AAAA,QACV,SAAS,EAAE,MAAM,WAAW,SAAS,IAAI,SAAS,MAAM,aAAa,wCAAwC;AAAA,QAC7G,UAAU,EAAE,MAAM,SAAS,OAAO,EAAE,MAAM,UAAU,aAAa,YAAY,GAAG,aAAa,mCAAmC;AAAA,QAChI,OAAO,EAAE,MAAM,WAAW,aAAa,oCAAoC;AAAA,MAC7E;AAAA,MACA,sBAAsB;AAAA,IACxB;AAAA,IACA,aAAa,EAAE,OAAO,oBAAoB,GAAGD,MAAK;AAAA,IAClD,SAAS,CAAC,EAAE,SAAS,UAAU,MAAM,MAAM;AACzC,UAAI;AAAU,mBAAW,MAAM,SAAU,KAAI,CAAC,EAAE,SAAS,EAAE,EAAG,OAAM,IAAI,MAAM,kBAAkB,EAAE,kCAAkC;AAAA;AACpI,YAAM,IAAI,EAAE,iBAAiB,EAAE,SAAS,WAAW,KAAK,UAAU,MAAM,CAAC;AACzE,aAAO,EAAE,SAAS,CAAC,EAAE,MAAM,SAAS,MAAM,EAAE,MAAM,UAAU,YAAY,GAAG,EAAE,MAAM,QAAQ,MAAM,WAAW,EAAE,KAAK,OAAI,EAAE,MAAM,GAAG,CAAC,EAAE;AAAA,IACvI;AAAA,EACF,CAAC;AAED,MAAI;AAAA,IACF,MAAM;AAAA,IACN,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAa;AAAA,MACX,MAAM;AAAA,MACN,YAAY;AAAA,QACV,QAAQ,EAAE,MAAM,UAAU,MAAM,CAAC,aAAa,cAAc,YAAY,GAAG,aAAa,iCAAiC;AAAA,QACzH,SAAS,EAAE,MAAM,UAAU,SAAS,GAAG,SAAS,GAAG,aAAa,2CAA2C;AAAA,QAC3G,OAAO,EAAE,MAAM,UAAU,kBAAkB,GAAG,SAAS,GAAG,aAAa,qCAAqC;AAAA,QAC5G,OAAO,EAAE,MAAM,WAAW,aAAa,oCAAoC;AAAA,MAC7E;AAAA,MACA,sBAAsB;AAAA,IACxB;AAAA,IACA,aAAa,EAAE,OAAO,uBAAuB,GAAGA,MAAK;AAAA,IACrD,SAAS,OAAO,EAAE,QAAQ,SAAS,OAAO,MAAM,MAAM;AACpD,YAAM,QAAQ,MAAM,EAAE,YAAY,EAAE,QAAQ,SAAS,OAAO,MAAM,CAAC;AACnE,aAAO,EAAE,UAAU,UAAU,aAAa,OAAO,MAAM,QAAQ,MAAM,cAAc,KAAK,EAAE;AAAA,IAC5F;AAAA,EACF,CAAC;AAED,MAAI;AAAA,IACF,MAAM;AAAA,IACN,OAAO;AAAA,IACP,aACE;AAAA,IACF,aAAaI;AAAA,IACb,aAAa,EAAE,OAAO,iBAAiB,GAAGJ,MAAK;AAAA,IAC/C,SAAS,MAAM;AACb,YAAM,IAAI,EAAE,UAAU;AACtB,aAAO,EAAE,MAAM,cAAc,EAAE,KAAK,GAAG,OAAO,EAAE,MAAM,QAAQ,KAAK,EAAE,KAAK,UAAU,EAAE,SAAS;AAAA,IACjG;AAAA,EACF,CAAC;AAED,MAAI;AAAA,IACF,MAAM;AAAA,IACN,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAa,EAAE,MAAM,UAAU,YAAY,EAAE,SAAS,EAAE,MAAM,WAAW,aAAa,+CAA+C,EAAE,GAAG,sBAAsB,MAAM;AAAA,IACtK,aAAa,EAAE,OAAO,qBAAqB,GAAGA,MAAK;AAAA,IACnD,SAAS,CAAC,EAAE,QAAQ,MAAM,EAAE,OAAO,EAAE,QAAQ,CAAC;AAAA,EAChD,CAAC;AAED,MAAI;AAAA,IACF,MAAM;AAAA,IACN,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAa,EAAE,MAAM,UAAU,YAAY,EAAE,UAAU,EAAE,MAAM,UAAU,aAAa,2BAA2B,EAAE,GAAG,UAAU,CAAC,UAAU,GAAG,sBAAsB,MAAM;AAAA,IAC1K,aAAa,EAAE,OAAO,mBAAmB,GAAGG,aAAY;AAAA,IACxD,SAAS,CAAC,EAAE,SAAS,MAAM;AACzB,YAAM,WAAW,EAAE,SAAS,QAAQ;AACpC,YAAM,IAAI,EAAE;AACZ,aAAO,EAAE,OAAO,EAAE,OAAO,OAAO,QAAQ,EAAE,OAAO,QAAQ,QAAQ,EAAE,WAAW,GAAG,SAAS,EAAE,QAAQ,QAAQ,SAAS;AAAA,IACvH;AAAA,EACF,CAAC;AAED,QAAM,KAAK,GAAG,sBAAsB,CAAC,CAAC;AACtC,QAAM,KAAK,GAAG,mBAAmB,CAAC;AAElC,SAAO,EAAE,IAAI,QAAQ,MAAM,gBAAgB,WAAW,QAAQ,WAAW,MAAM;AACjF;;;ACj2BO,IAAM,cAA4E;AAAA,EACvF,EAAE,IAAI,SAAS,OAAO,SAAS,KAAK,IAAI;AAAA,EACxC,EAAE,IAAI,cAAc,OAAO,cAAc,KAAK,IAAI;AAAA,EAClD,EAAE,IAAI,OAAO,OAAO,OAAO,KAAK,IAAI;AAAA,EACpC,EAAE,IAAI,UAAU,OAAO,eAAe,KAAK,IAAI;AACjD;AAYO,IAAM,eAAN,MAAmB;AAAA,EAUxB,YACmB,YACA,KACjB;AAFiB;AACA;AAAA,EAChB;AAAA,EAFgB;AAAA,EACA;AAAA,EAXnB,OAAkB;AAAA;AAAA,EAElB,QAAuB;AAAA;AAAA,EAEvB,YAAwB,CAAC;AAAA,EACjB,OAAa;AAAA,EACb,QAAuB;AAAA,EACvB,UAAU;AAAA,EAOV,IAAI,GAAiD;AAC3D,UAAM,IAAI,KAAK,IAAI;AACnB,UAAM,IAAI,KAAK,WAAW,SAAS;AACnC,WAAO,iBAAiB,EAAE,MAAM,EAAE,SAAS,QAAQ,GAAG,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG;AAAA,EAC7F;AAAA,EAEQ,IAAI,GAAgC;AAC1C,UAAM,IAAI,KAAK,IAAI,CAAC;AACpB,WAAO,kBAAkB,GAAG,EAAE,GAAG,EAAE,GAAG,KAAK,WAAW,SAAS,EAAE,IAAI;AAAA,EACvE;AAAA;AAAA,EAGA,KAAK,GAA+B;AAClC,SAAK,QAAQ;AACb,QAAI,KAAK,KAAM,QAAO;AACtB,QAAI,EAAE,gBAAgB,OAAO;AAC3B,WAAK,UAAU;AACf,WAAK,QAAQ,EAAE,GAAG,EAAE,SAAS,GAAG,EAAE,QAAQ;AAAA,IAC5C,WAAW,EAAE,gBAAgB,YAAY,KAAK,WAAW,YAAY,EAAE,GAAG,EAAE,SAAS,GAAG,EAAE,QAAQ,GAAG,KAAK,OAAO,KAAK,WAAW,SAAS,EAAE,IAAI,IAAI;AAClJ,aAAO;AAAA,IACT;AACA,UAAM,SAAS,EAAE,WAAW;AAC5B,UAAM,OAAO,SAAS,QAAQ,KAAK;AACnC,QAAI,SAAS,OAAO;AAClB,WAAK,OAAO,EAAE,MAAM,OAAO,WAAW,EAAE,WAAW,GAAG,EAAE,SAAS,GAAG,EAAE,SAAS,KAAK,EAAE,GAAG,KAAK,WAAW,SAAS,EAAE,KAAK,IAAI,EAAE;AAC/H,aAAO;AAAA,IACT;AACA,QAAI,SAAS,UAAU;AACrB,YAAM,IAAI,KAAK,IAAI;AACnB,WAAK,OAAO,EAAE,MAAM,UAAU,WAAW,EAAE,WAAW,OAAO,KAAK,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,GAAG,EAAE,UAAU,EAAE,OAAO,EAAE,QAAQ,CAAC,GAAG,UAAU,KAAK,WAAW,SAAS,EAAE,KAAK,SAAS;AAChM,aAAO;AAAA,IACT;AACA,QAAI,SAAS,gBAAgB,EAAE,QAAQ;AACrC,WAAK,KAAK,CAAC;AACX,aAAO;AAAA,IACT;AACA,QAAI;AACF,YAAM,IAAI,KAAK,IAAI,CAAC;AACpB,YAAM,UAAU,KAAK,WAAW,YAAY,EAAE,OAAO,EAAE,CAAC;AACxD,cAAQ,KAAK,CAAC,CAAC,CAAC;AAChB,WAAK,OAAO,EAAE,MAAM,UAAU,WAAW,EAAE,UAAU;AACrD,aAAO;AAAA,IACT,SAAS,KAAK;AACZ,WAAK,QAAQ,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC5D,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEQ,KAAK,GAA4B;AACvC,UAAM,IAAI,KAAK,IAAI,CAAC;AACpB,UAAM,EAAE,OAAO,OAAO,IAAI,KAAK,WAAW,SAAS;AACnD,QAAI,EAAE,IAAI,KAAK,EAAE,IAAI,KAAK,EAAE,KAAK,SAAS,EAAE,KAAK,OAAQ;AACzD,SAAK,WAAW,SAAS,KAAK,WAAW,UAAU,EAAE,GAAG,EAAE,CAAC,EAAE,KAAK;AAAA,EACpE;AAAA,EAEA,KAAK,GAA4B;AAC/B,QAAI,EAAE,gBAAgB,MAAO,MAAK,QAAQ,EAAE,GAAG,EAAE,SAAS,GAAG,EAAE,QAAQ;AACvE,UAAM,IAAI,KAAK;AACf,QAAI,CAAC,KAAK,EAAE,cAAc,EAAE,UAAW;AACvC,QAAI,EAAE,SAAS,OAAO;AACpB,WAAK,WAAW,QAAQ,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,IAAI,EAAE,UAAU,EAAE,GAAG,GAAG,EAAE,IAAI,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC;AAC/F;AAAA,IACF;AACA,QAAI,EAAE,SAAS,UAAU;AACvB,YAAM,IAAI,KAAK,IAAI;AACnB,YAAM,IAAI,KAAK,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,GAAG,EAAE,UAAU,EAAE,OAAO,EAAE,QAAQ,CAAC;AACvF,UAAI,IAAI,EAAE,YAAa,IAAI,EAAE,SAAS,MAAO,KAAK;AAClD,UAAI,EAAE,SAAU,KAAI,KAAK,MAAM,IAAI,EAAE,IAAI;AACzC,WAAK,WAAW,QAAQ,EAAE,UAAU,EAAE,CAAC;AACvC;AAAA,IACF;AACA,UAAM,UAAU,KAAK,WAAW;AAChC,QAAI,CAAC,QAAS;AACd,UAAM,SAAS,OAAO,EAAE,uBAAuB,aAAa,EAAE,mBAAmB,IAAI,CAAC;AACtF,YAAQ,MAAM,OAAO,SAAS,SAAS,CAAC,CAAC,GAAG,IAAI,CAAC,OAAO,KAAK,IAAI,EAAE,CAAC,CAAC;AACrE,UAAM,YAAY,OAAO,EAAE,uBAAuB,aAAa,EAAE,mBAAmB,IAAI,CAAC;AACzF,SAAK,YAAY,UAAU,IAAI,CAAC,OAAO,KAAK,IAAI,EAAE,CAAC;AAAA,EACrD;AAAA,EAEA,GAAG,GAA4B;AAC7B,QAAI,EAAE,gBAAgB,MAAO,MAAK,UAAU;AAC5C,UAAM,IAAI,KAAK;AACf,QAAI,CAAC,KAAK,EAAE,cAAc,EAAE,UAAW;AACvC,SAAK,OAAO;AACZ,SAAK,YAAY,CAAC;AAClB,QAAI,EAAE,SAAS,SAAU,MAAK,WAAW,cAAc,IAAI;AAAA,EAC7D;AAAA,EAEA,SAAe;AACb,SAAK,UAAU;AACf,SAAK,YAAY,CAAC;AAClB,QAAI,KAAK,MAAM,SAAS,SAAU,MAAK,WAAW,cAAc,OAAO;AACvE,SAAK,OAAO;AAAA,EACd;AAAA,EAEA,IAAI,SAAkB;AACpB,WAAO,KAAK,SAAS;AAAA,EACvB;AAAA;AAAA,EAGA,MAAM,GAAmF;AACvF,UAAM,IAAI,KAAK,WAAW,SAAS;AACnC,QAAI,EAAE,UAAU;AACd,WAAK,WAAW,QAAQ,EAAE,UAAU,EAAE,KAAK,YAAY,EAAE,SAAS,IAAI,IAAI,IAAI,CAAC;AAC/E;AAAA,IACF;AACA,UAAM,IAAI,KAAK,IAAI;AACnB,UAAM,OAAO,KAAK,IAAI,UAAU,KAAK,IAAI,UAAU,EAAE,KAAK,OAAO,KAAK,IAAI,CAAC,EAAE,SAAS,KAAM,CAAC,CAAC;AAC9F,UAAM,IAAI,OAAO,EAAE,KAAK;AAExB,UAAM,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,QAAQ;AAC1C,UAAM,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS;AAC1C,SAAK,WAAW,QAAQ,EAAE,MAAM,KAAK,EAAE,GAAG,MAAM,KAAK,EAAE,KAAK,IAAI,KAAK,GAAG,GAAG,MAAM,KAAK,EAAE,KAAK,IAAI,KAAK,EAAE,EAAE,CAAC;AAAA,EAC7G;AACF;AAGO,SAAS,oBACd,YACA,SACA,GACS;AACT,QAAM,MAAM,EAAE,WAAW,EAAE;AAC3B,QAAM,MAAM,EAAE,IAAI,YAAY;AAC9B,MAAI,OAAO,QAAQ,KAAK;AACtB,QAAI,WAAW,SAAS,EAAE,SAAU,QAAO;AAC3C,QAAI,EAAE,SAAU,YAAW,KAAK;AAAA,QAC3B,YAAW,KAAK;AACrB,WAAO;AAAA,EACT;AACA,MAAI,OAAO,QAAQ,KAAK;AACtB,eAAW,KAAK;AAChB,WAAO;AAAA,EACT;AACA,MAAI,IAAK,QAAO;AAChB,QAAM,OAAO,YAAY,KAAK,CAAC,MAAM,EAAE,QAAQ,GAAG;AAClD,MAAI,MAAM;AACR,YAAQ,OAAO,KAAK;AACpB,WAAO;AAAA,EACT;AACA,QAAM,QAAQ,WAAW,SAAS,EAAE;AACpC,MAAI,QAAQ,OAAO,QAAQ,KAAK;AAC9B,UAAM,OAAO,KAAK,IAAI,GAAG,KAAK,MAAM,MAAM,IAAI,OAAO,IAAI,CAAC;AAC1D,eAAW,SAAS,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,GAAG,MAAM,IAAI,QAAQ,QAAQ,MAAM,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC;AACjG,WAAO;AAAA,EACT;AACA,MAAI,QAAQ,KAAK;AACf,eAAW,WAAW;AACtB,WAAO;AAAA,EACT;AACA,MAAI,QAAQ,KAAK;AACf,eAAW,QAAQ,EAAE,QAAQ,CAAC,WAAW,SAAS,EAAE,KAAK,OAAO,CAAC;AACjE,WAAO;AAAA,EACT;AACA,MAAI,QAAQ,UAAU;AACpB,eAAW,UAAU;AACrB,WAAO;AAAA,EACT;AACA,SAAO;AACT;AASO,IAAM,uBAAN,MAA2B;AAAA,EAKhC,YAA6B,YAAmC;AAAnC;AAAA,EAAoC;AAAA,EAApC;AAAA,EAJZ,WAAW,oBAAI,IAA+B;AAAA,EACvD,UAA8C;AAAA,EAC9C,OAAO;AAAA;AAAA,EAKf,OAAO,KAA6B;AAClC,UAAM,EAAE,OAAO,OAAO,IAAI,KAAK,WAAW,SAAS;AACnD,UAAM,OAAO,GAAG,KAAK,IAAI,MAAM;AAC/B,QAAI,QAAQ,KAAK,WAAW,UAAU;AACtC,QAAI,SAAS,KAAK,MAAM;AACtB,WAAK,OAAO;AACZ,WAAK,SAAS,MAAM;AACpB,cAAQ;AAAA,IACV;AACA,QAAI,QAAQ;AACZ,UAAM,OAAmB,EAAE,GAAG,GAAG,GAAG,GAAG,OAAO,OAAO;AACrD,SAAK,WAAW,eAAe,MAAM,CAAC,IAAI,IAAI,SAAS;AACrD,YAAM,MAAM,GAAG,EAAE,IAAI,EAAE;AACvB,UAAI,KAAK,SAAS,IAAI,GAAG,MAAM,KAAM;AACrC,WAAK,SAAS,IAAI,KAAK,IAAI;AAC3B,UAAI,CAAC,KAAK,QAAS,MAAK,UAAU,IAAI,gBAAgB,MAAM,IAAI;AAChE,WAAK,QAAQ,KAAK,IAAI,IAAI;AAC1B,YAAM,KAAK,KAAK;AAChB,YAAM,KAAK,KAAK;AAChB,UAAI,aAAa,KAAK,SAAkB,IAAI,IAAI,GAAG,GAAG,KAAK,IAAI,MAAM,QAAQ,EAAE,GAAG,KAAK,IAAI,MAAM,SAAS,EAAE,CAAC;AAC7G;AAAA,IACF,GAAG,EAAE,MAAM,CAAC;AACZ,WAAO;AAAA,EACT;AACF;AAGO,SAAS,aAAa,YAAmH;AAC9I,QAAM,IAAI,WAAW,SAAS;AAC9B,QAAM,OAAO,EAAE,SAAS;AACxB,QAAM,MAAsF,CAAC;AAC7F,aAAW,CAAC,MAAM,EAAE,KAAK,qBAAqB,EAAE,OAAO,UAAU,IAAI,EAAG,KAAI,KAAK,EAAE,MAAM,IAAI,MAAM,WAAW,CAAC;AAC/G,MAAI,EAAE,OAAO,YAAY,QAAS,YAAW,CAAC,MAAM,EAAE,KAAK,sBAAsB,EAAE,OAAO,aAAa,MAAM,EAAE,EAAG,KAAI,KAAK,EAAE,MAAM,IAAI,MAAM,cAAc,CAAC;AAC5J,SAAO;AACT;AAWO,IAAM,gBAA0C;AAAA,EACrD,EAAE,MAAM,YAAY,OAAO,QAAQ,KAAK,GAAG,KAAK,KAAK,MAAM,EAAE;AAAA,EAC7D,EAAE,MAAM,eAAe,OAAO,WAAW,KAAK,GAAG,KAAK,GAAG,MAAM,KAAK;AAAA,EACpE,EAAE,MAAM,YAAY,OAAO,QAAQ,KAAK,GAAG,KAAK,GAAG,MAAM,KAAK;AAAA,EAC9D,EAAE,MAAM,gBAAgB,OAAO,YAAY,KAAK,GAAG,KAAK,GAAG,MAAM,KAAK;AAAA,EACtE,EAAE,MAAM,eAAe,OAAO,WAAW,KAAK,MAAM,KAAK,GAAG,MAAM,KAAK;AAAA,EACvE,EAAE,MAAM,iBAAiB,OAAO,aAAa,KAAK,MAAM,KAAK,GAAG,MAAM,KAAK;AAAA,EAC3E,EAAE,MAAM,aAAa,OAAO,SAAS,KAAK,MAAM,KAAK,KAAK,MAAM,EAAE;AAAA,EAClE,EAAE,MAAM,SAAS,OAAO,SAAS,KAAK,GAAG,KAAK,GAAG,MAAM,KAAK;AAAA,EAC5D,EAAE,MAAM,iBAAiB,OAAO,aAAa,KAAK,GAAG,KAAK,MAAM,MAAM,KAAK;AAAA,EAC3E,EAAE,MAAM,qBAAqB,OAAO,sBAAsB,KAAK,GAAG,KAAK,MAAM,MAAM,KAAK;AAAA,EACxF,EAAE,MAAM,oBAAoB,OAAO,YAAY,KAAK,GAAG,KAAK,GAAG,MAAM,KAAK;AAAA,EAC1E,EAAE,MAAM,qBAAqB,OAAO,aAAa,KAAK,GAAG,KAAK,GAAG,MAAM,KAAK;AAAA,EAC5E,EAAE,MAAM,yBAAyB,OAAO,cAAc,KAAK,IAAI,KAAK,GAAG,MAAM,KAAK;AACpF;AAEO,IAAM,gBAA0C;AAAA,EACrD,EAAE,MAAM,SAAS,OAAO,eAAe,KAAK,GAAG,KAAK,GAAG,MAAM,KAAK;AAAA,EAClE,EAAE,MAAM,SAAS,OAAO,eAAe,KAAK,MAAM,KAAK,GAAG,MAAM,KAAK;AAAA,EACrE,EAAE,MAAM,WAAW,OAAO,WAAW,KAAK,GAAG,KAAK,GAAG,MAAM,KAAK;AAAA,EAChE,EAAE,MAAM,gBAAgB,OAAO,YAAY,KAAK,GAAG,KAAK,GAAG,MAAM,KAAK;AAAA,EACtE,EAAE,MAAM,cAAc,OAAO,cAAc,KAAK,GAAG,KAAK,GAAG,MAAM,KAAK;AAAA,EACtE,EAAE,MAAM,gBAAgB,OAAO,gBAAgB,KAAK,GAAG,KAAK,GAAG,MAAM,KAAK;AAAA,EAC1E,EAAE,MAAM,aAAa,OAAO,aAAa,KAAK,GAAG,KAAK,GAAG,MAAM,KAAK;AACtE;AAGO,SAAS,SAAS,KAAc,MAAsB;AAC3D,MAAI,IAAa;AACjB,aAAW,KAAK,KAAK,MAAM,GAAG,EAAG,KAAK,IAAgC,CAAC;AACvE,SAAO,OAAO,MAAM,WAAW,IAAI;AACrC;AAGO,SAAS,UAAU,KAA8B,MAAc,OAAwC;AAC5G,QAAM,CAAC,MAAM,GAAG,IAAI,IAAI,KAAK,MAAM,GAAG;AACtC,MAAI,CAAC,KAAK,OAAQ,QAAO,EAAE,CAAC,IAAI,GAAG,MAAM;AACzC,SAAO,EAAE,CAAC,IAAI,GAAG,EAAE,GAAI,IAAI,IAAI,GAA+B,GAAG,UAAW,IAAI,IAAI,KAAiC,CAAC,GAAG,KAAK,KAAK,GAAG,GAAG,KAAK,EAAE,EAAE;AACpJ;AAGO,SAAS,WAAW,OAAe,QAAwB;AAChE,QAAM,KAAM,QAAQ,MAAM,KAAK,KAAM;AACrC,SAAO,EAAE,GAAG,KAAK,IAAI,CAAC,IAAI,QAAQ,GAAG,KAAK,IAAI,CAAC,IAAI,OAAO;AAC5D;AAGO,SAAS,WAAW,GAAW,GAAmB;AACvD,UAAS,KAAK,MAAM,GAAG,CAAC,IAAI,MAAO,KAAK,KAAK,KAAK,OAAO;AAC3D;AAMO,SAAS,iBAAiB,MAAc,OAAmB,QAAQ,MAAkE;AAC1I,QAAM,OAAO,IAAI,kBAAkB,OAAO,OAAO,CAAC;AAClD,QAAM,IAAI,OAAO;AACjB,WAAS,IAAI,GAAG,IAAI,MAAM,KAAK;AAC7B,aAAS,IAAI,GAAG,IAAI,MAAM,KAAK;AAC7B,YAAM,KAAK,IAAI,MAAM;AACrB,YAAM,KAAK,IAAI,MAAM;AACrB,YAAM,IAAI,KAAK,MAAM,IAAI,EAAE,IAAI;AAC/B,UAAI,IAAI,KAAK,IAAI,MAAO;AACxB,YAAM,CAAC,IAAI,IAAI,EAAE,IAAI,SAAS,WAAW,WAAW,IAAI,EAAE,GAAG,KAAK,GAAG,GAAG,CAAC;AACzE,YAAM,KAAK,IAAI,OAAO,KAAK;AAE3B,YAAM,OAAO,KAAK,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,SAAS,CAAC;AACrD,WAAK,CAAC,IAAI;AACV,WAAK,IAAI,CAAC,IAAI;AACd,WAAK,IAAI,CAAC,IAAI;AACd,WAAK,IAAI,CAAC,IAAI,KAAK,MAAM,MAAM,KAAK,IAAI,GAAG,IAAI,CAAC;AAAA,IAClD;AAAA,EACF;AACA,SAAO,EAAE,OAAO,MAAM,QAAQ,MAAM,KAAK;AAC3C;AAGO,SAAS,UAAU,IAAY,IAAY,OAAmB,OAAuB;AAC1F,QAAM,CAAC,GAAG,GAAG,CAAC,IAAI,cAAc,KAAK;AACrC,QAAM,EAAE,GAAG,EAAE,IAAI,SAAS,GAAG,GAAG,CAAC;AACjC,QAAM,CAAC,IAAI,IAAI,EAAE,IAAI,SAAS,WAAW,WAAW,IAAI,EAAE,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,CAAC;AACnF,SAAO,cAAc,IAAI,IAAI,EAAE;AACjC;AAaO,IAAM,oBAA+C;AAAA,EAC1D,EAAE,OAAO,YAAY,OAAO,YAAY,OAAO,CAAC,MAAM,CAAC,EAAE,aAAa,EAAE,OAAO,SAAS,EAAE;AAAA,EAC1F,EAAE,OAAO,SAAS,OAAO,YAAY,OAAO,CAAC,MAAM,EAAE,aAAa,EAAE,OAAO,SAAS,EAAE;AACxF;","names":["unit","finite","d","HEX","HEX","layers","READ","WRITE","SET","DESTRUCTIVE","EMPTY","COLOR","tuning"]}
|