nuclo 0.3.5 → 0.3.7

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.
@@ -1 +1 @@
1
- {"version":3,"file":"nuclo.cjs","names":[],"sources":["../src/shared/errors.ts","../src/shared/environment.ts","../src/update/registry.ts","../src/shared/dom.ts","../src/hydration.ts","../src/element/lifecycle.ts","../src/element/factory-meta.ts","../src/element/events.ts","../src/element/event-attributes.ts","../src/shared/type-guards.ts","../src/update/reactive-text.ts","../src/list/template.ts","../src/list/runtime.ts","../src/update/reactive-attributes.ts","../src/element/inline-style.ts","../src/element/class-name.ts","../src/element/attributes.ts","../src/element/modifiers.ts","../src/when/runtime.ts","../src/when/builder.ts","../src/when/index.ts","../src/update/scope.ts","../src/update/update.ts","../src/list/index.ts","../src/render.ts","../src/style/engine.ts","../src/shared/strings.ts","../src/style/css.ts","../src/element/factory.ts","../src/element/tags.ts","../src/bootstrap.ts"],"sourcesContent":["export function logError(message: string, error?: Error | unknown): void {\n if (typeof console !== 'undefined') {\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 * Shared types and registries for reactive nodes.\n * Single source of truth — imported by reactive-text.ts and reactive-attributes.ts.\n *\n * Registry structure: the iteration sets only hold WeakRefs; the entries live\n * in WeakMaps keyed by the node, one flat object per node (its WeakRef plus\n * its reactive state). Storing entries in a strongly-held map would pin the\n * node in memory forever; with WeakMap storage the whole entry is collectible\n * as 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 = () => unknown;\n\n/**\n * A reactive text node. Resolver results render with the DSL's text\n * semantics: nullish and non-primitive values render as \"\".\n */\nexport interface ReactiveTextEntry {\n ref: WeakRef<Text>;\n resolver: TextResolver;\n lastValue: string;\n}\n\nexport type AttributeResolver = () => unknown;\n\n/**\n * Writes a resolved value to the element. A shared module-level function\n * (not a per-registration closure), so a reactive attribute costs no closure.\n */\nexport type AttributeApplier = (element: Element, key: string, value: unknown) => void;\n\nexport interface AttributeResolverRecord {\n key: string;\n resolver: AttributeResolver;\n apply: AttributeApplier;\n lastValue: unknown;\n}\n\nexport interface ReactiveElementEntry {\n ref: WeakRef<Element>;\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/** Iteration set of weak references to reactive text nodes. */\nexport const reactiveTextNodes = new Set<WeakRef<Text>>();\n\n/** O(1) lookup of a reactive text node's entry. */\nexport const reactiveTextNodesByNode = new WeakMap<Text, ReactiveTextEntry>();\n\n/** Iteration set of weak references to reactive elements. */\nexport const reactiveElements = new Set<WeakRef<Element>>();\n\n/** O(1) lookup of a reactive element's entry. */\nexport const reactiveElementsByNode = new WeakMap<Element, ReactiveElementEntry>();\n\n/**\n * Registers a reactive text node. Re-registration (e.g. repeated hydration)\n * replaces the resolver and last value in place.\n */\nexport function registerReactiveTextNode(node: Text, resolver: TextResolver, lastValue: string): void {\n const existing = reactiveTextNodesByNode.get(node);\n if (existing) {\n existing.resolver = resolver;\n existing.lastValue = lastValue;\n return;\n }\n const ref = new WeakRef(node);\n reactiveTextNodes.add(ref);\n reactiveTextNodesByNode.set(node, { ref, resolver, lastValue });\n}\n\n/** Returns the element's reactive entry, creating and registering it on first use. */\nexport function registerReactiveElement(element: Element): ReactiveElementEntry {\n let entry = reactiveElementsByNode.get(element);\n if (!entry) {\n const ref = new WeakRef(element);\n entry = { ref, attributeResolvers: [] };\n reactiveElements.add(ref);\n reactiveElementsByNode.set(element, entry);\n }\n return entry;\n}\n\n/** Unregisters a reactive text node (called when nuclo removes it). */\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/** Unregisters a reactive element (called when nuclo removes it). */\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","import { logError } from \"./errors\";\nimport { removeAllListeners } from \"../element/events\";\nimport { cleanupReactiveTextNode, cleanupReactiveElement } from \"../update/registry\";\nimport { disposeElementLifecycle, hasActiveLifecycleRegistrations } from \"../element/lifecycle\";\n\nexport const SVG_NAMESPACE = 'http://www.w3.org/2000/svg';\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 removeAllListeners(element);\n cleanupReactiveElement(element);\n } else if (node.nodeType === Node.TEXT_NODE) {\n cleanupReactiveTextNode(node as Text);\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 list()'s bulk clear/replace is about to\n * drop without walking through cleanupNodeTree()/safeRemoveChild(). Callers\n * skip it entirely unless hasActiveLifecycleRegistrations(), so the fast path\n * stays fast when lifecycle hooks aren't in use.\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 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 createMarkerPair(prefix: string, id: number): { start: Comment; end: Comment } {\n return { start: document.createComment(`${prefix}-start-${id}`), end: document.createComment(`${prefix}-end`) };\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\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 = host as unknown as Node & ParentNode;\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 * 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\nimport { safeRemoveChild } from \"./shared/dom\";\n\nlet _hydrating = false;\n// True while forceUpdate() re-hydrates a live, client-rendered tree: text\n// claims work without `<!-- text-N -->` markers and reused elements get their\n// previous listeners/class state reset before modifiers re-apply.\nlet _force = 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/** True only inside a forceUpdate() pass (never during plain hydrate()). */\nexport function isForceHydrating(): boolean {\n return _hydrating && _force;\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(force = false): void {\n _hydrating = true;\n _force = force;\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 _force = 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 * forceUpdate() text claim: claims the next child when it is a bare text node\n * (client renders emit no `<!-- text-N -->` markers). Whitespace-only text\n * that is followed by a text marker is SSR template formatting, not content —\n * it is left for the marker path, which skips it. Returns null when nothing\n * claimable is at the cursor.\n */\nexport function claimBareText(parent: Node): Text | null {\n const next = peekChild(parent);\n if (!next || next.nodeType !== 3) return null;\n if (isWhitespaceText(next)) {\n let sibling = next.nextSibling;\n while (sibling && isWhitespaceText(sibling)) sibling = sibling.nextSibling;\n if (\n sibling && sibling.nodeType === 8 &&\n (sibling.textContent ?? \"\").trimStart().startsWith(\"text-\")\n ) return null;\n }\n claimChild(parent);\n return next as Text;\n}\n\n/**\n * Claims a server-rendered `<!--{prefix}-start-…-->` … `<!--{prefix}-end-->`\n * block (list()/when()) at the cursor, leaving the cursor just after the start\n * marker. Returns null, claiming nothing, when the next child isn't a start\n * marker. Pairs are depth-counted because directly nested blocks share a\n * host. A missing end marker (corrupt/truncated SSR output) is recreated right\n * after the start marker and reported as `recreated`.\n */\nexport function claimMarkerPair(\n parent: Node,\n prefix: \"list\" | \"when\",\n): { start: Comment; end: Comment; recreated: boolean } | null {\n skipWhitespaceText(parent);\n const start = peekChild(parent);\n const startPrefix = prefix + \"-start-\";\n if (!start || start.nodeType !== 8 || !start.textContent?.startsWith(startPrefix)) return null;\n claimChild(parent);\n const endText = prefix + \"-end\";\n let depth = 0;\n for (let node = start.nextSibling; node; node = node.nextSibling) {\n if (node.nodeType !== 8) continue;\n const text = node.textContent;\n if (text === endText) {\n if (depth === 0) return { start: start as Comment, end: node as Comment, recreated: false };\n depth--;\n } else if (text?.startsWith(startPrefix)) {\n depth++;\n }\n }\n const end = document.createComment(endText);\n parent.insertBefore(end, start.nextSibling);\n return { start: start as Comment, end, recreated: true };\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 // safeRemoveChild (not a bare removeChild): during forceUpdate() the\n // unclaimed nodes were live — their listeners, registrations and\n // onDestroy hooks must be released, not just detached.\n safeRemoveChild(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 fast path that intentionally skips that per-node walk for performance\n * (list()'s bulk clear/replace) calls disposeLifecyclesInSubtree() directly\n * instead, so destroy still fires exactly at removal time there too —\n * without paying for a bookkeeping walk when nothing on the page ever\n * registered a lifecycle callback (hasActiveLifecycleRegistrations() makes\n * that a 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 { isForceHydrating, 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}\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 path (list() bulk clear) skip\n * disposeLifecyclesInSubtree()'s walk entirely with a single comparison —\n * true for the overwhelming majority of apps, which never use\n * 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\n/**\n * A new record is Pending and queued exactly once, right here: every later\n * registration for the element finds the record already queued (or already\n * mounted/disposed), so no per-record \"queued\" flag is needed.\n */\nfunction ensureRecord(element: Element): LifecycleRecord {\n let record = records.get(element);\n if (!record) {\n record = { mount: null, destroy: null, state: STATE_PENDING };\n records.set(element, record);\n activeCount++;\n mountQueue.push(new WeakRef(element));\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\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 // forceUpdate() reclaim: the element is already Mounted — its original\n // callbacks stay in force. Re-applied hooks are dropped: mount must not\n // re-fire for an element that never left the document, and repeated force\n // passes must not grow the callback slots.\n if (record.state !== STATE_PENDING && isForceHydrating()) return;\n record.mount = pushSlot(record.mount, callback as MountCallback<Element>);\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 if (record.state !== STATE_PENDING && isForceHydrating()) return; // see registerMount()\n record.destroy = pushSlot(record.destroy, callback as DestroyCallback<Element>);\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 // Queued only by ensureRecord(), right after the record was stored.\n const record = records.get(element)!;\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. Checked once, 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 * and by shared/dom.ts's cleanupNodeTree() to skip snapshotting children.\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 * Detaches every listener on()/nuclo attached to `element` (called when nuclo\n * removes the element).\n */\nexport function removeAllListeners(element: HTMLElement): void {\n const tracked = elementListeners.get(element);\n if (!tracked) return;\n if (Array.isArray(tracked)) {\n for (let i = 0; i < tracked.length; i++) detachListener(element, tracked[i]);\n } else {\n detachListener(element, tracked);\n }\n elementListeners.delete(element);\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","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","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\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","import { logError } from \"../shared/errors\";\nimport type { UpdateScope } from \"./scope\";\nimport { reactiveTextNodes, reactiveTextNodesByNode, registerReactiveTextNode, type TextResolver } from \"./registry\";\nimport { isBrowser } from \"../shared/environment\";\n\n/** DSL text semantics: nullish and non-primitive values render as \"\". */\nexport function toText(value: unknown): string {\n return value == null || typeof value === \"object\" || typeof value === \"function\" ? \"\" : String(value);\n}\n\n/**\n * Creates a text node showing `initial` (the resolver's already-evaluated\n * value) and registers it so every update() re-evaluates `resolver` into it.\n */\nexport function createReactiveTextNode(resolver: TextResolver, initial: unknown): Text {\n const str = toText(initial);\n const txt = document.createTextNode(str);\n if (isBrowser) registerReactiveTextNode(txt, resolver, str);\n return txt;\n}\n\n/**\n * Re-evaluates every registered reactive text node (in `scope`, if given) and\n * writes the ones whose text changed. Disconnected and collected nodes are\n * pruned as the pass goes.\n */\nexport function notifyReactiveTextNodes(scope?: UpdateScope): void {\n for (const ref of reactiveTextNodes) {\n const node = ref.deref();\n const entry = node && reactiveTextNodesByNode.get(node);\n if (!entry || !node.isConnected) {\n if (node) reactiveTextNodesByNode.delete(node);\n reactiveTextNodes.delete(ref);\n continue;\n }\n\n if (scope && !scope.contains(node)) continue;\n\n let value: string;\n try {\n value = toText(entry.resolver());\n } catch (e) {\n logError(\"Failed to update reactive text node\", e);\n value = \"\";\n }\n if (value !== entry.lastValue) {\n node.textContent = value;\n entry.lastValue = value;\n }\n }\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 { isNode } from \"../shared/type-guards\";\nimport { cleanupReactiveElement, cleanupReactiveTextNode } from \"../update/registry\";\nimport { toText } from \"../update/reactive-text\";\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. className-object\n // results (css()/cx()), nodes and nested builders are handled by the\n // normal path only.\n let v: unknown;\n try {\n v = (mod as () => unknown)();\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 = toText(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 = toText(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, safeRemoveChild, disposeLifecyclesInSubtree } from \"../shared/dom\";\nimport { isHydrating, isSerializing, claimMarkerPair, peekChild, setCursor } from \"../hydration\";\nimport type { ListRuntime, ListItemRecord } 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 existing = listRuntimeByMarker.get(startMarker);\n listRuntimeByMarker.set(startMarker, runtime);\n // Re-registration for the same markers (forceUpdate() reclaim): see\n // registerWhenRuntime() — adding another WeakRef would only grow the set.\n if (existing) return;\n const ref = new WeakRef(startMarker);\n activeListRuntimes.add(ref);\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\n/**\n * Resolves a render() result — a tag-builder factory / NodeModFn (called with\n * the host) or an already-built element — to the row element. Anything else\n * (null, primitives, attribute objects, non-element nodes) renders no row.\n */\nfunction toRowElement<TTagName extends ElementTagName>(\n result: unknown,\n host: ExpandedElement<TTagName>,\n index: number,\n): ExpandedElement<TTagName> | null {\n const value = typeof result === \"function\" ? (result as NodeModFn<TTagName>)(host, index) : result;\n return value !== null && typeof value === \"object\" && \"tagName\" in value\n ? value as ExpandedElement<TTagName>\n : null;\n}\n\n/**\n * Renders a row through the un-templated path. Used whenever a row's shape\n * doesn't match (or no longer matches) the list's active template — the\n * 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 return toRowElement(runtime.renderItem(item, index), 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 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 (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 = toRowElement(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 toRowElement(result, runtime.host, index);\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 safeRemoveChild, this does NOT eagerly walk each subtree to detach\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, so they are\n * 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. 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 = document.createDocumentFragment();\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 dynCreatedAt: dyn ? runtime.currentFlushEpoch : undefined,\n });\n runtime.lastRenderLeaves = null;\n fragment.appendChild(element as unknown as Node);\n }\n if (fragment.firstChild) 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++) safeRemoveChild(oldRecords[i].element as unknown as Node);\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++) safeRemoveChild(oldRecords[i].element as unknown as Node);\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++) safeRemoveChild(oldRecords[i].element as unknown as Node);\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]) safeRemoveChild(oldRecords[i].element as unknown as Node);\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 dynCreatedAt: dyn ? runtime.currentFlushEpoch : undefined,\n };\n runtime.lastRenderLeaves = null;\n fragment ??= document.createDocumentFragment();\n fragment.insertBefore(element as unknown as Node, fragment.firstChild);\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\n/** Every field initialized up front so all runtimes share one object shape. */\nfunction newRuntime<TItem, TTagName extends ElementTagName>(\n itemsProvider: ListItemsProvider<TItem>,\n renderItem: ListRenderFunction<TItem, TTagName>,\n startMarker: Comment,\n endMarker: Comment,\n records: ListItemRecord<TItem, TTagName>[],\n host: ExpandedElement<TTagName>,\n lastSyncedItems: readonly TItem[],\n): ListRuntime<TItem, TTagName> {\n return {\n itemsProvider,\n renderItem,\n startMarker,\n endMarker,\n records,\n host,\n lastSyncedItems,\n template: undefined,\n lastRenderLeaves: null,\n currentFlushEpoch: undefined,\n allRecordsCreatedAt: undefined,\n };\n}\n\nexport function createListRuntime<TItem, TTagName extends ElementTagName = ElementTagName>(\n itemsProvider: ListItemsProvider<TItem>,\n renderItem: ListRenderFunction<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: ListRenderFunction<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 = newRuntime(itemsProvider, renderItem, startMarker, endMarker, [], host, []);\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: ListRenderFunction<TItem, TTagName>,\n host: ExpandedElement<TTagName>,\n index: number,\n): ListRuntime<TItem, TTagName> {\n const parentNode = host as unknown as Node & ParentNode;\n\n // No list markers at the cursor: build the list fresh. A recreated end\n // marker (corrupt/truncated SSR output) makes every item claim below miss,\n // so those rows render fresh too.\n const pair = claimMarkerPair(parentNode, \"list\");\n if (!pair) return createListRuntimeNormal(itemsProvider, renderFn, host, index);\n const { start: startMarker, end: endMarker } = pair;\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 element = toRowElement(renderFn(currentItems[i], i), host, i);\n // Same record shape as sync() creates, so record access stays monomorphic.\n if (element) records.push({ item: currentItems[i], element, dyn: null, dynCreatedAt: undefined });\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 = newRuntime(itemsProvider, renderFn, startMarker, endMarker, records, host, currentItems.slice());\n\n if (isBrowser) {\n registerListRuntime(startMarker, runtime as ListRuntime<unknown, ElementTagName>);\n }\n\n return runtime;\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 (!startMarker.isConnected || !runtime.endMarker.isConnected) {\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 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 { logError } from \"../shared/errors\";\nimport type { UpdateScope } from \"./scope\";\nimport { reactiveElements, reactiveElementsByNode, registerReactiveElement } from \"./registry\";\nimport type { AttributeApplier, AttributeResolver, AttributeResolverRecord } from \"./registry\";\nimport { isBrowser } from \"../shared/environment\";\n\nconst UNSET_LAST_VALUE = {};\n\nfunction updateRecord(element: Element, 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 // Objects/arrays may be mutated in place (e.g. style objects), so only\n // primitives are compared against the last applied value.\n const cacheable = nextValue === null || typeof nextValue !== \"object\";\n if (cacheable && Object.is(nextValue, record.lastValue)) return;\n\n try {\n record.apply(element, record.key, 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\n/**\n * Makes `resolver` the reactive source of `element`'s `key`: applied now and\n * re-evaluated on every update(). Registering a key again replaces its\n * previous resolver. During SSR the value is applied once and nothing is\n * registered (update() never runs server-side).\n */\nexport function registerAttributeResolver<TTagName extends ElementTagName>(\n element: ExpandedElement<TTagName>,\n key: string,\n resolver: AttributeResolver,\n apply: AttributeApplier,\n): void {\n const el = element as unknown as Element;\n const record: AttributeResolverRecord = { key, resolver, apply, lastValue: UNSET_LAST_VALUE };\n if (isBrowser) {\n const resolvers = registerReactiveElement(el).attributeResolvers;\n let i = 0;\n while (i < resolvers.length && resolvers[i].key !== key) i++;\n resolvers[i] = record;\n }\n updateRecord(el, record);\n}\n\n/**\n * Re-evaluates the attribute resolvers of every registered reactive element\n * (in `scope`, if given). Disconnected and collected elements are pruned as\n * the pass goes.\n */\nexport function notifyReactiveElements(scope?: UpdateScope): void {\n for (const ref of reactiveElements) {\n const el = ref.deref();\n const entry = el && reactiveElementsByNode.get(el);\n if (!entry || !el.isConnected) {\n if (el) reactiveElementsByNode.delete(el);\n reactiveElements.delete(ref);\n continue;\n }\n\n if (scope && !scope.contains(el)) continue;\n\n const resolvers = entry.attributeResolvers;\n for (let i = 0; i < resolvers.length; i++) updateRecord(el, resolvers[i]);\n }\n}\n","import { isFunction } from \"../shared/type-guards\";\nimport { registerAttributeResolver } from \"../update/reactive-attributes\";\nimport { logError } from \"../shared/errors\";\n\ntype StyleAssignment = CSSStyleObject;\ntype StyleResolver = () => StyleAssignment | null | undefined;\n\n/**\n * Assigns each property of `styles` to the element's inline style (camelCase\n * or kebab-case keys); null, undefined and \"\" remove the property.\n */\nexport function assignInlineStyles<TTagName extends ElementTagName>(\n element: ExpandedElement<TTagName>,\n styles: StyleAssignment | null | undefined,\n): void {\n const style = element.style as unknown as Record<string, string> | undefined;\n if (!style || !styles) return;\n\n for (const property in styles) {\n const value = (styles as Record<string, unknown>)[property];\n try {\n style[property] = value == null ? \"\" : String(value);\n } catch {\n // Don't stringify the value in the message: that may be what threw.\n logError(`Failed to set style property '${property}'`);\n }\n }\n}\n\nfunction applyReactiveStyle(element: Element, _key: string, styles: unknown): void {\n assignInlineStyles(element as unknown as ExpandedElement, styles as StyleAssignment | null | undefined);\n}\n\nexport function applyStyleAttribute<TTagName extends ElementTagName>(\n element: ExpandedElement<TTagName>,\n styleValue: StyleAssignment | StyleResolver | null | undefined\n): void {\n if (isFunction(styleValue)) {\n registerAttributeResolver(element, 'style', styleValue, applyReactiveStyle);\n } else {\n assignInlineStyles(element, styleValue);\n }\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// Drop all className bookkeeping for an element (forceUpdate() reclaim).\nexport function resetClassNameTracking(el: HTMLElement): void {\n\tstaticClassNames.delete(el);\n\treactiveClassNameFlags.delete(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 { 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 neither\n * the static-attribute path (the bulk of attributes in list rows) nor a\n * reactive attribute (it is the registered applier, `merge` left unset)\n * allocates anything per attribute.\n */\nfunction setAttributeValue(\n el: Element,\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 unknown 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\nfunction applyReactiveClassName(el: Element, _key: string, v: unknown): void {\n mergeReactiveClassName(el as HTMLElement, String(v || ''));\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 registerAttributeResolver(el, k, resolver, applyReactiveClassName);\n } else {\n registerAttributeResolver(el, k, resolver, setAttributeValue);\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 as unknown as Element, 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 // 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","/**\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, toText } 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 { isHydrating, isForceHydrating, isSerializing, claimBareText, claimChild, peekChild, setCursor, skipWhitespaceText } from \"../hydration\";\nimport { isBrowser } from \"../shared/environment\";\n\nexport type NodeModifier<TTagName extends ElementTagName = ElementTagName> =\n\t| NodeMod<TTagName>\n\t| NodeModFn<TTagName>\n\t| AnyParentNodeModifier;\n\n/**\n * Shape of a css()/cx() StyleResult: an object whose only own key is\n * `className`. Typed as readonly to signal it should not be mutated.\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 {\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 = document.createTextNode(expected);\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\tconst v = modifier();\n\n\t\t\t\t// A css()/cx() result (only own key: a `className` string) makes this a\n\t\t\t\t// reactive className instead of reactive text.\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 is\n\t\t\t\t\t// registered raw — the notify pass renders nullish/non-primitive\n\t\t\t\t\t// results as \"\" — so no wrapper closure is allocated per text node.\n\t\t\t\t\tif (isHydrating()) {\n\t\t\t\t\t\tconst parentNode = parent as unknown as Node;\n\t\t\t\t\t\tconst expected = toText(v);\n\t\t\t\t\t\t// forceUpdate(): client-rendered text nodes carry no marker —\n\t\t\t\t\t\t// claim the bare text node, patch it, swap in the new resolver.\n\t\t\t\t\t\tif (isForceHydrating()) {\n\t\t\t\t\t\t\tconst claimed = claimBareText(parentNode);\n\t\t\t\t\t\t\tif (claimed) {\n\t\t\t\t\t\t\t\tif (claimed.textContent !== expected) claimed.textContent = expected;\n\t\t\t\t\t\t\t\tregisterReactiveTextNode(claimed, modifier, expected);\n\t\t\t\t\t\t\t\treturn null;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (nextChildIsTextComment(parentNode)) {\n\t\t\t\t\t\t\tclaimChild(parentNode); // skip <!-- text-N --> comment\n\t\t\t\t\t\t\tregisterReactiveTextNode(claimTextAfterMarker(parentNode, expected), modifier, expected);\n\t\t\t\t\t\t\treturn null;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn wrapTextNode(index, createReactiveTextNode(modifier, v));\n\t\t\t\t}\n\t\t\t\treturn null;\n\t\t\t} catch (error) {\n\t\t\t\tlogError(\"Error evaluating reactive text function:\", error);\n\t\t\t\treturn wrapTextNode(index, createReactiveTextNode(emptyText, \"\"));\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 wrapTextNode(index, document.createTextNode(String(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()) {\n\t\t\tconst parentNode = parent as unknown as Node;\n\t\t\tconst expected = String(candidate);\n\t\t\t// forceUpdate(): claim and patch the bare client-rendered text node.\n\t\t\tif (isForceHydrating()) {\n\t\t\t\tconst claimed = claimBareText(parentNode);\n\t\t\t\tif (claimed) {\n\t\t\t\t\tif (claimed.textContent !== expected) claimed.textContent = expected;\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (nextChildIsTextComment(parentNode)) {\n\t\t\t\tclaimChild(parentNode); // skip <!-- text-N --> comment\n\t\t\t\tclaimTextAfterMarker(parentNode, expected);\n\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\t\treturn wrapTextNode(index, document.createTextNode(String(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.\n */\nfunction wrapTextNode(index: number, textNode: Text): Node {\n\tif (isBrowser && !isHydrating() && !isSerializing()) {\n\t\treturn textNode;\n\t}\n\tconst fragment = document.createDocumentFragment();\n\tfragment.appendChild(document.createComment(` text-${index} `));\n\tfragment.appendChild(textNode);\n\treturn fragment;\n}\n\n/** Resolver for text whose first evaluation threw: stays empty. */\nfunction emptyText(): string {\n\treturn \"\";\n}\n","import { clearBetweenMarkers, insertNodesBefore, withScopedInsertion } from \"../shared/dom\";\nimport type { UpdateScope } from \"../update/scope\";\nimport { applyNodeModifier } from \"../element/modifiers\";\nimport { isFunction, isZeroArityFunction } from \"../shared/type-guards\";\nimport { logError } from \"../shared/errors\";\n\nexport interface WhenGroup<TTagName extends ElementTagName = ElementTagName> {\n condition: WhenCondition;\n content: ReadonlyArray<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: ReadonlyArray<WhenGroup<TTagName>>;\n elseContent: ReadonlyArray<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}\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 const condition = groups[i].condition;\n if (typeof condition === \"function\" ? condition() : 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 existing = whenRuntimeByMarker.get(runtime.startMarker);\n whenRuntimeByMarker.set(runtime.startMarker, runtime as WhenRuntime<ElementTagName>);\n // Re-registration for the same markers (forceUpdate() reclaim): the new\n // runtime replaced the old in the WeakMap; the iteration set and finalizer\n // already track this marker, so adding again would only grow the set.\n if (existing) return;\n const ref = new WeakRef(runtime.startMarker);\n activeWhenRuntimes.add(ref);\n whenMarkerFinalizer?.register(runtime.startMarker, ref);\n}\n\n/** The live runtime registered for a claimed start marker, if any. */\nexport function getWhenRuntime(startMarker: Comment): WhenRuntime<ElementTagName> | undefined {\n return whenRuntimeByMarker.get(startMarker);\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 (!startMarker.isConnected || !runtime.endMarker.isConnected) {\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 renderWhenContent(runtime);\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) || isZeroArityFunction(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, clearBetweenMarkers, insertNodesBefore } from \"../shared/dom\";\nimport type { WhenGroup, WhenRuntime } from \"./runtime\";\nimport { renderWhenContent, registerWhenRuntime, getWhenRuntime, evaluateActiveCondition, renderContentItems } from \"./runtime\";\nimport { isBrowser } from \"../shared/environment\";\nimport { isHydrating, claimMarkerPair, setCursor, 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 // Never mutated after construction, so chained builders and every runtime\n // rendered from this builder share them instead of copying.\n private readonly groups: ReadonlyArray<WhenGroup<TTagName>>;\n private readonly elseContent: ReadonlyArray<WhenContent<TTagName>>;\n\n constructor(groups: ReadonlyArray<WhenGroup<TTagName>>, elseContent: ReadonlyArray<WhenContent<TTagName>>) {\n this.groups = groups;\n this.elseContent = elseContent;\n }\n\n cloneWith(\n additionalGroup?: WhenGroup<TTagName>,\n newElseContent?: ReadonlyArray<WhenContent<TTagName>>,\n ): WhenBuilderImpl<TTagName> {\n return new WhenBuilderImpl(\n additionalGroup ? [...this.groups, additionalGroup] : this.groups,\n newElseContent ?? this.elseContent,\n );\n }\n\n render(host: ExpandedElement<TTagName>, index: number): Node {\n return isHydrating() ? this.hydrateRender(host, index) : this.freshRender(host, index);\n }\n\n private freshRender(host: ExpandedElement<TTagName>, index: number): Node {\n const { start: startMarker, end: endMarker } = createMarkerPair(\"when\", index);\n const runtime = this.createRuntimeFromMarkers(host, index, startMarker, endMarker);\n\n const parent = host as unknown as Node & ParentNode;\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 {\n const parentNode = host as unknown as Node & ParentNode;\n\n // No when markers at the cursor (SSR output without Nuclo markers):\n // create new markers and render from scratch.\n const pair = claimMarkerPair(parentNode, \"when\");\n if (!pair) return this.freshRender(host, index);\n const { start: startMarker, end: endMarker } = pair;\n\n // Determine which branch the client wants and which is rendered. A live\n // runtime (forceUpdate() reclaim) knows its actual branch — the marker\n // text only encodes the branch at SSR time and goes stale after\n // client-side toggles.\n const activeIndex = evaluateActiveCondition(this.groups, this.elseContent);\n const existing = getWhenRuntime(startMarker);\n const serverBranch = existing ? existing.activeIndex : decodeBranch(startMarker.textContent);\n const branchMatches = !pair.recreated &&\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 };\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 {\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\";\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","/**\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 { isBrowser } from \"../shared/environment\";\n\nexport interface UpdateScope {\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 // Re-registration (forceUpdate() reclaim) must not grow the set.\n // linear scan — scope root sets are a handful of elements.\n for (const ref of set) if (ref.deref() === el) return;\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 (!el.isConnected) {\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, function-valued\n * attributes and text.\n */\nimport { updateListRuntimes } from \"../list/runtime\";\nimport { notifyReactiveElements } from \"./reactive-attributes\";\nimport { notifyReactiveTextNodes } from \"./reactive-text\";\nimport { updateWhenRuntimes } from \"../when\";\nimport { getScopeRoots } from \"./scope\";\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\tnotifyReactiveElements,\n\tnotifyReactiveTextNodes,\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 = { contains: (node) => root.contains(node) };\n\t\t} else {\n\t\t\tscope = {\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 or a\n\t// newly-true when() branch) into an already-connected host. Flush once,\n\t// after all of them ran, so onMount fires exactly once per pass with the\n\t// DOM already settled — not once per updater.\n\tflushMountQueue();\n}\n","import { createListRuntime } from \"./runtime\";\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: ListRenderFunction<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","import { startHydration, endHydration, peekChild, setCursor } from \"./hydration\";\nimport { safeRemoveChild } from \"./shared/dom\";\nimport { flushMountQueue } from \"./element/lifecycle\";\nimport { isFunction, isZeroArityFunction } from \"./shared/type-guards\";\nimport { isBrowser } from \"./shared/environment\";\nimport { logError } from \"./shared/errors\";\n\n/**\n * A zero-arity component function. Rendering one (render(App) instead of\n * render(App())) lets a bare forceUpdate() re-invoke it later to rebuild the\n * tree with fresh static values.\n */\ntype Component<TTagName extends ElementTagName> = () => NodeModFn<TTagName>;\n\ninterface ForcedRoot {\n root: WeakRef<Element>;\n component: Component<ElementTagName>;\n}\n\n/**\n * Roots rendered/hydrated from a component function, so a bare forceUpdate()\n * can rebuild every one of them. Only a WeakRef to the root element is held;\n * disconnected roots are pruned on the next forceUpdate(). The entry itself\n * strongly holds the component closure, so — unlike the WeakRef-only\n * registries — a FinalizationRegistry drops the entry once its root is\n * collected: the closure (and whatever it captures) must not outlive the\n * app it renders, even if forceUpdate() is never called again.\n */\nconst forcedRoots: ForcedRoot[] = [];\nconst forcedRootFinalizer = typeof FinalizationRegistry !== \"undefined\"\n ? new FinalizationRegistry<ForcedRoot>((entry) => {\n const i = forcedRoots.indexOf(entry);\n if (i !== -1) forcedRoots.splice(i, 1);\n })\n : null;\n\n/**\n * Distinguishes render(App, ...) — a zero-arity component returning a\n * NodeModFn — from render(App(), ...) — the NodeModFn itself (which always\n * declares (parent, index)). Anything else passes through unchanged.\n */\nfunction unwrapComponent<TTagName extends ElementTagName>(\n fn: NodeModFn<TTagName> | Component<TTagName>,\n): { build: NodeModFn<TTagName>; component: Component<TTagName> | null } {\n if (isZeroArityFunction(fn)) {\n const built = (fn as Component<TTagName>)();\n if (isFunction(built)) {\n return { build: built as NodeModFn<TTagName>, component: fn as Component<TTagName> };\n }\n }\n return { build: fn as NodeModFn<TTagName>, component: null };\n}\n\nfunction registerForcedRoot(element: unknown, component: Component<ElementTagName> | null): void {\n if (!component || !isBrowser) return;\n if (!element || (element as Node).nodeType !== 1) return;\n const entry: ForcedRoot = { root: new WeakRef(element as Element), component };\n forcedRoots.push(entry);\n forcedRootFinalizer?.register(element as Element, entry, entry);\n}\n\n/**\n * Renders a component to a parent element by calling it and appending the result.\n *\n * Pass the component function itself (not its result) to make the root\n * refreshable by a bare forceUpdate() call:\n *\n * ```ts\n * const App = () => div(h1(\"Hello\"));\n * render(App, container); // forceUpdate() can now rebuild this root\n * render(App(), container); // also valid — but invisible to forceUpdate()\n * ```\n *\n * @param nodeModFn A component function, or a built NodeModFn (div(), h1(), ...)\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> | (() => NodeModFn<TTagName>),\n parent?: Element,\n index: number = 0\n): ExpandedElement<TTagName> {\n const { build, component } = unwrapComponent(nodeModFn);\n const targetParent = (parent || document.body) as ExpandedElement<TTagName>;\n const element = build(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 registerForcedRoot(element, component as Component<ElementTagName> | null);\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 * Like render(), passing the component function itself (hydrate(App, ...))\n * makes the root refreshable by a bare forceUpdate() call.\n *\n * @param nodeModFn A component function, or the NodeModFn 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(App());\n * // Client:\n * const app = document.getElementById(\"app\")!;\n * // app.innerHTML already contains the SSR HTML\n * hydrate(App, app);\n * ```\n */\nexport function hydrate<TTagName extends ElementTagName = ElementTagName>(\n nodeModFn: NodeModFn<TTagName> | (() => NodeModFn<TTagName>),\n parent?: Element,\n): ExpandedElement<TTagName> {\n const { build, component } = unwrapComponent(nodeModFn);\n const element = hydrateRoot(build, parent, false, null);\n registerForcedRoot(element, component as Component<ElementTagName> | null);\n return element;\n}\n\n/**\n * Re-evaluates every component-rendered root against its live DOM — including\n * static values that update() never touches (plain strings, numbers,\n * attribute literals captured when the tree was built):\n *\n * ```ts\n * const App = () => div(h1(labels[language].title), ...);\n * render(App, container); // pass the component function, not App()\n * // later, after `language` changed:\n * forceUpdate(); // every such root is rebuilt in place\n * ```\n *\n * Existing DOM nodes are reused in place (same claim walk as hydrate()), so\n * element state — focus, input values, scroll — survives. Listeners, reactive\n * resolvers and class/inline-style state on reused elements are replaced by\n * the new build; lifecycle hooks on reused elements keep their original\n * registrations (onMount does not re-fire). Nodes the new tree no longer\n * produces are removed with full cleanup (onDestroy fires).\n *\n * Roots rendered from an already-built tree (render(App())) are not\n * registered — their static values were captured and cannot be re-evaluated.\n * The explicit form forceUpdate(App(), parent) force-rehydrates one tree\n * manually and returns its root element.\n *\n * Use update() for ordinary reactivity — forceUpdate() is for rare, sweeping\n * changes (e.g. switching the UI language).\n */\nexport function forceUpdate(): void;\nexport function forceUpdate<TTagName extends ElementTagName = ElementTagName>(\n nodeModFn: NodeModFn<TTagName> | (() => NodeModFn<TTagName>),\n parent?: Element,\n): ExpandedElement<TTagName>;\nexport function forceUpdate<TTagName extends ElementTagName = ElementTagName>(\n nodeModFn?: NodeModFn<TTagName> | (() => NodeModFn<TTagName>),\n parent?: Element,\n): ExpandedElement<TTagName> | void {\n if (nodeModFn !== undefined) {\n return hydrateRoot(unwrapComponent(nodeModFn).build, parent, true, null);\n }\n\n let write = 0;\n for (let read = 0; read < forcedRoots.length; read++) {\n const entry = forcedRoots[read];\n const root = entry.root.deref();\n const parentEl = root?.parentNode;\n // Collected, disconnected or reparented-out-of-an-element roots drop out.\n if (!root || !root.isConnected || !parentEl || parentEl.nodeType !== 1) {\n forcedRootFinalizer?.unregister(entry);\n continue;\n }\n try {\n const el = hydrateRoot(\n entry.component() as NodeModFn<ElementTagName>,\n parentEl as Element,\n true,\n root,\n );\n // The walk replaces the root only on a tag mismatch — track the new one.\n if ((el as unknown) !== root) {\n entry.root = new WeakRef(el as unknown as Element);\n forcedRootFinalizer?.unregister(entry);\n forcedRootFinalizer?.register(el as unknown as Element, entry, entry);\n }\n } catch (error) {\n logError(\"forceUpdate(): component threw; keeping this root's previous DOM\", error);\n }\n forcedRoots[write++] = entry;\n }\n forcedRoots.length = write;\n}\n\nfunction hydrateRoot<TTagName extends ElementTagName>(\n nodeModFn: NodeModFn<TTagName>,\n parent: Element | undefined,\n force: boolean,\n at: Element | null,\n): ExpandedElement<TTagName> {\n const targetParent = (parent || document.body) as ExpandedElement<TTagName>;\n const parentNode = targetParent as unknown as Node & ParentNode;\n startHydration(force);\n // A known root (bare forceUpdate()): pin the claim cursor to it so the walk\n // starts exactly there — foreign siblings in the parent are never touched.\n if (at) setCursor(parentNode, at);\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()` (from\n * `nuclo/ssr`) reads an entirely different, always-empty one — SSR output\n * would render the right classes with no 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\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\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\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\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 rememberExternalRule(rule: CSSRule, query: string | undefined): void {\n\tconst state = getState();\n\tif (!state.externalRules) return;\n\tconst key = contextKeyOf(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 = contextKeyOf(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}\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\n/** Length-prefixed (query, selector-suffix) key — unambiguous for any strings. */\nexport function 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 */\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\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\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\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 * 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 atomBlock(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 * camelCase → kebab-case for CSS property (and attribute) names. A leading\n * capital becomes a leading dash, as vendor prefixes need\n * (WebkitTransition → -webkit-transition). Char-code loop with a\n * no-uppercase fast path: SSR runs this per style declaration.\n */\nexport function camelToKebab(str: string): string {\n let firstUpper = 0;\n for (; firstUpper < str.length; firstUpper++) {\n const code = str.charCodeAt(firstUpper);\n if (code >= 65 && code <= 90) break;\n }\n if (firstUpper === str.length) return str;\n\n let result = str.slice(0, firstUpper);\n for (let i = firstUpper; i < str.length; i++) {\n const code = str.charCodeAt(i);\n // A-Z is 65-90, a-z is 97-122 (difference of 32)\n result += code >= 65 && code <= 90 ? '-' + String.fromCharCode(code + 32) : str[i];\n }\n return result;\n}\n\nconst ATTR_ESCAPE_RE = /[&<>\"']/;\nconst TEXT_ESCAPE_RE = /[&<>]/;\n\n/**\n * Escapes HTML special characters in attribute values (includes \" and ')\n */\nexport function escapeHtml(text: string): string {\n // Fast path: most strings contain no special characters at all.\n const first = ATTR_ESCAPE_RE.exec(text);\n if (!first) return text;\n\n let result = '';\n let last = 0;\n for (let i = first.index; i < text.length; i++) {\n let escaped: string;\n switch (text.charCodeAt(i)) {\n case 38: escaped = '&amp;'; break; // &\n case 60: escaped = '&lt;'; break; // <\n case 62: escaped = '&gt;'; break; // >\n case 34: escaped = '&quot;'; break; // \"\n case 39: escaped = '&#039;'; break; // '\n default: continue;\n }\n result += text.slice(last, i) + escaped;\n last = i + 1;\n }\n return result + text.slice(last);\n}\n\n/**\n * Escapes HTML special characters in text node content.\n * Only &, < and > need escaping — quotes are safe inside text nodes.\n */\nexport function escapeText(text: string): string {\n const first = TEXT_ESCAPE_RE.exec(text);\n if (!first) return text;\n\n let result = '';\n let last = 0;\n for (let i = first.index; i < text.length; i++) {\n let escaped: string;\n switch (text.charCodeAt(i)) {\n case 38: escaped = '&amp;'; break; // &\n case 60: escaped = '&lt;'; break; // <\n case 62: escaped = '&gt;'; break; // >\n default: continue;\n }\n result += text.slice(last, i) + escaped;\n last = i + 1;\n }\n return result + text.slice(last);\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, contextKeyOf, ensureSheet, expandAmpersands, getStyleEpoch, hash, mergeBlocks, registerQueries } from \"./engine\";\nimport { camelToKebab } from \"../shared/strings\";\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// Property names repeat across css() calls, so conversions are memoized, with\n// a ceiling for arbitrary custom property names. Already-lowercase names skip\n// the cache entirely.\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 = camelToKebab(prop);\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/** Context key of a style's base (no query, no selector suffix) declarations. */\nconst BASE_CONTEXT = contextKeyOf(undefined, \"\");\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 key = contextKeyOf(query, 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\t/** Top-level declarations only (nested blocks are ignored), serialized. */\n\tfunction flatDecls(style: Record<string, unknown>): string {\n\t\tconst buckets = new Map<string, Bucket>();\n\t\twalk(style, undefined, \"\", buckets);\n\t\tlet decls = \"\";\n\t\tfor (const [prop, value] of buckets.get(BASE_CONTEXT)?.decls ?? []) decls += (decls ? \";\" : \"\") + prop + \":\" + value;\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","/**\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 { SVG_NAMESPACE } from \"../shared/dom\";\nimport { claimElement, claimChild, cleanupUnclaimedChildren, isForceHydrating, peekChild, setCursor } from \"../hydration\";\nimport { removeAllListeners } from \"./events\";\nimport { resetClassNameTracking } from \"./class-name\";\nimport { cleanupReactiveElement } from \"../update/registry\";\nimport { acquireMetadataOnlyFactory, isMetadataOnlyFactoryMode, setFactoryMeta } from \"./factory-meta\";\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 let localIndex = startIndex;\n const parentNode = element as unknown as Node & ParentNode;\n // Hoisted: constant for this frame — runWithoutHydration() only affects\n // nested calls, which hoist their own value.\n const force = isForceHydrating();\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 // forceUpdate(): a fresh node (structural mismatch) lands at the claim\n // cursor, keeping sibling order — a plain append would push it past\n // the still-unclaimed old children. insertBefore(x, null) === append.\n // The cursor is then pinned explicitly: with no entry, peekChild falls\n // back to firstChild, which the insertion may have just changed.\n if (force) {\n const at = peekChild(parentNode);\n parentNode.insertBefore(produced, at);\n setCursor(parentNode, at);\n } else {\n parentNode.appendChild(produced);\n }\n } else if (force && peekChild(parentNode) === produced) {\n // A raw Node child that is already in place (same instance passed\n // again): claim it so cleanupUnclaimedChildren doesn't remove it.\n claimChild(parentNode);\n }\n localIndex += 1;\n }\n}\n\n/**\n * forceUpdate() reclaim: clears the declarative state the previous build left\n * on a reused element so re-applying the current modifiers converges instead\n * of accumulating — on() listeners are detached (the re-applied modifiers\n * re-attach), reactive attribute resolvers are dropped (re-registered), and\n * class/inline-style state is rebuilt from scratch.\n * attributes the new tree no longer sets keep their old values —\n * nuclo keeps no per-element attribute manifest to diff against.\n */\nfunction resetReusedElement(el: Element): void {\n removeAllListeners(el as HTMLElement);\n cleanupReactiveElement(el);\n resetClassNameTracking(el as HTMLElement);\n el.removeAttribute(\"class\");\n el.removeAttribute(\"style\");\n}\n\n/**\n * Creates an element factory for `tagName` with the given modifiers. SVG\n * factories create namespaced elements and stay opaque to the list() template\n * engine (no factory metadata outside metadata-only mode), so rows containing\n * SVG always build through the normal path.\n */\nfunction createElementFactory(tagName: string, modifiers: ReadonlyArray<unknown>, svg: boolean): unknown {\n if (isMetadataOnlyFactoryMode()) {\n const stub = acquireMetadataOnlyFactory();\n setFactoryMeta(stub, tagName, modifiers);\n return stub;\n }\n\n const factory = function(parent?: Node, index = 0): Element {\n const claimed = parent ? claimElement(parent, tagName) : null;\n if (claimed && isForceHydrating()) resetReusedElement(claimed);\n const el = claimed ?? (svg ? document.createElementNS(SVG_NAMESPACE, tagName) : document.createElement(tagName));\n const lastOriginalChild = claimed ? el.lastChild : null;\n applyModifiers(el as unknown as ExpandedElement, modifiers as ReadonlyArray<NodeModifier>, index);\n if (claimed) cleanupUnclaimedChildren(el, lastOriginalChild);\n return el;\n };\n // Lets the list() template engine see the factory's structure (internal\n // symbols — invisible to the public API).\n if (!svg) setFactoryMeta(factory, tagName, modifiers);\n return factory;\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) => createElementFactory(tagName, mods, false) as DetachedExpandedElementFactory<TTagName>;\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) => createElementFactory(tagName, mods, true) as DetachedSVGElementFactory<TTagName>;\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\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 { 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, forceUpdate } 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 registry.forceUpdate = forceUpdate;\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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"}
1
+ {"version":3,"file":"nuclo.cjs","names":["globalScope"],"sources":["../src/shared/errors.ts","../src/shared/environment.ts","../src/update/registry.ts","../src/shared/dom.ts","../src/shared/serializing.ts","../src/hydration.ts","../src/element/lifecycle.ts","../src/element/factory-meta.ts","../src/element/events.ts","../src/element/event-attributes.ts","../src/shared/type-guards.ts","../src/update/reactive-text.ts","../src/list/template.ts","../src/list/runtime.ts","../src/update/reactive-attributes.ts","../src/element/inline-style.ts","../src/element/class-name.ts","../src/element/attributes.ts","../src/element/modifiers.ts","../src/when/runtime.ts","../src/when/builder.ts","../src/when/index.ts","../src/update/scope.ts","../src/update/update.ts","../src/list/index.ts","../src/render.ts","../src/style/engine.ts","../src/shared/strings.ts","../src/style/css.ts","../src/element/factory.ts","../src/element/tags.ts","../src/bootstrap.ts"],"sourcesContent":["export function logError(message: string, error?: Error | unknown): void {\n if (typeof console !== 'undefined') {\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 * Shared types and registries for reactive nodes.\n * Single source of truth — imported by reactive-text.ts and reactive-attributes.ts.\n *\n * Registry structure: the iteration sets only hold WeakRefs; the entries live\n * in WeakMaps keyed by the node, one flat object per node (its WeakRef plus\n * its reactive state). Storing entries in a strongly-held map would pin the\n * node in memory forever; with WeakMap storage the whole entry is collectible\n * as 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 = () => unknown;\n\n/**\n * A reactive text node. Resolver results render with the DSL's text\n * semantics: nullish and non-primitive values render as \"\".\n */\nexport interface ReactiveTextEntry {\n ref: WeakRef<Text>;\n resolver: TextResolver;\n lastValue: string;\n}\n\nexport type AttributeResolver = () => unknown;\n\n/**\n * Writes a resolved value to the element. A shared module-level function\n * (not a per-registration closure), so a reactive attribute costs no closure.\n */\nexport type AttributeApplier = (element: Element, key: string, value: unknown) => void;\n\nexport interface AttributeResolverRecord {\n key: string;\n resolver: AttributeResolver;\n apply: AttributeApplier;\n lastValue: unknown;\n}\n\nexport interface ReactiveElementEntry {\n ref: WeakRef<Element>;\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/** Iteration set of weak references to reactive text nodes. */\nexport const reactiveTextNodes = new Set<WeakRef<Text>>();\n\n/** O(1) lookup of a reactive text node's entry. */\nexport const reactiveTextNodesByNode = new WeakMap<Text, ReactiveTextEntry>();\n\n/** Iteration set of weak references to reactive elements. */\nexport const reactiveElements = new Set<WeakRef<Element>>();\n\n/** O(1) lookup of a reactive element's entry. */\nexport const reactiveElementsByNode = new WeakMap<Element, ReactiveElementEntry>();\n\n/**\n * Registers a reactive text node. Re-registration (e.g. repeated hydration)\n * replaces the resolver and last value in place.\n */\nexport function registerReactiveTextNode(node: Text, resolver: TextResolver, lastValue: string): void {\n const existing = reactiveTextNodesByNode.get(node);\n if (existing) {\n existing.resolver = resolver;\n existing.lastValue = lastValue;\n return;\n }\n const ref = new WeakRef(node);\n reactiveTextNodes.add(ref);\n reactiveTextNodesByNode.set(node, { ref, resolver, lastValue });\n}\n\n/** Returns the element's reactive entry, creating and registering it on first use. */\nexport function registerReactiveElement(element: Element): ReactiveElementEntry {\n let entry = reactiveElementsByNode.get(element);\n if (!entry) {\n const ref = new WeakRef(element);\n entry = { ref, attributeResolvers: [] };\n reactiveElements.add(ref);\n reactiveElementsByNode.set(element, entry);\n }\n return entry;\n}\n\n/** Unregisters a reactive text node (called when nuclo removes it). */\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/** Unregisters a reactive element (called when nuclo removes it). */\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","import { logError } from \"./errors\";\nimport { removeAllListeners } from \"../element/events\";\nimport { cleanupReactiveTextNode, cleanupReactiveElement } from \"../update/registry\";\nimport { disposeElementLifecycle, hasActiveLifecycleRegistrations } from \"../element/lifecycle\";\n\nexport const SVG_NAMESPACE = 'http://www.w3.org/2000/svg';\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 removeAllListeners(element);\n cleanupReactiveElement(element);\n } else if (node.nodeType === Node.TEXT_NODE) {\n cleanupReactiveTextNode(node as Text);\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 list()'s bulk clear/replace is about to\n * drop without walking through cleanupNodeTree()/safeRemoveChild(). Callers\n * skip it entirely unless hasActiveLifecycleRegistrations(), so the fast path\n * stays fast when lifecycle hooks aren't in use.\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 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 createMarkerPair(prefix: string, id: number): { start: Comment; end: Comment } {\n return { start: document.createComment(`${prefix}-start-${id}`), end: document.createComment(`${prefix}-end`) };\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\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 = host as unknown as Node & ParentNode;\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 * \"A tree is being built for renderToString()\" flag.\n *\n * True while renderToString() runs. Text children must keep their\n * `<!-- text-N -->` markers in this mode so the emitted HTML stays hydratable\n * — even when `isBrowser` is true (SSR under jsdom/happy-dom globals, or an\n * isomorphic worker that provides a DOM) — and nothing built for a throwaway\n * server tree may register itself anywhere (lifecycle hooks, reactive nodes,\n * list/when runtimes, scope roots). A pure client render leaves this false.\n *\n * Kept on globalThis under a Symbol.for key (like style/engine.ts's registry)\n * rather than in a module-level `let`: `nuclo` and `nuclo/ssr` ship as\n * separate bundles, each with its own module scope. renderToString() (in\n * nuclo/ssr) sets the flag and the tag builders (in nuclo) read it — as a\n * module variable those would be two unrelated booleans.\n */\nconst SERIALIZING_KEY = Symbol.for(\"nuclo.serializing.v1\");\nconst globalScope = globalThis as unknown as Record<symbol, { on: boolean } | undefined>;\nconst shared = globalScope[SERIALIZING_KEY] ?? (globalScope[SERIALIZING_KEY] = { on: false });\n\nexport function isSerializing(): boolean {\n return shared.on;\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 = shared.on;\n shared.on = true;\n try {\n return fn();\n } finally {\n shared.on = previous;\n }\n}\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\nimport { safeRemoveChild } from \"./shared/dom\";\n\n// The serialization flag is realm-shared state (see shared/serializing.ts);\n// re-exported here for callers that already import hydration helpers.\nexport { isSerializing, runSerializing } from \"./shared/serializing\";\n\nlet _hydrating = false;\n// True while forceUpdate() re-hydrates a live, client-rendered tree: text\n// claims work without `<!-- text-N -->` markers and reused elements get their\n// previous listeners/class state reset before modifiers re-apply.\nlet _force = 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/** True only inside a forceUpdate() pass (never during plain hydrate()). */\nexport function isForceHydrating(): boolean {\n return _hydrating && _force;\n}\n\nexport function startHydration(force = false): void {\n _hydrating = true;\n _force = force;\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 _force = 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 * forceUpdate() text claim: claims the next child when it is a bare text node\n * (client renders emit no `<!-- text-N -->` markers). Whitespace-only text\n * that is followed by a text marker is SSR template formatting, not content —\n * it is left for the marker path, which skips it. Returns null when nothing\n * claimable is at the cursor.\n */\nexport function claimBareText(parent: Node): Text | null {\n const next = peekChild(parent);\n if (!next || next.nodeType !== 3) return null;\n if (isWhitespaceText(next)) {\n let sibling = next.nextSibling;\n while (sibling && isWhitespaceText(sibling)) sibling = sibling.nextSibling;\n if (\n sibling && sibling.nodeType === 8 &&\n (sibling.textContent ?? \"\").trimStart().startsWith(\"text-\")\n ) return null;\n }\n claimChild(parent);\n return next as Text;\n}\n\n/**\n * Claims a server-rendered `<!--{prefix}-start-…-->` … `<!--{prefix}-end-->`\n * block (list()/when()) at the cursor, leaving the cursor just after the start\n * marker. Returns null, claiming nothing, when the next child isn't a start\n * marker. Pairs are depth-counted because directly nested blocks share a\n * host. A missing end marker (corrupt/truncated SSR output) is recreated right\n * after the start marker and reported as `recreated`.\n */\nexport function claimMarkerPair(\n parent: Node,\n prefix: \"list\" | \"when\",\n): { start: Comment; end: Comment; recreated: boolean } | null {\n skipWhitespaceText(parent);\n const start = peekChild(parent);\n const startPrefix = prefix + \"-start-\";\n if (!start || start.nodeType !== 8 || !start.textContent?.startsWith(startPrefix)) return null;\n claimChild(parent);\n const endText = prefix + \"-end\";\n let depth = 0;\n for (let node = start.nextSibling; node; node = node.nextSibling) {\n if (node.nodeType !== 8) continue;\n const text = node.textContent;\n if (text === endText) {\n if (depth === 0) return { start: start as Comment, end: node as Comment, recreated: false };\n depth--;\n } else if (text?.startsWith(startPrefix)) {\n depth++;\n }\n }\n const end = document.createComment(endText);\n parent.insertBefore(end, start.nextSibling);\n return { start: start as Comment, end, recreated: true };\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 // safeRemoveChild (not a bare removeChild): during forceUpdate() the\n // unclaimed nodes were live — their listeners, registrations and\n // onDestroy hooks must be released, not just detached.\n safeRemoveChild(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 fast path that intentionally skips that per-node walk for performance\n * (list()'s bulk clear/replace) calls disposeLifecyclesInSubtree() directly\n * instead, so destroy still fires exactly at removal time there too —\n * without paying for a bookkeeping walk when nothing on the page ever\n * registered a lifecycle callback (hasActiveLifecycleRegistrations() makes\n * that a 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 { isForceHydrating, 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}\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 path (list() bulk clear) skip\n * disposeLifecyclesInSubtree()'s walk entirely with a single comparison —\n * true for the overwhelming majority of apps, which never use\n * 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\n/**\n * A new record is Pending and queued exactly once, right here: every later\n * registration for the element finds the record already queued (or already\n * mounted/disposed), so no per-record \"queued\" flag is needed.\n */\nfunction ensureRecord(element: Element): LifecycleRecord {\n let record = records.get(element);\n if (!record) {\n record = { mount: null, destroy: null, state: STATE_PENDING };\n records.set(element, record);\n activeCount++;\n mountQueue.push(new WeakRef(element));\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\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 // forceUpdate() reclaim: the element is already Mounted — its original\n // callbacks stay in force. Re-applied hooks are dropped: mount must not\n // re-fire for an element that never left the document, and repeated force\n // passes must not grow the callback slots.\n if (record.state !== STATE_PENDING && isForceHydrating()) return;\n record.mount = pushSlot(record.mount, callback as MountCallback<Element>);\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 if (record.state !== STATE_PENDING && isForceHydrating()) return; // see registerMount()\n record.destroy = pushSlot(record.destroy, callback as DestroyCallback<Element>);\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 // Queued only by ensureRecord(), right after the record was stored.\n const record = records.get(element)!;\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. Checked once, 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 * and by shared/dom.ts's cleanupNodeTree() to skip snapshotting children.\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 * Detaches every listener on()/nuclo attached to `element` (called when nuclo\n * removes the element).\n */\nexport function removeAllListeners(element: HTMLElement): void {\n const tracked = elementListeners.get(element);\n if (!tracked) return;\n if (Array.isArray(tracked)) {\n for (let i = 0; i < tracked.length; i++) detachListener(element, tracked[i]);\n } else {\n detachListener(element, tracked);\n }\n elementListeners.delete(element);\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","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","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\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","import { logError } from \"../shared/errors\";\nimport type { UpdateScope } from \"./scope\";\nimport { reactiveTextNodes, reactiveTextNodesByNode, registerReactiveTextNode, type TextResolver } from \"./registry\";\nimport { isBrowser } from \"../shared/environment\";\nimport { isSerializing } from \"../shared/serializing\";\n\n/** DSL text semantics: nullish and non-primitive values render as \"\". */\nexport function toText(value: unknown): string {\n return value == null || typeof value === \"object\" || typeof value === \"function\" ? \"\" : String(value);\n}\n\n/**\n * Creates a text node showing `initial` (the resolver's already-evaluated\n * value) and registers it so every update() re-evaluates `resolver` into it.\n */\nexport function createReactiveTextNode(resolver: TextResolver, initial: unknown): Text {\n const str = toText(initial);\n const txt = document.createTextNode(str);\n if (isBrowser && !isSerializing()) registerReactiveTextNode(txt, resolver, str);\n return txt;\n}\n\n/**\n * Re-evaluates every registered reactive text node (in `scope`, if given) and\n * writes the ones whose text changed. Disconnected and collected nodes are\n * pruned as the pass goes.\n */\nexport function notifyReactiveTextNodes(scope?: UpdateScope): void {\n for (const ref of reactiveTextNodes) {\n const node = ref.deref();\n const entry = node && reactiveTextNodesByNode.get(node);\n if (!entry || !node.isConnected) {\n if (node) reactiveTextNodesByNode.delete(node);\n reactiveTextNodes.delete(ref);\n continue;\n }\n\n if (scope && !scope.contains(node)) continue;\n\n let value: string;\n try {\n value = toText(entry.resolver());\n } catch (e) {\n logError(\"Failed to update reactive text node\", e);\n value = \"\";\n }\n if (value !== entry.lastValue) {\n node.textContent = value;\n entry.lastValue = value;\n }\n }\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 { isNode } from \"../shared/type-guards\";\nimport { cleanupReactiveElement, cleanupReactiveTextNode } from \"../update/registry\";\nimport { toText } from \"../update/reactive-text\";\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. className-object\n // results (css()/cx()), nodes and nested builders are handled by the\n // normal path only.\n let v: unknown;\n try {\n v = (mod as () => unknown)();\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 = toText(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 = toText(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, safeRemoveChild, disposeLifecyclesInSubtree } from \"../shared/dom\";\nimport { isHydrating, isSerializing, claimMarkerPair, peekChild, setCursor } from \"../hydration\";\nimport type { ListRuntime, ListItemRecord } 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 existing = listRuntimeByMarker.get(startMarker);\n listRuntimeByMarker.set(startMarker, runtime);\n // Re-registration for the same markers (forceUpdate() reclaim): see\n // registerWhenRuntime() — adding another WeakRef would only grow the set.\n if (existing) return;\n const ref = new WeakRef(startMarker);\n activeListRuntimes.add(ref);\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\n/**\n * Resolves a render() result — a tag-builder factory / NodeModFn (called with\n * the host) or an already-built element — to the row element. Anything else\n * (null, primitives, attribute objects, non-element nodes) renders no row.\n */\nfunction toRowElement<TTagName extends ElementTagName>(\n result: unknown,\n host: ExpandedElement<TTagName>,\n index: number,\n): ExpandedElement<TTagName> | null {\n const value = typeof result === \"function\" ? (result as NodeModFn<TTagName>)(host, index) : result;\n return value !== null && typeof value === \"object\" && \"tagName\" in value\n ? value as ExpandedElement<TTagName>\n : null;\n}\n\n/**\n * Renders a row through the un-templated path. Used whenever a row's shape\n * doesn't match (or no longer matches) the list's active template — the\n * 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 return toRowElement(runtime.renderItem(item, index), 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 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 (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 = toRowElement(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 toRowElement(result, runtime.host, index);\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 safeRemoveChild, this does NOT eagerly walk each subtree to detach\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, so they are\n * 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. 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 = document.createDocumentFragment();\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 dynCreatedAt: dyn ? runtime.currentFlushEpoch : undefined,\n });\n runtime.lastRenderLeaves = null;\n fragment.appendChild(element as unknown as Node);\n }\n if (fragment.firstChild) 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++) safeRemoveChild(oldRecords[i].element as unknown as Node);\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++) safeRemoveChild(oldRecords[i].element as unknown as Node);\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++) safeRemoveChild(oldRecords[i].element as unknown as Node);\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]) safeRemoveChild(oldRecords[i].element as unknown as Node);\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 dynCreatedAt: dyn ? runtime.currentFlushEpoch : undefined,\n };\n runtime.lastRenderLeaves = null;\n fragment ??= document.createDocumentFragment();\n fragment.insertBefore(element as unknown as Node, fragment.firstChild);\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\n/** Every field initialized up front so all runtimes share one object shape. */\nfunction newRuntime<TItem, TTagName extends ElementTagName>(\n itemsProvider: ListItemsProvider<TItem>,\n renderItem: ListRenderFunction<TItem, TTagName>,\n startMarker: Comment,\n endMarker: Comment,\n records: ListItemRecord<TItem, TTagName>[],\n host: ExpandedElement<TTagName>,\n lastSyncedItems: readonly TItem[],\n): ListRuntime<TItem, TTagName> {\n return {\n itemsProvider,\n renderItem,\n startMarker,\n endMarker,\n records,\n host,\n lastSyncedItems,\n template: undefined,\n lastRenderLeaves: null,\n currentFlushEpoch: undefined,\n allRecordsCreatedAt: undefined,\n };\n}\n\nexport function createListRuntime<TItem, TTagName extends ElementTagName = ElementTagName>(\n itemsProvider: ListItemsProvider<TItem>,\n renderItem: ListRenderFunction<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: ListRenderFunction<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 = newRuntime(itemsProvider, renderItem, startMarker, endMarker, [], host, []);\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 && !isSerializing()) {\n // Register for future update() calls — never for a renderToString() tree\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: ListRenderFunction<TItem, TTagName>,\n host: ExpandedElement<TTagName>,\n index: number,\n): ListRuntime<TItem, TTagName> {\n const parentNode = host as unknown as Node & ParentNode;\n\n // No list markers at the cursor: build the list fresh. A recreated end\n // marker (corrupt/truncated SSR output) makes every item claim below miss,\n // so those rows render fresh too.\n const pair = claimMarkerPair(parentNode, \"list\");\n if (!pair) return createListRuntimeNormal(itemsProvider, renderFn, host, index);\n const { start: startMarker, end: endMarker } = pair;\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 element = toRowElement(renderFn(currentItems[i], i), host, i);\n // Same record shape as sync() creates, so record access stays monomorphic.\n if (element) records.push({ item: currentItems[i], element, dyn: null, dynCreatedAt: undefined });\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 = newRuntime(itemsProvider, renderFn, startMarker, endMarker, records, host, currentItems.slice());\n\n if (isBrowser && !isSerializing()) {\n registerListRuntime(startMarker, runtime as ListRuntime<unknown, ElementTagName>);\n }\n\n return runtime;\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 (!startMarker.isConnected || !runtime.endMarker.isConnected) {\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 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 { logError } from \"../shared/errors\";\nimport type { UpdateScope } from \"./scope\";\nimport { reactiveElements, reactiveElementsByNode, registerReactiveElement } from \"./registry\";\nimport type { AttributeApplier, AttributeResolver, AttributeResolverRecord } from \"./registry\";\nimport { isBrowser } from \"../shared/environment\";\nimport { isSerializing } from \"../shared/serializing\";\n\nconst UNSET_LAST_VALUE = {};\n\nfunction updateRecord(element: Element, 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 // Objects/arrays may be mutated in place (e.g. style objects), so only\n // primitives are compared against the last applied value.\n const cacheable = nextValue === null || typeof nextValue !== \"object\";\n if (cacheable && Object.is(nextValue, record.lastValue)) return;\n\n try {\n record.apply(element, record.key, 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\n/**\n * Makes `resolver` the reactive source of `element`'s `key`: applied now and\n * re-evaluated on every update(). Registering a key again replaces its\n * previous resolver. During SSR the value is applied once and nothing is\n * registered (update() never runs server-side).\n */\nexport function registerAttributeResolver<TTagName extends ElementTagName>(\n element: ExpandedElement<TTagName>,\n key: string,\n resolver: AttributeResolver,\n apply: AttributeApplier,\n): void {\n const el = element as unknown as Element;\n const record: AttributeResolverRecord = { key, resolver, apply, lastValue: UNSET_LAST_VALUE };\n if (isBrowser && !isSerializing()) {\n const resolvers = registerReactiveElement(el).attributeResolvers;\n let i = 0;\n while (i < resolvers.length && resolvers[i].key !== key) i++;\n resolvers[i] = record;\n }\n updateRecord(el, record);\n}\n\n/**\n * Re-evaluates the attribute resolvers of every registered reactive element\n * (in `scope`, if given). Disconnected and collected elements are pruned as\n * the pass goes.\n */\nexport function notifyReactiveElements(scope?: UpdateScope): void {\n for (const ref of reactiveElements) {\n const el = ref.deref();\n const entry = el && reactiveElementsByNode.get(el);\n if (!entry || !el.isConnected) {\n if (el) reactiveElementsByNode.delete(el);\n reactiveElements.delete(ref);\n continue;\n }\n\n if (scope && !scope.contains(el)) continue;\n\n const resolvers = entry.attributeResolvers;\n for (let i = 0; i < resolvers.length; i++) updateRecord(el, resolvers[i]);\n }\n}\n","import { isFunction } from \"../shared/type-guards\";\nimport { registerAttributeResolver } from \"../update/reactive-attributes\";\nimport { logError } from \"../shared/errors\";\n\ntype StyleAssignment = CSSStyleObject;\ntype StyleResolver = () => StyleAssignment | null | undefined;\n\n/**\n * Assigns each property of `styles` to the element's inline style (camelCase\n * or kebab-case keys); null, undefined and \"\" remove the property.\n */\nexport function assignInlineStyles<TTagName extends ElementTagName>(\n element: ExpandedElement<TTagName>,\n styles: StyleAssignment | null | undefined,\n): void {\n const style = element.style as unknown as Record<string, string> | undefined;\n if (!style || !styles) return;\n\n for (const property in styles) {\n const value = (styles as Record<string, unknown>)[property];\n try {\n style[property] = value == null ? \"\" : String(value);\n } catch {\n // Don't stringify the value in the message: that may be what threw.\n logError(`Failed to set style property '${property}'`);\n }\n }\n}\n\nfunction applyReactiveStyle(element: Element, _key: string, styles: unknown): void {\n assignInlineStyles(element as unknown as ExpandedElement, styles as StyleAssignment | null | undefined);\n}\n\nexport function applyStyleAttribute<TTagName extends ElementTagName>(\n element: ExpandedElement<TTagName>,\n styleValue: StyleAssignment | StyleResolver | null | undefined\n): void {\n if (isFunction(styleValue)) {\n registerAttributeResolver(element, 'style', styleValue, applyReactiveStyle);\n } else {\n assignInlineStyles(element, styleValue);\n }\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// Drop all className bookkeeping for an element (forceUpdate() reclaim).\nexport function resetClassNameTracking(el: HTMLElement): void {\n\tstaticClassNames.delete(el);\n\treactiveClassNameFlags.delete(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 { 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 neither\n * the static-attribute path (the bulk of attributes in list rows) nor a\n * reactive attribute (it is the registered applier, `merge` left unset)\n * allocates anything per attribute.\n */\nfunction setAttributeValue(\n el: Element,\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 unknown 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\nfunction applyReactiveClassName(el: Element, _key: string, v: unknown): void {\n mergeReactiveClassName(el as HTMLElement, String(v || ''));\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 registerAttributeResolver(el, k, resolver, applyReactiveClassName);\n } else {\n registerAttributeResolver(el, k, resolver, setAttributeValue);\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 as unknown as Element, 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 // 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","/**\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, toText } 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 { isHydrating, isForceHydrating, isSerializing, claimBareText, claimChild, peekChild, setCursor, skipWhitespaceText } from \"../hydration\";\nimport { isBrowser } from \"../shared/environment\";\n\nexport type NodeModifier<TTagName extends ElementTagName = ElementTagName> =\n\t| NodeMod<TTagName>\n\t| NodeModFn<TTagName>\n\t| AnyParentNodeModifier;\n\n/**\n * Shape of a css()/cx() StyleResult: an object whose only own key is\n * `className`. Typed as readonly to signal it should not be mutated.\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 {\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 = document.createTextNode(expected);\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\tconst v = modifier();\n\n\t\t\t\t// A css()/cx() result (only own key: a `className` string) makes this a\n\t\t\t\t// reactive className instead of reactive text.\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 is\n\t\t\t\t\t// registered raw — the notify pass renders nullish/non-primitive\n\t\t\t\t\t// results as \"\" — so no wrapper closure is allocated per text node.\n\t\t\t\t\tif (isHydrating()) {\n\t\t\t\t\t\tconst parentNode = parent as unknown as Node;\n\t\t\t\t\t\tconst expected = toText(v);\n\t\t\t\t\t\t// forceUpdate(): client-rendered text nodes carry no marker —\n\t\t\t\t\t\t// claim the bare text node, patch it, swap in the new resolver.\n\t\t\t\t\t\tif (isForceHydrating()) {\n\t\t\t\t\t\t\tconst claimed = claimBareText(parentNode);\n\t\t\t\t\t\t\tif (claimed) {\n\t\t\t\t\t\t\t\tif (claimed.textContent !== expected) claimed.textContent = expected;\n\t\t\t\t\t\t\t\tregisterReactiveTextNode(claimed, modifier, expected);\n\t\t\t\t\t\t\t\treturn null;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (nextChildIsTextComment(parentNode)) {\n\t\t\t\t\t\t\tclaimChild(parentNode); // skip <!-- text-N --> comment\n\t\t\t\t\t\t\tregisterReactiveTextNode(claimTextAfterMarker(parentNode, expected), modifier, expected);\n\t\t\t\t\t\t\treturn null;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn wrapTextNode(index, createReactiveTextNode(modifier, v));\n\t\t\t\t}\n\t\t\t\treturn null;\n\t\t\t} catch (error) {\n\t\t\t\tlogError(\"Error evaluating reactive text function:\", error);\n\t\t\t\treturn wrapTextNode(index, createReactiveTextNode(emptyText, \"\"));\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 wrapTextNode(index, document.createTextNode(String(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()) {\n\t\t\tconst parentNode = parent as unknown as Node;\n\t\t\tconst expected = String(candidate);\n\t\t\t// forceUpdate(): claim and patch the bare client-rendered text node.\n\t\t\tif (isForceHydrating()) {\n\t\t\t\tconst claimed = claimBareText(parentNode);\n\t\t\t\tif (claimed) {\n\t\t\t\t\tif (claimed.textContent !== expected) claimed.textContent = expected;\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (nextChildIsTextComment(parentNode)) {\n\t\t\t\tclaimChild(parentNode); // skip <!-- text-N --> comment\n\t\t\t\tclaimTextAfterMarker(parentNode, expected);\n\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\t\treturn wrapTextNode(index, document.createTextNode(String(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.\n */\nfunction wrapTextNode(index: number, textNode: Text): Node {\n\tif (isBrowser && !isHydrating() && !isSerializing()) {\n\t\treturn textNode;\n\t}\n\tconst fragment = document.createDocumentFragment();\n\tfragment.appendChild(document.createComment(` text-${index} `));\n\tfragment.appendChild(textNode);\n\treturn fragment;\n}\n\n/** Resolver for text whose first evaluation threw: stays empty. */\nfunction emptyText(): string {\n\treturn \"\";\n}\n","import { clearBetweenMarkers, insertNodesBefore, withScopedInsertion } from \"../shared/dom\";\nimport type { UpdateScope } from \"../update/scope\";\nimport { applyNodeModifier } from \"../element/modifiers\";\nimport { isFunction, isZeroArityFunction } from \"../shared/type-guards\";\nimport { logError } from \"../shared/errors\";\n\nexport interface WhenGroup<TTagName extends ElementTagName = ElementTagName> {\n condition: WhenCondition;\n content: ReadonlyArray<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: ReadonlyArray<WhenGroup<TTagName>>;\n elseContent: ReadonlyArray<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}\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 const condition = groups[i].condition;\n if (typeof condition === \"function\" ? condition() : 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 existing = whenRuntimeByMarker.get(runtime.startMarker);\n whenRuntimeByMarker.set(runtime.startMarker, runtime as WhenRuntime<ElementTagName>);\n // Re-registration for the same markers (forceUpdate() reclaim): the new\n // runtime replaced the old in the WeakMap; the iteration set and finalizer\n // already track this marker, so adding again would only grow the set.\n if (existing) return;\n const ref = new WeakRef(runtime.startMarker);\n activeWhenRuntimes.add(ref);\n whenMarkerFinalizer?.register(runtime.startMarker, ref);\n}\n\n/** The live runtime registered for a claimed start marker, if any. */\nexport function getWhenRuntime(startMarker: Comment): WhenRuntime<ElementTagName> | undefined {\n return whenRuntimeByMarker.get(startMarker);\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 (!startMarker.isConnected || !runtime.endMarker.isConnected) {\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 renderWhenContent(runtime);\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) || isZeroArityFunction(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, clearBetweenMarkers, insertNodesBefore } from \"../shared/dom\";\nimport type { WhenGroup, WhenRuntime } from \"./runtime\";\nimport { renderWhenContent, registerWhenRuntime, getWhenRuntime, evaluateActiveCondition, renderContentItems } from \"./runtime\";\nimport { isBrowser } from \"../shared/environment\";\nimport { isHydrating, isSerializing, claimMarkerPair, setCursor, 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 // Never mutated after construction, so chained builders and every runtime\n // rendered from this builder share them instead of copying.\n private readonly groups: ReadonlyArray<WhenGroup<TTagName>>;\n private readonly elseContent: ReadonlyArray<WhenContent<TTagName>>;\n\n constructor(groups: ReadonlyArray<WhenGroup<TTagName>>, elseContent: ReadonlyArray<WhenContent<TTagName>>) {\n this.groups = groups;\n this.elseContent = elseContent;\n }\n\n cloneWith(\n additionalGroup?: WhenGroup<TTagName>,\n newElseContent?: ReadonlyArray<WhenContent<TTagName>>,\n ): WhenBuilderImpl<TTagName> {\n return new WhenBuilderImpl(\n additionalGroup ? [...this.groups, additionalGroup] : this.groups,\n newElseContent ?? this.elseContent,\n );\n }\n\n render(host: ExpandedElement<TTagName>, index: number): Node {\n return isHydrating() ? this.hydrateRender(host, index) : this.freshRender(host, index);\n }\n\n private freshRender(host: ExpandedElement<TTagName>, index: number): Node {\n const { start: startMarker, end: endMarker } = createMarkerPair(\"when\", index);\n const runtime = this.createRuntimeFromMarkers(host, index, startMarker, endMarker);\n\n const parent = host as unknown as Node & ParentNode;\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 {\n const parentNode = host as unknown as Node & ParentNode;\n\n // No when markers at the cursor (SSR output without Nuclo markers):\n // create new markers and render from scratch.\n const pair = claimMarkerPair(parentNode, \"when\");\n if (!pair) return this.freshRender(host, index);\n const { start: startMarker, end: endMarker } = pair;\n\n // Determine which branch the client wants and which is rendered. A live\n // runtime (forceUpdate() reclaim) knows its actual branch — the marker\n // text only encodes the branch at SSR time and goes stale after\n // client-side toggles.\n const activeIndex = evaluateActiveCondition(this.groups, this.elseContent);\n const existing = getWhenRuntime(startMarker);\n const serverBranch = existing ? existing.activeIndex : decodeBranch(startMarker.textContent);\n const branchMatches = !pair.recreated &&\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 };\n\n if (isBrowser && !isSerializing()) {\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 {\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\";\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","/**\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 { isBrowser } from \"../shared/environment\";\nimport { isSerializing } from \"../shared/serializing\";\n\nexport interface UpdateScope {\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 // Re-registration (forceUpdate() reclaim) must not grow the set.\n // linear scan — scope root sets are a handful of elements.\n for (const ref of set) if (ref.deref() === el) return;\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 (!el.isConnected) {\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 || isSerializing()) 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, function-valued\n * attributes and text.\n */\nimport { updateListRuntimes } from \"../list/runtime\";\nimport { notifyReactiveElements } from \"./reactive-attributes\";\nimport { notifyReactiveTextNodes } from \"./reactive-text\";\nimport { updateWhenRuntimes } from \"../when\";\nimport { getScopeRoots } from \"./scope\";\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\tnotifyReactiveElements,\n\tnotifyReactiveTextNodes,\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 = { contains: (node) => root.contains(node) };\n\t\t} else {\n\t\t\tscope = {\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 or a\n\t// newly-true when() branch) into an already-connected host. Flush once,\n\t// after all of them ran, so onMount fires exactly once per pass with the\n\t// DOM already settled — not once per updater.\n\tflushMountQueue();\n}\n","import { createListRuntime } from \"./runtime\";\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: ListRenderFunction<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","import { startHydration, endHydration, peekChild, setCursor } from \"./hydration\";\nimport { safeRemoveChild } from \"./shared/dom\";\nimport { flushMountQueue } from \"./element/lifecycle\";\nimport { isFunction, isZeroArityFunction } from \"./shared/type-guards\";\nimport { isBrowser } from \"./shared/environment\";\nimport { logError } from \"./shared/errors\";\n\n/**\n * A zero-arity component function. Rendering one (render(App) instead of\n * render(App())) lets a bare forceUpdate() re-invoke it later to rebuild the\n * tree with fresh static values.\n */\ntype Component<TTagName extends ElementTagName> = () => NodeModFn<TTagName>;\n\ninterface ForcedRoot {\n root: WeakRef<Element>;\n component: Component<ElementTagName>;\n}\n\n/**\n * Roots rendered/hydrated from a component function, so a bare forceUpdate()\n * can rebuild every one of them. Only a WeakRef to the root element is held;\n * disconnected roots are pruned on the next forceUpdate(). The entry itself\n * strongly holds the component closure, so — unlike the WeakRef-only\n * registries — a FinalizationRegistry drops the entry once its root is\n * collected: the closure (and whatever it captures) must not outlive the\n * app it renders, even if forceUpdate() is never called again.\n */\nconst forcedRoots: ForcedRoot[] = [];\nconst forcedRootFinalizer = typeof FinalizationRegistry !== \"undefined\"\n ? new FinalizationRegistry<ForcedRoot>((entry) => {\n const i = forcedRoots.indexOf(entry);\n if (i !== -1) forcedRoots.splice(i, 1);\n })\n : null;\n\n/**\n * Distinguishes render(App, ...) — a zero-arity component returning a\n * NodeModFn — from render(App(), ...) — the NodeModFn itself (which always\n * declares (parent, index)). Anything else passes through unchanged.\n */\nfunction unwrapComponent<TTagName extends ElementTagName>(\n fn: NodeModFn<TTagName> | Component<TTagName>,\n): { build: NodeModFn<TTagName>; component: Component<TTagName> | null } {\n if (isZeroArityFunction(fn)) {\n const built = (fn as Component<TTagName>)();\n if (isFunction(built)) {\n return { build: built as NodeModFn<TTagName>, component: fn as Component<TTagName> };\n }\n }\n return { build: fn as NodeModFn<TTagName>, component: null };\n}\n\nfunction registerForcedRoot(element: unknown, component: Component<ElementTagName> | null): void {\n if (!component || !isBrowser) return;\n if (!element || (element as Node).nodeType !== 1) return;\n const entry: ForcedRoot = { root: new WeakRef(element as Element), component };\n forcedRoots.push(entry);\n forcedRootFinalizer?.register(element as Element, entry, entry);\n}\n\n/**\n * Renders a component to a parent element by calling it and appending the result.\n *\n * Pass the component function itself (not its result) to make the root\n * refreshable by a bare forceUpdate() call:\n *\n * ```ts\n * const App = () => div(h1(\"Hello\"));\n * render(App, container); // forceUpdate() can now rebuild this root\n * render(App(), container); // also valid — but invisible to forceUpdate()\n * ```\n *\n * @param nodeModFn A component function, or a built NodeModFn (div(), h1(), ...)\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> | (() => NodeModFn<TTagName>),\n parent?: Element,\n index: number = 0\n): ExpandedElement<TTagName> {\n const { build, component } = unwrapComponent(nodeModFn);\n const targetParent = (parent || document.body) as ExpandedElement<TTagName>;\n const element = build(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 registerForcedRoot(element, component as Component<ElementTagName> | null);\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 * Like render(), passing the component function itself (hydrate(App, ...))\n * makes the root refreshable by a bare forceUpdate() call.\n *\n * @param nodeModFn A component function, or the NodeModFn 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(App());\n * // Client:\n * const app = document.getElementById(\"app\")!;\n * // app.innerHTML already contains the SSR HTML\n * hydrate(App, app);\n * ```\n */\nexport function hydrate<TTagName extends ElementTagName = ElementTagName>(\n nodeModFn: NodeModFn<TTagName> | (() => NodeModFn<TTagName>),\n parent?: Element,\n): ExpandedElement<TTagName> {\n const { build, component } = unwrapComponent(nodeModFn);\n const element = hydrateRoot(build, parent, false, null);\n registerForcedRoot(element, component as Component<ElementTagName> | null);\n return element;\n}\n\n/**\n * Re-evaluates every component-rendered root against its live DOM — including\n * static values that update() never touches (plain strings, numbers,\n * attribute literals captured when the tree was built):\n *\n * ```ts\n * const App = () => div(h1(labels[language].title), ...);\n * render(App, container); // pass the component function, not App()\n * // later, after `language` changed:\n * forceUpdate(); // every such root is rebuilt in place\n * ```\n *\n * Existing DOM nodes are reused in place (same claim walk as hydrate()), so\n * element state — focus, input values, scroll — survives. Listeners, reactive\n * resolvers and class/inline-style state on reused elements are replaced by\n * the new build; lifecycle hooks on reused elements keep their original\n * registrations (onMount does not re-fire). Nodes the new tree no longer\n * produces are removed with full cleanup (onDestroy fires).\n *\n * Roots rendered from an already-built tree (render(App())) are not\n * registered — their static values were captured and cannot be re-evaluated.\n * The explicit form forceUpdate(App(), parent) force-rehydrates one tree\n * manually and returns its root element.\n *\n * Use update() for ordinary reactivity — forceUpdate() is for rare, sweeping\n * changes (e.g. switching the UI language).\n */\nexport function forceUpdate(): void;\nexport function forceUpdate<TTagName extends ElementTagName = ElementTagName>(\n nodeModFn: NodeModFn<TTagName> | (() => NodeModFn<TTagName>),\n parent?: Element,\n): ExpandedElement<TTagName>;\nexport function forceUpdate<TTagName extends ElementTagName = ElementTagName>(\n nodeModFn?: NodeModFn<TTagName> | (() => NodeModFn<TTagName>),\n parent?: Element,\n): ExpandedElement<TTagName> | void {\n if (nodeModFn !== undefined) {\n return hydrateRoot(unwrapComponent(nodeModFn).build, parent, true, null);\n }\n\n let write = 0;\n for (let read = 0; read < forcedRoots.length; read++) {\n const entry = forcedRoots[read];\n const root = entry.root.deref();\n const parentEl = root?.parentNode;\n // Collected, disconnected or reparented-out-of-an-element roots drop out.\n if (!root || !root.isConnected || !parentEl || parentEl.nodeType !== 1) {\n forcedRootFinalizer?.unregister(entry);\n continue;\n }\n try {\n const el = hydrateRoot(\n entry.component() as NodeModFn<ElementTagName>,\n parentEl as Element,\n true,\n root,\n );\n // The walk replaces the root only on a tag mismatch — track the new one.\n if ((el as unknown) !== root) {\n entry.root = new WeakRef(el as unknown as Element);\n forcedRootFinalizer?.unregister(entry);\n forcedRootFinalizer?.register(el as unknown as Element, entry, entry);\n }\n } catch (error) {\n logError(\"forceUpdate(): component threw; keeping this root's previous DOM\", error);\n }\n forcedRoots[write++] = entry;\n }\n forcedRoots.length = write;\n}\n\nfunction hydrateRoot<TTagName extends ElementTagName>(\n nodeModFn: NodeModFn<TTagName>,\n parent: Element | undefined,\n force: boolean,\n at: Element | null,\n): ExpandedElement<TTagName> {\n const targetParent = (parent || document.body) as ExpandedElement<TTagName>;\n const parentNode = targetParent as unknown as Node & ParentNode;\n startHydration(force);\n // A known root (bare forceUpdate()): pin the claim cursor to it so the walk\n // starts exactly there — foreign siblings in the parent are never touched.\n if (at) setCursor(parentNode, at);\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()` (from\n * `nuclo/ssr`) reads an entirely different, always-empty one — SSR output\n * would render the right classes with no 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\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\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\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\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 rememberExternalRule(rule: CSSRule, query: string | undefined): void {\n\tconst state = getState();\n\tif (!state.externalRules) return;\n\tconst key = contextKeyOf(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 = contextKeyOf(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}\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\n/** Length-prefixed (query, selector-suffix) key — unambiguous for any strings. */\nexport function 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 */\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\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\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\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 * 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 atomBlock(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 * camelCase → kebab-case for CSS property (and attribute) names. A leading\n * capital becomes a leading dash, as vendor prefixes need\n * (WebkitTransition → -webkit-transition). Char-code loop with a\n * no-uppercase fast path: SSR runs this per style declaration.\n */\nexport function camelToKebab(str: string): string {\n let firstUpper = 0;\n for (; firstUpper < str.length; firstUpper++) {\n const code = str.charCodeAt(firstUpper);\n if (code >= 65 && code <= 90) break;\n }\n if (firstUpper === str.length) return str;\n\n let result = str.slice(0, firstUpper);\n for (let i = firstUpper; i < str.length; i++) {\n const code = str.charCodeAt(i);\n // A-Z is 65-90, a-z is 97-122 (difference of 32)\n result += code >= 65 && code <= 90 ? '-' + String.fromCharCode(code + 32) : str[i];\n }\n return result;\n}\n\nconst ATTR_ESCAPE_RE = /[&<>\"']/;\nconst TEXT_ESCAPE_RE = /[&<>]/;\n\n/**\n * Escapes HTML special characters in attribute values (includes \" and ')\n */\nexport function escapeHtml(text: string): string {\n // Fast path: most strings contain no special characters at all.\n const first = ATTR_ESCAPE_RE.exec(text);\n if (!first) return text;\n\n let result = '';\n let last = 0;\n for (let i = first.index; i < text.length; i++) {\n let escaped: string;\n switch (text.charCodeAt(i)) {\n case 38: escaped = '&amp;'; break; // &\n case 60: escaped = '&lt;'; break; // <\n case 62: escaped = '&gt;'; break; // >\n case 34: escaped = '&quot;'; break; // \"\n case 39: escaped = '&#039;'; break; // '\n default: continue;\n }\n result += text.slice(last, i) + escaped;\n last = i + 1;\n }\n return result + text.slice(last);\n}\n\n/**\n * Escapes HTML special characters in text node content.\n * Only &, < and > need escaping — quotes are safe inside text nodes.\n */\nexport function escapeText(text: string): string {\n const first = TEXT_ESCAPE_RE.exec(text);\n if (!first) return text;\n\n let result = '';\n let last = 0;\n for (let i = first.index; i < text.length; i++) {\n let escaped: string;\n switch (text.charCodeAt(i)) {\n case 38: escaped = '&amp;'; break; // &\n case 60: escaped = '&lt;'; break; // <\n case 62: escaped = '&gt;'; break; // >\n default: continue;\n }\n result += text.slice(last, i) + escaped;\n last = i + 1;\n }\n return result + text.slice(last);\n}\n\n/**\n * IDL property name → HTML content attribute name, for the camelCase keys a\n * real element reflects (tabIndex → tabindex, htmlFor → for,\n * ariaDescribedBy → aria-describedby, httpEquiv → http-equiv). Lowercase and\n * kebab-case names pass through unchanged. SSR runs this per polyfill attribute.\n */\nexport function propertyToAttribute(name: string): string {\n switch (name) {\n case 'htmlFor': return 'for';\n case 'httpEquiv': return 'http-equiv';\n case 'acceptCharset': return 'accept-charset';\n case 'defaultValue': return 'value';\n case 'defaultChecked': return 'checked';\n case 'defaultSelected': return 'selected';\n }\n // ARIA reflection: one dash after \"aria\", the rest lowercased\n // (ariaDescribedBy → aria-describedby, not aria-described-by).\n const c = name.charCodeAt(4);\n if (c >= 65 && c <= 90 && name.startsWith('aria')) return 'aria-' + name.slice(4).toLowerCase();\n return name.toLowerCase();\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, contextKeyOf, ensureSheet, expandAmpersands, getStyleEpoch, hash, mergeBlocks, registerQueries } from \"./engine\";\nimport { camelToKebab } from \"../shared/strings\";\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// Property names repeat across css() calls, so conversions are memoized, with\n// a ceiling for arbitrary custom property names. Already-lowercase names skip\n// the cache entirely.\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 = camelToKebab(prop);\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/** Context key of a style's base (no query, no selector suffix) declarations. */\nconst BASE_CONTEXT = contextKeyOf(undefined, \"\");\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 key = contextKeyOf(query, 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\t/** Top-level declarations only (nested blocks are ignored), serialized. */\n\tfunction flatDecls(style: Record<string, unknown>): string {\n\t\tconst buckets = new Map<string, Bucket>();\n\t\twalk(style, undefined, \"\", buckets);\n\t\tlet decls = \"\";\n\t\tfor (const [prop, value] of buckets.get(BASE_CONTEXT)?.decls ?? []) decls += (decls ? \";\" : \"\") + prop + \":\" + value;\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","/**\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 { SVG_NAMESPACE } from \"../shared/dom\";\nimport { claimElement, claimChild, cleanupUnclaimedChildren, isForceHydrating, peekChild, setCursor } from \"../hydration\";\nimport { removeAllListeners } from \"./events\";\nimport { resetClassNameTracking } from \"./class-name\";\nimport { cleanupReactiveElement } from \"../update/registry\";\nimport { acquireMetadataOnlyFactory, isMetadataOnlyFactoryMode, setFactoryMeta } from \"./factory-meta\";\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 let localIndex = startIndex;\n const parentNode = element as unknown as Node & ParentNode;\n // Hoisted: constant for this frame — runWithoutHydration() only affects\n // nested calls, which hoist their own value.\n const force = isForceHydrating();\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 // forceUpdate(): a fresh node (structural mismatch) lands at the claim\n // cursor, keeping sibling order — a plain append would push it past\n // the still-unclaimed old children. insertBefore(x, null) === append.\n // The cursor is then pinned explicitly: with no entry, peekChild falls\n // back to firstChild, which the insertion may have just changed.\n if (force) {\n const at = peekChild(parentNode);\n parentNode.insertBefore(produced, at);\n setCursor(parentNode, at);\n } else {\n parentNode.appendChild(produced);\n }\n } else if (force && peekChild(parentNode) === produced) {\n // A raw Node child that is already in place (same instance passed\n // again): claim it so cleanupUnclaimedChildren doesn't remove it.\n claimChild(parentNode);\n }\n localIndex += 1;\n }\n}\n\n/**\n * forceUpdate() reclaim: clears the declarative state the previous build left\n * on a reused element so re-applying the current modifiers converges instead\n * of accumulating — on() listeners are detached (the re-applied modifiers\n * re-attach), reactive attribute resolvers are dropped (re-registered), and\n * class/inline-style state is rebuilt from scratch.\n * attributes the new tree no longer sets keep their old values —\n * nuclo keeps no per-element attribute manifest to diff against.\n */\nfunction resetReusedElement(el: Element): void {\n removeAllListeners(el as HTMLElement);\n cleanupReactiveElement(el);\n resetClassNameTracking(el as HTMLElement);\n el.removeAttribute(\"class\");\n el.removeAttribute(\"style\");\n}\n\n/**\n * Creates an element factory for `tagName` with the given modifiers. SVG\n * factories create namespaced elements and stay opaque to the list() template\n * engine (no factory metadata outside metadata-only mode), so rows containing\n * SVG always build through the normal path.\n */\nfunction createElementFactory(tagName: string, modifiers: ReadonlyArray<unknown>, svg: boolean): unknown {\n if (isMetadataOnlyFactoryMode()) {\n const stub = acquireMetadataOnlyFactory();\n setFactoryMeta(stub, tagName, modifiers);\n return stub;\n }\n\n const factory = function(parent?: Node, index = 0): Element {\n const claimed = parent ? claimElement(parent, tagName) : null;\n if (claimed && isForceHydrating()) resetReusedElement(claimed);\n const el = claimed ?? (svg ? document.createElementNS(SVG_NAMESPACE, tagName) : document.createElement(tagName));\n const lastOriginalChild = claimed ? el.lastChild : null;\n applyModifiers(el as unknown as ExpandedElement, modifiers as ReadonlyArray<NodeModifier>, index);\n if (claimed) cleanupUnclaimedChildren(el, lastOriginalChild);\n return el;\n };\n // Lets the list() template engine see the factory's structure (internal\n // symbols — invisible to the public API).\n if (!svg) setFactoryMeta(factory, tagName, modifiers);\n return factory;\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) => createElementFactory(tagName, mods, false) as DetachedExpandedElementFactory<TTagName>;\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) => createElementFactory(tagName, mods, true) as DetachedSVGElementFactory<TTagName>;\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\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 { 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, forceUpdate } 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 registry.forceUpdate = forceUpdate;\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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"}