nuclo 0.3.22 → 0.3.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +54 -0
- package/dist/nuclo.cjs +1 -1
- package/dist/nuclo.cjs.map +1 -1
- package/dist/nuclo.mjs +1 -1
- package/dist/nuclo.mjs.map +1 -1
- package/dist/polyfill/nuclo.polyfill.cjs +1 -1
- package/dist/polyfill/nuclo.polyfill.cjs.map +1 -1
- package/dist/polyfill/nuclo.polyfill.mjs +1 -1
- package/dist/polyfill/nuclo.polyfill.mjs.map +1 -1
- package/dist/ssr/nuclo.ssr.cjs +2 -2
- package/dist/ssr/nuclo.ssr.cjs.map +1 -1
- package/dist/ssr/nuclo.ssr.mjs +2 -2
- package/dist/ssr/nuclo.ssr.mjs.map +1 -1
- package/package.json +3 -3
- package/types/core/base.d.ts +3 -0
- package/types/features/region.d.ts +29 -0
- package/types/features/render.d.ts +13 -0
- package/types/features/when.d.ts +1 -1
- package/types/index.d.ts +19 -1
package/dist/nuclo.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nuclo.mjs","names":["globalScope","logError","message","error","isBrowser","reactiveTextNodes","reactiveTextNodesByNode","reactiveElements","reactiveElementsByNode","registerReactiveTextNode","existing","node","resolver","lastValue","ref","registerReactiveElement","entry","element","cleanupReactiveTextNode","cleanupReactiveElement","cleanupNodeTree","removeAllListeners","children","hasActiveLifecycleRegistrations","i","disposeElementLifecycle","disposeLifecyclesInSubtree","safeRemoveChild","child","safeInsertBefore","parent","newNode","referenceNode","createMarker","text","createMarkerPair","prefix","id","clearBetweenMarkers","current","startMarker","endMarker","next","insertNodesBefore","nodes","withScopedInsertion","host","originalAppend","originalInsert","callback","SERIALIZING_KEY","globalScope$1","shared","isSerializing","_hydrating","_force","_cursors","isHydrating","isForceHydrating","startHydration","force","endHydration","runWithoutHydration","wasHydrating","fn","peekChild","setCursor","runFreshAtCursor","at","build","isWhitespaceText","skipWhitespaceText","advanced","drop","claimChild","claimBareText","sibling","claimMarkerPair","start","startPrefix","endText","depth","end","claimElement","candidate","name","tagName","cleanupUnclaimedChildren","lastOriginalChild","records","activeCount","mountQueue","shouldSkip","ensureRecord","record","pushSlot","slot","cb","registerMount","registerDestroy","runMount","cleanup","runDestroy","fireMount","mount","flushMountQueue","batch","mountQueueMark","cancelMountsSince","mark","wasMounted","destroy","FACTORY_TAG","FACTORY_MODS","EVENT_MODIFIER","metadataOnlyFactoryDepth","metadataOnlyStubPool","metadataOnlyPoolIndex","acquireMetadataOnlyFactory","setFactoryMeta","tag","mods","getFactoryMods","getFactoryTag","markEventModifier","isEventModifier","isMetadataOnlyFactoryMode","withMetadataOnlyFactories","item","index","getMetadataOnlyFactoryCheckpoint","releaseMetadataOnlyFactories","checkpoint","factory","elementListeners","trackListener","tracked","info","detachListener","noopEventModifier","createLifecycleModifier","el","kind","createTrackedListener","currentTarget","listener","event","type","on","options","RESERVED_LIFECYCLE_ATTRIBUTES","fallbackEventListeners","eventAttributeToProperty","attribute","firstEventCharacter","setEventAttribute","property","list","previous","isPrimitive","value","isNode","isObject","isFunction","isZeroArityFunction","toText","createReactiveTextNode","str","initial","txt","notifyReactiveTextNodes","scope","e","setsAttribute","slots","k","key","analyzeFactory","mod","t","childMods","childTag","v","attrs","keys","specs","vt","eventProperty","prepareSkeleton","tmpl","skeleton","spec","instantiateTemplate","attrCount","_k","target","s","resolved","leaves","textNode","adoptTemplateLeaves","flushRowLeaves","arraysEqual","a","b","activeListRuntimes","listRuntimeByMarker","listMarkerFinalizer","updateListFlushEpoch","registerListRuntime","runtime","normalizeItems","items","toRowElement","result","rebuildRowNormally","leafScratch","takeLeaves","renderItem","renderItemWithTemplate","template","canUseTemplate","adopted","clone","bulkClearRecords","longestIncreasingSubsequence","n","arr","predecessor","tails","x","lo","hi","mid","idx","buildAndInsert","fragment","startIndex","endIndexExclusive","dyn","targetRecords","anchor","selectOwning","sync","select","selectedValue","diffRows","fallback","oldRecords","oldLen","newLen","maxTrim","suffix","maxSuffix","oldStart","oldEnd","newStart","newEnd","fresh","oldWinLen","newWinLen","sources","claimed","reusedCount","pinEnd","pinnedCount","buckets","j","oldIndex","stable","pinnedOnly","survivorOldIndices","survivorPositions","lis","windowRecords","nullCount","src","firstFlushed","merged","w","newRuntime","createListRuntime","hydrateListRuntime","itemsProvider","createListRuntimeNormal","parentNode","pair","renderFn","currentItems","leftover","recordNode","updateListRuntimes","UNSET_LAST_VALUE","updateRecord","nextValue","cacheable","applied","registerAttributeResolver","resolvers","notifyReactiveElements","assignInlineStyles","style","styles","applyReactiveStyle","applyStyleAttribute","styleValue","staticClassNames","reactiveClassNameFlags","getClass","setClass","addClassTokens","len","className","joinClasses","cls","classes","initReactiveClassName","classSet","resetClassNameTracking","hasReactiveClassName","addStaticClasses","mergeReactiveClassName","staticClasses","reactiveClassName","token","mergeStaticClassName","newClassName","currentClassName","selectValues","setSelectValue","retrySelectValue","forgetSelectValue","setAttributeValue","merge","applyReactiveClassName","applySingleAttribute","raw","shouldMergeClassName","applyAttributes","valueLast","attributes","mergeClassName","isClassNameOnlyObject","nextChildIsTextComment","claimTextAfterMarker","expected","created","applyNodeModifier","modifier","wrapTextNode","emptyText","produced","activeWhenRuntimes","whenRuntimeByMarker","whenMarkerFinalizer","evaluateActiveCondition","groups","condition","elseContent","renderWhenContent","newActive","renderContentItems","registerWhenRuntime","getWhenRuntime","updateWhenRuntimes","renderContentItem","maybeNode","applyModifiers","localIndex","hydrating","modifiers","resetReusedElement","createElementFactory","stub","svg","createHtmlTagBuilder","createSvgTagBuilder","encodeBranch","activeIndex","decodeBranch","match","markerText","WhenBuilderImpl","additionalGroup","newElseContent","serverBranch","contentToRender","createWhenBuilderFunction","builder","content","when","scopeRootsById","scopeRootFinalizer","set","normalizeScopeIds","normalized","seen","ids","idsByRoot","sweepAt","addScopeRoot","getScopeRoots","scopeIds","roots","updaters","update","root","render","forcedRoots","forcedRootFinalizer","unwrapComponent","built","registerForcedRoot","component","nodeModFn","targetParent","hydrate","hydrateRoot","forceUpdate","write","read","parentEl","elementNode","stale","after","createState","ENGINE_STATE_KEY","globalScope","cachedState","getState","registerQueries","query","queries","state","createGroup","group","groupQueryOf","groupQueries","cached","rule","brace","ruleIdentity","rememberExternalRule","contextKeyOf","texts","consumeExternalRule","indexExternalRules","rules","prelude","insertBase","inserted","insertGrouped","getOrCreateGroup","direct","ensureSheet","r","bucket","hash","input","c","appendKeyPart","expandAmpersands","expanded","quote","code","replacement","selectorFor","selector","isValidClassName","second","atomBlock","contextKey","prop","decls","declKey","exactName","body","mergeBlocks","first","concat","lastIndex","decl","conflictKeyOf","meta","getStyleEpoch","addRawRule","dedupeKey","getCssText","out","resetStyles","camelToKebab","firstUpper","PSEUDO","ALIAS","COMPOSITE","TOKEN_PROP","UNITLESS","kebabCache","kebab","toQuery","screen","isBareCondition","leadsWithNot","combineQuery","outer","inner","outerCondition","innerCondition","mergeStyle","source","StyleResultImpl","makeResult","pickClass","picked","prev","collectClassString","collectClasses","inputs","composeClassName","cxPairMemo","isPlainCxObject","cx","only","epoch","hit","BASE_CONTEXT","createCss","screens","theme","memo","toCssValue","bucketFor","walk","raws","pseudo","composite","targets","css","named","nameOrStyle","maybeStyle","isBase","flatDecls","keyframes","stop","frames","globalStyle","variants","normalize","config","groupNames","defaults","baseStyle","compounds","compoundStyle","conditions","cache","cacheEpoch","selection","chosen","props","compound","matches","defaultInstance","getDefaultInstance","HTML_TAGS","SVG_TAGS","defineLazyGlobal","create","registerHtmlTag","registerSvgTag","exportName","registerGlobalTagBuilders","marker","initializeRuntime","registry"],"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/element/factory.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/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 * Returning `false` reports that the write did not take (a <select> value\n * whose <option> does not exist yet): the value is then not cached, so the\n * next update() applies it again.\n */\nexport type AttributeApplier = (element: Element, key: string, value: unknown) => boolean | 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\n/**\n * Creates one of nuclo's own marker comments (text / list / when). The extra\n * argument is ignored by a real DOM; the SSR polyfill records it so\n * renderToString() can emit markers without inspecting their text.\n */\nexport function createMarker(text: string): Comment {\n return (document as unknown as { createComment(data: string, marker: boolean): Comment }).createComment(text, true);\n}\n\nexport function createMarkerPair(prefix: string, id: number): { start: Comment; end: Comment } {\n return { start: createMarker(`${prefix}-start-${id}`), end: createMarker(`${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, withScopedInsertion } 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 // Cursor values are strong node references (the next unclaimed sibling).\n // Dropped with the pass, so a node the app removes later is not kept alive\n // by its parent's cursor until the next pass replaces the map.\n _cursors = new WeakMap<Node, Node | null>();\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\n/**\n * Builds a fresh list()/when() block in the middle of a hydration pass, when\n * there are no SSR markers to claim. The block's appends land at the claim\n * cursor (not after the still-unclaimed children) and the cursor is pinned\n * behind it, so no later sibling can claim the block's fresh nodes.\n */\nexport function runFreshAtCursor<T>(parent: Node, build: () => T): T {\n const at = peekChild(parent);\n // Pin: with no entry, peekChild would follow the block's new firstChild.\n setCursor(parent, at);\n return runWithoutHydration(() => at ? withScopedInsertion(parent, at, build) : build());\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 *\n * forceUpdate() is different: the DOM it walks was built by nuclo, where a\n * bare whitespace text is a real text child. One that sits where the new tree\n * expects an element or a marker is a child the tree no longer produces — it\n * is dropped (`drop`), or it would survive in front of the cursor forever.\n */\nexport function skipWhitespaceText(parent: Node, drop = _force): void {\n let child = peekChild(parent);\n let advanced = false;\n while (child && isWhitespaceText(child)) {\n const next = child.nextSibling;\n if (drop) safeRemoveChild(child);\n child = next;\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) {\n // HTML elements report \"DIV\"; SVG elements keep their case — exact match\n // first, so camelCase SVG tags (linearGradient, clipPath) are claimable.\n const name = (candidate as Element).tagName;\n if (name === tagName || name.toLowerCase() === tagName) 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) — fresh nodes sit before the cursor and\n * nodes a modifier appended itself come after that boundary; both are\n * preserved.\n *\n * When `lastOriginalChild` is no longer a child, the modifiers already dealt\n * with every original node: a `textContent`/`innerHTML` attribute replaced\n * them wholesale, or the claim walk reached and dropped it. Whatever the\n * element holds now is the new build's own content — walking it for a boundary\n * that is gone would remove all of it.\n */\nexport function cleanupUnclaimedChildren(node: Node, lastOriginalChild: Node | null): void {\n if (!lastOriginalChild || lastOriginalChild.parentNode !== node) 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()` or `innerHTML = ''` on a container built by render()) never\n * gets its onDestroy callbacks or onMount cleanups run — not even on a later\n * update(). This file does not use a MutationObserver, and update() only\n * prunes disconnected nodes from its registries without disposing their\n * lifecycles. That never leaks memory (all bookkeeping below is\n * WeakMap-based, exactly like every other nuclo registry — see\n * test/memory/gc-collectability.test.ts), but timers or subscriptions the\n * app started in onMount keep running. Apps that need teardown should remove\n * the subtree through nuclo, e.g. by switching off a when() around it.\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/** Current end of the mount queue — pass it to cancelMountsSince(). */\nexport function mountQueueMark(): number {\n return mountQueue.length;\n}\n\n/**\n * Cancels the mounts queued since `mark` for elements that never made it into\n * the document: the operation that was building them threw, so they were\n * discarded instead of attached. Left queued, the next flush would fire\n * onMount on a detached element — one nuclo never removes, so its cleanup and\n * onDestroy could never run. Elements that did get attached keep their turn.\n */\nexport function cancelMountsSince(mark: number): void {\n for (let i = mountQueue.length - 1; i >= mark; i--) {\n const element = mountQueue[i].deref();\n if (element && !element.isConnected) disposeElementLifecycle(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, the same attribute key set by\n * two attribute objects of one element, SVG) bails to the normal build path —\n * the template is per-list state, so unsupported lists simply never activate\n * it. A per-row shape mismatch (heterogeneous render output) deactivates the\n * template for that 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 /**\n * Static attrs: a skeleton clone already carries the first-row value, so a\n * row with that same value needs no write. False for state cloneNode() does\n * not copy (e.g. a <select>'s value) — those rows always write.\n */\n cloned: 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/** True when an earlier attribute object of the same element already sets `key`. */\nfunction setsAttribute(slots: readonly TemplateSlot[], key: string): boolean {\n for (let i = 0; i < slots.length; i++) {\n const slot = slots[i];\n if (slot.kind !== SLOT_ATTRS) continue;\n for (let k = 0; k < slot.keys.length; k++) {\n if (slot.keys[k].key === key && slot.keys[k].kind !== ATTR_NULL) return true;\n }\n }\n return false;\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\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, cloned: false });\n continue;\n }\n if (key === \"style\") return null;\n // The same key set by two attribute objects (className merging, or a\n // plain \"last one wins\" attribute): patching a clone slot by slot\n // can't replay that — a later slot whose value equals its first-row\n // value is skipped, leaving an earlier slot's row value in place.\n if (setsAttribute(slots, key)) 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, cloned: false, value: eventProperty });\n continue;\n }\n if (key === \"className\" && (v as () => unknown).length === 0) {\n specs.push({ key, kind: ATTR_REACTIVE_CLASSNAME, prop: false, cloned: 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 specs.push({ key, kind: ATTR_STATIC, prop: false, cloned: 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 spec.cloned = spec.prop\n ? (skeleton as unknown as Record<string, unknown>)[spec.key] === spec.value\n : skeleton.getAttribute(spec.key) === String(spec.value);\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 && spec.cloned) 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 // The key must be there and nullish: a row whose object has a\n // different key in its place also reads as undefined here, and\n // would otherwise lose that attribute.\n if (v != null || !(spec.key in attrs)) 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, clearBetweenMarkers, safeRemoveChild, disposeLifecyclesInSubtree } from \"../shared/dom\";\nimport { isHydrating, isSerializing, claimMarkerPair, peekChild, setCursor, runFreshAtCursor } 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, mountQueueMark, cancelMountsSince } 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\n/**\n * The single-choice <select> whose options a list renders: its direct parent,\n * or an <optgroup>'s parent. (A `multiple` select has no one value to keep.)\n */\nfunction selectOwning(parent: Node | null): HTMLSelectElement | null {\n if (!parent) return null;\n const node = parent.nodeName === \"OPTGROUP\" ? parent.parentNode : parent;\n return node && node.nodeName === \"SELECT\" && !(node as HTMLSelectElement).multiple ? node as HTMLSelectElement : null;\n}\n\nexport function sync<TItem, TTagName extends ElementTagName>(\n runtime: ListRuntime<TItem, TTagName>\n): void {\n const items = normalizeItems(runtime.itemsProvider());\n\n if (arraysEqual(runtime.lastSyncedItems, items)) return;\n\n // Removing, moving or rebuilding <option>s makes the browser re-pick the\n // selection — rows rebuilt from refetched data, or a plain reorder, would\n // silently change what a <select> shows. Keep it on the value it had.\n const select = isBrowser ? selectOwning(runtime.startMarker.parentNode) : null;\n const selectedValue = select && select.selectedIndex >= 0 ? select.value : null;\n\n const mark = mountQueueMark();\n try {\n diffRows(runtime, items);\n if (selectedValue !== null && select!.value !== selectedValue) {\n const fallback = select!.selectedIndex;\n select!.value = selectedValue;\n // No option carries that value any more: keep the browser's pick.\n if (select!.value !== selectedValue) select!.selectedIndex = fallback;\n }\n } catch (error) {\n // A render function threw mid-diff: rows may already be removed, moved or\n // recorded without being inserted, so the records no longer mirror the\n // DOM. Reset to an empty list — the next sync rebuilds it from scratch\n // instead of diffing against a state that does not exist.\n const { startMarker, endMarker } = runtime;\n if (startMarker.parentNode && startMarker.parentNode === endMarker.parentNode) {\n clearBetweenMarkers(startMarker, endMarker);\n }\n runtime.records = [];\n runtime.lastSyncedItems = [];\n runtime.allRecordsCreatedAt = undefined;\n // Rows built but never inserted must not mount on a later flush.\n cancelMountsSince(mark);\n throw error;\n }\n}\n\nfunction diffRows<TItem, TTagName extends ElementTagName>(\n runtime: ListRuntime<TItem, TTagName>,\n items: readonly TItem[],\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 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 runFreshAtCursor(parentNode, () => 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 updateListFlushEpoch++;\n\n for (const ref of activeListRuntimes) {\n const startMarker = ref.deref();\n\n // Marker was garbage collected\n if (!startMarker) {\n activeListRuntimes.delete(ref);\n continue;\n }\n\n const runtime = listRuntimeByMarker.get(startMarker);\n if (!runtime) {\n activeListRuntimes.delete(ref);\n continue;\n }\n\n // Clean up if disconnected from DOM\n if (!startMarker.isConnected || !runtime.endMarker.isConnected) {\n listRuntimeByMarker.delete(startMarker);\n activeListRuntimes.delete(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","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 const applied = record.apply(element, record.key, nextValue);\n record.lastValue = cacheable && applied !== false ? 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<Element, Set<string>>();\nconst reactiveClassNameFlags = new WeakSet<Element>();\n\n// SVG's `className` is a read-only SVGAnimatedString, so non-HTML elements go\n// through the `class` attribute. The SSR polyfill's elements are all\n// HTMLElement and keep the plain `.className` string the serializer reads.\nfunction getClass(el: Element): string {\n\treturn el instanceof HTMLElement ? el.className : el.getAttribute('class') || '';\n}\n\nfunction setClass(el: Element, value: string): void {\n\tif (el instanceof HTMLElement) el.className = value;\n\telse el.setAttribute('class', value);\n}\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: Element): void {\n\tconst current = getClass(el);\n\tif (current && !staticClassNames.has(el)) {\n\t\tconst classSet = new Set<string>();\n\t\taddClassTokens(classSet, current);\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: Element): void {\n\tstaticClassNames.delete(el);\n\treactiveClassNameFlags.delete(el);\n}\n\n// Check if element has a reactive className\nexport function hasReactiveClassName(el: Element): boolean {\n\treturn reactiveClassNameFlags.has(el);\n}\n\n// Add static classes to the element's tracked set\nexport function addStaticClasses(el: Element, 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: Element, 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 (getClass(el) !== next) setClass(el, next);\n\t\treturn;\n\t}\n\tif (!reactiveClassName) {\n\t\tsetClass(el, 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\tsetClass(el, result);\n}\n\n// Merge static className (for non-reactive className attributes)\nexport function mergeStaticClassName(el: Element, newClassName: string): void {\n\tif (!newClassName) return;\n\tconst currentClassName = getClass(el);\n\tif (currentClassName && currentClassName !== newClassName) {\n\t\tconst existing = new Set<string>();\n\t\taddClassTokens(existing, currentClassName);\n\t\taddClassTokens(existing, newClassName);\n\t\tsetClass(el, joinClasses(existing));\n\t} else {\n\t\tsetClass(el, 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 * The value each <select> was last asked to show.\n *\n * A select only accepts a value one of its options carries, and attributes\n * are applied before children — so `select({ value }, option(...), ...)`\n * writes the value into a select that has no options yet and the browser\n * drops it. hydrate()/forceUpdate() have the mirror problem: the value is\n * applied against the old options, which are then re-labelled in place. The\n * element factory therefore re-applies it once the children are settled.\n */\nconst selectValues = new WeakMap<Element, unknown>();\n\n/**\n * Sets a <select>'s value. When no option carries it (yet) the assignment\n * would only deselect everything, so the previous selection is put back;\n * `false` keeps a reactive value uncached so every update() retries it until\n * an option matches.\n */\nfunction setSelectValue(select: HTMLSelectElement, v: unknown): boolean | void {\n const value = String(v);\n selectValues.set(select, v);\n if (select.value === value) return;\n const previous = select.selectedIndex;\n select.value = value;\n if (select.value === value) return;\n select.selectedIndex = previous;\n return false;\n}\n\n/**\n * Re-applies a <select>'s value once its children are built (called by the\n * element factory): the options it needs exist only now.\n */\nexport function retrySelectValue(el: Element): void {\n const value = selectValues.get(el);\n if (value !== undefined) setSelectValue(el as HTMLSelectElement, value);\n}\n\n/** Drops a reused <select>'s remembered value before its new build re-applies (or omits) it. */\nexport function forgetSelectValue(el: Element): void {\n selectValues.delete(el);\n}\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 *\n * Returns false when the write did not take (see setSelectValue), which keeps\n * a reactive value from being cached until it does.\n */\nfunction setAttributeValue(\n el: Element,\n key: string,\n v: unknown,\n merge?: boolean,\n): boolean | 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') {\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 (className included)\n if (el instanceof Element && el.namespaceURI === SVG_NAMESPACE) {\n el.setAttribute(key === 'className' ? 'class' : key, String(v));\n } else if (key in el) {\n // For HTML elements, try to set as property first\n if (key === 'value' && el.localName === 'select') return setSelectValue(el as HTMLSelectElement, v);\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, 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') {\n initReactiveClassName(el as unknown as Element);\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 const node = el as unknown as Element;\n if (k === 'className' && hasReactiveClassName(node)) {\n // There's already a reactive className; update the tracked set and DOM atomically.\n const newClassName = String(raw || '');\n if (newClassName) {\n addStaticClasses(node, newClassName);\n mergeStaticClassName(node, newClassName);\n }\n return;\n }\n setAttributeValue(node, 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 // An <input>'s value is sanitized against its type/min/max/step as they\n // stand when it is written (a range input clamps it), so it is applied\n // after the object's other keys — `{ value: 150, max: 200 }` must not\n // clamp to the default max of 100.\n let valueLast = false;\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 if (k === 'value' && (element as unknown as Element).localName === 'input') {\n valueLast = true;\n continue;\n }\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 if (valueLast) {\n applySingleAttribute(\n element,\n 'value' as AttributeKey<TTagName>,\n (attributes as Record<string, unknown>).value as AttributeCandidate<TTagName> | undefined,\n );\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 { cleanupReactiveTextNode, 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\";\nimport { createMarker } from \"../shared/dom\";\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\t// The node may have been reactive in the previous build (the tree\n\t\t\t// shifted) — unregister it, or the next update() would overwrite\n\t\t\t// this static text with the stale resolver's value.\n\t\t\tconst force = isForceHydrating();\n\t\t\tif (force) {\n\t\t\t\tconst claimed = claimBareText(parentNode);\n\t\t\t\tif (claimed) {\n\t\t\t\t\tcleanupReactiveTextNode(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\tconst claimed = claimTextAfterMarker(parentNode, expected);\n\t\t\t\tif (force) cleanupReactiveTextNode(claimed);\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(createMarker(` 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 { getFactoryMods } from \"../element/factory-meta\";\nimport { mountQueueMark, cancelMountsSince } from \"../element/lifecycle\";\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 renderContentItems(contentToRender, host, index, 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 for (const ref of activeWhenRuntimes) {\n const startMarker = ref.deref();\n\n // Comment node was garbage collected\n if (startMarker === undefined) {\n activeWhenRuntimes.delete(ref);\n continue;\n }\n\n const runtime = whenRuntimeByMarker.get(startMarker);\n if (!runtime) {\n activeWhenRuntimes.delete(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 activeWhenRuntimes.delete(ref);\n continue;\n }\n\n // Skip if outside update scope\n if (scope && !scope.contains(startMarker)) continue;\n\n const mark = mountQueueMark();\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 activeWhenRuntimes.delete(ref);\n // Content built but never inserted must not mount on the next flush.\n cancelMountsSince(mark);\n }\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 // Primitives, attribute objects, reactive text and tag-builder factories\n // (which build their element detached) never append to the host themselves:\n // the caller inserts whatever node comes back. Keeping them off the scoped\n // path matters — it adds and deletes an own `appendChild` on the host, which\n // drops the element out of the engine's fast property mode for good.\n if (!isFunction(item) || isZeroArityFunction(item) || getFactoryMods(item) !== undefined) {\n return applyNodeModifier(host, item, index);\n }\n\n // Other functions (nested when()/list() blocks, custom modifiers) may append\n // to the host: scope those appends so they land 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 before the end marker, in source order.\n *\n * Each node is inserted as soon as its item produces it: nested when()/list()\n * blocks insert their own markers while they run, so collecting the element\n * nodes and inserting them afterwards would put every nested block ahead of\n * the siblings written before it.\n */\nexport function renderContentItems<TTagName extends ElementTagName>(\n items: ReadonlyArray<WhenContent<TTagName>>,\n host: ExpandedElement<TTagName>,\n index: number,\n endMarker: Comment\n): void {\n for (const item of items) {\n const node = renderContentItem(item, host, index, endMarker);\n if (node) insertNodesBefore([node], endMarker);\n }\n}\n","/**\n * Element creation: builds HTML/SVG elements and applies the modifier list\n * that was passed to a tag builder (children, attributes, text, on(), ...).\n */\nimport { applyNodeModifier, type NodeModifier } from \"./modifiers\";\nimport { forgetSelectValue, retrySelectValue } from \"./attributes\";\nimport { SVG_NAMESPACE } from \"../shared/dom\";\nimport { claimElement, claimChild, cleanupUnclaimedChildren, isHydrating, 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 hydrating = isHydrating();\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 // hydrate()/forceUpdate(): a fresh node (nothing to claim, or a\n // structural mismatch) lands at the claim cursor, keeping sibling\n // order — a plain append would put it after the cursor, where a later\n // sibling's claim would reach it. 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 (hydrating) {\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 * Clears state a claimed element carries from its previous build so\n * re-applying the current modifiers converges instead of accumulating.\n *\n * Every claim (hydrate() and forceUpdate()) rebuilds class state from scratch:\n * the existing class attribute is the output of className modifiers, and left\n * in place initReactiveClassName would capture it as static classes that a\n * dynamic className then adds to instead of replacing.\n *\n * forceUpdate() also detaches on() listeners (the re-applied modifiers\n * re-attach), drops reactive attribute resolvers (re-registered) and rebuilds\n * inline style. 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, force: boolean): void {\n resetClassNameTracking(el as HTMLElement);\n el.removeAttribute(\"class\");\n if (!force) return;\n removeAllListeners(el as HTMLElement);\n cleanupReactiveElement(el);\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) {\n resetReusedElement(claimed, isForceHydrating());\n if (tagName === \"select\") forgetSelectValue(claimed);\n }\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 // A select's value can only be applied once its options are in place.\n if (tagName === \"select\") retrySelectValue(el);\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","import { createMarkerPair, clearBetweenMarkers, safeRemoveChild } 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, peekChild, setCursor, runWithoutHydration, runFreshAtCursor } from \"../hydration\";\nimport { applyModifiers } from \"../element/factory\";\nimport type { NodeModifier } 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 runFreshAtCursor(parentNode, () => 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 // applyModifiers (not a bare applyNodeModifier): a node that could\n // not be claimed is inserted at the claim cursor instead of dropped.\n // One call per item — every branch item shares the block's `index`,\n // as in renderContentItems.\n for (const item of contentToRender) {\n applyModifiers(host, [item as NodeModifier<TTagName>], index);\n }\n }\n // Remove the SSR nodes the branch did not claim (same as list()).\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 } 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 runWithoutHydration(() => renderContentItems(contentToRender, host, index, endMarker));\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 (read once) or functions that are re-evaluated\n * on every update().\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 * let isLoggedIn = false;\n *\n * div(\n * when(() => isLoggedIn,\n * span('Welcome back!')\n * )\n * .else(\n * button('Login', { onClick: () => { isLoggedIn = true; update(); } })\n * )\n * )\n * ```\n *\n * @example\n * ```ts\n * // Multiple conditions\n * let status: 'loading' | 'error' | 'ready' = 'loading';\n *\n * div(\n * when(() => status === 'loading',\n * p('Loading…')\n * )\n * .when(() => status === 'error',\n * p('Something went wrong')\n * )\n * .else(\n * p('Ready')\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 */\nexport const scopeRootsById = new Map<ScopeId, Set<WeakRef<Element>>>();\n\n/**\n * Drops a collected root's entry — and its id, once no root is left under it.\n * Without this, per-row ids (scope(`row-${id}`)) that are never passed to\n * update() again would stay in the map forever: one id, one Set and one dead\n * WeakRef per row the app ever rendered. The sweeps below only bound a single\n * id's set, not the number of ids.\n */\nconst scopeRootFinalizer = typeof FinalizationRegistry !== \"undefined\"\n ? new FinalizationRegistry<{ id: ScopeId; ref: WeakRef<Element> }>(({ id, ref }) => {\n const set = scopeRootsById.get(id);\n if (set?.delete(ref) && set.size === 0) scopeRootsById.delete(id);\n })\n : null;\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\n/** Ids each root is already registered under: O(1) dedup instead of a set scan. */\nconst idsByRoot = new WeakMap<Element, Set<ScopeId>>();\n/** Sweep a set of dead refs once it grows past this; doubles with the live size. */\nconst sweepAt = new WeakMap<Set<WeakRef<Element>>, number>();\nconst MIN_SWEEP = 64;\n\nfunction addScopeRoot(id: ScopeId, el: Element): void {\n let ids = idsByRoot.get(el);\n if (!ids) idsByRoot.set(el, ids = new Set());\n // Re-registration (forceUpdate() reclaim) must not grow the set.\n if (ids.has(id)) return;\n ids.add(id);\n\n let set = scopeRootsById.get(id);\n if (!set) scopeRootsById.set(id, set = new Set());\n const ref = new WeakRef(el);\n set.add(ref);\n scopeRootFinalizer?.register(el, { id, ref });\n\n // Ids that are never passed to update(id) are never pruned by getScopeRoots(),\n // so list rows scoped with scope(\"row\") would grow the set forever. Sweep\n // collected refs at amortized O(1) per add. Detached roots are kept: they\n // are legitimately unattached while their tree is still being built.\n if (set.size >= (sweepAt.get(set) ?? MIN_SWEEP)) {\n for (const ref of set) if (ref.deref() === undefined) set.delete(ref);\n sweepAt.set(set, Math.max(MIN_SWEEP, set.size * 2));\n }\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 for (const ref of set) {\n const el = ref.deref();\n // Collected or disconnected: drop it (deleting while iterating a Set is safe).\n if (el === undefined) set.delete(ref);\n else if (!el.isConnected) {\n set.delete(ref);\n idsByRoot.get(el)?.delete(id); // let scope() re-register it if it comes back\n } else roots.add(el);\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, skipWhitespaceText } from \"./hydration\";\nimport { safeRemoveChild } from \"./shared/dom\";\nimport { flushMountQueue, mountQueueMark, cancelMountsSince } 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 mark = mountQueueMark();\n let element: ExpandedElement<TTagName>;\n try {\n element = build(targetParent, index) as ExpandedElement<TTagName>;\n (targetParent as unknown as Node).appendChild(element as Node);\n } catch (error) {\n // The half-built tree is discarded: nothing in it may mount later.\n cancelMountsSince(mark);\n throw error;\n }\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) — including\n * whitespace-only text inside the tree that sits where an element or block is\n * now expected (the container's own whitespace is never touched).\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 // The container belongs to the app, not to nuclo: step over its template\n // whitespace here so a force pass (which drops stale whitespace text inside\n // the tree it rebuilds) never removes it.\n else if (force) skipWhitespaceText(parentNode, false);\n const mark = mountQueueMark();\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 } catch (error) {\n // Fresh nodes of the half-built tree are discarded: they may not mount\n // later. Claimed nodes are live in the document and keep their turn.\n cancelMountsSince(mark);\n throw error;\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 = '&'; break; // &\n case 60: escaped = '<'; break; // <\n case 62: escaped = '>'; break; // >\n case 34: escaped = '"'; break; // \"\n case 39: escaped = '''; 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 = '&'; break; // &\n case 60: escaped = '<'; break; // <\n case 62: escaped = '>'; 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\n/**\n * True for an @media prelude that is a bare condition list (\"(min-width: 40em)\n * and (hover)\") rather than one led by a media type (\"print\", \"only screen\").\n * Only a bare list can sit on the right of an `and`: per the media-query\n * grammar a type (and the `only` keyword) must lead the whole query, so\n * \"(min-width: 768px) and print\" is not a valid query — every browser\n * normalizes it to `not all` and the block silently never matches.\n */\nfunction isBareCondition(condition: string): boolean {\n\treturn condition.charCodeAt(0) === 40 /* ( */;\n}\n\n/** A leading `not` negates the whole query, so it can never be flattened with `and`. */\nfunction leadsWithNot(condition: string): boolean {\n\tif (!condition.startsWith(\"not\")) return false;\n\tconst after = condition.charCodeAt(3);\n\treturn Number.isNaN(after) || after === 32 /* space */ || after === 40 /* ( */;\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\tconst outerCondition = outer.slice(6).trim();\n\t\tconst innerCondition = inner.slice(6).trim();\n\t\t// Put the media-type side first — the only arrangement the grammar allows.\n\t\tif (!leadsWithNot(outerCondition) && !leadsWithNot(innerCondition)) {\n\t\t\tif (isBareCondition(innerCondition)) return \"@media \" + outerCondition + \" and \" + innerCondition;\n\t\t\tif (isBareCondition(outerCondition)) return \"@media \" + innerCondition + \" and \" + outerCondition;\n\t\t}\n\t\t// Two media types, or a `not` on either side: no single flat prelude means\n\t\t// what was authored, and the engine emits one group per query rather than\n\t\t// nested groups. Drop the outer condition (as for any other nested at-rule)\n\t\t// instead of emitting a prelude that silently matches nothing.\n\t\tconsole.warn(\n\t\t\t`[nuclo] cannot combine nested media queries ${JSON.stringify(outer)} and ${JSON.stringify(inner)}; ` +\n\t\t\t\t\"using the inner query alone. Author one query that states both conditions.\",\n\t\t);\n\t\treturn inner;\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(name: string, style: Style<T>): StyleResult;\n\tfunction css(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(name: string, style: Style<object>): StyleResult;\n\t(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 * 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.mjs","names":["globalScope","RESERVED_LIFECYCLE_ATTRIBUTES","fallbackEventListeners","nativeEventHandlers","eventAttributeToProperty","attribute","firstEventCharacter","setEventAttribute","property","element","listener","handlers","type","list","i","previous","removeEventAttributes","target","listeners","logError","message","error","isBrowser","reactiveTextNodes","reactiveTextNodesByNode","reactiveElements","reactiveElementsByNode","registerReactiveTextNode","existing","node","resolver","lastValue","ref","registerReactiveElement","entry","cleanupReactiveTextNode","cleanupReactiveElement","cleanupNodeTree","removeAllListeners","disposeElementLifecycle","children","hasActiveLifecycleRegistrations","safeRemoveChild","child","safeInsertBefore","parent","newNode","referenceNode","createMarker","text","createMarkerPair","prefix","id","clearBetweenMarkers","current","startMarker","endMarker","next","insertNodesBefore","nodes","withScopedInsertion","host","originalAppend","originalInsert","callback","SERIALIZING_KEY","globalScope$1","shared","isSerializing","serializingScratch","_hydrating","_force","_cursors","isHydrating","isForceHydrating","startHydration","force","endHydration","runWithoutHydration","wasHydrating","fn","peekChild","setCursor","runFreshAtCursor","at","build","isWhitespaceText","skipWhitespaceText","advanced","drop","claimChild","claimBareText","sibling","claimMarkerPair","start","startPrefix","endText","depth","end","claimElement","candidate","name","tagName","cleanupUnclaimedChildren","lastOriginalChild","records","activeCount","mountQueue","shouldSkip","ensureRecord","record","pushSlot","slot","cb","registerMount","registerDestroy","setNodeDisposer","dispose","runMount","cleanup","runDestroy","fireMount","mount","flushMountQueue","batch","mountQueueMark","cancelMountsSince","mark","wasMounted","destroy","isMounted","FACTORY_TAG","FACTORY_MODS","EVENT_MODIFIER","metadataOnlyFactoryDepth","metadataOnlyStubPool","metadataOnlyPoolIndex","acquireMetadataOnlyFactory","setFactoryMeta","tag","mods","getFactoryMods","getFactoryTag","markEventModifier","isEventModifier","isMetadataOnlyFactoryMode","withMetadataOnlyFactories","item","index","getMetadataOnlyFactoryCheckpoint","releaseMetadataOnlyFactories","checkpoint","factory","elementListeners","trackListener","tracked","info","detachListener","noopEventModifier","createLifecycleModifier","el","kind","createTrackedListener","currentTarget","event","on","options","isPrimitive","value","isNode","isObject","isFunction","isZeroArityFunction","toText","createReactiveTextNode","str","initial","txt","notifyReactiveTextNodes","scope","setsAttribute","slots","k","key","analyzeFactory","mod","t","childMods","childTag","v","attrs","keys","specs","vt","eventProperty","prepareSkeleton","tmpl","skeleton","spec","instantiateTemplate","attrCount","_k","s","resolved","leaves","textNode","adoptTemplateLeaves","flushRowLeaves","UNSET_LAST_VALUE","updateRecord","nextValue","cacheable","applied","registerAttributeResolver","resolvers","notifyReactiveElements","assignInlineStyles","style","styles","applyReactiveStyle","applyStyleAttribute","styleValue","staticClassNames","reactiveClassNameFlags","getClass","setClass","addClassTokens","len","className","joinClasses","result","cls","classes","initReactiveClassName","classSet","resetClassNameTracking","hasReactiveClassName","addStaticClasses","mergeReactiveClassName","staticClasses","reactiveClassName","token","mergeStaticClassName","newClassName","currentClassName","selectValues","setSelectValue","select","retrySelectValue","forgetSelectValue","setAttributeValue","merge","applyReactiveClassName","applySingleAttribute","raw","shouldMergeClassName","applyAttributes","valueLast","attributes","mergeClassName","isClassNameOnlyObject","nextChildIsTextComment","claimTextAfterMarker","expected","created","applyNodeModifier","modifier","parentNode","claimed","wrapTextNode","emptyText","produced","fragment","activeWhenRuntimes","whenRuntimeByMarker","whenMarkerFinalizer","evaluateActiveCondition","groups","condition","elseContent","renderWhenContent","runtime","newActive","renderContentItems","registerWhenRuntime","getWhenRuntime","updateWhenRuntimes","renderContentItem","maybeNode","items","applyModifiers","localIndex","startIndex","hydrating","modifiers","resetReusedElement","createElementFactory","stub","svg","createHtmlTagBuilder","createSvgTagBuilder","emptyRegistry","page","runtimeByMarker","viewsByAnchor","SSR_KEY","registry","scratch","reg","markerFinalizer","waiting","forgetPending","claimingRegions","dropped","marker","dropRegion","rt","shown","view","detach","pendView","pruneRegions","anchor","placed","removeView","registerRegion","old","known","onMarkerDisposed","anchorRef","waitingView","addView","takeOrphans","orphans","regionOf","isViewAnchor","getRegion","liveRegionAt","unpend","attachViews","earlier","views","before","stamp","decodeCount","match","markerText","showIn","setRange","first","stop","showEmpty","placeView","e","h","reclaimView","claimAt","cursor","hostCursor","from","content","claimRange","boundary","leftover","boundaryAfter","last","claimEmpty","reclaimEmpty","underneath","sweepRegions","arraysEqual","a","b","activeListRuntimes","listRuntimeByMarker","listMarkerFinalizer","updateListFlushEpoch","registerListRuntime","normalizeItems","toRowElement","rebuildRowNormally","leafScratch","takeLeaves","renderItem","renderItemWithTemplate","template","canUseTemplate","adopted","clone","bulkClearRecords","longestIncreasingSubsequence","n","arr","predecessor","tails","x","lo","hi","mid","idx","buildAndInsert","endIndexExclusive","dyn","targetRecords","selectOwning","sync","selectedValue","diffRows","fallback","oldRecords","oldLen","newLen","maxTrim","suffix","maxSuffix","oldStart","oldEnd","newStart","newEnd","fresh","oldWinLen","newWinLen","sources","reusedCount","pinEnd","pinnedCount","buckets","j","oldIndex","stable","pinnedOnly","survivorOldIndices","survivorPositions","lis","windowRecords","nullCount","src","firstFlushed","merged","w","newRuntime","createListRuntime","hydrateListRuntime","itemsProvider","createListRuntimeNormal","pair","renderFn","currentItems","recordNode","updateListRuntimes","encodeBranch","activeIndex","decodeBranch","WhenBuilderImpl","additionalGroup","newElseContent","serverBranch","contentToRender","createWhenBuilderFunction","builder","when","scopeRootsById","scopeRootFinalizer","set","normalizeScopeIds","normalized","seen","ids","idsByRoot","sweepAt","addScopeRoot","getScopeRoots","scopeIds","roots","updaters","update","root","render","makeRuntime","empty","freshRegion","hydrateRegion","live","region","claimAnchor","into","targets","idOrRegions","forcedComponents","forcedRoots","forcedRootFinalizer","unwrapComponent","built","registerForcedRoot","component","nodeModFn","targetParent","hydrate","hydrateRoot","forceUpdate","write","read","parentEl","elementNode","stale","after","createState","ENGINE_STATE_KEY","globalScope","cachedState","getState","registerQueries","query","queries","state","createGroup","group","groupQueryOf","groupQueries","cached","rule","brace","ruleIdentity","rememberExternalRule","contextKeyOf","texts","consumeExternalRule","indexExternalRules","rules","prelude","insertBase","inserted","insertGrouped","getOrCreateGroup","direct","ensureSheet","r","bucket","hash","input","c","appendKeyPart","expandAmpersands","expanded","quote","code","replacement","selectorFor","selector","isValidClassName","second","atomBlock","contextKey","prop","decls","declKey","exactName","body","mergeBlocks","concat","lastIndex","decl","conflictKeyOf","meta","getStyleEpoch","addRawRule","dedupeKey","getCssText","out","resetStyles","camelToKebab","firstUpper","PSEUDO","ALIAS","COMPOSITE","TOKEN_PROP","UNITLESS","kebabCache","kebab","toQuery","screen","isBareCondition","leadsWithNot","combineQuery","outer","inner","outerCondition","innerCondition","mergeStyle","source","StyleResultImpl","makeResult","pickClass","picked","prev","collectClassString","collectClasses","inputs","composeClassName","cxPairMemo","isPlainCxObject","cx","only","epoch","hit","BASE_CONTEXT","createCss","screens","theme","memo","toCssValue","bucketFor","walk","raws","pseudo","composite","css","named","nameOrStyle","maybeStyle","isBase","flatDecls","keyframes","frames","globalStyle","variants","normalize","config","groupNames","defaults","baseStyle","compounds","compoundStyle","conditions","cache","cacheEpoch","selection","chosen","props","compound","matches","defaultInstance","getDefaultInstance","HTML_TAGS","SVG_TAGS","defineLazyGlobal","create","registerHtmlTag","registerSvgTag","exportName","registerGlobalTagBuilders","initializeRuntime"],"sources":["../src/element/event-attributes.ts","../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/shared/type-guards.ts","../src/update/reactive-text.ts","../src/list/template.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/element/factory.ts","../src/region/runtime.ts","../src/list/runtime.ts","../src/when/builder.ts","../src/when/index.ts","../src/update/scope.ts","../src/update/update.ts","../src/list/index.ts","../src/region/index.ts","../src/render.ts","../src/style/engine.ts","../src/shared/strings.ts","../src/style/css.ts","../src/element/tags.ts","../src/bootstrap.ts"],"sourcesContent":["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>();\nconst nativeEventHandlers = new WeakMap<HTMLElement, Map<string, EventListener>>();\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) {\n if (property in element) {\n (element as unknown as Record<string, unknown>)[property] = listener;\n let handlers = nativeEventHandlers.get(element);\n if (!handlers) nativeEventHandlers.set(element, handlers = new Map());\n handlers.set(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\n/** Releases only handlers installed through nuclo's event attributes. */\nexport function removeEventAttributes(element: HTMLElement) {\n const handlers = nativeEventHandlers.get(element);\n if (handlers) {\n const target = element as unknown as Record<string, unknown>;\n for (const [property, listener] of handlers) {\n // Leave a handler that external code replaced after our assignment alone.\n if (target[property] === listener) target[property] = null;\n }\n nativeEventHandlers.delete(element);\n }\n const listeners = fallbackEventListeners.get(element);\n if (listeners) {\n for (let i = 0; i < listeners.length; i += 2) {\n element.removeEventListener(listeners[i] as string, listeners[i + 1] as EventListener);\n }\n fallbackEventListeners.delete(element);\n }\n}\n","export function logError(message: string, error?: Error | unknown) {\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 * Returning `false` reports that the write did not take (a <select> value\n * whose <option> does not exist yet): the value is then not cached, so the\n * next update() applies it again.\n */\nexport type AttributeApplier = (element: Element, key: string, value: unknown) => boolean | 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) {\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) {\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) {\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 */\nexport function cleanupNodeTree(node: Node) {\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 } else if (node.nodeType === 8) {\n // A region's start marker or a view's anchor carries a disposer.\n disposeElementLifecycle(node);\n }\n\n // Recursively clean up all child nodes\n // Destroy callbacks can mutate the live childNodes collection. Snapshot\n // only when hooks exist; ordinary cleanup needs no additional allocation.\n const children = hasActiveLifecycleRegistrations() ? Array.from(node.childNodes) : node.childNodes;\n for (let i = 0; i < children.length; i++) {\n cleanupNodeTree(children[i]);\n }\n\n // Fire onDestroy last — after every descendant's onDestroy has already run\n // (post-order) — so a parent's teardown can rely on its children having\n // already released whatever they were using (e.g. a subscription or timer\n // the parent owns and children only read from). This mirrors onMount's own\n // order, which is naturally parent-before-child (registration order is\n // construction order: a parent's own onMount/{onMount} modifier is applied\n // before its child factories are even invoked) — so mount is top-down,\n // destroy is bottom-up, the same LIFO discipline nested resource scopes\n // always use. No-op unless this exact element registered a callback.\n if (node.nodeType === Node.ELEMENT_NODE) {\n disposeElementLifecycle(node as HTMLElement);\n }\n}\n\nexport function safeRemoveChild(child: Node) {\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) {\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\n/**\n * Creates one of nuclo's own marker comments (text / list / when). The extra\n * argument is ignored by a real DOM; the SSR polyfill records it so\n * renderToString() can emit markers without inspecting their text.\n */\nexport function createMarker(text: string): Comment {\n return (document as unknown as { createComment(data: string, marker: boolean): Comment }).createComment(text, true);\n}\n\nexport function createMarkerPair(prefix: string, id: number): { start: Comment; end: Comment } {\n return { start: createMarker(`${prefix}-start-${id}`), end: createMarker(`${prefix}-end`) };\n}\n\nexport function clearBetweenMarkers(startMarker: Comment, endMarker: Comment) {\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) {\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\");\ninterface SerializingState { on: boolean; scratch: Map<string, unknown> }\nconst globalScope = globalThis as unknown as Record<symbol, SerializingState | undefined>;\nconst shared = globalScope[SERIALIZING_KEY]\n ?? (globalScope[SERIALIZING_KEY] = { on: false, scratch: new Map<string, unknown>() });\n\nexport function isSerializing() {\n return shared.on;\n}\n\n/**\n * Scratch space for the current renderToString() call, emptied when that call\n * ends.\n *\n * A server renders every request from one process, so any registry a feature\n * keeps in module scope is shared by every request and every user at once.\n * Anything a server tree needs to look up mid-build goes here instead: it is\n * reachable for exactly as long as the tree is being built, and nothing from\n * one request is reachable from the next. Keys are namespaced by the feature\n * that owns them.\n */\nexport function serializingScratch(): Map<string, unknown> {\n return shared.scratch;\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 // Only the outermost call clears: a nested renderToString() is still part\n // of the same request and the tree around it is still being built.\n if (!shared.on) shared.scratch.clear();\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, withScopedInsertion } 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() {\n return _hydrating;\n}\n\n/** True only inside a forceUpdate() pass (never during plain hydrate()). */\nexport function isForceHydrating() {\n return _hydrating && _force;\n}\n\nexport function startHydration(force = false) {\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() {\n _hydrating = false;\n _force = false;\n // Cursor values are strong node references (the next unclaimed sibling).\n // Dropped with the pass, so a node the app removes later is not kept alive\n // by its parent's cursor until the next pass replaces the map.\n _cursors = new WeakMap<Node, Node | null>();\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) {\n _cursors.set(parent, node);\n}\n\n/**\n * Builds a fresh list()/when() block in the middle of a hydration pass, when\n * there are no SSR markers to claim. The block's appends land at the claim\n * cursor (not after the still-unclaimed children) and the cursor is pinned\n * behind it, so no later sibling can claim the block's fresh nodes.\n */\nexport function runFreshAtCursor<T>(parent: Node, build: () => T): T {\n const at = peekChild(parent);\n // Pin: with no entry, peekChild would follow the block's new firstChild.\n setCursor(parent, at);\n return runWithoutHydration(() => at ? withScopedInsertion(parent, at, build) : build());\n}\n\nfunction isWhitespaceText(node: Node) {\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 *\n * forceUpdate() is different: the DOM it walks was built by nuclo, where a\n * bare whitespace text is a real text child. One that sits where the new tree\n * expects an element or a marker is a child the tree no longer produces — it\n * is dropped (`drop`), or it would survive in front of the cursor forever.\n */\nexport function skipWhitespaceText(parent: Node, drop = _force) {\n let child = peekChild(parent);\n let advanced = false;\n while (child && isWhitespaceText(child)) {\n const next = child.nextSibling;\n if (drop) safeRemoveChild(child);\n child = next;\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\" | \"region\",\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) {\n // HTML elements report \"DIV\"; SVG elements keep their case — exact match\n // first, so camelCase SVG tags (linearGradient, clipPath) are claimable.\n const name = (candidate as Element).tagName;\n if (name === tagName || name.toLowerCase() === tagName) 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) — fresh nodes sit before the cursor and\n * nodes a modifier appended itself come after that boundary; both are\n * preserved.\n *\n * When `lastOriginalChild` is no longer a child, the modifiers already dealt\n * with every original node: a `textContent`/`innerHTML` attribute replaced\n * them wholesale, or the claim walk reached and dropped it. Whatever the\n * element holds now is the new build's own content — walking it for a boundary\n * that is gone would remove all of it.\n */\nexport function cleanupUnclaimedChildren(node: Node, lastOriginalChild: Node | null) {\n if (!lastOriginalChild || lastOriginalChild.parentNode !== node) 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 * list()'s bulk clear/replace also cleans each row before detaching it, so\n * destroy fires at removal time there too.\n *\n * An element removed through means nuclo never observes (e.g. a raw\n * `node.remove()` or `innerHTML = ''` on a container built by render()) never\n * gets its onDestroy callbacks or onMount cleanups run — not even on a later\n * update(). This file does not use a MutationObserver, and update() only\n * prunes disconnected nodes from its registries without disposing their\n * lifecycles. That never leaks memory (all bookkeeping below is\n * WeakMap-based, exactly like every other nuclo registry — see\n * test/memory/gc-collectability.test.ts), but timers or subscriptions the\n * app started in onMount keep running. Apps that need teardown should remove\n * the subtree through nuclo, e.g. by switching off a when() around it.\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 (cleanupNodeTree() in shared/dom.ts\n * recurses 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 /**\n * nuclo's own teardown for a marker node (a region's start marker, a\n * view's anchor). Unlike `destroy`, it runs whether or not the node ever\n * mounted: a tree discarded half-built (cancelMountsSince) may already have\n * put a view's content into a live region elsewhere.\n */\n dispose: ((node: Node) => void) | null;\n state: LifecycleStateValue;\n}\n\n// Keyed by Node, not Element: comment markers register a disposer too.\nconst records = new WeakMap<Node, LifecycleRecord>();\n\n/**\n * Count of Pending/Mounted records not yet disposed. Without live callbacks,\n * cleanupNodeTree() can walk childNodes without a mutation-safe snapshot.\n * Raw DOM removals can leave this count high, causing only extra snapshots.\n */\nlet activeCount = 0;\n\nlet mountQueue: WeakRef<Node>[] = [];\n\nfunction shouldSkip() {\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(node: Node): LifecycleRecord {\n let record = records.get(node);\n if (!record) {\n record = { mount: null, destroy: null, dispose: null, state: STATE_PENDING };\n records.set(node, record);\n activeCount++;\n mountQueue.push(new WeakRef(node));\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) {\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) {\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\n/**\n * Internal: nuclo's own teardown for a marker node, run once when nuclo\n * removes it (see `dispose` on the record). Idempotent per node, so a\n * forceUpdate() reclaim that passes the same function again changes nothing.\n */\nexport function setNodeDisposer(node: Node, dispose: (node: Node) => void) {\n if (shouldSkip()) return;\n const record = ensureRecord(node);\n if (record.state === STATE_DISPOSED) return;\n record.dispose = dispose;\n}\n\nfunction runMount(element: Element, callback: MountCallback<Element>, record: LifecycleRecord) {\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>) {\n try {\n callback(element);\n } catch (error) {\n logError(\"Error in destroy callback\", error);\n }\n}\n\nfunction fireMount(element: Element) {\n // Queued only by ensureRecord(), right after the record was stored. A\n // marker node's record has no mount callbacks; it just turns Mounted here.\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() {\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 as Element);\n }\n}\n\n/** Current end of the mount queue — pass it to cancelMountsSince(). */\nexport function mountQueueMark() {\n return mountQueue.length;\n}\n\n/**\n * Cancels the mounts queued since `mark` for elements that never made it into\n * the document: the operation that was building them threw, so they were\n * discarded instead of attached. Left queued, the next flush would fire\n * onMount on a detached element — one nuclo never removes, so its cleanup and\n * onDestroy could never run. Elements that did get attached keep their turn.\n */\nexport function cancelMountsSince(mark: number) {\n for (let i = mountQueue.length - 1; i >= mark; i--) {\n const element = mountQueue[i].deref();\n if (element && !element.isConnected) disposeElementLifecycle(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(node: Node) {\n const record = records.get(node);\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 const dispose = record.dispose;\n if (dispose !== null) {\n record.dispose = null;\n try {\n dispose(node);\n } catch (error) {\n logError(\"Error disposing node\", error);\n }\n }\n\n const element = node as Element;\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/** True once the node's queued mount has flushed: nuclo attached the tree it is in. */\nexport function isMounted(node: Node) {\n return records.get(node)?.state === STATE_MOUNTED;\n}\n\n/** Whether cleanup must snapshot children that lifecycle callbacks could mutate. */\nexport function hasActiveLifecycleRegistrations() {\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) {\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) {\n return typeof fn === \"function\" && (fn as { [EVENT_MODIFIER]?: boolean })[EVENT_MODIFIER] === true;\n}\n\nexport function isMetadataOnlyFactoryMode() {\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 { removeEventAttributes } from \"./event-attributes\";\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) {\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) {\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) {\n removeEventAttributes(element);\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>) {}\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>) {\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) {\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>) {\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","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.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) {\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) {\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, the same attribute key set by\n * two attribute objects of one element, SVG) bails to the normal build path —\n * the template is per-list state, so unsupported lists simply never activate\n * it. A per-row shape mismatch (heterogeneous render output) deactivates the\n * template for that 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 /**\n * Static attrs: a skeleton clone already carries the first-row value, so a\n * row with that same value needs no write. False for state cloneNode() does\n * not copy (e.g. a <select>'s value) — those rows always write.\n */\n cloned: 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/** True when an earlier attribute object of the same element already sets `key`. */\nfunction setsAttribute(slots: readonly TemplateSlot[], key: string) {\n for (let i = 0; i < slots.length; i++) {\n const slot = slots[i];\n if (slot.kind !== SLOT_ATTRS) continue;\n for (let k = 0; k < slot.keys.length; k++) {\n if (slot.keys[k].key === key && slot.keys[k].kind !== ATTR_NULL) return true;\n }\n }\n return false;\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\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, cloned: false });\n continue;\n }\n if (key === \"style\") return null;\n // The same key set by two attribute objects (className merging, or a\n // plain \"last one wins\" attribute): patching a clone slot by slot\n // can't replay that — a later slot whose value equals its first-row\n // value is skipped, leaving an earlier slot's row value in place.\n if (setsAttribute(slots, key)) 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, cloned: false, value: eventProperty });\n continue;\n }\n if (key === \"className\" && (v as () => unknown).length === 0) {\n specs.push({ key, kind: ATTR_REACTIVE_CLASSNAME, prop: false, cloned: 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 specs.push({ key, kind: ATTR_STATIC, prop: false, cloned: 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) {\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 spec.cloned = spec.prop\n ? (skeleton as unknown as Record<string, unknown>)[spec.key] === spec.value\n : skeleton.getAttribute(spec.key) === String(spec.value);\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) {\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 && spec.cloned) 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 setEventAttribute(el as HTMLElement, eventProperty, v as EventListener);\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 // The key must be there and nullish: a row whose object has a\n // different key in its place also reads as undefined here, and\n // would otherwise lose that attribute.\n if (v != null || !(spec.key in attrs)) 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) {\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) {\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","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) {\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 const applied = record.apply(element, record.key, nextValue);\n record.lastValue = cacheable && applied !== false ? 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) {\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) {\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) {\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) {\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) {\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<Element, Set<string>>();\nconst reactiveClassNameFlags = new WeakSet<Element>();\n\n// SVG's `className` is a read-only SVGAnimatedString, so non-HTML elements go\n// through the `class` attribute. The SSR polyfill's elements are all\n// HTMLElement and keep the plain `.className` string the serializer reads.\nfunction getClass(el: Element) {\n\treturn el instanceof HTMLElement ? el.className : el.getAttribute('class') || '';\n}\n\nfunction setClass(el: Element, value: string) {\n\tif (el instanceof HTMLElement) el.className = value;\n\telse el.setAttribute('class', value);\n}\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) {\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>) {\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: Element) {\n\tconst current = getClass(el);\n\tif (current && !staticClassNames.has(el)) {\n\t\tconst classSet = new Set<string>();\n\t\taddClassTokens(classSet, current);\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: Element) {\n\tstaticClassNames.delete(el);\n\treactiveClassNameFlags.delete(el);\n}\n\n// Check if element has a reactive className\nexport function hasReactiveClassName(el: Element) {\n\treturn reactiveClassNameFlags.has(el);\n}\n\n// Add static classes to the element's tracked set\nexport function addStaticClasses(el: Element, className: string) {\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: Element, reactiveClassName: string) {\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 (getClass(el) !== next) setClass(el, next);\n\t\treturn;\n\t}\n\tif (!reactiveClassName) {\n\t\tsetClass(el, 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\tsetClass(el, result);\n}\n\n// Merge static className (for non-reactive className attributes)\nexport function mergeStaticClassName(el: Element, newClassName: string) {\n\tif (!newClassName) return;\n\tconst currentClassName = getClass(el);\n\tif (currentClassName && currentClassName !== newClassName) {\n\t\tconst existing = new Set<string>();\n\t\taddClassTokens(existing, currentClassName);\n\t\taddClassTokens(existing, newClassName);\n\t\tsetClass(el, joinClasses(existing));\n\t} else {\n\t\tsetClass(el, 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 * The value each <select> was last asked to show.\n *\n * A select only accepts a value one of its options carries, and attributes\n * are applied before children — so `select({ value }, option(...), ...)`\n * writes the value into a select that has no options yet and the browser\n * drops it. hydrate()/forceUpdate() have the mirror problem: the value is\n * applied against the old options, which are then re-labelled in place. The\n * element factory therefore re-applies it once the children are settled.\n */\nconst selectValues = new WeakMap<Element, unknown>();\n\n/**\n * Sets a <select>'s value. When no option carries it (yet) the assignment\n * would only deselect everything, so the previous selection is put back;\n * `false` keeps a reactive value uncached so every update() retries it until\n * an option matches.\n */\nfunction setSelectValue(select: HTMLSelectElement, v: unknown): boolean | void {\n const value = String(v);\n selectValues.set(select, v);\n if (select.value === value) return;\n const previous = select.selectedIndex;\n select.value = value;\n if (select.value === value) return;\n select.selectedIndex = previous;\n return false;\n}\n\n/**\n * Re-applies a <select>'s value once its children are built (called by the\n * element factory): the options it needs exist only now.\n */\nexport function retrySelectValue(el: Element) {\n const value = selectValues.get(el);\n if (value !== undefined) setSelectValue(el as HTMLSelectElement, value);\n}\n\n/** Drops a reused <select>'s remembered value before its new build re-applies (or omits) it. */\nexport function forgetSelectValue(el: Element) {\n selectValues.delete(el);\n}\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 *\n * Returns false when the write did not take (see setSelectValue), which keeps\n * a reactive value from being cached until it does.\n */\nfunction setAttributeValue(\n el: Element,\n key: string,\n v: unknown,\n merge?: boolean,\n): boolean | 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') {\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 (className included)\n if (el instanceof Element && el.namespaceURI === SVG_NAMESPACE) {\n el.setAttribute(key === 'className' ? 'class' : key, String(v));\n } else if (key in el) {\n // For HTML elements, try to set as property first\n if (key === 'value' && el.localName === 'select') return setSelectValue(el as HTMLSelectElement, v);\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) {\n mergeReactiveClassName(el, 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) {\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 free of event-name normalization.\n if (k === \"onClick\") {\n setEventAttribute(el as HTMLElement, \"onclick\", raw as EventListener);\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 setEventAttribute(el as HTMLElement, k, raw as EventListener);\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') {\n initReactiveClassName(el as unknown as Element);\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 const node = el as unknown as Element;\n if (k === 'className' && hasReactiveClassName(node)) {\n // There's already a reactive className; update the tracked set and DOM atomically.\n const newClassName = String(raw || '');\n if (newClassName) {\n addStaticClasses(node, newClassName);\n mergeStaticClassName(node, newClassName);\n }\n return;\n }\n setAttributeValue(node, k, raw, shouldMergeClassName);\n}\n\nexport function applyAttributes<TTagName extends ElementTagName>(\n element: ExpandedElement<TTagName>,\n attributes: ExpandedElementAttributes<TTagName>,\n mergeClassName = true,\n) {\n // An <input>'s value is sanitized against its type/min/max/step as they\n // stand when it is written (a range input clamps it), so it is applied\n // after the object's other keys — `{ value: 150, max: 200 }` must not\n // clamp to the default max of 100.\n let valueLast = false;\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 if (k === 'value' && (element as unknown as Element).localName === 'input') {\n valueLast = true;\n continue;\n }\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 if (valueLast) {\n applySingleAttribute(\n element,\n 'value' as AttributeKey<TTagName>,\n (attributes as Record<string, unknown>).value as AttributeCandidate<TTagName> | undefined,\n );\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 { cleanupReactiveTextNode, 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\";\nimport { createMarker } from \"../shared/dom\";\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) {\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\t// The node may have been reactive in the previous build (the tree\n\t\t\t// shifted) — unregister it, or the next update() would overwrite\n\t\t\t// this static text with the stale resolver's value.\n\t\t\tconst force = isForceHydrating();\n\t\t\tif (force) {\n\t\t\t\tconst claimed = claimBareText(parentNode);\n\t\t\t\tif (claimed) {\n\t\t\t\t\tcleanupReactiveTextNode(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\tconst claimed = claimTextAfterMarker(parentNode, expected);\n\t\t\t\tif (force) cleanupReactiveTextNode(claimed);\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(createMarker(` text-${index} `));\n\tfragment.appendChild(textNode);\n\treturn fragment;\n}\n\n/** Resolver for text whose first evaluation threw: stays empty. */\nfunction emptyText() {\n\treturn \"\";\n}\n","import { clearBetweenMarkers, insertNodesBefore, withScopedInsertion } from \"../shared/dom\";\nimport type { UpdateScope } from \"../update/scope\";\nimport { applyNodeModifier } from \"../element/modifiers\";\nimport { getFactoryMods } from \"../element/factory-meta\";\nimport { mountQueueMark, cancelMountsSince } from \"../element/lifecycle\";\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) {\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 renderContentItems(contentToRender, host, index, 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) {\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) {\n for (const ref of activeWhenRuntimes) {\n const startMarker = ref.deref();\n\n // Comment node was garbage collected\n if (startMarker === undefined) {\n activeWhenRuntimes.delete(ref);\n continue;\n }\n\n const runtime = whenRuntimeByMarker.get(startMarker);\n if (!runtime) {\n activeWhenRuntimes.delete(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 activeWhenRuntimes.delete(ref);\n continue;\n }\n\n // Skip if outside update scope\n if (scope && !scope.contains(startMarker)) continue;\n\n const mark = mountQueueMark();\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 activeWhenRuntimes.delete(ref);\n // Content built but never inserted must not mount on the next flush.\n cancelMountsSince(mark);\n }\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: Node\n): Node | null {\n // Primitives, attribute objects, reactive text and tag-builder factories\n // (which build their element detached) never append to the host themselves:\n // the caller inserts whatever node comes back. Keeping them off the scoped\n // path matters — it adds and deletes an own `appendChild` on the host, which\n // drops the element out of the engine's fast property mode for good.\n if (!isFunction(item) || isZeroArityFunction(item) || getFactoryMods(item) !== undefined) {\n return applyNodeModifier(host, item, index);\n }\n\n // Other functions (nested when()/list() blocks, custom modifiers) may append\n // to the host: scope those appends so they land 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 before `endMarker` (any reference node in\n * the host — a region inserts ahead of its unclaimed server markup), in\n * source order.\n *\n * Each node is inserted as soon as its item produces it: nested when()/list()\n * blocks insert their own markers while they run, so collecting the element\n * nodes and inserting them afterwards would put every nested block ahead of\n * the siblings written before it.\n */\nexport function renderContentItems<TTagName extends ElementTagName>(\n items: ReadonlyArray<WhenContent<TTagName>>,\n host: ExpandedElement<TTagName>,\n index: number,\n endMarker: Node\n) {\n for (const item of items) {\n const node = renderContentItem(item, host, index, endMarker);\n if (node) insertNodesBefore([node], endMarker);\n }\n}\n","/**\n * Element creation: builds HTML/SVG elements and applies the modifier list\n * that was passed to a tag builder (children, attributes, text, on(), ...).\n */\nimport { applyNodeModifier, type NodeModifier } from \"./modifiers\";\nimport { forgetSelectValue, retrySelectValue } from \"./attributes\";\nimport { SVG_NAMESPACE } from \"../shared/dom\";\nimport { claimElement, claimChild, cleanupUnclaimedChildren, isHydrating, 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) {\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 hydrating = isHydrating();\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 // hydrate()/forceUpdate(): a fresh node (nothing to claim, or a\n // structural mismatch) lands at the claim cursor, keeping sibling\n // order — a plain append would put it after the cursor, where a later\n // sibling's claim would reach it. 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 (hydrating) {\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 * Clears state a claimed element carries from its previous build so\n * re-applying the current modifiers converges instead of accumulating.\n *\n * Every claim (hydrate() and forceUpdate()) rebuilds class state from scratch:\n * the existing class attribute is the output of className modifiers, and left\n * in place initReactiveClassName would capture it as static classes that a\n * dynamic className then adds to instead of replacing.\n *\n * forceUpdate() also detaches on() and event-attribute listeners (the re-applied modifiers\n * re-attach), drops reactive attribute resolvers (re-registered) and rebuilds\n * inline style. 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, force: boolean) {\n resetClassNameTracking(el);\n el.removeAttribute(\"class\");\n if (!force) return;\n removeAllListeners(el as HTMLElement);\n cleanupReactiveElement(el);\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) {\n resetReusedElement(claimed, isForceHydrating());\n if (tagName === \"select\") forgetSelectValue(claimed);\n }\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 // A select's value can only be applied once its options are in place.\n if (tagName === \"select\") retrySelectValue(el);\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","import { clearBetweenMarkers, safeRemoveChild } from \"../shared/dom\";\nimport { renderContentItems } from \"../when/runtime\";\nimport { isHydrating, peekChild, setCursor } from \"../hydration\";\nimport { isSerializing, serializingScratch } from \"../shared/serializing\";\nimport { applyModifiers } from \"../element/factory\";\nimport { isMounted, setNodeDisposer } from \"../element/lifecycle\";\nimport type { NodeModifier } from \"../element/modifiers\";\n\n/**\n * One into() placement. A view is a portal: its content lives between its\n * region's markers, and the view itself is a single `<!--view-N-->` anchor\n * comment standing where it was written. The anchor is what ties the content\n * to the view's own lifetime — when nuclo removes the anchor (its when()\n * closes, its list() row goes, its tree is replaced), the content leaves the\n * region with it, and a view whose region has not been built yet waits for\n * as long as its anchor is in the tree.\n */\nexport interface ViewRuntime {\n id: string;\n content: readonly WhenContent<ElementTagName>[];\n anchor: Comment;\n /**\n * The region showing this view; null while it waits for one. Held weakly,\n * like everything else that points into the DOM: a view outlives a region\n * wiped behind nuclo's back, and must not keep that layout in memory. A\n * region collected under a view leaves it orphaned until the next region\n * with its id takes it — see takeOrphans().\n */\n region: WeakRef<RegionRuntime<ElementTagName>> | null;\n /** Its entry in the waiting list, while it waits. */\n pendingRef: WeakRef<Comment> | null;\n /** Its entry in the placed list, while a region holds it. */\n placedRef?: WeakRef<Comment> | null;\n /**\n * First and last top-level node of its content between the region's\n * markers, both null when the content produced nothing. Top-level nodes are\n * stable: a nested list()/when() only ever changes what sits between its own\n * markers, so the range stays correct until the region or the view drops it.\n * Weak for the same reason as `region`.\n */\n first: WeakRef<Node> | null;\n last: WeakRef<Node> | null;\n}\n\n/**\n * A region is a named place in the tree; `into()` calls fill it from anywhere\n * else, in any order. The region owns a marker pair and every view's content\n * is inserted between them.\n */\nexport interface RegionRuntime<TTagName extends ElementTagName = ElementTagName> {\n id: string;\n type: RegionType;\n empty: readonly WhenContent<TTagName>[];\n startMarker: Comment;\n endMarker: Comment;\n host: ExpandedElement<TTagName>;\n index: number;\n /** The views it shows, in arrival order — one at most for \"latest\". */\n views: ViewRuntime[];\n /**\n * \"latest\" only: the views a newer one replaced, oldest first. They keep\n * their place so the one underneath shows again — rebuilt — when the view\n * on top leaves, which is what lets a layer open over a page in a latest\n * region and close without taking the page with it.\n */\n hidden: ViewRuntime[];\n /** True while the `empty` content occupies the markers. */\n showingEmpty: boolean;\n /**\n * Server markup between the markers that no into() has claimed yet, and the\n * cursor to claim it from. Null outside a hydration pass. The region's own\n * host cursor is parked past the end marker as usual — the host keeps\n * hydrating its later children — so claiming swaps this one in and out.\n */\n claimCursor: Node | null;\n claiming: boolean;\n /**\n * Views that arrived while one was being placed — a view's content placing\n * another view into the same region. Placed once the first is done, in\n * order, so neither's node range swallows the other's.\n */\n deferred: Array<[ViewRuntime, ViewRuntime | null]> | null;\n}\n\n/**\n * Regions are addressed by id, which has to survive until an into() looks it\n * up, but must not keep a detached layout alive. Same shape as the when()\n * registry: the id map holds only a WeakRef to the start marker (which the DOM\n * holds strongly while it is in the tree) and the runtime hangs off it in a\n * WeakMap, so dropping the subtree drops the runtime, its host and its\n * content. Views waiting for a region are kept the same way, by a WeakRef to\n * their anchor, and so are the views a region shows: a view holds its region\n * only weakly, so the placed list is how a region that takes the id over\n * finds the views of one that was collected.\n *\n * This registry belongs to one page. On a server the same module scope serves\n * every request and every user at once, so a server tree never touches it —\n * it gets one that lives and dies with the one renderToString() call, which\n * is also the only window in which its regions can be looked up.\n */\ninterface Registry {\n /** region id → start marker of the live region. */\n regions: Map<string, WeakRef<Comment>>;\n /** region id → anchors of the views waiting for it, in arrival order. */\n pending: Map<string, Set<WeakRef<Comment>>>;\n /** region id → anchors of the views a region with this id shows or hides, in arrival order. */\n placed: Map<string, Set<WeakRef<Comment>>>;\n}\n\nfunction emptyRegistry(): Registry {\n return { regions: new Map(), pending: new Map(), placed: new Map() };\n}\n\nconst page: Registry = emptyRegistry();\nconst runtimeByMarker = new WeakMap<Comment, RegionRuntime<ElementTagName>>();\nconst viewsByAnchor = new WeakMap<Comment, ViewRuntime[]>();\n\nconst SSR_KEY = \"region.registry\";\n\n/** The registry for whoever is asking: this page, or this request. */\nfunction registry(): Registry {\n if (!isSerializing()) return page;\n const scratch = serializingScratch();\n let reg = scratch.get(SSR_KEY) as Registry | undefined;\n if (!reg) scratch.set(SSR_KEY, (reg = emptyRegistry()));\n return reg;\n}\n\n/**\n * Prunes the page registry once a marker is collected — the case nuclo never\n * saw the removal (a container's innerHTML wiped). A region's entry goes by\n * id; a waiting view's entry is unregistered as soon as it is placed or its\n * anchor is removed, so only the wiped ones ever reach the callback.\n */\nconst markerFinalizer = typeof FinalizationRegistry !== \"undefined\"\n ? new FinalizationRegistry<{ id: string; ref: WeakRef<Comment>; waiting: boolean }>(({ id, ref, waiting }) => {\n if (waiting) forgetPending(page, id, ref);\n else if (page.regions.get(id) === ref) page.regions.delete(id);\n })\n : null;\n\n/** Regions holding unclaimed server markup, swept when the pass ends. */\nconst claimingRegions: Array<RegionRuntime<ElementTagName>> = [];\n\n/**\n * A marker nuclo once attached that is no longer in the document: its tree\n * was dropped behind nuclo's back (a container's innerHTML wiped), so nothing\n * disposed it. Until it is collected it would still answer lookups — a region\n * would take views meant for its replacement, and a view would render stale\n * content into a region built later. A marker that was never attached is a\n * tree still being built, which is detached by design. The same test every\n * other registry applies on update().\n */\nfunction dropped(marker: Comment) {\n return isMounted(marker) && !marker.isConnected;\n}\n\n/** Unregisters a region; its views go back to waiting for the next one with this id. */\nexport function dropRegion(rt: RegionRuntime<ElementTagName>) {\n runtimeByMarker.delete(rt.startMarker);\n const reg = registry();\n if (reg.regions.get(rt.id)?.deref() === rt.startMarker) reg.regions.delete(rt.id);\n const shown = [...rt.hidden, ...rt.views];\n rt.hidden.length = 0;\n rt.views.length = 0;\n for (const view of shown) {\n detach(view);\n // A view whose own tree was wiped along with the region has no one left\n // to wait for.\n if (!dropped(view.anchor)) pendView(view);\n }\n}\n\n/**\n * update()'s pass over the registry: a region or a into (waiting or shown) in\n * a tree that left the document behind nuclo's back is let go of now rather\n * than on its next lookup, so a live view does not keep a wiped layout alive,\n * and a wiped view neither stays in a live region nor waits for one.\n */\nexport function pruneRegions() {\n const reg = registry();\n for (const [id, waiting] of reg.pending) {\n for (const ref of waiting) {\n const anchor = ref.deref();\n if (anchor && !dropped(anchor)) continue;\n waiting.delete(ref);\n if (!isSerializing()) markerFinalizer?.unregister(ref);\n const view = anchor && viewsByAnchor.get(anchor)?.find((v) => v.pendingRef === ref);\n if (view) view.pendingRef = null;\n }\n if (waiting.size === 0) reg.pending.delete(id);\n }\n for (const [id, placed] of reg.placed) {\n for (const ref of placed) if (!ref.deref()) placed.delete(ref);\n if (placed.size === 0) reg.placed.delete(id);\n }\n for (const [id, ref] of reg.regions) {\n const marker = ref.deref();\n if (!marker) {\n reg.regions.delete(id);\n continue;\n }\n const rt = runtimeByMarker.get(marker);\n if (!rt) continue;\n if (dropped(marker)) {\n dropRegion(rt);\n continue;\n }\n for (const view of [...rt.hidden, ...rt.views]) if (dropped(view.anchor)) removeView(view);\n }\n}\n\nexport function registerRegion<TTagName extends ElementTagName>(runtime: RegionRuntime<TTagName>) {\n const rt = runtime as unknown as RegionRuntime<ElementTagName>;\n const reg = registry();\n const previous = reg.regions.get(rt.id)?.deref();\n // Two regions answering to the same id are fighting over the same views:\n // whichever registered last wins and the other stays empty forever. Only a\n // region already in the document is caught here — two written side by side\n // in one tree are both detached until render() inserts them, and nothing\n // distinguishes that from the ordinary case of a replaced tree re-using its\n // id.\n if (previous && previous !== rt.startMarker && previous.isConnected) {\n console.warn(\n `nuclo: two regions share the id \"${rt.id}\". Every into(\"${rt.id}\", …) now ` +\n \"goes to the one built last; the other stays empty. Give each region its own id.\",\n );\n } else if (previous && previous !== rt.startMarker && dropped(previous)) {\n // The id is being re-used by the replacement of a wiped tree: views that\n // were showing in the old region (from trees still alive) come over.\n const old = runtimeByMarker.get(previous);\n if (old) dropRegion(old);\n }\n const known = runtimeByMarker.has(rt.startMarker);\n const ref = new WeakRef(rt.startMarker);\n reg.regions.set(rt.id, ref);\n runtimeByMarker.set(rt.startMarker, rt);\n // The finalizer prunes the page-lifetime map only; the request-scoped one is\n // dropped wholesale when the render ends. A marker re-registered by a later\n // pass is already on the finalizer's books.\n if (!known && !isSerializing()) markerFinalizer?.register(rt.startMarker, { id: rt.id, ref, waiting: false });\n setNodeDisposer(rt.startMarker, onMarkerDisposed);\n if (rt.claiming) claimingRegions.push(rt);\n // The region takes the views that were waiting for it, in the order they\n // arrived — then those of an earlier region with this id that was collected\n // before nuclo saw it go, as update() would have handed them on.\n const waiting = reg.pending.get(rt.id);\n if (waiting) {\n reg.pending.delete(rt.id);\n for (const anchorRef of waiting) {\n if (!isSerializing()) markerFinalizer?.unregister(anchorRef);\n const view = waitingView(anchorRef, rt.id);\n if (!view) continue;\n view.pendingRef = null;\n addView(rt, view, null);\n }\n }\n for (const view of takeOrphans(reg, rt.id)) addView(rt, view, null);\n}\n\n/**\n * The views whose region with this id was collected — a layout wiped behind\n * nuclo's back with no update() since — in arrival order, taken off the\n * placed list. Views wiped along with it are left behind.\n */\nfunction takeOrphans(reg: Registry, id: string): ViewRuntime[] {\n const placed = reg.placed.get(id);\n if (!placed) return [];\n const orphans: ViewRuntime[] = [];\n for (const ref of placed) {\n const anchor = ref.deref();\n const view = anchor && viewsByAnchor.get(anchor)?.find((v) => v.placedRef === ref);\n if (view && regionOf(view)) continue;\n placed.delete(ref);\n if (!view) continue;\n detach(view);\n if (!dropped(view.anchor)) orphans.push(view);\n }\n if (placed.size === 0) reg.placed.delete(id);\n return orphans;\n}\n\n/**\n * True for the anchor comment an into() left where it was written. list()\n * accepts one as a row, which is what lets a page place itself: the row is\n * the anchor, and the row leaving the list takes the content out of the region.\n */\nexport function isViewAnchor(node: Node) {\n return node.nodeType === 8 && viewsByAnchor.has(node as Comment);\n}\n\n\n/** The live region registered under an id, if one is still in the tree. */\nexport function getRegion(id: string): RegionRuntime<ElementTagName> | undefined {\n const reg = registry();\n const marker = reg.regions.get(id)?.deref();\n if (!marker) {\n reg.regions.delete(id);\n return undefined;\n }\n const rt = runtimeByMarker.get(marker);\n if (rt && dropped(marker)) {\n dropRegion(rt);\n return undefined;\n }\n return rt;\n}\n\n/**\n * The region already live on a claimed marker pair — a forceUpdate() pass, or\n * hydrate() over a tree that is live already. Its runtime and views are kept;\n * each into() re-running in the pass then reclaims its own content in place.\n */\nexport function liveRegionAt(start: Comment, end: Comment): RegionRuntime<ElementTagName> | undefined {\n const rt = runtimeByMarker.get(start);\n return rt && rt.endMarker === end ? rt : undefined;\n}\n\n/** How many views are waiting for a region with this id (for tests). */\nexport function pendingViewCount(id: string) {\n return registry().pending.get(id)?.size ?? 0;\n}\n\n/** The still-waiting view behind a pending entry, or nothing once its anchor is gone or it was placed. */\nfunction waitingView(ref: WeakRef<Comment>, id: string): ViewRuntime | undefined {\n const anchor = ref.deref();\n if (!anchor || dropped(anchor)) return undefined;\n return viewsByAnchor.get(anchor)?.find((v) => v.id === id && v.region === null);\n}\n\nfunction forgetPending(reg: Registry, id: string, ref: WeakRef<Comment>) {\n const waiting = reg.pending.get(id);\n if (!waiting) return;\n waiting.delete(ref);\n if (waiting.size === 0) reg.pending.delete(id);\n}\n\n/** Queues a view for a region that does not exist yet. */\nfunction pendView(view: ViewRuntime) {\n if (view.pendingRef) return;\n const reg = registry();\n let waiting = reg.pending.get(view.id);\n if (!waiting) reg.pending.set(view.id, (waiting = new Set()));\n const ref = new WeakRef(view.anchor);\n view.pendingRef = ref;\n waiting.add(ref);\n // The ref is its own unregister token: one registration per entry.\n if (!isSerializing()) markerFinalizer?.register(view.anchor, { id: view.id, ref, waiting: true }, ref);\n}\n\n/** Takes a view off the waiting list. */\nfunction unpend(view: ViewRuntime) {\n const ref = view.pendingRef;\n if (!ref) return;\n view.pendingRef = null;\n forgetPending(registry(), view.id, ref);\n if (!isSerializing()) markerFinalizer?.unregister(ref);\n}\n\n/**\n * Ties the views written at one anchor to it and places each in its region —\n * or, for a region not built yet, leaves it waiting. During hydration the\n * anchor may be one claimed from a live tree, whose earlier views are then\n * replaced: a view still shown by its region reclaims that content in place,\n * and one still waiting keeps its place in the waiting list.\n */\nexport function attachViews(anchor: Comment, views: ViewRuntime[]) {\n const earlier = viewsByAnchor.get(anchor);\n for (const old of earlier ?? []) {\n if (!views.some((view) => view.id === old.id)) removeView(old);\n }\n viewsByAnchor.set(anchor, views);\n setNodeDisposer(anchor, onMarkerDisposed);\n for (const view of views) {\n const before = earlier?.find((v) => v.id === view.id) ?? null;\n if (before) {\n view.pendingRef = before.pendingRef;\n before.pendingRef = null;\n }\n const rt = getRegion(view.id);\n if (rt) {\n unpend(view);\n addView(rt, view, before);\n } else {\n pendView(view);\n }\n }\n}\n\n/** `region-start-{index}-v{views}`, so hydration knows what the server left. */\nfunction stamp(rt: RegionRuntime<ElementTagName>) {\n rt.startMarker.textContent = `region-start-${rt.index}-v${rt.views.length}`;\n}\n\n/** Reads the view count out of an SSR start marker. */\nexport function decodeCount(markerText: string | null) {\n const match = /-v(\\d+)$/.exec(markerText || \"\");\n return match ? parseInt(match[1], 10) : 0;\n}\n\n/** The region showing a view: null while it waits, and once its region was collected. */\nfunction regionOf(view: ViewRuntime): RegionRuntime<ElementTagName> | null {\n return view.region?.deref() ?? null;\n}\n\n/**\n * Records that `rt` shows `view`. A view taking over from `earlier` on the\n * same anchor (a pass re-running a live tree) takes over its placed entry too,\n * and with it its place in arrival order.\n */\nfunction showIn(view: ViewRuntime, rt: RegionRuntime<ElementTagName>, earlier: ViewRuntime | null = null) {\n view.region = new WeakRef(rt);\n if (earlier?.placedRef) {\n view.placedRef = earlier.placedRef;\n earlier.placedRef = null;\n }\n if (view.placedRef) return;\n const reg = registry();\n let placed = reg.placed.get(view.id);\n if (!placed) reg.placed.set(view.id, (placed = new Set()));\n view.placedRef = new WeakRef(view.anchor);\n placed.add(view.placedRef);\n}\n\nfunction detach(view: ViewRuntime) {\n view.region = null;\n view.first = null;\n view.last = null;\n const ref = view.placedRef;\n if (!ref) return;\n view.placedRef = null;\n const reg = registry();\n const placed = reg.placed.get(view.id);\n if (!placed) return;\n placed.delete(ref);\n if (placed.size === 0) reg.placed.delete(view.id);\n}\n\n/** Records which nodes a view just produced: everything between `before` and `stop`. */\nfunction setRange(view: ViewRuntime, before: Node, stop: Node) {\n const first = before.nextSibling;\n view.first = first === stop || !first ? null : new WeakRef(first);\n view.last = view.first ? new WeakRef(stop.previousSibling!) : null;\n}\n\n/** Puts the region back to its `empty` content, replacing whatever it holds. */\nexport function showEmpty<TTagName extends ElementTagName>(runtime: RegionRuntime<TTagName>) {\n const rt = runtime as unknown as RegionRuntime<ElementTagName>;\n clearBetweenMarkers(rt.startMarker, rt.endMarker);\n for (const view of rt.views) detach(view);\n for (const view of rt.hidden) detach(view);\n rt.views.length = 0;\n rt.hidden.length = 0;\n rt.showingEmpty = true;\n if (rt.empty.length) renderContentItems(rt.empty, rt.host, rt.index, rt.endMarker);\n stamp(rt);\n}\n\n/**\n * Adds one into()'s content to a region.\n *\n * \"stack\" keeps every view, bottom first — the view that arrives second opens\n * over the first without touching it, so the content underneath keeps its DOM,\n * its focus and its form state. \"latest\" keeps only the newest.\n *\n * `earlier` is the view this one replaces on the same anchor (a hydration pass\n * re-running a live tree): if the region still shows it, the new view takes\n * over its place and claims its nodes.\n */\nfunction addView(\n rt: RegionRuntime<ElementTagName>,\n view: ViewRuntime,\n earlier: ViewRuntime | null,\n) {\n // Arrived from inside the content being placed right now: its turn comes\n // once that content is complete, so the two node ranges stay separate.\n if (rt.deferred) {\n rt.deferred.push([view, earlier]);\n return;\n }\n rt.deferred = [];\n try {\n placeView(rt, view, earlier);\n } finally {\n const next = rt.deferred;\n rt.deferred = null;\n for (const [v, e] of next) addView(rt, v, e);\n }\n}\n\nfunction placeView(rt: RegionRuntime<ElementTagName>, view: ViewRuntime, earlier: ViewRuntime | null) {\n if (earlier && regionOf(earlier) === rt) {\n // A view underneath a newer one keeps its place there, still unseen.\n const h = rt.hidden.indexOf(earlier);\n if (h !== -1) {\n rt.hidden[h] = view;\n showIn(view, rt, earlier);\n earlier.region = null;\n return;\n }\n reclaimView(rt, view, earlier);\n return;\n }\n if (rt.showingEmpty || (rt.type === \"latest\" && rt.views.length > 0)) {\n // Clearing throws away the server markup along with everything else, so it\n // also ends any claim in progress: the rest of this region renders fresh.\n clearBetweenMarkers(rt.startMarker, rt.endMarker);\n // A latest region shows only the newest, but the one it replaces is not\n // gone: it comes back when the newer view leaves.\n for (const old of rt.views) {\n old.first = null;\n old.last = null;\n rt.hidden.push(old);\n }\n rt.views.length = 0;\n rt.showingEmpty = false;\n rt.claiming = false;\n rt.claimCursor = null;\n }\n rt.views.push(view);\n showIn(view, rt);\n if (isHydrating() && rt.claiming) {\n const { before, cursor } = claimAt(rt, view.content);\n setRange(view, before, cursor);\n } else {\n // A view built fresh while the region is still claiming (a when() branch\n // the server did not render) goes in ahead of the unclaimed server\n // markup, or the sweep would take it for leftovers.\n const at = rt.claiming && rt.claimCursor ? rt.claimCursor : rt.endMarker;\n const before = at.previousSibling!;\n renderContentItems(view.content, rt.host, rt.index, at);\n setRange(view, before, at);\n }\n stamp(rt);\n}\n\n/**\n * Claims the region's unclaimed server markup for `content`, advancing the\n * claim cursor past it. Nothing is removed: what follows may belong to a view\n * that has not run yet, so leftovers are judged by the sweep.\n *\n * applyModifiers rather than a bare render: a node the content could not claim\n * is inserted at the claim cursor instead of dropped, exactly as when() does\n * for a branch it is re-running over SSR output.\n */\nfunction claimAt(\n rt: RegionRuntime<ElementTagName>,\n content: readonly WhenContent<ElementTagName>[],\n): { before: Node; cursor: Node } {\n const parent = rt.host as unknown as Node;\n const hostCursor = peekChild(parent);\n const from = rt.claimCursor ?? rt.endMarker;\n const before = from.previousSibling!;\n setCursor(parent, from);\n for (const item of content) applyModifiers(rt.host, [item as NodeModifier<ElementTagName>], rt.index);\n const cursor = peekChild(parent) ?? rt.endMarker;\n rt.claimCursor = cursor;\n setCursor(parent, hostCursor);\n return { before, cursor };\n}\n\n/**\n * Re-runs `content` over the nodes from `from` up to `stop` (exclusive),\n * claiming what matches and dropping the rest. Returns the node before the\n * range, for setRange().\n */\nfunction claimRange(\n rt: RegionRuntime<ElementTagName>,\n content: readonly WhenContent<ElementTagName>[],\n from: Node,\n stop: Node,\n): Node {\n const parent = rt.host as unknown as Node;\n const hostCursor = peekChild(parent);\n const before = from.previousSibling!;\n // A non-claimable boundary keeps growing content from consuming the next view.\n const boundary = document.createComment(\"region-claim-boundary\");\n parent.insertBefore(boundary, stop);\n setCursor(parent, from === stop ? boundary : from);\n try {\n for (const item of content) applyModifiers(rt.host, [item as NodeModifier<ElementTagName>], rt.index);\n let leftover = peekChild(parent);\n while (leftover && leftover !== boundary) {\n const next: Node | null = leftover.nextSibling;\n safeRemoveChild(leftover);\n leftover = next;\n }\n } finally {\n parent.removeChild(boundary);\n setCursor(parent, hostCursor);\n }\n return before;\n}\n\n/** The node right after a view's content: the next view's first node, or the end marker. */\nfunction boundaryAfter(rt: RegionRuntime<ElementTagName>, view: ViewRuntime): Node {\n const last = view.last?.deref();\n if (last) return last.nextSibling ?? rt.endMarker;\n for (let i = rt.views.indexOf(view) + 1; i < rt.views.length; i++) {\n const first = rt.views[i].first?.deref();\n if (first) return first;\n }\n return rt.endMarker;\n}\n\n/** A view re-running over its own earlier content takes its place and claims its nodes. */\nfunction reclaimView(rt: RegionRuntime<ElementTagName>, view: ViewRuntime, earlier: ViewRuntime) {\n const stop = boundaryAfter(rt, earlier);\n const before = claimRange(rt, view.content, earlier.first?.deref() ?? stop, stop);\n rt.views[rt.views.indexOf(earlier)] = view;\n showIn(view, rt, earlier);\n detach(earlier);\n setRange(view, before, stop);\n stamp(rt);\n}\n\n/**\n * Claims the server's `empty` content in place, for a region that had no views\n * on either side. Leaves the region claiming, so the sweep still drops\n * anything the empty content did not account for.\n */\nexport function claimEmpty<TTagName extends ElementTagName>(runtime: RegionRuntime<TTagName>) {\n const rt = runtime as unknown as RegionRuntime<ElementTagName>;\n if (rt.empty.length) claimAt(rt, rt.empty);\n rt.showingEmpty = true;\n}\n\n/** Re-claims a live region's `empty` content in place (a pass re-running a live tree). */\nexport function reclaimEmpty(rt: RegionRuntime<ElementTagName>) {\n claimRange(rt, rt.empty, rt.startMarker.nextSibling ?? rt.endMarker, rt.endMarker);\n}\n\n/** Takes a view's content out of its region; the region falls back to `empty` when none is left. */\nfunction removeView(view: ViewRuntime) {\n unpend(view);\n const rt = regionOf(view);\n if (!rt) {\n // Waiting, or orphaned by a collected region: nothing left to take out.\n detach(view);\n return;\n }\n const h = rt.hidden.indexOf(view);\n if (h !== -1) {\n rt.hidden.splice(h, 1);\n detach(view);\n return;\n }\n const i = rt.views.indexOf(view);\n if (i !== -1) {\n rt.views.splice(i, 1);\n const last = view.last?.deref();\n const stop = last ? last.nextSibling : null;\n let node = view.first?.deref() ?? null;\n while (node && node !== stop) {\n const next: Node | null = node.nextSibling;\n safeRemoveChild(node);\n node = next;\n }\n }\n detach(view);\n if (i === -1) return;\n if (rt.views.length > 0 || rt.claiming) {\n // Mid-hydration the sweep decides, once it knows which views stayed.\n stamp(rt);\n return;\n }\n // The view underneath shows again, rebuilt; with none left, `empty` does.\n const underneath = rt.hidden.pop();\n if (underneath) addView(rt, underneath, null);\n else showEmpty(rt);\n}\n\n/**\n * nuclo removed a marker node of ours. A view's anchor takes its content out\n * of the region. A region's start marker unregisters the region and puts its\n * views back to waiting, in order, so a region that returns under the same id\n * (a layout switched off and on) shows them again.\n */\nfunction onMarkerDisposed(node: Node) {\n const anchor = node as Comment;\n const views = viewsByAnchor.get(anchor);\n if (views) {\n viewsByAnchor.delete(anchor);\n for (const view of views) removeView(view);\n return;\n }\n const rt = runtimeByMarker.get(anchor);\n if (rt) dropRegion(rt);\n}\n\n/**\n * Drops server markup no into() claimed, once the hydration pass is over.\n *\n * Nothing announces \"this region has all its views now\" mid-pass, so the\n * leftovers can only be judged at the end: a client that renders fewer views\n * than the server did leaves the tail of the region unclaimed.\n */\nexport function sweepRegions() {\n for (const rt of claimingRegions) {\n // A region torn down mid-pass (inside a when() branch the client did not\n // keep) is no longer the one under its marker; nothing of it is settled.\n if (rt.claiming && runtimeByMarker.get(rt.startMarker) === rt) {\n let leftover = rt.claimCursor;\n while (leftover && leftover !== rt.endMarker) {\n const next: Node | null = leftover.nextSibling;\n safeRemoveChild(leftover);\n leftover = next;\n }\n // A region the client left with no views at all falls back to `empty`.\n if (rt.views.length === 0 && !rt.showingEmpty) showEmpty(rt);\n }\n rt.claiming = false;\n rt.claimCursor = null;\n }\n claimingRegions.length = 0;\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, clearBetweenMarkers, safeRemoveChild, cleanupNodeTree } from \"../shared/dom\";\nimport { isHydrating, isSerializing, claimMarkerPair, peekChild, setCursor, runFreshAtCursor } 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 { mountQueueMark, cancelMountsSince } from \"../element/lifecycle\";\nimport { isViewAnchor } from \"../region/runtime\";\n\nfunction arraysEqual<T>(a: readonly T[], b: readonly T[]) {\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>) {\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 node. A into() is a row\n * too: its anchor stands in the list and its content lives in the region, so\n * the row leaving the list takes the content with it. Anything else (null,\n * primitives, attribute objects, other 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 if (value === null || typeof value !== \"object\") return null;\n return \"tagName\" in value || isViewAnchor(value as Node) ? (value as ExpandedElement<TTagName>) : 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 * Cleans every row before detaching it. Weak bookkeeping permits collection,\n * but retained DOM nodes must stop invoking removed views' event handlers.\n * Keep the native bulk removal below to avoid Range's quadratic DOM walk.\n * Returns false without mutation when the markers no longer share a parent.\n */\nfunction bulkClearRecords<TItem, TTagName extends ElementTagName>(\n records: ReadonlyArray<ListItemRecord<TItem, TTagName>>,\n parent: Node & ParentNode,\n startMarker: Comment,\n endMarker: Comment,\n) {\n if (startMarker.parentNode !== parent || endMarker.parentNode !== parent) return false;\n\n for (let i = 0; i < records.length; i++) {\n const node = records[i].element as unknown as Node | null;\n if (node) cleanupNodeTree(node);\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) {\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\n/**\n * The single-choice <select> whose options a list renders: its direct parent,\n * or an <optgroup>'s parent. (A `multiple` select has no one value to keep.)\n */\nfunction selectOwning(parent: Node | null): HTMLSelectElement | null {\n if (!parent) return null;\n const node = parent.nodeName === \"OPTGROUP\" ? parent.parentNode : parent;\n return node && node.nodeName === \"SELECT\" && !(node as HTMLSelectElement).multiple ? node as HTMLSelectElement : null;\n}\n\nexport function sync<TItem, TTagName extends ElementTagName>(\n runtime: ListRuntime<TItem, TTagName>\n) {\n const items = normalizeItems(runtime.itemsProvider());\n\n if (arraysEqual(runtime.lastSyncedItems, items)) return;\n\n // Removing, moving or rebuilding <option>s makes the browser re-pick the\n // selection — rows rebuilt from refetched data, or a plain reorder, would\n // silently change what a <select> shows. Keep it on the value it had.\n const select = isBrowser ? selectOwning(runtime.startMarker.parentNode) : null;\n const selectedValue = select && select.selectedIndex >= 0 ? select.value : null;\n\n const mark = mountQueueMark();\n try {\n diffRows(runtime, items);\n if (selectedValue !== null && select!.value !== selectedValue) {\n const fallback = select!.selectedIndex;\n select!.value = selectedValue;\n // No option carries that value any more: keep the browser's pick.\n if (select!.value !== selectedValue) select!.selectedIndex = fallback;\n }\n } catch (error) {\n // A render function threw mid-diff: rows may already be removed, moved or\n // recorded without being inserted, so the records no longer mirror the\n // DOM. Reset to an empty list — the next sync rebuilds it from scratch\n // instead of diffing against a state that does not exist.\n const { startMarker, endMarker } = runtime;\n if (startMarker.parentNode && startMarker.parentNode === endMarker.parentNode) {\n clearBetweenMarkers(startMarker, endMarker);\n }\n runtime.records = [];\n runtime.lastSyncedItems = [];\n runtime.allRecordsCreatedAt = undefined;\n // Rows built but never inserted must not mount on a later flush.\n cancelMountsSince(mark);\n throw error;\n }\n}\n\nfunction diffRows<TItem, TTagName extends ElementTagName>(\n runtime: ListRuntime<TItem, TTagName>,\n items: readonly TItem[],\n) {\n const { startMarker, endMarker } = runtime;\n const parent = (startMarker.parentNode ?? (runtime.host as unknown as Node & ParentNode)) as\n Node & ParentNode;\n\n const oldRecords = runtime.records;\n const oldLen = oldRecords.length;\n const newLen = items.length;\n\n // Fast path — clear: clean the rows before the native bulk removal.\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 runFreshAtCursor(parentNode, () => 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) {\n updateListFlushEpoch++;\n\n for (const ref of activeListRuntimes) {\n const startMarker = ref.deref();\n\n // Marker was garbage collected\n if (!startMarker) {\n activeListRuntimes.delete(ref);\n continue;\n }\n\n const runtime = listRuntimeByMarker.get(startMarker);\n if (!runtime) {\n activeListRuntimes.delete(ref);\n continue;\n }\n\n // Clean up if disconnected from DOM\n if (!startMarker.isConnected || !runtime.endMarker.isConnected) {\n listRuntimeByMarker.delete(startMarker);\n activeListRuntimes.delete(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","import { createMarkerPair, clearBetweenMarkers, safeRemoveChild } 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, peekChild, setCursor, runWithoutHydration, runFreshAtCursor } from \"../hydration\";\nimport { applyModifiers } from \"../element/factory\";\nimport type { NodeModifier } 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) {\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 runFreshAtCursor(parentNode, () => 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 // applyModifiers (not a bare applyNodeModifier): a node that could\n // not be claimed is inserted at the claim cursor instead of dropped.\n // One call per item — every branch item shares the block's `index`,\n // as in renderContentItems.\n for (const item of contentToRender) {\n applyModifiers(host, [item as NodeModifier<TTagName>], index);\n }\n }\n // Remove the SSR nodes the branch did not claim (same as list()).\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 } 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 runWithoutHydration(() => renderContentItems(contentToRender, host, index, endMarker));\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 (read once) or functions that are re-evaluated\n * on every update().\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 * let isLoggedIn = false;\n *\n * div(\n * when(() => isLoggedIn,\n * span('Welcome back!')\n * )\n * .else(\n * button('Login', { onClick: () => { isLoggedIn = true; update(); } })\n * )\n * )\n * ```\n *\n * @example\n * ```ts\n * // Multiple conditions\n * let status: 'loading' | 'error' | 'ready' = 'loading';\n *\n * div(\n * when(() => status === 'loading',\n * p('Loading…')\n * )\n * .when(() => status === 'error',\n * p('Something went wrong')\n * )\n * .else(\n * p('Ready')\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 */\nexport const scopeRootsById = new Map<ScopeId, Set<WeakRef<Element>>>();\n\n/**\n * Drops a collected root's entry — and its id, once no root is left under it.\n * Without this, per-row ids (scope(`row-${id}`)) that are never passed to\n * update() again would stay in the map forever: one id, one Set and one dead\n * WeakRef per row the app ever rendered. The sweeps below only bound a single\n * id's set, not the number of ids.\n */\nconst scopeRootFinalizer = typeof FinalizationRegistry !== \"undefined\"\n ? new FinalizationRegistry<{ id: ScopeId; ref: WeakRef<Element> }>(({ id, ref }) => {\n const set = scopeRootsById.get(id);\n if (set?.delete(ref) && set.size === 0) scopeRootsById.delete(id);\n })\n : null;\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\n/** Ids each root is already registered under: O(1) dedup instead of a set scan. */\nconst idsByRoot = new WeakMap<Element, Set<ScopeId>>();\n/** Sweep a set of dead refs once it grows past this; doubles with the live size. */\nconst sweepAt = new WeakMap<Set<WeakRef<Element>>, number>();\nconst MIN_SWEEP = 64;\n\nfunction addScopeRoot(id: ScopeId, el: Element) {\n let ids = idsByRoot.get(el);\n if (!ids) idsByRoot.set(el, ids = new Set());\n // Re-registration (forceUpdate() reclaim) must not grow the set.\n if (ids.has(id)) return;\n ids.add(id);\n\n let set = scopeRootsById.get(id);\n if (!set) scopeRootsById.set(id, set = new Set());\n const ref = new WeakRef(el);\n set.add(ref);\n scopeRootFinalizer?.register(el, { id, ref });\n\n // Ids that are never passed to update(id) are never pruned by getScopeRoots(),\n // so list rows scoped with scope(\"row\") would grow the set forever. Sweep\n // collected refs at amortized O(1) per add. Detached roots are kept: they\n // are legitimately unattached while their tree is still being built.\n if (set.size >= (sweepAt.get(set) ?? MIN_SWEEP)) {\n for (const ref of set) if (ref.deref() === undefined) set.delete(ref);\n sweepAt.set(set, Math.max(MIN_SWEEP, set.size * 2));\n }\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 for (const ref of set) {\n const el = ref.deref();\n // Collected or disconnected: drop it (deleting while iterating a Set is safe).\n if (el === undefined) set.delete(ref);\n else if (!el.isConnected) {\n set.delete(ref);\n idsByRoot.get(el)?.delete(id); // let scope() re-register it if it comes back\n } else roots.add(el);\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>) {\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 { pruneRegions } from \"../region/runtime\";\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\t// First: a region or view whose tree left the document behind nuclo's back\n\t// is let go of before any when()/list() content runs and looks regions up.\n\tpruneRegions,\n\tupdateListRuntimes,\n\tupdateWhenRuntimes,\n\tnotifyReactiveElements,\n\tnotifyReactiveTextNodes,\n] satisfies ReadonlyArray<(scope?: UpdateScope) => void>;\n\nexport function update(...scopeIds: string[]) {\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 { createMarker, createMarkerPair } from \"../shared/dom\";\nimport {\n claimChild,\n claimMarkerPair,\n isHydrating,\n peekChild,\n runFreshAtCursor,\n runWithoutHydration,\n setCursor,\n skipWhitespaceText,\n} from \"../hydration\";\nimport type { RegionRuntime, ViewRuntime } from \"./runtime\";\nimport {\n attachViews,\n claimEmpty,\n decodeCount,\n dropRegion,\n liveRegionAt,\n reclaimEmpty,\n registerRegion,\n showEmpty,\n} from \"./runtime\";\n\nexport { sweepRegions } from \"./runtime\";\n\nfunction makeRuntime(\n options: RegionOptions,\n host: ExpandedElement<ElementTagName>,\n index: number,\n startMarker: Comment,\n endMarker: Comment,\n): RegionRuntime<ElementTagName> {\n const empty = options.empty === undefined ? [] : [options.empty];\n return {\n id: options.id,\n type: options.type ?? \"latest\",\n empty,\n startMarker,\n endMarker,\n host,\n index,\n views: [],\n hidden: [],\n showingEmpty: false,\n claimCursor: null,\n claiming: false,\n deferred: null,\n };\n}\n\nfunction freshRegion(\n options: RegionOptions,\n host: ExpandedElement<ElementTagName>,\n index: number,\n): Comment {\n const { start, end } = createMarkerPair(\"region\", index);\n const parent = host as unknown as Node & ParentNode;\n parent.appendChild(start);\n parent.appendChild(end);\n\n const runtime = makeRuntime(options, host, index, start, end);\n // `empty` first: registering drains the views that were waiting for this\n // id, and the first of them replaces it.\n showEmpty(runtime);\n registerRegion(runtime);\n return start;\n}\n\nfunction hydrateRegion(\n options: RegionOptions,\n host: ExpandedElement<ElementTagName>,\n index: number,\n): Comment {\n const parent = host as unknown as Node & ParentNode;\n\n // No region markers at the cursor (SSR output from something else): build\n // the region from scratch, as when() and list() do.\n const pair = claimMarkerPair(parent, \"region\");\n if (!pair) return runFreshAtCursor(parent, () => freshRegion(options, host, index));\n const { start, end } = pair;\n\n // The host carries on hydrating its own later children past the region. The\n // region's content is claimed through a cursor of its own, because the\n // into() that claims it runs somewhere else entirely in the tree.\n setCursor(parent, end.nextSibling);\n\n // A region already live on these markers — forceUpdate(), or hydrate() over\n // a tree that is live — keeps its runtime and its views: every into() that\n // re-runs in this pass reclaims its own content in place, so nothing here\n // can tell a view in another root from server leftovers and nothing is\n // swept. Only the options are taken fresh.\n const live = liveRegionAt(start, end);\n if (live && (live.id !== options.id || live.type !== (options.type ?? \"latest\"))) {\n dropRegion(live);\n const runtime = makeRuntime(options, host, index, start, end);\n runWithoutHydration(() => {\n showEmpty(runtime);\n registerRegion(runtime);\n });\n return start;\n }\n if (live) {\n live.type = options.type ?? \"latest\";\n live.empty = options.empty === undefined ? [] : [options.empty];\n live.host = host;\n live.index = index;\n if (live.showingEmpty) reclaimEmpty(live);\n return start;\n }\n\n const runtime = makeRuntime(options, host, index, start, end);\n if (pair.recreated) {\n showEmpty(runtime);\n registerRegion(runtime);\n return start;\n }\n\n runtime.claiming = true;\n runtime.claimCursor = start.nextSibling;\n // `-v0` means the server had no views either and what sits between the\n // markers is the `empty` content — claim it rather than rebuild it. Before\n // registering: the views waiting for this id replace it, as they would have\n // on the server had they existed there.\n if (decodeCount(start.textContent) === 0) claimEmpty(runtime);\n registerRegion(runtime);\n return start;\n}\n\n/**\n * Marks a named place in the tree for `into()` to fill.\n *\n * A region decouples *where* content appears from *who* builds it: the layout\n * says `region({ id: \"main\" })` and anything, at any depth, can put content\n * there with `into(\"main\", …)` — no props threaded through every component in\n * between.\n *\n * `type` decides what happens when a region holds more than one view:\n * `\"stack\"` renders all of them, in arrival order, and `\"latest\"` (the\n * default) renders only the newest.\n *\n * Order does not matter: a view written before its region, or rendered into\n * a different root earlier, waits and shows up the moment the region is\n * built. A region that goes away (its when() closes) hands its views back to\n * waiting, so a region that returns under the same id shows them again.\n *\n * @example\n * ```ts\n * div(\n * region({\n * id: \"main\",\n * type: \"stack\",\n * empty: div(\"Nothing open.\"),\n * }),\n * )\n *\n * // anywhere else, at any depth, before or after\n * into(\"main\", h1(\"Hello from the main region\"))\n * ```\n */\nexport function region(options: RegionOptions): MarkerModifier {\n return function (host: ExpandedElement<ElementTagName>, index: number) {\n return isHydrating() ? hydrateRegion(options, host, index) : freshRegion(options, host, index);\n };\n}\n\n/** Claims the `<!--view-N-->` anchor the server left at the cursor, if any. */\nfunction claimAnchor(parent: Node): Comment | null {\n skipWhitespaceText(parent);\n const next = peekChild(parent);\n if (!next || next.nodeType !== 8 || !next.textContent?.startsWith(\"view-\")) return null;\n claimChild(parent);\n return next as Comment;\n}\n\n/**\n * Renders content into the `region()` with a matching id, wherever that region\n * sits in the tree.\n *\n * `into()` is a portal: where it is written it leaves only an anchor comment,\n * so a component can declare where its own output belongs instead of being\n * handed down to the right place. A page loaded by a router is the usual case\n * — it returns an `into()` and lands in the app's layout without the layout,\n * or the app, knowing anything about it.\n *\n * The content lives exactly as long as the view does: when the `when()` that\n * holds the view closes, or its `list()` row goes, the content leaves the\n * region too. A view whose region is not built yet waits for it.\n *\n * Pass one id, or an object to fill several regions at once. Either form\n * nests: an `into()` inside another view's content targets its own region.\n *\n * @example\n * ```ts\n * // one region\n * into(\"main\", div(h1(\"Eager route\")))\n *\n * // several at once\n * into({\n * main: div(h1(\"Eager route\")),\n * sidebar: div(\"Related links\"),\n * })\n * ```\n */\nexport function into(id: string, ...content: WhenContent[]): MarkerModifier;\nexport function into(\n regions: Readonly<Record<string, WhenContent | readonly WhenContent[]>>,\n): MarkerModifier;\nexport function into(\n idOrRegions: string | Readonly<Record<string, unknown>>,\n ...content: WhenContent[]\n): MarkerModifier {\n const targets: Array<[string, readonly WhenContent<ElementTagName>[]]> =\n typeof idOrRegions === \"string\"\n ? [[idOrRegions, content]]\n : Object.entries(idOrRegions).map(([id, value]) => [\n id,\n (Array.isArray(value) ? value : [value]) as readonly WhenContent<ElementTagName>[],\n ]);\n\n return function (host: ExpandedElement<ElementTagName>, index: number) {\n const parent = host as unknown as Node & ParentNode;\n const anchor = (isHydrating() && claimAnchor(parent)) || createMarker(`view-${index}`);\n const views: ViewRuntime[] = targets.map(([id, items]) => ({\n id,\n content: items,\n anchor,\n region: null,\n pendingRef: null,\n first: null,\n last: null,\n }));\n attachViews(anchor, views);\n return anchor;\n };\n}\n","import { startHydration, endHydration, peekChild, setCursor, skipWhitespaceText } from \"./hydration\";\nimport { sweepRegions } from \"./region\";\nimport { safeRemoveChild } from \"./shared/dom\";\nimport { flushMountQueue, mountQueueMark, cancelMountsSince } 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}\n\n/**\n * Iteration holds only weak roots; component closures live under their DOM\n * root in a WeakMap so a closure capturing its own root is collectible too.\n */\nconst forcedComponents = new WeakMap<Element, { component: Component<ElementTagName> }>();\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) {\n if (!component || !isBrowser) return;\n if (!element || (element as Node).nodeType !== 1) return;\n const root = element as Element;\n const existing = forcedComponents.get(root);\n if (existing) {\n existing.component = component;\n return;\n }\n const entry: ForcedRoot = { root: new WeakRef(root) };\n forcedComponents.set(root, { 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(\n nodeModFn: MarkerModifier | (() => MarkerModifier),\n parent?: Element,\n index?: number,\n): Comment;\nexport function render<TTagName extends ElementTagName = ElementTagName>(\n nodeModFn: NodeModFn<TTagName> | (() => NodeModFn<TTagName>),\n parent?: Element,\n index?: number\n): ExpandedElement<TTagName>;\nexport function render<TTagName extends ElementTagName = ElementTagName>(\n nodeModFn: NodeModFn<TTagName> | (() => NodeModFn<TTagName>),\n parent?: Element,\n index = 0\n): ExpandedElement<TTagName> | Comment {\n const { build, component } = unwrapComponent(nodeModFn);\n const targetParent = (parent || document.body) as ExpandedElement<TTagName>;\n const mark = mountQueueMark();\n let element: ExpandedElement<TTagName>;\n try {\n element = build(targetParent, index) as ExpandedElement<TTagName>;\n // Marker blocks (region, list, when) attach their own start/end pair and\n // return the start marker: re-appending it would move it past the end.\n if ((element as unknown as Node).parentNode !== targetParent) {\n (targetParent as unknown as Node).appendChild(element as Node);\n }\n } catch (error) {\n // The half-built tree is discarded: nothing in it may mount later.\n cancelMountsSince(mark);\n throw error;\n }\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(\n nodeModFn: MarkerModifier | (() => MarkerModifier),\n parent?: Element,\n): Comment;\nexport function hydrate<TTagName extends ElementTagName = ElementTagName>(\n nodeModFn: NodeModFn<TTagName> | (() => NodeModFn<TTagName>),\n parent?: Element,\n): ExpandedElement<TTagName>;\nexport function hydrate<TTagName extends ElementTagName = ElementTagName>(\n nodeModFn: NodeModFn<TTagName> | (() => NodeModFn<TTagName>),\n parent?: Element,\n): ExpandedElement<TTagName> | Comment {\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) — including\n * whitespace-only text inside the tree that sits where an element or block is\n * now expected (the container's own whitespace is never touched).\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(\n nodeModFn: MarkerModifier | (() => MarkerModifier),\n parent?: Element,\n): Comment;\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> | Comment | void {\n if (nodeModFn !== undefined) {\n const { build } = unwrapComponent(nodeModFn);\n return hydrateRoot(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 if (root) forcedComponents.delete(root);\n continue;\n }\n const record = forcedComponents.get(root)!;\n try {\n const build = record.component();\n const el = hydrateRoot(\n build,\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 forcedComponents.delete(root);\n forcedComponents.set(el as unknown as Element, record);\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 // The container belongs to the app, not to nuclo: step over its template\n // whitespace here so a force pass (which drops stale whitespace text inside\n // the tree it rebuilds) never removes it.\n else if (force) skipWhitespaceText(parentNode, false);\n const mark = mountQueueMark();\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 } catch (error) {\n // Fresh nodes of the half-built tree are discarded: they may not mount\n // later. Claimed nodes are live in the document and keep their turn.\n cancelMountsSince(mark);\n throw error;\n } finally {\n endHydration();\n // After the pass, not during it: only now is it settled which views a\n // region got, so server markup none of them claimed can be dropped.\n sweepRegions();\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>) {\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) {\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) {\n\treturn rule instanceof CSSStyleRule ? rule.selectorText : groupQueryOf(rule);\n}\n\nfunction rememberExternalRule(rule: CSSRule, query: string | undefined) {\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) {\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) {\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) {\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) {\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) {\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) {\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) {\n\tconst queryPart = query === undefined ? \"-\" : \"+\" + query.length + \":\" + query;\n\treturn queryPart + suffix.length + \":\" + suffix;\n}\n\nfunction appendKeyPart(key: string, value: string) {\n\treturn key + value.length + \":\" + value;\n}\n\nexport function expandAmpersands(input: string, replacement: 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) {\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) {\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) {\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) {\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() {\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) {\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() {\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() {\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) {\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) {\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 = '&'; break; // &\n case 60: escaped = '<'; break; // <\n case 62: escaped = '>'; break; // >\n case 34: escaped = '"'; break; // \"\n case 39: escaped = '''; 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) {\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 = '&'; break; // &\n case 60: escaped = '<'; break; // <\n case 62: escaped = '>'; 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) {\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) {\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) {\n\treturn screen.charCodeAt(0) === 64 /* @ */ ? screen : \"@media \" + screen;\n}\n\n/**\n * True for an @media prelude that is a bare condition list (\"(min-width: 40em)\n * and (hover)\") rather than one led by a media type (\"print\", \"only screen\").\n * Only a bare list can sit on the right of an `and`: per the media-query\n * grammar a type (and the `only` keyword) must lead the whole query, so\n * \"(min-width: 768px) and print\" is not a valid query — every browser\n * normalizes it to `not all` and the block silently never matches.\n */\nfunction isBareCondition(condition: string) {\n\treturn condition.charCodeAt(0) === 40 /* ( */;\n}\n\n/** A leading `not` negates the whole query, so it can never be flattened with `and`. */\nfunction leadsWithNot(condition: string) {\n\tif (!condition.startsWith(\"not\")) return false;\n\tconst after = condition.charCodeAt(3);\n\treturn Number.isNaN(after) || after === 32 /* space */ || after === 40 /* ( */;\n}\n\nfunction combineQuery(outer: string | undefined, inner: 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\tconst outerCondition = outer.slice(6).trim();\n\t\tconst innerCondition = inner.slice(6).trim();\n\t\t// Put the media-type side first — the only arrangement the grammar allows.\n\t\tif (!leadsWithNot(outerCondition) && !leadsWithNot(innerCondition)) {\n\t\t\tif (isBareCondition(innerCondition)) return \"@media \" + outerCondition + \" and \" + innerCondition;\n\t\t\tif (isBareCondition(outerCondition)) return \"@media \" + innerCondition + \" and \" + outerCondition;\n\t\t}\n\t\t// Two media types, or a `not` on either side: no single flat prelude means\n\t\t// what was authored, and the engine emits one group per query rather than\n\t\t// nested groups. Drop the outer condition (as for any other nested at-rule)\n\t\t// instead of emitting a prelude that silently matches nothing.\n\t\tconsole.warn(\n\t\t\t`[nuclo] cannot combine nested media queries ${JSON.stringify(outer)} and ${JSON.stringify(inner)}; ` +\n\t\t\t\t\"using the inner query alone. Author one query that states both conditions.\",\n\t\t);\n\t\treturn inner;\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() {\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) {\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>) {\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>) {\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[]) {\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) {\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>) {\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(name: string, style: Style<T>): StyleResult;\n\tfunction css(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>) {\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>) {\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>) {\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(name: string, style: Style<object>): StyleResult;\n\t(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 * 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) {\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) {\n Object.defineProperty(target, key, { value, configurable: true, enumerable: true, writable: true });\n },\n });\n}\n\nfunction registerHtmlTag(target: Record<string, unknown>, tagName: ElementTagName) {\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) {\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) {\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 { region, into } from \"./region\";\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() {\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.region = region;\n registry.into = into;\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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"}
|