@pixerate/editor 0.135.0 → 0.137.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 +63 -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 +10 -2
- package/dist/animation-editor/index.js.map +1 -1
- package/dist/{bezier-J8i4uqSH.d.cts → bezier-CZ2AhjID.d.cts} +1 -1
- package/dist/{bezier-lNEOp0Jx.d.ts → bezier-Dywv3Bw8.d.ts} +1 -1
- package/dist/blending-D7jCmjO6.d.cts +1026 -0
- package/dist/blending-NgF3qo3d.d.ts +1026 -0
- package/dist/brushes-CnvZSYYU.d.cts +744 -0
- package/dist/brushes-DJmUbIgz.d.ts +744 -0
- package/dist/{brushstrokeRender-SII6MG4R.js → brushstrokeRender-2FAXA3XC.js} +13 -16
- package/dist/{brushstrokeRender-SII6MG4R.js.map → brushstrokeRender-2FAXA3XC.js.map} +1 -1
- package/dist/{brushstrokeRender-JNHVEUFG.cjs → brushstrokeRender-IMFY3FF6.cjs} +16 -19
- package/dist/brushstrokeRender-IMFY3FF6.cjs.map +1 -0
- package/dist/canvas/index.cjs +10 -10
- package/dist/canvas/index.cjs.map +1 -1
- package/dist/canvas/index.d.cts +10 -7
- package/dist/canvas/index.d.ts +10 -7
- package/dist/canvas/index.js +4 -4
- package/dist/{chunk-W4LNKTHT.cjs → chunk-2XS6LTUP.cjs} +63 -63
- package/dist/{chunk-W4LNKTHT.cjs.map → chunk-2XS6LTUP.cjs.map} +1 -1
- package/dist/{chunk-HHTCDFZC.js → chunk-3D77LOBM.js} +234 -136
- package/dist/chunk-3D77LOBM.js.map +1 -0
- package/dist/{chunk-BR7EKQUP.js → chunk-3G6J7UFV.js} +322 -2
- package/dist/chunk-3G6J7UFV.js.map +1 -0
- package/dist/{chunk-62XUO5LB.js → chunk-3X6IAJUQ.js} +2 -2
- package/dist/{chunk-EM3FMJWE.js → chunk-5FSRTP6E.js} +320 -3
- package/dist/chunk-5FSRTP6E.js.map +1 -0
- package/dist/{chunk-Z2H7KECK.cjs → chunk-5OOIUXNJ.cjs} +345 -247
- package/dist/chunk-5OOIUXNJ.cjs.map +1 -0
- package/dist/{chunk-7RJ6P7MI.js → chunk-6S6362D2.js} +2 -2
- package/dist/chunk-A3BVTI3G.js +150 -0
- package/dist/chunk-A3BVTI3G.js.map +1 -0
- package/dist/{chunk-24ATT2PE.cjs → chunk-AEAAN4AD.cjs} +120 -120
- package/dist/{chunk-24ATT2PE.cjs.map → chunk-AEAAN4AD.cjs.map} +1 -1
- package/dist/chunk-ECCXGELC.cjs +727 -0
- package/dist/chunk-ECCXGELC.cjs.map +1 -0
- package/dist/{chunk-SVYE5HIM.js → chunk-EQQMGO42.js} +2 -2
- package/dist/{chunk-FHPVDTI2.cjs → chunk-F2Y4E4GU.cjs} +22 -22
- package/dist/{chunk-FHPVDTI2.cjs.map → chunk-F2Y4E4GU.cjs.map} +1 -1
- package/dist/{chunk-OXSV64JX.js → chunk-G6IKY6PL.js} +4 -4
- package/dist/{chunk-UYQUPUR6.js → chunk-HUO3TI4C.js} +3 -3
- package/dist/chunk-I52DRGGJ.js +727 -0
- package/dist/chunk-I52DRGGJ.js.map +1 -0
- package/dist/{chunk-DDSO4HS7.cjs → chunk-KEENUAFN.cjs} +2 -2
- package/dist/{chunk-DDSO4HS7.cjs.map → chunk-KEENUAFN.cjs.map} +1 -1
- package/dist/{chunk-2HC4DRF4.js → chunk-LLFHCSU2.js} +2 -2
- package/dist/{chunk-J5BA3BQ6.cjs → chunk-O7LUD7MH.cjs} +323 -3
- package/dist/chunk-O7LUD7MH.cjs.map +1 -0
- package/dist/{chunk-ILYFOJUN.js → chunk-OIBIRXRG.js} +3 -3
- package/dist/{chunk-FWEO3HSL.js → chunk-PQQF5KOW.js} +8 -8
- package/dist/{chunk-T6TV6HY6.cjs → chunk-PRSRYHQD.cjs} +36 -36
- package/dist/{chunk-T6TV6HY6.cjs.map → chunk-PRSRYHQD.cjs.map} +1 -1
- package/dist/chunk-Q6OUXEK3.cjs +150 -0
- package/dist/chunk-Q6OUXEK3.cjs.map +1 -0
- package/dist/{chunk-6GFRKLLS.cjs → chunk-QBWEH3IM.cjs} +429 -112
- package/dist/chunk-QBWEH3IM.cjs.map +1 -0
- package/dist/{chunk-ESIWZMMK.js → chunk-SYT2TLQF.js} +35 -37
- package/dist/{chunk-ESIWZMMK.js.map → chunk-SYT2TLQF.js.map} +1 -1
- package/dist/{chunk-YT3JL7YM.cjs → chunk-TLCTTQFF.cjs} +53 -53
- package/dist/{chunk-YT3JL7YM.cjs.map → chunk-TLCTTQFF.cjs.map} +1 -1
- 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-YAFS2QFZ.cjs → chunk-XN2NBLV5.cjs} +313 -315
- package/dist/chunk-XN2NBLV5.cjs.map +1 -0
- package/dist/effects/index.d.cts +7 -4
- package/dist/effects/index.d.ts +7 -4
- package/dist/{export-DMeG6E06.d.ts → export-41rL6Cne.d.ts} +1 -1
- package/dist/{export-AZSwX087.d.cts → export-CyJdfP_Z.d.cts} +5 -4
- package/dist/{export-KzubBKo7.d.cts → export-D9mXp05Q.d.cts} +1 -1
- package/dist/{export-BDkyDNM8.d.ts → export-DwnZ_hvQ.d.ts} +5 -4
- 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-C-RgeyvH.d.ts} +25 -8
- package/dist/{helpers-DHl28yLO.d.cts → helpers-v6GMazzg.d.cts} +25 -8
- package/dist/image-editor/index.cjs +986 -986
- package/dist/image-editor/index.cjs.map +1 -1
- package/dist/image-editor/index.d.cts +15 -11
- package/dist/image-editor/index.d.ts +15 -11
- package/dist/image-editor/index.js +94 -94
- package/dist/index.cjs +28 -28
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +36 -36
- package/dist/{opentype-BWR7Qv8W.d.cts → opentype-KR_jj6b_.d.cts} +1 -1
- package/dist/{opentype-Dfcx6wFx.d.ts → opentype-a1KAW-qs.d.ts} +1 -1
- package/dist/paint/index.cjs +5 -8
- package/dist/paint/index.cjs.map +1 -1
- package/dist/paint/index.d.cts +4 -2
- package/dist/paint/index.d.ts +4 -2
- package/dist/paint/index.js +15 -18
- package/dist/paint-editor/index.cjs +405 -403
- package/dist/paint-editor/index.cjs.map +1 -1
- package/dist/paint-editor/index.d.cts +15 -748
- package/dist/paint-editor/index.d.ts +15 -748
- package/dist/paint-editor/index.js +79 -77
- package/dist/paint-editor/index.js.map +1 -1
- package/dist/{pathfinder-D8KQ6blQ.d.cts → pathfinder-BHS4vQNm.d.cts} +1 -1
- package/dist/{pathfinder-Celbi3e6.d.ts → pathfinder-BVvTIBMo.d.ts} +1 -1
- package/dist/{pool-8JZGWHvR.d.ts → pool-CZQOrSXZ.d.ts} +1 -1
- package/dist/{pool-BfuxBKTd.d.cts → pool-FjZZmZ80.d.cts} +1 -1
- package/dist/provenance-DmlcgdzT.d.cts +426 -0
- package/dist/provenance-uh5r2TQ8.d.ts +426 -0
- package/dist/rand-8xbUb6ur.d.ts +1118 -0
- package/dist/rand-Cw9VLrVC.d.cts +1118 -0
- package/dist/raster/index.cjs +17 -19
- package/dist/raster/index.cjs.map +1 -1
- package/dist/raster/index.js +9 -11
- package/dist/raster/index.js.map +1 -1
- package/dist/{svg-CxxqG3_W.d.ts → svg-CSz3mzkw.d.ts} +2 -2
- package/dist/{svg-pwXWq6s2.d.cts → svg-DTb40ICU.d.cts} +2 -2
- package/dist/{tools-y1M6O3UT.d.ts → tools-B0wXP5cF.d.ts} +1 -1
- package/dist/{tools-3EBjR91b.d.cts → tools-Ca0kI1qo.d.cts} +1 -1
- package/dist/vector/index.cjs +2698 -1674
- package/dist/vector/index.cjs.map +1 -1
- package/dist/vector/index.d.cts +390 -72
- package/dist/vector/index.d.ts +390 -72
- package/dist/vector/index.js +1665 -641
- 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-DTOp0lON.d.cts} +1 -1
- package/dist/{warp-C1gwu2G_.d.ts → warp-pd7hrH4T.d.ts} +1 -1
- package/package.json +1 -1
- package/skills/pixerate-vector/SKILL.md +22 -0
- package/dist/brushstrokeRender-JNHVEUFG.cjs.map +0 -1
- package/dist/chunk-64PYNEHJ.js +0 -340
- package/dist/chunk-64PYNEHJ.js.map +0 -1
- package/dist/chunk-6GFRKLLS.cjs.map +0 -1
- package/dist/chunk-7QN76ESJ.js +0 -323
- package/dist/chunk-7QN76ESJ.js.map +0 -1
- package/dist/chunk-BR7EKQUP.js.map +0 -1
- package/dist/chunk-DCLJNVZS.cjs +0 -323
- package/dist/chunk-DCLJNVZS.cjs.map +0 -1
- package/dist/chunk-EM3FMJWE.js.map +0 -1
- package/dist/chunk-HHTCDFZC.js.map +0 -1
- package/dist/chunk-J5BA3BQ6.cjs.map +0 -1
- package/dist/chunk-YAFS2QFZ.cjs.map +0 -1
- package/dist/chunk-Z2H7KECK.cjs.map +0 -1
- package/dist/chunk-Z6OUCS2K.cjs +0 -340
- package/dist/chunk-Z6OUCS2K.cjs.map +0 -1
- package/dist/rand-BszBST4s.d.ts +0 -2140
- package/dist/rand-DOH_aMvm.d.cts +0 -2140
- /package/dist/{chunk-62XUO5LB.js.map → chunk-3X6IAJUQ.js.map} +0 -0
- /package/dist/{chunk-7RJ6P7MI.js.map → chunk-6S6362D2.js.map} +0 -0
- /package/dist/{chunk-SVYE5HIM.js.map → chunk-EQQMGO42.js.map} +0 -0
- /package/dist/{chunk-OXSV64JX.js.map → chunk-G6IKY6PL.js.map} +0 -0
- /package/dist/{chunk-UYQUPUR6.js.map → chunk-HUO3TI4C.js.map} +0 -0
- /package/dist/{chunk-2HC4DRF4.js.map → chunk-LLFHCSU2.js.map} +0 -0
- /package/dist/{chunk-ILYFOJUN.js.map → chunk-OIBIRXRG.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"]}
|
|
@@ -74,7 +74,7 @@ function profileAlongPolyline(points, values, count = 32) {
|
|
|
74
74
|
var round3 = (v) => Math.round(v * 1e3) / 1e3;
|
|
75
75
|
var loading = null;
|
|
76
76
|
function loadCanvasBrushstrokeRenderer() {
|
|
77
|
-
loading ??= Promise.resolve().then(() => _interopRequireWildcard(require("./brushstrokeRender-
|
|
77
|
+
loading ??= Promise.resolve().then(() => _interopRequireWildcard(require("./brushstrokeRender-IMFY3FF6.cjs"))).catch((error) => {
|
|
78
78
|
loading = null;
|
|
79
79
|
throw error;
|
|
80
80
|
});
|
|
@@ -109,4 +109,4 @@ async function getBrushedShapeSvg(shape, size, options = {}) {
|
|
|
109
109
|
|
|
110
110
|
|
|
111
111
|
exports.isBrushedShape = isBrushedShape; exports.pathDataToPolyline = pathDataToPolyline; exports.profileAlongPolyline = profileAlongPolyline; exports.loadCanvasBrushstrokeRenderer = loadCanvasBrushstrokeRenderer; exports.listCanvasBrushes = listCanvasBrushes; exports.validateCanvasBrush = validateCanvasBrush; exports.validateCanvasBrushPaint = validateCanvasBrushPaint; exports.renderShapeBrushstroke = renderShapeBrushstroke; exports.getBrushedShapeSvg = getBrushedShapeSvg;
|
|
112
|
-
//# sourceMappingURL=chunk-
|
|
112
|
+
//# sourceMappingURL=chunk-KEENUAFN.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/home/runner/work/editor/editor/packages/core/dist/chunk-DDSO4HS7.cjs","../src/canvas/brushstroke.ts"],"names":[],"mappings":"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","file":"/home/runner/work/editor/editor/packages/core/dist/chunk-DDSO4HS7.cjs","sourcesContent":[null,"/**\n * Brushed freehand strokes: a path shape with a `brush` keeps its path (selection, editing, eraser\n * hit-testing, grouping and export work as for any path) and is drawn with the paint engine's\n * dry brushstroke renderer instead of an SVG stroke. The renderer, the paint presets and the colour\n * parser live in a separate chunk, loaded the first time a brushed stroke is drawn, so canvases\n * without brushes never load the paint engine.\n */\nimport { brushstrokeScaleBucket } from '../paint/brushstroke-scale.js';\nimport { parseSvgPath, type PathShape, type ShapeDescription, type ShapeSize } from './shapeGeometry.js';\nimport type { Point } from './types.js';\nimport type { CanvasBrush, CanvasBrushPaint, CanvasBrushPreset, CanvasBrushstroke } from './brushTypes.js';\n\nexport type { CanvasBrush, CanvasBrushPaint, CanvasBrushPaintMapping, CanvasBrushPaintStop, CanvasBrushPreset, CanvasBrushSettings, CanvasBrushstroke } from './brushTypes.js';\n\nexport { brushstrokeScaleBucket };\n\n/** A brushed stroke's image, placed in the path's coordinates (the shape's view box). */\nexport interface CanvasBrushstrokeImage {\n\t/** PNG data URL. */\n\thref: string;\n\tx: number;\n\ty: number;\n\twidth: number;\n\theight: number;\n\t/** Image pixels per path unit. */\n\tscale: number;\n}\n\n/** A path shape with a brush. */\nexport type BrushedPathShape = PathShape & { brush: CanvasBrushstroke };\n\n/** Whether a shape is a brushed stroke. */\nexport function isBrushedShape(shape: ShapeDescription | null | undefined): shape is BrushedPathShape {\n\treturn !!shape && shape.kind === 'path' && !!shape.brush && typeof shape.brush === 'object' && shape.brush.brush != null;\n}\n\n/**\n * The open polyline of a path's first subpath, in path coordinates: lines kept, curves sampled\n * every `step` units or so. Brushed strokes are drawn along it.\n */\nexport function pathDataToPolyline(d: string, step = 2): Point[] {\n\tconst out: Point[] = [];\n\tlet x = 0;\n\tlet y = 0;\n\tlet started = false;\n\tconst push = (px: number, py: number) => {\n\t\tconst last = out[out.length - 1];\n\t\tif (!last || last[0] !== px || last[1] !== py) out.push([px, py]);\n\t};\n\tfor (const c of parseSvgPath(d)) {\n\t\tif (c.type === 'M') {\n\t\t\tif (started) break;\n\t\t\tstarted = true;\n\t\t\tx = c.x;\n\t\t\ty = c.y;\n\t\t\tpush(x, y);\n\t\t} else if (c.type === 'Z') {\n\t\t\tif (out.length) push(out[0][0], out[0][1]);\n\t\t\tbreak;\n\t\t} else if (c.type === 'C' || c.type === 'Q') {\n\t\t\tconst pts = c.type === 'C' ? [[x, y], [c.x1, c.y1], [c.x2, c.y2], [c.x, c.y]] : [[x, y], [c.x1, c.y1], [c.x, c.y]];\n\t\t\tlet hull = 0;\n\t\t\tfor (let i = 1; i < pts.length; i++) hull += Math.hypot(pts[i][0] - pts[i - 1][0], pts[i][1] - pts[i - 1][1]);\n\t\t\tconst n = Math.max(1, Math.min(256, Math.ceil(hull / Math.max(0.25, step))));\n\t\t\tfor (let k = 1; k <= n; k++) {\n\t\t\t\tconst t = k / n;\n\t\t\t\tconst u = 1 - t;\n\t\t\t\tif (c.type === 'C') {\n\t\t\t\t\tpush(\n\t\t\t\t\t\tu * u * u * x + 3 * u * u * t * c.x1 + 3 * u * t * t * c.x2 + t * t * t * c.x,\n\t\t\t\t\t\tu * u * u * y + 3 * u * u * t * c.y1 + 3 * u * t * t * c.y2 + t * t * t * c.y\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\tpush(u * u * x + 2 * u * t * c.x1 + t * t * c.x, u * u * y + 2 * u * t * c.y1 + t * t * c.y);\n\t\t\t\t}\n\t\t\t}\n\t\t\tx = c.x;\n\t\t\ty = c.y;\n\t\t} else {\n\t\t\t// Lines, and arcs as their chords (freehand paths have none).\n\t\t\tx = c.x;\n\t\t\ty = c.y;\n\t\t\tpush(x, y);\n\t\t}\n\t}\n\treturn out;\n}\n\n/**\n * Resamples per-point values into `count` values spread evenly along the polyline's length (the\n * profile a brushed stroke stores). Values are rounded to three decimals.\n */\nexport function profileAlongPolyline(points: readonly Point[], values: readonly number[], count = 32): number[] {\n\tconst n = Math.min(points.length, values.length);\n\tif (n === 0) return [];\n\tif (n === 1) return [round3(values[0])];\n\tconst lengths = [0];\n\tfor (let i = 1; i < n; i++) lengths.push(lengths[i - 1] + Math.hypot(points[i][0] - points[i - 1][0], points[i][1] - points[i - 1][1]));\n\tconst total = lengths[n - 1];\n\tconst m = Math.max(2, Math.min(count, n));\n\tconst out: number[] = [];\n\tlet j = 0;\n\tfor (let k = 0; k < m; k++) {\n\t\tconst at = total > 0 ? (total * k) / (m - 1) : 0;\n\t\twhile (j < n - 2 && lengths[j + 1] < at) j++;\n\t\tconst span = lengths[j + 1] - lengths[j];\n\t\tconst f = span > 0 ? Math.min(1, Math.max(0, (at - lengths[j]) / span)) : 0;\n\t\tout.push(round3(values[j] + (values[j + 1] - values[j]) * f));\n\t}\n\treturn out;\n}\n\nconst round3 = (v: number) => Math.round(v * 1000) / 1000;\n\n// ---------------------------------------------------------------------------\n// The lazily loaded renderer\n// ---------------------------------------------------------------------------\n\n/** The renderer chunk (`./brushstrokeRender.ts`). */\nexport interface CanvasBrushstrokeRenderer {\n\tlistCanvasBrushes(): CanvasBrushPreset[];\n\t/** Throws for an unknown or non-dry brush; the result is the paint engine's brush. */\n\tresolveCanvasBrush(brush: CanvasBrush, width: number): unknown;\n\t/** Throws for paint that is not a colour or gradient paint a canvas stroke can use; the result is the paint engine's `PaintSource`. */\n\tresolveCanvasPaint(paint: unknown): unknown;\n\trenderShapeBrushstrokeNow(shape: BrushedPathShape, scale: number): CanvasBrushstrokeImage | null;\n\tbrushedShapeSvgNow(shape: BrushedPathShape, size: ShapeSize, scale: number): string;\n}\n\nlet loading: Promise<CanvasBrushstrokeRenderer> | null = null;\n\n/**\n * Loads the brushstroke renderer (the paint engine's dry brushes, the paint presets and a CSS\n * colour parser). Called for you by the functions below; call it early to warm up.\n */\nexport function loadCanvasBrushstrokeRenderer(): Promise<CanvasBrushstrokeRenderer> {\n\tloading ??= (import('./brushstrokeRender.js') as Promise<CanvasBrushstrokeRenderer>).catch((error) => {\n\t\tloading = null;\n\t\tthrow error;\n\t});\n\treturn loading;\n}\n\n/** The dry paint presets a freehand stroke can use (wet, mixer, blender, smudge and eraser presets are left out). */\nexport async function listCanvasBrushes(): Promise<CanvasBrushPreset[]> {\n\treturn (await loadCanvasBrushstrokeRenderer()).listCanvasBrushes();\n}\n\n/**\n * Checks a brush: an unknown preset id, a wet (or other non-dry) preset, or settings that are not\n * an object throw an error saying which presets can be used.\n */\nexport async function validateCanvasBrush(brush: CanvasBrush): Promise<void> {\n\t(await loadCanvasBrushstrokeRenderer()).resolveCanvasBrush(brush, 1);\n}\n\n/**\n * Checks a brushed stroke's `paint` (a colour or gradient paint): bad stops, an unknown mapping,\n * or a mapping that needs timed samples (`velocity`, `time`) throw an error saying what to use.\n */\nexport async function validateCanvasBrushPaint(paint: CanvasBrushPaint): Promise<void> {\n\t(await loadCanvasBrushstrokeRenderer()).resolveCanvasPaint(paint);\n}\n\nexport interface RenderShapeBrushstrokeOptions {\n\t/** Image pixels per path unit; pass `brushstrokeScaleBucket(zoom × node scale, devicePixelRatio)` (default 1). */\n\tscale?: number;\n}\n\n/**\n * Renders a brushed path shape to a cached PNG placed in path coordinates, or null for a shape\n * without a brush or an empty path. Throws for an unknown or non-dry brush.\n */\nexport async function renderShapeBrushstroke(shape: ShapeDescription, options: RenderShapeBrushstrokeOptions = {}): Promise<CanvasBrushstrokeImage | null> {\n\tif (!isBrushedShape(shape)) return null;\n\treturn (await loadCanvasBrushstrokeRenderer()).renderShapeBrushstrokeNow(shape, options.scale ?? 1);\n}\n\n/**\n * The brushed stroke as a standalone SVG document of `size` (the node box), with the image\n * embedded as a PNG data URL: what an SVG export writes for the node. Shapes without a brush give\n * null (export them as paths).\n */\nexport async function getBrushedShapeSvg(shape: ShapeDescription, size: ShapeSize, options: RenderShapeBrushstrokeOptions = {}): Promise<string | null> {\n\tif (!isBrushedShape(shape)) return null;\n\treturn (await loadCanvasBrushstrokeRenderer()).brushedShapeSvgNow(shape, size, options.scale ?? 2);\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["/home/runner/work/editor/editor/packages/core/dist/chunk-KEENUAFN.cjs","../src/canvas/brushstroke.ts"],"names":[],"mappings":"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","file":"/home/runner/work/editor/editor/packages/core/dist/chunk-KEENUAFN.cjs","sourcesContent":[null,"/**\n * Brushed freehand strokes: a path shape with a `brush` keeps its path (selection, editing, eraser\n * hit-testing, grouping and export work as for any path) and is drawn with the paint engine's\n * dry brushstroke renderer instead of an SVG stroke. The renderer, the paint presets and the colour\n * parser live in a separate chunk, loaded the first time a brushed stroke is drawn, so canvases\n * without brushes never load the paint engine.\n */\nimport { brushstrokeScaleBucket } from '../paint/brushstroke-scale.js';\nimport { parseSvgPath, type PathShape, type ShapeDescription, type ShapeSize } from './shapeGeometry.js';\nimport type { Point } from './types.js';\nimport type { CanvasBrush, CanvasBrushPaint, CanvasBrushPreset, CanvasBrushstroke } from './brushTypes.js';\n\nexport type { CanvasBrush, CanvasBrushPaint, CanvasBrushPaintMapping, CanvasBrushPaintStop, CanvasBrushPreset, CanvasBrushSettings, CanvasBrushstroke } from './brushTypes.js';\n\nexport { brushstrokeScaleBucket };\n\n/** A brushed stroke's image, placed in the path's coordinates (the shape's view box). */\nexport interface CanvasBrushstrokeImage {\n\t/** PNG data URL. */\n\thref: string;\n\tx: number;\n\ty: number;\n\twidth: number;\n\theight: number;\n\t/** Image pixels per path unit. */\n\tscale: number;\n}\n\n/** A path shape with a brush. */\nexport type BrushedPathShape = PathShape & { brush: CanvasBrushstroke };\n\n/** Whether a shape is a brushed stroke. */\nexport function isBrushedShape(shape: ShapeDescription | null | undefined): shape is BrushedPathShape {\n\treturn !!shape && shape.kind === 'path' && !!shape.brush && typeof shape.brush === 'object' && shape.brush.brush != null;\n}\n\n/**\n * The open polyline of a path's first subpath, in path coordinates: lines kept, curves sampled\n * every `step` units or so. Brushed strokes are drawn along it.\n */\nexport function pathDataToPolyline(d: string, step = 2): Point[] {\n\tconst out: Point[] = [];\n\tlet x = 0;\n\tlet y = 0;\n\tlet started = false;\n\tconst push = (px: number, py: number) => {\n\t\tconst last = out[out.length - 1];\n\t\tif (!last || last[0] !== px || last[1] !== py) out.push([px, py]);\n\t};\n\tfor (const c of parseSvgPath(d)) {\n\t\tif (c.type === 'M') {\n\t\t\tif (started) break;\n\t\t\tstarted = true;\n\t\t\tx = c.x;\n\t\t\ty = c.y;\n\t\t\tpush(x, y);\n\t\t} else if (c.type === 'Z') {\n\t\t\tif (out.length) push(out[0][0], out[0][1]);\n\t\t\tbreak;\n\t\t} else if (c.type === 'C' || c.type === 'Q') {\n\t\t\tconst pts = c.type === 'C' ? [[x, y], [c.x1, c.y1], [c.x2, c.y2], [c.x, c.y]] : [[x, y], [c.x1, c.y1], [c.x, c.y]];\n\t\t\tlet hull = 0;\n\t\t\tfor (let i = 1; i < pts.length; i++) hull += Math.hypot(pts[i][0] - pts[i - 1][0], pts[i][1] - pts[i - 1][1]);\n\t\t\tconst n = Math.max(1, Math.min(256, Math.ceil(hull / Math.max(0.25, step))));\n\t\t\tfor (let k = 1; k <= n; k++) {\n\t\t\t\tconst t = k / n;\n\t\t\t\tconst u = 1 - t;\n\t\t\t\tif (c.type === 'C') {\n\t\t\t\t\tpush(\n\t\t\t\t\t\tu * u * u * x + 3 * u * u * t * c.x1 + 3 * u * t * t * c.x2 + t * t * t * c.x,\n\t\t\t\t\t\tu * u * u * y + 3 * u * u * t * c.y1 + 3 * u * t * t * c.y2 + t * t * t * c.y\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\tpush(u * u * x + 2 * u * t * c.x1 + t * t * c.x, u * u * y + 2 * u * t * c.y1 + t * t * c.y);\n\t\t\t\t}\n\t\t\t}\n\t\t\tx = c.x;\n\t\t\ty = c.y;\n\t\t} else {\n\t\t\t// Lines, and arcs as their chords (freehand paths have none).\n\t\t\tx = c.x;\n\t\t\ty = c.y;\n\t\t\tpush(x, y);\n\t\t}\n\t}\n\treturn out;\n}\n\n/**\n * Resamples per-point values into `count` values spread evenly along the polyline's length (the\n * profile a brushed stroke stores). Values are rounded to three decimals.\n */\nexport function profileAlongPolyline(points: readonly Point[], values: readonly number[], count = 32): number[] {\n\tconst n = Math.min(points.length, values.length);\n\tif (n === 0) return [];\n\tif (n === 1) return [round3(values[0])];\n\tconst lengths = [0];\n\tfor (let i = 1; i < n; i++) lengths.push(lengths[i - 1] + Math.hypot(points[i][0] - points[i - 1][0], points[i][1] - points[i - 1][1]));\n\tconst total = lengths[n - 1];\n\tconst m = Math.max(2, Math.min(count, n));\n\tconst out: number[] = [];\n\tlet j = 0;\n\tfor (let k = 0; k < m; k++) {\n\t\tconst at = total > 0 ? (total * k) / (m - 1) : 0;\n\t\twhile (j < n - 2 && lengths[j + 1] < at) j++;\n\t\tconst span = lengths[j + 1] - lengths[j];\n\t\tconst f = span > 0 ? Math.min(1, Math.max(0, (at - lengths[j]) / span)) : 0;\n\t\tout.push(round3(values[j] + (values[j + 1] - values[j]) * f));\n\t}\n\treturn out;\n}\n\nconst round3 = (v: number) => Math.round(v * 1000) / 1000;\n\n// ---------------------------------------------------------------------------\n// The lazily loaded renderer\n// ---------------------------------------------------------------------------\n\n/** The renderer chunk (`./brushstrokeRender.ts`). */\nexport interface CanvasBrushstrokeRenderer {\n\tlistCanvasBrushes(): CanvasBrushPreset[];\n\t/** Throws for an unknown or non-dry brush; the result is the paint engine's brush. */\n\tresolveCanvasBrush(brush: CanvasBrush, width: number): unknown;\n\t/** Throws for paint that is not a colour or gradient paint a canvas stroke can use; the result is the paint engine's `PaintSource`. */\n\tresolveCanvasPaint(paint: unknown): unknown;\n\trenderShapeBrushstrokeNow(shape: BrushedPathShape, scale: number): CanvasBrushstrokeImage | null;\n\tbrushedShapeSvgNow(shape: BrushedPathShape, size: ShapeSize, scale: number): string;\n}\n\nlet loading: Promise<CanvasBrushstrokeRenderer> | null = null;\n\n/**\n * Loads the brushstroke renderer (the paint engine's dry brushes, the paint presets and a CSS\n * colour parser). Called for you by the functions below; call it early to warm up.\n */\nexport function loadCanvasBrushstrokeRenderer(): Promise<CanvasBrushstrokeRenderer> {\n\tloading ??= (import('./brushstrokeRender.js') as Promise<CanvasBrushstrokeRenderer>).catch((error) => {\n\t\tloading = null;\n\t\tthrow error;\n\t});\n\treturn loading;\n}\n\n/** The dry paint presets a freehand stroke can use (wet, mixer, blender, smudge and eraser presets are left out). */\nexport async function listCanvasBrushes(): Promise<CanvasBrushPreset[]> {\n\treturn (await loadCanvasBrushstrokeRenderer()).listCanvasBrushes();\n}\n\n/**\n * Checks a brush: an unknown preset id, a wet (or other non-dry) preset, or settings that are not\n * an object throw an error saying which presets can be used.\n */\nexport async function validateCanvasBrush(brush: CanvasBrush): Promise<void> {\n\t(await loadCanvasBrushstrokeRenderer()).resolveCanvasBrush(brush, 1);\n}\n\n/**\n * Checks a brushed stroke's `paint` (a colour or gradient paint): bad stops, an unknown mapping,\n * or a mapping that needs timed samples (`velocity`, `time`) throw an error saying what to use.\n */\nexport async function validateCanvasBrushPaint(paint: CanvasBrushPaint): Promise<void> {\n\t(await loadCanvasBrushstrokeRenderer()).resolveCanvasPaint(paint);\n}\n\nexport interface RenderShapeBrushstrokeOptions {\n\t/** Image pixels per path unit; pass `brushstrokeScaleBucket(zoom × node scale, devicePixelRatio)` (default 1). */\n\tscale?: number;\n}\n\n/**\n * Renders a brushed path shape to a cached PNG placed in path coordinates, or null for a shape\n * without a brush or an empty path. Throws for an unknown or non-dry brush.\n */\nexport async function renderShapeBrushstroke(shape: ShapeDescription, options: RenderShapeBrushstrokeOptions = {}): Promise<CanvasBrushstrokeImage | null> {\n\tif (!isBrushedShape(shape)) return null;\n\treturn (await loadCanvasBrushstrokeRenderer()).renderShapeBrushstrokeNow(shape, options.scale ?? 1);\n}\n\n/**\n * The brushed stroke as a standalone SVG document of `size` (the node box), with the image\n * embedded as a PNG data URL: what an SVG export writes for the node. Shapes without a brush give\n * null (export them as paths).\n */\nexport async function getBrushedShapeSvg(shape: ShapeDescription, size: ShapeSize, options: RenderShapeBrushstrokeOptions = {}): Promise<string | null> {\n\tif (!isBrushedShape(shape)) return null;\n\treturn (await loadCanvasBrushstrokeRenderer()).brushedShapeSvgNow(shape, size, options.scale ?? 2);\n}\n"]}
|
|
@@ -34,7 +34,7 @@ import {
|
|
|
34
34
|
translateSurface,
|
|
35
35
|
writeDeepRegion,
|
|
36
36
|
writeRegion
|
|
37
|
-
} from "./chunk-
|
|
37
|
+
} from "./chunk-3G6J7UFV.js";
|
|
38
38
|
|
|
39
39
|
// src/raster/effects/model.ts
|
|
40
40
|
var DEFAULT_GLOBAL_LIGHT = { angle: 120, altitude: 30 };
|
|
@@ -4314,4 +4314,4 @@ export {
|
|
|
4314
4314
|
warpSurface,
|
|
4315
4315
|
compositeSurfaceOver
|
|
4316
4316
|
};
|
|
4317
|
-
//# sourceMappingURL=chunk-
|
|
4317
|
+
//# sourceMappingURL=chunk-LLFHCSU2.js.map
|
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; } var _class; var _class2
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; } var _class; var _class2;
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
var _chunk643B2HKCcjs = require('./chunk-643B2HKC.cjs');
|
|
5
|
+
|
|
6
|
+
// src/raster/pigment.ts
|
|
2
7
|
var PIGMENT_BANDS = 36;
|
|
3
8
|
var PIGMENT_LAMBDA_MIN = 380;
|
|
4
9
|
var PIGMENT_LAMBDA_STEP = 10;
|
|
@@ -1336,6 +1341,321 @@ function keepDeepSamples(before, after) {
|
|
|
1336
1341
|
return tiles ? new TiledSurface(ch, tiles, after.defaultValue) : after;
|
|
1337
1342
|
}
|
|
1338
1343
|
|
|
1344
|
+
// src/raster/png.ts
|
|
1345
|
+
var SIGNATURE = [137, 80, 78, 71, 13, 10, 26, 10];
|
|
1346
|
+
var crcTable = null;
|
|
1347
|
+
function crc32(bytes, start, end) {
|
|
1348
|
+
if (!crcTable) {
|
|
1349
|
+
crcTable = new Uint32Array(256);
|
|
1350
|
+
for (let n = 0; n < 256; n++) {
|
|
1351
|
+
let c2 = n;
|
|
1352
|
+
for (let k = 0; k < 8; k++) c2 = c2 & 1 ? 3988292384 ^ c2 >>> 1 : c2 >>> 1;
|
|
1353
|
+
crcTable[n] = c2 >>> 0;
|
|
1354
|
+
}
|
|
1355
|
+
}
|
|
1356
|
+
let c = 4294967295;
|
|
1357
|
+
for (let i = start; i < end; i++) c = crcTable[(c ^ bytes[i]) & 255] ^ c >>> 8;
|
|
1358
|
+
return (c ^ 4294967295) >>> 0;
|
|
1359
|
+
}
|
|
1360
|
+
function paeth(a, b, c) {
|
|
1361
|
+
const p = a + b - c;
|
|
1362
|
+
const pa = Math.abs(p - a);
|
|
1363
|
+
const pb = Math.abs(p - b);
|
|
1364
|
+
const pc = Math.abs(p - c);
|
|
1365
|
+
return pa <= pb && pa <= pc ? a : pb <= pc ? b : c;
|
|
1366
|
+
}
|
|
1367
|
+
function encodePng(width, height, data, channels = 4) {
|
|
1368
|
+
const stride = width * channels;
|
|
1369
|
+
const raw = new Uint8Array((stride + 1) * height);
|
|
1370
|
+
const bpp = channels;
|
|
1371
|
+
const cand = [new Uint8Array(stride), new Uint8Array(stride), new Uint8Array(stride), new Uint8Array(stride), new Uint8Array(stride)];
|
|
1372
|
+
for (let y = 0; y < height; y++) {
|
|
1373
|
+
const row = y * stride;
|
|
1374
|
+
const prevRow = (y - 1) * stride;
|
|
1375
|
+
let best = 0;
|
|
1376
|
+
let bestScore = Infinity;
|
|
1377
|
+
for (let f = 0; f < 5; f++) {
|
|
1378
|
+
const out2 = cand[f];
|
|
1379
|
+
let score = 0;
|
|
1380
|
+
for (let x = 0; x < stride; x++) {
|
|
1381
|
+
const v = data[row + x];
|
|
1382
|
+
const a = x >= bpp ? data[row + x - bpp] : 0;
|
|
1383
|
+
const b = y > 0 ? data[prevRow + x] : 0;
|
|
1384
|
+
const c = x >= bpp && y > 0 ? data[prevRow + x - bpp] : 0;
|
|
1385
|
+
let r;
|
|
1386
|
+
switch (f) {
|
|
1387
|
+
case 0:
|
|
1388
|
+
r = v;
|
|
1389
|
+
break;
|
|
1390
|
+
case 1:
|
|
1391
|
+
r = v - a;
|
|
1392
|
+
break;
|
|
1393
|
+
case 2:
|
|
1394
|
+
r = v - b;
|
|
1395
|
+
break;
|
|
1396
|
+
case 3:
|
|
1397
|
+
r = v - (a + b >> 1);
|
|
1398
|
+
break;
|
|
1399
|
+
default:
|
|
1400
|
+
r = v - paeth(a, b, c);
|
|
1401
|
+
}
|
|
1402
|
+
r &= 255;
|
|
1403
|
+
out2[x] = r;
|
|
1404
|
+
score += r < 128 ? r : 256 - r;
|
|
1405
|
+
if (score >= bestScore) break;
|
|
1406
|
+
}
|
|
1407
|
+
if (score < bestScore) {
|
|
1408
|
+
bestScore = score;
|
|
1409
|
+
best = f;
|
|
1410
|
+
}
|
|
1411
|
+
}
|
|
1412
|
+
const o = y * (stride + 1);
|
|
1413
|
+
raw[o] = best;
|
|
1414
|
+
raw.set(cand[best], o + 1);
|
|
1415
|
+
}
|
|
1416
|
+
const idat = _chunk643B2HKCcjs.deflate.call(void 0, raw);
|
|
1417
|
+
const chunks = [];
|
|
1418
|
+
const ihdr = new Uint8Array(13);
|
|
1419
|
+
writeU32(ihdr, 0, width);
|
|
1420
|
+
writeU32(ihdr, 4, height);
|
|
1421
|
+
ihdr[8] = 8;
|
|
1422
|
+
ihdr[9] = channels === 1 ? 0 : 6;
|
|
1423
|
+
chunks.push(["IHDR", ihdr], ["IDAT", idat], ["IEND", new Uint8Array(0)]);
|
|
1424
|
+
let size = 8;
|
|
1425
|
+
for (const [, d] of chunks) size += 12 + d.length;
|
|
1426
|
+
const out = new Uint8Array(size);
|
|
1427
|
+
out.set(SIGNATURE, 0);
|
|
1428
|
+
let p = 8;
|
|
1429
|
+
for (const [type, d] of chunks) {
|
|
1430
|
+
writeU32(out, p, d.length);
|
|
1431
|
+
for (let i = 0; i < 4; i++) out[p + 4 + i] = type.charCodeAt(i);
|
|
1432
|
+
out.set(d, p + 8);
|
|
1433
|
+
writeU32(out, p + 8 + d.length, crc32(out, p + 4, p + 8 + d.length));
|
|
1434
|
+
p += 12 + d.length;
|
|
1435
|
+
}
|
|
1436
|
+
return out;
|
|
1437
|
+
}
|
|
1438
|
+
function writeU32(b, o, v) {
|
|
1439
|
+
b[o] = v >>> 24;
|
|
1440
|
+
b[o + 1] = v >>> 16 & 255;
|
|
1441
|
+
b[o + 2] = v >>> 8 & 255;
|
|
1442
|
+
b[o + 3] = v & 255;
|
|
1443
|
+
}
|
|
1444
|
+
function readU32(b, o) {
|
|
1445
|
+
return (b[o] << 24 | b[o + 1] << 16 | b[o + 2] << 8 | b[o + 3]) >>> 0;
|
|
1446
|
+
}
|
|
1447
|
+
function isPng(bytes) {
|
|
1448
|
+
return bytes.length > 8 && SIGNATURE.every((v, i) => bytes[i] === v);
|
|
1449
|
+
}
|
|
1450
|
+
function decodePng(bytes, options = {}) {
|
|
1451
|
+
if (!isPng(bytes)) throw new Error("Not a PNG image.");
|
|
1452
|
+
let p = 8;
|
|
1453
|
+
let width = 0;
|
|
1454
|
+
let height = 0;
|
|
1455
|
+
let depth = 0;
|
|
1456
|
+
let type = 0;
|
|
1457
|
+
let interlace = 0;
|
|
1458
|
+
let palette = null;
|
|
1459
|
+
let trns = null;
|
|
1460
|
+
const idat = [];
|
|
1461
|
+
while (p + 8 <= bytes.length) {
|
|
1462
|
+
const len = readU32(bytes, p);
|
|
1463
|
+
const t = String.fromCharCode(bytes[p + 4], bytes[p + 5], bytes[p + 6], bytes[p + 7]);
|
|
1464
|
+
const body = bytes.subarray(p + 8, p + 8 + len);
|
|
1465
|
+
if (p + 12 + len > bytes.length) throw new Error("Truncated PNG.");
|
|
1466
|
+
if (t === "IHDR") {
|
|
1467
|
+
width = readU32(body, 0);
|
|
1468
|
+
height = readU32(body, 4);
|
|
1469
|
+
depth = body[8];
|
|
1470
|
+
type = body[9];
|
|
1471
|
+
interlace = body[12];
|
|
1472
|
+
} else if (t === "PLTE") palette = body;
|
|
1473
|
+
else if (t === "tRNS") trns = body;
|
|
1474
|
+
else if (t === "IDAT") idat.push(body);
|
|
1475
|
+
else if (t === "IEND") break;
|
|
1476
|
+
p += 12 + len;
|
|
1477
|
+
}
|
|
1478
|
+
if (!width || !height) throw new Error("PNG has no image header.");
|
|
1479
|
+
if (interlace) throw new Error("Interlaced PNGs are not supported here; decode them with a canvas.");
|
|
1480
|
+
const maxPixels = _nullishCoalesce(options.maxPixels, () => ( 1 << 28));
|
|
1481
|
+
if (width * height > maxPixels) throw new Error(`PNG is too large (${width}\xD7${height}).`);
|
|
1482
|
+
const samples = type === 0 ? 1 : type === 2 ? 3 : type === 3 ? 1 : type === 4 ? 2 : type === 6 ? 4 : 0;
|
|
1483
|
+
if (!samples || ![1, 2, 4, 8, 16].includes(depth)) throw new Error(`Unsupported PNG format (type ${type}, depth ${depth}).`);
|
|
1484
|
+
let total = 0;
|
|
1485
|
+
for (const c of idat) total += c.length;
|
|
1486
|
+
const z = new Uint8Array(total);
|
|
1487
|
+
let o = 0;
|
|
1488
|
+
for (const c of idat) {
|
|
1489
|
+
z.set(c, o);
|
|
1490
|
+
o += c.length;
|
|
1491
|
+
}
|
|
1492
|
+
const bitsPerPixel = samples * depth;
|
|
1493
|
+
const stride = Math.ceil(width * bitsPerPixel / 8);
|
|
1494
|
+
const raw = _chunk643B2HKCcjs.inflate.call(void 0, z, { maxOutput: (stride + 1) * height, sizeHint: (stride + 1) * height });
|
|
1495
|
+
if (raw.length < (stride + 1) * height) throw new Error("PNG image data is truncated.");
|
|
1496
|
+
const bpp = Math.max(1, bitsPerPixel >> 3);
|
|
1497
|
+
const lines = new Uint8Array(stride * height);
|
|
1498
|
+
for (let y = 0; y < height; y++) {
|
|
1499
|
+
const f = raw[y * (stride + 1)];
|
|
1500
|
+
const src = y * (stride + 1) + 1;
|
|
1501
|
+
const dst = y * stride;
|
|
1502
|
+
const up = dst - stride;
|
|
1503
|
+
for (let x = 0; x < stride; x++) {
|
|
1504
|
+
const v = raw[src + x];
|
|
1505
|
+
const a = x >= bpp ? lines[dst + x - bpp] : 0;
|
|
1506
|
+
const b = y > 0 ? lines[up + x] : 0;
|
|
1507
|
+
const c = x >= bpp && y > 0 ? lines[up + x - bpp] : 0;
|
|
1508
|
+
let r;
|
|
1509
|
+
switch (f) {
|
|
1510
|
+
case 0:
|
|
1511
|
+
r = v;
|
|
1512
|
+
break;
|
|
1513
|
+
case 1:
|
|
1514
|
+
r = v + a;
|
|
1515
|
+
break;
|
|
1516
|
+
case 2:
|
|
1517
|
+
r = v + b;
|
|
1518
|
+
break;
|
|
1519
|
+
case 3:
|
|
1520
|
+
r = v + (a + b >> 1);
|
|
1521
|
+
break;
|
|
1522
|
+
case 4:
|
|
1523
|
+
r = v + paeth(a, b, c);
|
|
1524
|
+
break;
|
|
1525
|
+
default:
|
|
1526
|
+
throw new Error(`Invalid PNG filter ${f}.`);
|
|
1527
|
+
}
|
|
1528
|
+
lines[dst + x] = r & 255;
|
|
1529
|
+
}
|
|
1530
|
+
}
|
|
1531
|
+
const sample = (y, i) => {
|
|
1532
|
+
const row = y * stride;
|
|
1533
|
+
if (depth === 8) return lines[row + i];
|
|
1534
|
+
if (depth === 16) return lines[row + i * 2];
|
|
1535
|
+
const perByte = 8 / depth;
|
|
1536
|
+
const byte = lines[row + Math.floor(i / perByte)];
|
|
1537
|
+
const shift = 8 - depth * (i % perByte + 1);
|
|
1538
|
+
const v = byte >> shift & (1 << depth) - 1;
|
|
1539
|
+
return type === 3 ? v : Math.round(v * 255 / ((1 << depth) - 1));
|
|
1540
|
+
};
|
|
1541
|
+
const gray = options.keepGray && type === 0 && !trns;
|
|
1542
|
+
const channels = gray ? 1 : 4;
|
|
1543
|
+
const out = new Uint8ClampedArray(width * height * channels);
|
|
1544
|
+
const trnsGray = trns && type === 0 ? depth === 16 ? trns[0] : sample16(trns, 0, depth) : -1;
|
|
1545
|
+
const trnsRgb = trns && type === 2 ? [0, 1, 2].map((k) => depth === 16 ? trns[k * 2] : sample16(trns, k, depth)) : null;
|
|
1546
|
+
for (let y = 0; y < height; y++) {
|
|
1547
|
+
for (let x = 0; x < width; x++) {
|
|
1548
|
+
const d = (y * width + x) * channels;
|
|
1549
|
+
if (type === 0) {
|
|
1550
|
+
const v = sample(y, x);
|
|
1551
|
+
if (gray) out[d] = v;
|
|
1552
|
+
else {
|
|
1553
|
+
out[d] = out[d + 1] = out[d + 2] = v;
|
|
1554
|
+
out[d + 3] = v === trnsGray && trns ? 0 : 255;
|
|
1555
|
+
}
|
|
1556
|
+
} else if (type === 2) {
|
|
1557
|
+
const r = sample(y, x * 3);
|
|
1558
|
+
const g = sample(y, x * 3 + 1);
|
|
1559
|
+
const b = sample(y, x * 3 + 2);
|
|
1560
|
+
out[d] = r;
|
|
1561
|
+
out[d + 1] = g;
|
|
1562
|
+
out[d + 2] = b;
|
|
1563
|
+
out[d + 3] = trnsRgb && r === trnsRgb[0] && g === trnsRgb[1] && b === trnsRgb[2] ? 0 : 255;
|
|
1564
|
+
} else if (type === 3) {
|
|
1565
|
+
const i = sample(y, x);
|
|
1566
|
+
if (!palette || i * 3 + 2 >= palette.length) throw new Error("PNG palette index out of range.");
|
|
1567
|
+
out[d] = palette[i * 3];
|
|
1568
|
+
out[d + 1] = palette[i * 3 + 1];
|
|
1569
|
+
out[d + 2] = palette[i * 3 + 2];
|
|
1570
|
+
out[d + 3] = trns && i < trns.length ? trns[i] : 255;
|
|
1571
|
+
} else if (type === 4) {
|
|
1572
|
+
const v = sample(y, x * 2);
|
|
1573
|
+
out[d] = out[d + 1] = out[d + 2] = v;
|
|
1574
|
+
out[d + 3] = sample(y, x * 2 + 1);
|
|
1575
|
+
} else {
|
|
1576
|
+
out[d] = sample(y, x * 4);
|
|
1577
|
+
out[d + 1] = sample(y, x * 4 + 1);
|
|
1578
|
+
out[d + 2] = sample(y, x * 4 + 2);
|
|
1579
|
+
out[d + 3] = sample(y, x * 4 + 3);
|
|
1580
|
+
}
|
|
1581
|
+
}
|
|
1582
|
+
}
|
|
1583
|
+
return { width, height, channels, data: out };
|
|
1584
|
+
}
|
|
1585
|
+
function sample16(trns, k, depth) {
|
|
1586
|
+
const v = trns[k * 2] << 8 | trns[k * 2 + 1];
|
|
1587
|
+
if (depth === 8) return v & 255;
|
|
1588
|
+
return Math.round((v & (1 << depth) - 1) * 255 / ((1 << depth) - 1));
|
|
1589
|
+
}
|
|
1590
|
+
var B64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
1591
|
+
var B64_INV = null;
|
|
1592
|
+
function bytesToBase64(bytes) {
|
|
1593
|
+
const parts = [];
|
|
1594
|
+
const CHUNK = 3 * 4096;
|
|
1595
|
+
for (let start = 0; start < bytes.length; start += CHUNK) {
|
|
1596
|
+
const end = Math.min(bytes.length, start + CHUNK);
|
|
1597
|
+
let s = "";
|
|
1598
|
+
let i = start;
|
|
1599
|
+
for (; i + 2 < end; i += 3) {
|
|
1600
|
+
const n = bytes[i] << 16 | bytes[i + 1] << 8 | bytes[i + 2];
|
|
1601
|
+
s += B64[n >> 18] + B64[n >> 12 & 63] + B64[n >> 6 & 63] + B64[n & 63];
|
|
1602
|
+
}
|
|
1603
|
+
if (i < end) {
|
|
1604
|
+
const n = bytes[i] << 16 | (i + 1 < end ? bytes[i + 1] << 8 : 0);
|
|
1605
|
+
s += B64[n >> 18] + B64[n >> 12 & 63] + (i + 1 < end ? B64[n >> 6 & 63] : "=") + "=";
|
|
1606
|
+
}
|
|
1607
|
+
parts.push(s);
|
|
1608
|
+
}
|
|
1609
|
+
return parts.join("");
|
|
1610
|
+
}
|
|
1611
|
+
function base64ToBytes(text) {
|
|
1612
|
+
if (!B64_INV) {
|
|
1613
|
+
B64_INV = new Int16Array(128).fill(-1);
|
|
1614
|
+
for (let i = 0; i < 64; i++) B64_INV[B64.charCodeAt(i)] = i;
|
|
1615
|
+
B64_INV["-".charCodeAt(0)] = 62;
|
|
1616
|
+
B64_INV["_".charCodeAt(0)] = 63;
|
|
1617
|
+
}
|
|
1618
|
+
const inv = B64_INV;
|
|
1619
|
+
const clean = text.replace(/[\s=]/g, "");
|
|
1620
|
+
const out = new Uint8Array(Math.floor(clean.length * 3 / 4));
|
|
1621
|
+
let bits = 0;
|
|
1622
|
+
let acc = 0;
|
|
1623
|
+
let o = 0;
|
|
1624
|
+
for (let i = 0; i < clean.length; i++) {
|
|
1625
|
+
const c = clean.charCodeAt(i);
|
|
1626
|
+
const v = c < 128 ? inv[c] : -1;
|
|
1627
|
+
if (v < 0) throw new Error("Invalid base64 data.");
|
|
1628
|
+
acc = acc << 6 | v;
|
|
1629
|
+
bits += 6;
|
|
1630
|
+
if (bits >= 8) {
|
|
1631
|
+
bits -= 8;
|
|
1632
|
+
out[o++] = acc >> bits & 255;
|
|
1633
|
+
}
|
|
1634
|
+
}
|
|
1635
|
+
return out.subarray(0, o);
|
|
1636
|
+
}
|
|
1637
|
+
function parseDataUrl(url) {
|
|
1638
|
+
const m = /^data:([^;,]*)((?:;[^;,]*)*?),/i.exec(url);
|
|
1639
|
+
if (!m) return null;
|
|
1640
|
+
const body = url.slice(m[0].length);
|
|
1641
|
+
const isBase64 = /;base64/i.test(m[2]);
|
|
1642
|
+
if (isBase64) return { mime: m[1] || "text/plain", bytes: base64ToBytes(body) };
|
|
1643
|
+
const text = decodeURIComponent(body);
|
|
1644
|
+
const bytes = new Uint8Array(text.length);
|
|
1645
|
+
for (let i = 0; i < text.length; i++) bytes[i] = text.charCodeAt(i) & 255;
|
|
1646
|
+
return { mime: m[1] || "text/plain", bytes };
|
|
1647
|
+
}
|
|
1648
|
+
function pngDataUrl(width, height, data, channels = 4) {
|
|
1649
|
+
return `data:image/png;base64,${bytesToBase64(encodePng(width, height, data, channels))}`;
|
|
1650
|
+
}
|
|
1651
|
+
|
|
1652
|
+
|
|
1653
|
+
|
|
1654
|
+
|
|
1655
|
+
|
|
1656
|
+
|
|
1657
|
+
|
|
1658
|
+
|
|
1339
1659
|
|
|
1340
1660
|
|
|
1341
1661
|
|
|
@@ -1412,5 +1732,5 @@ function keepDeepSamples(before, after) {
|
|
|
1412
1732
|
|
|
1413
1733
|
|
|
1414
1734
|
|
|
1415
|
-
exports.PIGMENT_BANDS = PIGMENT_BANDS; exports.PIGMENT_LAMBDA_MIN = PIGMENT_LAMBDA_MIN; exports.PIGMENT_LAMBDA_STEP = PIGMENT_LAMBDA_STEP; exports.PIGMENT_WAVELENGTHS = PIGMENT_WAVELENGTHS; exports.rgbToReflectance = rgbToReflectance; exports.reflectanceToRgb = reflectanceToRgb; exports.createPigment = createPigment; exports.setPigmentColor = setPigmentColor; exports.mixPigments = mixPigments; exports.lerpPigment = lerpPigment; exports.lerpPigmentInto = lerpPigmentInto; exports.BLEND_MODES = BLEND_MODES; exports.isBlendMode = isBlendMode; exports.PAINTERLY_BLEND_MODES = PAINTERLY_BLEND_MODES; exports.isPainterlyBlendMode = isPainterlyBlendMode; exports.standardBlendMode = standardBlendMode; exports.normalizeBlendMode = normalizeBlendMode; exports.canvasCompositeOperation = canvasCompositeOperation; exports.isSeparableBlendMode = isSeparableBlendMode; exports.blendChannel = blendChannel; exports.blendLum = blendLum; exports.setLum = setLum; exports.blendRgb = blendRgb; exports.SHADOW_AMBIENT = SHADOW_AMBIENT; exports.mixPigmentRgb = mixPigmentRgb; exports.pigment8 = pigment8; exports.mixPigment8 = mixPigment8; exports.blendPixel = blendPixel; exports.blendImageData = blendImageData; exports.TILE = TILE; exports.TILE_SHIFT = TILE_SHIFT; exports.tileKey = tileKey; exports.tileCoord = tileCoord; exports.tileRect = tileRect; exports.TiledSurface = TiledSurface; exports.uniformTile = uniformTile; exports.packRgba = packRgba; exports.finishTile = finishTile; exports.emptySurface = emptySurface; exports.solidSurface = solidSurface; exports.surfaceFromPixels = surfaceFromPixels; exports.tilesInRect = tilesInRect; exports.readRegion = readRegion; exports.readPixel = readPixel; exports.contentBounds = contentBounds; exports.SurfaceDraft = SurfaceDraft; exports.writeRegion = writeRegion; exports.fillRect = fillRect; exports.translateSurface = translateSurface; exports.surfaceBytes = surfaceBytes; exports.collectTiles = collectTiles; exports.surfacesEqual = surfacesEqual; exports.BIT_DEPTHS = BIT_DEPTHS; exports.isBitDepth = isBitDepth; exports.srgbDecode = srgbDecode; exports.srgbEncode = srgbEncode; exports.to16From8 = to16From8; exports.to32From8 = to32From8; exports.to32From16 = to32From16; exports.to16From32 = to16From32; exports.to8From16 = to8From16; exports.to8From32 = to8From32; exports.proxyOf = proxyOf; exports.depthOf = depthOf; exports.deepTile = deepTile; exports.tileSamples16 = tileSamples16; exports.tileSamples32 = tileSamples32; exports.tileSamples = tileSamples; exports.surfaceDepth = surfaceDepth; exports.readDeepRegion = readDeepRegion; exports.writeDeepRegion = writeDeepRegion; exports.surfaceFromDeepPixels = surfaceFromDeepPixels; exports.convertSurfaceDepth = convertSurfaceDepth; exports.deepBytes = deepBytes; exports.keepDeepSamples = keepDeepSamples;
|
|
1416
|
-
//# sourceMappingURL=chunk-
|
|
1735
|
+
exports.PIGMENT_BANDS = PIGMENT_BANDS; exports.PIGMENT_LAMBDA_MIN = PIGMENT_LAMBDA_MIN; exports.PIGMENT_LAMBDA_STEP = PIGMENT_LAMBDA_STEP; exports.PIGMENT_WAVELENGTHS = PIGMENT_WAVELENGTHS; exports.rgbToReflectance = rgbToReflectance; exports.reflectanceToRgb = reflectanceToRgb; exports.createPigment = createPigment; exports.setPigmentColor = setPigmentColor; exports.mixPigments = mixPigments; exports.lerpPigment = lerpPigment; exports.lerpPigmentInto = lerpPigmentInto; exports.BLEND_MODES = BLEND_MODES; exports.isBlendMode = isBlendMode; exports.PAINTERLY_BLEND_MODES = PAINTERLY_BLEND_MODES; exports.isPainterlyBlendMode = isPainterlyBlendMode; exports.standardBlendMode = standardBlendMode; exports.normalizeBlendMode = normalizeBlendMode; exports.canvasCompositeOperation = canvasCompositeOperation; exports.isSeparableBlendMode = isSeparableBlendMode; exports.blendChannel = blendChannel; exports.blendLum = blendLum; exports.setLum = setLum; exports.blendRgb = blendRgb; exports.SHADOW_AMBIENT = SHADOW_AMBIENT; exports.mixPigmentRgb = mixPigmentRgb; exports.pigment8 = pigment8; exports.mixPigment8 = mixPigment8; exports.blendPixel = blendPixel; exports.blendImageData = blendImageData; exports.TILE = TILE; exports.TILE_SHIFT = TILE_SHIFT; exports.tileKey = tileKey; exports.tileCoord = tileCoord; exports.tileRect = tileRect; exports.TiledSurface = TiledSurface; exports.uniformTile = uniformTile; exports.packRgba = packRgba; exports.finishTile = finishTile; exports.emptySurface = emptySurface; exports.solidSurface = solidSurface; exports.surfaceFromPixels = surfaceFromPixels; exports.tilesInRect = tilesInRect; exports.readRegion = readRegion; exports.readPixel = readPixel; exports.contentBounds = contentBounds; exports.SurfaceDraft = SurfaceDraft; exports.writeRegion = writeRegion; exports.fillRect = fillRect; exports.translateSurface = translateSurface; exports.surfaceBytes = surfaceBytes; exports.collectTiles = collectTiles; exports.surfacesEqual = surfacesEqual; exports.BIT_DEPTHS = BIT_DEPTHS; exports.isBitDepth = isBitDepth; exports.srgbDecode = srgbDecode; exports.srgbEncode = srgbEncode; exports.to16From8 = to16From8; exports.to32From8 = to32From8; exports.to32From16 = to32From16; exports.to16From32 = to16From32; exports.to8From16 = to8From16; exports.to8From32 = to8From32; exports.proxyOf = proxyOf; exports.depthOf = depthOf; exports.deepTile = deepTile; exports.tileSamples16 = tileSamples16; exports.tileSamples32 = tileSamples32; exports.tileSamples = tileSamples; exports.surfaceDepth = surfaceDepth; exports.readDeepRegion = readDeepRegion; exports.writeDeepRegion = writeDeepRegion; exports.surfaceFromDeepPixels = surfaceFromDeepPixels; exports.convertSurfaceDepth = convertSurfaceDepth; exports.deepBytes = deepBytes; exports.keepDeepSamples = keepDeepSamples; exports.encodePng = encodePng; exports.isPng = isPng; exports.decodePng = decodePng; exports.bytesToBase64 = bytesToBase64; exports.base64ToBytes = base64ToBytes; exports.parseDataUrl = parseDataUrl; exports.pngDataUrl = pngDataUrl;
|
|
1736
|
+
//# sourceMappingURL=chunk-O7LUD7MH.cjs.map
|