@rig-c/play 0.0.0-stage → 1.8.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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["../src/pixelRatio.ts","../node_modules/rig-c/src/core/world.ts","../node_modules/rig-c/src/core/skins.ts","../node_modules/rig-c/src/core/deform.ts","../node_modules/rig-c/src/core/draw_order.ts","../node_modules/rig-c/src/core/events.ts","../node_modules/rig-c/src/core/clipping.ts","../node_modules/rig-c/src/core/vertices.ts","../node_modules/rig-c/src/core/constraints_path.ts","../node_modules/rig-c/src/core/constraints_physics.ts","../node_modules/rig-c/src/core/constraints_slider.ts","../node_modules/rig-c/src/core/constraints.ts","../node_modules/rig-c/src/core/animation.ts","../node_modules/rig-c/src/core/index.ts","../node_modules/rig-c/src/core/raw.ts","../node_modules/rig-c/src/core/track.ts","../node_modules/rig-c/src/core/tracks.ts","../node_modules/rig-c/src/core/uvs.ts","../src/DomTexture.ts","../src/MeshGlBlitter.ts","../src/DomRenderer.ts","../src/CanvasRenderer.ts","../src/loadModel.ts","../src/posedFrame.ts","../src/player.ts"],"sourcesContent":["/**\n * The one forced layout both renderers share: how many device pixels one of\n * the root's CSS pixels covers on screen, read off a throwaway box.\n *\n * A renderer rasters at `world × pixelRatio` in the root's own coordinates,\n * so a `transform: scale(z)` on an ancestor — how a pan/zoom stage is built —\n * oversamples by 1/z² in backing pixels unless the zoom is folded into the\n * ratio. Neither renderer measures this on its own: it is a layout read, and\n * there is no per-frame layout read anywhere in this library. The caller\n * invokes `syncPixelRatio()` when a zoom or a resize settles.\n */\n\n/** Edge length of the throwaway box the root is measured with. */\nconst SCALE_PROBE_PX = 100;\n/**\n * Relative change below which the ratio is left alone. Layout reads are\n * quantized (1/64 px in Blink), so a 100 px probe carries ~0.016% of\n * measurement noise — 6× under this band, which in turn is 10× under the\n * smallest zoom step a UI realistically takes (1%). Inside the band the\n * sampling error is worth ~0.2% of backing pixels; outside it, a rewrite of\n * `pixelRatio` recreates every canvas's GPU surface.\n */\nconst PIXEL_RATIO_DEADBAND = 1e-3;\n\n/**\n * Measures `root`'s effective on-screen scale once and returns the ratio now\n * in effect: `devicePixelRatio × scale` when that differs from `current` by\n * more than the deadband, else `current` unchanged. A root that is not laid\n * out (a `display: none` ancestor, a detached root) measures nothing, so\n * nothing is decided and `current` comes back. Appends a hidden box to the\n * root, reads its rect, removes it — the root's children are the same\n * elements in the same order on both sides of the call.\n */\nexport function syncedPixelRatio(root: HTMLElement, current: number): number {\n const probe = document.createElement('div');\n probe.style.position = 'absolute';\n probe.style.left = '0';\n probe.style.top = '0';\n probe.style.width = `${SCALE_PROBE_PX}px`;\n probe.style.height = `${SCALE_PROBE_PX}px`;\n probe.style.visibility = 'hidden';\n probe.style.pointerEvents = 'none';\n root.appendChild(probe);\n let width = 0;\n let height = 0;\n try {\n const rect = probe.getBoundingClientRect();\n width = rect.width;\n height = rect.height;\n } finally {\n probe.remove();\n }\n\n const scale = Math.max(width, height) / SCALE_PROBE_PX;\n if (!(scale > 0)) return current;\n\n const dpr = typeof devicePixelRatio === 'number' ? devicePixelRatio : 1;\n const next = dpr * scale;\n if (current > 0 && Math.abs(next - current) < current * PIXEL_RATIO_DEADBAND) return current;\n return next;\n}\n","/**\n * The core's own setup evaluator: every bone's world matrix and origin from\n * the compiled model's bones (issue #925). Written from what a bone's fields\n * mean and from measurement against the runtime's pose dump\n * (`tools/pose_oracle.ts dump`, spine-core 4.3.13), and held to it by the core\n * suite's equivalence controls.\n *\n * ⭐ **The compiler's setup transforms are this evaluator too** (issue #1015),\n * under the same arithmetic (issue #1021). `src/transform.ts` held a second\n * evaluator of its own until #1015, and the two differed in exactly three\n * places, none of them a different matrix: the degree factor (`Math.PI / 180`\n * there, the runtime's 3.1415927 here), the frame of a bone with scale 1 and\n * no shear (`[cos, −sin, sin, cos]` of the rotation there, the y column at\n * `rotation + 90` here), and how a radian angle is turned into degrees\n * (divided by the degree factor there, multiplied by `180 / pi` here). #1015\n * made them a parameter (`WorldArithmetic`) so that no byte moved; #1021\n * measured which binds closer — every point the compiler binds from a world\n * position, posed by spine-core from the emitted build, against that position\n * — and the runtime's three put every one at the float32 floor where the\n * compiler's left `gallery/look`'s up to 8.6e-5 off. So the compiler passes\n * none now, and `RUNTIME_ARITHMETIC`, the measured choices below, is the only\n * arithmetic anything here runs under; the parameter stays for the plants\n * that swap one choice back in to show a control fire.\n *\n * ## What each measured choice is\n *\n * - **Degrees to radians with pi written 3.1415927.** The runtime's root bone\n * at rotation 0 reads `b = -2.3205103333142417e-8` and\n * `d = 0.9999999999999998`: `cos` and `sin` of 90 degrees converted with\n * pi = 3.1415927, since `(3.1415927 - pi) / 2 = 2.3205e-8`. It is that\n * decimal in double arithmetic — not float32: pi rounded to float32 would\n * give `4.37e-8`, and the bone fields read through `Math.fround` moved the\n * dump further, not closer (measured on the nineteen recipes).\n * - **The degree factor is taken once**, `pi / 180`, and every angle is\n * multiplied by it.\n * - **The y column is `cos(rotation + 90 + shearY)` and `sin(…)` on every\n * bone**, never `-sin`/`cos` of the rotation. With the constant above but\n * the `-sin` form, `2-the-12-principles` stays 61 millionths off.\n * - **A root bone is its local matrix at its own `x`, `y`**: the skeleton is\n * at the origin, unscaled, in every dump taken.\n *\n * Both halves together read IDENTICAL, worst delta exactly 0, on the 12\n * recipes without constraints (`tools/core_gate.ts`); either half alone is\n * exact on none of them.\n *\n * ## The five inherit modes\n *\n * What each mode takes from the parent, as the format's documentation words\n * it, then how it is computed here. A child's ORIGIN is always the parent's\n * matrix applied to the local `x`, `y` plus the parent's origin — the modes\n * change only the matrix.\n *\n * - `normal` — everything: parent matrix times local matrix.\n * - `onlyTranslation` — the parent's position only: the local matrix alone.\n * - `noRotationOrReflection` — the parent's scale (and what shear leaves of\n * it), not its rotation and not a reflection. The parent's matrix is made\n * conformal on its x axis: that axis kept, the y axis turned to 90 degrees\n * from it with length `|det| / |x axis|` (so the area, the scale the parent\n * carries, is kept and its sign is not); the local matrix is built at the\n * bone's rotation MINUS the parent's x-axis angle; the product is the world.\n * ⚠️ **A parent x axis whose squared length is at most `1e-5` squared is\n * collapsed** (issue #979, `COLLAPSED_X_AXIS_SQ`): the conformal frame is\n * then the parent's y column with its x component negated, beside a zero x\n * column, and the local matrix is built at the rotation less 90 plus the y\n * column's angle, summed in that order. Measured on a child of such a\n * parent: by bisection on the x axis's length, 1e-5 reads collapsed and the\n * next double above does not, at parent rotations 0, 30 and 45 (whether the\n * runtime compares the squared length with `1e-5 · 1e-5` or the length with\n * `1e-5`, 200,000 parents searched separated no pair); 480 probes of x axes\n * from 1e-4 down to 1e-20 and 0 under y axes up to 2e17, sheared, scaled and\n * reflected, read exact, where the reading this replaced (collapsed only at\n * length 0, the y column as it is, the angle less 90) read 71 of 96 off and\n * the rotation-first sum `rotation − (90 − angle)` 10 of 480. The zero\n * matrix of a bone below an inactive one is the collapsed case at length 0,\n * and it fixes the signs of zero of every child in this mode there (`CC13`).\n * - `noScale` — the parent's rotation (and reflection), not its scale: the\n * bone's local rotation is carried through the parent's matrix as a\n * direction, normalised to unit length; the y axis is that direction turned\n * 90 degrees, turned the other way when the parent reflects (`det < 0`);\n * the bone's own shear and scale are applied on that frame.\n * - `noScaleOrReflection` — as `noScale`, never turned for a reflection.\n *\n * ## To the bit (issue #966)\n *\n * The rules above were measured on the oracle's six-decimal grid; three of\n * the modes matched it and not the runtime's last bit (issue #959). Held\n * against `pose_oracle.ts dump --raw` at tolerance 0 — a bone in the mode\n * under a parent rotated, scaled, sheared and reflecting, two children 1e9\n * units out (the core suite's `CR02`, 300 per mode) — three operation orders\n * are the runtime's and the grid could not tell them:\n *\n * - a radian angle is turned into degrees by multiplying with `180 / pi`\n * (`RUNTIME_DEG`), not by dividing by `pi / 180`: the division read 106\n * of 300 `noRotationOrReflection` bones off;\n * - `noRotationOrReflection`'s y angle is `r + shearY + 90`, the shear\n * added before the right angle (`r + 90 + shearY` read 46 of 300 off);\n * - `noScale`'s direction is normalised by multiplying with the reciprocal\n * of its length (dividing read 138 of 300 off).\n *\n * Measured: `normal` on 12 recipes, `onlyTranslation` on 1 and\n * `noRotationOrReflection` on 2 of the tree's corpus; all five, under rotated,\n * scaled, sheared and reflecting parents, on the hand-written probe the core\n * suite builds (`CO07`), because the corpus reaches `noScale` only on a rig\n * with constraints and `noScaleOrReflection` on none.\n */\nimport type { ModelBone } from '../model.ts';\n\n/** Pi as the runtime converts degrees with it — see the header. */\nexport const RUNTIME_PI = 3.1415927;\nconst RAD = RUNTIME_PI / 180;\n/** Radians to degrees as the runtime converts them (issue #966): multiplied by `180 / pi`, not divided by `pi / 180` — the two differ in the last bit. */\nexport const RUNTIME_DEG = 180 / RUNTIME_PI;\n\n/** A parent x axis whose squared length is at most this is collapsed for `noRotationOrReflection` (issue #979): `1e-5` squared, as measured — see the header. */\nexport const COLLAPSED_X_AXIS_SQ = 0.00001 * 0.00001;\n\n/**\n * The three places an evaluator's arithmetic may differ in the last bit while\n * computing the same matrix (issue #1015) — see the header. The core poses and\n * the compiler binds with `RUNTIME_ARITHMETIC` (issue #1021); another value is\n * a plant's.\n */\nexport interface WorldArithmetic {\n /** Degrees to radians: every angle is multiplied by it. */\n radiansPerDegree: number;\n /** Radians to degrees — the angle `noRotationOrReflection` takes off a parent's axis. */\n degreesOf: (radians: number) => number;\n /** A bone with scale 1 and no shear takes `[cos r, −sin r, sin r, cos r]` instead of the y column at `r + 90`; the general frame everywhere else. */\n rotationOnlyFrame: boolean;\n}\n\n/** The runtime's arithmetic, as measured (the header's three choices): what the core poses with. */\nexport const RUNTIME_ARITHMETIC: WorldArithmetic = {\n radiansPerDegree: RAD,\n degreesOf: (radians) => radians * RUNTIME_DEG,\n rotationOnlyFrame: false,\n};\n\n/** One bone's world transform: the matrix `[a b; c d]` and the origin, y up. */\nexport interface CoreWorld {\n a: number;\n b: number;\n c: number;\n d: number;\n worldX: number;\n worldY: number;\n}\n\n/** The five modes, after the first-letter fold the rig spec admits. */\nexport type CoreInheritMode = 'normal' | 'onlyTranslation' | 'noRotationOrReflection' | 'noScale' | 'noScaleOrReflection';\n\nexport type M2 = [number, number, number, number];\n\n/** What computes a child's world matrix from its mode, its parent's world, its own fields and the arithmetic in force. */\nexport type InheritComputation = (mode: CoreInheritMode, parent: CoreWorld, bone: ModelBone, arithmetic: WorldArithmetic) => M2;\n\n/** The matrix of a rotation, shears and scales, in the column form the header states. */\nfunction frame(rotation: number, shearX: number, shearY: number, scaleX: number, scaleY: number, rad: number = RAD): M2 {\n const xAngle = (rotation + shearX) * rad;\n const yAngle = (rotation + 90 + shearY) * rad;\n return [Math.cos(xAngle) * scaleX, Math.cos(yAngle) * scaleY, Math.sin(xAngle) * scaleX, Math.sin(yAngle) * scaleY];\n}\n\n/** A bone's own frame — a root's matrix, and the local factor of `normal` and `onlyTranslation` — under `arithmetic`. */\nfunction localFrame(arithmetic: WorldArithmetic, rotation: number, shearX: number, shearY: number, scaleX: number, scaleY: number): M2 {\n const rad = arithmetic.radiansPerDegree;\n if (arithmetic.rotationOnlyFrame && scaleX === 1 && scaleY === 1 && shearX === 0 && shearY === 0) {\n const cos = Math.cos(rotation * rad);\n const sin = Math.sin(rotation * rad);\n return [cos, -sin, sin, cos];\n }\n return frame(rotation, shearX, shearY, scaleX, scaleY, rad);\n}\n\nfunction times(p: M2, q: M2): M2 {\n return [p[0] * q[0] + p[1] * q[2], p[0] * q[1] + p[1] * q[3], p[2] * q[0] + p[3] * q[2], p[2] * q[1] + p[3] * q[3]];\n}\n\n/**\n * The unit direction a `noScale` / `noScaleOrReflection` bone's x axis takes:\n * its local rotation carried through the parent's matrix and normalised. Shared\n * by the forward frame and `localFromWorld`'s read-back (`./constraints.ts`),\n * which builds the frame to read the bone's columns in from the rotation it\n * has just read, through this same arithmetic (issue #966).\n */\nexport function noScaleDirection(p: M2, rotation: number, rad: number = RAD): [number, number] {\n const r = rotation * rad;\n const cos = Math.cos(r);\n const sin = Math.sin(r);\n const ux = p[0] * cos + p[1] * sin;\n const uy = p[2] * cos + p[3] * sin;\n // Normalised by multiplying with the reciprocal of the length, not by dividing by it (issue #966): the division reads 1 ulp off on 375 bone-samples of the corpus's `noScale` row.\n const inverse = 1 / Math.sqrt(ux * ux + uy * uy);\n return [ux * inverse, uy * inverse];\n}\n\n/** The world matrix of a child under `parent` in `mode`, under `arithmetic` (the runtime's unless a caller passes its own). */\nfunction modeMatrix(mode: CoreInheritMode, parent: CoreWorld, bone: ModelBone, arithmetic: WorldArithmetic = RUNTIME_ARITHMETIC): M2 {\n const rotation = bone.rotation ?? 0;\n const shearX = bone.shearX ?? 0;\n const shearY = bone.shearY ?? 0;\n const scaleX = bone.scaleX ?? 1;\n const scaleY = bone.scaleY ?? 1;\n const rad = arithmetic.radiansPerDegree;\n const p: M2 = [parent.a, parent.b, parent.c, parent.d];\n switch (mode) {\n case 'normal':\n return times(p, localFrame(arithmetic, rotation, shearX, shearY, scaleX, scaleY));\n case 'onlyTranslation':\n return localFrame(arithmetic, rotation, shearX, shearY, scaleX, scaleY);\n case 'noRotationOrReflection': {\n const xLengthSq = p[0] * p[0] + p[2] * p[2];\n let conformal: M2;\n let r: number;\n if (xLengthSq > COLLAPSED_X_AXIS_SQ) {\n const k = Math.abs(p[0] * p[3] - p[1] * p[2]) / xLengthSq;\n conformal = [p[0], -p[2] * k, p[2], p[0] * k];\n r = rotation - arithmetic.degreesOf(Math.atan2(p[2], p[0]));\n } else {\n // A collapsed x axis (issue #979): the parent's y column with its x component negated, and the rotation less 90 plus the y column's angle — see the header.\n conformal = [0, -p[1], 0, p[3]];\n r = rotation - 90 + arithmetic.degreesOf(Math.atan2(p[3], p[1]));\n }\n // The y angle adds the shear before the right angle here, unlike `frame` (issue #966): `(r + 90 + shearY)` reads last-bit off on 81 of 205 sheared or scaled bones at a 1e9 amplifier, `(r + shearY + 90)` on none; `r = rotation − parentAngle` taken first (adding the shear before the parent's angle is taken off reads 102 of 205 off).\n const xAngle = (r + shearX) * rad;\n const yAngle = (r + shearY + 90) * rad;\n return times(conformal, [Math.cos(xAngle) * scaleX, Math.cos(yAngle) * scaleY, Math.sin(xAngle) * scaleX, Math.sin(yAngle) * scaleY]);\n }\n case 'noScale':\n case 'noScaleOrReflection': {\n const [ux, uy] = noScaleDirection(p, rotation, rad);\n const flip = mode === 'noScale' && p[0] * p[3] - p[1] * p[2] < 0 ? -1 : 1;\n const turned: M2 = [ux, -uy * flip, uy, ux * flip];\n return times(turned, frame(0, shearX, shearY, scaleX, scaleY, rad));\n }\n }\n}\n\n/** The fold the rig spec admits: the first letter lower-cased; anything else is not a mode. */\nfunction modeOf(bone: ModelBone): CoreInheritMode {\n const stated = bone.inheritMode;\n if (stated === undefined) return 'normal';\n const folded = stated.length === 0 ? stated : stated[0].toLowerCase() + stated.slice(1);\n if (folded === 'normal' || folded === 'onlyTranslation' || folded === 'noRotationOrReflection' || folded === 'noScale' || folded === 'noScaleOrReflection') return folded;\n throw new Error(`bone \"${bone.name}\": inheritMode ${JSON.stringify(stated)} is no mode (readModel refuses it first)`);\n}\n\n/**\n * Every bone's setup world transform, parents first as the model lists them.\n *\n * `active`, when given, is the set of bones the applied skins leave active; a\n * bone outside it is not posed. Measured on a hand-written skeleton: the\n * runtime's dump reads an inactive bone as all zeros — matrix and origin, its\n * world as a skeleton is created — and a bone under it, active or not, is\n * posed from those zeros like any child. `inherit` replaces the mode\n * computation — the core suite's plant passes a copy with one mode's sign\n * flipped, and nothing else does. `arithmetic` is the runtime's unless a\n * caller states its own, and only a plant does: `src/transform.ts` takes the\n * default since issue #1021, as every posing path does.\n */\nexport function worldTransforms(\n bones: readonly ModelBone[],\n active: ReadonlySet<string> | null = null,\n inherit: InheritComputation = modeMatrix,\n arithmetic: WorldArithmetic = RUNTIME_ARITHMETIC,\n): Map<string, CoreWorld> {\n const out = new Map<string, CoreWorld>();\n for (const bone of bones) {\n if (active !== null && !active.has(bone.name)) {\n out.set(bone.name, { a: 0, b: 0, c: 0, d: 0, worldX: 0, worldY: 0 });\n continue;\n }\n const x = bone.x ?? 0;\n const y = bone.y ?? 0;\n if (bone.parent === undefined) {\n const [a, b, c, d] = localFrame(arithmetic, bone.rotation ?? 0, bone.shearX ?? 0, bone.shearY ?? 0, bone.scaleX ?? 1, bone.scaleY ?? 1);\n out.set(bone.name, { a, b, c, d, worldX: x, worldY: y });\n continue;\n }\n const parent = out.get(bone.parent);\n if (parent === undefined) throw new Error(`bone \"${bone.name}\": parent \"${bone.parent}\" is not posed before it`);\n const [a, b, c, d] = inherit(modeOf(bone), parent, bone, arithmetic);\n out.set(bone.name, { a, b, c, d, worldX: parent.a * x + parent.b * y + parent.worldX, worldY: parent.c * x + parent.d * y + parent.worldY });\n }\n return out;\n}\n\n/** The mode computation `worldTransforms` uses, exported so a control can wrap it. */\nexport { modeMatrix };\n","/**\n * The skin a document is posed under (issue #932): every skin merged — the\n * oracle's `--skin all` — or one skin by name, `--skin <name>`. Each rule\n * below was measured by posing hand-written skeletons through\n * `tools/pose_oracle.ts dump --skin <name>` (spine-core 4.3.13) and reading\n * the rows it printed; the core suite's `CN` controls hold the same\n * skeletons against the core at tolerance 0.\n *\n * - **What a slot shows under a named skin**: the named skin's record for\n * the placeholder, else the default skin's, else nothing. Three skins\n * `default`, `s1`, `s2` over five slots — a placeholder the default and\n * `s1` and `s2` fill, one the default alone fills, one `s1` alone, one no\n * skin, one `s1` and the default — dumped under `default`, `s1` and `s2`\n * in two file orders (`default, s1, s2` and `s2, s1, default`): `s1`\n * showed `s1`'s record where it filled the placeholder and the default's\n * where only the default did; `s2` showed `s2`'s, then the default's, and\n * nothing for the placeholder only `s1` fills; a placeholder no skin fills\n * showed nothing under every skin; the two file orders read the same row\n * under every named skin. An attachment key switching the slot at a\n * sample resolves the same way. So a named skin has no order question:\n * nothing a placeholder shows depends on the file's skin order, which the\n * model does not hold (the slots' ⚠️ in `./index.ts`).\n * - **The bones a named skin activates**: a skin-required bone is active\n * exactly when the NAMED skin names it or a bone below it — the default\n * skin's `bones` list does not count. Measured on the same probe: a\n * skin-required bone only the default names read active under `default`\n * and inactive under `s1` and `s2`; one `s1` names, and its skin-required\n * parent, active under `s1` only; a bone that is not skin-required under\n * an inactive one stayed active under every skin.\n * - **The constraints a named skin applies**: a skin-required constraint of\n * any kind is applied exactly when the named skin's list for its kind names\n * it — the default skin's list does not count either (`./constraints.ts`'s\n * header, the nine readings per kind).\n *\n * - **A slot on an inactive bone is not animated** (the commander's private\n * finding on this issue: a 19-skin rig read DIFF on 18 of its 19 skin\n * runs). A slot whose bone the applied skin leaves inactive keeps its\n * setup colour, dark colour and attachment under every slot timeline —\n * `rgba`, `rgb`, `alpha`, `rgba2`, `rgb2` and `attachment` — whether an\n * animation plays it or a slider applies it, and a deform timeline on its\n * attachment does not apply either (a mesh weighted to an ACTIVE bone, so\n * the deform would show: moved by 5 under `all` and `s1`, unmoved under\n * `default`, which leaves the slot's bone inactive). Measured on\n * hand-written skeletons under `--skin all`, `s1` (naming the bone) and\n * `default` (not): each timeline moved the slot under the first two and\n * not under the third, and the setup row read the setup under all three\n * (a slider's key included). A slot on an ACTIVE bone that shows nothing\n * (no skin holds its placeholder) IS animated: every colour key applied,\n * and an attachment key switched it. A draw-order key moves a slot on an\n * inactive bone like any other. A sequence timeline is held by the same\n * gate; its effect on such a slot is not observable in the dump — a\n * region's corners on an inactive bone are all zeros whatever the frame.\n * So the predicate is the slot bone's activity (`slotTimelinesApply`),\n * not what the slot shows; under `all` every bone some skin names is\n * active, so a one-skin rig is unchanged.\n *\n * - **No skin set** (issue #1051): a fresh skeleton whose `setSkin` was never\n * called — `underNoSkin`, the state `render` without `--skin`, A10's walk\n * and `validate()` pose in. No skin's `bones` or constraint lists are\n * applied, the default skin's included, and a slot shows the default\n * skin's record for its placeholder, else nothing — so over a document\n * with skins and no `default` one every slot shows nothing. Measured with\n * `tools/pose_oracle.ts dump --skin none` on 93 skeletons rebuilt through\n * `ingest` and `compile` (31 with no default skin, 31 whose default names\n * skin-required members, 31 with a plain default): `Skeleton.skin` read\n * `null` on all 93; all 311 skin-required bones read inactive — the 51 a\n * default skin names among them, and the 66 a constraint writes — and the\n * 125 bones that are not skin-required under one read active and unposed;\n * all 73 skin-required constraints read inactive and moved nothing when\n * removed — the 12 a default skin lists among them — and the 81 that are\n * not read active; 199 slots whose placeholder the default skin fills\n * showed it and 359 only named skins fill showed nothing; a colour key on\n * a slot whose bone is inactive held its setup colour (50 of 50) and moved\n * it on an active one (46 of 46), and a draw-order key applied either way\n * (93 of 93). The core suite's `CO29` holds the same population against\n * the core under `--raw` at tolerance 0, and `CO30` plants each rejected\n * reading (the old one among them: no skin set read as the default skin,\n * which differs exactly where the default skin names a skin-required\n * member).\n *\n * Under `all` every skin is applied at once: `bones` and the constraint\n * lists of every skin count, and a placeholder several skins fill shows the\n * LAST of them in the Spine file's order — the case `./index.ts` leaves out\n * by name, and the one the per-skin dumps exist to judge.\n */\nimport type { ModelSlot } from '../model.ts';\nimport type { CompiledDocument, CoreSkin } from './index.ts';\n\n/** The skin option that merges every skin — the oracle's `--skin all`. */\nexport const CORE_ALL_SKINS = 'all';\n\n/** The skin a document names its default skin with — Spine's `SkeletonData.defaultSkin` is the skin of this name. */\nexport const CORE_DEFAULT_SKIN = 'default';\n\n/** The skins whose `bones` and constraint lists are applied: every skin under `all`, none with no skin set, the named skin alone otherwise (the header's measurements). */\nexport function appliedSkins(doc: CompiledDocument): CoreSkin[] {\n if (doc.skin === null) return [];\n return doc.skin === CORE_ALL_SKINS ? doc.skins : doc.skins.filter((k) => k.name === doc.skin);\n}\n\n/** Under a named skin or none, the skins a placeholder is looked up in, in precedence order: the named skin, then the default skin (the header's measurements). */\nexport function lookupSkins(doc: CompiledDocument): CoreSkin[] {\n if (doc.skin === CORE_ALL_SKINS) return doc.skins;\n const named = doc.skin === null ? undefined : doc.skins.find((k) => k.name === doc.skin);\n const fallback = doc.skin === CORE_DEFAULT_SKIN ? undefined : doc.skins.find((k) => k.name === CORE_DEFAULT_SKIN);\n return [named, fallback].filter((k): k is CoreSkin => k !== undefined);\n}\n\n/**\n * The skins that could show a slot's placeholder: under `all` every skin\n * filling it — several is the file-order question — and under a named skin\n * the one it resolves to, or none.\n */\nexport function fillingSkins(doc: CompiledDocument, slot: string, placeholder: string): string[] {\n if (doc.skin === CORE_ALL_SKINS) return doc.skins.filter((k) => k.attachments[slot]?.[placeholder] !== undefined).map((k) => k.name);\n const first = lookupSkins(doc).find((k) => k.attachments[slot]?.[placeholder] !== undefined);\n return first === undefined ? [] : [first.name];\n}\n\n/** Whether a slot's timelines — its colour and attachment timelines, and the deform and sequence timelines on what it shows — apply: `slotTimelinesApply` unless a plant passes another. */\nexport type SlotTimelineGate = (doc: CompiledDocument, slot: ModelSlot, active: ReadonlySet<string>) => boolean;\n\n/** A slot's timelines apply exactly when its bone is active under the skin posed (the header's measurement). */\nexport const slotTimelinesApply: SlotTimelineGate = (_doc, slot, active) => active.has(slot.bone);\n\n/** Whether an applied skin's list for `kind` names the constraint — what applies a skin-required one (`./constraints.ts`'s header). */\nexport function listedByAppliedSkin(doc: CompiledDocument, kind: keyof CoreSkin['constraints'], name: string): boolean {\n return appliedSkins(doc).some((k) => k.constraints[kind].includes(name));\n}\n","/**\n * Construct 4 of the core, its remainder (issue #955, step 2f of issue #380):\n * the two timelines an attachment carries — `deform`, a vertex attachment's\n * vertices keyed over time, and `sequence`, the frame a region's series shows\n * — at a sample time, and under a slider at the time and mix it was applied\n * with.\n *\n * Every rule below was measured by posing hand-written skeletons through\n * `tools/pose_oracle.ts dump` (spine-core 4.3.13, `--skin all`,\n * `--physics none`) and comparing a formula over the core's own world\n * transforms (`./world.ts`, exact on every probe) with the rows the dump\n * printed, at the oracle's six-decimal rounding. Nothing here was written\n * from the runtime's source. The core suite's `CD` controls hold the same\n * skeletons against the core at tolerance 0.\n *\n * ## Deform: what a key holds\n *\n * A key states a run — `vertices`, starting at `offset` (0 unstated) — into\n * the attachment's deform array: one `x, y` pair per vertex of an unweighted\n * attachment, one pair per BINDING of a weighted one (in vertex order, then\n * binding order). What the run does not cover is an offset of 0, and a key\n * with no `vertices` is all zeros — the setup geometry.\n *\n * - **Unweighted, the runtime holds the key as positions, each the float32 sum\n * `fround(fround(setup) + fround(offset))`.** Over 800 samples of 40\n * random meshes on rotated, scaled bones, five-decimal numbers: that\n * reading 0 misses; the double sum lerped 788, the lerped positions\n * rounded to float32 791, the offsets lerped and then added 788.\n * - **Weighted, the runtime holds the key as offsets** (`fround(offset)`) and\n * adds each to its binding's float32 coordinate when the world vertices\n * are computed: `(fround(bx) + dx)·a + (fround(by) + dy)·b + worldX`, times\n * the weight, summed. Over 1,600 samples of 80 random meshes over one to\n * three of three bones: 0 misses; the float32 sum held as a position 775\n * and 780, the lerped offset rounded to float32 711 and 716.\n *\n * ## Deform: at a sample time\n *\n * The key search is construct 4's (the last key at or before `t`, key times\n * float32). Before the first key the setup geometry; at or after the last\n * key, and on a `stepped` segment, that key; between two keys the lerp\n * `a + (b − a)·p` of the two held arrays, in double — measured above, and on\n * 7,200 samples of 180 random multi-key timelines (runs short and offset,\n * keys without vertices, stepped, linear and Bézier segments): 0 misses with\n * the Bézier rule below, 114 with the far end 1, every one on a Bézier\n * piece next to the eighth or ninth point. The form `a·(1 − p) + b·p` read\n * the same 0: the two differ below the oracle's grid, so which one the\n * runtime writes is not measurable here, and the first is taken.\n *\n * - **Linear**: `p = (t − t0) / (t1 − t0)`, the key times float32 (a float32\n * `p` missed 341 of 2,400).\n * - **Bézier**: one channel whose value axis runs from 0 to 1 — the fraction\n * of the way from one key's geometry to the next — shaped as a bone\n * channel's is (`bezierPolyline` in `./animation.ts`: the polyline through\n * the cubic's nine points at tenths of its parameter, stated numbers,\n * float32 points) with ONE measured difference: ⚠️ **the recurrence runs to\n * a far end of `0.99999999`, not 1, while the polyline's last point is the\n * next key at 1.** Read off 126 curves, each point fixed by intersecting\n * the two pieces meeting at it (a 10⁵-unit run makes `p` legible to 1e-11):\n * with the far end 1 the points missed 64 of 1,134; with `0.99999999`, 1 —\n * a first point whose piece held too few samples to fit — and every other\n * far end tried missed more (1 − 2⁻²⁷ 17, 0.999999989 10, 0.99999998 68;\n * the exact one-sixth with the far end 1, 68). On the 1,080 points of the\n * 120 random curves among them, the other readings of the recurrence\n * missed more still: float32 handles 222, float32 running sums or\n * constants 258 and more (1,024 combinations tried), the cubic evaluated\n * directly 67. The residual the far end 1 leaves is one float32 step,\n * always downward, growing with the point's index. A bone\n * channel shaped by the same handles read the far end 1 (`CD02` holds\n * both): the deform curve is its own reading. The last piece, from the\n * ninth point to the next key, read exact.\n * ⚠️ **Which form each piece takes (issue #975)**: the first piece, from\n * the key to the first point, is `y1·(t − x0) / (x1 − x0)`; the last, from\n * the ninth point to the next key, `y0 + (1 − y0)·(t − x0) / (x1 − x0)`\n * (each product before its division); the eight between are the bone\n * channel's `y0 + (t − x0) / (x1 − x0) · (y1 − y0)`. A bone channel reads\n * all ten pieces in the between form (`channelAt`, bit-exact at a 1e9\n * amplifier, `CR08`). The forms differ below the oracle's six-decimal grid,\n * so they were read off `pose_oracle --raw` at tolerance 0 on `CR09`'s\n * cells (60 five-vertex meshes, one deform segment each, 40 irrational\n * samples; five-decimal keys / float32-exact keys): every piece in the\n * between form 30 / 31 of 60 exact; the first piece's product alone 52 /\n * 53; the last piece's alone 37 / 37; both 60 / 60 (and 60 / 60 on another\n * seed at 200 samples, where the between form read 14 / 14). The far end\n * stays `0.99999999`: with both forms and the far end 1, 38 / 38.\n *\n * ## Under a slider\n *\n * A slider applies its animation's deforms after the sample's own, at its\n * time, from the CURRENT deform — the sample's, or the setup geometry where\n * the sample set none (the setup positions unweighted, zero offsets\n * weighted) — with alpha its mix: `current + (target − current)·mix`, and\n * `additive` `current + (target − setup)·mix` (the setup positions\n * unweighted, zeros weighted). ⚠️ At mix exactly 1, not additive, it IS the\n * target: `current + (target − current)·1` read 1 ulp off spine-core on 27\n * of 2,790 posed rows of issue #969's hand-written population (`DM01`, the\n * survey's doubles), the target on none. ⚠️ **Additive at mix exactly 1\n * over NO current deform** — at the setup pose, or at a sample whose own\n * animation set none on that slot — **it is the target too**, not\n * `setup + (target − setup)·1` (issue #993, read off `pose_oracle --raw` at\n * tolerance 0; weighted, the setup is zeros and the two agree to the bit).\n * On 1,000 rigs of `CD05`'s generator: that rule 1,000 exact; the stated\n * blend everywhere 985 (15 misses, every one unweighted, additive, mix 1,\n * with no current deform, 1–16 ulp on a vertex). Read at every additive\n * mix 1, current deform or not: `current + target − setup` 917,\n * `current − setup + target` and `target + (current − setup)` 951 each (with\n * no current deform both are the target to the bit — they miss over one),\n * the target itself 850. So over a current deform the stated blend stands:\n * the 107 additive mix-1 rigs whose sample animation keys a deform of its\n * own read exact at every sample with it. Before the timeline's first key it\n * writes nothing. Measured on 300 samples of 60 random rigs — weighted and not,\n * additive and not, mix 1, 0.5 and in [−1, 2], with and without a deform in\n * the sample's own animation: 0 misses; reading the non-additive blend from\n * the setup geometry missed 45, reading additive as the key's positions\n * added missed 100.\n *\n * ## Which slot a deform timeline moves\n *\n * The timeline names a skin, a slot and a placeholder: a RECORD. It moves\n * every slot whose shown record at that moment — after the attachment\n * timelines and the sliders — is that record, or a linked mesh that plays\n * that record's timelines (`timelines` true), whichever slot the timeline is\n * filed under. Measured (`CD07`): a deform keyed on mesh `m` of slot `y`\n * moved a linked mesh of `m` in slot `x` and another in slot `z`, and moved\n * `x` while `y` showed another mesh and while `y` showed nothing; a linked\n * mesh with `timelines` false did not move; a deform keyed on an attachment\n * the slot shows only between two attachment keys moved it there alone.\n *\n * ## A switch\n *\n * The sample's own attachment timelines are applied before its deform and\n * sequence timelines, so those are matched against what the slot shows after\n * the sample's switches. A slider applies its animation after the sample —\n * its attachment key, then its deform and sequence keys — and ⚠️ **a slider\n * switching the slot to ANOTHER attachment clears the deform and the frame\n * the sample set**, while one naming the attachment already shown keeps\n * them. Measured on two meshes `m`, `n` and on two series `r` (setup frame 1)\n * and `q` (setup frame 2) (`CD14`): a slider switching `m` to `n` over a\n * sample deforming `m` drew `n` undeformed, and over a sample deforming `n`\n * drew `n` undeformed too (the sample's deform of `n` found `m` shown); a\n * slider naming `m` over a sample deforming `m` kept the deform; a slider\n * switching to `n` and deforming it drew its own deform; the series alike —\n * `q` at its setup frame after the switch, `r` at the sample's frame 3 when\n * the slider named `r`. ⚠️ Under\n * `--skin all` a placeholder several skins fill shows the LAST of them in the\n * Spine file's skin order, which the model does not hold (the slots' ⚠️ in\n * `./index.ts`), so a timeline keyed on such a placeholder is not posed: the\n * block is absent, naming it. Under `--skin <name>` one record resolves —\n * the named skin's, else the default's (`./skins.ts`) — and a timeline\n * moves it exactly when it is keyed under that record's skin (`CN01`).\n *\n * ## Sequence\n *\n * A region's series shows its setup frame (`sequence.setup`, 0 unstated)\n * until a sequence timeline's first key. From a key — `mode` (`hold`\n * unstated), `index` (0 unstated), `delay` (⚠️ unstated, the key before\n * it's, 0 on the first key) — the frame is `index` plus\n * `floor((t − time) / delay + 0.00001)` steps when `delay` is above 0 (no\n * step otherwise, and none in `hold`), then per mode over `count` frames:\n * `hold` the index held at the last frame, `once` the same, `loop` modulo\n * `count`, `pingpong` modulo `2·(count − 1)` folded back, and each\n * `…Reverse` mode the forward mode's frame `f` read as `count − 1 − f`. The\n * key time and `delay` are float32. Measured on 74,041 samples of 380\n * random timelines, 300 of them with delays built to put the quotient within\n * 1e-6 to 4e-5 of a whole step (52,768 samples): the epsilon 0.00001 missed\n * 0; no epsilon 440, 0.0001 1,266, a float32 quotient 306; on the 52,768,\n * 0.000005 148 and 0.00002 248. ⚠️ **A key stating no\n * delay steps by the key before it's**, carried through keys that state\n * none: a hold with delay 0.2, then a hold at index 1, then a loop at index 0\n * stating no delay stepped every 0.2 from the third key; a delay of 0 stated\n * after one of 0.2 held; the index and the mode are not carried (a key\n * stating no index after one at 3 showed frame 0; one stating no mode\n * after a loop held). A slider applies a\n * sequence key at any mix but 0. Only a region's corners read the frame (its\n * rectangle, `sequence.atlas[frame]`); a mesh's vertices read no atlas.\n *\n * ## Purity\n *\n * As the rest of the core: nothing from the Spine runtime package, nothing\n * from `src/transform.ts`, no clock, no randomness, no I/O.\n */\nimport type { ModelSlot, ModelVertices } from '../model.ts';\nimport { bezierPolyline, keyIndexAt, type CoreAnimationTimelines, type CoreCurve } from './animation.ts';\nimport { activeBones, shownRow, type CompiledDocument, type CoreShown, type CoreSkin, type ShownResolution } from './index.ts';\nimport { fillingSkins, slotTimelinesApply, type SlotTimelineGate } from './skins.ts';\nimport type { CoreGeometry, ShownGeometry } from './vertices.ts';\n\n/** The far end the deform curve's recurrence runs to — the header's measurement. */\nexport const DEFORM_CURVE_END = 0.99999999;\n\n/** A sequence timeline's modes, as the model spells them. */\nexport const SEQUENCE_MODES = ['hold', 'once', 'loop', 'pingpong', 'onceReverse', 'loopReverse', 'pingpongReverse'] as const;\nexport type SequenceMode = (typeof SEQUENCE_MODES)[number];\n\n/** The step a sequence adds to its quotient before flooring it — the header's measurement. */\nexport const SEQUENCE_EPSILON = 0.00001;\n\n/** One deform key, as read: its time float32 and as stated, its curve, and its run. */\nexport interface CoreDeformKey {\n time: number;\n stated: number;\n curve: CoreCurve;\n offset: number;\n /** The run as the document states it; the runtime stores each float32. */\n vertices: number[];\n}\n\n/** One sequence key, as read — each field the parser's value where unstated. */\nexport interface CoreSequenceKey {\n time: number;\n mode: SequenceMode;\n index: number;\n /** Float32, as the runtime stores it. */\n delay: number;\n}\n\n/** One attachment's timelines in one animation: the skin, slot and placeholder it names, and its deform and sequence keys. */\nexport interface CoreAttachmentTimeline {\n skin: string;\n slot: string;\n attachment: string;\n deform: CoreDeformKey[] | null;\n sequence: CoreSequenceKey[] | null;\n}\n\nconst isRecord = (v: unknown): v is Record<string, unknown> => typeof v === 'object' && v !== null && !Array.isArray(v);\nconst finite = (v: unknown): v is number => typeof v === 'number' && Number.isFinite(v);\n\n/** How long the deform array of a vertex array is: a pair per vertex, or per binding when weighted. */\nexport function deformLength(vertices: ModelVertices): number {\n return vertices.weighted ? 2 * vertices.bindings.reduce((n, b) => n + b.length, 0) : vertices.xy.length;\n}\n\nfunction keyTimes(list: unknown[], at: string, problems: string[]): void {\n let last = -Infinity;\n list.forEach((k, i) => {\n if (!isRecord(k)) return;\n const t = k.time;\n if (!finite(t) || t < 0) problems.push(`${at}[${i}]: time is ${JSON.stringify(t)}, not a finite time at or after 0`);\n else if (t <= last) problems.push(`${at}[${i}]: time ${t} is not after the key before it — the writer refuses key times that do not strictly increase`);\n if (finite(t)) last = Math.max(last, t);\n });\n}\n\nfunction readDeformKeys(value: unknown, at: string, vertices: ModelVertices, problems: string[]): CoreDeformKey[] {\n if (!Array.isArray(value) || value.length === 0) {\n problems.push(`${at}: keys is not a non-empty list`);\n return [];\n }\n keyTimes(value, at, problems);\n const length = deformLength(vertices);\n const out: CoreDeformKey[] = [];\n value.forEach((k, i) => {\n const kat = `${at}[${i}]`;\n if (!isRecord(k)) {\n problems.push(`${kat} is not an object`);\n return;\n }\n for (const key of Object.keys(k)) if (!['time', 'offset', 'vertices', 'curve'].includes(key)) problems.push(`${kat}: field \"${key}\" is not one a deform key carries; it carries [time, offset, vertices, curve]`);\n const run = k.vertices;\n let vertexRun: number[] = [];\n if (run !== undefined) {\n if (!Array.isArray(run) || run.length === 0 || !run.every(finite)) problems.push(`${kat}: vertices is not a non-empty list of finite numbers (omit it for the setup geometry)`);\n else vertexRun = run as number[];\n }\n let offset = 0;\n if (k.offset !== undefined) {\n if (run === undefined) problems.push(`${kat}: offset ${JSON.stringify(k.offset)} with no vertices — a key with no run is the setup geometry, and the writer states no start for it`);\n else if (typeof k.offset !== 'number' || !Number.isInteger(k.offset) || k.offset < 0) problems.push(`${kat}: offset is ${JSON.stringify(k.offset)}, not a whole index at or after 0`);\n else offset = k.offset;\n }\n if (offset + vertexRun.length > length) problems.push(`${kat}: the run starts at ${offset} and is ${vertexRun.length} long, past the ${length} numbers of the attachment's deform array`);\n let curve: CoreCurve = 'linear';\n if (k.curve !== undefined) {\n if (i === value.length - 1) problems.push(`${kat}: the last key carries a curve, which eases to no key — the writer refuses it`);\n else if (k.curve === 'stepped') curve = 'stepped';\n else if (Array.isArray(k.curve) && k.curve.length === 4 && k.curve.every(finite)) curve = k.curve as number[];\n else problems.push(`${kat}: curve is ${JSON.stringify(k.curve)}, not \"stepped\" nor 4 finite numbers (a deform key's curve is one channel)`);\n }\n const time = finite(k.time) ? k.time : 0;\n out.push({ time: Math.fround(time), stated: time, curve, offset, vertices: vertexRun });\n });\n return out;\n}\n\nfunction readSequenceKeys(value: unknown, at: string, count: number, problems: string[]): CoreSequenceKey[] {\n if (!Array.isArray(value) || value.length === 0) {\n problems.push(`${at}: keys is not a non-empty list`);\n return [];\n }\n keyTimes(value, at, problems);\n const out: CoreSequenceKey[] = [];\n value.forEach((k, i) => {\n const kat = `${at}[${i}]`;\n if (!isRecord(k)) {\n problems.push(`${kat} is not an object`);\n return;\n }\n for (const key of Object.keys(k)) if (!['time', 'mode', 'index', 'delay'].includes(key)) problems.push(`${kat}: field \"${key}\" is not one a sequence key carries; it carries [time, mode, index, delay]`);\n let mode: SequenceMode = 'hold';\n if (k.mode !== undefined) {\n const m = SEQUENCE_MODES.find((x) => x === k.mode);\n if (m === undefined) problems.push(`${kat}: mode is ${JSON.stringify(k.mode)}, none of ${SEQUENCE_MODES.join(', ')}`);\n else mode = m;\n }\n let index = 0;\n if (k.index !== undefined) {\n if (typeof k.index !== 'number' || !Number.isInteger(k.index) || k.index < 0 || k.index >= count) problems.push(`${kat}: index is ${JSON.stringify(k.index)}, not a frame of the series' ${count} — the writer refuses an index past the last frame`);\n else index = k.index;\n }\n // Unstated, the key before it's (the header's ⚠️).\n let delay = out.length === 0 ? 0 : out[out.length - 1].delay;\n if (k.delay !== undefined) {\n // A negative delay steps backwards through a floor this cut never measured; the writer states none.\n if (!finite(k.delay) || k.delay < 0) problems.push(`${kat}: delay is ${JSON.stringify(k.delay)}, not a finite number of seconds at or above 0`);\n else delay = Math.fround(k.delay);\n }\n out.push({ time: Math.fround(finite(k.time) ? k.time : 0), mode, index, delay });\n });\n return out;\n}\n\n/**\n * An animation record's `attachments` group, read: each skin, slot and\n * placeholder one of the document's records, a `deform` only on a vertex\n * attachment (mesh, bounding box, clipping, path — the four the writer keys)\n * with every run fitting its deform array, a `sequence` only on a record with\n * a series, and every key checked field by field. Every problem is named.\n */\nexport function readAttachmentTimelines(value: unknown, label: string, skins: readonly CoreSkin[], problems: string[]): CoreAttachmentTimeline[] {\n const out: CoreAttachmentTimeline[] = [];\n const where = `${label}.attachments`;\n if (!Array.isArray(value)) {\n problems.push(`${where} is not a list`);\n return out;\n }\n value.forEach((skinEntry, i) => {\n const sat = `${where}[${i}]`;\n if (!isRecord(skinEntry) || typeof skinEntry.name !== 'string') {\n problems.push(`${sat} names no skin`);\n return;\n }\n const skin = skins.find((k) => k.name === skinEntry.name);\n if (skin === undefined) problems.push(`${sat}: \"${skinEntry.name}\" is not a skin of this document`);\n if (!Array.isArray(skinEntry.slots)) {\n problems.push(`${sat}: slots is not a list`);\n return;\n }\n skinEntry.slots.forEach((slotEntry: unknown, j: number) => {\n const lat = `${sat}.slots[${j}]`;\n if (!isRecord(slotEntry) || typeof slotEntry.name !== 'string') {\n problems.push(`${lat} names no slot`);\n return;\n }\n if (!Array.isArray(slotEntry.attachments)) {\n problems.push(`${lat}: attachments is not a list`);\n return;\n }\n const slot = slotEntry.name;\n slotEntry.attachments.forEach((attEntry: unknown, m: number) => {\n const aat = `${lat}.attachments[${m}]`;\n if (!isRecord(attEntry) || typeof attEntry.name !== 'string') {\n problems.push(`${aat} names no attachment`);\n return;\n }\n for (const key of Object.keys(attEntry)) if (!['name', 'deform', 'sequence'].includes(key)) problems.push(`${aat}: field \"${key}\" is not one this reader knows; it reads [name, deform, sequence]`);\n const record = skin?.attachments[slot]?.[attEntry.name];\n const label2 = `${aat} \"${skinEntry.name}/${slot}/${attEntry.name}\"`;\n if (skin !== undefined && record === undefined) problems.push(`${label2}: skin \"${skin.name}\" files no attachment \"${attEntry.name}\" under slot \"${slot}\"`);\n const timeline: CoreAttachmentTimeline = { skin: skinEntry.name as string, slot, attachment: attEntry.name, deform: null, sequence: null };\n if (attEntry.deform !== undefined && record !== undefined) {\n const g = record.geometry;\n if (g === undefined || (g.kind !== 'mesh' && g.kind !== 'clipping' && g.kind !== 'boundingbox' && g.kind !== 'path')) problems.push(`${label2}: a deform keys the vertices of a mesh, bounding box, clipping or path attachment, and this one is a ${record.kind}`);\n else timeline.deform = readDeformKeys(attEntry.deform, `${label2}.deform`, g.vertices, problems);\n }\n if (attEntry.sequence !== undefined && record !== undefined) {\n const count = record.sequenceCount;\n if (count === undefined) problems.push(`${label2}: a sequence timeline steps a series, and this ${record.kind} carries no sequence`);\n else timeline.sequence = readSequenceKeys(attEntry.sequence, `${label2}.sequence`, count, problems);\n }\n if (attEntry.deform === undefined && attEntry.sequence === undefined) problems.push(`${label2}: carries neither a deform nor a sequence timeline`);\n out.push(timeline);\n });\n });\n });\n return out;\n}\n\n// ---------------------------------------------------------------------------\n// evaluation\n// ---------------------------------------------------------------------------\n\n/** The array a key holds — the header's *what a key holds*: positions unweighted, offsets weighted. */\nexport function heldArray(vertices: ModelVertices, key: CoreDeformKey): number[] {\n const out = setupArray(vertices);\n key.vertices.forEach((v, i) => {\n const at = key.offset + i;\n out[at] = vertices.weighted ? Math.fround(v) : Math.fround(out[at] + Math.fround(v));\n });\n return out;\n}\n\n/** The deform array of no deform: the setup positions (float32) unweighted, zero offsets weighted. */\nexport function setupArray(vertices: ModelVertices): number[] {\n return vertices.weighted ? new Array<number>(deformLength(vertices)).fill(0) : vertices.xy.map((v) => Math.fround(v));\n}\n\n/** The fraction of the way from key `a` to key `b` at `t` — the header's two curves. */\nexport function deformPercent(a: CoreDeformKey, b: CoreDeformKey, t: number): number {\n if (a.curve === 'stepped') return 0;\n if (a.curve === 'linear') return (t - a.time) / (b.time - a.time);\n const c = a.curve;\n const inner = bezierPolyline(a.stated, 0, c[0], c[1], c[2], c[3], b.stated, DEFORM_CURVE_END);\n const points = [a.time, 0, ...inner, b.time, 1];\n let i = 2;\n while (i < points.length - 2 && points[i] < t) i += 2;\n const [x0, y0, x1, y1] = [points[i - 2], points[i - 1], points[i], points[i + 1]];\n // The two end pieces multiply before they divide — the header's *which form each piece takes*.\n if (i === 2) return (y1 * (t - x0)) / (x1 - x0);\n if (i === points.length - 2) return y0 + ((1 - y0) * (t - x0)) / (x1 - x0);\n return y0 + ((t - x0) / (x1 - x0)) * (y1 - y0);\n}\n\n/** What evaluates a deform timeline at `t`: `deformAt` unless a plant passes another. */\nexport type DeformEvaluator = (vertices: ModelVertices, keys: readonly CoreDeformKey[], t: number) => number[] | null;\n\n/** The deform array a timeline sets at `t`, or `null` before its first key — the header's *at a sample time*. */\nexport function deformAt(vertices: ModelVertices, keys: readonly CoreDeformKey[], t: number): number[] | null {\n const i = keyIndexAt(keys, t);\n if (i < 0) return null;\n const a = keys[i];\n const held = heldArray(vertices, a);\n const b = keys[i + 1];\n if (b === undefined || a.curve === 'stepped') return held;\n const next = heldArray(vertices, b);\n const p = deformPercent(a, b, t);\n return held.map((v, k) => v + (next[k] - v) * p);\n}\n\n/** What blends a slider's deform over the current one: `blendDeform` unless a plant passes another. */\nexport type DeformBlender = (vertices: ModelVertices, current: readonly number[] | null, target: readonly number[], alpha: number, additive: boolean) => number[];\n\n/** A slider's deform over the current one — the header's *under a slider*. */\nexport function blendDeform(vertices: ModelVertices, current: readonly number[] | null, target: readonly number[], alpha: number, additive: boolean): number[] {\n const setup = setupArray(vertices);\n const from = current ?? setup;\n // #969: non-additive at mix 1 the target itself, not `c + (target − c)·1`, which is last-bit off it (measured, `./hooks.ts`' DM01).\n if (!additive && alpha === 1) return [...target];\n // #993: additive at mix 1 over no current deform the target too, not `setup + (target − setup)·1` (measured, the core suite's CR10).\n if (additive && alpha === 1 && current === null) return [...target];\n return from.map((c, k) => (additive ? c + (target[k] - setup[k]) * alpha : c + (target[k] - c) * alpha));\n}\n\n/**\n * The vertex array a deform array draws: unweighted the positions\n * themselves, weighted each binding's float32 coordinate plus its offset —\n * numbers the world-vertex computation reads as they are, not through\n * `Math.fround` again (`worldVertices`' `coords`).\n */\nexport function deformedVertices(vertices: ModelVertices, deform: readonly number[]): ModelVertices {\n if (!vertices.weighted) return { weighted: false, xy: [...deform] };\n let k = 0;\n return {\n weighted: true,\n bindings: vertices.bindings.map((influences) => influences.map((b) => {\n const x = Math.fround(b.x) + deform[k];\n const y = Math.fround(b.y) + deform[k + 1];\n k += 2;\n return { ...b, x, y };\n })),\n };\n}\n\n/** The frame a sequence timeline shows at `t`, or `null` before its first key — the header's *Sequence*. */\nexport function sequenceFrameAt(keys: readonly CoreSequenceKey[], count: number, t: number): number | null {\n const i = keyIndexAt(keys, t);\n if (i < 0) return null;\n const k = keys[i];\n let n = k.index;\n if (k.mode !== 'hold' && k.delay > 0) n += Math.floor((t - k.time) / k.delay + SEQUENCE_EPSILON);\n const reverse = k.mode.endsWith('Reverse');\n const base = reverse ? k.mode.slice(0, -'Reverse'.length) : k.mode;\n let f: number;\n if (base === 'hold' || base === 'once') f = Math.min(n, count - 1);\n else if (base === 'loop') f = n % count;\n else {\n const period = 2 * (count - 1);\n f = period === 0 ? 0 : n % period;\n if (f >= count) f = period - f;\n }\n return reverse ? count - 1 - f : f;\n}\n\n// ---------------------------------------------------------------------------\n// the slots' attachments at a pose\n// ---------------------------------------------------------------------------\n\n/** What evaluates a sequence timeline at `t`: `sequenceFrameAt` unless a plant passes another. */\nexport type SequenceEvaluator = (keys: readonly CoreSequenceKey[], count: number, t: number) => number | null;\n\n/** The applications this module reads off a slider (`SliderApplication` in `./constraints_slider.ts`). */\nexport interface AttachmentApplication {\n name: string;\n timelines: { attachments: readonly CoreAttachmentTimeline[]; slots: ReadonlyArray<{ name: string; timelines: ReadonlyArray<{ kind: string; keys?: ReadonlyArray<{ time: number; name?: string | null }> }> }> };\n at: number;\n alpha: number;\n additive: boolean;\n}\n\n/** The skin, slot and placeholder a slot's shown record plays timelines as — the header's *which slot* — or null when none can key it. */\nexport function timelineIdentity(slot: string, shown: CoreShown): string | null {\n const g = shown.record.geometry;\n if (g?.kind === 'linkedmesh') return shown.record.timelines === true ? `${g.skin}/${g.slot}/${g.source}` : null;\n return `${shown.skin}/${slot}/${shown.placeholder}`;\n}\n\nconst nameOf = (a: CoreAttachmentTimeline): string => `${a.skin}/${a.slot}/${a.attachment}`;\n\n/**\n * Every slot's shown geometry at one pose — the setup's (`sample` null) or a\n * sample's — with the deform array and the series' frame its attachment\n * timelines set, stage by stage as the header's *A switch* states: from what\n * the slot shows after the sample's own timelines (`placeholders`; the setup\n * placeholder at setup), the sample's deform and sequence timelines at `t`;\n * then each slider in order — its attachment key (a switch to another record\n * clears the deform and the frame), then its deform and sequence timelines at\n * the time and mix it was applied with. Slots in the model's order, showing a\n * record that carries geometry; a slot whose placeholder skins fill\n * differently is left to the slots' own absence. `why` names what the core\n * does not pose: a timeline moving a record whose placeholder several skins\n * fill (the header's ⚠️).\n */\nexport function attachmentStates(\n doc: CompiledDocument,\n resolve: (doc: CompiledDocument, slot: ModelSlot) => ShownResolution,\n placeholders: ReadonlyMap<string, string | null>,\n sample: { timelines: CoreAnimationTimelines; t: number } | null,\n sliders: readonly AttachmentApplication[],\n plant: { deform?: DeformEvaluator; deformBlend?: DeformBlender; sequence?: SequenceEvaluator; slotTimelines?: SlotTimelineGate } = {},\n /**\n * The live tracks' deforms (`./tracks.ts`, issue #1336), in place of a\n * sample's: each slot's deform array as the mixed entries left it (`null`\n * none) and the records their deform timelines keyed on it — what the\n * sample's own timelines would have set and seen. Absent on every other\n * caller.\n */\n mixed?: ReadonlyMap<string, { deform: number[] | null; seen: readonly string[] }>,\n): { shown: ShownGeometry[]; why: string[] } {\n const evalDeform = plant.deform ?? deformAt;\n const blendOf = plant.deformBlend ?? blendDeform;\n const evalFrame = plant.sequence ?? sequenceFrameAt;\n const shown: ShownGeometry[] = [];\n const why: string[] = [];\n const active = activeBones(doc);\n const gate = plant.slotTimelines ?? slotTimelinesApply;\n for (const slot of doc.slots) {\n // A slot on a bone the skin leaves inactive is not animated: no deform, no frame, no slider switch (`./skins.ts`).\n const live = gate(doc, slot, active);\n let placeholder = placeholders.get(slot.name) ?? null;\n const base = live ? mixed?.get(slot.name) : undefined;\n let deform: number[] | null = base?.deform ?? null;\n let frame: number | null = null;\n const seen: string[] = base === undefined ? [] : [...base.seen];\n // What the slot shows now, the record its timelines are keyed as, and what a deform or a frame is computed on.\n const state = (): { s: CoreShown; identity: string | null; vertices: ModelVertices | null; count: number | undefined } | null => {\n if (placeholder === null) return null;\n const s = resolve(doc, { ...slot, setup: placeholder });\n if (s === null || 'conflict' in s || s.record.geometry === undefined) return null;\n const g = s.record.geometry;\n const source = g.kind === 'linkedmesh' ? doc.skins.find((k) => k.name === g.skin)?.attachments[g.slot]?.[g.source] : s.record;\n const sg = source?.geometry;\n const vertices = sg !== undefined && sg.kind !== 'region' && sg.kind !== 'linkedmesh' ? sg.vertices : null;\n return { s, identity: timelineIdentity(slot.name, s), vertices, count: source?.sequenceCount };\n };\n const apply = (timelines: readonly CoreAttachmentTimeline[], t: number, blend: { alpha: number; additive: boolean } | null): void => {\n const now = state();\n if (now === null || now.identity === null) return;\n for (const a of timelines) {\n if (nameOf(a) !== now.identity) continue;\n if (!seen.includes(now.identity)) seen.push(now.identity);\n if (a.deform !== null && now.vertices !== null) {\n const target = evalDeform(now.vertices, a.deform, t);\n if (target !== null) deform = blend === null ? target : blendOf(now.vertices, deform, target, blend.alpha, blend.additive);\n }\n if (a.sequence !== null && now.count !== undefined) {\n const f = evalFrame(a.sequence, now.count, t);\n if (f !== null) frame = f;\n }\n }\n };\n if (sample !== null && live) apply(sample.timelines.attachments, sample.t, null);\n for (const app of live ? sliders : []) {\n // The slider's attachment key first, as the slot timelines are (`applySliderSlots` in `./constraints_slider.ts`); a switch to another placeholder clears what the timelines set.\n for (const target of app.timelines.slots) {\n if (target.name !== slot.name) continue;\n for (const tl of target.timelines) {\n if (tl.kind !== 'attachment' || tl.keys === undefined) continue;\n const i = keyIndexAt(tl.keys, app.at);\n if (i < 0) continue;\n const next = tl.keys[i].name ?? null;\n if (next !== placeholder) {\n deform = null;\n frame = null;\n }\n placeholder = next;\n }\n }\n apply(app.timelines.attachments, app.at, { alpha: app.alpha, additive: app.additive });\n }\n const now = state();\n if (now === null) continue;\n const entry: ShownGeometry = { slot: slot.name, bone: slot.bone, name: shownRow(now.s).name, placeholder: now.s.placeholder, skin: now.s.skin, geometry: now.s.record.geometry as CoreGeometry };\n shown.push(entry);\n const fillers = fillingSkins(doc, slot.name, now.s.placeholder).map((k) => `\"${k}\"`);\n if (seen.length > 0 && fillers.length > 1) {\n why.push(`slot \"${slot.name}\" shows placeholder \"${now.s.placeholder}\", which skins ${fillers.join(', ')} fill, and ${seen.map((x) => `\"${x}\"`).join(', ')} key(s) it — which record --skin all shows, and so whether the timeline moves it, is the Spine file's skin order, not the model's`);\n continue;\n }\n if (deform !== null) entry.deform = deform;\n if (frame !== null) entry.frame = frame;\n }\n return { shown, why };\n}\n","/**\n * Construct 4 of the core, its remainder (issue #955, step 2f of issue #380):\n * the draw order — at the setup pose, and a draw-order timeline's at a\n * sample time and under a slider.\n *\n * Every rule below was measured by posing hand-written skeletons through\n * `tools/pose_oracle.ts dump` (spine-core 4.3.13) and reading the slot names\n * the dump lists (`drawOrder`); nothing here was written from the runtime's\n * source. The core suite's `CD` controls hold the same skeletons against the\n * core.\n *\n * - **The setup order is the slot order** (`ModelSlot`: the model's slot\n * array is the draw order), on every probe and on 19 of 19 recipes.\n * - **A key's moves are a permutation of the SETUP order**, whatever the\n * order before it: each moved slot lands at its setup index plus its\n * offset, and the slots no key moves fill the remaining places in setup\n * order. The moves are applied as a set — the model holds them in the order\n * the spec states them, and the order they are listed in changes nothing.\n * - **Before the first key the setup order; a key with no moves restores\n * it.** Measured on 3,600 samples of 120 random timelines (three to eight\n * slots, one to four keys, one to three moves each, empty keys among them):\n * 0 misses.\n * - **Key times are float32**, as every key's (`./animation.ts`).\n * - **A slider applies its animation's draw-order key after the sample's, at\n * any mix but 0, and writes nothing before its first key**: a slider at\n * 0.5 over a key at 0.3 moving the first of three slots two places read\n * `s1, s2, s0` at setup at mix 1, 0.5, 0.01 and −1, and the setup order at\n * mix 0 and at a time before the key.\n *\n * 🚫 **Two moves landing on one place are refused by `readModel`, by name.**\n * The writer refuses a slot moved twice and a destination outside the slots\n * (`compileDrawOrder` in `src/compile.ts`), not two slots sent to one\n * destination; the runtime's fill then leaves a slot out and lists another\n * twice (the compiler's note on the parser), which is a parser's accident\n * and not an order to reproduce.\n */\nimport type { ModelSlot } from '../model.ts';\nimport { keyIndexAt } from './animation.ts';\n\n/** One draw-order key, as read: its time (float32) and its moves as slot indices, empty for the setup order. */\nexport interface CoreDrawOrderKey {\n time: number;\n moves: Array<{ slot: number; offset: number }>;\n}\n\nconst isRecord = (v: unknown): v is Record<string, unknown> => typeof v === 'object' && v !== null && !Array.isArray(v);\n\n/**\n * An animation record's `drawOrder` keys, read: times strictly increasing,\n * every move naming a slot of the document once per key, a whole offset\n * landing inside the slots, no two moves landing on one place.\n */\nexport function readDrawOrderKeys(value: unknown, label: string, slots: readonly ModelSlot[], problems: string[]): CoreDrawOrderKey[] {\n const where = `${label}.drawOrder`;\n if (!Array.isArray(value)) {\n problems.push(`${where} is not a list`);\n return [];\n }\n const indexOf = new Map(slots.map((s, i) => [s.name, i]));\n const out: CoreDrawOrderKey[] = [];\n let last = -Infinity;\n value.forEach((k, i) => {\n const at = `${where}[${i}]`;\n if (!isRecord(k)) {\n problems.push(`${at} is not an object`);\n return;\n }\n for (const key of Object.keys(k)) if (key !== 'time' && key !== 'offsets') problems.push(`${at}: field \"${key}\" is not one a draw-order key carries; it carries [time, offsets]`);\n const t = k.time;\n if (typeof t !== 'number' || !Number.isFinite(t) || t < 0) problems.push(`${at}: time is ${JSON.stringify(t)}, not a finite time at or after 0`);\n else if (t <= last) problems.push(`${at}: time ${t} is not after the key before it — the writer refuses key times that do not strictly increase`);\n if (typeof t === 'number' && Number.isFinite(t)) last = Math.max(last, t);\n const moves: CoreDrawOrderKey['moves'] = [];\n if (k.offsets !== undefined) {\n if (!Array.isArray(k.offsets)) problems.push(`${at}: offsets is not a list`);\n else {\n const landed = new Map<number, string>();\n k.offsets.forEach((o: unknown, j: number) => {\n const oat = `${at}.offsets[${j}]`;\n if (!isRecord(o) || typeof o.slot !== 'string') {\n problems.push(`${oat} names no slot`);\n return;\n }\n const index = indexOf.get(o.slot);\n if (index === undefined) {\n problems.push(`${oat}: \"${o.slot}\" is not a slot of this document`);\n return;\n }\n if (typeof o.offset !== 'number' || !Number.isInteger(o.offset)) {\n problems.push(`${oat}: slot \"${o.slot}\" offset is ${JSON.stringify(o.offset)}, not a whole number`);\n return;\n }\n if (moves.some((m) => m.slot === index)) problems.push(`${oat}: slot \"${o.slot}\" is moved twice in one key`);\n const to = index + o.offset;\n if (to < 0 || to >= slots.length) problems.push(`${oat}: slot \"${o.slot}\" is at ${index} and offset ${o.offset} lands at ${to}, outside the ${slots.length} slots`);\n else if (landed.has(to)) problems.push(`${oat}: slot \"${o.slot}\" lands at ${to}, where slot \"${landed.get(to)}\" lands too — two moves on one place leave a slot out of the runtime's order`);\n else landed.set(to, o.slot);\n moves.push({ slot: index, offset: o.offset });\n });\n }\n }\n out.push({ time: Math.fround(typeof t === 'number' && Number.isFinite(t) ? t : 0), moves });\n });\n return out;\n}\n\n/** The slot indices in the order a key's moves put them — the header's permutation of the setup order. */\nexport function orderOf(count: number, moves: CoreDrawOrderKey['moves']): number[] {\n const order = new Array<number>(count).fill(-1);\n for (const m of moves) order[m.slot + m.offset] = m.slot;\n const moved = new Set(moves.map((m) => m.slot));\n const rest = Array.from({ length: count }, (_v, i) => i).filter((i) => !moved.has(i));\n let next = 0;\n for (let i = 0; i < count; i++) if (order[i] === -1) order[i] = rest[next++];\n return order;\n}\n\n/** What evaluates a draw-order timeline: `drawOrderAt` unless a plant passes another. */\nexport type DrawOrderEvaluator = (count: number, keys: readonly CoreDrawOrderKey[], t: number) => number[] | null;\n\n/** The order a timeline sets at `t` as slot indices, or `null` before its first key. */\nexport function drawOrderAt(count: number, keys: readonly CoreDrawOrderKey[], t: number): number[] | null {\n const i = keyIndexAt(keys, t);\n return i < 0 ? null : orderOf(count, keys[i].moves);\n}\n","/**\n * Construct 4 of the core, its remainder (issue #955, step 2f of issue #380):\n * the events an animation's event timeline fires between two samples — the\n * oracle's per-sample `events` block, `[name, time, int, float, string]`.\n *\n * Every rule below was measured by posing hand-written skeletons through\n * `tools/pose_oracle.ts dump` (spine-core 4.3.13) and reading the block back;\n * nothing here was written from the runtime's source. The core suite's `CD`\n * controls hold the same skeletons against the core.\n *\n * - **A sample lists the keys whose time is in `(previous sample's t, t]`**,\n * the first sample's interval opening at −1: an event keyed at 0.25 fired\n * at the sample at 0.25 and not at the one after; one keyed at 0 fired at\n * the first sample; on an animation of duration 0 every sample sits at 0,\n * and the keys at 0 fired at the first sample alone.\n * - **Key times are float32**: an event keyed at 0.1 (float32\n * 0.10000000149) did not fire at a sample at 0.1 but at the next.\n * - **In key order**: two events keyed at one time fired in the order the\n * keys are listed.\n * - **The row's time is the key's (float32), and each of `int`, `float`,\n * `string` is the key's where it states one, else the event\n * definition's, else the parser's `0`, `0`, `\"\"`** — an event declared with\n * no string read `\"\"`, not `null` (so `tools/pose_oracle.ts`' header, which\n * said `null`, was wrong about the runtime and says so now). `volume` and\n * `balance` are the audio's, and the block does not carry them.\n * - **`float` is the double the document states**, the definition's and the\n * key's alike: `0.1000065`, which rounds to `0.100007` as a double and to\n * `0.100006` through `Math.fround`, read `0.100007` from each.\n * - A slider fires no event into the block: the oracle lists the events of\n * the sample's own animation.\n */\nimport { gridRound } from './index.ts';\n\n/** An event definition, as the model states it (`ModelEvent`): the payload a key falls back to. */\nexport interface CoreEventDef {\n name: string;\n int: number;\n float: number;\n string: string;\n}\n\n/** One event key, as read: its time (float32) and the payload it fires with, each field resolved. */\nexport interface CoreEventKey {\n time: number;\n name: string;\n int: number;\n float: number;\n string: string;\n}\n\n/** One row of a sample's `events` block: `[name, time, int, float, string]`, the oracle's row. */\nexport type CoreEventRow = [string, number | null, number, number | null, string | null];\n\nconst isRecord = (v: unknown): v is Record<string, unknown> => typeof v === 'object' && v !== null && !Array.isArray(v);\nconst EVENT_DEF_FIELDS = ['name', 'int', 'float', 'string', 'audio', 'volume', 'balance'] as const;\nconst EVENT_KEY_FIELDS = ['time', 'name', 'int', 'float', 'string', 'volume', 'balance'] as const;\n\nfunction payload(raw: Record<string, unknown>, at: string, problems: string[]): { int?: number; float?: number; string?: string } {\n const out: { int?: number; float?: number; string?: string } = {};\n if (raw.int !== undefined) {\n if (typeof raw.int !== 'number' || !Number.isInteger(raw.int)) problems.push(`${at}: int is ${JSON.stringify(raw.int)}, not a whole number`);\n else out.int = raw.int;\n }\n if (raw.float !== undefined) {\n if (typeof raw.float !== 'number' || !Number.isFinite(raw.float)) problems.push(`${at}: float is ${JSON.stringify(raw.float)}, not a finite number`);\n else out.float = raw.float;\n }\n if (raw.string !== undefined) {\n if (typeof raw.string !== 'string') problems.push(`${at}: string is ${JSON.stringify(raw.string)}, not a string`);\n else out.string = raw.string;\n }\n for (const key of ['volume', 'balance'] as const) if (raw[key] !== undefined && (typeof raw[key] !== 'number' || !Number.isFinite(raw[key]))) problems.push(`${at}: ${key} is ${JSON.stringify(raw[key])}, not a finite number`);\n return out;\n}\n\n/** The document's `events` section, read: a list of named definitions, each name once, each field of its type. */\nexport function readEventDefs(value: unknown, problems: string[]): Map<string, CoreEventDef> {\n const out = new Map<string, CoreEventDef>();\n if (!Array.isArray(value)) {\n problems.push('events is not a list');\n return out;\n }\n value.forEach((raw, i) => {\n const at = `events[${i}]`;\n if (!isRecord(raw) || typeof raw.name !== 'string' || raw.name === '') {\n problems.push(`${at} names no event`);\n return;\n }\n for (const key of Object.keys(raw)) if (!(EVENT_DEF_FIELDS as readonly string[]).includes(key)) problems.push(`${at} \"${raw.name}\": field \"${key}\" is not one this reader knows; it reads [${EVENT_DEF_FIELDS.join(', ')}]`);\n if (raw.audio !== undefined && typeof raw.audio !== 'string') problems.push(`${at} \"${raw.name}\": audio is ${JSON.stringify(raw.audio)}, not a string`);\n if (out.has(raw.name)) problems.push(`${at}: event \"${raw.name}\" is declared twice`);\n const p = payload(raw, `${at} \"${raw.name}\"`, problems);\n out.set(raw.name, { name: raw.name, int: p.int ?? 0, float: p.float ?? 0, string: p.string ?? '' });\n });\n return out;\n}\n\n/** An animation record's `events` keys, read: each names a declared event, times do not go backwards (equal times are two firings), each field of its type. */\nexport function readEventKeys(value: unknown, label: string, defs: ReadonlyMap<string, CoreEventDef>, problems: string[]): CoreEventKey[] {\n const where = `${label}.events`;\n if (!Array.isArray(value)) {\n problems.push(`${where} is not a list`);\n return [];\n }\n const out: CoreEventKey[] = [];\n let last = -Infinity;\n value.forEach((raw, i) => {\n const at = `${where}[${i}]`;\n if (!isRecord(raw)) {\n problems.push(`${at} is not an object`);\n return;\n }\n for (const key of Object.keys(raw)) if (!(EVENT_KEY_FIELDS as readonly string[]).includes(key)) problems.push(`${at}: field \"${key}\" is not one an event key carries; it carries [${EVENT_KEY_FIELDS.join(', ')}]`);\n const t = raw.time;\n if (typeof t !== 'number' || !Number.isFinite(t) || t < 0) problems.push(`${at}: time is ${JSON.stringify(t)}, not a finite time at or after 0`);\n else if (t < last) problems.push(`${at}: time ${t} is before the key before it — the writer refuses event times that go backwards`);\n if (typeof t === 'number' && Number.isFinite(t)) last = Math.max(last, t);\n const def = typeof raw.name === 'string' ? defs.get(raw.name) : undefined;\n if (def === undefined) {\n problems.push(`${at}: event ${JSON.stringify(raw.name)} is not declared in the document's events`);\n return;\n }\n const p = payload(raw, at, problems);\n out.push({ time: Math.fround(typeof t === 'number' && Number.isFinite(t) ? t : 0), name: def.name, int: p.int ?? def.int, float: p.float ?? def.float, string: p.string ?? def.string });\n });\n return out;\n}\n\n/** What lists the events fired over `(last, t]` — or across the wrap when `wrapped` — : `eventsFired` unless a plant passes another. */\nexport type EventsFired = (keys: readonly CoreEventKey[], last: number, t: number, round?: (v: number) => number | null, wrapped?: boolean) => CoreEventRow[];\n\n/**\n * The rows of the keys fired over `(last, t]`, in key order — the header's\n * rules, rounded as the oracle rounds. `wrapped` is a looping track's step\n * whose animation time went down (`t < last`, the wrap): the keys after\n * `last`, in key order, then the keys at or before `t`, in key order — the\n * header's *Across the wrap*. Nothing but a looping track passes it.\n */\nexport function eventsFired(keys: readonly CoreEventKey[], last: number, t: number, round: (v: number) => number | null = gridRound, wrapped = false): CoreEventRow[] {\n const row = (k: CoreEventKey): CoreEventRow => [k.name, round(k.time), k.int, round(k.float), k.string];\n if (wrapped) return [...keys.filter((k) => k.time > last), ...keys.filter((k) => k.time <= t)].map(row);\n return keys.filter((k) => k.time > last && k.time <= t).map(row);\n}\n","/**\n * The core's sixth construct: clipping applied to the draw (issue #964, §5\n * item 6 of the design on issue #380) — the oracle's `clipped` block, the\n * triangles every region and mesh drawn while a clip is active hands to the\n * runtime's clipper, as the clipper returns them.\n *\n * ## How every rule below was fixed\n *\n * By running spine-core 4.3.13's `SkeletonClipping` — `clipStart`,\n * `clipEnd(slot)`, `clipEnd()`, `isClipping` and `clipTrianglesUnpacked`, the\n * calls `src/render.ts` makes, in the order it makes them — on hand-written\n * skeletons and on random triangles and polygons, and reading what it\n * returned: the return value, `clippedVerticesTyped`, `clippedUVsTyped`,\n * `clippedTrianglesTyped`. The runtime's source was not read. Each rule is a\n * reading that reproduced every case measured, next to the readings the\n * measurements rejected. The core suite's `CL` controls hold a hand-written\n * skeleton of every case against the runtime at tolerance 0.\n *\n * ## When a clip is active — the draw walk\n *\n * The walk is `src/render.ts`'s `piecesOf`: slots in the posed draw order; at\n * a clipping attachment, end the clip if this slot is its end, then start\n * this clip if its slot's bone is active and no clip is active; at every\n * other slot, clip what it draws while a clip is active, then end the clip\n * if this slot is its end. Measured on one hand-written skeleton per case:\n *\n * | case | read |\n * | --- | --- |\n * | a clip ending at a slot | that slot is clipped, the one after it is not |\n * | ending at a slot that shows nothing | ends there all the same |\n * | ending at a slot drawn BEFORE the clip, or at its own slot | never ends: every later slot is clipped |\n * | no end slot | every later slot is clipped |\n * | a second clip while the first is active | ignored: a region inside the second and outside the first read wholly cut |\n * | a second clip after the first ended | applies |\n * | a clip ending at the slot of the next clip | the next clip starts there |\n * | a clip on an inactive bone | starts nothing |\n * | a region on an inactive bone under a clip | clipped like any other |\n *\n * ## What one triangle becomes\n *\n * The clip polygon is the clipping attachment's world polygon (the `clips`\n * row, `./vertices.ts`), unrounded. When its signed area is positive (counter\n * clockwise, y up) its vertices are reversed, so it is walked clockwise, and\n * its edges are taken from vertex 0: `(v0, v1), (v1, v2), …, (vn-1, v0)`.\n * A point is inside an edge `(p, q)` when `(q.x − p.x)(y − p.y) − (q.y −\n * p.y)(x − p.x) < 0`, strictly.\n *\n * Each triangle `(a, b, c)` of the attachment, in its own order, is clipped\n * edge by edge (Sutherland–Hodgman): walking the current polygon's sides\n * `(s, e)` from `(v0, v1)` round to `(vk, v0)`, an inside `s` with an inside\n * `e` keeps `e`; inside to outside adds the intersection; outside to inside\n * adds the intersection and then `e`; outside to outside adds nothing. The\n * intersection is `s + t·(e − s)` with `t = ((q.x − p.x)(s.y − p.y) − (q.y −\n * p.y)(s.x − p.x)) / ((q.y − p.y)(e.x − s.x) − (q.x − p.x)(e.y − s.y))`, in\n * doubles. A triangle no side of which was outside any edge is returned as it\n * came, `a, b, c` — not the rotation the walk leaves it in. A result of fewer\n * than three points adds nothing; otherwise its points are appended and fanned\n * from the first: `(0, 1, 2), (0, 2, 3), …` offset by the vertices already\n * written. The clipper stores vertices and UVs as float32: every number\n * written goes through `Math.fround`.\n *\n * A triangle no side of which was outside any edge keeps its corners' own\n * UVs (through `Math.fround`) rather than weighing them — the two agree on\n * the grid, and on three rows of `spineboy-pro`'s portal the weighed UV of a\n * corner at 0 read `2e-17` where the runtime holds 0 (issue #966, `dump\n * --raw`). Each point of a triangle that was cut has a UV barycentric over\n * the source triangle, from the unrounded\n * point: with `d = 1 / ((b.y − c.y)(a.x − c.x) + (c.x − b.x)(a.y − c.y))`,\n * `wa = ((b.y − c.y)(x − c.x) + (c.x − b.x)(y − c.y))·d`,\n * `wb = ((c.y − a.y)(x − c.x) + (a.x − c.x)(y − c.y))·d`, `wc = 1 − wa − wb`,\n * and `uv = ua·wa + ub·wb + uc·wc`, the corner UVs read through\n * `Math.fround`.\n *\n * The clipper returns `true` when any triangle had a point outside any edge,\n * else `false` — and `src/render.ts` then draws the attachment's own geometry.\n *\n * Measured on 2641 random cases, every polygon strictly convex, both\n * windings, one to three triangles of both windings each: 400 against\n * polygons of three to seven vertices, 600 whose intersections fall near the\n * origin, 1200 with corner UVs chosen so the weights' rounding shows, 300\n * cutting one edge once, and 141 random star polygons that came out convex —\n * the vertex list, the UVs, the triangle list and the return value exact on\n * 2641 of 2641. On the public corpus, `spineboy-pro`'s portal animation\n * (a three-vertex clip ending at a slot) reads IDENTICAL at tolerance 0 on\n * 4338 rows drawn under it (241 dense samples; 2653 left whole, 106 cut,\n * 1579 cut away). Rejected readings, each with what it read:\n *\n * | reading | read |\n * | --- | --- |\n * | the polygon's own winding, edges from vertex 0 | triangle lists 219 of 400; vertices 36 |\n * | the polygon made counter-clockwise, inside on the left | triangle lists 400; vertices in order 130 of 400 |\n * | a triangle wholly inside returned as the walk leaves it | 396 of 400 in order — the four wholly inside rotated |\n * | the polygon as its JSON spells it, through `Math.fround` | 79 of 400 exact: the world polygon carries the bone's matrix (`b` is `cos 90°` at the runtime's pi, −2.3e-8) |\n * | the intersection from the clip edge, `p + u·(q − p)` | 228 of 300 on a horizontal edge at y = 0, where `s + t·(e − s)` read 300 |\n * | the UV weights by a division rather than a reciprocal | 586 of 600 |\n * | the UV weights relative to `a` (`wb, wc` solved, `wa = 1 − wb − wc`) | 105 of 600 |\n *\n * ## What is not posed, and why\n *\n * The block is left out, naming the slot, when a clip that starts is one of:\n *\n * - ⚠️ **not strictly convex** — a reflex vertex, three collinear vertices or\n * a repeated one. The runtime decomposes such a polygon into convex pieces\n * and clips each triangle against each piece in turn: a covering triangle\n * read the pieces (a notched square into three triangles, an L into two\n * quads; a collinear vertex dropped; a repeated vertex clipped everything\n * away). Which pieces, in which order and from which vertex is the\n * runtime's own decomposition, and the dump alone did not fix it (issue\n * #964's report). Posing it would be guessing an algorithm.\n * - **`inverse`** — the clip keeps what is outside the polygon, through a\n * decomposition of the triangle around it (a covering triangle came back as\n * fifteen vertices in five fans). Not measured past that.\n *\n * What the core DRAWS under such a clip — a decomposition of its own, the\n * `clipped` block still left out — is the last section of this file\n * (`clipThrough`, issue #964).\n *\n * `convex: true` on a strictly convex polygon changes nothing: 400 of 400\n * cases byte-identical with and without it. On a polygon that is not, the\n * runtime clips against its convex hull (a notched square with `convex` read\n * as the square); that is the first case above and is left out.\n */\n/** One row of `clipped`: `[slot, attachment, clipped, vertices, uvs, triangles]`, the oracle's row. */\nexport type CoreClippedRow = [string, string, 0 | 1, Array<number | null>, Array<number | null>, number[]];\n\n/** What the clipper returns for one attachment: the return value and the three arrays, unrounded to the oracle's grid. */\nexport interface ClipResult {\n clipped: boolean;\n vertices: number[];\n uvs: number[];\n triangles: number[];\n /** The source triangle (an index into the attachment's triangles by threes) each returned triangle was cut from — what the render samples it at (issue #964). */\n sources: number[];\n}\n\ntype Pt = [number, number];\n\n/**\n * The readings the header's table rejected, each a switch — what the core\n * suite's `CL` plants pass to show the gate names it. `clipTriangles` with\n * none set is the rule measured; nothing but a plant sets one.\n */\nexport interface ClipReading {\n /** Walk the polygon in its own winding, not clockwise. */\n ownWinding?: boolean;\n /** Walk the polygon counter-clockwise — the runtime's winding flipped. */\n flippedWinding?: boolean;\n /** Return a triangle wholly inside as the walk leaves it. */\n insideRotated?: boolean;\n /** Take the intersection from the clip edge, `p + u·(q − p)`. */\n fromClipEdge?: boolean;\n /** Divide the UV weights by the determinant rather than multiply by its reciprocal. */\n uvByDivision?: boolean;\n}\n\n/** A world polygon's signed area, doubled: positive when counter-clockwise (y up). */\nexport function signedArea2(polygon: readonly number[]): number {\n let a = 0;\n const n = polygon.length / 2;\n for (let i = 0; i < n; i++) {\n const j = (i + 1) % n;\n a += polygon[2 * i] * polygon[2 * j + 1] - polygon[2 * j] * polygon[2 * i + 1];\n }\n return a;\n}\n\n/** Why a world polygon is not one the core clips against — not strictly convex — or null. */\nexport function convexWhy(polygon: readonly number[]): string | null {\n const n = polygon.length / 2;\n if (n < 3) return `it has ${n} vertex(es)`;\n let sign = 0;\n for (let i = 0; i < n; i++) {\n const [ax, ay] = [polygon[2 * i], polygon[2 * i + 1]];\n const j = (i + 1) % n;\n const k = (i + 2) % n;\n const cross = (polygon[2 * j] - ax) * (polygon[2 * k + 1] - polygon[2 * j + 1]) - (polygon[2 * j + 1] - ay) * (polygon[2 * k] - polygon[2 * j]);\n if (cross === 0) return `vertices ${i}, ${j} and ${k} are collinear or repeated`;\n const s = Math.sign(cross);\n if (sign === 0) sign = s;\n else if (s !== sign) return `vertex ${j} turns against the others (a reflex vertex)`;\n }\n return null;\n}\n\n/** The polygon walked clockwise, as the clipper walks it (the header). */\nfunction clockwise(polygon: readonly number[], reading: ClipReading): Pt[] {\n const pts: Pt[] = [];\n for (let i = 0; i + 1 < polygon.length; i += 2) pts.push([polygon[i], polygon[i + 1]]);\n if (reading.ownWinding === true) return pts;\n const cw = signedArea2(polygon) > 0 ? pts.reverse() : pts;\n return reading.flippedWinding === true ? cw.reverse() : cw;\n}\n\nfunction intersectFromClipEdge(s: Pt, e: Pt, p: Pt, q: Pt): Pt {\n const dx = e[0] - s[0];\n const dy = e[1] - s[1];\n const ex = q[0] - p[0];\n const ey = q[1] - p[1];\n const u = (dx * (s[1] - p[1]) - dy * (s[0] - p[0])) / (ey * dx - ex * dy);\n return [p[0] + u * ex, p[1] + u * ey];\n}\n\nfunction intersect(s: Pt, e: Pt, p: Pt, q: Pt): Pt {\n const dx = e[0] - s[0];\n const dy = e[1] - s[1];\n const ex = q[0] - p[0];\n const ey = q[1] - p[1];\n const t = (ex * (s[1] - p[1]) - ey * (s[0] - p[0])) / (ey * dx - ex * dy);\n return [s[0] + t * dx, s[1] + t * dy];\n}\n\n/** One triangle against the clockwise polygon: the points, and whether any side was outside any edge. */\nfunction clipTriangle(tri: readonly Pt[], poly: readonly Pt[], reading: ClipReading): { points: Pt[]; cut: boolean } {\n const cross = reading.fromClipEdge === true ? intersectFromClipEdge : intersect;\n let input: Pt[] = [...tri];\n let cut = false;\n for (let i = 0; i < poly.length && input.length > 0; i++) {\n const p = poly[i];\n const q = poly[(i + 1) % poly.length];\n const inside = (v: Pt): boolean => (q[0] - p[0]) * (v[1] - p[1]) - (q[1] - p[1]) * (v[0] - p[0]) < 0;\n const out: Pt[] = [];\n for (let k = 0; k < input.length; k++) {\n const s = input[k];\n const e = input[(k + 1) % input.length];\n const si = inside(s);\n const ei = inside(e);\n if (si) {\n if (ei) out.push(e);\n else {\n out.push(cross(s, e, p, q));\n cut = true;\n }\n } else {\n cut = true;\n if (ei) out.push(cross(s, e, p, q), e);\n }\n }\n input = out;\n }\n return { points: cut || reading.insideRotated === true ? input : [...tri], cut };\n}\n\n/**\n * An attachment's triangles clipped against a strictly convex world polygon —\n * the header's rule. `vertices` are the attachment's world vertices, `uvs`\n * one pair per vertex, `triangles` indices into them.\n */\nexport function clipTriangles(polygon: readonly number[], vertices: readonly number[], triangles: readonly number[], uvs: readonly number[], reading: ClipReading = {}): ClipResult {\n const poly = clockwise(polygon, reading);\n const f = Math.fround;\n const outV: number[] = [];\n const outUv: number[] = [];\n const outT: number[] = [];\n const sources: number[] = [];\n let clipped = false;\n for (let k = 0; k + 2 < triangles.length; k += 3) {\n const idx = [triangles[k], triangles[k + 1], triangles[k + 2]];\n const tri = idx.map((i): Pt => [vertices[2 * i], vertices[2 * i + 1]]);\n const tuv = idx.map((i): Pt => [f(uvs[2 * i]), f(uvs[2 * i + 1])]);\n const { points, cut } = clipTriangle(tri, poly, reading);\n for (let j = 1; j + 1 < points.length; j++) sources.push(k / 3);\n clipped ||= cut;\n if (points.length < 3) continue;\n const [a, b, c] = tri;\n const d0 = b[1] - c[1];\n const d1 = c[0] - b[0];\n const d2 = a[0] - c[0];\n const d4 = c[1] - a[1];\n const det = d0 * d2 + d1 * (a[1] - c[1]);\n const d = 1 / det;\n const weigh = (v: number): number => (reading.uvByDivision === true ? v / det : v * d);\n const base = outV.length / 2;\n // A triangle no side of which was outside any edge keeps its own corner UVs (issue #966): weighed barycentrically, a corner's UV of 0 reads 2e-17 off it, 3 rows of `spineboy-pro`'s portal.\n if (!cut && reading.insideRotated !== true) {\n tri.forEach(([x, y], k2) => {\n outV.push(f(x), f(y));\n outUv.push(tuv[k2][0], tuv[k2][1]);\n });\n for (let j = 1; j + 1 < points.length; j++) outT.push(base, base + j, base + j + 1);\n continue;\n }\n for (const [x, y] of points) {\n const wa = weigh(d0 * (x - c[0]) + d1 * (y - c[1]));\n const wb = weigh(d4 * (x - c[0]) + d2 * (y - c[1]));\n const wc = 1 - wa - wb;\n outV.push(f(x), f(y));\n outUv.push(f(tuv[0][0] * wa + tuv[1][0] * wb + tuv[2][0] * wc), f(tuv[0][1] * wa + tuv[1][1] * wb + tuv[2][1] * wc));\n }\n for (let j = 1; j + 1 < points.length; j++) outT.push(base, base + j, base + j + 1);\n }\n return { clipped, vertices: outV, uvs: outUv, triangles: outT, sources };\n}\n\n/** The clipper's reading of one attachment, replaceable by the suite's plants. */\nexport type TriangleClipper = (polygon: readonly number[], vertices: readonly number[], triangles: readonly number[], uvs: readonly number[]) => ClipResult;\n\n/** One step of the draw walk: a slot, what its bone's activity is, and what it shows as the walk reads it. */\nexport type DrawStep =\n | { slot: string; kind: 'clip'; attachment: string; active: boolean; end: string | null; polygon: number[]; inverse: boolean; convex: boolean }\n | { slot: string; kind: 'draw'; attachment: string; vertices: number[]; triangles: number[]; uvs: number[] }\n | { slot: string; kind: 'none' };\n\n/** The local UVs the oracle hands a region's four corners to the clipper with, in the corner order (bottom-left, upper-left, upper-right, bottom-right). */\nexport const REGION_UVS: readonly number[] = [0, 1, 0, 0, 1, 0, 1, 1];\n/** A region's two triangles over its four corners — the runtime's quad triangulation (`src/render.ts`'s `QUAD_TRIANGLES`). */\nexport const REGION_TRIANGLES: readonly number[] = [0, 1, 2, 2, 3, 0];\n\n/** `clipThrough`'s shape, replaceable by the render suite's plants (`RC08`'s dropped region). */\nexport type ShapeClipper = (shape: ClipShape, vertices: readonly number[], triangles: readonly number[], uvs: readonly number[]) => ClipResult | null;\n\n/**\n * The `clipped` block from the draw walk (the header's first table), every\n * number through `round`, or why it is absent: a clip that starts over a\n * polygon the core does not reproduce the runtime's triangle list for (not\n * strictly convex, or inverse), each named.\n *\n * Beside it, `drawn`: the same walk's rows as the core DRAWS them — the block's\n * own rows wherever the block is posed, and, where a clip that is not strictly\n * convex or is inverse starts, that clip cut through `clipThrough` (a\n * decomposition of the core's own, held to the runtime by the render's pixels,\n * issue #964). `drawnWhy` names a clip the core does not draw at all (a\n * polygon that is not simple).\n */\nexport function poseClipped(\n walk: readonly DrawStep[],\n round: (v: number) => number | null,\n clip: TriangleClipper = clipTriangles,\n through: ShapeClipper = (shape, v, t, uv) => clipThrough(shape, v, t, uv, clip),\n): { rows: CoreClippedRow[] | null; why: string | null; drawn: CoreClippedRow[] | null; drawnWhy: string | null } {\n const rows: CoreClippedRow[] = [];\n const refused: string[] = [];\n const undrawn: string[] = [];\n let active: { end: string | null; shape: ClipShape } | null = null;\n for (const step of walk) {\n if (step.kind === 'clip') {\n if (active !== null && active.end === step.slot) active = null;\n if (step.active && active === null) {\n const why = step.inverse ? 'it is inverse' : convexWhy(step.polygon);\n if (why !== null) refused.push(`slot \"${step.slot}\" starts clip \"${step.attachment}\", and ${why}`);\n const shape: ClipShape = { polygon: step.polygon, inverse: step.inverse, convex: step.convex };\n const plan = clipShapeOf(shape);\n if (plan.kind === 'refused') undrawn.push(`slot \"${step.slot}\" starts clip \"${step.attachment}\", and ${plan.why}`);\n active = { end: step.end, shape };\n }\n continue;\n }\n if (step.kind === 'draw' && active !== null) {\n const r = through(active.shape, step.vertices, step.triangles, step.uvs);\n if (r !== null) rows.push([step.slot, step.attachment, r.clipped ? 1 : 0, r.vertices.map(round), r.uvs.map(round), r.triangles]);\n }\n if (active !== null && active.end === step.slot) active = null;\n }\n const drawnWhy = undrawn.length === 0\n ? null\n : `${undrawn.join('; ')} — the runtime's coverage of a polygon that is not simple is its own triangulation's, measured not to be the polygon's area (src/core/clipping.ts)`;\n const drawn = drawnWhy === null ? rows : null;\n if (refused.length > 0) {\n return { rows: null, why: `${refused.join('; ')} — the runtime decomposes such a polygon into convex pieces of its own choosing, or clips the outside of an inverse one, and neither was reproduced from the dump (src/core/clipping.ts)`, drawn, drawnWhy };\n }\n return { rows, why: null, drawn, drawnWhy };\n}\n\n// ---------------------------------------------------------------------------\n// #964 what the core draws under a concave or inverse clip\n// ---------------------------------------------------------------------------\n//\n// The oracle's `clipped` block under such a clip is the runtime's own triangle list and stays\n// absent by name (above). What the core DRAWS there is a decomposition of its own, and the claim\n// it makes is coverage, not the list: the union of the pieces is the polygon whatever the pieces\n// are. Every reading below was fixed by running spine-core 4.3.13's `SkeletonClipping` (the calls\n// `src/render.ts` makes) and reading the area it returned; the source was not read, and the\n// runtime's decomposition was not reconstructed. The runtime's documentation of the two flags\n// (`ClippingAttachment.convex` / `.inverse` in its public type declarations) says `convex` clips\n// by the convex hull of a polygon that is not convex, and that inverse clipping is always convex.\n//\n// | polygon | the core | measured against spine-core |\n// | --- | --- | --- |\n// | strictly convex, not inverse | the measured rule above, one piece: the oracle's rows | the header's 2641 cases |\n// | simple, a reflex or a collinear vertex | collinear vertices dropped, ear clipping from vertex 0, pieces merged while strictly convex (Hertel–Mehlhorn); each triangle clipped against each piece in turn by the rule above | area and return value equal on every case of `CL05` |\n// | `convex: true`, simple | its convex hull, one piece | area equal (`CL05`); the hull is the documented reading |\n// | `inverse: true`, simple | the triangle outside the hull: for each hull edge in the walk, the part outside it and inside every edge before it | area and return value equal (`CL05`): the return value is `true` for every triangle, cut or not, as the runtime's was |\n// | an otherwise strictly convex polygon with a repeated vertex, not inverse | the rule above as it stands: its zero-length edge has no inside, so nothing is drawn | the runtime drew nothing on 141 of 141 random cases |\n// | a repeated vertex anywhere else | **refused**, naming the vertices | the runtime drew nothing on 11 of 159 random non-convex cases and the polygon's area on the other 148 — which, is its decomposition's |\n// | not simple (edges crossing or touching) | **refused**, naming the edges | a self-overlapping six-vertex fan read an area of 2.67 where its even-odd fill is 26.7, its non-zero fill 29.4 and its shoelace area 32; its `convex` and `inverse` readings used the same 2.67 |\n//\n// ⭐ The render draws through this pixel for pixel as spine-core draws (`RC08`), because the\n// rasteriser samples each drawn triangle at its SOURCE triangle's affine UV (`Mesh.source` in\n// `src/render.ts`, the source index being `ClipResult.sources`): before that, a pixel falling in\n// a sub-triangle other than the runtime's was sampled at a UV a few float32 steps off, and one\n// level of one channel moved on up to 50 pixels of a probe's frame set — as much as the runtime's\n// own render moved when the same polygon was spelled from another start vertex.\n\n/**\n * A clip as the draw reads it: its world polygon and its two flags. Which\n * reading `clipThrough` takes is `clipShapeOf`'s (the table in this section's\n * header, `clipThrough`).\n */\nexport interface ClipShape {\n polygon: readonly number[];\n inverse: boolean;\n convex: boolean;\n}\n\n/**\n * How a clip is drawn through the core: `convex` — the measured rule above,\n * one piece, the oracle's `clipped` block reproduced to the bit; `pieces` —\n * a simple polygon that is not strictly convex, cut into convex pieces of the\n * core's own choosing; `inverse` — the outside of the polygon's convex hull;\n * `empty` — an otherwise strictly convex polygon with a repeated vertex, which\n * the measured rule itself clips everything away against. `refused` names why\n * the core does not draw it.\n */\nexport type ClipPlan =\n | { kind: 'convex'; polygon: readonly number[] }\n | { kind: 'pieces'; pieces: Pt[][] }\n | { kind: 'inverse'; hull: Pt[] }\n | { kind: 'refused'; why: string };\n\nfunction pointsOf(polygon: readonly number[]): Pt[] {\n const pts: Pt[] = [];\n for (let i = 0; i + 1 < polygon.length; i += 2) pts.push([polygon[i], polygon[i + 1]]);\n return pts;\n}\n\nfunction cross3(o: Pt, a: Pt, b: Pt): number {\n return (a[0] - o[0]) * (b[1] - o[1]) - (a[1] - o[1]) * (b[0] - o[0]);\n}\n\n/** Whether segments `ab` and `cd` meet, touching included (exact arithmetic on the doubles given). */\nfunction segmentsMeet(a: Pt, b: Pt, c: Pt, d: Pt): boolean {\n const d1 = cross3(c, d, a);\n const d2 = cross3(c, d, b);\n const d3 = cross3(a, b, c);\n const d4 = cross3(a, b, d);\n if (((d1 > 0 && d2 < 0) || (d1 < 0 && d2 > 0)) && ((d3 > 0 && d4 < 0) || (d3 < 0 && d4 > 0))) return true;\n const on = (p: Pt, q: Pt, r: Pt): boolean => Math.min(p[0], q[0]) <= r[0] && r[0] <= Math.max(p[0], q[0]) && Math.min(p[1], q[1]) <= r[1] && r[1] <= Math.max(p[1], q[1]);\n return (d1 === 0 && on(c, d, a)) || (d2 === 0 && on(c, d, b)) || (d3 === 0 && on(a, b, c)) || (d4 === 0 && on(a, b, d));\n}\n\n/** Why a polygon of distinct vertices is not simple — two edges that are not neighbours meet, or a neighbour folds back over its edge — or null. */\nfunction selfCrossingWhy(pts: readonly Pt[]): string | null {\n const n = pts.length;\n for (let i = 0; i < n; i++) {\n const a = pts[i];\n const b = pts[(i + 1) % n];\n // A neighbour folding back: the next edge runs back along this one.\n const c = pts[(i + 2) % n];\n if (cross3(a, b, c) === 0 && (c[0] - b[0]) * (a[0] - b[0]) + (c[1] - b[1]) * (a[1] - b[1]) > 0) return `edges ${i} and ${(i + 1) % n} fold back over each other at vertex ${(i + 1) % n}`;\n for (let j = i + 2; j < n; j++) {\n if (i === 0 && j === n - 1) continue;\n if (segmentsMeet(a, b, pts[j], pts[(j + 1) % n])) return `edges ${i} and ${j} cross or touch (the polygon is not simple)`;\n }\n }\n return null;\n}\n\n/** The polygon with every vertex dropped that lies on the line through its two neighbours — the area is the same. */\nfunction withoutCollinear(pts: readonly Pt[]): Pt[] {\n let out = [...pts];\n for (let changed = true; changed && out.length > 3; ) {\n changed = false;\n for (let i = 0; i < out.length; i++) {\n const prev = out[(i + out.length - 1) % out.length];\n const next = out[(i + 1) % out.length];\n if (cross3(prev, out[i], next) === 0) {\n out = [...out.slice(0, i), ...out.slice(i + 1)];\n changed = true;\n break;\n }\n }\n }\n return out;\n}\n\n/** The convex hull (Andrew's monotone chain), counter-clockwise, no collinear vertex, from the lowest-leftmost point. */\nfunction convexHull(pts: readonly Pt[]): Pt[] {\n const sorted = [...pts].sort((p, q) => p[0] - q[0] || p[1] - q[1]);\n const half = (list: readonly Pt[]): Pt[] => {\n const h: Pt[] = [];\n for (const p of list) {\n while (h.length >= 2 && cross3(h[h.length - 2], h[h.length - 1], p) <= 0) h.pop();\n h.push(p);\n }\n h.pop();\n return h;\n };\n return [...half(sorted), ...half([...sorted].reverse())];\n}\n\nfunction ccw(pts: readonly Pt[]): Pt[] {\n const flat = pts.flat();\n return signedArea2(flat) < 0 ? [...pts].reverse() : [...pts];\n}\n\n/**\n * A simple counter-clockwise polygon with no collinear vertex cut into convex\n * pieces: ear clipping into triangles (the first ear from vertex 0, walking\n * forward), then every diagonal removed whose two pieces merge into a strictly\n * convex polygon (Hertel–Mehlhorn), in the order the diagonals were cut. Each\n * piece is counter-clockwise, over the polygon's own vertices — none added,\n * every one used.\n */\nexport function convexPieces(polygon: readonly number[]): number[][] {\n return piecesOf(ccw(withoutCollinear(pointsOf(polygon)))).map((piece) => piece.flat());\n}\n\nfunction piecesOf(pts: readonly Pt[]): Pt[][] {\n const n = pts.length;\n const idx = pts.map((_, i) => i);\n const tris: number[][] = [];\n const inTri = (p: Pt, a: Pt, b: Pt, c: Pt): boolean => cross3(a, b, p) >= 0 && cross3(b, c, p) >= 0 && cross3(c, a, p) >= 0;\n while (idx.length > 3) {\n let cut = false;\n for (let k = 0; k < idx.length; k++) {\n const i0 = idx[(k + idx.length - 1) % idx.length];\n const i1 = idx[k];\n const i2 = idx[(k + 1) % idx.length];\n if (cross3(pts[i0], pts[i1], pts[i2]) <= 0) continue;\n if (idx.some((j) => j !== i0 && j !== i1 && j !== i2 && inTri(pts[j], pts[i0], pts[i1], pts[i2]))) continue;\n tris.push([i0, i1, i2]);\n idx.splice(k, 1);\n cut = true;\n break;\n }\n if (!cut) throw new Error(`convexPieces: no ear left among vertices [${idx.join(', ')}] of a polygon the caller held simple — a defect in src/core/clipping.ts`);\n }\n tris.push([...idx]);\n // Hertel–Mehlhorn: merge across a shared edge while the union stays strictly convex.\n let pieces = tris.map((t) => [...t]);\n const strictlyConvex = (ring: readonly number[]): boolean => ring.every((v, i) => cross3(pts[ring[(i + ring.length - 1) % ring.length]], pts[v], pts[ring[(i + 1) % ring.length]]) > 0);\n for (let merged = true; merged; ) {\n merged = false;\n search: for (let a = 0; a < pieces.length; a++) {\n for (let b = a + 1; b < pieces.length; b++) {\n const A = pieces[a];\n const B = pieces[b];\n for (let i = 0; i < A.length; i++) {\n const u = A[i];\n const v = A[(i + 1) % A.length];\n const j = B.indexOf(v);\n if (j < 0 || B[(j + 1) % B.length] !== u) continue;\n // A walks u→v, B walks v→u: splice B's other vertices in between.\n const rest: number[] = [];\n for (let k = (j + 2) % B.length; k !== j; k = (k + 1) % B.length) rest.push(B[k]);\n const ring = [...A.slice(0, i + 1), ...rest, ...A.slice(i + 1)];\n if (!strictlyConvex(ring)) continue;\n pieces = [...pieces.slice(0, a), ring, ...pieces.slice(a + 1, b), ...pieces.slice(b + 1)];\n merged = true;\n break search;\n }\n }\n }\n }\n if (n !== new Set(pieces.flat()).size) throw new Error('convexPieces: a vertex is in no piece — a defect in src/core/clipping.ts');\n return pieces.map((ring) => ring.map((v) => pts[v]));\n}\n\n/**\n * Which reading a clip is drawn through (this section's `ClipPlan`), from its\n * world polygon and flags. A strictly convex polygon (`convexWhy` null) is the\n * measured rule whatever its flags say but `inverse`; `convex` on any other\n * simple polygon, and `inverse` always, read its convex hull, as the\n * runtime's own documentation of the two flags states.\n */\nexport function clipShapeOf(shape: ClipShape): ClipPlan {\n const pts = pointsOf(shape.polygon);\n if (pts.length < 3) return { kind: 'refused', why: `it has ${pts.length} vertex(es)` };\n const repeated: string[] = [];\n for (let i = 0; i < pts.length; i++) for (let j = i + 1; j < pts.length; j++) if (pts[i][0] === pts[j][0] && pts[i][1] === pts[j][1]) repeated.push(`${i} and ${j}`);\n if (repeated.length > 0) {\n // Consecutive repeats of an otherwise strictly convex polygon: the measured rule, whose zero-length edge has no inside.\n const distinct = pts.filter((p, i) => { const q = pts[(i + 1) % pts.length]; return p[0] !== q[0] || p[1] !== q[1]; });\n if (!shape.inverse && distinct.length === pts.length - repeated.length && distinct.length >= 3 && convexWhy(distinct.flat()) === null) return { kind: 'convex', polygon: shape.polygon };\n return { kind: 'refused', why: `vertices ${repeated.join(', ')} are the same point` };\n }\n const crossing = selfCrossingWhy(pts);\n if (crossing !== null) return { kind: 'refused', why: crossing };\n const simple = withoutCollinear(pts);\n if (cross3(simple[0], simple[1], simple[2]) === 0 && simple.length === 3) return { kind: 'refused', why: 'every vertex lies on one line' };\n if (shape.inverse) return { kind: 'inverse', hull: convexHull(simple) };\n if (convexWhy(shape.polygon) === null) return { kind: 'convex', polygon: shape.polygon };\n if (shape.convex) return { kind: 'convex', polygon: convexHull(simple).flat() };\n const pieces = piecesOf(ccw(simple));\n return pieces.length === 1 ? { kind: 'convex', polygon: pieces[0].flat() } : { kind: 'pieces', pieces };\n}\n\n/** Clip `input` to the inside of the edge `(p, q)` — one Sutherland–Hodgman step of `clipTriangle`, the same inside test and intersection. */\nfunction clipHalf(input: readonly Pt[], p: Pt, q: Pt): { points: Pt[]; cut: boolean } {\n const inside = (v: Pt): boolean => (q[0] - p[0]) * (v[1] - p[1]) - (q[1] - p[1]) * (v[0] - p[0]) < 0;\n const out: Pt[] = [];\n let cut = false;\n for (let k = 0; k < input.length; k++) {\n const s = input[k];\n const e = input[(k + 1) % input.length];\n const si = inside(s);\n const ei = inside(e);\n if (si) {\n if (ei) out.push(e);\n else {\n out.push(intersect(s, e, p, q));\n cut = true;\n }\n } else {\n cut = true;\n if (ei) out.push(intersect(s, e, p, q), e);\n }\n }\n return { points: out, cut };\n}\n\n/**\n * An attachment's triangles clipped against any clip the core draws\n * (`clipShapeOf`): the measured convex rule for a strictly convex polygon —\n * `clipTriangles` itself, so the oracle's rows stand — and otherwise, triangle\n * by triangle in the attachment's order, each convex region of the plan in\n * turn, every region cut exactly as a convex clip cuts it (a region a triangle\n * lies wholly inside keeps its corners and their UVs; a cut one is weighed and\n * fanned from its first point). `null` where the plan is refused.\n *\n * `inverse`: the regions are the triangle's parts outside the clockwise hull,\n * one per hull edge in the walk's order — outside edge `i` and inside every\n * edge before it — so they tile the triangle minus the hull without overlap.\n */\nexport function clipThrough(\n shape: ClipShape,\n vertices: readonly number[],\n triangles: readonly number[],\n uvs: readonly number[],\n clip: TriangleClipper = clipTriangles,\n reading: { dropRegion?: number } = {},\n): ClipResult | null {\n const plan = clipShapeOf(shape);\n if (plan.kind === 'refused') return null;\n if (plan.kind === 'convex') return clip(plan.polygon, vertices, triangles, uvs);\n const f = Math.fround;\n const outV: number[] = [];\n const outUv: number[] = [];\n const outT: number[] = [];\n const sources: number[] = [];\n let clipped = false;\n const regions = plan.kind === 'pieces' ? plan.pieces.map((piece) => clockwise(piece.flat(), {})) : null;\n const hull = plan.kind === 'inverse' ? clockwise(plan.hull.flat(), {}) : [];\n for (let k = 0; k + 2 < triangles.length; k += 3) {\n const idx = [triangles[k], triangles[k + 1], triangles[k + 2]];\n const tri = idx.map((i): Pt => [vertices[2 * i], vertices[2 * i + 1]]);\n const tuv = idx.map((i): Pt => [f(uvs[2 * i]), f(uvs[2 * i + 1])]);\n const parts: Array<{ points: Pt[]; cut: boolean }> = [];\n if (regions !== null) for (const poly of regions) parts.push(clipTriangle(tri, poly, {}));\n else {\n let remaining: Pt[] = [...tri];\n let cutSoFar = false;\n for (let i = 0; i < hull.length && remaining.length > 0; i++) {\n const p = hull[i];\n const q = hull[(i + 1) % hull.length];\n const outside = clipHalf(remaining, q, p);\n parts.push({ points: outside.cut || cutSoFar ? outside.points : [...tri], cut: outside.cut || cutSoFar });\n const inside = clipHalf(remaining, p, q);\n cutSoFar ||= inside.cut;\n remaining = inside.points;\n }\n clipped = true;\n }\n const [a, b, c] = tri;\n const d0 = b[1] - c[1];\n const d1 = c[0] - b[0];\n const d2 = a[0] - c[0];\n const d4 = c[1] - a[1];\n const d = 1 / (d0 * d2 + d1 * (a[1] - c[1]));\n for (const [r, { points, cut }] of parts.entries()) {\n clipped ||= cut;\n // `CL05`'s plant: one region of the plan dropped. Nothing but a plant sets it.\n if (r === reading.dropRegion) continue;\n if (points.length < 3) continue;\n const base = outV.length / 2;\n if (!cut) {\n tri.forEach(([x, y], k2) => {\n outV.push(f(x), f(y));\n outUv.push(tuv[k2][0], tuv[k2][1]);\n });\n } else {\n for (const [x, y] of points) {\n const wa = (d0 * (x - c[0]) + d1 * (y - c[1])) * d;\n const wb = (d4 * (x - c[0]) + d2 * (y - c[1])) * d;\n const wc = 1 - wa - wb;\n outV.push(f(x), f(y));\n outUv.push(f(tuv[0][0] * wa + tuv[1][0] * wb + tuv[2][0] * wc), f(tuv[0][1] * wa + tuv[1][1] * wb + tuv[2][1] * wc));\n }\n }\n for (let j = 1; j + 1 < points.length; j++) {\n outT.push(base, base + j, base + j + 1);\n sources.push(k / 3);\n }\n }\n }\n return { clipped, vertices: outV, uvs: outUv, triangles: outT, sources };\n}\n","/**\n * The core's third construct: every drawn attachment's world vertices at the\n * setup pose (issue #931, step 2c of issue #380) — the oracle's\n * `setup.attachments` block, a region's four corners and a mesh's vertices,\n * and its `setup.clips` block, a clipping polygon and the slot its clip ends\n * at. It is the first construct where the core's arithmetic meets geometry the\n * compiler measured, so exact equivalence here is also a check on the model.\n *\n * ## How every rule below was fixed\n *\n * By posing hand-written skeletons through `tools/pose_oracle.ts dump`\n * (spine-core 4.3.13, `--skin all`, `--physics none`) and comparing a formula\n * over the core's own world transforms (`./world.ts`) with the rows the dump\n * printed, at tolerance 0 on the oracle's six-decimal grid. The runtime's\n * source was not read. The bone rows read exact in every probe, so every\n * residual below belongs to the attachment rule. The core suite's `CO17`\n * holds a hand-written skeleton of every case against the core at tolerance 0.\n *\n * ## A region's four corners\n *\n * Let `W, H` be the record's `width, height`, `sx, sy` its `scaleX, scaleY`\n * (1 unstated), and `ox, oy, w, h, ow, oh` its atlas rectangle's `offsetX,\n * offsetY, width, height, originalWidth, originalHeight` (`ModelAtlasRect`,\n * issue #935). With `kx = W/ow·sx` and `ky = H/oh·sy`:\n *\n * x1 = −W/2·sx + ox·kx, y1 = −H/2·sy + oy·ky, x2 = x1 + w·kx, y2 = y1 + h·ky\n *\n * and the corners, in this order, are `(x1,y1) (x1,y2) (x2,y2) (x2,y1)` —\n * bottom-left, upper-left, upper-right, bottom-right, as the oracle's header\n * words them. Each is turned by the record's `rotation` (degrees, pi written\n * as `./world.ts`'s `RUNTIME_PI`), moved by its `x, y` (0 unstated), and\n * carried through the slot bone's world matrix: `a·x + b·y + worldX`,\n * `c·x + d·y + worldY`. Every record field is read as the double the document\n * spells.\n *\n * Measured on 6000 hand-written regions — 70% of them trimmed, atlas `rotate`\n * 0, 90, 180 or 270, placement in ±50, rotation in ±180 and scale in ±2 —\n * each on one of ten bones rotated, scaled, sheared and reflecting, posed\n * four times: field values float32-exact and spelled with five non-float32\n * decimals, each on a page of `scale:` 1 and 0.37 (1500 each):\n *\n * | reading | exact |\n * | --- | ---: |\n * | the rule above, fields as doubles | 6000 of 6000 |\n * | the trim ignored (`w, h` for `ow, oh`, offsets 0) | 1796 of 6000, worst 335.43 units |\n * | the fields read through `Math.fround`, on the non-float32 spellings | 13 of 3000, worst 41 millionths |\n * | the atlas `bounds` taken as transposed at 90 and 270 | 3007 of 6000, worst 1634.26 units |\n *\n * So the page's `scale:` and the atlas's `rotate` do not enter the corners;\n * the rectangle's `width` and `height` are in the drawing's orientation, as\n * `AtlasRegion` in `src/atlas.ts` states.\n *\n * - **A region with a `sequence` draws its setup frame's rectangle.** Four\n * probes of one three-frame sequence whose frames differ in their trims:\n * `setup` unstated and `setup: 0` matched frame 0's corners, `setup: 1`\n * frame 1's and `setup: 2` frame 2's, and no other frame's. The frame is\n * the model's `sequence.atlas[setup ?? 0]`.\n * - ⛔ **A region whose rectangle is `null` leaves the whole block out, by\n * name.** `null` is the model's statement that the build had no source for\n * that region (`ModelRegionAttachment.atlas`); posing it at a trim of 0\n * would be inventing the four numbers the corners read — the build pair of\n * issue #931 posed one such document 11.925 world units apart. A block\n * with one row missing would read as a roster difference, not an absence,\n * so the block is absent and every such slot is named.\n *\n * ## A mesh's vertices, and a clipping polygon's\n *\n * - Unweighted: each local `x, y` through the slot bone's world matrix plus\n * its origin.\n * - Weighted: per vertex, the sum over its bindings in order of\n * `(x·a + y·b + worldX)·weight` and `(x·c + y·d + worldY)·weight`, each\n * binding's bone looked up BY NAME (`ModelBinding`) — its world, not the\n * slot bone's.\n * - ⚠️ **Every vertex coordinate, bind coordinate and weight is read through\n * `Math.fround` first**: the runtime stores a vertex attachment's array as\n * float32, while it reads a bone's and a region's numbers as the doubles\n * the text spells (`src/model.ts`'s 🔸). Measured on 1200 meshes over the\n * ten bones (60% weighted over one to four of them): float32-exact inputs\n * 600 of 600 either way; inputs with five non-float32 decimals 600 of 600\n * through `Math.fround`, 0 of 600 as doubles (worst 11 millionths). On the\n * corpus, `gallery/flex`'s weighted meshes and `gallery/squash`'s ball read\n * 1 to 3 millionths off as doubles and exact through `Math.fround`.\n * - A linked mesh is written by the oracle as kind `mesh` under its own name,\n * and its vertices are its SOURCE mesh's (`skin`, `slot`, `source` in the\n * model) through the linked mesh's own slot bone: a linked mesh on a\n * rotated, reflected and sheared bone, sourced from a mesh in another slot\n * of another skin, read exact.\n * - The atlas does not enter a mesh's vertices, and a mesh's `sequence`\n * changes none of them.\n * - A clipping polygon follows the mesh rule, and its row's `end` is the\n * model's `end` slot or `null`: 1200 polygons drawn as the meshes above,\n * half of them ending at a slot, read exact and with the right end through\n * `Math.fround` (600 of 600 on each spelling), and 0 of 600 as doubles on\n * the non-float32 spelling (worst 11 millionths).\n *\n * ## Which slots, and in what order\n *\n * A slot is listed when what it shows at setup (`shownAttachment`, issue\n * #928) is a region, a mesh or a linked mesh (`setup.attachments`) or a\n * clipping polygon (`setup.clips`), whether or not its bone is active — an\n * inactive bone's world is all zeros, and the oracle's ill-conditioned rule\n * excludes it. Rows are in the model's slot order, which is the setup draw\n * order (`ModelSlot`): measured the same order as spine-core's on 19 of 19\n * recipes. A bounding box and a path attachment have no row: the oracle's\n * dump writes no vertices for either, so neither can be posed against it.\n *\n * ## At a sample, and under a deform or a sequence (issue #955)\n *\n * `poseGeometry` poses a sample's attachments the same way, through the\n * sample's bones and in its draw order. A slot a deform timeline moved\n * carries its deform array (`ShownGeometry.deform`): the vertices are the\n * array's (`deformedVertices` in `./deform.ts`) and their coordinates are read\n * AS THEY ARE, not through `Math.fround` again — a lerped deform is a double\n * the runtime does not round (`./deform.ts`'s header: the lerped positions\n * rounded to float32 missed 791 of 800 samples). A region a sequence\n * timeline stepped carries its frame (`ShownGeometry.frame`), and its corners\n * read that frame's rectangle (`CoreRegionGeometry.frames`).\n */\nimport type { ModelAtlasRect, ModelBinding, ModelVertices } from '../model.ts';\nimport { RUNTIME_PI, type CoreWorld } from './world.ts';\nimport { deformedVertices } from './deform.ts';\nimport { poseClipped, REGION_TRIANGLES, REGION_UVS, type CoreClippedRow, type DrawStep, type ShapeClipper, type TriangleClipper } from './clipping.ts';\n\nconst RAD = RUNTIME_PI / 180;\n\n/** What a region record carries for its corners — `atlas` already the rectangle of the frame shown at setup. */\nexport interface CoreRegionGeometry {\n x?: number;\n y?: number;\n rotation?: number;\n scaleX?: number;\n scaleY?: number;\n width: number;\n height: number;\n /** The rectangle drawn at setup, or `null` when the model states the build had none. */\n atlas: ModelAtlasRect | null;\n /** A sequence's rectangles, one per frame (`sequence.atlas`) — what a sequence timeline's frame draws (`./deform.ts`). */\n frames?: ModelAtlasRect[];\n}\n\n/** The geometry a record carries, by kind, as far as the construct reads it. */\nexport type CoreGeometry =\n | { kind: 'region'; region: CoreRegionGeometry }\n | { kind: 'mesh'; vertices: ModelVertices; uvs: number[]; triangles: number[]; hull?: number }\n | { kind: 'linkedmesh'; skin: string; slot: string; source: string }\n | { kind: 'clipping'; end: string | null; vertices: ModelVertices; inverse: boolean; convex: boolean }\n | { kind: 'boundingbox'; vertices: ModelVertices }\n | { kind: 'path'; vertices: ModelVertices; closed: boolean; constantSpeed: boolean; lengths: number[] };\n\n/** One row of `setup.attachments`: `[slot, attachment, kind, vertices]`, the oracle's row. */\nexport type CoreAttachmentRow = [string, string, 'region' | 'mesh', Array<number | null>];\n/** One row of `setup.clips`: `[slot, attachment, end, polygon]`, the oracle's row. */\nexport type CoreClipRow = [string, string, string | null, Array<number | null>];\n\n/** What computes a region's corners in the slot bone's world: `regionCorners` unless a caller passes another. */\nexport type RegionPoser = (region: CoreRegionGeometry & { atlas: ModelAtlasRect }, bone: CoreWorld) => number[];\n/** What computes a vertex array's world positions: `worldVertices` unless a caller passes another. */\nexport type VertexPoser = (vertices: ModelVertices, bone: CoreWorld, world: ReadonlyMap<string, CoreWorld>, coords?: (v: number) => number) => number[];\n\n/** A deformed array's coordinates are read as they are (`./deform.ts`, `deformedVertices`): they are not the stored float32s. */\nexport const EXACT_COORDS = (v: number): number => v;\n\n/** A region's four corners in world units — the header's rule. */\nexport function regionCorners(region: CoreRegionGeometry & { atlas: ModelAtlasRect }, bone: CoreWorld): number[] {\n const { width: W, height: H } = region;\n const sx = region.scaleX ?? 1;\n const sy = region.scaleY ?? 1;\n const r = region.atlas;\n const kx = (W / r.originalWidth) * sx;\n const ky = (H / r.originalHeight) * sy;\n const x1 = (-W / 2) * sx + r.offsetX * kx;\n const y1 = (-H / 2) * sy + r.offsetY * ky;\n const x2 = x1 + r.width * kx;\n const y2 = y1 + r.height * ky;\n const angle = (region.rotation ?? 0) * RAD;\n const cos = Math.cos(angle);\n const sin = Math.sin(angle);\n const x = region.x ?? 0;\n const y = region.y ?? 0;\n const out: number[] = [];\n for (const [px, py] of [[x1, y1], [x1, y2], [x2, y2], [x2, y1]]) {\n // The operation order is measured to the bit (issue #966): the placement is added to the cosine term before the sine term is taken off — `px·cos − py·sin + x` reads 1 ulp off on 748 attachment-samples of six corpus rows.\n const lx = px * cos + x - py * sin;\n const ly = py * cos + y + px * sin;\n out.push(bone.a * lx + bone.b * ly + bone.worldX, bone.c * lx + bone.d * ly + bone.worldY);\n }\n return out;\n}\n\n/**\n * A vertex array's world positions — the header's mesh rule, every stored\n * number through `Math.fround`; with `coords`, the coordinates through it\n * instead (a deformed array's are read as they are, `EXACT_COORDS`), the\n * weights through `Math.fround` still.\n */\nexport function worldVertices(vertices: ModelVertices, bone: CoreWorld, world: ReadonlyMap<string, CoreWorld>, coords: (v: number) => number = Math.fround): number[] {\n const out: number[] = [];\n if (!vertices.weighted) {\n for (let i = 0; i + 1 < vertices.xy.length; i += 2) {\n const x = coords(vertices.xy[i]);\n const y = coords(vertices.xy[i + 1]);\n out.push(x * bone.a + y * bone.b + bone.worldX, x * bone.c + y * bone.d + bone.worldY);\n }\n return out;\n }\n for (const influences of vertices.bindings) {\n let wx = 0;\n let wy = 0;\n for (const binding of influences) {\n const t = world.get(binding.bone);\n if (t === undefined) throw new Error(`a binding names bone \"${binding.bone}\", which has no world transform (readModel refuses it first)`);\n const x = coords(binding.x);\n const y = coords(binding.y);\n const weight = Math.fround(binding.weight);\n wx += (x * t.a + y * t.b + t.worldX) * weight;\n wy += (x * t.c + y * t.d + t.worldY) * weight;\n }\n out.push(wx, wy);\n }\n return out;\n}\n\nconst isRecord = (v: unknown): v is Record<string, unknown> => typeof v === 'object' && v !== null && !Array.isArray(v);\nconst finite = (v: unknown): v is number => typeof v === 'number' && Number.isFinite(v);\nconst RECT_FIELDS = ['width', 'height', 'offsetX', 'offsetY', 'originalWidth', 'originalHeight'] as const;\n\nfunction readRect(value: unknown, where: string, problems: string[]): ModelAtlasRect | undefined {\n if (!isRecord(value)) {\n problems.push(`${where} is ${JSON.stringify(value)}, not an atlas rectangle`);\n return undefined;\n }\n const before = problems.length;\n for (const key of Object.keys(value)) if (!(RECT_FIELDS as readonly string[]).includes(key)) problems.push(`${where}: field \"${key}\" is not one this reader knows; it reads [${RECT_FIELDS.join(', ')}]`);\n for (const key of RECT_FIELDS) if (!finite(value[key])) problems.push(`${where}: ${key} is ${JSON.stringify(value[key]) ?? 'absent'}, not a finite number`);\n return problems.length === before ? (value as unknown as ModelAtlasRect) : undefined;\n}\n\n/** A `ModelVertices`, checked: an even run of finite numbers, or per vertex a non-empty list of bindings each naming a bone of the document. */\nfunction readVertices(value: unknown, where: string, bones: ReadonlySet<string>, problems: string[]): ModelVertices | undefined {\n if (!isRecord(value) || typeof value.weighted !== 'boolean') {\n problems.push(`${where} is not { weighted: false, xy } or { weighted: true, bindings }`);\n return undefined;\n }\n const before = problems.length;\n if (!value.weighted) {\n const xy = value.xy;\n if (!Array.isArray(xy) || xy.length % 2 !== 0 || !xy.every(finite)) problems.push(`${where}.xy is not an even-length list of finite numbers`);\n return problems.length === before ? { weighted: false, xy: xy as number[] } : undefined;\n }\n const bindings = value.bindings;\n if (!Array.isArray(bindings)) {\n problems.push(`${where}.bindings is not a list`);\n return undefined;\n }\n bindings.forEach((influences, i) => {\n if (!Array.isArray(influences) || influences.length === 0) {\n problems.push(`${where}.bindings[${i}] is not a non-empty list of bindings`);\n return;\n }\n influences.forEach((b: unknown, j) => {\n const at = `${where}.bindings[${i}][${j}]`;\n if (!isRecord(b)) {\n problems.push(`${at} is not an object`);\n return;\n }\n if (typeof b.bone !== 'string' || !bones.has(b.bone)) problems.push(`${at}: bone ${JSON.stringify(b.bone)} is not a bone of this document`);\n for (const key of ['x', 'y', 'weight'] as const) if (!finite(b[key])) problems.push(`${at}: ${key} is ${JSON.stringify(b[key]) ?? 'absent'}, not a finite number`);\n });\n });\n return problems.length === before ? { weighted: true, bindings: bindings as ModelBinding[][] } : undefined;\n}\n\n/**\n * The geometry of one attachment record, read and checked field by field —\n * called by `readModel` for every record of every skin. Returns `undefined`\n * when something was refused (the problem is pushed, naming the path). What is\n * refused mirrors the writer (`attachmentOf` in `src/model.ts`): a region\n * carrying neither a rectangle nor a sequence, or both; a sequence whose\n * `atlas` is not one rectangle per frame, or whose setup frame is not one of\n * them; and a binding, a linked mesh's link or a clip's `end` naming nothing.\n * A linked mesh's source is resolved later, once every skin is read.\n */\nexport function readGeometry(raw: Record<string, unknown>, kind: CoreGeometry['kind'], where: string, bones: ReadonlySet<string>, slots: ReadonlySet<string>, problems: string[]): CoreGeometry | undefined {\n const before = problems.length;\n switch (kind) {\n case 'region': {\n for (const key of ['x', 'y', 'rotation', 'scaleX', 'scaleY'] as const) if (raw[key] !== undefined && !finite(raw[key])) problems.push(`${where}: ${key} is ${JSON.stringify(raw[key])}, not a finite number`);\n for (const key of ['width', 'height'] as const) if (!finite(raw[key])) problems.push(`${where}: ${key} is ${JSON.stringify(raw[key]) ?? 'absent'}, not a finite number`);\n const hasRect = raw.atlas !== undefined;\n const hasSequence = raw.sequence !== undefined;\n let atlas: ModelAtlasRect | null | undefined;\n let frames: ModelAtlasRect[] | undefined;\n if (hasRect === hasSequence) {\n problems.push(`${where}: the region carries ${hasRect ? 'both an atlas rectangle and a sequence' : 'neither an atlas rectangle nor a sequence'}; the writer states exactly one of the two, and a sequence holds a rectangle per frame (issue #935)`);\n } else if (hasRect) {\n // `readModel` has read the rectangle itself (`readAtlasRect`); here only its value is taken.\n atlas = raw.atlas === null ? null : isRecord(raw.atlas) ? (raw.atlas as unknown as ModelAtlasRect) : undefined;\n } else {\n const seq = raw.sequence;\n if (!isRecord(seq)) problems.push(`${where}.sequence is not an object`);\n else {\n const count = seq.count;\n const setup = seq.setup ?? 0;\n if (typeof count !== 'number' || !Number.isInteger(count) || count < 1) problems.push(`${where}.sequence: count is ${JSON.stringify(count)}, not a whole number of at least 1`);\n else if (typeof setup !== 'number' || !Number.isInteger(setup) || setup < 0 || setup >= count) problems.push(`${where}.sequence: setup is ${JSON.stringify(seq.setup)}, not a frame of the ${count}`);\n if (!Array.isArray(seq.atlas) || seq.atlas.length !== count) problems.push(`${where}.sequence: atlas is not a list of ${JSON.stringify(count)} rectangle(s), one per frame`);\n else {\n const rects = seq.atlas.map((r, i) => readRect(r, `${where}.sequence.atlas[${i}]`, problems));\n if (typeof setup === 'number' && Number.isInteger(setup) && setup >= 0 && setup < rects.length) atlas = rects[setup];\n if (rects.every((r) => r !== undefined)) frames = rects as ModelAtlasRect[];\n }\n }\n }\n if (problems.length !== before || atlas === undefined) return undefined;\n const pick = (key: 'x' | 'y' | 'rotation' | 'scaleX' | 'scaleY'): { [k: string]: number } => (raw[key] === undefined ? {} : { [key]: raw[key] as number });\n return {\n kind: 'region',\n region: { ...pick('x'), ...pick('y'), ...pick('rotation'), ...pick('scaleX'), ...pick('scaleY'), width: raw.width as number, height: raw.height as number, atlas, ...(frames === undefined ? {} : { frames }) },\n };\n }\n case 'linkedmesh': {\n for (const key of ['skin', 'slot', 'source'] as const) if (typeof raw[key] !== 'string' || raw[key] === '') problems.push(`${where}: ${key} is ${JSON.stringify(raw[key]) ?? 'absent'}, not a non-empty string`);\n if (typeof raw.slot === 'string' && !slots.has(raw.slot)) problems.push(`${where}: slot \"${raw.slot}\" is not a slot of this document`);\n if (problems.length !== before) return undefined;\n return { kind: 'linkedmesh', skin: raw.skin as string, slot: raw.slot as string, source: raw.source as string };\n }\n case 'mesh':\n case 'clipping':\n case 'boundingbox':\n case 'path': {\n const vertices = readVertices(raw.vertices, `${where}.vertices`, bones, problems);\n if (kind === 'clipping' && raw.end !== undefined && (typeof raw.end !== 'string' || !slots.has(raw.end))) problems.push(`${where}: end is ${JSON.stringify(raw.end)}, not a slot of this document`);\n if (kind === 'clipping') for (const key of ['inverse', 'convex'] as const) if (raw[key] !== undefined && typeof raw[key] !== 'boolean') problems.push(`${where}: ${key} is ${JSON.stringify(raw[key])}, not a boolean`);\n const mesh = kind === 'mesh' && vertices !== undefined ? readMeshTriangles(raw, vertices, where, problems) : undefined;\n if (vertices === undefined || problems.length !== before) return undefined;\n if (kind === 'mesh') return mesh === undefined ? undefined : { kind, vertices, ...mesh };\n if (kind === 'clipping') return { kind, end: typeof raw.end === 'string' ? raw.end : null, vertices, inverse: raw.inverse === true, convex: raw.convex === true };\n if (kind === 'boundingbox') return { kind, vertices };\n return readPathGeometry(raw, vertices, where, problems);\n }\n }\n}\n\n/**\n * A mesh's `uvs` and `triangles`, what the clipper reads besides its vertices\n * (issue #964, `./clipping.ts`): one finite pair per vertex, and whole\n * indices into the vertices in threes — as the writer writes them.\n */\nfunction readMeshTriangles(raw: Record<string, unknown>, vertices: ModelVertices, where: string, problems: string[]): { uvs: number[]; triangles: number[]; hull?: number } | undefined {\n const before = problems.length;\n const count = vertices.weighted ? vertices.bindings.length : vertices.xy.length / 2;\n const uvs = raw.uvs;\n const triangles = raw.triangles;\n if (!Array.isArray(uvs) || !uvs.every(finite) || uvs.length !== 2 * count) problems.push(`${where}.uvs is not ${2 * count} finite numbers, one pair per vertex`);\n if (!Array.isArray(triangles) || triangles.length % 3 !== 0 || !triangles.every((i) => Number.isInteger(i) && i >= 0 && i < count)) problems.push(`${where}.triangles is not a list of whole indices below ${count}, in threes`);\n // The hull's vertex count (issue #966, retained for the raw entry): a whole number no larger than the vertices.\n const hull = raw.hull;\n if (hull !== undefined && !(typeof hull === 'number' && Number.isInteger(hull) && hull >= 0 && hull <= count)) problems.push(`${where}.hull is ${JSON.stringify(hull)}, not a whole number of vertices from 0 to ${count}`);\n return problems.length === before ? { uvs: uvs as number[], triangles: triangles as number[], ...(hull === undefined ? {} : { hull: hull as number }) } : undefined;\n}\n\n/**\n * A path attachment's own fields past its vertices (construct 5's second cut,\n * `./constraints_path.ts`): `closed` and `constantSpeed` as the writer states\n * them — absent reads the parser's `false` and `true` (the `pathAttachments`\n * block of a dump of a record stating neither) — and `lengths`, one finite\n * entry per three points, as the writer always writes it (`buildRigPath` in\n * `src/compile.ts`). `vertexCount` must be the vertices' own count and a\n * multiple of 3: the writer refuses any other, and the curve walk reads\n * groups of three.\n */\nfunction readPathGeometry(raw: Record<string, unknown>, vertices: ModelVertices, where: string, problems: string[]): CoreGeometry | undefined {\n const before = problems.length;\n for (const key of ['closed', 'constantSpeed'] as const) if (raw[key] !== undefined && typeof raw[key] !== 'boolean') problems.push(`${where}: ${key} is ${JSON.stringify(raw[key])}, not a boolean`);\n const count = vertices.weighted ? vertices.bindings.length : vertices.xy.length / 2;\n if (raw.vertexCount !== count) problems.push(`${where}: vertexCount is ${JSON.stringify(raw.vertexCount) ?? 'absent'}, and the vertices hold ${count} point(s)`);\n else if (count % 3 !== 0 || count < (raw.closed === true ? 3 : 6)) problems.push(`${where}: vertexCount is ${count}, not a multiple of 3 of at least ${raw.closed === true ? 3 : 6} — the curve walk reads knots and handles in threes`);\n const lengths = raw.lengths;\n if (!Array.isArray(lengths) || !lengths.every(finite)) problems.push(`${where}: lengths is not a list of finite numbers`);\n else if (lengths.length !== count / 3) problems.push(`${where}: lengths has ${lengths.length} entry(ies) where the vertices make ${count / 3}`);\n if (problems.length !== before) return undefined;\n return { kind: 'path', vertices, closed: raw.closed === true, constantSpeed: raw.constantSpeed !== false, lengths: lengths as number[] };\n}\n\n/** One slot as the construct reads it: its name and bone, and what it shows — the record's name, kind and geometry — or nothing. */\nexport interface ShownGeometry {\n slot: string;\n bone: string;\n /** The name the oracle's row carries (`shownRow`). */\n name: string;\n placeholder: string;\n skin: string;\n geometry: CoreGeometry;\n /** The deform array a deform timeline set on the slot (`./deform.ts`), or none. */\n deform?: readonly number[];\n /** The frame a sequence timeline set on a region's series (`./deform.ts`), or none: the setup frame. */\n frame?: number;\n}\n\n/** Resolves a linked mesh's source to its vertex array, or names why not. */\nexport type SourceOf = (skin: string, slot: string, source: string) => ModelVertices | string;\n\n/**\n * What the draw walk of `./clipping.ts` needs past the shown records: the\n * draw order (every slot, showing something or not — a clip ends at a slot\n * whatever it shows), the active bones, and a mesh's `uvs` and `triangles`\n * by where a linked mesh's source is filed.\n */\nexport interface DrawWalk {\n order: readonly string[];\n active: ReadonlySet<string>;\n meshOf: (skin: string, slot: string, source: string) => { uvs: number[]; triangles: number[] } | undefined;\n clip?: TriangleClipper;\n /** What the drawn rows are cut through (`clipThrough`), replaceable by the render suite's plants. */\n through?: ShapeClipper;\n}\n\n/**\n * The two blocks from the slots' shown records, in slot order, every number\n * through `round` (the oracle's, `gridRound` in `./index.ts`), or — for\n * `attachments` — the reason it is absent: a shown region whose rectangle is\n * `null` (the header's ⛔), every one named. With `draw`, also the `clipped`\n * block (issue #964, `./clipping.ts`) from the unrounded geometry, or why it\n * is absent.\n */\nexport function poseGeometry(\n shown: readonly ShownGeometry[],\n world: ReadonlyMap<string, CoreWorld>,\n sourceOf: SourceOf,\n round: (v: number) => number | null,\n plant: { region?: RegionPoser; vertices?: VertexPoser } = {},\n draw?: DrawWalk,\n): { attachments: CoreAttachmentRow[] | null; attachmentsWhy: string | null; clips: CoreClipRow[]; clipped: CoreClippedRow[] | null; clippedWhy: string | null; drawnClipped: CoreClippedRow[] | null; drawnClippedWhy: string | null } {\n const region = plant.region ?? regionCorners;\n const vertices = plant.vertices ?? worldVertices;\n const attachments: CoreAttachmentRow[] = [];\n const clips: CoreClipRow[] = [];\n const nulls: string[] = [];\n const steps = new Map<string, DrawStep>();\n for (const s of shown) {\n const bone = world.get(s.bone);\n if (bone === undefined) throw new Error(`slot \"${s.slot}\": bone \"${s.bone}\" has no world transform`);\n const g = s.geometry;\n // A deform array replaces the stored vertices, its coordinates read as they are (`./deform.ts`).\n const drawn = (v: ModelVertices): number[] => (s.deform === undefined ? vertices(v, bone, world) : vertices(deformedVertices(v, s.deform), bone, world, EXACT_COORDS));\n if (g.kind === 'region') {\n const rect = s.frame === undefined ? g.region.atlas : (g.region.frames?.[s.frame] ?? g.region.atlas);\n if (rect === null) {\n nulls.push(`slot \"${s.slot}\" shows region \"${s.name}\" (skin \"${s.skin}\", placeholder \"${s.placeholder}\")`);\n continue;\n }\n const corners = region({ ...g.region, atlas: rect }, bone);\n attachments.push([s.slot, s.name, 'region', corners.map(round)]);\n steps.set(s.slot, { slot: s.slot, kind: 'draw', attachment: s.name, vertices: corners, triangles: [...REGION_TRIANGLES], uvs: [...REGION_UVS] });\n } else if (g.kind === 'mesh') {\n const world = drawn(g.vertices);\n attachments.push([s.slot, s.name, 'mesh', world.map(round)]);\n steps.set(s.slot, { slot: s.slot, kind: 'draw', attachment: s.name, vertices: world, triangles: g.triangles, uvs: g.uvs });\n } else if (g.kind === 'linkedmesh') {\n const source = sourceOf(g.skin, g.slot, g.source);\n if (typeof source === 'string') throw new Error(`slot \"${s.slot}\": ${source} (readModel refuses it first)`);\n const world = drawn(source);\n attachments.push([s.slot, s.name, 'mesh', world.map(round)]);\n // A linked mesh draws its source's triangles over its source's UVs.\n const mesh = draw?.meshOf(g.skin, g.slot, g.source);\n if (draw !== undefined && mesh === undefined) throw new Error(`slot \"${s.slot}\": the linked mesh's source \"${g.source}\" carries no triangles (readModel refuses it first)`);\n if (mesh !== undefined) steps.set(s.slot, { slot: s.slot, kind: 'draw', attachment: s.name, vertices: world, triangles: mesh.triangles, uvs: mesh.uvs });\n } else if (g.kind === 'clipping') {\n const polygon = drawn(g.vertices);\n clips.push([s.slot, s.name, g.end, polygon.map(round)]);\n steps.set(s.slot, { slot: s.slot, kind: 'clip', attachment: s.name, active: draw?.active.has(s.bone) ?? false, end: g.end, polygon, inverse: g.inverse, convex: g.convex });\n }\n }\n const attachmentsWhy = nulls.length === 0\n ? null\n : `${nulls.join('; ')} — the model states the build had no atlas rectangle for it (atlas: null), and its corners read the trim and original size; a trim of 0 is not assumed`;\n let clipped: CoreClippedRow[] | null = null;\n let clippedWhy: string | null = draw === undefined ? 'the draw order was not given' : attachmentsWhy;\n let drawnClipped: CoreClippedRow[] | null = null;\n let drawnClippedWhy: string | null = clippedWhy;\n if (draw !== undefined && attachmentsWhy === null) {\n const walk = draw.order.map((slot): DrawStep => steps.get(slot) ?? { slot, kind: 'none' });\n const posed = poseClipped(walk, round, draw.clip, draw.through);\n clipped = posed.rows;\n clippedWhy = posed.why;\n drawnClipped = posed.drawn;\n drawnClippedWhy = posed.drawnWhy;\n }\n return { attachments: attachmentsWhy === null ? attachments : null, attachmentsWhy, clips, clipped, clippedWhy, drawnClipped, drawnClippedWhy };\n}\n","/**\n * Construct 5 of the core, second cut (issue #938, step 2e-ii of issue #380):\n * the path constraint, at the setup pose and at a sample time, with its\n * timelines. `./constraints.ts` runs it in the update order the first cut\n * measured; this module reads its record, walks its curve and moves its\n * bones.\n *\n * Every rule below was measured by posing hand-written skeletons through\n * `tools/pose_oracle.ts dump` (spine-core 4.3.13, `--skin all`,\n * `--physics none`) and comparing the core's rows at tolerance 0, most with\n * amplifier bones ten thousand units out along each axis of a constrained\n * bone, so that 1e-10 in its matrix reads as a grid step. Nothing here was\n * written from the runtime's source. Where a rule is not the obvious\n * reading, the reading that missed is stated beside it with its count. The\n * populations it names: the **grid** — one bone on two and three curves,\n * open and closed, at constant speed and not, percent and fixed, 61\n * positions each (976 probes); the **population** — 2,000 random probes of\n * every mode, setting, mix and curve (the core suite's `CP03` draws 600\n * like them); the **stated population** — 1,000 probes off stated lengths\n * spelled with non-float32 decimals. The core suite's `CP` controls hold the\n * probes; `tools/core_gate.ts` holds the corpus.\n *\n * ## The curve\n *\n * The constraint walks what its slot shows (`shownAttachment` at the setup\n * pose; the slot's attachment and deform timelines are not admitted, and an\n * animation keying either on a walked path leaves the samples' bones out by\n * name). A slot showing no path makes the constraint do nothing. The path's\n * world points are `./vertices.ts`'s `worldVertices`: every vertex number\n * through `Math.fround`, an unweighted path through its slot bone, a weighted\n * one through its bound bones — the doubles missed 1,946 of the population's\n * 2,000. Its `lengths` are read as the doubles the text spells: through\n * `Math.fround` they missed 697 of the stated population's 1,000. The points\n * form the chain `src/compile.ts`'s `pathChain` states — an open path drops\n * its first and last point (the end knots' outer handles), a closed one is\n * turned by one and repeats its first knot and handle — knot, handle,\n * handle, knot, …\n *\n * ## The walk: where a length along the curve is\n *\n * Every bone is placed at a length along the path: the `position`, then\n * each space after it (below). **At constant speed** (the default) the\n * runtime measures the curve itself, every pose:\n *\n * 1. **A table of the curves' lengths**, each curve four forward-difference\n * steps (`0.1875`, `0.09375`, `0.75` and `0.16666667`, the running total\n * carried across curves) — `curveLengthTable`, which `src/compile.ts`'s\n * `pathCurveLengths` also calls (issue #1015). A ten-step table missed\n * 460 of the grid's 976. The\n * last entry is the path's length; `percent` multiplies the position by\n * it. The stated `lengths` are not read: the stated total in their place\n * missed 680 of 1,000.\n * 2. **The curve** holding the length is searched for in the table from the\n * curve the previous space ended on, forward — on an open path it is not\n * restarted, so a space that walks backwards across a curve (a negative\n * spacing) stays on the later curve with a negative fraction; restarting\n * from the first curve missed 36 of the population's 2,000. A closed\n * path takes the length modulo its total (plus the total below 0) and\n * searches from the first curve every time. The fraction of the curve is\n * `(p − previous) / (entry − previous)`.\n * 3. **A table of ten segments** of that curve, ten forward-difference steps\n * of 1/10 (`0.3`, `0.03`, `0.006`, `0.16666667`), built when the curve\n * changes. The fraction times the ten-step total is searched for from the\n * segment the previous space ended on while the curve is the same, and\n * the curve's parameter is `(segment + fraction of the segment) / 10` —\n * so the parameter is linear in length within a segment, not along the\n * whole curve: the fraction of the curve used as the parameter missed 380\n * of the grid, the parameter at the exact arc length (a 2,000-piece\n * polyline) 380, and the point on the ten-segment polyline instead of the\n * curve 392.\n * 4. **The point is the cubic at that parameter**, evaluated for any\n * parameter: a negative one extrapolates the curve backwards. Only a\n * parameter that is not a number (a curve of length 0) takes the curve's\n * first knot and the direction of its first handle. Clamping every\n * parameter below 0.00001 to the start missed 11 of the population.\n *\n * **Off constant speed** (`constantSpeed: false`) the stated `lengths` are\n * the table: its entry for the last curve is the total (`vertexCount / 3`\n * less 2 on an open path, less 1 on a closed one), the curve is found as in\n * 2, and the fraction of the curve IS the cubic's parameter — the stated\n * numbers decide where bones stand even where they disagree with the\n * geometry (issue #804): measured off the geometry instead, 711 of the\n * stated population's 1,000 missed.\n *\n * **Past the ends** of an open path a bone stands on the straight line\n * through the first knot and its handle (before the start) or through the\n * last handle and the last knot (past the end), the overshoot along it.\n *\n * ## Spaces: `spacingMode`\n *\n * A `tangent` constraint places one point per bone; `chain` and\n * `chainScale` one more, the last bone's tip. The first space is 0. Each\n * next space, for the bone before it, with `L` its `length` and `W` the\n * length of `L` times its world x column:\n *\n * - `length`: `max(0, L + spacing) · W / L` — the clamp at 0 is measured:\n * without it 16 of the population missed;\n * - `fixed`: `spacing · W / L`;\n * - a bone whose `L` is below 0.00001, in either: `spacing` as stated;\n * - `percent`: `spacing`, and every space is multiplied by the path's\n * total;\n * - `proportional`: `W` (or `spacing` for a bone below 0.00001), all of them\n * then scaled by `count · spacing / their sum` when the sum is above 0,\n * and multiplied by the total over the count of spaces — the whole total\n * missed 260 of the population.\n *\n * ## Moving the bones: `rotateMode`, `offsetRotation`, the mixes\n *\n * Nothing moves when all three mixes are 0. Each bone in turn: its world\n * origin moves toward its point by `mixX` and `mixY` (the two axes on their\n * own); with `chainScale`, a bone longer than 0.00001 has its world x column\n * scaled by `(distance to the next point / W − 1) · mixRotate + 1`. Then,\n * when `mixRotate` is above 0 (a negative one turns nothing: reading it\n * as \"not 0\" missed 58 of the population), the bone turns by\n * `mixRotate` times the change from its x axis's angle to:\n *\n * - `tangent`: the curve's direction at its point — the derivative there,\n * or below a parameter of 0.001 (negative ones included; 7 of 2,000\n * tangent probes missed with 0.001 as a floor above 0) its first handle's\n * direction;\n * - `chain`, `chainScale`: the direction to the next point — ⚠️ but when the\n * next space is exactly 0, the next point's tangent. That is exact\n * equality: a space of ±1e-7 turns to the (rounding-level) direction,\n * and an ε test missed 157 of the population.\n * - `chain` with no offset: the next bone starts at this bone's tip, the\n * bone's `length` along its turned axis (the runtime's \"tip\"); not\n * carrying the tip missed 191 of the population.\n * - Otherwise `offsetRotation` degrees (the model's `rotation`) are added,\n * in the runtime's π, NEGATED when the slot bone's world matrix does not\n * have a positive determinant — never flipping missed 241 of the\n * population. Which slot bone's world that is, is the next section.\n *\n * The change is brought once into [−π, π] with the runtime's π\n * (3.1415927), which `Math.PI` there missed 881 of 2,000 by. The bones are\n * then moved in world space and read back into local values at once, as the\n * first cut's world-space transform is (`./constraints.ts`, `localFromWorld`).\n *\n * ## Which slot bone the offset reads\n *\n * The runtime brings bones up to date in an order it builds before it\n * poses: each constraint in turn brings up to date the bones it reads and\n * the bones it moves (a bone after its parents, and once only until a\n * constraint moves a bone above it), and every bone left over follows at\n * the end. A path constraint reads its slot bone only for the offset's\n * sign, and it asks the order for its slot bone only when the slot holds an\n * UNWEIGHTED path in some skin — a weighted one asks for its bound bones\n * instead. So a weighted path's slot bone can be read before the pose has\n * set it (`slotBonePlan` emulates the order):\n *\n * - set by an earlier constraint's ordering — its world as it was brought\n * up to date then, before that constraint ran; or as that constraint left\n * it when it moved the bone itself;\n * - set by nothing yet — the previous pose's world: on a new skeleton all\n * zeros, which is not positive, so the oracle's setup pose turns the\n * offset the other way; at a sample, the sample before's.\n *\n * Measured on eight hand-written cases, each exact at the setup pose and at\n * nine samples, of which reading the slot bone fresh missed three, and on\n * random update orders of path, ik and transform constraints, 783 of 783\n * exact, fresh 774 (`CP06`, `CP07`).\n *\n * A physics constraint orders its one bone as a one-bone constraint does\n * (its parents first, what hangs below it reset, the bone done), though\n * under `Physics.none` it moves nothing. A slider sets no bone in the order —\n * neither its dial nor the bones its animation keys — and resets each bone\n * its animation keys and what hangs below it, so a later constraint that\n * orders one of them sets it again. Measured on eighteen hand-written orders\n * around a weighted path with an offset (`CP13`), each exact at the setup\n * pose and three samples, where the readings rejected each miss one or two:\n * physics ordering nothing, a slider ordering its dial, a slider ordering\n * the bones it keys, a slider resetting nothing, a slider resetting only\n * below the bones it keys; and on 400 random orders of one to five physics,\n * slider, ik and transform constraints around such a path, 400 exact\n * (physics ordering nothing 388, a slider ordering its dial and keyed bones\n * 379). The previous sample is the oracle's\n * order of animations, which the model does not hold: the core poses a\n * sample with the setup pose's reading, which is the runtime's exactly\n * when the slot bone's reflection is the setup's at every sample, and\n * leaves the samples' bones out by name when it is not.\n *\n * ## Which constraints run\n *\n * One with `skin: true` runs exactly when an applied skin's `path` list\n * names it (`./constraints.ts`'s header, issue #932); one whose slot bone is\n * inactive does not. One whose constrained bone is inactive still runs\n * (measured: its other bones move; the inactive one's matrix is collapsed\n * and the oracle's ill-conditioned rule excludes it). A weight bound to an\n * inactive bone reads its world of zeros.\n *\n * ## The record and its timelines\n *\n * The dump's `paths` block is the runtime's reading of each field, and the\n * core writes the same block (`pathRows`): `positionMode` absent reads\n * `percent`, `spacingMode` `length`, `rotateMode` `tangent`, `rotation`,\n * `position` and `spacing` 0, `mixRotate` and `mixX` 1 and `mixY` the\n * resolved `mixX`; a mode's first letter is read in either case. A path\n * attachment's `closed` absent reads false and `constantSpeed` true (the\n * `pathAttachments` block, `pathAttachmentRows`). The three timelines —\n * `position` and `spacing` one channel each, `mix` three — are evaluated by\n * construct 4's `keyIndexAt` and `channelAt`, float32 key times and values,\n * before the first key the constraint's own; a key stating no value reads\n * 0, one stating no mix 1 and no `mixY` its own `mixX` (`CP08`, 24 keyed\n * skeletons at 200 dense samples). The value a key gives reaches the pose\n * through the setup blend at alpha 1, `setup + (value − setup)·1`, as the ik\n * and transform timelines' do (`./constraints.ts`, *The timelines*; issue\n * #984, `CY01`: the value as keyed read 0 of 60 probes keying all three\n * timelines bit-exact under `--raw`, the blend 60).\n *\n * ## Purity\n *\n * As the rest of the core: nothing from the Spine runtime package, nothing\n * from `src/transform.ts`, no clock, no randomness, no I/O.\n */\nimport type { ModelBone, ModelVertices } from '../model.ts';\nimport { RUNTIME_PI, type CoreWorld } from './world.ts';\nimport { EXACT_COORDS, worldVertices } from './vertices.ts';\nimport type { CoreCurve, CoreKey } from './animation.ts';\nimport type { CoreConstraintRecord } from './constraints.ts';\n\nconst RAD = RUNTIME_PI / 180;\n\n/**\n * The constant-speed walk's table of the curves' lengths — the header's *The\n * walk*, step 1: each curve four forward-difference steps (`0.1875`,\n * `0.09375`, `0.75`, `0.16666667`), the running total carried across curves,\n * one cumulative entry per curve. `chain` is flat, `x, y` per point, knot\n * handle handle knot …; `curveCount` curves are read off it.\n *\n * Exported because it has a second caller: an omitted `lengths` on a path\n * attachment is measured by `src/compile.ts` through this function (issue\n * #1015), so the number rigc writes into a file and the number the core walks\n * are one computation. Measured as the header states it on the grid (a\n * ten-step table missed 460 of 976) and held there by the core suite's `CP`\n * controls.\n */\nexport function curveLengthTable(chain: readonly number[], curveCount: number): number[] {\n const curveEnds: number[] = [];\n let total = 0;\n let x1 = chain[0];\n let y1 = chain[1];\n for (let i = 0, w = 2; i < curveCount; i++, w += 6) {\n const cx1 = chain[w];\n const cy1 = chain[w + 1];\n const cx2 = chain[w + 2];\n const cy2 = chain[w + 3];\n const x2 = chain[w + 4];\n const y2 = chain[w + 5];\n const h2x = (x1 - cx1 * 2 + cx2) * 0.1875;\n const h2y = (y1 - cy1 * 2 + cy2) * 0.1875;\n const d3x = ((cx1 - cx2) * 3 - x1 + x2) * 0.09375;\n const d3y = ((cy1 - cy2) * 3 - y1 + y2) * 0.09375;\n let d2x = h2x * 2 + d3x;\n let d2y = h2y * 2 + d3y;\n let d1x = (cx1 - x1) * 0.75 + h2x + d3x * 0.16666667;\n let d1y = (cy1 - y1) * 0.75 + h2y + d3y * 0.16666667;\n total += Math.sqrt(d1x * d1x + d1y * d1y);\n d1x += d2x;\n d1y += d2y;\n d2x += d3x;\n d2y += d3y;\n total += Math.sqrt(d1x * d1x + d1y * d1y);\n d1x += d2x;\n d1y += d2y;\n total += Math.sqrt(d1x * d1x + d1y * d1y);\n d1x += d2x + d3x;\n d1y += d2y + d3y;\n total += Math.sqrt(d1x * d1x + d1y * d1y);\n curveEnds.push(total);\n x1 = x2;\n y1 = y2;\n }\n return curveEnds;\n}\n\nconst EPSILON = 0.00001;\n\n/** The three modes a path constraint names, each as the model spells it once its first letter is lower-cased. */\nexport const PATH_POSITION_MODES = ['fixed', 'percent'] as const;\nexport const PATH_SPACING_MODES = ['length', 'fixed', 'percent', 'proportional'] as const;\nexport const PATH_ROTATE_MODES = ['tangent', 'chain', 'chainScale'] as const;\nexport type PathPositionMode = (typeof PATH_POSITION_MODES)[number];\nexport type PathSpacingMode = (typeof PATH_SPACING_MODES)[number];\nexport type PathRotateMode = (typeof PATH_ROTATE_MODES)[number];\n\n/** The fields a path record may carry after `kind`, `name`, `declaredIn` (`buildRigConstraint` in `src/compile.ts`). */\nexport const PATH_FIELDS = ['bones', 'slot', 'positionMode', 'spacingMode', 'rotateMode', 'rotation', 'position', 'spacing', 'mixRotate', 'mixX', 'mixY', 'skin'] as const;\n\n/** The curve a path constraint walks: the path attachment its slot shows, as the record states it. */\nexport interface CorePathGeometry {\n vertices: ModelVertices;\n closed: boolean;\n constantSpeed: boolean;\n lengths: number[];\n /** Set when a deform timeline replaced the vertices at a sample (`./deform.ts`): their coordinates are read as they are, not through `Math.fround`. */\n exact?: boolean;\n}\n\n/** The values a path constraint's timelines key. */\nexport interface PathPose {\n position: number;\n spacing: number;\n mixRotate: number;\n mixX: number;\n mixY: number;\n}\n\nexport interface CorePathRecord extends PathPose {\n kind: 'path';\n name: string;\n bones: string[];\n slot: string;\n /** The slot's bone — the frame an unweighted path's vertices are in. */\n slotBone: string;\n positionMode: PathPositionMode;\n spacingMode: PathSpacingMode;\n rotateMode: PathRotateMode;\n offsetRotation: number;\n skin: boolean;\n /** An applied skin's `path` list names it — what applies a skin-required one (`./constraints.ts`'s header); set per skin view by `underSkin` in `./index.ts`. */\n listedBySkin: boolean;\n /** What the slot shows at setup: its path, `null` when it shows no path (the constraint then does nothing). Set once the skins are read. */\n path: CorePathGeometry | null;\n /** Why what the slot shows cannot be told — skins that disagree over its placeholder — or null. */\n unresolved: string | null;\n /**\n * The bones the runtime brings up to date for this constraint's slot before\n * it runs, off every path attachment a skin the view can show files under\n * the slot (every skin under `all`, the named and default skins under a\n * named one, `lookupSkins` in `./skins.ts`): a\n * weighted one's bound bones, an unweighted one's slot bone (the header's\n * *Which slot bone*). Set once the skins are read.\n */\n slotDeps: string[];\n}\n\nconst isRecord = (v: unknown): v is Record<string, unknown> => typeof v === 'object' && v !== null && !Array.isArray(v);\n\nfunction fold<T extends string>(raw: Record<string, unknown>, key: string, modes: readonly T[], dflt: T, where: string, problems: string[]): T {\n const v = raw[key];\n if (v === undefined) return dflt;\n const folded = typeof v === 'string' && v.length > 0 ? v[0].toLowerCase() + v.slice(1) : '';\n const mode = modes.find((m) => m === folded);\n if (mode === undefined) {\n problems.push(`${where}: ${key} is ${JSON.stringify(v)}, none of ${modes.join(', ')} (first letter in either case)`);\n return dflt;\n }\n return mode;\n}\n\nfunction num(raw: Record<string, unknown>, key: string, dflt: number, where: string, problems: string[]): number {\n const v = raw[key];\n if (v === undefined) return dflt;\n if (typeof v !== 'number' || !Number.isFinite(v)) {\n problems.push(`${where}: ${key} is ${JSON.stringify(v)}, not a finite number`);\n return dflt;\n }\n return v;\n}\n\n/**\n * A path constraint's record, read field by field, or `undefined` with the\n * problems named. `bones` and `slots` are the document's names and each\n * slot's bone.\n */\nexport function readPathRecord(raw: Record<string, unknown>, name: string, where: string, bones: ReadonlySet<string>, slots: ReadonlyMap<string, string>, problems: string[]): CorePathRecord | undefined {\n const before = problems.length;\n for (const key of Object.keys(raw)) {\n if (key === 'kind' || key === 'name' || key === 'declaredIn') continue;\n if (!(PATH_FIELDS as readonly string[]).includes(key)) problems.push(`${where}: field \"${key}\" is not one this reader knows; it reads [${PATH_FIELDS.join(', ')}]`);\n }\n const list: string[] = [];\n if (!Array.isArray(raw.bones) || raw.bones.length === 0) problems.push(`${where}: bones is ${JSON.stringify(raw.bones)}, not a non-empty list of bone names`);\n else raw.bones.forEach((b, i) => (typeof b === 'string' && bones.has(b) ? list.push(b) : problems.push(`${where}: bones[${i}] ${JSON.stringify(b)} is not a bone of this document`)));\n const slot = typeof raw.slot === 'string' ? raw.slot : '';\n const slotBone = slots.get(slot);\n if (slotBone === undefined) problems.push(`${where}: slot is ${JSON.stringify(raw.slot)}, not a slot of this document`);\n if (raw.skin !== undefined && typeof raw.skin !== 'boolean') problems.push(`${where}: skin is ${JSON.stringify(raw.skin)}, not a boolean`);\n const mixX = num(raw, 'mixX', 1, where, problems);\n const record: CorePathRecord = {\n kind: 'path', name, bones: list, slot, slotBone: slotBone ?? '',\n positionMode: fold(raw, 'positionMode', PATH_POSITION_MODES, 'percent', where, problems),\n spacingMode: fold(raw, 'spacingMode', PATH_SPACING_MODES, 'length', where, problems),\n rotateMode: fold(raw, 'rotateMode', PATH_ROTATE_MODES, 'tangent', where, problems),\n offsetRotation: num(raw, 'rotation', 0, where, problems),\n position: num(raw, 'position', 0, where, problems),\n spacing: num(raw, 'spacing', 0, where, problems),\n mixRotate: num(raw, 'mixRotate', 1, where, problems),\n mixX,\n mixY: num(raw, 'mixY', mixX, where, problems),\n skin: raw.skin === true,\n listedBySkin: false,\n path: null,\n unresolved: null,\n slotDeps: [],\n };\n return problems.length === before ? record : undefined;\n}\n\n// ---------------------------------------------------------------------------\n// timelines\n// ---------------------------------------------------------------------------\n\n/** A path constraint's three timelines, by the name the model gives them, and the channels each keys. */\nexport const PATH_TIMELINES = { position: ['value'], spacing: ['value'], mix: ['mixRotate', 'mixX', 'mixY'] } as const;\nexport type PathTimelineName = keyof typeof PATH_TIMELINES;\n\n/** One animation's timelines of one path constraint. */\nexport interface CorePathTimelines {\n name: string;\n position?: CoreKey[];\n spacing?: CoreKey[];\n mix?: CoreKey[];\n}\n\nfunction keyCurve(raw: Record<string, unknown>, channels: number, last: boolean, at: string, problems: string[]): CoreCurve {\n const curve = raw.curve;\n if (curve === undefined) return 'linear';\n if (last) {\n problems.push(`${at}: the last key carries a curve, which eases to no key — the writer refuses it`);\n return 'linear';\n }\n if (curve === 'stepped') return 'stepped';\n if (!Array.isArray(curve) || curve.length !== channels * 4 || !curve.every((n) => typeof n === 'number' && Number.isFinite(n))) {\n problems.push(`${at}: curve is ${JSON.stringify(curve)}, not \"stepped\" nor ${channels * 4} finite numbers (four per channel)`);\n return 'linear';\n }\n return curve as number[];\n}\n\n/**\n * The path timelines of one animation record's `constraints.path`, read: each\n * names a declared path constraint, each timeline is `position`, `spacing` or\n * `mix`, keys strictly increase in time, each key carries only its channels,\n * `time` and `curve`. An absent channel reads the parser's value, measured:\n * a position or spacing 0, a mix 1, a `mixY` the key's own `mixX` (the header).\n */\nexport function readPathTimelines(value: unknown, label: string, declared: ReadonlySet<string>, problems: string[]): CorePathTimelines[] {\n const out: CorePathTimelines[] = [];\n if (!Array.isArray(value)) return out;\n value.forEach((entry, i) => {\n const at = `${label}.constraints.path[${i}]`;\n if (!isRecord(entry) || typeof entry.name !== 'string') {\n problems.push(`${at} names no constraint`);\n return;\n }\n if (!declared.has(entry.name)) problems.push(`${at}: \"${entry.name}\" is not a path constraint of this document`);\n const tls: CorePathTimelines = { name: entry.name };\n if (!Array.isArray(entry.timelines)) {\n problems.push(`${at}: timelines is not a list`);\n return;\n }\n entry.timelines.forEach((tl: unknown, j: number) => {\n const tat = `${at}.timelines[${j}]`;\n if (!isRecord(tl) || typeof tl.name !== 'string' || !(tl.name in PATH_TIMELINES)) {\n problems.push(`${tat}: ${isRecord(tl) ? JSON.stringify(tl.name) : 'it'} is not a path timeline; they are ${Object.keys(PATH_TIMELINES).join(', ')}`);\n return;\n }\n const kind = tl.name as PathTimelineName;\n if (tls[kind] !== undefined) problems.push(`${tat}: \"${kind}\" is keyed twice on path constraint \"${entry.name}\"`);\n const channels: readonly string[] = PATH_TIMELINES[kind];\n const rawKeys = tl.keys;\n if (!Array.isArray(rawKeys) || rawKeys.length === 0) {\n problems.push(`${tat}: keys is not a non-empty list`);\n return;\n }\n let last = -Infinity;\n const keys: CoreKey[] = [];\n rawKeys.forEach((k: unknown, n: number) => {\n const kat = `${tat}.keys[${n}]`;\n if (!isRecord(k)) {\n problems.push(`${kat} is not an object`);\n return;\n }\n for (const f of Object.keys(k)) if (f !== 'time' && f !== 'curve' && !channels.includes(f)) problems.push(`${kat}: field \"${f}\" is not one this reader knows; it reads [time, ${channels.join(', ')}, curve]`);\n const time = k.time;\n if (typeof time !== 'number' || !Number.isFinite(time) || time < 0) {\n problems.push(`${kat}: time is ${JSON.stringify(time)}, not a finite time at or after 0`);\n return;\n }\n if (time <= last) problems.push(`${kat}: time ${time} is not after the key before it — the writer refuses key times that do not strictly increase`);\n last = Math.max(last, time);\n const stated = channels.map((c) => {\n if (c === 'mixY' && k.mixY === undefined) return num(k, 'mixX', 1, kat, problems);\n return num(k, c, kind === 'mix' ? 1 : 0, kat, problems);\n });\n keys.push({ time: Math.fround(time), values: stated.map(Math.fround), stated: { time, values: stated }, curve: keyCurve(k, channels.length, n === rawKeys.length - 1, kat, problems) });\n });\n tls[kind] = keys;\n });\n out.push(tls);\n });\n return out;\n}\n\n// ---------------------------------------------------------------------------\n// solving\n// ---------------------------------------------------------------------------\n\n/** What the path solver reads and writes: the bones' local values, their world transforms, which are active. */\nexport interface PathSolverState {\n bones: ModelBone[];\n index: Map<string, number>;\n world: Map<string, CoreWorld>;\n active: ReadonlySet<string>;\n}\n\n/** The slot's path vertices in world units, as the constraint reads them at the moment it runs. */\nfunction pathWorld(state: PathSolverState, c: CorePathRecord, g: CorePathGeometry): number[] {\n return worldVertices(g.vertices, state.world.get(c.slotBone) as CoreWorld, state.world, g.exact === true ? EXACT_COORDS : Math.fround);\n}\n\nfunction onLineBefore(p: number, x1: number, y1: number, x2: number, y2: number, out: number[], o: number): void {\n const r = Math.atan2(y2 - y1, x2 - x1);\n out[o] = x1 + p * Math.cos(r);\n out[o + 1] = y1 + p * Math.sin(r);\n out[o + 2] = r;\n}\n\nfunction onLinePast(p: number, x0: number, y0: number, x1: number, y1: number, out: number[], o: number): void {\n const r = Math.atan2(y1 - y0, x1 - x0);\n out[o] = x1 + p * Math.cos(r);\n out[o + 1] = y1 + p * Math.sin(r);\n out[o + 2] = r;\n}\n\nfunction onCurve(p: number, x1: number, y1: number, cx1: number, cy1: number, cx2: number, cy2: number, x2: number, y2: number, out: number[], o: number, wantsTangent: boolean): void {\n if (Number.isNaN(p)) {\n out[o] = x1;\n out[o + 1] = y1;\n out[o + 2] = Math.atan2(cy1 - y1, cx1 - x1);\n return;\n }\n const t2 = p * p;\n const t3 = t2 * p;\n const u = 1 - p;\n const u2 = u * u;\n const u3 = u2 * u;\n const ut = u * p;\n const ut3x = ut * 3;\n const w1 = u * ut3x;\n const w2 = ut3x * p;\n const x = x1 * u3 + cx1 * w1 + cx2 * w2 + x2 * t3;\n const y = y1 * u3 + cy1 * w1 + cy2 * w2 + y2 * t3;\n out[o] = x;\n out[o + 1] = y;\n if (wantsTangent) {\n if (p < 0.001) out[o + 2] = Math.atan2(cy1 - y1, cx1 - x1);\n else out[o + 2] = Math.atan2(y - (y1 * u2 + cy1 * ut * 2 + cy2 * t2), x - (x1 * u2 + cx1 * ut * 2 + cx2 * t2));\n }\n}\n\n/** The world position and angle of each space along the path. */\nfunction positionsOf(state: PathSolverState, c: CorePathRecord, g: CorePathGeometry, spaces: number[], wantsTangent: boolean): number[] {\n const spaceCount = spaces.length;\n const pts = pathWorld(state, c, g);\n const n = pts.length / 2;\n const P = (k: number): [number, number] => [pts[2 * k], pts[2 * k + 1]];\n const out: number[] = new Array(spaceCount * 3 + 2).fill(0);\n const closed = g.closed;\n let position = c.position;\n if (!g.constantSpeed) {\n const lengths = g.lengths;\n const curveCount = n / 3 - (closed ? 1 : 2);\n const total = lengths[curveCount];\n if (c.positionMode === 'percent') position *= total;\n const spaceScale = c.spacingMode === 'percent' ? total : c.spacingMode === 'proportional' ? total / spaceCount : 1;\n let curve = 0;\n for (let i = 0, o = 0; i < spaceCount; i++, o += 3) {\n const space = spaces[i] * spaceScale;\n position += space;\n let p = position;\n if (closed) {\n p %= total;\n if (p < 0) p += total;\n curve = 0;\n } else if (p < 0) {\n const [x1, y1] = P(1);\n const [x2, y2] = P(2);\n onLineBefore(p, x1, y1, x2, y2, out, o);\n continue;\n } else if (p > total) {\n const [x0, y0] = P(n - 3);\n const [x1, y1] = P(n - 2);\n onLinePast(p - total, x0, y0, x1, y1, out, o);\n continue;\n }\n for (;; curve++) {\n const length = lengths[curve];\n if (p > length) continue;\n if (curve === 0) p /= length;\n else {\n const prev = lengths[curve - 1];\n p = (p - prev) / (length - prev);\n }\n break;\n }\n const k = 3 * curve + 1;\n const q = (m: number): [number, number] => P((k + m) % n);\n const [x1, y1] = q(0);\n const [cx1, cy1] = q(1);\n const [cx2, cy2] = q(2);\n const [x2, y2] = q(3);\n onCurve(p, x1, y1, cx1, cy1, cx2, cy2, x2, y2, out, o, wantsTangent || (i > 0 && space === 0));\n }\n return out;\n }\n // constant speed: the chain, knot handle handle knot …\n const chain: number[] = [];\n if (closed) {\n for (let k = 1; k < n; k++) chain.push(...P(k));\n chain.push(...P(0), ...P(1));\n } else for (let k = 1; k < n - 1; k++) chain.push(...P(k));\n const curveCount = closed ? n / 3 : n / 3 - 1;\n const curveEnds = curveLengthTable(chain, curveCount);\n const total = curveEnds.length > 0 ? curveEnds[curveEnds.length - 1] : 0;\n if (c.positionMode === 'percent') position *= total;\n const spaceScale = c.spacingMode === 'percent' ? total : c.spacingMode === 'proportional' ? total / spaceCount : 1;\n const segmentEnds: number[] = new Array(10).fill(0);\n let curveTotal = 0;\n let lastCurve = -1;\n let x1 = 0, y1 = 0, cx1 = 0, cy1 = 0, cx2 = 0, cy2 = 0, x2 = 0, y2 = 0;\n for (let i = 0, o = 0, curve = 0, segment = 0; i < spaceCount; i++, o += 3) {\n const space = spaces[i] * spaceScale;\n position += space;\n let p = position;\n if (closed) {\n p %= total;\n if (p < 0) p += total;\n curve = 0;\n segment = 0;\n } else if (p < 0) {\n onLineBefore(p, chain[0], chain[1], chain[2], chain[3], out, o);\n continue;\n } else if (p > total) {\n const e = chain.length;\n onLinePast(p - total, chain[e - 4], chain[e - 3], chain[e - 2], chain[e - 1], out, o);\n continue;\n }\n for (;; curve++) {\n const length = curveEnds[curve];\n if (p > length) continue;\n if (curve === 0) p /= length;\n else {\n const prev = curveEnds[curve - 1];\n p = (p - prev) / (length - prev);\n }\n break;\n }\n if (curve !== lastCurve) {\n lastCurve = curve;\n const ii = curve * 6;\n x1 = chain[ii];\n y1 = chain[ii + 1];\n cx1 = chain[ii + 2];\n cy1 = chain[ii + 3];\n cx2 = chain[ii + 4];\n cy2 = chain[ii + 5];\n x2 = chain[ii + 6];\n y2 = chain[ii + 7];\n const h2x = (x1 - cx1 * 2 + cx2) * 0.03;\n const h2y = (y1 - cy1 * 2 + cy2) * 0.03;\n const d3x = ((cx1 - cx2) * 3 - x1 + x2) * 0.006;\n const d3y = ((cy1 - cy2) * 3 - y1 + y2) * 0.006;\n let d2x = h2x * 2 + d3x;\n let d2y = h2y * 2 + d3y;\n let d1x = (cx1 - x1) * 0.3 + h2x + d3x * 0.16666667;\n let d1y = (cy1 - y1) * 0.3 + h2y + d3y * 0.16666667;\n curveTotal = Math.sqrt(d1x * d1x + d1y * d1y);\n segmentEnds[0] = curveTotal;\n for (let s = 1; s < 8; s++) {\n d1x += d2x;\n d1y += d2y;\n d2x += d3x;\n d2y += d3y;\n curveTotal += Math.sqrt(d1x * d1x + d1y * d1y);\n segmentEnds[s] = curveTotal;\n }\n d1x += d2x;\n d1y += d2y;\n curveTotal += Math.sqrt(d1x * d1x + d1y * d1y);\n segmentEnds[8] = curveTotal;\n d1x += d2x + d3x;\n d1y += d2y + d3y;\n curveTotal += Math.sqrt(d1x * d1x + d1y * d1y);\n segmentEnds[9] = curveTotal;\n segment = 0;\n }\n p *= curveTotal;\n for (;; segment++) {\n const length = segmentEnds[segment];\n if (p > length) continue;\n if (segment === 0) p /= length;\n else {\n const prev = segmentEnds[segment - 1];\n p = segment + (p - prev) / (length - prev);\n }\n break;\n }\n onCurve(p * 0.1, x1, y1, cx1, cy1, cx2, cy2, x2, y2, out, o, wantsTangent || (i > 0 && space === 0));\n }\n return out;\n}\n\n/** A path constraint (the header): returns the bones it moved, every one in world space. */\nexport function solvePath(state: PathSolverState, c: CorePathRecord, slotWorld: CoreWorld): { changed: string[]; inWorld: string[] } {\n const g = c.path;\n const none = { changed: [], inWorld: [] };\n if (g === null) return none;\n const { mixRotate, mixX, mixY } = c;\n if (mixRotate === 0 && mixX === 0 && mixY === 0) return none;\n const wantsTangent = c.rotateMode === 'tangent';\n const scale = c.rotateMode === 'chainScale';\n const bones = c.bones.map((n) => state.bones[state.index.get(n) as number]);\n const boneCount = bones.length;\n const spaceCount = wantsTangent ? boneCount : boneCount + 1;\n const spaces: number[] = new Array(spaceCount).fill(0);\n const lengths: number[] = scale ? new Array(boneCount).fill(0) : [];\n const spacing = c.spacing;\n const worldOf = (b: ModelBone): CoreWorld => state.world.get(b.name) as CoreWorld;\n if (c.spacingMode === 'percent') {\n if (scale) {\n for (let i = 0; i < spaceCount - 1; i++) {\n const b = bones[i];\n const boneLength = b.length ?? 0;\n const w = worldOf(b);\n const x = boneLength * w.a;\n const y = boneLength * w.c;\n lengths[i] = Math.sqrt(x * x + y * y);\n }\n }\n for (let i = 1; i < spaceCount; i++) spaces[i] = spacing;\n } else if (c.spacingMode === 'proportional') {\n let sum = 0;\n for (let i = 0, n = spaceCount - 1; i < n; ) {\n const b = bones[i];\n const boneLength = b.length ?? 0;\n if (boneLength < EPSILON) {\n if (scale) lengths[i] = 0;\n spaces[++i] = spacing;\n } else {\n const w = worldOf(b);\n const x = boneLength * w.a;\n const y = boneLength * w.c;\n const length = Math.sqrt(x * x + y * y);\n if (scale) lengths[i] = length;\n spaces[++i] = length;\n sum += length;\n }\n }\n if (sum > 0) {\n sum = (spaceCount / sum) * spacing;\n for (let i = 1; i < spaceCount; i++) spaces[i] *= sum;\n }\n } else {\n const addsLength = c.spacingMode === 'length';\n for (let i = 0, n = spaceCount - 1; i < n; ) {\n const b = bones[i];\n const boneLength = b.length ?? 0;\n if (boneLength < EPSILON) {\n if (scale) lengths[i] = 0;\n spaces[++i] = spacing;\n } else {\n const w = worldOf(b);\n const x = boneLength * w.a;\n const y = boneLength * w.c;\n const length = Math.sqrt(x * x + y * y);\n if (scale) lengths[i] = length;\n spaces[++i] = ((addsLength ? Math.max(0, boneLength + spacing) : spacing) * length) / boneLength;\n }\n }\n }\n const positions = positionsOf(state, c, g, spaces, wantsTangent);\n let atX = positions[0];\n let atY = positions[1];\n let offsetRotation = c.offsetRotation;\n let fromTip: boolean;\n if (offsetRotation === 0) fromTip = c.rotateMode === 'chain';\n else {\n fromTip = false;\n const p = slotWorld;\n offsetRotation *= p.a * p.d - p.b * p.c > 0 ? RAD : -RAD;\n }\n const changed: string[] = [];\n for (let i = 0, p = 3; i < boneCount; i++, p += 3) {\n const b = bones[i];\n const w = { ...worldOf(b) };\n w.worldX += (atX - w.worldX) * mixX;\n w.worldY += (atY - w.worldY) * mixY;\n const x = positions[p];\n const y = positions[p + 1];\n const dx = x - atX;\n const dy = y - atY;\n if (scale) {\n const length = lengths[i];\n if (length >= EPSILON) {\n const s = (Math.sqrt(dx * dx + dy * dy) / length - 1) * mixRotate + 1;\n w.a *= s;\n w.c *= s;\n }\n }\n atX = x;\n atY = y;\n if (mixRotate > 0) {\n const { a, b: bb, c: cc, d } = w;\n let r: number;\n if (wantsTangent) r = positions[p - 1];\n else if (spaces[i + 1] === 0) r = positions[p + 2];\n else r = Math.atan2(dy, dx);\n r -= Math.atan2(cc, a);\n if (fromTip) {\n const cos = Math.cos(r);\n const sin = Math.sin(r);\n const length = b.length ?? 0;\n atX += (length * (cos * a - sin * cc) - dx) * mixRotate;\n atY += (length * (sin * a + cos * cc) - dy) * mixRotate;\n } else r += offsetRotation;\n if (r > RUNTIME_PI) r -= RUNTIME_PI * 2;\n else if (r < -RUNTIME_PI) r += RUNTIME_PI * 2;\n r *= mixRotate;\n const cos = Math.cos(r);\n const sin = Math.sin(r);\n w.a = cos * a - sin * cc;\n w.b = cos * bb - sin * d;\n w.c = sin * a + cos * cc;\n w.d = sin * bb + cos * d;\n }\n state.world.set(b.name, w);\n changed.push(b.name);\n }\n return { changed, inWorld: [...changed] };\n}\n\n// ---------------------------------------------------------------------------\n// the dump's two path blocks\n// ---------------------------------------------------------------------------\n\n/** A mode as the runtime's enum names it: the first letter upper-cased (`chainScale` → `ChainScale`). */\nconst enumName = (mode: string): string => mode[0].toUpperCase() + mode.slice(1);\n\n/** One `paths` row, the oracle's shape (`OraclePathRow` in `tools/pose_oracle.ts`). */\nexport interface CorePathRow {\n name: string;\n slot: string;\n bones: string[];\n positionMode: string;\n spacingMode: string;\n rotateMode: string;\n offsetRotation: number | null;\n position: number | null;\n spacing: number | null;\n mixRotate: number | null;\n mixX: number | null;\n mixY: number | null;\n}\n\n/** One `pathAttachments` row, the oracle's shape. */\nexport interface CorePathAttachmentRow {\n skin: string;\n slot: string;\n placeholder: string;\n closed: boolean;\n constantSpeed: boolean;\n lengths: Array<number | null>;\n}\n\n/** The `paths` block: every path record in the document's order, its modes as the runtime names them, its numbers through `round`. */\nexport function pathRows(records: readonly CorePathRecord[], round: (v: number) => number | null): CorePathRow[] {\n return records.map((r) => ({\n name: r.name, slot: r.slot, bones: [...r.bones],\n positionMode: enumName(r.positionMode), spacingMode: enumName(r.spacingMode), rotateMode: enumName(r.rotateMode),\n offsetRotation: round(r.offsetRotation), position: round(r.position), spacing: round(r.spacing), mixRotate: round(r.mixRotate), mixX: round(r.mixX), mixY: round(r.mixY),\n }));\n}\n\n/** The `pathAttachments` block: every path attachment of every skin, its two flags as read and its `lengths` through `round`. */\nexport function pathAttachmentRows(skins: ReadonlyArray<{ name: string; attachments: Record<string, Record<string, { geometry?: { kind: string } & Partial<CorePathGeometry> }>> }>, round: (v: number) => number | null): CorePathAttachmentRow[] {\n const out: CorePathAttachmentRow[] = [];\n for (const skin of skins) {\n for (const [slot, table] of Object.entries(skin.attachments)) {\n for (const [placeholder, record] of Object.entries(table)) {\n const g = record.geometry;\n if (g?.kind !== 'path') continue;\n out.push({ skin: skin.name, slot, placeholder, closed: g.closed === true, constantSpeed: g.constantSpeed !== false, lengths: (g.lengths ?? []).map(round) });\n }\n }\n }\n return out;\n}\n\n// ---------------------------------------------------------------------------\n// which slot bone the offset's sign reads\n// ---------------------------------------------------------------------------\n\n/**\n * When the runtime last set a path constraint's slot bone's world before the\n * constraint runs (the header's *Which slot bone*): during the ordering of\n * constraint `at` — brought up to date from its parent just `before` that\n * constraint runs, or moved by it and so as it left the bone, `after` it.\n */\nexport interface SlotBoneEvent {\n at: number;\n when: 'before' | 'after';\n}\n\n/**\n * For each path constraint, by its index in `records`, the last event that\n * set its slot bone's world before it runs — `null` when nothing has in this\n * pass, and the bone holds the previous pass's world. The runtime orders its\n * update before it poses: each constraint in turn brings the bones it reads\n * and moves up to date (a bone, its parents first, once until something\n * below which it hangs moves), and every bone left over follows at the end.\n * `skipped` names the constraints the runtime does not apply, which it does\n * not order either.\n */\nexport function slotBonePlan(bones: readonly ModelBone[], active: ReadonlySet<string>, records: readonly CoreConstraintRecord[], skipped: ReadonlySet<number>): Map<number, SlotBoneEvent | null> {\n const parent = new Map(bones.map((b) => [b.name, b.parent]));\n const children = new Map<string, string[]>();\n for (const b of bones) if (b.parent !== undefined) children.set(b.parent, [...(children.get(b.parent) ?? []), b.name]);\n const ordered = new Map(bones.map((b) => [b.name, !active.has(b.name)]));\n const last = new Map<string, SlotBoneEvent>();\n const orderBone = (name: string, m: number): void => {\n if (ordered.get(name)) return;\n const p = parent.get(name);\n if (p !== undefined) orderBone(p, m);\n ordered.set(name, true);\n last.set(name, { at: m, when: 'before' });\n };\n const unorder = (names: readonly string[]): void => {\n for (const n of names) {\n if (!active.has(n)) continue;\n if (ordered.get(n)) unorder(children.get(n) ?? []);\n ordered.set(n, false);\n }\n };\n const plan = new Map<number, SlotBoneEvent | null>();\n records.forEach((c, m) => {\n if (skipped.has(m)) return;\n let moved: readonly string[];\n // A slider sets no bone in the order; it resets each bone its animation keys, and what hangs below it (the header's *Which slot bone*).\n if (c.kind === 'slider') {\n unorder(c.timelines.bones.map((t) => t.name));\n return;\n }\n if (c.kind === 'ik') {\n moved = c.bones;\n orderBone(c.target, m);\n orderBone(c.bones[0], m);\n if (c.bones.length > 1) orderBone(c.bones[c.bones.length - 1], m);\n unorder(children.get(c.bones[0]) ?? []);\n if (c.bones.length > 1) ordered.set(c.bones[c.bones.length - 1], true);\n } else {\n // A physics constraint orders its one bone as a one-bone constraint does (the header's *Which slot bone*).\n moved = c.kind === 'physics' ? [c.bone] : c.bones;\n if (c.kind === 'transform') orderBone(c.source, m);\n else if (c.kind === 'path') for (const d of c.slotDeps) orderBone(d, m);\n for (const b of moved) orderBone(b, m);\n if (c.kind === 'path') plan.set(m, last.get(c.slotBone) ?? null);\n for (const b of moved) unorder(children.get(b) ?? []);\n for (const b of moved) ordered.set(b, true);\n }\n for (const b of moved) last.set(b, { at: m, when: 'after' });\n });\n return plan;\n}\n","/**\n * Construct 5 of the core, third and fourth cuts (issue #938, step 2e-iii,\n * and issue #956, step 2e-iv, of issue #380): the physics constraint — under\n * `Physics.none`, the oracle's default phase, where it applies nothing, and\n * stepped, `Physics.reset` then `Physics.update` at a fixed `dt`, where it\n * integrates.\n *\n * ## What an unstepped physics constraint contributes: nothing\n *\n * Measured by posing hand-written skeletons through `tools/pose_oracle.ts\n * dump` (spine-core 4.3.13, `--skin all`, `--physics none`) twice — once as\n * written, once with every physics constraint and every physics timeline\n * taken out — and comparing the two dumps at tolerance 0:\n *\n * - 400 one-constraint skeletons: the constrained bone in all five inherit\n * modes under a reflecting, sheared, scaled parent, with amplifier bones ten\n * thousand units out along its axes; each of the five components (`x`, `y`,\n * `rotate`, `scaleX`, `shearX`) at 1, between 0 and 2 or negative; `limit`,\n * `fps`, `inertia`, `strength`, `damping`, `mass`, `wind`, `gravity` and\n * `mix` at random, each `…Global` flag at random; half of them with\n * physics timelines keying `mix`, `wind` and `reset` in an animation that\n * also swings the parent — sampled at seven `grid` or `irr` times, every\n * sample posed on the ONE skeleton the dump reuses: **400 of 400\n * identical**.\n * - 462 nine-bone rigs whose two to six constraints mix physics constraints\n * with ik and world- and local-space transform constraints in random order\n * (so a physics constraint sits between a world-space edit and a constraint\n * that re-poses it), physics timelines keying `mix` and `inertia`, five\n * `irr` samples: **462 of 462 identical**, 41,577 bone-samples.\n *\n * So under `Physics.none` the physics constraint neither moves its bone nor\n * re-poses anything below it, whatever its parameters, its `mix` or its\n * timelines, and wherever it stands in the update order: `applyConstraints`\n * is given no step context and applies nothing.\n *\n * ## The stepped phase, measured (issue #956)\n *\n * Every rule below was fixed the same way: hand-written skeletons dumped by\n * `tools/pose_oracle.ts dump --physics step --dt <s>` (spine-core 4.3.13) and\n * by the core, compared at tolerance 0, most with amplifier bones ten\n * thousand units out so a difference of 1e-10 in a matrix reads as a grid\n * step. spine-core's source was not read; each rule is the reading the dump\n * left exact, and each is stated with the population that fixed it and the\n * readings it rejected. The figures `n of 400` below are one population\n * (seed 81 of the lab): 400 rigs of six bones under one to five constraints —\n * physics with every component, setting, `…Global` flag and timeline at\n * random, ik and transform among them, skin-required constraints, two\n * animations, `dt` among 1/60, 1/30, 1/120 and a random 0.005–0.05 — exact\n * on 400 of 400 (63,982 bone-samples) under the rules as written, and the\n * count is how many stayed exact with ONE rule replaced by the reading named.\n * The core suite's `CK` controls hold the probes.\n *\n * **Defaults.** A field the record leaves out reads the parser's value, read\n * off the oracle's `physics` block for a constraint stating nothing: every\n * component 0, `limit` 5000, `fps` 60 (`step` = 1 / fps: 45 read 0.022222),\n * `inertia` 0.5, `strength` 100, `damping` 0.85, `mass` 1 (the block holds\n * `massInverse`: 3 read 0.333333), `wind`, `gravity` 0, `mix` 1, every flag\n * false, `scaleY` `None`. The core writes that block from its records\n * (`physicsRows`), under both phases.\n *\n * **The schedule** (`stepSchedule`) is the oracle's, from its header: a\n * fresh state per animation, the animation applied at 0 and the skeleton\n * reset; then from each sample's predecessor `p`, a step to `p + k·dt` while\n * that is before `t`, then to `t`. The skeleton's clock is the SUM of the\n * steps' deltas (`s − previous s`), not `s`: the constraint reads its delta\n * off that clock. The setup pose under the step is the reset pose. Each step\n * applies the animation from the time the walk last applied it at\n * (`PhysicsStepContext.last`, −1 before the first), as a player does — which\n * decides only when a `reset` key fires (*reset*, below).\n *\n * **Which constraints step.** A constraint on an inactive bone does not. A\n * constraint with `skin: true` steps exactly when an applied skin's\n * `constraints.physics` list names it — under `--skin all` every skin is\n * applied at once, under `--skin <name>` the named skin alone\n * (`listedBySkin`, set per skin view by `underSkin` in `./index.ts`;\n * `physicsActive`). Measured on the\n * commander's private-corpus finding (two rows DIFF, the core leaving such\n * constraints inert): hand-written documents dumped under `--physics step`\n * with `--skin all`, `--skin s1` and `--skin default` — named by no skin:\n * not stepped under any; named by `s1`: stepped under `all` and `s1`, not\n * under `default`; named by the default skin: stepped (under `all`, and —\n * issue #932 — under `default` but not under `s1`); a skin naming the\n * constrained bone (skin-required or not), another physics constraint or an\n * ik constraint, but not this one: not stepped; no skins at all: not\n * stepped. The reading inherited from issue #938 — `skin: true` is never\n * applied under `--skin all` — was measured under `Physics.none`, where a\n * physics constraint applies nothing either way; it is rejected (`CK13`\n * plants it and turns the listed probe red). A\n * constraint whose `mix` is 0 does nothing at all at that update — not even\n * read its clock: a constraint muted from 0 to 0.3 s and then keyed to 1\n * integrates the whole 0.3 s on its first live update after the pending one\n * (sack-pro's `fall-in`; advancing the clock at `mix` 0 kept 394 of 400). A\n * constraint never updated is pending, like a reset one: its first update\n * takes the bone where it is and integrates nothing (not pending kept 399 of\n * 400 and turned sack-pro red).\n *\n * **The components.** Each is on when it is ABOVE 0: `x`, `y`, `scaleX`, and\n * the rotation when `rotate` or `shearX` is (reading any non-zero as on kept\n * 279 of 400). A negative `rotate` or `shearX` still weighs the rotation: its\n * weight is `(rotate + shearX)·mix` (dropping the negative kept 369 of 400).\n *\n * **The step** (`stepPhysics`), in the order measured. `reset` clears every\n * offset, velocity and lag, zeroes what remains and sets the constraint's\n * clock to now; it is also what a `reset` key does, while the animation is\n * applied — before the step's delta is added. Then:\n *\n * - `delta` is the clock since the constraint last read it (never below 0),\n * added to what remains. A pending constraint takes the bone's origin as\n * the one it follows and integrates nothing; what remains is kept.\n * - `x`, `y`: the offset gains `(previous origin − origin)·inertia`, held to\n * `±limit·delta`. Then while at least one fixed `step` remains: `velocity\n * += (wind·R − offset·strength)·massInverse·step` (`y`: `−= (gravity·R +\n * offset·strength)·…`), `offset += velocity·step`, `velocity *=\n * damping^(60·step)` (`damping` itself kept 268 of 400; exact at 60 fps,\n * where the exponent is 1), and one step is taken off. What remains is\n * carried to the next update (dropping it kept 116 of 400; integrating once\n * per update at `dt` in place of `step` kept 116).\n * - The offset shown is `offset − lag·(1 − remaining/step)` (at least 0),\n * `lag` the change the integration just made: the pose between two fixed\n * steps (showing the integrated offset kept 116 of 400). The bone's origin\n * moves by it times `mix` times the component.\n * - Rotation and shear follow the bone's tip: with `ca` the bone's x-axis\n * angle and `(dx, dy)` how far its origin moved since the last update (each\n * held to `±limit·delta`), the offset gains `atan2(dy + ty, dx + tx) − ca −\n * (offset − lag·z₀)·w`, brought into (−π, π] with the runtime's π\n * (3.1415927: `Math.PI` kept 369 of 400), times `inertia` — `(tx, ty)` the\n * tip `length·(a, c)` the last update left, `w` the weight above, and `z₀`\n * the SHOWN weight of the previous update: `1 − remaining/step` before\n * this update's delta is added (after it kept 177 of 400; no lag at all\n * kept 176). The spring then runs as for `x` with `−((wind·sin + gravity·\n * cos)·length/R + offset·strength)·massInverse` — `sin`, `cos` of the\n * shown angle, re-read after every step.\n * - `scaleX` follows the tip along the bone: the offset gains `(dx·cos +\n * dy·sin)·inertia / r`, `r = length·|x column|`, and springs with `(wind·cos\n * − gravity·sin − offset·strength)·massInverse`. ⚠️ With no rotation on,\n * `r` is `length·|x column| − lag·z₀` — a dimensionless lag taken from a\n * length. It is the measured reading, not a derived one: the plain `r`\n * left scale-only probes off by a relative `(inertia step)·lag/length`\n * (`1 − 0.00020008` on a 50-unit bone moved one unit a step, `5e-5` at 100\n * units, `8e-4` at 25), and the subtraction made them exact (the plain `r`\n * kept 357 of 400; with rotation on the plain `r` is the exact one).\n * - Applied last: the rotation `o = (offset − lag·z)·mix` turns both columns\n * by `o·rotate`; with `shearX` on, the y column turns by `o·rotate` and\n * the x column by `o·(rotate + shearX)` (the first reading turned the y\n * column for the shear and read 0.049 off). The x column is scaled by `1 +\n * (offset − lag·z)·mix·scaleX`. The tip `length·(a, c)` is kept for the next\n * update.\n * - After it the bone is a world edit, as a world-space transform constraint\n * leaves one: its local values read back (`localFromWorld`) and every bone\n * below it posed again — so a constraint whose components are all 0 but\n * whose `mix` is not still re-derives its bone.\n *\n * **referenceScale.** `R` above is the skeleton's `referenceScale`. A Spine\n * header stating 50 moved 30 of 50 wind-and-gravity probes, and moved none\n * without them. The model document states it (`referenceScale`, issue\n * #958): `readModel` refuses a document without it by name and stamps it on\n * every physics record (`CorePhysicsRecord.referenceScale`), which is what\n * the step reads. Until #958 the core read the parser's 100 as a constant.\n *\n * ## The timelines\n *\n * `inertia`, `strength`, `damping`, `mass`, `wind`, `gravity` and `mix`\n * keys, one channel each, construct 4's key search and curves (key times and\n * values float32), applied in the animation's order. Before the first key\n * the setup value; after it `setup + (value − setup)` — the blend at alpha 1,\n * not the value itself: the two differ by a unit in the last place, and a\n * mass probe (a parent thrown 3e11 units) and a two-constraint wind-and-mix\n * probe both read it (the value itself kept 400 of 400 in the population and\n * turned both probes red). A `mass` key states a mass: the pose holds\n * `1 / (m₀ + (value − m₀))`, `m₀ = 1 / massInverse`. A key omitting its\n * value reads 0, a `mix` key 1 (`docs/AUTHORING.md` §4.4; a first key with\n * no value, on each of the seven, read exact — the `mass` one NaN in both\n * dumps). The timeline that\n * names no constraint (`*`) writes every active constraint whose `…Global`\n * flag for that value is on, and resets every active constraint. A\n * slider's animation keys them too, at the slider's place in the update\n * order (issue #1049, `./constraints_slider.ts` *Its physics timelines*).\n *\n * **reset.** A `reset` key resets its constraints on the step whose apply\n * crosses it — a key in `(last, t]`, `last` the time the walk last applied\n * the animation at, −1 before the first (`resetCrossed`) — so once, as a\n * player crosses it (issue #960, measured against `Animation.apply(last,\n * t)` and against `AnimationState` with one track, which agreed to the bit:\n * `tools/pose_oracle.ts` §`--physics step`). Until issue #960 the oracle\n * applied the animation from 0 at every step, and this walk mirrored it: a\n * key reset its constraints at EVERY step from it on, holding the rig still\n * (ignoring the key, or firing it once, kept 278 of 400 under that\n * oracle). That\n * reading is rejected as a schedule no player runs; the core suite's `SC`\n * controls plant it and turn the probe red on the steps after the key.\n *\n * ## What is not exact, and why\n *\n * Over 3,000 random rigs of three shapes (all five inherit modes; ik and\n * transform among them; skin-required constraints; the timeline naming no\n * constraint) the step read exact on 2,986. The fourteen: three are wrong\n * under `--physics none` too (a transform collapsing its bone's scale, and\n * no step involved); one is a bone under an inactive parent, whose zero\n * matrix both dumpers take to NaN by different routes; the other ten are\n * last-bit differences upstream of the step, amplified by it — seven on a\n * bone in `noScale`, `noScaleOrReflection` or `noRotationOrReflection`,\n * whose world transform `./world.ts` reproduces to the grid but not to the\n * bit (a probe amplified a billion units read one of those modes a few\n * units in the last place on 61 of 61 samples, and the four other modes on\n * none), two after `localFromWorld` re-derived a bone the step then moves\n * again, and one under a constraint whose rotation weight is negative, where\n * the inertia pushes away and any difference grows. Each is exact with the\n * bones normal, or with the weight positive. The step itself holds no\n * residual found.\n *\n * ## Purity\n *\n * As the rest of the core: nothing from the Spine runtime package, nothing\n * from `src/transform.ts`, no clock, no randomness, no I/O.\n */\nimport { channelAt, keyIndexAt, poseAnimations, sampleTime, type CoreAnimationPose, type CoreCurve, type CoreKey, type SamplePhase, type TimelinePlant } from './animation.ts';\nimport { RUNTIME_PI, type CoreWorld } from './world.ts';\nimport { previousPassSlotBones, type CoreConstraintRecord } from './constraints.ts';\nimport { activeBones, type CompiledDocument } from './index.ts';\n\n/** The fields a physics constraint's record may carry after `kind`, `name`, `declaredIn` — the rig branch of `buildRigConstraint` and the motion spec's physics table (`src/compile.ts`). */\nexport const PHYSICS_FIELDS = [\n 'bone', 'scaleY', 'x', 'y', 'rotate', 'scaleX', 'shearX', 'limit', 'fps', 'inertia', 'strength', 'damping', 'mass', 'wind', 'gravity', 'mix',\n 'inertiaGlobal', 'strengthGlobal', 'dampingGlobal', 'massGlobal', 'windGlobal', 'gravityGlobal', 'mixGlobal', 'skin',\n] as const;\nconst PHYSICS_NUMBERS = ['x', 'y', 'rotate', 'scaleX', 'shearX', 'limit', 'fps', 'inertia', 'strength', 'damping', 'mass', 'wind', 'gravity', 'mix'] as const;\nconst PHYSICS_FLAGS = ['inertiaGlobal', 'strengthGlobal', 'dampingGlobal', 'massGlobal', 'windGlobal', 'gravityGlobal', 'mixGlobal', 'skin'] as const;\n/** The `scaleY` modes, first letter in either case (the ik constraint's enum, which a physics constraint shares). */\nconst SCALE_Y_MODES = ['none', 'uniform', 'volume'] as const;\n\n/** The five components a physics constraint drives, in the row's order. */\nexport const PHYSICS_COMPONENTS = ['x', 'y', 'rotate', 'scaleX', 'shearX'] as const;\n/** The seven values its pose holds and its timelines key, in the row's order (`mass` as the key states it; the pose holds its inverse). */\nexport const PHYSICS_PARAMETERS = ['inertia', 'strength', 'damping', 'mass', 'wind', 'gravity', 'mix'] as const;\nexport type PhysicsParameter = (typeof PHYSICS_PARAMETERS)[number];\n/** The timelines a physics constraint is keyed by: the seven values and `reset`. */\nexport const PHYSICS_TIMELINE_KINDS = [...PHYSICS_PARAMETERS, 'reset'] as const;\nexport type PhysicsTimelineKind = (typeof PHYSICS_TIMELINE_KINDS)[number];\n/** The model's name for the timeline that names no constraint (`EVERY_GLOBAL_PHYSICS` in `src/motion.ts`). */\nexport const EVERY_GLOBAL_PHYSICS = '*';\n\n/**\n * The parser's value for a field the record leaves out, measured off the\n * oracle's `physics` block for a constraint stating nothing (the header's\n * *Defaults*): every component 0, `limit` 5000, `fps` 60, `inertia` 0.5,\n * `strength` 100, `damping` 0.85, `mass` 1, `wind` and `gravity` 0, `mix` 1.\n */\nexport const PHYSICS_DEFAULTS = { x: 0, y: 0, rotate: 0, scaleX: 0, shearX: 0, limit: 5000, fps: 60, inertia: 0.5, strength: 100, damping: 0.85, mass: 1, wind: 0, gravity: 0, mix: 1 } as const;\n\n/** The values a physics constraint's pose holds — what its timelines set and its step reads. */\nexport interface PhysicsPose {\n inertia: number;\n strength: number;\n damping: number;\n massInverse: number;\n wind: number;\n gravity: number;\n mix: number;\n}\n\n/** A physics constraint, read field by field: its bone, the components it drives, its settings and its setup pose. */\nexport interface CorePhysicsRecord extends PhysicsPose {\n kind: 'physics';\n name: string;\n bone: string;\n skin: boolean;\n /** An applied skin's `constraints.physics` list names it — what makes a skin-required constraint step (the header's *Which constraints step*); set per skin view by `underSkin` in `./index.ts`. */\n listedBySkin: boolean;\n x: number;\n y: number;\n rotate: number;\n scaleX: number;\n shearX: number;\n limit: number;\n /** `1 / fps`, the integrator's fixed step in seconds. */\n step: number;\n /** The skeleton's reference scale — the document's `referenceScale` (issue #958), which wind and gravity act over. */\n referenceScale: number;\n /** Each `…Global` flag, by the value it opts in to being driven by the timeline that names no constraint. */\n global: Record<PhysicsParameter, boolean>;\n scaleYMode: 'None' | 'Uniform' | 'Volume';\n}\n\n/**\n * A physics constraint's record, read field by field — every field the writer\n * can write for the kind and no other, each of its type, its bone a bone of\n * the document — or `undefined` with the problems named. A field left out\n * reads the parser's value (`PHYSICS_DEFAULTS`). `referenceScale` is the\n * document's, read by `readModel` (issue #958), and stamped on the record.\n */\nexport function readPhysicsRecord(raw: Record<string, unknown>, name: string, where: string, bones: ReadonlySet<string>, referenceScale: number, problems: string[]): CorePhysicsRecord | undefined {\n const before = problems.length;\n for (const key of Object.keys(raw)) {\n if (key === 'kind' || key === 'name' || key === 'declaredIn') continue;\n if (!(PHYSICS_FIELDS as readonly string[]).includes(key)) problems.push(`${where}: field \"${key}\" is not one this reader knows; it reads [${PHYSICS_FIELDS.join(', ')}]`);\n }\n if (typeof raw.bone !== 'string' || !bones.has(raw.bone)) problems.push(`${where}: bone is ${JSON.stringify(raw.bone)}, not a bone of this document`);\n for (const key of PHYSICS_NUMBERS) {\n const v = raw[key];\n if (v !== undefined && (typeof v !== 'number' || !Number.isFinite(v))) problems.push(`${where}: ${key} is ${JSON.stringify(v)}, not a finite number`);\n }\n for (const key of PHYSICS_FLAGS) {\n const v = raw[key];\n if (v !== undefined && typeof v !== 'boolean') problems.push(`${where}: ${key} is ${JSON.stringify(v)}, not a boolean`);\n }\n let scaleYMode: CorePhysicsRecord['scaleYMode'] = 'None';\n if (raw.scaleY !== undefined) {\n const folded = typeof raw.scaleY === 'string' && raw.scaleY.length > 0 ? raw.scaleY[0].toLowerCase() + raw.scaleY.slice(1) : '';\n if (!(SCALE_Y_MODES as readonly string[]).includes(folded)) problems.push(`${where}: scaleY is ${JSON.stringify(raw.scaleY)}, none of ${SCALE_Y_MODES.join(', ')}`);\n else scaleYMode = folded === 'uniform' ? 'Uniform' : folded === 'volume' ? 'Volume' : 'None';\n }\n if (problems.length !== before) return undefined;\n const n = (key: keyof typeof PHYSICS_DEFAULTS): number => (typeof raw[key] === 'number' ? (raw[key] as number) : PHYSICS_DEFAULTS[key]);\n const global = {} as Record<PhysicsParameter, boolean>;\n for (const p of PHYSICS_PARAMETERS) global[p] = raw[`${p}Global`] === true;\n return {\n kind: 'physics', name, bone: raw.bone as string, skin: raw.skin === true, listedBySkin: false,\n x: n('x'), y: n('y'), rotate: n('rotate'), scaleX: n('scaleX'), shearX: n('shearX'), limit: n('limit'), step: 1 / n('fps'), referenceScale,\n inertia: n('inertia'), strength: n('strength'), damping: n('damping'), massInverse: 1 / n('mass'), wind: n('wind'), gravity: n('gravity'), mix: n('mix'),\n global, scaleYMode,\n };\n}\n\n/** Whether a physics record steps under the skin view posed: its bone active, and not skin-required unless an applied skin lists it — measured, the header's *Which constraints step*. */\nexport function physicsActive(r: CorePhysicsRecord, active: ReadonlySet<string>): boolean {\n return (!r.skin || r.listedBySkin) && active.has(r.bone);\n}\n\n/** One physics timeline: the constraint it names (`EVERY_GLOBAL_PHYSICS` for none), what it keys, its keys (a `reset` key's `values` empty). */\nexport interface CorePhysicsTimeline {\n name: string;\n kind: PhysicsTimelineKind;\n keys: CoreKey[];\n}\n\nconst isObject = (v: unknown): v is Record<string, unknown> => typeof v === 'object' && v !== null && !Array.isArray(v);\n\n/**\n * How many physics timelines one animation record's `constraints.physics`\n * holds — the census's count. Their key times also set the animation's\n * duration, which `./animation.ts` reads.\n */\nexport function physicsTimelineCount(value: unknown): number {\n if (!Array.isArray(value)) return 0;\n let n = 0;\n for (const entry of value) {\n if (typeof entry === 'object' && entry !== null && Array.isArray((entry as { timelines?: unknown }).timelines)) n += (entry as { timelines: unknown[] }).timelines.length;\n }\n return n;\n}\n\n/**\n * One animation record's physics timelines, read in the record's order —\n * which is the order the runtime applies them in — each naming a declared\n * physics constraint or `EVERY_GLOBAL_PHYSICS`, each kind once per name, keys\n * strictly increasing in time with a finite `value` (absent: 1 for `mix`, 0\n * for the rest — the parser's reading) and a `reset` key a time alone.\n */\nexport function readPhysicsTimelines(value: unknown, label: string, declared: ReadonlySet<string>, problems: string[]): CorePhysicsTimeline[] {\n const out: CorePhysicsTimeline[] = [];\n if (!Array.isArray(value)) return out;\n value.forEach((entry, i) => {\n const at = `${label}.constraints.physics[${i}]`;\n if (!isObject(entry) || typeof entry.name !== 'string') {\n problems.push(`${at} names no physics constraint`);\n return;\n }\n const name = entry.name;\n if (name !== EVERY_GLOBAL_PHYSICS && !declared.has(name)) problems.push(`${at}: \"${name}\" is not a physics constraint of this document (nor \"${EVERY_GLOBAL_PHYSICS}\", the timeline naming none)`);\n if (!Array.isArray(entry.timelines)) {\n problems.push(`${at}: timelines is not a list`);\n return;\n }\n const seen = new Set<string>();\n entry.timelines.forEach((raw: unknown, j: number) => {\n const tat = `${at}.timelines[${j}]`;\n const kind = isObject(raw) ? PHYSICS_TIMELINE_KINDS.find((k) => k === raw.name) : undefined;\n if (!isObject(raw) || kind === undefined) {\n problems.push(`${tat}: ${JSON.stringify(isObject(raw) ? raw.name : raw)} is not a physics timeline; one keys ${PHYSICS_TIMELINE_KINDS.join(', ')}`);\n return;\n }\n if (seen.has(kind)) problems.push(`${tat}: \"${kind}\" is keyed twice on \"${name}\"`);\n seen.add(kind);\n const keys: CoreKey[] = [];\n const rawKeys: unknown = raw.keys;\n if (!Array.isArray(rawKeys) || rawKeys.length === 0) {\n problems.push(`${tat} \"${kind}\": keys is not a non-empty list`);\n return;\n }\n let last = -Infinity;\n rawKeys.forEach((k: unknown, q: number) => {\n const kat = `${tat} \"${kind}\".keys[${q}]`;\n if (!isObject(k)) {\n problems.push(`${kat} is not an object`);\n return;\n }\n const known = kind === 'reset' ? ['time'] : ['time', 'value', 'curve'];\n for (const f of Object.keys(k)) if (!known.includes(f)) problems.push(`${kat}: field \"${f}\" is not one this reader knows; it reads [${known.join(', ')}]`);\n const time = k.time;\n if (typeof time !== 'number' || !Number.isFinite(time) || time < 0) {\n problems.push(`${kat}: time is ${JSON.stringify(time)}, not a finite time at or after 0`);\n return;\n }\n if (time <= last) problems.push(`${kat}: time ${time} is not after the key before it — the writer refuses key times that do not strictly increase`);\n last = Math.max(last, time);\n if (kind === 'reset') {\n keys.push({ time: Math.fround(time), values: [], stated: { time, values: [] }, curve: 'stepped' });\n return;\n }\n let v = kind === 'mix' ? 1 : 0;\n if (k.value !== undefined) {\n if (typeof k.value !== 'number' || !Number.isFinite(k.value)) problems.push(`${kat}: value is ${JSON.stringify(k.value)}, not a finite number`);\n else v = k.value;\n }\n let curve: CoreCurve = 'linear';\n if (k.curve !== undefined) {\n if (q === rawKeys.length - 1) problems.push(`${kat}: the last key carries a curve, which eases to no key — the writer refuses it`);\n else if (k.curve === 'stepped') curve = 'stepped';\n else if (Array.isArray(k.curve) && k.curve.length === 4 && k.curve.every((c) => typeof c === 'number' && Number.isFinite(c))) curve = k.curve as number[];\n else problems.push(`${kat}: curve is ${JSON.stringify(k.curve)}, not \"stepped\" nor four finite numbers`);\n }\n keys.push({ time: Math.fround(time), values: [Math.fround(v)], stated: { time, values: [v] }, curve });\n });\n out.push({ name, kind, keys });\n });\n });\n return out;\n}\n\n/** What evaluates one channel of a key and finds the key — construct 4's unless a plant passes others. */\nexport interface PhysicsTimelinePlant {\n channel?: (keys: readonly CoreKey[], index: number, channel: number, t: number) => number;\n search?: (keys: readonly CoreKey[], t: number) => number;\n}\n\n/**\n * The records a physics timeline that names no constraint (`*`) writes: every\n * active one whose `…Global` flag for `kind` is on, and for `reset` every\n * active one (the header's *The timelines*), in the order given. `posedPhysics`\n * asks it, and so does the additive probe (`./additive.ts`, issue #1025).\n */\nexport function unnamedPhysicsTargets<R extends CorePhysicsRecord>(records: readonly R[], kind: PhysicsTimelineKind, active: (r: CorePhysicsRecord) => boolean): R[] {\n return records.filter((r) => active(r) && (kind === 'reset' || r.global[kind]));\n}\n\n/**\n * Every physics record posed by the animation's physics timelines at `t`, in\n * the timelines' order (the header's *The timelines*), and the names of the\n * constraints a `reset` key resets while the animation is applied from\n * `last` to `t` (`resetCrossed`). `active`\n * says whether a constraint is applied at all (its skin and its bone).\n */\nexport function posedPhysics(records: readonly CorePhysicsRecord[], timelines: readonly CorePhysicsTimeline[], t: number, last: number, active: (r: CorePhysicsRecord) => boolean, plant: PhysicsTimelinePlant = {}, wrapped = false): { records: Map<string, CorePhysicsRecord>; reset: Set<string> } {\n const search = plant.search ?? keyIndexAt;\n const channel = plant.channel ?? channelAt;\n const setupOf = new Map(records.map((r) => [r.name, r]));\n const posed = new Map(records.map((r) => [r.name, { ...r }]));\n const reset = new Set<string>();\n for (const tl of timelines) {\n const targets = tl.name === EVERY_GLOBAL_PHYSICS ? unnamedPhysicsTargets([...posed.values()], tl.kind, active) : [posed.get(tl.name) as CorePhysicsRecord].filter((r) => active(r));\n if (tl.kind === 'reset') {\n if (resetCrossed(tl.keys, last, t, wrapped)) for (const r of targets) reset.add(r.name);\n continue;\n }\n const i = search(tl.keys, t);\n for (const r of targets) {\n const setup = setupOf.get(r.name) as CorePhysicsRecord;\n if (tl.kind === 'mass') {\n // The key states a mass; the pose holds its inverse, and the setup the blend starts from is the inverse inverted.\n const from = 1 / setup.massInverse;\n r.massInverse = i < 0 ? setup.massInverse : 1 / (from + (channel(tl.keys, i, 0, t) - from));\n } else {\n r[tl.kind] = i < 0 ? setup[tl.kind] : setup[tl.kind] + (channel(tl.keys, i, 0, t) - setup[tl.kind]);\n }\n }\n }\n return { records: posed, reset };\n}\n\n/**\n * Whether a `reset` timeline resets its constraints when the animation is\n * applied from `last` to `t`, as a player applies it (the header's *reset*,\n * issue #960): exactly when a key lies in `(last, t]` — so a key is crossed\n * once, by the step that reaches it, and `last` is −1 before the walk's\n * first apply, where a key at 0 is crossed.\n *\n * `wrapped` is a looping track's step whose animation time went DOWN (issue\n * #1025, `./walk.ts`): the key crossed is then one after `last` or one at or\n * before `t` — `(last, ∞)` and `(−1, t]` — measured against spine-core's\n * `PhysicsConstraint.reset` calls on A10's walk. A step that wraps the track\n * one or more times while its animation time still rises is not `wrapped`:\n * the runtime fired only `(last, t]` there (a key at 0.25 of a 0.3 s\n * animation stepped by 0.7 s, crossed by the track twice between two applies\n * at 0.1 and 0.2, fired on neither).\n */\nexport function resetCrossed(keys: readonly CoreKey[], last: number, t: number, wrapped = false): boolean {\n return wrapped ? keys.some((k) => k.time > last || k.time <= t) : keys.some((k) => last < k.time && k.time <= t);\n}\n\n// ---------------------------------------------------------------------------\n// the step\n// ---------------------------------------------------------------------------\n\n/** One physics constraint's state between two updates (the header's *The step*). */\nexport interface PhysicsState {\n /** The next update takes the bone where it is and integrates nothing: set by a reset and on a constraint never updated. */\n pending: boolean;\n lastTime: number;\n remaining: number;\n ux: number;\n uy: number;\n cx: number;\n cy: number;\n tx: number;\n ty: number;\n xOffset: number;\n xLag: number;\n xVelocity: number;\n yOffset: number;\n yLag: number;\n yVelocity: number;\n rotateOffset: number;\n rotateLag: number;\n rotateVelocity: number;\n scaleOffset: number;\n scaleLag: number;\n scaleVelocity: number;\n}\n\n/** A constraint's state before its first update: pending, its clock at 0. */\nexport function freshPhysicsState(): PhysicsState {\n return { pending: true, lastTime: 0, remaining: 0, ux: 0, uy: 0, cx: 0, cy: 0, tx: 0, ty: 0, xOffset: 0, xLag: 0, xVelocity: 0, yOffset: 0, yLag: 0, yVelocity: 0, rotateOffset: 0, rotateLag: 0, rotateVelocity: 0, scaleOffset: 0, scaleLag: 0, scaleVelocity: 0 };\n}\n\n/** A reset: offsets, velocities and lags cleared, nothing remaining, the clock read at `time`, pending. */\nexport function resetPhysicsState(s: PhysicsState, time: number): void {\n s.remaining = 0;\n s.lastTime = time;\n s.pending = true;\n s.xOffset = s.xLag = s.xVelocity = 0;\n s.yOffset = s.yLag = s.yVelocity = 0;\n s.rotateOffset = s.rotateLag = s.rotateVelocity = 0;\n s.scaleOffset = s.scaleLag = s.scaleVelocity = 0;\n}\n\n/** The runtime's two phases the oracle steps with: `reset` resets the state first. */\nexport type PhysicsPhase = 'reset' | 'update';\n\n/** What steps one constraint — `stepPhysics` unless a plant passes another. */\nexport type PhysicsStepper = (r: CorePhysicsRecord, w: CoreWorld, length: number, ctx: PhysicsStepContext) => boolean;\n\n/** What a stepped pose carries into every physics constraint it applies. */\nexport interface PhysicsStepContext {\n phase: PhysicsPhase;\n /** The skeleton's clock: the sum of every step's delta so far. */\n time: number;\n /** Each constraint's state, by name, carried from update to update. */\n states: Map<string, PhysicsState>;\n /** The step itself; a control passes a planted copy. */\n step?: PhysicsStepper;\n /**\n * The animation time the walk last applied the animation at, −1 before its\n * first apply — a fresh track's `TrackEntry.animationLast`, read −1 on\n * spine-core 4.3.13 (issue #960). A `reset` key fires on an apply from it\n * to the step's time (`resetCrossed`).\n */\n last: number;\n /**\n * The walk's track loops (`./walk.ts`, issue #1025): a step whose animation\n * time went down from `last` wrapped, and crosses the keys `resetCrossed`\n * names for that. Absent on every walk but the looping one.\n */\n loop?: boolean;\n /** A plant only (issue #1049, `sliderPhysicsLastsOnePass: false`): what the sliders wrote on the step before, by constraint and field. */\n carried?: Map<string, Partial<Record<'inertia' | 'strength' | 'damping' | 'massInverse' | 'wind' | 'gravity' | 'mix', number>>>;\n /** Each `constraint/field` the step's own animation keys — what the planted carried write gives way to. */\n keyedNow?: Set<string>;\n /** A plant only (issue #1049, `sliderPhysicsFromCurrent: false`): each physics record's setup values, before the step's own animation. */\n setupRecords?: Map<string, CorePhysicsRecord>;\n}\n\n/** A constraint's state in `ctx`, created fresh on its first update. */\nexport function physicsState(ctx: PhysicsStepContext, name: string): PhysicsState {\n let s = ctx.states.get(name);\n if (s === undefined) {\n s = freshPhysicsState();\n ctx.states.set(name, s);\n }\n return s;\n}\n\nconst PI2 = RUNTIME_PI * 2;\nconst INV_PI2 = 1 / PI2;\n\n/** What a physics constraint's step moves, by its five component fields. */\nexport interface PhysicsDrives {\n x: boolean;\n y: boolean;\n /** `rotate` or `shearX` above 0: the two share the angular part of the step. */\n rotateOrShearX: boolean;\n scaleX: boolean;\n}\n\n/**\n * Which parts of the step a constraint drives: a component above 0 drives its\n * part and nothing else does — the test `stepPhysics` takes before each part\n * of *The step* above, posed against the runtime with the rest of it. Exported\n * because `src/ingest.ts` asks the same question of a raw file (a\n * constraint that drives none of the four moves no bone, issue #731) and\n * answers it through this function (issue #1015).\n */\nexport function physicsDrives(r: { x: number; y: number; rotate: number; shearX: number; scaleX: number }): PhysicsDrives {\n return { x: r.x > 0, y: r.y > 0, rotateOrShearX: r.rotate > 0 || r.shearX > 0, scaleX: r.scaleX > 0 };\n}\n\n/**\n * One physics constraint updated on its bone's world transform `w`\n * (mutated), `length` the bone's length — the header's *The step*, every\n * expression in the order measured. Returns false when its `mix` is 0: the\n * constraint then does nothing at all, its clock included, and the bone is\n * not re-posed.\n */\nexport function stepPhysics(r: CorePhysicsRecord, w: CoreWorld, length: number, ctx: PhysicsStepContext): boolean {\n const mix = r.mix;\n if (mix === 0) return false;\n const s = physicsState(ctx, r.name);\n const { x, y, rotateOrShearX, scaleX } = physicsDrives(r);\n const l = length;\n if (ctx.phase === 'reset') resetPhysicsState(s, ctx.time);\n const delta = Math.max(ctx.time - s.lastTime, 0);\n // The interpolation weight of the previous update, before this one's time is added: the rotate and the scale-only inertia read the pose as it was shown.\n const shown = Math.max(0, 1 - s.remaining / r.step);\n s.remaining += delta;\n s.lastTime = ctx.time;\n const bx = w.worldX;\n const by = w.worldY;\n let z = 0;\n if (s.pending) {\n s.pending = false;\n s.ux = bx;\n s.uy = by;\n } else {\n let a = s.remaining;\n const i = r.inertia;\n const t = r.step;\n const f = r.referenceScale;\n let d = -1;\n const qx = r.limit * delta;\n const qy = qx;\n if (x || y) {\n if (x) {\n const u = (s.ux - bx) * i;\n s.xOffset += u > qx ? qx : u < -qx ? -qx : u;\n s.ux = bx;\n }\n if (y) {\n const u = (s.uy - by) * i;\n s.yOffset += u > qy ? qy : u < -qy ? -qy : u;\n s.uy = by;\n }\n if (a >= t) {\n d = Math.pow(r.damping, 60 * t);\n const m = r.massInverse * t;\n const e = r.strength;\n const wind = r.wind * f;\n const g = r.gravity * f;\n const xs = s.xOffset;\n const ys = s.yOffset;\n do {\n if (x) {\n s.xVelocity += (wind - s.xOffset * e) * m;\n s.xOffset += s.xVelocity * t;\n s.xVelocity *= d;\n }\n if (y) {\n s.yVelocity -= (g + s.yOffset * e) * m;\n s.yOffset += s.yVelocity * t;\n s.yVelocity *= d;\n }\n a -= t;\n } while (a >= t);\n s.xLag = s.xOffset - xs;\n s.yLag = s.yOffset - ys;\n }\n z = Math.max(0, 1 - a / t);\n if (x) w.worldX += (s.xOffset - s.xLag * z) * mix * r.x;\n if (y) w.worldY += (s.yOffset - s.yLag * z) * mix * r.y;\n }\n if (rotateOrShearX || scaleX) {\n const ca = Math.atan2(w.c, w.a);\n let c = 0;\n let sn = 0;\n let mr = 0;\n let dx = s.cx - w.worldX;\n let dy = s.cy - w.worldY;\n if (dx > qx) dx = qx;\n else if (dx < -qx) dx = -qx;\n if (dy > qy) dy = qy;\n else if (dy < -qy) dy = -qy;\n if (rotateOrShearX) {\n mr = (r.rotate + r.shearX) * mix;\n const lagged = s.rotateLag * shown;\n let rr = Math.atan2(dy + s.ty, dx + s.tx) - ca - (s.rotateOffset - lagged) * mr;\n s.rotateOffset += (rr - Math.ceil(rr * INV_PI2 - 0.5) * PI2) * i;\n rr = (s.rotateOffset - lagged) * mr + ca;\n c = Math.cos(rr);\n sn = Math.sin(rr);\n if (scaleX) {\n rr = l * Math.sqrt(w.a * w.a + w.c * w.c);\n if (rr > 0) s.scaleOffset += ((dx * c + dy * sn) * i) / rr;\n }\n } else {\n c = Math.cos(ca);\n sn = Math.sin(ca);\n const rr = l * Math.sqrt(w.a * w.a + w.c * w.c) - s.scaleLag * shown;\n if (rr > 0) s.scaleOffset += ((dx * c + dy * sn) * i) / rr;\n }\n a = s.remaining;\n if (a >= t) {\n if (d === -1) d = Math.pow(r.damping, 60 * t);\n const m = r.massInverse * t;\n const e = r.strength;\n const wind = r.wind;\n const g = r.gravity;\n const h = l / f;\n const rs = s.rotateOffset;\n const ss = s.scaleOffset;\n for (;;) {\n a -= t;\n if (scaleX) {\n s.scaleVelocity += (wind * c - g * sn - s.scaleOffset * e) * m;\n s.scaleOffset += s.scaleVelocity * t;\n s.scaleVelocity *= d;\n }\n if (rotateOrShearX) {\n s.rotateVelocity -= ((wind * sn + g * c) * h + s.rotateOffset * e) * m;\n s.rotateOffset += s.rotateVelocity * t;\n s.rotateVelocity *= d;\n if (a < t) break;\n const rr = s.rotateOffset * mr + ca;\n c = Math.cos(rr);\n sn = Math.sin(rr);\n } else if (a < t) break;\n }\n s.rotateLag = s.rotateOffset - rs;\n s.scaleLag = s.scaleOffset - ss;\n }\n z = Math.max(0, 1 - a / t);\n }\n s.remaining = a;\n }\n s.cx = w.worldX;\n s.cy = w.worldY;\n if (rotateOrShearX) {\n let o = (s.rotateOffset - s.rotateLag * z) * mix;\n let sn = 0;\n let c = 0;\n let a = 0;\n if (r.shearX > 0) {\n let rr = 0;\n if (r.rotate > 0) {\n // The rotation's share turns the y column here, and the x column with the shear below.\n rr = o * r.rotate;\n sn = Math.sin(rr);\n c = Math.cos(rr);\n a = w.b;\n w.b = c * a - sn * w.d;\n w.d = sn * a + c * w.d;\n }\n rr += o * r.shearX;\n sn = Math.sin(rr);\n c = Math.cos(rr);\n a = w.a;\n w.a = c * a - sn * w.c;\n w.c = sn * a + c * w.c;\n } else {\n o *= r.rotate;\n sn = Math.sin(o);\n c = Math.cos(o);\n a = w.a;\n w.a = c * a - sn * w.c;\n w.c = sn * a + c * w.c;\n a = w.b;\n w.b = c * a - sn * w.d;\n w.d = sn * a + c * w.d;\n }\n }\n if (scaleX) {\n const k = 1 + (s.scaleOffset - s.scaleLag * z) * mix * r.scaleX;\n w.a *= k;\n w.c *= k;\n }\n s.tx = l * w.a;\n s.ty = l * w.c;\n return true;\n}\n\n/** The oracle's `physics` block written from the records, in constraint order, rounded as the oracle rounds. */\nexport function physicsRows(records: readonly CorePhysicsRecord[], round: (v: number) => number | null): Array<Record<string, unknown>> {\n return records.map((r) => ({\n name: r.name, bone: r.bone,\n x: round(r.x), y: round(r.y), rotate: round(r.rotate), scaleX: round(r.scaleX), shearX: round(r.shearX), limit: round(r.limit), step: round(r.step),\n inertia: round(r.inertia), strength: round(r.strength), damping: round(r.damping), massInverse: round(r.massInverse), wind: round(r.wind), gravity: round(r.gravity), mix: round(r.mix),\n inertiaGlobal: r.global.inertia, strengthGlobal: r.global.strength, dampingGlobal: r.global.damping, massGlobal: r.global.mass, windGlobal: r.global.wind, gravityGlobal: r.global.gravity, mixGlobal: r.global.mix,\n skinRequired: r.skin, scaleYMode: r.scaleYMode,\n }));\n}\n\n// ---------------------------------------------------------------------------\n// the walk\n// ---------------------------------------------------------------------------\n\n/**\n * One step's constraint records: every physics record posed by the\n * animation's physics timelines at `t` (`posedPhysics`), and each constraint\n * a `reset` key resets reset now — while the animation is applied, before\n * the skeleton's clock moves to this step (`before` is the clock it reads;\n * the header's *reset*). `./animation.ts` calls it for every step of the walk.\n */\nexport function stepPhysicsRecords(records: readonly CoreConstraintRecord[], keyed: readonly CorePhysicsTimeline[], t: number, active: ReadonlySet<string>, ctx: PhysicsStepContext, before: number): CoreConstraintRecord[] {\n const physics = records.filter((r): r is CorePhysicsRecord => r.kind === 'physics');\n const posed = posedPhysics(physics, keyed, t, ctx.last, (r) => physicsActive(r, active), {}, ctx.loop === true && t < ctx.last);\n ctx.last = t;\n ctx.setupRecords = new Map(physics.map((r) => [r.name, r]));\n ctx.keyedNow = new Set(keyed.flatMap((tl) => (tl.kind === 'reset' ? [] : (tl.name === EVERY_GLOBAL_PHYSICS ? unnamedPhysicsTargets(physics, tl.kind, (r) => physicsActive(r, active)).map((r) => r.name) : [tl.name]).map((n) => `${n}/${tl.kind === 'mass' ? 'massInverse' : tl.kind}`))));\n for (const name of posed.reset) resetPhysicsState(physicsState(ctx, name), before);\n return records.map((r) => (r.kind === 'physics' ? (posed.records.get(r.name) as CorePhysicsRecord) : r));\n}\n\n/** A fresh step context for one animation's walk (or the setup's reset), the plant's step in place of `stepPhysics` when a control passes one. */\nexport function freshStepContext(step?: PhysicsStepper): PhysicsStepContext {\n return { phase: 'reset', time: 0, states: new Map(), last: -1, ...(step ? { step } : {}) };\n}\n\n/**\n * Why the samples' bones are left out under the step, or null: a path\n * constraint whose offset reads its slot bone from the previous pose, which\n * is then the previous step's — a pose the walk does not carry.\n */\nexport function steppedPreviousPassWhy(doc: CompiledDocument): string | null {\n const reads = previousPassSlotBones(doc, activeBones(doc));\n return reads.length === 0 ? null : `${reads.map((r) => `path constraint \"${r.constraint}\" reads slot bone \"${r.bone}\" from the previous pose`).join('; ')} — under the step the previous pose is the previous step's, which the stepped walk does not carry`;\n}\n\n/**\n * The oracle's schedule (the header's *The schedule*): for each of the `n`\n * samples of an animation of duration `d` under `phase`, the times the walk\n * steps to after the sample before it — from the previous sample's time `p`\n * (0 before the first), `p + k·dt` for `k = 1, 2, …` while that is before\n * the sample's `t`, then `t` itself unless the walk is already there. The\n * walk starts at 0 with the reset, so a sample at 0 takes no step.\n */\nexport function stepSchedule(phase: SamplePhase, d: number, n: number, dt: number): number[][] {\n const out: number[][] = [];\n let now = 0;\n for (let i = 0; i < n; i++) {\n const t = sampleTime(phase, d, i, n);\n const from = now;\n const steps: number[] = [];\n for (let k = 1; from + k * dt < t; k++) steps.push(from + k * dt);\n if (steps.length > 0) now = steps[steps.length - 1];\n if (t > now) {\n steps.push(t);\n now = t;\n }\n out.push(steps);\n }\n return out;\n}\n\n/**\n * Every animation of the document walked as the oracle's `--physics step\n * --dt <dt>` walks it (the header's *The schedule*) — `poseAnimations` in\n * `./animation.ts` given `dt`, which poses every block of each sample off\n * the last step's pose — and the steps the schedule takes to reach each\n * sample, per animation.\n */\nexport function poseSteppedAnimations(doc: CompiledDocument, phase: SamplePhase, n: number, dt: number, plant: TimelinePlant = {}): { animations: CoreAnimationPose[]; absent: Array<[string, string]>; steps: number[][] } {\n const posed = poseAnimations(doc, phase, n, plant, dt);\n return { ...posed, steps: doc.animations.map((a) => stepSchedule(phase, a.timelines.duration, n, dt).map((x) => x.length)) };\n}\n","/**\n * Construct 5 of the core, third cut (issue #938, step 2e-iii of issue\n * #380): the slider constraint at the setup pose and at a sample time, with\n * its timelines. A slider applies an animation — the one constraint kind\n * that writes bones' LOCAL values and slots rather than a world transform.\n *\n * Every rule below was measured by posing hand-written skeletons through\n * `tools/pose_oracle.ts dump` (spine-core 4.3.13, `--skin all`,\n * `--physics none`) and reading the rows back — a bone's local values through\n * `localSource` transform constraints written onto spare bones, a slot's row\n * as the dump prints it — then held at tolerance 0 by the core suite's `CQ`\n * controls. Nothing here was written from the runtime's source.\n *\n * ## Where it stands: the update order\n *\n * A slider is one more constraint in the document's order (`./constraints.ts`,\n * *The update order*): it reads its dial bone as the constraints before it\n * left it, writes the local values of the bones its animation keys, and those\n * bones and everything below them are posed again before the next\n * constraint. **Every bone its animation keys is posed again, whether or not\n * a timeline wrote it** (issue #989): a slider before a timeline's first key\n * writes nothing (below), and the bone is still posed again from its local\n * values — which is observable only on a bone an earlier constraint moved in\n * world space, whose world transform the runtime then rebuilds from the\n * local values read back from it (`localFromWorld` in `./constraints.ts`,\n * last-bit lossy against the world it came from). Measured on the three rigs\n * of `CQ06`'s population the lcg never drew (each a world-space transform on\n * `b2`, then a slider before its first key keying `b2` or its parent): `b2`'s\n * y column read 1e-7 relative off with the world kept, exact with it posed\n * again; so did every bone below. A slider at `mix` 0 poses nothing again\n * (the same three at mix 0 read exact only without it), nor does a bone\n * the animation names with no timeline (a `\"b2\": {}` entry). `CZ01` holds\n * the three, and plants the reading before.\n *\n * The runtime's setup pose and every sample apply it: at setup\n * the sliders compose on the setup pose; at a sample on the pose the sample's\n * own animation left (applied at alpha 1 from the setup pose, construct 4),\n * so **the sample's animation first, then each slider in constraint order**.\n *\n * ## The time it applies its animation at\n *\n * - **Bone-less**: the slider's `time` (a `slider` timeline's `time` key at a\n * sample), as it is: a negative time is a time before the animation's keys.\n * - **With a `bone`**: `to + (value − from) · scale`, `value` the dial's\n * `property` read exactly as a transform constraint reads its source with\n * no offset (`sourceValue` in `./constraints.ts`): `local` the local field\n * as earlier constraints left it, unwrapped; world `rotate` the x column's\n * angle brought into [0, 360); world `x`, `y` the origin; world `scaleX`,\n * `scaleY` the column lengths; world `shearY` the angle between the columns\n * less 90. Measured on a dial under a parent turned 30° and scaled 2 in x:\n * a local 10° at `scale` 0.01 read time 0.1, a world 10° read 0.350384 (the\n * x column at 35.0384°), a world −50° read 359.21° (0.35921 at 0.001).\n * Then `max(0, time)` — a dial at −50° applied the first frame — or, with\n * `loop`, `duration + (time mod duration)`: 3 over a 2 s animation read 1,\n * −0.5 read 1.5. A stated `time` beside a `bone` is not read (the bone won).\n * - The animation is then applied at that time, wrapped `time mod duration`\n * when `loop` (a bone-less 3.25 over 1 s read 0.25, which is before the\n * first key at 0.5 and so applied nothing), `duration` being the runtime's\n * (`./animation.ts`, the last key time as float32). ⚠️ A dial looping over\n * an animation of duration 0 computes `0 + (time mod 0)`, NaN — and the\n * runtime still applied the animation's one key (a rotate keyed 45 on a\n * bone at 20 read 65, as the same slider without `loop` and the bone-less\n * form looping at 0 and at 0.5 did): every key of such an animation sits\n * at 0, so the core applies it at 0. The compiler refuses the shape (A37);\n * a foreign file can still carry it.\n *\n * ## How it composes: the current pose, the mix, `additive`\n *\n * Each timeline of the slider's animation, in the animation's order, blends\n * from the CURRENT pose — whatever the setup, the sample's animation and the\n * constraints before it left — with `alpha` the slider's `mix`:\n *\n * - **Before the timeline's first key it writes nothing** (the current pose\n * stands: a slider at 0.2 over a rotate keyed from 0.5 left 20° at setup\n * and the sample's 50° alike). Not the setup value, as a sample's own\n * animation writes (construct 4).\n * - **`mix` 0 applies nothing at all** — not even an attachment key.\n * - `rotate`, `translate`/`x`/`y`, `shear`/`x`/`y`: `current + (setup + v −\n * current) · mix`; **`additive`**: `current + v · mix`. Measured on setup\n * rotation 20 and a sample at 50, the slider's value 150: 170 at mix 1,\n * 110 at 0.5, −10 at −0.5 (no clamp); additive 200 and 125. No wrap to the\n * short way round: 50 toward 290 at 0.3 read 122.\n * - `scale`/`x`/`y`: the target is `setup · v`; `current' + (target −\n * current') · mix` where `current'` is |current| with the TARGET's sign — a\n * setup `scaleY` 0.5 toward −0.5 at mix 0.5 read −0.5, not 0 — and ⚠️ at\n * mix exactly 1 the target itself (issue #989: `current' + (target −\n * current')·1` reads 11 of `CZ02`'s 50 absolute bones at mix 1 last-bit\n * off under `--raw`, the target none); **additive**: `current + (v · setup\n * − setup) · mix` (a current 6 on setup 2, v 3 read 10; issue #989:\n * `(v − 1) · setup · mix`, the reading before, reads 65 of `CZ02`'s 250\n * additive bones last-bit off, this none). The other kinds read 1,122 of\n * 1,122 probes of issue #989's scratch population bit-exact at every mix,\n * over the setup and over a current an earlier slider moved, and were left\n * as they are.\n * - `inherit`: the key's mode, from its first key on (`CQ06` holds it).\n * - Slot colours (`rgba`, `rgb`, `alpha`, `rgba2`, `rgb2`): each channel the\n * timeline names moves from the current value toward the key's by the mix\n * and is then clamped to [0, 1] — ⚠️ at mix exactly 1 it IS the key's value:\n * `current + (v − current)·1` read 1 ulp off spine-core on 30 of 13,950\n * slot readings of issue #969's hand-written population (`DM01`), the key's\n * value on none (a mix of −1 read alpha 0, of 2 read\n * 0.87451 from 0.12549 toward 0.5); `additive` changes nothing for them.\n * - `attachment`: the key's placeholder from its first key on, whatever the\n * mix above 0 (0.01 switched it); `null` shows nothing.\n *\n * ## Its timelines\n *\n * A sample's animation may key a slider's `time` and `mix` (one channel\n * each, construct 4's key search and curves, float32 key values). Before the\n * first key the slider's own value; a key omitting `value` reads 1 (the\n * compiler's note on the parser, measured again by `CQ07`). A bone-driven\n * slider ignores a `time` key: its time is its dial's.\n *\n * The keyed value reaches the slider through the setup blend at alpha 1,\n * `own + (value − own)·1` with `own` the slider's own `time` or `mix` —\n * the rule the ik, transform and path timelines follow (`./constraints.ts`,\n * *The timelines*). The two agree on the grid and part in the last bit: a\n * mix keyed linearly from 0.462 to 0.152 read 0.3521456338160804 as keyed\n * and 0.35214563381608044 through the blend at one sample, and the\n * partial-mix blend of a shear key then carried that ulp into the pose (issue\n * #991, which found it on a looped dial; the loop, the dial and the\n * translate key it was reduced with each turned out incidental — the same\n * rig without them misses on 44 to 71 of 200 draws of its two mix values as\n * keyed and on none through the blend). Measured on the issue's scratch\n * population — 500 rigs of one or two sliders, looped and unlooped dials and\n * bone-less ones, over own mixes in [−1, 2], mix keys and time keys in\n * linear, stepped and Bézier segments, under `--raw` at tolerance 0 — the\n * value as keyed read 351 of 500 exact, the blend on `mix` alone 465, on\n * `time` alone 375, on both 500. `CZ03` holds a reduced rig and plants the\n * value as keyed.\n *\n * ## What is left out, by name\n *\n * A slider whose animation keys a constraint timeline (ik, transform, path,\n * slider — writing a later constraint's pose, issue #665's case) is not\n * posed: the document's bones are absent, naming it; so is one whose\n * animation deforms a curve a path constraint walks (unmeasured). A slider's\n * deform, sequence and draw-order keys are posed since issue #955, after the\n * sample's own (`./deform.ts`, `./draw_order.ts`; they were `sliderAttachmentsWhy`'s\n * absence before). Its physics timelines are posed since issue #1049 (below),\n * and events a slider does not fire, so neither leaves anything out.\n *\n * ## Its physics timelines (issue #1049)\n *\n * Under `Physics.none` a physics constraint applies nothing\n * (`./constraints_physics.ts`), so neither do a slider's physics keys. Under\n * the step they do, and until issue #1049 the core applied none of them: on\n * the selftest's own builds where a dial's animation keys `wind` or\n * `gravity` of a constraint declared after it, every bone the constraint\n * drives left spine-core from the third step (`tip` worldX\n * 14.87037037037037 against 12.092592592592593 at 0.025 s), and with a slot\n * on that bone `render` drew wrong frames with no refusal. Measured against\n * spine-core 4.3.13's output only — A10's looping walk, `render`'s recipe at\n * 60 and 12 fps and the oracle's stepped grid under `--raw`, on 400 compiled\n * rigs of one or two sliders and one or two physics constraints in random\n * order, every kind keyed, at tolerance 0 — the rule is:\n *\n * - **A slider writes its physics keys into the pass's physics records, at\n * its place in the update order**, at the time it applies its animation at\n * (`at`), after the step's own animation posed them; a physics constraint\n * after it steps with what it wrote, one before it has already stepped.\n * Applying the writes to every constraint of the pass whatever its place\n * read 239 of the 400 rigs off; not applying them, 205.\n * - **A write lasts one pass.** The next step's records start again from the\n * step's own animation: a write that stood where the step's animation does\n * not key read 323 of 400 off.\n * - **Before the timeline's first key it writes nothing**, as for bones.\n * - **`wind`, `gravity` under `additive`: `current + v·mix`.** Every other\n * value (`inertia`, `strength`, `damping`, `mass`, `mix`), and every value\n * of a slider that is not additive: `current + (v − current)·mix`, with\n * `current` the value as the pass holds it (the step's own animation and\n * any slider before). Adding every kind read 104 of 400 off; blending from\n * the setup value (before the step's own animation), 80; writing the key\n * itself at mix exactly 1, 20 — in the last bit.\n * - **A `mass` key blends the mass**, `1 / (m + (v − m)·mix)` with `m =\n * 1 / massInverse`; blending the inverse read 28 of 400 off.\n * - **A `reset` key fires nothing** — the slider applies its animation at one\n * time, from that time, so no key is crossed (the path-slider suite's\n * `PS159` measured the same on the pose); firing a key at or before `at` on\n * every pass read 112 of 400 off.\n * - The timeline naming no constraint (`*`) writes every active constraint\n * whose `…Global` flag for that value is on, as a step's own does.\n *\n * `CO31` holds the rule on the `core_gate` probe rows and a seeded population\n * on all three entries; `CO32` plants each rejected reading (`SolverRules`).\n *\n * ## Purity\n *\n * As the rest of the core: nothing from the Spine runtime package, nothing\n * from `src/transform.ts`, no clock, no randomness, no I/O.\n */\nimport type { ModelBone } from '../model.ts';\nimport { channelAt, keyIndexAt, type CoreAnimationTimelines, type CoreCurve, type CoreKey } from './animation.ts';\nimport { sourceValue, TRANSFORM_PROPERTIES, type CoreConstraintRecord, type SolverRules, type SolverState, type TransformProperty } from './constraints.ts';\nimport type { CompiledDocument, CoreAnimation } from './index.ts';\nimport { EVERY_GLOBAL_PHYSICS, physicsActive, physicsState, resetPhysicsState, unnamedPhysicsTargets, type CorePhysicsRecord, type CorePhysicsTimeline, type PhysicsStepContext } from './constraints_physics.ts';\n\n/** The fields a slider's record may carry after `kind`, `name`, `declaredIn` (`buildRigConstraint` in `src/compile.ts`). */\nexport const SLIDER_FIELDS = ['animation', 'additive', 'loop', 'mix', 'bone', 'property', 'from', 'to', 'scale', 'max', 'local', 'time', 'skin'] as const;\n\n/** A slider, read: its animation's timelines and every setup value of the bones they key, so it can be applied with no other part of the document. */\nexport interface CoreSliderRecord {\n kind: 'slider';\n name: string;\n animation: string;\n timelines: CoreAnimationTimelines;\n /** Its animation's physics timelines, in the animation's order (issue #1049) — set by `readModel` once the animations' constraint timelines are read, which is after the records. */\n physics: readonly CorePhysicsTimeline[];\n /** The setup bones its animation keys, by name — what a non-additive key's value is added to. */\n setup: ReadonlyMap<string, ModelBone>;\n additive: boolean;\n loop: boolean;\n mix: number;\n time: number;\n /** The dial, or `null` for the bone-less form. */\n bone: string | null;\n property: TransformProperty;\n from: number;\n to: number;\n scale: number;\n local: boolean;\n skin: boolean;\n /** An applied skin's `slider` list names it — what applies a skin-required one (`./constraints.ts`'s header); set per skin view by `underSkin` in `./index.ts`. */\n listedBySkin: boolean;\n}\n\n/** One slider's timelines in one animation: the `time` and `mix` keys, `null` where not keyed. */\nexport interface CoreSliderTimeline {\n name: string;\n time: CoreKey[] | null;\n mix: CoreKey[] | null;\n}\n\n/** A slider as it was applied: its animation, at which time, with which alpha — what the slots are posed from after the bones. */\nexport interface SliderApplication {\n name: string;\n timelines: CoreAnimationTimelines;\n at: number;\n alpha: number;\n /** The slider's `additive` — how its deform timelines blend (`./deform.ts`). */\n additive: boolean;\n /** #969: the time it stored — `sliderTime`, before the animation's loop wrap — what the runtime's `SliderPose.time` reads (`./hooks.ts`). */\n time: number;\n}\n\nconst isRecord = (v: unknown): v is Record<string, unknown> => typeof v === 'object' && v !== null && !Array.isArray(v);\n\n/**\n * A slider's record, read field by field — every field the writer can write\n * for the kind and no other, each of its type, the animation one of the\n * document's, the dial a bone of it — or `undefined` with the problems named.\n * An absent field reads the parser's value (the header): `mix` 1, `time`,\n * `from`, `to` 0, `scale` 1, the flags false.\n */\nexport function readSliderRecord(raw: Record<string, unknown>, name: string, where: string, bones: readonly ModelBone[], animations: readonly CoreAnimation[], problems: string[]): CoreSliderRecord | undefined {\n const before = problems.length;\n for (const key of Object.keys(raw)) {\n if (key === 'kind' || key === 'name' || key === 'declaredIn') continue;\n if (!(SLIDER_FIELDS as readonly string[]).includes(key)) problems.push(`${where}: field \"${key}\" is not one this reader knows; it reads [${SLIDER_FIELDS.join(', ')}]`);\n }\n const num = (key: string, dflt: number): number => {\n const v = raw[key];\n if (v === undefined) return dflt;\n if (typeof v !== 'number' || !Number.isFinite(v)) {\n problems.push(`${where}: ${key} is ${JSON.stringify(v)}, not a finite number`);\n return dflt;\n }\n return v;\n };\n const flag = (key: string): boolean => {\n const v = raw[key];\n if (v === undefined) return false;\n if (typeof v !== 'boolean') {\n problems.push(`${where}: ${key} is ${JSON.stringify(v)}, not a boolean`);\n return false;\n }\n return v;\n };\n const anim = animations.find((a) => a.name === raw.animation);\n if (anim === undefined) problems.push(`${where}: a slider's animation is ${JSON.stringify(raw.animation)}, not an animation of this document`);\n const byName = new Map(bones.map((b) => [b.name, b]));\n let bone: string | null = null;\n if (raw.bone !== undefined) {\n if (typeof raw.bone !== 'string' || !byName.has(raw.bone)) problems.push(`${where}: bone is ${JSON.stringify(raw.bone)}, not a bone of this document`);\n else bone = raw.bone;\n }\n let property: TransformProperty = 'rotate';\n if (raw.property !== undefined) {\n const p = TRANSFORM_PROPERTIES.find((x) => x === raw.property);\n if (p === undefined) problems.push(`${where}: property is ${JSON.stringify(raw.property)}, none of ${TRANSFORM_PROPERTIES.join(', ')}`);\n else property = p;\n }\n num('max', 0);\n const loop = flag('loop');\n const setup = new Map<string, ModelBone>();\n for (const target of anim?.timelines.bones ?? []) {\n const b = byName.get(target.name);\n if (b !== undefined) setup.set(b.name, b);\n }\n const record: CoreSliderRecord = {\n kind: 'slider', name, animation: anim?.name ?? '', timelines: anim?.timelines ?? { declared: 0, duration: 0, bones: [], slots: [], later: [], attachments: [], drawOrder: [], events: [] }, physics: [], setup,\n additive: flag('additive'), loop, mix: num('mix', 1), time: num('time', 0), bone, property,\n from: num('from', 0), to: num('to', 0), scale: num('scale', 1), local: flag('local'), skin: flag('skin'), listedBySkin: false,\n };\n return problems.length === before ? record : undefined;\n}\n\n/**\n * The slider timelines of one animation record's `constraints.slider`, read:\n * each names a declared slider, each of its timelines is `time` or `mix` and\n * appears once, its keys strictly increase in time and carry `time`, `value`\n * and `curve` only.\n */\nexport function readSliderTimelines(value: unknown, label: string, declared: ReadonlyArray<{ kind: string; name: string }>, problems: string[]): CoreSliderTimeline[] {\n const out: CoreSliderTimeline[] = [];\n if (!Array.isArray(value)) return out;\n value.forEach((entry, i) => {\n const at = `${label}.constraints.slider[${i}]`;\n if (!isRecord(entry) || typeof entry.name !== 'string') {\n problems.push(`${at} names no slider`);\n return;\n }\n if (!declared.some((c) => c.kind === 'slider' && c.name === entry.name)) problems.push(`${at}: \"${entry.name}\" is not a slider of this document`);\n const tl: CoreSliderTimeline = { name: entry.name, time: null, mix: null };\n if (!Array.isArray(entry.timelines)) {\n problems.push(`${at}: timelines is not a list`);\n return;\n }\n entry.timelines.forEach((raw: unknown, j: number) => {\n const tat = `${at}.timelines[${j}]`;\n if (!isRecord(raw) || (raw.name !== 'time' && raw.name !== 'mix')) {\n problems.push(`${tat}: ${JSON.stringify(isRecord(raw) ? raw.name : raw)} is not a slider timeline; a slider keys time and mix`);\n return;\n }\n const which = raw.name;\n if (tl[which] !== null) problems.push(`${tat}: \"${which}\" is keyed twice on slider \"${entry.name}\"`);\n tl[which] = readKeys(raw.keys, `${tat} \"${which}\"`, problems);\n });\n out.push(tl);\n });\n return out;\n}\n\nfunction readKeys(value: unknown, at: string, problems: string[]): CoreKey[] {\n const keys: CoreKey[] = [];\n if (!Array.isArray(value) || value.length === 0) {\n problems.push(`${at}: keys is not a non-empty list`);\n return keys;\n }\n let last = -Infinity;\n value.forEach((k: unknown, j: number) => {\n const kat = `${at}.keys[${j}]`;\n if (!isRecord(k)) {\n problems.push(`${kat} is not an object`);\n return;\n }\n for (const key of Object.keys(k)) if (key !== 'time' && key !== 'value' && key !== 'curve') problems.push(`${kat}: field \"${key}\" is not one this reader knows; it reads [time, value, curve]`);\n const time = k.time;\n if (typeof time !== 'number' || !Number.isFinite(time) || time < 0) {\n problems.push(`${kat}: time is ${JSON.stringify(time)}, not a finite time at or after 0`);\n return;\n }\n if (time <= last) problems.push(`${kat}: time ${time} is not after the key before it — the writer refuses key times that do not strictly increase`);\n last = Math.max(last, time);\n let v = 1;\n if (k.value !== undefined) {\n if (typeof k.value !== 'number' || !Number.isFinite(k.value)) problems.push(`${kat}: value is ${JSON.stringify(k.value)}, not a finite number`);\n else v = k.value;\n }\n let curve: CoreCurve = 'linear';\n if (k.curve !== undefined) {\n if (j === value.length - 1) problems.push(`${kat}: the last key carries a curve, which eases to no key — the writer refuses it`);\n else if (k.curve === 'stepped') curve = 'stepped';\n else if (Array.isArray(k.curve) && k.curve.length === 4 && k.curve.every((n) => typeof n === 'number' && Number.isFinite(n))) curve = k.curve as number[];\n else problems.push(`${kat}: curve is ${JSON.stringify(k.curve)}, not \"stepped\" nor 4 finite numbers`);\n }\n keys.push({ time: Math.fround(time), values: [Math.fround(v)], stated: { time, values: [v] }, curve });\n });\n return keys;\n}\n\n/** What evaluates one channel of a key and finds the key — construct 4's unless a plant passes others. */\nexport interface SliderTimelinePlant {\n channel?: (keys: readonly CoreKey[], index: number, channel: number, t: number) => number;\n search?: (keys: readonly CoreKey[], t: number) => number;\n}\n\n/** A slider record with its timelines' `time` and `mix` at `t` in place of its own (the header's *Its timelines*). */\nexport function posedSlider(r: CoreSliderRecord, timelines: readonly CoreSliderTimeline[], t: number, plant: SliderTimelinePlant = {}): CoreSliderRecord {\n const tl = timelines.find((x) => x.name === r.name);\n if (tl === undefined) return r;\n const search = plant.search ?? keyIndexAt;\n const channel = plant.channel ?? channelAt;\n // Through the setup blend at alpha 1, `own + (value − own)·1` (issue #991), as the ik, transform and path timelines are: the value as keyed read 351 of 500 of the issue's scratch population bit-exact under --raw, the blend 500 (CZ03).\n const at = (keys: CoreKey[] | null, own: number): number => {\n if (keys === null) return own;\n const i = search(keys, t);\n return i < 0 ? own : own + (channel(keys, i, 0, t) - own) * 1;\n };\n return { ...r, time: at(tl.time, r.time), mix: at(tl.mix, r.mix) };\n}\n\n/** The time a slider applies its animation at (the header's rule), before the animation's own loop wrap. */\nexport function sliderTime(state: SolverState, r: CoreSliderRecord): number {\n if (r.bone === null) return r.time;\n const value = sourceValue(state, { source: r.bone, localSource: r.local, offsets: ZERO_OFFSETS }, r.property);\n const time = r.to + (value - r.from) * r.scale;\n const d = r.timelines.duration;\n // Looping over a duration of 0 is NaN in the runtime, and it applied the keys: every key of such an animation sits at 0.\n if (r.loop && d === 0) return 0;\n return r.loop ? d + (time % d) : Math.max(0, time);\n}\n\nconst ZERO_OFFSETS: Record<TransformProperty, number> = { rotate: 0, x: 0, y: 0, scaleX: 0, scaleY: 0, shearY: 0 };\n\n/** The channels of a timeline at `t`, or `null` before its first key — when a slider writes nothing. */\nfunction valuesAt(keys: readonly CoreKey[], t: number): number[] | null {\n const i = keyIndexAt(keys, t);\n if (i < 0) return null;\n return keys[i].values.map((_v, c) => channelAt(keys, i, c, t));\n}\n\n/**\n * Apply one slider to the solver's bones (the header's composition rules):\n * its local values move, and the bones written are returned for the update\n * loop to pose again with everything below them. The application is pushed\n * onto `applied` for the slots.\n */\nexport function applySlider(state: SolverState, r: CoreSliderRecord, applied?: SliderApplication[], physics?: SliderPhysicsTarget): string[] {\n if (r.mix === 0) return [];\n const time = sliderTime(state, r);\n const d = r.timelines.duration;\n const at = r.loop && d !== 0 ? time % d : time;\n applied?.push({ name: r.name, timelines: r.timelines, at, alpha: r.mix, additive: r.additive, time });\n const alpha = r.mix;\n if (physics !== undefined && state.rules.sliderWritesPhysics) applySliderPhysics(r, at, alpha, physics);\n const changed: string[] = [];\n for (const target of r.timelines.bones) {\n const index = state.index.get(target.name);\n const setup = r.setup.get(target.name);\n if (index === undefined || setup === undefined) continue;\n const b = state.bones[index];\n let wrote = false;\n for (const tl of target.timelines) {\n if (tl.kind === 'inherit') {\n const i = keyIndexAt(tl.keys, at);\n if (i < 0) continue;\n b.inheritMode = tl.keys[i].mode;\n wrote = true;\n continue;\n }\n const v = valuesAt(tl.keys, at);\n if (v === null) continue;\n wrote = true;\n const add = (field: 'x' | 'y' | 'rotation' | 'shearX' | 'shearY', i: number): void => {\n const current = b[field] ?? 0;\n b[field] = r.additive ? current + v[i] * alpha : current + ((setup[field] ?? 0) + v[i] - current) * alpha;\n };\n const times = (field: 'scaleX' | 'scaleY', i: number): void => {\n const current = b[field] ?? 1;\n const s = setup[field] ?? 1;\n if (r.additive) {\n // #989: the key's product with the setup less the setup, then the mix — `(v − 1)·setup·mix` reads last-bit off (CZ02).\n b[field] = state.rules.sliderAdditiveScaleProduct ? current + (v[i] * s - s) * alpha : current + (v[i] - 1) * s * alpha;\n return;\n }\n const target = s * v[i];\n // #989: at mix exactly 1 the target itself — `from + (target − from)·1` reads last-bit off (CZ02).\n if (alpha === 1 && state.rules.sliderScaleMixOneIsTarget) {\n b[field] = target;\n return;\n }\n const from = Math.abs(current) * Math.sign(target);\n b[field] = from + (target - from) * alpha;\n };\n switch (tl.kind) {\n case 'rotate': add('rotation', 0); break;\n case 'translate': add('x', 0); add('y', 1); break;\n case 'translatex': add('x', 0); break;\n case 'translatey': add('y', 0); break;\n case 'shear': add('shearX', 0); add('shearY', 1); break;\n case 'shearx': add('shearX', 0); break;\n case 'sheary': add('shearY', 0); break;\n case 'scale': times('scaleX', 0); times('scaleY', 1); break;\n case 'scalex': times('scaleX', 0); break;\n case 'scaley': times('scaleY', 0); break;\n }\n }\n // #989: a bone the animation keys is posed again whether or not a timeline wrote it (the header's update order).\n if (wrote || (state.rules.sliderReposesKeyedBones && target.timelines.length > 0)) changed.push(target.name);\n }\n return changed;\n}\n\n/** The physics records a stepped pass carries, by name — what a slider's physics timelines write and a later physics constraint steps with (issue #1049, the header's *Its physics timelines*). */\nexport interface SliderPhysicsTarget {\n records: Map<string, CorePhysicsRecord>;\n /** Each record's setup values, before the step's own animation — what a planted blend from the setup reads. */\n setup: ReadonlyMap<string, CorePhysicsRecord>;\n active: (r: CorePhysicsRecord) => boolean;\n rules: Readonly<SolverRules>;\n ctx: PhysicsStepContext;\n /** What the sliders wrote this pass, by constraint and field — kept only under the planted reading that a write outlasts its pass. */\n written: Map<string, Partial<Record<PhysicsField, number>>>;\n}\n\n/** The fields of a physics record a timeline writes. */\ntype PhysicsField = 'inertia' | 'strength' | 'damping' | 'massInverse' | 'wind' | 'gravity' | 'mix';\n\n/**\n * The physics records of one stepped pass, ready for the sliders to write\n * (issue #1049): every physics record as the step's own animation posed it.\n * Under the planted reading that a slider's write outlasts its pass, what\n * the sliders wrote on the step before stands wherever the step's own\n * animation does not key it (`PhysicsStepContext.keyedNow`).\n */\nexport function sliderPhysicsTarget(records: readonly CoreConstraintRecord[], active: ReadonlySet<string>, ctx: PhysicsStepContext, rules: Readonly<SolverRules>): SliderPhysicsTarget {\n const posed = new Map(records.flatMap((r): Array<[string, CorePhysicsRecord]> => (r.kind === 'physics' ? [[r.name, r]] : [])));\n const out = new Map(posed);\n const written = new Map<string, Partial<Record<PhysicsField, number>>>();\n if (!rules.sliderPhysicsLastsOnePass) {\n for (const [name, fields] of ctx.carried ?? new Map<string, Partial<Record<PhysicsField, number>>>()) {\n const r = out.get(name);\n if (r === undefined) continue;\n const next = { ...r };\n const kept: Partial<Record<PhysicsField, number>> = {};\n for (const [f, v] of Object.entries(fields) as Array<[PhysicsField, number]>) {\n if (ctx.keyedNow?.has(`${name}/${f}`)) continue;\n next[f] = v;\n kept[f] = v;\n }\n out.set(name, next);\n written.set(name, kept);\n }\n ctx.carried = written;\n }\n return { records: out, setup: ctx.setupRecords ?? posed, active: (r) => physicsActive(r, active), rules, ctx, written };\n}\n\n/** The value kinds a slider's physics timeline adds under `additive` (`./additive.ts`'s table); the rest write. */\nconst PHYSICS_ADDS: ReadonlySet<string> = new Set(['wind', 'gravity']);\n\n/** A slider's physics timelines applied at `at` with alpha `alpha` onto the pass's physics records (the header's *Its physics timelines*). */\nfunction applySliderPhysics(r: CoreSliderRecord, at: number, alpha: number, target: SliderPhysicsTarget): void {\n const rules = target.rules;\n for (const tl of r.physics) {\n const named = target.records.get(tl.name);\n const targets = tl.name === EVERY_GLOBAL_PHYSICS ? unnamedPhysicsTargets([...target.records.values()], tl.kind, target.active) : named !== undefined && target.active(named) ? [named] : [];\n if (tl.kind === 'reset') {\n // A slider applies its animation at one time, from that time: no key is crossed, so a reset key fires nothing (PS159).\n if (!rules.sliderPhysicsResetIsDead && tl.keys.some((k) => k.time <= at)) for (const p of targets) resetPhysicsState(physicsState(target.ctx, p.name), target.ctx.time);\n continue;\n }\n const i = keyIndexAt(tl.keys, at);\n if (i < 0) continue;\n const v = channelAt(tl.keys, i, 0, at);\n const adds = r.additive && (PHYSICS_ADDS.has(tl.kind) || !rules.sliderPhysicsAddsWindGravityOnly);\n for (const p of targets) {\n const from = rules.sliderPhysicsFromCurrent ? p : (target.setup.get(p.name) as CorePhysicsRecord);\n const next = { ...p };\n let field: PhysicsField;\n if (tl.kind === 'mass') {\n field = 'massInverse';\n if (rules.sliderPhysicsBlendsMass) {\n const m = 1 / from.massInverse;\n next.massInverse = 1 / (adds ? 1 / p.massInverse + v * alpha : m + (v - m) * alpha);\n } else next.massInverse = adds ? p.massInverse + (1 / v) * alpha : from.massInverse + (1 / v - from.massInverse) * alpha;\n } else {\n field = tl.kind;\n next[field] = adds ? p[field] + v * alpha : from[field] + (v - from[field]) * alpha;\n }\n target.records.set(p.name, next);\n if (!rules.sliderPhysicsLastsOnePass) target.written.set(p.name, { ...target.written.get(p.name), [field]: next[field] });\n }\n }\n}\n\n/** A slot's pose as the sliders move it: what it shows, its light colour and its dark colour (`null` when it states none). */\nexport interface SlotPoseState {\n placeholder: string | null;\n light: number[];\n dark: number[] | null;\n}\n\nconst clamp01 = (v: number): number => (v < 0 ? 0 : v > 1 ? 1 : v);\n/** Each colour timeline's channels, as indices into `light` (0–3) and `dark` (4–6). */\nconst COLOUR_CHANNELS: Record<string, readonly number[]> = { rgba: [0, 1, 2, 3], rgb: [0, 1, 2], alpha: [3], rgba2: [0, 1, 2, 3, 4, 5, 6], rgb2: [0, 1, 2, 4, 5, 6] };\n\n/** Every slider application's slot timelines on one slot, in order (the header's slot rules). */\nexport function applySliderSlots(slot: string, pose: SlotPoseState, applications: readonly SliderApplication[]): void {\n for (const app of applications) {\n for (const target of app.timelines.slots) {\n if (target.name !== slot) continue;\n for (const tl of target.timelines) {\n if (tl.kind === 'attachment') {\n const i = keyIndexAt(tl.keys, app.at);\n if (i >= 0) pose.placeholder = tl.keys[i].name ?? null;\n continue;\n }\n const v = valuesAt(tl.keys, app.at);\n if (v === null) continue;\n COLOUR_CHANNELS[tl.kind].forEach((at, i) => {\n // #969: at mix 1 the key's value itself, not `current + (v − current)·1`, which is last-bit off it (measured, below).\n if (at < 4) pose.light[at] = app.alpha === 1 ? clamp01(v[i]) : clamp01(pose.light[at] + (v[i] - pose.light[at]) * app.alpha);\n else if (pose.dark !== null) pose.dark[at - 4] = app.alpha === 1 ? clamp01(v[i]) : clamp01(pose.dark[at - 4] + (v[i] - pose.dark[at - 4]) * app.alpha);\n });\n }\n }\n }\n}\n\n/**\n * Why the document's bones cannot be posed because of a slider, or null: a\n * slider whose animation keys a constraint timeline other than physics, or\n * deforms a curve a path constraint walks (the header's *What is left out*),\n * named with the animation and the kinds or the attachments.\n */\nexport function sliderBonesWhy(doc: CompiledDocument): string | null {\n const found: string[] = [];\n for (const c of doc.constraints) {\n if (c.kind !== 'slider') continue;\n const anim = doc.animations.find((a) => a.name === c.animation);\n if (anim === undefined) continue;\n const k = anim.constraints;\n const sliderTimelines = k.slider.reduce((n, s) => n + (s.time === null ? 0 : 1) + (s.mix === null ? 0 : 1), 0);\n const paths = k.path.reduce((n, p) => n + [p.position, p.spacing, p.mix].filter((x) => x !== undefined).length, 0);\n const kinds = [k.ik.length > 0 ? 'ik' : null, k.transform.length > 0 ? 'transform' : null, paths > 0 ? 'path' : null, sliderTimelines > 0 ? 'slider' : null].filter((x): x is string => x !== null);\n if (kinds.length > 0) found.push(`slider \"${c.name}\" applies animation \"${c.animation}\", which keys ${kinds.join(', ')} constraint timelines — a slider writing a later constraint's pose is not posed by this cut`);\n // A path constraint walks its slot's curve as the constraints before it left it; a slider's deform of that curve is not measured (issue #955).\n const walked = doc.constraints.flatMap((p) => (p.record?.kind === 'path' ? [p.record.slot] : []));\n const deformsPath = anim.timelines.attachments.filter((a) => a.deform !== null && walked.includes(a.slot) && doc.skins.find((s) => s.name === a.skin)?.attachments[a.slot]?.[a.attachment]?.geometry?.kind === 'path');\n if (deformsPath.length > 0) found.push(`slider \"${c.name}\" applies animation \"${c.animation}\", which deforms walked path attachment(s) ${deformsPath.map((a) => `\"${a.skin}/${a.slot}/${a.attachment}\"`).join(', ')} — a slider's deform of a curve a path constraint walks is not posed by this cut`);\n }\n return found.length === 0 ? null : found.join('; ');\n}\n","/**\n * Construct 5 of the core, first cut (issue #938, step 2e-i of issue #380):\n * the update order, and the two constraint kinds that move bones only by\n * what the bones and their target say — `ik` and `transform` — at the setup\n * pose and at a sample time, with their timelines. The second cut (issue\n * #938, step 2e-ii) adds `path`, whose record, walk and solver are\n * `./constraints_path.ts`'s; the third cut (2e-iii) adds `physics` under\n * `Physics.none` (`./constraints_physics.ts`: it applies nothing) and\n * `slider` (`./constraints_slider.ts`); the fourth (issue #956, 2e-iv)\n * steps physics when `applyConstraints` is given a step context — the\n * constraint then moves its bone in world space and the bones below it are\n * posed again, as after a world-space transform. Each is one more step of the update\n * loop below, so every constraint kind is posed; what the core still cannot\n * pose exactly leaves the bones out by name (`constraintsAbsentWhy`).\n *\n * Every rule below was measured by posing hand-written skeletons through\n * `tools/pose_oracle.ts dump` (spine-core 4.3.13, `--skin all`,\n * `--physics none`) and comparing the core's rows at tolerance 0, most of them\n * with \"amplifier\" bones — a child a million units out along each axis of the\n * bone under test — so that a difference of 1e-12 in a matrix reads as one\n * grid step (the `CC` controls hold the populations at ten thousand units:\n * at a million a skewed chain's amplifier reached 1.7e9, where a double no\n * longer resolves the grid). Nothing here was written from the runtime's\n * source. The public\n * documentation fixes the order the constraints run in (the editor's list,\n * top first) and the shape of each solver; every numeric choice beyond that —\n * which frame, which wrap, which constant — is the measurement stated next to\n * it. The core suite's `CC` controls hold the hand-written probes, and\n * `tools/core_gate.ts` holds the corpus.\n *\n * ## The update order\n *\n * **Constraints run in the document's order** — the model lists them as the\n * rig declares them and the Spine file carries that order, which is the\n * runtime's constraint list (the oracle's `constraints` roster). After each\n * one, every bone below a bone it changed is posed again from its local\n * values under its parent's new world transform, so a later constraint reads\n * the bones as the earlier ones left them. Measured: 500 random nine-bone\n * rigs, each with two to six ik and transform constraints in random order,\n * random targets and sources, reflecting, sheared, non-normal and softened —\n * every one IDENTICAL at tolerance 0 (`CC05`). Swapping two constraints that\n * touch one chain moves the pose (`CC10`).\n *\n * - A constraint whose mix for a property is 0 does not touch that property,\n * and one that touches nothing leaves the bone and everything under it\n * exactly as they were — not re-posed from its local values. A transform\n * constraint driving `y` alone whose `mixY` is absent (the pose's initial\n * 0) re-posed its bone's children from lossy local values in the first\n * reading and was 4e-6 off; skipping it made the probe exact.\n * - **A bone a transform constraint moved in world space keeps that world\n * transform**, and its local values are re-derived from it at once\n * (`localFromWorld`, below), so that when a later constraint moves one of\n * its ancestors it follows from those. Measured: a transform setting a\n * child's world rotation, then an ik turning its parent by 90°, turned the\n * child with the parent (the child's world rotation 180°); in the other\n * order, 90°.\n * - **A slider poses again every bone its animation keys**, a timeline\n * before its first key included (issue #989, `./constraints_slider.ts`,\n * *Where it stands*): on a bone a transform moved in world space that\n * rebuilds the world from the read-back local values, which the runtime\n * does and keeping the world did not (`CZ01`).\n * - A constraint with `skin: true` is applied exactly when an APPLIED skin's\n * list for its kind names it (`listedBySkin`, set per skin view by\n * `underSkin` in `./index.ts`): under `--skin all` any skin's, under\n * `--skin <name>` that skin's alone — the default skin's list does not\n * count there. Measured for all five kinds (issue #932, which carries card\n * #961's fix): a skin-required ik, transform, path, physics and slider\n * constraint on a probe where applying it moves a bone, dumped under\n * `--skin all`, `default` and `s1` against the same constraint at mix 0 —\n * named by no list: inert under all three; named by `s1`'s list: applied\n * under `all` and `s1`, inert under `default`; named by the default skin's\n * list: applied under `all` and `default`, inert under `s1` — the same\n * nine readings for every kind, 45 in all (the core suite's `CN02`). A name filed under another kind's list\n * is refused by the runtime's loader (`Couldn't find IK constraint k for\n * skin s1.`), and by `readModel`. The rule this replaced — `skin: true`\n * never applied (2e-i) — was measured only on unlisted constraints; issue\n * #956 corrected it for physics first. An ik whose target is inactive is\n * not applied (measured on an ik with its target skin-required and named by\n * no skin: the bone did not turn), nor a transform whose source is; an ik\n * and a transform are applied to every bone they name, inactive ones\n * included (*Unposed bones and collapsed frames*, below); a path constraint is applied exactly when its\n * slot's bone is active (`./constraints_path.ts`, *Which constraints run*).\n * - A path constraint moves its bones in world space, as a world-space\n * transform does, and reads the bones as the earlier constraints left\n * them — except its slot bone's world, which the offset's sign reads as\n * the runtime last set it: its update order is built before it poses, and\n * a weighted path does not ask for its slot bone (`slotBonePlan`,\n * *Which slot bone* there). This is the one place the order the runtime\n * builds is observable: ik and transform ask for every bone they read.\n *\n * ## Unposed bones and collapsed frames (issue #979)\n *\n * A bone the posed skin leaves unposed — inactive, or below an inactive bone\n * — holds the zero matrix, so a constraint over it works in a collapsed\n * frame. The grid compare never reads such a bone (the oracle's\n * ill-conditioned rule, and a document spells `-0` as `0`), so every rule here\n * was measured through `tools/pose_oracle.ts unposed`, which compares those\n * rows by `Object.is`, and on posed \"reader\" bones that carry a bone's local\n * values through a local transform constraint. The rules, planted back one at\n * a time by the core suite's `CC13` and `CC14` (`SolverRules`):\n *\n * - **An ik frame of determinant at most 0.00001 is collapsed** — exactly\n * 0.00001 collapses, the next double above does not, on a posed parent\n * (`CC14`). A one-bone ik then reads the target at the frame's origin (the\n * offset `(0, 0)`, so `atan2` is 0): the bone turns to 0 less its `shearX`,\n * plus 180 when it reflects, and `compress` scales it by `mix` toward 0.\n * A two-bone ik reads its grandparent's inverse as zero, so the target and\n * the child's origin are both the grandparent frame's origin. Before this\n * the core divided by the determinant and wrote NaN into every field.\n * - **A one-bone ik under a `noRotationOrReflection` parent floors the\n * parent x axis's squared length at 0.00001** when it builds the conformal\n * frame (`k = |det| / max(0.00001, a² + c²)`): solving for the floor on\n * five parents whose x axes are under it read 1.0000000166e-5 on each, and\n * with 0.00001 written 432 of 432 probes over three modes, eight parent x\n * scales, three y scales, three rotations and with or without\n * `compress`/`stretch` read exact, where no floor read 33 off. `./world.ts`'s frame for the same mode has no floor.\n * - **`localFromWorld` under a collapsed parent** reads x and y as the\n * division leaves them (NaN or infinite), `scaleX` 0, `shearY` 0, `scaleY`\n * the y column's length (NaN) and `rotation` 0: a local x column that is not\n * above 0.0001 — NaN included — is collapsed, and a y column no longer than\n * 0.00001 reads `rotation` 0 when the x column is collapsed too, and\n * `shearY` 0 when it is not (measured by bisection: 1e-5 reads 0, the next\n * double above reads the column's angle).\n * - **A world-space `rotate` source negates the constraint's `rotation`\n * unless its determinant is above 0**: a source of determinant 0 negates it.\n * - **An inactive bone is not posed again** when a constraint moves a bone\n * above it — it keeps its zeros, or what a constraint wrote into them — and\n * the bones below it are posed again only when a constraint moved it\n * itself (a path on an inactive bone moves the bones below it; a transform\n * on its parent does not).\n * - **A transform constraint is applied when its source is active, to every\n * bone it names**: one inactive bone among them did not stop it moving a\n * posed one (the core skipped the whole constraint), and it wrote the\n * source's position into the inactive one.\n *\n * Under these, transform (six flag sets, five modes), path, physics (under\n * `none` and the step) and one- and two-bone ik over unposed bones, and iks\n * aimed at them, read every bone row equal to spine-core's, the sign of every\n * zero included (`CC13`).\n *\n * ⚠️ **What the runtime writes into an INACTIVE constrained bone depends on\n * the pass before.** An ik naming an inactive bone is applied by the runtime\n * reading that bone's ancestors before it brings them up to date in the pass\n * — the previous pass's worlds, or zeros on a fresh skeleton — and a\n * transform or path writing into an inactive bone starts from the world the\n * previous pass left in it (the runtime does not reset it). Measured by\n * posing one skeleton sample after sample, as the oracle's dump does, against\n * a fresh skeleton per sample: an ik on `arm, hand` with `arm` inactive, a\n * transform onto an inactive bone at mix 0.5, additive or at mix 1, and a\n * path at mix 0.5 each read differently at 4 of 5 sample times (the mix-1\n * transform at 1 of 5, by 2.4e-17 in a `worldX` of 5.8e-7). The runtime\n * disagrees with itself there, so there is no rule of the format to hold, and\n * the core poses as a function of the model, the skin and the time: it reads\n * this class as a fresh skeleton does, which is the runtime's own setup pose.\n * A transform or path writes into an inactive bone from zeros; an ik naming\n * an inactive bone reads the frame above its first bone as zeros unless the\n * pass has brought that bone up to date before the ik (`frameUpdatedBefore`,\n * the order `slotBonePlan` walks), and as posed otherwise. Held against the\n * fresh reading on every row, and against the sequential one wherever the\n * two agree (`CC13`; `pose_oracle unposed` classes the rest HISTORY by\n * measurement). An ik on `arm, hand` with its target under `arm`'s parent, or\n * after a transform on that parent, read no history at all.\n *\n * The render never reads an unposed bone (the seam's zero snapshot), so the\n * history reaches a picture only through a POSED bone that a constraint moves\n * while reading a bone the history reached — and that pose is refused by\n * name (`unposedLeakWhy`), which the render meets by falling back to\n * spine-core. The taint is by bone and by what the reader reads, its world\n * or its local values: measured on 48 writer-and-reader probes (`CC15`),\n * every one whose posed rows spine-core's two readings disagree on (14) is\n * refused, and 8 are refused where the reader reads a part of the bone the\n * history does not move — a refusal costs a named fallback, a miss a picture\n * that depends on which frame played before.\n *\n * ## Reading local values back from a world transform (`localFromWorld`)\n *\n * The runtime's re-derived values were read directly: a second transform\n * constraint with `localSource` reading the bone's `rotate`, `x`, `y`,\n * `scaleX`, `scaleY`, `shearY` onto an unrelated bone's `x` at scale 10000\n * gave each to 1e-10, and they agree with these rules on every probe:\n *\n * - `normal`: the local matrix is the parent's inverse (1 over its\n * determinant, multiplied in) times the world matrix, and the local\n * position the same inverse applied to the world origin's offset. Then\n * `scaleX` is the x column's length and `shearX` is 0; ⚠️ **a local x\n * column shorter than 0.0001 is read as `scaleX` 0**, `shearY` 0, `scaleY`\n * the y column's length and `rotation` the y column's angle less 90 —\n * measured on a column collapsed to 1.8e-6 by two `scaleX` properties, where\n * the runtime read `rotation` −248.958 (the unwrapped y angle less 90) and\n * `scaleX` 0. Otherwise `rotation` is the x column's angle, `scaleY` the y\n * column's length — NEGATIVE when the determinant is — and `shearY` the y\n * column's angle less `rotation + 90`, or less `rotation − 90` when the\n * determinant is negative, brought once into (−180, 180]. The negative\n * `scaleY` and the right angle taken off the other way are what reproduce\n * the runtime's ±2.66e-6° residual on a reflected bone: 138 of 400\n * reflected and sheared probes missed with a positive `scaleY`; turning the\n * y angle by 180 first agrees to 1e-10 and not to the bit (below).\n * - `onlyTranslation`: the world matrix is the local matrix.\n * - `noRotationOrReflection`: the local matrix is taken against the parent's\n * conformal matrix (the frame `./world.ts` builds for that mode), and the\n * parent's x-axis angle is added to the rotation.\n * - `noScale`, `noScaleOrReflection`: `rotation` is the angle of the parent's\n * inverse applied to the world x column; the frame the forward pose builds\n * from that rotation (`noScaleDirection` in `./world.ts`) is formed, both\n * world columns are read in it (flipped when the parent reflects, for\n * `noScale`), and that local matrix is decomposed with its x column's\n * angle — a residual of rounding — kept as `shearX`, and `shearY` measured\n * from 0, as the forward frame `frame(0, shearX, shearY, …)` reads them.\n *\n * Each of the five held on 300 probes at the million-unit amplifier: a world\n * edit on the bone, then a translation-only edit on its parent that makes the\n * bone re-posed from its re-derived values (`CC06`).\n *\n * ## To the bit (issue #966)\n *\n * Held against `pose_oracle.ts dump --raw` at tolerance 0 (the core suite's\n * `CR01`, the `CC` populations and seeds; the corpus through `core_gate\n * --raw`), these orders are the runtime's where the grid could not tell:\n *\n * - a one-bone ik accumulates the change from the bone's own angles first,\n * `−shearX − rotation + turn + atan2·DEG` (the target's direction first\n * read 53 of 600 random iks off);\n * - a two-bone ik takes the child's offset angle off in radians before\n * turning the change into degrees, `(a1 − offset)·DEG` (`a1·DEG −\n * offset·DEG` read 44 bone findings on `spineboy-pro` against 4);\n * - an ik timeline's keyed mix and softness reach the pose through the\n * setup blend, `setup + (value − setup)·1` (the value as keyed read a\n * Bézier-eased mix 2 ulp off on `spineboy-pro`'s jump);\n * - a world-space rotate turns the change in radians, wrapped at the\n * runtime's pi (the degree form read 113 bone findings on `spineboy-pro`\n * against 44);\n * - `localFromWorld` forms the inverse's entries before applying them, and\n * reads the shear as `yAngle − (rotation + 90)`;\n * - and, in the second cut (the band `CW` controls; each rule planted back to\n * the reading before it by a `SolverRules` flag), the three read-back forms\n * above — a reflected bone's shear as the y angle less `rotation − 90`\n * (`CW01`); `noRotationOrReflection`'s columns as `(pa·wa + pc·wc)·(1/(pa² +\n * pc²))` and `(pa·wc − pc·wa)·(1/|det|)` (`CW02`); the `noScale` modes read\n * in the frame of the rotation read first, the residual kept as `shearX`\n * (`CW03`) — which bring the read-back population from 164 to 400 of 400,\n * the update-order population from 389 to 400 and the stepped physics\n * population (`CR07`) from 140 to 150 of 150; an additive world-space\n * `shearY` as `(v + 90)·RAD − 90·RAD` (`CW04`: the transform population\n * from 865 to 900 of 900); a transform timeline's mixes through the setup\n * blend (`CW05`); and the two-bone ik over a parent whose scale is 0, below;\n * - and a path timeline's position, spacing and mixes through the setup blend\n * too (issue #984, `CY01`; *The timelines*, below), and a slider\n * timeline's `time` and `mix` (issue #991, `CZ03`).\n *\n * The local values were read to the bit rather than through the re-posed\n * world: a reader bone's `x` driven by a local transform from the bone's\n * `rotate`, `x`, `y`, `scaleX`, `scaleY` or `shearY` at scale 1 under the\n * root is the value itself in the raw dump. That separated a wrong local\n * value from a right one the forward pose reads differently — the `noScale`\n * modes' local values read bit-exact before their world did, which is how\n * the kept `shearX` was found.\n *\n * ## ik — one bone\n *\n * The bone turns so its x axis points at the target. With `v` the target in\n * the bone's parent frame:\n *\n * - `normal`, `noScale`, `noScaleOrReflection`: the parent's world matrix,\n * inverted by dividing by its determinant, applied to the target's offset\n * from the PARENT's world origin, less the bone's local `x`, `y`.\n * `onlyTranslation`: the target's offset from the bone's own world origin,\n * as it is. `noRotationOrReflection`: as `normal`, with the parent's\n * conformal matrix (x axis kept, y axis at 90° with length |det| / |x|) for\n * its matrix, and the parent's x-axis angle added to the angle. Each other\n * reading of that mode missed 14 to 200 of 300 probes; the offset from the\n * bone's own origin, for `normal`, is the same number up to rounding and\n * was exact on every random probe — ⚠️ but a target AT the bone's origin\n * has only rounding noise for a direction, and the runtime turned such a\n * bone to 56.56° where that reading read 30° (0.3345 off in `b`); the\n * parent-origin reading reproduces the noise exactly (`CC04`).\n * - The rotation it needs is `atan2(v)` less `shearX` less the current\n * rotation, plus 180 when `scaleX` is negative, brought once into\n * (−180, 180], times `mix`, added to the rotation.\n * - `compress` / `stretch`: with `len` the bone's `length` times `scaleX` and\n * `d` the length of `v` — of the world offset for the two `noScale` modes —\n * when `len` is above 0.00001 (issue #966, by bisection: 0.00001 exactly is\n * left alone and the double above is scaled; 0.0001, the reading before,\n * left every bone between the two unscaled) and the target is nearer (`compress`) or\n * farther (`stretch`), `scaleX` is multiplied by `(d / len − 1) · mix + 1`.\n * With `scaleY` `uniform` `scaleY` is multiplied by the same `s`; with\n * `volume` it is divided by `s`, except below 0.7 where it is divided by\n * `0.25 + s · 0.642857`. That constant is measured: a bone of `scaleY`\n * 100000 compressed to seven lengths read `(1/scaleY − 0.25) / s` =\n * 0.642857000 to nine places on every one, and the break is between 0.6999\n * and 0.7001.\n * - `mix` 0 leaves the bone alone.\n *\n * Measured: 1,000 random probes each over rotated, scaled, reflecting and\n * sheared parents and bones, all five inherit modes, `compress`, `stretch`,\n * the three `scaleY` modes and random `mix`, all exact (`CC02`).\n *\n * ## ik — two bones\n *\n * The public documentation: the second bone must be a child of the first;\n * the child's tip reaches the target; `bendPositive` picks the side;\n * `softness` slows the chain as it straightens; `stretch` scales it to reach.\n * Measured, in the parent's parent frame (the \"grandparent\", its world\n * matrix inverted by multiplying by 1 over its determinant):\n *\n * - **Either bone not `normal`: the constraint does nothing** (all four\n * other modes on each bone, 200 probes each).\n * - The parent keeps its shear. ⚠️ The public page says the parent's local\n * shear is set to 0; spine-core 4.3.13 keeps it (100 sheared probes: 100\n * off with the shear zeroed, 0 kept).\n * - **Uniform** when the parent's |scaleX| and |scaleY| differ by at most\n * 0.00001 — measured between 9.9e-6 (uniform) and 1.01e-5 (not), at scales\n * 0.5, 1 and 2. The public page's \"nonuniform\" was read as 0.0001 at first,\n * and a world-edited parent at 1.00005 went 2,261,052 units off at the\n * amplifier.\n * - The child's local `y` is set to 0 when the scale is not uniform or\n * `stretch` is on; otherwise it is kept, and it offsets the angles by\n * `atan2(y, x)` of the child's local position — unscaled.\n * - `l1` is the distance, in the grandparent frame, from the parent's local\n * origin to the child's world origin (that is, the parent's world matrix\n * applied to the child's local `x`, `y`); `l2` is the child's `length`\n * times |its scaleX|; the target is read in the same frame.\n * - **softness**: `s` = `softness` · |parent scaleX| · (|child scaleX| + 1) ·\n * 0.5; with `d` the target's distance and `sd = d − l1 − l2·|scaleX| + s`,\n * when `sd > 0` the target is drawn in toward the parent by\n * `(sd − s·(1 − q²)) / d` of itself, `q = min(1, sd / 2s) − 1`: the chain\n * reaches `d − sd²/4s` until `sd` is `2s`, and full length after. Measured\n * on a straight chain at eleven distances and two softnesses, then at the\n * amplifier: the fully softened chain is ill-conditioned (its bend is the\n * arc-cosine of 1 − a few ulp), and only this arithmetic, with the\n * subtraction in this order and the square root (not `hypot`) for `l1`,\n * read it exactly — 132, 102, 59 and 10 of 1,000 missed on the way.\n * - **Uniform**: the law of cosines, `cos = (d² − l1² − l2²) / (2·l1·l2)`\n * with `l2` scaled by |scaleX|; below −1 the bend is π·bend, above 1 it is\n * 0 and `stretch` multiplies the parent's `scaleX` (and `scaleY` for\n * `uniform`, divides it for `volume`) by `(d/(l1+l2) − 1)·mix + 1`. The\n * parent's angle is one `atan2` of the target turned back by the bend's\n * offset — the difference of two `atan2`s is off by 2π about 1 time in 30,\n * and 2π in the runtime's degrees is not 2π.\n * - **Not uniform**: the child's tip at `(X, Y)` in the parent's scaled frame\n * solves `(b² − a²)X² − 2b²·l1·X + b²·l1² + a²·d² − a²b² = 0`\n * (`a`, `b` = `l2` times |scaleX|, |scaleY|), solved the numerically stable\n * way and taking the root of smaller magnitude; when it has none, the\n * nearest reachable pose of the three candidates — folded, straight and the\n * ellipse's vertex — on the side of the midpoint of their squared reaches\n * the target is. The folded bend is π in the runtime's own π (3.1415927);\n * the parent's angle is here the DIFFERENCE of two `atan2`s.\n * - The parent's rotation is the angle less the offset, plus 180 when its\n * `scaleX` is negative, and the child's is `(bend + offset)·deg − shearX`,\n * times the product of the parent's scale signs, plus 180 when the child's\n * `scaleX` is negative. Each change is brought once into (−180, 180] —\n * **−180 goes to 180**: a folded chain under a reflecting parent read the\n * same child angle for both bends, measured at `mix` 0.5 — and multiplied\n * by `mix`.\n *\n * Measured: 2,000 random probes per combination — grandparents rotated,\n * scaled, reflecting and sheared; parents uniform, reflecting and not\n * uniform; children offset in `y`, scaled, reflecting and sheared; `stretch`,\n * `softness`, the `scaleY` modes, both bends, random `mix` — exact at the\n * amplifier (`CC03`). Degenerate cases (`CC04`): the child at the parent's\n * origin, the target at the parent's origin, the chain exactly straight,\n * exactly folded, the softness onset and its end, a child of length 0 — all\n * exact. The runtime throws on an ik whose (first) bone is the root, so the\n * reader refuses it. A collapsed grandparent (determinant 0) is left to the\n * oracle's ill-conditioned rule, which excludes the bone and everything below\n * it — the one case where the core's value is not the runtime's.\n *\n * **A parent whose scale is 0** (issue #966, reducing #959's third class, \"a\n * transform collapsing a bone's scale, with an ik below it\", to a two-bone ik\n * with no transform at all; `CW06`–`CW08`, compared by `Object.is` on every\n * bone, the ones compare's ill-conditioned rule leaves out included):\n *\n * - a scale of 0 counts as POSITIVE in the product of the parent's scale\n * signs that turns the child's offset and angle — `Math.sign` read it as 0\n * and read 59 of 300 iks over a parent of `scaleY` 0 exact;\n * - **a child whose origin is nearer the parent's than 0.00001** in the\n * grandparent frame (`l1`) makes the constraint a one-bone ik on the parent\n * — stretched as the constraint says, never compressed, its `scaleY` mode\n * read as none — with the child posed at rotation 0 and the local `y` the\n * solver set. A parent `scaleX` of 0 puts every child there (2 of 300\n * exact before). By bisection on the parent's x scale at three child\n * offsets and three rotations the edge is the distance, not the scale:\n * 0.00001 exactly solves and the double below folds (`CW07`). The child at\n * the parent's origin (`CC04`) is the same fold.\n *\n * ## transform\n *\n * 4.3's form: `properties` maps each source property (`rotate`, `x`, `y`,\n * `scaleX`, `scaleY`, `shearY`) with its `offset` to one or more target\n * properties, each with `offset`, `scale` and `max`. For each constrained\n * bone, each source property in the document's order, each target property:\n *\n * - **The source's value.** World (`localSource` false): `rotate` is the x\n * column's angle, plus the constraint's `rotation` — negated when the source\n * reflects — and then brought into [0, 360) by adding 360 once when below 0\n * (a scale of 0.5 read 95 for a source at −170); `x`, `y` are the source's\n * world transform applied to the constraint's `x`, `y`; `scaleX`, `scaleY`\n * the column lengths plus the constraint's offsets; `shearY` the angle\n * between the columns less 90, plus `shearY`. Local: the source's local\n * value (as constraints so far left it) plus the offset, unwrapped.\n * - Less the source property's `offset`, times the target property's `scale`\n * (absent 1), plus its `offset` (absent 0); with `clamp`, held between its\n * `offset` and its `max` whichever is larger — `max` absent reads 1 (a\n * clamped 30 read 1).\n * - **The mix** of the target property: `mixRotate`, `mixX`, `mixScaleX`,\n * `mixShearY` absent read 1 for a driven property; `mixY` absent reads the\n * resolved `mixX` when `x` is driven and 0 when it is not, `mixScaleY` the\n * same over `scaleX` (the parser's reading, `src/keyorder.ts`'s note on the\n * transform constraint, measured again here). A mix of 0 applies nothing.\n * - **World** (`localTarget` false): `rotate` turns both columns by the\n * change to the value (or by the value, `additive`) brought once into\n * (−180, 180] and times the mix; `x`, `y` move the world origin; `scaleX`,\n * `scaleY` scale a column to the value (or by it, additive: `1 + (v−1)·mix`);\n * `shearY` turns the y column to `v + 90` degrees from the x column, the\n * change brought once into (−π, π] with the RUNTIME's π (78 of 300 missed\n * with Math.PI), keeping its length — additive, it turns the y column by\n * `((v + 90)·RAD − 90·RAD)·mix`, unwrapped (issue #966, `CW04`: `v·RAD`\n * agrees on the grid and read 35 of 132 probes last-bit off). **Local**: the local field moves\n * toward the value by the mix (additive: adds `v·mix`, or scales by\n * `1 + (v−1)·mix`).\n *\n * Measured: 800 probes per property in world mode over reflecting, sheared,\n * offset, scaled and clamped sources and targets; 300 per property and mode\n * pair for local, additive and both; 1,000 with random cross-mappings (a\n * property to several, several to one); the six identity mappings in both\n * key orders — all exact, amplified (`CC07`). Every one on bones of all five\n * inherit modes.\n *\n * ## The timelines\n *\n * An `ik` timeline keys `mix` and `softness` (two curve channels) and\n * `bendPositive`, `compress`, `stretch` (stepped: the flags of the last key\n * at or before `t`); a `transform` timeline keys the six mixes (six\n * channels). The key search and the curves are construct 4's\n * (`keyIndexAt`, `channelAt` in `./animation.ts`), key times and values\n * float32, a Bézier from the stated numbers. Before the first key the\n * constraint's own values; a key omitting a field reads the parser's value\n * for it — `mix` 1, `softness` 0, `bendPositive` true, `compress` and\n * `stretch` false; a transform key's mixes 1, `mixY` the key's `mixX`\n * (`src/keyorder.ts`, `PARSER_DEFAULTS`). `CC08` holds each. The keyed values\n * reach the pose through the setup blend at alpha 1, `setup + (value −\n * setup)·1`, for both kinds (issue #966: the ik's mix on the corpus, the\n * transform's six mixes on `CW05`'s probe, where the value as keyed read 0\n * of 60 exact).\n *\n * A `path` timeline's values — `position`, `spacing` and the three mixes\n * (`./constraints_path.ts`, *The record and its timelines*) — reach the pose\n * through the same setup blend (issue #984). The reading before was the\n * value as keyed; the corpus could not tell them apart, since its one row\n * keying a path timeline keys `position` over a setup position of 0, where\n * `0 + (value − 0)·1` is the value to the bit. Measured on `CY01`'s probes —\n * 60 per timeline, keyed by Bézier segments over setup values that include 0\n * and negatives, in every position, spacing and rotate mode, one to three\n * bones, under `--raw` at 40 irrational samples, tolerance 0 — the value as\n * keyed read position 33, spacing 40 and mix 1 of 60 bit-exact (0 of 60 with\n * all three keyed), the blend 60 of 60 on each; each mix channel alone\n * planted back to the value as keyed turns the mix population red.\n *\n * A `slider` timeline's `time` and `mix` go through the same setup blend\n * (issue #991, `CZ03`; `./constraints_slider.ts`, *Its timelines*).\n *\n * ## Purity\n *\n * As the rest of the core: nothing from the Spine runtime package, nothing\n * from `src/transform.ts`, no clock, no randomness, no I/O.\n */\nimport type { ModelBone } from '../model.ts';\nimport { modeMatrix, noScaleDirection, RUNTIME_PI, worldTransforms, type CoreInheritMode, type CoreWorld } from './world.ts';\nimport { channelAt, keyIndexAt, type CoreCurve, type CoreKey } from './animation.ts';\nimport { activeBones, type CompiledDocument, type CoreConstraintKind } from './index.ts';\nimport { fillingSkins } from './skins.ts';\nimport { readPathTimelines, slotBonePlan, solvePath, type CorePathRecord, type CorePathTimelines, type SlotBoneEvent } from './constraints_path.ts';\nimport { physicsTimelineCount, readPhysicsTimelines, stepPhysics, type CorePhysicsRecord, type CorePhysicsTimeline, type PhysicsStepContext } from './constraints_physics.ts';\nimport { applySlider, posedSlider, sliderPhysicsTarget, readSliderTimelines, sliderBonesWhy, type CoreSliderRecord, type CoreSliderTimeline, type SliderApplication } from './constraints_slider.ts';\n\nconst DEG = 180 / RUNTIME_PI;\nconst RAD = RUNTIME_PI / 180;\n\n/** The kinds this cut poses. */\nexport const ADMITTED_CONSTRAINT_KINDS: readonly CoreConstraintKind[] = ['ik', 'transform', 'path', 'physics', 'slider'];\n\n/** A transform constraint's six properties, in the order its timeline's channels run. */\nexport const TRANSFORM_PROPERTIES = ['rotate', 'x', 'y', 'scaleX', 'scaleY', 'shearY'] as const;\nexport type TransformProperty = (typeof TRANSFORM_PROPERTIES)[number];\n/** The mix field of each property, in the same order. */\nexport const TRANSFORM_MIXES: Record<TransformProperty, string> = { rotate: 'mixRotate', x: 'mixX', y: 'mixY', scaleX: 'mixScaleX', scaleY: 'mixScaleY', shearY: 'mixShearY' };\n/** The constraint's offset field of each property. */\nconst TRANSFORM_OFFSETS: Record<TransformProperty, string> = { rotate: 'rotation', x: 'x', y: 'y', scaleX: 'scaleX', scaleY: 'scaleY', shearY: 'shearY' };\n/** The three `scaleY` modes an ik constraint names. */\nexport const IK_SCALE_Y_MODES = ['none', 'uniform', 'volume'] as const;\nexport type IkScaleYMode = (typeof IK_SCALE_Y_MODES)[number];\n\n/** The fields each admitted kind's record may carry after `kind`, `name`, `declaredIn` (`buildRigConstraint` in `src/compile.ts`). */\nexport const CONSTRAINT_FIELDS: Record<'ik' | 'transform', readonly string[]> = {\n ik: ['bones', 'target', 'scaleY', 'mix', 'softness', 'bendPositive', 'compress', 'stretch', 'skin'],\n transform: ['bones', 'source', 'properties', 'localSource', 'localTarget', 'additive', 'clamp', 'rotation', 'x', 'y', 'scaleX', 'scaleY', 'shearY', 'mixRotate', 'mixX', 'mixY', 'mixScaleX', 'mixScaleY', 'mixShearY', 'skin'],\n};\n\n/** The values an ik constraint's timeline keys, and a pose of them. */\nexport interface IkPose {\n mix: number;\n softness: number;\n bendPositive: boolean;\n compress: boolean;\n stretch: boolean;\n}\n\nexport interface CoreIkRecord extends IkPose {\n kind: 'ik';\n name: string;\n bones: string[];\n target: string;\n scaleY: IkScaleYMode;\n skin: boolean;\n /** An applied skin's `ik` list names it — what applies a skin-required one (the header's rule); set per skin view by `underSkin` in `./index.ts`. */\n listedBySkin: boolean;\n}\n\nexport interface CoreTransformTo {\n property: TransformProperty;\n offset: number;\n scale: number;\n max: number;\n}\n\nexport interface CoreTransformFrom {\n property: TransformProperty;\n offset: number;\n to: CoreTransformTo[];\n}\n\nexport interface CoreTransformRecord {\n kind: 'transform';\n name: string;\n bones: string[];\n source: string;\n properties: CoreTransformFrom[];\n localSource: boolean;\n localTarget: boolean;\n additive: boolean;\n clamp: boolean;\n /** The constraint's offsets: `rotation`, `x`, `y`, `scaleX`, `scaleY`, `shearY`, by the property they offset. */\n offsets: Record<TransformProperty, number>;\n /** The resolved mixes, by property — the header's reading of an absent one. */\n mixes: Record<TransformProperty, number>;\n skin: boolean;\n /** An applied skin's `transform` list names it (the header's rule); set per skin view by `underSkin` in `./index.ts`. */\n listedBySkin: boolean;\n}\n\nexport type CoreConstraintRecord = CoreIkRecord | CoreTransformRecord | CorePathRecord | CorePhysicsRecord | CoreSliderRecord;\n\nconst isRecord = (v: unknown): v is Record<string, unknown> => typeof v === 'object' && v !== null && !Array.isArray(v);\n\nfunction unknownFields(record: Record<string, unknown>, known: readonly string[], where: string, problems: string[]): void {\n for (const key of Object.keys(record)) if (!known.includes(key)) problems.push(`${where}: field \"${key}\" is not one this reader knows; it reads [${known.join(', ')}]`);\n}\n\nfunction num(raw: Record<string, unknown>, key: string, dflt: number, where: string, problems: string[]): number {\n const v = raw[key];\n if (v === undefined) return dflt;\n if (typeof v !== 'number' || !Number.isFinite(v)) {\n problems.push(`${where}: ${key} is ${JSON.stringify(v)}, not a finite number`);\n return dflt;\n }\n return v;\n}\n\nfunction flag(raw: Record<string, unknown>, key: string, dflt: boolean, where: string, problems: string[]): boolean {\n const v = raw[key];\n if (v === undefined) return dflt;\n if (typeof v !== 'boolean') {\n problems.push(`${where}: ${key} is ${JSON.stringify(v)}, not a boolean`);\n return dflt;\n }\n return v;\n}\n\nfunction boneList(raw: Record<string, unknown>, bones: ReadonlySet<string>, where: string, problems: string[]): string[] {\n if (!Array.isArray(raw.bones) || raw.bones.length === 0) {\n problems.push(`${where}: bones is ${JSON.stringify(raw.bones)}, not a non-empty list of bone names`);\n return [];\n }\n const out: string[] = [];\n raw.bones.forEach((b, i) => {\n if (typeof b !== 'string' || !bones.has(b)) problems.push(`${where}: bones[${i}] ${JSON.stringify(b)} is not a bone of this document`);\n else out.push(b);\n });\n return out;\n}\n\nfunction boneRef(raw: Record<string, unknown>, key: string, bones: ReadonlySet<string>, where: string, problems: string[]): string {\n const v = raw[key];\n if (typeof v !== 'string' || !bones.has(v)) {\n problems.push(`${where}: ${key} is ${JSON.stringify(v)}, not a bone of this document`);\n return '';\n }\n return v;\n}\n\n/** The mix of `property` as the header reads an absent one. */\nfunction resolvedMix(raw: Record<string, unknown>, property: TransformProperty, driven: ReadonlySet<TransformProperty>, where: string, problems: string[]): number {\n const stated = raw[TRANSFORM_MIXES[property]];\n if (stated !== undefined) return num(raw, TRANSFORM_MIXES[property], 0, where, problems);\n if (property === 'y') return driven.has('x') ? resolvedMix(raw, 'x', driven, where, problems) : 0;\n if (property === 'scaleY') return driven.has('scaleX') ? resolvedMix(raw, 'scaleX', driven, where, problems) : 0;\n return driven.has(property) ? 1 : 0;\n}\n\n/**\n * An ik or transform constraint's record, read field by field — every field\n * the writer can write for its kind and no other, each of its type, every\n * bone named a bone of the document — or `undefined` with the problems named.\n * `bones` is the document's bone names; `parents` each bone's parent, for the\n * two refusals the runtime would otherwise throw on while posing.\n */\nexport function readConstraintRecord(raw: Record<string, unknown>, kind: 'ik' | 'transform', name: string, where: string, bones: ReadonlySet<string>, parents: ReadonlyMap<string, string | undefined>, problems: string[]): CoreConstraintRecord | undefined {\n const before = problems.length;\n const rest: Record<string, unknown> = { ...raw };\n delete rest.kind;\n delete rest.name;\n delete rest.declaredIn;\n unknownFields(rest, CONSTRAINT_FIELDS[kind], where, problems);\n const list = boneList(raw, bones, where, problems);\n const skin = flag(raw, 'skin', false, where, problems);\n if (kind === 'ik') {\n const target = boneRef(raw, 'target', bones, where, problems);\n if (list.length > 2) problems.push(`${where}: an ik constraint names ${list.length} bones; the format takes one or two`);\n if (list.length >= 1 && parents.get(list[0]) === undefined) problems.push(`${where}: its first bone \"${list[0]}\" is the root; spine-core throws posing an ik constraint on a bone with no parent`);\n if (list.length === 2 && parents.get(list[1]) !== list[0]) problems.push(`${where}: \"${list[1]}\" is not a child of \"${list[0]}\"; a two-bone ik needs the second bone directly under the first`);\n let scaleY: IkScaleYMode = 'none';\n if (raw.scaleY !== undefined) {\n const folded = typeof raw.scaleY === 'string' && raw.scaleY.length > 0 ? raw.scaleY[0].toLowerCase() + raw.scaleY.slice(1) : '';\n const mode = IK_SCALE_Y_MODES.find((m) => m === folded);\n if (mode === undefined) problems.push(`${where}: scaleY is ${JSON.stringify(raw.scaleY)}, none of ${IK_SCALE_Y_MODES.join(', ')}`);\n else scaleY = mode;\n }\n const record: CoreIkRecord = {\n kind, name, bones: list, target, scaleY, skin, listedBySkin: false,\n mix: num(raw, 'mix', 1, where, problems),\n softness: num(raw, 'softness', 0, where, problems),\n bendPositive: flag(raw, 'bendPositive', true, where, problems),\n compress: flag(raw, 'compress', false, where, problems),\n stretch: flag(raw, 'stretch', false, where, problems),\n };\n return problems.length === before ? record : undefined;\n }\n const source = boneRef(raw, 'source', bones, where, problems);\n const properties: CoreTransformFrom[] = [];\n const driven = new Set<TransformProperty>();\n if (raw.properties !== undefined && !isRecord(raw.properties)) problems.push(`${where}: properties is not an object`);\n else if (isRecord(raw.properties)) {\n for (const [fromName, fromRaw] of Object.entries(raw.properties)) {\n const at = `${where}.properties.${fromName}`;\n const from = TRANSFORM_PROPERTIES.find((p) => p === fromName);\n if (from === undefined) {\n problems.push(`${at}: \"${fromName}\" is none of ${TRANSFORM_PROPERTIES.join(', ')}`);\n continue;\n }\n if (!isRecord(fromRaw)) {\n problems.push(`${at} is not an object`);\n continue;\n }\n unknownFields(fromRaw, ['offset', 'to'], at, problems);\n const to: CoreTransformTo[] = [];\n if (!isRecord(fromRaw.to)) problems.push(`${at}: to is not an object`);\n else {\n for (const [toName, toRaw] of Object.entries(fromRaw.to)) {\n const at2 = `${at}.to.${toName}`;\n const property = TRANSFORM_PROPERTIES.find((p) => p === toName);\n if (property === undefined) {\n problems.push(`${at2}: \"${toName}\" is none of ${TRANSFORM_PROPERTIES.join(', ')}`);\n continue;\n }\n if (!isRecord(toRaw)) {\n problems.push(`${at2} is not an object`);\n continue;\n }\n unknownFields(toRaw, ['offset', 'scale', 'max'], at2, problems);\n to.push({ property, offset: num(toRaw, 'offset', 0, at2, problems), scale: num(toRaw, 'scale', 1, at2, problems), max: num(toRaw, 'max', 1, at2, problems) });\n driven.add(property);\n }\n }\n properties.push({ property: from, offset: num(fromRaw, 'offset', 0, at, problems), to });\n }\n }\n const offsets = {} as Record<TransformProperty, number>;\n const mixes = {} as Record<TransformProperty, number>;\n for (const p of TRANSFORM_PROPERTIES) {\n offsets[p] = num(raw, TRANSFORM_OFFSETS[p], 0, where, problems);\n mixes[p] = resolvedMix(raw, p, driven, where, problems);\n }\n const record: CoreTransformRecord = {\n kind, name, bones: list, source, properties, skin, listedBySkin: false, offsets, mixes,\n localSource: flag(raw, 'localSource', false, where, problems),\n localTarget: flag(raw, 'localTarget', false, where, problems),\n additive: flag(raw, 'additive', false, where, problems),\n clamp: flag(raw, 'clamp', false, where, problems),\n };\n return problems.length === before ? record : undefined;\n}\n\n// ---------------------------------------------------------------------------\n// timelines\n// ---------------------------------------------------------------------------\n\n/** An ik key: `mix`, `softness` as channels, the three flags as the key states them or the parser reads them. */\nexport interface CoreIkKey extends CoreKey {\n flags: { bendPositive: boolean; compress: boolean; stretch: boolean };\n}\n\n/** One animation's ik, transform and path timelines, by constraint name, in the animation's order. */\nexport interface CoreConstraintTimelines {\n ik: Array<{ name: string; keys: CoreIkKey[] }>;\n transform: Array<{ name: string; keys: CoreKey[] }>;\n /** The path constraints' timelines (`./constraints_path.ts`). */\n path: CorePathTimelines[];\n /** How many physics timelines the animation holds — they pose nothing under `Physics.none` (`./constraints_physics.ts`). */\n physics: number;\n /** The physics timelines themselves, in the animation's order — what the stepped phase poses (`./constraints_physics.ts`). */\n physicsKeyed?: CorePhysicsTimeline[];\n /** The slider timelines (`./constraints_slider.ts`). */\n slider: CoreSliderTimeline[];\n}\n\n/** The ik key's curve channels, and the transform key's, in the order a curve indexes them. */\nexport const IK_KEY_CHANNELS = ['mix', 'softness'] as const;\nexport const TRANSFORM_KEY_CHANNELS = ['mixRotate', 'mixX', 'mixY', 'mixScaleX', 'mixScaleY', 'mixShearY'] as const;\n\nfunction keyCurve(raw: Record<string, unknown>, channels: number, last: boolean, at: string, problems: string[]): CoreCurve {\n const curve = raw.curve;\n if (curve === undefined) return 'linear';\n if (last) {\n problems.push(`${at}: the last key carries a curve, which eases to no key — the writer refuses it`);\n return 'linear';\n }\n if (curve === 'stepped') return 'stepped';\n if (!Array.isArray(curve) || curve.length !== channels * 4 || !curve.every((n) => typeof n === 'number' && Number.isFinite(n))) {\n problems.push(`${at}: curve is ${JSON.stringify(curve)}, not \"stepped\" nor ${channels * 4} finite numbers (four per channel)`);\n return 'linear';\n }\n return curve as number[];\n}\n\n/**\n * The ik, transform and path timelines of one animation record's\n * `constraints`, read: each names a declared constraint of its kind, its\n * keys strictly increase in time, each key carries only the fields the\n * parser reads for its kind (the path's, `readPathTimelines` in\n * `./constraints_path.ts`); the physics timelines are counted (they pose\n * nothing under `Physics.none`) and the slider timelines read by\n * `./constraints_slider.ts`.\n */\nexport function readConstraintTimelines(value: unknown, label: string, declared: ReadonlyArray<{ kind: CoreConstraintKind; name: string }>, problems: string[]): CoreConstraintTimelines {\n const out: CoreConstraintTimelines = { ik: [], transform: [], path: [], physics: 0, slider: [] };\n if (!isRecord(value)) return out;\n out.path = readPathTimelines(value.path, label, new Set(declared.filter((c) => c.kind === 'path').map((c) => c.name)), problems);\n out.physics = physicsTimelineCount(value.physics);\n out.physicsKeyed = readPhysicsTimelines(value.physics, label, new Set(declared.filter((c) => c.kind === 'physics').map((c) => c.name)), problems);\n out.slider = readSliderTimelines(value.slider, label, declared, problems);\n for (const kind of ['ik', 'transform'] as const) {\n const list = value[kind];\n if (!Array.isArray(list)) continue;\n list.forEach((entry, i) => {\n const at = `${label}.constraints.${kind}[${i}]`;\n if (!isRecord(entry) || typeof entry.name !== 'string') {\n problems.push(`${at} names no constraint`);\n return;\n }\n if (!declared.some((c) => c.kind === kind && c.name === entry.name)) problems.push(`${at}: \"${entry.name}\" is not a ${kind} constraint of this document`);\n const rawKeys: unknown = entry.keys;\n if (!Array.isArray(rawKeys) || rawKeys.length === 0) {\n problems.push(`${at}: keys is not a non-empty list`);\n return;\n }\n const channels: readonly string[] = kind === 'ik' ? IK_KEY_CHANNELS : TRANSFORM_KEY_CHANNELS;\n const known = kind === 'ik' ? ['time', ...IK_KEY_CHANNELS, 'bendPositive', 'compress', 'stretch', 'curve'] : ['time', ...TRANSFORM_KEY_CHANNELS, 'curve'];\n let last = -Infinity;\n const keys: CoreIkKey[] = [];\n rawKeys.forEach((k: unknown, j: number) => {\n const kat = `${at}.keys[${j}]`;\n if (!isRecord(k)) {\n problems.push(`${kat} is not an object`);\n return;\n }\n unknownFields(k, known, kat, problems);\n const time = k.time;\n if (typeof time !== 'number' || !Number.isFinite(time) || time < 0) {\n problems.push(`${kat}: time is ${JSON.stringify(time)}, not a finite time at or after 0`);\n return;\n }\n if (time <= last) problems.push(`${kat}: time ${time} is not after the key before it — the writer refuses key times that do not strictly increase`);\n last = Math.max(last, time);\n // The parser's reading of an absent field (`PARSER_DEFAULTS` in src/keyorder.ts): an ik key's mix 1, softness 0; a transform key's mixes 1 and its mixY its own mixX.\n const stated = channels.map((c) => {\n if (kind === 'transform' && c === 'mixY' && k.mixY === undefined) return num(k, 'mixX', 1, kat, problems);\n return num(k, c, c === 'softness' ? 0 : 1, kat, problems);\n });\n keys.push({\n time: Math.fround(time),\n values: stated.map(Math.fround),\n stated: { time, values: stated },\n curve: keyCurve(k, channels.length, j === rawKeys.length - 1, kat, problems),\n flags: { bendPositive: flag(k, 'bendPositive', true, kat, problems), compress: flag(k, 'compress', false, kat, problems), stretch: flag(k, 'stretch', false, kat, problems) },\n });\n });\n if (kind === 'ik') out.ik.push({ name: entry.name, keys });\n else out.transform.push({ name: entry.name, keys });\n });\n }\n return out;\n}\n\n/** What evaluates one channel of a constraint key, and finds the key — construct 4's unless a plant passes others. */\nexport interface ConstraintTimelinePlant {\n channel?: (keys: readonly CoreKey[], index: number, channel: number, t: number) => number;\n search?: (keys: readonly CoreKey[], t: number) => number;\n}\n\n/** Every admitted constraint record with its timeline's values at `t` in place of its own (the header's *The timelines*). */\nexport function posedRecords(records: readonly CoreConstraintRecord[], timelines: CoreConstraintTimelines | null, t: number, plant: ConstraintTimelinePlant = {}): CoreConstraintRecord[] {\n const search = plant.search ?? keyIndexAt;\n const channel = plant.channel ?? channelAt;\n return records.map((r): CoreConstraintRecord => {\n if (timelines === null || r.kind === 'physics') return r;\n if (r.kind === 'slider') return posedSlider(r, timelines.slider, t, plant);\n if (r.kind === 'path') {\n const tl = timelines.path.find((x) => x.name === r.name);\n if (tl === undefined) return r;\n const out = { ...r };\n for (const [kind, fields] of [['position', ['position']], ['spacing', ['spacing']], ['mix', ['mixRotate', 'mixX', 'mixY']]] as const) {\n const keys = tl[kind];\n if (keys === undefined) continue;\n const i = search(keys, t);\n if (i < 0) continue;\n // Through the setup blend at alpha 1 as well (issue #984): the value as keyed read position 33, spacing 40 and mix 1 of 60 Bézier-keyed probes bit-exact at 40 irrational samples, the blend 60 of each (CY01).\n fields.forEach((f, c) => (out[f] = r[f] + (channel(keys, i, c, t) - r[f]) * 1));\n }\n return out;\n }\n if (r.kind === 'ik') {\n const tl = timelines.ik.find((x) => x.name === r.name);\n if (tl === undefined) return r;\n const i = search(tl.keys, t);\n if (i < 0) return r;\n // The keyed values reach the pose through the setup blend at alpha 1, `setup + (value − setup)·1` (issue #966): the value as keyed agrees on the grid and reads off in the last bit — a Bézier-eased mix of 0.3899 on `spineboy-pro`'s jump moved its two-bone ik 2 ulp.\n return { ...r, mix: r.mix + (channel(tl.keys, i, 0, t) - r.mix) * 1, softness: r.softness + (channel(tl.keys, i, 1, t) - r.softness) * 1, ...tl.keys[i].flags };\n }\n const tl = timelines.transform.find((x) => x.name === r.name);\n if (tl === undefined) return r;\n const i = search(tl.keys, t);\n if (i < 0) return r;\n const mixes = {} as Record<TransformProperty, number>;\n // Through the setup blend at alpha 1 too (issue #966): on 60 probes keying all six mixes by Bézier segments over setup mixes in [−1, 2], sampled at 40 irrational times, the value as keyed read 0 bit-exact and the blend 60 (CW05).\n TRANSFORM_PROPERTIES.forEach((p, c) => (mixes[p] = r.mixes[p] + (channel(tl.keys, i, c, t) - r.mixes[p]) * 1));\n return { ...r, mixes };\n });\n}\n\n// ---------------------------------------------------------------------------\n// solving\n// ---------------------------------------------------------------------------\n\n/** A change brought once into (−180, 180] — the header's measured wrap (−180 goes to 180). */\nfunction wrap180(r: number): number {\n return r > 180 ? r - 360 : r <= -180 ? r + 360 : r;\n}\n\nconst IDENTITY: CoreWorld = { a: 1, b: 0, c: 0, d: 1, worldX: 0, worldY: 0 };\n\nfunction modeOf(bone: ModelBone): CoreInheritMode {\n const m = bone.inheritMode;\n if (m === undefined || m.length === 0) return 'normal';\n const folded = m[0].toLowerCase() + m.slice(1);\n return folded === 'onlyTranslation' || folded === 'noRotationOrReflection' || folded === 'noScale' || folded === 'noScaleOrReflection' ? folded : 'normal';\n}\n\n/**\n * The rules issue #979 measured on collapsed frames and on bones the posed\n * skin leaves unposed (the header's *Unposed bones and collapsed frames*),\n * as one object so that a control can plant each one back to the reading\n * before it (`CorePlant.solver`); nothing else passes another.\n */\nexport interface SolverRules {\n /** An ik frame whose determinant is at most this in magnitude is collapsed: a one-bone ik reads the target at the frame's origin, a two-bone ik reads its grandparent's inverse as zero. */\n ikCollapsedDet: number;\n /** A one-bone ik under a `noRotationOrReflection` parent: the floor under the parent x axis's squared length. */\n ikXAxisFloor: number;\n /** `localFromWorld`: a local x column that is not above 0.0001 — NaN included — reads as collapsed, and a y column no longer than 0.00001 reads rotation 0 (x collapsed too) or shearY 0. */\n readBackCollapsed: boolean;\n /** A world-space `rotate` source negates the constraint's `rotation` unless its determinant is above 0 — at 0 too. */\n offsetNegatedAtZeroDet: boolean;\n /** An inactive bone is never posed again, and the bones below it are posed again only when a constraint moved it. */\n inactiveHoldsItsWorld: boolean;\n /** A transform constraint is applied when its source is active, to every bone it names. */\n transformIgnoresBoneActivity: boolean;\n /** A pose in which a posed bone reads a bone whose value depends on the runtime's previous pass is refused by name (`unposedLeakWhy`). */\n refuseHistoryLeak: boolean;\n /** An ik naming an inactive bone is applied when its target is active, reading the frame above its first bone as a fresh skeleton holds it: zeros unless the pass brought that bone up to date before the ik (`frameUpdatedBefore`). */\n ikOverInactiveFresh: boolean;\n /** `localFromWorld`, a reflected local matrix: `shearY` is the y angle less `rotation − 90` (issue #966), not the y angle turned by 180 less `rotation + 90`. */\n readBackReflectedShear: boolean;\n /** `localFromWorld` in `noRotationOrReflection`: the conformal frame's inverse applied as the parent x axis over its squared length and its y axis over |det| (issue #966), not divided by the conformal determinant. */\n readBackConformalInverse: boolean;\n /** `localFromWorld` in the two `noScale` modes: the world columns read in the frame the forward pose builds from the rotation just read, the x column's residual angle kept as `shearX` (issue #966), not the x column's length with `shearX` 0. */\n readBackNoScaleFrame: boolean;\n /** An additive world-space `shearY`: `(v + 90)·RAD − 90·RAD` (issue #966), not `v·RAD`. */\n additiveShearRightAngle: boolean;\n /** A two-bone ik: a parent scale of 0 counts as positive in the product of the scale signs (issue #966), not as 0. */\n ikZeroScaleSignPositive: boolean;\n /** A one-bone ik compresses or stretches only a bone whose length times scaleX is above this (issue #966; the reading before, 0.0001, left bones between the two unscaled). */\n ikStretchMinLength: number;\n /** A two-bone ik whose child's origin is nearer the parent's than this, in the grandparent frame, is a one-bone ik on the parent with the child at rotation 0 (issue #966); negative, never. */\n ikTwoBoneNearChild: number;\n /** A slider poses again every bone its animation keys, whether or not a timeline wrote it — before its first key too (issue #989) — not only the bones a timeline wrote. */\n sliderReposesKeyedBones: boolean;\n /** A slider's additive scale key: `current + (v·setup − setup)·mix` (issue #989), not `current + (v − 1)·setup·mix`. */\n sliderAdditiveScaleProduct: boolean;\n /** A slider's scale key at mix exactly 1 writes `setup·v` itself (issue #989), not `from + (setup·v − from)·1`. */\n sliderScaleMixOneIsTarget: boolean;\n /**\n * Issue #1049, each the rule `./constraints_slider.ts` *Physics timelines* states — `false` (or the named reading)\n * plants the reading it rejected: a slider's physics keys write the pass's physics records (`false`: write nothing);\n * a non-additive one blends from the CURRENT value (`false`: from the setup value); only `wind` and `gravity` add\n * (`false`: every value kind adds); a `mass` key blends the mass (`false`: the inverse); the write lasts one pass\n * (`false`: what a slider wrote stands on the next step wherever the step's own animation does not key it); a\n * `reset` key fires nothing (`false`: a key at or before the slider's time resets its constraints on every pass).\n */\n sliderWritesPhysics: boolean;\n sliderPhysicsFromCurrent: boolean;\n sliderPhysicsAddsWindGravityOnly: boolean;\n sliderPhysicsBlendsMass: boolean;\n sliderPhysicsLastsOnePass: boolean;\n sliderPhysicsResetIsDead: boolean;\n}\n\n/** The runtime's rules, as measured. */\nexport const RUNTIME_SOLVER_RULES: Readonly<SolverRules> = {\n ikCollapsedDet: 0.00001,\n ikXAxisFloor: 0.00001,\n readBackCollapsed: true,\n offsetNegatedAtZeroDet: true,\n inactiveHoldsItsWorld: true,\n transformIgnoresBoneActivity: true,\n ikOverInactiveFresh: true,\n refuseHistoryLeak: true,\n readBackReflectedShear: true,\n readBackConformalInverse: true,\n readBackNoScaleFrame: true,\n additiveShearRightAngle: true,\n ikZeroScaleSignPositive: true,\n ikStretchMinLength: 0.00001,\n ikTwoBoneNearChild: 0.00001,\n sliderReposesKeyedBones: true,\n sliderAdditiveScaleProduct: true,\n sliderScaleMixOneIsTarget: true,\n sliderWritesPhysics: true,\n sliderPhysicsFromCurrent: true,\n sliderPhysicsAddsWindGravityOnly: true,\n sliderPhysicsBlendsMass: true,\n sliderPhysicsLastsOnePass: true,\n sliderPhysicsResetIsDead: true,\n};\n\n/** The runtime's rules with a plant's over them. */\nexport function solverRules(plant: Partial<SolverRules> | undefined): Readonly<SolverRules> {\n return plant === undefined ? RUNTIME_SOLVER_RULES : { ...RUNTIME_SOLVER_RULES, ...plant };\n}\n\n/** The runtime's `scaleY` for a bone an ik scaled by `s` along its length (the header's `volume` measurement). */\nfunction volumeScaleY(scaleY: number, s: number): number {\n return scaleY / (s < 0.7 ? 0.25 + s * 0.642857 : s);\n}\n\n/** The state the solvers work on: every bone's local values, its world transform, and which bones are active. */\nexport interface SolverState {\n bones: ModelBone[];\n index: Map<string, number>;\n world: Map<string, CoreWorld>;\n active: ReadonlySet<string>;\n /** `RUNTIME_SOLVER_RULES` unless a plant passes others. */\n rules: Readonly<SolverRules>;\n}\n\nfunction bone(state: SolverState, name: string): ModelBone {\n return state.bones[state.index.get(name) as number];\n}\n\nfunction parentWorld(state: SolverState, b: ModelBone): CoreWorld {\n return b.parent === undefined ? IDENTITY : (state.world.get(b.parent) as CoreWorld);\n}\n\n/** One bone's world transform from its local values under its parent's current world transform — `./world.ts`'s arithmetic. */\nfunction poseBone(state: SolverState, b: ModelBone): void {\n // An inactive bone is not posed again: it keeps its zeros, or what a constraint wrote into them (issue #979).\n if (!state.active.has(b.name)) {\n if (!state.rules.inactiveHoldsItsWorld) state.world.set(b.name, { a: 0, b: 0, c: 0, d: 0, worldX: 0, worldY: 0 });\n return;\n }\n if (b.parent === undefined) {\n state.world.set(b.name, worldTransforms([b]).get(b.name) as CoreWorld);\n return;\n }\n const p = state.world.get(b.parent) as CoreWorld;\n const [a, bb, c, d] = modeMatrix(modeOf(b), p, b);\n const x = b.x ?? 0;\n const y = b.y ?? 0;\n state.world.set(b.name, { a, b: bb, c, d, worldX: p.a * x + p.b * y + p.worldX, worldY: p.c * x + p.d * y + p.worldY });\n}\n\n/** The bone's local values read back from its world transform — the header's `localFromWorld`. */\nexport function localFromWorld(b: ModelBone, p: CoreWorld, w: CoreWorld, rules: Readonly<SolverRules> = RUNTIME_SOLVER_RULES): void {\n const mode = b.parent === undefined ? 'normal' : modeOf(b);\n const pid = 1 / (p.a * p.d - p.b * p.c);\n const dx = w.worldX - p.worldX;\n const dy = w.worldY - p.worldY;\n // The inverse's entries are formed first, then applied (issue #966): `dx·d·pid` reads last-bit off where `dx·(d·pid)` does not.\n b.x = dx * (p.d * pid) - dy * (p.b * pid);\n b.y = dy * (p.a * pid) - dx * (p.c * pid);\n b.shearX = 0;\n if (mode === 'noScale' || mode === 'noScaleOrReflection') {\n const det = p.a * p.d - p.b * p.c;\n const flip = mode === 'noScale' && det < 0 ? -1 : 1;\n if (!rules.readBackNoScaleFrame) {\n // The reading before issue #966's second cut, kept for the control that plants it back (CW03).\n const length = Math.sqrt(w.a * w.a + w.c * w.c);\n const [ux, uy] = [w.a / length, w.c / length];\n decompose(b, length, 0, ux * w.b + uy * w.d, (ux * w.d - uy * w.b) * flip, rules);\n b.rotation = Math.atan2((uy * p.a - ux * p.c) / det, (ux * p.d - uy * p.b) / det) * DEG;\n return;\n }\n // The rotation first: the angle of the parent's adjugate applied to the world x column, both parts negated when the parent reflects (issue #966).\n const sign = det < 0 ? -1 : 1;\n const rotation = Math.atan2((p.a * w.c - p.c * w.a) * sign, (p.d * w.a - p.b * w.c) * sign) * DEG;\n // Then the frame the forward pose builds from that rotation, and the world columns read in it — its transpose, flipped for noScale under a reflecting parent.\n const [ux, uy] = noScaleDirection([p.a, p.b, p.c, p.d], rotation);\n decompose(b, ux * w.a + uy * w.c, (ux * w.c - uy * w.a) * flip, ux * w.b + uy * w.d, (ux * w.d - uy * w.b) * flip, rules, 'shearX');\n b.rotation = rotation;\n return;\n }\n let la: number;\n let lb: number;\n let lc: number;\n let ld: number;\n if (mode === 'onlyTranslation') {\n [la, lb, lc, ld] = [w.a, w.b, w.c, w.d];\n } else if (mode === 'noRotationOrReflection') {\n if (rules.readBackConformalInverse) {\n // The conformal frame's inverse as its axes over their lengths (issue #966): the x axis over its squared length, the y axis over |det|, each reciprocal multiplied in.\n const xLengthInverse = 1 / (p.a * p.a + p.c * p.c);\n const detInverse = 1 / Math.abs(p.a * p.d - p.b * p.c);\n [la, lb, lc, ld] = [(p.a * w.a + p.c * w.c) * xLengthInverse, (p.a * w.b + p.c * w.d) * xLengthInverse, (p.a * w.c - p.c * w.a) * detInverse, (p.a * w.d - p.c * w.b) * detInverse];\n } else {\n // The reading before issue #966's second cut, kept for the control that plants it back (CW02).\n const k = Math.abs(p.a * p.d - p.b * p.c) / (p.a * p.a + p.c * p.c);\n const [ca, cb, cc, cd] = [p.a, -p.c * k, p.c, p.a * k];\n const cdet = ca * cd - cb * cc;\n [la, lb, lc, ld] = [(cd * w.a - cb * w.c) / cdet, (cd * w.b - cb * w.d) / cdet, (ca * w.c - cc * w.a) / cdet, (ca * w.d - cc * w.b) / cdet];\n }\n decompose(b, la, lc, lb, ld, rules);\n b.rotation = (b.rotation ?? 0) + Math.atan2(p.c, p.a) * DEG;\n return;\n } else {\n const [ia, ib, ic, id] = [p.d * pid, p.b * pid, p.c * pid, p.a * pid];\n [la, lb, lc, ld] = [ia * w.a - ib * w.c, ia * w.b - ib * w.d, id * w.c - ic * w.a, id * w.d - ic * w.b];\n }\n decompose(b, la, lc, lb, ld, rules);\n}\n\n/**\n * A local matrix `[la lb; lc ld]` (columns `(la, lc)` and `(lb, ld)`) as rotation, scales and shears — the header's rule.\n * `xAngleIn` says which field takes the x column's angle: `rotation` (every mode but the two `noScale` ones), or `shearX`\n * — the two `noScale` modes, whose rotation is read first (issue #966: the runtime keeps the residual angle of the x\n * column, in the frame built from that rotation, as `shearX`, and measures `shearY` from 0, as the forward frame\n * `frame(0, shearX, shearY, …)` reads them).\n */\nfunction decompose(b: ModelBone, la: number, lc: number, lb: number, ld: number, rules: Readonly<SolverRules>, xAngleIn: 'rotation' | 'shearX' = 'rotation'): void {\n const sx = Math.sqrt(la * la + lc * lc);\n const yLength = Math.sqrt(lb * lb + ld * ld);\n // Not above the bound, NaN included (issue #979: a collapsed parent's inverse is NaN, and the runtime reads scaleX 0 and shearY 0 from it); a y column no longer than 0.00001 reads rotation 0.\n if (rules.readBackCollapsed ? !(sx > 0.0001) : sx <= 0.0001) {\n b.scaleX = 0;\n b.scaleY = yLength;\n b.shearY = 0;\n b.rotation = !rules.readBackCollapsed || yLength > 0.00001 ? Math.atan2(ld, lb) * DEG - 90 : 0;\n return;\n }\n const xAngle = Math.atan2(lc, la) * DEG;\n const det = la * ld - lb * lc;\n let yAngle = Math.atan2(ld, lb) * DEG;\n if (xAngleIn === 'rotation') b.rotation = xAngle;\n else b.shearX = xAngle;\n b.scaleX = sx;\n b.scaleY = det < 0 ? -yLength : yLength;\n // The inverse of the forward frame's `rotation + 90 + shearY` (issue #966): the y angle less `rotation + 90`, or, when the determinant is negative (the\n // reflection carried by the negative scaleY), less `rotation − 90` — the reading before turned the y angle by 180 first and then took `rotation + 90` off.\n const from = xAngleIn === 'rotation' ? xAngle : 0;\n let right = 90;\n if (det < 0) {\n if (rules.readBackReflectedShear) right = -90;\n else yAngle += 180;\n }\n let shear = yAngle - (from + right);\n shear = shear > 180 ? shear - 360 : shear < -180 ? shear + 360 : shear;\n // A y column no longer than 0.00001 reads shearY 0 (issue #979), as it reads rotation 0 when the x column is collapsed too.\n b.shearY = !rules.readBackCollapsed || yLength > 0.00001 ? shear : 0;\n}\n\n/** A one-bone ik (the header's *ik — one bone*): returns the bone changed, or none. */\nfunction solveOne(state: SolverState, c: CoreIkRecord, frame: CoreWorld | null = null): string[] {\n const b = bone(state, c.bones[0]);\n const p = frame ?? parentWorld(state, b);\n const bw = state.world.get(b.name) as CoreWorld;\n const t = state.world.get(c.target) as CoreWorld;\n const mode = modeOf(b);\n let [pa, pb, pc, pd] = [p.a, p.b, p.c, p.d];\n let turn = 0;\n let lx: number;\n let ly: number;\n if (mode === 'noRotationOrReflection') {\n // The x axis's squared length is floored here (issue #979, `ikXAxisFloor`) — not in `./world.ts`'s frame for the same mode.\n const k = Math.abs(pa * pd - pb * pc) / Math.max(state.rules.ikXAxisFloor, pa * pa + pc * pc);\n pb = -pc * k;\n pd = pa * k;\n turn = Math.atan2(pc, pa) * DEG;\n const det = pa * pd - pb * pc;\n const x = t.worldX - p.worldX;\n const y = t.worldY - p.worldY;\n [lx, ly] = Math.abs(det) <= state.rules.ikCollapsedDet ? [0, 0] : [(x * pd - y * pb) / det - (b.x ?? 0), (y * pa - x * pc) / det - (b.y ?? 0)];\n } else {\n if (mode === 'onlyTranslation') {\n lx = t.worldX - bw.worldX;\n ly = t.worldY - bw.worldY;\n } else {\n const det = pa * pd - pb * pc;\n const x = t.worldX - p.worldX;\n const y = t.worldY - p.worldY;\n [lx, ly] = Math.abs(det) <= state.rules.ikCollapsedDet ? [0, 0] : [(x * pd - y * pb) / det - (b.x ?? 0), (y * pa - x * pc) / det - (b.y ?? 0)];\n }\n }\n const rotation = b.rotation ?? 0;\n const scaleX = b.scaleX ?? 1;\n // Accumulated from the bone's own angles first and the target's direction last (issue #966): `atan2·DEG − shearX − rotation + turn` agrees on the grid and reads last-bit off on 53 of 600 random one-bone iks, this order on none.\n let r = -(b.shearX ?? 0) - rotation + turn + Math.atan2(ly, lx) * DEG;\n if (scaleX < 0) r += 180;\n b.rotation = rotation + wrap180(r) * c.mix;\n const len = (b.length ?? 0) * scaleX;\n if ((c.compress || c.stretch) && len > state.rules.ikStretchMinLength) {\n const wx = t.worldX - bw.worldX;\n const wy = t.worldY - bw.worldY;\n const d = mode === 'noScale' || mode === 'noScaleOrReflection' ? Math.sqrt(wx * wx + wy * wy) : Math.sqrt(lx * lx + ly * ly);\n if ((c.compress && d < len) || (c.stretch && d > len)) {\n const s = (d / len - 1) * c.mix + 1;\n b.scaleX = scaleX * s;\n if (c.scaleY === 'uniform') b.scaleY = (b.scaleY ?? 1) * s;\n else if (c.scaleY === 'volume') b.scaleY = volumeScaleY(b.scaleY ?? 1, s);\n }\n }\n return [b.name];\n}\n\n/** A two-bone ik (the header's *ik — two bones*): returns the parent changed (the child is below it), or none. */\nfunction solveTwo(state: SolverState, c: CoreIkRecord, frame: CoreWorld | null = null): string[] {\n const parent = bone(state, c.bones[0]);\n const child = bone(state, c.bones[1]);\n if (modeOf(parent) !== 'normal' || modeOf(child) !== 'normal') return [];\n const g = frame ?? parentWorld(state, parent);\n const pw = state.world.get(parent.name) as CoreWorld;\n const t = state.world.get(c.target) as CoreWorld;\n const gdet = g.a * g.d - g.b * g.c;\n // A collapsed grandparent frame (issue #979): its inverse reads as zero, so every point in it is its origin.\n const gid = Math.abs(gdet) <= state.rules.ikCollapsedDet ? 0 : 1 / gdet;\n const inGrand = (wx: number, wy: number): [number, number] => {\n const x = wx - g.worldX;\n const y = wy - g.worldY;\n return [(x * g.d - y * g.b) * gid, (y * g.a - x * g.c) * gid];\n };\n const px = parent.x ?? 0;\n const py = parent.y ?? 0;\n const psx = parent.scaleX ?? 1;\n const psy = parent.scaleY ?? 1;\n const csx = child.scaleX ?? 1;\n let sx = psx;\n let sy = psy;\n const cx = child.x ?? 0;\n let cy = child.y ?? 0;\n const uniform = Math.abs(Math.abs(psx) - Math.abs(psy)) <= 0.00001;\n if (!uniform || c.stretch) cy = 0;\n const [ox, oy] = inGrand(pw.a * cx + pw.b * cy + pw.worldX, pw.c * cx + pw.d * cy + pw.worldY);\n const dx = ox - px;\n const dy = oy - py;\n const l1 = Math.sqrt(dx * dx + dy * dy);\n let l2 = (child.length ?? 0) * Math.abs(csx);\n // The child's origin nearer the parent's than 0.00001 in the grandparent frame (issue #966): the constraint turns the parent as a one-bone ik would,\n // stretching it but neither compressing it nor scaling its y (its `scaleY` mode read as none), and poses the child at rotation 0 with the local y the solver set. Measured on parents whose x scale is 0 (CW06), and by bisection\n // on the x scale at three child offsets and three rotations: an l1 of exactly 0.00001 solves, the double below folds.\n if (l1 < state.rules.ikTwoBoneNearChild) {\n solveOne(state, { ...c, bones: [parent.name], compress: false, scaleY: 'none' }, frame);\n child.rotation = 0;\n child.y = cy;\n return [parent.name];\n }\n let [tx, ty] = inGrand(t.worldX, t.worldY);\n tx -= px;\n ty -= py;\n let d2 = tx * tx + ty * ty;\n const bend = c.bendPositive ? 1 : -1;\n if (c.softness !== 0) {\n const soft = c.softness * (Math.abs(psx) * (Math.abs(csx) + 1) * 0.5);\n const d = Math.sqrt(d2);\n const sd = d - l1 - l2 * Math.abs(psx) + soft;\n if (sd > 0) {\n const q = Math.min(1, sd / (soft * 2)) - 1;\n const pull = (sd - soft * (1 - q * q)) / d;\n tx -= pull * tx;\n ty -= pull * ty;\n d2 = tx * tx + ty * ty;\n }\n }\n let a1: number;\n let a2: number;\n if (uniform) {\n l2 *= Math.abs(psx);\n let cos = (d2 - l1 * l1 - l2 * l2) / (2 * l1 * l2);\n if (cos < -1) {\n cos = -1;\n a2 = Math.PI * bend;\n } else if (cos > 1) {\n cos = 1;\n a2 = 0;\n if (c.stretch) {\n const f = (Math.sqrt(d2) / (l1 + l2) - 1) * c.mix + 1;\n sx *= f;\n if (c.scaleY === 'uniform') sy *= f;\n else if (c.scaleY === 'volume') sy = volumeScaleY(sy, f);\n }\n } else a2 = Math.acos(cos) * bend;\n const along = l1 + l2 * cos;\n const across = l2 * Math.sin(a2);\n a1 = Math.atan2(ty * along - tx * across, tx * along + ty * across);\n } else {\n const ea = Math.abs(psx) * l2;\n const eb = Math.abs(psy) * l2;\n const aa = ea * ea;\n const bb = eb * eb;\n const qa = bb - aa;\n const qb = -2 * bb * l1;\n const qc = bb * l1 * l1 + aa * d2 - aa * bb;\n const disc = qb * qb - 4 * qa * qc;\n let solved = false;\n a1 = 0;\n a2 = 0;\n if (disc >= 0) {\n let q = Math.sqrt(disc);\n if (qb < 0) q = -q;\n q = -(qb + q) * 0.5;\n const r0 = q / qa;\n const r1 = qc / q;\n const X = Math.abs(r0) < Math.abs(r1) ? r0 : r1;\n const y2 = d2 - X * X;\n if (y2 >= 0) {\n const Y = Math.sqrt(y2) * bend;\n a1 = Math.atan2(ty, tx) - Math.atan2(Y, X);\n a2 = Math.atan2(Y / Math.abs(psy), (X - l1) / Math.abs(psx));\n solved = true;\n }\n }\n if (!solved) {\n let near = { angle: RUNTIME_PI, x: l1 - ea, y: 0, dist: (l1 - ea) * (l1 - ea) };\n let far = { angle: 0, x: l1 + ea, y: 0, dist: (l1 + ea) * (l1 + ea) };\n const vertex = (-ea * l1) / (aa - bb);\n if (vertex >= -1 && vertex <= 1) {\n const angle = Math.acos(vertex);\n const x = ea * Math.cos(angle) + l1;\n const y = eb * Math.sin(angle);\n const dist = x * x + y * y;\n if (dist < near.dist) near = { angle, x, y, dist };\n if (dist > far.dist) far = { angle, x, y, dist };\n }\n const pick = d2 <= (near.dist + far.dist) * 0.5 ? near : far;\n a1 = Math.atan2(ty, tx) - Math.atan2(pick.y * bend, pick.x);\n a2 = pick.angle * bend;\n }\n }\n // A scale of 0 counts as positive (issue #966): `Math.sign` read 0 for it and zeroed both offsets and the child's angle — 59 of 300 two-bone iks over a parent of scaleY 0 exact, against 300 (CW06).\n const signs = state.rules.ikZeroScaleSignPositive ? (psx < 0 ? -1 : 1) * (psy < 0 ? -1 : 1) : Math.sign(psx) * Math.sign(psy);\n const offset = Math.atan2(cy, cx);\n // The child's offset angle is taken off in radians before the change is turned into degrees (issue #966): `a1·DEG − offset·DEG` agrees on the grid and reads 1–4 ulp off on `spineboy-pro`'s two-bone iks (44 bone findings of a raw compare against 4, the four the ik mix's setup blend below).\n const parentRotation = parent.rotation ?? 0;\n const parentChange = (a1 - signs * offset) * DEG + (psx < 0 ? 180 : 0) - parentRotation;\n parent.rotation = parentRotation + wrap180(parentChange) * c.mix;\n parent.scaleX = sx;\n parent.scaleY = sy;\n const childTarget = ((a2 + signs * offset) * DEG - (child.shearX ?? 0)) * signs + (csx < 0 ? 180 : 0);\n const childRotation = child.rotation ?? 0;\n child.y = cy;\n child.rotation = childRotation + wrap180(childTarget - childRotation) * c.mix;\n return [parent.name];\n}\n\n/** The source's value of `property` (the header's *transform*); a slider reads its dial through it with no offset. */\nexport function sourceValue(state: SolverState, c: Pick<CoreTransformRecord, 'source' | 'localSource' | 'offsets'>, property: TransformProperty): number {\n const s = bone(state, c.source);\n const o = c.offsets;\n if (c.localSource) {\n switch (property) {\n case 'rotate': return (s.rotation ?? 0) + o.rotate;\n case 'x': return (s.x ?? 0) + o.x;\n case 'y': return (s.y ?? 0) + o.y;\n case 'scaleX': return (s.scaleX ?? 1) + o.scaleX;\n case 'scaleY': return (s.scaleY ?? 1) + o.scaleY;\n case 'shearY': return (s.shearY ?? 0) + o.shearY;\n }\n }\n const w = state.world.get(c.source) as CoreWorld;\n switch (property) {\n case 'rotate': {\n // The offset is negated unless the determinant is above 0 — a collapsed source (determinant 0, issue #979) negates it too.\n const det = w.a * w.d - w.b * w.c;\n let r = Math.atan2(w.c, w.a) * DEG + ((state.rules.offsetNegatedAtZeroDet ? det > 0 : det >= 0) ? o.rotate : -o.rotate);\n if (r < 0) r += 360;\n return r;\n }\n case 'x': return w.a * o.x + w.b * o.y + w.worldX;\n case 'y': return w.c * o.x + w.d * o.y + w.worldY;\n case 'scaleX': return Math.sqrt(w.a * w.a + w.c * w.c) + o.scaleX;\n case 'scaleY': return Math.sqrt(w.b * w.b + w.d * w.d) + o.scaleY;\n case 'shearY': return (Math.atan2(w.d, w.b) - Math.atan2(w.c, w.a)) * DEG - 90 + o.shearY;\n }\n}\n\nfunction applyWorld(w: CoreWorld, property: TransformProperty, v: number, mix: number, additive: boolean, rules: Readonly<SolverRules>): void {\n switch (property) {\n case 'rotate': {\n // In radians, the change wrapped at the runtime's pi (issue #966): the degree form `wrap180(v − atan2·DEG)·mix·RAD` agrees on the grid and reads 1–2 ulp off on the corpus's `spineboy-pro` (202 findings of a raw compare, 113 of them bones, against 96 with this reading, the rest the two-bone ik below); this reading is exact on the row once those are fixed too.\n let r = additive ? v * RAD : v * RAD - Math.atan2(w.c, w.a);\n if (r > RUNTIME_PI) r -= 2 * RUNTIME_PI;\n else if (r < -RUNTIME_PI) r += 2 * RUNTIME_PI;\n r *= mix;\n const cos = Math.cos(r);\n const sin = Math.sin(r);\n const [a, b] = [w.a, w.b];\n w.a = cos * a - sin * w.c;\n w.b = cos * b - sin * w.d;\n w.c = sin * a + cos * w.c;\n w.d = sin * b + cos * w.d;\n return;\n }\n case 'x':\n w.worldX = additive ? w.worldX + v * mix : w.worldX + (v - w.worldX) * mix;\n return;\n case 'y':\n w.worldY = additive ? w.worldY + v * mix : w.worldY + (v - w.worldY) * mix;\n return;\n case 'scaleX':\n case 'scaleY': {\n const [p, q] = property === 'scaleX' ? (['a', 'c'] as const) : (['b', 'd'] as const);\n const s = Math.sqrt(w[p] * w[p] + w[q] * w[q]);\n if (s === 0) return;\n const k = additive ? 1 + (v - 1) * mix : 1 + ((v - s) * mix) / s;\n w[p] *= k;\n w[q] *= k;\n return;\n }\n case 'shearY': {\n const yAngle = Math.atan2(w.d, w.b);\n const xAngle = Math.atan2(w.c, w.a);\n // Additive (issue #966): the value is turned into radians with the right angle on, and the right angle taken off after — `(v + 90)·RAD − 90·RAD`, unwrapped — as the absolute form takes the columns' angle off the same sum; `v·RAD` read 35 of 132 of the transform population's additive world-shear probes last-bit off, and 123 of 300 single-mapping probes (CW04).\n let r = additive && !rules.additiveShearRightAngle ? v * RAD : (v + 90) * RAD - (additive ? 90 * RAD : yAngle - xAngle);\n if (!additive) r = r > RUNTIME_PI ? r - 2 * RUNTIME_PI : r < -RUNTIME_PI ? r + 2 * RUNTIME_PI : r;\n const angle = yAngle + r * mix;\n const s = Math.sqrt(w.b * w.b + w.d * w.d);\n w.b = Math.cos(angle) * s;\n w.d = Math.sin(angle) * s;\n return;\n }\n }\n}\n\nconst LOCAL_FIELD: Record<TransformProperty, 'rotation' | 'x' | 'y' | 'scaleX' | 'scaleY' | 'shearY'> = { rotate: 'rotation', x: 'x', y: 'y', scaleX: 'scaleX', scaleY: 'scaleY', shearY: 'shearY' };\n\nfunction applyLocal(b: ModelBone, property: TransformProperty, v: number, mix: number, additive: boolean): void {\n const field = LOCAL_FIELD[property];\n const scale = property === 'scaleX' || property === 'scaleY';\n const current = b[field] ?? (scale ? 1 : 0);\n if (!additive) b[field] = current + (v - current) * mix;\n else b[field] = scale ? current * (1 + (v - 1) * mix) : current + v * mix;\n}\n\n/** A transform constraint (the header's *transform*): returns the bones it changed, and those it changed in world space. */\nfunction solveTransform(state: SolverState, c: CoreTransformRecord): { changed: string[]; inWorld: string[] } {\n const changed: string[] = [];\n const inWorld: string[] = [];\n for (const name of c.bones) {\n const b = bone(state, name);\n const w = { ...(state.world.get(name) as CoreWorld) };\n let applied = false;\n for (const from of c.properties) {\n const value = sourceValue(state, c, from.property) - from.offset;\n for (const to of from.to) {\n const mix = c.mixes[to.property];\n if (mix === 0) continue;\n let v = value * to.scale + to.offset;\n if (c.clamp) {\n const lo = Math.min(to.offset, to.max);\n const hi = Math.max(to.offset, to.max);\n v = v < lo ? lo : v > hi ? hi : v;\n }\n applied = true;\n if (c.localTarget) applyLocal(b, to.property, v, mix, c.additive);\n else applyWorld(w, to.property, v, mix, c.additive, state.rules);\n }\n }\n if (!applied) continue;\n changed.push(name);\n if (!c.localTarget) {\n state.world.set(name, w);\n inWorld.push(name);\n }\n }\n return { changed, inWorld };\n}\n\n/** Why a constraint is not applied under the skin view posed (the header's measured rule), or null when it is. */\nfunction inactiveWhy(state: SolverState, c: CoreConstraintRecord): string | null {\n return constraintInactiveWhy(c, state.active, state.rules);\n}\n\n/**\n * Why a constraint is not applied under a skin view whose active bones are\n * `active` (the header's measured rule), or null when it is — `inactiveWhy`'s\n * reading, exported so the additive probe (`./additive.ts`, issue #1025) asks\n * the rule the solver applies rather than a copy of it.\n */\nexport function constraintInactiveWhy(c: CoreConstraintRecord, active: ReadonlySet<string>, rules: Readonly<SolverRules> = RUNTIME_SOLVER_RULES): string | null {\n // A skin-required constraint of any kind is applied when an applied skin's list for its kind names it (issue #932, card #961; physics first by issue #956).\n if (c.skin && !c.listedBySkin) return 'skin';\n // A path constraint is active when its slot's bone is (`./constraints_path.ts`, *Which constraints run*); every other kind when every bone it names is.\n // A transform constraint is applied when its source is, to every bone it names, inactive ones included (issue #979: an inactive bone among them did not stop it moving the others, and it wrote into the inactive one). An ik naming an inactive bone is left unapplied: the runtime applies it from ancestors it has not brought up to date (the header's *Unposed bones*).\n const named = c.kind === 'path' ? [c.slotBone] : c.kind === 'ik' ? (rules.ikOverInactiveFresh ? [c.target] : [...c.bones, c.target]) : c.kind === 'transform' ? (rules.transformIgnoresBoneActivity ? [c.source] : [...c.bones, c.source]) : c.kind === 'slider' ? (c.bone === null ? [] : [c.bone]) : [c.bone];\n return named.every((n) => active.has(n)) ? null : 'inactive bone';\n}\n\n/**\n * For each ik naming an inactive bone, by its index in `records`: whether the\n * pass has brought the bone above its first bone up to date by the time the\n * ik runs (the header's *Unposed bones and collapsed frames*). The runtime\n * orders its update before it poses, each constraint bringing up to date the\n * bones it reads, parents first; an inactive bone counts as already ordered,\n * so ordering one does not reach its parent. A bone ordered once in the pass\n * holds a world from this pass; one never ordered holds what the skeleton\n * held before, which on a fresh skeleton is zeros. The same walk as\n * `slotBonePlan` in `./constraints_path.ts`.\n */\nexport function frameUpdatedBefore(bones: readonly ModelBone[], active: ReadonlySet<string>, records: readonly CoreConstraintRecord[], skipped: ReadonlySet<number>): Map<number, boolean> {\n const parent = new Map(bones.map((b) => [b.name, b.parent]));\n const children = new Map<string, string[]>();\n for (const b of bones) if (b.parent !== undefined) children.set(b.parent, [...(children.get(b.parent) ?? []), b.name]);\n const ordered = new Map(bones.map((b) => [b.name, !active.has(b.name)]));\n const ever = new Set<string>();\n const orderBone = (name: string): void => {\n if (ordered.get(name)) return;\n const p = parent.get(name);\n if (p !== undefined) orderBone(p);\n ordered.set(name, true);\n ever.add(name);\n };\n const unorder = (names: readonly string[]): void => {\n for (const n of names) {\n if (!active.has(n)) continue;\n if (ordered.get(n)) unorder(children.get(n) ?? []);\n ordered.set(n, false);\n }\n };\n const out = new Map<number, boolean>();\n records.forEach((c, m) => {\n if (skipped.has(m)) return;\n if (c.kind === 'slider') {\n unorder(c.timelines.bones.map((t) => t.name));\n return;\n }\n if (c.kind === 'ik') {\n orderBone(c.target);\n orderBone(c.bones[0]);\n if (c.bones.length > 1) orderBone(c.bones[c.bones.length - 1]);\n if (c.bones.some((b) => !active.has(b))) {\n const f = parent.get(c.bones[0]);\n out.set(m, f === undefined || ever.has(f));\n }\n unorder(children.get(c.bones[0]) ?? []);\n if (c.bones.length > 1) ordered.set(c.bones[c.bones.length - 1], true);\n return;\n }\n const moved = c.kind === 'physics' ? [c.bone] : c.bones;\n if (c.kind === 'transform') orderBone(c.source);\n else if (c.kind === 'path') for (const d of c.slotDeps) orderBone(d);\n for (const b of moved) orderBone(b);\n for (const b of moved) unorder(children.get(b) ?? []);\n for (const b of moved) ordered.set(b, true);\n });\n return out;\n}\n\n/** The frame an ik over an inactive bone reads (`frameUpdatedBefore`): zeros when the pass has not brought it up to date, null (the current one) otherwise. */\nfunction inactiveIkFrame(state: SolverState, c: CoreIkRecord, i: number, updated: ReadonlyMap<number, boolean>): CoreWorld | null {\n if (!state.rules.ikOverInactiveFresh || updated.get(i) !== false) return null;\n return { a: 0, b: 0, c: 0, d: 0, worldX: 0, worldY: 0 };\n}\n\n/** A plant a control passes in place of the solving: the records as posed, rewritten (a mix scaled, a bend flipped, two swapped). */\nexport type ConstraintPlant = (records: CoreConstraintRecord[]) => CoreConstraintRecord[];\n\n/**\n * Every admitted constraint applied, in the document's order, to the bones'\n * local values (copied, never the caller's) and their world transforms as\n * `worldTransforms` posed them — the header's update order — and the world\n * transforms returned. With `physics`, the stepped phase's context, each\n * physics constraint is stepped on its bone (`stepPhysics` in\n * `./constraints_physics.ts`); without it, it applies nothing.\n */\nexport function applyConstraints(bones: readonly ModelBone[], world: ReadonlyMap<string, CoreWorld>, active: ReadonlySet<string>, records: readonly CoreConstraintRecord[], previous: ReadonlyMap<string, CoreWorld> | null = null, applied?: SliderApplication[], physics?: PhysicsStepContext, settled?: (state: SolverState) => void, rules: Readonly<SolverRules> = RUNTIME_SOLVER_RULES): Map<string, CoreWorld> {\n // No record: nothing to solve, so the world as given, copied (issue #1134) — and what `sliderPhysicsTarget` leaves on the step's context with no record, an empty carry, under the plant that carries one.\n if (records.length === 0 && settled === undefined) {\n if (physics !== undefined && !rules.sliderPhysicsLastsOnePass) physics.carried = new Map();\n return new Map(world);\n }\n const state: SolverState = { bones: bones.map((b) => ({ ...b })), index: boneIndex(bones, active), world: new Map(world), active, rules };\n const skipped = new Set<number>();\n records.forEach((c, i) => {\n if (inactiveWhy(state, c) !== null) skipped.add(i);\n });\n // A path constraint's offset reads its slot bone's world as the runtime last brought it up to date (`./constraints_path.ts`, *Which slot bone*).\n const plan = records.some((c) => c.kind === 'path') ? keptPlan(slotBonePlans, state, records, skipped, () => slotBonePlan(bones, active, records, skipped)) : new Map<number, SlotBoneEvent | null>();\n // An ik over an inactive bone reads the frame above it as the pass left it (issue #979).\n const updated = records.some((c) => c.kind === 'ik' && c.bones.some((b) => !active.has(b))) ? keptPlan(frameUpdates, state, records, skipped, () => frameUpdatedBefore(bones, active, records, skipped)) : new Map<number, boolean>();\n const snapshots = new Map<number, CoreWorld>();\n // Issue #1049: under the step a slider's physics timelines write the pass's physics records, which a later physics constraint steps with.\n const physicsPose = physics === undefined ? undefined : sliderPhysicsTarget(records, active, physics, rules);\n const snap = (i: number, when: 'before' | 'after'): void => {\n for (const [k, e] of plan) if (e !== null && e.at === i && e.when === when && !(k === i && when === 'before')) snapshots.set(k, { ...(state.world.get((records[k] as CorePathRecord).slotBone) as CoreWorld) });\n };\n for (let i = 0; i < records.length; i++) {\n const c = records[i];\n snap(i, 'before');\n if (skipped.has(i)) continue;\n let changed: string[] = [];\n let inWorld: string[] = [];\n if (c.kind === 'physics') {\n // Under Physics.none a physics constraint applies nothing; stepped, it moves its bone in world space (`./constraints_physics.ts`).\n if (physics !== undefined) {\n const w = { ...(state.world.get(c.bone) as CoreWorld) };\n const posed = physicsPose?.records.get(c.name) ?? c;\n if ((physics.step ?? stepPhysics)(posed, w, bone(state, c.bone).length ?? 0, physics)) {\n state.world.set(c.bone, w);\n changed = [c.bone];\n inWorld = [c.bone];\n }\n }\n } else if (c.kind === 'slider') {\n changed = applySlider(state, c, applied, physicsPose);\n } else if (c.kind === 'ik') {\n if (c.mix !== 0) {\n const frame = inactiveIkFrame(state, c, i, updated);\n changed = c.bones.length === 1 ? solveOne(state, c, frame) : solveTwo(state, c, frame);\n }\n } else if (c.kind === 'path') {\n const e = plan.get(i) ?? null;\n const stale = previous === null ? { a: 0, b: 0, c: 0, d: 0, worldX: 0, worldY: 0 } : (previous.get(c.slotBone) as CoreWorld);\n const slotWorld = (e !== null && e.at === i) ? (state.world.get(c.slotBone) as CoreWorld) : e !== null ? (snapshots.get(i) as CoreWorld) : stale;\n ({ changed, inWorld } = solvePath(state, c, slotWorld));\n } else {\n ({ changed, inWorld } = solveTransform(state, c));\n }\n if (changed.length > 0) repose(state, changed, inWorld);\n snap(i, 'after');\n }\n // #969: the solver's last state — every bone's local values as the constraints left them — for a caller reading a dial off it (`./hooks.ts`).\n settled?.(state);\n return state.world;\n}\n\n/**\n * What `slotBonePlan` (`./constraints_path.ts`) and `frameUpdatedBefore` read\n * of a record: its kind and the names it orders — a name by value, a list by\n * identity. Every pass of a walk poses its records afresh (`posedRecords`,\n * `pathDeformed`, `stepPhysicsRecords` spread each one), and a spread carries\n * these lists over as the same arrays.\n */\nfunction planShape(c: CoreConstraintRecord): readonly unknown[] {\n switch (c.kind) {\n case 'slider':\n return [c.kind, c.timelines.bones];\n case 'ik':\n return [c.kind, c.target, c.bones];\n case 'physics':\n return [c.kind, c.bone];\n case 'transform':\n return [c.kind, c.source, c.bones];\n case 'path':\n return [c.kind, c.bones, c.slotDeps, c.slotBone];\n }\n}\n\n/** A plan kept per solver index, with the record shapes (`planShape`) and the skipped records it was built over. */\ninterface KeptPlan<T> {\n shapes: ReadonlyArray<readonly unknown[]>;\n skipped: readonly number[];\n plan: T;\n}\nconst slotBonePlans = new WeakMap<ReadonlyMap<string, number>, KeptPlan<Map<number, SlotBoneEvent | null>>>();\nconst frameUpdates = new WeakMap<ReadonlyMap<string, number>, KeptPlan<Map<number, boolean>>>();\n\n/**\n * A pass's ordering plan — `slotBonePlan` or `frameUpdatedBefore` — reused\n * from the pass before when nothing it reads has changed (issue #1179): the\n * bones' names and parents and the active set (one solver index stands for\n * those, `boneIndex`), each record's shape, and which records are skipped.\n * Otherwise built again. Both read names and nothing else, so a reused plan is\n * the plan the pass would have built; neither is written once built.\n */\nfunction keptPlan<T>(kept: WeakMap<ReadonlyMap<string, number>, KeptPlan<T>>, state: SolverState, records: readonly CoreConstraintRecord[], skipped: ReadonlySet<number>, build: () => T): T {\n const shapes = records.map(planShape);\n const skips = [...skipped];\n const last = kept.get(state.index);\n if (\n last !== undefined &&\n last.shapes.length === shapes.length &&\n shapes.every((sh, i) => sh.length === last.shapes[i].length && sh.every((v, j) => v === last.shapes[i][j])) &&\n last.skipped.length === skips.length &&\n skips.every((k, i) => k === last.skipped[i])\n ) {\n return last.plan;\n }\n const plan = build();\n kept.set(state.index, { shapes, skipped: skips, plan });\n return plan;\n}\n\n/** The last bone index each view's active set was asked for, with the names and parents it was built over (`boneIndex`). */\nconst indexOfView = new WeakMap<ReadonlySet<string>, { names: string[]; parents: Array<string | undefined>; index: Map<string, number> }>();\n\n/**\n * Each bone's position in `bones`, by name — the solver's index. Every pose of\n * a view lists the same bones in the same order (issue #1134: a walk built it\n * anew on each of its passes), so the index last built under the view's\n * active set (`activeBones`, one object per view) is reused when the names\n * and the parents agree position by position, and built again otherwise —\n * the parents because `repose` keeps each bone's subtree beside the index\n * (`subtreesOf`), and a subtree is a reading of them. Read, never written.\n */\nfunction boneIndex(bones: readonly ModelBone[], active: ReadonlySet<string>): Map<string, number> {\n const kept = indexOfView.get(active);\n if (kept !== undefined && kept.names.length === bones.length && bones.every((b, i) => b.name === kept.names[i] && b.parent === kept.parents[i])) return kept.index;\n const index = new Map(bones.map((b, i) => [b.name, i]));\n indexOfView.set(active, { names: bones.map((b) => b.name), parents: bones.map((b) => b.parent), index });\n return index;\n}\n\n/** Each bone's subtree as `subtreesOf` built it, kept per solver index (one object per view's bones, `boneIndex`). */\nconst subtreesOfIndex = new WeakMap<ReadonlyMap<string, number>, ReadonlyArray<readonly number[]>>();\n\n/**\n * For the bone at each position of `state.bones`, the positions of the bone\n * and of every bone below it, ascending (issue #1179). Bones are parents\n * first, so each position is appended to its own list and its ancestors' in\n * ascending order. Built from the bones' parents once per solver index —\n * `boneIndex` hands back one index only while the names and the parents are\n * the ones it was built over, and the other two solver states (`previousPassSlotBones`,\n * `historyTaint`) build an index of their own.\n */\nfunction subtreesOf(state: SolverState): ReadonlyArray<readonly number[]> {\n const kept = subtreesOfIndex.get(state.index);\n if (kept !== undefined) return kept;\n const lists: number[][] = state.bones.map(() => []);\n for (let k = 0; k < state.bones.length; k++) {\n let at: number | undefined = k;\n while (at !== undefined) {\n lists[at].push(k);\n const parent: string | undefined = state.bones[at].parent;\n at = parent === undefined ? undefined : state.index.get(parent);\n }\n }\n subtreesOfIndex.set(state.index, lists);\n return lists;\n}\n\n/** After a constraint: the bones it moved in world space read back into local values, and every bone below one it moved posed again (the header's update order). */\nfunction repose(state: SolverState, changed: readonly string[], inWorld: readonly string[]): void {\n for (const name of inWorld) {\n const b = bone(state, name);\n localFromWorld(b, parentWorld(state, b), state.world.get(name) as CoreWorld, state.rules);\n }\n // `changed` and `inWorld` are a constraint's few bones: read as they are rather than copied into sets on each of a walk's passes (issue #1134).\n const moved = changed;\n const below = new Set(changed);\n const keep = inWorld;\n // A bone joins `below` only through its parent, so the bones that can are the moved bones' subtrees: the walk visits those, in bone order (issue\n // #1179), where it visited every bone from the first one moved (issue #1134) — the bones it no longer visits are the ones whose parent `below`\n // could never hold, so each bone it does visit reads the same `below`, and is posed again in the same order.\n const subtrees = subtreesOf(state);\n const lists: Array<readonly number[]> = [];\n for (const name of changed) {\n const at = state.index.get(name);\n if (at !== undefined) lists.push(subtrees[at]);\n }\n const visit = lists.length === 1 ? lists[0] : [...new Set(lists.flat())].sort((x, y) => x - y);\n for (const k of visit) {\n const b = state.bones[k];\n // Not through an inactive bone the constraint did not move itself (issue #979): the bones below it keep what the constraints wrote into them.\n if (b.parent !== undefined && below.has(b.parent) && (!state.rules.inactiveHoldsItsWorld || state.active.has(b.parent) || moved.includes(b.parent))) below.add(b.name);\n if (below.has(b.name) && !keep.includes(b.name)) poseBone(state, b);\n }\n}\n\n/**\n * The slot bones a path constraint's offset reads from the PREVIOUS pass —\n * those the runtime has not brought up to date in this one by the time the\n * constraint runs (`./constraints_path.ts`, *Which slot bone*) — named with\n * their constraint. Only a constraint with an offset reads its slot bone.\n */\nexport function previousPassSlotBones(doc: CompiledDocument, active: ReadonlySet<string>): Array<{ constraint: string; bone: string }> {\n const records = doc.constraints.flatMap((c) => (c.record === undefined ? [] : [c.record]));\n if (!records.some((r) => r.kind === 'path')) return [];\n const state: SolverState = { bones: [...doc.bones], index: new Map(doc.bones.map((b, i) => [b.name, i])), world: new Map(), active, rules: RUNTIME_SOLVER_RULES };\n const skipped = new Set<number>();\n records.forEach((c, i) => {\n if (inactiveWhy(state, c) !== null) skipped.add(i);\n });\n const out: Array<{ constraint: string; bone: string }> = [];\n for (const [k, e] of slotBonePlan(doc.bones, active, records, skipped)) {\n const r = records[k] as CorePathRecord;\n if (e === null && r.offsetRotation !== 0) out.push({ constraint: r.name, bone: r.slotBone });\n }\n return out;\n}\n\n/**\n * Why an animation's bones cannot be posed by this cut though the setup's\n * can, or null: a path constraint's slot whose attachment an animation keys\n * — the curve would not be the one the setup reads, and a switch of the\n * walked curve is not measured — or a path attachment an animation deforms\n * whose placeholder several skins fill, so which record `--skin all` shows,\n * and whether the deform moves it, is the Spine file's skin order (under a\n * named skin one record resolves, `./skins.ts`). A deform\n * of a walked path is otherwise posed (`./deform.ts`, issue #955).\n */\nexport function pathAnimationsWhy(doc: CompiledDocument): string | null {\n const found: string[] = [];\n const paths = doc.constraints.flatMap((c) => (c.record?.kind === 'path' ? [c.record] : []));\n for (const a of doc.animations) {\n for (const r of paths) {\n if (a.timelines.slots.some((s) => s.name === r.slot && s.timelines.some((t) => t.kind === 'attachment'))) found.push(`animation \"${a.name}\" keys the attachment of slot \"${r.slot}\", which path constraint \"${r.name}\" walks — a switch of the walked curve is not measured`);\n }\n for (const d of a.deforms) {\n const [skin, slot, att] = d.split('/');\n const g = doc.skins.find((k) => k.name === skin)?.attachments[slot]?.[att]?.geometry;\n const fillers = fillingSkins(doc, slot, att).map((k) => `\"${k}\"`);\n if (g?.kind === 'path' && fillers.length > 1) found.push(`animation \"${a.name}\" deforms path attachment \"${att}\" (skin \"${skin}\", slot \"${slot}\"), a placeholder skins ${fillers.join(', ')} fill — which of them --skin all walks, and so whether the deform moves it, is the Spine file's skin order, not the model's`);\n }\n }\n return found.length === 0 ? null : found.join('; ');\n}\n\n/**\n * Why a document's bones cannot be posed by this cut, or null when they can:\n * a path constraint walks a slot whose setup placeholder skins fill with\n * different curves (`CorePathRecord.unresolved`), it declares a constraint\n * of a kind not admitted (`ADMITTED_CONSTRAINT_KINDS` — since the path cut,\n * none is left), named with the counts of every kind it declares, or a\n * slider whose animation keys a constraint timeline (`sliderBonesWhy`).\n */\nexport function constraintsAbsentWhy(doc: CompiledDocument, rules: Readonly<SolverRules> = RUNTIME_SOLVER_RULES): string | null {\n const unresolved = doc.constraints.flatMap((c) => (c.record?.kind === 'path' && c.record.unresolved !== null ? [c.record.unresolved] : []));\n if (unresolved.length > 0) return unresolved.join('; ');\n const later = doc.constraints.filter((c) => !ADMITTED_CONSTRAINT_KINDS.includes(c.kind));\n if (later.length === 0) return sliderBonesWhy(doc) ?? (rules.refuseHistoryLeak ? unposedLeakWhy(doc) : null);\n const kinds = [...new Set(doc.constraints.map((c) => c.kind))];\n const laterKinds = [...new Set(later.map((c) => c.kind))];\n return `the document declares ${kinds.map((k) => `${k} ×${doc.constraints.filter((c) => c.kind === k).length}`).join(', ')}, and ${laterKinds.join(', ')} constraints are not admitted (item 5; ${ADMITTED_CONSTRAINT_KINDS.join(', ')} are): the oracle applies them`;\n}\n\n/**\n * Why the core refuses a pose because a posed bone would read a value the\n * runtime makes depend on its previous pass, or null (issue #979, the\n * header's ⚠️ under *Unposed bones and collapsed frames*). A constraint that\n * writes into an inactive constrained bone — an ik reading a frame the pass\n * has not brought up to date (`frameUpdatedBefore`), a transform or a path —\n * taints that bone (and, for a world write or a two-bone ik's child, the\n * bones below it): the runtime's value there differs between a skeleton\n * posed sample after sample and a fresh one. A later constraint reading a\n * tainted bone — an ik's target, a transform's or a slider's source, a\n * path's slot bone or the bones weighting its curve — taints what it moves\n * when that is unposed too, and is refused by name when it moves a posed\n * bone: that is where the history would reach the picture. The rendered\n * value of an unposed bone is the seam's zero snapshot, so nothing else of\n * this class reaches a frame.\n */\nexport function unposedLeakWhy(doc: CompiledDocument): string | null {\n return historyTaint(doc).refusal;\n}\n\n/** A constraint writing into an inactive constrained bone — what a history-dependent value started from. */\nexport interface HistoryWriter {\n kind: CoreConstraintKind;\n name: string;\n inactive: string;\n}\n\n/**\n * The walk `unposedLeakWhy` reads: every bone a writer into an inactive bone\n * reaches, world or local, with its writer (the first, in constraint order),\n * and the refusal where a posed bone would read one — the walk stops there.\n * `tools/pose_oracle.ts unposed` classes a stepped bone-sample by it (no fresh\n * reading is taken under the step).\n */\nexport function historyTaint(doc: CompiledDocument): { refusal: string | null; tainted: Map<string, HistoryWriter> } {\n const records = doc.constraints.flatMap((c) => (c.record === undefined ? [] : [c.record]));\n const active = activeBones(doc);\n if (doc.bones.every((b) => active.has(b.name))) return { refusal: null, tainted: new Map() };\n const parent = new Map(doc.bones.map((b) => [b.name, b.parent]));\n const unposed = new Set<string>();\n for (const b of doc.bones) if (!active.has(b.name) || (b.parent !== undefined && unposed.has(b.parent))) unposed.add(b.name);\n const below = (root: string): string[] => doc.bones.filter((b) => {\n for (let at: string | undefined = b.name; at !== undefined; at = parent.get(at)) if (at === root) return true;\n return false;\n }).map((b) => b.name);\n const state: SolverState = { bones: [...doc.bones], index: new Map(doc.bones.map((b, i) => [b.name, i])), world: new Map(), active, rules: RUNTIME_SOLVER_RULES };\n const skipped = new Set<number>();\n records.forEach((c, i) => {\n if (inactiveWhy(state, c) !== null) skipped.add(i);\n });\n const updated = frameUpdatedBefore(doc.bones, active, records, skipped);\n // What of a bone the previous pass reaches: its world (read by a world-space source, an ik's target, a path's slot) or its local values (read by a local source).\n const world = new Map<string, HistoryWriter>();\n const local = new Map<string, HistoryWriter>();\n const spell = (w: HistoryWriter): string => `${w.kind} constraint \"${w.name}\" writes into inactive bone \"${w.inactive}\"`;\n const union = (): Map<string, HistoryWriter> => {\n const out = new Map(world);\n for (const [k, v] of local) if (!out.has(k)) out.set(k, v);\n return out;\n };\n const taint = (into: Map<string, HistoryWriter>, names: readonly string[], origin: HistoryWriter): void => {\n for (const n of names) if (!into.has(n)) into.set(n, origin);\n };\n const label = (c: CoreConstraintRecord): string => `${c.kind} constraint \"${c.name}\"`;\n for (let i = 0; i < records.length; i++) {\n if (skipped.has(i)) continue;\n const c = records[i];\n const moved = c.kind === 'physics' ? [c.bone] : c.kind === 'slider' ? c.timelines.bones.map((t) => t.name) : c.bones;\n const readsLocal = (c.kind === 'transform' && c.localSource) || (c.kind === 'slider' && c.local);\n const operands = c.kind === 'ik' ? [c.target] : c.kind === 'transform' ? [c.source] : c.kind === 'path' ? [c.slotBone, ...c.slotDeps] : c.kind === 'slider' ? (c.bone === null ? [] : [c.bone]) : [];\n const from = readsLocal ? local : world;\n const read = operands.find((o) => from.has(o));\n if (read !== undefined) {\n const posed = moved.find((b) => !unposed.has(b));\n const origin = from.get(read) as HistoryWriter;\n if (posed !== undefined) return { refusal: `${label(c)} moves posed bone \"${posed}\" and reads ${readsLocal ? 'the local values' : 'the world transform'} of bone \"${read}\", a bone whose value depends on the runtime's previous pass (${spell(origin)}) — the runtime's own sample-after-sample and fresh-skeleton readings disagree there, so there is no one value to pose`, tainted: union() };\n taint(world, moved.flatMap(below), origin);\n taint(local, moved, origin);\n }\n const inactive = moved.find((b) => !active.has(b));\n if (inactive === undefined || c.kind === 'physics' || c.kind === 'slider') continue;\n const origin: HistoryWriter = { kind: c.kind, name: c.name, inactive };\n if (c.kind === 'ik') {\n // Its local values move; for a two-bone ik the child's, and with them the world of the child and the bones below it.\n if (updated.get(i) !== false) continue;\n taint(local, c.bones, origin);\n if (c.bones.length > 1) taint(world, below(c.bones[1]), origin);\n } else if (c.kind === 'transform' && c.localTarget) taint(local, moved, origin);\n else {\n // A world write: the bones moved and every bone below them, in world; their own local values read back from it.\n taint(world, moved.flatMap(below), origin);\n taint(local, moved, origin);\n }\n }\n return { refusal: null, tainted: union() };\n}\n","/**\n * Construct 4 of the core (issue #936, step 2d of issue #380): an animation's\n * bone and slot timelines at a sample time — the key search, the curve as the\n * runtime evaluates it, and every bone and slot timeline kind — posed on the\n * setup pose with the animation alone at full weight, the way the oracle\n * samples one (`tools/pose_oracle.ts`, *How a pose is posed*: the setup pose,\n * then the animation applied at `t` with alpha 1 from the setup pose, then the\n * world transforms).\n *\n * Every rule below was measured by posing a hand-written skeleton through\n * `tools/pose_oracle.ts dump` (spine-core 4.3.13) and reading the rows it\n * printed; nothing here was written from the runtime's source. The core\n * suite's `CA` controls hold the same skeletons against the core at tolerance\n * 0, and `tools/core_gate.ts` holds every recipe of the tree's corpus.\n *\n * ## The key search\n *\n * A timeline's value at `t` comes from the LAST key whose time is at or\n * before `t`. Measured on a `translatex` keyed at 0.5, 1 and 1.5 on a bone at\n * setup `x` 5, sampled on a grid of quarter seconds over 2 s:\n *\n * - **Before the first key the channel is at its setup value** — `x` read 5\n * at 0 and 0.25. ⚠️ Not \"untouched\": the timeline POSES the setup value. A\n * bone keyed by `translate` (0 → 10, 2 → 20) and by a `translatex` whose\n * first key is at 1 read `x` = setup (1, not 11) before 1 when `translatex`\n * is listed after `translate`, and 11 when it is listed before — each\n * timeline, in the animation's order, writes its channels at every time.\n * - **On a key exactly, that key** — a stepped key at 0.5 (value 10) followed\n * by a key at 1 (value 30) read 30 at t = 1, not 10.\n * - **At and after the last key, the last key's value** — 45 (setup 5 + 40)\n * at 1.5, 1.75 and 2.\n * - Key times are compared as the runtime stores them, float32\n * (`Math.fround`), against the sample time as a double; key values are read\n * as float32 too. A linear segment from (0, 0) to (0.4666667, 100000)\n * sampled at `off` read 12500, 37500, 62500, 87500 exactly — the key time\n * and the duration both the float32 0.46666669845581055; the double\n * 0.4666667 would have read 4.1e-5 to 2.9e-4 higher.\n *\n * ## The three curves, per segment\n *\n * A key's `curve` shapes the segment from it to the next key.\n *\n * - **None — linear**: `v0 + (t − t0) / (t1 − t0) · (v1 − v0)`, per channel.\n * - **`stepped`**: the key's own value until the next key's time.\n * - **Bézier** — four absolute numbers per channel, `cx1, cy1, cx2, cy2`, the\n * two handles of the cubic from `(t0, v0)` to `(t1, v1)` (the format's\n * documentation: a curve's control points are in the timeline's own time and\n * value). ⭐ **The runtime does not evaluate the cubic.** Posed on one bone,\n * one `translatex` from (0, 0) to (1, 1000) with handles (0.1, 800) and\n * (0.3, 1000), 2,000 `dense` samples read BELOW the exact cubic solved for\n * `t` at every interior sample, by up to 10.34 — the residual of chords\n * under a concave curve — and the slopes between consecutive samples fall\n * into exactly ten runs whose nine intersections are the cubic's points at\n * the parameter `u = 0.1, 0.2, …, 0.9` (to the fourth decimal of `t`). So\n * the curve is the POLYLINE through the key, the cubic's nine points at\n * tenths of its parameter, and the next key, and a sample is interpolated\n * linearly on the piece whose end is the first point at or after `t`.\n *\n * **The nine points, to the last float32 step.** They are stored float32,\n * and which float32 each lands on was fixed by two measurements, both with\n * the samples of spine-core's dump as the judge at the oracle's rounding:\n *\n * 1. *The recurrence.* Over 60 random segments whose every number was\n * already a float32 (82,731 samples), the cubic's tenths evaluated\n * directly missed 866 samples: each miss a point one float32 step off,\n * where the exact double lay within a few hundredths of a step of a\n * rounding midpoint — so the runtime's points carry a relative error\n * near 1e-9 before the rounding. Forward differencing the cubic at the\n * step h = 1/10 (the textbook recurrence: each point the previous plus a\n * first difference, which grows by a second, which grows by a third)\n * reproduces that error exactly when the third difference's one-sixth\n * is the eight-digit decimal `0.16666667`: 0 misses. With 1/6 exact it\n * missed 867, with 1/6 as a float32 1,694; a recurrence whose running\n * sums are float32 missed more than any.\n * 2. *The numbers it runs on.* Over 300 of the 8,145 Bézier channel\n * segments in the 19 recipes' bone timelines, each re-posed alone\n * (18,430 samples), the recurrence above missed 4,145 samples when run\n * on the key times, values and handles as float32 — and 0 when run on\n * the numbers AS THE FILE STATES THEM (the doubles its text parses to),\n * with only the polyline's two ends, the keys themselves, float32. The\n * mixed readings missed 2,479 (handles stated, keys float32), 2,587\n * (keys stated, handles float32) and 1,054 (the ends stated too). The\n * first population could not tell these apart because its numbers were\n * float32 to begin with; the model's numbers are float32 SHORTEST NAMES\n * (`f32` in `src/compile.ts`), whose doubles are not the float32 itself.\n *\n * So a key keeps both (`CoreKey.stated` and its float32 `time`/`values`),\n * and `bezierPolyline` is the recurrence over the stated numbers. The core\n * suite's `CA02` holds the measurement and every rejected reading missing.\n *\n * ## The bone timelines — alpha 1 from the setup pose\n *\n * Measured on bones with non-trivial setup values:\n *\n * - `rotate` ADDS to the setup rotation: setup 20, keys 350 → 10 read a world\n * x axis at 10° at t = 0 and at 200° (−160°) half way — the value is\n * interpolated as a number, 350 → 10 passing 180, and never wrapped to the\n * short way round.\n * - `translate`, `translatex`, `translatey` ADD to the setup position.\n * - `scale`, `scalex`, `scaley` MULTIPLY the setup scale: setup (2, 0.5) and a\n * key (3, 1) read (6, 0.5); a negative key or setup multiplies through\n * (setup −2, keys −1 → 3 read 2 → −6 through 0).\n * - `shear`, `shearx`, `sheary` ADD to the setup shear.\n * - `inherit` sets the bone's inherit mode, stepped by the format: before its\n * first key the setup mode, from each key that key's mode (measured\n * `normal → onlyTranslation → normal` under a rotated, scaled parent).\n *\n * The posed values replace the setup values in a copy of the bone and the\n * core's own evaluator (`worldTransforms`, `./world.ts`) poses the copies.\n *\n * ## The slot timelines\n *\n * - `attachment`: stepped by nature; before its first key the setup\n * attachment, from a key its placeholder, resolved exactly as the setup\n * placeholder is (`shownAttachment`), a placeholder no skin fills and a\n * `null` name both showing nothing.\n * - `rgba`, `rgb`, `alpha`, `rgba2`, `rgb2` SET the channels they name (they do\n * not add to or scale the setup colour) and leave every other channel at\n * setup: `rgb` keeps the setup alpha, `alpha` the setup rgb; `rgba2` and\n * `rgb2` set the dark colour too. A key's hex pair reads as its byte over 255\n * and is stored float32, as every key value is.\n * - **Every colour channel is clamped to [0, 1] after the curve**: an `rgba`\n * whose green curve dips below 0 and whose red curve rises above 1 read 0\n * and 1 there.\n * - 🚫 **`rgba2` or `rgb2` on a slot with no dark colour is refused.** Posed\n * through the runtime, such a timeline throws while the animation is\n * applied (`TypeError`), so no dump exists to hold a core to; the compiler\n * refuses the same timeline before any file is written (`compileTrack`).\n *\n * ## The duration and the sample times\n *\n * The oracle's sample times are the tool's formula (`sampleTime`, which the\n * tool calls here, as it rounds with `gridRound`), over the runtime's\n * duration of the animation: the LAST key time of every timeline in it — the\n * later constructs' (constraints, deform, sequence, draw order, events)\n * included — as float32, not the model's declared `duration`. Measured: a\n * rotate ending at 1 beside an event at 2.5, the model stating 0, sampled over\n * 2.5 in spine-core's dump (`CA09`); over the 54 animations of the 19 recipes,\n * every duration agreed.\n *\n * ## What is left out, by name\n *\n * The constraints are applied after the timelines, posed by their own\n * timelines at `t` (issue #938, `./constraints.ts`), and each slider's slot\n * timelines after the sample's own (`./constraints_slider.ts`); a document\n * whose setup bones are absent has no animation bones from the core, for the\n * same reason, and neither has one whose animation keys the attachment of a\n * walked path's slot, deforms a walked path whose placeholder several skins\n * fill, or whose path offset reads a slot bone from the previous pose that\n * changes its reflection (`./constraints_path.ts`); a slider whose animation\n * keys a slot on such a document, or a placeholder skins fill differently,\n * leaves the animation slots out as they leave the setup slots out.\n *\n * ## The rest of a sample (issue #955)\n *\n * The oracle's sample carries `drawOrder`, `attachments`, `clips` and\n * `events` too, and since issue #955 the core poses each: the draw order\n * (`./draw_order.ts`), every drawn attachment's and clipping polygon's world\n * vertices through the sample's bones, in that order, with what the deform\n * and sequence timelines set on them (`./deform.ts`), and the events fired\n * since the sample before (`./events.ts`); each module's header states its\n * rules with the measurements. A path walks the curve the sample's deform\n * timelines left on its slot (`pathDeformed`). The attachments and clips are\n * absent where the bones or the slots are, and the attachments where a shown\n * region's rectangle is `null` or a timeline moves a record several skins\n * fill; the draw order where a slider keys it on a document whose bones are\n * absent.\n */\nimport type { ModelBone, ModelSlot } from '../model.ts';\nimport { readAttachmentTimelines, type CoreAttachmentTimeline } from './deform.ts';\nimport { readDrawOrderKeys, type CoreDrawOrderKey } from './draw_order.ts';\nimport { readEventKeys, type CoreEventDef, type CoreEventKey } from './events.ts';\nimport { worldTransforms } from './world.ts';\nimport { applyConstraints, constraintsAbsentWhy, pathAnimationsWhy, posedRecords, previousPassSlotBones, solverRules, type CoreConstraintRecord, type CoreConstraintTimelines } from './constraints.ts';\nimport { attachmentStates, deformAt, deformedVertices, timelineIdentity } from './deform.ts';\nimport { freshStepContext, stepPhysicsRecords, stepSchedule, steppedPreviousPassWhy, type PhysicsStepContext } from './constraints_physics.ts';\nimport { drawOrderAt } from './draw_order.ts';\nimport { eventsFired, type CoreEventRow } from './events.ts';\nimport { poseGeometry, type CoreAttachmentRow, type CoreClipRow } from './vertices.ts';\nimport type { CoreClippedRow } from './clipping.ts';\nimport type { CoreWorld } from './world.ts';\nimport { applySliderSlots, type SliderApplication } from './constraints_slider.ts';\nimport { slotTimelinesApply } from './skins.ts';\nimport {\n activeBones,\n constraintRecords,\n CoreInputError,\n drawWalkOf,\n foldInheritMode,\n gridRound,\n readBlend,\n readColour,\n shownAttachment,\n shownRow,\n slidersKeyingWhy,\n sourceOfDoc,\n type CompiledDocument,\n type CoreAnimation,\n type CoreBoneRow,\n type CorePlant,\n type CoreSkin,\n type CoreSlotRow,\n} from './index.ts';\n\n/** The bone timelines that key numbers, and the channels each key carries, in the order a curve indexes them. */\nexport const BONE_TIMELINE_CHANNELS = {\n rotate: ['value'],\n translate: ['x', 'y'],\n translatex: ['value'],\n translatey: ['value'],\n scale: ['x', 'y'],\n scalex: ['value'],\n scaley: ['value'],\n shear: ['x', 'y'],\n shearx: ['value'],\n sheary: ['value'],\n} as const satisfies Record<string, readonly string[]>;\nexport type BoneNumberKind = keyof typeof BONE_TIMELINE_CHANNELS;\n\n/** Every bone timeline this construct poses: the ten that key numbers, and `inherit`. */\nexport const BONE_TIMELINE_KINDS = [...(Object.keys(BONE_TIMELINE_CHANNELS) as BoneNumberKind[]), 'inherit'] as const;\nexport type BoneTimelineKind = (typeof BONE_TIMELINE_KINDS)[number];\n\n/**\n * The slot timelines that key a colour: the key fields the writer spells each\n * with (`COLOUR_KEYS` in `src/compile.ts`), each field's hex length, and the\n * channels they carry, in the order a curve indexes them.\n */\nexport const SLOT_COLOUR_TIMELINES = {\n rgba: { fields: [['color', 8]], channels: ['r', 'g', 'b', 'a'] },\n rgb: { fields: [['color', 6]], channels: ['r', 'g', 'b'] },\n alpha: { fields: [], channels: ['a'] },\n rgba2: { fields: [['light', 8], ['dark', 6]], channels: ['r', 'g', 'b', 'a', 'r2', 'g2', 'b2'] },\n rgb2: { fields: [['light', 6], ['dark', 6]], channels: ['r', 'g', 'b', 'r2', 'g2', 'b2'] },\n} as const satisfies Record<string, { fields: ReadonlyArray<readonly [string, number]>; channels: readonly string[] }>;\nexport type SlotColourKind = keyof typeof SLOT_COLOUR_TIMELINES;\n\n/** Every slot timeline this construct poses. */\nexport const SLOT_TIMELINE_KINDS = ['attachment', ...(Object.keys(SLOT_COLOUR_TIMELINES) as SlotColourKind[])] as const;\nexport type SlotTimelineKind = (typeof SLOT_TIMELINE_KINDS)[number];\n\n/**\n * The groups of an animation after its bones and slots, in the document's\n * order: the constraint timelines (construct 5, `./constraints.ts`) and this\n * construct's remainder — attachment timelines (`./deform.ts`), the draw\n * order (`./draw_order.ts`) and events (`./events.ts`). Every key time in\n * them sets the runtime's duration.\n */\nexport const LATER_GROUPS = ['constraints', 'attachments', 'drawOrder', 'events'] as const;\n\n/** A key's curve as read: linear, a hold, or four float32 numbers per channel. */\nexport type CoreCurve = 'linear' | 'stepped' | number[];\n\n/**\n * One key, as read: its time and channels as the runtime stores them\n * (float32), the same two as the document states them (the doubles the file's\n * text parses to — what a Bézier's polyline is computed from, the header's\n * measurement), its curve, and a name or mode where the kind keys one.\n */\nexport interface CoreKey {\n time: number;\n values: number[];\n stated: { time: number; values: number[] };\n curve: CoreCurve;\n /** An attachment key's placeholder (`null` shows nothing). */\n name?: string | null;\n /** An inherit key's mode, folded. */\n mode?: string;\n}\n\nexport interface CoreTimeline<K extends string> {\n kind: K;\n keys: CoreKey[];\n}\n\nexport interface CoreTarget<K extends string> {\n name: string;\n timelines: Array<CoreTimeline<K>>;\n}\n\n/**\n * One animation's timelines, as far as this construct reads them: the bone\n * and slot timelines in full, and of every later group only how many\n * timelines it holds and its key times (which set the runtime's duration).\n */\nexport interface CoreAnimationTimelines {\n /** The model's declared duration. */\n declared: number;\n /** The runtime's duration: the last key time of every timeline, as float32 — the header's rule. */\n duration: number;\n bones: Array<CoreTarget<BoneTimelineKind>>;\n slots: Array<CoreTarget<SlotTimelineKind>>;\n /** Timelines per later group, in `LATER_GROUPS` order; a group holding none is not listed. */\n later: Array<[(typeof LATER_GROUPS)[number], number]>;\n /** The deform and sequence timelines, each attachment's (`./deform.ts`). */\n attachments: CoreAttachmentTimeline[];\n /** The draw-order keys (`./draw_order.ts`); empty where the animation keys none. */\n drawOrder: CoreDrawOrderKey[];\n /** The event keys (`./events.ts`); empty where the animation fires none. */\n events: CoreEventKey[];\n}\n\nconst isRecord = (v: unknown): v is Record<string, unknown> => typeof v === 'object' && v !== null && !Array.isArray(v);\nconst isHex = (v: unknown, digits: number): v is string => typeof v === 'string' && v.length === digits && /^[0-9a-fA-F]+$/.test(v);\n\n/** A key's time: finite, not negative, float32 as the runtime stores it — or a problem. */\nfunction keyTime(raw: Record<string, unknown>, where: string, problems: string[]): number | null {\n const time = raw.time;\n if (typeof time !== 'number' || !Number.isFinite(time) || time < 0) {\n problems.push(`${where}: time is ${JSON.stringify(time)}, not a finite time at or after 0`);\n return null;\n }\n return time;\n}\n\n/** A list of keys, each an object with a strictly later time than the one before — the writer's rule. */\nfunction keyList(value: unknown, where: string, problems: string[]): Array<{ raw: Record<string, unknown>; at: string; time: number }> {\n if (!Array.isArray(value) || value.length === 0) {\n problems.push(`${where}: keys is not a non-empty list`);\n return [];\n }\n const out: Array<{ raw: Record<string, unknown>; at: string; time: number }> = [];\n let last = -Infinity;\n value.forEach((raw, i) => {\n const at = `${where}.keys[${i}]`;\n if (!isRecord(raw)) {\n problems.push(`${at} is not an object`);\n return;\n }\n const time = keyTime(raw, at, problems);\n if (time === null) return;\n if (time <= last) problems.push(`${at}: time ${raw.time} is not after the key before it — the writer refuses key times that do not strictly increase`);\n last = Math.max(last, time);\n out.push({ raw, at, time });\n });\n return out;\n}\n\nfunction unknownKeyFields(raw: Record<string, unknown>, known: readonly string[], at: string, problems: string[]): void {\n for (const key of Object.keys(raw)) if (!known.includes(key)) problems.push(`${at}: field \"${key}\" is not one this timeline's keys carry; they carry [${known.join(', ')}]`);\n}\n\n/** A key's curve: absent (linear), `stepped`, or 4 finite numbers per channel; never on the last key. */\nfunction readCurve(raw: Record<string, unknown>, channels: number, last: boolean, at: string, problems: string[]): CoreCurve {\n const curve = raw.curve;\n if (curve === undefined) return 'linear';\n if (last) {\n problems.push(`${at}: the last key carries a curve, which eases to no key — the writer refuses it`);\n return 'linear';\n }\n if (curve === 'stepped') return 'stepped';\n if (!Array.isArray(curve) || curve.length !== channels * 4 || !curve.every((n) => typeof n === 'number' && Number.isFinite(n))) {\n problems.push(`${at}: curve is ${JSON.stringify(curve)}, not \"stepped\" nor ${channels * 4} finite numbers (four per channel)`);\n return 'linear';\n }\n return curve as number[];\n}\n\nfunction readBoneTimeline(kind: BoneTimelineKind, keysValue: unknown, where: string, problems: string[]): CoreKey[] {\n const listed = keyList(keysValue, where, problems);\n return listed.map(({ raw, at, time }, i): CoreKey => {\n if (kind === 'inherit') {\n unknownKeyFields(raw, ['time', 'inherit'], at, problems);\n const mode = typeof raw.inherit === 'string' ? foldInheritMode(raw.inherit) : null;\n if (mode === null) problems.push(`${at}: inherit is ${JSON.stringify(raw.inherit)}, which folds to no inherit mode`);\n return { time: Math.fround(time), values: [], stated: { time, values: [] }, curve: 'stepped', mode: mode ?? 'normal' };\n }\n const channels: readonly string[] = BONE_TIMELINE_CHANNELS[kind];\n unknownKeyFields(raw, ['time', ...channels, 'curve'], at, problems);\n const values = channels.map((c) => {\n const v = raw[c];\n if (typeof v !== 'number' || !Number.isFinite(v)) {\n problems.push(`${at}: ${c} is ${JSON.stringify(v)}, not a finite number — the writer states every channel on every key`);\n return 0;\n }\n return v;\n });\n return { time: Math.fround(time), values: values.map(Math.fround), stated: { time, values }, curve: readCurve(raw, channels.length, i === listed.length - 1, at, problems) };\n });\n}\n\n/** A hex spelling's channels, each byte over 255 (the stated values; the runtime stores each float32). */\nfunction hexChannels(hex: string, count: number): number[] {\n const out: number[] = [];\n for (let i = 0; i < count; i++) out.push(Number.parseInt(hex.slice(2 * i, 2 * i + 2), 16) / 255);\n return out;\n}\n\nfunction readSlotTimeline(kind: SlotTimelineKind, keysValue: unknown, where: string, problems: string[]): CoreKey[] {\n const listed = keyList(keysValue, where, problems);\n return listed.map(({ raw, at, time }, i): CoreKey => {\n if (kind === 'attachment') {\n unknownKeyFields(raw, ['time', 'name'], at, problems);\n if (raw.name !== null && (typeof raw.name !== 'string' || raw.name === '')) problems.push(`${at}: name is ${JSON.stringify(raw.name)}, not a placeholder name or null`);\n return { time: Math.fround(time), values: [], stated: { time, values: [] }, curve: 'stepped', name: typeof raw.name === 'string' ? raw.name : null };\n }\n const shape: { fields: ReadonlyArray<readonly [string, number]>; channels: readonly string[] } = SLOT_COLOUR_TIMELINES[kind];\n let values: number[] = [];\n if (kind === 'alpha') {\n unknownKeyFields(raw, ['time', 'value', 'curve'], at, problems);\n const v = raw.value;\n if (typeof v !== 'number' || !Number.isFinite(v)) problems.push(`${at}: value is ${JSON.stringify(v)}, not a finite number`);\n else values = [v];\n } else {\n unknownKeyFields(raw, ['time', ...shape.fields.map(([f]) => f), 'curve'], at, problems);\n for (const [field, digits] of shape.fields) {\n const v = raw[field];\n if (!isHex(v, digits)) problems.push(`${at}: ${field} is ${JSON.stringify(v)}, not ${digits} hex digits — the one spelling the writer gives a ${kind} key's ${field}`);\n else values.push(...hexChannels(v, field === 'dark' || digits === 6 ? 3 : 4));\n }\n }\n if (values.length !== shape.channels.length) values = shape.channels.map(() => 0);\n return { time: Math.fround(time), values: values.map(Math.fround), stated: { time, values }, curve: readCurve(raw, shape.channels.length, i === listed.length - 1, at, problems) };\n });\n}\n\n/** Every key time under an animation's `constraints` group, for the runtime's duration; a time that is not a finite number is a problem. */\nfunction constraintKeyTimes(value: unknown, where: string, problems: string[]): { timelines: number; times: number[] } {\n const times: number[] = [];\n let timelines = 0;\n const keys = (list: unknown, at: string): void => {\n timelines++;\n if (!Array.isArray(list)) {\n problems.push(`${at} is not a list of keys`);\n return;\n }\n list.forEach((k, i) => {\n if (!isRecord(k)) problems.push(`${at}[${i}] is not an object`);\n else {\n const t = keyTime(k, `${at}[${i}]`, problems);\n if (t !== null) times.push(Math.fround(t));\n }\n });\n };\n const named = (list: unknown, at: string, each: (entry: Record<string, unknown>, at: string) => void): void => {\n if (!Array.isArray(list)) {\n problems.push(`${at} is not a list`);\n return;\n }\n list.forEach((entry, i) => (isRecord(entry) ? each(entry, `${at}[${i}]`) : problems.push(`${at}[${i}] is not an object`)));\n };\n if (!isRecord(value)) problems.push(`${where} is not an object`);\n else {\n for (const kind of ['ik', 'transform'] as const) named(value[kind], `${where}.${kind}`, (e, at) => keys(e.keys, `${at}.keys`));\n for (const kind of ['path', 'physics', 'slider'] as const) named(value[kind], `${where}.${kind}`, (e, at) => named(e.timelines, `${at}.timelines`, (tl, at2) => keys(tl.keys, `${at2}.keys`)));\n }\n return { timelines, times };\n}\n\n/**\n * One animation record's timelines, read and checked: every bone and slot\n * timeline in full — a target that is not a bone or slot of the document, a\n * kind that is not one of this construct's, a kind keyed twice on one target,\n * a key missing a channel or spelling one otherwise than the writer does, a\n * curve of the wrong length or on the last key, times that do not increase,\n * and `rgba2`/`rgb2` on a slot with no dark colour are each a problem, named —\n * and of the later groups only their key times.\n */\nexport function readAnimationTimelines(\n raw: Record<string, unknown>,\n label: string,\n bones: ReadonlySet<string>,\n slots: readonly ModelSlot[],\n problems: string[],\n context: { skins: readonly CoreSkin[]; events: ReadonlyMap<string, CoreEventDef> },\n): CoreAnimationTimelines {\n const declared = typeof raw.duration === 'number' && Number.isFinite(raw.duration) ? raw.duration : 0;\n if (typeof raw.duration !== 'number' || !Number.isFinite(raw.duration)) problems.push(`${label}: duration is ${JSON.stringify(raw.duration)}, not a finite number`);\n const slotByName = new Map(slots.map((s) => [s.name, s]));\n const times: number[] = [];\n const targets = <K extends string>(group: 'bones' | 'slots', kinds: readonly K[], known: (name: string) => string | null, read: (kind: K, keys: unknown, at: string, target: string) => CoreKey[]): Array<CoreTarget<K>> => {\n const value = raw[group];\n const out: Array<CoreTarget<K>> = [];\n if (!Array.isArray(value)) {\n problems.push(`${label}: ${group} is not a list`);\n return out;\n }\n value.forEach((entry, i) => {\n const at = `${label}.${group}[${i}]`;\n if (!isRecord(entry) || typeof entry.name !== 'string') {\n problems.push(`${at} names no target`);\n return;\n }\n const where = `${at} \"${entry.name}\"`;\n const miss = known(entry.name);\n if (miss !== null) problems.push(`${where}: ${miss}`);\n if (!Array.isArray(entry.timelines)) {\n problems.push(`${where}: timelines is not a list`);\n return;\n }\n const name = entry.name;\n const target: CoreTarget<K> = { name, timelines: [] };\n entry.timelines.forEach((tl, j) => {\n const tat = `${where}.timelines[${j}]`;\n if (!isRecord(tl) || typeof tl.name !== 'string') {\n problems.push(`${tat} names no timeline`);\n return;\n }\n const kind = kinds.find((k) => k === tl.name);\n if (kind === undefined) {\n problems.push(`${tat}: \"${tl.name}\" is not a ${group === 'bones' ? 'bone' : 'slot'} timeline this core reads; it reads [${kinds.join(', ')}]`);\n return;\n }\n if (target.timelines.some((x) => x.kind === kind)) problems.push(`${tat}: \"${kind}\" is keyed twice on ${name} — the writer merges one property's tracks into one`);\n const keys = read(kind, tl.keys, `${tat} \"${kind}\"`, name);\n for (const k of keys) times.push(k.time);\n target.timelines.push({ kind, keys });\n });\n out.push(target);\n });\n return out;\n };\n const boneTargets = targets('bones', BONE_TIMELINE_KINDS, (n) => (bones.has(n) ? null : `\"${n}\" is not a bone of this document`), (kind, keys, at) => readBoneTimeline(kind, keys, at, problems));\n const slotTargets = targets('slots', SLOT_TIMELINE_KINDS, (n) => (slotByName.has(n) ? null : `\"${n}\" is not a slot of this document`), (kind, keys, at, slot) => {\n if ((kind === 'rgba2' || kind === 'rgb2') && slotByName.get(slot)?.dark === undefined) {\n problems.push(`${at}: slot \"${slot}\" states no dark colour, and a ${kind} timeline on such a slot makes the runtime throw while it is applied — the writer refuses it`);\n }\n return readSlotTimeline(kind, keys, at, problems);\n });\n const later: CoreAnimationTimelines['later'] = [];\n // The constraint timelines' key times only (construct 5 reads them, `./constraints.ts`); the other three groups are read in full here.\n const constraintTimes = constraintKeyTimes(raw.constraints, `${label}.constraints`, problems);\n times.push(...constraintTimes.times);\n if (constraintTimes.timelines > 0) later.push(['constraints', constraintTimes.timelines]);\n const attachments = readAttachmentTimelines(raw.attachments, label, context.skins, problems);\n const drawOrder = readDrawOrderKeys(raw.drawOrder, label, slots, problems);\n const events = readEventKeys(raw.events, label, context.events, problems);\n for (const a of attachments) for (const k of [...(a.deform ?? []), ...(a.sequence ?? [])]) times.push(k.time);\n for (const k of [...drawOrder, ...events]) times.push(k.time);\n const attachmentTimelines = attachments.reduce((n, a) => n + (a.deform === null ? 0 : 1) + (a.sequence === null ? 0 : 1), 0);\n if (attachmentTimelines > 0) later.push(['attachments', attachmentTimelines]);\n if (drawOrder.length > 0) later.push(['drawOrder', 1]);\n if (events.length > 0) later.push(['events', 1]);\n return { declared, duration: times.length === 0 ? 0 : Math.max(...times), bones: boneTargets, slots: slotTargets, later, attachments, drawOrder, events };\n}\n\n// ---------------------------------------------------------------------------\n// evaluation\n// ---------------------------------------------------------------------------\n\n/**\n * The one-sixth of the third forward difference, as the header measured it:\n * the eight-digit decimal, which alone of the spellings tried reproduced\n * 82,731 samples of 60 random Bézier segments and 18,430 of 300 corpus\n * segments at the oracle's rounding.\n */\nexport const BEZIER_SIXTH = 0.16666667;\n/** Pieces of the runtime's polyline per Bézier segment — the header's ten slope runs. */\nexport const BEZIER_PIECES = 10;\n\n/**\n * The nine interior points of one channel's Bézier segment, `[t1, v1, …, t9,\n * v9]`, each float32: the cubic from `(t0, v0)` through the handles to `(t3,\n * v3)` — every one of the eight the number the document states, not its\n * float32 (the header's second measurement) — at its parameter `u = 0.1 …\n * 0.9`, by forward differences at the step\n * h = 1/10. With `p` the four control numbers of one coordinate, the second\n * difference is `3h²(p0 − 2p1 + p2)` and the third `6h³(3(p1 − p2) − p0 + p3)`;\n * the first starts at `3h(p1 − p0)` plus the second plus the third times\n * `BEZIER_SIXTH`; each step adds the first to the point, the second to the\n * first and the third to the second (the header's measurement fixes the\n * order of those additions and the constant).\n */\nexport function bezierPolyline(t0: number, v0: number, cx1: number, cy1: number, cx2: number, cy2: number, t3: number, v3: number): number[] {\n const walk = (p0: number, p1: number, p2: number, p3: number): number[] => {\n const second = (p0 - 2 * p1 + p2) * 0.03;\n const third = ((p1 - p2) * 3 - p0 + p3) * 0.006;\n let first = (p1 - p0) * 0.3 + second + third * BEZIER_SIXTH;\n let d2 = second * 2 + third;\n let at = p0;\n const out: number[] = [];\n for (let i = 1; i < BEZIER_PIECES; i++) {\n at += first;\n first += d2;\n d2 += third;\n out.push(Math.fround(at));\n }\n return out;\n };\n const ts = walk(t0, cx1, cx2, t3);\n const vs = walk(v0, cy1, cy2, v3);\n const out: number[] = [];\n for (let i = 0; i < ts.length; i++) out.push(ts[i], vs[i]);\n return out;\n}\n\n/** What evaluates one channel of a segment: `channelAt` unless a plant passes another. */\nexport type ChannelEvaluator = (keys: readonly CoreKey[], index: number, channel: number, t: number) => number;\n\n/** What finds the key a time falls on: `keyIndexAt` unless a plant passes another. */\nexport type KeySearch = (keys: readonly CoreKey[], t: number) => number;\n\n/** The last key at or before `t`, or −1 before the first — the header's key search. */\nexport function keyIndexAt(keys: ReadonlyArray<{ time: number }>, t: number): number {\n let found = -1;\n for (let i = 0; i < keys.length; i++) {\n if (keys[i].time <= t) found = i;\n else break;\n }\n return found;\n}\n\n/**\n * Each Bézier segment's polylines, one per channel, kept with the key that\n * starts the segment and the key that ends it (issue #1134): a polyline is a\n * function of those two keys' stated numbers and handles only, and a walk\n * evaluated the same segment's on every step. A key read is never written; a\n * plant that changes a key passes a copy, which keeps polylines of its own.\n */\nconst segmentPolylines = new WeakMap<CoreKey, { end: CoreKey; channels: Array<number[] | undefined> }>();\n\n/** Channel `channel` of the segment starting at key `index` (not the last), at `t` — the header's three curves. */\nexport function channelAt(keys: readonly CoreKey[], index: number, channel: number, t: number): number {\n const a = keys[index];\n const b = keys[index + 1];\n if (b === undefined || a.curve === 'stepped') return a.values[channel];\n if (a.curve === 'linear') return a.values[channel] + ((t - a.time) / (b.time - a.time)) * (b.values[channel] - a.values[channel]);\n let kept = segmentPolylines.get(a);\n if (kept === undefined || kept.end !== b) {\n kept = { end: b, channels: [] };\n segmentPolylines.set(a, kept);\n }\n let points = kept.channels[channel];\n if (points === undefined) {\n const c = a.curve.slice(channel * 4, channel * 4 + 4);\n const inner = bezierPolyline(a.stated.time, a.stated.values[channel], c[0], c[1], c[2], c[3], b.stated.time, b.stated.values[channel]);\n points = [a.time, a.values[channel], ...inner, b.time, b.values[channel]];\n kept.channels[channel] = points;\n }\n let i = 2;\n while (i < points.length - 2 && points[i] < t) i += 2;\n const [x0, y0, x1, y1] = [points[i - 2], points[i - 1], points[i], points[i + 1]];\n return y0 + ((t - x0) / (x1 - x0)) * (y1 - y0);\n}\n\n/** Every plant this construct takes, beside the setup constructs' own (`CorePlant`). */\nexport interface TimelinePlant extends CorePlant {\n channel?: ChannelEvaluator;\n search?: KeySearch;\n}\n\n/** A timeline's channels at `t`, or `null` before its first key (the channels are then at setup). */\nfunction valuesAt(keys: readonly CoreKey[], t: number, plant: TimelinePlant): number[] | null {\n const index = (plant.search ?? keyIndexAt)(keys, t);\n if (index < 0) return null;\n const channel = plant.channel ?? channelAt;\n return keys[index].values.map((_v, c) => channel(keys, index, c, t));\n}\n\n/** The key a stepped-by-nature timeline (attachment, inherit) shows at `t`, or `null` before its first key. */\nfunction keyAt(keys: readonly CoreKey[], t: number, plant: TimelinePlant): CoreKey | null {\n const index = (plant.search ?? keyIndexAt)(keys, t);\n return index < 0 ? null : keys[index];\n}\n\n/** Each animation's bone timelines by bone name, kept with the timelines they index (`posedBones`). */\nconst boneTimelinesByName = new WeakMap<CoreAnimationTimelines, ReadonlyMap<string, CoreTarget<BoneTimelineKind>>>();\n\n/** The animation's bone timelines by bone name, built once per timelines object (issue #1134: a walk built it again on every step); timelines read are never written. */\nfunction boneTimelinesOf(timelines: CoreAnimationTimelines): ReadonlyMap<string, CoreTarget<BoneTimelineKind>> {\n let byName = boneTimelinesByName.get(timelines);\n if (byName === undefined) {\n byName = new Map(timelines.bones.map((b) => [b.name, b]));\n boneTimelinesByName.set(timelines, byName);\n }\n return byName;\n}\n\n/** The bones posed by the animation's bone timelines at `t`: copies of the setup bones with the posed fields — the header's rules. */\nexport function posedBones(doc: CompiledDocument, timelines: CoreAnimationTimelines, t: number, plant: TimelinePlant = {}): ModelBone[] {\n const byName = boneTimelinesOf(timelines);\n return doc.bones.map((setup) => {\n const target = byName.get(setup.name);\n if (target === undefined) return setup;\n const bone: ModelBone = { ...setup };\n for (const tl of target.timelines) {\n if (tl.kind === 'inherit') {\n const key = keyAt(tl.keys, t, plant);\n if (key === null) {\n if (setup.inheritMode === undefined) delete bone.inheritMode;\n else bone.inheritMode = setup.inheritMode;\n } else bone.inheritMode = key.mode;\n continue;\n }\n const v = valuesAt(tl.keys, t, plant);\n const add = (field: 'x' | 'y' | 'rotation' | 'shearX' | 'shearY', i: number): void => {\n bone[field] = (setup[field] ?? 0) + (v === null ? 0 : v[i]);\n };\n const times = (field: 'scaleX' | 'scaleY', i: number): void => {\n bone[field] = (setup[field] ?? 1) * (v === null ? 1 : v[i]);\n };\n switch (tl.kind) {\n case 'rotate': add('rotation', 0); break;\n case 'translate': add('x', 0); add('y', 1); break;\n case 'translatex': add('x', 0); break;\n case 'translatey': add('y', 0); break;\n case 'shear': add('shearX', 0); add('shearY', 1); break;\n case 'shearx': add('shearX', 0); break;\n case 'sheary': add('shearY', 0); break;\n case 'scale': times('scaleX', 0); times('scaleY', 1); break;\n case 'scalex': times('scaleX', 0); break;\n case 'scaley': times('scaleY', 0); break;\n }\n }\n return bone;\n });\n}\n\n/**\n * A player's bone-local adjustment (issue #1336): a function the live track\n * (`openTrack`'s `adjust`, `./track.ts`) calls once per pose, after the\n * animation's timelines have posed the bone locals at the step's time and\n * before the world transforms, the constraints and the physics step — so a\n * write is what the rest of the step reads: the bone's children, the\n * attachments drawn through it, every constraint and the physics constraint\n * stepped on top of it. It is spine-core's \"application code\" writing\n * `Bone.pose` between `AnimationState.apply` and `updateWorldTransform`\n * (`CO50` holds the two equal at tolerance 0).\n *\n * - **The view is the step's locals, posed from the setup pose.** Every pose\n * of a walk is posed from the setup pose at its time (`./raw.ts`,\n * `TrackState`), so a write lives for the pose it was written in and the\n * next step's hook reads the timelines' value again, not the write. A\n * channel no timeline keys reads its setup value on every step.\n * - **A bone the hook does not write is untouched**: the timelines' bone\n * object as it was, the setup bone itself where nothing keys it. A written\n * bone is copied before the write, so the document is never written.\n * - **A write that is not a finite number is refused by name**, the bone, the\n * channel and the value — where the core refuses a non-finite value, by\n * name, rather than posing a picture with it (`finite` in `./raw.ts`).\n */\nexport interface BoneLocals {\n rotation: number;\n x: number;\n y: number;\n scaleX: number;\n scaleY: number;\n shearX: number;\n shearY: number;\n}\n\n/** The locals of a step's bones, by name (`BoneLocals`). */\nexport interface AdjustableLocals {\n /** The document's bones, in its order. */\n readonly names: readonly string[];\n /** One bone's locals, read and written in place; a name the document has no bone for is refused by name. */\n bone(name: string): BoneLocals;\n}\n\n/** What `openTrack`'s `adjust` is: called once per pose with the step's locals (`BoneLocals`). */\nexport type LocalAdjust = (locals: AdjustableLocals) => void;\n\n/** The seven channels a `BoneLocals` reads and writes, each with the value an unstated one reads as (`worldTransforms`' defaults). */\nconst LOCAL_CHANNELS = { rotation: 0, x: 0, y: 0, scaleX: 1, scaleY: 1, shearX: 0, shearY: 0 } as const;\ntype LocalChannel = keyof typeof LOCAL_CHANNELS;\n\n/** One bone of a step's `bones`, read through and written through, copied on its first write (`BoneLocals`' second rule). */\nclass StepLocals implements BoneLocals {\n constructor(\n private readonly bones: ModelBone[],\n private readonly index: number,\n private readonly setup: ModelBone,\n ) {}\n\n private read(channel: LocalChannel): number {\n return this.bones[this.index][channel] ?? LOCAL_CHANNELS[channel];\n }\n\n private write(channel: LocalChannel, value: number): void {\n if (typeof value !== 'number' || !Number.isFinite(value)) throw new CoreInputError(`the adjustment wrote bone \"${this.setup.name}\" ${channel} = ${String(value)}, not a finite number`);\n if (this.bones[this.index] === this.setup) this.bones[this.index] = { ...this.setup };\n this.bones[this.index][channel] = value;\n }\n\n get rotation(): number { return this.read('rotation'); }\n set rotation(v: number) { this.write('rotation', v); }\n get x(): number { return this.read('x'); }\n set x(v: number) { this.write('x', v); }\n get y(): number { return this.read('y'); }\n set y(v: number) { this.write('y', v); }\n get scaleX(): number { return this.read('scaleX'); }\n set scaleX(v: number) { this.write('scaleX', v); }\n get scaleY(): number { return this.read('scaleY'); }\n set scaleY(v: number) { this.write('scaleY', v); }\n get shearX(): number { return this.read('shearX'); }\n set shearX(v: number) { this.write('shearX', v); }\n get shearY(): number { return this.read('shearY'); }\n set shearY(v: number) { this.write('shearY', v); }\n}\n\n/** The adjustment run over a step's `bones` (`posedBones`' array, in the document's order), which it may replace bone by bone (`BoneLocals`). */\nfunction adjustLocals(doc: CompiledDocument, bones: ModelBone[], adjust: LocalAdjust): void {\n const views = new Map<string, StepLocals>();\n const names = doc.bones.map((b) => b.name);\n adjust({\n names,\n bone(name: string): BoneLocals {\n let view = views.get(name);\n if (view === undefined) {\n const index = names.indexOf(name);\n if (index < 0) throw new CoreInputError(`the adjustment asked for bone ${JSON.stringify(name)}, which is not one of this document's bones`);\n // A copy the timelines made is this step's own; the setup bone is the document's, copied on its first write.\n view = new StepLocals(bones, index, doc.bones[index]);\n views.set(name, view);\n }\n return view;\n },\n });\n}\n\nconst clamp01 = (v: number): number => (v < 0 ? 0 : v > 1 ? 1 : v);\n\n/**\n * The slot rows at `t`, in the oracle's shape and rounding, or the conflicts\n * that leave them out: a slot showing a placeholder several skins fill\n * differently (the setup slots' ⚠️, `shownAttachment`).\n */\nexport function posedSlots(\n doc: CompiledDocument,\n timelines: CoreAnimationTimelines,\n t: number,\n plant: TimelinePlant = {},\n sliders: readonly SliderApplication[] = [],\n /** Filled with each slot's placeholder once the sample's own timelines have moved it, before the sliders — what the attachments are posed from (`attachmentStates`). */\n placeholders?: Map<string, string | null>,\n): { rows: CoreSlotRow[]; conflicts: string[] } {\n const colour = plant.colour ?? readColour;\n const byName = new Map(timelines.slots.map((s) => [s.name, s]));\n return slotRowsFrom(doc, plant, sliders, placeholders, (slot, live) => {\n let placeholder = slot.setup;\n const light = slot.color === undefined ? [1, 1, 1, 1] : colour(slot.color);\n const setupDark = slot.dark === undefined ? null : readColour(slot.dark);\n const dark = setupDark === null ? null : [setupDark[0], setupDark[1], setupDark[2]];\n for (const tl of live ? (byName.get(slot.name)?.timelines ?? []) : []) {\n if (tl.kind === 'attachment') {\n const key = keyAt(tl.keys, t, plant);\n placeholder = key === null ? slot.setup : (key.name ?? null);\n continue;\n }\n const v = valuesAt(tl.keys, t, plant);\n const setupLight = slot.color === undefined ? [1, 1, 1, 1] : colour(slot.color);\n const channels = SLOT_COLOUR_TIMELINES[tl.kind].channels;\n channels.forEach((name, i) => {\n const at = { r: 0, g: 1, b: 2, a: 3, r2: 4, g2: 5, b2: 6 }[name];\n if (at < 4) light[at] = v === null ? setupLight[at] : clamp01(v[i]);\n else if (dark !== null && setupDark !== null) dark[at - 4] = v === null ? setupDark[at - 4] : clamp01(v[i]);\n });\n }\n return { placeholder, light, dark };\n });\n}\n\n/**\n * What a slot holds once the timelines have posed it and before the sliders:\n * the placeholder it shows, its light colour and its dark one (`null` where\n * the slot states none). `posedSlots` reads it off one animation at `t`; the\n * live tracks off their mixed entries (`./tracks.ts`, issue #1336).\n */\nexport interface SlotBase {\n placeholder: string | null;\n light: number[];\n dark: number[] | null;\n}\n\n/**\n * The slot rows from each slot's `SlotBase` — `baseOf`, called once per slot\n * in the document's order with whether the slot is animated at all — then the\n * sliders, the resolution and the oracle's row: `posedSlots`' body past the\n * timelines, which the live tracks share (`./tracks.ts`).\n */\nexport function slotRowsFrom(\n doc: CompiledDocument,\n plant: TimelinePlant,\n sliders: readonly SliderApplication[],\n placeholders: Map<string, string | null> | undefined,\n baseOf: (slot: ModelSlot, live: boolean) => SlotBase,\n): { rows: CoreSlotRow[]; conflicts: string[] } {\n const resolve = plant.shown ?? shownAttachment;\n const blend = plant.blend ?? readBlend;\n const round = plant.round ?? gridRound;\n const rows: CoreSlotRow[] = [];\n const conflicts: string[] = [];\n const active = activeBones(doc);\n const gate = plant.slotTimelines ?? slotTimelinesApply;\n for (const slot of doc.slots) {\n // A slot on a bone the skin leaves inactive is not animated — not by the sample's timelines, not by a slider (`./skins.ts`).\n const live = gate(doc, slot, active);\n const base = baseOf(slot, live);\n let placeholder = base.placeholder;\n const { light, dark } = base;\n // The sliders, after the animation, in constraint order (`./constraints_slider.ts`).\n // What the slot shows after the sample's own timelines: the attachments' deform and sequence timelines are matched against it (`./deform.ts`, *A switch*).\n placeholders?.set(slot.name, placeholder);\n const pose = { placeholder, light, dark };\n if (live) applySliderSlots(slot.name, pose, sliders);\n placeholder = pose.placeholder;\n const shown = placeholder === null ? null : resolve(doc, { ...slot, setup: placeholder });\n if (shown !== null && 'conflict' in shown) {\n conflicts.push(`slot \"${slot.name}\" shows placeholder \"${placeholder}\", filled by skins ${shown.conflict.map((c) => `\"${c.skin}\" (shows ${JSON.stringify(c.shown)})`).join(', ')}`);\n continue;\n }\n const row = shown === null ? null : shownRow(shown);\n rows.push([\n slot.name,\n row === null ? null : row.name,\n round(light[0]), round(light[1]), round(light[2]), round(light[3]),\n dark === null ? null : [round(dark[0]), round(dark[1]), round(dark[2])],\n row === null ? null : row.path,\n // The slot's data, not its pose: no timeline moves it (the index header's blend rule).\n blend(slot),\n ]);\n }\n return { rows, conflicts };\n}\n\n/**\n * One step of the stepped phase, as a walk hands it to the bones: the physics\n * context and the clock before the step (`./constraints_physics.ts`), and the\n * caller's adjustment of the locals (`LocalAdjust`). The adjustment rides here\n * rather than on the plant because it is not a rule the core measured and a\n * control plants back — it is the caller's input to one walk — and because\n * the step context exists exactly where a walk is stepped: the live track's\n * every pose but a `reset: 'setup'` pose 0, which no animation is applied to.\n */\nexport interface PoseStep {\n ctx: PhysicsStepContext;\n before: number;\n adjust?: LocalAdjust;\n}\n\n/**\n * The bone rows at `t`, in the oracle's shape and rounding. With `constraints`\n * — the animation's constraint timelines — the document's constraints are\n * applied after the timelines, posed at `t` (`./constraints.ts`, construct\n * 5; each slider's application recorded into `sliders` for its slot\n * timelines), with the setup pose standing for the\n * previous pose a path's offset may read (`previousPassWhy` holds that);\n * without, the hierarchy and the timelines alone.\n */\nexport function posedBoneRows(doc: CompiledDocument, timelines: CoreAnimationTimelines, t: number, plant: TimelinePlant = {}, constraints?: CoreConstraintTimelines, sliders?: SliderApplication[]): CoreBoneRow[] {\n return posedBoneWorld(doc, timelines, t, plant, constraints, sliders).rows;\n}\n\n/** `posedBoneRows`, with the world transforms the rows were read off — what the sample's attachments are posed through. */\nexport function posedBoneWorld(doc: CompiledDocument, timelines: CoreAnimationTimelines, t: number, plant: TimelinePlant = {}, constraints?: CoreConstraintTimelines, sliders?: SliderApplication[], step?: PoseStep): { rows: CoreBoneRow[]; world: Map<string, CoreWorld> } {\n const posed = posedBoneStep(doc, timelines, t, plant, constraints, sliders, step);\n return { rows: stepRows(posed), world: posed.world };\n}\n\n/**\n * `posedBoneWorld`'s world transforms without its rows (issue #1179, the\n * second part): the same pose by the same operations in the same order, since\n * `stepRows` only reads the world once it is posed. A walk reads `world` and\n * no row, so the scan's walk (`scanWalkIn` in `./raw.ts`, A10's) asks for\n * this; the raw entry's walk still forms the rows it does not read, unchanged.\n */\nexport function posedBoneWorldAlone(doc: CompiledDocument, timelines: CoreAnimationTimelines, t: number, plant: TimelinePlant, constraints: CoreConstraintTimelines | undefined, sliders: SliderApplication[] | undefined, step: PoseStep | undefined): Map<string, CoreWorld> {\n return posedBoneStep(doc, timelines, t, plant, constraints, sliders, step).world;\n}\n\n/**\n * One pose of the bones before its rows are read: the world transforms, and\n * what the rows are rounded from. A stepped walk reads rows only off the step\n * that lands on a sample (issue #1134: of the stepped run's poses, nine in ten\n * are steps between samples), so `stepRows` rounds them when they are read,\n * once; every bone's transform is required here, at every step.\n */\ninterface PosedStep {\n bones: ModelBone[];\n world: Map<string, CoreWorld>;\n active: ReadonlySet<string>;\n round: (v: number) => number | null;\n rows?: CoreBoneRow[];\n}\n\n/** A step's bone rows, in the oracle's shape and rounding, rounded the first time they are read. */\nfunction stepRows(posed: PosedStep): CoreBoneRow[] {\n if (posed.rows !== undefined) return posed.rows;\n const { world, active, round } = posed;\n posed.rows = posed.bones.map((b): CoreBoneRow => {\n const w = world.get(b.name) as CoreWorld;\n return [b.name, round(w.worldX), round(w.worldY), round(w.a), round(w.b), round(w.c), round(w.d), active.has(b.name) ? 1 : 0, b.parent ?? null];\n });\n return posed.rows;\n}\n\n/** `posedBoneWorld` up to its rows, refusing a bone the evaluator gave no transform (`PosedStep`). */\nfunction posedBoneStep(doc: CompiledDocument, timelines: CoreAnimationTimelines, t: number, plant: TimelinePlant, constraints: CoreConstraintTimelines | undefined, sliders: SliderApplication[] | undefined, step: PoseStep | undefined): PosedStep {\n const bones = posedBones(doc, timelines, t, plant);\n // One step of the stepped phase (issue #956, `./constraints_physics.ts`): the physics records posed by their timelines and stepped under the walk's context; the deformed curve a path walks as above.\n if (constraints !== undefined && step !== undefined) return steppedLocals(doc, bones, plant, () => pathDeformed(doc, posedRecords(constraintRecords(doc), constraints, t), timelines, t, plant), constraints.physicsKeyed ?? [], t, sliders, step);\n const active = activeBones(doc);\n // The caller's adjustment, after the timelines and before anything reads the locals (`LocalAdjust`).\n if (step?.adjust !== undefined) adjustLocals(doc, bones, step.adjust);\n let world = (plant.evaluate ?? worldTransforms)(bones, active);\n if (constraints !== undefined) {\n const setupRecords = constraintRecords(doc);\n // A path walks the curve the sample's deform timelines left on its slot (`./deform.ts`); a slider's deform of a walked path leaves the bones out (`pathAnimationsWhy`).\n const records = pathDeformed(doc, posedRecords(setupRecords, constraints, t), timelines, t, plant);\n // A path constraint may read a slot bone the runtime has not yet brought up to date in this pass, as the previous pass left it (`./constraints_path.ts`, *Which slot bone*); `poseAnimations` holds that pass to the setup pose's reading.\n const previous = setupRecords.some((r) => r.kind === 'path') ? applyConstraints(doc.bones, (plant.evaluate ?? worldTransforms)(doc.bones, active), active, plant.constraints ? plant.constraints(setupRecords) : setupRecords, null, undefined, undefined, undefined, solverRules(plant.solver)) : null;\n world = applyConstraints(bones, world, active, plant.constraints ? plant.constraints(records) : records, previous, sliders, undefined, undefined, solverRules(plant.solver));\n }\n for (const b of bones) if (world.get(b.name) === undefined) throw new CoreInputError(`the evaluator returned no transform for bone \"${b.name}\"`);\n return { bones, world, active, round: plant.round ?? gridRound };\n}\n\n/**\n * One step of the stepped phase from locals already posed (issue #1336): the\n * caller's adjustment (`LocalAdjust`), the world transforms, the physics\n * records posed by `records` and stepped under the walk's context, then every\n * constraint. No previous pass: under the step it is the previous step's, and\n * `poseAnimations` leaves such bones out. A single animation's walk reaches it\n * through `posedBoneStep` with the locals `posedBones` posed; the live tracks\n * (`./tracks.ts`) with the locals their mixed entries posed — one pose path\n * past the timelines for both.\n */\nfunction steppedLocals(doc: CompiledDocument, bones: ModelBone[], plant: TimelinePlant, records: () => CoreConstraintRecord[], physicsKeyed: NonNullable<CoreConstraintTimelines['physicsKeyed']>, t: number, sliders: SliderApplication[] | undefined, step: PoseStep): PosedStep {\n const active = activeBones(doc);\n // The caller's adjustment, after the timelines and before anything reads the locals (`LocalAdjust`).\n if (step.adjust !== undefined) adjustLocals(doc, bones, step.adjust);\n let world = (plant.evaluate ?? worldTransforms)(bones, active);\n const stepped = stepPhysicsRecords(records(), physicsKeyed, t, active, step.ctx, step.before);\n world = applyConstraints(bones, world, active, plant.constraints ? plant.constraints(stepped) : stepped, null, sliders, step.ctx, undefined, solverRules(plant.solver));\n for (const b of bones) if (world.get(b.name) === undefined) throw new CoreInputError(`the evaluator returned no transform for bone \"${b.name}\"`);\n return { bones, world, active, round: plant.round ?? gridRound };\n}\n\n/**\n * `steppedLocals`' world transforms, the oracle's rows formed beside them when\n * `rows` is set (as `posedBoneWorld` forms them and `posedBoneWorldAlone` does\n * not): the live tracks' entry to the stepped phase (`./tracks.ts`). The\n * document's constraint records as they stand — the live tracks mix no\n * constraint timeline — and no physics timeline keyed.\n */\nexport function steppedLocalsWorld(doc: CompiledDocument, bones: ModelBone[], plant: TimelinePlant, sliders: SliderApplication[], step: PoseStep, rows: boolean): Map<string, CoreWorld> {\n const posed = steppedLocals(doc, bones, plant, () => constraintRecords(doc), [], 0, sliders, step);\n if (rows) stepRows(posed);\n return posed.world;\n}\n\n/** Each path record with the curve its slot shows deformed by the sample's own deform timelines at `t` (`./deform.ts`), or as it was. */\nfunction pathDeformed(doc: CompiledDocument, records: CoreConstraintRecord[], timelines: CoreAnimationTimelines, t: number, plant: TimelinePlant): CoreConstraintRecord[] {\n if (timelines.attachments.every((a) => a.deform === null)) return records;\n return records.map((r) => {\n if (r.kind !== 'path' || r.path === null) return r;\n const slot = doc.slots.find((x) => x.name === r.slot);\n const shown = slot === undefined ? null : (plant.shown ?? shownAttachment)(doc, slot);\n if (shown === null || 'conflict' in shown) return r;\n const identity = timelineIdentity(r.slot, shown);\n const keyed = timelines.attachments.find((a) => a.deform !== null && `${a.skin}/${a.slot}/${a.attachment}` === identity);\n if (keyed === undefined || keyed.deform === null) return r;\n const d = (plant.deform ?? deformAt)(r.path.vertices, keyed.deform, t);\n return d === null ? r : { ...r, path: { ...r.path, vertices: deformedVertices(r.path.vertices, d), exact: true } };\n });\n}\n\n// ---------------------------------------------------------------------------\n// the samples\n// ---------------------------------------------------------------------------\n\n/** The oracle's phases, as `tools/pose_oracle.ts` names them. */\nexport type SamplePhase = 'grid' | 'off' | 'irr' | 'dense';\n\n/** `1 − 1/φ`, the tool's irrational offset, to the nine places it writes. */\nexport const IRR_OFFSET = 0.381966011;\n\n/**\n * Sample `i` of `n` over duration `d` under `phase` — the tool's formula\n * (`tools/pose_oracle.ts`, *Sample times*), held here so the two dumpers\n * sample at one set of times: `grid` `d·i/(n−1)` (`0` when `n` is 1), `off`\n * `d·(i+0.5)/n`, `irr` and `dense` `d·(i+IRR_OFFSET)/n`.\n */\nexport function sampleTime(phase: SamplePhase, d: number, i: number, n: number): number {\n if (phase === 'off') return (d * (i + 0.5)) / n;\n if (phase === 'irr' || phase === 'dense') return (d * (i + IRR_OFFSET)) / n;\n return n === 1 ? 0 : (d * i) / (n - 1);\n}\n\n/** One posed sample: the time and the blocks this construct produces (`null` where it leaves one out). */\nexport interface CoreSample {\n t: number | null;\n events: CoreEventRow[] | null;\n bones: CoreBoneRow[] | null;\n slots: CoreSlotRow[] | null;\n drawOrder: string[] | null;\n attachments: CoreAttachmentRow[] | null;\n clips: CoreClipRow[] | null;\n /** The triangles drawn under a clip (issue #964, `./clipping.ts`). */\n clipped: CoreClippedRow[] | null;\n}\n\nexport interface CoreAnimationPose {\n name: string;\n duration: number | null;\n samples: CoreSample[];\n}\n\n\n/** Why the animation slots are left out because a slider poses them and the bones are absent, or null. */\nfunction slidersWhy(doc: CompiledDocument): string | null {\n const keyed = doc.constraints.flatMap((c) => {\n if (c.kind !== 'slider') return [];\n const slots = doc.animations.find((a) => a.name === c.animation)?.slots ?? [];\n return slots.length === 0 ? [] : [`slider \"${c.name}\" applies animation \"${c.animation}\", which keys slot(s) ${slots.map((x) => `\"${x}\"`).join(', ')}`];\n });\n return keyed.length === 0 ? null : `${keyed.join('; ')} — the oracle applies sliders after every animation, and a slider poses the slots its animation keys at a time read off the bones, which are absent`;\n}\n\n/**\n * Why the samples' bones are left out although each was posed, or null: a\n * path constraint whose offset reads its slot bone from the previous pass\n * (`previousPassSlotBones`) is posed with the setup pose's reading of it,\n * which is the runtime's exactly when that bone's world keeps the sign of\n * its determinant — its reflection — at the setup pose and at every sample;\n * the oracle's previous pass is the sample before, in its own order of\n * animations, which the model does not hold.\n */\nfunction previousPassWhy(doc: CompiledDocument, animations: readonly CoreAnimationPose[], plant: TimelinePlant): string | null {\n const active = activeBones(doc);\n const reads = previousPassSlotBones(doc, active);\n if (reads.length === 0) return null;\n const records = constraintRecords(doc);\n const setup = applyConstraints(doc.bones, (plant.evaluate ?? worldTransforms)(doc.bones, active), active, plant.constraints ? plant.constraints(records) : records, null, undefined, undefined, undefined, solverRules(plant.solver));\n const bad: string[] = [];\n for (const { constraint, bone } of reads) {\n const w = setup.get(bone);\n const sign = w === undefined ? 0 : Math.sign(w.a * w.d - w.b * w.c);\n const flips = animations.flatMap((a) => a.samples.filter((x) => {\n const row = x.bones?.find((r) => r[0] === bone);\n if (row === undefined || row[3] === null || row[4] === null || row[5] === null || row[6] === null) return true;\n const det = row[3] * row[6] - row[4] * row[5];\n return Math.abs(det) < 1e-6 || Math.sign(det) !== sign;\n }).map((x) => `${a.name}@${x.t}`));\n if (sign === 0 || flips.length > 0) bad.push(`path constraint \"${constraint}\" reads slot bone \"${bone}\" from the previous pose, and its reflection is not the setup's at ${flips.slice(0, 3).join(', ')}${flips.length > 3 ? ` and ${flips.length - 3} more` : ''}`);\n }\n return bad.length === 0 ? null : `${bad.join('; ')} — the runtime's previous pose is the sample before in the Spine file's order of animations, which the model does not hold`;\n}\n\n/**\n * Every animation of the document sampled as the oracle samples it: `n`\n * samples in `phase` over each animation's runtime duration, each the bone\n * rows and the slot rows at `t`, in the model's order of animations. Returns\n * the blocks left out with their reasons, `animations.bones` and\n * `animations.slots` in document order.\n */\nexport function poseAnimations(doc: CompiledDocument, phase: SamplePhase, n: number, plant: TimelinePlant = {}, dt?: number): { animations: CoreAnimationPose[]; absent: Array<[string, string]> } {\n let bonesReason = constraintsAbsentWhy(doc, solverRules(plant.solver)) ?? pathAnimationsWhy(doc) ?? (dt === undefined ? null : steppedPreviousPassWhy(doc));\n const slotConflicts: string[] = [];\n const attachmentWhy: string[] = [];\n const clippedWhy: string[] = [];\n const resolve = plant.shown ?? shownAttachment;\n const round = plant.round ?? gridRound;\n const animations = doc.animations.map((anim: CoreAnimation): CoreAnimationPose => {\n const d = anim.timelines.duration;\n const samples: CoreSample[] = [];\n let last = -1;\n // Under `--physics step` (issue #956): one walk per animation — reset at 0, then the oracle's schedule, each sample posed off its last step (`./constraints_physics.ts`).\n const walk = dt === undefined || bonesReason !== null ? null : { ctx: freshStepContext(plant.physicsStep), now: 0, schedule: stepSchedule(phase, d, n, dt), sliders: [] as SliderApplication[], posed: null as PosedStep | null };\n if (walk !== null) {\n walk.posed = posedBoneStep(doc, anim.timelines, 0, plant, anim.constraints, walk.sliders, { ctx: walk.ctx, before: 0 });\n walk.ctx.phase = 'update';\n }\n for (let i = 0; i < n; i++) {\n const t = sampleTime(phase, d, i, n);\n let sliders: SliderApplication[] = [];\n let posed: { rows: CoreBoneRow[]; world: Map<string, CoreWorld> } | null = null;\n if (walk !== null) {\n for (const s of walk.schedule[i]) {\n const before = walk.ctx.time;\n walk.ctx.time += s - walk.now;\n walk.sliders = [];\n walk.posed = posedBoneStep(doc, anim.timelines, s, plant, anim.constraints, walk.sliders, { ctx: walk.ctx, before });\n walk.now = s;\n }\n sliders = walk.sliders;\n posed = walk.posed === null ? null : { rows: stepRows(walk.posed), world: walk.posed.world };\n } else posed = bonesReason === null ? posedBoneWorld(doc, anim.timelines, t, plant, anim.constraints, sliders) : null;\n const placeholders = new Map<string, string | null>();\n const slots = posedSlots(doc, anim.timelines, t, plant, sliders, placeholders);\n for (const c of slots.conflicts) if (!slotConflicts.includes(`${c} at animation \"${anim.name}\"`)) slotConflicts.push(`${c} at animation \"${anim.name}\"`);\n // The draw order: the sample's key, or the setup order before it, then each slider's key (`./draw_order.ts`).\n const evalOrder = plant.drawOrder ?? drawOrderAt;\n let order = evalOrder(doc.slots.length, anim.timelines.drawOrder, t) ?? doc.slots.map((_s, k) => k);\n for (const app of sliders) order = evalOrder(doc.slots.length, app.timelines.drawOrder, app.at) ?? order;\n const drawOrder = order.map((k) => doc.slots[k].name);\n // The attachments and clips, in the draw order, with the deform and sequence timelines' state (`./deform.ts`).\n let attachments: CoreAttachmentRow[] | null = null;\n let clips: CoreClipRow[] | null = null;\n let clipped: CoreClippedRow[] | null = null;\n if (posed !== null) {\n const states = attachmentStates(doc, resolve, placeholders, { timelines: anim.timelines, t }, sliders, plant);\n for (const w of states.why) if (!attachmentWhy.includes(w)) attachmentWhy.push(w);\n const rank = new Map(order.map((k, r) => [doc.slots[k].name, r]));\n const shown = [...states.shown].sort((a, b) => (rank.get(a.slot) ?? 0) - (rank.get(b.slot) ?? 0));\n const geometry = poseGeometry(shown, posed.world, sourceOfDoc(doc), round, { region: plant.region, vertices: plant.vertices }, drawWalkOf(doc, drawOrder, plant));\n if (geometry.attachmentsWhy !== null && !attachmentWhy.includes(geometry.attachmentsWhy)) attachmentWhy.push(geometry.attachmentsWhy);\n attachments = geometry.attachments;\n clips = geometry.clips;\n clipped = geometry.clipped;\n if (geometry.clippedWhy !== null && geometry.attachmentsWhy === null && !clippedWhy.includes(geometry.clippedWhy)) clippedWhy.push(geometry.clippedWhy);\n }\n const events = (plant.events ?? eventsFired)(anim.timelines.events, last, t, round);\n last = t;\n samples.push({ t: round(t), events, bones: posed === null ? null : posed.rows, slots: slots.rows, drawOrder, attachments, clips, clipped });\n }\n return { name: anim.name, duration: round(d), samples };\n });\n if (bonesReason === null && dt === undefined) bonesReason = previousPassWhy(doc, animations, plant);\n if (bonesReason !== null) for (const a of animations) for (const s of a.samples) s.bones = null;\n const slotsReason = (bonesReason === null ? null : slidersWhy(doc)) ?? (slotConflicts.length === 0\n ? null\n : `${slotConflicts.slice(0, 5).join('; ')}${slotConflicts.length > 5 ? `; and ${slotConflicts.length - 5} more` : ''} — under --skin all the LAST of them in the Spine file's skin order wins, and that order is the emitter's, not the model's`);\n if (slotsReason !== null) for (const a of animations) for (const s of a.samples) s.slots = null;\n const orderReason = bonesReason === null ? null : slidersKeyingWhy(doc, 'drawOrder');\n if (orderReason !== null) for (const a of animations) for (const s of a.samples) s.drawOrder = null;\n // Every vertex goes through a bone's world matrix and follows what the slot shows, so the attachments and clips need both blocks.\n const upstream = [bonesReason === null ? null : `animations.bones is absent (${bonesReason}), and every vertex goes through a bone's world matrix`, slotsReason === null ? null : 'animations.slots is absent, so what a slot shows is not posed'].filter((x): x is string => x !== null);\n const clipsReason = upstream.length > 0 ? upstream.join('; ') : attachmentWhy.some((w) => !w.includes('(atlas: null)')) ? attachmentWhy.filter((w) => !w.includes('(atlas: null)')).join('; ') : null;\n const attachmentsReason = clipsReason ?? (attachmentWhy.length === 0 ? null : attachmentWhy.join('; '));\n if (attachmentsReason !== null) for (const a of animations) for (const s of a.samples) s.attachments = null;\n if (clipsReason !== null) for (const a of animations) for (const s of a.samples) s.clips = null;\n // The clipped triangles follow the attachments and the clips, and are left out where a clip starts over a polygon the core does not clip against (`./clipping.ts`).\n const clippedReason = attachmentsReason ?? orderReason ?? (clippedWhy.length === 0 ? null : clippedWhy.join('; '));\n if (clippedReason !== null) for (const a of animations) for (const s of a.samples) s.clipped = null;\n const absent: Array<[string, string]> = [];\n if (bonesReason !== null) absent.push(['animations.bones', bonesReason]);\n if (slotsReason !== null) absent.push(['animations.slots', slotsReason]);\n if (orderReason !== null) absent.push(['animations.drawOrder', orderReason]);\n if (attachmentsReason !== null) absent.push(['animations.attachments', attachmentsReason]);\n if (clipsReason !== null) absent.push(['animations.clips', clipsReason]);\n if (clippedReason !== null) absent.push(['animations.clipped', clippedReason]);\n return { animations, absent };\n}\n","/**\n * rigc's own core: it reads the compiled model as `build` writes it\n * (`rigc-compiled/3`, and `/2` before issue #1026 and `/1` before issue #1016;\n * `skeleton.model.json`)\n * and poses it (issue #925, step 2a\n * of issue #380). It is the second dumper `tools/pose_oracle.ts` was shaped\n * for: what it poses is written into the same `pose-oracle/2` document the\n * runtime's dump is, and `compare` holds the two to each other.\n *\n * ## What it poses, and what it does not yet\n *\n * Three constructs are here, in the runtime's own order (§5 of the design on\n * issue #380): **the setup pose of every bone** — its world origin and matrix,\n * its active flag and its parent (issue #925) — **the slots at the setup\n * pose** — what each shows, its colour and dark colour, the region path\n * the shown attachment names (issue #928, below) and its blend mode (issue\n * #933) — and **every drawn\n * attachment's world vertices at the setup pose** — a region's corners, a\n * mesh's vertices and a clipping polygon (issue #931, `./vertices.ts`, whose\n * header states each measured rule). All are rounded as the oracle rounds\n * (`gridRound`). A fourth, **every animation's bone and slot timelines at the\n * oracle's sample times** (issue #936), is its own module, `./animation.ts`,\n * which this reader calls for each animation record. Its remainder (issue\n * #955) — the draw order at setup and at a sample (`./draw_order.ts`), the\n * deform and sequence timelines, which move what the attachments and clips\n * draw at setup (under a slider) and at a sample (`./deform.ts`), and the\n * events a sample fires (`./events.ts`) — is posed too. With the physics\n * parameters (issue #956, `./constraints_physics.ts`) no block of the\n * oracle's document is left: `NOT_ADMITTED` is empty. The `clipped` block\n * (issue #964, `./clipping.ts`) — the triangles drawn under a clip, as the\n * runtime's clipper returns them — is posed at setup and at every sample,\n * and left out by name where a clip that is not strictly convex, or an\n * inverse one, starts.\n *\n * **Constraints (construct 5, issue #938, `./constraints.ts`).** The oracle\n * poses the setup pose with every constraint applied, so a bone a constraint\n * moves is not where its hierarchy alone puts it. The core applies the ik,\n * transform, path, physics and slider constraints in the document's order\n * after the hierarchy, as the runtime's update order does (`./constraints.ts`'s\n * header states it with its measurements, `./constraints_path.ts`'s the\n * path's; a physics constraint under `Physics.none` applies nothing, and\n * under the stepped phase — `poseSetup`'s `physics` context, the reset —\n * integrates, `./constraints_physics.ts`, whose `poseSteppedAnimations`\n * walks the oracle's `--physics step` schedule; a slider applies an animation,\n * `./constraints_slider.ts`); a path the core cannot pose exactly (skins\n * that disagree over the curve it walks) leaves the setup bones out naming\n * it (`constraintsAbsentWhy`). Before issue #938, measured over the nineteen\n * recipes `tools/emit_hashes.ts` generates: seven declared a constraint, and\n * on each the runtime's setup pose differed from the hierarchy's alone; all\n * seven read IDENTICAL now. The `paths` and `pathAttachments` blocks — each\n * path constraint's settings and each path attachment's flags and\n * `lengths`, as the runtime reads them — are written from the model\n * (`pathRows`, `pathAttachmentRows`).\n *\n * 🔸 **Active** is measured rather than assumed. Posed through the runtime by\n * `tools/pose_oracle.ts dump` on a hand-written skeleton (issue #925's\n * report; held by the core suite's `CO07`): a bone that is not skin-required\n * is active; a skin-required bone is active exactly when the applied skin\n * names it or names a bone below it — a skin-required parent of a named bone\n * is active, and a bone that is not skin-required stays active under an\n * inactive parent. The oracle's `--skin all` applies every skin at once, so\n * under it `active` means: not skin-required, or named — itself or a bone\n * below it — by ANY skin's `bones` list. Under `--skin <name>` (issue #932,\n * `underSkin`) it is the named skin's list alone — the default skin's does\n * not count (`./skins.ts`, measured). An inactive bone is not posed\n * (`worldTransforms` in `./world.ts`).\n *\n ## The slots at the setup pose (issue #928)\n *\n * Every rule below was measured by posing a hand-written skeleton through\n * `tools/pose_oracle.ts dump` (spine-core 4.3.13, `--skin all`) and reading\n * the slot rows it printed; the core suite's `CO11` holds the same skeleton\n * against the core at tolerance 0.\n *\n * - **Which attachment a slot shows.** A slot whose setup placeholder is\n * `null` shows nothing (`null`). Otherwise the placeholder is looked up in\n * every skin; one skin filling it — the default or a named one alone —\n * shows that record. A placeholder no skin fills shows nothing: the row\n * reads `null` for the attachment and for the path, not the placeholder's\n * name.\n * - ⚠️ **Several skins filling one placeholder: the LAST in the Spine FILE's\n * skin order wins — and the model does not hold that order.** Three skins\n * filling one placeholder with three names, in three file orders\n * (`default, s1, s2`; `s2, s1, default`; `s1, default, s2`), showed `s2`,\n * `default` and `s2`'s name: the last one listed, every time — the oracle's\n * `--skin all` merges the skins in file order, a later one replacing an\n * earlier one's entry. The file's order is not the model's: the Spine\n * emitter writes `default` first and the rest in the editor's order\n * (`editorSkinOrder` in `src/compile.ts`), so a rig built with skins\n * `default, zulu, alpha` has a model listing them so and a file listing\n * `default, alpha, zulu`; with `zulu` and `alpha` filling one placeholder,\n * spine-core showed `zulu`'s attachment, and \"last in the model's order\"\n * would have shown `alpha`'s (measured through `ingest` and `build`; the\n * core suite's `CO12` builds it). That order is a Spine spelling the model\n * rightly does not carry (census §4's class), so the core does not guess it:\n * where every skin filling a slot's setup placeholder gives the same row —\n * the same shown name and path — the order cannot matter and the row is\n * posed; where they differ, the whole `setup.slots` block is absent, naming\n * the slot, the placeholder and the skins. Posing one skin at a time\n * (`--skin <name>`, `underSkin`, issue #932) has no order to know — the\n * named skin's record, else the default skin's (`./skins.ts`) — so the\n * per-skin dumps judge what the merged view leaves out, and\n * `tools/core_gate.ts` runs one per skin on a row declaring several.\n * - **The name shown** is the record's own `name` where the model states one,\n * else the placeholder: a region filed under `p` with `path: \"other\"` shows\n * `p`; one stating `name: \"n\"` shows `n`.\n * - **The region path** is the record's `path` where stated, else the name\n * shown — for a region, a mesh and a linked mesh (a region stating\n * `name: \"n\"` and no path reads path `n`; a linked mesh stating\n * `path: \"lm\"` reads `lm`; a region or mesh with a `sequence` reads its\n * stated `path` as written, `seq` and not a numbered frame). A bounding\n * box, a clipping polygon and a path attachment read `null`, as does a\n * point, which rigc does not emit.\n * - **Colour.** No colour stated reads `1, 1, 1, 1`. A stated colour reads\n * each channel as its two hex digits over 255 (`ff800040` reads\n * `1, 0.501961, 0, 0.25098`; upper case reads the same); six digits read\n * an alpha of 1. The attachment's own colour does not enter the slot's row\n * (a region tinted `00000080` under an unstated slot colour read white).\n * Every one of the 256 byte values in every channel is held by `CO11`.\n * - **Dark colour** is `null` when the slot states none, else its first\n * three channels read the same way; eight digits read the same three, the\n * fourth unread.\n * - 🚫 **Any other spelling is refused by `readModel`, by name.** The\n * runtime's reading of one is not a colour: `ff80004` (seven digits) read\n * alpha 1, `zz800040` read a red of NaN, `f` read red 0.058824 and green\n * NaN, and an empty colour read white while an empty dark colour read none.\n * Reproducing that would be copying a parser's accidents, not posing a slot.\n * - **A slot on an inactive bone still shows its attachment** (a slot on a\n * skin-required bone no skin names read its region and path).\n * - ⚠️ **A slider poses slots at setup; the other four constraint kinds do\n * not.** A slider applies an animation, and the oracle's setup applies\n * constraints: a hand-written slider whose animation keys a slot's `rgba`\n * to `ff000080` and its attachment to `q` turned that slot's setup row from\n * `r, 1, 1, 1, 1` to `q, 1, 0, 0, 0.501961`, with its dial bone and without\n * one. Issue #928 left `setup.slots` absent wherever a slider keys a slot;\n * since issue #938 each slider's slot timelines are applied after the\n * bones, in constraint order, at the time and mix it was applied with\n * (`applySliderSlots` in `./constraints_slider.ts`, which states the blend).\n * The slots are still absent, naming the slider, where the bones its time\n * is read from are absent. An ik, transform, path or physics constraint\n * moves bones only.\n * - **The blend mode** (issue #933) is the row's last cell, as the runtime's\n * enum names it: `Normal`, `Additive`, `Multiply`, `Screen`. A slot that\n * states none reads `Normal`. The runtime reads a stated blend by\n * upper-casing its first letter and looking the result up: `additive` and\n * `Additive` both read `Additive`, while `ADDITIVE` and `mUlTiPlY` read no\n * mode at all (the dump's `null`) and an empty string threw on load. So the\n * core reads exactly the eight spellings whose first letter folds to one of\n * the four names and `readModel` refuses every other by name. The mode is\n * the slot's data, not its pose: an animation keying the slot's colour left\n * it where setup put it, so a sample's row carries the setup's mode.\n *\n * ## The evaluator\n *\n * World transforms come from the core's own evaluator, `worldTransforms` in\n * `./world.ts`, written from what a bone's fields mean and from measurement\n * against the runtime's dump; its header states each measured choice. It is\n * not reached through `src/transform.ts`'s `computeWorldTransforms`: that is\n * the compiler's adapter over this same evaluator (issues #1015 and #1021 —\n * the same arithmetic since #1021), and the core importing the compiler would\n * be a cycle. The compiler's evaluator before #1015, called as it was, read\n * IDENTICAL on 1 of the 12 recipes the core poses (DIFF on 11, worst 61\n * millionths against a tolerance of one — issue #925's report). The owner's\n * decision is recorded on issue #380. `poseSetup` takes a\n * `CorePlant` — the evaluator, the skin resolution, the colour and blend readings — so\n * the suite's plants can pass a copy of one of them; nothing else passes one.\n *\n * ## Purity\n *\n * `src/` is pure and this directory is held to it by the core suite's tree\n * rule (`selftest.ts`, band `CO`): no clock, no randomness, no network, no\n * child process, no file system — `readModel` takes the document's TEXT — and\n * nothing from the Spine runtime package, as a value or as a type.\n */\nimport type { ModelAtlasRect, ModelBone, ModelEditorOrder, ModelPage, ModelPageRegion, ModelSlot, ModelStage, ModelVertices, SkinTableEntry } from '../model.ts';\nimport { worldTransforms, type CoreWorld } from './world.ts';\nimport { readAnimationTimelines, type CoreAnimationTimelines } from './animation.ts';\nimport { readEventDefs, type CoreEventDef } from './events.ts';\nimport { poseGeometry, readGeometry, type CoreAttachmentRow, type CoreClipRow, type CoreGeometry, type DrawWalk, type RegionPoser, type ShownGeometry, type VertexPoser } from './vertices.ts';\nimport type { CoreClippedRow, ShapeClipper, TriangleClipper } from './clipping.ts';\nimport { applyConstraints, constraintsAbsentWhy, readConstraintRecord, readConstraintTimelines, solverRules, type ConstraintPlant, type CoreConstraintRecord, type CoreConstraintTimelines, type SolverRules } from './constraints.ts';\nimport { readPathRecord } from './constraints_path.ts';\nimport { readPhysicsRecord, type PhysicsStepContext, type PhysicsStepper } from './constraints_physics.ts';\nimport { appliedSkins, CORE_ALL_SKINS, fillingSkins, listedByAppliedSkin, lookupSkins, slotTimelinesApply, type SlotTimelineGate } from './skins.ts';\nimport { applySliderSlots, readSliderRecord, type SliderApplication, type SlotPoseState } from './constraints_slider.ts';\nimport { attachmentStates, type DeformBlender, type DeformEvaluator, type SequenceEvaluator } from './deform.ts';\nimport { drawOrderAt, type DrawOrderEvaluator } from './draw_order.ts';\nimport type { EventsFired } from './events.ts';\n\n/**\n * The document spec `build` writes today (issue #1026): the `pages` section\n * (issue #1016) with each page's `pma` and `scale`, and the `stage` and\n * `editorOrder` sections — what only the Spine files beside a `/2` document\n * state.\n */\nexport const CORE_DOCUMENT_SPEC = 'rigc-compiled/3';\n\n/**\n * The spec before issue #1026: `/3` without `stage`, `editorOrder` and the\n * pages' `pma` and `scale`. Read as before, with `stated` null — a reader that\n * needs those reads them off the Spine files beside the document, and says so\n * (`src/render.ts`'s poser line, the survey's order).\n */\nexport const CORE_DOCUMENT_SPEC_2 = 'rigc-compiled/2';\n\n/**\n * The spec before issue #1016: `/2` without `pages`. Read as before — the\n * draw then takes where each region sits from the atlas beside the document\n * (`corePoser` in `src/render_core.ts` says so by name), because a `/1`\n * document does not state it.\n */\nexport const CORE_DOCUMENT_SPEC_1 = 'rigc-compiled/1';\n\n/** Every spec this reader takes, newest first. */\nexport const CORE_DOCUMENT_SPECS: readonly string[] = [CORE_DOCUMENT_SPEC, CORE_DOCUMENT_SPEC_2, CORE_DOCUMENT_SPEC_1];\n\n/** Who posed a dump the core wrote — the oracle document's `dumper`. */\nexport const CORE_DUMPER = 'rigc-core';\n\n/** A refusal about the document read. Every problem is collected and named in one throw. */\nexport class CoreInputError extends Error {}\n\n/** The document's sections after `spec`, in its key order (`modelDocument` in `src/model.ts`). */\nexport const CORE_SECTIONS = [\n // Issue #1026: `stage` (the header's setup-pose box, or null) and `editorOrder` (the order the Spine file lists skins, slot keys and animations in). `/3` only.\n 'referenceScale', 'stage', 'bones', 'slots', 'skins', 'constraints', 'events', 'animations', 'editorOrder',\n 'images', 'pageGrids', 'droppedStates', 'absentParts', 'meshBones', 'meshes', 'physics', 'deformTransforms', 'trackDerivations', 'rig',\n // Issue #1016: where each region sits on its page, in the atlas written beside the document (`pagesOfAtlas` in `src/model.ts`). `/2` only.\n 'pages',\n // Issue #968: the digest of the `skeleton.json` written beside the document (`spineFileSha256` in `src/model.ts`).\n 'spine',\n] as const;\n\n/** The sections of a `rigc-compiled/2` document: `CORE_SECTIONS` without `stage` and `editorOrder`. */\nexport const CORE_SECTIONS_2: readonly string[] = CORE_SECTIONS.filter((key) => key !== 'stage' && key !== 'editorOrder');\n\n/** The sections of a `rigc-compiled/1` document: `CORE_SECTIONS_2` without `pages`. */\nexport const CORE_SECTIONS_1: readonly string[] = CORE_SECTIONS_2.filter((key) => key !== 'pages');\n\n/** The fields of a page and of a region in the `pages` section, as the writer lists them (`MODEL_PAGE_FIELDS`, `MODEL_PAGE_REGION_FIELDS` in `src/model.ts`, mirrored). */\nexport const CORE_PAGE_FIELDS = ['name', 'width', 'height', 'pma', 'scale', 'regions'] as const;\n/** A `rigc-compiled/2` page's fields: `CORE_PAGE_FIELDS` without `pma` and `scale` (issue #1026). */\nexport const CORE_PAGE_FIELDS_2: readonly string[] = CORE_PAGE_FIELDS.filter((key) => key !== 'pma' && key !== 'scale');\n/** The stage's fields, as the writer lists them (`MODEL_STAGE_FIELDS` in `src/model.ts`, mirrored). */\nexport const CORE_STAGE_FIELDS = ['x', 'y', 'width', 'height'] as const;\n/** The stage box's fields (issue #1168), as the writer lists them (`MODEL_STAGE_BOX_FIELDS` in `src/model.ts`, mirrored). */\nexport const CORE_STAGE_BOX_FIELDS = ['slot', 'attachment'] as const;\nexport const CORE_PAGE_REGION_FIELDS = ['name', 'x', 'y', 'width', 'height', 'offsetX', 'offsetY', 'originalWidth', 'originalHeight', 'degrees', 'index'] as const;\n\n/** The fields a bone record may carry, as the writer lists them. A field outside this list is refused. */\nexport const CORE_BONE_FIELDS = ['name', 'parent', 'length', 'x', 'y', 'rotation', 'scaleX', 'scaleY', 'shearX', 'shearY', 'inheritMode', 'skinRequired', 'editor'] as const;\nconst BONE_NUMBERS = ['length', 'x', 'y', 'rotation', 'scaleX', 'scaleY', 'shearX', 'shearY'] as const;\n/** The fields a slot record may carry. */\nexport const CORE_SLOT_FIELDS = ['name', 'bone', 'setup', 'color', 'dark', 'blend'] as const;\n/** The fields a skin record may carry. */\nexport const CORE_SKIN_FIELDS = ['name', 'bones', 'constraints', 'attachments'] as const;\n/**\n * The fields each attachment kind's record may carry, as the writer lists them\n * (`ATTACHMENT_FIELDS` in `src/model.ts`, mirrored as the bone and slot lists\n * are). A field outside its kind's list is refused.\n */\nexport const CORE_ATTACHMENT_FIELDS: Readonly<Record<SkinTableEntry['kind'], readonly string[]>> = {\n mesh: ['kind', 'name', 'path', 'color', 'uvs', 'triangles', 'vertices', 'hull', 'edges', 'width', 'height', 'sequence'],\n boundingbox: ['kind', 'name', 'vertexCount', 'vertices', 'editorColor'],\n clipping: ['kind', 'name', 'end', 'convex', 'inverse', 'vertexCount', 'vertices', 'editorColor'],\n path: ['kind', 'name', 'closed', 'constantSpeed', 'vertexCount', 'vertices', 'lengths', 'editorColor'],\n region: ['kind', 'name', 'path', 'x', 'y', 'rotation', 'scaleX', 'scaleY', 'width', 'height', 'color', 'sequence', 'atlas'],\n linkedmesh: ['kind', 'name', 'path', 'source', 'skin', 'slot', 'timelines', 'width', 'height', 'color', 'sequence'],\n};\n/** The kinds whose shown record names an atlas region — the ones the oracle's row gives a path (the header's measurement). */\nexport const CORE_REGION_KINDS: ReadonlySet<SkinTableEntry['kind']> = new Set(['region', 'mesh', 'linkedmesh']);\n/** A colour the core reads: six or eight hex digits, either case (the header's measurement; anything else is refused). */\nconst HEX_COLOUR = /^[0-9a-fA-F]{6}([0-9a-fA-F]{2})?$/;\n/** The blend modes, as the runtime's enum names them (the header's measurement). */\nexport const CORE_BLEND_MODES = ['Normal', 'Additive', 'Multiply', 'Screen'] as const;\nexport type CoreBlendMode = (typeof CORE_BLEND_MODES)[number];\n/** A stated blend's reading: its first letter upper-cased, when that is one of the four names; `null` otherwise. */\nexport function foldBlend(stated: string): CoreBlendMode | null {\n const folded = `${stated.slice(0, 1).toUpperCase()}${stated.slice(1)}`;\n return (CORE_BLEND_MODES as readonly string[]).includes(folded) ? (folded as CoreBlendMode) : null;\n}\n/** The five constraint kinds a document names. */\nexport const CORE_CONSTRAINT_KINDS = ['ik', 'transform', 'path', 'physics', 'slider'] as const;\nexport type CoreConstraintKind = (typeof CORE_CONSTRAINT_KINDS)[number];\n/** The five inherit modes, as the rig spec spells them once its first letter is lower-cased. */\nexport const CORE_INHERIT_MODES = ['normal', 'onlyTranslation', 'noRotationOrReflection', 'noScale', 'noScaleOrReflection'] as const;\n\n/**\n * The fields of a region's atlas rectangle (`ModelAtlasRect` in `src/model.ts`,\n * issue #935), every one required and a finite number.\n */\nexport const CORE_ATLAS_RECT_FIELDS = ['width', 'height', 'offsetX', 'offsetY', 'originalWidth', 'originalHeight'] as const;\n\n/**\n * One attachment record, as far as the slots read it: its kind, and its own\n * name and region path where stated — and a region's atlas rectangle where the\n * record carries one, `null` where the build had no source for it (issue #935);\n * and, for the world vertices (issue #931, `./vertices.ts`), the geometry the\n * record carries, checked field by field (`readGeometry`).\n */\nexport interface CoreAttachment {\n kind: SkinTableEntry['kind'];\n name?: string;\n path?: string;\n atlas?: ModelAtlasRect | null;\n geometry?: CoreGeometry;\n /** How many frames the record's series holds, where it states a `sequence` — what a sequence key's index is checked against (`./deform.ts`). */\n sequenceCount?: number;\n /** A linked mesh's `timelines`: whether it plays its source's deform and sequence timelines (`./deform.ts`). */\n timelines?: boolean;\n /** The record's `color`, six or eight hex digits, where stated (issue #966): what the raw entry's attachment colour reads (`./raw.ts`); white where unstated. */\n color?: string;\n /** The frame its `sequence` shows at setup (`sequence.setup`, 0 unstated), where it states one (issue #966): the raw entry's sequence index when no timeline set another. */\n sequenceSetup?: number;\n}\n\n/** One skin, as far as these constructs read it: its name, the bones and constraints it activates, and its table — slot, then placeholder. */\nexport interface CoreSkin {\n name: string;\n bones: string[];\n /** The constraints it activates, by kind — a kind the document leaves out lists none (issue #932, `./skins.ts`). */\n constraints: Record<CoreConstraintKind, string[]>;\n attachments: Record<string, Record<string, CoreAttachment>>;\n}\n\n/** One constraint, as far as these constructs read it: its kind and name, a slider's animation, and an ik or transform constraint's record (`./constraints.ts`). */\nexport interface CoreConstraint {\n kind: CoreConstraintKind;\n name: string;\n /** The animation a slider applies — the one constraint kind measured to pose a slot (the slots' ⚠️). */\n animation?: string;\n /** The constraint read field by field (construct 5, issue #938): ik and transform (`./constraints.ts`), physics (`./constraints_physics.ts`), slider (`./constraints_slider.ts`). */\n record?: CoreConstraintRecord;\n}\n\n/** One animation: its name, the slots its timelines key, its timelines as construct 4 reads them (`./animation.ts`), and its constraint timelines (`./constraints.ts`). */\nexport interface CoreAnimation {\n name: string;\n slots: string[];\n timelines: CoreAnimationTimelines;\n constraints: CoreConstraintTimelines;\n /** Every attachment a `deform` timeline keys, as `skin/slot/attachment` — what a path constraint walking a deformed path needs to know (`./constraints_path.ts`). */\n deforms: string[];\n}\n\n/**\n * A `rigc-compiled/3` (or `/2`, or `/1`) document, read. `bones` and `slots` are checked field by\n * field against the writer's own records; skins and constraints are read as\n * far as their names and memberships, and every other section is only\n * required to be present — no construct this card admits reads it.\n */\nexport interface CompiledDocument {\n spec: string;\n /**\n * The skin the document is posed under (issue #932, `./skins.ts`): `all` —\n * every skin merged, the oracle's `--skin all` and `readModel`'s reading —\n * one skin's name, `underSkin`'s, or `null` — no skin set, the runtime's\n * `Skeleton.skin` before `setSkin` is called (`underNoSkin`, issue #1051).\n */\n skin: string | null;\n /** The skeleton's reference scale (issue #958), which every physics record carries too (`CorePhysicsRecord.referenceScale`). */\n referenceScale: number;\n bones: ModelBone[];\n slots: ModelSlot[];\n skins: CoreSkin[];\n constraints: CoreConstraint[];\n animations: CoreAnimation[];\n /** The digest of the `skeleton.json` `build` wrote beside the document (issue #968) — what a render holds the file beside it to before posing it here. */\n spine: { sha256: string };\n /**\n * Every page of the atlas `build` wrote beside the document and every region\n * on it, in file order (issue #1016) — where each drawing sits, which the\n * draw's page UVs read. `null` for a `rigc-compiled/1` document, which does\n * not state it. A `rigc-compiled/3` document's pages carry `pma` and `scale`\n * too (issue #1026); a `/2` document's carry neither.\n */\n pages: ModelPage[] | null;\n /**\n * What a `rigc-compiled/3` document states that only the Spine files beside\n * a `/2` or `/1` document hold (issue #1026): the setup-pose box the header\n * declares, or `null` for none, and the order the editor lists skins, their\n * slot keys and animations in. `null` for a `/2` or `/1` document.\n */\n stated: CoreStated | null;\n}\n\n/** A `rigc-compiled/3` document's `stage` and `editorOrder`, read (`CompiledDocument.stated`). */\nexport interface CoreStated {\n stage: ModelStage | null;\n editorOrder: ModelEditorOrder;\n}\n\n/**\n * The `pages` section, checked: a list of pages, each holding exactly\n * `CORE_PAGE_FIELDS` — a non-empty name, a size of two positive finite\n * numbers, a list of at least one region (issue #1054) — and each region exactly\n * `CORE_PAGE_REGION_FIELDS`, a non-empty name and nine finite numbers. Every\n * fault is named by its path. Nothing is defaulted: a field the writer always\n * writes is required here.\n */\nfunction readPages(value: unknown, problems: string[], flags: boolean): ModelPage[] {\n if (!Array.isArray(value)) {\n problems.push(`pages is ${JSON.stringify(value) ?? 'absent'}, not a list of pages`);\n return [];\n }\n const out: ModelPage[] = [];\n value.forEach((raw, i) => {\n const where = `pages[${i}]`;\n if (!isRecord(raw)) {\n problems.push(`${where} is not an object`);\n return;\n }\n const before = problems.length;\n const label = typeof raw.name === 'string' ? `${where} \"${raw.name}\"` : where;\n unknownFields(raw, flags ? CORE_PAGE_FIELDS : CORE_PAGE_FIELDS_2, label, problems);\n if (typeof raw.name !== 'string' || raw.name === '') problems.push(`${where}: name is ${JSON.stringify(raw.name) ?? 'absent'}, not a non-empty string`);\n for (const key of ['width', 'height'] as const) {\n const v = raw[key];\n if (typeof v !== 'number' || !Number.isFinite(v) || v <= 0) problems.push(`${label}: ${key} is ${JSON.stringify(v) ?? 'absent'}, not a positive finite number — a page UV divides by it`);\n }\n // Issue #1026: a /3 page states its `pma:` as the runtime reads it and the number its own `scale:` line states, or null for none.\n if (flags) {\n if (typeof raw.pma !== 'boolean') problems.push(`${label}: pma is ${JSON.stringify(raw.pma) ?? 'absent'}, not true or false — whether the page's texels are premultiplied`);\n if (raw.scale !== null && (typeof raw.scale !== 'number' || !Number.isFinite(raw.scale))) problems.push(`${label}: scale is ${JSON.stringify(raw.scale) ?? 'absent'}, not a finite number or null — the number the page's scale: line states, null where it has none`);\n }\n const regions: ModelPageRegion[] = [];\n if (!Array.isArray(raw.regions)) problems.push(`${label}: regions is not a list`);\n // Issue #1054: a page holding no region is one no build writes — the atlas text's block for it would end before any region line, which\n // the round trip refuses (A07_ATLAS_TEXT_SHAPE: \"the last page block declares no region\") — so a document stating one is refused here by\n // the page's name rather than read, where nothing on the model side would name it.\n else if (raw.regions.length === 0) problems.push(`${label}: regions is an empty list — a page holds at least one region; the atlas text cannot state a page with none (its block would end before a region line, which A07_ATLAS_TEXT_SHAPE refuses), so no build writes one`);\n else {\n raw.regions.forEach((region, j) => {\n const at = `${label}.regions[${j}]`;\n if (!isRecord(region)) {\n problems.push(`${at} is not an object`);\n return;\n }\n const named = typeof region.name === 'string' ? `${at} \"${region.name}\"` : at;\n unknownFields(region, CORE_PAGE_REGION_FIELDS, named, problems);\n if (typeof region.name !== 'string' || region.name === '') problems.push(`${at}: name is ${JSON.stringify(region.name) ?? 'absent'}, not a non-empty string`);\n for (const key of CORE_PAGE_REGION_FIELDS) {\n if (key === 'name') continue;\n const v = region[key];\n if (typeof v !== 'number' || !Number.isFinite(v)) problems.push(`${named}: ${key} is ${JSON.stringify(v) ?? 'absent'}, not a finite number`);\n }\n regions.push(region as unknown as ModelPageRegion);\n });\n }\n if (problems.length === before) {\n out.push(\n flags\n ? { name: raw.name as string, width: raw.width as number, height: raw.height as number, pma: raw.pma as boolean, scale: raw.scale as number | null, regions }\n : { name: raw.name as string, width: raw.width as number, height: raw.height as number, regions },\n );\n }\n });\n return out;\n}\n\n/** The `spine` section's value, checked: `{ \"sha256\": <64 lowercase hex> }` and nothing else, each fault named by path (issue #968). */\nfunction readSpineDigest(value: unknown, problems: string[]): string {\n if (value === undefined) return '';\n if (!isRecord(value)) {\n problems.push(`spine is ${JSON.stringify(value)}, not { \"sha256\": \"<64 lowercase hex digits>\" }`);\n return '';\n }\n for (const key of Object.keys(value)) if (key !== 'sha256') problems.push(`spine: field \"${key}\" is not one this reader knows; it reads [sha256]`);\n const sha = value.sha256;\n if (typeof sha !== 'string' || !/^[0-9a-f]{64}$/.test(sha)) {\n problems.push(`spine.sha256 is ${JSON.stringify(sha) ?? 'absent'}, not 64 lowercase hex digits — the SHA-256 of the skeleton.json written beside the document`);\n return '';\n }\n return sha;\n}\n\n/**\n * The `stage` section, checked (issue #1026): `null` — the header declares no\n * stage — or exactly `CORE_STAGE_FIELDS`, four finite numbers, each fault\n * named by path. Nothing is defaulted: the writer always writes all four.\n */\nfunction readStage(value: unknown, problems: string[]): ModelStage | null {\n if (value === null) return null;\n if (!isRecord(value)) {\n problems.push(`stage is ${JSON.stringify(value) ?? 'absent'}, not null or { x, y, width, height } — the setup-pose box the Spine header declares`);\n return null;\n }\n const before = problems.length;\n unknownFields(value, [...CORE_STAGE_FIELDS, 'box'], 'stage', problems);\n for (const key of CORE_STAGE_FIELDS) {\n const v = value[key];\n if (typeof v !== 'number' || !Number.isFinite(v)) problems.push(`stage: ${key} is ${JSON.stringify(v) ?? 'absent'}, not a finite number`);\n }\n // The stage box (issue #1168): written only where the rig asked for one, and then exactly its two names.\n const box = value.box;\n if (box !== undefined) {\n if (!isRecord(box)) problems.push(`stage.box is ${JSON.stringify(box)}, not { slot, attachment }`);\n else {\n unknownFields(box, CORE_STAGE_BOX_FIELDS, 'stage.box', problems);\n for (const key of CORE_STAGE_BOX_FIELDS) if (typeof box[key] !== 'string' || box[key] === '') problems.push(`stage.box: ${key} is ${JSON.stringify(box[key]) ?? 'absent'}, not a non-empty string`);\n }\n }\n if (problems.length !== before) return null;\n const stage: ModelStage = { x: value.x as number, y: value.y as number, width: value.width as number, height: value.height as number };\n if (isRecord(box)) stage.box = { slot: box.slot as string, attachment: box.attachment as string };\n return stage;\n}\n\n/**\n * The `editorOrder` section, checked against the records the document holds\n * (issue #1026): `skins`, every skin exactly once as `{ name, slots }` with\n * `slots` its table's slot keys exactly once each, and `animations`, every\n * animation's name exactly once. An order naming a skin, slot key or\n * animation the document does not hold, or leaving one out, is refused by\n * path — it would be another rig's order.\n */\nfunction readEditorOrder(value: unknown, skins: readonly CoreSkin[], animations: readonly CoreAnimation[], problems: string[]): ModelEditorOrder {\n const out: ModelEditorOrder = { skins: [], animations: [] };\n if (!isRecord(value)) {\n problems.push(`editorOrder is ${JSON.stringify(value) ?? 'absent'}, not { skins, animations }`);\n return out;\n }\n unknownFields(value, ['skins', 'animations'], 'editorOrder', problems);\n const names = (list: unknown, where: string): string[] | null => {\n if (!Array.isArray(list) || list.some((n) => typeof n !== 'string')) {\n problems.push(`${where} is ${JSON.stringify(list) ?? 'absent'}, not a list of names`);\n return null;\n }\n return list as string[];\n };\n /** `stated` lists exactly the names of `held`, each once — else one problem naming the first difference. */\n const permutation = (stated: readonly string[], held: readonly string[], where: string, what: string): void => {\n const seen = new Set<string>();\n for (const name of stated) {\n if (seen.has(name)) return void problems.push(`${where} lists ${what} \"${name}\" twice`);\n seen.add(name);\n if (!held.includes(name)) return void problems.push(`${where} lists ${what} \"${name}\", which the document does not hold`);\n }\n const missing = held.find((name) => !seen.has(name));\n if (missing !== undefined) problems.push(`${where} leaves out ${what} \"${missing}\"`);\n };\n if (!Array.isArray(value.skins)) problems.push(`editorOrder.skins is ${JSON.stringify(value.skins) ?? 'absent'}, not a list`);\n else {\n value.skins.forEach((entry, i) => {\n const at = `editorOrder.skins[${i}]`;\n if (!isRecord(entry) || typeof entry.name !== 'string') return void problems.push(`${at} is not { name, slots }`);\n unknownFields(entry, ['name', 'slots'], at, problems);\n const slots = names(entry.slots, `${at}.slots`);\n const skin = skins.find((k) => k.name === entry.name);\n if (slots !== null && skin !== undefined) permutation(slots, Object.keys(skin.attachments), `${at}.slots`, 'slot key');\n out.skins.push({ name: entry.name, slots: slots ?? [] });\n });\n permutation(out.skins.map((k) => k.name), skins.map((k) => k.name), 'editorOrder.skins', 'skin');\n }\n const order = names(value.animations, 'editorOrder.animations');\n if (order !== null) {\n permutation(order, animations.map((a) => a.name), 'editorOrder.animations', 'animation');\n out.animations = order;\n }\n return out;\n}\n\nconst isRecord = (v: unknown): v is Record<string, unknown> => typeof v === 'object' && v !== null && !Array.isArray(v);\n\n/** The mode a stated `inheritMode` folds to — the first letter lower-cased and nothing else — or null. */\nexport function foldInheritMode(value: string): (typeof CORE_INHERIT_MODES)[number] | null {\n const folded = value.length === 0 ? value : value[0].toLowerCase() + value.slice(1);\n return CORE_INHERIT_MODES.find((m) => m === folded) ?? null;\n}\n\nfunction unknownFields(record: Record<string, unknown>, known: readonly string[], where: string, problems: string[]): void {\n for (const key of Object.keys(record)) {\n if (!known.includes(key)) problems.push(`${where}: field \"${key}\" is not one this reader knows; it reads [${known.join(', ')}]`);\n }\n}\n\nfunction readBones(value: unknown, problems: string[]): ModelBone[] {\n if (!Array.isArray(value)) {\n problems.push('bones is not a list');\n return [];\n }\n const out: ModelBone[] = [];\n const seen = new Set<string>();\n value.forEach((raw, i) => {\n const where = `bones[${i}]`;\n if (!isRecord(raw)) {\n problems.push(`${where} is not an object`);\n return;\n }\n const label = typeof raw.name === 'string' ? `${where} \"${raw.name}\"` : where;\n unknownFields(raw, CORE_BONE_FIELDS, label, problems);\n if (typeof raw.name !== 'string' || raw.name === '') problems.push(`${where}: name is ${JSON.stringify(raw.name)}, not a non-empty string`);\n else if (seen.has(raw.name)) problems.push(`${label}: the name is declared twice`);\n if (raw.parent !== undefined) {\n if (typeof raw.parent !== 'string') problems.push(`${label}: parent is ${JSON.stringify(raw.parent)}, not a bone name`);\n else if (!seen.has(raw.parent)) problems.push(`${label}: parent \"${raw.parent}\" is not declared before it; bones are parents first`);\n }\n for (const key of BONE_NUMBERS) {\n const v = raw[key];\n if (v !== undefined && (typeof v !== 'number' || !Number.isFinite(v))) problems.push(`${label}: ${key} is ${JSON.stringify(v)}, not a finite number`);\n }\n if (raw.inheritMode !== undefined) {\n if (typeof raw.inheritMode !== 'string' || foldInheritMode(raw.inheritMode) === null) {\n problems.push(`${label}: inheritMode is ${JSON.stringify(raw.inheritMode)}, which folds to none of ${CORE_INHERIT_MODES.join(', ')}`);\n }\n }\n if (raw.skinRequired !== undefined && typeof raw.skinRequired !== 'boolean') problems.push(`${label}: skinRequired is ${JSON.stringify(raw.skinRequired)}, not a boolean`);\n if (raw.editor !== undefined) {\n if (!isRecord(raw.editor)) problems.push(`${label}: editor is not an object`);\n else {\n unknownFields(raw.editor, ['color', 'icon'], `${label}.editor`, problems);\n for (const key of ['color', 'icon'] as const) {\n if (raw.editor[key] !== undefined && typeof raw.editor[key] !== 'string') problems.push(`${label}.editor: ${key} is not a string`);\n }\n }\n }\n if (typeof raw.name === 'string' && raw.name !== '') seen.add(raw.name);\n out.push(raw as unknown as ModelBone);\n });\n return out;\n}\n\nfunction readSlots(value: unknown, bones: ReadonlySet<string>, problems: string[]): ModelSlot[] {\n if (!Array.isArray(value)) {\n problems.push('slots is not a list');\n return [];\n }\n const out: ModelSlot[] = [];\n value.forEach((raw, i) => {\n const where = `slots[${i}]`;\n if (!isRecord(raw)) {\n problems.push(`${where} is not an object`);\n return;\n }\n const label = typeof raw.name === 'string' ? `${where} \"${raw.name}\"` : where;\n unknownFields(raw, CORE_SLOT_FIELDS, label, problems);\n if (typeof raw.name !== 'string' || raw.name === '') problems.push(`${where}: name is ${JSON.stringify(raw.name)}, not a non-empty string`);\n if (typeof raw.bone !== 'string') problems.push(`${label}: bone is ${JSON.stringify(raw.bone)}, not a bone name`);\n else if (!bones.has(raw.bone)) problems.push(`${label}: bone \"${raw.bone}\" is not a bone of this document`);\n if (raw.setup !== null && typeof raw.setup !== 'string') problems.push(`${label}: setup is ${JSON.stringify(raw.setup)}, not a placeholder name or null`);\n for (const key of ['color', 'dark', 'blend'] as const) {\n if (raw[key] !== undefined && typeof raw[key] !== 'string') problems.push(`${label}: ${key} is ${JSON.stringify(raw[key])}, not a string`);\n }\n for (const key of ['color', 'dark'] as const) {\n const v = raw[key];\n if (typeof v === 'string' && !HEX_COLOUR.test(v)) problems.push(`${label}: ${key} is ${JSON.stringify(v)}, not six or eight hex digits (rrggbb or rrggbbaa) — the only spellings whose reading was measured to be a colour`);\n }\n if (typeof raw.blend === 'string' && foldBlend(raw.blend) === null) {\n problems.push(`${label}: blend is ${JSON.stringify(raw.blend)}, which the runtime reads as no mode — one of ${CORE_BLEND_MODES.join(', ')}, first letter in either case, is the only spelling measured to be one`);\n }\n out.push(raw as unknown as ModelSlot);\n });\n return out;\n}\n\nfunction readAttachments(value: Record<string, unknown>, bones: ReadonlySet<string>, slots: ReadonlySet<string>, label: string, problems: string[]): Record<string, Record<string, CoreAttachment>> {\n const out: Record<string, Record<string, CoreAttachment>> = {};\n for (const [slot, table] of Object.entries(value)) {\n const at = `${label}.attachments[\"${slot}\"]`;\n if (!slots.has(slot)) problems.push(`${at}: \"${slot}\" is not a slot of this document`);\n if (!isRecord(table)) {\n problems.push(`${at} is not an object`);\n continue;\n }\n const entries: Record<string, CoreAttachment> = {};\n for (const [placeholder, raw] of Object.entries(table)) {\n const where = `${at}[\"${placeholder}\"]`;\n if (!isRecord(raw)) {\n problems.push(`${where} is not an object`);\n continue;\n }\n const kinds = Object.keys(CORE_ATTACHMENT_FIELDS) as Array<SkinTableEntry['kind']>;\n const kind = kinds.find((k) => k === raw.kind);\n if (kind === undefined) {\n problems.push(`${where}: kind is ${JSON.stringify(raw.kind)}, none of ${kinds.join(', ')}`);\n continue;\n }\n unknownFields(raw, CORE_ATTACHMENT_FIELDS[kind], where, problems);\n const record: CoreAttachment = { kind };\n for (const key of ['name', 'path'] as const) {\n const v = raw[key];\n if (v === undefined) continue;\n if (typeof v !== 'string' || v === '') problems.push(`${where}: ${key} is ${JSON.stringify(v)}, not a non-empty string`);\n else record[key] = v;\n }\n if (kind === 'region' && raw.atlas !== undefined) {\n const rect = readAtlasRect(raw.atlas, `${where}.atlas`, problems);\n if (rect !== undefined) record.atlas = rect;\n }\n const geometry = readGeometry(raw, kind, where, bones, slots, problems);\n if (geometry !== undefined) record.geometry = geometry;\n // The series' length, whatever the kind: a sequence key's index is a frame of it (`./deform.ts`).\n if (isRecord(raw.sequence)) {\n const count = raw.sequence.count;\n if (typeof count === 'number' && Number.isInteger(count) && count >= 1) record.sequenceCount = count;\n else if (kind !== 'region') problems.push(`${where}.sequence: count is ${JSON.stringify(count)}, not a whole number of at least 1`);\n const setupFrame = raw.sequence.setup ?? 0;\n if (typeof setupFrame === 'number' && Number.isInteger(setupFrame) && setupFrame >= 0 && (typeof count !== 'number' || setupFrame < count)) record.sequenceSetup = setupFrame;\n else if (kind !== 'region') problems.push(`${where}.sequence: setup is ${JSON.stringify(raw.sequence.setup)}, not a frame of the ${JSON.stringify(count)}`);\n }\n // The attachment's own colour (issue #966): the raw entry forms the tint from it and the slot's.\n if (raw.color !== undefined) {\n if (typeof raw.color !== 'string' || !HEX_COLOUR.test(raw.color)) problems.push(`${where}: color is ${JSON.stringify(raw.color)}, not six or eight hex digits`);\n else record.color = raw.color;\n }\n if (kind === 'linkedmesh') {\n if (typeof raw.timelines !== 'boolean') problems.push(`${where}: timelines is ${JSON.stringify(raw.timelines) ?? 'absent'}, not a boolean — the writer states whether the link plays its source's timelines`);\n else record.timelines = raw.timelines;\n }\n entries[placeholder] = record;\n }\n out[slot] = entries;\n }\n return out;\n}\n\n/** A region's `atlas`: `null`, or an object holding exactly the six fields, each a finite number. `undefined` when refused. */\nfunction readAtlasRect(value: unknown, where: string, problems: string[]): ModelAtlasRect | null | undefined {\n if (value === null) return null;\n if (!isRecord(value)) {\n problems.push(`${where} is ${JSON.stringify(value)}, neither null nor an object`);\n return undefined;\n }\n const before = problems.length;\n unknownFields(value, CORE_ATLAS_RECT_FIELDS, where, problems);\n for (const key of CORE_ATLAS_RECT_FIELDS) {\n const v = value[key];\n if (typeof v !== 'number' || !Number.isFinite(v)) problems.push(`${where}: ${key} is ${JSON.stringify(v) ?? 'absent'}, not a finite number`);\n }\n return problems.length === before ? (value as unknown as ModelAtlasRect) : undefined;\n}\n\nfunction readSkins(value: unknown, bones: ReadonlySet<string>, slots: ReadonlySet<string>, problems: string[]): CoreSkin[] {\n if (!Array.isArray(value)) {\n problems.push('skins is not a list');\n return [];\n }\n const out: CoreSkin[] = [];\n value.forEach((raw, i) => {\n const where = `skins[${i}]`;\n if (!isRecord(raw)) {\n problems.push(`${where} is not an object`);\n return;\n }\n const label = typeof raw.name === 'string' ? `${where} \"${raw.name}\"` : where;\n unknownFields(raw, CORE_SKIN_FIELDS, label, problems);\n if (typeof raw.name !== 'string' || raw.name === '') problems.push(`${where}: name is ${JSON.stringify(raw.name)}, not a non-empty string`);\n const members: string[] = [];\n if (!Array.isArray(raw.bones)) problems.push(`${label}: bones is not a list`);\n else {\n raw.bones.forEach((b, j) => {\n if (typeof b !== 'string') problems.push(`${label}: bones[${j}] is not a bone name`);\n else if (!bones.has(b)) problems.push(`${label}: bones[${j}] \"${b}\" is not a bone of this document`);\n else members.push(b);\n });\n }\n const lists = Object.fromEntries(CORE_CONSTRAINT_KINDS.map((k) => [k, [] as string[]])) as Record<CoreConstraintKind, string[]>;\n if (!isRecord(raw.constraints)) problems.push(`${label}: constraints is not an object`);\n else {\n for (const [kind, list] of Object.entries(raw.constraints)) {\n const known = CORE_CONSTRAINT_KINDS.find((k) => k === kind);\n if (known === undefined) problems.push(`${label}.constraints: \"${kind}\" is not a constraint kind; a skin lists ${CORE_CONSTRAINT_KINDS.join(', ')}`);\n else if (!Array.isArray(list) || list.some((n) => typeof n !== 'string')) problems.push(`${label}.constraints.${kind} is not a list of constraint names`);\n else lists[known] = list as string[];\n }\n }\n let attachments: Record<string, Record<string, CoreAttachment>> = {};\n if (!isRecord(raw.attachments)) problems.push(`${label}: attachments is not an object`);\n else attachments = readAttachments(raw.attachments, bones, slots, label, problems);\n out.push({ name: typeof raw.name === 'string' ? raw.name : '', bones: members, constraints: lists, attachments });\n });\n return out;\n}\n\nfunction readAnimations(value: unknown, bones: ReadonlySet<string>, slotRecords: readonly ModelSlot[], skins: readonly CoreSkin[], events: ReadonlyMap<string, CoreEventDef>, problems: string[]): CoreAnimation[] {\n const slots = new Set(slotRecords.map((s) => s.name));\n if (!Array.isArray(value)) {\n problems.push('animations is not a list');\n return [];\n }\n const out: CoreAnimation[] = [];\n value.forEach((raw, i) => {\n const where = `animations[${i}]`;\n if (!isRecord(raw)) {\n problems.push(`${where} is not an object`);\n return;\n }\n if (typeof raw.name !== 'string' || raw.name === '') problems.push(`${where}: name is ${JSON.stringify(raw.name)}, not a non-empty string`);\n const label = typeof raw.name === 'string' ? `${where} \"${raw.name}\"` : where;\n const keyed: string[] = [];\n if (!Array.isArray(raw.slots)) problems.push(`${label}: slots is not a list`);\n else {\n raw.slots.forEach((entry, j) => {\n if (!isRecord(entry) || typeof entry.name !== 'string') problems.push(`${label}: slots[${j}] names no slot`);\n else if (!slots.has(entry.name)) problems.push(`${label}: slots[${j}] \"${entry.name}\" is not a slot of this document`);\n else keyed.push(entry.name);\n });\n }\n const deforms: string[] = [];\n // The structure is checked with the key times (`laterKeyTimes` in `./animation.ts`); here only the names are taken.\n const list = (v: unknown): Array<Record<string, unknown>> => (Array.isArray(v) ? v.filter(isRecord) : []);\n for (const skin of list(raw.attachments)) for (const slot of list(skin.slots)) for (const att of list(slot.attachments)) if (att.deform !== undefined) deforms.push(`${String(skin.name)}/${String(slot.name)}/${String(att.name)}`);\n out.push({ name: typeof raw.name === 'string' ? raw.name : '', slots: keyed, timelines: readAnimationTimelines(raw, label, bones, slotRecords, problems, { skins, events }), constraints: { ik: [], transform: [], path: [], physics: 0, slider: [] }, deforms });\n });\n return out;\n}\n\nfunction readConstraints(value: unknown, animations: readonly CoreAnimation[], bones: readonly ModelBone[], slots: readonly ModelSlot[], referenceScale: number, problems: string[]): CoreConstraint[] {\n const names = new Set(bones.map((b) => b.name));\n const slotBones = new Map(slots.map((s) => [s.name, s.bone]));\n const parents = new Map(bones.map((b) => [b.name, b.parent]));\n if (!Array.isArray(value)) {\n problems.push('constraints is not a list');\n return [];\n }\n const out: CoreConstraint[] = [];\n value.forEach((raw, i) => {\n const where = `constraints[${i}]`;\n if (!isRecord(raw)) {\n problems.push(`${where} is not an object`);\n return;\n }\n const kind = CORE_CONSTRAINT_KINDS.find((k) => k === raw.kind);\n if (kind === undefined) problems.push(`${where}: kind is ${JSON.stringify(raw.kind)}, none of ${CORE_CONSTRAINT_KINDS.join(', ')}`);\n if (typeof raw.name !== 'string' || raw.name === '') problems.push(`${where}: name is ${JSON.stringify(raw.name)}, not a non-empty string`);\n if (raw.declaredIn !== 'rig' && raw.declaredIn !== 'motion') problems.push(`${where}: declaredIn is ${JSON.stringify(raw.declaredIn)}, not \"rig\" or \"motion\"`);\n const at = `${where} \"${String(raw.name)}\"`;\n let record: CoreConstraintRecord | undefined;\n if (typeof raw.name === 'string') {\n if (kind === 'ik' || kind === 'transform') record = readConstraintRecord(raw, kind, raw.name, at, names, parents, problems);\n else if (kind === 'path') record = readPathRecord(raw, raw.name, at, names, slotBones, problems);\n else if (kind === 'physics') record = readPhysicsRecord(raw, raw.name, at, names, referenceScale, problems);\n else if (kind === 'slider') record = readSliderRecord(raw, raw.name, at, bones, animations, problems);\n }\n if (kind !== undefined && typeof raw.name === 'string') out.push({ kind, name: raw.name, ...(kind === 'slider' && typeof raw.animation === 'string' ? { animation: raw.animation } : {}), ...(record !== undefined ? { record } : {}) });\n });\n return out;\n}\n\n/**\n * Read a `rigc-compiled/3` document — or a `rigc-compiled/2` one, which has\n * no `stage`, `editorOrder` or page `pma`/`scale` and is read with `stated:\n * null`, or a `rigc-compiled/1` one, which has no `pages` either and is read\n * with `pages: null` — from its text, refusing by name a text\n * that is not JSON, a wrong `spec`, a missing section (`referenceScale`\n * among them, issue #958), a section the document does not have, a\n * `referenceScale` that is not a finite number, and — in the records these constructs read (bones, slots,\n * skins and their attachment tables) — a field the writer does not write (the\n * writer's own rule, `ordered` in `src/model.ts`, mirrored), a value of the\n * wrong type, a colour spelled other than six or eight hex digits, a parent\n * declared after its child and a name that resolves to nothing. Every problem\n * is collected and thrown once.\n */\nexport function readModel(text: string, where = 'the model document'): CompiledDocument {\n let value: unknown;\n try {\n value = JSON.parse(text);\n } catch (err) {\n throw new CoreInputError(`${where}: not JSON — ${(err as Error).message}`);\n }\n if (!isRecord(value)) throw new CoreInputError(`${where}: not a JSON object`);\n if (typeof value.spec !== 'string' || !CORE_DOCUMENT_SPECS.includes(value.spec)) {\n throw new CoreInputError(\n `${where}: spec is ${JSON.stringify(value.spec)}, not \"${CORE_DOCUMENT_SPEC}\" (or \"${CORE_DOCUMENT_SPEC_2}\", read without its stage, editor order and page flags, or \"${CORE_DOCUMENT_SPEC_1}\", read without its pages too)`,\n );\n }\n const spec = value.spec;\n const sections: readonly string[] = spec === CORE_DOCUMENT_SPEC ? CORE_SECTIONS : spec === CORE_DOCUMENT_SPEC_2 ? CORE_SECTIONS_2 : CORE_SECTIONS_1;\n const problems: string[] = [];\n for (const key of sections) if (!(key in value)) problems.push(`section \"${key}\" is missing`);\n for (const key of Object.keys(value)) {\n if (key !== 'spec' && !sections.includes(key)) problems.push(`section \"${key}\" is not one a ${spec} document has`);\n }\n const pages = spec !== CORE_DOCUMENT_SPEC_1 && 'pages' in value ? readPages(value.pages, problems, spec === CORE_DOCUMENT_SPEC) : null;\n const stage = spec === CORE_DOCUMENT_SPEC && 'stage' in value ? readStage(value.stage, problems) : null;\n // The skeleton's reference scale (issue #958): wind and gravity act over it, so a missing one is the section refusal above, and a value the runtime could not read as a number is refused here by name.\n const referenceScale = typeof value.referenceScale === 'number' && Number.isFinite(value.referenceScale) ? value.referenceScale : NaN;\n if ('referenceScale' in value && Number.isNaN(referenceScale)) problems.push(`referenceScale is ${JSON.stringify(value.referenceScale)}, not a finite number — wind and gravity act over it`);\n const spine = readSpineDigest(value.spine, problems);\n const bones = readBones(value.bones, problems);\n const names = new Set(bones.map((b) => b.name));\n const slots = readSlots(value.slots, names, problems);\n const slotNames = new Set(slots.map((x) => x.name));\n const skins = readSkins(value.skins, names, slotNames, problems);\n problems.push(...linkProblems(skins));\n const events = readEventDefs(value.events, problems);\n const animations = readAnimations(value.animations, names, slots, skins, events, problems);\n const constraints = readConstraints(value.constraints, animations, bones, slots, referenceScale, problems);\n // Each skin's constraint lists name a constraint of that kind: the runtime's loader refuses any other name (`./skins.ts`).\n for (const skin of skins) {\n for (const kind of CORE_CONSTRAINT_KINDS) {\n for (const name of skin.constraints[kind]) {\n if (!constraints.some((c) => c.kind === kind && c.name === name)) problems.push(`skin \"${skin.name}\".constraints.${kind}: \"${name}\" is not a ${kind} constraint of this document — the runtime refuses the file (\"Couldn't find … constraint ${name} for skin ${skin.name}.\")`);\n }\n }\n }\n if (Array.isArray(value.animations)) {\n value.animations.forEach((raw, i) => {\n if (isRecord(raw) && animations[i] !== undefined) animations[i].constraints = readConstraintTimelines(raw.constraints, `animations[${i}] \"${animations[i].name}\"`, constraints, problems);\n });\n }\n // A slider's physics timelines are its animation's (issue #1049), read only now.\n for (const c of constraints) {\n const r = c.record;\n if (r?.kind === 'slider') r.physics = animations.find((a) => a.name === r.animation)?.constraints.physicsKeyed ?? [];\n }\n const editorOrder = spec === CORE_DOCUMENT_SPEC && 'editorOrder' in value ? readEditorOrder(value.editorOrder, skins, animations, problems) : null;\n if (problems.length > 0) throw new CoreInputError(`${where}: ${problems.length} problem(s): ${problems.join('; ')}`);\n const stated: CoreStated | null = editorOrder === null ? null : { stage, editorOrder };\n const doc: CompiledDocument = { spec, skin: CORE_ALL_SKINS, referenceScale, bones, slots, skins, constraints, animations, spine: { sha256: spine }, pages, stated };\n resolveSkinView(doc);\n return doc;\n}\n\n/**\n * The document posed under one skin (issue #932): `name` is `all` — every\n * skin merged, `readModel`'s reading — or a skin of the document, refused by\n * name otherwise. The skins, rosters and records are the document's own; the\n * constraint records are copied, so each view carries its own reading of\n * which constraints apply and what a path walks (`resolveSkinView`).\n */\nexport function underSkin(doc: CompiledDocument, name: string): CompiledDocument {\n if (name !== CORE_ALL_SKINS && !doc.skins.some((k) => k.name === name)) {\n throw new CoreInputError(`--skin ${JSON.stringify(name)}: no such skin; this document declares [${doc.skins.map((k) => k.name).join(', ') || 'none'}] (or pass ${CORE_ALL_SKINS})`);\n }\n const view: CompiledDocument = { ...doc, skin: name, constraints: doc.constraints.map((c) => (c.record === undefined ? c : { ...c, record: { ...c.record } as CoreConstraintRecord })) };\n resolveSkinView(view);\n return view;\n}\n\n/**\n * The document posed with no skin set (issue #1051): no skin's `bones` or\n * constraint lists applied — the default skin's included — and every slot\n * resolved through the default skin alone, or through nothing where the\n * document declares none (`./skins.ts`, *No skin set*, for the measurement).\n * The view a fresh skeleton is in: `render` without `--skin`, A10's walk and\n * `validate()`'s poses (`noSkinView` in `src/render_core.ts`).\n */\nexport function underNoSkin(doc: CompiledDocument): CompiledDocument {\n const view: CompiledDocument = { ...doc, skin: null, constraints: doc.constraints.map((c) => (c.record === undefined ? c : { ...c, record: { ...c.record } as CoreConstraintRecord })) };\n resolveSkinView(view);\n return view;\n}\n\n/**\n * What a skin view decides on the constraint records: whether an applied\n * skin's list names each (`listedBySkin`, `./skins.ts`), and what each path\n * constraint walks — the curve its slot shows at setup, or why that cannot\n * be told (`unresolved`) — and which bones its slot reads (`slotDeps`).\n */\nfunction resolveSkinView(doc: CompiledDocument): void {\n for (const c of doc.constraints) if (c.record !== undefined) c.record.listedBySkin = listedByAppliedSkin(doc, c.kind, c.name);\n // A path constraint walks what its slot shows at setup (construct 5's second cut, `./constraints_path.ts`).\n for (const c of doc.constraints) {\n const r = c.record;\n if (r?.kind !== 'path') continue;\n r.path = null;\n r.unresolved = null;\n const slot = doc.slots.find((s) => s.name === r.slot) as ModelSlot;\n const shown = shownAttachment(doc, slot);\n // Under `all`, every skin filling the slot's setup placeholder: the curve walked is the LAST of them in the Spine file's skin order, which the model does not hold (the slots' ⚠️), so skins stating two curves leave it unresolved. Under a named skin one resolves (`fillingSkins`).\n const fills = slot.setup === null ? [] : fillingSkins(doc, slot.name, slot.setup).flatMap((name) => {\n const g = doc.skins.find((k) => k.name === name)?.attachments[slot.name]?.[slot.setup as string]?.geometry;\n return g === undefined ? [] : [{ skin: name, g: JSON.stringify(g) }];\n });\n if (fills.length > 1 && fills.some((f) => f.g !== fills[0].g)) r.unresolved = `path constraint \"${r.name}\" walks slot \"${r.slot}\", whose placeholder \"${slot.setup}\" skins ${fills.map((x) => `\"${x.skin}\"`).join(', ')} fill differently — which one --skin all shows is the Spine file's skin order, not the model's; the per-skin dumps (--skin <name>) judge it`;\n else if (shown !== null && 'conflict' in shown) r.unresolved = `path constraint \"${r.name}\" walks slot \"${r.slot}\", whose placeholder \"${slot.setup}\" skins ${shown.conflict.map((x) => `\"${x.skin}\"`).join(', ')} fill differently — which one --skin all shows is the Spine file's skin order, not the model's; the per-skin dumps (--skin <name>) judge it`;\n else if (shown !== null && shown.record.geometry?.kind === 'path') {\n const g = shown.record.geometry;\n r.path = { vertices: g.vertices, closed: g.closed, constantSpeed: g.constantSpeed, lengths: g.lengths };\n }\n const deps: string[] = [];\n for (const skin of lookupSkins(doc)) {\n for (const record of Object.values(skin.attachments[r.slot] ?? {})) {\n const g = record.geometry;\n if (g?.kind !== 'path') continue;\n for (const b of g.vertices.weighted ? g.vertices.bindings.flatMap((v) => v.map((x) => x.bone)) : [r.slotBone]) if (!deps.includes(b)) deps.push(b);\n }\n }\n r.slotDeps = deps;\n }\n}\n\n/** Every linked mesh whose `skin`, `slot` and `source` do not resolve to a mesh record, named — the runtime refuses such a file too. */\nfunction linkProblems(skins: readonly CoreSkin[]): string[] {\n const out: string[] = [];\n skins.forEach((skin, i) => {\n for (const [slot, table] of Object.entries(skin.attachments)) {\n for (const [placeholder, record] of Object.entries(table)) {\n const g = record.geometry;\n if (g?.kind !== 'linkedmesh') continue;\n const why = sourceProblem(skins, g.skin, g.slot, g.source);\n if (why !== null) out.push(`skins[${i}] \"${skin.name}\".attachments[\"${slot}\"][\"${placeholder}\"]: ${why}`);\n }\n }\n });\n return out;\n}\n\n/** Why a linked mesh's source does not resolve, or null when it is a mesh record. */\nfunction sourceProblem(skins: readonly CoreSkin[], skin: string, slot: string, source: string): string | null {\n const found = skins.find((k) => k.name === skin);\n if (found === undefined) return `the linked mesh's skin \"${skin}\" is not a skin of this document`;\n const record = found.attachments[slot]?.[source];\n if (record === undefined) return `the linked mesh's source \"${source}\" is not in skin \"${skin}\" slot \"${slot}\"`;\n if (record.kind !== 'mesh') return `the linked mesh's source \"${source}\" in skin \"${skin}\" slot \"${slot}\" is a ${record.kind}, not a mesh`;\n return null;\n}\n\n/**\n * The oracle's rounding, stated in its header: six decimals, half up\n * (`Math.round(v * 1e6) / 1e6`), `null` for a value that is not finite, and a\n * `-0` written as `0`. `tools/pose_oracle.ts` rounds with this function, so the\n * two dumpers cannot round two ways.\n */\nexport function gridRound(v: number): number | null {\n if (!Number.isFinite(v)) return null;\n const out = Math.round(v * 1e6) / 1e6;\n return out === 0 ? 0 : out;\n}\n\n/**\n * The raw entry's number (issue #966): the double as computed, `null` for a\n * value that is not finite, and a `-0` written as `0` — what `JSON.stringify`\n * writes for it anyway, so an in-process row and its document agree. No grid:\n * `pose_oracle.ts dump --raw` writes both dumpers' numbers through this.\n */\nexport function rawNumber(v: number): number | null {\n if (!Number.isFinite(v)) return null;\n return v === 0 ? 0 : v;\n}\n\n/** One bone of a posed setup: `[name, worldX, worldY, a, b, c, d, active, parent]`, the oracle's row. */\nexport type CoreBoneRow = [string, number | null, number | null, number | null, number | null, number | null, number | null, 0 | 1, string | null];\n\n/** What computes the world transforms: the core's own `worldTransforms` (`./world.ts`) unless a caller passes another. */\nexport type SetupEvaluator = (bones: readonly ModelBone[], active: ReadonlySet<string>) => Map<string, CoreWorld>;\n\n/** One slot of a posed setup: `[name, attachment, r, g, b, a, dark, path, blend]`, the oracle's row. */\nexport type CoreSlotRow = [string, string | null, number | null, number | null, number | null, number | null, [number | null, number | null, number | null] | null, string | null, string | null];\n\n/** The record a slot's setup placeholder resolves to, and the skin whose table holds it. */\nexport interface CoreShown {\n skin: string;\n placeholder: string;\n record: CoreAttachment;\n}\n\n/**\n * What a slot shows at setup: `null` for nothing, the record shown, or — when\n * the skins filling its placeholder disagree about the row — `conflict`,\n * naming each skin with the name it would show (the header's ⚠️).\n */\nexport type ShownResolution = CoreShown | null | { conflict: Array<{ skin: string; shown: string; path: string | null }> };\n\n/** What resolves a slot's setup attachment: `shownAttachment` unless a caller passes another. */\nexport type ShownResolver = (doc: CompiledDocument, slot: ModelSlot) => ShownResolution;\n\n/** What reads a slot's blend mode: `readBlend` unless a caller passes another. */\nexport type BlendReader = (slot: ModelSlot) => CoreBlendMode;\n\n/** What reads a stated light colour into its four channels: `readColour` unless a caller passes another. */\nexport type ColourReader = (hex: string) => [number, number, number, number];\n\n/**\n * What the core poses with, each part replaceable. The core suite's plants\n * pass a copy of one of them — a mode's sign flipped, the wrong skin, a\n * channel misread — and nothing else passes any.\n */\nexport interface CorePlant {\n evaluate?: SetupEvaluator;\n shown?: ShownResolver;\n colour?: ColourReader;\n /** A slot's blend mode (`readBlend`). */\n blend?: BlendReader;\n /** A region's corners (`regionCorners` in `./vertices.ts`). */\n region?: RegionPoser;\n /** A vertex array's world positions (`worldVertices` in `./vertices.ts`). */\n vertices?: VertexPoser;\n /** The ik, transform and path constraints as posed, rewritten before they are applied (`./constraints.ts`). */\n constraints?: ConstraintPlant;\n /** Issue #979's solver rules, one planted back to the reading before it (`RUNTIME_SOLVER_RULES` in `./constraints.ts`). */\n solver?: Partial<SolverRules>;\n /** A deform timeline's array at a time (`deformAt` in `./deform.ts`). */\n deform?: DeformEvaluator;\n /** A slider's deform over the current one (`blendDeform` in `./deform.ts`). */\n deformBlend?: DeformBlender;\n /** A sequence timeline's frame at a time (`sequenceFrameAt` in `./deform.ts`). */\n sequence?: SequenceEvaluator;\n /** A draw-order timeline's order at a time (`drawOrderAt` in `./draw_order.ts`). */\n drawOrder?: DrawOrderEvaluator;\n /** The events fired between two samples (`eventsFired` in `./events.ts`). */\n events?: EventsFired;\n /** The stepped phase's step of one physics constraint (`stepPhysics` in `./constraints_physics.ts`). */\n physicsStep?: PhysicsStepper;\n /** One attachment's triangles against a clip polygon (`clipTriangles` in `./clipping.ts`). */\n clip?: TriangleClipper;\n /** One attachment's triangles against any clip the core draws (`clipThrough` in `./clipping.ts`) — the drawn rows the raw entry hands the render. */\n through?: ShapeClipper;\n /** Whether a slot's timelines apply (`slotTimelinesApply` in `./skins.ts`). */\n slotTimelines?: SlotTimelineGate;\n /**\n * Not a plant: what every number of a row is written as — `gridRound` (the\n * oracle's grid) unless the raw entry (`./raw.ts`, issue #966) passes\n * `rawNumber`, the unrounded double.\n */\n round?: (v: number) => number | null;\n}\n\n/** The document's ik, transform and path constraint records, in its order — what `applyConstraints` runs. */\nexport function constraintRecords(doc: CompiledDocument): CoreConstraintRecord[] {\n return doc.constraints.flatMap((c) => (c.record === undefined ? [] : [c.record]));\n}\n\n/**\n * The blocks of the oracle's document the core does not produce, each with the\n * construct that has to be admitted first (§5 of the design on issue #380), in the\n * document's key order. Empty since issue #956 wrote the `physics` block, the\n * last one; kept so a block left to a later construct has one place to be\n * named. `setup.*` blocks are not here: each is produced, or absent for the\n * reason `poseSetup` gives.\n */\nexport const NOT_ADMITTED: ReadonlyArray<readonly [string, string]> = [];\n\n/** The setup blocks the core poses, in the document's order. */\nconst POSED_BLOCKS = ['setup.bones', 'setup.slots', 'setup.drawOrder', 'setup.attachments', 'setup.clips', 'setup.clipped'] as const;\n\n/** Each view's active bones, kept for the view (`activeBones`). */\nconst activeOfView = new WeakMap<CompiledDocument, ReadonlySet<string>>();\n\n/**\n * Bones active under the skin view posed — the rule measured in the header\n * (`all`) and in `./skins.ts` (a named skin). Derived once per view object and\n * kept with it (issue #1134): the answer reads the view's bones and skins\n * only, a view is never written once it is posed, and every pose of a walk\n * asked again. Read-only to every caller; a view built anew (`underSkin`,\n * `underNoSkin`, a plant's) derives its own.\n */\nexport function activeBones(doc: CompiledDocument): ReadonlySet<string> {\n const kept = activeOfView.get(doc);\n if (kept !== undefined) return kept;\n const made = deriveActiveBones(doc);\n activeOfView.set(doc, made);\n return made;\n}\n\nfunction deriveActiveBones(doc: CompiledDocument): ReadonlySet<string> {\n const named = new Set(appliedSkins(doc).flatMap((s) => s.bones));\n const parentOf = new Map(doc.bones.map((b) => [b.name, b.parent]));\n const reached = new Set<string>();\n for (const name of named) {\n for (let at: string | undefined = name; at !== undefined && !reached.has(at); at = parentOf.get(at)) reached.add(at);\n }\n return new Set(doc.bones.filter((b) => b.skinRequired !== true || reached.has(b.name)).map((b) => b.name));\n}\n\n/**\n * A stated light colour's four channels: each pair of hex digits over 255,\n * and an alpha of 1 when six digits are stated (the header's measurement).\n * `readModel` has already refused every other spelling.\n */\nexport function readColour(hex: string): [number, number, number, number] {\n const channel = (i: number): number => Number.parseInt(hex.slice(2 * i, 2 * i + 2), 16) / 255;\n return [channel(0), channel(1), channel(2), hex.length === 8 ? channel(3) : 1];\n}\n\n/**\n * A slot's blend mode: `Normal` when it states none, else the stated\n * spelling folded (the header's measurement). `readModel` has already refused\n * every spelling that folds to no mode.\n */\nexport function readBlend(slot: ModelSlot): CoreBlendMode {\n if (slot.blend === undefined) return 'Normal';\n const mode = foldBlend(slot.blend);\n if (mode === null) throw new CoreInputError(`slot \"${slot.name}\": blend ${JSON.stringify(slot.blend)} is no mode the runtime reads`);\n return mode;\n}\n\n/** The name a record shows and the region path it names — the header's two measured rules. */\nexport function shownRow(shown: CoreShown): { name: string; path: string | null } {\n const name = shown.record.name ?? shown.placeholder;\n return { name, path: CORE_REGION_KINDS.has(shown.record.kind) ? (shown.record.path ?? name) : null };\n}\n\n/** Each view's resolutions, by slot and placeholder, kept for the view (`shownAttachment`). */\nconst shownOfView = new WeakMap<CompiledDocument, Map<string, Map<string, ShownResolution>>>();\n\n/**\n * What a slot shows at setup under every skin at once — the header's rule:\n * nothing for a `null` placeholder or one no skin fills; the one record where\n * every skin filling the placeholder gives the same row; a `conflict`, naming\n * each skin in the model's order, where they differ.\n *\n * The answer reads the view's skins and the slot's name and placeholder only,\n * so it is resolved once per view, slot and placeholder and kept (issue\n * #1134: every sample of a walk resolved every slot again). Read-only to every\n * caller; a view built anew resolves its own.\n */\nexport function shownAttachment(doc: CompiledDocument, slot: ModelSlot): ShownResolution {\n if (slot.setup === null) return null;\n let bySlot = shownOfView.get(doc);\n if (bySlot === undefined) {\n bySlot = new Map();\n shownOfView.set(doc, bySlot);\n }\n let byPlaceholder = bySlot.get(slot.name);\n if (byPlaceholder === undefined) {\n byPlaceholder = new Map();\n bySlot.set(slot.name, byPlaceholder);\n }\n if (byPlaceholder.has(slot.setup)) return byPlaceholder.get(slot.setup) as ShownResolution;\n const resolved = resolveShown(doc, slot.name, slot.setup);\n byPlaceholder.set(slot.setup, resolved);\n return resolved;\n}\n\nfunction resolveShown(doc: CompiledDocument, slotName: string, placeholder: string): ShownResolution {\n // Under a named skin: that skin's record, else the default skin's, else nothing (`./skins.ts`).\n if (doc.skin !== CORE_ALL_SKINS) {\n for (const skin of lookupSkins(doc)) {\n const record = skin.attachments[slotName]?.[placeholder];\n if (record !== undefined) return { skin: skin.name, placeholder, record };\n }\n return null;\n }\n const filling: CoreShown[] = [];\n for (const skin of doc.skins) {\n const record = skin.attachments[slotName]?.[placeholder];\n if (record !== undefined) filling.push({ skin: skin.name, placeholder, record });\n }\n if (filling.length === 0) return null;\n const rows = filling.map((f) => ({ skin: f.skin, ...shownRow(f) }));\n const agree = rows.every((r) => r.name === rows[0].name && r.path === rows[0].path);\n return agree ? filling[0] : { conflict: rows.map((r) => ({ skin: r.skin, shown: r.name, path: r.path })) };\n}\n\n/** The oracle's `setup` block as the core writes it: bones, slots, attachments and clips posed or absent, the draw order absent. */\nexport interface CoreSetup {\n bones: CoreBoneRow[] | null;\n slots: CoreSlotRow[] | null;\n drawOrder: string[] | null;\n attachments: CoreAttachmentRow[] | null;\n clips: CoreClipRow[] | null;\n /** The triangles drawn under a clip, as the clipper returns them (issue #964, `./clipping.ts`). */\n clipped: CoreClippedRow[] | null;\n}\n\n/**\n * The setup pose of every bone and every slot, in the oracle's row shapes and\n * rounding, and every block the core leaves absent with its reason (`absent`,\n * in document order). Bones are absent when the document declares a\n * constraint (the header's ⚠️), with the kinds and counts named; slots are\n * absent when a slot's setup placeholder is filled by skins that disagree\n * (the slots' ⚠️), with each such slot named. The attachments' world vertices\n * and the clipping polygons (`./vertices.ts`, issue #931) are absent when\n * either of those is — they go through the bones' world matrices and follow\n * what each slot shows — and the attachments also when a shown region's atlas\n * rectangle is `null`, every such slot named.\n */\nexport function poseSetup(doc: CompiledDocument, plant: CorePlant = {}, physics?: PhysicsStepContext): { setup: CoreSetup; absent: Array<[string, string]>; world: Map<string, CoreWorld> | null; shown: ShownGeometry[] | null } {\n const evaluate = plant.evaluate ?? worldTransforms;\n const resolve = plant.shown ?? shownAttachment;\n const colour = plant.colour ?? readColour;\n const blend = plant.blend ?? readBlend;\n const round = plant.round ?? gridRound;\n const bonesWhy = constraintsAbsentWhy(doc, solverRules(plant.solver));\n let bones: CoreBoneRow[] | null = null;\n let setupWorld: Map<string, CoreWorld> | null = null;\n // Each slider as it was applied, in constraint order — what the slots are posed from (`./constraints_slider.ts`).\n const applied: SliderApplication[] = [];\n if (bonesWhy === null) {\n const active = activeBones(doc);\n const records = constraintRecords(doc);\n setupWorld = applyConstraints(doc.bones, evaluate(doc.bones, active), active, plant.constraints ? plant.constraints(records) : records, null, applied, physics, undefined, solverRules(plant.solver));\n const world = setupWorld;\n bones = doc.bones.map((b): CoreBoneRow => {\n const t = world.get(b.name);\n if (t === undefined) throw new CoreInputError(`the evaluator returned no transform for bone \"${b.name}\"`);\n return [b.name, round(t.worldX), round(t.worldY), round(t.a), round(t.b), round(t.c), round(t.d), active.has(b.name) ? 1 : 0, b.parent ?? null];\n });\n }\n const conflicts: string[] = [];\n const slotRows: CoreSlotRow[] = [];\n const liveBones = activeBones(doc);\n const slotGate = plant.slotTimelines ?? slotTimelinesApply;\n for (const slot of doc.slots) {\n const pose: SlotPoseState = {\n placeholder: slot.setup,\n light: slot.color === undefined ? [1, 1, 1, 1] : [...colour(slot.color)],\n dark: slot.dark === undefined ? null : readColour(slot.dark).slice(0, 3),\n };\n // A slot on an inactive bone is not animated, by a slider either (`./skins.ts`).\n if (slotGate(doc, slot, liveBones)) applySliderSlots(slot.name, pose, applied);\n const posedRecord: ModelSlot = { ...slot, setup: pose.placeholder };\n const shown = pose.placeholder === null ? null : resolve(doc, posedRecord);\n if (shown !== null && 'conflict' in shown) {\n conflicts.push(`slot \"${slot.name}\" placeholder \"${pose.placeholder}\" is filled by skins ${shown.conflict.map((c) => `\"${c.skin}\" (shows ${JSON.stringify(c.shown)}, path ${JSON.stringify(c.path)})`).join(', ')}`);\n continue;\n }\n const row = shown === null ? null : shownRow(shown);\n const [r, g, b, a] = pose.light;\n const dark = pose.dark;\n slotRows.push([\n slot.name,\n row === null ? null : row.name,\n round(r), round(g), round(b), round(a),\n dark === null ? null : [round(dark[0]), round(dark[1]), round(dark[2])],\n row === null ? null : row.path,\n blend(slot),\n ]);\n }\n const slotsWhy = (bonesWhy === null ? null : slidersWhy(doc)) ?? (conflicts.length === 0\n ? null\n : `${conflicts.join('; ')} — under --skin all the LAST of them in the Spine file's skin order wins, and that order is the emitter's (default first, the rest in the editor's order), not the model's; the per-skin dumps (--skin <name>) judge it`);\n const slots = slotsWhy === null ? slotRows : null;\n const upstream = [bonesWhy === null ? null : `setup.bones is absent (${bonesWhy}), and every vertex goes through a bone's world matrix`, slotsWhy === null ? null : 'setup.slots is absent, so what a slot shows is not posed'].filter((x): x is string => x !== null);\n // The draw order: the slot order, then each slider's draw-order key (`./draw_order.ts`), which needs the sliders' times, read off the bones.\n const orderWhy = bonesWhy === null ? null : slidersKeyingWhy(doc, 'drawOrder');\n let drawOrder: string[] | null = null;\n if (orderWhy === null) {\n let order: number[] = doc.slots.map((_s, i) => i);\n for (const app of applied) order = (plant.drawOrder ?? drawOrderAt)(doc.slots.length, app.timelines.drawOrder, app.at) ?? order;\n drawOrder = order.map((i) => doc.slots[i].name);\n }\n let attachments: CoreAttachmentRow[] | null = null;\n let clips: CoreClipRow[] | null = null;\n let clipsWhy: string | null = upstream.length === 0 ? null : upstream.join('; ');\n let attachmentsWhy: string | null = clipsWhy;\n let clipped: CoreClippedRow[] | null = null;\n let clippedWhy: string | null = clipsWhy ?? orderWhy;\n // What the raw entry reads past the rows (issue #966, `./raw.ts`): the unrounded world transforms and the shown records in draw order.\n let shownInOrder: ShownGeometry[] | null = null;\n if (clipsWhy === null && setupWorld !== null && drawOrder !== null) {\n const world = setupWorld;\n // Each slot's shown record, with what the sliders' deform and sequence timelines set on it (`./deform.ts`), in the draw order.\n // From the setup placeholders; `attachmentStates` applies each slider's attachment key, then its deform and sequence keys, in order.\n const placeholders = new Map(doc.slots.map((sl) => [sl.name, sl.setup]));\n const states = attachmentStates(doc, resolve, placeholders, null, applied, plant);\n const rank = new Map(drawOrder.map((n, i) => [n, i]));\n const shown = [...states.shown].sort((a, b) => (rank.get(a.slot) ?? 0) - (rank.get(b.slot) ?? 0));\n shownInOrder = states.why.length === 0 ? shown : null;\n const posed = poseGeometry(shown, world, sourceOfDoc(doc), round, { region: plant.region, vertices: plant.vertices }, drawWalkOf(doc, drawOrder, plant));\n const stateWhy = states.why.length === 0 ? null : `${states.why.join('; ')}`;\n attachments = stateWhy === null ? posed.attachments : null;\n attachmentsWhy = stateWhy ?? posed.attachmentsWhy;\n clips = stateWhy === null ? posed.clips : null;\n clipsWhy = stateWhy;\n clipped = stateWhy === null ? posed.clipped : null;\n clippedWhy = stateWhy ?? posed.clippedWhy;\n }\n // `NOT_ADMITTED` is in document order; bones and slots stand before `setup.drawOrder`, attachments and clips after it.\n const why: Record<(typeof POSED_BLOCKS)[number], string | null> = { 'setup.bones': bonesWhy, 'setup.slots': slotsWhy, 'setup.drawOrder': orderWhy, 'setup.attachments': attachmentsWhy, 'setup.clips': clipsWhy, 'setup.clipped': clippedWhy };\n // `NOT_ADMITTED` (empty since issue #956) stands before the setup blocks in the document's order.\n const absent: Array<[string, string]> = NOT_ADMITTED.map(([block, reason]): [string, string] => [block, reason]);\n for (const block of POSED_BLOCKS) if (why[block] !== null) absent.push([block, why[block] as string]);\n return { setup: { bones, slots, drawOrder, attachments, clips, clipped }, absent, world: setupWorld, shown: shownInOrder };\n}\n\n/** What the clipped block's draw walk reads (`DrawWalk` in `./vertices.ts`): the draw order, the active bones, and a linked mesh's source triangles. */\nexport function drawWalkOf(doc: CompiledDocument, order: readonly string[], plant: CorePlant = {}): DrawWalk {\n const active = activeBones(doc);\n return {\n order,\n active,\n meshOf: (skin, slot, source) => {\n const g = doc.skins.find((k) => k.name === skin)?.attachments[slot]?.[source]?.geometry;\n return g?.kind === 'mesh' ? { uvs: g.uvs, triangles: g.triangles } : undefined;\n },\n ...(plant.clip === undefined ? {} : { clip: plant.clip }),\n ...(plant.through === undefined ? {} : { through: plant.through }),\n };\n}\n\n/** A linked mesh's source vertices, or why they do not resolve — what `poseGeometry` reads a linked mesh through. */\nexport function sourceOfDoc(doc: CompiledDocument): (skin: string, slot: string, source: string) => ModelVertices | string {\n return (skin, slot, source) => {\n const g = doc.skins.find((k) => k.name === skin)?.attachments[slot]?.[source]?.geometry;\n return g?.kind === 'mesh' ? g.vertices : (sourceProblem(doc.skins, skin, slot, source) ?? `the linked mesh's source \"${source}\" carries no vertices`);\n };\n}\n\n/** Why a block a slider's animation keys cannot be posed because the bones its time is read from are absent, or null: `drawOrder` for the draw order. */\nexport function slidersKeyingWhy(doc: CompiledDocument, group: 'drawOrder'): string | null {\n const keyed = doc.constraints.flatMap((c) => {\n if (c.kind !== 'slider') return [];\n const anim = doc.animations.find((a) => a.name === c.animation);\n return anim !== undefined && anim.timelines[group].length > 0 ? [`slider \"${c.name}\" applies animation \"${c.animation}\", which keys the draw order`] : [];\n });\n return keyed.length === 0 ? null : `${keyed.join('; ')} — a slider's time is read off the bones, which are absent`;\n}\n\n/** Why the setup slots cannot be posed because a slider poses them and the bones its time is read from are absent, or null when no slider's animation keys a slot. */\nfunction slidersWhy(doc: CompiledDocument): string | null {\n const keyed = doc.constraints.flatMap((c) => {\n if (c.kind !== 'slider') return [];\n const slots = doc.animations.find((a) => a.name === c.animation)?.slots ?? [];\n return slots.length === 0 ? [] : [`slider \"${c.name}\" applies animation \"${c.animation}\", which keys slot(s) ${slots.map((x) => `\"${x}\"`).join(', ')}`];\n });\n return keyed.length === 0 ? null : `${keyed.join('; ')} — the oracle's setup applies sliders, and a slider poses the slots its animation keys at a time read off the bones, which are absent`;\n}\n","/**\n * The core's raw entry (issue #966, step 3b of issue #380): one pose, or one\n * animation walked at the caller's own steps, returned as the doubles the\n * core computed — no grid — with everything a renderer or a deform measurer\n * reads past the oracle's rows: each bone's world rotation and scale\n * readings, each drawn attachment's local UVs, triangles, hull, sequence\n * frame and colour, the clip polygons, the triangles drawn under a clip, and\n * the events fired.\n *\n * The oracle's document (`tools/pose_oracle.ts`) samples an animation on a\n * phase grid, re-applying it from the setup pose at every sample; the two\n * consumers step instead. `src/render.ts` resets a track at 0 and then takes\n * exactly one step of `1/fps` per frame; `src/deformmeasure.ts` resets and\n * takes one step of `time`. So the entry takes a list of steps rather than a\n * list of times, and this header states what one step is, as measured.\n *\n * ## One step — the walk, measured\n *\n * Measured against spine-core 4.3.13 running `src/render.ts`'s recipe\n * (`AnimationState` with one non-looping track: frame 0 `apply`,\n * `Skeleton.update(0)`, `updateWorldTransform(Physics.reset)`; every later\n * frame `AnimationState.update(dt)`, `apply`, `Skeleton.update(dt)`,\n * `updateWorldTransform(Physics.update)`), read off `TrackEntry.trackTime`,\n * `TrackEntry.getAnimationTime()` and every bone's `appliedPose` in full\n * doubles (the PR of issue #966 carries the table):\n *\n * - **The track time is the running sum of the steps**, `T += dt` in double,\n * not `i·dt`, and the animation is applied at the sum. Over every\n * animation of the nineteen tree rows `TrackEntry.trackTime` equalled the\n * running sum on 2,612 of 2,612 frames at 12 fps (12,850 of 12,850 at 60,\n * 5,173 of 5,173 at 24) and `i·dt` on only 662 (1,168; 810): at 12 fps\n * frame 6 reads `0.49999999999999994`, not `0.5`, and frame 10\n * `0.8333333333333334`, not `0.8333333333333333`. `src/render.ts` files a\n * frame under `i·dt`, which is its label and not the time posed.\n * - **A non-looping track holds at its duration**: the animation time is\n * `min(T, duration)`, where `duration` is the runtime's (the last key of\n * every timeline, as float32 — `CoreAnimationTimelines.duration`). With\n * `round(duration·fps)` frames the last one overshoots on 20 animation\n * frames of the 2,612 at 12 fps (19 at 60, 25 at 24), and\n * `getAnimationTime()` read the duration on every one of them.\n * - **The physics clock moves by the step itself**, `time += dt` (the\n * skeleton's `update`), and a physics constraint integrates the time it\n * moved (`./constraints_physics.ts`). Pose 0 is the reset, every physics\n * state reset there (where, below).\n * - **Events fire over `(previous animation time, animation time]`**, the\n * first step's interval opening at −1 — so held past the duration, a step\n * fires nothing. Measured against `AnimationState`'s event listener on\n * every frame above.\n * - **Where the reset is taken is the caller's** (`RawReset`): render's\n * frame 0 applies the animation at 0 and resets there (`animation`);\n * deformmeasure's `poseAt` resets at the setup pose and then applies the\n * animation in its one step (`setup`). On a physics rig the two differ by\n * whole units, not bits: of the 162 one-jump poses (three per animation),\n * 12 read off under `animation` — six on `7-anticipation`'s physics rig (a\n * cape bone 1.7° off at 0.617 s) and six on `gallery/look`'s — and none\n * under `setup`.\n *\n * Every step poses the animation from the setup pose at its animation time\n * (the setup blend at alpha 1), as the oracle's stepped dump does, applied\n * from the animation time of the step before (−1 before the first): a\n * physics `reset` key fires on the step that crosses it, once. Until issue\n * #960 this walk fired such a key at every step from it on (the oracle's\n * reading then), and against the recipe above a probe with a key at 0.5\n * read 32 of 61 frames bit-exact at 60 fps, the rest off by up to 53 units;\n * with the key crossed once, 61 of 61 at 60 fps and 13 of 13 at 12. None of\n * the nineteen tree rows keys a `reset`, which is why the raw gate never\n * saw it. The one difference from `--physics step` is where the steps fall,\n * which is the caller's.\n *\n * ## What a pose carries\n *\n * - `bones` — the world matrix and origin, and the four readings the\n * runtime's getters give: `rotationX = atan2(c, a)·DEG`, `rotationY =\n * atan2(d, b)·DEG`, `scaleX = √(a² + c²)`, `scaleY = √(b² + d²)`, with\n * `DEG = 180 / π` at the runtime's π (`RUNTIME_DEG` in `./world.ts`) —\n * measured bit-exact against `BonePose.getWorldRotationX/Y` and\n * `getWorldScaleX/Y` on every bone of 2,793 poses of the nineteen tree\n * rows (the setup, every 12 fps frame, three jumps per animation).\n * - `slots` — the oracle's slot row as doubles (`posedSlots`).\n * - `drawn` — every region and mesh a slot shows, in draw order: its world\n * vertices (the oracle's `attachments` row as doubles), its LOCAL UVs as the\n * runtime holds them (a region's unit corners `0 1, 0 0, 1 0, 1 1` in the\n * corner order; a mesh's `uvs` — a linked mesh's source's — as the\n * document spells them: `MeshAttachment.regionUVs` read the doubles, not\n * their float32, on every mesh of the nineteen rows — `6-arcs`'\n * `2.554152e-7` where `Math.fround` gives `2.5541518766658555e-7`), its\n * triangles (a region's `0 1 2 2\n * 3 0`), its hull (a mesh's; `null` for a region), its sequence frame (the\n * frame a sequence timeline set, else the series' setup frame, else 0 —\n * the runtime gives every region and mesh a series, one frame long when\n * the record states none, and `Sequence.resolveIndex` read 0 on every such\n * attachment of the nineteen rows) and its own colour (the record's `color`, white\n * unstated) — so the caller forms the tint, slot colour times attachment\n * colour, itself. Where a region sits on a page is not the model's\n * (`ModelAtlasRect`'s 🔸); the page UVs are issue #967's.\n * - `clips`, `clipped` — the oracle's rows as doubles; `clipped` is what the\n * core DRAWS, which is the oracle's block wherever the core poses it and,\n * under a clip that is not strictly convex or is inverse (a block the core\n * leaves out), the core's own convex decomposition (`clipThrough` in\n * `./clipping.ts`, issue #964), held to spine-core by the render's pixels.\n * - `events` — the oracle's event rows as doubles.\n *\n * 🔁 **A second walk shares this one** (issue #1025, cut 4c-5a): A10's\n * LOOPING walk, which keeps a non-finite value rather than refusing it, is\n * `./walk.ts`; both are `walkIn` below in a `WalkMode`, and every difference\n * is a branch on the mode — so this entry's walk is the one it was, and the\n * raw gate's lines did not move.\n *\n * ⛔ **Nothing is posed that the core would leave out.** Where the oracle's\n * core dump names a block absent — a constraint the core cannot pose\n * exactly, skins disagreeing over a placeholder under the merged view, a\n * region with no atlas rectangle — the raw entry refuses the whole call,\n * naming why (`CoreInputError`): a renderer handed a pose with a block\n * missing would draw a different picture in silence.\n */\nimport { activeBones, CoreInputError, drawWalkOf, poseSetup, rawNumber, readColour, shownAttachment, sourceOfDoc, underNoSkin, type CompiledDocument, type CorePlant, type CoreSlotRow } from './index.ts';\nimport { posedBoneWorld, posedBoneWorldAlone, posedSlots, type CoreAnimationTimelines, type LocalAdjust, type TimelinePlant } from './animation.ts';\nimport { constraintsAbsentWhy, pathAnimationsWhy } from './constraints.ts';\nimport { freshStepContext, steppedPreviousPassWhy } from './constraints_physics.ts';\nimport { attachmentStates } from './deform.ts';\nimport { drawOrderAt, type CoreDrawOrderKey } from './draw_order.ts';\nimport { eventsFired, type CoreEventRow } from './events.ts';\nimport { REGION_TRIANGLES, REGION_UVS, type CoreClippedRow, type ShapeClipper } from './clipping.ts';\nimport { poseGeometry, type CoreAttachmentRow, type CoreClipRow, type ShownGeometry } from './vertices.ts';\nimport { RUNTIME_DEG, type CoreWorld } from './world.ts';\nimport type { SliderApplication } from './constraints_slider.ts';\n\n/** One bone, posed: the world transform and the runtime getters' four readings (the header's `bones`). */\nexport interface RawBone {\n name: string;\n parent: string | null;\n active: boolean;\n a: number;\n b: number;\n c: number;\n d: number;\n worldX: number;\n worldY: number;\n rotationX: number;\n rotationY: number;\n scaleX: number;\n scaleY: number;\n}\n\n/** One region or mesh drawn, in draw order (the header's `drawn`). */\nexport interface RawDrawn {\n slot: string;\n attachment: string;\n kind: 'region' | 'mesh';\n vertices: number[];\n uvs: number[];\n triangles: number[];\n hull: number | null;\n sequenceIndex: number;\n colour: [number, number, number, number];\n}\n\n/** One clip polygon: `[slot, attachment, end, polygon]` as doubles. */\nexport type RawClip = [string, string, string | null, number[]];\n/** One attachment drawn under a clip: `[slot, attachment, clipped, vertices, uvs, triangles]` as the clipper returns them. */\nexport type RawClipped = [string, string, 0 | 1, number[], number[], number[]];\n/** One event fired: `[name, time, int, float, string]`. */\nexport type RawEvent = [string, number, number, number, string | null];\n\n/**\n * Where a walk's physics is reset (the header's *One step*): `animation` —\n * the animation applied at 0 and the reset taken there (`src/render.ts`'s\n * frame 0); `setup` — the reset taken at the setup pose before the animation\n * is applied (`src/deformmeasure.ts`'s `poseAt`), pose 0 then the setup pose.\n */\nexport type RawReset = 'animation' | 'setup';\n\n/** One pose — the setup's, or one step of an animation's walk. */\nexport interface RawPose {\n /** The track time (the running sum of the steps), 0 for the setup pose. */\n trackTime: number;\n /** The time the animation was applied at: the track time held at the duration. */\n animationTime: number;\n bones: RawBone[];\n slots: CoreSlotRow[];\n drawOrder: string[];\n drawn: RawDrawn[];\n clips: RawClip[];\n clipped: RawClipped[];\n events: RawEvent[];\n // --- #968 render: begin ---\n /**\n * What each slot shows, in draw order — the records `drawn` was posed from\n * (skin, placeholder, series frame, deform). `src/render_core.ts` resolves\n * each drawn attachment's atlas region and page UVs through it, with\n * `./uvs.ts`'s `drawnRegions` (issue #967's gated rule), rather than walking\n * which record a slot shows a second time.\n */\n shown: ShownGeometry[];\n // --- #968 render: end ---\n}\n\n/**\n * One bone as the scan reads it (issue #1179, the second part): the world\n * matrix and origin `RawBone` carries, and none of the readings it forms from\n * them. `A10_NO_NAN_AFTER_STEPPING` reads these six numbers and the name off a\n * bone, and nothing else (`firstNonFinite` in `src/nonfinite.ts`).\n */\nexport interface ScanBone {\n name: string;\n a: number;\n b: number;\n c: number;\n d: number;\n worldX: number;\n worldY: number;\n}\n\n/**\n * One pose as the scan reads it (issue #1179, the second part) — the scan's\n * walk (`scanWalkIn`, `scanSetupIn`): the time the animation was applied at,\n * and the bones, slot rows and drawn attachments computed exactly as a\n * `RawPose`'s are. Internal to A10's walk (`./walk.ts`); no exported pose type\n * changed for it.\n */\nexport interface ScanPose {\n animationTime: number;\n bones: ScanBone[];\n slots: CoreSlotRow[];\n drawn: ScanDrawn[];\n}\n\n/** One region or mesh drawn, as the scan reads it: its slot, its name and its world vertices, as `RawDrawn` carries them. */\nexport interface ScanDrawn {\n slot: string;\n attachment: string;\n vertices: number[];\n}\n\n// --- #968 render: begin ---\n/** The shown records in `order`, the pose's draw order (a pose's `shown`). */\nfunction drawOrderOf(shown: readonly ShownGeometry[], order: readonly string[]): ShownGeometry[] {\n const rank = new Map(order.map((n, r) => [n, r]));\n return [...shown].sort((a, b) => (rank.get(a.slot) ?? 0) - (rank.get(b.slot) ?? 0));\n}\n// --- #968 render: end ---\n\n/** A double the entry computed: never `null`, since a non-finite pose is refused rather than passed on. */\nfunction finite(v: number | null, what: string): number {\n if (v === null) throw new CoreInputError(`the raw pose computed a non-finite ${what}`);\n return v;\n}\n\n/**\n * How a walk treats the two things the raw entry and the looping walk\n * (`./walk.ts`, issue #1025) read differently: whether the track loops, and\n * whether a value that is not finite is kept in the pose or refuses the call.\n * The raw entry is `{ loop: false, keep: false }`, and that is its contract.\n */\nexport interface WalkMode {\n loop: boolean;\n keep: boolean;\n /** A plant only (the core suite's `CO26`): the animation time a looping step applies at, from its track time, the duration and the track time before it — `loopedTime` unless given. */\n time?: (trackTime: number, duration: number, before: number) => number;\n /** A plant only (`CO26`): what the physics clock moves by, from the step and how far the animation time moved — the step itself unless given. */\n clock?: (dt: number, moved: number) => number;\n /** A plant only (`CO26`): `false` fires no `reset` key across the wrap — the reading the walk was measured against and rejected. */\n wrapResets?: boolean;\n /**\n * The live track's looping mode (`./track.ts`, issue #1276): a looping walk\n * that fires its events across the wrap and cuts its clipped rows, as the\n * raw entry does. Absent on A10's looping walk (`./walk.ts`), which does\n * neither — its one reader reads no event and no clipped row.\n */\n live?: boolean;\n}\n\n/** The raw entry's mode: a track that holds at its duration, and a non-finite value refused. */\nconst RAW_MODE: WalkMode = { loop: false, keep: false };\n\n/** What a kept walk writes a number as: the double itself, finite or not — so a NaN and an Infinity stay what they are. */\nconst keptNumber = (v: number): number => v;\n\n/** The plant a walk in `mode` poses with: the raw entry's unrounded double, or under `keep` the number whatever it is. */\nconst roundPlant = (mode: WalkMode): CorePlant => ({ round: mode.keep ? keptNumber : rawNumber });\n\n/** A double a kept walk computed, as it is; a raw walk's, refused when it is not finite (`finite`). */\nfunction numberOf(v: number | null, what: string, mode: WalkMode): number {\n return mode.keep ? (v === null ? Number.NaN : v) : finite(v, what);\n}\n\n/**\n * What the looping walk cuts a drawn attachment through under a clip: nothing\n * (issue #1179). Its one reader, A10, reads no clipped row — `./walk.ts`\n * narrows them away with the events — so the walk does not cut them; what it\n * still does is plan every clip it starts (`poseClipped`'s `clipShapeOf`), so\n * a clip the core does not draw refuses the walk by name as before. Every\n * number a looping pose carries is computed as it was.\n */\nconst NO_CLIPPED_ROWS: ShapeClipper = () => null;\n\n/** The bones of a pose from the world transforms (the header's `bones`). */\nfunction rawBones(doc: CompiledDocument, world: ReadonlyMap<string, CoreWorld>): RawBone[] {\n const active = activeBones(doc);\n return doc.bones.map((b): RawBone => {\n const w = world.get(b.name);\n if (w === undefined) throw new CoreInputError(`bone \"${b.name}\" has no world transform`);\n return {\n name: b.name,\n parent: b.parent ?? null,\n active: active.has(b.name),\n a: w.a,\n b: w.b,\n c: w.c,\n d: w.d,\n worldX: w.worldX,\n worldY: w.worldY,\n rotationX: Math.atan2(w.c, w.a) * RUNTIME_DEG,\n rotationY: Math.atan2(w.d, w.b) * RUNTIME_DEG,\n scaleX: Math.sqrt(w.a * w.a + w.c * w.c),\n scaleY: Math.sqrt(w.b * w.b + w.d * w.d),\n };\n });\n}\n\n/**\n * The bones of a scan pose (`ScanBone`): `rawBones` less the parent, the\n * active flag and the four getter readings, which nothing the scan reads is\n * computed from — each reading is formed from the world after it is posed,\n * and the matrix and origin are copied as they are.\n */\nfunction scanBones(doc: CompiledDocument, world: ReadonlyMap<string, CoreWorld>): ScanBone[] {\n return doc.bones.map((b): ScanBone => {\n const w = world.get(b.name);\n if (w === undefined) throw new CoreInputError(`bone \"${b.name}\" has no world transform`);\n return { name: b.name, a: w.a, b: w.b, c: w.c, d: w.d, worldX: w.worldX, worldY: w.worldY };\n });\n}\n\n/**\n * What a pose draws, posed and refused where the core leaves it out: the\n * attachment rows, the clip rows and the drawn clipped rows — what `rawDrawn`\n * and `scanDrawn` both assemble from.\n */\nfunction drawnGeometry(doc: CompiledDocument, shown: readonly ShownGeometry[], world: ReadonlyMap<string, CoreWorld>, order: readonly string[], plant: CorePlant, mode: WalkMode): { rows: CoreAttachmentRow[]; clips: CoreClipRow[]; drawnClipped: CoreClippedRow[] } {\n const draw = drawWalkOf(doc, order, plant);\n const geometry = poseGeometry(shown, world, sourceOfDoc(doc), mode.keep ? keptNumber : rawNumber, { region: plant.region, vertices: plant.vertices }, mode.loop && mode.live !== true && plant.through === undefined ? { ...draw, through: NO_CLIPPED_ROWS } : draw);\n if (geometry.attachments === null) throw new CoreInputError(`the raw pose leaves the attachments out: ${geometry.attachmentsWhy}`);\n // The drawn rows (issue #964): the oracle's `clipped` rows where it is posed, and a concave or inverse clip cut through the core's own decomposition.\n if (geometry.drawnClipped === null) throw new CoreInputError(`the raw pose leaves the clipped triangles out: ${geometry.drawnClippedWhy}`);\n return { rows: geometry.attachments, clips: geometry.clips, drawnClipped: geometry.drawnClipped };\n}\n\n/**\n * The drawn attachments of a scan pose (`ScanDrawn`): `rawDrawn`'s rows, each\n * its slot, its name and its world vertices through the same `numberOf`, and\n * none of what `rawDrawn` reads past them for a renderer — the UVs and\n * triangles it copies, the record it looks up for the colour and the sequence\n * frame, the hull, the clip rows' numbers. No vertex is computed from any of\n * those. The one refusal `rawDrawn` makes past the rows, a linked mesh whose\n * source carries no mesh, is not reachable here: `poseGeometry` resolved the\n * same source by the same lookup (`sourceOfDoc`) and throws before it returns.\n *\n * 🔁 **No copy of the vertices** (issue #1179, the second part): `rawDrawn`\n * maps each row through `numberOf` into a new array; under `keep` that map is\n * the identity on every number and turns only a `null` into NaN. The scan\n * hands the row's own array on wherever it holds no `null` (`allNumbers`) and\n * maps it as before where it does, so A10 reads the same values either way.\n * What makes the row's array safe to keep past the step — A10 collects an\n * animation's 120 frames before it scans one — is that it is the pose's own:\n * `poseGeometry` (`./vertices.ts`) builds every row's vertices with\n * `.map(round)` over the corners or the skinned vertices it just computed, a\n * new array per attachment per pose, held by nothing but the row. The core\n * suite's `CO45` plants a poser that hands every pose the same array and reads\n * the retained frames red.\n */\nfunction scanDrawn(doc: CompiledDocument, shown: readonly ShownGeometry[], world: ReadonlyMap<string, CoreWorld>, order: readonly string[], plant: CorePlant, mode: WalkMode, scanPlant: ScanPlant = {}): ScanDrawn[] {\n const { rows } = drawnGeometry(doc, shown, world, order, plant, mode);\n const drawn: ScanDrawn[] = [];\n let k = 0;\n for (const s of shown) {\n const g = s.geometry;\n if (g.kind !== 'region' && g.kind !== 'mesh' && g.kind !== 'linkedmesh') continue;\n const row = rows[k++];\n if (row === undefined || row[0] !== s.slot) throw new CoreInputError(`slot \"${s.slot}\": the attachment rows are not in the shown records' order`);\n const vertices = row[3];\n const kept = mode.keep && allNumbers(vertices) ? vertices : vertices.map((v) => numberOf(v, `vertex of slot \"${s.slot}\"`, mode));\n drawn.push({ slot: s.slot, attachment: row[1], vertices: scanPlant.vertices === undefined ? kept : scanPlant.vertices(kept, s.slot) });\n }\n return drawn;\n}\n\n/** Whether a row's vertices hold no `null` — what `numberOf` would map — so the row's own array can be handed on as numbers. */\nfunction allNumbers(values: Array<number | null>): values is number[] {\n for (const v of values) if (v === null) return false;\n return true;\n}\n\n/**\n * The scan's one plant (the core suite's `CO45`): what a drawn row's vertices\n * are handed on as, given the array the scan would hand on. A poser that\n * reuses one buffer per slot across steps is the plant `CO45` passes.\n * Nothing but a control passes one.\n */\nexport interface ScanPlant {\n vertices?: (vertices: number[], slot: string) => number[];\n}\n\n/** Every region and mesh the shown records draw, with what the renderer reads past the vertices (the header's `drawn`). */\nfunction rawDrawn(doc: CompiledDocument, shown: readonly ShownGeometry[], world: ReadonlyMap<string, CoreWorld>, order: readonly string[], plant: CorePlant, mode: WalkMode = RAW_MODE): { drawn: RawDrawn[]; clips: RawClip[]; clipped: RawClipped[] } {\n const geometry = drawnGeometry(doc, shown, world, order, plant, mode);\n // Under a concave or inverse clip the oracle's `clipped` block is absent (the runtime's own triangle list); what the core draws is `drawnClipped`,\n // its own decomposition, and the render samples each drawn triangle at its source triangle's affine UV, so the pixels are the decomposition's\n // coverage alone (issue #964, `Mesh.source` in src/render.ts).\n const rows = geometry.rows;\n const drawn: RawDrawn[] = [];\n let k = 0;\n for (const s of shown) {\n const g = s.geometry;\n if (g.kind !== 'region' && g.kind !== 'mesh' && g.kind !== 'linkedmesh') continue;\n const row = rows[k++];\n if (row === undefined || row[0] !== s.slot) throw new CoreInputError(`slot \"${s.slot}\": the attachment rows are not in the shown records' order`);\n const record = doc.skins.find((x) => x.name === s.skin)?.attachments[s.slot]?.[s.placeholder];\n const colour = record?.color === undefined ? ([1, 1, 1, 1] as [number, number, number, number]) : readColour(record.color);\n let uvs: number[];\n let triangles: number[];\n let hull: number | null = null;\n if (g.kind === 'region') {\n uvs = [...REGION_UVS];\n triangles = [...REGION_TRIANGLES];\n } else {\n const source = g.kind === 'mesh' ? g : doc.skins.find((x) => x.name === g.skin)?.attachments[g.slot]?.[g.source]?.geometry;\n if (source === undefined || source.kind !== 'mesh') throw new CoreInputError(`slot \"${s.slot}\": the linked mesh's source carries no mesh`);\n uvs = [...source.uvs];\n triangles = [...source.triangles];\n hull = source.hull ?? null;\n }\n const sequenceIndex = s.frame ?? record?.sequenceSetup ?? 0;\n drawn.push({ slot: s.slot, attachment: row[1], kind: row[2], vertices: row[3].map((v) => numberOf(v, `vertex of slot \"${s.slot}\"`, mode)), uvs, triangles, hull, sequenceIndex, colour });\n }\n const clips = geometry.clips.map((c): RawClip => [c[0], c[1], c[2], c[3].map((v) => numberOf(v, `clip vertex of slot \"${c[0]}\"`, mode))]);\n const clipped = geometry.drawnClipped.map((c): RawClipped => [c[0], c[1], c[2], c[3].map((v) => numberOf(v, `clipped vertex of slot \"${c[0]}\"`, mode)), c[4].map((v) => numberOf(v, `clipped uv of slot \"${c[0]}\"`, mode)), c[5]]);\n return { drawn, clips, clipped };\n}\n\n/**\n * The setup pose as the renderer poses a skeleton with no animation — the\n * setup pose, every physics state reset — in full doubles. Refused by name\n * where the core leaves a block of it out.\n */\nexport function poseRawSetup(doc: CompiledDocument, plant: CorePlant = {}): RawPose {\n return setupPoseIn(doc, plant, RAW_MODE);\n}\n\n/** `poseRawSetup` in `mode` — under `keep`, a value that is not finite stays in the pose (`./walk.ts`). */\nexport function setupPoseIn(doc: CompiledDocument, plant: CorePlant, mode: WalkMode): RawPose {\n const { world, shown, slots, drawOrder } = setupPosed(doc, plant, mode);\n const drawn = rawDrawn(doc, shown, world, drawOrder, plant, mode);\n return { trackTime: 0, animationTime: 0, bones: rawBones(doc, world), slots, drawOrder, ...drawn, events: [], shown: drawOrderOf(shown, drawOrder) };\n}\n\n/** `setupPoseIn` as the scan reads it (`ScanPose`): the same setup pose, the same refusals in the same order, assembled into the scan's pose. */\nexport function scanSetupIn(doc: CompiledDocument, plant: CorePlant, mode: WalkMode, scanPlant: ScanPlant = {}): ScanPose {\n const { world, shown, slots, drawOrder } = setupPosed(doc, plant, mode);\n const drawn = scanDrawn(doc, shown, world, drawOrder, plant, mode, scanPlant);\n return { animationTime: 0, bones: scanBones(doc, world), slots, drawn };\n}\n\n/** The setup pose `setupPoseIn` and `scanSetupIn` assemble, refused by name where the core leaves a block of it out. */\nfunction setupPosed(doc: CompiledDocument, plant: CorePlant, mode: WalkMode): { world: Map<string, CoreWorld>; shown: ShownGeometry[]; slots: CoreSlotRow[]; drawOrder: string[] } {\n const posed = poseSetup(doc, { ...plant, ...roundPlant(mode) }, freshStepContext(plant.physicsStep));\n // `setup.clipped` is the oracle's block, left out under a concave or inverse clip whose triangle list is the runtime's own; what the core draws there is `rawDrawn`'s to refuse or pose (issue #964).\n const absent = posed.absent.filter(([block]) => block !== 'setup.clipped');\n if (absent.length > 0) throw new CoreInputError(`the raw setup pose leaves ${absent.map(([b, why]) => `${b} out (${why})`).join('; ')}`);\n const { setup, world, shown } = posed;\n if (world === null || shown === null || setup.slots === null || setup.drawOrder === null) throw new CoreInputError('the raw setup pose was not posed');\n return { world, shown, slots: setup.slots, drawOrder: setup.drawOrder };\n}\n\n/**\n * One animation walked at the caller's steps (the header's *One step*): the\n * reset pose at 0, then one pose per step of `steps` — `steps.length + 1`\n * poses in all. `src/render.ts`'s walk is `count` steps of `1/fps`;\n * `src/deformmeasure.ts`'s is one step of `time`. A step must be a finite\n * time at or above 0; the animation must be the document's; a construct the\n * core would leave out refuses the call by name. `reset` is where the\n * physics is reset (`RawReset`): `animation` for render's walk, `setup` for\n * deformmeasure's one jump.\n */\nexport function poseRawAnimation(doc: CompiledDocument, animation: string, steps: readonly number[], plant: TimelinePlant = {}, reset: RawReset = 'animation'): RawPose[] {\n return walkIn(doc, animation, steps, plant, reset, RAW_MODE);\n}\n\n/**\n * `poseRawAnimation`, each pose handed to `visit` as it is posed rather than\n * collected (issue #1180): the same walk, the same poses in the same order,\n * and the caller holds as many of them as it keeps. `src/render_core.ts`\n * draws each and lets it go, so a render holds one pose and not an\n * animation's series — on the production rig the core poser's render peaked\n * highest on, the largest animation's series was 153 MiB of retained heap.\n * A refusal is thrown from the pose it is met at, after `visit` has seen the\n * poses before it.\n */\nexport function poseRawAnimationEach(doc: CompiledDocument, animation: string, steps: readonly number[], plant: TimelinePlant, reset: RawReset, visit: (pose: RawPose, index: number) => void): void {\n walkEach(doc, animation, steps, plant, reset, RAW_MODE, RAW_SHAPE, visit);\n}\n\n/**\n * The animation time a looping track applies its animation at (`./walk.ts`,\n * *The time*): the track time wrapped by the duration, and 0 over a duration\n * of 0.\n */\nexport function loopedTime(trackTime: number, duration: number): number {\n return duration === 0 ? 0 : trackTime % duration;\n}\n\n/**\n * `poseRawAnimation` in `mode`: the raw entry's walk, or the looping walk\n * `./walk.ts` documents — the animation time the track time wrapped by the\n * duration, every value kept whatever it is. Each difference is a branch on\n * `mode` here, so the raw entry's walk is the one it was.\n */\nexport function walkIn(doc: CompiledDocument, animation: string, steps: readonly number[], plant: TimelinePlant, reset: RawReset, mode: WalkMode): RawPose[] {\n const poses: RawPose[] = [];\n walkEach(doc, animation, steps, plant, reset, mode, RAW_SHAPE, (pose) => poses.push(pose));\n return poses;\n}\n\n/**\n * `walkIn` as the scan reads it (`ScanPose`, issue #1179, the second part):\n * the same walk — every pose posed by the same operations in the same order,\n * every refusal at the same place — each pose assembled into what A10 reads.\n * `./walk.ts`'s `scanLoopingWalk` is its one caller.\n */\nexport function scanWalkIn(doc: CompiledDocument, animation: string, steps: readonly number[], plant: TimelinePlant, reset: RawReset, mode: WalkMode, scanPlant: ScanPlant = {}): ScanPose[] {\n const poses: ScanPose[] = [];\n walkEach(doc, animation, steps, plant, reset, mode, scanPlant.vertices === undefined ? SCAN_SHAPE : scanShape(scanPlant), (pose) => poses.push(pose));\n return poses;\n}\n\n/** What one step of a walk posed, before a pose is assembled from it (`PoseShape`). */\ninterface WalkStep {\n trackTime: number;\n animationTime: number;\n world: Map<string, CoreWorld>;\n slots: CoreSlotRow[];\n drawOrder: string[];\n shown: ShownGeometry[];\n /** The events the step fired, computed when called — after the drawn rows, as the raw entry has always ordered its refusals. */\n events: () => RawEvent[];\n}\n\n/**\n * What a walk assembles each pose into (issue #1179, the second part): the raw\n * entry's whole pose (`RAW_SHAPE`), or the scan's (`SCAN_SHAPE`). The walk\n * (`walkEach`) is one body: every number a pose carries is computed there and\n * in the two assemblers below, by the same calls, whatever the shape. A shape\n * chooses only what is assembled from what was posed — the scan drops the\n * readings, rows and copies nothing it reads is computed from — and keeps the\n * order of every call that can refuse.\n */\ninterface PoseShape<P> {\n /** Whether a step forms the oracle's bone rows beside its world (`posedBoneWorld`), which no walk pose carries; `false` poses the world alone (`posedBoneWorldAlone`). */\n rows: boolean;\n /** The reset pose at the setup (`reset: 'setup'`). */\n setup: (doc: CompiledDocument, world: Map<string, CoreWorld>, slots: CoreSlotRow[], drawOrder: string[], shown: ShownGeometry[], plant: CorePlant, mode: WalkMode) => P;\n /** One step's pose. */\n step: (doc: CompiledDocument, posed: WalkStep, plant: CorePlant, mode: WalkMode) => P;\n}\n\n/** The raw entry's pose, assembled as it always was: at the reset the bones, then the drawn rows; at a step the drawn rows, the events, then the bones. */\nconst RAW_SHAPE: PoseShape<RawPose> = {\n rows: true,\n setup: (doc, world, slots, drawOrder, shown, plant, mode) => ({ trackTime: 0, animationTime: 0, bones: rawBones(doc, world), slots, drawOrder, ...rawDrawn(doc, shown, world, drawOrder, plant, mode), events: [], shown: drawOrderOf(shown, drawOrder) }),\n step: (doc, p, plant, mode) => {\n const drawn = rawDrawn(doc, p.shown, p.world, p.drawOrder, plant, mode);\n const events = p.events();\n return { trackTime: p.trackTime, animationTime: p.animationTime, bones: rawBones(doc, p.world), slots: p.slots, drawOrder: p.drawOrder, ...drawn, events, shown: p.shown };\n },\n};\n\n/** The scan's pose (`ScanPose`), in the raw shape's order: the scan's walk is a looping one, which fires no event. */\nfunction scanShape(scanPlant: ScanPlant): PoseShape<ScanPose> {\n return {\n rows: false,\n setup: (doc, world, slots, drawOrder, shown, plant, mode) => {\n const bones = scanBones(doc, world);\n return { animationTime: 0, bones, slots, drawn: scanDrawn(doc, shown, world, drawOrder, plant, mode, scanPlant) };\n },\n step: (doc, p, plant, mode) => {\n const drawn = scanDrawn(doc, p.shown, p.world, p.drawOrder, plant, mode, scanPlant);\n return { animationTime: p.animationTime, bones: scanBones(doc, p.world), slots: p.slots, drawn };\n },\n };\n}\nconst SCAN_SHAPE: PoseShape<ScanPose> = scanShape({});\n\n/**\n * A walk between two of its steps (issue #1276): everything `walkEach` carries\n * from one step to the next, held in one object, so the walk can be stepped one\n * `dt` at a time (`openTrack` in `./track.ts`) as well as over a list. That is\n * the physics context (`ctx`: the skeleton's clock, the phase, each physics\n * constraint's state, the animation time a `reset` key is crossed from, whether\n * the track loops), the running track time, the animation time of the step\n * before (−1 before the first) and what the walk was opened with. Nothing else\n * survives a step: every pose is posed from the setup pose at its time.\n */\nexport interface TrackState<P> {\n readonly doc: CompiledDocument;\n readonly anim: CompiledDocument['animations'][number];\n /** The runtime's duration (`CoreAnimationTimelines.duration`). */\n readonly duration: number;\n readonly mode: WalkMode;\n readonly plant: TimelinePlant;\n /** `plant` with the mode's rounding (`roundPlant`). */\n readonly raw: TimelinePlant;\n readonly resolve: NonNullable<TimelinePlant['shown']>;\n readonly shape: PoseShape<P>;\n readonly ctx: ReturnType<typeof freshStepContext>;\n /** The caller's adjustment of each step's locals (`LocalAdjust` in `./animation.ts`): the live track's `adjust`, absent on every batch walk. */\n readonly adjust?: LocalAdjust;\n /** The running sum of the steps taken. */\n trackTime: number;\n /** The animation time of the step before, −1 before the first. */\n last: number;\n}\n\n/** The document's animation named `animation`, or the walk refused naming the document's animations. */\nfunction animationOf(doc: CompiledDocument, animation: string): CompiledDocument['animations'][number] {\n const anim = doc.animations.find((a) => a.name === animation);\n if (anim === undefined) throw new CoreInputError(`animation \"${animation}\" is not one of this document's [${doc.animations.map((a) => a.name).join(', ')}]`);\n return anim;\n}\n\n/**\n * A walk opened (issue #1276): the refusals a walk makes before its first pose,\n * then pose 0 — the reset — and the state the walk steps on from. Under\n * `reset: 'setup'` pose 0 is the setup pose, reset; under `animation` it is the\n * animation applied at 0 and reset there, a step of 0 (`stepWalk`'s `first`).\n */\nfunction openWalk<P>(doc: CompiledDocument, anim: CompiledDocument['animations'][number], plant: TimelinePlant, reset: RawReset, mode: WalkMode, shape: PoseShape<P>, adjust?: LocalAdjust): { track: TrackState<P>; first: P } {\n const why = constraintsAbsentWhy(doc) ?? pathAnimationsWhy(doc) ?? steppedPreviousPassWhy(doc);\n if (why !== null) throw new CoreInputError(`the raw walk leaves the bones out: ${why}`);\n const ctx = freshStepContext(plant.physicsStep);\n if (mode.loop && mode.wrapResets !== false) ctx.loop = true;\n const track: TrackState<P> = { doc, anim, duration: anim.timelines.duration, mode, plant, raw: { ...plant, ...roundPlant(mode) }, resolve: plant.shown ?? shownAttachment, shape, ctx, adjust, trackTime: 0, last: -1 };\n if (reset === 'setup') {\n // The reset taken at the setup pose, before the animation is applied (`src/deformmeasure.ts`'s `poseAt`): pose 0 is the setup pose.\n const setup = poseSetup(doc, { ...plant, ...roundPlant(mode) }, ctx);\n const absent = setup.absent.filter(([block]) => block !== 'setup.clipped');\n if (absent.length > 0) throw new CoreInputError(`the raw walk's reset pose leaves ${absent.map(([b, w]) => `${b} out (${w})`).join('; ')}`);\n if (setup.world === null || setup.shown === null || setup.setup.slots === null || setup.setup.drawOrder === null) throw new CoreInputError('the raw walk\\'s reset pose was not posed');\n ctx.phase = 'update';\n return { track, first: shape.setup(doc, setup.world, setup.setup.slots, setup.setup.drawOrder, setup.shown, plant, mode) };\n }\n return { track, first: stepWalk(track, 0, true) };\n}\n\n/**\n * One step of a walk (the header's *One step*): the track time moved by `dt`,\n * the animation applied at the mode's time from the setup pose, the physics\n * clock moved by the step, and the pose assembled in the track's shape.\n * `first` is the reset pose under `reset: 'animation'` — a step of 0 that\n * resets the physics there — and nothing else passes it.\n */\nfunction stepWalk<P>(track: TrackState<P>, dt: number, first = false): P {\n const { doc, anim, duration, mode, plant, raw, resolve, shape, ctx, adjust } = track;\n track.trackTime += dt;\n const trackTime = track.trackTime;\n const last = track.last;\n const t = mode.loop ? (mode.time ?? loopedTime)(trackTime, duration, trackTime - dt) : trackTime < duration ? trackTime : duration;\n const before = ctx.time;\n ctx.time += mode.clock === undefined ? dt : mode.clock(dt, t - (first ? 0 : Math.max(last, 0)));\n // A10's looping walk fires no event here — its one reader reads none — nor cuts its drawn attachments through a clip (`NO_CLIPPED_ROWS`), so its\n // `clipped` rows are empty. The live track's looping mode (`live`) fires its events across the wrap by the rule `./track.ts` states as measured.\n const fire = plant.events ?? eventsFired;\n const keys = anim.timelines.events;\n const pose = poseStepFrom(doc, plant, resolve, shape, mode, ctx, first, trackTime, t, {\n world: (sliders) => (shape.rows ? posedBoneWorld(doc, anim.timelines, t, raw, anim.constraints, sliders, { ctx, before, adjust }).world : posedBoneWorldAlone(doc, anim.timelines, t, raw, anim.constraints, sliders, { ctx, before, adjust })),\n slots: (sliders, placeholders) => posedSlots(doc, anim.timelines, t, raw, sliders, placeholders),\n drawOrder: anim.timelines.drawOrder,\n at: t,\n sample: { timelines: anim.timelines, t },\n events: () => (mode.loop && mode.live !== true ? [] : mode.loop ? fire(keys, last, t, rawNumber, t < last) : fire(keys, last, t, rawNumber)),\n });\n track.last = t;\n return pose;\n}\n\n/**\n * What decides one step's pose before it is assembled (issue #1336): the bone\n * world through the stepped phase, filling the sliders it applied; the slot\n * rows, filling the placeholders the timelines left; the draw-order keys and\n * the time they are read at; the deform and sequence timelines' sample, or the\n * mixed deforms in its place; the events, computed when called. A walk's step\n * reads every one off one animation at its time (`stepWalk`); the live tracks\n * off their mixed entries (`./tracks.ts`). Everything past these is one body,\n * `poseStepFrom`.\n */\nexport interface StepPosers {\n world: (sliders: SliderApplication[]) => Map<string, CoreWorld>;\n slots: (sliders: readonly SliderApplication[], placeholders: Map<string, string | null>) => { rows: CoreSlotRow[]; conflicts: string[] };\n drawOrder: readonly CoreDrawOrderKey[];\n at: number;\n sample: { timelines: CoreAnimationTimelines; t: number } | null;\n mixed?: ReadonlyMap<string, { deform: number[] | null; seen: readonly string[] }>;\n events: () => CoreEventRow[];\n}\n\n/**\n * One step's pose from what decided it (`StepPosers`): the bone world, the\n * physics phase moved past the reset on `first`, the slot rows, the draw\n * order (the keys' order, else the setup's, then each slider's key), the\n * attachments drawn in it, and the pose assembled in `shape` — refused by name\n * where the core leaves a block out, in that order. The one body a walk's step\n * and a live tracks' step share.\n */\nfunction poseStepFrom<P>(doc: CompiledDocument, plant: TimelinePlant, resolve: NonNullable<TimelinePlant['shown']>, shape: PoseShape<P>, mode: WalkMode, ctx: ReturnType<typeof freshStepContext>, first: boolean, trackTime: number, animationTime: number, posers: StepPosers): P {\n const sliders: SliderApplication[] = [];\n const world = posers.world(sliders);\n if (first) ctx.phase = 'update';\n const placeholders = new Map<string, string | null>();\n const slots = posers.slots(sliders, placeholders);\n if (slots.conflicts.length > 0) throw new CoreInputError(`the raw walk leaves the slots out: ${slots.conflicts.join('; ')}`);\n const evalOrder = plant.drawOrder ?? drawOrderAt;\n let order = evalOrder(doc.slots.length, posers.drawOrder, posers.at) ?? doc.slots.map((_s, k) => k);\n for (const app of sliders) order = evalOrder(doc.slots.length, app.timelines.drawOrder, app.at) ?? order;\n const drawOrder = order.map((k) => doc.slots[k].name);\n const states = attachmentStates(doc, resolve, placeholders, posers.sample, sliders, plant, posers.mixed);\n if (states.why.length > 0) throw new CoreInputError(`the raw walk leaves the attachments out: ${states.why.join('; ')}`);\n const rank = new Map(drawOrder.map((n, r) => [n, r]));\n const shown = [...states.shown].sort((a, b) => (rank.get(a.slot) ?? 0) - (rank.get(b.slot) ?? 0));\n const events = (): RawEvent[] => posers.events().map((e): RawEvent => [e[0], finite(e[1], 'event time'), e[2], finite(e[3], 'event float'), e[4]]);\n return shape.step(doc, { trackTime, animationTime, world, slots: slots.rows, drawOrder, shown, events }, plant, mode);\n}\n\n/**\n * The live tracks' side of the raw pose path (issue #1336, `./tracks.ts`):\n * the refusals a walk makes before its first pose, a fresh physics context,\n * the plant with the raw entry's rounding, and the two ways a pose is made —\n * the setup pose reset (`reset: 'setup'`'s pose 0) and one step from what the\n * mixed entries decided, assembled as the raw entry's pose (`RAW_SHAPE`,\n * `RAW_MODE`: a non-finite value refused, every clipped row cut).\n */\nexport interface RawTracksPath {\n readonly ctx: ReturnType<typeof freshStepContext>;\n /** `plant` with the raw entry's rounding. */\n readonly raw: TimelinePlant;\n setupPose(): RawPose;\n step(first: boolean, trackTime: number, animationTime: number, posers: StepPosers): RawPose;\n}\n\n/** `RawTracksPath` opened on `doc`, refused by name where a walk on it would be (`openWalk`). */\nexport function openRawTracksPath(doc: CompiledDocument, plant: TimelinePlant): RawTracksPath {\n const why = constraintsAbsentWhy(doc) ?? pathAnimationsWhy(doc) ?? steppedPreviousPassWhy(doc);\n if (why !== null) throw new CoreInputError(`the raw walk leaves the bones out: ${why}`);\n const ctx = freshStepContext(plant.physicsStep);\n const raw: TimelinePlant = { ...plant, ...roundPlant(RAW_MODE) };\n const resolve = plant.shown ?? shownAttachment;\n return {\n ctx,\n raw,\n setupPose: () => {\n const setup = poseSetup(doc, raw, ctx);\n const absent = setup.absent.filter(([block]) => block !== 'setup.clipped');\n if (absent.length > 0) throw new CoreInputError(`the raw walk's reset pose leaves ${absent.map(([b, w]) => `${b} out (${w})`).join('; ')}`);\n if (setup.world === null || setup.shown === null || setup.setup.slots === null || setup.setup.drawOrder === null) throw new CoreInputError('the raw walk\\'s reset pose was not posed');\n ctx.phase = 'update';\n return RAW_SHAPE.setup(doc, setup.world, setup.setup.slots, setup.setup.drawOrder, setup.shown, plant, RAW_MODE);\n },\n step: (first, trackTime, animationTime, posers) => poseStepFrom(doc, plant, resolve, RAW_SHAPE, RAW_MODE, ctx, first, trackTime, animationTime, posers),\n };\n}\n\n/** `walkIn`'s walk, each pose assembled in `shape` and handed to `visit` in order as it is posed (`poseRawAnimationEach`): the walk opened, then stepped over `steps`. */\nfunction walkEach<P>(doc: CompiledDocument, animation: string, steps: readonly number[], plant: TimelinePlant, reset: RawReset, mode: WalkMode, shape: PoseShape<P>, visit: (pose: P, index: number) => void): void {\n const anim = animationOf(doc, animation);\n const bad = steps.findIndex((s) => !Number.isFinite(s) || s < 0);\n if (bad >= 0) throw new CoreInputError(`step ${bad} is ${steps[bad]}, not a finite time at or above 0`);\n const { track, first } = openWalk(doc, anim, plant, reset, mode, shape);\n let visited = 0;\n visit(first, visited++);\n for (const dt of steps) visit(stepWalk(track, dt), visited++);\n}\n\n/**\n * The raw entry's walk opened for stepping one `dt` at a time (issue #1276,\n * `openTrack` in `./track.ts`): the same refusals in the same order as\n * `walkIn`'s past the step list, pose 0 as `walkIn` poses it, and the state\n * `stepRawTrack` steps. Every pose is assembled as the raw entry's\n * (`RAW_SHAPE`).\n */\nexport function openRawTrack(doc: CompiledDocument, animation: string, plant: TimelinePlant, reset: RawReset, mode: WalkMode, adjust?: LocalAdjust): { track: TrackState<RawPose>; first: RawPose } {\n return openWalk(doc, animationOf(doc, animation), plant, reset, mode, RAW_SHAPE, adjust);\n}\n\n/** One step of an opened raw track (`openRawTrack`): `walkIn`'s step, the step itself checked by the caller. */\nexport function stepRawTrack(track: TrackState<RawPose>, dt: number): RawPose {\n return stepWalk(track, dt);\n}\n\n// --- #907 the setup-pose bounding box: begin ---\n/**\n * The setup-pose bounding box (issue #907) — `setupBounds` below: the axis-aligned box around every\n * region and mesh a skeleton draws at its setup pose, as spine-core's\n * `Skeleton.getBounds(offset, size, temp)` returns it on a fresh skeleton —\n * no skin set, `updateWorldTransform(Physics.none)` — which is what the Spine\n * format says the header's `x`, `y`, `width` and `height` are.\n *\n * Every rule below was measured by running spine-core 4.3.13 through the\n * tree's own loader, not read off its source:\n *\n * - **The view is \"no skin set\"** (`underNoSkin`, issue #1051): a skeleton\n * `build` writes is loaded and bounded before anyone calls `setSkin`, so\n * the slots resolve through the default skin alone and no skin's bones or\n * constraint lists apply.\n * - **Constraints applied.** The box is of the pose `updateWorldTransform`\n * leaves, every ik, transform, path and slider constraint applied in the\n * document's order — the pose `poseSetup` computes. The editor's own\n * header is of that pose too: on `examples/spineboy/export/spineboy-pro.json`\n * (seven ik and seven transform constraints) `getBounds` with the\n * constraints applied is within 0.0035 of the header the editor wrote, and\n * with them stripped it is 0.31 off in `y` and `height`.\n * - **Physics.none.** A physics constraint applies nothing at the setup pose\n * (the oracle's setup reading). Under `Physics.reset` spine-core's box was\n * the same, to the bit, on all nineteen tree rows (two declare a physics constraint).\n * - **What is counted.** A region's four corners and a mesh's (a linked\n * mesh's) world vertices — the rows of the oracle's `setup.attachments`\n * block, in full doubles. A clipping polygon, a bounding box, a path and a\n * point are not counted (measured: each placed 5000 units out moved\n * `getBounds` by nothing), and the box is not clipped: `getBounds` called\n * without its optional clipper.\n * - **A slot on an inactive bone is not counted** — measured: a skin-required\n * bone 1000 units out, which only a named skin activates, carrying a region\n * left `getBounds` at the other region's 20 units with no skin set, and 1020\n * with the bone not skin-required. A bone that is not skin-required under an\n * inactive parent is active and unposed, and its slot is counted at the\n * vertices that pose gives; the core poses the same vertices (the oracle's\n * `setup.attachments`, held at tolerance 0), and a probe of that shape read\n * the same box both ways.\n * - **The box.** `x`, `y` are the least `x` and `y` over every counted\n * vertex and `width`, `height` the greatest less the least — the\n * bottom-left corner in Spine's y-up world, not the top-left. In full\n * doubles; `build` writes each on the model's 1e-6 grid at float32\n * (`headerBoxNumber` in `src/compile.ts`, whose comment says why).\n * - **Nothing drawn is no box.** `getBounds` over no vertex returns an offset\n * of `+Infinity` and a size of `-Infinity`, which is not a box; this\n * returns `null` for it, and the emitter writes no box rather than a number\n * nobody measured.\n *\n * Pure, like the rest of `src/core/`: it links nothing from the runtime, and\n * `tools/core_gate.ts` holds it to `getBounds` at tolerance 0 over the corpus\n * (its `BOUNDS` rows).\n */\n\n/** The setup-pose box: its bottom-left corner and its extent, in Spine world units, in full doubles. */\nexport interface CoreBounds {\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\n/**\n * The setup-pose bounding box of a model document (the header's rules), or\n * `null` where nothing is drawn. Refused by name — `CoreInputError` — where\n * the core leaves the setup attachments out, since a box over the rest would\n * be a box of a different pose.\n */\nexport function setupBounds(doc: CompiledDocument, plant: CorePlant = {}): CoreBounds | null {\n const view = underNoSkin(doc);\n const posed = poseSetup(view, { ...plant, round: rawNumber });\n const rows = posed.setup.attachments;\n if (rows === null) {\n const why = posed.absent.find(([block]) => block === 'setup.attachments')?.[1] ?? 'the setup attachments were not posed';\n throw new CoreInputError(`the setup-pose bounding box cannot be computed: ${why}`);\n }\n const active = activeBones(view);\n const boneOf = new Map(view.slots.map((s) => [s.name, s.bone]));\n let minX = Infinity;\n let minY = Infinity;\n let maxX = -Infinity;\n let maxY = -Infinity;\n for (const [slot, attachment, , vertices] of rows) {\n const bone = boneOf.get(slot);\n if (bone === undefined || !active.has(bone)) continue;\n for (let i = 0; i + 1 < vertices.length; i += 2) {\n const x = vertices[i];\n const y = vertices[i + 1];\n if (x === null || y === null) throw new CoreInputError(`the setup-pose bounding box cannot be computed: slot \"${slot}\" attachment \"${attachment}\" vertex ${i / 2} is not finite`);\n minX = Math.min(minX, x);\n minY = Math.min(minY, y);\n maxX = Math.max(maxX, x);\n maxY = Math.max(maxY, y);\n }\n }\n if (minX === Infinity) return null;\n return { x: minX, y: minY, width: maxX - minX, height: maxY - minY };\n}\n// --- #907 the setup-pose bounding box: end ---\n","/**\n * The core's live track (issue #1276): one animation opened on a track and\n * stepped one `dt` at a time — a player's frame loop, whose steps are not known\n * in advance — every pose the raw entry's (`RawPose` in `./raw.ts`), the doubles\n * the core computed.\n *\n * It is not new math. Both batch walks — the raw entry's `poseRawAnimation`\n * and A10's looping walk (`./walk.ts`) — take their steps up front and pose\n * every step from the setup pose, carrying from one step to the next only the\n * physics context, the running track time and the animation time of the step\n * before. That carry is one object (`TrackState` in `./raw.ts`), and the batch\n * walk is \"open, then step over the list\"; this track opens the same walk and\n * takes its steps as they come. Measured before and after that split, over the\n * nineteen tree rows' 54 animations: 956 batch walks — the raw entry at 12, 24\n * and 60 fps from each reset, held three times past the duration, its two\n * one-step jumps under each reset, `poseRawAnimationEach`, A10's walk and its\n * scan on A10's schedule and at 60 fps over three cycles — 157,771 poses, every\n * one the same bits (the PR of issue #1276 carries the table).\n *\n * Several animations on several tracks, set, queued and mixed as spine-core's\n * `AnimationState` mixes them, are `openTracks` (`./tracks.ts`, issue #1336):\n * a second state machine over the same pose path past the timelines, which\n * this track reaches with the locals its one animation posed.\n *\n * ## The walk\n *\n * - **Held** (`loop: false`): the raw entry's walk — the track time the\n * running sum of the steps, the animation time held at the duration, the\n * physics clock moved by the step, events over `(previous animation time,\n * animation time]` (`./raw.ts`, *One step*). `CO46` holds it to\n * `poseRawAnimation` pose for pose, every field, bit for bit.\n * - **Looped** (`loop: true`): A10's looping walk's time, clock and `reset`\n * keys across the wrap (`./walk.ts`, *The walk*) — and, which that walk does\n * not carry because its one reader reads neither, the events it fires across\n * the wrap and the clipped rows it cuts. `CO46` holds it to\n * `poseLoopingWalk` narrowed to what that walk carries, bit for bit.\n * - **The reset is the caller's**, as on the raw entry (`RawReset`): pose 0\n * (`first`) is posed when the track is opened, the batch walk's pose 0\n * under the same reset, and every `step` is one pose after it.\n * - **Neither keeps a value that is not finite** (`keep: false`, the raw\n * entry's argument: a renderer handed one draws a different picture in\n * silence). What the raw entry refuses is a drawn vertex, a clip or clipped\n * vertex, a clipped UV and an event's numbers; a bone's matrix and a slot's\n * colour channel it passes on (NaN, `null`), and so does this track. Of\n * 108 forged animations of the tree rows (a leaf and its parent scaled past\n * the largest double), 98 were refused at the first non-finite vertex and 4\n * walked holding a non-finite bone no drawn vertex reads; `CO49` holds both\n * halves, the second on a slotless bone chain.\n *\n * ## Across the wrap — what a looping track fires, measured\n *\n * Read off spine-core 4.3.13 — `AnimationState` with `setAnimation(0, name,\n * true)`, pose 0 applied at 0 and reset there or reset at the setup pose\n * with nothing applied, then per step `update(dt)`, `apply`,\n * `Skeleton.update(dt)`, `updateWorldTransform(Physics.update)` — by a\n * listener collecting `event` and `complete` in the order queued, on the\n * tree rows' six animations keying events and on 300 seeded probes whose keys\n * sit at 0, 1e-3 after it, in the middle, one float32 ulp and 1e-3 before the\n * duration, on it, and one ulp and 1e-3 past the bone's last key (where the\n * key sets the duration); over step lists that cross the wrap once and\n * several times, land exactly on the duration, and carry the track past it by\n * more than a cycle: 4,284 walks, 229,656 steps, 13,436 across the wrap, 8,846\n * longer than a cycle, 52,880 events and 24,587 completes, each in the\n * listener's order on every step. `CO47` holds the rule on its own population.\n *\n * - **A step whose animation time rose fires `(previous time, time]`**, as the\n * raw entry's — so a step that carries the track past the duration once or\n * more while its animation time still rises fires only that interval: the\n * keys it passed on the way are not fired.\n * - **A step whose animation time went down — the wrap — fires the keys after\n * the previous time, in key order, then the keys at or before the new time,\n * in key order** (`eventsFired`'s `wrapped`): the second interval opens at\n * −1, so a key at 0 fires on every wrap. Read in key order instead, 7,680 of\n * the steps read off; with the second interval opening at 0, 6,066; with\n * nothing fired across the wrap, 12,956.\n * - **A key at exactly the duration fires on the wrap step and on no other**,\n * before the keys from 0: 11,978 such firings, every one on a wrap step. A\n * key one float32 ulp before the duration is an ordinary key — it fired on a\n * rising step 545 times, where the animation time reached it before the wrap.\n * - **An equal time is not a wrap** (`loopedTime`: a track time of exactly the\n * duration applies at 0). A track stepped by exactly the duration applies at\n * 0 on every step, so it fires its keys at 0 on its first step and nothing\n * after; stepped by half the duration it wraps on every second step.\n * - **`complete` is not carried** — a listener is the player's. Measured, it is\n * queued once on a step whose track time's whole cycles rose past 0 —\n * `⌊T / d⌋ > 0` and `⌊T / d⌋ > ⌊T_before / d⌋`, on every step at a duration\n * of 0 — however many cycles the step crossed, after the keys after the\n * previous time and before the keys from 0. A player derives it from\n * `trackTime` and `duration`.\n *\n * ## The clipped rows\n *\n * The looping mode cuts every drawn attachment under a clip as the raw entry\n * does — the oracle's rows, and the core's own decomposition under a concave\n * or inverse clip (`clipThrough`) — where A10's walk cuts none. That is a\n * mode and not a measurement: the cut is per pose and does not read whether\n * the track loops. `CO48` holds it: on the clipping probe and the tree row\n * that clips, every looping pose, past the wrap included, equals the raw\n * entry's one step to its animation time in every field but the track time\n * and the events (4,009 of 4,009 on the tree row, 690 of them cutting 12,420\n * rows).\n *\n * ## The adjustment (issue #1336)\n *\n * `adjust` is a player's own bone-local value — a breath's scale, a look's\n * rotation — written onto the bones every pose, after the animation's\n * timelines posed the locals at the step's time and before the world\n * transforms, the constraints and the physics step (`LocalAdjust` in\n * `./animation.ts`, which states the view's rules). It runs on every pose the\n * animation is applied to — every `step`, and pose 0 under `reset:\n * 'animation'` — and not on pose 0 under `reset: 'setup'`, the setup pose\n * with nothing applied: a player applies its adjustment wherever it applies\n * the animation state, the first frame included, and spine-core's reset at\n * the setup pose applies none. Absent, every pose is the one the track posed\n * before it existed, bit for bit (`CO46`, unchanged; `CO50` holds a hook that\n * writes nothing to the same bits).\n *\n * `CO50` holds it to spine-core 4.3.13 on gallery/look, whose `head` carries\n * the deformed head mesh and every face bone, and the physics-driven\n * `ahoge_whip` two bones below it: the same `scaleY` written on `head` by the\n * core's hook and on `Bone.pose` between `AnimationState.apply` and\n * `updateWorldTransform(Physics.update)`, every bone's world transform and\n * every drawn vertex equal at tolerance 0 over looping and held walks under\n * both resets — spine-core's skeleton brought back to the setup pose\n * (`setupPoseBones`) before each `apply`, which is the core's own reading:\n * every pose is posed from the setup pose. Measured, and held red there:\n *\n * - **The write carried from frame to frame** — spine-core without that\n * reset, where no timeline writes an unkeyed channel back, so a `scaleY`\n * multiplied every frame compounds (every walk off from pose 2). The core\n * carries no local from one step to the next; a value a player wants\n * carried it keeps and writes again.\n * - **The write at draw time** — made after `updateWorldTransform`, the\n * bone's own matrix alone brought up to date: the bone moves, its\n * children, the meshes they carry and the physics do not.\n * - **Pose 0 not adjusted** under `reset: 'animation'`.\n *\n * ## The oracle chain\n *\n * Nothing here is held to spine-core directly but the events: the live track\n * is held to the batch walk (`CO46`), the held batch walk to spine-core's\n * render and deform-measure recipes (`CR03`), the looped one to A10's recipe\n * (`CO25`), and both to `tools/pose_oracle.ts`'s stepped dump, whose schedule\n * is `stepSchedule` in `./constraints_physics.ts`. A second dump would be the\n * same numbers twice.\n *\n * ⛔ **A track refused part-way stays refused.** A step is checked before\n * anything moves; a refusal past that — a construct the core leaves out, a\n * non-finite vertex or write — comes after the track time and the physics\n * have moved, so every later `step` refuses naming the step it was refused\n * at, and the caller opens the track again. So does an error the caller's own\n * `adjust` throws: it is thrown mid-step, after the same moves. Seeking is the caller's too: a physics rig has\n * history, so a seek is \"open, then step to the time\".\n */\nimport { CoreInputError, type CompiledDocument } from './index.ts';\nimport { openRawTrack, stepRawTrack, type RawPose, type RawReset, type TrackState, type WalkMode } from './raw.ts';\nimport type { LocalAdjust, TimelinePlant } from './animation.ts';\nexport type { AdjustableLocals, BoneLocals, LocalAdjust } from './animation.ts';\n\n/** How a live track is opened: whether it loops, and where its physics is reset (`RawReset`) — both the caller's, neither with a default — and the caller's adjustment of every pose's bone locals (the header's *The adjustment*). */\nexport interface TrackOptions {\n loop: boolean;\n reset: RawReset;\n adjust?: LocalAdjust;\n}\n\n/** A live track (`openTrack`): pose 0, then one pose per `step`. */\nexport interface LiveTrack {\n /** Pose 0, posed when the track was opened: the batch walk's first pose under the same `reset`. */\n readonly first: RawPose;\n /** The next pose: the track time moved by `dt`, a finite time at or above 0. */\n step(dt: number): RawPose;\n /** The running sum of the steps taken, 0 before the first. */\n readonly trackTime: number;\n /** The time the latest pose applied the animation at (0 for pose 0). */\n readonly animationTime: number;\n /** The runtime's duration of the animation (`CoreAnimationTimelines.duration`). */\n readonly duration: number;\n}\n\n/** The two modes: a track that holds at its duration is the raw entry's walk; a looping one fires its events across the wrap and cuts its clipped rows (`live`). Neither keeps a non-finite value. */\nconst HELD: WalkMode = { loop: false, keep: false };\nconst LOOPED: WalkMode = { loop: true, keep: false, live: true };\n\n/**\n * One animation opened on a live track (the header): refused by name where the\n * batch walk refuses the same document and animation, pose 0 posed, then\n * stepped one `dt` at a time.\n */\nexport function openTrack(doc: CompiledDocument, animation: string, options: TrackOptions, plant: TimelinePlant = {}): LiveTrack {\n if (typeof options !== 'object' || options === null || typeof options.loop !== 'boolean') throw new CoreInputError(`the live track's options.loop is ${JSON.stringify((options as Partial<TrackOptions> | null)?.loop)}, not true or false`);\n if (options.reset !== 'animation' && options.reset !== 'setup') throw new CoreInputError(`the live track's options.reset is ${JSON.stringify(options.reset)}, not \"animation\" or \"setup\"`);\n if (options.adjust !== undefined && typeof options.adjust !== 'function') throw new CoreInputError(`the live track's options.adjust is ${typeof options.adjust}, not a function`);\n const { track, first } = openRawTrack(doc, animation, plant, options.reset, options.loop ? LOOPED : HELD, options.adjust);\n return new Track(track, first);\n}\n\nclass Track implements LiveTrack {\n readonly first: RawPose;\n private readonly track: TrackState<RawPose>;\n private steps = 0;\n private latest: number;\n private refused: string | null = null;\n\n constructor(track: TrackState<RawPose>, first: RawPose) {\n this.track = track;\n this.first = first;\n this.latest = first.animationTime;\n }\n\n get trackTime(): number {\n return this.track.trackTime;\n }\n\n get animationTime(): number {\n return this.latest;\n }\n\n get duration(): number {\n return this.track.duration;\n }\n\n step(dt: number): RawPose {\n const n = this.steps + 1;\n if (this.refused !== null) throw new CoreInputError(`the live track was refused at step ${this.refused}, after its time and physics had moved; open the track again`);\n if (typeof dt !== 'number' || !Number.isFinite(dt) || dt < 0) throw new CoreInputError(`the live track's step ${n} is ${String(dt)}, not a finite time at or above 0`);\n try {\n const pose = stepRawTrack(this.track, dt);\n this.steps = n;\n this.latest = pose.animationTime;\n return pose;\n } catch (err) {\n this.refused = `${n} (${err instanceof Error ? err.message : String(err)})`;\n throw err;\n }\n }\n}\n","/**\n * The core's live tracks (issue #1336, piece (a)): several animations over\n * one document, each on a track of its own, queued, replaced and mixed out the\n * way spine-core 4.3.13's `AnimationState` does it, stepped one `dt` at a\n * time — a player composing a character in real time: a looping base on\n * track 0, a pose held at its end on track 1 and replaced over a mix, a\n * one-shot on track 2 played once and mixed back out, and the player's own\n * bone-local adjustment (`LocalAdjust`, issue #1336's piece (b)) after every\n * track. Every pose is the raw entry's (`RawPose` in `./raw.ts`).\n *\n * It sits beside `openTrack` (`./track.ts`) rather than inside it because it\n * is a different object: one track holds one animation and its walk, and the\n * mixing below is a second state machine as long as that module's whole body.\n * What the two share is the pose path past the timelines — the adjustment,\n * the world, every constraint and the physics step (`steppedLocalsWorld` in\n * `./animation.ts`), the slot rows and the sliders (`slotRowsFrom`), the draw\n * order, the attachments and the pose's assembly (`openRawTracksPath` in\n * `./raw.ts`) — one body that the single track reaches with the locals one\n * animation posed and this state with the locals its mixed entries posed.\n *\n * ## What a step is\n *\n * `step(dt)` is a player's frame on spine-core: `AnimationState.update(dt)`,\n * `apply`, `Skeleton.update(dt)`, `updateWorldTransform(Physics.update)`. The\n * update moves every entry's track time, starts a queued entry whose delay\n * has passed, moves every mix and ends the entries a finished mix leaves; the\n * apply poses every track in order 0..N over the setup pose — every pose is\n * posed from the setup pose, as the single track's is, so nothing but the\n * entries' state survives a step — and then the adjustment, the constraints\n * and the physics. `start()` is pose 0, the reset, where `reset` says\n * (`RawReset`): at the setup pose with nothing applied, or with the tracks set\n * so far applied at 0 (an `apply` with no `update`) and reset there.\n *\n * ## The mixing — spine-core's, ported and measured\n *\n * The state below is `AnimationState`'s, field for field and in its order of\n * operations, over the core's own timelines — so that every number is the one\n * the runtime computes, which is the only thing a control at tolerance 0 can\n * hold. In brief:\n *\n * - **Track 0 at full weight poses from the setup pose** (`MixFrom.setup`,\n * alpha 1): exactly the single track's pose. `CO51`'s positive control holds\n * a state with only track 0 set to `openTrack` on the same animation, every\n * field, bit for bit.\n * - **Every other application reads its `timelineMode`**: a property no\n * earlier entry of the same track and no lower track keys mixes from the\n * setup pose (`SETUP`); one a lower track keys mixes from the value it left\n * (`CURRENT`: a bone channel `current + (value + setup − current)·alpha`,\n * and nothing at all before the timeline's first key); one an older entry of\n * the same track keys mixes from the current value, and before its first key\n * towards the setup value (`FIRST`). A property the entry mixing in keys too\n * is HELD on the entry mixing out — applied at the hold alpha\n * `alphaMix / (1 − mix)` rather than faded, so the two do not dip through\n * the setup pose — and a hold whose next entry stops keying it fades by that\n * entry's own mix (`timelineHoldMix`).\n * - **The mix**: `mixTime / mixDuration` clamped to 1 (a mix of 0 is 1), the\n * mixing-out entry applied at `alphaMix = a·(1 − mix)`; the entry mixing in\n * at the mix. A rotation mixed at an alpha below 1 turns the way it first\n * turned (`applyRotateTimeline`'s remembered direction); a scale mixed out\n * keeps the sign of the value it mixes from.\n * - **Attachments**: an entry mixing out never keeps an attachment it keys —\n * it shows it for its own deform timelines and the slot goes back to its\n * setup attachment at the end of the apply unless an entry applied at full\n * strength keyed it (`ATTACH_SETUP` / `ATTACH_RETAIN`).\n * - **The queue**: `addAnimation` with a delay at or below 0 starts the entry\n * when the entry before it completes less its mix — at its duration, or for\n * a looping one at the end of its current cycle (`getTrackComplete`) — plus\n * the delay; `addEmptyAnimation(track, mix, 0)` after a one-shot so mixes it\n * out over its last `mix` seconds. A `delay` above 0 is that many seconds\n * after the entry before starts.\n * - **Events** fire from each track's current entry as the single live track\n * fires them (`CO47`'s rule, across the wrap included). ⚠️ **An entry mixing\n * out fires none** — not \"until the mix passes half way\": `eventThreshold`\n * defaults to 0 and an entry's events are applied only while `mix <\n * eventThreshold`, which no mix is. `complete` is not carried (issue #1276).\n * - **Physics** steps on top of the mixed locals, as on one track.\n *\n * `CO51` holds all of it to spine-core 4.3.13 at tolerance 0 — every bone's\n * world transform, every drawn attachment's world vertices, every slot's\n * colour and attachment, the draw order and the events — over scripted calls\n * and seeded steps on the tree's rows, and reads each rejected reading red\n * (`TracksPlant`). The oracle's bones are brought back to the setup pose\n * (`Skeleton.setupPoseBones`) before every `apply`, as `CO50`'s are, and\n * measured that reset is needed for one thing only: with no adjustment,\n * spine-core with no reset at all agrees on every walk — `AnimationState`\n * writes back every property it keyed, through mixes, holds, empties and the\n * queue — while the player's write on a channel no entry keys carries and\n * compounds without it. The state carries nothing from one step to the next\n * but its entries, so a write lasts one pose, as on the single track.\n *\n * ## Alpha and additive entries (issue #1344)\n *\n * An entry carries spine-core's `TrackEntry.alpha` (`MixOptions.alpha`, 1 when\n * absent, changed while it plays by `setAlpha`) and `TrackEntry.additive`\n * (`MixOptions.additive`). 4.3.13 has no `MixBlend` on an entry — `additive` is\n * a boolean fixed before the next apply — so the option carries that name and\n * that type. What the runtime does with them, ported and measured (`CO52`):\n *\n * - **Alpha is a weight, multiplied in**: the current entry applies at\n * `alpha · mix`; one mixing out at `from.alpha · fromMix · (1 − mix)`, its\n * held timelines at that over `1 − mix · to.alpha`. Track 0 below alpha 1\n * leaves the setup-pose shortcut and mixes as a higher track does.\n * - **Events ignore alpha**: the current entry fires its events at any alpha,\n * 0 included; an entry mixing out fires none (`eventThreshold` 0, above).\n * - **Attachments ignore alpha**: `alphaAttachmentThreshold` is 0, so the\n * current entry keeps its attachments at any alpha, 0 included;\n * `mixAttachmentThreshold` is 0, so an entry mixing out keeps none. The draw\n * order stays refused, so `mixDrawOrderThreshold` has nothing to act on.\n * - **Additive adds what the runtime marks additive** (`Timeline.additive`):\n * every bone timeline keying numbers and the deform. On a property a lower\n * track or an older entry keyed, the keyed value (a rotation's, a\n * translation's, a shear's) is added times alpha — `current + value · alpha`\n * — a scale's offset from the setup scale is added, and a deform's offset\n * from the setup vertices (weighted: the offsets themselves). From the setup\n * pose it is the same as replacing. A rotation is added as it stands, with\n * no shortest-angle wrap and no remembered direction (`shortestRotation` is\n * `additive || …`). Colour, attachment, inherit and event timelines do not\n * read `add`: under an additive entry they apply as under a replacing one.\n * Track 0 at alpha 1 with no mix adds nothing — the runtime passes `add`\n * false on that shortcut.\n * - **An additive entry is never held**, and does not hold what it mixes in\n * over: its additive timelines take their mode with no `HOLD` bit, and a\n * timeline of an entry it replaces is not held for it. Mixing out, an\n * additive entry adds at its faded alpha, so its offset fades to nothing.\n *\n * `CO52`'s oracle resets bones and slots (`setupPose()`) before every apply,\n * not the bones alone as `CO51`'s does: on its blend probe a two-colour key at\n * a partial alpha over track 0's `rgba` mixes the dark colour from what the\n * previous frame left, which carries in a runtime whose slots are not reset —\n * measured off with the bones-only reset, equal with the full one. The state\n * poses every frame from the setup pose, slots included, as it always has.\n *\n * Each rejected reading is planted (`TracksPlant`) and read red by `CO52`:\n * alpha inverted, alpha ignored, additive as replace, an additive rotation\n * through the remembered direction, an additive entry's attachments as a\n * plain timeline, the hold blind to the entry mixing in, the holds as if no\n * entry were additive, and an alpha threshold of one half on attachments.\n *\n * ## What is left out, by name\n *\n * An animation is refused when it is set or queued if it keys what the state\n * does not mix: a constraint timeline (ik, transform, path, physics, slider),\n * a sequence timeline, the draw order, or a deform of a path attachment (a\n * path's deformed curve reaches the constraints, which this state poses from\n * their records as they stand). `timeScale`, `holdPrevious`, `reverse`,\n * `shortestRotation` on a replacing entry, the thresholds as options, per-pair\n * mix tables and the listeners are not offered. An additive entry is refused\n * nothing more: every timeline the state accepts is defined under it (*Alpha\n * and additive entries* below).\n *\n * ⛔ **A state refused part-way stays refused**, as a live track does: a step\n * is checked before anything moves, and a refusal past that — a construct the\n * core leaves out, a non-finite vertex or write, an error the caller's own\n * `adjust` throws — comes after the entries and the physics have moved, so\n * every later call refuses naming the call it was refused at.\n */\nimport type { ModelBone, ModelSlot, ModelVertices } from '../model.ts';\nimport { activeBones, CoreInputError, rawNumber, readColour, shownAttachment, type CompiledDocument, type CoreShown } from './index.ts';\nimport { channelAt, keyIndexAt, SLOT_COLOUR_TIMELINES, slotRowsFrom, steppedLocalsWorld, type BoneTimelineKind, type CoreKey, type LocalAdjust, type SlotBase, type SlotColourKind, type TimelinePlant } from './animation.ts';\nimport { deformAt, setupArray, type CoreAttachmentTimeline } from './deform.ts';\nimport { eventsFired, type CoreEventKey, type CoreEventRow } from './events.ts';\nimport { openRawTracksPath, type RawPose, type RawReset, type RawTracksPath } from './raw.ts';\nimport { slotTimelinesApply } from './skins.ts';\n\n/** How the live tracks are opened: where the physics is reset (`RawReset`, the caller's, no default) and the caller's adjustment of every pose's bone locals. */\nexport interface TracksOptions {\n reset: RawReset;\n adjust?: LocalAdjust;\n}\n\n/**\n * How `setAnimation` starts an entry: whether it loops, over how many seconds\n * the entry it replaces mixes out (0 cuts), and — issue #1344 — how strongly\n * it applies and whether it adds (the header's *Alpha and additive entries*).\n */\nexport interface MixOptions {\n loop: boolean;\n mixDuration: number;\n /** `TrackEntry.alpha`: from 0 to 1, multiplied into every timeline's weight; 1 when absent. Changed while the entry plays with `LiveTracks.setAlpha`. */\n alpha?: number;\n /** `TrackEntry.additive`: the entry's bone and deform timelines add their keyed values to what the tracks below posed rather than replacing it; `false` when absent. Fixed when the entry is set or queued, as the runtime fixes it before the next apply. */\n additive?: boolean;\n}\n\n/** How `addAnimation` queues an entry: `MixOptions`, and its delay — at or below 0 relative to when the entry before it completes, above 0 seconds after the entry before starts. */\nexport interface QueueOptions extends MixOptions {\n delay: number;\n}\n\n/** A track's current entry as a player reads it: what it plays (`null` the empty animation), its times and the animation's duration — what a player detects a completion from. */\nexport interface TrackEntryView {\n animation: string | null;\n loop: boolean;\n trackTime: number;\n /** The animation time the entry applies at now (`getAnimationTime`): the track time wrapped or held at the duration. */\n animationTime: number;\n duration: number;\n /** The entry's alpha as it stands (`MixOptions.alpha`, `LiveTracks.setAlpha`). */\n alpha: number;\n /** Whether the entry adds (`MixOptions.additive`). */\n additive: boolean;\n}\n\n/** The live tracks (`openTracks`). */\nexport interface LiveTracks {\n /** Replaces what `track` plays; the entry it replaces mixes out over `mixDuration` seconds (0 cuts). Every queued entry on the track is dropped. */\n setAnimation(track: number, animation: string, options: MixOptions): void;\n /** Mixes `track` out to nothing over `mixDuration` seconds. */\n setEmptyAnimation(track: number, mixDuration: number): void;\n /** Queues `animation` after the last entry on `track` (`QueueOptions`); on an empty track, it is set. */\n addAnimation(track: number, animation: string, options: QueueOptions): void;\n /** Queues a mix out to nothing after the last entry on `track`; `delay` 0 ends the mix when that entry completes. */\n addEmptyAnimation(track: number, mixDuration: number, delay: number): void;\n /** Sets the alpha of `track`'s current entry (`TrackEntry.alpha`), from the next pose on; an entry it mixes from keeps its own. A track playing nothing is refused. */\n setAlpha(track: number, alpha: number): void;\n /** Pose 0, the reset (the header's *What a step is*): once, before the first `step`. */\n start(): RawPose;\n /** The next pose: every entry moved by `dt`, a finite time at or above 0. */\n step(dt: number): RawPose;\n /** `track`'s current entry, or `null` where it plays nothing. */\n current(track: number): TrackEntryView | null;\n /** The running sum of the steps taken, 0 before the first. */\n readonly trackTime: number;\n}\n\n/**\n * The rejected readings `CO51` plants back, each on its own: the mix reversed\n * (`1 − mix`), every track above 0 mixed from the setup pose rather than the\n * value the tracks below left, the hold ignored (an entry mixing out faded on\n * a property the entry mixing in keys too), a queued entry's delay at or\n * below 0 read as \"now\" rather than as the entry before's completion, and an\n * entry mixing out firing its events until the mix passes one half. Nothing\n * but a control passes one.\n */\nexport interface TracksPlant extends TimelinePlant {\n mixReversed?: boolean;\n higherTracksFromSetup?: boolean;\n holdFaded?: boolean;\n queueDelayNow?: boolean;\n /** An entry mixing out fires its events while the mix is below one half — the reading the issue's brief stated, which the runtime's `eventThreshold` of 0 contradicts. */\n eventsUntilHalfMix?: boolean;\n /** `CO52`'s, issue #1344: every entry's alpha read as `1 − alpha`. */\n alphaInverted?: boolean;\n /** Every entry's alpha read as 1 — the option ignored. */\n alphaIgnored?: boolean;\n /** An additive entry applied, and its modes computed, as a replacing one. */\n additiveAsReplace?: boolean;\n /** An additive entry's rotations mixed through the remembered direction (`applyRotateTimeline`) as a replacing entry's are, rather than added through the timeline itself. */\n additiveRotateRemembered?: boolean;\n /** An additive entry's attachment timelines applied as a plain timeline (`AttachmentTimeline.apply`, no attachment state) rather than under the threshold rule (`applyAttachmentTimeline`). */\n additiveAttachmentsDirect?: boolean;\n /** The hold alpha computed as if the entry mixing in were at alpha 1 (`keep = 1 − mix`, not `1 − mix·to.alpha`). */\n holdIgnoresEntryAlpha?: boolean;\n /** The holds computed as if no entry were additive: an additive entry's own timelines held, and a timeline held under an additive entry mixing in. */\n additiveHeld?: boolean;\n /** An entry applied below alpha one half keeps none of its attachments — a threshold the runtime's `alphaAttachmentThreshold` of 0 does not have. */\n attachmentsBelowHalfAlpha?: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// the timelines, as the state applies them\n// ---------------------------------------------------------------------------\n\n/** `timelineMode`'s bits, as `AnimationState` spells them: where a timeline mixes from, and whether it is held. */\nconst CURRENT = 0;\nconst SETUP = 1;\nconst FIRST = 2;\nconst MODE = 3;\nconst HOLD = 4;\n\n/** One timeline of an animation in the order spine-core's `Animation.timelines` holds them: the slots' (attachment and colour), the bones', the deforms, then the events. */\ntype MixTimeline =\n | { type: 'bone'; bone: number; kind: BoneTimelineKind; keys: CoreKey[]; ids: string[]; instant: boolean }\n | { type: 'colour'; slot: number; kind: SlotColourKind; keys: CoreKey[]; ids: string[]; instant: false }\n | { type: 'attachment'; slot: number; keys: CoreKey[]; ids: string[]; instant: true }\n | { type: 'deform'; identity: string; timeline: CoreAttachmentTimeline; ids: string[]; instant: false }\n | { type: 'events'; keys: CoreEventKey[]; ids: string[]; instant: true };\n\n/** An animation as the state applies it: its runtime duration, its timelines and every property they key (`Animation.hasTimeline`). */\ninterface MixAnimation {\n name: string | null;\n duration: number;\n timelines: MixTimeline[];\n ids: ReadonlySet<string>;\n}\n\n/** The empty animation (`AnimationState.emptyAnimation`): no timeline, duration 0 — one object, so setting it on an entry never applied replaces that entry. */\nconst EMPTY: MixAnimation = { name: null, duration: 0, timelines: [], ids: new Set() };\n\n/** `Timeline.additive`: the timelines the runtime adds under an additive entry — every bone timeline that keys numbers, and the deform. Colour, attachment, inherit and event timelines do not read `add`. */\nfunction addable(tl: MixTimeline): boolean {\n return tl.type === 'deform' || (tl.type === 'bone' && tl.kind !== 'inherit');\n}\n\n/** The properties a bone timeline keys, spine-core's `propertyIds` by bone name. */\nconst BONE_PROPERTIES: Record<BoneTimelineKind, readonly string[]> = {\n rotate: ['rotate'], translate: ['x', 'y'], translatex: ['x'], translatey: ['y'], scale: ['scaleX', 'scaleY'], scalex: ['scaleX'], scaley: ['scaleY'], shear: ['shearX', 'shearY'], shearx: ['shearX'], sheary: ['shearY'], inherit: ['inherit'],\n};\n\n/** The properties a slot colour timeline keys. */\nconst COLOUR_PROPERTIES: Record<SlotColourKind, readonly string[]> = { rgba: ['rgb', 'alpha'], rgb: ['rgb'], alpha: ['alpha'], rgba2: ['rgb', 'alpha', 'rgb2'], rgb2: ['rgb', 'rgb2'] };\n\n/**\n * An animation compiled for the state, or refused by name where it keys what\n * the state does not mix (the header's *What is left out*). The property ids\n * are spine-core's by name — `x|bone`, `rgb|slot`, `deform|slot|record` — so\n * two timelines key one property exactly where the runtime's do.\n */\nfunction mixAnimationOf(doc: CompiledDocument, name: string): MixAnimation {\n const anim = doc.animations.find((a) => a.name === name);\n if (anim === undefined) throw new CoreInputError(`animation \"${name}\" is not one of this document's [${doc.animations.map((a) => a.name).join(', ')}]`);\n const t = anim.timelines;\n const c = anim.constraints;\n const left: string[] = [];\n for (const [kind, n] of [['ik', c.ik.length], ['transform', c.transform.length], ['path', c.path.length], ['physics', c.physics + (c.physicsKeyed?.length ?? 0)], ['slider', c.slider.length]] as const) if (n > 0) left.push(`${kind} constraint timelines`);\n if (t.attachments.some((a) => a.sequence !== null)) left.push('a sequence timeline');\n if (t.drawOrder.length > 0) left.push('the draw order');\n for (const a of t.attachments) {\n if (a.deform === null) continue;\n const g = doc.skins.find((k) => k.name === a.skin)?.attachments[a.slot]?.[a.attachment]?.geometry;\n if (g?.kind === 'path') left.push(`a deform of path attachment \"${a.skin}/${a.slot}/${a.attachment}\"`);\n }\n if (left.length > 0) throw new CoreInputError(`animation \"${name}\" keys ${left.join(', ')}, which the live tracks do not mix — they mix bone, slot colour, attachment and deform timelines, and fire events (issue #1336)`);\n const boneIndex = new Map(doc.bones.map((b, i) => [b.name, i]));\n const slotIndex = new Map(doc.slots.map((s, i) => [s.name, i]));\n const timelines: MixTimeline[] = [];\n for (const target of t.slots) {\n const slot = slotIndex.get(target.name) as number;\n for (const tl of target.timelines) {\n if (tl.kind === 'attachment') timelines.push({ type: 'attachment', slot, keys: tl.keys, ids: [`attachment|${target.name}`], instant: true });\n else timelines.push({ type: 'colour', slot, kind: tl.kind, keys: tl.keys, ids: COLOUR_PROPERTIES[tl.kind].map((p) => `${p}|${target.name}`), instant: false });\n }\n }\n for (const target of t.bones) {\n const bone = boneIndex.get(target.name) as number;\n for (const tl of target.timelines) timelines.push({ type: 'bone', bone, kind: tl.kind, keys: tl.keys, ids: BONE_PROPERTIES[tl.kind].map((p) => `${p}|${target.name}`), instant: tl.kind === 'inherit' });\n }\n for (const a of t.attachments) {\n if (a.deform === null) continue;\n const identity = `${a.skin}/${a.slot}/${a.attachment}`;\n timelines.push({ type: 'deform', identity, timeline: a, ids: [`deform|${a.slot}|${identity}`], instant: false });\n }\n if (t.events.length > 0) timelines.push({ type: 'events', keys: t.events, ids: ['event'], instant: true });\n return { name, duration: t.duration, timelines, ids: new Set(timelines.flatMap((x) => x.ids)) };\n}\n\n/**\n * The property ids an animation's timelines key, in the order the state\n * applies them — what `CO51` holds to spine-core's `Animation.timelines`, since\n * a timeline's mode depends on which timeline of the same track saw its\n * property first.\n */\nexport function mixPropertyOrder(doc: CompiledDocument, animation: string): string[][] {\n return mixAnimationOf(doc, animation).timelines.map((x) => x.ids);\n}\n\n// ---------------------------------------------------------------------------\n// the entries — `TrackEntry`\n// ---------------------------------------------------------------------------\n\ninterface Entry {\n anim: MixAnimation;\n loop: boolean;\n previous: Entry | null;\n next: Entry | null;\n mixingFrom: Entry | null;\n mixingTo: Entry | null;\n delay: number;\n trackTime: number;\n trackLast: number;\n nextTrackLast: number;\n trackEnd: number;\n animationLast: number;\n nextAnimationLast: number;\n mixTime: number;\n mixDuration: number;\n totalAlpha: number;\n /** `TrackEntry.alpha`. */\n alpha: number;\n /** `TrackEntry.additive`. */\n additive: boolean;\n keepHold: boolean;\n timelineMode: number[];\n timelineHoldMix: Array<Entry | null | undefined>;\n /** Each rotate timeline's remembered direction, two numbers per timeline; its length is what marks the first frame (`applyRotateTimeline`). */\n timelinesRotation: number[];\n}\n\n/** A new entry (`AnimationState.trackEntry`): every field the runtime's default; the mix duration 0, `AnimationStateData`'s default mix, alpha 1, not additive. */\nfunction newEntry(anim: MixAnimation, loop: boolean): Entry {\n return {\n anim, loop, previous: null, next: null, mixingFrom: null, mixingTo: null,\n delay: 0, trackTime: 0, trackLast: -1, nextTrackLast: -1, trackEnd: Number.MAX_VALUE,\n animationLast: -1, nextAnimationLast: -1, mixTime: 0, mixDuration: 0, totalAlpha: 0, alpha: 1, additive: false, keepHold: false,\n timelineMode: [], timelineHoldMix: [], timelinesRotation: [],\n };\n}\n\n/** `TrackEntry.getAnimationTime`: the track time wrapped by the duration (0 over a duration of 0) when looping, else held at the duration. */\nfunction animationTimeOf(e: Entry): number {\n if (!e.loop) return Math.min(e.trackTime + 0, e.anim.duration);\n const d = e.anim.duration;\n if (d === 0) return 0;\n return (e.trackTime % d) + 0;\n}\n\n/** `TrackEntry.getTrackComplete`: when a looping entry ends its current cycle, when a held one reaches its duration, or now. */\nfunction trackComplete(e: Entry): number {\n const d = e.anim.duration;\n if (d !== 0) {\n if (e.loop) return d * (1 + ((e.trackTime / d) | 0));\n if (e.trackTime < d) return d;\n }\n return e.trackTime;\n}\n\nconst signum = (v: number): number => (v > 0 ? 1 : v < 0 ? -1 : 0);\nconst clamp01 = (v: number): number => (v < 0 ? 0 : v > 1 ? 1 : v);\n\n// ---------------------------------------------------------------------------\n// one step's skeleton — the pose the entries are applied to\n// ---------------------------------------------------------------------------\n\n/** `Slot.attachmentState` against the apply's `unkeyedState`: untouched, shown for a deform only, or kept. */\nconst ATTACH_NONE = 0;\nconst ATTACH_SETUP = 1;\nconst ATTACH_RETAIN = 2;\n\ninterface SlotState {\n placeholder: string | null;\n light: number[];\n dark: number[] | null;\n deform: number[] | null;\n seen: string[];\n attachmentState: number;\n}\n\n/** What a slot's placeholder resolves to, as the state compares attachments: the record's own key, whether it is a vertex attachment, and the record its deform timelines are keyed as (`VertexAttachment.timelineAttachment`). */\ninterface Resolved {\n key: string | null;\n vertex: boolean;\n timeline: string | null;\n vertices: ModelVertices | null;\n}\n\nclass Pose {\n readonly bones: ModelBone[];\n readonly slots: SlotState[];\n readonly events: CoreEventRow[] = [];\n private readonly active: ReadonlySet<string>;\n private readonly live: boolean[];\n private readonly resolved = new Map<string, Resolved>();\n\n constructor(\n private readonly doc: CompiledDocument,\n private readonly plant: TracksPlant,\n ) {\n this.bones = [...doc.bones];\n this.active = activeBones(doc);\n const colour = plant.colour ?? readColour;\n const gate = plant.slotTimelines ?? slotTimelinesApply;\n this.live = doc.slots.map((s) => gate(doc, s, this.active));\n this.slots = doc.slots.map((slot): SlotState => {\n const setupDark = slot.dark === undefined ? null : readColour(slot.dark);\n return { placeholder: slot.setup, light: slot.color === undefined ? [1, 1, 1, 1] : colour(slot.color), dark: setupDark === null ? null : [setupDark[0], setupDark[1], setupDark[2]], deform: null, seen: [], attachmentState: ATTACH_NONE };\n });\n }\n\n /** Bone `i`'s locals to write: the setup bone copied on its first write, as `posedBones` copies a keyed one. */\n bone(i: number): ModelBone | null {\n const b = this.bones[i];\n if (!this.active.has(b.name)) return null;\n if (b === this.doc.bones[i]) this.bones[i] = { ...b };\n return this.bones[i];\n }\n\n slotLive(i: number): boolean {\n return this.live[i];\n }\n\n /** What `placeholder` shows in slot `i` (`Resolved`). */\n resolve(i: number, placeholder: string | null): Resolved {\n if (placeholder === null) return { key: null, vertex: false, timeline: null, vertices: null };\n const slot = this.doc.slots[i];\n const memo = `${i}\\u0000${placeholder}`;\n const known = this.resolved.get(memo);\n if (known !== undefined) return known;\n const s = (this.plant.shown ?? shownAttachment)(this.doc, { ...slot, setup: placeholder });\n let out: Resolved;\n if (s === null) out = { key: null, vertex: false, timeline: null, vertices: null };\n else if ('conflict' in s) out = { key: `conflict\\u0000${placeholder}`, vertex: false, timeline: null, vertices: null };\n else out = resolvedOf(this.doc, slot, s);\n this.resolved.set(memo, out);\n return out;\n }\n\n /** `SlotPose.setAttachment`: a different attachment clears the deform unless both play the same record's timelines. */\n setAttachment(i: number, placeholder: string | null): void {\n const s = this.slots[i];\n const was = this.resolve(i, s.placeholder);\n const now = this.resolve(i, placeholder);\n s.placeholder = placeholder;\n if (was.key === now.key) return;\n if (!now.vertex || !was.vertex || now.timeline !== was.timeline) s.deform = null;\n }\n}\n\n/** A shown record as the state compares it (`Resolved`): a vertex attachment plays its own record's timelines, a linked mesh that plays its source's those. */\nfunction resolvedOf(doc: CompiledDocument, slot: ModelSlot, s: CoreShown): Resolved {\n const g = s.record.geometry;\n const key = `${s.skin}\\u0000${s.placeholder}`;\n if (g === undefined || g.kind === 'region') return { key, vertex: false, timeline: null, vertices: null };\n if (g.kind === 'linkedmesh') {\n const source = doc.skins.find((k) => k.name === g.skin)?.attachments[g.slot]?.[g.source]?.geometry;\n const vertices = source !== undefined && source.kind !== 'region' && source.kind !== 'linkedmesh' ? source.vertices : null;\n return { key, vertex: true, timeline: s.record.timelines === true ? `${g.skin}/${g.slot}/${g.source}` : `${s.skin}/${slot.name}/${s.placeholder}`, vertices };\n }\n return { key, vertex: true, timeline: `${s.skin}/${slot.name}/${s.placeholder}`, vertices: g.vertices };\n}\n\n// ---------------------------------------------------------------------------\n// the state — `AnimationState`\n// ---------------------------------------------------------------------------\n\nclass Mixer {\n readonly tracks: Array<Entry | null> = [];\n private animationsChanged = false;\n private readonly propertyIds = new Map<string, number>();\n private readonly anims = new Map<string, MixAnimation>();\n\n constructor(\n private readonly doc: CompiledDocument,\n private readonly plant: TracksPlant,\n ) {}\n\n animation(name: string): MixAnimation {\n let a = this.anims.get(name);\n if (a === undefined) {\n a = mixAnimationOf(this.doc, name);\n this.anims.set(name, a);\n }\n return a;\n }\n\n private changed(): void {\n this.animationsChanged = true;\n }\n\n private expandToIndex(index: number): Entry | null {\n while (this.tracks.length <= index) this.tracks.push(null);\n return this.tracks[index];\n }\n\n private clearNext(entry: Entry): void {\n entry.next = null;\n }\n\n private setTrack(index: number, current: Entry): void {\n const from = this.expandToIndex(index);\n this.tracks[index] = current;\n current.previous = null;\n if (from !== null) {\n from.next = null;\n current.mixingFrom = from;\n from.mixingTo = current;\n current.mixTime = 0;\n // Reset rotation for mixing out, in case the entry was mixed in.\n from.timelinesRotation.length = 0;\n }\n this.changed();\n }\n\n setAnimation(track: number, anim: MixAnimation, loop: boolean): Entry {\n let current = this.expandToIndex(track);\n if (current !== null) {\n if (current.nextTrackLast === -1 && current.anim === anim) {\n // Don't mix from an entry that was never applied.\n this.tracks[track] = current.mixingFrom;\n this.changed();\n this.clearNext(current);\n current = current.mixingFrom;\n } else this.clearNext(current);\n }\n const entry = newEntry(anim, loop);\n this.setTrack(track, entry);\n return entry;\n }\n\n addAnimation(track: number, anim: MixAnimation, loop: boolean, delay: number): Entry {\n let last = this.expandToIndex(track);\n if (last !== null) while (last.next !== null) last = last.next;\n const entry = newEntry(anim, loop);\n if (last === null) {\n this.setTrack(track, entry);\n if (delay < 0) delay = 0;\n } else {\n last.next = entry;\n entry.previous = last;\n if (delay <= 0) delay = Math.max(delay + this.complete(last) - entry.mixDuration, 0);\n }\n entry.delay = delay;\n return entry;\n }\n\n /** `TrackEntry.setMixDuration(mixDuration, delay)`. */\n setMixDuration(entry: Entry, mixDuration: number, delay: number): void {\n entry.mixDuration = mixDuration;\n if (delay <= 0) delay = entry.previous === null ? 0 : Math.max(delay + this.complete(entry.previous) - mixDuration, 0);\n entry.delay = delay;\n }\n\n /** `getTrackComplete`, or 0 under the plant that reads a queued delay as \"now\". */\n complete(e: Entry): number {\n return this.plant.queueDelayNow === true ? e.trackTime : trackComplete(e);\n }\n\n /** `TrackEntry.mix()`: `mixTime / mixDuration` clamped to 1, 1 over a mix of 0 — reversed under the plant. */\n mixOf(e: Entry): number {\n let m: number;\n if (e.mixDuration === 0) m = 1;\n else {\n m = e.mixTime / e.mixDuration;\n if (m >= 1) m = 1;\n }\n return this.plant.mixReversed === true ? 1 - m : m;\n }\n\n /** `TrackEntry.alpha` — inverted or ignored under the plants. */\n alphaOf(e: Entry): number {\n if (this.plant.alphaIgnored === true) return 1;\n return this.plant.alphaInverted === true ? 1 - e.alpha : e.alpha;\n }\n\n /** `TrackEntry.additive` — never under the plant that applies an additive entry as a replacing one. */\n additiveOf(e: Entry): boolean {\n return e.additive && this.plant.additiveAsReplace !== true;\n }\n\n /** Whether `computeHold` reads an entry as additive — never under the plant that holds as if none were. */\n private holdsAdditive(e: Entry | null): boolean {\n return e !== null && this.additiveOf(e) && this.plant.additiveHeld !== true;\n }\n\n update(delta: number): void {\n const tracks = this.tracks;\n for (let i = 0, n = tracks.length; i < n; i++) {\n const current = tracks[i];\n if (current === null) continue;\n current.animationLast = current.nextAnimationLast;\n current.trackLast = current.nextTrackLast;\n let currentDelta = delta;\n if (current.delay > 0) {\n current.delay -= currentDelta;\n if (current.delay > 0) continue;\n currentDelta = -current.delay;\n current.delay = 0;\n }\n let next = current.next;\n if (next !== null) {\n // When the next entry's delay is passed, change to the next entry, preserving leftover time.\n const nextTime = current.trackLast - next.delay;\n if (nextTime >= 0) {\n next.delay = 0;\n next.trackTime += nextTime + delta;\n current.trackTime += currentDelta;\n this.setTrack(i, next);\n while (next.mixingFrom !== null) {\n next.mixTime += delta;\n next = next.mixingFrom;\n }\n continue;\n }\n } else if (current.trackLast >= current.trackEnd && current.mixingFrom === null) {\n tracks[i] = null;\n this.changed();\n this.clearNext(current);\n continue;\n }\n if (current.mixingFrom !== null && this.updateMixingFrom(current, delta)) {\n // End mixing from entries once all have completed.\n const from = current.mixingFrom;\n current.mixingFrom = null;\n if (from !== null) from.mixingTo = null;\n this.changed();\n }\n current.trackTime += currentDelta;\n }\n }\n\n private updateMixingFrom(to: Entry, delta: number): boolean {\n const from = to.mixingFrom;\n if (from === null) return true;\n const finished = this.updateMixingFrom(from, delta);\n from.animationLast = from.nextAnimationLast;\n from.trackLast = from.nextTrackLast;\n // The from entry was applied at least once and the mix is complete.\n if (to.nextTrackLast !== -1 && to.mixTime >= to.mixDuration) {\n // Mixing is complete for all entries before the from entry or the mix is instantaneous.\n if (from.totalAlpha === 0 || to.mixDuration === 0) {\n to.mixingFrom = from.mixingFrom;\n if (from.mixingFrom !== null) from.mixingFrom.mixingTo = to;\n if (from.totalAlpha === 0) for (let next: Entry | null = to; next.mixingTo !== null; next = next.mixingTo) next.keepHold = true;\n this.changed();\n }\n return finished;\n }\n from.trackTime += delta;\n to.mixTime += delta;\n return false;\n }\n\n /** `AnimationState.apply` onto one step's pose, every track in order; returns track 0's current entry's animation time (0 where it applied none). */\n apply(pose: Pose): number {\n if (this.animationsChanged) this.computeModes();\n let base = 0;\n const tracks = this.tracks;\n for (let i = 0, n = tracks.length; i < n; i++) {\n const current = tracks[i];\n if (current === null || current.delay > 0) continue;\n // Apply mixing from entries first.\n let alpha = this.alphaOf(current);\n if (current.mixingFrom !== null) alpha *= this.applyMixingFrom(current, pose, i);\n else if (current.trackTime >= current.trackEnd && current.next === null) alpha = 0;\n // Apply the current entry.\n const animationLast = current.animationLast;\n const animationTime = animationTimeOf(current);\n const timelines = current.anim.timelines;\n const count = timelines.length;\n if (i === 0 && alpha === 1) {\n // Track 0 at full weight poses from the setup pose and adds nothing, additive or not — the runtime passes `add` false here.\n for (const tl of timelines) {\n if (tl.type === 'attachment') this.applyAttachment(pose, tl, animationTime, SETUP, true);\n else this.applyTimeline(pose, tl, animationLast, animationTime, true, 1, SETUP, false, false);\n }\n } else {\n const modes = current.timelineMode;\n // `alphaAttachmentThreshold` is 0: an entry keeps its attachments at any alpha, 0 included.\n const retain = this.plant.attachmentsBelowHalfAlpha === true ? alpha >= 0.5 : alpha >= 0;\n const add = this.additiveOf(current);\n // `shortestRotation = add || …`: an additive entry's rotations go through the timeline itself, never the remembered direction.\n const shortest = add && this.plant.additiveRotateRemembered !== true;\n const firstFrame = !shortest && current.timelinesRotation.length !== count << 1;\n if (firstFrame) current.timelinesRotation.length = count << 1;\n timelines.forEach((tl, ii) => {\n const from = this.fromOf(modes[ii] & MODE, i);\n if (!shortest && tl.type === 'bone' && tl.kind === 'rotate') this.applyRotate(pose, tl, animationTime, alpha, from, current.timelinesRotation, ii << 1, firstFrame);\n else if (tl.type === 'attachment') {\n if (add && this.plant.additiveAttachmentsDirect === true) this.applyAttachmentDirect(pose, tl, animationTime, from, false);\n else this.applyAttachment(pose, tl, animationTime, from, retain);\n } else this.applyTimeline(pose, tl, animationLast, animationTime, true, alpha, from, false, add);\n });\n }\n if (i === 0) base = animationTime;\n current.nextAnimationLast = animationTime;\n current.nextTrackLast = current.trackTime;\n }\n // Set slot attachments to the setup pose if they were set temporarily to apply deform timelines.\n pose.slots.forEach((s, k) => {\n if (s.attachmentState === ATTACH_SETUP) pose.setAttachment(k, this.doc.slots[k].setup);\n });\n return base;\n }\n\n /** Where a timeline mixes from — `CURRENT` read as `SETUP` above track 0 under the plant. */\n private fromOf(from: number, track: number): number {\n return this.plant.higherTracksFromSetup === true && track > 0 && from === CURRENT ? SETUP : from;\n }\n\n private applyMixingFrom(to: Entry, pose: Pose, track: number): number {\n const from = to.mixingFrom as Entry;\n const fromMix = from.mixingFrom !== null ? this.applyMixingFrom(from, pose, track) : 1;\n const mix = this.mixOf(to);\n const a = this.alphaOf(from) * fromMix;\n const keep = 1 - mix * (this.plant.holdIgnoresEntryAlpha === true ? 1 : this.alphaOf(to));\n const alphaMix = a * (1 - mix);\n const alphaHold = keep > 0 ? alphaMix / keep : a;\n const timelines = from.anim.timelines;\n const count = timelines.length;\n const modes = from.timelineMode;\n const holdMix = from.timelineHoldMix;\n const add = this.additiveOf(from);\n const shortest = add && this.plant.additiveRotateRemembered !== true;\n const firstFrame = !shortest && from.timelinesRotation.length !== count << 1;\n if (firstFrame) from.timelinesRotation.length = count << 1;\n const animationLast = from.animationLast;\n const animationTime = animationTimeOf(from);\n const fire = this.plant.eventsUntilHalfMix === true && mix < 0.5;\n from.totalAlpha = 0;\n timelines.forEach((tl, i) => {\n const mode = modes[i];\n const mixFrom = this.fromOf(mode & MODE, track);\n let alpha: number;\n if ((mode & HOLD) !== 0 && this.plant.holdFaded !== true) {\n const h = holdMix[i];\n alpha = h === null || h === undefined ? alphaHold : alphaHold * (1 - this.mixOf(h));\n } else alpha = alphaMix;\n from.totalAlpha += alpha;\n if (!shortest && tl.type === 'bone' && tl.kind === 'rotate') this.applyRotate(pose, tl, animationTime, alpha, mixFrom, from.timelinesRotation, i << 1, firstFrame);\n else if (tl.type === 'attachment') {\n // `mixAttachmentThreshold` is 0: an entry mixing out never keeps an attachment, whatever its alpha.\n if (add && this.plant.additiveAttachmentsDirect === true) this.applyAttachmentDirect(pose, tl, animationTime, mixFrom, true);\n else this.applyAttachment(pose, tl, animationTime, mixFrom, false);\n }\n // An entry mixing out fires no event: `eventThreshold` is 0 and its events are applied only while the mix is below it.\n // An additive one mixing out adds at the faded alpha — its additive timelines are never held (`computeHold`).\n else this.applyTimeline(pose, tl, animationLast, animationTime, fire, alpha, mixFrom, true, add);\n });\n from.nextAnimationLast = animationTime;\n from.nextTrackLast = from.trackTime;\n return mix;\n }\n\n /** `_animationsChanged`: every track's entries' modes, oldest first, the property owners cleared after. */\n private computeModes(): void {\n this.animationsChanged = false;\n this.tracks.forEach((top, i) => {\n if (top === null) return;\n let entry: Entry | null = top;\n while (entry.mixingFrom !== null) entry = entry.mixingFrom;\n do {\n this.computeHold(entry, i);\n entry = entry.mixingTo;\n } while (entry !== null);\n });\n this.propertyIds.clear();\n }\n\n private computeHold(entry: Entry, track: number): void {\n const timelines = entry.anim.timelines;\n const modes = entry.timelineMode;\n modes.length = timelines.length;\n const holdMix = entry.timelineHoldMix;\n holdMix.length = 0;\n const to = entry.mixingTo;\n const add = this.holdsAdditive(entry);\n const toAdds = this.holdsAdditive(to);\n timelines.forEach((tl, i) => {\n const from = this.propertyFrom(track, tl.ids);\n // An additive entry's additive timelines are never held, and the entry's keepHold does not reach them.\n if (add && addable(tl)) {\n modes[i] = from;\n return;\n }\n let mode: number;\n // Hold if the next entry will overwrite this property — an additive one adding to it does not.\n if (to === null || tl.instant || (toAdds && addable(tl)) || !hasAny(to.anim, tl.ids)) mode = from;\n else {\n mode = from | HOLD;\n // Find the next entry that doesn't overwrite this property. Its mix fades out the hold, instead of it ending abruptly.\n for (let next = to.mixingTo; next !== null; next = next.mixingTo) {\n if ((this.holdsAdditive(next) && addable(tl)) || !hasAny(next.anim, tl.ids)) {\n if (next.mixDuration > 0) holdMix[i] = next;\n break;\n }\n }\n }\n if (entry.keepHold) mode = (mode & ~HOLD) | ((modes[i] ?? 0) & HOLD);\n modes[i] = mode;\n });\n }\n\n /** `AnimationState.from`: `SETUP` for a property no one keyed yet, `FIRST` for one this track keyed first, `CURRENT` for one a lower track keyed. */\n private propertyFrom(track: number, ids: readonly string[]): number {\n const owners = this.propertyIds;\n let from = SETUP;\n for (let i = 0, n = ids.length; i < n; i++) {\n const owner = owners.get(ids[i]);\n if (owner === undefined) owners.set(ids[i], track);\n else {\n if (owner !== track) {\n while (++i < n) if (!owners.has(ids[i])) owners.set(ids[i], track);\n return CURRENT;\n }\n from = FIRST;\n }\n }\n return from;\n }\n\n // -------------------------------------------------------------------------\n // the timelines' `apply`\n // -------------------------------------------------------------------------\n\n private values(keys: readonly CoreKey[], t: number): number[] | null {\n const index = (this.plant.search ?? keyIndexAt)(keys, t);\n if (index < 0) return null;\n const channel = this.plant.channel ?? channelAt;\n return keys[index].values.map((_v, c) => channel(keys, index, c, t));\n }\n\n /** `Timeline.apply` for every timeline but an attachment's and a rotation mixed below full weight; `add` is the entry's, read only by the timelines the runtime adds (`addable`). */\n private applyTimeline(pose: Pose, tl: MixTimeline, lastTime: number, time: number, fire: boolean, alpha: number, from: number, out: boolean, add: boolean): void {\n switch (tl.type) {\n case 'bone': return this.applyBone(pose, tl, time, alpha, from, out, add);\n case 'colour': return this.applyColour(pose, tl, time, alpha, from);\n case 'deform': return this.applyDeform(pose, tl, time, alpha, from, add);\n case 'events':\n if (fire) pose.events.push(...eventsFired(tl.keys, lastTime, time, rawNumber, time < lastTime));\n return;\n case 'attachment': return;\n }\n }\n\n private applyBone(pose: Pose, tl: Extract<MixTimeline, { type: 'bone' }>, time: number, alpha: number, from: number, out: boolean, add: boolean): void {\n const bone = pose.bone(tl.bone);\n if (bone === null) return;\n const setup = this.doc.bones[tl.bone];\n if (tl.kind === 'inherit') {\n const restore = (): void => {\n if (setup.inheritMode === undefined) delete bone.inheritMode;\n else bone.inheritMode = setup.inheritMode;\n };\n if (out) {\n if (from !== CURRENT) restore();\n return;\n }\n const index = (this.plant.search ?? keyIndexAt)(tl.keys, time);\n if (index < 0) {\n if (from !== CURRENT) restore();\n } else bone.inheritMode = tl.keys[index].mode;\n return;\n }\n const v = this.values(tl.keys, time);\n const relative = (field: 'x' | 'y' | 'rotation' | 'shearX' | 'shearY', i: number): void => {\n const s = setup[field] ?? 0;\n const c = bone[field] ?? 0;\n // `getRelativeValue`: from the setup pose the same either way; else the keyed value added, or the value over the setup mixed in.\n bone[field] = v === null ? beforeFirstKey(from, alpha, c, s) : from === SETUP ? s + v[i] * alpha : c + (add ? v[i] : v[i] + s - c) * alpha;\n };\n const pair = (fx: 'x' | 'shearX', fy: 'y' | 'shearY'): void => {\n const sx = setup[fx] ?? 0;\n const sy = setup[fy] ?? 0;\n if (v === null) {\n if (from === SETUP) {\n bone[fx] = sx;\n bone[fy] = sy;\n } else if (from === FIRST) {\n bone[fx] = (bone[fx] ?? 0) + (sx - (bone[fx] ?? 0)) * alpha;\n bone[fy] = (bone[fy] ?? 0) + (sy - (bone[fy] ?? 0)) * alpha;\n }\n return;\n }\n if (from === SETUP) {\n bone[fx] = sx + v[0] * alpha;\n bone[fy] = sy + v[1] * alpha;\n } else if (add) {\n bone[fx] = (bone[fx] ?? 0) + v[0] * alpha;\n bone[fy] = (bone[fy] ?? 0) + v[1] * alpha;\n } else {\n bone[fx] = (bone[fx] ?? 0) + (sx + v[0] - (bone[fx] ?? 0)) * alpha;\n bone[fy] = (bone[fy] ?? 0) + (sy + v[1] - (bone[fy] ?? 0)) * alpha;\n }\n };\n const scale = (field: 'scaleX' | 'scaleY', i: number): void => {\n const s = setup[field] ?? 1;\n const c = bone[field] ?? 1;\n bone[field] = v === null ? beforeFirstKey(from, alpha, c, s) : scaleValue(v[i] * s, alpha, from, out, add, c, s);\n };\n switch (tl.kind) {\n case 'rotate': relative('rotation', 0); break;\n case 'translate': pair('x', 'y'); break;\n case 'translatex': relative('x', 0); break;\n case 'translatey': relative('y', 0); break;\n case 'shear': pair('shearX', 'shearY'); break;\n case 'shearx': relative('shearX', 0); break;\n case 'sheary': relative('shearY', 0); break;\n case 'scale':\n if (v === null) {\n const sx = setup.scaleX ?? 1;\n const sy = setup.scaleY ?? 1;\n if (from === SETUP) {\n bone.scaleX = sx;\n bone.scaleY = sy;\n } else if (from === FIRST) {\n bone.scaleX = (bone.scaleX ?? 1) + (sx - (bone.scaleX ?? 1)) * alpha;\n bone.scaleY = (bone.scaleY ?? 1) + (sy - (bone.scaleY ?? 1)) * alpha;\n }\n } else {\n bone.scaleX = scaleValue(v[0] * (setup.scaleX ?? 1), alpha, from, out, add, bone.scaleX ?? 1, setup.scaleX ?? 1);\n bone.scaleY = scaleValue(v[1] * (setup.scaleY ?? 1), alpha, from, out, add, bone.scaleY ?? 1, setup.scaleY ?? 1);\n }\n break;\n case 'scalex': scale('scaleX', 0); break;\n case 'scaley': scale('scaleY', 0); break;\n }\n }\n\n /** `applyRotateTimeline`: a rotation mixed below full weight turns the way it first turned. */\n private applyRotate(pose: Pose, tl: Extract<MixTimeline, { type: 'bone' }>, time: number, alpha: number, from: number, rotations: number[], i: number, firstFrame: boolean): void {\n if (firstFrame) rotations[i] = 0;\n if (alpha === 1) {\n this.applyBone(pose, tl, time, 1, from, false, false);\n return;\n }\n const bone = pose.bone(tl.bone);\n if (bone === null) return;\n const setup = this.doc.bones[tl.bone].rotation ?? 0;\n const v = this.values(tl.keys, time);\n let r1: number;\n let r2: number;\n if (v === null) {\n if (from === SETUP) {\n bone.rotation = setup;\n return;\n }\n if (from === CURRENT) return;\n r1 = bone.rotation ?? 0;\n r2 = setup;\n } else {\n r1 = from === SETUP ? setup : (bone.rotation ?? 0);\n r2 = setup + v[0];\n }\n // Mix between rotations using the direction of the shortest route on the first frame while detecting crosses.\n let total: number;\n let diff = r2 - r1;\n diff -= Math.ceil(diff / 360 - 0.5) * 360;\n if (diff === 0) total = rotations[i];\n else {\n let lastTotal: number;\n let lastDiff: number;\n if (firstFrame) {\n lastTotal = 0;\n lastDiff = diff;\n } else {\n lastTotal = rotations[i];\n // A slot the runtime's array never wrote reads `undefined`, which compares as NaN.\n lastDiff = rotations[i + 1] ?? Number.NaN;\n }\n const loops = lastTotal - (lastTotal % 360);\n total = diff + loops;\n const current = diff >= 0;\n let dir = lastTotal >= 0;\n if (Math.abs(lastDiff) <= 90 && signum(lastDiff) !== signum(diff)) {\n if (Math.abs(lastTotal - loops) > 180) {\n total += 360 * signum(lastTotal);\n dir = current;\n } else if (loops !== 0) total -= 360 * signum(lastTotal);\n else dir = current;\n }\n if (dir !== current) total += 360 * signum(lastTotal);\n rotations[i] = total;\n }\n rotations[i + 1] = diff;\n bone.rotation = r1 + total * alpha;\n }\n\n /** `applyAttachmentTimeline`: shown for good when retained, else for the deform timelines only and set back at the end of the apply. */\n private applyAttachment(pose: Pose, tl: Extract<MixTimeline, { type: 'attachment' }>, time: number, from: number, retain: boolean): void {\n if (!pose.slotLive(tl.slot)) return;\n const s = pose.slots[tl.slot];\n if (!retain && s.attachmentState === ATTACH_RETAIN) return;\n const index = (this.plant.search ?? keyIndexAt)(tl.keys, time);\n let setup = index < 0;\n let name: string | null = null;\n if (!setup) {\n name = tl.keys[index].name ?? null;\n setup = !retain && name === null;\n }\n if (setup) {\n if (from === CURRENT) return;\n name = this.doc.slots[tl.slot].setup;\n }\n pose.setAttachment(tl.slot, name);\n if (retain) s.attachmentState = ATTACH_RETAIN;\n else if (!setup) s.attachmentState = ATTACH_SETUP;\n }\n\n /** `AttachmentTimeline.apply` — the plain timeline, writing no attachment state: only `additiveAttachmentsDirect` reaches it, the reading `CO52` rejects. */\n private applyAttachmentDirect(pose: Pose, tl: Extract<MixTimeline, { type: 'attachment' }>, time: number, from: number, out: boolean): void {\n if (!pose.slotLive(tl.slot)) return;\n const index = (this.plant.search ?? keyIndexAt)(tl.keys, time);\n if (out || index < 0) {\n if (from !== CURRENT) pose.setAttachment(tl.slot, this.doc.slots[tl.slot].setup);\n } else pose.setAttachment(tl.slot, tl.keys[index].name ?? null);\n }\n\n private applyColour(pose: Pose, tl: Extract<MixTimeline, { type: 'colour' }>, time: number, alpha: number, from: number): void {\n if (!pose.slotLive(tl.slot)) return;\n const slot = this.doc.slots[tl.slot];\n const s = pose.slots[tl.slot];\n const l = s.light;\n const d = s.dark;\n const sl = slot.color === undefined ? [1, 1, 1, 1] : (this.plant.colour ?? readColour)(slot.color);\n const sdFull = slot.dark === undefined ? null : readColour(slot.dark);\n const sd = sdFull === null ? [0, 0, 0] : [sdFull[0], sdFull[1], sdFull[2]];\n const clampLight = (): void => {\n for (let k = 0; k < 4; k++) l[k] = clamp01(l[k]);\n };\n const v = this.values(tl.keys, time);\n const channels = SLOT_COLOUR_TIMELINES[tl.kind].channels.length;\n switch (tl.kind) {\n case 'rgba': {\n if (v === null) {\n if (from === SETUP) for (let k = 0; k < 4; k++) l[k] = sl[k];\n else if (from === FIRST) {\n for (let k = 0; k < 4; k++) l[k] += (sl[k] - l[k]) * alpha;\n clampLight();\n }\n return;\n }\n if (alpha === 1) for (let k = 0; k < 4; k++) l[k] = v[k];\n else if (from === SETUP) for (let k = 0; k < 4; k++) l[k] = sl[k] + (v[k] - sl[k]) * alpha;\n else for (let k = 0; k < 4; k++) l[k] += (v[k] - l[k]) * alpha;\n clampLight();\n return;\n }\n case 'rgb': {\n if (v === null) {\n if (from === SETUP) for (let k = 0; k < 3; k++) l[k] = sl[k];\n else if (from === FIRST) for (let k = 0; k < 3; k++) l[k] += (sl[k] - l[k]) * alpha;\n return;\n }\n const rgb = [v[0], v[1], v[2]];\n if (alpha !== 1) for (let k = 0; k < 3; k++) rgb[k] = from === SETUP ? sl[k] + (rgb[k] - sl[k]) * alpha : l[k] + (rgb[k] - l[k]) * alpha;\n for (let k = 0; k < 3; k++) l[k] = clamp01(rgb[k]);\n return;\n }\n case 'alpha': {\n if (v === null) {\n if (from === SETUP) l[3] = sl[3];\n else if (from === FIRST) l[3] += (sl[3] - l[3]) * alpha;\n return;\n }\n let a = v[0];\n if (alpha !== 1) a = from === SETUP ? sl[3] + (a - sl[3]) * alpha : l[3] + (a - l[3]) * alpha;\n l[3] = clamp01(a);\n return;\n }\n case 'rgba2':\n case 'rgb2': {\n if (d === null) return;\n const withAlpha = tl.kind === 'rgba2';\n const lightN = withAlpha ? 4 : 3;\n if (v === null) {\n if (from === SETUP) {\n for (let k = 0; k < lightN; k++) l[k] = sl[k];\n for (let k = 0; k < 3; k++) d[k] = sd[k];\n } else if (from === FIRST) {\n for (let k = 0; k < lightN; k++) l[k] += (sl[k] - l[k]) * alpha;\n if (withAlpha) clampLight();\n for (let k = 0; k < 3; k++) d[k] += (sd[k] - d[k]) * alpha;\n }\n return;\n }\n const light = v.slice(0, lightN);\n const dark = v.slice(lightN, channels);\n if (withAlpha) {\n if (alpha === 1) for (let k = 0; k < 4; k++) l[k] = light[k];\n else if (from === SETUP) {\n for (let k = 0; k < 4; k++) l[k] = sl[k] + (light[k] - sl[k]) * alpha;\n for (let k = 0; k < 3; k++) dark[k] = sd[k] + (dark[k] - sd[k]) * alpha;\n } else {\n for (let k = 0; k < 4; k++) l[k] += (light[k] - l[k]) * alpha;\n for (let k = 0; k < 3; k++) dark[k] = d[k] + (dark[k] - d[k]) * alpha;\n }\n clampLight();\n } else {\n if (alpha !== 1) {\n for (let k = 0; k < 3; k++) {\n light[k] = from === SETUP ? sl[k] + (light[k] - sl[k]) * alpha : l[k] + (light[k] - l[k]) * alpha;\n dark[k] = from === SETUP ? sd[k] + (dark[k] - sd[k]) * alpha : d[k] + (dark[k] - d[k]) * alpha;\n }\n }\n for (let k = 0; k < 3; k++) l[k] = clamp01(light[k]);\n }\n for (let k = 0; k < 3; k++) d[k] = clamp01(dark[k]);\n return;\n }\n }\n }\n\n /** `DeformTimeline.apply`: every live slot showing the record the timeline keys, its deform array mixed. */\n private applyDeform(pose: Pose, tl: Extract<MixTimeline, { type: 'deform' }>, time: number, alpha: number, from: number, add: boolean): void {\n const keys = tl.timeline.deform;\n if (keys === null) return;\n pose.slots.forEach((s, k) => {\n if (!pose.slotLive(k)) return;\n const shown = pose.resolve(k, s.placeholder);\n if (!shown.vertex || shown.timeline !== tl.identity || shown.vertices === null) return;\n const vertices = shown.vertices;\n if (!s.seen.includes(tl.identity)) s.seen.push(tl.identity);\n const target = (this.plant.deform ?? deformAt)(vertices, keys, time);\n let mixFrom = from;\n if (s.deform === null) mixFrom = SETUP;\n if (target === null) {\n // `applyBeforeFirst`.\n if (mixFrom === SETUP) s.deform = null;\n else if (mixFrom === FIRST) {\n if (alpha === 1) {\n s.deform = null;\n return;\n }\n const current = s.deform as number[];\n if (!vertices.weighted) {\n const setup = setupArray(vertices);\n s.deform = current.map((c, i) => c + (setup[i] - c) * alpha);\n } else {\n const keep = 1 - alpha;\n s.deform = current.map((c) => c * keep);\n }\n }\n return;\n }\n // `applyToSlot`: added only over a deform already there — over none it is the setup pose's branch, additive or not.\n const fromSetup = mixFrom === SETUP;\n if (alpha === 1) {\n if (add && !fromSetup) {\n const current = s.deform as number[];\n if (!vertices.weighted) {\n const setup = setupArray(vertices);\n s.deform = current.map((c, i) => c + (target[i] - setup[i]));\n } else s.deform = current.map((c, i) => c + target[i]);\n } else s.deform = [...target];\n } else if (fromSetup) {\n if (!vertices.weighted) {\n const setup = setupArray(vertices);\n s.deform = target.map((v, i) => setup[i] + (v - setup[i]) * alpha);\n } else s.deform = target.map((v) => v * alpha);\n } else if (add) {\n const current = s.deform as number[];\n if (!vertices.weighted) {\n const setup = setupArray(vertices);\n s.deform = current.map((c, i) => c + (target[i] - setup[i]) * alpha);\n } else s.deform = current.map((c, i) => c + target[i] * alpha);\n } else {\n const current = s.deform as number[];\n s.deform = current.map((c, i) => c + (target[i] - c) * alpha);\n }\n });\n }\n}\n\n/** `CurveTimeline1.beforeFirstKey`. */\nfunction beforeFirstKey(from: number, alpha: number, current: number, setup: number): number {\n if (from === SETUP) return setup;\n if (from === FIRST) return current + (setup - current) * alpha;\n return current;\n}\n\n/** `CurveTimeline1.getScaleValue` past the first key, `value` the curve times the setup scale; added, its offset from the setup scale is added to the base. */\nfunction scaleValue(value: number, alpha: number, from: number, out: boolean, add: boolean, current: number, setup: number): number {\n if (alpha === 1 && !add) return value;\n let base = from === SETUP ? setup : current;\n if (add) return base + (value - setup) * alpha;\n if (out) return base + (Math.abs(value) * Math.sign(base) - base) * alpha;\n base = Math.abs(base) * Math.sign(value);\n return base + (value - base) * alpha;\n}\n\nfunction hasAny(anim: MixAnimation, ids: readonly string[]): boolean {\n for (const id of ids) if (anim.ids.has(id)) return true;\n return false;\n}\n\n// ---------------------------------------------------------------------------\n// the live tracks\n// ---------------------------------------------------------------------------\n\n/** A track index: a whole number at or above 0, or the call refused naming it. */\nfunction trackIndex(track: number, call: string): number {\n if (typeof track !== 'number' || !Number.isInteger(track) || track < 0) throw new CoreInputError(`the live tracks' ${call} names track ${String(track)}, not a whole number at or above 0`);\n return track;\n}\n\nfunction finiteAtOrAbove0(v: number, what: string, call: string): number {\n if (typeof v !== 'number' || !Number.isFinite(v) || v < 0) throw new CoreInputError(`the live tracks' ${call} ${what} is ${String(v)}, not a finite time at or above 0`);\n return v;\n}\n\nfunction loopOf(options: MixOptions | undefined, call: string): boolean {\n if (typeof options !== 'object' || options === null || typeof options.loop !== 'boolean') throw new CoreInputError(`the live tracks' ${call} options.loop is ${JSON.stringify((options as Partial<MixOptions> | null | undefined)?.loop)}, not true or false`);\n return options.loop;\n}\n\n/** An alpha: a finite number from 0 to 1, or the call refused naming it — the runtime clamps nothing and defines no weight outside it. */\nfunction alphaValue(v: unknown, what: string, call: string): number {\n if (typeof v !== 'number' || !Number.isFinite(v) || v < 0 || v > 1) throw new CoreInputError(`the live tracks' ${call} ${what} is ${typeof v === 'number' ? String(v) : JSON.stringify(v)}, not a number from 0 to 1`);\n return v;\n}\n\n/** `options.alpha` and `options.additive`: 1 and `false` when absent, else refused by name where they are not a weight and a boolean. */\nfunction blendOf(options: MixOptions, call: string): { alpha: number; additive: boolean } {\n const alpha = options.alpha === undefined ? 1 : alphaValue(options.alpha, 'options.alpha', call);\n const additive: unknown = options.additive;\n if (additive !== undefined && typeof additive !== 'boolean') throw new CoreInputError(`the live tracks' ${call} options.additive is ${JSON.stringify(additive)}, not true or false — an entry adds or it does not`);\n return { alpha, additive: additive === true };\n}\n\nfunction delayOf(v: number, call: string): number {\n if (typeof v !== 'number' || !Number.isFinite(v)) throw new CoreInputError(`the live tracks' ${call} delay is ${String(v)}, not a finite number`);\n return v;\n}\n\n/**\n * The live tracks over `doc` (the header): refused by name where a walk on the\n * document would be, then animations set, queued and mixed out on any track,\n * pose 0 posed by `start()` and one pose per `step`.\n */\nexport function openTracks(doc: CompiledDocument, options: TracksOptions, plant: TracksPlant = {}): LiveTracks {\n if (typeof options !== 'object' || options === null || (options.reset !== 'animation' && options.reset !== 'setup')) throw new CoreInputError(`the live tracks' options.reset is ${JSON.stringify((options as Partial<TracksOptions> | null)?.reset)}, not \"animation\" or \"setup\"`);\n if (options.adjust !== undefined && typeof options.adjust !== 'function') throw new CoreInputError(`the live tracks' options.adjust is ${typeof options.adjust}, not a function`);\n return new Tracks(doc, options.reset, options.adjust, plant, openRawTracksPath(doc, plant));\n}\n\nclass Tracks implements LiveTracks {\n private readonly mixer: Mixer;\n private started = false;\n private steps = 0;\n private time = 0;\n private refused: string | null = null;\n\n constructor(\n private readonly doc: CompiledDocument,\n private readonly reset: RawReset,\n private readonly adjust: LocalAdjust | undefined,\n private readonly plant: TracksPlant,\n private readonly path: RawTracksPath,\n ) {\n this.mixer = new Mixer(doc, plant);\n }\n\n get trackTime(): number {\n return this.time;\n }\n\n private live(call: string): void {\n if (this.refused !== null) throw new CoreInputError(`the live tracks were refused at ${this.refused}, after their entries and physics had moved; open them again (${call} not made)`);\n }\n\n setAnimation(track: number, animation: string, options: MixOptions): void {\n this.live('setAnimation');\n const i = trackIndex(track, 'setAnimation');\n const loop = loopOf(options, 'setAnimation');\n const mix = finiteAtOrAbove0(options.mixDuration, 'mixDuration', 'setAnimation');\n const blend = blendOf(options, 'setAnimation');\n const entry = this.mixer.setAnimation(i, this.mixer.animation(animation), loop);\n entry.mixDuration = mix;\n entry.alpha = blend.alpha;\n entry.additive = blend.additive;\n }\n\n setEmptyAnimation(track: number, mixDuration: number): void {\n this.live('setEmptyAnimation');\n const i = trackIndex(track, 'setEmptyAnimation');\n const mix = finiteAtOrAbove0(mixDuration, 'mixDuration', 'setEmptyAnimation');\n const entry = this.mixer.setAnimation(i, EMPTY, false);\n entry.mixDuration = mix;\n entry.trackEnd = mix;\n }\n\n addAnimation(track: number, animation: string, options: QueueOptions): void {\n this.live('addAnimation');\n const i = trackIndex(track, 'addAnimation');\n const loop = loopOf(options, 'addAnimation');\n const mix = finiteAtOrAbove0(options.mixDuration, 'mixDuration', 'addAnimation');\n const delay = delayOf(options.delay, 'addAnimation');\n const blend = blendOf(options, 'addAnimation');\n const entry = this.mixer.addAnimation(i, this.mixer.animation(animation), loop, delay);\n this.mixer.setMixDuration(entry, mix, delay);\n entry.alpha = blend.alpha;\n entry.additive = blend.additive;\n }\n\n addEmptyAnimation(track: number, mixDuration: number, delay: number): void {\n this.live('addEmptyAnimation');\n const i = trackIndex(track, 'addEmptyAnimation');\n const mix = finiteAtOrAbove0(mixDuration, 'mixDuration', 'addEmptyAnimation');\n const d = delayOf(delay, 'addEmptyAnimation');\n const entry = this.mixer.addAnimation(i, EMPTY, false, d);\n if (d <= 0) entry.delay = Math.max(entry.delay + entry.mixDuration - mix, 0);\n entry.mixDuration = mix;\n entry.trackEnd = mix;\n }\n\n setAlpha(track: number, alpha: number): void {\n this.live('setAlpha');\n const i = trackIndex(track, 'setAlpha');\n const a = alphaValue(alpha, 'alpha', 'setAlpha');\n const e = this.mixer.tracks[i] ?? null;\n if (e === null) throw new CoreInputError(`the live tracks' setAlpha names track ${i}, which plays nothing — there is no entry to weigh`);\n e.alpha = a;\n }\n\n current(track: number): TrackEntryView | null {\n const e = this.mixer.tracks[trackIndex(track, 'current')] ?? null;\n if (e === null) return null;\n return { animation: e.anim.name, loop: e.loop, trackTime: e.trackTime, animationTime: animationTimeOf(e), duration: e.anim.duration, alpha: e.alpha, additive: e.additive };\n }\n\n start(): RawPose {\n this.live('start');\n if (this.started) throw new CoreInputError('the live tracks were started already; pose 0 is posed once');\n this.started = true;\n return this.guard('start', () => {\n if (this.reset === 'setup') return this.path.setupPose();\n return this.pose(0, true);\n });\n }\n\n step(dt: number): RawPose {\n const n = this.steps + 1;\n this.live(`step ${n}`);\n if (!this.started) throw new CoreInputError(`the live tracks' step ${n} comes before start(), which poses pose 0`);\n if (typeof dt !== 'number' || !Number.isFinite(dt) || dt < 0) throw new CoreInputError(`the live tracks' step ${n} is ${String(dt)}, not a finite time at or above 0`);\n return this.guard(`step ${n}`, () => {\n this.time += dt;\n this.mixer.update(dt);\n const pose = this.pose(dt, false);\n this.steps = n;\n return pose;\n });\n }\n\n /** `f`, the state refused for good if it throws once anything has moved. */\n private guard(call: string, f: () => RawPose): RawPose {\n try {\n return f();\n } catch (err) {\n this.refused = `${call} (${err instanceof Error ? err.message : String(err)})`;\n throw err;\n }\n }\n\n /** One pose: the entries applied over the setup pose, then the raw pose path (`openRawTracksPath`). */\n private pose(dt: number, first: boolean): RawPose {\n const { doc, path } = this;\n const ctx = path.ctx;\n const before = ctx.time;\n ctx.time += dt;\n const pose = new Pose(doc, this.plant);\n const animationTime = this.mixer.apply(pose);\n const mixed = new Map(doc.slots.map((s, k) => [s.name, { deform: pose.slots[k].deform, seen: pose.slots[k].seen }]));\n return path.step(first, this.time, animationTime, {\n world: (sliders) => steppedLocalsWorld(doc, pose.bones, path.raw, sliders, { ctx, before, adjust: this.adjust }, true),\n slots: (sliders, placeholders) => slotRowsFrom(doc, path.raw, sliders, placeholders, (_slot, _live): SlotBase => {\n const s = pose.slots[doc.slots.indexOf(_slot)];\n return { placeholder: s.placeholder, light: s.light, dark: s.dark };\n }),\n drawOrder: [],\n at: 0,\n sample: null,\n mixed,\n events: () => pose.events,\n });\n }\n}\n","/**\n * The draw's last input the core lacked (issue #967, step 3c of issue #380):\n * each drawn attachment's atlas PAGE and its PAGE UVs — the oracle's `uvs`\n * block, what `src/render.ts`'s `pieceOf` reads off `sequence.regions[index]`\n * and `sequence.getUVs(index)` — and `MeshAttachment.computeUVs`'s job, the\n * mapping texture substitution calls, as pure functions.\n *\n * The page layout is not a model record (`ModelAtlasRect`'s 🔸 in\n * `src/model.ts`: the page, `x`, `y` and `rotate` are the packer's\n * arrangement, not the drawing). It reaches these rules as a lookup\n * (`UvLookup`), so nothing here links the runtime or opens a file: since\n * issue #1016 from the document's own `pages` section, which `build` spells\n * from the atlas it writes (`documentPageLookup` below); for a\n * `rigc-compiled/1` document, which has none, from the atlas beside it, read\n * by rigc's own reader (`parseAtlasText` and `atlasRegionLookup` in\n * `src/atlas.ts`).\n *\n * ## How every rule below was fixed\n *\n * By loading hand-written atlases and skeletons through spine-core 4.3.13\n * (`TextureAtlas`, `AtlasAttachmentLoader`, `SkeletonJson`) and reading what\n * the loaded attachments hold — `sequence.getUVs(i)`, `sequence.regions[i]`,\n * `region.page.name` — and what `MeshAttachment.computeUVs` writes, then\n * comparing a formula over the atlas's own numbers, bit for bit (not on the\n * oracle's grid). The runtime's source was not read. Regions were random:\n * pages of power-of-two and other sizes, one to three pages, `bounds` anywhere\n * on the page, 70% trimmed (`offsets` other than `0, 0, width, height`), and\n * `rotate` spelled `0`, `90`, `180`, `270`, `true`, `false` and, for the\n * branch rules, `45`, `-90`, `360` and `450`; mesh and art UVs spelled with\n * five non-float32 decimals, some outside `[0, 1]`.\n *\n * ### The region's own numbers\n *\n * With `W, H` the page's `size`, the region's `u = x/W`, `v = y/H`, and its far\n * corner `u2 = (x + width)/W`, `v2 = (y + height)/H` — with `width` and\n * `height` exchanged at `rotate: 90` (and `true`) ONLY. 1,500 of 1,500\n * regions, as doubles; exchanged at 270 as well missed 262, never exchanged\n * 484. (That 270 is not exchanged is the runtime's, and the reason\n * `pageFootprint` in `src/atlas.ts` derives the page rectangle rather than\n * reading these two numbers.)\n *\n * ### A region attachment's four UVs\n *\n * In the corner order of its world vertices (bottom-left, upper-left,\n * upper-right, bottom-right — `./vertices.ts`): at `degrees === 90`\n * `(u2, v2) (u, v2) (u, v) (u2, v)`, at every other value — 0, 180, 270 and\n * the odd spellings alike — `(u, v2) (u, v) (u2, v) (u2, v2)`; each held as\n * float32. 1,500 of 1,500 through `Math.fround`; as doubles, 575 missed. The\n * readings rejected, on the same 1,500:\n *\n * | reading | misses |\n * | --- | ---: |\n * | 270 turned as 90 over a transposed rectangle | 262 |\n * | 90's corners the other way round, `(u, v) (u2, v) (u2, v2) (u, v2)` | 487 |\n * | 180 turned, `(u2, v) (u2, v2) (u, v2) (u, v)` | 260 |\n * | the trim inset into the UVs | 724 |\n *\n * The trim does not enter a region's UVs: it enters its corners\n * (`regionCorners` in `./vertices.ts`, through `ModelAtlasRect`).\n *\n * ### A mesh's page UVs — `MeshAttachment.computeUVs`\n *\n * From the attachment's own UVs `(s, t)` — art space, over the untrimmed\n * drawing — per `degrees`, in doubles, starting from `u = x/W`, `v = y/H`:\n *\n * | degrees | `u −=` | `v −=` | span `w, h` | `(u′, v′)` |\n * | --- | --- | --- | --- | --- |\n * | 90 | `(oh − oy − height)/W` | `(ow − ox − width)/H` | `oh/W, ow/H` | `u + t·w, v + (1 − s)·h` |\n * | 180 | `(ow − ox − width)/W` | `oy/H` | `ow/W, oh/H` | `u + (1 − s)·w, v + (1 − t)·h` |\n * | 270 | `oy/W` | `ox/H` | `oh/W, ow/H` | `u + (1 − t)·w, v + s·h` |\n * | any other | `ox/W` | `(oh − oy − height)/H` | `ow/W, oh/H` | `u + s·w, v + t·h` |\n *\n * (`ox, oy, ow, oh` the region's `offsetX, offsetY, originalWidth,\n * originalHeight`; `width, height` its `bounds` size.) The subtraction is its\n * own step: called into a plain array, the rule read 6,000 of 6,000 calls bit\n * for bit in doubles, while one fraction `(x − ox)/W` missed 936 and texels\n * first, `(x − ox + s·ow)/W`, 2,227. Into a plain array the function writes\n * these doubles — 4,000 of 4,000 calls wrote a value that is not a float32 —\n * and what an attachment HOLDS is each through `Math.fround`, because its\n * array is a `Float32Array`: 1,500 of 1,500 meshes, and `computeUVs` over the\n * attachment's region and own UVs reproduced the held array on all 1,500. The\n * rule through `Math.fround` held on 4,000 direct calls into a `Float32Array`,\n * 400 per spelling, the odd spellings taking the last row.\n *\n * ⚠️ **The mesh's own UVs are read as the doubles the text spells, not as\n * float32.** Reading them through `Math.fround` first missed 311 of 1,500\n * meshes (worst 4.8e-7, one float32 step of a UV near 1); every intermediate\n * in float32 missed 844. So `computeUvs` takes the model's `uvs` as they are.\n *\n * ### Which region, on which page\n *\n * - A region or mesh draws the atlas region named by its `path`, else its\n * name — the oracle's `path` cell (`shownRow` in `./index.ts`). The first\n * region of that name in the file wins (two regions named alike, the first\n * drawn), and the name is compared as the atlas line spells it: a region\n * line `art ` is not found as `art`, while CRLF line ends are not part of a\n * name (`parseAtlasText` splits on them).\n * - A **sequence**'s frame `i` draws `path + (start + i)`, the number padded\n * with zeros to `digits` (`padStart`): `start` 1 and `digits` 0 when\n * unstated — a three-frame `x` drew `x1, x2, x3`; `start 8, digits 0` drew\n * `x8, x9, x10`; `start 99, digits 1` `x99, x100`; `start 5, digits 4`\n * `x0005, x0006`. The atlas's own `index:` field is not how a frame is\n * found: regions named `seq` with `index: 1` and `2` loaded as `Region not\n * found in atlas: seq1`. Each frame draws on its own region's page: a\n * four-frame series over two pages drew frames 0–1 on the first and 2–3 on\n * the second, a mesh's frames alike.\n * - The frame drawn is the one the pose shows (`./deform.ts`'s sequence rule,\n * measured there through a region's corners), or the sequence's `setup` (0\n * unstated) where no timeline set one.\n * - A **linked mesh** draws its OWN `path`'s region (and its own sequence's\n * frames — a link stating one drew `l1, l2, l3` from setup frame 2 whatever\n * its source stated; a link stating none drew its own path) over its\n * SOURCE's UVs: a link on page `a.png` whose source sat on `b.png` drew\n * `a.png`, and its uvs were `computeUVs` of its own region over the\n * source's `regionUVs`.\n * - The page cell is the page's name as `parseAtlasText` trims it — the\n * runtime's `page.name` for a page line ` p.png ` read `p.png`.\n *\n * ## What is posed, and what is left out\n *\n * Rows in the pose's draw order, one per slot showing a region, a mesh or a\n * linked mesh — the slots the `attachments` block lists, whatever their bone\n * or alpha. Which record a slot shows and the frame its series is at are the\n * ones `./deform.ts`'s `attachmentStates` computes for the same pose, from the\n * placeholders the sample's own timelines leave (`posedSlots`) and the\n * sliders' applications (`posedBoneWorld`); at setup, from the setup\n * placeholders and the sliders applied to the setup pose. That repeats the\n * walk `poseSetup` and `poseAnimations` make, because neither returns the\n * frame (issue #966 retains it in the raw entry); the gate holds the two\n * walks to one answer by comparing both against the runtime.\n *\n * A region the atlas does not have is refused by name (`CoreInputError`):\n * spine-core refuses to load the same pair. The block is left out, with the\n * reason, where what a slot shows is not posed — the slots or the draw order\n * absent — and where a linked mesh stating its own sequence is stepped by a\n * sequence timeline counted over its source's frames, a case never measured.\n *\n * ## Purity\n *\n * As the rest of the core: nothing from the Spine runtime package, nothing\n * from `src/transform.ts`, no clock, no randomness, no I/O.\n */\nimport { activeBones, constraintRecords, CoreInputError, shownAttachment, type CompiledDocument, type CoreAnimation } from './index.ts';\nimport { posedBoneWorld, posedSlots } from './animation.ts';\nimport { applyConstraints } from './constraints.ts';\nimport type { SliderApplication } from './constraints_slider.ts';\nimport { attachmentStates } from './deform.ts';\nimport type { ShownGeometry } from './vertices.ts';\nimport type { ModelPage, ModelPageRegion } from '../model.ts';\nimport { worldTransforms } from './world.ts';\n\n/** A region as these rules read it — `AtlasRegion` in `src/atlas.ts` is one, and so is spine-core's `TextureAtlasRegion`. */\nexport interface UvRegion {\n x: number;\n y: number;\n width: number;\n height: number;\n offsetX: number;\n offsetY: number;\n originalWidth: number;\n originalHeight: number;\n degrees: number;\n}\n\n/** A page as these rules read it: its trimmed name and its `size`. */\nexport interface UvPage {\n name: string;\n width: number;\n height: number;\n}\n\n/** The region an atlas draws under a name, and its page — the first of that name, as the header states; `null` when there is none. */\nexport type UvLookup = (name: string) => { page: UvPage; region: UvRegion } | null;\n\n/**\n * The lookup over a document's `pages` section (issue #1016): the first region\n * of a name in file order, pages in order and regions in each page's order —\n * the order `pagesOfAtlas` in `src/model.ts` copies from the atlas, so this is\n * `atlasRegionLookup` over the same text, with no atlas read. The name is\n * compared as stored, untrimmed, as the header's *Which region* states.\n */\nexport function documentPageLookup(pages: readonly ModelPage[]): (name: string) => { page: UvPage; region: ModelPageRegion } | null {\n const first = new Map<string, { page: UvPage; region: ModelPageRegion }>();\n for (const page of pages) {\n const at: UvPage = { name: page.name, width: page.width, height: page.height };\n for (const region of page.regions) if (!first.has(region.name)) first.set(region.name, { page: at, region });\n }\n return (name) => first.get(name) ?? null;\n}\n\n/**\n * The readings the header's tables rejected, each a switch — what the core\n * suite's `CU` plants pass to show the gate names it. The functions below with\n * none set are the rules measured; nothing but a plant sets one.\n */\nexport interface UvReading {\n /** A region at 90 in the other corner order, `(u, v) (u2, v) (u2, v2) (u, v2)` — the rotation flipped. */\n rotationFlipped?: boolean;\n /** A region at 270 turned as one at 90, over a transposed rectangle; a mesh at 270 mapped by 90's `(u + t·w, v + (1 − s)·h)`. */\n turned270?: boolean;\n /** A mesh's page UVs with the trim offsets dropped (`ox = oy = 0`, the original size the kept one). */\n trimDropped?: boolean;\n /** A mesh's own UVs read through `Math.fround` first. */\n artAsFloat32?: boolean;\n}\n\n/** A region attachment's four page UVs as the runtime holds them — the header's rule, in the world corners' order. */\nexport function regionPageUvs(region: UvRegion, page: UvPage, reading: UvReading = {}): number[] {\n const turned = region.degrees === 90 || (reading.turned270 === true && region.degrees === 270);\n const u = region.x / page.width;\n const v = region.y / page.height;\n const u2 = (region.x + (turned ? region.height : region.width)) / page.width;\n const v2 = (region.y + (turned ? region.width : region.height)) / page.height;\n let out: number[];\n if (turned) out = reading.rotationFlipped === true ? [u, v, u2, v, u2, v2, u, v2] : [u2, v2, u, v2, u, v, u2, v];\n else out = [u, v2, u, v, u2, v, u2, v2];\n return out.map(Math.fround);\n}\n\n/**\n * `MeshAttachment.computeUVs`: art-space UVs over the untrimmed drawing mapped\n * onto `region` of `page`, in doubles — the header's table. What texture\n * substitution writes into its plain array; an attachment holds each value\n * through `Math.fround` (`meshPageUvs`).\n */\nexport function computeUvs(region: UvRegion, page: UvPage, art: readonly number[], reading: UvReading = {}): number[] {\n const dropped = reading.trimDropped === true;\n const ox = dropped ? 0 : region.offsetX;\n const oy = dropped ? 0 : region.offsetY;\n const ow = dropped ? region.width : region.originalWidth;\n const oh = dropped ? region.height : region.originalHeight;\n const W = page.width;\n const H = page.height;\n const s = reading.artAsFloat32 === true ? art.map(Math.fround) : art;\n let u = region.x / W;\n let v = region.y / H;\n const out: number[] = [];\n switch (region.degrees) {\n case 90: {\n u -= (oh - oy - region.height) / W;\n v -= (ow - ox - region.width) / H;\n const w = oh / W;\n const h = ow / H;\n for (let i = 0; i + 1 < s.length; i += 2) out.push(u + s[i + 1] * w, v + (1 - s[i]) * h);\n return out;\n }\n case 180: {\n u -= (ow - ox - region.width) / W;\n v -= oy / H;\n const w = ow / W;\n const h = oh / H;\n for (let i = 0; i + 1 < s.length; i += 2) out.push(u + (1 - s[i]) * w, v + (1 - s[i + 1]) * h);\n return out;\n }\n case 270: {\n u -= oy / W;\n v -= ox / H;\n const w = oh / W;\n const h = ow / H;\n if (reading.turned270 === true) for (let i = 0; i + 1 < s.length; i += 2) out.push(u + s[i + 1] * w, v + (1 - s[i]) * h);\n else for (let i = 0; i + 1 < s.length; i += 2) out.push(u + (1 - s[i + 1]) * w, v + s[i] * h);\n return out;\n }\n default: {\n u -= ox / W;\n v -= (oh - oy - region.height) / H;\n const w = ow / W;\n const h = oh / H;\n for (let i = 0; i + 1 < s.length; i += 2) out.push(u + s[i] * w, v + s[i + 1] * h);\n return out;\n }\n }\n}\n\n/** A mesh's page UVs as the attachment holds them: `computeUvs`, each through `Math.fround`. */\nexport function meshPageUvs(region: UvRegion, page: UvPage, art: readonly number[], reading: UvReading = {}): number[] {\n return computeUvs(region, page, art, reading).map(Math.fround);\n}\n\n/** A record's series, as the parser reads the four fields: `start` 1, `digits` 0 and `setup` 0 when unstated. */\nexport interface UvSequence {\n count: number;\n start: number;\n digits: number;\n setup: number;\n}\n\n/** Every record's series, by `skin/slot/placeholder` — `readUvSequences`. */\nexport type UvSequences = ReadonlyMap<string, UvSequence>;\n\n/** The region a series' frame draws: `path + (start + frame)`, padded with zeros to `digits` — the header's rule. */\nexport function frameRegionName(path: string, sequence: UvSequence, frame: number): string {\n return path + String(sequence.start + frame).padStart(sequence.digits, '0');\n}\n\nconst isRecord = (v: unknown): v is Record<string, unknown> => typeof v === 'object' && v !== null && !Array.isArray(v);\nconst whole = (v: unknown, min: number): v is number => typeof v === 'number' && Number.isInteger(v) && v >= min;\n\n/**\n * Every record's `sequence` in a `rigc-compiled/1` document, as the parser\n * reads it — `readModel` keeps a series' count and nothing else of it, and a\n * frame's region name needs `start` and `digits`. Refuses, naming the path, a\n * field that is not a whole number (`count` of at least 1, the others of at\n * least 0) or a `setup` that is not one of the frames.\n */\nexport function readUvSequences(document: unknown): UvSequences {\n const out = new Map<string, UvSequence>();\n const problems: string[] = [];\n const skins = isRecord(document) && Array.isArray(document.skins) ? document.skins : [];\n skins.forEach((skin: unknown, k: number) => {\n if (!isRecord(skin) || typeof skin.name !== 'string' || !isRecord(skin.attachments)) return;\n for (const [slot, table] of Object.entries(skin.attachments)) {\n if (!isRecord(table)) continue;\n for (const [placeholder, record] of Object.entries(table)) {\n if (!isRecord(record) || record.sequence === undefined) continue;\n const where = `skins[${k}] \"${skin.name}\".attachments[\"${slot}\"][\"${placeholder}\"].sequence`;\n const seq = record.sequence;\n if (!isRecord(seq)) {\n problems.push(`${where} is not an object`);\n continue;\n }\n const before = problems.length;\n if (!whole(seq.count, 1)) problems.push(`${where}: count is ${JSON.stringify(seq.count) ?? 'absent'}, not a whole number of at least 1`);\n for (const key of ['start', 'digits', 'setup'] as const) if (seq[key] !== undefined && !whole(seq[key], 0)) problems.push(`${where}: ${key} is ${JSON.stringify(seq[key])}, not a whole number of at least 0`);\n if (problems.length !== before) continue;\n const count = seq.count as number;\n const setup = (seq.setup as number | undefined) ?? 0;\n if (setup >= count) {\n problems.push(`${where}: setup is ${setup}, and a ${count}-frame series has frames 0 to ${count - 1}`);\n continue;\n }\n out.set(`${skin.name}/${slot}/${placeholder}`, { count, start: (seq.start as number | undefined) ?? 1, digits: (seq.digits as number | undefined) ?? 0, setup });\n }\n }\n });\n if (problems.length > 0) throw new CoreInputError(`the model document's sequences: ${problems.join('; ')}`);\n return out;\n}\n\n/** What `poseUvs` reads besides the pose: the atlas lookup, the document's series, and a plant's reading. */\nexport interface UvSource {\n lookup: UvLookup;\n sequences: UvSequences;\n reading?: UvReading;\n}\n\n/** One row of `uvs`: `[slot, attachment, page, uvs]`, the oracle's row. */\nexport type CoreUvRow = [string, string, string, Array<number | null>];\n\n/**\n * Each slot's shown record and its series' frame at the setup pose — what\n * `poseSetup` hands `poseGeometry`: the setup placeholders, and the sliders\n * applied to the setup bones (`applyConstraints`), each slider's attachment,\n * deform and sequence keys applied in order by `attachmentStates`.\n */\nexport function shownAtSetup(doc: CompiledDocument): { shown: ShownGeometry[]; why: string[] } {\n const active = activeBones(doc);\n const applied: SliderApplication[] = [];\n applyConstraints(doc.bones, worldTransforms(doc.bones, active), active, constraintRecords(doc), null, applied);\n const placeholders = new Map(doc.slots.map((s) => [s.name, s.setup]));\n return attachmentStates(doc, shownAttachment, placeholders, null, applied);\n}\n\n/**\n * Each slot's shown record and its series' frame at time `t` of `anim` — what\n * `poseAnimations` hands `poseGeometry` under `--physics none`: the sliders\n * `posedBoneWorld` applies at `t`, the placeholders the sample's own\n * timelines leave (`posedSlots`), then `attachmentStates`.\n */\nexport function shownAtSample(doc: CompiledDocument, anim: CoreAnimation, t: number): { shown: ShownGeometry[]; why: string[] } {\n const sliders: SliderApplication[] = [];\n // The bones are posed for what the sliders apply, and only a slider constraint applies one (`applySlider`): with none, the list stays empty and the pose would be read for nothing (issue #1134).\n if (doc.constraints.some((c) => c.kind === 'slider')) posedBoneWorld(doc, anim.timelines, t, {}, anim.constraints, sliders);\n const placeholders = new Map<string, string | null>();\n posedSlots(doc, anim.timelines, t, {}, sliders, placeholders);\n return attachmentStates(doc, shownAttachment, placeholders, { timelines: anim.timelines, t }, sliders);\n}\n\n/** One drawn attachment resolved to its atlas region: what `poseUvs` maps, and what a census reads. */\nexport interface DrawnRegion {\n slot: string;\n /** The attachment's name — the row's second cell. */\n name: string;\n kind: 'region' | 'mesh' | 'linkedmesh';\n /** The region name drawn: the path, with the frame's number for a series. */\n region: string;\n /** The series' frame drawn, or `null` for a record with no series. */\n frame: number | null;\n found: { page: UvPage; region: UvRegion };\n /** The attachment's own UVs for a mesh — a linked mesh's source's — or `null` for a region. */\n art: readonly number[] | null;\n}\n\n/**\n * Every slot of `order` showing a region, a mesh or a linked mesh, resolved to\n * the atlas region it draws — the header's *Which region, on which page* — or\n * why the pose is not posed. A region the atlas lacks is refused by name.\n */\nexport function drawnRegions(doc: CompiledDocument, shown: readonly ShownGeometry[], order: readonly string[], source: UvSource): { drawn: DrawnRegion[] | null; why: string | null } {\n const bySlot = new Map(shown.map((s) => [s.slot, s]));\n const drawn: DrawnRegion[] = [];\n const unmeasured: string[] = [];\n for (const slot of order) {\n const s = bySlot.get(slot);\n if (s === undefined) continue;\n const g = s.geometry;\n if (g.kind !== 'region' && g.kind !== 'mesh' && g.kind !== 'linkedmesh') continue;\n const record = doc.skins.find((k) => k.name === s.skin)?.attachments[s.slot]?.[s.placeholder];\n if (record === undefined) throw new CoreInputError(`slot \"${s.slot}\": skin \"${s.skin}\" files no record under placeholder \"${s.placeholder}\" (readModel refuses it first)`);\n const path = record.path ?? s.name;\n const sequence = source.sequences.get(`${s.skin}/${s.slot}/${s.placeholder}`);\n if (g.kind === 'linkedmesh' && sequence !== undefined && s.frame !== undefined) {\n const sourceCount = doc.skins.find((k) => k.name === g.skin)?.attachments[g.slot]?.[g.source]?.sequenceCount;\n if (sourceCount !== sequence.count) {\n unmeasured.push(`slot \"${s.slot}\" shows linked mesh \"${s.name}\", whose own ${sequence.count}-frame series a sequence timeline steps over its source's ${sourceCount ?? 'unstated'} frame(s)`);\n continue;\n }\n }\n const frame = sequence === undefined ? null : (s.frame ?? sequence.setup);\n const name = sequence === undefined || frame === null ? path : frameRegionName(path, sequence, frame);\n const found = source.lookup(name);\n if (found === null) {\n throw new CoreInputError(\n `slot \"${s.slot}\" shows \"${s.name}\", which draws atlas region \"${name}\"${frame === null ? '' : ` (frame ${frame} of its series over \"${path}\")`}, and the atlas has no region of that name — spine-core refuses to load the pair (\"Region not found in atlas\")`,\n );\n }\n let art: readonly number[] | null = null;\n if (g.kind === 'mesh') art = g.uvs;\n else if (g.kind === 'linkedmesh') {\n // A linked mesh draws its source's UVs over its own region (the header's *Which region*).\n const from = doc.skins.find((k) => k.name === g.skin)?.attachments[g.slot]?.[g.source]?.geometry;\n if (from?.kind !== 'mesh') throw new CoreInputError(`slot \"${s.slot}\": the linked mesh's source \"${g.source}\" carries no uvs (readModel refuses it first)`);\n art = from.uvs;\n }\n drawn.push({ slot: s.slot, name: s.name, kind: g.kind, region: name, frame, found, art });\n }\n if (unmeasured.length > 0) return { drawn: null, why: `${unmeasured.join('; ')} — which of the two counts the runtime steps it over was not measured` };\n return { drawn, why: null };\n}\n\n/**\n * The `uvs` rows of one pose: `shown` (from `shownAtSetup`/`shownAtSample`) in\n * `order`, the pose's draw order, every number through `round` (the oracle's,\n * `gridRound`) — or why the block is left out. A region the atlas lacks is\n * refused by name.\n */\nexport function poseUvs(doc: CompiledDocument, shown: readonly ShownGeometry[], order: readonly string[], source: UvSource, round: (v: number) => number | null): { rows: CoreUvRow[] | null; why: string | null } {\n const reading = source.reading ?? {};\n const { drawn, why } = drawnRegions(doc, shown, order, source);\n if (drawn === null) return { rows: null, why };\n const rows = drawn.map((d): CoreUvRow => {\n const uvs = d.art === null ? regionPageUvs(d.found.region, d.found.page, reading) : meshPageUvs(d.found.region, d.found.page, d.art, reading);\n return [d.slot, d.name, d.found.page.name, uvs.map(round)];\n });\n return { rows, why: null };\n}\n\n/** Why a document's `uvs` blocks are not posed under the stepped phase, or null: a slider keying a slot's attachment or a series — its time is read off bones the step moves, and this walk poses them unstepped. */\nexport function steppedUvsWhy(doc: CompiledDocument): string | null {\n const keyed = doc.constraints.flatMap((c) => {\n if (c.kind !== 'slider') return [];\n const anim = doc.animations.find((a) => a.name === c.animation);\n if (anim === undefined) return [];\n const switches = anim.timelines.slots.some((sl) => sl.timelines.some((tl) => tl.kind === 'attachment'));\n const frames = anim.timelines.attachments.some((a) => a.sequence !== null);\n return switches || frames ? [`slider \"${c.name}\" applies animation \"${c.animation}\", which keys ${switches ? 'a slot\\'s attachment' : 'a sequence'}`] : [];\n });\n return keyed.length === 0 ? null : `${keyed.join('; ')} — under --physics step its time is read off stepped bones, and the uvs walk poses the sliders unstepped`;\n}\n","/**\n * Where one region sits on its page — the fields of a model document's\n * `pages[].regions[]` entry (`ModelPageRegion` in rig-c) that a cut reads.\n * `width` and `height` are the artwork's own, unrotated: a region packed at\n * `degrees: 90` occupies a `height × width` rect on the page.\n */\nexport interface PageRegion {\n name: string;\n x: number;\n y: number;\n width: number;\n height: number;\n degrees: number;\n}\n\n/**\n * One page of the layout `unpackRegions` cuts from — a model document's\n * `pages[]` entry. `width`/`height` are the page's *declared* size (the atlas\n * `size:` line the build wrote), not necessarily the image's.\n */\nexport interface PageLayout {\n name: string;\n width: number;\n height: number;\n /** Whether the page's texels are premultiplied by their alpha (absent: false). */\n pma?: boolean;\n regions: readonly PageRegion[];\n}\n\n/** One region with its page, in the order the layout lists them. */\ninterface PlacedRegion {\n region: PageRegion;\n page: PageLayout;\n}\n\nexport interface RegionImage {\n /**\n * URL of the unpacked (rotation-restored) region pixels: a blob URL minted\n * by unpackRegions, the page image URL itself when the region covers its\n * whole page, or anything the caller put there in a hand-built map.\n */\n url: string;\n /**\n * Unpacked width in **atlas units** — the region's own `width`, not the\n * bitmap's pixel width. The two differ whenever the page image ships at a\n * resolution its atlas `size:` line does not mention (see cutRegion): a\n * half-resolution page yields a bitmap half this wide. This is the layout\n * box the rigid tier writes onto its `<img>` and the denominator of the CSS\n * matrix it builds, so it stays in the frame the skeleton is authored in\n * and the browser scales the bitmap into it — the same thing a GPU does\n * when it samples normalized UVs from a texture of any resolution.\n */\n width: number;\n /** Unpacked height in atlas units — see `width`. */\n height: number;\n}\n\n/**\n * Blob URLs minted by unpackRegions, i.e. the ones this module owns.\n *\n * Ownership has to be tracked because a RegionImage map is not necessarily\n * ours: callers may hand the renderer a map built from their own URLs (loose\n * part PNGs need no unpacking at all). revokeRegions() therefore frees only\n * what is listed here and leaves caller-owned URLs untouched.\n */\nconst ownedUrls = new Set<string>();\n\n/** Revokes `url` if unpackRegions minted it. Idempotent, caller-safe. */\nfunction revokeOwned(url: string): void {\n if (!ownedUrls.delete(url)) return;\n URL.revokeObjectURL(url);\n}\n\n/**\n * Page pixels in the alpha convention a DOM/canvas2d consumer needs: the page\n * image itself, or the derived canvas below when the page is premultiplied.\n */\nexport type PageSource = HTMLImageElement | HTMLCanvasElement;\n\n/**\n * Straight-alpha derivations of `pma: true` page images, one per image.\n *\n * Spine's texture packer premultiplies by default, and an atlas says so with a\n * `pma: true` page line: the file's RGB is already multiplied by its alpha. The\n * DOM and canvas 2D have no such mode — an <img> and `drawImage` composite\n * straight alpha by definition, so they multiply by alpha again and every\n * semi-transparent texel comes out darker than it was authored (#37). Both\n * consumers of that convention here — the region cuts below and the canvas2d\n * mesh raster in DomRenderer — therefore read this derivation instead of\n * the page, and it is *shared*: deriving per consumer would pay for the same\n * page once per renderer and once again for the load.\n *\n * (The GL mesh backend needs no derivation. It consumes premultiplied texels by\n * construction, so it just skips `UNPACK_PREMULTIPLY_ALPHA_WEBGL` at upload —\n * lossless, and the reason the two backends differ at all on such a page.)\n *\n * Weak by the page image, exactly like the GL texture cache: this package never\n * pins the caller's image, and a page the caller drops takes its derivation\n * with it. So nothing has to be freed by hand and `dispose()` stays out of it —\n * the ownership boundary is the same one `revokeRegions` respects.\n *\n * **What it costs while alive:** one page-sized canvas per `pma` page image\n * (4 bytes/px — 1 MiB for a 1024×256 page, 16 MiB for a 2048×2048 one), held\n * for as long as the caller holds the page. It is deliberately *not* charged to\n * the cut-backing budget below: that budget bounds the canvases in flight\n * during a load, a peak that appears and drains, while this sits alongside the\n * decoded page itself for the page's whole life — the same category as the\n * decoded pages the budget already documents as resident throughout.\n */\nconst straightAlphaPages = new WeakMap<HTMLImageElement, PageSource>();\n\n/** Derivations performed since load — see straightAlphaDerivations(). */\nlet derivationCount = 0;\n\n/**\n * How many straight-alpha page derivations have been built in this document.\n *\n * Deterministic (no GC in the path) and monotonic, so a test reads it before\n * and after and asserts the *difference*. Exported for the tests only — it is\n * not re-exported from index.ts and the `exports` map denies deep imports, so\n * it is not package API. (The same arrangement as `liveTextureCount` on the GL\n * blitter, and for the same reason: a cache that works is invisible.)\n */\nexport function straightAlphaDerivations(): number {\n return derivationCount;\n}\n\n/**\n * The page as a straight-alpha source: the image itself when `pma` is false,\n * otherwise its (cached) un-premultiplied derivation.\n *\n * `rgb = round(rgb * 255 / a)`, clamped, with `a === 0` left at (0,0,0,0) —\n * there is no colour to recover from a fully transparent texel.\n *\n * **Precision.** The division is done in 8 bits and cannot be done anywhere\n * else: a 2D canvas stores premultiplied colour, so `getImageData` hands back\n * `round(round(u * a / 255) * 255 / a)` for a file value `u`, already quantized\n * by the read (measured on both engines: put→get moves a value by up to 127 at\n * a = 1). The colour a low-alpha texel composites to is therefore off by at\n * most ~min(a, 127.5/a + 0.5) of 255 — nothing at a = 255 or a = 0, ≤ 1 above\n * a = 128, worst ~12 around a = 11, and bounded by `a` below that. Writing the\n * values back is exact, not a second premultiply: the canvas quantizer is\n * idempotent, so putting a value that came out of it stores it unchanged\n * (measured: a second round trip moves nothing on either engine). The remaining\n * error is one-way rounding on near-invisible texels, against a defect that\n * darkened every semi-transparent texel by up to 59 luma.\n *\n * A page image that cannot be read — no 2D context, or a cross-origin image\n * without CORS, where `getImageData` throws — falls back to the page itself and\n * caches *that*: the colour is then as wrong as it is today, but it happens\n * once per image instead of once per frame, and no frame throws. (The cut path\n * already fails on such an image at `toBlob`, so only the mesh tier can get\n * here.) An image that has not decoded yet is left uncached, so the derivation\n * happens once it has.\n */\nexport function straightAlphaSource(page: HTMLImageElement, pma: boolean): PageSource {\n if (!pma) return page;\n const cached = straightAlphaPages.get(page);\n if (cached) return cached;\n\n const width = page.naturalWidth;\n const height = page.naturalHeight;\n // Nothing to read yet: decide later rather than caching an empty canvas.\n if (!(width > 0) || !(height > 0)) return page;\n\n const derived = unpremultiply(page, width, height);\n straightAlphaPages.set(page, derived);\n if (derived !== page) derivationCount++;\n return derived;\n}\n\n/** The pixel pass behind straightAlphaSource; `page` back on any read failure. */\nfunction unpremultiply(page: HTMLImageElement, width: number, height: number): PageSource {\n const canvas = document.createElement('canvas');\n canvas.width = width;\n canvas.height = height;\n // No willReadFrequently: this reads once and is then a drawImage *source*\n // for the rest of its life, which wants the accelerated surface.\n const ctx = canvas.getContext('2d');\n if (!ctx) return page;\n ctx.drawImage(page, 0, 0);\n let pixels: ImageData;\n try {\n pixels = ctx.getImageData(0, 0, width, height);\n } catch {\n // Tainted canvas (cross-origin page image, no CORS).\n return page;\n }\n const data = pixels.data;\n for (let i = 0; i < data.length; i += 4) {\n const a = data[i + 3];\n if (a === 255) continue;\n if (a === 0) {\n // Nothing to divide by, and nothing there to see.\n data[i] = 0;\n data[i + 1] = 0;\n data[i + 2] = 0;\n continue;\n }\n const scale = 255 / a;\n // Rounded explicitly: assigning a fraction to a Uint8ClampedArray rounds\n // half-to-even, which is not the rule stated above.\n data[i] = Math.min(255, Math.round(data[i] * scale));\n data[i + 1] = Math.min(255, Math.round(data[i + 1] * scale));\n data[i + 2] = Math.min(255, Math.round(data[i + 2] * scale));\n }\n ctx.putImageData(pixels, 0, 0);\n return canvas;\n}\n\n/**\n * Backing pixels the cuts still waiting for their PNG encode may hold at once.\n *\n * A started cut keeps its canvas alive until `toBlob` calls back, so starting\n * every region at once peaks at Σ(cut area) of canvas backing — on top of the\n * decoded pages, which stay resident throughout. A cut is allocated at the\n * page image's own resolution, so what is charged here is that area, not the\n * region's atlas-unit area: a half-resolution page costs a quarter of it, an\n * @2x page four times it. Measured by counting the simultaneously-alive cut\n * canvases and their backing at `toBlob` (chromium, 1:1 pages):\n * the demo's 40-region 1024×256 atlas peaks at all 40 cuts and 194,742 px\n * (0.19 Mpx ≈ 0.74 MiB), which is nothing; a synthetic 256-region atlas on\n * four 2048×2048 pages peaks at 16.78 Mpx ≈ 64 MiB, which doubles that\n * atlas's resident cost for the length of the load.\n *\n * So the cuts are started against a budget rather than all at once. 4 Mpx is\n * one 2048×2048 page's worth (≈ 16 MiB at 4 bytes/px): small atlases still run\n * every region concurrently (spineboy: all 40, budget never engaged), and the\n * synthetic one runs 64 cuts at a time — 4 waves instead of 256 serial\n * encodes, for a quarter of the peak. A single region bigger than the budget\n * is started anyway when nothing else is in flight, so the budget can never\n * starve a cut.\n */\nconst CUT_BACKING_BUDGET_PX = 4 * 1024 * 1024;\n\n/** Where one region's pixels are on its page image, and how big its cut is. */\ninterface CutPlan {\n /** The region is its whole declared page, unrotated: hand the page through. */\n passThrough: boolean;\n /** Source rect on the page image, in the image's own pixels. */\n sx: number;\n sy: number;\n sw: number;\n sh: number;\n /** Cut canvas size: that same rect, turned artwork-side up. */\n cw: number;\n ch: number;\n}\n\n/**\n * Locates a region on its page image.\n *\n * **The rect is read in the image's own frame, not in declared atlas pixels.**\n * An atlas `size:` line and the image that ships for the page need not agree:\n * projects export textures at half resolution (or @2x) and leave the atlas\n * alone. Every official Spine runtime absorbs that for free, because\n * spine-core turns a region's bounds into *normalized* UVs against the\n * declared page size (`region.u = region.x / page.width`) and a GPU samples\n * normalized coordinates at whatever resolution the texture happens to have.\n * So the rect here is the region's bounds relative to the declared page size,\n * times the image's natural size — the continuous `uv * size` frame both mesh\n * backends already address texels in. No `size - 1`, no half-texel term: this\n * maps a rect, it does not sample.\n *\n * With a page that does ship at its declared size the scale is exactly 1 and\n * every number below is the region's own integer bounds, unchanged.\n *\n * Rotation: a region packed at 90° lies on its side, so it occupies a\n * `height × width` rect on the page — which is how spine-core reads it too\n * (`u2 = (x + height) / page.width` when `degrees === 90`). The cut canvas is\n * the rect turned back upright, so the bitmap comes out in artwork\n * orientation. *Which way* back is `cutRegion`'s, derived there from the UVs\n * spine-core assigns such a region and not from this plan.\n *\n * Rounding: each *edge* is rounded to the nearest image pixel, rather than the\n * width being rounded on its own. Neighbouring regions share an edge, so\n * rounding the edge keeps their cuts tiling the image exactly — no gap, no\n * overlap, and at most half a pixel of either region's own content given up on\n * a boundary that falls mid-pixel. Rounding outward would instead pull a whole\n * neighbouring pixel into every cut on every side, which is bleed the caller\n * can see. A rect that scales down below one pixel still gets a 1×1 bitmap,\n * since a zero-sized canvas is not one.\n *\n * The alternative was measured, not argued away (#35): sampling the\n * *fractional* rect with interpolation — what a GPU does with normalized UVs —\n * buys exact placement with a resample of the whole bitmap. Both rules drew\n * the same frozen rigid-only pose from a rescaled page, diffed against that\n * pose drawn from the 1:1 page. The result is split, so the lossless copy\n * stays: sampling lowers the raw difference and the peak channel delta, while\n * rounding lowers the count of pixels with no in-tolerance match anywhere in\n * the reference's 3×3 — rounding displaces the picture, which a shift-tolerant\n * compare forgives, and sampling blurs it, which it does not. On that\n * shift-tolerant count at 0.5×, the common case, rounding is ahead in every\n * cell measured, by 1.3× to 2.2× (chromium 638 vs 1238, webkit 1443 vs 1888) —\n * an ordering rather than a count, since the counts themselves move with the\n * raster. At an integer page scale the two rules come out bit-identical, there\n * being no fractional part to disagree about, so an @2x page never had a\n * question to answer. `tests/cut-rule.spec.ts` holds the 0.5× half of this.\n */\nfunction planCut({ region, page }: PlacedRegion, image: HTMLImageElement): CutPlan {\n const iw = image.naturalWidth;\n const ih = image.naturalHeight;\n // A page with no `size:` line (or a malformed one) declares nothing, so the\n // image is taken to be its own declared size — which is what this did for\n // every page before the frame above existed.\n const pageW = page.width > 0 ? page.width : iw;\n const pageH = page.height > 0 ? page.height : ih;\n\n const rotated = region.degrees === 90;\n const packedW = rotated ? region.height : region.width;\n const packedH = rotated ? region.width : region.height;\n\n // Whole-page pass-through: an unrotated region covering its entire page\n // would be cut into a pixel-for-pixel copy of the page image, so reuse the\n // page URL instead — no canvas, no PNG re-encode, no second decoded copy in\n // memory, and nothing to revoke afterwards. Atlases written as one part per\n // page (the loose-part-PNG workflow, where every part is declared its own\n // page) hit this for every single region.\n //\n // The test is against the declared page size, at any image resolution: a\n // whole page is a whole page whether it ships at 1×, half or double, and the\n // cut would copy the image either way. (It used to be tested against the\n // image, which was the same rule as long as the two always agreed.)\n //\n // Except on a premultiplied page, where the page URL is exactly what must not\n // be handed through: those pixels are premultiplied and an <img> composites\n // straight alpha, so passing the URL along would ship the defect to the one\n // atlas shape that never even allocates a canvas (one part per page). Such a\n // region is cut like any other — from the straight-alpha derivation — and the\n // blob it mints is owned and revoked like any other.\n if (\n !page.pma &&\n !rotated &&\n region.x === 0 &&\n region.y === 0 &&\n packedW === pageW &&\n packedH === pageH\n ) {\n return { passThrough: true, sx: 0, sy: 0, sw: iw, sh: ih, cw: iw, ch: ih };\n }\n\n const scaleX = iw / pageW;\n const scaleY = ih / pageH;\n const x0 = Math.round(region.x * scaleX);\n const y0 = Math.round(region.y * scaleY);\n const sw = Math.max(1, Math.round((region.x + packedW) * scaleX) - x0);\n const sh = Math.max(1, Math.round((region.y + packedH) * scaleY) - y0);\n\n return {\n passThrough: false,\n sx: x0,\n sy: y0,\n sw,\n sh,\n cw: rotated ? sh : sw,\n ch: rotated ? sw : sh,\n };\n}\n\n/** Backing pixels one cut allocates — the charge against the budget above. */\nfunction cutBackingPixels(\n placed: PlacedRegion,\n pageImages: ReadonlyMap<string, HTMLImageElement>,\n): number {\n const image = pageImages.get(placed.page.name);\n // No image: this region is about to fail in the cut. Charging its atlas\n // units keeps the walk moving until it does.\n if (!image) return placed.region.width * placed.region.height;\n const plan = planCut(placed, image);\n return plan.cw * plan.ch;\n}\n\n/**\n * One region's bitmap: the whole-page pass-through, or a cut canvas encoded to\n * a blob URL this module then owns.\n *\n * The cut is a **1:1 copy of the source rect** planCut located — never a\n * resample — so the bitmap has the native resolution of those pixels, while\n * the `RegionImage` sizes reported alongside it stay in atlas units. A page\n * shipped at half resolution therefore costs a quarter of the cut pixels and\n * still poses identically; upscaling the cut back to declared size would only\n * quadruple the pixels and add a resample.\n *\n * Everything before the `toBlob` await runs synchronously, so calling this is\n * what \"starts\" a cut: the canvas is painted and the encode is handed to the\n * browser before control comes back.\n */\nasync function cutRegion(\n placed: PlacedRegion,\n pageImages: ReadonlyMap<string, HTMLImageElement>,\n encoding: RegionEncoding,\n): Promise<RegionImage> {\n const { region, page } = placed;\n const image = pageImages.get(page.name);\n if (!image) throw new Error(`Missing page image: ${page.name}`);\n\n const w = region.width;\n const h = region.height;\n const plan = planCut(placed, image);\n if (plan.passThrough) return { url: image.src, width: w, height: h };\n\n const canvas = document.createElement('canvas');\n canvas.width = plan.cw;\n canvas.height = plan.ch;\n const ctx = canvas.getContext('2d');\n if (!ctx) throw new Error('2d context unavailable');\n\n if (region.degrees === 90) {\n // The region is packed rotated. Turn the destination frame back so the\n // source rect, drawn at its own size, lands upright and fills the canvas —\n // and turn it *clockwise*, which is derived from spine-core's UVs rather\n // than from anything this file does.\n //\n // `TextureAtlas` takes `u`/`v` from the packed rect's top-left corner and,\n // at `degrees === 90`, `u2`/`v2` from `x + height` / `y + width` — the\n // rect's far edges. `RegionAttachment` then hands the artwork's corners out\n // in the rigid tier's own order, BL, UL, UR, BR, as\n //\n // BL (u2, v2) UL (u, v2) UR (u, v) BR (u2, v)\n //\n // so the artwork's top-left corner is the packed rect's *bottom-left* and\n // its top-right is the rect's *top-left*: the artwork's top edge runs up\n // the rect's left edge, which is a packer that turned it counter-clockwise.\n //\n // `translate(cw, 0); rotate(+π/2)` maps a pixel (x, y) of the source rect —\n // sw × sh on the page, and cw = sh, ch = sw — to canvas (cw − y, x), which\n // is that turn undone:\n //\n // packed bottom-left (0, sh) → (0, 0) the cut's top-left = UL\n // packed top-left (0, 0) → (cw, 0) the cut's top-right = UR\n // packed top-right (sw, 0) → (cw, ch) the cut's bottom-right = BR\n // packed bottom-right (sw, sh) → (0, ch) the cut's bottom-left = BL\n //\n // Until #49 this was `translate(0, ch); rotate(−π/2)`, mapping (x, y) to\n // (y, ch − x): a *second* counter-clockwise turn, landing the artwork's\n // top-left at the cut's bottom-right. The bitmap came out 180° round, and\n // since `renderRegion` pins a bitmap's top-left to the attachment's UL\n // corner either way, every rotated rigid part was drawn inverted — from the\n // first commit of this package to 0.7.0. The mesh tier never was: it\n // samples the page through the UVs above.\n ctx.translate(plan.cw, 0);\n ctx.rotate(Math.PI / 2);\n }\n // Straight alpha on a premultiplied page, since the cut is encoded to a PNG\n // and shown in an <img>. The rect was planned against the image, and the\n // derivation is that image's own size, so the coordinates carry over\n // unchanged — including on a page that ships at another resolution.\n const source = straightAlphaSource(image, page.pma === true);\n ctx.drawImage(source, plan.sx, plan.sy, plan.sw, plan.sh, 0, 0, plan.sw, plan.sh);\n\n // A `data:` URL is the same PNG inline: nothing is minted, so nothing is\n // owned and `revokeRegions` has nothing to free. It is for a consumer whose\n // content policy or snapshotting does not carry `blob:`; it costs the\n // base64 string per region for as long as the map lives.\n if (encoding === 'data') return { url: canvas.toDataURL('image/png'), width: w, height: h };\n\n const blob = await new Promise<Blob>((resolve, reject) => {\n canvas.toBlob((b) => (b ? resolve(b) : reject(new Error('toBlob failed'))), 'image/png');\n });\n const url = URL.createObjectURL(blob);\n ownedUrls.add(url);\n return { url, width: w, height: h };\n}\n\n/**\n * How a cut region's PNG is handed to the `<img>`: a `blob:` URL this module\n * owns and `revokeRegions` frees (the default), or a `data:` URL that owns\n * nothing and needs no revoke.\n */\nexport type RegionEncoding = 'blob' | 'data';\n\nexport interface UnpackRegionsOptions {\n /** `'blob'` by default. */\n encoding?: RegionEncoding;\n}\n\n/**\n * Cuts every region of a page layout — a model document's `pages` section —\n * out of its page image into its own bitmap once at load time, restoring 90°\n * packing rotation, so the per-frame path never touches a canvas. Returns\n * image URLs keyed by region name. `pageImages` is keyed by page name.\n * `loadModel` calls this; it is exported for callers whose page images do not\n * come from a URL.\n *\n * This is a loading-pipeline step, not a rendering step: after this runs,\n * rendering is pure DOM (one <img> per slot, one CSS matrix write per frame).\n *\n * A region that covers its whole page unrotated skips the cut and reuses the\n * page image URL — see the pass-through in planCut.\n *\n * **A page may ship at a resolution its atlas does not declare.** Half-size\n * texture builds and @2x variants are normal, and no option is needed for\n * them: a region's bounds are read relative to the declared page size and\n * scaled onto the image's natural size, which is exactly how spine-core\n * derives the UVs the mesh tier already samples with. Each bitmap comes out at\n * the native resolution of the pixels it was cut from, and the `RegionImage`\n * sizes beside it stay in atlas units, so nothing downstream has to know.\n *\n * *Behaviour change (0.5.1 → next).* An atlas whose `size:` line is simply\n * wrong — bounds written in image pixels under a page declared some other size\n * — used to be cut \"as the coordinates say\", because the cut read the image\n * directly. It is now read the way every other Spine runtime reads it:\n * relative to the declared size. Such an atlas rendered with a skewed mesh\n * tier and an intact rigid tier before; now both tiers agree, and the fix is\n * to correct the `size:` line.\n *\n * **The cuts run concurrently.** PNG encoding is asynchronous and the browser\n * does it off the main thread, so the encodes are started together and awaited\n * together instead of one `toBlob` per iteration: awaited in series a load\n * costs the *sum* of every encode, which a throttled document turns into one\n * full throttle period per region (measured: a single 8×8 `toBlob` took 7.5 s\n * to call back in a hidden desktop Chromium pane). How many run at once is\n * bounded by CUT_BACKING_BUDGET_PX above, not by an option.\n *\n * Concurrency changes nothing a caller can observe:\n *\n * - **Order.** The returned map is keyed in layout order — pages in order,\n * each page's regions in order, which is the atlas's own order — whatever\n * order the blobs arrive in: the map is built after the cuts settle, from\n * the region list, not from the arrivals.\n * - **Duplicate names.** The last region of a given name in atlas order wins,\n * and the shadowed URL is revoked (and dropped from the ledger) rather than\n * stranded.\n * - **Failure.** Every URL this call minted is revoked before the error\n * propagates, *including cuts that were still in flight when the first\n * failure happened* — their blobs arrive later, and a load that walked away\n * from them would mint owned URLs nobody could ever revoke. So a failure\n * stops new cuts from starting but still waits for the started ones, and the\n * error it raises is the one from the earliest region in atlas order (what\n * the serial loop used to throw). Nothing here rejects unobserved.\n *\n * The blob URLs stay alive until revokeRegions() frees them — a document-wide\n * allocation the GC cannot reclaim on its own. Callers that load and unload\n * skeletons repeatedly (cutscenes, level transitions) must pair every\n * unpackRegions() with a revokeRegions(); a caller that loads once for the\n * page lifetime can ignore it.\n */\nexport async function unpackRegions(\n pages: readonly PageLayout[],\n pageImages: ReadonlyMap<string, HTMLImageElement>,\n options: UnpackRegionsOptions = {},\n): Promise<Map<string, RegionImage>> {\n const encoding = options.encoding ?? 'blob';\n if (encoding !== 'blob' && encoding !== 'data') throw new Error(`encoding must be 'blob' or 'data', got ${String(options.encoding)}`);\n const regions: PlacedRegion[] = pages.flatMap((page) => page.regions.map((region) => ({ region, page })));\n const cuts = new Array<RegionImage | undefined>(regions.length);\n\n // The earliest-in-atlas-order failure is the one that propagates, so that a\n // broken atlas reports the same region whichever encode happens to land\n // first.\n let failedIndex = -1;\n let failure: unknown;\n\n /** One in-flight cut: `done` is set before its promise resolves. */\n interface Job {\n promise: Promise<void>;\n done: boolean;\n }\n let inFlight: Job[] = [];\n let inFlightPixels = 0;\n\n for (let index = 0; index < regions.length && failedIndex === -1; index++) {\n const region = regions[index];\n if (!region) continue;\n // A pass-through allocates no canvas, but it also resolves without waiting\n // for anything, so charging it the page's area costs at most one drain.\n const pixels = cutBackingPixels(region, pageImages);\n\n while (inFlight.length > 0 && inFlightPixels + pixels > CUT_BACKING_BUDGET_PX) {\n await Promise.race(inFlight.map((job) => job.promise));\n inFlight = inFlight.filter((job) => !job.done);\n if (failedIndex !== -1) break;\n }\n if (failedIndex !== -1) break;\n\n inFlightPixels += pixels;\n const job: Job = { done: false, promise: Promise.resolve() };\n // Jobs settle, they never reject: the failure is recorded here so that\n // nothing is left for an unhandled-rejection handler to find.\n job.promise = (async () => {\n try {\n cuts[index] = await cutRegion(region, pageImages, encoding);\n } catch (error) {\n if (failedIndex === -1 || index < failedIndex) {\n failedIndex = index;\n failure = error;\n }\n } finally {\n inFlightPixels -= pixels;\n job.done = true;\n }\n })();\n inFlight.push(job);\n }\n\n // Every cut this call started is settled after this, so the cleanup below\n // reaches the blobs that arrived after the first failure too.\n await Promise.all(inFlight.map((job) => job.promise));\n\n if (failedIndex !== -1) {\n for (const cut of cuts) if (cut) revokeOwned(cut.url);\n throw failure;\n }\n\n const result = new Map<string, RegionImage>();\n for (let index = 0; index < regions.length; index++) {\n const placed = regions[index];\n const cut = cuts[index];\n if (!placed || !cut) continue;\n // Duplicate region names would otherwise strand the shadowed URL in the\n // ledger with nothing left pointing at it. Map.set keeps the key where it\n // first appeared, so atlas order survives the overwrite.\n const shadowed = result.get(placed.region.name);\n if (shadowed) revokeOwned(shadowed.url);\n result.set(placed.region.name, cut);\n }\n return result;\n}\n\n/**\n * Frees the blob URLs unpackRegions minted for `images` — the counterpart of\n * unpackRegions, to call once the skeletons using them are gone (after\n * `renderer.dispose()`, since a live <img> would keep pointing at a dead URL).\n *\n * Only URLs this module created are revoked: entries the caller supplied\n * itself (a hand-built map of loose part PNGs) and page images reused\n * verbatim by the whole-page pass-through are left alone. Idempotent —\n * revoking twice is a no-op, so it is safe on a map that is shared or\n * partially reused.\n *\n * The map keeps its entries; drop the reference (or reload) afterwards, since\n * the URLs no longer resolve.\n */\nexport function revokeRegions(images: Map<string, RegionImage>): void {\n for (const image of images.values()) revokeOwned(image.url);\n}\n","/**\n * Shared offscreen WebGL rasterizer for the mesh (deform) tier.\n *\n * One module-level context serves every renderer instance: browsers cap live\n * WebGL contexts (16 on Chrome/Safari) and a page can hold many renderers, so\n * per-renderer contexts would evict each other. Per flush, every dirty mesh is\n * shelf-packed into a rect of the offscreen canvas, its triangles are drawn\n * textured (atlas page texture, premultiplied alpha), and each rect is blitted\n * onto the mesh's per-part 2d canvas with an unclipped drawImage rect copy.\n * The texture is premultiplied either by the upload or by the exporter — a\n * `pma: true` page arrives that way, so it is uploaded unconverted (textureFor).\n *\n * Why this exists: Safari antialiases canvas2d clip paths, so the standard\n * per-triangle clip+transform+drawImage mapping pays a per-triangle AA-mask\n * cost in the GPU process — invisible to in-callback JS timing, but it\n * rAF-limits heavy scenes. GL rasterizes shared triangle edges seamlessly\n * (no clip, no crack overdraw needed), and the remaining canvas2d work is a\n * plain rect blit.\n *\n * The offscreen buffer is scratch space: rects are scissor-cleared and\n * redrawn every flush and read back in the same task, so neither\n * preserveDrawingBuffer nor cross-frame content is relied on. The buffer\n * grows quantized and never shrinks, mirroring the per-part backing policy\n * (reallocating GPU surfaces per frame is a Safari killer).\n *\n * Page textures are the one thing here with a lifetime, and since this object\n * outlives every renderer they are reference-counted: a renderer retains each\n * page it queues a job for and releases them in dispose(), and the last\n * release deletes the GL texture (a later job re-uploads it). The cache is\n * keyed weakly by the page image, so a consumer that never disposes still\n * loses nothing but GPU memory — this object never pins the caller's image.\n *\n * The canvas render mode (`CanvasRenderer`) draws through the same context: a\n * `FrameJob` is a whole player's frame — every region and mesh as textured,\n * vertex-coloured triangles in draw order, with the blend mode as batch state —\n * into one rect, blitted onto that player's one visible canvas. It has its own\n * program (colour and optional dark attributes) so the mesh tier's program and\n * its output stay exactly what they were; both share the page textures and\n * their reference counts.\n */\n\nimport type { BlendMode } from './posedFrame.js';\n\nexport interface MeshBlitJob {\n /** Destination per-part canvas; the blit clears its full backing first. */\n canvas: HTMLCanvasElement;\n /** Atlas page image the mesh samples (cached as a GL texture on first use). */\n page: HTMLImageElement;\n /**\n * `page.pma` — whether the page's texels are already premultiplied, which\n * decides whether the upload premultiplies them again (see textureFor). It\n * travels with the page because it describes the page's *pixels*, and the\n * blend below wants them premultiplied exactly once.\n */\n pma: boolean;\n /** Bbox-relative vertices in CSS px, x/y interleaved (indexed via `triangles`). */\n vertices: Float64Array;\n /** Normalized page UVs aligned with `vertices`. */\n uvs: ArrayLike<number>;\n /** Triangle index list into vertex/UV pairs. */\n triangles: ArrayLike<number>;\n /** Backing-store pixels per CSS px. */\n ratio: number;\n /** Rasterized region in device px — the packed rect and the blit both use it. */\n width: number;\n height: number;\n}\n\n/**\n * One run of a frame job's triangles: a stretch of the vertex data that samples\n * one page under one blend mode — one draw call.\n */\nexport interface FrameRun {\n page: HTMLImageElement;\n /** `page.pma`, as for MeshBlitJob. */\n pma: boolean;\n blend: BlendMode;\n /** First vertex of the run (not float) in `FrameJob.data`. */\n first: number;\n /** Vertices in the run — three per triangle. */\n count: number;\n}\n\n/**\n * A whole frame of one player (the canvas render mode): unindexed triangles,\n * interleaved per vertex as\n * `x, y, u, v, r, g, b, a` (stride 8) or `x, y, u, v, r, g, b, a, dr, dg, db`\n * (stride 11, the two-colour form, only when the frame carries a dark colour).\n * Positions are device px relative to the job's rect, top-left origin; the\n * colour is premultiplied by its alpha and so is the dark colour. Drawn into\n * one rect of the offscreen buffer, then blitted onto `canvas` in one\n * `drawImage`.\n */\nexport interface FrameJob {\n canvas: HTMLCanvasElement;\n width: number;\n height: number;\n data: Float32Array;\n stride: 8 | 11;\n runs: FrameRun[];\n}\n\n/**\n * Premultiplied-source blend factors per mode — the RGB pair; alpha always\n * takes ONE against the same destination factor, so a mode drawn over\n * transparency still leaves coverage behind for the blit to composite.\n */\nconst BLEND_FACTORS: Record<BlendMode, readonly [src: number, dst: number]> = {\n Normal: [1 /* ONE */, 0x0303 /* ONE_MINUS_SRC_ALPHA */],\n Additive: [1 /* ONE */, 1 /* ONE */],\n Multiply: [0x0306 /* DST_COLOR */, 0x0303 /* ONE_MINUS_SRC_ALPHA */],\n Screen: [1 /* ONE */, 0x0301 /* ONE_MINUS_SRC_COLOR */],\n};\n\nconst FRAME_VERTEX_SHADER = `\nattribute vec2 aPos;\nattribute vec2 aUV;\nattribute vec4 aColor;\nattribute vec3 aDark;\nuniform vec2 uResolution;\nuniform vec2 uOrigin;\nvarying vec2 vUV;\nvarying vec4 vColor;\nvarying vec3 vDark;\nvoid main() {\n vec2 clip = (aPos + uOrigin) / uResolution * 2.0 - 1.0;\n gl_Position = vec4(clip.x, -clip.y, 0.0, 1.0);\n vUV = aUV;\n vColor = aColor;\n vDark = aDark;\n}`;\n\n/*\n * Two-colour tint over a premultiplied texel t: in straight terms the texel's\n * colour c is mapped to c·light + (1 − c)·dark, with alpha t.a·light.a.\n * Premultiplying that by the output alpha gives\n * t.rgb·(light·a) + (t.a − t.rgb)·(dark·a) — which is why both vertex colours\n * arrive premultiplied. With no dark colour the dark attribute is a constant 0\n * and this is a plain premultiplied vertex-colour multiply.\n */\nconst FRAME_FRAGMENT_SHADER = `\nprecision mediump float;\nuniform sampler2D uTex;\nvarying vec2 vUV;\nvarying vec4 vColor;\nvarying vec3 vDark;\nvoid main() {\n vec4 t = texture2D(uTex, vUV);\n gl_FragColor = vec4(t.rgb * vColor.rgb + (t.a - t.rgb) * vDark, t.a * vColor.a);\n}`;\n\n/** WebGL contexts this module has created; see glContextCount(). */\nlet contextsCreated = 0;\n\n/**\n * WebGL contexts this module has created — the whole of the context-cap\n * accounting: one, however many renderers and players draw through it.\n *\n * @internal Read by the test harness; not part of the package API.\n */\nexport function glContextCount(): number {\n return contextsCreated;\n}\n\nconst VERTEX_SHADER = `\nattribute vec2 aPos;\nattribute vec2 aUV;\nuniform vec2 uResolution;\nvarying vec2 vUV;\nvoid main() {\n // aPos is in offscreen-canvas device px, top-left origin (matching the\n // top-left-origin drawImage read of the same rect).\n vec2 clip = aPos / uResolution * 2.0 - 1.0;\n gl_Position = vec4(clip.x, -clip.y, 0.0, 1.0);\n vUV = aUV;\n}`;\n\nconst FRAGMENT_SHADER = `\nprecision mediump float;\nuniform sampler2D uTex;\nvarying vec2 vUV;\nvoid main() {\n gl_FragColor = texture2D(uTex, vUV);\n}`;\n\n/** Gap between packed rects; blits are 1:1 unfiltered, so 1px is plenty. */\nconst GUTTER = 1;\n/** Drawing-buffer growth quantum (device px). */\nconst GROW_STEP = 256;\n\n/** Cache entry for one atlas page: the upload, and how many renderers want it. */\ninterface PageTexture {\n /** Uploaded lazily, on the first flush that binds this page. */\n texture: WebGLTexture | null;\n /** Live retain() calls outstanding — one per renderer drawing this page. */\n users: number;\n /** The alpha convention `texture` was uploaded under; meaningless without it. */\n pma: boolean;\n}\n\nclass MeshGlBlitter {\n lost = false;\n /**\n * Page textures created minus deleted, i.e. how many uploads are live right\n * now. Deterministic (no GC in the path), which is what the lifetime tests\n * assert against — see tests/gl-textures.spec.ts.\n */\n liveTextureCount = 0;\n\n private readonly canvas = document.createElement('canvas');\n private readonly gl: WebGLRenderingContext;\n private readonly uResolution: WebGLUniformLocation;\n private readonly meshProgram: WebGLProgram;\n private readonly meshPos: number;\n private readonly meshUV: number;\n private readonly frameProgram: WebGLProgram;\n private readonly frameResolution: WebGLUniformLocation;\n private readonly frameOrigin: WebGLUniformLocation;\n private readonly framePos: number;\n private readonly frameUV: number;\n private readonly frameColor: number;\n private readonly frameDark: number;\n /** Which program's attribute layout is bound — each flush binds its own. */\n private bound: 'mesh' | 'frame' | null = null;\n /**\n * Weak by the page image on purpose: a consumer that forgets dispose()\n * leaks its texture until context loss, but dropping the image still lets\n * the image (and then the WebGLTexture this entry holds) be collected.\n * Reassigned wholesale on context loss, never iterated.\n */\n private textures = new WeakMap<HTMLImageElement, PageTexture>();\n private readonly maxSize: number;\n private vertexData = new Float32Array(8192);\n /** Per-job packed rect origins, filled by flush(). */\n private packX: number[] = [];\n private packY: number[] = [];\n\n constructor() {\n const gl = this.canvas.getContext('webgl', {\n alpha: true,\n premultipliedAlpha: true,\n antialias: false,\n depth: false,\n stencil: false,\n preserveDrawingBuffer: false,\n });\n if (!gl) throw new Error('WebGL unavailable');\n contextsCreated++;\n this.gl = gl;\n // No restore attempt: on loss the renderer falls back to canvas2d and the\n // backend signature re-dirties every mesh, so frames stay complete.\n this.canvas.addEventListener('webglcontextlost', () => {\n this.markLost();\n });\n\n const program = this.link(VERTEX_SHADER, FRAGMENT_SHADER);\n this.meshProgram = program;\n gl.useProgram(program);\n const uResolution = gl.getUniformLocation(program, 'uResolution');\n if (!uResolution) throw new Error('uResolution not found');\n this.uResolution = uResolution;\n gl.uniform1i(gl.getUniformLocation(program, 'uTex'), 0);\n this.meshPos = gl.getAttribLocation(program, 'aPos');\n this.meshUV = gl.getAttribLocation(program, 'aUV');\n\n const frame = this.link(FRAME_VERTEX_SHADER, FRAME_FRAGMENT_SHADER);\n this.frameProgram = frame;\n gl.useProgram(frame);\n const frameResolution = gl.getUniformLocation(frame, 'uResolution');\n const frameOrigin = gl.getUniformLocation(frame, 'uOrigin');\n if (!frameResolution || !frameOrigin) throw new Error('frame program uniforms not found');\n this.frameResolution = frameResolution;\n this.frameOrigin = frameOrigin;\n gl.uniform1i(gl.getUniformLocation(frame, 'uTex'), 0);\n this.framePos = gl.getAttribLocation(frame, 'aPos');\n this.frameUV = gl.getAttribLocation(frame, 'aUV');\n this.frameColor = gl.getAttribLocation(frame, 'aColor');\n this.frameDark = gl.getAttribLocation(frame, 'aDark');\n\n // One dynamic buffer for both programs; each flush binds its own layout\n // (bindMesh / bindFrame), so neither sees the other's attribute state.\n gl.bindBuffer(gl.ARRAY_BUFFER, gl.createBuffer());\n gl.enable(gl.BLEND);\n gl.enable(gl.SCISSOR_TEST);\n gl.clearColor(0, 0, 0, 0);\n gl.activeTexture(gl.TEXTURE0);\n this.maxSize = Math.min((gl.getParameter(gl.MAX_RENDERBUFFER_SIZE) as number) || 4096, 8192);\n }\n\n /**\n * Rasterize every job into the offscreen buffer, then blit each rect onto\n * its per-part canvas. Returns false when the context is lost (or the jobs\n * cannot fit) so the caller can rasterize the batch on the canvas2d path.\n */\n flush(jobs: MeshBlitJob[]): boolean {\n const gl = this.gl;\n if (this.lost || gl.isContextLost()) return false;\n\n // Shelf-pack, tallest first (indices keep job order for the draw pass).\n let width = Math.max(512, this.canvas.width);\n for (const job of jobs) width = Math.max(width, job.width + GUTTER * 2);\n if (width > this.maxSize) return false;\n const order = jobs.map((_, i) => i).sort((a, b) => jobs[b].height - jobs[a].height);\n const packX = (this.packX = new Array<number>(jobs.length));\n const packY = (this.packY = new Array<number>(jobs.length));\n let shelfX = GUTTER;\n let shelfY = GUTTER;\n let shelfH = 0;\n let height = GUTTER;\n for (const i of order) {\n const job = jobs[i];\n if (shelfX + job.width + GUTTER > width) {\n shelfY += shelfH + GUTTER;\n shelfX = GUTTER;\n shelfH = 0;\n }\n packX[i] = shelfX;\n packY[i] = shelfY;\n shelfX += job.width + GUTTER;\n if (job.height > shelfH) shelfH = job.height;\n if (shelfY + job.height + GUTTER > height) height = shelfY + job.height + GUTTER;\n }\n if (height > this.maxSize) return false;\n\n // Grow-only quantized drawing buffer. Resizing clears it, which is fine:\n // every rect below is cleared and redrawn anyway.\n if (width > this.canvas.width || height > this.canvas.height) {\n this.canvas.width = Math.min(this.maxSize, Math.ceil(width / GROW_STEP) * GROW_STEP);\n this.canvas.height = Math.min(\n this.maxSize,\n Math.ceil(Math.max(height, this.canvas.height) / GROW_STEP) * GROW_STEP,\n );\n }\n const bufW = this.canvas.width;\n const bufH = this.canvas.height;\n gl.viewport(0, 0, bufW, bufH);\n this.bindMesh();\n gl.uniform2f(this.uResolution, bufW, bufH);\n\n // Build one interleaved vertex array for the whole batch (unindexed —\n // meshes are a few hundred triangles, expansion is cheaper than managing\n // index buffers).\n let floats = 0;\n for (const job of jobs) floats += job.triangles.length * 4;\n if (this.vertexData.length < floats) {\n this.vertexData = new Float32Array(1 << Math.ceil(Math.log2(floats)));\n }\n const data = this.vertexData;\n let f = 0;\n for (let i = 0; i < jobs.length; i++) {\n const { vertices, uvs, triangles, ratio } = jobs[i];\n const ox = packX[i];\n const oy = packY[i];\n for (let t = 0; t < triangles.length; t++) {\n const vi = triangles[t] * 2;\n data[f++] = ox + vertices[vi] * ratio;\n data[f++] = oy + vertices[vi + 1] * ratio;\n data[f++] = uvs[vi];\n data[f++] = uvs[vi + 1];\n }\n }\n gl.bufferData(gl.ARRAY_BUFFER, data.subarray(0, floats), gl.DYNAMIC_DRAW);\n\n let boundPage: HTMLImageElement | null = null;\n let first = 0;\n for (let i = 0; i < jobs.length; i++) {\n const job = jobs[i];\n if (job.page !== boundPage) {\n gl.bindTexture(gl.TEXTURE_2D, this.textureFor(job.page, job.pma));\n boundPage = job.page;\n }\n // Scissor is bottom-left origin; pack coords are top-left origin.\n gl.scissor(packX[i], bufH - packY[i] - job.height, job.width, job.height);\n gl.clear(gl.COLOR_BUFFER_BIT);\n gl.drawArrays(gl.TRIANGLES, first, job.triangles.length);\n first += job.triangles.length;\n }\n\n // If the context died mid-batch the draws above were no-ops; report it\n // before blitting stale/blank rects onto the part canvases.\n if (gl.isContextLost()) {\n this.markLost();\n return false;\n }\n\n // Blit each rect onto its per-part canvas: same-task read (no\n // preserveDrawingBuffer needed), 1:1 device px (no filtering).\n for (let i = 0; i < jobs.length; i++) {\n const job = jobs[i];\n const ctx = job.canvas.getContext('2d');\n if (!ctx) continue;\n ctx.setTransform(1, 0, 0, 1, 0, 0);\n // Clear the full backing: the previous raster may have been larger.\n ctx.clearRect(0, 0, job.canvas.width, job.canvas.height);\n ctx.drawImage(this.canvas, packX[i], packY[i], job.width, job.height, 0, 0, job.width, job.height);\n }\n return true;\n }\n\n /**\n * Draws one player's frame (the canvas render mode) into a rect of the\n * offscreen buffer and blits it onto `job.canvas`, whose full backing is\n * cleared first. Returns false when the context is lost or the rect cannot\n * fit, so the caller can draw the frame on its canvas2d fallback instead.\n */\n flushFrame(job: FrameJob): boolean {\n const gl = this.gl;\n if (this.lost || gl.isContextLost()) return false;\n const width = job.width + GUTTER * 2;\n const height = job.height + GUTTER * 2;\n if (width > this.maxSize || height > this.maxSize) return false;\n if (width > this.canvas.width || height > this.canvas.height) {\n this.canvas.width = Math.min(this.maxSize, Math.ceil(Math.max(width, this.canvas.width) / GROW_STEP) * GROW_STEP);\n this.canvas.height = Math.min(this.maxSize, Math.ceil(Math.max(height, this.canvas.height) / GROW_STEP) * GROW_STEP);\n }\n const bufW = this.canvas.width;\n const bufH = this.canvas.height;\n gl.viewport(0, 0, bufW, bufH);\n this.bindFrame(job.stride);\n gl.uniform2f(this.frameResolution, bufW, bufH);\n gl.uniform2f(this.frameOrigin, GUTTER, GUTTER);\n\n let vertices = 0;\n for (const run of job.runs) vertices = Math.max(vertices, run.first + run.count);\n if (vertices > 0) gl.bufferData(gl.ARRAY_BUFFER, job.data.subarray(0, vertices * job.stride), gl.DYNAMIC_DRAW);\n\n // Scissor is bottom-left origin; the rect sits at (GUTTER, GUTTER) top-left.\n gl.scissor(GUTTER, bufH - GUTTER - job.height, job.width, job.height);\n gl.clear(gl.COLOR_BUFFER_BIT);\n let boundPage: HTMLImageElement | null = null;\n let boundBlend: BlendMode | null = null;\n for (const run of job.runs) {\n if (run.page !== boundPage) {\n gl.bindTexture(gl.TEXTURE_2D, this.textureFor(run.page, run.pma));\n boundPage = run.page;\n }\n if (run.blend !== boundBlend) {\n const [src, dst] = BLEND_FACTORS[run.blend];\n gl.blendFuncSeparate(src, dst, gl.ONE, dst);\n boundBlend = run.blend;\n }\n gl.drawArrays(gl.TRIANGLES, run.first, run.count);\n }\n if (gl.isContextLost()) {\n this.markLost();\n return false;\n }\n\n // One blit: same-task read, 1:1 device px.\n const ctx = job.canvas.getContext('2d');\n if (!ctx) return true;\n ctx.setTransform(1, 0, 0, 1, 0, 0);\n ctx.globalAlpha = 1;\n ctx.globalCompositeOperation = 'source-over';\n ctx.clearRect(0, 0, job.canvas.width, job.canvas.height);\n if (job.width > 0 && job.height > 0) {\n ctx.drawImage(this.canvas, GUTTER, GUTTER, job.width, job.height, 0, 0, job.width, job.height);\n }\n return true;\n }\n\n /** The mesh tier's layout, [x, y, u, v], and its premultiplied source-over. */\n private bindMesh(): void {\n const gl = this.gl;\n if (this.bound !== 'mesh') {\n gl.useProgram(this.meshProgram);\n this.disableAttributes();\n gl.enableVertexAttribArray(this.meshPos);\n gl.enableVertexAttribArray(this.meshUV);\n gl.vertexAttribPointer(this.meshPos, 2, gl.FLOAT, false, 16, 0);\n gl.vertexAttribPointer(this.meshUV, 2, gl.FLOAT, false, 16, 8);\n this.bound = 'mesh';\n }\n // Premultiplied source-over, matching canvas2d triangle compositing. Set on\n // every mesh flush: a frame job in between leaves its last blend behind.\n gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);\n }\n\n /** The frame layout: [x, y, u, v, r, g, b, a], and [dr, dg, db] at stride 11. */\n private bindFrame(stride: 8 | 11): void {\n const gl = this.gl;\n gl.useProgram(this.frameProgram);\n this.disableAttributes();\n const bytes = stride * 4;\n gl.enableVertexAttribArray(this.framePos);\n gl.enableVertexAttribArray(this.frameUV);\n gl.enableVertexAttribArray(this.frameColor);\n gl.vertexAttribPointer(this.framePos, 2, gl.FLOAT, false, bytes, 0);\n gl.vertexAttribPointer(this.frameUV, 2, gl.FLOAT, false, bytes, 8);\n gl.vertexAttribPointer(this.frameColor, 4, gl.FLOAT, false, bytes, 16);\n if (stride === 11) {\n gl.enableVertexAttribArray(this.frameDark);\n gl.vertexAttribPointer(this.frameDark, 3, gl.FLOAT, false, bytes, 32);\n } else {\n // No slot carries a dark colour: a constant zero, which reduces the\n // two-colour form to the plain colour multiply.\n gl.vertexAttrib3f(this.frameDark, 0, 0, 0);\n }\n this.bound = 'frame';\n }\n\n private disableAttributes(): void {\n const gl = this.gl;\n for (const location of [this.meshPos, this.meshUV, this.framePos, this.frameUV, this.frameColor, this.frameDark]) {\n if (location >= 0) gl.disableVertexAttribArray(location);\n }\n }\n\n private link(vertex: string, fragment: string): WebGLProgram {\n const gl = this.gl;\n const program = gl.createProgram();\n if (!program) throw new Error('createProgram failed');\n gl.attachShader(program, this.compile(gl.VERTEX_SHADER, vertex));\n gl.attachShader(program, this.compile(gl.FRAGMENT_SHADER, fragment));\n gl.linkProgram(program);\n if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {\n throw new Error(`program link failed: ${gl.getProgramInfoLog(program)}`);\n }\n return program;\n }\n\n /**\n * Declares one more user of `page`. The upload itself stays lazy (the first\n * flush that binds the page does it) — this only counts, so that the last\n * release() can free the texture instead of the module holding it forever.\n * Callers retain once per page and hand the same page back exactly once;\n * DomRenderer and CanvasRenderer each keep that ledger and settle it in dispose().\n */\n retain(page: HTMLImageElement): void {\n const entry = this.textures.get(page);\n if (entry) entry.users++;\n else this.textures.set(page, { texture: null, users: 1, pma: false });\n }\n\n /**\n * Gives back one retain(). The GL texture goes when the last user of the\n * page is gone; a later job for the same page simply uploads it again. A\n * page the cache does not know (a release after a context loss dropped\n * everything, or a double dispose) is a no-op, so this is safe to call\n * unconditionally.\n */\n release(page: HTMLImageElement): void {\n const entry = this.textures.get(page);\n if (!entry) return;\n if (--entry.users > 0) return;\n this.textures.delete(page);\n if (!entry.texture) return;\n // deleteTexture is a documented no-op on a lost context rather than a\n // throw, but a lost context has already dropped the cache and zeroed the\n // count — reaching here with `lost` set would mean decrementing twice.\n if (!this.lost && !this.gl.isContextLost()) this.gl.deleteTexture(entry.texture);\n this.liveTextureCount--;\n }\n\n /**\n * Context loss invalidates every texture handle at once. Drop the cache and\n * the count instead of carrying dead handles (deleting them is pointless —\n * the GPU side is already gone) and let the next frames re-upload if the\n * caller keeps drawing; the renderer meanwhile falls back to canvas2d.\n */\n private markLost(): void {\n this.lost = true;\n this.textures = new WeakMap();\n this.liveTextureCount = 0;\n }\n\n private compile(type: number, source: string): WebGLShader {\n const gl = this.gl;\n const shader = gl.createShader(type);\n if (!shader) throw new Error('createShader failed');\n gl.shaderSource(shader, source);\n gl.compileShader(shader);\n if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {\n throw new Error(`shader compile failed: ${gl.getShaderInfoLog(shader)}`);\n }\n return shader;\n }\n\n /**\n * The page's GL texture, uploaded on demand.\n *\n * `pma` is a property of the page's *pixels*, so one image cannot honestly be\n * both: two atlases naming the same image with different `pma:` lines are not\n * a mixed page, one of them is simply wrong about the file. The cache is keyed\n * by the image, so rather than trusting that, a flag that disagrees with the\n * live upload re-uploads under the new one — the pathological case stays\n * correct (at the price of re-uploading while it lasts) instead of silently\n * drawing one of the two atlases wrong.\n */\n private textureFor(page: HTMLImageElement, pma: boolean): WebGLTexture {\n let entry = this.textures.get(page);\n if (entry?.texture) {\n if (entry.pma === pma) return entry.texture;\n this.gl.deleteTexture(entry.texture);\n entry.texture = null;\n this.liveTextureCount--;\n }\n const gl = this.gl;\n const texture = gl.createTexture();\n if (!texture) throw new Error('createTexture failed');\n gl.bindTexture(gl.TEXTURE_2D, texture);\n // Premultiply at upload so blending and the premultiplied canvas agree —\n // unless the page is already premultiplied (`pma: true`), where doing it\n // again is the second multiply that darkens every semi-transparent texel\n // (#37). The blend below is premultiplied source-over either way, so a pma\n // page is simply uploaded as it is: no conversion, nothing lost.\n gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, pma ? 0 : 1);\n gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 0);\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, page);\n // Linear, no mips, clamped — NPOT-safe in WebGL1.\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\n if (!entry) {\n // Nobody retained this page — not a path this package takes, since the\n // renderer retains as it queues each job. Cache it anyway so the batch\n // does not re-upload per flush; with no users only a context loss (or\n // the image being collected, which takes the weak entry with it) clears\n // it, which is exactly the old behavior for a caller that opts out.\n entry = { texture: null, users: 0, pma };\n this.textures.set(page, entry);\n }\n entry.pma = pma;\n entry.texture = texture;\n this.liveTextureCount++;\n return texture;\n }\n}\n\nlet shared: MeshGlBlitter | null | undefined;\n\n/**\n * The module-level blitter, created on first use. Returns null when WebGL is\n * unavailable or the shared context has been lost — callers then stay on the\n * canvas2d path.\n */\nexport function getMeshGlBlitter(): MeshGlBlitter | null {\n if (shared === undefined) {\n try {\n shared = new MeshGlBlitter();\n } catch {\n shared = null;\n }\n }\n return shared && !shared.lost ? shared : null;\n}\n","import { syncedPixelRatio } from './pixelRatio.js';\nimport { type PageSource, type RegionImage, straightAlphaSource } from './DomTexture.js';\nimport { getMeshGlBlitter, type MeshBlitJob } from './MeshGlBlitter.js';\nimport type { BlendMode, PosedClip, PosedFrame, PosedMesh, PosedRegion, PosedSlot } from './posedFrame.js';\n\n/** Rasterizer used for the mesh (deform) tier. */\nexport type MeshBackend = 'canvas2d' | 'webgl';\n\nconst regionVertices = new Float32Array(8);\nconst SVG_NS = 'http://www.w3.org/2000/svg';\n/** Unique tint-filter ids across renderer instances (ids are document-global). */\nlet tintFilterSeq = 0;\n/** Push a point away from (cx, cy) by `amount` pixels. */\nfunction expandPoint(x: number, y: number, cx: number, cy: number, amount: number): [number, number] {\n const dx = x - cx;\n const dy = y - cy;\n const len = Math.sqrt(dx * dx + dy * dy);\n if (len < 1e-6) return [x, y];\n const s = amount / len;\n return [x + dx * s, y + dy * s];\n}\n\n/**\n * Formats one clip-path coordinate, rounded to 1/1000 of the element's local\n * unit so that a pose which recomputes to a bit-different float does not\n * defeat the write cache.\n *\n * Why 1/1000: the local unit is an atlas unit for a rigid `<img>` (the matrix\n * denominator) and a CSS pixel for a mesh canvas, so the worst error this can\n * add on screen is half a quantum times the element's local-to-screen scale.\n * At a 50× upscale — far past anything a skeleton is posed at — that is\n * 0.025 px, an order of magnitude under one device pixel at dpr 3, while\n * still sitting three orders of magnitude above the f32 recomputation jitter\n * of coordinates that run 10²–10³ units. Shortest-round-trip number\n * formatting then keeps every coordinate at three decimals or fewer.\n */\nfunction clipCoord(v: number): string {\n return `${clipNum(v)}px`;\n}\n\n/**\n * The same quantized number without a unit, for `path()` data — SVG path\n * coordinates are user units and a `px` suffix there is a parse error.\n */\nfunction clipNum(v: number): number {\n return Math.round(v * 1000) / 1000;\n}\n\n/**\n * Bound past which a local coordinate is treated as degenerate rather than\n * written. Two reasons, and the second is the hard one: a near-singular\n * element matrix sends the inverse — and with it these coordinates — toward\n * infinity, and JavaScript switches to exponential notation at 1e21, which is\n * not valid CSS. The browser would then drop the whole declaration and the\n * element would render UNCLIPPED, which is the one failure mode a clip must\n * never have. A billion local units is already far outside anything a\n * skeleton poses, so nothing expressible is lost by stopping here.\n */\nconst CLIP_COORD_LIMIT = 1e9;\n\ntype SlotKind = 'image' | 'canvas';\n\ninterface SlotView {\n kind: SlotKind;\n el: HTMLImageElement | HTMLCanvasElement;\n /** Region name currently shown (image kind), to skip src rewrites. */\n regionName: string;\n visible: boolean;\n zIndex: number;\n opacity: number;\n blendMode: BlendMode;\n /** Last transform string written, to skip no-op style writes. */\n transform: string;\n /** Last clip-path string written ('' = none), to skip no-op style writes. */\n clipPath: string;\n /** Current RGB tint; (1,1,1) means untinted (no filter applied). */\n tintR: number;\n tintG: number;\n tintB: number;\n /** Lazily created SVG reference filter for non-white tints. */\n tintId: string;\n tintMatrix: SVGFEColorMatrixElement | null;\n /** Canvas kind: allocated backing-store size (grow-only, quantized). */\n canvasW: number;\n canvasH: number;\n /** Canvas kind: pixelRatio the backing/CSS sizing was computed with. */\n meshRatio: number;\n /**\n * Canvas kind: shape signature of the last raster, for dirty-skipping. The\n * UV and triangle arrays are compared by identity: the frame hands the same\n * objects for the same region and attachment (see PosedMesh), so a new array\n * is a new texture mapping and an old one is not.\n */\n meshUvs: ArrayLike<number> | null;\n meshTriangles: ArrayLike<number> | null;\n meshPage: HTMLImageElement | null;\n meshSequenceIndex: number;\n meshExpand: number;\n meshVertexCount: number;\n /** Backend that produced the last raster — a backend switch re-dirties. */\n meshBackendDrawn: MeshBackend | '';\n /**\n * Canvas-space (bbox-relative) vertices of the last raster. Float64: the\n * compared values are f64 (f32 world vertex minus integer bbox origin);\n * storing them as f32 would round some of them and leave those meshes\n * permanently \"dirty\".\n */\n meshVertices: Float64Array;\n /** The render() call that last drew this view — a view not drawn by the current one is hidden. */\n drawnIn: number;\n}\n\nconst BLEND_CSS: Record<BlendMode, string> = {\n Normal: '',\n Additive: 'plus-lighter',\n Multiply: 'multiply',\n Screen: 'screen',\n};\n\n/**\n * Renders a posed frame (`PosedFrame`) as DOM, split by slot kind:\n *\n * - Region slots (rigid parts) become one absolutely-positioned <img>\n * posed with a single CSS matrix() write per frame — exact, since bone\n * transforms are affine.\n * - Mesh slots (deform parts) each get a small per-part <canvas> sized\n * to the mesh's world bounding box, redrawn per frame — either with the\n * standard per-triangle clip+transform+drawImage mapping (default), or via\n * a shared offscreen WebGL canvas that rect-blits into the same per-part\n * canvases (meshBackend = 'webgl'). Frames where the canvas-space vertices\n * are unchanged reuse the previous raster on both backends.\n *\n * Both element kinds share one stacking context, so draw order interleaves\n * freely via z-index (rear hair canvas < torso img < front hair canvas).\n * The RGB tint the frame carries (slot × attachment × the player's colour) is\n * applied per element with an SVG feColorMatrix reference filter — exact\n * channel multiply, works the same on <img> and <canvas>. Dark (two-color)\n * tint is not expressible that way and is unsupported. A clip the frame\n * carries becomes a CSS clip-path per element, in that element's own local\n * frame (see `clipping`) — which slots a clip covers is decided by the poser's\n * adapter (`frameOf`), not here.\n *\n * Coordinate mapping: the frame is world space, Y-up; CSS is Y-down — world Y\n * is negated. The poser computes everything (bones, constraints, physics,\n * deformed vertices) on the CPU; this class only draws.\n */\nexport class DomRenderer {\n /**\n * Apply the clips the frame carries (default). Each element drawn inside a\n * clip gets a CSS `clip-path` in its own local frame — an element-level\n * feature, so both mesh backends see exactly the same thing and neither\n * raster path knows clipping exists.\n *\n * Which slots a clip covers is the frame's, decided by the adapter on the\n * runtime's semantics (`clipCover` in posedFrame.ts: one clip in force at a\n * time, a second one met while one is in force ignored, a clip covering the\n * slots after its own through its end slot inclusive, an end slot that is\n * the clip's own slot — or one already passed — never ending it). A clip\n * that covers every slot of the frame is the whole-skeleton clip, and it\n * takes a fast path: one `clip-path` on the root instead of one per element.\n * The root is the caller's element, so its inline `clip-path` is borrowed —\n * saved on the first write and restored when the clip stops covering the\n * frame, when `clipping` goes false, and by `dispose()`.\n *\n * False restores the pre-0.6 behaviour: clips are counted in clipSkipCount\n * and nothing is clipped, with any clip-path this renderer wrote removed.\n */\n clipping = true;\n /** Clips applied last frame — distinct clip polygons over the drawn slots. */\n clipCount = 0;\n /**\n * Clips in the frame NOT applied last frame: `clipping` is false, or the\n * polygon has fewer than three points. A clip the runtime itself ignores (a\n * second one met while one is in force, one on an inactive bone) never\n * reaches the frame, so it is not counted here.\n */\n clipSkipCount = 0;\n /**\n * `clip-path` style writes performed last frame, across slot elements and\n * the root, clears included. A static polygon over static elements settles\n * at zero: every clip-path is cached per element exactly as `transform` is.\n */\n clipWriteCount = 0;\n /** Mesh canvases rasterized last frame. */\n meshCount = 0;\n /** Mesh canvases that reused their previous raster last frame. */\n meshReuseCount = 0;\n /**\n * Mesh canvas backing stores (re)allocated last frame. Should drop to zero\n * once an animation reaches its steady state; a persistent nonzero value\n * means GPU surfaces are being recreated per frame (a Safari killer).\n */\n canvasReallocCount = 0;\n /** Triangles rasterized last frame. */\n triangleCount = 0;\n /**\n * How far (px) each triangle's clip polygon is expanded from its centroid.\n * Closes antialiased-clip cracks between adjacent triangles (Safari);\n * set to 0 to see them.\n */\n triangleExpand = 0.5;\n /**\n * Mesh-canvas backing-store pixels per CSS pixel. Defaults to the device\n * pixel ratio. If the caller scales the root element, fold that scale in\n * (e.g. devicePixelRatio * rootScale) so the raster matches the on-screen\n * resolution instead of over- or under-sampling — syncPixelRatio() measures\n * that scale and folds it in for you.\n */\n pixelRatio = typeof devicePixelRatio === 'number' ? devicePixelRatio : 1;\n /**\n * Rasterizer for the mesh (deform) tier. 'canvas2d' (default) maps each\n * triangle with clip+transform+drawImage directly on the per-part canvas.\n * 'webgl' rasterizes every dirty mesh into one shared offscreen WebGL\n * canvas and rect-blits each mesh back onto its per-part canvas — the DOM\n * structure and all element-level behavior (z-index interleave, tint\n * filter, mix-blend-mode, dirty-skip) are identical, only the raster step\n * changes. Motivation: Safari antialiases canvas2d clip paths, so the\n * per-triangle clip mapping pays a per-triangle AA-mask cost in the GPU\n * process that rAF-limits heavy scenes; GL rasterizes shared edges\n * seamlessly (no clip, no crack overdraw) and the blit is an unclipped\n * rect copy. Falls back to 'canvas2d' when WebGL is unavailable or the\n * shared context is lost — see meshBackendActive.\n */\n meshBackend: MeshBackend = 'canvas2d';\n /** Backend that actually rasterized the mesh tier during the last render(). */\n meshBackendActive: MeshBackend = 'canvas2d';\n\n private readonly views = new Map<string, SlotView>();\n /** Counts render() calls: the stamp a view drawn this frame carries (`SlotView.drawnIn`). */\n private frameNumber = 0;\n private readonly pendingJobs: MeshBlitJob[] = [];\n private readonly pendingViews: SlotView[] = [];\n /**\n * Atlas page images this renderer has retained from the shared blitter,\n * one retain each. Allocated on the first webgl mesh job, so a renderer\n * that never leaves canvas2d holds nothing and gives nothing back.\n */\n private glPages: Set<HTMLImageElement> | null = null;\n /**\n * World vertices copied out of the frame. Float32, as the rigid and mesh\n * paths have always read them: the raster, the dirty signature and the\n * clip-path quantization below are calibrated on single-precision\n * coordinates, and the frame's doubles are rounded here once rather than\n * changing what those paths see.\n */\n private scratchVertices = new Float32Array(256);\n private tintDefs: SVGSVGElement | null = null;\n /** The clip whose polygon is loaded in `clipPolygon`, if any. */\n private clipActive: PosedClip | null = null;\n /** The clips counted so far this frame, applied or skipped — one count each. */\n private readonly clipsSeen = new Set<PosedClip>();\n private clipInverse = false;\n /** True while the active clip is served by one clip-path on the root. */\n private clipOnRoot = false;\n /** The active clip polygon in CSS space (Y already negated), flat x,y. */\n private clipPolygon = new Float64Array(0);\n private clipPolygonLength = 0;\n /**\n * The root's inline `clip-path` before this renderer borrowed it; null means\n * not borrowed. The root belongs to the caller, so the fast path gives back\n * exactly the string it found.\n */\n private rootClipSaved: string | null = null;\n /** Last clip-path string written to the root, to skip no-op style writes. */\n private rootClipWritten = '';\n\n /**\n * @param root Positioned element (e.g. position:absolute) that becomes the\n * skeleton origin. The renderer only appends slot elements to it — layout\n * and scaling of the root belong to the caller.\n * @param regionImages Unpacked per-region bitmaps (for the rigid tier),\n * keyed by region name — `PosedRegion.region`.\n * @param pages Page images (for the mesh tier), keyed by page name —\n * `PosedMesh.page`. Read on every mesh draw, so a caller may fill it after\n * construction.\n */\n constructor(\n private readonly root: HTMLElement,\n private readonly regionImages: ReadonlyMap<string, RegionImage>,\n private readonly pages: ReadonlyMap<string, HTMLImageElement> = new Map(),\n ) {}\n\n /**\n * Backing-store pixels currently allocated across the mesh canvases\n * (Σ width × height). Computed on demand from the views — nothing is\n * tracked per frame — so reading it is cheap but not free; the demo reads it\n * with the other counters, twice a second.\n *\n * This is the quantity `pixelRatio` moves quadratically, and the one that\n * makes an oversampling stage visible before the frame rate does: a root\n * scaled down by CSS without that scale folded into `pixelRatio` holds\n * 1/scale² of the backing it needs. Hidden slots are included — their\n * canvases keep their allocation.\n */\n get meshBackingPixels(): number {\n let total = 0;\n for (const view of this.views.values()) {\n if (view.kind === 'canvas') total += view.canvasW * view.canvasH;\n }\n return total;\n }\n\n /**\n * Re-derives `pixelRatio` from the root's effective on-screen scale, so the\n * mesh tier rasters at the resolution the screen actually shows.\n *\n * Mesh canvases are sized in the root's own coordinates, and a CSS transform\n * anywhere above the root — the natural way to build a pan/zoom stage is\n * `transform: scale(zoom)` on an ancestor — rescales them on screen without\n * the renderer seeing it. At zoom z the raster is then oversampled by 1/z per\n * axis, 1/z² in backing pixels: GPU memory and fill rate, not correctness.\n * This folds the measured scale in, `devicePixelRatio × scale`.\n *\n * One layout read per call. The root itself is usually 0×0 (slot elements are\n * absolutely positioned and posed by transforms), so there is no box to\n * measure: a hidden 100×100 px child is appended, measured once with\n * getBoundingClientRect(), and removed again — nothing of it is left behind.\n * It cannot disturb the slot elements either: they interleave by z-index,\n * which applyCommon() writes explicitly on every visible one, so DOM order is\n * not what orders them; and the probe is `visibility: hidden` and gone before\n * anything can paint.\n *\n * The scale is the larger axis of the measured box. An ancestor rotation\n * inflates that axis-aligned box, so the ratio errs high — the safe side:\n * oversampling costs pixels, undersampling costs picture.\n *\n * A move smaller than 0.1% (see PIXEL_RATIO_DEADBAND) changes nothing, and a\n * root that is not laid out (a `display: none` ancestor — the probe measures\n * 0) changes nothing either. Both matter because writing `pixelRatio`\n * reallocates every mesh canvas on the next frame.\n *\n * The renderer never calls this itself. It is a forced synchronous layout,\n * which has no business in a render path — and there is no per-frame layout\n * read anywhere in this class. Call it when a zoom or a layout settles: after\n * a wheel/pinch gesture ends, on a debounced resize, not during the drag.\n *\n * @returns the pixel ratio now in effect (the current one if nothing moved).\n */\n syncPixelRatio(): number {\n this.pixelRatio = syncedPixelRatio(this.root, this.pixelRatio);\n return this.pixelRatio;\n }\n\n /**\n * Draws one frame. Slots the frame does not carry — no attachment, a\n * clipping attachment, an inactive bone, a kind the DOM tier does not draw —\n * are hidden, their elements kept for when they draw again.\n */\n render(frame: PosedFrame): void {\n this.clipCount = 0;\n this.clipSkipCount = 0;\n this.clipWriteCount = 0;\n this.meshCount = 0;\n this.meshReuseCount = 0;\n this.canvasReallocCount = 0;\n this.triangleCount = 0;\n this.clipActive = null;\n this.clipInverse = false;\n this.clipOnRoot = false;\n this.clipsSeen.clear();\n const stamp = ++this.frameNumber;\n const blitter = this.meshBackend === 'webgl' ? getMeshGlBlitter() : null;\n this.meshBackendActive = blitter ? 'webgl' : 'canvas2d';\n const order = frame.order;\n\n // Whole-skeleton fast path: one clip covers every slot of the frame, so\n // every element is inside it — one clip-path on the root beats one per\n // element. The frame shares one clip object across the slots it covers,\n // so \"every slot\" is an identity test. An inverse clip is excluded: its\n // CSS form needs an outer ring around the element's own box, and the root\n // is an origin element with no box to use.\n const first = order.length > 0 ? order[0].clip : undefined;\n if (first && !first.inverse && this.clipping && first.polygon.length >= 6) {\n let whole = true;\n for (let i = 1, n = order.length; i < n && whole; i++) whole = order[i].clip === first;\n if (whole) {\n this.useClip(first);\n this.clipOnRoot = true;\n this.writeRootClip(this.rootClipPath());\n }\n }\n\n for (let i = 0, n = order.length; i < n; i++) {\n const slot = order[i];\n if (!this.clipOnRoot) this.useClip(slot.clip);\n const drawn = slot.kind === 'region' ? this.renderRegion(slot) : this.renderMesh(slot);\n if (drawn) drawn.drawnIn = stamp;\n }\n for (const view of this.views.values()) if (view.drawnIn !== stamp) this.hide(view);\n // Only a clip that covered the whole frame keeps the root's style; every\n // other frame hands the caller's inline value back.\n if (!this.clipOnRoot) this.releaseRootClip();\n\n if (this.pendingJobs.length) {\n if (!blitter || !blitter.flush(this.pendingJobs)) {\n // Context lost mid-frame: rasterize this batch on the 2d path so the\n // frame stays complete; the next render() re-selects the backend.\n for (let i = 0; i < this.pendingJobs.length; i++) {\n const job = this.pendingJobs[i];\n this.pendingViews[i].meshBackendDrawn = 'canvas2d';\n this.rasterizeMesh2d(\n job.canvas,\n // The 2d path wants straight alpha where the upload wanted it\n // premultiplied; the derivation is cached, so this costs a lookup.\n straightAlphaSource(job.page, job.pma),\n job.vertices,\n job.uvs,\n job.triangles,\n job.ratio,\n );\n }\n }\n this.pendingJobs.length = 0;\n this.pendingViews.length = 0;\n }\n }\n\n /**\n * Removes every element this renderer added to the root (slot elements and\n * the tint filter defs), restores the root's own inline `clip-path` if the\n * whole-skeleton clip path borrowed it, and hands the atlas pages it\n * uploaded back to the shared GL blitter — the one resource here that outlives the instance, so\n * the one that has to be given back explicitly (GPU memory, and no garbage\n * collector feels pressure from it). The pages are reference-counted there:\n * a page another live renderer still draws stays uploaded, and the texture\n * is deleted only when the last user of it is disposed.\n *\n * The region bitmaps are deliberately untouched: the map is the caller's,\n * and one map is normally shared by many renderers (disposing one instance\n * must not blind the others). Free the unpacked blob URLs with\n * revokeRegions() once no renderer needs them.\n *\n * Idempotent: the retained-page ledger is cleared here, so a second call\n * releases nothing a second time.\n */\n dispose(): void {\n // The root is the caller's element and outlives this renderer, so the\n // borrowed inline clip-path goes back before the slot elements go.\n this.releaseRootClip();\n for (const view of this.views.values()) view.el.remove();\n this.views.clear();\n this.tintDefs?.remove();\n this.tintDefs = null;\n if (this.glPages) {\n const blitter = getMeshGlBlitter();\n if (blitter) for (const page of this.glPages) blitter.release(page);\n this.glPages = null;\n }\n }\n\n // --- rigid tier -----------------------------------------------------------\n\n private renderRegion(slot: PosedRegion): SlotView | null {\n const regionImage = this.regionImages.get(slot.region);\n if (!regionImage) return null;\n\n const view = this.view(slot.slot, 'image');\n const img = view.el as HTMLImageElement;\n if (view.regionName !== slot.region) {\n view.regionName = slot.region;\n img.src = regionImage.url;\n img.width = regionImage.width;\n img.height = regionImage.height;\n }\n\n const corners = slot.corners;\n for (let v = 0; v < 8; v++) regionVertices[v] = corners[v];\n // Corner order is BL, UL, UR, BR — the runtime's, which the poser keeps:\n // the region's UVs run (u,v2), (u,v), (u2,v), (u2,v2) in that order.\n // (The br/bl/ul/ur comments inside spine-core's computeWorldVertices are\n // stale.) Flip Y for CSS (the frame is Y-up).\n const blx = regionVertices[0], bly = -regionVertices[1];\n const ulx = regionVertices[2], uly = -regionVertices[3];\n const urx = regionVertices[4], ury = -regionVertices[5];\n\n const w = regionImage.width;\n const h = regionImage.height;\n const a = (urx - ulx) / w;\n const b = (ury - uly) / w;\n const c = (blx - ulx) / h;\n const d = (bly - uly) / h;\n this.setTransform(view, `matrix(${a},${b},${c},${d},${ulx},${uly})`);\n // Rigid elements carry a full affine, so the clip polygon rides its\n // inverse into the local (atlas-unit) frame the <img> box spans.\n this.applyClip(view, a, b, c, d, ulx, uly, w, h);\n\n this.applyCommon(view, slot);\n return view;\n }\n\n // --- deform tier ----------------------------------------------------------\n\n private renderMesh(slot: PosedMesh): SlotView | null {\n const sequenceIndex = slot.sequence;\n const page = this.pages.get(slot.page);\n if (!page) return null;\n // Which alpha convention the page's texels are in. The two backends consume\n // opposite ones — GL wants them premultiplied, `drawImage` wants them\n // straight — so this decides what each is handed, never what it does.\n const pma = slot.pma;\n\n const source = slot.vertices;\n const count = source.length;\n if (this.scratchVertices.length < count) this.scratchVertices = new Float32Array(count);\n const vertices = this.scratchVertices;\n for (let v = 0; v < count; v++) vertices[v] = source[v];\n\n // World bounds (in CSS coords: Y negated).\n let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;\n for (let v = 0; v < count; v += 2) {\n const x = vertices[v];\n const y = -vertices[v + 1];\n vertices[v + 1] = y;\n if (x < minX) minX = x;\n if (x > maxX) maxX = x;\n if (y < minY) minY = y;\n if (y > maxY) maxY = y;\n }\n const pad = 1;\n minX = Math.floor(minX) - pad;\n minY = Math.floor(minY) - pad;\n const w = Math.ceil(maxX) + pad - minX;\n const h = Math.ceil(maxY) + pad - minY;\n if (w <= 0 || h <= 0) return null;\n\n const view = this.view(slot.slot, 'canvas');\n const canvas = view.el as HTMLCanvasElement;\n const ratio = this.pixelRatio;\n const uvs = slot.uvs;\n const triangles = slot.triangles;\n let dirty =\n view.meshUvs !== uvs ||\n view.meshTriangles !== triangles ||\n view.meshPage !== page ||\n view.meshSequenceIndex !== sequenceIndex ||\n view.meshExpand !== this.triangleExpand ||\n view.meshVertexCount !== count ||\n view.meshBackendDrawn !== this.meshBackendActive;\n // The backing store only grows, in 32-device-px steps. Setting\n // canvas.width recreates the GPU surface, and a deforming mesh changes\n // its bbox every frame — reallocating every mesh canvas per frame\n // stalled real Safari to ~3 fps while the JS split showed ~4 ms (the\n // cost lives in the compositor, invisible to in-callback timing). With\n // grow-only quantized backing, steady-state animation reallocates\n // nothing. A pixelRatio change is the one exception to grow-only: it\n // reallocates every mesh canvas anyway, so the new size comes from the\n // new need alone. Keeping the old size as a floor there would make a\n // ratio *drop* pay the reallocation and keep every oversized pixel — the\n // backing would never come back down to what that ratio needs. The CSS\n // size mirrors the whole backing so the pixel mapping stays 1:1; the mesh\n // draws into the top-left w×h logical region and the rest stays\n // transparent.\n const needW = Math.max(1, Math.round(w * ratio));\n const needH = Math.max(1, Math.round(h * ratio));\n const ratioChanged = view.meshRatio !== ratio;\n if (needW > view.canvasW || needH > view.canvasH || ratioChanged) {\n // 25% slack: at low fps the animation is sampled sparsely, so new bbox\n // maxima keep being discovered for many seconds — allocate ahead of the\n // curve instead of chasing it.\n const step = 32;\n const floorW = ratioChanged ? 0 : view.canvasW;\n const floorH = ratioChanged ? 0 : view.canvasH;\n view.canvasW = Math.ceil(Math.max(needW * 1.25, floorW) / step) * step;\n view.canvasH = Math.ceil(Math.max(needH * 1.25, floorH) / step) * step;\n view.meshRatio = ratio;\n canvas.width = view.canvasW;\n canvas.height = view.canvasH;\n canvas.style.width = `${view.canvasW / ratio}px`;\n canvas.style.height = `${view.canvasH / ratio}px`;\n this.canvasReallocCount++;\n dirty = true;\n }\n\n // Canvas-space vertices: identical values mean last frame's raster is\n // still exact (static pose, or the part moved by whole pixels), so the\n // per-triangle redraw can be skipped — the CSS translate below keeps\n // tracking the part. This is the main WebKit cost lever: idle skeletons\n // stop paying the raster entirely.\n if (view.meshVertices.length < count) {\n view.meshVertices = new Float64Array(count);\n dirty = true;\n }\n const rel = view.meshVertices;\n for (let v = 0; v < count; v += 2) {\n const x = vertices[v] - minX;\n const y = vertices[v + 1] - minY;\n if (rel[v] !== x || rel[v + 1] !== y) dirty = true;\n rel[v] = x;\n rel[v + 1] = y;\n }\n\n this.setTransform(view, `translate(${minX}px,${minY}px)`);\n // A mesh canvas is posed by a translate only, so its local frame is the\n // CSS-space polygon minus that translate. The clip never reaches the\n // raster: it is not part of the dirty signature, and a mesh whose vertices\n // held still still reuses its raster under a moving clip.\n this.applyClip(view, 1, 0, 0, 1, minX, minY, view.canvasW / ratio, view.canvasH / ratio);\n\n if (!dirty) {\n this.meshReuseCount++;\n } else {\n view.meshUvs = uvs;\n view.meshTriangles = triangles;\n view.meshPage = page;\n view.meshSequenceIndex = sequenceIndex;\n view.meshExpand = this.triangleExpand;\n view.meshVertexCount = count;\n view.meshBackendDrawn = this.meshBackendActive;\n\n if (this.meshBackendActive === 'webgl') {\n // Queued, not drawn: render() flushes the whole batch through the\n // shared GL context once the slot loop is done. `rel` is this view's\n // own signature array — nothing mutates it before the flush.\n this.pendingJobs.push({\n canvas,\n page,\n pma,\n vertices: rel,\n uvs,\n triangles,\n ratio,\n width: Math.min(view.canvasW, Math.ceil(w * ratio)),\n height: Math.min(view.canvasH, Math.ceil(h * ratio)),\n });\n this.pendingViews.push(view);\n this.retainPage(page);\n } else {\n this.rasterizeMesh2d(canvas, straightAlphaSource(page, pma), rel, uvs, triangles, ratio);\n }\n this.meshCount++;\n this.triangleCount += triangles.length / 3;\n }\n\n this.applyCommon(view, slot);\n return view;\n }\n\n /**\n * Declares this renderer a user of `page` with the shared blitter, once per\n * page — the counterpart of the release in dispose(). The set is this\n * renderer's own ledger, so sharing one page across renderers works by\n * counting rather than by guessing. On the render path this costs one\n * Set.has per queued mesh job and allocates nothing after the first page.\n */\n private retainPage(page: HTMLImageElement): void {\n const pages = (this.glPages ??= new Set<HTMLImageElement>());\n if (pages.has(page)) return;\n // Null only if the context died between the backend pick and here; the\n // flush then fails too and the batch falls back to canvas2d.\n const blitter = getMeshGlBlitter();\n if (!blitter) return;\n pages.add(page);\n blitter.retain(page);\n }\n\n /** The canvas2d raster path: clear the backing, map each triangle. */\n private rasterizeMesh2d(\n canvas: HTMLCanvasElement,\n page: PageSource,\n vertices: Float64Array,\n uvs: ArrayLike<number>,\n triangles: ArrayLike<number>,\n ratio: number,\n ): void {\n const ctx = canvas.getContext('2d');\n if (!ctx) return;\n // Clear the full backing: the previous frame's bbox (and so its drawn\n // region) may have been larger than today's.\n ctx.setTransform(1, 0, 0, 1, 0, 0);\n ctx.clearRect(0, 0, canvas.width, canvas.height);\n ctx.setTransform(ratio, 0, 0, ratio, 0, 0);\n\n // Texel addressing, shared with the GL blitter: a normalized UV maps to\n // `uv * size` in the continuous texture frame where the page spans\n // [0, size] and texel i covers [i, i+1). drawImage-under-a-transform and\n // texture2D() both read that frame, so both backends land on the same\n // source pixels. (No half-texel term: the affine below *maps* corners, it\n // does not sample — see drawTriangle.) `page` is the page image, or its\n // straight-alpha derivation on a premultiplied one; the derivation is the\n // image's own natural size, so the frame is the same either way.\n const uw = page.width;\n const uh = page.height;\n for (let t = 0; t < triangles.length; t += 3) {\n const i0 = triangles[t] * 2;\n const i1 = triangles[t + 1] * 2;\n const i2 = triangles[t + 2] * 2;\n this.drawTriangle(\n ctx, page,\n vertices[i0], vertices[i0 + 1], uvs[i0] * uw, uvs[i0 + 1] * uh,\n vertices[i1], vertices[i1 + 1], uvs[i1] * uw, uvs[i1 + 1] * uh,\n vertices[i2], vertices[i2 + 1], uvs[i2] * uw, uvs[i2 + 1] * uh,\n );\n }\n }\n\n /**\n * Standard canvas triangle texture mapping (same math as the official\n * spine-canvas renderer): derive the affine that sends the triangle's\n * texture-space corners to its screen-space corners, clip, draw the page —\n * but only the part of the page this triangle can show (see below).\n *\n * The clip polygon is expanded outward from the centroid by a fraction of\n * a pixel. Browsers that antialias clip paths (Safari) otherwise leave\n * hairline cracks between adjacent triangles; the expanded clips overlap\n * into the neighbouring triangle, and since the texture is continuous\n * across the shared edge the overlap draws the same pixels — cracks close\n * with no visible cost. The texture-mapping affine itself stays exact.\n *\n * ## Why a source sub-rect instead of the whole page\n *\n * The draw is a 9-argument `drawImage` whose source rect covers exactly what\n * the clip can reveal, placed at the same texture-space position, so the\n * mapping is identical to drawing the whole page — the same affine, the same\n * texels, only fewer of them offered to the rasterizer.\n *\n * That is not an optimization. Linux WebKit — the software rasterizer, the\n * only engine this has been observed on; Chromium and macOS WebKit never show\n * it — garbles individual triangles when the whole page is drawn under a\n * steep per-triangle affine: read off the parity dump, head/goggles/foot\n * triangles land with displaced texture while the webgl capture of the same\n * pose stays clean. Switching this one call to a source sub-rect — the only\n * variable changed — took that platform's bad-pixel counts from 1042 to 2\n * (hoverboard), 231 to 4 (portal) and 803 to 3 (walk + tint), and left every\n * Chromium capture byte-identical. [measured on the ubuntu CI runner through\n * PARITY_DUMP: first with a fixed 2-texel pad (run 35209262693), then with\n * the derived rect below — the same counts (run 35213286993).] WHY that\n * rasterizer garbles the whole-page form is not identified; steep affines\n * making whole-page coordinates large is a suspicion, not a measurement. The\n * sub-rect sidesteps it. (Moving `clip()` before `transform()` was tried as a\n * separate one-variable experiment: every number came back identical, so the\n * clip path is not the cause.)\n *\n * ## How the sub-rect is derived\n *\n * It must provably cover everything the clip can reveal, which is the\n * *expanded* polygon, not the triangle. So each clip corner's canvas-space\n * displacement is pushed back through the inverse of the 2×2 affine into\n * texture space, the bounding box is taken over the displaced corners, one\n * texel of bilinear support is added, and the result is floor/ceil'd to texel\n * boundaries (so the sub-rect itself resamples nothing) and clamped to the\n * page. A fixed pad would not do: the texture-space reach of the expansion is\n * `triangleExpand` times the local texels-per-canvas-unit, which on the\n * demo's own meshes ranges from ~0.26 texels on a typical triangle to ~8.6 on\n * a foreshortened one. Under-padding lets the rim of the overdraw sample\n * nothing, which brings back the very seams the overdraw exists to close.\n *\n * No half-texel offset is applied to the incoming u/v: the `(i + 0.5) / size`\n * texel-centre convention belongs to *sampling* (landing inside the intended\n * texel instead of on a filter boundary). This solves for the affine that\n * sends three source corners to three destination corners; the rasterizer\n * then samples continuously along that map. Biasing all three corners by\n * half a texel would translate the texture against the geometry — the very\n * class of offset the `uv * size` addressing removes.\n */\n private drawTriangle(\n ctx: CanvasRenderingContext2D, img: PageSource,\n x0: number, y0: number, u0: number, v0: number,\n x1: number, y1: number, u1: number, v1: number,\n x2: number, y2: number, u2: number, v2: number,\n ): void {\n drawTexturedTriangle(ctx, img, this.triangleExpand, x0, y0, u0, v0, x1, y1, u1, v1, x2, y2, u2, v2);\n }\n\n // --- clipping tier ---------------------------------------------------------\n\n /**\n * Makes `clip` the clip in force for the slot about to be drawn, loading its\n * polygon when it is not the one already loaded. Each clip object is counted\n * once per frame — in clipCount when applied, in clipSkipCount when\n * `clipping` is off or the polygon has fewer than three points (no clip is\n * in force then, so the slot draws unclipped, as the runtime would).\n *\n * The polygon is the poser's world-space one, and the only things done to it\n * here are the single-precision read the vertex paths share and the Y\n * negation the rest of the renderer already applies. It is NOT convexified\n * or triangulated the way the CPU clipper does — CSS `polygon()` takes a\n * concave polygon directly, so the decomposition that exists to feed a\n * triangle rasterizer has no job here.\n */\n private useClip(clip: PosedClip | undefined): void {\n if (!clip) {\n this.clipActive = null;\n return;\n }\n if (clip === this.clipActive) return;\n const count = clip.polygon.length;\n const counted = this.clipsSeen.has(clip);\n if (!this.clipping || count < 6) {\n if (!counted) {\n this.clipsSeen.add(clip);\n this.clipSkipCount++;\n }\n this.clipActive = null;\n return;\n }\n if (!counted) {\n this.clipsSeen.add(clip);\n this.clipCount++;\n }\n const polygon = clip.polygon;\n if (this.scratchVertices.length < count) this.scratchVertices = new Float32Array(count);\n const world = this.scratchVertices;\n for (let v = 0; v < count; v++) world[v] = polygon[v];\n if (this.clipPolygon.length < count) this.clipPolygon = new Float64Array(count);\n const poly = this.clipPolygon;\n for (let v = 0; v < count; v += 2) {\n poly[v] = world[v];\n poly[v + 1] = -world[v + 1]; // The frame is Y-up, CSS is Y-down.\n }\n this.clipPolygonLength = count;\n this.clipActive = clip;\n this.clipInverse = clip.inverse;\n }\n\n /**\n * Writes (or clears) this element's clip-path. `a…f` is the element's own\n * CSS transform, and the world polygon is carried through its INVERSE:\n * clip-path is resolved in the element's local frame and then transformed\n * along with the element, so the polygon has to arrive there already.\n *\n * `transform-origin` is `0 0` on every slot element (see view()), so the\n * matrix maps local (0,0) to (e,f) with no origin term to undo, and\n * `left/top: 0` puts the border box — clip-path's reference box — on that\n * same local origin.\n */\n private applyClip(\n view: SlotView,\n a: number,\n b: number,\n c: number,\n d: number,\n e: number,\n f: number,\n boxW: number,\n boxH: number,\n ): void {\n if (!this.clipActive || this.clipOnRoot) {\n this.setClipPath(view, '');\n return;\n }\n const det = a * d - b * c;\n // Singular: the element is collapsed onto a line or a point and draws\n // nothing, so there is no clip to express and no style write to pay for.\n if (det === 0) return;\n const inv = 1 / det;\n const poly = this.clipPolygon;\n const n = this.clipPolygonLength;\n // An inverse clip shows what is OUTSIDE the polygon. That shape has a hole\n // in it, so it needs TWO rings — an outer one and the polygon — and\n // `polygon()` cannot carry two: it is one closed ring, and listing a box\n // and a polygon inside it just makes one self-intersecting ring whose\n // even-odd fill leaves a wedge of the seam between them (measured, on a\n // corner of spineboy's boot). `path()` takes subpaths, so an inverse clip\n // is written as two of them with the even-odd rule. The outer ring is the\n // element's own box: the element paints nothing outside it anyway, so\n // box-minus-polygon is exactly the visible part of the inverse region.\n const inverse = this.clipInverse;\n let s = inverse\n ? `path(evenodd,'M0 0H${clipNum(boxW)}V${clipNum(boxH)}H0Z`\n : 'polygon(';\n for (let v = 0; v < n; v += 2) {\n const dx = poly[v] - e;\n const dy = poly[v + 1] - f;\n const lx = (d * dx - c * dy) * inv;\n const ly = (a * dy - b * dx) * inv;\n // Near-singular matrices blow the inverse up; see CLIP_COORD_LIMIT for\n // why an unwritable coordinate must not become a written-and-ignored one.\n if (!(Math.abs(lx) <= CLIP_COORD_LIMIT) || !(Math.abs(ly) <= CLIP_COORD_LIMIT)) return;\n if (inverse) {\n s += `${v > 0 ? 'L' : 'M'}${clipNum(lx)} ${clipNum(ly)}`;\n } else {\n s += `${v > 0 ? ',' : ''}${clipCoord(lx)} ${clipCoord(ly)}`;\n }\n }\n this.setClipPath(view, inverse ? `${s}Z')` : `${s})`);\n }\n\n private setClipPath(view: SlotView, clipPath: string): void {\n if (view.clipPath === clipPath) return;\n view.clipPath = clipPath;\n view.el.style.clipPath = clipPath;\n this.clipWriteCount++;\n }\n\n /** The active polygon in the root's own frame — no element transform. */\n private rootClipPath(): string {\n const poly = this.clipPolygon;\n let s = 'polygon(';\n for (let v = 0, n = this.clipPolygonLength; v < n; v += 2) {\n if (v > 0) s += ',';\n s += `${clipCoord(poly[v])} ${clipCoord(poly[v + 1])}`;\n }\n return `${s})`;\n }\n\n private writeRootClip(clipPath: string): void {\n // Borrow the caller's inline value once, so releaseRootClip gives back\n // exactly what was there. Reading `.style` is CSSOM, not a layout read.\n if (this.rootClipSaved === null) this.rootClipSaved = this.root.style.clipPath;\n if (this.rootClipWritten === clipPath) return;\n this.rootClipWritten = clipPath;\n this.root.style.clipPath = clipPath;\n this.clipWriteCount++;\n }\n\n private releaseRootClip(): void {\n if (this.rootClipSaved === null) return;\n this.root.style.clipPath = this.rootClipSaved;\n this.rootClipSaved = null;\n this.rootClipWritten = '';\n this.clipWriteCount++;\n }\n\n // --- shared plumbing -------------------------------------------------------\n\n private setTransform(view: SlotView, transform: string): void {\n if (view.transform !== transform) {\n view.transform = transform;\n view.el.style.transform = transform;\n }\n }\n\n private applyCommon(view: SlotView, slot: PosedSlot): void {\n const zIndex = slot.z;\n const tint = slot.tint;\n if (view.zIndex !== zIndex) {\n view.zIndex = zIndex;\n view.el.style.zIndex = String(zIndex);\n }\n const alpha = tint[3];\n if (view.opacity !== alpha) {\n view.opacity = alpha;\n view.el.style.opacity = alpha === 1 ? '' : String(alpha);\n }\n // RGB tint (uniform per slot) rides an feColorMatrix reference filter:\n // scaling the channels is an exact multiply, applies to <img> and\n // <canvas> alike, and never touches the raster. Needs reference-filter\n // support (Safari 15+).\n const r = tint[0];\n const g = tint[1];\n const b = tint[2];\n if (view.tintR !== r || view.tintG !== g || view.tintB !== b) {\n view.tintR = r;\n view.tintG = g;\n view.tintB = b;\n if (r === 1 && g === 1 && b === 1) {\n view.el.style.filter = '';\n } else {\n this.tintMatrixFor(view).setAttribute(\n 'values',\n `${r} 0 0 0 0 0 ${g} 0 0 0 0 0 ${b} 0 0 0 0 0 1 0`,\n );\n view.el.style.filter = `url(#${view.tintId})`;\n }\n }\n const blendMode = slot.blend;\n if (view.blendMode !== blendMode) {\n view.blendMode = blendMode;\n view.el.style.mixBlendMode = BLEND_CSS[blendMode];\n }\n if (!view.visible) {\n view.visible = true;\n view.el.style.display = '';\n }\n }\n\n private tintMatrixFor(view: SlotView): SVGFEColorMatrixElement {\n if (view.tintMatrix) return view.tintMatrix;\n if (!this.tintDefs) {\n const svg = document.createElementNS(SVG_NS, 'svg');\n svg.setAttribute('width', '0');\n svg.setAttribute('height', '0');\n svg.style.position = 'absolute';\n this.root.appendChild(svg);\n this.tintDefs = svg;\n }\n const filter = document.createElementNS(SVG_NS, 'filter');\n view.tintId = `rig-play-tint-${tintFilterSeq++}`;\n filter.setAttribute('id', view.tintId);\n // Filter math must happen in sRGB to match Spine's color multiply\n // (SVG filters default to linearRGB).\n filter.setAttribute('color-interpolation-filters', 'sRGB');\n const matrix = document.createElementNS(SVG_NS, 'feColorMatrix');\n matrix.setAttribute('in', 'SourceGraphic');\n matrix.setAttribute('type', 'matrix');\n filter.appendChild(matrix);\n this.tintDefs.appendChild(filter);\n view.tintMatrix = matrix;\n return matrix;\n }\n\n private view(slot: string, kind: SlotKind): SlotView {\n let view = this.views.get(slot);\n if (view && view.kind !== kind) {\n view.el.remove();\n view.tintMatrix?.parentElement?.remove();\n view = undefined;\n }\n if (!view) {\n const el = kind === 'image' ? document.createElement('img') : document.createElement('canvas');\n if (el instanceof HTMLImageElement) el.draggable = false;\n el.style.position = 'absolute';\n el.style.left = '0';\n el.style.top = '0';\n el.style.transformOrigin = '0 0';\n el.style.pointerEvents = 'none';\n el.style.userSelect = 'none';\n el.style.display = 'none';\n view = {\n kind,\n el,\n regionName: '',\n visible: false,\n zIndex: -1,\n opacity: 1,\n blendMode: 'Normal',\n transform: '',\n clipPath: '',\n tintR: 1,\n tintG: 1,\n tintB: 1,\n tintId: '',\n tintMatrix: null,\n canvasW: 0,\n canvasH: 0,\n meshRatio: -1,\n meshUvs: null,\n meshTriangles: null,\n meshPage: null,\n meshSequenceIndex: -1,\n meshExpand: -1,\n meshVertexCount: -1,\n meshBackendDrawn: '',\n meshVertices: new Float64Array(0),\n drawnIn: 0,\n };\n this.views.set(slot, view);\n this.root.appendChild(el);\n }\n return view;\n }\n\n private hide(view: SlotView): void {\n if (view.visible) {\n view.visible = false;\n view.el.style.display = 'none';\n }\n // A hidden element keeps no clip-path: one left behind would sit there\n // stale until the slot draws again, and \"nothing is clipped\" has to be\n // true of the DOM, not only of what gets painted. Cached like every other\n // write, so the sweep costs one write per element, once.\n this.setClipPath(view, '');\n }\n}\n\n/**\n * The body of `DomRenderer.drawTriangle` (see it for the mapping, the clip\n * overdraw and the source sub-rect), as a function so the canvas render mode's\n * 2d fallback draws its triangles through the same code.\n *\n * @internal Not part of the package API.\n */\nexport function drawTexturedTriangle(\n ctx: CanvasRenderingContext2D, img: PageSource, expand: number,\n x0: number, y0: number, u0: number, v0: number,\n x1: number, y1: number, u1: number, v1: number,\n x2: number, y2: number, u2: number, v2: number,\n): void {\n const cx = (x0 + x1 + x2) / 3;\n const cy = (y0 + y1 + y2) / 3;\n const [px0, py0] = expandPoint(x0, y0, cx, cy, expand);\n const [px1, py1] = expandPoint(x1, y1, cx, cy, expand);\n const [px2, py2] = expandPoint(x2, y2, cx, cy, expand);\n ctx.beginPath();\n ctx.moveTo(px0, py0);\n ctx.lineTo(px1, py1);\n ctx.lineTo(px2, py2);\n ctx.closePath();\n\n // Edge vectors, in canvas space and in texture space.\n const ex1 = x1 - x0, ey1 = y1 - y0;\n const ex2 = x2 - x0, ey2 = y2 - y0;\n const eu1 = u1 - u0, ev1 = v1 - v0;\n const eu2 = u2 - u0, ev2 = v2 - v0;\n\n let det = eu1 * ev2 - eu2 * ev1;\n if (det === 0) return;\n det = 1 / det;\n\n const a = (ev2 * ex1 - ev1 * ex2) * det;\n const b = (ev2 * ey1 - ev1 * ey2) * det;\n const c = (eu1 * ex2 - eu2 * ex1) * det;\n const d = (eu1 * ey2 - eu2 * ey1) * det;\n const e = x0 - a * u0 - c * v0;\n const f = y0 - b * u0 - d * v0;\n\n // Texture-space bounds of the clip polygon. The triangle's own corners\n // first, then the three expansion offsets carried back through the inverse\n // of [[a, c], [b, d]] — the clip reaches exactly that far and no further.\n let minU = Math.min(u0, u1, u2);\n let maxU = Math.max(u0, u1, u2);\n let minV = Math.min(v0, v1, v2);\n let maxV = Math.max(v0, v1, v2);\n const detM = a * d - b * c;\n if (detM !== 0) {\n const im = 1 / detM;\n const ia = d * im, ic = -c * im, ib = -b * im, id = a * im;\n let gx = px0 - x0, gy = py0 - y0;\n let tu = u0 + ia * gx + ic * gy, tv = v0 + ib * gx + id * gy;\n minU = Math.min(minU, tu); maxU = Math.max(maxU, tu);\n minV = Math.min(minV, tv); maxV = Math.max(maxV, tv);\n gx = px1 - x1; gy = py1 - y1;\n tu = u1 + ia * gx + ic * gy; tv = v1 + ib * gx + id * gy;\n minU = Math.min(minU, tu); maxU = Math.max(maxU, tu);\n minV = Math.min(minV, tv); maxV = Math.max(maxV, tv);\n gx = px2 - x2; gy = py2 - y2;\n tu = u2 + ia * gx + ic * gy; tv = v2 + ib * gx + id * gy;\n minU = Math.min(minU, tu); maxU = Math.max(maxU, tu);\n minV = Math.min(minV, tv); maxV = Math.max(maxV, tv);\n }\n // One texel of bilinear support on every side, snapped outward to texel\n // boundaries, clamped to the page. Source rect and destination rect are the\n // same rect in texture space, so the affine below maps it exactly as it\n // mapped the whole page.\n const sx = Math.max(0, Math.floor(minU - 1));\n const sy = Math.max(0, Math.floor(minV - 1));\n const sw = Math.min(img.width, Math.ceil(maxU + 1)) - sx;\n const sh = Math.min(img.height, Math.ceil(maxV + 1)) - sy;\n if (!(sw > 0) || !(sh > 0)) return;\n\n ctx.save();\n ctx.transform(a, b, c, d, e, f);\n ctx.clip();\n ctx.drawImage(img, sx, sy, sw, sh, sx, sy, sw, sh);\n ctx.restore();\n}\n","import { syncedPixelRatio } from './pixelRatio.js';\nimport { clipThrough, REGION_TRIANGLES } from 'rig-c/core';\nimport { drawTexturedTriangle } from './DomRenderer.js';\nimport { type PageSource, straightAlphaSource } from './DomTexture.js';\nimport { type FrameRun, getMeshGlBlitter } from './MeshGlBlitter.js';\nimport type { BlendMode, PosedClip, PosedFrame, PosedSlot } from './posedFrame.js';\n\n/** What actually drew the last frame of a `CanvasRenderer`. */\nexport type CanvasBackend = 'webgl' | 'canvas2d';\n\n/** A rectangle of world space, Y up: `x`, `y` is its bottom-left corner. */\nexport interface CanvasViewport {\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\nconst BLEND_CODE: Record<BlendMode, number> = { Normal: 0, Additive: 1, Multiply: 2, Screen: 3 };\nconst COMPOSITE: Record<BlendMode, GlobalCompositeOperation> = {\n Normal: 'source-over',\n Additive: 'lighter',\n Multiply: 'multiply',\n Screen: 'screen',\n};\n/** Root units added round the drawn bounds when the automatic viewport grows. */\nconst GROW_PAD = 16;\n\n/**\n * Renders a posed frame (`PosedFrame`) into **one `<canvas>`** — the canvas\n * render mode, beside the DOM tier (`DomRenderer`) and with the same\n * `render(frame)` interface.\n *\n * Every slot is drawn as textured triangles straight from its atlas page — a\n * region as two triangles over its four corners and its page UVs, a mesh as its\n * own triangles — through the **shared module-level WebGL context** of the mesh\n * blitter (`MeshGlBlitter.ts`), into one rect of its offscreen buffer, and the\n * rect is copied onto this renderer's visible canvas with one `drawImage`. No\n * context is created per renderer, so any number of players draw under the\n * browser's ~16-context cap, and the page textures are shared and\n * reference-counted with every other renderer on the page.\n *\n * - **Tint** (slot × attachment × the player's colour) is a vertex colour,\n * premultiplied by its alpha; the **dark** (two-colour) tint is a second\n * vertex colour, carried only when some slot of the frame has one.\n * - **Blend** is batch state: a run of triangles ends wherever the page or the\n * blend mode changes (`drawCalls`, and `blendFlushes` for the blend changes).\n * The blends are composed inside this canvas's own rect, which starts\n * transparent — an additive or multiply slot meets the slots under it, not\n * the page behind the canvas.\n * - **Clipping** is the core's cut: every triangle a clip covers goes through\n * `clipThrough` from `rig-c/core` (convex polygons by the runtime's measured\n * rule, concave ones into convex pieces, inverse clips as the hull's\n * outside). No stencil, no `clip-path`.\n * - **Projection**: the canvas covers a rect of the root's own coordinates\n * (world x, world −y — the DOM tier's frame), so a world point lands at\n * `((x − left) · pixelRatio, (−y − top) · pixelRatio)` device px. That rect\n * is the caller's `viewport` when set, and otherwise grows to cover what the\n * frames draw (grow-only, so steady animation reallocates nothing).\n * - **Dirty-skip**: a frame whose record equals the last one drawn — vertex\n * arrays, tints, order, clips, pages — draws nothing (`framesReused`).\n *\n * When WebGL is unavailable or the shared context is lost, the frame is drawn\n * on the same visible canvas with canvas2d: regions by `drawImage` under their\n * affine, meshes and clipped pieces by the DOM tier's per-triangle mapping.\n * That fallback multiplies **alpha only** — RGB and dark tints are not drawn\n * there (`ctx.filter` is not available on Safari) — and it is a safety net,\n * not the measured path.\n */\nexport class CanvasRenderer {\n /**\n * Backing-store pixels per root CSS pixel; defaults to the device pixel\n * ratio. A root under a CSS-scaled ancestor rasters at the wrong resolution\n * until the scale is folded in — `syncPixelRatio()` measures it, as for the\n * DOM tier. The next `render` sizes the backing store to the new ratio.\n */\n pixelRatio = typeof devicePixelRatio === 'number' ? devicePixelRatio : 1;\n /** Apply the clips the frame carries (default). False draws every slot unclipped and counts the clips in `clipSkipCount`. */\n clipping = true;\n /**\n * The world rect the canvas covers. Null (default) sizes it from the frames\n * themselves: it grows to cover everything drawn and never shrinks. Set it to\n * pin the canvas to a stage box; what falls outside is not drawn.\n */\n viewport: CanvasViewport | null = null;\n /** The backend to draw with: 'webgl' (default) through the shared context, or 'canvas2d' to force the fallback. */\n backend: CanvasBackend = 'webgl';\n /** What drew the last frame (or would have, had it not been reused). */\n backendActive: CanvasBackend = 'webgl';\n /** The visible canvas — the renderer's one element in the root. */\n readonly canvas: HTMLCanvasElement;\n\n /** Draw calls issued last frame — one per run of one page under one blend. */\n drawCalls = 0;\n /** Of those runs, how many began because the blend mode changed. */\n blendFlushes = 0;\n /** Triangles drawn last frame, clipped pieces counted as cut. */\n trianglesDrawn = 0;\n /** 1 when the last render() found the record unchanged and drew nothing, else 0. */\n framesReused = 0;\n /** Blits onto the visible canvas last frame (0 or 1). */\n blits = 0;\n /** Visible-canvas backing reallocations last frame; settles at zero. */\n canvasReallocCount = 0;\n /** Distinct clips applied last frame. */\n clipCount = 0;\n /** Clips in the frame not applied last frame: `clipping` off, fewer than three points, or a polygon the core refuses to cut. */\n clipSkipCount = 0;\n\n private readonly ctx: CanvasRenderingContext2D | null;\n /** The rect in root units the canvas covers: left, top, right, bottom (Y down). Empty until the first frame. */\n private left = 0;\n private top = 0;\n private right = 0;\n private bottom = 0;\n private hasRect = false;\n private backingW = 0;\n private backingH = 0;\n private backingRatio = -1;\n private data = new Float32Array(4096);\n private readonly runs: FrameRun[] = [];\n /** Pages retained from the shared blitter, one retain each, released by dispose(). */\n private readonly glPages = new Set<HTMLImageElement>();\n /** The dirty signature of the last frame drawn: its numbers, and the objects it compares by identity. */\n private sig = new Float64Array(256);\n private sigLength = -1;\n private sigRefs: unknown[] = [];\n private nextSig = new Float64Array(256);\n private nextRefs: unknown[] = [];\n\n /**\n * @param root Positioned element that becomes the skeleton origin, exactly as\n * for `DomRenderer`: the canvas is appended to it and placed in its own\n * coordinates; layout and scaling of the root belong to the caller.\n * @param pages Page images keyed by page name — `PosedRegion.page` and\n * `PosedMesh.page`. Read on every draw.\n */\n constructor(\n private readonly root: HTMLElement,\n private readonly pages: ReadonlyMap<string, HTMLImageElement>,\n ) {\n const canvas = document.createElement('canvas');\n canvas.style.position = 'absolute';\n canvas.style.left = '0';\n canvas.style.top = '0';\n canvas.style.transformOrigin = '0 0';\n canvas.style.pointerEvents = 'none';\n canvas.style.userSelect = 'none';\n canvas.width = 0;\n canvas.height = 0;\n this.canvas = canvas;\n this.ctx = canvas.getContext('2d');\n root.appendChild(canvas);\n }\n\n /** Grows the automatic viewport to cover `box` (world units, Y up) ahead of the frames reaching it. */\n /**\n * Measures the root's effective on-screen scale and sets `pixelRatio` to\n * `devicePixelRatio × scale`, returning the ratio now in effect — the same\n * call, the same meaning and the same deadband as `DomRenderer`'s, so code\n * written against `player.renderer` survives a `mode` change. One forced\n * layout per call (a hidden box appended to the root, read, removed), which\n * is why the renderer never calls it for you. The backing store follows on\n * the next `render`; a root that is not laid out leaves the ratio alone.\n */\n syncPixelRatio(): number {\n this.pixelRatio = syncedPixelRatio(this.root, this.pixelRatio);\n return this.pixelRatio;\n }\n\n reserve(box: CanvasViewport): void {\n this.growTo(box.x, -(box.y + box.height), box.x + box.width, -box.y);\n }\n\n /** Draws one frame. */\n render(frame: PosedFrame): void {\n this.drawCalls = 0;\n this.blendFlushes = 0;\n this.trianglesDrawn = 0;\n this.framesReused = 0;\n this.blits = 0;\n this.canvasReallocCount = 0;\n this.clipCount = 0;\n this.clipSkipCount = 0;\n const blitter = this.backend === 'webgl' ? getMeshGlBlitter() : null;\n this.backendActive = blitter ? 'webgl' : 'canvas2d';\n const order = frame.order;\n\n // The rect: the caller's, or the grow-only cover of what this frame draws.\n const view = this.viewport;\n if (view) {\n this.setRect(Math.floor(view.x), Math.floor(-(view.y + view.height)), Math.ceil(view.x + view.width), Math.ceil(-view.y));\n } else {\n let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;\n for (let i = 0; i < order.length; i++) {\n const slot = order[i];\n const v = slot.kind === 'region' ? slot.corners : slot.vertices;\n for (let k = 0; k + 1 < v.length; k += 2) {\n const x = v[k];\n const y = -v[k + 1];\n if (x < minX) minX = x;\n if (x > maxX) maxX = x;\n if (y < minY) minY = y;\n if (y > maxY) maxY = y;\n }\n }\n if (minX <= maxX && minY <= maxY) this.growTo(minX, minY, maxX, maxY);\n }\n this.sizeBacking();\n\n if (!this.signatureChanged(order)) {\n this.framesReused = 1;\n this.countClips(order);\n return;\n }\n if (this.backingW === 0 || this.backingH === 0) return;\n\n if (blitter) {\n this.buildVertices(order);\n if (blitter.flushFrame({ canvas: this.canvas, width: this.backingW, height: this.backingH, data: this.data, stride: this.stride, runs: this.runs })) {\n this.blits = 1;\n return;\n }\n // Lost mid-frame: draw this frame on the fallback; the next render() re-selects.\n this.backendActive = 'canvas2d';\n this.sigLength = -1;\n }\n this.draw2d(order);\n }\n\n /** Removes the canvas from the root and hands the pages it uploaded back to the shared blitter. Idempotent. */\n dispose(): void {\n this.canvas.remove();\n if (this.glPages.size) {\n const blitter = getMeshGlBlitter();\n if (blitter) for (const page of this.glPages) blitter.release(page);\n this.glPages.clear();\n }\n this.sigLength = -1;\n }\n\n // --- the rect -------------------------------------------------------------\n\n private growTo(minX: number, minY: number, maxX: number, maxY: number): void {\n if (this.hasRect && minX >= this.left && minY >= this.top && maxX <= this.right && maxY <= this.bottom) return;\n if (!this.hasRect) {\n this.setRect(Math.floor(minX) - GROW_PAD, Math.floor(minY) - GROW_PAD, Math.ceil(maxX) + GROW_PAD, Math.ceil(maxY) + GROW_PAD);\n return;\n }\n // Grow with slack on the side that was outgrown, so a pose sampled sparsely\n // does not reallocate on every new extreme it finds.\n const slackX = Math.max(GROW_PAD, Math.round((this.right - this.left) / 4));\n const slackY = Math.max(GROW_PAD, Math.round((this.bottom - this.top) / 4));\n this.setRect(\n minX < this.left ? Math.floor(minX) - slackX : this.left,\n minY < this.top ? Math.floor(minY) - slackY : this.top,\n maxX > this.right ? Math.ceil(maxX) + slackX : this.right,\n maxY > this.bottom ? Math.ceil(maxY) + slackY : this.bottom,\n );\n }\n\n private setRect(left: number, top: number, right: number, bottom: number): void {\n if (this.hasRect && left === this.left && top === this.top && right === this.right && bottom === this.bottom) return;\n this.left = left;\n this.top = top;\n this.right = Math.max(left, right);\n this.bottom = Math.max(top, bottom);\n this.hasRect = true;\n this.canvas.style.transform = `translate(${left}px,${top}px)`;\n }\n\n /** The backing store at `rect × pixelRatio`; reallocated only when that changes. */\n private sizeBacking(): void {\n const ratio = this.pixelRatio;\n const w = this.hasRect ? Math.max(0, Math.ceil((this.right - this.left) * ratio)) : 0;\n const h = this.hasRect ? Math.max(0, Math.ceil((this.bottom - this.top) * ratio)) : 0;\n if (w === this.backingW && h === this.backingH && ratio === this.backingRatio) return;\n this.backingW = w;\n this.backingH = h;\n this.backingRatio = ratio;\n this.canvas.width = w;\n this.canvas.height = h;\n this.canvas.style.width = `${w / ratio}px`;\n this.canvas.style.height = `${h / ratio}px`;\n this.canvasReallocCount++;\n this.sigLength = -1;\n }\n\n // --- dirty-skip -----------------------------------------------------------\n\n /** Writes this frame's signature and compares it with the last one drawn; keeps it when it differs. */\n private signatureChanged(order: PosedSlot[]): boolean {\n let n = 0;\n const refs = this.nextRefs;\n refs.length = 0;\n let sig = this.nextSig;\n const need = (k: number): void => {\n if (n + k > sig.length) {\n const grown = new Float64Array(Math.max(sig.length * 2, n + k));\n grown.set(sig.subarray(0, n));\n sig = grown;\n this.nextSig = grown;\n }\n };\n need(8);\n sig[n++] = this.left;\n sig[n++] = this.top;\n sig[n++] = this.backingW;\n sig[n++] = this.backingH;\n sig[n++] = this.backingRatio;\n sig[n++] = this.backendActive === 'webgl' ? 1 : 0;\n sig[n++] = this.clipping ? 1 : 0;\n sig[n++] = order.length;\n let lastClip: PosedClip | undefined;\n for (let i = 0; i < order.length; i++) {\n const slot = order[i];\n const v = slot.kind === 'region' ? slot.corners : slot.vertices;\n const clip = slot.clip;\n need(10 + v.length + (clip && clip !== lastClip ? clip.polygon.length + 3 : 1));\n sig[n++] = slot.kind === 'region' ? 0 : 1;\n sig[n++] = BLEND_CODE[slot.blend];\n const t = slot.tint;\n sig[n++] = t[0];\n sig[n++] = t[1];\n sig[n++] = t[2];\n sig[n++] = t[3];\n const d = slot.dark;\n sig[n++] = d ? d[0] : -1;\n sig[n++] = d ? d[1] : -1;\n sig[n++] = d ? d[2] : -1;\n sig[n++] = v.length;\n for (let k = 0; k < v.length; k++) sig[n++] = v[k];\n if (!clip) {\n sig[n++] = 0;\n } else if (clip === lastClip) {\n sig[n++] = 1;\n } else {\n sig[n++] = 2;\n sig[n++] = (clip.inverse ? 1 : 0) + (clip.convex ? 2 : 0);\n sig[n++] = clip.polygon.length;\n for (let k = 0; k < clip.polygon.length; k++) sig[n++] = clip.polygon[k];\n lastClip = clip;\n }\n refs.push(this.pages.get(slot.page), slot.uvs);\n if (slot.kind === 'mesh') refs.push(slot.triangles);\n }\n let same = n === this.sigLength && refs.length === this.sigRefs.length;\n for (let k = 0; same && k < n; k++) same = sig[k] === this.sig[k];\n for (let k = 0; same && k < refs.length; k++) same = refs[k] === this.sigRefs[k];\n if (same) return false;\n // Swap: the new signature becomes the kept one.\n this.nextSig = this.sig;\n this.sig = sig;\n this.sigLength = n;\n this.nextRefs = this.sigRefs;\n this.sigRefs = refs;\n return true;\n }\n\n /** The clip counters for a reused frame — what drawing it would have counted. */\n private countClips(order: PosedSlot[]): void {\n const seen = new Set<PosedClip>();\n for (const slot of order) {\n const clip = slot.clip;\n if (!clip || seen.has(clip)) continue;\n seen.add(clip);\n if (this.clipping && clip.polygon.length >= 6) this.clipCount++;\n else this.clipSkipCount++;\n }\n }\n\n // --- geometry ---------------------------------------------------------------\n\n private stride: 8 | 11 = 8;\n\n /**\n * The slot's triangles in world space with their page UVs — cut by the clip\n * over it when one applies — or null when the slot draws nothing.\n */\n private piecesOf(\n slot: PosedSlot,\n clips: Map<PosedClip, boolean>,\n ): { vertices: ArrayLike<number>; uvs: ArrayLike<number>; triangles: ArrayLike<number> } | null {\n const vertices = slot.kind === 'region' ? slot.corners : slot.vertices;\n const triangles = slot.kind === 'region' ? REGION_TRIANGLES : slot.triangles;\n const clip = slot.clip;\n if (!clip) return { vertices, uvs: slot.uvs, triangles };\n let applies = clips.get(clip);\n if (applies === undefined) {\n applies = this.clipping && clip.polygon.length >= 6;\n clips.set(clip, applies);\n if (applies) this.clipCount++;\n else this.clipSkipCount++;\n }\n if (!applies) return { vertices, uvs: slot.uvs, triangles };\n const cut = clipThrough({ polygon: clip.polygon, inverse: clip.inverse, convex: clip.convex }, vertices, triangles, slot.uvs);\n if (cut === null) {\n // A polygon the core does not draw (self-crossing, collinear): counted\n // once as skipped, and the slot drawn unclipped as for a skipped clip.\n clips.set(clip, false);\n this.clipCount--;\n this.clipSkipCount++;\n return { vertices, uvs: slot.uvs, triangles };\n }\n return cut.clipped ? cut : { vertices, uvs: slot.uvs, triangles };\n }\n\n /** Fills `data` and `runs` for the GL path. */\n private buildVertices(order: PosedSlot[]): void {\n let dark = false;\n for (let i = 0; i < order.length && !dark; i++) dark = order[i].dark !== undefined;\n const stride: 8 | 11 = dark ? 11 : 8;\n this.stride = stride;\n const runs = this.runs;\n runs.length = 0;\n const clips = new Map<PosedClip, boolean>();\n const ratio = this.backingRatio;\n const left = this.left;\n const top = this.top;\n const blitter = getMeshGlBlitter();\n let vertex = 0;\n let run: FrameRun | null = null;\n for (let i = 0; i < order.length; i++) {\n const slot = order[i];\n const page = this.pages.get(slot.page);\n if (!page) continue;\n const piece = this.piecesOf(slot, clips);\n if (!piece) continue;\n const { vertices, uvs, triangles } = piece;\n const count = triangles.length;\n if (count === 0) continue;\n if (!this.glPages.has(page) && blitter) {\n this.glPages.add(page);\n blitter.retain(page);\n }\n if (!run || run.page !== page || run.blend !== slot.blend) {\n if (run && run.blend !== slot.blend) this.blendFlushes++;\n run = { page, pma: slot.pma, blend: slot.blend, first: vertex, count: 0 };\n runs.push(run);\n }\n const need = (vertex + count) * stride;\n if (this.data.length < need) {\n const grown = new Float32Array(1 << Math.ceil(Math.log2(need)));\n grown.set(this.data.subarray(0, vertex * stride));\n this.data = grown;\n }\n const data = this.data;\n const [r, g, b, a] = slot.tint;\n const d = slot.dark;\n let f = vertex * stride;\n for (let t = 0; t < count; t++) {\n const vi = triangles[t] * 2;\n data[f++] = (vertices[vi] - left) * ratio;\n data[f++] = (-vertices[vi + 1] - top) * ratio;\n data[f++] = uvs[vi];\n data[f++] = uvs[vi + 1];\n data[f++] = r * a;\n data[f++] = g * a;\n data[f++] = b * a;\n data[f++] = a;\n if (stride === 11) {\n data[f++] = d ? d[0] * a : 0;\n data[f++] = d ? d[1] * a : 0;\n data[f++] = d ? d[2] * a : 0;\n }\n }\n vertex += count;\n run.count += count;\n this.trianglesDrawn += count / 3;\n }\n this.drawCalls = runs.length;\n }\n\n // --- the canvas2d fallback -----------------------------------------------\n\n private draw2d(order: PosedSlot[]): void {\n const ctx = this.ctx;\n if (!ctx) return;\n ctx.setTransform(1, 0, 0, 1, 0, 0);\n ctx.globalAlpha = 1;\n ctx.globalCompositeOperation = 'source-over';\n ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n const clips = new Map<PosedClip, boolean>();\n const ratio = this.backingRatio;\n const left = this.left;\n const top = this.top;\n const X = (x: number): number => (x - left) * ratio;\n const Y = (y: number): number => (-y - top) * ratio;\n let blend: BlendMode | null = null;\n for (let i = 0; i < order.length; i++) {\n const slot = order[i];\n const image = this.pages.get(slot.page);\n if (!image) continue;\n const piece = this.piecesOf(slot, clips);\n if (!piece) continue;\n const source: PageSource = straightAlphaSource(image, slot.pma);\n const uw = source.width;\n const uh = source.height;\n if (slot.blend !== blend) {\n if (blend !== null) this.blendFlushes++;\n blend = slot.blend;\n ctx.globalCompositeOperation = COMPOSITE[blend];\n }\n ctx.globalAlpha = Math.max(0, Math.min(1, slot.tint[3]));\n this.drawCalls++;\n const { vertices, uvs, triangles } = piece;\n if (slot.kind === 'region' && vertices === slot.corners) {\n // A whole quad: its page sub-rect under the affine that sends the UL,\n // UR and BL texel corners to their device corners (BL, UL, UR, BR).\n const c = vertices;\n const sx0 = uvs[2] * uw, sy0 = uvs[3] * uh; // UL\n const sx1 = uvs[4] * uw, sy1 = uvs[5] * uh; // UR\n const sx2 = uvs[0] * uw, sy2 = uvs[1] * uh; // BL\n const m = affine(sx0, sy0, sx1, sy1, sx2, sy2, X(c[2]), Y(c[3]), X(c[4]), Y(c[5]), X(c[0]), Y(c[1]));\n if (m) {\n const minU = Math.min(uvs[0], uvs[2], uvs[4], uvs[6]) * uw;\n const minV = Math.min(uvs[1], uvs[3], uvs[5], uvs[7]) * uh;\n const maxU = Math.max(uvs[0], uvs[2], uvs[4], uvs[6]) * uw;\n const maxV = Math.max(uvs[1], uvs[3], uvs[5], uvs[7]) * uh;\n ctx.setTransform(m[0], m[1], m[2], m[3], m[4], m[5]);\n if (maxU > minU && maxV > minV) ctx.drawImage(source, minU, minV, maxU - minU, maxV - minV, minU, minV, maxU - minU, maxV - minV);\n ctx.setTransform(1, 0, 0, 1, 0, 0);\n }\n this.trianglesDrawn += 2;\n continue;\n }\n for (let t = 0; t + 2 < triangles.length; t += 3) {\n const i0 = triangles[t] * 2;\n const i1 = triangles[t + 1] * 2;\n const i2 = triangles[t + 2] * 2;\n drawTexturedTriangle(\n ctx, source, 0.5,\n X(vertices[i0]), Y(vertices[i0 + 1]), uvs[i0] * uw, uvs[i0 + 1] * uh,\n X(vertices[i1]), Y(vertices[i1 + 1]), uvs[i1] * uw, uvs[i1 + 1] * uh,\n X(vertices[i2]), Y(vertices[i2 + 1]), uvs[i2] * uw, uvs[i2 + 1] * uh,\n );\n }\n this.trianglesDrawn += triangles.length / 3;\n }\n ctx.globalAlpha = 1;\n ctx.globalCompositeOperation = 'source-over';\n }\n}\n\n/** The affine sending three source points to three destination points, as canvas `setTransform` arguments; null when degenerate. */\nfunction affine(\n u0: number, v0: number, u1: number, v1: number, u2: number, v2: number,\n x0: number, y0: number, x1: number, y1: number, x2: number, y2: number,\n): [number, number, number, number, number, number] | null {\n const eu1 = u1 - u0, ev1 = v1 - v0, eu2 = u2 - u0, ev2 = v2 - v0;\n const det = eu1 * ev2 - eu2 * ev1;\n if (det === 0) return null;\n const inv = 1 / det;\n const ex1 = x1 - x0, ey1 = y1 - y0, ex2 = x2 - x0, ey2 = y2 - y0;\n const a = (ev2 * ex1 - ev1 * ex2) * inv;\n const b = (ev2 * ey1 - ev1 * ey2) * inv;\n const c = (eu1 * ex2 - eu2 * ex1) * inv;\n const d = (eu1 * ey2 - eu2 * ey1) * inv;\n return [a, b, c, d, x0 - a * u0 - c * v0, y0 - b * u0 - d * v0];\n}\n","import { type CompiledDocument, CORE_DOCUMENT_SPECS, CoreInputError, readModel } from 'rig-c/core';\nimport { type RegionImage, revokeRegions, unpackRegions } from './DomTexture.js';\n\n/**\n * Loads a rig built by `rigc build`: the compiled model document\n * (`skeleton.model.json`, spec `rigc-compiled/3`) and the page images its\n * `pages` section names, cut into region bitmaps once.\n *\n * The document states everything the player reads — the skeleton, the\n * animations, and where every region sits on its page — so the `.atlas` and\n * `skeleton.json` the build writes beside it are not fetched. A Spine export\n * (`.json`, `.skel`) is refused by name: this package poses the compiled model\n * through `rig-c/core` and reads nothing else.\n */\n\nexport interface LoadModelOptions {\n /** URL of the compiled model document (`skeleton.model.json`). */\n modelUrl: string;\n /**\n * Maps a page name from the document's `pages` section to the URL its image\n * lives at. Defaults to resolving the name against the model URL's\n * directory: a build writes page names as paths relative to its own\n * directory, which is where the document sits.\n */\n resolvePage?: (pageName: string, modelUrl: string) => string;\n /**\n * crossOrigin attribute for the page images. Needed when the images come\n * from another origin: the region cut reads them into a canvas, and a\n * tainted canvas cannot be exported (SecurityError from toBlob).\n */\n crossOrigin?: string;\n /** fetch implementation, for custom headers or a test double. */\n fetch?: typeof globalThis.fetch;\n /**\n * What the region cut produces — the rigid tier's per-region bitmaps, which\n * only the DOM mode draws. `'blob'` (the default): `blob:` URLs the load\n * owns and `dispose` frees. `'data'`: `data:` URLs, for a content policy or\n * a snapshot that does not carry `blob:`; nothing to free. `'none'`: no cut\n * at all, for a load that only ever draws in the canvas mode — the pages\n * are loaded, `regionImages` is empty, and a DOM-mode player opened on the\n * assets is refused by name.\n */\n regions?: RegionLoading;\n}\n\n/** `LoadModelOptions.regions`: how, or whether, the regions are cut. */\nexport type RegionLoading = 'blob' | 'data' | 'none';\n\n/**\n * What `new RigPlayer(root, assets)` draws from. The caller owns it: one load\n * can back any number of players, and nothing a player does disposes it.\n */\nexport interface ModelAssets {\n /** The document's spec, e.g. `rigc-compiled/3`. */\n readonly spec: string;\n /** Every animation the document carries, in its order, with the runtime's duration. */\n readonly animations: ReadonlyArray<{ readonly name: string; readonly duration: number }>;\n /** Every skin the document declares, in its order. */\n readonly skins: readonly string[];\n /**\n * The document's `stage` section, in world units (Y up): the stage the\n * build declared — the rig's own framing, for laying out a stage — or null\n * where the document has none. Where its value comes from is rigc's rule,\n * not this package's (rigc `docs/AUTHORING.md`, *Where the rebuild's stage\n * comes from*): a source that states a stage is written as stated, and a\n * source that states none gets the setup pose's bounding box in its place.\n * So one rig's `stage` is a declared frame and another's is a box, and the\n * field does not say which. For the box of what a pose draws, read\n * `player.bounds()`.\n */\n readonly stage: { readonly x: number; readonly y: number; readonly width: number; readonly height: number } | null;\n /** How the regions were cut (`LoadModelOptions.regions`): `'none'` means `regionImages` is empty and only the canvas mode can draw. */\n readonly regions: RegionLoading;\n /** Unpacked per-region bitmaps, keyed by region name — the rigid tier's. Empty on a `regions: 'none'` load. */\n readonly regionImages: Map<string, RegionImage>;\n /** Page images, keyed by the document's page names — the mesh tier's. */\n readonly pageImages: Map<string, HTMLImageElement>;\n /**\n * The document as `rig-c/core` read it. Opaque to callers: the player poses\n * it, and its shape is rig-c's, not this package's.\n */\n readonly document: ModelDocument;\n /**\n * Frees the blob URLs this load created (see revokeRegions). Idempotent.\n * Call it after the players drawing from these assets are disposed — a live\n * <img> would be left pointing at a dead URL.\n */\n dispose(): void;\n}\n\n/** The read document, held for the player. Deliberately opaque. */\nexport interface ModelDocument {\n readonly spec: string;\n}\n\n/** @internal What the player reads off `ModelAssets.document`. */\nexport interface ReadDocument extends ModelDocument {\n readonly doc: CompiledDocument;\n /** The document's parsed JSON — the sequences' `start`/`digits`, which `readModel` does not keep, are read off it. */\n readonly parsed: unknown;\n}\n\nfunction stageOf(doc: CompiledDocument): ModelAssets['stage'] {\n const stage = doc.stated?.stage;\n return stage ? { x: stage.x, y: stage.y, width: stage.width, height: stage.height } : null;\n}\n\nfunction resolveAgainstModel(pageName: string, modelUrl: string): string {\n return new URL(pageName, new URL(modelUrl, document.baseURI)).href;\n}\n\nasync function fetchText(fetchImpl: typeof globalThis.fetch, url: string): Promise<string> {\n const response = await fetchImpl(url);\n if (!response.ok) throw new Error(`Failed to fetch ${url}: ${response.status}`);\n return response.text();\n}\n\nfunction loadImage(url: string, crossOrigin?: string): Promise<HTMLImageElement> {\n return new Promise((resolve, reject) => {\n const image = new Image();\n if (crossOrigin !== undefined) image.crossOrigin = crossOrigin;\n image.onload = () => resolve(image);\n image.onerror = () => reject(new Error(`Failed to load page image: ${url}`));\n image.src = url;\n });\n}\n\n/** The URL's path without its query or fragment, lower-cased — what the export check reads. */\nfunction pathOf(url: string): string {\n return url.split(/[?#]/, 1)[0].toLowerCase();\n}\n\n/**\n * Reads a model document's text, refusing by name what this package does not\n * read: a Spine export, a document whose spec `rig-c/core` does not read, and a\n * document without a `pages` section (`rigc-compiled/1`).\n *\n * @internal Shared with the loader below; not part of the package API.\n */\nexport function readModelText(text: string, where: string): ReadDocument {\n let doc: CompiledDocument;\n try {\n doc = readModel(text, where);\n } catch (error) {\n if (error instanceof CoreInputError) {\n throw new CoreInputError(`${error.message} — build it with \\`rigc build\\``);\n }\n throw error;\n }\n if (doc.pages === null) {\n throw new CoreInputError(\n `${where}: a ${doc.spec} document does not state where each region sits on its page — build it with \\`rigc build\\``,\n );\n }\n return { spec: doc.spec, doc, parsed: JSON.parse(text) as unknown };\n}\n\n/**\n * Loads a rig built by `rigc build`.\n *\n * ```ts\n * const assets = await loadModel({ modelUrl: '/rigs/walk/skeleton.model.json' });\n * const player = new RigPlayer(root, assets);\n * player.play('walk');\n * // each frame: player.frame(dt)\n * // …later: player.dispose(); assets.dispose();\n * ```\n *\n * Page images load in parallel. If anything fails part-way, no blob URL is\n * left behind.\n */\nexport async function loadModel(options: LoadModelOptions): Promise<ModelAssets> {\n const { modelUrl, crossOrigin } = options;\n const path = pathOf(modelUrl);\n if (path.endsWith('.skel') || (path.endsWith('.json') && !path.endsWith('.model.json'))) {\n throw new CoreInputError(\n `${modelUrl} is a Spine export; this player reads a compiled model document (${CORE_DOCUMENT_SPECS[0]}, skeleton.model.json) — build it with \\`rigc build\\``,\n );\n }\n const regions = options.regions ?? 'blob';\n if (regions !== 'blob' && regions !== 'data' && regions !== 'none') {\n throw new Error(`regions must be 'blob', 'data' or 'none', got ${String(options.regions)}`);\n }\n const fetchImpl = options.fetch ?? globalThis.fetch.bind(globalThis);\n const resolvePage = options.resolvePage ?? resolveAgainstModel;\n\n const read = readModelText(await fetchText(fetchImpl, modelUrl), modelUrl);\n const pages = read.doc.pages ?? [];\n const pageImages = new Map<string, HTMLImageElement>();\n await Promise.all(\n pages.map(async (page) => {\n pageImages.set(page.name, await loadImage(resolvePage(page.name, modelUrl), crossOrigin));\n }),\n );\n\n const regionImages = regions === 'none' ? new Map<string, RegionImage>() : await unpackRegions(pages, pageImages, { encoding: regions });\n\n let disposed = false;\n return {\n spec: read.spec,\n animations: read.doc.animations.map((a) => ({ name: a.name, duration: a.timelines.duration })),\n skins: read.doc.skins.map((s) => s.name),\n stage: stageOf(read.doc),\n regions,\n regionImages,\n pageImages,\n document: read,\n dispose(): void {\n if (disposed) return;\n disposed = true;\n revokeRegions(regionImages);\n },\n };\n}\n","import {\n activeBones,\n type CompiledDocument,\n CoreInputError,\n type CoreSlotRow,\n type DrawnRegion,\n documentPageLookup,\n drawnRegions,\n meshPageUvs,\n type ModelPage,\n type RawDrawn,\n type RawPose,\n readUvSequences,\n regionPageUvs,\n type UvSource,\n} from 'rig-c/core';\n\n/**\n * The record the DOM tier draws: one posed moment of a rig, every slot the\n * renderer shows, in draw order.\n *\n * The renderer never needed a skeleton. Per slot it needs the kind, four world\n * corners or world vertices with page UVs and triangles, the bitmap or the\n * page image with its alpha convention, a tint, a blend mode, a clip polygon\n * and a stacking position — and every one of those is a field of a pose that\n * `rig-c/core` computes from the compiled model document, plus that document's\n * `pages` section. This module is the adapter from one to the other\n * (`frameOf`), and these types are the whole of what crosses it.\n *\n * Coordinates are world space, Y up, exactly as the poser computed them; the\n * renderer does the Y flip. Nothing here is rounded or re-ordered.\n */\nexport interface PosedFrame {\n /** Every slot that draws, in draw order. */\n order: PosedSlot[];\n}\n\n/** The four blend modes, spelled as the runtime's enum names them. */\nexport type BlendMode = 'Normal' | 'Additive' | 'Multiply' | 'Screen';\n\n/**\n * A clip polygon in world space and whether it keeps what is outside it.\n *\n * One object per clip in force: every slot a clip covers carries the *same*\n * object, which is how the renderer tells a clip that covers the whole frame\n * (one `clip-path` on the root) from one that covers a range of it.\n */\nexport interface PosedClip {\n /** Flat x, y pairs, world space. */\n polygon: number[];\n inverse: boolean;\n /**\n * The clipping attachment's `convex` flag: a polygon that is not convex is\n * clipped against its hull rather than decomposed. The DOM tier's CSS\n * `clip-path` takes the polygon as authored and does not read it; the canvas\n * mode's triangle cut does (`clipThrough` in `rig-c/core`).\n */\n convex: boolean;\n}\n\ninterface PosedSlotCommon {\n /** The slot's name — the renderer keys its element on it. */\n slot: string;\n /** The slot's index in the full draw order (hidden slots included): its z-index. */\n z: number;\n blend: BlendMode;\n /** Slot colour × attachment colour × the player's own colour, r g b a in [0, 1]. */\n tint: [number, number, number, number];\n /** The slot's dark (two-colour) tint, where it carries one. The DOM tier cannot draw it. */\n dark?: [number, number, number];\n /** The clip in force over this slot, where one is. */\n clip?: PosedClip;\n}\n\n/** A rigid slot: an unpacked region bitmap posed by its four world corners. */\nexport interface PosedRegion extends PosedSlotCommon {\n kind: 'region';\n /** The region drawn — the key into the region bitmap map (a sequence frame's own name). */\n region: string;\n /** Four world corners, bottom-left, upper-left, upper-right, bottom-right: x0 y0 … x3 y3. */\n corners: number[];\n /**\n * The page the region sits on — the key into the page image map. The DOM tier\n * draws the region's own bitmap and never reads it; the canvas mode samples\n * the page through `uvs`.\n */\n page: string;\n /** Whether the page's texels are premultiplied by their alpha. */\n pma: boolean;\n /**\n * The region's page UVs at its four corners, in the corners' order (u, v\n * pairs, the page spanning [0, 1]) — the runtime's region UVs, a 90°-packed\n * region's turn included. The same array object from frame to frame for the\n * same region.\n */\n uvs: number[];\n}\n\n/** A deform slot: world vertices over page UVs, rastered from the page image. */\nexport interface PosedMesh extends PosedSlotCommon {\n kind: 'mesh';\n /** The page drawn — the key into the page image map. */\n page: string;\n /** Whether the page's texels are premultiplied by their alpha. */\n pma: boolean;\n /** World vertices, flat x, y pairs. */\n vertices: number[];\n /**\n * Page UVs, flat u, v pairs, the page spanning [0, 1]. The same array object\n * from frame to frame for the same region and attachment, so the renderer\n * can tell a mesh whose texture did not change by identity.\n */\n uvs: number[];\n /** Triangle indices into `vertices`, three per triangle. Stable by identity like `uvs`. */\n triangles: number[];\n /** The sequence frame drawn (0 for an attachment with no series). */\n sequence: number;\n}\n\nexport type PosedSlot = PosedRegion | PosedMesh;\n\n/**\n * What a document's frames read besides the pose, built once per document\n * view (`frameSource`): where every region sits on its page, each record's\n * sequence, which bones are active, and the per-region arrays the frames\n * share.\n *\n * @internal Not part of the package API: it holds `rig-c/core` objects, and\n * the package's types name none of them.\n */\nexport interface FrameSource {\n doc: CompiledDocument;\n uv: UvSource;\n pages: ReadonlyMap<string, ModelPage>;\n active: ReadonlySet<string>;\n boneOf: ReadonlyMap<string, string>;\n /** Page UVs kept per placement and attachment UV array, so a mesh's `uvs` is one object for its lifetime. */\n uvs: WeakMap<object, Map<readonly number[], number[]>>;\n /** Region page UVs kept per placement, so a region's `uvs` is one object for its lifetime. */\n regionUvs: WeakMap<object, number[]>;\n /** Triangle lists kept per slot and attachment, compared index for index before reuse. */\n triangles: Map<string, number[][]>;\n}\n\n/**\n * Builds the frame source for one view of a document — the view the track was\n * opened on (`underSkin` / `underNoSkin`), since which bones are active is a\n * fact of the skin. `text` is the document's own text: the sequences' `start`\n * and `digits` are not kept by `readModel`, and `readUvSequences` reads them\n * off the parsed JSON.\n *\n * @internal\n */\nexport function frameSource(doc: CompiledDocument, parsed: unknown): FrameSource {\n if (doc.pages === null) {\n throw new CoreInputError(\n `a ${doc.spec} document does not state where each region sits on its page; build it with \\`rigc build\\``,\n );\n }\n const pages = new Map(doc.pages.map((page) => [page.name, page]));\n return {\n doc,\n uv: { lookup: documentPageLookup(doc.pages), sequences: readUvSequences(parsed) },\n pages,\n active: activeBones(doc),\n boneOf: new Map(doc.slots.map((slot) => [slot.name, slot.bone])),\n uvs: new WeakMap(),\n regionUvs: new WeakMap(),\n triangles: new Map(),\n };\n}\n\n/** A slot row's colour channel. The core writes `null` only for a value that is not finite. */\nfunction channel(value: number | null, slot: string): number {\n if (value === null) throw new CoreInputError(`slot \"${slot}\": the pose computed a colour channel that is not finite`);\n return value;\n}\n\n/** The page UVs a drawn mesh samples — `meshPageUvs`, kept per placement and UV array. */\nfunction meshUvs(source: FrameSource, found: DrawnRegion): number[] {\n const art = found.art as readonly number[];\n let byArt = source.uvs.get(found.found);\n if (byArt === undefined) {\n byArt = new Map();\n source.uvs.set(found.found, byArt);\n }\n let kept = byArt.get(art);\n if (kept === undefined) {\n kept = meshPageUvs(found.found.region, found.found.page, art);\n byArt.set(art, kept);\n }\n return kept;\n}\n\n/** The page UVs a drawn region samples — `regionPageUvs`, kept per placement. */\nfunction regionUvs(source: FrameSource, found: DrawnRegion): number[] {\n let kept = source.regionUvs.get(found.found);\n if (kept === undefined) {\n kept = regionPageUvs(found.found.region, found.found.page);\n source.regionUvs.set(found.found, kept);\n }\n return kept;\n}\n\n/** A triangle list equal, index for index, to `drawn.triangles`, kept for reuse by identity. */\nfunction trianglesOf(source: FrameSource, drawn: RawDrawn): number[] {\n const key = `${drawn.slot}\\u0000${drawn.attachment}`;\n let lists = source.triangles.get(key);\n if (lists === undefined) {\n lists = [];\n source.triangles.set(key, lists);\n }\n const wanted = drawn.triangles;\n let kept = lists.find((list) => list.length === wanted.length && list.every((v, i) => v === wanted[i]));\n if (kept === undefined) {\n kept = [...wanted];\n lists.push(kept);\n }\n return kept;\n}\n\n/**\n * The clip over each slot of the draw order, where one covers it — the official\n * draw loops' `clipStart`/`clipEnd`, restated over a pose (rigc's\n * `clipCover` in `src/render_core.ts` is the specification this follows):\n *\n * - walking the draw order, a slot showing a clipping attachment first ends the\n * clip in force if it is that clip's end slot, then starts its own when its\n * bone is active and no clip is in force — a second clip met while one is in\n * force is ignored, not nested;\n * - every other slot is covered by the clip in force, and ends it after being\n * covered if it is the end slot (the end slot is inside its own clip);\n * - a clip whose end slot is its own slot, or one already passed, never ends.\n *\n * Each started clip is one `PosedClip` object, shared by every slot it covers.\n *\n * @internal Exported for the frame gate's synthetic cover cases.\n */\nexport function clipCover(pose: Pick<RawPose, 'clips' | 'shown' | 'drawOrder'>, active: ReadonlySet<string>, draws: (slot: string) => boolean = () => true): Map<string, PosedClip> {\n const polygons = new Map(pose.clips.map((c) => [c[0], { end: c[2], polygon: c[3] }]));\n const shownOf = new Map(pose.shown.map((s) => [s.slot, s]));\n const cover = new Map<string, PosedClip>();\n let current: { end: string | null; clip: PosedClip } | null = null;\n for (const slot of pose.drawOrder) {\n const shown = shownOf.get(slot);\n const g = shown?.geometry;\n const clip = g?.kind === 'clipping' ? polygons.get(slot) : undefined;\n if (shown !== undefined && g?.kind === 'clipping' && clip !== undefined) {\n if (current !== null && current.end === slot) current = null;\n // A clip start the player does not draw does not clip: the filter is a\n // draw filter, and a clip is drawn by its effect on what it covers.\n if (active.has(shown.bone) && current === null && draws(slot)) {\n current = { end: clip.end, clip: { polygon: clip.polygon, inverse: g.inverse, convex: g.convex } };\n }\n continue;\n }\n if (current !== null) cover.set(slot, current.clip);\n if (current !== null && current.end === slot) current = null;\n }\n return cover;\n}\n\n/**\n * One pose as a frame.\n *\n * - `order` is the pose's draw order narrowed to the attachments it draws\n * (`pose.drawn`, regions and meshes) on active bones; `z` is the slot's index\n * in the full draw order.\n * - A region's `corners` are its drawn vertices, which the core writes in the\n * runtime's corner order: bottom-left, upper-left, upper-right, bottom-right.\n * - A region's `uvs` are `regionPageUvs` over the region `drawnRegions`\n * resolves for it, and its `page`/`pma` that region's page.\n * - A mesh's `uvs` are `meshPageUvs` over the region `drawnRegions` resolves\n * for it (a sequence frame's own region, a linked mesh's own region over its\n * source's UVs) and its `page`/`pma` that region's page.\n * - `tint` is the slot row's colour times the attachment's colour, channel by\n * channel, then times `color` — the player's own whole-rig colour, which is\n * not a document value.\n * - `blend` is the slot row's mode; `dark` its dark colour where it has one.\n * - `clip` is `clipCover` above.\n *\n * @internal\n */\nexport function frameOf(\n source: FrameSource,\n pose: RawPose,\n color: readonly [number, number, number, number] = [1, 1, 1, 1],\n draws: (slot: string) => boolean = () => true,\n): PosedFrame {\n const { drawn: regions, why } = drawnRegions(source.doc, pose.shown, pose.drawOrder, source.uv);\n if (regions === null) throw new CoreInputError(`the page UVs are not posed: ${why}`);\n const regionOf = new Map(regions.map((r) => [r.slot, r]));\n const rows = new Map<string, CoreSlotRow>(pose.slots.map((row) => [row[0], row]));\n const z = new Map(pose.drawOrder.map((slot, index) => [slot, index]));\n const cover = clipCover(pose, source.active, draws);\n const [sr, sg, sb, sa] = color;\n const order: PosedSlot[] = [];\n for (const d of pose.drawn) {\n if (!draws(d.slot)) continue;\n const bone = source.boneOf.get(d.slot);\n if (bone === undefined || !source.active.has(bone)) continue;\n const found = regionOf.get(d.slot);\n if (found === undefined) throw new CoreInputError(`slot \"${d.slot}\" drew \"${d.attachment}\", and no atlas region was resolved for it`);\n const row = rows.get(d.slot);\n if (row === undefined) throw new CoreInputError(`slot \"${d.slot}\" drew and has no slot row`);\n const tint: [number, number, number, number] = [\n channel(row[2], d.slot) * d.colour[0] * sr,\n channel(row[3], d.slot) * d.colour[1] * sg,\n channel(row[4], d.slot) * d.colour[2] * sb,\n channel(row[5], d.slot) * d.colour[3] * sa,\n ];\n const darkRow = row[6];\n const common = {\n slot: d.slot,\n z: z.get(d.slot) as number,\n blend: (row[8] ?? 'Normal') as BlendMode,\n tint,\n ...(darkRow === null ? {} : { dark: [channel(darkRow[0], d.slot), channel(darkRow[1], d.slot), channel(darkRow[2], d.slot)] as [number, number, number] }),\n ...(cover.has(d.slot) ? { clip: cover.get(d.slot) as PosedClip } : {}),\n };\n const page = source.pages.get(found.found.page.name);\n if (d.kind === 'region') {\n order.push({\n ...common,\n kind: 'region',\n region: found.region,\n corners: d.vertices,\n page: found.found.page.name,\n pma: page?.pma === true,\n uvs: regionUvs(source, found),\n });\n } else {\n order.push({\n ...common,\n kind: 'mesh',\n page: found.found.page.name,\n pma: page?.pma === true,\n vertices: d.vertices,\n uvs: meshUvs(source, found),\n triangles: trianglesOf(source, d),\n sequence: d.sequenceIndex,\n });\n }\n }\n return { order };\n}\n","import { type CompiledDocument, eventsFired, type LiveTrack, type LiveTracks, type LocalAdjust as CoreLocalAdjust, openTrack, openTracks, poseRawSetup, type RawPose, type TrackEntryView, underNoSkin, underSkin } from 'rig-c/core';\nimport { CanvasRenderer } from './CanvasRenderer.js';\nimport { DomRenderer, type MeshBackend } from './DomRenderer.js';\nimport type { ModelAssets, ReadDocument } from './loadModel.js';\nimport { type FrameSource, frameOf, frameSource, type PosedFrame } from './posedFrame.js';\n\n/**\n * Plays a rig built by `rigc build` on a DOM root.\n *\n * The player owns the track and the renderer: `play` opens an animation on a\n * live track (`openTrack` from `rig-c/core`), each `frame(dt)` steps it by\n * `dt × timeScale`, turns the pose into a `PosedFrame` and hands that to its\n * renderer — a `DomRenderer` (`mode: 'dom'`, the default) or a\n * `CanvasRenderer` (`mode: 'canvas'`). Everything the pose holds is computed by\n * the core from the compiled model document; this class schedules and draws.\n */\n\n/**\n * How a player draws: `'dom'` — elements, the rigid tier as `<img>` and the\n * mesh tier on per-part canvases (`DomRenderer`); `'canvas'` — the whole frame\n * into one `<canvas>` through the shared WebGL context (`CanvasRenderer`).\n */\nexport type RenderMode = 'dom' | 'canvas';\n\nexport interface RigPlayerOptions {\n /**\n * The skin to pose under. Absent is the runtime's \"no skin set\" — a fresh\n * skeleton whose `setSkin` was never called (`underNoSkin`): no skin's bones\n * or constraints applied, every slot resolved through the default skin.\n */\n skin?: string;\n /** The per-pose adjustment of bone locals (`player.adjust`), set from the first pose. */\n adjust?: BoneAdjust | null;\n /** Which slots this player draws (`player.slots`); every slot when absent. */\n slots?: SlotFilter | null;\n /** How the player draws (see `RenderMode`). Default `'dom'`. Can be changed later through `mode`. */\n mode?: RenderMode;\n /** The mesh tier's rasterizer (see `DomRenderer.meshBackend`) — the DOM mode only. */\n meshBackend?: MeshBackend;\n /**\n * The step `seek` walks the track forward with, in seconds. A seek is\n * \"reopen, then step to the time\", never a jump: a physics rig has history,\n * and the pose at a time depends on the steps taken to reach it.\n */\n seekStep?: number;\n /**\n * Stand the player on rig-c's live tracks from the first `play`, so the\n * first composing call — a mix, another track, a queue, a clear — never\n * replays. Without it a plain `play` runs on the single live track, and the\n * first composing call carries it over by replaying the time played in\n * `seekStep` increments (there is no hand-over of a live track's physics\n * state in the core), which on a stage that idled a while is one long\n * frame. Pick the single track for a rig whose animations key what the\n * tracks do not mix (constraints, sequences, the draw order, a path's\n * deform); pick the tracks for layering.\n */\n tracks?: boolean;\n}\n\n/** What `on('event', …)` hands a listener: one event key the step crossed. */\nexport interface RigEvent {\n name: string;\n /** The key's time in the animation. */\n time: number;\n int: number;\n float: number;\n string: string | null;\n /**\n * The track whose current entry fired it. The core's pose lists a step's\n * events in track order without naming the track, so the player attributes\n * them by counting what each track's current entry fires over the step;\n * when that count does not match the pose (an entry replaced inside the\n * step), the step's events carry no track rather than a guessed one.\n */\n track?: number;\n}\n\n/** What `on('complete', …)` hands a listener: the entry that completed, and its track. */\nexport interface RigComplete {\n animation: string;\n track: number;\n}\n\n/** How `play` starts an entry, and `queue` queues one. */\nexport interface PlayOptions {\n /** Loop; true by default. */\n loop?: boolean;\n /** The track; 0 by default. A base on 0, a layer over it on 1, a one-shot on 2. */\n track?: number;\n /** Seconds the entry this one replaces mixes out over; 0 (the default) cuts. */\n mix?: number;\n /**\n * The entry's weight, from 0 to 1 (1 by default), multiplied into every\n * timeline it applies — the same clip at 0.6 and at 0.85. Change it while\n * the entry plays with `setAlpha`. It does not touch events (fired at any\n * alpha, 0 included) or attachments (kept at any alpha).\n */\n alpha?: number;\n /**\n * The entry adds its keyed bone and deform values to what the tracks below\n * posed, rather than replacing them — a layer keying the same bone channels\n * as the base without covering its motion (false by default). Fixed when the\n * entry is set or queued. A rotation is added as it stands, with no\n * shortest-angle wrap; mixing out, an additive entry fades with its alpha\n * and is never held.\n */\n additive?: boolean;\n}\n\nexport interface QueueOptions extends PlayOptions {\n /**\n * At or below 0 (the default 0): the entry starts when the one before it\n * completes, less this entry's `mix` — a one-shot then mixes into the next\n * over its last `mix` seconds. Above 0: that many seconds after the entry\n * before it starts.\n */\n delay?: number;\n}\n\n/** A track's current entry as the player reads it (`entry(track)`). */\nexport interface TrackEntry {\n /** What it plays; null for the empty animation a `clear` left. */\n animation: string | null;\n loop: boolean;\n /** The entry's own track time, from its start. */\n trackTime: number;\n /** The animation time it applies at now: the track time wrapped, or held at the duration. */\n animationTime: number;\n duration: number;\n /** The entry's weight as it stands (`PlayOptions.alpha`, `setAlpha`). */\n alpha: number;\n /** Whether the entry adds (`PlayOptions.additive`). */\n additive: boolean;\n}\n\ntype Listener<T> = (payload: T) => void;\n\n/**\n * One rig on one root.\n *\n * ```ts\n * const player = new RigPlayer(root, assets);\n * player.play('walk');\n * requestAnimationFrame(function tick(now) { player.frame(dt); requestAnimationFrame(tick); });\n * ```\n */\n/**\n * One bone's local values at a pose, read and written in place: the seven\n * channels the runtime's bone has, in its units (degrees, world-unit\n * translation, scale factors, shear in degrees). What `BoneAdjust` receives\n * through `AdjustableBones.bone`.\n */\nexport interface BoneLocals {\n rotation: number;\n x: number;\n y: number;\n scaleX: number;\n scaleY: number;\n shearX: number;\n shearY: number;\n}\n\n/** The bones of one pose, by name, as a `BoneAdjust` sees them. */\nexport interface AdjustableBones {\n /** The document's bones, in its order. */\n readonly names: readonly string[];\n /** One bone's locals, read and written in place; a name the document has no bone for is refused by name. */\n bone(name: string): BoneLocals;\n}\n\n/**\n * A caller's adjustment of a pose's bone locals — a breath's scale, a look's\n * rotation, a mouth's `scaleY` — called once per pose after the animation's\n * timelines and before the world transforms, constraints and physics (the\n * core's `openTrack({ adjust })`, held to the Spine runtime at tolerance 0\n * by rig-c). **A write lasts one pose**: the core poses every step from the\n * setup pose, so a value the caller wants held is written again each pose,\n * and nothing compounds. A non-finite value, an unknown bone, or an error the\n * function throws refuses that step in the core's words.\n */\nexport type BoneAdjust = (bones: AdjustableBones) => void;\n\n/**\n * Where a bone is in the pose the player holds — world units, Y up, the\n * numbers `rig-c/core` posed (`RawBone`): the world matrix `a b c d`, the\n * world position, the world rotation of each axis in degrees and the world\n * scale of each, and whether the bone is active under the player's skin.\n */\nexport interface BoneWorld {\n name: string;\n active: boolean;\n x: number;\n y: number;\n a: number;\n b: number;\n c: number;\n d: number;\n rotationX: number;\n rotationY: number;\n scaleX: number;\n scaleY: number;\n}\n\n/**\n * Which slots a player draws: an allow list of slot names, or a predicate\n * over the name. The pose is the whole rig's whatever the filter — bones,\n * constraints, physics, `bone()` and `adjust` are untouched — and only the\n * draw is filtered. A clipping slot the filter leaves out does not clip.\n */\nexport type SlotFilter = readonly string[] | ((slot: string) => boolean);\n\n/** A box in world units, Y up: `y` is the bottom edge. */\nexport interface PoseBounds {\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\n/** An allow list as a predicate. */\nfunction predicateOf(names: readonly string[]): (slot: string) => boolean {\n const allowed = new Set(names);\n return (slot) => allowed.has(slot);\n}\n\nexport class RigPlayer {\n /**\n * The renderer this player draws through — its knobs and counters are the\n * caller's to read and set. A `DomRenderer` in the DOM mode, a\n * `CanvasRenderer` in the canvas mode; a new object after `mode` changes.\n */\n get renderer(): DomRenderer | CanvasRenderer {\n return this.active;\n }\n /** Multiplies every step. 0 holds the pose (nothing is re-posed); negative is refused by the track. */\n timeScale = 1;\n /** The player's whole-rig colour, r g b a — multiplied into every slot's tint. Not a document value. */\n color: [number, number, number, number] = [1, 1, 1, 1];\n\n private active: DomRenderer | CanvasRenderer;\n private readonly root: HTMLElement;\n private readonly assets: ModelAssets;\n private readonly meshBackend: MeshBackend | undefined;\n private view: CompiledDocument;\n private source: FrameSource;\n private readonly read: ReadDocument;\n private skinName: string | undefined;\n private readonly seekStep: number;\n /**\n * The single live track (`openTrack`): what a plain `play` on track 0 runs\n * on, as every 1.x player did — one animation, every construct the core\n * poses, `seek` and a skin change by reopening. Null once the player is\n * composed.\n */\n private track: LiveTrack | null = null;\n /**\n * The live tracks (`openTracks`): opened by the first composing call — a\n * `play` with a mix or on another track, a `queue`, a `clear` — from the\n * single track's animation stepped to its time. The mixing is the Spine\n * runtime's, which does not mix a constraint, sequence, draw-order or\n * path-deform timeline, so such an animation is refused here and plays on\n * the single track only.\n */\n private tracks: LiveTracks | null = null;\n /** Track 0's animation and loop as `play` last set them — what `seek` and a skin change reopen. */\n private animation: string | null = null;\n private loop = true;\n /** One past the highest track touched — how many `current(track)` reads a step takes. */\n private trackCount = 0;\n /** `RigPlayerOptions.tracks`: every play opens the live tracks, never the single track. */\n private readonly trackMode: boolean;\n /** Set once anything beyond a plain play on track 0 happened: a mix, another track, a queue, a clear. `seek` and `skin` then cannot replay and refuse. */\n private beyondBase = false;\n private paused = false;\n private pose: RawPose | null = null;\n private setup: RawPose | null = null;\n private adjustFn: BoneAdjust | null = null;\n private slotFilter: SlotFilter | null = null;\n /** `slotFilter` as a predicate; every slot when null. */\n private draws: (slot: string) => boolean = () => true;\n /** Handed to every track the player opens; reads the current `adjust` so setting it later needs no reopen. */\n private readonly adjustHook: CoreLocalAdjust = (locals) => {\n if (this.adjustFn !== null) this.adjustFn(locals);\n };\n private readonly listeners = {\n event: new Set<Listener<RigEvent>>(),\n complete: new Set<Listener<RigComplete>>(),\n };\n\n constructor(root: HTMLElement, assets: ModelAssets, options: RigPlayerOptions = {}) {\n const read = assets.document as ReadDocument;\n this.read = read;\n this.skinName = options.skin;\n this.view = options.skin === undefined ? underNoSkin(read.doc) : underSkin(read.doc, options.skin);\n this.source = frameSource(this.view, read.parsed);\n this.seekStep = options.seekStep ?? 1 / 60;\n this.trackMode = options.tracks === true;\n if (!(this.seekStep > 0)) throw new Error(`seekStep must be a positive number of seconds, got ${String(options.seekStep)}`);\n this.root = root;\n this.assets = assets;\n this.meshBackend = options.meshBackend;\n this.adjustFn = options.adjust ?? null;\n if (options.slots !== undefined && options.slots !== null) this.slots = options.slots;\n this.active = this.create(options.mode ?? 'dom');\n }\n\n /**\n * How the player draws. Setting it swaps the renderer without reloading\n * anything: the old one is disposed (its elements removed, its GPU pages\n * handed back), the new one is created over the same root and the same\n * assets, `pixelRatio` and `clipping` carry over, and the pose the player\n * holds is drawn again at once.\n */\n get mode(): RenderMode {\n return this.active instanceof CanvasRenderer ? 'canvas' : 'dom';\n }\n\n set mode(mode: RenderMode) {\n if (mode !== 'dom' && mode !== 'canvas') throw new Error(`mode must be 'dom' or 'canvas', got ${String(mode)}`);\n if (mode === this.mode) return;\n const old = this.active;\n const next = this.create(mode);\n next.pixelRatio = old.pixelRatio;\n next.clipping = old.clipping;\n old.dispose();\n this.active = next;\n this.draw();\n }\n\n private create(mode: RenderMode): DomRenderer | CanvasRenderer {\n if (mode === 'canvas') {\n const renderer = new CanvasRenderer(this.root, this.assets.pageImages);\n // The rig's own framing, so the canvas starts at the size the setup pose\n // needs rather than growing into it frame by frame.\n if (this.assets.stage) renderer.reserve(this.assets.stage);\n return renderer;\n }\n if (mode !== 'dom') throw new Error(`mode must be 'dom' or 'canvas', got ${String(mode)}`);\n if (this.assets.regions === 'none') {\n throw new Error(\n \"these assets were loaded with regions: 'none' (no region bitmaps, for the canvas mode only); the DOM mode needs a load with regions 'blob' or 'data'\",\n );\n }\n const renderer = new DomRenderer(this.root, this.assets.regionImages, this.assets.pageImages);\n if (this.meshBackend) renderer.meshBackend = this.meshBackend;\n return renderer;\n }\n\n /** What track 0 plays, or null before `play` and after a `clear` of track 0 has mixed out. */\n get current(): string | null {\n return this.tracks !== null ? (this.tracks.current(0)?.animation ?? null) : this.animation;\n }\n\n /** The player's time — the running sum of the steps since `play` (or the last `seek`). */\n get time(): number {\n return this.tracks?.trackTime ?? this.track?.trackTime ?? 0;\n }\n\n /**\n * Plays `name` on a track — track 0 by default, which is what `play(name)`\n * has always meant: the first `play` opens the tracks at their first pose\n * with the physics reset there, and the pose is drawn on the next `frame`.\n * Later calls replace what the track plays: the entry it replaces mixes out\n * over `mix` seconds (0 cuts), and every entry queued on that track is\n * dropped. The pose the player holds is re-posed at once, so a held player\n * shows the change on its next `draw`. The mixing is the Spine runtime's,\n * which rig-c holds at tolerance 0; an animation keying what the tracks do\n * not mix — a constraint, a sequence, the draw order, a path's deform — is\n * refused here, by name, in the core's words.\n */\n play(name: string, options: PlayOptions = {}): void {\n const track = options.track ?? 0;\n const loop = options.loop ?? true;\n const mix = options.mix ?? 0;\n const alpha = options.alpha ?? 1;\n const additive = options.additive ?? false;\n this.paused = false;\n const plain = track === 0 && mix === 0 && alpha === 1 && !additive;\n if (!plain) this.beyondBase = true;\n if (this.tracks === null && plain && !this.trackMode) {\n // A plain play on track 0: the single live track, reopened at the\n // animation's first pose with the physics reset there.\n this.animation = name;\n this.loop = loop;\n this.track = openTrack(this.view, name, { loop, reset: 'animation', adjust: this.adjustHook });\n this.pose = this.track.first;\n return;\n }\n const tracks = this.compose();\n tracks.setAnimation(track, name, { loop, mixDuration: mix, alpha, additive });\n this.trackCount = Math.max(this.trackCount, track + 1);\n if (track === 0) {\n this.animation = name;\n this.loop = loop;\n }\n this.pose = tracks.step(0);\n }\n\n /**\n * Queues `name` after the last entry on `track` (`QueueOptions`): with\n * `delay` at or below 0 it starts when that entry completes less its own\n * `mix`, so a one-shot hands over to it across a mix; on an empty track it\n * is set. Before any `play`, the tracks are opened for it.\n */\n queue(name: string, options: QueueOptions = {}): void {\n const track = options.track ?? 0;\n this.beyondBase = true;\n const tracks = this.compose();\n tracks.addAnimation(track, name, { loop: options.loop ?? true, mixDuration: options.mix ?? 0, delay: options.delay ?? 0, alpha: options.alpha ?? 1, additive: options.additive ?? false });\n this.trackCount = Math.max(this.trackCount, track + 1);\n this.pose = tracks.step(0);\n }\n\n /**\n * Mixes `track` out to nothing over `mix` seconds — the layer or one-shot\n * gone and the tracks below showing through. Track 0 cleared shows the\n * setup pose. The pose the player holds is re-posed at once.\n */\n clear(track = 0, options: { mix?: number } = {}): void {\n this.beyondBase = true;\n const tracks = this.compose();\n tracks.setEmptyAnimation(track, options.mix ?? 0);\n this.trackCount = Math.max(this.trackCount, track + 1);\n this.pose = tracks.step(0);\n }\n\n /**\n * Queues a mix out to nothing after the last entry on `track`, over `mix`\n * seconds; with `delay` 0 (the default) the mix ends as that entry\n * completes, so a one-shot queued this way plays once and fades out over\n * its last `mix` seconds.\n */\n queueClear(track = 0, options: { mix?: number; delay?: number } = {}): void {\n this.beyondBase = true;\n const tracks = this.compose();\n tracks.addEmptyAnimation(track, options.mix ?? 0, options.delay ?? 0);\n this.trackCount = Math.max(this.trackCount, track + 1);\n this.pose = tracks.step(0);\n }\n\n /**\n * Sets the weight of `track`'s current entry, from 0 to 1, from the next pose\n * on — the pose the player holds is re-posed at once, so a held player shows\n * it on its next `draw`. An entry it is mixing from keeps its own weight. A\n * track playing nothing, or a weight outside 0..1, is refused in the core's\n * words. On the single track this composes: the player moves onto the tracks.\n */\n setAlpha(track: number, alpha: number): void {\n this.beyondBase = true;\n const tracks = this.compose();\n tracks.setAlpha(track, alpha);\n this.pose = tracks.step(0);\n }\n\n /** `track`'s current entry, or null where it plays nothing (and before `play`). */\n entry(track = 0): TrackEntry | null {\n if (this.tracks !== null) {\n const view = this.tracks.current(track);\n return view === null\n ? null\n : { animation: view.animation, loop: view.loop, trackTime: view.trackTime, animationTime: view.animationTime, duration: view.duration, alpha: view.alpha, additive: view.additive };\n }\n const single = this.track;\n if (track !== 0 || single === null) return null;\n return { animation: this.animation, loop: this.loop, trackTime: single.trackTime, animationTime: single.animationTime, duration: single.duration, alpha: 1, additive: false };\n }\n\n /** Whether the player is composed: on the live tracks rather than the single track. */\n get composed(): boolean {\n return this.tracks !== null;\n }\n\n /**\n * The live tracks, opened by the first composing call (or by the first\n * `play` under `tracks: true`). A single track in play is carried over by\n * replay: track 0 set to its animation, pose 0 taken by `start()` (the\n * player's — nothing steps before it) and the tracks stepped to the single\n * track's time in `seekStep` increments, so a physics rig's history\n * restarts there and nothing is fired on the way. The core offers no\n * hand-over of a live track's state, so that replay costs one pose per\n * `seekStep` of time played — which `tracks: true` avoids entirely.\n */\n private compose(): LiveTracks {\n if (this.tracks !== null) return this.tracks;\n const tracks = openTracks(this.view, { reset: 'animation', adjust: this.adjustHook });\n const single = this.track;\n const time = single?.trackTime ?? 0;\n if (single !== null && this.animation !== null) {\n tracks.setAnimation(0, this.animation, { loop: this.loop, mixDuration: 0 });\n this.trackCount = 1;\n }\n this.tracks = tracks;\n this.track = null;\n this.pose = tracks.start();\n if (time > 0) this.stepTo(time);\n return tracks;\n }\n\n /** Stops stepping; `frame` keeps drawing the pose it holds. */\n pause(): void {\n this.paused = true;\n }\n\n /** Resumes stepping after `pause`. */\n resume(): void {\n this.paused = false;\n }\n\n /**\n * Moves a single animation on track 0 to `time`: the tracks are reopened\n * with that animation and stepped forward in `seekStep` increments (the\n * last one shorter) until the time is reached. Events and completes crossed\n * on the way are not fired. It has a meaning for one animation on one\n * track only — the player cannot replay when a mix, a second track or a\n * queue was asked for — so after any of those it refuses by name; step the\n * player forward instead.\n */\n seek(time: number): void {\n if (this.animation === null) throw new Error('seek before play: no animation is open');\n if (!(time >= 0) || !Number.isFinite(time)) throw new Error(`seek time must be a finite time at or above 0, got ${String(time)}`);\n if (this.beyondBase) throw new Error('seek is defined for a single animation on track 0; after a mix, another track, a queue or a clear the player cannot replay to a time — step it forward with frame/advance instead');\n this.reopen();\n this.stepTo(time);\n }\n\n /** Whatever is open, opened again with track 0's animation as `play` last set it, at pose 0: the single track, or the tracks under `tracks: true`. */\n private reopen(): void {\n if (this.tracks !== null) {\n const tracks = openTracks(this.view, { reset: 'animation', adjust: this.adjustHook });\n tracks.setAnimation(0, this.animation as string, { loop: this.loop, mixDuration: 0 });\n this.trackCount = 1;\n this.tracks = tracks;\n this.pose = tracks.start();\n return;\n }\n this.track = openTrack(this.view, this.animation as string, { loop: this.loop, reset: 'animation', adjust: this.adjustHook });\n this.pose = this.track.first;\n }\n\n /** Steps whatever is open forward to `time` in `seekStep` increments, the last one shorter. */\n private stepTo(time: number): void {\n const stepper = this.tracks ?? (this.track as LiveTrack);\n const steps = Math.floor(time / this.seekStep);\n for (let i = 0; i < steps; i++) this.pose = stepper.step(this.seekStep);\n const rest = time - stepper.trackTime;\n if (rest > 0) this.pose = stepper.step(rest);\n }\n\n /** Adds a listener; returns a function that removes it. */\n on(type: 'event', listener: Listener<RigEvent>): () => void;\n on(type: 'complete', listener: Listener<RigComplete>): () => void;\n on(type: 'event' | 'complete', listener: Listener<never>): () => void {\n const set = this.listeners[type] as Set<Listener<never>>;\n set.add(listener);\n return () => set.delete(listener);\n }\n\n /**\n * Advances the track by `dt × timeScale` seconds and draws the pose —\n * `advance(dt)` then `draw()`.\n */\n frame(dt: number): void {\n this.advance(dt);\n this.draw();\n }\n\n /**\n * Steps the track by `dt × timeScale` seconds and fires the step's listeners,\n * without drawing. A paused player, or a step of zero, keeps the pose it\n * holds without re-posing it, so a held rig costs the renderer's dirty\n * checks and nothing else.\n */\n advance(dt: number): void {\n if (this.pose === null) return;\n const step = dt * this.timeScale;\n if (this.paused || !(step > 0)) return;\n const tracks = this.tracks;\n if (tracks !== null) {\n const before: Array<TrackEntryView | null> = [];\n for (let t = 0; t < this.trackCount; t++) before.push(tracks.current(t));\n this.pose = tracks.step(step);\n this.dispatch(this.pose, before, tracks);\n return;\n }\n const track = this.track;\n if (track === null) return;\n const before = track.trackTime;\n this.pose = track.step(step);\n this.dispatchSingle(this.pose, before, track);\n }\n\n /** Draws the pose the player holds. */\n draw(): void {\n if (this.pose === null) return;\n this.renderer.render(this.posedFrame());\n }\n\n /**\n * The skin the rig is posed under — `RigPlayerOptions.skin`, or undefined\n * for no skin set. Setting it re-resolves the pose under the new skin\n * (which attachment each slot shows, which bones and constraints are\n * active) and keeps the animation, its loop and its track time: the track\n * is reopened under the new skin and stepped to the same time the way\n * `seek` does, so a physics rig's history restarts there and nothing is\n * fired on the way. The pose is drawn on the next `draw`/`frame`. An\n * unknown skin is refused by name, and the player is left as it was.\n */\n get skin(): string | undefined {\n return this.skinName;\n }\n\n set skin(name: string | undefined) {\n if (name === this.skinName) return;\n if (this.beyondBase) throw new Error('skin cannot change after a mix, another track, a queue or a clear: the player cannot replay those to the current time — set it before composing, or play again');\n const view = name === undefined ? underNoSkin(this.read.doc) : underSkin(this.read.doc, name);\n this.view = view;\n this.source = frameSource(view, this.read.parsed);\n this.skinName = name;\n this.setup = null;\n if (this.animation !== null && (this.track !== null || this.tracks !== null)) {\n const time = this.time;\n this.reopen();\n this.stepTo(time);\n }\n }\n\n /**\n * Which slots this player draws (`SlotFilter`), or null for every slot.\n * Settable on a live player: the next `draw` shows it, and `bounds()` reads\n * the drawn slots. An allow list naming a slot the document does not have\n * is refused by name. The pose is the whole rig's: `bone()`, `adjust`, the\n * events and the tracks see no filter.\n */\n get slots(): SlotFilter | null {\n return this.slotFilter;\n }\n\n set slots(filter: SlotFilter | null) {\n if (filter === null) {\n this.slotFilter = null;\n this.draws = () => true;\n return;\n }\n if (typeof filter === 'function') {\n this.slotFilter = filter;\n this.draws = filter;\n return;\n }\n if (!Array.isArray(filter)) throw new Error(`slots must be an array of slot names, a function, or null, got ${typeof filter}`);\n const known = new Set(this.read.doc.slots.map((slot) => slot.name));\n const unknown = filter.filter((name) => !known.has(name));\n if (unknown.length > 0) {\n throw new Error(`no slot named ${unknown.map((n) => JSON.stringify(n)).join(', ')} in this document (slots: ${[...known].join(', ')})`);\n }\n const allowed = new Set(filter);\n this.slotFilter = [...filter];\n this.draws = (slot) => allowed.has(slot);\n }\n\n /**\n * The per-pose adjustment of bone locals (`BoneAdjust`), or null for none.\n * It is applied by every track the player opens — `play`, the reopen inside\n * `seek` — and by the pose drawn again after `mode` changes, on every pose\n * the animation is applied to, the first one included. Setting it re-poses\n * the pose the player holds at once (`repose`), so a held or paused player\n * shows the change on its next `draw` without a step.\n */\n get adjust(): BoneAdjust | null {\n return this.adjustFn;\n }\n\n set adjust(fn: BoneAdjust | null) {\n if (fn !== null && typeof fn !== 'function') throw new Error(`adjust must be a function or null, got ${typeof fn}`);\n this.adjustFn = fn;\n this.repose();\n }\n\n /**\n * Poses the held pose again at the same track time, through the current\n * `adjust`, without stepping, firing or drawing. A paused player and a zero\n * step re-pose nothing, so a caller whose adjustment reads its own state\n * (a mouth driven while the body is held) calls this when that state\n * changed, then `draw`. Nothing before `play`.\n */\n repose(): void {\n const stepper = this.tracks ?? this.track;\n if (stepper === null || this.pose === null) return;\n this.pose = stepper.step(0);\n }\n\n /**\n * Where `name` is in the pose the player holds — the pose of the last\n * `advance`/`frame`/`seek`, or the setup pose before `play`. Read off the\n * core's pose, so it is the same in `dom` and `canvas` mode and costs nothing\n * until called. An unknown bone is refused by name.\n */\n bone(name: string): BoneWorld {\n const pose = this.posed();\n for (const bone of pose.bones) {\n if (bone.name !== name) continue;\n return {\n name,\n active: bone.active,\n x: bone.worldX,\n y: bone.worldY,\n a: bone.a,\n b: bone.b,\n c: bone.c,\n d: bone.d,\n rotationX: bone.rotationX,\n rotationY: bone.rotationY,\n scaleX: bone.scaleX,\n scaleY: bone.scaleY,\n };\n }\n throw new Error(`no bone named ${JSON.stringify(name)} in this document (bones: ${pose.bones.map((b) => b.name).join(', ')})`);\n }\n\n /**\n * The box of what the pose the player holds draws, in world units, Y up:\n * every region's four corners and every mesh's vertices, in the same frame\n * record the renderer takes (`posedFrame`). A slot under a clip counts only\n * inside the clip polygon's own box (an inverse clip removes nothing from\n * the count); bounding boxes, paths and points are not drawn and do not\n * count. `null` when nothing draws. The same numbers in `dom` and `canvas`\n * mode; nothing is computed until called.\n */\n bounds(): PoseBounds | null {\n const frame = this.pose === null ? frameOf(this.source, this.posed(), this.color, this.draws) : this.posedFrame();\n let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;\n for (const slot of frame.order) {\n const points = slot.kind === 'region' ? slot.corners : slot.vertices;\n let lo = -Infinity, lb = -Infinity, hi = Infinity, hb = Infinity;\n if (slot.clip && !slot.clip.inverse) {\n const c = slot.clip.polygon;\n lo = Infinity; lb = Infinity; hi = -Infinity; hb = -Infinity;\n for (let i = 0; i < c.length; i += 2) {\n if (c[i] < lo) lo = c[i];\n if (c[i] > hi) hi = c[i];\n if (c[i + 1] < lb) lb = c[i + 1];\n if (c[i + 1] > hb) hb = c[i + 1];\n }\n }\n for (let i = 0; i < points.length; i += 2) {\n const x = Math.min(Math.max(points[i], lo), hi);\n const y = Math.min(Math.max(points[i + 1], lb), hb);\n if (x < minX) minX = x;\n if (x > maxX) maxX = x;\n if (y < minY) minY = y;\n if (y > maxY) maxY = y;\n }\n }\n if (minX === Infinity) return null;\n return { x: minX, y: minY, width: maxX - minX, height: maxY - minY };\n }\n\n /** The pose the reads above see: the track's, or the setup pose before `play` (posed once). */\n private posed(): RawPose {\n if (this.pose !== null) return this.pose;\n if (this.setup === null) this.setup = poseRawSetup(this.view);\n return this.setup;\n }\n\n /**\n * The pose the player holds, as the frame record the renderer draws — under\n * this player's `slots` filter, or under `slots` given here instead (a\n * second renderer over the same assets drawing this player's pose on\n * another root: `other.render(player.posedFrame(['hand_f']))`, the one rig\n * posed once).\n */\n posedFrame(slots?: SlotFilter | null): PosedFrame {\n if (this.pose === null) return { order: [] };\n const draws = slots === undefined ? this.draws : slots === null ? () => true : typeof slots === 'function' ? slots : predicateOf(slots);\n return frameOf(this.source, this.pose, this.color, draws);\n }\n\n /** Removes the renderer's elements and hands its GPU pages back. The assets stay the caller's. */\n dispose(): void {\n this.renderer.dispose();\n this.tracks = null;\n this.track = null;\n this.pose = null;\n }\n\n /** The single track's step: its events (track 0) and its complete, as every 1.x player fired them. */\n private dispatchSingle(pose: RawPose, before: number, track: LiveTrack): void {\n if (this.listeners.event.size > 0) {\n for (const [name, time, int, float, string] of pose.events) {\n const event: RigEvent = { name, time, int, float, string, track: 0 };\n for (const listener of this.listeners.event) listener(event);\n }\n }\n if (this.listeners.complete.size > 0) {\n const d = track.duration;\n const after = track.trackTime;\n const cycles = d > 0 ? Math.floor(after / d) : Infinity;\n const was = d > 0 ? Math.floor(before / d) : -Infinity;\n if (this.loop ? cycles > 0 && cycles > was : before < d && after >= d) {\n const payload: RigComplete = { animation: this.animation as string, track: 0 };\n for (const listener of this.listeners.complete) listener(payload);\n }\n }\n }\n\n /**\n * The step's events, then its completes, each with its track. The core\n * fires a track's keys from its current entry (`pose.events`, in track\n * order and in the runtime's order across a wrap) — an entry mixing out\n * fires none — and leaves `complete` to the player, which derives it per\n * track from that track's current entry: on a looping entry, once on a step\n * whose whole cycles rose; on a held one, on the step that reaches its\n * duration. An entry replaced inside the step — by `play`, or by a queued\n * entry starting at its completion less the mix — is no longer current and\n * completes no more than it fires, which is the runtime's rule too.\n */\n private dispatch(pose: RawPose, before: ReadonlyArray<TrackEntryView | null>, tracks: LiveTracks): void {\n const after: Array<TrackEntryView | null> = [];\n for (let t = 0; t < this.trackCount; t++) after.push(tracks.current(t));\n const same = (b: TrackEntryView | null, a: TrackEntryView | null): boolean =>\n b !== null && a !== null && b.animation === a.animation && b.loop === a.loop && a.trackTime >= b.trackTime;\n\n if (this.listeners.event.size > 0 && pose.events.length > 0) {\n // Attribute by count: what each track's current entry fired over the step.\n const counts: number[] = [];\n let total = 0;\n for (let t = 0; t < this.trackCount; t++) {\n const a = after[t];\n const b = before[t];\n let n = 0;\n if (a !== null && a.animation !== null) {\n const keys = this.view.animations.find((anim) => anim.name === a.animation)?.timelines.events ?? [];\n if (keys.length > 0) {\n const last = same(b, a) ? (b as TrackEntryView).animationTime : -1;\n n = eventsFired(keys, last, a.animationTime, undefined, a.animationTime < last).length;\n }\n }\n counts.push(n);\n total += n;\n }\n const attributed = total === pose.events.length;\n let track = 0;\n let left = counts[0] ?? 0;\n for (const [name, time, int, float, string] of pose.events) {\n if (attributed) {\n while (left === 0 && track < counts.length - 1) {\n track++;\n left = counts[track];\n }\n left--;\n }\n const event: RigEvent = attributed ? { name, time, int, float, string, track } : { name, time, int, float, string };\n for (const listener of this.listeners.event) listener(event);\n }\n }\n if (this.listeners.complete.size > 0) {\n for (let t = 0; t < this.trackCount; t++) {\n const a = after[t];\n const b = before[t];\n if (!same(b, a) || a === null || a.animation === null) continue;\n const d = a.duration;\n const cycles = d > 0 ? Math.floor(a.trackTime / d) : Infinity;\n const was = d > 0 ? Math.floor((b as TrackEntryView).trackTime / d) : -Infinity;\n const fired = a.loop ? cycles > 0 && cycles > was : (b as TrackEntryView).trackTime < d && a.trackTime >= d;\n if (!fired) continue;\n const payload: RigComplete = { animation: a.animation, track: t };\n for (const listener of this.listeners.complete) listener(payload);\n }\n }\n }\n}\n"],"names":["RAD","bone","modeOf","a","b","c","d","isRecord","finite","blendOf","frame","now","world","num","keyCurve","curveCount","total","spaceScale","x1","y1","x2","y2","cx1","cy1","cx2","cy2","cos","sin","channel","flag","valuesAt","times","target","clamp01","unknownFields","record","tl","i","ux","uy","origin","out","boneIndex","document","job","whole","renderer","before","payload"],"mappings":"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","x_google_ignoreList":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17]}