@pixerate/editor 0.134.0 → 0.136.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/animation-editor/index.cjs +58 -55
- package/dist/animation-editor/index.cjs.map +1 -1
- package/dist/animation-editor/index.d.cts +8 -5
- package/dist/animation-editor/index.d.ts +8 -5
- package/dist/animation-editor/index.js +5 -2
- package/dist/animation-editor/index.js.map +1 -1
- package/dist/{bezier-J8i4uqSH.d.cts → bezier-CdccFsF8.d.cts} +1 -1
- package/dist/{bezier-lNEOp0Jx.d.ts → bezier-DG9qNZQV.d.ts} +1 -1
- package/dist/canvas/index.d.cts +10 -7
- package/dist/canvas/index.d.ts +10 -7
- package/dist/{chunk-Z2H7KECK.cjs → chunk-2R3UW57U.cjs} +13 -2
- package/dist/chunk-2R3UW57U.cjs.map +1 -0
- package/dist/{chunk-ESIWZMMK.js → chunk-6QQR4LKE.js} +2 -2
- package/dist/chunk-A3BVTI3G.js +150 -0
- package/dist/chunk-A3BVTI3G.js.map +1 -0
- package/dist/{chunk-T6TV6HY6.cjs → chunk-B2CUCM7Y.cjs} +36 -36
- package/dist/{chunk-T6TV6HY6.cjs.map → chunk-B2CUCM7Y.cjs.map} +1 -1
- package/dist/chunk-ECCXGELC.cjs +727 -0
- package/dist/chunk-ECCXGELC.cjs.map +1 -0
- package/dist/{chunk-OXSV64JX.js → chunk-G6IKY6PL.js} +4 -4
- package/dist/chunk-I52DRGGJ.js +727 -0
- package/dist/chunk-I52DRGGJ.js.map +1 -0
- package/dist/{chunk-6CTZAGZ2.js → chunk-ILYFOJUN.js} +56 -1
- package/dist/chunk-ILYFOJUN.js.map +1 -0
- package/dist/{chunk-YAFS2QFZ.cjs → chunk-JLGNZMUV.cjs} +82 -82
- package/dist/{chunk-YAFS2QFZ.cjs.map → chunk-JLGNZMUV.cjs.map} +1 -1
- package/dist/{chunk-7RJ6P7MI.js → chunk-KZXLZCQ7.js} +2 -2
- package/dist/{chunk-HHTCDFZC.js → chunk-MAHQC3SK.js} +13 -2
- package/dist/chunk-MAHQC3SK.js.map +1 -0
- package/dist/{chunk-FWEO3HSL.js → chunk-PQQF5KOW.js} +8 -8
- package/dist/chunk-Q6OUXEK3.cjs +150 -0
- package/dist/chunk-Q6OUXEK3.cjs.map +1 -0
- package/dist/{chunk-P3RQ5UJE.cjs → chunk-UTQKC66X.cjs} +4 -4
- package/dist/{chunk-P3RQ5UJE.cjs.map → chunk-UTQKC66X.cjs.map} +1 -1
- package/dist/{chunk-J3B45HTA.cjs → chunk-XB25WOC2.cjs} +6 -6
- package/dist/{chunk-J3B45HTA.cjs.map → chunk-XB25WOC2.cjs.map} +1 -1
- package/dist/{chunk-NVTHUPJ6.cjs → chunk-YT3JL7YM.cjs} +71 -16
- package/dist/chunk-YT3JL7YM.cjs.map +1 -0
- package/dist/effects/index.d.cts +7 -4
- package/dist/effects/index.d.ts +7 -4
- package/dist/{export-BGdT02aL.d.cts → export-BOheWw2R.d.cts} +13 -5
- package/dist/{export-Dng22YB8.d.ts → export-ByKKIA2S.d.ts} +13 -5
- package/dist/{export-KzubBKo7.d.cts → export-CEYeRQXH.d.cts} +1 -1
- package/dist/{export-DMeG6E06.d.ts → export-Ds7zgGD8.d.ts} +1 -1
- package/dist/extensions/index.cjs +3 -3
- package/dist/extensions/index.cjs.map +1 -1
- package/dist/extensions/index.js +2 -2
- package/dist/generation/index.cjs +150 -945
- package/dist/generation/index.cjs.map +1 -1
- package/dist/generation/index.d.cts +3 -423
- package/dist/generation/index.d.ts +3 -423
- package/dist/generation/index.js +59 -854
- package/dist/generation/index.js.map +1 -1
- package/dist/grammar/index.cjs +3 -3
- package/dist/grammar/index.cjs.map +1 -1
- package/dist/grammar/index.js +2 -2
- package/dist/{helpers-Coa4e2j_.d.ts → helpers--ns3W2D7.d.ts} +7 -1
- package/dist/{helpers-DHl28yLO.d.cts → helpers-BVkU4oUi.d.cts} +7 -1
- package/dist/image-editor/index.cjs +742 -647
- package/dist/image-editor/index.cjs.map +1 -1
- package/dist/image-editor/index.d.cts +29 -11
- package/dist/image-editor/index.d.ts +29 -11
- package/dist/image-editor/index.js +107 -12
- package/dist/image-editor/index.js.map +1 -1
- package/dist/index.cjs +28 -28
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +36 -36
- package/dist/{opentype-Dfcx6wFx.d.ts → opentype-DfoVYgmG.d.ts} +1 -1
- package/dist/{opentype-BWR7Qv8W.d.cts → opentype-yi-Kz4ND.d.cts} +1 -1
- package/dist/paint/index.cjs +10 -2
- package/dist/paint/index.cjs.map +1 -1
- package/dist/paint/index.d.cts +2 -2
- package/dist/paint/index.d.ts +2 -2
- package/dist/paint/index.js +9 -1
- package/dist/paint-editor/index.cjs +10 -7
- package/dist/paint-editor/index.cjs.map +1 -1
- package/dist/paint-editor/index.d.cts +10 -7
- package/dist/paint-editor/index.d.ts +10 -7
- package/dist/paint-editor/index.js +5 -2
- package/dist/paint-editor/index.js.map +1 -1
- package/dist/{pathfinder-D8KQ6blQ.d.cts → pathfinder-7JkMwYvC.d.cts} +1 -1
- package/dist/{pathfinder-Celbi3e6.d.ts → pathfinder-GM3UWdBZ.d.ts} +1 -1
- package/dist/{pool-BfuxBKTd.d.cts → pool-04qp8iW4.d.cts} +1 -1
- package/dist/{pool-8JZGWHvR.d.ts → pool-CkTxlLMC.d.ts} +1 -1
- package/dist/provenance-DmlcgdzT.d.cts +426 -0
- package/dist/provenance-uh5r2TQ8.d.ts +426 -0
- package/dist/{rand-BaqEOs1Y.d.ts → rand-BszBST4s.d.ts} +31 -1
- package/dist/{rand-DdpFzCo6.d.cts → rand-DOH_aMvm.d.cts} +31 -1
- package/dist/{svg-pwXWq6s2.d.cts → svg-BDDKvWWY.d.cts} +2 -2
- package/dist/{svg-CxxqG3_W.d.ts → svg-rV6_HPmn.d.ts} +2 -2
- package/dist/{tools-3EBjR91b.d.cts → tools-BAjSbTdY.d.cts} +1 -1
- package/dist/{tools-y1M6O3UT.d.ts → tools-DPYerqeR.d.ts} +1 -1
- package/dist/vector/index.cjs +2684 -1860
- package/dist/vector/index.cjs.map +1 -1
- package/dist/vector/index.d.cts +313 -71
- package/dist/vector/index.d.ts +313 -71
- package/dist/vector/index.js +4700 -3876
- package/dist/vector/index.js.map +1 -1
- package/dist/video-editor/index.d.cts +7 -4
- package/dist/video-editor/index.d.ts +7 -4
- package/dist/{warp-Ceqdz7kj.d.cts → warp-DQh9R7Ie.d.cts} +1 -1
- package/dist/{warp-C1gwu2G_.d.ts → warp-XVL6SpSh.d.ts} +1 -1
- package/package.json +1 -1
- package/skills/pixerate-image-editor/SKILL.md +4 -4
- package/skills/pixerate-vector/SKILL.md +20 -1
- package/dist/chunk-6CTZAGZ2.js.map +0 -1
- package/dist/chunk-HHTCDFZC.js.map +0 -1
- package/dist/chunk-NVTHUPJ6.cjs.map +0 -1
- package/dist/chunk-Z2H7KECK.cjs.map +0 -1
- /package/dist/{chunk-ESIWZMMK.js.map → chunk-6QQR4LKE.js.map} +0 -0
- /package/dist/{chunk-OXSV64JX.js.map → chunk-G6IKY6PL.js.map} +0 -0
- /package/dist/{chunk-7RJ6P7MI.js.map → chunk-KZXLZCQ7.js.map} +0 -0
- /package/dist/{chunk-FWEO3HSL.js.map → chunk-PQQF5KOW.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/generation/capabilities.ts","../src/generation/plan.ts","../src/generation/hash.ts"],"sourcesContent":["/**\n * Declarative descriptions of generative models (what a model accepts) and of\n * the requests sent to them. Everything here is plain data so capabilities can\n * come from a server, be merged with local presentation overlays, and be\n * turned into JSON Schema for agents.\n */\n\nexport type GenerationMediaKind = 'image' | 'video' | 'audio' | 'text';\n\n/** The reference roles this library knows by name (labels, aliases, schema order). */\nexport type BuiltinReferenceRole =\n\t| 'start_frame'\n\t| 'end_frame'\n\t| 'style_ref'\n\t| 'character_ref'\n\t| 'background_ref'\n\t| 'mask'\n\t| 'image_ref'\n\t| 'video_ref'\n\t| 'audio_ref';\n\n/**\n * What a reference input (an asset) is used for. The built-in roles are\n * listed in {@link REFERENCE_ROLES}; models may declare any other role name\n * (e.g. `subject`, `pose`) in `references.roles`, which makes it valid for\n * that model. Role names match {@link REFERENCE_ROLE_NAME_REGEX}.\n */\nexport type ReferenceRole = BuiltinReferenceRole | (string & {});\n\n/** Valid role names: a letter, then letters, digits, `_` or `-`, not ending in `_` or `-`. */\nexport const REFERENCE_ROLE_NAME_REGEX = /^[A-Za-z](?:[A-Za-z0-9_-]*[A-Za-z0-9])?$/;\n\n/** True for a string usable as a role name. */\nexport function isReferenceRoleName(value: unknown): value is ReferenceRole {\n\treturn typeof value === 'string' && value.length <= 64 && REFERENCE_ROLE_NAME_REGEX.test(value);\n}\n\n/** Every built-in reference role, in a stable display order. */\nexport const REFERENCE_ROLES: readonly BuiltinReferenceRole[] = [\n\t'start_frame',\n\t'end_frame',\n\t'style_ref',\n\t'character_ref',\n\t'background_ref',\n\t'mask',\n\t'image_ref',\n\t'video_ref',\n\t'audio_ref'\n];\n\n/** Human-readable default labels for reference roles. */\nexport const REFERENCE_ROLE_LABELS: Readonly<Record<BuiltinReferenceRole, string>> = {\n\tstart_frame: 'Start frame',\n\tend_frame: 'End frame',\n\tstyle_ref: 'Style reference',\n\tcharacter_ref: 'Character reference',\n\tbackground_ref: 'Background reference',\n\tmask: 'Mask',\n\timage_ref: 'Image reference',\n\tvideo_ref: 'Video reference',\n\taudio_ref: 'Audio reference'\n};\n\n/**\n * Friendly role names accepted wherever a role is written by hand (asset\n * mentions such as `@fox:style`, agent calls). A model that declares the\n * alias itself (e.g. its own `style` role) keeps it; otherwise the alias maps\n * to the built-in role. Keys are lower case.\n */\nexport const REFERENCE_ROLE_ALIASES: Readonly<Record<string, BuiltinReferenceRole>> = {\n\treference: 'image_ref',\n\timage: 'image_ref',\n\tstyle: 'style_ref',\n\tcharacter: 'character_ref',\n\tbackground: 'background_ref',\n\t'start-frame': 'start_frame',\n\t'first-frame': 'start_frame',\n\tfirst_frame: 'start_frame',\n\t'end-frame': 'end_frame',\n\t'last-frame': 'end_frame',\n\tlast_frame: 'end_frame',\n\t'style-ref': 'style_ref',\n\t'character-ref': 'character_ref',\n\t'background-ref': 'background_ref',\n\t'image-ref': 'image_ref',\n\t'video-ref': 'video_ref',\n\t'audio-ref': 'audio_ref',\n\tvideo: 'video_ref',\n\taudio: 'audio_ref'\n};\n\nconst isBuiltinRole = (role: string): role is BuiltinReferenceRole =>\n\t(REFERENCE_ROLES as readonly string[]).includes(role);\n\n/** Display label of a role: the model's label, the built-in label, or the name made readable. */\nexport function referenceRoleLabel(role: ReferenceRole, caps?: ModelCapabilities): string {\n\tconst declared = caps?.references?.roles[role]?.label;\n\tif (declared) return declared;\n\tif (isBuiltinRole(role)) return REFERENCE_ROLE_LABELS[role];\n\tconst words = String(role).replace(/[_-]+/g, ' ').trim();\n\treturn words.charAt(0).toUpperCase() + words.slice(1);\n}\n\n/**\n * Canonical role for a hand-written name: the name itself when the model\n * declares it (or, without a model, when it is built in), else its alias\n * ({@link REFERENCE_ROLE_ALIASES}, case-insensitive), else the trimmed name.\n */\nexport function normalizeReferenceRole(role: string, caps?: ModelCapabilities): ReferenceRole {\n\tconst name = String(role).trim();\n\tif (caps ? !!caps.references?.roles[name] : isBuiltinRole(name)) return name;\n\tconst lower = name.toLowerCase();\n\tif (caps?.references?.roles[lower]) return lower;\n\tif (!caps && isBuiltinRole(lower)) return lower;\n\treturn REFERENCE_ROLE_ALIASES[lower] ?? (isBuiltinRole(lower) ? lower : name);\n}\n\n/**\n * Whether `mediaType` (a MIME type such as `image/png`, or a media kind such\n * as `image`) matches one of `accepts` (`image`, `image/*`, `image/png`).\n * An empty or missing `accepts` accepts everything; an unknown media type\n * only matches a missing `accepts`.\n */\nexport function mediaTypeMatches(mediaType: string | undefined, accepts: readonly string[] | undefined): boolean {\n\tif (!accepts || accepts.length === 0) return true;\n\tif (!mediaType) return false;\n\tconst type = mediaType.split(';')[0].trim().toLowerCase();\n\tconst kind = type.split('/')[0];\n\treturn accepts.some((entry) => {\n\t\tconst pattern = entry.trim().toLowerCase();\n\t\tif (pattern === '*' || pattern === '*/*' || pattern === type) return true;\n\t\tif (!pattern.includes('/')) return pattern === kind;\n\t\tif (pattern.endsWith('/*')) return pattern.slice(0, -2) === kind;\n\t\treturn false;\n\t});\n}\n\n/** A choice from a fixed list. `options` order matters (low → high where it applies). */\nexport interface EnumCapability<T extends string | number = string> {\n\toptions: readonly T[];\n\tdefault?: T;\n\t/** Display labels by option value. */\n\tlabels?: Readonly<Record<string, string>>;\n}\n\nexport interface TextFieldCapability {\n\tmaxLength?: number;\n}\n\nexport interface PromptCapability extends TextFieldCapability {\n\t/**\n\t * Count the resolved prompt (templates expanded, variables substituted)\n\t * against `maxLength` rather than the raw template text. Default `true`.\n\t * Pass the resolved text to the planner as `resolvedPrompt`.\n\t */\n\tcountResolved?: boolean;\n\t/** The prompt must be non-empty. */\n\trequired?: boolean;\n}\n\nexport interface CountCapability {\n\t/** Largest number of outputs per request. */\n\tmax: number;\n\t/** Predefined choices; when given, requests snap to one of them. */\n\toptions?: readonly number[];\n\tdefault?: number;\n}\n\nexport interface DurationCapability {\n\t/** Seconds. */\n\tmin?: number;\n\tmax?: number;\n\t/** Predefined choices; when given, requests snap to one of them. */\n\toptions?: readonly number[];\n\tdefault?: number;\n\tstep?: number;\n}\n\nexport interface SeedCapability {\n\tmin?: number;\n\tmax?: number;\n}\n\nexport interface ReferenceRoleCapability {\n\t/** Most references of this role. */\n\tmax: number;\n\t/** Fewest references of this role (e.g. an image-to-video model needs a `start_frame`). */\n\tmin?: number;\n\tlabel?: string;\n\tdescription?: string;\n\t/**\n\t * Media accepted for this role: kinds (`image`), wildcards (`image/*`) or\n\t * MIME types (`image/png`). Absent: anything. References whose\n\t * `mediaType` does not match are dropped or rejected by the planner.\n\t */\n\taccepts?: readonly string[];\n}\n\nexport interface ReferenceCapability {\n\t/** Supported roles and their per-role limits. Roles not listed are unsupported. */\n\troles: Partial<Readonly<Record<ReferenceRole, ReferenceRoleCapability>>>;\n\t/** Most references across all roles. */\n\tmaxTotal?: number;\n}\n\nexport interface NumberParamSpec {\n\ttype: 'number' | 'integer';\n\tmin?: number;\n\tmax?: number;\n\tstep?: number;\n\tdefault?: number;\n\tlabel?: string;\n\tdescription?: string;\n}\n\nexport interface EnumParamSpec {\n\ttype: 'enum';\n\toptions: readonly (string | number)[];\n\tdefault?: string | number;\n\tlabel?: string;\n\tdescription?: string;\n}\n\nexport interface BooleanParamSpec {\n\ttype: 'boolean';\n\tdefault?: boolean;\n\tlabel?: string;\n\tdescription?: string;\n}\n\n/** A model-specific parameter (`guidance`, `motion_strength`, `style`, …). */\nexport type ExtraParamSpec = NumberParamSpec | EnumParamSpec | BooleanParamSpec;\n\n/** Rough timing used for progress estimates (`expectedDurationFor`). */\nexport interface TimingCapability {\n\t/** Fixed cost of one request in ms. */\n\tbaseMs: number;\n\t/** Extra ms per output beyond the first. */\n\tperItemMs?: number;\n\t/** Extra ms per second of requested duration (video/audio). */\n\tperSecondMs?: number;\n\t/** Extra ms per megapixel of the requested resolution. */\n\tperMegapixelMs?: number;\n}\n\n/** Presentation-only fields; overlays may set these (see `mergeCapabilities`). */\nexport interface CapabilityPresentation {\n\tname?: string;\n\tdescription?: string;\n\tbadges?: readonly string[];\n\ticon?: string;\n\tgroup?: string;\n}\n\n/** Everything a generative model accepts. Absent sections mean \"unsupported\". */\nexport interface ModelCapabilities extends CapabilityPresentation {\n\tid: string;\n\tmedia: GenerationMediaKind;\n\tprompt?: PromptCapability;\n\t/** Negative prompt support (`true` or limits). */\n\tnegativePrompt?: boolean | TextFieldCapability;\n\t/** System prompt support (`true` or limits). */\n\tsystemPrompt?: boolean | TextFieldCapability;\n\t/** E.g. `['1:1', '16:9', '9:16']`. */\n\taspectRatios?: EnumCapability<string>;\n\t/** E.g. `['512x512', '1024x1024']`, `['720p', '1080p']` or `['1k', '2k', '4k']`, low → high. */\n\tresolutions?: EnumCapability<string>;\n\t/** Ordered low → high, e.g. `['draft', 'standard', 'high']`. */\n\tquality?: EnumCapability<string>;\n\tcount?: CountCapability;\n\tduration?: DurationCapability;\n\tseed?: boolean | SeedCapability;\n\treferences?: ReferenceCapability;\n\t/** Accepts a source to edit (`mode: 'edit'`). */\n\tediting?: boolean;\n\t/** Accepts a source plus a `mask` reference (`mode: 'inpaint'`). */\n\tinpainting?: boolean;\n\tparams?: Readonly<Record<string, ExtraParamSpec>>;\n\ttiming?: TimingCapability;\n}\n\nexport interface GenerationReference {\n\t/** Asset id (opaque to this library). */\n\tid: string;\n\trole: ReferenceRole;\n\turl?: string;\n\t/** MIME type or media kind, checked against the role's `accepts`. */\n\tmediaType?: string;\n\t/** Content hash of the asset when it was referenced (used by generation records). */\n\tcontentHash?: string;\n}\n\nexport type GenerationMode = 'generate' | 'edit' | 'inpaint';\n\nexport type GenerationParamValue = string | number | boolean;\n\n/** A request for one model. Every field is optional; the planner fills and fixes. */\nexport interface GenerationRequest {\n\tmodel?: string;\n\tprompt?: string;\n\tnegativePrompt?: string;\n\tsystemPrompt?: string;\n\taspectRatio?: string;\n\tresolution?: string;\n\tquality?: string;\n\tcount?: number;\n\t/** Seconds. */\n\tduration?: number;\n\tseed?: number;\n\tmode?: GenerationMode;\n\treferences?: GenerationReference[];\n\tparams?: Record<string, GenerationParamValue>;\n}\n\n/** Fields of {@link GenerationRequest} the planner knows about, in planning order. */\nexport const GENERATION_REQUEST_FIELDS = [\n\t'model',\n\t'prompt',\n\t'negativePrompt',\n\t'systemPrompt',\n\t'aspectRatio',\n\t'resolution',\n\t'quality',\n\t'count',\n\t'duration',\n\t'seed',\n\t'mode',\n\t'references',\n\t'params'\n] as const;\n\n/** Text field limits normalized from `boolean | TextFieldCapability`. */\nexport function textFieldCapability(value: boolean | TextFieldCapability | undefined): TextFieldCapability | null {\n\tif (!value) return null;\n\treturn value === true ? {} : value;\n}\n\n/** Seed limits normalized from `boolean | SeedCapability`. */\nexport function seedCapability(value: boolean | SeedCapability | undefined): SeedCapability | null {\n\tif (!value) return null;\n\treturn value === true ? {} : value;\n}\n\n/**\n * Supported reference roles of a model: built-in roles in\n * {@link REFERENCE_ROLES} order, then custom roles in declaration order.\n */\nexport function supportedReferenceRoles(caps: ModelCapabilities): ReferenceRole[] {\n\tconst roles = caps.references?.roles ?? {};\n\tconst builtin: ReferenceRole[] = REFERENCE_ROLES.filter((role) => (roles[role]?.max ?? 0) > 0);\n\tconst custom = Object.keys(roles).filter(\n\t\t(role) => !isBuiltinRole(role) && isReferenceRoleName(role) && (roles[role]?.max ?? 0) > 0\n\t);\n\treturn [...builtin, ...custom];\n}\n\n/** Supported generation modes of a model. */\nexport function supportedModes(caps: ModelCapabilities): GenerationMode[] {\n\tconst modes: GenerationMode[] = ['generate'];\n\tif (caps.editing) modes.push('edit');\n\tif (caps.inpainting) modes.push('inpaint');\n\treturn modes;\n}\n\nconst PRESENTATION_KEYS = ['name', 'description', 'badges', 'icon', 'group'] as const;\n\n/** A partial model entry used to decorate (or add) models locally. */\nexport type CapabilityOverlay = Partial<ModelCapabilities> & { id: string };\n\n/**\n * Merges server-reported capabilities with a local overlay. For models the\n * server knows, every capability value comes from `remote`; the overlay only\n * contributes presentation fields (`name`, `description`, `badges`, `icon`,\n * `group`), filling in or replacing the remote ones. Overlay entries for\n * models the server does not report are appended when they are complete\n * (have a `media` kind). Remote order is kept; overlay-only models follow in\n * overlay order.\n */\nexport function mergeCapabilities(\n\tremote: readonly ModelCapabilities[],\n\toverlay: readonly CapabilityOverlay[] = []\n): ModelCapabilities[] {\n\tconst overlayById = new Map(overlay.map((entry) => [entry.id, entry]));\n\tconst remoteIds = new Set(remote.map((model) => model.id));\n\tconst merged = remote.map((model) => {\n\t\tconst extra = overlayById.get(model.id);\n\t\tif (!extra) return { ...model };\n\t\tconst next: ModelCapabilities = { ...model };\n\t\tfor (const key of PRESENTATION_KEYS) {\n\t\t\tif (extra[key] !== undefined) (next as any)[key] = extra[key];\n\t\t}\n\t\treturn next;\n\t});\n\tfor (const entry of overlay) {\n\t\tif (remoteIds.has(entry.id) || !entry.media) continue;\n\t\tremoteIds.add(entry.id);\n\t\tmerged.push({ ...(entry as ModelCapabilities) });\n\t}\n\treturn merged;\n}\n","import {\n\tGENERATION_REQUEST_FIELDS,\n\tREFERENCE_ROLES,\n\tisReferenceRoleName,\n\tmediaTypeMatches,\n\tnormalizeReferenceRole,\n\tseedCapability,\n\tsupportedReferenceRoles,\n\tsupportedModes,\n\ttextFieldCapability,\n\ttype EnumCapability,\n\ttype ExtraParamSpec,\n\ttype GenerationParamValue,\n\ttype GenerationReference,\n\ttype GenerationRequest,\n\ttype ModelCapabilities,\n\ttype ReferenceRole,\n\ttype ReferenceRoleCapability\n} from './capabilities.js';\n\n/**\n * How the planner treats values the model does not support:\n *\n * - `error`: nothing is changed; every mismatch is an error.\n * - `nearest`: snap to the closest supported value (ties go to the higher\n * value), clamp ranges, truncate lists, drop unsupported fields and\n * unsupported references.\n * - `downgrade`: like `nearest`, but ties go to the lower value.\n * - `upgrade`: like `nearest`, but never drops references the model cannot\n * use (that would lose intent), so those are errors.\n *\n * \"Lower\" means a narrower aspect ratio, fewer pixels, an earlier quality\n * option, a smaller number.\n */\nexport type PlanStrategy = 'error' | 'upgrade' | 'downgrade' | 'nearest';\n\nexport type PlanAdjustmentKind = 'snapped' | 'clamped' | 'truncated' | 'dropped' | 'defaulted';\n\nexport interface PlanAdjustment {\n\t/** Request path, e.g. `aspectRatio`, `params.guidance`, `references.style_ref`. */\n\tfield: string;\n\tfrom: unknown;\n\tto: unknown;\n\treason: string;\n\tkind: PlanAdjustmentKind;\n}\n\nexport interface PlanError {\n\tfield: string;\n\tvalue: unknown;\n\tmessage: string;\n}\n\nexport interface GenerationPlan {\n\t/** `true` when there are no errors and `request` can be sent. */\n\tok: boolean;\n\t/** The adjusted request (always a copy; the input is never mutated). */\n\trequest: GenerationRequest;\n\tadjustments: PlanAdjustment[];\n\terrors: PlanError[];\n\t/** Model the plan was made for. */\n\tmodel: string;\n\tstrategy: PlanStrategy;\n}\n\nexport interface PlanOptions {\n\t/** Default `nearest`. */\n\tstrategy?: PlanStrategy;\n\t/**\n\t * The prompt with templates and variables resolved. Measured against\n\t * `prompt.maxLength` when the model counts resolved text (the default).\n\t */\n\tresolvedPrompt?: string;\n\t/** Fill missing fields that have a capability `default` (reported as `defaulted`). */\n\tfillDefaults?: boolean;\n\t/** Override whether references with unsupported roles may be dropped (default: `nearest` and `downgrade` only). */\n\tdropUnsupportedReferences?: boolean;\n\t/**\n\t * Assets mentioned in the prompt (e.g. from `extractMentions(text, { details: true, roles: true })`\n\t * joined with your asset library). They are appended to `request.references`\n\t * and validated per role like any other reference. A mention without a role\n\t * gets `defaultMentionRole`, or the first role of the model that accepts its\n\t * media type (reported as `defaulted`).\n\t */\n\tmentions?: readonly PlanAssetMention[];\n\t/** Role for mentions that have none (see `mentions`). */\n\tdefaultMentionRole?: ReferenceRole;\n}\n\n/** An asset mention handed to the planner (see {@link PlanOptions.mentions}). */\nexport interface PlanAssetMention {\n\t/** Asset id. */\n\tid: string;\n\trole?: ReferenceRole | null;\n\tmediaType?: string;\n\tcontentHash?: string;\n\turl?: string;\n\t/** The mention text, used in messages (default: the id). */\n\tlabel?: string;\n}\n\nconst EPSILON = 1e-9;\n\n/** Numeric rank of an aspect ratio such as `16:9` (log of width / height). */\nexport function aspectRatioRank(value: string): number | undefined {\n\tconst match = /^\\s*(\\d+(?:\\.\\d+)?)\\s*[:x/×]\\s*(\\d+(?:\\.\\d+)?)\\s*$/i.exec(String(value));\n\tif (!match) return undefined;\n\tconst w = Number(match[1]);\n\tconst h = Number(match[2]);\n\tif (!(w > 0) || !(h > 0)) return undefined;\n\treturn Math.log(w / h);\n}\n\n/**\n * Numeric rank of a resolution: `1024x768` (pixels), `720p` (16:9 pixels at\n * that height) or `2k` (square of that many kibi-pixels). Log scale.\n */\nexport function resolutionRank(value: string): number | undefined {\n\tconst text = String(value).trim().toLowerCase();\n\tlet pixels: number | undefined;\n\tlet match = /^(\\d+(?:\\.\\d+)?)\\s*[x×*]\\s*(\\d+(?:\\.\\d+)?)$/.exec(text);\n\tif (match) pixels = Number(match[1]) * Number(match[2]);\n\telse if ((match = /^(\\d+(?:\\.\\d+)?)p$/.exec(text))) pixels = (Number(match[1]) ** 2 * 16) / 9;\n\telse if ((match = /^(\\d+(?:\\.\\d+)?)k$/.exec(text))) pixels = (Number(match[1]) * 1024) ** 2;\n\treturn pixels && pixels > 0 ? Math.log(pixels) : undefined;\n}\n\n/** Megapixels of a resolution string, when it can be parsed. */\nexport function resolutionMegapixels(value: string): number | undefined {\n\tconst rank = resolutionRank(value);\n\treturn rank === undefined ? undefined : Math.exp(rank) / 1_000_000;\n}\n\n/** Common quality names, low → high. Used to compare values missing from a model's options. */\nexport const QUALITY_LADDER: Readonly<Record<string, number>> = {\n\tdraft: 0,\n\tpreview: 0,\n\tlow: 1,\n\tfast: 1,\n\tturbo: 1,\n\tstandard: 2,\n\tnormal: 2,\n\tmedium: 2,\n\tbalanced: 2,\n\thigh: 3,\n\thd: 3,\n\tquality: 3,\n\tultra: 4,\n\tmax: 5,\n\tbest: 5\n};\n\nexport function qualityRank(value: string): number | undefined {\n\treturn QUALITY_LADDER[String(value).trim().toLowerCase()];\n}\n\nconst numberRank = (value: unknown) => (typeof value === 'number' && Number.isFinite(value) ? value : undefined);\n\n/**\n * Picks the option closest to `value` by `rank`. Ties go to the lower or\n * higher rank. Returns `undefined` when `value` or no option can be ranked.\n */\nexport function snapToOption<T>(\n\tvalue: unknown,\n\toptions: readonly T[],\n\trank: (value: any) => number | undefined,\n\ttie: 'lower' | 'higher'\n): T | undefined {\n\tconst target = rank(value);\n\tif (target === undefined) return undefined;\n\tlet best: { option: T; distance: number; rank: number } | undefined;\n\tfor (const option of options) {\n\t\tconst r = rank(option);\n\t\tif (r === undefined) continue;\n\t\tconst distance = Math.abs(r - target);\n\t\tif (\n\t\t\t!best ||\n\t\t\tdistance < best.distance - EPSILON ||\n\t\t\t(Math.abs(distance - best.distance) <= EPSILON && (tie === 'lower' ? r < best.rank : r > best.rank))\n\t\t) {\n\t\t\tbest = { option, distance, rank: r };\n\t\t}\n\t}\n\treturn best?.option;\n}\n\n/** Truncates to `max` UTF-16 units without splitting a surrogate pair. */\nfunction truncateText(text: string, max: number): string {\n\tif (text.length <= max) return text;\n\tlet end = max;\n\tconst code = text.charCodeAt(end - 1);\n\tif (end > 0 && code >= 0xd800 && code <= 0xdbff) end -= 1;\n\treturn text.slice(0, end);\n}\n\nfunction cloneRequest(request: GenerationRequest): GenerationRequest {\n\tconst copy: GenerationRequest = { ...request };\n\tif (request.references) copy.references = request.references.map((ref) => ({ ...ref }));\n\tif (request.params) copy.params = { ...request.params };\n\treturn copy;\n}\n\nconst describe = (value: unknown) => (typeof value === 'string' ? `\"${value}\"` : JSON.stringify(value));\nconst list = (options: readonly unknown[]) => options.map(describe).join(', ');\n\nclass Planner {\n\treadonly adjustments: PlanAdjustment[] = [];\n\treadonly errors: PlanError[] = [];\n\treadonly tie: 'lower' | 'higher';\n\treadonly strict: boolean;\n\n\tconstructor(\n\t\treadonly caps: ModelCapabilities,\n\t\treadonly request: GenerationRequest,\n\t\treadonly options: PlanOptions,\n\t\treadonly strategy: PlanStrategy\n\t) {\n\t\tthis.tie = strategy === 'downgrade' ? 'lower' : 'higher';\n\t\tthis.strict = strategy === 'error';\n\t}\n\n\tadjust(field: string, from: unknown, to: unknown, kind: PlanAdjustmentKind, reason: string) {\n\t\tthis.adjustments.push({ field, from, to, kind, reason });\n\t}\n\n\terror(field: string, value: unknown, message: string) {\n\t\tthis.errors.push({ field, value, message });\n\t}\n\n\t/** Removes an unsupported field (or reports it under `error`). */\n\tunsupported(field: keyof GenerationRequest, message: string) {\n\t\tconst value = this.request[field];\n\t\tif (this.strict) {\n\t\t\tthis.error(field, value, message);\n\t\t\treturn;\n\t\t}\n\t\tdelete this.request[field];\n\t\tthis.adjust(field, value, undefined, 'dropped', message);\n\t}\n\n\tdefaulted(field: string, value: unknown, set: () => void) {\n\t\tif (!this.options.fillDefaults || value === undefined) return;\n\t\tset();\n\t\tthis.adjust(field, undefined, value, 'defaulted', 'Filled with the model default.');\n\t}\n\n\tplanText(field: 'prompt' | 'negativePrompt' | 'systemPrompt', maxLength: number | undefined, measured?: string) {\n\t\tconst value = this.request[field];\n\t\tif (value === undefined || maxLength === undefined) return;\n\t\tif (typeof value !== 'string') {\n\t\t\tthis.error(field, value, `Expected text.`);\n\t\t\treturn;\n\t\t}\n\t\tconst text = measured ?? value;\n\t\tif (text.length <= maxLength) return;\n\t\tif (this.strict || measured !== undefined) {\n\t\t\tthis.error(\n\t\t\t\tfield,\n\t\t\t\ttext.length,\n\t\t\t\t`${measured !== undefined ? 'Resolved text' : 'Text'} is ${text.length} characters; the model accepts at most ${maxLength}.`\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\t\tconst next = truncateText(value, maxLength);\n\t\tthis.request[field] = next;\n\t\tthis.adjust(field, value.length, next.length, 'truncated', `Truncated to the model's ${maxLength}-character limit.`);\n\t}\n\n\tplanEnum(\n\t\tfield: 'aspectRatio' | 'resolution' | 'quality',\n\t\tcap: EnumCapability<string> | undefined,\n\t\trank: (value: string) => number | undefined,\n\t\tlabel: string\n\t) {\n\t\tconst value = this.request[field];\n\t\tif (value === undefined) {\n\t\t\tif (cap) this.defaulted(field, cap.default, () => (this.request[field] = cap.default));\n\t\t\treturn;\n\t\t}\n\t\tif (!cap || cap.options.length === 0) {\n\t\t\tthis.unsupported(field, `The model does not take a ${label}.`);\n\t\t\treturn;\n\t\t}\n\t\tif (cap.options.includes(value)) return;\n\t\tif (this.strict) {\n\t\t\tthis.error(field, value, `${describe(value)} is not a supported ${label}; supported: ${list(cap.options)}.`);\n\t\t\treturn;\n\t\t}\n\t\tconst snapped = snapToOption(value, cap.options, rank, this.tie);\n\t\tconst next = snapped ?? cap.default ?? cap.options[0];\n\t\tthis.request[field] = next;\n\t\tthis.adjust(\n\t\t\tfield,\n\t\t\tvalue,\n\t\t\tnext,\n\t\t\t'snapped',\n\t\t\tsnapped !== undefined\n\t\t\t\t? `${describe(value)} is not supported; using the nearest ${label}.`\n\t\t\t\t: `${describe(value)} is not supported; using ${cap.default !== undefined ? 'the default' : 'the first option'}.`\n\t\t);\n\t}\n\n\t/** Clamps/rounds/snaps a number. Returns the next value or `undefined` after an error. */\n\tplanNumber(\n\t\tfield: string,\n\t\tvalue: unknown,\n\t\tspec: { min?: number; max?: number; step?: number; integer?: boolean; options?: readonly number[] },\n\t\tlabel: string\n\t): { value: number; changed: boolean } | undefined {\n\t\tif (typeof value !== 'number' || !Number.isFinite(value)) {\n\t\t\tthis.error(field, value, `Expected a number for ${label}.`);\n\t\t\treturn undefined;\n\t\t}\n\t\tconst options = spec.options?.filter(\n\t\t\t(o) => (spec.min === undefined || o >= spec.min) && (spec.max === undefined || o <= spec.max)\n\t\t);\n\t\tif (options && options.length > 0) {\n\t\t\tif (options.includes(value)) return { value, changed: false };\n\t\t\tif (this.strict) {\n\t\t\t\tthis.error(field, value, `${value} is not a supported ${label}; supported: ${list(options)}.`);\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t\tconst next = snapToOption(value, options, numberRank, this.tie)!;\n\t\t\tthis.adjust(field, value, next, 'snapped', `${value} is not supported; using the nearest ${label}.`);\n\t\t\treturn { value: next, changed: true };\n\t\t}\n\t\tlet next = value;\n\t\tif (spec.step !== undefined && spec.step > 0) {\n\t\t\tconst base = spec.min ?? 0;\n\t\t\tconst steps = (next - base) / spec.step;\n\t\t\tconst rounded = Math.abs(steps - Math.trunc(steps) - 0.5) < EPSILON\n\t\t\t\t? this.tie === 'lower' ? Math.floor(steps) : Math.ceil(steps)\n\t\t\t\t: Math.round(steps);\n\t\t\tnext = Number((base + rounded * spec.step).toPrecision(12));\n\t\t}\n\t\tif (spec.integer && !Number.isInteger(next)) {\n\t\t\tconst frac = next - Math.floor(next);\n\t\t\tnext = Math.abs(frac - 0.5) < EPSILON ? (this.tie === 'lower' ? Math.floor(next) : Math.ceil(next)) : Math.round(next);\n\t\t}\n\t\tlet kind: PlanAdjustmentKind = 'snapped';\n\t\tif (spec.min !== undefined && next < spec.min) {\n\t\t\tnext = spec.min;\n\t\t\tkind = 'clamped';\n\t\t}\n\t\tif (spec.max !== undefined && next > spec.max) {\n\t\t\tnext = spec.max;\n\t\t\tkind = 'clamped';\n\t\t}\n\t\tif (next === value) return { value, changed: false };\n\t\tconst range = `${spec.min ?? '-∞'}–${spec.max ?? '∞'}`;\n\t\tif (this.strict) {\n\t\t\tthis.error(\n\t\t\t\tfield,\n\t\t\t\tvalue,\n\t\t\t\tkind === 'clamped' ? `${label} must be within ${range}.` : `${value} is not a valid ${label} (try ${next}).`\n\t\t\t);\n\t\t\treturn undefined;\n\t\t}\n\t\tthis.adjust(\n\t\t\tfield,\n\t\t\tvalue,\n\t\t\tnext,\n\t\t\tkind,\n\t\t\tkind === 'clamped' ? `Clamped to the supported range ${range}.` : `Rounded to a supported ${label}.`\n\t\t);\n\t\treturn { value: next, changed: true };\n\t}\n\n\tplanCount() {\n\t\tconst value = this.request.count;\n\t\tconst cap = this.caps.count;\n\t\tif (value === undefined) {\n\t\t\tif (cap) this.defaulted('count', cap.default, () => (this.request.count = cap.default));\n\t\t\treturn;\n\t\t}\n\t\tif (!cap) {\n\t\t\tif (value === 1) return;\n\t\t\tthis.unsupported('count', 'The model produces one output per request.');\n\t\t\treturn;\n\t\t}\n\t\tconst result = this.planNumber('count', value, { min: 1, max: cap.max, integer: true, options: cap.options }, 'output count');\n\t\tif (result) this.request.count = result.value;\n\t}\n\n\tplanDuration() {\n\t\tconst value = this.request.duration;\n\t\tconst cap = this.caps.duration;\n\t\tif (value === undefined) {\n\t\t\tif (cap) this.defaulted('duration', cap.default, () => (this.request.duration = cap.default));\n\t\t\treturn;\n\t\t}\n\t\tif (!cap) {\n\t\t\tthis.unsupported('duration', 'The model does not take a duration.');\n\t\t\treturn;\n\t\t}\n\t\tconst result = this.planNumber('duration', value, cap, 'duration');\n\t\tif (result) this.request.duration = result.value;\n\t}\n\n\tplanSeed() {\n\t\tconst value = this.request.seed;\n\t\tif (value === undefined) return;\n\t\tconst cap = seedCapability(this.caps.seed);\n\t\tif (!cap) {\n\t\t\tthis.unsupported('seed', 'The model does not take a seed.');\n\t\t\treturn;\n\t\t}\n\t\tconst result = this.planNumber('seed', value, { ...cap, integer: true }, 'seed');\n\t\tif (result) this.request.seed = result.value;\n\t}\n\n\tplanMode() {\n\t\tconst mode = this.request.mode;\n\t\tif (mode === undefined) return;\n\t\tconst modes = supportedModes(this.caps);\n\t\tif (!modes.includes(mode)) {\n\t\t\tthis.error('mode', mode, `The model does not support ${describe(mode)}; supported: ${list(modes)}.`);\n\t\t}\n\t}\n\n\troleCapability(role: ReferenceRole): ReferenceRoleCapability | undefined {\n\t\tconst cap = this.caps.references?.roles[role];\n\t\tif (cap && cap.max > 0) return cap;\n\t\tif (role === 'mask' && this.caps.inpainting) return { max: 1 };\n\t\treturn undefined;\n\t}\n\n\t/** Turns `options.mentions` into references (appended after the request's own). */\n\taddMentions() {\n\t\tconst mentions = this.options.mentions;\n\t\tif (!mentions?.length) return;\n\t\tconst refs = [...(this.request.references ?? [])];\n\t\tfor (const mention of mentions) {\n\t\t\tif (!mention || typeof mention.id !== 'string' || mention.id === '') continue;\n\t\t\tlet role = mention.role ?? undefined;\n\t\t\tif (!role) {\n\t\t\t\trole = this.options.defaultMentionRole ?? this.inferRole(mention.mediaType);\n\t\t\t\tthis.adjust(\n\t\t\t\t\t`references.${role}`,\n\t\t\t\t\tundefined,\n\t\t\t\t\trole,\n\t\t\t\t\t'defaulted',\n\t\t\t\t\t`@${mention.label ?? mention.id} has no role; using ${role}.`\n\t\t\t\t);\n\t\t\t}\n\t\t\trefs.push({\n\t\t\t\tid: mention.id,\n\t\t\t\trole,\n\t\t\t\t...(mention.url !== undefined ? { url: mention.url } : {}),\n\t\t\t\t...(mention.mediaType !== undefined ? { mediaType: mention.mediaType } : {}),\n\t\t\t\t...(mention.contentHash !== undefined ? { contentHash: mention.contentHash } : {})\n\t\t\t});\n\t\t}\n\t\tthis.request.references = refs;\n\t}\n\n\t/** First role of the model (other than `mask`) whose `accepts` matches `mediaType`. */\n\tinferRole(mediaType: string | undefined): ReferenceRole {\n\t\tfor (const role of supportedReferenceRoles(this.caps)) {\n\t\t\tif (role === 'mask') continue;\n\t\t\tconst cap = this.roleCapability(role);\n\t\t\tif (cap && (mediaType === undefined || mediaTypeMatches(mediaType, cap.accepts))) return role;\n\t\t}\n\t\treturn 'image_ref';\n\t}\n\n\tplanReferences() {\n\t\tconst refs = this.request.references;\n\t\tconst allowDrop =\n\t\t\t!this.strict &&\n\t\t\t(this.options.dropUnsupportedReferences ?? (this.strategy === 'nearest' || this.strategy === 'downgrade'));\n\t\tconst byRole = new Map<ReferenceRole, GenerationReference[]>();\n\t\tconst kept: GenerationReference[] = [];\n\t\tconst unsupported = new Map<string, number>();\n\t\tfor (const [index, original] of (refs ?? []).entries()) {\n\t\t\tlet ref = original;\n\t\t\tif (!ref || typeof ref.id !== 'string' || ref.id === '' || !isReferenceRoleName(ref.role)) {\n\t\t\t\tthis.error(`references.${index}`, ref, 'Each reference needs an `id` and a valid `role`.');\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (!this.roleCapability(ref.role)) {\n\t\t\t\tconst alias = normalizeReferenceRole(ref.role, this.caps);\n\t\t\t\tif (alias !== ref.role && this.roleCapability(alias)) {\n\t\t\t\t\tif (this.strict) {\n\t\t\t\t\t\tthis.error(`references.${ref.role}`, ref.role, `The model calls this role ${describe(alias)}.`);\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tthis.adjust(\n\t\t\t\t\t\t`references.${ref.role}`,\n\t\t\t\t\t\tref.role,\n\t\t\t\t\t\talias,\n\t\t\t\t\t\t'snapped',\n\t\t\t\t\t\t`Using the model's ${alias} role for ${describe(ref.role)}.`\n\t\t\t\t\t);\n\t\t\t\t\tref = { ...ref, role: alias };\n\t\t\t\t} else {\n\t\t\t\t\tunsupported.set(ref.role, (unsupported.get(ref.role) ?? 0) + 1);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst cap = this.roleCapability(ref.role)!;\n\t\t\tif (ref.mediaType !== undefined && !mediaTypeMatches(ref.mediaType, cap.accepts)) {\n\t\t\t\tconst message = `${describe(ref.id)} is ${describe(ref.mediaType)}; ${ref.role} accepts ${list(cap.accepts ?? [])}.`;\n\t\t\t\tif (allowDrop) this.adjust(`references.${ref.role}`, ref.id, undefined, 'dropped', message);\n\t\t\t\telse this.error(`references.${ref.role}`, ref.id, message);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst group = byRole.get(ref.role) ?? [];\n\t\t\tif (group.some((other) => other.id === ref.id)) {\n\t\t\t\tthis.adjust(`references.${ref.role}`, ref.id, undefined, 'dropped', `Duplicate reference \"${ref.id}\" removed.`);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tgroup.push(ref);\n\t\t\tbyRole.set(ref.role, group);\n\t\t\tkept.push(ref);\n\t\t}\n\n\t\tfor (const [role, count] of unsupported) {\n\t\t\tconst message =\n\t\t\t\tthis.caps.media === 'text' || !this.caps.references\n\t\t\t\t\t? `The ${this.caps.media} model \"${this.caps.id}\" does not accept reference inputs (${role}).`\n\t\t\t\t\t: `The model does not accept ${role} references.`;\n\t\t\tif (allowDrop) this.adjust(`references.${role}`, count, 0, 'dropped', message);\n\t\t\telse this.error(`references.${role}`, count, message);\n\t\t}\n\n\t\t// Per-role limits (built-in roles first, then the model's own roles).\n\t\tconst removed = new Set<GenerationReference>();\n\t\tconst custom = supportedReferenceRoles(this.caps).filter(\n\t\t\t(role) => !(REFERENCE_ROLES as readonly string[]).includes(role)\n\t\t);\n\t\tfor (const role of [...REFERENCE_ROLES, ...custom]) {\n\t\t\tconst cap = this.roleCapability(role);\n\t\t\tconst group = byRole.get(role) ?? [];\n\t\t\tif (!cap) continue;\n\t\t\tif (group.length > cap.max) {\n\t\t\t\tif (this.strict) {\n\t\t\t\t\tthis.error(`references.${role}`, group.length, `At most ${cap.max} ${role} reference(s) are supported.`);\n\t\t\t\t} else {\n\t\t\t\t\tgroup.slice(cap.max).forEach((ref) => removed.add(ref));\n\t\t\t\t\tthis.adjust(\n\t\t\t\t\t\t`references.${role}`,\n\t\t\t\t\t\tgroup.length,\n\t\t\t\t\t\tcap.max,\n\t\t\t\t\t\t'truncated',\n\t\t\t\t\t\t`Kept the first ${cap.max} ${role} reference(s); the model accepts no more.`\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (cap.min !== undefined && group.length < cap.min) {\n\t\t\t\tthis.error(`references.${role}`, group.length, `At least ${cap.min} ${role} reference(s) are required.`);\n\t\t\t}\n\t\t}\n\t\tlet next = kept.filter((ref) => !removed.has(ref));\n\n\t\t// Total limit.\n\t\tconst maxTotal = this.caps.references?.maxTotal;\n\t\tif (maxTotal !== undefined && next.length > maxTotal) {\n\t\t\tif (this.strict) {\n\t\t\t\tthis.error('references', next.length, `At most ${maxTotal} references are supported in total.`);\n\t\t\t} else {\n\t\t\t\tthis.adjust(\n\t\t\t\t\t'references',\n\t\t\t\t\tnext.length,\n\t\t\t\t\tmaxTotal,\n\t\t\t\t\t'truncated',\n\t\t\t\t\t`Kept the first ${maxTotal} references; the model accepts no more in total.`\n\t\t\t\t);\n\t\t\t\tnext = next.slice(0, maxTotal);\n\t\t\t}\n\t\t}\n\n\t\tif (this.request.mode === 'inpaint' && !next.some((ref) => ref.role === 'mask')) {\n\t\t\tthis.error('references.mask', 0, 'Inpainting needs a `mask` reference.');\n\t\t}\n\n\t\tif (refs === undefined) return;\n\t\tif (!this.strict) {\n\t\t\tif (next.length > 0) this.request.references = next;\n\t\t\telse delete this.request.references;\n\t\t}\n\t}\n\n\tplanParam(name: string, spec: ExtraParamSpec | undefined, value: GenerationParamValue): GenerationParamValue | undefined {\n\t\tconst field = `params.${name}`;\n\t\tif (!spec) {\n\t\t\tif (this.strict) this.error(field, value, `Unknown parameter \"${name}\".`);\n\t\t\telse this.adjust(field, value, undefined, 'dropped', `The model has no \"${name}\" parameter.`);\n\t\t\treturn undefined;\n\t\t}\n\t\tconst label = spec.label ?? name;\n\t\tif (spec.type === 'boolean') {\n\t\t\tif (typeof value !== 'boolean') this.error(field, value, `Expected true or false for ${label}.`);\n\t\t\treturn value;\n\t\t}\n\t\tif (spec.type === 'enum') {\n\t\t\tif (spec.options.includes(value as string | number)) return value;\n\t\t\tif (this.strict) {\n\t\t\t\tthis.error(field, value, `${describe(value)} is not a supported ${label}; supported: ${list(spec.options)}.`);\n\t\t\t\treturn value;\n\t\t\t}\n\t\t\tconst numeric = spec.options.every((o) => typeof o === 'number');\n\t\t\tconst snapped = numeric ? snapToOption(value, spec.options, numberRank, this.tie) : undefined;\n\t\t\tconst next = snapped ?? spec.default ?? spec.options[0];\n\t\t\tthis.adjust(\n\t\t\t\tfield,\n\t\t\t\tvalue,\n\t\t\t\tnext,\n\t\t\t\t'snapped',\n\t\t\t\tsnapped !== undefined ? `Using the nearest supported ${label}.` : `${describe(value)} is not supported; using ${spec.default !== undefined ? 'the default' : 'the first option'}.`\n\t\t\t);\n\t\t\treturn next;\n\t\t}\n\t\tconst result = this.planNumber(field, value, { ...spec, integer: spec.type === 'integer' }, label);\n\t\treturn result ? result.value : value;\n\t}\n\n\tplanParams() {\n\t\tconst params = this.request.params;\n\t\tconst specs = this.caps.params ?? {};\n\t\tconst next: Record<string, GenerationParamValue> = {};\n\t\tfor (const [name, value] of Object.entries(params ?? {})) {\n\t\t\tif (value === undefined) continue;\n\t\t\tconst planned = this.planParam(name, specs[name], value);\n\t\t\tif (planned !== undefined) next[name] = planned;\n\t\t\telse if (this.strict) next[name] = value;\n\t\t}\n\t\tif (this.options.fillDefaults) {\n\t\t\tfor (const [name, spec] of Object.entries(specs)) {\n\t\t\t\tif (next[name] === undefined && spec.default !== undefined) {\n\t\t\t\t\tnext[name] = spec.default;\n\t\t\t\t\tthis.adjust(`params.${name}`, undefined, spec.default, 'defaulted', 'Filled with the model default.');\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (Object.keys(next).length > 0) this.request.params = next;\n\t\telse delete this.request.params;\n\t}\n\n\trun(): void {\n\t\tconst { caps, request } = this;\n\t\tfor (const key of Object.keys(request)) {\n\t\t\tif ((GENERATION_REQUEST_FIELDS as readonly string[]).includes(key)) continue;\n\t\t\tconst value = (request as any)[key];\n\t\t\tif (this.strict) this.error(key, value, `Unknown request field \"${key}\".`);\n\t\t\telse {\n\t\t\t\tdelete (request as any)[key];\n\t\t\t\tthis.adjust(key, value, undefined, 'dropped', `Unknown request field \"${key}\".`);\n\t\t\t}\n\t\t}\n\n\t\tif (request.model !== undefined && request.model !== caps.id) {\n\t\t\tthis.error('model', request.model, `The request targets \"${request.model}\" but the plan is for \"${caps.id}\".`);\n\t\t}\n\t\trequest.model = caps.id;\n\n\t\t// Text fields.\n\t\tconst promptCap = caps.prompt ?? {};\n\t\tif (promptCap.required && !(request.prompt ?? '').trim()) {\n\t\t\tthis.error('prompt', request.prompt, 'A prompt is required.');\n\t\t}\n\t\tconst countResolved = promptCap.countResolved ?? true;\n\t\tconst measured =\n\t\t\tcountResolved && this.options.resolvedPrompt !== undefined && this.options.resolvedPrompt !== request.prompt\n\t\t\t\t? this.options.resolvedPrompt\n\t\t\t\t: undefined;\n\t\tthis.planText('prompt', promptCap.maxLength, measured);\n\t\tfor (const field of ['negativePrompt', 'systemPrompt'] as const) {\n\t\t\tif (request[field] === undefined) continue;\n\t\t\tconst cap = textFieldCapability(caps[field]);\n\t\t\tif (!cap) {\n\t\t\t\tthis.unsupported(field, `The model does not take a ${field === 'negativePrompt' ? 'negative' : 'system'} prompt.`);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tthis.planText(field, cap.maxLength);\n\t\t}\n\n\t\tthis.planEnum('aspectRatio', caps.aspectRatios, aspectRatioRank, 'aspect ratio');\n\t\tthis.planEnum('resolution', caps.resolutions, resolutionRank, 'resolution');\n\t\tthis.planEnum('quality', caps.quality, qualityRank, 'quality');\n\t\tthis.planCount();\n\t\tthis.planDuration();\n\t\tthis.planSeed();\n\t\tthis.planMode();\n\t\tthis.addMentions();\n\t\tthis.planReferences();\n\t\tthis.planParams();\n\t}\n}\n\n/**\n * Plans `request` against a model's capabilities before sending it: snaps\n * enum values (aspect ratio, resolution, quality, count/duration choices) to\n * the nearest supported option, clamps ranges, truncates text and reference\n * lists over their limits, drops unsupported fields, and reports every change\n * in `adjustments` and every unfixable problem in `errors`.\n *\n * Pure and deterministic: the input is not mutated and the same input always\n * gives the same plan.\n */\nexport function planGenerationRequest(\n\trequest: GenerationRequest,\n\tcaps: ModelCapabilities,\n\toptions: PlanOptions = {}\n): GenerationPlan {\n\tconst strategy = options.strategy ?? 'nearest';\n\tconst planner = new Planner(caps, cloneRequest(request ?? {}), options, strategy);\n\tplanner.run();\n\treturn {\n\t\tok: planner.errors.length === 0,\n\t\trequest: planner.request,\n\t\tadjustments: planner.adjustments,\n\t\terrors: planner.errors,\n\t\tmodel: caps.id,\n\t\tstrategy\n\t};\n}\n","import type { ModelCapabilities } from './capabilities.js';\n\n/**\n * Stable JSON: object keys sorted, `undefined` members left out, so equal\n * values always give the same string regardless of key order.\n */\nexport function stableStringify(value: unknown): string {\n\tif (Array.isArray(value)) return `[${value.map((item) => (item === undefined ? 'null' : stableStringify(item))).join(',')}]`;\n\tif (value && typeof value === 'object') {\n\t\tconst entries = Object.keys(value as object)\n\t\t\t.filter((key) => (value as any)[key] !== undefined)\n\t\t\t.sort()\n\t\t\t.map((key) => `${JSON.stringify(key)}:${stableStringify((value as any)[key])}`);\n\t\treturn `{${entries.join(',')}}`;\n\t}\n\treturn JSON.stringify(value) ?? 'null';\n}\n\nconst FNV_PRIME = 0x01000193;\n\n/**\n * A short, stable, synchronous content hash (two independent 32-bit FNV-1a\n * lanes over the UTF-16 code units, 16 hex digits, prefixed with `h1-`).\n * It detects changes; it is not cryptographic, so do not use it to\n * authenticate content.\n */\nexport function hashText(text: string): string {\n\tlet a = 0x811c9dc5;\n\tlet b = 0x2f0e1d5b;\n\tfor (let i = 0; i < text.length; i++) {\n\t\tconst unit = text.charCodeAt(i);\n\t\ta = Math.imul(a ^ (unit & 0xff), FNV_PRIME);\n\t\ta = Math.imul(a ^ (unit >>> 8), FNV_PRIME);\n\t\tb = Math.imul(b ^ (unit >>> 8), FNV_PRIME);\n\t\tb = Math.imul(b ^ (unit & 0xff), FNV_PRIME);\n\t\tb ^= b >>> 15;\n\t}\n\t// Final avalanche so short inputs still spread over all digits.\n\ta ^= a >>> 16;\n\ta = Math.imul(a, 0x85ebca6b);\n\ta ^= a >>> 13;\n\tb ^= b >>> 16;\n\tb = Math.imul(b, 0xc2b2ae35);\n\tb ^= b >>> 13;\n\tconst hex = (n: number) => (n >>> 0).toString(16).padStart(8, '0');\n\treturn `h1-${hex(a)}${hex(b)}`;\n}\n\n/** {@link hashText} of the {@link stableStringify} form of `value`. */\nexport function hashValue(value: unknown): string {\n\treturn hashText(stableStringify(value));\n}\n\nconst PRESENTATION_ONLY = new Set(['name', 'description', 'badges', 'icon', 'group', 'timing']);\n\n/**\n * Hash of what a model accepts. Presentation fields (`name`, `description`,\n * `badges`, `icon`, `group`) and `timing` are left out, so renaming a model or\n * changing its progress estimate is not reported as a capability change.\n */\nexport function hashCapabilities(caps: ModelCapabilities): string {\n\tconst relevant: Record<string, unknown> = {};\n\tfor (const key of Object.keys(caps)) {\n\t\tif (!PRESENTATION_ONLY.has(key)) relevant[key] = (caps as any)[key];\n\t}\n\treturn hashValue(relevant);\n}\n"],"mappings":"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","names":["next"]}
|
|
@@ -584,6 +584,57 @@ function retouchFilter(data, w, h, n, kind, radius = 2, amount = 1) {
|
|
|
584
584
|
data[i] = v > 0 ? v : 0;
|
|
585
585
|
}
|
|
586
586
|
}
|
|
587
|
+
var IDENTITY_CLONE_TRANSFORM = { scaleX: 1, scaleY: 1, rotate: 0 };
|
|
588
|
+
function isIdentityCloneTransform(t) {
|
|
589
|
+
return t.scaleX === 1 && t.scaleY === 1 && (t.rotate % 360 + 360) % 360 === 0;
|
|
590
|
+
}
|
|
591
|
+
function cloneSamplePoint(t, source, anchor, x, y) {
|
|
592
|
+
const a = -t.rotate * Math.PI / 180;
|
|
593
|
+
const c = Math.cos(a);
|
|
594
|
+
const s = Math.sin(a);
|
|
595
|
+
const dx = x - anchor.x;
|
|
596
|
+
const dy = y - anchor.y;
|
|
597
|
+
return [source.x + (c * dx - s * dy) / t.scaleX, source.y + (s * dx + c * dy) / t.scaleY];
|
|
598
|
+
}
|
|
599
|
+
var TransformedPixelSource = class {
|
|
600
|
+
constructor(inner, map) {
|
|
601
|
+
this.inner = inner;
|
|
602
|
+
this.map = map;
|
|
603
|
+
}
|
|
604
|
+
inner;
|
|
605
|
+
map;
|
|
606
|
+
px = [0, 0, 0, 0];
|
|
607
|
+
sample(x, y, out) {
|
|
608
|
+
const [u, v] = this.map(x, y);
|
|
609
|
+
const x0 = Math.floor(u);
|
|
610
|
+
const y0 = Math.floor(v);
|
|
611
|
+
const fx = u - x0;
|
|
612
|
+
const fy = v - y0;
|
|
613
|
+
let r = 0;
|
|
614
|
+
let g = 0;
|
|
615
|
+
let b = 0;
|
|
616
|
+
let a = 0;
|
|
617
|
+
for (let k = 0; k < 4; k++) {
|
|
618
|
+
const w = (k & 1 ? fx : 1 - fx) * (k & 2 ? fy : 1 - fy);
|
|
619
|
+
if (w <= 0) continue;
|
|
620
|
+
if (!this.inner.sample(x0 + (k & 1), y0 + (k >> 1), this.px)) continue;
|
|
621
|
+
const pa = this.px[3] * w;
|
|
622
|
+
r += this.px[0] * pa;
|
|
623
|
+
g += this.px[1] * pa;
|
|
624
|
+
b += this.px[2] * pa;
|
|
625
|
+
a += pa;
|
|
626
|
+
}
|
|
627
|
+
if (!(a > 0)) {
|
|
628
|
+
out[0] = out[1] = out[2] = out[3] = 0;
|
|
629
|
+
return false;
|
|
630
|
+
}
|
|
631
|
+
out[0] = r / a;
|
|
632
|
+
out[1] = g / a;
|
|
633
|
+
out[2] = b / a;
|
|
634
|
+
out[3] = a;
|
|
635
|
+
return true;
|
|
636
|
+
}
|
|
637
|
+
};
|
|
587
638
|
var TilePixelSource = class {
|
|
588
639
|
constructor(readTile, channels, offset = { x: 0, y: 0 }) {
|
|
589
640
|
this.readTile = readTile;
|
|
@@ -1064,6 +1115,10 @@ export {
|
|
|
1064
1115
|
normalizeRetouch,
|
|
1065
1116
|
boxBlurPixels,
|
|
1066
1117
|
retouchFilter,
|
|
1118
|
+
IDENTITY_CLONE_TRANSFORM,
|
|
1119
|
+
isIdentityCloneTransform,
|
|
1120
|
+
cloneSamplePoint,
|
|
1121
|
+
TransformedPixelSource,
|
|
1067
1122
|
TilePixelSource,
|
|
1068
1123
|
RegionPixelSource,
|
|
1069
1124
|
readSourceRegion,
|
|
@@ -1078,4 +1133,4 @@ export {
|
|
|
1078
1133
|
spongeEffect,
|
|
1079
1134
|
rgbaViewOfGrey
|
|
1080
1135
|
};
|
|
1081
|
-
//# sourceMappingURL=chunk-
|
|
1136
|
+
//# sourceMappingURL=chunk-ILYFOJUN.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/paint/heal.ts","../src/paint/retouch.ts"],"sourcesContent":["// Portions ported from photocraft/crates/algo/src/poisson.rs and inpaint.rs (MIT OR Apache-2.0, © ArtCraft Team and contributors). See THIRD_PARTY_NOTICES.md.\n\n/**\n * Gradient-domain (\"Poisson\") blending for the Healing Brush and the Spot Healing Brush.\n *\n * Method: P. Pérez, M. Gangnet, A. Blake, *Poisson Image Editing*, SIGGRAPH 2003. Seamless cloning\n * looks for `f` over a region Ω with `f = f*` (the destination) on its boundary and `∇f` as close\n * as possible to the source's `∇g`. The answer is `f = g + h`, where `h` is the membrane: the\n * harmonic function (`Δh = 0`) that equals `f* − g` on the boundary. So healed pixels keep the\n * source's texture while their colour and lighting are pulled to the pixels around the stroke.\n *\n * The Laplace equation is solved on the 4-connected grid by successive over-relaxation, started\n * from a recursively solved half-resolution grid (cascadic multigrid). Harmonic functions are\n * smooth, so the coarse guess is close and a few sweeps per level remove the rest.\n *\n * Buffers are interleaved `w × h × ch` floats in any units (the callers use 0..255). Pure maths:\n * no DOM, no framework.\n */\n\n/** Largest per-sweep update below which a solve has converged. */\nconst TOL = 2e-3;\n/** Sweeps (cap) and relaxation on every level above the coarsest. */\nconst FINE_ITERS = 30;\nconst FINE_OMEGA = 1.7;\n\n/**\n * Solves `Δv = 0` on the `unknown` pixels, with the known pixels of `v` as Dirichlet values\n * (neighbours off the grid are ignored: a free boundary). `v` holds the known values on entry and\n * the solution on exit.\n */\nexport function solveMembrane(w: number, h: number, unknown: ArrayLike<boolean | number>, v: Float32Array): void {\n if (unknown.length !== w * h || v.length !== w * h) throw new RangeError(`solveMembrane: expected ${w * h} cells, got ${unknown.length} and ${v.length}.`);\n const u = new Uint8Array(w * h);\n for (let i = 0; i < u.length; i++) u[i] = unknown[i] ? 1 : 0;\n solveLevel(w, h, u, v, 0);\n}\n\nfunction solveLevel(w: number, h: number, unknown: Uint8Array, v: Float32Array, depth: number): void {\n let nUnknown = 0;\n let knownSum = 0;\n let nKnown = 0;\n for (let i = 0; i < unknown.length; i++) {\n if (unknown[i]) nUnknown++;\n else {\n knownSum += v[i];\n nKnown++;\n }\n }\n if (nUnknown === 0 || nKnown === 0) return;\n if (w >= 8 && h >= 8 && nUnknown > 64 && depth < 16) {\n // Restrict: a coarse cell is known when any of its children is (the mean of those).\n const cw = Math.ceil(w / 2);\n const chh = Math.ceil(h / 2);\n const cu = new Uint8Array(cw * chh).fill(1);\n const cv = new Float32Array(cw * chh);\n for (let cy = 0; cy < chh; cy++) {\n for (let cx = 0; cx < cw; cx++) {\n let s = 0;\n let n = 0;\n for (let k = 0; k < 4; k++) {\n const x = cx * 2 + (k & 1);\n const y = cy * 2 + (k >> 1);\n if (x < w && y < h && !unknown[y * w + x]) {\n s += v[y * w + x];\n n++;\n }\n }\n if (n > 0) {\n cu[cy * cw + cx] = 0;\n cv[cy * cw + cx] = s / n;\n }\n }\n }\n solveLevel(cw, chh, cu, cv, depth + 1);\n // Prolong: a bilinear sample of the coarse solution is the starting guess.\n for (let y = 0; y < h; y++) {\n const fy = Math.min(chh - 1, Math.max(0, (y + 0.5) / 2 - 0.5));\n const y0 = Math.floor(fy);\n const y1 = Math.min(chh - 1, y0 + 1);\n const ty = fy - y0;\n for (let x = 0; x < w; x++) {\n if (!unknown[y * w + x]) continue;\n const fx = Math.min(cw - 1, Math.max(0, (x + 0.5) / 2 - 0.5));\n const x0 = Math.floor(fx);\n const x1 = Math.min(cw - 1, x0 + 1);\n const tx = fx - x0;\n const a = cv[y0 * cw + x0] + (cv[y0 * cw + x1] - cv[y0 * cw + x0]) * tx;\n const b = cv[y1 * cw + x0] + (cv[y1 * cw + x1] - cv[y1 * cw + x0]) * tx;\n v[y * w + x] = a + (b - a) * ty;\n }\n }\n sor(w, h, unknown, v, FINE_ITERS, FINE_OMEGA);\n } else {\n const mean = knownSum / nKnown;\n for (let i = 0; i < v.length; i++) if (unknown[i]) v[i] = mean;\n sor(w, h, unknown, v, 2000, 1.85);\n }\n}\n\n/** Over-relaxed Gauss-Seidel sweeps over the unknown cells until the largest update is below `TOL`. */\nfunction sor(w: number, h: number, unknown: Uint8Array, v: Float32Array, maxIter: number, omega: number): void {\n let n = 0;\n for (let i = 0; i < unknown.length; i++) if (unknown[i]) n++;\n const cells = new Uint32Array(n);\n const masks = new Uint8Array(n);\n for (let i = 0, k = 0; i < unknown.length; i++) {\n if (!unknown[i]) continue;\n const x = i % w;\n const y = (i - x) / w;\n cells[k] = i;\n masks[k++] = (x > 0 ? 1 : 0) | (x + 1 < w ? 2 : 0) | (y > 0 ? 4 : 0) | (y + 1 < h ? 8 : 0);\n }\n for (let it = 0; it < maxIter; it++) {\n let maxD = 0;\n for (let k = 0; k < n; k++) {\n const i = cells[k];\n const m = masks[k];\n let s: number;\n let c: number;\n if (m === 15) {\n s = v[i - 1] + v[i + 1] + v[i - w] + v[i + w];\n c = 4;\n } else {\n s = 0;\n c = 0;\n if (m & 1) (s += v[i - 1]), c++;\n if (m & 2) (s += v[i + 1]), c++;\n if (m & 4) (s += v[i - w]), c++;\n if (m & 8) (s += v[i + w]), c++;\n if (c === 0) continue;\n }\n const d = omega * (s / c - v[i]);\n v[i] += d;\n const ad = d < 0 ? -d : d;\n if (ad > maxD) maxD = ad;\n }\n if (maxD < TOL) break;\n }\n}\n\n/**\n * Seamless cloning: `dst` outside `mask`; inside, `src` plus the membrane that removes the\n * mismatch at the mask's edge. So the result keeps the source's texture and takes the\n * destination's colour and light. `src` and `dst` are interleaved `w × h × ch`; leave a one-pixel\n * unmasked margin for a fully fixed boundary.\n */\nexport function seamlessClone(w: number, h: number, ch: number, src: ArrayLike<number>, dst: ArrayLike<number>, mask: ArrayLike<boolean | number>): Float32Array {\n const n = w * h;\n if (src.length !== n * ch || dst.length !== n * ch || mask.length !== n) throw new RangeError('seamlessClone: src, dst and mask must cover w × h pixels.');\n const out = new Float32Array(n * ch);\n const hv = new Float32Array(n);\n for (let c = 0; c < ch; c++) {\n for (let i = 0; i < n; i++) hv[i] = mask[i] ? 0 : dst[i * ch + c] - src[i * ch + c];\n solveMembrane(w, h, mask, hv);\n for (let i = 0; i < n; i++) out[i * ch + c] = mask[i] ? src[i * ch + c] + hv[i] : dst[i * ch + c];\n }\n return out;\n}\n\n/** Membrane fill (no source texture): the known pixels interpolated smoothly into `hole`. */\nexport function membraneFill(w: number, h: number, ch: number, img: ArrayLike<number>, hole: ArrayLike<boolean | number>): Float32Array {\n const n = w * h;\n const out = new Float32Array(n * ch);\n const v = new Float32Array(n);\n for (let c = 0; c < ch; c++) {\n for (let i = 0; i < n; i++) v[i] = hole[i] ? 0 : img[i * ch + c];\n solveMembrane(w, h, hole, v);\n for (let i = 0; i < n; i++) out[i * ch + c] = v[i];\n }\n return out;\n}\n\n/** A mask grown by `r` pixels (square structuring element). */\nexport function dilateMask(w: number, h: number, mask: ArrayLike<boolean | number>, r: number): Uint8Array {\n const tmp = new Uint8Array(w * h);\n for (let y = 0; y < h; y++) {\n for (let x = 0; x < w; x++) {\n if (!mask[y * w + x]) continue;\n for (let xx = Math.max(0, x - r); xx <= Math.min(w - 1, x + r); xx++) tmp[y * w + xx] = 1;\n }\n }\n const out = new Uint8Array(w * h);\n for (let y = 0; y < h; y++) {\n for (let x = 0; x < w; x++) {\n if (!tmp[y * w + x]) continue;\n for (let yy = Math.max(0, y - r); yy <= Math.min(h - 1, y + r); yy++) out[yy * w + x] = 1;\n }\n }\n return out;\n}\n\n/** A summed-area table over a mask, for \"how many masked cells in this window\". */\nclass MaskIntegral {\n private readonly s: Uint32Array;\n constructor(\n private readonly w: number,\n private readonly h: number,\n mask: ArrayLike<boolean | number>\n ) {\n const W = w + 1;\n this.s = new Uint32Array(W * (h + 1));\n for (let y = 0; y < h; y++) {\n let row = 0;\n for (let x = 0; x < w; x++) {\n row += mask[y * w + x] ? 1 : 0;\n this.s[(y + 1) * W + x + 1] = this.s[y * W + x + 1] + row;\n }\n }\n }\n /** Masked cells in [x0, x1) × [y0, y1) (clipped to the grid). */\n count(x0: number, y0: number, x1: number, y1: number): number {\n const W = this.w + 1;\n const a = Math.max(0, Math.min(this.w, x0));\n const b = Math.max(0, Math.min(this.h, y0));\n const c = Math.max(0, Math.min(this.w, x1));\n const d = Math.max(0, Math.min(this.h, y1));\n if (c <= a || d <= b) return 0;\n return this.s[d * W + c] - this.s[b * W + c] - this.s[d * W + a] + this.s[b * W + a];\n }\n}\n\n/** Bounding box [x0, y0, x1, y1) of the set cells, or null. */\nexport function maskBounds(w: number, h: number, mask: ArrayLike<boolean | number>): [number, number, number, number] | null {\n let x0 = w;\n let y0 = h;\n let x1 = -1;\n let y1 = -1;\n for (let y = 0; y < h; y++) {\n for (let x = 0; x < w; x++) {\n if (!mask[y * w + x]) continue;\n if (x < x0) x0 = x;\n if (x > x1) x1 = x;\n if (y < y0) y0 = y;\n if (y > y1) y1 = y;\n }\n }\n return x1 < 0 ? null : [x0, y0, x1 + 1, y1 + 1];\n}\n\n/**\n * Proximity match: the translation `(dx, dy)` (within `maxRadius`) whose pixels best match the\n * ring of `ring` pixels around the hole (sum of squared differences), so `img[p + (dx, dy)]` can\n * fill `p` in the hole. The source window must lie on the grid and hold no hole pixels. Nearer\n * sources win ties. Returns null when no translation fits.\n */\nexport function bestOffset(w: number, h: number, ch: number, img: ArrayLike<number>, hole: ArrayLike<boolean | number>, ring: number, maxRadius: number): [number, number] | null {\n const bb = maskBounds(w, h, hole);\n if (!bb) return null;\n const extent = Math.max(w, h);\n const R = Math.max(0, Math.min(extent, Math.floor(maxRadius)));\n if (R === 0) return null;\n const rg = Math.max(1, Math.min(extent, Math.floor(ring)));\n const hs = new MaskIntegral(w, h, hole);\n const x0 = bb[0] - rg;\n const y0 = bb[1] - rg;\n const x1 = bb[2] + rg;\n const y1 = bb[3] + rg;\n // Sample points: the ring around the hole, subsampled to about 2000.\n const pts: number[] = [];\n for (let y = Math.max(0, y0); y < Math.min(h, y1); y++) {\n for (let x = Math.max(0, x0); x < Math.min(w, x1); x++) {\n if (hole[y * w + x]) continue;\n if (hs.count(x - rg, y - rg, x + rg + 1, y + rg + 1) > 0) pts.push(x, y);\n }\n }\n const stride = Math.max(1, Math.floor(pts.length / 2 / 2000));\n const sx: number[] = [];\n const sy: number[] = [];\n for (let i = 0; i < pts.length; i += 2 * stride) {\n sx.push(pts[i]);\n sy.push(pts[i + 1]);\n }\n const n = Math.max(1, sx.length);\n const evalAt = (dx: number, dy: number, cutoff: number): number | null => {\n if (dx === 0 && dy === 0) return null;\n const hx0 = x0 + dx;\n const hy0 = y0 + dy;\n const hx1 = x1 + dx;\n const hy1 = y1 + dy;\n if (hx0 < 0 || hy0 < 0 || hx1 > w || hy1 > h) return null;\n if (hs.count(hx0, hy0, hx1, hy1) !== 0) return null;\n const penalty = 1 + 1e-3 * (Math.hypot(dx, dy) / R);\n let e = 0;\n for (let i = 0; i < sx.length; i++) {\n const a = (sy[i] * w + sx[i]) * ch;\n const b = ((sy[i] + dy) * w + sx[i] + dx) * ch;\n for (let c = 0; c < ch; c++) {\n const d = img[a + c] - img[b + c];\n e += d * d;\n }\n if ((i & 31) === 31 && (e / n) * penalty >= cutoff) return null;\n }\n return (e / n) * penalty;\n };\n const found: { best: [number, number] | null; e: number } = { best: null, e: Infinity };\n const consider = (dx: number, dy: number) => {\n const e = evalAt(dx, dy, found.e);\n if (e !== null && e < found.e) {\n found.e = e;\n found.best = [dx, dy];\n }\n };\n // A coarse grid over the search window, then every offset around the winner.\n const step = Math.max(1, Math.floor(R / 24));\n for (let dy = -R; dy <= R; dy += step) for (let dx = -R; dx <= R; dx += step) consider(dx, dy);\n if (step > 1 && found.best) {\n const [bx, by] = found.best;\n for (let dy = by - step; dy <= by + step; dy++) for (let dx = bx - step; dx <= bx + step; dx++) consider(dx, dy);\n }\n return found.best;\n}\n\n// ---------------------------------------------------------------------------\n// Content-aware fill (PatchMatch, coarse to fine)\n// ---------------------------------------------------------------------------\n\nconst PATCH_R = 3;\n\n/** A small deterministic generator (mulberry32). */\nfunction rng(seed: number): () => number {\n let a = seed >>> 0;\n return () => {\n a = (a + 0x6d2b79f5) >>> 0;\n let t = a;\n t = Math.imul(t ^ (t >>> 15), t | 1);\n t ^= t + Math.imul(t ^ (t >>> 7), t | 61);\n return ((t ^ (t >>> 14)) >>> 0) / 4294967296;\n };\n}\n\ninterface Level {\n w: number;\n h: number;\n img: Float32Array;\n hole: Uint8Array;\n}\n\n/** Half-size level: known pixels averaged, a block is hole when any of it is. */\nfunction downsample(l: Level, ch: number): Level {\n const w = Math.max(1, l.w >> 1);\n const h = Math.max(1, l.h >> 1);\n const img = new Float32Array(w * h * ch);\n const hole = new Uint8Array(w * h);\n for (let y = 0; y < h; y++) {\n for (let x = 0; x < w; x++) {\n let n = 0;\n const o = (y * w + x) * ch;\n for (let dy = 0; dy < 2; dy++) {\n for (let dx = 0; dx < 2; dx++) {\n const sx = Math.min(l.w - 1, 2 * x + dx);\n const sy = Math.min(l.h - 1, 2 * y + dy);\n const i = sy * l.w + sx;\n if (l.hole[i]) {\n hole[y * w + x] = 1;\n continue;\n }\n for (let c = 0; c < ch; c++) img[o + c] += l.img[i * ch + c];\n n++;\n }\n }\n if (n) for (let c = 0; c < ch; c++) img[o + c] /= n;\n }\n }\n return { w, h, img, hole };\n}\n\n/**\n * Fills `hole` in `img` (`w × h × ch` floats) from the rest of the image, so texture and edges\n * continue across it: PatchMatch nearest-neighbour fields over 7 × 7 patches with patch voting\n * (Wexler et al. / Barnes et al.), run coarse to fine from a smooth fill. Deterministic for the\n * same input. Returns the filled image; pixels outside `hole` are unchanged. Falls back to a\n * smooth fill when there is no whole patch to copy from.\n */\nexport function contentAwareFill(w: number, h: number, ch: number, img: ArrayLike<number>, hole: ArrayLike<boolean | number>, options: { iterations?: number; seed?: number } = {}): Float32Array {\n const iters = options.iterations ?? 4;\n const base: Level = { w, h, img: Float32Array.from(img), hole: Uint8Array.from(hole as ArrayLike<number>, (v) => (v ? 1 : 0)) };\n const levels: Level[] = [base];\n // Coarser levels while the hole is still more than a couple of patches across.\n while (levels.length < 4) {\n const top = levels[levels.length - 1];\n const b = maskBounds(top.w, top.h, top.hole);\n if (!b || Math.max(b[2] - b[0], b[3] - b[1]) < 4 * PATCH_R || top.w < 8 * PATCH_R || top.h < 8 * PATCH_R) break;\n levels.push(downsample(top, ch));\n }\n const random = rng(options.seed ?? w * 73856093 + h * 19349663);\n let prevFill: Float32Array | null = null;\n let prevNnf: Int32Array | null = null;\n let prevW = 0;\n for (let li = levels.length - 1; li >= 0; li--) {\n const { w: W, h: H, hole: holeL } = levels[li];\n const cur = new Float32Array(levels[li].img);\n // Start: the coarser fill scaled up, or a smooth fill at the coarsest level.\n if (prevFill) {\n for (let i = 0; i < W * H; i++) {\n if (!holeL[i]) continue;\n const x = Math.min(prevW - 1, (i % W) >> 1);\n const y = Math.min(Math.floor(prevFill.length / ch / prevW) - 1, Math.floor(i / W) >> 1);\n for (let c = 0; c < ch; c++) cur[i * ch + c] = prevFill[(y * prevW + x) * ch + c];\n }\n } else cur.set(membraneFill(W, H, ch, cur, holeL));\n // Valid sources: whole patches with no hole in them.\n const blocked = dilateMask(W, H, holeL, PATCH_R);\n const valid: number[] = [];\n for (let y = PATCH_R; y < H - PATCH_R; y++) for (let x = PATCH_R; x < W - PATCH_R; x++) if (!blocked[y * W + x]) valid.push(y * W + x);\n if (!valid.length) {\n prevFill = cur;\n prevNnf = null;\n prevW = W;\n continue;\n }\n // Targets: patch centres whose patch touches the hole (kept inside the image).\n const targets: number[] = [];\n for (let y = 0; y < H; y++) for (let x = 0; x < W; x++) if (blocked[y * W + x]) targets.push(y * W + x);\n const nnf = new Int32Array(W * H).fill(-1);\n const cost = new Float64Array(W * H);\n const clampC = (v: number, n: number) => Math.min(n - 1 - PATCH_R, Math.max(PATCH_R, v));\n const dist = (t: number, s: number, limit: number) => {\n const tx = clampC(t % W, W);\n const ty = clampC(Math.floor(t / W), H);\n const sx = s % W;\n const sy = Math.floor(s / W);\n let d = 0;\n for (let dy = -PATCH_R; dy <= PATCH_R; dy++) {\n const tr = (ty + dy) * W;\n const sr = (sy + dy) * W;\n for (let dx = -PATCH_R; dx <= PATCH_R; dx++) {\n const a = (tr + tx + dx) * ch;\n const b = (sr + sx + dx) * ch;\n for (let c = 0; c < ch; c++) {\n const e = cur[a + c] - cur[b + c];\n d += e * e;\n }\n }\n if (d >= limit) return d;\n }\n return d;\n };\n const isValid = (s: number) => {\n const x = s % W;\n const y = Math.floor(s / W);\n return s >= 0 && x >= PATCH_R && y >= PATCH_R && x < W - PATCH_R && y < H - PATCH_R && !blocked[s];\n };\n for (const t of targets) {\n let s = -1;\n if (prevNnf) {\n const px = Math.min(prevW - 1, (t % W) >> 1);\n const py = Math.floor(t / W) >> 1;\n const ps = prevNnf[py * prevW + px];\n if (ps >= 0) {\n const cand = (Math.floor(ps / prevW) * 2 + (Math.floor(t / W) & 1)) * W + (ps % prevW) * 2 + ((t % W) & 1);\n if (isValid(cand)) s = cand;\n }\n }\n if (s < 0) s = valid[Math.floor(random() * valid.length)];\n nnf[t] = s;\n }\n for (let em = 0; em < iters; em++) {\n for (const t of targets) cost[t] = dist(t, nnf[t], Infinity);\n for (let pass = 0; pass < 4; pass++) {\n const fwd = pass % 2 === 0;\n const step = fwd ? 1 : -1;\n for (let k = 0; k < targets.length; k++) {\n const t = targets[fwd ? k : targets.length - 1 - k];\n const tx = t % W;\n const ty = Math.floor(t / W);\n // Propagation: a neighbour's match, shifted by one.\n for (const [nx, ny] of [[tx - step, ty], [tx, ty - step]]) {\n if (nx < 0 || ny < 0 || nx >= W || ny >= H) continue;\n const ns = nnf[ny * W + nx];\n if (ns < 0) continue;\n const cand = ns + step * (nx === tx ? W : 1);\n if (!isValid(cand) || cand === nnf[t]) continue;\n const d = dist(t, cand, cost[t]);\n if (d < cost[t]) {\n cost[t] = d;\n nnf[t] = cand;\n }\n }\n // Random search in shrinking windows around the current match.\n const bx = nnf[t] % W;\n const by = Math.floor(nnf[t] / W);\n for (let r = Math.max(W, H); r >= 1; r >>= 1) {\n const cx = Math.round(bx + (random() * 2 - 1) * r);\n const cy = Math.round(by + (random() * 2 - 1) * r);\n const cand = cy * W + cx;\n if (cx < 0 || cy < 0 || cx >= W || cy >= H || !isValid(cand)) continue;\n const d = dist(t, cand, cost[t]);\n if (d < cost[t]) {\n cost[t] = d;\n nnf[t] = cand;\n }\n }\n }\n }\n // Voting: each hole pixel averages what the patches covering it propose.\n const acc = new Float64Array(W * H * ch);\n const wsum = new Float64Array(W * H);\n for (const t of targets) {\n const tx = clampC(t % W, W);\n const ty = clampC(Math.floor(t / W), H);\n const s = nnf[t];\n const sx = s % W;\n const sy = Math.floor(s / W);\n for (let dy = -PATCH_R; dy <= PATCH_R; dy++) {\n for (let dx = -PATCH_R; dx <= PATCH_R; dx++) {\n const q = (ty + dy) * W + tx + dx;\n if (!holeL[q]) continue;\n const src = ((sy + dy) * W + sx + dx) * ch;\n for (let c = 0; c < ch; c++) acc[q * ch + c] += cur[src + c];\n wsum[q] += 1;\n }\n }\n }\n for (let q = 0; q < W * H; q++) if (holeL[q] && wsum[q] > 0) for (let c = 0; c < ch; c++) cur[q * ch + c] = acc[q * ch + c] / wsum[q];\n }\n prevFill = cur;\n prevNnf = nnf;\n prevW = W;\n }\n const out = Float32Array.from(img);\n for (let i = 0; i < w * h; i++) if (base.hole[i]) for (let c = 0; c < ch; c++) out[i * ch + c] = prevFill![i * ch + c];\n return out;\n}\n","// Portions ported from photocraft/crates/paint/src/retouch.rs, crates/algo/src/retouch.rs and crates/engine/src/retouch_cmds.rs (MIT OR Apache-2.0, © ArtCraft Team and contributors). See THIRD_PARTY_NOTICES.md.\n\n/**\n * The retouching tools on the shared brush engine: Clone Stamp, Healing Brush, Spot Healing\n * Brush, Smudge, Dodge, Burn and Sponge. Two stroke shapes cover them all:\n *\n * - **Accumulate, then composite** (Clone Stamp, Dodge, Burn; the Healing tools' result): the\n * stroke's dabs build up one `CoverageMap` (flow builds towards the dab's opacity ceiling), and\n * per-pixel paint taken from the pre-stroke state (a cloned source, a toned copy of the pixel,\n * a healed patch) is composited through it with `applyRetouchToTile`. Pixels painted earlier in\n * the stroke are never sampled again, and overlapping dabs never exceed the stroke's opacity.\n * - **Sequential dabs** (Smudge, Sponge): `RetouchDabStroke` runs each dab in order over live\n * tiles, so dab n sees what dab n − 1 did.\n *\n * The Healing Brush clones while it is drawn and, when the stroke ends, replaces the clone with a\n * seamless clone (`healPixels`, Poisson blending): the source's texture with the colour and light\n * of the pixels around the stroke. The Spot Healing Brush finds its own source (`spotHealPixels`).\n *\n * Tone curves (`dodgeBurnCurve`, `dodgeBurn`, `sponge`) are photocraft's, made to behave like\n * Photoshop's tools: the chosen range moves most, black and white stay put for midtones, and\n * Protect Tones works on luma so hue and saturation are kept. Data in, pixels out; no DOM.\n */\n\nimport { blendPixel, type BlendMode } from '../raster/blend';\nimport type { RasterRect } from '../raster/surface';\nimport { TILE, tileKey } from '../raster/surface';\nimport { srgbDecode, srgbEncode } from '../raster/deep';\nimport { DabWalker, dabRect, rasterizeDab, type BrushSettings, type CoverageMap, type Dab, type StrokePoint } from './brush';\nimport { SmudgeTip, type SmudgeSettings } from './blending';\nimport { TileMedium, put255, type PaintPixels, type PaintTileTarget } from './exchange';\nimport { bestOffset, contentAwareFill, dilateMask, maskBounds, membraneFill, seamlessClone } from './heal';\n\n// ---------------------------------------------------------------------------\n// Tone kernels\n// ---------------------------------------------------------------------------\n\n/** The tonal range Dodge and Burn work on most. */\nexport type ToneRange = 'shadows' | 'midtones' | 'highlights';\n\nexport const TONE_RANGES: readonly ToneRange[] = ['shadows', 'midtones', 'highlights'];\n\n/** Rec. 601 luma of straight RGB (0..1). */\nexport function luma(r: number, g: number, b: number): number {\n return 0.299 * r + 0.587 * g + 0.114 * b;\n}\n\n/** The dodge (or burn) transfer of one value `v` (0..1) at exposure `e` (0..1). */\nexport function dodgeBurnCurve(v: number, e: number, range: ToneRange, burn: boolean): number {\n const x = Math.max(0, v);\n const k = Math.min(1, Math.max(0, e));\n const c = Math.min(1, x);\n if (range === 'midtones') {\n // A gamma bend weighted to peak at mid-grey: 0 and 1 stay where they are.\n const w = Math.min(1, Math.max(0, 4 * x * (1 - x)));\n return x + w * (Math.pow(c, burn ? 1 + k : 1 / (1 + k)) - x);\n }\n // Shadows / highlights: `v + e·w·(target − v)`, weighted (1 − v)² or v², so that end moves most.\n const w = range === 'shadows' ? (1 - c) * (1 - c) : c * c;\n return burn ? x - k * w * x : x + k * w * (1 - c);\n}\n\n/** Brings RGB back into 0..1 keeping its luma (mixing towards grey) rather than clipping each channel. */\nfunction compressGamut(c: number[], l: number): void {\n const L = Math.min(1, Math.max(0, l));\n const lo = Math.min(c[0], c[1], c[2]);\n const hi = Math.max(c[0], c[1], c[2]);\n let t = 1;\n if (hi > 1 && hi - L > 1e-9) t = Math.min(t, (1 - L) / (hi - L));\n if (lo < 0 && L - lo > 1e-9) t = Math.min(t, L / (L - lo));\n for (let i = 0; i < 3; i++) c[i] = L + (c[i] - L) * t;\n}\n\n/**\n * Dodge (or burn) straight RGB `c` (0..1, written in place) at exposure `e`. With `protectTones`\n * the curve moves luma and the colour is scaled to it (hue and saturation kept); otherwise each\n * channel goes through the curve.\n */\nexport function dodgeBurn(c: number[], e: number, range: ToneRange, burn: boolean, protectTones: boolean): number[] {\n if (!(e > 0)) return c;\n if (protectTones) {\n const l = luma(c[0], c[1], c[2]);\n const nl = dodgeBurnCurve(l, e, range, burn);\n if (l > 1e-6) for (let i = 0; i < 3; i++) c[i] *= nl / l;\n else c[0] = c[1] = c[2] = nl;\n compressGamut(c, nl);\n } else for (let i = 0; i < 3; i++) c[i] = dodgeBurnCurve(c[i], e, range, burn);\n return c;\n}\n\n/** HSV saturation (chroma / max) of straight RGB. */\nexport function saturationOf(r: number, g: number, b: number): number {\n const lo = Math.min(r, g, b);\n const hi = Math.max(r, g, b);\n return hi <= 1e-6 ? 0 : Math.min(1, Math.max(0, (hi - lo) / hi));\n}\n\n/**\n * Sponge: moves straight RGB `c` (written in place) away from (`saturate`) or towards its luma\n * grey by `amount` (0..1). `vibrance` damps it where it would clip: saturating touches already\n * saturated colours less, desaturating touches near-greys less. Gamut-compressed, never clipped.\n */\nexport function sponge(c: number[], amount: number, saturate: boolean, vibrance: boolean): number[] {\n let a = Math.min(1, Math.max(0, amount));\n if (!(a > 0)) return c;\n if (vibrance) {\n const s = saturationOf(c[0], c[1], c[2]);\n a *= saturate ? 1 - s : 0.25 + 0.75 * s;\n }\n const l = luma(c[0], c[1], c[2]);\n const k = saturate ? 1 + a : 1 - a;\n for (let i = 0; i < 3; i++) c[i] = l + (c[i] - l) * k;\n compressGamut(c, l);\n return c;\n}\n\n/** Per-dab strength so that one pass over a point totals about `e`, whatever the spacing. */\nexport function perDabStrength(e: number, spacing: number): number {\n return 1 - Math.pow(1 - Math.min(1, Math.max(0, e)), Math.min(1, Math.max(0.01, spacing)));\n}\n\n// ---------------------------------------------------------------------------\n// Settings\n// ---------------------------------------------------------------------------\n\n/** Which pixels the Clone Stamp and the Healing tools sample. */\nexport type RetouchSample = 'current' | 'current-below' | 'all';\n\nexport const RETOUCH_SAMPLES: readonly RetouchSample[] = ['current', 'current-below', 'all'];\n\n/** How the Spot Healing Brush finds its source. */\nexport type SpotHealType = 'proximity-match' | 'content-aware' | 'smooth';\n\nexport const SPOT_HEAL_TYPES: readonly SpotHealType[] = ['proximity-match', 'content-aware', 'smooth'];\n\n/** The retouching tools' options. */\nexport interface RetouchSettings {\n /** Clone / heal: keep the source offset from stroke to stroke (default true); off, every stroke starts at the source point. */\n aligned: boolean;\n /** Clone / heal / spot heal: what is sampled (default `current`: the target layer). */\n sample: RetouchSample;\n /** Spot heal: `proximity-match` (default: the best matching patch nearby), `content-aware` (texture and edges synthesised from patches around it) or `smooth` (a smooth fill from the edges). */\n spotType: SpotHealType;\n /** Dodge / burn: the tonal range (default `midtones`). */\n range: ToneRange;\n /** Dodge / burn: exposure 0..1 (default 0.5). */\n exposure: number;\n /** Dodge / burn: tone luma only, keeping hue and saturation (default true). */\n protectTones: boolean;\n /** Sponge: `desaturate` (default) or `saturate`. */\n spongeMode: 'desaturate' | 'saturate';\n /** Sponge: damp the change where colours would clip (default true). */\n vibrance: boolean;\n /** Smudge: how strongly the finger carries and lays paint; Blur / Sharpen: how strongly they act, 0..1 (default 0.5). */\n strength: number;\n /** History Brush: how many undo steps back it paints from; 0 (default) is the oldest state history keeps. */\n historySteps: number;\n}\n\nexport const DEFAULT_RETOUCH: Readonly<RetouchSettings> = {\n aligned: true,\n sample: 'current',\n spotType: 'proximity-match',\n range: 'midtones',\n exposure: 0.5,\n protectTones: true,\n spongeMode: 'desaturate',\n vibrance: true,\n strength: 0.5,\n historySteps: 0,\n};\n\n/** Retouch settings with every field valid (missing or invalid fields from `base`). */\nexport function normalizeRetouch(raw: Partial<RetouchSettings> = {}, base: RetouchSettings = DEFAULT_RETOUCH): RetouchSettings {\n const unit = (v: unknown, d: number) => (typeof v === 'number' && Number.isFinite(v) ? Math.min(1, Math.max(0, v)) : d);\n const bool = (v: unknown, d: boolean) => (typeof v === 'boolean' ? v : d);\n const pick = <T extends string>(v: unknown, all: readonly T[], d: T): T => (all.includes(v as T) ? (v as T) : d);\n return {\n aligned: bool(raw.aligned, base.aligned),\n sample: pick(raw.sample, RETOUCH_SAMPLES, base.sample),\n spotType: pick(raw.spotType, SPOT_HEAL_TYPES, base.spotType),\n range: pick(raw.range, TONE_RANGES, base.range),\n exposure: unit(raw.exposure, base.exposure),\n protectTones: bool(raw.protectTones, base.protectTones),\n spongeMode: pick(raw.spongeMode, ['desaturate', 'saturate'] as const, base.spongeMode),\n vibrance: bool(raw.vibrance, base.vibrance),\n strength: unit(raw.strength, base.strength),\n historySteps: typeof raw.historySteps === 'number' && Number.isFinite(raw.historySteps) ? Math.min(1000, Math.max(0, Math.round(raw.historySteps))) : base.historySteps,\n };\n}\n\n/**\n * Box blur of `data` (`w × h × n` floats) in place, `r` pixels each side, edges clamped. RGBA\n * blurs premultiplied, so transparent pixels lend no colour. Run twice for a near-Gaussian.\n */\nexport function boxBlurPixels(data: Float32Array, w: number, h: number, n: 1 | 4, r: number): void {\n if (r < 1) return;\n if (n === 4) for (let i = 0; i < data.length; i += 4) for (let c = 0; c < 3; c++) data[i + c] *= data[i + 3] / 255;\n const tmp = new Float32Array(data.length);\n const k = 1 / (2 * r + 1);\n for (let y = 0; y < h; y++) {\n for (let x = 0; x < w; x++) {\n for (let c = 0; c < n; c++) {\n let s = 0;\n for (let d = -r; d <= r; d++) s += data[(y * w + Math.min(w - 1, Math.max(0, x + d))) * n + c];\n tmp[(y * w + x) * n + c] = s * k;\n }\n }\n }\n for (let y = 0; y < h; y++) {\n for (let x = 0; x < w; x++) {\n for (let c = 0; c < n; c++) {\n let s = 0;\n for (let d = -r; d <= r; d++) s += tmp[(Math.min(h - 1, Math.max(0, y + d)) * w + x) * n + c];\n data[(y * w + x) * n + c] = s * k;\n }\n }\n }\n if (n === 4) {\n for (let i = 0; i < data.length; i += 4) {\n const a = data[i + 3] / 255;\n for (let c = 0; c < 3; c++) data[i + c] = a > 0 ? data[i + c] / a : 0;\n }\n }\n}\n\n/**\n * The Blur / Sharpen tools' filter over a padded region (`w × h × n` floats on the 0..255 scale,\n * in place): `blur` is two box passes of `radius`; `sharpen` is an unsharp mask of `amount`\n * over a radius-1 blur (colour only; alpha kept). Values stay at or above 0.\n */\nexport function retouchFilter(data: Float32Array, w: number, h: number, n: 1 | 4, kind: 'blur' | 'sharpen', radius = 2, amount = 1): void {\n if (kind === 'blur') {\n boxBlurPixels(data, w, h, n, radius);\n boxBlurPixels(data, w, h, n, radius);\n return;\n }\n const soft = data.slice();\n boxBlurPixels(soft, w, h, n, 1);\n for (let i = 0; i < data.length; i++) {\n if (n === 4 && (i & 3) === 3) continue;\n const v = data[i] + amount * (data[i] - soft[i]);\n data[i] = v > 0 ? v : 0;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Pixel sources\n// ---------------------------------------------------------------------------\n\n/** Pixels a retouching stroke samples, by document pixel. */\nexport interface PixelSource {\n /** Straight RGBA 0..255 of document pixel (x, y) into `out`; false (and `out` zeroed) where there is nothing. */\n sample(x: number, y: number, out: number[]): boolean;\n}\n\n/**\n * Photoshop's Clone Source transform: the cloned pixels appear scaled by `scaleX` / `scaleY`\n * (negative flips) and rotated by `rotate` degrees (clockwise) about the stroke's start.\n */\nexport interface CloneTransform {\n scaleX: number;\n scaleY: number;\n rotate: number;\n}\n\nexport const IDENTITY_CLONE_TRANSFORM: CloneTransform = { scaleX: 1, scaleY: 1, rotate: 0 };\n\nexport function isIdentityCloneTransform(t: CloneTransform): boolean {\n return t.scaleX === 1 && t.scaleY === 1 && ((t.rotate % 360) + 360) % 360 === 0;\n}\n\n/**\n * Where a clone samples for target point (`x`, `y`): `source + M⁻¹ · (p − anchor)`, with `M` the\n * transform (scale then rotate) and `anchor` the target point that maps onto the source point.\n */\nexport function cloneSamplePoint(t: CloneTransform, source: { x: number; y: number }, anchor: { x: number; y: number }, x: number, y: number): [number, number] {\n const a = (-t.rotate * Math.PI) / 180;\n const c = Math.cos(a);\n const s = Math.sin(a);\n const dx = x - anchor.x;\n const dy = y - anchor.y;\n return [source.x + (c * dx - s * dy) / t.scaleX, source.y + (s * dx + c * dy) / t.scaleY];\n}\n\n/** A source seen through a map from document points to source points (bilinear, premultiplied). */\nexport class TransformedPixelSource implements PixelSource {\n private readonly px = [0, 0, 0, 0];\n\n constructor(\n private readonly inner: PixelSource,\n private readonly map: (x: number, y: number) => [number, number]\n ) {}\n\n sample(x: number, y: number, out: number[]): boolean {\n const [u, v] = this.map(x, y);\n const x0 = Math.floor(u);\n const y0 = Math.floor(v);\n const fx = u - x0;\n const fy = v - y0;\n let r = 0;\n let g = 0;\n let b = 0;\n let a = 0;\n for (let k = 0; k < 4; k++) {\n const w = (k & 1 ? fx : 1 - fx) * (k & 2 ? fy : 1 - fy);\n if (w <= 0) continue;\n if (!this.inner.sample(x0 + (k & 1), y0 + (k >> 1), this.px)) continue;\n const pa = this.px[3] * w;\n r += this.px[0] * pa;\n g += this.px[1] * pa;\n b += this.px[2] * pa;\n a += pa;\n }\n if (!(a > 0)) {\n out[0] = out[1] = out[2] = out[3] = 0;\n return false;\n }\n out[0] = r / a;\n out[1] = g / a;\n out[2] = b / a;\n out[3] = a;\n return true;\n }\n}\n\n/**\n * A source over raster tiles (layer pixels, a mask, or composite tiles): `readTile` gives tile\n * (tx, ty) in source space or `null` when it is empty; source pixel = document pixel − `offset`.\n * One-channel tiles read as grey (alpha 255). Tiles are cached, so make one per stroke.\n */\nexport class TilePixelSource implements PixelSource {\n private readonly cache = new Map<number, PaintPixels | null>();\n private lastKey = NaN;\n private last: PaintPixels | null = null;\n\n constructor(\n /** A tile's bytes, or a float working tile on the same 0..255 scale (16 / 32 bits). */\n private readonly readTile: (tx: number, ty: number) => PaintPixels | null,\n readonly channels: 1 | 4,\n readonly offset: { x: number; y: number } = { x: 0, y: 0 }\n ) {}\n\n sample(x: number, y: number, out: number[]): boolean {\n const lx = x - this.offset.x;\n const ly = y - this.offset.y;\n const tx = Math.floor(lx / TILE);\n const ty = Math.floor(ly / TILE);\n const key = tileKey(tx, ty);\n if (key !== this.lastKey) {\n let t = this.cache.get(key);\n if (t === undefined) {\n t = this.readTile(tx, ty);\n this.cache.set(key, t);\n }\n this.last = t;\n this.lastKey = key;\n }\n const t = this.last;\n if (!t) {\n out[0] = out[1] = out[2] = out[3] = 0;\n return false;\n }\n const p = (ly - ty * TILE) * TILE + (lx - tx * TILE);\n if (this.channels === 1) {\n out[0] = out[1] = out[2] = t[p];\n out[3] = 255;\n return true;\n }\n const i = p * 4;\n out[0] = t[i];\n out[1] = t[i + 1];\n out[2] = t[i + 2];\n out[3] = t[i + 3];\n return out[3] > 0;\n }\n}\n\n/** A source over a region of float RGBA pixels (0..255), e.g. a healed patch. */\nexport class RegionPixelSource implements PixelSource {\n constructor(\n readonly rect: RasterRect,\n readonly data: Float32Array\n ) {}\n\n sample(x: number, y: number, out: number[]): boolean {\n const r = this.rect;\n const lx = x - r.x;\n const ly = y - r.y;\n if (lx < 0 || ly < 0 || lx >= r.width || ly >= r.height) {\n out[0] = out[1] = out[2] = out[3] = 0;\n return false;\n }\n const i = (ly * r.width + lx) * 4;\n out[0] = this.data[i];\n out[1] = this.data[i + 1];\n out[2] = this.data[i + 2];\n out[3] = this.data[i + 3];\n return out[3] > 0;\n }\n}\n\n/** `rect` of a source, shifted by (dx, dy), as float RGBA 0..255 (`rect.width × rect.height × 4`). */\nexport function readSourceRegion(source: PixelSource, rect: RasterRect, dx = 0, dy = 0): Float32Array {\n const out = new Float32Array(rect.width * rect.height * 4);\n const px = [0, 0, 0, 0];\n for (let y = 0; y < rect.height; y++) {\n for (let x = 0; x < rect.width; x++) {\n source.sample(rect.x + x + dx, rect.y + y + dy, px);\n const i = (y * rect.width + x) * 4;\n out[i] = px[0];\n out[i + 1] = px[1];\n out[i + 2] = px[2];\n out[i + 3] = px[3];\n }\n }\n return out;\n}\n\n// ---------------------------------------------------------------------------\n// Accumulate, then composite\n// ---------------------------------------------------------------------------\n\n/** What a coverage-based retouching stroke lays through its coverage. */\nexport type RetouchPaint =\n /** Source pixels at document pixel + (dx, dy) (Clone Stamp, a healed patch). */\n | { kind: 'source'; source: PixelSource; dx: number; dy: number }\n /** The target pixel itself, toned (Dodge, Burn): `tone` edits straight RGB 0..1 in place. */\n | { kind: 'tone'; tone: (rgb: number[]) => void }\n /** A flat colour (the Spot Healing Brush's trail while it is drawn), RGBA 0..255. */\n | { kind: 'color'; color: readonly [number, number, number, number] };\n\n/** How a coverage-based retouching stroke composites. */\nexport interface RetouchApply {\n /** Stroke opacity 0..1. */\n opacity: number;\n /** Blend mode for source paint (default normal). */\n blend?: BlendMode;\n lockTransparency: boolean;\n /** Selection coverage (document space, canvas-sized), or `null`. */\n selection: { width: number; height: number; data: ArrayLike<number> } | null;\n /** Layer offset (target pixels are in layer space). */\n offset: { x: number; y: number };\n}\n\n/**\n * Composites `paint` through the stroke's coverage over `tileData` (target tile (tx, ty) as it was\n * before the stroke, layer space; RGBA, or one byte per pixel for masks) and returns the new tile.\n * With `into` (the previous result) and `region` (document space), only `region` is recomputed.\n * Tone paint keeps alpha; source and colour paint composite with `blend` (source-over by\n * default), keeping alpha on a locked layer.\n */\nexport function applyRetouchToTile<T extends PaintPixels>(\n coverage: CoverageMap,\n tileData: T,\n channels: 1 | 4,\n tx: number,\n ty: number,\n paint: RetouchPaint,\n s: RetouchApply,\n options: { into?: T; region?: RasterRect } = {}\n): T {\n // A float working tile (16 / 32 bits) stays float and keeps fractions; bytes round as ever.\n const out = (options.into ?? tileData).slice() as T;\n const ox = tx * TILE + s.offset.x;\n const oy = ty * TILE + s.offset.y;\n let x0 = 0;\n let y0 = 0;\n let x1 = TILE;\n let y1 = TILE;\n if (options.region) {\n const r = options.region;\n x0 = Math.max(0, Math.floor(r.x) - ox);\n y0 = Math.max(0, Math.floor(r.y) - oy);\n x1 = Math.min(TILE, Math.ceil(r.x + r.width) - ox);\n y1 = Math.min(TILE, Math.ceil(r.y + r.height) - oy);\n if (x1 <= x0 || y1 <= y0) return out;\n if (options.into) {\n for (let y = y0; y < y1; y++) out.set(tileData.subarray((y * TILE + x0) * channels, (y * TILE + x1) * channels), (y * TILE + x0) * channels);\n }\n }\n const sel = s.selection;\n const blend = s.blend ?? 'normal';\n const src = [0, 0, 0, 0];\n const rgb = [0, 0, 0];\n const cb = [0, 0, 0, 0];\n const cs = [0, 0, 0, 0];\n // The coverage tile under the pixel, looked up once per tile it crosses.\n let covKey = NaN;\n let covTile: Float32Array | undefined;\n for (let y = y0; y < y1; y++) {\n const dy = oy + y;\n const cty = Math.floor(dy / TILE);\n for (let x = x0; x < x1; x++) {\n const dx = ox + x;\n const ctx = Math.floor(dx / TILE);\n const key = tileKey(ctx, cty);\n if (key !== covKey) {\n covKey = key;\n covTile = coverage.tiles.get(key);\n }\n if (!covTile) continue;\n const c = covTile[(dy - cty * TILE) * TILE + (dx - ctx * TILE)];\n if (c <= 0) continue;\n let k = c * s.opacity;\n if (sel) {\n if (dx < 0 || dy < 0 || dx >= sel.width || dy >= sel.height) continue;\n k *= sel.data[dy * sel.width + dx] / 255;\n }\n if (k > 1) k = 1;\n if (k <= 0) continue;\n const p = y * TILE + x;\n if (channels === 1) {\n // Masks: grey values; the source's grey is its red channel.\n const g = out[p];\n let t: number;\n if (paint.kind === 'tone') {\n rgb[0] = rgb[1] = rgb[2] = g / 255;\n paint.tone(rgb);\n t = luma(rgb[0], rgb[1], rgb[2]) * 255;\n } else if (paint.kind === 'color') t = paint.color[0];\n else {\n if (!paint.source.sample(dx + paint.dx, dy + paint.dy, src)) continue;\n t = src[0];\n k *= src[3] / 255;\n }\n out[p] = Math.round(g + (t - g) * k);\n continue;\n }\n const i = p * 4;\n const a = out[i + 3];\n if (paint.kind === 'tone') {\n if (a === 0) continue;\n rgb[0] = out[i] / 255;\n rgb[1] = out[i + 1] / 255;\n rgb[2] = out[i + 2] / 255;\n const r0 = rgb[0];\n const g0 = rgb[1];\n const b0 = rgb[2];\n paint.tone(rgb);\n put255(out, i, r0 + (rgb[0] - r0) * k);\n put255(out, i + 1, g0 + (rgb[1] - g0) * k);\n put255(out, i + 2, b0 + (rgb[2] - b0) * k);\n continue;\n }\n if (s.lockTransparency && a === 0) continue;\n if (paint.kind === 'color') {\n src[0] = paint.color[0];\n src[1] = paint.color[1];\n src[2] = paint.color[2];\n src[3] = paint.color[3];\n } else if (!paint.source.sample(dx + paint.dx, dy + paint.dy, src)) continue;\n for (let ch = 0; ch < 4; ch++) {\n cb[ch] = out[i + ch] / 255;\n cs[ch] = src[ch] / 255;\n }\n // Source-over, as a brush lays paint: cloning transparency paints nothing.\n const o = blendPixel(blend, cb, cs, k);\n put255(out, i, o[0]);\n put255(out, i + 1, o[1]);\n put255(out, i + 2, o[2]);\n if (!s.lockTransparency) put255(out, i + 3, o[3]);\n }\n }\n return out;\n}\n\n/**\n * Dodge / Burn at 16 or 32 bits: `applyRetouchToTile`'s tone paint on a layer tile's deep samples\n * (`Uint16Array` sRGB-encoded, or `Float32Array` linear light, RGBA). The tone curves work on\n * encoded values as at 8 bits, so 32-bit samples are encoded, toned and decoded (colour above 1 is\n * toned at 1 and keeps its excess). Returns the new samples.\n */\nexport function applyToneToDeepTile(\n coverage: CoverageMap,\n samples: Uint16Array | Float32Array,\n tx: number,\n ty: number,\n tone: (rgb: number[]) => void,\n s: RetouchApply,\n options: { into?: Uint16Array | Float32Array; region?: RasterRect } = {}\n): Uint16Array | Float32Array {\n const linear = samples instanceof Float32Array;\n const out = (options.into ?? samples).slice() as Uint16Array | Float32Array;\n const ox = tx * TILE + s.offset.x;\n const oy = ty * TILE + s.offset.y;\n let x0 = 0;\n let y0 = 0;\n let x1 = TILE;\n let y1 = TILE;\n if (options.region) {\n const r = options.region;\n x0 = Math.max(0, Math.floor(r.x) - ox);\n y0 = Math.max(0, Math.floor(r.y) - oy);\n x1 = Math.min(TILE, Math.ceil(r.x + r.width) - ox);\n y1 = Math.min(TILE, Math.ceil(r.y + r.height) - oy);\n if (x1 <= x0 || y1 <= y0) return out;\n if (options.into) for (let y = y0; y < y1; y++) out.set(samples.subarray((y * TILE + x0) * 4, (y * TILE + x1) * 4), (y * TILE + x0) * 4);\n }\n const sel = s.selection;\n const rgb = [0, 0, 0];\n const before = [0, 0, 0];\n const excess = [0, 0, 0];\n let covKey = NaN;\n let covTile: Float32Array | undefined;\n for (let y = y0; y < y1; y++) {\n const dy = oy + y;\n const cty = Math.floor(dy / TILE);\n for (let x = x0; x < x1; x++) {\n const dx = ox + x;\n const ctx = Math.floor(dx / TILE);\n const key = tileKey(ctx, cty);\n if (key !== covKey) {\n covKey = key;\n covTile = coverage.tiles.get(key);\n }\n if (!covTile) continue;\n const c = covTile[(dy - cty * TILE) * TILE + (dx - ctx * TILE)];\n if (c <= 0) continue;\n let k = c * s.opacity;\n if (sel) {\n if (dx < 0 || dy < 0 || dx >= sel.width || dy >= sel.height) continue;\n k *= sel.data[dy * sel.width + dx] / 255;\n }\n if (k > 1) k = 1;\n if (k <= 0) continue;\n const i = (y * TILE + x) * 4;\n if (out[i + 3] === 0) continue;\n for (let ch = 0; ch < 3; ch++) {\n const v = out[i + ch];\n if (linear) {\n excess[ch] = v > 1 ? v - 1 : 0;\n rgb[ch] = srgbEncode(v > 1 ? 1 : v < 0 ? 0 : v);\n } else rgb[ch] = v / 65535;\n before[ch] = rgb[ch];\n }\n tone(rgb);\n for (let ch = 0; ch < 3; ch++) {\n const e = before[ch] + (rgb[ch] - before[ch]) * k;\n if (linear) out[i + ch] = srgbDecode(e) + excess[ch];\n else out[i + ch] = e <= 0 ? 0 : e >= 1 ? 65535 : Math.round(e * 65535);\n }\n }\n }\n return out;\n}\n\n/** The tone function of a Dodge or Burn stroke. */\nexport function toneOf(tool: 'dodge' | 'burn', settings: Pick<RetouchSettings, 'exposure' | 'range' | 'protectTones'>): (rgb: number[]) => void {\n const burn = tool === 'burn';\n return (rgb) => {\n dodgeBurn(rgb, settings.exposure, settings.range, burn, settings.protectTones);\n };\n}\n\n// ---------------------------------------------------------------------------\n// Healing\n// ---------------------------------------------------------------------------\n\n/**\n * Heals `src` into `dst` over `mask` (all `w × h`, RGBA floats 0..255): a seamless clone solved\n * only over the mask's bounds plus a one-pixel fixed ring; elsewhere the result is `dst`.\n */\nexport function healPixels(w: number, h: number, src: Float32Array, dst: Float32Array, mask: ArrayLike<boolean | number>): Float32Array {\n const out = new Float32Array(dst);\n const bb = maskBounds(w, h, mask);\n if (!bb) return out;\n const x0 = Math.max(0, bb[0] - 1);\n const y0 = Math.max(0, bb[1] - 1);\n const x1 = Math.min(w, bb[2] + 1);\n const y1 = Math.min(h, bb[3] + 1);\n const rw = x1 - x0;\n const rh = y1 - y0;\n const s = new Float32Array(rw * rh * 4);\n const d = new Float32Array(rw * rh * 4);\n const m = new Uint8Array(rw * rh);\n for (let y = 0; y < rh; y++) {\n for (let x = 0; x < rw; x++) {\n const gi = (y + y0) * w + x + x0;\n const li = y * rw + x;\n m[li] = mask[gi] ? 1 : 0;\n for (let c = 0; c < 4; c++) {\n s[li * 4 + c] = src[gi * 4 + c];\n d[li * 4 + c] = dst[gi * 4 + c];\n }\n }\n }\n const healed = seamlessClone(rw, rh, 4, s, d, m);\n for (let y = 0; y < rh; y++) {\n for (let x = 0; x < rw; x++) {\n const gi = ((y + y0) * w + x + x0) * 4;\n const li = (y * rw + x) * 4;\n for (let c = 0; c < 4; c++) out[gi + c] = Math.min(255, Math.max(0, healed[li + c]));\n }\n }\n return out;\n}\n\n/**\n * Spot healing: fills `hole` (`w × h`) of `img` (RGBA floats 0..255) with no given source, then\n * heals the fill into its surroundings. `proximity-match` copies the best matching nearby patch\n * (falling back to `smooth` when none fits); `smooth` interpolates the edges inwards. `size` is\n * the brush diameter in pixels. Returns the healed pixels over the whole grid.\n */\nexport function spotHealPixels(\n w: number,\n h: number,\n img: Float32Array,\n hole: ArrayLike<boolean | number>,\n size: number,\n type: SpotHealType,\n /** Told the patch offset it copied (`null`: a smooth fill). */\n onOffset?: (offset: [number, number] | null) => void\n): Float32Array {\n // Fill a slightly larger domain than the healed area, so the solve's boundary sees filled values\n // that differ from the untouched pixels: that mismatch is what the membrane corrects.\n const domain = dilateMask(w, h, hole, 2);\n const healMask = dilateMask(w, h, hole, 1);\n let filled: Float32Array | null = null;\n let bestFound: [number, number] | null = null;\n if (type === 'proximity-match') {\n const ring = Math.min(16, Math.max(3, Math.floor(size / 8)));\n const off = bestOffset(w, h, 4, img, domain, ring, Math.floor(Math.max(w, h) / 2));\n if (off) {\n bestFound = off;\n // Copy from the pre-healing pixels, never from what this loop already wrote.\n filled = new Float32Array(img);\n const [ddx, ddy] = off;\n for (let i = 0; i < w * h; i++) {\n if (!domain[i]) continue;\n const x = (i % w) + ddx;\n const y = Math.floor(i / w) + ddy;\n const j = (y * w + x) * 4;\n for (let c = 0; c < 4; c++) filled[i * 4 + c] = img[j + c];\n }\n }\n }\n onOffset?.(filled ? (bestFound as [number, number]) : null);\n // Content-aware: texture and edges synthesised from patches all around (PatchMatch).\n if (!filled && type === 'content-aware') filled = contentAwareFill(w, h, 4, img, domain);\n if (!filled) filled = membraneFill(w, h, 4, img, domain);\n return healPixels(w, h, filled, img, healMask);\n}\n\n/** The window a Spot Healing stroke over `bounds` looks for texture in: the bounds grown by their size, on the canvas. */\nexport function spotHealWindow(bounds: RasterRect, canvas: { width: number; height: number }): RasterRect {\n const g = Math.max(8, Math.ceil(Math.max(bounds.width, bounds.height)));\n const x0 = Math.max(0, bounds.x - g);\n const y0 = Math.max(0, bounds.y - g);\n const x1 = Math.min(canvas.width, bounds.x + bounds.width + g);\n const y1 = Math.min(canvas.height, bounds.y + bounds.height + g);\n return { x: x0, y: y0, width: Math.max(0, x1 - x0), height: Math.max(0, y1 - y0) };\n}\n\n// ---------------------------------------------------------------------------\n// Sequential dabs\n// ---------------------------------------------------------------------------\n\n/**\n * One dab of a sequential retouching stroke: `cov` is the tip's pure coverage over `rect`\n * (document space, 0..1); `d.alpha` is the flow and `d.opacity` the pressure opacity.\n */\nexport type RetouchDabEffect = (medium: TileMedium, d: Dab, rect: RasterRect, cov: Float32Array) => void;\n\n/**\n * A stroke whose dabs edit live tiles in order (Smudge, Sponge). Feed points with `push` (any\n * chunks give the same dabs), end with `finish`; each returns the document rectangles it touched.\n */\nexport class RetouchDabStroke {\n dabCount = 0;\n bounds: RasterRect | null = null;\n private readonly walker: DabWalker;\n private readonly medium: TileMedium;\n private smoothPos: StrokePoint | null = null;\n private buf = new Float32Array(0);\n\n constructor(\n readonly brush: BrushSettings,\n target: PaintTileTarget,\n private readonly effect: RetouchDabEffect\n ) {\n this.walker = new DabWalker(brush);\n this.medium = new TileMedium(target);\n }\n\n push(points: readonly StrokePoint[]): RasterRect[] {\n const dabs: Dab[] = [];\n for (const p of points) this.walker.push(this.smooth(p), dabs);\n return this.paint(dabs);\n }\n\n finish(last?: StrokePoint): RasterRect[] {\n const dabs: Dab[] = [];\n if (last && this.smoothPos && (this.smoothPos.x !== last.x || this.smoothPos.y !== last.y)) this.walker.push(last, dabs);\n this.walker.finish(dabs);\n return this.paint(dabs);\n }\n\n private smooth(p: StrokePoint): StrokePoint {\n const a = 1 - Math.min(0.95, Math.max(0, this.brush.smoothing));\n const cur = this.smoothPos;\n const n = cur && a < 1 ? { ...p, x: cur.x + (p.x - cur.x) * a, y: cur.y + (p.y - cur.y) * a } : p;\n this.smoothPos = n;\n return n;\n }\n\n private paint(dabs: Dab[]): RasterRect[] {\n const rects: RasterRect[] = [];\n for (const d of dabs) {\n const rect = dabRect(d, this.brush.hardness);\n const n = rect.width * rect.height;\n if (this.buf.length < n) this.buf = new Float32Array(n);\n const cov = this.buf.subarray(0, n);\n rasterizeDab({ ...d, alpha: 1 }, this.brush.hardness, rect, cov);\n this.medium.reset();\n this.effect(this.medium, d, rect, cov);\n rects.push(rect);\n this.bounds = unionRect(this.bounds, rect);\n this.dabCount++;\n }\n return rects;\n }\n}\n\n/** The Smudge's per-dab effect: a `SmudgeTip` whose strength carries and lays the paint. */\nexport function smudgeEffect(brush: BrushSettings, strength: number, mixing: SmudgeSettings['mixing'] = 'rgb'): RetouchDabEffect {\n const s = Math.min(1, Math.max(0, strength));\n const tip = new SmudgeTip({ strength: s, length: s, mixing }, brush.size);\n return (medium, d, rect, cov) => tip.dab(medium, { x: d.x, y: d.y, radius: d.radius, opacity: d.opacity * d.alpha }, rect, cov);\n}\n\n/** The Sponge's per-dab effect: each dab moves saturation by about half its flow, compounding over passes. */\nexport function spongeEffect(brush: BrushSettings, saturate: boolean, vibrance: boolean): RetouchDabEffect {\n const rgb = [0, 0, 0];\n return (medium, d, rect, cov) => {\n const w = rect.width;\n for (let yy = 0; yy < rect.height; yy++) {\n for (let xx = 0; xx < w; xx++) {\n const cv = cov[yy * w + xx];\n if (cv <= 0) continue;\n const dx = rect.x + xx;\n const dy = rect.y + yy;\n const k = perDabStrength(cv * d.alpha * d.opacity * 0.5, brush.spacing) * medium.selectionAt(dx, dy);\n if (k <= 0) continue;\n const ri = medium.locate(dx, dy, false);\n if (ri < 0 || medium.pixels[ri + 3] === 0) continue;\n const i = medium.locate(dx, dy, true);\n const px = medium.pixels;\n rgb[0] = px[i] / 255;\n rgb[1] = px[i + 1] / 255;\n rgb[2] = px[i + 2] / 255;\n sponge(rgb, k, saturate, vibrance);\n put255(px, i, rgb[0]);\n put255(px, i + 1, rgb[1]);\n put255(px, i + 2, rgb[2]);\n }\n }\n };\n}\n\n/**\n * An RGBA view of one-channel tiles (masks), for the sequential-dab tools: reads expand grey to\n * opaque RGB, writes land in RGBA copies, and `flush` writes their red channel back through\n * `target.writeTile`. Alpha is locked, so a mask's values are all a dab changes.\n */\nexport function rgbaViewOfGrey(target: PaintTileTarget): { target: PaintTileTarget; flush(): void } {\n const views = new Map<number, Uint8ClampedArray>();\n const dirty = new Map<number, { tx: number; ty: number; data: Uint8ClampedArray }>();\n const expand = (g: Uint8ClampedArray) => {\n const out = new Uint8ClampedArray(g.length * 4);\n for (let i = 0; i < g.length; i++) {\n out[i * 4] = out[i * 4 + 1] = out[i * 4 + 2] = g[i];\n out[i * 4 + 3] = 255;\n }\n return out;\n };\n const view: PaintTileTarget = {\n offset: target.offset,\n lockTransparency: true,\n selection: target.selection,\n readTile: (tx, ty) => {\n const key = tileKey(tx, ty);\n let v = views.get(key);\n if (!v) {\n // An empty mask tile is still values (0), not transparency: always give a tile.\n v = expand((target.readTile(tx, ty) as Uint8ClampedArray | null) ?? new Uint8ClampedArray(TILE * TILE));\n views.set(key, v);\n }\n return v;\n },\n writeTile: (tx, ty) => {\n const key = tileKey(tx, ty);\n let v = views.get(key);\n if (!v) {\n v = expand((target.readTile(tx, ty) as Uint8ClampedArray | null) ?? new Uint8ClampedArray(TILE * TILE));\n views.set(key, v);\n }\n dirty.set(key, { tx, ty, data: v });\n return v;\n },\n };\n return {\n target: view,\n flush: () => {\n for (const { tx, ty, data } of dirty.values()) {\n const g = target.writeTile(tx, ty);\n for (let i = 0; i < g.length; i++) g[i] = data[i * 4];\n }\n dirty.clear();\n },\n };\n}\n\nfunction unionRect(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"],"mappings":";;;;;;;;;;;;;;;;;AAoBA,IAAM,MAAM;AAEZ,IAAM,aAAa;AACnB,IAAM,aAAa;AAOZ,SAAS,cAAc,GAAW,GAAW,SAAsC,GAAuB;AAC/G,MAAI,QAAQ,WAAW,IAAI,KAAK,EAAE,WAAW,IAAI,EAAG,OAAM,IAAI,WAAW,2BAA2B,IAAI,CAAC,eAAe,QAAQ,MAAM,QAAQ,EAAE,MAAM,GAAG;AACzJ,QAAM,IAAI,IAAI,WAAW,IAAI,CAAC;AAC9B,WAAS,IAAI,GAAG,IAAI,EAAE,QAAQ,IAAK,GAAE,CAAC,IAAI,QAAQ,CAAC,IAAI,IAAI;AAC3D,aAAW,GAAG,GAAG,GAAG,GAAG,CAAC;AAC1B;AAEA,SAAS,WAAW,GAAW,GAAW,SAAqB,GAAiB,OAAqB;AACnG,MAAI,WAAW;AACf,MAAI,WAAW;AACf,MAAI,SAAS;AACb,WAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AACvC,QAAI,QAAQ,CAAC,EAAG;AAAA,SACX;AACH,kBAAY,EAAE,CAAC;AACf;AAAA,IACF;AAAA,EACF;AACA,MAAI,aAAa,KAAK,WAAW,EAAG;AACpC,MAAI,KAAK,KAAK,KAAK,KAAK,WAAW,MAAM,QAAQ,IAAI;AAEnD,UAAM,KAAK,KAAK,KAAK,IAAI,CAAC;AAC1B,UAAM,MAAM,KAAK,KAAK,IAAI,CAAC;AAC3B,UAAM,KAAK,IAAI,WAAW,KAAK,GAAG,EAAE,KAAK,CAAC;AAC1C,UAAM,KAAK,IAAI,aAAa,KAAK,GAAG;AACpC,aAAS,KAAK,GAAG,KAAK,KAAK,MAAM;AAC/B,eAAS,KAAK,GAAG,KAAK,IAAI,MAAM;AAC9B,YAAI,IAAI;AACR,YAAI,IAAI;AACR,iBAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,gBAAM,IAAI,KAAK,KAAK,IAAI;AACxB,gBAAM,IAAI,KAAK,KAAK,KAAK;AACzB,cAAI,IAAI,KAAK,IAAI,KAAK,CAAC,QAAQ,IAAI,IAAI,CAAC,GAAG;AACzC,iBAAK,EAAE,IAAI,IAAI,CAAC;AAChB;AAAA,UACF;AAAA,QACF;AACA,YAAI,IAAI,GAAG;AACT,aAAG,KAAK,KAAK,EAAE,IAAI;AACnB,aAAG,KAAK,KAAK,EAAE,IAAI,IAAI;AAAA,QACzB;AAAA,MACF;AAAA,IACF;AACA,eAAW,IAAI,KAAK,IAAI,IAAI,QAAQ,CAAC;AAErC,aAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,YAAM,KAAK,KAAK,IAAI,MAAM,GAAG,KAAK,IAAI,IAAI,IAAI,OAAO,IAAI,GAAG,CAAC;AAC7D,YAAM,KAAK,KAAK,MAAM,EAAE;AACxB,YAAM,KAAK,KAAK,IAAI,MAAM,GAAG,KAAK,CAAC;AACnC,YAAM,KAAK,KAAK;AAChB,eAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,YAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,EAAG;AACzB,cAAM,KAAK,KAAK,IAAI,KAAK,GAAG,KAAK,IAAI,IAAI,IAAI,OAAO,IAAI,GAAG,CAAC;AAC5D,cAAM,KAAK,KAAK,MAAM,EAAE;AACxB,cAAM,KAAK,KAAK,IAAI,KAAK,GAAG,KAAK,CAAC;AAClC,cAAM,KAAK,KAAK;AAChB,cAAM,IAAI,GAAG,KAAK,KAAK,EAAE,KAAK,GAAG,KAAK,KAAK,EAAE,IAAI,GAAG,KAAK,KAAK,EAAE,KAAK;AACrE,cAAM,IAAI,GAAG,KAAK,KAAK,EAAE,KAAK,GAAG,KAAK,KAAK,EAAE,IAAI,GAAG,KAAK,KAAK,EAAE,KAAK;AACrE,UAAE,IAAI,IAAI,CAAC,IAAI,KAAK,IAAI,KAAK;AAAA,MAC/B;AAAA,IACF;AACA,QAAI,GAAG,GAAG,SAAS,GAAG,YAAY,UAAU;AAAA,EAC9C,OAAO;AACL,UAAM,OAAO,WAAW;AACxB,aAAS,IAAI,GAAG,IAAI,EAAE,QAAQ,IAAK,KAAI,QAAQ,CAAC,EAAG,GAAE,CAAC,IAAI;AAC1D,QAAI,GAAG,GAAG,SAAS,GAAG,KAAM,IAAI;AAAA,EAClC;AACF;AAGA,SAAS,IAAI,GAAW,GAAW,SAAqB,GAAiB,SAAiB,OAAqB;AAC7G,MAAI,IAAI;AACR,WAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,IAAK,KAAI,QAAQ,CAAC,EAAG;AACzD,QAAM,QAAQ,IAAI,YAAY,CAAC;AAC/B,QAAM,QAAQ,IAAI,WAAW,CAAC;AAC9B,WAAS,IAAI,GAAG,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AAC9C,QAAI,CAAC,QAAQ,CAAC,EAAG;AACjB,UAAM,IAAI,IAAI;AACd,UAAM,KAAK,IAAI,KAAK;AACpB,UAAM,CAAC,IAAI;AACX,UAAM,GAAG,KAAK,IAAI,IAAI,IAAI,MAAM,IAAI,IAAI,IAAI,IAAI,MAAM,IAAI,IAAI,IAAI,MAAM,IAAI,IAAI,IAAI,IAAI;AAAA,EAC1F;AACA,WAAS,KAAK,GAAG,KAAK,SAAS,MAAM;AACnC,QAAI,OAAO;AACX,aAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,YAAM,IAAI,MAAM,CAAC;AACjB,YAAM,IAAI,MAAM,CAAC;AACjB,UAAI;AACJ,UAAI;AACJ,UAAI,MAAM,IAAI;AACZ,YAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC;AAC5C,YAAI;AAAA,MACN,OAAO;AACL,YAAI;AACJ,YAAI;AACJ,YAAI,IAAI,EAAG,CAAC,KAAK,EAAE,IAAI,CAAC,GAAI;AAC5B,YAAI,IAAI,EAAG,CAAC,KAAK,EAAE,IAAI,CAAC,GAAI;AAC5B,YAAI,IAAI,EAAG,CAAC,KAAK,EAAE,IAAI,CAAC,GAAI;AAC5B,YAAI,IAAI,EAAG,CAAC,KAAK,EAAE,IAAI,CAAC,GAAI;AAC5B,YAAI,MAAM,EAAG;AAAA,MACf;AACA,YAAM,IAAI,SAAS,IAAI,IAAI,EAAE,CAAC;AAC9B,QAAE,CAAC,KAAK;AACR,YAAM,KAAK,IAAI,IAAI,CAAC,IAAI;AACxB,UAAI,KAAK,KAAM,QAAO;AAAA,IACxB;AACA,QAAI,OAAO,IAAK;AAAA,EAClB;AACF;AAQO,SAAS,cAAc,GAAW,GAAW,IAAY,KAAwB,KAAwB,MAAiD;AAC/J,QAAM,IAAI,IAAI;AACd,MAAI,IAAI,WAAW,IAAI,MAAM,IAAI,WAAW,IAAI,MAAM,KAAK,WAAW,EAAG,OAAM,IAAI,WAAW,8DAA2D;AACzJ,QAAM,MAAM,IAAI,aAAa,IAAI,EAAE;AACnC,QAAM,KAAK,IAAI,aAAa,CAAC;AAC7B,WAAS,IAAI,GAAG,IAAI,IAAI,KAAK;AAC3B,aAAS,IAAI,GAAG,IAAI,GAAG,IAAK,IAAG,CAAC,IAAI,KAAK,CAAC,IAAI,IAAI,IAAI,IAAI,KAAK,CAAC,IAAI,IAAI,IAAI,KAAK,CAAC;AAClF,kBAAc,GAAG,GAAG,MAAM,EAAE;AAC5B,aAAS,IAAI,GAAG,IAAI,GAAG,IAAK,KAAI,IAAI,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI,IAAI,IAAI,KAAK,CAAC,IAAI,GAAG,CAAC,IAAI,IAAI,IAAI,KAAK,CAAC;AAAA,EAClG;AACA,SAAO;AACT;AAGO,SAAS,aAAa,GAAW,GAAW,IAAY,KAAwB,MAAiD;AACtI,QAAM,IAAI,IAAI;AACd,QAAM,MAAM,IAAI,aAAa,IAAI,EAAE;AACnC,QAAM,IAAI,IAAI,aAAa,CAAC;AAC5B,WAAS,IAAI,GAAG,IAAI,IAAI,KAAK;AAC3B,aAAS,IAAI,GAAG,IAAI,GAAG,IAAK,GAAE,CAAC,IAAI,KAAK,CAAC,IAAI,IAAI,IAAI,IAAI,KAAK,CAAC;AAC/D,kBAAc,GAAG,GAAG,MAAM,CAAC;AAC3B,aAAS,IAAI,GAAG,IAAI,GAAG,IAAK,KAAI,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;AAAA,EACnD;AACA,SAAO;AACT;AAGO,SAAS,WAAW,GAAW,GAAW,MAAmC,GAAuB;AACzG,QAAM,MAAM,IAAI,WAAW,IAAI,CAAC;AAChC,WAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,aAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,UAAI,CAAC,KAAK,IAAI,IAAI,CAAC,EAAG;AACtB,eAAS,KAAK,KAAK,IAAI,GAAG,IAAI,CAAC,GAAG,MAAM,KAAK,IAAI,IAAI,GAAG,IAAI,CAAC,GAAG,KAAM,KAAI,IAAI,IAAI,EAAE,IAAI;AAAA,IAC1F;AAAA,EACF;AACA,QAAM,MAAM,IAAI,WAAW,IAAI,CAAC;AAChC,WAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,aAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,UAAI,CAAC,IAAI,IAAI,IAAI,CAAC,EAAG;AACrB,eAAS,KAAK,KAAK,IAAI,GAAG,IAAI,CAAC,GAAG,MAAM,KAAK,IAAI,IAAI,GAAG,IAAI,CAAC,GAAG,KAAM,KAAI,KAAK,IAAI,CAAC,IAAI;AAAA,IAC1F;AAAA,EACF;AACA,SAAO;AACT;AAGA,IAAM,eAAN,MAAmB;AAAA,EAEjB,YACmB,GACA,GACjB,MACA;AAHiB;AACA;AAGjB,UAAM,IAAI,IAAI;AACd,SAAK,IAAI,IAAI,YAAY,KAAK,IAAI,EAAE;AACpC,aAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,UAAI,MAAM;AACV,eAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,eAAO,KAAK,IAAI,IAAI,CAAC,IAAI,IAAI;AAC7B,aAAK,GAAG,IAAI,KAAK,IAAI,IAAI,CAAC,IAAI,KAAK,EAAE,IAAI,IAAI,IAAI,CAAC,IAAI;AAAA,MACxD;AAAA,IACF;AAAA,EACF;AAAA,EAbmB;AAAA,EACA;AAAA,EAHF;AAAA;AAAA,EAiBjB,MAAM,IAAY,IAAY,IAAY,IAAoB;AAC5D,UAAM,IAAI,KAAK,IAAI;AACnB,UAAM,IAAI,KAAK,IAAI,GAAG,KAAK,IAAI,KAAK,GAAG,EAAE,CAAC;AAC1C,UAAM,IAAI,KAAK,IAAI,GAAG,KAAK,IAAI,KAAK,GAAG,EAAE,CAAC;AAC1C,UAAM,IAAI,KAAK,IAAI,GAAG,KAAK,IAAI,KAAK,GAAG,EAAE,CAAC;AAC1C,UAAM,IAAI,KAAK,IAAI,GAAG,KAAK,IAAI,KAAK,GAAG,EAAE,CAAC;AAC1C,QAAI,KAAK,KAAK,KAAK,EAAG,QAAO;AAC7B,WAAO,KAAK,EAAE,IAAI,IAAI,CAAC,IAAI,KAAK,EAAE,IAAI,IAAI,CAAC,IAAI,KAAK,EAAE,IAAI,IAAI,CAAC,IAAI,KAAK,EAAE,IAAI,IAAI,CAAC;AAAA,EACrF;AACF;AAGO,SAAS,WAAW,GAAW,GAAW,MAA4E;AAC3H,MAAI,KAAK;AACT,MAAI,KAAK;AACT,MAAI,KAAK;AACT,MAAI,KAAK;AACT,WAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,aAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,UAAI,CAAC,KAAK,IAAI,IAAI,CAAC,EAAG;AACtB,UAAI,IAAI,GAAI,MAAK;AACjB,UAAI,IAAI,GAAI,MAAK;AACjB,UAAI,IAAI,GAAI,MAAK;AACjB,UAAI,IAAI,GAAI,MAAK;AAAA,IACnB;AAAA,EACF;AACA,SAAO,KAAK,IAAI,OAAO,CAAC,IAAI,IAAI,KAAK,GAAG,KAAK,CAAC;AAChD;AAQO,SAAS,WAAW,GAAW,GAAW,IAAY,KAAwB,MAAmC,MAAc,WAA4C;AAChL,QAAM,KAAK,WAAW,GAAG,GAAG,IAAI;AAChC,MAAI,CAAC,GAAI,QAAO;AAChB,QAAM,SAAS,KAAK,IAAI,GAAG,CAAC;AAC5B,QAAM,IAAI,KAAK,IAAI,GAAG,KAAK,IAAI,QAAQ,KAAK,MAAM,SAAS,CAAC,CAAC;AAC7D,MAAI,MAAM,EAAG,QAAO;AACpB,QAAM,KAAK,KAAK,IAAI,GAAG,KAAK,IAAI,QAAQ,KAAK,MAAM,IAAI,CAAC,CAAC;AACzD,QAAM,KAAK,IAAI,aAAa,GAAG,GAAG,IAAI;AACtC,QAAM,KAAK,GAAG,CAAC,IAAI;AACnB,QAAM,KAAK,GAAG,CAAC,IAAI;AACnB,QAAM,KAAK,GAAG,CAAC,IAAI;AACnB,QAAM,KAAK,GAAG,CAAC,IAAI;AAEnB,QAAM,MAAgB,CAAC;AACvB,WAAS,IAAI,KAAK,IAAI,GAAG,EAAE,GAAG,IAAI,KAAK,IAAI,GAAG,EAAE,GAAG,KAAK;AACtD,aAAS,IAAI,KAAK,IAAI,GAAG,EAAE,GAAG,IAAI,KAAK,IAAI,GAAG,EAAE,GAAG,KAAK;AACtD,UAAI,KAAK,IAAI,IAAI,CAAC,EAAG;AACrB,UAAI,GAAG,MAAM,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,GAAG,IAAI,KAAK,CAAC,IAAI,EAAG,KAAI,KAAK,GAAG,CAAC;AAAA,IACzE;AAAA,EACF;AACA,QAAM,SAAS,KAAK,IAAI,GAAG,KAAK,MAAM,IAAI,SAAS,IAAI,GAAI,CAAC;AAC5D,QAAM,KAAe,CAAC;AACtB,QAAM,KAAe,CAAC;AACtB,WAAS,IAAI,GAAG,IAAI,IAAI,QAAQ,KAAK,IAAI,QAAQ;AAC/C,OAAG,KAAK,IAAI,CAAC,CAAC;AACd,OAAG,KAAK,IAAI,IAAI,CAAC,CAAC;AAAA,EACpB;AACA,QAAM,IAAI,KAAK,IAAI,GAAG,GAAG,MAAM;AAC/B,QAAM,SAAS,CAAC,IAAY,IAAY,WAAkC;AACxE,QAAI,OAAO,KAAK,OAAO,EAAG,QAAO;AACjC,UAAM,MAAM,KAAK;AACjB,UAAM,MAAM,KAAK;AACjB,UAAM,MAAM,KAAK;AACjB,UAAM,MAAM,KAAK;AACjB,QAAI,MAAM,KAAK,MAAM,KAAK,MAAM,KAAK,MAAM,EAAG,QAAO;AACrD,QAAI,GAAG,MAAM,KAAK,KAAK,KAAK,GAAG,MAAM,EAAG,QAAO;AAC/C,UAAM,UAAU,IAAI,QAAQ,KAAK,MAAM,IAAI,EAAE,IAAI;AACjD,QAAI,IAAI;AACR,aAAS,IAAI,GAAG,IAAI,GAAG,QAAQ,KAAK;AAClC,YAAM,KAAK,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,KAAK;AAChC,YAAM,MAAM,GAAG,CAAC,IAAI,MAAM,IAAI,GAAG,CAAC,IAAI,MAAM;AAC5C,eAAS,IAAI,GAAG,IAAI,IAAI,KAAK;AAC3B,cAAM,IAAI,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC;AAChC,aAAK,IAAI;AAAA,MACX;AACA,WAAK,IAAI,QAAQ,MAAO,IAAI,IAAK,WAAW,OAAQ,QAAO;AAAA,IAC7D;AACA,WAAQ,IAAI,IAAK;AAAA,EACnB;AACA,QAAM,QAAsD,EAAE,MAAM,MAAM,GAAG,SAAS;AACtF,QAAM,WAAW,CAAC,IAAY,OAAe;AAC3C,UAAM,IAAI,OAAO,IAAI,IAAI,MAAM,CAAC;AAChC,QAAI,MAAM,QAAQ,IAAI,MAAM,GAAG;AAC7B,YAAM,IAAI;AACV,YAAM,OAAO,CAAC,IAAI,EAAE;AAAA,IACtB;AAAA,EACF;AAEA,QAAM,OAAO,KAAK,IAAI,GAAG,KAAK,MAAM,IAAI,EAAE,CAAC;AAC3C,WAAS,KAAK,CAAC,GAAG,MAAM,GAAG,MAAM,KAAM,UAAS,KAAK,CAAC,GAAG,MAAM,GAAG,MAAM,KAAM,UAAS,IAAI,EAAE;AAC7F,MAAI,OAAO,KAAK,MAAM,MAAM;AAC1B,UAAM,CAAC,IAAI,EAAE,IAAI,MAAM;AACvB,aAAS,KAAK,KAAK,MAAM,MAAM,KAAK,MAAM,KAAM,UAAS,KAAK,KAAK,MAAM,MAAM,KAAK,MAAM,KAAM,UAAS,IAAI,EAAE;AAAA,EACjH;AACA,SAAO,MAAM;AACf;AAMA,IAAM,UAAU;AAGhB,SAAS,IAAI,MAA4B;AACvC,MAAI,IAAI,SAAS;AACjB,SAAO,MAAM;AACX,QAAK,IAAI,eAAgB;AACzB,QAAI,IAAI;AACR,QAAI,KAAK,KAAK,IAAK,MAAM,IAAK,IAAI,CAAC;AACnC,SAAK,IAAI,KAAK,KAAK,IAAK,MAAM,GAAI,IAAI,EAAE;AACxC,aAAS,IAAK,MAAM,QAAS,KAAK;AAAA,EACpC;AACF;AAUA,SAAS,WAAW,GAAU,IAAmB;AAC/C,QAAM,IAAI,KAAK,IAAI,GAAG,EAAE,KAAK,CAAC;AAC9B,QAAM,IAAI,KAAK,IAAI,GAAG,EAAE,KAAK,CAAC;AAC9B,QAAM,MAAM,IAAI,aAAa,IAAI,IAAI,EAAE;AACvC,QAAM,OAAO,IAAI,WAAW,IAAI,CAAC;AACjC,WAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,aAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,UAAI,IAAI;AACR,YAAM,KAAK,IAAI,IAAI,KAAK;AACxB,eAAS,KAAK,GAAG,KAAK,GAAG,MAAM;AAC7B,iBAAS,KAAK,GAAG,KAAK,GAAG,MAAM;AAC7B,gBAAM,KAAK,KAAK,IAAI,EAAE,IAAI,GAAG,IAAI,IAAI,EAAE;AACvC,gBAAM,KAAK,KAAK,IAAI,EAAE,IAAI,GAAG,IAAI,IAAI,EAAE;AACvC,gBAAM,IAAI,KAAK,EAAE,IAAI;AACrB,cAAI,EAAE,KAAK,CAAC,GAAG;AACb,iBAAK,IAAI,IAAI,CAAC,IAAI;AAClB;AAAA,UACF;AACA,mBAAS,IAAI,GAAG,IAAI,IAAI,IAAK,KAAI,IAAI,CAAC,KAAK,EAAE,IAAI,IAAI,KAAK,CAAC;AAC3D;AAAA,QACF;AAAA,MACF;AACA,UAAI,EAAG,UAAS,IAAI,GAAG,IAAI,IAAI,IAAK,KAAI,IAAI,CAAC,KAAK;AAAA,IACpD;AAAA,EACF;AACA,SAAO,EAAE,GAAG,GAAG,KAAK,KAAK;AAC3B;AASO,SAAS,iBAAiB,GAAW,GAAW,IAAY,KAAwB,MAAmC,UAAkD,CAAC,GAAiB;AAChM,QAAM,QAAQ,QAAQ,cAAc;AACpC,QAAM,OAAc,EAAE,GAAG,GAAG,KAAK,aAAa,KAAK,GAAG,GAAG,MAAM,WAAW,KAAK,MAA2B,CAAC,MAAO,IAAI,IAAI,CAAE,EAAE;AAC9H,QAAM,SAAkB,CAAC,IAAI;AAE7B,SAAO,OAAO,SAAS,GAAG;AACxB,UAAM,MAAM,OAAO,OAAO,SAAS,CAAC;AACpC,UAAM,IAAI,WAAW,IAAI,GAAG,IAAI,GAAG,IAAI,IAAI;AAC3C,QAAI,CAAC,KAAK,KAAK,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,IAAI,WAAW,IAAI,IAAI,IAAI,WAAW,IAAI,IAAI,IAAI,QAAS;AAC1G,WAAO,KAAK,WAAW,KAAK,EAAE,CAAC;AAAA,EACjC;AACA,QAAM,SAAS,IAAI,QAAQ,QAAQ,IAAI,WAAW,IAAI,QAAQ;AAC9D,MAAI,WAAgC;AACpC,MAAI,UAA6B;AACjC,MAAI,QAAQ;AACZ,WAAS,KAAK,OAAO,SAAS,GAAG,MAAM,GAAG,MAAM;AAC9C,UAAM,EAAE,GAAG,GAAG,GAAG,GAAG,MAAM,MAAM,IAAI,OAAO,EAAE;AAC7C,UAAM,MAAM,IAAI,aAAa,OAAO,EAAE,EAAE,GAAG;AAE3C,QAAI,UAAU;AACZ,eAAS,IAAI,GAAG,IAAI,IAAI,GAAG,KAAK;AAC9B,YAAI,CAAC,MAAM,CAAC,EAAG;AACf,cAAM,IAAI,KAAK,IAAI,QAAQ,GAAI,IAAI,KAAM,CAAC;AAC1C,cAAM,IAAI,KAAK,IAAI,KAAK,MAAM,SAAS,SAAS,KAAK,KAAK,IAAI,GAAG,KAAK,MAAM,IAAI,CAAC,KAAK,CAAC;AACvF,iBAAS,IAAI,GAAG,IAAI,IAAI,IAAK,KAAI,IAAI,KAAK,CAAC,IAAI,UAAU,IAAI,QAAQ,KAAK,KAAK,CAAC;AAAA,MAClF;AAAA,IACF,MAAO,KAAI,IAAI,aAAa,GAAG,GAAG,IAAI,KAAK,KAAK,CAAC;AAEjD,UAAM,UAAU,WAAW,GAAG,GAAG,OAAO,OAAO;AAC/C,UAAM,QAAkB,CAAC;AACzB,aAAS,IAAI,SAAS,IAAI,IAAI,SAAS,IAAK,UAAS,IAAI,SAAS,IAAI,IAAI,SAAS,IAAK,KAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,EAAG,OAAM,KAAK,IAAI,IAAI,CAAC;AACrI,QAAI,CAAC,MAAM,QAAQ;AACjB,iBAAW;AACX,gBAAU;AACV,cAAQ;AACR;AAAA,IACF;AAEA,UAAM,UAAoB,CAAC;AAC3B,aAAS,IAAI,GAAG,IAAI,GAAG,IAAK,UAAS,IAAI,GAAG,IAAI,GAAG,IAAK,KAAI,QAAQ,IAAI,IAAI,CAAC,EAAG,SAAQ,KAAK,IAAI,IAAI,CAAC;AACtG,UAAM,MAAM,IAAI,WAAW,IAAI,CAAC,EAAE,KAAK,EAAE;AACzC,UAAM,OAAO,IAAI,aAAa,IAAI,CAAC;AACnC,UAAM,SAAS,CAAC,GAAW,MAAc,KAAK,IAAI,IAAI,IAAI,SAAS,KAAK,IAAI,SAAS,CAAC,CAAC;AACvF,UAAM,OAAO,CAAC,GAAW,GAAW,UAAkB;AACpD,YAAM,KAAK,OAAO,IAAI,GAAG,CAAC;AAC1B,YAAM,KAAK,OAAO,KAAK,MAAM,IAAI,CAAC,GAAG,CAAC;AACtC,YAAM,KAAK,IAAI;AACf,YAAM,KAAK,KAAK,MAAM,IAAI,CAAC;AAC3B,UAAI,IAAI;AACR,eAAS,KAAK,CAAC,SAAS,MAAM,SAAS,MAAM;AAC3C,cAAM,MAAM,KAAK,MAAM;AACvB,cAAM,MAAM,KAAK,MAAM;AACvB,iBAAS,KAAK,CAAC,SAAS,MAAM,SAAS,MAAM;AAC3C,gBAAM,KAAK,KAAK,KAAK,MAAM;AAC3B,gBAAM,KAAK,KAAK,KAAK,MAAM;AAC3B,mBAAS,IAAI,GAAG,IAAI,IAAI,KAAK;AAC3B,kBAAM,IAAI,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC;AAChC,iBAAK,IAAI;AAAA,UACX;AAAA,QACF;AACA,YAAI,KAAK,MAAO,QAAO;AAAA,MACzB;AACA,aAAO;AAAA,IACT;AACA,UAAM,UAAU,CAAC,MAAc;AAC7B,YAAM,IAAI,IAAI;AACd,YAAM,IAAI,KAAK,MAAM,IAAI,CAAC;AAC1B,aAAO,KAAK,KAAK,KAAK,WAAW,KAAK,WAAW,IAAI,IAAI,WAAW,IAAI,IAAI,WAAW,CAAC,QAAQ,CAAC;AAAA,IACnG;AACA,eAAW,KAAK,SAAS;AACvB,UAAI,IAAI;AACR,UAAI,SAAS;AACX,cAAM,KAAK,KAAK,IAAI,QAAQ,GAAI,IAAI,KAAM,CAAC;AAC3C,cAAM,KAAK,KAAK,MAAM,IAAI,CAAC,KAAK;AAChC,cAAM,KAAK,QAAQ,KAAK,QAAQ,EAAE;AAClC,YAAI,MAAM,GAAG;AACX,gBAAM,QAAQ,KAAK,MAAM,KAAK,KAAK,IAAI,KAAK,KAAK,MAAM,IAAI,CAAC,IAAI,MAAM,IAAK,KAAK,QAAS,KAAM,IAAI,IAAK;AACxG,cAAI,QAAQ,IAAI,EAAG,KAAI;AAAA,QACzB;AAAA,MACF;AACA,UAAI,IAAI,EAAG,KAAI,MAAM,KAAK,MAAM,OAAO,IAAI,MAAM,MAAM,CAAC;AACxD,UAAI,CAAC,IAAI;AAAA,IACX;AACA,aAAS,KAAK,GAAG,KAAK,OAAO,MAAM;AACjC,iBAAW,KAAK,QAAS,MAAK,CAAC,IAAI,KAAK,GAAG,IAAI,CAAC,GAAG,QAAQ;AAC3D,eAAS,OAAO,GAAG,OAAO,GAAG,QAAQ;AACnC,cAAM,MAAM,OAAO,MAAM;AACzB,cAAM,OAAO,MAAM,IAAI;AACvB,iBAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AACvC,gBAAM,IAAI,QAAQ,MAAM,IAAI,QAAQ,SAAS,IAAI,CAAC;AAClD,gBAAM,KAAK,IAAI;AACf,gBAAM,KAAK,KAAK,MAAM,IAAI,CAAC;AAE3B,qBAAW,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,KAAK,MAAM,EAAE,GAAG,CAAC,IAAI,KAAK,IAAI,CAAC,GAAG;AACzD,gBAAI,KAAK,KAAK,KAAK,KAAK,MAAM,KAAK,MAAM,EAAG;AAC5C,kBAAM,KAAK,IAAI,KAAK,IAAI,EAAE;AAC1B,gBAAI,KAAK,EAAG;AACZ,kBAAM,OAAO,KAAK,QAAQ,OAAO,KAAK,IAAI;AAC1C,gBAAI,CAAC,QAAQ,IAAI,KAAK,SAAS,IAAI,CAAC,EAAG;AACvC,kBAAM,IAAI,KAAK,GAAG,MAAM,KAAK,CAAC,CAAC;AAC/B,gBAAI,IAAI,KAAK,CAAC,GAAG;AACf,mBAAK,CAAC,IAAI;AACV,kBAAI,CAAC,IAAI;AAAA,YACX;AAAA,UACF;AAEA,gBAAM,KAAK,IAAI,CAAC,IAAI;AACpB,gBAAM,KAAK,KAAK,MAAM,IAAI,CAAC,IAAI,CAAC;AAChC,mBAAS,IAAI,KAAK,IAAI,GAAG,CAAC,GAAG,KAAK,GAAG,MAAM,GAAG;AAC5C,kBAAM,KAAK,KAAK,MAAM,MAAM,OAAO,IAAI,IAAI,KAAK,CAAC;AACjD,kBAAM,KAAK,KAAK,MAAM,MAAM,OAAO,IAAI,IAAI,KAAK,CAAC;AACjD,kBAAM,OAAO,KAAK,IAAI;AACtB,gBAAI,KAAK,KAAK,KAAK,KAAK,MAAM,KAAK,MAAM,KAAK,CAAC,QAAQ,IAAI,EAAG;AAC9D,kBAAM,IAAI,KAAK,GAAG,MAAM,KAAK,CAAC,CAAC;AAC/B,gBAAI,IAAI,KAAK,CAAC,GAAG;AACf,mBAAK,CAAC,IAAI;AACV,kBAAI,CAAC,IAAI;AAAA,YACX;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAEA,YAAM,MAAM,IAAI,aAAa,IAAI,IAAI,EAAE;AACvC,YAAM,OAAO,IAAI,aAAa,IAAI,CAAC;AACnC,iBAAW,KAAK,SAAS;AACvB,cAAM,KAAK,OAAO,IAAI,GAAG,CAAC;AAC1B,cAAM,KAAK,OAAO,KAAK,MAAM,IAAI,CAAC,GAAG,CAAC;AACtC,cAAM,IAAI,IAAI,CAAC;AACf,cAAM,KAAK,IAAI;AACf,cAAM,KAAK,KAAK,MAAM,IAAI,CAAC;AAC3B,iBAAS,KAAK,CAAC,SAAS,MAAM,SAAS,MAAM;AAC3C,mBAAS,KAAK,CAAC,SAAS,MAAM,SAAS,MAAM;AAC3C,kBAAM,KAAK,KAAK,MAAM,IAAI,KAAK;AAC/B,gBAAI,CAAC,MAAM,CAAC,EAAG;AACf,kBAAM,QAAQ,KAAK,MAAM,IAAI,KAAK,MAAM;AACxC,qBAAS,IAAI,GAAG,IAAI,IAAI,IAAK,KAAI,IAAI,KAAK,CAAC,KAAK,IAAI,MAAM,CAAC;AAC3D,iBAAK,CAAC,KAAK;AAAA,UACb;AAAA,QACF;AAAA,MACF;AACA,eAAS,IAAI,GAAG,IAAI,IAAI,GAAG,IAAK,KAAI,MAAM,CAAC,KAAK,KAAK,CAAC,IAAI,EAAG,UAAS,IAAI,GAAG,IAAI,IAAI,IAAK,KAAI,IAAI,KAAK,CAAC,IAAI,IAAI,IAAI,KAAK,CAAC,IAAI,KAAK,CAAC;AAAA,IACtI;AACA,eAAW;AACX,cAAU;AACV,YAAQ;AAAA,EACV;AACA,QAAM,MAAM,aAAa,KAAK,GAAG;AACjC,WAAS,IAAI,GAAG,IAAI,IAAI,GAAG,IAAK,KAAI,KAAK,KAAK,CAAC,EAAG,UAAS,IAAI,GAAG,IAAI,IAAI,IAAK,KAAI,IAAI,KAAK,CAAC,IAAI,SAAU,IAAI,KAAK,CAAC;AACrH,SAAO;AACT;;;ACneO,IAAM,cAAoC,CAAC,WAAW,YAAY,YAAY;AAG9E,SAAS,KAAK,GAAW,GAAW,GAAmB;AAC5D,SAAO,QAAQ,IAAI,QAAQ,IAAI,QAAQ;AACzC;AAGO,SAAS,eAAe,GAAW,GAAW,OAAkB,MAAuB;AAC5F,QAAM,IAAI,KAAK,IAAI,GAAG,CAAC;AACvB,QAAM,IAAI,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,CAAC,CAAC;AACpC,QAAM,IAAI,KAAK,IAAI,GAAG,CAAC;AACvB,MAAI,UAAU,YAAY;AAExB,UAAMA,KAAI,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,IAAI,KAAK,IAAI,EAAE,CAAC;AAClD,WAAO,IAAIA,MAAK,KAAK,IAAI,GAAG,OAAO,IAAI,IAAI,KAAK,IAAI,EAAE,IAAI;AAAA,EAC5D;AAEA,QAAM,IAAI,UAAU,aAAa,IAAI,MAAM,IAAI,KAAK,IAAI;AACxD,SAAO,OAAO,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI;AACjD;AAGA,SAAS,cAAc,GAAa,GAAiB;AACnD,QAAM,IAAI,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,CAAC,CAAC;AACpC,QAAM,KAAK,KAAK,IAAI,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC;AACpC,QAAM,KAAK,KAAK,IAAI,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC;AACpC,MAAI,IAAI;AACR,MAAI,KAAK,KAAK,KAAK,IAAI,KAAM,KAAI,KAAK,IAAI,IAAI,IAAI,MAAM,KAAK,EAAE;AAC/D,MAAI,KAAK,KAAK,IAAI,KAAK,KAAM,KAAI,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG;AACzD,WAAS,IAAI,GAAG,IAAI,GAAG,IAAK,GAAE,CAAC,IAAI,KAAK,EAAE,CAAC,IAAI,KAAK;AACtD;AAOO,SAAS,UAAU,GAAa,GAAW,OAAkB,MAAe,cAAiC;AAClH,MAAI,EAAE,IAAI,GAAI,QAAO;AACrB,MAAI,cAAc;AAChB,UAAM,IAAI,KAAK,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC;AAC/B,UAAM,KAAK,eAAe,GAAG,GAAG,OAAO,IAAI;AAC3C,QAAI,IAAI,KAAM,UAAS,IAAI,GAAG,IAAI,GAAG,IAAK,GAAE,CAAC,KAAK,KAAK;AAAA,QAClD,GAAE,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI;AAC1B,kBAAc,GAAG,EAAE;AAAA,EACrB,MAAO,UAAS,IAAI,GAAG,IAAI,GAAG,IAAK,GAAE,CAAC,IAAI,eAAe,EAAE,CAAC,GAAG,GAAG,OAAO,IAAI;AAC7E,SAAO;AACT;AAGO,SAAS,aAAa,GAAW,GAAW,GAAmB;AACpE,QAAM,KAAK,KAAK,IAAI,GAAG,GAAG,CAAC;AAC3B,QAAM,KAAK,KAAK,IAAI,GAAG,GAAG,CAAC;AAC3B,SAAO,MAAM,OAAO,IAAI,KAAK,IAAI,GAAG,KAAK,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;AACjE;AAOO,SAAS,OAAO,GAAa,QAAgB,UAAmB,UAA6B;AAClG,MAAI,IAAI,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,MAAM,CAAC;AACvC,MAAI,EAAE,IAAI,GAAI,QAAO;AACrB,MAAI,UAAU;AACZ,UAAM,IAAI,aAAa,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC;AACvC,SAAK,WAAW,IAAI,IAAI,OAAO,OAAO;AAAA,EACxC;AACA,QAAM,IAAI,KAAK,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC;AAC/B,QAAM,IAAI,WAAW,IAAI,IAAI,IAAI;AACjC,WAAS,IAAI,GAAG,IAAI,GAAG,IAAK,GAAE,CAAC,IAAI,KAAK,EAAE,CAAC,IAAI,KAAK;AACpD,gBAAc,GAAG,CAAC;AAClB,SAAO;AACT;AAGO,SAAS,eAAe,GAAW,SAAyB;AACjE,SAAO,IAAI,KAAK,IAAI,IAAI,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,CAAC,CAAC,GAAG,KAAK,IAAI,GAAG,KAAK,IAAI,MAAM,OAAO,CAAC,CAAC;AAC3F;AASO,IAAM,kBAA4C,CAAC,WAAW,iBAAiB,KAAK;AAKpF,IAAM,kBAA2C,CAAC,mBAAmB,iBAAiB,QAAQ;AA0B9F,IAAM,kBAA6C;AAAA,EACxD,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,UAAU;AAAA,EACV,OAAO;AAAA,EACP,UAAU;AAAA,EACV,cAAc;AAAA,EACd,YAAY;AAAA,EACZ,UAAU;AAAA,EACV,UAAU;AAAA,EACV,cAAc;AAChB;AAGO,SAAS,iBAAiB,MAAgC,CAAC,GAAG,OAAwB,iBAAkC;AAC7H,QAAM,OAAO,CAAC,GAAY,MAAe,OAAO,MAAM,YAAY,OAAO,SAAS,CAAC,IAAI,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,CAAC,CAAC,IAAI;AACrH,QAAM,OAAO,CAAC,GAAY,MAAgB,OAAO,MAAM,YAAY,IAAI;AACvE,QAAM,OAAO,CAAmB,GAAY,KAAmB,MAAa,IAAI,SAAS,CAAM,IAAK,IAAU;AAC9G,SAAO;AAAA,IACL,SAAS,KAAK,IAAI,SAAS,KAAK,OAAO;AAAA,IACvC,QAAQ,KAAK,IAAI,QAAQ,iBAAiB,KAAK,MAAM;AAAA,IACrD,UAAU,KAAK,IAAI,UAAU,iBAAiB,KAAK,QAAQ;AAAA,IAC3D,OAAO,KAAK,IAAI,OAAO,aAAa,KAAK,KAAK;AAAA,IAC9C,UAAU,KAAK,IAAI,UAAU,KAAK,QAAQ;AAAA,IAC1C,cAAc,KAAK,IAAI,cAAc,KAAK,YAAY;AAAA,IACtD,YAAY,KAAK,IAAI,YAAY,CAAC,cAAc,UAAU,GAAY,KAAK,UAAU;AAAA,IACrF,UAAU,KAAK,IAAI,UAAU,KAAK,QAAQ;AAAA,IAC1C,UAAU,KAAK,IAAI,UAAU,KAAK,QAAQ;AAAA,IAC1C,cAAc,OAAO,IAAI,iBAAiB,YAAY,OAAO,SAAS,IAAI,YAAY,IAAI,KAAK,IAAI,KAAM,KAAK,IAAI,GAAG,KAAK,MAAM,IAAI,YAAY,CAAC,CAAC,IAAI,KAAK;AAAA,EAC7J;AACF;AAMO,SAAS,cAAc,MAAoB,GAAW,GAAW,GAAU,GAAiB;AACjG,MAAI,IAAI,EAAG;AACX,MAAI,MAAM,EAAG,UAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK,EAAG,UAAS,IAAI,GAAG,IAAI,GAAG,IAAK,MAAK,IAAI,CAAC,KAAK,KAAK,IAAI,CAAC,IAAI;AAC/G,QAAM,MAAM,IAAI,aAAa,KAAK,MAAM;AACxC,QAAM,IAAI,KAAK,IAAI,IAAI;AACvB,WAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,aAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,eAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,YAAI,IAAI;AACR,iBAAS,IAAI,CAAC,GAAG,KAAK,GAAG,IAAK,MAAK,MAAM,IAAI,IAAI,KAAK,IAAI,IAAI,GAAG,KAAK,IAAI,GAAG,IAAI,CAAC,CAAC,KAAK,IAAI,CAAC;AAC7F,aAAK,IAAI,IAAI,KAAK,IAAI,CAAC,IAAI,IAAI;AAAA,MACjC;AAAA,IACF;AAAA,EACF;AACA,WAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,aAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,eAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,YAAI,IAAI;AACR,iBAAS,IAAI,CAAC,GAAG,KAAK,GAAG,IAAK,MAAK,KAAK,KAAK,IAAI,IAAI,GAAG,KAAK,IAAI,GAAG,IAAI,CAAC,CAAC,IAAI,IAAI,KAAK,IAAI,CAAC;AAC5F,cAAM,IAAI,IAAI,KAAK,IAAI,CAAC,IAAI,IAAI;AAAA,MAClC;AAAA,IACF;AAAA,EACF;AACA,MAAI,MAAM,GAAG;AACX,aAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK,GAAG;AACvC,YAAM,IAAI,KAAK,IAAI,CAAC,IAAI;AACxB,eAAS,IAAI,GAAG,IAAI,GAAG,IAAK,MAAK,IAAI,CAAC,IAAI,IAAI,IAAI,KAAK,IAAI,CAAC,IAAI,IAAI;AAAA,IACtE;AAAA,EACF;AACF;AAOO,SAAS,cAAc,MAAoB,GAAW,GAAW,GAAU,MAA0B,SAAS,GAAG,SAAS,GAAS;AACxI,MAAI,SAAS,QAAQ;AACnB,kBAAc,MAAM,GAAG,GAAG,GAAG,MAAM;AACnC,kBAAc,MAAM,GAAG,GAAG,GAAG,MAAM;AACnC;AAAA,EACF;AACA,QAAM,OAAO,KAAK,MAAM;AACxB,gBAAc,MAAM,GAAG,GAAG,GAAG,CAAC;AAC9B,WAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,QAAI,MAAM,MAAM,IAAI,OAAO,EAAG;AAC9B,UAAM,IAAI,KAAK,CAAC,IAAI,UAAU,KAAK,CAAC,IAAI,KAAK,CAAC;AAC9C,SAAK,CAAC,IAAI,IAAI,IAAI,IAAI;AAAA,EACxB;AACF;AAsBO,IAAM,2BAA2C,EAAE,QAAQ,GAAG,QAAQ,GAAG,QAAQ,EAAE;AAEnF,SAAS,yBAAyB,GAA4B;AACnE,SAAO,EAAE,WAAW,KAAK,EAAE,WAAW,MAAO,EAAE,SAAS,MAAO,OAAO,QAAQ;AAChF;AAMO,SAAS,iBAAiB,GAAmB,QAAkC,QAAkC,GAAW,GAA6B;AAC9J,QAAM,IAAK,CAAC,EAAE,SAAS,KAAK,KAAM;AAClC,QAAM,IAAI,KAAK,IAAI,CAAC;AACpB,QAAM,IAAI,KAAK,IAAI,CAAC;AACpB,QAAM,KAAK,IAAI,OAAO;AACtB,QAAM,KAAK,IAAI,OAAO;AACtB,SAAO,CAAC,OAAO,KAAK,IAAI,KAAK,IAAI,MAAM,EAAE,QAAQ,OAAO,KAAK,IAAI,KAAK,IAAI,MAAM,EAAE,MAAM;AAC1F;AAGO,IAAM,yBAAN,MAAoD;AAAA,EAGzD,YACmB,OACA,KACjB;AAFiB;AACA;AAAA,EAChB;AAAA,EAFgB;AAAA,EACA;AAAA,EAJF,KAAK,CAAC,GAAG,GAAG,GAAG,CAAC;AAAA,EAOjC,OAAO,GAAW,GAAW,KAAwB;AACnD,UAAM,CAAC,GAAG,CAAC,IAAI,KAAK,IAAI,GAAG,CAAC;AAC5B,UAAM,KAAK,KAAK,MAAM,CAAC;AACvB,UAAM,KAAK,KAAK,MAAM,CAAC;AACvB,UAAM,KAAK,IAAI;AACf,UAAM,KAAK,IAAI;AACf,QAAI,IAAI;AACR,QAAI,IAAI;AACR,QAAI,IAAI;AACR,QAAI,IAAI;AACR,aAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,YAAM,KAAK,IAAI,IAAI,KAAK,IAAI,OAAO,IAAI,IAAI,KAAK,IAAI;AACpD,UAAI,KAAK,EAAG;AACZ,UAAI,CAAC,KAAK,MAAM,OAAO,MAAM,IAAI,IAAI,MAAM,KAAK,IAAI,KAAK,EAAE,EAAG;AAC9D,YAAM,KAAK,KAAK,GAAG,CAAC,IAAI;AACxB,WAAK,KAAK,GAAG,CAAC,IAAI;AAClB,WAAK,KAAK,GAAG,CAAC,IAAI;AAClB,WAAK,KAAK,GAAG,CAAC,IAAI;AAClB,WAAK;AAAA,IACP;AACA,QAAI,EAAE,IAAI,IAAI;AACZ,UAAI,CAAC,IAAI,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI;AACpC,aAAO;AAAA,IACT;AACA,QAAI,CAAC,IAAI,IAAI;AACb,QAAI,CAAC,IAAI,IAAI;AACb,QAAI,CAAC,IAAI,IAAI;AACb,QAAI,CAAC,IAAI;AACT,WAAO;AAAA,EACT;AACF;AAOO,IAAM,kBAAN,MAA6C;AAAA,EAKlD,YAEmB,UACR,UACA,SAAmC,EAAE,GAAG,GAAG,GAAG,EAAE,GACzD;AAHiB;AACR;AACA;AAAA,EACR;AAAA,EAHgB;AAAA,EACR;AAAA,EACA;AAAA,EARM,QAAQ,oBAAI,IAAgC;AAAA,EACrD,UAAU;AAAA,EACV,OAA2B;AAAA,EASnC,OAAO,GAAW,GAAW,KAAwB;AACnD,UAAM,KAAK,IAAI,KAAK,OAAO;AAC3B,UAAM,KAAK,IAAI,KAAK,OAAO;AAC3B,UAAM,KAAK,KAAK,MAAM,KAAK,IAAI;AAC/B,UAAM,KAAK,KAAK,MAAM,KAAK,IAAI;AAC/B,UAAM,MAAM,QAAQ,IAAI,EAAE;AAC1B,QAAI,QAAQ,KAAK,SAAS;AACxB,UAAIC,KAAI,KAAK,MAAM,IAAI,GAAG;AAC1B,UAAIA,OAAM,QAAW;AACnB,QAAAA,KAAI,KAAK,SAAS,IAAI,EAAE;AACxB,aAAK,MAAM,IAAI,KAAKA,EAAC;AAAA,MACvB;AACA,WAAK,OAAOA;AACZ,WAAK,UAAU;AAAA,IACjB;AACA,UAAM,IAAI,KAAK;AACf,QAAI,CAAC,GAAG;AACN,UAAI,CAAC,IAAI,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI;AACpC,aAAO;AAAA,IACT;AACA,UAAM,KAAK,KAAK,KAAK,QAAQ,QAAQ,KAAK,KAAK;AAC/C,QAAI,KAAK,aAAa,GAAG;AACvB,UAAI,CAAC,IAAI,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;AAC9B,UAAI,CAAC,IAAI;AACT,aAAO;AAAA,IACT;AACA,UAAM,IAAI,IAAI;AACd,QAAI,CAAC,IAAI,EAAE,CAAC;AACZ,QAAI,CAAC,IAAI,EAAE,IAAI,CAAC;AAChB,QAAI,CAAC,IAAI,EAAE,IAAI,CAAC;AAChB,QAAI,CAAC,IAAI,EAAE,IAAI,CAAC;AAChB,WAAO,IAAI,CAAC,IAAI;AAAA,EAClB;AACF;AAGO,IAAM,oBAAN,MAA+C;AAAA,EACpD,YACW,MACA,MACT;AAFS;AACA;AAAA,EACR;AAAA,EAFQ;AAAA,EACA;AAAA,EAGX,OAAO,GAAW,GAAW,KAAwB;AACnD,UAAM,IAAI,KAAK;AACf,UAAM,KAAK,IAAI,EAAE;AACjB,UAAM,KAAK,IAAI,EAAE;AACjB,QAAI,KAAK,KAAK,KAAK,KAAK,MAAM,EAAE,SAAS,MAAM,EAAE,QAAQ;AACvD,UAAI,CAAC,IAAI,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI;AACpC,aAAO;AAAA,IACT;AACA,UAAM,KAAK,KAAK,EAAE,QAAQ,MAAM;AAChC,QAAI,CAAC,IAAI,KAAK,KAAK,CAAC;AACpB,QAAI,CAAC,IAAI,KAAK,KAAK,IAAI,CAAC;AACxB,QAAI,CAAC,IAAI,KAAK,KAAK,IAAI,CAAC;AACxB,QAAI,CAAC,IAAI,KAAK,KAAK,IAAI,CAAC;AACxB,WAAO,IAAI,CAAC,IAAI;AAAA,EAClB;AACF;AAGO,SAAS,iBAAiB,QAAqB,MAAkB,KAAK,GAAG,KAAK,GAAiB;AACpG,QAAM,MAAM,IAAI,aAAa,KAAK,QAAQ,KAAK,SAAS,CAAC;AACzD,QAAM,KAAK,CAAC,GAAG,GAAG,GAAG,CAAC;AACtB,WAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,aAAS,IAAI,GAAG,IAAI,KAAK,OAAO,KAAK;AACnC,aAAO,OAAO,KAAK,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,EAAE;AAClD,YAAM,KAAK,IAAI,KAAK,QAAQ,KAAK;AACjC,UAAI,CAAC,IAAI,GAAG,CAAC;AACb,UAAI,IAAI,CAAC,IAAI,GAAG,CAAC;AACjB,UAAI,IAAI,CAAC,IAAI,GAAG,CAAC;AACjB,UAAI,IAAI,CAAC,IAAI,GAAG,CAAC;AAAA,IACnB;AAAA,EACF;AACA,SAAO;AACT;AAmCO,SAAS,mBACd,UACA,UACA,UACA,IACA,IACA,OACA,GACA,UAA6C,CAAC,GAC3C;AAEH,QAAM,OAAO,QAAQ,QAAQ,UAAU,MAAM;AAC7C,QAAM,KAAK,KAAK,OAAO,EAAE,OAAO;AAChC,QAAM,KAAK,KAAK,OAAO,EAAE,OAAO;AAChC,MAAI,KAAK;AACT,MAAI,KAAK;AACT,MAAI,KAAK;AACT,MAAI,KAAK;AACT,MAAI,QAAQ,QAAQ;AAClB,UAAM,IAAI,QAAQ;AAClB,SAAK,KAAK,IAAI,GAAG,KAAK,MAAM,EAAE,CAAC,IAAI,EAAE;AACrC,SAAK,KAAK,IAAI,GAAG,KAAK,MAAM,EAAE,CAAC,IAAI,EAAE;AACrC,SAAK,KAAK,IAAI,MAAM,KAAK,KAAK,EAAE,IAAI,EAAE,KAAK,IAAI,EAAE;AACjD,SAAK,KAAK,IAAI,MAAM,KAAK,KAAK,EAAE,IAAI,EAAE,MAAM,IAAI,EAAE;AAClD,QAAI,MAAM,MAAM,MAAM,GAAI,QAAO;AACjC,QAAI,QAAQ,MAAM;AAChB,eAAS,IAAI,IAAI,IAAI,IAAI,IAAK,KAAI,IAAI,SAAS,UAAU,IAAI,OAAO,MAAM,WAAW,IAAI,OAAO,MAAM,QAAQ,IAAI,IAAI,OAAO,MAAM,QAAQ;AAAA,IAC7I;AAAA,EACF;AACA,QAAM,MAAM,EAAE;AACd,QAAM,QAAQ,EAAE,SAAS;AACzB,QAAM,MAAM,CAAC,GAAG,GAAG,GAAG,CAAC;AACvB,QAAM,MAAM,CAAC,GAAG,GAAG,CAAC;AACpB,QAAM,KAAK,CAAC,GAAG,GAAG,GAAG,CAAC;AACtB,QAAM,KAAK,CAAC,GAAG,GAAG,GAAG,CAAC;AAEtB,MAAI,SAAS;AACb,MAAI;AACJ,WAAS,IAAI,IAAI,IAAI,IAAI,KAAK;AAC5B,UAAM,KAAK,KAAK;AAChB,UAAM,MAAM,KAAK,MAAM,KAAK,IAAI;AAChC,aAAS,IAAI,IAAI,IAAI,IAAI,KAAK;AAC5B,YAAM,KAAK,KAAK;AAChB,YAAM,MAAM,KAAK,MAAM,KAAK,IAAI;AAChC,YAAM,MAAM,QAAQ,KAAK,GAAG;AAC5B,UAAI,QAAQ,QAAQ;AAClB,iBAAS;AACT,kBAAU,SAAS,MAAM,IAAI,GAAG;AAAA,MAClC;AACA,UAAI,CAAC,QAAS;AACd,YAAM,IAAI,SAAS,KAAK,MAAM,QAAQ,QAAQ,KAAK,MAAM,KAAK;AAC9D,UAAI,KAAK,EAAG;AACZ,UAAI,IAAI,IAAI,EAAE;AACd,UAAI,KAAK;AACP,YAAI,KAAK,KAAK,KAAK,KAAK,MAAM,IAAI,SAAS,MAAM,IAAI,OAAQ;AAC7D,aAAK,IAAI,KAAK,KAAK,IAAI,QAAQ,EAAE,IAAI;AAAA,MACvC;AACA,UAAI,IAAI,EAAG,KAAI;AACf,UAAI,KAAK,EAAG;AACZ,YAAM,IAAI,IAAI,OAAO;AACrB,UAAI,aAAa,GAAG;AAElB,cAAM,IAAI,IAAI,CAAC;AACf,YAAI;AACJ,YAAI,MAAM,SAAS,QAAQ;AACzB,cAAI,CAAC,IAAI,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,IAAI;AAC/B,gBAAM,KAAK,GAAG;AACd,cAAI,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC,IAAI;AAAA,QACrC,WAAW,MAAM,SAAS,QAAS,KAAI,MAAM,MAAM,CAAC;AAAA,aAC/C;AACH,cAAI,CAAC,MAAM,OAAO,OAAO,KAAK,MAAM,IAAI,KAAK,MAAM,IAAI,GAAG,EAAG;AAC7D,cAAI,IAAI,CAAC;AACT,eAAK,IAAI,CAAC,IAAI;AAAA,QAChB;AACA,YAAI,CAAC,IAAI,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC;AACnC;AAAA,MACF;AACA,YAAM,IAAI,IAAI;AACd,YAAM,IAAI,IAAI,IAAI,CAAC;AACnB,UAAI,MAAM,SAAS,QAAQ;AACzB,YAAI,MAAM,EAAG;AACb,YAAI,CAAC,IAAI,IAAI,CAAC,IAAI;AAClB,YAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI;AACtB,YAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI;AACtB,cAAM,KAAK,IAAI,CAAC;AAChB,cAAM,KAAK,IAAI,CAAC;AAChB,cAAM,KAAK,IAAI,CAAC;AAChB,cAAM,KAAK,GAAG;AACd,eAAO,KAAK,GAAG,MAAM,IAAI,CAAC,IAAI,MAAM,CAAC;AACrC,eAAO,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,MAAM,CAAC;AACzC,eAAO,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,MAAM,CAAC;AACzC;AAAA,MACF;AACA,UAAI,EAAE,oBAAoB,MAAM,EAAG;AACnC,UAAI,MAAM,SAAS,SAAS;AAC1B,YAAI,CAAC,IAAI,MAAM,MAAM,CAAC;AACtB,YAAI,CAAC,IAAI,MAAM,MAAM,CAAC;AACtB,YAAI,CAAC,IAAI,MAAM,MAAM,CAAC;AACtB,YAAI,CAAC,IAAI,MAAM,MAAM,CAAC;AAAA,MACxB,WAAW,CAAC,MAAM,OAAO,OAAO,KAAK,MAAM,IAAI,KAAK,MAAM,IAAI,GAAG,EAAG;AACpE,eAAS,KAAK,GAAG,KAAK,GAAG,MAAM;AAC7B,WAAG,EAAE,IAAI,IAAI,IAAI,EAAE,IAAI;AACvB,WAAG,EAAE,IAAI,IAAI,EAAE,IAAI;AAAA,MACrB;AAEA,YAAM,IAAI,WAAW,OAAO,IAAI,IAAI,CAAC;AACrC,aAAO,KAAK,GAAG,EAAE,CAAC,CAAC;AACnB,aAAO,KAAK,IAAI,GAAG,EAAE,CAAC,CAAC;AACvB,aAAO,KAAK,IAAI,GAAG,EAAE,CAAC,CAAC;AACvB,UAAI,CAAC,EAAE,iBAAkB,QAAO,KAAK,IAAI,GAAG,EAAE,CAAC,CAAC;AAAA,IAClD;AAAA,EACF;AACA,SAAO;AACT;AAQO,SAAS,oBACd,UACA,SACA,IACA,IACA,MACA,GACA,UAAsE,CAAC,GAC3C;AAC5B,QAAM,SAAS,mBAAmB;AAClC,QAAM,OAAO,QAAQ,QAAQ,SAAS,MAAM;AAC5C,QAAM,KAAK,KAAK,OAAO,EAAE,OAAO;AAChC,QAAM,KAAK,KAAK,OAAO,EAAE,OAAO;AAChC,MAAI,KAAK;AACT,MAAI,KAAK;AACT,MAAI,KAAK;AACT,MAAI,KAAK;AACT,MAAI,QAAQ,QAAQ;AAClB,UAAM,IAAI,QAAQ;AAClB,SAAK,KAAK,IAAI,GAAG,KAAK,MAAM,EAAE,CAAC,IAAI,EAAE;AACrC,SAAK,KAAK,IAAI,GAAG,KAAK,MAAM,EAAE,CAAC,IAAI,EAAE;AACrC,SAAK,KAAK,IAAI,MAAM,KAAK,KAAK,EAAE,IAAI,EAAE,KAAK,IAAI,EAAE;AACjD,SAAK,KAAK,IAAI,MAAM,KAAK,KAAK,EAAE,IAAI,EAAE,MAAM,IAAI,EAAE;AAClD,QAAI,MAAM,MAAM,MAAM,GAAI,QAAO;AACjC,QAAI,QAAQ,KAAM,UAAS,IAAI,IAAI,IAAI,IAAI,IAAK,KAAI,IAAI,QAAQ,UAAU,IAAI,OAAO,MAAM,IAAI,IAAI,OAAO,MAAM,CAAC,IAAI,IAAI,OAAO,MAAM,CAAC;AAAA,EACzI;AACA,QAAM,MAAM,EAAE;AACd,QAAM,MAAM,CAAC,GAAG,GAAG,CAAC;AACpB,QAAM,SAAS,CAAC,GAAG,GAAG,CAAC;AACvB,QAAM,SAAS,CAAC,GAAG,GAAG,CAAC;AACvB,MAAI,SAAS;AACb,MAAI;AACJ,WAAS,IAAI,IAAI,IAAI,IAAI,KAAK;AAC5B,UAAM,KAAK,KAAK;AAChB,UAAM,MAAM,KAAK,MAAM,KAAK,IAAI;AAChC,aAAS,IAAI,IAAI,IAAI,IAAI,KAAK;AAC5B,YAAM,KAAK,KAAK;AAChB,YAAM,MAAM,KAAK,MAAM,KAAK,IAAI;AAChC,YAAM,MAAM,QAAQ,KAAK,GAAG;AAC5B,UAAI,QAAQ,QAAQ;AAClB,iBAAS;AACT,kBAAU,SAAS,MAAM,IAAI,GAAG;AAAA,MAClC;AACA,UAAI,CAAC,QAAS;AACd,YAAM,IAAI,SAAS,KAAK,MAAM,QAAQ,QAAQ,KAAK,MAAM,KAAK;AAC9D,UAAI,KAAK,EAAG;AACZ,UAAI,IAAI,IAAI,EAAE;AACd,UAAI,KAAK;AACP,YAAI,KAAK,KAAK,KAAK,KAAK,MAAM,IAAI,SAAS,MAAM,IAAI,OAAQ;AAC7D,aAAK,IAAI,KAAK,KAAK,IAAI,QAAQ,EAAE,IAAI;AAAA,MACvC;AACA,UAAI,IAAI,EAAG,KAAI;AACf,UAAI,KAAK,EAAG;AACZ,YAAM,KAAK,IAAI,OAAO,KAAK;AAC3B,UAAI,IAAI,IAAI,CAAC,MAAM,EAAG;AACtB,eAAS,KAAK,GAAG,KAAK,GAAG,MAAM;AAC7B,cAAM,IAAI,IAAI,IAAI,EAAE;AACpB,YAAI,QAAQ;AACV,iBAAO,EAAE,IAAI,IAAI,IAAI,IAAI,IAAI;AAC7B,cAAI,EAAE,IAAI,WAAW,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,CAAC;AAAA,QAChD,MAAO,KAAI,EAAE,IAAI,IAAI;AACrB,eAAO,EAAE,IAAI,IAAI,EAAE;AAAA,MACrB;AACA,WAAK,GAAG;AACR,eAAS,KAAK,GAAG,KAAK,GAAG,MAAM;AAC7B,cAAM,IAAI,OAAO,EAAE,KAAK,IAAI,EAAE,IAAI,OAAO,EAAE,KAAK;AAChD,YAAI,OAAQ,KAAI,IAAI,EAAE,IAAI,WAAW,CAAC,IAAI,OAAO,EAAE;AAAA,YAC9C,KAAI,IAAI,EAAE,IAAI,KAAK,IAAI,IAAI,KAAK,IAAI,QAAQ,KAAK,MAAM,IAAI,KAAK;AAAA,MACvE;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAGO,SAAS,OAAO,MAAwB,UAAiG;AAC9I,QAAM,OAAO,SAAS;AACtB,SAAO,CAAC,QAAQ;AACd,cAAU,KAAK,SAAS,UAAU,SAAS,OAAO,MAAM,SAAS,YAAY;AAAA,EAC/E;AACF;AAUO,SAAS,WAAW,GAAW,GAAW,KAAmB,KAAmB,MAAiD;AACtI,QAAM,MAAM,IAAI,aAAa,GAAG;AAChC,QAAM,KAAK,WAAW,GAAG,GAAG,IAAI;AAChC,MAAI,CAAC,GAAI,QAAO;AAChB,QAAM,KAAK,KAAK,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC;AAChC,QAAM,KAAK,KAAK,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC;AAChC,QAAM,KAAK,KAAK,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC;AAChC,QAAM,KAAK,KAAK,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC;AAChC,QAAM,KAAK,KAAK;AAChB,QAAM,KAAK,KAAK;AAChB,QAAM,IAAI,IAAI,aAAa,KAAK,KAAK,CAAC;AACtC,QAAM,IAAI,IAAI,aAAa,KAAK,KAAK,CAAC;AACtC,QAAM,IAAI,IAAI,WAAW,KAAK,EAAE;AAChC,WAAS,IAAI,GAAG,IAAI,IAAI,KAAK;AAC3B,aAAS,IAAI,GAAG,IAAI,IAAI,KAAK;AAC3B,YAAM,MAAM,IAAI,MAAM,IAAI,IAAI;AAC9B,YAAM,KAAK,IAAI,KAAK;AACpB,QAAE,EAAE,IAAI,KAAK,EAAE,IAAI,IAAI;AACvB,eAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,UAAE,KAAK,IAAI,CAAC,IAAI,IAAI,KAAK,IAAI,CAAC;AAC9B,UAAE,KAAK,IAAI,CAAC,IAAI,IAAI,KAAK,IAAI,CAAC;AAAA,MAChC;AAAA,IACF;AAAA,EACF;AACA,QAAM,SAAS,cAAc,IAAI,IAAI,GAAG,GAAG,GAAG,CAAC;AAC/C,WAAS,IAAI,GAAG,IAAI,IAAI,KAAK;AAC3B,aAAS,IAAI,GAAG,IAAI,IAAI,KAAK;AAC3B,YAAM,OAAO,IAAI,MAAM,IAAI,IAAI,MAAM;AACrC,YAAM,MAAM,IAAI,KAAK,KAAK;AAC1B,eAAS,IAAI,GAAG,IAAI,GAAG,IAAK,KAAI,KAAK,CAAC,IAAI,KAAK,IAAI,KAAK,KAAK,IAAI,GAAG,OAAO,KAAK,CAAC,CAAC,CAAC;AAAA,IACrF;AAAA,EACF;AACA,SAAO;AACT;AAQO,SAAS,eACd,GACA,GACA,KACA,MACA,MACA,MAEA,UACc;AAGd,QAAM,SAAS,WAAW,GAAG,GAAG,MAAM,CAAC;AACvC,QAAM,WAAW,WAAW,GAAG,GAAG,MAAM,CAAC;AACzC,MAAI,SAA8B;AAClC,MAAI,YAAqC;AACzC,MAAI,SAAS,mBAAmB;AAC9B,UAAM,OAAO,KAAK,IAAI,IAAI,KAAK,IAAI,GAAG,KAAK,MAAM,OAAO,CAAC,CAAC,CAAC;AAC3D,UAAM,MAAM,WAAW,GAAG,GAAG,GAAG,KAAK,QAAQ,MAAM,KAAK,MAAM,KAAK,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC;AACjF,QAAI,KAAK;AACP,kBAAY;AAEZ,eAAS,IAAI,aAAa,GAAG;AAC7B,YAAM,CAAC,KAAK,GAAG,IAAI;AACnB,eAAS,IAAI,GAAG,IAAI,IAAI,GAAG,KAAK;AAC9B,YAAI,CAAC,OAAO,CAAC,EAAG;AAChB,cAAM,IAAK,IAAI,IAAK;AACpB,cAAM,IAAI,KAAK,MAAM,IAAI,CAAC,IAAI;AAC9B,cAAM,KAAK,IAAI,IAAI,KAAK;AACxB,iBAAS,IAAI,GAAG,IAAI,GAAG,IAAK,QAAO,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC;AAAA,MAC3D;AAAA,IACF;AAAA,EACF;AACA,aAAW,SAAU,YAAiC,IAAI;AAE1D,MAAI,CAAC,UAAU,SAAS,gBAAiB,UAAS,iBAAiB,GAAG,GAAG,GAAG,KAAK,MAAM;AACvF,MAAI,CAAC,OAAQ,UAAS,aAAa,GAAG,GAAG,GAAG,KAAK,MAAM;AACvD,SAAO,WAAW,GAAG,GAAG,QAAQ,KAAK,QAAQ;AAC/C;AAGO,SAAS,eAAe,QAAoB,QAAuD;AACxG,QAAM,IAAI,KAAK,IAAI,GAAG,KAAK,KAAK,KAAK,IAAI,OAAO,OAAO,OAAO,MAAM,CAAC,CAAC;AACtE,QAAM,KAAK,KAAK,IAAI,GAAG,OAAO,IAAI,CAAC;AACnC,QAAM,KAAK,KAAK,IAAI,GAAG,OAAO,IAAI,CAAC;AACnC,QAAM,KAAK,KAAK,IAAI,OAAO,OAAO,OAAO,IAAI,OAAO,QAAQ,CAAC;AAC7D,QAAM,KAAK,KAAK,IAAI,OAAO,QAAQ,OAAO,IAAI,OAAO,SAAS,CAAC;AAC/D,SAAO,EAAE,GAAG,IAAI,GAAG,IAAI,OAAO,KAAK,IAAI,GAAG,KAAK,EAAE,GAAG,QAAQ,KAAK,IAAI,GAAG,KAAK,EAAE,EAAE;AACnF;AAgBO,IAAM,mBAAN,MAAuB;AAAA,EAQ5B,YACW,OACT,QACiB,QACjB;AAHS;AAEQ;AAEjB,SAAK,SAAS,IAAI,UAAU,KAAK;AACjC,SAAK,SAAS,IAAI,WAAW,MAAM;AAAA,EACrC;AAAA,EANW;AAAA,EAEQ;AAAA,EAVnB,WAAW;AAAA,EACX,SAA4B;AAAA,EACX;AAAA,EACA;AAAA,EACT,YAAgC;AAAA,EAChC,MAAM,IAAI,aAAa,CAAC;AAAA,EAWhC,KAAK,QAA8C;AACjD,UAAM,OAAc,CAAC;AACrB,eAAW,KAAK,OAAQ,MAAK,OAAO,KAAK,KAAK,OAAO,CAAC,GAAG,IAAI;AAC7D,WAAO,KAAK,MAAM,IAAI;AAAA,EACxB;AAAA,EAEA,OAAO,MAAkC;AACvC,UAAM,OAAc,CAAC;AACrB,QAAI,QAAQ,KAAK,cAAc,KAAK,UAAU,MAAM,KAAK,KAAK,KAAK,UAAU,MAAM,KAAK,GAAI,MAAK,OAAO,KAAK,MAAM,IAAI;AACvH,SAAK,OAAO,OAAO,IAAI;AACvB,WAAO,KAAK,MAAM,IAAI;AAAA,EACxB;AAAA,EAEQ,OAAO,GAA6B;AAC1C,UAAM,IAAI,IAAI,KAAK,IAAI,MAAM,KAAK,IAAI,GAAG,KAAK,MAAM,SAAS,CAAC;AAC9D,UAAM,MAAM,KAAK;AACjB,UAAM,IAAI,OAAO,IAAI,IAAI,EAAE,GAAG,GAAG,GAAG,IAAI,KAAK,EAAE,IAAI,IAAI,KAAK,GAAG,GAAG,IAAI,KAAK,EAAE,IAAI,IAAI,KAAK,EAAE,IAAI;AAChG,SAAK,YAAY;AACjB,WAAO;AAAA,EACT;AAAA,EAEQ,MAAM,MAA2B;AACvC,UAAM,QAAsB,CAAC;AAC7B,eAAW,KAAK,MAAM;AACpB,YAAM,OAAO,QAAQ,GAAG,KAAK,MAAM,QAAQ;AAC3C,YAAM,IAAI,KAAK,QAAQ,KAAK;AAC5B,UAAI,KAAK,IAAI,SAAS,EAAG,MAAK,MAAM,IAAI,aAAa,CAAC;AACtD,YAAM,MAAM,KAAK,IAAI,SAAS,GAAG,CAAC;AAClC,mBAAa,EAAE,GAAG,GAAG,OAAO,EAAE,GAAG,KAAK,MAAM,UAAU,MAAM,GAAG;AAC/D,WAAK,OAAO,MAAM;AAClB,WAAK,OAAO,KAAK,QAAQ,GAAG,MAAM,GAAG;AACrC,YAAM,KAAK,IAAI;AACf,WAAK,SAAS,UAAU,KAAK,QAAQ,IAAI;AACzC,WAAK;AAAA,IACP;AACA,WAAO;AAAA,EACT;AACF;AAGO,SAAS,aAAa,OAAsB,UAAkB,SAAmC,OAAyB;AAC/H,QAAM,IAAI,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,QAAQ,CAAC;AAC3C,QAAM,MAAM,IAAI,UAAU,EAAE,UAAU,GAAG,QAAQ,GAAG,OAAO,GAAG,MAAM,IAAI;AACxE,SAAO,CAAC,QAAQ,GAAG,MAAM,QAAQ,IAAI,IAAI,QAAQ,EAAE,GAAG,EAAE,GAAG,GAAG,EAAE,GAAG,QAAQ,EAAE,QAAQ,SAAS,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG;AAChI;AAGO,SAAS,aAAa,OAAsB,UAAmB,UAAqC;AACzG,QAAM,MAAM,CAAC,GAAG,GAAG,CAAC;AACpB,SAAO,CAAC,QAAQ,GAAG,MAAM,QAAQ;AAC/B,UAAM,IAAI,KAAK;AACf,aAAS,KAAK,GAAG,KAAK,KAAK,QAAQ,MAAM;AACvC,eAAS,KAAK,GAAG,KAAK,GAAG,MAAM;AAC7B,cAAM,KAAK,IAAI,KAAK,IAAI,EAAE;AAC1B,YAAI,MAAM,EAAG;AACb,cAAM,KAAK,KAAK,IAAI;AACpB,cAAM,KAAK,KAAK,IAAI;AACpB,cAAM,IAAI,eAAe,KAAK,EAAE,QAAQ,EAAE,UAAU,KAAK,MAAM,OAAO,IAAI,OAAO,YAAY,IAAI,EAAE;AACnG,YAAI,KAAK,EAAG;AACZ,cAAM,KAAK,OAAO,OAAO,IAAI,IAAI,KAAK;AACtC,YAAI,KAAK,KAAK,OAAO,OAAO,KAAK,CAAC,MAAM,EAAG;AAC3C,cAAM,IAAI,OAAO,OAAO,IAAI,IAAI,IAAI;AACpC,cAAM,KAAK,OAAO;AAClB,YAAI,CAAC,IAAI,GAAG,CAAC,IAAI;AACjB,YAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI;AACrB,YAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI;AACrB,eAAO,KAAK,GAAG,UAAU,QAAQ;AACjC,eAAO,IAAI,GAAG,IAAI,CAAC,CAAC;AACpB,eAAO,IAAI,IAAI,GAAG,IAAI,CAAC,CAAC;AACxB,eAAO,IAAI,IAAI,GAAG,IAAI,CAAC,CAAC;AAAA,MAC1B;AAAA,IACF;AAAA,EACF;AACF;AAOO,SAAS,eAAe,QAAqE;AAClG,QAAM,QAAQ,oBAAI,IAA+B;AACjD,QAAM,QAAQ,oBAAI,IAAiE;AACnF,QAAM,SAAS,CAAC,MAAyB;AACvC,UAAM,MAAM,IAAI,kBAAkB,EAAE,SAAS,CAAC;AAC9C,aAAS,IAAI,GAAG,IAAI,EAAE,QAAQ,KAAK;AACjC,UAAI,IAAI,CAAC,IAAI,IAAI,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;AAClD,UAAI,IAAI,IAAI,CAAC,IAAI;AAAA,IACnB;AACA,WAAO;AAAA,EACT;AACA,QAAM,OAAwB;AAAA,IAC5B,QAAQ,OAAO;AAAA,IACf,kBAAkB;AAAA,IAClB,WAAW,OAAO;AAAA,IAClB,UAAU,CAAC,IAAI,OAAO;AACpB,YAAM,MAAM,QAAQ,IAAI,EAAE;AAC1B,UAAI,IAAI,MAAM,IAAI,GAAG;AACrB,UAAI,CAAC,GAAG;AAEN,YAAI,OAAQ,OAAO,SAAS,IAAI,EAAE,KAAkC,IAAI,kBAAkB,OAAO,IAAI,CAAC;AACtG,cAAM,IAAI,KAAK,CAAC;AAAA,MAClB;AACA,aAAO;AAAA,IACT;AAAA,IACA,WAAW,CAAC,IAAI,OAAO;AACrB,YAAM,MAAM,QAAQ,IAAI,EAAE;AAC1B,UAAI,IAAI,MAAM,IAAI,GAAG;AACrB,UAAI,CAAC,GAAG;AACN,YAAI,OAAQ,OAAO,SAAS,IAAI,EAAE,KAAkC,IAAI,kBAAkB,OAAO,IAAI,CAAC;AACtG,cAAM,IAAI,KAAK,CAAC;AAAA,MAClB;AACA,YAAM,IAAI,KAAK,EAAE,IAAI,IAAI,MAAM,EAAE,CAAC;AAClC,aAAO;AAAA,IACT;AAAA,EACF;AACA,SAAO;AAAA,IACL,QAAQ;AAAA,IACR,OAAO,MAAM;AACX,iBAAW,EAAE,IAAI,IAAI,KAAK,KAAK,MAAM,OAAO,GAAG;AAC7C,cAAM,IAAI,OAAO,UAAU,IAAI,EAAE;AACjC,iBAAS,IAAI,GAAG,IAAI,EAAE,QAAQ,IAAK,GAAE,CAAC,IAAI,KAAK,IAAI,CAAC;AAAA,MACtD;AACA,YAAM,MAAM;AAAA,IACd;AAAA,EACF;AACF;AAEA,SAAS,UAAU,GAAsB,GAA2B;AAClE,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;","names":["w","t"]}
|