nuclo 0.2.35 → 0.2.36
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/nuclo.cjs +1 -1
- package/dist/nuclo.cjs.map +1 -1
- package/dist/nuclo.mjs +1 -1
- package/dist/nuclo.mjs.map +1 -1
- package/dist/nuclo.umd.js +1 -1
- package/dist/nuclo.umd.js.map +1 -1
- package/package.json +3 -3
- package/dist/bootstrap.d.ts +0 -5
- package/dist/bootstrap.d.ts.map +0 -1
- package/dist/element/attributes.d.ts +0 -6
- package/dist/element/attributes.d.ts.map +0 -1
- package/dist/element/class-name.d.ts +0 -6
- package/dist/element/class-name.d.ts.map +0 -1
- package/dist/element/event-attributes.d.ts +0 -5
- package/dist/element/event-attributes.d.ts.map +0 -1
- package/dist/element/events.d.ts +0 -46
- package/dist/element/events.d.ts.map +0 -1
- package/dist/element/factory-meta.d.ts +0 -27
- package/dist/element/factory-meta.d.ts.map +0 -1
- package/dist/element/factory.d.ts +0 -32
- package/dist/element/factory.d.ts.map +0 -1
- package/dist/element/inline-style.d.ts +0 -9
- package/dist/element/inline-style.d.ts.map +0 -1
- package/dist/element/lifecycle.d.ts +0 -106
- package/dist/element/lifecycle.d.ts.map +0 -1
- package/dist/element/modifiers.d.ts +0 -11
- package/dist/element/modifiers.d.ts.map +0 -1
- package/dist/element/tags.d.ts +0 -5
- package/dist/element/tags.d.ts.map +0 -1
- package/dist/hydration.d.ts +0 -73
- package/dist/hydration.d.ts.map +0 -1
- package/dist/index.d.ts +0 -17
- package/dist/index.d.ts.map +0 -1
- package/dist/list/index.d.ts +0 -7
- package/dist/list/index.d.ts.map +0 -1
- package/dist/list/runtime.d.ts +0 -6
- package/dist/list/runtime.d.ts.map +0 -1
- package/dist/list/template.d.ts +0 -113
- package/dist/list/template.d.ts.map +0 -1
- package/dist/list/types.d.ts +0 -57
- package/dist/list/types.d.ts.map +0 -1
- package/dist/polyfill/Document.d.ts +0 -19
- package/dist/polyfill/Document.d.ts.map +0 -1
- package/dist/polyfill/Element.d.ts +0 -48
- package/dist/polyfill/Element.d.ts.map +0 -1
- package/dist/polyfill/Event.d.ts +0 -43
- package/dist/polyfill/Event.d.ts.map +0 -1
- package/dist/polyfill/Node.d.ts +0 -13
- package/dist/polyfill/Node.d.ts.map +0 -1
- package/dist/polyfill/Text.d.ts +0 -11
- package/dist/polyfill/Text.d.ts.map +0 -1
- package/dist/polyfill/index.d.ts +0 -24
- package/dist/polyfill/index.d.ts.map +0 -1
- package/dist/render.d.ts +0 -33
- package/dist/render.d.ts.map +0 -1
- package/dist/shared/conditions.d.ts +0 -4
- package/dist/shared/conditions.d.ts.map +0 -1
- package/dist/shared/dom.d.ts +0 -80
- package/dist/shared/dom.d.ts.map +0 -1
- package/dist/shared/environment.d.ts +0 -5
- package/dist/shared/environment.d.ts.map +0 -1
- package/dist/shared/errors.d.ts +0 -2
- package/dist/shared/errors.d.ts.map +0 -1
- package/dist/shared/renderables.d.ts +0 -4
- package/dist/shared/renderables.d.ts.map +0 -1
- package/dist/shared/strings.d.ts +0 -19
- package/dist/shared/strings.d.ts.map +0 -1
- package/dist/shared/type-guards.d.ts +0 -16
- package/dist/shared/type-guards.d.ts.map +0 -1
- package/dist/ssr/index.d.ts +0 -19
- package/dist/ssr/index.d.ts.map +0 -1
- package/dist/ssr/render-to-string.d.ts +0 -41
- package/dist/ssr/render-to-string.d.ts.map +0 -1
- package/dist/style/css.d.ts +0 -26
- package/dist/style/css.d.ts.map +0 -1
- package/dist/style/engine.d.ts +0 -94
- package/dist/style/engine.d.ts.map +0 -1
- package/dist/style/index.d.ts +0 -3
- package/dist/style/index.d.ts.map +0 -1
- package/dist/update/conditional.d.ts +0 -3
- package/dist/update/conditional.d.ts.map +0 -1
- package/dist/update/reactive-attributes.d.ts +0 -45
- package/dist/update/reactive-attributes.d.ts.map +0 -1
- package/dist/update/reactive-text.d.ts +0 -38
- package/dist/update/reactive-text.d.ts.map +0 -1
- package/dist/update/registry.d.ts +0 -116
- package/dist/update/registry.d.ts.map +0 -1
- package/dist/update/scope.d.ts +0 -7
- package/dist/update/scope.d.ts.map +0 -1
- package/dist/update/update.d.ts +0 -4
- package/dist/update/update.d.ts.map +0 -1
- package/dist/when/builder.d.ts +0 -16
- package/dist/when/builder.d.ts.map +0 -1
- package/dist/when/index.d.ts +0 -44
- package/dist/when/index.d.ts.map +0 -1
- package/dist/when/runtime.d.ts +0 -59
- package/dist/when/runtime.d.ts.map +0 -1
package/dist/nuclo.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nuclo.mjs","names":[],"sources":["../src/shared/type-guards.ts","../src/shared/errors.ts","../src/shared/environment.ts","../src/hydration.ts","../src/element/lifecycle.ts","../src/element/events.ts","../src/update/registry.ts","../src/shared/dom.ts","../src/update/reactive-attributes.ts","../src/element/inline-style.ts","../src/element/event-attributes.ts","../src/element/class-name.ts","../src/update/reactive-text.ts","../src/element/attributes.ts","../src/element/modifiers.ts","../src/element/factory-meta.ts","../src/element/factory.ts","../src/element/tags.ts","../src/shared/renderables.ts","../src/list/template.ts","../src/list/runtime.ts","../src/list/index.ts","../src/shared/conditions.ts","../src/when/runtime.ts","../src/when/builder.ts","../src/when/index.ts","../src/update/conditional.ts","../src/update/scope.ts","../src/update/update.ts","../src/render.ts","../src/style/engine.ts","../src/style/css.ts","../src/bootstrap.ts"],"sourcesContent":["export function isPrimitive(value: unknown): value is Primitive {\n\treturn value === null || (typeof value !== \"object\" && typeof value !== \"function\");\n}\n\nexport function isNode<T>(value: T): value is T & Node {\n\tif (value instanceof Node) return true;\n\tif (typeof value !== 'object' || value === null) return false;\n\t// Recognize polyfill DOM objects (plain objects with a numeric nodeType)\n\treturn typeof (value as { nodeType?: unknown }).nodeType === 'number';\n}\n\nexport function isObject(value: unknown): value is object {\n\treturn typeof value === \"object\" && value !== null;\n}\n\nexport function isTagLike<T>(value: T): value is T & { tagName?: string } {\n\treturn isObject(value) && \"tagName\" in (value as object);\n}\n\nexport function isBoolean(value: unknown): value is boolean {\n\treturn typeof value === \"boolean\";\n}\n\n/**\n * Narrows `value` to a callable. The generic `<T extends Function>` is intentionally\n * removed: it allowed callers to assert any specific function signature via the type\n * parameter without a runtime check, which is unsafe. Use explicit casts at call sites\n * when a more specific signature is needed.\n */\nexport function isFunction(value: unknown): value is (...args: unknown[]) => unknown {\n\treturn typeof value === \"function\";\n}\n\nexport function isZeroArityFunction(value: unknown): value is () => unknown {\n\treturn isFunction(value) && (value as { length: number }).length === 0;\n}\n","export function logError(message: string, error?: Error | unknown): void {\n if (typeof console !== 'undefined') {\n // eslint-disable-next-line no-console\n console.error(`nuclo: ${message}`, error);\n }\n}","/**\n * Simplified environment detection - minimal overhead for smaller bundle size\n */\n\n// Basic environment detection - no complex caching or edge cases\nexport const isBrowser = typeof window !== 'undefined' && typeof document !== 'undefined';\n","/**\n * Hydration context — tracks global hydration state and per-parent cursor positions.\n *\n * During hydration the component tree is built against an existing DOM tree\n * (produced by SSR). Instead of creating new nodes, factories claim existing\n * children from their parent element by advancing a cursor.\n *\n * The cursor is a *node pointer* (the next unclaimed child), not an index.\n * Indexed childNodes access is O(n) after any tree/attribute mutation in\n * jsdom (live NodeList re-materialization) which made hydration O(n²);\n * firstChild/nextSibling pointers are O(1) in every DOM implementation.\n */\n\nlet _hydrating = false;\n// True while renderToString() is building a tree destined for serialization.\nlet _serializing = false;\n// Missing entry = cursor at parent.firstChild; null = past the last child.\nlet _cursors = new WeakMap<Node, Node | null>();\n\nexport function isHydrating(): boolean {\n return _hydrating;\n}\n\n/**\n * True while a tree is being built for SSR serialization (inside\n * renderToString). Text children must keep their `<!-- text-N -->` markers in\n * this mode so the emitted HTML stays hydratable — even when `isBrowser` is\n * true (SSR running under jsdom, or an isomorphic worker that provides a DOM).\n * A pure client render leaves this false and skips the markers.\n */\nexport function isSerializing(): boolean {\n return _serializing;\n}\n\n/**\n * Runs `fn` with serialization mode enabled, restoring the previous state\n * afterwards (so nested/re-entrant renderToString calls behave correctly).\n */\nexport function runSerializing<T>(fn: () => T): T {\n const previous = _serializing;\n _serializing = true;\n try {\n return fn();\n } finally {\n _serializing = previous;\n }\n}\n\nexport function startHydration(): void {\n _hydrating = true;\n // Each hydration pass starts with a clean cursor slate. Stale cursors from\n // a previous pass would desynchronize claims when a container's content is\n // replaced and re-hydrated (HMR, islands re-mounting).\n _cursors = new WeakMap<Node, Node | null>();\n}\n\nexport function endHydration(): void {\n _hydrating = false;\n}\n\n/**\n * Runs a callback with hydration temporarily disabled, restoring the previous\n * state afterwards. Used when a server/client mismatch forces a subtree to be\n * rendered fresh in the middle of a hydration pass — fresh rendering must not\n * claim nodes from the surrounding SSR DOM.\n */\nexport function runWithoutHydration<T>(fn: () => T): T {\n const wasHydrating = _hydrating;\n _hydrating = false;\n try {\n return fn();\n } finally {\n _hydrating = wasHydrating;\n }\n}\n\n/**\n * Returns the next unclaimed child of a parent node (or null at the end)\n * without advancing the cursor.\n */\nexport function peekChild(parent: Node): Node | null {\n const entry = _cursors.get(parent);\n return entry === undefined ? parent.firstChild : entry;\n}\n\n/**\n * Sets the cursor to a specific child node (or null for \"past the end\").\n */\nexport function setCursor(parent: Node, node: Node | null): void {\n _cursors.set(parent, node);\n}\n\nfunction isWhitespaceText(node: Node): boolean {\n return node.nodeType === 3 && !/\\S/.test(node.textContent || '');\n}\n\n/**\n * Advances the cursor past whitespace-only text nodes.\n *\n * Nuclo's own SSR output never produces bare whitespace text nodes (text\n * children are always preceded by a `<!-- text-N -->` marker), so unmarked\n * whitespace comes from the surrounding template or an HTML\n * formatter/minifier. Skipping (without removing) keeps the cursor aligned\n * while leaving the document's visual whitespace untouched.\n */\nexport function skipWhitespaceText(parent: Node): void {\n let child = peekChild(parent);\n let advanced = false;\n while (child && isWhitespaceText(child)) {\n child = child.nextSibling;\n advanced = true;\n }\n if (advanced) {\n setCursor(parent, child);\n }\n}\n\n/**\n * Claims the next child node from parent at the current cursor position.\n * Advances the cursor by one.\n */\nexport function claimChild(parent: Node): Node | null {\n const child = peekChild(parent);\n if (child) {\n setCursor(parent, child.nextSibling);\n }\n return child;\n}\n\n/**\n * Attempts to claim an existing element from the parent during hydration.\n * Returns the claimed element if the next child matches the expected tag, or null.\n */\nexport function claimElement(parent: Node, tagName: string): Element | null {\n if (!_hydrating) return null;\n skipWhitespaceText(parent);\n const candidate = peekChild(parent);\n if (candidate && candidate.nodeType === 1 && (candidate as Element).tagName.toLowerCase() === tagName) {\n return claimChild(parent) as Element;\n }\n return null;\n}\n\n/**\n * Removes unclaimed SSR children from a hydrated element.\n * Must be called after modifiers have been applied to a claimed element.\n * Removes nodes from the cursor through `lastOriginalChild` (the element's\n * last child before modifiers ran) — nodes appended by modifiers come after\n * that boundary and are preserved.\n */\nexport function cleanupUnclaimedChildren(node: Node, lastOriginalChild: Node | null): void {\n if (!lastOriginalChild) return;\n let current = peekChild(node);\n while (current) {\n const next = current === lastOriginalChild ? null : current.nextSibling;\n node.removeChild(current);\n current = next;\n }\n setCursor(node, null);\n}\n","/**\n * Mount/destroy lifecycle hooks.\n *\n * Two equivalent ways to register them, both funneling into this module:\n * - `on(\"mount\", cb)` / `on(\"destroy\", cb)` (./events.ts)\n * - `{ onMount: cb }` / `{ onDestroy: cb }` attributes (./attributes.ts)\n *\n * ── Mount timing ─────────────────────────────────────────────────────────\n * A freshly created element is still detached while its own subtree (and,\n * for the initial page render, every ancestor up to the root) is being\n * assembled — nuclo builds a tree fully off-document before attaching it in\n * one shot (render()/hydrate()), and list()/when() do the same for the\n * rows/branches they insert into an already-connected host. So onMount can't\n * fire the instant a modifier runs; the element is queued and the queue is\n * flushed once the surrounding operation (render(), hydrate(), or update())\n * finishes inserting its nodes — at that point the element is guaranteed\n * connected. See flushMountQueue() and its call sites in render.ts/update.ts.\n *\n * ── Destroy timing ───────────────────────────────────────────────────────\n * onDestroy fires eagerly and synchronously the moment nuclo removes the\n * element through its own machinery — see the disposeElementLifecycle() call\n * in shared/dom.ts's cleanupNodeTree(), which every ordinary removal\n * (list()/when() diffing, any safeRemoveChild() call) already goes through.\n * The handful of fast paths that intentionally skip that per-node walk for\n * performance (list()'s bulk clear/replace, the single-element when()/else()\n * swap) call disposeLifecyclesInSubtree() directly instead, so destroy still\n * fires exactly at removal time there too — without paying for a bookkeeping\n * walk when nothing in the affected subtree ever registered a lifecycle\n * callback (hasActiveLifecycleRegistrations() short-circuits that to a\n * single integer comparison in the — by far most common — case where\n * lifecycle hooks aren't used at all).\n *\n * An element removed through means nuclo never observes (e.g. a raw\n * `node.remove()` on a container built by render()) is only noticed the next\n * time render()/hydrate()/update() runs and finds it disconnected — this\n * file does not use a MutationObserver. That never leaks memory (all\n * bookkeeping below is WeakMap-based, exactly like every other nuclo\n * registry — see test/memory/gc-collectability.test.ts), but if an app\n * removes a node that way and never calls update() again afterwards,\n * onDestroy for it will not run either. This matches list()/when()'s own\n * documented \"disconnection is noticed lazily, on the next update()\"\n * contract; it is not a lifecycle-specific limitation.\n *\n * ── Ordering (parent/child, any depth) ──────────────────────────────────\n * Neither mechanism below cares how many list()s, when()s, or plain\n * component functions wrap an element — every element gets its own\n * independent WeakMap record, keyed by the element itself, so correctness\n * never depends on nesting depth. What nesting *does* affect is the relative\n * order two related elements' callbacks fire in, which follows normal\n * resource-scoping discipline in both directions:\n * - onMount fires parent-before-child. This falls out of queue order for\n * free — a parent's own {onMount}/on(\"mount\", ...) modifier is applied\n * (queuing it) before the child factories in its own modifier list are\n * even invoked, since applying modifiers is a synchronous, in-order walk.\n * A child's onMount can safely assume any context the parent's onMount\n * set up is already in place.\n * - onDestroy fires child-before-parent (see cleanupNodeTree() and\n * disposeLifecyclesInSubtree() in shared/dom.ts, both post-order: they\n * recurse into every descendant *before* disposing the node itself). A\n * parent's onDestroy can safely release something its children were\n * still using — they have already run by the time it does.\n * Together: mount is top-down, destroy is bottom-up — the same order a\n * `try { ... } finally { ... }` stack of nested resource scopes unwinds in,\n * applied to the DOM tree instead of the call stack.\n *\n * ── Memory ───────────────────────────────────────────────────────────────\n * Per-element bookkeeping lives in a WeakMap keyed by the element, so it is\n * collectible the instant nothing else references the element — exactly the\n * same shape as list/runtime.ts's and update/registry.ts's registries. The\n * mountQueue holds only WeakRefs, so abandoned builds are collectible even\n * if no later operation flushes the queue. Completed mount callbacks are\n * released immediately; only their returned cleanup survives until destroy.\n */\n\nimport { logError } from \"../shared/errors\";\nimport { isBrowser } from \"../shared/environment\";\nimport { isSerializing } from \"../hydration\";\n\ntype CallbackSlot<T> = T | T[];\n\n// Plain numeric constants rather than `const enum` — this project's tsconfig\n// enables erasableSyntaxOnly, which `const enum` (a non-erasable construct:\n// it needs its values inlined by the TS compiler itself) is incompatible\n// with. Mirrors the same pattern already used by list/template.ts's\n// LEAF_TEXT/LEAF_CLASSNAME/SLOT_*/ATTR_* constants.\ntype LifecycleStateValue = 0 | 1 | 2;\n/** Registered, not yet flushed (or already disposed before it could be). */\nconst STATE_PENDING: LifecycleStateValue = 0;\nconst STATE_MOUNTED: LifecycleStateValue = 1;\nconst STATE_DISPOSED: LifecycleStateValue = 2;\n\ninterface LifecycleRecord {\n mount: CallbackSlot<MountCallback<Element>> | null;\n destroy: CallbackSlot<DestroyCallback<Element>> | null;\n state: LifecycleStateValue;\n /** True while this element sits in mountQueue awaiting a flush — guards\n * against queuing the same element twice across multiple on()/attribute\n * registrations. */\n queued: boolean;\n}\n\nconst records = new WeakMap<Element, LifecycleRecord>();\n\n/**\n * Count of Pending/Mounted records not yet disposeElementLifecycle()'d. Lets\n * the hot, lifecycle-free removal paths (list() bulk clear, the conditional-\n * element swap) skip disposeLifecyclesInSubtree()'s walk entirely with a\n * single comparison — true for the overwhelming majority of apps, which\n * never use onMount/onDestroy at all.\n *\n * Only ever incremented by ensureRecord() and decremented by\n * disposeElementLifecycle(), so an element GC'd via the raw-removal path\n * documented above (disposed by neither) leaves this one too high until the\n * page's very last such element is finally disposed — never unbounded, and\n * the cost of staying \"on\" a little longer than strictly necessary is just\n * the same cheap WeakMap probe this counter exists to let most apps skip\n * entirely, so it isn't worth a FinalizationRegistry to correct.\n */\nlet activeCount = 0;\n\nlet mountQueue: WeakRef<Element>[] = [];\n\nfunction shouldSkip(): boolean {\n // isSerializing() is checked in addition to isBrowser (unlike on()'s plain\n // DOM-event path) because renderToString() can run under jsdom, where\n // isBrowser is true. A DOM event registered there is inert (nothing ever\n // dispatches it), but a mount callback registered there would actually\n // *run* — including any side effects, like starting a timer or opening a\n // subscription — purely from serializing a page to a string. Skipping\n // registration entirely during serialization avoids that.\n return !isBrowser || isSerializing();\n}\n\nfunction ensureRecord(element: Element): LifecycleRecord {\n let record = records.get(element);\n if (!record) {\n record = { mount: null, destroy: null, state: STATE_PENDING, queued: false };\n records.set(element, record);\n activeCount++;\n }\n return record;\n}\n\nfunction pushSlot<T>(slot: CallbackSlot<T> | null, cb: T): CallbackSlot<T> {\n if (slot === null) return cb;\n if (Array.isArray(slot)) {\n slot.push(cb);\n return slot;\n }\n return [slot, cb];\n}\n\nfunction enqueue(element: Element, record: LifecycleRecord): void {\n if (record.queued || record.state !== STATE_PENDING) return;\n record.queued = true;\n mountQueue.push(new WeakRef(element));\n}\n\n/** Registers a mount callback for `element`. See the module doc for timing. */\nexport function registerMount<TElement extends Element>(\n element: TElement,\n callback: MountCallback<TElement>,\n): void {\n if (shouldSkip()) return;\n const record = ensureRecord(element);\n // Not reachable through the tag-builder DSL (every modifier — on()/attrs —\n // runs once, synchronously, while the element is still Pending) — only via\n // a direct, manual on(\"mount\", cb)(element, 0) call on an element nuclo has\n // already disposed. Dropped rather than stored so it can't grow the\n // record's callback list for an element that will never mount again.\n if (record.state === STATE_DISPOSED) return;\n record.mount = pushSlot(record.mount, callback as MountCallback<Element>);\n enqueue(element, record);\n}\n\n/** Registers a destroy callback for `element`. See the module doc for timing. */\nexport function registerDestroy<TElement extends Element>(\n element: TElement,\n callback: DestroyCallback<TElement>,\n): void {\n if (shouldSkip()) return;\n const record = ensureRecord(element);\n if (record.state === STATE_DISPOSED) return; // see registerMount()\n record.destroy = pushSlot(record.destroy, callback as DestroyCallback<Element>);\n enqueue(element, record);\n}\n\nfunction runMount(element: Element, callback: MountCallback<Element>, record: LifecycleRecord): void {\n if (record.state !== STATE_MOUNTED) return;\n try {\n const cleanup = callback(element);\n if (typeof cleanup === \"function\") {\n // A mount-returned cleanup takes no arguments (matches the\n // useEffect()/onMount() convention) while DestroyCallback is called\n // with the element — but storing it as-is, uncast wrapper, is safe and\n // avoids allocating a closure for every mount that returns one: JS\n // silently ignores call arguments a function doesn't declare, so\n // runDestroy()'s `callback(element)` just calls `cleanup()` with an\n // extra, unused argument.\n // The callback may synchronously remove itself through a nested update.\n if (records.get(element)?.state === STATE_DISPOSED) runDestroy(element, cleanup);\n else record.destroy = pushSlot(record.destroy, cleanup);\n }\n } catch (error) {\n logError(\"Error in mount callback\", error);\n }\n}\n\nfunction runDestroy(element: Element, callback: DestroyCallback<Element>): void {\n try {\n callback(element);\n } catch (error) {\n logError(\"Error in destroy callback\", error);\n }\n}\n\nfunction fireMount(element: Element): void {\n const record = records.get(element);\n if (!record) return;\n record.queued = false;\n // Disposed before its queued turn came up (e.g. built and discarded within\n // the same pass) — the mount never observably happened, so don't fire it.\n if (record.state !== STATE_PENDING) return;\n record.state = STATE_MOUNTED;\n\n const mount = record.mount;\n record.mount = null;\n if (mount === null) return;\n if (Array.isArray(mount)) {\n for (let i = 0; i < mount.length; i++) runMount(element, mount[i], record);\n } else {\n runMount(element, mount, record);\n }\n}\n\n/**\n * Flushes every element queued since the last flush, firing its mount\n * callback(s) now that the surrounding render()/hydrate()/update() pass has\n * finished inserting nodes into the (connected) document.\n *\n * Swaps the shared queue out to a local batch before iterating, so a mount\n * callback that itself triggers a nested update() (which pushes onto a fresh\n * queue and flushes it in its own, inner call) can't corrupt or be corrupted\n * by the batch this call is still draining.\n */\nexport function flushMountQueue(): void {\n if (mountQueue.length === 0) return;\n const batch = mountQueue;\n mountQueue = [];\n for (let i = 0; i < batch.length; i++) {\n const element = batch[i].deref();\n if (element) fireMount(element);\n }\n}\n\n/**\n * Finalizes one element's lifecycle: silently cancels a mount that never got\n * to run (state was still Pending — built and discarded within one pass), or\n * fires its destroy callback(s) (state was Mounted). Idempotent — safe to\n * call more than once for the same element, e.g. once eagerly from\n * cleanupNodeTree() and, redundantly, once more from a fast-path caller that\n * doesn't know whether the eager walk already reached this node.\n */\nexport function disposeElementLifecycle(element: Element): void {\n const record = records.get(element);\n if (!record) return;\n if (record.state === STATE_DISPOSED) return;\n\n const wasMounted = record.state === STATE_MOUNTED;\n record.state = STATE_DISPOSED;\n activeCount--;\n\n if (wasMounted) {\n const destroy = record.destroy;\n if (destroy !== null) {\n if (Array.isArray(destroy)) {\n for (let i = 0; i < destroy.length; i++) runDestroy(element, destroy[i]);\n } else {\n runDestroy(element, destroy);\n }\n }\n }\n\n // Drop references eagerly instead of waiting for the WeakMap entry to be\n // collected along with the element — the callbacks (and anything they\n // closed over) become unreachable from here immediately.\n record.mount = null;\n record.destroy = null;\n}\n\n/**\n * True while at least one element anywhere on the page has a live (Pending\n * or Mounted) lifecycle record. Called by disposeLifecyclesInSubtree() in\n * shared/dom.ts (its own short-circuit) and, hoisted out of its per-row\n * loop, by list/runtime.ts's bulkClearRecords() — so clearing a large\n * lifecycle-free list costs one comparison, not one skipped call per row.\n */\nexport function hasActiveLifecycleRegistrations(): boolean {\n return activeCount > 0;\n}\n","/**\n * Typed event listener helper.\n *\n * Usage:\n * button(\n * \"Click\",\n * on(\"click\", (e) => {\n * // e and currentTarget are inferred from the native event map\n * })\n * )\n *\n * Design notes:\n * - Returns a NodeModFn so it can be used like any other modifier.\n * - Produces no child node (returns void in the modifier body).\n * - Provides strong typing of the event object based on the DOM event name.\n * - Stores listener references in a WeakMap to prevent memory leaks.\n * - Listeners are automatically cleaned up when elements are garbage collected.\n */\n\nimport { logError } from \"../shared/errors\";\nimport { isBrowser } from \"../shared/environment\";\nimport { registerMount, registerDestroy } from \"./lifecycle\";\n\ntype EventListenerOptions = boolean | AddEventListenerOptions;\n\ninterface TrackedListener {\n type: string;\n wrapped: EventListener;\n capture: boolean;\n}\n\ntype TrackedListeners = TrackedListener | TrackedListener[];\n\n/**\n * Tracks attached listeners per element so removeAllListeners() can detach them.\n *\n * The common single-listener case stores its registration directly. An array\n * is allocated only when an element has multiple distinct listeners. A\n * registration belongs to the reusable modifier rather than an attachment, so\n * applying one modifier to many elements adds no per-element metadata objects.\n * Only the capture flag is retained because it is the sole option compared by\n * removeEventListener.\n */\nconst elementListeners = new WeakMap<HTMLElement, TrackedListeners>();\n\n/**\n * Store listener info for an element to enable cleanup.\n */\nfunction trackListener(\n element: HTMLElement,\n info: TrackedListener,\n): void {\n const tracked = elementListeners.get(element);\n if (!tracked) {\n elementListeners.set(element, info);\n } else if (Array.isArray(tracked)) {\n if (!tracked.includes(info)) tracked.push(info);\n } else if (tracked !== info) {\n elementListeners.set(element, [tracked, info]);\n }\n}\n\n/**\n * Detach a single tracked listener from the DOM.\n */\nfunction detachListener(\n element: HTMLElement,\n info: TrackedListener,\n): void {\n element.removeEventListener(info.type, info.wrapped, info.capture);\n}\n\n/**\n * Remove all listeners of a specific type from an element.\n */\nexport function removeAllListeners(\n element: HTMLElement,\n type?: string\n): void {\n const tracked = elementListeners.get(element);\n if (!tracked) return;\n\n if (type === undefined) {\n if (Array.isArray(tracked)) {\n for (let i = 0; i < tracked.length; i++) {\n detachListener(element, tracked[i]);\n }\n } else {\n detachListener(element, tracked);\n }\n elementListeners.delete(element);\n return;\n }\n\n if (!Array.isArray(tracked)) {\n if (tracked.type === type) {\n detachListener(element, tracked);\n elementListeners.delete(element);\n }\n return;\n }\n\n // Detach matching listeners, compacting survivors back into the same array.\n let write = 0;\n for (let read = 0; read < tracked.length; read++) {\n const info = tracked[read];\n if (info.type === type) {\n detachListener(element, info);\n } else {\n tracked[write++] = info;\n }\n }\n if (write === 0) {\n elementListeners.delete(element);\n } else if (write === 1) {\n elementListeners.set(element, tracked[0]);\n } else {\n tracked.length = write;\n }\n}\n\nfunction noopEventModifier(_parent: ExpandedElement<ElementTagName>): void {}\n\n/**\n * \"mount\"/\"destroy\" are pseudo-events: there is no native DOM event to\n * addEventListener for, so on()'s runtime dispatches them here instead of\n * through createTrackedListener(). See element/lifecycle.ts for what\n * registerMount()/registerDestroy() actually do and when the callback fires.\n */\nfunction createLifecycleModifier<TTagName extends ElementTagName>(\n kind: \"mount\" | \"destroy\",\n callback: (element: HTMLElementTagNameMap[TTagName]) => unknown,\n): NodeModFn<TTagName> {\n if (!isBrowser) return noopEventModifier as NodeModFn<TTagName>;\n\n return function(parent: ExpandedElement<TTagName>): void {\n if (!parent) return;\n const el = parent as unknown as HTMLElementTagNameMap[TTagName];\n if (kind === \"mount\") {\n registerMount(el, callback as MountCallback<HTMLElementTagNameMap[TTagName]>);\n } else {\n registerDestroy(el, callback as DestroyCallback<HTMLElementTagNameMap[TTagName]>);\n }\n };\n}\n\nfunction createTrackedListener<TTagName extends ElementTagName>(\n type: string,\n listener: TypedEventListener<HTMLElementTagNameMap[TTagName], Event>,\n capture: boolean,\n): TrackedListener {\n const wrapped = function(this: EventTarget, event: Event): void {\n const currentTarget = this as HTMLElementTagNameMap[TTagName];\n try {\n listener.call(\n currentTarget,\n event as Event & { currentTarget: HTMLElementTagNameMap[TTagName] },\n );\n } catch (error) {\n logError(`Error in '${type}' listener`, error);\n }\n };\n\n return { type, wrapped, capture };\n}\n\n/**\n * Overload for standard HTMLElement events (strongly typed via lib.dom.d.ts)\n */\nexport function on<\n K extends NucloHTMLElementEventName,\n TTagName extends NucloHTMLElementTagNameForEvent<K> = NucloHTMLElementTagNameForEvent<K>,\n>(\n type: K,\n listener: TypedEventListener<\n HTMLElementTagNameMap[TTagName],\n NucloHTMLElementEventForName<K>\n >,\n options?: EventListenerOptions\n): NodeModFn<TTagName>;\n\n/**\n * Fires once, after the element has been created and connected to the live\n * document. Equivalent to `{ onMount: ... }`. May return a cleanup function —\n * equivalent to also registering it with on(\"destroy\", ...).\n *\n * Listed before the generic string overload below on purpose: \"mount\" is a\n * string too, so a less specific overload earlier would shadow this one.\n */\nexport function on<TTagName extends ElementTagName = ElementTagName>(\n type: \"mount\",\n listener: MountCallback<HTMLElementTagNameMap[TTagName]>,\n): NodeModFn<TTagName>;\n\n/** Fires once the element has been removed. Equivalent to `{ onDestroy: ... }`. */\nexport function on<TTagName extends ElementTagName = ElementTagName>(\n type: \"destroy\",\n listener: DestroyCallback<HTMLElementTagNameMap[TTagName]>,\n): NodeModFn<TTagName>;\n\n/**\n * Fallback / custom event overload (arbitrary event names or custom event types).\n * Specify a custom event type with the E generic if needed:\n * on<\"my-event\", CustomEvent<MyDetail>>(\"my-event\", e => { ... })\n */\nexport function on<\n K extends string,\n E extends Event = Event,\n TTagName extends ElementTagName = ElementTagName\n>(\n type: K,\n listener: TypedEventListener<HTMLElementTagNameMap[TTagName], E>,\n options?: EventListenerOptions\n): NodeModFn<TTagName>;\n\nexport function on<TTagName extends ElementTagName = ElementTagName>(\n type: string,\n listener:\n | TypedEventListener<HTMLElementTagNameMap[TTagName], Event>\n | MountCallback<HTMLElementTagNameMap[TTagName]>\n | DestroyCallback<HTMLElementTagNameMap[TTagName]>,\n options?: EventListenerOptions\n): NodeModFn<TTagName> {\n if (type === \"mount\" || type === \"destroy\") {\n return createLifecycleModifier<TTagName>(\n type,\n listener as (element: HTMLElementTagNameMap[TTagName]) => unknown,\n );\n }\n\n if (!isBrowser) return noopEventModifier as NodeModFn<TTagName>;\n\n const capture = options === true\n || (options !== null && typeof options === \"object\" && options.capture === true);\n // type is neither \"mount\" nor \"destroy\" past the check above, so listener\n // is really the TypedEventListener member of the union — TS can't narrow a\n // union on a check of a different parameter, hence the cast.\n const info = createTrackedListener(\n type,\n listener as TypedEventListener<HTMLElementTagNameMap[TTagName], Event>,\n capture,\n );\n\n return function(parent: ExpandedElement<TTagName>): void {\n // Type guard: verify parent is an HTMLElement with addEventListener\n if (!parent || typeof (parent as HTMLElement).addEventListener !== \"function\") {\n return;\n }\n\n const el = parent as HTMLElementTagNameMap[TTagName];\n\n el.addEventListener(type, info.wrapped, options);\n\n // Track the listener so removeAllListeners() can detach it later.\n trackListener(el, info);\n };\n}\n","/**\n * Shared types and registries for reactive nodes.\n * Single source of truth — imported by reactiveText.ts and reactiveAttributes.ts.\n *\n * Registry structure: the iteration sets only hold WeakRefs; the actual info\n * records live in WeakMaps keyed by the node. Info records may strongly\n * reference the node (e.g. attribute applyValue closures capture the\n * element), so storing them in a strongly-held map would pin the node in\n * memory forever. With WeakMap storage the whole record is collectible as\n * soon as the node is unreachable.\n *\n * Dead WeakRefs left in the iteration sets are pruned by the notify passes as\n * they iterate (deref() === undefined, or node disconnected). Registration is\n * the hottest path in list-heavy renders (one text node + often one element\n * per row), so no per-node FinalizationRegistry is used here: its register()\n * cost per row outweighs keeping the sets tidy between updates, and a stale\n * husk is just an empty WeakRef until the next update() sweeps it.\n */\n\nexport type TextResolver = () => Primitive;\n\nexport interface ReactiveTextNodeInfo {\n resolver: TextResolver;\n lastValue: string;\n /**\n * DSL semantics: nullish and non-primitive resolver results render as \"\"\n * (instead of String(value)). Set by the tag-builder text path so it can\n * register the user's resolver directly rather than allocating a\n * sanitizing wrapper closure per text node.\n */\n sanitize?: boolean;\n}\n\nexport type AttributeResolver = () => unknown;\n\nexport interface AttributeResolverRecord {\n key: string;\n resolver: AttributeResolver;\n applyValue: (value: unknown) => void;\n lastValue: unknown;\n}\n\nexport interface ReactiveElementInfo {\n /**\n * Flat keyed array rather than a Map: elements almost always carry one or\n * two reactive attributes, so linear key lookup on registration beats a Map\n * allocation per element, and the per-update flush iterates with a plain\n * index loop (no iterator/destructuring allocations).\n */\n attributeResolvers: AttributeResolverRecord[];\n}\n\n/**\n * Iteration set of weak references to reactive text nodes.\n */\nexport const reactiveTextNodes = new Set<WeakRef<Text>>();\n\n/**\n * WeakMap for O(1) lookups of reactive text node info by node reference.\n */\nexport const reactiveTextNodesByNode = new WeakMap<Text, { ref: WeakRef<Text>; info: ReactiveTextNodeInfo }>();\n\n/**\n * Iteration set of weak references to reactive elements.\n */\nexport const reactiveElements = new Set<WeakRef<Element>>();\n\n/**\n * WeakMap for O(1) lookups of reactive element info by element reference.\n */\nexport const reactiveElementsByNode = new WeakMap<Element, { ref: WeakRef<Element>; info: ReactiveElementInfo }>();\n\n/**\n * Registers a reactive text node in both lookup structures.\n */\nexport function registerReactiveTextNode(node: Text, info: ReactiveTextNodeInfo): void {\n const existing = reactiveTextNodesByNode.get(node);\n if (existing) {\n // Re-registration (e.g. repeated hydration): replace the info in place.\n existing.info.resolver = info.resolver;\n existing.info.lastValue = info.lastValue;\n existing.info.sanitize = info.sanitize;\n return;\n }\n const ref = new WeakRef(node);\n reactiveTextNodes.add(ref);\n reactiveTextNodesByNode.set(node, { ref, info });\n}\n\n/**\n * Registers a reactive element in both lookup structures.\n */\nexport function registerReactiveElement(element: Element, info: ReactiveElementInfo): void {\n const existing = reactiveElementsByNode.get(element);\n if (existing) {\n existing.info = info;\n return;\n }\n const ref = new WeakRef(element);\n reactiveElements.add(ref);\n reactiveElementsByNode.set(element, { ref, info });\n}\n\n/**\n * Removes a reactive text node's WeakRef entry from the iteration set.\n */\nexport function removeReactiveTextNodeRef(ref: WeakRef<Text>): void {\n reactiveTextNodes.delete(ref);\n}\n\n/**\n * Removes a reactive element's WeakRef entry from the iteration set.\n */\nexport function removeReactiveElementRef(ref: WeakRef<Element>): void {\n reactiveElements.delete(ref);\n}\n\n/**\n * Manually removes reactive text node info for a specific text node.\n * This should be called when a text node is removed from the DOM to prevent memory leaks.\n */\nexport function cleanupReactiveTextNode(node: Text): void {\n const entry = reactiveTextNodesByNode.get(node);\n if (entry) {\n reactiveTextNodes.delete(entry.ref);\n reactiveTextNodesByNode.delete(node);\n }\n}\n\n/**\n * Manually removes reactive element info for a specific element.\n * This should be called when an element is removed from the DOM to prevent memory leaks.\n */\nexport function cleanupReactiveElement(element: Element): void {\n const entry = reactiveElementsByNode.get(element);\n if (entry) {\n reactiveElements.delete(entry.ref);\n reactiveElementsByNode.delete(element);\n }\n}\n\n// ─── Conditional elements ────────────────────────────────────────────────────\n// Same idea as above, but for nodes created by conditional rendering: the\n// registry remembers each node's condition + modifiers so update() can\n// re-evaluate and swap the element in place.\n\nexport interface ConditionalInfo<TTagName extends ElementTagName = ElementTagName> {\n\tcondition: () => boolean;\n\ttagName: TTagName;\n\tmodifiers: Array<NodeMod<TTagName> | NodeModFn<TTagName>>;\n\tisSvg: boolean;\n}\n\n// WeakMap replaces the _conditionalInfo expando property — zero `any`, no DOM pollution, auto-GC.\nconst conditionalInfoMap = new WeakMap<Node, ConditionalInfo<ElementTagName>>();\n\n/**\n * Registry of all nodes that have conditional info attached.\n * Uses WeakRef to prevent memory leaks — allows garbage collection of removed nodes.\n * This enables O(nConditionals) updates instead of a full DOM tree walk.\n */\nconst activeConditionalNodes = new Set<WeakRef<Node>>();\n\n/**\n * Reverse lookup for O(1) unregister — maps node to its WeakRef in the active set.\n */\nconst refByNode = new WeakMap<Node, WeakRef<Node>>();\n\n/**\n * Prunes dead WeakRefs from the active set as soon as their node is\n * collected, instead of waiting for the next getActiveConditionalNodes() pass.\n */\nconst conditionalNodeFinalizer = typeof FinalizationRegistry !== \"undefined\"\n\t? new FinalizationRegistry<WeakRef<Node>>((ref) => { activeConditionalNodes.delete(ref); })\n\t: null;\n\n/**\n * Attach conditional info to a node and register it.\n */\nexport function storeConditionalInfo<TTagName extends ElementTagName>(\n\tnode: Node,\n\tinfo: ConditionalInfo<TTagName>\n): void {\n\tconditionalInfoMap.set(node, info as ConditionalInfo<ElementTagName>);\n\tif (refByNode.has(node)) return;\n\tconst ref = new WeakRef(node);\n\tactiveConditionalNodes.add(ref);\n\trefByNode.set(node, ref);\n\tconditionalNodeFinalizer?.register(node, ref, ref);\n}\n\n/**\n * Explicit unregister helper (optional use on teardown if needed).\n * O(1) via reverse lookup WeakMap.\n */\nexport function unregisterConditionalNode(node: Node): void {\n\tconditionalInfoMap.delete(node);\n\tconst ref = refByNode.get(node);\n\tif (ref) {\n\t\tactiveConditionalNodes.delete(ref);\n\t\tconditionalNodeFinalizer?.unregister(ref);\n\t\trefByNode.delete(node);\n\t}\n}\n\n/**\n * Returns an array of currently tracked conditional nodes that are still alive.\n * Automatically cleans up garbage-collected nodes.\n */\nexport function getActiveConditionalNodes(): Node[] {\n\tconst nodes: Node[] = [];\n\n\tfor (const ref of activeConditionalNodes) {\n\t\tconst node = ref.deref();\n\t\tif (node === undefined) {\n\t\t\tactiveConditionalNodes.delete(ref);\n\t\t} else {\n\t\t\tnodes.push(node);\n\t\t}\n\t}\n\n\treturn nodes;\n}\n\nexport function getConditionalInfo(node: Node): ConditionalInfo<ElementTagName> | null {\n\treturn conditionalInfoMap.get(node) ?? null;\n}\n","import { logError } from \"./errors\";\nimport { removeAllListeners } from \"../element/events\";\nimport { cleanupReactiveTextNode, cleanupReactiveElement, unregisterConditionalNode } from \"../update/registry\";\nimport { disposeElementLifecycle, hasActiveLifecycleRegistrations } from \"../element/lifecycle\";\n\nexport const SVG_NAMESPACE = 'http://www.w3.org/2000/svg';\n\n/**\n * Creates an HTML element.\n * Wrapper for document.createElement with type safety.\n */\nexport function createElement<K extends keyof HTMLElementTagNameMap>(\n tagName: K\n): HTMLElementTagNameMap[K] | null;\nexport function createElement(tagName: string): ExpandedElement | null;\nexport function createElement(tagName: string): ExpandedElement | null {\n return globalThis.document ? document.createElement(tagName) as ExpandedElement : null;\n}\n\n/**\n * Creates an element in the given namespace (typically for SVG elements).\n * Wrapper for document.createElementNS with type safety.\n */\nexport function createElementNS(\n namespace: string,\n tagName: string\n): ExpandedElement | null {\n return globalThis.document ? document.createElementNS(namespace, tagName) as ExpandedElement : null;\n}\n\n/**\n * Creates a text node with the given content.\n * Wrapper for document.createTextNode.\n */\nexport function createTextNode(text: string): Text | null {\n return globalThis.document ? document.createTextNode(text) : null;\n}\n\n/**\n * Creates a document fragment.\n * Wrapper for document.createDocumentFragment.\n */\nexport function createDocumentFragment(): DocumentFragment | null {\n return globalThis.document ? document.createDocumentFragment() : null;\n}\n\nfunction safeAppendChild(parent: Element | Node, child: Node): boolean {\n try {\n parent.appendChild(child);\n return true;\n } catch (error) {\n logError('Failed to append child node', error);\n return false;\n }\n}\n\n/**\n * Recursively removes all event listeners and reactive subscriptions from a node and its descendants\n * to prevent memory leaks when elements are removed from the DOM.\n */\nfunction cleanupNodeTree(node: Node): void {\n // Clean up the node itself based on its type. Order-independent bookkeeping\n // (listeners, reactive registrations) runs up front; onDestroy is fired\n // below, after descendants — see the comment there.\n if (node.nodeType === Node.ELEMENT_NODE) {\n const element = node as HTMLElement;\n // Remove all event listeners\n removeAllListeners(element);\n // Remove reactive attribute resolvers\n cleanupReactiveElement(element);\n // Remove conditional info\n unregisterConditionalNode(element);\n } else if (node.nodeType === Node.TEXT_NODE) {\n // Remove reactive text node info\n cleanupReactiveTextNode(node as Text);\n } else if (node.nodeType === Node.COMMENT_NODE) {\n // Remove conditional info from comment nodes (used by when/list)\n unregisterConditionalNode(node);\n }\n\n // Recursively clean up all child nodes\n // Destroy callbacks can mutate the live childNodes collection. Snapshot\n // only when hooks exist; ordinary cleanup needs no additional allocation.\n const children = hasActiveLifecycleRegistrations() ? Array.from(node.childNodes) : node.childNodes;\n for (let i = 0; i < children.length; i++) {\n cleanupNodeTree(children[i]);\n }\n\n // Fire onDestroy last — after every descendant's onDestroy has already run\n // (post-order) — so a parent's teardown can rely on its children having\n // already released whatever they were using (e.g. a subscription or timer\n // the parent owns and children only read from). This mirrors onMount's own\n // order, which is naturally parent-before-child (registration order is\n // construction order: a parent's own onMount/{onMount} modifier is applied\n // before its child factories are even invoked) — so mount is top-down,\n // destroy is bottom-up, the same LIFO discipline nested resource scopes\n // always use. No-op unless this exact element registered a callback.\n if (node.nodeType === Node.ELEMENT_NODE) {\n disposeElementLifecycle(node as HTMLElement);\n }\n}\n\n/**\n * Fires onDestroy for a subtree that a fast removal path (list()'s bulk\n * clear/replace, the single-element when()/else() swap) is about to drop\n * without walking through cleanupNodeTree()/safeRemoveChild(). Short-circuits\n * to a single comparison when nothing on the page has ever registered a\n * lifecycle callback — the common case — so those fast paths stay fast.\n *\n * Same post-order (children, then self) as cleanupNodeTree() above, for the\n * same reason — see the comment there.\n */\nexport function disposeLifecyclesInSubtree(node: Node): void {\n if (!hasActiveLifecycleRegistrations()) return;\n const children = Array.from(node.childNodes);\n for (let i = 0; i < children.length; i++) {\n disposeLifecyclesInSubtree(children[i]);\n }\n if (node.nodeType === Node.ELEMENT_NODE) {\n disposeElementLifecycle(node as Element);\n }\n}\n\nexport function safeRemoveChild(child: Node): boolean {\n if (!child?.parentNode) return false;\n try {\n // Clean up all event listeners before removing the element\n cleanupNodeTree(child);\n // A destroy callback may already have removed the node.\n child.parentNode?.removeChild(child);\n return true;\n } catch (error) {\n logError('Failed to remove child node', error);\n return false;\n }\n}\n\nfunction safeInsertBefore(parent: Node, newNode: Node, referenceNode: Node | null): boolean {\n try {\n parent.insertBefore(newNode, referenceNode);\n return true;\n } catch (error) {\n logError('Failed to insert node before reference', error);\n return false;\n }\n}\n\nexport function createComment(text: string): Comment | null {\n return globalThis.document ? globalThis.document.createComment(text) : null;\n}\n\nexport function createConditionalComment(tagName: string, suffix = \"hidden\"): Comment | null {\n return globalThis.document ? globalThis.document.createComment(`conditional-${tagName}-${suffix}`) : null;\n}\n\nexport function createMarkerPair(prefix: string, id: number | string): { start: Comment; end: Comment } {\n const endComment = createComment(`${prefix}-end`);\n if (!endComment) throw new Error(\"Failed to create comment: document not available\");\n const startComment = createComment(`${prefix}-start-${id}`);\n if (!startComment) throw new Error(\"Failed to create comment: document not available\");\n return { start: startComment, end: endComment };\n}\n\nexport function clearBetweenMarkers(startMarker: Comment, endMarker: Comment): void {\n let current = startMarker.nextSibling;\n while (current && current !== endMarker) {\n const next = current.nextSibling;\n safeRemoveChild(current);\n current = next;\n }\n}\n\nexport function insertNodesBefore(nodes: Node[], referenceNode: Node): void {\n const parent = referenceNode.parentNode;\n if (parent) {\n for (let i = 0; i < nodes.length; i++) {\n safeInsertBefore(parent, nodes[i], referenceNode);\n }\n }\n}\n\nexport function appendChildren(\n parent: Element | Node,\n ...children: Array<Element | Node | string | null | undefined>\n): Element | Node {\n if (!parent) return parent;\n\n for (let i = 0; i < children.length; i++) {\n const child = children[i];\n if (child != null) {\n let nodeToAppend: Node;\n\n if (typeof child === \"string\") {\n const textNode = createTextNode(child);\n if (textNode) {\n nodeToAppend = textNode;\n } else {\n continue;\n }\n } else {\n nodeToAppend = child as Node;\n }\n\n safeAppendChild(parent, nodeToAppend);\n }\n }\n\n return parent;\n}\n\nexport function isNodeConnected(node: Node | null | undefined): boolean {\n return node?.isConnected === true;\n}\n\n/**\n * Safely replaces an old node with a new node in the DOM.\n * Returns true on success, false on failure (and logs the error).\n */\nexport function replaceNodeSafely(oldNode: Node, newNode: Node): boolean {\n if (!oldNode?.parentNode) return false;\n try {\n oldNode.parentNode.replaceChild(newNode, oldNode);\n return true;\n } catch (error) {\n logError(\"Error replacing conditional node\", error);\n return false;\n }\n}\n\n// ─── Type-safe DOM helpers ───────────────────────────────────────────────────\n\n/**\n * Safely casts an Element-like object to Node & ParentNode interface.\n * This is a common pattern needed when working with DOM manipulation.\n *\n * @param element - The element to cast\n * @returns The element typed as Node & ParentNode\n */\nexport function asParentNode<T extends Element | object>(element: T): Node & ParentNode {\n return element as unknown as Node & ParentNode;\n}\n\n/**\n * Creates a scoped DOM insertion context that temporarily redirects appendChild\n * to insertBefore at a specific reference node. This is useful for inserting\n * content at specific positions in the DOM tree.\n *\n * @param host - The host element\n * @param referenceNode - The node before which new nodes should be inserted\n * @param callback - Function to execute with the scoped context\n * @returns The result of the callback\n */\nexport function withScopedInsertion<T, THost extends Element | object>(\n host: THost,\n referenceNode: Node,\n callback: () => T\n): T {\n const parent = asParentNode(host);\n const originalAppend = Object.getOwnPropertyDescriptor(parent, \"appendChild\");\n const originalInsert = parent.insertBefore;\n\n // Temporarily override appendChild to insert before the reference node\n // TypeScript doesn't like this override but it's safe at runtime\n (parent as unknown as Record<string, unknown>).appendChild = function(node: Node): Node {\n return originalInsert.call(parent, node, referenceNode);\n };\n\n try {\n return callback();\n } finally {\n // Restore original method\n if (originalAppend) Object.defineProperty(parent, \"appendChild\", originalAppend);\n else Reflect.deleteProperty(parent, \"appendChild\");\n }\n}\n\n/**\n * Type-safe wrapper for setting CSS style properties.\n * Provides better error handling than direct CSSStyleDeclaration access.\n * Supports both camelCase and kebab-case property names.\n *\n * @param element - The element to apply styles to\n * @param property - The CSS property name (camelCase or kebab-case)\n * @param value - The value to set (string, number, or null to remove)\n * @returns true if the style was applied successfully, false otherwise\n */\nexport function setStyleProperty(\n element: HTMLElement,\n property: string,\n value: string | number | null\n): boolean {\n try {\n if (value === null || value === undefined || value === '') {\n // Use bracket notation to remove property (works with camelCase)\n (element.style as unknown as Record<string, string>)[property] = '';\n return true;\n }\n\n // Convert value to string first (might throw if toString() throws)\n const stringValue = String(value);\n // Use bracket notation to set property (works with camelCase)\n (element.style as unknown as Record<string, string>)[property] = stringValue;\n return true;\n } catch {\n return false;\n }\n}\n","import { logError } from \"../shared/errors\";\nimport { isNodeConnected } from \"../shared/dom\";\nimport type { UpdateScope } from \"./scope\";\nimport { reactiveElements, reactiveElementsByNode, registerReactiveElement, removeReactiveElementRef } from \"./registry\";\nimport type { AttributeResolver, AttributeResolverRecord, ReactiveElementInfo } from \"./registry\";\nimport { isBrowser } from \"../shared/environment\";\n\nconst UNSET_LAST_VALUE = {};\nlet updateEventListenerRegistered = false;\n\nfunction handleUpdateEvent(event: Event): void {\n // Update all reactive elements on the event's target ancestor chain.\n // This preserves the \"dispatchEvent(new Event('update'))\" workflow without\n // per-element event listeners.\n const target = event.target;\n if (!target || typeof Node === \"undefined\" || !(target instanceof Node)) return;\n\n let node: Node | null = target;\n while (node) {\n if (node instanceof Element) {\n const entry = reactiveElementsByNode.get(node);\n if (entry) {\n if (!isNodeConnected(node)) {\n removeReactiveElementRef(entry.ref);\n reactiveElementsByNode.delete(node);\n } else {\n applyAttributeResolvers(entry.info);\n }\n }\n }\n node = node.parentNode;\n }\n}\n\nfunction ensureGlobalUpdateEventListener(): void {\n if (updateEventListenerRegistered) return;\n if (typeof document === \"undefined\" || typeof document.addEventListener !== \"function\") return;\n document.addEventListener(\"update\", handleUpdateEvent, true);\n updateEventListenerRegistered = true;\n}\n\nfunction ensureElementInfo(el: Element): ReactiveElementInfo {\n const entry = reactiveElementsByNode.get(el);\n if (entry) return entry.info;\n\n // No existing info, create new\n const info: ReactiveElementInfo = { attributeResolvers: [] };\n registerReactiveElement(el, info);\n return info;\n}\n\nfunction isCacheableValue(value: unknown): boolean {\n // Avoid caching objects/arrays that may be mutated in place (e.g. style objects).\n return value === null || typeof value !== \"object\";\n}\n\nfunction updateAttributeResolverRecord(record: AttributeResolverRecord): void {\n let nextValue: unknown;\n try {\n nextValue = record.resolver();\n } catch (e) {\n logError(`Failed to resolve reactive attribute: ${record.key}`, e);\n return;\n }\n\n const cacheable = isCacheableValue(nextValue);\n if (cacheable && Object.is(nextValue, record.lastValue)) return;\n\n try {\n record.applyValue(nextValue);\n record.lastValue = cacheable ? nextValue : UNSET_LAST_VALUE;\n } catch (e) {\n logError(`Failed to apply reactive attribute: ${record.key}`, e);\n }\n}\n\nfunction applyAttributeResolvers(info: ReactiveElementInfo): void {\n const resolvers = info.attributeResolvers;\n for (let i = 0; i < resolvers.length; i++) {\n updateAttributeResolverRecord(resolvers[i]);\n }\n}\n\n/**\n * Registers a reactive attribute resolver for an element.\n *\n * The resolver will be called whenever reactive updates run (e.g. via `update()`),\n * or when an `\"update\"` event is dispatched on the element (or a descendant),\n * allowing attributes to reactively update based on application state.\n *\n * @param element - The DOM element to make reactive\n * @param key - The attribute name being made reactive (e.g., 'class', 'style', 'disabled')\n * @param resolver - Function that returns the new attribute value\n * @param applyValue - Callback that applies the resolved value to the element\n *\n * @example\n * ```ts\n * const isActive = signal(false);\n * const button = document.createElement('button');\n * registerAttributeResolver(\n * button,\n * 'class',\n * () => isActive.value ? 'active' : 'inactive',\n * (value) => button.className = String(value)\n * );\n * ```\n */\nexport function registerAttributeResolver<TTagName extends ElementTagName>(\n element: ExpandedElement<TTagName>,\n key: string,\n resolver: AttributeResolver,\n applyValue: (value: unknown) => void\n): void {\n if (!(element instanceof Element) || !key || typeof resolver !== \"function\") {\n logError(\"Invalid parameters for registerAttributeResolver\");\n return;\n }\n\n const record: AttributeResolverRecord = { key, resolver, applyValue, lastValue: UNSET_LAST_VALUE };\n\n if (!isBrowser) {\n // SSR: just apply once, no registration needed (update() is never called server-side)\n updateAttributeResolverRecord(record);\n return;\n }\n\n ensureGlobalUpdateEventListener();\n const info = ensureElementInfo(element as Element);\n // Re-registration for a key replaces its record (previous Map.set semantics).\n const resolvers = info.attributeResolvers;\n let replaced = false;\n for (let i = 0; i < resolvers.length; i++) {\n if (resolvers[i].key === key) {\n resolvers[i] = record;\n replaced = true;\n break;\n }\n }\n if (!replaced) resolvers.push(record);\n updateAttributeResolverRecord(record);\n}\n\n/**\n * Updates all registered reactive elements by re-evaluating their attribute resolvers.\n *\n * Iterates through all reactive elements and triggers their registered attribute resolvers\n * to update. Automatically cleans up disconnected elements and their event listeners.\n *\n * This function should be called after state changes to synchronize element attributes\n * with application state.\n *\n * @example\n * ```ts\n * // After updating application state\n * isActive.value = true;\n * notifyReactiveElements(); // All reactive attributes update\n * ```\n */\nexport function notifyReactiveElements(scope?: UpdateScope): void {\n for (const ref of reactiveElements) {\n const el = ref.deref();\n if (el === undefined) {\n removeReactiveElementRef(ref);\n continue;\n }\n\n const entry = reactiveElementsByNode.get(el);\n if (!entry) {\n removeReactiveElementRef(ref);\n continue;\n }\n\n if (!isNodeConnected(el)) {\n reactiveElementsByNode.delete(el);\n removeReactiveElementRef(ref);\n continue;\n }\n\n if (scope && !scope.contains(el)) continue;\n applyAttributeResolvers(entry.info);\n }\n\n}\n","import { isFunction } from \"../shared/type-guards\";\nimport { registerAttributeResolver } from \"../update/reactive-attributes\";\nimport { setStyleProperty } from \"../shared/dom\";\nimport { logError } from \"../shared/errors\";\n\ntype StyleAssignment = CSSStyleObject;\ntype StyleResolver = () => StyleAssignment | null | undefined;\n\n/**\n * Simplified style management - basic functionality with minimal overhead\n */\nexport function assignInlineStyles<TTagName extends ElementTagName>(\n element: ExpandedElement<TTagName>,\n styles: StyleAssignment | null | undefined,\n): void {\n if (!element?.style || !styles) return;\n\n for (const property in styles) {\n const success = setStyleProperty(\n element as HTMLElement,\n property,\n (styles as Record<string, string | number | null>)[property]\n );\n\n if (!success) {\n // Don't try to stringify value in error message as it might throw\n logError(`Failed to set style property '${property}'`);\n }\n }\n}\n\nexport function applyStyleAttribute<TTagName extends ElementTagName>(\n element: ExpandedElement<TTagName>,\n styleValue: StyleAssignment | StyleResolver | null | undefined\n): void {\n if (!element) return;\n\n if (isFunction(styleValue)) {\n registerAttributeResolver(element, 'style', styleValue, function(resolvedStyles) {\n assignInlineStyles(element, resolvedStyles as StyleAssignment);\n });\n } else {\n assignInlineStyles(element, styleValue);\n }\n}\n","const ON_DOUBLE_CLICK = \"onDoubleClick\";\n\n/**\n * `onMount`/`onDestroy` look like `on*` event attributes but aren't real DOM\n * events — there is no native `onmount`/`ondestroy` IDL property for\n * `\"onmount\" in element` to find, so without this exclusion they'd fall into\n * the generic addEventListener fallback below and silently never fire (the\n * browser never dispatches a \"mount\"/\"destroy\" event). attributes.ts special-\n * cases these two keys before ever calling this function; the exclusion here\n * is what makes list/template.ts's row-template analysis correctly bail its\n * skeleton-clone fast path for rows using them too (see element/lifecycle.ts).\n */\nconst RESERVED_LIFECYCLE_ATTRIBUTES = new Set([\"onMount\", \"onDestroy\"]);\n\ntype FallbackEventListenerList = Array<string | EventListener>;\n\nconst fallbackEventListeners = new WeakMap<EventTarget, FallbackEventListenerList>();\n\n/** Converts a public camel-cased event attribute to its native IDL property. */\nexport function eventAttributeToProperty(attribute: string): string | null {\n if (\n attribute.length <= 2\n || attribute.charCodeAt(0) !== 111 /* o */\n || attribute.charCodeAt(1) !== 110 /* n */\n ) {\n return null;\n }\n\n const firstEventCharacter = attribute.charCodeAt(2);\n if (firstEventCharacter < 65 /* A */ || firstEventCharacter > 90 /* Z */) {\n return null;\n }\n\n if (RESERVED_LIFECYCLE_ATTRIBUTES.has(attribute)) return null;\n if (attribute === ON_DOUBLE_CLICK) return \"ondblclick\";\n return attribute.toLowerCase();\n}\n\n/** Assigns an event attribute, falling back when the IDL property is absent. */\nexport function setEventAttribute(\n element: HTMLElement,\n property: string,\n listener: EventListener,\n): void {\n if (property in element) {\n (element as unknown as Record<string, unknown>)[property] = listener;\n return;\n }\n\n const type = property.slice(2);\n const list = fallbackEventListeners.get(element);\n if (list) {\n for (let i = 0; i < list.length; i += 2) {\n if (list[i] !== type) continue;\n\n const previous = list[i + 1] as EventListener;\n if (previous === listener) return;\n element.removeEventListener(type, previous);\n element.addEventListener(type, listener);\n list[i + 1] = listener;\n return;\n }\n\n element.addEventListener(type, listener);\n list.push(type, listener);\n return;\n }\n\n element.addEventListener(type, listener);\n fallbackEventListeners.set(element, [type, listener]);\n}\n","// WeakMap/WeakSet replace expando properties — zero `any`, automatic GC on element removal.\nconst staticClassNames = new WeakMap<HTMLElement, Set<string>>();\nconst reactiveClassNameFlags = new WeakSet<HTMLElement>();\n\n/**\n * Splits a className string into non-empty tokens and adds them to a Set.\n * Single-pass via charCodeAt — avoids intermediate array from split().filter().\n */\nfunction addClassTokens(target: Set<string>, className: string): void {\n\tconst len = className.length;\n\tlet start = 0;\n\tfor (let i = 0; i <= len; i++) {\n\t\tif (i === len || className.charCodeAt(i) === 32) { // 32 = ' '\n\t\t\tif (i > start) target.add(className.substring(start, i));\n\t\t\tstart = i + 1;\n\t\t}\n\t}\n}\n\n/**\n * Joins a Set of class names into a single space-separated string.\n */\nfunction joinClasses(classes: Set<string>): string {\n\tlet result = '';\n\tfor (const cls of classes) {\n\t\tif (result) result += ' ';\n\t\tresult += cls;\n\t}\n\treturn result;\n}\n\n// Mark element as having a reactive className and capture static classes.\n// Only allocate the tracking Set when the element actually has static classes —\n// reactive-only elements (the common case, e.g. a list row's `class={...}`)\n// skip the Set entirely. mergeReactiveClassName/addStaticClasses both handle a\n// missing Set, so an empty one carries no information.\nexport function initReactiveClassName(el: HTMLElement): void {\n\tif (el.className && !staticClassNames.has(el)) {\n\t\tconst classSet = new Set<string>();\n\t\taddClassTokens(classSet, el.className);\n\t\tstaticClassNames.set(el, classSet);\n\t}\n\treactiveClassNameFlags.add(el);\n}\n\n// Check if element has a reactive className\nexport function hasReactiveClassName(el: HTMLElement): boolean {\n\treturn reactiveClassNameFlags.has(el);\n}\n\n// Add static classes to the element's tracked set\nexport function addStaticClasses(el: HTMLElement, className: string): void {\n\tif (!className) return;\n\tlet classSet = staticClassNames.get(el);\n\tif (!classSet) {\n\t\tclassSet = new Set<string>();\n\t\tstaticClassNames.set(el, classSet);\n\t}\n\taddClassTokens(classSet, className);\n}\n\n// Merge reactive className with static classes — called on every reactive update\nexport function mergeReactiveClassName(el: HTMLElement, reactiveClassName: string): void {\n\tconst staticClasses = staticClassNames.get(el);\n\n\tif (!staticClasses || staticClasses.size === 0) {\n\t\t// Skip the DOM write when nothing changes — the common case is the very\n\t\t// first apply of a reactive className resolving to '' on a fresh element.\n\t\tconst next = reactiveClassName || '';\n\t\tif (el.className !== next) el.className = next;\n\t\treturn;\n\t}\n\tif (!reactiveClassName) {\n\t\tel.className = joinClasses(staticClasses);\n\t\treturn;\n\t}\n\t// Hot path: static + reactive. Avoid new Set() — build string directly\n\t// and deduplicate by checking if reactive tokens already exist in static set\n\tlet result = joinClasses(staticClasses);\n\tconst len = reactiveClassName.length;\n\tlet start = 0;\n\tfor (let i = 0; i <= len; i++) {\n\t\tif (i === len || reactiveClassName.charCodeAt(i) === 32) {\n\t\t\tif (i > start) {\n\t\t\t\tconst token = reactiveClassName.substring(start, i);\n\t\t\t\tif (!staticClasses.has(token)) {\n\t\t\t\t\tresult += ' ' + token;\n\t\t\t\t}\n\t\t\t}\n\t\t\tstart = i + 1;\n\t\t}\n\t}\n\tel.className = result;\n}\n\n// Merge static className (for non-reactive className attributes)\nexport function mergeStaticClassName(el: HTMLElement, newClassName: string): void {\n\tif (!newClassName) return;\n\tconst currentClassName = el.className;\n\tif (currentClassName && currentClassName !== newClassName) {\n\t\tconst existing = new Set<string>();\n\t\taddClassTokens(existing, currentClassName);\n\t\taddClassTokens(existing, newClassName);\n\t\tel.className = joinClasses(existing);\n\t} else {\n\t\tel.className = newClassName;\n\t}\n}\n","import { logError } from \"../shared/errors\";\nimport { isNodeConnected, createTextNode } from \"../shared/dom\";\nimport type { UpdateScope } from \"./scope\";\nimport { reactiveTextNodes, reactiveTextNodesByNode, registerReactiveTextNode, removeReactiveTextNodeRef } from \"./registry\";\nimport type { TextResolver } from \"./registry\";\nimport { isBrowser } from \"../shared/environment\";\n\n/**\n * Creates a reactive text node that automatically updates when its resolver function changes.\n *\n * The text node will be registered for reactive updates and its content will be synchronized\n * whenever notifyReactiveTextNodes() is called.\n *\n * @param resolver - Function that returns the text content (string, number, boolean, etc.)\n * @param preEvaluated - Optional pre-evaluated value to avoid calling resolver immediately\n * @returns A Text node that will reactively update its content\n *\n * @example\n * ```ts\n * const count = signal(0);\n * const textNode = createReactiveTextNode(() => `Count: ${count.value}`);\n * // Later, when count changes and notifyReactiveTextNodes() is called,\n * // the text content automatically updates\n * ```\n */\nexport function createReactiveTextNode(resolver: TextResolver, preEvaluated?: unknown, sanitize?: boolean): Text | DocumentFragment {\n if (typeof resolver !== \"function\") {\n logError(\"Invalid resolver provided to createReactiveTextNode\");\n const fallbackNode = createTextNode(\"\");\n if (!fallbackNode) {\n throw new Error(\"Failed to create text node: document not available\");\n }\n return fallbackNode;\n }\n\n let initial: unknown;\n if (arguments.length > 1) {\n initial = preEvaluated;\n } else {\n try {\n initial = resolver();\n } catch (e) {\n logError(\"Failed to evaluate reactive text resolver\", e);\n initial = \"\";\n }\n }\n const str = initial === undefined ? \"\" : String(initial);\n const txt = createTextNode(str);\n \n if (!txt) {\n throw new Error(\"Failed to create text node: document not available\");\n }\n\n if (isBrowser) {\n registerReactiveTextNode(txt, { resolver, lastValue: str, sanitize });\n }\n return txt;\n}\n\n/**\n * Updates all registered reactive text nodes.\n *\n * Iterates through all reactive text nodes, re-evaluates their resolver functions,\n * and updates their content if it has changed. Automatically cleans up disconnected nodes.\n *\n * This function should be called after state changes to synchronize the DOM with application state.\n *\n * @example\n * ```ts\n * // After updating application state\n * count.value++;\n * notifyReactiveTextNodes(); // All reactive text nodes update\n * ```\n */\nexport function notifyReactiveTextNodes(scope?: UpdateScope): void {\n for (const ref of reactiveTextNodes) {\n const node = ref.deref();\n if (node === undefined) {\n removeReactiveTextNodeRef(ref);\n continue;\n }\n\n const entry = reactiveTextNodesByNode.get(node);\n if (!entry) {\n removeReactiveTextNodeRef(ref);\n continue;\n }\n const info = entry.info;\n\n if (!isNodeConnected(node)) {\n reactiveTextNodesByNode.delete(node);\n removeReactiveTextNodeRef(ref);\n continue;\n }\n\n if (scope && !scope.contains(node)) continue;\n\n let raw: unknown;\n try {\n raw = info.resolver();\n } catch (e) {\n logError(\"Failed to update reactive text node\", e);\n raw = undefined;\n }\n\n // sanitize: DSL text resolvers render nullish/non-primitive results as \"\"\n // (the resolver is registered raw; see ReactiveTextNodeInfo.sanitize).\n const newVal = info.sanitize\n ? (raw == null || typeof raw === \"object\" || typeof raw === \"function\" ? \"\" : String(raw))\n : (raw === undefined ? \"\" : String(raw));\n if (newVal !== info.lastValue) {\n node.textContent = newVal;\n info.lastValue = newVal;\n }\n }\n\n}\n","import { isFunction } from \"../shared/type-guards\";\nimport { registerAttributeResolver } from \"../update/reactive-attributes\";\nimport { applyStyleAttribute } from \"./inline-style\";\nimport { SVG_NAMESPACE } from \"../shared/dom\";\nimport { eventAttributeToProperty, setEventAttribute } from \"./event-attributes\";\nimport { registerMount, registerDestroy } from \"./lifecycle\";\nimport {\n\tinitReactiveClassName,\n\thasReactiveClassName,\n\taddStaticClasses,\n\tmergeReactiveClassName,\n\tmergeStaticClassName\n} from \"./class-name\";\n\ntype AttributeKey<TTagName extends ElementTagName> = keyof ExpandedElementAttributes<TTagName>;\ntype AttributeCandidate<TTagName extends ElementTagName> =\n ExpandedElementAttributes<TTagName>[AttributeKey<TTagName>];\n\n/**\n * Applies a resolved (non-function) attribute value to an element.\n *\n * Module-level rather than a closure inside applySingleAttribute so the\n * static-attribute path — the bulk of attributes in list rows — allocates\n * nothing per attribute.\n */\nfunction setAttributeValue(\n el: ExpandedElement<ElementTagName>,\n key: string,\n v: unknown,\n merge: boolean,\n): void {\n if (v == null) return;\n\n // Special handling for className to merge instead of replace (only for non-reactive updates)\n if (merge && key === 'className' && el instanceof HTMLElement) {\n mergeStaticClassName(el, String(v));\n return;\n }\n\n // SVG elements should always use setAttribute for most attributes\n // because many SVG properties are read-only\n if (el instanceof Element && el.namespaceURI === SVG_NAMESPACE) {\n el.setAttribute(key, String(v));\n } else if (key in el) {\n // For HTML elements, try to set as property first\n try {\n (el as Record<string, unknown>)[key] = v;\n } catch {\n // If property is read-only, fall back to setAttribute\n if (el instanceof Element) {\n el.setAttribute(key, String(v));\n }\n }\n } else if (el instanceof Element) {\n el.setAttribute(key, String(v));\n }\n}\n\nexport function applySingleAttribute<TTagName extends ElementTagName>(\n el: ExpandedElement<TTagName>,\n key: AttributeKey<TTagName>,\n raw: AttributeCandidate<TTagName> | undefined,\n shouldMergeClassName = false,\n): void {\n if (raw == null) return;\n const k = key as string;\n\n if (k === \"style\") {\n applyStyleAttribute(el, raw as unknown as ValueOrFactory<CSSStyleObject>);\n return;\n }\n\n if (isFunction(raw)) {\n // onMount/onDestroy aren't real DOM events (no native onmount/ondestroy\n // IDL property exists) — checked first so they never fall into the\n // generic on* handling below, which would silently register a dead\n // addEventListener(\"mount\"/\"destroy\", ...) that the browser never fires.\n if (k === \"onMount\") {\n registerMount(el as unknown as Element, raw as MountCallback<Element>);\n return;\n }\n if (k === \"onDestroy\") {\n registerDestroy(el as unknown as Element, raw as DestroyCallback<Element>);\n return;\n }\n\n // Keep the dominant event path to one comparison and one assignment.\n if (k === \"onClick\") {\n (el as Record<string, unknown>).onclick = raw;\n return;\n }\n\n if (\n k.charCodeAt(0) === 111 /* o */\n && k.charCodeAt(1) === 110 /* n */\n ) {\n // Camel-cased `on*` props are handlers, not reactive value resolvers.\n const eventProperty = eventAttributeToProperty(k);\n if (eventProperty) {\n setEventAttribute(el as HTMLElement, eventProperty, raw as EventListener);\n return;\n }\n\n // Preserve runtime compatibility for native lowercase IDL properties\n // passed from untyped JavaScript. Public types reject these names.\n if (k in el) {\n (el as Record<string, unknown>)[k] = raw;\n return;\n }\n }\n\n if (raw.length === 0) {\n // Type narrowing: zero-arity function that returns an attribute value\n const resolver = raw as () => AttributeCandidate<TTagName>;\n\n // For reactive className, we need to track which classes are reactive\n // so we can preserve static classes when the reactive className changes\n if (k === 'className' && el instanceof HTMLElement) {\n initReactiveClassName(el);\n\n registerAttributeResolver(el, k, resolver, function(v) {\n mergeReactiveClassName(el, String(v || ''));\n });\n } else {\n registerAttributeResolver(el, k, resolver, function(v) {\n setAttributeValue(el, k, v, false);\n });\n }\n return;\n }\n // Non-event functions with parameters fall through and are assigned as-is\n // (same as any other static value), matching previous behavior.\n }\n\n // Static attributes should merge classNames\n // For className, if there's already a reactive className, add to static classes\n if (k === 'className' && el instanceof HTMLElement && hasReactiveClassName(el)) {\n // There's already a reactive className; update the tracked set and DOM atomically.\n const newClassName = String(raw || '');\n if (newClassName) {\n addStaticClasses(el, newClassName);\n mergeStaticClassName(el, newClassName);\n }\n return;\n }\n setAttributeValue(el, k, raw, shouldMergeClassName);\n}\n\nexport function applyAttributes<TTagName extends ElementTagName>(\n element: ExpandedElement<TTagName>,\n attributes: ExpandedElementAttributes<TTagName>,\n mergeClassName = true,\n): void {\n if (!attributes) return;\n // for-in over Object.keys() avoids allocating a key array per element —\n // attribute objects are always plain literals, so no prototype keys leak in.\n for (const k in attributes) {\n const key = k as AttributeKey<TTagName>;\n const value = (attributes as Record<string, unknown>)[k] as\n AttributeCandidate<TTagName> | undefined;\n // Only merge className for non-className keys OR when explicitly enabled for className\n const shouldMerge = mergeClassName && key === 'className';\n applySingleAttribute(element, key, value, shouldMerge);\n }\n}\n\nexport { createReactiveTextNode } from \"../update/reactive-text\";\n","/**\n * Interprets every argument passed to a tag builder: strings/numbers become\n * text nodes, objects become attributes, functions become reactive text or\n * nested builders, Nodes are appended as-is.\n */\nimport { applyAttributes } from \"./attributes\";\nimport { createReactiveTextNode } from \"../update/reactive-text\";\nimport { registerReactiveTextNode } from \"../update/registry\";\nimport { logError } from \"../shared/errors\";\nimport { isFunction, isNode, isObject, isPrimitive, isZeroArityFunction } from \"../shared/type-guards\";\nimport { createComment, createDocumentFragment, createTextNode } from \"../shared/dom\";\nimport { isHydrating, isSerializing, claimChild, peekChild, setCursor, skipWhitespaceText } from \"../hydration\";\nimport { isBrowser } from \"../shared/environment\";\n\n/**\n * Caches the probe result of zero-arity function modifiers so the same\n * function is not re-invoked when it reappears during re-renders.\n */\nexport const modifierProbeCache = new WeakMap<() => unknown, { value: unknown; error: boolean }>();\n\nexport type NodeModifier<TTagName extends ElementTagName = ElementTagName> =\n\t| NodeMod<TTagName>\n\t| NodeModFn<TTagName>\n\t| AnyParentNodeModifier;\n\n/**\n * Shape returned by cn() helper: a plain object with exactly one key `className`.\n * Typed as readonly to signal it should not be mutated after creation.\n */\ninterface ClassNameOnlyObject {\n\treadonly className: string;\n}\n\nfunction isClassNameOnlyObject(v: unknown): v is ClassNameOnlyObject {\n\treturn (\n\t\tisObject(v) &&\n\t\t!isNode(v) &&\n\t\t'className' in v &&\n\t\ttypeof (v as { className: unknown }).className === 'string' &&\n\t\tObject.keys(v).length === 1\n\t);\n}\n\nfunction nextChildIsTextComment(parent: Node): boolean {\n\tskipWhitespaceText(parent);\n\tconst child = peekChild(parent);\n\treturn !!child && child.nodeType === 8 &&\n\t\t(child as Comment).textContent?.trimStart().startsWith('text-') === true;\n}\n\n/**\n * Claims the text node that follows an already-claimed `<!-- text-N -->`\n * marker and patches its content to the client value.\n *\n * The HTML parser drops empty text nodes, so SSR output for an empty string\n * has a marker with no text node after it — in that case a fresh text node is\n * inserted at the cursor to keep the DOM identical to a client render.\n * Content mismatches (data changed between SSR and hydration) are patched so\n * hydration always converges on the client value.\n */\nfunction claimTextAfterMarker(parent: Node, expected: string): Text | null {\n\tconst next = peekChild(parent);\n\tif (next && next.nodeType === 3) {\n\t\tclaimChild(parent);\n\t\tif (next.textContent !== expected) {\n\t\t\tnext.textContent = expected;\n\t\t}\n\t\treturn next as Text;\n\t}\n\tconst created = createTextNode(expected);\n\tif (!created) return null;\n\tparent.insertBefore(created, next);\n\tsetCursor(parent, next);\n\treturn created;\n}\n\nexport function applyNodeModifier<TTagName extends ElementTagName>(\n\tparent: ExpandedElement<TTagName>,\n\tmodifier: NodeModifier<TTagName>,\n\tindex: number,\n): Node | null {\n\tif (modifier == null) return null;\n\n\tif (isFunction(modifier)) {\n\t\t// Handle zero-argument functions (reactive text or reactive className)\n\t\tif (isZeroArityFunction(modifier)) {\n\t\t\ttry {\n\t\t\t\tlet record = modifierProbeCache.get(modifier);\n\t\t\t\tif (!record) {\n\t\t\t\t\tconst value = modifier();\n\t\t\t\t\trecord = { value, error: false };\n\t\t\t\t\tmodifierProbeCache.set(modifier, record);\n\t\t\t\t}\n\t\t\t\tif (record.error) {\n\t\t\t\t\treturn createReactiveTextChild(index, () => \"\");\n\t\t\t\t}\n\t\t\t\tconst v = record.value;\n\n\t\t\t\t// Detect cn() result: plain object with only a `className` string key\n\t\t\t\tif (isClassNameOnlyObject(v)) {\n\t\t\t\t\tconst classNameFn = (): string => {\n\t\t\t\t\t\tconst result = modifier();\n\t\t\t\t\t\treturn isClassNameOnlyObject(result) ? result.className : \"\";\n\t\t\t\t\t};\n\t\t\t\t\tapplyAttributes(parent, { className: classNameFn } as ExpandedElementAttributes<TTagName>);\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\n\t\t\t\tif (isPrimitive(v)) {\n\t\t\t\t\t// Nullish probes register as empty reactive text instead of being\n\t\t\t\t\t// dropped: a resolver with no value yet (data still loading) must\n\t\t\t\t\t// stay reactive so a later update() can fill it in. The resolver\n\t\t\t\t\t// is registered raw with `sanitize` set — the notify pass renders\n\t\t\t\t\t// nullish/non-primitive results as \"\" — instead of allocating a\n\t\t\t\t\t// sanitizing wrapper closure per text node.\n\t\t\t\t\tconst resolver = modifier as () => Primitive;\n\t\t\t\t\tconst initial: Primitive = v != null ? (v as Primitive) : \"\";\n\t\t\t\t\tif (isHydrating() && nextChildIsTextComment(parent as unknown as Node)) {\n\t\t\t\t\t\tconst parentNode = parent as unknown as Node;\n\t\t\t\t\t\tclaimChild(parentNode); // skip <!-- text-N --> comment\n\t\t\t\t\t\tconst expected = String(initial);\n\t\t\t\t\t\tconst textNode = claimTextAfterMarker(parentNode, expected);\n\t\t\t\t\t\tif (textNode) {\n\t\t\t\t\t\t\tregisterReactiveTextNode(textNode, {\n\t\t\t\t\t\t\t\tresolver,\n\t\t\t\t\t\t\t\tlastValue: expected,\n\t\t\t\t\t\t\t\tsanitize: true,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\t\t\t\t\treturn createReactiveTextChild(index, resolver, initial, true);\n\t\t\t\t}\n\t\t\t\treturn null;\n\t\t\t} catch (error) {\n\t\t\t\tmodifierProbeCache.set(modifier, { value: undefined, error: true });\n\t\t\t\tlogError(\"Error evaluating reactive text function:\", error);\n\t\t\t\treturn createReactiveTextChild(index, () => \"\");\n\t\t\t}\n\t\t}\n\n\t\t// Handle NodeModFn functions\n\t\tconst produced = (modifier as NodeModFn<TTagName>)(parent, index);\n\t\tif (produced == null) return null;\n\t\tif (isPrimitive(produced)) return createStaticTextChild(index, produced);\n\t\tif (isNode(produced)) return produced;\n\t\tif (isObject(produced)) {\n\t\t\tapplyAttributes(parent, produced as ExpandedElementAttributes<TTagName>);\n\t\t}\n\t\treturn null;\n\t}\n\n\t// Handle non-function modifiers\n\tconst candidate = modifier as NodeMod<TTagName>;\n\tif (isPrimitive(candidate)) {\n\t\tif (isHydrating() && nextChildIsTextComment(parent as unknown as Node)) {\n\t\t\tconst parentNode = parent as unknown as Node;\n\t\t\tclaimChild(parentNode); // skip <!-- text-N --> comment\n\t\t\tclaimTextAfterMarker(parentNode, String(candidate));\n\t\t\treturn null;\n\t\t}\n\t\treturn createStaticTextChild(index, candidate);\n\t}\n\tif (isNode(candidate)) return candidate;\n\tapplyAttributes(parent, candidate as ExpandedElementAttributes<TTagName>);\n\treturn null;\n}\n\n/**\n * Wraps a freshly created text node for insertion.\n *\n * The `<!-- text-N -->` marker only exists so hydration can pair an SSR text\n * node with its client resolver. A pure client render never hydrates, so the\n * marker (and the DocumentFragment that carries it) is dead weight: two extra\n * DOM nodes and a fragment allocation per text child that nothing ever reads.\n * In that case we return the bare text node — halving the per-row DOM node\n * count and the DOM inserts in list-heavy renders.\n *\n * SSR (isBrowser === false, or renderToString's serialization mode) and the\n * hydration-mismatch fresh-render path keep the marker so the emitted/repaired\n * DOM stays hydratable. A null text node (document unavailable) is skipped,\n * matching the previous per-path guards.\n */\nfunction wrapTextNode(index: number, textNode: Node | null): Node | null {\n\tif (isBrowser && !isHydrating() && !isSerializing()) {\n\t\treturn textNode;\n\t}\n\tconst fragment = createDocumentFragment();\n\tif (!fragment) {\n\t\tthrow new Error(\"Failed to create document fragment: document not available\");\n\t}\n\tconst comment = createComment(` text-${index} `);\n\tif (comment) fragment.appendChild(comment);\n\tif (textNode) fragment.appendChild(textNode);\n\treturn fragment;\n}\n\nfunction createReactiveTextChild(\n\tindex: number,\n\tresolver: () => Primitive,\n\tpreEvaluated?: unknown,\n\tsanitize?: boolean\n): Node | null {\n\treturn wrapTextNode(index, createReactiveTextNode(resolver, preEvaluated, sanitize));\n}\n\nfunction createStaticTextChild(index: number, value: Primitive): Node | null {\n\treturn wrapTextNode(index, createTextNode(String(value)));\n}\n","/**\n * Internal factory metadata.\n *\n * Tag builders return opaque factory closures; the list() template engine\n * needs to see through them (tag name + modifier list) to decide whether a\n * row can be built by cloning a skeleton instead of running the factory.\n * The metadata is attached under symbols so nothing leaks into the public\n * API surface or enumerable properties.\n */\n\nexport const FACTORY_TAG = Symbol(\"nuclo.factory.tag\");\nexport const FACTORY_MODS = Symbol(\"nuclo.factory.mods\");\nlet metadataOnlyFactoryDepth = 0;\n\n/**\n * Metadata-only factories (list() template rows past the first) are read\n * once, via getFactoryTag/getFactoryMods, during the same synchronous render\n * pass that created them, and are never invoked or retained afterward — so a\n * small pool of stub functions can be reused across rows instead of\n * allocating a fresh closure per tag-builder call. Each row checkpoints the\n * pool before rendering and releases its metadata after consumption, including\n * on failure. Nested renders use later slots so they cannot overwrite an\n * outer row's still-live factory tree.\n */\nconst metadataOnlyStubPool: Array<() => null> = [];\nlet metadataOnlyPoolIndex = 0;\n\nexport function acquireMetadataOnlyFactory(): () => null {\n if (metadataOnlyPoolIndex >= metadataOnlyStubPool.length) {\n metadataOnlyStubPool.push(() => null);\n }\n return metadataOnlyStubPool[metadataOnlyPoolIndex++]!;\n}\n\ninterface TaggedFactory {\n [FACTORY_TAG]?: string;\n [FACTORY_MODS]?: readonly unknown[];\n}\n\nexport function setFactoryMeta(\n factory: unknown,\n tag: string,\n mods: readonly unknown[],\n): void {\n (factory as TaggedFactory)[FACTORY_TAG] = tag;\n (factory as TaggedFactory)[FACTORY_MODS] = mods;\n}\n\n/** Returns the modifier list of a tag-builder factory, or undefined. */\nexport function getFactoryMods(fn: unknown): readonly unknown[] | undefined {\n return typeof fn === \"function\" ? (fn as TaggedFactory)[FACTORY_MODS] : undefined;\n}\n\n/** Returns the tag name of a tag-builder factory, or undefined. */\nexport function getFactoryTag(fn: unknown): string | undefined {\n return typeof fn === \"function\" ? (fn as TaggedFactory)[FACTORY_TAG] : undefined;\n}\n\nexport function isMetadataOnlyFactoryMode(): boolean {\n return metadataOnlyFactoryDepth > 0;\n}\n\n/**\n * Takes the render function and its two args directly (rather than a `() =>`\n * thunk) so the hot per-row call in list/runtime.ts doesn't allocate a\n * closure just to defer a single call.\n */\nexport function withMetadataOnlyFactories<TItem, T>(fn: (item: TItem, index: number) => T, item: TItem, index: number): T {\n metadataOnlyFactoryDepth++;\n try {\n return fn(item, index);\n } finally {\n metadataOnlyFactoryDepth--;\n }\n}\n\nexport function getMetadataOnlyFactoryCheckpoint() {\n return metadataOnlyPoolIndex;\n}\n\nexport function releaseMetadataOnlyFactories(checkpoint: number) {\n while (metadataOnlyPoolIndex > checkpoint) {\n const factory = metadataOnlyStubPool[--metadataOnlyPoolIndex] as TaggedFactory;\n factory[FACTORY_TAG] = undefined;\n factory[FACTORY_MODS] = undefined;\n }\n}\n","/**\n * Element creation: builds HTML/SVG elements and applies the modifier list\n * that was passed to a tag builder (children, attributes, text, on(), ...).\n */\nimport { applyNodeModifier, type NodeModifier } from \"./modifiers\";\nimport { createElement, createElementNS, SVG_NAMESPACE } from \"../shared/dom\";\nimport { claimElement, cleanupUnclaimedChildren } from \"../hydration\";\nimport { acquireMetadataOnlyFactory, isMetadataOnlyFactoryMode, setFactoryMeta } from \"./factory-meta\";\n\nexport type { NodeModifier };\n\n/**\n * Applies modifiers to an element, appending newly produced Nodes while avoiding\n * duplicate DOM insertions (i.e. only appends if parentNode differs).\n *\n * `localIndex` advances once per appended child so each reactive/static text\n * modifier gets a unique `text-N` marker; it is internal bookkeeping only and\n * is not returned (no production caller consumed the previous result object).\n */\nexport function applyModifiers<TTagName extends ElementTagName>(\n element: ExpandedElement<TTagName>,\n modifiers: ReadonlyArray<NodeModifier<TTagName>>,\n startIndex = 0\n): void {\n if (!modifiers || modifiers.length === 0) return;\n\n let localIndex = startIndex;\n const parentNode = element as unknown as Node & ParentNode;\n\n for (let i = 0; i < modifiers.length; i += 1) {\n const mod = modifiers[i];\n // Fast null/undefined skip\n if (mod == null) continue;\n\n const produced = applyNodeModifier(element, mod, localIndex);\n if (!produced) continue;\n\n // Only append if the node isn't already where we expect\n if (produced.parentNode !== parentNode) {\n parentNode.appendChild(produced);\n }\n localIndex += 1;\n }\n}\n\n/**\n * Creates an HTML element with the specified tag name and applies modifiers to it.\n */\nexport function createHtmlElementWithModifiers<TTagName extends ElementTagName>(\n tagName: TTagName,\n modifiers: ReadonlyArray<NodeModifier<TTagName>>\n): ExpandedElement<TTagName> {\n const el = createElement(tagName) as ExpandedElement<TTagName>;\n if (!el) {\n throw new Error(`Failed to create element: ${tagName}`);\n }\n applyModifiers(el, modifiers, 0);\n return el;\n}\n\n/**\n * Creates an SVG element with the specified tag name and applies modifiers to it.\n */\nexport function createSvgElementWithModifiers<TTagName extends keyof SVGElementTagNameMap>(\n tagName: TTagName,\n modifiers: ReadonlyArray<unknown>\n): SVGElementTagNameMap[TTagName] {\n const el = createElementNS(SVG_NAMESPACE, tagName);\n if (!el) {\n throw new Error(`Failed to create SVG element: ${tagName}`);\n }\n applyModifiers(el as unknown as ExpandedElement<ElementTagName>, modifiers as ReadonlyArray<NodeModifier<ElementTagName>>, 0);\n return el as unknown as SVGElementTagNameMap[TTagName];\n}\n\n\n/**\n * Creates an HTML element factory with the given modifiers.\n */\nfunction createHtmlElementFactory<TTagName extends ElementTagName>(\n tagName: TTagName,\n modifiers: ReadonlyArray<NodeModifier<TTagName>>\n): DetachedExpandedElementFactory<TTagName> {\n if (isMetadataOnlyFactoryMode()) {\n const factory = acquireMetadataOnlyFactory() as unknown as DetachedExpandedElementFactory<TTagName>;\n setFactoryMeta(factory, tagName, modifiers);\n return factory;\n }\n\n const factory = function(_parent?: ExpandedElement<TTagName>, index = 0): ExpandedElement<TTagName> {\n const parentNode = _parent as unknown as Node | undefined;\n const claimed = parentNode ? claimElement(parentNode, tagName) as ExpandedElement<TTagName> | null : null;\n const el = claimed ?? createElement(tagName) as ExpandedElement<TTagName>;\n if (!el) {\n throw new Error(`Failed to create element: ${tagName}`);\n }\n const elNode = el as unknown as Node;\n const lastOriginalChild = claimed ? elNode.lastChild : null;\n applyModifiers(el, modifiers as ReadonlyArray<NodeModifier<TTagName>>, index);\n if (claimed) {\n cleanupUnclaimedChildren(elNode, lastOriginalChild);\n }\n return el;\n } as DetachedExpandedElementFactory<TTagName>;\n // Lets the list() template engine see the factory's structure (internal\n // symbols — invisible to the public API).\n setFactoryMeta(factory, tagName, modifiers);\n return factory;\n}\n\n/**\n * Creates an SVG element factory with the given modifiers.\n */\nfunction createSvgElementFactory<TTagName extends keyof SVGElementTagNameMap>(\n tagName: TTagName,\n modifiers: ReadonlyArray<unknown>\n): DetachedSVGElementFactory<TTagName> {\n if (isMetadataOnlyFactoryMode()) {\n const factory = acquireMetadataOnlyFactory() as unknown as DetachedSVGElementFactory<TTagName>;\n setFactoryMeta(factory, tagName, modifiers);\n return factory;\n }\n\n return function(_parent?, index = 0): SVGElementTagNameMap[TTagName] {\n const parentNode = _parent as unknown as Node | undefined;\n const claimed = parentNode ? claimElement(parentNode, tagName) as ExpandedElement | null : null;\n const el = claimed ?? createElementNS(SVG_NAMESPACE, tagName);\n if (!el) {\n throw new Error(`Failed to create SVG element: ${tagName}`);\n }\n const elNode = el as unknown as Node;\n const lastOriginalChild = claimed ? elNode.lastChild : null;\n applyModifiers(el as unknown as ExpandedElement<ElementTagName>, modifiers as ReadonlyArray<NodeModifier<ElementTagName>>, index);\n if (claimed) {\n cleanupUnclaimedChildren(elNode, lastOriginalChild);\n }\n return el as unknown as SVGElementTagNameMap[TTagName];\n } as DetachedSVGElementFactory<TTagName>;\n}\n\n/**\n * Creates an HTML tag builder function.\n */\nexport function createHtmlTagBuilder<TTagName extends ElementTagName>(\n tagName: TTagName,\n): ExpandedElementBuilder<TTagName> {\n return (...mods) => createHtmlElementFactory(tagName, mods);\n}\n\n/**\n * Creates an SVG tag builder function.\n */\nexport function createSvgTagBuilder<TTagName extends keyof SVGElementTagNameMap>(\n tagName: TTagName,\n): ExpandedSVGElementBuilder<TTagName> {\n return (...mods) => createSvgElementFactory(tagName, mods);\n}\n","/**\n * The HTML/SVG tag catalogue and the code that turns every tag into a global\n * builder function (`div(...)`, `span(...)`, `rectSvg(...)`, ...).\n */\nimport { createHtmlTagBuilder, createSvgTagBuilder } from \"./factory\";\n\nexport const HTML_TAGS = [\n \"a\", \"abbr\", \"address\", \"area\", \"article\", \"aside\", \"audio\", \"b\", \"base\",\n \"bdi\", \"bdo\", \"blockquote\", \"body\", \"br\", \"button\", \"canvas\", \"caption\",\n \"cite\", \"code\", \"col\", \"colgroup\", \"data\", \"datalist\", \"dd\", \"del\", \"details\",\n \"dfn\", \"dialog\", \"div\", \"dl\", \"dt\", \"em\", \"embed\", \"fieldset\", \"figcaption\",\n \"figure\", \"footer\", \"form\", \"h1\", \"h2\", \"h3\", \"h4\", \"h5\", \"h6\", \"head\",\n \"header\", \"hgroup\", \"hr\", \"html\", \"i\", \"iframe\", \"img\", \"input\", \"ins\",\n \"kbd\", \"label\", \"legend\", \"li\", \"link\", \"main\", \"map\", \"mark\", \"menu\",\n \"meta\", \"meter\", \"nav\", \"noscript\", \"object\", \"ol\", \"optgroup\", \"option\",\n \"output\", \"p\", \"picture\", \"pre\", \"progress\", \"q\", \"rp\", \"rt\", \"ruby\", \"s\",\n \"samp\", \"script\", \"search\", \"section\", \"select\", \"slot\", \"small\", \"source\",\n \"span\", \"strong\", \"style\", \"sub\", \"summary\", \"sup\", \"table\", \"tbody\", \"td\",\n \"template\", \"textarea\", \"tfoot\", \"th\", \"thead\", \"time\", \"title\", \"tr\",\n \"track\", \"u\", \"ul\", \"var\", \"video\", \"wbr\",\n] as const satisfies ReadonlyArray<ElementTagName>;\n\nexport const SVG_TAGS = [\n \"a\", \"animate\", \"animateMotion\", \"animateTransform\", \"circle\", \"clipPath\",\n \"defs\", \"desc\", \"ellipse\", \"feBlend\", \"feColorMatrix\", \"feComponentTransfer\",\n \"feComposite\", \"feConvolveMatrix\", \"feDiffuseLighting\", \"feDisplacementMap\",\n \"feDistantLight\", \"feDropShadow\", \"feFlood\", \"feFuncA\", \"feFuncB\", \"feFuncG\",\n \"feFuncR\", \"feGaussianBlur\", \"feImage\", \"feMerge\", \"feMergeNode\", \"feMorphology\",\n \"feOffset\", \"fePointLight\", \"feSpecularLighting\", \"feSpotLight\", \"feTile\",\n \"feTurbulence\", \"filter\", \"foreignObject\", \"g\", \"image\", \"line\", \"linearGradient\",\n \"marker\", \"mask\", \"metadata\", \"mpath\", \"path\", \"pattern\", \"polygon\", \"polyline\",\n \"radialGradient\", \"rect\", \"script\", \"set\", \"stop\", \"style\", \"svg\", \"switch\",\n \"symbol\", \"text\", \"textPath\", \"title\", \"tspan\", \"use\", \"view\",\n] as const satisfies ReadonlyArray<keyof SVGElementTagNameMap>;\n\nexport const SELF_CLOSING_TAGS = [\n \"area\", \"base\", \"br\", \"col\", \"embed\", \"hr\", \"img\", \"input\", \"link\", \"meta\",\n \"source\", \"track\", \"wbr\",\n] as const satisfies ReadonlyArray<ElementTagName>;\n\n\n// Tag builders are installed as self-overwriting lazy getters instead of\n// being created eagerly: registerGlobalTagBuilders() touches ~180 HTML+SVG\n// tags, but a typical app only ever calls a handful of them. Deferring the\n// createHtmlTagBuilder()/createSvgTagBuilder() closure allocation to first\n// access keeps boot-time work and idle memory proportional to what the app\n// actually uses instead of the whole tag catalogue.\nfunction defineLazyGlobal<T>(target: Record<string, unknown>, key: string, tagName: T, create: (tagName: T) => unknown): void {\n Object.defineProperty(target, key, {\n configurable: true,\n enumerable: true,\n get(): unknown {\n const value = create(tagName);\n Object.defineProperty(target, key, { value, configurable: true, enumerable: true, writable: true });\n return value;\n },\n // A plain accessor-only property would throw on direct assignment\n // (`globalThis.div = ...`), unlike the eager `target[tagName] = builder`\n // it replaces. Route writes through the same \"become a normal data\n // property\" path so overwriting behaves exactly as before.\n set(value: unknown): void {\n Object.defineProperty(target, key, { value, configurable: true, enumerable: true, writable: true });\n },\n });\n}\n\nfunction registerHtmlTag(target: Record<string, unknown>, tagName: ElementTagName): void {\n // Don't overwrite non-function properties (safety check)\n if (tagName in target && typeof target[tagName] !== 'function') {\n return;\n }\n defineLazyGlobal(target, tagName, tagName, createHtmlTagBuilder);\n // `var` is a reserved word, so the declared global is `var_` — register it\n // under that name too (the bare `var` key stays for globalThis[\"var\"] access).\n if (tagName === \"var\") {\n defineLazyGlobal(target, \"var_\", tagName, createHtmlTagBuilder);\n }\n}\n\nfunction registerSvgTag(target: Record<string, unknown>, tagName: keyof SVGElementTagNameMap): void {\n // All SVG tags use camelCase Svg suffix: aSvg, rectSvg, pathSvg, etc.\n const exportName = `${tagName}Svg`;\n\n if (!(exportName in target)) {\n defineLazyGlobal(target, exportName, tagName, createSvgTagBuilder);\n }\n}\n\nexport function registerGlobalTagBuilders(target: Record<string, unknown> = globalThis): void {\n const marker = \"__nuclo_tags_registered\";\n if ((target as Record<string, boolean>)[marker]) return;\n\n // Register SVG tags with Svg suffix\n for (let i = 0; i < SVG_TAGS.length; i++) {\n registerSvgTag(target, SVG_TAGS[i]);\n }\n\n // Register HTML tags\n for (let i = 0; i < HTML_TAGS.length; i++) {\n registerHtmlTag(target, HTML_TAGS[i]);\n }\n\n (target as Record<string, boolean>)[marker] = true;\n}\n","import { isFunction, isTagLike } from \"./type-guards\";\n\ntype RenderableInput<TTagName extends ElementTagName = ElementTagName> =\n | NodeModFn<TTagName>\n | DetachedExpandedElementFactory<TTagName>\n | DetachedSVGElementFactory\n | SVGElementModifierFn\n | ExpandedElement<TTagName>\n | SVGElement\n | Node\n | null\n | undefined;\n\nexport function resolveRenderable<TTagName extends ElementTagName = ElementTagName>(\n result: RenderableInput<TTagName>,\n host: ExpandedElement<TTagName>,\n index: number\n): ExpandedElement<TTagName> | null {\n if (isFunction(result)) {\n const element = (result as (parent: ExpandedElement<TTagName>, index: number) => unknown)(host, index);\n if (element && isTagLike(element)) {\n return element as ExpandedElement<TTagName>;\n }\n return null;\n }\n\n if (result && isTagLike(result)) {\n return result as ExpandedElement<TTagName>;\n }\n\n return null;\n}\n","/**\n * Row-template cloning for list().\n *\n * Building a row through the normal pipeline costs one createElement + a full\n * modifier pass per element. For a keyed list every row comes from the same\n * render function, so the structure is identical across rows and only the\n * leaves differ (text values, event handlers, reactive resolvers, and —\n * rarely — static attribute values). This module:\n *\n * 1. analyzes the first row's factory tree (via the internal factory\n * metadata symbols) and, when every modifier falls into a supported\n * shape, records a slot program for the row;\n * 2. clones the first row's built element as a skeleton (cloneNode does not\n * copy property-assigned `on*` handlers or reactive registrations, and\n * reactive classNames are scrubbed so a selected first row can't leak\n * its state into the skeleton);\n * 3. builds every other row as skeleton.cloneNode(true) + a patch pass that\n * walks the new factory tree in lockstep with the slot program.\n *\n * Any construct outside the supported shape (style objects, on() modifiers,\n * nested list()/when(), node children, resolvers returning non-primitives,\n * multiple className sources per element, SVG) bails to the normal build\n * path — the template is per-list state, so unsupported lists simply never\n * activate it. A per-row shape mismatch (heterogeneous render output)\n * deactivates the template for that list and rebuilds the row normally.\n */\n\nimport { getFactoryMods, getFactoryTag } from \"../element/factory-meta\";\nimport { eventAttributeToProperty, setEventAttribute } from \"../element/event-attributes\";\nimport { modifierProbeCache } from \"../element/modifiers\";\nimport { isNode } from \"../shared/type-guards\";\nimport { cleanupReactiveElement, cleanupReactiveTextNode } from \"../update/registry\";\n\nexport const LEAF_TEXT = 0;\nexport const LEAF_CLASSNAME = 1;\n\n/**\n * A clone's dynamic leaf, owned by its list record instead of the global\n * reactive registries: template rows have a known lifetime (they live and die\n * with their record), so update() can flush them with a tight array walk —\n * no WeakRef/WeakMap bookkeeping per row, nothing for the GC sweeps to prune.\n */\nexport interface RowLeaf {\n kind: number;\n node: Text | HTMLElement;\n fn: () => unknown;\n last: string;\n}\n\nexport const SLOT_ATTRS = 0;\nexport const SLOT_TEXT = 1;\nexport const SLOT_REACTIVE_TEXT = 2;\nexport const SLOT_CHILD = 3;\nexport const SLOT_NULL = 4;\n\nexport const ATTR_STATIC = 0;\nexport const ATTR_EVENT = 1;\nexport const ATTR_REACTIVE_CLASSNAME = 2;\nexport const ATTR_NULL = 3;\n\nexport interface AttrSpec {\n key: string;\n kind: number;\n /** Static attrs: element exposes the key as a property (filled from the skeleton). */\n prop: boolean;\n /** Static attrs: first-row value. Events: normalized native property name. */\n value?: unknown;\n}\n\nexport type TemplateSlot =\n | { kind: typeof SLOT_ATTRS; keys: AttrSpec[] }\n | { kind: typeof SLOT_TEXT }\n | { kind: typeof SLOT_REACTIVE_TEXT }\n | { kind: typeof SLOT_CHILD; child: TemplateNode }\n | { kind: typeof SLOT_NULL };\n\nexport interface TemplateNode {\n tag: string;\n slots: TemplateSlot[];\n}\n\nexport interface ListTemplate {\n tmpl: TemplateNode;\n skeleton: Element;\n}\n\n/**\n * Classifies a factory's modifier tree into a slot program, or returns null\n * when any modifier falls outside the supported shape.\n */\nexport function analyzeFactory(tag: string, mods: readonly unknown[]): TemplateNode | null {\n const slots: TemplateSlot[] = [];\n let classNameSources = 0;\n\n for (let i = 0; i < mods.length; i++) {\n const mod = mods[i];\n if (mod == null) {\n slots.push({ kind: SLOT_NULL });\n continue;\n }\n\n const t = typeof mod;\n\n if (t === \"function\") {\n const childMods = getFactoryMods(mod);\n if (childMods !== undefined) {\n const childTag = getFactoryTag(mod);\n if (!childTag) return null;\n const child = analyzeFactory(childTag, childMods);\n if (!child) return null;\n slots.push({ kind: SLOT_CHILD, child });\n continue;\n }\n if ((mod as () => unknown).length === 0) {\n // Probe once to confirm this is a text resolver. cn()-style objects,\n // nodes and nested builders are handled by the normal path only.\n let v: unknown;\n try {\n v = (mod as () => unknown)();\n modifierProbeCache.set(mod as () => unknown, { value: v, error: false });\n } catch {\n return null;\n }\n if (v == null || (typeof v !== \"object\" && typeof v !== \"function\")) {\n slots.push({ kind: SLOT_REACTIVE_TEXT });\n continue;\n }\n return null;\n }\n // on() modifiers, when()/list() blocks, arbitrary NodeModFns.\n return null;\n }\n\n if (t === \"object\") {\n if (isNode(mod)) return null;\n const attrs = mod as Record<string, unknown>;\n const keys = Object.keys(attrs);\n const specs: AttrSpec[] = [];\n for (let k = 0; k < keys.length; k++) {\n const key = keys[k];\n const v = attrs[key];\n if (v == null) {\n specs.push({ key, kind: ATTR_NULL, prop: false });\n continue;\n }\n if (key === \"style\") return null;\n const vt = typeof v;\n if (vt === \"function\") {\n const eventProperty = eventAttributeToProperty(key);\n if (eventProperty) {\n specs.push({ key, kind: ATTR_EVENT, prop: false, value: eventProperty });\n continue;\n }\n if (key === \"className\" && (v as () => unknown).length === 0) {\n if (classNameSources++) return null;\n specs.push({ key, kind: ATTR_REACTIVE_CLASSNAME, prop: false });\n continue;\n }\n // Reactive non-className attributes need skeleton scrubbing per\n // key to stay correct — not worth it; normal path handles them.\n return null;\n }\n if (vt === \"object\") return null;\n if (key === \"className\" && classNameSources++) return null;\n specs.push({ key, kind: ATTR_STATIC, prop: false, value: v });\n }\n slots.push({ kind: SLOT_ATTRS, keys: specs });\n continue;\n }\n\n // string | number | boolean → static text child\n slots.push({ kind: SLOT_TEXT });\n }\n\n return { tag, slots };\n}\n\n/**\n * One-time skeleton pass: fills each static attr's property-vs-attribute\n * flag and scrubs reactive classNames (the first row may have rendered with\n * row-specific state, e.g. a selected row's \"danger\" class).\n */\nexport function prepareSkeleton(tmpl: TemplateNode, skeleton: Element): void {\n const slots = tmpl.slots;\n let child: Node | null = skeleton.firstChild;\n for (let i = 0; i < slots.length; i++) {\n const slot = slots[i];\n switch (slot.kind) {\n case SLOT_ATTRS: {\n const specs = slot.keys;\n for (let k = 0; k < specs.length; k++) {\n const spec = specs[k];\n if (spec.kind === ATTR_STATIC) {\n spec.prop = spec.key in skeleton;\n } else if (spec.kind === ATTR_REACTIVE_CLASSNAME) {\n (skeleton as HTMLElement).className = \"\";\n }\n }\n break;\n }\n case SLOT_TEXT:\n case SLOT_REACTIVE_TEXT:\n child = child && child.nextSibling;\n break;\n case SLOT_CHILD:\n if (!child) return;\n prepareSkeleton(slot.child, child as Element);\n child = child.nextSibling;\n break;\n // SLOT_NULL: no node produced\n }\n }\n}\n\n/**\n * Patches a skeleton clone from a fresh factory tree. Returns false on any\n * shape mismatch — the caller then rebuilds the row through the normal path\n * (a partially patched clone is safe to abandon: its reactive registrations\n * are weak and disconnected, so the next update() sweeps them).\n */\nexport function instantiateTemplate(\n tmpl: TemplateNode,\n mods: readonly unknown[],\n el: Element,\n leaves: RowLeaf[],\n): boolean {\n const slots = tmpl.slots;\n if (mods.length !== slots.length) return false;\n let child: Node | null = el.firstChild;\n\n for (let i = 0; i < slots.length; i++) {\n const slot = slots[i];\n const mod = mods[i];\n\n switch (slot.kind) {\n case SLOT_ATTRS: {\n if (mod == null || typeof mod !== \"object\") return false;\n const attrs = mod as Record<string, unknown>;\n const specs = slot.keys;\n let attrCount = 0;\n for (const _k in attrs) attrCount++;\n if (attrCount !== specs.length) return false;\n for (let k = 0; k < specs.length; k++) {\n const spec = specs[k];\n const v = attrs[spec.key];\n switch (spec.kind) {\n case ATTR_STATIC: {\n if (v == null || typeof v === \"object\" || typeof v === \"function\") return false;\n if (v === spec.value) break;\n if (spec.prop) {\n const target = el as unknown as Record<string, unknown>;\n if (target[spec.key] !== v) target[spec.key] = v;\n } else {\n const s = String(v);\n if (el.getAttribute(spec.key) !== s) el.setAttribute(spec.key, s);\n }\n break;\n }\n case ATTR_EVENT: {\n if (typeof v !== \"function\") return false;\n const eventProperty = spec.value as string;\n if (eventProperty === \"onclick\") {\n (el as unknown as Record<string, unknown>).onclick = v;\n } else {\n setEventAttribute(el as HTMLElement, eventProperty, v as EventListener);\n }\n break;\n }\n case ATTR_REACTIVE_CLASSNAME: {\n if (typeof v !== \"function\" || (v as () => unknown).length !== 0) return false;\n // Single-source reactive className (analysis bails on mixed\n // static+reactive), and the skeleton is scrubbed to \"\" — so a\n // plain className assignment is exact, no merge needed.\n const fn = v as () => unknown;\n let resolved: unknown;\n try {\n resolved = fn();\n } catch {\n return false;\n }\n const s = resolved ? String(resolved) : \"\";\n if (s) (el as HTMLElement).className = s;\n leaves.push({ kind: LEAF_CLASSNAME, node: el as HTMLElement, fn, last: s });\n break;\n }\n case ATTR_NULL: {\n if (v != null) return false;\n break;\n }\n }\n }\n break;\n }\n\n case SLOT_TEXT: {\n if (mod == null || typeof mod === \"object\" || typeof mod === \"function\") return false;\n if (!child) return false;\n (child as Text).nodeValue = String(mod);\n child = child.nextSibling;\n break;\n }\n\n case SLOT_REACTIVE_TEXT: {\n if (typeof mod !== \"function\" || (mod as () => unknown).length !== 0) return false;\n if (getFactoryMods(mod) !== undefined) return false;\n if (!child) return false;\n let v: unknown;\n try {\n v = (mod as () => unknown)();\n } catch {\n return false;\n }\n if (v != null && (typeof v === \"object\" || typeof v === \"function\")) return false;\n const s = v == null ? \"\" : String(v);\n const textNode = child as Text;\n textNode.nodeValue = s;\n leaves.push({ kind: LEAF_TEXT, node: textNode, fn: mod as () => unknown, last: s });\n child = textNode.nextSibling;\n break;\n }\n\n case SLOT_CHILD: {\n const childMods = getFactoryMods(mod);\n if (childMods === undefined) return false;\n if (getFactoryTag(mod) !== slot.child.tag) return false;\n if (!child) return false;\n if (!instantiateTemplate(slot.child, childMods, child as Element, leaves)) return false;\n child = child.nextSibling;\n break;\n }\n\n case SLOT_NULL: {\n if (mod != null) return false;\n break;\n }\n }\n }\n return true;\n}\n\n/**\n * Converts the normally-built first row of a compatible template into the same\n * record-owned dynamic leaf representation used by skeleton clones.\n *\n * The normal builder has already registered reactive text/className leaves in\n * the global registries. Template rows have a tighter lifetime through their\n * list record, so unregister those first-row leaves and let updateListRuntimes()\n * flush them with the rest of the templated rows.\n */\nexport function adoptTemplateLeaves(\n tmpl: TemplateNode,\n mods: readonly unknown[],\n el: Element,\n leaves: RowLeaf[],\n): boolean {\n const slots = tmpl.slots;\n if (mods.length !== slots.length) return false;\n let child: Node | null = el.firstChild;\n\n for (let i = 0; i < slots.length; i++) {\n const slot = slots[i];\n const mod = mods[i];\n\n switch (slot.kind) {\n case SLOT_ATTRS: {\n if (mod == null || typeof mod !== \"object\") return false;\n const attrs = mod as Record<string, unknown>;\n const specs = slot.keys;\n let k = 0;\n for (const key in attrs) {\n if (k >= specs.length) return false;\n const spec = specs[k];\n if (spec.key !== key) return false;\n k++;\n const v = attrs[key];\n if (spec.kind === ATTR_REACTIVE_CLASSNAME) {\n if (typeof v !== \"function\" || (v as () => unknown).length !== 0) return false;\n cleanupReactiveElement(el);\n leaves.push({\n kind: LEAF_CLASSNAME,\n node: el as HTMLElement,\n fn: v as () => unknown,\n last: (el as HTMLElement).className,\n });\n }\n }\n if (k !== specs.length) return false;\n break;\n }\n\n case SLOT_TEXT:\n if (!child) return false;\n child = child.nextSibling;\n break;\n\n case SLOT_REACTIVE_TEXT: {\n if (typeof mod !== \"function\" || (mod as () => unknown).length !== 0) return false;\n if (!child || child.nodeType !== 3) return false;\n const textNode = child as Text;\n cleanupReactiveTextNode(textNode);\n leaves.push({\n kind: LEAF_TEXT,\n node: textNode,\n fn: mod as () => unknown,\n last: textNode.nodeValue ?? \"\",\n });\n child = textNode.nextSibling;\n break;\n }\n\n case SLOT_CHILD: {\n const childMods = getFactoryMods(mod);\n if (childMods === undefined) return false;\n if (getFactoryTag(mod) !== slot.child.tag) return false;\n if (!child) return false;\n if (!adoptTemplateLeaves(slot.child, childMods, child as Element, leaves)) return false;\n child = child.nextSibling;\n break;\n }\n\n case SLOT_NULL:\n if (mod != null) return false;\n break;\n }\n }\n return true;\n}\n\n/**\n * Flushes a template row's dynamic leaves: re-evaluates each resolver and\n * writes the DOM only on change. Resolver errors leave the previous value in\n * place (matching the notify passes' error tolerance).\n */\nexport function flushRowLeaves(leaves: RowLeaf[]): void {\n for (let i = 0; i < leaves.length; i++) {\n const leaf = leaves[i];\n let v: unknown;\n try {\n v = leaf.fn();\n } catch {\n continue;\n }\n if (leaf.kind === LEAF_TEXT) {\n const s = v == null || typeof v === \"object\" || typeof v === \"function\" ? \"\" : String(v);\n if (s !== leaf.last) {\n (leaf.node as Text).nodeValue = s;\n leaf.last = s;\n }\n } else {\n const s = v ? String(v) : \"\";\n if (s !== leaf.last) {\n (leaf.node as HTMLElement).className = s;\n leaf.last = s;\n }\n }\n }\n}\n","/**\n * Keyed list runtime: renders `list(provider, render)` blocks and keeps their\n * DOM rows in sync with the provider's items on every update().\n *\n * sync() is a keyed diff over item identity (===):\n * 1. skip when the items are unchanged (arraysEqual),\n * 2. trim rows that already back the same item at the same position from both\n * ends — pure appends, prepends, insertions and deletions then need no\n * keying structures at all,\n * 3. key the remaining window by item identity (same-position rows pinned\n * first, duplicate items matched FIFO), remove the rows whose item is gone,\n * 4. place the window anchored backwards from the row after it: survivors on\n * the longest increasing subsequence of old positions never move, and runs\n * of freshly built rows are batched into DocumentFragments.\n */\nimport { createMarkerPair, createComment, safeRemoveChild, isNodeConnected, createDocumentFragment, disposeLifecyclesInSubtree } from \"../shared/dom\";\nimport { resolveRenderable } from \"../shared/renderables\";\nimport { isHydrating, isSerializing, claimChild, peekChild, setCursor, skipWhitespaceText } from \"../hydration\";\nimport type { ListRenderer, ListRuntime, ListItemRecord, ListItemsInput, ListItemsProvider, ListRenderedRow } from \"./types\";\nimport type { UpdateScope } from \"../update/scope\";\nimport { isBrowser } from \"../shared/environment\";\nimport { getFactoryMods, getFactoryTag, withMetadataOnlyFactories, getMetadataOnlyFactoryCheckpoint, releaseMetadataOnlyFactories } from \"../element/factory-meta\";\nimport { analyzeFactory, prepareSkeleton, instantiateTemplate, adoptTemplateLeaves, flushRowLeaves, type RowLeaf } from \"./template\";\nimport { hasActiveLifecycleRegistrations } from \"../element/lifecycle\";\n\nfunction arraysEqual<T>(a: readonly T[], b: readonly T[]): boolean {\n if (a === b) return true;\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) {\n if (a[i] !== b[i]) return false;\n }\n return true;\n}\n\n/**\n * Registry of active list runtimes.\n *\n * The iteration set only holds WeakRefs; the runtime itself lives in a\n * WeakMap keyed by its start marker. This keeps the global registry free of\n * strong references to the runtime (which holds the host element, records,\n * and markers), so removing a list's DOM subtree makes the whole runtime\n * collectible — even if update() is never called again. The\n * FinalizationRegistry prunes dead WeakRefs from the set once the marker is\n * collected; updateListRuntimes() also prunes as it iterates.\n */\nconst activeListRuntimes = new Set<WeakRef<Comment>>();\nconst listRuntimeByMarker = new WeakMap<Comment, ListRuntime<unknown, ElementTagName>>();\nconst listMarkerFinalizer = typeof FinalizationRegistry !== \"undefined\"\n ? new FinalizationRegistry<WeakRef<Comment>>((ref) => { activeListRuntimes.delete(ref); })\n : null;\nlet updateListFlushEpoch = 0;\n\nfunction registerListRuntime(startMarker: Comment, runtime: ListRuntime<unknown, ElementTagName>): void {\n const ref = new WeakRef(startMarker);\n activeListRuntimes.add(ref);\n listRuntimeByMarker.set(startMarker, runtime);\n listMarkerFinalizer?.register(startMarker, ref);\n}\n\nfunction normalizeItems<TItem>(items: ListItemsInput<TItem>): readonly TItem[] {\n return Array.isArray(items) ? items : Array.from(items);\n}\n\nfunction isRenderedRow<TTagName extends ElementTagName>(value: unknown): value is ListRenderedRow<TTagName> {\n if (value == null || typeof value !== \"object\") return false;\n const element = (value as { element?: unknown }).element;\n return !!element && typeof Node !== \"undefined\" && element instanceof Node;\n}\n\n/**\n * Renders a row through the un-templated path and normalizes the result. Used\n * whenever a row's shape doesn't match (or no longer matches) the list's\n * active template — the caller has already reset `runtime.template`.\n */\nfunction rebuildRowNormally<TItem, TTagName extends ElementTagName>(\n runtime: ListRuntime<TItem, TTagName>,\n item: TItem,\n index: number,\n): ExpandedElement<TTagName> | null {\n const fallback = runtime.renderItem(item, index);\n if (isRenderedRow<TTagName>(fallback)) {\n runtime.lastRenderRefresh = typeof fallback.update === \"function\" ? fallback.update : null;\n return fallback.element;\n }\n return resolveRenderable<TTagName>(fallback as never, runtime.host, index);\n}\n\nfunction renderItem<TItem, TTagName extends ElementTagName>(\n runtime: ListRuntime<TItem, TTagName>,\n item: TItem,\n index: number,\n) {\n const checkpoint = getMetadataOnlyFactoryCheckpoint();\n try {\n return renderItemWithTemplate(runtime, item, index);\n } finally {\n releaseMetadataOnlyFactories(checkpoint);\n }\n}\n\nfunction renderItemWithTemplate<TItem, TTagName extends ElementTagName>(\n runtime: ListRuntime<TItem, TTagName>,\n item: TItem,\n index: number,\n): ExpandedElement<TTagName> | null {\n runtime.lastRenderLeaves = null;\n runtime.lastRenderRefresh = null;\n const template = runtime.template;\n const canUseTemplate = isBrowser && !isHydrating() && !isSerializing();\n\n // Row-template fast path: rows from the same render function share their\n // structure, so after analyzing the first row every following row is a\n // skeleton clone + leaf patch instead of a full per-element build.\n const result = template && canUseTemplate\n ? withMetadataOnlyFactories(runtime.renderItem, item, index)\n : runtime.renderItem(item, index);\n\n if (isRenderedRow<TTagName>(result)) {\n runtime.lastRenderRefresh = typeof result.update === \"function\" ? result.update : null;\n return result.element;\n }\n\n if (template !== null && canUseTemplate) {\n const mods = getFactoryMods(result);\n if (mods !== undefined) {\n if (template === undefined) {\n const tag = getFactoryTag(result);\n const tmpl = tag ? analyzeFactory(tag, mods) : null;\n const el = resolveRenderable<TTagName>(result, runtime.host, index);\n if (tmpl && el) {\n const skeleton = (el as unknown as Node).cloneNode(true) as Element;\n prepareSkeleton(tmpl, skeleton);\n const leaves: RowLeaf[] = [];\n if (adoptTemplateLeaves(tmpl, mods, el as unknown as Element, leaves)) {\n if (leaves.length > 0) runtime.lastRenderLeaves = leaves;\n } else {\n runtime.template = null;\n runtime.lastRenderLeaves = null;\n return el;\n }\n runtime.template = { tmpl, skeleton };\n } else {\n runtime.template = null;\n }\n return el;\n }\n const clone = template.skeleton.cloneNode(true) as Element;\n const leaves: RowLeaf[] = [];\n if (getFactoryTag(result) === template.tmpl.tag && instantiateTemplate(template.tmpl, mods, clone, leaves)) {\n if (leaves.length > 0) runtime.lastRenderLeaves = leaves;\n return clone as unknown as ExpandedElement<TTagName>;\n }\n // Heterogeneous rows: deactivate and rebuild this row normally. The\n // abandoned clone is disconnected and unregistered — plain garbage.\n // (lastRenderLeaves is already null from the top of this call.)\n runtime.template = null;\n return rebuildRowNormally(runtime, item, index);\n } else if (template === undefined) {\n runtime.template = null;\n } else {\n runtime.template = null;\n return rebuildRowNormally(runtime, item, index);\n }\n }\n\n return resolveRenderable<TTagName>(result as never, runtime.host, index);\n}\n\n/**\n * Detaches one row eagerly: safeRemoveChild walks the subtree to abort\n * listeners and prune reactive registries before removing the node. Used for\n * partial removals, where the walk is cheap; full clears/replaces use\n * bulkClearRecords instead.\n */\nfunction removeRecord<TItem, TTagName extends ElementTagName>(record: ListItemRecord<TItem, TTagName>): void {\n safeRemoveChild(record.element as unknown as Node);\n}\n\n/**\n * Detaches every record's row element from the DOM with a plain removeChild\n * loop — one call per top-level row, never descending into a row's subtree.\n * Each record's element is a direct child of `parent` (the rows between the two\n * list markers), so iterating records removes exactly the same nodes the\n * markers span.\n *\n * This is O(rows): removeChild is O(1) given the node. We deliberately do NOT\n * use Range.deleteContents() here. Its spec-faithful \"is this node contained?\"\n * check (compareBoundaryPointsPosition → isFollowing) re-walks the tree from\n * the range start for *every* spanned node, which is O(nodes²) in non-native\n * DOM implementations (jsdom) and — because the walk visits descendants — scales\n * with nodes-per-row, so a nested `tr>td>td` row template made replace/clear\n * quadratic where a flat `div` row only looked linear.\n *\n * Unlike removeRecord, this does NOT eagerly walk each subtree to abort\n * listeners and prune reactive registries. That walk is the dominant per-row\n * cost when clearing/replacing a large list, and it is redundant here:\n * - Reactive text/attribute registries hold their targets only through\n * WeakRef/WeakMap, and every update() prunes entries whose node became\n * disconnected (which removeChild makes them). The real-GC tests in\n * test/memory/gc-collectability.test.ts prove a detached subtree is\n * collectible with no eager cleanup and no extra update pass.\n * - Event listeners are tracked in a WeakMap keyed by element and registered\n * with an AbortSignal, so they are released when the element is collected.\n *\n * Returns false (and mutates nothing) when the markers aren't both children of\n * `parent`, so the caller can fall back to per-node removal.\n */\nfunction bulkClearRecords<TItem, TTagName extends ElementTagName>(\n records: ReadonlyArray<ListItemRecord<TItem, TTagName>>,\n parent: Node & ParentNode,\n startMarker: Comment,\n endMarker: Comment,\n): boolean {\n if (startMarker.parentNode !== parent || endMarker.parentNode !== parent) return false;\n\n // Neither fast path below walks each row's subtree (that's the whole point\n // — see the class doc comment), so it can't rely on cleanupNodeTree() to\n // fire onDestroy for rows using it. Firing it here first keeps that\n // guarantee without costing anything when lifecycle hooks aren't in use\n // anywhere on the page (the single comparison inside\n // hasActiveLifecycleRegistrations() short-circuits the whole loop).\n if (hasActiveLifecycleRegistrations()) {\n for (let i = 0; i < records.length; i++) {\n const node = records[i].element as unknown as Node | null;\n if (node) disposeLifecyclesInSubtree(node);\n }\n }\n\n // Fastest clear: when the list spans the whole parent (the common case — a\n // tbody or ul dedicated to the list), one textContent write drops every row\n // in a single native call, then the marker pair is re-attached (same nodes,\n // so registry identity is preserved).\n if (isBrowser && parent.firstChild === startMarker && parent.lastChild === endMarker) {\n (parent as Node).textContent = \"\";\n parent.appendChild(startMarker);\n parent.appendChild(endMarker);\n return true;\n }\n\n for (let i = 0; i < records.length; i++) {\n const node = records[i].element as unknown as Node | null;\n // Detach the row (guard against an already-moved/detached element so a\n // stale record can't throw). Children of the row go with it in one call.\n if (node && node.parentNode === parent) parent.removeChild(node);\n }\n return true;\n}\n\n/**\n * Computes a longest strictly-increasing subsequence of `arr` and returns the\n * indices (into `arr`) that belong to it, in ascending order. O(n log n).\n *\n * Used so reordering only moves the minimum number of DOM nodes: records whose\n * old position sits on the increasing subsequence are already in the correct\n * relative order and never touched; everything else is repositioned.\n */\nfunction longestIncreasingSubsequence(arr: number[]): number[] {\n const n = arr.length;\n if (n === 0) return [];\n const predecessor = new Array<number>(n);\n // tails[k] = index into arr of the smallest tail of an increasing\n // subsequence of length k+1.\n const tails: number[] = [];\n for (let i = 0; i < n; i++) {\n const x = arr[i];\n let lo = 0;\n let hi = tails.length;\n while (lo < hi) {\n const mid = (lo + hi) >> 1;\n if (arr[tails[mid]] < x) lo = mid + 1;\n else hi = mid;\n }\n predecessor[i] = lo > 0 ? tails[lo - 1] : -1;\n if (lo === tails.length) tails.push(i);\n else tails[lo] = i;\n }\n let k = tails.length;\n let idx = tails[k - 1];\n const result = new Array<number>(k);\n while (k > 0) {\n result[--k] = idx;\n idx = predecessor[idx];\n }\n return result;\n}\n\n/**\n * Renders items in [startIndex, endIndexExclusive) and inserts their elements\n * before `anchor` as a single DocumentFragment (falling back to per-node\n * insertion when fragments are unavailable). Appends the created records to\n * `targetRecords` in order.\n */\nfunction buildAndInsert<TItem, TTagName extends ElementTagName>(\n runtime: ListRuntime<TItem, TTagName>,\n parent: Node & ParentNode,\n items: readonly TItem[],\n startIndex: number,\n endIndexExclusive: number,\n anchor: Node,\n targetRecords: ListItemRecord<TItem, TTagName>[],\n): void {\n const fragment = createDocumentFragment();\n let buffered = 0;\n for (let i = startIndex; i < endIndexExclusive; i++) {\n const item = items[i];\n const element = renderItem(runtime, item, i);\n if (!element) continue;\n const dyn = runtime.lastRenderLeaves;\n targetRecords.push({\n item,\n element,\n dyn,\n refresh: runtime.lastRenderRefresh,\n dynCreatedAt: dyn ? runtime.currentFlushEpoch : undefined,\n });\n runtime.lastRenderLeaves = null;\n runtime.lastRenderRefresh = null;\n const node = element as unknown as Node;\n if (fragment) {\n fragment.appendChild(node);\n buffered++;\n } else {\n parent.insertBefore(node, anchor);\n }\n }\n if (fragment && buffered > 0) parent.insertBefore(fragment, anchor);\n}\n\nexport function sync<TItem, TTagName extends ElementTagName>(\n runtime: ListRuntime<TItem, TTagName>\n): void {\n const { startMarker, endMarker } = runtime;\n const parent = (startMarker.parentNode ?? (runtime.host as unknown as Node & ParentNode)) as\n Node & ParentNode;\n\n const items = normalizeItems(runtime.itemsProvider());\n\n if (arraysEqual(runtime.lastSyncedItems, items)) return;\n\n const oldRecords = runtime.records;\n const oldLen = oldRecords.length;\n const newLen = items.length;\n\n // Fast path — clear: one removeChild per row, skipping the eager per-subtree\n // cleanup walk (see bulkClearRecords).\n if (newLen === 0) {\n if (oldLen > 0 && !bulkClearRecords(oldRecords, parent, startMarker, endMarker)) {\n for (let i = 0; i < oldLen; i++) removeRecord(oldRecords[i]);\n }\n runtime.records = [];\n runtime.lastSyncedItems = [];\n runtime.allRecordsCreatedAt = undefined;\n return;\n }\n\n // Trim rows that already back the same item at the same position from both\n // ends. They never move, and most updates (append, prepend, single insert or\n // delete) reduce to an empty window on one side.\n let prefix = 0;\n const maxTrim = Math.min(oldLen, newLen);\n while (prefix < maxTrim && oldRecords[prefix].item === items[prefix]) prefix++;\n let suffix = 0;\n const maxSuffix = maxTrim - prefix;\n while (suffix < maxSuffix && oldRecords[oldLen - 1 - suffix].item === items[newLen - 1 - suffix]) {\n suffix++;\n }\n\n const oldStart = prefix;\n const oldEnd = oldLen - suffix;\n const newStart = prefix;\n const newEnd = newLen - suffix;\n\n // Every old row was trimmed → pure insertion (first render, append, prepend,\n // middle insert). Build the new rows into one fragment before the row that\n // follows the gap. (An empty new window is a no-op here.)\n if (oldStart === oldEnd) {\n const anchor: Node = oldEnd < oldLen ? (oldRecords[oldEnd].element as unknown as Node) : endMarker;\n if (oldEnd === oldLen) {\n buildAndInsert(runtime, parent, items, newStart, newEnd, anchor, oldRecords);\n runtime.allRecordsCreatedAt = oldLen === 0 ? runtime.currentFlushEpoch : undefined;\n } else {\n const fresh: ListItemRecord<TItem, TTagName>[] = [];\n buildAndInsert(runtime, parent, items, newStart, newEnd, anchor, fresh);\n runtime.records = oldRecords.slice(0, oldStart).concat(fresh, oldRecords.slice(oldStart));\n runtime.allRecordsCreatedAt = undefined;\n }\n runtime.lastSyncedItems = items.slice();\n return;\n }\n\n // Every new row was trimmed → pure removal. This is always partial (a full\n // clear was handled above), so remove each row eagerly.\n if (newStart === newEnd) {\n for (let i = oldStart; i < oldEnd; i++) removeRecord(oldRecords[i]);\n oldRecords.splice(oldStart, oldEnd - oldStart);\n runtime.allRecordsCreatedAt = undefined;\n runtime.lastSyncedItems = items.slice();\n return;\n }\n\n // General keyed diff over the window ---------------------------------------\n const oldWinLen = oldEnd - oldStart;\n const newWinLen = newEnd - newStart;\n\n // sources[j] = index into oldRecords of the record backing new position\n // newStart + j, or -1 when the row must be freshly rendered.\n const sources = new Array<number>(newWinLen).fill(-1);\n // claimed[i - oldStart] = the old record was matched to a new position.\n const claimed = new Uint8Array(oldWinLen);\n let reusedCount = 0;\n\n // Pin records whose item is unchanged at the same position. This keeps\n // duplicate item references attached to their original rows.\n const pinEnd = Math.min(oldEnd, newEnd);\n for (let i = prefix; i < pinEnd; i++) {\n if (oldRecords[i].item === items[i]) {\n sources[i - newStart] = i;\n claimed[i - oldStart] = 1;\n reusedCount++;\n }\n }\n\n // Bucket in reverse DOM order so pop() matches duplicates FIFO in O(1). The value\n // is a single old index, promoted to an index array only when the same item\n // occurs more than once (duplicates are matched FIFO).\n const buckets = new Map<TItem, number | number[]>();\n for (let i = oldEnd - 1; i >= oldStart; i--) {\n if (claimed[i - oldStart]) continue;\n const item = oldRecords[i].item;\n const entry = buckets.get(item);\n if (entry === undefined) buckets.set(item, i);\n else if (typeof entry === \"number\") buckets.set(item, [entry, i]);\n else entry.push(i);\n }\n\n for (let j = 0; j < newWinLen; j++) {\n if (sources[j] !== -1) continue;\n const entry = buckets.get(items[newStart + j]);\n if (entry === undefined) continue;\n let oldIndex: number;\n if (typeof entry === \"number\") {\n oldIndex = entry;\n buckets.delete(items[newStart + j]);\n } else {\n oldIndex = entry.pop()!;\n if (entry.length === 0) buckets.delete(items[newStart + j]);\n }\n sources[j] = oldIndex;\n claimed[oldIndex - oldStart] = 1;\n reusedCount++;\n }\n\n // Nothing survives anywhere → full replace: bulk-detach all old rows and\n // build every new row into a single fragment.\n if (reusedCount === 0 && oldStart === 0 && oldEnd === oldLen) {\n if (!bulkClearRecords(oldRecords, parent, startMarker, endMarker)) {\n for (let i = 0; i < oldLen; i++) removeRecord(oldRecords[i]);\n }\n const fresh: ListItemRecord<TItem, TTagName>[] = [];\n buildAndInsert(runtime, parent, items, 0, newLen, endMarker, fresh);\n runtime.records = fresh;\n runtime.allRecordsCreatedAt = runtime.currentFlushEpoch;\n runtime.lastSyncedItems = items.slice();\n return;\n }\n\n // Remove stale rows BEFORE placement. A removed element left in the DOM\n // would end up interleaved with the survivors the placement phase leaves\n // untouched.\n for (let i = oldStart; i < oldEnd; i++) {\n if (!claimed[i - oldStart]) removeRecord(oldRecords[i]);\n }\n\n // Determine the minimal set of survivors that must move. Survivors whose old\n // positions form an increasing subsequence are already correctly ordered.\n let stable: Uint8Array | null = null;\n if (reusedCount > 0) {\n const survivorOldIndices: number[] = [];\n const survivorPositions: number[] = [];\n for (let j = 0; j < newWinLen; j++) {\n if (sources[j] !== -1) {\n survivorOldIndices.push(sources[j]);\n survivorPositions.push(j);\n }\n }\n stable = new Uint8Array(newWinLen);\n const lis = longestIncreasingSubsequence(survivorOldIndices);\n for (let k = 0; k < lis.length; k++) stable[survivorPositions[lis[k]]] = 1;\n }\n\n // Place the window anchored backwards from the first row after it. Runs of\n // freshly created rows are batched into a fragment; survivors on the LIS are\n // left untouched.\n const windowRecords = new Array<ListItemRecord<TItem, TTagName> | null>(newWinLen);\n let nullCount = 0;\n let anchor: Node = oldEnd < oldLen ? (oldRecords[oldEnd].element as unknown as Node) : endMarker;\n let fragment: DocumentFragment | null = null;\n\n for (let j = newWinLen - 1; j >= 0; j--) {\n const src = sources[j];\n\n if (src === -1) {\n // Fresh row. Prefer batching consecutive new rows into a fragment (one\n // DOM insert); prepending keeps ascending order.\n const item = items[newStart + j];\n const element = renderItem(runtime, item, newStart + j);\n if (!element) {\n windowRecords[j] = null;\n nullCount++;\n continue;\n }\n const dyn = runtime.lastRenderLeaves;\n windowRecords[j] = {\n item,\n element,\n dyn,\n refresh: runtime.lastRenderRefresh,\n dynCreatedAt: dyn ? runtime.currentFlushEpoch : undefined,\n };\n runtime.lastRenderLeaves = null;\n runtime.lastRenderRefresh = null;\n const node = element as unknown as Node;\n if (!fragment) fragment = createDocumentFragment();\n if (fragment) {\n fragment.insertBefore(node, fragment.firstChild);\n } else {\n // No DocumentFragment available — insert directly and advance the\n // anchor so the next (earlier) row lands before this one.\n parent.insertBefore(node, anchor);\n anchor = node;\n }\n continue;\n }\n\n // Survivor: flush any pending fresh rows (they belong after it), moving\n // the anchor to the first flushed node so this row lands before them.\n const record = oldRecords[src];\n windowRecords[j] = record;\n const node = record.element as unknown as Node;\n if (fragment && fragment.firstChild) {\n const firstFlushed = fragment.firstChild;\n parent.insertBefore(fragment, anchor);\n anchor = firstFlushed;\n fragment = null;\n }\n if (!stable || !stable[j]) {\n parent.insertBefore(node, anchor);\n }\n anchor = node;\n }\n if (fragment && fragment.firstChild) parent.insertBefore(fragment, anchor);\n\n // Stitch the untouched prefix and suffix around the window's records.\n const merged = new Array<ListItemRecord<TItem, TTagName>>(\n oldStart + (newWinLen - nullCount) + (oldLen - oldEnd),\n );\n let w = 0;\n for (let i = 0; i < oldStart; i++) merged[w++] = oldRecords[i];\n for (let j = 0; j < newWinLen; j++) {\n const record = windowRecords[j];\n if (record) merged[w++] = record;\n }\n for (let i = oldEnd; i < oldLen; i++) merged[w++] = oldRecords[i];\n runtime.records = merged;\n runtime.allRecordsCreatedAt = undefined;\n runtime.lastSyncedItems = items.slice();\n}\n\nexport function createListRuntime<TItem, TTagName extends ElementTagName = ElementTagName>(\n itemsProvider: ListItemsProvider<TItem>,\n renderItem: ListRenderer<TItem, TTagName>,\n host: ExpandedElement<TTagName>,\n index: number,\n): ListRuntime<TItem, TTagName> {\n if (isHydrating()) {\n return hydrateListRuntime(itemsProvider, renderItem, host, index);\n }\n\n return createListRuntimeNormal(itemsProvider, renderItem, host, index);\n}\n\nfunction createListRuntimeNormal<TItem, TTagName extends ElementTagName>(\n itemsProvider: ListItemsProvider<TItem>,\n renderItem: ListRenderer<TItem, TTagName>,\n host: ExpandedElement<TTagName>,\n index: number,\n): ListRuntime<TItem, TTagName> {\n const { start: startMarker, end: endMarker } = createMarkerPair(\"list\", index);\n\n const runtime: ListRuntime<TItem, TTagName> = {\n itemsProvider,\n renderItem,\n startMarker,\n endMarker,\n records: [],\n host,\n lastSyncedItems: [],\n };\n\n const parentNode = host as unknown as Node & ParentNode;\n parentNode.appendChild(startMarker);\n parentNode.appendChild(endMarker);\n\n sync(runtime);\n\n if (isBrowser) {\n // Register for future update() calls — not needed in SSR\n registerListRuntime(startMarker, runtime as ListRuntime<unknown, ElementTagName>);\n }\n\n return runtime;\n}\n\nfunction hydrateListRuntime<TItem, TTagName extends ElementTagName>(\n itemsProvider: ListItemsProvider<TItem>,\n renderFn: ListRenderer<TItem, TTagName>,\n host: ExpandedElement<TTagName>,\n index: number,\n): ListRuntime<TItem, TTagName> {\n const parentNode = host as unknown as Node & ParentNode;\n\n // Check if next child is actually a list-start comment marker.\n // If not, fall back to normal (non-hydration) list creation.\n skipWhitespaceText(parentNode);\n const candidate = peekChild(parentNode);\n if (!candidate || candidate.nodeType !== 8 ||\n !(candidate as Comment).textContent?.startsWith('list-start-')) {\n return createListRuntimeNormal(itemsProvider, renderFn, host, index);\n }\n\n // Claim existing start marker\n const startMarker = claimChild(parentNode) as Comment;\n\n // Find end marker (without claiming) so we know when to stop.\n // Pairs are depth-counted in case nested list markers share this host.\n let depth = 0;\n let scanNode: Node | null = peekChild(parentNode);\n while (scanNode) {\n if (scanNode.nodeType === 8) {\n const text = (scanNode as Comment).textContent || '';\n if (text.startsWith('list-start-')) {\n depth++;\n } else if (text === 'list-end') {\n if (depth === 0) break;\n depth--;\n }\n }\n scanNode = scanNode.nextSibling;\n }\n let endMarker = scanNode as Comment | null;\n if (!endMarker) {\n // Corrupt/truncated SSR output — recreate the end marker; every item\n // claim below will miss and render fresh.\n const created = createComment('list-end');\n if (created) {\n parentNode.insertBefore(created, startMarker.nextSibling);\n endMarker = created;\n }\n }\n if (!endMarker) {\n return createListRuntimeNormal(itemsProvider, renderFn, host, index);\n }\n\n // Get current items and claim existing elements by running render functions\n const currentItems = normalizeItems(itemsProvider());\n const records: ListItemRecord<TItem, TTagName>[] = [];\n\n for (let i = 0; i < currentItems.length; i++) {\n const result = renderFn(currentItems[i], i);\n const rendered = isRenderedRow<TTagName>(result) ? result : null;\n const element = rendered\n ? rendered.element\n : resolveRenderable<TTagName>(result as never, host, i);\n if (element) {\n records.push({\n item: currentItems[i],\n element,\n refresh: rendered && typeof rendered.update === \"function\" ? rendered.update : undefined,\n });\n }\n }\n\n // Reconcile server/client mismatches.\n // 1) Server rendered more items than the client has: remove the leftover\n // nodes between the claim cursor and the end marker.\n let leftover = peekChild(parentNode);\n while (leftover && leftover !== endMarker) {\n const next: Node | null = leftover.nextSibling;\n safeRemoveChild(leftover);\n leftover = next;\n }\n\n // 2) Client has items the claim pass could not match: place them in item\n // order, anchored backwards from the end marker (same strategy as sync()).\n let anchor: Node = endMarker;\n for (let i = records.length - 1; i >= 0; i--) {\n const recordNode = records[i].element as unknown as Node;\n if (recordNode.parentNode !== parentNode || recordNode.nextSibling !== anchor) {\n parentNode.insertBefore(recordNode, anchor);\n }\n anchor = recordNode;\n }\n\n // Advance cursor past end marker\n setCursor(parentNode, endMarker.nextSibling);\n\n const runtime: ListRuntime<TItem, TTagName> = {\n itemsProvider,\n renderItem: renderFn,\n startMarker,\n endMarker,\n records,\n host,\n lastSyncedItems: currentItems.slice(),\n };\n\n if (isBrowser) {\n registerListRuntime(startMarker, runtime as ListRuntime<unknown, ElementTagName>);\n }\n\n return runtime;\n}\n\n/**\n * Drops a disconnected runtime's item/element references. The runtime object\n * can outlive its list (it stays reachable through the WeakMap entry while\n * someone still references the detached subtree), so clearing the records\n * keeps it from pinning the items.\n */\nfunction releaseRuntime(runtime: ListRuntime<unknown, ElementTagName>): void {\n runtime.template = null;\n runtime.lastRenderLeaves = null;\n runtime.lastRenderRefresh = null;\n for (let i = 0; i < runtime.records.length; i++) {\n const record = runtime.records[i] as { item: unknown; element: unknown; dyn?: unknown; refresh?: unknown };\n record.element = null;\n record.item = null;\n record.dyn = null;\n record.refresh = null;\n delete (record as { dynCreatedAt?: number }).dynCreatedAt;\n }\n runtime.records = [];\n runtime.lastSyncedItems = [];\n runtime.allRecordsCreatedAt = undefined;\n}\n\nexport function updateListRuntimes(scope?: UpdateScope): void {\n const toDelete: WeakRef<Comment>[] = [];\n updateListFlushEpoch++;\n\n for (const ref of activeListRuntimes) {\n const startMarker = ref.deref();\n\n // Marker was garbage collected\n if (!startMarker) {\n toDelete.push(ref);\n continue;\n }\n\n const runtime = listRuntimeByMarker.get(startMarker);\n if (!runtime) {\n toDelete.push(ref);\n continue;\n }\n\n // Clean up if disconnected from DOM\n if (!isNodeConnected(startMarker) || !isNodeConnected(runtime.endMarker)) {\n releaseRuntime(runtime);\n listRuntimeByMarker.delete(startMarker);\n toDelete.push(ref);\n continue;\n }\n\n // Skip if outside update scope\n if (scope && !scope.contains(startMarker)) continue;\n\n runtime.currentFlushEpoch = updateListFlushEpoch;\n try {\n sync(runtime);\n } finally {\n runtime.currentFlushEpoch = undefined;\n }\n\n // Flush template rows' record-owned dynamic leaves. Rows built through\n // the normal path registered globally and are flushed by the notify\n // passes instead.\n if (runtime.allRecordsCreatedAt === updateListFlushEpoch) continue;\n const records = runtime.records;\n for (let i = 0; i < records.length; i++) {\n if (records[i].dynCreatedAt === updateListFlushEpoch) continue;\n const refresh = records[i].refresh;\n if (refresh) refresh();\n const dyn = records[i].dyn;\n if (dyn) flushRowLeaves(dyn);\n }\n }\n\n // Clean up dead references\n for (const ref of toDelete) {\n activeListRuntimes.delete(ref);\n }\n}\n","import { createListRuntime } from \"./runtime\";\nimport type { ListRenderer, ListItemsProvider } from \"./types\";\n\n/**\n * Maps items to DOM elements, keeping them in sync with changes.\n * Returns a function compatible with both HTML and SVG contexts.\n */\nexport function list<TItem, TTagName extends ElementTagName = ElementTagName>(\n itemsProvider: ListItemsProvider<TItem>,\n render: ListRenderer<TItem, TTagName>,\n): ListModifier<TTagName> {\n return function<TParent extends ElementTagName>(host: ExpandedElement<TParent>, index: number): Comment {\n const runtime = createListRuntime(itemsProvider, render, host as unknown as ExpandedElement<TTagName>, index);\n // Return the start marker comment node\n // Comment is a Node, making this compatible with both HTML and SVG modifiers\n return runtime.startMarker;\n } as unknown as ListModifier<TTagName>;\n}\n","export type ConditionInput = boolean | (() => boolean);\n\nexport function runCondition(\n condition: () => boolean,\n onError?: (error: unknown) => void\n): boolean {\n try {\n return condition();\n } catch (error) {\n if (onError) {\n onError(error);\n return false;\n }\n throw error;\n }\n}\n\nexport function resolveCondition(\n value: ConditionInput,\n onError?: (error: unknown) => void\n): boolean {\n return typeof value === \"function\" ? runCondition(value, onError) : Boolean(value);\n}\n","import { clearBetweenMarkers, insertNodesBefore, isNodeConnected, withScopedInsertion } from \"../shared/dom\";\nimport { resolveCondition } from \"../shared/conditions\";\nimport type { UpdateScope } from \"../update/scope\";\nimport { applyNodeModifier, modifierProbeCache } from \"../element/modifiers\";\nimport { isFunction, isZeroArityFunction } from \"../shared/type-guards\";\nimport { logError } from \"../shared/errors\";\n\nexport type WhenCondition = boolean | (() => boolean);\nexport type WhenContent<TTagName extends ElementTagName = ElementTagName> =\n NodeModLike<TTagName>;\n\nexport interface WhenGroup<TTagName extends ElementTagName = ElementTagName> {\n condition: WhenCondition;\n content: WhenContent<TTagName>[];\n}\n\nexport interface WhenRuntime<TTagName extends ElementTagName = ElementTagName> {\n startMarker: Comment;\n endMarker: Comment;\n host: ExpandedElement<TTagName>;\n index: number;\n groups: WhenGroup<TTagName>[];\n elseContent: WhenContent<TTagName>[];\n /**\n * Tracks which branch is currently rendered:\n * - null: nothing rendered yet (initial state)\n * - -1: else branch is active\n * - >= 0: groups[activeIndex] is active\n */\n activeIndex: number | null;\n update(): void;\n}\n\n/**\n * Registry of active when runtimes.\n *\n * The iteration set only holds WeakRefs; the runtime itself lives in a\n * WeakMap keyed by its start marker. This keeps the global registry free of\n * strong references to the runtime (which holds the host element, branch\n * content, and markers), so removing the surrounding DOM subtree makes the\n * runtime collectible — even if update() is never called again. The\n * FinalizationRegistry prunes dead WeakRefs once the marker is collected;\n * updateWhenRuntimes() also prunes as it iterates.\n */\nconst activeWhenRuntimes = new Set<WeakRef<Comment>>();\nconst whenRuntimeByMarker = new WeakMap<Comment, WhenRuntime<ElementTagName>>();\nconst whenMarkerFinalizer = typeof FinalizationRegistry !== \"undefined\"\n ? new FinalizationRegistry<WeakRef<Comment>>((ref) => { activeWhenRuntimes.delete(ref); })\n : null;\n\n/**\n * Evaluates which condition branch should be active.\n * Returns the index of the first truthy condition, -1 for else branch, or null for no match.\n */\nexport function evaluateActiveCondition<TTagName extends ElementTagName>(\n groups: ReadonlyArray<WhenGroup<TTagName>>,\n elseContent: ReadonlyArray<WhenContent<TTagName>>\n): number | null {\n for (let i = 0; i < groups.length; i++) {\n if (resolveCondition(groups[i].condition)) {\n return i;\n }\n }\n return elseContent.length > 0 ? -1 : null;\n}\n\n/**\n * Main render function for when/else conditionals.\n * Evaluates conditions, clears old content, and renders the active branch.\n */\nexport function renderWhenContent<TTagName extends ElementTagName>(\n runtime: WhenRuntime<TTagName>\n): void {\n const { groups, elseContent, host, index, endMarker } = runtime;\n\n const newActive = evaluateActiveCondition(groups, elseContent);\n\n // No change needed\n if (newActive === runtime.activeIndex) return;\n\n // Clear previous content and update active index\n clearBetweenMarkers(runtime.startMarker, runtime.endMarker);\n runtime.activeIndex = newActive;\n\n // Nothing to render\n if (newActive === null) return;\n\n // Render the active branch\n const contentToRender = newActive >= 0 ? groups[newActive].content : elseContent;\n const nodes = renderContentItems(contentToRender, host, index, endMarker);\n\n insertNodesBefore(nodes, endMarker);\n}\n\n/**\n * Registers a when runtime for tracking and updates.\n * Uses WeakRef to prevent memory leaks when elements are removed.\n * The runtime object itself is mutable and will be updated in place.\n */\nexport function registerWhenRuntime<TTagName extends ElementTagName>(\n runtime: WhenRuntime<TTagName>\n): void {\n const ref = new WeakRef(runtime.startMarker);\n activeWhenRuntimes.add(ref);\n whenRuntimeByMarker.set(runtime.startMarker, runtime as WhenRuntime<ElementTagName>);\n whenMarkerFinalizer?.register(runtime.startMarker, ref);\n}\n\n/**\n * Updates all active when/else conditional runtimes.\n *\n * Re-evaluates all conditional branches and re-renders if the active branch has changed.\n * Automatically cleans up runtimes that are garbage collected or disconnected from DOM.\n *\n * This function should be called after state changes that affect conditional expressions.\n *\n * @example\n * ```ts\n * isLoggedIn.value = true;\n * updateWhenRuntimes(); // All when() conditionals re-evaluate\n * ```\n */\nexport function updateWhenRuntimes(scope?: UpdateScope): void {\n const toDelete: WeakRef<Comment>[] = [];\n\n for (const ref of activeWhenRuntimes) {\n const startMarker = ref.deref();\n\n // Comment node was garbage collected\n if (startMarker === undefined) {\n toDelete.push(ref);\n continue;\n }\n\n const runtime = whenRuntimeByMarker.get(startMarker);\n if (!runtime) {\n toDelete.push(ref);\n continue;\n }\n\n // Check if markers are still connected to DOM\n if (!isNodeConnected(startMarker) || !isNodeConnected(runtime.endMarker)) {\n whenRuntimeByMarker.delete(startMarker);\n toDelete.push(ref);\n continue;\n }\n\n // Skip if outside update scope\n if (scope && !scope.contains(startMarker)) continue;\n\n try {\n runtime.update();\n } catch (error) {\n // Clean up runtimes that throw errors\n logError(\"when() branch threw during update; unregistering this conditional\", error);\n whenRuntimeByMarker.delete(startMarker);\n toDelete.push(ref);\n }\n }\n\n // Clean up dead references\n for (const ref of toDelete) {\n activeWhenRuntimes.delete(ref);\n }\n}\n\n// ─── Content rendering ───────────────────────────────────────────────────────\n/**\n * Renders a single content item and returns the resulting node if any.\n */\nfunction renderContentItem<TTagName extends ElementTagName>(\n item: WhenContent<TTagName>,\n host: ExpandedElement<TTagName>,\n index: number,\n endMarker: Comment\n): Node | null {\n if (!isFunction(item)) {\n return applyNodeModifier(host, item, index);\n }\n\n // Zero-arity functions need cache cleared\n if (isZeroArityFunction(item)) {\n modifierProbeCache.delete(item);\n return applyNodeModifier(host, item, index);\n }\n\n // Non-zero-arity functions need scoped insertion to insert before endMarker\n return withScopedInsertion(host, endMarker, () => {\n const maybeNode = applyNodeModifier(host, item, index);\n // Only include nodes that weren't already inserted\n return maybeNode && !maybeNode.parentNode ? maybeNode : null;\n });\n}\n\n/**\n * Renders a list of content items and collects the resulting nodes.\n */\nexport function renderContentItems<TTagName extends ElementTagName>(\n items: ReadonlyArray<WhenContent<TTagName>>,\n host: ExpandedElement<TTagName>,\n index: number,\n endMarker: Comment\n): Node[] {\n const nodes: Node[] = [];\n for (const item of items) {\n const node = renderContentItem(item, host, index, endMarker);\n if (node) {\n nodes.push(node);\n }\n }\n return nodes;\n}\n","import { createMarkerPair, createComment, clearBetweenMarkers, insertNodesBefore, asParentNode } from \"../shared/dom\";\nimport type { WhenCondition, WhenContent, WhenGroup, WhenRuntime } from \"./runtime\";\nimport { renderWhenContent, registerWhenRuntime, evaluateActiveCondition, renderContentItems } from \"./runtime\";\nimport { isBrowser } from \"../shared/environment\";\nimport { isHydrating, claimChild, peekChild, setCursor, skipWhitespaceText, runWithoutHydration } from \"../hydration\";\nimport { applyNodeModifier } from \"../element/modifiers\";\n\n/**\n * Encodes the active branch into the start marker so hydration can detect\n * server/client branch mismatches: `when-start-{index}-b{branch}` where\n * branch is the group index, -1 for the else branch, or `n` for none.\n */\nfunction encodeBranch(index: number, activeIndex: number | null): string {\n return `when-start-${index}-b${activeIndex === null ? 'n' : activeIndex}`;\n}\n\n/**\n * Reads the branch encoded in an SSR start marker.\n * Returns `undefined` for legacy markers without branch info.\n */\nfunction decodeBranch(markerText: string | null): number | null | undefined {\n const match = /-b(n|-?\\d+)$/.exec(markerText || '');\n if (!match) return undefined;\n return match[1] === 'n' ? null : parseInt(match[1], 10);\n}\n\nclass WhenBuilderImpl<TTagName extends ElementTagName = ElementTagName> {\n private groups: WhenGroup<TTagName>[] = [];\n private elseContent: WhenContent<TTagName>[] = [];\n\n constructor(initialCondition: WhenCondition, ...content: WhenContent<TTagName>[]) {\n this.groups.push({ condition: initialCondition, content });\n }\n\n cloneWith(\n additionalGroup?: WhenGroup<TTagName>,\n newElseContent?: WhenContent<TTagName>[],\n ): WhenBuilderImpl<TTagName> {\n const b = Object.create(WhenBuilderImpl.prototype) as WhenBuilderImpl<TTagName>;\n b.groups = [...this.groups];\n if (additionalGroup) b.groups.push(additionalGroup);\n b.elseContent = newElseContent ?? [...this.elseContent];\n return b;\n }\n\n when(condition: WhenCondition, ...content: WhenContent<TTagName>[]): WhenBuilderImpl<TTagName> {\n this.groups.push({ condition, content });\n return this;\n }\n\n else(...content: WhenContent<TTagName>[]): WhenBuilderImpl<TTagName> {\n this.elseContent = content;\n return this;\n }\n\n render(host: ExpandedElement<TTagName>, index: number): Node | null {\n if (!globalThis.document) {\n return null;\n }\n\n if (isHydrating()) {\n return this.hydrateRender(host, index);\n }\n\n return this.freshRender(host, index);\n }\n\n private freshRender(host: ExpandedElement<TTagName>, index: number): Node | null {\n const { start: startMarker, end: endMarker } = createMarkerPair(\"when\", index);\n const runtime = this.createRuntimeFromMarkers(host, index, startMarker, endMarker);\n\n const parent = asParentNode(host);\n parent.appendChild(startMarker);\n parent.appendChild(endMarker);\n\n renderWhenContent(runtime);\n\n // Record which branch was rendered so hydration can detect mismatches.\n startMarker.textContent = encodeBranch(index, runtime.activeIndex);\n\n return startMarker;\n }\n\n private hydrateRender(host: ExpandedElement<TTagName>, index: number): Node | null {\n const parentNode = host as unknown as Node & ParentNode;\n\n // Check if next child is actually a when-start comment marker.\n // If the SSR HTML doesn't contain Nuclo comment markers, fall back\n // to normal rendering (create new markers + render from scratch).\n skipWhitespaceText(parentNode);\n const candidate = peekChild(parentNode);\n if (!candidate || candidate.nodeType !== 8 ||\n !(candidate as Comment).textContent?.startsWith('when-start-')) {\n return this.freshRender(host, index);\n }\n\n // Claim existing start marker\n const startMarker = claimChild(parentNode) as Comment;\n\n // Find end marker (without claiming). Directly nested when() blocks\n // share this host, so matching pairs must be depth-counted.\n let depth = 0;\n let scanNode: Node | null = peekChild(parentNode);\n while (scanNode) {\n if (scanNode.nodeType === 8) {\n const text = (scanNode as Comment).textContent || '';\n if (text.startsWith('when-start-')) {\n depth++;\n } else if (text === 'when-end') {\n if (depth === 0) break;\n depth--;\n }\n }\n scanNode = scanNode.nextSibling;\n }\n let endMarker = scanNode as Comment | null;\n let endMarkerMissing = false;\n if (!endMarker) {\n // Corrupt/truncated SSR output — recreate the end marker right after\n // the start marker and render the branch fresh.\n const created = createComment('when-end');\n if (!created) return startMarker;\n parentNode.insertBefore(created, startMarker.nextSibling);\n endMarker = created;\n endMarkerMissing = true;\n }\n\n // Determine which branch the client wants and which the server rendered.\n const activeIndex = evaluateActiveCondition(this.groups, this.elseContent);\n const serverBranch = decodeBranch(startMarker.textContent);\n const branchMatches = !endMarkerMissing &&\n (serverBranch === undefined || serverBranch === activeIndex);\n\n if (branchMatches) {\n // Re-run active branch content to register reactivity on existing nodes\n if (activeIndex !== null) {\n const contentToRender = activeIndex >= 0 ? this.groups[activeIndex].content : this.elseContent;\n for (const item of contentToRender) {\n applyNodeModifier(host, item as NodeMod<TTagName> | NodeModFn<TTagName>, index);\n }\n }\n } else {\n // Server rendered a different branch (or the markup is unusable):\n // drop the server content and render the client branch fresh.\n clearBetweenMarkers(startMarker, endMarker);\n if (activeIndex !== null) {\n const contentToRender = activeIndex >= 0 ? this.groups[activeIndex].content : this.elseContent;\n const end = endMarker;\n runWithoutHydration(() => {\n const nodes = renderContentItems(contentToRender, host, index, end);\n insertNodesBefore(nodes, end);\n });\n }\n }\n\n // Advance cursor past end marker\n setCursor(parentNode, endMarker.nextSibling);\n\n this.createRuntimeFromMarkers(host, index, startMarker, endMarker, activeIndex);\n\n return startMarker;\n }\n\n private createRuntimeFromMarkers(\n host: ExpandedElement<TTagName>,\n index: number,\n startMarker: Comment,\n endMarker: Comment,\n activeIndex: number | null = null,\n ): WhenRuntime<TTagName> {\n const runtime: WhenRuntime<TTagName> = {\n startMarker,\n endMarker,\n host,\n index,\n groups: [...this.groups],\n elseContent: [...this.elseContent],\n activeIndex,\n update: function() { renderWhenContent(runtime); },\n };\n\n if (isBrowser) {\n registerWhenRuntime(runtime);\n }\n\n return runtime;\n }\n}\n\nexport function createWhenBuilderFunction<TTagName extends ElementTagName>(\n builder: WhenBuilderImpl<TTagName>\n): WhenBuilder<TTagName> {\n const nodeModFn = function(host: ExpandedElement<TTagName>, index: number): Node | null {\n return builder.render(host, index);\n };\n\n return Object.assign(nodeModFn, {\n when: function(condition: WhenCondition, ...content: WhenContent<TTagName>[]): WhenBuilder<TTagName> {\n return createWhenBuilderFunction(builder.cloneWith({ condition, content }));\n },\n else: function(...content: WhenContent<TTagName>[]): WhenBuilder<TTagName> {\n return createWhenBuilderFunction(builder.cloneWith(undefined, content));\n },\n }) as unknown as WhenBuilder<TTagName>;\n}\n\nexport { WhenBuilderImpl };\n","import { WhenBuilderImpl, createWhenBuilderFunction } from \"./builder\";\nimport type { WhenCondition, WhenContent } from \"./runtime\";\n\nexport { updateWhenRuntimes } from \"./runtime\";\n\n/**\n * Creates a conditional rendering block (when/else logic).\n *\n * Renders different content based on boolean conditions, similar to if/else statements.\n * Conditions can be static booleans or reactive functions that are re-evaluated on updates.\n *\n * @param condition - Boolean value or function returning a boolean\n * @param content - Content to render when condition is true\n * @returns A builder that allows chaining additional .when() or .else() branches\n *\n * @example\n * ```ts\n * const isLoggedIn = signal(false);\n *\n * div(\n * when(() => isLoggedIn.value,\n * span('Welcome back!')\n * )\n * .else(\n * button('Login', on('click', () => login()))\n * )\n * )\n * ```\n *\n * @example\n * ```ts\n * // Multiple conditions\n * div(\n * when(() => status.value === 'loading',\n * spinner()\n * )\n * .when(() => status.value === 'error',\n * errorMessage()\n * )\n * .else(\n * contentView()\n * )\n * )\n * ```\n */\nexport function when<TTagName extends ElementTagName = ElementTagName>(\n condition: WhenCondition,\n ...content: WhenContent<TTagName>[]\n): WhenBuilder<TTagName> {\n const builder = new WhenBuilderImpl<TTagName>(condition, ...content);\n return createWhenBuilderFunction(builder);\n}\n","import { createHtmlElementWithModifiers, createSvgElementWithModifiers } from \"../element/factory\";\nimport { isBrowser } from \"../shared/environment\";\nimport {\n ConditionalInfo,\n getConditionalInfo,\n storeConditionalInfo,\n getActiveConditionalNodes,\n unregisterConditionalNode,\n} from \"./registry\";\nimport { runCondition } from \"../shared/conditions\";\nimport { replaceNodeSafely, createConditionalComment, createElement, createElementNS, SVG_NAMESPACE, disposeLifecyclesInSubtree } from \"../shared/dom\";\nimport { logError } from \"../shared/errors\";\nimport type { UpdateScope } from \"./scope\";\n\nfunction createElementFromConditionalInfo<TTagName extends ElementTagName>(\n conditionalInfo: ConditionalInfo<TTagName>\n): ExpandedElement<TTagName> | SVGElement {\n try {\n if (conditionalInfo.isSvg) {\n return createSvgElementWithModifiers(conditionalInfo.tagName as keyof SVGElementTagNameMap, conditionalInfo.modifiers);\n }\n return createHtmlElementWithModifiers(conditionalInfo.tagName, conditionalInfo.modifiers);\n } catch (error) {\n logError(`Error applying modifiers in conditional element \"${conditionalInfo.tagName}\"`, error);\n // Return a basic element without modifiers as fallback\n if (conditionalInfo.isSvg) {\n const el = createElementNS(SVG_NAMESPACE, conditionalInfo.tagName);\n if (!el) {\n throw new Error(`Failed to create SVG element: ${conditionalInfo.tagName}`, { cause: error });\n }\n return el as unknown as SVGElement;\n }\n const el = createElement(conditionalInfo.tagName);\n if (!el) {\n throw new Error(`Failed to create element: ${conditionalInfo.tagName}`, { cause: error });\n }\n return el as ExpandedElement<TTagName>;\n }\n}\n\nfunction updateConditionalNode(node: Element | Comment): void {\n const conditionalInfo = getConditionalInfo(node);\n if (!conditionalInfo) {\n return;\n }\n\n const shouldShow = runCondition(conditionalInfo.condition, (error) => {\n logError(\"Error evaluating conditional condition\", error);\n });\n const isElement = node.nodeType === Node.ELEMENT_NODE;\n\n if (shouldShow && !isElement) {\n const element = createElementFromConditionalInfo(conditionalInfo);\n storeConditionalInfo(element as Node, conditionalInfo);\n replaceNodeSafely(node, element as Node);\n } else if (!shouldShow && isElement) {\n const comment = createConditionalComment(conditionalInfo.tagName);\n if (comment) {\n // replaceNodeSafely() below doesn't walk the outgoing element the way\n // safeRemoveChild() does, so fire its onDestroy (if any) here first.\n disposeLifecyclesInSubtree(node);\n storeConditionalInfo(comment, conditionalInfo);\n replaceNodeSafely(node, comment);\n }\n }\n}\n\nexport function updateConditionalElements(scope?: UpdateScope): void {\n if (!isBrowser) return;\n\n try {\n const nodes = getActiveConditionalNodes();\n for (const node of nodes) {\n if (!node.isConnected) {\n unregisterConditionalNode(node);\n continue;\n }\n\n if (scope && !scope.contains(node)) continue;\n updateConditionalNode(node as Element | Comment);\n }\n } catch (error) {\n logError(\"Error during conditional elements update\", error);\n }\n}\n","/**\n * scope() – tags an element as the root of a named update scope so\n * `update(\"name\")` can refresh just that part of the page.\n */\nimport { isNodeConnected } from \"../shared/dom\";\nimport { isBrowser } from \"../shared/environment\";\n\nexport interface UpdateScope {\n roots: ReadonlyArray<Element>;\n contains(node: Node): boolean;\n}\n\n\ntype ScopeId = string;\n\n/**\n * Stores weak references to scope root elements.\n * Using WeakRef prevents memory leaks - elements can be garbage collected when removed from DOM.\n */\nconst scopeRootsById = new Map<ScopeId, Set<WeakRef<Element>>>();\n\nfunction normalizeScopeIds(ids: readonly string[]): ScopeId[] {\n const normalized: ScopeId[] = [];\n const seen = new Set<ScopeId>();\n\n for (const raw of ids) {\n if (typeof raw !== \"string\") continue;\n const id = raw.trim();\n if (!id) continue;\n if (seen.has(id)) continue;\n seen.add(id);\n normalized.push(id);\n }\n\n return normalized;\n}\n\nfunction addScopeRoot(id: ScopeId, el: Element): void {\n let set = scopeRootsById.get(id);\n if (!set) {\n set = new Set<WeakRef<Element>>();\n scopeRootsById.set(id, set);\n }\n set.add(new WeakRef(el));\n}\n\nexport function getScopeRoots(ids: readonly string[]): Element[] {\n const scopeIds = normalizeScopeIds(ids);\n if (scopeIds.length === 0) return [];\n\n const roots = new Set<Element>();\n\n for (const id of scopeIds) {\n const set = scopeRootsById.get(id);\n if (!set) continue;\n\n const toDelete: WeakRef<Element>[] = [];\n\n for (const ref of set) {\n const el = ref.deref();\n if (el === undefined) {\n // Element was garbage collected\n toDelete.push(ref);\n continue;\n }\n if (!isNodeConnected(el)) {\n // Element is disconnected, clean it up\n toDelete.push(ref);\n continue;\n }\n roots.add(el);\n }\n\n // Clean up dead and disconnected references\n for (const ref of toDelete) {\n set.delete(ref);\n }\n\n if (set.size === 0) scopeRootsById.delete(id);\n }\n\n return Array.from(roots);\n}\n\nexport function scope<TTagName extends ElementTagName = ElementTagName>(\n ...ids: string[]\n): NodeModFn<TTagName> {\n const scopeIds = normalizeScopeIds(ids);\n\n return function(parent: ExpandedElement<TTagName>): void {\n if (!isBrowser) return;\n if (!(parent instanceof Element)) return;\n for (const id of scopeIds) addScopeRoot(id, parent);\n };\n}\n","/**\n * update() – the heart of nuclo's reactivity. Re-runs every registered\n * reactive part of the page: lists, when() blocks, conditional elements,\n * function-valued attributes and text, then fires a global \"update\" event.\n */\nimport { updateListRuntimes } from \"../list/runtime\";\nimport { notifyReactiveElements } from \"./reactive-attributes\";\nimport { notifyReactiveTextNodes } from \"./reactive-text\";\nimport { updateWhenRuntimes } from \"../when\";\nimport { updateConditionalElements } from \"./conditional\";\nimport { getScopeRoots } from \"./scope\";\nimport { logError } from \"../shared/errors\";\nimport { flushMountQueue } from \"../element/lifecycle\";\nimport type { UpdateScope } from \"./scope\";\n\n// `satisfies` checks every entry matches the signature without widening the tuple type.\nconst updaters = [\n\tupdateListRuntimes,\n\tupdateWhenRuntimes,\n\tupdateConditionalElements,\n\tnotifyReactiveElements,\n\tnotifyReactiveTextNodes,\n\tdispatchGlobalUpdateEvent,\n] satisfies ReadonlyArray<(scope?: UpdateScope) => void>;\n\nexport function update(...scopeIds: string[]): void {\n\tlet scope: UpdateScope | undefined;\n\n\tif (scopeIds.length > 0) {\n\t\tconst roots = getScopeRoots(scopeIds);\n\n\t\tif (roots.length === 1) {\n\t\t\tconst root = roots[0]!;\n\t\t\tscope = {\n\t\t\t\troots,\n\t\t\t\tcontains: (node) => root.contains(node),\n\t\t\t};\n\t\t} else {\n\t\t\tscope = {\n\t\t\t\troots,\n\t\t\t\tcontains: (node) => {\n\t\t\t\t\tfor (const root of roots) {\n\t\t\t\t\t\tif (root.contains(node)) return true;\n\t\t\t\t\t}\n\t\t\t\t\treturn false;\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\t}\n\n\tfor (const fn of updaters) fn(scope);\n\n\t// Every updater above may have inserted new nodes (a new list() row, a\n\t// newly-true when() branch, a conditional element flipping on) into an\n\t// already-connected host. Flush once, after all of them ran, so onMount\n\t// fires exactly once per pass with the DOM already settled — not once per\n\t// updater.\n\tflushMountQueue();\n}\n\nexport function dispatchGlobalUpdateEvent(scope?: UpdateScope): void {\n if (typeof document === \"undefined\") return;\n\n // Scoped update: the event fires on the scope roots (bubbling up from\n // there), not on the whole document — listeners outside the scope's\n // ancestor chain must not observe a scoped update. An unknown scope id\n // (zero roots) dispatches nothing.\n // Unscoped: a single dispatch on body (or document as fallback) — the\n // event bubbles to document on its own; dispatching on both would run\n // document-level listeners twice.\n const targets: readonly EventTarget[] = scope\n ? scope.roots\n : [document.body ?? document];\n\n for (const target of targets) {\n try {\n target.dispatchEvent(new Event(\"update\", { bubbles: true }));\n } catch (error) {\n logError(\"Error dispatching global update event\", error);\n }\n }\n}\n","import { startHydration, endHydration, peekChild, setCursor } from \"./hydration\";\nimport { safeRemoveChild } from \"./shared/dom\";\nimport { flushMountQueue } from \"./element/lifecycle\";\n\n/**\n * Renders a NodeModFn to a parent element by calling it and appending the result.\n *\n * @param nodeModFn The NodeModFn to render (created by tag builders like div(), h1(), etc.)\n * @param parent The parent element to render into (defaults to document.body)\n * @param index The index to pass to the NodeModFn (defaults to 0)\n * @returns The rendered element\n */\nexport function render<TTagName extends ElementTagName = ElementTagName>(\n nodeModFn: NodeModFn<TTagName>,\n parent?: Element,\n index: number = 0\n): ExpandedElement<TTagName> {\n const targetParent = (parent || document.body) as ExpandedElement<TTagName>;\n const element = nodeModFn(targetParent, index) as ExpandedElement<TTagName>;\n (targetParent as unknown as Node).appendChild(element as Node);\n // The whole tree was built off-document and just got attached in this one\n // call — every onMount queued while building it can fire now.\n flushMountQueue();\n return element;\n}\n\n/**\n * Hydrates an existing server-rendered DOM tree by walking it in parallel with\n * the component tree, reusing existing nodes and re-attaching reactivity.\n *\n * Instead of clearing the container and creating new DOM nodes (like render()),\n * hydrate() claims existing nodes from the SSR output and registers reactive\n * text nodes, attributes, event listeners, list runtimes, and when runtimes\n * on them.\n *\n * @param nodeModFn The NodeModFn to hydrate (same component used for SSR)\n * @param parent The parent element containing the SSR HTML (defaults to document.body)\n * @returns The hydrated root element\n *\n * @example\n * ```ts\n * // Server: const html = renderToString(div(h1(\"Hello\")));\n * // Client:\n * const app = document.getElementById(\"app\")!;\n * // app.innerHTML already contains the SSR HTML\n * hydrate(div(h1(\"Hello\")), app);\n * ```\n */\nexport function hydrate<TTagName extends ElementTagName = ElementTagName>(\n nodeModFn: NodeModFn<TTagName>,\n parent?: Element,\n): ExpandedElement<TTagName> {\n const targetParent = (parent || document.body) as ExpandedElement<TTagName>;\n const parentNode = targetParent as unknown as Node & ParentNode;\n startHydration();\n let element: ExpandedElement<TTagName>;\n try {\n element = nodeModFn(targetParent, 0) as ExpandedElement<TTagName>;\n const elementNode = element as unknown as Node | null | undefined;\n // Claim failed (empty container or tag mismatch): the factory built a\n // fresh, detached root. Replace the mismatched SSR node at the cursor —\n // or append when there is nothing to replace — so the app is always live\n // in the document. Only the single candidate node is touched; siblings\n // (other roots, scripts) are preserved.\n if (elementNode && elementNode.nodeType === 1 && elementNode.parentNode !== parentNode) {\n const stale = peekChild(parentNode);\n if (stale) {\n const after = stale.nextSibling;\n parentNode.insertBefore(elementNode, stale);\n safeRemoveChild(stale);\n setCursor(parentNode, after);\n } else {\n parentNode.appendChild(elementNode);\n setCursor(parentNode, null);\n }\n }\n } finally {\n endHydration();\n }\n // Claimed nodes were already connected (they're existing SSR output inside\n // the live `parent`); freshly-built replacement nodes just got attached\n // above. Either way, by this point everything nodeModFn() touched is\n // settled in the document, so queued onMount callbacks can fire — but only\n // on this success path. Placed outside the try/finally on purpose: if\n // nodeModFn() throws, the tree it was building is incomplete/inconsistent,\n // so any mounts it had already queued are left Pending rather than fired.\n flushMountQueue();\n return element;\n}\n","/**\n * Shared generated-CSS engine state.\n *\n * One stylesheet, one rule registry, shared by every `createCss` instance so\n * identical declarations dedupe globally and cascade order stays deterministic:\n * base rules first (insertion order), then one grouping rule per at-rule query\n * in registration order (theme `screens` order).\n *\n * Browser: rules are injected through CSSOM with O(1) appends — no rescans.\n * SSR: rules accumulate in the registry; `getCssText()` serializes them.\n *\n * The state below lives on `globalThis`, keyed by a `Symbol.for(...)` (the\n * global symbol registry, shared by every realm-local copy of this module).\n * `nuclo` publishes `.`, `./ssr`, and `./polyfill` as independently built\n * bundle files (see tsdown.config.ts) — a consumer that resolves them\n * through normal package resolution (any bundler/runtime that doesn't\n * alias every subpath to this same source file) loads two or three\n * separate copies of this module, each with its own module-scope\n * variables. Without a realm-wide singleton, `css()` (from `nuclo`) would\n * mint rules into one copy's registry while `getCssText()`/\n * `setSSRCollector()` (from `nuclo/ssr`) read an entirely different,\n * always-empty one — SSR output would render the right classes with no\n * matching CSS at all. Storing the registry on `globalThis` instead makes\n * every copy of this module share the same state regardless of how many\n * times it ends up bundled.\n *\n * The registry never shrinks on its own: atomCache/atomMeta/rawKeys/\n * baseRules/queryRules retain every rule for the life of the process —\n * content-addressed dedup needs a durable record of what each class means,\n * and the engine has no way to know whether a minted class still backs a\n * live DOM node (it's deliberately decoupled from element/list lifecycle),\n * so it can't safely evict. Only resetStyles() (a manual test helper)\n * clears it. This is fine for the intended use — a bounded design-token\n * vocabulary — but a caller piping truly per-instance dynamic values\n * through css({ raw: {...} }) (e.g. per-row data in a list) mints one\n * permanent class per unique value; prefer the `style` prop\n * (element/inline-style.ts) for values that vary per instance rather than\n * per design token. See test/style/registry-growth.test.ts.\n */\n\n// SSR collector — optional hook that receives every newly minted rule string\n// (wrapped in its at-rule, if any). Installed once at server startup.\ntype SSRCollector = (rule: string) => void;\n\nexport interface BlockMeta {\n\treadonly query: string | undefined;\n\treadonly suffix: string;\n\treadonly decls: ReadonlyArray<readonly [string, string]>;\n\t/** Author-supplied identity from `css(name, …)`; inherited by cx() merges. */\n\treadonly name: string | undefined;\n}\n\ninterface EngineState {\n\tssrCollector: SSRCollector | null;\n\n\t// Registry — the source of truth for all generated CSS.\n\t// atomCache: declaration-block key -> class name (dedup)\n\t// atomMeta: class name -> what the class means (its selector context and its\n\t// declarations). This is what lets cx() merge two same-context classes at the\n\t// declaration level instead of guessing: the engine can always recover the\n\t// exact content of any class it minted.\n\tatomCache: Map<string, string>;\n\tatomMeta: Map<string, BlockMeta>;\n\trawKeys: Set<string>;\n\tbaseRules: string[];\n\tqueryRules: Map<string, string[]>;\n\tstyleEpoch: number;\n\n\t// Memoized getCssText() output. SSR calls getCssText() once per request, but the\n\t// rule set is stable after warmup — so the serialized sheet is recomputed only\n\t// when a new rule is actually recorded. Invalidated in record() and resetStyles().\n\tcssTextCache: string | null;\n\n\t// Browser CSSOM state. Base rules occupy [0, baseRuleCount); grouping rules\n\t// (one per query, created in registration order) live after them. CSSRule\n\t// references stay live when indices shift, so insertion never rescans.\n\tsheet: CSSStyleSheet | null;\n\tsheetDocument: Document | null;\n\tbaseRuleCount: number;\n\tgroupRules: Map<string, CSSGroupingRule>;\n\n\t// Normalized rules already sitting in a freshly-adopted stylesheet that this\n\t// module didn't insert itself — e.g. server-rendered CSS being hydrated.\n\t// Rebuilt on every fresh bind in ensureSheet(); null when there is nothing\n\t// external to guard against.\n\texternalRules: Map<string, Set<string>> | null;\n\thasExternalGroups: boolean;\n}\n\nfunction createState(): EngineState {\n\treturn {\n\t\tssrCollector: null,\n\t\tatomCache: new Map(),\n\t\tatomMeta: new Map(),\n\t\trawKeys: new Set(),\n\t\tbaseRules: [],\n\t\tqueryRules: new Map(),\n\t\tstyleEpoch: 0,\n\t\tcssTextCache: null,\n\t\tsheet: null,\n\t\tsheetDocument: null,\n\t\tbaseRuleCount: 0,\n\t\tgroupRules: new Map(),\n\t\texternalRules: null,\n\t\thasExternalGroups: false,\n\t};\n}\n\nconst ENGINE_STATE_KEY = Symbol.for(\"nuclo.style.engine.v1\");\nconst globalScope = globalThis as unknown as Record<symbol, EngineState>;\n// Importing the runtime does not allocate the registry until styling is used.\nlet cachedState: EngineState | undefined;\nfunction getState(): EngineState {\n\treturn cachedState ??= globalScope[ENGINE_STATE_KEY] ?? (globalScope[ENGINE_STATE_KEY] = createState());\n}\n\nexport function setSSRCollector(fn: SSRCollector | null): void {\n\tconst state = getState();\n\tstate.ssrCollector = fn;\n}\n\n/** Pre-register at-rule queries so their cascade order follows theme order. */\nexport function registerQueries(queries: Iterable<string>): void {\n\tfor (const query of queries) {\n\t\tconst state = getState();\n\t\tif (!state.queryRules.has(query)) state.queryRules.set(query, []);\n\t}\n}\n\nfunction createGroup(s: CSSStyleSheet, query: string): CSSGroupingRule | null {\n\tconst state = getState();\n\ttry {\n\t\tconst idx = s.cssRules.length;\n\t\ts.insertRule(query + \"{}\", idx);\n\t\tconst group = s.cssRules[idx] as CSSGroupingRule;\n\t\tstate.groupRules.set(query, group);\n\t\tstate.groupRules.set(groupQueryOf(group), group);\n\t\treturn group;\n\t} catch {\n\t\treturn null; // unsupported at-rule in this environment\n\t}\n}\n\n// A group prelude is stable while its children grow. Reading cssText on each\n// insertion would serialize all previous children and make loading quadratic.\n// Weak keys allow detached stylesheets to be collected after reset/rebinding.\nconst groupQueries = new WeakMap<CSSRule, string>();\nfunction groupQueryOf(rule: CSSRule): string {\n\tconst cached = groupQueries.get(rule);\n\tif (cached !== undefined) return cached;\n\tconst text = rule.cssText;\n\tconst brace = text.indexOf(\"{\");\n\tconst query = (brace === -1 ? text : text.slice(0, brace)).trim();\n\tgroupQueries.set(rule, query);\n\treturn query;\n}\n\nfunction ruleIdentity(rule: CSSRule): string {\n\treturn rule instanceof CSSStyleRule ? rule.selectorText : groupQueryOf(rule);\n}\n\nfunction scopedRuleKey(query: string | undefined, identity: string): string {\n\tconst scope = query === undefined ? \"-\" : \"+\" + query.length + \":\" + query;\n\treturn scope + identity.length + \":\" + identity;\n}\n\nfunction rememberExternalRule(rule: CSSRule, query: string | undefined): void {\n\tconst state = getState();\n\tif (!state.externalRules) return;\n\tconst key = scopedRuleKey(query, ruleIdentity(rule));\n\tlet texts = state.externalRules.get(key);\n\tif (!texts) {\n\t\ttexts = new Set();\n\t\tstate.externalRules.set(key, texts);\n\t}\n\ttexts.add(rule.cssText);\n}\n\nfunction consumeExternalRule(rule: CSSRule, query: string | undefined): boolean {\n\tconst state = getState();\n\tif (!state.externalRules) return false;\n\tconst key = scopedRuleKey(query, ruleIdentity(rule));\n\tconst texts = state.externalRules.get(key);\n\tif (!texts?.delete(rule.cssText)) return false;\n\tif (texts.size === 0) state.externalRules.delete(key);\n\tif (state.externalRules.size === 0) state.externalRules = null;\n\treturn true;\n}\n\n/**\n * Index an already-populated stylesheet found on adopt (SSR output, most\n * commonly): every top-level conditional grouping rule (@media/@container/…)\n * is registered into groupRules (by its reconstructed at-rule text) so later\n * record() calls append into it instead of creating a sibling duplicate. The\n * other rules are indexed by scope, selector/prelude, and normalized cssText\n * so exact server/client matches can be skipped without hiding a changed\n * named or global rule that happens to reuse the same selector.\n */\nfunction indexExternalRules(rules: CSSRuleList): void {\n\tconst state = getState();\n\tfor (let i = 0; i < rules.length; i++) {\n\t\tconst rule = rules[i];\n\t\tif (rule instanceof CSSStyleRule) {\n\t\t\trememberExternalRule(rule, undefined);\n\t\t\tcontinue;\n\t\t}\n\t\tconst prelude = groupQueryOf(rule);\n\t\tif (\"cssRules\" in rule && !prelude.startsWith(\"@keyframes\")) {\n\t\t\tconst group = rule as CSSGroupingRule;\n\t\t\tstate.hasExternalGroups = true;\n\t\t\tstate.groupRules.set(prelude, group);\n\t\t\tfor (let j = 0; j < group.cssRules.length; j++) {\n\t\t\t\trememberExternalRule(group.cssRules[j], prelude);\n\t\t\t}\n\t\t} else {\n\t\t\t// @keyframes, @font-face, … — one-shot rules matched by prelude.\n\t\t\trememberExternalRule(rule, undefined);\n\t\t}\n\t}\n}\n\nfunction insertBase(s: CSSStyleSheet, rule: string): void {\n\tconst state = getState();\n\ttry {\n\t\ts.insertRule(rule, state.baseRuleCount);\n\t\tconst inserted = s.cssRules[state.baseRuleCount];\n\t\tif (consumeExternalRule(inserted, undefined)) {\n\t\t\ts.deleteRule(state.baseRuleCount);\n\t\t\treturn;\n\t\t}\n\t\tstate.baseRuleCount++;\n\t} catch {\n\t\t// Invalid value/selector: drop the declaration, like browsers do for bad CSS.\n\t}\n}\n\nfunction insertGrouped(group: CSSGroupingRule, rule: string): void {\n\tconst state = getState();\n\ttry {\n\t\tconst index = group.cssRules.length;\n\t\tgroup.insertRule(rule, index);\n\t\tconst inserted = group.cssRules[index];\n\t\tif (state.externalRules && consumeExternalRule(inserted, groupQueryOf(group))) group.deleteRule(index);\n\t} catch {\n\t\t// Invalid value/selector: drop the declaration, like browsers do for bad CSS.\n\t}\n}\n\nfunction getOrCreateGroup(s: CSSStyleSheet, query: string): CSSGroupingRule | null {\n\tconst state = getState();\n\tconst direct = state.groupRules.get(query);\n\tif (direct) return direct;\n\tif (!state.hasExternalGroups) return createGroup(s, query);\n\n\t// CSSOM may normalize whitespace in an at-rule prelude. Normalize the\n\t// authored query through a temporary empty group before deciding that an\n\t// adopted SSR group is missing.\n\ttry {\n\t\tconst index = s.cssRules.length;\n\t\ts.insertRule(query + \"{}\", index);\n\t\tconst normalized = groupQueryOf(s.cssRules[index]);\n\t\ts.deleteRule(index);\n\t\tconst existing = state.groupRules.get(normalized);\n\t\tif (existing) {\n\t\t\tstate.groupRules.set(query, existing);\n\t\t\treturn existing;\n\t\t}\n\t} catch {\n\t\treturn null;\n\t}\n\treturn createGroup(s, query);\n}\n\n/**\n * Returns the live stylesheet, (re)binding when the document changes — e.g.\n * fresh jsdom documents between tests. Rebinding replays the whole registry,\n * which replaces v1's per-call classExistsInDOM() DOM scans with a single\n * replay per document.\n */\nexport function ensureSheet(): CSSStyleSheet | null {\n\tconst state = getState();\n\tif (typeof document === \"undefined\") return null;\n\t// The nuclo SSR polyfill provides a document without getElementById — in\n\t// that context rules accumulate in the registry for getCssText() only.\n\tif (typeof document.getElementById !== \"function\") return null;\n\tif (\n\t\tstate.sheet &&\n\t\tstate.sheetDocument === document &&\n\t\tstate.sheet.ownerNode &&\n\t\t(state.sheet.ownerNode as Element).isConnected\n\t) {\n\t\treturn state.sheet;\n\t}\n\tconst existing = document.getElementById(\"nuclo-styles\");\n\tlet el: HTMLStyleElement;\n\tif (existing?.tagName === \"STYLE\") {\n\t\tel = existing as HTMLStyleElement;\n\t} else {\n\t\tel = document.createElement(\"style\");\n\t\tel.id = \"nuclo-styles\";\n\t\tif (existing) existing.replaceWith(el);\n\t\telse document.head.appendChild(el);\n\t}\n\tstate.sheet = el.sheet;\n\tstate.sheetDocument = document;\n\tstate.groupRules.clear();\n\tstate.baseRuleCount = 0;\n\tstate.externalRules = null;\n\tstate.hasExternalGroups = false;\n\tif (!state.sheet) return null;\n\tif (state.sheet.cssRules.length > 0) {\n\t\t// Leading top-level non-group rules (style rules, @keyframes — before\n\t\t// the first @media/@container group) are this element's existing\n\t\t// \"base\" region — count them so insertBase() keeps inserting new base\n\t\t// rules right after them, still ahead of every group.\n\t\tlet i = 0;\n\t\twhile (i < state.sheet.cssRules.length) {\n\t\t\tconst r = state.sheet.cssRules[i];\n\t\t\tif (!(r instanceof CSSStyleRule) && \"cssRules\" in r && !groupQueryOf(r).startsWith(\"@keyframes\")) break;\n\t\t\ti++;\n\t\t}\n\t\tstate.baseRuleCount = i;\n\t\tstate.externalRules = new Map();\n\t\tindexExternalRules(state.sheet.cssRules);\n\t}\n\tfor (const rule of state.baseRules) insertBase(state.sheet, rule);\n\tfor (const [query, rules] of state.queryRules) {\n\t\tconst group = getOrCreateGroup(state.sheet, query);\n\t\tif (group) for (const rule of rules) insertGrouped(group, rule);\n\t}\n\treturn state.sheet;\n}\n\nfunction record(rule: string, query: string | undefined): void {\n\tconst state = getState();\n\t// Bind/replay *before* this rule joins the registry, so a fresh bind's\n\t// replay only ever covers previously-known rules — never this one twice.\n\tconst s = ensureSheet();\n\n\tif (query === undefined) {\n\t\tstate.baseRules.push(rule);\n\t} else {\n\t\tlet bucket = state.queryRules.get(query);\n\t\tif (!bucket) {\n\t\t\tbucket = [];\n\t\t\tstate.queryRules.set(query, bucket);\n\t\t}\n\t\tbucket.push(rule);\n\t}\n\tstate.cssTextCache = null; // a new rule changes the serialized sheet\n\n\tif (s) {\n\t\tif (query === undefined) {\n\t\t\tinsertBase(s, rule);\n\t\t} else {\n\t\t\tconst group = getOrCreateGroup(s, query);\n\t\t\tif (group) insertGrouped(group, rule);\n\t\t}\n\t}\n\tstate.ssrCollector?.(query === undefined ? rule : query + \"{\" + rule + \"}\");\n}\n\n/**\n * Content-addressed ~42-bit hash (two interleaved FNV-1a style passes). Class\n * names must match between server and client for SSR hydration, so a counter\n * is not an option; 42 bits keeps collision odds low (~1e-5 at 10k\n * unique declaration blocks).\n */\nexport function hash(input: string): string {\n\tlet a = 0x811c9dc5;\n\tlet b = 0x7ee3623b;\n\tfor (let i = 0; i < input.length; i++) {\n\t\tconst c = input.charCodeAt(i);\n\t\ta = Math.imul(a ^ c, 0x01000193);\n\t\tb = Math.imul(b ^ c, 0x85ebca6b);\n\t}\n\treturn (a >>> 0).toString(36) + ((b >>> 9) % 1296).toString(36);\n}\n\nfunction contextKeyOf(query: string | undefined, suffix: string): string {\n\tconst queryPart = query === undefined ? \"-\" : \"+\" + query.length + \":\" + query;\n\treturn queryPart + suffix.length + \":\" + suffix;\n}\n\nfunction appendKeyPart(key: string, value: string): string {\n\treturn key + value.length + \":\" + value;\n}\n\nexport function expandAmpersands(input: string, replacement: string): string {\n\tlet expanded = \"\";\n\tlet quote = 0;\n\tfor (let i = 0; i < input.length; i++) {\n\t\tconst code = input.charCodeAt(i);\n\t\tif (code === 92 /* \\\\ */ && i + 1 < input.length) {\n\t\t\texpanded += input[i] + input[++i];\n\t\t\tcontinue;\n\t\t}\n\t\tif (quote !== 0) {\n\t\t\texpanded += input[i];\n\t\t\tif (code === quote) quote = 0;\n\t\t\tcontinue;\n\t\t}\n\t\tif (code === 34 /* \" */ || code === 39 /* ' */) {\n\t\t\tquote = code;\n\t\t\texpanded += input[i];\n\t\t} else {\n\t\t\texpanded += code === 38 /* & */ ? replacement : input[i];\n\t\t}\n\t}\n\treturn expanded;\n}\n\nfunction selectorFor(className: string, suffix: string): string {\n\tconst selector = \".\" + className;\n\treturn selector + expandAmpersands(suffix, selector);\n}\n\n/**\n * True for strings usable verbatim as an unescaped CSS class selector:\n * letters/digits/`-`/`_`, not starting with a digit or `-`+digit.\n * Char-code loop rather than a RegExp — this runs on the cold mint path but\n * stays allocation-free either way.\n */\nfunction isValidClassName(name: string): boolean {\n\tif (name.length === 0 || name === \"-\") return false;\n\tfor (let i = 0; i < name.length; i++) {\n\t\tconst c = name.charCodeAt(i);\n\t\tconst ok =\n\t\t\t(c >= 97 && c <= 122) || // a-z\n\t\t\t(c >= 65 && c <= 90) || // A-Z\n\t\t\tc === 45 || c === 95 || // - _\n\t\t\t(i > 0 && c >= 48 && c <= 57); // 0-9, never leading\n\t\tif (!ok) return false;\n\t}\n\t// \"-9foo\" is not a valid identifier start either.\n\tif (name.charCodeAt(0) === 45 && name.length > 1) {\n\t\tconst second = name.charCodeAt(1);\n\t\tif (second >= 48 && second <= 57) return false;\n\t}\n\treturn true;\n}\n\n/**\n * Mint (or reuse) the class for a declaration block in a selector context.\n *\n * Declarations keep their authored order — CSS resolves shorthand/longhand\n * and repeated-property conflicts by declaration order, so reordering (e.g.\n * alphabetical sorting) would silently change what `{ pt: 20, p: 16 }` means.\n * The cost is that the same declarations authored in a different order mint a\n * second, content-identical class — harmless, and rare in practice.\n *\n * `name` is the author's identity for the style (`css(\"app-root\", …)`). It\n * becomes part of the cache key, so two different names never share a class\n * even with identical declarations. With `exactName`, this block *is* the\n * named one and takes the name verbatim; otherwise the name is only a\n * readable prefix on a content-addressed prefix (`app-root-1a2b3c`), which is\n * how a named style's non-base contexts and its cx() merges stay identifiable\n * in devtools without ever colliding with the base class.\n */\nfunction mintBlock(\n\tquery: string | undefined,\n\tsuffix: string,\n\tdecls: ReadonlyArray<readonly [string, string]>,\n\tname?: string,\n\texactName = false,\n): string {\n\tconst state = getState();\n\tlet contextKey = contextKeyOf(query, suffix);\n\tfor (const [prop, value] of decls) {\n\t\tcontextKey = appendKeyPart(appendKeyPart(contextKey, prop), value);\n\t}\n\tif (name !== undefined && !isValidClassName(name)) {\n\t\t// eslint-disable-next-line no-console\n\t\tconsole.warn(\n\t\t\t`[nuclo] css() name ${JSON.stringify(name)} is not a valid CSS class name ` +\n\t\t\t\t\"(letters, digits, - and _ only, not starting with a digit); falling back to a generated name.\",\n\t\t);\n\t\tname = undefined;\n\t}\n\tconst declKey = name === undefined ? \"a\" + contextKey : \"n\" + appendKeyPart(\"\", name) + contextKey;\n\tlet className = state.atomCache.get(declKey);\n\tif (className !== undefined) {\n\t\t// Touch the sheet so a swapped document (tests) gets the replayed rules.\n\t\tensureSheet();\n\t\treturn className;\n\t}\n\n\tif (name === undefined) {\n\t\tclassName = \"n\" + hash(declKey);\n\t} else {\n\t\tclassName = exactName ? name : name + \"-\" + hash(declKey);\n\t\tif (state.atomMeta.has(className)) {\n\t\t\t// eslint-disable-next-line no-console\n\t\t\tconsole.warn(\n\t\t\t\t`[nuclo] css() name ${JSON.stringify(className)} is already used by a different style. ` +\n\t\t\t\t\t\"Both rules are emitted under the same class, so they will override each other — rename one.\",\n\t\t\t);\n\t\t}\n\t}\n\n\tlet body = \"\";\n\tfor (const [prop, value] of decls) body += (body ? \";\" : \"\") + prop + \":\" + value;\n\tstate.atomCache.set(declKey, className);\n\tstate.atomMeta.set(className, { query, suffix, decls, name });\n\trecord(selectorFor(className, suffix) + \"{\" + body + \"}\", query);\n\treturn className;\n}\n\n/**\n * One class per (query, selector-suffix) — every declaration that shares that\n * context compiles into a single rule under a single generated class name,\n * rather than one class per individual property. Pass `name` to give the\n * style a stable, readable identity (see mintBlock).\n */\nexport function atomBlock(\n\tquery: string | undefined,\n\tsuffix: string,\n\tdecls: ReadonlyArray<readonly [string, string]>,\n\tname?: string,\n\texactName = false,\n): string {\n\treturn mintBlock(query, suffix, decls, name, exactName);\n}\n\n/**\n * Merge two same-context generated classes into one: `second`'s declarations\n * override `first`'s per exact property (shorthand/longhand interplay is left\n * to CSS order), and the combined block mints its own content-addressed class\n * — so cx(base, override) keeps base's untouched properties instead of\n * dropping the whole base class. Deterministic: the same pair always yields\n * the same class name, on server and client alike. A named base passes its\n * name down as a prefix, so `cx(appRoot, active)` reads as `app-root-1a2b3c`.\n */\nexport function mergeBlocks(first: string, second: string): string {\n\tconst state = getState();\n\tconst a = state.atomMeta.get(first);\n\tconst b = state.atomMeta.get(second);\n\tif (!a || !b) return second; // unknown input — nothing to merge with\n\tconst concat = [...a.decls, ...b.decls];\n\t// Keep only the last occurrence of each exact property, at its position —\n\t// so a later `padding` still fully resets an earlier `padding-top`.\n\tconst lastIndex = new Map<string, number>();\n\tfor (let i = 0; i < concat.length; i++) lastIndex.set(concat[i][0], i);\n\tconst merged = concat.filter((decl, i) => lastIndex.get(decl[0]) === i);\n\treturn mintBlock(a.query, a.suffix, merged, a.name ?? b.name);\n}\n\n/** Conflict key (query|suffix) for a generated class — lets cx() group classes by selector context. */\nexport function conflictKeyOf(className: string): string | undefined {\n\tconst state = getState();\n\tconst meta = state.atomMeta.get(className);\n\treturn meta === undefined ? undefined : contextKeyOf(meta.query, meta.suffix);\n}\n\n/** Current registry generation, used to invalidate per-instance WeakMap hits after resetStyles(). */\nexport function getStyleEpoch(): number {\n\treturn (cachedState ?? globalScope[ENGINE_STATE_KEY])?.styleEpoch ?? 0;\n}\n\n/** Register a non-atomic rule (keyframes, global styles) once per dedupe key. */\nexport function addRawRule(dedupeKey: string, rule: string): void {\n\tconst state = getState();\n\tif (state.rawKeys.has(dedupeKey)) {\n\t\tensureSheet();\n\t\treturn;\n\t}\n\tstate.rawKeys.add(dedupeKey);\n\trecord(rule, undefined);\n}\n\n/** All generated CSS — base rules first, then at-rule groups in registration order. */\nexport function getCssText(): string {\n\tconst state = getState();\n\tif (state.cssTextCache !== null) return state.cssTextCache;\n\tlet out = state.baseRules.join(\"\");\n\tfor (const [query, rules] of state.queryRules) {\n\t\tif (rules.length > 0) out += query + \"{\" + rules.join(\"\") + \"}\";\n\t}\n\tstate.cssTextCache = out;\n\treturn out;\n}\n\n/** Clear all engine state (test helper). Removes the injected style element. */\nexport function resetStyles(): void {\n\tconst state = getState();\n\tstate.atomCache.clear();\n\tstate.atomMeta.clear();\n\tstate.rawKeys.clear();\n\tstate.baseRules.length = 0;\n\tstate.queryRules.clear();\n\tstate.groupRules.clear();\n\tstate.cssTextCache = null;\n\tstate.baseRuleCount = 0;\n\tstate.sheet = null;\n\tstate.sheetDocument = null;\n\tstate.externalRules = null;\n\tstate.hasExternalGroups = false;\n\tstate.styleEpoch++;\n\tif (typeof document !== \"undefined\") {\n\t\tdocument.getElementById(\"nuclo-styles\")?.remove();\n\t}\n}\n","/**\n * nuclo styling — theme-aware, typed CSS-in-TS.\n *\n * One typed object in, one generated class per selector context out (a class\n * groups every declaration that shares its query + pseudo-selector, so a\n * base style and a :hover override always compile to at least two classes):\n *\n * const { css, cx } = createCss({\n * colors: { primary: \"#6366f1\" },\n * screens: { md: \"(min-width: 768px)\" },\n * });\n * const button = css({ px: 24, py: 12, bg: \"primary\", rounded: 8, hover: { bg: \"#4f46e5\" } });\n * div(button, \"Save\"); // button is { className } — a regular nuclo attributes object\n */\nimport { atomBlock, addRawRule, conflictKeyOf, ensureSheet, expandAmpersands, getStyleEpoch, hash, mergeBlocks, registerQueries } from \"./engine\";\n\n// ---------------------------------------------------------------------------\n// Types live in types/style.d.ts (shipped with the package) so the published\n// global declarations can import them without reaching into unpublished src/.\n// They are re-exported here so module-style consumers keep the same surface.\n// ---------------------------------------------------------------------------\nimport type {\n\tClassInput,\n\tCssInstance,\n\tFlatStyle,\n\tKeyframeFrames,\n\tPseudo,\n\tStyle,\n\tStyleResult,\n\tThemeConfig,\n\tVariantDefinitions,\n\tVariantProps,\n\tVariantsConfig,\n\tVariantsFn,\n} from \"../../types/style\";\n\nexport type {\n\tClassInput,\n\tCssInstance,\n\tCSSProperties,\n\tFlatStyle,\n\tKeyframeFrames,\n\tKeyframeStop,\n\tPseudo,\n\tSize,\n\tStyle,\n\tStyleResult,\n\tThemeConfig,\n\tVariantDefinitions,\n\tVariantProps,\n\tVariantsConfig,\n\tVariantsFn,\n} from \"../../types/style\";\n\n\nconst PSEUDO = {\n\thover: \":hover\",\n\tfocus: \":focus\",\n\tfocusVisible: \":focus-visible\",\n\tfocusWithin: \":focus-within\",\n\tactive: \":active\",\n\tvisited: \":visited\",\n\tdisabled: \":disabled\",\n\tenabled: \":enabled\",\n\tchecked: \":checked\",\n\trequired: \":required\",\n\tinvalid: \":invalid\",\n\tvalid: \":valid\",\n\treadOnly: \":read-only\",\n\tfirst: \":first-child\",\n\tlast: \":last-child\",\n\tonly: \":only-child\",\n\todd: \":nth-child(odd)\",\n\teven: \":nth-child(even)\",\n\tempty: \":empty\",\n\tplaceholderShown: \":placeholder-shown\",\n\tplaceholder: \"::placeholder\",\n\tbefore: \"::before\",\n\tafter: \"::after\",\n\tselection: \"::selection\",\n\tmarker: \"::marker\",\n\tfirstLine: \"::first-line\",\n\tfirstLetter: \"::first-letter\",\n} as const satisfies Record<Pseudo, string>;\n\n// ---------------------------------------------------------------------------\n// Runtime tables\n// ---------------------------------------------------------------------------\nconst ALIAS: Record<string, readonly string[]> = {\n\tbg: [\"background\"],\n\tp: [\"padding\"],\n\tpx: [\"padding-left\", \"padding-right\"],\n\tpy: [\"padding-top\", \"padding-bottom\"],\n\tpt: [\"padding-top\"], pr: [\"padding-right\"], pb: [\"padding-bottom\"], pl: [\"padding-left\"],\n\tm: [\"margin\"],\n\tmx: [\"margin-left\", \"margin-right\"],\n\tmy: [\"margin-top\", \"margin-bottom\"],\n\tmt: [\"margin-top\"], mr: [\"margin-right\"], mb: [\"margin-bottom\"], ml: [\"margin-left\"],\n\tw: [\"width\"], h: [\"height\"],\n\tminW: [\"min-width\"], maxW: [\"max-width\"], minH: [\"min-height\"], maxH: [\"max-height\"],\n\tsize: [\"width\", \"height\"],\n\ttext: [\"font-size\"],\n\tfont: [\"font-family\"],\n\tweight: [\"font-weight\"],\n\tleading: [\"line-height\"],\n\ttracking: [\"letter-spacing\"],\n\talign: [\"text-align\"],\n\titems: [\"align-items\"],\n\tjustify: [\"justify-content\"],\n\tz: [\"z-index\"],\n\trounded: [\"border-radius\"],\n\tshadow: [\"box-shadow\"],\n\tselect: [\"user-select\"],\n};\n\nconst COMPOSITE: Record<string, Record<string, string>> = {\n\trow: { display: \"flex\", \"flex-direction\": \"row\" },\n\tcol: { display: \"flex\", \"flex-direction\": \"column\" },\n\tcenter: { \"align-items\": \"center\", \"justify-content\": \"center\" },\n\ttruncate: { overflow: \"hidden\", \"text-overflow\": \"ellipsis\", \"white-space\": \"nowrap\" },\n};\n\n/** CSS property → theme token table it resolves against. */\nconst TOKEN_PROP: Record<string, keyof ThemeConfig> = {\n\tbackground: \"colors\",\n\t\"background-color\": \"colors\",\n\tcolor: \"colors\",\n\t\"border-color\": \"colors\",\n\t\"border-top-color\": \"colors\",\n\t\"border-right-color\": \"colors\",\n\t\"border-bottom-color\": \"colors\",\n\t\"border-left-color\": \"colors\",\n\t\"outline-color\": \"colors\",\n\t\"caret-color\": \"colors\",\n\t\"text-decoration-color\": \"colors\",\n\t\"font-family\": \"fonts\",\n\t\"box-shadow\": \"shadows\",\n\t\"border-radius\": \"radii\",\n};\n\n/** Properties where bare numbers stay unitless instead of becoming px. */\nconst UNITLESS = new Set([\n\t\"z-index\", \"opacity\", \"font-weight\", \"line-height\", \"flex\", \"flex-grow\",\n\t\"flex-shrink\", \"order\", \"aspect-ratio\", \"zoom\", \"scale\", \"column-count\",\n\t\"orphans\", \"widows\", \"tab-size\", \"animation-iteration-count\", \"grid-column\", \"grid-row\",\n]);\n\n// Cache only conversions, with a ceiling for arbitrary custom property names.\nconst kebabCache = new Map<string, string>();\nfunction kebab(prop: string): string {\n\tif (!/[A-Z]/.test(prop)) return prop;\n\tlet out = kebabCache.get(prop);\n\tif (out === undefined) {\n\t\tout = prop.replace(/[A-Z]/g, (m) => \"-\" + m.toLowerCase());\n\t\tif (kebabCache.size >= 512) kebabCache.clear();\n\t\tkebabCache.set(prop, out);\n\t}\n\treturn out;\n}\n\nfunction toQuery(screen: string): string {\n\treturn screen.charCodeAt(0) === 64 /* @ */ ? screen : \"@media \" + screen;\n}\n\nfunction combineQuery(outer: string | undefined, inner: string): string {\n\t// Nested @media conditions combine with \"and\"; other combinations: inner wins.\n\tif (outer !== undefined && outer.startsWith(\"@media\") && inner.startsWith(\"@media\")) {\n\t\treturn outer + \" and\" + inner.slice(6);\n\t}\n\treturn inner;\n}\n\n/**\n * Deep-merge style objects, later sources winning per property — recurses\n * into nested pseudo/screen/&/@ blocks and `raw` so a style set two levels\n * deep still overrides precisely. Used by variants() to combine base with\n * selected variants/compounds *before* compiling: css() mints one class per\n * selector context, so merging after compilation (via cx()) would only be\n * able to replace a whole context's class, not override one property in it.\n */\nfunction mergeStyle(target: Record<string, unknown>, source: Record<string, unknown>): Record<string, unknown> {\n\tfor (const key in source) {\n\t\tconst value = source[key];\n\t\tconst existing = target[key];\n\t\tif (\n\t\t\tvalue !== null && typeof value === \"object\" && !Array.isArray(value) &&\n\t\t\texisting !== null && typeof existing === \"object\" && !Array.isArray(existing)\n\t\t) {\n\t\t\ttarget[key] = mergeStyle({ ...(existing as Record<string, unknown>) }, value as Record<string, unknown>);\n\t\t} else {\n\t\t\ttarget[key] = value;\n\t\t}\n\t}\n\treturn target;\n}\n\n// A class rather than an object literal + Object.defineProperty: toString()\n// lives on the prototype, which is non-enumerable by spec at no per-call\n// cost — attribute application iterates Object.keys()/for-in and must only\n// see className, same contract the old defineProperty call paid for on\n// every mint. This runs on every cx() call (no cache) and every css() cache\n// miss, so the allocation shape matters.\nclass StyleResultImpl {\n\treadonly className: string;\n\tconstructor(className: string) {\n\t\tthis.className = className;\n\t}\n\ttoString(): string {\n\t\treturn this.className;\n\t}\n}\n\nfunction makeResult(className: string): StyleResult {\n\treturn new StyleResultImpl(className);\n}\n\nfunction pickClass(picked: Map<string, string>, name: string): void {\n\tconst key = conflictKeyOf(name);\n\tif (key === undefined) {\n\t\t// External class the engine didn't mint — pass through, dedupe by name.\n\t\tpicked.set(name, name);\n\t\treturn;\n\t}\n\tconst prev = picked.get(key);\n\tif (prev === undefined || prev === name) picked.set(key, name);\n\t// Same selector context seen twice: merge declaration-wise, later wins per\n\t// property. Minting is content-addressed, so a redundant merge (override\n\t// restates every property) collapses back to the override's own class.\n\telse picked.set(key, mergeBlocks(prev, name));\n}\n\nfunction collectClassString(className: string, picked: Map<string, string>): void {\n\tlet start = 0;\n\tfor (let i = 0; i <= className.length; i++) {\n\t\tconst code = i === className.length ? 32 : className.charCodeAt(i);\n\t\tconst whitespace = code === 32 || code === 9 || code === 10 || code === 12 || code === 13;\n\t\tif (!whitespace) continue;\n\t\tif (i > start) pickClass(picked, className.slice(start, i));\n\t\tstart = i + 1;\n\t}\n}\n\nfunction collectClasses(inputs: readonly ClassInput[], picked: Map<string, string>): void {\n\tfor (const input of inputs) {\n\t\tif (!input) continue;\n\t\tif (typeof input === \"string\") {\n\t\t\tcollectClassString(input, picked);\n\t\t} else if (Array.isArray(input)) {\n\t\t\tcollectClasses(input, picked);\n\t\t} else {\n\t\t\tcollectClassString((input as StyleResult).className, picked);\n\t\t}\n\t}\n}\n\nfunction composeClassName(inputs: readonly ClassInput[]): string {\n\tconst picked = new Map<string, string>();\n\tcollectClasses(inputs, picked);\n\tlet className = \"\";\n\tfor (const name of picked.values()) className += (className ? \" \" : \"\") + name;\n\treturn className;\n}\n\n// Memoizes cx(a, b) by the identity of its two arguments — the shape of a\n// per-render `cx(base, active)` conditional-class helper, called with the\n// same two object references every time. Mirrors css()'s own memo (below):\n// nested WeakMaps so entries die with either argument, epoch-gated so a\n// resetStyles() call can't hand back a className with no backing rule.\nconst cxPairMemo = new WeakMap<object, WeakMap<object, { epoch: number; first: string; second: string; result: StyleResult }>>();\n\nfunction isPlainCxObject(value: ClassInput): value is StyleResult {\n\treturn !!value && typeof value === \"object\" && !Array.isArray(value);\n}\n\n/**\n * Compose class lists with exact conflict resolution: when two inputs style\n * the same (query, selector-suffix) context, their declaration blocks merge\n * with the later input winning per property — the merged block gets its own\n * content-addressed class, so `cx(base, active)` keeps every base property\n * the active style doesn't override. Works because the engine remembers what\n * every class it minted means. Unknown external classes pass through as-is.\n * Nested arrays are flattened, so `cx([a, cond && b], c)` composes the same\n * as `cx(a, cond && b, c)`.\n */\nexport function cx(...inputs: ClassInput[]): StyleResult {\n\tif (inputs.length === 0) return makeResult(\"\");\n\tif (inputs.length === 1) {\n\t\tconst only = inputs[0];\n\t\tif (!only) return makeResult(\"\");\n\t\tif (!Array.isArray(only)) {\n\t\t\tconst name = typeof only === \"string\" ? only : (only as StyleResult).className;\n\t\t\t// Multiple tokens may include conflicting generated classes even in one input.\n\t\t\tif (!/[\\t\\n\\f\\r ]/.test(name)) return makeResult(name);\n\t\t}\n\t}\n\n\tif (inputs.length === 2 && isPlainCxObject(inputs[0]) && isPlainCxObject(inputs[1])) {\n\t\tconst a = inputs[0] as object;\n\t\tconst b = inputs[1] as object;\n\t\tconst epoch = getStyleEpoch();\n\t\tconst inner = cxPairMemo.get(a);\n\t\tconst hit = inner?.get(b);\n\t\tif (hit !== undefined && hit.epoch === epoch && hit.first === inputs[0].className && hit.second === inputs[1].className) {\n\t\t\tensureSheet();\n\t\t\treturn hit.result;\n\t\t}\n\n\t\tconst result = makeResult(composeClassName(inputs));\n\t\tconst bucket = inner ?? new WeakMap<object, { epoch: number; first: string; second: string; result: StyleResult }>();\n\t\tbucket.set(b, { epoch, first: inputs[0].className, second: inputs[1].className, result });\n\t\tif (!inner) cxPairMemo.set(a, bucket);\n\t\treturn result;\n\t}\n\n\treturn makeResult(composeClassName(inputs));\n}\n\n// ---------------------------------------------------------------------------\n// Factory\n// ---------------------------------------------------------------------------\nexport function createCss<const T extends ThemeConfig>(theme: T = {} as T): CssInstance<T> {\n\tconst screens: Record<string, string> = theme.screens ?? {};\n\tregisterQueries(Object.values(screens).map(toQuery));\n\n\t// Fast path for repeated css() calls on the same style object. Holds the\n\t// name it was compiled under so a re-compile under a different name can't\n\t// hand back the wrong classes. WeakMap: entries die with the style object.\n\tconst memo = new WeakMap<object, { epoch: number; name: string | undefined; result: StyleResult }>();\n\n\tfunction toCssValue(prop: string, value: string | number): string {\n\t\tif (typeof value === \"number\") {\n\t\t\treturn value === 0 || UNITLESS.has(prop) ? String(value) : value + \"px\";\n\t\t}\n\t\tconst group = TOKEN_PROP[prop];\n\t\tif (group !== undefined) {\n\t\t\tconst hit = (theme[group] as Record<string, string> | undefined)?.[value];\n\t\t\tif (hit !== undefined) return hit;\n\t\t}\n\t\treturn value;\n\t}\n\n\t/** Every (query, selector-suffix) context touched by one css() call collects its declarations here, then compiles to a single class. */\n\ttype Bucket = { query: string | undefined; suffix: string; decls: Array<[string, string]> };\n\n\tfunction bucketFor(buckets: Map<string, Bucket>, query: string | undefined, suffix: string): Bucket {\n\t\tconst queryPart = query === undefined ? \"-\" : \"+\" + query.length + \":\" + query;\n\t\tconst key = queryPart + suffix.length + \":\" + suffix;\n\t\tlet bucket = buckets.get(key);\n\t\tif (!bucket) {\n\t\t\tbucket = { query, suffix, decls: [] };\n\t\t\tbuckets.set(key, bucket);\n\t\t}\n\t\treturn bucket;\n\t}\n\n\tfunction walk(style: Record<string, unknown>, query: string | undefined, suffix: string, buckets: Map<string, Bucket>): void {\n\t\tfor (const key in style) {\n\t\t\tconst value = style[key];\n\t\t\tif (value == null || value === false) continue;\n\n\t\t\tif (typeof value === \"object\") {\n\t\t\t\tif (key === \"raw\") {\n\t\t\t\t\tconst raws = value as Record<string, string | number>;\n\t\t\t\t\tconst decls = bucketFor(buckets, query, suffix).decls;\n\t\t\t\t\tfor (const prop in raws) decls.push([prop, toCssValue(prop, raws[prop])]);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tconst pseudo = (PSEUDO as Record<string, string | undefined>)[key];\n\t\t\t\tif (pseudo !== undefined) {\n\t\t\t\t\twalk(value as Record<string, unknown>, query, suffix + pseudo, buckets);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tconst screen = screens[key];\n\t\t\t\tif (screen !== undefined) {\n\t\t\t\t\twalk(value as Record<string, unknown>, combineQuery(query, toQuery(screen)), suffix, buckets);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tconst first = key.charCodeAt(0);\n\t\t\t\tif (first === 38 /* & */) {\n\t\t\t\t\tconst nested = expandAmpersands(key, \"&\" + suffix);\n\t\t\t\t\twalk(value as Record<string, unknown>, query, nested.slice(1), buckets);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (first === 64 /* @ */) {\n\t\t\t\t\twalk(value as Record<string, unknown>, combineQuery(query, key), suffix, buckets);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tcontinue; // unknown nested key — unreachable through the typed API\n\t\t\t}\n\n\t\t\tif (value === true) {\n\t\t\t\tconst composite = COMPOSITE[key];\n\t\t\t\tif (composite) {\n\t\t\t\t\tconst decls = bucketFor(buckets, query, suffix).decls;\n\t\t\t\t\tfor (const prop in composite) decls.push([prop, composite[prop]]);\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst targets = ALIAS[key];\n\t\t\tif (targets !== undefined) {\n\t\t\t\tconst decls = bucketFor(buckets, query, suffix).decls;\n\t\t\t\tfor (const prop of targets) decls.push([prop, toCssValue(prop, value as string | number)]);\n\t\t\t} else {\n\t\t\t\tconst prop = kebab(key);\n\t\t\t\tbucketFor(buckets, query, suffix).decls.push([prop, toCssValue(prop, value as string | number)]);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Compile a style object into classes — one per (query, selector-suffix)\n\t * context it touches, not one per property. Idempotent and cached.\n\t *\n\t * An optional leading name gives the style a stable, readable identity:\n\t *\n\t * css(\"app-root\", { minHeight: \"100vh\", hover: { color: \"red\" } })\n\t * // → \"app-root app-root-1a2b3c\"\n\t *\n\t * The base context takes the name verbatim; the style's other contexts\n\t * (pseudo-selectors, media queries) take it as a prefix on a\n\t * content-addressed suffix so they stay greppable without ever colliding.\n\t * Named styles are keyed by name as well as content, so they never share a\n\t * class with an unrelated style — which also means they don't dedupe\n\t * against identical anonymous blocks. Name the styles you want to find in\n\t * devtools; leave the rest anonymous to keep the sheet small.\n\t */\n\tfunction css(style: Style<T>): StyleResult;\n\tfunction css(name: string, style: Style<T>): StyleResult;\n\tfunction css(nameOrStyle: string | Style<T>, maybeStyle?: Style<T>): StyleResult {\n\t\tconst named = typeof nameOrStyle === \"string\";\n\t\tconst style = (named ? maybeStyle : nameOrStyle) as Style<T>;\n\t\tconst name = named ? nameOrStyle : undefined;\n\t\tif (style == null) return makeResult(\"\");\n\n\t\t// The memo is keyed by style-object identity; the same object compiled\n\t\t// under two different names must not reuse the first result.\n\t\tconst epoch = getStyleEpoch();\n\t\tconst hit = memo.get(style);\n\t\tif (hit !== undefined && hit.epoch === epoch && hit.name === name) {\n\t\t\tensureSheet();\n\t\t\treturn hit.result;\n\t\t}\n\n\t\tconst buckets = new Map<string, Bucket>();\n\t\twalk(style as Record<string, unknown>, undefined, \"\", buckets);\n\t\tconst classes: string[] = [];\n\t\tfor (const bucket of buckets.values()) {\n\t\t\tif (bucket.decls.length === 0) continue;\n\t\t\tconst isBase = bucket.query === undefined && bucket.suffix === \"\";\n\t\t\tclasses.push(atomBlock(bucket.query, bucket.suffix, bucket.decls, name, isBase));\n\t\t}\n\t\tconst result = makeResult(classes.join(\" \"));\n\t\tmemo.set(style, { epoch, name, result });\n\t\treturn result;\n\t}\n\n\tfunction flatDecls(style: Record<string, unknown>): string {\n\t\tlet decls = \"\";\n\t\tconst push = (prop: string, v: string): void => {\n\t\t\tdecls += (decls ? \";\" : \"\") + prop + \":\" + v;\n\t\t};\n\t\tfor (const key in style) {\n\t\t\tconst value = style[key];\n\t\t\tif (value == null || value === false) continue;\n\t\t\tif (key === \"raw\" && typeof value === \"object\") {\n\t\t\t\tconst raws = value as Record<string, string | number>;\n\t\t\t\tfor (const prop in raws) push(prop, toCssValue(prop, raws[prop]));\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (typeof value === \"object\") continue;\n\t\t\tif (value === true) {\n\t\t\t\tconst composite = COMPOSITE[key];\n\t\t\t\tif (composite) for (const prop in composite) push(prop, composite[prop]);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst targets = ALIAS[key];\n\t\t\tif (targets !== undefined) {\n\t\t\t\tfor (const prop of targets) push(prop, toCssValue(prop, value as string | number));\n\t\t\t} else {\n\t\t\t\tconst prop = kebab(key);\n\t\t\t\tpush(prop, toCssValue(prop, value as string | number));\n\t\t\t}\n\t\t}\n\t\treturn decls;\n\t}\n\n\t/** Register a @keyframes block; returns its generated name for use in `animation`. */\n\tfunction keyframes(frames: KeyframeFrames<T>): string {\n\t\tlet body = \"\";\n\t\tfor (const stop in frames) {\n\t\t\tbody += stop + \"{\" + flatDecls(frames[stop] as Record<string, unknown>) + \"}\";\n\t\t}\n\t\tconst name = \"nk\" + hash(body);\n\t\taddRawRule(name, \"@keyframes \" + name + \"{\" + body + \"}\");\n\t\treturn name;\n\t}\n\n\t/** Global selector styles (body, resets). Flat properties only. */\n\tfunction globalStyle(selector: string, style: FlatStyle<T>): void {\n\t\tconst rule = selector + \"{\" + flatDecls(style as Record<string, unknown>) + \"}\";\n\t\taddRawRule(\"g|\" + rule, rule);\n\t}\n\n\t/**\n\t * Compile a typed variants recipe into a call-with-props function.\n\t *\n\t * const button = variants({\n\t * base: { rounded: 8, weight: 600 },\n\t * variants: {\n\t * intent: { primary: { bg: \"primary\" }, danger: { bg: \"danger\" } },\n\t * size: { sm: { px: 8, py: 4 }, lg: { px: 16, py: 10 } },\n\t * block: { true: { display: \"block\", w: \"100%\" } },\n\t * },\n\t * defaultVariants: { intent: \"primary\", size: \"sm\" },\n\t * compoundVariants: [{ intent: \"danger\", size: \"lg\", css: { weight: 700 } }],\n\t * });\n\t * div(button({ intent: \"danger\", size: \"lg\" }), \"Delete\");\n\t *\n\t * A call resolves defaults + props into a selection, deep-merges base with\n\t * every matching variant/compound's raw style object (later sources win\n\t * per property — not per class, since css() now mints one class per\n\t * selector context rather than one per property), compiles the merge with\n\t * css(), and caches the result per selection — repeated calls are a Map\n\t * lookup.\n\t */\n\tfunction variants<const V extends VariantDefinitions<T>>(\n\t\tconfig: VariantsConfig<T, V>,\n\t): VariantsFn<V> {\n\t\tconst normalize = (value: unknown): string =>\n\t\t\tvalue === true ? \"true\" : value === false ? \"false\" : String(value);\n\n\t\tconst groups = (config.variants ?? {}) as Record<string, Record<string, Style<T>>>;\n\t\tconst groupNames = Object.keys(groups);\n\t\tconst defaults = (config.defaultVariants ?? {}) as Record<string, unknown>;\n\t\tconst baseStyle = (config.base ?? null) as Record<string, unknown> | null;\n\n\t\tconst compounds = (config.compoundVariants ?? []).map((entry) => {\n\t\t\tconst { css: compoundStyle, ...match } = entry as VariantProps<V> & { css: Style<T> };\n\t\t\tconst conditions: Record<string, string> = {};\n\t\t\tfor (const group in match) conditions[group] = normalize((match as Record<string, unknown>)[group]);\n\t\t\treturn { conditions, style: compoundStyle as Record<string, unknown> };\n\t\t});\n\n\t\tconst cache = new Map<string, StyleResult>();\n\t\tlet cacheEpoch = getStyleEpoch();\n\n\t\treturn function recipe(props?: VariantProps<V>): StyleResult {\n\t\t\tconst epoch = getStyleEpoch();\n\t\t\tif (cacheEpoch !== epoch) {\n\t\t\t\tcache.clear();\n\t\t\t\tcacheEpoch = epoch;\n\t\t\t}\n\t\t\t// Resolve final selection: defaults, overridden by explicit props.\n\t\t\tconst selection: Record<string, string> = {};\n\t\t\tfor (const group of groupNames) {\n\t\t\t\tconst provided = props ? (props as Record<string, unknown>)[group] : undefined;\n\t\t\t\tconst chosen = provided !== undefined && provided !== null ? provided : defaults[group];\n\t\t\t\tif (chosen === undefined || chosen === null) continue;\n\t\t\t\tselection[group] = normalize(chosen);\n\t\t\t}\n\n\t\t\t// Cache the compiled result per selection (stable group order).\n\t\t\tlet key = \"\";\n\t\t\tfor (const group of groupNames) {\n\t\t\t\tconst value = selection[group];\n\t\t\t\tkey += group.length + \":\" + group;\n\t\t\t\tkey += value === undefined ? \"-\" : \"+\" + value.length + \":\" + value;\n\t\t\t}\n\t\t\tconst cached = cache.get(key);\n\t\t\tif (cached) {\n\t\t\t\tensureSheet();\n\t\t\t\treturn cached;\n\t\t\t}\n\n\t\t\tlet merged: Record<string, unknown> = {};\n\t\t\tif (baseStyle) merged = mergeStyle(merged, baseStyle);\n\t\t\tfor (const group of groupNames) {\n\t\t\t\tconst value = selection[group];\n\t\t\t\tif (value !== undefined) {\n\t\t\t\t\tconst style = groups[group][value];\n\t\t\t\t\tif (style) merged = mergeStyle(merged, style as Record<string, unknown>);\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor (const compound of compounds) {\n\t\t\t\tlet matches = true;\n\t\t\t\tfor (const group in compound.conditions) {\n\t\t\t\t\tif (selection[group] !== compound.conditions[group]) {\n\t\t\t\t\t\tmatches = false;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (matches) merged = mergeStyle(merged, compound.style);\n\t\t\t}\n\n\t\t\tconst result = css(merged as Style<T>);\n\t\t\tcache.set(key, result);\n\t\t\treturn result;\n\t\t};\n\t}\n\n\treturn { css, cx, variants, keyframes, globalStyle, theme };\n}\n\n// ---------------------------------------------------------------------------\n// Default themeless instance — registered as globals by the runtime bootstrap.\n// Apps with design tokens create their own instance via createCss(theme).\n//\n// Built lazily on first use rather than at module load: most apps that\n// import nuclo never call css()/variants()/keyframes()/globalStyle(), and\n// createCss() eagerly allocates a memo WeakMap and walks the (empty) theme's\n// screens — work worth skipping entirely for those apps.\n// ---------------------------------------------------------------------------\nlet defaultInstance: CssInstance<object> | undefined;\nfunction getDefaultInstance(): CssInstance<object> {\n\treturn (defaultInstance ??= createCss({}));\n}\n\n/** Themeless css() — full property/variant typing, no tokens or screens. */\nexport const css: {\n\t(style: Style<object>): StyleResult;\n\t(name: string, style: Style<object>): StyleResult;\n} = (nameOrStyle: string | Style<object>, style?: Style<object>): StyleResult =>\n\ttypeof nameOrStyle === \"string\"\n\t\t? getDefaultInstance().css(nameOrStyle, style as Style<object>)\n\t\t: getDefaultInstance().css(nameOrStyle);\n/** Themeless variants() recipe helper. */\nexport const variants: <const V extends VariantDefinitions<object>>(\n\tconfig: VariantsConfig<object, V>,\n) => VariantsFn<V> = (config) => getDefaultInstance().variants(config);\n/** Themeless keyframes() helper. */\nexport const keyframes: (frames: KeyframeFrames<object>) => string = (frames) => getDefaultInstance().keyframes(frames);\n/** Themeless globalStyle() helper. */\nexport const globalStyle: (selector: string, style: FlatStyle<object>) => void = (selector, style) =>\n\tgetDefaultInstance().globalStyle(selector, style);\n","import { registerGlobalTagBuilders } from \"./element/tags\";\nimport { list } from \"./list\";\nimport { update } from \"./update/update\";\nimport { when } from \"./when\";\nimport { on } from \"./element/events\";\nimport { render, hydrate } from \"./render\";\nimport { scope } from \"./update/scope\";\nimport { createCss, css, cx, variants, keyframes, globalStyle } from \"./style\";\n\n/**\n * Initializes the nuclo runtime by exposing tag builders and utilities.\n */\n\nexport function initializeRuntime(): void {\n registerGlobalTagBuilders();\n\n const registry = globalThis as Record<string, unknown>;\n registry.list = list;\n registry.update = update;\n registry.when = when;\n registry.on = on;\n registry.scope = scope;\n registry.render = render;\n registry.hydrate = hydrate;\n\n // Styling — a themeless default instance plus the factory for themed ones.\n // None of these names collide with window/globalThis properties.\n registry.createCss = createCss;\n registry.css = css;\n registry.cx = cx;\n registry.variants = variants;\n registry.keyframes = keyframes;\n registry.globalStyle = globalStyle;\n}\n\ninitializeRuntime();\n"],"mappings":"AAAA,SAAgB,EAAY,EAAoC,CAC/D,OAAO,IAAU,MAAS,OAAO,GAAU,UAAY,OAAO,GAAU,UACzE,CAEA,SAAgB,EAAU,EAA6B,CAItD,OAHI,aAAiB,KAAa,GAC9B,OAAO,GAAU,WAAY,EAAuB,GAEjD,OAAQ,EAAiC,UAAa,QAC9D,CAEA,SAAgB,EAAS,EAAiC,CACzD,OAAO,OAAO,GAAU,YAAY,CACrC,CAEA,SAAgB,EAAa,EAA6C,CACzE,OAAO,EAAS,CAAK,GAAK,YAAc,CACzC,CAEA,SAAgB,EAAU,EAAkC,CAC3D,OAAO,OAAO,GAAU,SACzB,CAQA,SAAgB,EAAW,EAA0D,CACpF,OAAO,OAAO,GAAU,UACzB,CAEA,SAAgB,EAAoB,EAAwC,CAC3E,OAAO,EAAW,CAAK,GAAM,EAA6B,SAAW,CACtE,CCnCA,SAAgB,EAAS,EAAiB,EAA+B,CACnE,OAAO,QAAY,KAErB,QAAQ,MAAM,UAAU,IAAW,CAAK,CAE5C,CCAA,MAAa,EAAY,OAAO,OAAW,KAAe,OAAO,SAAa,ICQ9E,IAAI,EAAa,GAIb,kBAAW,IAAI,QAEnB,SAAgB,GAAuB,CACrC,OAAO,CACT,CASA,SAAgB,GAAyB,CACvC,MAAO,EACT,CAgBA,SAAgB,GAAuB,CACrC,EAAa,GAIb,kBAAW,IAAI,OACjB,CAEA,SAAgB,GAAqB,CACnC,EAAa,EACf,CAQA,SAAgB,EAAuB,EAAgB,CACrD,IAAM,EAAe,EACrB,EAAa,GACb,GAAI,CACF,OAAO,EAAG,CACZ,QAAU,CACR,EAAa,CACf,CACF,CAMA,SAAgB,EAAU,EAA2B,CACnD,IAAM,EAAQ,EAAS,IAAI,CAAM,EACjC,OAAO,IAAU,IAAA,GAAY,EAAO,WAAa,CACnD,CAKA,SAAgB,EAAU,EAAc,EAAyB,CAC/D,EAAS,IAAI,EAAQ,CAAI,CAC3B,CAEA,SAAS,EAAiB,EAAqB,CAC7C,OAAO,EAAK,WAAa,GAAK,CAAC,KAAK,KAAK,EAAK,aAAe,EAAE,CACjE,CAWA,SAAgB,EAAmB,EAAoB,CACrD,IAAI,EAAQ,EAAU,CAAM,EACxB,EAAW,GACf,KAAO,GAAS,EAAiB,CAAK,GACpC,EAAQ,EAAM,YACd,EAAW,GAET,GACF,EAAU,EAAQ,CAAK,CAE3B,CAMA,SAAgB,EAAW,EAA2B,CACpD,IAAM,EAAQ,EAAU,CAAM,EAI9B,OAHI,GACF,EAAU,EAAQ,EAAM,WAAW,EAE9B,CACT,CAMA,SAAgB,GAAa,EAAc,EAAiC,CAC1E,GAAI,CAAC,EAAY,OAAO,KACxB,EAAmB,CAAM,EACzB,IAAM,EAAY,EAAU,CAAM,EAIlC,OAHI,GAAa,EAAU,WAAa,GAAM,EAAsB,QAAQ,YAAY,IAAM,EACrF,EAAW,CAAM,EAEnB,IACT,CASA,SAAgB,EAAyB,EAAY,EAAsC,CACzF,GAAI,CAAC,EAAmB,OACxB,IAAI,EAAU,EAAU,CAAI,EAC5B,KAAO,GAAS,CACd,IAAM,EAAO,IAAY,EAAoB,KAAO,EAAQ,YAC5D,EAAK,YAAY,CAAO,EACxB,EAAU,CACZ,CACA,EAAU,EAAM,IAAI,CACtB,CCxEA,MAcM,kBAAU,IAAI,QAiBpB,IAAI,EAAc,EAEd,EAAiC,CAAC,EAEtC,SAAS,GAAsB,CAQ7B,MAAO,CAAC,GAAa,EAAc,CACrC,CAEA,SAAS,EAAa,EAAmC,CACvD,IAAI,EAAS,EAAQ,IAAI,CAAO,EAMhC,OALK,IACH,EAAS,CAAE,MAAO,KAAM,QAAS,KAAM,MAAO,EAAe,OAAQ,EAAM,EAC3E,EAAQ,IAAI,EAAS,CAAM,EAC3B,KAEK,CACT,CAEA,SAAS,EAAY,EAA8B,EAAwB,CAMzE,OALI,IAAS,KAAa,EACtB,MAAM,QAAQ,CAAI,GACpB,EAAK,KAAK,CAAE,EACL,GAEF,CAAC,EAAM,CAAE,CAClB,CAEA,SAAS,EAAQ,EAAkB,EAA+B,CAC5D,EAAO,QAAU,EAAO,QAAU,IACtC,EAAO,OAAS,GAChB,EAAW,KAAK,IAAI,QAAQ,CAAO,CAAC,EACtC,CAGA,SAAgB,GACd,EACA,EACM,CACN,GAAI,EAAW,EAAG,OAClB,IAAM,EAAS,EAAa,CAAO,EAM/B,EAAO,QAAU,IACrB,EAAO,MAAQ,EAAS,EAAO,MAAO,CAAkC,EACxE,EAAQ,EAAS,CAAM,EACzB,CAGA,SAAgB,GACd,EACA,EACM,CACN,GAAI,EAAW,EAAG,OAClB,IAAM,EAAS,EAAa,CAAO,EAC/B,EAAO,QAAU,IACrB,EAAO,QAAU,EAAS,EAAO,QAAS,CAAoC,EAC9E,EAAQ,EAAS,CAAM,EACzB,CAEA,SAAS,GAAS,EAAkB,EAAkC,EAA+B,CAC/F,KAAO,QAAU,EACrB,GAAI,CACF,IAAM,EAAU,EAAS,CAAO,EAC5B,OAAO,GAAY,aASjB,EAAQ,IAAI,CAAO,CAAC,EAAE,QAAU,EAAgB,GAAW,EAAS,CAAO,EAC1E,EAAO,QAAU,EAAS,EAAO,QAAS,CAAO,EAE1D,OAAS,EAAO,CACd,EAAS,0BAA2B,CAAK,CAC3C,CACF,CAEA,SAAS,GAAW,EAAkB,EAA0C,CAC9E,GAAI,CACF,EAAS,CAAO,CAClB,OAAS,EAAO,CACd,EAAS,4BAA6B,CAAK,CAC7C,CACF,CAEA,SAAS,GAAU,EAAwB,CACzC,IAAM,EAAS,EAAQ,IAAI,CAAO,EAKlC,GAJI,CAAC,IACL,EAAO,OAAS,GAGZ,EAAO,QAAU,GAAe,OACpC,EAAO,MAAQ,EAEf,IAAM,EAAQ,EAAO,MACrB,KAAO,MAAQ,KACX,IAAU,KACd,IAAI,MAAM,QAAQ,CAAK,EACrB,IAAK,IAAI,EAAI,EAAG,EAAI,EAAM,OAAQ,IAAK,GAAS,EAAS,EAAM,GAAI,CAAM,OAEzE,GAAS,EAAS,EAAO,CAAM,CAAA,CAEnC,CAYA,SAAgB,IAAwB,CACtC,GAAI,EAAW,SAAW,EAAG,OAC7B,IAAM,EAAQ,EACd,EAAa,CAAC,EACd,IAAK,IAAI,EAAI,EAAG,EAAI,EAAM,OAAQ,IAAK,CACrC,IAAM,EAAU,EAAM,EAAE,CAAC,MAAM,EAC3B,GAAS,GAAU,CAAO,CAChC,CACF,CAUA,SAAgB,GAAwB,EAAwB,CAC9D,IAAM,EAAS,EAAQ,IAAI,CAAO,EAElC,GADI,CAAC,GACD,EAAO,QAAU,EAAgB,OAErC,IAAM,EAAa,EAAO,QAAU,EAIpC,GAHA,EAAO,MAAQ,EACf,IAEI,EAAY,CACd,IAAM,EAAU,EAAO,QACvB,GAAI,IAAY,KAAM,CACpB,GAAI,MAAM,QAAQ,CAAO,EACvB,IAAK,IAAI,EAAI,EAAG,EAAI,EAAQ,OAAQ,IAAK,GAAW,EAAS,EAAQ,EAAE,OAEvE,GAAW,EAAS,CAAO,CAE/B,CACF,CAKA,EAAO,MAAQ,KACf,EAAO,QAAU,IACnB,CASA,SAAgB,IAA2C,CACzD,OAAO,EAAc,CACvB,CChQA,MAAM,kBAAmB,IAAI,QAK7B,SAAS,GACP,EACA,EACM,CACN,IAAM,EAAU,EAAiB,IAAI,CAAO,EACvC,EAEM,MAAM,QAAQ,CAAO,EACzB,EAAQ,SAAS,CAAI,GAAG,EAAQ,KAAK,CAAI,EACrC,IAAY,GACrB,EAAiB,IAAI,EAAS,CAAC,EAAS,CAAI,CAAC,EAJ7C,EAAiB,IAAI,EAAS,CAAI,CAMtC,CAKA,SAAS,GACP,EACA,EACM,CACN,EAAQ,oBAAoB,EAAK,KAAM,EAAK,QAAS,EAAK,OAAO,CACnE,CAKA,SAAgB,GACd,EACA,EACM,CACN,IAAM,EAAU,EAAiB,IAAI,CAAO,EAC5C,GAAI,CAAC,EAAS,OAEd,GAAI,IAAS,IAAA,GAAW,CACtB,GAAI,MAAM,QAAQ,CAAO,EACvB,IAAK,IAAI,EAAI,EAAG,EAAI,EAAQ,OAAQ,IAClC,GAAe,EAAS,EAAQ,EAAE,OAGpC,GAAe,EAAS,CAAO,EAEjC,EAAiB,OAAO,CAAO,EAC/B,MACF,CAEA,GAAI,CAAC,MAAM,QAAQ,CAAO,EAAG,CACvB,EAAQ,OAAS,IACnB,GAAe,EAAS,CAAO,EAC/B,EAAiB,OAAO,CAAO,GAEjC,MACF,CAGA,IAAI,EAAQ,EACZ,IAAK,IAAI,EAAO,EAAG,EAAO,EAAQ,OAAQ,IAAQ,CAChD,IAAM,EAAO,EAAQ,GACjB,EAAK,OAAS,EAChB,GAAe,EAAS,CAAI,EAE5B,EAAQ,KAAW,CAEvB,CACI,IAAU,EACZ,EAAiB,OAAO,CAAO,EACtB,IAAU,EACnB,EAAiB,IAAI,EAAS,EAAQ,EAAE,EAExC,EAAQ,OAAS,CAErB,CAEA,SAAS,GAAkB,EAAgD,CAAC,CAQ5E,SAAS,GACP,EACA,EACqB,CAGrB,OAFK,EAEE,SAAS,EAAyC,CACvD,GAAI,CAAC,EAAQ,OACb,IAAM,EAAK,EACP,IAAS,QACX,GAAc,EAAI,CAA0D,EAE5E,GAAgB,EAAI,CAA4D,CAEpF,EAVuB,EAWzB,CAEA,SAAS,GACP,EACA,EACA,EACiB,CAajB,MAAO,CAAE,OAAM,iBAZ6B,EAAoB,CAC9D,IAAM,EAAgB,KACtB,GAAI,CACF,EAAS,KACP,EACA,CACF,CACF,OAAS,EAAO,CACd,EAAS,aAAa,EAAK,YAAa,CAAK,CAC/C,CACF,EAEwB,SAAQ,CAClC,CAmDA,SAAgB,GACd,EACA,EAIA,EACqB,CACrB,GAAI,IAAS,SAAW,IAAS,UAC/B,OAAO,GACL,EACA,CACF,EAGF,GAAI,CAAC,EAAW,OAAO,GAOvB,IAAM,EAAO,GACX,EACA,EAPc,IAAY,IACF,OAAO,GAAY,YAAvC,GAAmD,EAAQ,UAAY,EAQ7E,EAEA,OAAO,SAAS,EAAyC,CAEvD,GAAI,CAAC,GAAU,OAAQ,EAAuB,kBAAqB,WACjE,OAGF,IAAM,EAAK,EAEX,EAAG,iBAAiB,EAAM,EAAK,QAAS,CAAO,EAG/C,GAAc,EAAI,CAAI,CACxB,CACF,CCzMA,MAAa,mBAAoB,IAAI,IAKxB,kBAA0B,IAAI,QAK9B,mBAAmB,IAAI,IAKvB,kBAAyB,IAAI,QAK1C,SAAgB,GAAyB,EAAY,EAAkC,CACrF,IAAM,EAAW,EAAwB,IAAI,CAAI,EACjD,GAAI,EAAU,CAEZ,EAAS,KAAK,SAAW,EAAK,SAC9B,EAAS,KAAK,UAAY,EAAK,UAC/B,EAAS,KAAK,SAAW,EAAK,SAC9B,MACF,CACA,IAAM,EAAM,IAAI,QAAQ,CAAI,EAC5B,GAAkB,IAAI,CAAG,EACzB,EAAwB,IAAI,EAAM,CAAE,MAAK,MAAK,CAAC,CACjD,CAKA,SAAgB,GAAwB,EAAkB,EAAiC,CACzF,IAAM,EAAW,EAAuB,IAAI,CAAO,EACnD,GAAI,EAAU,CACZ,EAAS,KAAO,EAChB,MACF,CACA,IAAM,EAAM,IAAI,QAAQ,CAAO,EAC/B,GAAiB,IAAI,CAAG,EACxB,EAAuB,IAAI,EAAS,CAAE,MAAK,MAAK,CAAC,CACnD,CAKA,SAAgB,GAA0B,EAA0B,CAClE,GAAkB,OAAO,CAAG,CAC9B,CAKA,SAAgB,GAAyB,EAA6B,CACpE,GAAiB,OAAO,CAAG,CAC7B,CAMA,SAAgB,GAAwB,EAAkB,CACxD,IAAM,EAAQ,EAAwB,IAAI,CAAI,EAC1C,IACF,GAAkB,OAAO,EAAM,GAAG,EAClC,EAAwB,OAAO,CAAI,EAEvC,CAMA,SAAgB,GAAuB,EAAwB,CAC7D,IAAM,EAAQ,EAAuB,IAAI,CAAO,EAC5C,IACF,GAAiB,OAAO,EAAM,GAAG,EACjC,EAAuB,OAAO,CAAO,EAEzC,CAeA,MAAM,mBAAqB,IAAI,QAOzB,kBAAyB,IAAI,IAK7B,mBAAY,IAAI,QAMhB,GAA2B,OAAO,qBAAyB,IAC9D,IAAI,qBAAqC,GAAQ,CAAE,EAAuB,OAAO,CAAG,CAAG,CAAC,EACxF,KAKH,SAAgB,GACf,EACA,EACO,CAEP,GADA,GAAmB,IAAI,EAAM,CAAuC,EAChE,GAAU,IAAI,CAAI,EAAG,OACzB,IAAM,EAAM,IAAI,QAAQ,CAAI,EAC5B,EAAuB,IAAI,CAAG,EAC9B,GAAU,IAAI,EAAM,CAAG,EACvB,IAA0B,SAAS,EAAM,EAAK,CAAG,CAClD,CAMA,SAAgB,GAA0B,EAAkB,CAC3D,GAAmB,OAAO,CAAI,EAC9B,IAAM,EAAM,GAAU,IAAI,CAAI,EAC1B,IACH,EAAuB,OAAO,CAAG,EACjC,IAA0B,WAAW,CAAG,EACxC,GAAU,OAAO,CAAI,EAEvB,CAMA,SAAgB,IAAoC,CACnD,IAAM,EAAgB,CAAC,EAEvB,IAAK,IAAM,KAAO,EAAwB,CACzC,IAAM,EAAO,EAAI,MAAM,EACnB,IAAS,IAAA,GACZ,EAAuB,OAAO,CAAG,EAEjC,EAAM,KAAK,CAAI,CAEjB,CAEA,OAAO,CACR,CAEA,SAAgB,GAAmB,EAAoD,CACtF,OAAO,GAAmB,IAAI,CAAI,GAAK,IACxC,CC7NA,MAAa,GAAgB,6BAU7B,SAAgB,GAAc,EAAyC,CACrE,OAAO,WAAW,SAAW,SAAS,cAAc,CAAO,EAAuB,IACpF,CAMA,SAAgB,GACd,EACA,EACwB,CACxB,OAAO,WAAW,SAAW,SAAS,gBAAgB,EAAW,CAAO,EAAuB,IACjG,CAMA,SAAgB,EAAe,EAA2B,CACxD,OAAO,WAAW,SAAW,SAAS,eAAe,CAAI,EAAI,IAC/D,CAMA,SAAgB,IAAkD,CAChE,OAAO,WAAW,SAAW,SAAS,uBAAuB,EAAI,IACnE,CAEA,SAAS,GAAgB,EAAwB,EAAsB,CACrE,GAAI,CAEF,OADA,EAAO,YAAY,CAAK,EACjB,EACT,OAAS,EAAO,CAEd,OADA,EAAS,8BAA+B,CAAK,EACtC,EACT,CACF,CAMA,SAAS,GAAgB,EAAkB,CAIzC,GAAI,EAAK,WAAa,KAAK,aAAc,CACvC,IAAM,EAAU,EAEhB,GAAmB,CAAO,EAE1B,GAAuB,CAAO,EAE9B,GAA0B,CAAO,CACnC,MAAW,EAAK,WAAa,KAAK,UAEhC,GAAwB,CAAY,EAC3B,EAAK,WAAa,KAAK,cAEhC,GAA0B,CAAI,EAMhC,IAAM,EAAW,GAAgC,EAAI,MAAM,KAAK,EAAK,UAAU,EAAI,EAAK,WACxF,IAAK,IAAI,EAAI,EAAG,EAAI,EAAS,OAAQ,IACnC,GAAgB,EAAS,EAAE,EAYzB,EAAK,WAAa,KAAK,cACzB,GAAwB,CAAmB,CAE/C,CAYA,SAAgB,GAA2B,EAAkB,CAC3D,GAAI,CAAC,GAAgC,EAAG,OACxC,IAAM,EAAW,MAAM,KAAK,EAAK,UAAU,EAC3C,IAAK,IAAI,EAAI,EAAG,EAAI,EAAS,OAAQ,IACnC,GAA2B,EAAS,EAAE,EAEpC,EAAK,WAAa,KAAK,cACzB,GAAwB,CAAe,CAE3C,CAEA,SAAgB,GAAgB,EAAsB,CACpD,GAAI,CAAC,GAAO,WAAY,MAAO,GAC/B,GAAI,CAKF,OAHA,GAAgB,CAAK,EAErB,EAAM,YAAY,YAAY,CAAK,EAC5B,EACT,OAAS,EAAO,CAEd,OADA,EAAS,8BAA+B,CAAK,EACtC,EACT,CACF,CAEA,SAAS,GAAiB,EAAc,EAAe,EAAqC,CAC1F,GAAI,CAEF,OADA,EAAO,aAAa,EAAS,CAAa,EACnC,EACT,OAAS,EAAO,CAEd,OADA,EAAS,yCAA0C,CAAK,EACjD,EACT,CACF,CAEA,SAAgB,EAAc,EAA8B,CAC1D,OAAO,WAAW,SAAW,WAAW,SAAS,cAAc,CAAI,EAAI,IACzE,CAEA,SAAgB,GAAyB,EAAiB,EAAS,SAA0B,CAC3F,OAAO,WAAW,SAAW,WAAW,SAAS,cAAc,eAAe,EAAQ,GAAG,GAAQ,EAAI,IACvG,CAEA,SAAgB,GAAiB,EAAgB,EAAuD,CACtG,IAAM,EAAa,EAAc,GAAG,EAAO,KAAK,EAChD,GAAI,CAAC,EAAY,MAAU,MAAM,kDAAkD,EACnF,IAAM,EAAe,EAAc,GAAG,EAAO,SAAS,GAAI,EAC1D,GAAI,CAAC,EAAc,MAAU,MAAM,kDAAkD,EACrF,MAAO,CAAE,MAAO,EAAc,IAAK,CAAW,CAChD,CAEA,SAAgB,GAAoB,EAAsB,EAA0B,CAClF,IAAI,EAAU,EAAY,YAC1B,KAAO,GAAW,IAAY,GAAW,CACvC,IAAM,EAAO,EAAQ,YACrB,GAAgB,CAAO,EACvB,EAAU,CACZ,CACF,CAEA,SAAgB,GAAkB,EAAe,EAA2B,CAC1E,IAAM,EAAS,EAAc,WAC7B,GAAI,EACF,IAAK,IAAI,EAAI,EAAG,EAAI,EAAM,OAAQ,IAChC,GAAiB,EAAQ,EAAM,GAAI,CAAa,CAGtD,CAEA,SAAgB,GACd,EACA,GAAG,EACa,CAChB,GAAI,CAAC,EAAQ,OAAO,EAEpB,IAAK,IAAI,EAAI,EAAG,EAAI,EAAS,OAAQ,IAAK,CACxC,IAAM,EAAQ,EAAS,GACvB,GAAI,GAAS,KAAM,CACjB,IAAI,EAEJ,GAAI,OAAO,GAAU,SAAU,CAC7B,IAAM,EAAW,EAAe,CAAK,EACrC,GAAI,EACF,EAAe,OAEf,QAEJ,KACE,GAAe,EAGjB,GAAgB,EAAQ,CAAY,CACtC,CACF,CAEA,OAAO,CACT,CAEA,SAAgB,EAAgB,EAAwC,CACtE,OAAO,GAAM,cAAgB,EAC/B,CAMA,SAAgB,GAAkB,EAAe,EAAwB,CACvE,GAAI,CAAC,GAAS,WAAY,MAAO,GACjC,GAAI,CAEF,OADA,EAAQ,WAAW,aAAa,EAAS,CAAO,EACzC,EACT,OAAS,EAAO,CAEd,OADA,EAAS,mCAAoC,CAAK,EAC3C,EACT,CACF,CAWA,SAAgB,GAAyC,EAA+B,CACtF,OAAO,CACT,CAYA,SAAgB,GACd,EACA,EACA,EACG,CACH,IAAM,EAAS,GAAa,CAAI,EAC1B,EAAiB,OAAO,yBAAyB,EAAQ,aAAa,EACtE,EAAiB,EAAO,aAI9B,EAA+C,YAAc,SAAS,EAAkB,CACtF,OAAO,EAAe,KAAK,EAAQ,EAAM,CAAa,CACxD,EAEA,GAAI,CACF,OAAO,EAAS,CAClB,QAAU,CAEJ,EAAgB,OAAO,eAAe,EAAQ,cAAe,CAAc,EAC1E,QAAQ,eAAe,EAAQ,aAAa,CACnD,CACF,CAYA,SAAgB,GACd,EACA,EACA,EACS,CACT,GAAI,CACF,GAAI,GAAU,MAA+B,IAAU,GAGrD,MADA,GAAS,MAA4C,GAAY,GAC1D,GAIT,IAAM,EAAc,OAAO,CAAK,EAGhC,MADA,GAAS,MAA4C,GAAY,EAC1D,EACT,MAAQ,CACN,MAAO,EACT,CACF,CC3SA,MAAM,GAAmB,CAAC,EAC1B,IAAI,GAAgC,GAEpC,SAAS,GAAkB,EAAoB,CAI7C,IAAM,EAAS,EAAM,OACrB,GAAI,CAAC,GAAU,OAAO,KAAS,KAAe,EAAE,aAAkB,MAAO,OAEzE,IAAI,EAAoB,EACxB,KAAO,GAAM,CACX,GAAI,aAAgB,QAAS,CAC3B,IAAM,EAAQ,EAAuB,IAAI,CAAI,EACzC,IACG,EAAgB,CAAI,EAIvB,GAAwB,EAAM,IAAI,GAHlC,GAAyB,EAAM,GAAG,EAClC,EAAuB,OAAO,CAAI,GAKxC,CACA,EAAO,EAAK,UACd,CACF,CAEA,SAAS,IAAwC,CAC3C,IACA,OAAO,SAAa,KAAe,OAAO,SAAS,kBAAqB,aAC5E,SAAS,iBAAiB,SAAU,GAAmB,EAAI,EAC3D,GAAgC,GAClC,CAEA,SAAS,GAAkB,EAAkC,CAC3D,IAAM,EAAQ,EAAuB,IAAI,CAAE,EAC3C,GAAI,EAAO,OAAO,EAAM,KAGxB,IAAM,EAA4B,CAAE,mBAAoB,CAAC,CAAE,EAE3D,OADA,GAAwB,EAAI,CAAI,EACzB,CACT,CAEA,SAAS,GAAiB,EAAyB,CAEjD,OAAyB,OAAO,GAAU,WAAnC,CACT,CAEA,SAAS,GAA8B,EAAuC,CAC5E,IAAI,EACJ,GAAI,CACF,EAAY,EAAO,SAAS,CAC9B,OAAS,EAAG,CACV,EAAS,yCAAyC,EAAO,MAAO,CAAC,EACjE,MACF,CAEA,IAAM,EAAY,GAAiB,CAAS,EACxC,QAAa,OAAO,GAAG,EAAW,EAAO,SAAS,GAEtD,GAAI,CACF,EAAO,WAAW,CAAS,EAC3B,EAAO,UAAY,EAAY,EAAY,EAC7C,OAAS,EAAG,CACV,EAAS,uCAAuC,EAAO,MAAO,CAAC,CACjE,CACF,CAEA,SAAS,GAAwB,EAAiC,CAChE,IAAM,EAAY,EAAK,mBACvB,IAAK,IAAI,EAAI,EAAG,EAAI,EAAU,OAAQ,IACpC,GAA8B,EAAU,EAAE,CAE9C,CA0BA,SAAgB,GACd,EACA,EACA,EACA,EACM,CACN,GAAI,EAAE,aAAmB,UAAY,CAAC,GAAO,OAAO,GAAa,WAAY,CAC3E,EAAS,kDAAkD,EAC3D,MACF,CAEA,IAAM,EAAkC,CAAE,MAAK,WAAU,aAAY,UAAW,EAAiB,EAEjG,GAAI,CAAC,EAAW,CAEd,GAA8B,CAAM,EACpC,MACF,CAEA,GAAgC,EAGhC,IAAM,EAFO,GAAkB,CAEV,CAAC,CAAC,mBACnB,EAAW,GACf,IAAK,IAAI,EAAI,EAAG,EAAI,EAAU,OAAQ,IACpC,GAAI,EAAU,EAAE,CAAC,MAAQ,EAAK,CAC5B,EAAU,GAAK,EACf,EAAW,GACX,KACF,CAEG,GAAU,EAAU,KAAK,CAAM,EACpC,GAA8B,CAAM,CACtC,CAkBA,SAAgB,GAAuB,EAA2B,CAChE,IAAK,IAAM,KAAO,GAAkB,CAClC,IAAM,EAAK,EAAI,MAAM,EACrB,GAAI,IAAO,IAAA,GAAW,CACpB,GAAyB,CAAG,EAC5B,QACF,CAEA,IAAM,EAAQ,EAAuB,IAAI,CAAE,EAC3C,GAAI,CAAC,EAAO,CACV,GAAyB,CAAG,EAC5B,QACF,CAEA,GAAI,CAAC,EAAgB,CAAE,EAAG,CACxB,EAAuB,OAAO,CAAE,EAChC,GAAyB,CAAG,EAC5B,QACF,EAEI,IAAU,EAAM,SAAS,CAAE,IAC/B,GAAwB,EAAM,IAAI,CACpC,CAEF,CC3KA,SAAgB,GACd,EACA,EACM,CACF,GAAC,GAAS,OAAU,EAExB,IAAK,IAAM,KAAY,EACL,GACd,EACA,EACC,EAAkD,EAG1C,GAET,EAAS,iCAAiC,EAAS,EAAE,CAG3D,CAEA,SAAgB,GACd,EACA,EACM,CACD,IAED,EAAW,CAAU,EACvB,GAA0B,EAAS,QAAS,EAAY,SAAS,EAAgB,CAC/E,GAAmB,EAAS,CAAiC,CAC/D,CAAC,EAED,GAAmB,EAAS,CAAU,EAE1C,CC5CA,MAYM,mBAAgC,IAAI,IAAI,CAAC,UAAW,WAAW,CAAC,EAIhE,mBAAyB,IAAI,QAGnC,SAAgB,GAAyB,EAAkC,CACzE,GACE,EAAU,QAAU,GACjB,EAAU,WAAW,CAAC,IAAM,KAC5B,EAAU,WAAW,CAAC,IAAM,IAE/B,OAAO,KAGT,IAAM,EAAsB,EAAU,WAAW,CAAC,EAOlD,OANI,EAAsB,IAAc,EAAsB,IAI1D,GAA8B,IAAI,CAAS,EAAU,KACrD,IAAc,gBAAwB,aACnC,EAAU,YAAY,CAC/B,CAGA,SAAgB,GACd,EACA,EACA,EACM,CACN,GAAI,KAAY,EAAS,CACvB,EAAgD,GAAY,EAC5D,MACF,CAEA,IAAM,EAAO,EAAS,MAAM,CAAC,EACvB,EAAO,GAAuB,IAAI,CAAO,EAC/C,GAAI,EAAM,CACR,IAAK,IAAI,EAAI,EAAG,EAAI,EAAK,OAAQ,GAAK,EAAG,CACvC,GAAI,EAAK,KAAO,EAAM,SAEtB,IAAM,EAAW,EAAK,EAAI,GAC1B,GAAI,IAAa,EAAU,OAC3B,EAAQ,oBAAoB,EAAM,CAAQ,EAC1C,EAAQ,iBAAiB,EAAM,CAAQ,EACvC,EAAK,EAAI,GAAK,EACd,MACF,CAEA,EAAQ,iBAAiB,EAAM,CAAQ,EACvC,EAAK,KAAK,EAAM,CAAQ,EACxB,MACF,CAEA,EAAQ,iBAAiB,EAAM,CAAQ,EACvC,GAAuB,IAAI,EAAS,CAAC,EAAM,CAAQ,CAAC,CACtD,CCrEA,MAAM,kBAAmB,IAAI,QACvB,mBAAyB,IAAI,QAMnC,SAAS,GAAe,EAAqB,EAAyB,CACrE,IAAM,EAAM,EAAU,OAClB,EAAQ,EACZ,IAAK,IAAI,EAAI,EAAG,GAAK,EAAK,KACrB,IAAM,GAAO,EAAU,WAAW,CAAC,IAAM,MACxC,EAAI,GAAO,EAAO,IAAI,EAAU,UAAU,EAAO,CAAC,CAAC,EACvD,EAAQ,EAAI,EAGf,CAKA,SAAS,GAAY,EAA8B,CAClD,IAAI,EAAS,GACb,IAAK,IAAM,KAAO,EACb,IAAQ,GAAU,KACtB,GAAU,EAEX,OAAO,CACR,CAOA,SAAgB,GAAsB,EAAuB,CAC5D,GAAI,EAAG,WAAa,CAAC,EAAiB,IAAI,CAAE,EAAG,CAC9C,IAAM,kBAAW,IAAI,IACrB,GAAe,EAAU,EAAG,SAAS,EACrC,EAAiB,IAAI,EAAI,CAAQ,CAClC,CACA,GAAuB,IAAI,CAAE,CAC9B,CAGA,SAAgB,GAAqB,EAA0B,CAC9D,OAAO,GAAuB,IAAI,CAAE,CACrC,CAGA,SAAgB,GAAiB,EAAiB,EAAyB,CAC1E,GAAI,CAAC,EAAW,OAChB,IAAI,EAAW,EAAiB,IAAI,CAAE,EACjC,IACJ,kBAAW,IAAI,IACf,EAAiB,IAAI,EAAI,CAAQ,GAElC,GAAe,EAAU,CAAS,CACnC,CAGA,SAAgB,GAAuB,EAAiB,EAAiC,CACxF,IAAM,EAAgB,EAAiB,IAAI,CAAE,EAE7C,GAAI,CAAC,GAAiB,EAAc,OAAS,EAAG,CAG/C,IAAM,EAAO,GAAqB,GAC9B,EAAG,YAAc,IAAM,EAAG,UAAY,GAC1C,MACD,CACA,GAAI,CAAC,EAAmB,CACvB,EAAG,UAAY,GAAY,CAAa,EACxC,MACD,CAGA,IAAI,EAAS,GAAY,CAAa,EAChC,EAAM,EAAkB,OAC1B,EAAQ,EACZ,IAAK,IAAI,EAAI,EAAG,GAAK,EAAK,IACzB,GAAI,IAAM,GAAO,EAAkB,WAAW,CAAC,IAAM,GAAI,CACxD,GAAI,EAAI,EAAO,CACd,IAAM,EAAQ,EAAkB,UAAU,EAAO,CAAC,EAC7C,EAAc,IAAI,CAAK,IAC3B,GAAU,IAAM,EAElB,CACA,EAAQ,EAAI,CACb,CAED,EAAG,UAAY,CAChB,CAGA,SAAgB,GAAqB,EAAiB,EAA4B,CACjF,GAAI,CAAC,EAAc,OACnB,IAAM,EAAmB,EAAG,UAC5B,GAAI,GAAoB,IAAqB,EAAc,CAC1D,IAAM,kBAAW,IAAI,IACrB,GAAe,EAAU,CAAgB,EACzC,GAAe,EAAU,CAAY,EACrC,EAAG,UAAY,GAAY,CAAQ,CACpC,KACC,GAAG,UAAY,CAEjB,CClFA,SAAgB,GAAuB,EAAwB,EAAwB,EAA6C,CAClI,GAAI,OAAO,GAAa,WAAY,CAClC,EAAS,qDAAqD,EAC9D,IAAM,EAAe,EAAe,EAAE,EACtC,GAAI,CAAC,EACH,MAAU,MAAM,oDAAoD,EAEtE,OAAO,CACT,CAEA,IAAI,EACJ,GAAI,UAAU,OAAS,EACrB,EAAU,OAEV,GAAI,CACF,EAAU,EAAS,CACrB,OAAS,EAAG,CACV,EAAS,4CAA6C,CAAC,EACvD,EAAU,EACZ,CAEF,IAAM,EAAM,IAAY,IAAA,GAAY,GAAK,OAAO,CAAO,EACjD,EAAM,EAAe,CAAG,EAE9B,GAAI,CAAC,EACH,MAAU,MAAM,oDAAoD,EAMtE,OAHI,GACF,GAAyB,EAAK,CAAE,WAAU,UAAW,EAAK,UAAS,CAAC,EAE/D,CACT,CAiBA,SAAgB,GAAwB,EAA2B,CACjE,IAAK,IAAM,KAAO,GAAmB,CACnC,IAAM,EAAO,EAAI,MAAM,EACvB,GAAI,IAAS,IAAA,GAAW,CACtB,GAA0B,CAAG,EAC7B,QACF,CAEA,IAAM,EAAQ,EAAwB,IAAI,CAAI,EAC9C,GAAI,CAAC,EAAO,CACV,GAA0B,CAAG,EAC7B,QACF,CACA,IAAM,EAAO,EAAM,KAEnB,GAAI,CAAC,EAAgB,CAAI,EAAG,CAC1B,EAAwB,OAAO,CAAI,EACnC,GAA0B,CAAG,EAC7B,QACF,CAEA,GAAI,GAAS,CAAC,EAAM,SAAS,CAAI,EAAG,SAEpC,IAAI,EACJ,GAAI,CACF,EAAM,EAAK,SAAS,CACtB,OAAS,EAAG,CACV,EAAS,sCAAuC,CAAC,EACjD,EAAM,IAAA,EACR,CAIA,IAAM,EAAS,EAAK,SACf,GAAO,MAAQ,OAAO,GAAQ,UAAY,OAAO,GAAQ,WAAa,GAAK,OAAO,CAAG,EACrF,IAAQ,IAAA,GAAY,GAAK,OAAO,CAAG,EACpC,IAAW,EAAK,YAClB,EAAK,YAAc,EACnB,EAAK,UAAY,EAErB,CAEF,CC3FA,SAAS,GACP,EACA,EACA,EACA,EACM,CACF,MAAK,KAGT,IAAI,GAAS,IAAQ,aAAe,aAAc,YAAa,CAC7D,GAAqB,EAAI,OAAO,CAAC,CAAC,EAClC,MACF,CAIA,GAAI,aAAc,SAAW,EAAG,eAAA,6BAC9B,EAAG,aAAa,EAAK,OAAO,CAAC,CAAC,OACzB,GAAI,KAAO,EAEhB,GAAI,CACF,EAAgC,GAAO,CACzC,MAAQ,CAEF,aAAc,SAChB,EAAG,aAAa,EAAK,OAAO,CAAC,CAAC,CAElC,MACS,aAAc,SACvB,EAAG,aAAa,EAAK,OAAO,CAAC,CAAC,CAjBhC,CAmBF,CAEA,SAAgB,GACd,EACA,EACA,EACA,EAAuB,GACjB,CACN,GAAI,GAAO,KAAM,OACjB,IAAM,EAAI,EAEV,GAAI,IAAM,QAAS,CACjB,GAAoB,EAAI,CAAgD,EACxE,MACF,CAEA,GAAI,EAAW,CAAG,EAAG,CAKnB,GAAI,IAAM,UAAW,CACnB,GAAc,EAA0B,CAA6B,EACrE,MACF,CACA,GAAI,IAAM,YAAa,CACrB,GAAgB,EAA0B,CAA+B,EACzE,MACF,CAGA,GAAI,IAAM,UAAW,CACnB,EAAgC,QAAU,EAC1C,MACF,CAEA,GACE,EAAE,WAAW,CAAC,IAAM,KACjB,EAAE,WAAW,CAAC,IAAM,IACvB,CAEA,IAAM,EAAgB,GAAyB,CAAC,EAChD,GAAI,EAAe,CACjB,GAAkB,EAAmB,EAAe,CAAoB,EACxE,MACF,CAIA,GAAI,KAAK,EAAI,CACX,EAAgC,GAAK,EACrC,MACF,CACF,CAEA,GAAI,EAAI,SAAW,EAAG,CAEpB,IAAM,EAAW,EAIb,IAAM,aAAe,aAAc,aACrC,GAAsB,CAAE,EAExB,GAA0B,EAAI,EAAG,EAAU,SAAS,EAAG,CACrD,GAAuB,EAAI,OAAO,GAAK,EAAE,CAAC,CAC5C,CAAC,GAED,GAA0B,EAAI,EAAG,EAAU,SAAS,EAAG,CACrD,GAAkB,EAAI,EAAG,EAAG,EAAK,CACnC,CAAC,EAEH,MACF,CAGF,CAIA,GAAI,IAAM,aAAe,aAAc,aAAe,GAAqB,CAAE,EAAG,CAE9E,IAAM,EAAe,OAAO,GAAO,EAAE,EACjC,IACF,GAAiB,EAAI,CAAY,EACjC,GAAqB,EAAI,CAAY,GAEvC,MACF,CACA,GAAkB,EAAI,EAAG,EAAK,CAAoB,CACpD,CAEA,SAAgB,EACd,EACA,EACA,EAAiB,GACX,CACD,KAGL,IAAK,IAAM,KAAK,EAAY,CAC1B,IAAM,EAAM,EACN,EAAS,EAAuC,GAItD,GAAqB,EAAS,EAAK,EADf,GAAkB,IAAQ,WACO,CACvD,CACF,CClJA,MAAa,kBAAqB,IAAI,QAetC,SAAS,GAAsB,EAAsC,CACpE,OACC,EAAS,CAAC,GACV,CAAC,EAAO,CAAC,GACT,cAAe,GACf,OAAQ,EAA6B,WAAc,UACnD,OAAO,KAAK,CAAC,CAAC,CAAC,SAAW,CAE5B,CAEA,SAAS,GAAuB,EAAuB,CACtD,EAAmB,CAAM,EACzB,IAAM,EAAQ,EAAU,CAAM,EAC9B,MAAO,CAAC,CAAC,GAAS,EAAM,WAAa,GACnC,EAAkB,aAAa,UAAU,CAAC,CAAC,WAAW,OAAO,IAAM,EACtE,CAYA,SAAS,GAAqB,EAAc,EAA+B,CAC1E,IAAM,EAAO,EAAU,CAAM,EAC7B,GAAI,GAAQ,EAAK,WAAa,EAK7B,OAJA,EAAW,CAAM,EACb,EAAK,cAAgB,IACxB,EAAK,YAAc,GAEb,EAER,IAAM,EAAU,EAAe,CAAQ,EAIvC,OAHK,GACL,EAAO,aAAa,EAAS,CAAI,EACjC,EAAU,EAAQ,CAAI,EACf,GAHc,IAItB,CAEA,SAAgB,EACf,EACA,EACA,EACc,CACd,GAAI,GAAY,KAAM,OAAO,KAE7B,GAAI,EAAW,CAAQ,EAAG,CAEzB,GAAI,EAAoB,CAAQ,EAC/B,GAAI,CACH,IAAI,EAAS,EAAmB,IAAI,CAAQ,EAM5C,GALK,IAEJ,EAAS,CAAE,MADG,EACC,EAAG,MAAO,EAAM,EAC/B,EAAmB,IAAI,EAAU,CAAM,GAEpC,EAAO,MACV,OAAO,GAAwB,MAAa,EAAE,EAE/C,IAAM,EAAI,EAAO,MAGjB,GAAI,GAAsB,CAAC,EAM1B,OADA,EAAgB,EAAQ,CAAE,cAJQ,CACjC,IAAM,EAAS,EAAS,EACxB,OAAO,GAAsB,CAAM,EAAI,EAAO,UAAY,EAC3D,CACiD,CAAwC,EAClF,KAGR,GAAI,EAAY,CAAC,EAAG,CAOnB,IAAM,EAAW,EACX,EAAqB,GAA+B,GAC1D,GAAI,EAAY,GAAK,GAAuB,CAAyB,EAAG,CACvE,IAAM,EAAa,EACnB,EAAW,CAAU,EACrB,IAAM,EAAW,OAAO,CAAO,EACzB,EAAW,GAAqB,EAAY,CAAQ,EAQ1D,OAPI,GACH,GAAyB,EAAU,CAClC,WACA,UAAW,EACX,SAAU,EACX,CAAC,EAEK,IACR,CACA,OAAO,GAAwB,EAAO,EAAU,EAAS,EAAI,CAC9D,CACA,OAAO,IACR,OAAS,EAAO,CAGf,OAFA,EAAmB,IAAI,EAAU,CAAE,MAAO,IAAA,GAAW,MAAO,EAAK,CAAC,EAClE,EAAS,2CAA4C,CAAK,EACnD,GAAwB,MAAa,EAAE,CAC/C,CAID,IAAM,EAAY,EAAiC,EAAQ,CAAK,EAOhE,OANI,GAAY,KAAa,KACzB,EAAY,CAAQ,EAAU,GAAsB,EAAO,CAAQ,EACnE,EAAO,CAAQ,EAAU,GACzB,EAAS,CAAQ,GACpB,EAAgB,EAAQ,CAA+C,EAEjE,KACR,CAGA,IAAM,EAAY,EAClB,GAAI,EAAY,CAAS,EAAG,CAC3B,GAAI,EAAY,GAAK,GAAuB,CAAyB,EAAG,CACvE,IAAM,EAAa,EAGnB,OAFA,EAAW,CAAU,EACrB,GAAqB,EAAY,OAAO,CAAS,CAAC,EAC3C,IACR,CACA,OAAO,GAAsB,EAAO,CAAS,CAC9C,CAGA,OAFI,EAAO,CAAS,EAAU,GAC9B,EAAgB,EAAQ,CAAgD,EACjE,KACR,CAiBA,SAAS,GAAa,EAAe,EAAoC,CACxE,GAAI,GAAa,CAAC,EAAY,GAAK,CAAC,EAAc,EACjD,OAAO,EAER,IAAM,EAAW,GAAuB,EACxC,GAAI,CAAC,EACJ,MAAU,MAAM,4DAA4D,EAE7E,IAAM,EAAU,EAAc,SAAS,EAAM,EAAE,EAG/C,OAFI,GAAS,EAAS,YAAY,CAAO,EACrC,GAAU,EAAS,YAAY,CAAQ,EACpC,CACR,CAEA,SAAS,GACR,EACA,EACA,EACA,EACc,CACd,OAAO,GAAa,EAAO,GAAuB,EAAU,EAAc,CAAQ,CAAC,CACpF,CAEA,SAAS,GAAsB,EAAe,EAA+B,CAC5E,OAAO,GAAa,EAAO,EAAe,OAAO,CAAK,CAAC,CAAC,CACzD,CCtMA,MAAa,GAAc,OAAO,mBAAmB,EACxC,GAAe,OAAO,oBAAoB,EACvD,IAAI,GAA2B,EAY/B,MAAM,GAA0C,CAAC,EACjD,IAAI,EAAwB,EAE5B,SAAgB,IAAyC,CAIvD,OAHI,GAAyB,GAAqB,QAChD,GAAqB,SAAW,IAAI,EAE/B,GAAqB,IAC9B,CAOA,SAAgB,GACd,EACA,EACA,EACM,CACN,EAA2B,IAAe,EAC1C,EAA2B,IAAgB,CAC7C,CAGA,SAAgB,EAAe,EAA6C,CAC1E,OAAO,OAAO,GAAO,WAAc,EAAqB,IAAgB,IAAA,EAC1E,CAGA,SAAgB,EAAc,EAAiC,CAC7D,OAAO,OAAO,GAAO,WAAc,EAAqB,IAAe,IAAA,EACzE,CAEA,SAAgB,IAAqC,CACnD,OAAO,GAA2B,CACpC,CAOA,SAAgB,GAAoC,EAAuC,EAAa,EAAkB,CACxH,KACA,GAAI,CACF,OAAO,EAAG,EAAM,CAAK,CACvB,QAAU,CACR,IACF,CACF,CAEA,SAAgB,IAAmC,CACjD,OAAO,CACT,CAEA,SAAgB,GAA6B,EAAoB,CAC/D,KAAO,EAAwB,GAAY,CACzC,IAAM,EAAU,GAAqB,EAAE,GACvC,EAAQ,IAAe,IAAA,GACvB,EAAQ,IAAgB,IAAA,EAC1B,CACF,CCnEA,SAAgB,EACd,EACA,EACA,EAAa,EACP,CACN,GAAI,CAAC,GAAa,EAAU,SAAW,EAAG,OAE1C,IAAI,EAAa,EACX,EAAa,EAEnB,IAAK,IAAI,EAAI,EAAG,EAAI,EAAU,OAAQ,GAAK,EAAG,CAC5C,IAAM,EAAM,EAAU,GAEtB,GAAI,GAAO,KAAM,SAEjB,IAAM,EAAW,EAAkB,EAAS,EAAK,CAAU,EACtD,IAGD,EAAS,aAAe,GAC1B,EAAW,YAAY,CAAQ,EAEjC,GAAc,EAChB,CACF,CAKA,SAAgB,GACd,EACA,EAC2B,CAC3B,IAAM,EAAK,GAAc,CAAO,EAChC,GAAI,CAAC,EACH,MAAU,MAAM,6BAA6B,GAAS,EAGxD,OADA,EAAe,EAAI,EAAW,CAAC,EACxB,CACT,CAKA,SAAgB,GACd,EACA,EACgC,CAChC,IAAM,EAAK,GAAgB,GAAe,CAAO,EACjD,GAAI,CAAC,EACH,MAAU,MAAM,iCAAiC,GAAS,EAG5D,OADA,EAAe,EAAkD,EAA0D,CAAC,EACrH,CACT,CAMA,SAAS,GACP,EACA,EAC0C,CAC1C,GAAI,GAA0B,EAAG,CAC/B,IAAM,EAAU,GAA2B,EAE3C,OADA,GAAe,EAAS,EAAS,CAAS,EACnC,CACT,CAEA,IAAM,EAAU,SAAS,EAAqC,EAAQ,EAA8B,CAClG,IAAM,EAAa,EACb,EAAU,EAAa,GAAa,EAAY,CAAO,EAAwC,KAC/F,EAAK,GAAW,GAAc,CAAO,EAC3C,GAAI,CAAC,EACH,MAAU,MAAM,6BAA6B,GAAS,EAExD,IAAM,EAAS,EACT,EAAoB,EAAU,EAAO,UAAY,KAKvD,OAJA,EAAe,EAAI,EAAoD,CAAK,EACxE,GACF,EAAyB,EAAQ,CAAiB,EAE7C,CACT,EAIA,OADA,GAAe,EAAS,EAAS,CAAS,EACnC,CACT,CAKA,SAAS,GACP,EACA,EACqC,CACrC,GAAI,GAA0B,EAAG,CAC/B,IAAM,EAAU,GAA2B,EAE3C,OADA,GAAe,EAAS,EAAS,CAAS,EACnC,CACT,CAEA,OAAO,SAAS,EAAU,EAAQ,EAAmC,CACnE,IAAM,EAAa,EACb,EAAU,EAAa,GAAa,EAAY,CAAO,EAA8B,KACrF,EAAK,GAAW,GAAA,6BAA+B,CAAO,EAC5D,GAAI,CAAC,EACH,MAAU,MAAM,iCAAiC,GAAS,EAE5D,IAAM,EAAS,EACT,EAAoB,EAAU,EAAO,UAAY,KAKvD,OAJA,EAAe,EAAkD,EAA0D,CAAK,EAC5H,GACF,EAAyB,EAAQ,CAAiB,EAE7C,CACT,CACF,CAKA,SAAgB,GACd,EACkC,CAClC,OAAQ,GAAG,IAAS,GAAyB,EAAS,CAAI,CAC5D,CAKA,SAAgB,GACd,EACqC,CACrC,OAAQ,GAAG,IAAS,GAAwB,EAAS,CAAI,CAC3D,CCtJA,MAAa,GAAY,gnBAczB,EAEa,GAAW,+lBAWxB,EAEa,GAAoB,CAC/B,OAAQ,OAAQ,KAAM,MAAO,QAAS,KAAM,MAAO,QAAS,OAAQ,OACpE,SAAU,QAAS,KACrB,EASA,SAAS,GAAoB,EAAiC,EAAa,EAAY,EAAuC,CAC5H,OAAO,eAAe,EAAQ,EAAK,CACjC,aAAc,GACd,WAAY,GACZ,KAAe,CACb,IAAM,EAAQ,EAAO,CAAO,EAE5B,OADA,OAAO,eAAe,EAAQ,EAAK,CAAE,QAAO,aAAc,GAAM,WAAY,GAAM,SAAU,EAAK,CAAC,EAC3F,CACT,EAKA,IAAI,EAAsB,CACxB,OAAO,eAAe,EAAQ,EAAK,CAAE,QAAO,aAAc,GAAM,WAAY,GAAM,SAAU,EAAK,CAAC,CACpG,CACF,CAAC,CACH,CAEA,SAAS,GAAgB,EAAiC,EAA+B,CAEnF,KAAW,GAAU,OAAO,EAAO,IAAa,aAGpD,GAAiB,EAAQ,EAAS,EAAS,EAAoB,EAG3D,IAAY,OACd,GAAiB,EAAQ,OAAQ,EAAS,EAAoB,EAElE,CAEA,SAAS,GAAe,EAAiC,EAA2C,CAElG,IAAM,EAAa,GAAG,EAAQ,KAExB,KAAc,GAClB,GAAiB,EAAQ,EAAY,EAAS,EAAmB,CAErE,CAEA,SAAgB,GAA0B,EAAkC,WAAkB,CAC5F,IAAM,EAAS,0BACV,MAAmC,GAGxC,KAAK,IAAI,EAAI,EAAG,EAAI,GAAS,OAAQ,IACnC,GAAe,EAAQ,GAAS,EAAE,EAIpC,IAAK,IAAI,EAAI,EAAG,EAAI,GAAU,OAAQ,IACpC,GAAgB,EAAQ,GAAU,EAAE,EAGtC,EAAoC,GAAU,EARV,CAStC,CC1FA,SAAgB,EACd,EACA,EACA,EACkC,CAClC,GAAI,EAAW,CAAM,EAAG,CACtB,IAAM,EAAW,EAAyE,EAAM,CAAK,EAIrG,OAHI,GAAW,EAAU,CAAO,EACvB,EAEF,IACT,CAMA,OAJI,GAAU,EAAU,CAAM,EACrB,EAGF,IACT,CC2DA,SAAgB,GAAe,EAAa,EAA+C,CACzF,IAAM,EAAwB,CAAC,EAC3B,EAAmB,EAEvB,IAAK,IAAI,EAAI,EAAG,EAAI,EAAK,OAAQ,IAAK,CACpC,IAAM,EAAM,EAAK,GACjB,GAAI,GAAO,KAAM,CACf,EAAM,KAAK,CAAE,KAAA,CAAgB,CAAC,EAC9B,QACF,CAEA,IAAM,EAAI,OAAO,EAEjB,GAAI,IAAM,WAAY,CACpB,IAAM,EAAY,EAAe,CAAG,EACpC,GAAI,IAAc,IAAA,GAAW,CAC3B,IAAM,EAAW,EAAc,CAAG,EAClC,GAAI,CAAC,EAAU,OAAO,KACtB,IAAM,EAAQ,GAAe,EAAU,CAAS,EAChD,GAAI,CAAC,EAAO,OAAO,KACnB,EAAM,KAAK,CAAE,KAAA,EAAkB,OAAM,CAAC,EACtC,QACF,CACA,GAAK,EAAsB,SAAW,EAAG,CAGvC,IAAI,EACJ,GAAI,CACF,EAAK,EAAsB,EAC3B,EAAmB,IAAI,EAAsB,CAAE,MAAO,EAAG,MAAO,EAAM,CAAC,CACzE,MAAQ,CACN,OAAO,IACT,CACA,GAAI,GAAK,MAAS,OAAO,GAAM,UAAY,OAAO,GAAM,WAAa,CACnE,EAAM,KAAK,CAAE,KAAA,CAAyB,CAAC,EACvC,QACF,CACA,OAAO,IACT,CAEA,OAAO,IACT,CAEA,GAAI,IAAM,SAAU,CAClB,GAAI,EAAO,CAAG,EAAG,OAAO,KACxB,IAAM,EAAQ,EACR,EAAO,OAAO,KAAK,CAAK,EACxB,EAAoB,CAAC,EAC3B,IAAK,IAAI,EAAI,EAAG,EAAI,EAAK,OAAQ,IAAK,CACpC,IAAM,EAAM,EAAK,GACX,EAAI,EAAM,GAChB,GAAI,GAAK,KAAM,CACb,EAAM,KAAK,CAAE,MAAK,KAAA,EAAiB,KAAM,EAAM,CAAC,EAChD,QACF,CACA,GAAI,IAAQ,QAAS,OAAO,KAC5B,IAAM,EAAK,OAAO,EAClB,GAAI,IAAO,WAAY,CACrB,IAAM,EAAgB,GAAyB,CAAG,EAClD,GAAI,EAAe,CACjB,EAAM,KAAK,CAAE,MAAK,KAAA,EAAkB,KAAM,GAAO,MAAO,CAAc,CAAC,EACvE,QACF,CACA,GAAI,IAAQ,aAAgB,EAAoB,SAAW,EAAG,CAC5D,GAAI,IAAoB,OAAO,KAC/B,EAAM,KAAK,CAAE,MAAK,KAAA,EAA+B,KAAM,EAAM,CAAC,EAC9D,QACF,CAGA,OAAO,IACT,CAEA,GADI,IAAO,UACP,IAAQ,aAAe,IAAoB,OAAO,KACtD,EAAM,KAAK,CAAE,MAAK,KAAA,EAAmB,KAAM,GAAO,MAAO,CAAE,CAAC,CAC9D,CACA,EAAM,KAAK,CAAE,KAAA,EAAkB,KAAM,CAAM,CAAC,EAC5C,QACF,CAGA,EAAM,KAAK,CAAE,KAAA,CAAgB,CAAC,CAChC,CAEA,MAAO,CAAE,MAAK,OAAM,CACtB,CAOA,SAAgB,GAAgB,EAAoB,EAAyB,CAC3E,IAAM,EAAQ,EAAK,MACf,EAAqB,EAAS,WAClC,IAAK,IAAI,EAAI,EAAG,EAAI,EAAM,OAAQ,IAAK,CACrC,IAAM,EAAO,EAAM,GACnB,OAAQ,EAAK,KAAb,CACE,IAAA,GAAiB,CACf,IAAM,EAAQ,EAAK,KACnB,IAAK,IAAI,EAAI,EAAG,EAAI,EAAM,OAAQ,IAAK,CACrC,IAAM,EAAO,EAAM,GACf,EAAK,OAAA,EACP,EAAK,KAAO,EAAK,OAAO,EACf,EAAK,OAAA,IACd,EAA0B,UAAY,GAE1C,CACA,KACF,CACA,IAAA,GACA,IAAA,GACE,IAAiB,EAAM,YACvB,MACF,IAAA,GACE,GAAI,CAAC,EAAO,OACZ,GAAgB,EAAK,MAAO,CAAgB,EAC5C,EAAQ,EAAM,WAGlB,CACF,CACF,CAQA,SAAgB,GACd,EACA,EACA,EACA,EACS,CACT,IAAM,EAAQ,EAAK,MACnB,GAAI,EAAK,SAAW,EAAM,OAAQ,MAAO,GACzC,IAAI,EAAqB,EAAG,WAE5B,IAAK,IAAI,EAAI,EAAG,EAAI,EAAM,OAAQ,IAAK,CACrC,IAAM,EAAO,EAAM,GACb,EAAM,EAAK,GAEjB,OAAQ,EAAK,KAAb,CACE,IAAA,GAAiB,CACf,GAAmB,OAAO,GAAQ,WAA9B,EAAwC,MAAO,GACnD,IAAM,EAAQ,EACR,EAAQ,EAAK,KACf,EAAY,EAChB,IAAK,IAAM,KAAM,EAAO,IACxB,GAAI,IAAc,EAAM,OAAQ,MAAO,GACvC,IAAK,IAAI,EAAI,EAAG,EAAI,EAAM,OAAQ,IAAK,CACrC,IAAM,EAAO,EAAM,GACb,EAAI,EAAM,EAAK,KACrB,OAAQ,EAAK,KAAb,CACE,IAAA,GACE,GAAI,GAAK,MAAQ,OAAO,GAAM,UAAY,OAAO,GAAM,WAAY,MAAO,GAC1E,GAAI,IAAM,EAAK,MAAO,MACtB,GAAI,EAAK,KAAM,CACb,IAAM,EAAS,EACX,EAAO,EAAK,OAAS,IAAG,EAAO,EAAK,KAAO,EACjD,KAAO,CACL,IAAM,EAAI,OAAO,CAAC,EACd,EAAG,aAAa,EAAK,GAAG,IAAM,GAAG,EAAG,aAAa,EAAK,IAAK,CAAC,CAClE,CACA,MAEF,IAAA,GAAiB,CACf,GAAI,OAAO,GAAM,WAAY,MAAO,GACpC,IAAM,EAAgB,EAAK,MACvB,IAAkB,UACpB,EAA2C,QAAU,EAErD,GAAkB,EAAmB,EAAe,CAAkB,EAExE,KACF,CACA,IAAA,GAA8B,CAC5B,GAAI,OAAO,GAAM,YAAe,EAAoB,SAAW,EAAG,MAAO,GAIzE,IAAM,EAAK,EACP,EACJ,GAAI,CACF,EAAW,EAAG,CAChB,MAAQ,CACN,MAAO,EACT,CACA,IAAM,EAAI,EAAW,OAAO,CAAQ,EAAI,GACpC,IAAG,EAAoB,UAAY,GACvC,EAAO,KAAK,CAAE,KAAA,EAAsB,KAAM,EAAmB,KAAI,KAAM,CAAE,CAAC,EAC1E,KACF,CACA,IAAA,GACE,GAAI,GAAK,KAAM,MAAO,EAG1B,CACF,CACA,KACF,CAEA,IAAA,GAEE,GADI,GAAO,MAAQ,OAAO,GAAQ,UAAY,OAAO,GAAQ,YACzD,CAAC,EAAO,MAAO,GACnB,EAAgB,UAAY,OAAO,CAAG,EACtC,EAAQ,EAAM,YACd,MAGF,IAAA,GAAyB,CAGvB,GAFI,OAAO,GAAQ,YAAe,EAAsB,SAAW,GAC/D,EAAe,CAAG,IAAM,IAAA,IACxB,CAAC,EAAO,MAAO,GACnB,IAAI,EACJ,GAAI,CACF,EAAK,EAAsB,CAC7B,MAAQ,CACN,MAAO,EACT,CACA,GAAI,GAAK,OAAS,OAAO,GAAM,UAAY,OAAO,GAAM,YAAa,MAAO,GAC5E,IAAM,EAAI,GAAK,KAAO,GAAK,OAAO,CAAC,EAC7B,EAAW,EACjB,EAAS,UAAY,EACrB,EAAO,KAAK,CAAE,KAAA,EAAiB,KAAM,EAAU,GAAI,EAAsB,KAAM,CAAE,CAAC,EAClF,EAAQ,EAAS,YACjB,KACF,CAEA,IAAA,GAAiB,CACf,IAAM,EAAY,EAAe,CAAG,EAIpC,GAHI,IAAc,IAAA,IACd,EAAc,CAAG,IAAM,EAAK,MAAM,KAClC,CAAC,GACD,CAAC,GAAoB,EAAK,MAAO,EAAW,EAAkB,CAAM,EAAG,MAAO,GAClF,EAAQ,EAAM,YACd,KACF,CAEA,IAAA,GACE,GAAI,GAAO,KAAM,MAAO,EAG5B,CACF,CACA,MAAO,EACT,CAWA,SAAgB,GACd,EACA,EACA,EACA,EACS,CACT,IAAM,EAAQ,EAAK,MACnB,GAAI,EAAK,SAAW,EAAM,OAAQ,MAAO,GACzC,IAAI,EAAqB,EAAG,WAE5B,IAAK,IAAI,EAAI,EAAG,EAAI,EAAM,OAAQ,IAAK,CACrC,IAAM,EAAO,EAAM,GACb,EAAM,EAAK,GAEjB,OAAQ,EAAK,KAAb,CACE,IAAA,GAAiB,CACf,GAAmB,OAAO,GAAQ,WAA9B,EAAwC,MAAO,GACnD,IAAM,EAAQ,EACR,EAAQ,EAAK,KACf,EAAI,EACR,IAAK,IAAM,KAAO,EAAO,CACvB,GAAI,GAAK,EAAM,OAAQ,MAAO,GAC9B,IAAM,EAAO,EAAM,GACnB,GAAI,EAAK,MAAQ,EAAK,MAAO,GAC7B,IACA,IAAM,EAAI,EAAM,GAChB,GAAI,EAAK,OAAA,EAAkC,CACzC,GAAI,OAAO,GAAM,YAAe,EAAoB,SAAW,EAAG,MAAO,GACzE,GAAuB,CAAE,EACzB,EAAO,KAAK,CACV,KAAA,EACA,KAAM,EACN,GAAI,EACJ,KAAO,EAAmB,SAC5B,CAAC,CACH,CACF,CACA,GAAI,IAAM,EAAM,OAAQ,MAAO,GAC/B,KACF,CAEA,IAAA,GACE,GAAI,CAAC,EAAO,MAAO,GACnB,EAAQ,EAAM,YACd,MAEF,IAAA,GAAyB,CAEvB,GADI,OAAO,GAAQ,YAAe,EAAsB,SAAW,GAC/D,CAAC,GAAS,EAAM,WAAa,EAAG,MAAO,GAC3C,IAAM,EAAW,EACjB,GAAwB,CAAQ,EAChC,EAAO,KAAK,CACV,KAAA,EACA,KAAM,EACN,GAAI,EACJ,KAAM,EAAS,WAAa,EAC9B,CAAC,EACD,EAAQ,EAAS,YACjB,KACF,CAEA,IAAA,GAAiB,CACf,IAAM,EAAY,EAAe,CAAG,EAIpC,GAHI,IAAc,IAAA,IACd,EAAc,CAAG,IAAM,EAAK,MAAM,KAClC,CAAC,GACD,CAAC,GAAoB,EAAK,MAAO,EAAW,EAAkB,CAAM,EAAG,MAAO,GAClF,EAAQ,EAAM,YACd,KACF,CAEA,IAAA,GACE,GAAI,GAAO,KAAM,MAAO,EAE5B,CACF,CACA,MAAO,EACT,CAOA,SAAgB,GAAe,EAAyB,CACtD,IAAK,IAAI,EAAI,EAAG,EAAI,EAAO,OAAQ,IAAK,CACtC,IAAM,EAAO,EAAO,GAChB,EACJ,GAAI,CACF,EAAI,EAAK,GAAG,CACd,MAAQ,CACN,QACF,CACA,GAAI,EAAK,OAAA,EAAoB,CAC3B,IAAM,EAAI,GAAK,MAAQ,OAAO,GAAM,UAAY,OAAO,GAAM,WAAa,GAAK,OAAO,CAAC,EACnF,IAAM,EAAK,OACb,EAAM,KAAc,UAAY,EAChC,EAAK,KAAO,EAEhB,KAAO,CACL,IAAM,EAAI,EAAI,OAAO,CAAC,EAAI,GACtB,IAAM,EAAK,OACb,EAAM,KAAqB,UAAY,EACvC,EAAK,KAAO,EAEhB,CACF,CACF,CC/aA,SAAS,GAAe,EAAiB,EAA0B,CACjE,GAAI,IAAM,EAAG,MAAO,GACpB,GAAI,EAAE,SAAW,EAAE,OAAQ,MAAO,GAClC,IAAK,IAAI,EAAI,EAAG,EAAI,EAAE,OAAQ,IAC5B,GAAI,EAAE,KAAO,EAAE,GAAI,MAAO,GAE5B,MAAO,EACT,CAaA,MAAM,kBAAqB,IAAI,IACzB,mBAAsB,IAAI,QAC1B,GAAsB,OAAO,qBAAyB,IACxD,IAAI,qBAAwC,GAAQ,CAAE,EAAmB,OAAO,CAAG,CAAG,CAAC,EACvF,KACJ,IAAI,EAAuB,EAE3B,SAAS,GAAoB,EAAsB,EAAqD,CACtG,IAAM,EAAM,IAAI,QAAQ,CAAW,EACnC,EAAmB,IAAI,CAAG,EAC1B,GAAoB,IAAI,EAAa,CAAO,EAC5C,IAAqB,SAAS,EAAa,CAAG,CAChD,CAEA,SAAS,GAAsB,EAAgD,CAC7E,OAAO,MAAM,QAAQ,CAAK,EAAI,EAAQ,MAAM,KAAK,CAAK,CACxD,CAEA,SAAS,GAA+C,EAAoD,CAC1G,GAAqB,OAAO,GAAU,WAAlC,EAA4C,MAAO,GACvD,IAAM,EAAW,EAAgC,QACjD,MAAO,CAAC,CAAC,GAAW,OAAO,KAAS,KAAe,aAAmB,IACxE,CAOA,SAAS,GACP,EACA,EACA,EACkC,CAClC,IAAM,EAAW,EAAQ,WAAW,EAAM,CAAK,EAK/C,OAJI,GAAwB,CAAQ,GAClC,EAAQ,kBAAoB,OAAO,EAAS,QAAW,WAAa,EAAS,OAAS,KAC/E,EAAS,SAEX,EAA4B,EAAmB,EAAQ,KAAM,CAAK,CAC3E,CAEA,SAAS,GACP,EACA,EACA,EACA,CACA,IAAM,EAAa,GAAiC,EACpD,GAAI,CACF,OAAO,GAAuB,EAAS,EAAM,CAAK,CACpD,QAAU,CACR,GAA6B,CAAU,CACzC,CACF,CAEA,SAAS,GACP,EACA,EACA,EACkC,CAClC,EAAQ,iBAAmB,KAC3B,EAAQ,kBAAoB,KAC5B,IAAM,EAAW,EAAQ,SACnB,EAAiB,GAAa,CAAC,EAAY,GAAK,CAAC,EAAc,EAK/D,EAAS,GAAY,EACvB,GAA0B,EAAQ,WAAY,EAAM,CAAK,EACzD,EAAQ,WAAW,EAAM,CAAK,EAElC,GAAI,GAAwB,CAAM,EAEhC,MADA,GAAQ,kBAAoB,OAAO,EAAO,QAAW,WAAa,EAAO,OAAS,KAC3E,EAAO,QAGhB,GAAI,IAAa,MAAQ,EAAgB,CACvC,IAAM,EAAO,EAAe,CAAM,EAClC,GAAI,IAAS,IAAA,GAAW,CACtB,GAAI,IAAa,IAAA,GAAW,CAC1B,IAAM,EAAM,EAAc,CAAM,EAC1B,EAAO,EAAM,GAAe,EAAK,CAAI,EAAI,KACzC,EAAK,EAA4B,EAAQ,EAAQ,KAAM,CAAK,EAClE,GAAI,GAAQ,EAAI,CACd,IAAM,EAAY,EAAuB,UAAU,EAAI,EACvD,GAAgB,EAAM,CAAQ,EAC9B,IAAM,EAAoB,CAAC,EAC3B,GAAI,GAAoB,EAAM,EAAM,EAA0B,CAAM,EAC9D,EAAO,OAAS,IAAG,EAAQ,iBAAmB,QAIlD,MAFA,GAAQ,SAAW,KACnB,EAAQ,iBAAmB,KACpB,EAET,EAAQ,SAAW,CAAE,OAAM,UAAS,CACtC,KACE,GAAQ,SAAW,KAErB,OAAO,CACT,CACA,IAAM,EAAQ,EAAS,SAAS,UAAU,EAAI,EACxC,EAAoB,CAAC,EAS3B,OARI,EAAc,CAAM,IAAM,EAAS,KAAK,KAAO,GAAoB,EAAS,KAAM,EAAM,EAAO,CAAM,GACnG,EAAO,OAAS,IAAG,EAAQ,iBAAmB,GAC3C,IAKT,EAAQ,SAAW,KACZ,GAAmB,EAAS,EAAM,CAAK,EAChD,CAAO,GAAI,IAAa,IAAA,GACtB,EAAQ,SAAW,UAGnB,MADA,GAAQ,SAAW,KACZ,GAAmB,EAAS,EAAM,CAAK,CAElD,CAEA,OAAO,EAA4B,EAAiB,EAAQ,KAAM,CAAK,CACzE,CAQA,SAAS,EAAqD,EAA+C,CAC3G,GAAgB,EAAO,OAA0B,CACnD,CA+BA,SAAS,GACP,EACA,EACA,EACA,EACS,CACT,GAAI,EAAY,aAAe,GAAU,EAAU,aAAe,EAAQ,MAAO,GAQjF,GAAI,GAAgC,EAClC,IAAK,IAAI,EAAI,EAAG,EAAI,EAAQ,OAAQ,IAAK,CACvC,IAAM,EAAO,EAAQ,EAAE,CAAC,QACpB,GAAM,GAA2B,CAAI,CAC3C,CAOF,GAAI,GAAa,EAAO,aAAe,GAAe,EAAO,YAAc,EAIzE,MAHA,GAAiB,YAAc,GAC/B,EAAO,YAAY,CAAW,EAC9B,EAAO,YAAY,CAAS,EACrB,GAGT,IAAK,IAAI,EAAI,EAAG,EAAI,EAAQ,OAAQ,IAAK,CACvC,IAAM,EAAO,EAAQ,EAAE,CAAC,QAGpB,GAAQ,EAAK,aAAe,GAAQ,EAAO,YAAY,CAAI,CACjE,CACA,MAAO,EACT,CAUA,SAAS,GAA6B,EAAyB,CAC7D,IAAM,EAAI,EAAI,OACd,GAAI,IAAM,EAAG,MAAO,CAAC,EACrB,IAAM,EAAkB,MAAc,CAAC,EAGjC,EAAkB,CAAC,EACzB,IAAK,IAAI,EAAI,EAAG,EAAI,EAAG,IAAK,CAC1B,IAAM,EAAI,EAAI,GACV,EAAK,EACL,EAAK,EAAM,OACf,KAAO,EAAK,GAAI,CACd,IAAM,EAAO,EAAK,GAAO,EACrB,EAAI,EAAM,IAAQ,EAAG,EAAK,EAAM,EAC/B,EAAK,CACZ,CACA,EAAY,GAAK,EAAK,EAAI,EAAM,EAAK,GAAK,GACtC,IAAO,EAAM,OAAQ,EAAM,KAAK,CAAC,EAChC,EAAM,GAAM,CACnB,CACA,IAAI,EAAI,EAAM,OACV,EAAM,EAAM,EAAI,GACd,EAAa,MAAc,CAAC,EAClC,KAAO,EAAI,GACT,EAAO,EAAE,GAAK,EACd,EAAM,EAAY,GAEpB,OAAO,CACT,CAQA,SAAS,GACP,EACA,EACA,EACA,EACA,EACA,EACA,EACM,CACN,IAAM,EAAW,GAAuB,EACpC,EAAW,EACf,IAAK,IAAI,EAAI,EAAY,EAAI,EAAmB,IAAK,CACnD,IAAM,EAAO,EAAM,GACb,EAAU,GAAW,EAAS,EAAM,CAAC,EAC3C,GAAI,CAAC,EAAS,SACd,IAAM,EAAM,EAAQ,iBACpB,EAAc,KAAK,CACjB,OACA,UACA,MACA,QAAS,EAAQ,kBACjB,aAAc,EAAM,EAAQ,kBAAoB,IAAA,EAClD,CAAC,EACD,EAAQ,iBAAmB,KAC3B,EAAQ,kBAAoB,KAC5B,IAAM,EAAO,EACT,GACF,EAAS,YAAY,CAAI,EACzB,KAEA,EAAO,aAAa,EAAM,CAAM,CAEpC,CACI,GAAY,EAAW,GAAG,EAAO,aAAa,EAAU,CAAM,CACpE,CAEA,SAAgB,GACd,EACM,CACN,GAAM,CAAE,cAAa,aAAc,EAC7B,EAAU,EAAY,YAAe,EAAQ,KAG7C,EAAQ,GAAe,EAAQ,cAAc,CAAC,EAEpD,GAAI,GAAY,EAAQ,gBAAiB,CAAK,EAAG,OAEjD,IAAM,EAAa,EAAQ,QACrB,EAAS,EAAW,OACpB,EAAS,EAAM,OAIrB,GAAI,IAAW,EAAG,CAChB,GAAI,EAAS,GAAK,CAAC,GAAiB,EAAY,EAAQ,EAAa,CAAS,EAC5E,IAAK,IAAI,EAAI,EAAG,EAAI,EAAQ,IAAK,EAAa,EAAW,EAAE,EAE7D,EAAQ,QAAU,CAAC,EACnB,EAAQ,gBAAkB,CAAC,EAC3B,EAAQ,oBAAsB,IAAA,GAC9B,MACF,CAKA,IAAI,EAAS,EACP,EAAU,KAAK,IAAI,EAAQ,CAAM,EACvC,KAAO,EAAS,GAAW,EAAW,EAAO,CAAC,OAAS,EAAM,IAAS,IACtE,IAAI,EAAS,EACP,EAAY,EAAU,EAC5B,KAAO,EAAS,GAAa,EAAW,EAAS,EAAI,EAAO,CAAC,OAAS,EAAM,EAAS,EAAI,IACvF,IAGF,IAAM,EAAW,EACX,EAAS,EAAS,EAClB,EAAW,EACX,EAAS,EAAS,EAKxB,GAAI,IAAa,EAAQ,CACvB,IAAM,EAAe,EAAS,EAAU,EAAW,EAAO,CAAC,QAA8B,EACzF,GAAI,IAAW,EACb,GAAe,EAAS,EAAQ,EAAO,EAAU,EAAQ,EAAQ,CAAU,EAC3E,EAAQ,oBAAsB,IAAW,EAAI,EAAQ,kBAAoB,IAAA,OACpE,CACL,IAAM,EAA2C,CAAC,EAClD,GAAe,EAAS,EAAQ,EAAO,EAAU,EAAQ,EAAQ,CAAK,EACtE,EAAQ,QAAU,EAAW,MAAM,EAAG,CAAQ,CAAC,CAAC,OAAO,EAAO,EAAW,MAAM,CAAQ,CAAC,EACxF,EAAQ,oBAAsB,IAAA,EAChC,CACA,EAAQ,gBAAkB,EAAM,MAAM,EACtC,MACF,CAIA,GAAI,IAAa,EAAQ,CACvB,IAAK,IAAI,EAAI,EAAU,EAAI,EAAQ,IAAK,EAAa,EAAW,EAAE,EAClE,EAAW,OAAO,EAAU,EAAS,CAAQ,EAC7C,EAAQ,oBAAsB,IAAA,GAC9B,EAAQ,gBAAkB,EAAM,MAAM,EACtC,MACF,CAGA,IAAM,EAAY,EAAS,EACrB,EAAY,EAAS,EAIrB,EAAc,MAAc,CAAS,CAAC,CAAC,KAAK,EAAE,EAE9C,EAAU,IAAI,WAAW,CAAS,EACpC,EAAc,EAIZ,GAAS,KAAK,IAAI,EAAQ,CAAM,EACtC,IAAK,IAAI,EAAI,EAAQ,EAAI,GAAQ,IAC3B,EAAW,EAAE,CAAC,OAAS,EAAM,KAC/B,EAAQ,EAAI,GAAY,EACxB,EAAQ,EAAI,GAAY,EACxB,KAOJ,IAAM,kBAAU,IAAI,IACpB,IAAK,IAAI,EAAI,EAAS,EAAG,GAAK,EAAU,IAAK,CAC3C,GAAI,EAAQ,EAAI,GAAW,SAC3B,IAAM,EAAO,EAAW,EAAE,CAAC,KACrB,EAAQ,EAAQ,IAAI,CAAI,EAC1B,IAAU,IAAA,GAAW,EAAQ,IAAI,EAAM,CAAC,EACnC,OAAO,GAAU,SAAU,EAAQ,IAAI,EAAM,CAAC,EAAO,CAAC,CAAC,EAC3D,EAAM,KAAK,CAAC,CACnB,CAEA,IAAK,IAAI,EAAI,EAAG,EAAI,EAAW,IAAK,CAClC,GAAI,EAAQ,KAAO,GAAI,SACvB,IAAM,EAAQ,EAAQ,IAAI,EAAM,EAAW,EAAE,EAC7C,GAAI,IAAU,IAAA,GAAW,SACzB,IAAI,EACA,OAAO,GAAU,UACnB,EAAW,EACX,EAAQ,OAAO,EAAM,EAAW,EAAE,IAElC,EAAW,EAAM,IAAI,EACjB,EAAM,SAAW,GAAG,EAAQ,OAAO,EAAM,EAAW,EAAE,GAE5D,EAAQ,GAAK,EACb,EAAQ,EAAW,GAAY,EAC/B,GACF,CAIA,GAAI,IAAgB,GAAK,IAAa,GAAK,IAAW,EAAQ,CAC5D,GAAI,CAAC,GAAiB,EAAY,EAAQ,EAAa,CAAS,EAC9D,IAAK,IAAI,EAAI,EAAG,EAAI,EAAQ,IAAK,EAAa,EAAW,EAAE,EAE7D,IAAM,EAA2C,CAAC,EAClD,GAAe,EAAS,EAAQ,EAAO,EAAG,EAAQ,EAAW,CAAK,EAClE,EAAQ,QAAU,EAClB,EAAQ,oBAAsB,EAAQ,kBACtC,EAAQ,gBAAkB,EAAM,MAAM,EACtC,MACF,CAKA,IAAK,IAAI,EAAI,EAAU,EAAI,EAAQ,IAC5B,EAAQ,EAAI,IAAW,EAAa,EAAW,EAAE,EAKxD,IAAI,EAA4B,KAChC,GAAI,EAAc,EAAG,CACnB,IAAM,EAA+B,CAAC,EAChC,EAA8B,CAAC,EACrC,IAAK,IAAI,EAAI,EAAG,EAAI,EAAW,IACzB,EAAQ,KAAO,KACjB,EAAmB,KAAK,EAAQ,EAAE,EAClC,EAAkB,KAAK,CAAC,GAG5B,EAAS,IAAI,WAAW,CAAS,EACjC,IAAM,EAAM,GAA6B,CAAkB,EAC3D,IAAK,IAAI,EAAI,EAAG,EAAI,EAAI,OAAQ,IAAK,EAAO,EAAkB,EAAI,KAAO,CAC3E,CAKA,IAAM,EAAoB,MAA8C,CAAS,EAC7E,EAAY,EACZ,EAAe,EAAS,EAAU,EAAW,EAAO,CAAC,QAA8B,EACnF,EAAoC,KAExC,IAAK,IAAI,EAAI,EAAY,EAAG,GAAK,EAAG,IAAK,CACvC,IAAM,EAAM,EAAQ,GAEpB,GAAI,IAAQ,GAAI,CAGd,IAAM,EAAO,EAAM,EAAW,GACxB,EAAU,GAAW,EAAS,EAAM,EAAW,CAAC,EACtD,GAAI,CAAC,EAAS,CACZ,EAAc,GAAK,KACnB,IACA,QACF,CACA,IAAM,EAAM,EAAQ,iBACpB,EAAc,GAAK,CACjB,OACA,UACA,MACA,QAAS,EAAQ,kBACjB,aAAc,EAAM,EAAQ,kBAAoB,IAAA,EAClD,EACA,EAAQ,iBAAmB,KAC3B,EAAQ,kBAAoB,KAC5B,IAAM,EAAO,EACb,AAAe,IAAW,GAAuB,EAC7C,EACF,EAAS,aAAa,EAAM,EAAS,UAAU,GAI/C,EAAO,aAAa,EAAM,CAAM,EAChC,EAAS,GAEX,QACF,CAIA,IAAM,EAAS,EAAW,GAC1B,EAAc,GAAK,EACnB,IAAM,EAAO,EAAO,QACpB,GAAI,GAAY,EAAS,WAAY,CACnC,IAAM,EAAe,EAAS,WAC9B,EAAO,aAAa,EAAU,CAAM,EACpC,EAAS,EACT,EAAW,IACb,EACI,CAAC,GAAU,CAAC,EAAO,KACrB,EAAO,aAAa,EAAM,CAAM,EAElC,EAAS,CACX,CACI,GAAY,EAAS,YAAY,EAAO,aAAa,EAAU,CAAM,EAGzE,IAAM,EAAa,MACjB,GAAY,EAAY,IAAc,EAAS,EACjD,EACI,EAAI,EACR,IAAK,IAAI,EAAI,EAAG,EAAI,EAAU,IAAK,EAAO,KAAO,EAAW,GAC5D,IAAK,IAAI,EAAI,EAAG,EAAI,EAAW,IAAK,CAClC,IAAM,EAAS,EAAc,GACzB,IAAQ,EAAO,KAAO,EAC5B,CACA,IAAK,IAAI,EAAI,EAAQ,EAAI,EAAQ,IAAK,EAAO,KAAO,EAAW,GAC/D,EAAQ,QAAU,EAClB,EAAQ,oBAAsB,IAAA,GAC9B,EAAQ,gBAAkB,EAAM,MAAM,CACxC,CAEA,SAAgB,GACd,EACA,EACA,EACA,EAC8B,CAK9B,OAJI,EAAY,EACP,GAAmB,EAAe,EAAY,EAAM,CAAK,EAG3D,GAAwB,EAAe,EAAY,EAAM,CAAK,CACvE,CAEA,SAAS,GACP,EACA,EACA,EACA,EAC8B,CAC9B,GAAM,CAAE,MAAO,EAAa,IAAK,GAAc,GAAiB,OAAQ,CAAK,EAEvE,EAAwC,CAC5C,gBACA,aACA,cACA,YACA,QAAS,CAAC,EACV,OACA,gBAAiB,CAAC,CACpB,EAEM,EAAa,EAWnB,OAVA,EAAW,YAAY,CAAW,EAClC,EAAW,YAAY,CAAS,EAEhC,GAAK,CAAO,EAER,GAEF,GAAoB,EAAa,CAA+C,EAG3E,CACT,CAEA,SAAS,GACP,EACA,EACA,EACA,EAC8B,CAC9B,IAAM,EAAa,EAInB,EAAmB,CAAU,EAC7B,IAAM,EAAY,EAAU,CAAU,EACtC,GAAI,CAAC,GAAa,EAAU,WAAa,GACrC,CAAE,EAAsB,aAAa,WAAW,aAAa,EAC/D,OAAO,GAAwB,EAAe,EAAU,EAAM,CAAK,EAIrE,IAAM,EAAc,EAAW,CAAU,EAIrC,EAAQ,EACR,EAAwB,EAAU,CAAU,EAChD,KAAO,GAAU,CACf,GAAI,EAAS,WAAa,EAAG,CAC3B,IAAM,EAAQ,EAAqB,aAAe,GAClD,GAAI,EAAK,WAAW,aAAa,EAC/B,SACK,GAAI,IAAS,WAAY,CAC9B,GAAI,IAAU,EAAG,MACjB,GACF,CACF,CACA,EAAW,EAAS,WACtB,CACA,IAAI,EAAY,EAChB,GAAI,CAAC,EAAW,CAGd,IAAM,EAAU,EAAc,UAAU,EACpC,IACF,EAAW,aAAa,EAAS,EAAY,WAAW,EACxD,EAAY,EAEhB,CACA,GAAI,CAAC,EACH,OAAO,GAAwB,EAAe,EAAU,EAAM,CAAK,EAIrE,IAAM,EAAe,GAAe,EAAc,CAAC,EAC7C,EAA6C,CAAC,EAEpD,IAAK,IAAI,EAAI,EAAG,EAAI,EAAa,OAAQ,IAAK,CAC5C,IAAM,EAAS,EAAS,EAAa,GAAI,CAAC,EACpC,EAAW,GAAwB,CAAM,EAAI,EAAS,KACtD,EAAU,EACZ,EAAS,QACT,EAA4B,EAAiB,EAAM,CAAC,EACpD,GACF,EAAQ,KAAK,CACX,KAAM,EAAa,GACnB,UACA,QAAS,GAAY,OAAO,EAAS,QAAW,WAAa,EAAS,OAAS,IAAA,EACjF,CAAC,CAEL,CAKA,IAAI,EAAW,EAAU,CAAU,EACnC,KAAO,GAAY,IAAa,GAAW,CACzC,IAAM,EAAoB,EAAS,YACnC,GAAgB,CAAQ,EACxB,EAAW,CACb,CAIA,IAAI,EAAe,EACnB,IAAK,IAAI,EAAI,EAAQ,OAAS,EAAG,GAAK,EAAG,IAAK,CAC5C,IAAM,EAAa,EAAQ,EAAE,CAAC,SAC1B,EAAW,aAAe,GAAc,EAAW,cAAgB,IACrE,EAAW,aAAa,EAAY,CAAM,EAE5C,EAAS,CACX,CAGA,EAAU,EAAY,EAAU,WAAW,EAE3C,IAAM,EAAwC,CAC5C,gBACA,WAAY,EACZ,cACA,YACA,UACA,OACA,gBAAiB,EAAa,MAAM,CACtC,EAMA,OAJI,GACF,GAAoB,EAAa,CAA+C,EAG3E,CACT,CAQA,SAAS,GAAe,EAAqD,CAC3E,EAAQ,SAAW,KACnB,EAAQ,iBAAmB,KAC3B,EAAQ,kBAAoB,KAC5B,IAAK,IAAI,EAAI,EAAG,EAAI,EAAQ,QAAQ,OAAQ,IAAK,CAC/C,IAAM,EAAS,EAAQ,QAAQ,GAC/B,EAAO,QAAU,KACjB,EAAO,KAAO,KACd,EAAO,IAAM,KACb,EAAO,QAAU,KACjB,OAAQ,EAAqC,YAC/C,CACA,EAAQ,QAAU,CAAC,EACnB,EAAQ,gBAAkB,CAAC,EAC3B,EAAQ,oBAAsB,IAAA,EAChC,CAEA,SAAgB,GAAmB,EAA2B,CAC5D,IAAM,EAA+B,CAAC,EACtC,IAEA,IAAK,IAAM,KAAO,EAAoB,CACpC,IAAM,EAAc,EAAI,MAAM,EAG9B,GAAI,CAAC,EAAa,CAChB,EAAS,KAAK,CAAG,EACjB,QACF,CAEA,IAAM,EAAU,GAAoB,IAAI,CAAW,EACnD,GAAI,CAAC,EAAS,CACZ,EAAS,KAAK,CAAG,EACjB,QACF,CAGA,GAAI,CAAC,EAAgB,CAAW,GAAK,CAAC,EAAgB,EAAQ,SAAS,EAAG,CACxE,GAAe,CAAO,EACtB,GAAoB,OAAO,CAAW,EACtC,EAAS,KAAK,CAAG,EACjB,QACF,CAGA,GAAI,GAAS,CAAC,EAAM,SAAS,CAAW,EAAG,SAE3C,EAAQ,kBAAoB,EAC5B,GAAI,CACF,GAAK,CAAO,CACd,QAAU,CACR,EAAQ,kBAAoB,IAAA,EAC9B,CAKA,GAAI,EAAQ,sBAAwB,EAAsB,SAC1D,IAAM,EAAU,EAAQ,QACxB,IAAK,IAAI,EAAI,EAAG,EAAI,EAAQ,OAAQ,IAAK,CACvC,GAAI,EAAQ,EAAE,CAAC,eAAiB,EAAsB,SACtD,IAAM,EAAU,EAAQ,EAAE,CAAC,QACvB,GAAS,EAAQ,EACrB,IAAM,EAAM,EAAQ,EAAE,CAAC,IACnB,GAAK,GAAe,CAAG,CAC7B,CACF,CAGA,IAAK,IAAM,KAAO,EAChB,EAAmB,OAAO,CAAG,CAEjC,CC1xBA,SAAgB,GACd,EACA,EACwB,CACxB,OAAO,SAAyC,EAAgC,EAAwB,CAItG,OAHgB,GAAkB,EAAe,EAAQ,EAA8C,CAG1F,CAAC,CAAC,WACjB,CACF,CCfA,SAAgB,GACd,EACA,EACS,CACT,GAAI,CACF,OAAO,EAAU,CACnB,OAAS,EAAO,CACd,GAAI,EAEF,OADA,EAAQ,CAAK,EACN,GAET,MAAM,CACR,CACF,CAEA,SAAgB,GACd,EACA,EACS,CACT,OAAO,OAAO,GAAU,WAAa,GAAa,EAAO,CAAO,EAAI,EAAQ,CAC9E,CCsBA,MAAM,mBAAqB,IAAI,IACzB,mBAAsB,IAAI,QAC1B,GAAsB,OAAO,qBAAyB,IACxD,IAAI,qBAAwC,GAAQ,CAAE,GAAmB,OAAO,CAAG,CAAG,CAAC,EACvF,KAMJ,SAAgB,GACd,EACA,EACe,CACf,IAAK,IAAI,EAAI,EAAG,EAAI,EAAO,OAAQ,IACjC,GAAI,GAAiB,EAAO,EAAE,CAAC,SAAS,EACtC,OAAO,EAGX,OAAO,EAAY,OAAS,EAAI,GAAK,IACvC,CAMA,SAAgB,GACd,EACM,CACN,GAAM,CAAE,SAAQ,cAAa,OAAM,QAAO,aAAc,EAElD,EAAY,GAAwB,EAAQ,CAAW,EAGzD,IAAc,EAAQ,cAG1B,GAAoB,EAAQ,YAAa,EAAQ,SAAS,EAC1D,EAAQ,YAAc,EAGlB,IAAc,OAMlB,GAFc,GADU,GAAa,EAAI,EAAO,EAAU,CAAC,QAAU,EACnB,EAAM,EAAO,CAE7C,EAAO,CAAS,CACpC,CAOA,SAAgB,GACd,EACM,CACN,IAAM,EAAM,IAAI,QAAQ,EAAQ,WAAW,EAC3C,GAAmB,IAAI,CAAG,EAC1B,GAAoB,IAAI,EAAQ,YAAa,CAAsC,EACnF,IAAqB,SAAS,EAAQ,YAAa,CAAG,CACxD,CAgBA,SAAgB,GAAmB,EAA2B,CAC5D,IAAM,EAA+B,CAAC,EAEtC,IAAK,IAAM,KAAO,GAAoB,CACpC,IAAM,EAAc,EAAI,MAAM,EAG9B,GAAI,IAAgB,IAAA,GAAW,CAC7B,EAAS,KAAK,CAAG,EACjB,QACF,CAEA,IAAM,EAAU,GAAoB,IAAI,CAAW,EACnD,GAAI,CAAC,EAAS,CACZ,EAAS,KAAK,CAAG,EACjB,QACF,CAGA,GAAI,CAAC,EAAgB,CAAW,GAAK,CAAC,EAAgB,EAAQ,SAAS,EAAG,CACxE,GAAoB,OAAO,CAAW,EACtC,EAAS,KAAK,CAAG,EACjB,QACF,CAGI,OAAU,EAAM,SAAS,CAAW,EAExC,GAAI,CACF,EAAQ,OAAO,CACjB,OAAS,EAAO,CAEd,EAAS,oEAAqE,CAAK,EACnF,GAAoB,OAAO,CAAW,EACtC,EAAS,KAAK,CAAG,CACnB,CACF,CAGA,IAAK,IAAM,KAAO,EAChB,GAAmB,OAAO,CAAG,CAEjC,CAMA,SAAS,GACP,EACA,EACA,EACA,EACa,CAYb,OAXK,EAAW,CAAI,EAKhB,EAAoB,CAAI,GAC1B,EAAmB,OAAO,CAAI,EACvB,EAAkB,EAAM,EAAM,CAAK,GAIrC,GAAoB,EAAM,MAAiB,CAChD,IAAM,EAAY,EAAkB,EAAM,EAAM,CAAK,EAErD,OAAO,GAAa,CAAC,EAAU,WAAa,EAAY,IAC1D,CAAC,EAdQ,EAAkB,EAAM,EAAM,CAAK,CAe9C,CAKA,SAAgB,GACd,EACA,EACA,EACA,EACQ,CACR,IAAM,EAAgB,CAAC,EACvB,IAAK,IAAM,KAAQ,EAAO,CACxB,IAAM,EAAO,GAAkB,EAAM,EAAM,EAAO,CAAS,EACvD,GACF,EAAM,KAAK,CAAI,CAEnB,CACA,OAAO,CACT,CCvMA,SAAS,GAAa,EAAe,EAAoC,CACvE,MAAO,cAAc,EAAM,IAAI,IAAgB,KAAO,IAAM,GAC9D,CAMA,SAAS,GAAa,EAAsD,CAC1E,IAAM,EAAQ,eAAe,KAAK,GAAc,EAAE,EAC7C,KACL,OAAO,EAAM,KAAO,IAAM,KAAO,SAAS,EAAM,GAAI,EAAE,CACxD,CAEA,IAAM,GAAN,MAAM,CAAkE,CACtE,OAAwC,CAAC,EACzC,YAA+C,CAAC,EAEhD,YAAY,EAAiC,GAAG,EAAkC,CAChF,KAAK,OAAO,KAAK,CAAE,UAAW,EAAkB,SAAQ,CAAC,CAC3D,CAEA,UACE,EACA,EAC2B,CAC3B,IAAM,EAAI,OAAO,OAAO,EAAgB,SAAS,EAIjD,MAHA,GAAE,OAAS,CAAC,GAAG,KAAK,MAAM,EACtB,GAAiB,EAAE,OAAO,KAAK,CAAe,EAClD,EAAE,YAAc,GAAkB,CAAC,GAAG,KAAK,WAAW,EAC/C,CACT,CAEA,KAAK,EAA0B,GAAG,EAA6D,CAE7F,OADA,KAAK,OAAO,KAAK,CAAE,YAAW,SAAQ,CAAC,EAChC,IACT,CAEA,KAAK,GAAG,EAA6D,CAEnE,MADA,MAAK,YAAc,EACZ,IACT,CAEA,OAAO,EAAiC,EAA4B,CASlE,OARK,WAAW,SAIZ,EAAY,EACP,KAAK,cAAc,EAAM,CAAK,EAGhC,KAAK,YAAY,EAAM,CAAK,EAP1B,IAQX,CAEA,YAAoB,EAAiC,EAA4B,CAC/E,GAAM,CAAE,MAAO,EAAa,IAAK,GAAc,GAAiB,OAAQ,CAAK,EACvE,EAAU,KAAK,yBAAyB,EAAM,EAAO,EAAa,CAAS,EAE3E,EAAS,GAAa,CAAI,EAShC,OARA,EAAO,YAAY,CAAW,EAC9B,EAAO,YAAY,CAAS,EAE5B,GAAkB,CAAO,EAGzB,EAAY,YAAc,GAAa,EAAO,EAAQ,WAAW,EAE1D,CACT,CAEA,cAAsB,EAAiC,EAA4B,CACjF,IAAM,EAAa,EAKnB,EAAmB,CAAU,EAC7B,IAAM,EAAY,EAAU,CAAU,EACtC,GAAI,CAAC,GAAa,EAAU,WAAa,GACrC,CAAE,EAAsB,aAAa,WAAW,aAAa,EAC/D,OAAO,KAAK,YAAY,EAAM,CAAK,EAIrC,IAAM,EAAc,EAAW,CAAU,EAIrC,EAAQ,EACR,EAAwB,EAAU,CAAU,EAChD,KAAO,GAAU,CACf,GAAI,EAAS,WAAa,EAAG,CAC3B,IAAM,EAAQ,EAAqB,aAAe,GAClD,GAAI,EAAK,WAAW,aAAa,EAC/B,SACK,GAAI,IAAS,WAAY,CAC9B,GAAI,IAAU,EAAG,MACjB,GACF,CACF,CACA,EAAW,EAAS,WACtB,CACA,IAAI,EAAY,EACZ,EAAmB,GACvB,GAAI,CAAC,EAAW,CAGd,IAAM,EAAU,EAAc,UAAU,EACxC,GAAI,CAAC,EAAS,OAAO,EACrB,EAAW,aAAa,EAAS,EAAY,WAAW,EACxD,EAAY,EACZ,EAAmB,EACrB,CAGA,IAAM,EAAc,GAAwB,KAAK,OAAQ,KAAK,WAAW,EACnE,EAAe,GAAa,EAAY,WAAW,EAIzD,GAHsB,CAAC,IACpB,IAAiB,IAAA,IAAa,IAAiB,GAI5C,IAAA,IAAgB,KAAM,CACxB,IAAM,EAAkB,GAAe,EAAI,KAAK,OAAO,EAAY,CAAC,QAAU,KAAK,YACnF,IAAK,IAAM,KAAQ,EACjB,EAAkB,EAAM,EAAiD,CAAK,CAElF,OAKA,GADA,GAAoB,EAAa,CAAS,EACtC,IAAgB,KAAM,CACxB,IAAM,EAAkB,GAAe,EAAI,KAAK,OAAO,EAAY,CAAC,QAAU,KAAK,YAC7E,EAAM,EACZ,MAA0B,CAExB,GADc,GAAmB,EAAiB,EAAM,EAAO,CAC7C,EAAO,CAAG,CAC9B,CAAC,CACH,CAQF,OAJA,EAAU,EAAY,EAAU,WAAW,EAE3C,KAAK,yBAAyB,EAAM,EAAO,EAAa,EAAW,CAAW,EAEvE,CACT,CAEA,yBACE,EACA,EACA,EACA,EACA,EAA6B,KACN,CACvB,IAAM,EAAiC,CACrC,cACA,YACA,OACA,QACA,OAAQ,CAAC,GAAG,KAAK,MAAM,EACvB,YAAa,CAAC,GAAG,KAAK,WAAW,EACjC,cACA,OAAQ,UAAW,CAAE,GAAkB,CAAO,CAAG,CACnD,EAMA,OAJI,GACF,GAAoB,CAAO,EAGtB,CACT,CACF,EAEA,SAAgB,GACd,EACuB,CAKvB,OAAO,OAAO,OAAO,SAJM,EAAiC,EAA4B,CACtF,OAAO,EAAQ,OAAO,EAAM,CAAK,CACnC,EAEgC,CAC9B,KAAM,SAAS,EAA0B,GAAG,EAAyD,CACnG,OAAO,GAA0B,EAAQ,UAAU,CAAE,YAAW,SAAQ,CAAC,CAAC,CAC5E,EACA,KAAM,SAAS,GAAG,EAAyD,CACzE,OAAO,GAA0B,EAAQ,UAAU,IAAA,GAAW,CAAO,CAAC,CACxE,CACF,CAAC,CACH,CC/JA,SAAgB,GACd,EACA,GAAG,EACoB,CAEvB,OAAO,GAA0B,IADb,GAA0B,EAAW,GAAG,CAC3B,CAAO,CAC1C,CCrCA,SAAS,GACP,EACwC,CACxC,GAAI,CAIF,OAHI,EAAgB,MACX,GAA8B,EAAgB,QAAuC,EAAgB,SAAS,EAEhH,GAA+B,EAAgB,QAAS,EAAgB,SAAS,CAC1F,OAAS,EAAO,CAGd,GAFA,EAAS,oDAAoD,EAAgB,QAAQ,GAAI,CAAK,EAE1F,EAAgB,MAAO,CACzB,IAAM,EAAK,GAAgB,GAAe,EAAgB,OAAO,EACjE,GAAI,CAAC,EACH,MAAU,MAAM,iCAAiC,EAAgB,UAAW,CAAE,MAAO,CAAM,CAAC,EAE9F,OAAO,CACT,CACA,IAAM,EAAK,GAAc,EAAgB,OAAO,EAChD,GAAI,CAAC,EACH,MAAU,MAAM,6BAA6B,EAAgB,UAAW,CAAE,MAAO,CAAM,CAAC,EAE1F,OAAO,CACT,CACF,CAEA,SAAS,GAAsB,EAA+B,CAC5D,IAAM,EAAkB,GAAmB,CAAI,EAC/C,GAAI,CAAC,EACH,OAGF,IAAM,EAAa,GAAa,EAAgB,UAAY,GAAU,CACpE,EAAS,yCAA0C,CAAK,CAC1D,CAAC,EACK,EAAY,EAAK,WAAa,KAAK,aAEzC,GAAI,GAAc,CAAC,EAAW,CAC5B,IAAM,EAAU,GAAiC,CAAe,EAChE,GAAqB,EAAiB,CAAe,EACrD,GAAkB,EAAM,CAAe,CACzC,MAAO,GAAI,CAAC,GAAc,EAAW,CACnC,IAAM,EAAU,GAAyB,EAAgB,OAAO,EAC5D,IAGF,GAA2B,CAAI,EAC/B,GAAqB,EAAS,CAAe,EAC7C,GAAkB,EAAM,CAAO,EAEnC,CACF,CAEA,SAAgB,GAA0B,EAA2B,CAC9D,KAEL,GAAI,CACF,IAAM,EAAQ,GAA0B,EACxC,IAAK,IAAM,KAAQ,EAAO,CACxB,GAAI,CAAC,EAAK,YAAa,CACrB,GAA0B,CAAI,EAC9B,QACF,EAEI,IAAU,EAAM,SAAS,CAAI,IACjC,GAAsB,CAAyB,CACjD,CACF,OAAS,EAAO,CACd,EAAS,2CAA4C,CAAK,CAC5D,CACF,CCjEA,MAAM,mBAAiB,IAAI,IAE3B,SAAS,GAAkB,EAAmC,CAC5D,IAAM,EAAwB,CAAC,EACzB,kBAAO,IAAI,IAEjB,IAAK,IAAM,KAAO,EAAK,CACrB,GAAI,OAAO,GAAQ,SAAU,SAC7B,IAAM,EAAK,EAAI,KAAK,EACf,IACD,EAAK,IAAI,CAAE,IACf,EAAK,IAAI,CAAE,EACX,EAAW,KAAK,CAAE,GACpB,CAEA,OAAO,CACT,CAEA,SAAS,GAAa,EAAa,EAAmB,CACpD,IAAI,EAAM,GAAe,IAAI,CAAE,EAC1B,IACH,kBAAM,IAAI,IACV,GAAe,IAAI,EAAI,CAAG,GAE5B,EAAI,IAAI,IAAI,QAAQ,CAAE,CAAC,CACzB,CAEA,SAAgB,GAAc,EAAmC,CAC/D,IAAM,EAAW,GAAkB,CAAG,EACtC,GAAI,EAAS,SAAW,EAAG,MAAO,CAAC,EAEnC,IAAM,kBAAQ,IAAI,IAElB,IAAK,IAAM,KAAM,EAAU,CACzB,IAAM,EAAM,GAAe,IAAI,CAAE,EACjC,GAAI,CAAC,EAAK,SAEV,IAAM,EAA+B,CAAC,EAEtC,IAAK,IAAM,KAAO,EAAK,CACrB,IAAM,EAAK,EAAI,MAAM,EACrB,GAAI,IAAO,IAAA,GAAW,CAEpB,EAAS,KAAK,CAAG,EACjB,QACF,CACA,GAAI,CAAC,EAAgB,CAAE,EAAG,CAExB,EAAS,KAAK,CAAG,EACjB,QACF,CACA,EAAM,IAAI,CAAE,CACd,CAGA,IAAK,IAAM,KAAO,EAChB,EAAI,OAAO,CAAG,EAGZ,EAAI,OAAS,GAAG,GAAe,OAAO,CAAE,CAC9C,CAEA,OAAO,MAAM,KAAK,CAAK,CACzB,CAEA,SAAgB,GACd,GAAG,EACkB,CACrB,IAAM,EAAW,GAAkB,CAAG,EAEtC,OAAO,SAAS,EAAyC,CAClD,MACC,aAAkB,QACxB,IAAK,IAAM,KAAM,EAAU,GAAa,EAAI,CAAM,CACpD,CACF,CC9EA,MAAM,GAAW,CAChB,GACA,GACA,GACA,GACA,GACA,EACD,EAEA,SAAgB,GAAO,GAAG,EAA0B,CACnD,IAAI,EAEJ,GAAI,EAAS,OAAS,EAAG,CACxB,IAAM,EAAQ,GAAc,CAAQ,EAEpC,GAAI,EAAM,SAAW,EAAG,CACvB,IAAM,EAAO,EAAM,GACnB,EAAQ,CACP,QACA,SAAW,GAAS,EAAK,SAAS,CAAI,CACvC,CACD,KACC,GAAQ,CACP,QACA,SAAW,GAAS,CACnB,IAAK,IAAM,KAAQ,EAClB,GAAI,EAAK,SAAS,CAAI,EAAG,MAAO,GAEjC,MAAO,EACR,CACD,CAEF,CAEA,IAAK,IAAM,KAAM,GAAU,EAAG,CAAK,EAOnC,GAAgB,CACjB,CAEA,SAAgB,GAA0B,EAA2B,CACnE,GAAI,OAAO,SAAa,IAAa,OASrC,IAAM,EAAkC,EACpC,EAAM,MACN,CAAC,SAAS,MAAQ,QAAQ,EAE9B,IAAK,IAAM,KAAU,EACnB,GAAI,CACF,EAAO,cAAc,IAAI,MAAM,SAAU,CAAE,QAAS,EAAK,CAAC,CAAC,CAC7D,OAAS,EAAO,CACd,EAAS,wCAAyC,CAAK,CACzD,CAEJ,CCrEA,SAAgB,GACd,EACA,EACA,EAAgB,EACW,CAC3B,IAAM,EAAgB,GAAU,SAAS,KACnC,EAAU,EAAU,EAAc,CAAK,EAK7C,OAJA,EAAkC,YAAY,CAAe,EAG7D,GAAgB,EACT,CACT,CAwBA,SAAgB,GACd,EACA,EAC2B,CAC3B,IAAM,EAAgB,GAAU,SAAS,KACnC,EAAa,EACnB,EAAe,EACf,IAAI,EACJ,GAAI,CACF,EAAU,EAAU,EAAc,CAAC,EACnC,IAAM,EAAc,EAMpB,GAAI,GAAe,EAAY,WAAa,GAAK,EAAY,aAAe,EAAY,CACtF,IAAM,EAAQ,EAAU,CAAU,EAClC,GAAI,EAAO,CACT,IAAM,EAAQ,EAAM,YACpB,EAAW,aAAa,EAAa,CAAK,EAC1C,GAAgB,CAAK,EACrB,EAAU,EAAY,CAAK,CAC7B,MACE,EAAW,YAAY,CAAW,EAClC,EAAU,EAAY,IAAI,CAE9B,CACF,QAAU,CACR,EAAa,CACf,CASA,OADA,GAAgB,EACT,CACT,CCCA,SAAS,IAA2B,CACnC,MAAO,CACN,aAAc,KACd,0BAAW,IAAI,IACf,yBAAU,IAAI,IACd,wBAAS,IAAI,IACb,UAAW,CAAC,EACZ,2BAAY,IAAI,IAChB,WAAY,EACZ,aAAc,KACd,MAAO,KACP,cAAe,KACf,cAAe,EACf,2BAAY,IAAI,IAChB,cAAe,KACf,kBAAmB,EACpB,CACD,CAEA,MAAM,GAAmB,OAAO,IAAI,uBAAuB,EACrD,GAAc,WAEpB,IAAI,GACJ,SAAS,GAAwB,CAChC,MAAO,MAAgB,GAAY,MAAsB,GAAY,IAAoB,GAAY,EACtG,CAEA,SAAgB,GAAgB,EAA+B,CAC9D,IAAM,EAAQ,EAAS,EACvB,EAAM,aAAe,CACtB,CAGA,SAAgB,GAAgB,EAAiC,CAChE,IAAK,IAAM,KAAS,EAAS,CAC5B,IAAM,EAAQ,EAAS,EAClB,EAAM,WAAW,IAAI,CAAK,GAAG,EAAM,WAAW,IAAI,EAAO,CAAC,CAAC,CACjE,CACD,CAEA,SAAS,GAAY,EAAkB,EAAuC,CAC7E,IAAM,EAAQ,EAAS,EACvB,GAAI,CACH,IAAM,EAAM,EAAE,SAAS,OACvB,EAAE,WAAW,EAAQ,KAAM,CAAG,EAC9B,IAAM,EAAQ,EAAE,SAAS,GAGzB,OAFA,EAAM,WAAW,IAAI,EAAO,CAAK,EACjC,EAAM,WAAW,IAAI,EAAa,CAAK,EAAG,CAAK,EACxC,CACR,MAAQ,CACP,OAAO,IACR,CACD,CAKA,MAAM,mBAAe,IAAI,QACzB,SAAS,EAAa,EAAuB,CAC5C,IAAM,EAAS,GAAa,IAAI,CAAI,EACpC,GAAI,IAAW,IAAA,GAAW,OAAO,EACjC,IAAM,EAAO,EAAK,QACZ,EAAQ,EAAK,QAAQ,GAAG,EACxB,GAAS,IAAU,GAAK,EAAO,EAAK,MAAM,EAAG,CAAK,EAAA,CAAG,KAAK,EAEhE,OADA,GAAa,IAAI,EAAM,CAAK,EACrB,CACR,CAEA,SAAS,GAAa,EAAuB,CAC5C,OAAO,aAAgB,aAAe,EAAK,aAAe,EAAa,CAAI,CAC5E,CAEA,SAAS,GAAc,EAA2B,EAA0B,CAE3E,OADc,IAAU,IAAA,GAAY,IAAM,IAAM,EAAM,OAAS,IAAM,GACtD,EAAS,OAAS,IAAM,CACxC,CAEA,SAAS,GAAqB,EAAe,EAAiC,CAC7E,IAAM,EAAQ,EAAS,EACvB,GAAI,CAAC,EAAM,cAAe,OAC1B,IAAM,EAAM,GAAc,EAAO,GAAa,CAAI,CAAC,EAC/C,EAAQ,EAAM,cAAc,IAAI,CAAG,EAClC,IACJ,kBAAQ,IAAI,IACZ,EAAM,cAAc,IAAI,EAAK,CAAK,GAEnC,EAAM,IAAI,EAAK,OAAO,CACvB,CAEA,SAAS,GAAoB,EAAe,EAAoC,CAC/E,IAAM,EAAQ,EAAS,EACvB,GAAI,CAAC,EAAM,cAAe,MAAO,GACjC,IAAM,EAAM,GAAc,EAAO,GAAa,CAAI,CAAC,EAC7C,EAAQ,EAAM,cAAc,IAAI,CAAG,EAIzC,OAHK,GAAO,OAAO,EAAK,OAAO,GAC3B,EAAM,OAAS,GAAG,EAAM,cAAc,OAAO,CAAG,EAChD,EAAM,cAAc,OAAS,IAAG,EAAM,cAAgB,MACnD,IAHkC,EAI1C,CAWA,SAAS,GAAmB,EAA0B,CACrD,IAAM,EAAQ,EAAS,EACvB,IAAK,IAAI,EAAI,EAAG,EAAI,EAAM,OAAQ,IAAK,CACtC,IAAM,EAAO,EAAM,GACnB,GAAI,aAAgB,aAAc,CACjC,GAAqB,EAAM,IAAA,EAAS,EACpC,QACD,CACA,IAAM,EAAU,EAAa,CAAI,EACjC,GAAI,aAAc,GAAQ,CAAC,EAAQ,WAAW,YAAY,EAAG,CAC5D,IAAM,EAAQ,EACd,EAAM,kBAAoB,GAC1B,EAAM,WAAW,IAAI,EAAS,CAAK,EACnC,IAAK,IAAI,EAAI,EAAG,EAAI,EAAM,SAAS,OAAQ,IAC1C,GAAqB,EAAM,SAAS,GAAI,CAAO,CAEjD,MAEC,GAAqB,EAAM,IAAA,EAAS,CAEtC,CACD,CAEA,SAAS,GAAW,EAAkB,EAAoB,CACzD,IAAM,EAAQ,EAAS,EACvB,GAAI,CACH,EAAE,WAAW,EAAM,EAAM,aAAa,EACtC,IAAM,EAAW,EAAE,SAAS,EAAM,eAClC,GAAI,GAAoB,EAAU,IAAA,EAAS,EAAG,CAC7C,EAAE,WAAW,EAAM,aAAa,EAChC,MACD,CACA,EAAM,eACP,MAAQ,CAER,CACD,CAEA,SAAS,GAAc,EAAwB,EAAoB,CAClE,IAAM,EAAQ,EAAS,EACvB,GAAI,CACH,IAAM,EAAQ,EAAM,SAAS,OAC7B,EAAM,WAAW,EAAM,CAAK,EAC5B,IAAM,EAAW,EAAM,SAAS,GAC5B,EAAM,eAAiB,GAAoB,EAAU,EAAa,CAAK,CAAC,GAAG,EAAM,WAAW,CAAK,CACtG,MAAQ,CAER,CACD,CAEA,SAAS,GAAiB,EAAkB,EAAuC,CAClF,IAAM,EAAQ,EAAS,EACjB,EAAS,EAAM,WAAW,IAAI,CAAK,EACzC,GAAI,EAAQ,OAAO,EACnB,GAAI,CAAC,EAAM,kBAAmB,OAAO,GAAY,EAAG,CAAK,EAKzD,GAAI,CACH,IAAM,EAAQ,EAAE,SAAS,OACzB,EAAE,WAAW,EAAQ,KAAM,CAAK,EAChC,IAAM,EAAa,EAAa,EAAE,SAAS,EAAM,EACjD,EAAE,WAAW,CAAK,EAClB,IAAM,EAAW,EAAM,WAAW,IAAI,CAAU,EAChD,GAAI,EAEH,OADA,EAAM,WAAW,IAAI,EAAO,CAAQ,EAC7B,CAET,MAAQ,CACP,OAAO,IACR,CACA,OAAO,GAAY,EAAG,CAAK,CAC5B,CAQA,SAAgB,GAAoC,CACnD,IAAM,EAAQ,EAAS,EAIvB,GAHI,OAAO,SAAa,KAGpB,OAAO,SAAS,gBAAmB,WAAY,OAAO,KAC1D,GACC,EAAM,OACN,EAAM,gBAAkB,UACxB,EAAM,MAAM,WACX,EAAM,MAAM,UAAsB,YAEnC,OAAO,EAAM,MAEd,IAAM,EAAW,SAAS,eAAe,cAAc,EACnD,EAeJ,GAdI,GAAU,UAAY,QACzB,EAAK,GAEL,EAAK,SAAS,cAAc,OAAO,EACnC,EAAG,GAAK,eACJ,EAAU,EAAS,YAAY,CAAE,EAChC,SAAS,KAAK,YAAY,CAAE,GAElC,EAAM,MAAQ,EAAG,MACjB,EAAM,cAAgB,SACtB,EAAM,WAAW,MAAM,EACvB,EAAM,cAAgB,EACtB,EAAM,cAAgB,KACtB,EAAM,kBAAoB,GACtB,CAAC,EAAM,MAAO,OAAO,KACzB,GAAI,EAAM,MAAM,SAAS,OAAS,EAAG,CAKpC,IAAI,EAAI,EACR,KAAO,EAAI,EAAM,MAAM,SAAS,QAAQ,CACvC,IAAM,EAAI,EAAM,MAAM,SAAS,GAC/B,GAAI,EAAE,aAAa,eAAiB,aAAc,GAAK,CAAC,EAAa,CAAC,CAAC,CAAC,WAAW,YAAY,EAAG,MAClG,GACD,CACA,EAAM,cAAgB,EACtB,EAAM,8BAAgB,IAAI,IAC1B,GAAmB,EAAM,MAAM,QAAQ,CACxC,CACA,IAAK,IAAM,KAAQ,EAAM,UAAW,GAAW,EAAM,MAAO,CAAI,EAChE,IAAK,GAAM,CAAC,EAAO,KAAU,EAAM,WAAY,CAC9C,IAAM,EAAQ,GAAiB,EAAM,MAAO,CAAK,EACjD,GAAI,EAAO,IAAK,IAAM,KAAQ,EAAO,GAAc,EAAO,CAAI,CAC/D,CACA,OAAO,EAAM,KACd,CAEA,SAAS,GAAO,EAAc,EAAiC,CAC9D,IAAM,EAAQ,EAAS,EAGjB,EAAI,EAAY,EAEtB,GAAI,IAAU,IAAA,GACb,EAAM,UAAU,KAAK,CAAI,MACnB,CACN,IAAI,EAAS,EAAM,WAAW,IAAI,CAAK,EAClC,IACJ,EAAS,CAAC,EACV,EAAM,WAAW,IAAI,EAAO,CAAM,GAEnC,EAAO,KAAK,CAAI,CACjB,CAGA,GAFA,EAAM,aAAe,KAEjB,EAAG,CACN,GAAI,IAAU,IAAA,GACb,GAAW,EAAG,CAAI,MACZ,CACN,IAAM,EAAQ,GAAiB,EAAG,CAAK,EACnC,GAAO,GAAc,EAAO,CAAI,CACrC,CACD,CACA,EAAM,eAAe,IAAU,IAAA,GAAY,EAAO,EAAQ,IAAM,EAAO,GAAG,CAC3E,CAQA,SAAgB,GAAK,EAAuB,CAC3C,IAAI,EAAI,WACJ,EAAI,WACR,IAAK,IAAI,EAAI,EAAG,EAAI,EAAM,OAAQ,IAAK,CACtC,IAAM,EAAI,EAAM,WAAW,CAAC,EAC5B,EAAI,KAAK,KAAK,EAAI,EAAG,QAAU,EAC/B,EAAI,KAAK,KAAK,EAAI,EAAG,UAAU,CAChC,CACA,OAAQ,IAAM,EAAA,CAAG,SAAS,EAAE,IAAM,IAAM,GAAK,KAAA,CAAM,SAAS,EAAE,CAC/D,CAEA,SAAS,GAAa,EAA2B,EAAwB,CAExE,OADkB,IAAU,IAAA,GAAY,IAAM,IAAM,EAAM,OAAS,IAAM,GACtD,EAAO,OAAS,IAAM,CAC1C,CAEA,SAAS,GAAc,EAAa,EAAuB,CAC1D,OAAO,EAAM,EAAM,OAAS,IAAM,CACnC,CAEA,SAAgB,GAAiB,EAAe,EAA6B,CAC5E,IAAI,EAAW,GACX,EAAQ,EACZ,IAAK,IAAI,EAAI,EAAG,EAAI,EAAM,OAAQ,IAAK,CACtC,IAAM,EAAO,EAAM,WAAW,CAAC,EAC/B,GAAI,IAAS,IAAe,EAAI,EAAI,EAAM,OAAQ,CACjD,GAAY,EAAM,GAAK,EAAM,EAAE,GAC/B,QACD,CACA,GAAI,IAAU,EAAG,CAChB,GAAY,EAAM,GACd,IAAS,IAAO,EAAQ,GAC5B,QACD,CACI,IAAS,IAAc,IAAS,IACnC,EAAQ,EACR,GAAY,EAAM,IAElB,GAAY,IAAS,GAAa,EAAc,EAAM,EAExD,CACA,OAAO,CACR,CAEA,SAAS,GAAY,EAAmB,EAAwB,CAC/D,IAAM,EAAW,IAAM,EACvB,OAAO,EAAW,GAAiB,EAAQ,CAAQ,CACpD,CAQA,SAAS,GAAiB,EAAuB,CAChD,GAAI,EAAK,SAAW,GAAK,IAAS,IAAK,MAAO,GAC9C,IAAK,IAAI,EAAI,EAAG,EAAI,EAAK,OAAQ,IAAK,CACrC,IAAM,EAAI,EAAK,WAAW,CAAC,EAM3B,GAAI,EAJF,GAAK,IAAM,GAAK,KAChB,GAAK,IAAM,GAAK,IACjB,IAAM,IAAM,IAAM,IACjB,EAAI,GAAK,GAAK,IAAM,GAAK,IAClB,MAAO,EACjB,CAEA,GAAI,EAAK,WAAW,CAAC,IAAM,IAAM,EAAK,OAAS,EAAG,CACjD,IAAM,EAAS,EAAK,WAAW,CAAC,EAChC,GAAI,GAAU,IAAM,GAAU,GAAI,MAAO,EAC1C,CACA,MAAO,EACR,CAmBA,SAAS,GACR,EACA,EACA,EACA,EACA,EAAY,GACH,CACT,IAAM,EAAQ,EAAS,EACnB,EAAa,GAAa,EAAO,CAAM,EAC3C,IAAK,GAAM,CAAC,EAAM,KAAU,EAC3B,EAAa,GAAc,GAAc,EAAY,CAAI,EAAG,CAAK,EAE9D,IAAS,IAAA,IAAa,CAAC,GAAiB,CAAI,IAE/C,QAAQ,KACP,sBAAsB,KAAK,UAAU,CAAI,EAAE,6HAE5C,EACA,EAAO,IAAA,IAER,IAAM,EAAU,IAAS,IAAA,GAAY,IAAM,EAAa,IAAM,GAAc,GAAI,CAAI,EAAI,EACpF,EAAY,EAAM,UAAU,IAAI,CAAO,EAC3C,GAAI,IAAc,IAAA,GAGjB,OADA,EAAY,EACL,EAGJ,IAAS,IAAA,GACZ,EAAY,IAAM,GAAK,CAAO,GAE9B,EAAY,EAAY,EAAO,EAAO,IAAM,GAAK,CAAO,EACpD,EAAM,SAAS,IAAI,CAAS,GAE/B,QAAQ,KACP,sBAAsB,KAAK,UAAU,CAAS,EAAE,mIAEjD,GAIF,IAAI,EAAO,GACX,IAAK,GAAM,CAAC,EAAM,KAAU,EAAO,IAAS,EAAO,IAAM,IAAM,EAAO,IAAM,EAI5E,OAHA,EAAM,UAAU,IAAI,EAAS,CAAS,EACtC,EAAM,SAAS,IAAI,EAAW,CAAE,QAAO,SAAQ,QAAO,MAAK,CAAC,EAC5D,GAAO,GAAY,EAAW,CAAM,EAAI,IAAM,EAAO,IAAK,CAAK,EACxD,CACR,CAQA,SAAgB,GACf,EACA,EACA,EACA,EACA,EAAY,GACH,CACT,OAAO,GAAU,EAAO,EAAQ,EAAO,EAAM,CAAS,CACvD,CAWA,SAAgB,GAAY,EAAe,EAAwB,CAClE,IAAM,EAAQ,EAAS,EACjB,EAAI,EAAM,SAAS,IAAI,CAAK,EAC5B,EAAI,EAAM,SAAS,IAAI,CAAM,EACnC,GAAI,CAAC,GAAK,CAAC,EAAG,OAAO,EACrB,IAAM,EAAS,CAAC,GAAG,EAAE,MAAO,GAAG,EAAE,KAAK,EAGhC,kBAAY,IAAI,IACtB,IAAK,IAAI,EAAI,EAAG,EAAI,EAAO,OAAQ,IAAK,EAAU,IAAI,EAAO,EAAE,CAAC,GAAI,CAAC,EACrE,IAAM,EAAS,EAAO,QAAQ,EAAM,IAAM,EAAU,IAAI,EAAK,EAAE,IAAM,CAAC,EACtE,OAAO,GAAU,EAAE,MAAO,EAAE,OAAQ,EAAQ,EAAE,MAAQ,EAAE,IAAI,CAC7D,CAGA,SAAgB,GAAc,EAAuC,CAEpE,IAAM,EADQ,EACG,CAAC,CAAC,SAAS,IAAI,CAAS,EACzC,OAAO,IAAS,IAAA,GAAY,IAAA,GAAY,GAAa,EAAK,MAAO,EAAK,MAAM,CAC7E,CAGA,SAAgB,GAAwB,CACvC,OAAQ,IAAe,GAAY,IAAA,EAAoB,YAAc,CACtE,CAGA,SAAgB,GAAW,EAAmB,EAAoB,CACjE,IAAM,EAAQ,EAAS,EACvB,GAAI,EAAM,QAAQ,IAAI,CAAS,EAAG,CACjC,EAAY,EACZ,MACD,CACA,EAAM,QAAQ,IAAI,CAAS,EAC3B,GAAO,EAAM,IAAA,EAAS,CACvB,CAGA,SAAgB,IAAqB,CACpC,IAAM,EAAQ,EAAS,EACvB,GAAI,EAAM,eAAiB,KAAM,OAAO,EAAM,aAC9C,IAAI,EAAM,EAAM,UAAU,KAAK,EAAE,EACjC,IAAK,GAAM,CAAC,EAAO,KAAU,EAAM,WAC9B,EAAM,OAAS,IAAG,GAAO,EAAQ,IAAM,EAAM,KAAK,EAAE,EAAI,KAG7D,MADA,GAAM,aAAe,EACd,CACR,CAGA,SAAgB,IAAoB,CACnC,IAAM,EAAQ,EAAS,EACvB,EAAM,UAAU,MAAM,EACtB,EAAM,SAAS,MAAM,EACrB,EAAM,QAAQ,MAAM,EACpB,EAAM,UAAU,OAAS,EACzB,EAAM,WAAW,MAAM,EACvB,EAAM,WAAW,MAAM,EACvB,EAAM,aAAe,KACrB,EAAM,cAAgB,EACtB,EAAM,MAAQ,KACd,EAAM,cAAgB,KACtB,EAAM,cAAgB,KACtB,EAAM,kBAAoB,GAC1B,EAAM,aACF,OAAO,SAAa,KACvB,SAAS,eAAe,cAAc,CAAC,EAAE,OAAO,CAElD,CCliBA,MAAM,GAAS,CACd,MAAO,SACP,MAAO,SACP,aAAc,iBACd,YAAa,gBACb,OAAQ,UACR,QAAS,WACT,SAAU,YACV,QAAS,WACT,QAAS,WACT,SAAU,YACV,QAAS,WACT,MAAO,SACP,SAAU,aACV,MAAO,eACP,KAAM,cACN,KAAM,cACN,IAAK,kBACL,KAAM,mBACN,MAAO,SACP,iBAAkB,qBAClB,YAAa,gBACb,OAAQ,WACR,MAAO,UACP,UAAW,cACX,OAAQ,WACR,UAAW,eACX,YAAa,gBACd,EAKM,GAA2C,CAChD,GAAI,CAAC,YAAY,EACjB,EAAG,CAAC,SAAS,EACb,GAAI,CAAC,eAAgB,eAAe,EACpC,GAAI,CAAC,cAAe,gBAAgB,EACpC,GAAI,CAAC,aAAa,EAAG,GAAI,CAAC,eAAe,EAAG,GAAI,CAAC,gBAAgB,EAAG,GAAI,CAAC,cAAc,EACvF,EAAG,CAAC,QAAQ,EACZ,GAAI,CAAC,cAAe,cAAc,EAClC,GAAI,CAAC,aAAc,eAAe,EAClC,GAAI,CAAC,YAAY,EAAG,GAAI,CAAC,cAAc,EAAG,GAAI,CAAC,eAAe,EAAG,GAAI,CAAC,aAAa,EACnF,EAAG,CAAC,OAAO,EAAG,EAAG,CAAC,QAAQ,EAC1B,KAAM,CAAC,WAAW,EAAG,KAAM,CAAC,WAAW,EAAG,KAAM,CAAC,YAAY,EAAG,KAAM,CAAC,YAAY,EACnF,KAAM,CAAC,QAAS,QAAQ,EACxB,KAAM,CAAC,WAAW,EAClB,KAAM,CAAC,aAAa,EACpB,OAAQ,CAAC,aAAa,EACtB,QAAS,CAAC,aAAa,EACvB,SAAU,CAAC,gBAAgB,EAC3B,MAAO,CAAC,YAAY,EACpB,MAAO,CAAC,aAAa,EACrB,QAAS,CAAC,iBAAiB,EAC3B,EAAG,CAAC,SAAS,EACb,QAAS,CAAC,eAAe,EACzB,OAAQ,CAAC,YAAY,EACrB,OAAQ,CAAC,aAAa,CACvB,EAEM,GAAoD,CACzD,IAAK,CAAE,QAAS,OAAQ,iBAAkB,KAAM,EAChD,IAAK,CAAE,QAAS,OAAQ,iBAAkB,QAAS,EACnD,OAAQ,CAAE,cAAe,SAAU,kBAAmB,QAAS,EAC/D,SAAU,CAAE,SAAU,SAAU,gBAAiB,WAAY,cAAe,QAAS,CACtF,EAGM,GAAgD,CACrD,WAAY,SACZ,mBAAoB,SACpB,MAAO,SACP,eAAgB,SAChB,mBAAoB,SACpB,qBAAsB,SACtB,sBAAuB,SACvB,oBAAqB,SACrB,gBAAiB,SACjB,cAAe,SACf,wBAAyB,SACzB,cAAe,QACf,aAAc,UACd,gBAAiB,OAClB,EAGM,mBAAW,IAAI,IAAI,CACxB,UAAW,UAAW,cAAe,cAAe,OAAQ,YAC5D,cAAe,QAAS,eAAgB,OAAQ,QAAS,eACzD,UAAW,SAAU,WAAY,4BAA6B,cAAe,UAC9E,CAAC,EAGK,mBAAa,IAAI,IACvB,SAAS,GAAM,EAAsB,CACpC,GAAI,CAAC,QAAQ,KAAK,CAAI,EAAG,OAAO,EAChC,IAAI,EAAM,GAAW,IAAI,CAAI,EAM7B,OALI,IAAQ,IAAA,KACX,EAAM,EAAK,QAAQ,SAAW,GAAM,IAAM,EAAE,YAAY,CAAC,EACrD,GAAW,MAAQ,KAAK,GAAW,MAAM,EAC7C,GAAW,IAAI,EAAM,CAAG,GAElB,CACR,CAEA,SAAS,GAAQ,EAAwB,CACxC,OAAO,EAAO,WAAW,CAAC,IAAM,GAAa,EAAS,UAAY,CACnE,CAEA,SAAS,GAAa,EAA2B,EAAuB,CAKvE,OAHI,IAAU,IAAA,IAAa,EAAM,WAAW,QAAQ,GAAK,EAAM,WAAW,QAAQ,EAC1E,EAAQ,OAAS,EAAM,MAAM,CAAC,EAE/B,CACR,CAUA,SAAS,GAAW,EAAiC,EAA0D,CAC9G,IAAK,IAAM,KAAO,EAAQ,CACzB,IAAM,EAAQ,EAAO,GACf,EAAW,EAAO,GACxB,AAMC,EAAO,GALW,OAAO,GAAU,UAAnC,GAA+C,CAAC,MAAM,QAAQ,CAAK,GAC9C,OAAO,GAAa,UAAzC,GAAqD,CAAC,MAAM,QAAQ,CAAQ,EAE9D,GAAW,CAAE,GAAI,CAAqC,EAAG,CAAgC,EAEzF,CAEhB,CACA,OAAO,CACR,CAQA,IAAM,GAAN,KAAsB,CACrB,UACA,YAAY,EAAmB,CAC9B,KAAK,UAAY,CAClB,CACA,UAAmB,CAClB,OAAO,KAAK,SACb,CACD,EAEA,SAAS,EAAW,EAAgC,CACnD,OAAO,IAAI,GAAgB,CAAS,CACrC,CAEA,SAAS,GAAU,EAA6B,EAAoB,CACnE,IAAM,EAAM,GAAc,CAAI,EAC9B,GAAI,IAAQ,IAAA,GAAW,CAEtB,EAAO,IAAI,EAAM,CAAI,EACrB,MACD,CACA,IAAM,EAAO,EAAO,IAAI,CAAG,EACvB,IAAS,IAAA,IAAa,IAAS,EAAM,EAAO,IAAI,EAAK,CAAI,EAIxD,EAAO,IAAI,EAAK,GAAY,EAAM,CAAI,CAAC,CAC7C,CAEA,SAAS,GAAmB,EAAmB,EAAmC,CACjF,IAAI,EAAQ,EACZ,IAAK,IAAI,EAAI,EAAG,GAAK,EAAU,OAAQ,IAAK,CAC3C,IAAM,EAAO,IAAM,EAAU,OAAS,GAAK,EAAU,WAAW,CAAC,GAC9C,IAAS,IAAM,IAAS,GAAK,IAAS,IAAM,IAAS,IAAM,IAAS,MAEnF,EAAI,GAAO,GAAU,EAAQ,EAAU,MAAM,EAAO,CAAC,CAAC,EAC1D,EAAQ,EAAI,EACb,CACD,CAEA,SAAS,GAAe,EAA+B,EAAmC,CACzF,IAAK,IAAM,KAAS,EACd,IACD,OAAO,GAAU,SACpB,GAAmB,EAAO,CAAM,EACtB,MAAM,QAAQ,CAAK,EAC7B,GAAe,EAAO,CAAM,EAE5B,GAAoB,EAAsB,UAAW,CAAM,EAG9D,CAEA,SAAS,GAAiB,EAAuC,CAChE,IAAM,kBAAS,IAAI,IACnB,GAAe,EAAQ,CAAM,EAC7B,IAAI,EAAY,GAChB,IAAK,IAAM,KAAQ,EAAO,OAAO,EAAG,IAAc,EAAY,IAAM,IAAM,EAC1E,OAAO,CACR,CAOA,MAAM,mBAAa,IAAI,QAEvB,SAAS,GAAgB,EAAyC,CACjE,MAAO,CAAC,CAAC,GAAS,OAAO,GAAU,UAAY,CAAC,MAAM,QAAQ,CAAK,CACpE,CAYA,SAAgB,GAAG,GAAG,EAAmC,CACxD,GAAI,EAAO,SAAW,EAAG,OAAO,EAAW,EAAE,EAC7C,GAAI,EAAO,SAAW,EAAG,CACxB,IAAM,EAAO,EAAO,GACpB,GAAI,CAAC,EAAM,OAAO,EAAW,EAAE,EAC/B,GAAI,CAAC,MAAM,QAAQ,CAAI,EAAG,CACzB,IAAM,EAAO,OAAO,GAAS,SAAW,EAAQ,EAAqB,UAErE,GAAI,CAAC,cAAc,KAAK,CAAI,EAAG,OAAO,EAAW,CAAI,CACtD,CACD,CAEA,GAAI,EAAO,SAAW,GAAK,GAAgB,EAAO,EAAE,GAAK,GAAgB,EAAO,EAAE,EAAG,CACpF,IAAM,EAAI,EAAO,GACX,EAAI,EAAO,GACX,EAAQ,EAAc,EACtB,EAAQ,GAAW,IAAI,CAAC,EACxB,EAAM,GAAO,IAAI,CAAC,EACxB,GAAI,IAAQ,IAAA,IAAa,EAAI,QAAU,GAAS,EAAI,QAAU,EAAO,EAAE,CAAC,WAAa,EAAI,SAAW,EAAO,EAAE,CAAC,UAE7G,OADA,EAAY,EACL,EAAI,OAGZ,IAAM,EAAS,EAAW,GAAiB,CAAM,CAAC,EAC5C,EAAS,mBAAS,IAAI,QAG5B,OAFA,EAAO,IAAI,EAAG,CAAE,QAAO,MAAO,EAAO,EAAE,CAAC,UAAW,OAAQ,EAAO,EAAE,CAAC,UAAW,QAAO,CAAC,EACnF,GAAO,GAAW,IAAI,EAAG,CAAM,EAC7B,CACR,CAEA,OAAO,EAAW,GAAiB,CAAM,CAAC,CAC3C,CAKA,SAAgB,GAAuC,EAAW,CAAC,EAAwB,CAC1F,IAAM,EAAkC,EAAM,SAAW,CAAC,EAC1D,GAAgB,OAAO,OAAO,CAAO,CAAC,CAAC,IAAI,EAAO,CAAC,EAKnD,IAAM,kBAAO,IAAI,QAEjB,SAAS,EAAW,EAAc,EAAgC,CACjE,GAAI,OAAO,GAAU,SACpB,OAAO,IAAU,GAAK,GAAS,IAAI,CAAI,EAAI,OAAO,CAAK,EAAI,EAAQ,KAEpE,IAAM,EAAQ,GAAW,GACzB,GAAI,IAAU,IAAA,GAAW,CACxB,IAAM,EAAO,EAAM,EAAM,GAA0C,GACnE,GAAI,IAAQ,IAAA,GAAW,OAAO,CAC/B,CACA,OAAO,CACR,CAKA,SAAS,EAAU,EAA8B,EAA2B,EAAwB,CAEnG,IAAM,GADY,IAAU,IAAA,GAAY,IAAM,IAAM,EAAM,OAAS,IAAM,GACjD,EAAO,OAAS,IAAM,EAC1C,EAAS,EAAQ,IAAI,CAAG,EAK5B,OAJK,IACJ,EAAS,CAAE,QAAO,SAAQ,MAAO,CAAC,CAAE,EACpC,EAAQ,IAAI,EAAK,CAAM,GAEjB,CACR,CAEA,SAAS,EAAK,EAAgC,EAA2B,EAAgB,EAAoC,CAC5H,IAAK,IAAM,KAAO,EAAO,CACxB,IAAM,EAAQ,EAAM,GACpB,GAAI,GAAS,MAAQ,IAAU,GAAO,SAEtC,GAAI,OAAO,GAAU,SAAU,CAC9B,GAAI,IAAQ,MAAO,CAClB,IAAM,EAAO,EACP,EAAQ,EAAU,EAAS,EAAO,CAAM,CAAC,CAAC,MAChD,IAAK,IAAM,KAAQ,EAAM,EAAM,KAAK,CAAC,EAAM,EAAW,EAAM,EAAK,EAAK,CAAC,CAAC,EACxE,QACD,CACA,IAAM,EAAU,GAA8C,GAC9D,GAAI,IAAW,IAAA,GAAW,CACzB,EAAK,EAAkC,EAAO,EAAS,EAAQ,CAAO,EACtE,QACD,CACA,IAAM,EAAS,EAAQ,GACvB,GAAI,IAAW,IAAA,GAAW,CACzB,EAAK,EAAkC,GAAa,EAAO,GAAQ,CAAM,CAAC,EAAG,EAAQ,CAAO,EAC5F,QACD,CACA,IAAM,EAAQ,EAAI,WAAW,CAAC,EAC9B,GAAI,IAAU,GAAY,CAEzB,EAAK,EAAkC,EADxB,GAAiB,EAAK,IAAM,CACQ,CAAC,CAAC,MAAM,CAAC,EAAG,CAAO,EACtE,QACD,CACA,GAAI,IAAU,GAAY,CACzB,EAAK,EAAkC,GAAa,EAAO,CAAG,EAAG,EAAQ,CAAO,EAChF,QACD,CACA,QACD,CAEA,GAAI,IAAU,GAAM,CACnB,IAAM,EAAY,GAAU,GAC5B,GAAI,EAAW,CACd,IAAM,EAAQ,EAAU,EAAS,EAAO,CAAM,CAAC,CAAC,MAChD,IAAK,IAAM,KAAQ,EAAW,EAAM,KAAK,CAAC,EAAM,EAAU,EAAK,CAAC,CACjE,CACA,QACD,CAEA,IAAM,EAAU,GAAM,GACtB,GAAI,IAAY,IAAA,GAAW,CAC1B,IAAM,EAAQ,EAAU,EAAS,EAAO,CAAM,CAAC,CAAC,MAChD,IAAK,IAAM,KAAQ,EAAS,EAAM,KAAK,CAAC,EAAM,EAAW,EAAM,CAAwB,CAAC,CAAC,CAC1F,KAAO,CACN,IAAM,EAAO,GAAM,CAAG,EACtB,EAAU,EAAS,EAAO,CAAM,CAAC,CAAC,MAAM,KAAK,CAAC,EAAM,EAAW,EAAM,CAAwB,CAAC,CAAC,CAChG,CACD,CACD,CAqBA,SAAS,EAAI,EAAgC,EAAoC,CAChF,IAAM,EAAQ,OAAO,GAAgB,SAC/B,EAAS,EAAQ,EAAa,EAC9B,EAAO,EAAQ,EAAc,IAAA,GACnC,GAAI,GAAS,KAAM,OAAO,EAAW,EAAE,EAIvC,IAAM,EAAQ,EAAc,EACtB,EAAM,EAAK,IAAI,CAAK,EAC1B,GAAI,IAAQ,IAAA,IAAa,EAAI,QAAU,GAAS,EAAI,OAAS,EAE5D,OADA,EAAY,EACL,EAAI,OAGZ,IAAM,kBAAU,IAAI,IACpB,EAAK,EAAkC,IAAA,GAAW,GAAI,CAAO,EAC7D,IAAM,EAAoB,CAAC,EAC3B,IAAK,IAAM,KAAU,EAAQ,OAAO,EAAG,CACtC,GAAI,EAAO,MAAM,SAAW,EAAG,SAC/B,IAAM,EAAS,EAAO,QAAU,IAAA,IAAa,EAAO,SAAW,GAC/D,EAAQ,KAAK,GAAU,EAAO,MAAO,EAAO,OAAQ,EAAO,MAAO,EAAM,CAAM,CAAC,CAChF,CACA,IAAM,EAAS,EAAW,EAAQ,KAAK,GAAG,CAAC,EAE3C,OADA,EAAK,IAAI,EAAO,CAAE,QAAO,OAAM,QAAO,CAAC,EAChC,CACR,CAEA,SAAS,EAAU,EAAwC,CAC1D,IAAI,EAAQ,GACN,GAAQ,EAAc,IAAoB,CAC/C,IAAU,EAAQ,IAAM,IAAM,EAAO,IAAM,CAC5C,EACA,IAAK,IAAM,KAAO,EAAO,CACxB,IAAM,EAAQ,EAAM,GACpB,GAAI,GAAS,MAAQ,IAAU,GAAO,SACtC,GAAI,IAAQ,OAAS,OAAO,GAAU,SAAU,CAC/C,IAAM,EAAO,EACb,IAAK,IAAM,KAAQ,EAAM,EAAK,EAAM,EAAW,EAAM,EAAK,EAAK,CAAC,EAChE,QACD,CACA,GAAI,OAAO,GAAU,SAAU,SAC/B,GAAI,IAAU,GAAM,CACnB,IAAM,EAAY,GAAU,GAC5B,GAAI,EAAW,IAAK,IAAM,KAAQ,EAAW,EAAK,EAAM,EAAU,EAAK,EACvE,QACD,CACA,IAAM,EAAU,GAAM,GACtB,GAAI,IAAY,IAAA,GACf,IAAK,IAAM,KAAQ,EAAS,EAAK,EAAM,EAAW,EAAM,CAAwB,CAAC,MAC3E,CACN,IAAM,EAAO,GAAM,CAAG,EACtB,EAAK,EAAM,EAAW,EAAM,CAAwB,CAAC,CACtD,CACD,CACA,OAAO,CACR,CAGA,SAAS,EAAU,EAAmC,CACrD,IAAI,EAAO,GACX,IAAK,IAAM,KAAQ,EAClB,GAAQ,EAAO,IAAM,EAAU,EAAO,EAAgC,EAAI,IAE3E,IAAM,EAAO,KAAO,GAAK,CAAI,EAE7B,OADA,GAAW,EAAM,cAAgB,EAAO,IAAM,EAAO,GAAG,EACjD,CACR,CAGA,SAAS,EAAY,EAAkB,EAA2B,CACjE,IAAM,EAAO,EAAW,IAAM,EAAU,CAAgC,EAAI,IAC5E,GAAW,KAAO,EAAM,CAAI,CAC7B,CAwBA,SAAS,EACR,EACgB,CAChB,IAAM,EAAa,GAClB,IAAU,GAAO,OAAS,IAAU,GAAQ,QAAU,OAAO,CAAK,EAE7D,EAAU,EAAO,UAAY,CAAC,EAC9B,EAAa,OAAO,KAAK,CAAM,EAC/B,EAAY,EAAO,iBAAmB,CAAC,EACvC,EAAa,EAAO,MAAQ,KAE5B,GAAa,EAAO,kBAAoB,CAAC,EAAA,CAAG,IAAK,GAAU,CAChE,GAAM,CAAE,IAAK,EAAe,GAAG,GAAU,EACnC,EAAqC,CAAC,EAC5C,IAAK,IAAM,KAAS,EAAO,EAAW,GAAS,EAAW,EAAkC,EAAM,EAClG,MAAO,CAAE,aAAY,MAAO,CAAyC,CACtE,CAAC,EAEK,kBAAQ,IAAI,IACd,EAAa,EAAc,EAE/B,OAAO,SAAgB,EAAsC,CAC5D,IAAM,EAAQ,EAAc,EACxB,IAAe,IAClB,EAAM,MAAM,EACZ,EAAa,GAGd,IAAM,EAAoC,CAAC,EAC3C,IAAK,IAAM,KAAS,EAAY,CAC/B,IACM,GADW,EAAS,EAAkC,GAAS,IAAA,KACG,EAAS,GAC7E,GAAmC,OACvC,EAAU,GAAS,EAAU,CAAM,EACpC,CAGA,IAAI,EAAM,GACV,IAAK,IAAM,KAAS,EAAY,CAC/B,IAAM,EAAQ,EAAU,GACxB,GAAO,EAAM,OAAS,IAAM,EAC5B,GAAO,IAAU,IAAA,GAAY,IAAM,IAAM,EAAM,OAAS,IAAM,CAC/D,CACA,IAAM,EAAS,EAAM,IAAI,CAAG,EAC5B,GAAI,EAEH,OADA,EAAY,EACL,EAGR,IAAI,EAAkC,CAAC,EACnC,IAAW,EAAS,GAAW,EAAQ,CAAS,GACpD,IAAK,IAAM,KAAS,EAAY,CAC/B,IAAM,EAAQ,EAAU,GACxB,GAAI,IAAU,IAAA,GAAW,CACxB,IAAM,EAAQ,EAAO,EAAM,CAAC,GACxB,IAAO,EAAS,GAAW,EAAQ,CAAgC,EACxE,CACD,CACA,IAAK,IAAM,KAAY,EAAW,CACjC,IAAI,EAAU,GACd,IAAK,IAAM,KAAS,EAAS,WAC5B,GAAI,EAAU,KAAW,EAAS,WAAW,GAAQ,CACpD,EAAU,GACV,KACD,CAEG,IAAS,EAAS,GAAW,EAAQ,EAAS,KAAK,EACxD,CAEA,IAAM,EAAS,EAAI,CAAkB,EAErC,OADA,EAAM,IAAI,EAAK,CAAM,EACd,CACR,CACD,CAEA,MAAO,CAAE,MAAK,MAAI,WAAU,YAAW,cAAa,OAAM,CAC3D,CAWA,IAAI,GACJ,SAAS,GAA0C,CAClD,MAAQ,MAAoB,GAAU,CAAC,CAAC,CACzC,CAGA,MAAa,IAGR,EAAqC,IACzC,OAAO,GAAgB,SACpB,EAAmB,CAAC,CAAC,IAAI,EAAa,CAAsB,EAC5D,EAAmB,CAAC,CAAC,IAAI,CAAW,EAE3B,GAES,GAAW,EAAmB,CAAC,CAAC,SAAS,CAAM,EAExD,GAAyD,GAAW,EAAmB,CAAC,CAAC,UAAU,CAAM,EAEzG,IAAqE,EAAU,IAC3F,EAAmB,CAAC,CAAC,YAAY,EAAU,CAAK,EC7mBjD,SAAgB,IAA0B,CACxC,GAA0B,EAE1B,IAAM,EAAW,WACjB,EAAS,KAAO,GAChB,EAAS,OAAS,GAClB,EAAS,KAAO,GAChB,EAAS,GAAK,GACd,EAAS,MAAQ,GACjB,EAAS,OAAS,GAClB,EAAS,QAAU,GAInB,EAAS,UAAY,GACrB,EAAS,IAAM,GACf,EAAS,GAAK,GACd,EAAS,SAAW,GACpB,EAAS,UAAY,GACrB,EAAS,YAAc,EACzB,CAEA,GAAkB"}
|
|
1
|
+
{"version":3,"file":"nuclo.mjs","names":[],"sources":["../src/shared/type-guards.ts","../src/shared/errors.ts","../src/shared/environment.ts","../src/hydration.ts","../src/element/lifecycle.ts","../src/element/factory-meta.ts","../src/element/events.ts","../src/update/registry.ts","../src/shared/dom.ts","../src/update/reactive-attributes.ts","../src/element/inline-style.ts","../src/element/event-attributes.ts","../src/element/class-name.ts","../src/update/reactive-text.ts","../src/element/attributes.ts","../src/element/modifiers.ts","../src/element/factory.ts","../src/element/tags.ts","../src/shared/renderables.ts","../src/list/template.ts","../src/list/runtime.ts","../src/list/index.ts","../src/shared/conditions.ts","../src/when/runtime.ts","../src/when/builder.ts","../src/when/index.ts","../src/update/conditional.ts","../src/update/scope.ts","../src/update/update.ts","../src/render.ts","../src/style/engine.ts","../src/style/css.ts","../src/bootstrap.ts"],"sourcesContent":["export function isPrimitive(value: unknown): value is Primitive {\n\treturn value === null || (typeof value !== \"object\" && typeof value !== \"function\");\n}\n\nexport function isNode<T>(value: T): value is T & Node {\n\tif (value instanceof Node) return true;\n\tif (typeof value !== 'object' || value === null) return false;\n\t// Recognize polyfill DOM objects (plain objects with a numeric nodeType)\n\treturn typeof (value as { nodeType?: unknown }).nodeType === 'number';\n}\n\nexport function isObject(value: unknown): value is object {\n\treturn typeof value === \"object\" && value !== null;\n}\n\nexport function isTagLike<T>(value: T): value is T & { tagName?: string } {\n\treturn isObject(value) && \"tagName\" in (value as object);\n}\n\nexport function isBoolean(value: unknown): value is boolean {\n\treturn typeof value === \"boolean\";\n}\n\n/**\n * Narrows `value` to a callable. The generic `<T extends Function>` is intentionally\n * removed: it allowed callers to assert any specific function signature via the type\n * parameter without a runtime check, which is unsafe. Use explicit casts at call sites\n * when a more specific signature is needed.\n */\nexport function isFunction(value: unknown): value is (...args: unknown[]) => unknown {\n\treturn typeof value === \"function\";\n}\n\nexport function isZeroArityFunction(value: unknown): value is () => unknown {\n\treturn isFunction(value) && (value as { length: number }).length === 0;\n}\n","export function logError(message: string, error?: Error | unknown): void {\n if (typeof console !== 'undefined') {\n // eslint-disable-next-line no-console\n console.error(`nuclo: ${message}`, error);\n }\n}","/**\n * Simplified environment detection - minimal overhead for smaller bundle size\n */\n\n// Basic environment detection - no complex caching or edge cases\nexport const isBrowser = typeof window !== 'undefined' && typeof document !== 'undefined';\n","/**\n * Hydration context — tracks global hydration state and per-parent cursor positions.\n *\n * During hydration the component tree is built against an existing DOM tree\n * (produced by SSR). Instead of creating new nodes, factories claim existing\n * children from their parent element by advancing a cursor.\n *\n * The cursor is a *node pointer* (the next unclaimed child), not an index.\n * Indexed childNodes access is O(n) after any tree/attribute mutation in\n * jsdom (live NodeList re-materialization) which made hydration O(n²);\n * firstChild/nextSibling pointers are O(1) in every DOM implementation.\n */\n\nlet _hydrating = false;\n// True while renderToString() is building a tree destined for serialization.\nlet _serializing = false;\n// Missing entry = cursor at parent.firstChild; null = past the last child.\nlet _cursors = new WeakMap<Node, Node | null>();\n\nexport function isHydrating(): boolean {\n return _hydrating;\n}\n\n/**\n * True while a tree is being built for SSR serialization (inside\n * renderToString). Text children must keep their `<!-- text-N -->` markers in\n * this mode so the emitted HTML stays hydratable — even when `isBrowser` is\n * true (SSR running under jsdom, or an isomorphic worker that provides a DOM).\n * A pure client render leaves this false and skips the markers.\n */\nexport function isSerializing(): boolean {\n return _serializing;\n}\n\n/**\n * Runs `fn` with serialization mode enabled, restoring the previous state\n * afterwards (so nested/re-entrant renderToString calls behave correctly).\n */\nexport function runSerializing<T>(fn: () => T): T {\n const previous = _serializing;\n _serializing = true;\n try {\n return fn();\n } finally {\n _serializing = previous;\n }\n}\n\nexport function startHydration(): void {\n _hydrating = true;\n // Each hydration pass starts with a clean cursor slate. Stale cursors from\n // a previous pass would desynchronize claims when a container's content is\n // replaced and re-hydrated (HMR, islands re-mounting).\n _cursors = new WeakMap<Node, Node | null>();\n}\n\nexport function endHydration(): void {\n _hydrating = false;\n}\n\n/**\n * Runs a callback with hydration temporarily disabled, restoring the previous\n * state afterwards. Used when a server/client mismatch forces a subtree to be\n * rendered fresh in the middle of a hydration pass — fresh rendering must not\n * claim nodes from the surrounding SSR DOM.\n */\nexport function runWithoutHydration<T>(fn: () => T): T {\n const wasHydrating = _hydrating;\n _hydrating = false;\n try {\n return fn();\n } finally {\n _hydrating = wasHydrating;\n }\n}\n\n/**\n * Returns the next unclaimed child of a parent node (or null at the end)\n * without advancing the cursor.\n */\nexport function peekChild(parent: Node): Node | null {\n const entry = _cursors.get(parent);\n return entry === undefined ? parent.firstChild : entry;\n}\n\n/**\n * Sets the cursor to a specific child node (or null for \"past the end\").\n */\nexport function setCursor(parent: Node, node: Node | null): void {\n _cursors.set(parent, node);\n}\n\nfunction isWhitespaceText(node: Node): boolean {\n return node.nodeType === 3 && !/\\S/.test(node.textContent || '');\n}\n\n/**\n * Advances the cursor past whitespace-only text nodes.\n *\n * Nuclo's own SSR output never produces bare whitespace text nodes (text\n * children are always preceded by a `<!-- text-N -->` marker), so unmarked\n * whitespace comes from the surrounding template or an HTML\n * formatter/minifier. Skipping (without removing) keeps the cursor aligned\n * while leaving the document's visual whitespace untouched.\n */\nexport function skipWhitespaceText(parent: Node): void {\n let child = peekChild(parent);\n let advanced = false;\n while (child && isWhitespaceText(child)) {\n child = child.nextSibling;\n advanced = true;\n }\n if (advanced) {\n setCursor(parent, child);\n }\n}\n\n/**\n * Claims the next child node from parent at the current cursor position.\n * Advances the cursor by one.\n */\nexport function claimChild(parent: Node): Node | null {\n const child = peekChild(parent);\n if (child) {\n setCursor(parent, child.nextSibling);\n }\n return child;\n}\n\n/**\n * Attempts to claim an existing element from the parent during hydration.\n * Returns the claimed element if the next child matches the expected tag, or null.\n */\nexport function claimElement(parent: Node, tagName: string): Element | null {\n if (!_hydrating) return null;\n skipWhitespaceText(parent);\n const candidate = peekChild(parent);\n if (candidate && candidate.nodeType === 1 && (candidate as Element).tagName.toLowerCase() === tagName) {\n return claimChild(parent) as Element;\n }\n return null;\n}\n\n/**\n * Removes unclaimed SSR children from a hydrated element.\n * Must be called after modifiers have been applied to a claimed element.\n * Removes nodes from the cursor through `lastOriginalChild` (the element's\n * last child before modifiers ran) — nodes appended by modifiers come after\n * that boundary and are preserved.\n */\nexport function cleanupUnclaimedChildren(node: Node, lastOriginalChild: Node | null): void {\n if (!lastOriginalChild) return;\n let current = peekChild(node);\n while (current) {\n const next = current === lastOriginalChild ? null : current.nextSibling;\n node.removeChild(current);\n current = next;\n }\n setCursor(node, null);\n}\n","/**\n * Mount/destroy lifecycle hooks.\n *\n * Two equivalent ways to register them, both funneling into this module:\n * - `on(\"mount\", cb)` / `on(\"destroy\", cb)` (./events.ts)\n * - `{ onMount: cb }` / `{ onDestroy: cb }` attributes (./attributes.ts)\n *\n * ── Mount timing ─────────────────────────────────────────────────────────\n * A freshly created element is still detached while its own subtree (and,\n * for the initial page render, every ancestor up to the root) is being\n * assembled — nuclo builds a tree fully off-document before attaching it in\n * one shot (render()/hydrate()), and list()/when() do the same for the\n * rows/branches they insert into an already-connected host. So onMount can't\n * fire the instant a modifier runs; the element is queued and the queue is\n * flushed once the surrounding operation (render(), hydrate(), or update())\n * finishes inserting its nodes — at that point the element is guaranteed\n * connected. See flushMountQueue() and its call sites in render.ts/update.ts.\n *\n * ── Destroy timing ───────────────────────────────────────────────────────\n * onDestroy fires eagerly and synchronously the moment nuclo removes the\n * element through its own machinery — see the disposeElementLifecycle() call\n * in shared/dom.ts's cleanupNodeTree(), which every ordinary removal\n * (list()/when() diffing, any safeRemoveChild() call) already goes through.\n * The handful of fast paths that intentionally skip that per-node walk for\n * performance (list()'s bulk clear/replace, the single-element when()/else()\n * swap) call disposeLifecyclesInSubtree() directly instead, so destroy still\n * fires exactly at removal time there too — without paying for a bookkeeping\n * walk when nothing in the affected subtree ever registered a lifecycle\n * callback (hasActiveLifecycleRegistrations() short-circuits that to a\n * single integer comparison in the — by far most common — case where\n * lifecycle hooks aren't used at all).\n *\n * An element removed through means nuclo never observes (e.g. a raw\n * `node.remove()` on a container built by render()) is only noticed the next\n * time render()/hydrate()/update() runs and finds it disconnected — this\n * file does not use a MutationObserver. That never leaks memory (all\n * bookkeeping below is WeakMap-based, exactly like every other nuclo\n * registry — see test/memory/gc-collectability.test.ts), but if an app\n * removes a node that way and never calls update() again afterwards,\n * onDestroy for it will not run either. This matches list()/when()'s own\n * documented \"disconnection is noticed lazily, on the next update()\"\n * contract; it is not a lifecycle-specific limitation.\n *\n * ── Ordering (parent/child, any depth) ──────────────────────────────────\n * Neither mechanism below cares how many list()s, when()s, or plain\n * component functions wrap an element — every element gets its own\n * independent WeakMap record, keyed by the element itself, so correctness\n * never depends on nesting depth. What nesting *does* affect is the relative\n * order two related elements' callbacks fire in, which follows normal\n * resource-scoping discipline in both directions:\n * - onMount fires parent-before-child. This falls out of queue order for\n * free — a parent's own {onMount}/on(\"mount\", ...) modifier is applied\n * (queuing it) before the child factories in its own modifier list are\n * even invoked, since applying modifiers is a synchronous, in-order walk.\n * A child's onMount can safely assume any context the parent's onMount\n * set up is already in place.\n * - onDestroy fires child-before-parent (see cleanupNodeTree() and\n * disposeLifecyclesInSubtree() in shared/dom.ts, both post-order: they\n * recurse into every descendant *before* disposing the node itself). A\n * parent's onDestroy can safely release something its children were\n * still using — they have already run by the time it does.\n * Together: mount is top-down, destroy is bottom-up — the same order a\n * `try { ... } finally { ... }` stack of nested resource scopes unwinds in,\n * applied to the DOM tree instead of the call stack.\n *\n * ── Memory ───────────────────────────────────────────────────────────────\n * Per-element bookkeeping lives in a WeakMap keyed by the element, so it is\n * collectible the instant nothing else references the element — exactly the\n * same shape as list/runtime.ts's and update/registry.ts's registries. The\n * mountQueue holds only WeakRefs, so abandoned builds are collectible even\n * if no later operation flushes the queue. Completed mount callbacks are\n * released immediately; only their returned cleanup survives until destroy.\n */\n\nimport { logError } from \"../shared/errors\";\nimport { isBrowser } from \"../shared/environment\";\nimport { isSerializing } from \"../hydration\";\n\ntype CallbackSlot<T> = T | T[];\n\n// Plain numeric constants rather than `const enum` — this project's tsconfig\n// enables erasableSyntaxOnly, which `const enum` (a non-erasable construct:\n// it needs its values inlined by the TS compiler itself) is incompatible\n// with. Mirrors the same pattern already used by list/template.ts's\n// LEAF_TEXT/LEAF_CLASSNAME/SLOT_*/ATTR_* constants.\ntype LifecycleStateValue = 0 | 1 | 2;\n/** Registered, not yet flushed (or already disposed before it could be). */\nconst STATE_PENDING: LifecycleStateValue = 0;\nconst STATE_MOUNTED: LifecycleStateValue = 1;\nconst STATE_DISPOSED: LifecycleStateValue = 2;\n\ninterface LifecycleRecord {\n mount: CallbackSlot<MountCallback<Element>> | null;\n destroy: CallbackSlot<DestroyCallback<Element>> | null;\n state: LifecycleStateValue;\n /** True while this element sits in mountQueue awaiting a flush — guards\n * against queuing the same element twice across multiple on()/attribute\n * registrations. */\n queued: boolean;\n}\n\nconst records = new WeakMap<Element, LifecycleRecord>();\n\n/**\n * Count of Pending/Mounted records not yet disposeElementLifecycle()'d. Lets\n * the hot, lifecycle-free removal paths (list() bulk clear, the conditional-\n * element swap) skip disposeLifecyclesInSubtree()'s walk entirely with a\n * single comparison — true for the overwhelming majority of apps, which\n * never use onMount/onDestroy at all.\n *\n * Only ever incremented by ensureRecord() and decremented by\n * disposeElementLifecycle(), so an element GC'd via the raw-removal path\n * documented above (disposed by neither) leaves this one too high until the\n * page's very last such element is finally disposed — never unbounded, and\n * the cost of staying \"on\" a little longer than strictly necessary is just\n * the same cheap WeakMap probe this counter exists to let most apps skip\n * entirely, so it isn't worth a FinalizationRegistry to correct.\n */\nlet activeCount = 0;\n\nlet mountQueue: WeakRef<Element>[] = [];\n\nfunction shouldSkip(): boolean {\n // isSerializing() is checked in addition to isBrowser (unlike on()'s plain\n // DOM-event path) because renderToString() can run under jsdom, where\n // isBrowser is true. A DOM event registered there is inert (nothing ever\n // dispatches it), but a mount callback registered there would actually\n // *run* — including any side effects, like starting a timer or opening a\n // subscription — purely from serializing a page to a string. Skipping\n // registration entirely during serialization avoids that.\n return !isBrowser || isSerializing();\n}\n\nfunction ensureRecord(element: Element): LifecycleRecord {\n let record = records.get(element);\n if (!record) {\n record = { mount: null, destroy: null, state: STATE_PENDING, queued: false };\n records.set(element, record);\n activeCount++;\n }\n return record;\n}\n\nfunction pushSlot<T>(slot: CallbackSlot<T> | null, cb: T): CallbackSlot<T> {\n if (slot === null) return cb;\n if (Array.isArray(slot)) {\n slot.push(cb);\n return slot;\n }\n return [slot, cb];\n}\n\nfunction enqueue(element: Element, record: LifecycleRecord): void {\n if (record.queued || record.state !== STATE_PENDING) return;\n record.queued = true;\n mountQueue.push(new WeakRef(element));\n}\n\n/** Registers a mount callback for `element`. See the module doc for timing. */\nexport function registerMount<TElement extends Element>(\n element: TElement,\n callback: MountCallback<TElement>,\n): void {\n if (shouldSkip()) return;\n const record = ensureRecord(element);\n // Not reachable through the tag-builder DSL (every modifier — on()/attrs —\n // runs once, synchronously, while the element is still Pending) — only via\n // a direct, manual on(\"mount\", cb)(element, 0) call on an element nuclo has\n // already disposed. Dropped rather than stored so it can't grow the\n // record's callback list for an element that will never mount again.\n if (record.state === STATE_DISPOSED) return;\n record.mount = pushSlot(record.mount, callback as MountCallback<Element>);\n enqueue(element, record);\n}\n\n/** Registers a destroy callback for `element`. See the module doc for timing. */\nexport function registerDestroy<TElement extends Element>(\n element: TElement,\n callback: DestroyCallback<TElement>,\n): void {\n if (shouldSkip()) return;\n const record = ensureRecord(element);\n if (record.state === STATE_DISPOSED) return; // see registerMount()\n record.destroy = pushSlot(record.destroy, callback as DestroyCallback<Element>);\n enqueue(element, record);\n}\n\nfunction runMount(element: Element, callback: MountCallback<Element>, record: LifecycleRecord): void {\n if (record.state !== STATE_MOUNTED) return;\n try {\n const cleanup = callback(element);\n if (typeof cleanup === \"function\") {\n // A mount-returned cleanup takes no arguments (matches the\n // useEffect()/onMount() convention) while DestroyCallback is called\n // with the element — but storing it as-is, uncast wrapper, is safe and\n // avoids allocating a closure for every mount that returns one: JS\n // silently ignores call arguments a function doesn't declare, so\n // runDestroy()'s `callback(element)` just calls `cleanup()` with an\n // extra, unused argument.\n // The callback may synchronously remove itself through a nested update.\n if (records.get(element)?.state === STATE_DISPOSED) runDestroy(element, cleanup);\n else record.destroy = pushSlot(record.destroy, cleanup);\n }\n } catch (error) {\n logError(\"Error in mount callback\", error);\n }\n}\n\nfunction runDestroy(element: Element, callback: DestroyCallback<Element>): void {\n try {\n callback(element);\n } catch (error) {\n logError(\"Error in destroy callback\", error);\n }\n}\n\nfunction fireMount(element: Element): void {\n const record = records.get(element);\n if (!record) return;\n record.queued = false;\n // Disposed before its queued turn came up (e.g. built and discarded within\n // the same pass) — the mount never observably happened, so don't fire it.\n if (record.state !== STATE_PENDING) return;\n record.state = STATE_MOUNTED;\n\n const mount = record.mount;\n record.mount = null;\n if (mount === null) return;\n if (Array.isArray(mount)) {\n for (let i = 0; i < mount.length; i++) runMount(element, mount[i], record);\n } else {\n runMount(element, mount, record);\n }\n}\n\n/**\n * Flushes every element queued since the last flush, firing its mount\n * callback(s) now that the surrounding render()/hydrate()/update() pass has\n * finished inserting nodes into the (connected) document.\n *\n * Swaps the shared queue out to a local batch before iterating, so a mount\n * callback that itself triggers a nested update() (which pushes onto a fresh\n * queue and flushes it in its own, inner call) can't corrupt or be corrupted\n * by the batch this call is still draining.\n */\nexport function flushMountQueue(): void {\n if (mountQueue.length === 0) return;\n const batch = mountQueue;\n mountQueue = [];\n for (let i = 0; i < batch.length; i++) {\n const element = batch[i].deref();\n if (element) fireMount(element);\n }\n}\n\n/**\n * Finalizes one element's lifecycle: silently cancels a mount that never got\n * to run (state was still Pending — built and discarded within one pass), or\n * fires its destroy callback(s) (state was Mounted). Idempotent — safe to\n * call more than once for the same element, e.g. once eagerly from\n * cleanupNodeTree() and, redundantly, once more from a fast-path caller that\n * doesn't know whether the eager walk already reached this node.\n */\nexport function disposeElementLifecycle(element: Element): void {\n const record = records.get(element);\n if (!record) return;\n if (record.state === STATE_DISPOSED) return;\n\n const wasMounted = record.state === STATE_MOUNTED;\n record.state = STATE_DISPOSED;\n activeCount--;\n\n if (wasMounted) {\n const destroy = record.destroy;\n if (destroy !== null) {\n if (Array.isArray(destroy)) {\n for (let i = 0; i < destroy.length; i++) runDestroy(element, destroy[i]);\n } else {\n runDestroy(element, destroy);\n }\n }\n }\n\n // Drop references eagerly instead of waiting for the WeakMap entry to be\n // collected along with the element — the callbacks (and anything they\n // closed over) become unreachable from here immediately.\n record.mount = null;\n record.destroy = null;\n}\n\n/**\n * True while at least one element anywhere on the page has a live (Pending\n * or Mounted) lifecycle record. Called by disposeLifecyclesInSubtree() in\n * shared/dom.ts (its own short-circuit) and, hoisted out of its per-row\n * loop, by list/runtime.ts's bulkClearRecords() — so clearing a large\n * lifecycle-free list costs one comparison, not one skipped call per row.\n */\nexport function hasActiveLifecycleRegistrations(): boolean {\n return activeCount > 0;\n}\n","/**\n * Internal factory metadata.\n *\n * Tag builders return opaque factory closures; the list() template engine\n * needs to see through them (tag name + modifier list) to decide whether a\n * row can be built by cloning a skeleton instead of running the factory.\n * The metadata is attached under symbols so nothing leaks into the public\n * API surface or enumerable properties.\n */\n\nexport const FACTORY_TAG = Symbol(\"nuclo.factory.tag\");\nexport const FACTORY_MODS = Symbol(\"nuclo.factory.mods\");\n/**\n * Marks the modifier returned by on() for a native DOM event. Applying it only\n * attaches a listener to its parent (it produces no node and reads no row\n * state), so the list() template engine can replay it on a skeleton clone\n * exactly as the normal build path would.\n */\nexport const EVENT_MODIFIER = Symbol(\"nuclo.event.modifier\");\nlet metadataOnlyFactoryDepth = 0;\n\n/**\n * Metadata-only factories (list() template rows past the first) are read\n * once, via getFactoryTag/getFactoryMods, during the same synchronous render\n * pass that created them, and are never invoked or retained afterward — so a\n * small pool of stub functions can be reused across rows instead of\n * allocating a fresh closure per tag-builder call. Each row checkpoints the\n * pool before rendering and releases its metadata after consumption, including\n * on failure. Nested renders use later slots so they cannot overwrite an\n * outer row's still-live factory tree.\n */\nconst metadataOnlyStubPool: Array<() => null> = [];\nlet metadataOnlyPoolIndex = 0;\n\nexport function acquireMetadataOnlyFactory(): () => null {\n if (metadataOnlyPoolIndex >= metadataOnlyStubPool.length) {\n metadataOnlyStubPool.push(() => null);\n }\n return metadataOnlyStubPool[metadataOnlyPoolIndex++]!;\n}\n\ninterface TaggedFactory {\n [FACTORY_TAG]?: string;\n [FACTORY_MODS]?: readonly unknown[];\n}\n\nexport function setFactoryMeta(\n factory: unknown,\n tag: string,\n mods: readonly unknown[],\n): void {\n (factory as TaggedFactory)[FACTORY_TAG] = tag;\n (factory as TaggedFactory)[FACTORY_MODS] = mods;\n}\n\n/** Returns the modifier list of a tag-builder factory, or undefined. */\nexport function getFactoryMods(fn: unknown): readonly unknown[] | undefined {\n return typeof fn === \"function\" ? (fn as TaggedFactory)[FACTORY_MODS] : undefined;\n}\n\n/** Returns the tag name of a tag-builder factory, or undefined. */\nexport function getFactoryTag(fn: unknown): string | undefined {\n return typeof fn === \"function\" ? (fn as TaggedFactory)[FACTORY_TAG] : undefined;\n}\n\nexport function markEventModifier<T extends object>(fn: T): T {\n (fn as { [EVENT_MODIFIER]?: boolean })[EVENT_MODIFIER] = true;\n return fn;\n}\n\n/** True for a modifier returned by on() for a native DOM event. */\nexport function isEventModifier(fn: unknown): boolean {\n return typeof fn === \"function\" && (fn as { [EVENT_MODIFIER]?: boolean })[EVENT_MODIFIER] === true;\n}\n\nexport function isMetadataOnlyFactoryMode(): boolean {\n return metadataOnlyFactoryDepth > 0;\n}\n\n/**\n * Takes the render function and its two args directly (rather than a `() =>`\n * thunk) so the hot per-row call in list/runtime.ts doesn't allocate a\n * closure just to defer a single call.\n */\nexport function withMetadataOnlyFactories<TItem, T>(fn: (item: TItem, index: number) => T, item: TItem, index: number): T {\n metadataOnlyFactoryDepth++;\n try {\n return fn(item, index);\n } finally {\n metadataOnlyFactoryDepth--;\n }\n}\n\nexport function getMetadataOnlyFactoryCheckpoint() {\n return metadataOnlyPoolIndex;\n}\n\nexport function releaseMetadataOnlyFactories(checkpoint: number) {\n while (metadataOnlyPoolIndex > checkpoint) {\n const factory = metadataOnlyStubPool[--metadataOnlyPoolIndex] as TaggedFactory;\n factory[FACTORY_TAG] = undefined;\n factory[FACTORY_MODS] = undefined;\n }\n}\n","/**\n * Typed event listener helper.\n *\n * Usage:\n * button(\n * \"Click\",\n * on(\"click\", (e) => {\n * // e and currentTarget are inferred from the native event map\n * })\n * )\n *\n * Design notes:\n * - Returns a NodeModFn so it can be used like any other modifier.\n * - Produces no child node (returns void in the modifier body).\n * - Provides strong typing of the event object based on the DOM event name.\n * - Stores listener references in a WeakMap to prevent memory leaks.\n * - Listeners are automatically cleaned up when elements are garbage collected.\n */\n\nimport { logError } from \"../shared/errors\";\nimport { isBrowser } from \"../shared/environment\";\nimport { registerMount, registerDestroy } from \"./lifecycle\";\nimport { markEventModifier } from \"./factory-meta\";\n\ntype EventListenerOptions = boolean | AddEventListenerOptions;\n\ninterface TrackedListener {\n type: string;\n wrapped: EventListener;\n capture: boolean;\n}\n\ntype TrackedListeners = TrackedListener | TrackedListener[];\n\n/**\n * Tracks attached listeners per element so removeAllListeners() can detach them.\n *\n * The common single-listener case stores its registration directly. An array\n * is allocated only when an element has multiple distinct listeners. A\n * registration belongs to the reusable modifier rather than an attachment, so\n * applying one modifier to many elements adds no per-element metadata objects.\n * Only the capture flag is retained because it is the sole option compared by\n * removeEventListener.\n */\nconst elementListeners = new WeakMap<HTMLElement, TrackedListeners>();\n\n/**\n * Store listener info for an element to enable cleanup.\n */\nfunction trackListener(\n element: HTMLElement,\n info: TrackedListener,\n): void {\n const tracked = elementListeners.get(element);\n if (!tracked) {\n elementListeners.set(element, info);\n } else if (Array.isArray(tracked)) {\n if (!tracked.includes(info)) tracked.push(info);\n } else if (tracked !== info) {\n elementListeners.set(element, [tracked, info]);\n }\n}\n\n/**\n * Detach a single tracked listener from the DOM.\n */\nfunction detachListener(\n element: HTMLElement,\n info: TrackedListener,\n): void {\n element.removeEventListener(info.type, info.wrapped, info.capture);\n}\n\n/**\n * Remove all listeners of a specific type from an element.\n */\nexport function removeAllListeners(\n element: HTMLElement,\n type?: string\n): void {\n const tracked = elementListeners.get(element);\n if (!tracked) return;\n\n if (type === undefined) {\n if (Array.isArray(tracked)) {\n for (let i = 0; i < tracked.length; i++) {\n detachListener(element, tracked[i]);\n }\n } else {\n detachListener(element, tracked);\n }\n elementListeners.delete(element);\n return;\n }\n\n if (!Array.isArray(tracked)) {\n if (tracked.type === type) {\n detachListener(element, tracked);\n elementListeners.delete(element);\n }\n return;\n }\n\n // Detach matching listeners, compacting survivors back into the same array.\n let write = 0;\n for (let read = 0; read < tracked.length; read++) {\n const info = tracked[read];\n if (info.type === type) {\n detachListener(element, info);\n } else {\n tracked[write++] = info;\n }\n }\n if (write === 0) {\n elementListeners.delete(element);\n } else if (write === 1) {\n elementListeners.set(element, tracked[0]);\n } else {\n tracked.length = write;\n }\n}\n\nfunction noopEventModifier(_parent: ExpandedElement<ElementTagName>): void {}\n\n/**\n * \"mount\"/\"destroy\" are pseudo-events: there is no native DOM event to\n * addEventListener for, so on()'s runtime dispatches them here instead of\n * through createTrackedListener(). See element/lifecycle.ts for what\n * registerMount()/registerDestroy() actually do and when the callback fires.\n */\nfunction createLifecycleModifier<TTagName extends ElementTagName>(\n kind: \"mount\" | \"destroy\",\n callback: (element: HTMLElementTagNameMap[TTagName]) => unknown,\n): NodeModFn<TTagName> {\n if (!isBrowser) return noopEventModifier as NodeModFn<TTagName>;\n\n return function(parent: ExpandedElement<TTagName>): void {\n if (!parent) return;\n const el = parent as unknown as HTMLElementTagNameMap[TTagName];\n if (kind === \"mount\") {\n registerMount(el, callback as MountCallback<HTMLElementTagNameMap[TTagName]>);\n } else {\n registerDestroy(el, callback as DestroyCallback<HTMLElementTagNameMap[TTagName]>);\n }\n };\n}\n\nfunction createTrackedListener<TTagName extends ElementTagName>(\n type: string,\n listener: TypedEventListener<HTMLElementTagNameMap[TTagName], Event>,\n capture: boolean,\n): TrackedListener {\n const wrapped = function(this: EventTarget, event: Event): void {\n const currentTarget = this as HTMLElementTagNameMap[TTagName];\n try {\n listener.call(\n currentTarget,\n event as Event & { currentTarget: HTMLElementTagNameMap[TTagName] },\n );\n } catch (error) {\n logError(`Error in '${type}' listener`, error);\n }\n };\n\n return { type, wrapped, capture };\n}\n\n/**\n * Overload for standard HTMLElement events (strongly typed via lib.dom.d.ts)\n */\nexport function on<\n K extends NucloHTMLElementEventName,\n TTagName extends NucloHTMLElementTagNameForEvent<K> = NucloHTMLElementTagNameForEvent<K>,\n>(\n type: K,\n listener: TypedEventListener<\n HTMLElementTagNameMap[TTagName],\n NucloHTMLElementEventForName<K>\n >,\n options?: EventListenerOptions\n): NodeModFn<TTagName>;\n\n/**\n * Fires once, after the element has been created and connected to the live\n * document. Equivalent to `{ onMount: ... }`. May return a cleanup function —\n * equivalent to also registering it with on(\"destroy\", ...).\n *\n * Listed before the generic string overload below on purpose: \"mount\" is a\n * string too, so a less specific overload earlier would shadow this one.\n */\nexport function on<TTagName extends ElementTagName = ElementTagName>(\n type: \"mount\",\n listener: MountCallback<HTMLElementTagNameMap[TTagName]>,\n): NodeModFn<TTagName>;\n\n/** Fires once the element has been removed. Equivalent to `{ onDestroy: ... }`. */\nexport function on<TTagName extends ElementTagName = ElementTagName>(\n type: \"destroy\",\n listener: DestroyCallback<HTMLElementTagNameMap[TTagName]>,\n): NodeModFn<TTagName>;\n\n/**\n * Fallback / custom event overload (arbitrary event names or custom event types).\n * Specify a custom event type with the E generic if needed:\n * on<\"my-event\", CustomEvent<MyDetail>>(\"my-event\", e => { ... })\n */\nexport function on<\n K extends string,\n E extends Event = Event,\n TTagName extends ElementTagName = ElementTagName\n>(\n type: K,\n listener: TypedEventListener<HTMLElementTagNameMap[TTagName], E>,\n options?: EventListenerOptions\n): NodeModFn<TTagName>;\n\nexport function on<TTagName extends ElementTagName = ElementTagName>(\n type: string,\n listener:\n | TypedEventListener<HTMLElementTagNameMap[TTagName], Event>\n | MountCallback<HTMLElementTagNameMap[TTagName]>\n | DestroyCallback<HTMLElementTagNameMap[TTagName]>,\n options?: EventListenerOptions\n): NodeModFn<TTagName> {\n if (type === \"mount\" || type === \"destroy\") {\n return createLifecycleModifier<TTagName>(\n type,\n listener as (element: HTMLElementTagNameMap[TTagName]) => unknown,\n );\n }\n\n if (!isBrowser) return noopEventModifier as NodeModFn<TTagName>;\n\n const capture = options === true\n || (options !== null && typeof options === \"object\" && options.capture === true);\n // type is neither \"mount\" nor \"destroy\" past the check above, so listener\n // is really the TypedEventListener member of the union — TS can't narrow a\n // union on a check of a different parameter, hence the cast.\n const info = createTrackedListener(\n type,\n listener as TypedEventListener<HTMLElementTagNameMap[TTagName], Event>,\n capture,\n );\n\n // Marked so list() row templates can replay it on cloned rows instead of\n // falling back to a full per-row build (see list/template.ts SLOT_EVENT).\n return markEventModifier(function(parent: ExpandedElement<TTagName>): void {\n // Type guard: verify parent is an HTMLElement with addEventListener\n if (!parent || typeof (parent as HTMLElement).addEventListener !== \"function\") {\n return;\n }\n\n const el = parent as HTMLElementTagNameMap[TTagName];\n\n el.addEventListener(type, info.wrapped, options);\n\n // Track the listener so removeAllListeners() can detach it later.\n trackListener(el, info);\n });\n}\n","/**\n * Shared types and registries for reactive nodes.\n * Single source of truth — imported by reactiveText.ts and reactiveAttributes.ts.\n *\n * Registry structure: the iteration sets only hold WeakRefs; the actual info\n * records live in WeakMaps keyed by the node. Info records may strongly\n * reference the node (e.g. attribute applyValue closures capture the\n * element), so storing them in a strongly-held map would pin the node in\n * memory forever. With WeakMap storage the whole record is collectible as\n * soon as the node is unreachable.\n *\n * Dead WeakRefs left in the iteration sets are pruned by the notify passes as\n * they iterate (deref() === undefined, or node disconnected). Registration is\n * the hottest path in list-heavy renders (one text node + often one element\n * per row), so no per-node FinalizationRegistry is used here: its register()\n * cost per row outweighs keeping the sets tidy between updates, and a stale\n * husk is just an empty WeakRef until the next update() sweeps it.\n */\n\nexport type TextResolver = () => Primitive;\n\nexport interface ReactiveTextNodeInfo {\n resolver: TextResolver;\n lastValue: string;\n /**\n * DSL semantics: nullish and non-primitive resolver results render as \"\"\n * (instead of String(value)). Set by the tag-builder text path so it can\n * register the user's resolver directly rather than allocating a\n * sanitizing wrapper closure per text node.\n */\n sanitize?: boolean;\n}\n\nexport type AttributeResolver = () => unknown;\n\nexport interface AttributeResolverRecord {\n key: string;\n resolver: AttributeResolver;\n applyValue: (value: unknown) => void;\n lastValue: unknown;\n}\n\nexport interface ReactiveElementInfo {\n /**\n * Flat keyed array rather than a Map: elements almost always carry one or\n * two reactive attributes, so linear key lookup on registration beats a Map\n * allocation per element, and the per-update flush iterates with a plain\n * index loop (no iterator/destructuring allocations).\n */\n attributeResolvers: AttributeResolverRecord[];\n}\n\n/**\n * Iteration set of weak references to reactive text nodes.\n */\nexport const reactiveTextNodes = new Set<WeakRef<Text>>();\n\n/**\n * WeakMap for O(1) lookups of reactive text node info by node reference.\n */\nexport const reactiveTextNodesByNode = new WeakMap<Text, { ref: WeakRef<Text>; info: ReactiveTextNodeInfo }>();\n\n/**\n * Iteration set of weak references to reactive elements.\n */\nexport const reactiveElements = new Set<WeakRef<Element>>();\n\n/**\n * WeakMap for O(1) lookups of reactive element info by element reference.\n */\nexport const reactiveElementsByNode = new WeakMap<Element, { ref: WeakRef<Element>; info: ReactiveElementInfo }>();\n\n/**\n * Registers a reactive text node in both lookup structures.\n */\nexport function registerReactiveTextNode(node: Text, info: ReactiveTextNodeInfo): void {\n const existing = reactiveTextNodesByNode.get(node);\n if (existing) {\n // Re-registration (e.g. repeated hydration): replace the info in place.\n existing.info.resolver = info.resolver;\n existing.info.lastValue = info.lastValue;\n existing.info.sanitize = info.sanitize;\n return;\n }\n const ref = new WeakRef(node);\n reactiveTextNodes.add(ref);\n reactiveTextNodesByNode.set(node, { ref, info });\n}\n\n/**\n * Registers a reactive element in both lookup structures.\n */\nexport function registerReactiveElement(element: Element, info: ReactiveElementInfo): void {\n const existing = reactiveElementsByNode.get(element);\n if (existing) {\n existing.info = info;\n return;\n }\n const ref = new WeakRef(element);\n reactiveElements.add(ref);\n reactiveElementsByNode.set(element, { ref, info });\n}\n\n/**\n * Removes a reactive text node's WeakRef entry from the iteration set.\n */\nexport function removeReactiveTextNodeRef(ref: WeakRef<Text>): void {\n reactiveTextNodes.delete(ref);\n}\n\n/**\n * Removes a reactive element's WeakRef entry from the iteration set.\n */\nexport function removeReactiveElementRef(ref: WeakRef<Element>): void {\n reactiveElements.delete(ref);\n}\n\n/**\n * Manually removes reactive text node info for a specific text node.\n * This should be called when a text node is removed from the DOM to prevent memory leaks.\n */\nexport function cleanupReactiveTextNode(node: Text): void {\n const entry = reactiveTextNodesByNode.get(node);\n if (entry) {\n reactiveTextNodes.delete(entry.ref);\n reactiveTextNodesByNode.delete(node);\n }\n}\n\n/**\n * Manually removes reactive element info for a specific element.\n * This should be called when an element is removed from the DOM to prevent memory leaks.\n */\nexport function cleanupReactiveElement(element: Element): void {\n const entry = reactiveElementsByNode.get(element);\n if (entry) {\n reactiveElements.delete(entry.ref);\n reactiveElementsByNode.delete(element);\n }\n}\n\n// ─── Conditional elements ────────────────────────────────────────────────────\n// Same idea as above, but for nodes created by conditional rendering: the\n// registry remembers each node's condition + modifiers so update() can\n// re-evaluate and swap the element in place.\n\nexport interface ConditionalInfo<TTagName extends ElementTagName = ElementTagName> {\n\tcondition: () => boolean;\n\ttagName: TTagName;\n\tmodifiers: Array<NodeMod<TTagName> | NodeModFn<TTagName>>;\n\tisSvg: boolean;\n}\n\n// WeakMap replaces the _conditionalInfo expando property — zero `any`, no DOM pollution, auto-GC.\nconst conditionalInfoMap = new WeakMap<Node, ConditionalInfo<ElementTagName>>();\n\n/**\n * Registry of all nodes that have conditional info attached.\n * Uses WeakRef to prevent memory leaks — allows garbage collection of removed nodes.\n * This enables O(nConditionals) updates instead of a full DOM tree walk.\n */\nconst activeConditionalNodes = new Set<WeakRef<Node>>();\n\n/**\n * Reverse lookup for O(1) unregister — maps node to its WeakRef in the active set.\n */\nconst refByNode = new WeakMap<Node, WeakRef<Node>>();\n\n/**\n * Prunes dead WeakRefs from the active set as soon as their node is\n * collected, instead of waiting for the next getActiveConditionalNodes() pass.\n */\nconst conditionalNodeFinalizer = typeof FinalizationRegistry !== \"undefined\"\n\t? new FinalizationRegistry<WeakRef<Node>>((ref) => { activeConditionalNodes.delete(ref); })\n\t: null;\n\n/**\n * Attach conditional info to a node and register it.\n */\nexport function storeConditionalInfo<TTagName extends ElementTagName>(\n\tnode: Node,\n\tinfo: ConditionalInfo<TTagName>\n): void {\n\tconditionalInfoMap.set(node, info as ConditionalInfo<ElementTagName>);\n\tif (refByNode.has(node)) return;\n\tconst ref = new WeakRef(node);\n\tactiveConditionalNodes.add(ref);\n\trefByNode.set(node, ref);\n\tconditionalNodeFinalizer?.register(node, ref, ref);\n}\n\n/**\n * Explicit unregister helper (optional use on teardown if needed).\n * O(1) via reverse lookup WeakMap.\n */\nexport function unregisterConditionalNode(node: Node): void {\n\tconditionalInfoMap.delete(node);\n\tconst ref = refByNode.get(node);\n\tif (ref) {\n\t\tactiveConditionalNodes.delete(ref);\n\t\tconditionalNodeFinalizer?.unregister(ref);\n\t\trefByNode.delete(node);\n\t}\n}\n\n/**\n * Returns an array of currently tracked conditional nodes that are still alive.\n * Automatically cleans up garbage-collected nodes.\n */\nexport function getActiveConditionalNodes(): Node[] {\n\tconst nodes: Node[] = [];\n\n\tfor (const ref of activeConditionalNodes) {\n\t\tconst node = ref.deref();\n\t\tif (node === undefined) {\n\t\t\tactiveConditionalNodes.delete(ref);\n\t\t} else {\n\t\t\tnodes.push(node);\n\t\t}\n\t}\n\n\treturn nodes;\n}\n\nexport function getConditionalInfo(node: Node): ConditionalInfo<ElementTagName> | null {\n\treturn conditionalInfoMap.get(node) ?? null;\n}\n","import { logError } from \"./errors\";\nimport { removeAllListeners } from \"../element/events\";\nimport { cleanupReactiveTextNode, cleanupReactiveElement, unregisterConditionalNode } from \"../update/registry\";\nimport { disposeElementLifecycle, hasActiveLifecycleRegistrations } from \"../element/lifecycle\";\n\nexport const SVG_NAMESPACE = 'http://www.w3.org/2000/svg';\n\n/**\n * Creates an HTML element.\n * Wrapper for document.createElement with type safety.\n */\nexport function createElement<K extends keyof HTMLElementTagNameMap>(\n tagName: K\n): HTMLElementTagNameMap[K] | null;\nexport function createElement(tagName: string): ExpandedElement | null;\nexport function createElement(tagName: string): ExpandedElement | null {\n return globalThis.document ? document.createElement(tagName) as ExpandedElement : null;\n}\n\n/**\n * Creates an element in the given namespace (typically for SVG elements).\n * Wrapper for document.createElementNS with type safety.\n */\nexport function createElementNS(\n namespace: string,\n tagName: string\n): ExpandedElement | null {\n return globalThis.document ? document.createElementNS(namespace, tagName) as ExpandedElement : null;\n}\n\n/**\n * Creates a text node with the given content.\n * Wrapper for document.createTextNode.\n */\nexport function createTextNode(text: string): Text | null {\n return globalThis.document ? document.createTextNode(text) : null;\n}\n\n/**\n * Creates a document fragment.\n * Wrapper for document.createDocumentFragment.\n */\nexport function createDocumentFragment(): DocumentFragment | null {\n return globalThis.document ? document.createDocumentFragment() : null;\n}\n\nfunction safeAppendChild(parent: Element | Node, child: Node): boolean {\n try {\n parent.appendChild(child);\n return true;\n } catch (error) {\n logError('Failed to append child node', error);\n return false;\n }\n}\n\n/**\n * Recursively removes all event listeners and reactive subscriptions from a node and its descendants\n * to prevent memory leaks when elements are removed from the DOM.\n */\nfunction cleanupNodeTree(node: Node): void {\n // Clean up the node itself based on its type. Order-independent bookkeeping\n // (listeners, reactive registrations) runs up front; onDestroy is fired\n // below, after descendants — see the comment there.\n if (node.nodeType === Node.ELEMENT_NODE) {\n const element = node as HTMLElement;\n // Remove all event listeners\n removeAllListeners(element);\n // Remove reactive attribute resolvers\n cleanupReactiveElement(element);\n // Remove conditional info\n unregisterConditionalNode(element);\n } else if (node.nodeType === Node.TEXT_NODE) {\n // Remove reactive text node info\n cleanupReactiveTextNode(node as Text);\n } else if (node.nodeType === Node.COMMENT_NODE) {\n // Remove conditional info from comment nodes (used by when/list)\n unregisterConditionalNode(node);\n }\n\n // Recursively clean up all child nodes\n // Destroy callbacks can mutate the live childNodes collection. Snapshot\n // only when hooks exist; ordinary cleanup needs no additional allocation.\n const children = hasActiveLifecycleRegistrations() ? Array.from(node.childNodes) : node.childNodes;\n for (let i = 0; i < children.length; i++) {\n cleanupNodeTree(children[i]);\n }\n\n // Fire onDestroy last — after every descendant's onDestroy has already run\n // (post-order) — so a parent's teardown can rely on its children having\n // already released whatever they were using (e.g. a subscription or timer\n // the parent owns and children only read from). This mirrors onMount's own\n // order, which is naturally parent-before-child (registration order is\n // construction order: a parent's own onMount/{onMount} modifier is applied\n // before its child factories are even invoked) — so mount is top-down,\n // destroy is bottom-up, the same LIFO discipline nested resource scopes\n // always use. No-op unless this exact element registered a callback.\n if (node.nodeType === Node.ELEMENT_NODE) {\n disposeElementLifecycle(node as HTMLElement);\n }\n}\n\n/**\n * Fires onDestroy for a subtree that a fast removal path (list()'s bulk\n * clear/replace, the single-element when()/else() swap) is about to drop\n * without walking through cleanupNodeTree()/safeRemoveChild(). Short-circuits\n * to a single comparison when nothing on the page has ever registered a\n * lifecycle callback — the common case — so those fast paths stay fast.\n *\n * Same post-order (children, then self) as cleanupNodeTree() above, for the\n * same reason — see the comment there.\n */\nexport function disposeLifecyclesInSubtree(node: Node): void {\n if (!hasActiveLifecycleRegistrations()) return;\n const children = Array.from(node.childNodes);\n for (let i = 0; i < children.length; i++) {\n disposeLifecyclesInSubtree(children[i]);\n }\n if (node.nodeType === Node.ELEMENT_NODE) {\n disposeElementLifecycle(node as Element);\n }\n}\n\nexport function safeRemoveChild(child: Node): boolean {\n if (!child?.parentNode) return false;\n try {\n // Clean up all event listeners before removing the element\n cleanupNodeTree(child);\n // A destroy callback may already have removed the node.\n child.parentNode?.removeChild(child);\n return true;\n } catch (error) {\n logError('Failed to remove child node', error);\n return false;\n }\n}\n\nfunction safeInsertBefore(parent: Node, newNode: Node, referenceNode: Node | null): boolean {\n try {\n parent.insertBefore(newNode, referenceNode);\n return true;\n } catch (error) {\n logError('Failed to insert node before reference', error);\n return false;\n }\n}\n\nexport function createComment(text: string): Comment | null {\n return globalThis.document ? globalThis.document.createComment(text) : null;\n}\n\nexport function createConditionalComment(tagName: string, suffix = \"hidden\"): Comment | null {\n return globalThis.document ? globalThis.document.createComment(`conditional-${tagName}-${suffix}`) : null;\n}\n\nexport function createMarkerPair(prefix: string, id: number | string): { start: Comment; end: Comment } {\n const endComment = createComment(`${prefix}-end`);\n if (!endComment) throw new Error(\"Failed to create comment: document not available\");\n const startComment = createComment(`${prefix}-start-${id}`);\n if (!startComment) throw new Error(\"Failed to create comment: document not available\");\n return { start: startComment, end: endComment };\n}\n\nexport function clearBetweenMarkers(startMarker: Comment, endMarker: Comment): void {\n let current = startMarker.nextSibling;\n while (current && current !== endMarker) {\n const next = current.nextSibling;\n safeRemoveChild(current);\n current = next;\n }\n}\n\nexport function insertNodesBefore(nodes: Node[], referenceNode: Node): void {\n const parent = referenceNode.parentNode;\n if (parent) {\n for (let i = 0; i < nodes.length; i++) {\n safeInsertBefore(parent, nodes[i], referenceNode);\n }\n }\n}\n\nexport function appendChildren(\n parent: Element | Node,\n ...children: Array<Element | Node | string | null | undefined>\n): Element | Node {\n if (!parent) return parent;\n\n for (let i = 0; i < children.length; i++) {\n const child = children[i];\n if (child != null) {\n let nodeToAppend: Node;\n\n if (typeof child === \"string\") {\n const textNode = createTextNode(child);\n if (textNode) {\n nodeToAppend = textNode;\n } else {\n continue;\n }\n } else {\n nodeToAppend = child as Node;\n }\n\n safeAppendChild(parent, nodeToAppend);\n }\n }\n\n return parent;\n}\n\nexport function isNodeConnected(node: Node | null | undefined): boolean {\n return node?.isConnected === true;\n}\n\n/**\n * Safely replaces an old node with a new node in the DOM.\n * Returns true on success, false on failure (and logs the error).\n */\nexport function replaceNodeSafely(oldNode: Node, newNode: Node): boolean {\n if (!oldNode?.parentNode) return false;\n try {\n oldNode.parentNode.replaceChild(newNode, oldNode);\n return true;\n } catch (error) {\n logError(\"Error replacing conditional node\", error);\n return false;\n }\n}\n\n// ─── Type-safe DOM helpers ───────────────────────────────────────────────────\n\n/**\n * Safely casts an Element-like object to Node & ParentNode interface.\n * This is a common pattern needed when working with DOM manipulation.\n *\n * @param element - The element to cast\n * @returns The element typed as Node & ParentNode\n */\nexport function asParentNode<T extends Element | object>(element: T): Node & ParentNode {\n return element as unknown as Node & ParentNode;\n}\n\n/**\n * Creates a scoped DOM insertion context that temporarily redirects appendChild\n * to insertBefore at a specific reference node. This is useful for inserting\n * content at specific positions in the DOM tree.\n *\n * @param host - The host element\n * @param referenceNode - The node before which new nodes should be inserted\n * @param callback - Function to execute with the scoped context\n * @returns The result of the callback\n */\nexport function withScopedInsertion<T, THost extends Element | object>(\n host: THost,\n referenceNode: Node,\n callback: () => T\n): T {\n const parent = asParentNode(host);\n const originalAppend = Object.getOwnPropertyDescriptor(parent, \"appendChild\");\n const originalInsert = parent.insertBefore;\n\n // Temporarily override appendChild to insert before the reference node\n // TypeScript doesn't like this override but it's safe at runtime\n (parent as unknown as Record<string, unknown>).appendChild = function(node: Node): Node {\n return originalInsert.call(parent, node, referenceNode);\n };\n\n try {\n return callback();\n } finally {\n // Restore original method\n if (originalAppend) Object.defineProperty(parent, \"appendChild\", originalAppend);\n else Reflect.deleteProperty(parent, \"appendChild\");\n }\n}\n\n/**\n * Type-safe wrapper for setting CSS style properties.\n * Provides better error handling than direct CSSStyleDeclaration access.\n * Supports both camelCase and kebab-case property names.\n *\n * @param element - The element to apply styles to\n * @param property - The CSS property name (camelCase or kebab-case)\n * @param value - The value to set (string, number, or null to remove)\n * @returns true if the style was applied successfully, false otherwise\n */\nexport function setStyleProperty(\n element: HTMLElement,\n property: string,\n value: string | number | null\n): boolean {\n try {\n if (value === null || value === undefined || value === '') {\n // Use bracket notation to remove property (works with camelCase)\n (element.style as unknown as Record<string, string>)[property] = '';\n return true;\n }\n\n // Convert value to string first (might throw if toString() throws)\n const stringValue = String(value);\n // Use bracket notation to set property (works with camelCase)\n (element.style as unknown as Record<string, string>)[property] = stringValue;\n return true;\n } catch {\n return false;\n }\n}\n","import { logError } from \"../shared/errors\";\nimport { isNodeConnected } from \"../shared/dom\";\nimport type { UpdateScope } from \"./scope\";\nimport { reactiveElements, reactiveElementsByNode, registerReactiveElement, removeReactiveElementRef } from \"./registry\";\nimport type { AttributeResolver, AttributeResolverRecord, ReactiveElementInfo } from \"./registry\";\nimport { isBrowser } from \"../shared/environment\";\n\nconst UNSET_LAST_VALUE = {};\nlet updateEventListenerRegistered = false;\n\nfunction handleUpdateEvent(event: Event): void {\n // Update all reactive elements on the event's target ancestor chain.\n // This preserves the \"dispatchEvent(new Event('update'))\" workflow without\n // per-element event listeners.\n const target = event.target;\n if (!target || typeof Node === \"undefined\" || !(target instanceof Node)) return;\n\n let node: Node | null = target;\n while (node) {\n if (node instanceof Element) {\n const entry = reactiveElementsByNode.get(node);\n if (entry) {\n if (!isNodeConnected(node)) {\n removeReactiveElementRef(entry.ref);\n reactiveElementsByNode.delete(node);\n } else {\n applyAttributeResolvers(entry.info);\n }\n }\n }\n node = node.parentNode;\n }\n}\n\nfunction ensureGlobalUpdateEventListener(): void {\n if (updateEventListenerRegistered) return;\n if (typeof document === \"undefined\" || typeof document.addEventListener !== \"function\") return;\n document.addEventListener(\"update\", handleUpdateEvent, true);\n updateEventListenerRegistered = true;\n}\n\nfunction ensureElementInfo(el: Element): ReactiveElementInfo {\n const entry = reactiveElementsByNode.get(el);\n if (entry) return entry.info;\n\n // No existing info, create new\n const info: ReactiveElementInfo = { attributeResolvers: [] };\n registerReactiveElement(el, info);\n return info;\n}\n\nfunction isCacheableValue(value: unknown): boolean {\n // Avoid caching objects/arrays that may be mutated in place (e.g. style objects).\n return value === null || typeof value !== \"object\";\n}\n\nfunction updateAttributeResolverRecord(record: AttributeResolverRecord): void {\n let nextValue: unknown;\n try {\n nextValue = record.resolver();\n } catch (e) {\n logError(`Failed to resolve reactive attribute: ${record.key}`, e);\n return;\n }\n\n const cacheable = isCacheableValue(nextValue);\n if (cacheable && Object.is(nextValue, record.lastValue)) return;\n\n try {\n record.applyValue(nextValue);\n record.lastValue = cacheable ? nextValue : UNSET_LAST_VALUE;\n } catch (e) {\n logError(`Failed to apply reactive attribute: ${record.key}`, e);\n }\n}\n\nfunction applyAttributeResolvers(info: ReactiveElementInfo): void {\n const resolvers = info.attributeResolvers;\n for (let i = 0; i < resolvers.length; i++) {\n updateAttributeResolverRecord(resolvers[i]);\n }\n}\n\n/**\n * Registers a reactive attribute resolver for an element.\n *\n * The resolver will be called whenever reactive updates run (e.g. via `update()`),\n * or when an `\"update\"` event is dispatched on the element (or a descendant),\n * allowing attributes to reactively update based on application state.\n *\n * @param element - The DOM element to make reactive\n * @param key - The attribute name being made reactive (e.g., 'class', 'style', 'disabled')\n * @param resolver - Function that returns the new attribute value\n * @param applyValue - Callback that applies the resolved value to the element\n *\n * @example\n * ```ts\n * const isActive = signal(false);\n * const button = document.createElement('button');\n * registerAttributeResolver(\n * button,\n * 'class',\n * () => isActive.value ? 'active' : 'inactive',\n * (value) => button.className = String(value)\n * );\n * ```\n */\nexport function registerAttributeResolver<TTagName extends ElementTagName>(\n element: ExpandedElement<TTagName>,\n key: string,\n resolver: AttributeResolver,\n applyValue: (value: unknown) => void\n): void {\n if (!(element instanceof Element) || !key || typeof resolver !== \"function\") {\n logError(\"Invalid parameters for registerAttributeResolver\");\n return;\n }\n\n const record: AttributeResolverRecord = { key, resolver, applyValue, lastValue: UNSET_LAST_VALUE };\n\n if (!isBrowser) {\n // SSR: just apply once, no registration needed (update() is never called server-side)\n updateAttributeResolverRecord(record);\n return;\n }\n\n ensureGlobalUpdateEventListener();\n const info = ensureElementInfo(element as Element);\n // Re-registration for a key replaces its record (previous Map.set semantics).\n const resolvers = info.attributeResolvers;\n let replaced = false;\n for (let i = 0; i < resolvers.length; i++) {\n if (resolvers[i].key === key) {\n resolvers[i] = record;\n replaced = true;\n break;\n }\n }\n if (!replaced) resolvers.push(record);\n updateAttributeResolverRecord(record);\n}\n\n/**\n * Updates all registered reactive elements by re-evaluating their attribute resolvers.\n *\n * Iterates through all reactive elements and triggers their registered attribute resolvers\n * to update. Automatically cleans up disconnected elements and their event listeners.\n *\n * This function should be called after state changes to synchronize element attributes\n * with application state.\n *\n * @example\n * ```ts\n * // After updating application state\n * isActive.value = true;\n * notifyReactiveElements(); // All reactive attributes update\n * ```\n */\nexport function notifyReactiveElements(scope?: UpdateScope): void {\n for (const ref of reactiveElements) {\n const el = ref.deref();\n if (el === undefined) {\n removeReactiveElementRef(ref);\n continue;\n }\n\n const entry = reactiveElementsByNode.get(el);\n if (!entry) {\n removeReactiveElementRef(ref);\n continue;\n }\n\n if (!isNodeConnected(el)) {\n reactiveElementsByNode.delete(el);\n removeReactiveElementRef(ref);\n continue;\n }\n\n if (scope && !scope.contains(el)) continue;\n applyAttributeResolvers(entry.info);\n }\n\n}\n","import { isFunction } from \"../shared/type-guards\";\nimport { registerAttributeResolver } from \"../update/reactive-attributes\";\nimport { setStyleProperty } from \"../shared/dom\";\nimport { logError } from \"../shared/errors\";\n\ntype StyleAssignment = CSSStyleObject;\ntype StyleResolver = () => StyleAssignment | null | undefined;\n\n/**\n * Simplified style management - basic functionality with minimal overhead\n */\nexport function assignInlineStyles<TTagName extends ElementTagName>(\n element: ExpandedElement<TTagName>,\n styles: StyleAssignment | null | undefined,\n): void {\n if (!element?.style || !styles) return;\n\n for (const property in styles) {\n const success = setStyleProperty(\n element as HTMLElement,\n property,\n (styles as Record<string, string | number | null>)[property]\n );\n\n if (!success) {\n // Don't try to stringify value in error message as it might throw\n logError(`Failed to set style property '${property}'`);\n }\n }\n}\n\nexport function applyStyleAttribute<TTagName extends ElementTagName>(\n element: ExpandedElement<TTagName>,\n styleValue: StyleAssignment | StyleResolver | null | undefined\n): void {\n if (!element) return;\n\n if (isFunction(styleValue)) {\n registerAttributeResolver(element, 'style', styleValue, function(resolvedStyles) {\n assignInlineStyles(element, resolvedStyles as StyleAssignment);\n });\n } else {\n assignInlineStyles(element, styleValue);\n }\n}\n","const ON_DOUBLE_CLICK = \"onDoubleClick\";\n\n/**\n * `onMount`/`onDestroy` look like `on*` event attributes but aren't real DOM\n * events — there is no native `onmount`/`ondestroy` IDL property for\n * `\"onmount\" in element` to find, so without this exclusion they'd fall into\n * the generic addEventListener fallback below and silently never fire (the\n * browser never dispatches a \"mount\"/\"destroy\" event). attributes.ts special-\n * cases these two keys before ever calling this function; the exclusion here\n * is what makes list/template.ts's row-template analysis correctly bail its\n * skeleton-clone fast path for rows using them too (see element/lifecycle.ts).\n */\nconst RESERVED_LIFECYCLE_ATTRIBUTES = new Set([\"onMount\", \"onDestroy\"]);\n\ntype FallbackEventListenerList = Array<string | EventListener>;\n\nconst fallbackEventListeners = new WeakMap<EventTarget, FallbackEventListenerList>();\n\n/** Converts a public camel-cased event attribute to its native IDL property. */\nexport function eventAttributeToProperty(attribute: string): string | null {\n if (\n attribute.length <= 2\n || attribute.charCodeAt(0) !== 111 /* o */\n || attribute.charCodeAt(1) !== 110 /* n */\n ) {\n return null;\n }\n\n const firstEventCharacter = attribute.charCodeAt(2);\n if (firstEventCharacter < 65 /* A */ || firstEventCharacter > 90 /* Z */) {\n return null;\n }\n\n if (RESERVED_LIFECYCLE_ATTRIBUTES.has(attribute)) return null;\n if (attribute === ON_DOUBLE_CLICK) return \"ondblclick\";\n return attribute.toLowerCase();\n}\n\n/** Assigns an event attribute, falling back when the IDL property is absent. */\nexport function setEventAttribute(\n element: HTMLElement,\n property: string,\n listener: EventListener,\n): void {\n if (property in element) {\n (element as unknown as Record<string, unknown>)[property] = listener;\n return;\n }\n\n const type = property.slice(2);\n const list = fallbackEventListeners.get(element);\n if (list) {\n for (let i = 0; i < list.length; i += 2) {\n if (list[i] !== type) continue;\n\n const previous = list[i + 1] as EventListener;\n if (previous === listener) return;\n element.removeEventListener(type, previous);\n element.addEventListener(type, listener);\n list[i + 1] = listener;\n return;\n }\n\n element.addEventListener(type, listener);\n list.push(type, listener);\n return;\n }\n\n element.addEventListener(type, listener);\n fallbackEventListeners.set(element, [type, listener]);\n}\n","// WeakMap/WeakSet replace expando properties — zero `any`, automatic GC on element removal.\nconst staticClassNames = new WeakMap<HTMLElement, Set<string>>();\nconst reactiveClassNameFlags = new WeakSet<HTMLElement>();\n\n/**\n * Splits a className string into non-empty tokens and adds them to a Set.\n * Single-pass via charCodeAt — avoids intermediate array from split().filter().\n */\nfunction addClassTokens(target: Set<string>, className: string): void {\n\tconst len = className.length;\n\tlet start = 0;\n\tfor (let i = 0; i <= len; i++) {\n\t\tif (i === len || className.charCodeAt(i) === 32) { // 32 = ' '\n\t\t\tif (i > start) target.add(className.substring(start, i));\n\t\t\tstart = i + 1;\n\t\t}\n\t}\n}\n\n/**\n * Joins a Set of class names into a single space-separated string.\n */\nfunction joinClasses(classes: Set<string>): string {\n\tlet result = '';\n\tfor (const cls of classes) {\n\t\tif (result) result += ' ';\n\t\tresult += cls;\n\t}\n\treturn result;\n}\n\n// Mark element as having a reactive className and capture static classes.\n// Only allocate the tracking Set when the element actually has static classes —\n// reactive-only elements (the common case, e.g. a list row's `class={...}`)\n// skip the Set entirely. mergeReactiveClassName/addStaticClasses both handle a\n// missing Set, so an empty one carries no information.\nexport function initReactiveClassName(el: HTMLElement): void {\n\tif (el.className && !staticClassNames.has(el)) {\n\t\tconst classSet = new Set<string>();\n\t\taddClassTokens(classSet, el.className);\n\t\tstaticClassNames.set(el, classSet);\n\t}\n\treactiveClassNameFlags.add(el);\n}\n\n// Check if element has a reactive className\nexport function hasReactiveClassName(el: HTMLElement): boolean {\n\treturn reactiveClassNameFlags.has(el);\n}\n\n// Add static classes to the element's tracked set\nexport function addStaticClasses(el: HTMLElement, className: string): void {\n\tif (!className) return;\n\tlet classSet = staticClassNames.get(el);\n\tif (!classSet) {\n\t\tclassSet = new Set<string>();\n\t\tstaticClassNames.set(el, classSet);\n\t}\n\taddClassTokens(classSet, className);\n}\n\n// Merge reactive className with static classes — called on every reactive update\nexport function mergeReactiveClassName(el: HTMLElement, reactiveClassName: string): void {\n\tconst staticClasses = staticClassNames.get(el);\n\n\tif (!staticClasses || staticClasses.size === 0) {\n\t\t// Skip the DOM write when nothing changes — the common case is the very\n\t\t// first apply of a reactive className resolving to '' on a fresh element.\n\t\tconst next = reactiveClassName || '';\n\t\tif (el.className !== next) el.className = next;\n\t\treturn;\n\t}\n\tif (!reactiveClassName) {\n\t\tel.className = joinClasses(staticClasses);\n\t\treturn;\n\t}\n\t// Hot path: static + reactive. Avoid new Set() — build string directly\n\t// and deduplicate by checking if reactive tokens already exist in static set\n\tlet result = joinClasses(staticClasses);\n\tconst len = reactiveClassName.length;\n\tlet start = 0;\n\tfor (let i = 0; i <= len; i++) {\n\t\tif (i === len || reactiveClassName.charCodeAt(i) === 32) {\n\t\t\tif (i > start) {\n\t\t\t\tconst token = reactiveClassName.substring(start, i);\n\t\t\t\tif (!staticClasses.has(token)) {\n\t\t\t\t\tresult += ' ' + token;\n\t\t\t\t}\n\t\t\t}\n\t\t\tstart = i + 1;\n\t\t}\n\t}\n\tel.className = result;\n}\n\n// Merge static className (for non-reactive className attributes)\nexport function mergeStaticClassName(el: HTMLElement, newClassName: string): void {\n\tif (!newClassName) return;\n\tconst currentClassName = el.className;\n\tif (currentClassName && currentClassName !== newClassName) {\n\t\tconst existing = new Set<string>();\n\t\taddClassTokens(existing, currentClassName);\n\t\taddClassTokens(existing, newClassName);\n\t\tel.className = joinClasses(existing);\n\t} else {\n\t\tel.className = newClassName;\n\t}\n}\n","import { logError } from \"../shared/errors\";\nimport { isNodeConnected, createTextNode } from \"../shared/dom\";\nimport type { UpdateScope } from \"./scope\";\nimport { reactiveTextNodes, reactiveTextNodesByNode, registerReactiveTextNode, removeReactiveTextNodeRef } from \"./registry\";\nimport type { TextResolver } from \"./registry\";\nimport { isBrowser } from \"../shared/environment\";\n\n/**\n * Creates a reactive text node that automatically updates when its resolver function changes.\n *\n * The text node will be registered for reactive updates and its content will be synchronized\n * whenever notifyReactiveTextNodes() is called.\n *\n * @param resolver - Function that returns the text content (string, number, boolean, etc.)\n * @param preEvaluated - Optional pre-evaluated value to avoid calling resolver immediately\n * @returns A Text node that will reactively update its content\n *\n * @example\n * ```ts\n * const count = signal(0);\n * const textNode = createReactiveTextNode(() => `Count: ${count.value}`);\n * // Later, when count changes and notifyReactiveTextNodes() is called,\n * // the text content automatically updates\n * ```\n */\nexport function createReactiveTextNode(resolver: TextResolver, preEvaluated?: unknown, sanitize?: boolean): Text | DocumentFragment {\n if (typeof resolver !== \"function\") {\n logError(\"Invalid resolver provided to createReactiveTextNode\");\n const fallbackNode = createTextNode(\"\");\n if (!fallbackNode) {\n throw new Error(\"Failed to create text node: document not available\");\n }\n return fallbackNode;\n }\n\n let initial: unknown;\n if (arguments.length > 1) {\n initial = preEvaluated;\n } else {\n try {\n initial = resolver();\n } catch (e) {\n logError(\"Failed to evaluate reactive text resolver\", e);\n initial = \"\";\n }\n }\n const str = initial === undefined ? \"\" : String(initial);\n const txt = createTextNode(str);\n \n if (!txt) {\n throw new Error(\"Failed to create text node: document not available\");\n }\n\n if (isBrowser) {\n registerReactiveTextNode(txt, { resolver, lastValue: str, sanitize });\n }\n return txt;\n}\n\n/**\n * Updates all registered reactive text nodes.\n *\n * Iterates through all reactive text nodes, re-evaluates their resolver functions,\n * and updates their content if it has changed. Automatically cleans up disconnected nodes.\n *\n * This function should be called after state changes to synchronize the DOM with application state.\n *\n * @example\n * ```ts\n * // After updating application state\n * count.value++;\n * notifyReactiveTextNodes(); // All reactive text nodes update\n * ```\n */\nexport function notifyReactiveTextNodes(scope?: UpdateScope): void {\n for (const ref of reactiveTextNodes) {\n const node = ref.deref();\n if (node === undefined) {\n removeReactiveTextNodeRef(ref);\n continue;\n }\n\n const entry = reactiveTextNodesByNode.get(node);\n if (!entry) {\n removeReactiveTextNodeRef(ref);\n continue;\n }\n const info = entry.info;\n\n if (!isNodeConnected(node)) {\n reactiveTextNodesByNode.delete(node);\n removeReactiveTextNodeRef(ref);\n continue;\n }\n\n if (scope && !scope.contains(node)) continue;\n\n let raw: unknown;\n try {\n raw = info.resolver();\n } catch (e) {\n logError(\"Failed to update reactive text node\", e);\n raw = undefined;\n }\n\n // sanitize: DSL text resolvers render nullish/non-primitive results as \"\"\n // (the resolver is registered raw; see ReactiveTextNodeInfo.sanitize).\n const newVal = info.sanitize\n ? (raw == null || typeof raw === \"object\" || typeof raw === \"function\" ? \"\" : String(raw))\n : (raw === undefined ? \"\" : String(raw));\n if (newVal !== info.lastValue) {\n node.textContent = newVal;\n info.lastValue = newVal;\n }\n }\n\n}\n","import { isFunction } from \"../shared/type-guards\";\nimport { registerAttributeResolver } from \"../update/reactive-attributes\";\nimport { applyStyleAttribute } from \"./inline-style\";\nimport { SVG_NAMESPACE } from \"../shared/dom\";\nimport { eventAttributeToProperty, setEventAttribute } from \"./event-attributes\";\nimport { registerMount, registerDestroy } from \"./lifecycle\";\nimport {\n\tinitReactiveClassName,\n\thasReactiveClassName,\n\taddStaticClasses,\n\tmergeReactiveClassName,\n\tmergeStaticClassName\n} from \"./class-name\";\n\ntype AttributeKey<TTagName extends ElementTagName> = keyof ExpandedElementAttributes<TTagName>;\ntype AttributeCandidate<TTagName extends ElementTagName> =\n ExpandedElementAttributes<TTagName>[AttributeKey<TTagName>];\n\n/**\n * Applies a resolved (non-function) attribute value to an element.\n *\n * Module-level rather than a closure inside applySingleAttribute so the\n * static-attribute path — the bulk of attributes in list rows — allocates\n * nothing per attribute.\n */\nfunction setAttributeValue(\n el: ExpandedElement<ElementTagName>,\n key: string,\n v: unknown,\n merge: boolean,\n): void {\n if (v == null) return;\n\n // Special handling for className to merge instead of replace (only for non-reactive updates)\n if (merge && key === 'className' && el instanceof HTMLElement) {\n mergeStaticClassName(el, String(v));\n return;\n }\n\n // SVG elements should always use setAttribute for most attributes\n // because many SVG properties are read-only\n if (el instanceof Element && el.namespaceURI === SVG_NAMESPACE) {\n el.setAttribute(key, String(v));\n } else if (key in el) {\n // For HTML elements, try to set as property first\n try {\n (el as Record<string, unknown>)[key] = v;\n } catch {\n // If property is read-only, fall back to setAttribute\n if (el instanceof Element) {\n el.setAttribute(key, String(v));\n }\n }\n } else if (el instanceof Element) {\n el.setAttribute(key, String(v));\n }\n}\n\nexport function applySingleAttribute<TTagName extends ElementTagName>(\n el: ExpandedElement<TTagName>,\n key: AttributeKey<TTagName>,\n raw: AttributeCandidate<TTagName> | undefined,\n shouldMergeClassName = false,\n): void {\n if (raw == null) return;\n const k = key as string;\n\n if (k === \"style\") {\n applyStyleAttribute(el, raw as unknown as ValueOrFactory<CSSStyleObject>);\n return;\n }\n\n if (isFunction(raw)) {\n // onMount/onDestroy aren't real DOM events (no native onmount/ondestroy\n // IDL property exists) — checked first so they never fall into the\n // generic on* handling below, which would silently register a dead\n // addEventListener(\"mount\"/\"destroy\", ...) that the browser never fires.\n if (k === \"onMount\") {\n registerMount(el as unknown as Element, raw as MountCallback<Element>);\n return;\n }\n if (k === \"onDestroy\") {\n registerDestroy(el as unknown as Element, raw as DestroyCallback<Element>);\n return;\n }\n\n // Keep the dominant event path to one comparison and one assignment.\n if (k === \"onClick\") {\n (el as Record<string, unknown>).onclick = raw;\n return;\n }\n\n if (\n k.charCodeAt(0) === 111 /* o */\n && k.charCodeAt(1) === 110 /* n */\n ) {\n // Camel-cased `on*` props are handlers, not reactive value resolvers.\n const eventProperty = eventAttributeToProperty(k);\n if (eventProperty) {\n setEventAttribute(el as HTMLElement, eventProperty, raw as EventListener);\n return;\n }\n\n // Preserve runtime compatibility for native lowercase IDL properties\n // passed from untyped JavaScript. Public types reject these names.\n if (k in el) {\n (el as Record<string, unknown>)[k] = raw;\n return;\n }\n }\n\n if (raw.length === 0) {\n // Type narrowing: zero-arity function that returns an attribute value\n const resolver = raw as () => AttributeCandidate<TTagName>;\n\n // For reactive className, we need to track which classes are reactive\n // so we can preserve static classes when the reactive className changes\n if (k === 'className' && el instanceof HTMLElement) {\n initReactiveClassName(el);\n\n registerAttributeResolver(el, k, resolver, function(v) {\n mergeReactiveClassName(el, String(v || ''));\n });\n } else {\n registerAttributeResolver(el, k, resolver, function(v) {\n setAttributeValue(el, k, v, false);\n });\n }\n return;\n }\n // Non-event functions with parameters fall through and are assigned as-is\n // (same as any other static value), matching previous behavior.\n }\n\n // Static attributes should merge classNames\n // For className, if there's already a reactive className, add to static classes\n if (k === 'className' && el instanceof HTMLElement && hasReactiveClassName(el)) {\n // There's already a reactive className; update the tracked set and DOM atomically.\n const newClassName = String(raw || '');\n if (newClassName) {\n addStaticClasses(el, newClassName);\n mergeStaticClassName(el, newClassName);\n }\n return;\n }\n setAttributeValue(el, k, raw, shouldMergeClassName);\n}\n\nexport function applyAttributes<TTagName extends ElementTagName>(\n element: ExpandedElement<TTagName>,\n attributes: ExpandedElementAttributes<TTagName>,\n mergeClassName = true,\n): void {\n if (!attributes) return;\n // for-in over Object.keys() avoids allocating a key array per element —\n // attribute objects are always plain literals, so no prototype keys leak in.\n for (const k in attributes) {\n const key = k as AttributeKey<TTagName>;\n const value = (attributes as Record<string, unknown>)[k] as\n AttributeCandidate<TTagName> | undefined;\n // Only merge className for non-className keys OR when explicitly enabled for className\n const shouldMerge = mergeClassName && key === 'className';\n applySingleAttribute(element, key, value, shouldMerge);\n }\n}\n\nexport { createReactiveTextNode } from \"../update/reactive-text\";\n","/**\n * Interprets every argument passed to a tag builder: strings/numbers become\n * text nodes, objects become attributes, functions become reactive text or\n * nested builders, Nodes are appended as-is.\n */\nimport { applyAttributes } from \"./attributes\";\nimport { createReactiveTextNode } from \"../update/reactive-text\";\nimport { registerReactiveTextNode } from \"../update/registry\";\nimport { logError } from \"../shared/errors\";\nimport { isFunction, isNode, isObject, isPrimitive, isZeroArityFunction } from \"../shared/type-guards\";\nimport { createComment, createDocumentFragment, createTextNode } from \"../shared/dom\";\nimport { isHydrating, isSerializing, claimChild, peekChild, setCursor, skipWhitespaceText } from \"../hydration\";\nimport { isBrowser } from \"../shared/environment\";\n\n/**\n * Caches the probe result of zero-arity function modifiers so the same\n * function is not re-invoked when it reappears during re-renders.\n */\nexport const modifierProbeCache = new WeakMap<() => unknown, { value: unknown; error: boolean }>();\n\nexport type NodeModifier<TTagName extends ElementTagName = ElementTagName> =\n\t| NodeMod<TTagName>\n\t| NodeModFn<TTagName>\n\t| AnyParentNodeModifier;\n\n/**\n * Shape returned by cn() helper: a plain object with exactly one key `className`.\n * Typed as readonly to signal it should not be mutated after creation.\n */\ninterface ClassNameOnlyObject {\n\treadonly className: string;\n}\n\nfunction isClassNameOnlyObject(v: unknown): v is ClassNameOnlyObject {\n\treturn (\n\t\tisObject(v) &&\n\t\t!isNode(v) &&\n\t\t'className' in v &&\n\t\ttypeof (v as { className: unknown }).className === 'string' &&\n\t\tObject.keys(v).length === 1\n\t);\n}\n\nfunction nextChildIsTextComment(parent: Node): boolean {\n\tskipWhitespaceText(parent);\n\tconst child = peekChild(parent);\n\treturn !!child && child.nodeType === 8 &&\n\t\t(child as Comment).textContent?.trimStart().startsWith('text-') === true;\n}\n\n/**\n * Claims the text node that follows an already-claimed `<!-- text-N -->`\n * marker and patches its content to the client value.\n *\n * The HTML parser drops empty text nodes, so SSR output for an empty string\n * has a marker with no text node after it — in that case a fresh text node is\n * inserted at the cursor to keep the DOM identical to a client render.\n * Content mismatches (data changed between SSR and hydration) are patched so\n * hydration always converges on the client value.\n */\nfunction claimTextAfterMarker(parent: Node, expected: string): Text | null {\n\tconst next = peekChild(parent);\n\tif (next && next.nodeType === 3) {\n\t\tclaimChild(parent);\n\t\tif (next.textContent !== expected) {\n\t\t\tnext.textContent = expected;\n\t\t}\n\t\treturn next as Text;\n\t}\n\tconst created = createTextNode(expected);\n\tif (!created) return null;\n\tparent.insertBefore(created, next);\n\tsetCursor(parent, next);\n\treturn created;\n}\n\nexport function applyNodeModifier<TTagName extends ElementTagName>(\n\tparent: ExpandedElement<TTagName>,\n\tmodifier: NodeModifier<TTagName>,\n\tindex: number,\n): Node | null {\n\tif (modifier == null) return null;\n\n\tif (isFunction(modifier)) {\n\t\t// Handle zero-argument functions (reactive text or reactive className)\n\t\tif (isZeroArityFunction(modifier)) {\n\t\t\ttry {\n\t\t\t\tlet record = modifierProbeCache.get(modifier);\n\t\t\t\tif (!record) {\n\t\t\t\t\tconst value = modifier();\n\t\t\t\t\trecord = { value, error: false };\n\t\t\t\t\tmodifierProbeCache.set(modifier, record);\n\t\t\t\t}\n\t\t\t\tif (record.error) {\n\t\t\t\t\treturn createReactiveTextChild(index, () => \"\");\n\t\t\t\t}\n\t\t\t\tconst v = record.value;\n\n\t\t\t\t// Detect cn() result: plain object with only a `className` string key\n\t\t\t\tif (isClassNameOnlyObject(v)) {\n\t\t\t\t\tconst classNameFn = (): string => {\n\t\t\t\t\t\tconst result = modifier();\n\t\t\t\t\t\treturn isClassNameOnlyObject(result) ? result.className : \"\";\n\t\t\t\t\t};\n\t\t\t\t\tapplyAttributes(parent, { className: classNameFn } as ExpandedElementAttributes<TTagName>);\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\n\t\t\t\tif (isPrimitive(v)) {\n\t\t\t\t\t// Nullish probes register as empty reactive text instead of being\n\t\t\t\t\t// dropped: a resolver with no value yet (data still loading) must\n\t\t\t\t\t// stay reactive so a later update() can fill it in. The resolver\n\t\t\t\t\t// is registered raw with `sanitize` set — the notify pass renders\n\t\t\t\t\t// nullish/non-primitive results as \"\" — instead of allocating a\n\t\t\t\t\t// sanitizing wrapper closure per text node.\n\t\t\t\t\tconst resolver = modifier as () => Primitive;\n\t\t\t\t\tconst initial: Primitive = v != null ? (v as Primitive) : \"\";\n\t\t\t\t\tif (isHydrating() && nextChildIsTextComment(parent as unknown as Node)) {\n\t\t\t\t\t\tconst parentNode = parent as unknown as Node;\n\t\t\t\t\t\tclaimChild(parentNode); // skip <!-- text-N --> comment\n\t\t\t\t\t\tconst expected = String(initial);\n\t\t\t\t\t\tconst textNode = claimTextAfterMarker(parentNode, expected);\n\t\t\t\t\t\tif (textNode) {\n\t\t\t\t\t\t\tregisterReactiveTextNode(textNode, {\n\t\t\t\t\t\t\t\tresolver,\n\t\t\t\t\t\t\t\tlastValue: expected,\n\t\t\t\t\t\t\t\tsanitize: true,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\t\t\t\t\treturn createReactiveTextChild(index, resolver, initial, true);\n\t\t\t\t}\n\t\t\t\treturn null;\n\t\t\t} catch (error) {\n\t\t\t\tmodifierProbeCache.set(modifier, { value: undefined, error: true });\n\t\t\t\tlogError(\"Error evaluating reactive text function:\", error);\n\t\t\t\treturn createReactiveTextChild(index, () => \"\");\n\t\t\t}\n\t\t}\n\n\t\t// Handle NodeModFn functions\n\t\tconst produced = (modifier as NodeModFn<TTagName>)(parent, index);\n\t\tif (produced == null) return null;\n\t\tif (isPrimitive(produced)) return createStaticTextChild(index, produced);\n\t\tif (isNode(produced)) return produced;\n\t\tif (isObject(produced)) {\n\t\t\tapplyAttributes(parent, produced as ExpandedElementAttributes<TTagName>);\n\t\t}\n\t\treturn null;\n\t}\n\n\t// Handle non-function modifiers\n\tconst candidate = modifier as NodeMod<TTagName>;\n\tif (isPrimitive(candidate)) {\n\t\tif (isHydrating() && nextChildIsTextComment(parent as unknown as Node)) {\n\t\t\tconst parentNode = parent as unknown as Node;\n\t\t\tclaimChild(parentNode); // skip <!-- text-N --> comment\n\t\t\tclaimTextAfterMarker(parentNode, String(candidate));\n\t\t\treturn null;\n\t\t}\n\t\treturn createStaticTextChild(index, candidate);\n\t}\n\tif (isNode(candidate)) return candidate;\n\tapplyAttributes(parent, candidate as ExpandedElementAttributes<TTagName>);\n\treturn null;\n}\n\n/**\n * Wraps a freshly created text node for insertion.\n *\n * The `<!-- text-N -->` marker only exists so hydration can pair an SSR text\n * node with its client resolver. A pure client render never hydrates, so the\n * marker (and the DocumentFragment that carries it) is dead weight: two extra\n * DOM nodes and a fragment allocation per text child that nothing ever reads.\n * In that case we return the bare text node — halving the per-row DOM node\n * count and the DOM inserts in list-heavy renders.\n *\n * SSR (isBrowser === false, or renderToString's serialization mode) and the\n * hydration-mismatch fresh-render path keep the marker so the emitted/repaired\n * DOM stays hydratable. A null text node (document unavailable) is skipped,\n * matching the previous per-path guards.\n */\nfunction wrapTextNode(index: number, textNode: Node | null): Node | null {\n\tif (isBrowser && !isHydrating() && !isSerializing()) {\n\t\treturn textNode;\n\t}\n\tconst fragment = createDocumentFragment();\n\tif (!fragment) {\n\t\tthrow new Error(\"Failed to create document fragment: document not available\");\n\t}\n\tconst comment = createComment(` text-${index} `);\n\tif (comment) fragment.appendChild(comment);\n\tif (textNode) fragment.appendChild(textNode);\n\treturn fragment;\n}\n\nfunction createReactiveTextChild(\n\tindex: number,\n\tresolver: () => Primitive,\n\tpreEvaluated?: unknown,\n\tsanitize?: boolean\n): Node | null {\n\treturn wrapTextNode(index, createReactiveTextNode(resolver, preEvaluated, sanitize));\n}\n\nfunction createStaticTextChild(index: number, value: Primitive): Node | null {\n\treturn wrapTextNode(index, createTextNode(String(value)));\n}\n","/**\n * Element creation: builds HTML/SVG elements and applies the modifier list\n * that was passed to a tag builder (children, attributes, text, on(), ...).\n */\nimport { applyNodeModifier, type NodeModifier } from \"./modifiers\";\nimport { createElement, createElementNS, SVG_NAMESPACE } from \"../shared/dom\";\nimport { claimElement, cleanupUnclaimedChildren } from \"../hydration\";\nimport { acquireMetadataOnlyFactory, isMetadataOnlyFactoryMode, setFactoryMeta } from \"./factory-meta\";\n\nexport type { NodeModifier };\n\n/**\n * Applies modifiers to an element, appending newly produced Nodes while avoiding\n * duplicate DOM insertions (i.e. only appends if parentNode differs).\n *\n * `localIndex` advances once per appended child so each reactive/static text\n * modifier gets a unique `text-N` marker; it is internal bookkeeping only and\n * is not returned (no production caller consumed the previous result object).\n */\nexport function applyModifiers<TTagName extends ElementTagName>(\n element: ExpandedElement<TTagName>,\n modifiers: ReadonlyArray<NodeModifier<TTagName>>,\n startIndex = 0\n): void {\n if (!modifiers || modifiers.length === 0) return;\n\n let localIndex = startIndex;\n const parentNode = element as unknown as Node & ParentNode;\n\n for (let i = 0; i < modifiers.length; i += 1) {\n const mod = modifiers[i];\n // Fast null/undefined skip\n if (mod == null) continue;\n\n const produced = applyNodeModifier(element, mod, localIndex);\n if (!produced) continue;\n\n // Only append if the node isn't already where we expect\n if (produced.parentNode !== parentNode) {\n parentNode.appendChild(produced);\n }\n localIndex += 1;\n }\n}\n\n/**\n * Creates an HTML element with the specified tag name and applies modifiers to it.\n */\nexport function createHtmlElementWithModifiers<TTagName extends ElementTagName>(\n tagName: TTagName,\n modifiers: ReadonlyArray<NodeModifier<TTagName>>\n): ExpandedElement<TTagName> {\n const el = createElement(tagName) as ExpandedElement<TTagName>;\n if (!el) {\n throw new Error(`Failed to create element: ${tagName}`);\n }\n applyModifiers(el, modifiers, 0);\n return el;\n}\n\n/**\n * Creates an SVG element with the specified tag name and applies modifiers to it.\n */\nexport function createSvgElementWithModifiers<TTagName extends keyof SVGElementTagNameMap>(\n tagName: TTagName,\n modifiers: ReadonlyArray<unknown>\n): SVGElementTagNameMap[TTagName] {\n const el = createElementNS(SVG_NAMESPACE, tagName);\n if (!el) {\n throw new Error(`Failed to create SVG element: ${tagName}`);\n }\n applyModifiers(el as unknown as ExpandedElement<ElementTagName>, modifiers as ReadonlyArray<NodeModifier<ElementTagName>>, 0);\n return el as unknown as SVGElementTagNameMap[TTagName];\n}\n\n\n/**\n * Creates an HTML element factory with the given modifiers.\n */\nfunction createHtmlElementFactory<TTagName extends ElementTagName>(\n tagName: TTagName,\n modifiers: ReadonlyArray<NodeModifier<TTagName>>\n): DetachedExpandedElementFactory<TTagName> {\n if (isMetadataOnlyFactoryMode()) {\n const factory = acquireMetadataOnlyFactory() as unknown as DetachedExpandedElementFactory<TTagName>;\n setFactoryMeta(factory, tagName, modifiers);\n return factory;\n }\n\n const factory = function(_parent?: ExpandedElement<TTagName>, index = 0): ExpandedElement<TTagName> {\n const parentNode = _parent as unknown as Node | undefined;\n const claimed = parentNode ? claimElement(parentNode, tagName) as ExpandedElement<TTagName> | null : null;\n const el = claimed ?? createElement(tagName) as ExpandedElement<TTagName>;\n if (!el) {\n throw new Error(`Failed to create element: ${tagName}`);\n }\n const elNode = el as unknown as Node;\n const lastOriginalChild = claimed ? elNode.lastChild : null;\n applyModifiers(el, modifiers as ReadonlyArray<NodeModifier<TTagName>>, index);\n if (claimed) {\n cleanupUnclaimedChildren(elNode, lastOriginalChild);\n }\n return el;\n } as DetachedExpandedElementFactory<TTagName>;\n // Lets the list() template engine see the factory's structure (internal\n // symbols — invisible to the public API).\n setFactoryMeta(factory, tagName, modifiers);\n return factory;\n}\n\n/**\n * Creates an SVG element factory with the given modifiers.\n */\nfunction createSvgElementFactory<TTagName extends keyof SVGElementTagNameMap>(\n tagName: TTagName,\n modifiers: ReadonlyArray<unknown>\n): DetachedSVGElementFactory<TTagName> {\n if (isMetadataOnlyFactoryMode()) {\n const factory = acquireMetadataOnlyFactory() as unknown as DetachedSVGElementFactory<TTagName>;\n setFactoryMeta(factory, tagName, modifiers);\n return factory;\n }\n\n return function(_parent?, index = 0): SVGElementTagNameMap[TTagName] {\n const parentNode = _parent as unknown as Node | undefined;\n const claimed = parentNode ? claimElement(parentNode, tagName) as ExpandedElement | null : null;\n const el = claimed ?? createElementNS(SVG_NAMESPACE, tagName);\n if (!el) {\n throw new Error(`Failed to create SVG element: ${tagName}`);\n }\n const elNode = el as unknown as Node;\n const lastOriginalChild = claimed ? elNode.lastChild : null;\n applyModifiers(el as unknown as ExpandedElement<ElementTagName>, modifiers as ReadonlyArray<NodeModifier<ElementTagName>>, index);\n if (claimed) {\n cleanupUnclaimedChildren(elNode, lastOriginalChild);\n }\n return el as unknown as SVGElementTagNameMap[TTagName];\n } as DetachedSVGElementFactory<TTagName>;\n}\n\n/**\n * Creates an HTML tag builder function.\n */\nexport function createHtmlTagBuilder<TTagName extends ElementTagName>(\n tagName: TTagName,\n): ExpandedElementBuilder<TTagName> {\n return (...mods) => createHtmlElementFactory(tagName, mods);\n}\n\n/**\n * Creates an SVG tag builder function.\n */\nexport function createSvgTagBuilder<TTagName extends keyof SVGElementTagNameMap>(\n tagName: TTagName,\n): ExpandedSVGElementBuilder<TTagName> {\n return (...mods) => createSvgElementFactory(tagName, mods);\n}\n","/**\n * The HTML/SVG tag catalogue and the code that turns every tag into a global\n * builder function (`div(...)`, `span(...)`, `rectSvg(...)`, ...).\n */\nimport { createHtmlTagBuilder, createSvgTagBuilder } from \"./factory\";\n\nexport const HTML_TAGS = [\n \"a\", \"abbr\", \"address\", \"area\", \"article\", \"aside\", \"audio\", \"b\", \"base\",\n \"bdi\", \"bdo\", \"blockquote\", \"body\", \"br\", \"button\", \"canvas\", \"caption\",\n \"cite\", \"code\", \"col\", \"colgroup\", \"data\", \"datalist\", \"dd\", \"del\", \"details\",\n \"dfn\", \"dialog\", \"div\", \"dl\", \"dt\", \"em\", \"embed\", \"fieldset\", \"figcaption\",\n \"figure\", \"footer\", \"form\", \"h1\", \"h2\", \"h3\", \"h4\", \"h5\", \"h6\", \"head\",\n \"header\", \"hgroup\", \"hr\", \"html\", \"i\", \"iframe\", \"img\", \"input\", \"ins\",\n \"kbd\", \"label\", \"legend\", \"li\", \"link\", \"main\", \"map\", \"mark\", \"menu\",\n \"meta\", \"meter\", \"nav\", \"noscript\", \"object\", \"ol\", \"optgroup\", \"option\",\n \"output\", \"p\", \"picture\", \"pre\", \"progress\", \"q\", \"rp\", \"rt\", \"ruby\", \"s\",\n \"samp\", \"script\", \"search\", \"section\", \"select\", \"slot\", \"small\", \"source\",\n \"span\", \"strong\", \"style\", \"sub\", \"summary\", \"sup\", \"table\", \"tbody\", \"td\",\n \"template\", \"textarea\", \"tfoot\", \"th\", \"thead\", \"time\", \"title\", \"tr\",\n \"track\", \"u\", \"ul\", \"var\", \"video\", \"wbr\",\n] as const satisfies ReadonlyArray<ElementTagName>;\n\nexport const SVG_TAGS = [\n \"a\", \"animate\", \"animateMotion\", \"animateTransform\", \"circle\", \"clipPath\",\n \"defs\", \"desc\", \"ellipse\", \"feBlend\", \"feColorMatrix\", \"feComponentTransfer\",\n \"feComposite\", \"feConvolveMatrix\", \"feDiffuseLighting\", \"feDisplacementMap\",\n \"feDistantLight\", \"feDropShadow\", \"feFlood\", \"feFuncA\", \"feFuncB\", \"feFuncG\",\n \"feFuncR\", \"feGaussianBlur\", \"feImage\", \"feMerge\", \"feMergeNode\", \"feMorphology\",\n \"feOffset\", \"fePointLight\", \"feSpecularLighting\", \"feSpotLight\", \"feTile\",\n \"feTurbulence\", \"filter\", \"foreignObject\", \"g\", \"image\", \"line\", \"linearGradient\",\n \"marker\", \"mask\", \"metadata\", \"mpath\", \"path\", \"pattern\", \"polygon\", \"polyline\",\n \"radialGradient\", \"rect\", \"script\", \"set\", \"stop\", \"style\", \"svg\", \"switch\",\n \"symbol\", \"text\", \"textPath\", \"title\", \"tspan\", \"use\", \"view\",\n] as const satisfies ReadonlyArray<keyof SVGElementTagNameMap>;\n\nexport const SELF_CLOSING_TAGS = [\n \"area\", \"base\", \"br\", \"col\", \"embed\", \"hr\", \"img\", \"input\", \"link\", \"meta\",\n \"source\", \"track\", \"wbr\",\n] as const satisfies ReadonlyArray<ElementTagName>;\n\n\n// Tag builders are installed as self-overwriting lazy getters instead of\n// being created eagerly: registerGlobalTagBuilders() touches ~180 HTML+SVG\n// tags, but a typical app only ever calls a handful of them. Deferring the\n// createHtmlTagBuilder()/createSvgTagBuilder() closure allocation to first\n// access keeps boot-time work and idle memory proportional to what the app\n// actually uses instead of the whole tag catalogue.\nfunction defineLazyGlobal<T>(target: Record<string, unknown>, key: string, tagName: T, create: (tagName: T) => unknown): void {\n Object.defineProperty(target, key, {\n configurable: true,\n enumerable: true,\n get(): unknown {\n const value = create(tagName);\n Object.defineProperty(target, key, { value, configurable: true, enumerable: true, writable: true });\n return value;\n },\n // A plain accessor-only property would throw on direct assignment\n // (`globalThis.div = ...`), unlike the eager `target[tagName] = builder`\n // it replaces. Route writes through the same \"become a normal data\n // property\" path so overwriting behaves exactly as before.\n set(value: unknown): void {\n Object.defineProperty(target, key, { value, configurable: true, enumerable: true, writable: true });\n },\n });\n}\n\nfunction registerHtmlTag(target: Record<string, unknown>, tagName: ElementTagName): void {\n // Don't overwrite non-function properties (safety check)\n if (tagName in target && typeof target[tagName] !== 'function') {\n return;\n }\n defineLazyGlobal(target, tagName, tagName, createHtmlTagBuilder);\n // `var` is a reserved word, so the declared global is `var_` — register it\n // under that name too (the bare `var` key stays for globalThis[\"var\"] access).\n if (tagName === \"var\") {\n defineLazyGlobal(target, \"var_\", tagName, createHtmlTagBuilder);\n }\n}\n\nfunction registerSvgTag(target: Record<string, unknown>, tagName: keyof SVGElementTagNameMap): void {\n // All SVG tags use camelCase Svg suffix: aSvg, rectSvg, pathSvg, etc.\n const exportName = `${tagName}Svg`;\n\n if (!(exportName in target)) {\n defineLazyGlobal(target, exportName, tagName, createSvgTagBuilder);\n }\n}\n\nexport function registerGlobalTagBuilders(target: Record<string, unknown> = globalThis): void {\n const marker = \"__nuclo_tags_registered\";\n if ((target as Record<string, boolean>)[marker]) return;\n\n // Register SVG tags with Svg suffix\n for (let i = 0; i < SVG_TAGS.length; i++) {\n registerSvgTag(target, SVG_TAGS[i]);\n }\n\n // Register HTML tags\n for (let i = 0; i < HTML_TAGS.length; i++) {\n registerHtmlTag(target, HTML_TAGS[i]);\n }\n\n (target as Record<string, boolean>)[marker] = true;\n}\n","import { isFunction, isTagLike } from \"./type-guards\";\n\ntype RenderableInput<TTagName extends ElementTagName = ElementTagName> =\n | NodeModFn<TTagName>\n | DetachedExpandedElementFactory<TTagName>\n | DetachedSVGElementFactory\n | SVGElementModifierFn\n | ExpandedElement<TTagName>\n | SVGElement\n | Node\n | null\n | undefined;\n\nexport function resolveRenderable<TTagName extends ElementTagName = ElementTagName>(\n result: RenderableInput<TTagName>,\n host: ExpandedElement<TTagName>,\n index: number\n): ExpandedElement<TTagName> | null {\n if (isFunction(result)) {\n const element = (result as (parent: ExpandedElement<TTagName>, index: number) => unknown)(host, index);\n if (element && isTagLike(element)) {\n return element as ExpandedElement<TTagName>;\n }\n return null;\n }\n\n if (result && isTagLike(result)) {\n return result as ExpandedElement<TTagName>;\n }\n\n return null;\n}\n","/**\n * Row-template cloning for list().\n *\n * Building a row through the normal pipeline costs one createElement + a full\n * modifier pass per element. For a keyed list every row comes from the same\n * render function, so the structure is identical across rows and only the\n * leaves differ (text values, event handlers, reactive resolvers, and —\n * rarely — static attribute values). This module:\n *\n * 1. analyzes the first row's factory tree (via the internal factory\n * metadata symbols) and, when every modifier falls into a supported\n * shape, records a slot program for the row;\n * 2. clones the first row's built element as a skeleton (cloneNode does not\n * copy property-assigned `on*` handlers or reactive registrations, and\n * reactive classNames are scrubbed so a selected first row can't leak\n * its state into the skeleton);\n * 3. builds every other row as skeleton.cloneNode(true) + a patch pass that\n * walks the new factory tree in lockstep with the slot program.\n *\n * on() modifiers for native DOM events are supported: they only attach a\n * listener to their parent, so each clone replays them exactly as the normal\n * build would (cloneNode never copies addEventListener listeners, so the\n * skeleton itself stays listener-free).\n *\n * Any construct outside the supported shape (style objects, on(\"mount\") /\n * on(\"destroy\") and other arbitrary NodeModFns, nested list()/when(), node\n * children, resolvers returning non-primitives, multiple className sources\n * per element, SVG) bails to the normal build path — the template is per-list\n * state, so unsupported lists simply never activate it. A per-row shape\n * mismatch (heterogeneous render output) deactivates the template for that\n * list and rebuilds the row normally.\n */\n\nimport { getFactoryMods, getFactoryTag, isEventModifier } from \"../element/factory-meta\";\nimport { eventAttributeToProperty, setEventAttribute } from \"../element/event-attributes\";\nimport { modifierProbeCache } from \"../element/modifiers\";\nimport { isNode } from \"../shared/type-guards\";\nimport { cleanupReactiveElement, cleanupReactiveTextNode } from \"../update/registry\";\n\nexport const LEAF_TEXT = 0;\nexport const LEAF_CLASSNAME = 1;\n\n/** Array slots per leaf in RowLeaves: kind, node, resolver, last value. */\nexport const LEAF_STRIDE = 4;\n\n/**\n * A clone's dynamic leaves, owned by its list record instead of the global\n * reactive registries: template rows have a known lifetime (they live and die\n * with their record), so update() can flush them with a tight array walk —\n * no WeakRef/WeakMap bookkeeping per row, nothing for the GC sweeps to prune.\n *\n * Stored flat — [kind, node, fn, last, kind, node, fn, last, ...] — rather\n * than as one object per leaf: a row costs a single small array instead of an\n * array plus an object per leaf, which is the bulk of a template row's\n * retained bookkeeping and allocation.\n */\nexport type RowLeaves = unknown[];\n\nexport const SLOT_ATTRS = 0;\nexport const SLOT_TEXT = 1;\nexport const SLOT_REACTIVE_TEXT = 2;\nexport const SLOT_CHILD = 3;\nexport const SLOT_NULL = 4;\nexport const SLOT_EVENT = 5;\n\nexport const ATTR_STATIC = 0;\nexport const ATTR_EVENT = 1;\nexport const ATTR_REACTIVE_CLASSNAME = 2;\nexport const ATTR_NULL = 3;\n\nexport interface AttrSpec {\n key: string;\n kind: number;\n /** Static attrs: element exposes the key as a property (filled from the skeleton). */\n prop: boolean;\n /** Static attrs: first-row value. Events: normalized native property name. */\n value?: unknown;\n}\n\nexport type TemplateSlot =\n | { kind: typeof SLOT_ATTRS; keys: AttrSpec[] }\n | { kind: typeof SLOT_TEXT }\n | { kind: typeof SLOT_REACTIVE_TEXT }\n | { kind: typeof SLOT_CHILD; child: TemplateNode }\n | { kind: typeof SLOT_NULL }\n | { kind: typeof SLOT_EVENT };\n\nexport interface TemplateNode {\n tag: string;\n slots: TemplateSlot[];\n}\n\nexport interface ListTemplate {\n tmpl: TemplateNode;\n skeleton: Element;\n}\n\n/**\n * Classifies a factory's modifier tree into a slot program, or returns null\n * when any modifier falls outside the supported shape.\n */\nexport function analyzeFactory(tag: string, mods: readonly unknown[]): TemplateNode | null {\n const slots: TemplateSlot[] = [];\n let classNameSources = 0;\n\n for (let i = 0; i < mods.length; i++) {\n const mod = mods[i];\n if (mod == null) {\n slots.push({ kind: SLOT_NULL });\n continue;\n }\n\n const t = typeof mod;\n\n if (t === \"function\") {\n const childMods = getFactoryMods(mod);\n if (childMods !== undefined) {\n const childTag = getFactoryTag(mod);\n if (!childTag) return null;\n const child = analyzeFactory(childTag, childMods);\n if (!child) return null;\n slots.push({ kind: SLOT_CHILD, child });\n continue;\n }\n if ((mod as () => unknown).length === 0) {\n // Probe once to confirm this is a text resolver. cn()-style objects,\n // nodes and nested builders are handled by the normal path only.\n let v: unknown;\n try {\n v = (mod as () => unknown)();\n modifierProbeCache.set(mod as () => unknown, { value: v, error: false });\n } catch {\n return null;\n }\n if (v == null || (typeof v !== \"object\" && typeof v !== \"function\")) {\n slots.push({ kind: SLOT_REACTIVE_TEXT });\n continue;\n }\n return null;\n }\n if (isEventModifier(mod)) {\n slots.push({ kind: SLOT_EVENT });\n continue;\n }\n // on(\"mount\"/\"destroy\"), when()/list() blocks, arbitrary NodeModFns.\n return null;\n }\n\n if (t === \"object\") {\n if (isNode(mod)) return null;\n const attrs = mod as Record<string, unknown>;\n const keys = Object.keys(attrs);\n const specs: AttrSpec[] = [];\n for (let k = 0; k < keys.length; k++) {\n const key = keys[k];\n const v = attrs[key];\n if (v == null) {\n specs.push({ key, kind: ATTR_NULL, prop: false });\n continue;\n }\n if (key === \"style\") return null;\n const vt = typeof v;\n if (vt === \"function\") {\n const eventProperty = eventAttributeToProperty(key);\n if (eventProperty) {\n specs.push({ key, kind: ATTR_EVENT, prop: false, value: eventProperty });\n continue;\n }\n if (key === \"className\" && (v as () => unknown).length === 0) {\n if (classNameSources++) return null;\n specs.push({ key, kind: ATTR_REACTIVE_CLASSNAME, prop: false });\n continue;\n }\n // Reactive non-className attributes need skeleton scrubbing per\n // key to stay correct — not worth it; normal path handles them.\n return null;\n }\n if (vt === \"object\") return null;\n if (key === \"className\" && classNameSources++) return null;\n specs.push({ key, kind: ATTR_STATIC, prop: false, value: v });\n }\n slots.push({ kind: SLOT_ATTRS, keys: specs });\n continue;\n }\n\n // string | number | boolean → static text child\n slots.push({ kind: SLOT_TEXT });\n }\n\n return { tag, slots };\n}\n\n/**\n * One-time skeleton pass: fills each static attr's property-vs-attribute\n * flag and scrubs reactive classNames (the first row may have rendered with\n * row-specific state, e.g. a selected row's \"danger\" class).\n */\nexport function prepareSkeleton(tmpl: TemplateNode, skeleton: Element): void {\n const slots = tmpl.slots;\n let child: Node | null = skeleton.firstChild;\n for (let i = 0; i < slots.length; i++) {\n const slot = slots[i];\n switch (slot.kind) {\n case SLOT_ATTRS: {\n const specs = slot.keys;\n for (let k = 0; k < specs.length; k++) {\n const spec = specs[k];\n if (spec.kind === ATTR_STATIC) {\n spec.prop = spec.key in skeleton;\n } else if (spec.kind === ATTR_REACTIVE_CLASSNAME) {\n // Drop the attribute rather than assigning \"\": className = \"\"\n // leaves an empty class=\"\" that every clone would copy — per-row\n // attribute storage and style work the normal build never has.\n // The reactive resolver is this element's only class source, and\n // clones only write className when it resolves non-empty.\n skeleton.removeAttribute(\"class\");\n }\n }\n break;\n }\n case SLOT_TEXT:\n case SLOT_REACTIVE_TEXT:\n child = child && child.nextSibling;\n break;\n case SLOT_CHILD:\n if (!child) return;\n prepareSkeleton(slot.child, child as Element);\n child = child.nextSibling;\n break;\n // SLOT_NULL / SLOT_EVENT: no node produced\n }\n }\n}\n\n/**\n * Patches a skeleton clone from a fresh factory tree. Returns false on any\n * shape mismatch — the caller then rebuilds the row through the normal path\n * (a partially patched clone is safe to abandon: its reactive registrations\n * are weak and disconnected, so the next update() sweeps them).\n */\nexport function instantiateTemplate(\n tmpl: TemplateNode,\n mods: readonly unknown[],\n el: Element,\n leaves: RowLeaves,\n): boolean {\n const slots = tmpl.slots;\n if (mods.length !== slots.length) return false;\n let child: Node | null = el.firstChild;\n\n for (let i = 0; i < slots.length; i++) {\n const slot = slots[i];\n const mod = mods[i];\n\n switch (slot.kind) {\n case SLOT_ATTRS: {\n if (mod == null || typeof mod !== \"object\") return false;\n const attrs = mod as Record<string, unknown>;\n const specs = slot.keys;\n let attrCount = 0;\n for (const _k in attrs) attrCount++;\n if (attrCount !== specs.length) return false;\n for (let k = 0; k < specs.length; k++) {\n const spec = specs[k];\n const v = attrs[spec.key];\n switch (spec.kind) {\n case ATTR_STATIC: {\n if (v == null || typeof v === \"object\" || typeof v === \"function\") return false;\n if (v === spec.value) break;\n if (spec.prop) {\n const target = el as unknown as Record<string, unknown>;\n if (target[spec.key] !== v) target[spec.key] = v;\n } else {\n const s = String(v);\n if (el.getAttribute(spec.key) !== s) el.setAttribute(spec.key, s);\n }\n break;\n }\n case ATTR_EVENT: {\n if (typeof v !== \"function\") return false;\n const eventProperty = spec.value as string;\n if (eventProperty === \"onclick\") {\n (el as unknown as Record<string, unknown>).onclick = v;\n } else {\n setEventAttribute(el as HTMLElement, eventProperty, v as EventListener);\n }\n break;\n }\n case ATTR_REACTIVE_CLASSNAME: {\n if (typeof v !== \"function\" || (v as () => unknown).length !== 0) return false;\n // Single-source reactive className (analysis bails on mixed\n // static+reactive), and the skeleton is scrubbed to \"\" — so a\n // plain className assignment is exact, no merge needed.\n const fn = v as () => unknown;\n let resolved: unknown;\n try {\n resolved = fn();\n } catch {\n return false;\n }\n const s = resolved ? String(resolved) : \"\";\n if (s) (el as HTMLElement).className = s;\n leaves.push(LEAF_CLASSNAME, el, fn, s);\n break;\n }\n case ATTR_NULL: {\n if (v != null) return false;\n break;\n }\n }\n }\n break;\n }\n\n case SLOT_TEXT: {\n if (mod == null || typeof mod === \"object\" || typeof mod === \"function\") return false;\n if (!child) return false;\n (child as Text).nodeValue = String(mod);\n child = child.nextSibling;\n break;\n }\n\n case SLOT_REACTIVE_TEXT: {\n if (typeof mod !== \"function\" || (mod as () => unknown).length !== 0) return false;\n if (getFactoryMods(mod) !== undefined) return false;\n if (!child) return false;\n let v: unknown;\n try {\n v = (mod as () => unknown)();\n } catch {\n return false;\n }\n if (v != null && (typeof v === \"object\" || typeof v === \"function\")) return false;\n const s = v == null ? \"\" : String(v);\n const textNode = child as Text;\n textNode.nodeValue = s;\n leaves.push(LEAF_TEXT, textNode, mod, s);\n child = textNode.nextSibling;\n break;\n }\n\n case SLOT_CHILD: {\n const childMods = getFactoryMods(mod);\n if (childMods === undefined) return false;\n if (getFactoryTag(mod) !== slot.child.tag) return false;\n if (!child) return false;\n if (!instantiateTemplate(slot.child, childMods, child as Element, leaves)) return false;\n child = child.nextSibling;\n break;\n }\n\n case SLOT_NULL: {\n if (mod != null) return false;\n break;\n }\n\n case SLOT_EVENT: {\n if (!isEventModifier(mod)) return false;\n // Same call the normal build makes (applyNodeModifier): attaches and\n // tracks this row's listener on the clone. Produces no node.\n (mod as (parent: Element, index: number) => void)(el, 0);\n break;\n }\n }\n }\n return true;\n}\n\n/**\n * Converts the normally-built first row of a compatible template into the same\n * record-owned dynamic leaf representation used by skeleton clones.\n *\n * The normal builder has already registered reactive text/className leaves in\n * the global registries. Template rows have a tighter lifetime through their\n * list record, so unregister those first-row leaves and let updateListRuntimes()\n * flush them with the rest of the templated rows.\n */\nexport function adoptTemplateLeaves(\n tmpl: TemplateNode,\n mods: readonly unknown[],\n el: Element,\n leaves: RowLeaves,\n): boolean {\n const slots = tmpl.slots;\n if (mods.length !== slots.length) return false;\n let child: Node | null = el.firstChild;\n\n for (let i = 0; i < slots.length; i++) {\n const slot = slots[i];\n const mod = mods[i];\n\n switch (slot.kind) {\n case SLOT_ATTRS: {\n if (mod == null || typeof mod !== \"object\") return false;\n const attrs = mod as Record<string, unknown>;\n const specs = slot.keys;\n let k = 0;\n for (const key in attrs) {\n if (k >= specs.length) return false;\n const spec = specs[k];\n if (spec.key !== key) return false;\n k++;\n const v = attrs[key];\n if (spec.kind === ATTR_REACTIVE_CLASSNAME) {\n if (typeof v !== \"function\" || (v as () => unknown).length !== 0) return false;\n cleanupReactiveElement(el);\n leaves.push(LEAF_CLASSNAME, el, v, (el as HTMLElement).className);\n }\n }\n if (k !== specs.length) return false;\n break;\n }\n\n case SLOT_TEXT:\n if (!child) return false;\n child = child.nextSibling;\n break;\n\n case SLOT_REACTIVE_TEXT: {\n if (typeof mod !== \"function\" || (mod as () => unknown).length !== 0) return false;\n if (!child || child.nodeType !== 3) return false;\n const textNode = child as Text;\n cleanupReactiveTextNode(textNode);\n leaves.push(LEAF_TEXT, textNode, mod, textNode.nodeValue ?? \"\");\n child = textNode.nextSibling;\n break;\n }\n\n case SLOT_CHILD: {\n const childMods = getFactoryMods(mod);\n if (childMods === undefined) return false;\n if (getFactoryTag(mod) !== slot.child.tag) return false;\n if (!child) return false;\n if (!adoptTemplateLeaves(slot.child, childMods, child as Element, leaves)) return false;\n child = child.nextSibling;\n break;\n }\n\n case SLOT_NULL:\n if (mod != null) return false;\n break;\n\n case SLOT_EVENT:\n // The normal build already attached this listener; nothing to adopt.\n if (!isEventModifier(mod)) return false;\n break;\n }\n }\n return true;\n}\n\n/**\n * Flushes a template row's dynamic leaves: re-evaluates each resolver and\n * writes the DOM only on change. Resolver errors leave the previous value in\n * place (matching the notify passes' error tolerance).\n */\nexport function flushRowLeaves(leaves: RowLeaves): void {\n for (let i = 0; i < leaves.length; i += LEAF_STRIDE) {\n let v: unknown;\n try {\n v = (leaves[i + 2] as () => unknown)();\n } catch {\n continue;\n }\n if (leaves[i] === LEAF_TEXT) {\n const s = v == null || typeof v === \"object\" || typeof v === \"function\" ? \"\" : String(v);\n if (s !== leaves[i + 3]) {\n (leaves[i + 1] as Text).nodeValue = s;\n leaves[i + 3] = s;\n }\n } else {\n const s = v ? String(v) : \"\";\n if (s !== leaves[i + 3]) {\n (leaves[i + 1] as HTMLElement).className = s;\n leaves[i + 3] = s;\n }\n }\n }\n}\n","/**\n * Keyed list runtime: renders `list(provider, render)` blocks and keeps their\n * DOM rows in sync with the provider's items on every update().\n *\n * sync() is a keyed diff over item identity (===):\n * 1. skip when the items are unchanged (arraysEqual),\n * 2. trim rows that already back the same item at the same position from both\n * ends — pure appends, prepends, insertions and deletions then need no\n * keying structures at all,\n * 3. key the remaining window by item identity (same-position rows pinned\n * first, duplicate items matched FIFO), remove the rows whose item is gone,\n * 4. place the window anchored backwards from the row after it: survivors on\n * the longest increasing subsequence of old positions never move, and runs\n * of freshly built rows are batched into DocumentFragments.\n */\nimport { createMarkerPair, createComment, safeRemoveChild, isNodeConnected, createDocumentFragment, disposeLifecyclesInSubtree } from \"../shared/dom\";\nimport { resolveRenderable } from \"../shared/renderables\";\nimport { isHydrating, isSerializing, claimChild, peekChild, setCursor, skipWhitespaceText } from \"../hydration\";\nimport type { ListRenderer, ListRuntime, ListItemRecord, ListItemsInput, ListItemsProvider, ListRenderedRow } from \"./types\";\nimport type { UpdateScope } from \"../update/scope\";\nimport { isBrowser } from \"../shared/environment\";\nimport { getFactoryMods, getFactoryTag, withMetadataOnlyFactories, getMetadataOnlyFactoryCheckpoint, releaseMetadataOnlyFactories } from \"../element/factory-meta\";\nimport { analyzeFactory, prepareSkeleton, instantiateTemplate, adoptTemplateLeaves, flushRowLeaves, type RowLeaves } from \"./template\";\nimport { hasActiveLifecycleRegistrations } from \"../element/lifecycle\";\n\nfunction arraysEqual<T>(a: readonly T[], b: readonly T[]): boolean {\n if (a === b) return true;\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) {\n if (a[i] !== b[i]) return false;\n }\n return true;\n}\n\n/**\n * Registry of active list runtimes.\n *\n * The iteration set only holds WeakRefs; the runtime itself lives in a\n * WeakMap keyed by its start marker. This keeps the global registry free of\n * strong references to the runtime (which holds the host element, records,\n * and markers), so removing a list's DOM subtree makes the whole runtime\n * collectible — even if update() is never called again. The\n * FinalizationRegistry prunes dead WeakRefs from the set once the marker is\n * collected; updateListRuntimes() also prunes as it iterates.\n */\nconst activeListRuntimes = new Set<WeakRef<Comment>>();\nconst listRuntimeByMarker = new WeakMap<Comment, ListRuntime<unknown, ElementTagName>>();\nconst listMarkerFinalizer = typeof FinalizationRegistry !== \"undefined\"\n ? new FinalizationRegistry<WeakRef<Comment>>((ref) => { activeListRuntimes.delete(ref); })\n : null;\nlet updateListFlushEpoch = 0;\n\nfunction registerListRuntime(startMarker: Comment, runtime: ListRuntime<unknown, ElementTagName>): void {\n const ref = new WeakRef(startMarker);\n activeListRuntimes.add(ref);\n listRuntimeByMarker.set(startMarker, runtime);\n listMarkerFinalizer?.register(startMarker, ref);\n}\n\nfunction normalizeItems<TItem>(items: ListItemsInput<TItem>): readonly TItem[] {\n return Array.isArray(items) ? items : Array.from(items);\n}\n\nfunction isRenderedRow<TTagName extends ElementTagName>(value: unknown): value is ListRenderedRow<TTagName> {\n if (value == null || typeof value !== \"object\") return false;\n const element = (value as { element?: unknown }).element;\n return !!element && typeof Node !== \"undefined\" && element instanceof Node;\n}\n\n/**\n * Renders a row through the un-templated path and normalizes the result. Used\n * whenever a row's shape doesn't match (or no longer matches) the list's\n * active template — the caller has already reset `runtime.template`.\n */\nfunction rebuildRowNormally<TItem, TTagName extends ElementTagName>(\n runtime: ListRuntime<TItem, TTagName>,\n item: TItem,\n index: number,\n): ExpandedElement<TTagName> | null {\n const fallback = runtime.renderItem(item, index);\n if (isRenderedRow<TTagName>(fallback)) {\n runtime.lastRenderRefresh = typeof fallback.update === \"function\" ? fallback.update : null;\n return fallback.element;\n }\n return resolveRenderable<TTagName>(fallback as never, runtime.host, index);\n}\n\n/**\n * Shared collection buffer for a template row's dynamic leaves. A per-row `[]`\n * grown by push() gets a ~16-slot backing store which the record then retains\n * for the row's whole lifetime; collecting here and keeping an exact-size\n * slice() drops that slack. Each use starts at the current length and\n * truncates back to it afterwards, so a nested render (a resolver that renders\n * another list) can't clobber an outer row's leaves, and the buffer never\n * retains nodes or resolvers between rows.\n */\nconst leafScratch: RowLeaves = [];\n\nfunction takeLeaves(start: number): RowLeaves | null {\n return leafScratch.length > start ? leafScratch.slice(start) : null;\n}\n\nfunction renderItem<TItem, TTagName extends ElementTagName>(\n runtime: ListRuntime<TItem, TTagName>,\n item: TItem,\n index: number,\n) {\n const checkpoint = getMetadataOnlyFactoryCheckpoint();\n try {\n return renderItemWithTemplate(runtime, item, index);\n } finally {\n releaseMetadataOnlyFactories(checkpoint);\n }\n}\n\nfunction renderItemWithTemplate<TItem, TTagName extends ElementTagName>(\n runtime: ListRuntime<TItem, TTagName>,\n item: TItem,\n index: number,\n): ExpandedElement<TTagName> | null {\n runtime.lastRenderLeaves = null;\n runtime.lastRenderRefresh = null;\n const template = runtime.template;\n const canUseTemplate = isBrowser && !isHydrating() && !isSerializing();\n\n // Row-template fast path: rows from the same render function share their\n // structure, so after analyzing the first row every following row is a\n // skeleton clone + leaf patch instead of a full per-element build.\n const result = template && canUseTemplate\n ? withMetadataOnlyFactories(runtime.renderItem, item, index)\n : runtime.renderItem(item, index);\n\n if (isRenderedRow<TTagName>(result)) {\n runtime.lastRenderRefresh = typeof result.update === \"function\" ? result.update : null;\n return result.element;\n }\n\n if (template !== null && canUseTemplate) {\n const mods = getFactoryMods(result);\n if (mods !== undefined) {\n if (template === undefined) {\n const tag = getFactoryTag(result);\n const tmpl = tag ? analyzeFactory(tag, mods) : null;\n const el = resolveRenderable<TTagName>(result, runtime.host, index);\n if (tmpl && el) {\n const skeleton = (el as unknown as Node).cloneNode(true) as Element;\n prepareSkeleton(tmpl, skeleton);\n const start = leafScratch.length;\n let adopted = false;\n try {\n adopted = adoptTemplateLeaves(tmpl, mods, el as unknown as Element, leafScratch);\n if (adopted) runtime.lastRenderLeaves = takeLeaves(start);\n } finally {\n leafScratch.length = start;\n }\n if (!adopted) {\n runtime.template = null;\n runtime.lastRenderLeaves = null;\n return el;\n }\n runtime.template = { tmpl, skeleton };\n } else {\n runtime.template = null;\n }\n return el;\n }\n const clone = template.skeleton.cloneNode(true) as Element;\n const start = leafScratch.length;\n try {\n if (getFactoryTag(result) === template.tmpl.tag && instantiateTemplate(template.tmpl, mods, clone, leafScratch)) {\n runtime.lastRenderLeaves = takeLeaves(start);\n return clone as unknown as ExpandedElement<TTagName>;\n }\n } finally {\n leafScratch.length = start;\n }\n // Heterogeneous rows: deactivate and rebuild this row normally. The\n // abandoned clone is disconnected and unregistered — plain garbage.\n // (lastRenderLeaves is already null from the top of this call.)\n runtime.template = null;\n return rebuildRowNormally(runtime, item, index);\n } else if (template === undefined) {\n runtime.template = null;\n } else {\n runtime.template = null;\n return rebuildRowNormally(runtime, item, index);\n }\n }\n\n return resolveRenderable<TTagName>(result as never, runtime.host, index);\n}\n\n/**\n * Detaches one row eagerly: safeRemoveChild walks the subtree to abort\n * listeners and prune reactive registries before removing the node. Used for\n * partial removals, where the walk is cheap; full clears/replaces use\n * bulkClearRecords instead.\n */\nfunction removeRecord<TItem, TTagName extends ElementTagName>(record: ListItemRecord<TItem, TTagName>): void {\n safeRemoveChild(record.element as unknown as Node);\n}\n\n/**\n * Detaches every record's row element from the DOM with a plain removeChild\n * loop — one call per top-level row, never descending into a row's subtree.\n * Each record's element is a direct child of `parent` (the rows between the two\n * list markers), so iterating records removes exactly the same nodes the\n * markers span.\n *\n * This is O(rows): removeChild is O(1) given the node. We deliberately do NOT\n * use Range.deleteContents() here. Its spec-faithful \"is this node contained?\"\n * check (compareBoundaryPointsPosition → isFollowing) re-walks the tree from\n * the range start for *every* spanned node, which is O(nodes²) in non-native\n * DOM implementations (jsdom) and — because the walk visits descendants — scales\n * with nodes-per-row, so a nested `tr>td>td` row template made replace/clear\n * quadratic where a flat `div` row only looked linear.\n *\n * Unlike removeRecord, this does NOT eagerly walk each subtree to abort\n * listeners and prune reactive registries. That walk is the dominant per-row\n * cost when clearing/replacing a large list, and it is redundant here:\n * - Reactive text/attribute registries hold their targets only through\n * WeakRef/WeakMap, and every update() prunes entries whose node became\n * disconnected (which removeChild makes them). The real-GC tests in\n * test/memory/gc-collectability.test.ts prove a detached subtree is\n * collectible with no eager cleanup and no extra update pass.\n * - Event listeners are tracked in a WeakMap keyed by element and registered\n * with an AbortSignal, so they are released when the element is collected.\n *\n * Returns false (and mutates nothing) when the markers aren't both children of\n * `parent`, so the caller can fall back to per-node removal.\n */\nfunction bulkClearRecords<TItem, TTagName extends ElementTagName>(\n records: ReadonlyArray<ListItemRecord<TItem, TTagName>>,\n parent: Node & ParentNode,\n startMarker: Comment,\n endMarker: Comment,\n): boolean {\n if (startMarker.parentNode !== parent || endMarker.parentNode !== parent) return false;\n\n // Neither fast path below walks each row's subtree (that's the whole point\n // — see the class doc comment), so it can't rely on cleanupNodeTree() to\n // fire onDestroy for rows using it. Firing it here first keeps that\n // guarantee without costing anything when lifecycle hooks aren't in use\n // anywhere on the page (the single comparison inside\n // hasActiveLifecycleRegistrations() short-circuits the whole loop).\n if (hasActiveLifecycleRegistrations()) {\n for (let i = 0; i < records.length; i++) {\n const node = records[i].element as unknown as Node | null;\n if (node) disposeLifecyclesInSubtree(node);\n }\n }\n\n // Fastest clear: when the list spans the whole parent (the common case — a\n // tbody or ul dedicated to the list), one textContent write drops every row\n // in a single native call, then the marker pair is re-attached (same nodes,\n // so registry identity is preserved).\n if (isBrowser && parent.firstChild === startMarker && parent.lastChild === endMarker) {\n (parent as Node).textContent = \"\";\n parent.appendChild(startMarker);\n parent.appendChild(endMarker);\n return true;\n }\n\n for (let i = 0; i < records.length; i++) {\n const node = records[i].element as unknown as Node | null;\n // Detach the row (guard against an already-moved/detached element so a\n // stale record can't throw). Children of the row go with it in one call.\n if (node && node.parentNode === parent) parent.removeChild(node);\n }\n return true;\n}\n\n/** sync(): anchor on pinned rows alone when at most this many survivors move. */\nconst PINNED_ONLY_MAX_MOVES = 8;\n/** ...and only in windows this large, where skipping the LIS actually pays. */\nconst PINNED_ONLY_MIN_PINNED = 32;\n\n/**\n * Computes a longest strictly-increasing subsequence of `arr` and returns the\n * indices (into `arr`) that belong to it, in ascending order. O(n log n).\n *\n * Used so reordering only moves the minimum number of DOM nodes: records whose\n * old position sits on the increasing subsequence are already in the correct\n * relative order and never touched; everything else is repositioned.\n */\nfunction longestIncreasingSubsequence(arr: number[]): number[] {\n const n = arr.length;\n if (n === 0) return [];\n const predecessor = new Array<number>(n);\n // tails[k] = index into arr of the smallest tail of an increasing\n // subsequence of length k+1.\n const tails: number[] = [];\n for (let i = 0; i < n; i++) {\n const x = arr[i];\n let lo = 0;\n let hi = tails.length;\n while (lo < hi) {\n const mid = (lo + hi) >> 1;\n if (arr[tails[mid]] < x) lo = mid + 1;\n else hi = mid;\n }\n predecessor[i] = lo > 0 ? tails[lo - 1] : -1;\n if (lo === tails.length) tails.push(i);\n else tails[lo] = i;\n }\n let k = tails.length;\n let idx = tails[k - 1];\n const result = new Array<number>(k);\n while (k > 0) {\n result[--k] = idx;\n idx = predecessor[idx];\n }\n return result;\n}\n\n/**\n * Renders items in [startIndex, endIndexExclusive) and inserts their elements\n * before `anchor` as a single DocumentFragment (falling back to per-node\n * insertion when fragments are unavailable). Appends the created records to\n * `targetRecords` in order.\n */\nfunction buildAndInsert<TItem, TTagName extends ElementTagName>(\n runtime: ListRuntime<TItem, TTagName>,\n parent: Node & ParentNode,\n items: readonly TItem[],\n startIndex: number,\n endIndexExclusive: number,\n anchor: Node,\n targetRecords: ListItemRecord<TItem, TTagName>[],\n): void {\n const fragment = createDocumentFragment();\n let buffered = 0;\n for (let i = startIndex; i < endIndexExclusive; i++) {\n const item = items[i];\n const element = renderItem(runtime, item, i);\n if (!element) continue;\n const dyn = runtime.lastRenderLeaves;\n targetRecords.push({\n item,\n element,\n dyn,\n refresh: runtime.lastRenderRefresh,\n dynCreatedAt: dyn ? runtime.currentFlushEpoch : undefined,\n });\n runtime.lastRenderLeaves = null;\n runtime.lastRenderRefresh = null;\n const node = element as unknown as Node;\n if (fragment) {\n fragment.appendChild(node);\n buffered++;\n } else {\n parent.insertBefore(node, anchor);\n }\n }\n if (fragment && buffered > 0) parent.insertBefore(fragment, anchor);\n}\n\nexport function sync<TItem, TTagName extends ElementTagName>(\n runtime: ListRuntime<TItem, TTagName>\n): void {\n const { startMarker, endMarker } = runtime;\n const parent = (startMarker.parentNode ?? (runtime.host as unknown as Node & ParentNode)) as\n Node & ParentNode;\n\n const items = normalizeItems(runtime.itemsProvider());\n\n if (arraysEqual(runtime.lastSyncedItems, items)) return;\n\n const oldRecords = runtime.records;\n const oldLen = oldRecords.length;\n const newLen = items.length;\n\n // Fast path — clear: one removeChild per row, skipping the eager per-subtree\n // cleanup walk (see bulkClearRecords).\n if (newLen === 0) {\n if (oldLen > 0 && !bulkClearRecords(oldRecords, parent, startMarker, endMarker)) {\n for (let i = 0; i < oldLen; i++) removeRecord(oldRecords[i]);\n }\n runtime.records = [];\n runtime.lastSyncedItems = [];\n runtime.allRecordsCreatedAt = undefined;\n return;\n }\n\n // Trim rows that already back the same item at the same position from both\n // ends. They never move, and most updates (append, prepend, single insert or\n // delete) reduce to an empty window on one side.\n let prefix = 0;\n const maxTrim = Math.min(oldLen, newLen);\n while (prefix < maxTrim && oldRecords[prefix].item === items[prefix]) prefix++;\n let suffix = 0;\n const maxSuffix = maxTrim - prefix;\n while (suffix < maxSuffix && oldRecords[oldLen - 1 - suffix].item === items[newLen - 1 - suffix]) {\n suffix++;\n }\n\n const oldStart = prefix;\n const oldEnd = oldLen - suffix;\n const newStart = prefix;\n const newEnd = newLen - suffix;\n\n // Every old row was trimmed → pure insertion (first render, append, prepend,\n // middle insert). Build the new rows into one fragment before the row that\n // follows the gap. (An empty new window is a no-op here.)\n if (oldStart === oldEnd) {\n const anchor: Node = oldEnd < oldLen ? (oldRecords[oldEnd].element as unknown as Node) : endMarker;\n if (oldEnd === oldLen) {\n buildAndInsert(runtime, parent, items, newStart, newEnd, anchor, oldRecords);\n runtime.allRecordsCreatedAt = oldLen === 0 ? runtime.currentFlushEpoch : undefined;\n } else {\n const fresh: ListItemRecord<TItem, TTagName>[] = [];\n buildAndInsert(runtime, parent, items, newStart, newEnd, anchor, fresh);\n runtime.records = oldRecords.slice(0, oldStart).concat(fresh, oldRecords.slice(oldStart));\n runtime.allRecordsCreatedAt = undefined;\n }\n runtime.lastSyncedItems = items.slice();\n return;\n }\n\n // Every new row was trimmed → pure removal. This is always partial (a full\n // clear was handled above), so remove each row eagerly.\n if (newStart === newEnd) {\n for (let i = oldStart; i < oldEnd; i++) removeRecord(oldRecords[i]);\n oldRecords.splice(oldStart, oldEnd - oldStart);\n runtime.allRecordsCreatedAt = undefined;\n runtime.lastSyncedItems = items.slice();\n return;\n }\n\n // General keyed diff over the window ---------------------------------------\n const oldWinLen = oldEnd - oldStart;\n const newWinLen = newEnd - newStart;\n\n // sources[j] = index into oldRecords of the record backing new position\n // newStart + j, or -1 when the row must be freshly rendered.\n const sources = new Array<number>(newWinLen).fill(-1);\n // claimed[i - oldStart] = the old record was matched to a new position.\n const claimed = new Uint8Array(oldWinLen);\n let reusedCount = 0;\n\n // Pin records whose item is unchanged at the same position. This keeps\n // duplicate item references attached to their original rows.\n const pinEnd = Math.min(oldEnd, newEnd);\n for (let i = prefix; i < pinEnd; i++) {\n if (oldRecords[i].item === items[i]) {\n sources[i - newStart] = i;\n claimed[i - oldStart] = 1;\n reusedCount++;\n }\n }\n const pinnedCount = reusedCount;\n\n // Bucket in reverse DOM order so pop() matches duplicates FIFO in O(1). The value\n // is a single old index, promoted to an index array only when the same item\n // occurs more than once (duplicates are matched FIFO).\n const buckets = new Map<TItem, number | number[]>();\n for (let i = oldEnd - 1; i >= oldStart; i--) {\n if (claimed[i - oldStart]) continue;\n const item = oldRecords[i].item;\n const entry = buckets.get(item);\n if (entry === undefined) buckets.set(item, i);\n else if (typeof entry === \"number\") buckets.set(item, [entry, i]);\n else entry.push(i);\n }\n\n for (let j = 0; j < newWinLen; j++) {\n if (sources[j] !== -1) continue;\n const entry = buckets.get(items[newStart + j]);\n if (entry === undefined) continue;\n let oldIndex: number;\n if (typeof entry === \"number\") {\n oldIndex = entry;\n buckets.delete(items[newStart + j]);\n } else {\n oldIndex = entry.pop()!;\n if (entry.length === 0) buckets.delete(items[newStart + j]);\n }\n sources[j] = oldIndex;\n claimed[oldIndex - oldStart] = 1;\n reusedCount++;\n }\n\n // Nothing survives anywhere → full replace: bulk-detach all old rows and\n // build every new row into a single fragment.\n if (reusedCount === 0 && oldStart === 0 && oldEnd === oldLen) {\n if (!bulkClearRecords(oldRecords, parent, startMarker, endMarker)) {\n for (let i = 0; i < oldLen; i++) removeRecord(oldRecords[i]);\n }\n const fresh: ListItemRecord<TItem, TTagName>[] = [];\n buildAndInsert(runtime, parent, items, 0, newLen, endMarker, fresh);\n runtime.records = fresh;\n runtime.allRecordsCreatedAt = runtime.currentFlushEpoch;\n runtime.lastSyncedItems = items.slice();\n return;\n }\n\n // Remove stale rows BEFORE placement. A removed element left in the DOM\n // would end up interleaved with the survivors the placement phase leaves\n // untouched.\n for (let i = oldStart; i < oldEnd; i++) {\n if (!claimed[i - oldStart]) removeRecord(oldRecords[i]);\n }\n\n // Determine the minimal set of survivors that must move. Survivors whose old\n // positions form an increasing subsequence are already correctly ordered.\n //\n // Pinned rows (same index before and after) are such a subsequence on their\n // own. When nearly every survivor is pinned — swapping two rows of a large\n // list — anchoring on them alone moves only the few unpinned survivors and\n // skips the O(n log n) LIS pass and its arrays. The true LIS can save at\n // most `unpinned` moves over that, so the shortcut is bounded to a handful.\n let stable: Uint8Array | null = null;\n const unpinned = reusedCount - pinnedCount;\n const pinnedOnly = unpinned <= PINNED_ONLY_MAX_MOVES && pinnedCount >= PINNED_ONLY_MIN_PINNED;\n if (reusedCount > 0 && !pinnedOnly) {\n const survivorOldIndices: number[] = [];\n const survivorPositions: number[] = [];\n for (let j = 0; j < newWinLen; j++) {\n if (sources[j] !== -1) {\n survivorOldIndices.push(sources[j]);\n survivorPositions.push(j);\n }\n }\n stable = new Uint8Array(newWinLen);\n const lis = longestIncreasingSubsequence(survivorOldIndices);\n for (let k = 0; k < lis.length; k++) stable[survivorPositions[lis[k]]] = 1;\n }\n\n // Place the window anchored backwards from the first row after it. Runs of\n // freshly created rows are batched into a fragment; survivors on the LIS are\n // left untouched.\n const windowRecords = new Array<ListItemRecord<TItem, TTagName> | null>(newWinLen);\n let nullCount = 0;\n let anchor: Node = oldEnd < oldLen ? (oldRecords[oldEnd].element as unknown as Node) : endMarker;\n let fragment: DocumentFragment | null = null;\n\n for (let j = newWinLen - 1; j >= 0; j--) {\n const src = sources[j];\n\n if (src === -1) {\n // Fresh row. Prefer batching consecutive new rows into a fragment (one\n // DOM insert); prepending keeps ascending order.\n const item = items[newStart + j];\n const element = renderItem(runtime, item, newStart + j);\n if (!element) {\n windowRecords[j] = null;\n nullCount++;\n continue;\n }\n const dyn = runtime.lastRenderLeaves;\n windowRecords[j] = {\n item,\n element,\n dyn,\n refresh: runtime.lastRenderRefresh,\n dynCreatedAt: dyn ? runtime.currentFlushEpoch : undefined,\n };\n runtime.lastRenderLeaves = null;\n runtime.lastRenderRefresh = null;\n const node = element as unknown as Node;\n if (!fragment) fragment = createDocumentFragment();\n if (fragment) {\n fragment.insertBefore(node, fragment.firstChild);\n } else {\n // No DocumentFragment available — insert directly and advance the\n // anchor so the next (earlier) row lands before this one.\n parent.insertBefore(node, anchor);\n anchor = node;\n }\n continue;\n }\n\n // Survivor: flush any pending fresh rows (they belong after it), moving\n // the anchor to the first flushed node so this row lands before them.\n const record = oldRecords[src];\n windowRecords[j] = record;\n const node = record.element as unknown as Node;\n if (fragment && fragment.firstChild) {\n const firstFlushed = fragment.firstChild;\n parent.insertBefore(fragment, anchor);\n anchor = firstFlushed;\n fragment = null;\n }\n // Pinned-only mode: a survivor is pinned iff it kept its index (a bucket\n // match can never land on its own old index — the pin pass took those).\n if (stable ? !stable[j] : !(pinnedOnly && src === newStart + j)) {\n parent.insertBefore(node, anchor);\n }\n anchor = node;\n }\n if (fragment && fragment.firstChild) parent.insertBefore(fragment, anchor);\n\n // Stitch the untouched prefix and suffix around the window's records.\n const merged = new Array<ListItemRecord<TItem, TTagName>>(\n oldStart + (newWinLen - nullCount) + (oldLen - oldEnd),\n );\n let w = 0;\n for (let i = 0; i < oldStart; i++) merged[w++] = oldRecords[i];\n for (let j = 0; j < newWinLen; j++) {\n const record = windowRecords[j];\n if (record) merged[w++] = record;\n }\n for (let i = oldEnd; i < oldLen; i++) merged[w++] = oldRecords[i];\n runtime.records = merged;\n runtime.allRecordsCreatedAt = undefined;\n runtime.lastSyncedItems = items.slice();\n}\n\nexport function createListRuntime<TItem, TTagName extends ElementTagName = ElementTagName>(\n itemsProvider: ListItemsProvider<TItem>,\n renderItem: ListRenderer<TItem, TTagName>,\n host: ExpandedElement<TTagName>,\n index: number,\n): ListRuntime<TItem, TTagName> {\n if (isHydrating()) {\n return hydrateListRuntime(itemsProvider, renderItem, host, index);\n }\n\n return createListRuntimeNormal(itemsProvider, renderItem, host, index);\n}\n\nfunction createListRuntimeNormal<TItem, TTagName extends ElementTagName>(\n itemsProvider: ListItemsProvider<TItem>,\n renderItem: ListRenderer<TItem, TTagName>,\n host: ExpandedElement<TTagName>,\n index: number,\n): ListRuntime<TItem, TTagName> {\n const { start: startMarker, end: endMarker } = createMarkerPair(\"list\", index);\n\n const runtime: ListRuntime<TItem, TTagName> = {\n itemsProvider,\n renderItem,\n startMarker,\n endMarker,\n records: [],\n host,\n lastSyncedItems: [],\n };\n\n const parentNode = host as unknown as Node & ParentNode;\n parentNode.appendChild(startMarker);\n parentNode.appendChild(endMarker);\n\n sync(runtime);\n\n if (isBrowser) {\n // Register for future update() calls — not needed in SSR\n registerListRuntime(startMarker, runtime as ListRuntime<unknown, ElementTagName>);\n }\n\n return runtime;\n}\n\nfunction hydrateListRuntime<TItem, TTagName extends ElementTagName>(\n itemsProvider: ListItemsProvider<TItem>,\n renderFn: ListRenderer<TItem, TTagName>,\n host: ExpandedElement<TTagName>,\n index: number,\n): ListRuntime<TItem, TTagName> {\n const parentNode = host as unknown as Node & ParentNode;\n\n // Check if next child is actually a list-start comment marker.\n // If not, fall back to normal (non-hydration) list creation.\n skipWhitespaceText(parentNode);\n const candidate = peekChild(parentNode);\n if (!candidate || candidate.nodeType !== 8 ||\n !(candidate as Comment).textContent?.startsWith('list-start-')) {\n return createListRuntimeNormal(itemsProvider, renderFn, host, index);\n }\n\n // Claim existing start marker\n const startMarker = claimChild(parentNode) as Comment;\n\n // Find end marker (without claiming) so we know when to stop.\n // Pairs are depth-counted in case nested list markers share this host.\n let depth = 0;\n let scanNode: Node | null = peekChild(parentNode);\n while (scanNode) {\n if (scanNode.nodeType === 8) {\n const text = (scanNode as Comment).textContent || '';\n if (text.startsWith('list-start-')) {\n depth++;\n } else if (text === 'list-end') {\n if (depth === 0) break;\n depth--;\n }\n }\n scanNode = scanNode.nextSibling;\n }\n let endMarker = scanNode as Comment | null;\n if (!endMarker) {\n // Corrupt/truncated SSR output — recreate the end marker; every item\n // claim below will miss and render fresh.\n const created = createComment('list-end');\n if (created) {\n parentNode.insertBefore(created, startMarker.nextSibling);\n endMarker = created;\n }\n }\n if (!endMarker) {\n return createListRuntimeNormal(itemsProvider, renderFn, host, index);\n }\n\n // Get current items and claim existing elements by running render functions\n const currentItems = normalizeItems(itemsProvider());\n const records: ListItemRecord<TItem, TTagName>[] = [];\n\n for (let i = 0; i < currentItems.length; i++) {\n const result = renderFn(currentItems[i], i);\n const rendered = isRenderedRow<TTagName>(result) ? result : null;\n const element = rendered\n ? rendered.element\n : resolveRenderable<TTagName>(result as never, host, i);\n if (element) {\n records.push({\n item: currentItems[i],\n element,\n refresh: rendered && typeof rendered.update === \"function\" ? rendered.update : undefined,\n });\n }\n }\n\n // Reconcile server/client mismatches.\n // 1) Server rendered more items than the client has: remove the leftover\n // nodes between the claim cursor and the end marker.\n let leftover = peekChild(parentNode);\n while (leftover && leftover !== endMarker) {\n const next: Node | null = leftover.nextSibling;\n safeRemoveChild(leftover);\n leftover = next;\n }\n\n // 2) Client has items the claim pass could not match: place them in item\n // order, anchored backwards from the end marker (same strategy as sync()).\n let anchor: Node = endMarker;\n for (let i = records.length - 1; i >= 0; i--) {\n const recordNode = records[i].element as unknown as Node;\n if (recordNode.parentNode !== parentNode || recordNode.nextSibling !== anchor) {\n parentNode.insertBefore(recordNode, anchor);\n }\n anchor = recordNode;\n }\n\n // Advance cursor past end marker\n setCursor(parentNode, endMarker.nextSibling);\n\n const runtime: ListRuntime<TItem, TTagName> = {\n itemsProvider,\n renderItem: renderFn,\n startMarker,\n endMarker,\n records,\n host,\n lastSyncedItems: currentItems.slice(),\n };\n\n if (isBrowser) {\n registerListRuntime(startMarker, runtime as ListRuntime<unknown, ElementTagName>);\n }\n\n return runtime;\n}\n\n/**\n * Drops a disconnected runtime's item/element references. The runtime object\n * can outlive its list (it stays reachable through the WeakMap entry while\n * someone still references the detached subtree), so clearing the records\n * keeps it from pinning the items.\n */\nfunction releaseRuntime(runtime: ListRuntime<unknown, ElementTagName>): void {\n runtime.template = null;\n runtime.lastRenderLeaves = null;\n runtime.lastRenderRefresh = null;\n for (let i = 0; i < runtime.records.length; i++) {\n const record = runtime.records[i] as { item: unknown; element: unknown; dyn?: unknown; refresh?: unknown };\n record.element = null;\n record.item = null;\n record.dyn = null;\n record.refresh = null;\n delete (record as { dynCreatedAt?: number }).dynCreatedAt;\n }\n runtime.records = [];\n runtime.lastSyncedItems = [];\n runtime.allRecordsCreatedAt = undefined;\n}\n\nexport function updateListRuntimes(scope?: UpdateScope): void {\n const toDelete: WeakRef<Comment>[] = [];\n updateListFlushEpoch++;\n\n for (const ref of activeListRuntimes) {\n const startMarker = ref.deref();\n\n // Marker was garbage collected\n if (!startMarker) {\n toDelete.push(ref);\n continue;\n }\n\n const runtime = listRuntimeByMarker.get(startMarker);\n if (!runtime) {\n toDelete.push(ref);\n continue;\n }\n\n // Clean up if disconnected from DOM\n if (!isNodeConnected(startMarker) || !isNodeConnected(runtime.endMarker)) {\n releaseRuntime(runtime);\n listRuntimeByMarker.delete(startMarker);\n toDelete.push(ref);\n continue;\n }\n\n // Skip if outside update scope\n if (scope && !scope.contains(startMarker)) continue;\n\n runtime.currentFlushEpoch = updateListFlushEpoch;\n try {\n sync(runtime);\n } finally {\n runtime.currentFlushEpoch = undefined;\n }\n\n // Flush template rows' record-owned dynamic leaves. Rows built through\n // the normal path registered globally and are flushed by the notify\n // passes instead.\n if (runtime.allRecordsCreatedAt === updateListFlushEpoch) continue;\n const records = runtime.records;\n for (let i = 0; i < records.length; i++) {\n if (records[i].dynCreatedAt === updateListFlushEpoch) continue;\n const refresh = records[i].refresh;\n if (refresh) refresh();\n const dyn = records[i].dyn;\n if (dyn) flushRowLeaves(dyn);\n }\n }\n\n // Clean up dead references\n for (const ref of toDelete) {\n activeListRuntimes.delete(ref);\n }\n}\n","import { createListRuntime } from \"./runtime\";\nimport type { ListRenderer, ListItemsProvider } from \"./types\";\n\n/**\n * Maps items to DOM elements, keeping them in sync with changes.\n * Returns a function compatible with both HTML and SVG contexts.\n */\nexport function list<TItem, TTagName extends ElementTagName = ElementTagName>(\n itemsProvider: ListItemsProvider<TItem>,\n render: ListRenderer<TItem, TTagName>,\n): ListModifier<TTagName> {\n return function<TParent extends ElementTagName>(host: ExpandedElement<TParent>, index: number): Comment {\n const runtime = createListRuntime(itemsProvider, render, host as unknown as ExpandedElement<TTagName>, index);\n // Return the start marker comment node\n // Comment is a Node, making this compatible with both HTML and SVG modifiers\n return runtime.startMarker;\n } as unknown as ListModifier<TTagName>;\n}\n","export type ConditionInput = boolean | (() => boolean);\n\nexport function runCondition(\n condition: () => boolean,\n onError?: (error: unknown) => void\n): boolean {\n try {\n return condition();\n } catch (error) {\n if (onError) {\n onError(error);\n return false;\n }\n throw error;\n }\n}\n\nexport function resolveCondition(\n value: ConditionInput,\n onError?: (error: unknown) => void\n): boolean {\n return typeof value === \"function\" ? runCondition(value, onError) : Boolean(value);\n}\n","import { clearBetweenMarkers, insertNodesBefore, isNodeConnected, withScopedInsertion } from \"../shared/dom\";\nimport { resolveCondition } from \"../shared/conditions\";\nimport type { UpdateScope } from \"../update/scope\";\nimport { applyNodeModifier, modifierProbeCache } from \"../element/modifiers\";\nimport { isFunction, isZeroArityFunction } from \"../shared/type-guards\";\nimport { logError } from \"../shared/errors\";\n\nexport type WhenCondition = boolean | (() => boolean);\nexport type WhenContent<TTagName extends ElementTagName = ElementTagName> =\n NodeModLike<TTagName>;\n\nexport interface WhenGroup<TTagName extends ElementTagName = ElementTagName> {\n condition: WhenCondition;\n content: WhenContent<TTagName>[];\n}\n\nexport interface WhenRuntime<TTagName extends ElementTagName = ElementTagName> {\n startMarker: Comment;\n endMarker: Comment;\n host: ExpandedElement<TTagName>;\n index: number;\n groups: WhenGroup<TTagName>[];\n elseContent: WhenContent<TTagName>[];\n /**\n * Tracks which branch is currently rendered:\n * - null: nothing rendered yet (initial state)\n * - -1: else branch is active\n * - >= 0: groups[activeIndex] is active\n */\n activeIndex: number | null;\n update(): void;\n}\n\n/**\n * Registry of active when runtimes.\n *\n * The iteration set only holds WeakRefs; the runtime itself lives in a\n * WeakMap keyed by its start marker. This keeps the global registry free of\n * strong references to the runtime (which holds the host element, branch\n * content, and markers), so removing the surrounding DOM subtree makes the\n * runtime collectible — even if update() is never called again. The\n * FinalizationRegistry prunes dead WeakRefs once the marker is collected;\n * updateWhenRuntimes() also prunes as it iterates.\n */\nconst activeWhenRuntimes = new Set<WeakRef<Comment>>();\nconst whenRuntimeByMarker = new WeakMap<Comment, WhenRuntime<ElementTagName>>();\nconst whenMarkerFinalizer = typeof FinalizationRegistry !== \"undefined\"\n ? new FinalizationRegistry<WeakRef<Comment>>((ref) => { activeWhenRuntimes.delete(ref); })\n : null;\n\n/**\n * Evaluates which condition branch should be active.\n * Returns the index of the first truthy condition, -1 for else branch, or null for no match.\n */\nexport function evaluateActiveCondition<TTagName extends ElementTagName>(\n groups: ReadonlyArray<WhenGroup<TTagName>>,\n elseContent: ReadonlyArray<WhenContent<TTagName>>\n): number | null {\n for (let i = 0; i < groups.length; i++) {\n if (resolveCondition(groups[i].condition)) {\n return i;\n }\n }\n return elseContent.length > 0 ? -1 : null;\n}\n\n/**\n * Main render function for when/else conditionals.\n * Evaluates conditions, clears old content, and renders the active branch.\n */\nexport function renderWhenContent<TTagName extends ElementTagName>(\n runtime: WhenRuntime<TTagName>\n): void {\n const { groups, elseContent, host, index, endMarker } = runtime;\n\n const newActive = evaluateActiveCondition(groups, elseContent);\n\n // No change needed\n if (newActive === runtime.activeIndex) return;\n\n // Clear previous content and update active index\n clearBetweenMarkers(runtime.startMarker, runtime.endMarker);\n runtime.activeIndex = newActive;\n\n // Nothing to render\n if (newActive === null) return;\n\n // Render the active branch\n const contentToRender = newActive >= 0 ? groups[newActive].content : elseContent;\n const nodes = renderContentItems(contentToRender, host, index, endMarker);\n\n insertNodesBefore(nodes, endMarker);\n}\n\n/**\n * Registers a when runtime for tracking and updates.\n * Uses WeakRef to prevent memory leaks when elements are removed.\n * The runtime object itself is mutable and will be updated in place.\n */\nexport function registerWhenRuntime<TTagName extends ElementTagName>(\n runtime: WhenRuntime<TTagName>\n): void {\n const ref = new WeakRef(runtime.startMarker);\n activeWhenRuntimes.add(ref);\n whenRuntimeByMarker.set(runtime.startMarker, runtime as WhenRuntime<ElementTagName>);\n whenMarkerFinalizer?.register(runtime.startMarker, ref);\n}\n\n/**\n * Updates all active when/else conditional runtimes.\n *\n * Re-evaluates all conditional branches and re-renders if the active branch has changed.\n * Automatically cleans up runtimes that are garbage collected or disconnected from DOM.\n *\n * This function should be called after state changes that affect conditional expressions.\n *\n * @example\n * ```ts\n * isLoggedIn.value = true;\n * updateWhenRuntimes(); // All when() conditionals re-evaluate\n * ```\n */\nexport function updateWhenRuntimes(scope?: UpdateScope): void {\n const toDelete: WeakRef<Comment>[] = [];\n\n for (const ref of activeWhenRuntimes) {\n const startMarker = ref.deref();\n\n // Comment node was garbage collected\n if (startMarker === undefined) {\n toDelete.push(ref);\n continue;\n }\n\n const runtime = whenRuntimeByMarker.get(startMarker);\n if (!runtime) {\n toDelete.push(ref);\n continue;\n }\n\n // Check if markers are still connected to DOM\n if (!isNodeConnected(startMarker) || !isNodeConnected(runtime.endMarker)) {\n whenRuntimeByMarker.delete(startMarker);\n toDelete.push(ref);\n continue;\n }\n\n // Skip if outside update scope\n if (scope && !scope.contains(startMarker)) continue;\n\n try {\n runtime.update();\n } catch (error) {\n // Clean up runtimes that throw errors\n logError(\"when() branch threw during update; unregistering this conditional\", error);\n whenRuntimeByMarker.delete(startMarker);\n toDelete.push(ref);\n }\n }\n\n // Clean up dead references\n for (const ref of toDelete) {\n activeWhenRuntimes.delete(ref);\n }\n}\n\n// ─── Content rendering ───────────────────────────────────────────────────────\n/**\n * Renders a single content item and returns the resulting node if any.\n */\nfunction renderContentItem<TTagName extends ElementTagName>(\n item: WhenContent<TTagName>,\n host: ExpandedElement<TTagName>,\n index: number,\n endMarker: Comment\n): Node | null {\n if (!isFunction(item)) {\n return applyNodeModifier(host, item, index);\n }\n\n // Zero-arity functions need cache cleared\n if (isZeroArityFunction(item)) {\n modifierProbeCache.delete(item);\n return applyNodeModifier(host, item, index);\n }\n\n // Non-zero-arity functions need scoped insertion to insert before endMarker\n return withScopedInsertion(host, endMarker, () => {\n const maybeNode = applyNodeModifier(host, item, index);\n // Only include nodes that weren't already inserted\n return maybeNode && !maybeNode.parentNode ? maybeNode : null;\n });\n}\n\n/**\n * Renders a list of content items and collects the resulting nodes.\n */\nexport function renderContentItems<TTagName extends ElementTagName>(\n items: ReadonlyArray<WhenContent<TTagName>>,\n host: ExpandedElement<TTagName>,\n index: number,\n endMarker: Comment\n): Node[] {\n const nodes: Node[] = [];\n for (const item of items) {\n const node = renderContentItem(item, host, index, endMarker);\n if (node) {\n nodes.push(node);\n }\n }\n return nodes;\n}\n","import { createMarkerPair, createComment, clearBetweenMarkers, insertNodesBefore, asParentNode } from \"../shared/dom\";\nimport type { WhenCondition, WhenContent, WhenGroup, WhenRuntime } from \"./runtime\";\nimport { renderWhenContent, registerWhenRuntime, evaluateActiveCondition, renderContentItems } from \"./runtime\";\nimport { isBrowser } from \"../shared/environment\";\nimport { isHydrating, claimChild, peekChild, setCursor, skipWhitespaceText, runWithoutHydration } from \"../hydration\";\nimport { applyNodeModifier } from \"../element/modifiers\";\n\n/**\n * Encodes the active branch into the start marker so hydration can detect\n * server/client branch mismatches: `when-start-{index}-b{branch}` where\n * branch is the group index, -1 for the else branch, or `n` for none.\n */\nfunction encodeBranch(index: number, activeIndex: number | null): string {\n return `when-start-${index}-b${activeIndex === null ? 'n' : activeIndex}`;\n}\n\n/**\n * Reads the branch encoded in an SSR start marker.\n * Returns `undefined` for legacy markers without branch info.\n */\nfunction decodeBranch(markerText: string | null): number | null | undefined {\n const match = /-b(n|-?\\d+)$/.exec(markerText || '');\n if (!match) return undefined;\n return match[1] === 'n' ? null : parseInt(match[1], 10);\n}\n\nclass WhenBuilderImpl<TTagName extends ElementTagName = ElementTagName> {\n private groups: WhenGroup<TTagName>[] = [];\n private elseContent: WhenContent<TTagName>[] = [];\n\n constructor(initialCondition: WhenCondition, ...content: WhenContent<TTagName>[]) {\n this.groups.push({ condition: initialCondition, content });\n }\n\n cloneWith(\n additionalGroup?: WhenGroup<TTagName>,\n newElseContent?: WhenContent<TTagName>[],\n ): WhenBuilderImpl<TTagName> {\n const b = Object.create(WhenBuilderImpl.prototype) as WhenBuilderImpl<TTagName>;\n b.groups = [...this.groups];\n if (additionalGroup) b.groups.push(additionalGroup);\n b.elseContent = newElseContent ?? [...this.elseContent];\n return b;\n }\n\n when(condition: WhenCondition, ...content: WhenContent<TTagName>[]): WhenBuilderImpl<TTagName> {\n this.groups.push({ condition, content });\n return this;\n }\n\n else(...content: WhenContent<TTagName>[]): WhenBuilderImpl<TTagName> {\n this.elseContent = content;\n return this;\n }\n\n render(host: ExpandedElement<TTagName>, index: number): Node | null {\n if (!globalThis.document) {\n return null;\n }\n\n if (isHydrating()) {\n return this.hydrateRender(host, index);\n }\n\n return this.freshRender(host, index);\n }\n\n private freshRender(host: ExpandedElement<TTagName>, index: number): Node | null {\n const { start: startMarker, end: endMarker } = createMarkerPair(\"when\", index);\n const runtime = this.createRuntimeFromMarkers(host, index, startMarker, endMarker);\n\n const parent = asParentNode(host);\n parent.appendChild(startMarker);\n parent.appendChild(endMarker);\n\n renderWhenContent(runtime);\n\n // Record which branch was rendered so hydration can detect mismatches.\n startMarker.textContent = encodeBranch(index, runtime.activeIndex);\n\n return startMarker;\n }\n\n private hydrateRender(host: ExpandedElement<TTagName>, index: number): Node | null {\n const parentNode = host as unknown as Node & ParentNode;\n\n // Check if next child is actually a when-start comment marker.\n // If the SSR HTML doesn't contain Nuclo comment markers, fall back\n // to normal rendering (create new markers + render from scratch).\n skipWhitespaceText(parentNode);\n const candidate = peekChild(parentNode);\n if (!candidate || candidate.nodeType !== 8 ||\n !(candidate as Comment).textContent?.startsWith('when-start-')) {\n return this.freshRender(host, index);\n }\n\n // Claim existing start marker\n const startMarker = claimChild(parentNode) as Comment;\n\n // Find end marker (without claiming). Directly nested when() blocks\n // share this host, so matching pairs must be depth-counted.\n let depth = 0;\n let scanNode: Node | null = peekChild(parentNode);\n while (scanNode) {\n if (scanNode.nodeType === 8) {\n const text = (scanNode as Comment).textContent || '';\n if (text.startsWith('when-start-')) {\n depth++;\n } else if (text === 'when-end') {\n if (depth === 0) break;\n depth--;\n }\n }\n scanNode = scanNode.nextSibling;\n }\n let endMarker = scanNode as Comment | null;\n let endMarkerMissing = false;\n if (!endMarker) {\n // Corrupt/truncated SSR output — recreate the end marker right after\n // the start marker and render the branch fresh.\n const created = createComment('when-end');\n if (!created) return startMarker;\n parentNode.insertBefore(created, startMarker.nextSibling);\n endMarker = created;\n endMarkerMissing = true;\n }\n\n // Determine which branch the client wants and which the server rendered.\n const activeIndex = evaluateActiveCondition(this.groups, this.elseContent);\n const serverBranch = decodeBranch(startMarker.textContent);\n const branchMatches = !endMarkerMissing &&\n (serverBranch === undefined || serverBranch === activeIndex);\n\n if (branchMatches) {\n // Re-run active branch content to register reactivity on existing nodes\n if (activeIndex !== null) {\n const contentToRender = activeIndex >= 0 ? this.groups[activeIndex].content : this.elseContent;\n for (const item of contentToRender) {\n applyNodeModifier(host, item as NodeMod<TTagName> | NodeModFn<TTagName>, index);\n }\n }\n } else {\n // Server rendered a different branch (or the markup is unusable):\n // drop the server content and render the client branch fresh.\n clearBetweenMarkers(startMarker, endMarker);\n if (activeIndex !== null) {\n const contentToRender = activeIndex >= 0 ? this.groups[activeIndex].content : this.elseContent;\n const end = endMarker;\n runWithoutHydration(() => {\n const nodes = renderContentItems(contentToRender, host, index, end);\n insertNodesBefore(nodes, end);\n });\n }\n }\n\n // Advance cursor past end marker\n setCursor(parentNode, endMarker.nextSibling);\n\n this.createRuntimeFromMarkers(host, index, startMarker, endMarker, activeIndex);\n\n return startMarker;\n }\n\n private createRuntimeFromMarkers(\n host: ExpandedElement<TTagName>,\n index: number,\n startMarker: Comment,\n endMarker: Comment,\n activeIndex: number | null = null,\n ): WhenRuntime<TTagName> {\n const runtime: WhenRuntime<TTagName> = {\n startMarker,\n endMarker,\n host,\n index,\n groups: [...this.groups],\n elseContent: [...this.elseContent],\n activeIndex,\n update: function() { renderWhenContent(runtime); },\n };\n\n if (isBrowser) {\n registerWhenRuntime(runtime);\n }\n\n return runtime;\n }\n}\n\nexport function createWhenBuilderFunction<TTagName extends ElementTagName>(\n builder: WhenBuilderImpl<TTagName>\n): WhenBuilder<TTagName> {\n const nodeModFn = function(host: ExpandedElement<TTagName>, index: number): Node | null {\n return builder.render(host, index);\n };\n\n return Object.assign(nodeModFn, {\n when: function(condition: WhenCondition, ...content: WhenContent<TTagName>[]): WhenBuilder<TTagName> {\n return createWhenBuilderFunction(builder.cloneWith({ condition, content }));\n },\n else: function(...content: WhenContent<TTagName>[]): WhenBuilder<TTagName> {\n return createWhenBuilderFunction(builder.cloneWith(undefined, content));\n },\n }) as unknown as WhenBuilder<TTagName>;\n}\n\nexport { WhenBuilderImpl };\n","import { WhenBuilderImpl, createWhenBuilderFunction } from \"./builder\";\nimport type { WhenCondition, WhenContent } from \"./runtime\";\n\nexport { updateWhenRuntimes } from \"./runtime\";\n\n/**\n * Creates a conditional rendering block (when/else logic).\n *\n * Renders different content based on boolean conditions, similar to if/else statements.\n * Conditions can be static booleans or reactive functions that are re-evaluated on updates.\n *\n * @param condition - Boolean value or function returning a boolean\n * @param content - Content to render when condition is true\n * @returns A builder that allows chaining additional .when() or .else() branches\n *\n * @example\n * ```ts\n * const isLoggedIn = signal(false);\n *\n * div(\n * when(() => isLoggedIn.value,\n * span('Welcome back!')\n * )\n * .else(\n * button('Login', on('click', () => login()))\n * )\n * )\n * ```\n *\n * @example\n * ```ts\n * // Multiple conditions\n * div(\n * when(() => status.value === 'loading',\n * spinner()\n * )\n * .when(() => status.value === 'error',\n * errorMessage()\n * )\n * .else(\n * contentView()\n * )\n * )\n * ```\n */\nexport function when<TTagName extends ElementTagName = ElementTagName>(\n condition: WhenCondition,\n ...content: WhenContent<TTagName>[]\n): WhenBuilder<TTagName> {\n const builder = new WhenBuilderImpl<TTagName>(condition, ...content);\n return createWhenBuilderFunction(builder);\n}\n","import { createHtmlElementWithModifiers, createSvgElementWithModifiers } from \"../element/factory\";\nimport { isBrowser } from \"../shared/environment\";\nimport {\n ConditionalInfo,\n getConditionalInfo,\n storeConditionalInfo,\n getActiveConditionalNodes,\n unregisterConditionalNode,\n} from \"./registry\";\nimport { runCondition } from \"../shared/conditions\";\nimport { replaceNodeSafely, createConditionalComment, createElement, createElementNS, SVG_NAMESPACE, disposeLifecyclesInSubtree } from \"../shared/dom\";\nimport { logError } from \"../shared/errors\";\nimport type { UpdateScope } from \"./scope\";\n\nfunction createElementFromConditionalInfo<TTagName extends ElementTagName>(\n conditionalInfo: ConditionalInfo<TTagName>\n): ExpandedElement<TTagName> | SVGElement {\n try {\n if (conditionalInfo.isSvg) {\n return createSvgElementWithModifiers(conditionalInfo.tagName as keyof SVGElementTagNameMap, conditionalInfo.modifiers);\n }\n return createHtmlElementWithModifiers(conditionalInfo.tagName, conditionalInfo.modifiers);\n } catch (error) {\n logError(`Error applying modifiers in conditional element \"${conditionalInfo.tagName}\"`, error);\n // Return a basic element without modifiers as fallback\n if (conditionalInfo.isSvg) {\n const el = createElementNS(SVG_NAMESPACE, conditionalInfo.tagName);\n if (!el) {\n throw new Error(`Failed to create SVG element: ${conditionalInfo.tagName}`, { cause: error });\n }\n return el as unknown as SVGElement;\n }\n const el = createElement(conditionalInfo.tagName);\n if (!el) {\n throw new Error(`Failed to create element: ${conditionalInfo.tagName}`, { cause: error });\n }\n return el as ExpandedElement<TTagName>;\n }\n}\n\nfunction updateConditionalNode(node: Element | Comment): void {\n const conditionalInfo = getConditionalInfo(node);\n if (!conditionalInfo) {\n return;\n }\n\n const shouldShow = runCondition(conditionalInfo.condition, (error) => {\n logError(\"Error evaluating conditional condition\", error);\n });\n const isElement = node.nodeType === Node.ELEMENT_NODE;\n\n if (shouldShow && !isElement) {\n const element = createElementFromConditionalInfo(conditionalInfo);\n storeConditionalInfo(element as Node, conditionalInfo);\n replaceNodeSafely(node, element as Node);\n } else if (!shouldShow && isElement) {\n const comment = createConditionalComment(conditionalInfo.tagName);\n if (comment) {\n // replaceNodeSafely() below doesn't walk the outgoing element the way\n // safeRemoveChild() does, so fire its onDestroy (if any) here first.\n disposeLifecyclesInSubtree(node);\n storeConditionalInfo(comment, conditionalInfo);\n replaceNodeSafely(node, comment);\n }\n }\n}\n\nexport function updateConditionalElements(scope?: UpdateScope): void {\n if (!isBrowser) return;\n\n try {\n const nodes = getActiveConditionalNodes();\n for (const node of nodes) {\n if (!node.isConnected) {\n unregisterConditionalNode(node);\n continue;\n }\n\n if (scope && !scope.contains(node)) continue;\n updateConditionalNode(node as Element | Comment);\n }\n } catch (error) {\n logError(\"Error during conditional elements update\", error);\n }\n}\n","/**\n * scope() – tags an element as the root of a named update scope so\n * `update(\"name\")` can refresh just that part of the page.\n */\nimport { isNodeConnected } from \"../shared/dom\";\nimport { isBrowser } from \"../shared/environment\";\n\nexport interface UpdateScope {\n roots: ReadonlyArray<Element>;\n contains(node: Node): boolean;\n}\n\n\ntype ScopeId = string;\n\n/**\n * Stores weak references to scope root elements.\n * Using WeakRef prevents memory leaks - elements can be garbage collected when removed from DOM.\n */\nconst scopeRootsById = new Map<ScopeId, Set<WeakRef<Element>>>();\n\nfunction normalizeScopeIds(ids: readonly string[]): ScopeId[] {\n const normalized: ScopeId[] = [];\n const seen = new Set<ScopeId>();\n\n for (const raw of ids) {\n if (typeof raw !== \"string\") continue;\n const id = raw.trim();\n if (!id) continue;\n if (seen.has(id)) continue;\n seen.add(id);\n normalized.push(id);\n }\n\n return normalized;\n}\n\nfunction addScopeRoot(id: ScopeId, el: Element): void {\n let set = scopeRootsById.get(id);\n if (!set) {\n set = new Set<WeakRef<Element>>();\n scopeRootsById.set(id, set);\n }\n set.add(new WeakRef(el));\n}\n\nexport function getScopeRoots(ids: readonly string[]): Element[] {\n const scopeIds = normalizeScopeIds(ids);\n if (scopeIds.length === 0) return [];\n\n const roots = new Set<Element>();\n\n for (const id of scopeIds) {\n const set = scopeRootsById.get(id);\n if (!set) continue;\n\n const toDelete: WeakRef<Element>[] = [];\n\n for (const ref of set) {\n const el = ref.deref();\n if (el === undefined) {\n // Element was garbage collected\n toDelete.push(ref);\n continue;\n }\n if (!isNodeConnected(el)) {\n // Element is disconnected, clean it up\n toDelete.push(ref);\n continue;\n }\n roots.add(el);\n }\n\n // Clean up dead and disconnected references\n for (const ref of toDelete) {\n set.delete(ref);\n }\n\n if (set.size === 0) scopeRootsById.delete(id);\n }\n\n return Array.from(roots);\n}\n\nexport function scope<TTagName extends ElementTagName = ElementTagName>(\n ...ids: string[]\n): NodeModFn<TTagName> {\n const scopeIds = normalizeScopeIds(ids);\n\n return function(parent: ExpandedElement<TTagName>): void {\n if (!isBrowser) return;\n if (!(parent instanceof Element)) return;\n for (const id of scopeIds) addScopeRoot(id, parent);\n };\n}\n","/**\n * update() – the heart of nuclo's reactivity. Re-runs every registered\n * reactive part of the page: lists, when() blocks, conditional elements,\n * function-valued attributes and text, then fires a global \"update\" event.\n */\nimport { updateListRuntimes } from \"../list/runtime\";\nimport { notifyReactiveElements } from \"./reactive-attributes\";\nimport { notifyReactiveTextNodes } from \"./reactive-text\";\nimport { updateWhenRuntimes } from \"../when\";\nimport { updateConditionalElements } from \"./conditional\";\nimport { getScopeRoots } from \"./scope\";\nimport { logError } from \"../shared/errors\";\nimport { flushMountQueue } from \"../element/lifecycle\";\nimport type { UpdateScope } from \"./scope\";\n\n// `satisfies` checks every entry matches the signature without widening the tuple type.\nconst updaters = [\n\tupdateListRuntimes,\n\tupdateWhenRuntimes,\n\tupdateConditionalElements,\n\tnotifyReactiveElements,\n\tnotifyReactiveTextNodes,\n\tdispatchGlobalUpdateEvent,\n] satisfies ReadonlyArray<(scope?: UpdateScope) => void>;\n\nexport function update(...scopeIds: string[]): void {\n\tlet scope: UpdateScope | undefined;\n\n\tif (scopeIds.length > 0) {\n\t\tconst roots = getScopeRoots(scopeIds);\n\n\t\tif (roots.length === 1) {\n\t\t\tconst root = roots[0]!;\n\t\t\tscope = {\n\t\t\t\troots,\n\t\t\t\tcontains: (node) => root.contains(node),\n\t\t\t};\n\t\t} else {\n\t\t\tscope = {\n\t\t\t\troots,\n\t\t\t\tcontains: (node) => {\n\t\t\t\t\tfor (const root of roots) {\n\t\t\t\t\t\tif (root.contains(node)) return true;\n\t\t\t\t\t}\n\t\t\t\t\treturn false;\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\t}\n\n\tfor (const fn of updaters) fn(scope);\n\n\t// Every updater above may have inserted new nodes (a new list() row, a\n\t// newly-true when() branch, a conditional element flipping on) into an\n\t// already-connected host. Flush once, after all of them ran, so onMount\n\t// fires exactly once per pass with the DOM already settled — not once per\n\t// updater.\n\tflushMountQueue();\n}\n\nexport function dispatchGlobalUpdateEvent(scope?: UpdateScope): void {\n if (typeof document === \"undefined\") return;\n\n // Scoped update: the event fires on the scope roots (bubbling up from\n // there), not on the whole document — listeners outside the scope's\n // ancestor chain must not observe a scoped update. An unknown scope id\n // (zero roots) dispatches nothing.\n // Unscoped: a single dispatch on body (or document as fallback) — the\n // event bubbles to document on its own; dispatching on both would run\n // document-level listeners twice.\n const targets: readonly EventTarget[] = scope\n ? scope.roots\n : [document.body ?? document];\n\n for (const target of targets) {\n try {\n target.dispatchEvent(new Event(\"update\", { bubbles: true }));\n } catch (error) {\n logError(\"Error dispatching global update event\", error);\n }\n }\n}\n","import { startHydration, endHydration, peekChild, setCursor } from \"./hydration\";\nimport { safeRemoveChild } from \"./shared/dom\";\nimport { flushMountQueue } from \"./element/lifecycle\";\n\n/**\n * Renders a NodeModFn to a parent element by calling it and appending the result.\n *\n * @param nodeModFn The NodeModFn to render (created by tag builders like div(), h1(), etc.)\n * @param parent The parent element to render into (defaults to document.body)\n * @param index The index to pass to the NodeModFn (defaults to 0)\n * @returns The rendered element\n */\nexport function render<TTagName extends ElementTagName = ElementTagName>(\n nodeModFn: NodeModFn<TTagName>,\n parent?: Element,\n index: number = 0\n): ExpandedElement<TTagName> {\n const targetParent = (parent || document.body) as ExpandedElement<TTagName>;\n const element = nodeModFn(targetParent, index) as ExpandedElement<TTagName>;\n (targetParent as unknown as Node).appendChild(element as Node);\n // The whole tree was built off-document and just got attached in this one\n // call — every onMount queued while building it can fire now.\n flushMountQueue();\n return element;\n}\n\n/**\n * Hydrates an existing server-rendered DOM tree by walking it in parallel with\n * the component tree, reusing existing nodes and re-attaching reactivity.\n *\n * Instead of clearing the container and creating new DOM nodes (like render()),\n * hydrate() claims existing nodes from the SSR output and registers reactive\n * text nodes, attributes, event listeners, list runtimes, and when runtimes\n * on them.\n *\n * @param nodeModFn The NodeModFn to hydrate (same component used for SSR)\n * @param parent The parent element containing the SSR HTML (defaults to document.body)\n * @returns The hydrated root element\n *\n * @example\n * ```ts\n * // Server: const html = renderToString(div(h1(\"Hello\")));\n * // Client:\n * const app = document.getElementById(\"app\")!;\n * // app.innerHTML already contains the SSR HTML\n * hydrate(div(h1(\"Hello\")), app);\n * ```\n */\nexport function hydrate<TTagName extends ElementTagName = ElementTagName>(\n nodeModFn: NodeModFn<TTagName>,\n parent?: Element,\n): ExpandedElement<TTagName> {\n const targetParent = (parent || document.body) as ExpandedElement<TTagName>;\n const parentNode = targetParent as unknown as Node & ParentNode;\n startHydration();\n let element: ExpandedElement<TTagName>;\n try {\n element = nodeModFn(targetParent, 0) as ExpandedElement<TTagName>;\n const elementNode = element as unknown as Node | null | undefined;\n // Claim failed (empty container or tag mismatch): the factory built a\n // fresh, detached root. Replace the mismatched SSR node at the cursor —\n // or append when there is nothing to replace — so the app is always live\n // in the document. Only the single candidate node is touched; siblings\n // (other roots, scripts) are preserved.\n if (elementNode && elementNode.nodeType === 1 && elementNode.parentNode !== parentNode) {\n const stale = peekChild(parentNode);\n if (stale) {\n const after = stale.nextSibling;\n parentNode.insertBefore(elementNode, stale);\n safeRemoveChild(stale);\n setCursor(parentNode, after);\n } else {\n parentNode.appendChild(elementNode);\n setCursor(parentNode, null);\n }\n }\n } finally {\n endHydration();\n }\n // Claimed nodes were already connected (they're existing SSR output inside\n // the live `parent`); freshly-built replacement nodes just got attached\n // above. Either way, by this point everything nodeModFn() touched is\n // settled in the document, so queued onMount callbacks can fire — but only\n // on this success path. Placed outside the try/finally on purpose: if\n // nodeModFn() throws, the tree it was building is incomplete/inconsistent,\n // so any mounts it had already queued are left Pending rather than fired.\n flushMountQueue();\n return element;\n}\n","/**\n * Shared generated-CSS engine state.\n *\n * One stylesheet, one rule registry, shared by every `createCss` instance so\n * identical declarations dedupe globally and cascade order stays deterministic:\n * base rules first (insertion order), then one grouping rule per at-rule query\n * in registration order (theme `screens` order).\n *\n * Browser: rules are injected through CSSOM with O(1) appends — no rescans.\n * SSR: rules accumulate in the registry; `getCssText()` serializes them.\n *\n * The state below lives on `globalThis`, keyed by a `Symbol.for(...)` (the\n * global symbol registry, shared by every realm-local copy of this module).\n * `nuclo` publishes `.`, `./ssr`, and `./polyfill` as independently built\n * bundle files (see tsdown.config.ts) — a consumer that resolves them\n * through normal package resolution (any bundler/runtime that doesn't\n * alias every subpath to this same source file) loads two or three\n * separate copies of this module, each with its own module-scope\n * variables. Without a realm-wide singleton, `css()` (from `nuclo`) would\n * mint rules into one copy's registry while `getCssText()`/\n * `setSSRCollector()` (from `nuclo/ssr`) read an entirely different,\n * always-empty one — SSR output would render the right classes with no\n * matching CSS at all. Storing the registry on `globalThis` instead makes\n * every copy of this module share the same state regardless of how many\n * times it ends up bundled.\n *\n * The registry never shrinks on its own: atomCache/atomMeta/rawKeys/\n * baseRules/queryRules retain every rule for the life of the process —\n * content-addressed dedup needs a durable record of what each class means,\n * and the engine has no way to know whether a minted class still backs a\n * live DOM node (it's deliberately decoupled from element/list lifecycle),\n * so it can't safely evict. Only resetStyles() (a manual test helper)\n * clears it. This is fine for the intended use — a bounded design-token\n * vocabulary — but a caller piping truly per-instance dynamic values\n * through css({ raw: {...} }) (e.g. per-row data in a list) mints one\n * permanent class per unique value; prefer the `style` prop\n * (element/inline-style.ts) for values that vary per instance rather than\n * per design token. See test/style/registry-growth.test.ts.\n */\n\n// SSR collector — optional hook that receives every newly minted rule string\n// (wrapped in its at-rule, if any). Installed once at server startup.\ntype SSRCollector = (rule: string) => void;\n\nexport interface BlockMeta {\n\treadonly query: string | undefined;\n\treadonly suffix: string;\n\treadonly decls: ReadonlyArray<readonly [string, string]>;\n\t/** Author-supplied identity from `css(name, …)`; inherited by cx() merges. */\n\treadonly name: string | undefined;\n}\n\ninterface EngineState {\n\tssrCollector: SSRCollector | null;\n\n\t// Registry — the source of truth for all generated CSS.\n\t// atomCache: declaration-block key -> class name (dedup)\n\t// atomMeta: class name -> what the class means (its selector context and its\n\t// declarations). This is what lets cx() merge two same-context classes at the\n\t// declaration level instead of guessing: the engine can always recover the\n\t// exact content of any class it minted.\n\tatomCache: Map<string, string>;\n\tatomMeta: Map<string, BlockMeta>;\n\trawKeys: Set<string>;\n\tbaseRules: string[];\n\tqueryRules: Map<string, string[]>;\n\tstyleEpoch: number;\n\n\t// Memoized getCssText() output. SSR calls getCssText() once per request, but the\n\t// rule set is stable after warmup — so the serialized sheet is recomputed only\n\t// when a new rule is actually recorded. Invalidated in record() and resetStyles().\n\tcssTextCache: string | null;\n\n\t// Browser CSSOM state. Base rules occupy [0, baseRuleCount); grouping rules\n\t// (one per query, created in registration order) live after them. CSSRule\n\t// references stay live when indices shift, so insertion never rescans.\n\tsheet: CSSStyleSheet | null;\n\tsheetDocument: Document | null;\n\tbaseRuleCount: number;\n\tgroupRules: Map<string, CSSGroupingRule>;\n\n\t// Normalized rules already sitting in a freshly-adopted stylesheet that this\n\t// module didn't insert itself — e.g. server-rendered CSS being hydrated.\n\t// Rebuilt on every fresh bind in ensureSheet(); null when there is nothing\n\t// external to guard against.\n\texternalRules: Map<string, Set<string>> | null;\n\thasExternalGroups: boolean;\n}\n\nfunction createState(): EngineState {\n\treturn {\n\t\tssrCollector: null,\n\t\tatomCache: new Map(),\n\t\tatomMeta: new Map(),\n\t\trawKeys: new Set(),\n\t\tbaseRules: [],\n\t\tqueryRules: new Map(),\n\t\tstyleEpoch: 0,\n\t\tcssTextCache: null,\n\t\tsheet: null,\n\t\tsheetDocument: null,\n\t\tbaseRuleCount: 0,\n\t\tgroupRules: new Map(),\n\t\texternalRules: null,\n\t\thasExternalGroups: false,\n\t};\n}\n\nconst ENGINE_STATE_KEY = Symbol.for(\"nuclo.style.engine.v1\");\nconst globalScope = globalThis as unknown as Record<symbol, EngineState>;\n// Importing the runtime does not allocate the registry until styling is used.\nlet cachedState: EngineState | undefined;\nfunction getState(): EngineState {\n\treturn cachedState ??= globalScope[ENGINE_STATE_KEY] ?? (globalScope[ENGINE_STATE_KEY] = createState());\n}\n\nexport function setSSRCollector(fn: SSRCollector | null): void {\n\tconst state = getState();\n\tstate.ssrCollector = fn;\n}\n\n/** Pre-register at-rule queries so their cascade order follows theme order. */\nexport function registerQueries(queries: Iterable<string>): void {\n\tfor (const query of queries) {\n\t\tconst state = getState();\n\t\tif (!state.queryRules.has(query)) state.queryRules.set(query, []);\n\t}\n}\n\nfunction createGroup(s: CSSStyleSheet, query: string): CSSGroupingRule | null {\n\tconst state = getState();\n\ttry {\n\t\tconst idx = s.cssRules.length;\n\t\ts.insertRule(query + \"{}\", idx);\n\t\tconst group = s.cssRules[idx] as CSSGroupingRule;\n\t\tstate.groupRules.set(query, group);\n\t\tstate.groupRules.set(groupQueryOf(group), group);\n\t\treturn group;\n\t} catch {\n\t\treturn null; // unsupported at-rule in this environment\n\t}\n}\n\n// A group prelude is stable while its children grow. Reading cssText on each\n// insertion would serialize all previous children and make loading quadratic.\n// Weak keys allow detached stylesheets to be collected after reset/rebinding.\nconst groupQueries = new WeakMap<CSSRule, string>();\nfunction groupQueryOf(rule: CSSRule): string {\n\tconst cached = groupQueries.get(rule);\n\tif (cached !== undefined) return cached;\n\tconst text = rule.cssText;\n\tconst brace = text.indexOf(\"{\");\n\tconst query = (brace === -1 ? text : text.slice(0, brace)).trim();\n\tgroupQueries.set(rule, query);\n\treturn query;\n}\n\nfunction ruleIdentity(rule: CSSRule): string {\n\treturn rule instanceof CSSStyleRule ? rule.selectorText : groupQueryOf(rule);\n}\n\nfunction scopedRuleKey(query: string | undefined, identity: string): string {\n\tconst scope = query === undefined ? \"-\" : \"+\" + query.length + \":\" + query;\n\treturn scope + identity.length + \":\" + identity;\n}\n\nfunction rememberExternalRule(rule: CSSRule, query: string | undefined): void {\n\tconst state = getState();\n\tif (!state.externalRules) return;\n\tconst key = scopedRuleKey(query, ruleIdentity(rule));\n\tlet texts = state.externalRules.get(key);\n\tif (!texts) {\n\t\ttexts = new Set();\n\t\tstate.externalRules.set(key, texts);\n\t}\n\ttexts.add(rule.cssText);\n}\n\nfunction consumeExternalRule(rule: CSSRule, query: string | undefined): boolean {\n\tconst state = getState();\n\tif (!state.externalRules) return false;\n\tconst key = scopedRuleKey(query, ruleIdentity(rule));\n\tconst texts = state.externalRules.get(key);\n\tif (!texts?.delete(rule.cssText)) return false;\n\tif (texts.size === 0) state.externalRules.delete(key);\n\tif (state.externalRules.size === 0) state.externalRules = null;\n\treturn true;\n}\n\n/**\n * Index an already-populated stylesheet found on adopt (SSR output, most\n * commonly): every top-level conditional grouping rule (@media/@container/…)\n * is registered into groupRules (by its reconstructed at-rule text) so later\n * record() calls append into it instead of creating a sibling duplicate. The\n * other rules are indexed by scope, selector/prelude, and normalized cssText\n * so exact server/client matches can be skipped without hiding a changed\n * named or global rule that happens to reuse the same selector.\n */\nfunction indexExternalRules(rules: CSSRuleList): void {\n\tconst state = getState();\n\tfor (let i = 0; i < rules.length; i++) {\n\t\tconst rule = rules[i];\n\t\tif (rule instanceof CSSStyleRule) {\n\t\t\trememberExternalRule(rule, undefined);\n\t\t\tcontinue;\n\t\t}\n\t\tconst prelude = groupQueryOf(rule);\n\t\tif (\"cssRules\" in rule && !prelude.startsWith(\"@keyframes\")) {\n\t\t\tconst group = rule as CSSGroupingRule;\n\t\t\tstate.hasExternalGroups = true;\n\t\t\tstate.groupRules.set(prelude, group);\n\t\t\tfor (let j = 0; j < group.cssRules.length; j++) {\n\t\t\t\trememberExternalRule(group.cssRules[j], prelude);\n\t\t\t}\n\t\t} else {\n\t\t\t// @keyframes, @font-face, … — one-shot rules matched by prelude.\n\t\t\trememberExternalRule(rule, undefined);\n\t\t}\n\t}\n}\n\nfunction insertBase(s: CSSStyleSheet, rule: string): void {\n\tconst state = getState();\n\ttry {\n\t\ts.insertRule(rule, state.baseRuleCount);\n\t\tconst inserted = s.cssRules[state.baseRuleCount];\n\t\tif (consumeExternalRule(inserted, undefined)) {\n\t\t\ts.deleteRule(state.baseRuleCount);\n\t\t\treturn;\n\t\t}\n\t\tstate.baseRuleCount++;\n\t} catch {\n\t\t// Invalid value/selector: drop the declaration, like browsers do for bad CSS.\n\t}\n}\n\nfunction insertGrouped(group: CSSGroupingRule, rule: string): void {\n\tconst state = getState();\n\ttry {\n\t\tconst index = group.cssRules.length;\n\t\tgroup.insertRule(rule, index);\n\t\tconst inserted = group.cssRules[index];\n\t\tif (state.externalRules && consumeExternalRule(inserted, groupQueryOf(group))) group.deleteRule(index);\n\t} catch {\n\t\t// Invalid value/selector: drop the declaration, like browsers do for bad CSS.\n\t}\n}\n\nfunction getOrCreateGroup(s: CSSStyleSheet, query: string): CSSGroupingRule | null {\n\tconst state = getState();\n\tconst direct = state.groupRules.get(query);\n\tif (direct) return direct;\n\tif (!state.hasExternalGroups) return createGroup(s, query);\n\n\t// CSSOM may normalize whitespace in an at-rule prelude. Normalize the\n\t// authored query through a temporary empty group before deciding that an\n\t// adopted SSR group is missing.\n\ttry {\n\t\tconst index = s.cssRules.length;\n\t\ts.insertRule(query + \"{}\", index);\n\t\tconst normalized = groupQueryOf(s.cssRules[index]);\n\t\ts.deleteRule(index);\n\t\tconst existing = state.groupRules.get(normalized);\n\t\tif (existing) {\n\t\t\tstate.groupRules.set(query, existing);\n\t\t\treturn existing;\n\t\t}\n\t} catch {\n\t\treturn null;\n\t}\n\treturn createGroup(s, query);\n}\n\n/**\n * Returns the live stylesheet, (re)binding when the document changes — e.g.\n * fresh jsdom documents between tests. Rebinding replays the whole registry,\n * which replaces v1's per-call classExistsInDOM() DOM scans with a single\n * replay per document.\n */\nexport function ensureSheet(): CSSStyleSheet | null {\n\tconst state = getState();\n\tif (typeof document === \"undefined\") return null;\n\t// The nuclo SSR polyfill provides a document without getElementById — in\n\t// that context rules accumulate in the registry for getCssText() only.\n\tif (typeof document.getElementById !== \"function\") return null;\n\tif (\n\t\tstate.sheet &&\n\t\tstate.sheetDocument === document &&\n\t\tstate.sheet.ownerNode &&\n\t\t(state.sheet.ownerNode as Element).isConnected\n\t) {\n\t\treturn state.sheet;\n\t}\n\tconst existing = document.getElementById(\"nuclo-styles\");\n\tlet el: HTMLStyleElement;\n\tif (existing?.tagName === \"STYLE\") {\n\t\tel = existing as HTMLStyleElement;\n\t} else {\n\t\tel = document.createElement(\"style\");\n\t\tel.id = \"nuclo-styles\";\n\t\tif (existing) existing.replaceWith(el);\n\t\telse document.head.appendChild(el);\n\t}\n\tstate.sheet = el.sheet;\n\tstate.sheetDocument = document;\n\tstate.groupRules.clear();\n\tstate.baseRuleCount = 0;\n\tstate.externalRules = null;\n\tstate.hasExternalGroups = false;\n\tif (!state.sheet) return null;\n\tif (state.sheet.cssRules.length > 0) {\n\t\t// Leading top-level non-group rules (style rules, @keyframes — before\n\t\t// the first @media/@container group) are this element's existing\n\t\t// \"base\" region — count them so insertBase() keeps inserting new base\n\t\t// rules right after them, still ahead of every group.\n\t\tlet i = 0;\n\t\twhile (i < state.sheet.cssRules.length) {\n\t\t\tconst r = state.sheet.cssRules[i];\n\t\t\tif (!(r instanceof CSSStyleRule) && \"cssRules\" in r && !groupQueryOf(r).startsWith(\"@keyframes\")) break;\n\t\t\ti++;\n\t\t}\n\t\tstate.baseRuleCount = i;\n\t\tstate.externalRules = new Map();\n\t\tindexExternalRules(state.sheet.cssRules);\n\t}\n\tfor (const rule of state.baseRules) insertBase(state.sheet, rule);\n\tfor (const [query, rules] of state.queryRules) {\n\t\tconst group = getOrCreateGroup(state.sheet, query);\n\t\tif (group) for (const rule of rules) insertGrouped(group, rule);\n\t}\n\treturn state.sheet;\n}\n\nfunction record(rule: string, query: string | undefined): void {\n\tconst state = getState();\n\t// Bind/replay *before* this rule joins the registry, so a fresh bind's\n\t// replay only ever covers previously-known rules — never this one twice.\n\tconst s = ensureSheet();\n\n\tif (query === undefined) {\n\t\tstate.baseRules.push(rule);\n\t} else {\n\t\tlet bucket = state.queryRules.get(query);\n\t\tif (!bucket) {\n\t\t\tbucket = [];\n\t\t\tstate.queryRules.set(query, bucket);\n\t\t}\n\t\tbucket.push(rule);\n\t}\n\tstate.cssTextCache = null; // a new rule changes the serialized sheet\n\n\tif (s) {\n\t\tif (query === undefined) {\n\t\t\tinsertBase(s, rule);\n\t\t} else {\n\t\t\tconst group = getOrCreateGroup(s, query);\n\t\t\tif (group) insertGrouped(group, rule);\n\t\t}\n\t}\n\tstate.ssrCollector?.(query === undefined ? rule : query + \"{\" + rule + \"}\");\n}\n\n/**\n * Content-addressed ~42-bit hash (two interleaved FNV-1a style passes). Class\n * names must match between server and client for SSR hydration, so a counter\n * is not an option; 42 bits keeps collision odds low (~1e-5 at 10k\n * unique declaration blocks).\n */\nexport function hash(input: string): string {\n\tlet a = 0x811c9dc5;\n\tlet b = 0x7ee3623b;\n\tfor (let i = 0; i < input.length; i++) {\n\t\tconst c = input.charCodeAt(i);\n\t\ta = Math.imul(a ^ c, 0x01000193);\n\t\tb = Math.imul(b ^ c, 0x85ebca6b);\n\t}\n\treturn (a >>> 0).toString(36) + ((b >>> 9) % 1296).toString(36);\n}\n\nfunction contextKeyOf(query: string | undefined, suffix: string): string {\n\tconst queryPart = query === undefined ? \"-\" : \"+\" + query.length + \":\" + query;\n\treturn queryPart + suffix.length + \":\" + suffix;\n}\n\nfunction appendKeyPart(key: string, value: string): string {\n\treturn key + value.length + \":\" + value;\n}\n\nexport function expandAmpersands(input: string, replacement: string): string {\n\tlet expanded = \"\";\n\tlet quote = 0;\n\tfor (let i = 0; i < input.length; i++) {\n\t\tconst code = input.charCodeAt(i);\n\t\tif (code === 92 /* \\\\ */ && i + 1 < input.length) {\n\t\t\texpanded += input[i] + input[++i];\n\t\t\tcontinue;\n\t\t}\n\t\tif (quote !== 0) {\n\t\t\texpanded += input[i];\n\t\t\tif (code === quote) quote = 0;\n\t\t\tcontinue;\n\t\t}\n\t\tif (code === 34 /* \" */ || code === 39 /* ' */) {\n\t\t\tquote = code;\n\t\t\texpanded += input[i];\n\t\t} else {\n\t\t\texpanded += code === 38 /* & */ ? replacement : input[i];\n\t\t}\n\t}\n\treturn expanded;\n}\n\nfunction selectorFor(className: string, suffix: string): string {\n\tconst selector = \".\" + className;\n\treturn selector + expandAmpersands(suffix, selector);\n}\n\n/**\n * True for strings usable verbatim as an unescaped CSS class selector:\n * letters/digits/`-`/`_`, not starting with a digit or `-`+digit.\n * Char-code loop rather than a RegExp — this runs on the cold mint path but\n * stays allocation-free either way.\n */\nfunction isValidClassName(name: string): boolean {\n\tif (name.length === 0 || name === \"-\") return false;\n\tfor (let i = 0; i < name.length; i++) {\n\t\tconst c = name.charCodeAt(i);\n\t\tconst ok =\n\t\t\t(c >= 97 && c <= 122) || // a-z\n\t\t\t(c >= 65 && c <= 90) || // A-Z\n\t\t\tc === 45 || c === 95 || // - _\n\t\t\t(i > 0 && c >= 48 && c <= 57); // 0-9, never leading\n\t\tif (!ok) return false;\n\t}\n\t// \"-9foo\" is not a valid identifier start either.\n\tif (name.charCodeAt(0) === 45 && name.length > 1) {\n\t\tconst second = name.charCodeAt(1);\n\t\tif (second >= 48 && second <= 57) return false;\n\t}\n\treturn true;\n}\n\n/**\n * Mint (or reuse) the class for a declaration block in a selector context.\n *\n * Declarations keep their authored order — CSS resolves shorthand/longhand\n * and repeated-property conflicts by declaration order, so reordering (e.g.\n * alphabetical sorting) would silently change what `{ pt: 20, p: 16 }` means.\n * The cost is that the same declarations authored in a different order mint a\n * second, content-identical class — harmless, and rare in practice.\n *\n * `name` is the author's identity for the style (`css(\"app-root\", …)`). It\n * becomes part of the cache key, so two different names never share a class\n * even with identical declarations. With `exactName`, this block *is* the\n * named one and takes the name verbatim; otherwise the name is only a\n * readable prefix on a content-addressed prefix (`app-root-1a2b3c`), which is\n * how a named style's non-base contexts and its cx() merges stay identifiable\n * in devtools without ever colliding with the base class.\n */\nfunction mintBlock(\n\tquery: string | undefined,\n\tsuffix: string,\n\tdecls: ReadonlyArray<readonly [string, string]>,\n\tname?: string,\n\texactName = false,\n): string {\n\tconst state = getState();\n\tlet contextKey = contextKeyOf(query, suffix);\n\tfor (const [prop, value] of decls) {\n\t\tcontextKey = appendKeyPart(appendKeyPart(contextKey, prop), value);\n\t}\n\tif (name !== undefined && !isValidClassName(name)) {\n\t\t// eslint-disable-next-line no-console\n\t\tconsole.warn(\n\t\t\t`[nuclo] css() name ${JSON.stringify(name)} is not a valid CSS class name ` +\n\t\t\t\t\"(letters, digits, - and _ only, not starting with a digit); falling back to a generated name.\",\n\t\t);\n\t\tname = undefined;\n\t}\n\tconst declKey = name === undefined ? \"a\" + contextKey : \"n\" + appendKeyPart(\"\", name) + contextKey;\n\tlet className = state.atomCache.get(declKey);\n\tif (className !== undefined) {\n\t\t// Touch the sheet so a swapped document (tests) gets the replayed rules.\n\t\tensureSheet();\n\t\treturn className;\n\t}\n\n\tif (name === undefined) {\n\t\tclassName = \"n\" + hash(declKey);\n\t} else {\n\t\tclassName = exactName ? name : name + \"-\" + hash(declKey);\n\t\tif (state.atomMeta.has(className)) {\n\t\t\t// eslint-disable-next-line no-console\n\t\t\tconsole.warn(\n\t\t\t\t`[nuclo] css() name ${JSON.stringify(className)} is already used by a different style. ` +\n\t\t\t\t\t\"Both rules are emitted under the same class, so they will override each other — rename one.\",\n\t\t\t);\n\t\t}\n\t}\n\n\tlet body = \"\";\n\tfor (const [prop, value] of decls) body += (body ? \";\" : \"\") + prop + \":\" + value;\n\tstate.atomCache.set(declKey, className);\n\tstate.atomMeta.set(className, { query, suffix, decls, name });\n\trecord(selectorFor(className, suffix) + \"{\" + body + \"}\", query);\n\treturn className;\n}\n\n/**\n * One class per (query, selector-suffix) — every declaration that shares that\n * context compiles into a single rule under a single generated class name,\n * rather than one class per individual property. Pass `name` to give the\n * style a stable, readable identity (see mintBlock).\n */\nexport function atomBlock(\n\tquery: string | undefined,\n\tsuffix: string,\n\tdecls: ReadonlyArray<readonly [string, string]>,\n\tname?: string,\n\texactName = false,\n): string {\n\treturn mintBlock(query, suffix, decls, name, exactName);\n}\n\n/**\n * Merge two same-context generated classes into one: `second`'s declarations\n * override `first`'s per exact property (shorthand/longhand interplay is left\n * to CSS order), and the combined block mints its own content-addressed class\n * — so cx(base, override) keeps base's untouched properties instead of\n * dropping the whole base class. Deterministic: the same pair always yields\n * the same class name, on server and client alike. A named base passes its\n * name down as a prefix, so `cx(appRoot, active)` reads as `app-root-1a2b3c`.\n */\nexport function mergeBlocks(first: string, second: string): string {\n\tconst state = getState();\n\tconst a = state.atomMeta.get(first);\n\tconst b = state.atomMeta.get(second);\n\tif (!a || !b) return second; // unknown input — nothing to merge with\n\tconst concat = [...a.decls, ...b.decls];\n\t// Keep only the last occurrence of each exact property, at its position —\n\t// so a later `padding` still fully resets an earlier `padding-top`.\n\tconst lastIndex = new Map<string, number>();\n\tfor (let i = 0; i < concat.length; i++) lastIndex.set(concat[i][0], i);\n\tconst merged = concat.filter((decl, i) => lastIndex.get(decl[0]) === i);\n\treturn mintBlock(a.query, a.suffix, merged, a.name ?? b.name);\n}\n\n/** Conflict key (query|suffix) for a generated class — lets cx() group classes by selector context. */\nexport function conflictKeyOf(className: string): string | undefined {\n\tconst state = getState();\n\tconst meta = state.atomMeta.get(className);\n\treturn meta === undefined ? undefined : contextKeyOf(meta.query, meta.suffix);\n}\n\n/** Current registry generation, used to invalidate per-instance WeakMap hits after resetStyles(). */\nexport function getStyleEpoch(): number {\n\treturn (cachedState ?? globalScope[ENGINE_STATE_KEY])?.styleEpoch ?? 0;\n}\n\n/** Register a non-atomic rule (keyframes, global styles) once per dedupe key. */\nexport function addRawRule(dedupeKey: string, rule: string): void {\n\tconst state = getState();\n\tif (state.rawKeys.has(dedupeKey)) {\n\t\tensureSheet();\n\t\treturn;\n\t}\n\tstate.rawKeys.add(dedupeKey);\n\trecord(rule, undefined);\n}\n\n/** All generated CSS — base rules first, then at-rule groups in registration order. */\nexport function getCssText(): string {\n\tconst state = getState();\n\tif (state.cssTextCache !== null) return state.cssTextCache;\n\tlet out = state.baseRules.join(\"\");\n\tfor (const [query, rules] of state.queryRules) {\n\t\tif (rules.length > 0) out += query + \"{\" + rules.join(\"\") + \"}\";\n\t}\n\tstate.cssTextCache = out;\n\treturn out;\n}\n\n/** Clear all engine state (test helper). Removes the injected style element. */\nexport function resetStyles(): void {\n\tconst state = getState();\n\tstate.atomCache.clear();\n\tstate.atomMeta.clear();\n\tstate.rawKeys.clear();\n\tstate.baseRules.length = 0;\n\tstate.queryRules.clear();\n\tstate.groupRules.clear();\n\tstate.cssTextCache = null;\n\tstate.baseRuleCount = 0;\n\tstate.sheet = null;\n\tstate.sheetDocument = null;\n\tstate.externalRules = null;\n\tstate.hasExternalGroups = false;\n\tstate.styleEpoch++;\n\tif (typeof document !== \"undefined\") {\n\t\tdocument.getElementById(\"nuclo-styles\")?.remove();\n\t}\n}\n","/**\n * nuclo styling — theme-aware, typed CSS-in-TS.\n *\n * One typed object in, one generated class per selector context out (a class\n * groups every declaration that shares its query + pseudo-selector, so a\n * base style and a :hover override always compile to at least two classes):\n *\n * const { css, cx } = createCss({\n * colors: { primary: \"#6366f1\" },\n * screens: { md: \"(min-width: 768px)\" },\n * });\n * const button = css({ px: 24, py: 12, bg: \"primary\", rounded: 8, hover: { bg: \"#4f46e5\" } });\n * div(button, \"Save\"); // button is { className } — a regular nuclo attributes object\n */\nimport { atomBlock, addRawRule, conflictKeyOf, ensureSheet, expandAmpersands, getStyleEpoch, hash, mergeBlocks, registerQueries } from \"./engine\";\n\n// ---------------------------------------------------------------------------\n// Types live in types/style.d.ts (shipped with the package) so the published\n// global declarations can import them without reaching into unpublished src/.\n// They are re-exported here so module-style consumers keep the same surface.\n// ---------------------------------------------------------------------------\nimport type {\n\tClassInput,\n\tCssInstance,\n\tFlatStyle,\n\tKeyframeFrames,\n\tPseudo,\n\tStyle,\n\tStyleResult,\n\tThemeConfig,\n\tVariantDefinitions,\n\tVariantProps,\n\tVariantsConfig,\n\tVariantsFn,\n} from \"../../types/style\";\n\nexport type {\n\tClassInput,\n\tCssInstance,\n\tCSSProperties,\n\tFlatStyle,\n\tKeyframeFrames,\n\tKeyframeStop,\n\tPseudo,\n\tSize,\n\tStyle,\n\tStyleResult,\n\tThemeConfig,\n\tVariantDefinitions,\n\tVariantProps,\n\tVariantsConfig,\n\tVariantsFn,\n} from \"../../types/style\";\n\n\nconst PSEUDO = {\n\thover: \":hover\",\n\tfocus: \":focus\",\n\tfocusVisible: \":focus-visible\",\n\tfocusWithin: \":focus-within\",\n\tactive: \":active\",\n\tvisited: \":visited\",\n\tdisabled: \":disabled\",\n\tenabled: \":enabled\",\n\tchecked: \":checked\",\n\trequired: \":required\",\n\tinvalid: \":invalid\",\n\tvalid: \":valid\",\n\treadOnly: \":read-only\",\n\tfirst: \":first-child\",\n\tlast: \":last-child\",\n\tonly: \":only-child\",\n\todd: \":nth-child(odd)\",\n\teven: \":nth-child(even)\",\n\tempty: \":empty\",\n\tplaceholderShown: \":placeholder-shown\",\n\tplaceholder: \"::placeholder\",\n\tbefore: \"::before\",\n\tafter: \"::after\",\n\tselection: \"::selection\",\n\tmarker: \"::marker\",\n\tfirstLine: \"::first-line\",\n\tfirstLetter: \"::first-letter\",\n} as const satisfies Record<Pseudo, string>;\n\n// ---------------------------------------------------------------------------\n// Runtime tables\n// ---------------------------------------------------------------------------\nconst ALIAS: Record<string, readonly string[]> = {\n\tbg: [\"background\"],\n\tp: [\"padding\"],\n\tpx: [\"padding-left\", \"padding-right\"],\n\tpy: [\"padding-top\", \"padding-bottom\"],\n\tpt: [\"padding-top\"], pr: [\"padding-right\"], pb: [\"padding-bottom\"], pl: [\"padding-left\"],\n\tm: [\"margin\"],\n\tmx: [\"margin-left\", \"margin-right\"],\n\tmy: [\"margin-top\", \"margin-bottom\"],\n\tmt: [\"margin-top\"], mr: [\"margin-right\"], mb: [\"margin-bottom\"], ml: [\"margin-left\"],\n\tw: [\"width\"], h: [\"height\"],\n\tminW: [\"min-width\"], maxW: [\"max-width\"], minH: [\"min-height\"], maxH: [\"max-height\"],\n\tsize: [\"width\", \"height\"],\n\ttext: [\"font-size\"],\n\tfont: [\"font-family\"],\n\tweight: [\"font-weight\"],\n\tleading: [\"line-height\"],\n\ttracking: [\"letter-spacing\"],\n\talign: [\"text-align\"],\n\titems: [\"align-items\"],\n\tjustify: [\"justify-content\"],\n\tz: [\"z-index\"],\n\trounded: [\"border-radius\"],\n\tshadow: [\"box-shadow\"],\n\tselect: [\"user-select\"],\n};\n\nconst COMPOSITE: Record<string, Record<string, string>> = {\n\trow: { display: \"flex\", \"flex-direction\": \"row\" },\n\tcol: { display: \"flex\", \"flex-direction\": \"column\" },\n\tcenter: { \"align-items\": \"center\", \"justify-content\": \"center\" },\n\ttruncate: { overflow: \"hidden\", \"text-overflow\": \"ellipsis\", \"white-space\": \"nowrap\" },\n};\n\n/** CSS property → theme token table it resolves against. */\nconst TOKEN_PROP: Record<string, keyof ThemeConfig> = {\n\tbackground: \"colors\",\n\t\"background-color\": \"colors\",\n\tcolor: \"colors\",\n\t\"border-color\": \"colors\",\n\t\"border-top-color\": \"colors\",\n\t\"border-right-color\": \"colors\",\n\t\"border-bottom-color\": \"colors\",\n\t\"border-left-color\": \"colors\",\n\t\"outline-color\": \"colors\",\n\t\"caret-color\": \"colors\",\n\t\"text-decoration-color\": \"colors\",\n\t\"font-family\": \"fonts\",\n\t\"box-shadow\": \"shadows\",\n\t\"border-radius\": \"radii\",\n};\n\n/** Properties where bare numbers stay unitless instead of becoming px. */\nconst UNITLESS = new Set([\n\t\"z-index\", \"opacity\", \"font-weight\", \"line-height\", \"flex\", \"flex-grow\",\n\t\"flex-shrink\", \"order\", \"aspect-ratio\", \"zoom\", \"scale\", \"column-count\",\n\t\"orphans\", \"widows\", \"tab-size\", \"animation-iteration-count\", \"grid-column\", \"grid-row\",\n]);\n\n// Cache only conversions, with a ceiling for arbitrary custom property names.\nconst kebabCache = new Map<string, string>();\nfunction kebab(prop: string): string {\n\tif (!/[A-Z]/.test(prop)) return prop;\n\tlet out = kebabCache.get(prop);\n\tif (out === undefined) {\n\t\tout = prop.replace(/[A-Z]/g, (m) => \"-\" + m.toLowerCase());\n\t\tif (kebabCache.size >= 512) kebabCache.clear();\n\t\tkebabCache.set(prop, out);\n\t}\n\treturn out;\n}\n\nfunction toQuery(screen: string): string {\n\treturn screen.charCodeAt(0) === 64 /* @ */ ? screen : \"@media \" + screen;\n}\n\nfunction combineQuery(outer: string | undefined, inner: string): string {\n\t// Nested @media conditions combine with \"and\"; other combinations: inner wins.\n\tif (outer !== undefined && outer.startsWith(\"@media\") && inner.startsWith(\"@media\")) {\n\t\treturn outer + \" and\" + inner.slice(6);\n\t}\n\treturn inner;\n}\n\n/**\n * Deep-merge style objects, later sources winning per property — recurses\n * into nested pseudo/screen/&/@ blocks and `raw` so a style set two levels\n * deep still overrides precisely. Used by variants() to combine base with\n * selected variants/compounds *before* compiling: css() mints one class per\n * selector context, so merging after compilation (via cx()) would only be\n * able to replace a whole context's class, not override one property in it.\n */\nfunction mergeStyle(target: Record<string, unknown>, source: Record<string, unknown>): Record<string, unknown> {\n\tfor (const key in source) {\n\t\tconst value = source[key];\n\t\tconst existing = target[key];\n\t\tif (\n\t\t\tvalue !== null && typeof value === \"object\" && !Array.isArray(value) &&\n\t\t\texisting !== null && typeof existing === \"object\" && !Array.isArray(existing)\n\t\t) {\n\t\t\ttarget[key] = mergeStyle({ ...(existing as Record<string, unknown>) }, value as Record<string, unknown>);\n\t\t} else {\n\t\t\ttarget[key] = value;\n\t\t}\n\t}\n\treturn target;\n}\n\n// A class rather than an object literal + Object.defineProperty: toString()\n// lives on the prototype, which is non-enumerable by spec at no per-call\n// cost — attribute application iterates Object.keys()/for-in and must only\n// see className, same contract the old defineProperty call paid for on\n// every mint. This runs on every cx() call (no cache) and every css() cache\n// miss, so the allocation shape matters.\nclass StyleResultImpl {\n\treadonly className: string;\n\tconstructor(className: string) {\n\t\tthis.className = className;\n\t}\n\ttoString(): string {\n\t\treturn this.className;\n\t}\n}\n\nfunction makeResult(className: string): StyleResult {\n\treturn new StyleResultImpl(className);\n}\n\nfunction pickClass(picked: Map<string, string>, name: string): void {\n\tconst key = conflictKeyOf(name);\n\tif (key === undefined) {\n\t\t// External class the engine didn't mint — pass through, dedupe by name.\n\t\tpicked.set(name, name);\n\t\treturn;\n\t}\n\tconst prev = picked.get(key);\n\tif (prev === undefined || prev === name) picked.set(key, name);\n\t// Same selector context seen twice: merge declaration-wise, later wins per\n\t// property. Minting is content-addressed, so a redundant merge (override\n\t// restates every property) collapses back to the override's own class.\n\telse picked.set(key, mergeBlocks(prev, name));\n}\n\nfunction collectClassString(className: string, picked: Map<string, string>): void {\n\tlet start = 0;\n\tfor (let i = 0; i <= className.length; i++) {\n\t\tconst code = i === className.length ? 32 : className.charCodeAt(i);\n\t\tconst whitespace = code === 32 || code === 9 || code === 10 || code === 12 || code === 13;\n\t\tif (!whitespace) continue;\n\t\tif (i > start) pickClass(picked, className.slice(start, i));\n\t\tstart = i + 1;\n\t}\n}\n\nfunction collectClasses(inputs: readonly ClassInput[], picked: Map<string, string>): void {\n\tfor (const input of inputs) {\n\t\tif (!input) continue;\n\t\tif (typeof input === \"string\") {\n\t\t\tcollectClassString(input, picked);\n\t\t} else if (Array.isArray(input)) {\n\t\t\tcollectClasses(input, picked);\n\t\t} else {\n\t\t\tcollectClassString((input as StyleResult).className, picked);\n\t\t}\n\t}\n}\n\nfunction composeClassName(inputs: readonly ClassInput[]): string {\n\tconst picked = new Map<string, string>();\n\tcollectClasses(inputs, picked);\n\tlet className = \"\";\n\tfor (const name of picked.values()) className += (className ? \" \" : \"\") + name;\n\treturn className;\n}\n\n// Memoizes cx(a, b) by the identity of its two arguments — the shape of a\n// per-render `cx(base, active)` conditional-class helper, called with the\n// same two object references every time. Mirrors css()'s own memo (below):\n// nested WeakMaps so entries die with either argument, epoch-gated so a\n// resetStyles() call can't hand back a className with no backing rule.\nconst cxPairMemo = new WeakMap<object, WeakMap<object, { epoch: number; first: string; second: string; result: StyleResult }>>();\n\nfunction isPlainCxObject(value: ClassInput): value is StyleResult {\n\treturn !!value && typeof value === \"object\" && !Array.isArray(value);\n}\n\n/**\n * Compose class lists with exact conflict resolution: when two inputs style\n * the same (query, selector-suffix) context, their declaration blocks merge\n * with the later input winning per property — the merged block gets its own\n * content-addressed class, so `cx(base, active)` keeps every base property\n * the active style doesn't override. Works because the engine remembers what\n * every class it minted means. Unknown external classes pass through as-is.\n * Nested arrays are flattened, so `cx([a, cond && b], c)` composes the same\n * as `cx(a, cond && b, c)`.\n */\nexport function cx(...inputs: ClassInput[]): StyleResult {\n\tif (inputs.length === 0) return makeResult(\"\");\n\tif (inputs.length === 1) {\n\t\tconst only = inputs[0];\n\t\tif (!only) return makeResult(\"\");\n\t\tif (!Array.isArray(only)) {\n\t\t\tconst name = typeof only === \"string\" ? only : (only as StyleResult).className;\n\t\t\t// Multiple tokens may include conflicting generated classes even in one input.\n\t\t\tif (!/[\\t\\n\\f\\r ]/.test(name)) return makeResult(name);\n\t\t}\n\t}\n\n\tif (inputs.length === 2 && isPlainCxObject(inputs[0]) && isPlainCxObject(inputs[1])) {\n\t\tconst a = inputs[0] as object;\n\t\tconst b = inputs[1] as object;\n\t\tconst epoch = getStyleEpoch();\n\t\tconst inner = cxPairMemo.get(a);\n\t\tconst hit = inner?.get(b);\n\t\tif (hit !== undefined && hit.epoch === epoch && hit.first === inputs[0].className && hit.second === inputs[1].className) {\n\t\t\tensureSheet();\n\t\t\treturn hit.result;\n\t\t}\n\n\t\tconst result = makeResult(composeClassName(inputs));\n\t\tconst bucket = inner ?? new WeakMap<object, { epoch: number; first: string; second: string; result: StyleResult }>();\n\t\tbucket.set(b, { epoch, first: inputs[0].className, second: inputs[1].className, result });\n\t\tif (!inner) cxPairMemo.set(a, bucket);\n\t\treturn result;\n\t}\n\n\treturn makeResult(composeClassName(inputs));\n}\n\n// ---------------------------------------------------------------------------\n// Factory\n// ---------------------------------------------------------------------------\nexport function createCss<const T extends ThemeConfig>(theme: T = {} as T): CssInstance<T> {\n\tconst screens: Record<string, string> = theme.screens ?? {};\n\tregisterQueries(Object.values(screens).map(toQuery));\n\n\t// Fast path for repeated css() calls on the same style object. Holds the\n\t// name it was compiled under so a re-compile under a different name can't\n\t// hand back the wrong classes. WeakMap: entries die with the style object.\n\tconst memo = new WeakMap<object, { epoch: number; name: string | undefined; result: StyleResult }>();\n\n\tfunction toCssValue(prop: string, value: string | number): string {\n\t\tif (typeof value === \"number\") {\n\t\t\treturn value === 0 || UNITLESS.has(prop) ? String(value) : value + \"px\";\n\t\t}\n\t\tconst group = TOKEN_PROP[prop];\n\t\tif (group !== undefined) {\n\t\t\tconst hit = (theme[group] as Record<string, string> | undefined)?.[value];\n\t\t\tif (hit !== undefined) return hit;\n\t\t}\n\t\treturn value;\n\t}\n\n\t/** Every (query, selector-suffix) context touched by one css() call collects its declarations here, then compiles to a single class. */\n\ttype Bucket = { query: string | undefined; suffix: string; decls: Array<[string, string]> };\n\n\tfunction bucketFor(buckets: Map<string, Bucket>, query: string | undefined, suffix: string): Bucket {\n\t\tconst queryPart = query === undefined ? \"-\" : \"+\" + query.length + \":\" + query;\n\t\tconst key = queryPart + suffix.length + \":\" + suffix;\n\t\tlet bucket = buckets.get(key);\n\t\tif (!bucket) {\n\t\t\tbucket = { query, suffix, decls: [] };\n\t\t\tbuckets.set(key, bucket);\n\t\t}\n\t\treturn bucket;\n\t}\n\n\tfunction walk(style: Record<string, unknown>, query: string | undefined, suffix: string, buckets: Map<string, Bucket>): void {\n\t\tfor (const key in style) {\n\t\t\tconst value = style[key];\n\t\t\tif (value == null || value === false) continue;\n\n\t\t\tif (typeof value === \"object\") {\n\t\t\t\tif (key === \"raw\") {\n\t\t\t\t\tconst raws = value as Record<string, string | number>;\n\t\t\t\t\tconst decls = bucketFor(buckets, query, suffix).decls;\n\t\t\t\t\tfor (const prop in raws) decls.push([prop, toCssValue(prop, raws[prop])]);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tconst pseudo = (PSEUDO as Record<string, string | undefined>)[key];\n\t\t\t\tif (pseudo !== undefined) {\n\t\t\t\t\twalk(value as Record<string, unknown>, query, suffix + pseudo, buckets);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tconst screen = screens[key];\n\t\t\t\tif (screen !== undefined) {\n\t\t\t\t\twalk(value as Record<string, unknown>, combineQuery(query, toQuery(screen)), suffix, buckets);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tconst first = key.charCodeAt(0);\n\t\t\t\tif (first === 38 /* & */) {\n\t\t\t\t\tconst nested = expandAmpersands(key, \"&\" + suffix);\n\t\t\t\t\twalk(value as Record<string, unknown>, query, nested.slice(1), buckets);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (first === 64 /* @ */) {\n\t\t\t\t\twalk(value as Record<string, unknown>, combineQuery(query, key), suffix, buckets);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tcontinue; // unknown nested key — unreachable through the typed API\n\t\t\t}\n\n\t\t\tif (value === true) {\n\t\t\t\tconst composite = COMPOSITE[key];\n\t\t\t\tif (composite) {\n\t\t\t\t\tconst decls = bucketFor(buckets, query, suffix).decls;\n\t\t\t\t\tfor (const prop in composite) decls.push([prop, composite[prop]]);\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst targets = ALIAS[key];\n\t\t\tif (targets !== undefined) {\n\t\t\t\tconst decls = bucketFor(buckets, query, suffix).decls;\n\t\t\t\tfor (const prop of targets) decls.push([prop, toCssValue(prop, value as string | number)]);\n\t\t\t} else {\n\t\t\t\tconst prop = kebab(key);\n\t\t\t\tbucketFor(buckets, query, suffix).decls.push([prop, toCssValue(prop, value as string | number)]);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Compile a style object into classes — one per (query, selector-suffix)\n\t * context it touches, not one per property. Idempotent and cached.\n\t *\n\t * An optional leading name gives the style a stable, readable identity:\n\t *\n\t * css(\"app-root\", { minHeight: \"100vh\", hover: { color: \"red\" } })\n\t * // → \"app-root app-root-1a2b3c\"\n\t *\n\t * The base context takes the name verbatim; the style's other contexts\n\t * (pseudo-selectors, media queries) take it as a prefix on a\n\t * content-addressed suffix so they stay greppable without ever colliding.\n\t * Named styles are keyed by name as well as content, so they never share a\n\t * class with an unrelated style — which also means they don't dedupe\n\t * against identical anonymous blocks. Name the styles you want to find in\n\t * devtools; leave the rest anonymous to keep the sheet small.\n\t */\n\tfunction css(style: Style<T>): StyleResult;\n\tfunction css(name: string, style: Style<T>): StyleResult;\n\tfunction css(nameOrStyle: string | Style<T>, maybeStyle?: Style<T>): StyleResult {\n\t\tconst named = typeof nameOrStyle === \"string\";\n\t\tconst style = (named ? maybeStyle : nameOrStyle) as Style<T>;\n\t\tconst name = named ? nameOrStyle : undefined;\n\t\tif (style == null) return makeResult(\"\");\n\n\t\t// The memo is keyed by style-object identity; the same object compiled\n\t\t// under two different names must not reuse the first result.\n\t\tconst epoch = getStyleEpoch();\n\t\tconst hit = memo.get(style);\n\t\tif (hit !== undefined && hit.epoch === epoch && hit.name === name) {\n\t\t\tensureSheet();\n\t\t\treturn hit.result;\n\t\t}\n\n\t\tconst buckets = new Map<string, Bucket>();\n\t\twalk(style as Record<string, unknown>, undefined, \"\", buckets);\n\t\tconst classes: string[] = [];\n\t\tfor (const bucket of buckets.values()) {\n\t\t\tif (bucket.decls.length === 0) continue;\n\t\t\tconst isBase = bucket.query === undefined && bucket.suffix === \"\";\n\t\t\tclasses.push(atomBlock(bucket.query, bucket.suffix, bucket.decls, name, isBase));\n\t\t}\n\t\tconst result = makeResult(classes.join(\" \"));\n\t\tmemo.set(style, { epoch, name, result });\n\t\treturn result;\n\t}\n\n\tfunction flatDecls(style: Record<string, unknown>): string {\n\t\tlet decls = \"\";\n\t\tconst push = (prop: string, v: string): void => {\n\t\t\tdecls += (decls ? \";\" : \"\") + prop + \":\" + v;\n\t\t};\n\t\tfor (const key in style) {\n\t\t\tconst value = style[key];\n\t\t\tif (value == null || value === false) continue;\n\t\t\tif (key === \"raw\" && typeof value === \"object\") {\n\t\t\t\tconst raws = value as Record<string, string | number>;\n\t\t\t\tfor (const prop in raws) push(prop, toCssValue(prop, raws[prop]));\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (typeof value === \"object\") continue;\n\t\t\tif (value === true) {\n\t\t\t\tconst composite = COMPOSITE[key];\n\t\t\t\tif (composite) for (const prop in composite) push(prop, composite[prop]);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst targets = ALIAS[key];\n\t\t\tif (targets !== undefined) {\n\t\t\t\tfor (const prop of targets) push(prop, toCssValue(prop, value as string | number));\n\t\t\t} else {\n\t\t\t\tconst prop = kebab(key);\n\t\t\t\tpush(prop, toCssValue(prop, value as string | number));\n\t\t\t}\n\t\t}\n\t\treturn decls;\n\t}\n\n\t/** Register a @keyframes block; returns its generated name for use in `animation`. */\n\tfunction keyframes(frames: KeyframeFrames<T>): string {\n\t\tlet body = \"\";\n\t\tfor (const stop in frames) {\n\t\t\tbody += stop + \"{\" + flatDecls(frames[stop] as Record<string, unknown>) + \"}\";\n\t\t}\n\t\tconst name = \"nk\" + hash(body);\n\t\taddRawRule(name, \"@keyframes \" + name + \"{\" + body + \"}\");\n\t\treturn name;\n\t}\n\n\t/** Global selector styles (body, resets). Flat properties only. */\n\tfunction globalStyle(selector: string, style: FlatStyle<T>): void {\n\t\tconst rule = selector + \"{\" + flatDecls(style as Record<string, unknown>) + \"}\";\n\t\taddRawRule(\"g|\" + rule, rule);\n\t}\n\n\t/**\n\t * Compile a typed variants recipe into a call-with-props function.\n\t *\n\t * const button = variants({\n\t * base: { rounded: 8, weight: 600 },\n\t * variants: {\n\t * intent: { primary: { bg: \"primary\" }, danger: { bg: \"danger\" } },\n\t * size: { sm: { px: 8, py: 4 }, lg: { px: 16, py: 10 } },\n\t * block: { true: { display: \"block\", w: \"100%\" } },\n\t * },\n\t * defaultVariants: { intent: \"primary\", size: \"sm\" },\n\t * compoundVariants: [{ intent: \"danger\", size: \"lg\", css: { weight: 700 } }],\n\t * });\n\t * div(button({ intent: \"danger\", size: \"lg\" }), \"Delete\");\n\t *\n\t * A call resolves defaults + props into a selection, deep-merges base with\n\t * every matching variant/compound's raw style object (later sources win\n\t * per property — not per class, since css() now mints one class per\n\t * selector context rather than one per property), compiles the merge with\n\t * css(), and caches the result per selection — repeated calls are a Map\n\t * lookup.\n\t */\n\tfunction variants<const V extends VariantDefinitions<T>>(\n\t\tconfig: VariantsConfig<T, V>,\n\t): VariantsFn<V> {\n\t\tconst normalize = (value: unknown): string =>\n\t\t\tvalue === true ? \"true\" : value === false ? \"false\" : String(value);\n\n\t\tconst groups = (config.variants ?? {}) as Record<string, Record<string, Style<T>>>;\n\t\tconst groupNames = Object.keys(groups);\n\t\tconst defaults = (config.defaultVariants ?? {}) as Record<string, unknown>;\n\t\tconst baseStyle = (config.base ?? null) as Record<string, unknown> | null;\n\n\t\tconst compounds = (config.compoundVariants ?? []).map((entry) => {\n\t\t\tconst { css: compoundStyle, ...match } = entry as VariantProps<V> & { css: Style<T> };\n\t\t\tconst conditions: Record<string, string> = {};\n\t\t\tfor (const group in match) conditions[group] = normalize((match as Record<string, unknown>)[group]);\n\t\t\treturn { conditions, style: compoundStyle as Record<string, unknown> };\n\t\t});\n\n\t\tconst cache = new Map<string, StyleResult>();\n\t\tlet cacheEpoch = getStyleEpoch();\n\n\t\treturn function recipe(props?: VariantProps<V>): StyleResult {\n\t\t\tconst epoch = getStyleEpoch();\n\t\t\tif (cacheEpoch !== epoch) {\n\t\t\t\tcache.clear();\n\t\t\t\tcacheEpoch = epoch;\n\t\t\t}\n\t\t\t// Resolve final selection: defaults, overridden by explicit props.\n\t\t\tconst selection: Record<string, string> = {};\n\t\t\tfor (const group of groupNames) {\n\t\t\t\tconst provided = props ? (props as Record<string, unknown>)[group] : undefined;\n\t\t\t\tconst chosen = provided !== undefined && provided !== null ? provided : defaults[group];\n\t\t\t\tif (chosen === undefined || chosen === null) continue;\n\t\t\t\tselection[group] = normalize(chosen);\n\t\t\t}\n\n\t\t\t// Cache the compiled result per selection (stable group order).\n\t\t\tlet key = \"\";\n\t\t\tfor (const group of groupNames) {\n\t\t\t\tconst value = selection[group];\n\t\t\t\tkey += group.length + \":\" + group;\n\t\t\t\tkey += value === undefined ? \"-\" : \"+\" + value.length + \":\" + value;\n\t\t\t}\n\t\t\tconst cached = cache.get(key);\n\t\t\tif (cached) {\n\t\t\t\tensureSheet();\n\t\t\t\treturn cached;\n\t\t\t}\n\n\t\t\tlet merged: Record<string, unknown> = {};\n\t\t\tif (baseStyle) merged = mergeStyle(merged, baseStyle);\n\t\t\tfor (const group of groupNames) {\n\t\t\t\tconst value = selection[group];\n\t\t\t\tif (value !== undefined) {\n\t\t\t\t\tconst style = groups[group][value];\n\t\t\t\t\tif (style) merged = mergeStyle(merged, style as Record<string, unknown>);\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor (const compound of compounds) {\n\t\t\t\tlet matches = true;\n\t\t\t\tfor (const group in compound.conditions) {\n\t\t\t\t\tif (selection[group] !== compound.conditions[group]) {\n\t\t\t\t\t\tmatches = false;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (matches) merged = mergeStyle(merged, compound.style);\n\t\t\t}\n\n\t\t\tconst result = css(merged as Style<T>);\n\t\t\tcache.set(key, result);\n\t\t\treturn result;\n\t\t};\n\t}\n\n\treturn { css, cx, variants, keyframes, globalStyle, theme };\n}\n\n// ---------------------------------------------------------------------------\n// Default themeless instance — registered as globals by the runtime bootstrap.\n// Apps with design tokens create their own instance via createCss(theme).\n//\n// Built lazily on first use rather than at module load: most apps that\n// import nuclo never call css()/variants()/keyframes()/globalStyle(), and\n// createCss() eagerly allocates a memo WeakMap and walks the (empty) theme's\n// screens — work worth skipping entirely for those apps.\n// ---------------------------------------------------------------------------\nlet defaultInstance: CssInstance<object> | undefined;\nfunction getDefaultInstance(): CssInstance<object> {\n\treturn (defaultInstance ??= createCss({}));\n}\n\n/** Themeless css() — full property/variant typing, no tokens or screens. */\nexport const css: {\n\t(style: Style<object>): StyleResult;\n\t(name: string, style: Style<object>): StyleResult;\n} = (nameOrStyle: string | Style<object>, style?: Style<object>): StyleResult =>\n\ttypeof nameOrStyle === \"string\"\n\t\t? getDefaultInstance().css(nameOrStyle, style as Style<object>)\n\t\t: getDefaultInstance().css(nameOrStyle);\n/** Themeless variants() recipe helper. */\nexport const variants: <const V extends VariantDefinitions<object>>(\n\tconfig: VariantsConfig<object, V>,\n) => VariantsFn<V> = (config) => getDefaultInstance().variants(config);\n/** Themeless keyframes() helper. */\nexport const keyframes: (frames: KeyframeFrames<object>) => string = (frames) => getDefaultInstance().keyframes(frames);\n/** Themeless globalStyle() helper. */\nexport const globalStyle: (selector: string, style: FlatStyle<object>) => void = (selector, style) =>\n\tgetDefaultInstance().globalStyle(selector, style);\n","import { registerGlobalTagBuilders } from \"./element/tags\";\nimport { list } from \"./list\";\nimport { update } from \"./update/update\";\nimport { when } from \"./when\";\nimport { on } from \"./element/events\";\nimport { render, hydrate } from \"./render\";\nimport { scope } from \"./update/scope\";\nimport { createCss, css, cx, variants, keyframes, globalStyle } from \"./style\";\n\n/**\n * Initializes the nuclo runtime by exposing tag builders and utilities.\n */\n\nexport function initializeRuntime(): void {\n registerGlobalTagBuilders();\n\n const registry = globalThis as Record<string, unknown>;\n registry.list = list;\n registry.update = update;\n registry.when = when;\n registry.on = on;\n registry.scope = scope;\n registry.render = render;\n registry.hydrate = hydrate;\n\n // Styling — a themeless default instance plus the factory for themed ones.\n // None of these names collide with window/globalThis properties.\n registry.createCss = createCss;\n registry.css = css;\n registry.cx = cx;\n registry.variants = variants;\n registry.keyframes = keyframes;\n registry.globalStyle = globalStyle;\n}\n\ninitializeRuntime();\n"],"mappings":"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"}
|