hayao 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +29 -12
- package/dist/art/autotile.d.ts +77 -0
- package/dist/art/bitmapFont.d.ts +113 -0
- package/dist/art/font5.d.ts +11 -0
- package/dist/art/palette.d.ts +38 -0
- package/dist/art/texture.d.ts +78 -0
- package/dist/audio/audio.d.ts +7 -0
- package/dist/content/dsl.d.ts +61 -0
- package/dist/core/dmath.d.ts +20 -0
- package/dist/core/math.d.ts +2 -0
- package/dist/index.d.ts +37 -1
- package/dist/index.js +4549 -69
- package/dist/index.js.map +4 -4
- package/dist/logic/fsm.d.ts +85 -0
- package/dist/logic/graph.d.ts +88 -0
- package/dist/logic/history.d.ts +54 -0
- package/dist/logic/random.d.ts +32 -0
- package/dist/net/browser.d.ts +37 -0
- package/dist/net/inputBuffer.d.ts +27 -0
- package/dist/net/lockstep.d.ts +79 -0
- package/dist/net/players.d.ts +27 -0
- package/dist/net/protocol.d.ts +100 -0
- package/dist/net/rollback.d.ts +89 -0
- package/dist/net/room.d.ts +78 -0
- package/dist/net/transport.d.ts +78 -0
- package/dist/persist/codec.d.ts +4 -0
- package/dist/persist/save.d.ts +32 -0
- package/dist/persist/storage.d.ts +46 -0
- package/dist/physics/rigidBody.d.ts +104 -0
- package/dist/physics/rigidCollide.d.ts +16 -0
- package/dist/physics/rigidJoints.d.ts +65 -0
- package/dist/physics/rigidQueries.d.ts +15 -0
- package/dist/physics/rigidStep.d.ts +14 -0
- package/dist/procgen/cave.d.ts +21 -0
- package/dist/procgen/grid.d.ts +21 -0
- package/dist/procgen/rooms.d.ts +34 -0
- package/dist/procgen/scatter.d.ts +32 -0
- package/dist/procgen/terrain.d.ts +24 -0
- package/dist/render/nineSlice.d.ts +32 -0
- package/dist/scene/floatingText.d.ts +51 -0
- package/dist/scene/particles.d.ts +64 -0
- package/dist/scene/pool.d.ts +16 -0
- package/dist/scene/tween.d.ts +26 -0
- package/dist/ui/transition.d.ts +107 -0
- package/dist/verify/layout.d.ts +39 -0
- package/docs/API.md +247 -8
- package/package.json +31 -9
package/dist/index.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../src/core/math.ts", "../src/core/rng.ts", "../src/core/clock.ts", "../src/core/events.ts", "../src/core/hash.ts", "../src/scene/node.ts", "../src/scene/nodes.ts", "../src/scene/tween.ts", "../src/scene/particles.ts", "../src/scene/registry.ts", "../src/input/actions.ts", "../src/input/source.ts", "../src/physics/tilemap.ts", "../src/physics/aabb.ts", "../src/physics/platformer.ts", "../src/physics/spatialHash.ts", "../src/physics/raycast.ts", "../src/render/commands.ts", "../src/render/svgString.ts", "../src/render/svg.ts", "../src/render/canvas.ts", "../src/render/headless.ts", "../src/art/palette.ts", "../src/art/shapes.ts", "../src/audio/audio.ts", "../src/ui/overlay.ts", "../src/ui/settings.ts", "../src/ui/shell.ts", "../src/verify/solver.ts", "../src/verify/determinism.ts", "../src/verify/playthrough.ts", "../src/verify/capture.ts", "../src/verify/driver.ts", "../src/verify/bot.ts", "../src/verify/feel.ts", "../src/verify/filmstrip.ts", "../src/world.ts", "../src/app/game.ts", "../src/app/browser.ts", "../src/index.ts"],
|
|
4
|
-
"sourcesContent": ["// Deterministic 2D math. Plain data + pure functions (no classes with hidden\n// state) so everything serializes and hashes cleanly.\n\nexport interface Vec2 {\n x: number;\n y: number;\n}\n\nexport const vec2 = (x = 0, y = 0): Vec2 => ({ x, y });\nexport const vadd = (a: Vec2, b: Vec2): Vec2 => ({ x: a.x + b.x, y: a.y + b.y });\nexport const vsub = (a: Vec2, b: Vec2): Vec2 => ({ x: a.x - b.x, y: a.y - b.y });\nexport const vscale = (a: Vec2, s: number): Vec2 => ({ x: a.x * s, y: a.y * s });\nexport const vdot = (a: Vec2, b: Vec2): number => a.x * b.x + a.y * b.y;\nexport const vlen = (a: Vec2): number => Math.hypot(a.x, a.y);\nexport const vdist = (a: Vec2, b: Vec2): number => Math.hypot(a.x - b.x, a.y - b.y);\nexport function vnorm(a: Vec2): Vec2 {\n const l = vlen(a);\n return l === 0 ? { x: 0, y: 0 } : { x: a.x / l, y: a.y / l };\n}\n\nexport const clamp = (v: number, lo: number, hi: number): number => (v < lo ? lo : v > hi ? hi : v);\nexport const lerp = (a: number, b: number, t: number): number => a + (b - a) * t;\nexport const invLerp = (a: number, b: number, v: number): number => (a === b ? 0 : (v - a) / (b - a));\nexport const remap = (v: number, a0: number, a1: number, b0: number, b1: number): number =>\n lerp(b0, b1, invLerp(a0, a1, v));\n\nexport const TAU = Math.PI * 2;\nexport const deg2rad = (d: number): number => (d * Math.PI) / 180;\nexport const rad2deg = (r: number): number => (r * 180) / Math.PI;\n\n/** Axis-aligned rectangle. */\nexport interface Rect {\n x: number;\n y: number;\n w: number;\n h: number;\n}\n\nexport function rectContains(r: Rect, p: Vec2): boolean {\n return p.x >= r.x && p.x <= r.x + r.w && p.y >= r.y && p.y <= r.y + r.h;\n}\n\nexport function rectsOverlap(a: Rect, b: Rect): boolean {\n return a.x < b.x + b.w && a.x + a.w > b.x && a.y < b.y + b.h && a.y + a.h > b.y;\n}\n\n/** 2D affine transform as a 6-value matrix [a b c d e f] (like SVG/Canvas). */\nexport interface Transform {\n a: number;\n b: number;\n c: number;\n d: number;\n e: number;\n f: number;\n}\n\nexport const IDENTITY: Transform = { a: 1, b: 0, c: 0, d: 1, e: 0, f: 0 };\n\nexport function composeTransform(m: Transform, n: Transform): Transform {\n return {\n a: m.a * n.a + m.c * n.b,\n b: m.b * n.a + m.d * n.b,\n c: m.a * n.c + m.c * n.d,\n d: m.b * n.c + m.d * n.d,\n e: m.a * n.e + m.c * n.f + m.e,\n f: m.b * n.e + m.d * n.f + m.f,\n };\n}\n\n/** Build a transform from position, rotation (radians), scale. */\nexport function makeTransform(pos: Vec2, rotation: number, scale: Vec2): Transform {\n const cos = Math.cos(rotation);\n const sin = Math.sin(rotation);\n return {\n a: cos * scale.x,\n b: sin * scale.x,\n c: -sin * scale.y,\n d: cos * scale.y,\n e: pos.x,\n f: pos.y,\n };\n}\n\nexport function applyTransform(m: Transform, p: Vec2): Vec2 {\n return { x: m.a * p.x + m.c * p.y + m.e, y: m.b * p.x + m.d * p.y + m.f };\n}\n\n/** Invert an affine transform (returns identity if singular). */\nexport function invertTransform(m: Transform): Transform {\n const det = m.a * m.d - m.b * m.c;\n if (det === 0) return { ...IDENTITY };\n const id = 1 / det;\n return {\n a: m.d * id,\n b: -m.b * id,\n c: -m.c * id,\n d: m.a * id,\n e: (m.c * m.f - m.d * m.e) * id,\n f: (m.b * m.e - m.a * m.f) * id,\n };\n}\n", "// Deterministic, seedable, splittable RNG. SplitMix64 for seeding, xoshiro128**\n// for the stream \u2014 fast, good distribution, trivially reproducible.\n// Every random draw in a game MUST flow through here (never Math.random()).\n\nfunction splitmix32(seed: number): () => number {\n let a = seed >>> 0;\n return () => {\n a = (a + 0x9e3779b9) >>> 0;\n let t = a;\n t = Math.imul(t ^ (t >>> 16), 0x21f0aaad);\n t = Math.imul(t ^ (t >>> 15), 0x735a2d97);\n return (t ^ (t >>> 15)) >>> 0;\n };\n}\n\nexport interface RngState {\n s: [number, number, number, number];\n}\n\nexport class Rng {\n private s0: number;\n private s1: number;\n private s2: number;\n private s3: number;\n\n constructor(seed: number | RngState = 0) {\n if (typeof seed === 'number') {\n const sm = splitmix32(seed === 0 ? 0x1234abcd : seed);\n this.s0 = sm();\n this.s1 = sm();\n this.s2 = sm();\n this.s3 = sm();\n } else {\n [this.s0, this.s1, this.s2, this.s3] = seed.s;\n }\n }\n\n /** Raw 32-bit unsigned integer. */\n private next(): number {\n const result = (Math.imul(this.rotl(Math.imul(this.s1, 5), 7), 9) >>> 0);\n const t = (this.s1 << 9) >>> 0;\n this.s2 ^= this.s0;\n this.s3 ^= this.s1;\n this.s1 ^= this.s2;\n this.s0 ^= this.s3;\n this.s2 = (this.s2 ^ t) >>> 0;\n this.s3 = this.rotl(this.s3, 11);\n return result >>> 0;\n }\n\n private rotl(x: number, k: number): number {\n return (((x << k) | (x >>> (32 - k))) >>> 0);\n }\n\n /** Float in [0, 1). */\n float(): number {\n return this.next() / 4294967296;\n }\n\n /** Float in [lo, hi). */\n range(lo: number, hi: number): number {\n return lo + this.float() * (hi - lo);\n }\n\n /** Integer in [0, n). */\n int(n: number): number {\n return Math.floor(this.float() * n);\n }\n\n /** Integer in [lo, hi] inclusive. */\n intRange(lo: number, hi: number): number {\n return lo + this.int(hi - lo + 1);\n }\n\n /** True with probability p. */\n chance(p: number): boolean {\n return this.float() < p;\n }\n\n /** Uniform element of an array. */\n pick<T>(arr: readonly T[]): T {\n return arr[this.int(arr.length)];\n }\n\n /** In-place Fisher\u2013Yates shuffle (deterministic). */\n shuffle<T>(arr: T[]): T[] {\n for (let i = arr.length - 1; i > 0; i--) {\n const j = this.int(i + 1);\n [arr[i], arr[j]] = [arr[j], arr[i]];\n }\n return arr;\n }\n\n /**\n * Derive an independent child stream. Same parent state + same key always\n * yields the same child \u2014 so subsystems (enemy AI, loot, terrain) get stable,\n * decorrelated randomness without threading one generator through everything.\n */\n split(key = 0): Rng {\n const mix = (this.s0 ^ Math.imul(key + 1, 0x9e3779b9)) >>> 0;\n const child = new Rng(mix ^ this.s3);\n // Advance parent so repeated splits differ.\n this.next();\n return child;\n }\n\n /** Serialize / restore for saves and replay. */\n getState(): RngState {\n return { s: [this.s0, this.s1, this.s2, this.s3] };\n }\n setState(state: RngState): void {\n [this.s0, this.s1, this.s2, this.s3] = state.s;\n }\n}\n\n/** Deterministic 32-bit FNV-1a hash of a string \u2014 handy for stable ids/seeds. */\nexport function hashString(str: string): number {\n let h = 2166136261 >>> 0;\n for (let i = 0; i < str.length; i++) {\n h ^= str.charCodeAt(i);\n h = Math.imul(h, 16777619);\n }\n return h >>> 0;\n}\n", "// Fixed-timestep clock. Real elapsed milliseconds go in; whole fixed steps come\n// out. This is what makes the sim frame-rate independent AND exactly reproducible:\n// the same input log always yields the same number of steps.\n\nexport interface ClockConfig {\n /** Simulation rate in Hz (steps per second). Default 60. */\n hz?: number;\n /** Max real ms consumed per advance, to avoid a spiral of death. Default 250. */\n maxFrameMs?: number;\n}\n\nexport class Clock {\n readonly stepMs: number;\n readonly dt: number; // fixed delta in seconds, for game logic\n private maxFrameMs: number;\n private accumulator = 0;\n private _frame = 0;\n private _simTimeMs = 0;\n\n constructor(config: ClockConfig = {}) {\n const hz = config.hz ?? 60;\n this.stepMs = 1000 / hz;\n this.dt = 1 / hz;\n this.maxFrameMs = config.maxFrameMs ?? 250;\n }\n\n /**\n * Feed real elapsed ms; returns how many fixed steps to run now.\n * Caller runs the sim exactly that many times.\n */\n advance(realMs: number): number {\n this.accumulator += Math.min(realMs, this.maxFrameMs);\n let steps = 0;\n while (this.accumulator >= this.stepMs) {\n this.accumulator -= this.stepMs;\n steps++;\n }\n return steps;\n }\n\n /** Called by the World once per executed step to keep counters honest. */\n tick(): void {\n this._frame++;\n this._simTimeMs += this.stepMs;\n }\n\n /** Interpolation alpha in [0,1) for smooth rendering between fixed steps. */\n get alpha(): number {\n return this.accumulator / this.stepMs;\n }\n\n get frame(): number {\n return this._frame;\n }\n get simTimeMs(): number {\n return this._simTimeMs;\n }\n get simTimeSec(): number {\n return this._simTimeMs / 1000;\n }\n\n getState() {\n return { accumulator: this.accumulator, frame: this._frame, simTimeMs: this._simTimeMs };\n }\n setState(s: { accumulator: number; frame: number; simTimeMs: number }): void {\n this.accumulator = s.accumulator;\n this._frame = s.frame;\n this._simTimeMs = s.simTimeMs;\n }\n}\n", "// Synchronous typed signal bus (Godot-style signals). Deterministic: listeners\n// fire in connection order, synchronously, within the current step.\n\nexport type Listener<T> = (payload: T) => void;\n\nexport class Signal<T = void> {\n private listeners: Listener<T>[] = [];\n\n connect(fn: Listener<T>): () => void {\n this.listeners.push(fn);\n return () => this.disconnect(fn);\n }\n\n once(fn: Listener<T>): () => void {\n const off = this.connect((p) => {\n off();\n fn(p);\n });\n return off;\n }\n\n disconnect(fn: Listener<T>): void {\n const i = this.listeners.indexOf(fn);\n if (i >= 0) this.listeners.splice(i, 1);\n }\n\n emit(payload: T): void {\n // Copy so a listener disconnecting mid-emit doesn't skip its neighbor.\n for (const fn of this.listeners.slice()) fn(payload);\n }\n\n get count(): number {\n return this.listeners.length;\n }\n\n clear(): void {\n this.listeners.length = 0;\n }\n}\n\n/**\n * A named event bus for cross-cutting game events, keyed by an event map so\n * payloads are typed. Prefer node-local Signals for local wiring; use the bus\n * for global concerns (score changed, level complete, sound cue).\n */\nexport class EventBus<Events extends Record<string, unknown>> {\n private signals = new Map<keyof Events, Signal<unknown>>();\n\n private signalFor<K extends keyof Events>(key: K): Signal<Events[K]> {\n let s = this.signals.get(key);\n if (!s) {\n s = new Signal<unknown>();\n this.signals.set(key, s);\n }\n return s as unknown as Signal<Events[K]>;\n }\n\n on<K extends keyof Events>(key: K, fn: Listener<Events[K]>): () => void {\n return this.signalFor(key).connect(fn);\n }\n\n once<K extends keyof Events>(key: K, fn: Listener<Events[K]>): () => void {\n return this.signalFor(key).once(fn);\n }\n\n emit<K extends keyof Events>(key: K, payload: Events[K]): void {\n this.signalFor(key).emit(payload);\n }\n\n clear(): void {\n this.signals.clear();\n }\n}\n", "// Deterministic structural hash of any JSON-like value. The spine of replay\n// verification: two runs are identical iff their state hashes match.\n\nfunction canonicalNumber(n: number): string {\n if (Number.isNaN(n)) return 'NaN';\n if (n === Infinity) return 'Inf';\n if (n === -Infinity) return '-Inf';\n if (n === 0) return '0'; // collapse -0 and 0\n return n.toString();\n}\n\n/**\n * Walk a value in a canonical order (object keys sorted) and fold it into a\n * 64-bit-ish FNV-1a hash represented as an 8-char hex string. Stable across runs\n * for structurally identical data.\n */\nexport function hashValue(value: unknown): string {\n let h1 = 2166136261 >>> 0;\n let h2 = 0x811c9dc5 >>> 0;\n const push = (s: string) => {\n for (let i = 0; i < s.length; i++) {\n const c = s.charCodeAt(i);\n h1 = Math.imul(h1 ^ c, 16777619) >>> 0;\n h2 = Math.imul(h2 ^ ((c << 3) | (c >>> 5)), 2246822519) >>> 0;\n }\n };\n\n const walk = (v: unknown): void => {\n if (v === null) return push('n');\n if (v === undefined) return push('u');\n switch (typeof v) {\n case 'number':\n return push('#' + canonicalNumber(v));\n case 'boolean':\n return push(v ? 't' : 'f');\n case 'string':\n return push('\"' + v);\n case 'object': {\n if (Array.isArray(v)) {\n push('[');\n for (const el of v) walk(el);\n push(']');\n return;\n }\n const obj = v as Record<string, unknown>;\n const keys = Object.keys(obj).sort();\n push('{');\n for (const k of keys) {\n push(k + ':');\n walk(obj[k]);\n }\n push('}');\n return;\n }\n default:\n push('?');\n }\n };\n\n walk(value);\n const hex = (n: number) => n.toString(16).padStart(8, '0');\n return hex(h1) + hex(h2);\n}\n", "// The scene node: a Godot-style tree element with a transform, lifecycle,\n// children, local signals, and attachable behaviors. Updates run in fixed tree\n// order (depth-first, child-index order) which keeps the whole tree deterministic.\n\nimport type { Rng } from '../core/rng';\nimport type { Clock } from '../core/clock';\nimport { Signal } from '../core/events';\nimport {\n IDENTITY,\n composeTransform,\n makeTransform,\n type Transform,\n type Vec2,\n} from '../core/math';\nimport type { DrawCommand } from '../render/commands';\n\n/** What a live node can see of its host world. The World implements this. */\nexport interface WorldContext {\n readonly rng: Rng;\n readonly clock: Clock;\n /** Queue a node to be freed at the end of the current step (safe during iteration). */\n requestFree(node: Node): void;\n /** Seconds elapsed in sim time. */\n readonly time: number;\n}\n\n/** A composable update unit attached to a node (favour over deep inheritance). */\nexport interface Behavior {\n ready?(node: Node): void;\n update?(node: Node, dt: number): void;\n exit?(node: Node): void;\n /** Optional tag for lookup/serialization. */\n readonly kind?: string;\n}\n\nlet __idCounter = 0;\n/** Deterministic id source \u2014 reset by the World on load so ids are reproducible. */\nexport function resetNodeIds(start = 0): void {\n __idCounter = start;\n}\n\nexport interface NodeConfig {\n name?: string;\n pos?: Vec2;\n rotation?: number;\n scale?: Vec2;\n z?: number;\n visible?: boolean;\n}\n\nexport class Node {\n readonly id: string;\n name: string;\n /** Type tag for serialization; subclasses override. */\n readonly type: string = 'Node';\n\n pos: Vec2;\n rotation: number;\n scale: Vec2;\n z: number;\n visible: boolean;\n /**\n * Cosmetic nodes are pure *view* (derived from game state, rebuildable) and are\n * excluded from serialize()/snapshot()/hash(). Mark a container cosmetic when it\n * only renders state that lives elsewhere \u2014 so transient display (move counters,\n * particles, tweened positions) never pollutes the canonical, verifiable state.\n */\n cosmetic = false;\n\n parent: Node | null = null;\n readonly children: Node[] = [];\n world: WorldContext | null = null;\n\n /** Optional inline update without subclassing: node.onUpdate = (n, dt) => {\u2026}. */\n onUpdate?: (node: Node, dt: number) => void;\n\n private behaviors: Behavior[] = [];\n private signals = new Map<string, Signal<unknown>>();\n private _ready = false;\n private _freed = false;\n\n constructor(config: NodeConfig = {}) {\n this.id = `n${__idCounter++}`;\n this.name = config.name ?? this.constructor.name;\n this.pos = config.pos ? { ...config.pos } : { x: 0, y: 0 };\n this.rotation = config.rotation ?? 0;\n this.scale = config.scale ? { ...config.scale } : { x: 1, y: 1 };\n this.z = config.z ?? 0;\n this.visible = config.visible ?? true;\n }\n\n // \u2500\u2500 Tree structure \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n addChild<T extends Node>(child: T): T {\n child.parent = this;\n this.children.push(child);\n if (this.world && this._ready) child.enterTree(this.world);\n return child;\n }\n\n removeChild(child: Node): void {\n const i = this.children.indexOf(child);\n if (i >= 0) {\n this.children.splice(i, 1);\n child.parent = null;\n }\n }\n\n /** Deferred free: runs exit hooks and detaches at the end of the step. */\n free(): void {\n this.world?.requestFree(this);\n }\n\n /** Depth-first find by name. */\n find(name: string): Node | null {\n if (this.name === name) return this;\n for (const c of this.children) {\n const r = c.find(name);\n if (r) return r;\n }\n return null;\n }\n\n /** All descendants (and self) of a given type tag. */\n query(type: string, out: Node[] = []): Node[] {\n if (this.type === type) out.push(this);\n for (const c of this.children) c.query(type, out);\n return out;\n }\n\n // \u2500\u2500 Behaviors \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n addBehavior(b: Behavior): this {\n this.behaviors.push(b);\n if (this._ready) b.ready?.(this);\n return this;\n }\n\n // \u2500\u2500 Signals \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n signal<T = void>(name: string): Signal<T> {\n let s = this.signals.get(name);\n if (!s) {\n s = new Signal<unknown>();\n this.signals.set(name, s);\n }\n return s as unknown as Signal<T>;\n }\n emit<T>(name: string, payload: T): void {\n this.signals.get(name)?.emit(payload);\n }\n\n // \u2500\u2500 Lifecycle (engine-called) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n enterTree(world: WorldContext): void {\n this.world = world;\n if (!this._ready) {\n this._ready = true;\n this.onReady();\n for (const b of this.behaviors) b.ready?.(this);\n }\n for (const c of this.children) c.enterTree(world);\n }\n\n updateTree(dt: number): void {\n if (this._freed) return;\n for (const b of this.behaviors) b.update?.(this, dt);\n this.onUpdate?.(this, dt);\n this.onProcess(dt);\n // Copy children so structural changes during update are safe.\n for (const c of this.children.slice()) c.updateTree(dt);\n }\n\n exitTree(): void {\n for (const b of this.behaviors) b.exit?.(this);\n this.onExit();\n for (const c of this.children.slice()) c.exitTree();\n this._freed = true;\n }\n\n get isFreed(): boolean {\n return this._freed;\n }\n\n // \u2500\u2500 Transforms \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n localTransform(): Transform {\n return makeTransform(this.pos, this.rotation, this.scale);\n }\n\n worldTransform(): Transform {\n const local = this.localTransform();\n return this.parent ? composeTransform(this.parent.worldTransform(), local) : local;\n }\n\n // \u2500\u2500 Rendering (projection) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n /** Walk the subtree, appending draw commands with computed world transforms. */\n collectDraw(out: DrawCommand[], parentWorld: Transform = IDENTITY): void {\n if (!this.visible) return;\n const world = composeTransform(parentWorld, this.localTransform());\n this.draw(out, world);\n for (const c of this.children) c.collectDraw(out, world);\n }\n\n /** Subclasses emit their own commands here. Base draws nothing. */\n protected draw(_out: DrawCommand[], _world: Transform): void {}\n\n // \u2500\u2500 Overridable hooks \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n protected onReady(): void {}\n protected onProcess(_dt: number): void {}\n protected onExit(): void {}\n\n // \u2500\u2500 Serialization (data only; behaviors/closures are re-attached by scene code) \u2500\u2500\n serialize(): SerializedNode {\n return {\n type: this.type,\n name: this.name,\n pos: { ...this.pos },\n rotation: this.rotation,\n scale: { ...this.scale },\n z: this.z,\n visible: this.visible,\n props: this.serializeProps(),\n children: this.children.filter((c) => !c.cosmetic).map((c) => c.serialize()),\n };\n }\n /** Subclasses persist their own fields here. */\n protected serializeProps(): Record<string, unknown> {\n return {};\n }\n /** Subclasses restore their own fields here. */\n applyProps(_props: Record<string, unknown>): void {}\n}\n\nexport interface SerializedNode {\n type: string;\n name: string;\n pos: Vec2;\n rotation: number;\n scale: Vec2;\n z: number;\n visible: boolean;\n props: Record<string, unknown>;\n children: SerializedNode[];\n}\n", "// Concrete node types built on Node. Code-as-art: a Sprite is a vector shape or\n// glyph, never a bitmap. Text is a DOM-quality label. Camera2D drives the view.\n// Timer is a deterministic countdown that emits a signal.\n\nimport type { Transform } from '../core/math';\nimport type { DrawCommand, Paint, TextAlign } from '../render/commands';\nimport { Node, type NodeConfig, type WorldContext } from './node';\n\n// \u2500\u2500 Sprite \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport type Shape =\n | { kind: 'rect'; w: number; h: number; r?: number }\n | { kind: 'circle'; radius: number }\n | { kind: 'poly'; points: number[]; closed?: boolean }\n | { kind: 'path'; d: string }\n | { kind: 'glyph'; char: string; size: number };\n\nexport interface SpriteConfig extends NodeConfig, Paint {\n shape: Shape;\n}\n\nexport class Sprite extends Node {\n override readonly type = 'Sprite';\n shape: Shape;\n paint: Paint;\n\n constructor(config: SpriteConfig) {\n super(config);\n this.shape = config.shape;\n this.paint = {\n fill: config.fill,\n stroke: config.stroke,\n strokeWidth: config.strokeWidth,\n opacity: config.opacity,\n round: config.round,\n };\n }\n\n protected override draw(out: DrawCommand[], world: Transform): void {\n const p = this.paint;\n const base = { transform: world, z: this.z, ...p };\n switch (this.shape.kind) {\n case 'rect':\n out.push({ kind: 'rect', x: -this.shape.w / 2, y: -this.shape.h / 2, w: this.shape.w, h: this.shape.h, r: this.shape.r, ...base });\n break;\n case 'circle':\n out.push({ kind: 'circle', cx: 0, cy: 0, radius: this.shape.radius, ...base });\n break;\n case 'poly':\n out.push({ kind: 'poly', points: this.shape.points, closed: this.shape.closed ?? true, ...base });\n break;\n case 'path':\n out.push({ kind: 'path', d: this.shape.d, ...base });\n break;\n case 'glyph':\n out.push({ kind: 'text', text: this.shape.char, x: 0, y: 0, size: this.shape.size, align: 'center', ...base });\n break;\n }\n }\n\n protected override serializeProps(): Record<string, unknown> {\n return { shape: this.shape, paint: this.paint };\n }\n override applyProps(props: Record<string, unknown>): void {\n if (props.shape) this.shape = props.shape as Shape;\n if (props.paint) this.paint = props.paint as Paint;\n }\n}\n\n// \u2500\u2500 Text \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport interface TextConfig extends NodeConfig, Paint {\n text: string;\n size?: number;\n font?: string;\n align?: TextAlign;\n weight?: number;\n}\n\nexport class Text extends Node {\n override readonly type = 'Text';\n text: string;\n size: number;\n font?: string;\n align: TextAlign;\n weight?: number;\n paint: Paint;\n\n constructor(config: TextConfig) {\n super(config);\n this.text = config.text;\n this.size = config.size ?? 24;\n this.font = config.font;\n this.align = config.align ?? 'left';\n this.weight = config.weight;\n this.paint = { fill: config.fill ?? '#000', stroke: config.stroke, strokeWidth: config.strokeWidth, opacity: config.opacity };\n }\n\n protected override draw(out: DrawCommand[], world: Transform): void {\n out.push({\n kind: 'text', text: this.text, x: 0, y: 0, size: this.size, font: this.font,\n align: this.align, weight: this.weight, transform: world, z: this.z, ...this.paint,\n });\n }\n\n protected override serializeProps(): Record<string, unknown> {\n return { text: this.text, size: this.size, align: this.align, paint: this.paint };\n }\n override applyProps(props: Record<string, unknown>): void {\n if (typeof props.text === 'string') this.text = props.text;\n if (typeof props.size === 'number') this.size = props.size;\n if (props.align) this.align = props.align as TextAlign;\n if (props.paint) this.paint = props.paint as Paint;\n }\n}\n\n// \u2500\u2500 Camera2D \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport interface CameraConfig extends NodeConfig {\n zoom?: number;\n /** Make this the active camera on ready. */\n current?: boolean;\n}\n\nexport class Camera2D extends Node {\n override readonly type = 'Camera2D';\n zoom: number;\n current: boolean;\n\n constructor(config: CameraConfig = {}) {\n super(config);\n this.zoom = config.zoom ?? 1;\n this.current = config.current ?? true;\n }\n\n protected override onReady(): void {\n if (this.current) (this.world as WorldContext & { activeCamera?: Camera2D }).activeCamera = this;\n }\n\n protected override serializeProps(): Record<string, unknown> {\n return { zoom: this.zoom, current: this.current };\n }\n override applyProps(props: Record<string, unknown>): void {\n if (typeof props.zoom === 'number') this.zoom = props.zoom;\n if (typeof props.current === 'boolean') this.current = props.current;\n }\n}\n\n// \u2500\u2500 Timer \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport interface TimerConfig extends NodeConfig {\n duration: number; // seconds\n autostart?: boolean;\n oneShot?: boolean;\n}\n\nexport class Timer extends Node {\n override readonly type = 'Timer';\n duration: number;\n oneShot: boolean;\n private remaining: number;\n private running: boolean;\n\n constructor(config: TimerConfig) {\n super(config);\n this.duration = config.duration;\n this.oneShot = config.oneShot ?? true;\n this.remaining = config.duration;\n this.running = config.autostart ?? true;\n }\n\n start(duration?: number): void {\n if (duration !== undefined) this.duration = duration;\n this.remaining = this.duration;\n this.running = true;\n }\n stop(): void {\n this.running = false;\n }\n\n get timeLeft(): number {\n return this.remaining;\n }\n\n protected override onProcess(dt: number): void {\n if (!this.running) return;\n this.remaining -= dt;\n if (this.remaining <= 0) {\n this.emit('timeout', undefined);\n if (this.oneShot) this.running = false;\n else this.remaining += this.duration;\n }\n }\n\n /** Signal emitted when the countdown reaches zero. */\n get timeout() {\n return this.signal('timeout');\n }\n\n protected override serializeProps(): Record<string, unknown> {\n return { duration: this.duration, oneShot: this.oneShot, remaining: this.remaining, running: this.running };\n }\n override applyProps(props: Record<string, unknown>): void {\n if (typeof props.duration === 'number') this.duration = props.duration;\n if (typeof props.oneShot === 'boolean') this.oneShot = props.oneShot;\n if (typeof props.remaining === 'number') this.remaining = props.remaining;\n if (typeof props.running === 'boolean') this.running = props.running;\n }\n}\n", "// Deterministic tweening. Tweens advance by the fixed dt, so animations are\n// exactly reproducible. Tweens animate via setter closures (transient visual\n// polish \u2014 not part of the hashed logic state), Godot AnimationPlayer-style.\n\nimport { clamp } from '../core/math';\nimport { Node } from './node';\n\nexport type Easing = (t: number) => number;\n\nconst pow = Math.pow;\nexport const EASINGS: Record<string, Easing> = {\n linear: (t) => t,\n quadIn: (t) => t * t,\n quadOut: (t) => 1 - (1 - t) * (1 - t),\n quadInOut: (t) => (t < 0.5 ? 2 * t * t : 1 - pow(-2 * t + 2, 2) / 2),\n cubicIn: (t) => t * t * t,\n cubicOut: (t) => 1 - pow(1 - t, 3),\n cubicInOut: (t) => (t < 0.5 ? 4 * t * t * t : 1 - pow(-2 * t + 2, 3) / 2),\n sineIn: (t) => 1 - Math.cos((t * Math.PI) / 2),\n sineOut: (t) => Math.sin((t * Math.PI) / 2),\n sineInOut: (t) => -(Math.cos(Math.PI * t) - 1) / 2,\n backOut: (t) => {\n const c1 = 1.70158;\n const c3 = c1 + 1;\n return 1 + c3 * pow(t - 1, 3) + c1 * pow(t - 1, 2);\n },\n elasticOut: (t) => {\n const c4 = (2 * Math.PI) / 3;\n return t === 0 ? 0 : t === 1 ? 1 : pow(2, -10 * t) * Math.sin((t * 10 - 0.75) * c4) + 1;\n },\n bounceOut: (t) => {\n const n1 = 7.5625;\n const d1 = 2.75;\n if (t < 1 / d1) return n1 * t * t;\n if (t < 2 / d1) return n1 * (t -= 1.5 / d1) * t + 0.75;\n if (t < 2.5 / d1) return n1 * (t -= 2.25 / d1) * t + 0.9375;\n return n1 * (t -= 2.625 / d1) * t + 0.984375;\n },\n};\n\ninterface Track {\n apply: (v: number) => void;\n from: number;\n to: number;\n duration: number;\n elapsed: number;\n ease: Easing;\n onDone?: () => void;\n delay: number;\n}\n\n/** A node that runs one or more property tweens and reports when they finish. */\nexport class AnimationPlayer extends Node {\n override readonly type = 'AnimationPlayer';\n private tracks: Track[] = [];\n\n /**\n * Animate a value from \u2192 to over `duration` seconds via `apply(value)`.\n * Returns this for chaining.\n */\n to(\n apply: (v: number) => void,\n from: number,\n to: number,\n duration: number,\n ease: keyof typeof EASINGS | Easing = 'cubicOut',\n opts: { delay?: number; onDone?: () => void } = {},\n ): this {\n this.tracks.push({\n apply,\n from,\n to,\n duration: Math.max(1e-6, duration),\n elapsed: 0,\n ease: typeof ease === 'function' ? ease : EASINGS[ease] ?? EASINGS.linear,\n delay: opts.delay ?? 0,\n onDone: opts.onDone,\n });\n return this;\n }\n\n get active(): boolean {\n return this.tracks.length > 0;\n }\n\n /** Signal emitted when all tracks complete. */\n get finished() {\n return this.signal('finished');\n }\n\n protected override onProcess(dt: number): void {\n if (this.tracks.length === 0) return;\n for (let i = this.tracks.length - 1; i >= 0; i--) {\n const tk = this.tracks[i];\n if (tk.delay > 0) {\n tk.delay -= dt;\n continue;\n }\n tk.elapsed += dt;\n const t = clamp(tk.elapsed / tk.duration, 0, 1);\n tk.apply(tk.from + (tk.to - tk.from) * tk.ease(t));\n if (t >= 1) {\n tk.onDone?.();\n this.tracks.splice(i, 1);\n }\n }\n if (this.tracks.length === 0) this.emit('finished', undefined);\n }\n}\n", "// Particles + screen shake: the juice kit. Both are COSMETIC by construction \u2014\n// they carry their own tiny Rng stream (never the world's), are excluded from\n// hashing/serialization, and can be deleted without changing any game outcome.\n// Emission is driven by sim events (jumped, landed, hit\u2026), so replays produce\n// identical visuals, but no canonical state ever depends on them.\n\nimport { Rng } from '../core/rng';\nimport { TAU, type Transform, type Vec2 } from '../core/math';\nimport type { DrawCommand } from '../render/commands';\nimport { Node, type NodeConfig } from './node';\n\nexport interface ParticleStyle {\n /** Colors drawn from at random per particle. */\n colors: string[];\n /** Particle radius range (px). */\n sizeMin: number;\n sizeMax: number;\n /** Initial speed range (px/s). */\n speedMin: number;\n speedMax: number;\n /** Emission arc: center angle + spread (radians). Default: full circle. */\n angle?: number;\n spread?: number;\n /** Lifetime range (s). */\n lifeMin: number;\n lifeMax: number;\n /** Gravity applied to particles (px/s\u00B2, +y is down). */\n gravity?: number;\n /** Velocity damping per second (0 = none, 5 = strong). */\n drag?: number;\n /** Shrink to zero over life (default true; also fades opacity). */\n shrink?: boolean;\n}\n\ninterface Particle {\n x: number;\n y: number;\n vx: number;\n vy: number;\n life: number;\n maxLife: number;\n size: number;\n color: string;\n}\n\n/**\n * A pooled particle emitter node. Call `burst(n, at, style)` from game code in\n * response to feel events. Always cosmetic; safe to add anywhere in the tree.\n */\nexport class Particles extends Node {\n override readonly type: string = 'Particles';\n private pool: Particle[] = [];\n private rng: Rng;\n /** Cap on live particles (oldest are recycled first). */\n maxParticles: number;\n\n constructor(config: NodeConfig & { seed?: number; maxParticles?: number } = {}) {\n super(config);\n this.cosmetic = true;\n this.rng = new Rng(config.seed ?? 7);\n this.maxParticles = config.maxParticles ?? 512;\n }\n\n /** Emit a burst at a position (in this node's local space). */\n burst(count: number, at: Vec2, style: ParticleStyle): void {\n const r = this.rng;\n for (let i = 0; i < count; i++) {\n const angle = style.angle !== undefined ? style.angle + (r.float() - 0.5) * (style.spread ?? 0.6) : r.float() * TAU;\n const speed = style.speedMin + r.float() * (style.speedMax - style.speedMin);\n const p: Particle = {\n x: at.x,\n y: at.y,\n vx: Math.cos(angle) * speed,\n vy: Math.sin(angle) * speed,\n life: 0,\n maxLife: style.lifeMin + r.float() * (style.lifeMax - style.lifeMin),\n size: style.sizeMin + r.float() * (style.sizeMax - style.sizeMin),\n color: style.colors[r.int(style.colors.length)],\n };\n if (this.pool.length >= this.maxParticles) this.pool.shift();\n this.pool.push(p);\n }\n // Stash style scalars on the instance for update (single-style emitters are\n // the common case; per-particle style costs memory for no visible gain).\n this.gravity = style.gravity ?? 0;\n this.drag = style.drag ?? 0;\n this.shrink = style.shrink ?? true;\n }\n\n private gravity = 0;\n private drag = 0;\n private shrink = true;\n\n protected override onProcess(dt: number): void {\n const drag = Math.max(0, 1 - this.drag * dt);\n let write = 0;\n for (const p of this.pool) {\n p.life += dt;\n if (p.life >= p.maxLife) continue;\n p.vy += this.gravity * dt;\n p.vx *= drag;\n p.vy *= drag;\n p.x += p.vx * dt;\n p.y += p.vy * dt;\n this.pool[write++] = p;\n }\n this.pool.length = write;\n }\n\n protected override draw(out: DrawCommand[], world: Transform): void {\n for (const p of this.pool) {\n const t = 1 - p.life / p.maxLife;\n out.push({\n kind: 'circle',\n cx: p.x,\n cy: p.y,\n radius: this.shrink ? p.size * t : p.size,\n fill: p.color,\n opacity: Math.min(1, t * 2),\n transform: world,\n z: this.z,\n });\n }\n }\n\n get liveCount(): number {\n return this.pool.length;\n }\n}\n\n/** Ready-made styles for the common feel moments. */\nexport const PARTICLE_PRESETS = {\n dust: (colors = ['#c8c2b6', '#a09a8c']): ParticleStyle => ({ colors, sizeMin: 2, sizeMax: 4, speedMin: 30, speedMax: 90, lifeMin: 0.2, lifeMax: 0.45, gravity: 300, drag: 3, shrink: true }),\n burst: (colors = ['#ffd75e', '#ff9d47', '#fff2c9']): ParticleStyle => ({ colors, sizeMin: 2, sizeMax: 5, speedMin: 120, speedMax: 320, lifeMin: 0.25, lifeMax: 0.6, drag: 4, shrink: true }),\n hit: (colors = ['#ff5e5e', '#ffd0d0']): ParticleStyle => ({ colors, sizeMin: 2, sizeMax: 4, speedMin: 160, speedMax: 380, lifeMin: 0.15, lifeMax: 0.35, drag: 6, shrink: true }),\n sparkle: (colors = ['#9ef7ff', '#e8fdff', '#4ed8e8']): ParticleStyle => ({ colors, sizeMin: 1.5, sizeMax: 3.5, speedMin: 20, speedMax: 70, lifeMin: 0.4, lifeMax: 0.9, gravity: -40, drag: 2, shrink: true }),\n} as const;\n\n/**\n * Screen shake as a cosmetic camera offset with its own Rng and exponential\n * decay. Attach to whatever node the camera follows and read `offset` into the\n * camera's position AFTER canonical follow logic \u2014 or simpler, add the shaker\n * as the camera's parent so the offset composes for free.\n */\nexport class Shaker extends Node {\n override readonly type: string = 'Shaker';\n private rng: Rng;\n private trauma = 0;\n /** Max offset in px at full trauma. */\n amplitude: number;\n /** Trauma decay per second. */\n decay: number;\n\n constructor(config: NodeConfig & { seed?: number; amplitude?: number; decay?: number } = {}) {\n super(config);\n this.cosmetic = true;\n this.rng = new Rng(config.seed ?? 99);\n this.amplitude = config.amplitude ?? 14;\n this.decay = config.decay ?? 2.6;\n }\n\n /** Add shake (0..1). Stacks, clamped to 1. Quadratic falloff feels right. */\n addTrauma(amount: number): void {\n this.trauma = Math.min(1, this.trauma + amount);\n }\n\n protected override onProcess(dt: number): void {\n this.trauma = Math.max(0, this.trauma - this.decay * dt);\n const s = this.trauma * this.trauma * this.amplitude;\n this.pos.x = (this.rng.float() * 2 - 1) * s;\n this.pos.y = (this.rng.float() * 2 - 1) * s;\n }\n}\n", "// Node type registry \u2192 lets a serialized tree (save file / prefab / snapshot)\n// be rebuilt into live nodes. Built-in types register here; games can register\n// custom node types the same way.\n\nimport { Node, type SerializedNode } from './node';\nimport { Sprite, Text, Camera2D, Timer } from './nodes';\nimport { AnimationPlayer } from './tween';\n\nexport type NodeFactory = () => Node;\n\nconst registry = new Map<string, NodeFactory>();\n\nexport function registerNode(type: string, factory: NodeFactory): void {\n registry.set(type, factory);\n}\n\n// Built-ins. Sprite/Text/Timer need required config, so provide safe defaults\n// that applyProps() immediately overwrites during deserialization.\nregisterNode('Node', () => new Node());\nregisterNode('Sprite', () => new Sprite({ shape: { kind: 'rect', w: 1, h: 1 } }));\nregisterNode('Text', () => new Text({ text: '' }));\nregisterNode('Camera2D', () => new Camera2D());\nregisterNode('Timer', () => new Timer({ duration: 1 }));\nregisterNode('AnimationPlayer', () => new AnimationPlayer());\n\n/** Rebuild a live node tree from serialized data. */\nexport function deserializeNode(data: SerializedNode): Node {\n const factory = registry.get(data.type);\n if (!factory) throw new Error(`hayao: unknown node type \"${data.type}\" (register it first)`);\n const node = factory();\n node.name = data.name;\n node.pos = { ...data.pos };\n node.rotation = data.rotation;\n node.scale = { ...data.scale };\n node.z = data.z;\n node.visible = data.visible;\n node.applyProps(data.props);\n for (const child of data.children) node.addChild(deserializeNode(child));\n return node;\n}\n", "// Input as ACTIONS, not keys. Game logic asks \"is 'jump' down?\", never \"is 'KeyZ'\n// down?\". Input is sampled once per fixed step, so a run is a pure function of its\n// input log \u2014 which is what makes replay and scripted playthroughs exact.\n\n/** action name \u2192 physical key codes (KeyboardEvent.code strings). */\nexport type InputMap = Record<string, string[]>;\n\nexport class InputState {\n private down = new Set<string>();\n private prev = new Set<string>();\n /** Analog axes (e.g. from gamepad or pointer), sampled per step. */\n readonly axes = new Map<string, number>();\n\n /** Engine: set which actions are down this step (from live input or replay). */\n beginFrame(actionsDown: Iterable<string>): void {\n this.prev = new Set(this.down);\n this.down = new Set(actionsDown);\n }\n\n isDown(action: string): boolean {\n return this.down.has(action);\n }\n justPressed(action: string): boolean {\n return this.down.has(action) && !this.prev.has(action);\n }\n justReleased(action: string): boolean {\n return !this.down.has(action) && this.prev.has(action);\n }\n axis(name: string): number {\n return this.axes.get(name) ?? 0;\n }\n\n /** The current down-set as a stable sorted array (for recording). */\n snapshot(): string[] {\n return [...this.down].sort();\n }\n\n getState() {\n return { down: [...this.down].sort(), prev: [...this.prev].sort() };\n }\n setState(s: { down: string[]; prev: string[] }): void {\n this.down = new Set(s.down);\n this.prev = new Set(s.prev);\n }\n}\n\n/** Map a set of raw key codes to the set of actions they trigger. */\nexport function keysToActions(map: InputMap, keysDown: Set<string>): string[] {\n const actions: string[] = [];\n for (const action in map) {\n if (map[action].some((k) => keysDown.has(k))) actions.push(action);\n }\n return actions.sort();\n}\n\n/** Records the per-frame action-down sets \u2192 a compact, replayable input log. */\nexport class InputRecorder {\n private frames: string[][] = [];\n\n record(actionsDown: string[]): void {\n this.frames.push(actionsDown.slice().sort());\n }\n\n get length(): number {\n return this.frames.length;\n }\n\n toLog(): InputLog {\n return { frames: this.frames.map((f) => f.slice()) };\n }\n}\n\nexport interface InputLog {\n frames: string[][];\n}\n\n/** Replays a recorded log: returns the action set for frame index i. */\nexport function frameActions(log: InputLog, i: number): string[] {\n return log.frames[i] ?? [];\n}\n\n/** A default set of common bindings games can start from. */\nexport const DEFAULT_INPUT_MAP: InputMap = {\n up: ['ArrowUp', 'KeyW'],\n down: ['ArrowDown', 'KeyS'],\n left: ['ArrowLeft', 'KeyA'],\n right: ['ArrowRight', 'KeyD'],\n confirm: ['Enter', 'Space'],\n cancel: ['Escape', 'Backspace'],\n action: ['KeyZ', 'KeyJ'],\n action2: ['KeyX', 'KeyK'],\n undo: ['KeyU'],\n restart: ['KeyR'],\n};\n", "// Browser input source: tracks physical keys and maps them to actions each step.\n// Kept separate from InputState so the pure sim never imports DOM.\n\nimport { keysToActions, type InputMap } from './actions';\n\nexport class KeyboardSource {\n private keysDown = new Set<string>();\n /** Virtual action taps (from DOM buttons etc.) pending consumption by a step. */\n private pressed = new Set<string>();\n private map: InputMap;\n private target: Document | HTMLElement;\n private onDown: (e: KeyboardEvent) => void;\n private onUp: (e: KeyboardEvent) => void;\n private onBlur: () => void;\n\n constructor(map: InputMap, target: Document | HTMLElement = document) {\n this.map = map;\n this.target = target;\n this.onDown = (e) => {\n this.keysDown.add(e.code);\n // Prevent scroll on arrows/space during play.\n if (e.code.startsWith('Arrow') || e.code === 'Space') e.preventDefault();\n };\n this.onUp = (e) => this.keysDown.delete(e.code);\n this.onBlur = () => this.keysDown.clear();\n target.addEventListener('keydown', this.onDown as EventListener);\n target.addEventListener('keyup', this.onUp as EventListener);\n globalThis.addEventListener?.('blur', this.onBlur);\n }\n\n /** The actions currently held down, as a stable sorted array. */\n currentActions(): string[] {\n const acts = keysToActions(this.map, this.keysDown);\n if (this.pressed.size === 0) return acts;\n const merged = new Set(acts);\n for (const a of this.pressed) merged.add(a);\n return [...merged].sort();\n }\n\n /**\n * Virtually tap an action (DOM button, touch control). The tap is held until\n * at least one fixed step has sampled it \u2014 the driver calls clearPressed()\n * after a successful advance \u2014 so UI clicks enter the SAME deterministic\n * input log as keys, and record/replay covers them.\n */\n press(action: string): void {\n this.pressed.add(action);\n }\n\n /** Consume pending virtual taps (driver-called after \u22651 step ran). */\n clearPressed(): void {\n this.pressed.clear();\n }\n\n setMap(map: InputMap): void {\n this.map = map;\n }\n\n dispose(): void {\n this.target.removeEventListener('keydown', this.onDown as EventListener);\n this.target.removeEventListener('keyup', this.onUp as EventListener);\n globalThis.removeEventListener?.('blur', this.onBlur);\n }\n}\n", "// Tilemaps: grid collision geometry authored as ASCII. Plain data + pure\n// functions (house style) so maps serialize, hash, and diff cleanly.\n\nexport const TILE = {\n EMPTY: 0,\n SOLID: 1,\n /** Passable from below/sides; solid only when landing on its top edge. */\n ONEWAY: 2,\n HAZARD: 3,\n} as const;\nexport type TileId = (typeof TILE)[keyof typeof TILE];\n\nexport interface TilemapData {\n /** Size in tiles. */\n cols: number;\n rows: number;\n /** Tile edge in design-space px. */\n tileSize: number;\n /** Row-major tile ids, length cols*rows. */\n tiles: number[];\n}\n\n/** Default ASCII vocabulary: `#` solid, `-` one-way, `^` hazard, else empty. */\nexport const DEFAULT_TILE_CHARS: Record<string, TileId> = {\n '#': TILE.SOLID,\n '-': TILE.ONEWAY,\n '^': TILE.HAZARD,\n};\n\n/**\n * Build a tilemap from ASCII rows. Unknown characters are EMPTY, so level\n * strings can carry entity markers (`@` spawn, `*` shard\u2026) for game code to\n * read separately via `asciiEntities`.\n */\nexport function tilemapFromAscii(rowsAscii: string[], tileSize = 32, chars: Record<string, TileId> = DEFAULT_TILE_CHARS): TilemapData {\n const rows = rowsAscii.length;\n const cols = Math.max(...rowsAscii.map((r) => r.length));\n const tiles = new Array<number>(cols * rows).fill(TILE.EMPTY);\n rowsAscii.forEach((row, ty) => {\n for (let tx = 0; tx < row.length; tx++) tiles[ty * cols + tx] = chars[row[tx]] ?? TILE.EMPTY;\n });\n return { cols, rows, tileSize, tiles };\n}\n\n/** Extract entity markers (any char not in the tile vocabulary, not space/dot). */\nexport function asciiEntities(rowsAscii: string[], tileSize = 32, chars: Record<string, TileId> = DEFAULT_TILE_CHARS): { char: string; tx: number; ty: number; x: number; y: number }[] {\n const out: { char: string; tx: number; ty: number; x: number; y: number }[] = [];\n rowsAscii.forEach((row, ty) => {\n for (let tx = 0; tx < row.length; tx++) {\n const c = row[tx];\n if (c === ' ' || c === '.' || chars[c] !== undefined) continue;\n out.push({ char: c, tx, ty, x: (tx + 0.5) * tileSize, y: (ty + 0.5) * tileSize });\n }\n });\n return out;\n}\n\n/** Tile id at tile coords; out-of-bounds reads as SOLID (levels are sealed). */\nexport function tileAt(map: TilemapData, tx: number, ty: number): number {\n if (tx < 0 || ty < 0 || tx >= map.cols || ty >= map.rows) return TILE.SOLID;\n return map.tiles[ty * map.cols + tx];\n}\n\nexport function tileAtPoint(map: TilemapData, x: number, y: number): number {\n return tileAt(map, Math.floor(x / map.tileSize), Math.floor(y / map.tileSize));\n}\n\nexport const mapWidth = (map: TilemapData): number => map.cols * map.tileSize;\nexport const mapHeight = (map: TilemapData): number => map.rows * map.tileSize;\n", "// Kinematic AABB movement against a tilemap plus extra solid rects (moving\n// platforms). Axis-separated, analytically clamped to obstacle edges \u2014 no\n// tunneling, exact and deterministic. Pure functions over plain data.\n\nimport type { Rect } from '../core/math';\nimport { TILE, tileAt, type TilemapData } from './tilemap';\n\nconst EPS = 1e-6;\n\n/** An extra solid the body collides with (moving platform, door, crate\u2026). */\nexport interface SolidRect extends Rect {\n /** Solid only when landing on its top (jump-through platform). */\n oneway?: boolean;\n}\n\nexport interface MoveResult {\n x: number;\n y: number;\n hitX: boolean;\n hitY: boolean;\n onFloor: boolean;\n onCeiling: boolean;\n onWallLeft: boolean;\n onWallRight: boolean;\n /** Final rect overlaps a HAZARD tile (with a small forgiveness inset). */\n hazard: boolean;\n /** Index into `solids` of the rect the body stands on, or -1. */\n floorSolid: number;\n}\n\nconst spanTiles = (lo: number, hi: number, ts: number): [number, number] => [Math.floor(lo / ts), Math.floor((hi - EPS) / ts)];\n\nexport interface MoveOpts {\n solids?: SolidRect[];\n /** Pass true while the player holds \"down\" to drop through one-way platforms. */\n dropThrough?: boolean;\n}\n\n/** Would a rect at (x, y) overlap any solid geometry? (Used for corner-correction probes.) */\nexport function rectBlocked(map: TilemapData, x: number, y: number, w: number, h: number, solids: SolidRect[] = []): boolean {\n const ts = map.tileSize;\n const [tx0, tx1] = spanTiles(x, x + w, ts);\n const [ty0, ty1] = spanTiles(y, y + h, ts);\n for (let ty = ty0; ty <= ty1; ty++)\n for (let tx = tx0; tx <= tx1; tx++) if (tileAt(map, tx, ty) === TILE.SOLID) return true;\n for (const s of solids) {\n if (s.oneway) continue;\n if (x < s.x + s.w - EPS && x + w > s.x + EPS && y < s.y + s.h - EPS && y + h > s.y + EPS) return true;\n }\n return false;\n}\n\n/**\n * Move a rect by (dx, dy) with axis-separated collision: X first, then Y.\n * One-way surfaces block only downward motion that starts at-or-above their top.\n */\nexport function moveRect(map: TilemapData, rect: Rect, dx: number, dy: number, opts: MoveOpts = {}): MoveResult {\n const ts = map.tileSize;\n const solids = opts.solids ?? [];\n let { x, y } = rect;\n const { w, h } = rect;\n let hitX = false;\n let hitY = false;\n let onWallLeft = false;\n let onWallRight = false;\n\n // \u2500\u2500 X axis \u2500\u2500\n if (dx !== 0) {\n const [ty0, ty1] = spanTiles(y, y + h, ts);\n if (dx > 0) {\n let limit = x + dx; // furthest allowed left-edge position\n const [c0, c1] = [Math.floor((x + w) / ts), Math.floor((x + w + dx - EPS) / ts)];\n for (let tx = c0; tx <= c1; tx++)\n for (let ty = ty0; ty <= ty1; ty++)\n if (tileAt(map, tx, ty) === TILE.SOLID) limit = Math.min(limit, tx * ts - w);\n for (const s of solids)\n if (!s.oneway && s.y < y + h - EPS && s.y + s.h > y + EPS && s.x >= x + w - EPS) limit = Math.min(limit, s.x - w);\n if (limit < x + dx - EPS) {\n hitX = true;\n onWallRight = true;\n }\n x = Math.min(x + dx, limit);\n } else {\n let limit = x + dx;\n const [c0, c1] = [Math.floor((x - EPS) / ts), Math.floor((x + dx) / ts)];\n for (let tx = c0; tx >= c1; tx--)\n for (let ty = ty0; ty <= ty1; ty++)\n if (tileAt(map, tx, ty) === TILE.SOLID) limit = Math.max(limit, (tx + 1) * ts);\n for (const s of solids)\n if (!s.oneway && s.y < y + h - EPS && s.y + s.h > y + EPS && s.x + s.w <= x + EPS) limit = Math.max(limit, s.x + s.w);\n if (limit > x + dx + EPS) {\n hitX = true;\n onWallLeft = true;\n }\n x = Math.max(x + dx, limit);\n }\n }\n\n // \u2500\u2500 Y axis \u2500\u2500\n const prevBottom = y + h;\n let onFloor = false;\n let onCeiling = false;\n let floorSolid = -1;\n if (dy !== 0) {\n const [tx0, tx1] = spanTiles(x, x + w, ts);\n if (dy > 0) {\n let limit = y + dy; // furthest allowed top position\n const [r0, r1] = [Math.floor(prevBottom / ts), Math.floor((prevBottom + dy - EPS) / ts)];\n for (let ty = r0; ty <= r1; ty++)\n for (let tx = tx0; tx <= tx1; tx++) {\n const t = tileAt(map, tx, ty);\n const blocks = t === TILE.SOLID || (t === TILE.ONEWAY && !opts.dropThrough && prevBottom <= ty * ts + EPS);\n if (blocks) limit = Math.min(limit, ty * ts - h);\n }\n for (let i = 0; i < solids.length; i++) {\n const s = solids[i];\n const inX = s.x < x + w - EPS && s.x + s.w > x + EPS;\n if (!inX || s.y < prevBottom - EPS) continue;\n if (s.oneway && (opts.dropThrough || prevBottom > s.y + EPS)) continue;\n if (s.y - h < limit) {\n limit = s.y - h;\n floorSolid = i;\n }\n }\n if (limit < y + dy - EPS) {\n hitY = true;\n onFloor = true;\n } else floorSolid = -1;\n y = Math.min(y + dy, limit);\n } else {\n let limit = y + dy;\n const [r0, r1] = [Math.floor((y - EPS) / ts), Math.floor((y + dy) / ts)];\n for (let ty = r0; ty >= r1; ty--)\n for (let tx = tx0; tx <= tx1; tx++)\n if (tileAt(map, tx, ty) === TILE.SOLID) limit = Math.max(limit, (ty + 1) * ts);\n for (const s of solids)\n if (!s.oneway && s.x < x + w - EPS && s.x + s.w > x + EPS && s.y + s.h <= y + EPS) limit = Math.max(limit, s.y + s.h);\n if (limit > y + dy + EPS) {\n hitY = true;\n onCeiling = true;\n }\n y = Math.max(y + dy, limit);\n }\n }\n\n // \u2500\u2500 Ground probe (also true when dy was 0 or clamped exactly) \u2500\u2500\n if (!onFloor) {\n const probe = groundAt(map, x, y, w, h, solids, opts.dropThrough ?? false);\n onFloor = probe.grounded;\n floorSolid = probe.solid;\n }\n\n // \u2500\u2500 Hazard overlap (inset for forgiveness) \u2500\u2500\n const inset = 3;\n let hazard = false;\n {\n const [hx0, hx1] = spanTiles(x + inset, x + w - inset, ts);\n const [hy0, hy1] = spanTiles(y + inset, y + h - inset, ts);\n for (let ty = hy0; ty <= hy1 && !hazard; ty++)\n for (let tx = hx0; tx <= hx1 && !hazard; tx++) if (tileAt(map, tx, ty) === TILE.HAZARD) hazard = true;\n }\n\n return { x, y, hitX, hitY, onFloor, onCeiling, onWallLeft, onWallRight, hazard, floorSolid };\n}\n\n/** Is there support directly under the rect (within 1px)? */\nexport function groundAt(map: TilemapData, x: number, y: number, w: number, h: number, solids: SolidRect[] = [], dropThrough = false): { grounded: boolean; solid: number } {\n const ts = map.tileSize;\n const bottom = y + h;\n const [tx0, tx1] = spanTiles(x, x + w, ts);\n const ty = Math.floor((bottom + 1) / ts);\n for (let tx = tx0; tx <= tx1; tx++) {\n const t = tileAt(map, tx, ty);\n if (t === TILE.SOLID) return { grounded: true, solid: -1 };\n if (t === TILE.ONEWAY && !dropThrough && Math.abs(bottom - ty * ts) <= 1 + EPS) return { grounded: true, solid: -1 };\n }\n for (let i = 0; i < solids.length; i++) {\n const s = solids[i];\n const inX = s.x < x + w - EPS && s.x + s.w > x + EPS;\n if (inX && bottom <= s.y + 1 + EPS && bottom >= s.y - 1 - EPS) return { grounded: true, solid: i };\n }\n return { grounded: false, solid: -1 };\n}\n", "// PlatformerController: a state-of-the-art 2D kinematic character controller.\n// Pure and deterministic \u2014 plain-data state, stepped at the fixed timestep, no\n// engine imports beyond physics/math \u2014 so every game-feel feature below is\n// unit-testable in Node by pumping frames.\n//\n// Implements the modern platforming canon:\n// coyote time \u00B7 jump buffering \u00B7 variable jump height \u00B7 halved-gravity apex\n// jump corner correction \u00B7 dash (8-way) \u00B7 dash corner correction\n// wall slide + wall jump \u00B7 moving-platform carry + lift momentum storage\n// one-way platforms + drop-through\n\nimport { moveRect, rectBlocked, type SolidRect } from './aabb';\nimport type { TilemapData } from './tilemap';\n\nexport interface PlatformerConfig {\n width: number;\n height: number;\n /** Ground run speed (px/s) and accelerations (px/s\u00B2). */\n runSpeed: number;\n groundAccel: number;\n groundFriction: number;\n airAccel: number;\n /**\n * Horizontal decel with no input while airborne (px/s\u00B2). Keep LOW: inherited\n * momentum (lift jumps, wall kicks) must survive flight to feel right.\n */\n airFriction: number;\n /** Gravity (px/s\u00B2), terminal fall speed, and the apex modifier. */\n gravity: number;\n maxFall: number;\n /** |vy| below this counts as the jump apex\u2026 */\n apexThreshold: number;\n /** \u2026where gravity is multiplied by this while jump is held (the floaty peak). */\n apexGravityMult: number;\n /** Initial jump velocity (px/s, upward) and early-release cut multiplier. */\n jumpVelocity: number;\n jumpCutMult: number;\n /** Grace timers (seconds). */\n coyoteTime: number;\n jumpBuffer: number;\n /** Max px the body is nudged sideways to slip past a ceiling corner when jumping. */\n jumpCornerNudge: number;\n /** Max px the body is nudged vertically to slip past a corner while dashing. */\n dashCornerNudge: number;\n /** Mid-air jumps (0 = none, 1 = double jump\u2026), refilled on landing/wall. */\n airJumps: number;\n /** Air-jump velocity as a fraction of jumpVelocity. */\n airJumpMult: number;\n /** Dash: speed (px/s), duration (s), cooldown (s), charges refilled on landing. */\n dashSpeed: number;\n dashTime: number;\n dashCooldown: number;\n dashCharges: number;\n /** Wall interaction. */\n wallSlideMaxFall: number;\n wallJumpVelX: number;\n wallJumpVelY: number;\n /** Seconds after a wall jump during which input can't cancel the outward velocity. */\n wallJumpLock: number;\n}\n\n/** Tuned for 32px tiles at 60Hz in the 1280\u00D7720 design space. */\nexport const DEFAULT_PLATFORMER: PlatformerConfig = {\n width: 22,\n height: 28,\n runSpeed: 340,\n groundAccel: 3800,\n groundFriction: 4200,\n airAccel: 2600,\n airFriction: 260,\n gravity: 2300,\n maxFall: 660,\n apexThreshold: 60,\n apexGravityMult: 0.5,\n jumpVelocity: 650,\n jumpCutMult: 0.4,\n coyoteTime: 0.1,\n jumpBuffer: 0.12,\n jumpCornerNudge: 10,\n dashCornerNudge: 12,\n airJumps: 0,\n airJumpMult: 0.92,\n dashSpeed: 640,\n dashTime: 0.14,\n dashCooldown: 0.25,\n dashCharges: 1,\n wallSlideMaxFall: 150,\n wallJumpVelX: 360,\n wallJumpVelY: 600,\n wallJumpLock: 0.13,\n};\n\n/** Per-step intent, sampled from actions by the game (never raw keys). */\nexport interface PadInput {\n moveX: number; // -1 | 0 | 1\n moveY: number; // -1 (up) | 0 | 1 (down)\n jumpHeld: boolean;\n jumpPressed: boolean;\n dashPressed: boolean;\n}\n\nexport const PAD_NEUTRAL: PadInput = { moveX: 0, moveY: 0, jumpHeld: false, jumpPressed: false, dashPressed: false };\n\n/** A moving platform: its current rect, plus its velocity this step (px/s). */\nexport interface Platform extends SolidRect {\n vx: number;\n vy: number;\n}\n\n/** Plain serializable controller state \u2014 put it in `world.state` so it hashes. */\nexport interface PlatformerState {\n x: number; // top-left of the collision box\n y: number;\n vx: number;\n vy: number;\n facing: number; // -1 | 1\n onGround: boolean;\n onWall: number; // -1 touching left wall, 1 right, 0 none\n coyote: number;\n buffer: number;\n jumping: boolean; // rising from a jump (variable-height window)\n wallLock: number;\n airJumpsLeft: number;\n dashing: number; // time left in current dash\n dashCd: number;\n dashesLeft: number;\n dashVx: number;\n dashVy: number;\n /** Velocity inherited from the platform we stand on (lift momentum storage). */\n carryVx: number;\n carryVy: number;\n dead: boolean;\n}\n\nexport function createPlatformerState(x: number, y: number): PlatformerState {\n return { x, y, vx: 0, vy: 0, facing: 1, onGround: false, onWall: 0, coyote: 0, buffer: 0, jumping: false, wallLock: 0, airJumpsLeft: 0, dashing: 0, dashCd: 0, dashesLeft: 1, dashVx: 0, dashVy: 0, carryVx: 0, carryVy: 0, dead: false };\n}\n\n/** Feel events emitted by a step \u2014 hooks for SFX / particles / screen shake. */\nexport interface PlatformerEvents {\n jumped: boolean;\n wallJumped: boolean;\n airJumped: boolean;\n dashed: boolean;\n landed: boolean;\n died: boolean;\n}\n\nconst approach = (v: number, target: number, delta: number): number => (v < target ? Math.min(v + delta, target) : Math.max(v - delta, target));\n\n/**\n * Advance the controller one fixed step. Mutates `s`; returns feel events.\n * `platforms` should already be at their post-move positions for this step,\n * with `vx/vy` set to their velocity, so the body is carried exactly.\n */\nexport function stepPlatformer(s: PlatformerState, input: PadInput, dt: number, map: TilemapData, cfg: PlatformerConfig = DEFAULT_PLATFORMER, platforms: Platform[] = []): PlatformerEvents {\n const ev: PlatformerEvents = { jumped: false, wallJumped: false, airJumped: false, dashed: false, landed: false, died: false };\n if (s.dead) return ev;\n const wasGrounded = s.onGround;\n\n // \u2500\u2500 Timers \u2500\u2500\n s.coyote = Math.max(0, s.coyote - dt);\n s.buffer = Math.max(0, s.buffer - dt);\n s.wallLock = Math.max(0, s.wallLock - dt);\n s.dashCd = Math.max(0, s.dashCd - dt);\n if (input.jumpPressed) s.buffer = cfg.jumpBuffer;\n\n // \u2500\u2500 Dash start \u2500\u2500\n if (input.dashPressed && s.dashing <= 0 && s.dashCd <= 0 && s.dashesLeft > 0) {\n let dx = input.moveX;\n let dy = input.moveY;\n if (dx === 0 && dy === 0) dx = s.facing;\n const inv = 1 / Math.hypot(dx, dy);\n s.dashing = cfg.dashTime;\n s.dashCd = cfg.dashCooldown;\n s.dashesLeft--;\n s.dashVx = dx * inv * cfg.dashSpeed;\n s.dashVy = dy * inv * cfg.dashSpeed;\n s.jumping = false;\n ev.dashed = true;\n }\n\n // \u2500\u2500 Horizontal intent \u2500\u2500\n if (s.dashing > 0) {\n s.vx = s.dashVx;\n s.vy = s.dashVy;\n s.dashing -= dt;\n } else if (s.wallLock <= 0) {\n const target = input.moveX * cfg.runSpeed;\n const accel = s.onGround ? (input.moveX !== 0 ? cfg.groundAccel : cfg.groundFriction) : input.moveX !== 0 ? cfg.airAccel : cfg.airFriction;\n s.vx = approach(s.vx, target, accel * dt);\n if (input.moveX !== 0) s.facing = input.moveX > 0 ? 1 : -1;\n }\n\n // \u2500\u2500 Gravity (skipped while dashing) \u2500\u2500\n if (s.dashing <= 0 && !s.onGround) {\n let g = cfg.gravity;\n if (Math.abs(s.vy) < cfg.apexThreshold && input.jumpHeld && s.jumping) g *= cfg.apexGravityMult; // halved-gravity peak\n s.vy = Math.min(s.vy + g * dt, cfg.maxFall);\n if (s.onWall !== 0 && s.vy > cfg.wallSlideMaxFall && input.moveX === s.onWall) s.vy = cfg.wallSlideMaxFall; // wall slide\n }\n\n // \u2500\u2500 Variable jump height: release cuts upward velocity \u2500\u2500\n if (s.jumping && !input.jumpHeld && s.vy < 0) {\n s.vy *= cfg.jumpCutMult;\n s.jumping = false;\n }\n\n // \u2500\u2500 Jump (buffered + coyote) / wall jump \u2500\u2500\n if (s.buffer > 0 && s.dashing <= 0) {\n if (s.onGround || s.coyote > 0) {\n s.vy = -cfg.jumpVelocity;\n // Lift momentum storage: keep the platform's motion.\n s.vx += s.carryVx;\n if (s.carryVy < 0) s.vy += s.carryVy;\n s.jumping = true;\n s.buffer = 0;\n s.coyote = 0;\n s.onGround = false;\n ev.jumped = true;\n } else if (s.onWall !== 0 && cfg.wallJumpVelY > 0) {\n s.vx = -s.onWall * cfg.wallJumpVelX;\n s.vy = -cfg.wallJumpVelY;\n s.facing = -s.onWall;\n s.jumping = true;\n s.buffer = 0;\n s.wallLock = cfg.wallJumpLock;\n ev.wallJumped = true;\n ev.jumped = true;\n } else if (s.airJumpsLeft > 0) {\n s.vy = -cfg.jumpVelocity * cfg.airJumpMult;\n s.airJumpsLeft--;\n s.jumping = true;\n s.buffer = 0;\n ev.jumped = true;\n ev.airJumped = true;\n }\n }\n\n // \u2500\u2500 Move-and-collide, with platform carry \u2500\u2500\n // Holding down passes through one-ways \u2014 INCLUDING while already falling,\n // or the body re-lands on the platform lip one frame after leaving it.\n const dropThrough = input.moveY > 0 && s.buffer <= 0;\n let dx = s.vx * dt + s.carryVx * dt * (s.onGround ? 1 : 0);\n let dy = s.vy * dt + Math.max(0, s.carryVy) * dt * (s.onGround ? 1 : 0);\n let res = moveRect(map, { x: s.x, y: s.y, w: cfg.width, h: cfg.height }, dx, dy, { solids: platforms, dropThrough });\n\n // \u2500\u2500 Jump corner correction: bonked a ceiling edge while rising \u2192 nudge sideways \u2500\u2500\n if (res.onCeiling && s.vy < 0 && s.dashing <= 0) {\n const slip = cornerSlipX(map, platforms, res.x, res.y, cfg.width, cfg.height, dy, cfg.jumpCornerNudge);\n if (slip !== null) {\n res = moveRect(map, { x: slip, y: res.y, w: cfg.width, h: cfg.height }, 0, dy, { solids: platforms, dropThrough });\n res.x = slip;\n }\n }\n\n // \u2500\u2500 Dash corner correction: clipped a wall edge while dashing \u2192 nudge vertically \u2500\u2500\n if (res.hitX && s.dashing > 0 && Math.abs(s.dashVy) < 1) {\n const slip = cornerSlipY(map, platforms, res.x, res.y, cfg.width, cfg.height, dx, cfg.dashCornerNudge);\n if (slip !== null) {\n res = moveRect(map, { x: res.x, y: slip, w: cfg.width, h: cfg.height }, dx, 0, { solids: platforms, dropThrough });\n res.y = slip;\n }\n }\n\n s.x = res.x;\n s.y = res.y;\n if (res.hitY && s.vy > 0) s.vy = 0;\n if (res.onCeiling) {\n s.vy = Math.max(s.vy, 0);\n s.jumping = false;\n }\n if (res.hitX && s.dashing <= 0) s.vx = 0;\n s.onWall = res.onWallLeft ? -1 : res.onWallRight ? 1 : wallTouch(map, platforms, s.x, s.y, cfg.width, cfg.height);\n s.onGround = res.onFloor;\n\n // \u2500\u2500 Ground bookkeeping: coyote, dash refill, landing, lift momentum \u2500\u2500\n if (s.onGround) {\n s.coyote = cfg.coyoteTime;\n s.dashesLeft = cfg.dashCharges;\n s.airJumpsLeft = cfg.airJumps;\n if (!wasGrounded) ev.landed = true;\n if (res.floorSolid >= 0) {\n const p = platforms[res.floorSolid];\n s.carryVx = p.vx;\n s.carryVy = p.vy;\n // Ride the platform exactly: snap feet to its top.\n s.y = p.y - cfg.height;\n } else {\n s.carryVx = 0;\n s.carryVy = 0;\n }\n if (s.vy > 0) s.vy = 0;\n s.jumping = false;\n } else if (wasGrounded && s.carryVy !== 0) {\n // Walked off a lift: keep stored momentum until landing or jumping.\n }\n\n if (res.hazard) {\n s.dead = true;\n ev.died = true;\n }\n return ev;\n}\n\n// \u2500\u2500 Movement envelope: derive level geometry from the config, never guess \u2500\u2500\n// Conservative closed-form bounds (they ignore the apex-gravity bonus, so the\n// real controller always reaches at least this far). Author levels against\n// these \u2014 \"it looks jumpable\" is how unwinnable geometry ships.\n\n/** Max rise of a full jump (px). */\nexport function jumpHeight(cfg: PlatformerConfig = DEFAULT_PLATFORMER): number {\n return (cfg.jumpVelocity * cfg.jumpVelocity) / (2 * cfg.gravity);\n}\n\n/** Full-jump airtime returning to takeoff height (s). */\nexport function jumpAirtime(cfg: PlatformerConfig = DEFAULT_PLATFORMER): number {\n return (2 * cfg.jumpVelocity) / cfg.gravity;\n}\n\n/** Max horizontal gap clearable by a running jump (px, flat-to-flat). */\nexport function jumpDistance(cfg: PlatformerConfig = DEFAULT_PLATFORMER): number {\n return cfg.runSpeed * jumpAirtime(cfg);\n}\n\n/** Max gap clearable by jump + one apex dash (px, flat-to-flat, horizontal dash). */\nexport function dashJumpDistance(cfg: PlatformerConfig = DEFAULT_PLATFORMER): number {\n return jumpDistance(cfg) + (cfg.dashSpeed - cfg.runSpeed) * cfg.dashTime;\n}\n\n/** Try shifting x by up to \u00B1nudge so a rect moving by dy is unblocked. Prefers the smaller shift. */\nfunction cornerSlipX(map: TilemapData, solids: SolidRect[], x: number, y: number, w: number, h: number, dy: number, nudge: number): number | null {\n for (let n = 1; n <= nudge; n++) {\n for (const dir of [1, -1]) {\n const nx = x + dir * n;\n if (!rectBlocked(map, nx, y + dy, w, h, solids) && !rectBlocked(map, nx, y, w, h, solids)) return nx;\n }\n }\n return null;\n}\n\n/** Try shifting y by up to \u00B1nudge so a rect moving by dx is unblocked. */\nfunction cornerSlipY(map: TilemapData, solids: SolidRect[], x: number, y: number, w: number, h: number, dx: number, nudge: number): number | null {\n for (let n = 1; n <= nudge; n++) {\n for (const dir of [-1, 1]) {\n const ny = y + dir * n;\n if (!rectBlocked(map, x + dx, ny, w, h, solids) && !rectBlocked(map, x, ny, w, h, solids)) return ny;\n }\n }\n return null;\n}\n\n/** Which wall (if any) is the body pressed against? (1px probes) */\nfunction wallTouch(map: TilemapData, solids: SolidRect[], x: number, y: number, w: number, h: number): number {\n if (rectBlocked(map, x + 1, y, w, h, solids)) return 1;\n if (rectBlocked(map, x - 1, y, w, h, solids)) return -1;\n return 0;\n}\n", "// Uniform-grid spatial hash for broad-phase queries over many moving entities\n// (hordes, bullets, RTS units). Deterministic: iteration order is insertion\n// order within cells, and query results preserve first-insertion order.\n// Rebuild-per-step is the intended pattern \u2014 clear() + insert all \u2014 which is\n// O(n) and avoids stale incremental state entirely.\n\nimport type { Rect } from '../core/math';\n\nexport class SpatialHash<T> {\n private cells = new Map<number, T[]>();\n private bounds = new Map<T, Rect>();\n private readonly cellSize: number;\n\n constructor(cellSize = 64) {\n this.cellSize = cellSize;\n }\n\n clear(): void {\n this.cells.clear();\n this.bounds.clear();\n }\n\n get size(): number {\n return this.bounds.size;\n }\n\n private key(cx: number, cy: number): number {\n // Interleave-free packing; fine for worlds within \u00B12^15 cells.\n return (cx + 32768) * 65536 + (cy + 32768);\n }\n\n insert(item: T, rect: Rect): void {\n this.bounds.set(item, rect);\n const cs = this.cellSize;\n const x0 = Math.floor(rect.x / cs);\n const x1 = Math.floor((rect.x + rect.w) / cs);\n const y0 = Math.floor(rect.y / cs);\n const y1 = Math.floor((rect.y + rect.h) / cs);\n for (let cy = y0; cy <= y1; cy++)\n for (let cx = x0; cx <= x1; cx++) {\n const k = this.key(cx, cy);\n const cell = this.cells.get(k);\n if (cell) cell.push(item);\n else this.cells.set(k, [item]);\n }\n }\n\n /** All items whose rects overlap the query rect (deduplicated, deterministic order). */\n query(rect: Rect): T[] {\n const cs = this.cellSize;\n const x0 = Math.floor(rect.x / cs);\n const x1 = Math.floor((rect.x + rect.w) / cs);\n const y0 = Math.floor(rect.y / cs);\n const y1 = Math.floor((rect.y + rect.h) / cs);\n const seen = new Set<T>();\n const out: T[] = [];\n for (let cy = y0; cy <= y1; cy++)\n for (let cx = x0; cx <= x1; cx++) {\n const cell = this.cells.get(this.key(cx, cy));\n if (!cell) continue;\n for (const item of cell) {\n if (seen.has(item)) continue;\n seen.add(item);\n const b = this.bounds.get(item)!;\n if (b.x < rect.x + rect.w && b.x + b.w > rect.x && b.y < rect.y + rect.h && b.y + b.h > rect.y) out.push(item);\n }\n }\n return out;\n }\n\n /** All items within `radius` of a point (circle vs rect-center test on bounds). */\n queryCircle(x: number, y: number, radius: number): T[] {\n const near = this.query({ x: x - radius, y: y - radius, w: radius * 2, h: radius * 2 });\n return near.filter((item) => {\n const b = this.bounds.get(item)!;\n const cx = Math.max(b.x, Math.min(x, b.x + b.w));\n const cy = Math.max(b.y, Math.min(y, b.y + b.h));\n return (x - cx) * (x - cx) + (y - cy) * (y - cy) <= radius * radius;\n });\n }\n}\n", "// Grid raycasting (DDA) over a tilemap \u2014 the sight primitive behind stealth\n// vision cones, sentry line-of-sight, roguelike FOV, and 2D lighting.\n\nimport { TILE, tileAt, type TilemapData } from './tilemap';\n\nexport interface RayHit {\n /** True if a solid tile stopped the ray before reaching (x1, y1). */\n blocked: boolean;\n /** Where the ray stopped (the hit point, or the target if unblocked). */\n x: number;\n y: number;\n /** Distance travelled. */\n dist: number;\n}\n\n/**\n * March a ray from (x0,y0) toward (x1,y1) through the tile grid (DDA \u2014 exact,\n * no step-size tuning). SOLID tiles block; everything else passes.\n */\nexport function raycastTiles(map: TilemapData, x0: number, y0: number, x1: number, y1: number): RayHit {\n const ts = map.tileSize;\n const dx = x1 - x0;\n const dy = y1 - y0;\n const maxDist = Math.hypot(dx, dy);\n if (maxDist === 0) return { blocked: false, x: x1, y: y1, dist: 0 };\n const dirX = dx / maxDist;\n const dirY = dy / maxDist;\n\n let tx = Math.floor(x0 / ts);\n let ty = Math.floor(y0 / ts);\n const stepX = dirX > 0 ? 1 : -1;\n const stepY = dirY > 0 ? 1 : -1;\n const tDeltaX = dirX !== 0 ? Math.abs(ts / dirX) : Infinity;\n const tDeltaY = dirY !== 0 ? Math.abs(ts / dirY) : Infinity;\n let tMaxX = dirX !== 0 ? (dirX > 0 ? (tx + 1) * ts - x0 : x0 - tx * ts) / Math.abs(dirX) : Infinity;\n let tMaxY = dirY !== 0 ? (dirY > 0 ? (ty + 1) * ts - y0 : y0 - ty * ts) / Math.abs(dirY) : Infinity;\n\n let t = 0;\n // The starting tile never blocks (the caster stands in it).\n for (let guard = 0; guard < 512; guard++) {\n if (tMaxX < tMaxY) {\n t = tMaxX;\n tMaxX += tDeltaX;\n tx += stepX;\n } else {\n t = tMaxY;\n tMaxY += tDeltaY;\n ty += stepY;\n }\n if (t >= maxDist) return { blocked: false, x: x1, y: y1, dist: maxDist };\n if (tileAt(map, tx, ty) === TILE.SOLID) {\n return { blocked: true, x: x0 + dirX * t, y: y0 + dirY * t, dist: t };\n }\n }\n return { blocked: true, x: x0 + dirX * t, y: y0 + dirY * t, dist: t };\n}\n\n/** Can a see b with no solid tile between? */\nexport function lineOfSight(map: TilemapData, ax: number, ay: number, bx: number, by: number): boolean {\n return !raycastTiles(map, ax, ay, bx, by).blocked;\n}\n\n/**\n * Is the target inside a vision cone AND visible? (facing is a unit vector;\n * fov is the FULL cone angle in radians.)\n */\nexport function inVisionCone(map: TilemapData, ex: number, ey: number, faceX: number, faceY: number, fov: number, range: number, tx: number, ty: number): boolean {\n const dx = tx - ex;\n const dy = ty - ey;\n const d = Math.hypot(dx, dy);\n if (d > range || d === 0) return false;\n const dot = (dx * faceX + dy * faceY) / d;\n if (dot < Math.cos(fov / 2)) return false;\n return lineOfSight(map, ex, ey, tx, ty);\n}\n", "// The display list: a flat, backend-agnostic vocabulary of draw commands.\n// The scene tree *projects* to DrawCommand[]; a backend (SVG/Canvas/Headless)\n// consumes them. Pure data \u2014 no browser types \u2014 so the projection is testable.\n\nimport type { Transform } from '../core/math';\n\nexport interface Paint {\n fill?: string;\n stroke?: string;\n strokeWidth?: number;\n opacity?: number;\n /** Round line joins/caps for organic shapes. */\n round?: boolean;\n}\n\nexport type TextAlign = 'left' | 'center' | 'right';\n\ninterface Base extends Paint {\n /** World transform (design-space). */\n transform: Transform;\n /** Painter's-order key; ties broken by tree order. Default 0. */\n z: number;\n}\n\nexport interface RectCommand extends Base {\n kind: 'rect';\n x: number;\n y: number;\n w: number;\n h: number;\n /** Corner radius. */\n r?: number;\n}\n\nexport interface CircleCommand extends Base {\n kind: 'circle';\n cx: number;\n cy: number;\n radius: number;\n}\n\nexport interface PolyCommand extends Base {\n kind: 'poly';\n /** Flat [x0,y0,x1,y1,\u2026] in local space. */\n points: number[];\n closed: boolean;\n}\n\nexport interface PathCommand extends Base {\n kind: 'path';\n /** SVG path data in local space. */\n d: string;\n}\n\nexport interface TextCommand extends Base {\n kind: 'text';\n text: string;\n x: number;\n y: number;\n size: number;\n font?: string;\n align?: TextAlign;\n weight?: number;\n}\n\nexport interface ImageCommand extends Base {\n kind: 'image';\n /** data: URI or path. */\n href: string;\n x: number;\n y: number;\n w: number;\n h: number;\n}\n\nexport type DrawCommand =\n | RectCommand\n | CircleCommand\n | PolyCommand\n | PathCommand\n | TextCommand\n | ImageCommand;\n\n/** Stable painter's sort: by z, then original index (tree order) as tiebreak. */\nexport function sortCommands(cmds: DrawCommand[]): DrawCommand[] {\n return cmds\n .map((c, i) => [c, i] as const)\n .sort((a, b) => a[0].z - b[0].z || a[1] - b[1])\n .map(([c]) => c);\n}\n", "// Pure display-list \u2192 SVG markup. No DOM required, so it runs in Node \u2014 which\n// means the engine can produce a *vector screenshot* of any frame headlessly\n// (an AI-first win: judge layout from a file, no browser, no GPU, no fuzz).\n// The DOM SvgRenderer reuses this; tests assert on it directly.\n\nimport { sortCommands, type DrawCommand, type Paint } from './commands';\nimport type { Transform } from '../core/math';\n\nconst n = (v: number): string => (Number.isInteger(v) ? String(v) : (Math.round(v * 1000) / 1000).toString());\n\nfunction matrix(t: Transform): string {\n return `matrix(${n(t.a)} ${n(t.b)} ${n(t.c)} ${n(t.d)} ${n(t.e)} ${n(t.f)})`;\n}\n\nfunction paintAttrs(p: Paint): string {\n const parts: string[] = [];\n parts.push(`fill=\"${p.fill ?? 'none'}\"`);\n if (p.stroke) {\n parts.push(`stroke=\"${p.stroke}\"`);\n parts.push(`stroke-width=\"${n(p.strokeWidth ?? 1)}\"`);\n if (p.round) parts.push('stroke-linejoin=\"round\" stroke-linecap=\"round\"');\n }\n if (p.opacity !== undefined && p.opacity !== 1) parts.push(`opacity=\"${n(p.opacity)}\"`);\n return parts.join(' ');\n}\n\nfunction escapeText(s: string): string {\n return s.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');\n}\n\nfunction commandToSVG(c: DrawCommand): string {\n const tf = `transform=\"${matrix(c.transform)}\"`;\n const paint = paintAttrs(c);\n switch (c.kind) {\n case 'rect':\n return `<rect x=\"${n(c.x)}\" y=\"${n(c.y)}\" width=\"${n(c.w)}\" height=\"${n(c.h)}\"${c.r ? ` rx=\"${n(c.r)}\"` : ''} ${tf} ${paint}/>`;\n case 'circle':\n return `<circle cx=\"${n(c.cx)}\" cy=\"${n(c.cy)}\" r=\"${n(c.radius)}\" ${tf} ${paint}/>`;\n case 'poly': {\n const pts = [];\n for (let i = 0; i < c.points.length; i += 2) pts.push(`${n(c.points[i])},${n(c.points[i + 1])}`);\n const tag = c.closed ? 'polygon' : 'polyline';\n return `<${tag} points=\"${pts.join(' ')}\" ${tf} ${paint}/>`;\n }\n case 'path':\n return `<path d=\"${c.d}\" ${tf} ${paint}/>`;\n case 'text': {\n const anchor = c.align === 'center' ? 'middle' : c.align === 'right' ? 'end' : 'start';\n const font = c.font ? ` font-family=\"${c.font}\"` : '';\n const weight = c.weight ? ` font-weight=\"${c.weight}\"` : '';\n const fill = c.fill ?? '#000';\n return `<text x=\"${n(c.x)}\" y=\"${n(c.y)}\" font-size=\"${n(c.size)}\" text-anchor=\"${anchor}\" dominant-baseline=\"middle\"${font}${weight} fill=\"${fill}\"${c.opacity !== undefined && c.opacity !== 1 ? ` opacity=\"${n(c.opacity)}\"` : ''} ${tf}>${escapeText(c.text)}</text>`;\n }\n case 'image':\n return `<image href=\"${c.href}\" x=\"${n(c.x)}\" y=\"${n(c.y)}\" width=\"${n(c.w)}\" height=\"${n(c.h)}\" ${tf}${c.opacity !== undefined && c.opacity !== 1 ? ` opacity=\"${n(c.opacity)}\"` : ''}/>`;\n }\n}\n\n/** Inner SVG markup for a display list (no wrapping <svg>). */\nexport function commandsToSVGInner(commands: DrawCommand[]): string {\n return sortCommands(commands).map(commandToSVG).join('');\n}\n\n/** A complete, standalone SVG document string for a frame \u2014 a headless screenshot. */\nexport function renderToSVGString(\n commands: DrawCommand[],\n width: number,\n height: number,\n background = '#ffffff',\n): string {\n return (\n `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 ${width} ${height}\" width=\"${width}\" height=\"${height}\">` +\n `<rect x=\"0\" y=\"0\" width=\"${width}\" height=\"${height}\" fill=\"${background}\"/>` +\n commandsToSVGInner(commands) +\n `</svg>`\n );\n}\n", "// SVG DOM backend. Resolution-independent (crisp at any DPR \u2014 the OHYG lesson:\n// SVG sidesteps canvas text fuzz entirely) and DOM-inspectable, which makes\n// browser verification trivial: querySelector IS the probe.\n\nimport type { DrawCommand } from './commands';\nimport type { Renderer, RendererConfig } from './renderer';\nimport { commandsToSVGInner } from './svgString';\n\nconst SVGNS = 'http://www.w3.org/2000/svg';\n\nexport class SvgRenderer implements Renderer {\n readonly width: number;\n readonly height: number;\n private background: string;\n private svg: SVGSVGElement;\n private bg: SVGRectElement;\n private layer: SVGGElement;\n\n constructor(config: RendererConfig) {\n this.width = config.width;\n this.height = config.height;\n this.background = config.background ?? '#ffffff';\n\n this.svg = document.createElementNS(SVGNS, 'svg');\n this.svg.setAttribute('viewBox', `0 0 ${this.width} ${this.height}`);\n this.svg.setAttribute('preserveAspectRatio', 'xMidYMid meet');\n this.svg.style.width = '100%';\n this.svg.style.height = '100%';\n this.svg.style.display = 'block';\n\n this.bg = document.createElementNS(SVGNS, 'rect');\n this.bg.setAttribute('x', '0');\n this.bg.setAttribute('y', '0');\n this.bg.setAttribute('width', String(this.width));\n this.bg.setAttribute('height', String(this.height));\n this.bg.setAttribute('fill', this.background);\n this.svg.appendChild(this.bg);\n\n this.layer = document.createElementNS(SVGNS, 'g');\n this.svg.appendChild(this.layer);\n }\n\n mount(parent: HTMLElement): void {\n parent.appendChild(this.svg);\n }\n\n draw(commands: DrawCommand[]): void {\n // Simple and correct for v0.1: rebuild the layer markup each frame. SVG is\n // retained-mode so the browser diffs efficiently; heavy scenes use Canvas2D.\n this.layer.innerHTML = commandsToSVGInner(commands);\n }\n\n setBackground(color: string): void {\n this.background = color;\n this.bg.setAttribute('fill', color);\n }\n\n get element(): SVGSVGElement {\n return this.svg;\n }\n\n dispose(): void {\n this.svg.remove();\n }\n}\n", "// Canvas2D backend. For scenes with many primitives/particles where SVG's DOM\n// node count would bite. Same display list, immediate-mode painting, DPR-aware.\n\nimport { sortCommands, type DrawCommand, type Paint } from './commands';\nimport type { Renderer, RendererConfig } from './renderer';\n\nexport class Canvas2DRenderer implements Renderer {\n readonly width: number;\n readonly height: number;\n private background: string;\n private canvas: HTMLCanvasElement;\n private ctx: CanvasRenderingContext2D;\n private dpr = 1;\n\n constructor(config: RendererConfig) {\n this.width = config.width;\n this.height = config.height;\n this.background = config.background ?? '#ffffff';\n this.canvas = document.createElement('canvas');\n this.canvas.style.width = '100%';\n this.canvas.style.height = '100%';\n this.canvas.style.display = 'block';\n const ctx = this.canvas.getContext('2d');\n if (!ctx) throw new Error('hayao: 2D canvas context unavailable');\n this.ctx = ctx;\n this.resize();\n }\n\n mount(parent: HTMLElement): void {\n parent.appendChild(this.canvas);\n this.resize();\n }\n\n private resize(): void {\n this.dpr = Math.min(3, globalThis.devicePixelRatio || 1);\n this.canvas.width = Math.round(this.width * this.dpr);\n this.canvas.height = Math.round(this.height * this.dpr);\n }\n\n draw(commands: DrawCommand[]): void {\n const ctx = this.ctx;\n ctx.setTransform(this.dpr, 0, 0, this.dpr, 0, 0);\n ctx.fillStyle = this.background;\n ctx.fillRect(0, 0, this.width, this.height);\n\n for (const c of sortCommands(commands)) {\n ctx.save();\n const t = c.transform;\n ctx.transform(t.a, t.b, t.c, t.d, t.e, t.f);\n ctx.globalAlpha = (c as Paint).opacity ?? 1;\n this.paint(ctx, c);\n ctx.restore();\n }\n }\n\n private stroke(ctx: CanvasRenderingContext2D, c: Paint): void {\n if (c.fill && c.fill !== 'none') {\n ctx.fillStyle = c.fill;\n ctx.fill();\n }\n if (c.stroke) {\n ctx.strokeStyle = c.stroke;\n ctx.lineWidth = c.strokeWidth ?? 1;\n if (c.round) {\n ctx.lineJoin = 'round';\n ctx.lineCap = 'round';\n }\n ctx.stroke();\n }\n }\n\n private paint(ctx: CanvasRenderingContext2D, c: DrawCommand): void {\n switch (c.kind) {\n case 'rect':\n ctx.beginPath();\n if (c.r) this.roundRect(ctx, c.x, c.y, c.w, c.h, c.r);\n else ctx.rect(c.x, c.y, c.w, c.h);\n this.stroke(ctx, c);\n break;\n case 'circle':\n ctx.beginPath();\n ctx.arc(c.cx, c.cy, c.radius, 0, Math.PI * 2);\n this.stroke(ctx, c);\n break;\n case 'poly':\n ctx.beginPath();\n for (let i = 0; i < c.points.length; i += 2) {\n if (i === 0) ctx.moveTo(c.points[i], c.points[i + 1]);\n else ctx.lineTo(c.points[i], c.points[i + 1]);\n }\n if (c.closed) ctx.closePath();\n this.stroke(ctx, c);\n break;\n case 'path':\n {\n const p = new Path2D(c.d);\n if (c.fill && c.fill !== 'none') {\n ctx.fillStyle = c.fill;\n ctx.fill(p);\n }\n if (c.stroke) {\n ctx.strokeStyle = c.stroke;\n ctx.lineWidth = c.strokeWidth ?? 1;\n if (c.round) {\n ctx.lineJoin = 'round';\n ctx.lineCap = 'round';\n }\n ctx.stroke(p);\n }\n }\n break;\n case 'text':\n ctx.fillStyle = c.fill ?? '#000';\n ctx.font = `${c.weight ?? 400} ${c.size}px ${c.font ?? 'sans-serif'}`;\n ctx.textAlign = c.align ?? 'left';\n ctx.textBaseline = 'middle';\n ctx.fillText(c.text, c.x, c.y);\n break;\n case 'image':\n break; // images loaded async; omitted in v0.1 canvas backend\n }\n }\n\n private roundRect(ctx: CanvasRenderingContext2D, x: number, y: number, w: number, h: number, r: number): void {\n const rr = Math.min(r, w / 2, h / 2);\n ctx.moveTo(x + rr, y);\n ctx.arcTo(x + w, y, x + w, y + h, rr);\n ctx.arcTo(x + w, y + h, x, y + h, rr);\n ctx.arcTo(x, y + h, x, y, rr);\n ctx.arcTo(x, y, x + w, y, rr);\n ctx.closePath();\n }\n\n get element(): HTMLCanvasElement {\n return this.canvas;\n }\n\n dispose(): void {\n this.canvas.remove();\n }\n}\n", "// The headless backend: records the last display list instead of painting it.\n// Tests assert on the commands directly; scripts turn them into a vector\n// screenshot via renderToSVGString. This is why a hayao game is testable with\n// zero browser \u2014 the renderer is just a data sink.\n\nimport type { DrawCommand } from './commands';\nimport type { Renderer, RendererConfig } from './renderer';\nimport { renderToSVGString } from './svgString';\n\nexport class HeadlessRenderer implements Renderer {\n readonly width: number;\n readonly height: number;\n private background: string;\n private last: DrawCommand[] = [];\n frameCount = 0;\n\n constructor(config: RendererConfig) {\n this.width = config.width;\n this.height = config.height;\n this.background = config.background ?? '#ffffff';\n }\n\n draw(commands: DrawCommand[]): void {\n this.last = commands;\n this.frameCount++;\n }\n\n /** The most recently drawn display list. */\n get commands(): DrawCommand[] {\n return this.last;\n }\n\n /** Count commands of a given kind (handy for assertions). */\n count(kind: DrawCommand['kind']): number {\n return this.last.filter((c) => c.kind === kind).length;\n }\n\n /** A vector screenshot of the last frame. */\n toSVGString(): string {\n return renderToSVGString(this.last, this.width, this.height, this.background);\n }\n}\n", "// Curated palettes \u2014 code-as-art means no arbitrary RGB; pick from a named,\n// on-model set. Default is a warm, high-legibility \"Meadow\" palette (a nod to\n// the Ghibli/Miyazaki-ish direction the engine is named for).\n\nexport interface Palette {\n name: string;\n bg: string;\n ink: string;\n inkSoft: string;\n line: string;\n accent: string;\n accent2: string;\n good: string;\n warn: string;\n /** A small ordered ramp for categorical fills. */\n ramp: string[];\n}\n\nexport const MEADOW: Palette = {\n name: 'meadow',\n bg: '#f3ecdb',\n ink: '#3d3323',\n inkSoft: '#6f6047',\n line: '#d9ccae',\n accent: '#a11d3a',\n accent2: '#5a7d4e',\n good: '#4d6b3c',\n warn: '#c8791f',\n ramp: ['#a11d3a', '#c8791f', '#c9a22f', '#5a7d4e', '#3f7d8c', '#6a4c93'],\n};\n\nexport const DUSK: Palette = {\n name: 'dusk',\n bg: '#1c1a24',\n ink: '#efe9f2',\n inkSoft: '#a89fb5',\n line: '#3a3546',\n accent: '#e26d8a',\n accent2: '#6cc4a1',\n good: '#6cc4a1',\n warn: '#e8b64a',\n ramp: ['#e26d8a', '#e8b64a', '#f2e07a', '#6cc4a1', '#5aa9d6', '#b493e6'],\n};\n\nexport const PAPER: Palette = {\n name: 'paper',\n bg: '#faf7f0',\n ink: '#2b2b2b',\n inkSoft: '#666',\n line: '#e2ddd2',\n accent: '#d1495b',\n accent2: '#2e86ab',\n good: '#3c896d',\n warn: '#e0902f',\n ramp: ['#d1495b', '#e0902f', '#edc531', '#3c896d', '#2e86ab', '#8a5a9e'],\n};\n\nexport const PALETTES: Record<string, Palette> = { meadow: MEADOW, dusk: DUSK, paper: PAPER };\n\n/** Blend two hex colors (t in [0,1]). Deterministic, no allocations of note. */\nexport function mix(a: string, b: string, t: number): string {\n const pa = hexToRgb(a);\n const pb = hexToRgb(b);\n const r = Math.round(pa[0] + (pb[0] - pa[0]) * t);\n const g = Math.round(pa[1] + (pb[1] - pa[1]) * t);\n const bl = Math.round(pa[2] + (pb[2] - pa[2]) * t);\n return rgbToHex(r, g, bl);\n}\n\nexport function withAlpha(hex: string, alpha: number): string {\n const [r, g, b] = hexToRgb(hex);\n return `rgba(${r}, ${g}, ${b}, ${alpha})`;\n}\n\nfunction hexToRgb(hex: string): [number, number, number] {\n let h = hex.replace('#', '');\n if (h.length === 3) h = h.split('').map((c) => c + c).join('');\n const n = parseInt(h, 16);\n return [(n >> 16) & 255, (n >> 8) & 255, n & 255];\n}\nfunction rgbToHex(r: number, g: number, b: number): string {\n return '#' + [r, g, b].map((v) => Math.max(0, Math.min(255, v)).toString(16).padStart(2, '0')).join('');\n}\n", "// Procedural vector shape builders \u2014 the \"code-as-art\" toolkit. All pure and\n// deterministic (any randomness must be passed an Rng), producing point arrays\n// or SVG path strings usable directly in a Sprite.\n\nimport type { Rng } from '../core/rng';\nimport { TAU, type Vec2 } from '../core/math';\n\n/** Regular polygon points (flat [x,y,\u2026]) centered at origin. */\nexport function regularPolygon(sides: number, radius: number, rotation = 0): number[] {\n const pts: number[] = [];\n for (let i = 0; i < sides; i++) {\n const a = rotation + (i / sides) * TAU;\n pts.push(Math.cos(a) * radius, Math.sin(a) * radius);\n }\n return pts;\n}\n\n/** Star with alternating outer/inner radii. */\nexport function star(points: number, outer: number, inner: number, rotation = -Math.PI / 2): number[] {\n const pts: number[] = [];\n for (let i = 0; i < points * 2; i++) {\n const r = i % 2 === 0 ? outer : inner;\n const a = rotation + (i / (points * 2)) * TAU;\n pts.push(Math.cos(a) * r, Math.sin(a) * r);\n }\n return pts;\n}\n\n/** An organic blob outline as an SVG path (deterministic given the Rng). */\nexport function blobPath(rng: Rng, radius: number, wobble = 0.25, lobes = 7): string {\n const pts: Vec2[] = [];\n for (let i = 0; i < lobes; i++) {\n const a = (i / lobes) * TAU;\n const r = radius * (1 - wobble + rng.float() * wobble * 2);\n pts.push({ x: Math.cos(a) * r, y: Math.sin(a) * r });\n }\n return smoothClosedPath(pts);\n}\n\n/** Convert a point list into a smooth closed path (Catmull-Rom \u2192 cubic B\u00E9zier). */\nexport function smoothClosedPath(points: Vec2[], tension = 1): string {\n const nPts = points.length;\n if (nPts < 3) return '';\n const p = (i: number) => points[((i % nPts) + nPts) % nPts];\n const r = (v: number) => Math.round(v * 100) / 100;\n let d = `M ${r(p(0).x)} ${r(p(0).y)}`;\n for (let i = 0; i < nPts; i++) {\n const p0 = p(i - 1);\n const p1 = p(i);\n const p2 = p(i + 1);\n const p3 = p(i + 2);\n const c1x = p1.x + ((p2.x - p0.x) / 6) * tension;\n const c1y = p1.y + ((p2.y - p0.y) / 6) * tension;\n const c2x = p2.x - ((p3.x - p1.x) / 6) * tension;\n const c2y = p2.y - ((p3.y - p1.y) / 6) * tension;\n d += ` C ${r(c1x)} ${r(c1y)}, ${r(c2x)} ${r(c2y)}, ${r(p2.x)} ${r(p2.y)}`;\n }\n return d + ' Z';\n}\n\n/** Smooth open path through points (for trails, curves). */\nexport function smoothOpenPath(points: Vec2[], tension = 1): string {\n const nPts = points.length;\n if (nPts < 2) return '';\n const r = (v: number) => Math.round(v * 100) / 100;\n let d = `M ${r(points[0].x)} ${r(points[0].y)}`;\n for (let i = 0; i < nPts - 1; i++) {\n const p0 = points[Math.max(0, i - 1)];\n const p1 = points[i];\n const p2 = points[i + 1];\n const p3 = points[Math.min(nPts - 1, i + 2)];\n const c1x = p1.x + ((p2.x - p0.x) / 6) * tension;\n const c1y = p1.y + ((p2.y - p0.y) / 6) * tension;\n const c2x = p2.x - ((p3.x - p1.x) / 6) * tension;\n const c2y = p2.y - ((p3.y - p1.y) / 6) * tension;\n d += ` C ${r(c1x)} ${r(c1y)}, ${r(c2x)} ${r(c2y)}, ${r(p2.x)} ${r(p2.y)}`;\n }\n return d;\n}\n", "// Procedural audio bus. Code-as-sound: zzfx-style tone synthesis + an ambient\n// pad, no audio files. A no-op when there's no AudioContext (Node/headless), so\n// automated runs are silent by construction (a narrow-js invariant).\n\nexport interface Volumes {\n master: number;\n music: number;\n sfx: number;\n muted: boolean;\n}\n\nconst DEFAULT_VOLUMES: Volumes = { master: 0.7, music: 0.6, sfx: 0.8, muted: false };\n\n/** A single zzfx-ish tone spec. */\nexport interface Tone {\n freq: number;\n duration: number;\n type?: OscillatorType;\n gain?: number;\n delay?: number;\n}\n\nexport class AudioBus {\n private ctx: AudioContext | null = null;\n private master: GainNode | null = null;\n private musicGain: GainNode | null = null;\n private sfxGain: GainNode | null = null;\n private vol: Volumes = { ...DEFAULT_VOLUMES };\n private padOn = false;\n\n get available(): boolean {\n return typeof globalThis.AudioContext !== 'undefined' || 'webkitAudioContext' in globalThis;\n }\n get started(): boolean {\n return !!this.ctx;\n }\n\n /** Must be called from a user gesture (browser autoplay policy). */\n start(): void {\n if (this.ctx) {\n void this.ctx.resume();\n return;\n }\n if (!this.available) return;\n const Ctx =\n globalThis.AudioContext ||\n (globalThis as unknown as { webkitAudioContext: typeof AudioContext }).webkitAudioContext;\n this.ctx = new Ctx();\n this.master = this.ctx.createGain();\n this.musicGain = this.ctx.createGain();\n this.sfxGain = this.ctx.createGain();\n this.musicGain.connect(this.master);\n this.sfxGain.connect(this.master);\n this.master.connect(this.ctx.destination);\n this.applyVolumes();\n }\n\n setVolumes(v: Partial<Volumes>): void {\n this.vol = { ...this.vol, ...v };\n this.applyVolumes();\n }\n getVolumes(): Volumes {\n return { ...this.vol };\n }\n\n private applyVolumes(): void {\n if (!this.ctx || !this.master || !this.musicGain || !this.sfxGain) return;\n const t = this.ctx.currentTime;\n this.master.gain.setTargetAtTime(this.vol.muted ? 0 : this.vol.master, t, 0.04);\n this.musicGain.gain.setTargetAtTime(this.vol.music * 0.5, t, 0.04);\n this.sfxGain.gain.setTargetAtTime(this.vol.sfx, t, 0.04);\n }\n\n /** Play a single tone (no-op if audio unstarted). */\n tone(spec: Tone): void {\n if (!this.ctx || !this.sfxGain) return;\n const { freq, duration, type = 'sine', gain = 0.2, delay = 0 } = spec;\n const t = this.ctx.currentTime + delay;\n const osc = this.ctx.createOscillator();\n osc.type = type;\n osc.frequency.value = freq;\n const g = this.ctx.createGain();\n g.gain.setValueAtTime(0, t);\n g.gain.linearRampToValueAtTime(gain, t + 0.008);\n g.gain.exponentialRampToValueAtTime(0.0001, t + duration);\n osc.connect(g);\n g.connect(this.sfxGain);\n osc.start(t);\n osc.stop(t + duration + 0.05);\n }\n\n /** Play a sequence of tones as an arpeggio/chord. */\n play(tones: Tone[]): void {\n for (const t of tones) this.tone(t);\n }\n\n /** Convenience SFX. */\n blip(freq = 520): void {\n this.tone({ freq, duration: 0.06, type: 'sine', gain: 0.18 });\n }\n chime(): void {\n [523.25, 659.25, 783.99].forEach((f, i) => this.tone({ freq: f, duration: 0.9 - i * 0.15, type: 'sine', gain: 0.15, delay: i * 0.04 }));\n }\n success(): void {\n [392, 493.88, 587.33, 783.99].forEach((f, i) => this.tone({ freq: f, duration: 0.4, type: 'triangle', gain: 0.15, delay: i * 0.08 }));\n }\n thud(): void {\n this.tone({ freq: 130, duration: 0.14, type: 'sine', gain: 0.22 });\n }\n\n /** Start a soft evolving ambient pad on the music bus. */\n startAmbient(root = 110, voices = [1, 1.5, 2, 2.5]): void {\n if (!this.ctx || !this.musicGain || this.padOn) return;\n this.padOn = true;\n const filter = this.ctx.createBiquadFilter();\n filter.type = 'lowpass';\n filter.frequency.value = 900;\n filter.connect(this.musicGain);\n const bus = this.ctx.createGain();\n bus.gain.value = 0;\n bus.connect(filter);\n for (const mult of voices) {\n const osc = this.ctx.createOscillator();\n osc.type = 'triangle';\n osc.frequency.value = root * mult;\n const g = this.ctx.createGain();\n g.gain.value = 0.1 / voices.length;\n osc.connect(g);\n g.connect(bus);\n osc.start();\n }\n bus.gain.setTargetAtTime(0.9, this.ctx.currentTime, 3);\n }\n}\n\n/** Shared default bus. */\nexport const audio = new AudioBus();\n", "// DOM overlay screens \u2014 titles, menus, game-over, HUD. Crisp DOM type instead of\n// canvas text (narrow-js lesson: humans compare canvas text to DOM and canvas\n// loses). Keyboard-navigable by construction. Browser-only; no-op guards for SSR.\n\nexport interface MenuAction {\n label: string;\n onSelect: () => void;\n primary?: boolean;\n}\n\nexport interface ScreenSpec {\n title?: string;\n /** Subtitle / body text (plain text or HTML string). */\n body?: string;\n /** Menu actions, navigable with up/down + Enter. */\n actions?: MenuAction[];\n /** Dim the game behind the screen. */\n dim?: boolean;\n /** Extra class for theming. */\n className?: string;\n}\n\nexport interface ScreenHandle {\n close(): void;\n readonly element: HTMLElement;\n}\n\nlet active: ScreenHandle | null = null;\n\nconst STYLE_ID = 'hayao-overlay-style';\nconst CSS = `\n.hy-scrim{position:absolute;inset:0;display:grid;place-items:center;z-index:50;font-family:var(--hy-serif,Georgia,serif)}\n.hy-scrim.dim{background:rgba(30,24,14,.5);backdrop-filter:blur(2px)}\n.hy-card{background:var(--hy-paper,#fbf6ea);color:var(--hy-ink,#3d3323);border:1px solid var(--hy-line,#d9ccae);border-radius:14px;box-shadow:0 14px 44px rgba(40,30,15,.3);padding:26px 30px;max-width:440px;text-align:center}\n.hy-card h1{margin:0 0 6px;font-size:30px}\n.hy-card .hy-body{color:var(--hy-ink-soft,#6f6047);font-size:15px;line-height:1.5;margin-bottom:18px}\n.hy-menu{display:flex;flex-direction:column;gap:8px;align-items:stretch}\n.hy-item{font:inherit;font-size:16px;padding:9px 16px;border-radius:9px;border:1px solid var(--hy-line,#d9ccae);background:transparent;color:inherit;cursor:pointer;transition:transform .1s,background .1s}\n.hy-item:hover,.hy-item.sel{background:var(--hy-accent,#a11d3a);color:#fdf3ee;border-color:transparent;transform:translateY(-1px)}\n.hy-item.primary{background:var(--hy-accent,#a11d3a);color:#fdf3ee;border-color:transparent}\n`;\n\nfunction ensureStyle(): void {\n if (typeof document === 'undefined' || document.getElementById(STYLE_ID)) return;\n const s = document.createElement('style');\n s.id = STYLE_ID;\n s.textContent = CSS;\n document.head.appendChild(s);\n}\n\nlet host: HTMLElement | null = null;\n/** Set the element overlays mount into (defaults to document.body). */\nexport function setOverlayHost(el: HTMLElement): void {\n host = el;\n}\n\n/** Show a screen (replaces any current one). Returns a handle. */\nexport function showScreen(spec: ScreenSpec): ScreenHandle {\n if (typeof document === 'undefined') {\n return { close() {}, element: null as unknown as HTMLElement };\n }\n ensureStyle();\n hideScreen();\n\n const scrim = document.createElement('div');\n scrim.className = `hy-scrim${spec.dim === false ? '' : ' dim'}${spec.className ? ' ' + spec.className : ''}`;\n const card = document.createElement('div');\n card.className = 'hy-card';\n\n if (spec.title) {\n const h = document.createElement('h1');\n h.textContent = spec.title;\n card.appendChild(h);\n }\n if (spec.body) {\n const b = document.createElement('div');\n b.className = 'hy-body';\n b.innerHTML = spec.body;\n card.appendChild(b);\n }\n\n const actions = spec.actions ?? [];\n let sel = Math.max(0, actions.findIndex((a) => a.primary));\n if (sel < 0) sel = 0;\n const items: HTMLButtonElement[] = [];\n if (actions.length) {\n const menu = document.createElement('div');\n menu.className = 'hy-menu';\n actions.forEach((a, i) => {\n const btn = document.createElement('button');\n btn.className = `hy-item${a.primary ? ' primary' : ''}`;\n btn.textContent = a.label;\n btn.addEventListener('click', () => a.onSelect());\n btn.addEventListener('mouseenter', () => setSel(i));\n menu.appendChild(btn);\n items.push(btn);\n });\n card.appendChild(menu);\n }\n\n function setSel(i: number): void {\n sel = (i + items.length) % items.length;\n items.forEach((el, k) => el.classList.toggle('sel', k === sel));\n }\n if (items.length) setSel(sel);\n\n const onKey = (e: KeyboardEvent) => {\n if (!items.length) return;\n if (e.code === 'ArrowDown') { setSel(sel + 1); e.preventDefault(); }\n else if (e.code === 'ArrowUp') { setSel(sel - 1); e.preventDefault(); }\n else if (e.code === 'Enter' || e.code === 'Space') { actions[sel]?.onSelect(); e.preventDefault(); }\n };\n document.addEventListener('keydown', onKey);\n\n scrim.appendChild(card);\n (host ?? document.body).appendChild(scrim);\n\n const handle: ScreenHandle = {\n element: scrim,\n close() {\n document.removeEventListener('keydown', onKey);\n scrim.remove();\n if (active === handle) active = null;\n },\n };\n active = handle;\n return handle;\n}\n\nexport function hideScreen(): void {\n active?.close();\n}\n", "// Player settings, persisted to localStorage and pushed into the audio bus.\n// Framework-agnostic (plain object + subscribe), so any game/UI can bind to it.\n\nimport { audio } from '../audio/audio';\n\nexport interface Settings {\n master: number;\n music: number;\n sfx: number;\n muted: boolean;\n colorblind: boolean;\n reducedMotion: boolean;\n}\n\nconst KEY = 'hayao.settings.v1';\nconst DEFAULTS: Settings = { master: 0.7, music: 0.6, sfx: 0.8, muted: false, colorblind: false, reducedMotion: false };\n\ntype Sub = (s: Settings) => void;\n\nclass SettingsStore {\n private state: Settings;\n private subs = new Set<Sub>();\n\n constructor() {\n this.state = this.load();\n this.pushToAudio();\n }\n\n get(): Settings {\n return { ...this.state };\n }\n\n set(patch: Partial<Settings>): void {\n this.state = { ...this.state, ...patch };\n this.save();\n this.pushToAudio();\n for (const fn of this.subs) fn(this.get());\n }\n\n subscribe(fn: Sub): () => void {\n this.subs.add(fn);\n return () => this.subs.delete(fn);\n }\n\n private pushToAudio(): void {\n audio.setVolumes({ master: this.state.master, music: this.state.music, sfx: this.state.sfx, muted: this.state.muted });\n }\n\n private load(): Settings {\n try {\n const raw = typeof localStorage !== 'undefined' && localStorage.getItem(KEY);\n if (raw) return { ...DEFAULTS, ...JSON.parse(raw) };\n } catch {\n /* ignore */\n }\n return { ...DEFAULTS };\n }\n private save(): void {\n try {\n localStorage.setItem(KEY, JSON.stringify(this.state));\n } catch {\n /* ignore */\n }\n }\n}\n\nexport const settings = new SettingsStore();\n\n// \u2500\u2500 Fullscreen helper \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport function toggleFullscreen(): void {\n if (typeof document === 'undefined') return;\n const doc = document as Document & { webkitFullscreenElement?: Element; webkitExitFullscreen?: () => void };\n const el = document.documentElement as HTMLElement & { webkitRequestFullscreen?: () => void };\n if (document.fullscreenElement || doc.webkitFullscreenElement) {\n (document.exitFullscreen ?? doc.webkitExitFullscreen)?.call(document);\n } else {\n (el.requestFullscreen ?? el.webkitRequestFullscreen)?.call(el);\n }\n}\n", "// The game shell: a pause menu (Esc) with volume, mute, fullscreen, restart, and\n// back-to-hub \u2014 every game gets it for free (narrow-js lesson: the shell owns Esc,\n// kills debug-key landmines, and standardizes chrome). Browser-only.\n\nimport { audio } from '../audio/audio';\nimport { settings, toggleFullscreen } from './settings';\nimport { showScreen, hideScreen } from './overlay';\n\nexport interface ShellOptions {\n onRestart?: () => void;\n onQuit?: () => void;\n /** Called with true when paused, false when resumed. */\n onPause?: (paused: boolean) => void;\n title?: string;\n}\n\nexport class Shell {\n private paused = false;\n private opts: ShellOptions;\n private keyHandler: (e: KeyboardEvent) => void;\n\n constructor(opts: ShellOptions = {}) {\n this.opts = opts;\n this.keyHandler = (e: KeyboardEvent) => {\n if (e.code === 'Escape') {\n e.preventDefault();\n this.toggle();\n }\n };\n if (typeof document !== 'undefined') document.addEventListener('keydown', this.keyHandler);\n }\n\n get isPaused(): boolean {\n return this.paused;\n }\n\n toggle(): void {\n this.paused ? this.resume() : this.pause();\n }\n\n pause(): void {\n if (this.paused) return;\n this.paused = true;\n audio.blip(440);\n this.opts.onPause?.(true);\n this.render();\n }\n\n resume(): void {\n if (!this.paused) return;\n this.paused = false;\n hideScreen();\n this.opts.onPause?.(false);\n }\n\n private render(): void {\n const s = settings.get();\n const vol = (label: string, v: number) => `${label}: ${Math.round(v * 100)}`;\n showScreen({\n title: this.opts.title ?? 'Paused',\n body:\n `<div style=\"font-size:13px;text-align:left;line-height:1.9\">` +\n `${vol('Master', s.master)} \u00B7 ${vol('Music', s.music)} \u00B7 ${vol('Sfx', s.sfx)}` +\n `<br/><span style=\"opacity:.7\">Use the menu, or keys: M mute \u00B7 F fullscreen</span></div>`,\n actions: [\n { label: 'Resume', primary: true, onSelect: () => this.resume() },\n { label: s.muted ? 'Unmute (M)' : 'Mute (M)', onSelect: () => { settings.set({ muted: !settings.get().muted }); this.render(); } },\n { label: 'Music \u2212/+', onSelect: () => { const m = Math.min(1, settings.get().music + 0.1) % 1.05; settings.set({ music: m > 1 ? 0 : m }); this.render(); } },\n { label: 'Fullscreen (F)', onSelect: () => toggleFullscreen() },\n ...(this.opts.onRestart ? [{ label: 'Restart', onSelect: () => { this.resume(); this.opts.onRestart!(); } }] : []),\n ...(this.opts.onQuit ? [{ label: 'Quit', onSelect: () => { this.resume(); this.opts.onQuit!(); } }] : []),\n ],\n });\n }\n\n dispose(): void {\n if (typeof document !== 'undefined') document.removeEventListener('keydown', this.keyHandler);\n hideScreen();\n }\n}\n", "// Generic winnability solver. Turn-based/puzzle logic implements the pure\n// Puzzle interface; the solver proves a level beatable by search. Deterministic\n// opponent (fixed order + tie-breaks) means single-agent BFS \u2014 no adversarial\n// branching. (narrow-js's insight, generalized and typed.)\n//\n// Rule of the house: a hand-authored level is presumed WRONG until the solver\n// proves it winnable. In-head verification has a documented failure rate.\n\nexport interface Puzzle<State, Move> {\n /** Starting state (optionally per level index). */\n initial(level?: number): State;\n /** Legal moves from a state, in deterministic order. */\n moves(state: State): Move[];\n /** Apply a player move (may fold in a deterministic opponent response). */\n apply(state: State, move: Move): State;\n /** Win test. */\n isWin(state: State): boolean;\n /** Optional dead/lost test \u2014 pruned from the search. */\n isDead?(state: State): boolean;\n /** Canonical key for de-duplication (visited set). */\n key(state: State): string;\n}\n\nexport interface SolveResult<Move> {\n solvable: boolean;\n /** Shortest winning move sequence, if found. */\n path?: Move[];\n /** Depth of the shortest solution. */\n depth?: number;\n /** Nodes expanded (a difficulty/complexity proxy). */\n nodes: number;\n /** True if the search hit a cap before proving/\u200Bdisproving. */\n exhausted: boolean;\n}\n\nexport interface SolveOptions {\n level?: number;\n maxDepth?: number;\n nodeCap?: number;\n}\n\n/** Breadth-first search \u2192 the shortest solution and a real winnability proof. */\nexport function solve<State, Move>(\n puzzle: Puzzle<State, Move>,\n options: SolveOptions = {},\n): SolveResult<Move> {\n const maxDepth = options.maxDepth ?? 60;\n const nodeCap = options.nodeCap ?? 1_000_000;\n const start = puzzle.initial(options.level);\n\n if (puzzle.isWin(start)) return { solvable: true, path: [], depth: 0, nodes: 0, exhausted: false };\n\n interface QNode {\n state: State;\n path: Move[];\n }\n let frontier: QNode[] = [{ state: start, path: [] }];\n const seen = new Set<string>([puzzle.key(start)]);\n let nodes = 0;\n\n for (let depth = 0; depth < maxDepth && frontier.length > 0; depth++) {\n const next: QNode[] = [];\n for (const { state, path } of frontier) {\n for (const move of puzzle.moves(state)) {\n if (nodes >= nodeCap) return { solvable: false, nodes, exhausted: true };\n nodes++;\n const after = puzzle.apply(state, move);\n if (puzzle.isDead?.(after)) continue;\n if (puzzle.isWin(after)) {\n return { solvable: true, path: [...path, move], depth: depth + 1, nodes, exhausted: false };\n }\n const k = puzzle.key(after);\n if (!seen.has(k)) {\n seen.add(k);\n next.push({ state: after, path: [...path, move] });\n }\n }\n }\n frontier = next;\n }\n return { solvable: false, nodes, exhausted: frontier.length > 0 };\n}\n\n/**\n * Assert a puzzle level is winnable (throws with detail if not). Use in tests as\n * the content-balance gate.\n */\nexport function assertSolvable<State, Move>(\n puzzle: Puzzle<State, Move>,\n options: SolveOptions = {},\n): SolveResult<Move> {\n const result = solve(puzzle, options);\n if (!result.solvable) {\n throw new Error(\n `hayao: level ${options.level ?? 0} is NOT winnable ` +\n `(expanded ${result.nodes} nodes${result.exhausted ? ', search capped \u2014 raise nodeCap/maxDepth' : ''}).`,\n );\n }\n return result;\n}\n", "// Determinism verification. Re-run the same seed + input log twice; if any step's\n// state hash diverges, some hidden nondeterminism (Math.random, Date.now, Set\n// iteration, unordered map) leaked in. This is the regression net that lets you\n// refactor the sim fearlessly.\n\nimport type { World } from '../world';\nimport type { InputLog } from '../input/actions';\nimport { frameActions } from '../input/actions';\n\nexport type WorldFactory = () => World;\n\n/** Run a world through an input log, returning the final hash and per-frame hashes. */\nexport function replay(makeWorld: WorldFactory, log: InputLog): { finalHash: string; hashes: string[] } {\n const world = makeWorld();\n const hashes: string[] = [];\n for (let i = 0; i < log.frames.length; i++) {\n world.step(frameActions(log, i));\n hashes.push(world.hash());\n }\n return { finalHash: world.hash(), hashes };\n}\n\nexport interface DeterminismReport {\n ok: boolean;\n frames: number;\n /** First frame index where the two runs diverged, or -1. */\n divergedAt: number;\n finalHash: string;\n}\n\n/** Run twice and compare every step's hash. */\nexport function checkDeterministic(makeWorld: WorldFactory, log: InputLog): DeterminismReport {\n const a = replay(makeWorld, log);\n const b = replay(makeWorld, log);\n let divergedAt = -1;\n for (let i = 0; i < a.hashes.length; i++) {\n if (a.hashes[i] !== b.hashes[i]) {\n divergedAt = i;\n break;\n }\n }\n return {\n ok: divergedAt === -1 && a.finalHash === b.finalHash,\n frames: log.frames.length,\n divergedAt,\n finalHash: a.finalHash,\n };\n}\n\n/** Assert determinism (throws with the divergence frame). */\nexport function assertDeterministic(makeWorld: WorldFactory, log: InputLog): DeterminismReport {\n const report = checkDeterministic(makeWorld, log);\n if (!report.ok) {\n throw new Error(\n `hayao: sim is NON-deterministic \u2014 runs diverged at frame ${report.divergedAt} ` +\n `of ${report.frames}. Check for Math.random/Date.now/Set-iteration/unordered-map in the sim.`,\n );\n }\n return report;\n}\n\n/**\n * Assert that restoring a snapshot reproduces the exact same continuation \u2014\n * i.e. save/load is lossless. Runs `warmup` steps, snapshots, runs `tail` more\n * on both the original and a restored copy, and compares final hashes.\n */\nexport function assertSnapshotStable(\n makeWorld: WorldFactory,\n log: InputLog,\n warmup: number,\n): { ok: boolean; hashA: string; hashB: string } {\n const original = makeWorld();\n for (let i = 0; i < warmup; i++) original.step(frameActions(log, i));\n const snap = original.snapshot();\n\n const restored = makeWorld();\n restored.restore(snap);\n\n for (let i = warmup; i < log.frames.length; i++) {\n original.step(frameActions(log, i));\n restored.step(frameActions(log, i));\n }\n const hashA = original.hash();\n const hashB = restored.hash();\n return { ok: hashA === hashB, hashA, hashB };\n}\n", "// Scripted playthroughs: drive a world headlessly with a sequence of held-input\n// segments and collect probe snapshots. This is Channel 1a \u2014 proving behavior on\n// game state, in Node, no browser. (Hold keys \u2265 a few frames: variable-height\n// jumps treat a 1-frame synthetic tap as a real short tap.)\n\nimport type { World } from '../world';\n\nexport interface Segment {\n /** Actions held down for this segment. */\n actions?: string[];\n /** Number of fixed steps to run. */\n frames: number;\n}\n\n/** Build a segment: hold `actions` for `frames` steps. */\nexport function hold(actions: string[], frames: number): Segment {\n return { actions, frames };\n}\n/** Build an idle segment (no input) for `frames` steps. */\nexport function wait(frames: number): Segment {\n return { actions: [], frames };\n}\n\nexport interface PlaythroughResult {\n totalFrames: number;\n finalHash: string;\n /** Probe snapshot after each segment. */\n probes: Record<string, unknown>[];\n}\n\n/** Run a scripted playthrough; returns a probe after each segment. */\nexport function scriptedPlaythrough(world: World, script: Segment[]): PlaythroughResult {\n const probes: Record<string, unknown>[] = [];\n let total = 0;\n for (const seg of script) {\n for (let i = 0; i < seg.frames; i++) world.step(seg.actions ?? []);\n total += seg.frames;\n probes.push(world.probe());\n }\n return { totalFrames: total, finalHash: world.hash(), probes };\n}\n\n/** Convenience: advance a world N frames with a fixed input set. */\nexport function pump(world: World, frames: number, actions: string[] = []): void {\n for (let i = 0; i < frames; i++) world.step(actions);\n}\n", "// Browser capture seam. Because the sim is headless-native \u2014 hayao owns the\n// clock and never touches document.hasFocus \u2014 this is ~30 lines, not the ~100 a\n// canvas engine needs. Exposes window.__hayao for scripted browser sessions and\n// aesthetic screenshots. Enable with ?capture=1.\n\nimport type { World } from '../world';\n\nexport interface CaptureTarget {\n readonly world: World;\n /** Advance one fixed step with the given actions and render. */\n stepOnce(actions?: string[]): void;\n /** Current frame as an SVG string (a vector screenshot). */\n renderSVG(): string;\n setPaused(paused: boolean): void;\n}\n\nexport interface HayaoCapture {\n pump(frames: number, actions?: string[]): Record<string, unknown>;\n probe(): Record<string, unknown>;\n hash(): string;\n shot(): string;\n save(path: string): Promise<boolean>;\n key(type: 'keydown' | 'keyup', code: string): void;\n readonly world: World;\n}\n\nexport function isCaptureMode(): boolean {\n return typeof location !== 'undefined' && new URLSearchParams(location.search).has('capture');\n}\n\n/** Install window.__hayao for scripted browser verification. */\nexport function installCapture(target: CaptureTarget): HayaoCapture {\n const api: HayaoCapture = {\n pump(frames, actions = []) {\n target.setPaused(true);\n for (let i = 0; i < frames; i++) target.stepOnce(actions);\n return target.world.probe();\n },\n probe: () => target.world.probe(),\n hash: () => target.world.hash(),\n shot: () => target.renderSVG(),\n async save(path) {\n const svg = target.renderSVG();\n try {\n const res = await fetch('/__shot', {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ path, svg }),\n });\n return res.ok;\n } catch {\n return false;\n }\n },\n key(type, code) {\n document.dispatchEvent(new KeyboardEvent(type, { code, bubbles: true }));\n },\n get world() {\n return target.world;\n },\n };\n (globalThis as unknown as { __hayao: HayaoCapture }).__hayao = api;\n return api;\n}\n", "// Declarative input scripts: the ergonomic way to author headless playthroughs\n// for real-time games, where hand-writing per-frame action arrays is hopeless.\n// A script is a list of segments; each holds actions for N frames, optionally\n// tapping others on its first frame.\n\nimport type { World } from '../world';\n\nexport interface ScriptSegment {\n /** Actions held down for every frame of this segment. */\n hold?: string[];\n /** Actions pressed only on the first frame of this segment (taps). */\n press?: string[];\n /** How many fixed steps this segment lasts (default 1). */\n frames?: number;\n}\n\nexport type InputScript = ScriptSegment[];\n\n/** Expand a script into per-frame action arrays (an InputLog's frames). */\nexport function scriptToFrames(script: InputScript): string[][] {\n const out: string[][] = [];\n for (const seg of script) {\n const n = seg.frames ?? 1;\n const hold = seg.hold ?? [];\n for (let i = 0; i < n; i++) out.push(i === 0 && seg.press ? [...hold, ...seg.press] : [...hold]);\n }\n return out;\n}\n\nexport interface DriveResult {\n frames: number;\n /** True if driving stopped early because `until` matched. */\n matched: boolean;\n}\n\n/**\n * Step a world through a script. Pass `until` to stop as soon as a probe\n * predicate holds (e.g. level solved) \u2014 the tail of the script is slack, so\n * playthrough scripts don't need frame-perfect lengths.\n */\nexport function drive(world: World, script: InputScript, until?: (probe: Record<string, unknown>) => boolean): DriveResult {\n let frames = 0;\n for (const f of scriptToFrames(script)) {\n if (until && until(world.probe())) return { frames, matched: true };\n world.step(f);\n frames++;\n }\n return { frames, matched: until ? until(world.probe()) : false };\n}\n", "// The plan-interpreter bot skeleton \u2014 promoted to the engine after three\n// example games (shard-ascent, sproutveil, gleamvale) each rebuilt the same\n// shape: a plan of semantic steps, executed reactively against the probe each\n// frame, emitting actions. Games supply the step executors (steering is\n// genre-specific); the engine supplies the lifecycle, retries, and telemetry.\n//\n// const bot = createPlanBot(plan, {\n// walk(step, probe, out, ctx) { \u2026steer\u2026; if (arrived) ctx.next(); },\n// });\n// while (!probe.won) world.step(bot(world.probe()));\n\nexport interface BotCtx {\n /** Frames spent in the current step. */\n frames: number;\n /** Free per-step scratch (cleared on step change). */\n mem: Record<string, unknown>;\n /** Advance to the next plan step. */\n next(): void;\n /** Restart the current step (retry) \u2014 clears frames + mem. */\n retry(): void;\n}\n\nexport type StepExec<Step, Probe> = (step: Step, probe: Probe, out: string[], ctx: BotCtx) => void;\n\nexport interface PlanBot<Probe> {\n (probe: Probe): string[];\n stepIndex(): number;\n done(): boolean;\n}\n\nexport function createPlanBot<Step extends { kind: string }, Probe>(plan: Step[], execs: Record<string, StepExec<Step, Probe>>): PlanBot<Probe> {\n let i = 0;\n let frames = 0;\n let mem: Record<string, unknown> = {};\n\n const fn = (probe: Probe): string[] => {\n const out: string[] = [];\n const step = plan[i];\n if (!step) return out;\n frames++;\n const ctx: BotCtx = {\n get frames() {\n return frames;\n },\n mem,\n next() {\n i++;\n frames = 0;\n mem = {};\n },\n retry() {\n frames = 0;\n mem = {};\n },\n };\n const exec = execs[step.kind];\n if (!exec) throw new Error(`plan bot: no executor for step kind \"${step.kind}\"`);\n exec(step, probe, out, ctx);\n return out;\n };\n const bot = fn as PlanBot<Probe>;\n bot.stepIndex = () => i;\n bot.done = () => i >= plan.length;\n return bot;\n}\n\n/** Shared steering helper: 4/8-way movement toward a point. */\nexport function steer2D(px: number, py: number, tx: number, ty: number, out: string[], dead = 8): void {\n if (px < tx - dead) out.push('right');\n else if (px > tx + dead) out.push('left');\n if (py < ty - dead) out.push('down');\n else if (py > ty + dead) out.push('up');\n}\n", "// Feel probes (Channel 3): quality proxies computed from a per-frame probe\n// timeline. The harness cannot feel fun, but it can measure fun's precursors \u2014\n// time-to-first-meaningful-action, event cadence, difficulty ramp, input\n// decision density \u2014 and fail when a game drifts outside its tuned windows.\n// These are proxies, not proof: pair them with the filmstrip and a human-set\n// window per game (see docs/VERIFICATION.md \u00A7Channel 3).\n\nimport type { World } from '../world';\n\nexport type ProbeFrame = Record<string, unknown>;\n\n/**\n * Step a world through per-frame action arrays, probing after every step.\n * Returns frames.length + 1 probes: index 0 is the pre-step state, index i is\n * the state after frame i. (With the default 60Hz clock, index / 60 = sim\n * seconds.) For a segment-level timeline use scriptedPlaythrough instead.\n */\nexport function recordTimeline(world: World, frames: string[][]): ProbeFrame[] {\n const out: ProbeFrame[] = [world.probe()];\n for (const f of frames) {\n world.step(f);\n out.push(world.probe());\n }\n return out;\n}\n\n/** First timeline index where `pred` holds, or -1 if it never does. */\nexport function firstFrame(timeline: ProbeFrame[], pred: (p: ProbeFrame) => boolean): number {\n for (let i = 0; i < timeline.length; i++) if (pred(timeline[i])) return i;\n return -1;\n}\n\n/** The value of one probe key across the timeline. */\nexport function series(timeline: ProbeFrame[], key: string): unknown[] {\n return timeline.map((p) => p[key]);\n}\n\n/** Timeline indices where `key`'s value differs from the previous frame \u2014 an event cadence. */\nexport function changeFrames(timeline: ProbeFrame[], key: string): number[] {\n const out: number[] = [];\n for (let i = 1; i < timeline.length; i++) if (timeline[i][key] !== timeline[i - 1][key]) out.push(i);\n return out;\n}\n\n/** Monotonic within slack: 'up' means every value \u2265 previous \u2212 slack. */\nexport function isMonotonic(values: number[], dir: 'up' | 'down', slack = 0): boolean {\n for (let i = 1; i < values.length; i++) {\n if (dir === 'up' ? values[i] < values[i - 1] - slack : values[i] > values[i - 1] + slack) return false;\n }\n return true;\n}\n\n/**\n * Fraction of frames carrying at least one action \u2014 a crude engagement proxy.\n * Near 0 the player is waiting; near 1 they are mashing; a tuned game usually\n * lives somewhere in between (set the window per genre).\n */\nexport function inputDensity(frames: string[][]): number {\n if (frames.length === 0) return 0;\n return frames.filter((f) => f.length > 0).length / frames.length;\n}\n\n/** Largest gap (in frames) between consecutive events \u2014 dead-air detector. */\nexport function longestLull(eventFrames: number[], totalFrames: number): number {\n const pts = [0, ...eventFrames, totalFrames];\n let worst = 0;\n for (let i = 1; i < pts.length; i++) worst = Math.max(worst, pts[i] - pts[i - 1]);\n return worst;\n}\n", "// Filmstrip: sampled frames of a run composed into ONE SVG contact sheet, so\n// the \"judge looks from a headless screenshot\" step can see MOTION \u2014 pacing,\n// readability during play, layering under load \u2014 not a single posed frame.\n// Looks only, never correctness: state was already proven numerically.\n\nimport type { World } from '../world';\nimport { commandsToSVGInner } from '../render/svgString';\n\nexport interface FilmstripOptions {\n /** The game's view size (defineGame width/height). */\n width: number;\n height: number;\n background?: string;\n /** How many panels to sample across the run (default 12, min 2). */\n panels?: number;\n /** Panels per row (default 4). */\n cols?: number;\n /** Rendered width of one panel in px (default 320). */\n panelWidth?: number;\n}\n\n/**\n * Step `world` through per-frame actions, sampling evenly spaced panels\n * (always including the first and last frame), and return one standalone SVG.\n * Panel labels are frame numbers plus sim seconds at the 60Hz convention.\n */\nexport function renderFilmstrip(world: World, frames: string[][], opts: FilmstripOptions): string {\n const panels = Math.max(2, opts.panels ?? 12);\n const every = Math.max(1, Math.ceil(frames.length / (panels - 1)));\n const shots: { frame: number; inner: string }[] = [{ frame: 0, inner: commandsToSVGInner(world.render()) }];\n for (let i = 0; i < frames.length; i++) {\n world.step(frames[i]);\n if ((i + 1) % every === 0 || i === frames.length - 1) {\n shots.push({ frame: i + 1, inner: commandsToSVGInner(world.render()) });\n }\n }\n\n const cols = Math.max(1, opts.cols ?? 4);\n const pw = opts.panelWidth ?? 320;\n const ph = Math.round((pw * opts.height) / opts.width);\n const labelH = 18;\n const gap = 8;\n const cellW = pw + gap;\n const cellH = ph + labelH + gap;\n const rows = Math.ceil(shots.length / cols);\n const totalW = cols * cellW + gap;\n const totalH = rows * cellH + gap;\n const bg = opts.background ?? '#ffffff';\n\n const cells = shots\n .map((s, i) => {\n const x = gap + (i % cols) * cellW;\n const y = gap + Math.floor(i / cols) * cellH;\n return (\n `<g transform=\"translate(${x} ${y})\">` +\n `<svg width=\"${pw}\" height=\"${ph}\" viewBox=\"0 0 ${opts.width} ${opts.height}\">` +\n `<rect x=\"0\" y=\"0\" width=\"${opts.width}\" height=\"${opts.height}\" fill=\"${bg}\"/>` +\n s.inner +\n `</svg>` +\n `<rect x=\"0\" y=\"0\" width=\"${pw}\" height=\"${ph}\" fill=\"none\" stroke=\"#999\" stroke-width=\"1\"/>` +\n `<text x=\"${pw / 2}\" y=\"${ph + 13}\" font-size=\"11\" font-family=\"monospace\" text-anchor=\"middle\" fill=\"#555\">` +\n `f ${s.frame} \u00B7 ${(s.frame / 60).toFixed(1)}s</text>` +\n `</g>`\n );\n })\n .join('');\n\n return (\n `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 ${totalW} ${totalH}\" width=\"${totalW}\" height=\"${totalH}\">` +\n `<rect x=\"0\" y=\"0\" width=\"${totalW}\" height=\"${totalH}\" fill=\"#f4f4f2\"/>` +\n cells +\n `</svg>`\n );\n}\n", "// The World: the deterministic simulation container. Owns the root scene, the\n// rng, the clock, the input state, an event bus, and a resource table. Advancing\n// the world is `step()` \u2014 a pure function of (previous state, input frame).\n\nimport { Clock, type ClockConfig } from './core/clock';\nimport { EventBus } from './core/events';\nimport { hashValue } from './core/hash';\nimport { Rng } from './core/rng';\nimport { InputState } from './input/actions';\nimport { Node, resetNodeIds, type WorldContext } from './scene/node';\nimport { deserializeNode } from './scene/registry';\nimport type { Camera2D } from './scene/nodes';\nimport { IDENTITY, composeTransform, invertTransform, makeTransform, type Transform } from './core/math';\nimport type { DrawCommand } from './render/commands';\n\nexport interface WorldConfig {\n seed?: number;\n clock?: ClockConfig;\n /** Design-space dimensions (default 1280\u00D7720). */\n width?: number;\n height?: number;\n}\n\n/** Default engine event map; games extend it with their own keys. */\nexport interface CoreEvents {\n [key: string]: unknown;\n}\n\nexport class World implements WorldContext {\n readonly rng: Rng;\n readonly clock: Clock;\n readonly input = new InputState();\n readonly events = new EventBus<CoreEvents>();\n readonly resources = new Map<string, unknown>();\n /**\n * Canonical game state that lives OUTSIDE the scene tree (pure-sim structs,\n * controllers). Must be plain JSON-serializable data: it is included in\n * `hash()` and `snapshot()`, so hidden state here cannot escape determinism\n * checks the way ad-hoc module variables can.\n */\n state: Record<string, unknown> = {};\n readonly width: number;\n readonly height: number;\n\n root: Node;\n activeCamera: Camera2D | null = null;\n\n private seed: number;\n private freeQueue: Node[] = [];\n private started = false;\n\n constructor(config: WorldConfig = {}) {\n this.seed = config.seed ?? 1;\n this.rng = new Rng(this.seed);\n this.clock = new Clock(config.clock);\n this.width = config.width ?? 1280;\n this.height = config.height ?? 720;\n this.root = new Node({ name: 'root' });\n }\n\n get time(): number {\n return this.clock.simTimeSec;\n }\n get frame(): number {\n return this.clock.frame;\n }\n\n /** Replace the scene root, entering the tree. */\n setRoot(node: Node): void {\n if (this.root) this.root.exitTree();\n this.root = node;\n this.started = false;\n }\n\n requestFree(node: Node): void {\n this.freeQueue.push(node);\n }\n\n private ensureStarted(): void {\n if (!this.started) {\n this.root.enterTree(this);\n this.started = true;\n }\n }\n\n /**\n * Advance exactly one fixed step with the given actions held down.\n * This is THE deterministic transition \u2014 call it from Node or the browser loop.\n */\n step(actionsDown: Iterable<string> = []): void {\n this.ensureStarted();\n this.input.beginFrame(actionsDown);\n this.root.updateTree(this.clock.dt);\n this.flushFree();\n this.clock.tick();\n }\n\n /** Feed real elapsed ms; runs 0+ fixed steps. Returns steps run. */\n advance(realMs: number, actionsDown: Iterable<string> = []): number {\n const steps = this.clock.advance(realMs);\n for (let i = 0; i < steps; i++) this.step(actionsDown);\n return steps;\n }\n\n private flushFree(): void {\n if (this.freeQueue.length === 0) return;\n const q = this.freeQueue;\n this.freeQueue = [];\n for (const node of q) {\n node.exitTree();\n node.parent?.removeChild(node);\n if (this.activeCamera === node) this.activeCamera = null;\n }\n }\n\n // \u2500\u2500 Rendering \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n /** The view transform (inverse of the active camera), mapping world \u2192 screen. */\n viewTransform(): Transform {\n if (!this.activeCamera) return IDENTITY;\n const cam = this.activeCamera;\n // Center the camera in design space, apply zoom, then invert.\n const camWorld = cam.worldTransform();\n const centered = composeTransform(makeTransform({ x: this.width / 2, y: this.height / 2 }, 0, { x: cam.zoom, y: cam.zoom }), invertTransform(camWorld));\n return centered;\n }\n\n /** Project the whole scene to a display list (already camera-applied). */\n render(): DrawCommand[] {\n this.ensureStarted();\n const out: DrawCommand[] = [];\n this.root.collectDraw(out, this.viewTransform());\n return out;\n }\n\n // \u2500\u2500 Determinism & saves \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n /** Deterministic structural hash of the whole sim state. */\n hash(): string {\n return hashValue({\n seed: this.seed,\n rng: this.rng.getState(),\n clock: this.clock.getState(),\n input: this.input.getState(),\n state: this.state,\n tree: this.root.serialize(),\n });\n }\n\n /** Compact snapshot for undo/time-travel and saves. */\n snapshot(): WorldSnapshot {\n return {\n seed: this.seed,\n rng: this.rng.getState(),\n clock: this.clock.getState(),\n input: this.input.getState(),\n state: structuredClone(this.state),\n tree: this.root.serialize(),\n };\n }\n\n /** Restore a snapshot. Rebuilds the tree from data (behaviors are re-attached by scene code). */\n restore(snap: WorldSnapshot): void {\n this.seed = snap.seed;\n this.rng.setState(snap.rng);\n this.clock.setState(snap.clock);\n this.input.setState(snap.input);\n this.state = structuredClone(snap.state);\n resetNodeIds(1_000_000); // avoid id collisions with the live session\n this.setRoot(deserializeNode(snap.tree));\n this.ensureStarted();\n }\n\n /** A compact probe snapshot for the verification harness (override-friendly). */\n probe(): Record<string, unknown> {\n return {\n frame: this.frame,\n time: this.time,\n hash: this.hash(),\n nodes: this.root.query('Sprite').length + this.root.query('Text').length,\n };\n }\n}\n\nexport interface WorldSnapshot {\n seed: number;\n rng: ReturnType<Rng['getState']>;\n clock: ReturnType<Clock['getState']>;\n input: ReturnType<InputState['getState']>;\n state: Record<string, unknown>;\n tree: ReturnType<Node['serialize']>;\n}\n", "// The project system. A game is a data definition: dimensions, input map, and a\n// build() that constructs the initial scene tree. `createWorld` turns it into a\n// live deterministic World \u2014 used identically by the browser driver, the headless\n// runner, and every test. That symmetry is the whole point.\n\nimport { World } from '../world';\nimport type { Node } from '../scene/node';\nimport { DEFAULT_INPUT_MAP, type InputLog, type InputMap } from '../input/actions';\nimport type { ClockConfig } from '../core/clock';\n\nexport interface GameDefinition {\n title: string;\n width?: number;\n height?: number;\n seed?: number;\n background?: string;\n clock?: ClockConfig;\n inputMap?: InputMap;\n /** Build the initial scene tree for a fresh world. */\n build(world: World): Node;\n /** Optional compact probe snapshot for verification (defaults to World.probe). */\n probe?(world: World): Record<string, unknown>;\n}\n\n/** Identity + defaults. Kept as a function so games read `export default defineGame({\u2026})`. */\nexport function defineGame(def: GameDefinition): Required<Pick<GameDefinition, 'width' | 'height' | 'seed' | 'inputMap' | 'background'>> & GameDefinition {\n return {\n width: 1280,\n height: 720,\n seed: 1,\n background: '#f3ecdb',\n inputMap: DEFAULT_INPUT_MAP,\n ...def,\n };\n}\n\n/** Build a live, deterministic World from a game definition. No browser needed. */\nexport function createWorld(def: GameDefinition, seedOverride?: number): World {\n const world = new World({\n seed: seedOverride ?? def.seed ?? 1,\n width: def.width ?? 1280,\n height: def.height ?? 720,\n clock: def.clock,\n });\n world.setRoot(def.build(world));\n if (def.probe) {\n // Instance override shadows the prototype method.\n (world as unknown as { probe: () => Record<string, unknown> }).probe = () => def.probe!(world);\n }\n return world;\n}\n\n/** The input map a game uses (with defaults applied). */\nexport function gameInputMap(def: GameDefinition): InputMap {\n return def.inputMap ?? DEFAULT_INPUT_MAP;\n}\n\nexport interface HeadlessResult {\n world: World;\n hash: string;\n steps: number;\n}\n\n/**\n * Run a game to completion in Node with no host \u2014 play an input log (or zero\n * steps) and return the final world + state hash. This is what tests, the CI\n * verifier, and replays call. The browser is never involved.\n */\nexport function runHeadless(def: GameDefinition, inputLog?: InputLog): HeadlessResult {\n const world = createWorld(def);\n const frames = inputLog?.frames ?? [];\n for (const f of frames) world.step(f);\n return { world, hash: world.hash(), steps: frames.length };\n}\n", "// Browser driver: mounts a renderer, samples real input into the fixed-step\n// kernel, projects to the renderer each frame, and wires audio + the pause shell.\n// Wall-clock only feeds the accumulator (how many steps to run) \u2014 replays use the\n// input log, not wall time, so the sim stays deterministic.\n\nimport type { GameDefinition } from './game';\nimport { createWorld } from './game';\nimport { KeyboardSource } from '../input/source';\nimport { SvgRenderer } from '../render/svg';\nimport { Canvas2DRenderer } from '../render/canvas';\nimport type { Renderer } from '../render/renderer';\nimport { renderToSVGString } from '../render/svgString';\nimport { audio } from '../audio/audio';\nimport { settings } from '../ui/settings';\nimport { setOverlayHost } from '../ui/overlay';\nimport { Shell } from '../ui/shell';\nimport { installCapture, isCaptureMode } from '../verify/capture';\nimport type { World } from '../world';\n\nexport interface RunOptions {\n renderer?: 'svg' | 'canvas';\n /** Start the pause/settings shell (Esc). Default true. */\n shell?: boolean;\n onRestart?: () => void;\n}\n\nexport interface GameHandle {\n world: World;\n renderer: Renderer;\n /** The live input source \u2014 game UI calls input.press('action') for buttons. */\n input: KeyboardSource;\n stop(): void;\n restart(): void;\n}\n\nexport function runBrowser(def: GameDefinition, mount: HTMLElement, opts: RunOptions = {}): GameHandle {\n const width = def.width ?? 1280;\n const height = def.height ?? 720;\n const background = def.background ?? '#f3ecdb';\n\n let world = createWorld(def);\n const renderer: Renderer =\n opts.renderer === 'canvas'\n ? new Canvas2DRenderer({ width, height, background })\n : new SvgRenderer({ width, height, background });\n\n mount.style.position = mount.style.position || 'relative';\n renderer.mount?.(mount);\n setOverlayHost(mount);\n\n const input = new KeyboardSource(def.inputMap ?? {}, document);\n const capture = isCaptureMode();\n\n // Start audio on first user gesture (autoplay policy).\n const startAudio = () => {\n audio.start();\n const s = settings.get();\n audio.setVolumes(s);\n window.removeEventListener('pointerdown', startAudio);\n window.removeEventListener('keydown', startAudio);\n };\n window.addEventListener('pointerdown', startAudio);\n window.addEventListener('keydown', startAudio);\n\n const renderFrame = () => renderer.draw(world.render());\n const restart = () => {\n world = createWorld(def);\n renderFrame();\n };\n\n const shell =\n opts.shell === false\n ? null\n : new Shell({\n title: def.title,\n onRestart: opts.onRestart ?? restart,\n onPause: () => {},\n });\n\n let raf = 0;\n let last = performance.now();\n const loop = (now: number) => {\n const dt = now - last;\n last = now;\n if (!capture && !(shell?.isPaused)) {\n const steps = world.advance(dt, input.currentActions());\n if (steps > 0) input.clearPressed(); // virtual taps held until sampled\n }\n renderFrame();\n raf = requestAnimationFrame(loop);\n };\n raf = requestAnimationFrame(loop);\n\n const handle: GameHandle = {\n get world() {\n return world;\n },\n renderer,\n input,\n stop() {\n cancelAnimationFrame(raf);\n input.dispose();\n shell?.dispose();\n renderer.dispose?.();\n },\n restart,\n };\n\n if (capture) {\n installCapture({\n get world() {\n return world;\n },\n stepOnce: (actions = []) => {\n world.step(actions);\n renderFrame();\n },\n renderSVG: () => renderToSVGString(world.render(), width, height, background),\n setPaused: () => {},\n });\n }\n\n return handle;\n}\n", "// @hayao \u2014 the single public seam. Games and examples import ONLY from here.\n// Everything below the barrel is swappable; this file is the whole API surface,\n// greppable in one place (an AI-first invariant).\n\n// \u2500\u2500 core: the deterministic kernel \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport * from './core/math';\nexport * from './core/rng';\nexport * from './core/clock';\nexport * from './core/events';\nexport * from './core/hash';\n\n// \u2500\u2500 scene: the Godot-style node tree \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport * from './scene/node';\n// Node2D is an alias for Node \u2014 the base node already carries a 2D transform.\nexport { Node as Node2D } from './scene/node';\nexport * from './scene/nodes';\nexport * from './scene/tween';\nexport * from './scene/particles';\nexport * from './scene/registry';\n\n// \u2500\u2500 input: actions, sampling, record/replay \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport * from './input/actions';\nexport * from './input/source';\n\n// \u2500\u2500 physics: tilemaps, kinematic AABB, character controllers \u2500\u2500\u2500\u2500\nexport * from './physics/tilemap';\nexport * from './physics/aabb';\nexport * from './physics/platformer';\nexport * from './physics/spatialHash';\nexport * from './physics/raycast';\n\n// \u2500\u2500 render: display list + backends \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport * from './render/commands';\nexport * from './render/renderer';\nexport * from './render/svgString';\nexport * from './render/svg';\nexport * from './render/canvas';\nexport * from './render/headless';\n\n// \u2500\u2500 art: code-as-art helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport * from './art/palette';\nexport * from './art/shapes';\n\n// \u2500\u2500 audio \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport * from './audio/audio';\n\n// \u2500\u2500 ui: DOM overlays + shell + settings \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport * from './ui/overlay';\nexport * from './ui/settings';\nexport * from './ui/shell';\n\n// \u2500\u2500 verify: the AI-first harness \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport * from './verify/solver';\nexport * from './verify/determinism';\nexport * from './verify/playthrough';\nexport * from './verify/capture';\nexport * from './verify/driver';\nexport * from './verify/bot';\nexport * from './verify/feel';\nexport * from './verify/filmstrip';\n\n// \u2500\u2500 world + app \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport * from './world';\nexport * from './app/game';\nexport * from './app/browser';\n\n/** Engine version. */\nexport const VERSION = '0.1.0';\n"],
|
|
5
|
-
"mappings": ";AAQO,IAAM,OAAO,CAAC,IAAI,GAAG,IAAI,OAAa,EAAE,GAAG,EAAE;AAC7C,IAAM,OAAO,CAAC,GAAS,OAAmB,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,GAAG,EAAE,IAAI,EAAE,EAAE;AACvE,IAAM,OAAO,CAAC,GAAS,OAAmB,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,GAAG,EAAE,IAAI,EAAE,EAAE;AACvE,IAAM,SAAS,CAAC,GAAS,OAAqB,EAAE,GAAG,EAAE,IAAI,GAAG,GAAG,EAAE,IAAI,EAAE;AACvE,IAAM,OAAO,CAAC,GAAS,MAAoB,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE;AAC/D,IAAM,OAAO,CAAC,MAAoB,KAAK,MAAM,EAAE,GAAG,EAAE,CAAC;AACrD,IAAM,QAAQ,CAAC,GAAS,MAAoB,KAAK,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC;AAC3E,SAAS,MAAM,GAAe;AACnC,QAAM,IAAI,KAAK,CAAC;AAChB,SAAO,MAAM,IAAI,EAAE,GAAG,GAAG,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,GAAG,GAAG,EAAE,IAAI,EAAE;AAC7D;AAEO,IAAM,QAAQ,CAAC,GAAW,IAAY,OAAwB,IAAI,KAAK,KAAK,IAAI,KAAK,KAAK;AAC1F,IAAM,OAAO,CAAC,GAAW,GAAW,MAAsB,KAAK,IAAI,KAAK;AACxE,IAAM,UAAU,CAAC,GAAW,GAAW,MAAuB,MAAM,IAAI,KAAK,IAAI,MAAM,IAAI;AAC3F,IAAM,QAAQ,CAAC,GAAW,IAAY,IAAY,IAAY,OACnE,KAAK,IAAI,IAAI,QAAQ,IAAI,IAAI,CAAC,CAAC;AAE1B,IAAM,MAAM,KAAK,KAAK;AACtB,IAAM,UAAU,CAAC,MAAuB,IAAI,KAAK,KAAM;AACvD,IAAM,UAAU,CAAC,MAAuB,IAAI,MAAO,KAAK;AAUxD,SAAS,aAAa,GAAS,GAAkB;AACtD,SAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE;AACxE;AAEO,SAAS,aAAa,GAAS,GAAkB;AACtD,SAAO,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE;AAChF;AAYO,IAAM,WAAsB,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,EAAE;AAEjE,SAAS,iBAAiB,GAAcA,IAAyB;AACtE,SAAO;AAAA,IACL,GAAG,EAAE,IAAIA,GAAE,IAAI,EAAE,IAAIA,GAAE;AAAA,IACvB,GAAG,EAAE,IAAIA,GAAE,IAAI,EAAE,IAAIA,GAAE;AAAA,IACvB,GAAG,EAAE,IAAIA,GAAE,IAAI,EAAE,IAAIA,GAAE;AAAA,IACvB,GAAG,EAAE,IAAIA,GAAE,IAAI,EAAE,IAAIA,GAAE;AAAA,IACvB,GAAG,EAAE,IAAIA,GAAE,IAAI,EAAE,IAAIA,GAAE,IAAI,EAAE;AAAA,IAC7B,GAAG,EAAE,IAAIA,GAAE,IAAI,EAAE,IAAIA,GAAE,IAAI,EAAE;AAAA,EAC/B;AACF;AAGO,SAAS,cAAc,KAAW,UAAkB,OAAwB;AACjF,QAAM,MAAM,KAAK,IAAI,QAAQ;AAC7B,QAAM,MAAM,KAAK,IAAI,QAAQ;AAC7B,SAAO;AAAA,IACL,GAAG,MAAM,MAAM;AAAA,IACf,GAAG,MAAM,MAAM;AAAA,IACf,GAAG,CAAC,MAAM,MAAM;AAAA,IAChB,GAAG,MAAM,MAAM;AAAA,IACf,GAAG,IAAI;AAAA,IACP,GAAG,IAAI;AAAA,EACT;AACF;AAEO,SAAS,eAAe,GAAc,GAAe;AAC1D,SAAO,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE;AAC1E;AAGO,SAAS,gBAAgB,GAAyB;AACvD,QAAM,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE;AAChC,MAAI,QAAQ,EAAG,QAAO,EAAE,GAAG,SAAS;AACpC,QAAM,KAAK,IAAI;AACf,SAAO;AAAA,IACL,GAAG,EAAE,IAAI;AAAA,IACT,GAAG,CAAC,EAAE,IAAI;AAAA,IACV,GAAG,CAAC,EAAE,IAAI;AAAA,IACV,GAAG,EAAE,IAAI;AAAA,IACT,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK;AAAA,IAC7B,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK;AAAA,EAC/B;AACF;;;AChGA,SAAS,WAAW,MAA4B;AAC9C,MAAI,IAAI,SAAS;AACjB,SAAO,MAAM;AACX,QAAK,IAAI,eAAgB;AACzB,QAAI,IAAI;AACR,QAAI,KAAK,KAAK,IAAK,MAAM,IAAK,SAAU;AACxC,QAAI,KAAK,KAAK,IAAK,MAAM,IAAK,UAAU;AACxC,YAAQ,IAAK,MAAM,QAAS;AAAA,EAC9B;AACF;AAMO,IAAM,MAAN,MAAM,KAAI;AAAA,EACP;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAER,YAAY,OAA0B,GAAG;AACvC,QAAI,OAAO,SAAS,UAAU;AAC5B,YAAM,KAAK,WAAW,SAAS,IAAI,YAAa,IAAI;AACpD,WAAK,KAAK,GAAG;AACb,WAAK,KAAK,GAAG;AACb,WAAK,KAAK,GAAG;AACb,WAAK,KAAK,GAAG;AAAA,IACf,OAAO;AACL,OAAC,KAAK,IAAI,KAAK,IAAI,KAAK,IAAI,KAAK,EAAE,IAAI,KAAK;AAAA,IAC9C;AAAA,EACF;AAAA;AAAA,EAGQ,OAAe;AACrB,UAAM,SAAU,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM;AACtE,UAAM,IAAK,KAAK,MAAM,MAAO;AAC7B,SAAK,MAAM,KAAK;AAChB,SAAK,MAAM,KAAK;AAChB,SAAK,MAAM,KAAK;AAChB,SAAK,MAAM,KAAK;AAChB,SAAK,MAAM,KAAK,KAAK,OAAO;AAC5B,SAAK,KAAK,KAAK,KAAK,KAAK,IAAI,EAAE;AAC/B,WAAO,WAAW;AAAA,EACpB;AAAA,EAEQ,KAAK,GAAW,GAAmB;AACzC,YAAU,KAAK,IAAM,MAAO,KAAK,OAAS;AAAA,EAC5C;AAAA;AAAA,EAGA,QAAgB;AACd,WAAO,KAAK,KAAK,IAAI;AAAA,EACvB;AAAA;AAAA,EAGA,MAAM,IAAY,IAAoB;AACpC,WAAO,KAAK,KAAK,MAAM,KAAK,KAAK;AAAA,EACnC;AAAA;AAAA,EAGA,IAAIC,IAAmB;AACrB,WAAO,KAAK,MAAM,KAAK,MAAM,IAAIA,EAAC;AAAA,EACpC;AAAA;AAAA,EAGA,SAAS,IAAY,IAAoB;AACvC,WAAO,KAAK,KAAK,IAAI,KAAK,KAAK,CAAC;AAAA,EAClC;AAAA;AAAA,EAGA,OAAO,GAAoB;AACzB,WAAO,KAAK,MAAM,IAAI;AAAA,EACxB;AAAA;AAAA,EAGA,KAAQ,KAAsB;AAC5B,WAAO,IAAI,KAAK,IAAI,IAAI,MAAM,CAAC;AAAA,EACjC;AAAA;AAAA,EAGA,QAAW,KAAe;AACxB,aAAS,IAAI,IAAI,SAAS,GAAG,IAAI,GAAG,KAAK;AACvC,YAAM,IAAI,KAAK,IAAI,IAAI,CAAC;AACxB,OAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;AAAA,IACpC;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,MAAM,GAAQ;AAClB,UAAMC,QAAO,KAAK,KAAK,KAAK,KAAK,MAAM,GAAG,UAAU,OAAO;AAC3D,UAAM,QAAQ,IAAI,KAAIA,OAAM,KAAK,EAAE;AAEnC,SAAK,KAAK;AACV,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,WAAqB;AACnB,WAAO,EAAE,GAAG,CAAC,KAAK,IAAI,KAAK,IAAI,KAAK,IAAI,KAAK,EAAE,EAAE;AAAA,EACnD;AAAA,EACA,SAAS,OAAuB;AAC9B,KAAC,KAAK,IAAI,KAAK,IAAI,KAAK,IAAI,KAAK,EAAE,IAAI,MAAM;AAAA,EAC/C;AACF;AAGO,SAAS,WAAW,KAAqB;AAC9C,MAAI,IAAI,eAAe;AACvB,WAAS,IAAI,GAAG,IAAI,IAAI,QAAQ,KAAK;AACnC,SAAK,IAAI,WAAW,CAAC;AACrB,QAAI,KAAK,KAAK,GAAG,QAAQ;AAAA,EAC3B;AACA,SAAO,MAAM;AACf;;;AChHO,IAAM,QAAN,MAAY;AAAA,EACR;AAAA,EACA;AAAA;AAAA,EACD;AAAA,EACA,cAAc;AAAA,EACd,SAAS;AAAA,EACT,aAAa;AAAA,EAErB,YAAY,SAAsB,CAAC,GAAG;AACpC,UAAM,KAAK,OAAO,MAAM;AACxB,SAAK,SAAS,MAAO;AACrB,SAAK,KAAK,IAAI;AACd,SAAK,aAAa,OAAO,cAAc;AAAA,EACzC;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,QAAQ,QAAwB;AAC9B,SAAK,eAAe,KAAK,IAAI,QAAQ,KAAK,UAAU;AACpD,QAAI,QAAQ;AACZ,WAAO,KAAK,eAAe,KAAK,QAAQ;AACtC,WAAK,eAAe,KAAK;AACzB;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,OAAa;AACX,SAAK;AACL,SAAK,cAAc,KAAK;AAAA,EAC1B;AAAA;AAAA,EAGA,IAAI,QAAgB;AAClB,WAAO,KAAK,cAAc,KAAK;AAAA,EACjC;AAAA,EAEA,IAAI,QAAgB;AAClB,WAAO,KAAK;AAAA,EACd;AAAA,EACA,IAAI,YAAoB;AACtB,WAAO,KAAK;AAAA,EACd;AAAA,EACA,IAAI,aAAqB;AACvB,WAAO,KAAK,aAAa;AAAA,EAC3B;AAAA,EAEA,WAAW;AACT,WAAO,EAAE,aAAa,KAAK,aAAa,OAAO,KAAK,QAAQ,WAAW,KAAK,WAAW;AAAA,EACzF;AAAA,EACA,SAAS,GAAoE;AAC3E,SAAK,cAAc,EAAE;AACrB,SAAK,SAAS,EAAE;AAChB,SAAK,aAAa,EAAE;AAAA,EACtB;AACF;;;AChEO,IAAM,SAAN,MAAuB;AAAA,EACpB,YAA2B,CAAC;AAAA,EAEpC,QAAQ,IAA6B;AACnC,SAAK,UAAU,KAAK,EAAE;AACtB,WAAO,MAAM,KAAK,WAAW,EAAE;AAAA,EACjC;AAAA,EAEA,KAAK,IAA6B;AAChC,UAAM,MAAM,KAAK,QAAQ,CAAC,MAAM;AAC9B,UAAI;AACJ,SAAG,CAAC;AAAA,IACN,CAAC;AACD,WAAO;AAAA,EACT;AAAA,EAEA,WAAW,IAAuB;AAChC,UAAM,IAAI,KAAK,UAAU,QAAQ,EAAE;AACnC,QAAI,KAAK,EAAG,MAAK,UAAU,OAAO,GAAG,CAAC;AAAA,EACxC;AAAA,EAEA,KAAK,SAAkB;AAErB,eAAW,MAAM,KAAK,UAAU,MAAM,EAAG,IAAG,OAAO;AAAA,EACrD;AAAA,EAEA,IAAI,QAAgB;AAClB,WAAO,KAAK,UAAU;AAAA,EACxB;AAAA,EAEA,QAAc;AACZ,SAAK,UAAU,SAAS;AAAA,EAC1B;AACF;AAOO,IAAM,WAAN,MAAuD;AAAA,EACpD,UAAU,oBAAI,IAAmC;AAAA,EAEjD,UAAkC,KAA2B;AACnE,QAAI,IAAI,KAAK,QAAQ,IAAI,GAAG;AAC5B,QAAI,CAAC,GAAG;AACN,UAAI,IAAI,OAAgB;AACxB,WAAK,QAAQ,IAAI,KAAK,CAAC;AAAA,IACzB;AACA,WAAO;AAAA,EACT;AAAA,EAEA,GAA2B,KAAQ,IAAqC;AACtE,WAAO,KAAK,UAAU,GAAG,EAAE,QAAQ,EAAE;AAAA,EACvC;AAAA,EAEA,KAA6B,KAAQ,IAAqC;AACxE,WAAO,KAAK,UAAU,GAAG,EAAE,KAAK,EAAE;AAAA,EACpC;AAAA,EAEA,KAA6B,KAAQ,SAA0B;AAC7D,SAAK,UAAU,GAAG,EAAE,KAAK,OAAO;AAAA,EAClC;AAAA,EAEA,QAAc;AACZ,SAAK,QAAQ,MAAM;AAAA,EACrB;AACF;;;ACrEA,SAAS,gBAAgBC,IAAmB;AAC1C,MAAI,OAAO,MAAMA,EAAC,EAAG,QAAO;AAC5B,MAAIA,OAAM,SAAU,QAAO;AAC3B,MAAIA,OAAM,UAAW,QAAO;AAC5B,MAAIA,OAAM,EAAG,QAAO;AACpB,SAAOA,GAAE,SAAS;AACpB;AAOO,SAAS,UAAU,OAAwB;AAChD,MAAI,KAAK,eAAe;AACxB,MAAI,KAAK,eAAe;AACxB,QAAM,OAAO,CAAC,MAAc;AAC1B,aAAS,IAAI,GAAG,IAAI,EAAE,QAAQ,KAAK;AACjC,YAAM,IAAI,EAAE,WAAW,CAAC;AACxB,WAAK,KAAK,KAAK,KAAK,GAAG,QAAQ,MAAM;AACrC,WAAK,KAAK,KAAK,MAAO,KAAK,IAAM,MAAM,IAAK,UAAU,MAAM;AAAA,IAC9D;AAAA,EACF;AAEA,QAAM,OAAO,CAAC,MAAqB;AACjC,QAAI,MAAM,KAAM,QAAO,KAAK,GAAG;AAC/B,QAAI,MAAM,OAAW,QAAO,KAAK,GAAG;AACpC,YAAQ,OAAO,GAAG;AAAA,MAChB,KAAK;AACH,eAAO,KAAK,MAAM,gBAAgB,CAAC,CAAC;AAAA,MACtC,KAAK;AACH,eAAO,KAAK,IAAI,MAAM,GAAG;AAAA,MAC3B,KAAK;AACH,eAAO,KAAK,MAAM,CAAC;AAAA,MACrB,KAAK,UAAU;AACb,YAAI,MAAM,QAAQ,CAAC,GAAG;AACpB,eAAK,GAAG;AACR,qBAAW,MAAM,EAAG,MAAK,EAAE;AAC3B,eAAK,GAAG;AACR;AAAA,QACF;AACA,cAAM,MAAM;AACZ,cAAM,OAAO,OAAO,KAAK,GAAG,EAAE,KAAK;AACnC,aAAK,GAAG;AACR,mBAAW,KAAK,MAAM;AACpB,eAAK,IAAI,GAAG;AACZ,eAAK,IAAI,CAAC,CAAC;AAAA,QACb;AACA,aAAK,GAAG;AACR;AAAA,MACF;AAAA,MACA;AACE,aAAK,GAAG;AAAA,IACZ;AAAA,EACF;AAEA,OAAK,KAAK;AACV,QAAM,MAAM,CAACA,OAAcA,GAAE,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG;AACzD,SAAO,IAAI,EAAE,IAAI,IAAI,EAAE;AACzB;;;AC3BA,IAAI,cAAc;AAEX,SAAS,aAAa,QAAQ,GAAS;AAC5C,gBAAc;AAChB;AAWO,IAAM,OAAN,MAAW;AAAA,EACP;AAAA,EACT;AAAA;AAAA,EAES,OAAe;AAAA,EAExB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,WAAW;AAAA,EAEX,SAAsB;AAAA,EACb,WAAmB,CAAC;AAAA,EAC7B,QAA6B;AAAA;AAAA,EAG7B;AAAA,EAEQ,YAAwB,CAAC;AAAA,EACzB,UAAU,oBAAI,IAA6B;AAAA,EAC3C,SAAS;AAAA,EACT,SAAS;AAAA,EAEjB,YAAY,SAAqB,CAAC,GAAG;AACnC,SAAK,KAAK,IAAI,aAAa;AAC3B,SAAK,OAAO,OAAO,QAAQ,KAAK,YAAY;AAC5C,SAAK,MAAM,OAAO,MAAM,EAAE,GAAG,OAAO,IAAI,IAAI,EAAE,GAAG,GAAG,GAAG,EAAE;AACzD,SAAK,WAAW,OAAO,YAAY;AACnC,SAAK,QAAQ,OAAO,QAAQ,EAAE,GAAG,OAAO,MAAM,IAAI,EAAE,GAAG,GAAG,GAAG,EAAE;AAC/D,SAAK,IAAI,OAAO,KAAK;AACrB,SAAK,UAAU,OAAO,WAAW;AAAA,EACnC;AAAA;AAAA,EAGA,SAAyB,OAAa;AACpC,UAAM,SAAS;AACf,SAAK,SAAS,KAAK,KAAK;AACxB,QAAI,KAAK,SAAS,KAAK,OAAQ,OAAM,UAAU,KAAK,KAAK;AACzD,WAAO;AAAA,EACT;AAAA,EAEA,YAAY,OAAmB;AAC7B,UAAM,IAAI,KAAK,SAAS,QAAQ,KAAK;AACrC,QAAI,KAAK,GAAG;AACV,WAAK,SAAS,OAAO,GAAG,CAAC;AACzB,YAAM,SAAS;AAAA,IACjB;AAAA,EACF;AAAA;AAAA,EAGA,OAAa;AACX,SAAK,OAAO,YAAY,IAAI;AAAA,EAC9B;AAAA;AAAA,EAGA,KAAK,MAA2B;AAC9B,QAAI,KAAK,SAAS,KAAM,QAAO;AAC/B,eAAW,KAAK,KAAK,UAAU;AAC7B,YAAM,IAAI,EAAE,KAAK,IAAI;AACrB,UAAI,EAAG,QAAO;AAAA,IAChB;AACA,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,MAAM,MAAc,MAAc,CAAC,GAAW;AAC5C,QAAI,KAAK,SAAS,KAAM,KAAI,KAAK,IAAI;AACrC,eAAW,KAAK,KAAK,SAAU,GAAE,MAAM,MAAM,GAAG;AAChD,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,YAAY,GAAmB;AAC7B,SAAK,UAAU,KAAK,CAAC;AACrB,QAAI,KAAK,OAAQ,GAAE,QAAQ,IAAI;AAC/B,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,OAAiB,MAAyB;AACxC,QAAI,IAAI,KAAK,QAAQ,IAAI,IAAI;AAC7B,QAAI,CAAC,GAAG;AACN,UAAI,IAAI,OAAgB;AACxB,WAAK,QAAQ,IAAI,MAAM,CAAC;AAAA,IAC1B;AACA,WAAO;AAAA,EACT;AAAA,EACA,KAAQ,MAAc,SAAkB;AACtC,SAAK,QAAQ,IAAI,IAAI,GAAG,KAAK,OAAO;AAAA,EACtC;AAAA;AAAA,EAGA,UAAU,OAA2B;AACnC,SAAK,QAAQ;AACb,QAAI,CAAC,KAAK,QAAQ;AAChB,WAAK,SAAS;AACd,WAAK,QAAQ;AACb,iBAAW,KAAK,KAAK,UAAW,GAAE,QAAQ,IAAI;AAAA,IAChD;AACA,eAAW,KAAK,KAAK,SAAU,GAAE,UAAU,KAAK;AAAA,EAClD;AAAA,EAEA,WAAW,IAAkB;AAC3B,QAAI,KAAK,OAAQ;AACjB,eAAW,KAAK,KAAK,UAAW,GAAE,SAAS,MAAM,EAAE;AACnD,SAAK,WAAW,MAAM,EAAE;AACxB,SAAK,UAAU,EAAE;AAEjB,eAAW,KAAK,KAAK,SAAS,MAAM,EAAG,GAAE,WAAW,EAAE;AAAA,EACxD;AAAA,EAEA,WAAiB;AACf,eAAW,KAAK,KAAK,UAAW,GAAE,OAAO,IAAI;AAC7C,SAAK,OAAO;AACZ,eAAW,KAAK,KAAK,SAAS,MAAM,EAAG,GAAE,SAAS;AAClD,SAAK,SAAS;AAAA,EAChB;AAAA,EAEA,IAAI,UAAmB;AACrB,WAAO,KAAK;AAAA,EACd;AAAA;AAAA,EAGA,iBAA4B;AAC1B,WAAO,cAAc,KAAK,KAAK,KAAK,UAAU,KAAK,KAAK;AAAA,EAC1D;AAAA,EAEA,iBAA4B;AAC1B,UAAM,QAAQ,KAAK,eAAe;AAClC,WAAO,KAAK,SAAS,iBAAiB,KAAK,OAAO,eAAe,GAAG,KAAK,IAAI;AAAA,EAC/E;AAAA;AAAA;AAAA,EAIA,YAAY,KAAoB,cAAyB,UAAgB;AACvE,QAAI,CAAC,KAAK,QAAS;AACnB,UAAM,QAAQ,iBAAiB,aAAa,KAAK,eAAe,CAAC;AACjE,SAAK,KAAK,KAAK,KAAK;AACpB,eAAW,KAAK,KAAK,SAAU,GAAE,YAAY,KAAK,KAAK;AAAA,EACzD;AAAA;AAAA,EAGU,KAAK,MAAqB,QAAyB;AAAA,EAAC;AAAA;AAAA,EAGpD,UAAgB;AAAA,EAAC;AAAA,EACjB,UAAU,KAAmB;AAAA,EAAC;AAAA,EAC9B,SAAe;AAAA,EAAC;AAAA;AAAA,EAG1B,YAA4B;AAC1B,WAAO;AAAA,MACL,MAAM,KAAK;AAAA,MACX,MAAM,KAAK;AAAA,MACX,KAAK,EAAE,GAAG,KAAK,IAAI;AAAA,MACnB,UAAU,KAAK;AAAA,MACf,OAAO,EAAE,GAAG,KAAK,MAAM;AAAA,MACvB,GAAG,KAAK;AAAA,MACR,SAAS,KAAK;AAAA,MACd,OAAO,KAAK,eAAe;AAAA,MAC3B,UAAU,KAAK,SAAS,OAAO,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,MAAM,EAAE,UAAU,CAAC;AAAA,IAC7E;AAAA,EACF;AAAA;AAAA,EAEU,iBAA0C;AAClD,WAAO,CAAC;AAAA,EACV;AAAA;AAAA,EAEA,WAAW,QAAuC;AAAA,EAAC;AACrD;;;AC/MO,IAAM,SAAN,cAAqB,KAAK;AAAA,EACb,OAAO;AAAA,EACzB;AAAA,EACA;AAAA,EAEA,YAAY,QAAsB;AAChC,UAAM,MAAM;AACZ,SAAK,QAAQ,OAAO;AACpB,SAAK,QAAQ;AAAA,MACX,MAAM,OAAO;AAAA,MACb,QAAQ,OAAO;AAAA,MACf,aAAa,OAAO;AAAA,MACpB,SAAS,OAAO;AAAA,MAChB,OAAO,OAAO;AAAA,IAChB;AAAA,EACF;AAAA,EAEmB,KAAK,KAAoB,OAAwB;AAClE,UAAM,IAAI,KAAK;AACf,UAAM,OAAO,EAAE,WAAW,OAAO,GAAG,KAAK,GAAG,GAAG,EAAE;AACjD,YAAQ,KAAK,MAAM,MAAM;AAAA,MACvB,KAAK;AACH,YAAI,KAAK,EAAE,MAAM,QAAQ,GAAG,CAAC,KAAK,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,MAAM,IAAI,GAAG,GAAG,KAAK,MAAM,GAAG,GAAG,KAAK,MAAM,GAAG,GAAG,KAAK,MAAM,GAAG,GAAG,KAAK,CAAC;AACjI;AAAA,MACF,KAAK;AACH,YAAI,KAAK,EAAE,MAAM,UAAU,IAAI,GAAG,IAAI,GAAG,QAAQ,KAAK,MAAM,QAAQ,GAAG,KAAK,CAAC;AAC7E;AAAA,MACF,KAAK;AACH,YAAI,KAAK,EAAE,MAAM,QAAQ,QAAQ,KAAK,MAAM,QAAQ,QAAQ,KAAK,MAAM,UAAU,MAAM,GAAG,KAAK,CAAC;AAChG;AAAA,MACF,KAAK;AACH,YAAI,KAAK,EAAE,MAAM,QAAQ,GAAG,KAAK,MAAM,GAAG,GAAG,KAAK,CAAC;AACnD;AAAA,MACF,KAAK;AACH,YAAI,KAAK,EAAE,MAAM,QAAQ,MAAM,KAAK,MAAM,MAAM,GAAG,GAAG,GAAG,GAAG,MAAM,KAAK,MAAM,MAAM,OAAO,UAAU,GAAG,KAAK,CAAC;AAC7G;AAAA,IACJ;AAAA,EACF;AAAA,EAEmB,iBAA0C;AAC3D,WAAO,EAAE,OAAO,KAAK,OAAO,OAAO,KAAK,MAAM;AAAA,EAChD;AAAA,EACS,WAAW,OAAsC;AACxD,QAAI,MAAM,MAAO,MAAK,QAAQ,MAAM;AACpC,QAAI,MAAM,MAAO,MAAK,QAAQ,MAAM;AAAA,EACtC;AACF;AAWO,IAAM,OAAN,cAAmB,KAAK;AAAA,EACX,OAAO;AAAA,EACzB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEA,YAAY,QAAoB;AAC9B,UAAM,MAAM;AACZ,SAAK,OAAO,OAAO;AACnB,SAAK,OAAO,OAAO,QAAQ;AAC3B,SAAK,OAAO,OAAO;AACnB,SAAK,QAAQ,OAAO,SAAS;AAC7B,SAAK,SAAS,OAAO;AACrB,SAAK,QAAQ,EAAE,MAAM,OAAO,QAAQ,QAAQ,QAAQ,OAAO,QAAQ,aAAa,OAAO,aAAa,SAAS,OAAO,QAAQ;AAAA,EAC9H;AAAA,EAEmB,KAAK,KAAoB,OAAwB;AAClE,QAAI,KAAK;AAAA,MACP,MAAM;AAAA,MAAQ,MAAM,KAAK;AAAA,MAAM,GAAG;AAAA,MAAG,GAAG;AAAA,MAAG,MAAM,KAAK;AAAA,MAAM,MAAM,KAAK;AAAA,MACvE,OAAO,KAAK;AAAA,MAAO,QAAQ,KAAK;AAAA,MAAQ,WAAW;AAAA,MAAO,GAAG,KAAK;AAAA,MAAG,GAAG,KAAK;AAAA,IAC/E,CAAC;AAAA,EACH;AAAA,EAEmB,iBAA0C;AAC3D,WAAO,EAAE,MAAM,KAAK,MAAM,MAAM,KAAK,MAAM,OAAO,KAAK,OAAO,OAAO,KAAK,MAAM;AAAA,EAClF;AAAA,EACS,WAAW,OAAsC;AACxD,QAAI,OAAO,MAAM,SAAS,SAAU,MAAK,OAAO,MAAM;AACtD,QAAI,OAAO,MAAM,SAAS,SAAU,MAAK,OAAO,MAAM;AACtD,QAAI,MAAM,MAAO,MAAK,QAAQ,MAAM;AACpC,QAAI,MAAM,MAAO,MAAK,QAAQ,MAAM;AAAA,EACtC;AACF;AASO,IAAM,WAAN,cAAuB,KAAK;AAAA,EACf,OAAO;AAAA,EACzB;AAAA,EACA;AAAA,EAEA,YAAY,SAAuB,CAAC,GAAG;AACrC,UAAM,MAAM;AACZ,SAAK,OAAO,OAAO,QAAQ;AAC3B,SAAK,UAAU,OAAO,WAAW;AAAA,EACnC;AAAA,EAEmB,UAAgB;AACjC,QAAI,KAAK,QAAS,CAAC,KAAK,MAAqD,eAAe;AAAA,EAC9F;AAAA,EAEmB,iBAA0C;AAC3D,WAAO,EAAE,MAAM,KAAK,MAAM,SAAS,KAAK,QAAQ;AAAA,EAClD;AAAA,EACS,WAAW,OAAsC;AACxD,QAAI,OAAO,MAAM,SAAS,SAAU,MAAK,OAAO,MAAM;AACtD,QAAI,OAAO,MAAM,YAAY,UAAW,MAAK,UAAU,MAAM;AAAA,EAC/D;AACF;AASO,IAAM,QAAN,cAAoB,KAAK;AAAA,EACZ,OAAO;AAAA,EACzB;AAAA,EACA;AAAA,EACQ;AAAA,EACA;AAAA,EAER,YAAY,QAAqB;AAC/B,UAAM,MAAM;AACZ,SAAK,WAAW,OAAO;AACvB,SAAK,UAAU,OAAO,WAAW;AACjC,SAAK,YAAY,OAAO;AACxB,SAAK,UAAU,OAAO,aAAa;AAAA,EACrC;AAAA,EAEA,MAAM,UAAyB;AAC7B,QAAI,aAAa,OAAW,MAAK,WAAW;AAC5C,SAAK,YAAY,KAAK;AACtB,SAAK,UAAU;AAAA,EACjB;AAAA,EACA,OAAa;AACX,SAAK,UAAU;AAAA,EACjB;AAAA,EAEA,IAAI,WAAmB;AACrB,WAAO,KAAK;AAAA,EACd;AAAA,EAEmB,UAAU,IAAkB;AAC7C,QAAI,CAAC,KAAK,QAAS;AACnB,SAAK,aAAa;AAClB,QAAI,KAAK,aAAa,GAAG;AACvB,WAAK,KAAK,WAAW,MAAS;AAC9B,UAAI,KAAK,QAAS,MAAK,UAAU;AAAA,UAC5B,MAAK,aAAa,KAAK;AAAA,IAC9B;AAAA,EACF;AAAA;AAAA,EAGA,IAAI,UAAU;AACZ,WAAO,KAAK,OAAO,SAAS;AAAA,EAC9B;AAAA,EAEmB,iBAA0C;AAC3D,WAAO,EAAE,UAAU,KAAK,UAAU,SAAS,KAAK,SAAS,WAAW,KAAK,WAAW,SAAS,KAAK,QAAQ;AAAA,EAC5G;AAAA,EACS,WAAW,OAAsC;AACxD,QAAI,OAAO,MAAM,aAAa,SAAU,MAAK,WAAW,MAAM;AAC9D,QAAI,OAAO,MAAM,YAAY,UAAW,MAAK,UAAU,MAAM;AAC7D,QAAI,OAAO,MAAM,cAAc,SAAU,MAAK,YAAY,MAAM;AAChE,QAAI,OAAO,MAAM,YAAY,UAAW,MAAK,UAAU,MAAM;AAAA,EAC/D;AACF;;;ACnMA,IAAM,MAAM,KAAK;AACV,IAAM,UAAkC;AAAA,EAC7C,QAAQ,CAAC,MAAM;AAAA,EACf,QAAQ,CAAC,MAAM,IAAI;AAAA,EACnB,SAAS,CAAC,MAAM,KAAK,IAAI,MAAM,IAAI;AAAA,EACnC,WAAW,CAAC,MAAO,IAAI,MAAM,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,GAAG,CAAC,IAAI;AAAA,EAClE,SAAS,CAAC,MAAM,IAAI,IAAI;AAAA,EACxB,UAAU,CAAC,MAAM,IAAI,IAAI,IAAI,GAAG,CAAC;AAAA,EACjC,YAAY,CAAC,MAAO,IAAI,MAAM,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,GAAG,CAAC,IAAI;AAAA,EACvE,QAAQ,CAAC,MAAM,IAAI,KAAK,IAAK,IAAI,KAAK,KAAM,CAAC;AAAA,EAC7C,SAAS,CAAC,MAAM,KAAK,IAAK,IAAI,KAAK,KAAM,CAAC;AAAA,EAC1C,WAAW,CAAC,MAAM,EAAE,KAAK,IAAI,KAAK,KAAK,CAAC,IAAI,KAAK;AAAA,EACjD,SAAS,CAAC,MAAM;AACd,UAAM,KAAK;AACX,UAAM,KAAK,KAAK;AAChB,WAAO,IAAI,KAAK,IAAI,IAAI,GAAG,CAAC,IAAI,KAAK,IAAI,IAAI,GAAG,CAAC;AAAA,EACnD;AAAA,EACA,YAAY,CAAC,MAAM;AACjB,UAAM,KAAM,IAAI,KAAK,KAAM;AAC3B,WAAO,MAAM,IAAI,IAAI,MAAM,IAAI,IAAI,IAAI,GAAG,MAAM,CAAC,IAAI,KAAK,KAAK,IAAI,KAAK,QAAQ,EAAE,IAAI;AAAA,EACxF;AAAA,EACA,WAAW,CAAC,MAAM;AAChB,UAAM,KAAK;AACX,UAAM,KAAK;AACX,QAAI,IAAI,IAAI,GAAI,QAAO,KAAK,IAAI;AAChC,QAAI,IAAI,IAAI,GAAI,QAAO,MAAM,KAAK,MAAM,MAAM,IAAI;AAClD,QAAI,IAAI,MAAM,GAAI,QAAO,MAAM,KAAK,OAAO,MAAM,IAAI;AACrD,WAAO,MAAM,KAAK,QAAQ,MAAM,IAAI;AAAA,EACtC;AACF;AAcO,IAAM,kBAAN,cAA8B,KAAK;AAAA,EACtB,OAAO;AAAA,EACjB,SAAkB,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA,EAM3B,GACE,OACA,MACA,IACA,UACA,OAAsC,YACtC,OAAgD,CAAC,GAC3C;AACN,SAAK,OAAO,KAAK;AAAA,MACf;AAAA,MACA;AAAA,MACA;AAAA,MACA,UAAU,KAAK,IAAI,MAAM,QAAQ;AAAA,MACjC,SAAS;AAAA,MACT,MAAM,OAAO,SAAS,aAAa,OAAO,QAAQ,IAAI,KAAK,QAAQ;AAAA,MACnE,OAAO,KAAK,SAAS;AAAA,MACrB,QAAQ,KAAK;AAAA,IACf,CAAC;AACD,WAAO;AAAA,EACT;AAAA,EAEA,IAAI,SAAkB;AACpB,WAAO,KAAK,OAAO,SAAS;AAAA,EAC9B;AAAA;AAAA,EAGA,IAAI,WAAW;AACb,WAAO,KAAK,OAAO,UAAU;AAAA,EAC/B;AAAA,EAEmB,UAAU,IAAkB;AAC7C,QAAI,KAAK,OAAO,WAAW,EAAG;AAC9B,aAAS,IAAI,KAAK,OAAO,SAAS,GAAG,KAAK,GAAG,KAAK;AAChD,YAAM,KAAK,KAAK,OAAO,CAAC;AACxB,UAAI,GAAG,QAAQ,GAAG;AAChB,WAAG,SAAS;AACZ;AAAA,MACF;AACA,SAAG,WAAW;AACd,YAAM,IAAI,MAAM,GAAG,UAAU,GAAG,UAAU,GAAG,CAAC;AAC9C,SAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,GAAG,QAAQ,GAAG,KAAK,CAAC,CAAC;AACjD,UAAI,KAAK,GAAG;AACV,WAAG,SAAS;AACZ,aAAK,OAAO,OAAO,GAAG,CAAC;AAAA,MACzB;AAAA,IACF;AACA,QAAI,KAAK,OAAO,WAAW,EAAG,MAAK,KAAK,YAAY,MAAS;AAAA,EAC/D;AACF;;;AC3DO,IAAM,YAAN,cAAwB,KAAK;AAAA,EAChB,OAAe;AAAA,EACzB,OAAmB,CAAC;AAAA,EACpB;AAAA;AAAA,EAER;AAAA,EAEA,YAAY,SAAgE,CAAC,GAAG;AAC9E,UAAM,MAAM;AACZ,SAAK,WAAW;AAChB,SAAK,MAAM,IAAI,IAAI,OAAO,QAAQ,CAAC;AACnC,SAAK,eAAe,OAAO,gBAAgB;AAAA,EAC7C;AAAA;AAAA,EAGA,MAAM,OAAe,IAAU,OAA4B;AACzD,UAAM,IAAI,KAAK;AACf,aAAS,IAAI,GAAG,IAAI,OAAO,KAAK;AAC9B,YAAM,QAAQ,MAAM,UAAU,SAAY,MAAM,SAAS,EAAE,MAAM,IAAI,QAAQ,MAAM,UAAU,OAAO,EAAE,MAAM,IAAI;AAChH,YAAM,QAAQ,MAAM,WAAW,EAAE,MAAM,KAAK,MAAM,WAAW,MAAM;AACnE,YAAM,IAAc;AAAA,QAClB,GAAG,GAAG;AAAA,QACN,GAAG,GAAG;AAAA,QACN,IAAI,KAAK,IAAI,KAAK,IAAI;AAAA,QACtB,IAAI,KAAK,IAAI,KAAK,IAAI;AAAA,QACtB,MAAM;AAAA,QACN,SAAS,MAAM,UAAU,EAAE,MAAM,KAAK,MAAM,UAAU,MAAM;AAAA,QAC5D,MAAM,MAAM,UAAU,EAAE,MAAM,KAAK,MAAM,UAAU,MAAM;AAAA,QACzD,OAAO,MAAM,OAAO,EAAE,IAAI,MAAM,OAAO,MAAM,CAAC;AAAA,MAChD;AACA,UAAI,KAAK,KAAK,UAAU,KAAK,aAAc,MAAK,KAAK,MAAM;AAC3D,WAAK,KAAK,KAAK,CAAC;AAAA,IAClB;AAGA,SAAK,UAAU,MAAM,WAAW;AAChC,SAAK,OAAO,MAAM,QAAQ;AAC1B,SAAK,SAAS,MAAM,UAAU;AAAA,EAChC;AAAA,EAEQ,UAAU;AAAA,EACV,OAAO;AAAA,EACP,SAAS;AAAA,EAEE,UAAU,IAAkB;AAC7C,UAAM,OAAO,KAAK,IAAI,GAAG,IAAI,KAAK,OAAO,EAAE;AAC3C,QAAI,QAAQ;AACZ,eAAW,KAAK,KAAK,MAAM;AACzB,QAAE,QAAQ;AACV,UAAI,EAAE,QAAQ,EAAE,QAAS;AACzB,QAAE,MAAM,KAAK,UAAU;AACvB,QAAE,MAAM;AACR,QAAE,MAAM;AACR,QAAE,KAAK,EAAE,KAAK;AACd,QAAE,KAAK,EAAE,KAAK;AACd,WAAK,KAAK,OAAO,IAAI;AAAA,IACvB;AACA,SAAK,KAAK,SAAS;AAAA,EACrB;AAAA,EAEmB,KAAK,KAAoB,OAAwB;AAClE,eAAW,KAAK,KAAK,MAAM;AACzB,YAAM,IAAI,IAAI,EAAE,OAAO,EAAE;AACzB,UAAI,KAAK;AAAA,QACP,MAAM;AAAA,QACN,IAAI,EAAE;AAAA,QACN,IAAI,EAAE;AAAA,QACN,QAAQ,KAAK,SAAS,EAAE,OAAO,IAAI,EAAE;AAAA,QACrC,MAAM,EAAE;AAAA,QACR,SAAS,KAAK,IAAI,GAAG,IAAI,CAAC;AAAA,QAC1B,WAAW;AAAA,QACX,GAAG,KAAK;AAAA,MACV,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEA,IAAI,YAAoB;AACtB,WAAO,KAAK,KAAK;AAAA,EACnB;AACF;AAGO,IAAM,mBAAmB;AAAA,EAC9B,MAAM,CAAC,SAAS,CAAC,WAAW,SAAS,OAAsB,EAAE,QAAQ,SAAS,GAAG,SAAS,GAAG,UAAU,IAAI,UAAU,IAAI,SAAS,KAAK,SAAS,MAAM,SAAS,KAAK,MAAM,GAAG,QAAQ,KAAK;AAAA,EAC1L,OAAO,CAAC,SAAS,CAAC,WAAW,WAAW,SAAS,OAAsB,EAAE,QAAQ,SAAS,GAAG,SAAS,GAAG,UAAU,KAAK,UAAU,KAAK,SAAS,MAAM,SAAS,KAAK,MAAM,GAAG,QAAQ,KAAK;AAAA,EAC1L,KAAK,CAAC,SAAS,CAAC,WAAW,SAAS,OAAsB,EAAE,QAAQ,SAAS,GAAG,SAAS,GAAG,UAAU,KAAK,UAAU,KAAK,SAAS,MAAM,SAAS,MAAM,MAAM,GAAG,QAAQ,KAAK;AAAA,EAC9K,SAAS,CAAC,SAAS,CAAC,WAAW,WAAW,SAAS,OAAsB,EAAE,QAAQ,SAAS,KAAK,SAAS,KAAK,UAAU,IAAI,UAAU,IAAI,SAAS,KAAK,SAAS,KAAK,SAAS,KAAK,MAAM,GAAG,QAAQ,KAAK;AAC7M;AAQO,IAAM,SAAN,cAAqB,KAAK;AAAA,EACb,OAAe;AAAA,EACzB;AAAA,EACA,SAAS;AAAA;AAAA,EAEjB;AAAA;AAAA,EAEA;AAAA,EAEA,YAAY,SAA6E,CAAC,GAAG;AAC3F,UAAM,MAAM;AACZ,SAAK,WAAW;AAChB,SAAK,MAAM,IAAI,IAAI,OAAO,QAAQ,EAAE;AACpC,SAAK,YAAY,OAAO,aAAa;AACrC,SAAK,QAAQ,OAAO,SAAS;AAAA,EAC/B;AAAA;AAAA,EAGA,UAAU,QAAsB;AAC9B,SAAK,SAAS,KAAK,IAAI,GAAG,KAAK,SAAS,MAAM;AAAA,EAChD;AAAA,EAEmB,UAAU,IAAkB;AAC7C,SAAK,SAAS,KAAK,IAAI,GAAG,KAAK,SAAS,KAAK,QAAQ,EAAE;AACvD,UAAM,IAAI,KAAK,SAAS,KAAK,SAAS,KAAK;AAC3C,SAAK,IAAI,KAAK,KAAK,IAAI,MAAM,IAAI,IAAI,KAAK;AAC1C,SAAK,IAAI,KAAK,KAAK,IAAI,MAAM,IAAI,IAAI,KAAK;AAAA,EAC5C;AACF;;;AClKA,IAAM,WAAW,oBAAI,IAAyB;AAEvC,SAAS,aAAa,MAAc,SAA4B;AACrE,WAAS,IAAI,MAAM,OAAO;AAC5B;AAIA,aAAa,QAAQ,MAAM,IAAI,KAAK,CAAC;AACrC,aAAa,UAAU,MAAM,IAAI,OAAO,EAAE,OAAO,EAAE,MAAM,QAAQ,GAAG,GAAG,GAAG,EAAE,EAAE,CAAC,CAAC;AAChF,aAAa,QAAQ,MAAM,IAAI,KAAK,EAAE,MAAM,GAAG,CAAC,CAAC;AACjD,aAAa,YAAY,MAAM,IAAI,SAAS,CAAC;AAC7C,aAAa,SAAS,MAAM,IAAI,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC;AACtD,aAAa,mBAAmB,MAAM,IAAI,gBAAgB,CAAC;AAGpD,SAAS,gBAAgB,MAA4B;AAC1D,QAAM,UAAU,SAAS,IAAI,KAAK,IAAI;AACtC,MAAI,CAAC,QAAS,OAAM,IAAI,MAAM,6BAA6B,KAAK,IAAI,uBAAuB;AAC3F,QAAM,OAAO,QAAQ;AACrB,OAAK,OAAO,KAAK;AACjB,OAAK,MAAM,EAAE,GAAG,KAAK,IAAI;AACzB,OAAK,WAAW,KAAK;AACrB,OAAK,QAAQ,EAAE,GAAG,KAAK,MAAM;AAC7B,OAAK,IAAI,KAAK;AACd,OAAK,UAAU,KAAK;AACpB,OAAK,WAAW,KAAK,KAAK;AAC1B,aAAW,SAAS,KAAK,SAAU,MAAK,SAAS,gBAAgB,KAAK,CAAC;AACvE,SAAO;AACT;;;AChCO,IAAM,aAAN,MAAiB;AAAA,EACd,OAAO,oBAAI,IAAY;AAAA,EACvB,OAAO,oBAAI,IAAY;AAAA;AAAA,EAEtB,OAAO,oBAAI,IAAoB;AAAA;AAAA,EAGxC,WAAW,aAAqC;AAC9C,SAAK,OAAO,IAAI,IAAI,KAAK,IAAI;AAC7B,SAAK,OAAO,IAAI,IAAI,WAAW;AAAA,EACjC;AAAA,EAEA,OAAO,QAAyB;AAC9B,WAAO,KAAK,KAAK,IAAI,MAAM;AAAA,EAC7B;AAAA,EACA,YAAY,QAAyB;AACnC,WAAO,KAAK,KAAK,IAAI,MAAM,KAAK,CAAC,KAAK,KAAK,IAAI,MAAM;AAAA,EACvD;AAAA,EACA,aAAa,QAAyB;AACpC,WAAO,CAAC,KAAK,KAAK,IAAI,MAAM,KAAK,KAAK,KAAK,IAAI,MAAM;AAAA,EACvD;AAAA,EACA,KAAK,MAAsB;AACzB,WAAO,KAAK,KAAK,IAAI,IAAI,KAAK;AAAA,EAChC;AAAA;AAAA,EAGA,WAAqB;AACnB,WAAO,CAAC,GAAG,KAAK,IAAI,EAAE,KAAK;AAAA,EAC7B;AAAA,EAEA,WAAW;AACT,WAAO,EAAE,MAAM,CAAC,GAAG,KAAK,IAAI,EAAE,KAAK,GAAG,MAAM,CAAC,GAAG,KAAK,IAAI,EAAE,KAAK,EAAE;AAAA,EACpE;AAAA,EACA,SAAS,GAA6C;AACpD,SAAK,OAAO,IAAI,IAAI,EAAE,IAAI;AAC1B,SAAK,OAAO,IAAI,IAAI,EAAE,IAAI;AAAA,EAC5B;AACF;AAGO,SAAS,cAAc,KAAe,UAAiC;AAC5E,QAAM,UAAoB,CAAC;AAC3B,aAAW,UAAU,KAAK;AACxB,QAAI,IAAI,MAAM,EAAE,KAAK,CAAC,MAAM,SAAS,IAAI,CAAC,CAAC,EAAG,SAAQ,KAAK,MAAM;AAAA,EACnE;AACA,SAAO,QAAQ,KAAK;AACtB;AAGO,IAAM,gBAAN,MAAoB;AAAA,EACjB,SAAqB,CAAC;AAAA,EAE9B,OAAO,aAA6B;AAClC,SAAK,OAAO,KAAK,YAAY,MAAM,EAAE,KAAK,CAAC;AAAA,EAC7C;AAAA,EAEA,IAAI,SAAiB;AACnB,WAAO,KAAK,OAAO;AAAA,EACrB;AAAA,EAEA,QAAkB;AAChB,WAAO,EAAE,QAAQ,KAAK,OAAO,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE;AAAA,EACrD;AACF;AAOO,SAAS,aAAa,KAAe,GAAqB;AAC/D,SAAO,IAAI,OAAO,CAAC,KAAK,CAAC;AAC3B;AAGO,IAAM,oBAA8B;AAAA,EACzC,IAAI,CAAC,WAAW,MAAM;AAAA,EACtB,MAAM,CAAC,aAAa,MAAM;AAAA,EAC1B,MAAM,CAAC,aAAa,MAAM;AAAA,EAC1B,OAAO,CAAC,cAAc,MAAM;AAAA,EAC5B,SAAS,CAAC,SAAS,OAAO;AAAA,EAC1B,QAAQ,CAAC,UAAU,WAAW;AAAA,EAC9B,QAAQ,CAAC,QAAQ,MAAM;AAAA,EACvB,SAAS,CAAC,QAAQ,MAAM;AAAA,EACxB,MAAM,CAAC,MAAM;AAAA,EACb,SAAS,CAAC,MAAM;AAClB;;;ACxFO,IAAM,iBAAN,MAAqB;AAAA,EAClB,WAAW,oBAAI,IAAY;AAAA;AAAA,EAE3B,UAAU,oBAAI,IAAY;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAER,YAAY,KAAe,SAAiC,UAAU;AACpE,SAAK,MAAM;AACX,SAAK,SAAS;AACd,SAAK,SAAS,CAAC,MAAM;AACnB,WAAK,SAAS,IAAI,EAAE,IAAI;AAExB,UAAI,EAAE,KAAK,WAAW,OAAO,KAAK,EAAE,SAAS,QAAS,GAAE,eAAe;AAAA,IACzE;AACA,SAAK,OAAO,CAAC,MAAM,KAAK,SAAS,OAAO,EAAE,IAAI;AAC9C,SAAK,SAAS,MAAM,KAAK,SAAS,MAAM;AACxC,WAAO,iBAAiB,WAAW,KAAK,MAAuB;AAC/D,WAAO,iBAAiB,SAAS,KAAK,IAAqB;AAC3D,eAAW,mBAAmB,QAAQ,KAAK,MAAM;AAAA,EACnD;AAAA;AAAA,EAGA,iBAA2B;AACzB,UAAM,OAAO,cAAc,KAAK,KAAK,KAAK,QAAQ;AAClD,QAAI,KAAK,QAAQ,SAAS,EAAG,QAAO;AACpC,UAAM,SAAS,IAAI,IAAI,IAAI;AAC3B,eAAW,KAAK,KAAK,QAAS,QAAO,IAAI,CAAC;AAC1C,WAAO,CAAC,GAAG,MAAM,EAAE,KAAK;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,QAAsB;AAC1B,SAAK,QAAQ,IAAI,MAAM;AAAA,EACzB;AAAA;AAAA,EAGA,eAAqB;AACnB,SAAK,QAAQ,MAAM;AAAA,EACrB;AAAA,EAEA,OAAO,KAAqB;AAC1B,SAAK,MAAM;AAAA,EACb;AAAA,EAEA,UAAgB;AACd,SAAK,OAAO,oBAAoB,WAAW,KAAK,MAAuB;AACvE,SAAK,OAAO,oBAAoB,SAAS,KAAK,IAAqB;AACnE,eAAW,sBAAsB,QAAQ,KAAK,MAAM;AAAA,EACtD;AACF;;;AC5DO,IAAM,OAAO;AAAA,EAClB,OAAO;AAAA,EACP,OAAO;AAAA;AAAA,EAEP,QAAQ;AAAA,EACR,QAAQ;AACV;AAcO,IAAM,qBAA6C;AAAA,EACxD,KAAK,KAAK;AAAA,EACV,KAAK,KAAK;AAAA,EACV,KAAK,KAAK;AACZ;AAOO,SAAS,iBAAiB,WAAqB,WAAW,IAAI,QAAgC,oBAAiC;AACpI,QAAM,OAAO,UAAU;AACvB,QAAM,OAAO,KAAK,IAAI,GAAG,UAAU,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC;AACvD,QAAM,QAAQ,IAAI,MAAc,OAAO,IAAI,EAAE,KAAK,KAAK,KAAK;AAC5D,YAAU,QAAQ,CAAC,KAAK,OAAO;AAC7B,aAAS,KAAK,GAAG,KAAK,IAAI,QAAQ,KAAM,OAAM,KAAK,OAAO,EAAE,IAAI,MAAM,IAAI,EAAE,CAAC,KAAK,KAAK;AAAA,EACzF,CAAC;AACD,SAAO,EAAE,MAAM,MAAM,UAAU,MAAM;AACvC;AAGO,SAAS,cAAc,WAAqB,WAAW,IAAI,QAAgC,oBAAsF;AACtL,QAAM,MAAwE,CAAC;AAC/E,YAAU,QAAQ,CAAC,KAAK,OAAO;AAC7B,aAAS,KAAK,GAAG,KAAK,IAAI,QAAQ,MAAM;AACtC,YAAM,IAAI,IAAI,EAAE;AAChB,UAAI,MAAM,OAAO,MAAM,OAAO,MAAM,CAAC,MAAM,OAAW;AACtD,UAAI,KAAK,EAAE,MAAM,GAAG,IAAI,IAAI,IAAI,KAAK,OAAO,UAAU,IAAI,KAAK,OAAO,SAAS,CAAC;AAAA,IAClF;AAAA,EACF,CAAC;AACD,SAAO;AACT;AAGO,SAAS,OAAO,KAAkB,IAAY,IAAoB;AACvE,MAAI,KAAK,KAAK,KAAK,KAAK,MAAM,IAAI,QAAQ,MAAM,IAAI,KAAM,QAAO,KAAK;AACtE,SAAO,IAAI,MAAM,KAAK,IAAI,OAAO,EAAE;AACrC;AAEO,SAAS,YAAY,KAAkB,GAAW,GAAmB;AAC1E,SAAO,OAAO,KAAK,KAAK,MAAM,IAAI,IAAI,QAAQ,GAAG,KAAK,MAAM,IAAI,IAAI,QAAQ,CAAC;AAC/E;AAEO,IAAM,WAAW,CAAC,QAA6B,IAAI,OAAO,IAAI;AAC9D,IAAM,YAAY,CAAC,QAA6B,IAAI,OAAO,IAAI;;;AC7DtE,IAAM,MAAM;AAuBZ,IAAM,YAAY,CAAC,IAAY,IAAY,OAAiC,CAAC,KAAK,MAAM,KAAK,EAAE,GAAG,KAAK,OAAO,KAAK,OAAO,EAAE,CAAC;AAStH,SAAS,YAAY,KAAkB,GAAW,GAAW,GAAW,GAAW,SAAsB,CAAC,GAAY;AAC3H,QAAM,KAAK,IAAI;AACf,QAAM,CAAC,KAAK,GAAG,IAAI,UAAU,GAAG,IAAI,GAAG,EAAE;AACzC,QAAM,CAAC,KAAK,GAAG,IAAI,UAAU,GAAG,IAAI,GAAG,EAAE;AACzC,WAAS,KAAK,KAAK,MAAM,KAAK;AAC5B,aAAS,KAAK,KAAK,MAAM,KAAK,KAAM,KAAI,OAAO,KAAK,IAAI,EAAE,MAAM,KAAK,MAAO,QAAO;AACrF,aAAW,KAAK,QAAQ;AACtB,QAAI,EAAE,OAAQ;AACd,QAAI,IAAI,EAAE,IAAI,EAAE,IAAI,OAAO,IAAI,IAAI,EAAE,IAAI,OAAO,IAAI,EAAE,IAAI,EAAE,IAAI,OAAO,IAAI,IAAI,EAAE,IAAI,IAAK,QAAO;AAAA,EACnG;AACA,SAAO;AACT;AAMO,SAAS,SAAS,KAAkB,MAAY,IAAY,IAAY,OAAiB,CAAC,GAAe;AAC9G,QAAM,KAAK,IAAI;AACf,QAAM,SAAS,KAAK,UAAU,CAAC;AAC/B,MAAI,EAAE,GAAG,EAAE,IAAI;AACf,QAAM,EAAE,GAAG,EAAE,IAAI;AACjB,MAAI,OAAO;AACX,MAAI,OAAO;AACX,MAAI,aAAa;AACjB,MAAI,cAAc;AAGlB,MAAI,OAAO,GAAG;AACZ,UAAM,CAAC,KAAK,GAAG,IAAI,UAAU,GAAG,IAAI,GAAG,EAAE;AACzC,QAAI,KAAK,GAAG;AACV,UAAI,QAAQ,IAAI;AAChB,YAAM,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,OAAO,IAAI,KAAK,EAAE,GAAG,KAAK,OAAO,IAAI,IAAI,KAAK,OAAO,EAAE,CAAC;AAC/E,eAAS,KAAK,IAAI,MAAM,IAAI;AAC1B,iBAAS,KAAK,KAAK,MAAM,KAAK;AAC5B,cAAI,OAAO,KAAK,IAAI,EAAE,MAAM,KAAK,MAAO,SAAQ,KAAK,IAAI,OAAO,KAAK,KAAK,CAAC;AAC/E,iBAAW,KAAK;AACd,YAAI,CAAC,EAAE,UAAU,EAAE,IAAI,IAAI,IAAI,OAAO,EAAE,IAAI,EAAE,IAAI,IAAI,OAAO,EAAE,KAAK,IAAI,IAAI,IAAK,SAAQ,KAAK,IAAI,OAAO,EAAE,IAAI,CAAC;AAClH,UAAI,QAAQ,IAAI,KAAK,KAAK;AACxB,eAAO;AACP,sBAAc;AAAA,MAChB;AACA,UAAI,KAAK,IAAI,IAAI,IAAI,KAAK;AAAA,IAC5B,OAAO;AACL,UAAI,QAAQ,IAAI;AAChB,YAAM,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,OAAO,IAAI,OAAO,EAAE,GAAG,KAAK,OAAO,IAAI,MAAM,EAAE,CAAC;AACvE,eAAS,KAAK,IAAI,MAAM,IAAI;AAC1B,iBAAS,KAAK,KAAK,MAAM,KAAK;AAC5B,cAAI,OAAO,KAAK,IAAI,EAAE,MAAM,KAAK,MAAO,SAAQ,KAAK,IAAI,QAAQ,KAAK,KAAK,EAAE;AACjF,iBAAW,KAAK;AACd,YAAI,CAAC,EAAE,UAAU,EAAE,IAAI,IAAI,IAAI,OAAO,EAAE,IAAI,EAAE,IAAI,IAAI,OAAO,EAAE,IAAI,EAAE,KAAK,IAAI,IAAK,SAAQ,KAAK,IAAI,OAAO,EAAE,IAAI,EAAE,CAAC;AACtH,UAAI,QAAQ,IAAI,KAAK,KAAK;AACxB,eAAO;AACP,qBAAa;AAAA,MACf;AACA,UAAI,KAAK,IAAI,IAAI,IAAI,KAAK;AAAA,IAC5B;AAAA,EACF;AAGA,QAAM,aAAa,IAAI;AACvB,MAAI,UAAU;AACd,MAAI,YAAY;AAChB,MAAI,aAAa;AACjB,MAAI,OAAO,GAAG;AACZ,UAAM,CAAC,KAAK,GAAG,IAAI,UAAU,GAAG,IAAI,GAAG,EAAE;AACzC,QAAI,KAAK,GAAG;AACV,UAAI,QAAQ,IAAI;AAChB,YAAM,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,MAAM,aAAa,EAAE,GAAG,KAAK,OAAO,aAAa,KAAK,OAAO,EAAE,CAAC;AACvF,eAAS,KAAK,IAAI,MAAM,IAAI;AAC1B,iBAAS,KAAK,KAAK,MAAM,KAAK,MAAM;AAClC,gBAAM,IAAI,OAAO,KAAK,IAAI,EAAE;AAC5B,gBAAM,SAAS,MAAM,KAAK,SAAU,MAAM,KAAK,UAAU,CAAC,KAAK,eAAe,cAAc,KAAK,KAAK;AACtG,cAAI,OAAQ,SAAQ,KAAK,IAAI,OAAO,KAAK,KAAK,CAAC;AAAA,QACjD;AACF,eAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;AACtC,cAAM,IAAI,OAAO,CAAC;AAClB,cAAM,MAAM,EAAE,IAAI,IAAI,IAAI,OAAO,EAAE,IAAI,EAAE,IAAI,IAAI;AACjD,YAAI,CAAC,OAAO,EAAE,IAAI,aAAa,IAAK;AACpC,YAAI,EAAE,WAAW,KAAK,eAAe,aAAa,EAAE,IAAI,KAAM;AAC9D,YAAI,EAAE,IAAI,IAAI,OAAO;AACnB,kBAAQ,EAAE,IAAI;AACd,uBAAa;AAAA,QACf;AAAA,MACF;AACA,UAAI,QAAQ,IAAI,KAAK,KAAK;AACxB,eAAO;AACP,kBAAU;AAAA,MACZ,MAAO,cAAa;AACpB,UAAI,KAAK,IAAI,IAAI,IAAI,KAAK;AAAA,IAC5B,OAAO;AACL,UAAI,QAAQ,IAAI;AAChB,YAAM,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,OAAO,IAAI,OAAO,EAAE,GAAG,KAAK,OAAO,IAAI,MAAM,EAAE,CAAC;AACvE,eAAS,KAAK,IAAI,MAAM,IAAI;AAC1B,iBAAS,KAAK,KAAK,MAAM,KAAK;AAC5B,cAAI,OAAO,KAAK,IAAI,EAAE,MAAM,KAAK,MAAO,SAAQ,KAAK,IAAI,QAAQ,KAAK,KAAK,EAAE;AACjF,iBAAW,KAAK;AACd,YAAI,CAAC,EAAE,UAAU,EAAE,IAAI,IAAI,IAAI,OAAO,EAAE,IAAI,EAAE,IAAI,IAAI,OAAO,EAAE,IAAI,EAAE,KAAK,IAAI,IAAK,SAAQ,KAAK,IAAI,OAAO,EAAE,IAAI,EAAE,CAAC;AACtH,UAAI,QAAQ,IAAI,KAAK,KAAK;AACxB,eAAO;AACP,oBAAY;AAAA,MACd;AACA,UAAI,KAAK,IAAI,IAAI,IAAI,KAAK;AAAA,IAC5B;AAAA,EACF;AAGA,MAAI,CAAC,SAAS;AACZ,UAAM,QAAQ,SAAS,KAAK,GAAG,GAAG,GAAG,GAAG,QAAQ,KAAK,eAAe,KAAK;AACzE,cAAU,MAAM;AAChB,iBAAa,MAAM;AAAA,EACrB;AAGA,QAAM,QAAQ;AACd,MAAI,SAAS;AACb;AACE,UAAM,CAAC,KAAK,GAAG,IAAI,UAAU,IAAI,OAAO,IAAI,IAAI,OAAO,EAAE;AACzD,UAAM,CAAC,KAAK,GAAG,IAAI,UAAU,IAAI,OAAO,IAAI,IAAI,OAAO,EAAE;AACzD,aAAS,KAAK,KAAK,MAAM,OAAO,CAAC,QAAQ;AACvC,eAAS,KAAK,KAAK,MAAM,OAAO,CAAC,QAAQ,KAAM,KAAI,OAAO,KAAK,IAAI,EAAE,MAAM,KAAK,OAAQ,UAAS;AAAA,EACrG;AAEA,SAAO,EAAE,GAAG,GAAG,MAAM,MAAM,SAAS,WAAW,YAAY,aAAa,QAAQ,WAAW;AAC7F;AAGO,SAAS,SAAS,KAAkB,GAAW,GAAW,GAAW,GAAW,SAAsB,CAAC,GAAG,cAAc,OAA6C;AAC1K,QAAM,KAAK,IAAI;AACf,QAAM,SAAS,IAAI;AACnB,QAAM,CAAC,KAAK,GAAG,IAAI,UAAU,GAAG,IAAI,GAAG,EAAE;AACzC,QAAM,KAAK,KAAK,OAAO,SAAS,KAAK,EAAE;AACvC,WAAS,KAAK,KAAK,MAAM,KAAK,MAAM;AAClC,UAAM,IAAI,OAAO,KAAK,IAAI,EAAE;AAC5B,QAAI,MAAM,KAAK,MAAO,QAAO,EAAE,UAAU,MAAM,OAAO,GAAG;AACzD,QAAI,MAAM,KAAK,UAAU,CAAC,eAAe,KAAK,IAAI,SAAS,KAAK,EAAE,KAAK,IAAI,IAAK,QAAO,EAAE,UAAU,MAAM,OAAO,GAAG;AAAA,EACrH;AACA,WAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;AACtC,UAAM,IAAI,OAAO,CAAC;AAClB,UAAM,MAAM,EAAE,IAAI,IAAI,IAAI,OAAO,EAAE,IAAI,EAAE,IAAI,IAAI;AACjD,QAAI,OAAO,UAAU,EAAE,IAAI,IAAI,OAAO,UAAU,EAAE,IAAI,IAAI,IAAK,QAAO,EAAE,UAAU,MAAM,OAAO,EAAE;AAAA,EACnG;AACA,SAAO,EAAE,UAAU,OAAO,OAAO,GAAG;AACtC;;;ACxHO,IAAM,qBAAuC;AAAA,EAClD,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,UAAU;AAAA,EACV,aAAa;AAAA,EACb,gBAAgB;AAAA,EAChB,UAAU;AAAA,EACV,aAAa;AAAA,EACb,SAAS;AAAA,EACT,SAAS;AAAA,EACT,eAAe;AAAA,EACf,iBAAiB;AAAA,EACjB,cAAc;AAAA,EACd,aAAa;AAAA,EACb,YAAY;AAAA,EACZ,YAAY;AAAA,EACZ,iBAAiB;AAAA,EACjB,iBAAiB;AAAA,EACjB,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW;AAAA,EACX,UAAU;AAAA,EACV,cAAc;AAAA,EACd,aAAa;AAAA,EACb,kBAAkB;AAAA,EAClB,cAAc;AAAA,EACd,cAAc;AAAA,EACd,cAAc;AAChB;AAWO,IAAM,cAAwB,EAAE,OAAO,GAAG,OAAO,GAAG,UAAU,OAAO,aAAa,OAAO,aAAa,MAAM;AAiC5G,SAAS,sBAAsB,GAAW,GAA4B;AAC3E,SAAO,EAAE,GAAG,GAAG,IAAI,GAAG,IAAI,GAAG,QAAQ,GAAG,UAAU,OAAO,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,OAAO,UAAU,GAAG,cAAc,GAAG,SAAS,GAAG,QAAQ,GAAG,YAAY,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,SAAS,GAAG,MAAM,MAAM;AAC1O;AAYA,IAAM,WAAW,CAAC,GAAW,QAAgB,UAA2B,IAAI,SAAS,KAAK,IAAI,IAAI,OAAO,MAAM,IAAI,KAAK,IAAI,IAAI,OAAO,MAAM;AAOtI,SAAS,eAAe,GAAoB,OAAiB,IAAY,KAAkB,MAAwB,oBAAoB,YAAwB,CAAC,GAAqB;AAC1L,QAAM,KAAuB,EAAE,QAAQ,OAAO,YAAY,OAAO,WAAW,OAAO,QAAQ,OAAO,QAAQ,OAAO,MAAM,MAAM;AAC7H,MAAI,EAAE,KAAM,QAAO;AACnB,QAAM,cAAc,EAAE;AAGtB,IAAE,SAAS,KAAK,IAAI,GAAG,EAAE,SAAS,EAAE;AACpC,IAAE,SAAS,KAAK,IAAI,GAAG,EAAE,SAAS,EAAE;AACpC,IAAE,WAAW,KAAK,IAAI,GAAG,EAAE,WAAW,EAAE;AACxC,IAAE,SAAS,KAAK,IAAI,GAAG,EAAE,SAAS,EAAE;AACpC,MAAI,MAAM,YAAa,GAAE,SAAS,IAAI;AAGtC,MAAI,MAAM,eAAe,EAAE,WAAW,KAAK,EAAE,UAAU,KAAK,EAAE,aAAa,GAAG;AAC5E,QAAIC,MAAK,MAAM;AACf,QAAIC,MAAK,MAAM;AACf,QAAID,QAAO,KAAKC,QAAO,EAAG,CAAAD,MAAK,EAAE;AACjC,UAAM,MAAM,IAAI,KAAK,MAAMA,KAAIC,GAAE;AACjC,MAAE,UAAU,IAAI;AAChB,MAAE,SAAS,IAAI;AACf,MAAE;AACF,MAAE,SAASD,MAAK,MAAM,IAAI;AAC1B,MAAE,SAASC,MAAK,MAAM,IAAI;AAC1B,MAAE,UAAU;AACZ,OAAG,SAAS;AAAA,EACd;AAGA,MAAI,EAAE,UAAU,GAAG;AACjB,MAAE,KAAK,EAAE;AACT,MAAE,KAAK,EAAE;AACT,MAAE,WAAW;AAAA,EACf,WAAW,EAAE,YAAY,GAAG;AAC1B,UAAM,SAAS,MAAM,QAAQ,IAAI;AACjC,UAAM,QAAQ,EAAE,WAAY,MAAM,UAAU,IAAI,IAAI,cAAc,IAAI,iBAAkB,MAAM,UAAU,IAAI,IAAI,WAAW,IAAI;AAC/H,MAAE,KAAK,SAAS,EAAE,IAAI,QAAQ,QAAQ,EAAE;AACxC,QAAI,MAAM,UAAU,EAAG,GAAE,SAAS,MAAM,QAAQ,IAAI,IAAI;AAAA,EAC1D;AAGA,MAAI,EAAE,WAAW,KAAK,CAAC,EAAE,UAAU;AACjC,QAAI,IAAI,IAAI;AACZ,QAAI,KAAK,IAAI,EAAE,EAAE,IAAI,IAAI,iBAAiB,MAAM,YAAY,EAAE,QAAS,MAAK,IAAI;AAChF,MAAE,KAAK,KAAK,IAAI,EAAE,KAAK,IAAI,IAAI,IAAI,OAAO;AAC1C,QAAI,EAAE,WAAW,KAAK,EAAE,KAAK,IAAI,oBAAoB,MAAM,UAAU,EAAE,OAAQ,GAAE,KAAK,IAAI;AAAA,EAC5F;AAGA,MAAI,EAAE,WAAW,CAAC,MAAM,YAAY,EAAE,KAAK,GAAG;AAC5C,MAAE,MAAM,IAAI;AACZ,MAAE,UAAU;AAAA,EACd;AAGA,MAAI,EAAE,SAAS,KAAK,EAAE,WAAW,GAAG;AAClC,QAAI,EAAE,YAAY,EAAE,SAAS,GAAG;AAC9B,QAAE,KAAK,CAAC,IAAI;AAEZ,QAAE,MAAM,EAAE;AACV,UAAI,EAAE,UAAU,EAAG,GAAE,MAAM,EAAE;AAC7B,QAAE,UAAU;AACZ,QAAE,SAAS;AACX,QAAE,SAAS;AACX,QAAE,WAAW;AACb,SAAG,SAAS;AAAA,IACd,WAAW,EAAE,WAAW,KAAK,IAAI,eAAe,GAAG;AACjD,QAAE,KAAK,CAAC,EAAE,SAAS,IAAI;AACvB,QAAE,KAAK,CAAC,IAAI;AACZ,QAAE,SAAS,CAAC,EAAE;AACd,QAAE,UAAU;AACZ,QAAE,SAAS;AACX,QAAE,WAAW,IAAI;AACjB,SAAG,aAAa;AAChB,SAAG,SAAS;AAAA,IACd,WAAW,EAAE,eAAe,GAAG;AAC7B,QAAE,KAAK,CAAC,IAAI,eAAe,IAAI;AAC/B,QAAE;AACF,QAAE,UAAU;AACZ,QAAE,SAAS;AACX,SAAG,SAAS;AACZ,SAAG,YAAY;AAAA,IACjB;AAAA,EACF;AAKA,QAAM,cAAc,MAAM,QAAQ,KAAK,EAAE,UAAU;AACnD,MAAI,KAAK,EAAE,KAAK,KAAK,EAAE,UAAU,MAAM,EAAE,WAAW,IAAI;AACxD,MAAI,KAAK,EAAE,KAAK,KAAK,KAAK,IAAI,GAAG,EAAE,OAAO,IAAI,MAAM,EAAE,WAAW,IAAI;AACrE,MAAI,MAAM,SAAS,KAAK,EAAE,GAAG,EAAE,GAAG,GAAG,EAAE,GAAG,GAAG,IAAI,OAAO,GAAG,IAAI,OAAO,GAAG,IAAI,IAAI,EAAE,QAAQ,WAAW,YAAY,CAAC;AAGnH,MAAI,IAAI,aAAa,EAAE,KAAK,KAAK,EAAE,WAAW,GAAG;AAC/C,UAAM,OAAO,YAAY,KAAK,WAAW,IAAI,GAAG,IAAI,GAAG,IAAI,OAAO,IAAI,QAAQ,IAAI,IAAI,eAAe;AACrG,QAAI,SAAS,MAAM;AACjB,YAAM,SAAS,KAAK,EAAE,GAAG,MAAM,GAAG,IAAI,GAAG,GAAG,IAAI,OAAO,GAAG,IAAI,OAAO,GAAG,GAAG,IAAI,EAAE,QAAQ,WAAW,YAAY,CAAC;AACjH,UAAI,IAAI;AAAA,IACV;AAAA,EACF;AAGA,MAAI,IAAI,QAAQ,EAAE,UAAU,KAAK,KAAK,IAAI,EAAE,MAAM,IAAI,GAAG;AACvD,UAAM,OAAO,YAAY,KAAK,WAAW,IAAI,GAAG,IAAI,GAAG,IAAI,OAAO,IAAI,QAAQ,IAAI,IAAI,eAAe;AACrG,QAAI,SAAS,MAAM;AACjB,YAAM,SAAS,KAAK,EAAE,GAAG,IAAI,GAAG,GAAG,MAAM,GAAG,IAAI,OAAO,GAAG,IAAI,OAAO,GAAG,IAAI,GAAG,EAAE,QAAQ,WAAW,YAAY,CAAC;AACjH,UAAI,IAAI;AAAA,IACV;AAAA,EACF;AAEA,IAAE,IAAI,IAAI;AACV,IAAE,IAAI,IAAI;AACV,MAAI,IAAI,QAAQ,EAAE,KAAK,EAAG,GAAE,KAAK;AACjC,MAAI,IAAI,WAAW;AACjB,MAAE,KAAK,KAAK,IAAI,EAAE,IAAI,CAAC;AACvB,MAAE,UAAU;AAAA,EACd;AACA,MAAI,IAAI,QAAQ,EAAE,WAAW,EAAG,GAAE,KAAK;AACvC,IAAE,SAAS,IAAI,aAAa,KAAK,IAAI,cAAc,IAAI,UAAU,KAAK,WAAW,EAAE,GAAG,EAAE,GAAG,IAAI,OAAO,IAAI,MAAM;AAChH,IAAE,WAAW,IAAI;AAGjB,MAAI,EAAE,UAAU;AACd,MAAE,SAAS,IAAI;AACf,MAAE,aAAa,IAAI;AACnB,MAAE,eAAe,IAAI;AACrB,QAAI,CAAC,YAAa,IAAG,SAAS;AAC9B,QAAI,IAAI,cAAc,GAAG;AACvB,YAAM,IAAI,UAAU,IAAI,UAAU;AAClC,QAAE,UAAU,EAAE;AACd,QAAE,UAAU,EAAE;AAEd,QAAE,IAAI,EAAE,IAAI,IAAI;AAAA,IAClB,OAAO;AACL,QAAE,UAAU;AACZ,QAAE,UAAU;AAAA,IACd;AACA,QAAI,EAAE,KAAK,EAAG,GAAE,KAAK;AACrB,MAAE,UAAU;AAAA,EACd,WAAW,eAAe,EAAE,YAAY,GAAG;AAAA,EAE3C;AAEA,MAAI,IAAI,QAAQ;AACd,MAAE,OAAO;AACT,OAAG,OAAO;AAAA,EACZ;AACA,SAAO;AACT;AAQO,SAAS,WAAW,MAAwB,oBAA4B;AAC7E,SAAQ,IAAI,eAAe,IAAI,gBAAiB,IAAI,IAAI;AAC1D;AAGO,SAAS,YAAY,MAAwB,oBAA4B;AAC9E,SAAQ,IAAI,IAAI,eAAgB,IAAI;AACtC;AAGO,SAAS,aAAa,MAAwB,oBAA4B;AAC/E,SAAO,IAAI,WAAW,YAAY,GAAG;AACvC;AAGO,SAAS,iBAAiB,MAAwB,oBAA4B;AACnF,SAAO,aAAa,GAAG,KAAK,IAAI,YAAY,IAAI,YAAY,IAAI;AAClE;AAGA,SAAS,YAAY,KAAkB,QAAqB,GAAW,GAAW,GAAW,GAAW,IAAY,OAA8B;AAChJ,WAASC,KAAI,GAAGA,MAAK,OAAOA,MAAK;AAC/B,eAAW,OAAO,CAAC,GAAG,EAAE,GAAG;AACzB,YAAM,KAAK,IAAI,MAAMA;AACrB,UAAI,CAAC,YAAY,KAAK,IAAI,IAAI,IAAI,GAAG,GAAG,MAAM,KAAK,CAAC,YAAY,KAAK,IAAI,GAAG,GAAG,GAAG,MAAM,EAAG,QAAO;AAAA,IACpG;AAAA,EACF;AACA,SAAO;AACT;AAGA,SAAS,YAAY,KAAkB,QAAqB,GAAW,GAAW,GAAW,GAAW,IAAY,OAA8B;AAChJ,WAASA,KAAI,GAAGA,MAAK,OAAOA,MAAK;AAC/B,eAAW,OAAO,CAAC,IAAI,CAAC,GAAG;AACzB,YAAM,KAAK,IAAI,MAAMA;AACrB,UAAI,CAAC,YAAY,KAAK,IAAI,IAAI,IAAI,GAAG,GAAG,MAAM,KAAK,CAAC,YAAY,KAAK,GAAG,IAAI,GAAG,GAAG,MAAM,EAAG,QAAO;AAAA,IACpG;AAAA,EACF;AACA,SAAO;AACT;AAGA,SAAS,UAAU,KAAkB,QAAqB,GAAW,GAAW,GAAW,GAAmB;AAC5G,MAAI,YAAY,KAAK,IAAI,GAAG,GAAG,GAAG,GAAG,MAAM,EAAG,QAAO;AACrD,MAAI,YAAY,KAAK,IAAI,GAAG,GAAG,GAAG,GAAG,MAAM,EAAG,QAAO;AACrD,SAAO;AACT;;;AC7VO,IAAM,cAAN,MAAqB;AAAA,EAClB,QAAQ,oBAAI,IAAiB;AAAA,EAC7B,SAAS,oBAAI,IAAa;AAAA,EACjB;AAAA,EAEjB,YAAY,WAAW,IAAI;AACzB,SAAK,WAAW;AAAA,EAClB;AAAA,EAEA,QAAc;AACZ,SAAK,MAAM,MAAM;AACjB,SAAK,OAAO,MAAM;AAAA,EACpB;AAAA,EAEA,IAAI,OAAe;AACjB,WAAO,KAAK,OAAO;AAAA,EACrB;AAAA,EAEQ,IAAI,IAAY,IAAoB;AAE1C,YAAQ,KAAK,SAAS,SAAS,KAAK;AAAA,EACtC;AAAA,EAEA,OAAO,MAAS,MAAkB;AAChC,SAAK,OAAO,IAAI,MAAM,IAAI;AAC1B,UAAM,KAAK,KAAK;AAChB,UAAM,KAAK,KAAK,MAAM,KAAK,IAAI,EAAE;AACjC,UAAM,KAAK,KAAK,OAAO,KAAK,IAAI,KAAK,KAAK,EAAE;AAC5C,UAAM,KAAK,KAAK,MAAM,KAAK,IAAI,EAAE;AACjC,UAAM,KAAK,KAAK,OAAO,KAAK,IAAI,KAAK,KAAK,EAAE;AAC5C,aAAS,KAAK,IAAI,MAAM,IAAI;AAC1B,eAAS,KAAK,IAAI,MAAM,IAAI,MAAM;AAChC,cAAM,IAAI,KAAK,IAAI,IAAI,EAAE;AACzB,cAAM,OAAO,KAAK,MAAM,IAAI,CAAC;AAC7B,YAAI,KAAM,MAAK,KAAK,IAAI;AAAA,YACnB,MAAK,MAAM,IAAI,GAAG,CAAC,IAAI,CAAC;AAAA,MAC/B;AAAA,EACJ;AAAA;AAAA,EAGA,MAAM,MAAiB;AACrB,UAAM,KAAK,KAAK;AAChB,UAAM,KAAK,KAAK,MAAM,KAAK,IAAI,EAAE;AACjC,UAAM,KAAK,KAAK,OAAO,KAAK,IAAI,KAAK,KAAK,EAAE;AAC5C,UAAM,KAAK,KAAK,MAAM,KAAK,IAAI,EAAE;AACjC,UAAM,KAAK,KAAK,OAAO,KAAK,IAAI,KAAK,KAAK,EAAE;AAC5C,UAAM,OAAO,oBAAI,IAAO;AACxB,UAAM,MAAW,CAAC;AAClB,aAAS,KAAK,IAAI,MAAM,IAAI;AAC1B,eAAS,KAAK,IAAI,MAAM,IAAI,MAAM;AAChC,cAAM,OAAO,KAAK,MAAM,IAAI,KAAK,IAAI,IAAI,EAAE,CAAC;AAC5C,YAAI,CAAC,KAAM;AACX,mBAAW,QAAQ,MAAM;AACvB,cAAI,KAAK,IAAI,IAAI,EAAG;AACpB,eAAK,IAAI,IAAI;AACb,gBAAM,IAAI,KAAK,OAAO,IAAI,IAAI;AAC9B,cAAI,EAAE,IAAI,KAAK,IAAI,KAAK,KAAK,EAAE,IAAI,EAAE,IAAI,KAAK,KAAK,EAAE,IAAI,KAAK,IAAI,KAAK,KAAK,EAAE,IAAI,EAAE,IAAI,KAAK,EAAG,KAAI,KAAK,IAAI;AAAA,QAC/G;AAAA,MACF;AACF,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,YAAY,GAAW,GAAW,QAAqB;AACrD,UAAM,OAAO,KAAK,MAAM,EAAE,GAAG,IAAI,QAAQ,GAAG,IAAI,QAAQ,GAAG,SAAS,GAAG,GAAG,SAAS,EAAE,CAAC;AACtF,WAAO,KAAK,OAAO,CAAC,SAAS;AAC3B,YAAM,IAAI,KAAK,OAAO,IAAI,IAAI;AAC9B,YAAM,KAAK,KAAK,IAAI,EAAE,GAAG,KAAK,IAAI,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC;AAC/C,YAAM,KAAK,KAAK,IAAI,EAAE,GAAG,KAAK,IAAI,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC;AAC/C,cAAQ,IAAI,OAAO,IAAI,OAAO,IAAI,OAAO,IAAI,OAAO,SAAS;AAAA,IAC/D,CAAC;AAAA,EACH;AACF;;;AC7DO,SAAS,aAAa,KAAkB,IAAY,IAAY,IAAY,IAAoB;AACrG,QAAM,KAAK,IAAI;AACf,QAAM,KAAK,KAAK;AAChB,QAAM,KAAK,KAAK;AAChB,QAAM,UAAU,KAAK,MAAM,IAAI,EAAE;AACjC,MAAI,YAAY,EAAG,QAAO,EAAE,SAAS,OAAO,GAAG,IAAI,GAAG,IAAI,MAAM,EAAE;AAClE,QAAM,OAAO,KAAK;AAClB,QAAM,OAAO,KAAK;AAElB,MAAI,KAAK,KAAK,MAAM,KAAK,EAAE;AAC3B,MAAI,KAAK,KAAK,MAAM,KAAK,EAAE;AAC3B,QAAM,QAAQ,OAAO,IAAI,IAAI;AAC7B,QAAM,QAAQ,OAAO,IAAI,IAAI;AAC7B,QAAM,UAAU,SAAS,IAAI,KAAK,IAAI,KAAK,IAAI,IAAI;AACnD,QAAM,UAAU,SAAS,IAAI,KAAK,IAAI,KAAK,IAAI,IAAI;AACnD,MAAI,QAAQ,SAAS,KAAK,OAAO,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,MAAM,KAAK,IAAI,IAAI,IAAI;AAC3F,MAAI,QAAQ,SAAS,KAAK,OAAO,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,MAAM,KAAK,IAAI,IAAI,IAAI;AAE3F,MAAI,IAAI;AAER,WAAS,QAAQ,GAAG,QAAQ,KAAK,SAAS;AACxC,QAAI,QAAQ,OAAO;AACjB,UAAI;AACJ,eAAS;AACT,YAAM;AAAA,IACR,OAAO;AACL,UAAI;AACJ,eAAS;AACT,YAAM;AAAA,IACR;AACA,QAAI,KAAK,QAAS,QAAO,EAAE,SAAS,OAAO,GAAG,IAAI,GAAG,IAAI,MAAM,QAAQ;AACvE,QAAI,OAAO,KAAK,IAAI,EAAE,MAAM,KAAK,OAAO;AACtC,aAAO,EAAE,SAAS,MAAM,GAAG,KAAK,OAAO,GAAG,GAAG,KAAK,OAAO,GAAG,MAAM,EAAE;AAAA,IACtE;AAAA,EACF;AACA,SAAO,EAAE,SAAS,MAAM,GAAG,KAAK,OAAO,GAAG,GAAG,KAAK,OAAO,GAAG,MAAM,EAAE;AACtE;AAGO,SAAS,YAAY,KAAkB,IAAY,IAAY,IAAY,IAAqB;AACrG,SAAO,CAAC,aAAa,KAAK,IAAI,IAAI,IAAI,EAAE,EAAE;AAC5C;AAMO,SAAS,aAAa,KAAkB,IAAY,IAAY,OAAe,OAAe,KAAa,OAAe,IAAY,IAAqB;AAChK,QAAM,KAAK,KAAK;AAChB,QAAM,KAAK,KAAK;AAChB,QAAM,IAAI,KAAK,MAAM,IAAI,EAAE;AAC3B,MAAI,IAAI,SAAS,MAAM,EAAG,QAAO;AACjC,QAAM,OAAO,KAAK,QAAQ,KAAK,SAAS;AACxC,MAAI,MAAM,KAAK,IAAI,MAAM,CAAC,EAAG,QAAO;AACpC,SAAO,YAAY,KAAK,IAAI,IAAI,IAAI,EAAE;AACxC;;;ACUO,SAAS,aAAa,MAAoC;AAC/D,SAAO,KACJ,IAAI,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAU,EAC7B,KAAK,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,EAC7C,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC;AACnB;;;ACjFA,IAAM,IAAI,CAAC,MAAuB,OAAO,UAAU,CAAC,IAAI,OAAO,CAAC,KAAK,KAAK,MAAM,IAAI,GAAI,IAAI,KAAM,SAAS;AAE3G,SAAS,OAAO,GAAsB;AACpC,SAAO,UAAU,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;AAC3E;AAEA,SAAS,WAAW,GAAkB;AACpC,QAAM,QAAkB,CAAC;AACzB,QAAM,KAAK,SAAS,EAAE,QAAQ,MAAM,GAAG;AACvC,MAAI,EAAE,QAAQ;AACZ,UAAM,KAAK,WAAW,EAAE,MAAM,GAAG;AACjC,UAAM,KAAK,iBAAiB,EAAE,EAAE,eAAe,CAAC,CAAC,GAAG;AACpD,QAAI,EAAE,MAAO,OAAM,KAAK,gDAAgD;AAAA,EAC1E;AACA,MAAI,EAAE,YAAY,UAAa,EAAE,YAAY,EAAG,OAAM,KAAK,YAAY,EAAE,EAAE,OAAO,CAAC,GAAG;AACtF,SAAO,MAAM,KAAK,GAAG;AACvB;AAEA,SAAS,WAAW,GAAmB;AACrC,SAAO,EAAE,QAAQ,MAAM,OAAO,EAAE,QAAQ,MAAM,MAAM,EAAE,QAAQ,MAAM,MAAM;AAC5E;AAEA,SAAS,aAAa,GAAwB;AAC5C,QAAM,KAAK,cAAc,OAAO,EAAE,SAAS,CAAC;AAC5C,QAAM,QAAQ,WAAW,CAAC;AAC1B,UAAQ,EAAE,MAAM;AAAA,IACd,KAAK;AACH,aAAO,YAAY,EAAE,EAAE,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,QAAQ,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,KAAK;AAAA,IAC7H,KAAK;AACH,aAAO,eAAe,EAAE,EAAE,EAAE,CAAC,SAAS,EAAE,EAAE,EAAE,CAAC,QAAQ,EAAE,EAAE,MAAM,CAAC,KAAK,EAAE,IAAI,KAAK;AAAA,IAClF,KAAK,QAAQ;AACX,YAAM,MAAM,CAAC;AACb,eAAS,IAAI,GAAG,IAAI,EAAE,OAAO,QAAQ,KAAK,EAAG,KAAI,KAAK,GAAG,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,OAAO,IAAI,CAAC,CAAC,CAAC,EAAE;AAC/F,YAAM,MAAM,EAAE,SAAS,YAAY;AACnC,aAAO,IAAI,GAAG,YAAY,IAAI,KAAK,GAAG,CAAC,KAAK,EAAE,IAAI,KAAK;AAAA,IACzD;AAAA,IACA,KAAK;AACH,aAAO,YAAY,EAAE,CAAC,KAAK,EAAE,IAAI,KAAK;AAAA,IACxC,KAAK,QAAQ;AACX,YAAM,SAAS,EAAE,UAAU,WAAW,WAAW,EAAE,UAAU,UAAU,QAAQ;AAC/E,YAAM,OAAO,EAAE,OAAO,iBAAiB,EAAE,IAAI,MAAM;AACnD,YAAM,SAAS,EAAE,SAAS,iBAAiB,EAAE,MAAM,MAAM;AACzD,YAAM,OAAO,EAAE,QAAQ;AACvB,aAAO,YAAY,EAAE,EAAE,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,gBAAgB,EAAE,EAAE,IAAI,CAAC,kBAAkB,MAAM,+BAA+B,IAAI,GAAG,MAAM,UAAU,IAAI,IAAI,EAAE,YAAY,UAAa,EAAE,YAAY,IAAI,aAAa,EAAE,EAAE,OAAO,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,WAAW,EAAE,IAAI,CAAC;AAAA,IAClQ;AAAA,IACA,KAAK;AACH,aAAO,gBAAgB,EAAE,IAAI,QAAQ,EAAE,EAAE,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,YAAY,UAAa,EAAE,YAAY,IAAI,aAAa,EAAE,EAAE,OAAO,CAAC,MAAM,EAAE;AAAA,EAC1L;AACF;AAGO,SAAS,mBAAmB,UAAiC;AAClE,SAAO,aAAa,QAAQ,EAAE,IAAI,YAAY,EAAE,KAAK,EAAE;AACzD;AAGO,SAAS,kBACd,UACA,OACA,QACA,aAAa,WACL;AACR,SACE,wDAAwD,KAAK,IAAI,MAAM,YAAY,KAAK,aAAa,MAAM,8BAC/E,KAAK,aAAa,MAAM,WAAW,UAAU,QACzE,mBAAmB,QAAQ,IAC3B;AAEJ;;;ACpEA,IAAM,QAAQ;AAEP,IAAM,cAAN,MAAsC;AAAA,EAClC;AAAA,EACA;AAAA,EACD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAER,YAAY,QAAwB;AAClC,SAAK,QAAQ,OAAO;AACpB,SAAK,SAAS,OAAO;AACrB,SAAK,aAAa,OAAO,cAAc;AAEvC,SAAK,MAAM,SAAS,gBAAgB,OAAO,KAAK;AAChD,SAAK,IAAI,aAAa,WAAW,OAAO,KAAK,KAAK,IAAI,KAAK,MAAM,EAAE;AACnE,SAAK,IAAI,aAAa,uBAAuB,eAAe;AAC5D,SAAK,IAAI,MAAM,QAAQ;AACvB,SAAK,IAAI,MAAM,SAAS;AACxB,SAAK,IAAI,MAAM,UAAU;AAEzB,SAAK,KAAK,SAAS,gBAAgB,OAAO,MAAM;AAChD,SAAK,GAAG,aAAa,KAAK,GAAG;AAC7B,SAAK,GAAG,aAAa,KAAK,GAAG;AAC7B,SAAK,GAAG,aAAa,SAAS,OAAO,KAAK,KAAK,CAAC;AAChD,SAAK,GAAG,aAAa,UAAU,OAAO,KAAK,MAAM,CAAC;AAClD,SAAK,GAAG,aAAa,QAAQ,KAAK,UAAU;AAC5C,SAAK,IAAI,YAAY,KAAK,EAAE;AAE5B,SAAK,QAAQ,SAAS,gBAAgB,OAAO,GAAG;AAChD,SAAK,IAAI,YAAY,KAAK,KAAK;AAAA,EACjC;AAAA,EAEA,MAAM,QAA2B;AAC/B,WAAO,YAAY,KAAK,GAAG;AAAA,EAC7B;AAAA,EAEA,KAAK,UAA+B;AAGlC,SAAK,MAAM,YAAY,mBAAmB,QAAQ;AAAA,EACpD;AAAA,EAEA,cAAc,OAAqB;AACjC,SAAK,aAAa;AAClB,SAAK,GAAG,aAAa,QAAQ,KAAK;AAAA,EACpC;AAAA,EAEA,IAAI,UAAyB;AAC3B,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,UAAgB;AACd,SAAK,IAAI,OAAO;AAAA,EAClB;AACF;;;AC1DO,IAAM,mBAAN,MAA2C;AAAA,EACvC;AAAA,EACA;AAAA,EACD;AAAA,EACA;AAAA,EACA;AAAA,EACA,MAAM;AAAA,EAEd,YAAY,QAAwB;AAClC,SAAK,QAAQ,OAAO;AACpB,SAAK,SAAS,OAAO;AACrB,SAAK,aAAa,OAAO,cAAc;AACvC,SAAK,SAAS,SAAS,cAAc,QAAQ;AAC7C,SAAK,OAAO,MAAM,QAAQ;AAC1B,SAAK,OAAO,MAAM,SAAS;AAC3B,SAAK,OAAO,MAAM,UAAU;AAC5B,UAAM,MAAM,KAAK,OAAO,WAAW,IAAI;AACvC,QAAI,CAAC,IAAK,OAAM,IAAI,MAAM,sCAAsC;AAChE,SAAK,MAAM;AACX,SAAK,OAAO;AAAA,EACd;AAAA,EAEA,MAAM,QAA2B;AAC/B,WAAO,YAAY,KAAK,MAAM;AAC9B,SAAK,OAAO;AAAA,EACd;AAAA,EAEQ,SAAe;AACrB,SAAK,MAAM,KAAK,IAAI,GAAG,WAAW,oBAAoB,CAAC;AACvD,SAAK,OAAO,QAAQ,KAAK,MAAM,KAAK,QAAQ,KAAK,GAAG;AACpD,SAAK,OAAO,SAAS,KAAK,MAAM,KAAK,SAAS,KAAK,GAAG;AAAA,EACxD;AAAA,EAEA,KAAK,UAA+B;AAClC,UAAM,MAAM,KAAK;AACjB,QAAI,aAAa,KAAK,KAAK,GAAG,GAAG,KAAK,KAAK,GAAG,CAAC;AAC/C,QAAI,YAAY,KAAK;AACrB,QAAI,SAAS,GAAG,GAAG,KAAK,OAAO,KAAK,MAAM;AAE1C,eAAW,KAAK,aAAa,QAAQ,GAAG;AACtC,UAAI,KAAK;AACT,YAAM,IAAI,EAAE;AACZ,UAAI,UAAU,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;AAC1C,UAAI,cAAe,EAAY,WAAW;AAC1C,WAAK,MAAM,KAAK,CAAC;AACjB,UAAI,QAAQ;AAAA,IACd;AAAA,EACF;AAAA,EAEQ,OAAO,KAA+B,GAAgB;AAC5D,QAAI,EAAE,QAAQ,EAAE,SAAS,QAAQ;AAC/B,UAAI,YAAY,EAAE;AAClB,UAAI,KAAK;AAAA,IACX;AACA,QAAI,EAAE,QAAQ;AACZ,UAAI,cAAc,EAAE;AACpB,UAAI,YAAY,EAAE,eAAe;AACjC,UAAI,EAAE,OAAO;AACX,YAAI,WAAW;AACf,YAAI,UAAU;AAAA,MAChB;AACA,UAAI,OAAO;AAAA,IACb;AAAA,EACF;AAAA,EAEQ,MAAM,KAA+B,GAAsB;AACjE,YAAQ,EAAE,MAAM;AAAA,MACd,KAAK;AACH,YAAI,UAAU;AACd,YAAI,EAAE,EAAG,MAAK,UAAU,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;AAAA,YAC/C,KAAI,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;AAChC,aAAK,OAAO,KAAK,CAAC;AAClB;AAAA,MACF,KAAK;AACH,YAAI,UAAU;AACd,YAAI,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,GAAG,KAAK,KAAK,CAAC;AAC5C,aAAK,OAAO,KAAK,CAAC;AAClB;AAAA,MACF,KAAK;AACH,YAAI,UAAU;AACd,iBAAS,IAAI,GAAG,IAAI,EAAE,OAAO,QAAQ,KAAK,GAAG;AAC3C,cAAI,MAAM,EAAG,KAAI,OAAO,EAAE,OAAO,CAAC,GAAG,EAAE,OAAO,IAAI,CAAC,CAAC;AAAA,cAC/C,KAAI,OAAO,EAAE,OAAO,CAAC,GAAG,EAAE,OAAO,IAAI,CAAC,CAAC;AAAA,QAC9C;AACA,YAAI,EAAE,OAAQ,KAAI,UAAU;AAC5B,aAAK,OAAO,KAAK,CAAC;AAClB;AAAA,MACF,KAAK;AACH;AACE,gBAAM,IAAI,IAAI,OAAO,EAAE,CAAC;AACxB,cAAI,EAAE,QAAQ,EAAE,SAAS,QAAQ;AAC/B,gBAAI,YAAY,EAAE;AAClB,gBAAI,KAAK,CAAC;AAAA,UACZ;AACA,cAAI,EAAE,QAAQ;AACZ,gBAAI,cAAc,EAAE;AACpB,gBAAI,YAAY,EAAE,eAAe;AACjC,gBAAI,EAAE,OAAO;AACX,kBAAI,WAAW;AACf,kBAAI,UAAU;AAAA,YAChB;AACA,gBAAI,OAAO,CAAC;AAAA,UACd;AAAA,QACF;AACA;AAAA,MACF,KAAK;AACH,YAAI,YAAY,EAAE,QAAQ;AAC1B,YAAI,OAAO,GAAG,EAAE,UAAU,GAAG,IAAI,EAAE,IAAI,MAAM,EAAE,QAAQ,YAAY;AACnE,YAAI,YAAY,EAAE,SAAS;AAC3B,YAAI,eAAe;AACnB,YAAI,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;AAC7B;AAAA,MACF,KAAK;AACH;AAAA,IACJ;AAAA,EACF;AAAA,EAEQ,UAAU,KAA+B,GAAW,GAAW,GAAW,GAAW,GAAiB;AAC5G,UAAM,KAAK,KAAK,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AACnC,QAAI,OAAO,IAAI,IAAI,CAAC;AACpB,QAAI,MAAM,IAAI,GAAG,GAAG,IAAI,GAAG,IAAI,GAAG,EAAE;AACpC,QAAI,MAAM,IAAI,GAAG,IAAI,GAAG,GAAG,IAAI,GAAG,EAAE;AACpC,QAAI,MAAM,GAAG,IAAI,GAAG,GAAG,GAAG,EAAE;AAC5B,QAAI,MAAM,GAAG,GAAG,IAAI,GAAG,GAAG,EAAE;AAC5B,QAAI,UAAU;AAAA,EAChB;AAAA,EAEA,IAAI,UAA6B;AAC/B,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,UAAgB;AACd,SAAK,OAAO,OAAO;AAAA,EACrB;AACF;;;ACnIO,IAAM,mBAAN,MAA2C;AAAA,EACvC;AAAA,EACA;AAAA,EACD;AAAA,EACA,OAAsB,CAAC;AAAA,EAC/B,aAAa;AAAA,EAEb,YAAY,QAAwB;AAClC,SAAK,QAAQ,OAAO;AACpB,SAAK,SAAS,OAAO;AACrB,SAAK,aAAa,OAAO,cAAc;AAAA,EACzC;AAAA,EAEA,KAAK,UAA+B;AAClC,SAAK,OAAO;AACZ,SAAK;AAAA,EACP;AAAA;AAAA,EAGA,IAAI,WAA0B;AAC5B,WAAO,KAAK;AAAA,EACd;AAAA;AAAA,EAGA,MAAM,MAAmC;AACvC,WAAO,KAAK,KAAK,OAAO,CAAC,MAAM,EAAE,SAAS,IAAI,EAAE;AAAA,EAClD;AAAA;AAAA,EAGA,cAAsB;AACpB,WAAO,kBAAkB,KAAK,MAAM,KAAK,OAAO,KAAK,QAAQ,KAAK,UAAU;AAAA,EAC9E;AACF;;;ACvBO,IAAM,SAAkB;AAAA,EAC7B,MAAM;AAAA,EACN,IAAI;AAAA,EACJ,KAAK;AAAA,EACL,SAAS;AAAA,EACT,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,MAAM;AAAA,EACN,MAAM;AAAA,EACN,MAAM,CAAC,WAAW,WAAW,WAAW,WAAW,WAAW,SAAS;AACzE;AAEO,IAAM,OAAgB;AAAA,EAC3B,MAAM;AAAA,EACN,IAAI;AAAA,EACJ,KAAK;AAAA,EACL,SAAS;AAAA,EACT,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,MAAM;AAAA,EACN,MAAM;AAAA,EACN,MAAM,CAAC,WAAW,WAAW,WAAW,WAAW,WAAW,SAAS;AACzE;AAEO,IAAM,QAAiB;AAAA,EAC5B,MAAM;AAAA,EACN,IAAI;AAAA,EACJ,KAAK;AAAA,EACL,SAAS;AAAA,EACT,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,MAAM;AAAA,EACN,MAAM;AAAA,EACN,MAAM,CAAC,WAAW,WAAW,WAAW,WAAW,WAAW,SAAS;AACzE;AAEO,IAAM,WAAoC,EAAE,QAAQ,QAAQ,MAAM,MAAM,OAAO,MAAM;AAGrF,SAAS,IAAI,GAAW,GAAW,GAAmB;AAC3D,QAAM,KAAK,SAAS,CAAC;AACrB,QAAM,KAAK,SAAS,CAAC;AACrB,QAAM,IAAI,KAAK,MAAM,GAAG,CAAC,KAAK,GAAG,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC;AAChD,QAAM,IAAI,KAAK,MAAM,GAAG,CAAC,KAAK,GAAG,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC;AAChD,QAAM,KAAK,KAAK,MAAM,GAAG,CAAC,KAAK,GAAG,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC;AACjD,SAAO,SAAS,GAAG,GAAG,EAAE;AAC1B;AAEO,SAAS,UAAU,KAAa,OAAuB;AAC5D,QAAM,CAAC,GAAG,GAAG,CAAC,IAAI,SAAS,GAAG;AAC9B,SAAO,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,KAAK;AACxC;AAEA,SAAS,SAAS,KAAuC;AACvD,MAAI,IAAI,IAAI,QAAQ,KAAK,EAAE;AAC3B,MAAI,EAAE,WAAW,EAAG,KAAI,EAAE,MAAM,EAAE,EAAE,IAAI,CAAC,MAAM,IAAI,CAAC,EAAE,KAAK,EAAE;AAC7D,QAAMC,KAAI,SAAS,GAAG,EAAE;AACxB,SAAO,CAAEA,MAAK,KAAM,KAAMA,MAAK,IAAK,KAAKA,KAAI,GAAG;AAClD;AACA,SAAS,SAAS,GAAW,GAAW,GAAmB;AACzD,SAAO,MAAM,CAAC,GAAG,GAAG,CAAC,EAAE,IAAI,CAAC,MAAM,KAAK,IAAI,GAAG,KAAK,IAAI,KAAK,CAAC,CAAC,EAAE,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG,CAAC,EAAE,KAAK,EAAE;AACxG;;;AC1EO,SAAS,eAAe,OAAe,QAAgB,WAAW,GAAa;AACpF,QAAM,MAAgB,CAAC;AACvB,WAAS,IAAI,GAAG,IAAI,OAAO,KAAK;AAC9B,UAAM,IAAI,WAAY,IAAI,QAAS;AACnC,QAAI,KAAK,KAAK,IAAI,CAAC,IAAI,QAAQ,KAAK,IAAI,CAAC,IAAI,MAAM;AAAA,EACrD;AACA,SAAO;AACT;AAGO,SAAS,KAAK,QAAgB,OAAe,OAAe,WAAW,CAAC,KAAK,KAAK,GAAa;AACpG,QAAM,MAAgB,CAAC;AACvB,WAAS,IAAI,GAAG,IAAI,SAAS,GAAG,KAAK;AACnC,UAAM,IAAI,IAAI,MAAM,IAAI,QAAQ;AAChC,UAAM,IAAI,WAAY,KAAK,SAAS,KAAM;AAC1C,QAAI,KAAK,KAAK,IAAI,CAAC,IAAI,GAAG,KAAK,IAAI,CAAC,IAAI,CAAC;AAAA,EAC3C;AACA,SAAO;AACT;AAGO,SAAS,SAAS,KAAU,QAAgB,SAAS,MAAM,QAAQ,GAAW;AACnF,QAAM,MAAc,CAAC;AACrB,WAAS,IAAI,GAAG,IAAI,OAAO,KAAK;AAC9B,UAAM,IAAK,IAAI,QAAS;AACxB,UAAM,IAAI,UAAU,IAAI,SAAS,IAAI,MAAM,IAAI,SAAS;AACxD,QAAI,KAAK,EAAE,GAAG,KAAK,IAAI,CAAC,IAAI,GAAG,GAAG,KAAK,IAAI,CAAC,IAAI,EAAE,CAAC;AAAA,EACrD;AACA,SAAO,iBAAiB,GAAG;AAC7B;AAGO,SAAS,iBAAiB,QAAgB,UAAU,GAAW;AACpE,QAAM,OAAO,OAAO;AACpB,MAAI,OAAO,EAAG,QAAO;AACrB,QAAM,IAAI,CAAC,MAAc,QAAS,IAAI,OAAQ,QAAQ,IAAI;AAC1D,QAAM,IAAI,CAAC,MAAc,KAAK,MAAM,IAAI,GAAG,IAAI;AAC/C,MAAI,IAAI,KAAK,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC;AACnC,WAAS,IAAI,GAAG,IAAI,MAAM,KAAK;AAC7B,UAAM,KAAK,EAAE,IAAI,CAAC;AAClB,UAAM,KAAK,EAAE,CAAC;AACd,UAAM,KAAK,EAAE,IAAI,CAAC;AAClB,UAAM,KAAK,EAAE,IAAI,CAAC;AAClB,UAAM,MAAM,GAAG,KAAM,GAAG,IAAI,GAAG,KAAK,IAAK;AACzC,UAAM,MAAM,GAAG,KAAM,GAAG,IAAI,GAAG,KAAK,IAAK;AACzC,UAAM,MAAM,GAAG,KAAM,GAAG,IAAI,GAAG,KAAK,IAAK;AACzC,UAAM,MAAM,GAAG,KAAM,GAAG,IAAI,GAAG,KAAK,IAAK;AACzC,SAAK,MAAM,EAAE,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;AAAA,EACzE;AACA,SAAO,IAAI;AACb;AAGO,SAAS,eAAe,QAAgB,UAAU,GAAW;AAClE,QAAM,OAAO,OAAO;AACpB,MAAI,OAAO,EAAG,QAAO;AACrB,QAAM,IAAI,CAAC,MAAc,KAAK,MAAM,IAAI,GAAG,IAAI;AAC/C,MAAI,IAAI,KAAK,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC;AAC7C,WAAS,IAAI,GAAG,IAAI,OAAO,GAAG,KAAK;AACjC,UAAM,KAAK,OAAO,KAAK,IAAI,GAAG,IAAI,CAAC,CAAC;AACpC,UAAM,KAAK,OAAO,CAAC;AACnB,UAAM,KAAK,OAAO,IAAI,CAAC;AACvB,UAAM,KAAK,OAAO,KAAK,IAAI,OAAO,GAAG,IAAI,CAAC,CAAC;AAC3C,UAAM,MAAM,GAAG,KAAM,GAAG,IAAI,GAAG,KAAK,IAAK;AACzC,UAAM,MAAM,GAAG,KAAM,GAAG,IAAI,GAAG,KAAK,IAAK;AACzC,UAAM,MAAM,GAAG,KAAM,GAAG,IAAI,GAAG,KAAK,IAAK;AACzC,UAAM,MAAM,GAAG,KAAM,GAAG,IAAI,GAAG,KAAK,IAAK;AACzC,SAAK,MAAM,EAAE,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;AAAA,EACzE;AACA,SAAO;AACT;;;ACnEA,IAAM,kBAA2B,EAAE,QAAQ,KAAK,OAAO,KAAK,KAAK,KAAK,OAAO,MAAM;AAW5E,IAAM,WAAN,MAAe;AAAA,EACZ,MAA2B;AAAA,EAC3B,SAA0B;AAAA,EAC1B,YAA6B;AAAA,EAC7B,UAA2B;AAAA,EAC3B,MAAe,EAAE,GAAG,gBAAgB;AAAA,EACpC,QAAQ;AAAA,EAEhB,IAAI,YAAqB;AACvB,WAAO,OAAO,WAAW,iBAAiB,eAAe,wBAAwB;AAAA,EACnF;AAAA,EACA,IAAI,UAAmB;AACrB,WAAO,CAAC,CAAC,KAAK;AAAA,EAChB;AAAA;AAAA,EAGA,QAAc;AACZ,QAAI,KAAK,KAAK;AACZ,WAAK,KAAK,IAAI,OAAO;AACrB;AAAA,IACF;AACA,QAAI,CAAC,KAAK,UAAW;AACrB,UAAM,MACJ,WAAW,gBACV,WAAsE;AACzE,SAAK,MAAM,IAAI,IAAI;AACnB,SAAK,SAAS,KAAK,IAAI,WAAW;AAClC,SAAK,YAAY,KAAK,IAAI,WAAW;AACrC,SAAK,UAAU,KAAK,IAAI,WAAW;AACnC,SAAK,UAAU,QAAQ,KAAK,MAAM;AAClC,SAAK,QAAQ,QAAQ,KAAK,MAAM;AAChC,SAAK,OAAO,QAAQ,KAAK,IAAI,WAAW;AACxC,SAAK,aAAa;AAAA,EACpB;AAAA,EAEA,WAAW,GAA2B;AACpC,SAAK,MAAM,EAAE,GAAG,KAAK,KAAK,GAAG,EAAE;AAC/B,SAAK,aAAa;AAAA,EACpB;AAAA,EACA,aAAsB;AACpB,WAAO,EAAE,GAAG,KAAK,IAAI;AAAA,EACvB;AAAA,EAEQ,eAAqB;AAC3B,QAAI,CAAC,KAAK,OAAO,CAAC,KAAK,UAAU,CAAC,KAAK,aAAa,CAAC,KAAK,QAAS;AACnE,UAAM,IAAI,KAAK,IAAI;AACnB,SAAK,OAAO,KAAK,gBAAgB,KAAK,IAAI,QAAQ,IAAI,KAAK,IAAI,QAAQ,GAAG,IAAI;AAC9E,SAAK,UAAU,KAAK,gBAAgB,KAAK,IAAI,QAAQ,KAAK,GAAG,IAAI;AACjE,SAAK,QAAQ,KAAK,gBAAgB,KAAK,IAAI,KAAK,GAAG,IAAI;AAAA,EACzD;AAAA;AAAA,EAGA,KAAK,MAAkB;AACrB,QAAI,CAAC,KAAK,OAAO,CAAC,KAAK,QAAS;AAChC,UAAM,EAAE,MAAM,UAAU,OAAO,QAAQ,OAAO,KAAK,QAAQ,EAAE,IAAI;AACjE,UAAM,IAAI,KAAK,IAAI,cAAc;AACjC,UAAM,MAAM,KAAK,IAAI,iBAAiB;AACtC,QAAI,OAAO;AACX,QAAI,UAAU,QAAQ;AACtB,UAAM,IAAI,KAAK,IAAI,WAAW;AAC9B,MAAE,KAAK,eAAe,GAAG,CAAC;AAC1B,MAAE,KAAK,wBAAwB,MAAM,IAAI,IAAK;AAC9C,MAAE,KAAK,6BAA6B,MAAQ,IAAI,QAAQ;AACxD,QAAI,QAAQ,CAAC;AACb,MAAE,QAAQ,KAAK,OAAO;AACtB,QAAI,MAAM,CAAC;AACX,QAAI,KAAK,IAAI,WAAW,IAAI;AAAA,EAC9B;AAAA;AAAA,EAGA,KAAK,OAAqB;AACxB,eAAW,KAAK,MAAO,MAAK,KAAK,CAAC;AAAA,EACpC;AAAA;AAAA,EAGA,KAAK,OAAO,KAAW;AACrB,SAAK,KAAK,EAAE,MAAM,UAAU,MAAM,MAAM,QAAQ,MAAM,KAAK,CAAC;AAAA,EAC9D;AAAA,EACA,QAAc;AACZ,KAAC,QAAQ,QAAQ,MAAM,EAAE,QAAQ,CAAC,GAAG,MAAM,KAAK,KAAK,EAAE,MAAM,GAAG,UAAU,MAAM,IAAI,MAAM,MAAM,QAAQ,MAAM,MAAM,OAAO,IAAI,KAAK,CAAC,CAAC;AAAA,EACxI;AAAA,EACA,UAAgB;AACd,KAAC,KAAK,QAAQ,QAAQ,MAAM,EAAE,QAAQ,CAAC,GAAG,MAAM,KAAK,KAAK,EAAE,MAAM,GAAG,UAAU,KAAK,MAAM,YAAY,MAAM,MAAM,OAAO,IAAI,KAAK,CAAC,CAAC;AAAA,EACtI;AAAA,EACA,OAAa;AACX,SAAK,KAAK,EAAE,MAAM,KAAK,UAAU,MAAM,MAAM,QAAQ,MAAM,KAAK,CAAC;AAAA,EACnE;AAAA;AAAA,EAGA,aAAa,OAAO,KAAK,SAAS,CAAC,GAAG,KAAK,GAAG,GAAG,GAAS;AACxD,QAAI,CAAC,KAAK,OAAO,CAAC,KAAK,aAAa,KAAK,MAAO;AAChD,SAAK,QAAQ;AACb,UAAM,SAAS,KAAK,IAAI,mBAAmB;AAC3C,WAAO,OAAO;AACd,WAAO,UAAU,QAAQ;AACzB,WAAO,QAAQ,KAAK,SAAS;AAC7B,UAAM,MAAM,KAAK,IAAI,WAAW;AAChC,QAAI,KAAK,QAAQ;AACjB,QAAI,QAAQ,MAAM;AAClB,eAAW,QAAQ,QAAQ;AACzB,YAAM,MAAM,KAAK,IAAI,iBAAiB;AACtC,UAAI,OAAO;AACX,UAAI,UAAU,QAAQ,OAAO;AAC7B,YAAM,IAAI,KAAK,IAAI,WAAW;AAC9B,QAAE,KAAK,QAAQ,MAAM,OAAO;AAC5B,UAAI,QAAQ,CAAC;AACb,QAAE,QAAQ,GAAG;AACb,UAAI,MAAM;AAAA,IACZ;AACA,QAAI,KAAK,gBAAgB,KAAK,KAAK,IAAI,aAAa,CAAC;AAAA,EACvD;AACF;AAGO,IAAM,QAAQ,IAAI,SAAS;;;AC7GlC,IAAI,SAA8B;AAElC,IAAM,WAAW;AACjB,IAAM,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAYZ,SAAS,cAAoB;AAC3B,MAAI,OAAO,aAAa,eAAe,SAAS,eAAe,QAAQ,EAAG;AAC1E,QAAM,IAAI,SAAS,cAAc,OAAO;AACxC,IAAE,KAAK;AACP,IAAE,cAAc;AAChB,WAAS,KAAK,YAAY,CAAC;AAC7B;AAEA,IAAI,OAA2B;AAExB,SAAS,eAAe,IAAuB;AACpD,SAAO;AACT;AAGO,SAAS,WAAW,MAAgC;AACzD,MAAI,OAAO,aAAa,aAAa;AACnC,WAAO,EAAE,QAAQ;AAAA,IAAC,GAAG,SAAS,KAA+B;AAAA,EAC/D;AACA,cAAY;AACZ,aAAW;AAEX,QAAM,QAAQ,SAAS,cAAc,KAAK;AAC1C,QAAM,YAAY,WAAW,KAAK,QAAQ,QAAQ,KAAK,MAAM,GAAG,KAAK,YAAY,MAAM,KAAK,YAAY,EAAE;AAC1G,QAAM,OAAO,SAAS,cAAc,KAAK;AACzC,OAAK,YAAY;AAEjB,MAAI,KAAK,OAAO;AACd,UAAM,IAAI,SAAS,cAAc,IAAI;AACrC,MAAE,cAAc,KAAK;AACrB,SAAK,YAAY,CAAC;AAAA,EACpB;AACA,MAAI,KAAK,MAAM;AACb,UAAM,IAAI,SAAS,cAAc,KAAK;AACtC,MAAE,YAAY;AACd,MAAE,YAAY,KAAK;AACnB,SAAK,YAAY,CAAC;AAAA,EACpB;AAEA,QAAM,UAAU,KAAK,WAAW,CAAC;AACjC,MAAI,MAAM,KAAK,IAAI,GAAG,QAAQ,UAAU,CAAC,MAAM,EAAE,OAAO,CAAC;AACzD,MAAI,MAAM,EAAG,OAAM;AACnB,QAAM,QAA6B,CAAC;AACpC,MAAI,QAAQ,QAAQ;AAClB,UAAM,OAAO,SAAS,cAAc,KAAK;AACzC,SAAK,YAAY;AACjB,YAAQ,QAAQ,CAAC,GAAG,MAAM;AACxB,YAAM,MAAM,SAAS,cAAc,QAAQ;AAC3C,UAAI,YAAY,UAAU,EAAE,UAAU,aAAa,EAAE;AACrD,UAAI,cAAc,EAAE;AACpB,UAAI,iBAAiB,SAAS,MAAM,EAAE,SAAS,CAAC;AAChD,UAAI,iBAAiB,cAAc,MAAM,OAAO,CAAC,CAAC;AAClD,WAAK,YAAY,GAAG;AACpB,YAAM,KAAK,GAAG;AAAA,IAChB,CAAC;AACD,SAAK,YAAY,IAAI;AAAA,EACvB;AAEA,WAAS,OAAO,GAAiB;AAC/B,WAAO,IAAI,MAAM,UAAU,MAAM;AACjC,UAAM,QAAQ,CAAC,IAAI,MAAM,GAAG,UAAU,OAAO,OAAO,MAAM,GAAG,CAAC;AAAA,EAChE;AACA,MAAI,MAAM,OAAQ,QAAO,GAAG;AAE5B,QAAM,QAAQ,CAAC,MAAqB;AAClC,QAAI,CAAC,MAAM,OAAQ;AACnB,QAAI,EAAE,SAAS,aAAa;AAAE,aAAO,MAAM,CAAC;AAAG,QAAE,eAAe;AAAA,IAAG,WAC1D,EAAE,SAAS,WAAW;AAAE,aAAO,MAAM,CAAC;AAAG,QAAE,eAAe;AAAA,IAAG,WAC7D,EAAE,SAAS,WAAW,EAAE,SAAS,SAAS;AAAE,cAAQ,GAAG,GAAG,SAAS;AAAG,QAAE,eAAe;AAAA,IAAG;AAAA,EACrG;AACA,WAAS,iBAAiB,WAAW,KAAK;AAE1C,QAAM,YAAY,IAAI;AACtB,GAAC,QAAQ,SAAS,MAAM,YAAY,KAAK;AAEzC,QAAM,SAAuB;AAAA,IAC3B,SAAS;AAAA,IACT,QAAQ;AACN,eAAS,oBAAoB,WAAW,KAAK;AAC7C,YAAM,OAAO;AACb,UAAI,WAAW,OAAQ,UAAS;AAAA,IAClC;AAAA,EACF;AACA,WAAS;AACT,SAAO;AACT;AAEO,SAAS,aAAmB;AACjC,UAAQ,MAAM;AAChB;;;ACrHA,IAAM,MAAM;AACZ,IAAM,WAAqB,EAAE,QAAQ,KAAK,OAAO,KAAK,KAAK,KAAK,OAAO,OAAO,YAAY,OAAO,eAAe,MAAM;AAItH,IAAM,gBAAN,MAAoB;AAAA,EACV;AAAA,EACA,OAAO,oBAAI,IAAS;AAAA,EAE5B,cAAc;AACZ,SAAK,QAAQ,KAAK,KAAK;AACvB,SAAK,YAAY;AAAA,EACnB;AAAA,EAEA,MAAgB;AACd,WAAO,EAAE,GAAG,KAAK,MAAM;AAAA,EACzB;AAAA,EAEA,IAAI,OAAgC;AAClC,SAAK,QAAQ,EAAE,GAAG,KAAK,OAAO,GAAG,MAAM;AACvC,SAAK,KAAK;AACV,SAAK,YAAY;AACjB,eAAW,MAAM,KAAK,KAAM,IAAG,KAAK,IAAI,CAAC;AAAA,EAC3C;AAAA,EAEA,UAAU,IAAqB;AAC7B,SAAK,KAAK,IAAI,EAAE;AAChB,WAAO,MAAM,KAAK,KAAK,OAAO,EAAE;AAAA,EAClC;AAAA,EAEQ,cAAoB;AAC1B,UAAM,WAAW,EAAE,QAAQ,KAAK,MAAM,QAAQ,OAAO,KAAK,MAAM,OAAO,KAAK,KAAK,MAAM,KAAK,OAAO,KAAK,MAAM,MAAM,CAAC;AAAA,EACvH;AAAA,EAEQ,OAAiB;AACvB,QAAI;AACF,YAAM,MAAM,OAAO,iBAAiB,eAAe,aAAa,QAAQ,GAAG;AAC3E,UAAI,IAAK,QAAO,EAAE,GAAG,UAAU,GAAG,KAAK,MAAM,GAAG,EAAE;AAAA,IACpD,QAAQ;AAAA,IAER;AACA,WAAO,EAAE,GAAG,SAAS;AAAA,EACvB;AAAA,EACQ,OAAa;AACnB,QAAI;AACF,mBAAa,QAAQ,KAAK,KAAK,UAAU,KAAK,KAAK,CAAC;AAAA,IACtD,QAAQ;AAAA,IAER;AAAA,EACF;AACF;AAEO,IAAM,WAAW,IAAI,cAAc;AAGnC,SAAS,mBAAyB;AACvC,MAAI,OAAO,aAAa,YAAa;AACrC,QAAM,MAAM;AACZ,QAAM,KAAK,SAAS;AACpB,MAAI,SAAS,qBAAqB,IAAI,yBAAyB;AAC7D,KAAC,SAAS,kBAAkB,IAAI,uBAAuB,KAAK,QAAQ;AAAA,EACtE,OAAO;AACL,KAAC,GAAG,qBAAqB,GAAG,0BAA0B,KAAK,EAAE;AAAA,EAC/D;AACF;;;AC9DO,IAAM,QAAN,MAAY;AAAA,EACT,SAAS;AAAA,EACT;AAAA,EACA;AAAA,EAER,YAAY,OAAqB,CAAC,GAAG;AACnC,SAAK,OAAO;AACZ,SAAK,aAAa,CAAC,MAAqB;AACtC,UAAI,EAAE,SAAS,UAAU;AACvB,UAAE,eAAe;AACjB,aAAK,OAAO;AAAA,MACd;AAAA,IACF;AACA,QAAI,OAAO,aAAa,YAAa,UAAS,iBAAiB,WAAW,KAAK,UAAU;AAAA,EAC3F;AAAA,EAEA,IAAI,WAAoB;AACtB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,SAAe;AACb,SAAK,SAAS,KAAK,OAAO,IAAI,KAAK,MAAM;AAAA,EAC3C;AAAA,EAEA,QAAc;AACZ,QAAI,KAAK,OAAQ;AACjB,SAAK,SAAS;AACd,UAAM,KAAK,GAAG;AACd,SAAK,KAAK,UAAU,IAAI;AACxB,SAAK,OAAO;AAAA,EACd;AAAA,EAEA,SAAe;AACb,QAAI,CAAC,KAAK,OAAQ;AAClB,SAAK,SAAS;AACd,eAAW;AACX,SAAK,KAAK,UAAU,KAAK;AAAA,EAC3B;AAAA,EAEQ,SAAe;AACrB,UAAM,IAAI,SAAS,IAAI;AACvB,UAAM,MAAM,CAAC,OAAe,MAAc,GAAG,KAAK,KAAK,KAAK,MAAM,IAAI,GAAG,CAAC;AAC1E,eAAW;AAAA,MACT,OAAO,KAAK,KAAK,SAAS;AAAA,MAC1B,MACE,+DACG,IAAI,UAAU,EAAE,MAAM,CAAC,SAAM,IAAI,SAAS,EAAE,KAAK,CAAC,SAAM,IAAI,OAAO,EAAE,GAAG,CAAC;AAAA,MAE9E,SAAS;AAAA,QACP,EAAE,OAAO,UAAU,SAAS,MAAM,UAAU,MAAM,KAAK,OAAO,EAAE;AAAA,QAChE,EAAE,OAAO,EAAE,QAAQ,eAAe,YAAY,UAAU,MAAM;AAAE,mBAAS,IAAI,EAAE,OAAO,CAAC,SAAS,IAAI,EAAE,MAAM,CAAC;AAAG,eAAK,OAAO;AAAA,QAAG,EAAE;AAAA,QACjI,EAAE,OAAO,kBAAa,UAAU,MAAM;AAAE,gBAAM,IAAI,KAAK,IAAI,GAAG,SAAS,IAAI,EAAE,QAAQ,GAAG,IAAI;AAAM,mBAAS,IAAI,EAAE,OAAO,IAAI,IAAI,IAAI,EAAE,CAAC;AAAG,eAAK,OAAO;AAAA,QAAG,EAAE;AAAA,QAC3J,EAAE,OAAO,kBAAkB,UAAU,MAAM,iBAAiB,EAAE;AAAA,QAC9D,GAAI,KAAK,KAAK,YAAY,CAAC,EAAE,OAAO,WAAW,UAAU,MAAM;AAAE,eAAK,OAAO;AAAG,eAAK,KAAK,UAAW;AAAA,QAAG,EAAE,CAAC,IAAI,CAAC;AAAA,QAChH,GAAI,KAAK,KAAK,SAAS,CAAC,EAAE,OAAO,QAAQ,UAAU,MAAM;AAAE,eAAK,OAAO;AAAG,eAAK,KAAK,OAAQ;AAAA,QAAG,EAAE,CAAC,IAAI,CAAC;AAAA,MACzG;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,UAAgB;AACd,QAAI,OAAO,aAAa,YAAa,UAAS,oBAAoB,WAAW,KAAK,UAAU;AAC5F,eAAW;AAAA,EACb;AACF;;;ACrCO,SAAS,MACd,QACA,UAAwB,CAAC,GACN;AACnB,QAAM,WAAW,QAAQ,YAAY;AACrC,QAAM,UAAU,QAAQ,WAAW;AACnC,QAAM,QAAQ,OAAO,QAAQ,QAAQ,KAAK;AAE1C,MAAI,OAAO,MAAM,KAAK,EAAG,QAAO,EAAE,UAAU,MAAM,MAAM,CAAC,GAAG,OAAO,GAAG,OAAO,GAAG,WAAW,MAAM;AAMjG,MAAI,WAAoB,CAAC,EAAE,OAAO,OAAO,MAAM,CAAC,EAAE,CAAC;AACnD,QAAM,OAAO,oBAAI,IAAY,CAAC,OAAO,IAAI,KAAK,CAAC,CAAC;AAChD,MAAI,QAAQ;AAEZ,WAAS,QAAQ,GAAG,QAAQ,YAAY,SAAS,SAAS,GAAG,SAAS;AACpE,UAAM,OAAgB,CAAC;AACvB,eAAW,EAAE,OAAO,KAAK,KAAK,UAAU;AACtC,iBAAW,QAAQ,OAAO,MAAM,KAAK,GAAG;AACtC,YAAI,SAAS,QAAS,QAAO,EAAE,UAAU,OAAO,OAAO,WAAW,KAAK;AACvE;AACA,cAAM,QAAQ,OAAO,MAAM,OAAO,IAAI;AACtC,YAAI,OAAO,SAAS,KAAK,EAAG;AAC5B,YAAI,OAAO,MAAM,KAAK,GAAG;AACvB,iBAAO,EAAE,UAAU,MAAM,MAAM,CAAC,GAAG,MAAM,IAAI,GAAG,OAAO,QAAQ,GAAG,OAAO,WAAW,MAAM;AAAA,QAC5F;AACA,cAAM,IAAI,OAAO,IAAI,KAAK;AAC1B,YAAI,CAAC,KAAK,IAAI,CAAC,GAAG;AAChB,eAAK,IAAI,CAAC;AACV,eAAK,KAAK,EAAE,OAAO,OAAO,MAAM,CAAC,GAAG,MAAM,IAAI,EAAE,CAAC;AAAA,QACnD;AAAA,MACF;AAAA,IACF;AACA,eAAW;AAAA,EACb;AACA,SAAO,EAAE,UAAU,OAAO,OAAO,WAAW,SAAS,SAAS,EAAE;AAClE;AAMO,SAAS,eACd,QACA,UAAwB,CAAC,GACN;AACnB,QAAM,SAAS,MAAM,QAAQ,OAAO;AACpC,MAAI,CAAC,OAAO,UAAU;AACpB,UAAM,IAAI;AAAA,MACR,gBAAgB,QAAQ,SAAS,CAAC,8BACnB,OAAO,KAAK,SAAS,OAAO,YAAY,kDAA6C,EAAE;AAAA,IACxG;AAAA,EACF;AACA,SAAO;AACT;;;ACvFO,SAAS,OAAO,WAAyB,KAAwD;AACtG,QAAM,QAAQ,UAAU;AACxB,QAAM,SAAmB,CAAC;AAC1B,WAAS,IAAI,GAAG,IAAI,IAAI,OAAO,QAAQ,KAAK;AAC1C,UAAM,KAAK,aAAa,KAAK,CAAC,CAAC;AAC/B,WAAO,KAAK,MAAM,KAAK,CAAC;AAAA,EAC1B;AACA,SAAO,EAAE,WAAW,MAAM,KAAK,GAAG,OAAO;AAC3C;AAWO,SAAS,mBAAmB,WAAyB,KAAkC;AAC5F,QAAM,IAAI,OAAO,WAAW,GAAG;AAC/B,QAAM,IAAI,OAAO,WAAW,GAAG;AAC/B,MAAI,aAAa;AACjB,WAAS,IAAI,GAAG,IAAI,EAAE,OAAO,QAAQ,KAAK;AACxC,QAAI,EAAE,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG;AAC/B,mBAAa;AACb;AAAA,IACF;AAAA,EACF;AACA,SAAO;AAAA,IACL,IAAI,eAAe,MAAM,EAAE,cAAc,EAAE;AAAA,IAC3C,QAAQ,IAAI,OAAO;AAAA,IACnB;AAAA,IACA,WAAW,EAAE;AAAA,EACf;AACF;AAGO,SAAS,oBAAoB,WAAyB,KAAkC;AAC7F,QAAM,SAAS,mBAAmB,WAAW,GAAG;AAChD,MAAI,CAAC,OAAO,IAAI;AACd,UAAM,IAAI;AAAA,MACR,iEAA4D,OAAO,UAAU,OACrE,OAAO,MAAM;AAAA,IACvB;AAAA,EACF;AACA,SAAO;AACT;AAOO,SAAS,qBACd,WACA,KACA,QAC+C;AAC/C,QAAM,WAAW,UAAU;AAC3B,WAAS,IAAI,GAAG,IAAI,QAAQ,IAAK,UAAS,KAAK,aAAa,KAAK,CAAC,CAAC;AACnE,QAAM,OAAO,SAAS,SAAS;AAE/B,QAAM,WAAW,UAAU;AAC3B,WAAS,QAAQ,IAAI;AAErB,WAAS,IAAI,QAAQ,IAAI,IAAI,OAAO,QAAQ,KAAK;AAC/C,aAAS,KAAK,aAAa,KAAK,CAAC,CAAC;AAClC,aAAS,KAAK,aAAa,KAAK,CAAC,CAAC;AAAA,EACpC;AACA,QAAM,QAAQ,SAAS,KAAK;AAC5B,QAAM,QAAQ,SAAS,KAAK;AAC5B,SAAO,EAAE,IAAI,UAAU,OAAO,OAAO,MAAM;AAC7C;;;ACtEO,SAAS,KAAK,SAAmB,QAAyB;AAC/D,SAAO,EAAE,SAAS,OAAO;AAC3B;AAEO,SAAS,KAAK,QAAyB;AAC5C,SAAO,EAAE,SAAS,CAAC,GAAG,OAAO;AAC/B;AAUO,SAAS,oBAAoB,OAAc,QAAsC;AACtF,QAAM,SAAoC,CAAC;AAC3C,MAAI,QAAQ;AACZ,aAAW,OAAO,QAAQ;AACxB,aAAS,IAAI,GAAG,IAAI,IAAI,QAAQ,IAAK,OAAM,KAAK,IAAI,WAAW,CAAC,CAAC;AACjE,aAAS,IAAI;AACb,WAAO,KAAK,MAAM,MAAM,CAAC;AAAA,EAC3B;AACA,SAAO,EAAE,aAAa,OAAO,WAAW,MAAM,KAAK,GAAG,OAAO;AAC/D;AAGO,SAAS,KAAK,OAAc,QAAgB,UAAoB,CAAC,GAAS;AAC/E,WAAS,IAAI,GAAG,IAAI,QAAQ,IAAK,OAAM,KAAK,OAAO;AACrD;;;ACnBO,SAAS,gBAAyB;AACvC,SAAO,OAAO,aAAa,eAAe,IAAI,gBAAgB,SAAS,MAAM,EAAE,IAAI,SAAS;AAC9F;AAGO,SAAS,eAAe,QAAqC;AAClE,QAAM,MAAoB;AAAA,IACxB,KAAK,QAAQ,UAAU,CAAC,GAAG;AACzB,aAAO,UAAU,IAAI;AACrB,eAAS,IAAI,GAAG,IAAI,QAAQ,IAAK,QAAO,SAAS,OAAO;AACxD,aAAO,OAAO,MAAM,MAAM;AAAA,IAC5B;AAAA,IACA,OAAO,MAAM,OAAO,MAAM,MAAM;AAAA,IAChC,MAAM,MAAM,OAAO,MAAM,KAAK;AAAA,IAC9B,MAAM,MAAM,OAAO,UAAU;AAAA,IAC7B,MAAM,KAAK,MAAM;AACf,YAAM,MAAM,OAAO,UAAU;AAC7B,UAAI;AACF,cAAM,MAAM,MAAM,MAAM,WAAW;AAAA,UACjC,QAAQ;AAAA,UACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,UAC9C,MAAM,KAAK,UAAU,EAAE,MAAM,IAAI,CAAC;AAAA,QACpC,CAAC;AACD,eAAO,IAAI;AAAA,MACb,QAAQ;AACN,eAAO;AAAA,MACT;AAAA,IACF;AAAA,IACA,IAAI,MAAM,MAAM;AACd,eAAS,cAAc,IAAI,cAAc,MAAM,EAAE,MAAM,SAAS,KAAK,CAAC,CAAC;AAAA,IACzE;AAAA,IACA,IAAI,QAAQ;AACV,aAAO,OAAO;AAAA,IAChB;AAAA,EACF;AACA,EAAC,WAAoD,UAAU;AAC/D,SAAO;AACT;;;AC5CO,SAAS,eAAe,QAAiC;AAC9D,QAAM,MAAkB,CAAC;AACzB,aAAW,OAAO,QAAQ;AACxB,UAAMC,KAAI,IAAI,UAAU;AACxB,UAAMC,QAAO,IAAI,QAAQ,CAAC;AAC1B,aAAS,IAAI,GAAG,IAAID,IAAG,IAAK,KAAI,KAAK,MAAM,KAAK,IAAI,QAAQ,CAAC,GAAGC,OAAM,GAAG,IAAI,KAAK,IAAI,CAAC,GAAGA,KAAI,CAAC;AAAA,EACjG;AACA,SAAO;AACT;AAaO,SAAS,MAAM,OAAc,QAAqB,OAAkE;AACzH,MAAI,SAAS;AACb,aAAW,KAAK,eAAe,MAAM,GAAG;AACtC,QAAI,SAAS,MAAM,MAAM,MAAM,CAAC,EAAG,QAAO,EAAE,QAAQ,SAAS,KAAK;AAClE,UAAM,KAAK,CAAC;AACZ;AAAA,EACF;AACA,SAAO,EAAE,QAAQ,SAAS,QAAQ,MAAM,MAAM,MAAM,CAAC,IAAI,MAAM;AACjE;;;AClBO,SAAS,cAAoD,MAAc,OAA8D;AAC9I,MAAI,IAAI;AACR,MAAI,SAAS;AACb,MAAI,MAA+B,CAAC;AAEpC,QAAM,KAAK,CAAC,UAA2B;AACrC,UAAM,MAAgB,CAAC;AACvB,UAAM,OAAO,KAAK,CAAC;AACnB,QAAI,CAAC,KAAM,QAAO;AAClB;AACA,UAAM,MAAc;AAAA,MAClB,IAAI,SAAS;AACX,eAAO;AAAA,MACT;AAAA,MACA;AAAA,MACA,OAAO;AACL;AACA,iBAAS;AACT,cAAM,CAAC;AAAA,MACT;AAAA,MACA,QAAQ;AACN,iBAAS;AACT,cAAM,CAAC;AAAA,MACT;AAAA,IACF;AACA,UAAM,OAAO,MAAM,KAAK,IAAI;AAC5B,QAAI,CAAC,KAAM,OAAM,IAAI,MAAM,wCAAwC,KAAK,IAAI,GAAG;AAC/E,SAAK,MAAM,OAAO,KAAK,GAAG;AAC1B,WAAO;AAAA,EACT;AACA,QAAM,MAAM;AACZ,MAAI,YAAY,MAAM;AACtB,MAAI,OAAO,MAAM,KAAK,KAAK;AAC3B,SAAO;AACT;AAGO,SAAS,QAAQ,IAAY,IAAY,IAAY,IAAY,KAAe,OAAO,GAAS;AACrG,MAAI,KAAK,KAAK,KAAM,KAAI,KAAK,OAAO;AAAA,WAC3B,KAAK,KAAK,KAAM,KAAI,KAAK,MAAM;AACxC,MAAI,KAAK,KAAK,KAAM,KAAI,KAAK,MAAM;AAAA,WAC1B,KAAK,KAAK,KAAM,KAAI,KAAK,IAAI;AACxC;;;ACvDO,SAAS,eAAe,OAAc,QAAkC;AAC7E,QAAM,MAAoB,CAAC,MAAM,MAAM,CAAC;AACxC,aAAW,KAAK,QAAQ;AACtB,UAAM,KAAK,CAAC;AACZ,QAAI,KAAK,MAAM,MAAM,CAAC;AAAA,EACxB;AACA,SAAO;AACT;AAGO,SAAS,WAAW,UAAwB,MAA0C;AAC3F,WAAS,IAAI,GAAG,IAAI,SAAS,QAAQ,IAAK,KAAI,KAAK,SAAS,CAAC,CAAC,EAAG,QAAO;AACxE,SAAO;AACT;AAGO,SAAS,OAAO,UAAwB,KAAwB;AACrE,SAAO,SAAS,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC;AACnC;AAGO,SAAS,aAAa,UAAwB,KAAuB;AAC1E,QAAM,MAAgB,CAAC;AACvB,WAAS,IAAI,GAAG,IAAI,SAAS,QAAQ,IAAK,KAAI,SAAS,CAAC,EAAE,GAAG,MAAM,SAAS,IAAI,CAAC,EAAE,GAAG,EAAG,KAAI,KAAK,CAAC;AACnG,SAAO;AACT;AAGO,SAAS,YAAY,QAAkB,KAAoB,QAAQ,GAAY;AACpF,WAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;AACtC,QAAI,QAAQ,OAAO,OAAO,CAAC,IAAI,OAAO,IAAI,CAAC,IAAI,QAAQ,OAAO,CAAC,IAAI,OAAO,IAAI,CAAC,IAAI,MAAO,QAAO;AAAA,EACnG;AACA,SAAO;AACT;AAOO,SAAS,aAAa,QAA4B;AACvD,MAAI,OAAO,WAAW,EAAG,QAAO;AAChC,SAAO,OAAO,OAAO,CAAC,MAAM,EAAE,SAAS,CAAC,EAAE,SAAS,OAAO;AAC5D;AAGO,SAAS,YAAY,aAAuB,aAA6B;AAC9E,QAAM,MAAM,CAAC,GAAG,GAAG,aAAa,WAAW;AAC3C,MAAI,QAAQ;AACZ,WAAS,IAAI,GAAG,IAAI,IAAI,QAAQ,IAAK,SAAQ,KAAK,IAAI,OAAO,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,CAAC;AAChF,SAAO;AACT;;;AC1CO,SAAS,gBAAgB,OAAc,QAAoB,MAAgC;AAChG,QAAM,SAAS,KAAK,IAAI,GAAG,KAAK,UAAU,EAAE;AAC5C,QAAM,QAAQ,KAAK,IAAI,GAAG,KAAK,KAAK,OAAO,UAAU,SAAS,EAAE,CAAC;AACjE,QAAM,QAA4C,CAAC,EAAE,OAAO,GAAG,OAAO,mBAAmB,MAAM,OAAO,CAAC,EAAE,CAAC;AAC1G,WAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;AACtC,UAAM,KAAK,OAAO,CAAC,CAAC;AACpB,SAAK,IAAI,KAAK,UAAU,KAAK,MAAM,OAAO,SAAS,GAAG;AACpD,YAAM,KAAK,EAAE,OAAO,IAAI,GAAG,OAAO,mBAAmB,MAAM,OAAO,CAAC,EAAE,CAAC;AAAA,IACxE;AAAA,EACF;AAEA,QAAM,OAAO,KAAK,IAAI,GAAG,KAAK,QAAQ,CAAC;AACvC,QAAM,KAAK,KAAK,cAAc;AAC9B,QAAM,KAAK,KAAK,MAAO,KAAK,KAAK,SAAU,KAAK,KAAK;AACrD,QAAM,SAAS;AACf,QAAM,MAAM;AACZ,QAAM,QAAQ,KAAK;AACnB,QAAM,QAAQ,KAAK,SAAS;AAC5B,QAAM,OAAO,KAAK,KAAK,MAAM,SAAS,IAAI;AAC1C,QAAM,SAAS,OAAO,QAAQ;AAC9B,QAAM,SAAS,OAAO,QAAQ;AAC9B,QAAM,KAAK,KAAK,cAAc;AAE9B,QAAM,QAAQ,MACX,IAAI,CAAC,GAAG,MAAM;AACb,UAAM,IAAI,MAAO,IAAI,OAAQ;AAC7B,UAAM,IAAI,MAAM,KAAK,MAAM,IAAI,IAAI,IAAI;AACvC,WACE,2BAA2B,CAAC,IAAI,CAAC,kBAClB,EAAE,aAAa,EAAE,kBAAkB,KAAK,KAAK,IAAI,KAAK,MAAM,8BAC/C,KAAK,KAAK,aAAa,KAAK,MAAM,WAAW,EAAE,QAC3E,EAAE,QACF,kCAC4B,EAAE,aAAa,EAAE,0DACjC,KAAK,CAAC,QAAQ,KAAK,EAAE,+EAC5B,EAAE,KAAK,UAAO,EAAE,QAAQ,IAAI,QAAQ,CAAC,CAAC;AAAA,EAG/C,CAAC,EACA,KAAK,EAAE;AAEV,SACE,wDAAwD,MAAM,IAAI,MAAM,YAAY,MAAM,aAAa,MAAM,8BACjF,MAAM,aAAa,MAAM,uBACrD,QACA;AAEJ;;;AC7CO,IAAM,QAAN,MAAoC;AAAA,EAChC;AAAA,EACA;AAAA,EACA,QAAQ,IAAI,WAAW;AAAA,EACvB,SAAS,IAAI,SAAqB;AAAA,EAClC,YAAY,oBAAI,IAAqB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAO9C,QAAiC,CAAC;AAAA,EACzB;AAAA,EACA;AAAA,EAET;AAAA,EACA,eAAgC;AAAA,EAExB;AAAA,EACA,YAAoB,CAAC;AAAA,EACrB,UAAU;AAAA,EAElB,YAAY,SAAsB,CAAC,GAAG;AACpC,SAAK,OAAO,OAAO,QAAQ;AAC3B,SAAK,MAAM,IAAI,IAAI,KAAK,IAAI;AAC5B,SAAK,QAAQ,IAAI,MAAM,OAAO,KAAK;AACnC,SAAK,QAAQ,OAAO,SAAS;AAC7B,SAAK,SAAS,OAAO,UAAU;AAC/B,SAAK,OAAO,IAAI,KAAK,EAAE,MAAM,OAAO,CAAC;AAAA,EACvC;AAAA,EAEA,IAAI,OAAe;AACjB,WAAO,KAAK,MAAM;AAAA,EACpB;AAAA,EACA,IAAI,QAAgB;AAClB,WAAO,KAAK,MAAM;AAAA,EACpB;AAAA;AAAA,EAGA,QAAQ,MAAkB;AACxB,QAAI,KAAK,KAAM,MAAK,KAAK,SAAS;AAClC,SAAK,OAAO;AACZ,SAAK,UAAU;AAAA,EACjB;AAAA,EAEA,YAAY,MAAkB;AAC5B,SAAK,UAAU,KAAK,IAAI;AAAA,EAC1B;AAAA,EAEQ,gBAAsB;AAC5B,QAAI,CAAC,KAAK,SAAS;AACjB,WAAK,KAAK,UAAU,IAAI;AACxB,WAAK,UAAU;AAAA,IACjB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,KAAK,cAAgC,CAAC,GAAS;AAC7C,SAAK,cAAc;AACnB,SAAK,MAAM,WAAW,WAAW;AACjC,SAAK,KAAK,WAAW,KAAK,MAAM,EAAE;AAClC,SAAK,UAAU;AACf,SAAK,MAAM,KAAK;AAAA,EAClB;AAAA;AAAA,EAGA,QAAQ,QAAgB,cAAgC,CAAC,GAAW;AAClE,UAAM,QAAQ,KAAK,MAAM,QAAQ,MAAM;AACvC,aAAS,IAAI,GAAG,IAAI,OAAO,IAAK,MAAK,KAAK,WAAW;AACrD,WAAO;AAAA,EACT;AAAA,EAEQ,YAAkB;AACxB,QAAI,KAAK,UAAU,WAAW,EAAG;AACjC,UAAM,IAAI,KAAK;AACf,SAAK,YAAY,CAAC;AAClB,eAAW,QAAQ,GAAG;AACpB,WAAK,SAAS;AACd,WAAK,QAAQ,YAAY,IAAI;AAC7B,UAAI,KAAK,iBAAiB,KAAM,MAAK,eAAe;AAAA,IACtD;AAAA,EACF;AAAA;AAAA;AAAA,EAIA,gBAA2B;AACzB,QAAI,CAAC,KAAK,aAAc,QAAO;AAC/B,UAAM,MAAM,KAAK;AAEjB,UAAM,WAAW,IAAI,eAAe;AACpC,UAAM,WAAW,iBAAiB,cAAc,EAAE,GAAG,KAAK,QAAQ,GAAG,GAAG,KAAK,SAAS,EAAE,GAAG,GAAG,EAAE,GAAG,IAAI,MAAM,GAAG,IAAI,KAAK,CAAC,GAAG,gBAAgB,QAAQ,CAAC;AACtJ,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,SAAwB;AACtB,SAAK,cAAc;AACnB,UAAM,MAAqB,CAAC;AAC5B,SAAK,KAAK,YAAY,KAAK,KAAK,cAAc,CAAC;AAC/C,WAAO;AAAA,EACT;AAAA;AAAA;AAAA,EAIA,OAAe;AACb,WAAO,UAAU;AAAA,MACf,MAAM,KAAK;AAAA,MACX,KAAK,KAAK,IAAI,SAAS;AAAA,MACvB,OAAO,KAAK,MAAM,SAAS;AAAA,MAC3B,OAAO,KAAK,MAAM,SAAS;AAAA,MAC3B,OAAO,KAAK;AAAA,MACZ,MAAM,KAAK,KAAK,UAAU;AAAA,IAC5B,CAAC;AAAA,EACH;AAAA;AAAA,EAGA,WAA0B;AACxB,WAAO;AAAA,MACL,MAAM,KAAK;AAAA,MACX,KAAK,KAAK,IAAI,SAAS;AAAA,MACvB,OAAO,KAAK,MAAM,SAAS;AAAA,MAC3B,OAAO,KAAK,MAAM,SAAS;AAAA,MAC3B,OAAO,gBAAgB,KAAK,KAAK;AAAA,MACjC,MAAM,KAAK,KAAK,UAAU;AAAA,IAC5B;AAAA,EACF;AAAA;AAAA,EAGA,QAAQ,MAA2B;AACjC,SAAK,OAAO,KAAK;AACjB,SAAK,IAAI,SAAS,KAAK,GAAG;AAC1B,SAAK,MAAM,SAAS,KAAK,KAAK;AAC9B,SAAK,MAAM,SAAS,KAAK,KAAK;AAC9B,SAAK,QAAQ,gBAAgB,KAAK,KAAK;AACvC,iBAAa,GAAS;AACtB,SAAK,QAAQ,gBAAgB,KAAK,IAAI,CAAC;AACvC,SAAK,cAAc;AAAA,EACrB;AAAA;AAAA,EAGA,QAAiC;AAC/B,WAAO;AAAA,MACL,OAAO,KAAK;AAAA,MACZ,MAAM,KAAK;AAAA,MACX,MAAM,KAAK,KAAK;AAAA,MAChB,OAAO,KAAK,KAAK,MAAM,QAAQ,EAAE,SAAS,KAAK,KAAK,MAAM,MAAM,EAAE;AAAA,IACpE;AAAA,EACF;AACF;;;AC3JO,SAAS,WAAW,KAA+H;AACxJ,SAAO;AAAA,IACL,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,YAAY;AAAA,IACZ,UAAU;AAAA,IACV,GAAG;AAAA,EACL;AACF;AAGO,SAAS,YAAY,KAAqB,cAA8B;AAC7E,QAAM,QAAQ,IAAI,MAAM;AAAA,IACtB,MAAM,gBAAgB,IAAI,QAAQ;AAAA,IAClC,OAAO,IAAI,SAAS;AAAA,IACpB,QAAQ,IAAI,UAAU;AAAA,IACtB,OAAO,IAAI;AAAA,EACb,CAAC;AACD,QAAM,QAAQ,IAAI,MAAM,KAAK,CAAC;AAC9B,MAAI,IAAI,OAAO;AAEb,IAAC,MAA8D,QAAQ,MAAM,IAAI,MAAO,KAAK;AAAA,EAC/F;AACA,SAAO;AACT;AAGO,SAAS,aAAa,KAA+B;AAC1D,SAAO,IAAI,YAAY;AACzB;AAaO,SAAS,YAAY,KAAqB,UAAqC;AACpF,QAAM,QAAQ,YAAY,GAAG;AAC7B,QAAM,SAAS,UAAU,UAAU,CAAC;AACpC,aAAW,KAAK,OAAQ,OAAM,KAAK,CAAC;AACpC,SAAO,EAAE,OAAO,MAAM,MAAM,KAAK,GAAG,OAAO,OAAO,OAAO;AAC3D;;;ACtCO,SAAS,WAAW,KAAqB,OAAoB,OAAmB,CAAC,GAAe;AACrG,QAAM,QAAQ,IAAI,SAAS;AAC3B,QAAM,SAAS,IAAI,UAAU;AAC7B,QAAM,aAAa,IAAI,cAAc;AAErC,MAAI,QAAQ,YAAY,GAAG;AAC3B,QAAM,WACJ,KAAK,aAAa,WACd,IAAI,iBAAiB,EAAE,OAAO,QAAQ,WAAW,CAAC,IAClD,IAAI,YAAY,EAAE,OAAO,QAAQ,WAAW,CAAC;AAEnD,QAAM,MAAM,WAAW,MAAM,MAAM,YAAY;AAC/C,WAAS,QAAQ,KAAK;AACtB,iBAAe,KAAK;AAEpB,QAAM,QAAQ,IAAI,eAAe,IAAI,YAAY,CAAC,GAAG,QAAQ;AAC7D,QAAM,UAAU,cAAc;AAG9B,QAAM,aAAa,MAAM;AACvB,UAAM,MAAM;AACZ,UAAM,IAAI,SAAS,IAAI;AACvB,UAAM,WAAW,CAAC;AAClB,WAAO,oBAAoB,eAAe,UAAU;AACpD,WAAO,oBAAoB,WAAW,UAAU;AAAA,EAClD;AACA,SAAO,iBAAiB,eAAe,UAAU;AACjD,SAAO,iBAAiB,WAAW,UAAU;AAE7C,QAAM,cAAc,MAAM,SAAS,KAAK,MAAM,OAAO,CAAC;AACtD,QAAM,UAAU,MAAM;AACpB,YAAQ,YAAY,GAAG;AACvB,gBAAY;AAAA,EACd;AAEA,QAAM,QACJ,KAAK,UAAU,QACX,OACA,IAAI,MAAM;AAAA,IACR,OAAO,IAAI;AAAA,IACX,WAAW,KAAK,aAAa;AAAA,IAC7B,SAAS,MAAM;AAAA,IAAC;AAAA,EAClB,CAAC;AAEP,MAAI,MAAM;AACV,MAAI,OAAO,YAAY,IAAI;AAC3B,QAAM,OAAO,CAAC,QAAgB;AAC5B,UAAM,KAAK,MAAM;AACjB,WAAO;AACP,QAAI,CAAC,WAAW,CAAE,OAAO,UAAW;AAClC,YAAM,QAAQ,MAAM,QAAQ,IAAI,MAAM,eAAe,CAAC;AACtD,UAAI,QAAQ,EAAG,OAAM,aAAa;AAAA,IACpC;AACA,gBAAY;AACZ,UAAM,sBAAsB,IAAI;AAAA,EAClC;AACA,QAAM,sBAAsB,IAAI;AAEhC,QAAM,SAAqB;AAAA,IACzB,IAAI,QAAQ;AACV,aAAO;AAAA,IACT;AAAA,IACA;AAAA,IACA;AAAA,IACA,OAAO;AACL,2BAAqB,GAAG;AACxB,YAAM,QAAQ;AACd,aAAO,QAAQ;AACf,eAAS,UAAU;AAAA,IACrB;AAAA,IACA;AAAA,EACF;AAEA,MAAI,SAAS;AACX,mBAAe;AAAA,MACb,IAAI,QAAQ;AACV,eAAO;AAAA,MACT;AAAA,MACA,UAAU,CAAC,UAAU,CAAC,MAAM;AAC1B,cAAM,KAAK,OAAO;AAClB,oBAAY;AAAA,MACd;AAAA,MACA,WAAW,MAAM,kBAAkB,MAAM,OAAO,GAAG,OAAO,QAAQ,UAAU;AAAA,MAC5E,WAAW,MAAM;AAAA,MAAC;AAAA,IACpB,CAAC;AAAA,EACH;AAEA,SAAO;AACT;;;ACxDO,IAAM,UAAU;",
|
|
6
|
-
"names": ["n", "n", "mix", "n", "dx", "dy", "n", "n", "n", "hold"]
|
|
3
|
+
"sources": ["../src/core/dmath.ts", "../src/core/math.ts", "../src/core/rng.ts", "../src/core/clock.ts", "../src/core/events.ts", "../src/core/hash.ts", "../src/scene/node.ts", "../src/scene/nodes.ts", "../src/scene/pool.ts", "../src/scene/tween.ts", "../src/scene/particles.ts", "../src/scene/floatingText.ts", "../src/scene/registry.ts", "../src/input/actions.ts", "../src/input/source.ts", "../src/physics/tilemap.ts", "../src/physics/aabb.ts", "../src/physics/platformer.ts", "../src/physics/spatialHash.ts", "../src/physics/raycast.ts", "../src/physics/rigidBody.ts", "../src/physics/rigidCollide.ts", "../src/physics/rigidJoints.ts", "../src/physics/rigidStep.ts", "../src/physics/rigidQueries.ts", "../src/render/commands.ts", "../src/render/svgString.ts", "../src/render/svg.ts", "../src/render/canvas.ts", "../src/render/headless.ts", "../src/render/nineSlice.ts", "../src/art/palette.ts", "../src/art/shapes.ts", "../src/art/texture.ts", "../src/art/font5.ts", "../src/art/bitmapFont.ts", "../src/art/autotile.ts", "../src/procgen/grid.ts", "../src/procgen/scatter.ts", "../src/procgen/cave.ts", "../src/procgen/terrain.ts", "../src/procgen/rooms.ts", "../src/audio/audio.ts", "../src/ui/overlay.ts", "../src/ui/settings.ts", "../src/ui/shell.ts", "../src/ui/transition.ts", "../src/verify/solver.ts", "../src/verify/determinism.ts", "../src/verify/playthrough.ts", "../src/verify/capture.ts", "../src/verify/driver.ts", "../src/verify/bot.ts", "../src/verify/layout.ts", "../src/verify/feel.ts", "../src/verify/filmstrip.ts", "../src/logic/fsm.ts", "../src/logic/random.ts", "../src/logic/graph.ts", "../src/logic/history.ts", "../src/persist/storage.ts", "../src/persist/codec.ts", "../src/persist/save.ts", "../src/content/dsl.ts", "../src/net/players.ts", "../src/net/protocol.ts", "../src/net/transport.ts", "../src/net/inputBuffer.ts", "../src/net/lockstep.ts", "../src/net/rollback.ts", "../src/net/room.ts", "../src/world.ts", "../src/app/game.ts", "../src/net/browser.ts", "../src/app/browser.ts", "../src/index.ts"],
|
|
4
|
+
"sourcesContent": ["// Deterministic transcendental math. JavaScript guarantees bit-exact results\n// across engines for +, -, *, /, Math.sqrt (IEEE-754 correctly rounded) \u2014 but\n// NOT for Math.sin/cos/atan2/pow/hypot/exp, which are implementation-defined\n// and may differ between V8, JSC, and SpiderMonkey. A cross-machine lockstep\n// game that touches them can desync even with identical input logs.\n//\n// These replacements are built from exactly-rounded ops only (fdlibm-style\n// polynomial kernels), so every engine computes bit-identical values. Sim code\n// MUST use these instead of the Math.* originals (enforced by\n// `npm run invariants`). Accuracy \u2248 1 ulp on game-scale inputs.\n\n// \u2500\u2500 argument reduction constants (\u03C0/2 split for Cody-Waite reduction) \u2500\u2500\nconst INV_PIO2 = 6.36619772367581382433e-1; // 2/\u03C0\nconst PIO2_HI = 1.57079632673412561417e0; // first 33 bits of \u03C0/2\nconst PIO2_LO = 6.07710050650619224932e-11; // \u03C0/2 \u2212 PIO2_HI\n\n// fdlibm kernel coefficients for sin/cos on |r| \u2264 \u03C0/4.\nconst S1 = -1.66666666666666324348e-1;\nconst S2 = 8.33333333332248946124e-3;\nconst S3 = -1.98412698298579493134e-4;\nconst S4 = 2.75573137070700676789e-6;\nconst S5 = -2.50507602534068634195e-8;\nconst S6 = 1.58969099521155010221e-10;\n\nconst C1 = 4.16666666666666019037e-2;\nconst C2 = -1.38888888888741095749e-3;\nconst C3 = 2.48015872894767294178e-5;\nconst C4 = -2.75573143513906633035e-7;\nconst C5 = 2.08757232129817482790e-9;\nconst C6 = -1.13596475577881948265e-11;\n\nfunction kSin(r: number): number {\n const z = r * r;\n return r + r * z * (S1 + z * (S2 + z * (S3 + z * (S4 + z * (S5 + z * S6)))));\n}\n\nfunction kCos(r: number): number {\n const z = r * r;\n return 1 - 0.5 * z + z * z * (C1 + z * (C2 + z * (C3 + z * (C4 + z * (C5 + z * C6)))));\n}\n\n/** Reduce x to r \u2208 [\u2212\u03C0/4, \u03C0/4] and quadrant n. Accurate for |x| \u2272 1e7 (plenty for game angles). */\nfunction reduce(x: number): { n: number; r: number } {\n const n = Math.round(x * INV_PIO2);\n const r = x - n * PIO2_HI - n * PIO2_LO;\n return { n: ((n % 4) + 4) % 4, r };\n}\n\n/** Deterministic sine (bit-identical on every JS engine). */\nexport function dsin(x: number): number {\n if (!Number.isFinite(x)) return NaN;\n const { n, r } = reduce(x);\n switch (n) {\n case 0:\n return kSin(r);\n case 1:\n return kCos(r);\n case 2:\n return -kSin(r);\n default:\n return -kCos(r);\n }\n}\n\n/** Deterministic cosine (bit-identical on every JS engine). */\nexport function dcos(x: number): number {\n if (!Number.isFinite(x)) return NaN;\n const { n, r } = reduce(x);\n switch (n) {\n case 0:\n return kCos(r);\n case 1:\n return -kSin(r);\n case 2:\n return -kCos(r);\n default:\n return kSin(r);\n }\n}\n\n// \u2500\u2500 atan / atan2 (fdlibm port) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nconst ATAN_HI = [4.63647609000806093515e-1, 7.85398163397448278999e-1, 9.82793723247329054082e-1, 1.570796326794896558e0];\nconst ATAN_LO = [2.26987774529616870924e-17, 3.06161699786838301793e-17, 1.39033110312309984516e-17, 6.12323399573676603587e-17];\nconst AT = [\n 3.33333333333329318027e-1, -1.99999999998764832476e-1, 1.42857142725034663711e-1, -1.1111110405462355788e-1,\n 9.09088713343650656196e-2, -7.69187620504482999495e-2, 6.66107313738753120669e-2, -5.83357013379057348645e-2,\n 4.97687799461593236017e-2, -3.6531572744216915527e-2, 1.62858201153657823623e-2,\n];\n\n/** Deterministic arctangent. */\nexport function datan(x: number): number {\n if (Number.isNaN(x)) return NaN;\n if (!Number.isFinite(x)) return x > 0 ? ATAN_HI[3] : -ATAN_HI[3];\n const sign = x < 0 || Object.is(x, -0) ? -1 : 1;\n let ax = Math.abs(x);\n if (ax >= 1e19) return sign * (ATAN_HI[3] + ATAN_LO[3]);\n\n let id = -1;\n if (ax < 0.4375) {\n if (ax < 1e-9) return x; // tiny: atan(x) \u2248 x\n } else if (ax < 0.6875) {\n id = 0;\n ax = (2 * ax - 1) / (2 + ax);\n } else if (ax < 1.1875) {\n id = 1;\n ax = (ax - 1) / (ax + 1);\n } else if (ax < 2.4375) {\n id = 2;\n ax = (ax - 1.5) / (1 + 1.5 * ax);\n } else {\n id = 3;\n ax = -1 / ax;\n }\n\n const z = ax * ax;\n const w = z * z;\n const s1 = z * (AT[0] + w * (AT[2] + w * (AT[4] + w * (AT[6] + w * (AT[8] + w * AT[10])))));\n const s2 = w * (AT[1] + w * (AT[3] + w * (AT[5] + w * (AT[7] + w * AT[9]))));\n if (id < 0) return sign * (ax - ax * (s1 + s2));\n const r = ATAN_HI[id] - (ax * (s1 + s2) - ATAN_LO[id] - ax);\n return sign * r;\n}\n\nconst PI = 3.141592653589793;\n\n/** Deterministic atan2(y, x) with standard quadrant conventions. */\nexport function datan2(y: number, x: number): number {\n if (Number.isNaN(x) || Number.isNaN(y)) return NaN;\n if (y === 0 && x === 0) return Object.is(x, -0) ? (Object.is(y, -0) ? -PI : PI) : Object.is(y, -0) ? -0 : 0;\n if (x === 0 || (!Number.isFinite(y) && Number.isFinite(x))) return y > 0 ? PI / 2 : -PI / 2;\n if (!Number.isFinite(x)) {\n if (!Number.isFinite(y)) {\n const q = x > 0 ? PI / 4 : (3 * PI) / 4;\n return y > 0 ? q : -q;\n }\n return x > 0 ? (y < 0 || Object.is(y, -0) ? -0 : 0) : y < 0 || Object.is(y, -0) ? -PI : PI;\n }\n const a = datan(y / x);\n if (x > 0) return a;\n return y < 0 || Object.is(y, -0) ? a - PI : a + PI;\n}\n\n// \u2500\u2500 exp2 (for easing curves and decay) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nconst LN2 = 6.93147180559945286227e-1;\n\n/** Deterministic 2^x via Taylor series on the reduced argument. */\nexport function dexp2(x: number): number {\n if (Number.isNaN(x)) return NaN;\n if (x >= 1024) return Infinity;\n if (x <= -1075) return 0;\n const k = Math.round(x);\n const y = (x - k) * LN2; // |y| \u2264 ln2/2 \u2248 0.347\n let term = 1;\n let sum = 1;\n for (let i = 1; i <= 13; i++) {\n term = (term * y) / i;\n sum += term;\n }\n return sum * 2 ** k; // 2^integer is exact in every engine\n}\n\n/** Deterministic natural exponential e\u02E3. Routes through dexp2 (e\u02E3 = 2^(x/ln2)). */\nexport function dexp(x: number): number {\n return dexp2(x * INV_LN2);\n}\n\n/** Deterministic hypotenuse: sqrt is IEEE-correctly-rounded, hypot is not. */\nexport function dhypot(x: number, y: number): number {\n return Math.sqrt(x * x + y * y);\n}\n\n// \u2500\u2500 logarithms \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// Decompose x = m\u00B72^e with the exponent read straight from the float bits\n// (bit-exact everywhere), then ln(m) on m \u2208 [\u221A\u00BD\u00B72, \u221A2) via the atanh series\n// ln(m) = 2\u00B7atanh((m\u22121)/(m+1)) \u2014 only exactly-rounded ops.\nconst logView = new DataView(new ArrayBuffer(8));\nconst LN2_HI = 6.93147180369123816490e-1;\nconst LN2_LO = 1.90821492927058770002e-10;\n\n/** Deterministic natural logarithm. */\nexport function dlog(x: number): number {\n if (Number.isNaN(x) || x < 0) return NaN;\n if (x === 0) return -Infinity;\n if (!Number.isFinite(x)) return Infinity;\n logView.setFloat64(0, x);\n let e = ((logView.getUint32(0) >>> 20) & 0x7ff) - 1023;\n if (e === -1023) {\n // subnormal: scale up by 2^54 (exact) and correct the exponent\n logView.setFloat64(0, x * 18014398509481984);\n e = ((logView.getUint32(0) >>> 20) & 0x7ff) - 1023 - 54;\n }\n // mantissa m \u2208 [1, 2); shift to [\u221A\u00BD\u00B72, \u221A2) so |s| stays small\n logView.setUint32(0, (logView.getUint32(0) & 0xfffff) | (1023 << 20));\n let m = logView.getFloat64(0);\n if (m > 1.4142135623730951) {\n m *= 0.5;\n e += 1;\n }\n const s = (m - 1) / (m + 1);\n const z = s * s;\n // 2\u00B7atanh(s) = 2s\u00B7(1 + z/3 + z\u00B2/5 + \u2026) \u2014 terms through z\u2079/19 keep the\n // truncation below 1 ulp for |s| \u2264 0.172\n const p =\n 1 +\n z *\n (0.3333333333333333 +\n z *\n (0.2 +\n z *\n (0.14285714285714285 +\n z *\n (0.1111111111111111 +\n z *\n (0.09090909090909091 +\n z * (0.07692307692307693 + z * (0.06666666666666667 + z * (0.058823529411764705 + z * 0.05263157894736842))))))));\n return e * LN2_HI + (2 * s * p + e * LN2_LO);\n}\n\nconst INV_LN10 = 4.34294481903251816668e-1; // 1/ln(10)\nconst INV_LN2 = 1.44269504088896338700e0; // 1/ln(2)\n\n/** Deterministic base-10 logarithm. */\nexport const dlog10 = (x: number): number => dlog(x) * INV_LN10;\n/** Deterministic base-2 logarithm. */\nexport const dlog2 = (x: number): number => dlog(x) * INV_LN2;\n", "// Deterministic 2D math. Plain data + pure functions (no classes with hidden\n// state) so everything serializes and hashes cleanly. Trig/hypot route through\n// dmath so results are bit-identical across JS engines (netplay-safe).\n\nimport { dcos, dhypot, dsin } from './dmath';\n\nexport interface Vec2 {\n x: number;\n y: number;\n}\n\nexport const vec2 = (x = 0, y = 0): Vec2 => ({ x, y });\nexport const vadd = (a: Vec2, b: Vec2): Vec2 => ({ x: a.x + b.x, y: a.y + b.y });\nexport const vsub = (a: Vec2, b: Vec2): Vec2 => ({ x: a.x - b.x, y: a.y - b.y });\nexport const vscale = (a: Vec2, s: number): Vec2 => ({ x: a.x * s, y: a.y * s });\nexport const vdot = (a: Vec2, b: Vec2): number => a.x * b.x + a.y * b.y;\nexport const vlen = (a: Vec2): number => dhypot(a.x, a.y);\nexport const vdist = (a: Vec2, b: Vec2): number => dhypot(a.x - b.x, a.y - b.y);\nexport function vnorm(a: Vec2): Vec2 {\n const l = vlen(a);\n return l === 0 ? { x: 0, y: 0 } : { x: a.x / l, y: a.y / l };\n}\n\nexport const clamp = (v: number, lo: number, hi: number): number => (v < lo ? lo : v > hi ? hi : v);\nexport const lerp = (a: number, b: number, t: number): number => a + (b - a) * t;\nexport const invLerp = (a: number, b: number, v: number): number => (a === b ? 0 : (v - a) / (b - a));\nexport const remap = (v: number, a0: number, a1: number, b0: number, b1: number): number =>\n lerp(b0, b1, invLerp(a0, a1, v));\n\n/** Hermite smoothstep: 0 below `edge0`, 1 above `edge1`, eased in between. */\nexport const smoothstep = (edge0: number, edge1: number, v: number): number => {\n const t = clamp(edge0 === edge1 ? (v < edge0 ? 0 : 1) : invLerp(edge0, edge1, v), 0, 1);\n return t * t * (3 - 2 * t);\n};\n\nexport const TAU = Math.PI * 2;\nexport const deg2rad = (d: number): number => (d * Math.PI) / 180;\nexport const rad2deg = (r: number): number => (r * 180) / Math.PI;\n\n/** Axis-aligned rectangle. */\nexport interface Rect {\n x: number;\n y: number;\n w: number;\n h: number;\n}\n\nexport function rectContains(r: Rect, p: Vec2): boolean {\n return p.x >= r.x && p.x <= r.x + r.w && p.y >= r.y && p.y <= r.y + r.h;\n}\n\nexport function rectsOverlap(a: Rect, b: Rect): boolean {\n return a.x < b.x + b.w && a.x + a.w > b.x && a.y < b.y + b.h && a.y + a.h > b.y;\n}\n\n/** 2D affine transform as a 6-value matrix [a b c d e f] (like SVG/Canvas). */\nexport interface Transform {\n a: number;\n b: number;\n c: number;\n d: number;\n e: number;\n f: number;\n}\n\nexport const IDENTITY: Transform = { a: 1, b: 0, c: 0, d: 1, e: 0, f: 0 };\n\nexport function composeTransform(m: Transform, n: Transform): Transform {\n return {\n a: m.a * n.a + m.c * n.b,\n b: m.b * n.a + m.d * n.b,\n c: m.a * n.c + m.c * n.d,\n d: m.b * n.c + m.d * n.d,\n e: m.a * n.e + m.c * n.f + m.e,\n f: m.b * n.e + m.d * n.f + m.f,\n };\n}\n\n/** Build a transform from position, rotation (radians), scale. */\nexport function makeTransform(pos: Vec2, rotation: number, scale: Vec2): Transform {\n const cos = dcos(rotation);\n const sin = dsin(rotation);\n return {\n a: cos * scale.x,\n b: sin * scale.x,\n c: -sin * scale.y,\n d: cos * scale.y,\n e: pos.x,\n f: pos.y,\n };\n}\n\nexport function applyTransform(m: Transform, p: Vec2): Vec2 {\n return { x: m.a * p.x + m.c * p.y + m.e, y: m.b * p.x + m.d * p.y + m.f };\n}\n\n/** Invert an affine transform (returns identity if singular). */\nexport function invertTransform(m: Transform): Transform {\n const det = m.a * m.d - m.b * m.c;\n if (det === 0) return { ...IDENTITY };\n const id = 1 / det;\n return {\n a: m.d * id,\n b: -m.b * id,\n c: -m.c * id,\n d: m.a * id,\n e: (m.c * m.f - m.d * m.e) * id,\n f: (m.b * m.e - m.a * m.f) * id,\n };\n}\n", "// Deterministic, seedable, splittable RNG. SplitMix64 for seeding, xoshiro128**\n// for the stream \u2014 fast, good distribution, trivially reproducible.\n// Every random draw in a game MUST flow through here (never Math.random()).\n\nfunction splitmix32(seed: number): () => number {\n let a = seed >>> 0;\n return () => {\n a = (a + 0x9e3779b9) >>> 0;\n let t = a;\n t = Math.imul(t ^ (t >>> 16), 0x21f0aaad);\n t = Math.imul(t ^ (t >>> 15), 0x735a2d97);\n return (t ^ (t >>> 15)) >>> 0;\n };\n}\n\nexport interface RngState {\n s: [number, number, number, number];\n}\n\nexport class Rng {\n private s0: number;\n private s1: number;\n private s2: number;\n private s3: number;\n\n constructor(seed: number | RngState = 0) {\n if (typeof seed === 'number') {\n const sm = splitmix32(seed === 0 ? 0x1234abcd : seed);\n this.s0 = sm();\n this.s1 = sm();\n this.s2 = sm();\n this.s3 = sm();\n } else {\n [this.s0, this.s1, this.s2, this.s3] = seed.s;\n }\n }\n\n /** Raw 32-bit unsigned integer. */\n private next(): number {\n const result = (Math.imul(this.rotl(Math.imul(this.s1, 5), 7), 9) >>> 0);\n const t = (this.s1 << 9) >>> 0;\n this.s2 ^= this.s0;\n this.s3 ^= this.s1;\n this.s1 ^= this.s2;\n this.s0 ^= this.s3;\n this.s2 = (this.s2 ^ t) >>> 0;\n this.s3 = this.rotl(this.s3, 11);\n return result >>> 0;\n }\n\n private rotl(x: number, k: number): number {\n return (((x << k) | (x >>> (32 - k))) >>> 0);\n }\n\n /** Float in [0, 1). */\n float(): number {\n return this.next() / 4294967296;\n }\n\n /** Float in [lo, hi). */\n range(lo: number, hi: number): number {\n return lo + this.float() * (hi - lo);\n }\n\n /** Integer in [0, n). */\n int(n: number): number {\n return Math.floor(this.float() * n);\n }\n\n /** Integer in [lo, hi] inclusive. */\n intRange(lo: number, hi: number): number {\n return lo + this.int(hi - lo + 1);\n }\n\n /** True with probability p. */\n chance(p: number): boolean {\n return this.float() < p;\n }\n\n /** Uniform element of an array. */\n pick<T>(arr: readonly T[]): T {\n return arr[this.int(arr.length)];\n }\n\n /** In-place Fisher\u2013Yates shuffle (deterministic). */\n shuffle<T>(arr: T[]): T[] {\n for (let i = arr.length - 1; i > 0; i--) {\n const j = this.int(i + 1);\n [arr[i], arr[j]] = [arr[j], arr[i]];\n }\n return arr;\n }\n\n /**\n * Derive an independent child stream. Same parent state + same key always\n * yields the same child \u2014 so subsystems (enemy AI, loot, terrain) get stable,\n * decorrelated randomness without threading one generator through everything.\n */\n split(key = 0): Rng {\n const mix = (this.s0 ^ Math.imul(key + 1, 0x9e3779b9)) >>> 0;\n const child = new Rng(mix ^ this.s3);\n // Advance parent so repeated splits differ.\n this.next();\n return child;\n }\n\n /** Serialize / restore for saves and replay. */\n getState(): RngState {\n return { s: [this.s0, this.s1, this.s2, this.s3] };\n }\n setState(state: RngState): void {\n [this.s0, this.s1, this.s2, this.s3] = state.s;\n }\n}\n\n/** Deterministic 32-bit FNV-1a hash of a string \u2014 handy for stable ids/seeds. */\nexport function hashString(str: string): number {\n let h = 2166136261 >>> 0;\n for (let i = 0; i < str.length; i++) {\n h ^= str.charCodeAt(i);\n h = Math.imul(h, 16777619);\n }\n return h >>> 0;\n}\n", "// Fixed-timestep clock. Real elapsed milliseconds go in; whole fixed steps come\n// out. This is what makes the sim frame-rate independent AND exactly reproducible:\n// the same input log always yields the same number of steps.\n\nexport interface ClockConfig {\n /** Simulation rate in Hz (steps per second). Default 60. */\n hz?: number;\n /** Max real ms consumed per advance, to avoid a spiral of death. Default 250. */\n maxFrameMs?: number;\n}\n\nexport class Clock {\n readonly stepMs: number;\n readonly dt: number; // fixed delta in seconds, for game logic\n private maxFrameMs: number;\n private accumulator = 0;\n private _frame = 0;\n private _simTimeMs = 0;\n\n constructor(config: ClockConfig = {}) {\n const hz = config.hz ?? 60;\n this.stepMs = 1000 / hz;\n this.dt = 1 / hz;\n this.maxFrameMs = config.maxFrameMs ?? 250;\n }\n\n /**\n * Feed real elapsed ms; returns how many fixed steps to run now.\n * Caller runs the sim exactly that many times.\n */\n advance(realMs: number): number {\n this.accumulator += Math.min(realMs, this.maxFrameMs);\n let steps = 0;\n while (this.accumulator >= this.stepMs) {\n this.accumulator -= this.stepMs;\n steps++;\n }\n return steps;\n }\n\n /** Called by the World once per executed step to keep counters honest. */\n tick(): void {\n this._frame++;\n this._simTimeMs += this.stepMs;\n }\n\n /** Interpolation alpha in [0,1) for smooth rendering between fixed steps. */\n get alpha(): number {\n return this.accumulator / this.stepMs;\n }\n\n get frame(): number {\n return this._frame;\n }\n get simTimeMs(): number {\n return this._simTimeMs;\n }\n get simTimeSec(): number {\n return this._simTimeMs / 1000;\n }\n\n getState() {\n return { accumulator: this.accumulator, frame: this._frame, simTimeMs: this._simTimeMs };\n }\n setState(s: { accumulator: number; frame: number; simTimeMs: number }): void {\n this.accumulator = s.accumulator;\n this._frame = s.frame;\n this._simTimeMs = s.simTimeMs;\n }\n}\n", "// Synchronous typed signal bus (Godot-style signals). Deterministic: listeners\n// fire in connection order, synchronously, within the current step.\n\nexport type Listener<T> = (payload: T) => void;\n\nexport class Signal<T = void> {\n private listeners: Listener<T>[] = [];\n\n connect(fn: Listener<T>): () => void {\n this.listeners.push(fn);\n return () => this.disconnect(fn);\n }\n\n once(fn: Listener<T>): () => void {\n const off = this.connect((p) => {\n off();\n fn(p);\n });\n return off;\n }\n\n disconnect(fn: Listener<T>): void {\n const i = this.listeners.indexOf(fn);\n if (i >= 0) this.listeners.splice(i, 1);\n }\n\n emit(payload: T): void {\n // Copy so a listener disconnecting mid-emit doesn't skip its neighbor.\n for (const fn of this.listeners.slice()) fn(payload);\n }\n\n get count(): number {\n return this.listeners.length;\n }\n\n clear(): void {\n this.listeners.length = 0;\n }\n}\n\n/**\n * A named event bus for cross-cutting game events, keyed by an event map so\n * payloads are typed. Prefer node-local Signals for local wiring; use the bus\n * for global concerns (score changed, level complete, sound cue).\n */\nexport class EventBus<Events extends Record<string, unknown>> {\n private signals = new Map<keyof Events, Signal<unknown>>();\n\n private signalFor<K extends keyof Events>(key: K): Signal<Events[K]> {\n let s = this.signals.get(key);\n if (!s) {\n s = new Signal<unknown>();\n this.signals.set(key, s);\n }\n return s as unknown as Signal<Events[K]>;\n }\n\n on<K extends keyof Events>(key: K, fn: Listener<Events[K]>): () => void {\n return this.signalFor(key).connect(fn);\n }\n\n once<K extends keyof Events>(key: K, fn: Listener<Events[K]>): () => void {\n return this.signalFor(key).once(fn);\n }\n\n emit<K extends keyof Events>(key: K, payload: Events[K]): void {\n this.signalFor(key).emit(payload);\n }\n\n clear(): void {\n this.signals.clear();\n }\n}\n", "// Deterministic structural hash of any JSON-like value. The spine of replay\n// verification: two runs are identical iff their state hashes match.\n\nfunction canonicalNumber(n: number): string {\n if (Number.isNaN(n)) return 'NaN';\n if (n === Infinity) return 'Inf';\n if (n === -Infinity) return '-Inf';\n if (n === 0) return '0'; // collapse -0 and 0\n return n.toString();\n}\n\n/**\n * Walk a value in a canonical order (object keys sorted) and fold it into a\n * 64-bit-ish FNV-1a hash represented as an 8-char hex string. Stable across runs\n * for structurally identical data.\n */\nexport function hashValue(value: unknown): string {\n let h1 = 2166136261 >>> 0;\n let h2 = 0x811c9dc5 >>> 0;\n const push = (s: string) => {\n for (let i = 0; i < s.length; i++) {\n const c = s.charCodeAt(i);\n h1 = Math.imul(h1 ^ c, 16777619) >>> 0;\n h2 = Math.imul(h2 ^ ((c << 3) | (c >>> 5)), 2246822519) >>> 0;\n }\n };\n\n const walk = (v: unknown): void => {\n if (v === null) return push('n');\n if (v === undefined) return push('u');\n switch (typeof v) {\n case 'number':\n return push('#' + canonicalNumber(v));\n case 'boolean':\n return push(v ? 't' : 'f');\n case 'string':\n return push('\"' + v);\n case 'object': {\n if (Array.isArray(v)) {\n push('[');\n for (const el of v) walk(el);\n push(']');\n return;\n }\n const obj = v as Record<string, unknown>;\n // Omit undefined-valued keys: JSON has no `undefined`, so `{a: undefined}`\n // and `{}` serialize identically. Counting the key would make hash()\n // disagree with the value after a save/load JSON round-trip (a Sprite's\n // unset paint fields are the canonical case). JSON-stable = the guarantee\n // persistence needs.\n const keys = Object.keys(obj)\n .filter((k) => obj[k] !== undefined)\n .sort();\n push('{');\n for (const k of keys) {\n push(k + ':');\n walk(obj[k]);\n }\n push('}');\n return;\n }\n default:\n push('?');\n }\n };\n\n walk(value);\n const hex = (n: number) => n.toString(16).padStart(8, '0');\n return hex(h1) + hex(h2);\n}\n", "// The scene node: a Godot-style tree element with a transform, lifecycle,\n// children, local signals, and attachable behaviors. Updates run in fixed tree\n// order (depth-first, child-index order) which keeps the whole tree deterministic.\n\nimport type { Rng } from '../core/rng';\nimport type { Clock } from '../core/clock';\nimport { Signal } from '../core/events';\nimport {\n IDENTITY,\n composeTransform,\n makeTransform,\n type Transform,\n type Vec2,\n} from '../core/math';\nimport type { DrawCommand } from '../render/commands';\n\n/** What a live node can see of its host world. The World implements this. */\nexport interface WorldContext {\n readonly rng: Rng;\n readonly clock: Clock;\n /** Queue a node to be freed at the end of the current step (safe during iteration). */\n requestFree(node: Node): void;\n /** Seconds elapsed in sim time. */\n readonly time: number;\n}\n\n/** A composable update unit attached to a node (favour over deep inheritance). */\nexport interface Behavior {\n ready?(node: Node): void;\n update?(node: Node, dt: number): void;\n exit?(node: Node): void;\n /** Optional tag for lookup/serialization. */\n readonly kind?: string;\n}\n\nlet __idCounter = 0;\n/** Deterministic id source \u2014 reset by the World on load so ids are reproducible. */\nexport function resetNodeIds(start = 0): void {\n __idCounter = start;\n}\n\nexport interface NodeConfig {\n name?: string;\n pos?: Vec2;\n rotation?: number;\n scale?: Vec2;\n z?: number;\n visible?: boolean;\n}\n\nexport class Node {\n readonly id: string;\n name: string;\n /** Type tag for serialization; subclasses override. */\n readonly type: string = 'Node';\n\n pos: Vec2;\n rotation: number;\n scale: Vec2;\n z: number;\n visible: boolean;\n /**\n * Cosmetic nodes are pure *view* (derived from game state, rebuildable) and are\n * excluded from serialize()/snapshot()/hash(). Mark a container cosmetic when it\n * only renders state that lives elsewhere \u2014 so transient display (move counters,\n * particles, tweened positions) never pollutes the canonical, verifiable state.\n */\n cosmetic = false;\n\n parent: Node | null = null;\n readonly children: Node[] = [];\n world: WorldContext | null = null;\n\n /** Optional inline update without subclassing: node.onUpdate = (n, dt) => {\u2026}. */\n onUpdate?: (node: Node, dt: number) => void;\n\n private behaviors: Behavior[] = [];\n private signals = new Map<string, Signal<unknown>>();\n private _ready = false;\n private _freed = false;\n\n constructor(config: NodeConfig = {}) {\n this.id = `n${__idCounter++}`;\n this.name = config.name ?? this.constructor.name;\n this.pos = config.pos ? { ...config.pos } : { x: 0, y: 0 };\n this.rotation = config.rotation ?? 0;\n this.scale = config.scale ? { ...config.scale } : { x: 1, y: 1 };\n this.z = config.z ?? 0;\n this.visible = config.visible ?? true;\n }\n\n // \u2500\u2500 Tree structure \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n addChild<T extends Node>(child: T): T {\n child.parent = this;\n this.children.push(child);\n if (this.world && this._ready) child.enterTree(this.world);\n return child;\n }\n\n removeChild(child: Node): void {\n const i = this.children.indexOf(child);\n if (i >= 0) {\n this.children.splice(i, 1);\n child.parent = null;\n }\n }\n\n /** Deferred free: runs exit hooks and detaches at the end of the step. */\n free(): void {\n this.world?.requestFree(this);\n }\n\n /** Depth-first find by name. */\n find(name: string): Node | null {\n if (this.name === name) return this;\n for (const c of this.children) {\n const r = c.find(name);\n if (r) return r;\n }\n return null;\n }\n\n /** All descendants (and self) of a given type tag. */\n query(type: string, out: Node[] = []): Node[] {\n if (this.type === type) out.push(this);\n for (const c of this.children) c.query(type, out);\n return out;\n }\n\n // \u2500\u2500 Behaviors \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n addBehavior(b: Behavior): this {\n this.behaviors.push(b);\n if (this._ready) b.ready?.(this);\n return this;\n }\n\n // \u2500\u2500 Signals \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n signal<T = void>(name: string): Signal<T> {\n let s = this.signals.get(name);\n if (!s) {\n s = new Signal<unknown>();\n this.signals.set(name, s);\n }\n return s as unknown as Signal<T>;\n }\n emit<T>(name: string, payload: T): void {\n this.signals.get(name)?.emit(payload);\n }\n\n // \u2500\u2500 Lifecycle (engine-called) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n enterTree(world: WorldContext): void {\n this.world = world;\n if (!this._ready) {\n this._ready = true;\n this.onReady();\n for (const b of this.behaviors) b.ready?.(this);\n }\n for (const c of this.children) c.enterTree(world);\n }\n\n updateTree(dt: number): void {\n if (this._freed) return;\n for (const b of this.behaviors) b.update?.(this, dt);\n this.onUpdate?.(this, dt);\n this.onProcess(dt);\n // Copy children so structural changes during update are safe.\n for (const c of this.children.slice()) c.updateTree(dt);\n }\n\n exitTree(): void {\n for (const b of this.behaviors) b.exit?.(this);\n this.onExit();\n for (const c of this.children.slice()) c.exitTree();\n this._freed = true;\n }\n\n get isFreed(): boolean {\n return this._freed;\n }\n\n // \u2500\u2500 Transforms \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n localTransform(): Transform {\n return makeTransform(this.pos, this.rotation, this.scale);\n }\n\n worldTransform(): Transform {\n const local = this.localTransform();\n return this.parent ? composeTransform(this.parent.worldTransform(), local) : local;\n }\n\n // \u2500\u2500 Rendering (projection) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n /** Walk the subtree, appending draw commands with computed world transforms. */\n collectDraw(out: DrawCommand[], parentWorld: Transform = IDENTITY): void {\n if (!this.visible) return;\n const world = composeTransform(parentWorld, this.localTransform());\n this.draw(out, world);\n for (const c of this.children) c.collectDraw(out, world);\n }\n\n /** Subclasses emit their own commands here. Base draws nothing. */\n protected draw(_out: DrawCommand[], _world: Transform): void {}\n\n // \u2500\u2500 Overridable hooks \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n protected onReady(): void {}\n protected onProcess(_dt: number): void {}\n protected onExit(): void {}\n\n // \u2500\u2500 Serialization (data only; behaviors/closures are re-attached by scene code) \u2500\u2500\n serialize(): SerializedNode {\n return {\n type: this.type,\n name: this.name,\n pos: { ...this.pos },\n rotation: this.rotation,\n scale: { ...this.scale },\n z: this.z,\n visible: this.visible,\n props: this.serializeProps(),\n children: this.children.filter((c) => !c.cosmetic).map((c) => c.serialize()),\n };\n }\n /** Subclasses persist their own fields here. */\n protected serializeProps(): Record<string, unknown> {\n return {};\n }\n /** Subclasses restore their own fields here. */\n applyProps(_props: Record<string, unknown>): void {}\n}\n\nexport interface SerializedNode {\n type: string;\n name: string;\n pos: Vec2;\n rotation: number;\n scale: Vec2;\n z: number;\n visible: boolean;\n props: Record<string, unknown>;\n children: SerializedNode[];\n}\n", "// Concrete node types built on Node. Code-as-art: a Sprite is a vector shape or\n// glyph, never a bitmap. Text is a DOM-quality label. Camera2D drives the view.\n// Timer is a deterministic countdown that emits a signal.\n\nimport type { Transform } from '../core/math';\nimport type { DrawCommand, Paint, TextAlign } from '../render/commands';\nimport { Node, type NodeConfig, type WorldContext } from './node';\n\n// \u2500\u2500 Sprite \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport type Shape =\n | { kind: 'rect'; w: number; h: number; r?: number }\n | { kind: 'circle'; radius: number }\n | { kind: 'poly'; points: number[]; closed?: boolean }\n | { kind: 'path'; d: string }\n | { kind: 'glyph'; char: string; size: number };\n\nexport interface SpriteConfig extends NodeConfig, Paint {\n shape: Shape;\n}\n\nexport class Sprite extends Node {\n override readonly type = 'Sprite';\n shape: Shape;\n paint: Paint;\n\n constructor(config: SpriteConfig) {\n super(config);\n this.shape = config.shape;\n this.paint = {\n fill: config.fill,\n stroke: config.stroke,\n strokeWidth: config.strokeWidth,\n opacity: config.opacity,\n round: config.round,\n };\n }\n\n protected override draw(out: DrawCommand[], world: Transform): void {\n const p = this.paint;\n const base = { transform: world, z: this.z, ...p };\n switch (this.shape.kind) {\n case 'rect':\n out.push({ kind: 'rect', x: -this.shape.w / 2, y: -this.shape.h / 2, w: this.shape.w, h: this.shape.h, r: this.shape.r, ...base });\n break;\n case 'circle':\n out.push({ kind: 'circle', cx: 0, cy: 0, radius: this.shape.radius, ...base });\n break;\n case 'poly':\n out.push({ kind: 'poly', points: this.shape.points, closed: this.shape.closed ?? true, ...base });\n break;\n case 'path':\n out.push({ kind: 'path', d: this.shape.d, ...base });\n break;\n case 'glyph':\n out.push({ kind: 'text', text: this.shape.char, x: 0, y: 0, size: this.shape.size, align: 'center', ...base });\n break;\n }\n }\n\n protected override serializeProps(): Record<string, unknown> {\n return { shape: this.shape, paint: this.paint };\n }\n override applyProps(props: Record<string, unknown>): void {\n if (props.shape) this.shape = props.shape as Shape;\n if (props.paint) this.paint = props.paint as Paint;\n }\n}\n\n// \u2500\u2500 Text \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport interface TextConfig extends NodeConfig, Paint {\n text: string;\n size?: number;\n font?: string;\n align?: TextAlign;\n weight?: number;\n}\n\nexport class Text extends Node {\n override readonly type = 'Text';\n text: string;\n size: number;\n font?: string;\n align: TextAlign;\n weight?: number;\n paint: Paint;\n\n constructor(config: TextConfig) {\n super(config);\n this.text = config.text;\n this.size = config.size ?? 24;\n this.font = config.font;\n this.align = config.align ?? 'left';\n this.weight = config.weight;\n this.paint = { fill: config.fill ?? '#000', stroke: config.stroke, strokeWidth: config.strokeWidth, opacity: config.opacity };\n }\n\n protected override draw(out: DrawCommand[], world: Transform): void {\n out.push({\n kind: 'text', text: this.text, x: 0, y: 0, size: this.size, font: this.font,\n align: this.align, weight: this.weight, transform: world, z: this.z, ...this.paint,\n });\n }\n\n protected override serializeProps(): Record<string, unknown> {\n return { text: this.text, size: this.size, align: this.align, paint: this.paint };\n }\n override applyProps(props: Record<string, unknown>): void {\n if (typeof props.text === 'string') this.text = props.text;\n if (typeof props.size === 'number') this.size = props.size;\n if (props.align) this.align = props.align as TextAlign;\n if (props.paint) this.paint = props.paint as Paint;\n }\n}\n\n// \u2500\u2500 Camera2D \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport interface CameraConfig extends NodeConfig {\n zoom?: number;\n /** Make this the active camera on ready. */\n current?: boolean;\n}\n\nexport class Camera2D extends Node {\n override readonly type = 'Camera2D';\n zoom: number;\n current: boolean;\n\n constructor(config: CameraConfig = {}) {\n super(config);\n this.zoom = config.zoom ?? 1;\n this.current = config.current ?? true;\n }\n\n protected override onReady(): void {\n if (this.current) (this.world as WorldContext & { activeCamera?: Camera2D }).activeCamera = this;\n }\n\n protected override serializeProps(): Record<string, unknown> {\n return { zoom: this.zoom, current: this.current };\n }\n override applyProps(props: Record<string, unknown>): void {\n if (typeof props.zoom === 'number') this.zoom = props.zoom;\n if (typeof props.current === 'boolean') this.current = props.current;\n }\n}\n\n// \u2500\u2500 Timer \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport interface TimerConfig extends NodeConfig {\n duration: number; // seconds\n autostart?: boolean;\n oneShot?: boolean;\n}\n\nexport class Timer extends Node {\n override readonly type = 'Timer';\n duration: number;\n oneShot: boolean;\n private remaining: number;\n private running: boolean;\n\n constructor(config: TimerConfig) {\n super(config);\n this.duration = config.duration;\n this.oneShot = config.oneShot ?? true;\n this.remaining = config.duration;\n this.running = config.autostart ?? true;\n }\n\n start(duration?: number): void {\n if (duration !== undefined) this.duration = duration;\n this.remaining = this.duration;\n this.running = true;\n }\n stop(): void {\n this.running = false;\n }\n\n get timeLeft(): number {\n return this.remaining;\n }\n\n protected override onProcess(dt: number): void {\n if (!this.running) return;\n this.remaining -= dt;\n if (this.remaining <= 0) {\n this.emit('timeout', undefined);\n if (this.oneShot) this.running = false;\n else this.remaining += this.duration;\n }\n }\n\n /** Signal emitted when the countdown reaches zero. */\n get timeout() {\n return this.signal('timeout');\n }\n\n protected override serializeProps(): Record<string, unknown> {\n return { duration: this.duration, oneShot: this.oneShot, remaining: this.remaining, running: this.running };\n }\n override applyProps(props: Record<string, unknown>): void {\n if (typeof props.duration === 'number') this.duration = props.duration;\n if (typeof props.oneShot === 'boolean') this.oneShot = props.oneShot;\n if (typeof props.remaining === 'number') this.remaining = props.remaining;\n if (typeof props.running === 'boolean') this.running = props.running;\n }\n}\n", "// Frame-scoped node pool: hide/show instead of create/destroy, for views that\n// redraw a whole entity set every frame (hordes, bullets, tiles, HP bars).\n// Usage per frame: begin() \u2192 get() once per live entity \u2192 end(). Nodes are\n// created on demand, reused in stable order, and surplus nodes are hidden \u2014\n// never removed \u2014 so the scene tree stays allocation-quiet at peak load.\n//\n// Pooled nodes are pure view: parent them to a `cosmetic = true` layer so the\n// pool's grow-only node set never enters world.hash().\n// (Promoted from six near-identical per-game copies \u2014 see docs/LESSONS.md.)\n\nimport type { Node } from './node';\n\nexport class NodePool<T extends Node = Node> {\n private items: T[] = [];\n private used = 0;\n\n constructor(\n private parent: Node,\n private make: () => T,\n ) {}\n\n /** Start a frame: every pooled node is up for reuse. */\n begin(): void {\n this.used = 0;\n }\n\n /** Claim the next node (created and parented on first use), made visible. */\n get(): T {\n if (this.used === this.items.length) this.items.push(this.parent.addChild(this.make()));\n const n = this.items[this.used++];\n n.visible = true;\n return n;\n }\n\n /** End a frame: hide every node not claimed since begin(). */\n end(): void {\n for (let i = this.used; i < this.items.length; i++) this.items[i].visible = false;\n }\n\n /** Nodes claimed this frame (call after the get() loop). */\n get liveCount(): number {\n return this.used;\n }\n}\n", "// Deterministic tweening. Tweens advance by the fixed dt, so animations are\n// exactly reproducible. Tweens animate via setter closures (transient visual\n// polish \u2014 not part of the hashed logic state), Godot AnimationPlayer-style.\n\nimport { clamp, lerp } from '../core/math';\nimport { dcos, dexp, dexp2, dsin } from '../core/dmath';\nimport { Node } from './node';\n\nexport type Easing = (t: number) => number;\n\n// \u2500\u2500 Framerate-independent smoothing \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// The naive `x += (target - x) * k` follows a target, but its stiffness scales\n// with frame count: halving dt halves the approach per step. These helpers fold\n// dt into an exponential so the same real-time response falls out of any fixed\n// step. Feed the FIXED clock dt (never a variable rAF delta) or a lockstep sim\n// desyncs. All pure + deterministic (exp routes through dmath), so they are safe\n// to use on hashed values as well as cosmetic ones.\n\n/**\n * Exponentially damp `current` toward `target`, framerate-independent.\n * `lambda` is the decay rate (1/s): larger = snappier. Reaches ~63% of the way\n * to the target after 1/lambda seconds regardless of how dt is subdivided.\n */\nexport const lerpDamp = (current: number, target: number, lambda: number, dt: number): number =>\n lerp(target, current, dexp(-lambda * dt));\n\n/** A critically-damped spring value: rides toward a target with no overshoot. */\nexport interface SpringState {\n value: number;\n vel: number;\n}\n\n/** Make a spring at rest on `value`. */\nexport const spring = (value = 0): SpringState => ({ value, vel: 0 });\n\n/**\n * Advance a critically-damped spring one fixed step toward `target`. `omega` is\n * the angular frequency (rad/s) \u2014 higher snaps faster. Critical damping means it\n * settles as fast as possible without oscillating. Mutates and returns the state.\n * Uses the closed-form solution so it is stable at any dt (no stiffness blow-up).\n */\nexport function springStep(s: SpringState, target: number, omega: number, dt: number): SpringState {\n const decay = dexp(-omega * dt);\n const d = s.value - target; // displacement from rest\n const c = s.vel + omega * d; // integration constant for x(t) = (d + c\u00B7t)\u00B7e^(\u2212\u03C9t)\n s.value = target + (d + c * dt) * decay;\n s.vel = (s.vel - c * omega * dt) * decay;\n return s;\n}\n\n/**\n * One-liner critically-damped follow that owns its own velocity in a closure \u2014\n * for camera/value chase where you don't want to thread a SpringState around.\n * `settle` is the approximate time (s) to arrive. Returns a `(target, dt) \u2192 value`.\n */\nexport function makeReach(start = 0, settle = 0.25): (target: number, dt: number) => number {\n // omega \u2248 4/settle puts ~98% of the move inside `settle` seconds.\n const omega = 4 / Math.max(1e-4, settle);\n const s = spring(start);\n return (target: number, dt: number) => springStep(s, target, omega, dt).value;\n}\n\n// Integer powers are spelled out as multiplication and 2^x routes through\n// dexp2: Math.pow is implementation-defined, and eased values land in hashed\n// node props, so easings must be bit-identical across engines.\nconst sq = (x: number) => x * x;\nconst cube = (x: number) => x * x * x;\nexport const EASINGS: Record<string, Easing> = {\n linear: (t) => t,\n quadIn: (t) => t * t,\n quadOut: (t) => 1 - (1 - t) * (1 - t),\n quadInOut: (t) => (t < 0.5 ? 2 * t * t : 1 - sq(-2 * t + 2) / 2),\n cubicIn: (t) => t * t * t,\n cubicOut: (t) => 1 - cube(1 - t),\n cubicInOut: (t) => (t < 0.5 ? 4 * t * t * t : 1 - cube(-2 * t + 2) / 2),\n sineIn: (t) => 1 - dcos((t * Math.PI) / 2),\n sineOut: (t) => dsin((t * Math.PI) / 2),\n sineInOut: (t) => -(dcos(Math.PI * t) - 1) / 2,\n backOut: (t) => {\n const c1 = 1.70158;\n const c3 = c1 + 1;\n return 1 + c3 * cube(t - 1) + c1 * sq(t - 1);\n },\n elasticOut: (t) => {\n const c4 = (2 * Math.PI) / 3;\n return t === 0 ? 0 : t === 1 ? 1 : dexp2(-10 * t) * dsin((t * 10 - 0.75) * c4) + 1;\n },\n bounceOut: (t) => {\n const n1 = 7.5625;\n const d1 = 2.75;\n if (t < 1 / d1) return n1 * t * t;\n if (t < 2 / d1) return n1 * (t -= 1.5 / d1) * t + 0.75;\n if (t < 2.5 / d1) return n1 * (t -= 2.25 / d1) * t + 0.9375;\n return n1 * (t -= 2.625 / d1) * t + 0.984375;\n },\n};\n\ninterface Track {\n apply: (v: number) => void;\n from: number;\n to: number;\n duration: number;\n elapsed: number;\n ease: Easing;\n onDone?: () => void;\n delay: number;\n}\n\n/** A node that runs one or more property tweens and reports when they finish. */\nexport class AnimationPlayer extends Node {\n override readonly type = 'AnimationPlayer';\n private tracks: Track[] = [];\n\n /**\n * Animate a value from \u2192 to over `duration` seconds via `apply(value)`.\n * Returns this for chaining.\n */\n to(\n apply: (v: number) => void,\n from: number,\n to: number,\n duration: number,\n ease: keyof typeof EASINGS | Easing = 'cubicOut',\n opts: { delay?: number; onDone?: () => void } = {},\n ): this {\n this.tracks.push({\n apply,\n from,\n to,\n duration: Math.max(1e-6, duration),\n elapsed: 0,\n ease: typeof ease === 'function' ? ease : EASINGS[ease] ?? EASINGS.linear,\n delay: opts.delay ?? 0,\n onDone: opts.onDone,\n });\n return this;\n }\n\n get active(): boolean {\n return this.tracks.length > 0;\n }\n\n /** Signal emitted when all tracks complete. */\n get finished() {\n return this.signal('finished');\n }\n\n protected override onProcess(dt: number): void {\n if (this.tracks.length === 0) return;\n for (let i = this.tracks.length - 1; i >= 0; i--) {\n const tk = this.tracks[i];\n if (tk.delay > 0) {\n tk.delay -= dt;\n continue;\n }\n tk.elapsed += dt;\n const t = clamp(tk.elapsed / tk.duration, 0, 1);\n tk.apply(tk.from + (tk.to - tk.from) * tk.ease(t));\n if (t >= 1) {\n tk.onDone?.();\n this.tracks.splice(i, 1);\n }\n }\n if (this.tracks.length === 0) this.emit('finished', undefined);\n }\n}\n", "// Particles + screen shake: the juice kit. Both are COSMETIC by construction \u2014\n// they carry their own tiny Rng stream (never the world's), are excluded from\n// hashing/serialization, and can be deleted without changing any game outcome.\n// Emission is driven by sim events (jumped, landed, hit\u2026), so replays produce\n// identical visuals, but no canonical state ever depends on them.\n\nimport { dcos, dsin } from '../core/dmath';\nimport { Rng } from '../core/rng';\nimport { smoothstep, TAU, type Transform, type Vec2 } from '../core/math';\nimport type { DrawCommand } from '../render/commands';\nimport { Node, type NodeConfig } from './node';\n\nexport interface ParticleStyle {\n /** Colors drawn from at random per particle. */\n colors: string[];\n /** Particle radius range (px). */\n sizeMin: number;\n sizeMax: number;\n /** Initial speed range (px/s). */\n speedMin: number;\n speedMax: number;\n /** Emission arc: center angle + spread (radians). Default: full circle. */\n angle?: number;\n spread?: number;\n /** Lifetime range (s). */\n lifeMin: number;\n lifeMax: number;\n /** Gravity applied to particles (px/s\u00B2, +y is down). */\n gravity?: number;\n /** Velocity damping per second (0 = none, 5 = strong). */\n drag?: number;\n /** Shrink to zero over life (default true; also fades opacity). */\n shrink?: boolean;\n}\n\ninterface Particle {\n x: number;\n y: number;\n vx: number;\n vy: number;\n life: number;\n maxLife: number;\n size: number;\n color: string;\n}\n\n/**\n * A pooled particle emitter node. Call `burst(n, at, style)` from game code in\n * response to feel events. Always cosmetic; safe to add anywhere in the tree.\n */\nexport class Particles extends Node {\n override readonly type: string = 'Particles';\n private pool: Particle[] = [];\n private rng: Rng;\n /** Cap on live particles (oldest are recycled first). */\n maxParticles: number;\n\n constructor(config: NodeConfig & { seed?: number; maxParticles?: number } = {}) {\n super(config);\n this.cosmetic = true;\n this.rng = new Rng(config.seed ?? 7);\n this.maxParticles = config.maxParticles ?? 512;\n }\n\n /** Emit a burst at a position (in this node's local space). */\n burst(count: number, at: Vec2, style: ParticleStyle): void {\n const r = this.rng;\n for (let i = 0; i < count; i++) {\n const angle = style.angle !== undefined ? style.angle + (r.float() - 0.5) * (style.spread ?? 0.6) : r.float() * TAU;\n const speed = style.speedMin + r.float() * (style.speedMax - style.speedMin);\n const p: Particle = {\n x: at.x,\n y: at.y,\n vx: dcos(angle) * speed,\n vy: dsin(angle) * speed,\n life: 0,\n maxLife: style.lifeMin + r.float() * (style.lifeMax - style.lifeMin),\n size: style.sizeMin + r.float() * (style.sizeMax - style.sizeMin),\n color: style.colors[r.int(style.colors.length)],\n };\n if (this.pool.length >= this.maxParticles) this.pool.shift();\n this.pool.push(p);\n }\n // Stash style scalars on the instance for update (single-style emitters are\n // the common case; per-particle style costs memory for no visible gain).\n this.gravity = style.gravity ?? 0;\n this.drag = style.drag ?? 0;\n this.shrink = style.shrink ?? true;\n }\n\n private gravity = 0;\n private drag = 0;\n private shrink = true;\n\n protected override onProcess(dt: number): void {\n const drag = Math.max(0, 1 - this.drag * dt);\n let write = 0;\n for (const p of this.pool) {\n p.life += dt;\n if (p.life >= p.maxLife) continue;\n p.vy += this.gravity * dt;\n p.vx *= drag;\n p.vy *= drag;\n p.x += p.vx * dt;\n p.y += p.vy * dt;\n this.pool[write++] = p;\n }\n this.pool.length = write;\n }\n\n protected override draw(out: DrawCommand[], world: Transform): void {\n for (const p of this.pool) {\n const t = 1 - p.life / p.maxLife;\n out.push({\n kind: 'circle',\n cx: p.x,\n cy: p.y,\n radius: this.shrink ? p.size * t : p.size,\n fill: p.color,\n opacity: Math.min(1, t * 2),\n transform: world,\n z: this.z,\n });\n }\n }\n\n get liveCount(): number {\n return this.pool.length;\n }\n}\n\n/** Ready-made styles for the common feel moments. */\nexport const PARTICLE_PRESETS = {\n dust: (colors = ['#c8c2b6', '#a09a8c']): ParticleStyle => ({ colors, sizeMin: 2, sizeMax: 4, speedMin: 30, speedMax: 90, lifeMin: 0.2, lifeMax: 0.45, gravity: 300, drag: 3, shrink: true }),\n burst: (colors = ['#ffd75e', '#ff9d47', '#fff2c9']): ParticleStyle => ({ colors, sizeMin: 2, sizeMax: 5, speedMin: 120, speedMax: 320, lifeMin: 0.25, lifeMax: 0.6, drag: 4, shrink: true }),\n hit: (colors = ['#ff5e5e', '#ffd0d0']): ParticleStyle => ({ colors, sizeMin: 2, sizeMax: 4, speedMin: 160, speedMax: 380, lifeMin: 0.15, lifeMax: 0.35, drag: 6, shrink: true }),\n sparkle: (colors = ['#9ef7ff', '#e8fdff', '#4ed8e8']): ParticleStyle => ({ colors, sizeMin: 1.5, sizeMax: 3.5, speedMin: 20, speedMax: 70, lifeMin: 0.4, lifeMax: 0.9, gravity: -40, drag: 2, shrink: true }),\n} as const;\n\n// \u2500\u2500 Ambient particle field (snow / rain / weather) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// A distinct preset family from the burst emitters above: instead of one-shot\n// `burst()` events, an AmbientField seeds a FIXED set of particles across a\n// screen-sized region and drifts them continuously, wrapping at the edges so the\n// field is effectively infinite. Fully cosmetic \u2014 its own Rng, out of the hash.\n// Weather intensity is a smoothstep envelope over SIM time (fixed `dt` from the\n// clock), never wall-clock, so replays and peers see the same storm.\n\nexport interface AmbientStyle {\n /** Colors drawn from at random per particle. */\n colors: string[];\n /** Particle radius range (px). */\n sizeMin: number;\n sizeMax: number;\n /** Steady horizontal wind (px/s). */\n windX?: number;\n /** Fall speed (px/s, +y down). Snow \u2248 40, rain \u2248 600. */\n fallY: number;\n /** Horizontal sway amplitude (px) and frequency (Hz) \u2014 gives snow its wobble. */\n swayAmp?: number;\n swayFreq?: number;\n /** Draw vertical streaks instead of dots (rain). */\n streak?: boolean;\n /** Streak length (px) in streak mode. Default = fallY * 0.03. */\n streakLen?: number;\n}\n\n/** A single weather keyframe: `intensity` (0..1) reached at sim `time` (s). */\nexport interface WeatherKey {\n time: number;\n intensity: number;\n}\n\n/**\n * Smoothstep-interpolated weather intensity at sim time `t` over an ordered list\n * of keyframes. Before the first / after the last key it holds that key's value.\n * Pure \u2014 drive it with `world.time`, never wall-clock.\n */\nexport function weatherEnvelope(t: number, keys: readonly WeatherKey[]): number {\n if (keys.length === 0) return 1;\n if (t <= keys[0].time) return keys[0].intensity;\n for (let i = 1; i < keys.length; i++) {\n if (t <= keys[i].time) {\n const a = keys[i - 1];\n const b = keys[i];\n return a.intensity + (b.intensity - a.intensity) * smoothstep(a.time, b.time, t);\n }\n }\n return keys[keys.length - 1].intensity;\n}\n\ninterface AmbientParticle {\n x: number;\n y: number;\n size: number;\n color: string;\n /** Sway phase offset so particles don't wobble in lockstep. */\n phase: number;\n /** Per-particle fall-speed multiplier (parallax depth). */\n depth: number;\n}\n\n/**\n * A screen-wrapping ambient field for snow, rain, dust, or ash. Seed once with a\n * region size; it fills itself and drifts forever. Set `.envelope` to fade the\n * weather in/out over sim time. Always cosmetic.\n */\nexport class AmbientField extends Node {\n override readonly type: string = 'AmbientField';\n private rng: Rng;\n private field: AmbientParticle[] = [];\n private time = 0;\n private style: AmbientStyle;\n /** Field region (px). Particles wrap within [0,width] \u00D7 [0,height]. */\n width: number;\n height: number;\n /** Optional weather intensity schedule; scales count/opacity. */\n envelope?: WeatherKey[];\n\n constructor(\n config: NodeConfig & {\n seed?: number;\n count?: number;\n width: number;\n height: number;\n style: AmbientStyle;\n envelope?: WeatherKey[];\n },\n ) {\n super(config);\n this.cosmetic = true;\n this.rng = new Rng(config.seed ?? 11);\n this.width = config.width;\n this.height = config.height;\n this.style = config.style;\n this.envelope = config.envelope;\n const count = config.count ?? 120;\n const s = this.style;\n for (let i = 0; i < count; i++) {\n this.field.push({\n x: this.rng.float() * this.width,\n y: this.rng.float() * this.height,\n size: s.sizeMin + this.rng.float() * (s.sizeMax - s.sizeMin),\n color: s.colors[this.rng.int(s.colors.length)],\n phase: this.rng.float() * TAU,\n depth: 0.5 + this.rng.float() * 0.5,\n });\n }\n }\n\n private intensity(): number {\n return this.envelope ? weatherEnvelope(this.time, this.envelope) : 1;\n }\n\n protected override onProcess(dt: number): void {\n this.time += dt;\n const s = this.style;\n const wind = s.windX ?? 0;\n const w = this.width;\n const h = this.height;\n for (const p of this.field) {\n p.y += s.fallY * p.depth * dt;\n p.x += wind * dt;\n // Wrap toroidally so the field never empties.\n if (p.y > h) p.y -= h;\n else if (p.y < 0) p.y += h;\n if (p.x > w) p.x -= w;\n else if (p.x < 0) p.x += w;\n }\n }\n\n protected override draw(out: DrawCommand[], world: Transform): void {\n const s = this.style;\n const intensity = this.intensity();\n if (intensity <= 0) return;\n // Envelope thins the field: draw only the first `intensity` fraction.\n const shown = Math.round(this.field.length * intensity);\n const swayAmp = s.swayAmp ?? 0;\n const swayFreq = s.swayFreq ?? 0;\n for (let i = 0; i < shown; i++) {\n const p = this.field[i];\n const sway = swayAmp !== 0 ? dsin(this.time * swayFreq * TAU + p.phase) * swayAmp : 0;\n const x = p.x + sway;\n if (s.streak) {\n const len = s.streakLen ?? s.fallY * 0.03;\n out.push({\n kind: 'poly',\n points: [x, p.y, x, p.y + len],\n closed: false,\n stroke: p.color,\n strokeWidth: p.size,\n opacity: intensity,\n transform: world,\n z: this.z,\n });\n } else {\n out.push({\n kind: 'circle',\n cx: x,\n cy: p.y,\n radius: p.size,\n fill: p.color,\n opacity: intensity,\n transform: world,\n z: this.z,\n });\n }\n }\n }\n\n get liveCount(): number {\n return this.field.length;\n }\n}\n\n/** Ready-made ambient weather styles (pair with `AmbientField`). */\nexport const AMBIENT_PRESETS = {\n snow: (colors = ['#ffffff', '#e8f0f8', '#cdd9e6']): AmbientStyle => ({ colors, sizeMin: 1.5, sizeMax: 3.5, windX: 8, fallY: 42, swayAmp: 14, swayFreq: 0.25 }),\n rain: (colors = ['#9fb4c8', '#c3d2e0']): AmbientStyle => ({ colors, sizeMin: 1, sizeMax: 1.8, windX: -40, fallY: 620, streak: true, streakLen: 16 }),\n ash: (colors = ['#6b6b6b', '#8a8580', '#3d3a36']): AmbientStyle => ({ colors, sizeMin: 1, sizeMax: 2.5, windX: 14, fallY: 26, swayAmp: 20, swayFreq: 0.18 }),\n} as const;\n\n/**\n * Screen shake as a cosmetic camera offset with its own Rng and exponential\n * decay. Attach to whatever node the camera follows and read `offset` into the\n * camera's position AFTER canonical follow logic \u2014 or simpler, add the shaker\n * as the camera's parent so the offset composes for free.\n */\nexport class Shaker extends Node {\n override readonly type: string = 'Shaker';\n private rng: Rng;\n private trauma = 0;\n /** Max offset in px at full trauma. */\n amplitude: number;\n /** Trauma decay per second. */\n decay: number;\n\n constructor(config: NodeConfig & { seed?: number; amplitude?: number; decay?: number } = {}) {\n super(config);\n this.cosmetic = true;\n this.rng = new Rng(config.seed ?? 99);\n this.amplitude = config.amplitude ?? 14;\n this.decay = config.decay ?? 2.6;\n }\n\n /** Add shake (0..1). Stacks, clamped to 1. Quadratic falloff feels right. */\n addTrauma(amount: number): void {\n this.trauma = Math.min(1, this.trauma + amount);\n }\n\n protected override onProcess(dt: number): void {\n this.trauma = Math.max(0, this.trauma - this.decay * dt);\n const s = this.trauma * this.trauma * this.amplitude;\n this.pos.x = (this.rng.float() * 2 - 1) * s;\n this.pos.y = (this.rng.float() * 2 - 1) * s;\n }\n}\n", "// Floating combat text: pooled rise-and-fade numbers/labels \u2014 the damage popups\n// every action/survivors/RPG game leans on. Cosmetic by construction, exactly\n// like Particles/Shaker: its own tiny Rng stream (never the world's, so deleting\n// it changes no game outcome), excluded from hashing, driven by the fixed dt.\n// Emission is triggered by sim events (hit for 12, healed, crit!), so replays\n// reproduce identical popups without any canonical state depending on them.\n\nimport { clamp } from '../core/math';\nimport { Rng } from '../core/rng';\nimport type { Transform, Vec2 } from '../core/math';\nimport type { DrawCommand, TextAlign } from '../render/commands';\nimport { Node, type NodeConfig } from './node';\n\nexport interface FloatStyle {\n /** Text colour. */\n color: string;\n /** Font size in px. */\n size?: number;\n font?: string;\n weight?: number;\n align?: TextAlign;\n /** Upward speed in px/s (screen +y is down, so this is negated internally). */\n rise?: number;\n /** Gravity pulling the rise back down (px/s\u00B2) \u2014 arcs the pop. */\n gravity?: number;\n /** Lifetime in seconds. */\n life?: number;\n /** Random horizontal spread of the launch (px/s). */\n jitter?: number;\n /** Fraction of life spent fading out at the end (0..1, default 0.4). */\n fade?: number;\n}\n\ninterface Popup {\n x: number;\n y: number;\n vx: number;\n vy: number;\n life: number;\n maxLife: number;\n text: string;\n color: string;\n size: number;\n font?: string;\n weight?: number;\n align: TextAlign;\n fade: number;\n}\n\n/**\n * A pooled floating-text emitter. Call `pop(text, at, style)` from game code in\n * response to feel events. Always cosmetic; add it wherever the numbers should\n * live in the tree (usually the world layer, so pops ride the camera).\n */\nexport class FloatingText extends Node {\n override readonly type: string = 'FloatingText';\n private pool: Popup[] = [];\n private rng: Rng;\n /** Cap on live popups (oldest recycled first). */\n maxPopups: number;\n\n constructor(config: NodeConfig & { seed?: number; maxPopups?: number } = {}) {\n super(config);\n this.cosmetic = true;\n this.rng = new Rng(config.seed ?? 31);\n this.maxPopups = config.maxPopups ?? 128;\n }\n\n /** Spawn one popup at `at` (in this node's local space). */\n pop(text: string, at: Vec2, style: FloatStyle): void {\n const jitter = style.jitter ?? 0;\n const p: Popup = {\n x: at.x + (this.rng.float() - 0.5) * jitter * 0.1,\n y: at.y,\n vx: (this.rng.float() - 0.5) * jitter,\n vy: -(style.rise ?? 60),\n life: 0,\n maxLife: Math.max(0.05, style.life ?? 0.9),\n text,\n color: style.color,\n size: style.size ?? 20,\n font: style.font,\n weight: style.weight,\n align: style.align ?? 'center',\n fade: clamp(style.fade ?? 0.4, 0, 1),\n };\n // Stash the shared gravity for the update step (single-style is the common case).\n this.gravity = style.gravity ?? 0;\n if (this.pool.length >= this.maxPopups) this.pool.shift();\n this.pool.push(p);\n }\n\n private gravity = 0;\n\n protected override onProcess(dt: number): void {\n let write = 0;\n for (const p of this.pool) {\n p.life += dt;\n if (p.life >= p.maxLife) continue;\n p.vy += this.gravity * dt;\n p.x += p.vx * dt;\n p.y += p.vy * dt;\n this.pool[write++] = p;\n }\n this.pool.length = write;\n }\n\n protected override draw(out: DrawCommand[], world: Transform): void {\n for (const p of this.pool) {\n const t = p.life / p.maxLife; // 0..1 through life\n const fadeStart = 1 - p.fade;\n const opacity = t < fadeStart ? 1 : clamp(1 - (t - fadeStart) / Math.max(1e-4, p.fade), 0, 1);\n out.push({\n kind: 'text',\n text: p.text,\n x: p.x,\n y: p.y,\n size: p.size,\n font: p.font,\n weight: p.weight,\n align: p.align,\n fill: p.color,\n opacity,\n transform: world,\n z: this.z,\n });\n }\n }\n\n get liveCount(): number {\n return this.pool.length;\n }\n}\n\n/** Ready-made popup looks for the common combat moments. */\nexport const FLOAT_PRESETS = {\n damage: (color = '#e14b4b'): FloatStyle => ({ color, size: 22, weight: 700, rise: 70, gravity: 120, life: 0.8, jitter: 40, fade: 0.4 }),\n crit: (color = '#ffb020'): FloatStyle => ({ color, size: 32, weight: 800, rise: 100, gravity: 160, life: 1.0, jitter: 60, fade: 0.35 }),\n heal: (color = '#4bb06a'): FloatStyle => ({ color, size: 20, weight: 700, rise: 55, gravity: 40, life: 1.0, jitter: 20, fade: 0.5 }),\n label: (color = '#3d3323'): FloatStyle => ({ color, size: 18, weight: 600, rise: 40, gravity: 0, life: 1.2, jitter: 0, fade: 0.5 }),\n} as const;\n", "// Node type registry \u2192 lets a serialized tree (save file / prefab / snapshot)\n// be rebuilt into live nodes. Built-in types register here; games can register\n// custom node types the same way.\n\nimport { Node, type SerializedNode } from './node';\nimport { Sprite, Text, Camera2D, Timer } from './nodes';\nimport { AnimationPlayer } from './tween';\n\nexport type NodeFactory = () => Node;\n\nconst registry = new Map<string, NodeFactory>();\n\nexport function registerNode(type: string, factory: NodeFactory): void {\n registry.set(type, factory);\n}\n\n// Built-ins. Sprite/Text/Timer need required config, so provide safe defaults\n// that applyProps() immediately overwrites during deserialization.\nregisterNode('Node', () => new Node());\nregisterNode('Sprite', () => new Sprite({ shape: { kind: 'rect', w: 1, h: 1 } }));\nregisterNode('Text', () => new Text({ text: '' }));\nregisterNode('Camera2D', () => new Camera2D());\nregisterNode('Timer', () => new Timer({ duration: 1 }));\nregisterNode('AnimationPlayer', () => new AnimationPlayer());\n\n/** Rebuild a live node tree from serialized data. */\nexport function deserializeNode(data: SerializedNode): Node {\n const factory = registry.get(data.type);\n if (!factory) throw new Error(`hayao: unknown node type \"${data.type}\" (register it first)`);\n const node = factory();\n node.name = data.name;\n node.pos = { ...data.pos };\n node.rotation = data.rotation;\n node.scale = { ...data.scale };\n node.z = data.z;\n node.visible = data.visible;\n node.applyProps(data.props);\n for (const child of data.children) node.addChild(deserializeNode(child));\n return node;\n}\n", "// Input as ACTIONS, not keys. Game logic asks \"is 'jump' down?\", never \"is 'KeyZ'\n// down?\". Input is sampled once per fixed step, so a run is a pure function of its\n// input log \u2014 which is what makes replay and scripted playthroughs exact.\n\n/** action name \u2192 physical key codes (KeyboardEvent.code strings). */\nexport type InputMap = Record<string, string[]>;\n\nexport class InputState {\n private down = new Set<string>();\n private prev = new Set<string>();\n /** Analog axes (e.g. from gamepad or pointer), sampled per step. */\n readonly axes = new Map<string, number>();\n\n /** Engine: set which actions are down this step (from live input or replay). */\n beginFrame(actionsDown: Iterable<string>): void {\n this.prev = new Set(this.down);\n this.down = new Set(actionsDown);\n }\n\n isDown(action: string): boolean {\n return this.down.has(action);\n }\n justPressed(action: string): boolean {\n return this.down.has(action) && !this.prev.has(action);\n }\n justReleased(action: string): boolean {\n return !this.down.has(action) && this.prev.has(action);\n }\n axis(name: string): number {\n return this.axes.get(name) ?? 0;\n }\n\n /** The current down-set as a stable sorted array (for recording). */\n snapshot(): string[] {\n return [...this.down].sort();\n }\n\n getState() {\n return { down: [...this.down].sort(), prev: [...this.prev].sort() };\n }\n setState(s: { down: string[]; prev: string[] }): void {\n this.down = new Set(s.down);\n this.prev = new Set(s.prev);\n }\n}\n\n/** Map a set of raw key codes to the set of actions they trigger. */\nexport function keysToActions(map: InputMap, keysDown: Set<string>): string[] {\n const actions: string[] = [];\n for (const action in map) {\n if (map[action].some((k) => keysDown.has(k))) actions.push(action);\n }\n return actions.sort();\n}\n\n/** Records the per-frame action-down sets \u2192 a compact, replayable input log. */\nexport class InputRecorder {\n private frames: string[][] = [];\n\n record(actionsDown: string[]): void {\n this.frames.push(actionsDown.slice().sort());\n }\n\n get length(): number {\n return this.frames.length;\n }\n\n toLog(): InputLog {\n return { frames: this.frames.map((f) => f.slice()) };\n }\n}\n\nexport interface InputLog {\n frames: string[][];\n}\n\n/** Replays a recorded log: returns the action set for frame index i. */\nexport function frameActions(log: InputLog, i: number): string[] {\n return log.frames[i] ?? [];\n}\n\n/** A default set of common bindings games can start from. */\nexport const DEFAULT_INPUT_MAP: InputMap = {\n up: ['ArrowUp', 'KeyW'],\n down: ['ArrowDown', 'KeyS'],\n left: ['ArrowLeft', 'KeyA'],\n right: ['ArrowRight', 'KeyD'],\n confirm: ['Enter', 'Space'],\n cancel: ['Escape', 'Backspace'],\n action: ['KeyZ', 'KeyJ'],\n action2: ['KeyX', 'KeyK'],\n undo: ['KeyU'],\n restart: ['KeyR'],\n};\n", "// Browser input source: tracks physical keys and maps them to actions each step.\n// Kept separate from InputState so the pure sim never imports DOM.\n\nimport { keysToActions, type InputMap } from './actions';\n\nexport class KeyboardSource {\n private keysDown = new Set<string>();\n /** Virtual action taps (from DOM buttons etc.) pending consumption by a step. */\n private pressed = new Set<string>();\n private map: InputMap;\n private target: Document | HTMLElement;\n private onDown: (e: KeyboardEvent) => void;\n private onUp: (e: KeyboardEvent) => void;\n private onBlur: () => void;\n\n constructor(map: InputMap, target: Document | HTMLElement = document) {\n this.map = map;\n this.target = target;\n this.onDown = (e) => {\n this.keysDown.add(e.code);\n // Prevent scroll on arrows/space during play.\n if (e.code.startsWith('Arrow') || e.code === 'Space') e.preventDefault();\n };\n this.onUp = (e) => this.keysDown.delete(e.code);\n this.onBlur = () => this.keysDown.clear();\n target.addEventListener('keydown', this.onDown as EventListener);\n target.addEventListener('keyup', this.onUp as EventListener);\n globalThis.addEventListener?.('blur', this.onBlur);\n }\n\n /** The actions currently held down, as a stable sorted array. */\n currentActions(): string[] {\n const acts = keysToActions(this.map, this.keysDown);\n if (this.pressed.size === 0) return acts;\n const merged = new Set(acts);\n for (const a of this.pressed) merged.add(a);\n return [...merged].sort();\n }\n\n /**\n * Virtually tap an action (DOM button, touch control). The tap is held until\n * at least one fixed step has sampled it \u2014 the driver calls clearPressed()\n * after a successful advance \u2014 so UI clicks enter the SAME deterministic\n * input log as keys, and record/replay covers them.\n */\n press(action: string): void {\n this.pressed.add(action);\n }\n\n /** Consume pending virtual taps (driver-called after \u22651 step ran). */\n clearPressed(): void {\n this.pressed.clear();\n }\n\n setMap(map: InputMap): void {\n this.map = map;\n }\n\n dispose(): void {\n this.target.removeEventListener('keydown', this.onDown as EventListener);\n this.target.removeEventListener('keyup', this.onUp as EventListener);\n globalThis.removeEventListener?.('blur', this.onBlur);\n }\n}\n", "// Tilemaps: grid collision geometry authored as ASCII. Plain data + pure\n// functions (house style) so maps serialize, hash, and diff cleanly.\n\nexport const TILE = {\n EMPTY: 0,\n SOLID: 1,\n /** Passable from below/sides; solid only when landing on its top edge. */\n ONEWAY: 2,\n HAZARD: 3,\n} as const;\nexport type TileId = (typeof TILE)[keyof typeof TILE];\n\nexport interface TilemapData {\n /** Size in tiles. */\n cols: number;\n rows: number;\n /** Tile edge in design-space px. */\n tileSize: number;\n /** Row-major tile ids, length cols*rows. */\n tiles: number[];\n}\n\n/** Default ASCII vocabulary: `#` solid, `-` one-way, `^` hazard, else empty. */\nexport const DEFAULT_TILE_CHARS: Record<string, TileId> = {\n '#': TILE.SOLID,\n '-': TILE.ONEWAY,\n '^': TILE.HAZARD,\n};\n\n/**\n * Build a tilemap from ASCII rows. Unknown characters are EMPTY, so level\n * strings can carry entity markers (`@` spawn, `*` shard\u2026) for game code to\n * read separately via `asciiEntities`.\n */\nexport function tilemapFromAscii(rowsAscii: string[], tileSize = 32, chars: Record<string, TileId> = DEFAULT_TILE_CHARS): TilemapData {\n const rows = rowsAscii.length;\n const cols = Math.max(...rowsAscii.map((r) => r.length));\n const tiles = new Array<number>(cols * rows).fill(TILE.EMPTY);\n rowsAscii.forEach((row, ty) => {\n for (let tx = 0; tx < row.length; tx++) tiles[ty * cols + tx] = chars[row[tx]] ?? TILE.EMPTY;\n });\n return { cols, rows, tileSize, tiles };\n}\n\n/** Extract entity markers (any char not in the tile vocabulary, not space/dot). */\nexport function asciiEntities(rowsAscii: string[], tileSize = 32, chars: Record<string, TileId> = DEFAULT_TILE_CHARS): { char: string; tx: number; ty: number; x: number; y: number }[] {\n const out: { char: string; tx: number; ty: number; x: number; y: number }[] = [];\n rowsAscii.forEach((row, ty) => {\n for (let tx = 0; tx < row.length; tx++) {\n const c = row[tx];\n if (c === ' ' || c === '.' || chars[c] !== undefined) continue;\n out.push({ char: c, tx, ty, x: (tx + 0.5) * tileSize, y: (ty + 0.5) * tileSize });\n }\n });\n return out;\n}\n\n/** Tile id at tile coords; out-of-bounds reads as SOLID (levels are sealed). */\nexport function tileAt(map: TilemapData, tx: number, ty: number): number {\n if (tx < 0 || ty < 0 || tx >= map.cols || ty >= map.rows) return TILE.SOLID;\n return map.tiles[ty * map.cols + tx];\n}\n\nexport function tileAtPoint(map: TilemapData, x: number, y: number): number {\n return tileAt(map, Math.floor(x / map.tileSize), Math.floor(y / map.tileSize));\n}\n\nexport const mapWidth = (map: TilemapData): number => map.cols * map.tileSize;\nexport const mapHeight = (map: TilemapData): number => map.rows * map.tileSize;\n", "// Kinematic AABB movement against a tilemap plus extra solid rects (moving\n// platforms). Axis-separated, analytically clamped to obstacle edges \u2014 no\n// tunneling, exact and deterministic. Pure functions over plain data.\n\nimport type { Rect } from '../core/math';\nimport { TILE, tileAt, type TilemapData } from './tilemap';\n\nconst EPS = 1e-6;\n\n/** An extra solid the body collides with (moving platform, door, crate\u2026). */\nexport interface SolidRect extends Rect {\n /** Solid only when landing on its top (jump-through platform). */\n oneway?: boolean;\n}\n\nexport interface MoveResult {\n x: number;\n y: number;\n hitX: boolean;\n hitY: boolean;\n onFloor: boolean;\n onCeiling: boolean;\n onWallLeft: boolean;\n onWallRight: boolean;\n /** Final rect overlaps a HAZARD tile (with a small forgiveness inset). */\n hazard: boolean;\n /** Index into `solids` of the rect the body stands on, or -1. */\n floorSolid: number;\n}\n\nconst spanTiles = (lo: number, hi: number, ts: number): [number, number] => [Math.floor(lo / ts), Math.floor((hi - EPS) / ts)];\n\nexport interface MoveOpts {\n solids?: SolidRect[];\n /** Pass true while the player holds \"down\" to drop through one-way platforms. */\n dropThrough?: boolean;\n}\n\n/** Would a rect at (x, y) overlap any solid geometry? (Used for corner-correction probes.) */\nexport function rectBlocked(map: TilemapData, x: number, y: number, w: number, h: number, solids: SolidRect[] = []): boolean {\n const ts = map.tileSize;\n const [tx0, tx1] = spanTiles(x, x + w, ts);\n const [ty0, ty1] = spanTiles(y, y + h, ts);\n for (let ty = ty0; ty <= ty1; ty++)\n for (let tx = tx0; tx <= tx1; tx++) if (tileAt(map, tx, ty) === TILE.SOLID) return true;\n for (const s of solids) {\n if (s.oneway) continue;\n if (x < s.x + s.w - EPS && x + w > s.x + EPS && y < s.y + s.h - EPS && y + h > s.y + EPS) return true;\n }\n return false;\n}\n\n/**\n * Move a rect by (dx, dy) with axis-separated collision: X first, then Y.\n * One-way surfaces block only downward motion that starts at-or-above their top.\n */\nexport function moveRect(map: TilemapData, rect: Rect, dx: number, dy: number, opts: MoveOpts = {}): MoveResult {\n const ts = map.tileSize;\n const solids = opts.solids ?? [];\n let { x, y } = rect;\n const { w, h } = rect;\n let hitX = false;\n let hitY = false;\n let onWallLeft = false;\n let onWallRight = false;\n\n // \u2500\u2500 X axis \u2500\u2500\n if (dx !== 0) {\n const [ty0, ty1] = spanTiles(y, y + h, ts);\n if (dx > 0) {\n let limit = x + dx; // furthest allowed left-edge position\n const [c0, c1] = [Math.floor((x + w) / ts), Math.floor((x + w + dx - EPS) / ts)];\n for (let tx = c0; tx <= c1; tx++)\n for (let ty = ty0; ty <= ty1; ty++)\n if (tileAt(map, tx, ty) === TILE.SOLID) limit = Math.min(limit, tx * ts - w);\n for (const s of solids)\n if (!s.oneway && s.y < y + h - EPS && s.y + s.h > y + EPS && s.x >= x + w - EPS) limit = Math.min(limit, s.x - w);\n if (limit < x + dx - EPS) {\n hitX = true;\n onWallRight = true;\n }\n x = Math.min(x + dx, limit);\n } else {\n let limit = x + dx;\n const [c0, c1] = [Math.floor((x - EPS) / ts), Math.floor((x + dx) / ts)];\n for (let tx = c0; tx >= c1; tx--)\n for (let ty = ty0; ty <= ty1; ty++)\n if (tileAt(map, tx, ty) === TILE.SOLID) limit = Math.max(limit, (tx + 1) * ts);\n for (const s of solids)\n if (!s.oneway && s.y < y + h - EPS && s.y + s.h > y + EPS && s.x + s.w <= x + EPS) limit = Math.max(limit, s.x + s.w);\n if (limit > x + dx + EPS) {\n hitX = true;\n onWallLeft = true;\n }\n x = Math.max(x + dx, limit);\n }\n }\n\n // \u2500\u2500 Y axis \u2500\u2500\n const prevBottom = y + h;\n let onFloor = false;\n let onCeiling = false;\n let floorSolid = -1;\n if (dy !== 0) {\n const [tx0, tx1] = spanTiles(x, x + w, ts);\n if (dy > 0) {\n let limit = y + dy; // furthest allowed top position\n const [r0, r1] = [Math.floor(prevBottom / ts), Math.floor((prevBottom + dy - EPS) / ts)];\n for (let ty = r0; ty <= r1; ty++)\n for (let tx = tx0; tx <= tx1; tx++) {\n const t = tileAt(map, tx, ty);\n const blocks = t === TILE.SOLID || (t === TILE.ONEWAY && !opts.dropThrough && prevBottom <= ty * ts + EPS);\n if (blocks) limit = Math.min(limit, ty * ts - h);\n }\n for (let i = 0; i < solids.length; i++) {\n const s = solids[i];\n const inX = s.x < x + w - EPS && s.x + s.w > x + EPS;\n if (!inX || s.y < prevBottom - EPS) continue;\n if (s.oneway && (opts.dropThrough || prevBottom > s.y + EPS)) continue;\n if (s.y - h < limit) {\n limit = s.y - h;\n floorSolid = i;\n }\n }\n if (limit < y + dy - EPS) {\n hitY = true;\n onFloor = true;\n } else floorSolid = -1;\n y = Math.min(y + dy, limit);\n } else {\n let limit = y + dy;\n const [r0, r1] = [Math.floor((y - EPS) / ts), Math.floor((y + dy) / ts)];\n for (let ty = r0; ty >= r1; ty--)\n for (let tx = tx0; tx <= tx1; tx++)\n if (tileAt(map, tx, ty) === TILE.SOLID) limit = Math.max(limit, (ty + 1) * ts);\n for (const s of solids)\n if (!s.oneway && s.x < x + w - EPS && s.x + s.w > x + EPS && s.y + s.h <= y + EPS) limit = Math.max(limit, s.y + s.h);\n if (limit > y + dy + EPS) {\n hitY = true;\n onCeiling = true;\n }\n y = Math.max(y + dy, limit);\n }\n }\n\n // \u2500\u2500 Ground probe (also true when dy was 0 or clamped exactly) \u2500\u2500\n if (!onFloor) {\n const probe = groundAt(map, x, y, w, h, solids, opts.dropThrough ?? false);\n onFloor = probe.grounded;\n floorSolid = probe.solid;\n }\n\n // \u2500\u2500 Hazard overlap (inset for forgiveness) \u2500\u2500\n const inset = 3;\n let hazard = false;\n {\n const [hx0, hx1] = spanTiles(x + inset, x + w - inset, ts);\n const [hy0, hy1] = spanTiles(y + inset, y + h - inset, ts);\n for (let ty = hy0; ty <= hy1 && !hazard; ty++)\n for (let tx = hx0; tx <= hx1 && !hazard; tx++) if (tileAt(map, tx, ty) === TILE.HAZARD) hazard = true;\n }\n\n return { x, y, hitX, hitY, onFloor, onCeiling, onWallLeft, onWallRight, hazard, floorSolid };\n}\n\n/** Is there support directly under the rect (within 1px)? */\nexport function groundAt(map: TilemapData, x: number, y: number, w: number, h: number, solids: SolidRect[] = [], dropThrough = false): { grounded: boolean; solid: number } {\n const ts = map.tileSize;\n const bottom = y + h;\n const [tx0, tx1] = spanTiles(x, x + w, ts);\n const ty = Math.floor((bottom + 1) / ts);\n for (let tx = tx0; tx <= tx1; tx++) {\n const t = tileAt(map, tx, ty);\n if (t === TILE.SOLID) return { grounded: true, solid: -1 };\n if (t === TILE.ONEWAY && !dropThrough && Math.abs(bottom - ty * ts) <= 1 + EPS) return { grounded: true, solid: -1 };\n }\n for (let i = 0; i < solids.length; i++) {\n const s = solids[i];\n const inX = s.x < x + w - EPS && s.x + s.w > x + EPS;\n if (inX && bottom <= s.y + 1 + EPS && bottom >= s.y - 1 - EPS) return { grounded: true, solid: i };\n }\n return { grounded: false, solid: -1 };\n}\n", "// PlatformerController: a state-of-the-art 2D kinematic character controller.\n// Pure and deterministic \u2014 plain-data state, stepped at the fixed timestep, no\n// engine imports beyond physics/math \u2014 so every game-feel feature below is\n// unit-testable in Node by pumping frames.\n//\n// Implements the modern platforming canon:\n// coyote time \u00B7 jump buffering \u00B7 variable jump height \u00B7 halved-gravity apex\n// jump corner correction \u00B7 dash (8-way) \u00B7 dash corner correction\n// wall slide + wall jump \u00B7 moving-platform carry + lift momentum storage\n// one-way platforms + drop-through\n\nimport { dhypot } from '../core/dmath';\nimport { moveRect, rectBlocked, type SolidRect } from './aabb';\nimport type { TilemapData } from './tilemap';\n\nexport interface PlatformerConfig {\n width: number;\n height: number;\n /** Ground run speed (px/s) and accelerations (px/s\u00B2). */\n runSpeed: number;\n groundAccel: number;\n groundFriction: number;\n airAccel: number;\n /**\n * Horizontal decel with no input while airborne (px/s\u00B2). Keep LOW: inherited\n * momentum (lift jumps, wall kicks) must survive flight to feel right.\n */\n airFriction: number;\n /** Gravity (px/s\u00B2), terminal fall speed, and the apex modifier. */\n gravity: number;\n maxFall: number;\n /** |vy| below this counts as the jump apex\u2026 */\n apexThreshold: number;\n /** \u2026where gravity is multiplied by this while jump is held (the floaty peak). */\n apexGravityMult: number;\n /** Initial jump velocity (px/s, upward) and early-release cut multiplier. */\n jumpVelocity: number;\n jumpCutMult: number;\n /** Grace timers (seconds). */\n coyoteTime: number;\n jumpBuffer: number;\n /** Max px the body is nudged sideways to slip past a ceiling corner when jumping. */\n jumpCornerNudge: number;\n /** Max px the body is nudged vertically to slip past a corner while dashing. */\n dashCornerNudge: number;\n /** Mid-air jumps (0 = none, 1 = double jump\u2026), refilled on landing/wall. */\n airJumps: number;\n /** Air-jump velocity as a fraction of jumpVelocity. */\n airJumpMult: number;\n /** Dash: speed (px/s), duration (s), cooldown (s), charges refilled on landing. */\n dashSpeed: number;\n dashTime: number;\n dashCooldown: number;\n dashCharges: number;\n /** Wall interaction. */\n wallSlideMaxFall: number;\n wallJumpVelX: number;\n wallJumpVelY: number;\n /** Seconds after a wall jump during which input can't cancel the outward velocity. */\n wallJumpLock: number;\n}\n\n/** Tuned for 32px tiles at 60Hz in the 1280\u00D7720 design space. */\nexport const DEFAULT_PLATFORMER: PlatformerConfig = {\n width: 22,\n height: 28,\n runSpeed: 340,\n groundAccel: 3800,\n groundFriction: 4200,\n airAccel: 2600,\n airFriction: 260,\n gravity: 2300,\n maxFall: 660,\n apexThreshold: 60,\n apexGravityMult: 0.5,\n jumpVelocity: 650,\n jumpCutMult: 0.4,\n coyoteTime: 0.1,\n jumpBuffer: 0.12,\n jumpCornerNudge: 10,\n dashCornerNudge: 12,\n airJumps: 0,\n airJumpMult: 0.92,\n dashSpeed: 640,\n dashTime: 0.14,\n dashCooldown: 0.25,\n dashCharges: 1,\n wallSlideMaxFall: 150,\n wallJumpVelX: 360,\n wallJumpVelY: 600,\n wallJumpLock: 0.13,\n};\n\n/** Per-step intent, sampled from actions by the game (never raw keys). */\nexport interface PadInput {\n moveX: number; // -1 | 0 | 1\n moveY: number; // -1 (up) | 0 | 1 (down)\n jumpHeld: boolean;\n jumpPressed: boolean;\n dashPressed: boolean;\n}\n\nexport const PAD_NEUTRAL: PadInput = { moveX: 0, moveY: 0, jumpHeld: false, jumpPressed: false, dashPressed: false };\n\n/** A moving platform: its current rect, plus its velocity this step (px/s). */\nexport interface Platform extends SolidRect {\n vx: number;\n vy: number;\n}\n\n/** Plain serializable controller state \u2014 put it in `world.state` so it hashes. */\nexport interface PlatformerState {\n x: number; // top-left of the collision box\n y: number;\n vx: number;\n vy: number;\n facing: number; // -1 | 1\n onGround: boolean;\n onWall: number; // -1 touching left wall, 1 right, 0 none\n coyote: number;\n buffer: number;\n jumping: boolean; // rising from a jump (variable-height window)\n wallLock: number;\n airJumpsLeft: number;\n dashing: number; // time left in current dash\n dashCd: number;\n dashesLeft: number;\n dashVx: number;\n dashVy: number;\n /** Velocity inherited from the platform we stand on (lift momentum storage). */\n carryVx: number;\n carryVy: number;\n dead: boolean;\n}\n\nexport function createPlatformerState(x: number, y: number): PlatformerState {\n return { x, y, vx: 0, vy: 0, facing: 1, onGround: false, onWall: 0, coyote: 0, buffer: 0, jumping: false, wallLock: 0, airJumpsLeft: 0, dashing: 0, dashCd: 0, dashesLeft: 1, dashVx: 0, dashVy: 0, carryVx: 0, carryVy: 0, dead: false };\n}\n\n/** Feel events emitted by a step \u2014 hooks for SFX / particles / screen shake. */\nexport interface PlatformerEvents {\n jumped: boolean;\n wallJumped: boolean;\n airJumped: boolean;\n dashed: boolean;\n landed: boolean;\n died: boolean;\n}\n\nconst approach = (v: number, target: number, delta: number): number => (v < target ? Math.min(v + delta, target) : Math.max(v - delta, target));\n\n/**\n * Advance the controller one fixed step. Mutates `s`; returns feel events.\n * `platforms` should already be at their post-move positions for this step,\n * with `vx/vy` set to their velocity, so the body is carried exactly.\n */\nexport function stepPlatformer(s: PlatformerState, input: PadInput, dt: number, map: TilemapData, cfg: PlatformerConfig = DEFAULT_PLATFORMER, platforms: Platform[] = []): PlatformerEvents {\n const ev: PlatformerEvents = { jumped: false, wallJumped: false, airJumped: false, dashed: false, landed: false, died: false };\n if (s.dead) return ev;\n const wasGrounded = s.onGround;\n\n // \u2500\u2500 Timers \u2500\u2500\n s.coyote = Math.max(0, s.coyote - dt);\n s.buffer = Math.max(0, s.buffer - dt);\n s.wallLock = Math.max(0, s.wallLock - dt);\n s.dashCd = Math.max(0, s.dashCd - dt);\n if (input.jumpPressed) s.buffer = cfg.jumpBuffer;\n\n // \u2500\u2500 Dash start \u2500\u2500\n if (input.dashPressed && s.dashing <= 0 && s.dashCd <= 0 && s.dashesLeft > 0) {\n let dx = input.moveX;\n let dy = input.moveY;\n if (dx === 0 && dy === 0) dx = s.facing;\n const inv = 1 / dhypot(dx, dy);\n s.dashing = cfg.dashTime;\n s.dashCd = cfg.dashCooldown;\n s.dashesLeft--;\n s.dashVx = dx * inv * cfg.dashSpeed;\n s.dashVy = dy * inv * cfg.dashSpeed;\n s.jumping = false;\n ev.dashed = true;\n }\n\n // \u2500\u2500 Horizontal intent \u2500\u2500\n if (s.dashing > 0) {\n s.vx = s.dashVx;\n s.vy = s.dashVy;\n s.dashing -= dt;\n } else if (s.wallLock <= 0) {\n const target = input.moveX * cfg.runSpeed;\n const accel = s.onGround ? (input.moveX !== 0 ? cfg.groundAccel : cfg.groundFriction) : input.moveX !== 0 ? cfg.airAccel : cfg.airFriction;\n s.vx = approach(s.vx, target, accel * dt);\n if (input.moveX !== 0) s.facing = input.moveX > 0 ? 1 : -1;\n }\n\n // \u2500\u2500 Gravity (skipped while dashing) \u2500\u2500\n if (s.dashing <= 0 && !s.onGround) {\n let g = cfg.gravity;\n if (Math.abs(s.vy) < cfg.apexThreshold && input.jumpHeld && s.jumping) g *= cfg.apexGravityMult; // halved-gravity peak\n s.vy = Math.min(s.vy + g * dt, cfg.maxFall);\n if (s.onWall !== 0 && s.vy > cfg.wallSlideMaxFall && input.moveX === s.onWall) s.vy = cfg.wallSlideMaxFall; // wall slide\n }\n\n // \u2500\u2500 Variable jump height: release cuts upward velocity \u2500\u2500\n if (s.jumping && !input.jumpHeld && s.vy < 0) {\n s.vy *= cfg.jumpCutMult;\n s.jumping = false;\n }\n\n // \u2500\u2500 Jump (buffered + coyote) / wall jump \u2500\u2500\n if (s.buffer > 0 && s.dashing <= 0) {\n if (s.onGround || s.coyote > 0) {\n s.vy = -cfg.jumpVelocity;\n // Lift momentum storage: keep the platform's motion.\n s.vx += s.carryVx;\n if (s.carryVy < 0) s.vy += s.carryVy;\n s.jumping = true;\n s.buffer = 0;\n s.coyote = 0;\n s.onGround = false;\n ev.jumped = true;\n } else if (s.onWall !== 0 && cfg.wallJumpVelY > 0) {\n s.vx = -s.onWall * cfg.wallJumpVelX;\n s.vy = -cfg.wallJumpVelY;\n s.facing = -s.onWall;\n s.jumping = true;\n s.buffer = 0;\n s.wallLock = cfg.wallJumpLock;\n ev.wallJumped = true;\n ev.jumped = true;\n } else if (s.airJumpsLeft > 0) {\n s.vy = -cfg.jumpVelocity * cfg.airJumpMult;\n s.airJumpsLeft--;\n s.jumping = true;\n s.buffer = 0;\n ev.jumped = true;\n ev.airJumped = true;\n }\n }\n\n // \u2500\u2500 Move-and-collide, with platform carry \u2500\u2500\n // Holding down passes through one-ways \u2014 INCLUDING while already falling,\n // or the body re-lands on the platform lip one frame after leaving it.\n const dropThrough = input.moveY > 0 && s.buffer <= 0;\n let dx = s.vx * dt + s.carryVx * dt * (s.onGround ? 1 : 0);\n let dy = s.vy * dt + Math.max(0, s.carryVy) * dt * (s.onGround ? 1 : 0);\n let res = moveRect(map, { x: s.x, y: s.y, w: cfg.width, h: cfg.height }, dx, dy, { solids: platforms, dropThrough });\n\n // \u2500\u2500 Jump corner correction: bonked a ceiling edge while rising \u2192 nudge sideways \u2500\u2500\n if (res.onCeiling && s.vy < 0 && s.dashing <= 0) {\n const slip = cornerSlipX(map, platforms, res.x, res.y, cfg.width, cfg.height, dy, cfg.jumpCornerNudge);\n if (slip !== null) {\n res = moveRect(map, { x: slip, y: res.y, w: cfg.width, h: cfg.height }, 0, dy, { solids: platforms, dropThrough });\n res.x = slip;\n }\n }\n\n // \u2500\u2500 Dash corner correction: clipped a wall edge while dashing \u2192 nudge vertically \u2500\u2500\n if (res.hitX && s.dashing > 0 && Math.abs(s.dashVy) < 1) {\n const slip = cornerSlipY(map, platforms, res.x, res.y, cfg.width, cfg.height, dx, cfg.dashCornerNudge);\n if (slip !== null) {\n res = moveRect(map, { x: res.x, y: slip, w: cfg.width, h: cfg.height }, dx, 0, { solids: platforms, dropThrough });\n res.y = slip;\n }\n }\n\n s.x = res.x;\n s.y = res.y;\n if (res.hitY && s.vy > 0) s.vy = 0;\n if (res.onCeiling) {\n s.vy = Math.max(s.vy, 0);\n s.jumping = false;\n }\n if (res.hitX && s.dashing <= 0) s.vx = 0;\n s.onWall = res.onWallLeft ? -1 : res.onWallRight ? 1 : wallTouch(map, platforms, s.x, s.y, cfg.width, cfg.height);\n s.onGround = res.onFloor;\n\n // \u2500\u2500 Ground bookkeeping: coyote, dash refill, landing, lift momentum \u2500\u2500\n if (s.onGround) {\n s.coyote = cfg.coyoteTime;\n s.dashesLeft = cfg.dashCharges;\n s.airJumpsLeft = cfg.airJumps;\n if (!wasGrounded) ev.landed = true;\n if (res.floorSolid >= 0) {\n const p = platforms[res.floorSolid];\n s.carryVx = p.vx;\n s.carryVy = p.vy;\n // Ride the platform exactly: snap feet to its top.\n s.y = p.y - cfg.height;\n } else {\n s.carryVx = 0;\n s.carryVy = 0;\n }\n if (s.vy > 0) s.vy = 0;\n s.jumping = false;\n } else if (wasGrounded && s.carryVy !== 0) {\n // Walked off a lift: keep stored momentum until landing or jumping.\n }\n\n if (res.hazard) {\n s.dead = true;\n ev.died = true;\n }\n return ev;\n}\n\n// \u2500\u2500 Movement envelope: derive level geometry from the config, never guess \u2500\u2500\n// Conservative closed-form bounds (they ignore the apex-gravity bonus, so the\n// real controller always reaches at least this far). Author levels against\n// these \u2014 \"it looks jumpable\" is how unwinnable geometry ships.\n\n/** Max rise of a full jump (px). */\nexport function jumpHeight(cfg: PlatformerConfig = DEFAULT_PLATFORMER): number {\n return (cfg.jumpVelocity * cfg.jumpVelocity) / (2 * cfg.gravity);\n}\n\n/** Full-jump airtime returning to takeoff height (s). */\nexport function jumpAirtime(cfg: PlatformerConfig = DEFAULT_PLATFORMER): number {\n return (2 * cfg.jumpVelocity) / cfg.gravity;\n}\n\n/** Max horizontal gap clearable by a running jump (px, flat-to-flat). */\nexport function jumpDistance(cfg: PlatformerConfig = DEFAULT_PLATFORMER): number {\n return cfg.runSpeed * jumpAirtime(cfg);\n}\n\n/** Max gap clearable by jump + one apex dash (px, flat-to-flat, horizontal dash). */\nexport function dashJumpDistance(cfg: PlatformerConfig = DEFAULT_PLATFORMER): number {\n return jumpDistance(cfg) + (cfg.dashSpeed - cfg.runSpeed) * cfg.dashTime;\n}\n\n/** Try shifting x by up to \u00B1nudge so a rect moving by dy is unblocked. Prefers the smaller shift. */\nfunction cornerSlipX(map: TilemapData, solids: SolidRect[], x: number, y: number, w: number, h: number, dy: number, nudge: number): number | null {\n for (let n = 1; n <= nudge; n++) {\n for (const dir of [1, -1]) {\n const nx = x + dir * n;\n if (!rectBlocked(map, nx, y + dy, w, h, solids) && !rectBlocked(map, nx, y, w, h, solids)) return nx;\n }\n }\n return null;\n}\n\n/** Try shifting y by up to \u00B1nudge so a rect moving by dx is unblocked. */\nfunction cornerSlipY(map: TilemapData, solids: SolidRect[], x: number, y: number, w: number, h: number, dx: number, nudge: number): number | null {\n for (let n = 1; n <= nudge; n++) {\n for (const dir of [-1, 1]) {\n const ny = y + dir * n;\n if (!rectBlocked(map, x + dx, ny, w, h, solids) && !rectBlocked(map, x, ny, w, h, solids)) return ny;\n }\n }\n return null;\n}\n\n/** Which wall (if any) is the body pressed against? (1px probes) */\nfunction wallTouch(map: TilemapData, solids: SolidRect[], x: number, y: number, w: number, h: number): number {\n if (rectBlocked(map, x + 1, y, w, h, solids)) return 1;\n if (rectBlocked(map, x - 1, y, w, h, solids)) return -1;\n return 0;\n}\n", "// Uniform-grid spatial hash for broad-phase queries over many moving entities\n// (hordes, bullets, RTS units). Deterministic: iteration order is insertion\n// order within cells, and query results preserve first-insertion order.\n// Rebuild-per-step is the intended pattern \u2014 clear() + insert all \u2014 which is\n// O(n) and avoids stale incremental state entirely.\n\nimport type { Rect } from '../core/math';\n\nexport class SpatialHash<T> {\n private cells = new Map<number, T[]>();\n private bounds = new Map<T, Rect>();\n private readonly cellSize: number;\n\n constructor(cellSize = 64) {\n this.cellSize = cellSize;\n }\n\n clear(): void {\n this.cells.clear();\n this.bounds.clear();\n }\n\n get size(): number {\n return this.bounds.size;\n }\n\n private key(cx: number, cy: number): number {\n // Interleave-free packing; fine for worlds within \u00B12^15 cells.\n return (cx + 32768) * 65536 + (cy + 32768);\n }\n\n insert(item: T, rect: Rect): void {\n this.bounds.set(item, rect);\n const cs = this.cellSize;\n const x0 = Math.floor(rect.x / cs);\n const x1 = Math.floor((rect.x + rect.w) / cs);\n const y0 = Math.floor(rect.y / cs);\n const y1 = Math.floor((rect.y + rect.h) / cs);\n for (let cy = y0; cy <= y1; cy++)\n for (let cx = x0; cx <= x1; cx++) {\n const k = this.key(cx, cy);\n const cell = this.cells.get(k);\n if (cell) cell.push(item);\n else this.cells.set(k, [item]);\n }\n }\n\n /** All items whose rects overlap the query rect (deduplicated, deterministic order). */\n query(rect: Rect): T[] {\n const cs = this.cellSize;\n const x0 = Math.floor(rect.x / cs);\n const x1 = Math.floor((rect.x + rect.w) / cs);\n const y0 = Math.floor(rect.y / cs);\n const y1 = Math.floor((rect.y + rect.h) / cs);\n const seen = new Set<T>();\n const out: T[] = [];\n for (let cy = y0; cy <= y1; cy++)\n for (let cx = x0; cx <= x1; cx++) {\n const cell = this.cells.get(this.key(cx, cy));\n if (!cell) continue;\n for (const item of cell) {\n if (seen.has(item)) continue;\n seen.add(item);\n const b = this.bounds.get(item)!;\n if (b.x < rect.x + rect.w && b.x + b.w > rect.x && b.y < rect.y + rect.h && b.y + b.h > rect.y) out.push(item);\n }\n }\n return out;\n }\n\n /** All items within `radius` of a point (circle vs rect-center test on bounds). */\n queryCircle(x: number, y: number, radius: number): T[] {\n const near = this.query({ x: x - radius, y: y - radius, w: radius * 2, h: radius * 2 });\n return near.filter((item) => {\n const b = this.bounds.get(item)!;\n const cx = Math.max(b.x, Math.min(x, b.x + b.w));\n const cy = Math.max(b.y, Math.min(y, b.y + b.h));\n return (x - cx) * (x - cx) + (y - cy) * (y - cy) <= radius * radius;\n });\n }\n}\n", "// Grid raycasting (DDA) over a tilemap \u2014 the sight primitive behind stealth\n// vision cones, sentry line-of-sight, roguelike FOV, and 2D lighting.\n\nimport { dcos, dhypot } from '../core/dmath';\nimport { TILE, tileAt, type TilemapData } from './tilemap';\n\nexport interface RayHit {\n /** True if a solid tile stopped the ray before reaching (x1, y1). */\n blocked: boolean;\n /** Where the ray stopped (the hit point, or the target if unblocked). */\n x: number;\n y: number;\n /** Distance travelled. */\n dist: number;\n}\n\n/**\n * March a ray from (x0,y0) toward (x1,y1) through the tile grid (DDA \u2014 exact,\n * no step-size tuning). SOLID tiles block; everything else passes.\n */\nexport function raycastTiles(map: TilemapData, x0: number, y0: number, x1: number, y1: number): RayHit {\n const ts = map.tileSize;\n const dx = x1 - x0;\n const dy = y1 - y0;\n const maxDist = dhypot(dx, dy);\n if (maxDist === 0) return { blocked: false, x: x1, y: y1, dist: 0 };\n const dirX = dx / maxDist;\n const dirY = dy / maxDist;\n\n let tx = Math.floor(x0 / ts);\n let ty = Math.floor(y0 / ts);\n const stepX = dirX > 0 ? 1 : -1;\n const stepY = dirY > 0 ? 1 : -1;\n const tDeltaX = dirX !== 0 ? Math.abs(ts / dirX) : Infinity;\n const tDeltaY = dirY !== 0 ? Math.abs(ts / dirY) : Infinity;\n let tMaxX = dirX !== 0 ? (dirX > 0 ? (tx + 1) * ts - x0 : x0 - tx * ts) / Math.abs(dirX) : Infinity;\n let tMaxY = dirY !== 0 ? (dirY > 0 ? (ty + 1) * ts - y0 : y0 - ty * ts) / Math.abs(dirY) : Infinity;\n\n let t = 0;\n // The starting tile never blocks (the caster stands in it).\n for (let guard = 0; guard < 512; guard++) {\n if (tMaxX < tMaxY) {\n t = tMaxX;\n tMaxX += tDeltaX;\n tx += stepX;\n } else {\n t = tMaxY;\n tMaxY += tDeltaY;\n ty += stepY;\n }\n if (t >= maxDist) return { blocked: false, x: x1, y: y1, dist: maxDist };\n if (tileAt(map, tx, ty) === TILE.SOLID) {\n return { blocked: true, x: x0 + dirX * t, y: y0 + dirY * t, dist: t };\n }\n }\n return { blocked: true, x: x0 + dirX * t, y: y0 + dirY * t, dist: t };\n}\n\n/** Can a see b with no solid tile between? */\nexport function lineOfSight(map: TilemapData, ax: number, ay: number, bx: number, by: number): boolean {\n return !raycastTiles(map, ax, ay, bx, by).blocked;\n}\n\n/**\n * Is the target inside a vision cone AND visible? (facing is a unit vector;\n * fov is the FULL cone angle in radians.)\n */\nexport function inVisionCone(map: TilemapData, ex: number, ey: number, faceX: number, faceY: number, fov: number, range: number, tx: number, ty: number): boolean {\n const dx = tx - ex;\n const dy = ty - ey;\n const d = dhypot(dx, dy);\n if (d > range || d === 0) return false;\n const dot = (dx * faceX + dy * faceY) / d;\n if (dot < dcos(fov / 2)) return false;\n return lineOfSight(map, ex, ey, tx, ty);\n}\n", "// Deterministic 2D rigid-body dynamics \u2014 data model. The whole physics world\n// is PLAIN JSON (no classes, no hidden caches), so it can live in\n// `world.state` and inherit hashing, snapshot/restore, replay verification,\n// and structuredClone-based planning bots for free. Pure functions over data.\n//\n// Units are pixels / seconds / radians. Only mass RATIOS matter to the\n// solver; density defaults keep numbers small. Convention: a body's local\n// origin is its center of mass (use `polygonBox`/`regularPolygon` helpers).\n\nimport { dcos, dsin } from '../core/dmath';\nimport type { Rect } from '../core/math';\n\nexport type RigidShape =\n | { kind: 'circle'; r: number }\n /** Convex polygon, CCW winding, local coords flat [x0,y0,x1,y1,\u2026]. */\n | { kind: 'poly'; points: number[] };\n\nexport type BodyKind = 'dynamic' | 'static' | 'kinematic';\n\nexport interface RigidBody {\n id: number;\n kind: BodyKind;\n shape: RigidShape;\n /** Pose: position of the center of mass + rotation. */\n x: number; y: number; a: number;\n /** Velocity: linear + angular (rad/s). */\n vx: number; vy: number; w: number;\n /** Mass properties (0 inverse = immovable / non-rotating). */\n m: number; invM: number; i: number; invI: number;\n restitution: number;\n friction: number;\n linDamp: number;\n angDamp: number;\n gravityScale: number;\n /** Swept-circle CCD each step (circles only) \u2014 for very fast bodies. */\n bullet: boolean;\n /** Overlap events only, no collision response. */\n sensor: boolean;\n /** Collision filtering: collide iff (a.mask & b.layer) && (b.mask & a.layer). */\n layer: number;\n mask: number;\n canSleep: boolean;\n sleeping: boolean;\n sleepTime: number;\n /** Characteristic radius: converts spin to rim speed for the sleep test. */\n sleepR: number;\n /** Per-step force/torque accumulators (cleared after integration). */\n fx: number; fy: number; torque: number;\n}\n\nexport interface RigidWorldOpts {\n gravityX?: number;\n gravityY?: number;\n /** Solver velocity iterations (default 16 \u2014 stacks need it). */\n iterations?: number;\n /** Broadphase cell size in px (default 96). */\n cellSize?: number;\n}\n\nexport interface RigidWorld {\n gravityX: number;\n gravityY: number;\n iterations: number;\n cellSize: number;\n nextId: number;\n bodies: RigidBody[];\n joints: import('./rigidJoints').Joint[];\n /** Warm-start impulse cache from the previous step, keyed \"a:b:feature\". */\n warm: Record<string, [number, number]>;\n}\n\nexport function createRigidWorld(opts: RigidWorldOpts = {}): RigidWorld {\n return {\n gravityX: opts.gravityX ?? 0,\n gravityY: opts.gravityY ?? 900,\n iterations: opts.iterations ?? 16,\n cellSize: opts.cellSize ?? 96,\n nextId: 1,\n bodies: [],\n joints: [],\n warm: {},\n };\n}\n\nexport interface RigidBodyDef {\n kind?: BodyKind;\n shape: RigidShape;\n x?: number; y?: number; a?: number;\n vx?: number; vy?: number; w?: number;\n density?: number;\n restitution?: number;\n friction?: number;\n linDamp?: number;\n angDamp?: number;\n gravityScale?: number;\n bullet?: boolean;\n sensor?: boolean;\n layer?: number;\n mask?: number;\n canSleep?: boolean;\n /** Lock rotation (players, elevators): infinite inertia. */\n fixedRotation?: boolean;\n}\n\n/** Area + second moment of area (about the local origin) for a shape. */\nfunction massProps(shape: RigidShape): { area: number; unitI: number } {\n if (shape.kind === 'circle') {\n const area = Math.PI * shape.r * shape.r;\n return { area, unitI: (shape.r * shape.r) / 2 }; // I = m r\u00B2/2\n }\n // Convex polygon: standard cross-product accumulation about the origin.\n const p = shape.points;\n const n = p.length / 2;\n let area = 0;\n let inertia = 0;\n for (let k = 0; k < n; k++) {\n const x0 = p[k * 2], y0 = p[k * 2 + 1];\n const j = (k + 1) % n;\n const x1 = p[j * 2], y1 = p[j * 2 + 1];\n const cross = x0 * y1 - x1 * y0;\n area += cross / 2;\n inertia += (cross * (x0 * x0 + x0 * x1 + x1 * x1 + y0 * y0 + y0 * y1 + y1 * y1)) / 12;\n }\n return { area: Math.abs(area), unitI: area !== 0 ? Math.abs(inertia) / Math.abs(area) : 0 };\n}\n\n/** Mass scale keeps typical bodies O(0.1\u201310) so impulses stay well-ranged. */\nconst DENSITY_SCALE = 1e-4;\n\nexport function addBody(rw: RigidWorld, def: RigidBodyDef): number {\n const kind = def.kind ?? 'dynamic';\n const density = def.density ?? 1;\n const { area, unitI } = massProps(def.shape);\n const m = kind === 'dynamic' ? Math.max(area * density * DENSITY_SCALE, 1e-6) : 0;\n const i = kind === 'dynamic' && !def.fixedRotation ? m * unitI : 0;\n const body: RigidBody = {\n id: rw.nextId++,\n kind,\n shape: def.shape,\n x: def.x ?? 0, y: def.y ?? 0, a: def.a ?? 0,\n vx: def.vx ?? 0, vy: def.vy ?? 0, w: def.w ?? 0,\n m, invM: m > 0 ? 1 / m : 0,\n i, invI: i > 0 ? 1 / i : 0,\n restitution: def.restitution ?? 0.1,\n friction: def.friction ?? 0.4,\n linDamp: def.linDamp ?? 0,\n angDamp: def.angDamp ?? 0.6,\n gravityScale: def.gravityScale ?? 1,\n bullet: def.bullet ?? false,\n sensor: def.sensor ?? false,\n layer: def.layer ?? 1,\n mask: def.mask ?? 0xffff,\n canSleep: def.canSleep ?? true,\n sleeping: false,\n sleepTime: 0,\n sleepR: def.shape.kind === 'circle'\n ? def.shape.r\n : Math.sqrt(def.shape.points.reduce((m, _, i, p) => (i % 2 ? m : Math.max(m, p[i] * p[i] + p[i + 1] * p[i + 1])), 0)),\n fx: 0, fy: 0, torque: 0,\n };\n rw.bodies.push(body);\n return body.id;\n}\n\nexport function getBody(rw: RigidWorld, id: number): RigidBody | undefined {\n const bs = rw.bodies;\n for (let k = 0; k < bs.length; k++) if (bs[k].id === id) return bs[k];\n return undefined;\n}\n\nexport function removeBody(rw: RigidWorld, id: number): void {\n const idx = rw.bodies.findIndex((b) => b.id === id);\n if (idx >= 0) rw.bodies.splice(idx, 1);\n rw.joints = rw.joints.filter((j) => j.a !== id && j.b !== id);\n}\n\nexport function wakeBody(b: RigidBody): void {\n b.sleeping = false;\n b.sleepTime = 0;\n}\n\n/** Apply an impulse at a world point (wakes the body). */\nexport function applyImpulse(rw: RigidWorld, id: number, ix: number, iy: number, px?: number, py?: number): void {\n const b = getBody(rw, id);\n if (!b || b.invM === 0) return;\n wakeBody(b);\n b.vx += ix * b.invM;\n b.vy += iy * b.invM;\n if (px !== undefined && py !== undefined) {\n b.w += ((px - b.x) * iy - (py - b.y) * ix) * b.invI;\n }\n}\n\n/** World-space vertices of a poly body (freshly computed \u2014 no caches). */\nexport function worldPoints(b: RigidBody): number[] {\n if (b.shape.kind !== 'poly') return [];\n const c = dcos(b.a), s = dsin(b.a);\n const p = b.shape.points;\n const out = new Array<number>(p.length);\n for (let k = 0; k < p.length; k += 2) {\n out[k] = b.x + p[k] * c - p[k + 1] * s;\n out[k + 1] = b.y + p[k] * s + p[k + 1] * c;\n }\n return out;\n}\n\nexport function bodyAABB(b: RigidBody): Rect {\n if (b.shape.kind === 'circle') {\n const r = b.shape.r;\n return { x: b.x - r, y: b.y - r, w: r * 2, h: r * 2 };\n }\n const wp = worldPoints(b);\n let x0 = Infinity, y0 = Infinity, x1 = -Infinity, y1 = -Infinity;\n for (let k = 0; k < wp.length; k += 2) {\n if (wp[k] < x0) x0 = wp[k];\n if (wp[k] > x1) x1 = wp[k];\n if (wp[k + 1] < y0) y0 = wp[k + 1];\n if (wp[k + 1] > y1) y1 = wp[k + 1];\n }\n return { x: x0, y: y0, w: x1 - x0, h: y1 - y0 };\n}\n\n/** Centered box as a CCW convex polygon \u2014 the workhorse shape helper. */\nexport function polygonBox(w: number, h: number): RigidShape {\n const hw = w / 2, hh = h / 2;\n return { kind: 'poly', points: [-hw, -hh, hw, -hh, hw, hh, -hw, hh] };\n}\n", "// Narrowphase collision for rigid bodies: circle\u2013circle, circle\u2013poly, and\n// poly\u2013poly (SAT + reference-face clipping, Box2D-lite style). Produces\n// contact manifolds with STABLE feature ids so the solver can warm-start.\n// Pure functions; deterministic tie-breaks everywhere.\n\nimport { dhypot } from '../core/dmath';\nimport type { RigidBody } from './rigidBody';\nimport { worldPoints } from './rigidBody';\n\nexport interface ContactPoint {\n px: number; py: number; // world contact point\n pen: number; // penetration depth (>0 means overlapping)\n feature: number; // stable id for warm starting\n // solver scratch (accumulated impulses live in the warm cache, not here)\n}\n\nexport interface Manifold {\n a: RigidBody;\n b: RigidBody;\n nx: number; ny: number; // contact normal, from A toward B\n points: ContactPoint[]; // 1..2\n}\n\nfunction collideCircles(a: RigidBody, b: RigidBody): Manifold | null {\n if (a.shape.kind !== 'circle' || b.shape.kind !== 'circle') return null;\n const dx = b.x - a.x, dy = b.y - a.y;\n const rsum = a.shape.r + b.shape.r;\n const d2 = dx * dx + dy * dy;\n if (d2 >= rsum * rsum) return null;\n const d = Math.sqrt(d2);\n // Coincident centers: deterministic fallback normal.\n const nx = d > 1e-9 ? dx / d : 1, ny = d > 1e-9 ? dy / d : 0;\n return {\n a, b, nx, ny,\n points: [{ px: a.x + nx * a.shape.r, py: a.y + ny * a.shape.r, pen: rsum - d, feature: 0 }],\n };\n}\n\n/** Circle B against polygon A. Returns manifold with normal A\u2192B. */\nfunction collidePolyCircle(a: RigidBody, b: RigidBody): Manifold | null {\n if (a.shape.kind !== 'poly' || b.shape.kind !== 'circle') return null;\n const wp = worldPoints(a);\n const n = wp.length / 2;\n const r = b.shape.r;\n // Find the face with max separation of the circle center.\n let bestSep = -Infinity, bestI = 0;\n for (let k = 0; k < n; k++) {\n const j = (k + 1) % n;\n const ex = wp[j * 2] - wp[k * 2], ey = wp[j * 2 + 1] - wp[k * 2 + 1];\n const len = dhypot(ex, ey) || 1;\n const nx = ey / len, ny = -ex / len; // outward for CCW in y-down coords\n const sep = (b.x - wp[k * 2]) * nx + (b.y - wp[k * 2 + 1]) * ny;\n if (sep > bestSep) { bestSep = sep; bestI = k; }\n }\n if (bestSep > r) return null;\n const k = bestI, j = (bestI + 1) % n;\n const ax = wp[k * 2], ay = wp[k * 2 + 1], bx2 = wp[j * 2], by2 = wp[j * 2 + 1];\n if (bestSep < 1e-9) {\n // Center inside the poly: push out along the deepest face normal.\n const ex = bx2 - ax, ey = by2 - ay;\n const len = dhypot(ex, ey) || 1;\n const nx = ey / len, ny = -ex / len;\n return { a, b, nx, ny, points: [{ px: b.x - nx * r, py: b.y - ny * r, pen: r - bestSep, feature: bestI }] };\n }\n // Closest point on the face segment (vertex regions included).\n const ex = bx2 - ax, ey = by2 - ay;\n const e2 = ex * ex + ey * ey || 1;\n let t = ((b.x - ax) * ex + (b.y - ay) * ey) / e2;\n t = t < 0 ? 0 : t > 1 ? 1 : t;\n const cx = ax + ex * t, cy = ay + ey * t;\n const dx = b.x - cx, dy = b.y - cy;\n const d2 = dx * dx + dy * dy;\n if (d2 >= r * r) return null;\n const d = Math.sqrt(d2) || 1e-9;\n const nx = dx / d, ny = dy / d;\n return { a, b, nx, ny, points: [{ px: cx, py: cy, pen: r - d, feature: bestI }] };\n}\n\n/** Max separation of B's hull from A's faces; returns [separation, faceIndex]. */\nfunction maxSeparation(wpA: number[], wpB: number[]): [number, number] {\n const nA = wpA.length / 2, nB = wpB.length / 2;\n let best = -Infinity, bestI = 0;\n for (let k = 0; k < nA; k++) {\n const j = (k + 1) % nA;\n const ex = wpA[j * 2] - wpA[k * 2], ey = wpA[j * 2 + 1] - wpA[k * 2 + 1];\n const len = dhypot(ex, ey) || 1;\n const nx = ey / len, ny = -ex / len;\n // Deepest point of B along this face normal.\n let minDot = Infinity;\n for (let v = 0; v < nB; v++) {\n const d = (wpB[v * 2] - wpA[k * 2]) * nx + (wpB[v * 2 + 1] - wpA[k * 2 + 1]) * ny;\n if (d < minDot) minDot = d;\n }\n if (minDot > best) { best = minDot; bestI = k; }\n }\n return [best, bestI];\n}\n\nfunction collidePolys(a: RigidBody, b: RigidBody): Manifold | null {\n const wpA = worldPoints(a), wpB = worldPoints(b);\n const [sepA, faceA] = maxSeparation(wpA, wpB);\n if (sepA > 0) return null;\n const [sepB, faceB] = maxSeparation(wpB, wpA);\n if (sepB > 0) return null;\n\n // Reference poly: the one with the larger (less negative) separation.\n // Deterministic bias toward A on near-ties.\n let ref: number[], inc: number[], refFace: number, flip: boolean;\n if (sepB > sepA + 1e-4) { ref = wpB; inc = wpA; refFace = faceB; flip = true; }\n else { ref = wpA; inc = wpB; refFace = faceA; flip = false; }\n\n const nRef = ref.length / 2, nInc = inc.length / 2;\n const rj = (refFace + 1) % nRef;\n const rex = ref[rj * 2] - ref[refFace * 2], rey = ref[rj * 2 + 1] - ref[refFace * 2 + 1];\n const rlen = dhypot(rex, rey) || 1;\n const rnx = rey / rlen, rny = -rex / rlen; // reference face normal (outward)\n const rtx = rex / rlen, rty = rey / rlen; // reference face tangent\n\n // Incident face: most anti-parallel to the reference normal.\n let incFace = 0, minDot = Infinity;\n for (let k = 0; k < nInc; k++) {\n const j = (k + 1) % nInc;\n const ex = inc[j * 2] - inc[k * 2], ey = inc[j * 2 + 1] - inc[k * 2 + 1];\n const len = dhypot(ex, ey) || 1;\n const d = (ey / len) * rnx + (-ex / len) * rny;\n if (d < minDot) { minDot = d; incFace = k; }\n }\n const ij = (incFace + 1) % nInc;\n // Two incident vertices; the feature id is (flip, refFace, slot) \u2014 NOT the\n // clip state. Clip-state ids churn every frame while a stack micro-rocks,\n // which mis-applies warm-start impulses and pumps energy into the pile.\n let v1x = inc[incFace * 2], v1y = inc[incFace * 2 + 1];\n let v2x = inc[ij * 2], v2y = inc[ij * 2 + 1];\n\n // Clip against the two side planes of the reference face.\n const refX = ref[refFace * 2], refY = ref[refFace * 2 + 1];\n const refX2 = ref[rj * 2], refY2 = ref[rj * 2 + 1];\n // Side 1: keep t >= 0 along tangent from refV1; Side 2: keep t <= faceLen.\n for (let side = 0; side < 2; side++) {\n const ox = side === 0 ? refX : refX2, oy = side === 0 ? refY : refY2;\n const sx = side === 0 ? rtx : -rtx, sy = side === 0 ? rty : -rty;\n const d1 = (v1x - ox) * sx + (v1y - oy) * sy;\n const d2 = (v2x - ox) * sx + (v2y - oy) * sy;\n if (d1 < 0 && d2 < 0) return null; // fully clipped (shouldn't happen on overlap)\n if (d1 < 0) {\n const t = d1 / (d1 - d2);\n v1x = v1x + (v2x - v1x) * t; v1y = v1y + (v2y - v1y) * t;\n } else if (d2 < 0) {\n const t = d2 / (d2 - d1);\n v2x = v2x + (v1x - v2x) * t; v2y = v2y + (v1y - v2y) * t;\n }\n }\n\n // Keep points behind the reference face; normal must point A\u2192B.\n const nx = flip ? -rnx : rnx, ny = flip ? -rny : rny;\n const points: ContactPoint[] = [];\n const pen1 = -((v1x - refX) * rnx + (v1y - refY) * rny);\n const pen2 = -((v2x - refX) * rnx + (v2y - refY) * rny);\n // Feature id = (flip, refFace, incFace, slot). Stable while the same two\n // faces stay in contact (micro-rocking stacks reuse warm impulses), but\n // fresh whenever a tumbling box rolls onto its next corner (stale impulses\n // at new lever arms would pump energy).\n const fid = ((flip ? 1 : 0) * 64 + refFace) * 64 + incFace;\n if (pen1 > 0) points.push({ px: v1x, py: v1y, pen: pen1, feature: fid * 2 });\n if (pen2 > 0) points.push({ px: v2x, py: v2y, pen: pen2, feature: fid * 2 + 1 });\n if (points.length === 0) return null;\n return { a, b, nx, ny, points };\n}\n\n/** Dispatch on shape kinds. Normal always points from A toward B. */\nexport function collide(a: RigidBody, b: RigidBody): Manifold | null {\n const ka = a.shape.kind, kb = b.shape.kind;\n if (ka === 'circle' && kb === 'circle') return collideCircles(a, b);\n if (ka === 'poly' && kb === 'poly') return collidePolys(a, b);\n if (ka === 'poly' && kb === 'circle') return collidePolyCircle(a, b);\n // circle vs poly: flip so poly is A, then invert the normal back.\n const m = collidePolyCircle(b, a);\n if (!m) return null;\n return { a, b, nx: -m.nx, ny: -m.ny, points: m.points };\n}\n", "// Joints for the rigid-body engine: distance (rod / rope) and revolute\n// (pin, with optional motor and angle limits). Velocity-level constraints\n// with Baumgarte stabilization, solved inside the same iteration loop as\n// contacts. Plain data + pure solve functions.\n\nimport { dcos, dhypot, dsin } from '../core/dmath';\nimport type { RigidBody, RigidWorld } from './rigidBody';\nimport { getBody, wakeBody } from './rigidBody';\n\nexport interface DistanceJoint {\n kind: 'distance';\n id: number;\n a: number; b: number; // body ids\n ax: number; ay: number; // local anchor on A\n bx: number; by: number; // local anchor on B\n length: number;\n /** Rope mode: only constrain when stretched past `length`. */\n rope: boolean;\n}\n\nexport interface RevoluteJoint {\n kind: 'revolute';\n id: number;\n a: number; b: number;\n ax: number; ay: number;\n bx: number; by: number;\n /** Motor: drive relative angular velocity toward `motorSpeed`. */\n motorSpeed: number;\n maxMotorTorque: number; // 0 = motor off\n /** Angle limits on (b.a - a.a - refAngle); NaN-free: enabled flag. */\n limitLower: number;\n limitUpper: number;\n limitEnabled: boolean;\n refAngle: number;\n}\n\nexport type Joint = DistanceJoint | RevoluteJoint;\n\nexport interface DistanceJointDef {\n a: number; b: number;\n ax?: number; ay?: number; bx?: number; by?: number;\n /** Defaults to the current anchor distance. */\n length?: number;\n rope?: boolean;\n}\n\nexport interface RevoluteJointDef {\n a: number; b: number;\n /** World-space pivot; local anchors are derived from current poses. */\n px: number; py: number;\n motorSpeed?: number;\n maxMotorTorque?: number;\n limitLower?: number;\n limitUpper?: number;\n}\n\nfunction toLocal(b: RigidBody, wx: number, wy: number): [number, number] {\n const c = dcos(b.a), s = dsin(b.a);\n const dx = wx - b.x, dy = wy - b.y;\n return [dx * c + dy * s, -dx * s + dy * c];\n}\n\nfunction anchorWorld(b: RigidBody, lx: number, ly: number): [number, number] {\n const c = dcos(b.a), s = dsin(b.a);\n return [b.x + lx * c - ly * s, b.y + lx * s + ly * c];\n}\n\nexport function addDistanceJoint(rw: RigidWorld, def: DistanceJointDef): number {\n const A = getBody(rw, def.a), B = getBody(rw, def.b);\n if (!A || !B) throw new Error(`distance joint: missing body ${def.a}/${def.b}`);\n const ax = def.ax ?? 0, ay = def.ay ?? 0, bx = def.bx ?? 0, by = def.by ?? 0;\n const [wax, way] = anchorWorld(A, ax, ay);\n const [wbx, wby] = anchorWorld(B, bx, by);\n const j: DistanceJoint = {\n kind: 'distance', id: rw.nextId++,\n a: def.a, b: def.b, ax, ay, bx, by,\n length: def.length ?? dhypot(wbx - wax, wby - way),\n rope: def.rope ?? false,\n };\n rw.joints.push(j);\n wakeBody(A); wakeBody(B);\n return j.id;\n}\n\nexport function addRevoluteJoint(rw: RigidWorld, def: RevoluteJointDef): number {\n const A = getBody(rw, def.a), B = getBody(rw, def.b);\n if (!A || !B) throw new Error(`revolute joint: missing body ${def.a}/${def.b}`);\n const [ax, ay] = toLocal(A, def.px, def.py);\n const [bx, by] = toLocal(B, def.px, def.py);\n const j: RevoluteJoint = {\n kind: 'revolute', id: rw.nextId++,\n a: def.a, b: def.b, ax, ay, bx, by,\n motorSpeed: def.motorSpeed ?? 0,\n maxMotorTorque: def.maxMotorTorque ?? 0,\n limitLower: def.limitLower ?? 0,\n limitUpper: def.limitUpper ?? 0,\n limitEnabled: def.limitLower !== undefined || def.limitUpper !== undefined,\n refAngle: B.a - A.a,\n };\n rw.joints.push(j);\n wakeBody(A); wakeBody(B);\n return j.id;\n}\n\nexport function getJoint(rw: RigidWorld, id: number): Joint | undefined {\n for (const j of rw.joints) if (j.id === id) return j;\n return undefined;\n}\n\nexport function removeJoint(rw: RigidWorld, id: number): void {\n rw.joints = rw.joints.filter((j) => j.id !== id);\n}\n\n/** Per-step scratch for accumulated-impulse clamping (one per joint). */\nexport interface JointScratch {\n motorImpulse: number;\n}\n\n/** One velocity iteration for a single joint. `bias` uses dt for Baumgarte. */\nexport function solveJoint(j: Joint, A: RigidBody, B: RigidBody, dt: number, scratch: JointScratch): void {\n const [wax, way] = anchorWorld(A, j.ax, j.ay);\n const [wbx, wby] = anchorWorld(B, j.bx, j.by);\n const rax = wax - A.x, ray = way - A.y;\n const rbx = wbx - B.x, rby = wby - B.y;\n\n if (j.kind === 'distance') {\n let dx = wbx - wax, dy = wby - way;\n const dist = dhypot(dx, dy);\n if (dist < 1e-9) return;\n dx /= dist; dy /= dist;\n const stretch = dist - j.length;\n if (j.rope && stretch <= 0) return; // slack rope\n // Relative velocity along the axis.\n const vax = A.vx - A.w * ray, vay = A.vy + A.w * rax;\n const vbx = B.vx - B.w * rby, vby = B.vy + B.w * rbx;\n const vrel = (vbx - vax) * dx + (vby - vay) * dy;\n const crossA = rax * dy - ray * dx;\n const crossB = rbx * dy - rby * dx;\n const k = A.invM + B.invM + A.invI * crossA * crossA + B.invI * crossB * crossB;\n if (k < 1e-12) return;\n const bias = (0.2 / dt) * stretch;\n let lambda = -(vrel + bias) / k;\n if (j.rope && lambda > 0) lambda = 0; // rope can only pull inward\n const ix = dx * lambda, iy = dy * lambda;\n A.vx -= ix * A.invM; A.vy -= iy * A.invM;\n A.w -= (rax * iy - ray * ix) * A.invI;\n B.vx += ix * B.invM; B.vy += iy * B.invM;\n B.w += (rbx * iy - rby * ix) * B.invI;\n return;\n }\n\n // Revolute: motor + limits first (1D angular), then point-to-point (2D).\n if (j.maxMotorTorque > 0) {\n const kw = A.invI + B.invI;\n if (kw > 1e-12) {\n const cdot = B.w - A.w - j.motorSpeed;\n const imp = -cdot / kw;\n // Accumulated clamp: total motor impulse this STEP \u2264 maxMotorTorque\u00B7dt,\n // regardless of iteration count (Box2D semantics).\n const maxImp = j.maxMotorTorque * dt;\n const acc0 = scratch.motorImpulse;\n scratch.motorImpulse = Math.min(Math.max(acc0 + imp, -maxImp), maxImp);\n const applied = scratch.motorImpulse - acc0;\n A.w -= applied * A.invI;\n B.w += applied * B.invI;\n }\n }\n if (j.limitEnabled) {\n const kw = A.invI + B.invI;\n if (kw > 1e-12) {\n const angle = B.a - A.a - j.refAngle;\n let c = 0;\n if (angle < j.limitLower) c = angle - j.limitLower;\n else if (angle > j.limitUpper) c = angle - j.limitUpper;\n if (c !== 0) {\n const cdot = B.w - A.w;\n const imp = -(cdot + (0.2 / dt) * c) / kw;\n // Only push back toward the range.\n if ((c < 0 && imp > 0) || (c > 0 && imp < 0)) {\n A.w -= imp * A.invI;\n B.w += imp * B.invI;\n }\n }\n }\n }\n // Point-to-point: solve the 2x2 system K * lambda = -(vrel + bias).\n const vax = A.vx - A.w * ray, vay = A.vy + A.w * rax;\n const vbx = B.vx - B.w * rby, vby = B.vy + B.w * rbx;\n const cx = wbx - wax, cy = wby - way;\n const vrx = vbx - vax + (0.2 / dt) * cx;\n const vry = vby - vay + (0.2 / dt) * cy;\n const k11 = A.invM + B.invM + A.invI * ray * ray + B.invI * rby * rby;\n const k12 = -A.invI * rax * ray - B.invI * rbx * rby;\n const k22 = A.invM + B.invM + A.invI * rax * rax + B.invI * rbx * rbx;\n const det = k11 * k22 - k12 * k12;\n if (Math.abs(det) < 1e-12) return;\n const ix = -(k22 * vrx - k12 * vry) / det;\n const iy = -(k11 * vry - k12 * vrx) / det;\n A.vx -= ix * A.invM; A.vy -= iy * A.invM;\n A.w -= (rax * iy - ray * ix) * A.invI;\n B.vx += ix * B.invM; B.vy += iy * B.invM;\n B.w += (rbx * iy - rby * ix) * B.invI;\n}\n", "// The rigid-body step pipeline: integrate forces \u2192 broadphase (spatial hash,\n// ordered pairs) \u2192 narrowphase \u2192 warm-started sequential-impulse solve\n// (joints + contacts) \u2192 integrate positions \u2192 bullet CCD \u2192 sleeping.\n//\n// Penetration recovery uses SPLIT IMPULSE (Chipmunk-style bias velocities): a\n// separate pseudo-velocity field feels the Baumgarte push, integrates into\n// POSITION only, and is discarded \u2014 so stacks recover overlap without gaining\n// kinetic energy, settle truly calm, and can sleep.\n//\n// Deterministic: bodies iterate in array order, pairs in (idA, idB) order,\n// and the warm-start cache is rebuilt every step from plain data.\n\nimport { dhypot } from '../core/dmath';\nimport { SpatialHash } from './spatialHash';\nimport type { RigidBody, RigidWorld } from './rigidBody';\nimport { bodyAABB, getBody, wakeBody, worldPoints } from './rigidBody';\nimport { collide, type Manifold } from './rigidCollide';\nimport { solveJoint } from './rigidJoints';\n\nexport interface ContactEvent {\n a: number; b: number; // body ids (a < b)\n px: number; py: number; // representative contact point\n nx: number; ny: number; // normal a\u2192b\n /** Total normal impulse this step \u2014 scales with hit violence. */\n impulse: number;\n /** Sensor overlap (no collision response was applied). */\n sensor: boolean;\n}\n\nconst SLOP = 0.5; // allowed overlap, px\nconst BIAS = 0.2; // Baumgarte factor (position recovery rate)\nconst REST_THRESHOLD = 40; // px/s \u2014 below this, no bounce\nconst SLEEP_LIN2 = 64; // (8 px/s)\u00B2 \u2014 resting piles hum at 5\u201320 px/s\nconst SLEEP_RIM = 8; // px/s of rim speed (|w|\u00B7sleepR)\nconst TIME_TO_SLEEP = 0.5; // s\nconst WAKE_LIN2 = 100; // partner speed\u00B2 that wakes a sleeper\n\ninterface SolvePoint {\n rax: number; ray: number; rbx: number; rby: number;\n pen: number;\n massN: number; massT: number;\n restBias: number; // restitution target velocity (real)\n posBias: number; // penetration target velocity (pseudo)\n pn: number; pt: number; // accumulated impulses (real)\n pb: number; // accumulated impulse (pseudo)\n key: string;\n}\n\ninterface SolveManifold {\n m: Manifold;\n ia: number; ib: number; // body array indices (for the bias fields)\n points: SolvePoint[];\n friction: number;\n}\n\nfunction canCollide(a: RigidBody, b: RigidBody): boolean {\n if (a.invM === 0 && b.invM === 0 && a.kind !== 'kinematic' && b.kind !== 'kinematic' && !a.sensor && !b.sensor) return false;\n return (a.mask & b.layer) !== 0 && (b.mask & a.layer) !== 0;\n}\n\nexport function rigidStep(rw: RigidWorld, dt: number): ContactEvent[] {\n const bodies = rw.bodies;\n const events: ContactEvent[] = [];\n if (dt <= 0) return events;\n\n // \u2500\u2500 1 \u00B7 integrate forces \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n for (let k = 0; k < bodies.length; k++) {\n const b = bodies[k];\n if (b.kind !== 'dynamic' || b.sleeping) { b.fx = 0; b.fy = 0; b.torque = 0; continue; }\n b.vx += (rw.gravityX * b.gravityScale + b.fx * b.invM) * dt;\n b.vy += (rw.gravityY * b.gravityScale + b.fy * b.invM) * dt;\n b.w += b.torque * b.invI * dt;\n const ld = 1 / (1 + b.linDamp * dt);\n b.vx *= ld; b.vy *= ld;\n b.w *= 1 / (1 + b.angDamp * dt);\n b.fx = 0; b.fy = 0; b.torque = 0;\n }\n\n // \u2500\u2500 2 \u00B7 broadphase: spatial hash, pairs in deterministic order \u2500\u2500\u2500\n const hash = new SpatialHash<RigidBody>(rw.cellSize);\n const indexOf = new Map<RigidBody, number>();\n for (let k = 0; k < bodies.length; k++) {\n hash.insert(bodies[k], bodyAABB(bodies[k]));\n indexOf.set(bodies[k], k);\n }\n const manifolds: SolveManifold[] = [];\n const seen = new Set<number>();\n // Joint-connected bodies never collide with each other (Box2D convention \u2014\n // a pinned wheel must not grind against its own anchor).\n const jointed = new Set<number>();\n for (const j of rw.joints) {\n const lo = Math.min(j.a, j.b), hi = Math.max(j.a, j.b);\n jointed.add(lo * 1048576 + hi);\n }\n for (let k = 0; k < bodies.length; k++) {\n const a = bodies[k];\n const near = hash.query(bodyAABB(a));\n for (const b of near) {\n if (b.id <= a.id) continue;\n const packed = a.id * 1048576 + b.id;\n if (seen.has(packed)) continue;\n seen.add(packed);\n if (jointed.has(packed)) continue;\n if (!canCollide(a, b)) continue;\n // Skip unless at least one side is an AWAKE mover \u2014 this is what lets a\n // settled stack truly freeze (a sleeping box on a static floor gets no\n // solver impulses at all).\n const activeA = !a.sleeping && a.kind !== 'static';\n const activeB = !b.sleeping && b.kind !== 'static';\n if (!activeA && !activeB) continue;\n const m = collide(a, b);\n if (!m) continue;\n // Wake a sleeper hit by something moving.\n const wakeIf = (s: RigidBody, o: RigidBody) => {\n if (s.sleeping && (o.vx * o.vx + o.vy * o.vy > WAKE_LIN2 || o.kind === 'kinematic')) wakeBody(s);\n };\n wakeIf(a, b); wakeIf(b, a);\n if (a.sensor || b.sensor) {\n events.push({ a: a.id, b: b.id, px: m.points[0].px, py: m.points[0].py, nx: m.nx, ny: m.ny, impulse: 0, sensor: true });\n continue;\n }\n // Pre-step: effective masses, restitution capture, warm start.\n const sp: SolvePoint[] = [];\n const tx = -m.ny, ty = m.nx;\n for (const p of m.points) {\n const rax = p.px - a.x, ray = p.py - a.y;\n const rbx = p.px - b.x, rby = p.py - b.y;\n const crossAN = rax * m.ny - ray * m.nx;\n const crossBN = rbx * m.ny - rby * m.nx;\n const kn = a.invM + b.invM + a.invI * crossAN * crossAN + b.invI * crossBN * crossBN;\n const crossAT = rax * ty - ray * tx;\n const crossBT = rbx * ty - rby * tx;\n const kt = a.invM + b.invM + a.invI * crossAT * crossAT + b.invI * crossBT * crossBT;\n // Approach speed for restitution (captured before solving).\n const vrx = b.vx - b.w * rby - a.vx + a.w * ray;\n const vry = b.vy + b.w * rbx - a.vy - a.w * rax;\n const vn = vrx * m.nx + vry * m.ny;\n const e = Math.max(a.restitution, b.restitution);\n const key = `${a.id}:${b.id}:${p.feature}`;\n const warm = rw.warm[key];\n const sp1: SolvePoint = {\n rax, ray, rbx, rby, pen: p.pen,\n massN: kn > 1e-12 ? 1 / kn : 0,\n massT: kt > 1e-12 ? 1 / kt : 0,\n restBias: vn < -REST_THRESHOLD ? -e * vn : 0,\n posBias: (BIAS / dt) * Math.max(0, p.pen - SLOP),\n pn: warm ? warm[0] : 0,\n pt: warm ? warm[1] : 0,\n pb: 0,\n key,\n };\n sp.push(sp1);\n }\n manifolds.push({ m, ia: k, ib: indexOf.get(b)!, points: sp, friction: Math.sqrt(a.friction * b.friction) });\n }\n }\n\n // Warm-start pass \u2014 applied only AFTER every point captured its clean\n // approach velocity. Interleaving capture with application double-counts\n // restitution (the bounce target re-adds speed warm-starting already\n // reversed) and pumps energy into resting piles.\n for (const sm of manifolds) {\n const { a, b, nx, ny } = sm.m;\n const tx = -ny, ty = nx;\n for (const p of sm.points) {\n if (p.pn === 0 && p.pt === 0) continue;\n const ix = nx * p.pn + tx * p.pt;\n const iy = ny * p.pn + ty * p.pt;\n a.vx -= ix * a.invM; a.vy -= iy * a.invM;\n a.w -= (p.rax * iy - p.ray * ix) * a.invI;\n b.vx += ix * b.invM; b.vy += iy * b.invM;\n b.w += (p.rbx * iy - p.rby * ix) * b.invI;\n }\n }\n\n // Solve in SUPPORT ORDER \u2014 static pairs first, then bottom-up (larger y\n // first in y-down coords). Sequential impulse converges a resting pile in\n // far fewer iterations when impulses propagate up the support chain.\n // Deterministic: ties break on (a.id, b.id).\n manifolds.sort((p, q) => {\n const ps = p.m.a.invM === 0 || p.m.b.invM === 0 ? 0 : 1;\n const qs = q.m.a.invM === 0 || q.m.b.invM === 0 ? 0 : 1;\n if (ps !== qs) return ps - qs;\n const py = Math.max(p.m.a.y, p.m.b.y), qy = Math.max(q.m.a.y, q.m.b.y);\n if (py !== qy) return qy - py;\n if (p.m.a.id !== q.m.a.id) return p.m.a.id - q.m.a.id;\n return p.m.b.id - q.m.b.id;\n });\n\n // Pseudo-velocity fields for split-impulse position recovery (scratch \u2014\n // never serialized, discarded at the end of the step).\n const bvx = new Float64Array(bodies.length);\n const bvy = new Float64Array(bodies.length);\n const bw = new Float64Array(bodies.length);\n\n // \u2500\u2500 3 \u00B7 velocity iterations: joints then contacts \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n const jointScratch = rw.joints.map(() => ({ motorImpulse: 0 }));\n for (let iter = 0; iter < rw.iterations; iter++) {\n for (let jk = 0; jk < rw.joints.length; jk++) {\n const j = rw.joints[jk];\n const A = getBody(rw, j.a), B = getBody(rw, j.b);\n if (!A || !B) continue;\n if (A.sleeping && B.sleeping) continue;\n if (A.sleeping) wakeBody(A);\n if (B.sleeping) wakeBody(B);\n solveJoint(j, A, B, dt, jointScratch[jk]);\n }\n for (const sm of manifolds) {\n const { a, b, nx, ny } = sm.m;\n const { ia, ib } = sm;\n const tx = -ny, ty = nx;\n for (const p of sm.points) {\n // Normal impulse (real velocities; restitution target only).\n let vrx = b.vx - b.w * p.rby - a.vx + a.w * p.ray;\n let vry = b.vy + b.w * p.rbx - a.vy - a.w * p.rax;\n const vn = vrx * nx + vry * ny;\n let dPn = p.massN * (p.restBias - vn);\n const pn0 = p.pn;\n p.pn = Math.max(pn0 + dPn, 0);\n dPn = p.pn - pn0;\n let ix = nx * dPn, iy = ny * dPn;\n a.vx -= ix * a.invM; a.vy -= iy * a.invM;\n a.w -= (p.rax * iy - p.ray * ix) * a.invI;\n b.vx += ix * b.invM; b.vy += iy * b.invM;\n b.w += (p.rbx * iy - p.rby * ix) * b.invI;\n // Friction impulse (clamped by the friction cone).\n vrx = b.vx - b.w * p.rby - a.vx + a.w * p.ray;\n vry = b.vy + b.w * p.rbx - a.vy - a.w * p.rax;\n const vt = vrx * tx + vry * ty;\n let dPt = p.massT * -vt;\n const maxPt = sm.friction * p.pn;\n const pt0 = p.pt;\n p.pt = Math.min(Math.max(pt0 + dPt, -maxPt), maxPt);\n dPt = p.pt - pt0;\n ix = tx * dPt; iy = ty * dPt;\n a.vx -= ix * a.invM; a.vy -= iy * a.invM;\n a.w -= (p.rax * iy - p.ray * ix) * a.invI;\n b.vx += ix * b.invM; b.vy += iy * b.invM;\n b.w += (p.rbx * iy - p.rby * ix) * b.invI;\n // Split-impulse penetration recovery (pseudo velocities \u2192 position\n // only; no kinetic energy enters the sim).\n if (p.posBias > 0) {\n const vbn = (bvx[ib] - bw[ib] * p.rby - bvx[ia] + bw[ia] * p.ray) * nx\n + (bvy[ib] + bw[ib] * p.rbx - bvy[ia] - bw[ia] * p.rax) * ny;\n let dPb = p.massN * (p.posBias - vbn);\n const pb0 = p.pb;\n p.pb = Math.max(pb0 + dPb, 0);\n dPb = p.pb - pb0;\n const bix = nx * dPb, biy = ny * dPb;\n // Linear-only pseudo push: rotating positions without refreshing\n // manifolds amplifies stack rocking, so pseudo torque stays off.\n bvx[ia] -= bix * a.invM; bvy[ia] -= biy * a.invM;\n bvx[ib] += bix * b.invM; bvy[ib] += biy * b.invM;\n }\n }\n }\n }\n\n // \u2500\u2500 4 \u00B7 integrate positions (real + pseudo velocity; pseudo dies) \u2500\n const preX: number[] = [], preY: number[] = [];\n for (let k = 0; k < bodies.length; k++) {\n const b = bodies[k];\n preX.push(b.x); preY.push(b.y);\n if (b.invM === 0 && b.kind !== 'kinematic') continue;\n if (b.sleeping) continue;\n b.x += (b.vx + bvx[k]) * dt;\n b.y += (b.vy + bvy[k]) * dt;\n b.a += (b.w + bw[k]) * dt;\n }\n\n // \u2500\u2500 5 \u00B7 bullet CCD (swept circle vs everything it can hit) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\n for (let k = 0; k < bodies.length; k++) {\n const b = bodies[k];\n if (!b.bullet || b.shape.kind !== 'circle' || b.sleeping) continue;\n const dx = b.x - preX[k], dy = b.y - preY[k];\n if (dx * dx + dy * dy < 1) continue;\n let bestT = 1;\n for (let q = 0; q < bodies.length; q++) {\n const o = bodies[q];\n if (o === b || o.bullet || o.sensor || !canCollide(b, o)) continue;\n const t = sweepCircle(preX[k], preY[k], dx, dy, b.shape.r, o);\n if (t >= 0 && t < bestT) bestT = t;\n }\n if (bestT < 1) {\n // Stop just PAST the impact time: a sub-slop penetration must exist or\n // the discrete narrowphase (pen > 0) never sees a contact, and the body\n // hangs on the surface accumulating gravity velocity forever.\n const len = dhypot(dx, dy) || 1;\n b.x = preX[k] + dx * bestT + (dx / len) * 0.4;\n b.y = preY[k] + dy * bestT + (dy / len) * 0.4;\n // leave velocity intact \u2014 next step's contact solve applies restitution.\n }\n }\n\n // \u2500\u2500 6 \u00B7 sleeping \u2014 ISLAND-atomic (a pile sleeps as one, or not at all) \u2500\n // Union-find over dynamic\u2013dynamic contacts and joints; static bodies do\n // not conduct (two piles on one floor are separate islands).\n const touching = new Set<number>();\n const parent: number[] = [];\n for (let k = 0; k < bodies.length; k++) parent.push(k);\n const find = (x: number): number => {\n while (parent[x] !== x) { parent[x] = parent[parent[x]]; x = parent[x]; }\n return x;\n };\n const union = (x: number, y: number) => { parent[find(x)] = find(y); };\n for (const sm of manifolds) {\n touching.add(sm.m.a.id); touching.add(sm.m.b.id);\n if (sm.m.a.kind === 'dynamic' && sm.m.b.kind === 'dynamic') union(sm.ia, sm.ib);\n }\n for (const j of rw.joints) {\n touching.add(j.a); touching.add(j.b);\n const A = getBody(rw, j.a), B = getBody(rw, j.b);\n if (A?.kind === 'dynamic' && B?.kind === 'dynamic') union(indexOf.get(A)!, indexOf.get(B)!);\n }\n // Per-body calm clocks (a solver-injected velocity also re-wakes a sleeper).\n for (let k = 0; k < bodies.length; k++) {\n const b = bodies[k];\n if (b.kind !== 'dynamic') continue;\n const lin2 = b.vx * b.vx + b.vy * b.vy;\n if (b.sleeping) {\n if (lin2 > WAKE_LIN2) wakeBody(b);\n continue;\n }\n if (!b.canSleep || !touching.has(b.id)) { b.sleepTime = 0; continue; }\n b.sleepTime = lin2 < SLEEP_LIN2 && Math.abs(b.w) * b.sleepR < SLEEP_RIM ? b.sleepTime + dt : 0;\n }\n // An island sleeps when EVERY member has been calm long enough.\n const islandMin = new Map<number, number>();\n for (let k = 0; k < bodies.length; k++) {\n const b = bodies[k];\n if (b.kind !== 'dynamic' || b.sleeping) continue;\n const root = find(k);\n const t = !b.canSleep || !touching.has(b.id) ? -1 : b.sleepTime;\n const cur = islandMin.get(root);\n islandMin.set(root, cur === undefined ? t : Math.min(cur, t));\n }\n for (let k = 0; k < bodies.length; k++) {\n const b = bodies[k];\n if (b.kind !== 'dynamic' || b.sleeping) continue;\n if ((islandMin.get(find(k)) ?? -1) >= TIME_TO_SLEEP) {\n b.sleeping = true;\n b.vx = 0; b.vy = 0; b.w = 0;\n }\n }\n\n // \u2500\u2500 7 \u00B7 contact events + rebuild the warm cache \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n const warm: Record<string, [number, number]> = {};\n for (const sm of manifolds) {\n let total = 0;\n for (const p of sm.points) {\n total += p.pn;\n if (p.pn !== 0 || p.pt !== 0) warm[p.key] = [p.pn, p.pt];\n }\n const p0 = sm.m.points[0];\n events.push({\n a: sm.m.a.id, b: sm.m.b.id, px: p0.px, py: p0.py,\n nx: sm.m.nx, ny: sm.m.ny, impulse: total, sensor: false,\n });\n }\n rw.warm = warm;\n return events;\n}\n\n/** Earliest t\u2208[0,1] where a circle swept along (dx,dy) first touches body o, or -1. */\nfunction sweepCircle(x0: number, y0: number, dx: number, dy: number, r: number, o: RigidBody): number {\n if (o.shape.kind === 'circle') {\n return sweepVsCircle(x0, y0, dx, dy, o.x, o.y, r + o.shape.r);\n }\n // Poly: Minkowski sum = edges offset outward by r + vertex circles of radius r.\n const wp = worldPoints(o);\n const n = wp.length / 2;\n let best = -1;\n for (let k = 0; k < n; k++) {\n const j = (k + 1) % n;\n const ax = wp[k * 2], ay = wp[k * 2 + 1];\n const bx = wp[j * 2], by = wp[j * 2 + 1];\n const ex = bx - ax, ey = by - ay;\n const len = dhypot(ex, ey) || 1;\n const nx = ey / len, ny = -ex / len;\n // Offset edge segment \u2014 only FRONT-side crossings count (motion into the\n // face), and only from a start point that is NOT already touching the\n // face. A touching/overlapping start is the contact solver's regime: TOI\n // would clamp t\u22480 every frame and pin a sliding ball in place.\n const startSep = (x0 - ax) * nx + (y0 - ay) * ny - r;\n if (dx * nx + dy * ny < 0 && startSep > 0.5) {\n const t = sweepVsSegment(x0, y0, dx, dy, ax + nx * r, ay + ny * r, bx + nx * r, by + ny * r);\n if (t >= 0 && (best < 0 || t < best)) best = t;\n }\n // Vertex circle.\n const tv = sweepVsCircle(x0, y0, dx, dy, ax, ay, r);\n if (tv >= 0 && (best < 0 || tv < best)) best = tv;\n }\n return best;\n}\n\nfunction sweepVsCircle(x0: number, y0: number, dx: number, dy: number, cx: number, cy: number, R: number): number {\n const fx = x0 - cx, fy = y0 - cy;\n const a = dx * dx + dy * dy;\n if (a < 1e-12) return -1;\n const b = 2 * (fx * dx + fy * dy);\n // Already touching or overlapping (within a slop ring): the contact solver\n // owns this \u2014 a TOI of ~0 would pin a rolling/sliding ball in place.\n if (fx * fx + fy * fy < (R + 0.5) * (R + 0.5)) return -1;\n const c = fx * fx + fy * fy - R * R;\n const disc = b * b - 4 * a * c;\n if (disc < 0) return -1;\n const t = (-b - Math.sqrt(disc)) / (2 * a);\n return t >= 0 && t <= 1 ? t : -1;\n}\n\nfunction sweepVsSegment(x0: number, y0: number, dx: number, dy: number, ax: number, ay: number, bx: number, by: number): number {\n const ex = bx - ax, ey = by - ay;\n const denom = dx * ey - dy * ex;\n if (Math.abs(denom) < 1e-12) return -1;\n const t = ((ax - x0) * ey - (ay - y0) * ex) / denom;\n const s = ((ax - x0) * dy - (ay - y0) * dx) / denom;\n return t >= 0 && t <= 1 && s >= 0 && s <= 1 ? t : -1;\n}\n", "// Spatial queries against rigid bodies: point tests and raycasts.\n// Pure functions; results are deterministic (bodies scanned in array order).\n\nimport { dhypot } from '../core/dmath';\nimport type { RigidBody, RigidWorld } from './rigidBody';\nimport { worldPoints } from './rigidBody';\n\nexport interface RigidRayHit {\n id: number;\n t: number; // fraction along the ray [0,1]\n x: number; y: number; // hit point\n nx: number; ny: number; // surface normal\n}\n\n/** Is a world point inside this body's shape? */\nexport function bodyContains(b: RigidBody, x: number, y: number): boolean {\n if (b.shape.kind === 'circle') {\n const dx = x - b.x, dy = y - b.y;\n return dx * dx + dy * dy <= b.shape.r * b.shape.r;\n }\n const wp = worldPoints(b);\n const n = wp.length / 2;\n for (let k = 0; k < n; k++) {\n const j = (k + 1) % n;\n const ex = wp[j * 2] - wp[k * 2], ey = wp[j * 2 + 1] - wp[k * 2 + 1];\n if ((x - wp[k * 2]) * ey - (y - wp[k * 2 + 1]) * ex > 0) return false;\n }\n return true;\n}\n\n/** First body containing the point (topmost = last added wins ties via scan order). */\nexport function pointQuery(rw: RigidWorld, x: number, y: number, mask = 0xffff): RigidBody | undefined {\n let hit: RigidBody | undefined;\n for (const b of rw.bodies) if ((b.layer & mask) !== 0 && bodyContains(b, x, y)) hit = b;\n return hit;\n}\n\nfunction rayCircle(x0: number, y0: number, dx: number, dy: number, cx: number, cy: number, r: number): number {\n const fx = x0 - cx, fy = y0 - cy;\n const a = dx * dx + dy * dy;\n if (a < 1e-12) return -1;\n const b = 2 * (fx * dx + fy * dy);\n const c = fx * fx + fy * fy - r * r;\n const disc = b * b - 4 * a * c;\n if (disc < 0) return -1;\n const t = (-b - Math.sqrt(disc)) / (2 * a);\n return t >= 0 && t <= 1 ? t : -1;\n}\n\n/** Closest hit along the segment (x0,y0)\u2192(x1,y1), or null. */\nexport function rayCastRigid(rw: RigidWorld, x0: number, y0: number, x1: number, y1: number, mask = 0xffff): RigidRayHit | null {\n const dx = x1 - x0, dy = y1 - y0;\n let best: RigidRayHit | null = null;\n for (const b of rw.bodies) {\n if ((b.layer & mask) === 0) continue;\n if (b.shape.kind === 'circle') {\n const t = rayCircle(x0, y0, dx, dy, b.x, b.y, b.shape.r);\n if (t >= 0 && (!best || t < best.t)) {\n const hx = x0 + dx * t, hy = y0 + dy * t;\n const len = dhypot(hx - b.x, hy - b.y) || 1;\n best = { id: b.id, t, x: hx, y: hy, nx: (hx - b.x) / len, ny: (hy - b.y) / len };\n }\n continue;\n }\n const wp = worldPoints(b);\n const n = wp.length / 2;\n for (let k = 0; k < n; k++) {\n const j = (k + 1) % n;\n const ax = wp[k * 2], ay = wp[k * 2 + 1];\n const ex = wp[j * 2] - ax, ey = wp[j * 2 + 1] - ay;\n const denom = dx * ey - dy * ex;\n if (Math.abs(denom) < 1e-12) continue;\n const t = ((ax - x0) * ey - (ay - y0) * ex) / denom;\n const s = ((ax - x0) * dy - (ay - y0) * dx) / denom;\n if (t < 0 || t > 1 || s < 0 || s > 1) continue;\n if (!best || t < best.t) {\n const len = dhypot(ex, ey) || 1;\n best = { id: b.id, t, x: x0 + dx * t, y: y0 + dy * t, nx: ey / len, ny: -ex / len };\n }\n }\n }\n return best;\n}\n", "// The display list: a flat, backend-agnostic vocabulary of draw commands.\n// The scene tree *projects* to DrawCommand[]; a backend (SVG/Canvas/Headless)\n// consumes them. Pure data \u2014 no browser types \u2014 so the projection is testable.\n\nimport type { Transform } from '../core/math';\n\nexport interface Paint {\n fill?: string;\n stroke?: string;\n strokeWidth?: number;\n opacity?: number;\n /** Round line joins/caps for organic shapes. */\n round?: boolean;\n}\n\nexport type TextAlign = 'left' | 'center' | 'right';\n\ninterface Base extends Paint {\n /** World transform (design-space). */\n transform: Transform;\n /** Painter's-order key; ties broken by tree order. Default 0. */\n z: number;\n}\n\nexport interface RectCommand extends Base {\n kind: 'rect';\n x: number;\n y: number;\n w: number;\n h: number;\n /** Corner radius. */\n r?: number;\n}\n\nexport interface CircleCommand extends Base {\n kind: 'circle';\n cx: number;\n cy: number;\n radius: number;\n}\n\nexport interface PolyCommand extends Base {\n kind: 'poly';\n /** Flat [x0,y0,x1,y1,\u2026] in local space. */\n points: number[];\n closed: boolean;\n}\n\nexport interface PathCommand extends Base {\n kind: 'path';\n /** SVG path data in local space. */\n d: string;\n}\n\nexport interface TextCommand extends Base {\n kind: 'text';\n text: string;\n x: number;\n y: number;\n size: number;\n font?: string;\n align?: TextAlign;\n weight?: number;\n}\n\nexport interface ImageCommand extends Base {\n kind: 'image';\n /** data: URI or path. */\n href: string;\n x: number;\n y: number;\n w: number;\n h: number;\n}\n\nexport type DrawCommand =\n | RectCommand\n | CircleCommand\n | PolyCommand\n | PathCommand\n | TextCommand\n | ImageCommand;\n\n/** Stable painter's sort: by z, then original index (tree order) as tiebreak. */\nexport function sortCommands(cmds: DrawCommand[]): DrawCommand[] {\n return cmds\n .map((c, i) => [c, i] as const)\n .sort((a, b) => a[0].z - b[0].z || a[1] - b[1])\n .map(([c]) => c);\n}\n", "// Pure display-list \u2192 SVG markup. No DOM required, so it runs in Node \u2014 which\n// means the engine can produce a *vector screenshot* of any frame headlessly\n// (an AI-first win: judge layout from a file, no browser, no GPU, no fuzz).\n// The DOM SvgRenderer reuses this; tests assert on it directly.\n\nimport { sortCommands, type DrawCommand, type Paint } from './commands';\nimport type { Transform } from '../core/math';\n\nconst n = (v: number): string => (Number.isInteger(v) ? String(v) : (Math.round(v * 1000) / 1000).toString());\n\nfunction matrix(t: Transform): string {\n return `matrix(${n(t.a)} ${n(t.b)} ${n(t.c)} ${n(t.d)} ${n(t.e)} ${n(t.f)})`;\n}\n\nfunction paintAttrs(p: Paint): string {\n const parts: string[] = [];\n parts.push(`fill=\"${p.fill ?? 'none'}\"`);\n if (p.stroke) {\n parts.push(`stroke=\"${p.stroke}\"`);\n parts.push(`stroke-width=\"${n(p.strokeWidth ?? 1)}\"`);\n if (p.round) parts.push('stroke-linejoin=\"round\" stroke-linecap=\"round\"');\n }\n if (p.opacity !== undefined && p.opacity !== 1) parts.push(`opacity=\"${n(p.opacity)}\"`);\n return parts.join(' ');\n}\n\nfunction escapeText(s: string): string {\n return s.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');\n}\n\nfunction commandToSVG(c: DrawCommand): string {\n const tf = `transform=\"${matrix(c.transform)}\"`;\n const paint = paintAttrs(c);\n switch (c.kind) {\n case 'rect':\n return `<rect x=\"${n(c.x)}\" y=\"${n(c.y)}\" width=\"${n(c.w)}\" height=\"${n(c.h)}\"${c.r ? ` rx=\"${n(c.r)}\"` : ''} ${tf} ${paint}/>`;\n case 'circle':\n return `<circle cx=\"${n(c.cx)}\" cy=\"${n(c.cy)}\" r=\"${n(c.radius)}\" ${tf} ${paint}/>`;\n case 'poly': {\n const pts = [];\n for (let i = 0; i < c.points.length; i += 2) pts.push(`${n(c.points[i])},${n(c.points[i + 1])}`);\n const tag = c.closed ? 'polygon' : 'polyline';\n return `<${tag} points=\"${pts.join(' ')}\" ${tf} ${paint}/>`;\n }\n case 'path':\n return `<path d=\"${c.d}\" ${tf} ${paint}/>`;\n case 'text': {\n const anchor = c.align === 'center' ? 'middle' : c.align === 'right' ? 'end' : 'start';\n const font = c.font ? ` font-family=\"${c.font}\"` : '';\n const weight = c.weight ? ` font-weight=\"${c.weight}\"` : '';\n const fill = c.fill ?? '#000';\n return `<text x=\"${n(c.x)}\" y=\"${n(c.y)}\" font-size=\"${n(c.size)}\" text-anchor=\"${anchor}\" dominant-baseline=\"middle\"${font}${weight} fill=\"${fill}\"${c.opacity !== undefined && c.opacity !== 1 ? ` opacity=\"${n(c.opacity)}\"` : ''} ${tf}>${escapeText(c.text)}</text>`;\n }\n case 'image':\n return `<image href=\"${c.href}\" x=\"${n(c.x)}\" y=\"${n(c.y)}\" width=\"${n(c.w)}\" height=\"${n(c.h)}\" ${tf}${c.opacity !== undefined && c.opacity !== 1 ? ` opacity=\"${n(c.opacity)}\"` : ''}/>`;\n }\n}\n\n/** Inner SVG markup for a display list (no wrapping <svg>). */\nexport function commandsToSVGInner(commands: DrawCommand[]): string {\n return sortCommands(commands).map(commandToSVG).join('');\n}\n\n/** A complete, standalone SVG document string for a frame \u2014 a headless screenshot. */\nexport function renderToSVGString(\n commands: DrawCommand[],\n width: number,\n height: number,\n background = '#ffffff',\n): string {\n return (\n `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 ${width} ${height}\" width=\"${width}\" height=\"${height}\">` +\n `<rect x=\"0\" y=\"0\" width=\"${width}\" height=\"${height}\" fill=\"${background}\"/>` +\n commandsToSVGInner(commands) +\n `</svg>`\n );\n}\n", "// SVG DOM backend. Resolution-independent (crisp at any DPR \u2014 the OHYG lesson:\n// SVG sidesteps canvas text fuzz entirely) and DOM-inspectable, which makes\n// browser verification trivial: querySelector IS the probe.\n\nimport type { DrawCommand } from './commands';\nimport type { Renderer, RendererConfig } from './renderer';\nimport { commandsToSVGInner } from './svgString';\n\nconst SVGNS = 'http://www.w3.org/2000/svg';\n\nexport class SvgRenderer implements Renderer {\n readonly width: number;\n readonly height: number;\n private background: string;\n private svg: SVGSVGElement;\n private bg: SVGRectElement;\n private layer: SVGGElement;\n\n constructor(config: RendererConfig) {\n this.width = config.width;\n this.height = config.height;\n this.background = config.background ?? '#ffffff';\n\n this.svg = document.createElementNS(SVGNS, 'svg');\n this.svg.setAttribute('viewBox', `0 0 ${this.width} ${this.height}`);\n this.svg.setAttribute('preserveAspectRatio', 'xMidYMid meet');\n this.svg.style.width = '100%';\n this.svg.style.height = '100%';\n this.svg.style.display = 'block';\n\n this.bg = document.createElementNS(SVGNS, 'rect');\n this.bg.setAttribute('x', '0');\n this.bg.setAttribute('y', '0');\n this.bg.setAttribute('width', String(this.width));\n this.bg.setAttribute('height', String(this.height));\n this.bg.setAttribute('fill', this.background);\n this.svg.appendChild(this.bg);\n\n this.layer = document.createElementNS(SVGNS, 'g');\n this.svg.appendChild(this.layer);\n }\n\n mount(parent: HTMLElement): void {\n parent.appendChild(this.svg);\n }\n\n draw(commands: DrawCommand[]): void {\n // Simple and correct for v0.1: rebuild the layer markup each frame. SVG is\n // retained-mode so the browser diffs efficiently; heavy scenes use Canvas2D.\n this.layer.innerHTML = commandsToSVGInner(commands);\n }\n\n setBackground(color: string): void {\n this.background = color;\n this.bg.setAttribute('fill', color);\n }\n\n get element(): SVGSVGElement {\n return this.svg;\n }\n\n dispose(): void {\n this.svg.remove();\n }\n}\n", "// Canvas2D backend. For scenes with many primitives/particles where SVG's DOM\n// node count would bite. Same display list, immediate-mode painting, DPR-aware.\n\nimport { sortCommands, type DrawCommand, type Paint } from './commands';\nimport type { Renderer, RendererConfig } from './renderer';\n\nexport class Canvas2DRenderer implements Renderer {\n readonly width: number;\n readonly height: number;\n private background: string;\n private canvas: HTMLCanvasElement;\n private ctx: CanvasRenderingContext2D;\n private dpr = 1;\n\n constructor(config: RendererConfig) {\n this.width = config.width;\n this.height = config.height;\n this.background = config.background ?? '#ffffff';\n this.canvas = document.createElement('canvas');\n this.canvas.style.width = '100%';\n this.canvas.style.height = '100%';\n // Letterbox, never stretch or crop: the design space must arrive intact\n // (a stretched canvas hides gameplay at the edges on off-ratio windows).\n this.canvas.style.objectFit = 'contain';\n this.canvas.style.display = 'block';\n const ctx = this.canvas.getContext('2d');\n if (!ctx) throw new Error('hayao: 2D canvas context unavailable');\n this.ctx = ctx;\n this.resize();\n }\n\n mount(parent: HTMLElement): void {\n parent.appendChild(this.canvas);\n this.resize();\n }\n\n private resize(): void {\n this.dpr = Math.min(3, globalThis.devicePixelRatio || 1);\n this.canvas.width = Math.round(this.width * this.dpr);\n this.canvas.height = Math.round(this.height * this.dpr);\n }\n\n draw(commands: DrawCommand[]): void {\n const ctx = this.ctx;\n ctx.setTransform(this.dpr, 0, 0, this.dpr, 0, 0);\n ctx.fillStyle = this.background;\n ctx.fillRect(0, 0, this.width, this.height);\n\n for (const c of sortCommands(commands)) {\n ctx.save();\n const t = c.transform;\n ctx.transform(t.a, t.b, t.c, t.d, t.e, t.f);\n ctx.globalAlpha = (c as Paint).opacity ?? 1;\n this.paint(ctx, c);\n ctx.restore();\n }\n }\n\n private stroke(ctx: CanvasRenderingContext2D, c: Paint): void {\n if (c.fill && c.fill !== 'none') {\n ctx.fillStyle = c.fill;\n ctx.fill();\n }\n if (c.stroke) {\n ctx.strokeStyle = c.stroke;\n ctx.lineWidth = c.strokeWidth ?? 1;\n if (c.round) {\n ctx.lineJoin = 'round';\n ctx.lineCap = 'round';\n }\n ctx.stroke();\n }\n }\n\n private paint(ctx: CanvasRenderingContext2D, c: DrawCommand): void {\n switch (c.kind) {\n case 'rect':\n ctx.beginPath();\n if (c.r) this.roundRect(ctx, c.x, c.y, c.w, c.h, c.r);\n else ctx.rect(c.x, c.y, c.w, c.h);\n this.stroke(ctx, c);\n break;\n case 'circle':\n ctx.beginPath();\n ctx.arc(c.cx, c.cy, c.radius, 0, Math.PI * 2);\n this.stroke(ctx, c);\n break;\n case 'poly':\n ctx.beginPath();\n for (let i = 0; i < c.points.length; i += 2) {\n if (i === 0) ctx.moveTo(c.points[i], c.points[i + 1]);\n else ctx.lineTo(c.points[i], c.points[i + 1]);\n }\n if (c.closed) ctx.closePath();\n this.stroke(ctx, c);\n break;\n case 'path':\n {\n const p = new Path2D(c.d);\n if (c.fill && c.fill !== 'none') {\n ctx.fillStyle = c.fill;\n ctx.fill(p);\n }\n if (c.stroke) {\n ctx.strokeStyle = c.stroke;\n ctx.lineWidth = c.strokeWidth ?? 1;\n if (c.round) {\n ctx.lineJoin = 'round';\n ctx.lineCap = 'round';\n }\n ctx.stroke(p);\n }\n }\n break;\n case 'text':\n ctx.fillStyle = c.fill ?? '#000';\n ctx.font = `${c.weight ?? 400} ${c.size}px ${c.font ?? 'sans-serif'}`;\n ctx.textAlign = c.align ?? 'left';\n ctx.textBaseline = 'middle';\n ctx.fillText(c.text, c.x, c.y);\n break;\n case 'image':\n break; // images loaded async; omitted in v0.1 canvas backend\n }\n }\n\n private roundRect(ctx: CanvasRenderingContext2D, x: number, y: number, w: number, h: number, r: number): void {\n const rr = Math.min(r, w / 2, h / 2);\n ctx.moveTo(x + rr, y);\n ctx.arcTo(x + w, y, x + w, y + h, rr);\n ctx.arcTo(x + w, y + h, x, y + h, rr);\n ctx.arcTo(x, y + h, x, y, rr);\n ctx.arcTo(x, y, x + w, y, rr);\n ctx.closePath();\n }\n\n get element(): HTMLCanvasElement {\n return this.canvas;\n }\n\n dispose(): void {\n this.canvas.remove();\n }\n}\n", "// The headless backend: records the last display list instead of painting it.\n// Tests assert on the commands directly; scripts turn them into a vector\n// screenshot via renderToSVGString. This is why a hayao game is testable with\n// zero browser \u2014 the renderer is just a data sink.\n\nimport type { DrawCommand } from './commands';\nimport type { Renderer, RendererConfig } from './renderer';\nimport { renderToSVGString } from './svgString';\n\nexport class HeadlessRenderer implements Renderer {\n readonly width: number;\n readonly height: number;\n private background: string;\n private last: DrawCommand[] = [];\n frameCount = 0;\n\n constructor(config: RendererConfig) {\n this.width = config.width;\n this.height = config.height;\n this.background = config.background ?? '#ffffff';\n }\n\n draw(commands: DrawCommand[]): void {\n this.last = commands;\n this.frameCount++;\n }\n\n /** The most recently drawn display list. */\n get commands(): DrawCommand[] {\n return this.last;\n }\n\n /** Count commands of a given kind (handy for assertions). */\n count(kind: DrawCommand['kind']): number {\n return this.last.filter((c) => c.kind === kind).length;\n }\n\n /** A vector screenshot of the last frame. */\n toSVGString(): string {\n return renderToSVGString(this.last, this.width, this.height, this.background);\n }\n}\n", "// 9-slice panels: one scalable UI frame from a handful of params. A rectangle is\n// split into a 3\u00D73 grid \u2014 the four corners keep a fixed size while the edges\n// stretch along one axis and the center fills \u2014 so a frame drawn at any size\n// keeps crisp, undistorted corners. Pure: it just emits DrawCommands into a\n// display list, so it renders headlessly and never touches game state. Colour the\n// regions differently (light top/left, dark bottom/right) for an instant bevel.\n\nimport { IDENTITY, type Rect, type Transform } from '../core/math';\nimport type { DrawCommand } from './commands';\n\nexport interface NineSliceStyle {\n /** Corner size in px \u2014 the slice inset that never stretches. */\n border: number;\n /** Center fill (the panel body). */\n fill?: string;\n /** Edge fill (top/bottom/left/right strips). Defaults to `fill`. */\n edge?: string;\n /** Corner fill (the four fixed squares). Defaults to `edge`. */\n corner?: string;\n /** Optional bevel: lighten the top/left, darken the bottom/right. */\n highlight?: string;\n shadow?: string;\n /** Outline stroke drawn around the whole frame. */\n stroke?: string;\n strokeWidth?: number;\n /** Outer corner radius applied to the four corner squares. */\n radius?: number;\n}\n\n/**\n * Emit the draw commands for a 9-slice panel filling `rect`. Regions are pushed\n * back-to-front (center \u2192 edges \u2192 corners) at painter key `z`, transformed by\n * `transform` (screen space by default). Border is clamped so it never exceeds\n * half the smaller side, keeping the grid valid at any size.\n */\nexport function nineSlice(rect: Rect, style: NineSliceStyle, z = 0, transform: Transform = IDENTITY): DrawCommand[] {\n const b = Math.max(0, Math.min(style.border, rect.w / 2, rect.h / 2));\n const fill = style.fill ?? '#fbf6ea';\n const edge = style.edge ?? fill;\n const corner = style.corner ?? edge;\n const out: DrawCommand[] = [];\n const x0 = rect.x;\n const x1 = rect.x + b;\n const x2 = rect.x + rect.w - b;\n const y0 = rect.y;\n const y1 = rect.y + b;\n const y2 = rect.y + rect.h - b;\n const iw = rect.w - 2 * b; // inner (stretched) width\n const ih = rect.h - 2 * b; // inner (stretched) height\n\n const push = (x: number, y: number, w: number, h: number, f: string, r?: number): void => {\n if (w <= 0 || h <= 0) return;\n out.push({ kind: 'rect', x, y, w, h, r, fill: f, transform, z });\n };\n\n // Center + the four stretchable edges.\n push(x1, y1, iw, ih, fill);\n push(x1, y0, iw, b, style.highlight ?? edge); // top\n push(x1, y2, iw, b, style.shadow ?? edge); // bottom\n push(x0, y1, b, ih, style.highlight ?? edge); // left\n push(x2, y1, b, ih, style.shadow ?? edge); // right\n\n // Four fixed corners (drawn last so their radius reads clean over the edges).\n const r = style.radius;\n push(x0, y0, b, b, corner, r);\n push(x2, y0, b, b, corner, r);\n push(x0, y2, b, b, corner, r);\n push(x2, y2, b, b, corner, r);\n\n // Optional outline around the whole frame.\n if (style.stroke) {\n out.push({\n kind: 'rect',\n x: rect.x,\n y: rect.y,\n w: rect.w,\n h: rect.h,\n r: style.radius,\n fill: 'none',\n stroke: style.stroke,\n strokeWidth: style.strokeWidth ?? 2,\n transform,\n z: z + 0.001,\n });\n }\n return out;\n}\n\n/** Ready-made frame looks. */\nexport const PANEL_PRESETS = {\n parchment: (): NineSliceStyle => ({ border: 10, fill: '#fbf6ea', edge: '#efe4c8', corner: '#e2d3a8', highlight: '#fdfaf0', shadow: '#d9c79c', stroke: '#b8a06a', strokeWidth: 2, radius: 4 }),\n slate: (): NineSliceStyle => ({ border: 8, fill: '#2c3040', edge: '#363c4f', corner: '#454c63', highlight: '#4a5268', shadow: '#20242f', stroke: '#151821', strokeWidth: 2, radius: 3 }),\n} as const;\n", "// Curated palettes \u2014 code-as-art means no arbitrary RGB; pick from a named,\n// on-model set. Default is a warm, high-legibility \"Meadow\" palette (a nod to\n// the Ghibli/Miyazaki-ish direction the engine is named for).\n\nimport type { Rng } from '../core/rng';\nimport { dexp2, dlog2 } from '../core/dmath';\n\nexport interface Palette {\n name: string;\n bg: string;\n ink: string;\n inkSoft: string;\n line: string;\n accent: string;\n accent2: string;\n good: string;\n warn: string;\n /** A small ordered ramp for categorical fills. */\n ramp: string[];\n}\n\nexport const MEADOW: Palette = {\n name: 'meadow',\n bg: '#f3ecdb',\n ink: '#3d3323',\n inkSoft: '#6f6047',\n line: '#d9ccae',\n accent: '#a11d3a',\n accent2: '#5a7d4e',\n good: '#4d6b3c',\n warn: '#c8791f',\n ramp: ['#a11d3a', '#c8791f', '#c9a22f', '#5a7d4e', '#3f7d8c', '#6a4c93'],\n};\n\nexport const DUSK: Palette = {\n name: 'dusk',\n bg: '#1c1a24',\n ink: '#efe9f2',\n inkSoft: '#a89fb5',\n line: '#3a3546',\n accent: '#e26d8a',\n accent2: '#6cc4a1',\n good: '#6cc4a1',\n warn: '#e8b64a',\n ramp: ['#e26d8a', '#e8b64a', '#f2e07a', '#6cc4a1', '#5aa9d6', '#b493e6'],\n};\n\nexport const PAPER: Palette = {\n name: 'paper',\n bg: '#faf7f0',\n ink: '#2b2b2b',\n inkSoft: '#666',\n line: '#e2ddd2',\n accent: '#d1495b',\n accent2: '#2e86ab',\n good: '#3c896d',\n warn: '#e0902f',\n ramp: ['#d1495b', '#e0902f', '#edc531', '#3c896d', '#2e86ab', '#8a5a9e'],\n};\n\nexport const PALETTES: Record<string, Palette> = { meadow: MEADOW, dusk: DUSK, paper: PAPER };\n\n/** Blend two hex colors (t in [0,1]). Deterministic, no allocations of note. */\nexport function mix(a: string, b: string, t: number): string {\n const pa = hexToRgb(a);\n const pb = hexToRgb(b);\n const r = Math.round(pa[0] + (pb[0] - pa[0]) * t);\n const g = Math.round(pa[1] + (pb[1] - pa[1]) * t);\n const bl = Math.round(pa[2] + (pb[2] - pa[2]) * t);\n return rgbToHex(r, g, bl);\n}\n\nexport function withAlpha(hex: string, alpha: number): string {\n const [r, g, b] = hexToRgb(hex);\n return `rgba(${r}, ${g}, ${b}, ${alpha})`;\n}\n\nfunction hexToRgb(hex: string): [number, number, number] {\n let h = hex.replace('#', '');\n if (h.length === 3) h = h.split('').map((c) => c + c).join('');\n const n = parseInt(h, 16);\n return [(n >> 16) & 255, (n >> 8) & 255, n & 255];\n}\nfunction rgbToHex(r: number, g: number, b: number): string {\n return '#' + [r, g, b].map((v) => Math.max(0, Math.min(255, Math.round(v))).toString(16).padStart(2, '0')).join('');\n}\n\n// \u2500\u2500 HSL / HSV constructors + drift \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// Procedural theming and palette drift (space-huggers `setHSLA`+`mutate`,\n// dr1v3n-wild/dodo `.hsl`). Pure arithmetic \u2014 no trig \u2014 so it's netplay-safe.\n// Colors are cosmetic; when drift reads `world.rng` it advances deterministically.\n\nexport interface HSL {\n /** Hue in degrees [0,360). */\n h: number;\n /** Saturation [0,1]. */\n s: number;\n /** Lightness [0,1]. */\n l: number;\n}\n\nconst mod360 = (h: number): number => ((h % 360) + 360) % 360;\nconst clamp01 = (v: number): number => (v < 0 ? 0 : v > 1 ? 1 : v);\n\n/** HSL \u2192 hex. h in degrees (wraps), s/l in [0,1]. */\nexport function hsl(h: number, s: number, l: number): string {\n h = mod360(h) / 360;\n s = clamp01(s);\n l = clamp01(l);\n if (s === 0) {\n const v = l * 255;\n return rgbToHex(v, v, v);\n }\n const q = l < 0.5 ? l * (1 + s) : l + s - l * s;\n const p = 2 * l - q;\n const hue = (t: number): number => {\n t = t < 0 ? t + 1 : t > 1 ? t - 1 : t;\n if (t < 1 / 6) return p + (q - p) * 6 * t;\n if (t < 1 / 2) return q;\n if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;\n return p;\n };\n return rgbToHex(hue(h + 1 / 3) * 255, hue(h) * 255, hue(h - 1 / 3) * 255);\n}\n\n/** HSV/HSB \u2192 hex. h in degrees (wraps), s/v in [0,1]. */\nexport function hsv(h: number, s: number, v: number): string {\n h = mod360(h) / 60;\n s = clamp01(s);\n v = clamp01(v);\n const c = v * s;\n const x = c * (1 - Math.abs((h % 2) - 1));\n const m = v - c;\n let r = 0;\n let g = 0;\n let b = 0;\n if (h < 1) [r, g, b] = [c, x, 0];\n else if (h < 2) [r, g, b] = [x, c, 0];\n else if (h < 3) [r, g, b] = [0, c, x];\n else if (h < 4) [r, g, b] = [0, x, c];\n else if (h < 5) [r, g, b] = [x, 0, c];\n else [r, g, b] = [c, 0, x];\n return rgbToHex((r + m) * 255, (g + m) * 255, (b + m) * 255);\n}\n\n/** Decompose a hex color into HSL. Inverse of `hsl()`. */\nexport function hexToHsl(hex: string): HSL {\n const [r255, g255, b255] = hexToRgb(hex);\n const r = r255 / 255;\n const g = g255 / 255;\n const b = b255 / 255;\n const max = Math.max(r, g, b);\n const min = Math.min(r, g, b);\n const l = (max + min) / 2;\n const d = max - min;\n if (d === 0) return { h: 0, s: 0, l };\n const s = l > 0.5 ? d / (2 - max - min) : d / (max + min);\n let h: number;\n if (max === r) h = (g - b) / d + (g < b ? 6 : 0);\n else if (max === g) h = (b - r) / d + 2;\n else h = (r - g) / d + 4;\n return { h: h * 60, s, l };\n}\n\nexport interface DriftAmounts {\n /** Max hue drift \u00B1 degrees. */\n hue?: number;\n /** Max saturation drift \u00B1 (absolute, [0,1]). */\n sat?: number;\n /** Max lightness drift \u00B1 (absolute, [0,1]). */\n light?: number;\n}\n\n/**\n * Drift a color in HSL space by random amounts from `world.rng` (space-huggers'\n * `mutate`). Deterministic given rng state; hue wraps, s/l clamp. Cosmetic, but\n * because it consumes rng draws, call it in a stable order.\n */\nexport function mutateColor(rng: Rng, hex: string, amounts: DriftAmounts = {}): string {\n const c = hexToHsl(hex);\n const dh = amounts.hue ?? 0;\n const ds = amounts.sat ?? 0;\n const dl = amounts.light ?? 0;\n return hsl(\n c.h + rng.range(-dh, dh),\n c.s + rng.range(-ds, ds),\n c.l + rng.range(-dl, dl),\n );\n}\n\n// \u2500\u2500 gamma-correct (linear-space) interpolation + gradients \u2500\u2500\u2500\u2500\u2500\u2500\n// super-castle blends in linear light, not sRGB \u2014 perceptually correct, no muddy\n// mid-tones. sRGB\u2194linear uses the exact IEC transfer curve; the 2.4 exponent\n// routes through dmath (dexp2/dlog2) so it's bit-identical across engines and\n// never trips the \"no Math.pow\" invariant.\n\nfunction dpow(base: number, exp: number): number {\n if (base <= 0) return 0;\n return dexp2(exp * dlog2(base));\n}\nconst srgbToLinear = (c: number): number => (c <= 0.04045 ? c / 12.92 : dpow((c + 0.055) / 1.055, 2.4));\nconst linearToSrgb = (c: number): number => (c <= 0.0031308 ? c * 12.92 : 1.055 * dpow(c, 1 / 2.4) - 0.055);\n\n/** Blend two hex colors in linear light (gamma-correct). t in [0,1]. */\nexport function mixLinear(a: string, b: string, t: number): string {\n const pa = hexToRgb(a);\n const pb = hexToRgb(b);\n const chan = (i: number): number => {\n const la = srgbToLinear(pa[i] / 255);\n const lb = srgbToLinear(pb[i] / 255);\n return linearToSrgb(la + (lb - la) * t) * 255;\n };\n return rgbToHex(chan(0), chan(1), chan(2));\n}\n\n/**\n * Sample a multi-stop gradient at t in [0,1], blending in linear light. Stops\n * are evenly spaced hex colors (\u2265 1). Great for procedural sky/heat/health ramps.\n */\nexport function sampleGradient(stops: readonly string[], t: number): string {\n if (stops.length === 0) return '#000000';\n if (stops.length === 1) return stops[0];\n const clamped = clamp01(t);\n const scaled = clamped * (stops.length - 1);\n const i = Math.min(stops.length - 2, Math.floor(scaled));\n return mixLinear(stops[i], stops[i + 1], scaled - i);\n}\n\n/** Materialize an n-color ramp from gradient stops (linear-light interpolation). */\nexport function gradient(stops: readonly string[], n: number): string[] {\n if (n <= 0) return [];\n if (n === 1) return [sampleGradient(stops, 0)];\n return Array.from({ length: n }, (_, i) => sampleGradient(stops, i / (n - 1)));\n}\n", "// Procedural vector shape builders \u2014 the \"code-as-art\" toolkit. All pure and\n// deterministic (any randomness must be passed an Rng), producing point arrays\n// or SVG path strings usable directly in a Sprite.\n\nimport { dcos, dsin } from '../core/dmath';\nimport type { Rng } from '../core/rng';\nimport { TAU, type Vec2 } from '../core/math';\n\n/** Regular polygon points (flat [x,y,\u2026]) centered at origin. */\nexport function regularPolygon(sides: number, radius: number, rotation = 0): number[] {\n const pts: number[] = [];\n for (let i = 0; i < sides; i++) {\n const a = rotation + (i / sides) * TAU;\n pts.push(dcos(a) * radius, dsin(a) * radius);\n }\n return pts;\n}\n\n/** Star with alternating outer/inner radii. */\nexport function star(points: number, outer: number, inner: number, rotation = -Math.PI / 2): number[] {\n const pts: number[] = [];\n for (let i = 0; i < points * 2; i++) {\n const r = i % 2 === 0 ? outer : inner;\n const a = rotation + (i / (points * 2)) * TAU;\n pts.push(dcos(a) * r, dsin(a) * r);\n }\n return pts;\n}\n\n/** An organic blob outline as an SVG path (deterministic given the Rng). */\nexport function blobPath(rng: Rng, radius: number, wobble = 0.25, lobes = 7): string {\n const pts: Vec2[] = [];\n for (let i = 0; i < lobes; i++) {\n const a = (i / lobes) * TAU;\n const r = radius * (1 - wobble + rng.float() * wobble * 2);\n pts.push({ x: dcos(a) * r, y: dsin(a) * r });\n }\n return smoothClosedPath(pts);\n}\n\n/** Convert a point list into a smooth closed path (Catmull-Rom \u2192 cubic B\u00E9zier). */\nexport function smoothClosedPath(points: Vec2[], tension = 1): string {\n const nPts = points.length;\n if (nPts < 3) return '';\n const p = (i: number) => points[((i % nPts) + nPts) % nPts];\n const r = (v: number) => Math.round(v * 100) / 100;\n let d = `M ${r(p(0).x)} ${r(p(0).y)}`;\n for (let i = 0; i < nPts; i++) {\n const p0 = p(i - 1);\n const p1 = p(i);\n const p2 = p(i + 1);\n const p3 = p(i + 2);\n const c1x = p1.x + ((p2.x - p0.x) / 6) * tension;\n const c1y = p1.y + ((p2.y - p0.y) / 6) * tension;\n const c2x = p2.x - ((p3.x - p1.x) / 6) * tension;\n const c2y = p2.y - ((p3.y - p1.y) / 6) * tension;\n d += ` C ${r(c1x)} ${r(c1y)}, ${r(c2x)} ${r(c2y)}, ${r(p2.x)} ${r(p2.y)}`;\n }\n return d + ' Z';\n}\n\n/** Smooth open path through points (for trails, curves). */\nexport function smoothOpenPath(points: Vec2[], tension = 1): string {\n const nPts = points.length;\n if (nPts < 2) return '';\n const r = (v: number) => Math.round(v * 100) / 100;\n let d = `M ${r(points[0].x)} ${r(points[0].y)}`;\n for (let i = 0; i < nPts - 1; i++) {\n const p0 = points[Math.max(0, i - 1)];\n const p1 = points[i];\n const p2 = points[i + 1];\n const p3 = points[Math.min(nPts - 1, i + 2)];\n const c1x = p1.x + ((p2.x - p0.x) / 6) * tension;\n const c1y = p1.y + ((p2.y - p0.y) / 6) * tension;\n const c2x = p2.x - ((p3.x - p1.x) / 6) * tension;\n const c2y = p2.y - ((p3.y - p1.y) / 6) * tension;\n d += ` C ${r(c1x)} ${r(c1y)}, ${r(c2x)} ${r(c2y)}, ${r(p2.x)} ${r(p2.y)}`;\n }\n return d;\n}\n", "// Procedural sprite / texture generation \u2014 build whole tilesets and sprites\n// from code with ~0 asset bytes (the defining js13k art trick). A `PixelBuffer`\n// is a tiny indexed bitmap; decoders reconstruct one from a compact encoding\n// (packed 2-bit, RLE run pairs, or a 1-bit BigInt/hex bitmap), and the emitter\n// projects it to run-merged `rect` draw commands the renderer already speaks.\n//\n// COSMETIC / DETERMINISM: the pixels here are pure *view* derived from constant\n// data (or from `world.rng`, never `Math.random`). The output rects carry no\n// canonical state, so `TextureSprite` sets `cosmetic = true` \u2014 it never enters\n// `world.hash()`/snapshot. Decoding is a pure function of its inputs.\n\nimport { IDENTITY, type Transform } from '../core/math';\nimport type { DrawCommand, RectCommand } from '../render/commands';\nimport { Node, type NodeConfig } from '../scene/node';\n\n/** A palette entry; `null` (or a missing index) renders transparent. */\nexport type Swatch = string | null;\n\n/** A small indexed bitmap: `data[y * width + x]` is a palette index. */\nexport class PixelBuffer {\n readonly width: number;\n readonly height: number;\n readonly data: Uint8Array;\n\n constructor(width: number, height: number, data?: Uint8Array) {\n this.width = width;\n this.height = height;\n this.data = data ?? new Uint8Array(width * height);\n }\n\n get(x: number, y: number): number {\n if (x < 0 || y < 0 || x >= this.width || y >= this.height) return 0;\n return this.data[y * this.width + x];\n }\n set(x: number, y: number, index: number): void {\n if (x < 0 || y < 0 || x >= this.width || y >= this.height) return;\n this.data[y * this.width + x] = index;\n }\n\n /** Build from a rows-of-strings grid, mapping each character to an index. */\n static fromRows(rows: readonly string[], charToIndex: Record<string, number>): PixelBuffer {\n const height = rows.length;\n const width = rows.reduce((w, r) => Math.max(w, r.length), 0);\n const buf = new PixelBuffer(width, height);\n for (let y = 0; y < height; y++) {\n const row = rows[y];\n for (let x = 0; x < row.length; x++) buf.data[y * width + x] = charToIndex[row[x]] ?? 0;\n }\n return buf;\n }\n\n /** A copy with every index passed through `lut` (2-bit \u2192 palette remap). */\n remap(lut: readonly number[]): PixelBuffer {\n const out = new Uint8Array(this.data.length);\n for (let i = 0; i < this.data.length; i++) out[i] = lut[this.data[i]] ?? 0;\n return new PixelBuffer(this.width, this.height, out);\n }\n}\n\n/** Normalize a packed bitmap source (hex string, `0b\u2026`/`0x\u2026`, or bigint) to a BigInt. */\nfunction toBig(source: bigint | string): bigint {\n if (typeof source === 'bigint') return source;\n const s = source.trim();\n if (s.startsWith('0x') || s.startsWith('0b') || s.startsWith('0o')) return BigInt(s);\n return BigInt('0x' + s);\n}\n\n/**\n * Decode a 1-bit-per-pixel bitmap packed MSB-first into a BigInt/hex string\n * (the super-castle-style trick). Pixel `i` reads bit `(w*h-1-i)`, so a hex\n * literal reads left-to-right, top-to-bottom. Produces indices 0 or 1.\n */\nexport function decodeBits(source: bigint | string, width: number, height: number): PixelBuffer {\n const bits = toBig(source);\n const total = width * height;\n const buf = new PixelBuffer(width, height);\n for (let i = 0; i < total; i++) {\n buf.data[i] = Number((bits >> BigInt(total - 1 - i)) & 1n);\n }\n return buf;\n}\n\n/**\n * Decode a 2-bit-per-pixel bitmap (indices 0\u20133) packed MSB-first, matching the\n * dying-dreams \"2-bit source \u2192 palette LUT\" pipeline. Pass the result through\n * `PixelBuffer.remap(lut)` to lift the 2-bit indices into a wider palette.\n */\nexport function decode2bit(source: bigint | string, width: number, height: number): PixelBuffer {\n const bits = toBig(source);\n const total = width * height;\n const buf = new PixelBuffer(width, height);\n for (let i = 0; i < total; i++) {\n const shift = BigInt((total - 1 - i) * 2);\n buf.data[i] = Number((bits >> shift) & 3n);\n }\n return buf;\n}\n\n/**\n * Decode a run-length-encoded index stream (witchcat-style). `runs` is a flat\n * list of `[count, index, count, index, \u2026]` filled row-major. A short encoding\n * for sprites dominated by flat colour.\n */\nexport function decodeRLE(runs: readonly number[], width: number, height: number): PixelBuffer {\n const buf = new PixelBuffer(width, height);\n let p = 0;\n for (let i = 0; i + 1 < runs.length; i += 2) {\n const count = runs[i];\n const index = runs[i + 1];\n for (let k = 0; k < count && p < buf.data.length; k++) buf.data[p++] = index;\n }\n return buf;\n}\n\n/** Encode a PixelBuffer back to RLE run pairs \u2014 the inverse of `decodeRLE`. */\nexport function encodeRLE(buf: PixelBuffer): number[] {\n const runs: number[] = [];\n const d = buf.data;\n for (let i = 0; i < d.length; ) {\n const v = d[i];\n let count = 1;\n while (i + count < d.length && d[i + count] === v) count++;\n runs.push(count, v);\n i += count;\n }\n return runs;\n}\n\nexport interface PixelDrawOptions {\n /** Size of one pixel cell in design units. Default 1. */\n cell?: number;\n /** Top-left origin in local space. Default 0,0. */\n x?: number;\n y?: number;\n /** Painter z. Default 0. */\n z?: number;\n /** World transform for the emitted commands. Default identity. */\n transform?: Transform;\n}\n\n/**\n * Project a PixelBuffer to `rect` draw commands, run-merging horizontal spans\n * of the same colour so a 16\u00D716 sprite is a handful of rects, not 256. Palette\n * entries that are `null`/undefined render transparent (skipped). Pure \u2014 the\n * commands carry no state and belong under a `cosmetic` node.\n */\nexport function pixelsToCommands(\n buf: PixelBuffer,\n palette: readonly Swatch[],\n options: PixelDrawOptions = {},\n): RectCommand[] {\n const cell = options.cell ?? 1;\n const ox = options.x ?? 0;\n const oy = options.y ?? 0;\n const z = options.z ?? 0;\n const transform = options.transform ?? IDENTITY;\n const out: RectCommand[] = [];\n for (let y = 0; y < buf.height; y++) {\n let x = 0;\n while (x < buf.width) {\n const idx = buf.get(x, y);\n const fill = palette[idx];\n if (fill == null) {\n x++;\n continue;\n }\n let run = 1;\n while (x + run < buf.width && buf.get(x + run, y) === idx) run++;\n out.push({\n kind: 'rect',\n x: ox + x * cell,\n y: oy + y * cell,\n w: run * cell,\n h: cell,\n transform,\n z,\n fill,\n });\n x += run;\n }\n }\n return out;\n}\n\nexport interface TextureSpriteConfig extends NodeConfig {\n buffer: PixelBuffer;\n palette: readonly Swatch[];\n /** Pixel cell size in design units. Default 1. */\n cell?: number;\n /** Draw centered on the node origin instead of top-left. Default true. */\n center?: boolean;\n}\n\n/**\n * A scene node that renders a decoded PixelBuffer. It is pure view over\n * constant art data, so it is `cosmetic = true` by default \u2014 excluded from\n * `serialize()`/`hash()`/snapshot. Position/scale it like any other node.\n */\nexport class TextureSprite extends Node {\n override readonly type = 'TextureSprite';\n buffer: PixelBuffer;\n palette: readonly Swatch[];\n cell: number;\n center: boolean;\n\n constructor(config: TextureSpriteConfig) {\n super(config);\n this.buffer = config.buffer;\n this.palette = config.palette;\n this.cell = config.cell ?? 1;\n this.center = config.center ?? true;\n this.cosmetic = true;\n }\n\n protected override draw(out: DrawCommand[], world: Transform): void {\n const cell = this.cell;\n const x = this.center ? -(this.buffer.width * cell) / 2 : 0;\n const y = this.center ? -(this.buffer.height * cell) / 2 : 0;\n for (const cmd of pixelsToCommands(this.buffer, this.palette, { cell, x, y, z: this.z, transform: world })) {\n out.push(cmd);\n }\n }\n}\n", "// A built-in 5-pixel-tall proportional bitmap font (\"code-as-art\" \u2014 no font\n// asset). Each glyph is rows of `#` (lit) / `.` (off), top to bottom; the glyph\n// width is its row length, so letters are proportional (I is 1 wide, M is 5).\n// Uppercase-only: layout folds lowercase to uppercase. Pure constant data.\n\n/** A font: named glyph bitmaps plus vertical/spacing metrics. */\nexport interface BitmapFont {\n readonly height: number;\n /** Blank columns between glyphs. */\n readonly tracking: number;\n /** Width of a space character (advance only, no pixels). */\n readonly spaceWidth: number;\n readonly glyphs: Readonly<Record<string, readonly string[]>>;\n}\n\nconst G: Record<string, string[]> = {\n A: ['.#.', '#.#', '###', '#.#', '#.#'],\n B: ['##.', '#.#', '##.', '#.#', '##.'],\n C: ['.##', '#..', '#..', '#..', '.##'],\n D: ['##.', '#.#', '#.#', '#.#', '##.'],\n E: ['###', '#..', '##.', '#..', '###'],\n F: ['###', '#..', '##.', '#..', '#..'],\n G: ['.##', '#..', '#.#', '#.#', '.##'],\n H: ['#.#', '#.#', '###', '#.#', '#.#'],\n I: ['#', '#', '#', '#', '#'],\n J: ['..#', '..#', '..#', '#.#', '.#.'],\n K: ['#.#', '##.', '#..', '##.', '#.#'],\n L: ['#..', '#..', '#..', '#..', '###'],\n M: ['#...#', '##.##', '#.#.#', '#...#', '#...#'],\n N: ['#...#', '##..#', '#.#.#', '#..##', '#...#'],\n O: ['.#.', '#.#', '#.#', '#.#', '.#.'],\n P: ['##.', '#.#', '##.', '#..', '#..'],\n Q: ['.#.', '#.#', '#.#', '#.#', '.##'],\n R: ['##.', '#.#', '##.', '#.#', '#.#'],\n S: ['.##', '#..', '.#.', '..#', '##.'],\n T: ['###', '.#.', '.#.', '.#.', '.#.'],\n U: ['#.#', '#.#', '#.#', '#.#', '###'],\n V: ['#.#', '#.#', '#.#', '#.#', '.#.'],\n W: ['#...#', '#...#', '#.#.#', '##.##', '#...#'],\n X: ['#.#', '#.#', '.#.', '#.#', '#.#'],\n Y: ['#.#', '#.#', '.#.', '.#.', '.#.'],\n Z: ['###', '..#', '.#.', '#..', '###'],\n '0': ['.#.', '#.#', '#.#', '#.#', '.#.'],\n '1': ['.#.', '##.', '.#.', '.#.', '###'],\n '2': ['##.', '..#', '.#.', '#..', '###'],\n '3': ['##.', '..#', '.#.', '..#', '##.'],\n '4': ['#.#', '#.#', '###', '..#', '..#'],\n '5': ['###', '#..', '##.', '..#', '##.'],\n '6': ['.##', '#..', '##.', '#.#', '.#.'],\n '7': ['###', '..#', '.#.', '.#.', '.#.'],\n '8': ['.#.', '#.#', '.#.', '#.#', '.#.'],\n '9': ['.#.', '#.#', '.##', '..#', '##.'],\n '.': ['.', '.', '.', '.', '#'],\n ',': ['..', '..', '..', '.#', '#.'],\n '!': ['#', '#', '#', '.', '#'],\n '?': ['##.', '..#', '.#.', '...', '.#.'],\n ':': ['.', '#', '.', '#', '.'],\n ';': ['..', '.#', '..', '.#', '#.'],\n '-': ['...', '...', '###', '...', '...'],\n '+': ['...', '.#.', '###', '.#.', '...'],\n '=': ['...', '###', '...', '###', '...'],\n '/': ['..#', '..#', '.#.', '#..', '#..'],\n \"'\": ['#', '#', '.', '.', '.'],\n '\"': ['#.#', '#.#', '...', '...', '...'],\n '(': ['.#', '#.', '#.', '#.', '.#'],\n ')': ['#.', '.#', '.#', '.#', '#.'],\n '<': ['..#', '.#.', '#..', '.#.', '..#'],\n '>': ['#..', '.#.', '..#', '.#.', '#..'],\n '%': ['#.#', '..#', '.#.', '#..', '#.#'],\n '*': ['...', '#.#', '.#.', '#.#', '...'],\n '#': ['#.#', '###', '#.#', '###', '#.#'],\n};\n\n/** The default built-in font: 5px tall, proportional, uppercase + digits + punctuation. */\nexport const FONT_5: BitmapFont = {\n height: 5,\n tracking: 1,\n spaceWidth: 3,\n glyphs: G,\n};\n", "// Bitmap/pixel text: glyph atlas \u2192 proportional layout \u2192 run-merged draw\n// commands. Covers what the js13k HUD/dialogue games hand-build: per-char\n// widths, word wrap, typewriter reveal (clock-driven, never wall-clock), and\n// inline colour markup via a `{tag}\u2026{/}` stack (clawstrike/coup-ahoo style).\n//\n// COSMETIC / DETERMINISM: text is pure view. Layout is a pure function of\n// (font, string, width). Typewriter reveal is a pure function of sim time from\n// `world.time`/`clock` \u2014 no `performance.now`. `BitmapText` is `cosmetic`.\n\nimport { IDENTITY, type Transform } from '../core/math';\nimport type { DrawCommand, RectCommand, TextAlign } from '../render/commands';\nimport { Node, type NodeConfig } from '../scene/node';\nimport { FONT_5, type BitmapFont } from './font5';\n\n/** One source character with an optional colour and its index in the source string. */\nexport interface RichChar {\n ch: string;\n color?: string;\n i: number;\n}\n\n/**\n * Parse inline colour markup into per-character colours. `{name}` pushes a\n * colour, `{/}` pops it (a stack, so nesting works); `{{` is a literal `{`.\n * A tag resolves through `colorMap`, or is used literally if it starts with `#`\n * or is not in the map. Text outside any tag has no colour (caller default).\n */\nexport function parseRich(markup: string, colorMap: Record<string, string> = {}): RichChar[] {\n const out: RichChar[] = [];\n const stack: string[] = [];\n let i = 0;\n let srcIndex = 0;\n while (i < markup.length) {\n const c = markup[i];\n if (c === '{' && markup[i + 1] === '{') {\n out.push({ ch: '{', color: stack[stack.length - 1], i: srcIndex++ });\n i += 2;\n continue;\n }\n if (c === '{') {\n const end = markup.indexOf('}', i);\n if (end === -1) {\n out.push({ ch: c, color: stack[stack.length - 1], i: srcIndex++ });\n i++;\n continue;\n }\n const tag = markup.slice(i + 1, end);\n if (tag === '/') stack.pop();\n else stack.push(tag[0] === '#' ? tag : (colorMap[tag] ?? tag));\n i = end + 1;\n continue;\n }\n out.push({ ch: c, color: stack[stack.length - 1], i: srcIndex++ });\n i++;\n }\n return out;\n}\n\n/** Fold a character to one the font can draw (uppercase; unknown \u2192 space or `?`). */\nfunction resolveChar(font: BitmapFont, ch: string): string {\n if (ch === ' ' || ch === '\\n') return ch;\n const up = ch.toUpperCase();\n if (font.glyphs[up]) return up;\n if (font.glyphs[ch]) return ch;\n return font.glyphs['?'] ? '?' : ' ';\n}\n\n/** Width of a single glyph (advance excludes tracking). */\nfunction glyphWidth(font: BitmapFont, ch: string): number {\n if (ch === ' ') return font.spaceWidth;\n const rows = font.glyphs[ch];\n return rows ? rows[0].length : font.spaceWidth;\n}\n\n/** Width in font-pixels of a run of already-resolved chars on one line. */\nexport function measureLine(font: BitmapFont, chars: readonly RichChar[]): number {\n let w = 0;\n for (let k = 0; k < chars.length; k++) {\n w += glyphWidth(font, chars[k].ch);\n if (k < chars.length - 1) w += font.tracking;\n }\n return w;\n}\n\n/** Width in font-pixels of a plain string (no wrapping). */\nexport function measureText(font: BitmapFont, text: string): number {\n return measureLine(font, [...text].map((ch, i) => ({ ch: resolveChar(font, ch), i })));\n}\n\nexport interface PlacedGlyph {\n ch: string;\n color?: string;\n /** Source-string index (for typewriter reveal). */\n i: number;\n /** Top-left in font-pixel units. */\n x: number;\n y: number;\n w: number;\n}\n\nexport interface TextLayout {\n glyphs: PlacedGlyph[];\n /** Bounding size in font-pixel units. */\n width: number;\n height: number;\n lines: number;\n}\n\nexport interface TextLayoutOptions {\n /** Wrap width in font-pixels. Omit for no wrapping. */\n maxWidth?: number;\n /** Extra blank rows between lines. Default 1. */\n lineSpacing?: number;\n /** Horizontal alignment within `maxWidth` (or the widest line). Default 'left'. */\n align?: TextAlign;\n}\n\n/**\n * Lay out text into placed glyphs (font-pixel coords), word-wrapping on spaces\n * and breaking on `\\n`. Accepts a plain string or a `RichChar[]` from\n * `parseRich`. Pure and deterministic.\n */\nexport function layoutText(\n font: BitmapFont,\n input: string | readonly RichChar[],\n options: TextLayoutOptions = {},\n): TextLayout {\n const lineSpacing = options.lineSpacing ?? 1;\n const source: RichChar[] =\n typeof input === 'string' ? [...input].map((ch, i) => ({ ch, i })) : input.map((r) => ({ ...r }));\n\n // Split into hard lines on '\\n', then greedily wrap each on spaces.\n const hardLines: RichChar[][] = [[]];\n for (const rc of source) {\n if (rc.ch === '\\n') hardLines.push([]);\n else hardLines[hardLines.length - 1].push({ ...rc, ch: resolveChar(font, rc.ch) });\n }\n\n const rows: RichChar[][] = [];\n for (const line of hardLines) {\n if (options.maxWidth === undefined) {\n rows.push(line);\n continue;\n }\n let current: RichChar[] = [];\n let word: RichChar[] = [];\n const flushWord = () => {\n if (word.length === 0) return;\n const sep = current.length ? font.spaceWidth + font.tracking : 0;\n if (current.length && measureLine(font, current) + sep + measureLine(font, word) > options.maxWidth!) {\n rows.push(current);\n current = [];\n }\n if (current.length) current.push({ ch: ' ', i: -1 });\n current.push(...word);\n word = [];\n };\n for (const rc of line) {\n if (rc.ch === ' ') flushWord();\n else word.push(rc);\n }\n flushWord();\n rows.push(current);\n }\n\n const glyphs: PlacedGlyph[] = [];\n let maxW = 0;\n for (const row of rows) maxW = Math.max(maxW, measureLine(font, row));\n const boundW = options.maxWidth ?? maxW;\n\n let y = 0;\n for (const row of rows) {\n const rowW = measureLine(font, row);\n let x = options.align === 'center' ? Math.floor((boundW - rowW) / 2) : options.align === 'right' ? boundW - rowW : 0;\n for (const rc of row) {\n const w = glyphWidth(font, rc.ch);\n if (rc.ch !== ' ') glyphs.push({ ch: rc.ch, color: rc.color, i: rc.i, x, y, w });\n x += w + font.tracking;\n }\n y += font.height + lineSpacing;\n }\n\n return { glyphs, width: boundW, height: rows.length * (font.height + lineSpacing) - lineSpacing, lines: rows.length };\n}\n\n/** Typewriter: how many source characters are revealed after `elapsed` seconds. */\nexport function typewriterCount(total: number, elapsedSec: number, charsPerSec: number): number {\n if (charsPerSec <= 0) return total;\n const n = Math.floor(elapsedSec * charsPerSec);\n return n < 0 ? 0 : n > total ? total : n;\n}\n\nexport interface TextDrawOptions {\n /** Font-pixel cell size in design units. Default 2. */\n cell?: number;\n /** Top-left origin in local space. Default 0,0. */\n x?: number;\n y?: number;\n z?: number;\n /** Default fill for glyphs without an inline colour. Default '#000'. */\n color?: string;\n transform?: Transform;\n /** Draw only glyphs whose source index is `< reveal` (typewriter). */\n reveal?: number;\n}\n\n/**\n * Project a laid-out text to run-merged `rect` commands \u2014 one rect per\n * horizontal span of lit pixels. Pure; the commands belong under a `cosmetic`\n * node.\n */\nexport function textToCommands(\n font: BitmapFont,\n layout: TextLayout,\n options: TextDrawOptions = {},\n): RectCommand[] {\n const cell = options.cell ?? 2;\n const ox = options.x ?? 0;\n const oy = options.y ?? 0;\n const z = options.z ?? 0;\n const transform = options.transform ?? IDENTITY;\n const defColor = options.color ?? '#000';\n const reveal = options.reveal;\n const out: RectCommand[] = [];\n for (const g of layout.glyphs) {\n if (reveal !== undefined && g.i >= reveal) continue;\n const rows = font.glyphs[g.ch];\n if (!rows) continue;\n const fill = g.color ?? defColor;\n for (let ry = 0; ry < rows.length; ry++) {\n const row = rows[ry];\n let cx = 0;\n while (cx < row.length) {\n if (row[cx] !== '#') {\n cx++;\n continue;\n }\n let run = 1;\n while (cx + run < row.length && row[cx + run] === '#') run++;\n out.push({\n kind: 'rect',\n x: ox + (g.x + cx) * cell,\n y: oy + (g.y + ry) * cell,\n w: run * cell,\n h: cell,\n transform,\n z,\n fill,\n });\n cx += run;\n }\n }\n }\n return out;\n}\n\nexport interface BitmapTextConfig extends NodeConfig {\n text: string;\n font?: BitmapFont;\n cell?: number;\n color?: string;\n /** Resolve `{tag}` markup names to colours. */\n colorMap?: Record<string, string>;\n /** Wrap width in font-pixels. */\n maxWidth?: number;\n lineSpacing?: number;\n align?: TextAlign;\n /** Typewriter speed in chars/sec (clock-driven). Omit to show all at once. */\n charsPerSec?: number;\n /** Center the block on the node origin instead of top-left. Default false. */\n center?: boolean;\n}\n\n/**\n * A scene node that renders bitmap text with optional inline colour and a\n * clock-driven typewriter reveal. Pure view \u2192 `cosmetic = true` (never hashed).\n */\nexport class BitmapText extends Node {\n override readonly type = 'BitmapText';\n text: string;\n font: BitmapFont;\n cell: number;\n color: string;\n colorMap: Record<string, string>;\n maxWidth?: number;\n lineSpacing: number;\n align: TextAlign;\n charsPerSec?: number;\n center: boolean;\n private startTime = 0;\n\n constructor(config: BitmapTextConfig) {\n super(config);\n this.text = config.text;\n this.font = config.font ?? FONT_5;\n this.cell = config.cell ?? 2;\n this.color = config.color ?? '#000';\n this.colorMap = config.colorMap ?? {};\n this.maxWidth = config.maxWidth;\n this.lineSpacing = config.lineSpacing ?? 1;\n this.align = config.align ?? 'left';\n this.charsPerSec = config.charsPerSec;\n this.center = config.center ?? false;\n this.cosmetic = true;\n }\n\n protected override onReady(): void {\n this.startTime = this.world?.time ?? 0;\n }\n\n /** Restart the typewriter from the current sim time. */\n restartReveal(): void {\n this.startTime = this.world?.time ?? 0;\n }\n\n private buildLayout(): TextLayout {\n const chars = parseRich(this.text, this.colorMap);\n return layoutText(this.font, chars, { maxWidth: this.maxWidth, lineSpacing: this.lineSpacing, align: this.align });\n }\n\n protected override draw(out: DrawCommand[], world: Transform): void {\n const layout = this.buildLayout();\n let reveal: number | undefined;\n if (this.charsPerSec !== undefined) {\n const elapsed = (this.world?.time ?? 0) - this.startTime;\n reveal = typewriterCount(this.text.length, elapsed, this.charsPerSec);\n }\n const x = this.center ? -(layout.width * this.cell) / 2 : 0;\n const y = this.center ? -(layout.height * this.cell) / 2 : 0;\n for (const cmd of textToCommands(this.font, layout, {\n cell: this.cell,\n x,\n y,\n z: this.z,\n color: this.color,\n transform: world,\n reveal,\n })) {\n out.push(cmd);\n }\n }\n}\n", "// Autotiling: turn a boolean/logical grid into seamless tile art. Two solvers,\n// both fully pure and deterministic (no RNG):\n// \u2022 4-/8-neighbour bitmask \u2192 a base `frame` + `rotation` (Wang tiles), the\n// dying-dreams/witchcat wall-and-edge trick.\n// \u2022 marching squares over the grid corners \u2192 a 0\u201315 case per dual cell, plus\n// iso-contour segments for smooth outlines.\n//\n// The classification is pure logic and MAY inform gameplay, but the *emitted*\n// draw commands are art \u2192 the caller places them under a `cosmetic` node so\n// they stay out of `world.hash()`. BoolGrid is row-major: `grid[y][x]`.\n\nimport { IDENTITY, type Transform } from '../core/math';\nimport type { PolyCommand, RectCommand } from '../render/commands';\n\nexport type BoolGrid = readonly (readonly boolean[])[];\n\n/** Build a grid from rows of text; a cell is solid when its char is in `solid`. */\nexport function gridFromRows(rows: readonly string[], solid = '#'): boolean[][] {\n return rows.map((r) => [...r].map((c) => solid.includes(c)));\n}\n\nfunction at(grid: BoolGrid, x: number, y: number): boolean {\n return y >= 0 && y < grid.length && x >= 0 && x < grid[y].length && grid[y][x];\n}\n\n// \u2500\u2500 4-neighbour Wang bitmask \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// Bit order N=1, E=2, S=4, W=8 (set when that side connects to another solid).\n\nexport const Edge = { N: 1, E: 2, S: 4, W: 8 } as const;\nexport type Edge = (typeof Edge)[keyof typeof Edge];\n\n/** 4-bit edge mask of solid neighbours around a cell. */\nexport function mask4(grid: BoolGrid, x: number, y: number): number {\n return (\n (at(grid, x, y - 1) ? Edge.N : 0) |\n (at(grid, x + 1, y) ? Edge.E : 0) |\n (at(grid, x, y + 1) ? Edge.S : 0) |\n (at(grid, x - 1, y) ? Edge.W : 0)\n );\n}\n\n/** 8-bit neighbour mask, bit order N,NE,E,SE,S,SW,W,NW (1,2,4,\u2026,128). */\nexport function mask8(grid: BoolGrid, x: number, y: number): number {\n let m = 0;\n const dirs: ReadonlyArray<readonly [number, number]> = [\n [0, -1], [1, -1], [1, 0], [1, 1], [0, 1], [-1, 1], [-1, 0], [-1, -1],\n ];\n for (let i = 0; i < 8; i++) if (at(grid, x + dirs[i][0], y + dirs[i][1])) m |= 1 << i;\n return m;\n}\n\n/** Base tile shapes an edge mask resolves to (rotate `frame` by `rotation`\u00D790\u00B0 CW). */\nexport const WangFrame = { Isolated: 0, Cap: 1, Straight: 2, Bend: 3, Tee: 4, Cross: 5 } as const;\nexport type WangFrame = (typeof WangFrame)[keyof typeof WangFrame];\n\nexport interface WangTile {\n mask: number;\n frame: WangFrame;\n /** Quarter turns clockwise applied to the base frame (0\u20133). */\n rotation: number;\n}\n\nfunction rotateCW(m: number): number {\n let r = 0;\n if (m & Edge.N) r |= Edge.E;\n if (m & Edge.E) r |= Edge.S;\n if (m & Edge.S) r |= Edge.W;\n if (m & Edge.W) r |= Edge.N;\n return r;\n}\n\n// Precomputed 16-entry mask \u2192 {frame, rotation} table. Built by rotating one\n// canonical mask per frame through four quarter turns (pure, module-load once).\nconst WANG4: WangTile[] = (() => {\n const bases: ReadonlyArray<readonly [WangFrame, number]> = [\n [WangFrame.Isolated, 0b0000],\n [WangFrame.Cap, Edge.N],\n [WangFrame.Straight, Edge.N | Edge.S],\n [WangFrame.Bend, Edge.N | Edge.E],\n [WangFrame.Tee, Edge.N | Edge.E | Edge.S],\n [WangFrame.Cross, 0b1111],\n ];\n const table: WangTile[] = new Array(16);\n for (const [frame, mask0] of bases) {\n let m = mask0;\n for (let rotation = 0; rotation < 4; rotation++) {\n if (table[m] === undefined) table[m] = { mask: m, frame, rotation };\n m = rotateCW(m);\n }\n }\n return table;\n})();\n\n/** Resolve an edge mask (0\u201315) to its base frame + rotation. */\nexport function wangTile(mask: number): WangTile {\n return WANG4[mask & 15];\n}\n\n/** Classify every solid cell into a {frame, rotation}; empty cells are `null`. */\nexport function autotile4(grid: BoolGrid): (WangTile | null)[][] {\n return grid.map((row, y) => row.map((solid, x) => (solid ? wangTile(mask4(grid, x, y)) : null)));\n}\n\n// \u2500\u2500 Marching squares (corner-sampled dual grid) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// Case bit order over a cell's corners: TL=1, TR=2, BR=4, BL=8.\n\n/** Per-dual-cell case index (0\u201315) over the grid corners; size (h-1)\u00D7(w-1). */\nexport function marchingSquaresCases(grid: BoolGrid): number[][] {\n const h = grid.length;\n const w = h ? grid[0].length : 0;\n const out: number[][] = [];\n for (let y = 0; y < h - 1; y++) {\n const row: number[] = [];\n for (let x = 0; x < w - 1; x++) {\n row.push(\n (at(grid, x, y) ? 1 : 0) |\n (at(grid, x + 1, y) ? 2 : 0) |\n (at(grid, x + 1, y + 1) ? 4 : 0) |\n (at(grid, x, y + 1) ? 8 : 0),\n );\n }\n out.push(row);\n }\n return out;\n}\n\n// Edge midpoints per case, referenced as pairs. T=top, R=right, B=bottom, L=left.\ntype MSEdge = 'T' | 'R' | 'B' | 'L';\nconst MS_SEGMENTS: ReadonlyArray<ReadonlyArray<readonly [MSEdge, MSEdge]>> = [\n [], // 0\n [['L', 'T']], // 1 TL\n [['T', 'R']], // 2 TR\n [['L', 'R']], // 3 TL,TR\n [['R', 'B']], // 4 BR\n [['L', 'T'], ['R', 'B']], // 5 saddle\n [['T', 'B']], // 6 TR,BR\n [['L', 'B']], // 7 TL,TR,BR\n [['B', 'L']], // 8 BL\n [['T', 'B']], // 9 TL,BL\n [['T', 'R'], ['B', 'L']], // 10 saddle\n [['R', 'B']], // 11 TL,TR,BL\n [['L', 'R']], // 12 BR,BL\n [['T', 'R']], // 13 TL,BR,BL\n [['L', 'T']], // 14 TR,BR,BL\n [], // 15\n];\n\nexport interface ContourSegment {\n a: { x: number; y: number };\n b: { x: number; y: number };\n}\n\nexport interface ContourOptions {\n /** Cell size in design units. Default 1. */\n cell?: number;\n x?: number;\n y?: number;\n}\n\n/** Iso-contour line segments tracing the solid/empty boundary (design units). */\nexport function marchingSquaresContours(grid: BoolGrid, options: ContourOptions = {}): ContourSegment[] {\n const cell = options.cell ?? 1;\n const ox = options.x ?? 0;\n const oy = options.y ?? 0;\n const cases = marchingSquaresCases(grid);\n const segs: ContourSegment[] = [];\n const mid = (edge: MSEdge, cx: number, cy: number) => {\n switch (edge) {\n case 'T': return { x: cx + cell / 2, y: cy };\n case 'R': return { x: cx + cell, y: cy + cell / 2 };\n case 'B': return { x: cx + cell / 2, y: cy + cell };\n case 'L': return { x: cx, y: cy + cell / 2 };\n }\n };\n for (let y = 0; y < cases.length; y++) {\n for (let x = 0; x < cases[y].length; x++) {\n const cx = ox + x * cell;\n const cy = oy + y * cell;\n for (const [e1, e2] of MS_SEGMENTS[cases[y][x]]) segs.push({ a: mid(e1, cx, cy), b: mid(e2, cx, cy) });\n }\n }\n return segs;\n}\n\n// \u2500\u2500 Emitters (cosmetic draw data) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport interface AutotileDrawOptions {\n /** Tile size in design units. Default 8. */\n tile?: number;\n x?: number;\n y?: number;\n z?: number;\n transform?: Transform;\n /** Fill colour of solid tiles. */\n fill?: string;\n /** Stroke colour drawn only on sides exposed to empty (the seam). */\n edge?: string;\n edgeWidth?: number;\n}\n\n/**\n * Draw a boolean grid as seamless tiles: a fill per solid cell plus an edge\n * stroke only on sides facing empty (derived from `mask4`). Pure draw data for\n * a `cosmetic` node.\n */\nexport function autotileToCommands(grid: BoolGrid, options: AutotileDrawOptions = {}): (RectCommand | PolyCommand)[] {\n const tile = options.tile ?? 8;\n const ox = options.x ?? 0;\n const oy = options.y ?? 0;\n const z = options.z ?? 0;\n const transform = options.transform ?? IDENTITY;\n const fill = options.fill ?? '#888';\n const edge = options.edge;\n const edgeWidth = options.edgeWidth ?? Math.max(1, tile / 8);\n const out: (RectCommand | PolyCommand)[] = [];\n for (let y = 0; y < grid.length; y++) {\n for (let x = 0; x < grid[y].length; x++) {\n if (!grid[y][x]) continue;\n const px = ox + x * tile;\n const py = oy + y * tile;\n out.push({ kind: 'rect', x: px, y: py, w: tile, h: tile, transform, z, fill });\n if (!edge) continue;\n const m = mask4(grid, x, y);\n const line = (points: number[]) =>\n out.push({ kind: 'poly', points, closed: false, transform, z: z + 1, stroke: edge, strokeWidth: edgeWidth });\n if (!(m & Edge.N)) line([px, py, px + tile, py]);\n if (!(m & Edge.E)) line([px + tile, py, px + tile, py + tile]);\n if (!(m & Edge.S)) line([px, py + tile, px + tile, py + tile]);\n if (!(m & Edge.W)) line([px, py, px, py + tile]);\n }\n }\n return out;\n}\n\n/** Draw the marching-squares iso-contour as open polylines (cosmetic draw data). */\nexport function contourToCommands(grid: BoolGrid, options: AutotileDrawOptions = {}): PolyCommand[] {\n const tile = options.tile ?? 8;\n const transform = options.transform ?? IDENTITY;\n const z = options.z ?? 0;\n const stroke = options.edge ?? options.fill ?? '#333';\n const strokeWidth = options.edgeWidth ?? Math.max(1, tile / 8);\n const segs = marchingSquaresContours(grid, { cell: tile, x: options.x ?? 0, y: options.y ?? 0 });\n return segs.map((s) => ({\n kind: 'poly',\n points: [s.a.x, s.a.y, s.b.x, s.b.y],\n closed: false,\n transform,\n z,\n stroke,\n strokeWidth,\n round: true,\n }));\n}\n", "// Shared boolean grid for procgen output. Plain data + pure functions (house\n// style) so generated levels serialize, hash, and diff cleanly. Convention:\n// `1` = solid/wall, `0` = open/floor \u2014 matching TILE.SOLID / TILE.EMPTY so a\n// grid drops straight into the collision tilemap.\n\nimport { TILE, type TilemapData } from '../physics/tilemap';\n\nexport interface Grid {\n cols: number;\n rows: number;\n /** Row-major cells, length cols*rows. 1 = solid, 0 = open. */\n cells: number[];\n}\n\n/** Allocate a grid filled with a single value (default open). */\nexport function makeGrid(cols: number, rows: number, fill = 0): Grid {\n return { cols, rows, cells: new Array<number>(cols * rows).fill(fill) };\n}\n\n/** Read a cell; out-of-bounds reads as solid (1) so borders seal naturally. */\nexport function gridAt(g: Grid, x: number, y: number): number {\n if (x < 0 || y < 0 || x >= g.cols || y >= g.rows) return 1;\n return g.cells[y * g.cols + x];\n}\n\n/** Write a cell (no-op out of bounds). */\nexport function gridSet(g: Grid, x: number, y: number, v: number): void {\n if (x < 0 || y < 0 || x >= g.cols || y >= g.rows) return;\n g.cells[y * g.cols + x] = v;\n}\n\n/** Count solid cells in the 8-neighbourhood (Moore) around (x,y). */\nexport function solidNeighbours(g: Grid, x: number, y: number): number {\n let n = 0;\n for (let dy = -1; dy <= 1; dy++) {\n for (let dx = -1; dx <= 1; dx++) {\n if (dx === 0 && dy === 0) continue;\n if (gridAt(g, x + dx, y + dy) === 1) n++;\n }\n }\n return n;\n}\n\n/**\n * Project a grid to collision geometry: 1 \u2192 SOLID, everything else \u2192 EMPTY.\n * The result is a logical, hash-relevant `TilemapData` \u2014 feed it straight to\n * the physics tilemap functions.\n */\nexport function gridToTilemap(g: Grid, tileSize = 32): TilemapData {\n const tiles = g.cells.map((c) => (c === 1 ? TILE.SOLID : TILE.EMPTY));\n return { cols: g.cols, rows: g.rows, tileSize, tiles };\n}\n", "// Coordinate-hash scatter + value noise \u2014 the corpus's actual \"procgen texture\"\n// need (witchcat / cat-survivors do `((x-812347*y)*928371)%17===0`), done right.\n//\n// Every function here is STATELESS and deterministic: the value at a cell is a\n// pure hash of (x, y, seed), so no PRNG stream is threaded and the same world\n// coordinate always decorates the same way \u2014 across frames, reloads, and peers.\n// Output is COSMETIC by intent (decoration placement, dithering, texture): keep\n// it out of `world.hash()`. For logical structure use the carving generators\n// (cave/terrain/rooms), which run off `world.rng`.\n\n/** 32-bit integer hash of a 2D cell + seed. Well-mixed; avalanche on any bit. */\nexport function cellHash(x: number, y: number, seed = 0): number {\n let h = (seed ^ 0x9e3779b9) >>> 0;\n h = Math.imul(h ^ (x | 0), 0x85ebca6b) >>> 0;\n h = Math.imul(h ^ (y | 0), 0xc2b2ae35) >>> 0;\n h ^= h >>> 13;\n h = Math.imul(h, 0x27d4eb2f) >>> 0;\n h ^= h >>> 15;\n return h >>> 0;\n}\n\n/** Deterministic float in [0,1) for a cell \u2014 hash normalized. */\nexport function cellFloat(x: number, y: number, seed = 0): number {\n return cellHash(x, y, seed) / 4294967296;\n}\n\n/** Deterministic integer in [0,n) for a cell (e.g. pick a decoration variant). */\nexport function cellInt(x: number, y: number, n: number, seed = 0): number {\n return Math.floor(cellFloat(x, y, seed) * n);\n}\n\n/** True with ~`probability` at this cell \u2014 the stateless scatter test. */\nexport function scatter(x: number, y: number, probability: number, seed = 0): boolean {\n return cellFloat(x, y, seed) < probability;\n}\n\n/**\n * Enumerate the chosen cells in a rectangle, row-major (ordered). Handy for\n * placing decoration nodes over a visible region without a PRNG. Cosmetic.\n */\nexport function scatterCells(\n x0: number,\n y0: number,\n cols: number,\n rows: number,\n probability: number,\n seed = 0,\n): { x: number; y: number }[] {\n const out: { x: number; y: number }[] = [];\n for (let y = y0; y < y0 + rows; y++) {\n for (let x = x0; x < x0 + cols; x++) {\n if (scatter(x, y, probability, seed)) out.push({ x, y });\n }\n }\n return out;\n}\n\nconst smooth = (t: number): number => t * t * (3 - 2 * t);\n\n/**\n * Value noise in [0,1] at a fractional coordinate \u2014 smooth bilinear blend of the\n * four surrounding integer-cell hashes. This is the deliberately-small\n * alternative to a simplex lib (see JS13K-MINING anti-recommendations): enough\n * for cosmetic terrain tint, cloud cover, wobble; not a gameplay dependency.\n */\nexport function valueNoise(x: number, y: number, seed = 0): number {\n const x0 = Math.floor(x);\n const y0 = Math.floor(y);\n const fx = smooth(x - x0);\n const fy = smooth(y - y0);\n const c00 = cellFloat(x0, y0, seed);\n const c10 = cellFloat(x0 + 1, y0, seed);\n const c01 = cellFloat(x0, y0 + 1, seed);\n const c11 = cellFloat(x0 + 1, y0 + 1, seed);\n const top = c00 + (c10 - c00) * fx;\n const bot = c01 + (c11 - c01) * fx;\n return top + (bot - top) * fy;\n}\n\nexport interface FractalOptions {\n octaves?: number;\n /** Frequency multiplier per octave (default 2). */\n lacunarity?: number;\n /** Amplitude multiplier per octave (default 0.5). */\n gain?: number;\n}\n\n/** Fractal (fBm) value noise \u2014 layered octaves, normalized to [0,1]. Cosmetic. */\nexport function fractalNoise(x: number, y: number, seed = 0, opts: FractalOptions = {}): number {\n const octaves = opts.octaves ?? 4;\n const lacunarity = opts.lacunarity ?? 2;\n const gain = opts.gain ?? 0.5;\n let amp = 1;\n let freq = 1;\n let sum = 0;\n let norm = 0;\n for (let o = 0; o < octaves; o++) {\n sum += amp * valueNoise(x * freq, y * freq, seed + o);\n norm += amp;\n amp *= gain;\n freq *= lacunarity;\n }\n return norm === 0 ? 0 : sum / norm;\n}\n", "// Cave / cavern carving via cellular automata \u2014 space-huggers-style organic\n// caverns. This is LOGICAL structure (it becomes collision geometry), so it is\n// fully deterministic and hash-relevant: all randomness draws from the passed\n// `world.rng`, and every loop iterates row-major (ordered). The knight-dreams\n// anti-pattern (raw `Math.random`) is exactly what this avoids \u2014 pass a seeded\n// `Rng` and the same seed always carves the same cave.\n\nimport type { Rng } from '../core/rng';\nimport { makeGrid, gridSet, solidNeighbours, type Grid } from './grid';\n\nexport interface CaveOptions {\n cols: number;\n rows: number;\n /** Initial solid-fill probability (0..1). ~0.45 gives balanced caverns. */\n fill?: number;\n /** Smoothing passes (more = rounder, larger chambers). Default 4. */\n steps?: number;\n /** A cell becomes solid if it has \u2265 this many solid neighbours. Default 5. */\n birth?: number;\n /** A solid cell survives if it has \u2265 this many solid neighbours. Default 4. */\n survive?: number;\n /** Force the outer ring solid so the cave is sealed. Default true. */\n border?: boolean;\n}\n\n/**\n * Generate a cave grid (1 = rock, 0 = open) with cellular automata. Deterministic\n * given `rng`'s state + options. Feed the result to `gridToTilemap` for physics.\n */\nexport function generateCave(rng: Rng, opts: CaveOptions): Grid {\n const { cols, rows } = opts;\n const fill = opts.fill ?? 0.45;\n const steps = opts.steps ?? 4;\n const birth = opts.birth ?? 5;\n const survive = opts.survive ?? 4;\n const border = opts.border ?? true;\n\n let g = makeGrid(cols, rows, 0);\n // Random seed fill \u2014 ordered draws from world.rng so replays match.\n for (let y = 0; y < rows; y++) {\n for (let x = 0; x < cols; x++) {\n const edge = border && (x === 0 || y === 0 || x === cols - 1 || y === rows - 1);\n gridSet(g, x, y, edge || rng.chance(fill) ? 1 : 0);\n }\n }\n\n // Smoothing passes into a fresh grid (double-buffer; no in-place bias).\n for (let s = 0; s < steps; s++) {\n const next = makeGrid(cols, rows, 0);\n for (let y = 0; y < rows; y++) {\n for (let x = 0; x < cols; x++) {\n if (border && (x === 0 || y === 0 || x === cols - 1 || y === rows - 1)) {\n gridSet(next, x, y, 1);\n continue;\n }\n const n = solidNeighbours(g, x, y);\n const wasSolid = g.cells[y * cols + x] === 1;\n gridSet(next, x, y, (wasSolid ? n >= survive : n >= birth) ? 1 : 0);\n }\n }\n g = next;\n }\n return g;\n}\n", "// Endless terrain surface \u2014 knight-dreams' infinite auto-runner terrain, done\n// deterministically. The ground height at a column is a PURE function of the\n// column index + seed (layered value noise), so it needs no PRNG stream and no\n// stored state: any column can be sampled in any order and an infinite world\n// stays perfectly reproducible across peers and reloads.\n//\n// This is LOGICAL structure (the surface is collision), so it belongs in the\n// hash \u2014 and because it is a stateless pure function of (col, seed), it is\n// deterministic by construction. Seed is explicit (derive it from `world.rng`\n// once at setup, e.g. `rng.int(1e9)`), never `Math.random`.\n\nimport { clamp } from '../core/math';\nimport { fractalNoise, type FractalOptions } from './scatter';\n\nexport interface TerrainOptions {\n /** Baseline ground row (tiles from the top). */\n base: number;\n /** Peak deviation above/below the baseline (tiles). */\n amplitude: number;\n /** Horizontal frequency \u2014 smaller = longer, smoother hills. Default 0.08. */\n scale?: number;\n /** Clamp ground into [minRow, maxRow] so it stays on-screen. */\n minRow?: number;\n maxRow?: number;\n seed?: number;\n fractal?: FractalOptions;\n}\n\n/**\n * Ground row (integer tile Y) for a column. Lower row = higher ground. Sampling\n * the same (col, opts) always returns the same height \u2014 the endless-terrain\n * contract.\n */\nexport function terrainHeight(col: number, opts: TerrainOptions): number {\n const scale = opts.scale ?? 0.08;\n const seed = opts.seed ?? 0;\n // valueNoise is [0,1]; center to [-1,1] so the surface undulates about `base`.\n const n = fractalNoise(col * scale, 0, seed, opts.fractal) * 2 - 1;\n let row = Math.round(opts.base + n * opts.amplitude);\n if (opts.minRow !== undefined || opts.maxRow !== undefined) {\n row = clamp(row, opts.minRow ?? -Infinity, opts.maxRow ?? Infinity);\n }\n return row;\n}\n\n/** Ground rows for a contiguous chunk `[startCol, startCol+count)` (ordered). */\nexport function terrainSlice(startCol: number, count: number, opts: TerrainOptions): number[] {\n const out = new Array<number>(count);\n for (let i = 0; i < count; i++) out[i] = terrainHeight(startCol + i, opts);\n return out;\n}\n\n/** True when a tile is solid ground (at or below the surface row) at (col,row). */\nexport function isGround(col: number, row: number, opts: TerrainOptions): boolean {\n return row >= terrainHeight(col, opts);\n}\n", "// Room / segment layout \u2014 space-huggers-style multi-floor bases. Places\n// non-overlapping rectangular rooms into a solid grid and links them with\n// L-shaped corridors, carving floor (0) out of rock (1). LOGICAL structure, so\n// it is hash-relevant: all randomness is drawn from the passed `world.rng` and\n// rooms connect in placement order (ordered iteration) \u2014 same seed, same base.\n\nimport type { Rng } from '../core/rng';\nimport { makeGrid, gridSet, type Grid } from './grid';\n\nexport interface Room {\n x: number;\n y: number;\n w: number;\n h: number;\n}\n\nexport interface DungeonOptions {\n cols: number;\n rows: number;\n /** How many placement attempts to make (actual rooms \u2264 this). Default 12. */\n attempts?: number;\n /** Room side length range (tiles), inclusive. */\n minSize?: number;\n maxSize?: number;\n /** Keep a 1-tile solid margin around the grid. Default true. */\n border?: boolean;\n}\n\nexport interface Dungeon {\n rooms: Room[];\n grid: Grid;\n}\n\n/** Center tile of a room (floored). */\nexport function roomCenter(r: Room): { x: number; y: number } {\n return { x: Math.floor(r.x + r.w / 2), y: Math.floor(r.y + r.h / 2) };\n}\n\nfunction overlaps(a: Room, b: Room): boolean {\n // 1-tile gap between rooms so walls never merge.\n return a.x <= b.x + b.w && a.x + a.w >= b.x && a.y <= b.y + b.h && a.y + a.h >= b.y;\n}\n\nfunction carveRoom(g: Grid, r: Room): void {\n for (let y = r.y; y < r.y + r.h; y++) {\n for (let x = r.x; x < r.x + r.w; x++) gridSet(g, x, y, 0);\n }\n}\n\nfunction carveHCorridor(g: Grid, x0: number, x1: number, y: number): void {\n for (let x = Math.min(x0, x1); x <= Math.max(x0, x1); x++) gridSet(g, x, y, 0);\n}\nfunction carveVCorridor(g: Grid, y0: number, y1: number, x: number): void {\n for (let y = Math.min(y0, y1); y <= Math.max(y0, y1); y++) gridSet(g, x, y, 0);\n}\n\n/**\n * Generate a room-and-corridor layout in a grid (1 = wall, 0 = floor).\n * Deterministic given `rng` state + options; consecutive rooms are joined so the\n * whole floor is connected. Feed `.grid` to `gridToTilemap` for physics.\n */\nexport function generateDungeon(rng: Rng, opts: DungeonOptions): Dungeon {\n const { cols, rows } = opts;\n const attempts = opts.attempts ?? 12;\n const minSize = opts.minSize ?? 4;\n const maxSize = opts.maxSize ?? 8;\n const margin = (opts.border ?? true) ? 1 : 0;\n\n const g = makeGrid(cols, rows, 1); // start solid, carve into it\n const rooms: Room[] = [];\n\n for (let i = 0; i < attempts; i++) {\n const w = rng.intRange(minSize, maxSize);\n const h = rng.intRange(minSize, maxSize);\n const x = rng.intRange(margin, cols - w - margin - 1);\n const y = rng.intRange(margin, rows - h - margin - 1);\n if (x < margin || y < margin) continue;\n const room: Room = { x, y, w, h };\n if (rooms.some((r) => overlaps(room, r))) continue;\n\n carveRoom(g, room);\n if (rooms.length > 0) {\n // Connect to the previous room with an L corridor; coin-flip the elbow.\n const prev = roomCenter(rooms[rooms.length - 1]);\n const cur = roomCenter(room);\n if (rng.chance(0.5)) {\n carveHCorridor(g, prev.x, cur.x, prev.y);\n carveVCorridor(g, prev.y, cur.y, cur.x);\n } else {\n carveVCorridor(g, prev.y, cur.y, prev.x);\n carveHCorridor(g, prev.x, cur.x, cur.y);\n }\n }\n rooms.push(room);\n }\n\n return { rooms, grid: g };\n}\n", "// Procedural audio bus. Code-as-sound: zzfx-style tone synthesis + an ambient\n// pad, no audio files. A no-op when there's no AudioContext (Node/headless), so\n// automated runs are silent by construction (a narrow-js invariant).\n\nexport interface Volumes {\n master: number;\n music: number;\n sfx: number;\n muted: boolean;\n}\n\nconst DEFAULT_VOLUMES: Volumes = { master: 0.7, music: 0.6, sfx: 0.8, muted: false };\n\n/** A single zzfx-ish tone spec. */\nexport interface Tone {\n freq: number;\n duration: number;\n type?: OscillatorType;\n gain?: number;\n delay?: number;\n /** Stereo position -1 (left) \u2026 1 (right) \u2014 the spatial-audio hook. */\n pan?: number;\n}\n\nexport class AudioBus {\n private ctx: AudioContext | null = null;\n private master: GainNode | null = null;\n private musicGain: GainNode | null = null;\n private sfxGain: GainNode | null = null;\n private vol: Volumes = { ...DEFAULT_VOLUMES };\n private padOn = false;\n\n get available(): boolean {\n return typeof globalThis.AudioContext !== 'undefined' || 'webkitAudioContext' in globalThis;\n }\n get started(): boolean {\n return !!this.ctx;\n }\n\n /** Must be called from a user gesture (browser autoplay policy). */\n start(): void {\n if (this.ctx) {\n void this.ctx.resume();\n return;\n }\n if (!this.available) return;\n const Ctx =\n globalThis.AudioContext ||\n (globalThis as unknown as { webkitAudioContext: typeof AudioContext }).webkitAudioContext;\n this.ctx = new Ctx();\n this.master = this.ctx.createGain();\n this.musicGain = this.ctx.createGain();\n this.sfxGain = this.ctx.createGain();\n this.musicGain.connect(this.master);\n this.sfxGain.connect(this.master);\n this.master.connect(this.ctx.destination);\n this.applyVolumes();\n }\n\n setVolumes(v: Partial<Volumes>): void {\n this.vol = { ...this.vol, ...v };\n this.applyVolumes();\n }\n getVolumes(): Volumes {\n return { ...this.vol };\n }\n\n private applyVolumes(): void {\n if (!this.ctx || !this.master || !this.musicGain || !this.sfxGain) return;\n const t = this.ctx.currentTime;\n this.master.gain.setTargetAtTime(this.vol.muted ? 0 : this.vol.master, t, 0.04);\n this.musicGain.gain.setTargetAtTime(this.vol.music * 0.5, t, 0.04);\n this.sfxGain.gain.setTargetAtTime(this.vol.sfx, t, 0.04);\n }\n\n /** Play a single tone (no-op if audio unstarted). */\n tone(spec: Tone): void {\n if (!this.ctx || !this.sfxGain) return;\n const { freq, duration, type = 'sine', gain = 0.2, delay = 0, pan } = spec;\n const t = this.ctx.currentTime + delay;\n const osc = this.ctx.createOscillator();\n osc.type = type;\n osc.frequency.value = freq;\n const g = this.ctx.createGain();\n g.gain.setValueAtTime(0, t);\n g.gain.linearRampToValueAtTime(gain, t + 0.008);\n g.gain.exponentialRampToValueAtTime(0.0001, t + duration);\n osc.connect(g);\n if (pan !== undefined && typeof this.ctx.createStereoPanner === 'function') {\n const p = this.ctx.createStereoPanner();\n p.pan.value = Math.max(-1, Math.min(1, pan));\n g.connect(p);\n p.connect(this.sfxGain);\n } else {\n g.connect(this.sfxGain);\n }\n osc.start(t);\n osc.stop(t + duration + 0.05);\n }\n\n /**\n * A positional cue: gain falls with distance, pan follows the horizontal\n * offset. dx/dist in design-space px; hearing range sets the falloff.\n */\n spatial(freq: number, dx: number, dist: number, hearing = 600, duration = 0.18, type: OscillatorType = 'sawtooth'): void {\n if (dist > hearing) return;\n const near = 1 - dist / hearing;\n this.tone({ freq, duration, type, gain: 0.04 + near * near * 0.3, pan: Math.max(-1, Math.min(1, dx / (hearing * 0.6))) });\n }\n\n /** Play a sequence of tones as an arpeggio/chord. */\n play(tones: Tone[]): void {\n for (const t of tones) this.tone(t);\n }\n\n /** Convenience SFX. */\n blip(freq = 520): void {\n this.tone({ freq, duration: 0.06, type: 'sine', gain: 0.18 });\n }\n chime(): void {\n [523.25, 659.25, 783.99].forEach((f, i) => this.tone({ freq: f, duration: 0.9 - i * 0.15, type: 'sine', gain: 0.15, delay: i * 0.04 }));\n }\n success(): void {\n [392, 493.88, 587.33, 783.99].forEach((f, i) => this.tone({ freq: f, duration: 0.4, type: 'triangle', gain: 0.15, delay: i * 0.08 }));\n }\n thud(): void {\n this.tone({ freq: 130, duration: 0.14, type: 'sine', gain: 0.22 });\n }\n\n /** Start a soft evolving ambient pad on the music bus. */\n startAmbient(root = 110, voices = [1, 1.5, 2, 2.5]): void {\n if (!this.ctx || !this.musicGain || this.padOn) return;\n this.padOn = true;\n const filter = this.ctx.createBiquadFilter();\n filter.type = 'lowpass';\n filter.frequency.value = 900;\n filter.connect(this.musicGain);\n const bus = this.ctx.createGain();\n bus.gain.value = 0;\n bus.connect(filter);\n for (const mult of voices) {\n const osc = this.ctx.createOscillator();\n osc.type = 'triangle';\n osc.frequency.value = root * mult;\n const g = this.ctx.createGain();\n g.gain.value = 0.1 / voices.length;\n osc.connect(g);\n g.connect(bus);\n osc.start();\n }\n bus.gain.setTargetAtTime(0.9, this.ctx.currentTime, 3);\n }\n}\n\n/** Shared default bus. */\nexport const audio = new AudioBus();\n", "// DOM overlay screens \u2014 titles, menus, game-over, HUD. Crisp DOM type instead of\n// canvas text (narrow-js lesson: humans compare canvas text to DOM and canvas\n// loses). Keyboard-navigable by construction. Browser-only; no-op guards for SSR.\n\nexport interface MenuAction {\n label: string;\n onSelect: () => void;\n primary?: boolean;\n}\n\nexport interface ScreenSpec {\n title?: string;\n /** Subtitle / body text (plain text or HTML string). */\n body?: string;\n /** Menu actions, navigable with up/down + Enter. */\n actions?: MenuAction[];\n /** Dim the game behind the screen. */\n dim?: boolean;\n /** Extra class for theming. */\n className?: string;\n}\n\nexport interface ScreenHandle {\n close(): void;\n readonly element: HTMLElement;\n}\n\nlet active: ScreenHandle | null = null;\n\nconst STYLE_ID = 'hayao-overlay-style';\nconst CSS = `\n.hy-scrim{position:absolute;inset:0;display:grid;place-items:center;z-index:50;font-family:var(--hy-serif,Georgia,serif)}\n.hy-scrim.dim{background:rgba(30,24,14,.5);backdrop-filter:blur(2px)}\n.hy-card{background:var(--hy-paper,#fbf6ea);color:var(--hy-ink,#3d3323);border:1px solid var(--hy-line,#d9ccae);border-radius:14px;box-shadow:0 14px 44px rgba(40,30,15,.3);padding:26px 30px;max-width:440px;text-align:center}\n.hy-card h1{margin:0 0 6px;font-size:30px}\n.hy-card .hy-body{color:var(--hy-ink-soft,#6f6047);font-size:15px;line-height:1.5;margin-bottom:18px}\n.hy-menu{display:flex;flex-direction:column;gap:8px;align-items:stretch}\n.hy-item{font:inherit;font-size:16px;padding:9px 16px;border-radius:9px;border:1px solid var(--hy-line,#d9ccae);background:transparent;color:inherit;cursor:pointer;transition:transform .1s,background .1s}\n.hy-item:hover,.hy-item.sel{background:var(--hy-accent,#a11d3a);color:#fdf3ee;border-color:transparent;transform:translateY(-1px)}\n.hy-item.primary{background:var(--hy-accent,#a11d3a);color:#fdf3ee;border-color:transparent}\n`;\n\nfunction ensureStyle(): void {\n if (typeof document === 'undefined' || document.getElementById(STYLE_ID)) return;\n const s = document.createElement('style');\n s.id = STYLE_ID;\n s.textContent = CSS;\n document.head.appendChild(s);\n}\n\nlet host: HTMLElement | null = null;\n/** Set the element overlays mount into (defaults to document.body). */\nexport function setOverlayHost(el: HTMLElement): void {\n host = el;\n}\n\n/** Show a screen (replaces any current one). Returns a handle. */\nexport function showScreen(spec: ScreenSpec): ScreenHandle {\n if (typeof document === 'undefined') {\n return { close() {}, element: null as unknown as HTMLElement };\n }\n ensureStyle();\n hideScreen();\n\n const scrim = document.createElement('div');\n scrim.className = `hy-scrim${spec.dim === false ? '' : ' dim'}${spec.className ? ' ' + spec.className : ''}`;\n const card = document.createElement('div');\n card.className = 'hy-card';\n\n if (spec.title) {\n const h = document.createElement('h1');\n h.textContent = spec.title;\n card.appendChild(h);\n }\n if (spec.body) {\n const b = document.createElement('div');\n b.className = 'hy-body';\n b.innerHTML = spec.body;\n card.appendChild(b);\n }\n\n const actions = spec.actions ?? [];\n let sel = Math.max(0, actions.findIndex((a) => a.primary));\n if (sel < 0) sel = 0;\n const items: HTMLButtonElement[] = [];\n if (actions.length) {\n const menu = document.createElement('div');\n menu.className = 'hy-menu';\n actions.forEach((a, i) => {\n const btn = document.createElement('button');\n btn.className = `hy-item${a.primary ? ' primary' : ''}`;\n btn.textContent = a.label;\n btn.addEventListener('click', () => a.onSelect());\n btn.addEventListener('mouseenter', () => setSel(i));\n menu.appendChild(btn);\n items.push(btn);\n });\n card.appendChild(menu);\n }\n\n function setSel(i: number): void {\n sel = (i + items.length) % items.length;\n items.forEach((el, k) => el.classList.toggle('sel', k === sel));\n }\n if (items.length) setSel(sel);\n\n const onKey = (e: KeyboardEvent) => {\n if (!items.length) return;\n if (e.code === 'ArrowDown') { setSel(sel + 1); e.preventDefault(); }\n else if (e.code === 'ArrowUp') { setSel(sel - 1); e.preventDefault(); }\n else if (e.code === 'Enter' || e.code === 'Space') { actions[sel]?.onSelect(); e.preventDefault(); }\n };\n document.addEventListener('keydown', onKey);\n\n scrim.appendChild(card);\n (host ?? document.body).appendChild(scrim);\n\n const handle: ScreenHandle = {\n element: scrim,\n close() {\n document.removeEventListener('keydown', onKey);\n scrim.remove();\n if (active === handle) active = null;\n },\n };\n active = handle;\n return handle;\n}\n\nexport function hideScreen(): void {\n active?.close();\n}\n", "// Player settings, persisted to localStorage and pushed into the audio bus.\n// Framework-agnostic (plain object + subscribe), so any game/UI can bind to it.\n\nimport { audio } from '../audio/audio';\n\nexport interface Settings {\n master: number;\n music: number;\n sfx: number;\n muted: boolean;\n colorblind: boolean;\n reducedMotion: boolean;\n}\n\nconst KEY = 'hayao.settings.v1';\nconst DEFAULTS: Settings = { master: 0.7, music: 0.6, sfx: 0.8, muted: false, colorblind: false, reducedMotion: false };\n\ntype Sub = (s: Settings) => void;\n\nclass SettingsStore {\n private state: Settings;\n private subs = new Set<Sub>();\n\n constructor() {\n this.state = this.load();\n this.pushToAudio();\n }\n\n get(): Settings {\n return { ...this.state };\n }\n\n set(patch: Partial<Settings>): void {\n this.state = { ...this.state, ...patch };\n this.save();\n this.pushToAudio();\n for (const fn of this.subs) fn(this.get());\n }\n\n subscribe(fn: Sub): () => void {\n this.subs.add(fn);\n return () => this.subs.delete(fn);\n }\n\n private pushToAudio(): void {\n audio.setVolumes({ master: this.state.master, music: this.state.music, sfx: this.state.sfx, muted: this.state.muted });\n }\n\n private load(): Settings {\n try {\n const raw = typeof localStorage !== 'undefined' && localStorage.getItem(KEY);\n if (raw) return { ...DEFAULTS, ...JSON.parse(raw) };\n } catch {\n /* ignore */\n }\n return { ...DEFAULTS };\n }\n private save(): void {\n try {\n localStorage.setItem(KEY, JSON.stringify(this.state));\n } catch {\n /* ignore */\n }\n }\n}\n\nexport const settings = new SettingsStore();\n\n// \u2500\u2500 Fullscreen helper \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport function toggleFullscreen(): void {\n if (typeof document === 'undefined') return;\n const doc = document as Document & { webkitFullscreenElement?: Element; webkitExitFullscreen?: () => void };\n const el = document.documentElement as HTMLElement & { webkitRequestFullscreen?: () => void };\n if (document.fullscreenElement || doc.webkitFullscreenElement) {\n (document.exitFullscreen ?? doc.webkitExitFullscreen)?.call(document);\n } else {\n (el.requestFullscreen ?? el.webkitRequestFullscreen)?.call(el);\n }\n}\n", "// The game shell: a pause menu (Esc) with volume, mute, fullscreen, restart, and\n// back-to-hub \u2014 every game gets it for free (narrow-js lesson: the shell owns Esc,\n// kills debug-key landmines, and standardizes chrome). Browser-only.\n\nimport { audio } from '../audio/audio';\nimport { settings, toggleFullscreen } from './settings';\nimport { showScreen, hideScreen } from './overlay';\n\nexport interface ShellOptions {\n onRestart?: () => void;\n onQuit?: () => void;\n /** Called with true when paused, false when resumed. */\n onPause?: (paused: boolean) => void;\n title?: string;\n}\n\nexport class Shell {\n private paused = false;\n private opts: ShellOptions;\n private keyHandler: (e: KeyboardEvent) => void;\n\n constructor(opts: ShellOptions = {}) {\n this.opts = opts;\n this.keyHandler = (e: KeyboardEvent) => {\n if (e.code === 'Escape') {\n e.preventDefault();\n this.toggle();\n }\n };\n if (typeof document !== 'undefined') document.addEventListener('keydown', this.keyHandler);\n }\n\n get isPaused(): boolean {\n return this.paused;\n }\n\n toggle(): void {\n this.paused ? this.resume() : this.pause();\n }\n\n pause(): void {\n if (this.paused) return;\n this.paused = true;\n audio.blip(440);\n this.opts.onPause?.(true);\n this.render();\n }\n\n resume(): void {\n if (!this.paused) return;\n this.paused = false;\n hideScreen();\n this.opts.onPause?.(false);\n }\n\n private render(): void {\n const s = settings.get();\n const vol = (label: string, v: number) => `${label}: ${Math.round(v * 100)}`;\n showScreen({\n title: this.opts.title ?? 'Paused',\n body:\n `<div style=\"font-size:13px;text-align:left;line-height:1.9\">` +\n `${vol('Master', s.master)} \u00B7 ${vol('Music', s.music)} \u00B7 ${vol('Sfx', s.sfx)}` +\n `<br/><span style=\"opacity:.7\">Use the menu, or keys: M mute \u00B7 F fullscreen</span></div>`,\n actions: [\n { label: 'Resume', primary: true, onSelect: () => this.resume() },\n { label: s.muted ? 'Unmute (M)' : 'Mute (M)', onSelect: () => { settings.set({ muted: !settings.get().muted }); this.render(); } },\n { label: 'Music \u2212/+', onSelect: () => { const m = Math.min(1, settings.get().music + 0.1) % 1.05; settings.set({ music: m > 1 ? 0 : m }); this.render(); } },\n { label: 'Fullscreen (F)', onSelect: () => toggleFullscreen() },\n ...(this.opts.onRestart ? [{ label: 'Restart', onSelect: () => { this.resume(); this.opts.onRestart!(); } }] : []),\n ...(this.opts.onQuit ? [{ label: 'Quit', onSelect: () => { this.resume(); this.opts.onQuit!(); } }] : []),\n ],\n });\n }\n\n dispose(): void {\n if (typeof document !== 'undefined') document.removeEventListener('keydown', this.keyHandler);\n hideScreen();\n }\n}\n", "// Screen transitions + a cinematic sequencer \u2014 the layer between showScreen()\n// (a static DOM dialog) and a scripted, animated scene change.\n//\n// Transition is a COSMETIC scene node that paints a full-screen wipe (fade /\n// iris / dither) in SCREEN space, so it sits on top of the camera untouched. It\n// runs on the fixed clock dt \u2014 not rAF delta \u2014 so a lockstep replay wipes\n// identically, and because it draws through the display list it renders headless\n// (a filmstrip can prove it). The classic move is cover \u2192 onMidpoint (swap the\n// level) \u2192 reveal, all gated off `busy`.\n//\n// CinematicPlayer walks a list of pure-data steps: each step runs an `enter`\n// hook (aim the camera, set text, mutate state) then holds until its duration\n// elapses AND its `until` gate passes \u2014 which is how you fade-gate advancement\n// (step waits on `!transition.busy`). Also cosmetic and dt-driven.\n\nimport { clamp, lerp, type Rect, type Transform, IDENTITY } from '../core/math';\nimport type { DrawCommand } from '../render/commands';\nimport { Node, type NodeConfig } from '../scene/node';\n\nexport type WipeKind = 'fade' | 'circle' | 'dither';\n\n// Ordered 4\u00D74 Bayer matrix (thresholds 0..15) for the dither dissolve.\nconst BAYER4 = [0, 8, 2, 10, 12, 4, 14, 6, 3, 11, 1, 9, 15, 7, 13, 5];\nconst smoothstep = (t: number): number => t * t * (3 - 2 * t);\n\ninterface Ramp {\n from: number | undefined; // resolved to current coverage when the ramp starts\n to: number;\n dur: number;\n elapsed: number;\n onEnd?: () => void;\n}\n\nexport interface WipeOptions {\n /** Seconds to cover the screen (default 0.4). */\n cover?: number;\n /** Seconds to hold fully covered before revealing (default 0). */\n hold?: number;\n /** Seconds to reveal the scene again (default = cover). */\n reveal?: number;\n /** Fired at full cover \u2014 swap the level/scene here. */\n onMidpoint?: () => void;\n /** Fired once the reveal finishes. */\n onDone?: () => void;\n}\n\nexport interface TransitionConfig extends NodeConfig {\n kind?: WipeKind;\n /** Overlay colour. */\n color?: string;\n /** Screen size in px (pass world.width / world.height). */\n width?: number;\n height?: number;\n /** Dither cell size in px (default 28). */\n cell?: number;\n}\n\n/**\n * A full-screen wipe overlay. Add it to the tree (cosmetic), then drive it with\n * `cover()` / `reveal()` / `wipe()`. `coverage` runs 0 (clear) \u2192 1 (opaque).\n */\nexport class ScreenTransition extends Node {\n override readonly type: string = 'ScreenTransition';\n kind: WipeKind;\n color: string;\n screenW: number;\n screenH: number;\n cell: number;\n /** 0 = fully clear, 1 = fully covering. */\n coverage = 0;\n private queue: Ramp[] = [];\n\n constructor(config: TransitionConfig = {}) {\n super(config);\n this.cosmetic = true;\n this.kind = config.kind ?? 'fade';\n this.color = config.color ?? '#1a1410';\n this.screenW = config.width ?? 1280;\n this.screenH = config.height ?? 720;\n this.cell = config.cell ?? 28;\n }\n\n /** True while a wipe is animating. */\n get busy(): boolean {\n return this.queue.length > 0;\n }\n\n private enqueue(to: number, dur: number, onEnd?: () => void): void {\n this.queue.push({ from: undefined, to, dur: Math.max(1e-4, dur), elapsed: 0, onEnd });\n }\n\n /** Animate the overlay to fully covering over `dur` seconds. */\n cover(dur = 0.4, onEnd?: () => void): this {\n this.enqueue(1, dur, onEnd);\n return this;\n }\n\n /** Animate the overlay back to fully clear over `dur` seconds. */\n reveal(dur = 0.4, onEnd?: () => void): this {\n this.enqueue(0, dur, onEnd);\n return this;\n }\n\n /** Hold the current coverage for `dur` seconds (chains after cover/reveal). */\n hold(dur: number, onEnd?: () => void): this {\n // Target the pending end-state so a mid-queue hold keeps that coverage.\n const target = this.queue.length ? this.queue[this.queue.length - 1].to : this.coverage;\n this.enqueue(target, dur, onEnd);\n return this;\n }\n\n /** The classic cover \u2192 onMidpoint \u2192 reveal sequence. Returns this for chaining. */\n wipe(opts: WipeOptions = {}): this {\n const cover = opts.cover ?? 0.4;\n this.cover(cover, () => {\n this.emit('covered', undefined);\n opts.onMidpoint?.();\n });\n if (opts.hold) this.hold(opts.hold);\n this.reveal(opts.reveal ?? cover, () => {\n this.emit('done', undefined);\n opts.onDone?.();\n });\n return this;\n }\n\n /** Signal emitted at full cover (the midpoint). */\n get covered() {\n return this.signal('covered');\n }\n /** Signal emitted when a wipe fully finishes revealing. */\n get done() {\n return this.signal('done');\n }\n\n protected override onProcess(dt: number): void {\n const step = this.queue[0];\n if (!step) return;\n if (step.from === undefined) step.from = this.coverage;\n step.elapsed += dt;\n const t = clamp(step.elapsed / step.dur, 0, 1);\n this.coverage = lerp(step.from, step.to, smoothstep(t));\n if (t >= 1) {\n this.coverage = step.to;\n const end = step.onEnd;\n this.queue.shift();\n end?.();\n }\n }\n\n protected override draw(out: DrawCommand[], _world: Transform): void {\n const c = this.coverage;\n if (c <= 0) return;\n // Screen space: ignore the camera transform so the wipe stays fixed.\n const z = this.z;\n if (this.kind === 'fade') {\n out.push({ kind: 'rect', x: 0, y: 0, w: this.screenW, h: this.screenH, fill: this.color, opacity: c, transform: IDENTITY, z });\n return;\n }\n if (this.kind === 'circle') {\n // Iris: a filled disc grown from the centre to the far corner.\n const cx = this.screenW / 2;\n const cy = this.screenH / 2;\n const diag = Math.sqrt(cx * cx + cy * cy);\n out.push({ kind: 'circle', cx, cy, radius: c * diag, fill: this.color, transform: IDENTITY, z });\n return;\n }\n // Dither: an ordered dissolve \u2014 one opaque cell per Bayer threshold below c.\n const cols = Math.ceil(this.screenW / this.cell);\n const rows = Math.ceil(this.screenH / this.cell);\n for (let cy = 0; cy < rows; cy++) {\n for (let cx = 0; cx < cols; cx++) {\n const threshold = (BAYER4[(cx & 3) + ((cy & 3) << 2)] + 0.5) / 16;\n if (threshold < c) {\n out.push({ kind: 'rect', x: cx * this.cell, y: cy * this.cell, w: this.cell, h: this.cell, fill: this.color, transform: IDENTITY, z });\n }\n }\n }\n }\n}\n\n// \u2500\u2500 Cinematic sequencer \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport interface CinematicStep {\n /** Optional label (handy for debugging/skip logic). */\n name?: string;\n /** Runs once when the step begins \u2014 aim the camera, set text, mutate state. */\n enter?: () => void;\n /** Minimum seconds to hold on this step before advancing (default 0). */\n duration?: number;\n /** Gate: advance only once this returns true (e.g. `() => !transition.busy`). */\n until?: () => boolean;\n}\n\n/**\n * Runs a list of pure-data cinematic steps on the fixed clock. Each step's\n * `enter` fires once, then the player waits for both its `duration` and its\n * `until` gate before moving on \u2014 the fade-gate pattern for scripted intros.\n * Cosmetic: it only orchestrates view/state changes, holds no hashed state.\n */\nexport class CinematicPlayer extends Node {\n override readonly type: string = 'CinematicPlayer';\n private steps: CinematicStep[] = [];\n private index = -1;\n private elapsed = 0;\n private running = false;\n private onFinish?: () => void;\n\n constructor(config: NodeConfig = {}) {\n super(config);\n this.cosmetic = true;\n }\n\n /** Load and start a sequence. `onDone` fires after the last step advances. */\n play(steps: CinematicStep[], onDone?: () => void): this {\n this.steps = steps;\n this.onFinish = onDone;\n this.index = -1;\n this.elapsed = 0;\n this.running = steps.length > 0;\n this.advance();\n return this;\n }\n\n /** True while a sequence is playing. */\n get active(): boolean {\n return this.running;\n }\n /** Index of the step currently on screen (\u22121 before play / after finish). */\n get step(): number {\n return this.index;\n }\n\n /** Signal emitted when the whole sequence finishes. */\n get finished() {\n return this.signal('finished');\n }\n\n private advance(): void {\n this.index++;\n this.elapsed = 0;\n if (this.index >= this.steps.length) {\n this.running = false;\n this.index = -1;\n this.emit('finished', undefined);\n this.onFinish?.();\n return;\n }\n this.steps[this.index].enter?.();\n }\n\n /** Abort the sequence immediately (no further enters, no finish callback). */\n stop(): void {\n this.running = false;\n this.index = -1;\n this.steps = [];\n }\n\n protected override onProcess(dt: number): void {\n if (!this.running) return;\n this.elapsed += dt;\n const s = this.steps[this.index];\n const durationDone = this.elapsed >= (s.duration ?? 0);\n const gateOpen = s.until ? s.until() : true;\n if (durationDone && gateOpen) this.advance();\n }\n}\n\n/**\n * Convenience: make a Transition sized to a world and add it to a parent (the\n * scene root by default, so it paints over everything). Returns the node.\n */\nexport function addTransition(parent: Node, config: TransitionConfig = {}): ScreenTransition {\n const t = new ScreenTransition({ z: 10_000, ...config });\n return parent.addChild(t);\n}\n\n/** A cinematic step that fires a wipe and gates advancement on its completion. */\nexport function wipeStep(transition: ScreenTransition, opts: WipeOptions & { name?: string } = {}): CinematicStep {\n return {\n name: opts.name ?? 'wipe',\n enter: () => transition.wipe(opts),\n until: () => !transition.busy,\n };\n}\n\n/** Screen rect helper for wiring a Transition into other 9-slice/UI code. */\nexport const screenRect = (w: number, h: number): Rect => ({ x: 0, y: 0, w, h });\n", "// Generic winnability solver. Turn-based/puzzle logic implements the pure\n// Puzzle interface; the solver proves a level beatable by search. Deterministic\n// opponent (fixed order + tie-breaks) means single-agent BFS \u2014 no adversarial\n// branching. (narrow-js's insight, generalized and typed.)\n//\n// Rule of the house: a hand-authored level is presumed WRONG until the solver\n// proves it winnable. In-head verification has a documented failure rate.\n\nexport interface Puzzle<State, Move> {\n /** Starting state (optionally per level index). */\n initial(level?: number): State;\n /** Legal moves from a state, in deterministic order. */\n moves(state: State): Move[];\n /** Apply a player move (may fold in a deterministic opponent response). */\n apply(state: State, move: Move): State;\n /** Win test. */\n isWin(state: State): boolean;\n /** Optional dead/lost test \u2014 pruned from the search. */\n isDead?(state: State): boolean;\n /** Canonical key for de-duplication (visited set). */\n key(state: State): string;\n}\n\nexport interface SolveResult<Move> {\n solvable: boolean;\n /** Shortest winning move sequence, if found. */\n path?: Move[];\n /** Depth of the shortest solution. */\n depth?: number;\n /** Nodes expanded (a difficulty/complexity proxy). */\n nodes: number;\n /** True if the search hit a cap before proving/\u200Bdisproving. */\n exhausted: boolean;\n}\n\nexport interface SolveOptions {\n level?: number;\n maxDepth?: number;\n nodeCap?: number;\n}\n\n/** Breadth-first search \u2192 the shortest solution and a real winnability proof. */\nexport function solve<State, Move>(\n puzzle: Puzzle<State, Move>,\n options: SolveOptions = {},\n): SolveResult<Move> {\n const maxDepth = options.maxDepth ?? 60;\n const nodeCap = options.nodeCap ?? 1_000_000;\n const start = puzzle.initial(options.level);\n\n if (puzzle.isWin(start)) return { solvable: true, path: [], depth: 0, nodes: 0, exhausted: false };\n\n interface QNode {\n state: State;\n path: Move[];\n }\n let frontier: QNode[] = [{ state: start, path: [] }];\n const seen = new Set<string>([puzzle.key(start)]);\n let nodes = 0;\n\n for (let depth = 0; depth < maxDepth && frontier.length > 0; depth++) {\n const next: QNode[] = [];\n for (const { state, path } of frontier) {\n for (const move of puzzle.moves(state)) {\n if (nodes >= nodeCap) return { solvable: false, nodes, exhausted: true };\n nodes++;\n const after = puzzle.apply(state, move);\n if (puzzle.isDead?.(after)) continue;\n if (puzzle.isWin(after)) {\n return { solvable: true, path: [...path, move], depth: depth + 1, nodes, exhausted: false };\n }\n const k = puzzle.key(after);\n if (!seen.has(k)) {\n seen.add(k);\n next.push({ state: after, path: [...path, move] });\n }\n }\n }\n frontier = next;\n }\n return { solvable: false, nodes, exhausted: frontier.length > 0 };\n}\n\n/**\n * Assert a puzzle level is winnable (throws with detail if not). Use in tests as\n * the content-balance gate.\n */\nexport function assertSolvable<State, Move>(\n puzzle: Puzzle<State, Move>,\n options: SolveOptions = {},\n): SolveResult<Move> {\n const result = solve(puzzle, options);\n if (!result.solvable) {\n throw new Error(\n `hayao: level ${options.level ?? 0} is NOT winnable ` +\n `(expanded ${result.nodes} nodes${result.exhausted ? ', search capped \u2014 raise nodeCap/maxDepth' : ''}).`,\n );\n }\n return result;\n}\n", "// Determinism verification. Re-run the same seed + input log twice; if any step's\n// state hash diverges, some hidden nondeterminism (Math.random, Date.now, Set\n// iteration, unordered map) leaked in. This is the regression net that lets you\n// refactor the sim fearlessly.\n\nimport type { World } from '../world';\nimport type { InputLog } from '../input/actions';\nimport { frameActions } from '../input/actions';\n\nexport type WorldFactory = () => World;\n\n/** Run a world through an input log, returning the final hash and per-frame hashes. */\nexport function replay(makeWorld: WorldFactory, log: InputLog): { finalHash: string; hashes: string[] } {\n const world = makeWorld();\n const hashes: string[] = [];\n for (let i = 0; i < log.frames.length; i++) {\n world.step(frameActions(log, i));\n hashes.push(world.hash());\n }\n return { finalHash: world.hash(), hashes };\n}\n\nexport interface DeterminismReport {\n ok: boolean;\n frames: number;\n /** First frame index where the two runs diverged, or -1. */\n divergedAt: number;\n finalHash: string;\n}\n\n/** Run twice and compare every step's hash. */\nexport function checkDeterministic(makeWorld: WorldFactory, log: InputLog): DeterminismReport {\n const a = replay(makeWorld, log);\n const b = replay(makeWorld, log);\n let divergedAt = -1;\n for (let i = 0; i < a.hashes.length; i++) {\n if (a.hashes[i] !== b.hashes[i]) {\n divergedAt = i;\n break;\n }\n }\n return {\n ok: divergedAt === -1 && a.finalHash === b.finalHash,\n frames: log.frames.length,\n divergedAt,\n finalHash: a.finalHash,\n };\n}\n\n/** Assert determinism (throws with the divergence frame). */\nexport function assertDeterministic(makeWorld: WorldFactory, log: InputLog): DeterminismReport {\n const report = checkDeterministic(makeWorld, log);\n if (!report.ok) {\n throw new Error(\n `hayao: sim is NON-deterministic \u2014 runs diverged at frame ${report.divergedAt} ` +\n `of ${report.frames}. Check for Math.random/Date.now/Set-iteration/unordered-map in the sim.`,\n );\n }\n return report;\n}\n\n/**\n * Assert that restoring a snapshot reproduces the exact same continuation \u2014\n * i.e. save/load is lossless. Runs `warmup` steps, snapshots, runs `tail` more\n * on both the original and a restored copy, and compares final hashes.\n */\nexport function assertSnapshotStable(\n makeWorld: WorldFactory,\n log: InputLog,\n warmup: number,\n): { ok: boolean; hashA: string; hashB: string } {\n const original = makeWorld();\n for (let i = 0; i < warmup; i++) original.step(frameActions(log, i));\n const snap = original.snapshot();\n\n const restored = makeWorld();\n restored.restore(snap);\n\n for (let i = warmup; i < log.frames.length; i++) {\n original.step(frameActions(log, i));\n restored.step(frameActions(log, i));\n }\n const hashA = original.hash();\n const hashB = restored.hash();\n return { ok: hashA === hashB, hashA, hashB };\n}\n", "// Scripted playthroughs: drive a world headlessly with a sequence of held-input\n// segments and collect probe snapshots. This is Channel 1a \u2014 proving behavior on\n// game state, in Node, no browser. (Hold keys \u2265 a few frames: variable-height\n// jumps treat a 1-frame synthetic tap as a real short tap.)\n\nimport type { World } from '../world';\n\nexport interface Segment {\n /** Actions held down for this segment. */\n actions?: string[];\n /** Number of fixed steps to run. */\n frames: number;\n}\n\n/** Build a segment: hold `actions` for `frames` steps. */\nexport function hold(actions: string[], frames: number): Segment {\n return { actions, frames };\n}\n/** Build an idle segment (no input) for `frames` steps. */\nexport function wait(frames: number): Segment {\n return { actions: [], frames };\n}\n\nexport interface PlaythroughResult {\n totalFrames: number;\n finalHash: string;\n /** Probe snapshot after each segment. */\n probes: Record<string, unknown>[];\n}\n\n/** Run a scripted playthrough; returns a probe after each segment. */\nexport function scriptedPlaythrough(world: World, script: Segment[]): PlaythroughResult {\n const probes: Record<string, unknown>[] = [];\n let total = 0;\n for (const seg of script) {\n for (let i = 0; i < seg.frames; i++) world.step(seg.actions ?? []);\n total += seg.frames;\n probes.push(world.probe());\n }\n return { totalFrames: total, finalHash: world.hash(), probes };\n}\n\n/** Convenience: advance a world N frames with a fixed input set. */\nexport function pump(world: World, frames: number, actions: string[] = []): void {\n for (let i = 0; i < frames; i++) world.step(actions);\n}\n", "// Browser capture seam. Because the sim is headless-native \u2014 hayao owns the\n// clock and never touches document.hasFocus \u2014 this is ~30 lines, not the ~100 a\n// canvas engine needs. Exposes window.__hayao for scripted browser sessions and\n// aesthetic screenshots. Enable with ?capture=1.\n\nimport type { World } from '../world';\n\nexport interface CaptureTarget {\n readonly world: World;\n /** Advance one fixed step with the given actions and render. */\n stepOnce(actions?: string[]): void;\n /** Current frame as an SVG string (a vector screenshot). */\n renderSVG(): string;\n setPaused(paused: boolean): void;\n}\n\nexport interface HayaoCapture {\n pump(frames: number, actions?: string[]): Record<string, unknown>;\n probe(): Record<string, unknown>;\n hash(): string;\n shot(): string;\n save(path: string): Promise<boolean>;\n key(type: 'keydown' | 'keyup', code: string): void;\n readonly world: World;\n}\n\nexport function isCaptureMode(): boolean {\n return typeof location !== 'undefined' && new URLSearchParams(location.search).has('capture');\n}\n\n/** Install window.__hayao for scripted browser verification. */\nexport function installCapture(target: CaptureTarget): HayaoCapture {\n const api: HayaoCapture = {\n pump(frames, actions = []) {\n target.setPaused(true);\n for (let i = 0; i < frames; i++) target.stepOnce(actions);\n return target.world.probe();\n },\n probe: () => target.world.probe(),\n hash: () => target.world.hash(),\n shot: () => target.renderSVG(),\n async save(path) {\n const svg = target.renderSVG();\n try {\n const res = await fetch('/__shot', {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ path, svg }),\n });\n return res.ok;\n } catch {\n return false;\n }\n },\n key(type, code) {\n document.dispatchEvent(new KeyboardEvent(type, { code, bubbles: true }));\n },\n get world() {\n return target.world;\n },\n };\n (globalThis as unknown as { __hayao: HayaoCapture }).__hayao = api;\n return api;\n}\n", "// Declarative input scripts: the ergonomic way to author headless playthroughs\n// for real-time games, where hand-writing per-frame action arrays is hopeless.\n// A script is a list of segments; each holds actions for N frames, optionally\n// tapping others on its first frame.\n\nimport type { World } from '../world';\n\nexport interface ScriptSegment {\n /** Actions held down for every frame of this segment. */\n hold?: string[];\n /** Actions pressed only on the first frame of this segment (taps). */\n press?: string[];\n /** How many fixed steps this segment lasts (default 1). */\n frames?: number;\n}\n\nexport type InputScript = ScriptSegment[];\n\n/** Expand a script into per-frame action arrays (an InputLog's frames). */\nexport function scriptToFrames(script: InputScript): string[][] {\n const out: string[][] = [];\n for (const seg of script) {\n const n = seg.frames ?? 1;\n const hold = seg.hold ?? [];\n for (let i = 0; i < n; i++) out.push(i === 0 && seg.press ? [...hold, ...seg.press] : [...hold]);\n }\n return out;\n}\n\nexport interface DriveResult {\n frames: number;\n /** True if driving stopped early because `until` matched. */\n matched: boolean;\n}\n\n/**\n * Step a world through a script. Pass `until` to stop as soon as a probe\n * predicate holds (e.g. level solved) \u2014 the tail of the script is slack, so\n * playthrough scripts don't need frame-perfect lengths.\n */\nexport function drive(world: World, script: InputScript, until?: (probe: Record<string, unknown>) => boolean): DriveResult {\n let frames = 0;\n for (const f of scriptToFrames(script)) {\n if (until && until(world.probe())) return { frames, matched: true };\n world.step(f);\n frames++;\n }\n return { frames, matched: until ? until(world.probe()) : false };\n}\n", "// The plan-interpreter bot skeleton \u2014 promoted to the engine after three\n// example games (shard-ascent, sproutveil, gleamvale) each rebuilt the same\n// shape: a plan of semantic steps, executed reactively against the probe each\n// frame, emitting actions. Games supply the step executors (steering is\n// genre-specific); the engine supplies the lifecycle, retries, and telemetry.\n//\n// const bot = createPlanBot(plan, {\n// walk(step, probe, out, ctx) { \u2026steer\u2026; if (arrived) ctx.next(); },\n// });\n// while (!probe.won) world.step(bot(world.probe()));\n\nexport interface BotCtx {\n /** Frames spent in the current step. */\n frames: number;\n /** Free per-step scratch (cleared on step change). */\n mem: Record<string, unknown>;\n /** Advance to the next plan step. */\n next(): void;\n /** Restart the current step (retry) \u2014 clears frames + mem. */\n retry(): void;\n}\n\nexport type StepExec<Step, Probe> = (step: Step, probe: Probe, out: string[], ctx: BotCtx) => void;\n\nexport interface PlanBot<Probe> {\n (probe: Probe): string[];\n stepIndex(): number;\n done(): boolean;\n}\n\nexport function createPlanBot<Step extends { kind: string }, Probe>(plan: Step[], execs: Record<string, StepExec<Step, Probe>>): PlanBot<Probe> {\n let i = 0;\n let frames = 0;\n let mem: Record<string, unknown> = {};\n\n const fn = (probe: Probe): string[] => {\n const out: string[] = [];\n const step = plan[i];\n if (!step) return out;\n frames++;\n const ctx: BotCtx = {\n get frames() {\n return frames;\n },\n mem,\n next() {\n i++;\n frames = 0;\n mem = {};\n },\n retry() {\n frames = 0;\n mem = {};\n },\n };\n const exec = execs[step.kind];\n if (!exec) throw new Error(`plan bot: no executor for step kind \"${step.kind}\"`);\n exec(step, probe, out, ctx);\n return out;\n };\n const bot = fn as PlanBot<Probe>;\n bot.stepIndex = () => i;\n bot.done = () => i >= plan.length;\n return bot;\n}\n\n/** Shared steering helper: 4/8-way movement toward a point. */\nexport function steer2D(px: number, py: number, tx: number, ty: number, out: string[], dead = 8): void {\n if (px < tx - dead) out.push('right');\n else if (px > tx + dead) out.push('left');\n if (py < ty - dead) out.push('down');\n else if (py > ty + dead) out.push('up');\n}\n", "// Layout lints \u2014 verification for the HUMAN-contact layer. The first real\n// playtest of the 20-genre campaign found that every reported defect lived in\n// the one layer the sim proofs cannot see: text buried under sprites, labels\n// kissing shapes, controls nobody explains. But the display list is pure\n// data, so the basics of readability are assertable like everything else.\n//\n// Rules enforced here (see CONVENTIONS \"The human-contact layer\"):\n// 1. TEXT IS SACRED. A shape may fully contain a text's box (it's a panel)\n// or be fully disjoint from it. Partial overlap = collision. Shapes at\n// z \u2264 1 are exempt \u2014 that's the background lattice (tile grids, felt).\n// 2. FIRST CONTACT. Every action in the input map must be mentioned by some\n// on-screen text on the first frame (its key or its name) \u2014 a player who\n// reads the screen must be able to discover the controls.\n\nimport type { DrawCommand, TextCommand } from '../render/commands';\nimport type { InputMap } from '../input/actions';\nimport type { World } from '../world';\n\nexport interface TextBox {\n cmd: TextCommand;\n x: number;\n y: number;\n w: number;\n h: number;\n}\n\n/** Approximate a text command's on-screen box (serif \u2248 0.56em per char). */\nexport function textBox(cmd: TextCommand): TextBox {\n const w = cmd.text.length * cmd.size * 0.56;\n const h = cmd.size * 1.25;\n const cx = cmd.transform.e + cmd.x;\n const by = cmd.transform.f + cmd.y; // baseline\n const left = cmd.align === 'center' ? cx - w / 2 : cmd.align === 'right' ? cx - w : cx;\n return { cmd, x: left, y: by - cmd.size, w, h };\n}\n\n/** Conservative bounds of a non-text command (local shape + translation). */\nexport function shapeBox(cmd: DrawCommand): { x: number; y: number; w: number; h: number } | null {\n const ex = cmd.transform.e;\n const ey = cmd.transform.f;\n switch (cmd.kind) {\n case 'rect':\n return { x: ex + cmd.x, y: ey + cmd.y, w: cmd.w, h: cmd.h };\n case 'circle':\n return { x: ex + cmd.cx - cmd.radius, y: ey + cmd.cy - cmd.radius, w: cmd.radius * 2, h: cmd.radius * 2 };\n case 'poly': {\n let minX = Infinity;\n let minY = Infinity;\n let maxX = -Infinity;\n let maxY = -Infinity;\n for (let i = 0; i < cmd.points.length; i += 2) {\n minX = Math.min(minX, cmd.points[i]);\n maxX = Math.max(maxX, cmd.points[i]);\n minY = Math.min(minY, cmd.points[i + 1]);\n maxY = Math.max(maxY, cmd.points[i + 1]);\n }\n return { x: ex + minX, y: ey + minY, w: maxX - minX, h: maxY - minY };\n }\n default:\n return null; // paths are decorative fans/arcs \u2014 skip (conservative)\n }\n}\n\nconst overlaps = (a: { x: number; y: number; w: number; h: number }, b: { x: number; y: number; w: number; h: number }): boolean =>\n a.x < b.x + b.w && a.x + a.w > b.x && a.y < b.y + b.h && a.y + a.h > b.y;\n\nconst contains = (outer: { x: number; y: number; w: number; h: number }, inner: { x: number; y: number; w: number; h: number }, pad = 2): boolean =>\n outer.x - pad <= inner.x && outer.y - pad <= inner.y && outer.x + outer.w + pad >= inner.x + inner.w && outer.y + outer.h + pad >= inner.y + inner.h;\n\nexport interface LayoutOptions {\n /** Shapes at or below this z are background lattice (tiles/felt) and may sit under text. */\n backgroundZ?: number;\n /** Extra pixels of breathing room demanded around text (default 0 = touch is allowed, overlap is not). */\n margin?: number;\n}\n\n/**\n * Lint a display list for text readability. Returns human-readable issues\n * (empty = clean). Checks: text-vs-shape partial overlaps (rule 1) and\n * text-vs-text overlaps.\n */\nexport function layoutIssues(commands: DrawCommand[], opts: LayoutOptions = {}): string[] {\n const backgroundZ = opts.backgroundZ ?? 1;\n const margin = opts.margin ?? 0;\n const issues: string[] = [];\n const texts: TextBox[] = [];\n for (const c of commands) if (c.kind === 'text' && (c as TextCommand).text.trim().length) texts.push(textBox(c as TextCommand));\n\n for (const t of texts) {\n const r = { x: t.x - margin, y: t.y - margin, w: t.w + margin * 2, h: t.h + margin * 2 };\n // A backing panel (any shape that fully contains the text, below it in\n // paint order) occludes whatever sits underneath IT \u2014 collisions with\n // shapes the panel covers are forgiven. This is how HUD scrims work.\n let panelZ = -Infinity;\n for (const c of commands) {\n if (c.kind === 'text') continue;\n const b = shapeBox(c);\n if (b && contains(b, t) && (c.opacity === undefined || c.opacity >= 0.6)) panelZ = Math.max(panelZ, c.z ?? 0);\n }\n for (const c of commands) {\n if (c.kind === 'text') continue;\n if ((c.z ?? 0) <= backgroundZ) continue; // background lattice\n if ((c.z ?? 0) <= panelZ) continue; // hidden behind the text's panel\n if (c.opacity !== undefined && c.opacity < 0.25) continue; // ghosts\n const b = shapeBox(c);\n if (!b) continue;\n if (overlaps(r, b) && !contains(b, t)) {\n issues.push(`text \"${clip(t.cmd.text)}\" collides with a ${c.kind} (z${c.z}) at ~(${Math.round(b.x)},${Math.round(b.y)}) \u2014 back it with a panel, or stay clear`);\n }\n }\n }\n for (let i = 0; i < texts.length; i++)\n for (let j = i + 1; j < texts.length; j++)\n if (overlaps(texts[i], texts[j])) issues.push(`texts \"${clip(texts[i].cmd.text)}\" and \"${clip(texts[j].cmd.text)}\" overlap`);\n return dedupe(issues);\n}\n\nconst clip = (s: string): string => (s.length > 28 ? s.slice(0, 25) + '\u2026' : s);\nconst dedupe = (a: string[]): string[] => [...new Set(a)];\n\n/** Friendly names a hint text may use to reference a key code. */\nexport function keyMentions(code: string): string[] {\n if (code.startsWith('Digit')) return [code.slice(5)];\n if (code.startsWith('Key')) return [code.slice(3).toLowerCase()];\n if (code.startsWith('Arrow')) return ['arrow', '\u2190', '\u2192', '\u2191', '\u2193', code.slice(5).toLowerCase()];\n if (code.startsWith('Shift')) return ['shift'];\n if (code === 'Space') return ['space'];\n if (code === 'Enter') return ['enter'];\n if (code === 'Period') return ['.'];\n return [code.toLowerCase()];\n}\n\n/**\n * First-contact check: which actions does no on-screen text explain? An\n * action passes if any text mentions its name or one of its keys' friendly\n * names. 'restart' is exempt (universal convention).\n */\nexport function missingControlHints(world: World, inputMap: InputMap): string[] {\n const textBlob = world\n .render()\n .filter((c): c is TextCommand => c.kind === 'text')\n .map((c) => c.text.toLowerCase())\n .join(' \u00B7 ');\n const missing: string[] = [];\n const mentions = (n: string): boolean => {\n if (!n.length) return false;\n // Short tokens (single letters, digits) must appear as standalone words,\n // or \"f\" would be satisfied by the word \"fire\" losing the actual key.\n if (n.length <= 2 && /^[a-z0-9.]+$/.test(n)) return new RegExp(`(^|[^a-z0-9])${n.replace('.', '\\\\.')}($|[^a-z0-9])`).test(textBlob);\n return textBlob.includes(n);\n };\n for (const [action, keys] of Object.entries(inputMap)) {\n if (action === 'restart') continue;\n const names = [action.toLowerCase().replace(/-\\d+$/, ''), ...keys.flatMap(keyMentions)];\n if (!names.some(mentions)) missing.push(action);\n }\n return dedupe(missing);\n}\n", "// Feel probes (Channel 3): quality proxies computed from a per-frame probe\n// timeline. The harness cannot feel fun, but it can measure fun's precursors \u2014\n// time-to-first-meaningful-action, event cadence, difficulty ramp, input\n// decision density \u2014 and fail when a game drifts outside its tuned windows.\n// These are proxies, not proof: pair them with the filmstrip and a human-set\n// window per game (see docs/VERIFICATION.md \u00A7Channel 3).\n\nimport type { World } from '../world';\n\nexport type ProbeFrame = Record<string, unknown>;\n\n/**\n * Step a world through per-frame action arrays, probing after every step.\n * Returns frames.length + 1 probes: index 0 is the pre-step state, index i is\n * the state after frame i. (With the default 60Hz clock, index / 60 = sim\n * seconds.) For a segment-level timeline use scriptedPlaythrough instead.\n */\nexport function recordTimeline(world: World, frames: string[][]): ProbeFrame[] {\n const out: ProbeFrame[] = [world.probe()];\n for (const f of frames) {\n world.step(f);\n out.push(world.probe());\n }\n return out;\n}\n\n/** First timeline index where `pred` holds, or -1 if it never does. */\nexport function firstFrame(timeline: ProbeFrame[], pred: (p: ProbeFrame) => boolean): number {\n for (let i = 0; i < timeline.length; i++) if (pred(timeline[i])) return i;\n return -1;\n}\n\n/** The value of one probe key across the timeline. */\nexport function series(timeline: ProbeFrame[], key: string): unknown[] {\n return timeline.map((p) => p[key]);\n}\n\n/** Timeline indices where `key`'s value differs from the previous frame \u2014 an event cadence. */\nexport function changeFrames(timeline: ProbeFrame[], key: string): number[] {\n const out: number[] = [];\n for (let i = 1; i < timeline.length; i++) if (timeline[i][key] !== timeline[i - 1][key]) out.push(i);\n return out;\n}\n\n/** Monotonic within slack: 'up' means every value \u2265 previous \u2212 slack. */\nexport function isMonotonic(values: number[], dir: 'up' | 'down', slack = 0): boolean {\n for (let i = 1; i < values.length; i++) {\n if (dir === 'up' ? values[i] < values[i - 1] - slack : values[i] > values[i - 1] + slack) return false;\n }\n return true;\n}\n\n/**\n * Fraction of frames carrying at least one action \u2014 a crude engagement proxy.\n * Near 0 the player is waiting; near 1 they are mashing; a tuned game usually\n * lives somewhere in between (set the window per genre).\n */\nexport function inputDensity(frames: string[][]): number {\n if (frames.length === 0) return 0;\n return frames.filter((f) => f.length > 0).length / frames.length;\n}\n\n/** Largest gap (in frames) between consecutive events \u2014 dead-air detector. */\nexport function longestLull(eventFrames: number[], totalFrames: number): number {\n const pts = [0, ...eventFrames, totalFrames];\n let worst = 0;\n for (let i = 1; i < pts.length; i++) worst = Math.max(worst, pts[i] - pts[i - 1]);\n return worst;\n}\n", "// Filmstrip: sampled frames of a run composed into ONE SVG contact sheet, so\n// the \"judge looks from a headless screenshot\" step can see MOTION \u2014 pacing,\n// readability during play, layering under load \u2014 not a single posed frame.\n// Looks only, never correctness: state was already proven numerically.\n\nimport type { World } from '../world';\nimport { commandsToSVGInner } from '../render/svgString';\n\nexport interface FilmstripOptions {\n /** The game's view size (defineGame width/height). */\n width: number;\n height: number;\n background?: string;\n /** How many panels to sample across the run (default 12, min 2). */\n panels?: number;\n /** Panels per row (default 4). */\n cols?: number;\n /** Rendered width of one panel in px (default 320). */\n panelWidth?: number;\n}\n\n/**\n * Step `world` through per-frame actions, sampling evenly spaced panels\n * (always including the first and last frame), and return one standalone SVG.\n * Panel labels are frame numbers plus sim seconds at the 60Hz convention.\n */\nexport function renderFilmstrip(world: World, frames: string[][], opts: FilmstripOptions): string {\n const panels = Math.max(2, opts.panels ?? 12);\n const every = Math.max(1, Math.ceil(frames.length / (panels - 1)));\n const shots: { frame: number; inner: string }[] = [{ frame: 0, inner: commandsToSVGInner(world.render()) }];\n for (let i = 0; i < frames.length; i++) {\n world.step(frames[i]);\n if ((i + 1) % every === 0 || i === frames.length - 1) {\n shots.push({ frame: i + 1, inner: commandsToSVGInner(world.render()) });\n }\n }\n\n const cols = Math.max(1, opts.cols ?? 4);\n const pw = opts.panelWidth ?? 320;\n const ph = Math.round((pw * opts.height) / opts.width);\n const labelH = 18;\n const gap = 8;\n const cellW = pw + gap;\n const cellH = ph + labelH + gap;\n const rows = Math.ceil(shots.length / cols);\n const totalW = cols * cellW + gap;\n const totalH = rows * cellH + gap;\n const bg = opts.background ?? '#ffffff';\n\n const cells = shots\n .map((s, i) => {\n const x = gap + (i % cols) * cellW;\n const y = gap + Math.floor(i / cols) * cellH;\n return (\n `<g transform=\"translate(${x} ${y})\">` +\n `<svg width=\"${pw}\" height=\"${ph}\" viewBox=\"0 0 ${opts.width} ${opts.height}\">` +\n `<rect x=\"0\" y=\"0\" width=\"${opts.width}\" height=\"${opts.height}\" fill=\"${bg}\"/>` +\n s.inner +\n `</svg>` +\n `<rect x=\"0\" y=\"0\" width=\"${pw}\" height=\"${ph}\" fill=\"none\" stroke=\"#999\" stroke-width=\"1\"/>` +\n `<text x=\"${pw / 2}\" y=\"${ph + 13}\" font-size=\"11\" font-family=\"monospace\" text-anchor=\"middle\" fill=\"#555\">` +\n `f ${s.frame} \u00B7 ${(s.frame / 60).toFixed(1)}s</text>` +\n `</g>`\n );\n })\n .join('');\n\n return (\n `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 ${totalW} ${totalH}\" width=\"${totalW}\" height=\"${totalH}\">` +\n `<rect x=\"0\" y=\"0\" width=\"${totalW}\" height=\"${totalH}\" fill=\"#f4f4f2\"/>` +\n cells +\n `</svg>`\n );\n}\n", "// Finite state machines for AI, screens, and move-animation. Two flavours:\n//\n// \u2022 `Fsm` \u2014 classic onEnter/onUpdate/onLeave states + an ORDERED transition\n// table (first matching guard wins). For enemy brains, UI phases, anything\n// driven by conditions.\n// \u2022 `PhaseClock` \u2014 the pure-logic\u2194`cosmetic` bridge. A timed phase with an\n// eased 0\u21921 progress value and a `next`-phase map (super-castle-game's\n// `IState` + `NextPhaseMap`, generalised): logical moves advance in discrete\n// phases while `progress()` feeds smooth interpolation to the view.\n//\n// Both are DETERMINISTIC: time arrives as a fixed `dt` (from the `Clock`, never\n// wall-clock), transitions are evaluated in array order, and the whole state is\n// a single serializable key + timer so it round-trips through `world.state`.\n\n/** Per-state lifecycle hooks. All optional; all pure over the shared context. */\nexport interface StateHandlers<C> {\n /** Ran once when the machine enters this state. */\n onEnter?(ctx: C): void;\n /** Ran every `update(dt)` while in this state. */\n onUpdate?(ctx: C, dt: number): void;\n /** Ran once when the machine leaves this state. */\n onLeave?(ctx: C): void;\n}\n\n/**\n * A guarded edge. `from` is a source state or `'*'` (any). Edges are evaluated\n * in table order every tick; the first whose `when` returns true fires. Keep\n * the table ordered \u2014 order IS the tie-break, so the machine stays hash-stable.\n */\nexport interface Transition<S extends string, C> {\n from: S | '*';\n to: S;\n when(ctx: C): boolean;\n}\n\nexport class Fsm<S extends string, C> {\n /** The active state key \u2014 this is the whole serializable state. */\n current: S;\n\n constructor(\n private readonly states: Record<S, StateHandlers<C>>,\n private readonly transitions: readonly Transition<S, C>[],\n initial: S,\n private readonly ctx: C,\n ) {\n this.current = initial;\n this.states[initial]?.onEnter?.(ctx);\n }\n\n /**\n * Advance one fixed step: fire the first satisfied transition (if any), then\n * run the current state's `onUpdate`. A transition runs its target's\n * `onUpdate` this same tick, so entering and acting aren't a frame apart.\n */\n update(dt: number): void {\n for (const t of this.transitions) {\n if ((t.from === '*' || t.from === this.current) && t.when(this.ctx)) {\n this.go(t.to);\n break;\n }\n }\n this.states[this.current]?.onUpdate?.(this.ctx, dt);\n }\n\n /** Force a transition (fires onLeave/onEnter). No-op if already there. */\n go(to: S): void {\n if (to === this.current) return;\n this.states[this.current]?.onLeave?.(this.ctx);\n this.current = to;\n this.states[to]?.onEnter?.(this.ctx);\n }\n\n /** True when in one of the given states. */\n is(...states: S[]): boolean {\n return states.includes(this.current);\n }\n\n /** Serialize (games persist this in `world.state`; the handlers are code). */\n getState(): S {\n return this.current;\n }\n /** Restore without firing enter/leave (it's a resume, not a transition). */\n setState(state: S): void {\n this.current = state;\n }\n}\n\n/** Eased progress curve `[0,1] \u2192 [0,1]`. Identity by default. */\nexport type Ease = (t: number) => number;\n\n/** A timed phase: how long it lasts and (optionally) what follows it. */\nexport interface PhaseDef {\n /** Duration in seconds (same units as the `dt` you feed `update`). */\n duration: number;\n /** Successor phase when this one elapses. Omit for a terminal phase. */\n next?: string;\n}\n\n/**\n * A phase with a countdown and an eased progress readout. Drives discrete\n * logical steps (each phase = one settled move) while exposing `progress()` for\n * the view to interpolate between the old and new position \u2014 so animation\n * timing rides on the same deterministic clock as the logic.\n */\nexport class PhaseClock {\n /** Current phase key \u2014 serializable with `elapsed`. */\n phase: string;\n /** Seconds spent in the current phase so far. */\n elapsed = 0;\n\n constructor(\n private readonly defs: Record<string, PhaseDef>,\n initial: string,\n ) {\n if (!defs[initial]) throw new Error(`hayao: PhaseClock has no phase '${initial}'`);\n this.phase = initial;\n }\n\n private get duration(): number {\n return this.defs[this.phase]?.duration ?? 0;\n }\n\n /** Eased fraction 0\u21921 through the current phase (clamped). For cosmetic interp. */\n progress(ease: Ease = (t) => t): number {\n const d = this.duration;\n const raw = d > 0 ? this.elapsed / d : 1;\n return ease(raw < 0 ? 0 : raw > 1 ? 1 : raw);\n }\n\n /** True once the current phase's duration has fully elapsed. */\n get done(): boolean {\n return this.elapsed >= this.duration;\n }\n\n /**\n * Advance by `dt`. When a phase completes and has a `next`, roll into it\n * (carrying any overshoot so long phases don't drift). Returns true on the\n * tick a new phase begins \u2014 the game's cue to commit the next logical step.\n */\n update(dt: number): boolean {\n this.elapsed += dt;\n let advanced = false;\n // Loop in case a very small duration is stepped over in one big dt.\n let guard = 0;\n while (this.elapsed >= this.duration && this.defs[this.phase]?.next !== undefined && guard++ < 1024) {\n const overshoot = this.elapsed - this.duration;\n this.phase = this.defs[this.phase].next as string;\n this.elapsed = overshoot;\n advanced = true;\n }\n return advanced;\n }\n\n /** Jump to a phase and reset its timer (fresh `onEnter`-style restart). */\n to(phase: string): void {\n if (!this.defs[phase]) throw new Error(`hayao: PhaseClock has no phase '${phase}'`);\n this.phase = phase;\n this.elapsed = 0;\n }\n\n getState(): { phase: string; elapsed: number } {\n return { phase: this.phase, elapsed: this.elapsed };\n }\n setState(state: { phase: string; elapsed: number }): void {\n this.phase = state.phase;\n this.elapsed = state.elapsed;\n }\n}\n", "// Weighted random picking + loot/spawn tables. Built strictly ON `world.rng`\n// (an `Rng`) \u2014 never `Math.random`. A single float draw per pick, scanned over\n// cumulative weights in array order, so results are deterministic and\n// reproducible from the RNG state alone. (js13k games fake this with\n// filter+shuffle or reach for `Math.random`; this is the honest primitive.)\n\nimport type { Rng } from '../core/rng';\n\n/** One weighted option: a value and its relative weight (\u2265 0). */\nexport interface WeightedEntry<T> {\n value: T;\n weight: number;\n}\n\n/** Sum a weight list, clamping negatives to 0 (a negative weight is a bug, not a subtraction). */\nfunction totalWeight(weights: readonly number[]): number {\n let sum = 0;\n for (const w of weights) sum += w > 0 ? w : 0;\n return sum;\n}\n\n/**\n * Pick an index in [0, weights.length) with probability \u221D weights[i]. Draws\n * exactly one `rng.float()` and walks the weights in order, so the choice is a\n * pure function of the RNG state. Throws if no weight is positive.\n */\nexport function weightedIndex(rng: Rng, weights: readonly number[]): number {\n const total = totalWeight(weights);\n if (total <= 0) throw new Error('hayao: weightedIndex needs at least one positive weight');\n let r = rng.float() * total;\n for (let i = 0; i < weights.length; i++) {\n const w = weights[i] > 0 ? weights[i] : 0;\n if (r < w) return i;\n r -= w;\n }\n // Float rounding can leave r \u2265 every remaining bucket; hand it the last positive one.\n for (let i = weights.length - 1; i >= 0; i--) if (weights[i] > 0) return i;\n return weights.length - 1;\n}\n\n/** Pick `items[i]` with probability \u221D `weights[i]` (parallel arrays). */\nexport function weightedPick<T>(rng: Rng, items: readonly T[], weights: readonly number[]): T {\n if (items.length !== weights.length) throw new Error('hayao: weightedPick items/weights length mismatch');\n return items[weightedIndex(rng, weights)];\n}\n\n/** Pick the value of one weighted entry. */\nexport function pickEntry<T>(rng: Rng, entries: readonly WeightedEntry<T>[]): T {\n return entries[weightedIndex(rng, entries.map((e) => e.weight))].value;\n}\n\n/**\n * A reusable loot/spawn table. Precomputes cumulative weights once so repeated\n * rolls are cheap; every draw still comes from the passed `Rng`, keeping the\n * table itself stateless and the randomness owned by `world.rng`.\n */\nexport class LootTable<T> {\n private readonly values: readonly T[];\n /** Cumulative (prefix-sum) weights; last element is the total. */\n private readonly cumulative: readonly number[];\n readonly total: number;\n\n constructor(entries: readonly WeightedEntry<T>[]) {\n if (entries.length === 0) throw new Error('hayao: LootTable needs at least one entry');\n const values: T[] = [];\n const cumulative: number[] = [];\n let sum = 0;\n for (const e of entries) {\n sum += e.weight > 0 ? e.weight : 0;\n values.push(e.value);\n cumulative.push(sum);\n }\n if (sum <= 0) throw new Error('hayao: LootTable needs at least one positive weight');\n this.values = values;\n this.cumulative = cumulative;\n this.total = sum;\n }\n\n /** One draw with replacement. */\n roll(rng: Rng): T {\n const r = rng.float() * this.total;\n // Linear scan (tables are small); ordered \u2192 deterministic.\n for (let i = 0; i < this.cumulative.length; i++) if (r < this.cumulative[i]) return this.values[i];\n return this.values[this.values.length - 1];\n }\n\n /** `n` independent draws with replacement, in order. */\n rollMany(rng: Rng, n: number): T[] {\n const out: T[] = [];\n for (let i = 0; i < n; i++) out.push(this.roll(rng));\n return out;\n }\n}\n", "// Graph search: BFS, flood-fill, connected-components, and grid A*/Dijkstra.\n// Pairs with `physics/tilemap.ts` (enemy nav, region/cluster detection, unit\n// routing) but works over any adjacency function too.\n//\n// DETERMINISM: neighbours are visited in a fixed order, the frontier is an\n// array (BFS) or a binary heap tie-broken by a monotonic insertion counter\n// (A*/Dijkstra), and grids are scanned row-major. `cameFrom`/`cost` maps are\n// only ever read by key \u2014 never iterated to drive logic \u2014 so no Set/Map\n// ordering hazard reaches `world.hash()`. No RNG, no wall-clock; fully pure.\n\nimport { TILE, tileAt, type TilemapData } from '../physics/tilemap';\n\n// \u2500\u2500 generic graph search over an adjacency function \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** Neighbours of a node, in deterministic order. */\nexport type Neighbours<N> = (node: N) => N[];\n/** Stable string identity for a node (visited-set + path keys). */\nexport type NodeKey<N> = (node: N) => string;\n\nexport interface BfsResult<N> {\n /** Nodes in expansion order (breadth-first). */\n order: N[];\n /** key \u2192 the node it was first reached from (for path reconstruction). */\n cameFrom: Map<string, N>;\n /** key \u2192 steps from the start (start = 0). */\n dist: Map<string, number>;\n}\n\n/**\n * Breadth-first search from `start`. Explores the whole reachable component\n * unless `goal` short-circuits it. `maxNodes` caps work on huge/open graphs.\n */\nexport function bfs<N>(\n start: N,\n neighbours: Neighbours<N>,\n key: NodeKey<N>,\n opts: { goal?: (n: N) => boolean; maxNodes?: number } = {},\n): BfsResult<N> {\n const maxNodes = opts.maxNodes ?? 1_000_000;\n const order: N[] = [];\n const cameFrom = new Map<string, N>();\n const dist = new Map<string, number>();\n const startKey = key(start);\n dist.set(startKey, 0);\n let frontier: N[] = [start];\n order.push(start);\n if (opts.goal?.(start)) return { order, cameFrom, dist };\n\n let expanded = 0;\n while (frontier.length > 0 && expanded < maxNodes) {\n const next: N[] = [];\n for (const node of frontier) {\n const d = dist.get(key(node)) ?? 0;\n for (const nb of neighbours(node)) {\n const k = key(nb);\n if (dist.has(k)) continue;\n dist.set(k, d + 1);\n cameFrom.set(k, node);\n order.push(nb);\n expanded++;\n if (opts.goal?.(nb)) return { order, cameFrom, dist };\n next.push(nb);\n }\n }\n frontier = next;\n }\n return { order, cameFrom, dist };\n}\n\n/** Reconstruct the path start\u2192goal from a `cameFrom` map, or [] if unreachable. */\nexport function reconstructPath<N>(cameFrom: Map<string, N>, key: NodeKey<N>, start: N, goal: N): N[] {\n const path: N[] = [goal];\n let cur = goal;\n const startKey = key(start);\n while (key(cur) !== startKey) {\n const prev = cameFrom.get(key(cur));\n if (prev === undefined) return []; // goal not connected to start\n cur = prev;\n path.push(cur);\n }\n path.reverse();\n return path;\n}\n\n// \u2500\u2500 weighted search: Dijkstra / A* over an adjacency function \u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** A neighbour with the step cost to reach it (must be \u2265 0). */\nexport interface WeightedEdge<N> {\n node: N;\n cost: number;\n}\nexport type WeightedNeighbours<N> = (node: N) => WeightedEdge<N>[];\n\n/**\n * A* (Dijkstra when `heuristic` is omitted/zero) over a weighted adjacency\n * function. Returns the least-cost path start\u2192goal (inclusive) or null.\n * Tie-broken by insertion order via a monotonic counter \u2192 identical path on\n * every engine.\n */\nexport function astar<N>(\n start: N,\n isGoal: (n: N) => boolean,\n neighbours: WeightedNeighbours<N>,\n key: NodeKey<N>,\n opts: { heuristic?: (n: N) => number; maxNodes?: number } = {},\n): { path: N[]; cost: number } | null {\n const h = opts.heuristic ?? (() => 0);\n const maxNodes = opts.maxNodes ?? 1_000_000;\n const cameFrom = new Map<string, N>();\n const gScore = new Map<string, number>();\n const heap = new MinHeap<N>();\n const startKey = key(start);\n gScore.set(startKey, 0);\n heap.push(start, h(start));\n\n let expanded = 0;\n while (heap.size > 0 && expanded < maxNodes) {\n const { item: cur, priority: f } = heap.pop();\n const ck = key(cur);\n const g = gScore.get(ck) ?? Infinity;\n // Stale heap entry (a cheaper path superseded it): f encodes g+h at push time.\n if (f > g + h(cur) + 1e-9) continue;\n if (isGoal(cur)) return { path: rebuild(cameFrom, key, cur), cost: g };\n expanded++;\n for (const edge of neighbours(cur)) {\n const nk = key(edge.node);\n const tentative = g + edge.cost;\n if (tentative < (gScore.get(nk) ?? Infinity)) {\n gScore.set(nk, tentative);\n cameFrom.set(nk, cur);\n heap.push(edge.node, tentative + h(edge.node));\n }\n }\n }\n return null;\n}\n\nfunction rebuild<N>(cameFrom: Map<string, N>, key: NodeKey<N>, goal: N): N[] {\n const path: N[] = [goal];\n let cur = goal;\n let prev = cameFrom.get(key(cur));\n while (prev !== undefined) {\n cur = prev;\n path.push(cur);\n prev = cameFrom.get(key(cur));\n }\n path.reverse();\n return path;\n}\n\n/**\n * Binary min-heap keyed on a numeric priority, tie-broken by insertion sequence\n * so equal-priority items pop in push order \u2014 the source of A*'s determinism.\n */\nclass MinHeap<T> {\n private items: T[] = [];\n private prio: number[] = [];\n private seq: number[] = [];\n private counter = 0;\n\n get size(): number {\n return this.items.length;\n }\n\n push(item: T, priority: number): void {\n this.items.push(item);\n this.prio.push(priority);\n this.seq.push(this.counter++);\n this.bubbleUp(this.items.length - 1);\n }\n\n pop(): { item: T; priority: number } {\n const item = this.items[0];\n const priority = this.prio[0];\n const last = this.items.length - 1;\n this.swap(0, last);\n this.items.pop();\n this.prio.pop();\n this.seq.pop();\n if (this.items.length > 0) this.bubbleDown(0);\n return { item, priority };\n }\n\n /** true if a is strictly higher priority (lower value, then earlier seq). */\n private less(a: number, b: number): boolean {\n return this.prio[a] < this.prio[b] || (this.prio[a] === this.prio[b] && this.seq[a] < this.seq[b]);\n }\n\n private bubbleUp(i: number): void {\n while (i > 0) {\n const parent = (i - 1) >> 1;\n if (!this.less(i, parent)) break;\n this.swap(i, parent);\n i = parent;\n }\n }\n\n private bubbleDown(i: number): void {\n const n = this.items.length;\n for (;;) {\n const l = 2 * i + 1;\n const r = 2 * i + 2;\n let smallest = i;\n if (l < n && this.less(l, smallest)) smallest = l;\n if (r < n && this.less(r, smallest)) smallest = r;\n if (smallest === i) break;\n this.swap(i, smallest);\n i = smallest;\n }\n }\n\n private swap(a: number, b: number): void {\n [this.items[a], this.items[b]] = [this.items[b], this.items[a]];\n [this.prio[a], this.prio[b]] = [this.prio[b], this.prio[a]];\n [this.seq[a], this.seq[b]] = [this.seq[b], this.seq[a]];\n }\n}\n\n// \u2500\u2500 grid conveniences (row-major, tilemap-friendly) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport interface Cell {\n x: number;\n y: number;\n}\n\n/** 4-neighbour offsets (N, E, S, W), in a fixed order. */\nexport const NEIGHBORS_4: readonly Cell[] = [\n { x: 0, y: -1 },\n { x: 1, y: 0 },\n { x: 0, y: 1 },\n { x: -1, y: 0 },\n];\n/** 8-neighbour offsets (orthogonals then diagonals), in a fixed order. */\nexport const NEIGHBORS_8: readonly Cell[] = [\n ...NEIGHBORS_4,\n { x: 1, y: -1 },\n { x: 1, y: 1 },\n { x: -1, y: 1 },\n { x: -1, y: -1 },\n];\n\n/** Is a cell walkable? Called for in-bounds cells only. */\nexport type Passable = (x: number, y: number) => boolean;\n\nconst cellKey = (c: Cell): string => `${c.x},${c.y}`;\n\nfunction gridNeighbours(passable: Passable, cols: number, rows: number, diagonal: boolean): Neighbours<Cell> {\n const offsets = diagonal ? NEIGHBORS_8 : NEIGHBORS_4;\n return (c: Cell) => {\n const out: Cell[] = [];\n for (const o of offsets) {\n const x = c.x + o.x;\n const y = c.y + o.y;\n if (x < 0 || y < 0 || x >= cols || y >= rows) continue;\n if (!passable(x, y)) continue;\n out.push({ x, y });\n }\n return out;\n };\n}\n\n/**\n * Flood-fill from a seed cell over `passable`, returning every reachable cell\n * in breadth-first (deterministic) order. The classic bucket-fill / region-grab.\n */\nexport function floodFill(\n start: Cell,\n passable: Passable,\n opts: { cols: number; rows: number; diagonal?: boolean },\n): Cell[] {\n if (!passable(start.x, start.y)) return [];\n const nb = gridNeighbours(passable, opts.cols, opts.rows, opts.diagonal ?? false);\n return bfs(start, nb, cellKey).order;\n}\n\nexport interface Components {\n /** Row-major label per cell: -1 for impassable, else a component id \u2265 0. */\n labels: number[];\n /** Cells of each component, indexed by id, each in row-major order. */\n cells: Cell[][];\n}\n\n/**\n * Label connected regions of passable cells. Scans row-major and flood-fills\n * each unlabeled passable cell, so component ids are assigned deterministically\n * (top-left region first). Region/cluster detection for match-3, territory, etc.\n */\nexport function connectedComponents(cols: number, rows: number, passable: Passable, diagonal = false): Components {\n const labels = new Array<number>(cols * rows).fill(-1);\n const cells: Cell[][] = [];\n const offsets = diagonal ? NEIGHBORS_8 : NEIGHBORS_4;\n for (let y = 0; y < rows; y++) {\n for (let x = 0; x < cols; x++) {\n if (labels[y * cols + x] !== -1 || !passable(x, y)) continue;\n const id = cells.length;\n const region: Cell[] = [];\n // Iterative BFS with an in-place label as the visited marker.\n let frontier: Cell[] = [{ x, y }];\n labels[y * cols + x] = id;\n while (frontier.length > 0) {\n const next: Cell[] = [];\n for (const c of frontier) {\n region.push(c);\n for (const o of offsets) {\n const nx = c.x + o.x;\n const ny = c.y + o.y;\n if (nx < 0 || ny < 0 || nx >= cols || ny >= rows) continue;\n const idx = ny * cols + nx;\n if (labels[idx] !== -1 || !passable(nx, ny)) continue;\n labels[idx] = id;\n next.push({ x: nx, y: ny });\n }\n }\n frontier = next;\n }\n cells.push(region);\n }\n }\n return { labels, cells };\n}\n\n/**\n * Grid A* / Dijkstra. Returns the least-cost cell path start\u2192goal (inclusive)\n * or null if unreachable. Default step cost is 1 (orthogonal) / \u221A2 (diagonal);\n * pass `cost(x,y)` to weight terrain. Heuristic defaults to Manhattan (4-dir)\n * or octile (8-dir) \u2014 admissible, integer-stable, so paths reproduce exactly.\n */\nexport function astarGrid(\n start: Cell,\n goal: Cell,\n passable: Passable,\n opts: { cols: number; rows: number; diagonal?: boolean; cost?: (x: number, y: number) => number; maxNodes?: number },\n): Cell[] | null {\n const diagonal = opts.diagonal ?? false;\n const offsets = diagonal ? NEIGHBORS_8 : NEIGHBORS_4;\n const stepCost = opts.cost ?? (() => 1);\n const SQRT2 = 1.4142135623730951;\n\n const neighbours: WeightedNeighbours<Cell> = (c) => {\n const out: WeightedEdge<Cell>[] = [];\n for (const o of offsets) {\n const x = c.x + o.x;\n const y = c.y + o.y;\n if (x < 0 || y < 0 || x >= opts.cols || y >= opts.rows) continue;\n if (!passable(x, y)) continue;\n const diag = o.x !== 0 && o.y !== 0;\n out.push({ node: { x, y }, cost: stepCost(x, y) * (diag ? SQRT2 : 1) });\n }\n return out;\n };\n\n const heuristic = (c: Cell): number => {\n const dx = Math.abs(c.x - goal.x);\n const dy = Math.abs(c.y - goal.y);\n if (!diagonal) return dx + dy; // Manhattan\n const lo = Math.min(dx, dy);\n return dx + dy - (2 - SQRT2) * lo; // octile\n };\n\n if (!passable(goal.x, goal.y)) return null;\n const result = astar(start, (c) => c.x === goal.x && c.y === goal.y, neighbours, cellKey, {\n heuristic,\n maxNodes: opts.maxNodes,\n });\n return result ? result.path : null;\n}\n\n/** Build a `Passable` from a tilemap: everything but SOLID/out-of-bounds walks. */\nexport function passableFromTilemap(map: TilemapData): Passable {\n return (x, y) => tileAt(map, x, y) !== TILE.SOLID;\n}\n", "// Undo / record-replay buffers over pure state. Nearly free given Hayao's\n// pure-logic + snapshot model, but worth packaging cleanly:\n// \u2022 UndoStack \u2014 a bounded memento (state-clone) stack with redo, for puzzle\n// undo over an immutable-ish State (dying-dreams clones its\n// PuzzleState; this is that, with a cursor and a size cap).\n// \u2022 RingBuffer \u2014 a bounded FIFO for ghost/echo trails (soul-jumper's 8-frame\n// pose history) \u2014 overwrites oldest, O(1) push.\n// Both are pure and deterministic; store their contents as plain data so they\n// ride along in `world.state` without escaping the hash.\n\n/** Deep clone used by default. structuredClone is available in Node \u226517 & browsers. */\nfunction deepClone<S>(s: S): S {\n return structuredClone(s);\n}\n\n/**\n * A memento stack for undo/redo over snapshots of pure state. Call `record()`\n * after every committed move; `undo()`/`redo()` walk the cursor. States are\n * cloned in and out so callers can freely mutate what they get back. Capacity is\n * bounded \u2014 the oldest entry is dropped once `limit` is exceeded (undo has a\n * horizon, memory doesn't grow without bound).\n */\nexport class UndoStack<S> {\n private history: S[] = [];\n private cursor = -1;\n private readonly limit: number;\n private readonly clone: (s: S) => S;\n\n constructor(opts: { limit?: number; clone?: (s: S) => S } = {}) {\n this.limit = Math.max(1, opts.limit ?? 64);\n this.clone = opts.clone ?? deepClone;\n }\n\n /** Push a new state as the present, discarding any redo branch ahead of it. */\n record(state: S): void {\n // Drop the redo tail, then append.\n this.history.length = this.cursor + 1;\n this.history.push(this.clone(state));\n this.cursor = this.history.length - 1;\n // Enforce the horizon from the front.\n if (this.history.length > this.limit) {\n const overflow = this.history.length - this.limit;\n this.history.splice(0, overflow);\n this.cursor -= overflow;\n }\n }\n\n /** Step back one state and return a clone of it (undefined if nothing to undo). */\n undo(): S | undefined {\n if (this.cursor <= 0) return undefined;\n this.cursor--;\n return this.clone(this.history[this.cursor]);\n }\n\n /** Step forward one state and return a clone of it (undefined if nothing to redo). */\n redo(): S | undefined {\n if (this.cursor >= this.history.length - 1) return undefined;\n this.cursor++;\n return this.clone(this.history[this.cursor]);\n }\n\n /** A clone of the current state, or undefined if empty. */\n current(): S | undefined {\n return this.cursor >= 0 ? this.clone(this.history[this.cursor]) : undefined;\n }\n\n get canUndo(): boolean {\n return this.cursor > 0;\n }\n get canRedo(): boolean {\n return this.cursor < this.history.length - 1;\n }\n /** Number of recorded states retained. */\n get size(): number {\n return this.history.length;\n }\n\n clear(): void {\n this.history.length = 0;\n this.cursor = -1;\n }\n}\n\n/**\n * A fixed-capacity ring buffer \u2014 the ghost/echo trail. Push a pose (or any value)\n * each frame; when full, the oldest is overwritten. `toArray()` returns\n * oldest\u2192newest, which is exactly the order a trail renderer wants (tail first,\n * head last). Pure and O(1) per push.\n */\nexport class RingBuffer<T> {\n private readonly buf: (T | undefined)[];\n private start = 0;\n private count = 0;\n\n constructor(readonly capacity: number) {\n if (!Number.isInteger(capacity) || capacity < 1) throw new Error('hayao: RingBuffer capacity must be a positive integer');\n this.buf = new Array<T | undefined>(capacity);\n }\n\n push(item: T): void {\n const end = (this.start + this.count) % this.capacity;\n this.buf[end] = item;\n if (this.count < this.capacity) {\n this.count++;\n } else {\n // Full: the write above overwrote the oldest slot; advance start past it.\n this.start = (this.start + 1) % this.capacity;\n }\n }\n\n /** Number of items currently held (\u2264 capacity). */\n get length(): number {\n return this.count;\n }\n get isFull(): boolean {\n return this.count === this.capacity;\n }\n\n /** Item by age index: 0 = oldest, length-1 = newest. Undefined if out of range. */\n at(i: number): T | undefined {\n if (i < 0 || i >= this.count) return undefined;\n return this.buf[(this.start + i) % this.capacity];\n }\n\n /** The most recently pushed item, or undefined if empty. */\n latest(): T | undefined {\n return this.at(this.count - 1);\n }\n\n /** Contents oldest\u2192newest. */\n toArray(): T[] {\n const out: T[] = [];\n for (let i = 0; i < this.count; i++) out.push(this.buf[(this.start + i) % this.capacity]!);\n return out;\n }\n\n clear(): void {\n this.start = 0;\n this.count = 0;\n this.buf.fill(undefined);\n }\n}\n", "// Pluggable persistence backend. The ONLY browser-coupled piece of save/load:\n// everything above it (codec, save manager) is pure and headless-stable. In the\n// browser you get `localStorage`; headless you get an in-memory map (so tests can\n// round-trip a save without touching disk or leaking global state) or a true\n// no-op. The sim never imports this directly \u2014 it snapshots/restores plain data.\n\n/**\n * A minimal key\u2192string store. Deliberately tiny (get/set/remove/keys) so any\n * backend \u2014 `localStorage`, a Map, a file, IndexedDB \u2014 satisfies it trivially.\n */\nexport interface StorageAdapter {\n get(key: string): string | null;\n set(key: string, value: string): void;\n remove(key: string): void;\n /** All keys currently held, in insertion order where the backend preserves it. */\n keys(): string[];\n}\n\n/** In-memory backend. Deterministic and self-contained \u2014 the headless default. */\nexport class MemoryStorage implements StorageAdapter {\n private readonly map = new Map<string, string>();\n\n get(key: string): string | null {\n return this.map.has(key) ? this.map.get(key)! : null;\n }\n set(key: string, value: string): void {\n this.map.set(key, value);\n }\n remove(key: string): void {\n this.map.delete(key);\n }\n keys(): string[] {\n return [...this.map.keys()];\n }\n}\n\n/** Swallows everything \u2014 reads always miss. For runs that must stay pristine. */\nexport class NullStorage implements StorageAdapter {\n get(_key: string): string | null {\n return null;\n }\n set(_key: string, _value: string): void {}\n remove(_key: string): void {}\n keys(): string[] {\n return [];\n }\n}\n\n/**\n * `localStorage`-backed, guarded on every call: a disabled/absent/full store\n * (private mode, quota, SSR) degrades to a silent miss instead of throwing, so a\n * save failure never crashes a game. Keys are namespaced by `prefix`.\n */\nexport class LocalStorageAdapter implements StorageAdapter {\n constructor(private readonly prefix = 'hayao.save.') {}\n\n private ls(): Storage | null {\n try {\n return typeof localStorage !== 'undefined' ? localStorage : null;\n } catch {\n return null; // access itself can throw when cookies/storage are blocked\n }\n }\n\n get(key: string): string | null {\n try {\n return this.ls()?.getItem(this.prefix + key) ?? null;\n } catch {\n return null;\n }\n }\n set(key: string, value: string): void {\n try {\n this.ls()?.setItem(this.prefix + key, value);\n } catch {\n /* quota / disabled \u2014 a lost save beats a crash */\n }\n }\n remove(key: string): void {\n try {\n this.ls()?.removeItem(this.prefix + key);\n } catch {\n /* ignore */\n }\n }\n keys(): string[] {\n const ls = this.ls();\n if (!ls) return [];\n const out: string[] = [];\n try {\n for (let i = 0; i < ls.length; i++) {\n const k = ls.key(i);\n if (k && k.startsWith(this.prefix)) out.push(k.slice(this.prefix.length));\n }\n } catch {\n /* ignore */\n }\n return out;\n }\n}\n\n/**\n * The right adapter for the current environment: `localStorage` when a real one\n * is present (browser), otherwise an in-memory map (headless tests/CI). Pass\n * `NullStorage` explicitly when you want reads to always miss.\n */\nexport function defaultStorage(prefix?: string): StorageAdapter {\n try {\n if (typeof localStorage !== 'undefined') {\n // Feature-probe rather than trust the global: some headless runtimes expose\n // a `localStorage` object whose methods throw. A real write/read/remove is\n // the only honest test; any failure falls through to the in-memory backend.\n const probe = '__hayao_probe__';\n localStorage.setItem(probe, '1');\n localStorage.removeItem(probe);\n return new LocalStorageAdapter(prefix);\n }\n } catch {\n /* fall through to memory */\n }\n return new MemoryStorage();\n}\n", "// Compact string codecs for levels and state \u2014 the js13k byte-squeeze trick, made\n// deterministic and fully reversible. Two independent tools:\n// \u2022 RLE \u2014 collapse runs in grid/level strings (walls, tiles), witchcat-style.\n// \u2022 varint pack \u2014 pack a list of small non-negative ints into a short URL-safe\n// string (base-64 continuation varints), soul-surf encode/decode.\n// Both are pure functions with exact round-trips; no RNG, no clock, no browser.\n\n// \u2500\u2500 Run-length encoding \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// Reversible for ANY string. A run of \u22654 (or any literal escape char) becomes\n// `~<char><count>~`; shorter runs stay literal. Compact for repetitive maps,\n// never larger by more than the escapes it introduces.\nconst ESC = '~';\nconst RLE_MIN_RUN = 4;\n\nexport function rleEncode(input: string): string {\n let out = '';\n let i = 0;\n while (i < input.length) {\n const ch = input[i];\n let run = 1;\n while (i + run < input.length && input[i + run] === ch) run++;\n if (run >= RLE_MIN_RUN || ch === ESC) {\n out += ESC + ch + run.toString(36) + ESC;\n } else {\n out += ch.repeat(run);\n }\n i += run;\n }\n return out;\n}\n\nexport function rleDecode(input: string): string {\n let out = '';\n let i = 0;\n while (i < input.length) {\n if (input[i] === ESC) {\n const ch = input[i + 1];\n const end = input.indexOf(ESC, i + 2);\n if (ch === undefined || end < 0) throw new Error('hayao: malformed RLE stream');\n const count = parseInt(input.slice(i + 2, end), 36);\n if (!Number.isFinite(count) || count < 1) throw new Error('hayao: malformed RLE count');\n out += ch.repeat(count);\n i = end + 1;\n } else {\n out += input[i];\n i++;\n }\n }\n return out;\n}\n\n// \u2500\u2500 Base-64 variable-length integers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// Pack non-negative integers into a URL/JSON-safe string: 6 bits per char, the\n// top bit a continuation flag (LEB128-style, base 32 per digit). Ideal for\n// coordinate lists, tile ids, and other small-int level payloads.\nconst ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_';\nconst INDEX: Record<string, number> = {};\nfor (let i = 0; i < ALPHABET.length; i++) INDEX[ALPHABET[i]] = i;\n\nexport function packVarints(nums: readonly number[]): string {\n let out = '';\n for (const n of nums) {\n if (!Number.isInteger(n) || n < 0) throw new Error(`hayao: packVarints expects non-negative integers, got ${n}`);\n let v = n;\n do {\n let digit = v & 0x1f; // low 5 bits\n v = Math.floor(v / 32);\n if (v > 0) digit |= 0x20; // continuation bit\n out += ALPHABET[digit];\n } while (v > 0);\n }\n return out;\n}\n\nexport function unpackVarints(input: string): number[] {\n const out: number[] = [];\n let v = 0;\n let shift = 1;\n for (const ch of input) {\n const digit = INDEX[ch];\n if (digit === undefined) throw new Error(`hayao: unpackVarints saw invalid char \"${ch}\"`);\n v += (digit & 0x1f) * shift;\n if (digit & 0x20) {\n shift *= 32; // more digits follow\n } else {\n out.push(v);\n v = 0;\n shift = 1;\n }\n }\n if (shift !== 1) throw new Error('hayao: unpackVarints hit a truncated stream');\n return out;\n}\n", "// Player-facing save/load over a pluggable StorageAdapter. Built ON TOP of the\n// existing `world.snapshot()`/`world.restore()` seam \u2014 it does NOT reinvent\n// serialization; it versions, guards, and persists what the world already emits.\n// A restored world reproduces the saved `hash()`/`probe()` exactly.\n\nimport type { World, WorldSnapshot } from '../world';\nimport { defaultStorage, type StorageAdapter } from './storage';\n\n/** Envelope stored per slot: a version tag around the raw WorldSnapshot. */\ninterface SaveEnvelope {\n v: number;\n snap: WorldSnapshot;\n}\n\n/** Bump when the snapshot shape changes in a way old saves can't satisfy. */\nexport const SAVE_FORMAT_VERSION = 1;\n\n/** Serialize a snapshot to a compact JSON string with a version envelope. */\nexport function serializeSnapshot(snap: WorldSnapshot): string {\n const envelope: SaveEnvelope = { v: SAVE_FORMAT_VERSION, snap };\n return JSON.stringify(envelope);\n}\n\n/**\n * Parse a serialized snapshot back. Returns `null` on anything malformed \u2014\n * corrupt JSON, wrong version, missing fields \u2014 so a bad save is a clean miss,\n * never a thrown exception mid-game. Guards `JSON.parse` per the invariant.\n */\nexport function parseSnapshot(text: string | null): WorldSnapshot | null {\n if (!text) return null;\n let parsed: unknown;\n try {\n parsed = JSON.parse(text);\n } catch {\n return null;\n }\n if (!parsed || typeof parsed !== 'object') return null;\n const env = parsed as Partial<SaveEnvelope>;\n if (env.v !== SAVE_FORMAT_VERSION || !env.snap || typeof env.snap !== 'object') return null;\n const snap = env.snap as Partial<WorldSnapshot>;\n // Minimal shape check on the fields `restore()` reads.\n if (typeof snap.seed !== 'number' || !snap.rng || !snap.clock || !snap.input || !snap.state || !snap.tree) {\n return null;\n }\n return snap as WorldSnapshot;\n}\n\n/**\n * A tiny save API bound to one World and one storage backend. Slots are named\n * ('auto', 'slot1', \u2026). Everything routes through `world.snapshot()`/`restore()`\n * so the saved and restored states share a hash.\n */\nexport class SaveManager {\n constructor(\n private readonly world: World,\n private readonly storage: StorageAdapter = defaultStorage(),\n ) {}\n\n /** Snapshot the world and persist it under `slot`. */\n save(slot = 'auto'): void {\n this.storage.set(slot, serializeSnapshot(this.world.snapshot()));\n }\n\n /** Restore `slot` into the world. Returns false if absent/corrupt (world untouched). */\n load(slot = 'auto'): boolean {\n const snap = parseSnapshot(this.storage.get(slot));\n if (!snap) return false;\n this.world.restore(snap);\n return true;\n }\n\n /** Is there a well-formed save in `slot`? */\n has(slot = 'auto'): boolean {\n return parseSnapshot(this.storage.get(slot)) !== null;\n }\n\n /** Delete a save slot. */\n delete(slot = 'auto'): void {\n this.storage.remove(slot);\n }\n\n /** All slot names currently persisted. */\n slots(): string[] {\n return this.storage.keys();\n }\n}\n", "// Data-driven content: a small schema + interpreter for declarative game content,\n// so waves, spawn tables, and upgrade trees are DATA (hashable, editable, diff-able)\n// rather than hand-rolled control flow. Two primitives, one determinism rule \u2014\n// rolls draw from `world.rng`, scheduling reads `world.time` (fixed sim seconds):\n// \u2022 SpawnDirector \u2014 a flat wave/spawn schedule (norman) with repeats and an\n// optional weighted spawn set (cat-survivors' director).\n// \u2022 upgrade trees \u2014 availability gating by owned prerequisites (evolutions).\n// Weighted rolls reuse `logic/random` (WeightedEntry + pickEntry), not a private\n// copy. The director's cursor state is plain JSON, so it lives in `world.state`\n// and is snapshotted/hashed like everything else.\n\nimport type { Rng } from '../core/rng';\nimport { pickEntry, type WeightedEntry } from '../logic/random';\n\n// \u2500\u2500 Wave / spawn director \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n/**\n * One declarative wave. Fires `count` of `spawn` at time `time` (sim seconds).\n * When `every` is set it repeats on that interval until `end` (exclusive),\n * modelling a continuous spawn stream. `spawn` may be a single id or a weighted\n * table, in which case each firing rolls the table via `world.rng`.\n */\nexport interface WaveDef {\n /** First fire time, in fixed sim seconds (compare against `world.time`). */\n time: number;\n /** What to spawn: a fixed id, or a weighted set rolled per firing. */\n spawn: string | WeightedEntry<string>[];\n /** How many per firing (default 1). */\n count?: number;\n /** Repeat interval in seconds; omit for a one-shot wave. */\n every?: number;\n /** Repeats stop once the next fire time reaches this (seconds). */\n end?: number;\n}\n\n/** Mutable director cursor \u2014 plain JSON, keep it in `world.state`. */\nexport interface DirectorState {\n /** Next fire time per wave index; Infinity once a wave is exhausted. */\n next: number[];\n}\n\n/** One resolved spawn instruction emitted by the director. */\nexport interface SpawnEvent {\n /** Concrete spawn id (already rolled if the wave used a weighted set). */\n spawn: string;\n count: number;\n /** Source wave index, for callers that want to key behavior off the wave. */\n wave: number;\n}\n\n/** Initialize a director cursor for a schedule. */\nexport function initDirector(waves: readonly WaveDef[]): DirectorState {\n return { next: waves.map((w) => w.time) };\n}\n\n/**\n * Advance the director to `time` (sim seconds) and return every spawn that is\n * now due, in wave order. Mutates `state.next` in place. Deterministic: it emits\n * the same events for the same (schedule, time, rng-state) on every machine.\n * A repeating wave can fire multiple times in one poll if the frame straddled\n * several intervals (e.g. after a restore), so catch-up never drops spawns.\n */\nexport function pollDirector(waves: readonly WaveDef[], state: DirectorState, time: number, rng?: Rng): SpawnEvent[] {\n const out: SpawnEvent[] = [];\n for (let i = 0; i < waves.length; i++) {\n const w = waves[i];\n let next = state.next[i] ?? w.time;\n while (next <= time) {\n let spawn: string;\n if (typeof w.spawn === 'string') {\n spawn = w.spawn;\n } else {\n if (!rng) throw new Error('hayao: pollDirector needs an Rng to roll a weighted wave');\n spawn = pickEntry(rng, w.spawn);\n }\n out.push({ spawn, count: w.count ?? 1, wave: i });\n if (w.every && w.every > 0) {\n next += w.every;\n if (w.end !== undefined && next >= w.end) {\n next = Infinity;\n break;\n }\n } else {\n next = Infinity;\n break;\n }\n }\n state.next[i] = next;\n }\n return out;\n}\n\n// \u2500\u2500 Upgrade / evolution trees \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n/**\n * A declarative upgrade or evolution node. `requires` lists ids that must all be\n * owned before this one can be offered \u2014 the cat-survivors evolution gate and a\n * deckbuilder's upgrade prerequisites are the same shape.\n */\nexport interface UpgradeDef {\n id: string;\n /** Ids that must all be owned before this becomes available. */\n requires?: string[];\n /** Optional: only offer while UNDER this many owned copies (repeatable upgrades). */\n maxStacks?: number;\n}\n\n/**\n * Which upgrades are offerable given what's owned: prerequisites all met, and\n * not already at `maxStacks` (default 1 \u2014 offered until owned once). `owned` may\n * repeat ids to represent stacks. Ordered by definition order for hash stability.\n */\nexport function availableUpgrades(defs: readonly UpgradeDef[], owned: readonly string[]): UpgradeDef[] {\n const counts = new Map<string, number>();\n for (const id of owned) counts.set(id, (counts.get(id) ?? 0) + 1);\n const has = (id: string) => (counts.get(id) ?? 0) > 0;\n return defs.filter((d) => {\n const stacks = counts.get(d.id) ?? 0;\n if (stacks >= (d.maxStacks ?? 1)) return false;\n return (d.requires ?? []).every(has);\n });\n}\n", "// Multiplayer inputs without touching the sim kernel: each player's actions are\n// namespaced (`p1:left`, `p2:jump`) and merged into the single flat action set\n// that `world.step()` already takes. The whole verify harness (InputLog, replay,\n// determinism checks) works on multiplayer games unchanged \u2014 a merged frame is\n// just a frame.\n\nimport type { World } from '../world';\n\n/** A player identity: 'p1', 'p2', \u2026 (any short string without ':' works). */\nexport type PlayerId = string;\n\n/** The canonical roster for n players: ['p1', \u2026, 'pn']. */\nexport function playerIds(count: number): PlayerId[] {\n const out: PlayerId[] = [];\n for (let i = 1; i <= count; i++) out.push(`p${i}`);\n return out;\n}\n\n/** Namespace one action for a player: ('p2', 'left') \u2192 'p2:left'. */\nexport const playerAction = (player: PlayerId, action: string): string => `${player}:${action}`;\n\n/**\n * Merge per-player action sets into one flat, sorted frame for `world.step()`.\n * Deterministic: players are processed in roster order and the result is sorted,\n * so every peer computes the identical frame from the same inputs.\n */\nexport function mergePlayerFrames(players: readonly PlayerId[], inputs: ReadonlyMap<PlayerId, readonly string[]>): string[] {\n const out: string[] = [];\n for (const p of players) {\n const actions = inputs.get(p) ?? [];\n for (const a of actions) out.push(playerAction(p, a));\n }\n return out.sort();\n}\n\n/**\n * A per-player view over the world's input state. Game logic asks\n * `player.isDown('left')` and never sees the namespacing.\n */\nexport class PlayerInput {\n constructor(\n private readonly world: World,\n readonly player: PlayerId,\n ) {}\n\n isDown(action: string): boolean {\n return this.world.input.isDown(playerAction(this.player, action));\n }\n justPressed(action: string): boolean {\n return this.world.input.justPressed(playerAction(this.player, action));\n }\n justReleased(action: string): boolean {\n return this.world.input.justReleased(playerAction(this.player, action));\n }\n}\n\n/** Convenience: the input view for one player. */\nexport const playerInput = (world: World, player: PlayerId): PlayerInput => new PlayerInput(world, player);\n", "// The wire protocol. Plain JSON messages over a bus transport (every peer sees\n// every message; `to` filters when a message is for one endpoint). Two layers\n// share the bus: the room layer (hello/welcome/join/leave/start \u2014 owned by\n// RoomHost/RoomClient) and the session layer (input/hash \u2014 owned by the\n// lockstep/rollback sessions).\n\nimport type { WorldSnapshot } from '../world';\nimport type { PlayerId } from './players';\n\nexport const NET_PROTOCOL_VERSION = 1;\n\n/** Session tuning shared by every peer (the host dictates it in `welcome`). */\nexport interface NetSessionConfig {\n mode: 'lockstep' | 'rollback';\n /** Frames of input delay (lockstep) \u2014 hides transport latency. */\n inputDelay: number;\n /** Exchange a state hash every N frames to catch desyncs early. */\n hashInterval: number;\n /** Rollback: how many frames of history can be rewound. */\n maxRollback: number;\n /** How many recent frames each input message re-sends (loss tolerance). */\n redundancy: number;\n}\n\nexport const DEFAULT_SESSION_CONFIG: NetSessionConfig = {\n mode: 'lockstep',\n inputDelay: 2,\n hashInterval: 20,\n maxRollback: 12,\n redundancy: 3,\n};\n\nexport type NetMessage =\n // \u2500\u2500 room layer \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n /** A new endpoint asks to join. `uid` is its transport-unique id. */\n | { v: number; t: 'hello'; uid: string; name?: string }\n /** Host \u2192 one endpoint: your player id + everything needed to start/join. */\n | {\n v: number;\n t: 'welcome';\n to: string;\n player: PlayerId;\n players: PlayerId[];\n seed: number;\n config: NetSessionConfig;\n /** Frame the joiner starts at (0 for a fresh game). */\n startFrame: number;\n /** Mid-game join: the world state at `startFrame`. */\n snapshot?: WorldSnapshot;\n /** Other joins announced but not yet live (their bootstrap frames). */\n joins?: Array<{ player: PlayerId; atFrame: number }>;\n }\n /** Host \u2192 all: a player will exist from `atFrame` on (late join). */\n | { v: number; t: 'join'; player: PlayerId; atFrame: number }\n /** Host \u2192 all: a player's inputs end at `atFrame` (disconnect/quit). */\n | { v: number; t: 'leave'; player: PlayerId; atFrame: number }\n /** Host \u2192 all: begin simulating from frame 0 with this final roster. */\n | { v: number; t: 'start'; players: PlayerId[] }\n /** Any endpoint \u2192 host: polite disconnect. */\n | { v: number; t: 'bye'; uid: string }\n /** Host \u2192 one endpoint: join refused (room full, mode without late join\u2026). */\n | { v: number; t: 'deny'; to: string; reason: string }\n // \u2500\u2500 session layer \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n /** Player inputs for frames [from, from+frames.length). Re-sends a small\n * window so a dropped message doesn't stall anyone. */\n | { v: number; t: 'input'; player: PlayerId; from: number; frames: string[][] }\n /** Structural world hash at a frame \u2014 cross-checked by every peer. */\n | { v: number; t: 'hash'; player: PlayerId; frame: number; hash: string };\n\nexport function encodeMessage(msg: NetMessage): string {\n return JSON.stringify(msg);\n}\n\n/** Decode + shallow-validate. Returns null for junk or version mismatch. */\nexport function decodeMessage(data: string): NetMessage | null {\n try {\n const msg = JSON.parse(data) as NetMessage;\n if (!msg || typeof msg !== 'object' || msg.v !== NET_PROTOCOL_VERSION || typeof msg.t !== 'string') return null;\n return msg;\n } catch {\n return null;\n }\n}\n\n/** Build a message with the protocol version stamped in. */\nexport function netMessage<T extends Omit<NetMessage, 'v'>>(msg: T): T & { v: number } {\n return { v: NET_PROTOCOL_VERSION, ...msg };\n}\n", "// Transports: how bytes move between peers. All transports are BUSES \u2014 send()\n// reaches every other peer on the same medium. That matches BroadcastChannel\n// (multi-tab), a dumb WebSocket relay (one room = one bus), and the in-memory\n// loopback hub (tests) with a single semantics, so sessions never care which\n// one they run on. Addressing, when needed, lives in the message (`to` field).\n\nexport interface Transport {\n /** Deliver to every other peer on the bus. */\n send(data: string): void;\n /** Subscribe to incoming data. Returns an unsubscribe function. */\n onMessage(cb: (data: string) => void): () => void;\n /** Fires when the transport goes away (socket close, hub shutdown). */\n onClose(cb: () => void): () => void;\n close(): void;\n readonly isOpen: boolean;\n}\n\n// \u2500\u2500 loopback: deterministic in-memory bus for tests \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport interface LoopbackOptions {\n /** Delivery delay in ticks (calls to hub.tick()). Default 0 = next tick. */\n delay?: number;\n /** Drop every Nth message (deterministic loss pattern). 0 = lossless. */\n dropEvery?: number;\n}\n\ninterface QueuedMessage {\n data: string;\n from: number;\n dueTick: number;\n seq: number;\n}\n\n/**\n * An in-memory bus with explicit, deterministic time: nothing is delivered\n * until `tick()` runs, messages arrive in send order, and loss follows a fixed\n * pattern. Network tests stay exactly reproducible \u2014 no timers, no races.\n */\nexport class LoopbackHub {\n private peers: LoopbackTransport[] = [];\n private queue: QueuedMessage[] = [];\n private tickCount = 0;\n private seq = 0;\n private sent = 0;\n private readonly delay: number;\n private readonly dropEvery: number;\n\n constructor(opts: LoopbackOptions = {}) {\n this.delay = opts.delay ?? 0;\n this.dropEvery = opts.dropEvery ?? 0;\n }\n\n /** Create a new endpoint on this bus. */\n connect(): LoopbackTransport {\n const t = new LoopbackTransport(this, this.peers.length);\n this.peers.push(t);\n return t;\n }\n\n /** @internal */\n enqueue(data: string, from: number): void {\n this.sent++;\n if (this.dropEvery > 0 && this.sent % this.dropEvery === 0) return;\n this.queue.push({ data, from, dueTick: this.tickCount + this.delay, seq: this.seq++ });\n }\n\n /** Advance one network tick, delivering everything that is due. */\n tick(): void {\n const due = this.queue.filter((m) => m.dueTick <= this.tickCount).sort((a, b) => a.seq - b.seq);\n this.queue = this.queue.filter((m) => m.dueTick > this.tickCount);\n this.tickCount++;\n for (const m of due) {\n for (const peer of this.peers) {\n if (peer.peerIndex !== m.from && peer.isOpen) peer.deliver(m.data);\n }\n }\n }\n\n /** Deliver everything in flight (repeated ticks until the queue drains). */\n flush(): void {\n while (this.queue.length > 0) this.tick();\n }\n\n get pending(): number {\n return this.queue.length;\n }\n}\n\nexport class LoopbackTransport implements Transport {\n private listeners: Array<(data: string) => void> = [];\n private closeListeners: Array<() => void> = [];\n private open = true;\n\n constructor(\n private readonly hub: LoopbackHub,\n readonly peerIndex: number,\n ) {}\n\n send(data: string): void {\n if (this.open) this.hub.enqueue(data, this.peerIndex);\n }\n onMessage(cb: (data: string) => void): () => void {\n this.listeners.push(cb);\n return () => {\n this.listeners = this.listeners.filter((l) => l !== cb);\n };\n }\n onClose(cb: () => void): () => void {\n this.closeListeners.push(cb);\n return () => {\n this.closeListeners = this.closeListeners.filter((l) => l !== cb);\n };\n }\n close(): void {\n if (!this.open) return;\n this.open = false;\n for (const cb of this.closeListeners) cb();\n }\n get isOpen(): boolean {\n return this.open;\n }\n /** @internal */\n deliver(data: string): void {\n for (const cb of this.listeners) cb(data);\n }\n}\n\n// \u2500\u2500 BroadcastChannel: zero-server multi-tab play \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * A bus over the browser's BroadcastChannel \u2014 every tab on the same origin\n * that opens the same room name is a peer. Perfect for local two-tab netplay\n * and demos: no server at all.\n */\nexport class BroadcastChannelTransport implements Transport {\n private channel: BroadcastChannel;\n private listeners: Array<(data: string) => void> = [];\n private closeListeners: Array<() => void> = [];\n private open = true;\n\n constructor(room: string) {\n this.channel = new BroadcastChannel(`hayao-net:${room}`);\n this.channel.onmessage = (e: MessageEvent) => {\n if (typeof e.data === 'string') for (const cb of this.listeners) cb(e.data);\n };\n }\n\n send(data: string): void {\n if (this.open) this.channel.postMessage(data);\n }\n onMessage(cb: (data: string) => void): () => void {\n this.listeners.push(cb);\n return () => {\n this.listeners = this.listeners.filter((l) => l !== cb);\n };\n }\n onClose(cb: () => void): () => void {\n this.closeListeners.push(cb);\n return () => {\n this.closeListeners = this.closeListeners.filter((l) => l !== cb);\n };\n }\n close(): void {\n if (!this.open) return;\n this.open = false;\n this.channel.close();\n for (const cb of this.closeListeners) cb();\n }\n get isOpen(): boolean {\n return this.open;\n }\n}\n\n// \u2500\u2500 WebSocket: real network play via the relay \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * A bus over a WebSocket to the hayao relay (`npm run relay`): everyone\n * connected to the same room URL is a peer; the relay forwards each message to\n * the room's other sockets. Resolves once the socket is open.\n */\nexport function connectWebSocket(url: string): Promise<Transport> {\n return new Promise((resolve, reject) => {\n const ws = new WebSocket(url);\n const listeners: Array<(data: string) => void> = [];\n const closeListeners: Array<() => void> = [];\n let open = false;\n\n const transport: Transport = {\n send(data: string) {\n if (open) ws.send(data);\n },\n onMessage(cb) {\n listeners.push(cb);\n return () => {\n const i = listeners.indexOf(cb);\n if (i >= 0) listeners.splice(i, 1);\n };\n },\n onClose(cb) {\n closeListeners.push(cb);\n return () => {\n const i = closeListeners.indexOf(cb);\n if (i >= 0) closeListeners.splice(i, 1);\n };\n },\n close() {\n open = false;\n ws.close();\n },\n get isOpen() {\n return open;\n },\n };\n\n ws.onopen = () => {\n open = true;\n resolve(transport);\n };\n ws.onmessage = (e: MessageEvent) => {\n if (typeof e.data === 'string') for (const cb of listeners) cb(e.data);\n };\n ws.onclose = () => {\n const wasOpen = open;\n open = false;\n if (wasOpen) for (const cb of closeListeners) cb();\n };\n ws.onerror = () => {\n if (!open) reject(new Error(`hayao-net: could not connect to ${url}`));\n };\n });\n}\n", "// Per-player input history. Both session kinds keep one: lockstep asks \"do I\n// have everyone's frame N?\", rollback asks \"what changed vs. my prediction?\".\n// First-write-wins per (player, frame) so duplicated or reordered redundancy\n// windows can never rewrite history.\n\nimport type { PlayerId } from './players';\n\nexport class InputBuffer {\n /** player \u2192 frame \u2192 actions (sorted). */\n private frames = new Map<PlayerId, Map<number, string[]>>();\n /** player \u2192 highest contiguous frame received (for prediction + confirm). */\n private contiguous = new Map<PlayerId, number>();\n\n addPlayer(player: PlayerId): void {\n if (!this.frames.has(player)) {\n this.frames.set(player, new Map());\n this.contiguous.set(player, -1);\n }\n }\n\n removePlayer(player: PlayerId): void {\n this.frames.delete(player);\n this.contiguous.delete(player);\n }\n\n players(): PlayerId[] {\n return [...this.frames.keys()];\n }\n\n /**\n * Record a player's actions for a frame. Returns true if this was new\n * information (first write for that slot).\n */\n set(player: PlayerId, frame: number, actions: readonly string[]): boolean {\n const perPlayer = this.frames.get(player);\n if (!perPlayer || perPlayer.has(frame)) return false;\n perPlayer.set(frame, [...actions].sort());\n // Advance the contiguous watermark as far as the new frame allows.\n let c = this.contiguous.get(player) ?? -1;\n while (perPlayer.has(c + 1)) c++;\n this.contiguous.set(player, c);\n return true;\n }\n\n has(player: PlayerId, frame: number): boolean {\n return this.frames.get(player)?.has(frame) ?? false;\n }\n\n get(player: PlayerId, frame: number): string[] | undefined {\n return this.frames.get(player)?.get(frame);\n }\n\n /** The last actions at or before `frame` \u2014 the rollback predictor's guess. */\n latestAt(player: PlayerId, frame: number): string[] {\n const perPlayer = this.frames.get(player);\n if (!perPlayer) return [];\n for (let f = frame; f >= 0; f--) {\n const a = perPlayer.get(f);\n if (a) return a;\n }\n return [];\n }\n\n /** Highest frame such that this player's inputs 0..frame are all known. */\n contiguousThrough(player: PlayerId): number {\n return this.contiguous.get(player) ?? -1;\n }\n\n /** Highest frame with ALL players' inputs known contiguously. */\n confirmedFrame(): number {\n let min = Infinity;\n for (const c of this.contiguous.values()) min = Math.min(min, c);\n return min === Infinity ? -1 : min;\n }\n\n /** Forget a player's frames at/after `frame` (leave cutoff). */\n clearFrom(player: PlayerId, frame: number): void {\n const perPlayer = this.frames.get(player);\n if (!perPlayer) return;\n for (const f of perPlayer.keys()) if (f >= frame) perPlayer.delete(f);\n let c = this.contiguous.get(player) ?? -1;\n if (c >= frame) c = frame - 1;\n this.contiguous.set(player, c);\n }\n\n /** Drop history strictly before `frame` (memory hygiene on long sessions). */\n prune(frame: number): void {\n for (const perPlayer of this.frames.values()) {\n for (const f of perPlayer.keys()) if (f < frame) perPlayer.delete(f);\n }\n }\n}\n", "// Deterministic lockstep: every peer runs the identical sim and only steps\n// frame N once it holds EVERY active player's input for N. Local input is\n// scheduled `inputDelay` frames ahead to hide transport latency. Because\n// `world.step(mergedFrame)` is already a pure transition, the network layer\n// never touches the sim \u2014 it only decides when a step may run and what the\n// merged frame contains.\n//\n// Desync safety: every `hashInterval` frames each peer broadcasts its\n// `world.hash()`; any mismatch surfaces the frame, both hashes, and the full\n// merged input log \u2014 which `replay()` can binary-search offline.\n\nimport type { World } from '../world';\nimport type { InputLog } from '../input/actions';\nimport { InputBuffer } from './inputBuffer';\nimport { mergePlayerFrames, type PlayerId } from './players';\nimport { DEFAULT_SESSION_CONFIG, decodeMessage, encodeMessage, netMessage, type NetSessionConfig } from './protocol';\nimport type { Transport } from './transport';\n\nexport interface DesyncInfo {\n frame: number;\n player: PlayerId;\n localHash: string;\n remoteHash: string;\n /** Merged frames from this session's startFrame \u2014 replay fodder. */\n log: InputLog;\n startFrame: number;\n}\n\nexport interface LockstepOptions {\n world: World;\n transport: Transport;\n localPlayer: PlayerId;\n /** Roster at startFrame, in canonical order. */\n players: PlayerId[];\n /** Frame this session begins at (0 for a fresh game, >0 for a late joiner). */\n startFrame?: number;\n config?: Partial<NetSessionConfig>;\n onDesync?: (info: DesyncInfo) => void;\n /** Fired when a step is blocked waiting on a player's input. */\n onStall?: (player: PlayerId, frame: number) => void;\n}\n\ninterface RosterEntry {\n player: PlayerId;\n from: number;\n until: number; // exclusive; Infinity = still present\n}\n\nexport class LockstepSession {\n readonly world: World;\n readonly localPlayer: PlayerId;\n readonly config: NetSessionConfig;\n readonly startFrame: number;\n\n private readonly transport: Transport;\n private readonly buffer = new InputBuffer();\n private roster: RosterEntry[] = [];\n private mergedLog: string[][] = [];\n private localHashes = new Map<number, string>();\n private pendingRemoteHashes: Array<{ player: PlayerId; frame: number; hash: string }> = [];\n private sentThrough: number;\n private stallCount = 0;\n private desynced = false;\n private afterStepListeners: Array<(frame: number) => void> = [];\n private unsubscribe: () => void;\n private readonly onDesync?: (info: DesyncInfo) => void;\n private readonly onStall?: (player: PlayerId, frame: number) => void;\n\n constructor(opts: LockstepOptions) {\n this.world = opts.world;\n this.transport = opts.transport;\n this.localPlayer = opts.localPlayer;\n this.config = { ...DEFAULT_SESSION_CONFIG, ...opts.config, mode: 'lockstep' };\n this.startFrame = opts.startFrame ?? 0;\n this.onDesync = opts.onDesync;\n this.onStall = opts.onStall;\n\n for (const p of opts.players) {\n this.roster.push({ player: p, from: this.startFrame, until: Infinity });\n this.buffer.addPlayer(p);\n // Bootstrap: a player's first `inputDelay` frames are empty \u2014 identical\n // on every peer without a single message. At a fresh start that is\n // everyone; a late joiner seeds only ITSELF (the veterans have real\n // inputs at its startFrame, which must be used, not zeroed).\n if (this.startFrame === 0 || p === this.localPlayer) {\n for (let f = this.startFrame; f < this.startFrame + this.config.inputDelay; f++) this.buffer.set(p, f, []);\n }\n }\n this.sentThrough = this.startFrame + this.config.inputDelay - 1;\n\n this.unsubscribe = this.transport.onMessage((data) => this.receive(data));\n }\n\n // \u2500\u2500 the roster (players can come and go at agreed frames) \u2500\u2500\u2500\u2500\n activePlayers(frame: number): PlayerId[] {\n return this.roster.filter((r) => r.from <= frame && frame < r.until).map((r) => r.player);\n }\n\n /** All peers must call this with the SAME atFrame (the room layer's job). */\n addPlayer(player: PlayerId, atFrame: number): void {\n if (this.roster.some((r) => r.player === player && r.until === Infinity)) return; // already present\n this.roster.push({ player, from: atFrame, until: Infinity });\n this.buffer.addPlayer(player);\n for (let f = atFrame; f < atFrame + this.config.inputDelay; f++) this.buffer.set(player, f, []);\n }\n\n /** All peers must call this with the SAME atFrame. */\n removePlayer(player: PlayerId, atFrame: number): void {\n const entry = this.roster.find((r) => r.player === player && r.until === Infinity);\n if (entry) entry.until = atFrame;\n // Frames at/after the cutoff must never merge, even if they arrived.\n this.buffer.clearFrom(player, atFrame);\n }\n\n // \u2500\u2500 driving the sim \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n get frame(): number {\n return this.world.frame;\n }\n\n /** Highest frame every currently-active player's input is known for. */\n get confirmedFrame(): number {\n let min = Infinity;\n for (const p of this.activePlayers(this.world.frame)) min = Math.min(min, this.buffer.contiguousThrough(p));\n return min === Infinity ? -1 : min;\n }\n\n get stalls(): number {\n return this.stallCount;\n }\n\n /**\n * Try to advance exactly one frame with the local player's current actions.\n * Returns 1 if the world stepped, 0 if blocked waiting for a remote input.\n */\n tick(localActions: readonly string[] = []): number {\n if (this.desynced) return 0;\n const f = this.world.frame;\n this.scheduleLocal(localActions);\n\n const active = this.activePlayers(f);\n for (const p of active) {\n if (!this.buffer.has(p, f)) {\n this.stallCount++;\n this.onStall?.(p, f);\n return 0;\n }\n }\n\n const inputs = new Map<PlayerId, readonly string[]>();\n for (const p of active) inputs.set(p, this.buffer.get(p, f)!);\n const merged = mergePlayerFrames(active, inputs);\n this.world.step(merged);\n this.mergedLog.push(merged);\n this.afterStep(this.world.frame);\n return 1;\n }\n\n /**\n * Feed real elapsed ms (the browser loop's dt). Runs the fixed steps the\n * clock grants \u2014 stalling drops time (the sim slows rather than desyncs) \u2014\n * then catches up if we're measurably behind the other peers.\n */\n advance(realMs: number, localActions: readonly string[] = []): number {\n let stepped = 0;\n const steps = this.world.clock.advance(realMs);\n for (let i = 0; i < steps; i++) {\n if (this.tick(localActions) === 0) break;\n stepped++;\n }\n // Catch-up: if remote inputs prove peers are ahead, step extra frames now.\n let guard = 0;\n while (guard++ < 8 && this.world.frame < this.remoteFrameEstimate() && this.tick(localActions) === 1) stepped++;\n return stepped;\n }\n\n /** The merged input log from startFrame \u2014 replayable when startFrame is 0. */\n inputLog(): InputLog {\n return { frames: this.mergedLog.map((f) => f.slice()) };\n }\n\n dispose(): void {\n this.unsubscribe();\n }\n\n /** Feed a raw transport message that arrived before this session existed. */\n deliver(data: string): void {\n this.receive(data);\n }\n\n /** Subscribe to \"the world just reached frame N\" (room layer uses this). */\n onAfterStep(cb: (frame: number) => void): () => void {\n this.afterStepListeners.push(cb);\n return () => {\n this.afterStepListeners = this.afterStepListeners.filter((l) => l !== cb);\n };\n }\n\n // \u2500\u2500 internals \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n private scheduleLocal(localActions: readonly string[]): void {\n const target = this.world.frame + this.config.inputDelay;\n if (this.sentThrough >= target) return;\n while (this.sentThrough < target) {\n this.sentThrough++;\n this.buffer.set(this.localPlayer, this.sentThrough, localActions);\n }\n // Send a small window ending at the newest frame so one lost message\n // cannot stall the room.\n const from = Math.max(this.startFrame, target - this.config.redundancy + 1);\n const frames: string[][] = [];\n for (let f = from; f <= target; f++) frames.push(this.buffer.get(this.localPlayer, f) ?? []);\n this.transport.send(encodeMessage(netMessage({ t: 'input', player: this.localPlayer, from, frames })));\n }\n\n private afterStep(frame: number): void {\n if (frame % this.config.hashInterval === 0) {\n const hash = this.world.hash();\n this.localHashes.set(frame, hash);\n this.transport.send(encodeMessage(netMessage({ t: 'hash', player: this.localPlayer, frame, hash })));\n this.checkPendingHashes();\n }\n // Memory hygiene: keep a generous tail, drop ancient history.\n if (frame % 64 === 0) {\n this.buffer.prune(frame - 128);\n for (const f of this.localHashes.keys()) if (f < frame - 512) this.localHashes.delete(f);\n }\n for (const cb of this.afterStepListeners) cb(frame);\n }\n\n private receive(data: string): void {\n const msg = decodeMessage(data);\n if (!msg) return;\n if (msg.t === 'input' && msg.player !== this.localPlayer) {\n for (let i = 0; i < msg.frames.length; i++) this.buffer.set(msg.player, msg.from + i, msg.frames[i]);\n } else if (msg.t === 'hash' && msg.player !== this.localPlayer) {\n this.pendingRemoteHashes.push({ player: msg.player, frame: msg.frame, hash: msg.hash });\n this.checkPendingHashes();\n }\n }\n\n private checkPendingHashes(): void {\n const still: typeof this.pendingRemoteHashes = [];\n for (const remote of this.pendingRemoteHashes) {\n const local = this.localHashes.get(remote.frame);\n if (local === undefined) {\n // We haven't reached (or have already pruned) that frame \u2014 keep it\n // unless it is ancient.\n if (remote.frame > this.world.frame - 512) still.push(remote);\n continue;\n }\n if (local !== remote.hash && !this.desynced) {\n this.desynced = true;\n this.onDesync?.({\n frame: remote.frame,\n player: remote.player,\n localHash: local,\n remoteHash: remote.hash,\n log: this.inputLog(),\n startFrame: this.startFrame,\n });\n }\n }\n this.pendingRemoteHashes = still;\n }\n\n private remoteFrameEstimate(): number {\n let max = -1;\n for (const entry of this.roster) {\n if (entry.player === this.localPlayer || entry.until !== Infinity) continue;\n // A peer schedules input `inputDelay` ahead of its sim frame.\n max = Math.max(max, this.buffer.contiguousThrough(entry.player) - this.config.inputDelay);\n }\n return max;\n }\n}\n", "// Predict-rollback netcode (GGPO/Rune-style) on top of the engine's proven\n// snapshot/restore. Every frame: send local input immediately, predict remote\n// inputs (repeat-last), step. When a real input contradicts a prediction,\n// restore the snapshot at the mispredicted frame and re-simulate to the\n// present with corrected inputs. `assertSnapshotStable` already proves\n// restore is lossless, so a rollback is exactly \"rewind + replay\".\n//\n// One engine-specific caveat: `World.restore()` rebuilds the scene tree from\n// data, and behaviors (closures) do not survive that. Games played under\n// rollback must either keep all sim logic in `world.state` + `onProcess`-free\n// nodes, or pass `attach(world)` to re-wire behaviors after every restore \u2014\n// the same hook scene code already uses for save/load.\n\nimport type { World, WorldSnapshot } from '../world';\nimport type { InputLog } from '../input/actions';\nimport { hashValue } from '../core/hash';\nimport { InputBuffer } from './inputBuffer';\nimport { mergePlayerFrames, type PlayerId } from './players';\nimport { DEFAULT_SESSION_CONFIG, decodeMessage, encodeMessage, netMessage, type NetSessionConfig } from './protocol';\nimport type { Transport } from './transport';\nimport type { DesyncInfo } from './lockstep';\n\nexport interface RollbackOptions {\n world: World;\n transport: Transport;\n localPlayer: PlayerId;\n players: PlayerId[];\n config?: Partial<NetSessionConfig>;\n /** Re-attach behaviors/controllers after every restore (save/load hook). */\n attach?: (world: World) => void;\n onDesync?: (info: DesyncInfo) => void;\n /** A correction arrived deeper than maxRollback \u2014 unrecoverable. */\n onRollbackOverflow?: (frame: number) => void;\n}\n\ninterface RingEntry {\n frame: number;\n snap: WorldSnapshot;\n}\n\nexport class RollbackSession {\n readonly world: World;\n readonly localPlayer: PlayerId;\n readonly config: NetSessionConfig;\n\n private readonly transport: Transport;\n private readonly players: PlayerId[];\n private readonly buffer = new InputBuffer();\n private readonly attach?: (world: World) => void;\n private readonly onDesync?: (info: DesyncInfo) => void;\n private readonly onRollbackOverflow?: (frame: number) => void;\n\n /** Snapshot AT frame f (state before stepping f), keyed f % ring length. */\n private ring: Array<RingEntry | null>;\n /** What we actually fed `step()` per frame \u2014 prediction bookkeeping. */\n private usedInputs = new Map<number, Map<PlayerId, string>>();\n private earliestBad = Infinity;\n private rollbackCount = 0;\n private resimulatedFrames = 0;\n private localHashes = new Map<number, string>();\n /** player \u2192 cutoff frame: their inputs are [] from there on (departed). */\n private dropped = new Map<PlayerId, number>();\n private pendingRemoteHashes: Array<{ player: PlayerId; frame: number; hash: string }> = [];\n private hashedThrough = -1;\n private desynced = false;\n private overflowed = false;\n private unsubscribe: () => void;\n\n constructor(opts: RollbackOptions) {\n this.world = opts.world;\n this.transport = opts.transport;\n this.localPlayer = opts.localPlayer;\n this.players = [...opts.players];\n this.config = { ...DEFAULT_SESSION_CONFIG, mode: 'rollback', inputDelay: 0, ...opts.config };\n this.attach = opts.attach;\n this.onDesync = opts.onDesync;\n this.onRollbackOverflow = opts.onRollbackOverflow;\n this.ring = new Array(this.config.maxRollback + 1).fill(null);\n for (const p of this.players) this.buffer.addPlayer(p);\n this.unsubscribe = this.transport.onMessage((data) => this.receive(data));\n }\n\n get frame(): number {\n return this.world.frame;\n }\n\n /** Highest frame all players' real inputs are known for (inclusive). */\n get confirmedFrame(): number {\n let min = Infinity;\n for (const p of this.players) {\n const cut = this.dropped.get(p);\n let c = this.buffer.contiguousThrough(p);\n // A departed player's inputs are [] forever from the cutoff \u2014 known.\n if (cut !== undefined && c >= cut - 1) c = Infinity;\n min = Math.min(min, c);\n }\n return min === Infinity ? -1 : min;\n }\n\n /** Highest contiguous frame received from `player` \u2014 the drop-cutoff basis. */\n lastKnownFrame(player: PlayerId): number {\n return this.buffer.contiguousThrough(player);\n }\n\n /**\n * A player left (or vanished): their inputs are [] from `atFrame` on, so the\n * session stops waiting on them. All peers must apply the SAME atFrame (the\n * room layer broadcasts it). Frames already simulated with a non-empty\n * prediction for the departed player roll back and re-simulate as usual.\n */\n removePlayer(player: PlayerId, atFrame: number): void {\n if (player === this.localPlayer || this.dropped.has(player)) return;\n this.dropped.set(player, atFrame);\n // Inputs at/after the cutoff must never merge, even if they arrived.\n this.buffer.clearFrom(player, atFrame);\n for (let f = atFrame; f < this.world.frame; f++) {\n const used = this.usedInputs.get(f)?.get(player);\n if (used !== undefined && used !== '[]') this.earliestBad = Math.min(this.earliestBad, f);\n }\n this.settleHashes();\n }\n\n get stats(): { rollbacks: number; resimulatedFrames: number } {\n return { rollbacks: this.rollbackCount, resimulatedFrames: this.resimulatedFrames };\n }\n\n /**\n * Advance one frame: publish local input, apply any pending correction,\n * then step with confirmed-or-predicted inputs. Returns 1 unless the sim\n * has outrun its rollback window (backpressure) or is desynced.\n */\n tick(localActions: readonly string[] = []): number {\n if (this.desynced || this.overflowed) return 0;\n const f = this.world.frame;\n\n // Backpressure: never outrun the ring \u2014 a correction must always land.\n if (f - (this.confirmedFrame + 1) >= this.config.maxRollback) return 0;\n\n this.publishLocal(f, localActions);\n if (!this.resolveCorrections()) return 0;\n\n this.storeSnapshot(f);\n this.stepFrame(f);\n this.settleHashes();\n if (f % 64 === 0) this.pruneOld(f);\n return 1;\n }\n\n /** Feed real elapsed ms; runs the fixed steps the clock grants. */\n advance(realMs: number, localActions: readonly string[] = []): number {\n let stepped = 0;\n const steps = this.world.clock.advance(realMs);\n for (let i = 0; i < steps; i++) {\n if (this.tick(localActions) === 0) break;\n stepped++;\n }\n return stepped;\n }\n\n /** Merged CONFIRMED input log from frame 0 \u2014 replayable ground truth. */\n inputLog(): InputLog {\n const frames: string[][] = [];\n const through = this.confirmedFrame;\n for (let f = 0; f <= through; f++) {\n const inputs = new Map<PlayerId, readonly string[]>();\n for (const p of this.players) inputs.set(p, this.buffer.get(p, f) ?? []);\n frames.push(mergePlayerFrames(this.players, inputs));\n }\n return { frames };\n }\n\n dispose(): void {\n this.unsubscribe();\n }\n\n /** Feed a raw transport message that arrived before this session existed. */\n deliver(data: string): void {\n this.receive(data);\n }\n\n // \u2500\u2500 internals \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n private publishLocal(frame: number, actions: readonly string[]): void {\n if (!this.buffer.set(this.localPlayer, frame, actions)) return;\n const from = Math.max(0, frame - this.config.redundancy + 1);\n const frames: string[][] = [];\n for (let f = from; f <= frame; f++) frames.push(this.buffer.get(this.localPlayer, f) ?? []);\n this.transport.send(encodeMessage(netMessage({ t: 'input', player: this.localPlayer, from, frames })));\n }\n\n private inputsFor(frame: number): Map<PlayerId, readonly string[]> {\n const inputs = new Map<PlayerId, readonly string[]>();\n for (const p of this.players) {\n const cut = this.dropped.get(p);\n if (cut !== undefined && frame >= cut) inputs.set(p, []);\n else inputs.set(p, this.buffer.get(p, frame) ?? this.buffer.latestAt(p, frame));\n }\n return inputs;\n }\n\n private stepFrame(frame: number): void {\n const inputs = this.inputsFor(frame);\n const used = new Map<PlayerId, string>();\n for (const p of this.players) used.set(p, JSON.stringify(inputs.get(p)));\n this.usedInputs.set(frame, used);\n this.world.step(mergePlayerFrames(this.players, inputs));\n }\n\n /** Apply pending corrections. False = overflow (fatal). */\n private resolveCorrections(): boolean {\n if (this.earliestBad === Infinity) return true;\n const target = this.world.frame;\n const bad = this.earliestBad;\n this.earliestBad = Infinity;\n\n const entry = this.ring[bad % this.ring.length];\n if (!entry || entry.frame !== bad) {\n this.overflowed = true;\n this.onRollbackOverflow?.(bad);\n return false;\n }\n\n this.rollbackCount++;\n this.world.restore(entry.snap);\n this.attach?.(this.world);\n for (let f = bad; f < target; f++) {\n this.storeSnapshot(f);\n this.stepFrame(f);\n this.resimulatedFrames++;\n }\n return true;\n }\n\n private storeSnapshot(frame: number): void {\n this.ring[frame % this.ring.length] = { frame, snap: this.world.snapshot() };\n }\n\n private receive(data: string): void {\n const msg = decodeMessage(data);\n if (!msg) return;\n if (msg.t === 'input' && msg.player !== this.localPlayer) {\n const cut = this.dropped.get(msg.player);\n for (let i = 0; i < msg.frames.length; i++) {\n const frame = msg.from + i;\n if (cut !== undefined && frame >= cut) continue; // post-cutoff never merges\n if (!this.buffer.set(msg.player, frame, msg.frames[i])) continue;\n // Did we already simulate this frame with a different guess?\n if (frame < this.world.frame) {\n const used = this.usedInputs.get(frame)?.get(msg.player);\n const actual = JSON.stringify([...msg.frames[i]].sort());\n if (used !== undefined && used !== actual) this.earliestBad = Math.min(this.earliestBad, frame);\n }\n }\n this.settleHashes();\n } else if (msg.t === 'hash' && msg.player !== this.localPlayer) {\n this.pendingRemoteHashes.push({ player: msg.player, frame: msg.frame, hash: msg.hash });\n this.compareHashes();\n }\n }\n\n /**\n * Hash exchange runs on CONFIRMED frames only (predicted state is\n * provisional by design). A snapshot has exactly the shape `world.hash()`\n * hashes, so ring entries give us hashes of past frames for free.\n */\n private settleHashes(): void {\n // Frames \u2264 confirmed+? \u2014 state AT frame h is confirmed once every input\n // for frames < h is known and no correction below h is pending.\n const settled = Math.min(this.confirmedFrame + 1, this.world.frame, this.earliestBad === Infinity ? Infinity : this.earliestBad);\n const interval = this.config.hashInterval;\n let h = (Math.floor(this.hashedThrough / interval) + 1) * interval;\n for (; h <= settled; h += interval) {\n const entry = this.ring[h % this.ring.length];\n if (!entry || entry.frame !== h) continue; // already recycled \u2014 skip\n const hash = hashValue(entry.snap);\n this.localHashes.set(h, hash);\n this.hashedThrough = h;\n this.transport.send(encodeMessage(netMessage({ t: 'hash', player: this.localPlayer, frame: h, hash })));\n }\n this.compareHashes();\n }\n\n private compareHashes(): void {\n const still: typeof this.pendingRemoteHashes = [];\n for (const remote of this.pendingRemoteHashes) {\n const local = this.localHashes.get(remote.frame);\n if (local === undefined) {\n if (remote.frame > this.hashedThrough - 512) still.push(remote);\n continue;\n }\n if (local !== remote.hash && !this.desynced) {\n this.desynced = true;\n this.onDesync?.({\n frame: remote.frame,\n player: remote.player,\n localHash: local,\n remoteHash: remote.hash,\n log: this.inputLog(),\n startFrame: 0,\n });\n }\n }\n this.pendingRemoteHashes = still;\n }\n\n private pruneOld(frame: number): void {\n this.buffer.prune(frame - 128);\n for (const f of this.usedInputs.keys()) if (f < frame - 128) this.usedInputs.delete(f);\n for (const f of this.localHashes.keys()) if (f < frame - 512) this.localHashes.delete(f);\n }\n}\n", "// The room layer: who is in the game, what seed it runs, when it starts.\n// Star topology over a bus transport \u2014 one endpoint is the RoomHost (assigns\n// player ids, dictates seed + session config, orchestrates late joins and\n// leaves); everyone else is a RoomClient. Both end up owning the same thing:\n// a World plus a running net session.\n//\n// Late join (lockstep only): the host schedules the newcomer at a future\n// frame, snapshots the world exactly when it reaches that frame, and ships\n// the snapshot; every peer adds the player at the same agreed frame, so all\n// rosters stay identical. Rollback rooms reject late joins \u2014 a joiner would\n// need a *confirmed* snapshot, which is future work.\n\nimport type { World, WorldSnapshot } from '../world';\nimport type { PlayerId } from './players';\nimport {\n DEFAULT_SESSION_CONFIG,\n decodeMessage,\n encodeMessage,\n netMessage,\n type NetMessage,\n type NetSessionConfig,\n} from './protocol';\nimport type { Transport } from './transport';\nimport { LockstepSession, type DesyncInfo } from './lockstep';\nimport { RollbackSession } from './rollback';\n\n/** A live networked game, the same shape on host and client. */\nexport interface NetGame {\n world: World;\n session: LockstepSession | RollbackSession;\n localPlayer: PlayerId;\n /** Roster at the time the game handle was created. */\n players: PlayerId[];\n /** Drive this from the render loop instead of world.advance(). */\n advance(realMs: number, localActions?: readonly string[]): number;\n dispose(): void;\n}\n\nexport interface RoomCallbacks {\n onDesync?: (info: DesyncInfo) => void;\n onPlayerJoin?: (player: PlayerId, atFrame: number) => void;\n onPlayerLeave?: (player: PlayerId, atFrame: number) => void;\n}\n\nfunction makeUid(): string {\n return globalThis.crypto.randomUUID();\n}\n\nfunction buildSession(\n mode: NetSessionConfig['mode'],\n world: World,\n transport: Transport,\n localPlayer: PlayerId,\n players: PlayerId[],\n startFrame: number,\n config: NetSessionConfig,\n attach: ((world: World) => void) | undefined,\n callbacks: RoomCallbacks,\n): LockstepSession | RollbackSession {\n if (mode === 'rollback') {\n return new RollbackSession({ world, transport, localPlayer, players, config, attach, onDesync: callbacks.onDesync });\n }\n return new LockstepSession({ world, transport, localPlayer, players, startFrame, config, onDesync: callbacks.onDesync });\n}\n\nfunction makeGame(\n world: World,\n session: LockstepSession | RollbackSession,\n localPlayer: PlayerId,\n players: PlayerId[],\n extraDispose?: () => void,\n): NetGame {\n return {\n world,\n session,\n localPlayer,\n players,\n advance: (realMs, localActions = []) => session.advance(realMs, localActions),\n dispose: () => {\n session.dispose();\n extraDispose?.();\n },\n };\n}\n\n// \u2500\u2500 host \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport interface RoomHostOptions extends RoomCallbacks {\n transport: Transport;\n /** Build the deterministic world every peer will run. */\n makeWorld: (seed: number) => World;\n seed?: number;\n config?: Partial<NetSessionConfig>;\n maxPlayers?: number;\n /** Frames between \"a joiner exists\" and their first live frame. */\n joinMargin?: number;\n /** Re-attach behaviors after restore (rollback / late-join snapshot). */\n attach?: (world: World) => void;\n}\n\nexport class RoomHost {\n readonly localPlayer: PlayerId = 'p1';\n readonly seed: number;\n readonly config: NetSessionConfig;\n\n private readonly transport: Transport;\n private readonly makeWorld: (seed: number) => World;\n private readonly maxPlayers: number;\n private readonly joinMargin: number;\n private readonly attach?: (world: World) => void;\n private readonly callbacks: RoomCallbacks;\n\n private players: PlayerId[] = ['p1'];\n private uidToPlayer = new Map<string, PlayerId>();\n private nextPlayerIndex = 2;\n private started = false;\n private game: NetGame | null = null;\n private pendingSnapshots: Array<{ uid: string; player: PlayerId; atFrame: number }> = [];\n private unsubscribe: () => void;\n\n constructor(opts: RoomHostOptions) {\n this.transport = opts.transport;\n this.makeWorld = opts.makeWorld;\n this.seed = opts.seed ?? 1;\n this.config = { ...DEFAULT_SESSION_CONFIG, ...opts.config };\n this.maxPlayers = opts.maxPlayers ?? 4;\n this.joinMargin = opts.joinMargin ?? 30;\n this.attach = opts.attach;\n this.callbacks = opts;\n this.unsubscribe = this.transport.onMessage((data) => this.receive(data));\n }\n\n /** Players currently in the room (host first). */\n get roster(): PlayerId[] {\n return [...this.players];\n }\n\n get isStarted(): boolean {\n return this.started;\n }\n\n /** Freeze the roster's frame 0 and begin simulating. */\n start(): NetGame {\n if (this.game) return this.game;\n this.started = true;\n const world = this.makeWorld(this.seed);\n const session = buildSession(\n this.config.mode,\n world,\n this.transport,\n this.localPlayer,\n this.players,\n 0,\n this.config,\n this.attach,\n this.callbacks,\n );\n if (session instanceof LockstepSession) {\n session.onAfterStep((frame) => this.serviceSnapshots(frame, world));\n }\n this.transport.send(encodeMessage(netMessage({ t: 'start', players: [...this.players] })));\n this.game = makeGame(world, session, this.localPlayer, this.players, () => this.unsubscribe());\n return this.game;\n }\n\n /** Announce a player's departure (disconnect handling is the app's call). */\n dropPlayer(player: PlayerId): void {\n const session = this.game?.session;\n if (!session) return;\n // Cut at the first frame nobody can have merged yet: one past the last\n // contiguous input everyone received from the departed player. Peers on a\n // reliable bus share the same received set, so the cutoff is consistent.\n // Rollback peers may already have PREDICTED past the cutoff \u2014 that's an\n // ordinary misprediction; removePlayer rolls back and re-simulates.\n const atFrame =\n session instanceof LockstepSession\n ? Math.max(session.frame, session.confirmedFrame + 1)\n : session.lastKnownFrame(player) + 1;\n this.transport.send(encodeMessage(netMessage({ t: 'leave', player, atFrame })));\n session.removePlayer(player, atFrame);\n this.players = this.players.filter((p) => p !== player);\n this.callbacks.onPlayerLeave?.(player, atFrame);\n }\n\n dispose(): void {\n this.unsubscribe();\n this.game?.dispose();\n }\n\n // \u2500\u2500 internals \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n private receive(data: string): void {\n const msg = decodeMessage(data);\n if (!msg) return;\n if (msg.t === 'hello') this.handleHello(msg);\n else if (msg.t === 'bye') {\n const player = this.uidToPlayer.get(msg.uid);\n if (player && this.started) this.dropPlayer(player);\n else if (player) {\n this.players = this.players.filter((p) => p !== player);\n this.uidToPlayer.delete(msg.uid);\n }\n }\n }\n\n private handleHello(msg: Extract<NetMessage, { t: 'hello' }>): void {\n if (this.uidToPlayer.has(msg.uid)) return; // duplicate hello \u2014 already welcomed\n if (this.players.length >= this.maxPlayers) {\n this.transport.send(encodeMessage(netMessage({ t: 'deny', to: msg.uid, reason: 'room full' })));\n return;\n }\n if (this.started && this.config.mode === 'rollback') {\n this.transport.send(encodeMessage(netMessage({ t: 'deny', to: msg.uid, reason: 'rollback rooms cannot be joined mid-game' })));\n return;\n }\n\n const player: PlayerId = `p${this.nextPlayerIndex++}`;\n this.uidToPlayer.set(msg.uid, player);\n this.players.push(player);\n\n if (!this.started) {\n this.transport.send(\n encodeMessage(\n netMessage({\n t: 'welcome',\n to: msg.uid,\n player,\n players: [...this.players],\n seed: this.seed,\n config: this.config,\n startFrame: 0,\n }),\n ),\n );\n this.callbacks.onPlayerJoin?.(player, 0);\n return;\n }\n\n // Late join: everyone (including us) adds the player at a future frame;\n // the snapshot ships when the host's world actually reaches it.\n const session = this.game!.session as LockstepSession;\n const atFrame = session.frame + this.joinMargin;\n this.transport.send(encodeMessage(netMessage({ t: 'join', player, atFrame })));\n session.addPlayer(player, atFrame);\n this.pendingSnapshots.push({ uid: msg.uid, player, atFrame });\n this.callbacks.onPlayerJoin?.(player, atFrame);\n }\n\n private serviceSnapshots(frame: number, world: World): void {\n if (this.pendingSnapshots.length === 0) return;\n const due = this.pendingSnapshots.filter((p) => p.atFrame === frame);\n if (due.length === 0) return;\n this.pendingSnapshots = this.pendingSnapshots.filter((p) => p.atFrame !== frame);\n const snapshot: WorldSnapshot = world.snapshot();\n for (const join of due) {\n // Joiners scheduled but not yet live go in `joins`, not the roster \u2014\n // the newcomer must add them at THEIR frame, not its own startFrame.\n const stillPending = this.pendingSnapshots.filter((p) => p.player !== join.player);\n const pendingIds = new Set(stillPending.map((p) => p.player));\n this.transport.send(\n encodeMessage(\n netMessage({\n t: 'welcome',\n to: join.uid,\n player: join.player,\n players: this.players.filter((p) => !pendingIds.has(p)),\n seed: this.seed,\n config: this.config,\n startFrame: frame,\n snapshot,\n joins: stillPending.map((p) => ({ player: p.player, atFrame: p.atFrame })),\n }),\n ),\n );\n }\n }\n}\n\n// \u2500\u2500 client \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport interface RoomClientOptions extends RoomCallbacks {\n transport: Transport;\n makeWorld: (seed: number) => World;\n attach?: (world: World) => void;\n name?: string;\n}\n\n/**\n * Join a room: send hello, wait for welcome (+start or snapshot), come back\n * with a NetGame. Session-layer messages that arrive while the snapshot is in\n * flight are buffered and replayed so no input is ever missed.\n */\nexport function joinRoom(opts: RoomClientOptions): Promise<NetGame> {\n const uid = makeUid();\n const transport = opts.transport;\n\n return new Promise((resolve, reject) => {\n let welcome: Extract<NetMessage, { t: 'welcome' }> | null = null;\n let started = false;\n /** Final frame-0 roster from `start` (a lobby can grow after our welcome). */\n let startRoster: PlayerId[] | null = null;\n const buffered: string[] = [];\n const pendingRoster: Array<Extract<NetMessage, { t: 'join' } | { t: 'leave' }>> = [];\n\n const finish = () => {\n if (!welcome || !started) return;\n unsub();\n const roster = startRoster ?? welcome.players;\n const world = opts.makeWorld(welcome.seed);\n if (welcome.snapshot) {\n world.restore(welcome.snapshot);\n opts.attach?.(world);\n }\n const session = buildSession(\n welcome.config.mode,\n world,\n transport,\n welcome.player,\n roster,\n welcome.startFrame,\n welcome.config,\n opts.attach,\n opts,\n );\n // Joins the host announced before our welcome (still-pending joiners):\n if (welcome.joins && session instanceof LockstepSession) {\n for (const j of welcome.joins) session.addPlayer(j.player, j.atFrame);\n }\n // Roster changes and inputs that raced past us while restoring:\n for (const m of pendingRoster) {\n if (m.t === 'join' && session instanceof LockstepSession) session.addPlayer(m.player, m.atFrame);\n if (m.t === 'leave') session.removePlayer(m.player, m.atFrame);\n }\n const roomUnsub = transport.onMessage((data) => {\n const msg = decodeMessage(data);\n if (!msg) return;\n if (msg.t === 'join' && session instanceof LockstepSession) {\n session.addPlayer(msg.player, msg.atFrame);\n opts.onPlayerJoin?.(msg.player, msg.atFrame);\n } else if (msg.t === 'leave') {\n session.removePlayer(msg.player, msg.atFrame);\n opts.onPlayerLeave?.(msg.player, msg.atFrame);\n }\n });\n const game = makeGame(world, session, welcome.player, roster, () => {\n roomUnsub();\n transport.send(encodeMessage(netMessage({ t: 'bye', uid })));\n });\n // Replay whatever the session missed while the snapshot was in flight.\n for (const data of buffered) session.deliver(data);\n resolve(game);\n };\n\n const unsub = transport.onMessage((data) => {\n const msg = decodeMessage(data);\n if (!msg) return;\n switch (msg.t) {\n case 'welcome':\n if (msg.to === uid) {\n welcome = msg;\n // A snapshot welcome means the game is already running.\n if (msg.snapshot || msg.startFrame > 0) started = true;\n finish();\n }\n break;\n case 'deny':\n if (msg.to === uid) {\n unsub();\n reject(new Error(`hayao-net: join denied \u2014 ${msg.reason}`));\n }\n break;\n case 'start':\n started = true;\n startRoster = msg.players;\n finish();\n break;\n case 'join':\n case 'leave':\n pendingRoster.push(msg);\n break;\n case 'input':\n case 'hash':\n buffered.push(data);\n break;\n }\n });\n\n transport.send(encodeMessage(netMessage({ t: 'hello', uid, name: opts.name })));\n });\n}\n\n/** Create a room host over a transport. Call `start()` when the lobby is set. */\nexport function hostRoom(opts: RoomHostOptions): RoomHost {\n return new RoomHost(opts);\n}\n", "// The World: the deterministic simulation container. Owns the root scene, the\n// rng, the clock, the input state, an event bus, and a resource table. Advancing\n// the world is `step()` \u2014 a pure function of (previous state, input frame).\n\nimport { Clock, type ClockConfig } from './core/clock';\nimport { EventBus } from './core/events';\nimport { hashValue } from './core/hash';\nimport { Rng } from './core/rng';\nimport { InputState } from './input/actions';\nimport { Node, resetNodeIds, type WorldContext } from './scene/node';\nimport { deserializeNode } from './scene/registry';\nimport type { Camera2D } from './scene/nodes';\nimport { IDENTITY, composeTransform, invertTransform, makeTransform, type Transform } from './core/math';\nimport type { DrawCommand } from './render/commands';\n\nexport interface WorldConfig {\n seed?: number;\n clock?: ClockConfig;\n /** Design-space dimensions (default 1280\u00D7720). */\n width?: number;\n height?: number;\n}\n\n/** Default engine event map; games extend it with their own keys. */\nexport interface CoreEvents {\n [key: string]: unknown;\n}\n\nexport class World implements WorldContext {\n readonly rng: Rng;\n readonly clock: Clock;\n readonly input = new InputState();\n readonly events = new EventBus<CoreEvents>();\n readonly resources = new Map<string, unknown>();\n /**\n * Canonical game state that lives OUTSIDE the scene tree (pure-sim structs,\n * controllers). Must be plain JSON-serializable data: it is included in\n * `hash()` and `snapshot()`, so hidden state here cannot escape determinism\n * checks the way ad-hoc module variables can.\n */\n state: Record<string, unknown> = {};\n readonly width: number;\n readonly height: number;\n\n root: Node;\n activeCamera: Camera2D | null = null;\n\n private seed: number;\n private freeQueue: Node[] = [];\n private started = false;\n\n constructor(config: WorldConfig = {}) {\n this.seed = config.seed ?? 1;\n this.rng = new Rng(this.seed);\n this.clock = new Clock(config.clock);\n this.width = config.width ?? 1280;\n this.height = config.height ?? 720;\n this.root = new Node({ name: 'root' });\n }\n\n get time(): number {\n return this.clock.simTimeSec;\n }\n get frame(): number {\n return this.clock.frame;\n }\n\n /** Replace the scene root, entering the tree. */\n setRoot(node: Node): void {\n if (this.root) this.root.exitTree();\n this.root = node;\n this.started = false;\n }\n\n requestFree(node: Node): void {\n this.freeQueue.push(node);\n }\n\n private ensureStarted(): void {\n if (!this.started) {\n this.root.enterTree(this);\n this.started = true;\n }\n }\n\n /**\n * Advance exactly one fixed step with the given actions held down.\n * This is THE deterministic transition \u2014 call it from Node or the browser loop.\n */\n step(actionsDown: Iterable<string> = []): void {\n this.ensureStarted();\n this.input.beginFrame(actionsDown);\n this.root.updateTree(this.clock.dt);\n this.flushFree();\n this.clock.tick();\n }\n\n /** Feed real elapsed ms; runs 0+ fixed steps. Returns steps run. */\n advance(realMs: number, actionsDown: Iterable<string> = []): number {\n const steps = this.clock.advance(realMs);\n for (let i = 0; i < steps; i++) this.step(actionsDown);\n return steps;\n }\n\n private flushFree(): void {\n if (this.freeQueue.length === 0) return;\n const q = this.freeQueue;\n this.freeQueue = [];\n for (const node of q) {\n node.exitTree();\n node.parent?.removeChild(node);\n if (this.activeCamera === node) this.activeCamera = null;\n }\n }\n\n // \u2500\u2500 Rendering \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n /** The view transform (inverse of the active camera), mapping world \u2192 screen. */\n viewTransform(): Transform {\n if (!this.activeCamera) return IDENTITY;\n const cam = this.activeCamera;\n // Center the camera in design space, apply zoom, then invert.\n const camWorld = cam.worldTransform();\n const centered = composeTransform(makeTransform({ x: this.width / 2, y: this.height / 2 }, 0, { x: cam.zoom, y: cam.zoom }), invertTransform(camWorld));\n return centered;\n }\n\n /** Project the whole scene to a display list (already camera-applied). */\n render(): DrawCommand[] {\n this.ensureStarted();\n const out: DrawCommand[] = [];\n this.root.collectDraw(out, this.viewTransform());\n return out;\n }\n\n // \u2500\u2500 Determinism & saves \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n /** Deterministic structural hash of the whole sim state. */\n hash(): string {\n return hashValue({\n seed: this.seed,\n rng: this.rng.getState(),\n clock: this.clock.getState(),\n input: this.input.getState(),\n state: this.state,\n tree: this.root.serialize(),\n });\n }\n\n /** Compact snapshot for undo/time-travel and saves. */\n snapshot(): WorldSnapshot {\n return {\n seed: this.seed,\n rng: this.rng.getState(),\n clock: this.clock.getState(),\n input: this.input.getState(),\n state: structuredClone(this.state),\n tree: this.root.serialize(),\n };\n }\n\n /** Restore a snapshot. Rebuilds the tree from data (behaviors are re-attached by scene code). */\n restore(snap: WorldSnapshot): void {\n this.seed = snap.seed;\n this.rng.setState(snap.rng);\n this.clock.setState(snap.clock);\n this.input.setState(snap.input);\n this.state = structuredClone(snap.state);\n resetNodeIds(1_000_000); // avoid id collisions with the live session\n this.setRoot(deserializeNode(snap.tree));\n this.ensureStarted();\n }\n\n /** A compact probe snapshot for the verification harness (override-friendly). */\n probe(): Record<string, unknown> {\n return {\n frame: this.frame,\n time: this.time,\n hash: this.hash(),\n nodes: this.root.query('Sprite').length + this.root.query('Text').length,\n };\n }\n}\n\nexport interface WorldSnapshot {\n seed: number;\n rng: ReturnType<Rng['getState']>;\n clock: ReturnType<Clock['getState']>;\n input: ReturnType<InputState['getState']>;\n state: Record<string, unknown>;\n tree: ReturnType<Node['serialize']>;\n}\n", "// The project system. A game is a data definition: dimensions, input map, and a\n// build() that constructs the initial scene tree. `createWorld` turns it into a\n// live deterministic World \u2014 used identically by the browser driver, the headless\n// runner, and every test. That symmetry is the whole point.\n\nimport { World } from '../world';\nimport type { Node } from '../scene/node';\nimport { DEFAULT_INPUT_MAP, type InputLog, type InputMap } from '../input/actions';\nimport type { ClockConfig } from '../core/clock';\n\nexport interface GameDefinition {\n title: string;\n width?: number;\n height?: number;\n seed?: number;\n background?: string;\n clock?: ClockConfig;\n inputMap?: InputMap;\n /** Build the initial scene tree for a fresh world. */\n build(world: World): Node;\n /** Optional compact probe snapshot for verification (defaults to World.probe). */\n probe?(world: World): Record<string, unknown>;\n}\n\n/** Identity + defaults. Kept as a function so games read `export default defineGame({\u2026})`. */\nexport function defineGame(def: GameDefinition): Required<Pick<GameDefinition, 'width' | 'height' | 'seed' | 'inputMap' | 'background'>> & GameDefinition {\n return {\n width: 1280,\n height: 720,\n seed: 1,\n background: '#f3ecdb',\n inputMap: DEFAULT_INPUT_MAP,\n ...def,\n };\n}\n\n/** Build a live, deterministic World from a game definition. No browser needed. */\nexport function createWorld(def: GameDefinition, seedOverride?: number): World {\n const world = new World({\n seed: seedOverride ?? def.seed ?? 1,\n width: def.width ?? 1280,\n height: def.height ?? 720,\n clock: def.clock,\n });\n world.setRoot(def.build(world));\n if (def.probe) {\n // Instance override shadows the prototype method.\n (world as unknown as { probe: () => Record<string, unknown> }).probe = () => def.probe!(world);\n }\n return world;\n}\n\n/** The input map a game uses (with defaults applied). */\nexport function gameInputMap(def: GameDefinition): InputMap {\n return def.inputMap ?? DEFAULT_INPUT_MAP;\n}\n\nexport interface HeadlessResult {\n world: World;\n hash: string;\n steps: number;\n}\n\n/**\n * Run a game to completion in Node with no host \u2014 play an input log (or zero\n * steps) and return the final world + state hash. This is what tests, the CI\n * verifier, and replays call. The browser is never involved.\n */\nexport function runHeadless(def: GameDefinition, inputLog?: InputLog): HeadlessResult {\n const world = createWorld(def);\n const frames = inputLog?.frames ?? [];\n for (const f of frames) world.step(f);\n return { world, hash: world.hash(), steps: frames.length };\n}\n", "// Browser driver for networked games \u2014 the net twin of runBrowser(). Same\n// mount/renderer/input wiring, but the world is created only after the room\n// handshake settles the seed and roster, and the RAF loop drives\n// `session.advance()` (which gates steps on network input) instead of\n// `world.advance()`.\n\nimport type { GameDefinition } from '../app/game';\nimport { createWorld } from '../app/game';\nimport { KeyboardSource } from '../input/source';\nimport { SvgRenderer } from '../render/svg';\nimport { Canvas2DRenderer } from '../render/canvas';\nimport type { Renderer } from '../render/renderer';\nimport { setOverlayHost } from '../ui/overlay';\nimport type { World } from '../world';\nimport type { Transport } from './transport';\nimport type { NetSessionConfig } from './protocol';\nimport type { NetGame, RoomCallbacks } from './room';\nimport { hostRoom, joinRoom, type RoomHost } from './room';\nimport type { PlayerId } from './players';\n\nexport interface NetRunOptions extends RoomCallbacks {\n transport: Transport;\n /** 'host' owns the lobby (first tab); 'join' connects to it. */\n role: 'host' | 'join';\n seed?: number;\n config?: Partial<NetSessionConfig>;\n maxPlayers?: number;\n /** Re-attach behaviors after any restore (rollback / late join). */\n attach?: (world: World) => void;\n renderer?: 'svg' | 'canvas';\n /** Lobby feedback (\"waiting for players\u2026\", \"connected as p2\"). */\n onStatus?: (status: string) => void;\n}\n\nexport interface NetGameHandle {\n /** Host only: freeze the lobby and start the game. No-op for joiners. */\n start(): void;\n /** The live game once running (null while in the lobby). */\n readonly game: NetGame | null;\n readonly localPlayer: PlayerId | null;\n readonly roster: PlayerId[];\n input: KeyboardSource;\n stop(): void;\n}\n\n/**\n * Run a game as a networked session. Host flow: call, wait for peers\n * (onPlayerJoin fires), then `handle.start()`. Join flow: call \u2014 the render\n * loop begins automatically when the host starts (or immediately mid-game\n * via snapshot late join).\n */\nexport function runBrowserNet(def: GameDefinition, mount: HTMLElement, opts: NetRunOptions): NetGameHandle {\n const width = def.width ?? 1280;\n const height = def.height ?? 720;\n const background = def.background ?? '#f3ecdb';\n\n const renderer: Renderer =\n opts.renderer === 'canvas'\n ? new Canvas2DRenderer({ width, height, background })\n : new SvgRenderer({ width, height, background });\n mount.style.position = mount.style.position || 'relative';\n renderer.mount?.(mount);\n setOverlayHost(mount);\n\n const input = new KeyboardSource(def.inputMap ?? {}, document);\n const makeWorld = (seed: number) => createWorld(def, seed);\n\n let game: NetGame | null = null;\n let host: RoomHost | null = null;\n let raf = 0;\n let stopped = false;\n\n const loop = (last: number) => (now: number) => {\n if (!stopped && game) {\n const stepped = game.advance(now - last, input.currentActions());\n if (stepped > 0) input.clearPressed();\n renderer.draw(game.world.render());\n }\n raf = requestAnimationFrame(loop(now));\n };\n\n const begin = (g: NetGame) => {\n game = g;\n opts.onStatus?.(`playing as ${g.localPlayer} (${g.players.length} players)`);\n raf = requestAnimationFrame(loop(performance.now()));\n };\n\n if (opts.role === 'host') {\n host = hostRoom({\n transport: opts.transport,\n makeWorld,\n seed: opts.seed ?? def.seed ?? 1,\n config: opts.config,\n maxPlayers: opts.maxPlayers,\n attach: opts.attach,\n onDesync: opts.onDesync,\n onPlayerJoin: (p, f) => {\n opts.onStatus?.(`${p} joined`);\n opts.onPlayerJoin?.(p, f);\n },\n onPlayerLeave: opts.onPlayerLeave,\n });\n opts.onStatus?.('hosting \u2014 waiting for players');\n } else {\n opts.onStatus?.('joining\u2026');\n joinRoom({\n transport: opts.transport,\n makeWorld,\n attach: opts.attach,\n onDesync: opts.onDesync,\n onPlayerJoin: opts.onPlayerJoin,\n onPlayerLeave: opts.onPlayerLeave,\n })\n .then(begin)\n .catch((err: Error) => opts.onStatus?.(err.message));\n }\n\n return {\n start() {\n if (host && !game) begin(host.start());\n },\n get game() {\n return game;\n },\n get localPlayer() {\n return game?.localPlayer ?? (opts.role === 'host' ? 'p1' : null);\n },\n get roster() {\n return host?.roster ?? game?.players ?? [];\n },\n input,\n stop() {\n stopped = true;\n cancelAnimationFrame(raf);\n game?.dispose();\n host?.dispose();\n input.dispose();\n renderer.dispose?.();\n },\n };\n}\n", "// Browser driver: mounts a renderer, samples real input into the fixed-step\n// kernel, projects to the renderer each frame, and wires audio + the pause shell.\n// Wall-clock only feeds the accumulator (how many steps to run) \u2014 replays use the\n// input log, not wall time, so the sim stays deterministic.\n\nimport type { GameDefinition } from './game';\nimport { createWorld } from './game';\nimport { KeyboardSource } from '../input/source';\nimport { SvgRenderer } from '../render/svg';\nimport { Canvas2DRenderer } from '../render/canvas';\nimport type { Renderer } from '../render/renderer';\nimport { renderToSVGString } from '../render/svgString';\nimport { audio } from '../audio/audio';\nimport { settings } from '../ui/settings';\nimport { setOverlayHost } from '../ui/overlay';\nimport { Shell } from '../ui/shell';\nimport { installCapture, isCaptureMode } from '../verify/capture';\nimport type { World } from '../world';\n\nexport interface RunOptions {\n renderer?: 'svg' | 'canvas';\n /** Start the pause/settings shell (Esc). Default true. */\n shell?: boolean;\n onRestart?: () => void;\n}\n\nexport interface GameHandle {\n world: World;\n renderer: Renderer;\n /** The live input source \u2014 game UI calls input.press('action') for buttons. */\n input: KeyboardSource;\n stop(): void;\n restart(): void;\n}\n\nexport function runBrowser(def: GameDefinition, mount: HTMLElement, opts: RunOptions = {}): GameHandle {\n const width = def.width ?? 1280;\n const height = def.height ?? 720;\n const background = def.background ?? '#f3ecdb';\n\n let world = createWorld(def);\n const renderer: Renderer =\n opts.renderer === 'canvas'\n ? new Canvas2DRenderer({ width, height, background })\n : new SvgRenderer({ width, height, background });\n\n mount.style.position = mount.style.position || 'relative';\n renderer.mount?.(mount);\n setOverlayHost(mount);\n\n const input = new KeyboardSource(def.inputMap ?? {}, document);\n const capture = isCaptureMode();\n\n // Start audio on first user gesture (autoplay policy).\n const startAudio = () => {\n audio.start();\n const s = settings.get();\n audio.setVolumes(s);\n window.removeEventListener('pointerdown', startAudio);\n window.removeEventListener('keydown', startAudio);\n };\n window.addEventListener('pointerdown', startAudio);\n window.addEventListener('keydown', startAudio);\n\n const renderFrame = () => renderer.draw(world.render());\n const restart = () => {\n world = createWorld(def);\n renderFrame();\n };\n\n const shell =\n opts.shell === false\n ? null\n : new Shell({\n title: def.title,\n onRestart: opts.onRestart ?? restart,\n onPause: () => {},\n });\n\n let raf = 0;\n let last = performance.now();\n const loop = (now: number) => {\n const dt = now - last;\n last = now;\n if (!capture && !(shell?.isPaused)) {\n const steps = world.advance(dt, input.currentActions());\n if (steps > 0) input.clearPressed(); // virtual taps held until sampled\n }\n renderFrame();\n raf = requestAnimationFrame(loop);\n };\n raf = requestAnimationFrame(loop);\n\n const handle: GameHandle = {\n get world() {\n return world;\n },\n renderer,\n input,\n stop() {\n cancelAnimationFrame(raf);\n input.dispose();\n shell?.dispose();\n renderer.dispose?.();\n },\n restart,\n };\n\n if (capture) {\n installCapture({\n get world() {\n return world;\n },\n stepOnce: (actions = []) => {\n world.step(actions);\n renderFrame();\n },\n renderSVG: () => renderToSVGString(world.render(), width, height, background),\n setPaused: () => {},\n });\n }\n\n return handle;\n}\n", "// @hayao \u2014 the single public seam. Games and examples import ONLY from here.\n// Everything below the barrel is swappable; this file is the whole API surface,\n// greppable in one place (an AI-first invariant).\n\n// \u2500\u2500 core: the deterministic kernel \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport * from './core/math';\nexport * from './core/dmath';\nexport * from './core/rng';\nexport * from './core/clock';\nexport * from './core/events';\nexport * from './core/hash';\n\n// \u2500\u2500 scene: the Godot-style node tree \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport * from './scene/node';\n// Node2D is an alias for Node \u2014 the base node already carries a 2D transform.\nexport { Node as Node2D } from './scene/node';\nexport * from './scene/nodes';\nexport * from './scene/pool';\nexport * from './scene/tween';\nexport * from './scene/particles';\nexport * from './scene/floatingText';\nexport * from './scene/registry';\n\n// \u2500\u2500 input: actions, sampling, record/replay \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport * from './input/actions';\nexport * from './input/source';\n\n// \u2500\u2500 physics: tilemaps, kinematic AABB, character controllers \u2500\u2500\u2500\u2500\nexport * from './physics/tilemap';\nexport * from './physics/aabb';\nexport * from './physics/platformer';\nexport * from './physics/spatialHash';\nexport * from './physics/raycast';\n// \u2500\u2500 physics: rigid-body dynamics (plain-data world \u2192 hash/snapshot free) \u2500\nexport * from './physics/rigidBody';\nexport * from './physics/rigidCollide';\nexport * from './physics/rigidJoints';\nexport * from './physics/rigidStep';\nexport * from './physics/rigidQueries';\n\n// \u2500\u2500 render: display list + backends \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport * from './render/commands';\nexport * from './render/renderer';\nexport * from './render/svgString';\nexport * from './render/svg';\nexport * from './render/canvas';\nexport * from './render/headless';\nexport * from './render/nineSlice';\n\n// \u2500\u2500 art: code-as-art helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport * from './art/palette';\nexport * from './art/shapes';\nexport * from './art/texture';\nexport * from './art/font5';\nexport * from './art/bitmapFont';\nexport * from './art/autotile';\n\n// \u2500\u2500 procgen: deterministic generators + stateless scatter \u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport * from './procgen/grid';\nexport * from './procgen/scatter';\nexport * from './procgen/cave';\nexport * from './procgen/terrain';\nexport * from './procgen/rooms';\n\n// \u2500\u2500 audio \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport * from './audio/audio';\n\n// \u2500\u2500 ui: DOM overlays + shell + settings \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport * from './ui/overlay';\nexport * from './ui/settings';\nexport * from './ui/shell';\nexport * from './ui/transition';\n\n// \u2500\u2500 verify: the AI-first harness \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport * from './verify/solver';\nexport * from './verify/determinism';\nexport * from './verify/playthrough';\nexport * from './verify/capture';\nexport * from './verify/driver';\nexport * from './verify/bot';\nexport * from './verify/layout';\nexport * from './verify/feel';\nexport * from './verify/filmstrip';\n\n// \u2500\u2500 logic: pure engine primitives (FSM, weighted tables, graph search) \u2500\nexport * from './logic/fsm';\nexport * from './logic/random';\nexport * from './logic/graph';\nexport * from './logic/history';\n\n// \u2500\u2500 persist: save/load over a pluggable storage adapter + compact codecs \u2500\nexport * from './persist/storage';\nexport * from './persist/codec';\nexport * from './persist/save';\n\n// \u2500\u2500 content: data-driven wave/spawn directors + upgrade trees \u2500\u2500\u2500\nexport * from './content/dsl';\n\n// \u2500\u2500 net: deterministic multiplayer (lockstep / rollback) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport * from './net/players';\nexport * from './net/protocol';\nexport * from './net/transport';\nexport * from './net/inputBuffer';\nexport * from './net/lockstep';\nexport * from './net/rollback';\nexport * from './net/room';\nexport * from './net/browser';\n\n// \u2500\u2500 world + app \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport * from './world';\nexport * from './app/game';\nexport * from './app/browser';\n\n/** Engine version. */\nexport const VERSION = '0.2.0';\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["n", "n", "n", "mix", "n", "n", "at", "at", "dx", "dy", "n", "area", "n", "m", "i", "n", "k", "j", "ex", "ey", "nx", "ny", "vax", "vay", "vbx", "vby", "ix", "iy", "warm", "n", "n", "r", "n", "n", "n", "n", "n", "n", "smoothstep", "n", "hold", "overlaps", "n", "n", "n", "n", "active", "host"]
|
|
7
7
|
}
|