payload-live-preview 2.0.2 → 2.0.3
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 +11 -8
- package/dist/adapters/astro/index.js +1 -1
- package/dist/adapters/astro/index.js.map +1 -1
- package/dist/adapters/astro/middleware-entry.js +1 -1
- package/dist/adapters/astro/middleware-entry.js.map +1 -1
- package/dist/adapters/nextjs/index.js +1 -1
- package/dist/adapters/nextjs/index.js.map +1 -1
- package/dist/adapters/nuxt/index.js +1 -1
- package/dist/adapters/nuxt/index.js.map +1 -1
- package/dist/adapters/sveltekit/index.js +1 -1
- package/dist/adapters/sveltekit/index.js.map +1 -1
- package/dist/client.cjs +1 -1
- package/dist/client.cjs.map +1 -1
- package/dist/client.js +1 -1
- package/dist/client.js.map +1 -1
- package/dist/core.cjs +1 -1
- package/dist/core.cjs.map +1 -1
- package/dist/core.d.cts +3 -2
- package/dist/core.d.ts +3 -2
- package/dist/core.js +1 -1
- package/dist/core.js.map +1 -1
- package/dist/doctor-cli.d.ts +1 -1
- package/dist/doctor-cli.js +1 -1
- package/dist/doctor-cli.js.map +1 -1
- package/dist/doctor.d.ts +2 -2
- package/dist/doctor.js +1 -1
- package/dist/doctor.js.map +1 -1
- package/dist/fragment.cjs.map +1 -1
- package/dist/fragment.js.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -2
- package/dist/index.d.ts +3 -2
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/lean.cjs +1 -1
- package/dist/lean.cjs.map +1 -1
- package/dist/lean.js +1 -1
- package/dist/lean.js.map +1 -1
- package/dist/lexical.cjs +1 -1
- package/dist/lexical.cjs.map +1 -1
- package/dist/lexical.js +1 -1
- package/dist/lexical.js.map +1 -1
- package/dist/plugins.cjs +1 -1
- package/dist/plugins.cjs.map +1 -1
- package/dist/plugins.js +1 -1
- package/dist/plugins.js.map +1 -1
- package/dist/{probe-DqaItcwX.d.ts → probe-DX_4wsBu.d.ts} +6 -0
- package/dist/server.cjs +1 -1
- package/dist/server.cjs.map +1 -1
- package/dist/server.js +1 -1
- package/dist/server.js.map +1 -1
- package/dist/structural.cjs +2 -2
- package/dist/structural.cjs.map +1 -1
- package/dist/structural.js +2 -2
- package/dist/structural.js.map +1 -1
- package/package.json +1 -1
package/dist/core.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"core.cjs","names":["VERSION","detectInitialLocale","document","lang","documentElement","getAttribute","length","readHtmlLang","navigator","language","readNavigatorLanguage","ELEMENT_ID","documentLeases","WeakMap","clearLeaseMessage","lease","timer","clearTimeout","messageNode","remove","A11yAnnouncer","german","constructor","locale","targetDocument","activeDocument","documentLocale","this","test","isGerman","mount","body","get","element","owned","refs","set","acquireDocumentLease","leased","isConnected","ownerDocument","getElementById","createElement","id","setAttribute","appendChild","announceConnected","say","announceDisconnected","announceUpdate","count","String","detach","delete","message","parentNode","createTextNode","hasChildNodes","data","previousSibling","setTimeout","parseFieldSchema","raw","Array","isArray","out","entry","parsed","parseFieldEntry","push","value","record","name","type","fields","blocks","slug","parseBlockSchema","result","optionalFieldOk","check","optionalTypeOk","isPlainObject","prototype","Object","getPrototypeOf","NULL_AS_ABSENT_FIELDS","CAPABILITY_DECLARATIONS","basic","since","observed","PROTOCOL_CAPABILITIES","keys","negotiateProtocol","theirs","sanitisedTheirs","Number","isFinite","Math","floor","effectiveTheirs","negotiated","min","seen","Set","capabilities","capability","has","add","ours","observeThenableResult","then","Promise","resolve","catch","sameRevision","a","b","generation","revision","MessageBus","matcher","handlers","boundListener","attachedTarget","queueHead","queueTail","attach","target","window","committed","listener","event","receive","origin","reportInvalid","resetQueue","addEventListener","error","removeEventListener","advanceGeneration","sendReady","targets","origins","payload","ready","protocolVersion","postMessage","matchesOrigin","matchesSource","v","x","isLivePreviewMessage","dispatchUpdate","normalized","field","Reflect","deleteProperty","fieldSchemaJSON","normalizeLivePreviewMessage","isDocumentEventMessage","invokeHandler","onDocumentEvent","focusFieldOf","onFocusField","hasUpdateData","isCurrentGeneration","messageRevision","validator","validateToken","commitUpdate","pending","verdict","next","enqueue","previewToken","settleValidation","approved","drainQueue","dequeue","onUpdate","reason","onInvalid","sourcePolicy","source","parent","opener","handler","args","expected","isolateDiagnostic","diagnostic","noopDiagnostic","safeConsoleError","console","safeConsoleWarn","warn","safeConsoleDebug","debug","HOW_TO_GET_IT","reported","reportOmittedFeature","feature","createA11y","options","__LEAN_BUILD__","enableA11y","refuseA11y","root","nodeType","isDocumentRoot","a11yLocale","buildA11y","defaultSendReady","Window","definedOnly","key","entries","STRUCTURAL_TYPES","buildSchemaIndex","schemas","basePath","Map","walk","schema","path","block","lookupSchema","index","fieldPath","wildcardPath","replace","getId","item","getBlockType","blockType","diffArray","prev","every","patches","prevIndexById","i","consumedFromPrev","to","kind","from","prevItem","shallowEqual","oldValue","diffById","diffByPosition","is","aRec","bRec","aKeys","bKeys","MAP","text","textarea","richText","email","number","checkbox","date","select","radio","array","group","tabs","row","collapsible","relationship","upload","point","json","code","ui","SAFE_PROTOCOLS","DANGEROUS_PROTOCOL_PATTERN","RELATIVE_PATH","PROTOCOL_RELATIVE","PARSER_IGNORED","isSafeUrl","url","trimmed","trim","startsWith","URL","protocol","isExternalHttpUrl","BLOCKED_ATTRIBUTES","URL_ATTRIBUTES","isWritableAttribute","resolveUnfaithfulPatchMode","onUnfaithfulPatch","onUnboundChange","reportUnfaithfulPatch","deps","state","reportedUnfaithful","unfaithfulCount","unfaithfulFields","fieldName","mode","log","unfaithfulPatches","reportUnboundChange","FORMATTING_RENDERERS","shownValue","tagName","textContent","excerpt","JSON","stringify","slice","noWriteCallbacks","WeakSet","markNoWriteCallback","callback","valueIdentity","FieldChangeTracker","previous","diff","dependencies","baseline","changed","identity","invalidated","dependents","dependent","reset","FRAGMENT_ATTRIBUTE","enclosingFragment","closest","resolveStrategy","explicit","collectionOwnerKey","documentId","nonEmpty","isBindingInScope","owner","includes","readDocumentId","SYSTEM_FIELD_NAMES","hasBinding","cache","ownerKeys","bindings","some","binding","hasBindingBelow","prefix","boundName","stripLocaleSuffix","suffix","endsWith","createFieldAddressability","localised","base","names","localisedBindingNames","unboundChangedFields","touched","isAddressable","unbound","SELF_SUFFICIENT_TYPES","NO_DEPENDENCIES","MergeNeed","rawChanges","resolved","queued","openUntil","decide","transaction","emitter","islands","listenerCount","values","rendersAReference","isPath","hrefField","srcField","altField","strategies","fragment","querySelector","readsPopulatedValues","merge","forceRender","verdictFor","schemaIndex","request","merger","windowMs","now","Date","dropQueued","leading","settle","promise","createPending","flush","recordMerged","doc","destroy","status","isScalar","namesAReference","fieldType","ProtocolTracker","negotiation","observe","fresh","filter","join","applyVersion","remoteVersion","current","owesForceRender","completed","RelationshipTracker","lastIdentity","edit","externallyUpdatedRelationship","entitySlug","updatedAt","isNew","previewedSlug","globalSlug","collectionSlug","previewedId","namesAnotherDocument","prefersReducedMotion","win","matchMedia","matches","FieldRevealer","lastField","reveal","rect","getBoundingClientRect","vertically","bottom","top","innerHeight","horizontally","right","left","innerWidth","isInViewport","scrollIntoView","behavior","revealElement","RevealLedger","note","slot","revealIdentities","revealTarget","commit","RuntimeState","started","suspended","deferredStart","hydration","activeUpdate","updateCount","supersededCount","completedCount","skippedUnchangedCount","lastFlush","absentFields","warnedOrphanFields","warnedStrategy","warnedUnattributableMessage","warnedVisibilityGate","warnedFragmentFallback","warnedProtocolShape","checkedServerFormat","escalatedCount","autoBindSearchMs","autoBindGuesses","warnedForeignSource","lastAppliedIdentity","revealLedger","fragmentStats","rendered","failed","superseded","routeStats","refreshes","refused","loopStopped","fragmentController","routeController","routeRetry","readyTimers","revealer","changes","merges","relationships","isRunning","isCurrent","complete","abortStrategies","controller","abort","BindingWriter","instanceContext","renderRichText","sanitizerPolicy","reportUnfaithful","apply","update","schemaEntry","renderer","schemaType","explicitFieldType","mapped","hasOwnProperty","call","payloadTypeToRenderer","resolveFieldType","children","looksLikeLexicalRoot","resolveRenderer","fail","emitElementUpdate","src","context","allFields","hidesWhenEmpty","toggleAttribute","isEmptyFieldValue","targetAttribute","attribute","toLowerCase","removeAttribute","stringValue","applyAttributeBinding","shown","format","watchServerFormatting","outcome","render","invokeRenderer","rendererUsesNoWriteOutcome","before","after","reportServerFormatting","emitWhile","previousValue","nextValue","receivedAt","applied","cause","Error","mergeDependencyMaps","maps","merged","map","bucket","dependencyMapFromBinding","dependsOn","ISLAND_EVENT","ISLAND_ATTRIBUTE","ISLAND_SELECTOR","islandAllowsPatching","island","isIslandBoundary","hasAttribute","isIslandRoot","isInsideIsland","parentElement","FIELD_ATTRIBUTE","TYPE_ATTRIBUTE","TARGET_ATTRIBUTE_ATTRIBUTE","HREF_ATTRIBUTE","SRC_ATTRIBUTE","ALT_ATTRIBUTE","ARRAY_TEMPLATE_ATTRIBUTE","ARRAY_SEPARATOR_ATTRIBUTE","LOCALE_ATTRIBUTE","RICH_TEXT_ATTRIBUTE","HTML_ATTRIBUTE","ARRAY_ATTRIBUTE","STRUCTURAL_ATTRIBUTE","OWNER_ATTRIBUTE","DEPENDS_ATTRIBUTE","STRATEGY_ATTRIBUTE","BOUNDARY_ATTRIBUTE","GUESSED_ATTRIBUTE","BINDING_ATTRIBUTES","FIELD_SELECTOR","OWNER_SELECTOR","resolveBindingOwner","CUSTOM_RENDERER_KEY","VALID_FIELD_TYPES","isRendererKey","ElementCache","entriesByField","entryByElement","islandRoots","alwaysTrue","dependencyMap","buildFromRoot","t0","performance","clear","elementCount","querySelectorAll","collectIslands","fieldCount","size","durationMs","resolveBinding","replaceEntry","removeEntry","append","getByElement","indexOf","splice","arrayTemplate","arraySeparator","split","parseDependencyList","strategy","guessed","fragmentBoundary","strategyKind","inputType","isPathSegment","maxLength","character","codePoint","codePointAt","hasControlCharacter","isSafeSlug","DataMerger","serverURL","apiRoute","depth","fetchFn","inflight","attempt","destroyDepth","end","withoutTrailingSlashes","route","canMerge","endpointOf","encodeURIComponent","endpoint","fetch","AbortController","response","method","credentials","headers","flattenLocales","signal","ok","PAYLOAD_2","fieldTyping","populatesRelationships","documentEvents","PAYLOAD_3","UNKNOWN","detectProtocolProfile","ObserverManager","callbacks","debounceMs","rootMargin","visible","mutation","intersection","debounceTimer","mutationDebounceMs","intersectionRootMargin","start","previousGeneration","stop","MutationObserver","mutations","handleMutations","IntersectionObserver","handleIntersection","threshold","childList","subtree","attributes","attributeFilter","disconnect","observeElement","unobserveElement","unobserve","markVisible","isVisible","m","attributeName","node","addedNodes","containsTrackedElement","removedNodes","hasStructuralImpact","onStructuralChange","isIntersecting","onVisibilityChange","BINDING_SELECTOR","signalSlot","w","armed","commits","onCommit","waiters","armReactCommitSignal","hook","__REACT_DEVTOOLS_GLOBAL_HOOK__","renderers","supportsFiber","inject","internals","installedHook","onCommitFiberRoot","rendererId","rest","container","containerInfo","waiter","forget","awaitSettled","onSettled","capMs","VUE_APP_PROPERTY","mountedApp","armVueMountSignal","proto","Element","getOwnPropertyDescriptor","defineProperty","configurable","app","writable","enumerable","live","nuxt","$nuxt","isHydrating","settleOnceHydrated","startAfterParse","host","startNow","later","startHydrated","HYDRATION_WAIT_CAP_MS","judge","ownsBindings","whenReactCommitted","mountedAround","whenVueMounted","defer","hydrated","HeartbeatTimer","timeoutMs","onTimeout","handle","lastKick","kick","lastKickAt","ConnectionState","markConnected","transition","markDisconnected","BOOLEAN_WORDS","NUMERIC","ENUM_TOKEN","LOCALE_CODE","SKIPPED_TAGS","isBindableValue","minLength","isRecord","bindableValues","claim","media","rawName","child","childValue","isBoundary","namespaceURI","editable","soleText","firstChild","nextSibling","isCandidateAttribute","search","hits","byElement","elements","byField","firstElementChild","nextElementSibling","textClaim","getAttributeNames","shape","tag","stamps","href","matched","alt","first","done","searchUnique","unique","candidates","candidate","searchRoot","adopt","when","adopted","observers","autoPolicy","BLOCKED_KEYS","resolveFieldValue","preferLocale","localized","readOwn","direct","segment","object","bindingValue","fallbackLocale","bindingIdentity","own","siblings","combined","sibling","report","warned","isBindableScalar","trustedHtml","html","policy","api","globalThis","trustedTypes","createPolicy","factory","createHTML","input","resolvePolicy","STATE_ATTRIBUTES","keyOf","keyAttributes","isMorphBoundary","morphElement","isMorphCompatible","focus","active","activeElement","HTMLElement","contains","selection","HTMLInputElement","HTMLTextAreaElement","selectionStart","selectionEnd","captureFocus","syncAttributes","retainChildrenOf","liveKeyed","keyed","duplicate","onDuplicateKey","indexKeyed","keyedElements","liveUnkeyed","childNodes","claimed","usedKeys","renderedNodes","cursor","unkeyedIndex","kept","reconcile","replaceWith","sameKind","replaceChild","following","isBlankText","insertBefore","morphChildren","snapshot","preventScroll","setSelectionRange","restoreFocus","nodeValue","Node","TEXT_NODE","reportDroppedAttribute","ALLOWED_TAGS","FORM_CONTROLS","REMOVE_COMPLETELY","ATTR_GLOBAL","ATTR_ARIA_PREFIX","ATTR_DATA_PREFIX","ATTR_BY_TAG","img","picture","audio","video","time","abbr","q","blockquote","table","th","td","col","colgroup","ol","li","pre","SanitizerEnvironmentError","TEMPLATE_ATTRIBUTES","DOCUMENT_SLOT","Symbol","for","sanitizeHtml","sanitizeHtmlWithPolicy","resolveDocument","__INLINE_BUILD__","instancePolicy","attrMap","attrs","allowedTags","attrByTag","allowFormControls","templateMode","allowedData","allowed","additionalAllowedTags","forEach","additionalAllowedAttributes","attr","allowedDataAttributes","template","innerHTML","sanitizeFragment","content","override","sanitizeElement","tagAttrs","isSafeSrcset","sanitizeAttributes","anchor","hardenAnchor","HTML_ESCAPES","freeze","HTML_ESCAPE_PATTERN","escapeHtml","char","ATTR_ESCAPES","ATTR_ESCAPE_PATTERN","escapeHtmlAttribute","PLACEHOLDER_PATTERN","collectTemplateKeys","items","interpolateArrayTemplate","knownKeys","placeholder","hasOwn","sharedItemAttributes","shared","everyItem","inheritItemAttributes","safeStringify","isEmptyValue","lruGet","lruSet","limit","oldest","lruTrim","TEMPLATE_EXTRA_TAGS","TEMPLATE_EXTRA_ATTRIBUTES","CUSTOM_TAG_PATTERN","optionsByTemplate","templateSanitizeOptions","cached","tags","match","matchAll","KEY_ATTRIBUTE","NESTED_KEY_ATTRIBUTE","NESTED_TEMPLATE_ATTRIBUTE","applyStructuralPatches","plan","prepareStructuralPlan","commitStructuralPlan","store","morph","isManagedNestedSlot","_live","env","nextItems","memory","templateKeys","initialChildren","keyedChildren","indexByAttribute","reserved","readKey","takeIndexedElement","replaces","renders","renderItem","nestedSlots","prepareNestedSlots","prepareReconciliation","patch","createPatchPlan","mutated","retained","liveSlot","renderedSlot","synchronizeAttributes","getMemory","rememberItem","oldItem","newItem","prevValue","oldSlotsByKey","findDirectNestedSlots","plans","newSlot","oldSlot","nextTemplate","previousTemplate","nextNested","readNestedArray","resolvedNext","templateChanged","ancestor","nested","indexed","pop","safe","warnFragmentFallback","warnUnsupportedStrategy","StrategyRunner","planFragments","planBoundaries","escalateUnfaithful","routeRefreshed","boundaries","boundary","coveringBoundaries","pendingFragments","runFragments","refreshRoute","hasUnboundChange","answered","hasRouteBinding","aborted","detail","cloneNode","morphFragment","patchFallback","restoreGuesses","scheduler","pendingCount","revealPending","updatedCount","runRoute","armRouteRetry","delayMs","stats","refresh","retryAfter","rebuildCache","reapply","schedule","transform","covered","covers","transformForBinding","originalValue","transformValue","transformed","returnedThenable","TypeError","err","emit","NOTHING_CHANGED","UpdatePipeline","createLeanStrategyRunner","scheduleAllFields","handleUpdate","heartbeat","observeCapabilities","relationshipEdit","timestamp","cancelled","acceptRevision","connection","a11y","processUpdate","resolveIncomingFields","dataFor","cancel","cancelRevision","applyFields","refined","autoBind","scope","ownerKeysForUpdate","folded","keep","adoptUniqueBindings","coalesced","mergeWindowMs","applyMerged","trackIdentity","skipUnchanged","scheduled","revealEditedField","last","ownsAnyBinding","childName","diagnoseOrphanFields","known","restoreUniqueBindings","scopeBindingsByOwner","collectionKey","messageOwnerKeys","onFlush","deferred","unfaithful","dispatchEvent","CustomEvent","bubbles","dispatchIslandUpdate","revealBinding","revealField","defaultView","UpdateScheduler","maxWaitMs","gateThresholdValue","gateDisabled","getCacheSize","scheduleFrame","cancelFrame","replay","activeFlushes","debounceToken","deadlineTimer","frameHandle","frameToken","windowUntil","activeRevision","activeRevisionCancelled","visibilityGateThreshold","disableVisibilityGate","requestAnimationFrame","bind","cancelAnimationFrame","existing","armDebounce","cancelScheduledWork","clearWork","flushNow","notifyVisible","didApply","statsFor","retarget","retargetBuffer","replayCount","gateThreshold","gateActive","opensTheWindow","requestFrame","token","clearDeadline","appliedFields","batchEntry","buffer","READY_RETRY_DELAYS_MS","LivePreviewRuntime","pipeline","writer","rootSentinel","observedRoot","bus","originMatcher","eventSourcePolicy","dataMerge","heartbeatMs","onHeartbeatTimeout","readyTargets","lockedOrigin","readyState","onReady","once","startWhenReady","startupHost","rollbackFailedStart","step","reportError","observerRoot","readDocumentBody","watchRootReplacement","buildCacheAndObserve","delay","sendReadyAfterStart","suspend","wasConnected","release","runCleanup","cleanup","refreshCache","followReplacedRoot","inspect","fieldNames","owners","version","trusted","locked","sort","profile","revisions","accepted","skippedUnchanged","orphanFields","ownerScoped","localeCompare","searchMs","fidelity","escalated","fragments","inFlight","visibilityGateActive","plugins","buildInspection","removed","isIdleDisconnected","EventEmitter","regular","on","register","off","emitSequential","shouldContinue","eligible","invoke","removeAllListeners","eventNames","label","isInIframe","self","isInPopup","isInPreviewContext","isDevMode","nodeEnv","process","readNodeEnv","location","hostname","LOCALHOST_PATTERN","VALID_ORIGIN_PATTERN","LOCALHOST_HANDSHAKE_PORTS","OriginDetector","additionalOrigins","normalised","normaliseOrigin","referrerOrigin","enableReferrerDetection","referrer","allowLocalhost","enableLocalhostMatching","forceDevMode","lockOrigin","unlockOrigin","enumerate","port","referrerWasAvailable","isProductionUnconfigured","isReferrerOnlyTrust","noopDisposer","ResourceScope","pluginName","resources","assertOpen","track","acquire","finalize","disposed","stage","resource","dispose","activate","counts","subscription","close","reverse","ScopedPluginEvents","events","subscriptions","subscribe","untypedHandler","callerEligible","find","subscriptionActive","wrapped","async","PluginManager","config","registerRenderer","onTransformError","initializing","teardowns","destroying","transforms","mutationQueue","queuedHooks","registerFieldRenderer","plugin","registerNow","unregister","unregisterNow","destroyAll","destroyAllNow","applyTransforms","registrations","registration","list","describe","cleanups","incompatibility","compat","runtimeVersion","runtime","range","exec","parseVersion","alternative","comparators","part","comparator","operator","order","delta","compare","satisfiesComparator","satisfiesRange","isInteger","incompatibilityOf","refuse","createContext","runHook","init","registerTransform","registerCleanup","getConfig","existingTeardown","holdQueue","teardown","destroyPlugin","operation","RendererRegistry","layers","layer","stack","wasTop","previousLayer","at","previousRenderer","ALIGNMENT_NUMERIC","ALIGNMENT_STRING","resolveAlignment","fmt","resolveIndent","indent","dirAttribute","direction","layoutClassAttribute","align","classes","VALID_TAGS","asRecord","readMedia","sanitizeIdent","pickRelationLabel","title","BLANK_TARGET","linkRenderer","ctx","renderChildren","internalUrl","resolveUrl","titleAttr","extractText","dimensionAttributes","width","height","typeAttribute","mimeType","registry","lookupBlockRenderer","UNRENDERED_BLOCK_SELECTOR","renderBlockNode","baseClass","custom","onUnrenderedBlock","spanAttribute","BUILTIN_NODE_RENDERERS","paragraph","heading","tagRaw","listType","startAttr","checkAttr","listitem","valueAttr","link","autolink","quote","linebreak","horizontalrule","tab","mime","renderVideo","renderAudio","renderImage","filename","renderFallbackLink","relationTo","classAttr","inlineBlock","tablerow","tablecell","header","warnedNoSanitizer","isLexicalContent","renderNode","extractPlainText","createTextRenderer","warnedElements","toPlainString","hasForeignChildren","warnOnce","escapeAndLinebreak","warnedKept","warnedLost","WRAPPER_TAGS","richTextRenderer","unrendered","verdicts","className","wrapperOf","placeholders","pairs","pairUnrenderedBlocks","replaceChildren","writeKeepingUnrenderedBlocks","sanitize","warnNoSanitizerOnce","lexicalToHtml","placeholderClass","lost","reportUnrenderedBlock","liveChild","renderedChild","htmlRenderer","acceptUrl","createLinkRenderer","toHref","urlRenderer","HAS_SCHEME","emailRenderer","IMAGE_SOURCE_ATTRIBUTES","clearImage","writeImage","srcset","sizes","srcsetUrl","buildSrcset","imageRenderer","pickSource","pickAlt","style","backgroundImage","escapeCssUrl","uploadRenderer","relationshipRenderer","selectRenderer","toValues","checked","option","labelFor","multiple","selected","writeSelect","FALSE_STRINGS","checkboxRenderer","toBoolean","NUMBER_CACHE","DATE_CACHE","buildKey","localePart","serialised","stableStringify","parts","inner","DATE_STYLES","TIME_STYLES","CURRENCY_CODE","FRACTION_DIGITS","dateFormat","numberFormat","formatOptionsFor","spec","separator","argument","dateStyle","timeStyle","minimumFractionDigits","maximumFractionDigits","currency","toUpperCase","parseValueFormat","warnUnknownFormat","dateRenderer","valid","isNaN","getTime","fallback","toISOString","DEFAULT_DATE_OPTIONS","Intl","DateTimeFormat","getDateTimeFormat","formatDate","day","getFullYear","padStart","pad","getMonth","getDate","clock","getHours","getMinutes","formatForInput","numberRenderer","num","NumberFormat","getNumberFormat","arrayRenderer","renderTemplate","templateOptions","createStructuralArrayRenderer","states","warnedContainers","warnedKeys","rawValue","warnMissingTemplate","previousState","domSnapshot","readDomKeySnapshot","position","__payloadDomPosition","sameDomKeySnapshot","needsForcedRender","nextKeys","itemKey","warnDuplicateKey","previousKeys","stable","warnAboutKeys","codes","builtinRenderers","omittedRenderer","V2_RUNTIME_DEFAULTS","disableReferrerDetection","V1_RUNTIME_DEFAULTS","invert","cryptoOverride","LivePreviewClient","detector","rendererRegistry","destroyed","tornDown","destroyPromise","rawConfig","rows","defaults","withProfileDefaults","mergeDepth","assertMergeDepthExplicit","allowedOrigins","disableLocalhostMatching","stateless","buildBuiltinRenderers","mergeFetch","e","autoStart","resume","resolveDestroy","rejectDestroy","reject","finish","finally","use","unuse","AUTHORIZED_PREVIEW_BRAND_KEY","BRAND","isAuthorizedPreviewContext","isFrozen","SLOT","DIAGNOSTIC_CODES","NoTrustedOrigin","ReferrerOnlyTrust","PluginIncompatible","ProfileFeatureOmitted","OrphanField","UnattributableUpdate","VisibilityGateDeferred","UnsafeAttributeWrite","TextTargetHasChildren","MissingArrayTemplate","StructuralItemUnkeyed","StructuralDuplicateKey","StructuralUnstableKeys","UnsupportedStrategy","UnknownValueFormat","SanitizerDroppedAttribute","UnrenderedBlockKept","UnfaithfulPatch","ServerFormatReplaced","UnrenderedBlockLost","MessageRejected","TokenRejected","ProtocolShapeUnknown","HandlerThrew","TransformThrew","RendererThrew","StartupFailed","ReadyFailed","HydrationWaitTimedOut","AuditRuntimeMissing","AuditNoFrameAncestors","AuditFrameOptionsBlocks","AuditBindingsExposed","AuditGateThresholdExceeded","AuditUnownedBindings","AuditNoBindings","AuditNotAPage","FragmentRequestFailed","FragmentResponseInvalid","FragmentUnauthorized","FragmentSuperseded","RouteRefreshLoop","FragmentStrategyUnavailable","UnboundChangeRefresh","V2ReadinessGap","RuntimeOnPublicPage","buildAttributes","bindByPath","picker","proxy","Proxy","_target","prop","recordPath","richtext","REGISTRY_ID","SUPPRESSED","gates","buildFrameAncestors","allowNone","buildScriptSrcWithNonce","nonce","RangeError","extra","strictDynamic","createPreviewBindings","authorized","authorization","bindOptions","boundaryOptions","boundaryAttributes","generateCspNonce","bytes","crypto","getRandomValues","fromGlobal","resolveCrypto","Uint8Array","binary","byte","fromCharCode","btoa","Buffer","toString","replaceAll","base64UrlEncode","hasCapability","initLivePreview","client","registerRouteRefresh","setCspCrypto","setSanitizerDocument"],"sources":["../package.json","../src/version.ts","../src/detection/locale.ts","../src/core/a11y.ts","../src/schema/parser.ts","../src/core/message-guards.ts","../src/core/protocol-version.ts","../src/core/thenable.ts","../src/core/message-bus.ts","../src/core/diagnostics.ts","../src/core/profile.ts","../src/core/runtime-wiring.ts","../src/types/defined-only.ts","../src/schema/walker.ts","../src/schema/diff.ts","../src/schema/field-type-map.ts","../src/security/url-validator.ts","../src/core/attribute-binding.ts","../src/core/fidelity.ts","../src/core/internal-outcome.ts","../src/core/value-identity.ts","../src/core/field-changes.ts","../src/core/strategies.ts","../src/core/binding-owner.ts","../src/core/unbound-fields.ts","../src/core/merge-need.ts","../src/core/protocol-tracker.ts","../src/core/relationship-tracker.ts","../src/core/reveal.ts","../src/core/reveal-ledger.ts","../src/core/runtime-state.ts","../src/core/binding-writer.ts","../src/core/dependencies.ts","../src/core/islands.ts","../src/core/cache.ts","../src/core/data-merger.ts","../src/core/protocol-profile.ts","../src/core/observers.ts","../src/core/hydration.ts","../src/core/hydration-vue.ts","../src/core/startup.ts","../src/core/state.ts","../src/core/auto-bind.ts","../src/core/field-value.ts","../src/security/trusted-types.ts","../src/core/orphan-diagnostics.ts","../src/core/morph.ts","../src/security/sanitizer-report.ts","../src/security/sanitizer.ts","../src/security/escape.ts","../src/core/array-template.ts","../src/field-types/utils.ts","../src/core/lru.ts","../src/core/template-sanitize.ts","../src/core/structural-applier.ts","../src/core/strategy-warnings.ts","../src/core/strategy-runner.ts","../src/core/transform-value.ts","../src/core/update-pipeline.ts","../src/core/strategy-runner-lean.ts","../src/core/update-scheduler.ts","../src/core/lifecycle.ts","../src/core/inspection/snapshot.ts","../src/events/emitter.ts","../src/detection/environment.ts","../src/detection/origin.ts","../src/plugins/resource-scope.ts","../src/plugins/scoped-events.ts","../src/plugins/manager.ts","../src/plugins/compat.ts","../src/plugins/renderer-registry.ts","../src/lexical/utils.ts","../src/lexical/nodes/paragraph.ts","../src/lexical/nodes/heading.ts","../src/lexical/value-shapes.ts","../src/lexical/nodes/link.ts","../src/lexical/nodes/code.ts","../src/lexical/nodes/upload.ts","../src/lexical/nodes/relationship.ts","../src/lexical/blocks/registry.ts","../src/lexical/nodes/block.ts","../src/lexical/nodes/table.ts","../src/lexical/nodes/builtin.ts","../src/lexical/nodes/text.ts","../src/lexical/types.ts","../src/lexical/nodes/list.ts","../src/lexical/nodes/quote.ts","../src/lexical/nodes/linebreak.ts","../src/lexical/registry.ts","../src/lexical/render.ts","../src/field-types/text.ts","../src/field-types/rich-text.ts","../src/field-types/html.ts","../src/field-types/unsafe-url.ts","../src/field-types/url.ts","../src/field-types/email.ts","../src/field-types/media.ts","../src/field-types/image.ts","../src/field-types/upload.ts","../src/field-types/relationship.ts","../src/field-types/select.ts","../src/field-types/checkbox.ts","../src/core/intl-cache.ts","../src/field-types/value-format.ts","../src/field-types/date.ts","../src/field-types/number.ts","../src/field-types/array.ts","../src/field-types/structural-array.ts","../src/field-types/registry.ts","../src/field-types/index.ts","../src/types/defaults-profile.ts","../src/client/index.ts","../src/security/csp.ts","../src/client/config.ts","../src/types/merge-depth.ts","../src/types/authorized-preview.ts","../src/core/protocol-capability-docs.ts","../src/core/route-refresh.ts","../src/core/diagnostic-codes.ts","../src/dsl/bind.ts","../src/dsl/preview-bindings.ts","../src/core-entry.ts"],"sourcesContent":["{\n \"name\": \"payload-live-preview\",\n \"version\": \"2.0.2\",\n \"description\": \"Live preview for Payload CMS on server-rendered and static frontends (Astro, Next.js, SvelteKit, Nuxt, plain HTML): DOM patches, server-rendered fragments, React and Vue hooks. Strict by default, zero dependencies.\",\n \"author\": \"relative23\",\n \"license\": \"MIT\",\n \"type\": \"module\",\n \"packageManager\": \"npm@12.0.2\",\n \"main\": \"./dist/index.cjs\",\n \"module\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\",\n \"exports\": {\n \".\": {\n \"import\": {\n \"types\": \"./dist/index.d.ts\",\n \"default\": \"./dist/index.js\"\n },\n \"require\": {\n \"types\": \"./dist/index.d.cts\",\n \"default\": \"./dist/index.cjs\"\n }\n },\n \"./core\": {\n \"import\": {\n \"types\": \"./dist/core.d.ts\",\n \"default\": \"./dist/core.js\"\n },\n \"require\": {\n \"types\": \"./dist/core.d.cts\",\n \"default\": \"./dist/core.cjs\"\n }\n },\n \"./astro\": {\n \"import\": {\n \"types\": \"./dist/adapters/astro/index.d.ts\",\n \"default\": \"./dist/adapters/astro/index.js\"\n }\n },\n \"./nextjs\": {\n \"import\": {\n \"types\": \"./dist/adapters/nextjs/index.d.ts\",\n \"default\": \"./dist/adapters/nextjs/index.js\"\n }\n },\n \"./sveltekit\": {\n \"import\": {\n \"types\": \"./dist/adapters/sveltekit/index.d.ts\",\n \"default\": \"./dist/adapters/sveltekit/index.js\"\n }\n },\n \"./nuxt\": {\n \"import\": {\n \"types\": \"./dist/adapters/nuxt/index.d.ts\",\n \"default\": \"./dist/adapters/nuxt/index.js\"\n }\n },\n \"./nuxt-module\": {\n \"import\": {\n \"types\": \"./dist/adapters/nuxt/module.d.ts\",\n \"default\": \"./dist/adapters/nuxt/module.js\"\n }\n },\n \"./react\": {\n \"import\": {\n \"types\": \"./dist/adapters/react/index.d.ts\",\n \"default\": \"./dist/adapters/react/index.js\"\n }\n },\n \"./vue\": {\n \"import\": {\n \"types\": \"./dist/adapters/vue/index.d.ts\",\n \"default\": \"./dist/adapters/vue/index.js\"\n }\n },\n \"./codegen\": {\n \"import\": {\n \"types\": \"./dist/codegen.d.ts\",\n \"default\": \"./dist/codegen.js\"\n },\n \"require\": {\n \"types\": \"./dist/codegen.d.cts\",\n \"default\": \"./dist/codegen.cjs\"\n }\n },\n \"./codegen/astro\": {\n \"import\": {\n \"types\": \"./dist/codegen-astro.d.ts\",\n \"default\": \"./dist/codegen-astro.js\"\n }\n },\n \"./annotate\": {\n \"import\": {\n \"types\": \"./dist/annotate.d.ts\",\n \"default\": \"./dist/annotate.js\"\n }\n },\n \"./doctor\": {\n \"import\": {\n \"types\": \"./dist/doctor.d.ts\",\n \"default\": \"./dist/doctor.js\"\n }\n },\n \"./migrate\": {\n \"import\": {\n \"types\": \"./dist/migrate.d.ts\",\n \"default\": \"./dist/migrate.js\"\n }\n },\n \"./payload\": {\n \"import\": {\n \"types\": \"./dist/payload.d.ts\",\n \"default\": \"./dist/payload.js\"\n },\n \"require\": {\n \"types\": \"./dist/payload.d.cts\",\n \"default\": \"./dist/payload.cjs\"\n }\n },\n \"./server\": {\n \"import\": {\n \"types\": \"./dist/server.d.ts\",\n \"default\": \"./dist/server.js\"\n },\n \"require\": {\n \"types\": \"./dist/server.d.cts\",\n \"default\": \"./dist/server.cjs\"\n }\n },\n \"./client\": {\n \"import\": {\n \"types\": \"./dist/client.d.ts\",\n \"default\": \"./dist/client.js\"\n },\n \"require\": {\n \"types\": \"./dist/client.d.cts\",\n \"default\": \"./dist/client.cjs\"\n }\n },\n \"./structural\": {\n \"import\": {\n \"types\": \"./dist/structural.d.ts\",\n \"default\": \"./dist/structural.js\"\n },\n \"require\": {\n \"types\": \"./dist/structural.d.cts\",\n \"default\": \"./dist/structural.cjs\"\n }\n },\n \"./lexical\": {\n \"import\": {\n \"types\": \"./dist/lexical.d.ts\",\n \"default\": \"./dist/lexical.js\"\n },\n \"require\": {\n \"types\": \"./dist/lexical.d.cts\",\n \"default\": \"./dist/lexical.cjs\"\n }\n },\n \"./plugins\": {\n \"import\": {\n \"types\": \"./dist/plugins.d.ts\",\n \"default\": \"./dist/plugins.js\"\n },\n \"require\": {\n \"types\": \"./dist/plugins.d.cts\",\n \"default\": \"./dist/plugins.cjs\"\n }\n },\n \"./lean\": {\n \"import\": {\n \"types\": \"./dist/lean.d.ts\",\n \"default\": \"./dist/lean.js\"\n },\n \"require\": {\n \"types\": \"./dist/lean.d.cts\",\n \"default\": \"./dist/lean.cjs\"\n }\n },\n \"./fragment\": {\n \"import\": {\n \"types\": \"./dist/fragment.d.ts\",\n \"default\": \"./dist/fragment.js\"\n },\n \"require\": {\n \"types\": \"./dist/fragment.d.cts\",\n \"default\": \"./dist/fragment.cjs\"\n }\n },\n \"./astro/RichText.astro\": \"./dist/adapters/astro/RichText.astro\",\n \"./astro/PreviewBoundary.astro\": \"./dist/adapters/astro/PreviewBoundary.astro\",\n \"./astro/middleware-entry\": {\n \"import\": {\n \"types\": \"./dist/adapters/astro/middleware-entry.d.ts\",\n \"default\": \"./dist/adapters/astro/middleware-entry.js\"\n }\n },\n \"./package.json\": \"./package.json\"\n },\n \"bin\": {\n \"pll-codegen\": \"./dist/codegen-cli.js\",\n \"pll\": \"./dist/doctor-cli.js\"\n },\n \"files\": [\n \"dist\",\n \"README.md\",\n \"LICENSE\"\n ],\n \"sideEffects\": false,\n \"scripts\": {\n \"build:runtime\": \"node -e \\\"const c=require('node:child_process'),e={...process.env};if(!e.SOURCE_DATE_EPOCH){const g=c.spawnSync('git',['show','-s','--format=%ct','HEAD'],{encoding:'utf8'});if(g.status===0)e.SOURCE_DATE_EPOCH=g.stdout.trim()}process.exit(c.spawnSync(process.execPath,['--import','tsx',process.argv[1]],{stdio:'inherit',env:e}).status??1)\\\" scripts/build-runtime.ts\",\n \"build\": \"npm run build:runtime && tsx scripts/build-dist.ts && npm run build:assets && npm run test:bundle && npm run test:treeshake && npm run test:edge && npm run test:interaction && npm run test:protocol-semantics\",\n \"build:assets\": \"node -e \\\"const fs=require('node:fs');for(const f of ['RichText','PreviewBoundary'])fs.copyFileSync('src/adapters/astro/'+f+'.astro','dist/adapters/astro/'+f+'.astro')\\\"\",\n \"dev\": \"tsup --watch\",\n \"pretest\": \"npm run build:runtime\",\n \"test\": \"vitest run\",\n \"test:watch\": \"vitest\",\n \"test:unit\": \"vitest run tests/unit\",\n \"test:integration\": \"vitest run tests/integration\",\n \"test:e2e\": \"playwright test\",\n \"check:fixtures\": \"tsx scripts/check-fixture-freshness.ts\",\n \"check:generated\": \"tsx scripts/check-generated-runtime.ts\",\n \"test:e2e:real-payload\": \"playwright test --config playwright.real-payload.config.ts\",\n \"test:a11y\": \"playwright test tests/e2e/specs/accessibility.spec.ts\",\n \"test:soak\": \"playwright test --config playwright.soak.config.ts\",\n \"test:browser-bench\": \"playwright test --config playwright.bench.config.ts\",\n \"test:bench\": \"vitest bench tests/benchmarks\",\n \"test:bench:codspeed\": \"vitest bench --run --config vitest.bench.config.ts\",\n \"test:bundle\": \"tsx scripts/check-bundle-size.ts\",\n \"test:interaction\": \"tsx scripts/check-interaction-budgets.ts\",\n \"test:protocol-semantics\": \"tsx scripts/check-protocol-semantics.ts\",\n \"test:upstream-findings\": \"tsx scripts/check-upstream-findings.ts\",\n \"test:treeshake\": \"tsx scripts/check-tree-shaking.ts\",\n \"test:edge\": \"NODE_OPTIONS='--experimental-vm-modules --no-warnings' tsx scripts/check-edge-runtime.ts\",\n \"compat:check\": \"tsx scripts/compat-table.ts --check\",\n \"compat:write\": \"tsx scripts/compat-table.ts --write\",\n \"compat:refresh\": \"tsx scripts/compat-table.ts --refresh\",\n \"diagnostics:check\": \"tsx scripts/diagnostic-table.ts --check\",\n \"test:package\": \"tsx scripts/check-package.ts\",\n \"audit:gate\": \"tsx scripts/audit-gate.ts\",\n \"test:smoke\": \"tsx scripts/post-publish-smoke.ts\",\n \"test:coverage\": \"vitest run --coverage\",\n \"test:coverage:diff\": \"tsx scripts/coverage-policy.ts\",\n \"test:policy\": \"tsx scripts/test-policy.ts\",\n \"test:architecture\": \"tsx scripts/architecture-policy.ts && tsx scripts/check-complexity.ts && tsx scripts/check-trusted-core.ts && tsx scripts/compare-scope.ts --check && tsx scripts/workflow-contracts.ts && tsx scripts/docs-contracts.ts && knip --no-progress --treat-config-hints-as-errors\",\n \"test:property\": \"vitest run tests/unit/property\",\n \"test:mutation\": \"stryker run stryker.config.js\",\n \"test:mutation:policy:pr\": \"tsx scripts/mutation-policy.ts --policy quality/mutation-policy-pr.json --report test-results/stryker-pr.json\",\n \"test:mutation:policy:core\": \"tsx scripts/mutation-policy.ts --policy quality/mutation-policy-core.json --report test-results/stryker-core.json\",\n \"test:mutation:policy\": \"tsx scripts/mutation-policy.ts\",\n \"test:leak\": \"node --expose-gc --import tsx scripts/leak-soak.ts\",\n \"test:leak:quick\": \"node --expose-gc --import tsx scripts/leak-soak.ts --quick\",\n \"api:update\": \"npm run build && tsx scripts/check-package.ts --update-api-reports\",\n \"typecheck\": \"tsc --noEmit\",\n \"lint\": \"eslint .\",\n \"lint:fix\": \"eslint . --fix\",\n \"format\": \"prettier --write \\\"src/**/*.ts\\\" \\\"tests/**/*.ts\\\" \\\"scripts/**/*.ts\\\" \\\"*.{js,cjs,mjs,ts,json,jsonc,yml,yaml,md}\\\" \\\"quality/**/*.json\\\" \\\"docs/**/*.md\\\" \\\"type-tests/**/*.md\\\" \\\".prettierrc.json\\\" \\\".changeset/*.{json,md}\\\" \\\".github/**/*.{yml,yaml,json}\\\" \\\"examples/**/*.{ts,tsx,js,cjs,mjs,json}\\\" && prettier --write \\\"type-tests/packed/*.fixture\\\" --parser typescript\",\n \"format:check\": \"prettier --check \\\"src/**/*.ts\\\" \\\"tests/**/*.ts\\\" \\\"scripts/**/*.ts\\\" \\\"*.{js,cjs,mjs,ts,json,jsonc,yml,yaml,md}\\\" \\\"quality/**/*.json\\\" \\\"docs/**/*.md\\\" \\\"type-tests/**/*.md\\\" \\\".prettierrc.json\\\" \\\".changeset/*.{json,md}\\\" \\\".github/**/*.{yml,yaml,json}\\\" \\\"examples/**/*.{ts,tsx,js,cjs,mjs,json}\\\" && prettier --check \\\"type-tests/packed/*.fixture\\\" --parser typescript\",\n \"check\": \"npm run typecheck && npm run lint && npm run format:check && npm run test:policy && npm run test:architecture && npm run compat:check && npm run diagnostics:check && npm run test\",\n \"prepublishOnly\": \"npm run build && npm run check && npm run format:check && npm run test:package\",\n \"changeset\": \"changeset\",\n \"version\": \"changeset version && tsx scripts/sync-lockfile-metadata.ts && npm run build:runtime\",\n \"release\": \"tsx scripts/publish-artifact.ts\",\n \"test:docs\": \"tsx scripts/docs-contracts.ts\"\n },\n \"devDependencies\": {\n \"@arethetypeswrong/cli\": \"^0.18.5\",\n \"@axe-core/playwright\": \"^4.13.0\",\n \"@changesets/cli\": \"^2.31.1\",\n \"@codspeed/vitest-plugin\": \"^5.7.1\",\n \"@eslint/js\": \"^10.0.1\",\n \"@fast-check/vitest\": \"^0.4.1\",\n \"@microsoft/api-extractor\": \"^7.58.12\",\n \"@payloadcms/live-preview\": \"^3.88.0\",\n \"@playwright/test\": \"^1.62.1\",\n \"@stryker-mutator/core\": \"^9.6.1\",\n \"@stryker-mutator/vitest-runner\": \"^9.6.1\",\n \"@testing-library/react\": \"^16.3.3\",\n \"@types/jsdom\": \"^30.0.0\",\n \"@types/node\": \"^22.20.1\",\n \"@types/react\": \"^19.2.18\",\n \"@types/react-dom\": \"^19.2.7\",\n \"@vitest/coverage-v8\": \"^4.1.11\",\n \"esbuild\": \"^0.28.2\",\n \"eslint\": \"^10.8.1\",\n \"fast-check\": \"^4.9.0\",\n \"globals\": \"^17.11.0\",\n \"jsdom\": \"^29.1.1\",\n \"knip\": \"^6.32.2\",\n \"prettier\": \"^3.9.6\",\n \"publint\": \"^0.3.23\",\n \"react\": \"^19.2.8\",\n \"react-dom\": \"^19.2.8\",\n \"terser\": \"^5.46.1\",\n \"ts-morph\": \"^28.0.0\",\n \"tsup\": \"^8.5.1\",\n \"tsx\": \"^4.23.12\",\n \"typescript\": \"^5.9.3\",\n \"typescript-eslint\": \"^8.67.0\",\n \"vite\": \"^7.3.6\",\n \"vitest\": \"^4.1.11\",\n \"vue\": \"^3.5.42\",\n \"yaml\": \"^2.9.0\"\n },\n \"overrides\": {\n \"qs\": \"6.15.3\",\n \"tsup\": {\n \"esbuild\": \"0.28.2\"\n }\n },\n \"allowScripts\": {\n \"esbuild@0.28.2\": true,\n \"fsevents@2.3.2\": false,\n \"fsevents@2.3.3\": false\n },\n \"keywords\": [\n \"astro\",\n \"astro-payload\",\n \"astro-cms\",\n \"astro-integration\",\n \"astro-live-preview\",\n \"payload\",\n \"payload-cms\",\n \"payload-live-preview\",\n \"live-preview\",\n \"preview\",\n \"cms\",\n \"headless\",\n \"headless-cms\",\n \"lexical\",\n \"sveltekit\",\n \"nuxt\",\n \"nextjs\",\n \"react\",\n \"vue\",\n \"ssr\",\n \"framework-agnostic\"\n ],\n \"peerDependencies\": {\n \"astro\": \">=4.0.0 <8.0.0\",\n \"react\": \">=18\",\n \"react-dom\": \">=18\",\n \"svelte\": \">=5\",\n \"ts-morph\": \"^28.0.0\",\n \"vite\": \">=5.4.0 <9.0.0\",\n \"vue\": \">=3.3\"\n },\n \"peerDependenciesMeta\": {\n \"astro\": {\n \"optional\": true\n },\n \"react\": {\n \"optional\": true\n },\n \"react-dom\": {\n \"optional\": true\n },\n \"svelte\": {\n \"optional\": true\n },\n \"ts-morph\": {\n \"optional\": true\n },\n \"vue\": {\n \"optional\": true\n },\n \"vite\": {\n \"optional\": true\n }\n },\n \"engines\": {\n \"node\": \">=20.19.0\"\n },\n \"publishConfig\": {\n \"access\": \"public\",\n \"provenance\": true\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"https://github.com/relative23/payload-live-preview.git\"\n },\n \"bugs\": {\n \"url\": \"https://github.com/relative23/payload-live-preview/issues\"\n },\n \"homepage\": \"https://github.com/relative23/payload-live-preview#readme\"\n}\n","/** The package version, read from package.json so the entries and the inline runtime cannot drift. */\n\nimport pkg from '../package.json' with { type: 'json' };\n\n/** @internal */\nexport const VERSION: string = pkg.version;\n","/** The locale for `Intl` renders before Payload names one: `<html lang>`, then `navigator.language`, then `'en'`. */\n\nconst FALLBACK_LOCALE = 'en';\n\n/** @internal */\nexport function detectInitialLocale(): string {\n return readHtmlLang() ?? readNavigatorLanguage() ?? FALLBACK_LOCALE;\n}\n\nfunction readHtmlLang(): string | undefined {\n if (typeof document === 'undefined') return undefined;\n const lang = document.documentElement.getAttribute('lang');\n return lang === null || lang.length === 0 ? undefined : lang;\n}\n\nfunction readNavigatorLanguage(): string | undefined {\n if (typeof navigator === 'undefined') return undefined;\n const lang = navigator.language;\n return typeof lang === 'string' && lang.length > 0 ? lang : undefined;\n}\n","/**\n * One polite `aria-live` region per document, leased by every announcer on\n * the page, for connect / update / disconnect announcements. The message\n * clears itself after a moment so a repeated string is heard again.\n */\n\nimport { detectInitialLocale } from '@detection/locale';\n\nconst ELEMENT_ID = 'payload-live-preview-a11y';\nconst CLEAR_DELAY_MS = 1500;\nconst STYLE =\n 'position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;' +\n 'clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0';\n\nfunction isGerman(locale: string): boolean {\n return /^de(?:[-_]|$)/i.test(locale);\n}\n\n/** Shared per document; reference-counted so one client cannot remove another's region. */\ninterface DocumentLease {\n element: HTMLElement | null;\n /** Created by this package (removable) rather than adopted from the page. */\n owned: boolean;\n messageNode: Text | null;\n refs: number;\n timer: ReturnType<typeof setTimeout> | null;\n}\n\nconst documentLeases = new WeakMap<Document, DocumentLease>();\n\nfunction acquireDocumentLease(activeDocument: Document): DocumentLease {\n let lease = documentLeases.get(activeDocument);\n if (lease === undefined) {\n lease = { element: null, owned: false, messageNode: null, refs: 0, timer: null };\n documentLeases.set(activeDocument, lease);\n }\n lease.refs += 1;\n return lease;\n}\n\n/** Remove only the package-owned message node, never consumer children. */\nfunction clearLeaseMessage(lease: DocumentLease): void {\n if (lease.timer !== null) {\n clearTimeout(lease.timer);\n lease.timer = null;\n }\n lease.messageNode?.remove();\n lease.messageNode = null;\n}\n\nexport class A11yAnnouncer {\n private readonly german: boolean;\n private readonly document: Document | null;\n private lease: DocumentLease | null = null;\n\n constructor(locale?: string, targetDocument?: Document | null) {\n const activeDocument = targetDocument ?? (typeof document === 'undefined' ? null : document);\n const documentLocale = activeDocument?.documentElement.getAttribute('lang') ?? '';\n this.german = isGerman(\n locale ?? (documentLocale.length > 0 ? documentLocale : detectInitialLocale()),\n );\n this.document = activeDocument;\n // The region mounts on the first announcement: a <head> inline script runs before `body` exists.\n }\n\n /** The shared region, or `null` without a body yet (announcements are then dropped). */\n private mount(): HTMLElement | null {\n const activeDocument = this.document;\n if (activeDocument?.body == null) return null;\n this.lease ??= acquireDocumentLease(activeDocument);\n const lease = this.lease;\n const leased = lease.element;\n if (leased?.isConnected && leased.ownerDocument === activeDocument) return leased;\n // The host removed or replaced the region between announcements.\n if (leased !== null) {\n const owned = lease.owned;\n clearLeaseMessage(lease);\n if (owned) leased.remove();\n }\n let element = activeDocument.getElementById(ELEMENT_ID);\n lease.owned = element === null;\n if (element === null) {\n element = activeDocument.createElement('div');\n element.id = ELEMENT_ID;\n element.setAttribute('role', 'status');\n element.setAttribute('aria-live', 'polite');\n element.setAttribute('aria-atomic', 'true');\n element.setAttribute('style', STYLE);\n activeDocument.body.appendChild(element);\n }\n lease.element = element;\n return element;\n }\n\n announceConnected(): void {\n this.say(this.german ? 'Vorschau verbunden' : 'Live preview connected');\n }\n\n announceDisconnected(): void {\n this.say(this.german ? 'Vorschau getrennt' : 'Live preview disconnected');\n }\n\n announceUpdate(count: number): void {\n if (count <= 0) return;\n this.say(\n this.german\n ? `${String(count)} ${count === 1 ? 'Änderung' : 'Änderungen'} angewendet`\n : `${String(count)} ${count === 1 ? 'change' : 'changes'} applied`,\n );\n }\n\n /** Release the lease; the last release removes an owned region but leaves an adopted one. Idempotent. */\n detach(): void {\n const lease = this.lease;\n const activeDocument = this.document;\n if (lease === null || activeDocument === null) return;\n this.lease = null;\n lease.refs -= 1;\n if (lease.refs > 0) return;\n const element = lease.element;\n if (element !== null) clearLeaseMessage(lease);\n if (lease.owned) element?.remove();\n lease.element = null;\n documentLeases.delete(activeDocument);\n }\n\n private say(message: string): void {\n const element = this.mount();\n const lease = this.lease;\n if (element === null || lease === null) return;\n let messageNode = lease.messageNode;\n if (messageNode?.parentNode !== element) {\n // A dedicated text node leaves consumer-owned children untouched.\n messageNode?.remove();\n messageNode = element.ownerDocument.createTextNode(\n element.hasChildNodes() ? ` ${message}` : message,\n );\n lease.messageNode = messageNode;\n element.appendChild(messageNode);\n } else {\n messageNode.data = messageNode.previousSibling === null ? message : ` ${message}`;\n }\n if (lease.timer !== null) clearTimeout(lease.timer);\n const timer = setTimeout(() => {\n if (lease.timer === timer && lease.element === element) clearLeaseMessage(lease);\n }, CLEAR_DELAY_MS);\n lease.timer = timer;\n }\n}\n","/**\n * Validates the `fieldSchemaJSON` the admin sends. Entries that fail\n * validation are dropped, never thrown: a Payload/runtime version mismatch\n * must not take the preview down.\n */\n\nimport type { PayloadBlockSchema, PayloadFieldSchema } from '@/types/payload-protocol';\n\nexport function parseFieldSchema(raw: unknown): readonly PayloadFieldSchema[] {\n if (!Array.isArray(raw)) return [];\n const out: PayloadFieldSchema[] = [];\n for (const entry of raw) {\n const parsed = parseFieldEntry(entry);\n if (parsed) out.push(parsed);\n }\n return out;\n}\n\nfunction parseFieldEntry(value: unknown): PayloadFieldSchema | undefined {\n if (typeof value !== 'object' || value === null) return undefined;\n const record = value as Record<string, unknown>;\n const name = record['name'];\n const type = record['type'];\n if (typeof name !== 'string' || name.length === 0) return undefined;\n if (typeof type !== 'string' || type.length === 0) return undefined;\n\n const fields = parseFieldSchema(record['fields']);\n const blocks = parseBlockSchema(record['blocks']);\n\n const result: Record<string, unknown> = { ...record, name, type };\n if (fields.length > 0) result['fields'] = fields;\n else delete result['fields'];\n if (blocks.length > 0) result['blocks'] = blocks;\n else delete result['blocks'];\n\n return result as unknown as PayloadFieldSchema;\n}\n\nfunction parseBlockSchema(raw: unknown): readonly PayloadBlockSchema[] {\n if (!Array.isArray(raw)) return [];\n const out: PayloadBlockSchema[] = [];\n for (const entry of raw) {\n if (typeof entry !== 'object' || entry === null) continue;\n const record = entry as Record<string, unknown>;\n const slug = record['slug'];\n if (typeof slug !== 'string' || slug.length === 0) continue;\n const fields = parseFieldSchema(record['fields']);\n out.push({ ...record, slug, fields });\n }\n return out;\n}\n","/** Shape guards for the messages the bus accepts. `null` counts as absent, as JSON bridges send it. */\n\nimport type {\n PayloadDocumentEventMessage,\n PayloadFieldSchema,\n PayloadLivePreviewMessage,\n} from '@/types/payload-protocol';\nimport { parseFieldSchema } from '@schema/parser';\n\nexport function isObjectMessage(value: unknown): value is { type: string } {\n return (\n typeof value === 'object' && value !== null && 'type' in value && typeof value.type === 'string'\n );\n}\n\n/** A `payload-live-preview` message: `data` a plain object when present, scalars of the right type or absent. */\nexport function isLivePreviewMessage(value: { type: string }): value is PayloadLivePreviewMessage {\n const v = value as Record<string, unknown>;\n if (v['data'] !== undefined && v['data'] !== null && !isPlainObject(v['data'])) return false;\n return (\n optionalTypeOk(v['fieldSchemaJSON'], (x) => Array.isArray(x)) &&\n optionalTypeOk(v['globalSlug'], (x) => typeof x === 'string') &&\n optionalTypeOk(v['collectionSlug'], (x) => typeof x === 'string') &&\n optionalTypeOk(v['locale'], (x) => typeof x === 'string') &&\n optionalTypeOk(v['ready'], (x) => typeof x === 'boolean') &&\n optionalTypeOk(v['previewToken'], (x) => typeof x === 'string') &&\n optionalTypeOk(v['protocolVersion'], (x) => typeof x === 'number')\n );\n}\n\n/** The non-empty field name of a `payload-live-preview-focus` message, else `undefined`. */\nexport function focusFieldOf(value: { type: string }): string | undefined {\n const field = (value as Record<string, unknown>)['field'];\n return typeof field === 'string' && field.length > 0 ? field : undefined;\n}\n\n/** Stock Payload sends only the `type`; custom senders may add the typed fields (omitted, never `null`). */\nexport function isDocumentEventMessage(value: {\n type: string;\n}): value is PayloadDocumentEventMessage {\n const v = value as Record<string, unknown>;\n return (\n optionalFieldOk(v['action'], (x) => x === 'updated' || x === 'created' || x === 'deleted') &&\n optionalFieldOk(v['slug'], (x) => typeof x === 'string') &&\n optionalFieldOk(v['id'], (x) => typeof x === 'string' || Number.isFinite(x))\n );\n}\n\nfunction optionalFieldOk(value: unknown, check: (v: unknown) => boolean): boolean {\n return value === undefined || check(value);\n}\n\nfunction optionalTypeOk(value: unknown, check: (v: unknown) => boolean): boolean {\n return value === undefined || value === null || check(value);\n}\n\nexport function isPlainObject(value: unknown): value is Record<string, unknown> {\n if (typeof value !== 'object' || value === null) return false;\n const prototype = Object.getPrototypeOf(value) as object | null;\n return prototype === null || Object.getPrototypeOf(prototype) === null;\n}\n\nconst NULL_AS_ABSENT_FIELDS = [\n 'data',\n 'fieldSchemaJSON',\n 'globalSlug',\n 'collectionSlug',\n 'locale',\n 'ready',\n 'previewToken',\n 'protocolVersion',\n] as const satisfies readonly (keyof PayloadLivePreviewMessage)[];\n\n/**\n * Drop `null` optionals so downstream sees the strict public type, and parse\n * the field schema entry by entry (malformed entries are dropped). Unknown\n * fields stay, for protocol evolution.\n */\nexport function normalizeLivePreviewMessage(\n message: PayloadLivePreviewMessage,\n): PayloadLivePreviewMessage {\n const normalized = { ...message };\n for (const field of NULL_AS_ABSENT_FIELDS) {\n const wireValue: unknown = Reflect.get(normalized, field);\n if (wireValue === null) Reflect.deleteProperty(normalized, field);\n }\n if (!Array.isArray(normalized.fieldSchemaJSON)) return normalized;\n let fieldSchemaJSON: readonly PayloadFieldSchema[];\n try {\n fieldSchemaJSON = parseFieldSchema(normalized.fieldSchemaJSON);\n } catch {\n fieldSchemaJSON = [];\n }\n return { ...normalized, fieldSchemaJSON };\n}\n","/**\n * Protocol negotiation. A capability is granted either by the version a peer\n * announces or by observation, since the stock Payload admin announces none:\n * what it can do is read off the messages it sends. See ADR 0010.\n */\n\n/** Bumped only when this library's understanding of the wire format changes. @internal */\nexport const LIBRARY_PROTOCOL_VERSION = 4;\n\n/** How a capability becomes active. @internal */\nexport type CapabilitySource = 'version' | 'observed';\n\n/** @internal */\nexport interface CapabilityDeclaration {\n /** Enabled once the negotiated version reaches this (for announced peers). */\n readonly since: number;\n /** The wire signal that grants this capability to a peer announcing no version. */\n readonly observed?:\n 'schema' | 'locale' | 'preview-token' | 'document-event' | 'relationship-event';\n}\n\n/** What activates each capability; the prose lives in `CAPABILITY_DOCUMENTATION`. */\nexport const CAPABILITY_DECLARATIONS = {\n basic: { since: 1 },\n 'schema-json': { since: 2, observed: 'schema' },\n locale: { since: 2, observed: 'locale' },\n 'preview-token': { since: 3, observed: 'preview-token' },\n 'nested-arrays': { since: 4 },\n 'recursive-diffs': { since: 4 },\n 'document-events': { since: 4, observed: 'document-event' },\n 'relationship-events': { since: 4, observed: 'relationship-event' },\n} as const satisfies Record<string, CapabilityDeclaration>;\n\nexport type ProtocolCapability = keyof typeof CAPABILITY_DECLARATIONS;\n\n/** Every declared capability, in declaration order. @internal */\nexport const PROTOCOL_CAPABILITIES = Object.keys(\n CAPABILITY_DECLARATIONS,\n) as readonly ProtocolCapability[];\n\nexport interface ProtocolNegotiation {\n /** This library's protocol version. */\n readonly ours: number;\n /** The remote party's version, when it announced one. */\n readonly theirs: number | undefined;\n /** `min(ours, theirs ?? 1)` — the version both sides actually share. */\n readonly negotiated: number;\n /** Capabilities active at the negotiated version or seen on the wire. */\n readonly capabilities: ReadonlySet<ProtocolCapability>;\n /** The subset that was observed on the wire rather than granted by version. */\n readonly observed: ReadonlySet<ProtocolCapability>;\n}\n\n/** Deterministic; the runtime re-runs it whenever either input changes. */\nexport function negotiateProtocol(\n theirs: number | undefined,\n observed: Iterable<ProtocolCapability> = [],\n): ProtocolNegotiation {\n const sanitisedTheirs =\n typeof theirs === 'number' && Number.isFinite(theirs) && theirs >= 1\n ? Math.floor(theirs)\n : undefined;\n const effectiveTheirs = sanitisedTheirs ?? 1;\n const negotiated = Math.min(LIBRARY_PROTOCOL_VERSION, effectiveTheirs);\n const seen = new Set<ProtocolCapability>(observed);\n const capabilities = new Set<ProtocolCapability>();\n for (const capability of PROTOCOL_CAPABILITIES) {\n if (negotiated >= CAPABILITY_DECLARATIONS[capability].since || seen.has(capability)) {\n capabilities.add(capability);\n }\n }\n return {\n ours: LIBRARY_PROTOCOL_VERSION,\n ...(sanitisedTheirs !== undefined ? { theirs: sanitisedTheirs } : { theirs: undefined }),\n negotiated,\n capabilities,\n observed: seen,\n };\n}\n\n/** @internal */\nexport function hasCapability(\n negotiation: ProtocolNegotiation,\n capability: ProtocolCapability,\n): boolean {\n return negotiation.capabilities.has(capability);\n}\n\n/** The capabilities a single message demonstrates, by its shape alone. */\nexport function observeCapabilities(message: {\n readonly fieldSchemaJSON?: unknown;\n readonly locale?: unknown;\n readonly previewToken?: unknown;\n readonly externallyUpdatedRelationship?: unknown;\n}): readonly ProtocolCapability[] {\n const seen: ProtocolCapability[] = [];\n if (Array.isArray(message.fieldSchemaJSON)) seen.push('schema-json');\n if (typeof message.locale === 'string') seen.push('locale');\n if (typeof message.previewToken === 'string') seen.push('preview-token');\n if (\n typeof message.externallyUpdatedRelationship === 'object' &&\n message.externallyUpdatedRelationship !== null\n ) {\n seen.push('relationship-events');\n }\n return seen;\n}\n","/**\n * Detect an invalid async result in a synchronous extension point.\n *\n * Rejected native Promises otherwise become unhandled after the caller falls\n * back synchronously. Assimilating the result through a handled Promise keeps\n * that contract violation observable only through the runtime's explicit\n * error channel.\n */\nexport function observeThenableResult(value: unknown): boolean {\n if ((typeof value !== 'object' || value === null) && typeof value !== 'function') return false;\n if (typeof (value as { readonly then?: unknown }).then !== 'function') return false;\n void Promise.resolve(value).catch(() => undefined);\n return true;\n}\n","/**\n * postMessage ingress: origin and source checks, per-type shape guards, the\n * ordered preview-token validation queue, and the `ready` handshake. The bus\n * never throws; a rejected message is dropped or reported via `onInvalid`.\n * Consumer callbacks may detach or re-attach the bus synchronously, so\n * anything that runs after one re-checks the generation it started in.\n * See ADR 0004.\n */\n\nimport type {\n PayloadDocumentEventMessage,\n PayloadLivePreviewMessage,\n} from '@/types/payload-protocol';\nimport {\n focusFieldOf,\n isDocumentEventMessage,\n isLivePreviewMessage,\n isObjectMessage,\n isPlainObject,\n normalizeLivePreviewMessage,\n} from './message-guards';\nimport { LIBRARY_PROTOCOL_VERSION } from './protocol-version';\nimport { observeThenableResult } from './thenable';\n\nexport type OriginMatcher = (origin: string) => boolean;\n\n/** Identity of a data-bearing update: `revision` is monotonic, `generation` names the listener attachment. */\nexport interface MessageRevision {\n readonly revision: number;\n readonly generation: number;\n}\nexport function sameRevision(a: MessageRevision, b: MessageRevision): boolean {\n return a.generation === b.generation && a.revision === b.revision;\n}\n\nexport type InvalidReason = 'origin' | 'shape' | 'type' | 'token' | 'source';\n\nexport interface MessageHandlers {\n /** A validated update; data-bearing ones carry their revision, ready handshakes do not. */\n readonly onUpdate: (\n msg: PayloadLivePreviewMessage,\n origin: string,\n messageRevision?: MessageRevision,\n ) => void;\n readonly onDocumentEvent: (msg: PayloadDocumentEventMessage, origin: string) => void;\n /** The admin reports the cursor moved into a field (reveal tier 2). */\n readonly onFocusField?: (field: string, origin: string) => void;\n readonly onInvalid?: (reason: InvalidReason, origin: string) => void;\n /** `'parent-or-opener'` refuses every window but the framing/opening one, even from an allowed origin. */\n readonly sourcePolicy?: 'any' | 'parent-or-opener';\n /**\n * Gate for data-bearing updates. Verdicts commit in arrival order, so an\n * earlier update is dispatched before a later one even when its validation\n * resolves later; an error counts as rejection.\n */\n readonly validateToken?: (\n token: string | undefined,\n origin: string,\n ) => boolean | Promise<boolean>;\n}\n\n/** One entry of the validation queue: a singly linked list in arrival order. */\ninterface PendingValidation {\n readonly generation: number;\n readonly message: PayloadLivePreviewMessage;\n readonly origin: string;\n readonly messageRevision: MessageRevision | undefined;\n /** `undefined` until the validator settled; only literal `true` approves. */\n verdict: boolean | undefined;\n next: PendingValidation | undefined;\n}\n\nexport class MessageBus {\n private readonly matcher: OriginMatcher;\n private readonly handlers: MessageHandlers;\n private boundListener: ((event: MessageEvent) => void) | undefined = undefined;\n private attachedTarget: Window | undefined = undefined;\n private generation = 0;\n private revision = 0;\n private queueHead: PendingValidation | undefined = undefined;\n private queueTail: PendingValidation | undefined = undefined;\n\n constructor(matcher: OriginMatcher, handlers: MessageHandlers) {\n this.matcher = matcher;\n this.handlers = handlers;\n }\n\n /** Start listening on `target`. Idempotent. */\n attach(target: Window = window): void {\n if (this.attachedTarget !== undefined) return;\n let committed = false;\n const listener = (event: MessageEvent): void => {\n // Each attachment owns its listener; a stale one must not borrow the new generation.\n if (!committed || this.boundListener !== listener) return;\n const generation = this.generation;\n try {\n this.receive(event, generation, target);\n } catch {\n // A synthetic event can carry throwing accessors; that is a shape failure.\n let origin: string;\n try {\n origin = event.origin;\n } catch {\n origin = '';\n }\n this.reportInvalid('shape', origin, generation);\n }\n };\n this.generation += 1;\n this.resetQueue();\n this.attachedTarget = target;\n this.boundListener = listener;\n try {\n target.addEventListener('message', listener);\n } catch (error) {\n // Invalidate before rollback: a hook may already have attached a newer generation.\n if (this.boundListener === listener) {\n this.attachedTarget = undefined;\n this.boundListener = undefined;\n this.resetQueue();\n }\n try {\n target.removeEventListener('message', listener);\n } catch {\n // Keep the original failure.\n }\n throw error;\n }\n if (this.boundListener === listener) {\n committed = true;\n } else {\n try {\n target.removeEventListener('message', listener);\n } catch {\n // The listener is identity-gated above even if removal fails.\n }\n }\n }\n\n /** Stop listening. Idempotent. */\n detach(): void {\n const target = this.attachedTarget;\n const listener = this.boundListener;\n if (target === undefined || listener === undefined) return;\n // Invalidate first so a listener already on the stack sees an obsolete generation.\n this.attachedTarget = undefined;\n this.boundListener = undefined;\n this.resetQueue();\n target.removeEventListener('message', listener);\n }\n\n /** Invalidate pending validations while staying attached (heartbeat expiry). */\n advanceGeneration(): boolean {\n if (this.attachedTarget === undefined) return false;\n this.generation += 1;\n this.resetQueue();\n return true;\n }\n\n /** Post the `ready` handshake to every target for every origin. */\n static sendReady(targets: readonly Window[], origins: readonly string[]): void {\n const payload: PayloadLivePreviewMessage = {\n type: 'payload-live-preview',\n ready: true,\n protocolVersion: LIBRARY_PROTOCOL_VERSION,\n };\n for (const target of targets) {\n for (const origin of origins) {\n try {\n target.postMessage(payload, origin);\n } catch {\n // A malformed origin is the consumer's configuration problem.\n }\n }\n }\n }\n\n private receive(event: MessageEvent, generation: number, target: Window): void {\n const origin = event.origin;\n if (!this.matchesOrigin(origin, generation)) {\n this.reportInvalid('origin', origin, generation);\n return;\n }\n if (!this.matchesSource(event, target)) {\n this.reportInvalid('source', origin, generation);\n return;\n }\n const data: unknown = event.data;\n if (!isObjectMessage(data)) {\n this.reportInvalid('shape', origin, generation);\n return;\n }\n switch (data.type) {\n case 'payload-live-preview':\n if (!isLivePreviewMessage(data)) {\n this.reportInvalid('shape', origin, generation);\n return;\n }\n this.dispatchUpdate(normalizeLivePreviewMessage(data), origin, generation);\n return;\n case 'payload-document-event':\n if (!isDocumentEventMessage(data)) {\n this.reportInvalid('shape', origin, generation);\n return;\n }\n this.invokeHandler(generation, this.handlers.onDocumentEvent, data, origin);\n return;\n case 'payload-live-preview-focus': {\n const field = focusFieldOf(data);\n if (field === undefined) {\n this.reportInvalid('shape', origin, generation);\n return;\n }\n this.invokeHandler(generation, this.handlers.onFocusField, field, origin);\n return;\n }\n default:\n this.reportInvalid('type', origin, generation);\n }\n }\n\n private dispatchUpdate(\n message: PayloadLivePreviewMessage,\n origin: string,\n generation: number,\n ): void {\n const hasUpdateData = isPlainObject(message.data);\n if (!this.isCurrentGeneration(generation)) return;\n // A shape-valid data update consumes its revision before validation; a rejected token leaves a gap.\n const messageRevision = hasUpdateData\n ? { generation, revision: (this.revision += 1) }\n : undefined;\n const validator = this.handlers.validateToken;\n if (!this.isCurrentGeneration(generation)) return;\n if (validator === undefined) {\n this.commitUpdate(message, origin, generation, messageRevision);\n return;\n }\n // The data-less ready handshake carries no token and passes, so the admin learns we listen.\n if (message.ready === true && message.data === undefined) {\n this.commitUpdate(message, origin, generation, undefined);\n return;\n }\n const pending: PendingValidation = {\n generation,\n message,\n origin,\n messageRevision,\n verdict: undefined,\n next: undefined,\n };\n this.enqueue(pending);\n let verdict: unknown;\n try {\n // Invoked eagerly; only the commit waits for earlier queue entries.\n verdict = validator(message.previewToken, origin);\n } catch {\n this.settleValidation(pending, false);\n return;\n }\n if (typeof verdict === 'boolean') {\n this.settleValidation(pending, verdict);\n return;\n }\n // Assimilate any thenable; only literal `true` approves.\n void Promise.resolve(verdict).then(\n (approved) => {\n this.settleValidation(pending, approved === true);\n },\n () => {\n this.settleValidation(pending, false);\n },\n );\n }\n\n private settleValidation(pending: PendingValidation, approved: boolean): void {\n pending.verdict = approved;\n this.drainQueue(pending.generation);\n }\n\n private drainQueue(generation: number): void {\n while (this.isCurrentGeneration(generation)) {\n const pending = this.queueHead;\n if (pending === undefined) return;\n // The matcher may have narrowed since ingress (origin lock); an obsolete\n // origin must not hold the queue head and block the locked origin's work.\n if (!this.matchesOrigin(pending.origin, generation)) {\n if (!this.dequeue(pending)) continue;\n this.reportInvalid('origin', pending.origin, pending.generation);\n continue;\n }\n if (pending.verdict === undefined) return;\n if (!this.dequeue(pending)) continue;\n if (pending.verdict) {\n this.commitUpdate(\n pending.message,\n pending.origin,\n pending.generation,\n pending.messageRevision,\n );\n } else {\n this.reportInvalid('token', pending.origin, pending.generation);\n }\n }\n }\n\n private commitUpdate(\n message: PayloadLivePreviewMessage,\n origin: string,\n generation: number,\n messageRevision: MessageRevision | undefined,\n ): void {\n if (messageRevision === undefined) {\n this.invokeHandler(generation, this.handlers.onUpdate, message, origin);\n } else {\n this.invokeHandler(generation, this.handlers.onUpdate, message, origin, messageRevision);\n }\n }\n\n private reportInvalid(reason: InvalidReason, origin: string, generation: number): void {\n this.invokeHandler(generation, this.handlers.onInvalid, reason, origin);\n }\n\n /** Under `'parent-or-opener'`, whether the event came from the attached window's parent or opener. */\n private matchesSource(event: MessageEvent, target: Window): boolean {\n if (this.handlers.sourcePolicy !== 'parent-or-opener') return true;\n try {\n // Only a window is a source: a missing one matches nothing, not even a missing opener.\n const source: unknown = event.source;\n if (typeof source !== 'object' || source === null) return false;\n const parent = target.parent;\n if (parent !== target && source === parent) return true;\n const opener: unknown = target.opener;\n return source === opener;\n } catch {\n return false;\n }\n }\n\n /** Fail-closed: only literal `true` from the matcher, and only within the generation it ran in. */\n private matchesOrigin(origin: string, generation: number): boolean {\n try {\n const approved: unknown = this.isCurrentGeneration(generation) && this.matcher(origin);\n return approved === true && this.isCurrentGeneration(generation);\n } catch {\n return false;\n }\n }\n\n /** Callbacks run only in a current generation and must not unwind the listener or the drain. */\n private invokeHandler<TArgs extends unknown[]>(\n generation: number,\n handler: ((...args: TArgs) => unknown) | undefined,\n ...args: TArgs\n ): void {\n if (handler === undefined || !this.isCurrentGeneration(generation)) return;\n try {\n observeThenableResult(handler(...args));\n } catch {\n // Isolated by contract.\n }\n }\n\n private isCurrentGeneration(generation: number): boolean {\n return this.attachedTarget !== undefined && this.generation === generation;\n }\n\n private enqueue(pending: PendingValidation): void {\n if (this.queueTail === undefined) this.queueHead = pending;\n else this.queueTail.next = pending;\n this.queueTail = pending;\n }\n\n /** Advance the head past `expected`, unless a matcher reset the queue meanwhile. */\n private dequeue(expected: PendingValidation): boolean {\n if (this.queueHead !== expected) return false;\n this.queueHead = expected.next;\n if (this.queueHead === undefined) this.queueTail = undefined;\n return true;\n }\n\n private resetQueue(): void {\n this.queueHead = undefined;\n this.queueTail = undefined;\n }\n}\n","import { observeThenableResult } from './thenable';\n\n/**\n * Diagnostics are observability, never control flow: a consumer logger may\n * throw or return a rejected thenable, and reporting a failure must not become\n * a second failure. Invocation stays synchronous for ordinary loggers.\n */\nexport function isolateDiagnostic(\n diagnostic: (...args: unknown[]) => unknown,\n): (...args: unknown[]) => void {\n return (...args): void => {\n try {\n observeThenableResult(diagnostic(...args));\n } catch {\n // Diagnostics must not become a second failure boundary.\n }\n };\n}\n\n/** Shared allocation-free default for disabled diagnostic channels. */\nexport function noopDiagnostic(): void {\n // Intentionally empty.\n}\n\n// Access, invocation and thenable inspection all happen inside the wrapper, so\n// a missing or hostile console cannot escape.\nexport const safeConsoleError = isolateDiagnostic((...args) =>\n (console.error as (...values: unknown[]) => unknown)(...args),\n);\n\nexport const safeConsoleWarn = isolateDiagnostic((...args) =>\n (console.warn as (...values: unknown[]) => unknown)(...args),\n);\n\nexport const safeConsoleDebug = isolateDiagnostic((...args) =>\n // eslint-disable-next-line no-console -- best-effort development diagnostics\n (console.debug as (...values: unknown[]) => unknown)(...args),\n);\n","/**\n * The build profile: which features are compiled into the inline runtime.\n *\n * `scripts/build-runtime.ts` builds the runtime twice — once with everything,\n * once with `__LEAN_BUILD__` defined — and the generator embeds whichever the\n * page asked for. The flag is read into a constant so esbuild folds it and\n * drops the branch, and with it every module only that branch referenced. In\n * the programmatic client the define is absent, so nothing is dropped there.\n *\n * A profile is a byte trade, never a behaviour trade in disguise: a page that\n * needs what the lean profile left out is told so (LP0104) instead of quietly\n * doing nothing.\n *\n * The flag itself is not exported. Each guard site reads `__LEAN_BUILD__`\n * directly, in expression position, because that is the only shape esbuild\n * folds — `src/types/build-flags.d.ts` explains why, with what was measured.\n */\n\nimport { safeConsoleWarn } from './diagnostics';\n\n/** What the lean profile leaves out, in the words the documentation uses. */\nexport type OmittedFeature =\n | 'structural arrays'\n | 'array templates'\n | 'server-rendered fragments'\n | 'route refreshes'\n | 'screen-reader announcements'\n | 'auto-binding';\n\nconst HOW_TO_GET_IT: Readonly<Record<OmittedFeature, string>> = {\n 'structural arrays': 'data-payload-type=\"array\" and keyed lists',\n 'array templates': 'data-payload-array-template',\n 'server-rendered fragments': 'data-payload-fragment boundaries',\n 'route refreshes': 'data-payload-strategy=\"route\" and bindings in <head>',\n 'screen-reader announcements': 'the aria-live region',\n 'auto-binding': \"autoBind: 'unique'\",\n};\n\nconst reported = new Set<OmittedFeature>();\n\n/**\n * Report once per feature and per page. The markup is the cause and it does not\n * change between updates, so a second message would only be noise.\n */\nexport function reportOmittedFeature(feature: OmittedFeature): void {\n if (reported.has(feature)) return;\n reported.add(feature);\n safeConsoleWarn(\n `[live-preview] LP0104: this page carries the lean runtime, which leaves out ${feature} ` +\n `(${HOW_TO_GET_IT[feature]}). The elements are left as the server rendered them. ` +\n `Remove \\`runtime: LEAN_RUNTIME\\` to get the full runtime.`,\n );\n}\n","/**\n * What the runtime builds around itself before it starts: the screen-reader\n * announcer, and where the `ready` handshake goes.\n *\n * Apart in this module for two reasons. The announcer is the one dependency the\n * lean profile leaves out, and the guard that drops it has to sit in expression\n * position at the seam (`src/types/build-flags.d.ts`); and `lifecycle.ts` is the\n * runtime's own lifecycle, which stays readable only if the wiring around it\n * lives next door rather than inside.\n */\n\nimport { A11yAnnouncer } from './a11y';\nimport { MessageBus } from './message-bus';\nimport { reportOmittedFeature } from './profile';\nimport type { RuntimeOptions } from './runtime-options';\n\n/**\n * The announcer and its locale table are ~800 bytes gzip the lean profile does\n * without; a page that asked for announcements is told instead (./profile).\n */\nexport function createA11y(options: RuntimeOptions): A11yAnnouncer | null {\n return typeof __LEAN_BUILD__ !== 'undefined' && __LEAN_BUILD__\n ? refuseA11y(options)\n : buildA11y(options);\n}\n\nfunction refuseA11y(options: RuntimeOptions): null {\n if (options.enableA11y !== false) reportOmittedFeature('screen-reader announcements');\n return null;\n}\n\nfunction buildA11y(options: RuntimeOptions): A11yAnnouncer | null {\n if (options.enableA11y === false) return null;\n const root = options.root;\n const targetDocument =\n root === undefined ? undefined : isDocumentRoot(root) ? root : root.ownerDocument;\n return new A11yAnnouncer(options.a11yLocale, targetDocument);\n}\n\n/** Node types are stable across realms; global constructors are not. */\nfunction isDocumentRoot(root: Document | Element): root is Document {\n return root.nodeType === 9;\n}\n\n/** The framing or opening window, which is the only one that asked for a preview. */\nexport function defaultSendReady(origins: readonly string[]): void {\n if (typeof window === 'undefined') return;\n const targets: Window[] = [];\n if (window.parent !== window) targets.push(window.parent);\n if (window.opener instanceof Window) targets.push(window.opener);\n MessageBus.sendReady(targets, origins);\n}\n","/** Drops `undefined`-valued keys, so a literal built from optional inputs satisfies `exactOptionalPropertyTypes`. */\n\nexport type DefinedOnly<T> = { readonly [K in keyof T]-?: Exclude<T[K], undefined> };\n\nexport function definedOnly<T extends object>(source: T): DefinedOnly<T> {\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(source)) {\n if (value !== undefined) result[key] = value;\n }\n return result as DefinedOnly<T>;\n}\n","/**\n * Flattens a parsed field schema into dotted paths (`hero.title`,\n * `sections.*.heading`). Tabs, rows and collapsibles have no name and\n * dissolve into their inner fields.\n */\n\nimport type {\n PayloadBlockSchema,\n PayloadFieldSchema,\n PayloadFieldType,\n} from '@/types/payload-protocol';\n\nexport type SchemaIndex = ReadonlyMap<string, PayloadFieldSchema>;\n\nconst STRUCTURAL_TYPES: ReadonlySet<PayloadFieldType> = new Set<PayloadFieldType>([\n 'tabs',\n 'row',\n 'collapsible',\n]);\n\nexport function buildSchemaIndex(\n schemas: readonly PayloadFieldSchema[],\n basePath = '',\n): SchemaIndex {\n const out = new Map<string, PayloadFieldSchema>();\n walk(schemas, basePath, out);\n return out;\n}\n\nfunction walk(\n schemas: readonly PayloadFieldSchema[],\n basePath: string,\n out: Map<string, PayloadFieldSchema>,\n): void {\n for (const schema of schemas) {\n if (STRUCTURAL_TYPES.has(schema.type)) {\n if (schema.fields) walk(schema.fields, basePath, out);\n continue;\n }\n const path = basePath === '' ? schema.name : `${basePath}.${schema.name}`;\n out.set(path, schema);\n if (schema.type === 'group') {\n if (schema.fields) walk(schema.fields, path, out);\n } else if (schema.type === 'array' && schema.fields) {\n walk(schema.fields, `${path}.*`, out);\n } else if (schema.type === 'blocks' && schema.blocks) {\n for (const block of schema.blocks) {\n walk(block.fields, `${path}.*.${block.slug}`, out);\n }\n }\n }\n}\n\n/** Schema for `fieldPath`; numeric segments are retried as `*` wildcards. */\nexport function lookupSchema(\n index: SchemaIndex,\n fieldPath: string,\n): PayloadFieldSchema | undefined {\n if (index.has(fieldPath)) return index.get(fieldPath);\n const wildcardPath = fieldPath.replace(/\\.\\d+(?=\\.|$)/g, '.*');\n if (index.has(wildcardPath)) return index.get(wildcardPath);\n return undefined;\n}\n\nexport function lookupBlockSchema(\n index: SchemaIndex,\n blocksFieldPath: string,\n blockType: string,\n): PayloadBlockSchema | undefined {\n const schema = lookupSchema(index, blocksFieldPath);\n if (!schema?.blocks) return undefined;\n return schema.blocks.find((b) => b.slug === blockType);\n}\n","/**\n * Structural diff for array and blocks fields. Items with an `id` are keyed\n * (moves are detected); without ids the diff is positional.\n * @internal\n */\n\nexport type ArrayPatch =\n | { readonly kind: 'insert'; readonly index: number; readonly value: unknown }\n | { readonly kind: 'remove'; readonly index: number; readonly value: unknown }\n | {\n readonly kind: 'move';\n readonly from: number;\n readonly to: number;\n readonly value: unknown;\n }\n | { readonly kind: 'update'; readonly index: number; readonly value: unknown }\n | {\n readonly kind: 'replace';\n readonly index: number;\n readonly oldValue: unknown;\n readonly value: unknown;\n };\n\nfunction getId(item: unknown): string | number | undefined {\n if (typeof item !== 'object' || item === null) return undefined;\n const id = (item as Record<string, unknown>)['id'];\n if (typeof id === 'string' || typeof id === 'number') return id;\n return undefined;\n}\n\nfunction getBlockType(item: unknown): string | undefined {\n if (typeof item !== 'object' || item === null) return undefined;\n const blockType = (item as Record<string, unknown>)['blockType'];\n return typeof blockType === 'string' ? blockType : undefined;\n}\n\n/** Patches that turn `prev` into `next`; a changed `blockType` is a `replace`, never an `update`. */\nexport function diffArray(\n prev: readonly unknown[],\n next: readonly unknown[],\n): readonly ArrayPatch[] {\n const haveIds = next.every((item) => getId(item) !== undefined);\n if (haveIds) return diffById(prev, next);\n return diffByPosition(prev, next);\n}\n\nfunction diffById(prev: readonly unknown[], next: readonly unknown[]): readonly ArrayPatch[] {\n const patches: ArrayPatch[] = [];\n const prevIndexById = new Map<string | number, number>();\n for (let i = 0; i < prev.length; i += 1) {\n const id = getId(prev[i]);\n if (id !== undefined) prevIndexById.set(id, i);\n }\n\n const consumedFromPrev = new Set<number>();\n for (let to = 0; to < next.length; to += 1) {\n const item = next[to];\n const id = getId(item);\n if (id === undefined) {\n patches.push({ kind: 'insert', index: to, value: item });\n continue;\n }\n const from = prevIndexById.get(id);\n if (from === undefined) {\n patches.push({ kind: 'insert', index: to, value: item });\n continue;\n }\n consumedFromPrev.add(from);\n const prevItem = prev[from];\n if (getBlockType(prevItem) !== getBlockType(item)) {\n patches.push({ kind: 'replace', index: to, oldValue: prevItem, value: item });\n continue;\n }\n if (from !== to) {\n patches.push({ kind: 'move', from, to, value: item });\n }\n if (!shallowEqual(prevItem, item)) {\n patches.push({ kind: 'update', index: to, value: item });\n }\n }\n\n for (let i = 0; i < prev.length; i += 1) {\n if (consumedFromPrev.has(i)) continue;\n patches.push({ kind: 'remove', index: i, value: prev[i] });\n }\n return patches;\n}\n\nfunction diffByPosition(prev: readonly unknown[], next: readonly unknown[]): readonly ArrayPatch[] {\n const patches: ArrayPatch[] = [];\n const min = Math.min(prev.length, next.length);\n for (let i = 0; i < min; i += 1) {\n if (!shallowEqual(prev[i], next[i])) {\n patches.push({ kind: 'update', index: i, value: next[i] });\n }\n }\n if (next.length > prev.length) {\n for (let i = prev.length; i < next.length; i += 1) {\n patches.push({ kind: 'insert', index: i, value: next[i] });\n }\n }\n if (prev.length > next.length) {\n for (let i = next.length; i < prev.length; i += 1) {\n patches.push({ kind: 'remove', index: i, value: prev[i] });\n }\n }\n return patches;\n}\n\n// Shallow on purpose: any nested reference change is an update, and the\n// renderer reconciles deeper differences itself.\nfunction shallowEqual(a: unknown, b: unknown): boolean {\n if (Object.is(a, b)) return true;\n if (typeof a !== 'object' || typeof b !== 'object' || a === null || b === null) return false;\n const aRec = a as Record<string, unknown>;\n const bRec = b as Record<string, unknown>;\n const aKeys = Object.keys(aRec);\n const bKeys = Object.keys(bRec);\n if (aKeys.length !== bKeys.length) return false;\n for (const key of aKeys) {\n if (!Object.is(aRec[key], bRec[key])) return false;\n }\n return true;\n}\n","/**\n * Payload field type → renderer name. Structural containers the walker has\n * already flattened, and types without a display, map to `text` so a new\n * Payload field type never leaves a binding without a renderer.\n */\n\nimport type { FieldType } from '@core/types';\nimport type { PayloadFieldType } from '@/types/payload-protocol';\n\nconst MAP: Readonly<Record<PayloadFieldType, FieldType>> = {\n text: 'text',\n textarea: 'textarea',\n richText: 'richText',\n email: 'email',\n number: 'number',\n checkbox: 'checkbox',\n date: 'date',\n select: 'select',\n radio: 'radio',\n array: 'array',\n blocks: 'blocks',\n group: 'text',\n tabs: 'text',\n row: 'text',\n collapsible: 'text',\n relationship: 'relationship',\n upload: 'upload',\n point: 'text',\n json: 'text',\n code: 'text',\n ui: 'text',\n};\n\n/** `undefined` for a type not in the table, so the caller can fall back to the DOM attribute. */\nexport function payloadTypeToRenderer(type: string): FieldType | undefined {\n if (Object.prototype.hasOwnProperty.call(MAP, type)) {\n return MAP[type as PayloadFieldType];\n }\n return undefined;\n}\n","/**\n * URL safety: the one scheme allow-list the runtime, the client and the\n * sanitizer share. Empty strings are not safe (`<a href=\"\">` is never emitted).\n */\n\nconst SAFE_PROTOCOLS: ReadonlySet<string> = new Set(['http:', 'https:', 'mailto:', 'tel:']);\n\n// Browsers strip leading whitespace before scheme detection.\nconst DANGEROUS_PROTOCOL_PATTERN = /^\\s*(?:javascript|data|vbscript|file|blob|about)\\s*:/i;\n\nconst RELATIVE_PATH = /^(?:\\.{1,2}\\/|[a-zA-Z0-9_-]+\\/?)/;\n\n// The URL parser treats `\\` as `/` for special schemes, so `/\\evil.com`\n// resolves to another origin rather than to a same-origin path.\nconst PROTOCOL_RELATIVE = /^[\\\\/]{2}/;\n\n/** The URL parser drops these anywhere in the input before it looks at anything. */\nconst PARSER_IGNORED = /[\\t\\n\\r]/g;\n\n/** `true` only for absolute `http`/`https`/`mailto`/`tel` URLs, protocol-relative URLs, paths, `#`/`?` fragments and relative paths. */\nexport function isSafeUrl(url: unknown): boolean {\n if (typeof url !== 'string') return false;\n const trimmed = url.trim().replace(PARSER_IGNORED, '');\n if (trimmed.length === 0) return false;\n if (DANGEROUS_PROTOCOL_PATTERN.test(trimmed)) return false;\n if (trimmed.startsWith('#') || trimmed.startsWith('?')) return true;\n if (PROTOCOL_RELATIVE.test(trimmed)) return true;\n if (trimmed.startsWith('/')) return true;\n try {\n const parsed = new URL(trimmed);\n return SAFE_PROTOCOLS.has(parsed.protocol);\n } catch {\n return RELATIVE_PATH.test(trimmed);\n }\n}\n\n/** Whether a URL points at another HTTP(S) origin, protocol-relative forms included, and so needs `noopener` hardening; every URL these two patterns match is one `isSafeUrl` admits. */\nexport function isExternalHttpUrl(url: string): boolean {\n const trimmed = url.trim().replace(PARSER_IGNORED, '');\n return /^https?:\\/\\//i.test(trimmed) || PROTOCOL_RELATIVE.test(trimmed);\n}\n\n/** The safe scheme set, for tests and introspection. */\nexport const SAFE_URL_PROTOCOLS: ReadonlySet<string> = SAFE_PROTOCOLS;\n","/**\n * Policed writes for `data-payload-attribute` bindings. The value is\n * remote-controlled, so event handlers, `style`, `srcdoc`, `formaction`/`form`,\n * `id`/`name` (DOM clobbering) and `srcset` (multi-URL syntax) are refused,\n * URL-bearing attributes must pass `isSafeUrl`, and non-scalars never write.\n */\n\nimport { isSafeUrl } from '@security/url-validator';\n\nconst BLOCKED_ATTRIBUTES: ReadonlySet<string> = new Set([\n 'style',\n 'srcdoc',\n 'formaction',\n 'form',\n 'id',\n 'name',\n 'is',\n 'srcset',\n 'imagesrcset',\n]);\n\nconst URL_ATTRIBUTES: ReadonlySet<string> = new Set([\n 'href',\n 'src',\n 'poster',\n 'cite',\n 'action',\n 'xlink:href',\n 'data',\n]);\n\nexport type AttributeApplyResult = 'applied' | 'blocked';\n\n/**\n * Whether this package may write an attribute of this name at all — event\n * handlers, `style`, the two DOM-clobbering names and the multi-URL ones\n * excluded. One rule, two callers: the binding below writes a remote value into\n * it, and the array renderers copy one from the page's own markup onto an item\n * they rebuilt (`src/core/array-template.ts`).\n */\nexport function isWritableAttribute(name: string): boolean {\n return !name.startsWith('on') && !BLOCKED_ATTRIBUTES.has(name);\n}\n\n/** Returns `'blocked'` without touching the DOM when the write is refused. */\nexport function applyAttributeBinding(\n element: Element,\n attribute: string,\n value: unknown,\n): AttributeApplyResult {\n const name = attribute.toLowerCase().trim();\n if (name.length === 0) return 'blocked';\n if (!isWritableAttribute(name)) return 'blocked';\n\n if (value === null || value === undefined) {\n element.removeAttribute(name);\n return 'applied';\n }\n if (typeof value !== 'string' && typeof value !== 'number' && typeof value !== 'boolean') {\n return 'blocked';\n }\n const stringValue = String(value);\n\n if (URL_ATTRIBUTES.has(name) && !isSafeUrl(stringValue)) return 'blocked';\n\n element.setAttribute(name, stringValue);\n return 'applied';\n}\n","/**\n * What the runtime does about a patch it knows will not reach what the server\n * would have drawn: a renderer that refused the value, a Lexical block whose\n * markup the write had to drop. The finding is made where the write happens;\n * the policy and the ledger live here, so the pipeline can hand the region to a\n * strategy once the flush is over instead of leaving the page worse off.\n *\n * A changed field with no binding at all is the same judgement made one step\n * earlier — there is no element to write to — and `StrategyRunner` reaches it\n * from `unbound-fields.ts` before anything is scheduled.\n */\n\nimport type { RuntimeDeps, RuntimeState } from './runtime-state';\nimport type { CachedElement } from './types';\n\n/**\n * `'ignore'` keeps the degraded patch, which is what 2.0 shipped under the\n * name `onUnboundChange: 'ignore'`. `'warn'` keeps it and says so (LP0411).\n * `'escalate'`, the default, asks a server to draw the region instead: the\n * fragment strategy when a boundary covers the binding, the route otherwise.\n *\n * Without a strategy to escalate to, every mode keeps the patch. A page that\n * cannot ask a server for better markup is not helped by being told twice.\n */\nexport type UnfaithfulPatchMode = 'ignore' | 'warn' | 'escalate';\n\n/**\n * Both spellings of the option; the 2.0 name stays until 3.0. Explicitly\n * `| undefined`, because one caller reads them out of the inline script's\n * positional tuple, where an omitted slot is exactly that.\n */\nexport interface UnfaithfulPatchOptions {\n readonly onUnfaithfulPatch?: UnfaithfulPatchMode | undefined;\n readonly onUnboundChange?: 'ignore' | 'route' | undefined;\n}\n\n/**\n * The 2.0 name maps onto the new one without loss: `'route'` was this option's\n * escalation and `'ignore'` its opt-out. Only an omitted option takes the new\n * default — a project that wrote `'ignore'` down chose it, and keeps it.\n */\nexport function resolveUnfaithfulPatchMode(options: UnfaithfulPatchOptions): UnfaithfulPatchMode {\n // `'ignore'` is the only thing the old name can still say that the new\n // default does not: its `'route'` and its absence both mean escalate now.\n return (\n options.onUnfaithfulPatch ?? (options.onUnboundChange === 'ignore' ? 'ignore' : 'escalate')\n );\n}\n\n/**\n * Record one binding this revision could not patch faithfully, and queue it for\n * the escalation the flush will run.\n *\n * Once per element, for the same reason every other diagnostic here is: the\n * cause is the markup or the value's shape, so the next message would report\n * the same thing. Under `'escalate'` that also stops a value the renderer keeps\n * refusing from becoming one route refresh per keystroke.\n *\n * Counted under every mode, before the mode decides anything: `inspect()` has\n * to be able to say \"three patches fell short, none was escalated\" on the page\n * whose owner chose `'ignore'` as much as on the one that has no strategy.\n */\nexport function reportUnfaithfulPatch(\n deps: RuntimeDeps,\n state: RuntimeState,\n target: CachedElement,\n reason: string,\n): void {\n if (state.reportedUnfaithful.has(target.element)) return;\n state.reportedUnfaithful.add(target.element);\n state.unfaithfulCount += 1;\n state.unfaithfulFields.add(target.fieldName);\n const mode = deps.onUnfaithfulPatch;\n if (mode === 'ignore') return;\n if (mode === 'warn') {\n deps.warn(`[live-preview] LP0411: \"${target.fieldName}\" ${reason}`);\n return;\n }\n deps.log('LP0411', target.fieldName, reason);\n state.unfaithfulPatches.push(target);\n}\n\n/**\n * Record a changed field the page has no binding for: the same judgement one\n * step earlier, where there is no element to write to and so nothing to queue.\n * The whole route is the only answer to it, and `StrategyRunner` asks for that\n * itself.\n *\n * Once per field name, for the reason LP0411 is once per element: the cause is\n * the markup, so the next keystroke into the same field would report the same\n * thing. Counted under every mode and on a page with no strategy at all —\n * that page is the one `inspect().fidelity` was written for, and it was the one\n * page the reading said nothing about.\n *\n * No message of its own: LP0201 already names the field, once, from the same\n * rule. The return value says whether this was the first time, so an escalation\n * is counted against the findings it answered rather than against a keystroke.\n */\nexport function reportUnboundChange(state: RuntimeState, fieldName: string): boolean {\n if (state.unfaithfulFields.has(fieldName)) return false;\n state.unfaithfulFields.add(fieldName);\n state.unfaithfulCount += 1;\n return true;\n}\n\n/**\n * Renderers that turn a stored value into a presentation, so the template that\n * printed the same field had to choose one too. A `text` binding whose content\n * differs is an edit; a `date`, `number` or `checkbox` binding whose content\n * differs is two answers to the question the runtime cannot ask —\n * `data-payload-format` is where the answer belongs.\n */\nconst FORMATTING_RENDERERS: ReadonlySet<string> = new Set(['date', 'number', 'checkbox']);\n\n/** Cap on either reading in the message: a diagnostic is a pointer, not a dump. */\nconst EXCERPT = 40;\n\n/**\n * What the element shows, when a difference there would be worth reporting —\n * `undefined` when it would not, so an ordinary page pays one `Set` lookup per\n * binding and reads no DOM at all.\n *\n * Called before the renderer writes, and only for the first write to a\n * binding: after that the element holds the runtime's own output, and\n * comparing it with the runtime's next output says nothing about the template.\n */\nexport function watchServerFormatting(\n deps: RuntimeDeps,\n state: RuntimeState,\n target: CachedElement,\n type: string,\n): string | undefined {\n if (deps.onUnfaithfulPatch === 'ignore') return undefined;\n if (target.format !== undefined || !FORMATTING_RENDERERS.has(type)) return undefined;\n if (state.checkedServerFormat.has(target.element)) return undefined;\n state.checkedServerFormat.add(target.element);\n const shown = shownValue(target.element);\n // An empty anchor lost nothing, and the boundary case (LP0201) is elsewhere.\n return shown.trim().length > 0 ? shown : undefined;\n}\n\n/**\n * Called once the renderer has written: both readings of the same value now\n * exist, and if they differ the page no longer matches the server.\n *\n * It reports and stops there. Escalating would hand the region to the route,\n * which redraws the template's format, which the re-apply overwrites again —\n * measured under Z3 — so the honest move is to name the two candidates and the\n * attribute that settles either of them.\n */\nexport function reportServerFormatting(\n deps: RuntimeDeps,\n target: CachedElement,\n before: string,\n): void {\n const after = shownValue(target.element);\n if (after === before) return;\n deps.warn(\n `[live-preview] LP0412: \"${target.fieldName}\" showed ${excerpt(before)}, the patch wrote ` +\n `${excerpt(after)} — either an edit that arrived before the preview connected, or a ` +\n 'template that formats this value differently. Set data-payload-format to match it.',\n );\n}\n\n/** The channel the date, number and checkbox renderers write. */\nfunction shownValue(element: Element): string {\n if (element.tagName === 'INPUT' || element.tagName === 'TEXTAREA') {\n return (element as HTMLInputElement).value;\n }\n return element.textContent;\n}\n\nfunction excerpt(value: string): string {\n const text = value.trim();\n return JSON.stringify(text.length > EXCERPT ? `${text.slice(0, EXCERPT)}…` : text);\n}\n","/**\n * Public renderer callbacks return `void`, but a JavaScript implementation may\n * return anything. Only callbacks marked here may reserve exact `false` as\n * \"no write\", so a custom renderer's incidental boolean cannot change the\n * lifecycle's applied counts.\n */\n\ntype Callback = (...args: never[]) => unknown;\n\nconst noWriteCallbacks = new WeakSet<Callback>();\n\n/** Mark a package-owned callback whose exact `false` return means no write. */\nexport function markNoWriteCallback<T extends Callback>(callback: T): T {\n noWriteCallbacks.add(callback);\n return callback;\n}\n\n/** Whether `callback` owns the internal exact-false sentinel contract. */\nexport function usesNoWriteOutcome(callback: Callback): boolean {\n return noWriteCallbacks.has(callback);\n}\n\n/** Check a renderer object without detaching its public method at the call site. */\nexport function rendererUsesNoWriteOutcome(renderer: { readonly render: Callback }): boolean {\n return noWriteCallbacks.has(renderer.render);\n}\n","/**\n * Stable identity for a field value, so two messages can be compared without\n * rendering either — every keystroke ships the whole document, of which one\n * field changed. Equality is structural (plain, unsorted JSON): Payload\n * allocates a fresh object graph per message, so reference identity would skip\n * nothing. A value JSON cannot represent has no identity and counts as\n * changed, which is the safe direction — a false \"equal\" leaves a stale\n * binding, a false \"different\" only renders once more.\n */\n\n/** Past this size the comparison is no longer obviously cheaper than the render it avoids. */\nexport const IDENTITY_SIZE_LIMIT = 64 * 1024;\n\n/**\n * Canonical string for `value`, or `undefined` when it cannot have one.\n * Primitives carry a type tag, so `1` and `'1'` differ even though a text\n * renderer prints them alike — that is the renderer's decision, not this one.\n */\nexport function valueIdentity(value: unknown): string | undefined {\n switch (typeof value) {\n case 'string':\n return value.length > IDENTITY_SIZE_LIMIT ? undefined : `s:${value}`;\n case 'number':\n // Object.is semantics at the top level: NaN equals NaN, -0 is not 0.\n return `n:${Object.is(value, -0) ? '-0' : String(value)}`;\n case 'boolean':\n return `b:${value ? '1' : '0'}`;\n case 'bigint':\n return `i:${String(value)}`;\n case 'undefined':\n return 'u';\n case 'object': {\n if (value === null) return 'z';\n let json: string;\n try {\n // Throws on a cycle and on a nested BigInt; both mean \"no identity\".\n json = JSON.stringify(value);\n } catch {\n return undefined;\n }\n return json.length > IDENTITY_SIZE_LIMIT ? undefined : `o:${json}`;\n }\n case 'symbol':\n case 'function':\n return undefined;\n }\n}\n","/**\n * The one per-message diff of top-level field values. Strategies, dependency\n * invalidation and reveal all consume it, so \"changed\" means the same thing\n * everywhere.\n */\n\nimport type { DependencyMap } from './dependencies';\nimport { valueIdentity } from './value-identity';\n\nexport interface FieldChanges {\n /** Fields whose value differs from the previous message; every field on the first one. */\n readonly changed: ReadonlySet<string>;\n /** Dependents of changed fields, per the dependency map. */\n readonly invalidated: ReadonlySet<string>;\n /**\n * The first message of a connection, where `changed` means \"everything the\n * document has\" rather than \"what the editor just did\". A caller that acts on\n * a change rather than rendering one has to sit this message out.\n */\n readonly baseline: boolean;\n}\n\nexport class FieldChangeTracker {\n private previous: Map<string, string | undefined> | null = null;\n\n /** Diff `fields` against the previous message and remember them for the next call. */\n diff(fields: Readonly<Record<string, unknown>>, dependencies: DependencyMap): FieldChanges {\n const previous = this.previous;\n const baseline = previous === null;\n const next = new Map<string, string | undefined>();\n const changed = new Set<string>();\n for (const [name, value] of Object.entries(fields)) {\n const identity = valueIdentity(value);\n next.set(name, identity);\n // A value without an identity always counts as changed: rendering once\n // more is cheap, a stale binding is not.\n if (previous === null || identity === undefined || previous.get(name) !== identity) {\n changed.add(name);\n }\n }\n if (previous !== null) {\n for (const name of previous.keys()) if (!next.has(name)) changed.add(name);\n }\n this.previous = next;\n const invalidated = new Set<string>();\n for (const [source, dependents] of Object.entries(dependencies)) {\n if (!changed.has(source)) continue;\n for (const dependent of dependents) invalidated.add(dependent);\n }\n return { changed, invalidated, baseline };\n }\n\n reset(): void {\n this.previous = null;\n }\n}\n","/**\n * How a bound region is brought up to date: the runtime patches it, a server\n * renders a `data-payload-fragment` boundary from the unsaved form state, or\n * the whole route refreshes. Core carries only the seam — which boundaries a\n * strategy owns and what it may do — so a patch-only page pays for nothing\n * more; the orchestration lives in `payload-live-preview/fragment`.\n */\nimport type { DiagnosticCode } from './diagnostic-codes';\n\n/** What produced an update: the runtime's DOM patching, a server-rendered fragment, or a route refresh. */\nexport type UpdateSource = 'patch' | 'fragment' | 'route';\n\n/** Marks a server-rendered boundary; the value is the registry id the server may render. @internal */\nexport const FRAGMENT_ATTRIBUTE = 'data-payload-fragment';\n\n/** The nearest fragment boundary enclosing `element` (the element itself included). */\nexport function enclosingFragment(element: Element): Element | null {\n return element.closest(`[${FRAGMENT_ATTRIBUTE}]`);\n}\n\n/** One revision, as a strategy sees it, with the runtime capabilities it may use. */\nexport interface FragmentContext {\n readonly root: ParentNode;\n readonly revision: number;\n readonly receivedAt: number;\n readonly fields: Readonly<Record<string, unknown>>;\n readonly locale: string | undefined;\n readonly collectionSlug: string | undefined;\n readonly globalSlug: string | undefined;\n /** Aborted when a newer revision arrives or the runtime stops. */\n readonly signal: AbortSignal;\n /** Whether this revision is still the current one. */\n readonly isCurrent: () => boolean;\n /** Morph server-rendered HTML into a boundary (Trusted Types and the keyed morph apply). */\n readonly morph: (boundary: Element, html: string) => void;\n /** Patch the boundary's own bindings from this revision — the deterministic fallback. */\n readonly patch: (boundary: Element) => void;\n /** Debug log through the runtime's logger, with the diagnostic code. */\n readonly log: (code: DiagnosticCode, detail: string) => void;\n /** Report a boundary rendered. */\n readonly rendered: (boundary: Element, id: string, key: string | undefined) => void;\n /** Report a boundary failed and patched instead; emits the `error` and `fragmentRender` events. */\n readonly failed: (\n boundary: Element,\n id: string,\n key: string | undefined,\n code: DiagnosticCode,\n reason: string,\n ) => void;\n}\n\nexport interface FragmentReport {\n readonly rendered: number;\n readonly failed: number;\n readonly superseded: number;\n}\n\n/** A fragment strategy: which boundaries it owns for a revision, and how it renders them. */\nexport interface FragmentStrategy {\n /** The boundaries this update re-renders; their inner bindings are left to the strategy. */\n readonly plan: (root: ParentNode, changedFields: ReadonlySet<string>) => readonly Element[];\n /** Render the planned boundaries; resolves once every one settled. */\n readonly render: (\n context: FragmentContext,\n boundaries: readonly Element[],\n ) => Promise<FragmentReport>;\n}\n\n/** One revision, as the route strategy sees it. */\nexport interface RouteContext {\n readonly revision: number;\n readonly receivedAt: number;\n /** Aborted when a newer revision arrives or the runtime stops. */\n readonly signal: AbortSignal;\n readonly isCurrent: () => boolean;\n readonly log: (code: DiagnosticCode, detail: string) => void;\n /**\n * Ask to be run again in `delayMs`, once. A strategy that refuses a refresh\n * because it is rate-limiting itself uses this: the window is a rate limit\n * and not a filter, so what falls inside it still has to reach the preview.\n * The runtime runs at most one such request, and only while the revision that\n * asked is still the current one.\n */\n readonly retryAfter?: (delayMs: number) => void;\n}\n\n/**\n * What one refresh did. `refused` is the strategy's own brake and not a\n * failure — it is counted separately, because a number that mixes a planned\n * pause with a broken request cannot be read.\n */\nexport type RouteOutcome = 'refreshed' | 'failed' | 'refused' | 'superseded';\n\n/**\n * Whether a revision needs the whole route re-rendered, and how. After a\n * refresh the runtime rescans and re-applies the revision, so the unsaved\n * state lands on the fresh markup.\n */\nexport interface RouteStrategy {\n readonly plan: (root: ParentNode, changedFields: ReadonlySet<string>) => boolean;\n readonly refresh: (context: RouteContext) => Promise<RouteOutcome>;\n}\n\nexport interface StrategyHandlers {\n readonly fragment?: FragmentStrategy;\n readonly route?: RouteStrategy;\n}\n\nconst STRATEGY_ATTRIBUTE = 'data-payload-strategy';\n\n/**\n * Explicit `data-payload-strategy` wins; otherwise a binding inside a fragment\n * boundary belongs to the fragment, one in `<head>` to the route, the rest is\n * patched. An unknown explicit value resolves to `undefined` (LP0407).\n * @internal\n */\nexport function resolveStrategy(element: Element): UpdateSource | undefined {\n const explicit = element.getAttribute(STRATEGY_ATTRIBUTE);\n if (explicit !== null && explicit.length > 0) {\n return explicit === 'patch' || explicit === 'fragment' || explicit === 'route'\n ? explicit\n : undefined;\n }\n if (enclosingFragment(element) !== null) return 'fragment';\n if (element.closest('head') !== null) return 'route';\n return 'patch';\n}\n","/**\n * Document ownership for bindings. A field name alone cannot identify a\n * binding on a page that previews several documents — `title` may belong to a\n * global, to shared SEO metadata and to every card at once. An owner marker\n * names the document a subtree belongs to, as a plain comparable string:\n * `global:<slug>`, `collection:<slug>`, `collection:<slug>:<id>`.\n */\n\n/** Identity of the document an incoming message describes. */\nexport interface MessageDocumentIdentity {\n readonly globalSlug?: string | undefined;\n readonly collectionSlug?: string | undefined;\n /** Primary key of the edited document, when the payload carries one. */\n readonly documentId?: string | undefined;\n}\n\n/** Owner key naming one Payload global. */\nexport function globalOwnerKey(slug: string): string {\n return `global:${slug}`;\n}\n\n/** Owner key for a collection; without an id it claims every document of it. */\nexport function collectionOwnerKey(slug: string, documentId?: string): string {\n return documentId === undefined || documentId === ''\n ? `collection:${slug}`\n : `collection:${slug}:${documentId}`;\n}\n\nfunction nonEmpty(value: string | undefined): value is string {\n return typeof value === 'string' && value.length > 0;\n}\n\n/**\n * Owner keys this message may address, or `null` when it carries no usable\n * identity — the runtime treats that as fail-closed rather than guessing. A\n * marker naming an id stays unreachable while the id is unknown: an unproven\n * identity must not satisfy an exact claim.\n */\nexport function messageOwnerKeys(identity: MessageDocumentIdentity): readonly string[] | null {\n if (nonEmpty(identity.globalSlug)) return [globalOwnerKey(identity.globalSlug)];\n if (!nonEmpty(identity.collectionSlug)) return null;\n const collectionKey = collectionOwnerKey(identity.collectionSlug);\n return nonEmpty(identity.documentId)\n ? [collectionKey, collectionOwnerKey(identity.collectionSlug, identity.documentId)]\n : [collectionKey];\n}\n\n/** Whether a binding may receive an update addressed to `keys`; an unowned binding never may. */\nexport function isBindingInScope(\n owner: string | undefined,\n keys: readonly string[] | null,\n): boolean {\n if (keys === null || owner === undefined) return false;\n return keys.includes(owner);\n}\n\n/** The document id Payload sends alongside the edited values; only scalars prove an identity. */\nexport function readDocumentId(fields: Record<string, unknown>): string | undefined {\n const id: unknown = fields['id'];\n if (typeof id === 'string' && id.length > 0) return id;\n if (typeof id === 'number' && Number.isFinite(id)) return String(id);\n return undefined;\n}\n","/**\n * Whether an incoming field has somewhere on the page to land.\n *\n * Two callers ask, for different reasons: LP0201 reports a field that never\n * has an anchor, and `onUnfaithfulPatch` decides whether a revision needs the\n * whole route. They have to answer the same way, so the lookup lives here\n * rather than in either of them — the locale suffix Payload appends, the owner\n * scope, and the fact that the diff names top-level fields while a binding may\n * name a path inside one.\n */\n\nimport { isBindingInScope } from './binding-owner';\nimport type { ElementCache } from './cache';\n\n/** Document fields Payload ships in every update that nobody binds to. */\nexport const SYSTEM_FIELD_NAMES: ReadonlySet<string> = new Set([\n 'id',\n '_id',\n 'createdAt',\n 'updatedAt',\n 'createdBy',\n 'updatedBy',\n '_status',\n 'globalType',\n 'collection',\n 'locale',\n 'localized',\n]);\n\n/** Owner keys as the update resolved them; `false` means scoping is off. */\nexport type OwnerScope = readonly string[] | null | false;\n\n/** Answers for one update; the locale index behind it is built at most once. */\nexport type FieldAddressability = (fieldName: string) => boolean;\n\n/**\n * `field_locale` names an element-local locale may consume while the message\n * locale differs, so those bindings are addressable under their suffixed name.\n */\nfunction localisedBindingNames(cache: ElementCache, ownerKeys: OwnerScope): Set<string> {\n const names = new Set<string>();\n for (const [fieldName, bindings] of cache.entries()) {\n for (const binding of bindings) {\n if (ownerKeys !== false && !isBindingInScope(binding.owner, ownerKeys)) continue;\n if (binding.locale !== undefined) names.add(`${fieldName}_${binding.locale}`);\n }\n }\n return names;\n}\n\nfunction hasBinding(cache: ElementCache, fieldName: string, ownerKeys: OwnerScope): boolean {\n const bindings = cache.get(fieldName);\n if (bindings === undefined) return false;\n if (ownerKeys === false) return true;\n return bindings.some((binding) => isBindingInScope(binding.owner, ownerKeys));\n}\n\n/**\n * A binding on a path inside the field — `hero.eyebrow` for the field `hero` —\n * makes it addressable. The diff names top-level fields only, so without this\n * every group and array on the page would look unbound.\n */\nexport function hasBindingBelow(\n cache: ElementCache,\n fieldName: string,\n ownerKeys: OwnerScope,\n): boolean {\n const prefix = `${fieldName}.`;\n for (const [boundName, bindings] of cache.entries()) {\n if (!boundName.startsWith(prefix)) continue;\n if (ownerKeys === false) return true;\n if (bindings.some((binding) => isBindingInScope(binding.owner, ownerKeys))) return true;\n }\n return false;\n}\n\nexport function stripLocaleSuffix(name: string, locale: string | undefined): string {\n if (locale === undefined || locale.length === 0) return name;\n const suffix = `_${locale}`;\n return name.endsWith(suffix) ? name.slice(0, -suffix.length) : name;\n}\n\n/** Whether any binding on the page belongs to the document this update carries. */\nexport function ownsAnyBinding(cache: ElementCache, ownerKeys: readonly string[] | null): boolean {\n for (const binding of cache.values()) {\n if (isBindingInScope(binding.owner, ownerKeys)) return true;\n }\n return false;\n}\n\n/**\n * The same rule for a caller that has names rather than the cache: the\n * `data-payload-field` values in a document, which is all a plugin can see\n * (`src/plugins/built-in/unbound-fields-overlay.ts`).\n *\n * It answers the first three of the four questions below — exact name, the\n * locale-stripped base, a binding on a path inside the field. The fourth needs\n * each binding's own `data-payload-locale`, which is a property of the element\n * rather than of its name, so a caller with names alone cannot ask it.\n */\nexport function createNameAddressability(\n boundNames: Iterable<string>,\n locale: string | undefined,\n): FieldAddressability {\n const names = new Set(boundNames);\n const covers = (fieldName: string): boolean => {\n if (names.has(fieldName)) return true;\n const prefix = `${fieldName}.`;\n for (const bound of names) if (bound.startsWith(prefix)) return true;\n return false;\n };\n return (fieldName) => {\n if (covers(fieldName)) return true;\n const base = stripLocaleSuffix(fieldName, locale);\n return base !== fieldName && covers(base);\n };\n}\n\n/**\n * The predicate for one update. The localised index is built on first use:\n * most fields are answered by the two cheap lookups before it.\n */\nexport function createFieldAddressability(\n cache: ElementCache,\n locale: string | undefined,\n ownerKeys: OwnerScope,\n): FieldAddressability {\n let localised: Set<string> | undefined;\n return (fieldName) => {\n if (hasBinding(cache, fieldName, ownerKeys)) return true;\n const base = stripLocaleSuffix(fieldName, locale);\n if (base !== fieldName && hasBinding(cache, base, ownerKeys)) return true;\n if (hasBindingBelow(cache, fieldName, ownerKeys)) return true;\n if (base !== fieldName && hasBindingBelow(cache, base, ownerKeys)) return true;\n localised ??= localisedBindingNames(cache, ownerKeys);\n return localised.has(fieldName);\n };\n}\n\n/**\n * The fields a revision changed that the page has nowhere to put: the rule\n * above, asked of a diff instead of a document. Both profiles ask it — the full\n * one to decide whether the whole route is the only honest answer, the lean one\n * because the finding is worth recording even where nothing can act on it — so\n * it stands here, beside the rule it is made of, rather than in either runner.\n */\nexport function unboundChangedFields(\n cache: ElementCache,\n touched: ReadonlySet<string>,\n locale: string | undefined,\n ownerKeys: OwnerScope,\n): string[] {\n const isAddressable = createFieldAddressability(cache, locale, ownerKeys);\n const unbound: string[] = [];\n for (const fieldName of touched) {\n if (!SYSTEM_FIELD_NAMES.has(fieldName) && !isAddressable(fieldName)) unbound.push(fieldName);\n }\n return unbound;\n}\n","/**\n * Whether an accepted message has to be resolved against the server before the\n * page can render it, and how many round trips a burst of them may cost. The\n * merge exists to populate relationships and uploads, so a page that renders\n * none of them needs no request at all, a message that moved no populated field\n * is answered from its own values over what the last merge resolved, and what\n * is left goes out once at the start of a burst and once at its end.\n *\n * Conservative in one direction on purpose: a request left out that was needed\n * puts an id where a name belongs and leaves it there, while one request too\n * many costs a round trip nobody sees.\n */\n\nimport { lookupSchema, type SchemaIndex } from '@schema/index';\nimport type { ElementCache } from './cache';\nimport type { DataMerger, MergeRequest, MergeResult } from './data-merger';\nimport type { DependencyMap } from './dependencies';\nimport { FieldChangeTracker } from './field-changes';\nimport type { RuntimeDeps, UpdateTransaction } from './runtime-state';\nimport { FRAGMENT_ATTRIBUTE } from './strategies';\nimport { hasBindingBelow, SYSTEM_FIELD_NAMES } from './unbound-fields';\n\n/**\n * Renderer keys and Payload types whose value the panel posts complete: a\n * scalar, with nothing inside it and nothing behind it to resolve. One\n * vocabulary answers both questions asked here — whether a page reads anything\n * the server populates, and whether one field does — because they are the same\n * question about a binding and about a value.\n */\nconst SELF_SUFFICIENT_TYPES: ReadonlySet<string> = new Set([\n 'text',\n 'textarea',\n 'email',\n 'number',\n 'checkbox',\n 'date',\n 'select',\n 'radio',\n 'point',\n 'code',\n 'json',\n 'ui',\n 'html',\n]);\n\n/** The raw diff answers \"what did the editor move\", which no dependency map changes. */\nconst NO_DEPENDENCIES: DependencyMap = {};\n\nexport interface MergePlan {\n /** Whether the server can still add something to these values. */\n readonly merge: boolean;\n /** The best document without it: this message's own values over the last resolved one. */\n readonly fields: Record<string, unknown>;\n}\n\nexport interface CoalescedMerge {\n /** Whether the request went out now. A deferred one lands after the window and refines what was rendered. */\n readonly leading: boolean;\n readonly result: Promise<MergeResult>;\n}\n\ninterface PendingMerge {\n readonly promise: Promise<MergeResult>;\n readonly settle: (result: MergeResult) => void;\n}\n\nexport class MergeNeed {\n /** What the panel last posted, so \"changed\" means what the editor moved, not what population added. */\n private readonly rawChanges = new FieldChangeTracker();\n private resolved: Record<string, unknown> | null = null;\n private queued: MergeRequest | null = null;\n private pending: PendingMerge | null = null;\n private timer: ReturnType<typeof setTimeout> | null = null;\n private openUntil = 0;\n\n /**\n * The decision, in the order the audit found the ways to get it wrong.\n *\n * 1. **Nothing on the page reads a populated value**, either because nobody\n * reads anything (LP-4) or because every binding renders a plain scalar.\n * See `readsPopulatedValues`.\n * 2. **Nothing populated moved** (LP-3): the fields the editor changed are\n * scalars that name no document, so they are taken from the message and\n * the rest is carried over from what the last merge resolved. Typing a\n * title costs nothing.\n *\n * What is left needs the server. It still renders at once — from the same\n * carried-over document — so the answer is not what the page waits for;\n * `request()` decides how often it is actually asked.\n */\n decide(deps: RuntimeDeps, transaction: UpdateTransaction): MergePlan {\n const raw = transaction.message.data ?? {};\n // Advanced for every message, including the ones that return here: the next\n // diff has to be against what the panel last posted either way.\n const { changed } = this.rawChanges.diff(raw, NO_DEPENDENCIES);\n if (!readsPopulatedValues(deps)) return { merge: false, fields: raw };\n const base = this.resolved;\n // The first message has nothing to carry over, so it buys the document once.\n if (base === null) {\n this.resolved = raw;\n return { merge: true, fields: raw };\n }\n const fields: Record<string, unknown> = { ...base };\n // A save in another document changes what population returns without moving\n // one value here (LP-1) — the one reason to ask that no field can state.\n let merge = transaction.forceRender;\n for (const field of changed) {\n const value = raw[field];\n if (SYSTEM_FIELD_NAMES.has(field)) {\n fields[field] = value;\n continue;\n }\n const verdict = verdictFor(field, base[field], value, deps.cache, transaction.schemaIndex);\n if (verdict !== 'own') merge = true;\n if (verdict !== 'keep') fields[field] = value;\n }\n this.resolved = fields;\n return { merge, fields };\n }\n\n /**\n * One request goes out now and the rest of a burst share the one that follows\n * its last message. The abort stays where it was: `DataMerger` still drops an\n * answer a newer request superseded, and what changes here is only how often\n * it is asked.\n *\n * The window is the scheduler's debounce, because it is the same burst: the\n * writes of one are coalesced into a single flush, and this is the request\n * behind them. A page that turns the debounce off turns this off with it.\n */\n request(merger: DataMerger, windowMs: number, request: MergeRequest): CoalescedMerge {\n const now = Date.now();\n if (now >= this.openUntil) {\n // The clock has closed the window, but its timer may not have run: a busy\n // main thread or a throttled engine fires it late. Left queued, that older\n // request would go out after this one, and `DataMerger` — which keeps the\n // newest request — would drop this keystroke's answer; measured in WebKit\n // as a preview one keystroke behind. This request carries the newer values.\n this.dropQueued();\n this.openUntil = now + windowMs;\n return { leading: true, result: merger.merge(request) };\n }\n this.queued = request;\n this.openUntil = now + windowMs;\n this.pending ??= createPending();\n if (this.timer !== null) clearTimeout(this.timer);\n this.timer = setTimeout(() => {\n this.flush(merger);\n }, windowMs);\n return { leading: false, result: this.pending.promise };\n }\n\n /** The server's document replaces what was carried over; the next message builds on it. */\n recordMerged(doc: Record<string, unknown>): void {\n this.resolved = doc;\n }\n\n destroy(): void {\n this.dropQueued();\n this.openUntil = 0;\n }\n\n /** Drop a queued request; whoever waits on it keeps what they already rendered. */\n private dropQueued(): void {\n if (this.timer !== null) clearTimeout(this.timer);\n this.timer = null;\n this.queued = null;\n this.pending?.settle({ status: 'superseded' });\n this.pending = null;\n }\n\n private flush(merger: DataMerger): void {\n const pending = this.pending;\n const request = this.queued;\n this.timer = null;\n this.pending = null;\n this.queued = null;\n if (pending === null || request === null) return;\n merger.merge(request).then(pending.settle, () => {\n pending.settle({ status: 'unavailable' });\n });\n }\n}\n\n/** What one changed field's own value is worth. */\ntype FieldVerdict =\n /** Everything the page can render is in it. */\n | 'own'\n /** It can be rendered now, and the server may still complete something inside it. */\n | 'ask'\n /** It is a bare id where a document stood; writing it would put that id on the page. */\n | 'keep';\n\nfunction verdictFor(\n field: string,\n previous: unknown,\n value: unknown,\n cache: ElementCache,\n schemaIndex: SchemaIndex | undefined,\n): FieldVerdict {\n // A structure — a rich-text tree, an array, a group — may hold a reference\n // inside it, and the message's own copy of it is still what the editor typed.\n if (!isScalar(value)) return 'ask';\n if (!isScalar(previous) || namesAReference(field, cache, schemaIndex)) return 'keep';\n // A field that was empty can be filled with either a word or an id, and the\n // two look alike. Render it and ask: a word must not wait for the answer.\n return previous == null ? 'ask' : 'own';\n}\n\n/** A document id and a title are both strings; only the schema or a binding says which this is. */\nfunction namesAReference(\n field: string,\n cache: ElementCache,\n schemaIndex: SchemaIndex | undefined,\n): boolean {\n const schema = schemaIndex === undefined ? undefined : lookupSchema(schemaIndex, field);\n if (schema !== undefined && !SELF_SUFFICIENT_TYPES.has(schema.type)) return true;\n if (cache.get(field)?.some(rendersAReference) === true) return true;\n // `venue.title` is a page saying the field holds a document; the owner scope\n // is off here on purpose, because a binding in any document still says so.\n return hasBindingBelow(cache, field, false);\n}\n\nfunction rendersAReference(binding: { readonly fieldType: string }): boolean {\n // A project renderer is unknown ground: it may resolve the value itself.\n return !SELF_SUFFICIENT_TYPES.has(binding.fieldType);\n}\n\n/**\n * Whether anything on this page reads a value the server would populate.\n *\n * Two findings meet here. LP-4: a page with no binding, no island, no boundary\n * a fragment strategy would render and no listener reading the document has\n * nobody to hand the answer to — measured on such a page, 17 keystrokes cost 19\n * authenticated POSTs. LP-3: a page whose every binding is a plain scalar\n * renderer on a top-level field renders the panel's own values exactly, so the\n * merge could only hand back what the message already carries.\n *\n * The route is deliberately not a reason to ask. Since Z3 an unbound change\n * escalates to it by default, but a refresh re-renders the page from the server\n * and never looks at these values.\n */\nfunction readsPopulatedValues(deps: RuntimeDeps): boolean {\n const { cache, emitter } = deps;\n if (cache.islands.length > 0) return true;\n if (emitter.listenerCount('beforeUpdate') > 0 || emitter.listenerCount('afterUpdate') > 0) {\n return true;\n }\n for (const binding of cache.values()) {\n // A reference renderer, a value with structure, or a path inside a field.\n if (rendersAReference(binding) || binding.fieldName.includes('.')) return true;\n if (isPath(binding.hrefField) || isPath(binding.srcField) || isPath(binding.altField)) {\n return true;\n }\n }\n // A boundary is rendered by a server that is handed exactly these fields.\n return (\n deps.strategies.fragment !== undefined &&\n deps.root.querySelector(`[${FRAGMENT_ATTRIBUTE}]`) !== null\n );\n}\n\nfunction isScalar(value: unknown): boolean {\n return value === null || (typeof value !== 'object' && typeof value !== 'function');\n}\n\nfunction isPath(field: string | undefined): boolean {\n return field?.includes('.') === true;\n}\n\nfunction createPending(): PendingMerge {\n let settle!: (result: MergeResult) => void;\n const promise = new Promise<MergeResult>((resolve) => {\n settle = resolve;\n });\n return { promise, settle };\n}\n","/** Tracks the announced protocol version and the capabilities seen on the wire. */\n\nimport {\n LIBRARY_PROTOCOL_VERSION,\n negotiateProtocol,\n type ProtocolCapability,\n type ProtocolNegotiation,\n} from './protocol-version';\n\nexport class ProtocolTracker {\n negotiation: ProtocolNegotiation = negotiateProtocol(undefined);\n readonly observed = new Set<ProtocolCapability>();\n\n /** Record capabilities a message demonstrated; the stock admin announces no version. */\n observe(capabilities: readonly ProtocolCapability[], log: (...args: unknown[]) => void): void {\n const fresh = capabilities.filter((capability) => !this.observed.has(capability));\n if (fresh.length === 0) return;\n for (const capability of fresh) this.observed.add(capability);\n this.negotiation = negotiateProtocol(this.negotiation.theirs, this.observed);\n log('protocol', `observed=${fresh.join(',')}`);\n }\n\n applyVersion(remoteVersion: number, log: (...args: unknown[]) => void): void {\n const current = this.negotiation;\n if (current.theirs === remoteVersion) return;\n const next = negotiateProtocol(remoteVersion, this.observed);\n this.negotiation = next;\n if (next.negotiated === current.negotiated) return;\n log(\n 'protocol',\n `ours=${LIBRARY_PROTOCOL_VERSION}`,\n `theirs=${remoteVersion}`,\n `negotiated=${next.negotiated}`,\n );\n }\n}\n","/**\n * Reads `externallyUpdatedRelationship` as an edge, not as a level. Payload's\n * panel fills the field from `useDocumentEvents().mostRecentUpdate`, a state\n * that every save of the previewed document raises and that nothing ever\n * clears, so the same event repeats in every message for the rest of the\n * session. Two questions make it news again: has the event changed since the\n * last one, and does it name a document other than the one on this page.\n */\n\nimport type {\n PayloadDocumentEventDetail,\n PayloadLivePreviewMessage,\n} from '@/types/payload-protocol';\nimport { readDocumentId } from './binding-owner';\n\n/**\n * Whether the event names a document other than the one this message previews.\n * A message that says which document that is settles it in both directions;\n * one that does not is taken at the event's word, because the repeat is\n * already handled by the identity and one re-render costs less than a drawer\n * edit the page never shows.\n */\nfunction namesAnotherDocument(\n event: PayloadDocumentEventDetail,\n message: PayloadLivePreviewMessage,\n): boolean {\n const previewedSlug = message.globalSlug ?? message.collectionSlug;\n if (typeof previewedSlug !== 'string' || event.entitySlug !== previewedSlug) return true;\n // The same entity. A global holds one document, so the event is its own\n // save; a collection is proven different only when both ids are known and\n // differ.\n const id = readDocumentId(event);\n const previewedId = readDocumentId(message.data ?? {});\n return id !== undefined && previewedId !== undefined && id !== previewedId;\n}\n\n/**\n * Whether the revision a new one supersedes still owes the page a drawer edit.\n *\n * The edit is news on exactly one message, and the panel posts the repeat in\n * the same burst: it supersedes the revision that carried the edit before the\n * server's populated answer arrives, so that answer is dropped, and the repeat\n * asks for nothing itself. The obligation passes to whoever supersedes it and\n * stops at the revision that completes.\n */\nexport function owesForceRender(\n previous: { readonly forceRender: boolean; readonly completed: boolean } | null,\n): boolean {\n return previous !== null && previous.forceRender && !previous.completed;\n}\n\n/** Remembers the last document event the panel sent, so its repeats are one event. */\nexport class RelationshipTracker {\n /**\n * Identity of the last event seen. Not `id` alone: a global's save carries\n * none, and an identity that required one would read every global save as a\n * new document.\n */\n private lastIdentity: string | undefined = undefined;\n\n /**\n * The edit this message brings that the page has not acted on yet: a changed\n * event about another document. `null` for a message without the field, for\n * the repeat, and for the previewed document's own save.\n */\n edit(message: PayloadLivePreviewMessage): PayloadDocumentEventDetail | null {\n const event = message.externallyUpdatedRelationship;\n if (typeof event !== 'object' || event === null) return null;\n const identity = JSON.stringify([event.entitySlug, readDocumentId(event), event.updatedAt]);\n const isNew = identity !== this.lastIdentity;\n this.lastIdentity = identity;\n return isNew && namesAnotherDocument(event, message) ? event : null;\n }\n}\n","/**\n * Scroll the edited field's bound element into view. Deliberately quiet: only\n * when the target is off-screen and only when the edited field changed since\n * the last reveal, so continuous typing never re-scrolls and a deliberate\n * scroll-away is not fought. Honours `prefers-reduced-motion`.\n */\n\n/** The slice of `Window` this reads, so it tests without a browser. */\nexport interface RevealWindow {\n readonly innerHeight: number;\n readonly innerWidth: number;\n matchMedia?: (query: string) => { readonly matches: boolean };\n}\n\n/** The slice of `Element` this module needs. */\nexport interface RevealElement {\n getBoundingClientRect: () => {\n readonly top: number;\n readonly bottom: number;\n readonly left: number;\n readonly right: number;\n };\n scrollIntoView: (options?: {\n behavior?: 'auto' | 'smooth';\n block?: 'center' | 'nearest' | 'start';\n }) => void;\n}\n\n/** Whether the viewer asked for reduced motion; smooth scrolling is suppressed when so. */\nexport function prefersReducedMotion(win: RevealWindow): boolean {\n try {\n return win.matchMedia?.('(prefers-reduced-motion: reduce)').matches === true;\n } catch {\n return false;\n }\n}\n\n/** A visible sliver counts: an element the editor can already see is never scrolled to. */\nexport function isInViewport(element: RevealElement, win: RevealWindow): boolean {\n const rect = element.getBoundingClientRect();\n const vertically = rect.bottom > 0 && rect.top < win.innerHeight;\n const horizontally = rect.right > 0 && rect.left < win.innerWidth;\n return vertically && horizontally;\n}\n\n/** Outcome of a reveal attempt, for the caller's diagnostics. */\nexport type RevealOutcome = 'revealed' | 'already-visible';\n\n/** Scroll `element` into view only when it is off-screen. */\nexport function revealElement(element: RevealElement, win: RevealWindow): RevealOutcome {\n if (isInViewport(element, win)) return 'already-visible';\n element.scrollIntoView({\n behavior: prefersReducedMotion(win) ? 'auto' : 'smooth',\n block: 'center',\n });\n return 'revealed';\n}\n\n/** Remembers the last field revealed, so only a change of field scrolls again. */\nexport class FieldRevealer {\n #lastField: string | undefined;\n\n /** `skipped-same` when this is still the field last revealed. */\n reveal(\n fieldName: string,\n element: RevealElement,\n win: RevealWindow,\n ): RevealOutcome | 'skipped-same' {\n if (fieldName === this.#lastField) return 'skipped-same';\n this.#lastField = fieldName;\n return revealElement(element, win);\n }\n\n /** Forget the last field, after a navigation that rebuilt the page. */\n reset(): void {\n this.#lastField = undefined;\n }\n}\n","/**\n * Which value each owned field was last seen with, and the one binding a\n * revision should scroll to: the bookkeeping behind \"reveal the edited field\",\n * kept apart from the pipeline that schedules the writes.\n *\n * Keyed by document, locale and field rather than by element. The element a\n * fragment renders does not survive its own re-render, but the field it shows\n * is the same field.\n *\n * The ledger is written only when a revision reaches its reveal point, not when\n * a candidate is noted. Writing at once lost reveals: an identical re-send\n * superseded the revision that had noted the change, then found nothing new.\n */\n\nimport { valueIdentity } from './value-identity';\n\n/** What the ledger needs of a binding: the key parts, and the element to reveal. */\nexport interface RevealKey {\n readonly owner?: string | undefined;\n readonly locale?: string | undefined;\n readonly fieldName: string;\n}\n\n/** The per-revision slot the ledger fills; the transaction carries it. */\nexport interface RevealSlot<T extends RevealKey> {\n revealIdentities: [key: string, identity: string][];\n revealTarget: T | undefined;\n}\n\nexport class RevealLedger {\n private readonly seen = new Map<string, string>();\n\n /**\n * Record what this binding's value looks like now and, for the first binding\n * whose value moved, mark it as the one to reveal.\n *\n * The first message is a baseline and a binding new to the page is not an\n * edit, so an unseen key only records. A value too large or cyclic to compare\n * cannot claim to have changed either, or it would take the reveal from a\n * field that did.\n */\n note<T extends RevealKey>(slot: RevealSlot<T>, target: T, value: unknown): void {\n const identity = valueIdentity(value);\n if (identity === undefined) return;\n const key = `${target.owner ?? ''}\u0000${target.locale ?? ''}\u0000${target.fieldName}`;\n const seen = this.seen.get(key);\n if (seen === undefined) {\n // A baseline is recorded at once: nothing is owed for it.\n this.seen.set(key, identity);\n return;\n }\n if (seen === identity) return;\n slot.revealIdentities.push([key, identity]);\n slot.revealTarget ??= target;\n }\n\n /**\n * The revision reached its reveal point: what it saw is now what the ledger\n * shows, whether or not there is anything to scroll to. Hands out the\n * binding to reveal once; a second call finds the slot empty.\n */\n commit<T extends RevealKey>(slot: RevealSlot<T>): T | undefined {\n for (const [key, identity] of slot.revealIdentities) this.seen.set(key, identity);\n slot.revealIdentities = [];\n const target = slot.revealTarget;\n slot.revealTarget = undefined;\n return target;\n }\n}\n","/**\n * What the runtime owns for its lifetime (`RuntimeDeps`) and what changes as it\n * runs (`RuntimeState`). Both are shared by the pipeline collaborators.\n */\n\nimport type { PayloadFieldSchema, PayloadLivePreviewMessage } from '@/types/payload-protocol';\nimport type { EventEmitter } from '@events/emitter';\nimport type { SchemaIndex } from '@schema/index';\nimport type { SanitizerPolicyMode } from '@security/sanitizer';\nimport type { A11yAnnouncer } from './a11y';\nimport type { AutoBindMode, KeptGuesses } from './auto-bind';\nimport type { ElementCache } from './cache';\nimport type { DataMerger } from './data-merger';\nimport type { UnfaithfulPatchMode } from './fidelity';\nimport type { HydrationMode, HydrationState } from './hydration';\nimport { FieldChangeTracker } from './field-changes';\nimport { MergeNeed } from './merge-need';\nimport type { MessageBus, MessageRevision } from './message-bus';\nimport type { ObserverManager } from './observers';\nimport { ProtocolTracker } from './protocol-tracker';\nimport { RelationshipTracker } from './relationship-tracker';\nimport { FieldRevealer } from './reveal';\nimport { RevealLedger } from './reveal-ledger';\nimport type { RuntimeOptions } from './runtime-options';\nimport type { ConnectionState, HeartbeatTimer } from './state';\nimport type { StrategyHandlers } from './strategies';\nimport type { CachedElement, FieldRenderer, RichTextRenderer } from './types';\nimport type { FlushStats, UpdateScheduler } from './update-scheduler';\n\n/** One accepted message on its way to the DOM. See ADR 0004. */\nexport interface UpdateTransaction {\n readonly revision: MessageRevision;\n readonly message: PayloadLivePreviewMessage;\n readonly locale: string | undefined;\n readonly schema: readonly PayloadFieldSchema[] | undefined;\n readonly schemaIndex: SchemaIndex | undefined;\n readonly receivedAt: number;\n /** A save in another document may change populated values only, so render everything. */\n readonly forceRender: boolean;\n /** Top-level fields whose value changed since the previous message, plus their dependents. */\n touched: ReadonlySet<string>;\n /** The connection's first message, where every field counts as changed. */\n baseline: boolean;\n /** Dependents of changed fields; re-applied even when their own value is unchanged. */\n invalidated: ReadonlySet<string>;\n /**\n * First binding whose value changed; revealed once its write landed. The\n * binding itself, not its field name: several documents on one page share\n * field names, and only this one belongs to the edited document.\n */\n revealTarget: CachedElement | undefined;\n /**\n * Identities the reveal ledger will record once this revision reaches its\n * reveal point — not before. A revision superseded on the way there never\n * revealed, so the ledger must still show the previous value: the message\n * that supersedes it is then the one that owes the reveal.\n */\n revealIdentities: [key: string, identity: string][];\n pendingFragments: number;\n routeRefreshed: boolean;\n cancelled: boolean;\n /** Terminal: the scheduled writes reached the DOM (or there were none). */\n completed: boolean;\n}\n\nexport interface RuntimeDeps {\n readonly emitter: EventEmitter;\n readonly cache: ElementCache;\n readonly observers: ObserverManager;\n readonly scheduler: UpdateScheduler;\n readonly bus: MessageBus;\n readonly connection: ConnectionState;\n readonly heartbeat: HeartbeatTimer;\n readonly renderers: Readonly<Record<string, FieldRenderer>>;\n readonly resolveRenderer: NonNullable<RuntimeOptions['resolveRenderer']>;\n readonly transformValue: RuntimeOptions['transformValue'];\n readonly renderRichText: RichTextRenderer | undefined;\n readonly sanitizerPolicy: SanitizerPolicyMode | undefined;\n readonly root: Document | Element;\n readonly readyTargets: () => readonly string[];\n readonly sendReady: (origins: readonly string[]) => void;\n readonly onHeartbeatTimeout: RuntimeOptions['onHeartbeatTimeout'];\n readonly log: (...args: unknown[]) => void;\n readonly warn: (...args: unknown[]) => void;\n readonly a11y: A11yAnnouncer | null;\n readonly merger: DataMerger | null;\n /** How long a burst of messages may share one merge; the scheduler's debounce window. */\n readonly mergeWindowMs: number;\n readonly scopeBindingsByOwner: boolean;\n readonly lockedOrigin: () => string | undefined;\n readonly skipUnchanged: boolean;\n readonly dependencies: Readonly<Record<string, readonly string[]>>;\n readonly strategies: StrategyHandlers;\n readonly revealEditedField: boolean;\n /** What to do about a patch the runtime knows cannot match the server's render. */\n readonly onUnfaithfulPatch: UnfaithfulPatchMode;\n /** Whether the first message is searched for bindings by value (ADR 0014). */\n readonly autoBind: AutoBindMode;\n /** The framework whose first commit the start waits for (ADR 0015); `undefined` on a page that declared none. */\n readonly hydration: HydrationMode | undefined;\n}\n\nexport class RuntimeState {\n started = false;\n /** Set by `suspend()`; lets `destroy()` finish a suspended instance. */\n suspended = false;\n /** Cancels a startup still waiting — for `DOMContentLoaded`, or for the framework's first commit (ADR 0015). */\n deferredStart: (() => void) | null = null;\n /** How far the wait for hydration got; `idle` on a page that declared none. */\n hydration: HydrationState = 'idle';\n activeUpdate: UpdateTransaction | null = null;\n locale: string | undefined = undefined;\n schema: readonly PayloadFieldSchema[] | undefined = undefined;\n schemaIndex: SchemaIndex | undefined = undefined;\n updateCount = 0;\n supersededCount = 0;\n completedCount = 0;\n skippedUnchangedCount = 0;\n lastFlush: FlushStats | null = null;\n readonly absentFields = new Set<string>();\n readonly warnedOrphanFields = new Set<string>();\n readonly warnedStrategy = new WeakSet<Element>();\n warnedUnattributableMessage = false;\n warnedVisibilityGate = false;\n warnedFragmentFallback = false;\n /** LP0503 is reported once: a drifting sender repeats the same shape on every keystroke. */\n warnedProtocolShape = false;\n /** LP0411 is reported once per element; the markup that causes it does not change. */\n readonly reportedUnfaithful = new WeakSet<Element>();\n /** Bindings whose first write has already been held against what the template printed (LP0412). */\n readonly checkedServerFormat = new WeakSet<Element>();\n /** Bindings this revision could not patch faithfully, drained by the flush that escalates them. */\n unfaithfulPatches: CachedElement[] = [];\n /** Every binding ever reported unfaithful, and how many of them a strategy was handed; `inspect().fidelity`. */\n unfaithfulCount = 0;\n escalatedCount = 0;\n readonly unfaithfulFields = new Set<string>();\n /** What the one auto-binding search cost, for `inspect()`; `undefined` until it ran. */\n autoBindSearchMs: number | undefined = undefined;\n /** What that search bound, looked for again after a route refresh (ADR 0014); `null` until it ran. */\n autoBindGuesses: KeptGuesses | null = null;\n\n /**\n * Whether the first message refused for coming from the wrong window has been\n * reported. `eventSourcePolicy` flipped from `'any'` to `'parent-or-opener'`\n * in 2.0, so a 1.x arrangement that posts from anywhere else stops working on\n * upgrade — silently, because a refusal only reaches the debug log.\n */\n warnedForeignSource = false;\n /** Identity of the value each element last applied; reset when the markup is re-rendered. */\n lastAppliedIdentity = new WeakMap<Element, string>();\n /** What each owned field was last seen with, for the reveal decision only. */\n readonly revealLedger = new RevealLedger();\n readonly fragmentStats = { rendered: 0, failed: 0, superseded: 0 };\n readonly routeStats = { refreshes: 0, failed: 0, refused: 0, loopStopped: 0 };\n fragmentController: AbortController | null = null;\n routeController: AbortController | null = null;\n /** The trailing run a refused refresh asked for; at most one, and always the newest. */\n routeRetry: ReturnType<typeof setTimeout> | null = null;\n readonly readyTimers: ReturnType<typeof setTimeout>[] = [];\n readonly revealer = new FieldRevealer();\n readonly changes = new FieldChangeTracker();\n readonly merges = new MergeNeed();\n readonly protocol = new ProtocolTracker();\n readonly relationships = new RelationshipTracker();\n\n /** Read through a method: TypeScript keeps a narrowed `started` across the calls that can flip it. */\n isRunning(): boolean {\n return this.started;\n }\n\n /** Whether `transaction` may still touch the DOM; re-checked after every reentrant callback. */\n isCurrent(transaction: UpdateTransaction): boolean {\n return this.started && this.activeUpdate === transaction;\n }\n\n complete(transaction: UpdateTransaction): void {\n if (transaction.completed) return;\n transaction.completed = true;\n this.completedCount += 1;\n }\n\n /**\n * Abort in-flight strategy work; a newer revision or a stop supersedes it.\n * The trailing route refresh goes with it: the revision that asked for it is\n * no longer the one on screen, and the newer one decides for itself — its\n * message carries the older one's values too.\n */\n abortStrategies(): void {\n if (this.routeRetry !== null) {\n clearTimeout(this.routeRetry);\n this.routeRetry = null;\n }\n for (const key of ['fragmentController', 'routeController'] as const) {\n const controller = this[key];\n if (controller === null) continue;\n this[key] = null;\n controller.abort();\n }\n }\n}\n","/**\n * Writes one scheduled value into its bound element: renderer resolution,\n * the attribute or renderer write, and the `elementUpdate` event. Every\n * consumer callback may accept a newer revision synchronously, so the\n * transaction is re-checked after each one (ADR 0004).\n */\n\nimport { definedOnly } from '@/types/defined-only';\nimport { sameRevision } from './message-bus';\nimport { lookupSchema, payloadTypeToRenderer } from '@schema/index';\nimport { applyAttributeBinding } from './attribute-binding';\nimport { reportServerFormatting, reportUnfaithfulPatch, watchServerFormatting } from './fidelity';\nimport { rendererUsesNoWriteOutcome } from './internal-outcome';\nimport { type RuntimeDeps, type RuntimeState, type UpdateTransaction } from './runtime-state';\nimport type { CachedElement, FieldRenderer, RenderContext, RendererKey } from './types';\nimport type { ScheduledUpdate } from './update-scheduler';\n\nexport class BindingWriter {\n /** The instance's share of every `RenderContext`, built once: a write allocates the context alone. */\n private readonly instanceContext: Pick<\n RenderContext,\n 'renderRichText' | 'sanitizerPolicy' | 'reportUnfaithful'\n >;\n\n constructor(\n private readonly deps: RuntimeDeps,\n private readonly state: RuntimeState,\n ) {\n this.instanceContext = definedOnly({\n renderRichText: deps.renderRichText,\n sanitizerPolicy: deps.sanitizerPolicy,\n // A renderer already holds its target, so one closure per instance says\n // as much as one per write and allocates nothing during an update.\n reportUnfaithful: (target: CachedElement, reason: string): void => {\n reportUnfaithfulPatch(deps, state, target, reason);\n },\n });\n }\n\n /** Scheduler callback. `false` means nothing reached the DOM. */\n apply(update: ScheduledUpdate): boolean {\n const { deps, state } = this;\n const transaction = state.activeUpdate;\n if (\n transaction === null ||\n update.revision === undefined ||\n !sameRevision(transaction.revision, update.revision) ||\n !state.isCurrent(transaction)\n ) {\n return false;\n }\n const { target, value } = update;\n const schemaEntry =\n transaction.schemaIndex !== undefined\n ? lookupSchema(transaction.schemaIndex, target.fieldName)\n : undefined;\n let type = resolveFieldType(target, schemaEntry?.type);\n // Payload 3.x sends no schema; a Lexical root is unmistakable.\n if (type === 'text' && target.explicitFieldType !== true && looksLikeLexicalRoot(value)) {\n type = 'richText';\n }\n let renderer: FieldRenderer | undefined;\n try {\n renderer = deps.resolveRenderer(type, target);\n } catch (error) {\n return this.fail(transaction, error);\n }\n if (!state.isCurrent(transaction)) return false;\n const emitElementUpdate = deps.emitter.listenerCount('elementUpdate') > 0;\n // Custom-element accessors run application code, so this is a boundary too.\n const previous = emitElementUpdate ? readElementSnapshot(target.element) : undefined;\n if (!state.isCurrent(transaction)) return false;\n const context: RenderContext = {\n allFields: update.allFields,\n locale: target.locale ?? transaction.locale,\n schema: schemaEntry,\n ...this.instanceContext,\n };\n // A boundary anchor stays out of layout and the accessibility tree while empty.\n if (target.hidesWhenEmpty === true) {\n target.element.toggleAttribute('hidden', isEmptyFieldValue(value));\n }\n try {\n if (target.targetAttribute !== undefined) {\n if (applyAttributeBinding(target.element, target.targetAttribute, value) === 'blocked') {\n deps.warn(\n `[live-preview] LP0401: refused to write \"${target.fieldName}\" into attribute \"${target.targetAttribute}\"`,\n );\n return false;\n }\n } else if (renderer !== undefined) {\n // Read before the write, because afterwards the template's own reading\n // of this value is gone (Z20). Costs nothing unless this is the first\n // write to a binding a formatting renderer owns.\n const shown = watchServerFormatting(deps, state, target, type);\n const outcome = invokeRenderer(renderer, target, value, context);\n if (outcome === false && rendererUsesNoWriteOutcome(renderer)) {\n // The renderer refused the value it was given, so the element still\n // shows what the server put there — right until the next edit makes\n // it stale. That is the moment to ask for better markup.\n reportUnfaithfulPatch(deps, state, target, `is a value ${renderer.name} cannot render`);\n return false;\n }\n if (shown !== undefined) reportServerFormatting(deps, target, shown);\n } else {\n deps.log('no renderer for', type);\n reportUnfaithfulPatch(deps, state, target, `has no renderer for \"${type}\"`);\n return false;\n }\n } catch (error) {\n return this.fail(transaction, error);\n }\n if (!state.isCurrent(transaction)) return false;\n if (emitElementUpdate) {\n void deps.emitter.emitWhile(\n 'elementUpdate',\n {\n element: target.element,\n fieldName: target.fieldName,\n previousValue: previous,\n nextValue: value,\n revision: transaction.revision.revision,\n receivedAt: transaction.receivedAt,\n source: 'patch',\n },\n () => state.isCurrent(transaction),\n );\n }\n // The first handler runs before emitWhile yields; a reentrant newer\n // revision must not count this write as applied.\n const applied = state.isCurrent(transaction);\n if (applied) {\n if (update.valueIdentity !== undefined) {\n state.lastAppliedIdentity.set(target.element, update.valueIdentity);\n } else {\n state.lastAppliedIdentity.delete(target.element);\n }\n }\n return applied;\n }\n\n private fail(transaction: UpdateTransaction, cause: unknown): false {\n if (!this.state.isCurrent(transaction)) return false;\n const error = cause instanceof Error ? cause : new Error(String(cause));\n void this.deps.emitter.emitWhile('error', { error, context: 'renderer', code: 'LP0603' }, () =>\n this.state.isCurrent(transaction),\n );\n return false;\n }\n}\n\n/** Explicit `data-payload-type` wins over the schema, which wins over tag heuristics. */\nfunction resolveFieldType(target: CachedElement, schemaType: string | undefined): RendererKey {\n if (target.explicitFieldType) return target.fieldType;\n if (schemaType !== undefined) {\n const mapped = payloadTypeToRenderer(schemaType);\n if (mapped !== undefined) return mapped;\n }\n return target.fieldType;\n}\n\n/** Built-in renderers may return exact `false` for a deliberate no-write; the public type stays `void`. */\nfunction invokeRenderer(\n renderer: FieldRenderer,\n target: CachedElement,\n value: unknown,\n context: RenderContext,\n): unknown {\n // eslint-disable-next-line @typescript-eslint/no-confusing-void-expression\n return renderer.render(target, value, context);\n}\n\n/** Same shape test as `isLexicalContent`, duplicated so core does not pull the Lexical renderer. */\nfunction looksLikeLexicalRoot(value: unknown): boolean {\n if (typeof value !== 'object' || value === null || !('root' in value)) return false;\n const root = value.root;\n return (\n typeof root === 'object' &&\n root !== null &&\n Array.isArray((root as { children?: unknown }).children)\n );\n}\n\nfunction readElementSnapshot(element: Element): unknown {\n if (element.tagName === 'INPUT' || element.tagName === 'TEXTAREA') {\n return (element as HTMLInputElement).value;\n }\n if (element.tagName === 'IMG') return (element as HTMLImageElement).src;\n return element.textContent;\n}\n\nfunction isEmptyFieldValue(value: unknown): boolean {\n if (value === null || value === undefined) return true;\n if (typeof value === 'string') return value.trim().length === 0;\n return Array.isArray(value) && value.length === 0;\n}\n","/**\n * One source → dependents map for `skipUnchanged`. Markup declares it the\n * other way round (`data-payload-depends=\"price\"` on the element bound to\n * `priceLabel`) because an author names what a binding needs; the runtime\n * option is keyed by source because the scheduler asks what changed.\n * @internal\n */\n\nexport type DependencyMap = Readonly<Record<string, readonly string[]>>;\n\n/**\n * Field names from an attribute value. Separators are commas and\n * whitespace; empty entries are dropped; order is kept, duplicates removed.\n * @internal\n */\nexport function parseDependencyList(value: string | null | undefined): readonly string[] {\n if (value === null || value === undefined) return [];\n const seen = new Set<string>();\n const names: string[] = [];\n for (const raw of value.split(/[\\s,]+/)) {\n const name = raw.trim();\n if (name.length === 0 || seen.has(name)) continue;\n seen.add(name);\n names.push(name);\n }\n return names;\n}\n\n/**\n * Merge dependency maps (source → dependents). Later maps add to earlier\n * ones; a dependent is listed once per source.\n * @internal\n */\nexport function mergeDependencyMaps(...maps: readonly DependencyMap[]): DependencyMap {\n const merged = new Map<string, Set<string>>();\n for (const map of maps) {\n for (const [source, dependents] of Object.entries(map)) {\n let bucket = merged.get(source);\n if (bucket === undefined) {\n bucket = new Set();\n merged.set(source, bucket);\n }\n for (const dependent of dependents) bucket.add(dependent);\n }\n }\n const result: Record<string, readonly string[]> = {};\n for (const [source, dependents] of merged) result[source] = [...dependents];\n return result;\n}\n\n/**\n * The map an element's `data-payload-depends` contributes: every declared\n * source points at this binding's field.\n * @internal\n */\nexport function dependencyMapFromBinding(\n fieldName: string,\n dependsOn: readonly string[],\n): DependencyMap {\n const map: Record<string, readonly string[]> = {};\n for (const source of dependsOn) {\n if (source === fieldName) continue;\n map[source] = [fieldName];\n }\n return map;\n}\n","/**\n * Hydrated islands own their subtree, so the runtime never patches inside one.\n * Instead every flush dispatches `payload-live-preview:update` on each island\n * root with the update in `detail`. `data-payload-island=\"patch\"` opts back in.\n * @internal\n */\n\nexport const ISLAND_EVENT = 'payload-live-preview:update';\n/** @internal */\nexport const ISLAND_ATTRIBUTE = 'data-payload-island';\nexport const ISLAND_SELECTOR = `astro-island, [${ISLAND_ATTRIBUTE}]`;\n\nexport interface IslandUpdateDetail {\n readonly fields: Readonly<Record<string, unknown>>;\n readonly revision: number;\n readonly receivedAt: number;\n readonly locale: string | undefined;\n}\n\nfunction isIslandRoot(element: Element): boolean {\n return element.tagName.toLowerCase() === 'astro-island' || element.hasAttribute(ISLAND_ATTRIBUTE);\n}\n\nfunction islandAllowsPatching(island: Element): boolean {\n return island.getAttribute(ISLAND_ATTRIBUTE) === 'patch';\n}\n\n/** Whether `element` itself is an island root that did not opt into patching. */\nexport function isIslandBoundary(element: Element): boolean {\n return isIslandRoot(element) && !islandAllowsPatching(element);\n}\n\n/** Whether `element` (or an ancestor) is an island that did not opt into patching. @internal */\nexport function isInsideIsland(element: Element): boolean {\n let current: Element | null = element;\n while (current !== null) {\n if (isIslandBoundary(current)) return true;\n current = current.parentElement;\n }\n return false;\n}\n\n/** Island roots under `root` that receive update events. */\nexport function collectIslands(root: ParentNode): Element[] {\n const islands: Element[] = [];\n for (const island of root.querySelectorAll(ISLAND_SELECTOR)) {\n if (!islandAllowsPatching(island)) islands.push(island);\n }\n return islands;\n}\n\nexport function dispatchIslandUpdate(\n islands: readonly Element[],\n detail: IslandUpdateDetail,\n): number {\n for (const island of islands) {\n island.dispatchEvent(\n new CustomEvent<IslandUpdateDetail>(ISLAND_EVENT, { detail, bubbles: false }),\n );\n }\n return islands.length;\n}\n","/**\n * Maps field names to their bound elements so an update walks the cache, not\n * the DOM. Everything an update needs about a binding is resolved here, once,\n * at build time.\n */\n\nimport {\n dependencyMapFromBinding,\n mergeDependencyMaps,\n parseDependencyList,\n type DependencyMap,\n} from './dependencies';\nimport { collectIslands } from './islands';\nimport { enclosingFragment, resolveStrategy } from './strategies';\nimport type { CachedElement, ElementPredicate, FieldType, RendererKey } from './types';\n\nexport const FIELD_ATTRIBUTE = 'data-payload-field';\nexport const TYPE_ATTRIBUTE = 'data-payload-type';\nexport const TARGET_ATTRIBUTE_ATTRIBUTE = 'data-payload-attribute';\nexport const HREF_ATTRIBUTE = 'data-payload-href';\nexport const SRC_ATTRIBUTE = 'data-payload-src';\nexport const ALT_ATTRIBUTE = 'data-payload-alt';\nexport const ARRAY_TEMPLATE_ATTRIBUTE = 'data-payload-array-template';\nexport const ARRAY_SEPARATOR_ATTRIBUTE = 'data-payload-array-separator';\nexport const LOCALE_ATTRIBUTE = 'data-payload-locale';\nexport const FORMAT_ATTRIBUTE = 'data-payload-format';\nexport const RICH_TEXT_ATTRIBUTE = 'data-payload-richtext';\nexport const HTML_ATTRIBUTE = 'data-payload-html';\nexport const ARRAY_ATTRIBUTE = 'data-payload-array';\nexport const STRUCTURAL_ATTRIBUTE = 'data-payload-structural';\nexport const OWNER_ATTRIBUTE = 'data-payload-owner';\nexport const DEPENDS_ATTRIBUTE = 'data-payload-depends';\nexport const STRATEGY_ATTRIBUTE = 'data-payload-strategy';\nexport const BOUNDARY_ATTRIBUTE = 'data-payload-boundary';\n/**\n * Written by the runtime, never by a template: the value an auto-binding\n * matched on (ADR 0014). Its presence is what tells a guessed binding from a\n * declared one, in `inspect()` and in the overlay.\n */\nexport const GUESSED_ATTRIBUTE = 'data-payload-guessed';\nexport const INPUT_TYPE_ATTRIBUTE = 'type';\n\n/**\n * Attributes captured in a `CachedElement`. The mutation observer watches\n * exactly this list, so a snapshot can never go stale on a mounted element.\n */\nexport const BINDING_ATTRIBUTES: readonly string[] = [\n FIELD_ATTRIBUTE,\n TYPE_ATTRIBUTE,\n TARGET_ATTRIBUTE_ATTRIBUTE,\n HREF_ATTRIBUTE,\n SRC_ATTRIBUTE,\n ALT_ATTRIBUTE,\n ARRAY_TEMPLATE_ATTRIBUTE,\n ARRAY_SEPARATOR_ATTRIBUTE,\n LOCALE_ATTRIBUTE,\n RICH_TEXT_ATTRIBUTE,\n HTML_ATTRIBUTE,\n ARRAY_ATTRIBUTE,\n STRUCTURAL_ATTRIBUTE,\n OWNER_ATTRIBUTE,\n DEPENDS_ATTRIBUTE,\n STRATEGY_ATTRIBUTE,\n BOUNDARY_ATTRIBUTE,\n INPUT_TYPE_ATTRIBUTE,\n];\n\nconst FIELD_SELECTOR = `[${FIELD_ATTRIBUTE}]`;\nconst OWNER_SELECTOR = `[${OWNER_ATTRIBUTE}]`;\n\n/** The document a binding belongs to: its nearest `data-payload-owner`, itself included. */\nexport function resolveBindingOwner(element: Element): string | undefined {\n const owner = element.closest(OWNER_SELECTOR)?.getAttribute(OWNER_ATTRIBUTE);\n return owner === null || owner === undefined || owner.length === 0 ? undefined : owner;\n}\n\n/** `namespace:name` — a project renderer key can never be a typo of a built-in type. */\nconst CUSTOM_RENDERER_KEY = /^[a-z][a-z0-9-]*:[a-z][a-z0-9-]*$/i;\n\nconst VALID_FIELD_TYPES: ReadonlySet<FieldType> = new Set<FieldType>([\n 'text',\n 'textarea',\n 'richText',\n 'email',\n 'number',\n 'checkbox',\n 'date',\n 'select',\n 'radio',\n 'array',\n 'blocks',\n 'group',\n 'tabs',\n 'row',\n 'collapsible',\n 'relationship',\n 'upload',\n 'point',\n 'json',\n 'code',\n 'ui',\n 'html',\n 'url',\n 'image',\n 'structural-array',\n]);\n\nfunction isRendererKey(value: string): value is RendererKey {\n return VALID_FIELD_TYPES.has(value as FieldType) || CUSTOM_RENDERER_KEY.test(value);\n}\n\nexport interface CacheBuildStats {\n readonly elementCount: number;\n readonly fieldCount: number;\n readonly durationMs: number;\n}\n\nexport interface ElementCacheOptions {\n /** Restricts which elements are accepted. Defaults to all. */\n readonly filter?: ElementPredicate;\n}\n\n/**\n * Elements share a field name when the same field is rendered in several\n * places; within a field the order is DOM order.\n */\nexport class ElementCache {\n private readonly entriesByField = new Map<string, CachedElement[]>();\n private entryByElement = new WeakMap<Element, CachedElement>();\n private readonly filter: ElementPredicate;\n private count = 0;\n private dependencies: DependencyMap | null = null;\n private islandRoots: readonly Element[] = [];\n\n constructor(options: ElementCacheOptions = {}) {\n this.filter = options.filter ?? alwaysTrue;\n }\n\n /** Source → dependents declared with `data-payload-depends`; memoised until the cache changes. */\n dependencyMap(): DependencyMap {\n if (this.dependencies !== null) return this.dependencies;\n const maps: DependencyMap[] = [];\n for (const binding of this.values()) {\n if (binding.dependsOn !== undefined) {\n maps.push(dependencyMapFromBinding(binding.fieldName, binding.dependsOn));\n }\n }\n this.dependencies = mergeDependencyMaps(...maps);\n return this.dependencies;\n }\n\n /** Island roots under the last built root, for update events. */\n get islands(): readonly Element[] {\n return this.islandRoots;\n }\n\n buildFromRoot(root: ParentNode): CacheBuildStats {\n const t0 = performance.now();\n this.clear();\n let elementCount = 0;\n for (const element of root.querySelectorAll(FIELD_SELECTOR)) {\n if (this.add(element) !== undefined) elementCount += 1;\n }\n this.islandRoots = collectIslands(root);\n return {\n elementCount,\n fieldCount: this.entriesByField.size,\n durationMs: performance.now() - t0,\n };\n }\n\n /**\n * Insert or replace a single element's binding. Re-adding refreshes the\n * snapshot in place; an element that is now filtered or unbound is removed.\n */\n add(element: Element): CachedElement | undefined {\n // Resolve before mutating so a throwing filter leaves the old entry intact.\n const entry = this.filter(element) ? this.resolveBinding(element) : undefined;\n const previous = this.entryByElement.get(element);\n this.dependencies = null;\n if (entry === undefined) {\n if (previous !== undefined) this.removeEntry(element, previous);\n return undefined;\n }\n if (previous !== undefined && this.replaceEntry(previous, entry)) {\n this.entryByElement.set(element, entry);\n return entry;\n }\n if (previous !== undefined) this.removeEntry(element, previous);\n this.append(entry);\n this.entryByElement.set(element, entry);\n return entry;\n }\n\n /** Returns whether a binding was removed. */\n remove(element: Element): boolean {\n const entry = this.entryByElement.get(element);\n if (!entry) return false;\n this.dependencies = null;\n return this.removeEntry(element, entry);\n }\n\n get(fieldName: string): readonly CachedElement[] | undefined {\n return this.entriesByField.get(fieldName);\n }\n\n getByElement(element: Element): CachedElement | undefined {\n return this.entryByElement.get(element);\n }\n\n get fieldCount(): number {\n return this.entriesByField.size;\n }\n\n get elementCount(): number {\n return this.count;\n }\n\n entries(): IterableIterator<[string, readonly CachedElement[]]> {\n return this.entriesByField.entries() as IterableIterator<[string, readonly CachedElement[]]>;\n }\n\n *values(): IterableIterator<CachedElement> {\n for (const bucket of this.entriesByField.values()) yield* bucket;\n }\n\n has(element: Element): boolean {\n return this.entryByElement.has(element);\n }\n\n clear(): void {\n this.entriesByField.clear();\n // WeakMap cannot be cleared; a detached element must not observe stale membership.\n this.entryByElement = new WeakMap();\n this.count = 0;\n this.dependencies = null;\n this.islandRoots = [];\n }\n\n /** Replace in place when the field bucket is unchanged, preserving order. */\n private replaceEntry(previous: CachedElement, next: CachedElement): boolean {\n if (previous.fieldName !== next.fieldName) return false;\n const bucket = this.entriesByField.get(previous.fieldName);\n const index = bucket === undefined ? -1 : bucket.indexOf(previous);\n if (bucket === undefined || index < 0) return false;\n bucket[index] = next;\n return true;\n }\n\n private removeEntry(element: Element, entry: CachedElement): boolean {\n this.entryByElement.delete(element);\n const bucket = this.entriesByField.get(entry.fieldName);\n const index = bucket === undefined ? -1 : bucket.indexOf(entry);\n if (bucket === undefined || index < 0) return false;\n bucket.splice(index, 1);\n if (bucket.length === 0) this.entriesByField.delete(entry.fieldName);\n this.count -= 1;\n return true;\n }\n\n private append(entry: CachedElement): void {\n const bucket = this.entriesByField.get(entry.fieldName);\n if (bucket) bucket.push(entry);\n else this.entriesByField.set(entry.fieldName, [entry]);\n this.count += 1;\n }\n\n private resolveBinding(element: Element): CachedElement | undefined {\n const fieldName = element.getAttribute(FIELD_ATTRIBUTE);\n if (fieldName === null || fieldName.length === 0) return undefined;\n const explicit = element.getAttribute(TYPE_ATTRIBUTE);\n const targetAttribute = element.getAttribute(TARGET_ATTRIBUTE_ATTRIBUTE);\n const hrefField = element.getAttribute(HREF_ATTRIBUTE);\n const srcField = element.getAttribute(SRC_ATTRIBUTE);\n const altField = element.getAttribute(ALT_ATTRIBUTE);\n const arrayTemplate = element.getAttribute(ARRAY_TEMPLATE_ATTRIBUTE);\n const arraySeparator = element.getAttribute(ARRAY_SEPARATOR_ATTRIBUTE);\n const locale = element.getAttribute(LOCALE_ATTRIBUTE);\n const format = element.getAttribute(FORMAT_ATTRIBUTE);\n const owner = resolveBindingOwner(element);\n const dependsOn = parseDependencyList(element.getAttribute(DEPENDS_ATTRIBUTE));\n const strategy = element.getAttribute(STRATEGY_ATTRIBUTE);\n const guessed = element.getAttribute(GUESSED_ATTRIBUTE);\n const fragmentBoundary = enclosingFragment(element);\n return {\n element,\n fieldName,\n fieldType: resolveFieldType(element),\n explicitFieldType: explicit !== null && isRendererKey(explicit),\n strategyKind: resolveStrategy(element) ?? 'unknown',\n ...(fragmentBoundary !== null ? { fragmentBoundary } : {}),\n ...(targetAttribute !== null && targetAttribute.length > 0 ? { targetAttribute } : {}),\n ...(hrefField !== null && hrefField.length > 0 ? { hrefField } : {}),\n ...(srcField !== null && srcField.length > 0 ? { srcField } : {}),\n ...(altField !== null && altField.length > 0 ? { altField } : {}),\n ...(arrayTemplate !== null ? { arrayTemplate } : {}),\n ...(arraySeparator !== null ? { arraySeparator } : {}),\n ...(locale !== null && locale.length > 0 ? { locale } : {}),\n ...(format !== null && format.length > 0 ? { format } : {}),\n ...(owner !== undefined ? { owner } : {}),\n ...(dependsOn.length > 0 ? { dependsOn } : {}),\n ...(strategy !== null && strategy.length > 0 ? { strategy } : {}),\n ...(element.hasAttribute(BOUNDARY_ATTRIBUTE) ? { hidesWhenEmpty: true } : {}),\n ...(guessed !== null ? { guessed } : {}),\n };\n }\n}\n\n/** Explicit `data-payload-type`, then element heuristics, then `text`. */\nexport function resolveFieldType(element: Element): RendererKey {\n const explicit = element.getAttribute(TYPE_ATTRIBUTE);\n if (explicit !== null && isRendererKey(explicit)) return explicit;\n if (element.hasAttribute(RICH_TEXT_ATTRIBUTE)) return 'richText';\n if (element.hasAttribute(HTML_ATTRIBUTE)) return 'html';\n if (element.hasAttribute(STRUCTURAL_ATTRIBUTE)) return 'structural-array';\n if (element.hasAttribute(ARRAY_ATTRIBUTE)) return 'array';\n if (element.tagName === 'IMG') return 'image';\n if (element.tagName === 'A') return 'url';\n if (element.tagName === 'TIME') return 'date';\n if (element.tagName === 'INPUT') {\n const inputType = (element as HTMLInputElement).type;\n if (inputType === 'checkbox') return 'checkbox';\n if (inputType === 'number') return 'number';\n if (inputType === 'date' || inputType === 'datetime-local') return 'date';\n }\n return 'text';\n}\n\nfunction alwaysTrue(): boolean {\n return true;\n}\n","/**\n * Server-side merge for Payload 3.x, whose admin posts raw form values with\n * relationships as bare ids. Like the official client, the update is re-fetched\n * through the REST API with `X-Payload-HTTP-Method-Override: GET`, which\n * merges the form values into the stored document and returns it populated.\n * Only the newest request matters: a newer merge aborts the one in flight.\n */\n\nimport { isolateDiagnostic, noopDiagnostic } from './diagnostics';\n\nexport interface DataMergerOptions {\n /** Payload server origin, e.g. `https://cms.example.com`. */\n readonly serverURL: string;\n /** REST route prefix. Defaults to `/api`. */\n readonly apiRoute?: string;\n /** Population depth requested from the server. Defaults to `1`. */\n readonly depth?: number;\n readonly fetchFn?: typeof fetch;\n readonly log?: (...args: unknown[]) => void;\n}\n\nexport interface MergeRequest {\n readonly collectionSlug?: string | undefined;\n readonly globalSlug?: string | undefined;\n readonly data: Record<string, unknown>;\n readonly locale?: string | undefined;\n}\n\n/** `superseded`: a newer merge replaced this one. `unavailable`: fall back to the raw values. */\nexport type MergeResult =\n | { readonly status: 'merged'; readonly doc: Record<string, unknown> }\n | { readonly status: 'superseded' }\n | { readonly status: 'unavailable' };\n\nfunction hasControlCharacter(value: string): boolean {\n for (const character of value) {\n // An iterated character always has a code point; 0 keeps the type and fails closed.\n const codePoint = character.codePointAt(0) ?? 0;\n if (codePoint <= 0x1f || codePoint === 0x7f) return true;\n }\n return false;\n}\n\n/** One path segment: non-empty, bounded, not a dot segment, without separators or control characters. */\nfunction isPathSegment(value: string, maxLength: number): boolean {\n return (\n value.length > 0 &&\n value.length <= maxLength &&\n value !== '.' &&\n value !== '..' &&\n !value.includes('/') &&\n !value.includes('\\\\') &&\n !hasControlCharacter(value)\n );\n}\n\n/** A slug is one of Payload's own names; `?` and `#` never belong in one. */\nfunction isSafeSlug(value: string): boolean {\n return isPathSegment(value, 128) && !value.includes('?') && !value.includes('#');\n}\n\n/** An id comes from the form values; a string one is encoded, so `?` and `#` may appear. */\nfunction isSafeId(value: unknown): value is string | number {\n if (typeof value === 'number') return Number.isFinite(value);\n return typeof value === 'string' && isPathSegment(value, 512);\n}\n\n/**\n * Trailing slashes off a base URL, without a regular expression: `/\\/+$/`\n * backtracks over a long run of slashes and takes quadratic time on input the\n * page supplies (CodeQL js/polynomial-redos).\n */\nfunction withoutTrailingSlashes(value: string): string {\n let end = value.length;\n while (value.endsWith('/', end)) end -= 1;\n return value.slice(0, end);\n}\n\nexport class DataMerger {\n private readonly serverURL: string;\n private readonly apiRoute: string;\n private readonly depth: number;\n private readonly fetchFn: typeof fetch | undefined;\n private readonly log: (...args: unknown[]) => void;\n private inflight: AbortController | null = null;\n private attempt = 0;\n private destroyDepth = 0;\n\n constructor(options: DataMergerOptions) {\n this.serverURL = withoutTrailingSlashes(options.serverURL);\n const route = options.apiRoute ?? '/api';\n this.apiRoute = route.startsWith('/') ? route : `/${route}`;\n this.depth = options.depth ?? 1;\n this.fetchFn = options.fetchFn;\n this.log = isolateDiagnostic(options.log ?? noopDiagnostic);\n }\n\n /** Collections need an `id` in the form values; globals only their slug. */\n canMerge(request: MergeRequest): boolean {\n return this.endpointOf(request) !== null;\n }\n\n /**\n * The path under `apiRoute`, or `null` when no safe one exists. A request\n * accessor that throws counts as none, and so does a lone surrogate, which\n * `encodeURIComponent` refuses with a `URIError`.\n */\n private endpointOf(request: MergeRequest): string | null {\n try {\n // An empty global slug means \"collection document\" on the wire.\n const globalSlug = request.globalSlug;\n if (globalSlug) {\n return isSafeSlug(globalSlug) ? `globals/${encodeURIComponent(globalSlug)}` : null;\n }\n const collectionSlug = request.collectionSlug ?? '';\n const id: unknown = request.data['id'];\n if (!isSafeSlug(collectionSlug) || !isSafeId(id)) return null;\n return `${encodeURIComponent(collectionSlug)}/${encodeURIComponent(String(id))}`;\n } catch {\n return null;\n }\n }\n\n async merge(request: MergeRequest): Promise<MergeResult> {\n if (this.destroyDepth > 0) return { status: 'superseded' };\n // Claim the attempt before aborting: abort listeners and fetch shims are\n // reentrant, and a newer merge they start must win. Nothing but this class\n // aborts the signal, and only after the counter moved, so the counter\n // alone decides who was superseded.\n const attempt = (this.attempt += 1);\n const previous = this.inflight;\n this.inflight = null;\n let controller: AbortController | null = null;\n const superseded = (): boolean => this.attempt !== attempt;\n try {\n previous?.abort();\n if (superseded()) return { status: 'superseded' };\n // The endpoint reads the request's own values, which may be consumer\n // getters that start a newer merge before throwing.\n const endpoint = this.endpointOf(request);\n if (endpoint === null) {\n return superseded() ? { status: 'superseded' } : { status: 'unavailable' };\n }\n const fetchFn = this.fetchFn ?? (typeof fetch === 'function' ? fetch : undefined);\n if (fetchFn === undefined) return { status: 'unavailable' };\n controller = new AbortController();\n this.inflight = controller;\n const url = `${this.serverURL}${this.apiRoute}/${endpoint}`;\n const response = await fetchFn(url, {\n method: 'POST',\n credentials: 'include',\n headers: {\n 'Content-Type': 'application/json',\n 'X-Payload-HTTP-Method-Override': 'GET',\n },\n // The admin already flattens locales before posting; an absent locale\n // is left out of the JSON.\n body: JSON.stringify({\n data: request.data,\n depth: this.depth,\n flattenLocales: false,\n locale: request.locale,\n }),\n signal: controller.signal,\n });\n // A fetch shim may ignore the signal; the attempt is authoritative.\n if (superseded()) return { status: 'superseded' };\n if (!response.ok) {\n this.log('merge HTTP', response.status, url);\n return { status: 'unavailable' };\n }\n const merged: unknown = await response.json();\n if (superseded()) return { status: 'superseded' };\n if (merged === null || typeof merged !== 'object' || Array.isArray(merged)) {\n this.log('merge invalid', url);\n return { status: 'unavailable' };\n }\n return { status: 'merged', doc: merged as Record<string, unknown> };\n } catch (error) {\n if (superseded()) return { status: 'superseded' };\n this.log('merge exception', error);\n return { status: 'unavailable' };\n } finally {\n // Only the newest attempt's controller is ever in flight: a superseded\n // attempt's is gone already, and its successor's is left alone.\n if (this.inflight === controller) this.inflight = null;\n }\n }\n\n /** Abort any in-flight merge. The merger stays usable across a stop/start cycle. */\n destroy(): void {\n this.attempt += 1;\n const inflight = this.inflight;\n this.inflight = null;\n this.destroyDepth += 1;\n try {\n inflight?.abort();\n } finally {\n this.destroyDepth -= 1;\n }\n }\n}\n","/**\n * What the peer does, derived from the capabilities its messages showed —\n * the runtime never asks which Payload version it is talking to. Unknown\n * until the admin reveals its shape. See ADR 0010.\n */\nimport type { ProtocolCapability } from './protocol-version';\n\nexport type ProtocolProfileName = 'unknown' | 'payload-2' | 'payload-3';\n\nexport interface ProtocolProfile {\n readonly name: ProtocolProfileName;\n /** Where field types come from. */\n readonly fieldTyping: 'schema' | 'heuristic';\n /**\n * Who populates relationships. Payload 2.x's admin posts populated data\n * (it merges client-side with `fieldSchemaJSON`); Payload 3.x posts raw\n * form values and the runtime asks the REST API when `serverURL` is set.\n */\n readonly populatesRelationships: 'admin' | 'server';\n /** Whether the peer reports document saves and relationship edits. */\n readonly documentEvents: boolean;\n}\n\nconst PAYLOAD_2: ProtocolProfile = {\n name: 'payload-2',\n fieldTyping: 'schema',\n populatesRelationships: 'admin',\n documentEvents: false,\n};\nconst PAYLOAD_3: ProtocolProfile = {\n name: 'payload-3',\n fieldTyping: 'heuristic',\n populatesRelationships: 'server',\n documentEvents: true,\n};\nconst UNKNOWN: ProtocolProfile = {\n name: 'unknown',\n fieldTyping: 'heuristic',\n populatesRelationships: 'server',\n documentEvents: false,\n};\n\n/**\n * `schema-json` on the wire is the Payload 2.x signature: 3.x removed\n * `fieldSchemaJSON`. Document or relationship events are 3.x-only. Until\n * either shows, the peer is unknown and treated like 3.x for merging — the\n * conservative choice, because a needless REST merge costs a request while\n * a missing one loses populated relationships.\n */\nexport function detectProtocolProfile(observed: ReadonlySet<ProtocolCapability>): ProtocolProfile {\n if (observed.has('schema-json')) return PAYLOAD_2;\n if (observed.has('document-events') || observed.has('relationship-events')) return PAYLOAD_3;\n return UNKNOWN;\n}\n","/**\n * Mutation and intersection observers: ask the host to rebuild the cache when\n * bindings appear, vanish or change metadata, and track which bound elements\n * are in the viewport so off-screen writes can wait. Kept apart from cache and\n * scheduler so tests can run without the browser observer APIs.\n */\n\nimport { BINDING_ATTRIBUTES, FIELD_ATTRIBUTE, OWNER_ATTRIBUTE } from './cache';\n\nexport interface ObserverCallbacks {\n readonly onStructuralChange: () => void;\n readonly onVisibilityChange: (element: Element, isVisible: boolean) => void;\n}\n\nexport interface ObserverOptions {\n /** Debounce for mutation batches in ms. Default 100. */\n readonly mutationDebounceMs?: number;\n /** `rootMargin` for the IntersectionObserver. Default `200px`. */\n readonly intersectionRootMargin?: string;\n}\n\nconst DEFAULT_DEBOUNCE_MS = 100;\nconst DEFAULT_ROOT_MARGIN = '200px';\n/** `nodeType` is stable across realms; the global `Node` constructor is not. */\nconst ELEMENT_NODE = 1;\n\nexport class ObserverManager {\n private readonly callbacks: ObserverCallbacks;\n private readonly debounceMs: number;\n private readonly rootMargin: string;\n private readonly visible = new Set<Element>();\n private mutation: MutationObserver | null = null;\n private intersection: IntersectionObserver | null = null;\n private debounceTimer: ReturnType<typeof setTimeout> | null = null;\n /** Bumped by every start/stop so deliveries from an older lifetime are inert. */\n private generation = 0;\n\n constructor(callbacks: ObserverCallbacks, options: ObserverOptions = {}) {\n this.callbacks = callbacks;\n this.debounceMs = options.mutationDebounceMs ?? DEFAULT_DEBOUNCE_MS;\n this.rootMargin = options.intersectionRootMargin ?? DEFAULT_ROOT_MARGIN;\n }\n\n /** Observe `root`; a repeated start hands over cleanly. */\n start(root: Node): void {\n const previousGeneration = this.generation;\n this.stop();\n const generation = previousGeneration + 1;\n // A disconnect hook may have started a newer generation; it owns the lifecycle.\n if (this.generation !== generation) return;\n let mutation: MutationObserver | null = null;\n let intersection: IntersectionObserver | null = null;\n try {\n mutation = new MutationObserver((mutations) => {\n this.handleMutations(mutations, generation);\n });\n // Both resources exist before either is live, so a missing IntersectionObserver leaves nothing behind.\n intersection = new IntersectionObserver(\n (entries) => {\n this.handleIntersection(entries, generation);\n },\n { rootMargin: this.rootMargin, threshold: 0 },\n );\n mutation.observe(root, {\n childList: true,\n subtree: true,\n attributes: true,\n attributeFilter: [...BINDING_ATTRIBUTES],\n });\n } catch (error) {\n mutation?.disconnect();\n intersection?.disconnect();\n throw error;\n }\n if (this.generation !== generation) {\n mutation.disconnect();\n intersection.disconnect();\n return;\n }\n this.mutation = mutation;\n this.intersection = intersection;\n }\n\n observeElement(element: Element): void {\n this.intersection?.observe(element);\n }\n\n unobserveElement(element: Element): void {\n this.intersection?.unobserve(element);\n this.visible.delete(element);\n }\n\n /** Seed visibility (tests). */\n markVisible(element: Element, visible: boolean): void {\n if (visible) this.visible.add(element);\n else this.visible.delete(element);\n }\n\n isVisible(element: Element): boolean {\n return this.visible.has(element);\n }\n\n /** Disconnect everything; safe to repeat. */\n stop(): void {\n // Invalidate first so queued deliveries and the timer are inert before disconnecting.\n this.generation += 1;\n const timer = this.debounceTimer;\n const mutation = this.mutation;\n const intersection = this.intersection;\n this.debounceTimer = null;\n this.mutation = null;\n this.intersection = null;\n this.visible.clear();\n if (timer !== null) clearTimeout(timer);\n try {\n mutation?.disconnect();\n } finally {\n intersection?.disconnect();\n }\n }\n\n private handleMutations(mutations: readonly MutationRecord[], generation: number): void {\n if (!this.isCurrentGeneration(generation) || !hasStructuralImpact(mutations)) return;\n if (this.debounceTimer !== null) clearTimeout(this.debounceTimer);\n const timer = setTimeout(() => {\n if (!this.isCurrentGeneration(generation) || this.debounceTimer !== timer) return;\n this.debounceTimer = null;\n this.callbacks.onStructuralChange();\n }, this.debounceMs);\n this.debounceTimer = timer;\n }\n\n private handleIntersection(\n entries: readonly IntersectionObserverEntry[],\n generation: number,\n ): void {\n for (const entry of entries) {\n if (!this.isCurrentGeneration(generation)) return;\n const { target } = entry;\n if (entry.isIntersecting) {\n if (this.visible.has(target)) continue;\n this.visible.add(target);\n this.callbacks.onVisibilityChange(target, true);\n } else if (this.visible.has(target)) {\n this.visible.delete(target);\n this.callbacks.onVisibilityChange(target, false);\n }\n }\n }\n\n private isCurrentGeneration(generation: number): boolean {\n return this.generation === generation && this.intersection !== null;\n }\n}\n\n/** Whether a mutation batch can change what is bound; unrelated DOM activity never rebuilds. */\nfunction hasStructuralImpact(mutations: readonly MutationRecord[]): boolean {\n for (const m of mutations) {\n if (\n m.type === 'attributes' &&\n m.attributeName !== null &&\n BINDING_ATTRIBUTES.includes(m.attributeName)\n ) {\n // The field and owner attributes matter anywhere; other metadata (notably\n // the native `type`) only on an element that is a binding.\n if (\n m.attributeName === FIELD_ATTRIBUTE ||\n m.attributeName === OWNER_ATTRIBUTE ||\n (m.target.nodeType === ELEMENT_NODE && (m.target as Element).hasAttribute(FIELD_ATTRIBUTE))\n ) {\n return true;\n }\n }\n for (const node of m.addedNodes) if (containsTrackedElement(node)) return true;\n for (const node of m.removedNodes) if (containsTrackedElement(node)) return true;\n }\n return false;\n}\n\nfunction containsTrackedElement(node: Node): boolean {\n if (node.nodeType !== ELEMENT_NODE) return false;\n const element = node as Element;\n return (\n element.hasAttribute(FIELD_ATTRIBUTE) || element.querySelector(`[${FIELD_ATTRIBUTE}]`) !== null\n );\n}\n","/**\n * Waiting for React before the first write (ADR 0015).\n *\n * A page a framework hydrates is not final when it is parsed: the client\n * bundle arrives later, walks the server markup and compares it with what it\n * would have rendered. A value the runtime wrote in between is a mismatch —\n * React 19 throws, discards the tree under the nearest Suspense boundary,\n * renders it again on the client, and the write is gone with it. Measured on\n * the Next fixture on 2026-09-11: the write at 93 ms, React's fiber on the\n * bound element at 174 ms, `Hydration failed` at 180 ms.\n *\n * Neither Next nor React says when hydration is done. What React does expose,\n * since 16 and for its own DevTools, is its instrumentation protocol: when\n * `react-dom` evaluates it looks for `window.__REACT_DEVTOOLS_GLOBAL_HOOK__`,\n * calls `inject()` if the hook says `supportsFiber`, and from then on\n * `onCommitFiberRoot(rendererId, root)` after every commit — each call guarded\n * by `typeof … === 'function'` and a `try`. The first commit of a root that\n * holds a binding is the moment React has taken the markup over; everything\n * before it is too early, and a commit into a root without a binding (Next's\n * dev overlay commits three times before the app does) is not ours to wait for.\n *\n * Two bundles read this: the runtime, which arms the hook when it starts, and\n * the bootstrap for asset delivery (`./loader`, built armed), where the runtime\n * itself is fetched and may evaluate after `react-dom`. They share one window\n * slot, read late, the way the route-refresh seam does.\n */\n\n/** The framework whose first commit the start waits for; `./hydration-vue` reads the second. */\nexport type HydrationMode = 'react' | 'vue';\nexport type HydrationOutcome = 'committed' | 'timed-out';\nexport type HydrationState = 'idle' | 'waiting' | HydrationOutcome;\n\n/**\n * How long the runtime waits for the commit before it starts anyway and says\n * so (LP0607). A page whose React never commits is broken; a preview that never\n * connects would hide that, one that connects five seconds late and says why\n * does not. A hydration slower than this regenerates the tree once, as before.\n */\nexport const HYDRATION_WAIT_CAP_MS = 5000;\n\n/** Where the prelude and the runtime meet. */\nexport const HYDRATION_SLOT = '__livePreviewHydration';\n\n/**\n * `[data-payload-field]`, spelled out rather than imported from `./cache`: the\n * armed bootstrap bundles this module beside the loader, and the import dragged\n * the cache's other selectors into a script that is measured to the byte. A\n * test holds it equal to `FIELD_ATTRIBUTE`.\n */\nexport const BINDING_SELECTOR = '[data-payload-field]';\n\n/**\n * What the two bundles share. The bootstrap only records: every container\n * React committed into goes to `commits` until the runtime, which alone knows\n * what a binding is, sets `onCommit` and judges the backlog and everything\n * after. Recording rather than judging keeps the armed bootstrap to the bytes\n * the delivery budgets hold a bootstrap to.\n */\ninterface HydrationSignal extends HydrationWait {\n armed: boolean;\n commits: unknown[];\n onCommit: ((container: unknown) => void) | undefined;\n}\n\n/**\n * What a wait shares whichever framework it is for: whether the framework has\n * taken the tree over, and who is waiting to hear it. The Vue observer keeps\n * one of its own (`./hydration-vue`); the cap and the cancel are the same.\n */\nexport interface HydrationWait {\n committed: boolean;\n waiters: (() => void)[];\n}\n\n/** The root React hands the hook after a commit; `containerInfo` is the DOM node it rendered into. */\ninterface FiberRootLike {\n readonly containerInfo?: unknown;\n}\n\n/**\n * The part of React's hook this module touches; the rest belongs to React and\n * its DevTools. React itself guards every other call it makes on the hook with\n * `typeof … === 'function'`; Fast Refresh (`react-refresh`, which every\n * development server runs) additionally walks `renderers` when it attaches,\n * and throws on a hook without the map — measured on the Next fixture, where\n * a hook without it stopped the page from hydrating at all.\n */\ninterface DevToolsHook {\n supportsFiber?: boolean;\n renderers?: Map<number, unknown>;\n inject?: (internals: unknown) => number;\n onCommitFiberRoot?: (\n this: unknown,\n rendererId: number,\n root?: FiberRootLike,\n ...rest: unknown[]\n ) => void;\n}\n\ntype HookWindow = Window & {\n __REACT_DEVTOOLS_GLOBAL_HOOK__?: DevToolsHook;\n [HYDRATION_SLOT]?: HydrationSignal;\n};\n\nfunction signalSlot(): HydrationSignal | undefined {\n if (typeof window === 'undefined') return undefined;\n const w = window as HookWindow;\n return (w[HYDRATION_SLOT] ??= {\n armed: false,\n committed: false,\n commits: [],\n onCommit: undefined,\n waiters: [],\n });\n}\n\n/**\n * Arm before React evaluates: install the hook React injects into when the\n * page has none, or wrap `onCommitFiberRoot` on the one that is there — the\n * React DevTools extension injects its own at `document_start`, and it keeps\n * working because the previous function runs first. Idempotent.\n */\nexport function armReactCommitSignal(): void {\n const signal = signalSlot();\n if (signal === undefined || signal.armed) return;\n signal.armed = true;\n const w = window as HookWindow;\n const hook = (w.__REACT_DEVTOOLS_GLOBAL_HOOK__ ??= installedHook());\n const previous = hook.onCommitFiberRoot;\n hook.onCommitFiberRoot = function (this: unknown, rendererId, root, ...rest) {\n try {\n previous?.call(this, rendererId, root, ...rest);\n } catch {\n // The DevTools backend's failure is not ours to propagate; React would\n // swallow it too.\n }\n const container = root?.containerInfo;\n if (signal.onCommit === undefined) signal.commits.push(container);\n else signal.onCommit(container);\n };\n}\n\n/**\n * The hook React finds when the page has none: what `injectInternals` reads\n * (`supportsFiber`, `inject`) and what Fast Refresh reads (`renderers`, kept\n * the way DevTools keeps it — one id per renderer, so the two React copies a\n * development server runs are not one to it).\n */\nfunction installedHook(): DevToolsHook {\n const renderers = new Map<number, unknown>();\n return {\n supportsFiber: true,\n renderers,\n inject: (internals) => {\n const id = renderers.size + 1;\n renderers.set(id, internals);\n return id;\n },\n };\n}\n\n/** A Document, or a container with a binding inside — the tree the runtime writes into. */\nfunction ownsBindings(container: unknown): boolean {\n const node = container as Partial<Pick<Element, 'nodeType' | 'querySelector'>> | null | undefined;\n return node?.nodeType === 9 || node?.querySelector?.(BINDING_SELECTOR) != null;\n}\n\n/** The framework has taken the tree over: every waiter hears it, once. */\nexport function settle(signal: HydrationWait): void {\n signal.committed = true;\n const waiters = signal.waiters;\n signal.waiters = [];\n for (const waiter of waiters) waiter();\n}\n\nfunction forget(signal: HydrationWait, waiter: () => void): void {\n const index = signal.waiters.indexOf(waiter);\n if (index >= 0) signal.waiters.splice(index, 1);\n}\n\n/**\n * Call back once the signal settles, or after `capMs` without it. Returns\n * `null` without calling back when it already has — a bfcache restore does\n * not wait again — and otherwise a cancel for a runtime that stops waiting.\n */\nexport function awaitSettled(\n signal: HydrationWait,\n onSettled: (outcome: HydrationOutcome) => void,\n capMs: number,\n): (() => void) | null {\n if (signal.committed) return null;\n let timer: ReturnType<typeof setTimeout> | null = null;\n const waiter = (): void => {\n if (timer !== null) clearTimeout(timer);\n timer = null;\n onSettled('committed');\n };\n signal.waiters.push(waiter);\n timer = setTimeout(() => {\n timer = null;\n forget(signal, waiter);\n onSettled('timed-out');\n }, capMs);\n return () => {\n if (timer !== null) clearTimeout(timer);\n timer = null;\n forget(signal, waiter);\n };\n}\n\n/**\n * Call back once React has committed a root that holds a binding, or after\n * `capMs` without one. Arms the signal if nothing has yet.\n */\nexport function whenReactCommitted(\n onSettled: (outcome: HydrationOutcome) => void,\n capMs = HYDRATION_WAIT_CAP_MS,\n): (() => void) | null {\n armReactCommitSignal();\n const signal = signalSlot();\n if (signal === undefined) return null;\n if (signal.onCommit === undefined) {\n // The runtime is the one that can judge a commit; the bootstrap may have\n // recorded some before it ran. The backlog first, then every commit live.\n const judge = (container: unknown): void => {\n if (!signal.committed && ownsBindings(container)) settle(signal);\n };\n signal.onCommit = judge;\n for (const container of signal.commits.splice(0)) judge(container);\n }\n return awaitSettled(signal, onSettled, capMs);\n}\n","/**\n * Waiting for Vue before the first write (ADR 0015, addendum of 2026-09-11).\n *\n * Vue's `hydrate()` walks the server markup and repairs what differs from its\n * own render, in place and quietly (development logs `Hydration completed but\n * contains mismatches.`). A value the runtime wrote before that is a mismatch\n * and is put back. Measured on the Nuxt fixture on 2026-09-11: the write at\n * 25.5 ms, hydration at 93.7 ms, the server's values back in the same tick;\n * what put them right again was the admin answering the runtime's second\n * `ready` at 500 ms — and a real admin answers `ready` once.\n *\n * Vue says nothing when it is done. What `runtime-core` does, in every build\n * and right after `hydrate()` has returned, is `rootContainer.__vue_app__ = app`\n * (`apiCreateApp.ts`, `mount`): the property Vue DevTools and `app.unmount()`\n * find the app by. The assignment is the signal. An accessor on\n * `Element.prototype` sees it without polling, files the app on the element\n * as an own property exactly as the assignment would have, and settles once\n * the container holds a binding — a widget mounted beside the page is not\n * ours to wait for. A runtime that evaluates after the mount (asset delivery)\n * finds the own property on an ancestor of its first binding instead, so no\n * armed bootstrap is needed: the signal is state, not an event.\n *\n * A Nuxt app hands its `$nuxt` on the same object, and a page whose setup\n * awaits real time hydrates its subtree only when the root Suspense resolves\n * (measured: `__vue_app__` at 494 ms, the subtree at 895 ms). Nuxt marks that\n * with `isHydrating`, cleared synchronously when the Suspense resolves and\n * before `app:suspense:resolve` runs — so an app still hydrating at the\n * mount is waited for through that hook, and one that is not settles at once.\n *\n * Not used, and why: `data-v-app` is set by `createApp().mount` only, never by\n * `createSSRApp()`'s (measured, and in `runtime-dom`); the DevTools hook\n * (`__VUE_DEVTOOLS_GLOBAL_HOOK__`, `app:init`) exists in development builds and\n * under `__VUE_PROD_DEVTOOLS__` only; a MutationObserver sees nothing on a\n * clean hydration; `window.useNuxtApp` is Nuxt's, set before the mount, and\n * `useNuxtApp()` needs Nuxt's context to answer from outside a component.\n */\n\nimport {\n BINDING_SELECTOR,\n HYDRATION_WAIT_CAP_MS,\n awaitSettled,\n settle,\n type HydrationOutcome,\n type HydrationWait,\n} from './hydration';\n\n/** Where runtime-core leaves the app on its container. */\nexport const VUE_APP_PROPERTY = '__vue_app__';\n\n/** One slot on the window, so a second copy of the runtime shares the state rather than the accessor. */\nexport const VUE_HYDRATION_SLOT = '__livePreviewVueHydration';\n\n/** The Nuxt hook that runs once the root Suspense has resolved, its subtree hydrated. */\nconst NUXT_HYDRATED_HOOK = 'app:suspense:resolve';\n\ninterface VueMountSignal extends HydrationWait {\n armed: boolean;\n}\n\n/** The two things read off a Nuxt app: whether it is still hydrating, and the hook that ends it. */\ninterface NuxtAppLike {\n readonly isHydrating?: boolean;\n readonly hook?: (name: string, fn: () => void) => unknown;\n}\n\ntype VueWindow = Window & { [VUE_HYDRATION_SLOT]?: VueMountSignal };\n\nfunction signalSlot(): VueMountSignal | undefined {\n if (typeof window === 'undefined') return undefined;\n const w = window as VueWindow;\n return (w[VUE_HYDRATION_SLOT] ??= { armed: false, committed: false, waiters: [] });\n}\n\n/** Vue's assignment lands as an own property; only that counts, never the accessor. */\nfunction mountedApp(node: Node): unknown {\n return Object.prototype.hasOwnProperty.call(node, VUE_APP_PROPERTY)\n ? (node as unknown as Record<string, unknown>)[VUE_APP_PROPERTY]\n : undefined;\n}\n\n/**\n * Arm before Vue mounts: the accessor on `Element.prototype` that turns the\n * mount into a signal. Idempotent, and it leaves a seam another copy of the\n * runtime — or a tool — already holds alone; the slot is shared either way,\n * and the accessor reads it live rather than closing over one.\n */\nexport function armVueMountSignal(): void {\n const signal = signalSlot();\n if (signal === undefined || signal.armed) return;\n signal.armed = true;\n const proto = Element.prototype;\n if (Object.getOwnPropertyDescriptor(proto, VUE_APP_PROPERTY) !== undefined) return;\n Object.defineProperty(proto, VUE_APP_PROPERTY, {\n configurable: true,\n get: () => undefined,\n set(this: Element, app: unknown) {\n Object.defineProperty(this, VUE_APP_PROPERTY, {\n value: app,\n writable: true,\n configurable: true,\n enumerable: true,\n });\n const live = signalSlot();\n if (live === undefined || live.committed || this.querySelector(BINDING_SELECTOR) === null) {\n return;\n }\n settleOnceHydrated(live, app);\n },\n });\n}\n\n/** Mounted, and — for a Nuxt app whose Suspense is still pending — hydrated too. */\nfunction settleOnceHydrated(signal: VueMountSignal, app: unknown): void {\n const nuxt = (app as { $nuxt?: NuxtAppLike } | null | undefined)?.$nuxt;\n if (nuxt?.isHydrating === true && typeof nuxt.hook === 'function') {\n nuxt.hook(NUXT_HYDRATED_HOOK, () => {\n if (!signal.committed) settle(signal);\n });\n return;\n }\n settle(signal);\n}\n\n/** Whether an app already sits on an ancestor of a binding under `root` — the runtime came after Vue. */\nfunction mountedAround(root: Document | Element): boolean {\n for (let node = root.querySelector(BINDING_SELECTOR); node !== null; node = node.parentElement) {\n if (mountedApp(node) !== undefined) return true;\n }\n return false;\n}\n\n/**\n * Call back once Vue has mounted — and, on Nuxt, hydrated — an app around a\n * binding of `root`, or after `capMs` without one. Arms the signal if nothing\n * has yet; `null` when it already happened.\n */\nexport function whenVueMounted(\n root: Document | Element,\n onSettled: (outcome: HydrationOutcome) => void,\n capMs = HYDRATION_WAIT_CAP_MS,\n): (() => void) | null {\n armVueMountSignal();\n const signal = signalSlot();\n if (signal === undefined) return null;\n if (!signal.committed && mountedAround(root)) settle(signal);\n return awaitSettled(signal, onSettled, capMs);\n}\n","/**\n * When the runtime may start: after the document has parsed, and on a page\n * that declares hydration after the framework's first commit — React's, or\n * Vue's mount — or the cap (ADR 0015).\n *\n * `lifecycle.ts` owns the resources a start acquires and how a failed one is\n * rolled back; this module owns only the waiting. It moved out when the\n * second wait pushed the lifecycle past its 500 lines, and it stays a chain of\n * plain functions over a small host so that a stage running after `start()`\n * has returned still rolls back and reports the way a synchronous failure\n * throws — the host's `later` is that seam, and `defer` is how `release()`\n * abandons whichever wait is in progress.\n */\n\nimport {\n HYDRATION_WAIT_CAP_MS,\n armReactCommitSignal,\n whenReactCommitted,\n type HydrationMode,\n type HydrationOutcome,\n type HydrationState,\n} from './hydration';\nimport { armVueMountSignal, whenVueMounted } from './hydration-vue';\n\n/** What the startup chain needs from the runtime. */\nexport interface StartupHost {\n readonly root: Document | Element;\n readonly hydration: HydrationMode | undefined;\n /** Whether the runtime is still meant to start; a stop in between abandons the chain. */\n isRunning(): boolean;\n /** Keeps the way to abandon the wait in progress, for `release()`. */\n defer(cancel: () => void): void;\n /** Runs a stage after `start()` has returned: a throw is rolled back and reported, not lost. */\n later(step: () => void): void;\n /** Records how far the wait for hydration got, for `inspect()`. */\n hydrated(state: HydrationState): void;\n warn(message: string): void;\n /** Acquires the resources; throws into the caller when synchronous. */\n startNow(): void;\n}\n\n/**\n * Synchronous when nothing is pending. Otherwise the host is handed a cancel\n * and the chain continues through `later` once the wait ends.\n */\nexport function startWhenReady(host: StartupHost): void {\n // Armed before anything defers: the framework may evaluate before DOMContentLoaded.\n if (host.hydration === 'react') armReactCommitSignal();\n else if (host.hydration === 'vue') armVueMountSignal();\n const { root } = host;\n if (!isDocumentRoot(root) || root.readyState !== 'loading') {\n startAfterParse(host);\n return;\n }\n const onReady = (): void => {\n if (!host.isRunning()) return;\n host.later(() => {\n startAfterParse(host);\n });\n };\n root.addEventListener('DOMContentLoaded', onReady, { once: true });\n host.defer(() => {\n root.removeEventListener('DOMContentLoaded', onReady);\n });\n}\n\n/** A page a framework hydrates is not final until the framework has committed. */\nfunction startAfterParse(host: StartupHost): void {\n if (host.hydration === undefined) {\n host.startNow();\n return;\n }\n const onSettled = (outcome: HydrationOutcome): void => {\n host.later(() => {\n startHydrated(host, outcome);\n });\n };\n const pending =\n host.hydration === 'react'\n ? whenReactCommitted(onSettled)\n : whenVueMounted(host.root, onSettled);\n // Already committed — a bfcache restore does not wait again.\n if (pending === null) {\n startHydrated(host, 'committed');\n return;\n }\n host.defer(pending);\n host.hydrated('waiting');\n}\n\nfunction startHydrated(host: StartupHost, outcome: HydrationOutcome): void {\n host.hydrated(outcome);\n if (outcome === 'timed-out') {\n host.warn(\n `[live-preview] LP0607: no ${host.hydration === 'react' ? 'React commit' : 'Vue mount'} in ${String(HYDRATION_WAIT_CAP_MS)} ms; started without waiting for hydration.`,\n );\n }\n host.startNow();\n}\n\n/** Node types are stable across realms; global constructors are not. */\nfunction isDocumentRoot(root: Document | Element): root is Document {\n return root.nodeType === 9;\n}\n","/** Connection status and the heartbeat that decides a disconnect. */\n\nexport type ConnectionStatus = 'disconnected' | 'connecting' | 'connected';\n\nexport interface HeartbeatOptions {\n /**\n * Silence before declaring a timeout. `0` disables the timer, which is right\n * for the stock Payload protocol: it sends messages only on edits, so any\n * idle timeout would report false disconnects.\n */\n readonly timeoutMs?: number;\n readonly onTimeout: () => void;\n}\n\nexport class HeartbeatTimer {\n private readonly timeoutMs: number;\n private readonly onTimeout: () => void;\n private handle: ReturnType<typeof setTimeout> | null = null;\n private lastKick = 0;\n\n constructor(options: HeartbeatOptions) {\n this.timeoutMs = options.timeoutMs ?? 0;\n this.onTimeout = options.onTimeout;\n }\n\n /** Called on every valid message; re-arms the timeout. */\n kick(): void {\n this.lastKick = Date.now();\n if (this.timeoutMs <= 0) return;\n if (this.handle !== null) clearTimeout(this.handle);\n const handle = setTimeout(() => {\n if (this.handle !== handle) return;\n this.handle = null;\n this.onTimeout();\n }, this.timeoutMs);\n this.handle = handle;\n }\n\n stop(): void {\n if (this.handle === null) return;\n clearTimeout(this.handle);\n this.handle = null;\n }\n\n get lastKickAt(): number {\n return this.lastKick;\n }\n\n get pending(): boolean {\n return this.handle !== null;\n }\n}\n\nexport class ConnectionState {\n private current: ConnectionStatus = 'disconnected';\n\n get status(): ConnectionStatus {\n return this.current;\n }\n\n /** Returns whether the status changed. */\n markConnected(): boolean {\n return this.transition('connected');\n }\n\n markDisconnected(): boolean {\n return this.transition('disconnected');\n }\n\n private transition(next: ConnectionStatus): boolean {\n if (this.current === next) return false;\n this.current = next;\n return true;\n }\n}\n","/**\n * Auto-binding (ADR 0014). On the connection's first message the document and\n * the DOM are two views of the same state, so a scalar field's value can be\n * looked for in the page: where it stands as the whole content of exactly one\n * element — its only text node, or one attribute the writer may set — that\n * element is bound to the field as if `data-payload-field` had been written\n * there. No match, several, a partial one, one split across nodes: nothing,\n * and the field stays unbound, which since Z3 escalates instead of degrading.\n *\n * Two jobs, two exports. `findUniqueBindings` is the search, the exclusions and\n * the candidate rule, and reads the DOM only. `adoptUniqueBindings` writes the\n * winners onto their elements as the attributes a template would have carried,\n * plus `data-payload-guessed` holding the value that matched, and registers\n * them with the cache. Stamping is what lets a cache rebuild find a guess again\n * the way it finds any binding, and what lets `inspect()` and the overlay tell\n * a guess from a declaration.\n */\n\nimport { isWritableAttribute } from './attribute-binding';\nimport { isBindingInScope } from './binding-owner';\nimport {\n ALT_ATTRIBUTE,\n FIELD_ATTRIBUTE,\n GUESSED_ATTRIBUTE,\n HREF_ATTRIBUTE,\n TARGET_ATTRIBUTE_ATTRIBUTE,\n TYPE_ATTRIBUTE,\n resolveBindingOwner,\n} from './cache';\nimport { isIslandBoundary } from './islands';\nimport type { RuntimeDeps, RuntimeState } from './runtime-state';\nimport { stripLocaleSuffix, SYSTEM_FIELD_NAMES, type OwnerScope } from './unbound-fields';\n\n/** `'unique'` searches once, on the first message; `'off'` (the default) never. */\nexport type AutoBindMode = 'off' | 'unique';\n\n/** An author's no: the element and everything under it is never guessed into. */\nexport const NO_BIND_ATTRIBUTE = 'data-payload-no-bind';\n/** The morph's boundary (`src/core/morph.ts`) is this search's boundary too: a subtree the site scripts itself. */\nconst OWNED_ATTRIBUTE = 'data-payload-owned';\n\n/**\n * Below this many characters a value is not looked for at all. Measured, not\n * chosen: on the trap corpus (`tests/fixtures/auto-bind-traps`) 13 is the\n * shortest floor at which no trap binds — at 12 the byline `Ada Lovelace`,\n * printed by a related post and never by the template, is a unique match in\n * the wrong place. The shortest value the shipped fixtures bind that a unique\n * match finds is `Visit Payload`, 13. So the floor separates the corpus with\n * no margin either way; what it is for are the short tokens ADR 0014 names,\n * and a phrase that occurs exactly once and in the wrong place is kept out by\n * nothing but its rarity.\n */\nexport const AUTO_BIND_MIN_LENGTH = 13;\n\nconst BOOLEAN_WORDS: ReadonlySet<string> = new Set(['true', 'false', 'yes', 'no', 'on', 'off']);\n/** Digits with the separators a date, a time, a price or a phone number carry. */\nconst NUMERIC = /^[\\d\\s.,:+/-]+$/u;\n/** A single lower-case token: an enum value, a slug, a code. */\nconst ENUM_TOKEN = /^[a-z][a-z0-9_-]*$/u;\n/** `de`, `de-AT`, `zh_Hant`, `sr-Latn-RS`. */\nconst LOCALE_CODE = /^[a-z]{2,3}(?:[-_][A-Za-z0-9]{2,8})*$/u;\n\n/** Elements whose text is code, metadata or a form value, not content. */\nconst SKIPPED_TAGS: ReadonlySet<string> = new Set([\n 'SCRIPT',\n 'STYLE',\n 'TEMPLATE',\n 'TITLE',\n 'NOSCRIPT',\n 'TEXTAREA',\n 'SELECT',\n 'OPTION',\n 'INPUT',\n 'IFRAME',\n]);\nconst HTML_NAMESPACE = 'http://www.w3.org/1999/xhtml';\n\nexport interface AutoBindCandidate {\n readonly element: Element;\n readonly fieldName: string;\n /** The value that matched: the text, or the attribute's value. */\n readonly matched: string;\n /** The attribute whose whole value matched; absent for a text match. */\n readonly attribute?: string;\n /** The `data-payload-*` attributes a template would have written for this binding. */\n readonly stamps: Readonly<Record<string, string>>;\n}\n\n/** A value's owner: the field, and whether it is an upload (matched by its `url` against an `<img>`). */\nexport interface Claim {\n readonly field: string;\n readonly media: boolean;\n}\n\n/**\n * What the baseline search adopted, kept for the server re-render a route\n * refresh morphs the page toward: that markup carries no stamp, so the guesses\n * are looked for again there — these fields, by these values — and nothing\n * else is. ADR 0014 §1 still holds for everything the baseline did not find.\n */\nexport interface KeptGuesses {\n /** The fields the guesses bound, a folded second field (`data-payload-href`, `data-payload-alt`) included. */\n readonly fields: ReadonlySet<string>;\n /** The texts they were found by, each claiming its field. */\n readonly values: ReadonlyMap<string, Claim>;\n}\n\n/** Whether a scalar is worth looking for: the short and shapeless ones match by accident. */\nexport function isBindableValue(value: unknown, minLength = AUTO_BIND_MIN_LENGTH): value is string {\n if (typeof value !== 'string') return false;\n const text = value.trim();\n if (text.length < minLength) return false;\n if (NUMERIC.test(text) || BOOLEAN_WORDS.has(text.toLowerCase())) return false;\n return !ENUM_TOKEN.test(text) && !LOCALE_CODE.test(text);\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\n/**\n * The values to look for, keyed by the exact text a match must equal. A value\n * two fields share maps to `null`: the element would be unique, the field not.\n * Groups are opened one level under the dotted name a binding would carry; an\n * upload is looked for by its `url`; a document with an `id` and no `url` is\n * another document, and its scalars are not this one's.\n */\nexport function bindableValues(\n fields: Readonly<Record<string, unknown>>,\n locale: string | undefined,\n minLength = AUTO_BIND_MIN_LENGTH,\n): Map<string, Claim | null> {\n const values = new Map<string, Claim | null>();\n const claim = (text: string, field: string, media: boolean): void => {\n values.set(text, values.has(text) ? null : { field, media });\n };\n for (const [rawName, value] of Object.entries(fields)) {\n if (SYSTEM_FIELD_NAMES.has(rawName)) continue;\n const name = stripLocaleSuffix(rawName, locale);\n if (isBindableValue(value, minLength)) {\n claim(value.trim(), name, false);\n } else if (isRecord(value)) {\n if (typeof value['url'] === 'string') {\n claim(value['url'], name, true);\n } else if (!('id' in value) && !('_id' in value)) {\n for (const [child, childValue] of Object.entries(value)) {\n if (SYSTEM_FIELD_NAMES.has(child) || !isBindableValue(childValue, minLength)) continue;\n claim(childValue.trim(), `${name}.${child}`, false);\n }\n }\n }\n }\n return values;\n}\n\n/** Where the search stops: nothing at or under this element may be claimed. */\nfunction isBoundary(element: Element): boolean {\n if (element.namespaceURI !== HTML_NAMESPACE || SKIPPED_TAGS.has(element.tagName)) return true;\n if (\n element.hasAttribute(FIELD_ATTRIBUTE) ||\n element.hasAttribute(NO_BIND_ATTRIBUTE) ||\n element.hasAttribute(OWNED_ATTRIBUTE) ||\n isIslandBoundary(element)\n ) {\n return true;\n }\n const editable = element.getAttribute('contenteditable');\n return editable !== null && editable !== 'false';\n}\n\n/**\n * The element's whole text, when it is exactly one text node — comments and\n * whitespace-only nodes aside — and no element. A second text node is a value\n * split across nodes; an element child is markup a text write would destroy.\n */\nfunction soleText(element: Element): string | undefined {\n let text: string | undefined;\n for (let child = element.firstChild; child !== null; child = child.nextSibling) {\n if (child.nodeType === 1) return undefined;\n if (child.nodeType !== 3) continue;\n const data = (child as Text).data.trim();\n if (data.length === 0) continue;\n if (text !== undefined) return undefined;\n text = data;\n }\n return text;\n}\n\n/** No second rule beyond the writer's own; `value` is the visitor's, and `data-payload-*` is ours. */\nfunction isCandidateAttribute(name: string): boolean {\n return isWritableAttribute(name) && !name.startsWith('data-payload-') && name !== 'value';\n}\n\ninterface ElementHits {\n /** The field whose value is the element's whole text. */\n text?: string;\n /** Attribute name → the field whose value it carries. */\n readonly attributes: Map<string, Claim>;\n}\n\ninterface Search {\n readonly values: ReadonlyMap<string, Claim | null>;\n readonly byElement: Map<Element, ElementHits>;\n /** Every element a field was found on; a field with more than one is ambiguous. */\n readonly byField: Map<string, Set<Element>>;\n}\n\nfunction record(search: Search, element: Element, claim: Claim): ElementHits {\n let hits = search.byElement.get(element);\n if (hits === undefined) {\n hits = { attributes: new Map() };\n search.byElement.set(element, hits);\n }\n let elements = search.byField.get(claim.field);\n if (elements === undefined) {\n elements = new Set();\n search.byField.set(claim.field, elements);\n }\n elements.add(element);\n return hits;\n}\n\n/**\n * One pass, depth first, in document order; the element under a boundary is\n * never looked at. Sibling pointers rather than `children` and `attributes`:\n * the live collections cost twenty times the walk in jsdom, where the\n * interaction gate measures this, and nothing in a browser.\n */\nfunction walk(element: Element, search: Search): void {\n for (let child = element.firstElementChild; child !== null; child = child.nextElementSibling) {\n if (isBoundary(child)) continue;\n const text = soleText(child);\n const textClaim = text === undefined ? undefined : search.values.get(text);\n if (textClaim != null && !textClaim.media) {\n record(search, child, textClaim).text = textClaim.field;\n }\n for (const name of child.getAttributeNames()) {\n if (!isCandidateAttribute(name)) continue;\n const claim = search.values.get(child.getAttribute(name) ?? '');\n if (claim == null) continue;\n // An upload is matched by its file, and an `<img>` is the one element that renders one.\n if (claim.media && (child.tagName !== 'IMG' || name !== 'src')) continue;\n record(search, child, claim).attributes.set(name, claim);\n }\n walk(child, search);\n }\n}\n\n/**\n * What a template would have written for this element. One binding per\n * element: the text wins, and the two idioms a template has for a second\n * field on the same element — `data-payload-href` on a link, `data-payload-alt`\n * on an image — are used when the second field matched that attribute.\n */\nfunction shape(\n element: Element,\n text: string | undefined,\n attributes: ReadonlyMap<string, string>,\n): AutoBindCandidate | undefined {\n const tag = element.tagName;\n if (text !== undefined) {\n const stamps: Record<string, string> = { [FIELD_ATTRIBUTE]: text };\n if (tag === 'A') {\n const href = attributes.get('href');\n // The url renderer derives the href from the text; a guess that never\n // matched the href must not clear it, so the text renderer is named.\n if (href === undefined) stamps[TYPE_ATTRIBUTE] = 'text';\n else if (href !== text) stamps[HREF_ATTRIBUTE] = href;\n }\n return { element, fieldName: text, matched: soleText(element) ?? '', stamps };\n }\n if (tag === 'IMG') {\n const src = attributes.get('src');\n if (src !== undefined) {\n const alt = attributes.get('alt');\n return {\n element,\n fieldName: src,\n matched: element.getAttribute('src') ?? '',\n attribute: 'src',\n stamps: {\n [FIELD_ATTRIBUTE]: src,\n ...(alt !== undefined && alt !== src ? { [ALT_ATTRIBUTE]: alt } : {}),\n },\n };\n }\n }\n // A link whose text did not match keeps its text: only the attribute is written.\n const first = attributes.entries().next();\n if (first.done) return undefined;\n const [name, field] = first.value;\n return {\n element,\n fieldName: field,\n matched: element.getAttribute(name) ?? '',\n attribute: name,\n stamps: { [FIELD_ATTRIBUTE]: field, [TARGET_ATTRIBUTE_ATTRIBUTE]: name },\n };\n}\n\n/**\n * The bindings the page allows, in document order: for every field found on\n * exactly one element, that element with the attributes a template would have\n * given it. `root` is searched as a whole; the caller decides that a document's\n * root is its body.\n */\nexport function findUniqueBindings(\n root: Element,\n fields: Readonly<Record<string, unknown>>,\n locale: string | undefined,\n minLength = AUTO_BIND_MIN_LENGTH,\n): AutoBindCandidate[] {\n return searchUnique(root, bindableValues(fields, locale, minLength));\n}\n\n/** The search proper, over a value table already decided on. */\nfunction searchUnique(\n root: Element,\n values: ReadonlyMap<string, Claim | null>,\n): AutoBindCandidate[] {\n const search: Search = { values, byElement: new Map(), byField: new Map() };\n if (values.size > 0 && !isBoundary(root)) walk(root, search);\n const unique = (field: string): boolean => search.byField.get(field)?.size === 1;\n const candidates: AutoBindCandidate[] = [];\n for (const [element, hits] of search.byElement) {\n const text = hits.text !== undefined && unique(hits.text) ? hits.text : undefined;\n const attributes = new Map<string, string>();\n for (const [name, claim] of hits.attributes) {\n if (unique(claim.field)) attributes.set(name, claim.field);\n }\n const candidate = shape(element, text, attributes);\n if (candidate !== undefined) candidates.push(candidate);\n }\n return candidates;\n}\n\n/** A document's root is its body: a binding in `<head>` needs the attribute and the route strategy. */\nfunction searchRoot(root: Document | Element): Element | null {\n return root.nodeType === 9 ? (root as Document).body : (root as Element);\n}\n\n/**\n * Run the search once and make its winners bindings. Returns how many. The\n * stamps land on the elements first, so the cache resolves each guess exactly\n * as it resolves a declared binding — and so the mutation observer's rebuild,\n * which the stamps themselves trigger, finds them again.\n */\nexport function adoptUniqueBindings(\n deps: RuntimeDeps,\n state: RuntimeState,\n fields: Readonly<Record<string, unknown>>,\n locale: string | undefined,\n ownerKeys: OwnerScope,\n): number {\n const started = performance.now();\n const root = searchRoot(deps.root);\n const values = bindableValues(fields, locale);\n const adopted =\n root === null ? [] : adopt(deps, searchUnique(root, values), ownerKeys, 'on the first message');\n state.autoBindGuesses = keep(values, adopted);\n state.autoBindSearchMs = performance.now() - started;\n return adopted.length;\n}\n\n/**\n * After a server render — a route refresh, or a fragment in its boundary: the\n * server's markup carries no stamp, so the guesses the baseline made are gone\n * from what it rendered. Look for them again, by the value\n * each was found by and by the field's value in this revision — the server\n * may have rendered either, the document as it was saved or a draft it\n * autosaved since. A field found by both, on two elements, is ambiguous and\n * stays unbound. Nothing the baseline did not bind is looked for: a second\n * baseline would be a second chance at a wrong match, and the first one is\n * the only moment the page is known to show the document (ADR 0014 §1).\n */\nexport function restoreUniqueBindings(\n deps: RuntimeDeps,\n state: RuntimeState,\n fields: Readonly<Record<string, unknown>>,\n locale: string | undefined,\n ownerKeys: OwnerScope,\n): number {\n const kept = state.autoBindGuesses;\n const root = searchRoot(deps.root);\n if (kept === null || kept.fields.size === 0 || root === null) return 0;\n const values = new Map<string, Claim | null>(kept.values);\n for (const [text, claim] of bindableValues(fields, locale)) {\n if (claim === null || !kept.fields.has(claim.field)) continue;\n const known = values.get(text);\n if (known === undefined) values.set(text, claim);\n else if (known?.field !== claim.field) values.set(text, null);\n }\n return adopt(deps, searchUnique(root, values), ownerKeys, 'after a server render').length;\n}\n\n/** Stamp the candidates, register them, say so; returns the ones that became bindings. */\nfunction adopt(\n deps: RuntimeDeps,\n candidates: readonly AutoBindCandidate[],\n ownerKeys: OwnerScope,\n when: string,\n): AutoBindCandidate[] {\n const adopted: AutoBindCandidate[] = [];\n for (const candidate of candidates) {\n const { element } = candidate;\n if (element.hasAttribute(FIELD_ATTRIBUTE)) continue;\n // Under owner scoping a guess outside the message's document would never\n // be written to; better to leave it unbound than to bind it to nothing.\n if (ownerKeys !== false && !isBindingInScope(resolveBindingOwner(element), ownerKeys)) continue;\n for (const [name, value] of Object.entries(candidate.stamps)) element.setAttribute(name, value);\n element.setAttribute(GUESSED_ATTRIBUTE, candidate.matched);\n if (deps.cache.add(element) === undefined) {\n // The cache's own filter refused it; a stamp that is not a binding must not stay.\n for (const name of Object.keys(candidate.stamps)) element.removeAttribute(name);\n element.removeAttribute(GUESSED_ATTRIBUTE);\n continue;\n }\n deps.observers.observeElement(element);\n deps.log(\n 'autoBind',\n candidate.fieldName,\n '→',\n `<${element.tagName.toLowerCase()}>`,\n candidate.attribute ?? 'text',\n JSON.stringify(candidate.matched),\n when,\n );\n adopted.push(candidate);\n }\n return adopted;\n}\n\n/** The fields the adopted guesses bound, and the values that found them. */\nfunction keep(\n values: ReadonlyMap<string, Claim | null>,\n adopted: readonly AutoBindCandidate[],\n): KeptGuesses {\n const fields = new Set<string>();\n for (const { fieldName, stamps } of adopted) {\n fields.add(fieldName);\n for (const name of [HREF_ATTRIBUTE, ALT_ATTRIBUTE]) {\n const folded = stamps[name];\n if (folded !== undefined) fields.add(folded);\n }\n }\n const kept = new Map<string, Claim>();\n for (const [text, claim] of values) {\n if (claim !== null && fields.has(claim.field)) kept.set(text, claim);\n }\n return { fields, values: kept };\n}\n","/**\n * Field-path resolution for bindings and sibling-field metadata, prototype-safe,\n * and the identity of everything one binding renders — which is the same\n * question one step later, because the siblings are part of the answer.\n */\n\nimport type { CachedElement } from './types';\nimport { valueIdentity } from './value-identity';\n\nconst BLOCKED_KEYS: ReadonlySet<string> = new Set(['__proto__', 'prototype', 'constructor']);\n\n/**\n * Resolve a dotted field path, preferring a `_<locale>` suffix when one is\n * active. Prototype-chain properties and pollution-prone segments never resolve.\n */\nexport function resolveFieldValue(\n fields: Record<string, unknown>,\n path: string,\n locale: string | undefined,\n preferLocale = false,\n): unknown {\n if (preferLocale && locale !== undefined) {\n const localized = readOwn(fields, `${path}_${locale}`);\n if (localized !== undefined) return localized;\n }\n const direct = readOwn(fields, path);\n if (direct !== undefined) return direct;\n\n if (path.includes('.')) {\n let current: unknown = fields;\n let resolved = true;\n for (const segment of path.split('.')) {\n if (BLOCKED_KEYS.has(segment) || current === null || typeof current !== 'object') {\n resolved = false;\n break;\n }\n current = readOwn(current as Record<string, unknown>, segment);\n if (current === undefined) {\n resolved = false;\n break;\n }\n }\n if (resolved) return current;\n }\n\n return locale === undefined ? undefined : readOwn(fields, `${path}_${locale}`);\n}\n\nfunction readOwn(object: Record<string, unknown>, key: string): unknown {\n if (BLOCKED_KEYS.has(key) || !Object.prototype.hasOwnProperty.call(object, key)) {\n return undefined;\n }\n return object[key];\n}\n\n/**\n * The value a binding renders. A binding that names its own locale reads that\n * locale and nothing else; one that does not falls back to the message locale.\n */\nexport function bindingValue(\n fields: Record<string, unknown>,\n target: { readonly locale?: string | undefined },\n fieldName: string,\n fallbackLocale: string | undefined,\n): unknown {\n return resolveFieldValue(\n fields,\n fieldName,\n target.locale ?? fallbackLocale,\n target.locale !== undefined,\n );\n}\n\n/** Identity of everything a binding renders: its value plus any sibling href/src/alt fields. */\nexport function bindingIdentity(\n target: CachedElement,\n value: unknown,\n fields: Record<string, unknown>,\n locale: string | undefined,\n): string | undefined {\n const own = valueIdentity(value);\n if (own === undefined) return undefined;\n const siblings = [target.hrefField, target.srcField, target.altField];\n let combined = own;\n for (const sibling of siblings) {\n if (sibling === undefined || sibling.length === 0) continue;\n const resolved = bindingValue(fields, target, sibling, locale);\n const identity = valueIdentity(resolved);\n if (identity === undefined) return undefined;\n combined += `|${sibling}=${identity}`;\n }\n return combined;\n}\n","/**\n * Trusted Types: every HTML sink routes through one policy, `payload-live-preview`,\n * whose `createHTML` is the identity — what reaches a sink is already sanitized\n * or escaped. Without the API, strings pass through untouched.\n */\n\n/** The subset of the Trusted Types API this module needs. */\nexport interface TrustedHtmlPolicyLike {\n createHTML(input: string): unknown;\n}\n\ninterface TrustedTypesFactoryLike {\n createPolicy(\n name: string,\n rules: { createHTML: (input: string) => string },\n ): TrustedHtmlPolicyLike;\n}\n\n/** @internal */\nexport const TRUSTED_TYPES_POLICY_NAME = 'payload-live-preview';\n\nlet policyOverride: TrustedHtmlPolicyLike | null | undefined;\nlet autoPolicy: TrustedHtmlPolicyLike | null | undefined;\n\n/**\n * Use `policy` for every sink, `null` to assign plain strings, `undefined` to\n * return to the auto-created package policy.\n */\nexport function setTrustedTypesPolicy(policy: TrustedHtmlPolicyLike | null | undefined): void {\n policyOverride = policy;\n}\n\nfunction factory(): TrustedTypesFactoryLike | undefined {\n const candidate = (globalThis as { trustedTypes?: unknown }).trustedTypes;\n if (typeof candidate !== 'object' || candidate === null) return undefined;\n const create = (candidate as { createPolicy?: unknown }).createPolicy;\n return typeof create === 'function' ? (candidate as TrustedTypesFactoryLike) : undefined;\n}\n\nfunction resolvePolicy(): TrustedHtmlPolicyLike | null {\n if (policyOverride !== undefined) return policyOverride;\n if (autoPolicy !== undefined) return autoPolicy;\n const api = factory();\n try {\n autoPolicy =\n api === undefined\n ? null\n : api.createPolicy(TRUSTED_TYPES_POLICY_NAME, { createHTML: (input) => input });\n } catch {\n // The site's `trusted-types` directive does not list this name; the\n // sink assignment will surface the enforcement error.\n autoPolicy = null;\n }\n return autoPolicy;\n}\n\n/** `html` as a `TrustedHTML` when a policy exists, else the string. Typed `string` for `innerHTML`. @internal */\nexport function trustedHtml(html: string): string {\n const policy = resolvePolicy();\n if (policy === null) return html;\n return policy.createHTML(html) as string;\n}\n\n/** Test hook: forget the auto-created policy. */\nexport function __resetTrustedTypesForTests(): void {\n policyOverride = undefined;\n autoPolicy = undefined;\n}\n","/**\n * LP0201: a scalar field arrived for which the page has no binding. The usual\n * cause is a template that renders the anchor only when the field is non-empty.\n *\n * Reported once per field name, because the cause is the markup rather than the\n * edit. `onUnfaithfulPatch` acts on the same fact per revision; both read the\n * addressability rules from `unbound-fields.ts`.\n */\n\nimport type { ElementCache } from './cache';\nimport {\n createFieldAddressability,\n ownsAnyBinding,\n stripLocaleSuffix,\n SYSTEM_FIELD_NAMES,\n type FieldAddressability,\n type OwnerScope,\n} from './unbound-fields';\n\nexport interface OrphanDiagnosticContext {\n readonly cache: ElementCache;\n readonly warned: Set<string>;\n readonly warn: (...args: unknown[]) => void;\n}\n\nexport function diagnoseOrphanFields(\n context: OrphanDiagnosticContext,\n fields: Readonly<Record<string, unknown>>,\n locale: string | undefined,\n ownerKeys: OwnerScope,\n): void {\n const { cache } = context;\n if (cache.fieldCount === 0) return;\n // With scoping on, a page that renders none of this document is normal.\n if (ownerKeys !== false && !ownsAnyBinding(cache, ownerKeys)) return;\n const isAddressable = createFieldAddressability(cache, locale, ownerKeys);\n for (const [rawName, value] of Object.entries(fields)) {\n if (SYSTEM_FIELD_NAMES.has(rawName)) continue;\n // Only scalars: an unbound relationship or block array is a template\n // decision, not the missing anchor this code is about.\n if (isBindableScalar(value)) {\n report(context, isAddressable, rawName, locale);\n continue;\n }\n if (!isPlainObject(value) || isAddressable(rawName)) continue;\n // A group with no anchor anywhere. `admission.priceFrom` is as bindable as\n // `slug` and was reported as neither, so the report names the scalar\n // instead of staying silent about the object around it. One level only:\n // deeper the shape is a rich-text tree more often than a group, and an\n // array's missing anchor stays a template decision at every depth.\n //\n // Restrained to a group the predicate above already calls unaddressable,\n // which is what keeps this in step with `onUnfaithfulPatch`: it escalates\n // on exactly these fields, and this says the same thing more precisely.\n const group = stripLocaleSuffix(rawName, locale);\n for (const [childName, childValue] of Object.entries(value)) {\n if (!isBindableScalar(childValue) || SYSTEM_FIELD_NAMES.has(childName)) continue;\n report(context, isAddressable, `${group}.${childName}`, locale);\n }\n }\n}\n\nfunction report(\n context: OrphanDiagnosticContext,\n isAddressable: FieldAddressability,\n name: string,\n locale: string | undefined,\n): void {\n const { warned, warn } = context;\n if (warned.has(name) || isAddressable(name)) return;\n warned.add(name);\n warn(\n `[live-preview] LP0201: no <… data-payload-field=\"${stripLocaleSuffix(name, locale)}\"> for field \"${name}\"; ` +\n 'render the anchor unconditionally so edits to an empty field have somewhere to land.',\n );\n}\n\nfunction isBindableScalar(value: unknown): boolean {\n const type = typeof value;\n return type === 'string' || type === 'number' || type === 'boolean' || type === 'bigint';\n}\n\n/** A group, as opposed to an array or a null: the one shape worth looking into. */\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n","/**\n * Keyed DOM morph: edits a live element toward a freshly rendered one while\n * keeping the live nodes, and with them focus, selection, scroll, playback and\n * listeners. Custom elements, islands, `contenteditable` and\n * `data-payload-owned` subtrees are boundaries the morph never enters.\n * See ADR 0008.\n */\n\nimport { ISLAND_ATTRIBUTE } from './islands';\n\nexport { ISLAND_ATTRIBUTE };\n/** @internal */\nexport const OWNED_ATTRIBUTE = 'data-payload-owned';\n\n/** Attributes the CMS controls only when the template names them (ADR 0008 §3). */\nconst STATE_ATTRIBUTES: ReadonlySet<string> = new Set(['open', 'value', 'checked', 'selected']);\n\nexport interface MorphOptions {\n /** Attributes that key child elements for pairing, tried in order; unkeyed children pair by position. */\n readonly keyAttributes: readonly string[];\n /** Called once per parent when two children share a key; the later ones pair by position. */\n readonly onDuplicateKey?: (parent: Element, key: string) => void;\n /** Elements whose attributes are synchronised but whose children are left alone (nested structural slots). */\n readonly retainChildrenOf?: (live: Element, rendered: Element) => boolean;\n}\n\n/** Empty attribute values (boolean markers such as `data-payload-island`) are not keys. */\nfunction keyOf(element: Element, options: MorphOptions): string | undefined {\n for (const attribute of options.keyAttributes) {\n const value = element.getAttribute(attribute);\n if (value !== null && value.length > 0) return `${attribute}=${value}`;\n }\n return undefined;\n}\n\n/** @internal */\nexport function isMorphBoundary(element: Element): boolean {\n if (element.tagName.toLowerCase().includes('-')) return true;\n if (element.hasAttribute(ISLAND_ATTRIBUTE) || element.hasAttribute(OWNED_ATTRIBUTE)) return true;\n const editable = element.getAttribute('contenteditable');\n return editable !== null && editable !== 'false';\n}\n\n/** Whether `live` can be edited toward `rendered` instead of being replaced by it. @internal */\nexport function isMorphCompatible(live: Element, rendered: Element): boolean {\n return (\n live.tagName === rendered.tagName &&\n live.namespaceURI === rendered.namespaceURI &&\n !isMorphBoundary(live) &&\n !isMorphBoundary(rendered)\n );\n}\n\n/**\n * Morph `live` toward `rendered`. Returns `live` when it was retained, or\n * `rendered` when the two are incompatible and the caller must replace.\n * `rendered` is consumed: its children may move into `live`.\n */\nexport function morphElement(live: Element, rendered: Element, options: MorphOptions): Element {\n if (!isMorphCompatible(live, rendered)) return rendered;\n const focus = captureFocus(live);\n syncAttributes(live, rendered);\n if (options.retainChildrenOf?.(live, rendered) !== true) morphChildren(live, rendered, options);\n restoreFocus(focus);\n return live;\n}\n\n/** Match attributes, except that state-bearing ones change only when `rendered` carries them. */\nexport function syncAttributes(live: Element, rendered: Element): void {\n for (const attribute of Array.from(live.attributes)) {\n if (rendered.hasAttribute(attribute.name)) continue;\n if (STATE_ATTRIBUTES.has(attribute.name.toLowerCase())) continue;\n live.removeAttribute(attribute.name);\n }\n for (const attribute of Array.from(rendered.attributes)) {\n if (live.getAttribute(attribute.name) !== attribute.value) {\n live.setAttribute(attribute.name, attribute.value);\n }\n }\n}\n\nfunction morphChildren(live: Element, rendered: Element, options: MorphOptions): void {\n const liveKeyed = indexKeyed(live, options);\n const keyedElements = new Set<Node>(liveKeyed.values());\n const liveUnkeyed = Array.from(live.childNodes).filter((node) => !keyedElements.has(node));\n const claimed = new Set<Node>();\n const usedKeys = new Set<string>();\n const renderedNodes = Array.from(rendered.childNodes);\n let cursor: Node | null = live.firstChild;\n let unkeyedIndex = 0;\n\n for (let i = 0; i < renderedNodes.length; i += 1) {\n const next = renderedNodes[i] as Node;\n let kept: Node | null = null;\n let key = next instanceof Element ? keyOf(next, options) : undefined;\n // A repeated key on the rendered side pairs positionally like a live duplicate.\n if (key !== undefined && usedKeys.has(key)) key = undefined;\n if (key !== undefined) {\n usedKeys.add(key);\n const candidate = liveKeyed.get(key);\n if (candidate !== undefined && !claimed.has(candidate)) {\n kept = reconcile(candidate, next, options) === candidate ? candidate : null;\n if (kept === null) {\n candidate.replaceWith(next);\n claimed.add(next);\n cursor = next.nextSibling;\n continue;\n }\n }\n } else {\n while (unkeyedIndex < liveUnkeyed.length) {\n const candidate = liveUnkeyed[unkeyedIndex] as Node;\n unkeyedIndex += 1;\n if (claimed.has(candidate)) continue;\n if (sameKind(candidate, next)) {\n kept = reconcile(candidate, next, options) === candidate ? candidate : null;\n if (kept === null) {\n live.replaceChild(next, candidate);\n claimed.add(next);\n cursor = next.nextSibling;\n }\n break;\n }\n if (candidate instanceof Element) {\n // `next` is a text/comment, or an element whose kind the following\n // rendered node matches: an insertion, so the live element stays for it.\n const following = renderedNodes[i + 1];\n if (\n !(next instanceof Element) ||\n (following !== undefined && sameKind(candidate, following))\n ) {\n unkeyedIndex -= 1;\n break;\n }\n live.replaceChild(next, candidate);\n claimed.add(next);\n cursor = next.nextSibling;\n break;\n }\n if (!(next instanceof Element)) {\n // Text vs comment: replace rather than rewrite one node type's value into the other.\n live.replaceChild(next, candidate);\n claimed.add(next);\n cursor = next.nextSibling;\n break;\n }\n // A surplus live text/comment before the element `next` needs; removed below.\n }\n if (kept === null && claimed.has(next)) continue;\n }\n\n const node: Node = kept ?? next;\n claimed.add(node);\n // Whitespace-only text the template did not render is surplus. Stepping the\n // cursor over it keeps a retained element where it is: `insertBefore` on a\n // node already in the tree is a remove-and-insert, which blurs a focused input.\n while (cursor !== null && cursor !== node && !claimed.has(cursor) && isBlankText(cursor)) {\n cursor = cursor.nextSibling;\n }\n if (node !== cursor) live.insertBefore(node, cursor);\n cursor = node.nextSibling;\n }\n\n for (const child of Array.from(live.childNodes)) {\n if (!claimed.has(child)) child.remove();\n }\n}\n\n/** Retain `candidate` when it can be edited toward `next`; otherwise report `next`. */\nfunction reconcile(candidate: Node, next: Node, options: MorphOptions): Node {\n if (candidate instanceof Element && next instanceof Element) {\n // A compatible boundary stays exactly as it is (ADR 0008 §4).\n if (isMorphBoundary(candidate) && isMorphBoundary(next)) return candidate;\n return morphElement(candidate, next, options);\n }\n if (candidate.nodeValue !== next.nodeValue) candidate.nodeValue = next.nodeValue;\n return candidate;\n}\n\nfunction isBlankText(node: Node): boolean {\n return node.nodeType === Node.TEXT_NODE && (node.nodeValue ?? '').trim().length === 0;\n}\n\nfunction sameKind(a: Node, b: Node): boolean {\n if (a.nodeType !== b.nodeType) return false;\n if (a instanceof Element && b instanceof Element) {\n return a.tagName === b.tagName && a.namespaceURI === b.namespaceURI;\n }\n return true;\n}\n\n/** First element per key; later duplicates are left as they are and pair positionally. */\nfunction indexKeyed(parent: Element, options: MorphOptions): Map<string, Element> {\n const keyed = new Map<string, Element>();\n let duplicate: string | undefined;\n for (const child of Array.from(parent.children)) {\n const key = keyOf(child, options);\n if (key === undefined) continue;\n if (keyed.has(key)) {\n duplicate ??= key.slice(key.indexOf('=') + 1);\n continue;\n }\n keyed.set(key, child);\n }\n if (duplicate !== undefined) options.onDuplicateKey?.(parent, duplicate);\n return keyed;\n}\n\ninterface FocusSnapshot {\n readonly element: HTMLElement;\n readonly selection: readonly [number | null, number | null] | null;\n}\n\n/** A keyed move is a remove-and-insert, which blurs; remember what had focus. */\nfunction captureFocus(live: Element): FocusSnapshot | null {\n const active = live.ownerDocument.activeElement;\n if (!(active instanceof HTMLElement) || !live.contains(active)) return null;\n const selection =\n active instanceof HTMLInputElement || active instanceof HTMLTextAreaElement\n ? ([active.selectionStart, active.selectionEnd] as const)\n : null;\n return { element: active, selection };\n}\n\nfunction restoreFocus(snapshot: FocusSnapshot | null): void {\n if (snapshot === null) return;\n const { element, selection } = snapshot;\n if (element.ownerDocument.activeElement === element || !element.isConnected) return;\n try {\n element.focus({ preventScroll: true });\n const [start, end] = selection ?? [null, null];\n if (start !== null && end !== null) {\n (element as HTMLInputElement).setSelectionRange(start, end);\n }\n } catch {\n // Not focusable any more; nothing to restore.\n }\n}\n","/**\n * LP0409 — what the strict sanitizer removed that the 1.x default kept.\n *\n * `sanitizerPolicy` defaults to `'strict'` since 2.0; before that it was\n * `'compat'`, which let `id` and every `data-*` through, and `name` only where\n * a per-tag list allowed it. The difference\n * only shows when a binding *writes* markup, so a project that upgrades and\n * whose rich text carries its own hooks loses them at the moment an editor\n * types — silently, and in the preview only. Measured on a real consumer: a\n * `data-partner-scroll` attribute driving a CSS selector disappeared on the\n * first write, with nothing said anywhere.\n *\n * So it is said here: once per attribute name per page, with the reason that\n * applies to that name rather than one sentence covering three different\n * decisions. This is a report, never a behaviour — the attribute stays removed.\n */\n\n/**\n * `console.warn` behind a try/catch rather than `@core/diagnostics`: `security`\n * is a leaf layer and may not import `core` (scripts/architecture-rules.ts), and\n * the shared helper's extra work — tolerating a logger that returns a thenable —\n * is for consumer-supplied loggers. This sink is fixed.\n */\nfunction warn(message: string): void {\n try {\n console.warn(message);\n } catch {\n // A diagnostic must never become a second failure.\n }\n}\n\nconst reported = new Set<string>();\n\n/** The binding prefix, restated rather than imported: this module must not pull the applier in. */\nconst BINDING_PREFIX = 'data-payload-';\n\nfunction reason(name: string): string {\n if (name.startsWith(BINDING_PREFIX)) {\n return (\n 'A binding inside CMS content is refused by design — an editor could otherwise ' +\n 'aim a write at any element on the page (docs/security.md)'\n );\n }\n if (name === 'id' || name === 'name') {\n return (\n 'CMS content that can name an element can shadow a global of that name — ' +\n 'DOM clobbering, refused by design (docs/security.md)'\n );\n }\n return (\n 'List it in `allowedDataAttributes` if the page needs it, or set ' +\n \"`sanitizerPolicy: 'compat'` to keep every `data-*` as 1.x did\"\n );\n}\n\n/**\n * Report one removal. Only for attributes `'compat'` would have kept: everything\n * else the sanitizer drops was refused in 1.x too and is not news to anyone.\n */\nexport function reportDroppedAttribute(name: string): void {\n if (reported.has(name)) return;\n reported.add(name);\n warn(\n `[live-preview] LP0409: the strict sanitizer removed \\`${name}\\` from written markup; ` +\n `the 1.x default (\\`sanitizerPolicy: 'compat'\\`) kept it. ${reason(name)}.`,\n );\n}\n\n/** Test seam: the report is once per page, and a test is not a page. */\nexport function resetDroppedAttributeReports(): void {\n reported.clear();\n}\n","/**\n * HTML sanitizer built on the host parser (`<template>`): allow-listed tags\n * and attributes, validated URLs, hardened external links, no `style`.\n * Needs a DOM; string-only sanitizers are historically brittle.\n */\n\nimport { trustedHtml } from './trusted-types';\nimport { isSafeUrl, isExternalHttpUrl } from './url-validator';\nimport { reportDroppedAttribute } from './sanitizer-report';\n\ndeclare const __INLINE_BUILD__: boolean | undefined;\n\n/** Tags kept with their content. Others are unwrapped unless in `REMOVE_COMPLETELY`. */\nconst ALLOWED_TAGS: ReadonlySet<string> = new Set([\n 'p',\n 'br',\n 'strong',\n 'b',\n 'em',\n 'i',\n 'u',\n 's',\n 'strike',\n 'mark',\n 'small',\n 'h1',\n 'h2',\n 'h3',\n 'h4',\n 'h5',\n 'h6',\n 'ul',\n 'ol',\n 'li',\n 'dl',\n 'dt',\n 'dd',\n 'blockquote',\n 'code',\n 'pre',\n 'kbd',\n 'samp',\n 'var',\n 'a',\n 'span',\n 'div',\n 'section',\n 'article',\n 'aside',\n 'header',\n 'footer',\n 'nav',\n 'figure',\n 'figcaption',\n 'img',\n 'picture',\n 'source',\n 'audio',\n 'video',\n 'sub',\n 'sup',\n 'hr',\n 'time',\n 'abbr',\n 'cite',\n 'q',\n 'table',\n 'thead',\n 'tbody',\n 'tfoot',\n 'tr',\n 'th',\n 'td',\n 'caption',\n 'colgroup',\n 'col',\n]);\n\n/** Tags `allowFormControls` re-admits for author templates; `form` is deliberately not one. */\nconst FORM_CONTROLS: ReadonlySet<string> = new Set([\n 'input',\n 'button',\n 'textarea',\n 'select',\n 'option',\n 'label',\n]);\n\n/** Removed with their children: the content itself is the hazard. */\nconst REMOVE_COMPLETELY: ReadonlySet<string> = new Set([\n 'script',\n 'style',\n 'iframe',\n 'object',\n 'embed',\n 'link',\n 'meta',\n 'base',\n 'form',\n 'input',\n 'button',\n 'select',\n 'textarea',\n 'svg',\n 'math',\n 'template',\n 'frame',\n 'frameset',\n 'noframes',\n 'noscript',\n]);\n\nconst ATTR_GLOBAL: ReadonlySet<string> = new Set([\n 'id',\n 'class',\n 'lang',\n 'dir',\n 'title',\n 'role',\n 'tabindex',\n]);\n\nconst ATTR_ARIA_PREFIX = 'aria-';\nconst ATTR_DATA_PREFIX = 'data-';\nconst BINDING_DATA_PREFIX = 'data-payload-';\n\nconst ATTR_BY_TAG: Readonly<Record<string, ReadonlySet<string>>> = {\n a: new Set(['href', 'target', 'rel', 'download', 'hreflang', 'type']),\n img: new Set(['src', 'srcset', 'sizes', 'alt', 'width', 'height', 'loading', 'decoding']),\n picture: new Set([]),\n source: new Set(['src', 'srcset', 'sizes', 'type', 'media']),\n audio: new Set(['src', 'controls', 'autoplay', 'loop', 'muted', 'preload']),\n video: new Set([\n 'src',\n 'poster',\n 'controls',\n 'autoplay',\n 'loop',\n 'muted',\n 'preload',\n 'width',\n 'height',\n 'playsinline',\n ]),\n time: new Set(['datetime']),\n abbr: new Set(['title']),\n q: new Set(['cite']),\n blockquote: new Set(['cite']),\n table: new Set(['summary']),\n th: new Set(['colspan', 'rowspan', 'scope', 'headers', 'abbr']),\n td: new Set(['colspan', 'rowspan', 'headers']),\n col: new Set(['span']),\n colgroup: new Set(['span']),\n ol: new Set(['start', 'reversed', 'type']),\n li: new Set(['value']),\n code: new Set(['class']),\n pre: new Set(['class']),\n};\n\nconst URL_ATTRIBUTES: ReadonlySet<string> = new Set(['href', 'src', 'cite', 'poster']);\n\n// Numeric nodeType constants keep an injected SSR document independent of a\n// browser-global `Node` constructor.\nconst ELEMENT_NODE = 1;\nconst COMMENT_NODE = 8;\n\n/** Thrown by `sanitizeHtml()` when no `document` is available (SSR without `setSanitizerDocument()`). */\nexport class SanitizerEnvironmentError extends Error {\n override readonly name = 'SanitizerEnvironmentError';\n}\n\n/**\n * `'strict'` (default) strips `id`, `name` and `data-payload-*` and passes\n * other `data-*` only via `allowedDataAttributes`; `'compat'` keeps them.\n */\nexport type SanitizerPolicyMode = 'compat' | 'strict';\n\nexport interface SanitizeOptions {\n /** Overrides the module default set by `setSanitizerPolicy()`. */\n readonly policy?: SanitizerPolicyMode;\n /** `data-*` attributes (full names) that pass under `'strict'`; `data-payload-*` never does. */\n readonly allowedDataAttributes?: readonly string[];\n /**\n * Keep `input`, `button`, `textarea`, `select`, `option` and `label` — only\n * for markup the page author wrote, never for CMS content. `form`,\n * handlers, `style` and unsafe URLs stay dropped.\n */\n readonly allowFormControls?: boolean;\n /** Extra tags to allow. Lower-case, untrimmed. */\n readonly additionalAllowedTags?: readonly string[];\n /**\n * Extra per-tag attributes, lower-case. Cannot re-admit handlers, `style`,\n * or — under `'strict'` — `id`, `name` and `data-payload-*`.\n */\n readonly additionalAllowedAttributes?: Readonly<Record<string, readonly string[]>>;\n /**\n * The input is a page-author item template, so `'strict'` keeps the\n * applier's reconciliation attributes (`TEMPLATE_ATTRIBUTES`) and nothing\n * else — every other `data-payload-*` is still stripped, so a template can\n * never add a binding.\n */\n readonly templateMode?: boolean;\n}\n\n/** What `templateMode` keeps under `'strict'`. */\nconst TEMPLATE_ATTRIBUTES: ReadonlySet<string> = new Set([\n 'id',\n 'name',\n 'data-payload-key',\n 'data-payload-nested-key',\n 'data-payload-nested-template',\n]);\n\ninterface ResolvedPolicy {\n readonly allowedTags: ReadonlySet<string>;\n readonly allowFormControls: boolean;\n readonly templateMode: boolean;\n readonly mode: SanitizerPolicyMode;\n readonly allowedData: ReadonlySet<string>;\n readonly attrByTag: ReadonlyMap<string, ReadonlySet<string>>;\n}\n\nlet defaultMode: SanitizerPolicyMode = 'strict';\n\n/**\n * The default for calls without an explicit `policy`, per package entry. A\n * runtime carries its own `sanitizerPolicy` and never writes here (ADR 0002).\n */\nexport function setSanitizerPolicy(mode: SanitizerPolicyMode): void {\n defaultMode = mode;\n}\n\n/** `instancePolicy` sits between a per-call `options.policy` and the process default. */\nfunction resolvePolicy(\n options: SanitizeOptions | undefined,\n instancePolicy: SanitizerPolicyMode | undefined,\n): ResolvedPolicy {\n const mode = options?.policy ?? instancePolicy ?? defaultMode;\n if (!options) {\n const attrMap = new Map<string, ReadonlySet<string>>();\n for (const [tag, attrs] of Object.entries(ATTR_BY_TAG)) attrMap.set(tag, attrs);\n return {\n allowedTags: ALLOWED_TAGS,\n attrByTag: attrMap,\n allowFormControls: false,\n templateMode: false,\n mode,\n allowedData: new Set(),\n };\n }\n const allowed = new Set(ALLOWED_TAGS);\n options.additionalAllowedTags?.forEach((tag) => allowed.add(tag));\n if (options.allowFormControls === true) for (const tag of FORM_CONTROLS) allowed.add(tag);\n const attrMap = new Map<string, ReadonlySet<string>>();\n for (const [tag, attrs] of Object.entries(ATTR_BY_TAG)) attrMap.set(tag, attrs);\n for (const [tag, attrs] of Object.entries(options.additionalAllowedAttributes ?? {})) {\n const merged = new Set(attrMap.get(tag));\n for (const attr of attrs) merged.add(attr);\n attrMap.set(tag, merged);\n }\n return {\n allowedTags: allowed,\n attrByTag: attrMap,\n allowFormControls: options.allowFormControls === true,\n templateMode: options.templateMode === true,\n mode,\n allowedData: new Set(options.allowedDataAttributes?.map((name) => name.toLowerCase())),\n };\n}\n\n/** The `Document` surface the sanitizer needs; jsdom, linkedom and happy-dom all provide it. */\nexport interface SanitizerDocument {\n createElement: (tagName: string) => {\n innerHTML: string;\n readonly content: ParentNode;\n };\n}\n\n// Held on the realm, not in this module: every package entry is its own bundle\n// with its own copy of this file, and a document supplied through the root has\n// to reach the rich text `payload-live-preview/lexical` renders.\nconst DOCUMENT_SLOT: unique symbol = Symbol.for('payload-live-preview.sanitizer-document');\n\ninterface DocumentSlot {\n [DOCUMENT_SLOT]?: SanitizerDocument | undefined;\n}\n\n/** Supply a `Document` for SSR, e.g. linkedom's `parseHTML(...).document`; `null` clears it, for every entry. */\nexport function setSanitizerDocument(doc: SanitizerDocument | null): void {\n (globalThis as DocumentSlot)[DOCUMENT_SLOT] = doc ?? undefined;\n}\n\n/**\n * Sanitize `html`; malformed input is recovered by the parser first.\n *\n * @throws {SanitizerEnvironmentError} when no DOM is available.\n */\nexport function sanitizeHtml(html: string, options?: SanitizeOptions): string {\n return sanitizeHtmlWithPolicy(html, undefined, options);\n}\n\n/**\n * The runtime's entry: `policy` is one instance's, applied unless `options`\n * carry their own, so two clients on a page never share a policy through\n * this module. Not public — a direct caller has `options.policy`.\n */\nexport function sanitizeHtmlWithPolicy(\n html: string,\n policy: SanitizerPolicyMode | undefined,\n options?: SanitizeOptions,\n): string {\n const doc = resolveDocument();\n if (!doc) throw environmentError();\n if (html === '') return '';\n\n const resolved = resolvePolicy(options, policy);\n const template = doc.createElement('template');\n // The sanitizer's own parse is a sink too: under Trusted Types it needs the policy.\n template.innerHTML = trustedHtml(html);\n sanitizeFragment(template.content, resolved);\n return template.innerHTML;\n}\n\n// Read the define at each branch rather than through a helper: a bundler\n// folds the substituted literal in place, but will not inline a call, and the\n// SSR-only class and override must not reach the browser runtime.\nfunction environmentError(): Error {\n if (typeof __INLINE_BUILD__ !== 'undefined' && __INLINE_BUILD__) {\n return new Error('sanitizeHtml needs a DOM');\n }\n return new SanitizerEnvironmentError(\n 'sanitizeHtml needs a DOM; provide one with setSanitizerDocument() during SSR.',\n );\n}\n\nfunction resolveDocument(): SanitizerDocument | undefined {\n if (typeof __INLINE_BUILD__ === 'undefined' || !__INLINE_BUILD__) {\n const override = (globalThis as DocumentSlot)[DOCUMENT_SLOT];\n if (override) return override;\n }\n if (typeof document === 'undefined') return undefined;\n return document;\n}\n\n/** Whether a DOM is available — the global or an injected one — for callers that treat sanitizing as optional. */\nexport function hasSanitizerDocument(): boolean {\n return resolveDocument() !== undefined;\n}\n\nfunction sanitizeFragment(node: ParentNode, policy: ResolvedPolicy): void {\n // Snapshot: children are mutated during the walk.\n for (const child of Array.from(node.childNodes)) {\n if (child.nodeType === ELEMENT_NODE) {\n sanitizeElement(child as Element, policy);\n } else if (child.nodeType === COMMENT_NODE) {\n child.remove();\n }\n }\n}\n\nfunction sanitizeElement(element: Element, policy: ResolvedPolicy): void {\n const tag = element.tagName.toLowerCase();\n\n if (REMOVE_COMPLETELY.has(tag) && !(policy.allowFormControls && FORM_CONTROLS.has(tag))) {\n element.remove();\n return;\n }\n\n if (!policy.allowedTags.has(tag)) {\n sanitizeFragment(element, policy);\n element.replaceWith(...element.childNodes);\n return;\n }\n\n sanitizeAttributes(element, tag, policy);\n if (tag === 'a') hardenAnchor(element);\n sanitizeFragment(element, policy);\n}\n\nfunction sanitizeAttributes(element: Element, tag: string, policy: ResolvedPolicy): void {\n const tagAttrs = policy.attrByTag.get(tag);\n\n for (const attr of Array.from(element.attributes)) {\n const name = attr.name.toLowerCase();\n if (name.startsWith('on') || name === 'style') {\n element.removeAttribute(attr.name);\n continue;\n }\n if (policy.mode === 'strict') {\n if (policy.templateMode && TEMPLATE_ATTRIBUTES.has(name)) continue;\n // DOM clobbering and binding injection (docs/security.md §5c). Checked\n // before the allow-list so an extension cannot re-admit them.\n if (name === 'id' || name === 'name' || name.startsWith(BINDING_DATA_PREFIX)) {\n element.removeAttribute(attr.name);\n // `compat` kept `name` only where a per-tag list allowed it, so only\n // there did the upgrade change anything to report.\n if (name !== 'name' || tagAttrs?.has(name) === true) reportDroppedAttribute(name);\n continue;\n }\n if (name.startsWith(ATTR_DATA_PREFIX)) {\n if (!policy.allowedData.has(name)) {\n element.removeAttribute(attr.name);\n reportDroppedAttribute(name);\n }\n continue;\n }\n if (ATTR_GLOBAL.has(name) || name.startsWith(ATTR_ARIA_PREFIX)) continue;\n } else if (\n ATTR_GLOBAL.has(name) ||\n name.startsWith(ATTR_ARIA_PREFIX) ||\n name.startsWith(ATTR_DATA_PREFIX)\n ) {\n continue;\n }\n if (tagAttrs?.has(name)) {\n if (URL_ATTRIBUTES.has(name) && !isSafeUrl(attr.value)) {\n element.removeAttribute(attr.name);\n } else if (name === 'srcset' && !isSafeSrcset(attr.value)) {\n element.removeAttribute(attr.name);\n }\n continue;\n }\n element.removeAttribute(attr.name);\n }\n}\n\n/** Every `srcset` candidate must pass; partial rewriting would silently change what renders. */\nfunction isSafeSrcset(value: string): boolean {\n for (const candidate of value.split(',')) {\n const trimmed = candidate.trim();\n if (trimmed.length === 0) continue;\n // The URL ends at the first whitespace; what follows is the descriptor.\n const [url = trimmed] = trimmed.split(/\\s/, 1);\n if (!isSafeUrl(url)) return false;\n }\n return true;\n}\n\nfunction hardenAnchor(anchor: Element): void {\n const href = anchor.getAttribute('href');\n if (href === null || !isExternalHttpUrl(href)) return;\n anchor.setAttribute('rel', 'noopener noreferrer');\n if (!anchor.hasAttribute('target')) anchor.setAttribute('target', '_blank');\n}\n\n/** The built-in allow-lists, for documentation and tests. */\nexport const SANITIZER_POLICY = Object.freeze({\n allowedTags: ALLOWED_TAGS,\n removeCompletely: REMOVE_COMPLETELY,\n globalAttributes: ATTR_GLOBAL,\n attributesByTag: ATTR_BY_TAG,\n urlAttributes: URL_ATTRIBUTES,\n});\n","/** HTML and CSS escaping primitives (OWASP XSS Prevention Cheat Sheet). DOM-free. */\n\nconst HTML_ESCAPES: Readonly<Record<string, string>> = Object.freeze({\n '&': '&',\n '<': '<',\n '>': '>',\n '\"': '"',\n \"'\": ''',\n '/': '/',\n '`': '`',\n '=': '=',\n});\n\nconst HTML_ESCAPE_PATTERN = /[&<>\"'/`=]/g;\n\n/** Escape `text` for an element body or a *quoted* attribute value; strings only, and unquoted attributes are not covered. */\nexport function escapeHtml(text: string): string {\n // The character class and the map are coupled: every match is a key.\n // eslint-disable-next-line @typescript-eslint/non-nullable-type-assertion-style\n return text.replace(HTML_ESCAPE_PATTERN, (char) => HTML_ESCAPES[char] as string);\n}\n\n/** Escape a value for a CSS `url(...)` literal; this stops the break-out, not the scheme, so pair it with `isSafeUrl()`. */\nexport function escapeCssUrl(value: string): string {\n return value.replace(/['\"()\\\\]/g, '\\\\$&');\n}\n\nconst ATTR_ESCAPES: Readonly<Record<string, string>> = Object.freeze({\n '&': '&',\n '<': '<',\n '>': '>',\n '\"': '"',\n \"'\": ''',\n});\n\nconst ATTR_ESCAPE_PATTERN = /[&<>\"']/g;\n\n/** Escape a value for a *quoted* HTML attribute, leaving URL characters intact; it validates no scheme, so run `isSafeUrl()` on `href`/`src` first. @internal */\nexport function escapeHtmlAttribute(value: string): string {\n // The character class and the map are coupled: every match is a key.\n // eslint-disable-next-line @typescript-eslint/non-nullable-type-assertion-style\n return value.replace(ATTR_ESCAPE_PATTERN, (char) => ATTR_ESCAPES[char] as string);\n}\n\n/** `escapeHtml()` then newlines to `<br>`; the order is what makes it safe. */\nexport function escapeAndLinebreak(text: string): string {\n return escapeHtml(text).replace(/\\r\\n|\\r|\\n/g, '<br>');\n}\n","/**\n * One array item out of one template: the interpolation, and the attributes the\n * template cannot know about.\n *\n * A replacement value is data, not template syntax: one `replace()` per key\n * would re-interpret `{{index}}` text that an earlier value introduced, and\n * would apply `String.replace`'s `$` semantics to CMS content.\n */\n\nimport { escapeHtml } from '@security/escape';\nimport { isWritableAttribute } from './attribute-binding';\n\nconst PLACEHOLDER_PATTERN = /\\{\\{([\\s\\S]*?)\\}\\}/g;\n\n/** The runtime's own annotations; a rebuilt item gets its own, never a copy. */\nconst BINDING_ATTRIBUTE_PREFIX = 'data-payload-';\n\n/** An attribute name and its value, as they travel from an old item to a new one. */\nexport type InheritedAttribute = readonly [name: string, value: string];\n\nfunction hasOwn(record: object, key: PropertyKey): boolean {\n return Object.prototype.hasOwnProperty.call(record, key);\n}\n\n/**\n * Every key any item carries. A placeholder naming one of these is a field of\n * this array, so a row that happens to lack it renders as nothing; a\n * placeholder no row can fill is a typo in the template and stays visible.\n */\nexport function collectTemplateKeys(items: readonly unknown[]): ReadonlySet<string> {\n const keys = new Set<string>();\n for (const item of items) {\n if (typeof item !== 'object' || item === null) continue;\n for (const key of Object.keys(item)) keys.add(key);\n }\n return keys;\n}\n\nexport function interpolateArrayTemplate(\n template: string,\n item: unknown,\n index: number,\n stringify: (value: unknown) => string,\n knownKeys?: ReadonlySet<string>,\n): string {\n const record = typeof item === 'object' && item !== null ? item : null;\n\n return template.replace(PLACEHOLDER_PATTERN, (placeholder, key: string) => {\n // Preserve the established object-field precedence when an object itself\n // has an `index` or `value` property. Otherwise these are reserved tokens.\n if (record !== null && hasOwn(record, key)) {\n return escapeHtml(stringify(Reflect.get(record, key)));\n }\n if (record === null && key === 'value') return escapeHtml(stringify(item));\n if (key === 'index') return String(index);\n // A field other rows carry: this one simply has none. Writing the\n // placeholder would print template syntax on the page, which is what an\n // editor sees the moment a row is added and not every field is filled in.\n if (record !== null && knownKeys?.has(key) === true) return '';\n return placeholder;\n });\n}\n\n/**\n * What the items already in `container` all carry, and an item rebuilt from the\n * template therefore has to carry too.\n *\n * A framework's scoped styles hang on a marker its compiler writes into the\n * markup — Astro's `data-astro-cid-…`, Vue's `data-v-…`, Svelte's class — and\n * the author's `data-payload-array-template` has none of it. The rebuilt list\n * then renders unstyled next to the one the server sent, while the write itself\n * succeeds, so nothing in the runtime can notice. Naming no framework is the\n * point: what identifies these attributes is that every item of the list has\n * them with the same value, which per-row state by definition does not.\n */\nexport function sharedItemAttributes(container: Element): readonly InheritedAttribute[] {\n const items = container.children;\n const first = items[0];\n if (first === undefined) return [];\n const shared: InheritedAttribute[] = [];\n for (const { name, value } of Array.from(first.attributes)) {\n if (!isWritableAttribute(name) || name.startsWith(BINDING_ATTRIBUTE_PREFIX)) continue;\n let everyItem = true;\n for (let index = 1; index < items.length && everyItem; index += 1) {\n everyItem = items[index]?.getAttribute(name) === value;\n }\n if (everyItem) shared.push([name, value]);\n }\n return shared;\n}\n\n/** Give a rebuilt item what its predecessors shared; the template's own value wins. */\nexport function inheritItemAttributes(item: Element, shared: readonly InheritedAttribute[]): void {\n for (const [name, value] of shared) {\n if (!item.hasAttribute(name)) item.setAttribute(name, value);\n }\n}\n","/** Value coercion shared by the field renderers. */\n\n/** Display string for any value: primitives as-is, objects as JSON, `null`/`undefined` as `''`. */\nexport function safeStringify(value: unknown): string {\n if (value === null || value === undefined) return '';\n if (typeof value === 'string') return value;\n if (typeof value === 'number' || typeof value === 'boolean' || typeof value === 'bigint') {\n return String(value);\n }\n try {\n return JSON.stringify(value);\n } catch {\n return '';\n }\n}\n\n/** The three values every renderer treats as \"clear\" (docs/renderers.md, value semantics). */\nexport function isEmptyValue(value: unknown): value is null | undefined | '' {\n return value === null || value === undefined || value === '';\n}\n","/**\n * LRU discipline for a module-scoped lookup `Map` (ADR 0003 §3). Functions\n * over the caller's own `Map` rather than a wrapper class: the inline bundle\n * mangles function names but not property names, so a class would pay for\n * every `this.entries` in full. A `Map` iterates in insertion order, which a\n * touch on every hit turns into recency order. Values are never `undefined`,\n * and a write follows a miss — a key already present keeps its position.\n */\n\n/** Read and touch: a hit becomes the newest entry. */\nexport function lruGet<K, V>(map: Map<K, V>, key: K): V | undefined {\n const value = map.get(key);\n if (value !== undefined) {\n map.delete(key);\n map.set(key, value);\n }\n return value;\n}\n\n/** Write as the newest entry, dropping the oldest ones past `limit`; returns `value`. */\nexport function lruSet<K, V>(map: Map<K, V>, key: K, value: V, limit: number): V {\n map.set(key, value);\n lruTrim(map, limit);\n return value;\n}\n\n/** Drop the oldest entries until `limit` holds. */\nexport function lruTrim<K>(map: Map<K, unknown>, limit: number): void {\n for (const oldest of map.keys()) {\n if (map.size <= limit) break;\n map.delete(oldest);\n }\n}\n","/**\n * Sanitizer options for item templates (`data-payload-array-template`,\n * nested templates). A template is the page author's markup and every\n * interpolated value is escaped to text before the sanitizer runs, so it may\n * carry form controls and custom elements the rich-text policy refuses.\n * Event handlers, `style` and unsafe URLs are still stripped.\n *\n * Some entries below are already admitted by the sanitizer through another\n * route — `video` and `audio` by the tag allow-list, `select` by\n * `allowFormControls`, `name` by `templateMode`, and `controls`, `muted`,\n * `loop`, `poster` and `src` by the per-tag attribute map. They are kept\n * because this list states what a template may contain, and an allow-list\n * that depends on a second list staying unchanged is the more fragile of the\n * two arrangements. Mutating those entries changes nothing observable, so\n * they survive mutation testing by construction; the behaviour they describe\n * is pinned in `tests/unit/core/template-sanitize.test.ts` instead.\n */\n\nimport type { SanitizeOptions } from '@security/sanitizer';\nimport { lruGet, lruSet } from './lru';\n\nconst TEMPLATE_EXTRA_TAGS: readonly string[] = [\n 'input',\n 'textarea',\n 'select',\n 'option',\n 'button',\n 'label',\n 'details',\n 'summary',\n 'dialog',\n 'video',\n 'audio',\n 'progress',\n 'meter',\n];\n\nconst TEMPLATE_EXTRA_ATTRIBUTES: readonly string[] = [\n 'type',\n 'name',\n 'placeholder',\n 'open',\n 'disabled',\n 'readonly',\n 'required',\n 'checked',\n 'selected',\n 'value',\n 'min',\n 'max',\n 'step',\n 'rows',\n 'cols',\n 'for',\n 'controls',\n 'muted',\n 'loop',\n 'poster',\n 'src',\n];\n\nconst CUSTOM_TAG_PATTERN = /<([a-z][a-z0-9]*(?:-[a-z0-9]+)+)\\b/gi;\n\n// 64 like the intl cache: more than a page declares, and a nested template is\n// interpolated with its parent's, so an outer value or `{{index}}` that lands\n// in it mints a key per item and per keystroke (ADR 0003 §3).\nexport const TEMPLATE_CACHE_LIMIT = 64;\nconst optionsByTemplate = new Map<string, SanitizeOptions>();\n\n/** Options for one template; memoised per template string. */\nexport function templateSanitizeOptions(template: string): SanitizeOptions {\n const cached = lruGet(optionsByTemplate, template);\n if (cached !== undefined) return cached;\n const tags = new Set(TEMPLATE_EXTRA_TAGS);\n for (const match of template.matchAll(CUSTOM_TAG_PATTERN)) {\n const tag = match[1]?.toLowerCase();\n if (tag !== undefined) tags.add(tag);\n }\n const attributes: Record<string, readonly string[]> = {};\n for (const tag of tags) attributes[tag] = TEMPLATE_EXTRA_ATTRIBUTES;\n const options: SanitizeOptions = {\n additionalAllowedTags: [...tags],\n additionalAllowedAttributes: attributes,\n allowFormControls: true,\n templateMode: true,\n };\n return lruSet(optionsByTemplate, template, options, TEMPLATE_CACHE_LIMIT);\n}\n","/**\n * Applies an `ArrayPatch[]` diff to a container as keyed DOM operations\n * instead of rebuilding the list, so consumer state on surviving children is\n * kept. Items are paired by `data-payload-key` (the item `id`); items without\n * one pair by position. Nested arrays reconcile recursively through\n * `data-payload-nested-key` slots. See ADR 0008.\n */\n\nimport { sanitizeHtmlWithPolicy, type SanitizerPolicyMode } from '@security/sanitizer';\nimport { trustedHtml } from '@security/trusted-types';\nimport {\n collectTemplateKeys,\n inheritItemAttributes,\n interpolateArrayTemplate,\n sharedItemAttributes,\n type InheritedAttribute,\n} from './array-template';\nimport { safeStringify } from '@field-types/utils';\nimport { diffArray, type ArrayPatch } from '@schema/diff';\nimport { morphElement } from './morph';\nimport { templateSanitizeOptions } from './template-sanitize';\n\n/** @internal */\nexport const KEY_ATTRIBUTE = 'data-payload-key';\nconst NESTED_KEY_ATTRIBUTE = 'data-payload-nested-key';\nconst NESTED_TEMPLATE_ATTRIBUTE = 'data-payload-nested-template';\n\n/** Last value seen per item key, per container; owned by the caller so instances never share it. @internal */\nexport type StructuralStore = WeakMap<Element, Map<string, unknown>>;\n\n/** @internal */\nexport function createStructuralStore(): StructuralStore {\n return new WeakMap<Element, Map<string, unknown>>();\n}\n\n/** @internal */\nexport interface StructuralApplyOptions {\n readonly template: string;\n readonly container: Element;\n readonly patches: readonly ArrayPatch[];\n /** The full new array; inserts and replaces render by index from it. */\n readonly nextItems: readonly unknown[];\n /** Pass the same store across renders so nested arrays diff incrementally. */\n readonly store: StructuralStore;\n /** Re-render existing items even when unchanged. */\n readonly forceRender?: boolean;\n /** The instance's policy for item markup; absent, the process default applies. */\n readonly sanitizerPolicy?: SanitizerPolicyMode | undefined;\n /** Edit a changed item in place instead of replacing it. Default `true`. */\n readonly morph?: boolean;\n /** Reported once per container when two items share a key (`LP0405`). */\n readonly onDuplicateKey?: (container: Element, key: string) => void;\n}\n\n/**\n * Returns `true` for a DOM mutation, `false` for an already-current tree, and\n * `null` when an item's markup has no sanitized element root — preflighted\n * before any mutation, so the previous DOM and memory stay intact.\n * @internal\n */\nexport function applyStructuralPatches(options: StructuralApplyOptions): boolean | null {\n const plan = prepareStructuralPlan(options.container, options.patches, options);\n if (plan === null) return null;\n return commitStructuralPlan(plan, options.store, {\n morph: options.morph ?? true,\n onDuplicateKey: options.onDuplicateKey,\n });\n}\n\n// Plan records are tuples: many are created per recursive render, and named\n// keys would repeat in the inline bundle.\ntype StructuralPlan = readonly [\n container: Element,\n entries: readonly ReconciliationEntry[],\n nextItems: readonly unknown[],\n];\ntype ReconciliationEntry = readonly [\n index: number,\n live: Element | null,\n rendered: Element | undefined,\n nestedSlots: readonly NestedSlotPlan[],\n /** A `replace` patch: a different item, never morphed toward. */\n replace: boolean,\n];\ntype NestedSlotPlan = readonly [\n live: Element | null,\n rendered: Element,\n children: StructuralPlan | undefined,\n];\n\n// One per container, not per item, so — unlike the tuples above — named keys\n// cost the inline bundle nothing per render.\ntype RenderEnv = Pick<\n StructuralApplyOptions,\n 'template' | 'nextItems' | 'forceRender' | 'store' | 'sanitizerPolicy'\n>;\n\ninterface CommitOptions {\n readonly morph: boolean;\n readonly onDuplicateKey: ((container: Element, key: string) => void) | undefined;\n}\n\n/** A rendered slot that still carries a nested template keeps its children for its own plan. */\nfunction isManagedNestedSlot(_live: Element, rendered: Element): boolean {\n return (\n rendered.hasAttribute(NESTED_KEY_ATTRIBUTE) && rendered.hasAttribute(NESTED_TEMPLATE_ATTRIBUTE)\n );\n}\n\n/** Materialise the whole recursive replacement tree before touching live DOM. */\nfunction prepareStructuralPlan(\n container: Element,\n patches: readonly ArrayPatch[],\n env: RenderEnv,\n): StructuralPlan | null {\n const entries = prepareReconciliation(container, createPatchPlan(patches), env);\n return entries === null ? null : [container, entries, env.nextItems];\n}\n\nfunction commitStructuralPlan(\n plan: StructuralPlan,\n store: StructuralStore,\n options: CommitOptions,\n): boolean {\n const [container, entries, nextItems] = plan;\n const claimed = new Set<Element>();\n let mutated = false;\n for (const [index, live, rendered, nestedSlots, replace] of entries) {\n let node = live;\n if (rendered !== undefined) {\n // Morph a compatible live item in place; otherwise transplant its live\n // nested slots into the rendered item and swap.\n const retained =\n options.morph && !replace && live !== null\n ? morphElement(live, rendered, {\n keyAttributes: [KEY_ATTRIBUTE, NESTED_KEY_ATTRIBUTE],\n retainChildrenOf: isManagedNestedSlot,\n ...(options.onDuplicateKey !== undefined\n ? { onDuplicateKey: options.onDuplicateKey }\n : {}),\n }) === live\n : false;\n if (!retained) {\n for (const [liveSlot, renderedSlot] of nestedSlots) {\n if (liveSlot === null) continue;\n synchronizeAttributes(liveSlot, renderedSlot);\n renderedSlot.replaceWith(liveSlot);\n }\n }\n for (const [, , children] of nestedSlots) {\n if (children !== undefined) commitStructuralPlan(children, store, options);\n }\n if (retained) {\n mutated = true;\n } else {\n if (live !== null) {\n live.replaceWith(rendered);\n mutated = true;\n }\n node = rendered;\n }\n }\n if (node === null) continue;\n const before = container.children[index] ?? null;\n if (node !== before) {\n container.insertBefore(node, before);\n mutated = true;\n }\n claimed.add(node);\n }\n // `nextItems` is the source of truth; this also drops SSR children the first value did not carry.\n for (const child of Array.from(container.children)) {\n if (claimed.has(child)) continue;\n child.remove();\n mutated = true;\n }\n const memory = getMemory(container, store);\n memory.clear();\n for (const value of nextItems) rememberItem(memory, value);\n return mutated;\n}\n\n/**\n * Pair every final item with a live child (by key, else by position) and\n * render what needs rendering. Patch indices describe `next`, live indices\n * move during reconciliation, so keyed nodes are resolved from the DOM first.\n */\nfunction prepareReconciliation(\n container: Element,\n plan: PatchPlan,\n env: RenderEnv,\n): readonly ReconciliationEntry[] | null {\n const { template, nextItems, forceRender = false, store, sanitizerPolicy } = env;\n const memory = store.get(container);\n // Read before anything is rendered: what the current items share is what the\n // template cannot say, and an inserted item has no predecessor of its own.\n const shared = sharedItemAttributes(container);\n const templateKeys = collectTemplateKeys(nextItems);\n const initialChildren = Array.from(container.children);\n const keyedChildren = indexByAttribute(initialChildren, KEY_ATTRIBUTE);\n const reserved = new Set<Element>();\n const entries: ReconciliationEntry[] = [];\n for (let index = 0; index < nextItems.length; index += 1) {\n const value = nextItems[index];\n const key = readKey(value);\n let live =\n key === undefined\n ? (initialChildren[index] ?? null)\n : (takeIndexedElement(keyedChildren, key) ?? null);\n if (live !== null && reserved.has(live)) live = null;\n if (live !== null) reserved.add(live);\n const replace = plan.replaces.has(index);\n const needsRender = forceRender || plan.renders.has(index) || live === null;\n const rendered = needsRender\n ? renderItem(\n container.ownerDocument,\n template,\n value,\n index,\n sanitizerPolicy,\n shared,\n templateKeys,\n )\n : undefined;\n if (rendered === null) return null;\n const nestedSlots =\n rendered === undefined\n ? []\n : prepareNestedSlots(\n replace ? null : live,\n rendered,\n value,\n key === undefined ? undefined : memory?.get(key),\n env,\n );\n if (nestedSlots === null) return null;\n entries.push([index, live, rendered, nestedSlots, replace]);\n }\n return entries;\n}\n\ninterface PatchPlan {\n readonly renders: ReadonlySet<number>;\n readonly replaces: ReadonlySet<number>;\n}\n\nfunction createPatchPlan(patches: readonly ArrayPatch[]): PatchPlan {\n const renders = new Set<number>();\n const replaces = new Set<number>();\n for (const patch of patches) {\n if (patch.kind === 'insert' || patch.kind === 'update') renders.add(patch.index);\n else if (patch.kind === 'replace') {\n renders.add(patch.index);\n replaces.add(patch.index);\n }\n }\n return { renders, replaces };\n}\n\n/** Plan each direct nested slot; a failure at any depth aborts before commit. */\nfunction prepareNestedSlots(\n oldItem: Element | null,\n newItem: Element,\n nextValue: unknown,\n prevValue: unknown,\n env: RenderEnv,\n): readonly NestedSlotPlan[] | null {\n const oldSlots = oldItem === null ? [] : findDirectNestedSlots(oldItem);\n const oldSlotsByKey = indexByAttribute(oldSlots, NESTED_KEY_ATTRIBUTE);\n const plans: NestedSlotPlan[] = [];\n for (const newSlot of findDirectNestedSlots(newItem)) {\n const key = newSlot.getAttribute(NESTED_KEY_ATTRIBUTE);\n if (key === null) continue;\n const oldSlot = takeIndexedElement(oldSlotsByKey, key) ?? null;\n const nextTemplate = newSlot.getAttribute(NESTED_TEMPLATE_ATTRIBUTE);\n // Without a nested template the slot's rendered static content is authoritative.\n const liveSlot = nextTemplate ? oldSlot : null;\n const previousTemplate = liveSlot?.getAttribute(NESTED_TEMPLATE_ATTRIBUTE) ?? null;\n let children: StructuralPlan | undefined;\n if (nextTemplate) {\n const nextNested = readNestedArray(nextValue, key);\n if (nextNested !== undefined || liveSlot !== null) {\n const resolvedNext = nextNested ?? [];\n const prevNested = liveSlot === null ? [] : (readNestedArray(prevValue, key) ?? []);\n const patches = diffArray(prevNested, resolvedNext);\n const templateChanged = liveSlot !== null && previousTemplate !== nextTemplate;\n if (patches.length > 0 || templateChanged) {\n children =\n prepareStructuralPlan(liveSlot ?? newSlot, patches, {\n template: nextTemplate,\n nextItems: resolvedNext,\n forceRender: templateChanged,\n store: env.store,\n sanitizerPolicy: env.sanitizerPolicy,\n }) ?? undefined;\n if (children === undefined) return null;\n }\n }\n }\n plans.push([liveSlot, newSlot, children]);\n }\n return plans;\n}\n\n/** Only the outermost nested slots: a transplanted slot owns the recursion below it. */\nfunction findDirectNestedSlots(item: Element): readonly Element[] {\n return Array.from(item.querySelectorAll(`[${NESTED_KEY_ATTRIBUTE}]`)).filter((slot) => {\n let ancestor = slot.parentElement;\n while (ancestor !== null && ancestor !== item) {\n if (ancestor.hasAttribute(NESTED_KEY_ATTRIBUTE)) return false;\n ancestor = ancestor.parentElement;\n }\n return ancestor === item;\n });\n}\n\nfunction synchronizeAttributes(target: Element, source: Element): void {\n for (const attribute of Array.from(target.attributes)) {\n if (!source.hasAttribute(attribute.name)) target.removeAttribute(attribute.name);\n }\n for (const attribute of Array.from(source.attributes)) {\n if (target.getAttribute(attribute.name) !== attribute.value) {\n target.setAttribute(attribute.name, attribute.value);\n }\n }\n}\n\nfunction readNestedArray(value: unknown, key: string): readonly unknown[] | undefined {\n if (typeof value !== 'object' || value === null) return undefined;\n const nested = (value as Record<string, unknown>)[key];\n return Array.isArray(nested) ? (nested as readonly unknown[]) : undefined;\n}\n\nfunction getMemory(container: Element, store: StructuralStore): Map<string, unknown> {\n let map = store.get(container);\n if (!map) {\n map = new Map();\n store.set(container, map);\n }\n return map;\n}\n\nfunction rememberItem(memory: Map<string, unknown>, value: unknown): void {\n const key = readKey(value);\n if (key !== undefined) memory.set(key, value);\n}\n\nfunction readKey(value: unknown): string | undefined {\n if (typeof value !== 'object' || value === null) return undefined;\n const id = (value as Record<string, unknown>)['id'];\n return typeof id === 'string' || typeof id === 'number' ? String(id) : undefined;\n}\n\nfunction indexByAttribute(elements: readonly Element[], attribute: string): Map<string, Element[]> {\n const indexed = new Map<string, Element[]>();\n // Reverse order so pop() yields duplicates in DOM order.\n for (let index = elements.length - 1; index >= 0; index -= 1) {\n const element = elements[index];\n if (element === undefined) continue;\n const key = element.getAttribute(attribute);\n if (key === null) continue;\n const bucket = indexed.get(key);\n if (bucket === undefined) indexed.set(key, [element]);\n else bucket.push(element);\n }\n return indexed;\n}\n\nfunction takeIndexedElement(indexed: Map<string, Element[]>, key: string): Element | undefined {\n return indexed.get(key)?.pop();\n}\n\n/** Render one item; its `id` is stamped as `data-payload-key` so later diffs find it. */\nfunction renderItem(\n ownerDocument: Document,\n template: string,\n value: unknown,\n index: number,\n policy: SanitizerPolicyMode | undefined,\n shared: readonly InheritedAttribute[],\n knownKeys: ReadonlySet<string>,\n): Element | null {\n const filled = interpolateArrayTemplate(template, value, index, safeStringify, knownKeys);\n const safe = sanitizeHtmlWithPolicy(filled, policy, templateSanitizeOptions(template));\n const host = ownerDocument.createElement('template');\n host.innerHTML = trustedHtml(safe);\n const first = host.content.firstElementChild;\n if (!first) return null;\n // Before the morph, which strips from the live item every attribute the\n // rendered one lacks: the marker has to be on this side to survive.\n inheritItemAttributes(first, shared);\n const key = readKey(value);\n if (key !== undefined) first.setAttribute(KEY_ATTRIBUTE, key);\n return first;\n}\n","/**\n * The two warnings a binding's strategy can produce, kept apart from the runner\n * that usually issues them: the lean profile has no runner (see ./profile) and\n * still owes a page these answers, because both describe the markup, not the\n * strategy machinery.\n */\n\nimport type { RuntimeDeps, RuntimeState } from './runtime-state';\nimport type { CachedElement } from './types';\n\n/** LP0806, once: a fragment boundary with no handler is patched instead. */\nexport function warnFragmentFallback(\n deps: RuntimeDeps,\n state: RuntimeState,\n target: CachedElement,\n): void {\n if (state.warnedFragmentFallback) return;\n state.warnedFragmentFallback = true;\n deps.warn(\n `[live-preview] LP0806: \"${target.fieldName}\" asks for the fragment strategy but no handler is configured; patching instead`,\n );\n}\n\n/** LP0407, once per element: an unknown strategy is left alone, not guessed at. */\nexport function warnUnsupportedStrategy(\n deps: RuntimeDeps,\n state: RuntimeState,\n target: CachedElement,\n): void {\n if (state.warnedStrategy.has(target.element)) return;\n state.warnedStrategy.add(target.element);\n deps.warn(\n `[live-preview] LP0407: \"${target.fieldName}\" asks for strategy \"${String(target.strategy)}\"; only patch, fragment and route exist`,\n );\n}\n","/**\n * Runs the fragment and route strategies for a revision. A strategy that\n * throws or rejects is treated as failed, never left to reject the runtime.\n */\n\nimport type { PayloadLivePreviewData } from '@/types/payload-protocol';\nimport { trustedHtml } from '@security/trusted-types';\nimport { reportUnboundChange } from './fidelity';\nimport { bindingValue } from './field-value';\nimport { morphElement } from './morph';\nimport type { RuntimeDeps, RuntimeState, UpdateTransaction } from './runtime-state';\nimport type { FragmentContext, FragmentStrategy, RouteOutcome, RouteStrategy } from './strategies';\nimport { KEY_ATTRIBUTE } from './structural-applier';\nimport { warnFragmentFallback, warnUnsupportedStrategy } from './strategy-warnings';\nimport { unboundChangedFields, type OwnerScope } from './unbound-fields';\nimport type { CachedElement } from './types';\n\n/** What the pipeline lends the runner. */\nexport interface StrategyHost {\n readonly reapply: (transaction: UpdateTransaction, data: PayloadLivePreviewData) => void;\n readonly transform: (\n target: CachedElement,\n value: unknown,\n allFields: Record<string, unknown>,\n isCurrent: () => boolean,\n ) => unknown;\n readonly rebuildCache: () => void;\n /** A server render — the route, or a fragment boundary — dropped the stamps a guess lives by; look for the baseline's guesses again (ADR 0014). */\n readonly restoreGuesses: (transaction: UpdateTransaction, data: PayloadLivePreviewData) => void;\n /** Scroll to the binding this revision marked, if it has not been revealed yet. */\n readonly revealPending: (transaction: UpdateTransaction) => void;\n}\n\nexport interface FragmentPlan {\n readonly boundaries: readonly Element[];\n readonly strategy: FragmentStrategy;\n /** Whether a binding sits inside a boundary the strategy renders this revision. */\n readonly covers: (target: CachedElement) => boolean;\n}\n\nexport class StrategyRunner {\n constructor(\n private readonly deps: RuntimeDeps,\n private readonly state: RuntimeState,\n private readonly host: StrategyHost,\n ) {}\n\n planFragments(touched: ReadonlySet<string>): FragmentPlan | null {\n const strategy = this.deps.strategies.fragment;\n if (strategy === undefined) return null;\n return planBoundaries(strategy, strategy.plan(this.deps.root, touched));\n }\n\n /**\n * Hand the bindings this revision could not patch faithfully to a server:\n * the fragment strategy when a boundary covers every one of them, the route\n * otherwise. All of them or none — a boundary renders its own region, so a\n * finding outside every boundary is only answered by the whole route.\n *\n * A revision that already refreshed the route is left alone: the second\n * request would fetch the bytes the first one just brought.\n */\n escalateUnfaithful(\n transaction: UpdateTransaction,\n data: PayloadLivePreviewData,\n targets: readonly CachedElement[],\n ): void {\n if (transaction.routeRefreshed) return;\n const { fragment, route } = this.deps.strategies;\n const boundaries = fragment === undefined ? undefined : coveringBoundaries(targets);\n if (fragment !== undefined && boundaries !== undefined) {\n this.state.escalatedCount += targets.length;\n transaction.pendingFragments += boundaries.length;\n void this.runFragments(transaction, data, planBoundaries(fragment, boundaries));\n return;\n }\n if (route === undefined) return;\n this.state.escalatedCount += targets.length;\n void this.refreshRoute(transaction, data, route);\n }\n\n /**\n * Whether this revision changed a field the page cannot patch — one with no\n * anchor anywhere, which is also how a section the template renders only\n * under a condition looks from here. The whole route is then the only honest\n * answer.\n *\n * Asked of every revision rather than only where a refresh could follow it,\n * because the finding is the same one under every mode and on a page with no\n * strategy — and that page is what `inspect().fidelity` is read on. What the\n * mode still decides is what is *done*: `'warn'` adds no line of its own\n * (LP0201 already names the field) and `'ignore'` keeps the stale value,\n * exactly as before; only the ledger sees them now.\n *\n * The baseline message is skipped, because there every field counts as\n * changed and the page has just been rendered from them anyway — and so is\n * the re-apply after a refresh, which would otherwise report it all twice.\n */\n hasUnboundChange(transaction: UpdateTransaction, ownerKeys: OwnerScope): boolean {\n const { deps, state } = this;\n if (transaction.baseline || transaction.routeRefreshed) return false;\n const unbound = unboundChangedFields(\n deps.cache,\n transaction.touched,\n transaction.locale,\n ownerKeys,\n );\n let answered = 0;\n for (const fieldName of unbound) if (reportUnboundChange(state, fieldName)) answered += 1;\n const [first] = unbound;\n if (first === undefined || deps.onUnfaithfulPatch !== 'escalate') return false;\n if (deps.strategies.route === undefined) return false;\n deps.log('route', 'LP0807', `field \"${first}\" has no binding; refreshing the route`);\n state.escalatedCount += answered;\n return true;\n }\n\n /** Whether a touched field is bound to an element the route owns. */\n hasRouteBinding(touched: ReadonlySet<string>): boolean {\n for (const [fieldName, bindings] of this.deps.cache.entries()) {\n if (!touched.has(fieldName)) continue;\n if (bindings.some((target) => target.strategyKind === 'route')) return true;\n }\n return false;\n }\n\n async runFragments(\n transaction: UpdateTransaction,\n data: PayloadLivePreviewData,\n plan: FragmentPlan,\n ): Promise<void> {\n const { deps, state } = this;\n const controller = new AbortController();\n state.fragmentController = controller;\n const isCurrent = (): boolean => state.isCurrent(transaction) && !controller.signal.aborted;\n const { emitter } = deps;\n const { message } = transaction;\n const revision = transaction.revision.revision;\n const receivedAt = transaction.receivedAt;\n const context: FragmentContext = {\n root: deps.root,\n revision,\n receivedAt,\n fields: data.fields,\n locale: transaction.locale,\n collectionSlug:\n typeof message.collectionSlug === 'string' ? message.collectionSlug : undefined,\n globalSlug: typeof message.globalSlug === 'string' ? message.globalSlug : undefined,\n signal: controller.signal,\n isCurrent,\n log: (code, detail) => {\n deps.log('fragment', code, detail);\n },\n morph: (boundary, html) => {\n morphFragment(boundary, html);\n },\n patch: (boundary) => {\n this.patchFallback(transaction, data, boundary);\n },\n rendered: (element, id, key) => {\n transaction.pendingFragments -= 1;\n void emitter.emitWhile(\n 'fragmentRender',\n { element, id, key, status: 'rendered', revision, receivedAt },\n isCurrent,\n );\n },\n failed: (element, id, key, code, reason) => {\n transaction.pendingFragments -= 1;\n const detail = `fragment \"${id}\" fell back to patch: ${reason}`;\n // Logged where the failure is, not where an exception would have been:\n // the supplied strategy answers a timeout or a refusal with an outcome\n // and never throws, so the `catch` around `render()` below is not on\n // this path and its LP0801 reached no log sink at all.\n deps.log('fragment', code, detail);\n void emitter.emitWhile(\n 'error',\n { error: new Error(detail), context: 'fragment', code },\n isCurrent,\n );\n void emitter.emitWhile(\n 'fragmentRender',\n { element, id, key, status: 'failed', code, revision, receivedAt },\n isCurrent,\n );\n },\n };\n let report = { rendered: 0, failed: 0, superseded: 0 };\n try {\n report = await plan.strategy.render(context, plan.boundaries);\n } catch (error) {\n deps.log('fragment', 'LP0801', error);\n if (isCurrent()) {\n for (const boundary of plan.boundaries) this.patchFallback(transaction, data, boundary);\n report = { rendered: 0, failed: plan.boundaries.length, superseded: 0 };\n }\n }\n state.fragmentStats.rendered += report.rendered;\n state.fragmentStats.failed += report.failed;\n state.fragmentStats.superseded += report.superseded;\n if (!isCurrent()) return;\n if (state.fragmentController === controller) state.fragmentController = null;\n transaction.pendingFragments = 0;\n // A rendered boundary holds the server's markup, which carries no stamp: the\n // guesses in it go back on, as after a refresh, before the revision counts\n // as complete. Without this a guess in a boundary did not outlive the first\n // message, which renders the boundary as well.\n if (report.rendered > 0) this.host.restoreGuesses(transaction, data);\n if (deps.scheduler.pendingCount === 0) state.complete(transaction);\n // The edited field may be one the server just rendered: its element is only\n // in place now, so this is the earliest point it can be scrolled to.\n this.host.revealPending(transaction);\n if (!isCurrent()) return;\n if (report.rendered === 0 || emitter.listenerCount('afterUpdate') === 0) return;\n void emitter.emitWhile(\n 'afterUpdate',\n {\n data,\n updatedCount: report.rendered,\n durationMs: Date.now() - receivedAt,\n revision,\n receivedAt,\n source: 'fragment',\n },\n isCurrent,\n );\n }\n\n /** Refresh the route once per revision, then re-apply the revision onto the fresh markup. */\n async refreshRoute(\n transaction: UpdateTransaction,\n data: PayloadLivePreviewData,\n strategy: RouteStrategy,\n ): Promise<void> {\n const { deps, state } = this;\n if (transaction.routeRefreshed) {\n state.routeStats.loopStopped += 1;\n deps.log(\n 'route',\n 'LP0805',\n `revision ${String(transaction.revision.revision)} asked for a second refresh`,\n );\n return;\n }\n // A refusal counts as asked as well: the trailing run below is this\n // revision's one refresh, and nothing else may start a second.\n transaction.routeRefreshed = true;\n await this.runRoute(transaction, data, strategy);\n }\n\n /**\n * The trailing run of a refused refresh: the strategy's window closes and the\n * request it held back runs, once. It cannot loop — a refresh re-renders the\n * page from the server and produces no message, so nothing asks again.\n */\n private armRouteRetry(\n transaction: UpdateTransaction,\n data: PayloadLivePreviewData,\n strategy: RouteStrategy,\n delayMs: number,\n ): void {\n const { state } = this;\n if (state.routeRetry !== null) clearTimeout(state.routeRetry);\n state.routeRetry = setTimeout(() => {\n state.routeRetry = null;\n if (!state.isCurrent(transaction)) return;\n void this.runRoute(transaction, data, strategy);\n }, delayMs);\n }\n\n /** One trip through the strategy, whether the revision asked for it or the window did. */\n private async runRoute(\n transaction: UpdateTransaction,\n data: PayloadLivePreviewData,\n strategy: RouteStrategy,\n ): Promise<void> {\n const { deps, state } = this;\n const stats = state.routeStats;\n const controller = new AbortController();\n state.routeController = controller;\n const isCurrent = (): boolean => state.isCurrent(transaction) && !controller.signal.aborted;\n let outcome: RouteOutcome;\n try {\n outcome = await strategy.refresh({\n revision: transaction.revision.revision,\n receivedAt: transaction.receivedAt,\n signal: controller.signal,\n isCurrent,\n log: (code, detail) => {\n deps.log('route', code, detail);\n },\n retryAfter: (delayMs) => {\n this.armRouteRetry(transaction, data, strategy, delayMs);\n },\n });\n } catch (error) {\n deps.log('route', 'LP0801', error);\n outcome = 'failed';\n }\n if (!isCurrent()) return;\n if (state.routeController === controller) state.routeController = null;\n if (outcome === 'refreshed') {\n stats.refreshes += 1;\n // The route rendered the saved document; nothing on the page is \"last applied\" any more.\n state.lastAppliedIdentity = new WeakMap();\n // The fresh markup carries no stamp: the guesses go back on before the\n // cache is rebuilt from it, or the rebuild would not know them.\n this.host.restoreGuesses(transaction, data);\n this.host.rebuildCache();\n if (!isCurrent()) return;\n this.host.reapply(transaction, data);\n if (deps.emitter.listenerCount('afterUpdate') > 0) {\n void deps.emitter.emitWhile(\n 'afterUpdate',\n {\n data,\n // The server re-rendered the whole route, so every binding now on\n // the page carries fresh markup; the unsaved fields scheduled just\n // above report themselves in their own `patch` batch.\n updatedCount: deps.cache.elementCount,\n durationMs: Date.now() - transaction.receivedAt,\n revision: transaction.revision.revision,\n receivedAt: transaction.receivedAt,\n source: 'route',\n },\n isCurrent,\n );\n }\n return;\n }\n // A refusal is a pause, not a breakage; counting the two together is how\n // `failed: 3` came to stand in an inspection where nothing was wrong.\n if (outcome === 'failed') stats.failed += 1;\n else if (outcome === 'refused') stats.refused += 1;\n // Either way the page shows what it can now: the window holds back the\n // server, not the bindings this revision could already have written.\n this.host.reapply(transaction, data);\n }\n\n /** LP0806, once: a fragment boundary with no handler is patched instead. */\n warnFragmentFallback(target: CachedElement): void {\n warnFragmentFallback(this.deps, this.state, target);\n }\n\n /** LP0407, once per element: an unknown strategy is left alone, not guessed at. */\n warnUnsupportedStrategy(target: CachedElement): void {\n warnUnsupportedStrategy(this.deps, this.state, target);\n }\n\n /** The deterministic fallback: patch the boundary's own bindings from the same revision. */\n private patchFallback(\n transaction: UpdateTransaction,\n data: PayloadLivePreviewData,\n boundary: Element,\n ): void {\n for (const [fieldName, bindings] of this.deps.cache.entries()) {\n for (const target of bindings) {\n if (target.fragmentBoundary !== boundary) continue;\n const value = bindingValue(data.fields, target, fieldName, transaction.locale);\n if (value === undefined) continue;\n this.deps.scheduler.schedule({\n target,\n value: this.host.transform(target, value, data.fields, () => true),\n allFields: data.fields,\n revision: transaction.revision,\n data,\n });\n }\n }\n }\n}\n\n/** The distinct boundaries around `targets`, or `undefined` when one sits outside them all. */\nfunction coveringBoundaries(targets: readonly CachedElement[]): Element[] | undefined {\n const boundaries: Element[] = [];\n for (const target of targets) {\n const boundary = target.fragmentBoundary;\n if (boundary === undefined) return undefined;\n if (!boundaries.includes(boundary)) boundaries.push(boundary);\n }\n return boundaries;\n}\n\n/** A plan over boundaries already chosen, whichever question chose them. */\nfunction planBoundaries(strategy: FragmentStrategy, boundaries: readonly Element[]): FragmentPlan {\n const covered = new Set(boundaries);\n return {\n boundaries,\n strategy,\n covers: (target) =>\n target.fragmentBoundary !== undefined && covered.has(target.fragmentBoundary),\n };\n}\n\n/** Morph server-rendered HTML into the boundary, keeping focus and visitor state. */\nfunction morphFragment(boundary: Element, html: string): void {\n const template = boundary.ownerDocument.createElement('template');\n template.innerHTML = trustedHtml(html);\n const rendered = boundary.cloneNode(false) as Element;\n rendered.append(template.content);\n morphElement(boundary, rendered, { keyAttributes: [KEY_ATTRIBUTE] });\n}\n","/**\n * The plugin boundary on a value's way to its binding. Transforms are consumer\n * code: their result is frozen into the scheduler entry, an error is reported\n * as LP0602 and the original value kept, and a thenable is a contract error —\n * a transform that awaits would hand the scheduler a promise to render.\n */\n\nimport type { RuntimeDeps } from './runtime-state';\nimport { observeThenableResult } from './thenable';\nimport type { CachedElement } from './types';\n\n/** Never awaited: every consumer callback may accept a newer revision synchronously (ADR 0004). */\nexport function transformForBinding(\n deps: RuntimeDeps,\n target: CachedElement,\n originalValue: unknown,\n allFields: Record<string, unknown>,\n isCurrent: () => boolean,\n): unknown {\n const transform = deps.transformValue;\n if (transform === undefined) return originalValue;\n try {\n const transformed = transform(\n target.fieldName,\n originalValue,\n { element: target.element, allFields },\n isCurrent,\n );\n const returnedThenable = observeThenableResult(transformed);\n if (!isCurrent()) return originalValue;\n if (returnedThenable) {\n throw new TypeError(\n `Transform for \"${target.fieldName}\" returned a thenable; transforms must be synchronous`,\n );\n }\n return transformed;\n } catch (err) {\n if (!isCurrent()) return originalValue;\n const error = err instanceof Error ? err : new Error(String(err));\n void deps.emitter.emit('error', { error, context: 'transform', code: 'LP0602' });\n return originalValue;\n }\n}\n","/**\n * From an accepted message to scheduled writes: merge, diff, plan the\n * strategies, schedule each binding, and finish the revision on flush.\n */\n\nimport type { PayloadLivePreviewData, PayloadLivePreviewMessage } from '@/types/payload-protocol';\nimport { buildSchemaIndex } from '@schema/index';\nimport { adoptUniqueBindings, restoreUniqueBindings } from './auto-bind';\nimport { isBindingInScope, messageOwnerKeys, readDocumentId } from './binding-owner';\nimport type { MergeResult } from './data-merger';\nimport { mergeDependencyMaps } from './dependencies';\nimport { bindingIdentity, bindingValue } from './field-value';\nimport { dispatchIslandUpdate } from './islands';\nimport { type MessageRevision, sameRevision } from './message-bus';\nimport { diagnoseOrphanFields } from './orphan-diagnostics';\nimport { reportOmittedFeature } from './profile';\nimport { detectProtocolProfile } from './protocol-profile';\nimport { observeCapabilities } from './protocol-version';\nimport { owesForceRender } from './relationship-tracker';\nimport type { RevealWindow } from './reveal';\nimport { type RuntimeDeps, type RuntimeState, type UpdateTransaction } from './runtime-state';\nimport { resolveStrategy } from './strategies';\nimport { StrategyRunner } from './strategy-runner';\nimport { createLeanStrategyRunner, type StrategyRunnerLike } from './strategy-runner-lean';\nimport { transformForBinding } from './transform-value';\nimport type { CachedElement } from './types';\nimport type { FlushStats, ScheduledUpdate } from './update-scheduler';\n\n/** A refinement moved no field: it completes values the revision already applied. */\nconst NOTHING_CHANGED: ReadonlySet<string> = new Set();\n\nexport class UpdatePipeline {\n private readonly strategies: StrategyRunnerLike;\n\n constructor(\n private readonly deps: RuntimeDeps,\n private readonly state: RuntimeState,\n rebuildCache: () => void,\n ) {\n // The profile decides, and esbuild folds the branch: the lean build drops\n // the real runner and everything only it reached — the morph, the fragment\n // client's server half, the route refresh (./profile, build-flags.d.ts).\n this.strategies =\n typeof __LEAN_BUILD__ !== 'undefined' && __LEAN_BUILD__\n ? createLeanStrategyRunner(deps, state)\n : new StrategyRunner(deps, state, {\n reapply: (transaction, data) => {\n this.scheduleAllFields(transaction, data);\n },\n transform: (target, value, allFields, isCurrent) =>\n transformForBinding(deps, target, value, allFields, isCurrent),\n rebuildCache,\n restoreGuesses: (transaction, data) => {\n this.restoreGuesses(transaction, data);\n },\n revealPending: (transaction) => {\n this.revealPending(transaction);\n },\n });\n }\n\n /** Message-bus callback for every shape-valid update. */\n handleUpdate(\n message: PayloadLivePreviewMessage,\n origin: string,\n revision: MessageRevision | undefined,\n ): void {\n const { deps, state } = this;\n deps.heartbeat.kick();\n state.protocol.observe(observeCapabilities(message), deps.log);\n if (message.data === undefined) {\n if (message.protocolVersion !== undefined) {\n state.protocol.applyVersion(message.protocolVersion, deps.log);\n }\n return;\n }\n if (revision === undefined) return;\n // A level, not an edge: the panel repeats its last document event in every\n // message and never clears it, so only a changed event about a document\n // other than this one is news (LP-1).\n const relationshipEdit = state.relationships.edit(message);\n if (relationshipEdit !== null) {\n void deps.emitter.emit('relationshipUpdate', {\n detail: relationshipEdit,\n timestamp: Date.now(),\n });\n }\n if (typeof message.locale === 'string') state.locale = message.locale;\n if (Array.isArray(message.fieldSchemaJSON)) {\n state.schema = message.fieldSchemaJSON;\n state.schemaIndex = buildSchemaIndex(message.fieldSchemaJSON);\n }\n const transaction: UpdateTransaction = {\n revision,\n message,\n locale: state.locale,\n schema: state.schema,\n schemaIndex: state.schemaIndex,\n receivedAt: Date.now(),\n forceRender: relationshipEdit !== null || owesForceRender(state.activeUpdate),\n touched: new Set(),\n baseline: false,\n invalidated: new Set(),\n revealTarget: undefined,\n revealIdentities: [],\n pendingFragments: 0,\n routeRefreshed: false,\n cancelled: false,\n completed: false,\n };\n // Acceptance is the single supersession point. Only a revision that never\n // reached its terminal state counts as superseded.\n const previous = state.activeUpdate;\n state.abortStrategies();\n if (previous !== null && !previous.completed) state.supersededCount += 1;\n state.activeUpdate = transaction;\n deps.scheduler.acceptRevision(revision);\n state.updateCount += 1;\n if (message.protocolVersion !== undefined) {\n state.protocol.applyVersion(message.protocolVersion, deps.log);\n if (!state.isCurrent(transaction)) return;\n }\n if (deps.connection.markConnected()) {\n deps.a11y?.announceConnected();\n void deps.emitter.emit('connect', { origin, timestamp: Date.now() });\n if (!state.isCurrent(transaction)) return;\n deps.log('connection', 'disconnected', '→', 'connected');\n if (!state.isCurrent(transaction)) return;\n }\n // Nothing awaits this, so an unexpected throw would leave the page as an\n // unhandled rejection — a console error the host cannot attribute, and a\n // process exit under `--unhandled-rejections=strict`.\n void this.processUpdate(transaction).catch((error: unknown) => {\n deps.log('update failed:', error);\n });\n }\n\n private async processUpdate(transaction: UpdateTransaction): Promise<void> {\n const { deps, state } = this;\n const fields = await this.resolveIncomingFields(transaction);\n if (fields === null || !state.isCurrent(transaction)) return;\n const data = this.dataFor(transaction, fields);\n if (deps.emitter.listenerCount('beforeUpdate') > 0) {\n const completed = await deps.emitter.emitWhile(\n 'beforeUpdate',\n {\n data,\n revision: transaction.revision.revision,\n receivedAt: transaction.receivedAt,\n source: 'patch',\n cancel: (): void => {\n transaction.cancelled = true;\n deps.scheduler.cancelRevision(transaction.revision);\n },\n },\n () => !transaction.cancelled && state.isCurrent(transaction),\n );\n if (!completed || transaction.cancelled || !state.isCurrent(transaction)) return;\n }\n this.applyFields(transaction, data, false);\n }\n\n private dataFor(\n transaction: UpdateTransaction,\n fields: Record<string, unknown>,\n ): PayloadLivePreviewData {\n const { message } = transaction;\n return {\n fields,\n ...(transaction.schema !== undefined ? { schema: transaction.schema } : {}),\n ...(typeof message.globalSlug === 'string' ? { globalSlug: message.globalSlug } : {}),\n ...(typeof message.collectionSlug === 'string'\n ? { collectionSlug: message.collectionSlug }\n : {}),\n ...(transaction.locale !== undefined ? { locale: transaction.locale } : {}),\n };\n }\n\n /**\n * Diff against what the page last showed, then schedule. A refinement is the\n * populated answer to values this revision already applied: it keeps the diff\n * in step without letting population count as an edit, because no strategy\n * may be planned a second time for one message.\n */\n private applyFields(\n transaction: UpdateTransaction,\n data: PayloadLivePreviewData,\n refined: boolean,\n ): void {\n const { deps, state } = this;\n const dependencies = mergeDependencyMaps(deps.dependencies, deps.cache.dependencyMap());\n const changes = state.changes.diff(data.fields, dependencies);\n if (changes.baseline && !refined && deps.autoBind !== 'off') {\n // Once, on the message that describes what the server rendered (ADR 0014\n // §1). The lean profile leaves the search out; esbuild folds the branch.\n if (typeof __LEAN_BUILD__ !== 'undefined' && __LEAN_BUILD__) {\n reportOmittedFeature('auto-binding');\n } else {\n const scope = this.ownerKeysForUpdate(transaction, data.fields);\n adoptUniqueBindings(deps, state, data.fields, transaction.locale, scope);\n }\n }\n transaction.baseline = changes.baseline;\n transaction.invalidated = refined ? NOTHING_CHANGED : changes.invalidated;\n transaction.touched = refined\n ? NOTHING_CHANGED\n : new Set([...changes.changed, ...changes.invalidated]);\n this.scheduleAllFields(transaction, data);\n }\n\n /** The document to render: merged when the server has something to add, else the message's own values; `null` when superseded. */\n private async resolveIncomingFields(\n transaction: UpdateTransaction,\n ): Promise<Record<string, unknown> | null> {\n const { deps, state } = this;\n const raw = transaction.message.data ?? {};\n if (deps.merger === null) return raw;\n // A Payload 2.x admin posts populated relationships itself.\n if (detectProtocolProfile(state.protocol.observed).populatesRelationships === 'admin') {\n return raw;\n }\n const plan = state.merges.decide(deps, transaction);\n if (!plan.merge) return plan.fields;\n const { message } = transaction;\n const coalesced = state.merges.request(deps.merger, deps.mergeWindowMs, {\n collectionSlug: message.collectionSlug,\n globalSlug: message.globalSlug,\n data: raw,\n locale: transaction.locale,\n });\n // A request the burst shares is not one the page waits for: it renders what\n // it already has, and the answer refines it when the window closes.\n if (!coalesced.leading) {\n void this.applyMerged(transaction, coalesced.result).catch((error: unknown) => {\n deps.log('update failed:', error);\n });\n return plan.fields;\n }\n const result = await coalesced.result;\n if (!state.isCurrent(transaction)) return null;\n if (result.status === 'merged') {\n state.merges.recordMerged(result.doc);\n return result.doc;\n }\n if (result.status === 'superseded') return null;\n return plan.fields;\n }\n\n /** Whoever is still current when the shared merge lands gets the populated document. */\n private async applyMerged(\n transaction: UpdateTransaction,\n pending: Promise<MergeResult>,\n ): Promise<void> {\n const { state } = this;\n const result = await pending;\n if (result.status !== 'merged' || !state.isCurrent(transaction)) return;\n state.merges.recordMerged(result.doc);\n this.applyFields(transaction, this.dataFor(transaction, result.doc), true);\n }\n\n scheduleAllFields(transaction: UpdateTransaction, data: PayloadLivePreviewData): void {\n const { deps, state } = this;\n if (!state.isCurrent(transaction)) return;\n const isCurrent = (): boolean => state.isCurrent(transaction);\n const ownerKeys = this.ownerKeysForUpdate(transaction, data.fields);\n const { touched } = transaction;\n // A revision that touches the route refreshes it first; the re-apply lands on the fresh markup.\n const route = deps.strategies.route;\n const unbound = this.strategies.hasUnboundChange(transaction, ownerKeys);\n if (\n route !== undefined &&\n !transaction.routeRefreshed &&\n (unbound || route.plan(deps.root, touched) || this.strategies.hasRouteBinding(touched))\n ) {\n void this.strategies.refreshRoute(transaction, data, route);\n return;\n }\n const plan = this.strategies.planFragments(touched);\n // Only `skipUnchanged` needs it now; the reveal keeps its own ledger.\n const trackIdentity = deps.skipUnchanged;\n let scheduled = 0;\n for (const [fieldName, bindings] of deps.cache.entries()) {\n if (!isCurrent()) return;\n for (const target of bindings) {\n if (ownerKeys !== false && !isBindingInScope(target.owner, ownerKeys)) continue;\n // A binding inside a boundary the server renders is patched only as the\n // fallback — but it can still be the field being edited, so the reveal\n // has to notice it here, before the boundary is re-rendered.\n if (plan?.covers(target) === true) {\n // Resolving the value is only worth it when something reveals.\n if (deps.revealEditedField) {\n const raw = bindingValue(data.fields, target, fieldName, transaction.locale);\n state.revealLedger.note(transaction, target, raw);\n }\n continue;\n }\n const kind = target.strategyKind ?? resolveStrategy(target.element) ?? 'unknown';\n if (kind === 'unknown') {\n this.strategies.warnUnsupportedStrategy(target);\n continue;\n }\n if (kind === 'fragment' && plan === null) this.strategies.warnFragmentFallback(target);\n const value = bindingValue(data.fields, target, fieldName, transaction.locale);\n if (value === undefined) {\n state.absentFields.add(fieldName);\n continue;\n }\n // Noted before `skipUnchanged` can skip the write: the reveal ledger is\n // its own record, and a binding whose write is unchanged since the last\n // one that landed may still be the field whose reveal was superseded.\n if (deps.revealEditedField) state.revealLedger.note(transaction, target, value);\n if (!isCurrent()) return;\n const transformed = transformForBinding(deps, target, value, data.fields, isCurrent);\n if (!isCurrent()) return;\n // A binding renders its own value *and* the sibling fields bound to\n // href/src/alt, so its identity must cover them: otherwise an edit to\n // the sibling alone looks unchanged and the link or image stays stale.\n const identity = trackIdentity\n ? bindingIdentity(target, transformed, data.fields, transaction.locale)\n : undefined;\n const last = state.lastAppliedIdentity.get(target.element);\n if (\n !transaction.forceRender &&\n deps.skipUnchanged &&\n identity !== undefined &&\n last === identity &&\n !transaction.invalidated.has(fieldName)\n ) {\n state.skippedUnchangedCount += 1;\n continue;\n }\n const update: ScheduledUpdate = {\n target,\n value: transformed,\n allFields: data.fields,\n revision: transaction.revision,\n data,\n valueIdentity: identity,\n };\n deps.scheduler.schedule(update);\n scheduled += 1;\n }\n }\n diagnoseOrphanFields(\n { cache: deps.cache, warned: state.warnedOrphanFields, warn: deps.warn },\n data.fields,\n transaction.locale,\n ownerKeys,\n );\n if (plan !== null && plan.boundaries.length > 0) {\n transaction.pendingFragments = plan.boundaries.length;\n void this.strategies.runFragments(transaction, data, plan);\n }\n // Nothing to flush is still this revision reaching its end — and its reveal\n // point: every write may be unchanged while the reveal is still owed.\n if (scheduled === 0 && transaction.pendingFragments === 0) {\n state.complete(transaction);\n this.revealPending(transaction);\n }\n }\n\n /**\n * A server render — the route, or a fragment boundary — replaced markup\n * without the stamps a guess lives by; look for the baseline's guesses\n * again, and for nothing else (ADR 0014).\n */\n private restoreGuesses(transaction: UpdateTransaction, data: PayloadLivePreviewData): void {\n const { deps, state } = this;\n if (deps.autoBind === 'off' || state.autoBindGuesses === null) return;\n // Nothing reaches this in the lean build, which renders no route and no\n // fragment. A folded branch, not an early return: esbuild drops the branch\n // before linking and a statement after `return` only after it, and the\n // search's module was in the lean artifact until the guard took this shape.\n if (!(typeof __LEAN_BUILD__ !== 'undefined' && __LEAN_BUILD__)) {\n const scope = this.ownerKeysForUpdate(transaction, data.fields);\n restoreUniqueBindings(deps, state, data.fields, transaction.locale, scope);\n }\n }\n\n /** Owner keys this update may address; `false` when scoping is off, `null` when the message names no document. */\n private ownerKeysForUpdate(\n transaction: UpdateTransaction,\n fields: Record<string, unknown>,\n ): readonly string[] | null | false {\n const { deps, state } = this;\n if (!deps.scopeBindingsByOwner) return false;\n const { message } = transaction;\n const keys = messageOwnerKeys({\n globalSlug: typeof message.globalSlug === 'string' ? message.globalSlug : undefined,\n collectionSlug:\n typeof message.collectionSlug === 'string' ? message.collectionSlug : undefined,\n documentId: readDocumentId(fields),\n });\n if (keys === null && !state.warnedUnattributableMessage) {\n state.warnedUnattributableMessage = true;\n deps.warn(\n '[live-preview] LP0202: scopeBindingsByOwner: update names no document; nothing applied',\n );\n }\n return keys;\n }\n\n /** Scheduler callback after every flush, including one that applied nothing. */\n onFlush(stats: FlushStats): void {\n const { deps, state } = this;\n state.lastFlush = stats;\n if (stats.deferred > 0 && !state.warnedVisibilityGate) {\n state.warnedVisibilityGate = true;\n deps.warn(\n `[live-preview] LP0301: visibility gate held ${String(stats.deferred)} off-screen update(s) until scrolled into view; see visibilityGateThreshold`,\n );\n }\n const { revision, data } = stats;\n if (revision === undefined) return;\n const transaction = state.activeUpdate;\n if (\n transaction === null ||\n !state.isCurrent(transaction) ||\n !sameRevision(transaction.revision, revision)\n ) {\n return;\n }\n if (transaction.pendingFragments === 0) state.complete(transaction);\n const isCurrent = (): boolean =>\n state.isCurrent(transaction) && sameRevision(transaction.revision, revision);\n // Reveal before the applied check: the edited element may be exactly the\n // off-screen one the visibility gate deferred, and scrolling to it is what replays it.\n this.revealPending(transaction);\n if (!isCurrent()) return;\n // Before the applied check, because a flush that applied nothing is exactly\n // the one whose every renderer refused its value.\n const unfaithful = state.unfaithfulPatches;\n if (unfaithful.length > 0) {\n state.unfaithfulPatches = [];\n if (data !== undefined) this.strategies.escalateUnfaithful(transaction, data, unfaithful);\n if (!isCurrent()) return;\n }\n if (stats.applied === 0 || data === undefined) return;\n deps.a11y?.announceUpdate(stats.applied);\n if (!isCurrent()) return;\n dispatchIslandUpdate(deps.cache.islands, {\n fields: data.fields,\n revision: revision.revision,\n receivedAt: transaction.receivedAt,\n locale: transaction.locale,\n });\n if (!isCurrent() || deps.emitter.listenerCount('afterUpdate') === 0) return;\n void deps.emitter.emitWhile(\n 'afterUpdate',\n {\n data,\n updatedCount: stats.applied,\n durationMs: stats.durationMs,\n revision: revision.revision,\n receivedAt: transaction.receivedAt,\n source: 'patch',\n },\n isCurrent,\n );\n }\n\n /**\n * Reveal the binding this revision marked, once. Called from the patch flush\n * and again once fragments land, because only one of the two runs for any\n * given field, and a fragment-rendered element is in place only afterwards.\n */\n revealPending(transaction: UpdateTransaction): void {\n const target = this.state.revealLedger.commit(transaction);\n if (target === undefined) return;\n try {\n this.revealBinding(target);\n } catch (error) {\n this.deps.log('reveal', error);\n }\n }\n\n /**\n * Scroll one field's bound element into view; the admin-focus path (tier 2)\n * names a field, so it takes the first binding — a focus message carries no\n * document identity to choose between several.\n */\n revealField(fieldName: string): 'revealed' | 'already-visible' | 'skipped-same' | 'no-element' {\n const target = this.deps.cache.get(fieldName)?.[0];\n if (target === undefined) return 'no-element';\n return this.revealBinding(target);\n }\n\n private revealBinding(\n target: CachedElement,\n ): 'revealed' | 'already-visible' | 'skipped-same' | 'no-element' {\n const { element } = target;\n const win = element.ownerDocument.defaultView as RevealWindow | null;\n if (win === null) return 'no-element';\n // Keyed by document as well as field: two documents on one page have their\n // own `title`, and revealing one must not count as revealing the other.\n const key = `${target.owner ?? ''} ${target.fieldName}`;\n return this.state.revealer.reveal(key, element, win);\n }\n}\n","/**\n * The strategy runner the lean profile gets instead of the real one: it plans\n * nothing, renders nothing, and says so once per feature (LP0104). Its purpose\n * is that the pipeline needs no branch of its own — it holds a runner either\n * way, and the profile decides which.\n *\n * Because this module names the real runner only as a type, the lean build\n * drops that file and everything only it referenced: the morph, the fragment\n * protocol client's server half, and the route refresh.\n */\n\nimport { reportUnboundChange } from './fidelity';\nimport { reportOmittedFeature } from './profile';\nimport type { StrategyRunner } from './strategy-runner';\nimport { warnFragmentFallback, warnUnsupportedStrategy } from './strategy-warnings';\nimport type { RuntimeDeps, RuntimeState, UpdateTransaction } from './runtime-state';\nimport { unboundChangedFields, type OwnerScope } from './unbound-fields';\nimport type { CachedElement } from './types';\n\n/** What `UpdatePipeline` calls on a runner; both profiles satisfy it. */\nexport type StrategyRunnerLike = Pick<\n StrategyRunner,\n | 'planFragments'\n | 'escalateUnfaithful'\n | 'hasUnboundChange'\n | 'hasRouteBinding'\n | 'runFragments'\n | 'refreshRoute'\n | 'warnFragmentFallback'\n | 'warnUnsupportedStrategy'\n>;\n\nexport function createLeanStrategyRunner(\n deps: RuntimeDeps,\n state: RuntimeState,\n): StrategyRunnerLike {\n return {\n planFragments: (): null => null,\n // Nothing to escalate to. The pipeline still drains its queue, so a page\n // that keeps producing findings does not keep producing entries.\n escalateUnfaithful: (): void => undefined,\n // Nothing here to escalate to, and the finding is still worth recording:\n // a page that changes a field it does not bind is the page\n // `inspect().fidelity` is read on, and `escalated` staying 0 beside it is\n // the truth about this profile rather than silence about the change.\n hasUnboundChange: (transaction: UpdateTransaction, ownerKeys: OwnerScope): boolean => {\n if (transaction.baseline) return false;\n const unbound = unboundChangedFields(\n deps.cache,\n transaction.touched,\n transaction.locale,\n ownerKeys,\n );\n for (const fieldName of unbound) reportUnboundChange(state, fieldName);\n return false;\n },\n hasRouteBinding: (): boolean => false,\n runFragments: (): Promise<void> => Promise.resolve(),\n // A page that carries a route prelude anyway (it can be injected by hand)\n // still gets no refresh here: this runtime has no code for one.\n refreshRoute: (): Promise<void> => {\n reportOmittedFeature('route refreshes');\n return Promise.resolve();\n },\n warnFragmentFallback: (target: CachedElement): void => {\n reportOmittedFeature('server-rendered fragments');\n warnFragmentFallback(deps, state, target);\n },\n warnUnsupportedStrategy: (target: CachedElement): void => {\n warnUnsupportedStrategy(deps, state, target);\n },\n };\n}\n","/**\n * Debounce, frame batching and off-screen replay for scheduled writes. The\n * first write of a quiet phase does not wait for the window: it goes out on the\n * next frame and opens the window that batches the rest of the burst, so an\n * isolated keystroke costs a frame instead of a whole debounce. The scheduler\n * never touches the DOM; the injected `apply` callback does.\n */\n\nimport type { PayloadLivePreviewData } from '@/types/payload-protocol';\nimport { usesNoWriteOutcome } from './internal-outcome';\nimport { type MessageRevision, sameRevision } from './message-bus';\nimport type { CachedElement } from './types';\n\nexport interface ScheduledUpdate {\n readonly target: CachedElement;\n readonly value: unknown;\n readonly allFields: Record<string, unknown>;\n /** Revision revision; runtime-produced entries always carry one. */\n readonly revision?: MessageRevision | undefined;\n readonly data?: PayloadLivePreviewData | undefined;\n /** `valueIdentity(value)`, computed once by the pipeline for skip and reveal. */\n readonly valueIdentity?: string | undefined;\n}\n\nexport type ApplyUpdate = (update: ScheduledUpdate) => void;\n\nexport interface UpdateSchedulerOptions {\n /** Debounce window in ms; the write that opens it does not wait for it. Default 50. */\n readonly debounceMs?: number;\n /** Longest a flush may be postponed by continuous scheduling. Default `4 * debounceMs`. */\n readonly maxWaitMs?: number;\n /** Deferred writes replay when the host reports the element visible via `notifyVisible()`. */\n readonly isVisible: (element: Element) => boolean;\n /** Apply every write immediately regardless of visibility. Default `false`. */\n readonly disableVisibilityGate?: boolean;\n /** Cached-element count above which the gate activates. Default 50. */\n readonly visibilityGateThreshold?: number;\n readonly getCacheSize: () => number;\n readonly onFlush?: (stats: FlushStats) => void;\n /** Frame scheduler; defaults to `requestAnimationFrame`. Tests inject a synchronous one. */\n readonly scheduleFrame?: (callback: FrameRequestCallback) => number;\n readonly cancelFrame?: (handle: number) => void;\n}\n\nexport interface FlushStats {\n readonly applied: number;\n /** Field names applied, in order; `applied` alone cannot say which binding stayed stale. */\n readonly appliedFields: readonly string[];\n readonly deferred: number;\n readonly durationMs: number;\n readonly revision?: MessageRevision;\n readonly data?: PayloadLivePreviewData;\n}\n\n/** Exported so the merge behind a burst of writes can share the window that batches them. */\nexport const DEFAULT_DEBOUNCE_MS = 50;\n/** Exported so `pll doctor` can prove its own copy of the number has not drifted. */\nexport const DEFAULT_VISIBILITY_THRESHOLD = 50;\n\ninterface BufferEntry {\n target: CachedElement;\n value: unknown;\n allFields: Record<string, unknown>;\n revision: MessageRevision | undefined;\n data: PayloadLivePreviewData | undefined;\n valueIdentity: string | undefined;\n}\n\nexport class UpdateScheduler {\n private readonly apply: ApplyUpdate;\n private readonly debounceMs: number;\n private readonly maxWaitMs: number;\n private readonly isVisible: (element: Element) => boolean;\n private readonly gateThresholdValue: number;\n private readonly gateDisabled: boolean;\n private readonly getCacheSize: () => number;\n private readonly onFlush: ((stats: FlushStats) => void) | undefined;\n private readonly scheduleFrame: (callback: FrameRequestCallback) => number;\n private readonly cancelFrame: (handle: number) => void;\n private pending = new Map<Element, BufferEntry>();\n private readonly replay = new Map<Element, BufferEntry>();\n private readonly activeFlushes = new Set<Map<Element, BufferEntry>>();\n private debounceTimer: ReturnType<typeof setTimeout> | null = null;\n private debounceToken = 0;\n private deadlineTimer: ReturnType<typeof setTimeout> | null = null;\n private frameHandle: number | null = null;\n private frameToken = 0;\n /** End of the window the leading write opened; inside it a write waits for the debounce. */\n private windowUntil = 0;\n private activeRevision: MessageRevision | null = null;\n private activeRevisionCancelled = false;\n\n constructor(apply: ApplyUpdate, options: UpdateSchedulerOptions) {\n this.apply = apply;\n this.debounceMs = options.debounceMs ?? DEFAULT_DEBOUNCE_MS;\n this.maxWaitMs = options.maxWaitMs ?? this.debounceMs * 4;\n this.isVisible = options.isVisible;\n this.gateThresholdValue = options.visibilityGateThreshold ?? DEFAULT_VISIBILITY_THRESHOLD;\n this.gateDisabled = options.disableVisibilityGate ?? false;\n this.getCacheSize = options.getCacheSize;\n this.onFlush = options.onFlush;\n this.scheduleFrame =\n options.scheduleFrame ??\n (typeof requestAnimationFrame === 'function'\n ? requestAnimationFrame.bind(globalThis)\n : (callback) =>\n setTimeout(() => {\n callback(performance.now());\n }, 0) as unknown as number);\n this.cancelFrame =\n options.cancelFrame ??\n (typeof cancelAnimationFrame === 'function'\n ? cancelAnimationFrame.bind(globalThis)\n : (handle) => {\n clearTimeout(handle as unknown as ReturnType<typeof setTimeout>);\n });\n }\n\n /** Queue a write; a later write for the same element replaces it until the flush. */\n schedule(update: ScheduledUpdate): void {\n if (update.revision !== undefined) {\n if (this.activeRevisionCancelled) return;\n if (this.activeRevision === null || !sameRevision(update.revision, this.activeRevision)) {\n return;\n }\n }\n const existing = this.pending.get(update.target.element);\n if (existing) {\n existing.value = update.value;\n existing.allFields = update.allFields;\n existing.revision = update.revision;\n existing.data = update.data;\n existing.valueIdentity = update.valueIdentity;\n } else {\n this.pending.set(update.target.element, {\n target: update.target,\n value: update.value,\n allFields: update.allFields,\n revision: update.revision,\n data: update.data,\n valueIdentity: update.valueIdentity,\n });\n }\n this.armDebounce();\n }\n\n /**\n * Make `revision` the sole revision allowed to schedule, flush or replay.\n * Older buffered work is dropped even if the new revision is later cancelled.\n */\n acceptRevision(revision: MessageRevision): void {\n if (this.activeRevision !== null && sameRevision(revision, this.activeRevision)) return;\n if (this.activeRevision !== null && compareRevision(revision, this.activeRevision) < 0) return;\n this.cancelScheduledWork();\n this.clearWork();\n this.activeRevision = revision;\n this.activeRevisionCancelled = false;\n }\n\n /** Cancel buffered work for exactly one revision without reviving its predecessor. */\n cancelRevision(revision: MessageRevision): void {\n if (this.activeRevision === null || !sameRevision(revision, this.activeRevision)) return;\n this.cancelScheduledWork();\n this.clearWork();\n this.activeRevisionCancelled = true;\n }\n\n /** Flush immediately, bypassing the debounce. */\n flushNow(): FlushStats {\n this.cancelScheduledWork();\n return this.flush();\n }\n\n /** Apply the buffered value for an element that scrolled into view. */\n notifyVisible(element: Element): void {\n const entry = this.replay.get(element);\n if (!entry) return;\n this.replay.delete(element);\n if (!this.isCurrent(entry)) return;\n const t0 = performance.now();\n const applied = this.didApply(entry) ? 1 : 0;\n this.onFlush?.(\n this.statsFor(\n entry,\n applied,\n 0,\n performance.now() - t0,\n applied === 1 ? [entry.target.fieldName] : [],\n ),\n );\n }\n\n /**\n * Point buffered work at a rebuilt cache entry for the same element and\n * field. A different field or locale is a different binding: drop the work.\n */\n retarget(target: CachedElement): void {\n this.retargetBuffer(this.pending, target);\n this.retargetBuffer(this.replay, target);\n for (const flush of this.activeFlushes) this.retargetBuffer(flush, target);\n }\n\n forget(element: Element): void {\n this.pending.delete(element);\n this.replay.delete(element);\n for (const flush of this.activeFlushes) flush.delete(element);\n }\n\n /** Cancel timers and drop buffered state without draining it. */\n destroy(): void {\n this.cancelScheduledWork();\n this.clearWork();\n this.activeRevision = null;\n this.activeRevisionCancelled = false;\n // A restarted scheduler is a quiet page again, not the tail of a burst.\n this.windowUntil = 0;\n }\n\n get pendingCount(): number {\n return this.pending.size;\n }\n\n get replayCount(): number {\n return this.replay.size;\n }\n\n get gateThreshold(): number {\n return this.gateThresholdValue;\n }\n\n get gateActive(): boolean {\n return !this.gateDisabled && this.getCacheSize() > this.gateThresholdValue;\n }\n\n private armDebounce(): void {\n const now = Date.now();\n const opensTheWindow = now >= this.windowUntil;\n this.windowUntil = now + this.debounceMs;\n // The debounce coalesces a burst, and the write that opens one is not yet a\n // burst: it costs a frame, and the window it opens batches what follows.\n // With the merge gone from the common path (see `MergeNeed`), that frame is\n // the whole distance between a keystroke and the page.\n if (opensTheWindow) {\n this.requestFrame();\n return;\n }\n const token = (this.debounceToken += 1);\n const timer = this.debounceTimer;\n this.debounceTimer = null;\n if (timer !== null) clearTimeout(timer);\n // clearTimeout is a host boundary; a reentrant schedule owns a newer token.\n if (this.debounceToken !== token) return;\n const next = setTimeout(() => {\n if (this.debounceToken !== token) return;\n this.debounceTimer = null;\n // The window a leading write opened is usually already empty when it\n // closes; flushing then would report a write nobody made.\n if (this.pending.size > 0) this.requestFrame();\n }, this.debounceMs);\n if (this.debounceToken === token) this.debounceTimer = next;\n // Continuous scheduling (key repeat) must not postpone the flush forever.\n if (this.deadlineTimer === null && this.maxWaitMs > this.debounceMs) {\n this.deadlineTimer = setTimeout(() => {\n this.deadlineTimer = null;\n if (this.pending.size > 0) this.requestFrame();\n }, this.maxWaitMs);\n }\n }\n\n private requestFrame(): void {\n const token = (this.frameToken += 1);\n const handle = this.frameHandle;\n this.frameHandle = null;\n if (handle !== null) this.cancelFrame(handle);\n if (this.frameToken !== token) return;\n let completed = false;\n const next = this.scheduleFrame(() => {\n if (this.frameToken !== token) return;\n completed = true;\n this.frameHandle = null;\n this.flush();\n });\n // An injected scheduler may run the callback synchronously; never publish a spent handle.\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n if (!completed && this.frameToken === token) this.frameHandle = next;\n }\n\n private flush(): FlushStats {\n const t0 = performance.now();\n this.clearDeadline();\n const gateActive = this.gateActive;\n const pending = this.pending;\n this.pending = new Map();\n let applied = 0;\n const appliedFields: string[] = [];\n let deferred = 0;\n let batchEntry: BufferEntry | undefined;\n this.activeFlushes.add(pending);\n try {\n for (const entry of pending.values()) {\n if (!this.isCurrent(entry)) continue;\n const visible = !gateActive || this.isVisible(entry.target.element);\n // The visibility callback is consumer code and may change the revision.\n if (!this.isCurrent(entry)) continue;\n batchEntry ??= entry;\n if (!visible) {\n this.replay.set(entry.target.element, entry);\n deferred += 1;\n continue;\n }\n this.replay.delete(entry.target.element);\n if (this.didApply(entry)) {\n applied += 1;\n appliedFields.push(entry.target.fieldName);\n }\n }\n } finally {\n this.activeFlushes.delete(pending);\n }\n const stats = this.statsFor(\n batchEntry,\n applied,\n deferred,\n performance.now() - t0,\n appliedFields,\n );\n this.onFlush?.(stats);\n return stats;\n }\n\n private isCurrent(entry: BufferEntry): boolean {\n return (\n entry.revision === undefined ||\n (!this.activeRevisionCancelled &&\n this.activeRevision !== null &&\n sameRevision(entry.revision, this.activeRevision))\n );\n }\n\n private didApply(entry: BufferEntry): boolean {\n // Only a runtime-marked callback may report exact `false` as \"no write\".\n // eslint-disable-next-line @typescript-eslint/no-confusing-void-expression\n const outcome: unknown = this.apply(entry);\n return outcome !== false || !usesNoWriteOutcome(this.apply);\n }\n\n private retargetBuffer(buffer: Map<Element, BufferEntry>, target: CachedElement): void {\n const entry = buffer.get(target.element);\n if (entry === undefined) return;\n if (entry.target.fieldName !== target.fieldName || entry.target.locale !== target.locale) {\n buffer.delete(target.element);\n return;\n }\n entry.target = target;\n }\n\n private clearWork(): void {\n this.pending.clear();\n this.replay.clear();\n for (const flush of this.activeFlushes) flush.clear();\n }\n\n private statsFor(\n entry: BufferEntry | undefined,\n applied: number,\n deferred: number,\n durationMs: number,\n appliedFields: readonly string[],\n ): FlushStats {\n return {\n applied,\n appliedFields,\n deferred,\n durationMs,\n ...(entry?.revision !== undefined ? { revision: entry.revision } : {}),\n ...(entry?.data !== undefined ? { data: entry.data } : {}),\n };\n }\n\n private clearDeadline(): void {\n if (this.deadlineTimer === null) return;\n clearTimeout(this.deadlineTimer);\n this.deadlineTimer = null;\n }\n\n private cancelScheduledWork(): void {\n const debounceTimer = this.debounceTimer;\n const frameHandle = this.frameHandle;\n // Revoke tokens before calling host cancellation, so a hook that\n // schedules newer work is not clobbered by this older cleanup.\n this.debounceToken += 1;\n this.frameToken += 1;\n this.debounceTimer = null;\n this.frameHandle = null;\n this.clearDeadline();\n if (debounceTimer !== null) clearTimeout(debounceTimer);\n if (frameHandle !== null) this.cancelFrame(frameHandle);\n }\n}\n\nfunction compareRevision(a: MessageRevision, b: MessageRevision): number {\n if (a.generation !== b.generation) return a.generation - b.generation;\n return a.revision - b.revision;\n}\n","/**\n * `LivePreviewRuntime` builds the primitives, owns their lifecycle and hands\n * accepted messages to the update pipeline. It never speaks postMessage\n * itself and never walks the DOM during an update. See ADR 0004.\n */\n\nimport { createA11y, defaultSendReady } from './runtime-wiring';\nimport { BindingWriter } from './binding-writer';\nimport { ElementCache } from './cache';\nimport { DataMerger } from './data-merger';\nimport type { DiagnosticCode } from './diagnostic-codes';\nimport { isolateDiagnostic, noopDiagnostic, safeConsoleWarn } from './diagnostics';\nimport { resolveUnfaithfulPatchMode } from './fidelity';\nimport { buildInspection } from './inspection/snapshot';\nimport type { LivePreviewInspection } from './inspection/types';\nimport { markNoWriteCallback } from './internal-outcome';\nimport { isInsideIsland } from './islands';\nimport { MessageBus } from './message-bus';\nimport { ObserverManager } from './observers';\nimport type { ProtocolNegotiation } from './protocol-version';\nimport type { RuntimeOptions } from './runtime-options';\nimport { RuntimeState, type RuntimeDeps } from './runtime-state';\nimport { startWhenReady, type StartupHost } from './startup';\nimport { ConnectionState, HeartbeatTimer } from './state';\nimport type { CachedElement } from './types';\nimport { UpdatePipeline } from './update-pipeline';\nimport { DEFAULT_DEBOUNCE_MS, UpdateScheduler } from './update-scheduler';\n\nexport type { RuntimeOptions } from './runtime-options';\nexport { resolveFieldValue } from './field-value';\n\n/** Re-broadcast `ready` a few times to absorb admin-side init latency. */\nconst READY_RETRY_DELAYS_MS = [0, 500, 1000, 2000] as const;\n\nexport class LivePreviewRuntime {\n private readonly deps: RuntimeDeps;\n private readonly state = new RuntimeState();\n private readonly pipeline: UpdatePipeline;\n private readonly writer: BindingWriter;\n /** Watches `<html>` for a swapped `<body>` so the observers follow it. */\n private rootSentinel: MutationObserver | null = null;\n private observedRoot: Node | null = null;\n\n constructor(options: RuntimeOptions) {\n const { emitter, renderers } = options;\n const log = options.log === undefined ? noopDiagnostic : isolateDiagnostic(options.log);\n const warn = options.warn === undefined ? safeConsoleWarn : isolateDiagnostic(options.warn);\n const root = options.root ?? (typeof document !== 'undefined' ? document : undefined);\n // Without a document there is nothing to bind. Failing here names the\n // option; the alternative is a TypeError from the first DOM read in start().\n if (root === undefined) throw new Error('LivePreviewRuntime: no document; pass options.root');\n // Bindings inside a hydrated island are the island's business (ADR 0008 §4).\n const cache = new ElementCache({ filter: (element) => !isInsideIsland(element) });\n const observers = new ObserverManager(\n {\n onStructuralChange: () => {\n this.rebuildCache();\n },\n onVisibilityChange: (element, visible) => {\n if (visible) scheduler.notifyVisible(element);\n },\n },\n options.intersectionRootMargin !== undefined\n ? { intersectionRootMargin: options.intersectionRootMargin }\n : {},\n );\n const scheduler = new UpdateScheduler(\n markNoWriteCallback((update) => this.writer.apply(update)),\n {\n ...(options.debounceMs !== undefined ? { debounceMs: options.debounceMs } : {}),\n ...(options.disableVisibilityGate !== undefined\n ? { disableVisibilityGate: options.disableVisibilityGate }\n : {}),\n ...(options.visibilityGateThreshold !== undefined\n ? { visibilityGateThreshold: options.visibilityGateThreshold }\n : {}),\n isVisible: (element) => observers.isVisible(element),\n getCacheSize: () => cache.elementCount,\n onFlush: (stats) => {\n this.pipeline.onFlush(stats);\n },\n },\n );\n const bus = new MessageBus(options.originMatcher, {\n onUpdate: (message, origin, revision) => {\n this.pipeline.handleUpdate(message, origin, revision);\n },\n onDocumentEvent: () => {\n this.state.protocol.observe(['document-events'], log);\n void emitter.emit('documentSave', { timestamp: Date.now() });\n },\n onFocusField: (field) => {\n if (this.deps.revealEditedField) this.pipeline.revealField(field);\n },\n onInvalid: (reason, origin) => {\n if (reason === 'token') {\n const error = new Error(`Preview token rejected (origin: ${origin})`);\n void emitter.emit('error', { error, context: 'token', code: 'LP0502' });\n }\n // A trusted origin sending a shape this runtime does not know is\n // protocol drift, not an attack — and the only place it is visible is\n // here, so it is said out loud once rather than only under `debug`.\n if ((reason === 'shape' || reason === 'type') && !this.state.warnedProtocolShape) {\n this.state.warnedProtocolShape = true;\n warn(\n `[live-preview] LP0503: ${origin} posted a message this runtime does not recognise ` +\n `(${reason === 'type' ? 'unknown message type' : 'unexpected shape'}); it was ` +\n 'ignored. A newer Payload or a custom sender: check that the versions match.',\n );\n }\n // The one refusal reason whose default changed in 2.0. A page whose\n // admin posts from somewhere other than the window that framed or\n // opened it simply stops updating, and the cause is invisible unless\n // `debug` happens to be on — so it is said once, like LP0503.\n if (reason === 'source' && !this.state.warnedForeignSource) {\n this.state.warnedForeignSource = true;\n warn(\n `[live-preview] LP0501: a message from ${origin} was ignored because it did not come ` +\n 'from the window that framed or opened this page. `eventSourcePolicy` is ' +\n \"'parent-or-opener' by default since 2.0, where 1.x accepted any window on a \" +\n \"trusted origin. Set `eventSourcePolicy: 'any'` if the admin posts from elsewhere.\",\n );\n }\n log('LP0501 message rejected:', reason, origin);\n },\n ...(options.validateToken !== undefined ? { validateToken: options.validateToken } : {}),\n ...(options.eventSourcePolicy !== undefined\n ? { sourcePolicy: options.eventSourcePolicy }\n : {}),\n });\n const merge = options.dataMerge;\n this.deps = {\n emitter,\n cache,\n observers,\n scheduler,\n bus,\n connection: new ConnectionState(),\n heartbeat: new HeartbeatTimer({\n ...(options.heartbeatMs !== undefined ? { timeoutMs: options.heartbeatMs } : {}),\n onTimeout: () => {\n this.onHeartbeatTimeout();\n },\n }),\n renderers,\n resolveRenderer: options.resolveRenderer ?? ((fieldType) => renderers[fieldType]),\n transformValue: options.transformValue,\n renderRichText: options.renderRichText,\n sanitizerPolicy: options.sanitizerPolicy,\n root,\n readyTargets:\n typeof options.readyTargets === 'function'\n ? options.readyTargets\n : (\n (targets) => (): readonly string[] =>\n targets\n )(options.readyTargets),\n sendReady: options.sendReady ?? defaultSendReady,\n onHeartbeatTimeout: options.onHeartbeatTimeout,\n log,\n warn,\n a11y: createA11y(options),\n merger:\n merge === undefined\n ? null\n : new DataMerger({\n serverURL: merge.serverURL,\n ...(merge.apiRoute !== undefined ? { apiRoute: merge.apiRoute } : {}),\n ...(merge.depth !== undefined ? { depth: merge.depth } : {}),\n ...(merge.fetchFn !== undefined ? { fetchFn: merge.fetchFn } : {}),\n log,\n }),\n mergeWindowMs: options.debounceMs ?? DEFAULT_DEBOUNCE_MS,\n scopeBindingsByOwner: options.scopeBindingsByOwner === true,\n lockedOrigin: options.lockedOrigin ?? ((): undefined => undefined),\n skipUnchanged: options.skipUnchanged === true,\n dependencies: options.dependencies ?? {},\n strategies: options.strategies ?? {},\n revealEditedField: options.revealEditedField === true,\n onUnfaithfulPatch: resolveUnfaithfulPatchMode(options),\n autoBind: options.autoBind ?? 'off',\n hydration: options.hydration,\n };\n this.writer = new BindingWriter(this.deps, this.state);\n this.pipeline = new UpdatePipeline(this.deps, this.state, () => {\n this.rebuildCache();\n });\n }\n\n /**\n * Build the cache, attach observers and listeners, broadcast `ready`.\n * Returns `false` when already started. While the document is still\n * parsing the real start waits for `DOMContentLoaded`; on a page that\n * declares hydration it then waits for React's first commit as well\n * (ADR 0015), so the first write lands on markup React keeps.\n */\n start(): boolean {\n const { state } = this;\n if (state.isRunning()) return false;\n state.started = true;\n state.suspended = false;\n try {\n startWhenReady(this.startupHost());\n return true;\n } catch (error) {\n this.rollbackFailedStart();\n throw error;\n }\n }\n\n /** The runtime as the startup chain sees it (./startup). */\n private startupHost(): StartupHost {\n const { state, deps } = this;\n return {\n root: deps.root,\n hydration: deps.hydration,\n isRunning: () => state.isRunning(),\n defer: (cancel) => {\n state.deferredStart = cancel;\n },\n later: (step) => {\n state.deferredStart = null;\n try {\n step();\n } catch (error) {\n // start() already returned; roll back and report through the error event.\n this.rollbackFailedStart();\n this.reportError(error, 'startup', 'LP0605');\n }\n },\n hydrated: (hydration) => {\n state.hydration = hydration;\n },\n warn: deps.warn,\n startNow: () => {\n this.startNow();\n },\n };\n }\n\n private startNow(): void {\n const { state, deps } = this;\n if (!state.isRunning()) return;\n const observerRoot: Node | null = isDocumentRoot(deps.root)\n ? readDocumentBody(deps.root)\n : deps.root;\n if (observerRoot === null) throw new Error('LivePreviewRuntime: document.body unavailable');\n deps.observers.start(observerRoot);\n this.observedRoot = observerRoot;\n this.watchRootReplacement();\n // Observers first: the cache scan registers its elements with them.\n this.buildCacheAndObserve();\n if (!state.isRunning()) return;\n deps.bus.attach();\n void deps.emitter.emitWhile('init', { timestamp: Date.now() }, () => state.isRunning());\n if (!state.isRunning()) return;\n for (const delay of READY_RETRY_DELAYS_MS) {\n if (!state.isRunning()) return;\n if (delay === 0) {\n deps.sendReady(deps.readyTargets());\n } else {\n state.readyTimers.push(\n setTimeout(() => {\n if (state.isRunning()) this.sendReadyAfterStart();\n }, delay),\n );\n }\n }\n }\n\n /**\n * Release the message ingress and observers but keep the configuration, so\n * `start()` brings the same instance back — what a back/forward-cache\n * restore needs, since it re-runs no scripts.\n */\n suspend(): boolean {\n if (!this.state.isRunning()) return false;\n const wasConnected = this.release();\n this.state.suspended = true;\n if (wasConnected) {\n void this.deps.emitter.emit('disconnect', { reason: 'unload', timestamp: Date.now() });\n }\n return true;\n }\n\n destroy(): void {\n const { state, deps } = this;\n if (!state.isRunning() && !state.suspended) return;\n const wasConnected = state.isRunning() ? this.release() : false;\n state.suspended = false;\n if (wasConnected) {\n void deps.emitter.emit('disconnect', { reason: 'destroy', timestamp: Date.now() });\n }\n deps.a11y?.detach();\n void deps.emitter.emit('destroy', { timestamp: Date.now() });\n }\n\n /** Invalidate first, then release everything startup may have acquired. */\n private release(): boolean {\n const { state, deps } = this;\n state.activeUpdate = null;\n state.started = false;\n const deferredStart = state.deferredStart;\n state.deferredStart = null;\n if (deferredStart !== null) this.runCleanup(deferredStart);\n for (const handle of state.readyTimers) {\n this.runCleanup(() => {\n clearTimeout(handle);\n });\n }\n state.readyTimers.length = 0;\n this.runCleanup(() => {\n deps.heartbeat.stop();\n });\n this.runCleanup(() => {\n deps.bus.detach();\n });\n state.abortStrategies();\n this.runCleanup(() => {\n this.rootSentinel?.disconnect();\n this.rootSentinel = null;\n this.observedRoot = null;\n });\n this.runCleanup(() => {\n deps.observers.stop();\n });\n this.runCleanup(() => {\n deps.scheduler.destroy();\n });\n this.runCleanup(() => {\n deps.merger?.destroy();\n state.merges.destroy();\n });\n deps.cache.clear();\n return deps.connection.markDisconnected();\n }\n\n private rollbackFailedStart(): void {\n this.release();\n this.runCleanup(() => {\n this.deps.a11y?.detach();\n });\n }\n\n private runCleanup(cleanup: () => void): void {\n try {\n cleanup();\n } catch (error) {\n this.deps.log('cleanup failed:', error);\n }\n }\n\n /** Re-scan the DOM and re-register every binding. */\n refreshCache(): void {\n if (!this.state.isRunning()) return;\n this.state.revealer.reset();\n if (!this.followReplacedRoot()) this.rebuildCache();\n }\n\n /** Some routers swap `document.body` on navigation, leaving observers on a detached node. */\n private watchRootReplacement(): void {\n const { root } = this.deps;\n if (!isDocumentRoot(root) || typeof MutationObserver === 'undefined') return;\n this.rootSentinel?.disconnect();\n this.rootSentinel = new MutationObserver(() => {\n this.followReplacedRoot();\n });\n this.rootSentinel.observe(root.documentElement, { childList: true });\n }\n\n /** Rebind observers and cache to a replaced body; returns whether it did. */\n private followReplacedRoot(): boolean {\n const { root } = this.deps;\n if (!this.state.isRunning() || !isDocumentRoot(root)) return false;\n const body = readDocumentBody(root);\n if (body === null || body === this.observedRoot) return false;\n this.observedRoot = body;\n this.deps.observers.start(body);\n this.rebuildCache();\n return true;\n }\n\n get status(): 'disconnected' | 'connecting' | 'connected' {\n return this.deps.connection.status;\n }\n\n get cache(): ElementCache {\n return this.deps.cache;\n }\n\n get updateCount(): number {\n return this.state.updateCount;\n }\n\n /** Negotiated protocol view, `min(library, remote)`. */\n get protocol(): ProtocolNegotiation {\n return this.state.protocol.negotiation;\n }\n\n /** Point-in-time read of runtime state for diagnosing a preview that is not updating. */\n inspect(): LivePreviewInspection {\n return buildInspection(this.deps, this.state);\n }\n\n private buildCacheAndObserve(): void {\n const { state, deps } = this;\n if (!state.isRunning()) return;\n const stats = deps.cache.buildFromRoot(deps.root);\n deps.log('cache', stats);\n if (!state.isRunning()) return;\n void deps.emitter.emitWhile('cacheRefresh', stats, () => state.isRunning());\n if (!state.isRunning()) return;\n for (const entry of deps.cache.values()) {\n if (!state.isRunning()) return;\n deps.observers.observeElement(entry.element);\n }\n }\n\n private rebuildCache(): void {\n const { state, deps } = this;\n if (!state.isRunning()) return;\n const previous = new Map<Element, CachedElement>();\n for (const entry of deps.cache.values()) {\n previous.set(entry.element, entry);\n deps.observers.unobserveElement(entry.element);\n }\n this.buildCacheAndObserve();\n if (!state.isRunning()) return;\n // Buffered work survives only while the same element is bound to the same field.\n for (const entry of deps.cache.values()) {\n const before = previous.get(entry.element);\n if (before?.fieldName === entry.fieldName) deps.scheduler.retarget(entry);\n else deps.scheduler.forget(entry.element);\n previous.delete(entry.element);\n }\n for (const removed of previous.values()) deps.scheduler.forget(removed.element);\n }\n\n private onHeartbeatTimeout(): void {\n const { state, deps } = this;\n if (!state.isRunning()) return;\n deps.bus.advanceGeneration();\n const active = state.activeUpdate;\n state.activeUpdate = null;\n if (active !== null) deps.scheduler.cancelRevision(active.revision);\n deps.merger?.destroy();\n state.merges.destroy();\n const wasConnected = deps.connection.markDisconnected();\n // Release the origin lock before the disconnect event: a listener may\n // reconnect from another allow-listed origin synchronously.\n try {\n deps.onHeartbeatTimeout?.();\n } catch (error) {\n deps.log('heartbeat:', error);\n }\n if (!state.isRunning()) return;\n if (wasConnected && this.isIdleDisconnected()) {\n deps.a11y?.announceDisconnected();\n void deps.emitter.emitWhile('disconnect', { reason: 'timeout', timestamp: Date.now() }, () =>\n this.isIdleDisconnected(),\n );\n if (!state.isRunning()) return;\n if (this.isIdleDisconnected()) deps.log('connection', 'connected', '→', 'disconnected');\n if (!state.isRunning()) return;\n }\n this.sendReadyAfterStart();\n }\n\n /** Later handshake retries are best-effort and must not escape timer callbacks. */\n private sendReadyAfterStart(): void {\n try {\n this.deps.sendReady(this.deps.readyTargets());\n } catch (error) {\n this.reportError(error, 'ready', 'LP0606');\n }\n }\n\n private reportError(cause: unknown, context: string, code: DiagnosticCode): void {\n const error = cause instanceof Error ? cause : new Error(String(cause));\n void this.deps.emitter.emit('error', { error, context, code });\n }\n\n private isIdleDisconnected(): boolean {\n return (\n this.state.isRunning() &&\n this.deps.connection.status === 'disconnected' &&\n this.state.activeUpdate === null\n );\n }\n}\n\n/** Node types are stable across realms; global constructors are not. */\nfunction isDocumentRoot(root: Document | Element): root is Document {\n return root.nodeType === 9;\n}\n\n/** lib.dom types body as present; a head-time document has none yet. */\nfunction readDocumentBody(root: Document): HTMLElement | null {\n return root.body;\n}\n","/** Assembles the `inspect()` snapshot. Reads state only; sends nothing anywhere. */\n\nimport { VERSION } from '../../version';\nimport { detectProtocolProfile } from '../protocol-profile';\nimport type { RuntimeDeps, RuntimeState } from '../runtime-state';\nimport type { LivePreviewInspection } from './types';\n\nexport function buildInspection(deps: RuntimeDeps, state: RuntimeState): LivePreviewInspection {\n const { cache, scheduler } = deps;\n const negotiation = state.protocol.negotiation;\n const active = state.activeUpdate;\n const flush = state.lastFlush;\n const fieldNames: string[] = [];\n const owners = new Set<string>();\n const guessed: { field: string; matched: string; attribute: string | undefined }[] = [];\n for (const [fieldName, bindings] of cache.entries()) {\n fieldNames.push(fieldName);\n for (const binding of bindings) {\n if (binding.owner !== undefined) owners.add(binding.owner);\n if (binding.guessed !== undefined) {\n guessed.push({\n field: fieldName,\n matched: binding.guessed,\n attribute:\n binding.targetAttribute ?? (binding.element.tagName === 'IMG' ? 'src' : undefined),\n });\n }\n }\n }\n return {\n version: VERSION,\n started: state.started,\n status: deps.connection.status,\n origins: { trusted: [...deps.readyTargets()], locked: deps.lockedOrigin() },\n protocol: {\n ours: negotiation.ours,\n theirs: negotiation.theirs,\n negotiated: negotiation.negotiated,\n capabilities: [...negotiation.capabilities].sort(),\n observed: [...negotiation.observed].sort(),\n profile: detectProtocolProfile(negotiation.observed).name,\n },\n revisions: {\n accepted: state.updateCount,\n superseded: state.supersededCount,\n completed: state.completedCount,\n skippedUnchanged: state.skippedUnchangedCount,\n active: active === null ? undefined : active.revision.revision,\n },\n bindings: {\n elements: cache.elementCount,\n fields: cache.fieldCount,\n fieldNames: fieldNames.sort(),\n absentFields: [...state.absentFields].sort(),\n orphanFields: [...state.warnedOrphanFields].sort(),\n ownerScoped: deps.scopeBindingsByOwner,\n owners: [...owners].sort(),\n guessed: guessed.sort((left, right) => left.field.localeCompare(right.field)),\n autoBind: { mode: deps.autoBind, searchMs: state.autoBindSearchMs },\n },\n route: { handler: deps.strategies.route !== undefined, ...state.routeStats },\n fidelity: {\n mode: deps.onUnfaithfulPatch,\n unfaithful: state.unfaithfulCount,\n escalated: state.escalatedCount,\n fields: [...state.unfaithfulFields].sort(),\n },\n hydration: { mode: deps.hydration ?? 'off', state: state.hydration },\n fragments: {\n handler: deps.strategies.fragment !== undefined,\n inFlight: active?.pendingFragments ?? 0,\n ...state.fragmentStats,\n },\n scheduler: {\n pending: scheduler.pendingCount,\n deferred: scheduler.replayCount,\n visibilityGateThreshold: scheduler.gateThreshold,\n visibilityGateActive: scheduler.gateActive,\n lastFlush:\n flush === null\n ? undefined\n : {\n applied: flush.applied,\n appliedFields: flush.appliedFields,\n deferred: flush.deferred,\n durationMs: flush.durationMs,\n },\n },\n plugins: [],\n renderers: Object.keys(deps.renderers).sort(),\n };\n}\n","/**\n * Per-instance typed emitter: handlers run sequentially in registration order,\n * may be async, and a throwing one is logged and isolated. See ADR 0002.\n */\n\nimport type { EventHandler, LivePreviewEventMap, Unsubscribe } from './types';\nimport { safeConsoleError } from '@core/diagnostics';\n\ntype AnyHandler = EventHandler<unknown>;\n\n// `object`, not `Record<string, unknown>`: interfaces with readonly and\n// exact-optional properties must be usable as maps.\nexport class EventEmitter<TMap extends object = LivePreviewEventMap> {\n readonly #regular = new Map<keyof TMap, Set<AnyHandler>>();\n readonly #once = new Map<keyof TMap, Set<AnyHandler>>();\n\n on<E extends keyof TMap>(event: E, handler: EventHandler<TMap[E]>): Unsubscribe {\n return this.#register(this.#regular, event, handler as AnyHandler);\n }\n\n once<E extends keyof TMap>(event: E, handler: EventHandler<TMap[E]>): Unsubscribe {\n return this.#register(this.#once, event, handler as AnyHandler);\n }\n\n off<E extends keyof TMap>(event: E, handler: EventHandler<TMap[E]>): void {\n this.#remove(this.#regular, event, handler as AnyHandler);\n this.#remove(this.#once, event, handler as AnyHandler);\n }\n\n /** Dispatch to every handler: regular ones first, then `once` handlers. */\n async emit<E extends keyof TMap>(event: E, payload: TMap[E]): Promise<void> {\n await this.#emitSequential(event, payload);\n }\n\n /**\n * Dispatch while `shouldContinue()` holds — checked around every handler, so\n * an obsolete transaction cannot resume across an await.\n * @internal\n */\n async emitWhile<E extends keyof TMap>(\n event: E,\n payload: TMap[E],\n shouldContinue: () => boolean,\n ): Promise<boolean> {\n return this.#emitSequential(event, payload, shouldContinue);\n }\n\n async #emitSequential<E extends keyof TMap>(\n event: E,\n payload: TMap[E],\n shouldContinue?: () => boolean,\n ): Promise<boolean> {\n const eligible = (): boolean => shouldContinue?.() ?? true;\n if (!eligible()) return false;\n const regular = this.#regular.get(event);\n if (regular) {\n for (const handler of [...regular]) {\n if (!eligible()) return false;\n await this.#invoke(handler, payload, event);\n if (!eligible()) return false;\n }\n }\n if (!eligible()) return false;\n const once = this.#once.get(event);\n if (once && once.size > 0) {\n const snapshot = [...once];\n this.#once.delete(event);\n for (const handler of snapshot) {\n if (!eligible()) return false;\n await this.#invoke(handler, payload, event);\n if (!eligible()) return false;\n }\n }\n return eligible();\n }\n\n /** Registered handlers for `event`, `on` and `once` together. */\n listenerCount(event: keyof TMap): number {\n return (this.#regular.get(event)?.size ?? 0) + (this.#once.get(event)?.size ?? 0);\n }\n\n /** Remove every handler, or only those of `event`. */\n removeAllListeners(event?: keyof TMap): void {\n if (event === undefined) {\n this.#regular.clear();\n this.#once.clear();\n return;\n }\n this.#regular.delete(event);\n this.#once.delete(event);\n }\n\n /** Event names with at least one handler. */\n eventNames(): (keyof TMap)[] {\n const names = new Set<keyof TMap>();\n for (const key of this.#regular.keys()) names.add(key);\n for (const key of this.#once.keys()) names.add(key);\n return [...names];\n }\n\n #register(\n bucket: Map<keyof TMap, Set<AnyHandler>>,\n event: keyof TMap,\n handler: AnyHandler,\n ): Unsubscribe {\n let set = bucket.get(event);\n if (!set) {\n set = new Set();\n bucket.set(event, set);\n }\n set.add(handler);\n return () => {\n this.#remove(bucket, event, handler);\n };\n }\n\n #remove(bucket: Map<keyof TMap, Set<AnyHandler>>, event: keyof TMap, handler: AnyHandler): void {\n const set = bucket.get(event);\n if (set === undefined) return;\n set.delete(handler);\n if (set.size === 0) bucket.delete(event);\n }\n\n async #invoke(handler: AnyHandler, payload: unknown, event: keyof TMap): Promise<void> {\n try {\n await handler(payload);\n } catch (err) {\n const label =\n typeof event === 'string' || typeof event === 'number' ? String(event) : '<event>';\n safeConsoleError(`[live-preview] LP0601: handler for \"${label}\" threw:`, err);\n }\n }\n}\n","/**\n * Where the runtime is running: framed, opened, or on a developer's machine.\n * Nothing reads bundler-injected variables; a Vite consumer passes\n * `import.meta.env.X` explicitly (docs/astro.md).\n * @internal\n */\n\nexport function isInIframe(): boolean {\n if (typeof window === 'undefined') return false;\n try {\n return window.self !== window.top;\n } catch {\n // A cross-origin parent throws on the comparison; that is an iframe.\n return true;\n }\n}\n\n/** @internal */\nexport function isInPopup(): boolean {\n if (typeof window === 'undefined') return false;\n return window.opener != null;\n}\n\n/** An iframe or a popup; top-level navigation never starts the preview. @internal */\nexport function isInPreviewContext(): boolean {\n return isInIframe() || isInPopup();\n}\n\n/** Under Node, `NODE_ENV !== 'production'`; in a browser the hostname, which is the only signal a bundle has. @internal */\nexport function isDevMode(): boolean {\n const nodeEnv = readNodeEnv();\n if (nodeEnv !== undefined) return nodeEnv !== 'production';\n if (typeof window !== 'undefined') {\n const host = window.location.hostname;\n return host === 'localhost' || host === '127.0.0.1';\n }\n return false;\n}\n\nfunction readNodeEnv(): string | undefined {\n if (typeof process === 'undefined') return undefined;\n const value = process.env['NODE_ENV'];\n return typeof value === 'string' ? value : undefined;\n}\n","/**\n * Which admin origins the runtime trusts: explicit ones always, the\n * `document.referrer` origin only when none is configured, any localhost port\n * in development. See docs/security.md §1.\n */\n\nimport { isDevMode, isInIframe } from './environment';\n\nconst LOCALHOST_PATTERN = /^https?:\\/\\/(localhost|127\\.0\\.0\\.1)(?::\\d+)?$/i;\nconst VALID_ORIGIN_PATTERN = /^https?:\\/\\/[^/?#\\s]+$/i;\n\n/** Ports the handshake broadcasts to when the localhost pattern is on; matching itself is unrestricted. */\nconst LOCALHOST_HANDSHAKE_PORTS: readonly number[] = [\n 3000, 3001, 3333, 4000, 4321, 5000, 5173, 5174, 8000, 8080, 8888, 9000,\n];\n\nexport interface OriginDetectorOptions {\n /** Explicit origins to trust. Always allowed. */\n readonly additionalOrigins?: readonly string[];\n /** Set to `false` to ignore `document.referrer`. */\n readonly enableReferrerDetection?: boolean;\n /** Set to `false` to ignore the localhost pattern even in development. */\n readonly enableLocalhostMatching?: boolean;\n /** Override dev-mode detection. */\n readonly forceDevMode?: boolean;\n /** Override `document.referrer` for tests. */\n readonly referrer?: string;\n}\n\nconst enum OriginSlot {\n ExplicitOrigins,\n ReferrerOrigin,\n AllowLocalhost,\n ReferrerWasAvailable,\n LockedOrigin,\n}\n\ntype OriginState = [\n explicitOrigins: ReadonlySet<string>,\n referrerOrigin: string | undefined,\n allowLocalhost: boolean,\n referrerWasAvailable: boolean,\n lockedOrigin: string | undefined,\n];\n\n/** The trusted-origin policy: the union of the candidate sources, narrowed to one by `lockOrigin()`. */\nexport class OriginDetector {\n readonly #state: OriginState;\n\n constructor(options: OriginDetectorOptions = {}) {\n const explicit = new Set<string>();\n for (const origin of options.additionalOrigins ?? []) {\n const normalised = normaliseOrigin(origin);\n if (normalised !== undefined) explicit.add(normalised);\n }\n let referrerOrigin: string | undefined;\n if (options.enableReferrerDetection ?? true) {\n const referrer =\n options.referrer ?? (typeof document !== 'undefined' ? document.referrer : '');\n if (referrer.length > 0) {\n try {\n const origin = new URL(referrer).origin;\n if (origin && origin !== 'null') referrerOrigin = origin;\n } catch {\n // opaque referrer\n }\n }\n }\n const allowLocalhost =\n (options.enableLocalhostMatching ?? true) && (options.forceDevMode ?? isDevMode());\n this.#state = [\n explicit,\n referrerOrigin,\n allowLocalhost,\n referrerOrigin !== undefined,\n undefined,\n ];\n }\n\n /** Whether `origin` is trusted: the locked origin alone once locked, otherwise the policy above. */\n matches(origin: string): boolean {\n if (origin.length === 0 || origin === 'null') return false;\n if (this.#state[OriginSlot.LockedOrigin] !== undefined) {\n return origin === this.#state[OriginSlot.LockedOrigin];\n }\n if (this.#state[OriginSlot.ExplicitOrigins].has(origin)) return true;\n // The referrer is a fallback, not a union member: any embedder lands there.\n if (\n this.#state[OriginSlot.ExplicitOrigins].size === 0 &&\n this.#state[OriginSlot.ReferrerOrigin] !== undefined &&\n origin === this.#state[OriginSlot.ReferrerOrigin]\n ) {\n return true;\n }\n if (this.#state[OriginSlot.AllowLocalhost] && LOCALHOST_PATTERN.test(origin)) return true;\n return false;\n }\n\n /** Narrow trust to `origin`; refused (`false`) when it is not currently trusted. */\n lockOrigin(origin: string): boolean {\n if (!this.matches(origin)) return false;\n this.#state[OriginSlot.LockedOrigin] = origin;\n return true;\n }\n\n /** Release the lock (heartbeat timeout) so another allow-listed origin may reconnect. Returns the previous lock. */\n unlockOrigin(): string | undefined {\n const previous = this.#state[OriginSlot.LockedOrigin];\n this.#state[OriginSlot.LockedOrigin] = undefined;\n return previous;\n }\n\n get lockedOrigin(): string | undefined {\n return this.#state[OriginSlot.LockedOrigin];\n }\n\n /** Every origin the `ready` handshake is broadcast to; the localhost pattern expands to the common dev ports. */\n enumerate(): string[] {\n if (this.#state[OriginSlot.LockedOrigin] !== undefined) {\n return [this.#state[OriginSlot.LockedOrigin]];\n }\n const result = new Set<string>(this.#state[OriginSlot.ExplicitOrigins]);\n if (\n this.#state[OriginSlot.ExplicitOrigins].size === 0 &&\n this.#state[OriginSlot.ReferrerOrigin] !== undefined\n ) {\n result.add(this.#state[OriginSlot.ReferrerOrigin]);\n }\n if (this.#state[OriginSlot.AllowLocalhost]) {\n for (const port of LOCALHOST_HANDSHAKE_PORTS) {\n result.add(`http://localhost:${String(port)}`);\n result.add(`http://127.0.0.1:${String(port)}`);\n }\n }\n return [...result];\n }\n\n /** Whether `document.referrer` contributed an origin (absent under `Referrer-Policy: no-referrer`). */\n get referrerWasAvailable(): boolean {\n return this.#state[OriginSlot.ReferrerWasAvailable];\n }\n\n /** Framed, outside development, with no trusted origin at all: the host should warn (LP0101). */\n get isProductionUnconfigured(): boolean {\n if (!isInIframe()) return false;\n if (this.#state[OriginSlot.ExplicitOrigins].size > 0) return false;\n if (this.#state[OriginSlot.AllowLocalhost]) return false;\n if (this.#state[OriginSlot.ReferrerOrigin] !== undefined) return false;\n return true;\n }\n\n /** The referrer is the only trust source, so any framing site may drive the preview (LP0102). */\n get isReferrerOnlyTrust(): boolean {\n if (this.#state[OriginSlot.ExplicitOrigins].size > 0) return false;\n if (this.#state[OriginSlot.AllowLocalhost]) return false;\n return this.#state[OriginSlot.ReferrerOrigin] !== undefined;\n }\n}\n\n/** The canonical `http(s)://host[:port]` form of `value`, or `undefined` when it is not one. */\nexport function normaliseOrigin(value: string): string | undefined {\n const trimmed = value.trim();\n if (trimmed.length === 0) return undefined;\n try {\n const url = new URL(trimmed);\n if (url.protocol !== 'http:' && url.protocol !== 'https:') return undefined;\n if (!VALID_ORIGIN_PATTERN.test(url.origin)) return undefined;\n return url.origin;\n } catch {\n return undefined;\n }\n}\n","/**\n * Registration-local resource scope: every listener, transform, renderer\n * layer and cleanup a plugin registers is staged here until `init` commits\n * and released together, in reverse order, when the plugin goes. See ADR 0005.\n */\n\nimport { observeThenableResult } from '@core/thenable';\nimport type { PluginDisposer } from './types';\n\nexport type ResourceKind = 'transform' | 'renderer' | 'subscription' | 'cleanup';\n\ninterface ScopedResource {\n readonly kind: ResourceKind;\n readonly acquire: (() => PluginDisposer | undefined) | undefined;\n readonly finalize: (() => void) | undefined;\n cleanup: PluginDisposer | undefined;\n disposed: boolean;\n}\n\nexport const noopDisposer: PluginDisposer = () => undefined;\n\nexport class ResourceScope {\n readonly #pluginName: string;\n readonly #log: (...args: unknown[]) => void;\n // Insertion order gives commit/reverse-teardown order; short-lived entries\n // (once listeners) leave immediately instead of accumulating until removal.\n readonly #resources = new Set<ScopedResource>();\n #state: 'staging' | 'committing' | 'active' | 'closed' = 'staging';\n\n constructor(pluginName: string, log: (...args: unknown[]) => void) {\n this.#pluginName = pluginName;\n this.#log = log;\n }\n\n assertOpen(): void {\n if (this.#state === 'closed') {\n throw new Error(`Plugin context for \"${this.#pluginName}\" is no longer active`);\n }\n }\n\n get active(): boolean {\n return this.#state === 'active';\n }\n\n /** Whether a retained context still belongs to this registration. */\n eligible(): boolean {\n return this.#state !== 'closed';\n }\n\n /** Own a resource the plugin itself already acquired. */\n own(cleanup: PluginDisposer): PluginDisposer {\n this.assertOpen();\n return this.#track({\n kind: 'cleanup',\n acquire: undefined,\n finalize: undefined,\n cleanup,\n disposed: false,\n });\n }\n\n /** Stage a manager-owned resource; an active scope acquires it at once. */\n stage(\n kind: ResourceKind,\n acquire: () => PluginDisposer | undefined,\n finalize?: () => void,\n ): PluginDisposer {\n this.assertOpen();\n const resource: ScopedResource = {\n kind,\n acquire,\n finalize,\n cleanup: undefined,\n disposed: false,\n };\n const dispose = this.#track(resource);\n if (this.#state === 'active') {\n try {\n this.#activate(resource);\n } catch (error) {\n this.#dispose(resource);\n throw error;\n }\n }\n return dispose;\n }\n\n /** Live resources by kind, what `inspect().plugins` reports. */\n counts(): Record<ResourceKind, number> {\n const counts: Record<ResourceKind, number> = {\n transform: 0,\n renderer: 0,\n subscription: 0,\n cleanup: 0,\n };\n for (const resource of this.#resources) counts[resource.kind] += 1;\n return counts;\n }\n\n /** Publish every staged resource at once after `init` succeeded. */\n commit(): void {\n if (this.#state !== 'staging') {\n throw new Error(`Plugin context for \"${this.#pluginName}\" cannot be committed`);\n }\n this.#state = 'committing';\n try {\n for (const resource of this.#resources) this.#activate(resource);\n this.#state = 'active';\n } catch (error) {\n this.close();\n throw error;\n }\n }\n\n close(): void {\n if (this.#state === 'closed') return;\n this.#state = 'closed';\n for (const resource of [...this.#resources].reverse()) this.#dispose(resource);\n this.#resources.clear();\n }\n\n #track(resource: ScopedResource): PluginDisposer {\n this.#resources.add(resource);\n return (): void => {\n this.#dispose(resource);\n };\n }\n\n #activate(resource: ScopedResource): void {\n if (resource.disposed || resource.cleanup !== undefined || resource.acquire === undefined) {\n return;\n }\n const cleanup = resource.acquire();\n resource.cleanup = cleanup ?? noopDisposer;\n }\n\n #dispose(resource: ScopedResource): void {\n if (resource.disposed) return;\n resource.disposed = true;\n this.#resources.delete(resource);\n const cleanup = resource.cleanup;\n resource.cleanup = undefined;\n if (cleanup !== undefined) {\n try {\n // A `void` cleanup may still return a thenable; observe it without awaiting.\n const cleanupWithResult: () => unknown = cleanup;\n if (observeThenableResult(cleanupWithResult())) {\n this.#log(\n `plugin \"${this.#pluginName}\" cleanup returned a Promise/thenable; cleanups must be synchronous`,\n );\n }\n } catch (error) {\n this.#log(`plugin \"${this.#pluginName}\" cleanup failed:`, error);\n }\n }\n try {\n resource.finalize?.();\n } catch (error) {\n this.#log(`plugin \"${this.#pluginName}\" cleanup failed:`, error);\n }\n }\n}\n","/**\n * Event facade handed to a plugin: subscriptions are owned by the plugin's\n * scope, emits go to the client's emitter. It implements the emitter surface\n * without extending it, so no unused base emitter is allocated per plugin.\n */\n\nimport type { EventEmitter } from '@events/emitter';\nimport type { EventHandler, LivePreviewEventMap, Unsubscribe } from '@events/types';\nimport { noopDisposer, type ResourceScope } from './resource-scope';\nimport type { PluginEvents } from './types';\n\ninterface OwnedSubscription {\n readonly kind: 'on' | 'once';\n readonly event: keyof LivePreviewEventMap;\n readonly handler: EventHandler<unknown>;\n dispose: Unsubscribe;\n}\n\nexport class ScopedPluginEvents implements PluginEvents {\n readonly #events: EventEmitter;\n readonly #scope: ResourceScope;\n readonly #subscriptions = new Set<OwnedSubscription>();\n\n constructor(events: EventEmitter, scope: ResourceScope) {\n this.#events = events;\n this.#scope = scope;\n }\n\n on<E extends keyof LivePreviewEventMap>(\n event: E,\n handler: EventHandler<LivePreviewEventMap[E]>,\n ): Unsubscribe {\n return this.#subscribe('on', event, handler);\n }\n\n once<E extends keyof LivePreviewEventMap>(\n event: E,\n handler: EventHandler<LivePreviewEventMap[E]>,\n ): Unsubscribe {\n return this.#subscribe('once', event, handler);\n }\n\n off<E extends keyof LivePreviewEventMap>(\n event: E,\n handler: EventHandler<LivePreviewEventMap[E]>,\n ): void {\n const untypedHandler = handler as EventHandler<unknown>;\n for (const subscription of [...this.#subscriptions]) {\n if (subscription.event === event && subscription.handler === untypedHandler) {\n subscription.dispose();\n }\n }\n }\n\n emit<E extends keyof LivePreviewEventMap>(\n event: E,\n payload: LivePreviewEventMap[E],\n ): Promise<void> {\n this.#scope.assertOpen();\n return this.#events.emit(event, payload);\n }\n\n emitWhile<E extends keyof LivePreviewEventMap>(\n event: E,\n payload: LivePreviewEventMap[E],\n shouldContinue: () => boolean,\n ): Promise<boolean> {\n this.#scope.assertOpen();\n return this.#events.emitWhile(event, payload, () => {\n if (!this.#scope.eligible()) return false;\n const callerEligible = shouldContinue();\n // The predicate is plugin code and may close this scope re-entrantly.\n if (!this.#scope.eligible()) return false;\n return callerEligible;\n });\n }\n\n listenerCount(event: keyof LivePreviewEventMap): number {\n let count = 0;\n for (const subscription of this.#subscriptions) {\n if (subscription.event === event) count += 1;\n }\n return count;\n }\n\n removeAllListeners(event?: keyof LivePreviewEventMap): void {\n for (const subscription of [...this.#subscriptions]) {\n if (event === undefined || subscription.event === event) subscription.dispose();\n }\n }\n\n eventNames(): (keyof LivePreviewEventMap)[] {\n const names = new Set<keyof LivePreviewEventMap>();\n for (const subscription of this.#subscriptions) names.add(subscription.event);\n return [...names];\n }\n\n #subscribe<E extends keyof LivePreviewEventMap>(\n kind: 'on' | 'once',\n event: E,\n handler: EventHandler<LivePreviewEventMap[E]>,\n ): Unsubscribe {\n this.#scope.assertOpen();\n\n const untypedHandler = handler as EventHandler<unknown>;\n const existing = [...this.#subscriptions].find(\n (subscription) =>\n subscription.kind === kind &&\n subscription.event === event &&\n subscription.handler === untypedHandler,\n );\n if (existing !== undefined) return existing.dispose;\n\n // A distinct wrapper per scope: two plugins passing the same handler\n // reference must be revocable independently in the Set-based emitter.\n let dispose = noopDisposer;\n let subscriptionActive = true;\n const wrapped: EventHandler<LivePreviewEventMap[E]> = async (payload) => {\n if (!this.#scope.active || !subscriptionActive) return;\n // Mirror the base emitter, which drops a once bucket before dispatch.\n if (kind === 'once') dispose();\n await handler(payload);\n };\n const subscription: OwnedSubscription = {\n kind,\n event,\n handler: untypedHandler,\n dispose: noopDisposer,\n };\n dispose = this.#scope.stage(\n 'subscription',\n () => this.#events[kind](event, wrapped),\n () => {\n subscriptionActive = false;\n this.#subscriptions.delete(subscription);\n },\n );\n subscription.dispose = dispose;\n this.#subscriptions.add(subscription);\n return dispose;\n }\n}\n","/**\n * Per-instance plugin manager. Mutations run through one call-order queue;\n * while a queue-held hook is pending, a requested mutation takes the direct\n * path because that hook may be awaiting it. See ADR 0005.\n */\n\nimport type { FieldRenderer } from '@core/types';\nimport type { PluginInspection } from '@core/inspection/types';\nimport { LIBRARY_PROTOCOL_VERSION } from '@core/protocol-version';\nimport { VERSION } from '@/version';\nimport { incompatibilityOf } from './compat';\nimport { isolateDiagnostic } from '@core/diagnostics';\nimport { observeThenableResult } from '@core/thenable';\nimport type { EventEmitter } from '@events/emitter';\nimport { ResourceScope } from './resource-scope';\nimport { ScopedPluginEvents } from './scoped-events';\nimport type { FieldTransform, LivePreviewPlugin, PluginContext } from './types';\n\nexport interface PluginManagerOptions {\n readonly events: EventEmitter;\n readonly config: Readonly<Record<string, unknown>>;\n /** Add one renderer layer to the host; may return the layer's disposer. */\n readonly registerFieldRenderer: (renderer: FieldRenderer) => void;\n /** Receives transform contract failures for the runtime's `error` event. */\n readonly onTransformError?: (error: Error) => unknown;\n readonly log: (...args: unknown[]) => void;\n}\n\ninterface PluginRegistration {\n readonly plugin: LivePreviewPlugin;\n readonly scope: ResourceScope;\n}\n\ninterface InitializingPluginRegistration {\n readonly scope: ResourceScope;\n cancelled: boolean;\n}\n\ninterface TransformRegistration {\n readonly transform: FieldTransform;\n active: boolean;\n}\n\nfunction isPluginDisposer(value: unknown): value is (() => void) | undefined {\n return typeof value === 'function';\n}\n\nexport class PluginManager {\n readonly #events: EventEmitter;\n readonly #config: Readonly<Record<string, unknown>>;\n // The public callback type is void; the client host returns its layer disposer through it.\n readonly #registerRenderer: (renderer: FieldRenderer) => unknown;\n readonly #onTransformError: ((error: Error) => void) | undefined;\n readonly #log: (...args: unknown[]) => void;\n readonly #plugins = new Map<string, PluginRegistration>();\n readonly #initializing = new Map<string, InitializingPluginRegistration>();\n readonly #teardowns = new Map<string, Promise<void>>();\n readonly #destroying = new Set<string>();\n readonly #transforms = new Map<string, TransformRegistration[]>();\n #mutationQueue: Promise<void> = Promise.resolve();\n // Hooks awaited by the queue entry in flight. Hooks started on the direct\n // path never hold the queue, so they must not open it for others.\n #queuedHooks = 0;\n\n constructor(options: PluginManagerOptions) {\n this.#events = options.events;\n this.#config = options.config;\n this.#registerRenderer = options.registerFieldRenderer;\n this.#log = isolateDiagnostic(options.log);\n const onTransformError = options.onTransformError;\n this.#onTransformError =\n onTransformError === undefined\n ? undefined\n : isolateDiagnostic((...args: unknown[]): unknown => {\n // Private and single-callered: `applyTransforms` normalizes to an\n // Error before it reports one.\n const error = args[0] as Error;\n try {\n return onTransformError(error);\n } catch (reportError) {\n this.#log('transform error reporter failed:', reportError);\n return undefined;\n }\n });\n }\n\n /** Register a plugin transactionally; concurrent mutations run in call order. */\n register(plugin: LivePreviewPlugin): Promise<void> {\n if (this.#queuedHooks > 0) return this.#registerNow(plugin, false);\n return this.#enqueue(() => this.#registerNow(plugin, true));\n }\n\n /** Remove one plugin and every resource its registration created. */\n unregister(name: string): Promise<void> {\n if (this.#queuedHooks > 0) return this.#unregisterNow(name, false);\n return this.#enqueue(async () => {\n await this.#unregisterNow(name, true);\n });\n }\n\n /** Destroy every registration; one failure never strands another. */\n destroyAll(): Promise<void> {\n if (this.#queuedHooks > 0) return this.#destroyAllNow(false);\n return this.#enqueue(async () => {\n await this.#destroyAllNow(true);\n });\n }\n\n /** Apply active transforms in registration order; a failure returns the original value. */\n applyTransforms(\n fieldName: string,\n value: unknown,\n context: { readonly element: Element; readonly allFields: Record<string, unknown> },\n isCurrent?: () => boolean,\n ): unknown {\n const registrations = this.#transforms.get(fieldName);\n if (registrations === undefined || registrations.length === 0) return value;\n\n let result: unknown = value;\n for (const registration of [...registrations]) {\n if (!registration.active) continue;\n const { transform } = registration;\n if (isCurrent?.() === false) return value;\n try {\n result = transform(result, {\n fieldName,\n element: context.element,\n allFields: context.allFields,\n });\n const returnedThenable = observeThenableResult(result);\n // A transform may synchronously let a newer message in; then its\n // result belongs to a superseded revision and is not reported.\n if (isCurrent?.() === false) return value;\n if (returnedThenable) {\n throw new TypeError(\n `Transform for \"${fieldName}\" returned a Promise/thenable; transforms must be synchronous`,\n );\n }\n } catch (error) {\n if (isCurrent?.() === false) return value;\n const normalized = error instanceof Error ? error : new Error(String(error));\n this.#log(`transform for \"${fieldName}\" failed:`, normalized);\n this.#onTransformError?.(normalized);\n return value;\n }\n }\n return result;\n }\n\n list(): readonly string[] {\n return [...this.#plugins.keys()];\n }\n\n /** Every plugin with its state and live registrations (`inspect().plugins`). */\n snapshot(): readonly PluginInspection[] {\n const entries: PluginInspection[] = [];\n const describe = (\n name: string,\n version: string | undefined,\n state: PluginInspection['state'],\n scope: ResourceScope,\n ): PluginInspection => {\n const counts = scope.counts();\n return {\n name,\n version,\n state,\n registrations: {\n transforms: counts.transform,\n renderers: counts.renderer,\n subscriptions: counts.subscription,\n cleanups: counts.cleanup,\n },\n };\n };\n for (const [name, initializing] of this.#initializing) {\n entries.push(describe(name, undefined, 'initializing', initializing.scope));\n }\n for (const [name, registration] of this.#plugins) {\n entries.push(describe(name, registration.plugin.version, 'active', registration.scope));\n }\n // A name with a pending teardown left `#plugins` before the teardown began.\n for (const name of this.#teardowns.keys()) {\n entries.push({\n name,\n version: undefined,\n state: 'tearing-down',\n registrations: { transforms: 0, renderers: 0, subscriptions: 0, cleanups: 0 },\n });\n }\n return entries;\n }\n\n get size(): number {\n return this.#plugins.size;\n }\n\n async #registerNow(plugin: LivePreviewPlugin, queued: boolean): Promise<void> {\n if (\n this.#plugins.has(plugin.name) ||\n this.#initializing.has(plugin.name) ||\n this.#teardowns.has(plugin.name)\n ) {\n this.#log(`plugin \"${plugin.name}\" already registered`);\n return;\n }\n\n const incompatibility = incompatibilityOf(plugin.compat, VERSION, LIBRARY_PROTOCOL_VERSION);\n if (incompatibility !== undefined) {\n this.#refuse(plugin.name, incompatibility);\n return;\n }\n const scope = new ResourceScope(plugin.name, this.#log);\n const context = this.#createContext(plugin.name, scope);\n const initializing: InitializingPluginRegistration = { scope, cancelled: false };\n this.#initializing.set(plugin.name, initializing);\n try {\n await this.#runHook(() => plugin.init(context), queued);\n if (initializing.cancelled) return;\n scope.commit();\n } catch (error) {\n scope.close();\n if (!initializing.cancelled) this.#log(`plugin \"${plugin.name}\" init failed:`, error);\n return;\n } finally {\n if (this.#initializing.get(plugin.name) === initializing) {\n this.#initializing.delete(plugin.name);\n }\n }\n\n this.#plugins.set(plugin.name, { plugin, scope });\n this.#log(`plugin \"${plugin.name}\" registered`);\n }\n\n /** A refused plugin is an integration mistake; it reaches the `error` event, not only the log. */\n #refuse(name: string, reason: string): void {\n const message = `plugin \"${name}\" refused: ${reason}`;\n this.#log(message);\n void this.#events.emit('error', {\n error: new Error(message),\n context: 'plugin',\n code: 'LP0103',\n });\n }\n\n #createContext(pluginName: string, scope: ResourceScope): PluginContext {\n return {\n events: new ScopedPluginEvents(this.#events, scope),\n registerFieldRenderer: (renderer) => {\n scope.stage('renderer', () => {\n const result = this.#registerRenderer(renderer);\n return isPluginDisposer(result) ? result : undefined;\n });\n },\n registerTransform: (fieldName, transform) => {\n const registration: TransformRegistration = { transform, active: false };\n scope.stage('transform', () => {\n registration.active = true;\n const existing = this.#transforms.get(fieldName);\n if (existing === undefined) this.#transforms.set(fieldName, [registration]);\n else existing.push(registration);\n\n return () => {\n registration.active = false;\n const current = this.#transforms.get(fieldName);\n if (current === undefined) return;\n const index = current.indexOf(registration);\n if (index >= 0) current.splice(index, 1);\n if (current.length === 0) this.#transforms.delete(fieldName);\n };\n });\n },\n registerCleanup: (cleanup) => {\n scope.own(cleanup);\n },\n getConfig: () => this.#config,\n log: (...args) => {\n this.#log(`[${pluginName}]`, ...args);\n },\n };\n }\n\n #unregisterNow(name: string, queued: boolean): Promise<void> {\n const initializing = this.#initializing.get(name);\n if (initializing !== undefined) {\n initializing.cancelled = true;\n initializing.scope.close();\n return Promise.resolve();\n }\n\n const existingTeardown = this.#teardowns.get(name);\n if (existingTeardown !== undefined) {\n // A destroy hook removing its own name cannot await the teardown that\n // awaits it; its resources are already revoked, so this is complete.\n if (this.#destroying.has(name)) return Promise.resolve();\n return queued ? this.#holdQueue(existingTeardown) : existingTeardown;\n }\n const registration = this.#plugins.get(name);\n if (registration === undefined) return Promise.resolve();\n\n // Revoke before consumer code runs: a throwing destroy keeps no access,\n // and a same-name registration from inside destroy stays a duplicate.\n this.#plugins.delete(name);\n registration.scope.close();\n const teardown = Promise.resolve().then(() =>\n this.#destroyPlugin(name, registration.plugin, queued),\n );\n this.#teardowns.set(name, teardown);\n void teardown.then(() => {\n if (this.#teardowns.get(name) === teardown) this.#teardowns.delete(name);\n });\n return teardown;\n }\n\n async #destroyPlugin(name: string, plugin: LivePreviewPlugin, queued: boolean): Promise<void> {\n if (plugin.destroy === undefined) return;\n this.#destroying.add(name);\n try {\n await this.#runHook(() => plugin.destroy?.(), queued);\n } catch (error) {\n this.#log(`plugin \"${name}\" destroy failed:`, error);\n } finally {\n this.#destroying.delete(name);\n }\n }\n\n async #destroyAllNow(queued: boolean): Promise<void> {\n for (const initializing of this.#initializing.values()) {\n initializing.cancelled = true;\n initializing.scope.close();\n }\n const names = [...this.#plugins.keys()];\n for (const name of names) await this.#unregisterNow(name, queued);\n }\n\n async #runHook(hook: () => void | Promise<void>, queued: boolean): Promise<void> {\n if (!queued) {\n await hook();\n return;\n }\n await this.#holdQueue(Promise.resolve().then(hook));\n }\n\n async #holdQueue(pending: Promise<void>): Promise<void> {\n this.#queuedHooks += 1;\n try {\n await pending;\n } finally {\n this.#queuedHooks -= 1;\n }\n }\n\n #enqueue(operation: () => void | Promise<void>): Promise<void> {\n const result = this.#mutationQueue.then(operation);\n // Keep the tail usable after an escaped error; the caller still sees it on `result`.\n this.#mutationQueue = result.catch((error: unknown) => {\n this.#log('plugin manager mutation failed:', error);\n });\n return result;\n }\n}\n","/**\n * Plugin compatibility claims. The range grammar is the subset a plugin\n * author writes (`*`, `1.2.3`, `^`, `~`, `>=`, `>`, `<`, `<=`, space-joined\n * conjunctions, `||` alternatives); prerelease tags are ignored.\n */\n\nexport interface PluginCompatibility {\n /** A semver range the runtime's `VERSION` must satisfy, e.g. `>=2.0.0`. */\n readonly runtime?: string;\n /** The highest postMessage protocol version the plugin understands. */\n readonly protocol?: number;\n}\n\ntype Version = readonly [number, number, number];\n\nfunction parseVersion(text: string): Version | undefined {\n const match = /^v?(\\d+)\\.(\\d+)\\.(\\d+)/.exec(text.trim());\n if (match === null) return undefined;\n return [Number(match[1]), Number(match[2]), Number(match[3])];\n}\n\nfunction compare(a: Version, b: Version): number {\n for (let index = 0; index < 3; index += 1) {\n const delta = (a[index] ?? 0) - (b[index] ?? 0);\n if (delta !== 0) return delta;\n }\n return 0;\n}\n\nfunction satisfiesComparator(version: Version, comparator: string): boolean {\n const trimmed = comparator.trim();\n if (trimmed === '' || trimmed === '*') return true;\n const match = /^(\\^|~|>=|<=|>|<|=)?\\s*v?(\\d+)\\.(\\d+)\\.(\\d+)/.exec(trimmed);\n if (match === null) return false;\n const operator = match[1] ?? '=';\n const target: Version = [Number(match[2]), Number(match[3]), Number(match[4])];\n const order = compare(version, target);\n switch (operator) {\n case '=':\n return order === 0;\n case '>':\n return order > 0;\n case '>=':\n return order >= 0;\n case '<':\n return order < 0;\n case '<=':\n return order <= 0;\n case '~':\n return order >= 0 && version[0] === target[0] && version[1] === target[1];\n case '^':\n if (order < 0) return false;\n if (target[0] > 0) return version[0] === target[0];\n if (target[1] > 0) return version[0] === 0 && version[1] === target[1];\n return version[0] === 0 && version[1] === 0 && version[2] === target[2];\n default:\n return false;\n }\n}\n\n/** Whether `version` satisfies `range`; anything unparsable never satisfies. */\nexport function satisfiesRange(version: string, range: string): boolean {\n const parsed = parseVersion(version);\n if (parsed === undefined) return false;\n const alternatives = range.split('||');\n return alternatives.some((alternative) => {\n const comparators = alternative\n .trim()\n .split(/\\s+/)\n .filter((part) => part.length > 0);\n if (comparators.length === 0) return alternative.trim() === '' && range.trim() === '';\n return comparators.every((comparator) => satisfiesComparator(parsed, comparator));\n });\n}\n\n/** Why a plugin was refused, or `undefined` when it fits. */\nexport function incompatibilityOf(\n compat: PluginCompatibility | undefined,\n runtimeVersion: string,\n protocolVersion: number,\n): string | undefined {\n if (compat === undefined) return undefined;\n if (compat.runtime !== undefined && !satisfiesRange(runtimeVersion, compat.runtime)) {\n return `declares runtime ${compat.runtime}, this runtime is ${runtimeVersion}`;\n }\n if (compat.protocol !== undefined) {\n if (!Number.isInteger(compat.protocol) || compat.protocol < 1) {\n return `declares an invalid protocol version ${String(compat.protocol)}`;\n }\n if (compat.protocol < protocolVersion) {\n return `declares protocol ${String(compat.protocol)}, this runtime speaks ${String(protocolVersion)}`;\n }\n }\n return undefined;\n}\n","/**\n * Per-client renderer layers: built-ins are the base, plugin registrations\n * stack above per field type, and removing a layer by identity reveals the\n * one beneath. See ADR 0005.\n */\n\nimport type { FieldRenderer, RendererKey } from '@core/types';\nimport type { PluginDisposer } from './types';\n\ninterface RendererLayer {\n readonly renderer: FieldRenderer;\n}\n\nexport class RendererRegistry {\n readonly #base: Readonly<Record<string, FieldRenderer>>;\n readonly #active: Record<string, FieldRenderer>;\n readonly #layers = new Map<RendererKey, RendererLayer[]>();\n\n constructor(base: Readonly<Record<string, FieldRenderer>>) {\n this.#base = base;\n this.#active = { ...base };\n }\n\n /** Stable live map, retained for the runtime's `renderers` option. */\n get renderers(): Readonly<Record<string, FieldRenderer>> {\n return this.#active;\n }\n\n resolve(fieldType: RendererKey): FieldRenderer | undefined {\n return this.#active[fieldType];\n }\n\n register(renderer: FieldRenderer): PluginDisposer {\n const fieldType = renderer.name;\n const layer: RendererLayer = { renderer };\n const stack = this.#layers.get(fieldType);\n if (stack === undefined) this.#layers.set(fieldType, [layer]);\n else stack.push(layer);\n this.#active[fieldType] = renderer;\n\n let active = true;\n return () => {\n if (!active) return;\n active = false;\n\n const current = this.#layers.get(fieldType);\n if (current === undefined) return;\n const index = current.indexOf(layer);\n if (index < 0) return;\n const wasTop = index === current.length - 1;\n current.splice(index, 1);\n if (current.length === 0) this.#layers.delete(fieldType);\n if (!wasTop) return;\n\n const previousLayer = current.at(-1);\n const previousRenderer = previousLayer?.renderer ?? this.#base[fieldType];\n if (previousRenderer === undefined) Reflect.deleteProperty(this.#active, fieldType);\n else this.#active[fieldType] = previousRenderer;\n };\n }\n}\n","/** Attribute helpers shared by the block-level node renderers. */\n\nimport type { LexicalNode } from './types';\n\nconst ALIGNMENT_NUMERIC: Readonly<Record<number, string>> = {\n 1: 'left',\n 2: 'center',\n 3: 'right',\n 4: 'justify',\n};\n\nconst ALIGNMENT_STRING = new Set(['left', 'center', 'right', 'justify', 'start', 'end']);\n\n/** Alignment of a block node; Payload emits it as a string or as Lexical's numeric format. */\nexport function resolveAlignment(node: LexicalNode): string | undefined {\n const fmt = node.format;\n if (typeof fmt === 'string' && ALIGNMENT_STRING.has(fmt)) return fmt;\n if (typeof fmt === 'number') return ALIGNMENT_NUMERIC[fmt];\n return undefined;\n}\n\nexport function resolveIndent(node: LexicalNode): number {\n const indent = node.indent;\n return typeof indent === 'number' && indent > 0 ? indent : 0;\n}\n\nexport function dirAttribute(node: LexicalNode): string {\n if (node.direction === 'rtl') return ' dir=\"rtl\"';\n if (node.direction === 'ltr') return ' dir=\"ltr\"';\n return '';\n}\n\n/**\n * Alignment and indent as `lp-align-*` / `lp-indent-N` classes. The sanitizer\n * strips `style` under every policy, so inline CSS would never reach the page.\n */\nexport function layoutClassAttribute(node: LexicalNode): string {\n const align = resolveAlignment(node);\n const indent = resolveIndent(node);\n const classes: string[] = [];\n if (align !== undefined) classes.push(`lp-align-${align}`);\n if (indent > 0) classes.push(`lp-indent-${String(indent)}`);\n return classes.length === 0 ? '' : ` class=\"${classes.join(' ')}\"`;\n}\n","import type { NodeRenderer } from '../registry';\nimport { dirAttribute, layoutClassAttribute } from '../utils';\n\nconst paragraphRenderer: NodeRenderer = (node, ctx): string => {\n const children = ctx.renderChildren(node.children ?? []);\n return `<p${dirAttribute(node)}${layoutClassAttribute(node)}>${children}</p>`;\n};\n\nexport { paragraphRenderer };\n","/** `heading` renderer; an unknown `tag` (transient editor states emit them) falls back to `h2`. */\n\nimport type { NodeRenderer } from '../registry';\nimport { dirAttribute, layoutClassAttribute } from '../utils';\n\nconst VALID_TAGS = new Set(['h1', 'h2', 'h3', 'h4', 'h5', 'h6']);\n\nconst headingRenderer: NodeRenderer = (node, ctx): string => {\n const tagRaw = typeof node['tag'] === 'string' ? node['tag'].toLowerCase() : 'h2';\n const tag = VALID_TAGS.has(tagRaw) ? tagRaw : 'h2';\n const children = ctx.renderChildren(node.children ?? []);\n return `<${tag}${dirAttribute(node)}${layoutClassAttribute(node)}>${children}</${tag}>`;\n};\n\nexport { headingRenderer };\n","/**\n * Value-shape helpers shared by the Lexical node renderers and the field\n * renderers. They live here because `field-types` may import `lexical`, never\n * the reverse (scripts/architecture-policy.ts).\n */\n\nexport interface MediaShape {\n readonly id?: string | number;\n readonly url?: string;\n readonly alt?: string;\n readonly filename?: string;\n readonly mimeType?: string;\n readonly width?: number;\n readonly height?: number;\n readonly sizes?: Readonly<\n Record<string, { readonly url?: string; readonly width?: number; readonly height?: number }>\n >;\n}\n\nexport interface RelationShape {\n readonly id?: string | number;\n readonly title?: string;\n readonly name?: string;\n readonly slug?: string;\n readonly url?: string;\n}\n\nexport function asRecord(value: unknown): Record<string, unknown> | undefined {\n return typeof value === 'object' && value !== null\n ? (value as Record<string, unknown>)\n : undefined;\n}\n\nexport function readMedia(value: unknown): MediaShape | undefined {\n return asRecord(value);\n}\n\n/** Reduce `value` to `[a-z0-9_-]` so it can be a class-name fragment without escaping. */\nexport function sanitizeIdent(value: string): string {\n return value.replace(/[^a-zA-Z0-9_-]/g, '-').toLowerCase();\n}\n\nfunction nonEmpty(value: unknown): string | undefined {\n return typeof value === 'string' && value.length > 0 ? value : undefined;\n}\n\n/** Label precedence for a populated relation: `title`, `name`, `slug`, then `id`. */\nexport function pickRelationLabel(value: RelationShape): string | undefined {\n const label = nonEmpty(value.title) ?? nonEmpty(value.name) ?? nonEmpty(value.slug);\n if (label !== undefined) return label;\n return value.id === undefined ? undefined : String(value.id);\n}\n","/**\n * `link` / `autolink` renderer. Payload 3.x serialises links as\n * `{ fields: { linkType, url, newTab, doc } }`; vanilla Lexical puts `url`\n * and `target` on the node itself. Both shapes are read, Payload's first.\n */\n\nimport { escapeHtml, escapeHtmlAttribute } from '@security/escape';\nimport { isExternalHttpUrl, isSafeUrl } from '@security/url-validator';\nimport type { NodeRenderer } from '../registry';\nimport type { LexicalNode } from '../types';\nimport { asRecord } from '../value-shapes';\n\nconst BLANK_TARGET = ' target=\"_blank\" rel=\"noopener noreferrer\"';\n\nconst linkRenderer: NodeRenderer = (node, ctx): string => {\n const children = ctx.renderChildren(node.children ?? []);\n const fields = asRecord(node['fields']);\n const url = resolveUrl(node, fields);\n if (url === undefined || !isSafeUrl(url)) return children;\n const titleAttr =\n typeof node['title'] === 'string' ? ` title=\"${escapeHtml(node['title'])}\"` : '';\n return `<a href=\"${escapeHtmlAttribute(url)}\"${targetAttribute(node, fields, url)}${titleAttr}>${children}</a>`;\n};\n\nfunction resolveUrl(\n node: LexicalNode,\n fields: Record<string, unknown> | undefined,\n): string | undefined {\n if (fields?.['linkType'] === 'internal') return internalUrl(fields['doc']);\n const url = fields?.['url'] ?? node['url'];\n return typeof url === 'string' && url.length > 0 ? url : undefined;\n}\n\n/** An internal link needs the populated document; a bare id has no route to offer. */\nfunction internalUrl(doc: unknown): string | undefined {\n const value = asRecord(asRecord(doc)?.['value']);\n const url = value?.['url'];\n if (typeof url === 'string' && url.length > 0) return url;\n const slug = value?.['slug'];\n return typeof slug === 'string' && slug.length > 0 ? `/${slug}` : undefined;\n}\n\n/** `_blank` always carries `noopener noreferrer`, whichever side asked for it. */\nfunction targetAttribute(\n node: LexicalNode,\n fields: Record<string, unknown> | undefined,\n url: string,\n): string {\n if (fields?.['newTab'] === true || isExternalHttpUrl(url)) return BLANK_TARGET;\n const target = typeof node['target'] === 'string' ? node['target'] : '';\n if (target === '') return '';\n if (target === '_blank') return BLANK_TARGET;\n return ` target=\"${escapeHtml(target)}\"`;\n}\n\nexport { linkRenderer };\n","/** `code` (fenced block) and `code-highlight` (token span) renderers. */\n\nimport { escapeHtml } from '@security/escape';\nimport type { NodeRenderer } from '../registry';\nimport type { LexicalNode } from '../types';\nimport { sanitizeIdent } from '../value-shapes';\n\nconst codeRenderer: NodeRenderer = (node): string => {\n const language = sanitizeIdent(typeof node['language'] === 'string' ? node['language'] : '');\n const langClass = language === '' ? '' : ` class=\"language-${language}\"`;\n return `<pre><code${langClass}>${escapeHtml(extractText(node))}</code></pre>`;\n};\n\nconst codeHighlightRenderer: NodeRenderer = (node): string => {\n const text = typeof node.text === 'string' ? node.text : '';\n const highlight =\n typeof node['highlightType'] === 'string'\n ? ` class=\"token-${sanitizeIdent(node['highlightType'])}\"`\n : '';\n return `<span${highlight}>${escapeHtml(text)}</span>`;\n};\n\nexport { codeRenderer, codeHighlightRenderer };\n\nfunction extractText(node: LexicalNode): string {\n if (typeof node.text === 'string') return node.text;\n if (!node.children) return '';\n let out = '';\n for (const child of node.children) out += extractText(child);\n return out;\n}\n","/**\n * `upload` renderer: `<img>` for image (or unknown) MIME types, `<video>` /\n * `<audio>` for media, a download link otherwise. An unsafe URL renders nothing.\n */\n\nimport { escapeHtml, escapeHtmlAttribute } from '@security/escape';\nimport { isSafeUrl } from '@security/url-validator';\nimport type { NodeRenderer } from '../registry';\nimport { readMedia, type MediaShape } from '../value-shapes';\n\nconst uploadRenderer: NodeRenderer = (node): string => {\n const value = readMedia(node['value']);\n if (value === undefined) return '';\n const url = value.url;\n if (typeof url !== 'string' || !isSafeUrl(url)) return '';\n\n const mime = typeof value.mimeType === 'string' ? value.mimeType : '';\n if (mime.startsWith('video/')) return renderVideo(value, url);\n if (mime.startsWith('audio/')) return renderAudio(value, url);\n if (mime === '' || mime.startsWith('image/')) return renderImage(value, url);\n return renderFallbackLink(value, url);\n};\n\nexport { uploadRenderer };\n\nfunction dimensionAttributes(value: MediaShape): string {\n const width = typeof value.width === 'number' ? ` width=\"${String(value.width)}\"` : '';\n const height = typeof value.height === 'number' ? ` height=\"${String(value.height)}\"` : '';\n return `${width}${height}`;\n}\n\nfunction typeAttribute(value: MediaShape): string {\n return typeof value.mimeType === 'string' ? ` type=\"${escapeHtmlAttribute(value.mimeType)}\"` : '';\n}\n\nfunction renderImage(value: MediaShape, url: string): string {\n const alt = typeof value.alt === 'string' ? escapeHtml(value.alt) : '';\n return `<img src=\"${escapeHtmlAttribute(url)}\" alt=\"${alt}\"${dimensionAttributes(value)} loading=\"lazy\" decoding=\"async\">`;\n}\n\nfunction renderVideo(value: MediaShape, url: string): string {\n return `<video controls${dimensionAttributes(value)}><source src=\"${escapeHtmlAttribute(url)}\"${typeAttribute(value)}></video>`;\n}\n\nfunction renderAudio(value: MediaShape, url: string): string {\n return `<audio controls><source src=\"${escapeHtmlAttribute(url)}\"${typeAttribute(value)}></audio>`;\n}\n\nfunction renderFallbackLink(value: MediaShape, url: string): string {\n const label = typeof value.filename === 'string' ? escapeHtml(value.filename) : escapeHtml(url);\n return `<a href=\"${escapeHtmlAttribute(url)}\" target=\"_blank\" rel=\"noopener noreferrer\">${label}</a>`;\n}\n","/** `relationship` renderer: a link when the populated document carries a URL, a span otherwise. */\n\nimport { escapeHtml, escapeHtmlAttribute } from '@security/escape';\nimport { isSafeUrl } from '@security/url-validator';\nimport type { NodeRenderer } from '../registry';\nimport { asRecord, pickRelationLabel, sanitizeIdent, type RelationShape } from '../value-shapes';\n\nconst relationshipRenderer: NodeRenderer = (node): string => {\n const relationTo = typeof node['relationTo'] === 'string' ? node['relationTo'] : '';\n const value = asRecord(node['value']) as RelationShape | undefined;\n const label = escapeHtml((value && pickRelationLabel(value)) ?? `#${relationTo}`);\n const slug = sanitizeIdent(relationTo);\n const classAttr =\n slug === '' ? ' class=\"lp-relation\"' : ` class=\"lp-relation lp-relation--${slug}\"`;\n const url = value?.url;\n if (typeof url === 'string' && isSafeUrl(url)) {\n return `<a href=\"${escapeHtmlAttribute(url)}\"${classAttr}>${label}</a>`;\n }\n return `<span${classAttr}>${label}</span>`;\n};\n\nexport { relationshipRenderer };\n","/** Block-renderer registry keyed by Payload block slug; consulted by the `block` and `inlineBlock` nodes. */\n\nimport type { LexicalNode } from '../types';\n\nexport interface BlockRenderContext {\n /** Render nested Lexical content through the node registry. */\n readonly renderChildren: (children: readonly LexicalNode[]) => string;\n}\n\n/** Receives the block's `fields` (with `blockType`) and returns HTML. */\nexport type BlockRenderer = (\n fields: Record<string, unknown>,\n context: BlockRenderContext,\n) => string;\n\nconst registry = new Map<string, BlockRenderer>();\n\n/** Register or replace the renderer for `blockType`. */\nexport function registerBlockRenderer(blockType: string, renderer: BlockRenderer): void {\n registry.set(blockType, renderer);\n}\n\n/** @internal */\nexport function lookupBlockRenderer(blockType: string): BlockRenderer | undefined {\n return registry.get(blockType);\n}\n\n/** @internal */\nexport function registeredBlockTypes(): readonly string[] {\n return [...registry.keys()];\n}\n\n/** Test-only: clear the registry. */\nexport function __resetBlockRegistryForTests(): void {\n registry.clear();\n}\n","/**\n * `block` and `inlineBlock` renderers for Payload's BlocksFeature. The block\n * registry is consulted first; without a renderer for the slug the node becomes\n * an empty, class-tagged element a consumer can style or replace.\n *\n * That element is a placeholder, not a rendering. `UNRENDERED_BLOCK_SELECTOR`\n * names it so the write path can keep the markup the server already rendered\n * for the block in its place, instead of replacing a figure and its image with\n * an empty div (LP0410). Whether that succeeds is decided there, not here: this\n * renderer only tells the context which slug it had no renderer for, and the\n * write says what became of it (LP0410 kept, LP0413 lost).\n */\n\nimport { lookupBlockRenderer } from '../blocks/registry';\nimport type { NodeRenderer, RenderNodeContext } from '../registry';\nimport type { LexicalNode } from '../types';\nimport { asRecord, sanitizeIdent } from '../value-shapes';\n\n/**\n * The placeholders above, in the rendered tree. Both are empty by construction,\n * and a registered renderer's output is not: it carries the block's content and\n * its own class (`lp-block-callout`, …).\n */\nexport const UNRENDERED_BLOCK_SELECTOR = '.lp-block:empty,.lp-inline-block:empty';\n\nfunction renderBlockNode(\n node: LexicalNode,\n ctx: RenderNodeContext,\n tag: 'div' | 'span',\n baseClass: string,\n): string {\n const fields = asRecord(node['fields']) ?? {};\n const blockType = typeof fields['blockType'] === 'string' ? fields['blockType'] : '';\n const slug = sanitizeIdent(blockType);\n const classes = slug === '' ? baseClass : `${baseClass} ${baseClass}--${slug}`;\n if (blockType !== '') {\n const custom = lookupBlockRenderer(blockType) ?? lookupBlockRenderer(slug);\n if (custom) return custom(fields, { renderChildren: ctx.renderChildren });\n // The real slug is known only here — the class carries `sanitizeIdent(slug)`,\n // and a hint that names the wrong one to register is no hint.\n ctx.onUnrenderedBlock?.(blockType, classes);\n }\n return `<${tag} class=\"${classes}\"></${tag}>`;\n}\n\nconst blockRenderer: NodeRenderer = (node, ctx) => renderBlockNode(node, ctx, 'div', 'lp-block');\n\nconst inlineBlockRenderer: NodeRenderer = (node, ctx) =>\n renderBlockNode(node, ctx, 'span', 'lp-inline-block');\n\nexport { blockRenderer, inlineBlockRenderer };\n","/** `table` / `tablerow` / `tablecell` renderers for the `@lexical/table` shapes Payload's table feature emits. */\n\nimport type { NodeRenderer } from '../registry';\nimport { dirAttribute } from '../utils';\n\n// `@lexical/table` TableCellHeaderStates: ROW marks a cell in a header row, COLUMN one in a header column.\nconst HEADER_ROW = 1;\nconst HEADER_COLUMN = 2;\n\nconst tableRenderer: NodeRenderer = (node, ctx) =>\n `<table${dirAttribute(node)}><tbody>${ctx.renderChildren(node.children ?? [])}</tbody></table>`;\n\nconst tableRowRenderer: NodeRenderer = (node, ctx) =>\n `<tr>${ctx.renderChildren(node.children ?? [])}</tr>`;\n\nconst tableCellRenderer: NodeRenderer = (node, ctx): string => {\n const header = typeof node['headerState'] === 'number' ? node['headerState'] : 0;\n const tag = (header & (HEADER_ROW | HEADER_COLUMN)) === 0 ? 'td' : 'th';\n const scope =\n header === HEADER_ROW ? ' scope=\"col\"' : header === HEADER_COLUMN ? ' scope=\"row\"' : '';\n return `<${tag}${scope}${spanAttribute('colspan', node['colSpan'])}${spanAttribute('rowspan', node['rowSpan'])}>${ctx.renderChildren(node.children ?? [])}</${tag}>`;\n};\n\nfunction spanAttribute(name: string, value: unknown): string {\n return typeof value === 'number' && value > 1 ? ` ${name}=\"${String(value)}\"` : '';\n}\n\nexport { tableRenderer, tableRowRenderer, tableCellRenderer };\n","import type { NodeRenderer } from '../registry';\nimport { textRenderer } from './text';\nimport { paragraphRenderer } from './paragraph';\nimport { headingRenderer } from './heading';\nimport { listRenderer, listItemRenderer } from './list';\nimport { linkRenderer } from './link';\nimport { quoteRenderer } from './quote';\nimport { codeRenderer, codeHighlightRenderer } from './code';\nimport { linebreakRenderer, horizontalRuleRenderer, tabRenderer } from './linebreak';\nimport { uploadRenderer } from './upload';\nimport { relationshipRenderer } from './relationship';\nimport { blockRenderer, inlineBlockRenderer } from './block';\nimport { tableCellRenderer, tableRenderer, tableRowRenderer } from './table';\n\n// A value table instead of `register()` calls at import time: a consumer that\n// never renders Lexical content must not carry these under `sideEffects: false`.\nexport const BUILTIN_NODE_RENDERERS: Readonly<Record<string, NodeRenderer>> = {\n text: textRenderer,\n paragraph: paragraphRenderer,\n heading: headingRenderer,\n list: listRenderer,\n listitem: listItemRenderer,\n link: linkRenderer,\n autolink: linkRenderer,\n quote: quoteRenderer,\n code: codeRenderer,\n 'code-highlight': codeHighlightRenderer,\n linebreak: linebreakRenderer,\n horizontalrule: horizontalRuleRenderer,\n tab: tabRenderer,\n upload: uploadRenderer,\n relationship: relationshipRenderer,\n block: blockRenderer,\n inlineBlock: inlineBlockRenderer,\n table: tableRenderer,\n tablerow: tableRowRenderer,\n tablecell: tableCellRenderer,\n};\n","/** `text` renderer. Format flags wrap in a fixed order so equal input gives byte-equal output. */\n\nimport { escapeHtml } from '@security/escape';\nimport type { LexicalNode } from '../types';\nimport { TextFormat } from '../types';\nimport type { NodeRenderer } from '../registry';\n\nconst textRenderer: NodeRenderer = (node: LexicalNode): string => {\n const raw = typeof node.text === 'string' ? node.text : '';\n let out = escapeHtml(raw);\n const format = typeof node.format === 'number' ? node.format : 0;\n if ((format & TextFormat.CODE) !== 0) out = `<code>${out}</code>`;\n if ((format & TextFormat.BOLD) !== 0) out = `<strong>${out}</strong>`;\n if ((format & TextFormat.ITALIC) !== 0) out = `<em>${out}</em>`;\n if ((format & TextFormat.UNDERLINE) !== 0) out = `<u>${out}</u>`;\n if ((format & TextFormat.STRIKETHROUGH) !== 0) out = `<s>${out}</s>`;\n if ((format & TextFormat.SUBSCRIPT) !== 0) out = `<sub>${out}</sub>`;\n if ((format & TextFormat.SUPERSCRIPT) !== 0) out = `<sup>${out}</sup>`;\n if ((format & TextFormat.HIGHLIGHT) !== 0) out = `<mark>${out}</mark>`;\n return out;\n};\n\nexport { textRenderer };\n","/**\n * Lexical document types. Only `type` and `children` are required; every\n * other property is forwarded opaquely to the renderer for that node type.\n */\n\n/** Lexical text-format bitmask; flags combine (`BOLD | ITALIC === 3`). @internal */\nexport const TextFormat = {\n BOLD: 1,\n ITALIC: 2,\n STRIKETHROUGH: 4,\n UNDERLINE: 8,\n CODE: 16,\n SUBSCRIPT: 32,\n SUPERSCRIPT: 64,\n HIGHLIGHT: 128,\n} as const;\n\nexport interface LexicalNode {\n readonly type: string;\n readonly version?: number;\n readonly format?: number | string;\n readonly indent?: number;\n readonly direction?: 'ltr' | 'rtl' | null;\n readonly children?: readonly LexicalNode[];\n readonly text?: string;\n readonly [extra: string]: unknown;\n}\n\nexport interface LexicalRoot {\n readonly root: {\n readonly type?: string;\n readonly children: readonly LexicalNode[];\n readonly direction?: 'ltr' | 'rtl' | null;\n readonly format?: number | string;\n readonly indent?: number;\n readonly [extra: string]: unknown;\n };\n}\n","/** `list` / `listitem` renderers: `bullet` → `<ul>`, `number` → `<ol>`, `check` → `<ul role=\"list\">` with `aria-checked` items. */\n\nimport { escapeHtml } from '@security/escape';\nimport type { NodeRenderer } from '../registry';\nimport { dirAttribute, layoutClassAttribute } from '../utils';\n\nconst listRenderer: NodeRenderer = (node, ctx): string => {\n const listType = typeof node['listType'] === 'string' ? node['listType'] : 'bullet';\n const tag = listType === 'number' ? 'ol' : 'ul';\n const startAttr =\n listType === 'number' && typeof node['start'] === 'number' && node['start'] > 1\n ? ` start=\"${String(node['start'])}\"`\n : '';\n const checkAttr = listType === 'check' ? ' role=\"list\"' : '';\n const children = ctx.renderChildren(node.children ?? []);\n return `<${tag}${dirAttribute(node)}${layoutClassAttribute(node)}${startAttr}${checkAttr}>${children}</${tag}>`;\n};\n\nconst listItemRenderer: NodeRenderer = (node, ctx): string => {\n const children = ctx.renderChildren(node.children ?? []);\n if (typeof node['checked'] === 'boolean') {\n const state = node['checked'] ? 'true' : 'false';\n return `<li role=\"checkbox\" aria-checked=\"${state}\"${layoutClassAttribute(node)}>${children}</li>`;\n }\n const valueAttr =\n typeof node['value'] === 'number' ? ` value=\"${escapeHtml(String(node['value']))}\"` : '';\n return `<li${dirAttribute(node)}${layoutClassAttribute(node)}${valueAttr}>${children}</li>`;\n};\n\nexport { listRenderer, listItemRenderer };\n","import type { NodeRenderer } from '../registry';\nimport { dirAttribute, layoutClassAttribute } from '../utils';\n\nconst quoteRenderer: NodeRenderer = (node, ctx): string => {\n const children = ctx.renderChildren(node.children ?? []);\n return `<blockquote${dirAttribute(node)}${layoutClassAttribute(node)}>${children}</blockquote>`;\n};\n\nexport { quoteRenderer };\n","import type { NodeRenderer } from '../registry';\n\nconst linebreakRenderer: NodeRenderer = () => '<br>';\nconst horizontalRuleRenderer: NodeRenderer = () => '<hr>';\nconst tabRenderer: NodeRenderer = () => '\\t';\n\nexport { linebreakRenderer, horizontalRuleRenderer, tabRenderer };\n","/** Node-renderer registry: consumer registrations layered over the built-in table. */\n\nimport type { LexicalNode } from './types';\nimport { BUILTIN_NODE_RENDERERS } from './nodes/builtin';\n\nexport interface RenderNodeContext {\n /** Render child nodes through the registry. */\n readonly renderChildren: (children: readonly LexicalNode[]) => string;\n /** Text alignment of a block node, or `undefined`. */\n readonly resolveAlignment: (node: LexicalNode) => string | undefined;\n /** Indent level of a node, `0` when none. */\n readonly resolveIndent: (node: LexicalNode) => number;\n /**\n * Where a `block` or `inlineBlock` without a renderer is reported, with the\n * slug Payload sent and the class of the placeholder written in its place.\n * `undefined` on a plain `lexicalToHtml()` call; the `richText` write sets it.\n */\n readonly onUnrenderedBlock?: ((blockType: string, placeholderClass: string) => void) | undefined;\n}\n\nexport type NodeRenderer = (node: LexicalNode, context: RenderNodeContext) => string;\n\nconst registry = new Map<string, NodeRenderer>();\n\n/** Register or replace the renderer for `type`. */\nexport function register(type: string, renderer: NodeRenderer): void {\n registry.set(type, renderer);\n}\n\n/** @internal */\nexport function lookup(type: string): NodeRenderer | undefined {\n return registry.get(type) ?? BUILTIN_NODE_RENDERERS[type];\n}\n\nexport function registeredTypes(): readonly string[] {\n return [...new Set([...Object.keys(BUILTIN_NODE_RENDERERS), ...registry.keys()])];\n}\n\n/** Test-only: drop consumer registrations. */\nexport function __resetForTests(): void {\n registry.clear();\n}\n","/**\n * Lexical → HTML. Each node dispatches to the renderer registered for its\n * `type`; an unknown node renders its children so content is never lost.\n */\n\nimport { sanitizeHtml, hasSanitizerDocument } from '@security/sanitizer';\nimport { lookup, type RenderNodeContext } from './registry';\nimport type { LexicalNode, LexicalRoot } from './types';\nimport { resolveAlignment, resolveIndent } from './utils';\n\nexport interface LexicalRenderOptions {\n /** Pass the result through `sanitizeHtml()` (default `true`). */\n readonly sanitize?: boolean;\n /**\n * Called for every `block` or `inlineBlock` the registry has no renderer\n * for, with the block's slug as Payload sent it and the class its empty\n * placeholder carries. The `richText` write listens: it is the one caller\n * that later knows whether the server's markup for the block survived, so\n * the diagnostic is spoken there (LP0410, LP0413), not here.\n */\n readonly onUnrenderedBlock?: (blockType: string, placeholderClass: string) => void;\n}\n\nlet warnedNoSanitizer = false;\n\n/** @internal */\nexport function isLexicalContent(value: unknown): value is LexicalRoot {\n if (typeof value !== 'object' || value === null) return false;\n if (!('root' in value)) return false;\n const root = value.root;\n if (typeof root !== 'object' || root === null) return false;\n if (!('children' in root)) return false;\n return Array.isArray(root.children);\n}\n\n/** Render a Lexical document to HTML; without `setSanitizerDocument()` the result is unsanitised and warns once. */\nexport function lexicalToHtml(content: LexicalRoot, options: LexicalRenderOptions = {}): string {\n if (!isLexicalContent(content)) return '';\n const html = createContext(options.onUnrenderedBlock).renderChildren(content.root.children);\n if (options.sanitize === false) return html;\n if (hasSanitizerDocument()) return sanitizeHtml(html);\n warnNoSanitizerOnce();\n return html;\n}\n\n/** Plain text of a document, paragraphs separated by `\\n`. */\nexport function lexicalToPlainText(content: LexicalRoot): string {\n if (!isLexicalContent(content)) return '';\n return content.root.children.map(extractPlainText).join('\\n').trim();\n}\n\n/** Test-only: allow the SSR warning to fire again. */\nexport function __resetSanitizerWarningForTests(): void {\n warnedNoSanitizer = false;\n}\n\n/**\n * One context per document: `renderChildren` closes over it so a nested\n * block — a `block` inside a list item, an `inlineBlock` inside a paragraph —\n * reports to the same listener as a top-level one.\n */\nfunction createContext(\n onUnrenderedBlock: RenderNodeContext['onUnrenderedBlock'],\n): RenderNodeContext {\n const context: RenderNodeContext = {\n renderChildren: (children) => {\n let out = '';\n for (const child of children) out += renderNode(child, context);\n return out;\n },\n resolveAlignment,\n resolveIndent,\n onUnrenderedBlock,\n };\n return context;\n}\n\nfunction renderNode(node: LexicalNode, context: RenderNodeContext): string {\n const renderer = lookup(node.type);\n if (renderer) return renderer(node, context);\n return node.children !== undefined ? context.renderChildren(node.children) : '';\n}\n\nfunction extractPlainText(node: LexicalNode): string {\n if (typeof node.text === 'string') return node.text;\n if (node.type === 'linebreak') return '\\n';\n if (node.children === undefined) return '';\n let out = '';\n for (const child of node.children) out += extractPlainText(child);\n return out;\n}\n\n// This layer may not import `@core/diagnostics` (architecture policy), so the\n// warn-once lives here; a hostile or absent console must not break rendering.\nfunction warnNoSanitizerOnce(): void {\n if (warnedNoSanitizer) return;\n warnedNoSanitizer = true;\n try {\n console.warn(\n '[live-preview] lexicalToHtml() has no sanitizer document and returned unsanitised HTML; ' +\n 'call setSanitizerDocument() (linkedom/jsdom) for server rendering, see \"HTML sanitization\" in docs/security.md.',\n );\n } catch {\n // Diagnostics never become a second failure.\n }\n}\n","/**\n * `text` / `textarea` renderer. An element with structured children is left\n * alone (warned once) unless it opts in with `data-payload-text`, so a styled\n * wrapper is not destroyed by a value meant for its text node.\n */\n\nimport { isLexicalContent, lexicalToPlainText } from '@lexical/render';\nimport { trustedHtml } from '@security/trusted-types';\nimport { escapeAndLinebreak } from '@security/escape';\nimport { safeConsoleWarn } from '@core/diagnostics';\nimport { markNoWriteCallback } from '@core/internal-outcome';\nimport type { FieldRenderer, RendererKey } from '@core/types';\n\nconst TEXT_OPT_IN_ATTRIBUTE = 'data-payload-text';\n\n/** Build the renderer with its own warn-once state; one per client (ADR 0002). */\nexport function createTextRenderer(name: RendererKey = 'text'): FieldRenderer {\n const warnedElements = new WeakSet<Element>();\n\n return {\n name,\n render: /* @__PURE__ */ markNoWriteCallback((target, value) => {\n const element = target.element;\n const text = toPlainString(value);\n if (element.tagName === 'INPUT' || element.tagName === 'TEXTAREA') {\n (element as HTMLInputElement | HTMLTextAreaElement).value = text;\n return;\n }\n if (hasForeignChildren(element) && !element.hasAttribute(TEXT_OPT_IN_ATTRIBUTE)) {\n warnOnce(warnedElements, element, target.fieldName);\n return false;\n }\n if (text.includes('\\n') || text.includes('\\r')) {\n element.innerHTML = trustedHtml(escapeAndLinebreak(text));\n return;\n }\n element.textContent = text;\n return;\n }),\n };\n}\n\n// `<br>` is this renderer's own multiline output, not a consumer wrapper;\n// counting it froze every multiline binding after its first write.\nfunction hasForeignChildren(element: Element): boolean {\n return element.querySelector(':scope > :not(br)') !== null;\n}\n\nfunction warnOnce(warnedElements: WeakSet<Element>, element: Element, fieldName: string): void {\n if (warnedElements.has(element)) return;\n warnedElements.add(element);\n safeConsoleWarn(\n `[live-preview] LP0402: Skipping text update for \"${fieldName}\": ` +\n `<${element.tagName.toLowerCase()}> has structured children. Move ` +\n `data-payload-field to the value element, or add data-payload-text to replace them.`,\n );\n}\n\nfunction toPlainString(value: unknown): string {\n if (value === null || value === undefined) return '';\n if (isLexicalContent(value)) return lexicalToPlainText(value);\n if (typeof value === 'string') return value;\n if (typeof value === 'number' || typeof value === 'boolean') return String(value);\n return JSON.stringify(value);\n}\n","/**\n * `richText` renderer: a Lexical root or an HTML string. A project\n * `renderRichText` takes precedence; its output is sanitised like every\n * other HTML write.\n *\n * The Lexical write keeps the markup the server rendered for a block the\n * registry cannot render, rather than replacing it with the empty placeholder\n * the node renderer produces for one, and it keeps the wrapper a template put\n * around the whole field. The verdict is spoken here, after the write, because\n * only the write knows it: LP0410 when the server's markup stands, LP0413 when\n * the two trees did not line up and it is gone — and the second goes through\n * `context.reportUnfaithful` too, which is the case `onUnfaithfulPatch`\n * escalates.\n */\n\nimport { isLexicalContent, lexicalToHtml } from '@lexical/render';\nimport { UNRENDERED_BLOCK_SELECTOR } from '@lexical/nodes/block';\nimport { trustedHtml } from '@security/trusted-types';\nimport { sanitizeHtmlWithPolicy } from '@security/sanitizer';\nimport { FIELD_ATTRIBUTE } from '@core/cache';\nimport { safeConsoleWarn } from '@core/diagnostics';\nimport { markNoWriteCallback } from '@core/internal-outcome';\nimport type { CachedElement, FieldRenderer, RenderContext } from '@core/types';\nimport { isEmptyValue } from './utils';\n\n/** Block slugs already reported, one set per verdict: a block kept once may still be lost later. */\nconst warnedKept = new Set<string>();\nconst warnedLost = new Set<string>();\n\n/** The containers a template wraps rich text in; Lexical renders none of them for content. */\nconst WRAPPER_TAGS: ReadonlySet<string> = new Set(['DIV', 'SECTION', 'ARTICLE']);\n\nconst richTextRenderer: FieldRenderer = {\n name: 'richText',\n render: /* @__PURE__ */ markNoWriteCallback((target, value, context) => {\n const element = target.element;\n if (isEmptyValue(value)) {\n element.textContent = '';\n return;\n }\n const policy = context.sanitizerPolicy;\n if (context.renderRichText !== undefined) {\n const html = context.renderRichText(value, {\n fieldName: target.fieldName,\n element,\n locale: context.locale,\n });\n element.innerHTML = trustedHtml(sanitizeHtmlWithPolicy(html, policy));\n return;\n }\n if (isLexicalContent(value)) {\n // Slug by placeholder class: the class is what the write finds standing.\n const unrendered = new Map<string, string>();\n const lexical = lexicalToHtml(value, {\n // Lexical would otherwise sanitise with the process default; the sink\n // below does it with the instance's policy instead.\n sanitize: false,\n onUnrenderedBlock: (blockType, placeholderClass) => {\n unrendered.set(placeholderClass, blockType);\n },\n });\n const verdicts = writeKeepingUnrenderedBlocks(\n element,\n sanitizeHtmlWithPolicy(lexical, policy),\n );\n for (const [placeholderClass, lost] of verdicts) {\n const blockType = unrendered.get(placeholderClass);\n if (blockType !== undefined) reportUnrenderedBlock(target, context, blockType, lost);\n }\n return;\n }\n if (typeof value === 'string') {\n element.innerHTML = trustedHtml(sanitizeHtmlWithPolicy(value, policy));\n return;\n }\n return false;\n }),\n};\n\n/**\n * Write `html` into `element`, but move the live element standing where an\n * unrendered block's placeholder stands over into the new tree first. Every\n * pairing is resolved before the first move: a move takes a child out of the\n * live element, which would shift the position each later one is read at.\n *\n * Returns a verdict per placeholder class: `false` where a live element that\n * was not itself a placeholder took the placeholder's place, `true` where one\n * is still standing over markup the element had — the descent found no\n * counterpart, so this write lost what the server drew for that block. No\n * verdict where there was nothing to keep: a container the page left empty,\n * or a placeholder an earlier write put there, whose loss was reported then.\n */\nfunction writeKeepingUnrenderedBlocks(\n element: Element,\n html: string,\n): ReadonlyMap<string, boolean> {\n const rendered = element.cloneNode(false) as Element;\n rendered.innerHTML = trustedHtml(html);\n const target = wrapperOf(element, rendered) ?? element;\n const verdicts = new Map<string, boolean>();\n const placeholders = rendered.querySelectorAll(UNRENDERED_BLOCK_SELECTOR);\n if (placeholders.length > 0 && target.firstElementChild !== null) {\n const pairs: [placeholder: Element, live: Element][] = [];\n pairUnrenderedBlocks(target, rendered, pairs);\n for (const [placeholder, live] of pairs) {\n placeholder.replaceWith(live);\n if (!live.matches(UNRENDERED_BLOCK_SELECTOR)) verdicts.set(placeholder.className, false);\n }\n // A placeholder the moves left in the tree is one no live element answered for.\n for (const placeholder of placeholders) {\n if (placeholder.parentNode !== null) verdicts.set(placeholder.className, true);\n }\n }\n target.replaceChildren(...rendered.childNodes);\n return verdicts;\n}\n\n/**\n * The one wrapper a template puts around rich text when the server renders it\n * — `<div class=\"prose\">` around the blocks, the usual Tailwind shape — or\n * `null` when the rendered document is written straight into `element`. The\n * wrapper stays, because the typography hangs on its class, and the pairing\n * runs inside it, where the blocks are; without this the live tree had one\n * child where the rendered one had five, and the descent stopped before it\n * reached the block (measured on the demo, Z29).\n *\n * A wrapper is the element's only child, of a kind Lexical does not render\n * content as, with no binding of its own, standing where the rendered document\n * has several elements — and unlike every one of them: a `<div>` a registered\n * block renders is content, and the paragraph typed after it must not be\n * written into it. One rendered element says nothing either way, and the\n * positional pairing already answers for that case.\n */\nfunction wrapperOf(element: Element, rendered: Element): Element | null {\n const child = element.firstElementChild;\n if (child?.nextElementSibling !== null || rendered.children.length < 2) return null;\n if (!WRAPPER_TAGS.has(child.tagName) || child.hasAttribute(FIELD_ATTRIBUTE)) return null;\n for (const block of rendered.children) {\n if (block.tagName === child.tagName && block.className === child.className) return null;\n }\n return child;\n}\n\n/**\n * Pair each placeholder with the live element in its position. Both trees\n * describe the same document, so position is the only key there is — the server\n * writes no id to match on. Descent stops where the child counts differ: the\n * two do not line up there, nothing is kept, and the placeholder is written,\n * which is what this renderer did before.\n */\nfunction pairUnrenderedBlocks(\n live: Element,\n rendered: Element,\n kept: [placeholder: Element, live: Element][],\n): void {\n if (live.children.length !== rendered.children.length) return;\n let liveChild = live.firstElementChild;\n let renderedChild = rendered.firstElementChild;\n // Nothing moves until every pairing is known, so walking siblings is stable.\n while (liveChild !== null && renderedChild !== null) {\n if (renderedChild.matches(UNRENDERED_BLOCK_SELECTOR)) kept.push([renderedChild, liveChild]);\n else pairUnrenderedBlocks(liveChild, renderedChild, kept);\n liveChild = liveChild.nextElementSibling;\n renderedChild = renderedChild.nextElementSibling;\n }\n}\n\n/**\n * Say what became of a block nobody registered a renderer for, once per slug\n * and verdict. Not through the runtime's `warn` option: a renderer has no\n * channel to it, and `RenderContext` carries the one thing that matters more —\n * the report that lets a strategy redraw the region the write just degraded.\n */\nfunction reportUnrenderedBlock(\n target: CachedElement,\n context: RenderContext,\n blockType: string,\n lost: boolean,\n): void {\n if (lost) {\n context.reportUnfaithful?.(target, `lost the markup the server drew for block \"${blockType}\"`);\n }\n const warned = lost ? warnedLost : warnedKept;\n if (warned.has(blockType)) return;\n warned.add(blockType);\n safeConsoleWarn(\n `[live-preview] ${\n lost\n ? `LP0413: no renderer for block \"${blockType}\", and the markup the server rendered for it is lost.`\n : `LP0410: no renderer for block \"${blockType}\"; keeping what the server rendered for it.`\n } Register one with registerBlockRenderer().`,\n );\n}\n\n/** Test-only: let LP0410 and LP0413 fire again. */\nexport function __resetBlockWarningsForTests(): void {\n warnedKept.clear();\n warnedLost.clear();\n}\n\nexport { richTextRenderer };\n","/** `html` renderer (`data-payload-type=\"html\"`): the value is sanitised, then injected. */\n\nimport { sanitizeHtmlWithPolicy } from '@security/sanitizer';\nimport { trustedHtml } from '@security/trusted-types';\nimport type { FieldRenderer } from '@core/types';\nimport { isEmptyValue, safeStringify } from './utils';\n\nconst htmlRenderer: FieldRenderer = {\n name: 'html',\n render(target, value, context) {\n if (isEmptyValue(value)) {\n target.element.textContent = '';\n return;\n }\n const html = typeof value === 'string' ? value : safeStringify(value);\n target.element.innerHTML = trustedHtml(sanitizeHtmlWithPolicy(html, context.sanitizerPolicy));\n },\n};\n\nexport { htmlRenderer };\n","/** URL acceptance shared by the renderers that write `href` / `src`: one LP0401 warning per element. */\n\nimport { safeConsoleWarn } from '@core/diagnostics';\nimport { isSafeUrl } from '@security/url-validator';\n\n// Keyed by element so a second client on the same page does not repeat the warning.\nconst warned = new WeakSet<Element>();\n\nexport type UrlOutcome =\n | { readonly kind: 'none' }\n | { readonly kind: 'unsafe' }\n | { readonly kind: 'safe'; readonly url: string };\n\n/** `none` when there is no URL to write, `unsafe` (warned once) when it fails `isSafeUrl`. */\nexport function acceptUrl(element: Element, fieldName: string, candidate: unknown): UrlOutcome {\n if (typeof candidate !== 'string' || candidate.length === 0) return { kind: 'none' };\n if (isSafeUrl(candidate)) return { kind: 'safe', url: candidate };\n if (!warned.has(element)) {\n warned.add(element);\n safeConsoleWarn(\n `[live-preview] LP0401: refused an unsafe URL for \"${fieldName}\" on ` +\n `<${element.tagName.toLowerCase()}>; the attribute was cleared.`,\n );\n }\n return { kind: 'unsafe' };\n}\n","/**\n * `url` renderer and the factory the `email` renderer shares. On an `<a>` the\n * value (or the `data-payload-href` sibling) becomes `href`; the value is\n * always the visible text.\n */\n\nimport { resolveFieldValue } from '@core/field-value';\nimport type { FieldRenderer, RendererKey } from '@core/types';\nimport { acceptUrl } from './unsafe-url';\nimport { isEmptyValue, safeStringify } from './utils';\n\n/** Build the link renderer named `name`; `toHref` derives the URL from the field value. */\nexport function createLinkRenderer(\n name: RendererKey,\n toHref: (value: string) => string = (value) => value,\n): FieldRenderer {\n return {\n name,\n render(target, value, context) {\n const element = target.element;\n if (isEmptyValue(value)) {\n clear(element);\n return;\n }\n const text = safeStringify(value);\n if (element.tagName === 'INPUT' || element.tagName === 'TEXTAREA') {\n (element as HTMLInputElement | HTMLTextAreaElement).value = text;\n return;\n }\n if (element.tagName === 'A') {\n const hrefField = target.hrefField;\n const candidate =\n hrefField === undefined || hrefField.length === 0\n ? toHref(text)\n : resolveFieldValue(\n context.allFields,\n hrefField,\n context.locale,\n target.locale !== undefined,\n );\n const outcome = acceptUrl(element, target.fieldName, candidate);\n if (outcome.kind === 'safe') element.setAttribute('href', outcome.url);\n else if (outcome.kind === 'unsafe') element.removeAttribute('href');\n }\n element.textContent = text;\n },\n };\n}\n\nfunction clear(element: Element): void {\n if (element.tagName === 'INPUT' || element.tagName === 'TEXTAREA') {\n (element as HTMLInputElement | HTMLTextAreaElement).value = '';\n return;\n }\n element.removeAttribute('href');\n element.textContent = '';\n}\n\nexport const urlRenderer: FieldRenderer = createLinkRenderer('url');\n","/** `email` renderer: a bare address becomes a `mailto:` link, a value with a scheme is used as written. */\n\nimport type { FieldRenderer } from '@core/types';\nimport { createLinkRenderer } from './url';\n\nconst HAS_SCHEME = /^[a-zA-Z][a-zA-Z0-9+.-]*:/;\n\nfunction mailtoHref(value: string): string {\n const trimmed = value.trim();\n if (HAS_SCHEME.test(trimmed) || !trimmed.includes('@')) return trimmed;\n return `mailto:${trimmed}`;\n}\n\nexport const emailRenderer: FieldRenderer = createLinkRenderer('email', mailtoHref);\n","/** `<img>` writes shared by the image and upload renderers. */\n\nimport { isSafeUrl } from '@security/url-validator';\nimport type { MediaShape } from '@lexical/value-shapes';\n\nconst IMAGE_SOURCE_ATTRIBUTES = ['src', 'srcset', 'sizes'] as const;\n\nexport function clearImage(img: HTMLImageElement): void {\n for (const name of IMAGE_SOURCE_ATTRIBUTES) img.removeAttribute(name);\n}\n\n/**\n * A server-rendered `srcset` would keep winning over a new `src`, so it is\n * rebuilt from the media's `sizes` or removed together with `sizes`.\n */\nexport function writeImage(\n img: HTMLImageElement,\n url: string,\n media: MediaShape | undefined,\n): void {\n img.src = url;\n const srcset = buildSrcset(media);\n if (srcset === undefined) {\n img.removeAttribute('srcset');\n img.removeAttribute('sizes');\n return;\n }\n img.setAttribute('srcset', srcset);\n}\n\nfunction buildSrcset(media: MediaShape | undefined): string | undefined {\n if (media?.sizes === undefined) return undefined;\n const candidates: string[] = [];\n for (const size of Object.values(media.sizes)) {\n if (typeof size.url !== 'string' || typeof size.width !== 'number' || !isSafeUrl(size.url)) {\n continue;\n }\n candidates.push(`${srcsetUrl(size.url)} ${String(size.width)}w`);\n }\n if (candidates.length === 0) return undefined;\n if (typeof media.width === 'number' && typeof media.url === 'string' && isSafeUrl(media.url)) {\n candidates.push(`${srcsetUrl(media.url)} ${String(media.width)}w`);\n }\n return candidates.join(', ');\n}\n\n// Commas and whitespace delimit srcset candidates and cannot appear raw in a URL there.\nfunction srcsetUrl(url: string): string {\n return url.replace(/[\\s,]/g, encodeURIComponent);\n}\n","/**\n * `image` renderer: `src`/`alt`/`srcset` on an `<img>`, a CSS background on\n * anything else. The value is a media object, a URL string, or resolved from\n * the `data-payload-src` / `data-payload-alt` sibling fields.\n */\n\nimport { escapeCssUrl } from '@security/escape';\nimport { resolveFieldValue } from '@core/field-value';\nimport { markNoWriteCallback } from '@core/internal-outcome';\nimport type { CachedElement, FieldRenderer, RenderContext } from '@core/types';\nimport { readMedia, type MediaShape } from '@lexical/value-shapes';\nimport { clearImage, writeImage } from './media';\nimport { acceptUrl } from './unsafe-url';\nimport { isEmptyValue } from './utils';\n\nconst imageRenderer: FieldRenderer = {\n name: 'image',\n render: /* @__PURE__ */ markNoWriteCallback((target, value, context) => {\n const element = target.element;\n if (isEmptyValue(value)) {\n clear(element);\n return;\n }\n const preferLocale = target.locale !== undefined;\n const { media, candidate } = pickSource(target, value, context, preferLocale);\n const outcome = acceptUrl(element, target.fieldName, candidate);\n if (outcome.kind === 'none') return false;\n if (outcome.kind === 'unsafe') {\n clear(element);\n return;\n }\n if (element.tagName === 'IMG') {\n const img = element as HTMLImageElement;\n writeImage(img, outcome.url, media);\n const alt = pickAlt(media, target.altField, context.allFields, context.locale, preferLocale);\n if (alt !== undefined) img.alt = alt;\n return;\n }\n (element as HTMLElement).style.backgroundImage = `url('${escapeCssUrl(outcome.url)}')`;\n return;\n }),\n};\n\nfunction clear(element: Element): void {\n if (element.tagName === 'IMG') clearImage(element as HTMLImageElement);\n else (element as HTMLElement).style.backgroundImage = '';\n}\n\nfunction pickSource(\n target: CachedElement,\n value: unknown,\n context: RenderContext,\n preferLocale: boolean,\n): { readonly media: MediaShape | undefined; readonly candidate: unknown } {\n const source =\n target.srcField !== undefined && target.srcField.length > 0\n ? resolveFieldValue(context.allFields, target.srcField, context.locale, preferLocale)\n : value;\n const media = readMedia(source);\n return { media, candidate: media === undefined ? source : media.url };\n}\n\nfunction pickAlt(\n media: MediaShape | undefined,\n altField: string | undefined,\n allFields: Record<string, unknown>,\n locale: string | undefined,\n preferLocale: boolean,\n): string | undefined {\n if (altField !== undefined && altField.length > 0) {\n const sibling = resolveFieldValue(allFields, altField, locale, preferLocale);\n return typeof sibling === 'string' ? sibling : undefined;\n }\n return media?.alt;\n}\n\nexport { imageRenderer };\n","/** `upload` renderer: an image on `<img>`, a download link on `<a>`, an injected link elsewhere. */\n\nimport { escapeHtml, escapeHtmlAttribute } from '@security/escape';\nimport { trustedHtml } from '@security/trusted-types';\nimport { markNoWriteCallback } from '@core/internal-outcome';\nimport type { FieldRenderer } from '@core/types';\nimport { readMedia } from '@lexical/value-shapes';\nimport { clearImage, writeImage } from './media';\nimport { acceptUrl } from './unsafe-url';\nimport { isEmptyValue } from './utils';\n\nconst uploadRenderer: FieldRenderer = {\n name: 'upload',\n render: /* @__PURE__ */ markNoWriteCallback((target, value) => {\n const element = target.element;\n if (isEmptyValue(value)) {\n clear(element);\n return;\n }\n const media = readMedia(value);\n if (media === undefined) return false;\n const outcome = acceptUrl(element, target.fieldName, media.url);\n if (outcome.kind === 'none') return false;\n if (outcome.kind === 'unsafe') {\n clear(element);\n return;\n }\n const url = outcome.url;\n if (element.tagName === 'IMG') {\n const img = element as HTMLImageElement;\n writeImage(img, url, media);\n if (media.alt !== undefined) img.alt = media.alt;\n return;\n }\n if (element.tagName === 'A') {\n element.setAttribute('href', url);\n element.textContent = media.filename ?? url;\n return;\n }\n const label = escapeHtml(media.filename ?? url);\n element.innerHTML = trustedHtml(`<a href=\"${escapeHtmlAttribute(url)}\">${label}</a>`);\n return;\n }),\n};\n\nfunction clear(element: Element): void {\n if (element.tagName === 'IMG') {\n clearImage(element as HTMLImageElement);\n return;\n }\n element.removeAttribute('href');\n element.textContent = '';\n}\n\nexport { uploadRenderer };\n","/** `relationship` renderer: the relation's label as text; on an `<a>` a populated `url` becomes `href`. */\n\nimport type { FieldRenderer } from '@core/types';\nimport { asRecord, pickRelationLabel, type RelationShape } from '@lexical/value-shapes';\nimport { acceptUrl } from './unsafe-url';\nimport { isEmptyValue, safeStringify } from './utils';\n\nconst relationshipRenderer: FieldRenderer = {\n name: 'relationship',\n render(target, value) {\n const element = target.element;\n if (isEmptyValue(value)) {\n element.removeAttribute('href');\n element.textContent = '';\n return;\n }\n if (element.tagName === 'A' && !Array.isArray(value)) {\n const outcome = acceptUrl(element, target.fieldName, asRecord(value)?.['url']);\n if (outcome.kind === 'safe') element.setAttribute('href', outcome.url);\n else if (outcome.kind === 'unsafe') element.removeAttribute('href');\n }\n element.textContent = Array.isArray(value) ? value.map(label).join(', ') : label(value);\n },\n};\n\nfunction label(value: unknown): string {\n const record = asRecord(value) as RelationShape | undefined;\n if (record === undefined) return safeStringify(value);\n return pickRelationLabel(record) ?? '';\n}\n\nexport { relationshipRenderer };\n","/**\n * `select` / `radio` renderer. Form controls receive option values; other\n * elements show the option labels from the field schema when the admin sent\n * one, else the values.\n */\n\nimport type { FieldRenderer, RenderContext } from '@core/types';\nimport { asRecord } from '@lexical/value-shapes';\nimport { isEmptyValue, safeStringify } from './utils';\n\nconst selectRenderer: FieldRenderer = {\n name: 'select',\n render(target, value, context) {\n const element = target.element;\n const values = isEmptyValue(value) ? [] : toValues(value);\n if (element.tagName === 'SELECT') {\n writeSelect(element as HTMLSelectElement, values);\n return;\n }\n if (element.tagName === 'INPUT' && (element as HTMLInputElement).type === 'radio') {\n const radio = element as HTMLInputElement;\n radio.checked = values.includes(radio.value);\n return;\n }\n element.textContent = values.map((item) => labelFor(item, context)).join(', ');\n },\n};\n\nfunction toValues(value: unknown): readonly string[] {\n if (Array.isArray(value)) return value.map(safeStringify);\n return [safeStringify(value)];\n}\n\n// `.value = 'a, b'` on a multiple select selects nothing; options are set one by one.\nfunction writeSelect(select: HTMLSelectElement, values: readonly string[]): void {\n if (select.multiple) {\n for (const option of Array.from(select.options)) {\n option.selected = values.includes(option.value);\n }\n return;\n }\n select.value = values[0] ?? '';\n}\n\nfunction labelFor(value: string, context: RenderContext): string {\n const options = context.schema?.['options'];\n if (!Array.isArray(options)) return value;\n for (const option of options) {\n const record = asRecord(option);\n if (record === undefined || safeStringify(record['value']) !== value) continue;\n return typeof record['label'] === 'string' ? record['label'] : value;\n }\n return value;\n}\n\nexport { selectRenderer };\n","/** `checkbox` renderer: `checked` on an input, `aria-checked` where present, `true`/`false` text otherwise. */\n\nimport type { FieldRenderer } from '@core/types';\n\nconst FALSE_STRINGS = new Set(['', 'false', '0', 'off', 'no']);\n\nconst checkboxRenderer: FieldRenderer = {\n name: 'checkbox',\n render(target, value) {\n const element = target.element;\n const checked = toBoolean(value);\n if (element.tagName === 'INPUT' && (element as HTMLInputElement).type === 'checkbox') {\n (element as HTMLInputElement).checked = checked;\n return;\n }\n if (element.hasAttribute('aria-checked')) {\n element.setAttribute('aria-checked', checked ? 'true' : 'false');\n return;\n }\n element.textContent = checked ? 'true' : 'false';\n },\n};\n\n// Form state and query parameters arrive as strings; `Boolean('false')` is not an answer.\nfunction toBoolean(value: unknown): boolean {\n if (typeof value === 'boolean') return value;\n if (typeof value === 'string') return !FALSE_STRINGS.has(value.trim().toLowerCase());\n if (typeof value === 'number') return value !== 0;\n return value !== null && value !== undefined;\n}\n\nexport { checkboxRenderer };\n","/**\n * Memoised `Intl` formatters, keyed by locale and options. Constructing them\n * per call dominates render time for arrays of many numeric or date fields,\n * and a formatter is a pure function of its key, so one instance is safe to\n * share across the page. Bounded so a language switcher cannot grow it without\n * limit.\n */\n\nimport { lruGet, lruSet, lruTrim } from './lru';\n\nconst NUMBER_CACHE = new Map<string, Intl.NumberFormat>();\nconst DATE_CACHE = new Map<string, Intl.DateTimeFormat>();\n\nconst DEFAULT_MAX_ENTRIES = 64;\n\nlet maxEntries = DEFAULT_MAX_ENTRIES;\n\n/** Internal test helper — purges every cached formatter. */\nexport function __resetIntlCache(): void {\n NUMBER_CACHE.clear();\n DATE_CACHE.clear();\n maxEntries = DEFAULT_MAX_ENTRIES;\n}\n\n/** Adjust the LRU bound. Returns the previous value. */\nexport function setIntlCacheLimit(limit: number): number {\n if (!Number.isFinite(limit) || limit < 1) return maxEntries;\n const previous = maxEntries;\n maxEntries = Math.floor(limit);\n lruTrim(NUMBER_CACHE, maxEntries);\n lruTrim(DATE_CACHE, maxEntries);\n return previous;\n}\n\n/** Cache occupancy, for tests and dev observability. */\nexport function intlCacheSize(): { readonly numbers: number; readonly dates: number } {\n return { numbers: NUMBER_CACHE.size, dates: DATE_CACHE.size };\n}\n\nexport function getNumberFormat(\n locale: string | undefined,\n options?: Intl.NumberFormatOptions,\n): Intl.NumberFormat {\n const key = buildKey(locale, options);\n return (\n lruGet(NUMBER_CACHE, key) ??\n lruSet(NUMBER_CACHE, key, new Intl.NumberFormat(locale, options), maxEntries)\n );\n}\n\nexport function getDateTimeFormat(\n locale: string | undefined,\n options?: Intl.DateTimeFormatOptions,\n): Intl.DateTimeFormat {\n const key = buildKey(locale, options);\n return (\n lruGet(DATE_CACHE, key) ??\n lruSet(DATE_CACHE, key, new Intl.DateTimeFormat(locale, options), maxEntries)\n );\n}\n\nfunction buildKey(locale: string | undefined, options: unknown): string {\n // Stable key order so equivalent option objects share a slot, and an empty\n // one collapses to the bare-locale key.\n const localePart = locale ?? '';\n if (options === undefined || options === null) return localePart;\n const serialised = stableStringify(options);\n if (serialised === '{}') return localePart;\n return `${localePart}|${serialised}`;\n}\n\nfunction stableStringify(value: unknown): string {\n if (value === null || typeof value !== 'object') return JSON.stringify(value);\n if (Array.isArray(value)) {\n return `[${value.map((v) => stableStringify(v)).join(',')}]`;\n }\n const record = value as Record<string, unknown>;\n const keys = Object.keys(record).sort();\n const parts: string[] = [];\n for (const key of keys) {\n const inner = record[key];\n if (inner === undefined) continue;\n parts.push(`${JSON.stringify(key)}:${stableStringify(inner)}`);\n }\n return `{${parts.join(',')}}`;\n}\n","/**\n * `data-payload-format`: a closed vocabulary deciding how a date or a number is\n * written. Without it a bound price shows the raw amount and a bound date an\n * ISO instant, so a template that formats on the server has to leave both\n * unbound — which is where an edit becomes invisible.\n *\n * Closed on purpose. Anything a consumer could pass here would be code running\n * inside the preview, and the runtime takes no code from the page. Two\n * renderers read it, so the parsing lives beside them rather than in either.\n *\n * `relative` (\"in 3 days\") is deliberately absent: choosing the unit and its\n * rounding is policy, not formatting, and two readers will want different\n * answers. A project that needs it renders it on the server behind a fragment.\n */\n\nimport { safeConsoleWarn } from '@core/diagnostics';\n\n/** What a renderer does with a parsed vocabulary entry. */\nexport type ValueFormat =\n | { readonly kind: 'date'; readonly options: Intl.DateTimeFormatOptions }\n | { readonly kind: 'number'; readonly options: Intl.NumberFormatOptions };\n\nconst DATE_STYLES = new Set(['short', 'medium', 'long', 'full']);\nconst TIME_STYLES = new Set(['short', 'medium', 'long', 'full']);\n\n/** ISO 4217: three letters, and `Intl` rejects anything else at construction. */\nconst CURRENCY_CODE = /^[A-Za-z]{3}$/u;\nconst FRACTION_DIGITS = /^[0-4]$/u;\n\n/**\n * `undefined` for a spec this vocabulary does not contain — the caller then\n * keeps its own default formatting and reports LP0408 once for that element.\n */\nexport function parseValueFormat(spec: string): ValueFormat | undefined {\n const separator = spec.indexOf(':');\n const name = separator === -1 ? spec : spec.slice(0, separator);\n const argument = separator === -1 ? undefined : spec.slice(separator + 1);\n\n switch (name) {\n case 'date':\n if (argument === undefined) return dateFormat({ dateStyle: 'medium' });\n return DATE_STYLES.has(argument)\n ? dateFormat({ dateStyle: argument as Intl.DateTimeFormatOptions['dateStyle'] })\n : undefined;\n case 'time':\n if (argument === undefined) return dateFormat({ timeStyle: 'short' });\n return TIME_STYLES.has(argument)\n ? dateFormat({ timeStyle: argument as Intl.DateTimeFormatOptions['timeStyle'] })\n : undefined;\n case 'datetime':\n // The bare form is the renderer's own default, so `datetime` changes\n // nothing and exists to be written down next to the others.\n if (argument === undefined) return dateFormat({ dateStyle: 'medium', timeStyle: 'short' });\n return DATE_STYLES.has(argument)\n ? dateFormat({\n dateStyle: argument as Intl.DateTimeFormatOptions['dateStyle'],\n timeStyle: argument === 'short' ? 'short' : 'medium',\n })\n : undefined;\n case 'number':\n if (argument === undefined) return numberFormat({});\n if (!FRACTION_DIGITS.test(argument)) return undefined;\n return numberFormat({\n minimumFractionDigits: Number(argument),\n maximumFractionDigits: Number(argument),\n });\n case 'currency':\n if (argument === undefined || !CURRENCY_CODE.test(argument)) return undefined;\n return numberFormat({ style: 'currency', currency: argument.toUpperCase() });\n case 'percent':\n return argument === undefined ? numberFormat({ style: 'percent' }) : undefined;\n default:\n return undefined;\n }\n}\n\nfunction dateFormat(options: Intl.DateTimeFormatOptions): ValueFormat {\n return { kind: 'date', options };\n}\n\nfunction numberFormat(options: Intl.NumberFormatOptions): ValueFormat {\n return { kind: 'number', options };\n}\n\nconst warned = new WeakSet<Element>();\n\n/** Reported once per element: the markup is the cause, and it does not change. */\nexport function warnUnknownFormat(element: Element, fieldName: string, spec: string): void {\n if (warned.has(element)) return;\n warned.add(element);\n safeConsoleWarn(\n `[live-preview] LP0408: data-payload-format=\"${spec}\" on \"${fieldName}\" is not a ` +\n 'known format; the default formatting was used. Known: date, date:short|medium|long|full, ' +\n 'time, datetime, number, number:0-4, currency:XXX, percent.',\n );\n}\n\n/**\n * The options a renderer should use, or `undefined` to keep its own default —\n * which is also the answer when the spec belongs to the other renderer, so\n * `currency:EUR` on a date changes nothing rather than breaking it.\n */\nexport function formatOptionsFor<K extends ValueFormat['kind']>(\n kind: K,\n spec: string | undefined,\n element: Element,\n fieldName: string,\n): Extract<ValueFormat, { kind: K }>['options'] | undefined {\n if (spec === undefined || spec === '') return undefined;\n const parsed = parseValueFormat(spec);\n if (parsed === undefined) {\n warnUnknownFormat(element, fieldName, spec);\n return undefined;\n }\n if (parsed.kind !== kind) return undefined;\n return parsed.options;\n}\n","/**\n * `date` renderer. `<time>` gets an ISO `datetime` plus a localised label;\n * date inputs get the value in the visitor's local time zone, because that is\n * what the control displays.\n */\n\nimport { detectInitialLocale } from '@detection/locale';\nimport { getDateTimeFormat } from '@core/intl-cache';\nimport type { CachedElement, FieldRenderer, RenderContext } from '@core/types';\nimport { isEmptyValue, safeStringify } from './utils';\nimport { formatOptionsFor } from './value-format';\n\nconst dateRenderer: FieldRenderer = {\n name: 'date',\n render(target, value, context) {\n const element = target.element;\n if (isEmptyValue(value)) {\n if (element.tagName === 'INPUT') (element as HTMLInputElement).value = '';\n else {\n element.removeAttribute('datetime');\n element.textContent = '';\n }\n return;\n }\n const raw = typeof value === 'number' ? value : safeStringify(value);\n const date = new Date(raw);\n const valid = !Number.isNaN(date.getTime());\n const fallback = String(raw);\n if (element.tagName === 'INPUT') {\n (element as HTMLInputElement).value = valid\n ? formatForInput((element as HTMLInputElement).type, date)\n : fallback;\n return;\n }\n if (element.tagName === 'TIME') {\n element.setAttribute('datetime', valid ? date.toISOString() : fallback);\n }\n element.textContent = valid ? formatDate(date, target, context) : fallback;\n },\n};\n\nconst DEFAULT_DATE_OPTIONS: Intl.DateTimeFormatOptions = {\n dateStyle: 'medium',\n timeStyle: 'short',\n};\n\nfunction formatDate(date: Date, target: CachedElement, context: RenderContext): string {\n const locale = target.locale ?? context.locale ?? detectInitialLocale();\n const options =\n formatOptionsFor('date', target.format, target.element, target.fieldName) ??\n DEFAULT_DATE_OPTIONS;\n try {\n return getDateTimeFormat(locale, options).format(date);\n } catch {\n return date.toISOString();\n }\n}\n\n/** Value for `<input type=\"date|datetime-local|time\">` in local time; other inputs get the ISO instant. */\nexport function formatForInput(type: string, date: Date): string {\n const day = `${String(date.getFullYear()).padStart(4, '0')}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}`;\n const clock = `${pad(date.getHours())}:${pad(date.getMinutes())}`;\n if (type === 'date') return day;\n if (type === 'datetime-local') return `${day}T${clock}`;\n if (type === 'time') return clock;\n return date.toISOString();\n}\n\nfunction pad(value: number): string {\n return String(value).padStart(2, '0');\n}\n\nexport { dateRenderer };\n","/** `number` renderer: raw value on inputs, `Intl.NumberFormat` elsewhere. */\n\nimport { detectInitialLocale } from '@detection/locale';\nimport { getNumberFormat } from '@core/intl-cache';\nimport type { CachedElement, FieldRenderer, RenderContext } from '@core/types';\nimport { isEmptyValue, safeStringify } from './utils';\nimport { formatOptionsFor } from './value-format';\n\nconst numberRenderer: FieldRenderer = {\n name: 'number',\n render(target, value, context) {\n const element = target.element;\n if (isEmptyValue(value)) {\n if (element.tagName === 'INPUT') (element as HTMLInputElement).value = '';\n else element.textContent = '';\n return;\n }\n const num = typeof value === 'number' ? value : Number(safeStringify(value));\n if (Number.isNaN(num)) {\n element.textContent = safeStringify(value);\n return;\n }\n if (element.tagName === 'INPUT') {\n (element as HTMLInputElement).value = String(num);\n return;\n }\n element.textContent = format(num, target, context);\n },\n};\n\nfunction format(num: number, target: CachedElement, context: RenderContext): string {\n const locale = target.locale ?? context.locale ?? detectInitialLocale();\n const options = formatOptionsFor('number', target.format, target.element, target.fieldName);\n try {\n return getNumberFormat(locale, options).format(num);\n } catch {\n // An `Intl` option this build rejects — an unknown currency, say.\n return String(num);\n }\n}\n\nexport { numberRenderer };\n","/**\n * `array` / `blocks` renderer. With `data-payload-array-template` each item\n * is interpolated into the template (`{{key}}`, `{{value}}`, `{{index}}`);\n * without one, items are joined by `data-payload-array-separator`.\n */\n\nimport { sanitizeHtmlWithPolicy } from '@security/sanitizer';\nimport { trustedHtml } from '@security/trusted-types';\nimport {\n collectTemplateKeys,\n inheritItemAttributes,\n interpolateArrayTemplate,\n sharedItemAttributes,\n} from '@core/array-template';\nimport { markNoWriteCallback } from '@core/internal-outcome';\nimport { templateSanitizeOptions } from '@core/template-sanitize';\nimport type { FieldRenderer } from '@core/types';\nimport { isEmptyValue, safeStringify } from './utils';\n\nconst arrayRenderer: FieldRenderer = {\n name: 'array',\n render: /* @__PURE__ */ markNoWriteCallback((target, value, context) => {\n const element = target.element;\n if (isEmptyValue(value)) {\n element.textContent = '';\n return;\n }\n if (!Array.isArray(value)) return false;\n const template = target.arrayTemplate;\n if (template !== undefined && template.length > 0) {\n const html = renderTemplate(template, value);\n const policy = context.sanitizerPolicy;\n const templateOptions = templateSanitizeOptions(template);\n // Read before the write: the items about to be replaced are the only\n // record of what the server put on them.\n const shared = sharedItemAttributes(element);\n element.innerHTML = trustedHtml(sanitizeHtmlWithPolicy(html, policy, templateOptions));\n for (const item of Array.from(element.children)) inheritItemAttributes(item, shared);\n return;\n }\n element.textContent = value.map(safeStringify).join(target.arraySeparator ?? ', ');\n return;\n }),\n};\n\nfunction renderTemplate(template: string, items: readonly unknown[]): string {\n const knownKeys = collectTemplateKeys(items);\n let out = '';\n for (let i = 0; i < items.length; i += 1) {\n out += interpolateArrayTemplate(template, items[i], i, safeStringify, knownKeys);\n }\n return out;\n}\n\nexport { arrayRenderer };\n","/**\n * `structural-array` renderer (`data-payload-structural`): diffs the previous\n * and next item lists and patches the container through the keyed morph\n * (ADR 0008). All diff memory lives in the closure, one per client.\n */\n\nimport { safeConsoleWarn } from '@core/diagnostics';\nimport { markNoWriteCallback } from '@core/internal-outcome';\nimport {\n applyStructuralPatches,\n createStructuralStore,\n KEY_ATTRIBUTE,\n type StructuralStore,\n} from '@core/structural-applier';\nimport { diffArray } from '@schema/diff';\nimport type { FieldRenderer } from '@core/types';\nimport { isEmptyValue } from './utils';\n\ninterface StructuralRenderState {\n readonly values: readonly unknown[];\n readonly template: string;\n readonly domSnapshot: readonly (string | null)[];\n}\n\ntype WarnedCodes = WeakMap<Element, Set<string>>;\n\n/** @internal */\nexport function createStructuralArrayRenderer(): FieldRenderer {\n const states = new WeakMap<Element, StructuralRenderState>();\n const warnedContainers = new WeakSet<Element>();\n const warnedKeys: WarnedCodes = new WeakMap();\n const store: StructuralStore = createStructuralStore();\n\n return {\n name: 'structural-array',\n render: /* @__PURE__ */ markNoWriteCallback((target, rawValue, context) => {\n const value = isEmptyValue(rawValue) ? [] : rawValue;\n if (!Array.isArray(value)) return false;\n const container = target.element;\n const template = target.arrayTemplate;\n if (template === undefined || template.length === 0) {\n warnMissingTemplate(warnedContainers, container, target.fieldName);\n return false;\n }\n const previousState = states.get(container);\n const domSnapshot = readDomKeySnapshot(container);\n const previous = previousState?.values ?? valuesFromDomSnapshot(domSnapshot);\n const patches = diffArray(previous, value);\n const forceRender = needsForcedRender(previousState, template, domSnapshot);\n if (patches.length === 0 && !forceRender) {\n states.set(container, { values: value.slice(), template, domSnapshot });\n return false;\n }\n warnAboutKeys(warnedKeys, container, target.fieldName, previousState?.values, value);\n const applied = applyStructuralPatches({\n template,\n container,\n patches,\n nextItems: value,\n store,\n forceRender,\n sanitizerPolicy: context.sanitizerPolicy,\n onDuplicateKey: (owner, key) => {\n warnDuplicateKey(warnedKeys, owner, target.fieldName, key);\n },\n });\n if (applied === null) return false;\n states.set(container, {\n values: value.slice(),\n template,\n domSnapshot: readDomKeySnapshot(container),\n });\n return applied ? undefined : false;\n }),\n };\n}\n\nfunction needsForcedRender(\n previous: StructuralRenderState | undefined,\n template: string,\n domSnapshot: readonly (string | null)[],\n): boolean {\n if (previous === undefined) return true;\n return previous.template !== template || !sameDomKeySnapshot(previous.domSnapshot, domSnapshot);\n}\n\n// SSR markup exists before any in-memory snapshot; its direct-child keys let\n// the first update reconcile instead of appending a second copy.\nfunction readDomKeySnapshot(container: Element): readonly (string | null)[] {\n return Array.from(container.children, (child) => child.getAttribute(KEY_ATTRIBUTE));\n}\n\nfunction valuesFromDomSnapshot(snapshot: readonly (string | null)[]): readonly unknown[] {\n return snapshot.map((key, position) =>\n key === null ? { __payloadDomPosition: position } : { id: key },\n );\n}\n\nfunction sameDomKeySnapshot(\n previous: readonly (string | null)[],\n current: readonly (string | null)[],\n): boolean {\n if (previous.length !== current.length) return false;\n return previous.every((key, index) => key === current[index]);\n}\n\nfunction warnMissingTemplate(\n warnedContainers: WeakSet<Element>,\n container: Element,\n fieldName: string,\n): void {\n if (warnedContainers.has(container)) return;\n warnedContainers.add(container);\n safeConsoleWarn(\n `[live-preview] LP0403: Skipping structural update for \"${fieldName}\": ` +\n `<${container.tagName.toLowerCase()} data-payload-structural> needs ` +\n `data-payload-array-template (for example \"<li>{{label}}</li>\").`,\n );\n}\n\nfunction itemKey(value: unknown): string | undefined {\n if (typeof value !== 'object' || value === null) return undefined;\n const id = (value as Record<string, unknown>)['id'];\n return typeof id === 'string' || typeof id === 'number' ? String(id) : undefined;\n}\n\n/** Key problems degrade the morph, they do not break it; each is announced once per container (ADR 0008 §5). */\nfunction warnAboutKeys(\n warned: WarnedCodes,\n container: Element,\n fieldName: string,\n previous: readonly unknown[] | undefined,\n next: readonly unknown[],\n): void {\n const nextKeys = next.map(itemKey);\n const seen = new Set<string>();\n const duplicate = nextKeys.find((key) => {\n if (key === undefined) return false;\n if (seen.has(key)) return true;\n seen.add(key);\n return false;\n });\n if (duplicate !== undefined) warnDuplicateKey(warned, container, fieldName, duplicate);\n if (nextKeys.some((key) => key === undefined)) {\n warnOnce(\n warned,\n container,\n 'LP0404',\n `LP0404: an item of \"${fieldName}\" has no id and pairs by ` +\n 'position, so an insert re-renders every row after it. Give items a stable id.',\n );\n }\n if (previous?.length === next.length && next.length > 1) {\n const previousKeys = new Set(previous.map(itemKey).filter((key) => key !== undefined));\n const stable = nextKeys.some((key) => key !== undefined && previousKeys.has(key));\n if (previousKeys.size > 0 && !stable) {\n warnOnce(\n warned,\n container,\n 'LP0406',\n `LP0406: every key of \"${fieldName}\" changed at once; the ` +\n 'source generates ids per message, so no item can be retained across updates.',\n );\n }\n }\n}\n\n// Reached from the pre-diff check and from the morph's nested-slot check; one site, one message.\nfunction warnDuplicateKey(\n warned: WarnedCodes,\n owner: Element,\n fieldName: string,\n key: string,\n): void {\n warnOnce(\n warned,\n owner,\n 'LP0405',\n `LP0405: two items of \"${fieldName}\" share the key \"${key}\"; later ones pair by ` +\n 'position. Make `id` unique per item.',\n );\n}\n\nfunction warnOnce(warned: WarnedCodes, container: Element, code: string, message: string): void {\n let codes = warned.get(container);\n if (codes === undefined) {\n codes = new Set();\n warned.set(container, codes);\n }\n if (codes.has(code)) return;\n codes.add(code);\n safeConsoleWarn(`[live-preview] ${message}`);\n}\n","/**\n * Explicit renderer overrides, layered above the defaults each time a map is\n * built. The registry never retains the defaults, so stateful ones can be\n * recreated per client.\n */\n\nimport type { FieldRenderer, RendererKey } from '@core/types';\n\nconst builtinRenderers = new Map<RendererKey, FieldRenderer>();\n\nexport function buildBuiltinRenderers(\n defaults: readonly FieldRenderer[] = [],\n): Readonly<Record<string, FieldRenderer>> {\n const out: Record<string, FieldRenderer> = {};\n for (const renderer of defaults) out[renderer.name] = renderer;\n for (const [type, renderer] of builtinRenderers) out[type] = renderer;\n return Object.freeze(out);\n}\n\n/** Register or replace an override for maps built afterwards. */\nexport function registerBuiltinRenderer(renderer: FieldRenderer): void {\n builtinRenderers.set(renderer.name, renderer);\n}\n\n/** Test-only: clear the overrides. */\nexport function __resetBuiltinRenderersForTests(): void {\n builtinRenderers.clear();\n}\n","/** Built-in field renderers, assembled as values so `sideEffects: false` bundlers keep them all. */\n\nimport type { FieldRenderer } from '@core/types';\nimport { createTextRenderer } from './text';\nimport { richTextRenderer } from './rich-text';\nimport { htmlRenderer } from './html';\nimport { urlRenderer } from './url';\nimport { emailRenderer } from './email';\nimport { imageRenderer } from './image';\nimport { uploadRenderer } from './upload';\nimport { relationshipRenderer } from './relationship';\nimport { selectRenderer } from './select';\nimport { checkboxRenderer } from './checkbox';\nimport { dateRenderer } from './date';\nimport { numberRenderer } from './number';\nimport { arrayRenderer } from './array';\nimport { createStructuralArrayRenderer } from './structural-array';\nimport {\n buildBuiltinRenderers as buildRegistry,\n registerBuiltinRenderer,\n __resetBuiltinRenderersForTests,\n} from './registry';\nimport { reportOmittedFeature } from '@core/profile';\n\n/**\n * The array renderers carry the keyed morph, the structural applier and the item\n * templates — the largest optional cluster in the runtime. The lean profile\n * answers a page that needs them with LP0104 instead (@core/profile).\n */\nfunction arrayRenderers(): readonly FieldRenderer[] {\n return typeof __LEAN_BUILD__ !== 'undefined' && __LEAN_BUILD__\n ? [\n omittedRenderer('array', 'structural arrays'),\n omittedRenderer('blocks', 'structural arrays'),\n ]\n : [arrayRenderer, { ...arrayRenderer, name: 'blocks' }];\n}\n\n/** A renderer that only explains itself: the lean profile does not carry this field type. */\nfunction omittedRenderer(name: FieldRenderer['name'], feature: 'structural arrays'): FieldRenderer {\n return {\n name,\n render() {\n reportOmittedFeature(feature);\n },\n };\n}\n\n/** One renderer map per client; the stateful text and structural renderers are created fresh each call. @internal */\nexport function buildBuiltinRenderers(): Readonly<Record<string, FieldRenderer>> {\n // Built per call: a module-level table would pin every renderer into any\n // consumer importing an unrelated symbol from the root barrel.\n const stateless: readonly FieldRenderer[] = [\n richTextRenderer,\n htmlRenderer,\n urlRenderer,\n emailRenderer,\n imageRenderer,\n uploadRenderer,\n relationshipRenderer,\n selectRenderer,\n { ...selectRenderer, name: 'radio' },\n checkboxRenderer,\n dateRenderer,\n numberRenderer,\n ...arrayRenderers(),\n ];\n\n return buildRegistry([\n createTextRenderer('text'),\n createTextRenderer('textarea'),\n ...stateless,\n ...(typeof __LEAN_BUILD__ !== 'undefined' && __LEAN_BUILD__\n ? []\n : [createStructuralArrayRenderer()]),\n ]);\n}\n\nexport { registerBuiltinRenderer, __resetBuiltinRenderersForTests };\nexport type { PayloadMedia, PayloadRelationship } from './types';\n","/**\n * The two defaults profiles, row by row. 2.0 ships `v2`; `defaults: 'v1'` opts\n * back into the 1.x table for a staged migration. Each row belongs to exactly\n * one side — the adapter's request decision or the browser runtime — and a\n * test asserts the profile assigns every readiness row that has an option, so\n * a row added later cannot be forgotten. See ADR 0007.\n *\n * It lives in the leaf `types` domain, like `merge-depth.ts`, because the\n * inline generator resolves the profile too, and the generator is server-side\n * code that may not reach the browser runtime in `core`.\n */\n\n/** `'v2'` is the 2.0 default; `'v1'` is the 1.x table. */\nexport type DefaultsProfile = 'v1' | 'v2';\n\n/** How the runtime decides which windows may post updates. */\nexport type EventSourcePolicy = 'any' | 'parent-or-opener';\n\n/** Readiness rows that are options, keyed by the option they set. */\nexport const READINESS_ROWS = Object.freeze({\n strict: 'production response changes require an authorized context',\n previewSignals: 'query-only intent signal',\n disableReferrerDetection: 'referrer trust off',\n eventSourcePolicy: 'messages must come from parent/opener',\n skipUnchanged: 'skip unchanged bindings by default',\n sanitizerPolicy: 'hardened sanitizer id/data-* policy',\n} as const);\n\n/** Options an adapter's request decision reads from the profile. */\nexport interface AdapterProfileDefaults {\n readonly strict: boolean;\n readonly previewSignals: readonly ('query' | 'fetch-dest' | 'referer')[];\n}\n\n/** Options the browser runtime reads from the profile (through the inline configuration). */\nexport interface RuntimeProfileDefaults {\n readonly disableReferrerDetection: boolean;\n readonly eventSourcePolicy: EventSourcePolicy;\n readonly skipUnchanged: boolean;\n readonly sanitizerPolicy: 'compat' | 'strict';\n}\n\nexport const V2_ADAPTER_DEFAULTS: AdapterProfileDefaults = Object.freeze({\n strict: true,\n previewSignals: Object.freeze(['query'] as const),\n});\n\nexport const V2_RUNTIME_DEFAULTS: RuntimeProfileDefaults = Object.freeze({\n disableReferrerDetection: true,\n eventSourcePolicy: 'parent-or-opener',\n skipUnchanged: true,\n sanitizerPolicy: 'strict',\n});\n\n/** The 1.x table, spelled out so the profiles compare row by row. */\nexport const V1_ADAPTER_DEFAULTS: AdapterProfileDefaults = Object.freeze({\n strict: false,\n previewSignals: Object.freeze(['query', 'fetch-dest', 'referer'] as const),\n});\n\nexport const V1_RUNTIME_DEFAULTS: RuntimeProfileDefaults = Object.freeze({\n disableReferrerDetection: false,\n eventSourcePolicy: 'any',\n skipUnchanged: false,\n sanitizerPolicy: 'compat',\n});\n\n/** Only an explicit `'v1'` opts out; everything else gets the hardened rows. */\nexport function adapterDefaultsFor(profile: DefaultsProfile | undefined): AdapterProfileDefaults {\n return profile === 'v1' ? V1_ADAPTER_DEFAULTS : V2_ADAPTER_DEFAULTS;\n}\n\nexport function runtimeDefaultsFor(profile: DefaultsProfile | undefined): RuntimeProfileDefaults {\n return profile === 'v1' ? V1_RUNTIME_DEFAULTS : V2_RUNTIME_DEFAULTS;\n}\n","/**\n * `LivePreviewClient`: a `LivePreviewRuntime` with its own emitter, plugin\n * manager and renderer registry. A page that only needs a working preview uses\n * `generateInlineScript()` instead.\n */\n\nimport { assertMergeDepthExplicit } from '@/types/merge-depth';\nimport { LivePreviewRuntime, type RuntimeOptions } from '@core/lifecycle';\nimport type { LivePreviewInspection } from '@core/inspection/types';\nimport type { CachedElement, RendererKey } from '@core/types';\nimport { EventEmitter } from '@events/emitter';\nimport { OriginDetector } from '@detection/origin';\nimport { PluginManager } from '@plugins/manager';\nimport { RendererRegistry } from '@plugins/renderer-registry';\nimport type { LivePreviewPlugin } from '@plugins/types';\nimport { isDevMode, isInPreviewContext } from '@detection/environment';\nimport { buildBuiltinRenderers } from '@field-types/index';\nimport { definedOnly } from '@/types/defined-only';\nimport { withProfileDefaults, type LivePreviewClientConfig } from './config';\nimport { noopDiagnostic, safeConsoleDebug } from '@core/diagnostics';\n\n/** `T` with every property optional and `undefined`-able, for literals built from optional inputs. */\ntype Loose<T> = { readonly [K in keyof T]?: T[K] | undefined };\n\nfunction invert(value: boolean | undefined): boolean | undefined {\n return value === undefined ? undefined : !value;\n}\n\nexport class LivePreviewClient {\n readonly #emitter = new EventEmitter();\n readonly #detector: OriginDetector;\n readonly #rendererRegistry: RendererRegistry;\n readonly #runtime: LivePreviewRuntime;\n readonly #plugins: PluginManager;\n readonly #log: (...args: unknown[]) => void;\n #started = false;\n #destroyed = false;\n #tornDown = false;\n #destroyPromise: Promise<void> | null = null;\n\n constructor(rawConfig: LivePreviewClientConfig = {}) {\n const config = withProfileDefaults(rawConfig);\n const serverURL = config.serverURL ?? '';\n assertMergeDepthExplicit({\n defaults: rawConfig.defaults,\n serverURL,\n mergeDepth: config.mergeDepth,\n });\n const debug = config.debug ?? isDevMode();\n this.#log = debug\n ? (...args): void => {\n safeConsoleDebug('[live-preview]', ...args);\n }\n : noopDiagnostic;\n\n this.#detector = new OriginDetector(\n definedOnly({\n additionalOrigins: config.allowedOrigins,\n enableReferrerDetection: invert(config.disableReferrerDetection),\n enableLocalhostMatching: invert(config.disableLocalhostMatching),\n }),\n );\n\n if (this.#detector.isProductionUnconfigured) {\n this.#log('no trusted origin could be detected — set allowedOrigins');\n }\n\n this.#rendererRegistry = new RendererRegistry(buildBuiltinRenderers());\n\n this.#plugins = new PluginManager({\n events: this.#emitter,\n config: Object.freeze({ ...config }),\n registerFieldRenderer: (renderer) => this.#rendererRegistry.register(renderer),\n onTransformError: (error) => {\n void this.#emitter.emit('error', { error, context: 'transform', code: 'LP0602' });\n },\n log: this.#log,\n });\n\n this.#runtime = new LivePreviewRuntime(\n definedOnly({\n root: config.root,\n renderers: this.#rendererRegistry.renderers,\n resolveRenderer: (fieldType: RendererKey, target: CachedElement) =>\n config.resolveRenderer?.(fieldType, target) ?? this.#rendererRegistry.resolve(fieldType),\n renderRichText: config.renderRichText,\n sanitizerPolicy: config.sanitizerPolicy,\n transformValue: (\n fieldName: string,\n value: unknown,\n context: { readonly element: Element; readonly allFields: Record<string, unknown> },\n isCurrent?: () => boolean,\n ) => this.#plugins.applyTransforms(fieldName, value, context, isCurrent),\n originMatcher: (origin: string) => this.#detector.matches(origin),\n // Read per handshake, not once: after a lock, a bfcache restore must\n // re-broadcast to the locked origin alone, not every pre-lock candidate.\n readyTargets: () => this.#detector.enumerate(),\n emitter: this.#emitter,\n dataMerge:\n serverURL === ''\n ? undefined\n : definedOnly({\n serverURL,\n apiRoute: config.apiRoute,\n depth: config.mergeDepth,\n fetchFn: config.mergeFetch,\n }),\n debounceMs: config.debounceMs,\n heartbeatMs: config.heartbeatMs,\n intersectionRootMargin: config.intersectionRootMargin,\n scopeBindingsByOwner: config.scopeBindingsByOwner,\n skipUnchanged: config.skipUnchanged,\n revealEditedField: config.revealEditedField,\n autoBind: config.autoBind,\n eventSourcePolicy: config.eventSourcePolicy,\n dependencies: config.dependencies,\n strategies: config.strategies,\n disableVisibilityGate: config.disableVisibilityGate,\n visibilityGateThreshold: config.visibilityGateThreshold,\n enableA11y: config.enableA11y,\n a11yLocale: config.a11yLocale,\n onHeartbeatTimeout: () => {\n this.#detector.unlockOrigin();\n },\n lockedOrigin: () => this.#detector.lockedOrigin,\n validateToken: config.validateToken,\n log: this.#log,\n } satisfies Loose<RuntimeOptions>),\n );\n\n this.#emitter.on('connect', (e) => {\n this.#detector.lockOrigin(e.origin);\n });\n\n if (config.autoStart !== false) {\n this.start();\n }\n }\n\n /**\n * Start the runtime: `true` while eligible and started or scheduled for DOM\n * readiness, `false` once destroyed or outside a preview context.\n */\n start(): boolean {\n if (this.#destroyed) return false;\n if (this.#started) {\n // A deferred DOM-ready startup can fail after this returned and roll\n // itself back; this call retries it.\n this.#runtime.start();\n return true;\n }\n if (!isInPreviewContext()) return false;\n const started = this.#runtime.start();\n if (started) this.#started = true;\n return started;\n }\n\n /**\n * Release the message ingress, keeping plugins and renderers, for `pagehide`:\n * a bfcache restore re-runs no script, so an attached client would return\n * bound to a frozen page. `false` when nothing was running.\n */\n suspend(): boolean {\n if (this.#destroyed || !this.#started) return false;\n return this.#runtime.suspend();\n }\n\n /** Reacquire after `suspend()`: the same path as `start()`, because a restored document needs the same rebuild. */\n resume(): boolean {\n if (this.#destroyed || !this.#started) return false;\n return this.#runtime.start();\n }\n\n /** Stop the runtime and tear down every plugin. Idempotent; concurrent callers share one promise. */\n destroy(): Promise<void> {\n if (this.#destroyPromise !== null) return this.#destroyPromise;\n this.#destroyed = true;\n let resolveDestroy!: () => void;\n let rejectDestroy!: (reason: unknown) => void;\n const inFlight = new Promise<void>((resolve, reject) => {\n resolveDestroy = resolve;\n rejectDestroy = reject;\n });\n // Published before the teardown: a `destroy` handler calling destroy()\n // re-entrantly must get this same promise.\n this.#destroyPromise = inFlight;\n const finish = (): void => {\n this.#emitter.removeAllListeners();\n this.#tornDown = true;\n };\n try {\n this.#runtime.destroy();\n void this.#plugins.destroyAll().finally(finish).then(resolveDestroy, rejectDestroy);\n } catch (error) {\n finish();\n rejectDestroy(error);\n }\n return inFlight;\n }\n\n async use(plugin: LivePreviewPlugin): Promise<void> {\n if (this.#destroyed) throw new Error('LivePreviewClient: already destroyed');\n await this.#plugins.register(plugin);\n }\n\n /** Unregister a plugin and release everything its registration owned. Still allowed from a destroy hook during teardown. */\n async unuse(name: string): Promise<void> {\n if (this.#tornDown) throw new Error('LivePreviewClient: already destroyed');\n await this.#plugins.unregister(name);\n }\n\n refreshCache(): void {\n this.#runtime.refreshCache();\n }\n\n get events(): EventEmitter {\n return this.#emitter;\n }\n\n /** Names of the registered plugins. */\n get plugins(): readonly string[] {\n return this.#plugins.list();\n }\n\n get status(): 'disconnected' | 'connecting' | 'connected' {\n return this.#runtime.status;\n }\n\n /**\n * Point-in-time read of runtime state, no I/O: `bindings.orphanFields` when a\n * field refuses to update, `scheduler.deferred` when updates stop below the fold.\n */\n inspect(): LivePreviewInspection {\n return { ...this.#runtime.inspect(), plugins: this.#plugins.snapshot() };\n }\n\n /** Number of accepted updates so far. */\n get updateCount(): number {\n return this.#runtime.updateCount;\n }\n\n /** `true` once `destroy()` has been called. */\n get destroyed(): boolean {\n return this.#destroyed;\n }\n}\n\n/** A started client, or `null` when the page is not a preview context. */\nexport function initLivePreview(config: LivePreviewClientConfig = {}): LivePreviewClient | null {\n const client = new LivePreviewClient({ ...config, autoStart: false });\n return client.start() ? client : null;\n}\n\nexport type { LivePreviewClientConfig } from './config';\n","/**\n * Content-Security-Policy helpers: nonce generation, directive builders and\n * the header merge every adapter uses. Isomorphic; needs only Web Crypto.\n */\n\nconst DEFAULT_NONCE_BYTES = 16;\n\n/** CSP3's exact whitespace set: HTAB, LF, FF, CR, and SPACE. */\nconst CSP_ASCII_WHITESPACE = /[\\t\\n\\f\\r ]+/;\n\n/** Reads one code unit; an index past the end yields NaN, which matches nothing. */\nfunction isCspWhitespace(value: string, index: number): boolean {\n const code = value.charCodeAt(index);\n return code === 9 || code === 10 || code === 12 || code === 13 || code === 32;\n}\n\n/**\n * Trim CSP whitespace by scanning from both ends.\n *\n * The obvious `/^\\s+|\\s+$/` is superlinear by construction: for a long run the\n * trailing alternative is retried at every position. V8 happens to optimise the\n * shape away, but this header can come from a consumer's own response and this\n * module runs in every engine, so the guarantee has to come from the algorithm\n * rather than from one engine's optimiser.\n */\nfunction trimCspWhitespace(value: string): string {\n let start = 0;\n let end = value.length;\n while (start < end && isCspWhitespace(value, start)) start += 1;\n while (end > start && isCspWhitespace(value, end - 1)) end -= 1;\n return start === 0 && end === value.length ? value : value.slice(start, end);\n}\n\n/** CSP names are ASCII; Unicode case folding must not create directives. */\nfunction asciiLowercase(value: string): string {\n return value.replace(/[A-Z]/g, (character) => character.toLowerCase());\n}\n\n/** The one Web Crypto method this module calls; accepts Node's `webcrypto` without a cast. */\ninterface WebCryptoLike {\n getRandomValues: <T extends ArrayBufferView | null>(array: T) => T;\n}\n\nlet cryptoOverride: WebCryptoLike | undefined;\n\n/** Supply a Web Crypto implementation for runtimes without `globalThis.crypto`; `null` clears it. @internal */\nexport function setCspCrypto(crypto: WebCryptoLike | null): void {\n cryptoOverride = crypto ?? undefined;\n}\n\n/** A base64url nonce of `bytes` random bytes (default 16); throws without Web Crypto, since a predictable nonce silently defeats the CSP. @internal */\nexport function generateCspNonce(bytes: number = DEFAULT_NONCE_BYTES): string {\n if (!Number.isInteger(bytes) || bytes < 8) {\n throw new RangeError(`generateCspNonce: bytes must be an integer >= 8, got ${String(bytes)}`);\n }\n const crypto = resolveCrypto();\n if (!crypto) {\n throw new Error(\n 'generateCspNonce: Web Crypto is unavailable. On Node 18 call setCspCrypto(webcrypto) ' +\n \"once at startup, or run with --experimental-global-webcrypto. We won't fabricate \" +\n 'a predictable nonce — that would silently defeat the entire CSP.',\n );\n }\n const buffer = new Uint8Array(bytes);\n crypto.getRandomValues(buffer);\n return base64UrlEncode(buffer);\n}\n\nfunction resolveCrypto(): WebCryptoLike | undefined {\n if (cryptoOverride?.getRandomValues) return cryptoOverride;\n const fromGlobal = (globalThis as { crypto?: WebCryptoLike }).crypto;\n if (fromGlobal?.getRandomValues) return fromGlobal;\n return undefined;\n}\n\nfunction base64UrlEncode(bytes: Uint8Array): string {\n let binary = '';\n for (const byte of bytes) binary += String.fromCharCode(byte);\n const base64 = typeof btoa === 'function' ? btoa(binary) : Buffer.from(bytes).toString('base64');\n return base64.replaceAll('+', '-').replaceAll('/', '_').replaceAll('=', '');\n}\n\n/** A `frame-ancestors` source: `'self'`, `'none'`, or an origin. */\nexport type FrameAncestorSource = string;\n\nexport interface FrameAncestorsOptions {\n readonly self?: boolean;\n readonly origins?: readonly string[];\n readonly allowNone?: boolean;\n}\n\n/** The `frame-ancestors` value: `'self'` and the origins, deduplicated; `'none'` when empty. */\nexport function buildFrameAncestors(options: FrameAncestorsOptions = {}): string {\n const { self = true, origins = [], allowNone = false } = options;\n const seen = new Set<string>();\n const out: FrameAncestorSource[] = [];\n if (allowNone && !self && origins.length === 0) return \"'none'\";\n if (self) {\n out.push(\"'self'\");\n seen.add(\"'self'\");\n }\n for (const origin of origins) {\n const trimmed = origin.trim();\n if (trimmed.length === 0 || seen.has(trimmed)) continue;\n seen.add(trimmed);\n out.push(trimmed);\n }\n return out.length > 0 ? out.join(' ') : \"'none'\";\n}\n\n/**\n * A `script-src` value permitting one nonce plus optional extra sources.\n * `'strict-dynamic'` is opt-in: it makes CSP 3 browsers ignore `'self'` and\n * host sources, so every script on the page must then carry the nonce.\n * @internal\n */\nexport function buildScriptSrcWithNonce(\n nonce: string,\n options: {\n readonly self?: boolean;\n readonly extra?: readonly string[];\n readonly strictDynamic?: boolean;\n } = {},\n): string {\n if (nonce.length === 0) throw new RangeError('buildScriptSrcWithNonce: nonce is empty');\n const { self = true, extra = [], strictDynamic = false } = options;\n const parts: string[] = [];\n if (self) parts.push(\"'self'\");\n parts.push(`'nonce-${nonce}'`);\n if (strictDynamic) parts.push(\"'strict-dynamic'\");\n for (const e of extra) {\n const trimmed = e.trim();\n if (trimmed.length > 0) parts.push(trimmed);\n }\n return parts.join(' ');\n}\n\n/** `union` (default) adds sources to an existing directive; `replace` overwrites it. */\nexport interface CspDirectiveMerge {\n readonly value: string;\n readonly mode?: 'union' | 'replace';\n}\n\n/**\n * Merge directives into an existing `Content-Security-Policy` header value.\n * Commas separate policies (that is how `Headers.get()` joins repeated\n * headers); each is merged, because a browser enforces every policy and\n * widening only the last would leave the others blocking.\n */\nexport function mergeCspHeader(\n existing: string,\n additions: Readonly<Record<string, string | CspDirectiveMerge>>,\n): string {\n const policies = existing.split(',').filter((policy) => policy.trim().length > 0);\n if (policies.length === 0) return mergeCspPolicy('', additions);\n return policies.map((policy) => mergeCspPolicy(policy, additions)).join(', ');\n}\n\nfunction mergeCspPolicy(\n existing: string,\n additions: Readonly<Record<string, string | CspDirectiveMerge>>,\n): string {\n const directives = new Map<string, string>();\n for (const part of existing.split(';')) {\n const trimmed = trimCspWhitespace(part);\n if (trimmed.length === 0) continue;\n const whitespaceIndex = trimmed.search(CSP_ASCII_WHITESPACE);\n const name = asciiLowercase(whitespaceIndex < 0 ? trimmed : trimmed.slice(0, whitespaceIndex));\n // CSP3 §2.2.1: a user agent ignores later duplicates, so a looser\n // duplicate must not become the policy that is serialized.\n if (directives.has(name)) continue;\n const value = whitespaceIndex < 0 ? '' : trimCspWhitespace(trimmed.slice(whitespaceIndex));\n directives.set(name, value);\n }\n\n for (const [rawName, rawAddition] of Object.entries(additions)) {\n const name = asciiLowercase(rawName);\n const addition: CspDirectiveMerge =\n typeof rawAddition === 'string' ? { value: rawAddition } : rawAddition;\n const mode = addition.mode ?? 'union';\n const current = directives.get(name);\n if (mode === 'replace' || current === undefined || current.length === 0) {\n directives.set(name, addition.value);\n continue;\n }\n const seen = new Set<string>();\n const merged: string[] = [];\n for (const token of [\n ...current.split(CSP_ASCII_WHITESPACE),\n ...addition.value.split(CSP_ASCII_WHITESPACE),\n ]) {\n if (token.length === 0 || seen.has(token)) continue;\n seen.add(token);\n merged.push(token);\n }\n // `'none'` cannot coexist with other sources.\n const withoutNone = merged.filter((token) => token !== \"'none'\");\n directives.set(name, (withoutNone.length > 0 ? withoutNone : merged).join(' '));\n }\n\n const out: string[] = [];\n for (const [name, value] of directives) {\n out.push(value.length === 0 ? name : `${name} ${value}`);\n }\n return out.join('; ');\n}\n","/**\n * `LivePreviewClient` configuration. Defaults are the 2.0 rows; `defaults: 'v1'`\n * restores the 1.x values named per option (ADR 0007).\n */\n\nimport type { CachedElement, FieldRenderer, RendererKey, RichTextRenderer } from '@core/types';\nimport type { StrategyHandlers } from '@core/strategies';\nimport {\n runtimeDefaultsFor,\n type DefaultsProfile,\n type EventSourcePolicy,\n} from '@/types/defaults-profile';\n\nexport interface LivePreviewClientConfig {\n /** Explicit trusted admin origins. */\n readonly allowedOrigins?: readonly string[];\n /** Payload origin; every update is then re-fetched through the REST API so relations arrive populated. Requires `mergeDepth`. */\n readonly serverURL?: string;\n /** REST route prefix used with `serverURL`. Default `/api`. */\n readonly apiRoute?: string;\n /** Population depth used with `serverURL`. Required with it; `defaults: 'v1'` falls back to `1`. */\n readonly mergeDepth?: number;\n /** Custom fetch for the `serverURL` merge request: attach auth headers or route through a proxy. */\n readonly mergeFetch?: typeof fetch;\n /** Verbose console output. Defaults to dev-mode detection. */\n readonly debug?: boolean;\n /** Debounce window for incoming updates. Default 50 ms. */\n readonly debounceMs?: number;\n /** Heartbeat timeout in ms; `0` disables it (default), because the admin posts only on edits. */\n readonly heartbeatMs?: number;\n /** IntersectionObserver `rootMargin`. Default `200px`. */\n readonly intersectionRootMargin?: string;\n /** Update only bindings under a matching `data-payload-owner`; an unowned binding is then never updated. Default `false`. */\n readonly scopeBindingsByOwner?: boolean;\n /** Skip a binding whose value did not change. Default `true`; `defaults: 'v1'` sets `false`. */\n readonly skipUnchanged?: boolean;\n /** Scroll the preview to the field being edited when its value changes. Default `false`. */\n readonly revealEditedField?: boolean;\n /**\n * Find bindings by value on the connection's first message: a scalar whose\n * value is the whole content of exactly one element is bound to it as if\n * `data-payload-field` stood there; every guess is stamped `data-payload-guessed`\n * and listed in `inspect().bindings.guessed`. Default `'off'`.\n */\n readonly autoBind?: 'off' | 'unique';\n /** Fields whose change re-applies other bindings regardless of their own value: `{ price: ['priceLabel'] }`. Used with `skipUnchanged`. */\n readonly dependencies?: Readonly<Record<string, readonly string[]>>;\n /** Strategy handlers beyond patching; `createFragmentStrategy()` from `payload-live-preview/fragment` builds one. */\n readonly strategies?: StrategyHandlers;\n /** Apply every update regardless of visibility. Default `false`. */\n readonly disableVisibilityGate?: boolean;\n /** Cache size above which off-screen updates wait for intersection. Default `50`. */\n readonly visibilityGateThreshold?: number;\n /** Mount an `aria-live` region for connections, applied updates and heartbeat disconnects. Default `true`. */\n readonly enableA11y?: boolean;\n /** Locale of the announcement strings. Defaults to the detected locale. */\n readonly a11yLocale?: string;\n /** Document root. Default `document`. */\n readonly root?: Document | Element;\n /** Renderer resolution ahead of the registry; return `undefined` to fall through. */\n readonly resolveRenderer?: (\n fieldType: RendererKey,\n target: CachedElement,\n ) => FieldRenderer | undefined;\n /** The project's rich-text renderer, shared with SSR. Its output is sanitized. */\n readonly renderRichText?: RichTextRenderer;\n /** Ignore `document.referrer` as an origin source. Default `true`; `defaults: 'v1'` sets `false`. */\n readonly disableReferrerDetection?: boolean;\n /** Disable the dev-mode localhost matcher. Default `false`. */\n readonly disableLocalhostMatching?: boolean;\n /** Which windows may post updates. Default `'parent-or-opener'`; `defaults: 'v1'` sets `'any'`. */\n readonly eventSourcePolicy?: EventSourcePolicy;\n /**\n * Sanitizer policy for this client's rich text and HTML writes. Default\n * `'strict'`; `defaults: 'v1'` sets `'compat'`. Per instance: it leaves the\n * process default that `setSanitizerPolicy()` sets for direct `sanitizeHtml()` calls alone.\n */\n readonly sanitizerPolicy?: 'compat' | 'strict';\n /** `'v2'` (default) is the 2.0 table; `'v1'` restores every 1.x row at once. Explicit options win. */\n readonly defaults?: DefaultsProfile;\n /** Start the runtime in the constructor. Default `true`. */\n readonly autoStart?: boolean;\n /** Preview-token validator; every update must then carry a `previewToken` it approves. Stock Payload sends none. */\n readonly validateToken?: (\n token: string | undefined,\n origin: string,\n ) => boolean | Promise<boolean>;\n}\n\n/** The configuration with the `defaults` profile applied: explicit options win, `'v1'` changes nothing. */\nexport function withProfileDefaults(config: LivePreviewClientConfig): LivePreviewClientConfig {\n // `'v1'` fills the rows too: the runtime's own fallbacks are the 2.0 values\n // since the default flip, so leaving the config alone would hand a v1 client\n // the strict sanitizer and `skipUnchanged` it opted out of.\n const rows = runtimeDefaultsFor(config.defaults);\n return {\n ...config,\n skipUnchanged: config.skipUnchanged ?? rows.skipUnchanged,\n disableReferrerDetection: config.disableReferrerDetection ?? rows.disableReferrerDetection,\n eventSourcePolicy: config.eventSourcePolicy ?? rows.eventSourcePolicy,\n sanitizerPolicy: config.sanitizerPolicy ?? rows.sanitizerPolicy,\n };\n}\n","/**\n * The one rule shared by the adapters, the client and the inline generator:\n * `serverURL` needs an explicit `mergeDepth` under the 2.0 defaults (ADR 0007,\n * entry 10). It lives in the leaf `types` domain because the inline generator\n * is server-side code that may not reach the browser runtime in `core`, and\n * three copies of the check had already drifted in what they treated as\n * \"no server\" and \"no depth\".\n */\n\nimport type { DefaultsProfile } from '@/types/defaults-profile';\n\n/**\n * The population depth is a deliberate choice; the 1.x default of 1 stays only\n * behind `defaults: 'v1'`. An empty `serverURL` fetches nothing and owes no\n * depth; `null` counts as omitted because the inline wire config carries it.\n */\nexport function assertMergeDepthExplicit(options: {\n readonly defaults?: DefaultsProfile | undefined;\n readonly serverURL?: string | undefined;\n readonly mergeDepth?: number | null | undefined;\n}): void {\n if (options.defaults === 'v1') return;\n if ((options.serverURL ?? '') === '' || options.mergeDepth != null) return;\n throw new Error(\n 'payload-live-preview: `serverURL` needs an explicit `mergeDepth` under the 2.0 defaults — ' +\n \"choose the population depth deliberately (0 for none), or pass `defaults: 'v1'` to keep \" +\n 'the 1.x default of 1 while migrating (ADR 0007, entry 10).',\n );\n}\n","/**\n * The authorized preview context's shape and brand, in the leaf `types` domain\n * so producer and consumers recognise the same context. See ADR 0006.\n */\n\n/**\n * The brand key, in the type and on the object.\n *\n * This was a `unique symbol` until 2026-08-30. A `unique symbol` is nominal per\n * *declaration*, and the published entries each carry their own declaration\n * file — so `AuthorizedPreviewContext` from the root barrel was a different\n * type from the one in `./server` or in an adapter, and the documented flow\n * (authorize once, hand the context to the adapter hook and to the draft read)\n * did not type-check in any combination a consumer can write.\n *\n * That is the same trap the runtime brand below already avoids by using\n * `Symbol.for` rather than `Symbol()`; the lesson simply had not reached the\n * type. A shared string literal is identical in every bundle for the same\n * reason a registry symbol is.\n *\n * It is not what makes a context trustworthy. `isAuthorizedPreviewContext`\n * decides that, on the registry symbol and on `Object.isFrozen`, and every\n * consumption point calls it — the adapter policy, the draft read and the\n * binding emitter. Writing this key by hand buys nothing.\n */\nexport const AUTHORIZED_PREVIEW_BRAND_KEY = 'payload-live-preview.authorized-preview-context';\n\nexport type PreviewAuthorizationStrategyName = 'payload-session' | 'signed-token' | 'verifier';\n\n/** What a context is bound to; every field is optional because every strategy binds differently. */\nexport interface AuthorizedPreviewScope {\n /** The site origin the credential was issued for. */\n readonly audience?: string;\n /** The request pathname the credential is valid for. */\n readonly path?: string;\n readonly locale?: string;\n}\n\n/** The verdict of a successful `authorizePreviewRequest()`: frozen, branded, produced only there. Carry it, do not rebuild it. */\nexport interface AuthorizedPreviewContext {\n readonly [AUTHORIZED_PREVIEW_BRAND_KEY]: true;\n readonly strategy: PreviewAuthorizationStrategyName;\n /** The user id, token subject, or whatever the verifier named. */\n readonly subject: string | undefined;\n /** Unix milliseconds. */\n readonly authorizedAt: number;\n /** Unix milliseconds, or `undefined` when the strategy does not know. */\n readonly expiresAt: number | undefined;\n readonly scope: AuthorizedPreviewScope;\n /** The minimal request material a draft read forwards to Payload — one verified cookie, never the whole `Cookie` header. */\n readonly payloadHeaders: Readonly<Record<string, string>>;\n}\n\n// A registry symbol: entries are separate bundles, and a per-bundle `Symbol()`\n// would refuse the other's contexts in the package while unit tests passed.\nconst BRAND = Symbol.for(AUTHORIZED_PREVIEW_BRAND_KEY);\n\n/** Whether `value` was produced by `authorizePreviewRequest()`; a copy or JSON round trip is not. */\nexport function isAuthorizedPreviewContext(value: unknown): value is AuthorizedPreviewContext {\n return (\n typeof value === 'object' &&\n value !== null &&\n (value as Record<PropertyKey, unknown>)[BRAND] === true &&\n Object.isFrozen(value)\n );\n}\n\n/** Internal: the one place a context is made. */\nexport function createAuthorizedPreviewContext(\n fields: Omit<AuthorizedPreviewContext, typeof AUTHORIZED_PREVIEW_BRAND_KEY>,\n): AuthorizedPreviewContext {\n const context = Object.freeze({\n ...fields,\n scope: Object.freeze({ ...fields.scope }),\n payloadHeaders: Object.freeze({ ...fields.payloadHeaders }),\n [BRAND]: true,\n [AUTHORIZED_PREVIEW_BRAND_KEY]: true,\n });\n // No cast: the frozen object carries the brand key the interface declares.\n return context;\n}\n","/**\n * What each capability tells the runtime, for `inspect()` and consumer\n * diagnostics. Kept out of the runtime module so the inline bundle ships the\n * rules and not this prose. See ADR 0010.\n */\nimport type { ProtocolCapability } from './protocol-version';\n\nexport interface CapabilityDocumentation {\n /** The runtime behaviour that depends on the capability. */\n readonly gates: string;\n /** What the runtime does without it. */\n readonly fallback: string;\n}\n\nexport const CAPABILITY_DOCUMENTATION: Readonly<\n Record<ProtocolCapability, CapabilityDocumentation>\n> = {\n basic: {\n gates: 'data updates are applied to bound elements',\n fallback: 'none — every peer has it',\n },\n 'schema-json': {\n gates: 'field typing from fieldSchemaJSON (Payload 2.x) and the payload-2 profile',\n fallback: 'field types come from DOM heuristics and Lexical auto-detection',\n },\n locale: {\n gates:\n 'locale-aware field resolution (`title_de` before `title`) and the locale on island events',\n fallback: 'bindings resolve the unsuffixed field value',\n },\n 'preview-token': {\n gates: 'per-message token validation (library extension)',\n fallback: 'messages carry no token; validateToken cannot be satisfied',\n },\n 'nested-arrays': {\n gates: 'keyed array diffs below the top level',\n fallback: 'array updates replace the whole array',\n },\n 'recursive-diffs': {\n gates: 'recursive object diffs',\n fallback: 'nested objects re-render as a unit',\n },\n 'document-events': {\n gates: 'the `documentSave` runtime event, the document-save plugin and the payload-3 profile',\n fallback: 'no documentSave event; a save is not distinguishable from an edit',\n },\n 'relationship-events': {\n gates:\n 'the `relationshipUpdate` runtime event and an unconditional re-render of the update that carries it',\n fallback: 'a related document edited in a drawer shows up on the next data update only',\n },\n};\n","/**\n * The seam between a host framework's own router and the route strategy.\n *\n * The route strategy answers a revision by fetching the route and morphing it\n * into the living page. On a page whose DOM belongs to a reconciler that is\n * working against the framework, and it was seen to break once: `removeChild`\n * on `null` inside React's commit phase, over markup this package had patched.\n * A host that re-renders the route itself does the same job without the morph\n * and without the second HTML request, so it is given the chance to.\n *\n * Why a named slot on `window` and not a reference: the runtime is an inline\n * script that builds its strategy before any application code has hydrated, so\n * there is nothing to hand a component; `window.__livePreview`, the only other\n * public surface, is created later and not at all outside a preview; and the\n * two richer extension points — plugins and events — are reachable only through\n * the programmatic client, which a page using an adapter does not have. One\n * slot, written by whoever mounts and read at the moment of a refresh, is the\n * smallest thing that survives both orders of arrival.\n */\n\n/**\n * A host's own route refresh. It must settle once the fresh markup is\n * committed: the runtime re-applies the revision on top of it, and doing that\n * against the markup being replaced would write into nodes about to be dropped.\n */\nexport type RouteRefresh = () => void | Promise<void>;\n\n/** Read late, so it does not matter whether the runtime or the component came first. */\nconst SLOT = '__livePreviewRouteRefresh';\n\ntype WindowSlot = Record<string, RouteRefresh | undefined>;\n\nfunction slot(): WindowSlot | undefined {\n return typeof window === 'undefined' ? undefined : (window as unknown as WindowSlot);\n}\n\n/**\n * Lend the runtime the host's route refresh; the return value undoes it, for a\n * component's cleanup. A later registration wins, and undoing one that has\n * already been replaced does nothing — two components on one page would\n * otherwise take the slot from each other on unmount.\n */\nexport function registerRouteRefresh(refresh: RouteRefresh): () => void {\n const target = slot();\n if (target === undefined) return () => undefined;\n target[SLOT] = refresh;\n return () => {\n // Cleared rather than deleted: the slot is read through `?.` anyway, and\n // removing the key buys nothing a lint rule would not have to be argued out of.\n if (target[SLOT] === refresh) target[SLOT] = undefined;\n };\n}\n\n/** The registered refresh, or `undefined` on a page that registered none. */\nexport function readRouteRefresh(): RouteRefresh | undefined {\n return slot()?.[SLOT];\n}\n","/**\n * Every diagnostic code the runtime and tools emit, so a consumer can branch\n * on `e.code` instead of matching message text. A code is never reused for a\n * different meaning; a retired one stays reserved.\n *\n * Browser-side reporting sites write the literal (`code: 'LP0603'`) rather than\n * reading it from this record: the frozen table would then ship in the inline\n * runtime for the sake of six characters — it did, 1 287 B in every page, for\n * the one read Z6 left in the strategy runner, and `diagnostic-codes.test.ts`\n * now holds the artifact free of it. Server-side tools may import it.\n */\n\n/**\n * Every diagnostic code the runtime can report, by name.\n *\n * ```ts\n * client.events.on('error', (e) => {\n * if (e.code === DIAGNOSTIC_CODES.TransformThrew) reportToSentry(e.error);\n * });\n * ```\n */\nexport const DIAGNOSTIC_CODES = Object.freeze({\n /** No trusted origin configured in production; nothing will be accepted. */\n NoTrustedOrigin: 'LP0101',\n /** Origin trust rests on `document.referrer`, so any framing site is trusted. */\n ReferrerOnlyTrust: 'LP0102',\n /** A plugin declares a runtime range this runtime does not satisfy; it was refused. */\n PluginIncompatible: 'LP0103',\n /** The page carries the lean runtime and needs a feature that profile leaves out. */\n ProfileFeatureOmitted: 'LP0104',\n\n /** An update named a field with no binding anchor on the page. */\n OrphanField: 'LP0201',\n /** Owner scoping is on and the update names no document it could belong to. */\n UnattributableUpdate: 'LP0202',\n\n /** The visibility gate held offscreen writes back until they scroll into view. */\n VisibilityGateDeferred: 'LP0301',\n\n /** A value was refused because the attribute or the value itself is unsafe. */\n UnsafeAttributeWrite: 'LP0401',\n /** A text element has structured children, so replacing its text was skipped. */\n TextTargetHasChildren: 'LP0402',\n /** A structural container has no array template, so the update was skipped. */\n MissingArrayTemplate: 'LP0403',\n /** A structural item has no `id`; it pairs positionally, so an insert re-renders every row after it. */\n StructuralItemUnkeyed: 'LP0404',\n /** Two structural items share a key; later ones pair positionally. */\n StructuralDuplicateKey: 'LP0405',\n /** Every structural key changed while the length did not; the source generates keys per message. */\n StructuralUnstableKeys: 'LP0406',\n /** A binding asks for a delivery strategy this release does not have; it is left unchanged. */\n UnsupportedStrategy: 'LP0407',\n /** `data-payload-format` names a format the vocabulary does not contain; the default formatting was used instead. */\n UnknownValueFormat: 'LP0408',\n /** The strict sanitizer removed an attribute the 1.x `'compat'` policy kept. */\n SanitizerDroppedAttribute: 'LP0409',\n /** A Lexical block has no renderer; the markup the server rendered for it is kept instead. */\n UnrenderedBlockKept: 'LP0410',\n /** A patch cannot reach what the server would have drawn; `onUnfaithfulPatch` decided what happens next. */\n UnfaithfulPatch: 'LP0411',\n /** The first write to a date, number or checkbox binding replaced a different reading of the same value. */\n ServerFormatReplaced: 'LP0412',\n /** A Lexical block has no renderer, and the write could not keep the markup the server rendered for it; it is gone. */\n UnrenderedBlockLost: 'LP0413',\n\n /** A message was rejected before it reached the update pipeline. */\n MessageRejected: 'LP0501',\n /** A preview token was rejected. */\n TokenRejected: 'LP0502',\n /** A trusted origin sent a message this protocol version does not recognise. */\n ProtocolShapeUnknown: 'LP0503',\n\n /** A consumer event handler threw. */\n HandlerThrew: 'LP0601',\n /** A consumer transform threw; the original value was kept. */\n TransformThrew: 'LP0602',\n /** A renderer threw while writing a value. */\n RendererThrew: 'LP0603',\n // LP0604 is reserved and unassigned; codes are never reused or renumbered.\n /** Runtime startup failed. */\n StartupFailed: 'LP0605',\n /** Sending the ready handshake failed. */\n ReadyFailed: 'LP0606',\n /** The page declared hydration, but no React commit or Vue mount came within the cap; the runtime started without waiting. */\n HydrationWaitTimedOut: 'LP0607',\n\n /** The audit found no runtime in a response that carried preview intent. */\n AuditRuntimeMissing: 'LP0701',\n /** The preview response declares no `frame-ancestors`. */\n AuditNoFrameAncestors: 'LP0702',\n /** `X-Frame-Options` forbids framing, which no CSP can undo; `SAMEORIGIN` forbids it from another origin only. */\n AuditFrameOptionsBlocks: 'LP0703',\n /** Binding attributes are served to anonymous visitors. */\n AuditBindingsExposed: 'LP0704',\n /** More bindings than the default visibility gate will write eagerly. */\n AuditGateThresholdExceeded: 'LP0705',\n /** Owner markers exist, but some bindings are outside all of them. */\n AuditUnownedBindings: 'LP0706',\n /** The preview response carries no bindings at all. */\n AuditNoBindings: 'LP0707',\n /** The URL did not return an HTML page, so nothing else can be judged. */\n AuditNotAPage: 'LP0708',\n /** A fragment request failed (network, timeout, server error); the boundary was patched instead. */\n FragmentRequestFailed: 'LP0801',\n /** The fragment response had the wrong content type or shape; the boundary was patched instead. */\n FragmentResponseInvalid: 'LP0802',\n /** The fragment endpoint refused the preview (not authorized); the boundary was patched instead. */\n FragmentUnauthorized: 'LP0803',\n /** A fragment response arrived for a revision that was already superseded and was discarded. */\n FragmentSuperseded: 'LP0804',\n /** A route refresh was refused: the loop guard, or the strategy's minimum interval. */\n RouteRefreshLoop: 'LP0805',\n /** A boundary asks for the fragment strategy but no fragment handler is configured; it is patched. */\n FragmentStrategyUnavailable: 'LP0806',\n /** A revision changed a field with no binding; `onUnfaithfulPatch` refreshed the route. */\n UnboundChangeRefresh: 'LP0807',\n /** A readiness row is not yet at its 2.0 value; `pll doctor --v2` reports it. */\n V2ReadinessGap: 'LP0709',\n /** The preview runtime is served to anonymous visitors, not only inside the admin frame. */\n RuntimeOnPublicPage: 'LP0710',\n} as const);\n\n/** A diagnostic code, as it appears in log output and on the `error` event. */\nexport type DiagnosticCode = (typeof DIAGNOSTIC_CODES)[keyof typeof DIAGNOSTIC_CODES];\n","/**\n * Typed helpers emitting the `data-payload-*` attributes the runtime reads.\n * `bindByPath` records the path through a Proxy, so a rename follows.\n */\n\nimport type { FieldName } from './paths';\n\n/** A spreadable attribute record: `<h1 {...bind<Homepage>('heroTitle')}>`. */\nexport interface FieldBindingAttributes {\n readonly 'data-payload-field': string;\n readonly 'data-payload-attribute'?: string;\n readonly 'data-payload-type'?: string;\n readonly 'data-payload-richtext'?: string;\n readonly 'data-payload-html'?: string;\n readonly 'data-payload-locale'?: string;\n readonly 'data-payload-alt'?: string;\n readonly 'data-payload-href'?: string;\n readonly 'data-payload-array-template'?: string;\n}\n\nexport interface BindOptions {\n /** Attribute to write instead of the text content, e.g. `'src'` for `<img>`. */\n readonly attribute?: string;\n /** Explicit field type, bypassing schema detection. */\n readonly type?: string;\n /** Mark the binding as Lexical rich text; needed only when the initial render is empty. */\n readonly richtext?: boolean;\n /** Render the value as sanitised HTML rather than text. */\n readonly html?: boolean;\n /** Lock this element to one locale, overriding the message locale. */\n readonly locale?: string;\n /** Field whose value becomes the image `alt`. */\n readonly alt?: string;\n /** Field whose value becomes the link `href`. */\n readonly href?: string;\n /** Markup per array item with `{{value}}` placeholders. */\n readonly arrayTemplate?: string;\n}\n\n/** `bind<Homepage>('heroTitle')`; without `T` any string is accepted. */\nexport function bind<T = Record<string, unknown>>(\n field: FieldName<T>,\n options?: BindOptions,\n): FieldBindingAttributes {\n return buildAttributes(field, options);\n}\n\n/** `bindByPath<Homepage>(d => d.slides[0].title)` → `slides.title`; array indices are dropped because bindings resolve against the schema. */\n// `T` is used once, by design: the caller names the document type so the\n// picker is checked against it instead of against an untyped `d`.\n// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-parameters\nexport function bindByPath<T = Record<string, unknown>>(\n picker: (data: T) => unknown,\n options?: BindOptions,\n): FieldBindingAttributes {\n const path = recordPath(picker);\n if (path.length === 0) {\n throw new Error(\n 'bindByPath: the picker did not read any field — return data.<field> instead of a constant',\n );\n }\n return buildAttributes(path.join('.'), options);\n}\n\nfunction buildAttributes(field: string, options: BindOptions | undefined): FieldBindingAttributes {\n if (field.length === 0) {\n throw new Error('bind: field name must be a non-empty string');\n }\n const attrs: {\n 'data-payload-field': string;\n 'data-payload-attribute'?: string;\n 'data-payload-type'?: string;\n 'data-payload-richtext'?: string;\n 'data-payload-html'?: string;\n 'data-payload-locale'?: string;\n 'data-payload-alt'?: string;\n 'data-payload-href'?: string;\n 'data-payload-array-template'?: string;\n } = { 'data-payload-field': field };\n if (options?.attribute !== undefined) attrs['data-payload-attribute'] = options.attribute;\n if (options?.type !== undefined) attrs['data-payload-type'] = options.type;\n // Presence attributes: the runtime tests for the attribute, not its value.\n if (options?.richtext === true) attrs['data-payload-richtext'] = '';\n if (options?.html === true) attrs['data-payload-html'] = '';\n if (options?.locale !== undefined) attrs['data-payload-locale'] = options.locale;\n if (options?.alt !== undefined) attrs['data-payload-alt'] = options.alt;\n if (options?.href !== undefined) attrs['data-payload-href'] = options.href;\n if (options?.arrayTemplate !== undefined) {\n attrs['data-payload-array-template'] = options.arrayTemplate;\n }\n return attrs;\n}\n\nfunction recordPath(picker: (data: never) => unknown): string[] {\n const path: string[] = [];\n const proxy: unknown = new Proxy(\n {},\n {\n get(_target, prop: string | symbol): unknown {\n if (typeof prop === 'symbol') return undefined;\n if (/^\\d+$/.test(prop)) return proxy;\n path.push(prop);\n return proxy;\n },\n },\n );\n try {\n picker(proxy as never);\n } catch {\n // A picker doing math or JSX on the proxy throws after recording the path it meant.\n }\n return path;\n}\n","/**\n * Binding helpers gated on one authorization verdict per request: the\n * attributes publish the content model, so an unauthorized response carries\n * none and a binding is suppressed whole, never in part. See ADR 0006.\n */\n\nimport {\n isAuthorizedPreviewContext,\n type AuthorizedPreviewContext,\n} from '@/types/authorized-preview';\nimport { bind, bindByPath, type BindOptions, type FieldBindingAttributes } from './bind';\nimport type { FieldName } from './paths';\n\nexport interface OwnerBindingAttributes {\n readonly 'data-payload-owner': string;\n}\n\n/** The attributes marking a server-rendered boundary (ADR 0011, docs/hybrid.md). */\nexport interface FragmentBoundaryAttributes {\n readonly 'data-payload-fragment': string;\n readonly 'data-payload-fragment-key'?: string;\n readonly 'data-payload-depends'?: string;\n}\n\nexport interface FragmentBoundaryOptions {\n /** Distinguishes boundaries when one registry id renders several on a page. */\n readonly key?: string;\n /** The fields that re-render the boundary. Without it, every update does. */\n readonly dependsOn?: readonly string[];\n}\n\n/**\n * Stricter than the endpoint's own check, which accepts either case: an id is\n * written here, and one that only differs in case from the registry key is a\n * boundary that silently never renders.\n */\nconst REGISTRY_ID = /^[a-z][a-z0-9-]{0,63}$/u;\nconst MAX_KEY_LENGTH = 128;\n\n/** No attributes at all: an unauthorized response is byte-identical to one that never knew about live preview. */\nexport type SuppressedBinding = Readonly<Record<string, never>>;\n\nconst SUPPRESSED: SuppressedBinding = Object.freeze({});\n\n/** The verdict from `authorizePreviewRequest()`, or `null` for a public response. Only a branded context authorizes emission. */\nexport interface PreviewBindingsOptions {\n readonly authorization: AuthorizedPreviewContext | null;\n /** Document this subtree belongs to, emitted as `data-payload-owner`; needed with `scopeBindingsByOwner`. */\n readonly owner?: string;\n}\n\n/** Request-scoped binding helpers carrying one authorization decision. */\nexport interface PreviewBindings {\n readonly authorized: boolean;\n /** Typed field binding, or nothing while unauthorized. */\n bind: <T = Record<string, unknown>>(\n field: FieldName<T>,\n options?: BindOptions,\n ) => FieldBindingAttributes | SuppressedBinding;\n /** Rename-safe field binding, or nothing while unauthorized. */\n // `T` names the caller's document type; see bindByPath in ./bind.\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-parameters\n bindByPath: <T = Record<string, unknown>>(\n picker: (data: T) => unknown,\n options?: BindOptions,\n ) => FieldBindingAttributes | SuppressedBinding;\n /** Owner marker for this subtree, or nothing while unauthorized or without an owner. */\n owner: () => OwnerBindingAttributes | SuppressedBinding;\n /**\n * A server-rendered boundary, or nothing while unauthorized — the id and the\n * fields it depends on describe the content model as much as a binding does.\n * The registry behind `id` is the endpoint's (docs/hybrid.md).\n */\n boundary: (\n id: string,\n options?: FragmentBoundaryOptions,\n ) => FragmentBoundaryAttributes | SuppressedBinding;\n}\n\n/** Built whether or not the response is authorized, so a bad id fails everywhere, not only in preview. */\nfunction boundaryAttributes(\n id: string,\n options: FragmentBoundaryOptions,\n): FragmentBoundaryAttributes {\n if (!REGISTRY_ID.test(id)) {\n throw new RangeError(\n `createPreviewBindings().boundary(): \"${id}\" is not a registry id — lowercase, starting ` +\n 'with a letter, then letters, digits or hyphens (max 64). The runtime would post it and ' +\n 'the endpoint would refuse it.',\n );\n }\n const key = options.key;\n if (key !== undefined && (key.length === 0 || key.length > MAX_KEY_LENGTH)) {\n throw new RangeError(\n `createPreviewBindings().boundary(): the key for \"${id}\" must be 1 to ${String(MAX_KEY_LENGTH)} characters.`,\n );\n }\n const dependsOn = options.dependsOn ?? [];\n return {\n 'data-payload-fragment': id,\n ...(key !== undefined ? { 'data-payload-fragment-key': key } : {}),\n ...(dependsOn.length > 0 ? { 'data-payload-depends': dependsOn.join(',') } : {}),\n };\n}\n\n/** Request-scoped `bind`, `bindByPath` and `owner`, all suppressed unless `authorization` is a real context. */\nexport function createPreviewBindings(options: PreviewBindingsOptions): PreviewBindings {\n // A copied or hand-written context is a public response.\n const authorized = isAuthorizedPreviewContext(options.authorization);\n const owner = options.owner !== undefined && options.owner.length > 0 ? options.owner : undefined;\n\n return Object.freeze({\n authorized,\n bind: <T = Record<string, unknown>>(\n field: FieldName<T>,\n bindOptions?: BindOptions,\n ): FieldBindingAttributes | SuppressedBinding =>\n authorized ? bind<T>(field, bindOptions) : SUPPRESSED,\n // `T` names the caller's document type; see bindByPath in ./bind.\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-parameters\n bindByPath: <T = Record<string, unknown>>(\n picker: (data: T) => unknown,\n bindOptions?: BindOptions,\n ): FieldBindingAttributes | SuppressedBinding =>\n authorized ? bindByPath<T>(picker, bindOptions) : SUPPRESSED,\n owner: (): OwnerBindingAttributes | SuppressedBinding =>\n authorized && owner !== undefined ? { 'data-payload-owner': owner } : SUPPRESSED,\n boundary: (\n id: string,\n boundaryOptions: FragmentBoundaryOptions = {},\n ): FragmentBoundaryAttributes | SuppressedBinding => {\n const attributes = boundaryAttributes(id, boundaryOptions);\n return authorized ? attributes : SUPPRESSED;\n },\n });\n}\n","/**\n * Narrow public entry — the minimum API for sites that only need to\n * receive postMessage updates and apply them to the DOM.\n *\n * Consumers who import from `payload-live-preview/core`\n * get a bundle that **does not** include:\n *\n * - the built-in plugin constructors (`@plugins/built-in/*`)\n * - the inline-script generator and the embedded runtime source\n * - the framework adapters\n *\n * The client still includes its built-in field renderers, including Lexical\n * rendering. The omitted exports add weight without being needed on a typical\n * production page. The full entry (`payload-live-preview`) re-exports them for\n * users who want the convenience.\n *\n * @packageDocumentation\n */\n\nexport { VERSION } from './version';\n/** @internal */\nexport const CORE_ENTRY = true;\n\n// High-level client — without the heavyweight built-in plugins.\nexport { LivePreviewClient } from './client';\nexport { initLivePreview, type LivePreviewClientConfig } from './client';\n\n// Security primitives (consumers building their own CSP)\nexport {\n buildFrameAncestors,\n buildScriptSrcWithNonce,\n generateCspNonce,\n setCspCrypto,\n isSafeUrl,\n isExternalHttpUrl,\n sanitizeHtml,\n setSanitizerDocument,\n escapeHtml,\n escapeHtmlAttribute,\n type FrameAncestorsOptions,\n type SanitizerDocument,\n} from './security';\n\n// Events\nexport { EventEmitter } from './events';\nexport { type EventHandler, type LivePreviewEventMap, type Unsubscribe } from './events';\n\n// Detection helpers\nexport { OriginDetector } from './detection';\nexport {\n detectInitialLocale,\n isInIframe,\n isInPopup,\n isInPreviewContext,\n isDevMode,\n} from './detection';\n\n// Protocol negotiation — needed for any consumer that wants to branch\n// on capabilities.\nexport {\n LIBRARY_PROTOCOL_VERSION,\n hasCapability,\n negotiateProtocol,\n} from './core/protocol-version';\nexport type { ProtocolCapability, ProtocolNegotiation } from './core/protocol-version';\nexport { CAPABILITY_DECLARATIONS, PROTOCOL_CAPABILITIES } from './core/protocol-version';\nexport type { CapabilityDeclaration, CapabilitySource } from './core/protocol-version';\nexport { CAPABILITY_DOCUMENTATION } from './core/protocol-capability-docs';\nexport type { CapabilityDocumentation } from './core/protocol-capability-docs';\nexport { detectProtocolProfile } from './core/protocol-profile';\nexport type { ProtocolProfile, ProtocolProfileName } from './core/protocol-profile';\nexport type {\n InspectionBindings,\n InspectionOrigins,\n InspectionProtocol,\n InspectionRevisions,\n PluginInspection,\n InspectionFidelity,\n InspectionFragments,\n InspectionRoute,\n InspectionScheduler,\n LivePreviewInspection,\n} from './core/inspection/types';\nexport type {\n FragmentContext,\n FragmentReport,\n FragmentStrategy,\n RouteContext,\n RouteOutcome,\n RouteStrategy,\n StrategyHandlers,\n UpdateSource,\n} from './core/strategies';\nexport { registerRouteRefresh, type RouteRefresh } from './core/route-refresh';\nexport type { PayloadDocumentEventDetail } from './types/payload-protocol';\nexport { DIAGNOSTIC_CODES, type DiagnosticCode } from './core/diagnostic-codes';\nexport type { ConnectionStatus } from './core/state';\n\n// Typed binding DSL — small enough to live in the core slice\nexport { bind, bindByPath, createPreviewBindings } from './dsl';\nexport type { DefaultsProfile, EventSourcePolicy } from './types/defaults-profile';\n// The branded verdict `createPreviewBindings({ authorization })` accepts. The\n// producer (`authorizePreviewRequest`) lives on the root entry; the guard is a\n// few lines and belongs wherever the type is accepted.\nexport {\n AUTHORIZED_PREVIEW_BRAND_KEY,\n isAuthorizedPreviewContext,\n type AuthorizedPreviewContext,\n type AuthorizedPreviewScope,\n type PreviewAuthorizationStrategyName,\n} from './types/authorized-preview';\nexport type {\n BindOptions,\n FieldBindingAttributes,\n FieldName,\n FieldPath,\n FragmentBoundaryAttributes,\n FragmentBoundaryOptions,\n OwnerBindingAttributes,\n PreviewBindings,\n PreviewBindingsOptions,\n SuppressedBinding,\n ValueAt,\n} from './dsl';\n\n// Core types\nexport type {\n CachedElement,\n CustomRendererKey,\n FieldRenderer,\n FieldType,\n RenderContext,\n RendererKey,\n RichTextRenderer,\n} from './core/types';\n\n// Payload protocol types\nexport type {\n PayloadFieldCondition,\n PayloadFieldSchema,\n PayloadFieldType,\n PayloadLivePreviewData,\n PayloadLivePreviewMessage,\n} from './types/payload-protocol';\nexport type { PluginCompatibility } from './plugins';\nexport type { SanitizerPolicyMode } from './security';\n\n// Island interoperability — the bridge event and the boundary test (docs/renderers.md, islands).\nexport { ISLAND_EVENT, isInsideIsland, type IslandUpdateDetail } from './core/islands';\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"core.cjs","names":["VERSION","detectInitialLocale","document","lang","documentElement","getAttribute","length","readHtmlLang","navigator","language","readNavigatorLanguage","ELEMENT_ID","documentLeases","WeakMap","clearLeaseMessage","lease","timer","clearTimeout","messageNode","remove","A11yAnnouncer","german","constructor","locale","targetDocument","activeDocument","documentLocale","this","test","isGerman","mount","body","get","element","owned","refs","set","acquireDocumentLease","leased","isConnected","ownerDocument","getElementById","createElement","id","setAttribute","appendChild","announceConnected","say","announceDisconnected","announceUpdate","count","String","detach","delete","message","parentNode","createTextNode","hasChildNodes","data","previousSibling","setTimeout","parseFieldSchema","raw","Array","isArray","out","entry","parsed","parseFieldEntry","push","value","record","name","type","fields","blocks","slug","parseBlockSchema","result","optionalFieldOk","check","optionalTypeOk","isPlainObject","prototype","Object","getPrototypeOf","NULL_AS_ABSENT_FIELDS","CAPABILITY_DECLARATIONS","basic","since","observed","PROTOCOL_CAPABILITIES","keys","negotiateProtocol","theirs","sanitisedTheirs","Number","isFinite","Math","floor","effectiveTheirs","negotiated","min","seen","Set","capabilities","capability","has","add","ours","observeThenableResult","then","Promise","resolve","catch","sameRevision","a","b","generation","revision","MessageBus","matcher","handlers","boundListener","attachedTarget","queueHead","queueTail","attach","target","window","committed","listener","event","receive","origin","reportInvalid","resetQueue","addEventListener","error","removeEventListener","advanceGeneration","sendReady","targets","origins","payload","ready","protocolVersion","postMessage","matchesOrigin","matchesSource","v","x","isLivePreviewMessage","dispatchUpdate","normalized","field","Reflect","deleteProperty","fieldSchemaJSON","normalizeLivePreviewMessage","isDocumentEventMessage","invokeHandler","onDocumentEvent","focusFieldOf","onFocusField","hasUpdateData","isCurrentGeneration","messageRevision","validator","validateToken","commitUpdate","pending","verdict","next","enqueue","previewToken","settleValidation","approved","drainQueue","dequeue","onUpdate","reason","onInvalid","sourcePolicy","source","parent","opener","handler","args","expected","isolateDiagnostic","diagnostic","noopDiagnostic","safeConsoleError","console","safeConsoleWarn","warn","safeConsoleDebug","debug","HOW_TO_GET_IT","reported","reportOmittedFeature","feature","createA11y","options","__LEAN_BUILD__","enableA11y","refuseA11y","root","nodeType","isDocumentRoot","a11yLocale","buildA11y","defaultSendReady","Window","definedOnly","key","entries","STRUCTURAL_TYPES","buildSchemaIndex","schemas","basePath","Map","walk","schema","path","block","lookupSchema","index","fieldPath","wildcardPath","replace","getId","item","getBlockType","blockType","diffArray","prev","every","patches","prevIndexById","i","consumedFromPrev","to","kind","from","prevItem","shallowEqual","oldValue","diffById","diffByPosition","is","aRec","bRec","aKeys","bKeys","MAP","text","textarea","richText","email","number","checkbox","date","select","radio","array","group","tabs","row","collapsible","relationship","upload","point","json","code","ui","SAFE_PROTOCOLS","DANGEROUS_PROTOCOL_PATTERN","RELATIVE_PATH","PROTOCOL_RELATIVE","PARSER_IGNORED","isSafeUrl","url","trimmed","trim","startsWith","URL","protocol","isExternalHttpUrl","BLOCKED_ATTRIBUTES","URL_ATTRIBUTES","isWritableAttribute","resolveUnfaithfulPatchMode","onUnfaithfulPatch","onUnboundChange","reportUnfaithfulPatch","deps","state","reportedUnfaithful","unfaithfulCount","unfaithfulFields","fieldName","mode","log","unfaithfulPatches","reportUnboundChange","FORMATTING_RENDERERS","shownValue","tagName","textContent","excerpt","JSON","stringify","slice","noWriteCallbacks","WeakSet","markNoWriteCallback","callback","valueIdentity","FieldChangeTracker","previous","diff","dependencies","baseline","changed","identity","invalidated","dependents","dependent","reset","FRAGMENT_ATTRIBUTE","enclosingFragment","closest","resolveStrategy","explicit","collectionOwnerKey","documentId","nonEmpty","isBindingInScope","owner","includes","readDocumentId","SYSTEM_FIELD_NAMES","hasBinding","cache","ownerKeys","bindings","some","binding","hasBindingBelow","prefix","boundName","stripLocaleSuffix","suffix","endsWith","createFieldAddressability","localised","base","names","localisedBindingNames","unboundChangedFields","touched","isAddressable","unbound","SELF_SUFFICIENT_TYPES","NO_DEPENDENCIES","MergeNeed","rawChanges","resolved","queued","openUntil","decide","transaction","emitter","islands","listenerCount","values","rendersAReference","isPath","hrefField","srcField","altField","strategies","fragment","querySelector","readsPopulatedValues","merge","forceRender","verdictFor","schemaIndex","request","merger","windowMs","now","Date","dropQueued","leading","settle","promise","createPending","flush","recordMerged","doc","destroy","status","isScalar","namesAReference","fieldType","ProtocolTracker","negotiation","observe","fresh","filter","join","applyVersion","remoteVersion","current","owesForceRender","completed","RelationshipTracker","lastIdentity","edit","externallyUpdatedRelationship","entitySlug","updatedAt","isNew","previewedSlug","globalSlug","collectionSlug","previewedId","namesAnotherDocument","prefersReducedMotion","win","matchMedia","matches","FieldRevealer","lastField","reveal","rect","getBoundingClientRect","vertically","bottom","top","innerHeight","horizontally","right","left","innerWidth","isInViewport","scrollIntoView","behavior","revealElement","RevealLedger","note","slot","revealIdentities","revealTarget","commit","RuntimeState","started","suspended","deferredStart","hydration","activeUpdate","updateCount","supersededCount","completedCount","skippedUnchangedCount","lastFlush","absentFields","warnedOrphanFields","warnedStrategy","warnedUnattributableMessage","warnedVisibilityGate","warnedFragmentFallback","warnedProtocolShape","checkedServerFormat","escalatedCount","autoBindSearchMs","autoBindGuesses","warnedForeignSource","lastAppliedIdentity","revealLedger","fragmentStats","rendered","failed","superseded","routeStats","refreshes","refused","loopStopped","fragmentController","routeController","routeRetry","routeRefreshOwed","readyTimers","revealer","changes","merges","relationships","isRunning","isCurrent","complete","abortStrategies","controller","abort","BindingWriter","instanceContext","renderRichText","sanitizerPolicy","reportUnfaithful","apply","update","schemaEntry","renderer","schemaType","explicitFieldType","mapped","hasOwnProperty","call","payloadTypeToRenderer","resolveFieldType","children","looksLikeLexicalRoot","resolveRenderer","fail","emitElementUpdate","src","context","allFields","hidesWhenEmpty","toggleAttribute","isEmptyFieldValue","targetAttribute","attribute","toLowerCase","removeAttribute","stringValue","applyAttributeBinding","shown","format","watchServerFormatting","outcome","render","invokeRenderer","rendererUsesNoWriteOutcome","before","after","reportServerFormatting","emitWhile","previousValue","nextValue","receivedAt","applied","cause","Error","mergeDependencyMaps","maps","merged","map","bucket","dependencyMapFromBinding","dependsOn","ISLAND_EVENT","ISLAND_ATTRIBUTE","ISLAND_SELECTOR","islandAllowsPatching","island","isIslandBoundary","hasAttribute","isIslandRoot","isInsideIsland","parentElement","FIELD_ATTRIBUTE","TYPE_ATTRIBUTE","TARGET_ATTRIBUTE_ATTRIBUTE","HREF_ATTRIBUTE","SRC_ATTRIBUTE","ALT_ATTRIBUTE","ARRAY_TEMPLATE_ATTRIBUTE","ARRAY_SEPARATOR_ATTRIBUTE","LOCALE_ATTRIBUTE","RICH_TEXT_ATTRIBUTE","HTML_ATTRIBUTE","ARRAY_ATTRIBUTE","STRUCTURAL_ATTRIBUTE","OWNER_ATTRIBUTE","DEPENDS_ATTRIBUTE","STRATEGY_ATTRIBUTE","BOUNDARY_ATTRIBUTE","GUESSED_ATTRIBUTE","BINDING_ATTRIBUTES","FIELD_SELECTOR","OWNER_SELECTOR","resolveBindingOwner","CUSTOM_RENDERER_KEY","VALID_FIELD_TYPES","isRendererKey","ElementCache","entriesByField","entryByElement","islandRoots","alwaysTrue","dependencyMap","buildFromRoot","t0","performance","clear","elementCount","querySelectorAll","collectIslands","fieldCount","size","durationMs","resolveBinding","replaceEntry","removeEntry","append","getByElement","indexOf","splice","arrayTemplate","arraySeparator","split","parseDependencyList","strategy","guessed","fragmentBoundary","strategyKind","inputType","isPathSegment","maxLength","character","codePoint","codePointAt","hasControlCharacter","isSafeSlug","DataMerger","serverURL","apiRoute","depth","fetchFn","inflight","attempt","destroyDepth","end","withoutTrailingSlashes","route","canMerge","endpointOf","encodeURIComponent","endpoint","fetch","AbortController","response","method","credentials","headers","flattenLocales","signal","ok","PAYLOAD_2","fieldTyping","populatesRelationships","documentEvents","PAYLOAD_3","UNKNOWN","detectProtocolProfile","ObserverManager","callbacks","debounceMs","rootMargin","visible","mutation","intersection","debounceTimer","mutationDebounceMs","intersectionRootMargin","start","previousGeneration","stop","MutationObserver","mutations","handleMutations","IntersectionObserver","handleIntersection","threshold","childList","subtree","attributes","attributeFilter","disconnect","observeElement","unobserveElement","unobserve","markVisible","isVisible","m","attributeName","node","addedNodes","containsTrackedElement","removedNodes","hasStructuralImpact","onStructuralChange","isIntersecting","onVisibilityChange","BINDING_SELECTOR","signalSlot","w","armed","commits","onCommit","waiters","armReactCommitSignal","hook","__REACT_DEVTOOLS_GLOBAL_HOOK__","renderers","supportsFiber","inject","internals","installedHook","onCommitFiberRoot","rendererId","rest","container","containerInfo","waiter","forget","awaitSettled","onSettled","capMs","VUE_APP_PROPERTY","mountedApp","armVueMountSignal","proto","Element","getOwnPropertyDescriptor","defineProperty","configurable","app","writable","enumerable","live","nuxt","$nuxt","isHydrating","settleOnceHydrated","startAfterParse","host","startNow","later","startHydrated","HYDRATION_WAIT_CAP_MS","judge","ownsBindings","whenReactCommitted","mountedAround","whenVueMounted","defer","hydrated","HeartbeatTimer","timeoutMs","onTimeout","handle","lastKick","kick","lastKickAt","ConnectionState","markConnected","transition","markDisconnected","BOOLEAN_WORDS","NUMERIC","ENUM_TOKEN","LOCALE_CODE","SKIPPED_TAGS","isBindableValue","minLength","isRecord","bindableValues","claim","media","rawName","child","childValue","isBoundary","namespaceURI","editable","soleText","firstChild","nextSibling","isCandidateAttribute","search","hits","byElement","elements","byField","firstElementChild","nextElementSibling","textClaim","getAttributeNames","shape","tag","stamps","href","matched","alt","first","done","searchUnique","unique","candidates","candidate","searchRoot","adopt","when","adopted","observers","BLOCKED_KEYS","resolveFieldValue","preferLocale","localized","readOwn","direct","segment","object","bindingValue","fallbackLocale","bindingIdentity","own","siblings","combined","sibling","report","warned","isBindableScalar","SLOT","Symbol","for","trustedHtml","html","policy","policies","realm","globalThis","existing","created","shared","override","auto","api","trustedTypes","createPolicy","factory","createHTML","input","resolvePolicy","STATE_ATTRIBUTES","keyOf","keyAttributes","isMorphBoundary","morphElement","isMorphCompatible","focus","active","activeElement","HTMLElement","contains","selection","HTMLInputElement","HTMLTextAreaElement","selectionStart","selectionEnd","captureFocus","syncAttributes","retainChildrenOf","liveKeyed","keyed","duplicate","onDuplicateKey","indexKeyed","keyedElements","liveUnkeyed","childNodes","claimed","usedKeys","renderedNodes","cursor","unkeyedIndex","kept","reconcile","replaceWith","sameKind","replaceChild","following","isBlankText","insertBefore","morphChildren","snapshot","preventScroll","setSelectionRange","restoreFocus","nodeValue","Node","TEXT_NODE","reportDroppedAttribute","ALLOWED_TAGS","FORM_CONTROLS","REMOVE_COMPLETELY","ATTR_GLOBAL","ATTR_ARIA_PREFIX","ATTR_DATA_PREFIX","ATTR_BY_TAG","img","picture","audio","video","time","abbr","q","blockquote","table","th","td","col","colgroup","ol","li","pre","SanitizerEnvironmentError","TEMPLATE_ATTRIBUTES","DOCUMENT_SLOT","sanitizeHtml","sanitizeHtmlWithPolicy","resolveDocument","__INLINE_BUILD__","instancePolicy","attrMap","attrs","allowedTags","attrByTag","allowFormControls","templateMode","allowedData","allowed","additionalAllowedTags","forEach","additionalAllowedAttributes","attr","allowedDataAttributes","template","innerHTML","sanitizeFragment","content","sanitizeElement","tagAttrs","isSafeSrcset","sanitizeAttributes","anchor","hardenAnchor","HTML_ESCAPES","freeze","HTML_ESCAPE_PATTERN","escapeHtml","char","ATTR_ESCAPES","ATTR_ESCAPE_PATTERN","escapeHtmlAttribute","PLACEHOLDER_PATTERN","collectTemplateKeys","items","interpolateArrayTemplate","knownKeys","placeholder","hasOwn","sharedItemAttributes","everyItem","inheritItemAttributes","safeStringify","isEmptyValue","lruGet","lruSet","limit","oldest","lruTrim","TEMPLATE_EXTRA_TAGS","TEMPLATE_EXTRA_ATTRIBUTES","CUSTOM_TAG_PATTERN","optionsByTemplate","templateSanitizeOptions","cached","tags","match","matchAll","KEY_ATTRIBUTE","NESTED_KEY_ATTRIBUTE","NESTED_TEMPLATE_ATTRIBUTE","applyStructuralPatches","plan","prepareStructuralPlan","commitStructuralPlan","store","morph","isManagedNestedSlot","_live","env","nextItems","memory","templateKeys","initialChildren","keyedChildren","indexByAttribute","reserved","readKey","takeIndexedElement","replaces","renders","renderItem","nestedSlots","prepareNestedSlots","prepareReconciliation","patch","createPatchPlan","mutated","retained","liveSlot","renderedSlot","synchronizeAttributes","getMemory","rememberItem","oldItem","newItem","prevValue","oldSlotsByKey","findDirectNestedSlots","plans","newSlot","oldSlot","nextTemplate","previousTemplate","nextNested","readNestedArray","resolvedNext","templateChanged","ancestor","nested","indexed","pop","safe","warnFragmentFallback","warnUnsupportedStrategy","StrategyRunner","planFragments","planBoundaries","escalateUnfaithful","routeRefreshed","boundaries","boundary","coveringBoundaries","pendingFragments","runFragments","refreshRoute","hasUnboundChange","answered","hasRouteBinding","aborted","detail","cloneNode","morphFragment","patchFallback","restoreGuesses","scheduler","pendingCount","revealPending","updatedCount","runRoute","armRouteRetry","delayMs","stats","refresh","retryAfter","rebuildCache","reapply","schedule","transform","covered","covers","transformForBinding","originalValue","transformValue","transformed","returnedThenable","TypeError","err","emit","NOTHING_CHANGED","UpdatePipeline","createLeanStrategyRunner","scheduleAllFields","handleUpdate","heartbeat","observeCapabilities","relationshipEdit","timestamp","cancelled","acceptRevision","connection","a11y","processUpdate","resolveIncomingFields","dataFor","cancel","cancelRevision","applyFields","refined","autoBind","scope","ownerKeysForUpdate","folded","keep","adoptUniqueBindings","coalesced","mergeWindowMs","applyMerged","owed","trackIdentity","skipUnchanged","scheduled","revealEditedField","last","ownsAnyBinding","childName","diagnoseOrphanFields","notifyIslands","dispatchEvent","CustomEvent","bubbles","dispatchIslandUpdate","known","restoreUniqueBindings","scopeBindingsByOwner","collectionKey","messageOwnerKeys","onFlush","deferred","unfaithful","revealBinding","revealField","defaultView","UpdateScheduler","maxWaitMs","gateThresholdValue","gateDisabled","getCacheSize","scheduleFrame","cancelFrame","replay","activeFlushes","debounceToken","deadlineTimer","frameHandle","frameToken","windowUntil","activeRevision","activeRevisionCancelled","visibilityGateThreshold","disableVisibilityGate","requestAnimationFrame","bind","cancelAnimationFrame","armDebounce","cancelScheduledWork","clearWork","flushNow","notifyVisible","didApply","statsFor","retarget","retargetBuffer","replayCount","gateThreshold","gateActive","opensTheWindow","requestFrame","token","clearDeadline","appliedFields","batchEntry","buffer","READY_RETRY_DELAYS_MS","LivePreviewRuntime","pipeline","writer","rootSentinel","observedRoot","bus","originMatcher","eventSourcePolicy","dataMerge","heartbeatMs","onHeartbeatTimeout","readyTargets","lockedOrigin","readyState","onReady","once","startWhenReady","startupHost","rollbackFailedStart","step","reportError","observerRoot","readDocumentBody","watchRootReplacement","buildCacheAndObserve","delay","sendReadyAfterStart","suspend","wasConnected","release","runCleanup","cleanup","refreshCache","followReplacedRoot","inspect","fieldNames","owners","version","trusted","locked","sort","profile","revisions","accepted","skippedUnchanged","orphanFields","ownerScoped","localeCompare","searchMs","fidelity","escalated","fragments","inFlight","visibilityGateActive","plugins","buildInspection","removed","isIdleDisconnected","EventEmitter","regular","on","register","off","emitSequential","shouldContinue","eligible","invoke","removeAllListeners","eventNames","label","isInIframe","self","isInPopup","isInPreviewContext","isDevMode","nodeEnv","process","readNodeEnv","location","hostname","LOCALHOST_PATTERN","VALID_ORIGIN_PATTERN","LOCALHOST_HANDSHAKE_PORTS","OriginDetector","additionalOrigins","normalised","normaliseOrigin","referrerOrigin","enableReferrerDetection","referrer","allowLocalhost","enableLocalhostMatching","forceDevMode","lockOrigin","unlockOrigin","enumerate","port","referrerWasAvailable","isProductionUnconfigured","isReferrerOnlyTrust","noopDisposer","ResourceScope","pluginName","resources","assertOpen","track","acquire","finalize","disposed","stage","resource","dispose","activate","counts","subscription","close","reverse","ScopedPluginEvents","events","subscriptions","subscribe","untypedHandler","callerEligible","find","subscriptionActive","wrapped","async","PluginManager","config","registerRenderer","onTransformError","initializing","teardowns","destroying","transforms","mutationQueue","queuedHooks","registerFieldRenderer","plugin","registerNow","unregister","unregisterNow","destroyAll","destroyAllNow","applyTransforms","registrations","registration","list","describe","cleanups","incompatibility","compat","runtimeVersion","runtime","range","exec","parseVersion","alternative","comparators","part","comparator","operator","order","delta","compare","satisfiesComparator","satisfiesRange","isInteger","incompatibilityOf","refuse","createContext","runHook","init","registerTransform","registerCleanup","getConfig","existingTeardown","holdQueue","teardown","destroyPlugin","operation","RendererRegistry","layers","layer","stack","wasTop","previousLayer","at","previousRenderer","ALIGNMENT_NUMERIC","ALIGNMENT_STRING","resolveAlignment","fmt","resolveIndent","indent","dirAttribute","direction","layoutClassAttribute","align","classes","VALID_TAGS","asRecord","readMedia","sanitizeIdent","pickRelationLabel","title","BLANK_TARGET","linkRenderer","ctx","renderChildren","internalUrl","resolveUrl","titleAttr","extractText","dimensionAttributes","width","height","typeAttribute","mimeType","registry","lookupBlockRenderer","UNRENDERED_BLOCK_SELECTOR","renderBlockNode","baseClass","custom","onUnrenderedBlock","spanAttribute","BUILTIN_NODE_RENDERERS","paragraph","heading","tagRaw","listType","startAttr","checkAttr","listitem","valueAttr","link","autolink","quote","linebreak","horizontalrule","tab","mime","renderVideo","renderAudio","renderImage","filename","renderFallbackLink","relationTo","classAttr","inlineBlock","tablerow","tablecell","header","warnedNoSanitizer","isLexicalContent","renderNode","extractPlainText","createTextRenderer","warnedElements","toPlainString","hasForeignChildren","warnOnce","escapeAndLinebreak","warnedKept","warnedLost","WRAPPER_TAGS","richTextRenderer","unrendered","verdicts","className","wrapperOf","placeholders","pairs","pairUnrenderedBlocks","replaceChildren","writeKeepingUnrenderedBlocks","sanitize","warnNoSanitizerOnce","lexicalToHtml","placeholderClass","lost","reportUnrenderedBlock","liveChild","renderedChild","htmlRenderer","acceptUrl","createLinkRenderer","toHref","urlRenderer","HAS_SCHEME","emailRenderer","IMAGE_SOURCE_ATTRIBUTES","clearImage","writeImage","srcset","sizes","srcsetUrl","buildSrcset","imageRenderer","pickSource","pickAlt","style","backgroundImage","escapeCssUrl","uploadRenderer","relationshipRenderer","selectRenderer","toValues","checked","option","labelFor","multiple","selected","writeSelect","FALSE_STRINGS","checkboxRenderer","toBoolean","NUMBER_CACHE","DATE_CACHE","buildKey","localePart","serialised","stableStringify","parts","inner","DATE_STYLES","TIME_STYLES","CURRENCY_CODE","FRACTION_DIGITS","dateFormat","numberFormat","formatOptionsFor","spec","separator","argument","dateStyle","timeStyle","minimumFractionDigits","maximumFractionDigits","currency","toUpperCase","parseValueFormat","warnUnknownFormat","dateRenderer","valid","isNaN","getTime","fallback","toISOString","DEFAULT_DATE_OPTIONS","Intl","DateTimeFormat","getDateTimeFormat","formatDate","day","getFullYear","padStart","pad","getMonth","getDate","clock","getHours","getMinutes","formatForInput","numberRenderer","num","NumberFormat","getNumberFormat","arrayRenderer","renderTemplate","templateOptions","createStructuralArrayRenderer","states","warnedContainers","warnedKeys","rawValue","warnMissingTemplate","previousState","domSnapshot","readDomKeySnapshot","position","__payloadDomPosition","sameDomKeySnapshot","needsForcedRender","nextKeys","itemKey","warnDuplicateKey","previousKeys","stable","warnAboutKeys","codes","builtinRenderers","omittedRenderer","V2_RUNTIME_DEFAULTS","disableReferrerDetection","V1_RUNTIME_DEFAULTS","invert","cryptoOverride","LivePreviewClient","detector","rendererRegistry","destroyed","tornDown","destroyPromise","rawConfig","rows","defaults","withProfileDefaults","mergeDepth","assertMergeDepthExplicit","allowedOrigins","disableLocalhostMatching","stateless","buildBuiltinRenderers","mergeFetch","e","autoStart","resume","resolveDestroy","rejectDestroy","reject","finish","finally","use","unuse","AUTHORIZED_PREVIEW_BRAND_KEY","BRAND","isAuthorizedPreviewContext","isFrozen","DIAGNOSTIC_CODES","NoTrustedOrigin","ReferrerOnlyTrust","PluginIncompatible","ProfileFeatureOmitted","OrphanField","UnattributableUpdate","VisibilityGateDeferred","UnsafeAttributeWrite","TextTargetHasChildren","MissingArrayTemplate","StructuralItemUnkeyed","StructuralDuplicateKey","StructuralUnstableKeys","UnsupportedStrategy","UnknownValueFormat","SanitizerDroppedAttribute","UnrenderedBlockKept","UnfaithfulPatch","ServerFormatReplaced","UnrenderedBlockLost","MessageRejected","TokenRejected","ProtocolShapeUnknown","HandlerThrew","TransformThrew","RendererThrew","StartupFailed","ReadyFailed","HydrationWaitTimedOut","AuditRuntimeMissing","AuditNoFrameAncestors","AuditFrameOptionsBlocks","AuditBindingsExposed","AuditGateThresholdExceeded","AuditUnownedBindings","AuditNoBindings","AuditNotAPage","FragmentRequestFailed","FragmentResponseInvalid","FragmentUnauthorized","FragmentSuperseded","RouteRefreshLoop","FragmentStrategyUnavailable","UnboundChangeRefresh","V2ReadinessGap","RuntimeOnPublicPage","buildAttributes","bindByPath","picker","proxy","Proxy","_target","prop","recordPath","richtext","REGISTRY_ID","SUPPRESSED","gates","buildFrameAncestors","allowNone","buildScriptSrcWithNonce","nonce","RangeError","extra","strictDynamic","createPreviewBindings","authorized","authorization","bindOptions","boundaryOptions","boundaryAttributes","generateCspNonce","bytes","crypto","getRandomValues","fromGlobal","resolveCrypto","Uint8Array","binary","byte","fromCharCode","btoa","Buffer","toString","replaceAll","base64UrlEncode","hasCapability","initLivePreview","client","registerRouteRefresh","setCspCrypto","setSanitizerDocument"],"sources":["../package.json","../src/version.ts","../src/detection/locale.ts","../src/core/a11y.ts","../src/schema/parser.ts","../src/core/message-guards.ts","../src/core/protocol-version.ts","../src/core/thenable.ts","../src/core/message-bus.ts","../src/core/diagnostics.ts","../src/core/profile.ts","../src/core/runtime-wiring.ts","../src/types/defined-only.ts","../src/schema/walker.ts","../src/schema/diff.ts","../src/schema/field-type-map.ts","../src/security/url-validator.ts","../src/core/attribute-binding.ts","../src/core/fidelity.ts","../src/core/internal-outcome.ts","../src/core/value-identity.ts","../src/core/field-changes.ts","../src/core/strategies.ts","../src/core/binding-owner.ts","../src/core/unbound-fields.ts","../src/core/merge-need.ts","../src/core/protocol-tracker.ts","../src/core/relationship-tracker.ts","../src/core/reveal.ts","../src/core/reveal-ledger.ts","../src/core/runtime-state.ts","../src/core/binding-writer.ts","../src/core/dependencies.ts","../src/core/islands.ts","../src/core/cache.ts","../src/core/data-merger.ts","../src/core/protocol-profile.ts","../src/core/observers.ts","../src/core/hydration.ts","../src/core/hydration-vue.ts","../src/core/startup.ts","../src/core/state.ts","../src/core/auto-bind.ts","../src/core/field-value.ts","../src/core/orphan-diagnostics.ts","../src/security/trusted-types.ts","../src/core/morph.ts","../src/security/sanitizer-report.ts","../src/security/sanitizer.ts","../src/security/escape.ts","../src/core/array-template.ts","../src/field-types/utils.ts","../src/core/lru.ts","../src/core/template-sanitize.ts","../src/core/structural-applier.ts","../src/core/strategy-warnings.ts","../src/core/strategy-runner.ts","../src/core/transform-value.ts","../src/core/update-pipeline.ts","../src/core/strategy-runner-lean.ts","../src/core/update-scheduler.ts","../src/core/lifecycle.ts","../src/core/inspection/snapshot.ts","../src/events/emitter.ts","../src/detection/environment.ts","../src/detection/origin.ts","../src/plugins/resource-scope.ts","../src/plugins/scoped-events.ts","../src/plugins/manager.ts","../src/plugins/compat.ts","../src/plugins/renderer-registry.ts","../src/lexical/utils.ts","../src/lexical/nodes/paragraph.ts","../src/lexical/nodes/heading.ts","../src/lexical/value-shapes.ts","../src/lexical/nodes/link.ts","../src/lexical/nodes/code.ts","../src/lexical/nodes/upload.ts","../src/lexical/nodes/relationship.ts","../src/lexical/blocks/registry.ts","../src/lexical/nodes/block.ts","../src/lexical/nodes/table.ts","../src/lexical/nodes/builtin.ts","../src/lexical/nodes/text.ts","../src/lexical/types.ts","../src/lexical/nodes/list.ts","../src/lexical/nodes/quote.ts","../src/lexical/nodes/linebreak.ts","../src/lexical/registry.ts","../src/lexical/render.ts","../src/field-types/text.ts","../src/field-types/rich-text.ts","../src/field-types/html.ts","../src/field-types/unsafe-url.ts","../src/field-types/url.ts","../src/field-types/email.ts","../src/field-types/media.ts","../src/field-types/image.ts","../src/field-types/upload.ts","../src/field-types/relationship.ts","../src/field-types/select.ts","../src/field-types/checkbox.ts","../src/core/intl-cache.ts","../src/field-types/value-format.ts","../src/field-types/date.ts","../src/field-types/number.ts","../src/field-types/array.ts","../src/field-types/structural-array.ts","../src/field-types/registry.ts","../src/field-types/index.ts","../src/types/defaults-profile.ts","../src/client/index.ts","../src/security/csp.ts","../src/client/config.ts","../src/types/merge-depth.ts","../src/types/authorized-preview.ts","../src/core/protocol-capability-docs.ts","../src/core/route-refresh.ts","../src/core/diagnostic-codes.ts","../src/dsl/bind.ts","../src/dsl/preview-bindings.ts","../src/core-entry.ts"],"sourcesContent":["{\n \"name\": \"payload-live-preview\",\n \"version\": \"2.0.3\",\n \"description\": \"Live preview for Payload CMS on server-rendered and static frontends (Astro, Next.js, SvelteKit, Nuxt, plain HTML): DOM patches, server-rendered fragments, React and Vue hooks. Strict by default, zero dependencies.\",\n \"author\": \"relative23\",\n \"license\": \"MIT\",\n \"type\": \"module\",\n \"packageManager\": \"npm@12.0.2\",\n \"main\": \"./dist/index.cjs\",\n \"module\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\",\n \"exports\": {\n \".\": {\n \"import\": {\n \"types\": \"./dist/index.d.ts\",\n \"default\": \"./dist/index.js\"\n },\n \"require\": {\n \"types\": \"./dist/index.d.cts\",\n \"default\": \"./dist/index.cjs\"\n }\n },\n \"./core\": {\n \"import\": {\n \"types\": \"./dist/core.d.ts\",\n \"default\": \"./dist/core.js\"\n },\n \"require\": {\n \"types\": \"./dist/core.d.cts\",\n \"default\": \"./dist/core.cjs\"\n }\n },\n \"./astro\": {\n \"import\": {\n \"types\": \"./dist/adapters/astro/index.d.ts\",\n \"default\": \"./dist/adapters/astro/index.js\"\n }\n },\n \"./nextjs\": {\n \"import\": {\n \"types\": \"./dist/adapters/nextjs/index.d.ts\",\n \"default\": \"./dist/adapters/nextjs/index.js\"\n }\n },\n \"./sveltekit\": {\n \"import\": {\n \"types\": \"./dist/adapters/sveltekit/index.d.ts\",\n \"default\": \"./dist/adapters/sveltekit/index.js\"\n }\n },\n \"./nuxt\": {\n \"import\": {\n \"types\": \"./dist/adapters/nuxt/index.d.ts\",\n \"default\": \"./dist/adapters/nuxt/index.js\"\n }\n },\n \"./nuxt-module\": {\n \"import\": {\n \"types\": \"./dist/adapters/nuxt/module.d.ts\",\n \"default\": \"./dist/adapters/nuxt/module.js\"\n }\n },\n \"./react\": {\n \"import\": {\n \"types\": \"./dist/adapters/react/index.d.ts\",\n \"default\": \"./dist/adapters/react/index.js\"\n }\n },\n \"./vue\": {\n \"import\": {\n \"types\": \"./dist/adapters/vue/index.d.ts\",\n \"default\": \"./dist/adapters/vue/index.js\"\n }\n },\n \"./codegen\": {\n \"import\": {\n \"types\": \"./dist/codegen.d.ts\",\n \"default\": \"./dist/codegen.js\"\n },\n \"require\": {\n \"types\": \"./dist/codegen.d.cts\",\n \"default\": \"./dist/codegen.cjs\"\n }\n },\n \"./codegen/astro\": {\n \"import\": {\n \"types\": \"./dist/codegen-astro.d.ts\",\n \"default\": \"./dist/codegen-astro.js\"\n }\n },\n \"./annotate\": {\n \"import\": {\n \"types\": \"./dist/annotate.d.ts\",\n \"default\": \"./dist/annotate.js\"\n }\n },\n \"./doctor\": {\n \"import\": {\n \"types\": \"./dist/doctor.d.ts\",\n \"default\": \"./dist/doctor.js\"\n }\n },\n \"./migrate\": {\n \"import\": {\n \"types\": \"./dist/migrate.d.ts\",\n \"default\": \"./dist/migrate.js\"\n }\n },\n \"./payload\": {\n \"import\": {\n \"types\": \"./dist/payload.d.ts\",\n \"default\": \"./dist/payload.js\"\n },\n \"require\": {\n \"types\": \"./dist/payload.d.cts\",\n \"default\": \"./dist/payload.cjs\"\n }\n },\n \"./server\": {\n \"import\": {\n \"types\": \"./dist/server.d.ts\",\n \"default\": \"./dist/server.js\"\n },\n \"require\": {\n \"types\": \"./dist/server.d.cts\",\n \"default\": \"./dist/server.cjs\"\n }\n },\n \"./client\": {\n \"import\": {\n \"types\": \"./dist/client.d.ts\",\n \"default\": \"./dist/client.js\"\n },\n \"require\": {\n \"types\": \"./dist/client.d.cts\",\n \"default\": \"./dist/client.cjs\"\n }\n },\n \"./structural\": {\n \"import\": {\n \"types\": \"./dist/structural.d.ts\",\n \"default\": \"./dist/structural.js\"\n },\n \"require\": {\n \"types\": \"./dist/structural.d.cts\",\n \"default\": \"./dist/structural.cjs\"\n }\n },\n \"./lexical\": {\n \"import\": {\n \"types\": \"./dist/lexical.d.ts\",\n \"default\": \"./dist/lexical.js\"\n },\n \"require\": {\n \"types\": \"./dist/lexical.d.cts\",\n \"default\": \"./dist/lexical.cjs\"\n }\n },\n \"./plugins\": {\n \"import\": {\n \"types\": \"./dist/plugins.d.ts\",\n \"default\": \"./dist/plugins.js\"\n },\n \"require\": {\n \"types\": \"./dist/plugins.d.cts\",\n \"default\": \"./dist/plugins.cjs\"\n }\n },\n \"./lean\": {\n \"import\": {\n \"types\": \"./dist/lean.d.ts\",\n \"default\": \"./dist/lean.js\"\n },\n \"require\": {\n \"types\": \"./dist/lean.d.cts\",\n \"default\": \"./dist/lean.cjs\"\n }\n },\n \"./fragment\": {\n \"import\": {\n \"types\": \"./dist/fragment.d.ts\",\n \"default\": \"./dist/fragment.js\"\n },\n \"require\": {\n \"types\": \"./dist/fragment.d.cts\",\n \"default\": \"./dist/fragment.cjs\"\n }\n },\n \"./astro/RichText.astro\": \"./dist/adapters/astro/RichText.astro\",\n \"./astro/PreviewBoundary.astro\": \"./dist/adapters/astro/PreviewBoundary.astro\",\n \"./astro/middleware-entry\": {\n \"import\": {\n \"types\": \"./dist/adapters/astro/middleware-entry.d.ts\",\n \"default\": \"./dist/adapters/astro/middleware-entry.js\"\n }\n },\n \"./package.json\": \"./package.json\"\n },\n \"bin\": {\n \"pll-codegen\": \"./dist/codegen-cli.js\",\n \"pll\": \"./dist/doctor-cli.js\"\n },\n \"files\": [\n \"dist\",\n \"README.md\",\n \"LICENSE\"\n ],\n \"sideEffects\": false,\n \"scripts\": {\n \"build:runtime\": \"node -e \\\"const c=require('node:child_process'),e={...process.env};if(!e.SOURCE_DATE_EPOCH){const g=c.spawnSync('git',['show','-s','--format=%ct','HEAD'],{encoding:'utf8'});if(g.status===0)e.SOURCE_DATE_EPOCH=g.stdout.trim()}process.exit(c.spawnSync(process.execPath,['--import','tsx',process.argv[1]],{stdio:'inherit',env:e}).status??1)\\\" scripts/build-runtime.ts\",\n \"build\": \"npm run build:runtime && tsx scripts/build-dist.ts && npm run build:assets && npm run test:bundle && npm run test:treeshake && npm run test:edge && npm run test:interaction && npm run test:protocol-semantics\",\n \"build:assets\": \"node -e \\\"const fs=require('node:fs');for(const f of ['RichText','PreviewBoundary'])fs.copyFileSync('src/adapters/astro/'+f+'.astro','dist/adapters/astro/'+f+'.astro')\\\"\",\n \"dev\": \"tsup --watch\",\n \"pretest\": \"npm run build:runtime\",\n \"test\": \"vitest run\",\n \"test:watch\": \"vitest\",\n \"test:unit\": \"vitest run tests/unit\",\n \"test:integration\": \"vitest run tests/integration\",\n \"test:e2e\": \"playwright test\",\n \"check:fixtures\": \"tsx scripts/check-fixture-freshness.ts\",\n \"check:generated\": \"tsx scripts/check-generated-runtime.ts\",\n \"test:e2e:real-payload\": \"playwright test --config playwright.real-payload.config.ts\",\n \"test:a11y\": \"playwright test tests/e2e/specs/accessibility.spec.ts\",\n \"test:soak\": \"playwright test --config playwright.soak.config.ts\",\n \"test:browser-bench\": \"playwright test --config playwright.bench.config.ts\",\n \"test:bench\": \"vitest bench tests/benchmarks\",\n \"test:bench:codspeed\": \"vitest bench --run --config vitest.bench.config.ts\",\n \"test:bundle\": \"tsx scripts/check-bundle-size.ts\",\n \"test:interaction\": \"tsx scripts/check-interaction-budgets.ts\",\n \"test:protocol-semantics\": \"tsx scripts/check-protocol-semantics.ts\",\n \"test:upstream-findings\": \"tsx scripts/check-upstream-findings.ts\",\n \"test:treeshake\": \"tsx scripts/check-tree-shaking.ts\",\n \"test:edge\": \"NODE_OPTIONS='--experimental-vm-modules --no-warnings' tsx scripts/check-edge-runtime.ts\",\n \"compat:check\": \"tsx scripts/compat-table.ts --check\",\n \"compat:write\": \"tsx scripts/compat-table.ts --write\",\n \"compat:refresh\": \"tsx scripts/compat-table.ts --refresh\",\n \"diagnostics:check\": \"tsx scripts/diagnostic-table.ts --check\",\n \"test:package\": \"tsx scripts/check-package.ts\",\n \"audit:gate\": \"tsx scripts/audit-gate.ts\",\n \"test:smoke\": \"tsx scripts/post-publish-smoke.ts\",\n \"test:coverage\": \"vitest run --coverage\",\n \"test:coverage:diff\": \"tsx scripts/coverage-policy.ts\",\n \"test:policy\": \"tsx scripts/test-policy.ts\",\n \"test:architecture\": \"tsx scripts/architecture-policy.ts && tsx scripts/check-complexity.ts && tsx scripts/check-trusted-core.ts && tsx scripts/compare-scope.ts --check && tsx scripts/workflow-contracts.ts && tsx scripts/docs-contracts.ts && knip --no-progress --treat-config-hints-as-errors\",\n \"test:property\": \"vitest run tests/unit/property\",\n \"test:mutation\": \"stryker run stryker.config.js\",\n \"test:mutation:policy:pr\": \"tsx scripts/mutation-policy.ts --policy quality/mutation-policy-pr.json --report test-results/stryker-pr.json\",\n \"test:mutation:policy:core\": \"tsx scripts/mutation-policy.ts --policy quality/mutation-policy-core.json --report test-results/stryker-core.json\",\n \"test:mutation:policy\": \"tsx scripts/mutation-policy.ts\",\n \"test:leak\": \"node --expose-gc --import tsx scripts/leak-soak.ts\",\n \"test:leak:quick\": \"node --expose-gc --import tsx scripts/leak-soak.ts --quick\",\n \"api:update\": \"npm run build && tsx scripts/check-package.ts --update-api-reports\",\n \"typecheck\": \"tsc --noEmit\",\n \"lint\": \"eslint .\",\n \"lint:fix\": \"eslint . --fix\",\n \"format\": \"prettier --write \\\"src/**/*.ts\\\" \\\"tests/**/*.ts\\\" \\\"scripts/**/*.ts\\\" \\\"*.{js,cjs,mjs,ts,json,jsonc,yml,yaml,md}\\\" \\\"quality/**/*.json\\\" \\\"docs/**/*.md\\\" \\\"type-tests/**/*.md\\\" \\\".prettierrc.json\\\" \\\".changeset/*.{json,md}\\\" \\\".github/**/*.{yml,yaml,json}\\\" \\\"examples/**/*.{ts,tsx,js,cjs,mjs,json}\\\" && prettier --write \\\"type-tests/packed/*.fixture\\\" --parser typescript\",\n \"format:check\": \"prettier --check \\\"src/**/*.ts\\\" \\\"tests/**/*.ts\\\" \\\"scripts/**/*.ts\\\" \\\"*.{js,cjs,mjs,ts,json,jsonc,yml,yaml,md}\\\" \\\"quality/**/*.json\\\" \\\"docs/**/*.md\\\" \\\"type-tests/**/*.md\\\" \\\".prettierrc.json\\\" \\\".changeset/*.{json,md}\\\" \\\".github/**/*.{yml,yaml,json}\\\" \\\"examples/**/*.{ts,tsx,js,cjs,mjs,json}\\\" && prettier --check \\\"type-tests/packed/*.fixture\\\" --parser typescript\",\n \"check\": \"npm run typecheck && npm run lint && npm run format:check && npm run test:policy && npm run test:architecture && npm run compat:check && npm run diagnostics:check && npm run test\",\n \"prepublishOnly\": \"npm run build && npm run check && npm run format:check && npm run test:package\",\n \"changeset\": \"changeset\",\n \"version\": \"changeset version && tsx scripts/sync-lockfile-metadata.ts && npm run build:runtime\",\n \"release\": \"tsx scripts/publish-artifact.ts\",\n \"test:docs\": \"tsx scripts/docs-contracts.ts\"\n },\n \"devDependencies\": {\n \"@arethetypeswrong/cli\": \"^0.18.5\",\n \"@axe-core/playwright\": \"^4.13.0\",\n \"@changesets/cli\": \"^2.31.1\",\n \"@codspeed/vitest-plugin\": \"^5.7.1\",\n \"@eslint/js\": \"^10.0.1\",\n \"@fast-check/vitest\": \"^0.4.1\",\n \"@microsoft/api-extractor\": \"^7.58.12\",\n \"@payloadcms/live-preview\": \"^3.88.0\",\n \"@playwright/test\": \"^1.62.1\",\n \"@stryker-mutator/core\": \"^9.6.1\",\n \"@stryker-mutator/vitest-runner\": \"^9.6.1\",\n \"@testing-library/react\": \"^16.3.3\",\n \"@types/jsdom\": \"^30.0.0\",\n \"@types/node\": \"^22.20.1\",\n \"@types/react\": \"^19.2.18\",\n \"@types/react-dom\": \"^19.2.7\",\n \"@vitest/coverage-v8\": \"^4.1.11\",\n \"esbuild\": \"^0.28.2\",\n \"eslint\": \"^10.8.1\",\n \"fast-check\": \"^4.9.0\",\n \"globals\": \"^17.11.0\",\n \"jsdom\": \"^29.1.1\",\n \"knip\": \"^6.32.2\",\n \"prettier\": \"^3.9.6\",\n \"publint\": \"^0.3.23\",\n \"react\": \"^19.2.8\",\n \"react-dom\": \"^19.2.8\",\n \"terser\": \"^5.46.1\",\n \"ts-morph\": \"^28.0.0\",\n \"tsup\": \"^8.5.1\",\n \"tsx\": \"^4.23.12\",\n \"typescript\": \"^5.9.3\",\n \"typescript-eslint\": \"^8.67.0\",\n \"vite\": \"^7.3.6\",\n \"vitest\": \"^4.1.11\",\n \"vue\": \"^3.5.42\",\n \"yaml\": \"^2.9.0\"\n },\n \"overrides\": {\n \"qs\": \"6.15.3\",\n \"tsup\": {\n \"esbuild\": \"0.28.2\"\n }\n },\n \"allowScripts\": {\n \"esbuild@0.28.2\": true,\n \"fsevents@2.3.2\": false,\n \"fsevents@2.3.3\": false\n },\n \"keywords\": [\n \"astro\",\n \"astro-payload\",\n \"astro-cms\",\n \"astro-integration\",\n \"astro-live-preview\",\n \"payload\",\n \"payload-cms\",\n \"payload-live-preview\",\n \"live-preview\",\n \"preview\",\n \"cms\",\n \"headless\",\n \"headless-cms\",\n \"lexical\",\n \"sveltekit\",\n \"nuxt\",\n \"nextjs\",\n \"react\",\n \"vue\",\n \"ssr\",\n \"framework-agnostic\"\n ],\n \"peerDependencies\": {\n \"astro\": \">=4.0.0 <8.0.0\",\n \"react\": \">=18\",\n \"react-dom\": \">=18\",\n \"svelte\": \">=5\",\n \"ts-morph\": \"^28.0.0\",\n \"vite\": \">=5.4.0 <9.0.0\",\n \"vue\": \">=3.3\"\n },\n \"peerDependenciesMeta\": {\n \"astro\": {\n \"optional\": true\n },\n \"react\": {\n \"optional\": true\n },\n \"react-dom\": {\n \"optional\": true\n },\n \"svelte\": {\n \"optional\": true\n },\n \"ts-morph\": {\n \"optional\": true\n },\n \"vue\": {\n \"optional\": true\n },\n \"vite\": {\n \"optional\": true\n }\n },\n \"engines\": {\n \"node\": \">=20.19.0\"\n },\n \"publishConfig\": {\n \"access\": \"public\",\n \"provenance\": true\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"https://github.com/relative23/payload-live-preview.git\"\n },\n \"bugs\": {\n \"url\": \"https://github.com/relative23/payload-live-preview/issues\"\n },\n \"homepage\": \"https://github.com/relative23/payload-live-preview#readme\"\n}\n","/** The package version, read from package.json so the entries and the inline runtime cannot drift. */\n\nimport pkg from '../package.json' with { type: 'json' };\n\n/** @internal */\nexport const VERSION: string = pkg.version;\n","/** The locale for `Intl` renders before Payload names one: `<html lang>`, then `navigator.language`, then `'en'`. */\n\nconst FALLBACK_LOCALE = 'en';\n\n/** @internal */\nexport function detectInitialLocale(): string {\n return readHtmlLang() ?? readNavigatorLanguage() ?? FALLBACK_LOCALE;\n}\n\nfunction readHtmlLang(): string | undefined {\n if (typeof document === 'undefined') return undefined;\n const lang = document.documentElement.getAttribute('lang');\n return lang === null || lang.length === 0 ? undefined : lang;\n}\n\nfunction readNavigatorLanguage(): string | undefined {\n if (typeof navigator === 'undefined') return undefined;\n const lang = navigator.language;\n return typeof lang === 'string' && lang.length > 0 ? lang : undefined;\n}\n","/**\n * One polite `aria-live` region per document, leased by every announcer on\n * the page, for connect / update / disconnect announcements. The message\n * clears itself after a moment so a repeated string is heard again.\n */\n\nimport { detectInitialLocale } from '@detection/locale';\n\nconst ELEMENT_ID = 'payload-live-preview-a11y';\nconst CLEAR_DELAY_MS = 1500;\nconst STYLE =\n 'position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;' +\n 'clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0';\n\nfunction isGerman(locale: string): boolean {\n return /^de(?:[-_]|$)/i.test(locale);\n}\n\n/** Shared per document; reference-counted so one client cannot remove another's region. */\ninterface DocumentLease {\n element: HTMLElement | null;\n /** Created by this package (removable) rather than adopted from the page. */\n owned: boolean;\n messageNode: Text | null;\n refs: number;\n timer: ReturnType<typeof setTimeout> | null;\n}\n\nconst documentLeases = new WeakMap<Document, DocumentLease>();\n\nfunction acquireDocumentLease(activeDocument: Document): DocumentLease {\n let lease = documentLeases.get(activeDocument);\n if (lease === undefined) {\n lease = { element: null, owned: false, messageNode: null, refs: 0, timer: null };\n documentLeases.set(activeDocument, lease);\n }\n lease.refs += 1;\n return lease;\n}\n\n/** Remove only the package-owned message node, never consumer children. */\nfunction clearLeaseMessage(lease: DocumentLease): void {\n if (lease.timer !== null) {\n clearTimeout(lease.timer);\n lease.timer = null;\n }\n lease.messageNode?.remove();\n lease.messageNode = null;\n}\n\nexport class A11yAnnouncer {\n private readonly german: boolean;\n private readonly document: Document | null;\n private lease: DocumentLease | null = null;\n\n constructor(locale?: string, targetDocument?: Document | null) {\n const activeDocument = targetDocument ?? (typeof document === 'undefined' ? null : document);\n const documentLocale = activeDocument?.documentElement.getAttribute('lang') ?? '';\n this.german = isGerman(\n locale ?? (documentLocale.length > 0 ? documentLocale : detectInitialLocale()),\n );\n this.document = activeDocument;\n // The region mounts on the first announcement: a <head> inline script runs before `body` exists.\n }\n\n /** The shared region, or `null` without a body yet (announcements are then dropped). */\n private mount(): HTMLElement | null {\n const activeDocument = this.document;\n if (activeDocument?.body == null) return null;\n this.lease ??= acquireDocumentLease(activeDocument);\n const lease = this.lease;\n const leased = lease.element;\n if (leased?.isConnected && leased.ownerDocument === activeDocument) return leased;\n // The host removed or replaced the region between announcements.\n if (leased !== null) {\n const owned = lease.owned;\n clearLeaseMessage(lease);\n if (owned) leased.remove();\n }\n let element = activeDocument.getElementById(ELEMENT_ID);\n lease.owned = element === null;\n if (element === null) {\n element = activeDocument.createElement('div');\n element.id = ELEMENT_ID;\n element.setAttribute('role', 'status');\n element.setAttribute('aria-live', 'polite');\n element.setAttribute('aria-atomic', 'true');\n element.setAttribute('style', STYLE);\n activeDocument.body.appendChild(element);\n }\n lease.element = element;\n return element;\n }\n\n announceConnected(): void {\n this.say(this.german ? 'Vorschau verbunden' : 'Live preview connected');\n }\n\n announceDisconnected(): void {\n this.say(this.german ? 'Vorschau getrennt' : 'Live preview disconnected');\n }\n\n announceUpdate(count: number): void {\n if (count <= 0) return;\n this.say(\n this.german\n ? `${String(count)} ${count === 1 ? 'Änderung' : 'Änderungen'} angewendet`\n : `${String(count)} ${count === 1 ? 'change' : 'changes'} applied`,\n );\n }\n\n /** Release the lease; the last release removes an owned region but leaves an adopted one. Idempotent. */\n detach(): void {\n const lease = this.lease;\n const activeDocument = this.document;\n if (lease === null || activeDocument === null) return;\n this.lease = null;\n lease.refs -= 1;\n if (lease.refs > 0) return;\n const element = lease.element;\n if (element !== null) clearLeaseMessage(lease);\n if (lease.owned) element?.remove();\n lease.element = null;\n documentLeases.delete(activeDocument);\n }\n\n private say(message: string): void {\n const element = this.mount();\n const lease = this.lease;\n if (element === null || lease === null) return;\n let messageNode = lease.messageNode;\n if (messageNode?.parentNode !== element) {\n // A dedicated text node leaves consumer-owned children untouched.\n messageNode?.remove();\n messageNode = element.ownerDocument.createTextNode(\n element.hasChildNodes() ? ` ${message}` : message,\n );\n lease.messageNode = messageNode;\n element.appendChild(messageNode);\n } else {\n messageNode.data = messageNode.previousSibling === null ? message : ` ${message}`;\n }\n if (lease.timer !== null) clearTimeout(lease.timer);\n const timer = setTimeout(() => {\n if (lease.timer === timer && lease.element === element) clearLeaseMessage(lease);\n }, CLEAR_DELAY_MS);\n lease.timer = timer;\n }\n}\n","/**\n * Validates the `fieldSchemaJSON` the admin sends. Entries that fail\n * validation are dropped, never thrown: a Payload/runtime version mismatch\n * must not take the preview down.\n */\n\nimport type { PayloadBlockSchema, PayloadFieldSchema } from '@/types/payload-protocol';\n\nexport function parseFieldSchema(raw: unknown): readonly PayloadFieldSchema[] {\n if (!Array.isArray(raw)) return [];\n const out: PayloadFieldSchema[] = [];\n for (const entry of raw) {\n const parsed = parseFieldEntry(entry);\n if (parsed) out.push(parsed);\n }\n return out;\n}\n\nfunction parseFieldEntry(value: unknown): PayloadFieldSchema | undefined {\n if (typeof value !== 'object' || value === null) return undefined;\n const record = value as Record<string, unknown>;\n const name = record['name'];\n const type = record['type'];\n if (typeof name !== 'string' || name.length === 0) return undefined;\n if (typeof type !== 'string' || type.length === 0) return undefined;\n\n const fields = parseFieldSchema(record['fields']);\n const blocks = parseBlockSchema(record['blocks']);\n\n const result: Record<string, unknown> = { ...record, name, type };\n if (fields.length > 0) result['fields'] = fields;\n else delete result['fields'];\n if (blocks.length > 0) result['blocks'] = blocks;\n else delete result['blocks'];\n\n return result as unknown as PayloadFieldSchema;\n}\n\nfunction parseBlockSchema(raw: unknown): readonly PayloadBlockSchema[] {\n if (!Array.isArray(raw)) return [];\n const out: PayloadBlockSchema[] = [];\n for (const entry of raw) {\n if (typeof entry !== 'object' || entry === null) continue;\n const record = entry as Record<string, unknown>;\n const slug = record['slug'];\n if (typeof slug !== 'string' || slug.length === 0) continue;\n const fields = parseFieldSchema(record['fields']);\n out.push({ ...record, slug, fields });\n }\n return out;\n}\n","/** Shape guards for the messages the bus accepts. `null` counts as absent, as JSON bridges send it. */\n\nimport type {\n PayloadDocumentEventMessage,\n PayloadFieldSchema,\n PayloadLivePreviewMessage,\n} from '@/types/payload-protocol';\nimport { parseFieldSchema } from '@schema/parser';\n\nexport function isObjectMessage(value: unknown): value is { type: string } {\n return (\n typeof value === 'object' && value !== null && 'type' in value && typeof value.type === 'string'\n );\n}\n\n/** A `payload-live-preview` message: `data` a plain object when present, scalars of the right type or absent. */\nexport function isLivePreviewMessage(value: { type: string }): value is PayloadLivePreviewMessage {\n const v = value as Record<string, unknown>;\n if (v['data'] !== undefined && v['data'] !== null && !isPlainObject(v['data'])) return false;\n return (\n optionalTypeOk(v['fieldSchemaJSON'], (x) => Array.isArray(x)) &&\n optionalTypeOk(v['globalSlug'], (x) => typeof x === 'string') &&\n optionalTypeOk(v['collectionSlug'], (x) => typeof x === 'string') &&\n optionalTypeOk(v['locale'], (x) => typeof x === 'string') &&\n optionalTypeOk(v['ready'], (x) => typeof x === 'boolean') &&\n optionalTypeOk(v['previewToken'], (x) => typeof x === 'string') &&\n optionalTypeOk(v['protocolVersion'], (x) => typeof x === 'number')\n );\n}\n\n/** The non-empty field name of a `payload-live-preview-focus` message, else `undefined`. */\nexport function focusFieldOf(value: { type: string }): string | undefined {\n const field = (value as Record<string, unknown>)['field'];\n return typeof field === 'string' && field.length > 0 ? field : undefined;\n}\n\n/** Stock Payload sends only the `type`; custom senders may add the typed fields (omitted, never `null`). */\nexport function isDocumentEventMessage(value: {\n type: string;\n}): value is PayloadDocumentEventMessage {\n const v = value as Record<string, unknown>;\n return (\n optionalFieldOk(v['action'], (x) => x === 'updated' || x === 'created' || x === 'deleted') &&\n optionalFieldOk(v['slug'], (x) => typeof x === 'string') &&\n optionalFieldOk(v['id'], (x) => typeof x === 'string' || Number.isFinite(x))\n );\n}\n\nfunction optionalFieldOk(value: unknown, check: (v: unknown) => boolean): boolean {\n return value === undefined || check(value);\n}\n\nfunction optionalTypeOk(value: unknown, check: (v: unknown) => boolean): boolean {\n return value === undefined || value === null || check(value);\n}\n\nexport function isPlainObject(value: unknown): value is Record<string, unknown> {\n if (typeof value !== 'object' || value === null) return false;\n const prototype = Object.getPrototypeOf(value) as object | null;\n return prototype === null || Object.getPrototypeOf(prototype) === null;\n}\n\nconst NULL_AS_ABSENT_FIELDS = [\n 'data',\n 'fieldSchemaJSON',\n 'globalSlug',\n 'collectionSlug',\n 'locale',\n 'ready',\n 'previewToken',\n 'protocolVersion',\n] as const satisfies readonly (keyof PayloadLivePreviewMessage)[];\n\n/**\n * Drop `null` optionals so downstream sees the strict public type, and parse\n * the field schema entry by entry (malformed entries are dropped). Unknown\n * fields stay, for protocol evolution.\n */\nexport function normalizeLivePreviewMessage(\n message: PayloadLivePreviewMessage,\n): PayloadLivePreviewMessage {\n const normalized = { ...message };\n for (const field of NULL_AS_ABSENT_FIELDS) {\n const wireValue: unknown = Reflect.get(normalized, field);\n if (wireValue === null) Reflect.deleteProperty(normalized, field);\n }\n if (!Array.isArray(normalized.fieldSchemaJSON)) return normalized;\n let fieldSchemaJSON: readonly PayloadFieldSchema[];\n try {\n fieldSchemaJSON = parseFieldSchema(normalized.fieldSchemaJSON);\n } catch {\n fieldSchemaJSON = [];\n }\n return { ...normalized, fieldSchemaJSON };\n}\n","/**\n * Protocol negotiation. A capability is granted either by the version a peer\n * announces or by observation, since the stock Payload admin announces none:\n * what it can do is read off the messages it sends. See ADR 0010.\n */\n\n/** Bumped only when this library's understanding of the wire format changes. @internal */\nexport const LIBRARY_PROTOCOL_VERSION = 4;\n\n/** How a capability becomes active. @internal */\nexport type CapabilitySource = 'version' | 'observed';\n\n/** @internal */\nexport interface CapabilityDeclaration {\n /** Enabled once the negotiated version reaches this (for announced peers). */\n readonly since: number;\n /** The wire signal that grants this capability to a peer announcing no version. */\n readonly observed?:\n 'schema' | 'locale' | 'preview-token' | 'document-event' | 'relationship-event';\n}\n\n/** What activates each capability; the prose lives in `CAPABILITY_DOCUMENTATION`. */\nexport const CAPABILITY_DECLARATIONS = {\n basic: { since: 1 },\n 'schema-json': { since: 2, observed: 'schema' },\n locale: { since: 2, observed: 'locale' },\n 'preview-token': { since: 3, observed: 'preview-token' },\n 'nested-arrays': { since: 4 },\n 'recursive-diffs': { since: 4 },\n 'document-events': { since: 4, observed: 'document-event' },\n 'relationship-events': { since: 4, observed: 'relationship-event' },\n} as const satisfies Record<string, CapabilityDeclaration>;\n\nexport type ProtocolCapability = keyof typeof CAPABILITY_DECLARATIONS;\n\n/** Every declared capability, in declaration order. @internal */\nexport const PROTOCOL_CAPABILITIES = Object.keys(\n CAPABILITY_DECLARATIONS,\n) as readonly ProtocolCapability[];\n\nexport interface ProtocolNegotiation {\n /** This library's protocol version. */\n readonly ours: number;\n /** The remote party's version, when it announced one. */\n readonly theirs: number | undefined;\n /** `min(ours, theirs ?? 1)` — the version both sides actually share. */\n readonly negotiated: number;\n /** Capabilities active at the negotiated version or seen on the wire. */\n readonly capabilities: ReadonlySet<ProtocolCapability>;\n /** The subset that was observed on the wire rather than granted by version. */\n readonly observed: ReadonlySet<ProtocolCapability>;\n}\n\n/** Deterministic; the runtime re-runs it whenever either input changes. */\nexport function negotiateProtocol(\n theirs: number | undefined,\n observed: Iterable<ProtocolCapability> = [],\n): ProtocolNegotiation {\n const sanitisedTheirs =\n typeof theirs === 'number' && Number.isFinite(theirs) && theirs >= 1\n ? Math.floor(theirs)\n : undefined;\n const effectiveTheirs = sanitisedTheirs ?? 1;\n const negotiated = Math.min(LIBRARY_PROTOCOL_VERSION, effectiveTheirs);\n const seen = new Set<ProtocolCapability>(observed);\n const capabilities = new Set<ProtocolCapability>();\n for (const capability of PROTOCOL_CAPABILITIES) {\n if (negotiated >= CAPABILITY_DECLARATIONS[capability].since || seen.has(capability)) {\n capabilities.add(capability);\n }\n }\n return {\n ours: LIBRARY_PROTOCOL_VERSION,\n ...(sanitisedTheirs !== undefined ? { theirs: sanitisedTheirs } : { theirs: undefined }),\n negotiated,\n capabilities,\n observed: seen,\n };\n}\n\n/** @internal */\nexport function hasCapability(\n negotiation: ProtocolNegotiation,\n capability: ProtocolCapability,\n): boolean {\n return negotiation.capabilities.has(capability);\n}\n\n/** The capabilities a single message demonstrates, by its shape alone. */\nexport function observeCapabilities(message: {\n readonly fieldSchemaJSON?: unknown;\n readonly locale?: unknown;\n readonly previewToken?: unknown;\n readonly externallyUpdatedRelationship?: unknown;\n}): readonly ProtocolCapability[] {\n const seen: ProtocolCapability[] = [];\n if (Array.isArray(message.fieldSchemaJSON)) seen.push('schema-json');\n if (typeof message.locale === 'string') seen.push('locale');\n if (typeof message.previewToken === 'string') seen.push('preview-token');\n if (\n typeof message.externallyUpdatedRelationship === 'object' &&\n message.externallyUpdatedRelationship !== null\n ) {\n seen.push('relationship-events');\n }\n return seen;\n}\n","/**\n * Detect an invalid async result in a synchronous extension point.\n *\n * Rejected native Promises otherwise become unhandled after the caller falls\n * back synchronously. Assimilating the result through a handled Promise keeps\n * that contract violation observable only through the runtime's explicit\n * error channel.\n */\nexport function observeThenableResult(value: unknown): boolean {\n if ((typeof value !== 'object' || value === null) && typeof value !== 'function') return false;\n if (typeof (value as { readonly then?: unknown }).then !== 'function') return false;\n void Promise.resolve(value).catch(() => undefined);\n return true;\n}\n","/**\n * postMessage ingress: origin and source checks, per-type shape guards, the\n * ordered preview-token validation queue, and the `ready` handshake. The bus\n * never throws; a rejected message is dropped or reported via `onInvalid`.\n * Consumer callbacks may detach or re-attach the bus synchronously, so\n * anything that runs after one re-checks the generation it started in.\n * See ADR 0004.\n */\n\nimport type {\n PayloadDocumentEventMessage,\n PayloadLivePreviewMessage,\n} from '@/types/payload-protocol';\nimport {\n focusFieldOf,\n isDocumentEventMessage,\n isLivePreviewMessage,\n isObjectMessage,\n isPlainObject,\n normalizeLivePreviewMessage,\n} from './message-guards';\nimport { LIBRARY_PROTOCOL_VERSION } from './protocol-version';\nimport { observeThenableResult } from './thenable';\n\nexport type OriginMatcher = (origin: string) => boolean;\n\n/** Identity of a data-bearing update: `revision` is monotonic, `generation` names the listener attachment. */\nexport interface MessageRevision {\n readonly revision: number;\n readonly generation: number;\n}\nexport function sameRevision(a: MessageRevision, b: MessageRevision): boolean {\n return a.generation === b.generation && a.revision === b.revision;\n}\n\nexport type InvalidReason = 'origin' | 'shape' | 'type' | 'token' | 'source';\n\nexport interface MessageHandlers {\n /** A validated update; data-bearing ones carry their revision, ready handshakes do not. */\n readonly onUpdate: (\n msg: PayloadLivePreviewMessage,\n origin: string,\n messageRevision?: MessageRevision,\n ) => void;\n readonly onDocumentEvent: (msg: PayloadDocumentEventMessage, origin: string) => void;\n /** The admin reports the cursor moved into a field (reveal tier 2). */\n readonly onFocusField?: (field: string, origin: string) => void;\n readonly onInvalid?: (reason: InvalidReason, origin: string) => void;\n /** `'parent-or-opener'` refuses every window but the framing/opening one, even from an allowed origin. */\n readonly sourcePolicy?: 'any' | 'parent-or-opener';\n /**\n * Gate for data-bearing updates. Verdicts commit in arrival order, so an\n * earlier update is dispatched before a later one even when its validation\n * resolves later; an error counts as rejection.\n */\n readonly validateToken?: (\n token: string | undefined,\n origin: string,\n ) => boolean | Promise<boolean>;\n}\n\n/** One entry of the validation queue: a singly linked list in arrival order. */\ninterface PendingValidation {\n readonly generation: number;\n readonly message: PayloadLivePreviewMessage;\n readonly origin: string;\n readonly messageRevision: MessageRevision | undefined;\n /** `undefined` until the validator settled; only literal `true` approves. */\n verdict: boolean | undefined;\n next: PendingValidation | undefined;\n}\n\nexport class MessageBus {\n private readonly matcher: OriginMatcher;\n private readonly handlers: MessageHandlers;\n private boundListener: ((event: MessageEvent) => void) | undefined = undefined;\n private attachedTarget: Window | undefined = undefined;\n private generation = 0;\n private revision = 0;\n private queueHead: PendingValidation | undefined = undefined;\n private queueTail: PendingValidation | undefined = undefined;\n\n constructor(matcher: OriginMatcher, handlers: MessageHandlers) {\n this.matcher = matcher;\n this.handlers = handlers;\n }\n\n /** Start listening on `target`. Idempotent. */\n attach(target: Window = window): void {\n if (this.attachedTarget !== undefined) return;\n let committed = false;\n const listener = (event: MessageEvent): void => {\n // Each attachment owns its listener; a stale one must not borrow the new generation.\n if (!committed || this.boundListener !== listener) return;\n const generation = this.generation;\n try {\n this.receive(event, generation, target);\n } catch {\n // A synthetic event can carry throwing accessors; that is a shape failure.\n let origin: string;\n try {\n origin = event.origin;\n } catch {\n origin = '';\n }\n this.reportInvalid('shape', origin, generation);\n }\n };\n this.generation += 1;\n this.resetQueue();\n this.attachedTarget = target;\n this.boundListener = listener;\n try {\n target.addEventListener('message', listener);\n } catch (error) {\n // Invalidate before rollback: a hook may already have attached a newer generation.\n if (this.boundListener === listener) {\n this.attachedTarget = undefined;\n this.boundListener = undefined;\n this.resetQueue();\n }\n try {\n target.removeEventListener('message', listener);\n } catch {\n // Keep the original failure.\n }\n throw error;\n }\n if (this.boundListener === listener) {\n committed = true;\n } else {\n try {\n target.removeEventListener('message', listener);\n } catch {\n // The listener is identity-gated above even if removal fails.\n }\n }\n }\n\n /** Stop listening. Idempotent. */\n detach(): void {\n const target = this.attachedTarget;\n const listener = this.boundListener;\n if (target === undefined || listener === undefined) return;\n // Invalidate first so a listener already on the stack sees an obsolete generation.\n this.attachedTarget = undefined;\n this.boundListener = undefined;\n this.resetQueue();\n target.removeEventListener('message', listener);\n }\n\n /** Invalidate pending validations while staying attached (heartbeat expiry). */\n advanceGeneration(): boolean {\n if (this.attachedTarget === undefined) return false;\n this.generation += 1;\n this.resetQueue();\n return true;\n }\n\n /** Post the `ready` handshake to every target for every origin. */\n static sendReady(targets: readonly Window[], origins: readonly string[]): void {\n const payload: PayloadLivePreviewMessage = {\n type: 'payload-live-preview',\n ready: true,\n protocolVersion: LIBRARY_PROTOCOL_VERSION,\n };\n for (const target of targets) {\n for (const origin of origins) {\n try {\n target.postMessage(payload, origin);\n } catch {\n // A malformed origin is the consumer's configuration problem.\n }\n }\n }\n }\n\n private receive(event: MessageEvent, generation: number, target: Window): void {\n const origin = event.origin;\n if (!this.matchesOrigin(origin, generation)) {\n this.reportInvalid('origin', origin, generation);\n return;\n }\n if (!this.matchesSource(event, target)) {\n this.reportInvalid('source', origin, generation);\n return;\n }\n const data: unknown = event.data;\n if (!isObjectMessage(data)) {\n this.reportInvalid('shape', origin, generation);\n return;\n }\n switch (data.type) {\n case 'payload-live-preview':\n if (!isLivePreviewMessage(data)) {\n this.reportInvalid('shape', origin, generation);\n return;\n }\n this.dispatchUpdate(normalizeLivePreviewMessage(data), origin, generation);\n return;\n case 'payload-document-event':\n if (!isDocumentEventMessage(data)) {\n this.reportInvalid('shape', origin, generation);\n return;\n }\n this.invokeHandler(generation, this.handlers.onDocumentEvent, data, origin);\n return;\n case 'payload-live-preview-focus': {\n const field = focusFieldOf(data);\n if (field === undefined) {\n this.reportInvalid('shape', origin, generation);\n return;\n }\n this.invokeHandler(generation, this.handlers.onFocusField, field, origin);\n return;\n }\n default:\n this.reportInvalid('type', origin, generation);\n }\n }\n\n private dispatchUpdate(\n message: PayloadLivePreviewMessage,\n origin: string,\n generation: number,\n ): void {\n const hasUpdateData = isPlainObject(message.data);\n if (!this.isCurrentGeneration(generation)) return;\n // A shape-valid data update consumes its revision before validation; a rejected token leaves a gap.\n const messageRevision = hasUpdateData\n ? { generation, revision: (this.revision += 1) }\n : undefined;\n const validator = this.handlers.validateToken;\n if (!this.isCurrentGeneration(generation)) return;\n if (validator === undefined) {\n this.commitUpdate(message, origin, generation, messageRevision);\n return;\n }\n // The data-less ready handshake carries no token and passes, so the admin learns we listen.\n if (message.ready === true && message.data === undefined) {\n this.commitUpdate(message, origin, generation, undefined);\n return;\n }\n const pending: PendingValidation = {\n generation,\n message,\n origin,\n messageRevision,\n verdict: undefined,\n next: undefined,\n };\n this.enqueue(pending);\n let verdict: unknown;\n try {\n // Invoked eagerly; only the commit waits for earlier queue entries.\n verdict = validator(message.previewToken, origin);\n } catch {\n this.settleValidation(pending, false);\n return;\n }\n if (typeof verdict === 'boolean') {\n this.settleValidation(pending, verdict);\n return;\n }\n // Assimilate any thenable; only literal `true` approves.\n void Promise.resolve(verdict).then(\n (approved) => {\n this.settleValidation(pending, approved === true);\n },\n () => {\n this.settleValidation(pending, false);\n },\n );\n }\n\n private settleValidation(pending: PendingValidation, approved: boolean): void {\n pending.verdict = approved;\n this.drainQueue(pending.generation);\n }\n\n private drainQueue(generation: number): void {\n while (this.isCurrentGeneration(generation)) {\n const pending = this.queueHead;\n if (pending === undefined) return;\n // The matcher may have narrowed since ingress (origin lock); an obsolete\n // origin must not hold the queue head and block the locked origin's work.\n if (!this.matchesOrigin(pending.origin, generation)) {\n if (!this.dequeue(pending)) continue;\n this.reportInvalid('origin', pending.origin, pending.generation);\n continue;\n }\n if (pending.verdict === undefined) return;\n if (!this.dequeue(pending)) continue;\n if (pending.verdict) {\n this.commitUpdate(\n pending.message,\n pending.origin,\n pending.generation,\n pending.messageRevision,\n );\n } else {\n this.reportInvalid('token', pending.origin, pending.generation);\n }\n }\n }\n\n private commitUpdate(\n message: PayloadLivePreviewMessage,\n origin: string,\n generation: number,\n messageRevision: MessageRevision | undefined,\n ): void {\n if (messageRevision === undefined) {\n this.invokeHandler(generation, this.handlers.onUpdate, message, origin);\n } else {\n this.invokeHandler(generation, this.handlers.onUpdate, message, origin, messageRevision);\n }\n }\n\n private reportInvalid(reason: InvalidReason, origin: string, generation: number): void {\n this.invokeHandler(generation, this.handlers.onInvalid, reason, origin);\n }\n\n /** Under `'parent-or-opener'`, whether the event came from the attached window's parent or opener. */\n private matchesSource(event: MessageEvent, target: Window): boolean {\n if (this.handlers.sourcePolicy !== 'parent-or-opener') return true;\n try {\n // Only a window is a source: a missing one matches nothing, not even a missing opener.\n const source: unknown = event.source;\n if (typeof source !== 'object' || source === null) return false;\n const parent = target.parent;\n if (parent !== target && source === parent) return true;\n const opener: unknown = target.opener;\n return source === opener;\n } catch {\n return false;\n }\n }\n\n /** Fail-closed: only literal `true` from the matcher, and only within the generation it ran in. */\n private matchesOrigin(origin: string, generation: number): boolean {\n try {\n const approved: unknown = this.isCurrentGeneration(generation) && this.matcher(origin);\n return approved === true && this.isCurrentGeneration(generation);\n } catch {\n return false;\n }\n }\n\n /** Callbacks run only in a current generation and must not unwind the listener or the drain. */\n private invokeHandler<TArgs extends unknown[]>(\n generation: number,\n handler: ((...args: TArgs) => unknown) | undefined,\n ...args: TArgs\n ): void {\n if (handler === undefined || !this.isCurrentGeneration(generation)) return;\n try {\n observeThenableResult(handler(...args));\n } catch {\n // Isolated by contract.\n }\n }\n\n private isCurrentGeneration(generation: number): boolean {\n return this.attachedTarget !== undefined && this.generation === generation;\n }\n\n private enqueue(pending: PendingValidation): void {\n if (this.queueTail === undefined) this.queueHead = pending;\n else this.queueTail.next = pending;\n this.queueTail = pending;\n }\n\n /** Advance the head past `expected`, unless a matcher reset the queue meanwhile. */\n private dequeue(expected: PendingValidation): boolean {\n if (this.queueHead !== expected) return false;\n this.queueHead = expected.next;\n if (this.queueHead === undefined) this.queueTail = undefined;\n return true;\n }\n\n private resetQueue(): void {\n this.queueHead = undefined;\n this.queueTail = undefined;\n }\n}\n","import { observeThenableResult } from './thenable';\n\n/**\n * Diagnostics are observability, never control flow: a consumer logger may\n * throw or return a rejected thenable, and reporting a failure must not become\n * a second failure. Invocation stays synchronous for ordinary loggers.\n */\nexport function isolateDiagnostic(\n diagnostic: (...args: unknown[]) => unknown,\n): (...args: unknown[]) => void {\n return (...args): void => {\n try {\n observeThenableResult(diagnostic(...args));\n } catch {\n // Diagnostics must not become a second failure boundary.\n }\n };\n}\n\n/** Shared allocation-free default for disabled diagnostic channels. */\nexport function noopDiagnostic(): void {\n // Intentionally empty.\n}\n\n// Access, invocation and thenable inspection all happen inside the wrapper, so\n// a missing or hostile console cannot escape.\nexport const safeConsoleError = isolateDiagnostic((...args) =>\n (console.error as (...values: unknown[]) => unknown)(...args),\n);\n\nexport const safeConsoleWarn = isolateDiagnostic((...args) =>\n (console.warn as (...values: unknown[]) => unknown)(...args),\n);\n\nexport const safeConsoleDebug = isolateDiagnostic((...args) =>\n // eslint-disable-next-line no-console -- best-effort development diagnostics\n (console.debug as (...values: unknown[]) => unknown)(...args),\n);\n","/**\n * The build profile: which features are compiled into the inline runtime.\n *\n * `scripts/build-runtime.ts` builds the runtime twice — once with everything,\n * once with `__LEAN_BUILD__` defined — and the generator embeds whichever the\n * page asked for. The flag is read into a constant so esbuild folds it and\n * drops the branch, and with it every module only that branch referenced. In\n * the programmatic client the define is absent, so nothing is dropped there.\n *\n * A profile is a byte trade, never a behaviour trade in disguise: a page that\n * needs what the lean profile left out is told so (LP0104) instead of quietly\n * doing nothing.\n *\n * The flag itself is not exported. Each guard site reads `__LEAN_BUILD__`\n * directly, in expression position, because that is the only shape esbuild\n * folds — `src/types/build-flags.d.ts` explains why, with what was measured.\n */\n\nimport { safeConsoleWarn } from './diagnostics';\n\n/** What the lean profile leaves out, in the words the documentation uses. */\nexport type OmittedFeature =\n | 'structural arrays'\n | 'array templates'\n | 'server-rendered fragments'\n | 'route refreshes'\n | 'screen-reader announcements'\n | 'auto-binding';\n\nconst HOW_TO_GET_IT: Readonly<Record<OmittedFeature, string>> = {\n 'structural arrays': 'data-payload-type=\"array\" and keyed lists',\n 'array templates': 'data-payload-array-template',\n 'server-rendered fragments': 'data-payload-fragment boundaries',\n 'route refreshes': 'data-payload-strategy=\"route\" and bindings in <head>',\n 'screen-reader announcements': 'the aria-live region',\n 'auto-binding': \"autoBind: 'unique'\",\n};\n\nconst reported = new Set<OmittedFeature>();\n\n/**\n * Report once per feature and per page. The markup is the cause and it does not\n * change between updates, so a second message would only be noise.\n */\nexport function reportOmittedFeature(feature: OmittedFeature): void {\n if (reported.has(feature)) return;\n reported.add(feature);\n safeConsoleWarn(\n `[live-preview] LP0104: this page carries the lean runtime, which leaves out ${feature} ` +\n `(${HOW_TO_GET_IT[feature]}). The elements are left as the server rendered them. ` +\n `Remove \\`runtime: LEAN_RUNTIME\\` to get the full runtime.`,\n );\n}\n","/**\n * What the runtime builds around itself before it starts: the screen-reader\n * announcer, and where the `ready` handshake goes.\n *\n * Apart in this module for two reasons. The announcer is the one dependency the\n * lean profile leaves out, and the guard that drops it has to sit in expression\n * position at the seam (`src/types/build-flags.d.ts`); and `lifecycle.ts` is the\n * runtime's own lifecycle, which stays readable only if the wiring around it\n * lives next door rather than inside.\n */\n\nimport { A11yAnnouncer } from './a11y';\nimport { MessageBus } from './message-bus';\nimport { reportOmittedFeature } from './profile';\nimport type { RuntimeOptions } from './runtime-options';\n\n/**\n * The announcer and its locale table are ~800 bytes gzip the lean profile does\n * without; a page that asked for announcements is told instead (./profile).\n */\nexport function createA11y(options: RuntimeOptions): A11yAnnouncer | null {\n return typeof __LEAN_BUILD__ !== 'undefined' && __LEAN_BUILD__\n ? refuseA11y(options)\n : buildA11y(options);\n}\n\nfunction refuseA11y(options: RuntimeOptions): null {\n if (options.enableA11y !== false) reportOmittedFeature('screen-reader announcements');\n return null;\n}\n\nfunction buildA11y(options: RuntimeOptions): A11yAnnouncer | null {\n if (options.enableA11y === false) return null;\n const root = options.root;\n const targetDocument =\n root === undefined ? undefined : isDocumentRoot(root) ? root : root.ownerDocument;\n return new A11yAnnouncer(options.a11yLocale, targetDocument);\n}\n\n/** Node types are stable across realms; global constructors are not. */\nfunction isDocumentRoot(root: Document | Element): root is Document {\n return root.nodeType === 9;\n}\n\n/** The framing or opening window, which is the only one that asked for a preview. */\nexport function defaultSendReady(origins: readonly string[]): void {\n if (typeof window === 'undefined') return;\n const targets: Window[] = [];\n if (window.parent !== window) targets.push(window.parent);\n if (window.opener instanceof Window) targets.push(window.opener);\n MessageBus.sendReady(targets, origins);\n}\n","/** Drops `undefined`-valued keys, so a literal built from optional inputs satisfies `exactOptionalPropertyTypes`. */\n\nexport type DefinedOnly<T> = { readonly [K in keyof T]-?: Exclude<T[K], undefined> };\n\nexport function definedOnly<T extends object>(source: T): DefinedOnly<T> {\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(source)) {\n if (value !== undefined) result[key] = value;\n }\n return result as DefinedOnly<T>;\n}\n","/**\n * Flattens a parsed field schema into dotted paths (`hero.title`,\n * `sections.*.heading`). Tabs, rows and collapsibles have no name and\n * dissolve into their inner fields.\n */\n\nimport type {\n PayloadBlockSchema,\n PayloadFieldSchema,\n PayloadFieldType,\n} from '@/types/payload-protocol';\n\nexport type SchemaIndex = ReadonlyMap<string, PayloadFieldSchema>;\n\nconst STRUCTURAL_TYPES: ReadonlySet<PayloadFieldType> = new Set<PayloadFieldType>([\n 'tabs',\n 'row',\n 'collapsible',\n]);\n\nexport function buildSchemaIndex(\n schemas: readonly PayloadFieldSchema[],\n basePath = '',\n): SchemaIndex {\n const out = new Map<string, PayloadFieldSchema>();\n walk(schemas, basePath, out);\n return out;\n}\n\nfunction walk(\n schemas: readonly PayloadFieldSchema[],\n basePath: string,\n out: Map<string, PayloadFieldSchema>,\n): void {\n for (const schema of schemas) {\n if (STRUCTURAL_TYPES.has(schema.type)) {\n if (schema.fields) walk(schema.fields, basePath, out);\n continue;\n }\n const path = basePath === '' ? schema.name : `${basePath}.${schema.name}`;\n out.set(path, schema);\n if (schema.type === 'group') {\n if (schema.fields) walk(schema.fields, path, out);\n } else if (schema.type === 'array' && schema.fields) {\n walk(schema.fields, `${path}.*`, out);\n } else if (schema.type === 'blocks' && schema.blocks) {\n for (const block of schema.blocks) {\n walk(block.fields, `${path}.*.${block.slug}`, out);\n }\n }\n }\n}\n\n/** Schema for `fieldPath`; numeric segments are retried as `*` wildcards. */\nexport function lookupSchema(\n index: SchemaIndex,\n fieldPath: string,\n): PayloadFieldSchema | undefined {\n if (index.has(fieldPath)) return index.get(fieldPath);\n const wildcardPath = fieldPath.replace(/\\.\\d+(?=\\.|$)/g, '.*');\n if (index.has(wildcardPath)) return index.get(wildcardPath);\n return undefined;\n}\n\nexport function lookupBlockSchema(\n index: SchemaIndex,\n blocksFieldPath: string,\n blockType: string,\n): PayloadBlockSchema | undefined {\n const schema = lookupSchema(index, blocksFieldPath);\n if (!schema?.blocks) return undefined;\n return schema.blocks.find((b) => b.slug === blockType);\n}\n","/**\n * Structural diff for array and blocks fields. Items with an `id` are keyed\n * (moves are detected); without ids the diff is positional.\n * @internal\n */\n\nexport type ArrayPatch =\n | { readonly kind: 'insert'; readonly index: number; readonly value: unknown }\n | { readonly kind: 'remove'; readonly index: number; readonly value: unknown }\n | {\n readonly kind: 'move';\n readonly from: number;\n readonly to: number;\n readonly value: unknown;\n }\n | { readonly kind: 'update'; readonly index: number; readonly value: unknown }\n | {\n readonly kind: 'replace';\n readonly index: number;\n readonly oldValue: unknown;\n readonly value: unknown;\n };\n\nfunction getId(item: unknown): string | number | undefined {\n if (typeof item !== 'object' || item === null) return undefined;\n const id = (item as Record<string, unknown>)['id'];\n if (typeof id === 'string' || typeof id === 'number') return id;\n return undefined;\n}\n\nfunction getBlockType(item: unknown): string | undefined {\n if (typeof item !== 'object' || item === null) return undefined;\n const blockType = (item as Record<string, unknown>)['blockType'];\n return typeof blockType === 'string' ? blockType : undefined;\n}\n\n/** Patches that turn `prev` into `next`; a changed `blockType` is a `replace`, never an `update`. */\nexport function diffArray(\n prev: readonly unknown[],\n next: readonly unknown[],\n): readonly ArrayPatch[] {\n const haveIds = next.every((item) => getId(item) !== undefined);\n if (haveIds) return diffById(prev, next);\n return diffByPosition(prev, next);\n}\n\nfunction diffById(prev: readonly unknown[], next: readonly unknown[]): readonly ArrayPatch[] {\n const patches: ArrayPatch[] = [];\n const prevIndexById = new Map<string | number, number>();\n for (let i = 0; i < prev.length; i += 1) {\n const id = getId(prev[i]);\n if (id !== undefined) prevIndexById.set(id, i);\n }\n\n const consumedFromPrev = new Set<number>();\n for (let to = 0; to < next.length; to += 1) {\n const item = next[to];\n const id = getId(item);\n if (id === undefined) {\n patches.push({ kind: 'insert', index: to, value: item });\n continue;\n }\n const from = prevIndexById.get(id);\n if (from === undefined) {\n patches.push({ kind: 'insert', index: to, value: item });\n continue;\n }\n consumedFromPrev.add(from);\n const prevItem = prev[from];\n if (getBlockType(prevItem) !== getBlockType(item)) {\n patches.push({ kind: 'replace', index: to, oldValue: prevItem, value: item });\n continue;\n }\n if (from !== to) {\n patches.push({ kind: 'move', from, to, value: item });\n }\n if (!shallowEqual(prevItem, item)) {\n patches.push({ kind: 'update', index: to, value: item });\n }\n }\n\n for (let i = 0; i < prev.length; i += 1) {\n if (consumedFromPrev.has(i)) continue;\n patches.push({ kind: 'remove', index: i, value: prev[i] });\n }\n return patches;\n}\n\nfunction diffByPosition(prev: readonly unknown[], next: readonly unknown[]): readonly ArrayPatch[] {\n const patches: ArrayPatch[] = [];\n const min = Math.min(prev.length, next.length);\n for (let i = 0; i < min; i += 1) {\n if (!shallowEqual(prev[i], next[i])) {\n patches.push({ kind: 'update', index: i, value: next[i] });\n }\n }\n if (next.length > prev.length) {\n for (let i = prev.length; i < next.length; i += 1) {\n patches.push({ kind: 'insert', index: i, value: next[i] });\n }\n }\n if (prev.length > next.length) {\n for (let i = next.length; i < prev.length; i += 1) {\n patches.push({ kind: 'remove', index: i, value: prev[i] });\n }\n }\n return patches;\n}\n\n// Shallow on purpose: any nested reference change is an update, and the\n// renderer reconciles deeper differences itself.\nfunction shallowEqual(a: unknown, b: unknown): boolean {\n if (Object.is(a, b)) return true;\n if (typeof a !== 'object' || typeof b !== 'object' || a === null || b === null) return false;\n const aRec = a as Record<string, unknown>;\n const bRec = b as Record<string, unknown>;\n const aKeys = Object.keys(aRec);\n const bKeys = Object.keys(bRec);\n if (aKeys.length !== bKeys.length) return false;\n for (const key of aKeys) {\n if (!Object.is(aRec[key], bRec[key])) return false;\n }\n return true;\n}\n","/**\n * Payload field type → renderer name. Structural containers the walker has\n * already flattened, and types without a display, map to `text` so a new\n * Payload field type never leaves a binding without a renderer.\n */\n\nimport type { FieldType } from '@core/types';\nimport type { PayloadFieldType } from '@/types/payload-protocol';\n\nconst MAP: Readonly<Record<PayloadFieldType, FieldType>> = {\n text: 'text',\n textarea: 'textarea',\n richText: 'richText',\n email: 'email',\n number: 'number',\n checkbox: 'checkbox',\n date: 'date',\n select: 'select',\n radio: 'radio',\n array: 'array',\n blocks: 'blocks',\n group: 'text',\n tabs: 'text',\n row: 'text',\n collapsible: 'text',\n relationship: 'relationship',\n upload: 'upload',\n point: 'text',\n json: 'text',\n code: 'text',\n ui: 'text',\n};\n\n/** `undefined` for a type not in the table, so the caller can fall back to the DOM attribute. */\nexport function payloadTypeToRenderer(type: string): FieldType | undefined {\n if (Object.prototype.hasOwnProperty.call(MAP, type)) {\n return MAP[type as PayloadFieldType];\n }\n return undefined;\n}\n","/**\n * URL safety: the one scheme allow-list the runtime, the client and the\n * sanitizer share. Empty strings are not safe (`<a href=\"\">` is never emitted).\n */\n\nconst SAFE_PROTOCOLS: ReadonlySet<string> = new Set(['http:', 'https:', 'mailto:', 'tel:']);\n\n// Browsers strip leading whitespace before scheme detection.\nconst DANGEROUS_PROTOCOL_PATTERN = /^\\s*(?:javascript|data|vbscript|file|blob|about)\\s*:/i;\n\nconst RELATIVE_PATH = /^(?:\\.{1,2}\\/|[a-zA-Z0-9_-]+\\/?)/;\n\n// The URL parser treats `\\` as `/` for special schemes, so `/\\evil.com`\n// resolves to another origin rather than to a same-origin path.\nconst PROTOCOL_RELATIVE = /^[\\\\/]{2}/;\n\n/** The URL parser drops these anywhere in the input before it looks at anything. */\nconst PARSER_IGNORED = /[\\t\\n\\r]/g;\n\n/** `true` only for absolute `http`/`https`/`mailto`/`tel` URLs, protocol-relative URLs, paths, `#`/`?` fragments and relative paths. */\nexport function isSafeUrl(url: unknown): boolean {\n if (typeof url !== 'string') return false;\n const trimmed = url.trim().replace(PARSER_IGNORED, '');\n if (trimmed.length === 0) return false;\n if (DANGEROUS_PROTOCOL_PATTERN.test(trimmed)) return false;\n if (trimmed.startsWith('#') || trimmed.startsWith('?')) return true;\n if (PROTOCOL_RELATIVE.test(trimmed)) return true;\n if (trimmed.startsWith('/')) return true;\n try {\n const parsed = new URL(trimmed);\n return SAFE_PROTOCOLS.has(parsed.protocol);\n } catch {\n return RELATIVE_PATH.test(trimmed);\n }\n}\n\n/** Whether a URL points at another HTTP(S) origin, protocol-relative forms included, and so needs `noopener` hardening; every URL these two patterns match is one `isSafeUrl` admits. */\nexport function isExternalHttpUrl(url: string): boolean {\n const trimmed = url.trim().replace(PARSER_IGNORED, '');\n return /^https?:\\/\\//i.test(trimmed) || PROTOCOL_RELATIVE.test(trimmed);\n}\n\n/** The safe scheme set, for tests and introspection. */\nexport const SAFE_URL_PROTOCOLS: ReadonlySet<string> = SAFE_PROTOCOLS;\n","/**\n * Policed writes for `data-payload-attribute` bindings. The value is\n * remote-controlled, so event handlers, `style`, `srcdoc`, `formaction`/`form`,\n * `id`/`name` (DOM clobbering) and `srcset` (multi-URL syntax) are refused,\n * URL-bearing attributes must pass `isSafeUrl`, and non-scalars never write.\n */\n\nimport { isSafeUrl } from '@security/url-validator';\n\nconst BLOCKED_ATTRIBUTES: ReadonlySet<string> = new Set([\n 'style',\n 'srcdoc',\n 'formaction',\n 'form',\n 'id',\n 'name',\n 'is',\n 'srcset',\n 'imagesrcset',\n]);\n\nconst URL_ATTRIBUTES: ReadonlySet<string> = new Set([\n 'href',\n 'src',\n 'poster',\n 'cite',\n 'action',\n 'xlink:href',\n 'data',\n]);\n\nexport type AttributeApplyResult = 'applied' | 'blocked';\n\n/**\n * Whether this package may write an attribute of this name at all — event\n * handlers, `style`, the two DOM-clobbering names and the multi-URL ones\n * excluded. One rule, two callers: the binding below writes a remote value into\n * it, and the array renderers copy one from the page's own markup onto an item\n * they rebuilt (`src/core/array-template.ts`).\n */\nexport function isWritableAttribute(name: string): boolean {\n return !name.startsWith('on') && !BLOCKED_ATTRIBUTES.has(name);\n}\n\n/** Returns `'blocked'` without touching the DOM when the write is refused. */\nexport function applyAttributeBinding(\n element: Element,\n attribute: string,\n value: unknown,\n): AttributeApplyResult {\n const name = attribute.toLowerCase().trim();\n if (name.length === 0) return 'blocked';\n if (!isWritableAttribute(name)) return 'blocked';\n\n if (value === null || value === undefined) {\n element.removeAttribute(name);\n return 'applied';\n }\n if (typeof value !== 'string' && typeof value !== 'number' && typeof value !== 'boolean') {\n return 'blocked';\n }\n const stringValue = String(value);\n\n if (URL_ATTRIBUTES.has(name) && !isSafeUrl(stringValue)) return 'blocked';\n\n element.setAttribute(name, stringValue);\n return 'applied';\n}\n","/**\n * What the runtime does about a patch it knows will not reach what the server\n * would have drawn: a renderer that refused the value, a Lexical block whose\n * markup the write had to drop. The finding is made where the write happens;\n * the policy and the ledger live here, so the pipeline can hand the region to a\n * strategy once the flush is over instead of leaving the page worse off.\n *\n * A changed field with no binding at all is the same judgement made one step\n * earlier — there is no element to write to — and `StrategyRunner` reaches it\n * from `unbound-fields.ts` before anything is scheduled.\n */\n\nimport type { RuntimeDeps, RuntimeState } from './runtime-state';\nimport type { CachedElement } from './types';\n\n/**\n * `'ignore'` keeps the degraded patch, which is what 2.0 shipped under the\n * name `onUnboundChange: 'ignore'`. `'warn'` keeps it and says so (LP0411).\n * `'escalate'`, the default, asks a server to draw the region instead: the\n * fragment strategy when a boundary covers the binding, the route otherwise.\n *\n * Without a strategy to escalate to, every mode keeps the patch. A page that\n * cannot ask a server for better markup is not helped by being told twice.\n */\nexport type UnfaithfulPatchMode = 'ignore' | 'warn' | 'escalate';\n\n/**\n * Both spellings of the option; the 2.0 name stays until 3.0. Explicitly\n * `| undefined`, because one caller reads them out of the inline script's\n * positional tuple, where an omitted slot is exactly that.\n */\nexport interface UnfaithfulPatchOptions {\n readonly onUnfaithfulPatch?: UnfaithfulPatchMode | undefined;\n readonly onUnboundChange?: 'ignore' | 'route' | undefined;\n}\n\n/**\n * The 2.0 name maps onto the new one without loss: `'route'` was this option's\n * escalation and `'ignore'` its opt-out. Only an omitted option takes the new\n * default — a project that wrote `'ignore'` down chose it, and keeps it.\n */\nexport function resolveUnfaithfulPatchMode(options: UnfaithfulPatchOptions): UnfaithfulPatchMode {\n // `'ignore'` is the only thing the old name can still say that the new\n // default does not: its `'route'` and its absence both mean escalate now.\n return (\n options.onUnfaithfulPatch ?? (options.onUnboundChange === 'ignore' ? 'ignore' : 'escalate')\n );\n}\n\n/**\n * Record one binding this revision could not patch faithfully, and queue it for\n * the escalation the flush will run.\n *\n * Once per element, for the same reason every other diagnostic here is: the\n * cause is the markup or the value's shape, so the next message would report\n * the same thing. Under `'escalate'` that also stops a value the renderer keeps\n * refusing from becoming one route refresh per keystroke.\n *\n * Counted under every mode, before the mode decides anything: `inspect()` has\n * to be able to say \"three patches fell short, none was escalated\" on the page\n * whose owner chose `'ignore'` as much as on the one that has no strategy.\n */\nexport function reportUnfaithfulPatch(\n deps: RuntimeDeps,\n state: RuntimeState,\n target: CachedElement,\n reason: string,\n): void {\n if (state.reportedUnfaithful.has(target.element)) return;\n state.reportedUnfaithful.add(target.element);\n state.unfaithfulCount += 1;\n state.unfaithfulFields.add(target.fieldName);\n const mode = deps.onUnfaithfulPatch;\n if (mode === 'ignore') return;\n if (mode === 'warn') {\n deps.warn(`[live-preview] LP0411: \"${target.fieldName}\" ${reason}`);\n return;\n }\n deps.log('LP0411', target.fieldName, reason);\n state.unfaithfulPatches.push(target);\n}\n\n/**\n * Record a changed field the page has no binding for: the same judgement one\n * step earlier, where there is no element to write to and so nothing to queue.\n * The whole route is the only answer to it, and `StrategyRunner` asks for that\n * itself.\n *\n * Once per field name, for the reason LP0411 is once per element: the cause is\n * the markup, so the next keystroke into the same field would report the same\n * thing. Counted under every mode and on a page with no strategy at all —\n * that page is the one `inspect().fidelity` was written for, and it was the one\n * page the reading said nothing about.\n *\n * No message of its own: LP0201 already names the field, once, from the same\n * rule. The return value says whether this was the first time, so an escalation\n * is counted against the findings it answered rather than against a keystroke.\n */\nexport function reportUnboundChange(state: RuntimeState, fieldName: string): boolean {\n if (state.unfaithfulFields.has(fieldName)) return false;\n state.unfaithfulFields.add(fieldName);\n state.unfaithfulCount += 1;\n return true;\n}\n\n/**\n * Renderers that turn a stored value into a presentation, so the template that\n * printed the same field had to choose one too. A `text` binding whose content\n * differs is an edit; a `date`, `number` or `checkbox` binding whose content\n * differs is two answers to the question the runtime cannot ask —\n * `data-payload-format` is where the answer belongs.\n */\nconst FORMATTING_RENDERERS: ReadonlySet<string> = new Set(['date', 'number', 'checkbox']);\n\n/** Cap on either reading in the message: a diagnostic is a pointer, not a dump. */\nconst EXCERPT = 40;\n\n/**\n * What the element shows, when a difference there would be worth reporting —\n * `undefined` when it would not, so an ordinary page pays one `Set` lookup per\n * binding and reads no DOM at all.\n *\n * Called before the renderer writes, and only for the first write to a\n * binding: after that the element holds the runtime's own output, and\n * comparing it with the runtime's next output says nothing about the template.\n */\nexport function watchServerFormatting(\n deps: RuntimeDeps,\n state: RuntimeState,\n target: CachedElement,\n type: string,\n): string | undefined {\n if (deps.onUnfaithfulPatch === 'ignore') return undefined;\n if (target.format !== undefined || !FORMATTING_RENDERERS.has(type)) return undefined;\n if (state.checkedServerFormat.has(target.element)) return undefined;\n state.checkedServerFormat.add(target.element);\n const shown = shownValue(target.element);\n // An empty anchor lost nothing, and the boundary case (LP0201) is elsewhere.\n return shown.trim().length > 0 ? shown : undefined;\n}\n\n/**\n * Called once the renderer has written: both readings of the same value now\n * exist, and if they differ the page no longer matches the server.\n *\n * It reports and stops there. Escalating would hand the region to the route,\n * which redraws the template's format, which the re-apply overwrites again —\n * measured under Z3 — so the honest move is to name the two candidates and the\n * attribute that settles either of them.\n */\nexport function reportServerFormatting(\n deps: RuntimeDeps,\n target: CachedElement,\n before: string,\n): void {\n const after = shownValue(target.element);\n if (after === before) return;\n deps.warn(\n `[live-preview] LP0412: \"${target.fieldName}\" showed ${excerpt(before)}, the patch wrote ` +\n `${excerpt(after)} — either an edit that arrived before the preview connected, or a ` +\n 'template that formats this value differently. Set data-payload-format to match it.',\n );\n}\n\n/** The channel the date, number and checkbox renderers write. */\nfunction shownValue(element: Element): string {\n if (element.tagName === 'INPUT' || element.tagName === 'TEXTAREA') {\n return (element as HTMLInputElement).value;\n }\n return element.textContent;\n}\n\nfunction excerpt(value: string): string {\n const text = value.trim();\n return JSON.stringify(text.length > EXCERPT ? `${text.slice(0, EXCERPT)}…` : text);\n}\n","/**\n * Public renderer callbacks return `void`, but a JavaScript implementation may\n * return anything. Only callbacks marked here may reserve exact `false` as\n * \"no write\", so a custom renderer's incidental boolean cannot change the\n * lifecycle's applied counts.\n */\n\ntype Callback = (...args: never[]) => unknown;\n\nconst noWriteCallbacks = new WeakSet<Callback>();\n\n/** Mark a package-owned callback whose exact `false` return means no write. */\nexport function markNoWriteCallback<T extends Callback>(callback: T): T {\n noWriteCallbacks.add(callback);\n return callback;\n}\n\n/** Whether `callback` owns the internal exact-false sentinel contract. */\nexport function usesNoWriteOutcome(callback: Callback): boolean {\n return noWriteCallbacks.has(callback);\n}\n\n/** Check a renderer object without detaching its public method at the call site. */\nexport function rendererUsesNoWriteOutcome(renderer: { readonly render: Callback }): boolean {\n return noWriteCallbacks.has(renderer.render);\n}\n","/**\n * Stable identity for a field value, so two messages can be compared without\n * rendering either — every keystroke ships the whole document, of which one\n * field changed. Equality is structural (plain, unsorted JSON): Payload\n * allocates a fresh object graph per message, so reference identity would skip\n * nothing. A value JSON cannot represent has no identity and counts as\n * changed, which is the safe direction — a false \"equal\" leaves a stale\n * binding, a false \"different\" only renders once more.\n */\n\n/** Past this size the comparison is no longer obviously cheaper than the render it avoids. */\nexport const IDENTITY_SIZE_LIMIT = 64 * 1024;\n\n/**\n * Canonical string for `value`, or `undefined` when it cannot have one.\n * Primitives carry a type tag, so `1` and `'1'` differ even though a text\n * renderer prints them alike — that is the renderer's decision, not this one.\n */\nexport function valueIdentity(value: unknown): string | undefined {\n switch (typeof value) {\n case 'string':\n return value.length > IDENTITY_SIZE_LIMIT ? undefined : `s:${value}`;\n case 'number':\n // Object.is semantics at the top level: NaN equals NaN, -0 is not 0.\n return `n:${Object.is(value, -0) ? '-0' : String(value)}`;\n case 'boolean':\n return `b:${value ? '1' : '0'}`;\n case 'bigint':\n return `i:${String(value)}`;\n case 'undefined':\n return 'u';\n case 'object': {\n if (value === null) return 'z';\n let json: string;\n try {\n // Throws on a cycle and on a nested BigInt; both mean \"no identity\".\n json = JSON.stringify(value);\n } catch {\n return undefined;\n }\n return json.length > IDENTITY_SIZE_LIMIT ? undefined : `o:${json}`;\n }\n case 'symbol':\n case 'function':\n return undefined;\n }\n}\n","/**\n * The one per-message diff of top-level field values. Strategies, dependency\n * invalidation and reveal all consume it, so \"changed\" means the same thing\n * everywhere.\n */\n\nimport type { DependencyMap } from './dependencies';\nimport { valueIdentity } from './value-identity';\n\nexport interface FieldChanges {\n /** Fields whose value differs from the previous message; every field on the first one. */\n readonly changed: ReadonlySet<string>;\n /** Dependents of changed fields, per the dependency map. */\n readonly invalidated: ReadonlySet<string>;\n /**\n * The first message of a connection, where `changed` means \"everything the\n * document has\" rather than \"what the editor just did\". A caller that acts on\n * a change rather than rendering one has to sit this message out.\n */\n readonly baseline: boolean;\n}\n\nexport class FieldChangeTracker {\n private previous: Map<string, string | undefined> | null = null;\n\n /** Diff `fields` against the previous message and remember them for the next call. */\n diff(fields: Readonly<Record<string, unknown>>, dependencies: DependencyMap): FieldChanges {\n const previous = this.previous;\n const baseline = previous === null;\n const next = new Map<string, string | undefined>();\n const changed = new Set<string>();\n for (const [name, value] of Object.entries(fields)) {\n const identity = valueIdentity(value);\n next.set(name, identity);\n // A value without an identity always counts as changed: rendering once\n // more is cheap, a stale binding is not.\n if (previous === null || identity === undefined || previous.get(name) !== identity) {\n changed.add(name);\n }\n }\n if (previous !== null) {\n for (const name of previous.keys()) if (!next.has(name)) changed.add(name);\n }\n this.previous = next;\n const invalidated = new Set<string>();\n for (const [source, dependents] of Object.entries(dependencies)) {\n if (!changed.has(source)) continue;\n for (const dependent of dependents) invalidated.add(dependent);\n }\n return { changed, invalidated, baseline };\n }\n\n reset(): void {\n this.previous = null;\n }\n}\n","/**\n * How a bound region is brought up to date: the runtime patches it, a server\n * renders a `data-payload-fragment` boundary from the unsaved form state, or\n * the whole route refreshes. Core carries only the seam — which boundaries a\n * strategy owns and what it may do — so a patch-only page pays for nothing\n * more; the orchestration lives in `payload-live-preview/fragment`.\n */\nimport type { DiagnosticCode } from './diagnostic-codes';\n\n/** What produced an update: the runtime's DOM patching, a server-rendered fragment, or a route refresh. */\nexport type UpdateSource = 'patch' | 'fragment' | 'route';\n\n/** Marks a server-rendered boundary; the value is the registry id the server may render. @internal */\nexport const FRAGMENT_ATTRIBUTE = 'data-payload-fragment';\n\n/** The nearest fragment boundary enclosing `element` (the element itself included). */\nexport function enclosingFragment(element: Element): Element | null {\n return element.closest(`[${FRAGMENT_ATTRIBUTE}]`);\n}\n\n/** One revision, as a strategy sees it, with the runtime capabilities it may use. */\nexport interface FragmentContext {\n readonly root: ParentNode;\n readonly revision: number;\n readonly receivedAt: number;\n readonly fields: Readonly<Record<string, unknown>>;\n readonly locale: string | undefined;\n readonly collectionSlug: string | undefined;\n readonly globalSlug: string | undefined;\n /** Aborted when a newer revision arrives or the runtime stops. */\n readonly signal: AbortSignal;\n /** Whether this revision is still the current one. */\n readonly isCurrent: () => boolean;\n /** Morph server-rendered HTML into a boundary (Trusted Types and the keyed morph apply). */\n readonly morph: (boundary: Element, html: string) => void;\n /** Patch the boundary's own bindings from this revision — the deterministic fallback. */\n readonly patch: (boundary: Element) => void;\n /** Debug log through the runtime's logger, with the diagnostic code. */\n readonly log: (code: DiagnosticCode, detail: string) => void;\n /** Report a boundary rendered. */\n readonly rendered: (boundary: Element, id: string, key: string | undefined) => void;\n /** Report a boundary failed and patched instead; emits the `error` and `fragmentRender` events. */\n readonly failed: (\n boundary: Element,\n id: string,\n key: string | undefined,\n code: DiagnosticCode,\n reason: string,\n ) => void;\n}\n\nexport interface FragmentReport {\n readonly rendered: number;\n readonly failed: number;\n readonly superseded: number;\n}\n\n/** A fragment strategy: which boundaries it owns for a revision, and how it renders them. */\nexport interface FragmentStrategy {\n /** The boundaries this update re-renders; their inner bindings are left to the strategy. */\n readonly plan: (root: ParentNode, changedFields: ReadonlySet<string>) => readonly Element[];\n /** Render the planned boundaries; resolves once every one settled. */\n readonly render: (\n context: FragmentContext,\n boundaries: readonly Element[],\n ) => Promise<FragmentReport>;\n}\n\n/** One revision, as the route strategy sees it. */\nexport interface RouteContext {\n readonly revision: number;\n readonly receivedAt: number;\n /** Aborted when a newer revision arrives or the runtime stops. */\n readonly signal: AbortSignal;\n readonly isCurrent: () => boolean;\n readonly log: (code: DiagnosticCode, detail: string) => void;\n /**\n * Ask to be run again in `delayMs`, once. A strategy that refuses a refresh\n * because it is rate-limiting itself uses this: the window is a rate limit\n * and not a filter, so what falls inside it still has to reach the preview.\n * The runtime runs at most one such request, and only while the revision that\n * asked is still the current one.\n */\n readonly retryAfter?: (delayMs: number) => void;\n}\n\n/**\n * What one refresh did. `refused` is the strategy's own brake and not a\n * failure — it is counted separately, because a number that mixes a planned\n * pause with a broken request cannot be read.\n */\nexport type RouteOutcome = 'refreshed' | 'failed' | 'refused' | 'superseded';\n\n/**\n * Whether a revision needs the whole route re-rendered, and how. After a\n * refresh the runtime rescans and re-applies the revision, so the unsaved\n * state lands on the fresh markup.\n */\nexport interface RouteStrategy {\n readonly plan: (root: ParentNode, changedFields: ReadonlySet<string>) => boolean;\n readonly refresh: (context: RouteContext) => Promise<RouteOutcome>;\n}\n\nexport interface StrategyHandlers {\n readonly fragment?: FragmentStrategy;\n readonly route?: RouteStrategy;\n}\n\nconst STRATEGY_ATTRIBUTE = 'data-payload-strategy';\n\n/**\n * Explicit `data-payload-strategy` wins; otherwise a binding inside a fragment\n * boundary belongs to the fragment, one in `<head>` to the route, the rest is\n * patched. An unknown explicit value resolves to `undefined` (LP0407).\n * @internal\n */\nexport function resolveStrategy(element: Element): UpdateSource | undefined {\n const explicit = element.getAttribute(STRATEGY_ATTRIBUTE);\n if (explicit !== null && explicit.length > 0) {\n return explicit === 'patch' || explicit === 'fragment' || explicit === 'route'\n ? explicit\n : undefined;\n }\n if (enclosingFragment(element) !== null) return 'fragment';\n if (element.closest('head') !== null) return 'route';\n return 'patch';\n}\n","/**\n * Document ownership for bindings. A field name alone cannot identify a\n * binding on a page that previews several documents — `title` may belong to a\n * global, to shared SEO metadata and to every card at once. An owner marker\n * names the document a subtree belongs to, as a plain comparable string:\n * `global:<slug>`, `collection:<slug>`, `collection:<slug>:<id>`.\n */\n\n/** Identity of the document an incoming message describes. */\nexport interface MessageDocumentIdentity {\n readonly globalSlug?: string | undefined;\n readonly collectionSlug?: string | undefined;\n /** Primary key of the edited document, when the payload carries one. */\n readonly documentId?: string | undefined;\n}\n\n/** Owner key naming one Payload global. */\nexport function globalOwnerKey(slug: string): string {\n return `global:${slug}`;\n}\n\n/** Owner key for a collection; without an id it claims every document of it. */\nexport function collectionOwnerKey(slug: string, documentId?: string): string {\n return documentId === undefined || documentId === ''\n ? `collection:${slug}`\n : `collection:${slug}:${documentId}`;\n}\n\nfunction nonEmpty(value: string | undefined): value is string {\n return typeof value === 'string' && value.length > 0;\n}\n\n/**\n * Owner keys this message may address, or `null` when it carries no usable\n * identity — the runtime treats that as fail-closed rather than guessing. A\n * marker naming an id stays unreachable while the id is unknown: an unproven\n * identity must not satisfy an exact claim.\n */\nexport function messageOwnerKeys(identity: MessageDocumentIdentity): readonly string[] | null {\n if (nonEmpty(identity.globalSlug)) return [globalOwnerKey(identity.globalSlug)];\n if (!nonEmpty(identity.collectionSlug)) return null;\n const collectionKey = collectionOwnerKey(identity.collectionSlug);\n return nonEmpty(identity.documentId)\n ? [collectionKey, collectionOwnerKey(identity.collectionSlug, identity.documentId)]\n : [collectionKey];\n}\n\n/** Whether a binding may receive an update addressed to `keys`; an unowned binding never may. */\nexport function isBindingInScope(\n owner: string | undefined,\n keys: readonly string[] | null,\n): boolean {\n if (keys === null || owner === undefined) return false;\n return keys.includes(owner);\n}\n\n/** The document id Payload sends alongside the edited values; only scalars prove an identity. */\nexport function readDocumentId(fields: Record<string, unknown>): string | undefined {\n const id: unknown = fields['id'];\n if (typeof id === 'string' && id.length > 0) return id;\n if (typeof id === 'number' && Number.isFinite(id)) return String(id);\n return undefined;\n}\n","/**\n * Whether an incoming field has somewhere on the page to land.\n *\n * Two callers ask, for different reasons: LP0201 reports a field that never\n * has an anchor, and `onUnfaithfulPatch` decides whether a revision needs the\n * whole route. They have to answer the same way, so the lookup lives here\n * rather than in either of them — the locale suffix Payload appends, the owner\n * scope, and the fact that the diff names top-level fields while a binding may\n * name a path inside one.\n */\n\nimport { isBindingInScope } from './binding-owner';\nimport type { ElementCache } from './cache';\n\n/** Document fields Payload ships in every update that nobody binds to. */\nexport const SYSTEM_FIELD_NAMES: ReadonlySet<string> = new Set([\n 'id',\n '_id',\n 'createdAt',\n 'updatedAt',\n 'createdBy',\n 'updatedBy',\n '_status',\n 'globalType',\n 'collection',\n 'locale',\n 'localized',\n]);\n\n/** Owner keys as the update resolved them; `false` means scoping is off. */\nexport type OwnerScope = readonly string[] | null | false;\n\n/** Answers for one update; the locale index behind it is built at most once. */\nexport type FieldAddressability = (fieldName: string) => boolean;\n\n/**\n * `field_locale` names an element-local locale may consume while the message\n * locale differs, so those bindings are addressable under their suffixed name.\n */\nfunction localisedBindingNames(cache: ElementCache, ownerKeys: OwnerScope): Set<string> {\n const names = new Set<string>();\n for (const [fieldName, bindings] of cache.entries()) {\n for (const binding of bindings) {\n if (ownerKeys !== false && !isBindingInScope(binding.owner, ownerKeys)) continue;\n if (binding.locale !== undefined) names.add(`${fieldName}_${binding.locale}`);\n }\n }\n return names;\n}\n\nfunction hasBinding(cache: ElementCache, fieldName: string, ownerKeys: OwnerScope): boolean {\n const bindings = cache.get(fieldName);\n if (bindings === undefined) return false;\n if (ownerKeys === false) return true;\n return bindings.some((binding) => isBindingInScope(binding.owner, ownerKeys));\n}\n\n/**\n * A binding on a path inside the field — `hero.eyebrow` for the field `hero` —\n * makes it addressable. The diff names top-level fields only, so without this\n * every group and array on the page would look unbound.\n */\nexport function hasBindingBelow(\n cache: ElementCache,\n fieldName: string,\n ownerKeys: OwnerScope,\n): boolean {\n const prefix = `${fieldName}.`;\n for (const [boundName, bindings] of cache.entries()) {\n if (!boundName.startsWith(prefix)) continue;\n if (ownerKeys === false) return true;\n if (bindings.some((binding) => isBindingInScope(binding.owner, ownerKeys))) return true;\n }\n return false;\n}\n\nexport function stripLocaleSuffix(name: string, locale: string | undefined): string {\n if (locale === undefined || locale.length === 0) return name;\n const suffix = `_${locale}`;\n return name.endsWith(suffix) ? name.slice(0, -suffix.length) : name;\n}\n\n/** Whether any binding on the page belongs to the document this update carries. */\nexport function ownsAnyBinding(cache: ElementCache, ownerKeys: readonly string[] | null): boolean {\n for (const binding of cache.values()) {\n if (isBindingInScope(binding.owner, ownerKeys)) return true;\n }\n return false;\n}\n\n/**\n * The same rule for a caller that has names rather than the cache: the\n * `data-payload-field` values in a document, which is all a plugin can see\n * (`src/plugins/built-in/unbound-fields-overlay.ts`).\n *\n * It answers the first three of the four questions below — exact name, the\n * locale-stripped base, a binding on a path inside the field. The fourth needs\n * each binding's own `data-payload-locale`, which is a property of the element\n * rather than of its name, so a caller with names alone cannot ask it.\n */\nexport function createNameAddressability(\n boundNames: Iterable<string>,\n locale: string | undefined,\n): FieldAddressability {\n const names = new Set(boundNames);\n const covers = (fieldName: string): boolean => {\n if (names.has(fieldName)) return true;\n const prefix = `${fieldName}.`;\n for (const bound of names) if (bound.startsWith(prefix)) return true;\n return false;\n };\n return (fieldName) => {\n if (covers(fieldName)) return true;\n const base = stripLocaleSuffix(fieldName, locale);\n return base !== fieldName && covers(base);\n };\n}\n\n/**\n * The predicate for one update. The localised index is built on first use:\n * most fields are answered by the two cheap lookups before it.\n */\nexport function createFieldAddressability(\n cache: ElementCache,\n locale: string | undefined,\n ownerKeys: OwnerScope,\n): FieldAddressability {\n let localised: Set<string> | undefined;\n return (fieldName) => {\n if (hasBinding(cache, fieldName, ownerKeys)) return true;\n const base = stripLocaleSuffix(fieldName, locale);\n if (base !== fieldName && hasBinding(cache, base, ownerKeys)) return true;\n if (hasBindingBelow(cache, fieldName, ownerKeys)) return true;\n if (base !== fieldName && hasBindingBelow(cache, base, ownerKeys)) return true;\n localised ??= localisedBindingNames(cache, ownerKeys);\n return localised.has(fieldName);\n };\n}\n\n/**\n * The fields a revision changed that the page has nowhere to put: the rule\n * above, asked of a diff instead of a document. Both profiles ask it — the full\n * one to decide whether the whole route is the only honest answer, the lean one\n * because the finding is worth recording even where nothing can act on it — so\n * it stands here, beside the rule it is made of, rather than in either runner.\n */\nexport function unboundChangedFields(\n cache: ElementCache,\n touched: ReadonlySet<string>,\n locale: string | undefined,\n ownerKeys: OwnerScope,\n): string[] {\n const isAddressable = createFieldAddressability(cache, locale, ownerKeys);\n const unbound: string[] = [];\n for (const fieldName of touched) {\n if (!SYSTEM_FIELD_NAMES.has(fieldName) && !isAddressable(fieldName)) unbound.push(fieldName);\n }\n return unbound;\n}\n","/**\n * Whether an accepted message has to be resolved against the server before the\n * page can render it, and how many round trips a burst of them may cost. The\n * merge exists to populate relationships and uploads, so a page that renders\n * none of them needs no request at all, a message that moved no populated field\n * is answered from its own values over what the last merge resolved, and what\n * is left goes out once at the start of a burst and once at its end.\n *\n * Conservative in one direction on purpose: a request left out that was needed\n * puts an id where a name belongs and leaves it there, while one request too\n * many costs a round trip nobody sees.\n */\n\nimport { lookupSchema, type SchemaIndex } from '@schema/index';\nimport type { ElementCache } from './cache';\nimport type { DataMerger, MergeRequest, MergeResult } from './data-merger';\nimport type { DependencyMap } from './dependencies';\nimport { FieldChangeTracker } from './field-changes';\nimport type { RuntimeDeps, UpdateTransaction } from './runtime-state';\nimport { FRAGMENT_ATTRIBUTE } from './strategies';\nimport { hasBindingBelow, SYSTEM_FIELD_NAMES } from './unbound-fields';\n\n/**\n * Renderer keys and Payload types whose value the panel posts complete: a\n * scalar, with nothing inside it and nothing behind it to resolve. One\n * vocabulary answers both questions asked here — whether a page reads anything\n * the server populates, and whether one field does — because they are the same\n * question about a binding and about a value.\n */\nconst SELF_SUFFICIENT_TYPES: ReadonlySet<string> = new Set([\n 'text',\n 'textarea',\n 'email',\n 'number',\n 'checkbox',\n 'date',\n 'select',\n 'radio',\n 'point',\n 'code',\n 'json',\n 'ui',\n 'html',\n]);\n\n/** The raw diff answers \"what did the editor move\", which no dependency map changes. */\nconst NO_DEPENDENCIES: DependencyMap = {};\n\nexport interface MergePlan {\n /** Whether the server can still add something to these values. */\n readonly merge: boolean;\n /** The best document without it: this message's own values over the last resolved one. */\n readonly fields: Record<string, unknown>;\n}\n\nexport interface CoalescedMerge {\n /** Whether the request went out now. A deferred one lands after the window and refines what was rendered. */\n readonly leading: boolean;\n readonly result: Promise<MergeResult>;\n}\n\ninterface PendingMerge {\n readonly promise: Promise<MergeResult>;\n readonly settle: (result: MergeResult) => void;\n}\n\nexport class MergeNeed {\n /** What the panel last posted, so \"changed\" means what the editor moved, not what population added. */\n private readonly rawChanges = new FieldChangeTracker();\n private resolved: Record<string, unknown> | null = null;\n private queued: MergeRequest | null = null;\n private pending: PendingMerge | null = null;\n private timer: ReturnType<typeof setTimeout> | null = null;\n private openUntil = 0;\n\n /**\n * The decision, in the order the audit found the ways to get it wrong.\n *\n * 1. **Nothing on the page reads a populated value**, either because nobody\n * reads anything (LP-4) or because every binding renders a plain scalar.\n * See `readsPopulatedValues`.\n * 2. **Nothing populated moved** (LP-3): the fields the editor changed are\n * scalars that name no document, so they are taken from the message and\n * the rest is carried over from what the last merge resolved. Typing a\n * title costs nothing.\n *\n * What is left needs the server. It still renders at once — from the same\n * carried-over document — so the answer is not what the page waits for;\n * `request()` decides how often it is actually asked.\n */\n decide(deps: RuntimeDeps, transaction: UpdateTransaction): MergePlan {\n const raw = transaction.message.data ?? {};\n // Advanced for every message, including the ones that return here: the next\n // diff has to be against what the panel last posted either way.\n const { changed } = this.rawChanges.diff(raw, NO_DEPENDENCIES);\n if (!readsPopulatedValues(deps)) return { merge: false, fields: raw };\n const base = this.resolved;\n // The first message has nothing to carry over, so it buys the document once.\n if (base === null) {\n this.resolved = raw;\n return { merge: true, fields: raw };\n }\n const fields: Record<string, unknown> = { ...base };\n // A save in another document changes what population returns without moving\n // one value here (LP-1) — the one reason to ask that no field can state.\n let merge = transaction.forceRender;\n for (const field of changed) {\n const value = raw[field];\n if (SYSTEM_FIELD_NAMES.has(field)) {\n fields[field] = value;\n continue;\n }\n const verdict = verdictFor(field, base[field], value, deps.cache, transaction.schemaIndex);\n if (verdict !== 'own') merge = true;\n if (verdict !== 'keep') fields[field] = value;\n }\n this.resolved = fields;\n return { merge, fields };\n }\n\n /**\n * One request goes out now and the rest of a burst share the one that follows\n * its last message. The abort stays where it was: `DataMerger` still drops an\n * answer a newer request superseded, and what changes here is only how often\n * it is asked.\n *\n * The window is the scheduler's debounce, because it is the same burst: the\n * writes of one are coalesced into a single flush, and this is the request\n * behind them. A page that turns the debounce off turns this off with it.\n */\n request(merger: DataMerger, windowMs: number, request: MergeRequest): CoalescedMerge {\n const now = Date.now();\n if (now >= this.openUntil) {\n // The clock has closed the window, but its timer may not have run: a busy\n // main thread or a throttled engine fires it late. Left queued, that older\n // request would go out after this one, and `DataMerger` — which keeps the\n // newest request — would drop this keystroke's answer; measured in WebKit\n // as a preview one keystroke behind. This request carries the newer values.\n this.dropQueued();\n this.openUntil = now + windowMs;\n return { leading: true, result: merger.merge(request) };\n }\n this.queued = request;\n this.openUntil = now + windowMs;\n this.pending ??= createPending();\n if (this.timer !== null) clearTimeout(this.timer);\n this.timer = setTimeout(() => {\n this.flush(merger);\n }, windowMs);\n return { leading: false, result: this.pending.promise };\n }\n\n /** The server's document replaces what was carried over; the next message builds on it. */\n recordMerged(doc: Record<string, unknown>): void {\n this.resolved = doc;\n }\n\n destroy(): void {\n this.dropQueued();\n this.openUntil = 0;\n }\n\n /** Drop a queued request; whoever waits on it keeps what they already rendered. */\n private dropQueued(): void {\n if (this.timer !== null) clearTimeout(this.timer);\n this.timer = null;\n this.queued = null;\n this.pending?.settle({ status: 'superseded' });\n this.pending = null;\n }\n\n private flush(merger: DataMerger): void {\n const pending = this.pending;\n const request = this.queued;\n this.timer = null;\n this.pending = null;\n this.queued = null;\n if (pending === null || request === null) return;\n merger.merge(request).then(pending.settle, () => {\n pending.settle({ status: 'unavailable' });\n });\n }\n}\n\n/** What one changed field's own value is worth. */\ntype FieldVerdict =\n /** Everything the page can render is in it. */\n | 'own'\n /** It can be rendered now, and the server may still complete something inside it. */\n | 'ask'\n /** It is a bare id where a document stood; writing it would put that id on the page. */\n | 'keep';\n\nfunction verdictFor(\n field: string,\n previous: unknown,\n value: unknown,\n cache: ElementCache,\n schemaIndex: SchemaIndex | undefined,\n): FieldVerdict {\n // A structure — a rich-text tree, an array, a group — may hold a reference\n // inside it, and the message's own copy of it is still what the editor typed.\n if (!isScalar(value)) return 'ask';\n if (!isScalar(previous) || namesAReference(field, cache, schemaIndex)) return 'keep';\n // A field that was empty can be filled with either a word or an id, and the\n // two look alike. Render it and ask: a word must not wait for the answer.\n return previous == null ? 'ask' : 'own';\n}\n\n/** A document id and a title are both strings; only the schema or a binding says which this is. */\nfunction namesAReference(\n field: string,\n cache: ElementCache,\n schemaIndex: SchemaIndex | undefined,\n): boolean {\n const schema = schemaIndex === undefined ? undefined : lookupSchema(schemaIndex, field);\n if (schema !== undefined && !SELF_SUFFICIENT_TYPES.has(schema.type)) return true;\n if (cache.get(field)?.some(rendersAReference) === true) return true;\n // `venue.title` is a page saying the field holds a document; the owner scope\n // is off here on purpose, because a binding in any document still says so.\n return hasBindingBelow(cache, field, false);\n}\n\nfunction rendersAReference(binding: { readonly fieldType: string }): boolean {\n // A project renderer is unknown ground: it may resolve the value itself.\n return !SELF_SUFFICIENT_TYPES.has(binding.fieldType);\n}\n\n/**\n * Whether anything on this page reads a value the server would populate.\n *\n * Two findings meet here. LP-4: a page with no binding, no island, no boundary\n * a fragment strategy would render and no listener reading the document has\n * nobody to hand the answer to — measured on such a page, 17 keystrokes cost 19\n * authenticated POSTs. LP-3: a page whose every binding is a plain scalar\n * renderer on a top-level field renders the panel's own values exactly, so the\n * merge could only hand back what the message already carries.\n *\n * The route is deliberately not a reason to ask. Since Z3 an unbound change\n * escalates to it by default, but a refresh re-renders the page from the server\n * and never looks at these values.\n */\nfunction readsPopulatedValues(deps: RuntimeDeps): boolean {\n const { cache, emitter } = deps;\n if (cache.islands.length > 0) return true;\n if (emitter.listenerCount('beforeUpdate') > 0 || emitter.listenerCount('afterUpdate') > 0) {\n return true;\n }\n for (const binding of cache.values()) {\n // A reference renderer, a value with structure, or a path inside a field.\n if (rendersAReference(binding) || binding.fieldName.includes('.')) return true;\n if (isPath(binding.hrefField) || isPath(binding.srcField) || isPath(binding.altField)) {\n return true;\n }\n }\n // A boundary is rendered by a server that is handed exactly these fields.\n return (\n deps.strategies.fragment !== undefined &&\n deps.root.querySelector(`[${FRAGMENT_ATTRIBUTE}]`) !== null\n );\n}\n\nfunction isScalar(value: unknown): boolean {\n return value === null || (typeof value !== 'object' && typeof value !== 'function');\n}\n\nfunction isPath(field: string | undefined): boolean {\n return field?.includes('.') === true;\n}\n\nfunction createPending(): PendingMerge {\n let settle!: (result: MergeResult) => void;\n const promise = new Promise<MergeResult>((resolve) => {\n settle = resolve;\n });\n return { promise, settle };\n}\n","/** Tracks the announced protocol version and the capabilities seen on the wire. */\n\nimport {\n LIBRARY_PROTOCOL_VERSION,\n negotiateProtocol,\n type ProtocolCapability,\n type ProtocolNegotiation,\n} from './protocol-version';\n\nexport class ProtocolTracker {\n negotiation: ProtocolNegotiation = negotiateProtocol(undefined);\n readonly observed = new Set<ProtocolCapability>();\n\n /** Record capabilities a message demonstrated; the stock admin announces no version. */\n observe(capabilities: readonly ProtocolCapability[], log: (...args: unknown[]) => void): void {\n const fresh = capabilities.filter((capability) => !this.observed.has(capability));\n if (fresh.length === 0) return;\n for (const capability of fresh) this.observed.add(capability);\n this.negotiation = negotiateProtocol(this.negotiation.theirs, this.observed);\n log('protocol', `observed=${fresh.join(',')}`);\n }\n\n applyVersion(remoteVersion: number, log: (...args: unknown[]) => void): void {\n const current = this.negotiation;\n if (current.theirs === remoteVersion) return;\n const next = negotiateProtocol(remoteVersion, this.observed);\n this.negotiation = next;\n if (next.negotiated === current.negotiated) return;\n log(\n 'protocol',\n `ours=${LIBRARY_PROTOCOL_VERSION}`,\n `theirs=${remoteVersion}`,\n `negotiated=${next.negotiated}`,\n );\n }\n}\n","/**\n * Reads `externallyUpdatedRelationship` as an edge, not as a level. Payload's\n * panel fills the field from `useDocumentEvents().mostRecentUpdate`, a state\n * that every save of the previewed document raises and that nothing ever\n * clears, so the same event repeats in every message for the rest of the\n * session. Two questions make it news again: has the event changed since the\n * last one, and does it name a document other than the one on this page.\n */\n\nimport type {\n PayloadDocumentEventDetail,\n PayloadLivePreviewMessage,\n} from '@/types/payload-protocol';\nimport { readDocumentId } from './binding-owner';\n\n/**\n * Whether the event names a document other than the one this message previews.\n * A message that says which document that is settles it in both directions;\n * one that does not is taken at the event's word, because the repeat is\n * already handled by the identity and one re-render costs less than a drawer\n * edit the page never shows.\n */\nfunction namesAnotherDocument(\n event: PayloadDocumentEventDetail,\n message: PayloadLivePreviewMessage,\n): boolean {\n const previewedSlug = message.globalSlug ?? message.collectionSlug;\n if (typeof previewedSlug !== 'string' || event.entitySlug !== previewedSlug) return true;\n // The same entity. A global holds one document, so the event is its own\n // save; a collection is proven different only when both ids are known and\n // differ.\n const id = readDocumentId(event);\n const previewedId = readDocumentId(message.data ?? {});\n return id !== undefined && previewedId !== undefined && id !== previewedId;\n}\n\n/**\n * Whether the revision a new one supersedes still owes the page a drawer edit.\n *\n * The edit is news on exactly one message, and the panel posts the repeat in\n * the same burst: it supersedes the revision that carried the edit before the\n * server's populated answer arrives, so that answer is dropped, and the repeat\n * asks for nothing itself. The obligation passes to whoever supersedes it and\n * stops at the revision that completes.\n */\nexport function owesForceRender(\n previous: { readonly forceRender: boolean; readonly completed: boolean } | null,\n): boolean {\n return previous !== null && previous.forceRender && !previous.completed;\n}\n\n/** Remembers the last document event the panel sent, so its repeats are one event. */\nexport class RelationshipTracker {\n /**\n * Identity of the last event seen. Not `id` alone: a global's save carries\n * none, and an identity that required one would read every global save as a\n * new document.\n */\n private lastIdentity: string | undefined = undefined;\n\n /**\n * The edit this message brings that the page has not acted on yet: a changed\n * event about another document. `null` for a message without the field, for\n * the repeat, and for the previewed document's own save.\n */\n edit(message: PayloadLivePreviewMessage): PayloadDocumentEventDetail | null {\n const event = message.externallyUpdatedRelationship;\n if (typeof event !== 'object' || event === null) return null;\n const identity = JSON.stringify([event.entitySlug, readDocumentId(event), event.updatedAt]);\n const isNew = identity !== this.lastIdentity;\n this.lastIdentity = identity;\n return isNew && namesAnotherDocument(event, message) ? event : null;\n }\n}\n","/**\n * Scroll the edited field's bound element into view. Deliberately quiet: only\n * when the target is off-screen and only when the edited field changed since\n * the last reveal, so continuous typing never re-scrolls and a deliberate\n * scroll-away is not fought. Honours `prefers-reduced-motion`.\n */\n\n/** The slice of `Window` this reads, so it tests without a browser. */\nexport interface RevealWindow {\n readonly innerHeight: number;\n readonly innerWidth: number;\n matchMedia?: (query: string) => { readonly matches: boolean };\n}\n\n/** The slice of `Element` this module needs. */\nexport interface RevealElement {\n getBoundingClientRect: () => {\n readonly top: number;\n readonly bottom: number;\n readonly left: number;\n readonly right: number;\n };\n scrollIntoView: (options?: {\n behavior?: 'auto' | 'smooth';\n block?: 'center' | 'nearest' | 'start';\n }) => void;\n}\n\n/** Whether the viewer asked for reduced motion; smooth scrolling is suppressed when so. */\nexport function prefersReducedMotion(win: RevealWindow): boolean {\n try {\n return win.matchMedia?.('(prefers-reduced-motion: reduce)').matches === true;\n } catch {\n return false;\n }\n}\n\n/** A visible sliver counts: an element the editor can already see is never scrolled to. */\nexport function isInViewport(element: RevealElement, win: RevealWindow): boolean {\n const rect = element.getBoundingClientRect();\n const vertically = rect.bottom > 0 && rect.top < win.innerHeight;\n const horizontally = rect.right > 0 && rect.left < win.innerWidth;\n return vertically && horizontally;\n}\n\n/** Outcome of a reveal attempt, for the caller's diagnostics. */\nexport type RevealOutcome = 'revealed' | 'already-visible';\n\n/** Scroll `element` into view only when it is off-screen. */\nexport function revealElement(element: RevealElement, win: RevealWindow): RevealOutcome {\n if (isInViewport(element, win)) return 'already-visible';\n element.scrollIntoView({\n behavior: prefersReducedMotion(win) ? 'auto' : 'smooth',\n block: 'center',\n });\n return 'revealed';\n}\n\n/** Remembers the last field revealed, so only a change of field scrolls again. */\nexport class FieldRevealer {\n #lastField: string | undefined;\n\n /** `skipped-same` when this is still the field last revealed. */\n reveal(\n fieldName: string,\n element: RevealElement,\n win: RevealWindow,\n ): RevealOutcome | 'skipped-same' {\n if (fieldName === this.#lastField) return 'skipped-same';\n this.#lastField = fieldName;\n return revealElement(element, win);\n }\n\n /** Forget the last field, after a navigation that rebuilt the page. */\n reset(): void {\n this.#lastField = undefined;\n }\n}\n","/**\n * Which value each owned field was last seen with, and the one binding a\n * revision should scroll to: the bookkeeping behind \"reveal the edited field\",\n * kept apart from the pipeline that schedules the writes.\n *\n * Keyed by document, locale and field rather than by element. The element a\n * fragment renders does not survive its own re-render, but the field it shows\n * is the same field.\n *\n * The ledger is written only when a revision reaches its reveal point, not when\n * a candidate is noted. Writing at once lost reveals: an identical re-send\n * superseded the revision that had noted the change, then found nothing new.\n */\n\nimport { valueIdentity } from './value-identity';\n\n/** What the ledger needs of a binding: the key parts, and the element to reveal. */\nexport interface RevealKey {\n readonly owner?: string | undefined;\n readonly locale?: string | undefined;\n readonly fieldName: string;\n}\n\n/** The per-revision slot the ledger fills; the transaction carries it. */\nexport interface RevealSlot<T extends RevealKey> {\n revealIdentities: [key: string, identity: string][];\n revealTarget: T | undefined;\n}\n\nexport class RevealLedger {\n private readonly seen = new Map<string, string>();\n\n /**\n * Record what this binding's value looks like now and, for the first binding\n * whose value moved, mark it as the one to reveal.\n *\n * The first message is a baseline and a binding new to the page is not an\n * edit, so an unseen key only records. A value too large or cyclic to compare\n * cannot claim to have changed either, or it would take the reveal from a\n * field that did.\n */\n note<T extends RevealKey>(slot: RevealSlot<T>, target: T, value: unknown): void {\n const identity = valueIdentity(value);\n if (identity === undefined) return;\n const key = `${target.owner ?? ''}\u0000${target.locale ?? ''}\u0000${target.fieldName}`;\n const seen = this.seen.get(key);\n if (seen === undefined) {\n // A baseline is recorded at once: nothing is owed for it.\n this.seen.set(key, identity);\n return;\n }\n if (seen === identity) return;\n slot.revealIdentities.push([key, identity]);\n slot.revealTarget ??= target;\n }\n\n /**\n * The revision reached its reveal point: what it saw is now what the ledger\n * shows, whether or not there is anything to scroll to. Hands out the\n * binding to reveal once; a second call finds the slot empty.\n */\n commit<T extends RevealKey>(slot: RevealSlot<T>): T | undefined {\n for (const [key, identity] of slot.revealIdentities) this.seen.set(key, identity);\n slot.revealIdentities = [];\n const target = slot.revealTarget;\n slot.revealTarget = undefined;\n return target;\n }\n}\n","/**\n * What the runtime owns for its lifetime (`RuntimeDeps`) and what changes as it\n * runs (`RuntimeState`). Both are shared by the pipeline collaborators.\n */\n\nimport type { PayloadFieldSchema, PayloadLivePreviewMessage } from '@/types/payload-protocol';\nimport type { EventEmitter } from '@events/emitter';\nimport type { SchemaIndex } from '@schema/index';\nimport type { SanitizerPolicyMode } from '@security/sanitizer';\nimport type { A11yAnnouncer } from './a11y';\nimport type { AutoBindMode, KeptGuesses } from './auto-bind';\nimport type { ElementCache } from './cache';\nimport type { DataMerger } from './data-merger';\nimport type { UnfaithfulPatchMode } from './fidelity';\nimport type { HydrationMode, HydrationState } from './hydration';\nimport { FieldChangeTracker } from './field-changes';\nimport { MergeNeed } from './merge-need';\nimport type { MessageBus, MessageRevision } from './message-bus';\nimport type { ObserverManager } from './observers';\nimport { ProtocolTracker } from './protocol-tracker';\nimport { RelationshipTracker } from './relationship-tracker';\nimport { FieldRevealer } from './reveal';\nimport { RevealLedger } from './reveal-ledger';\nimport type { RuntimeOptions } from './runtime-options';\nimport type { ConnectionState, HeartbeatTimer } from './state';\nimport type { StrategyHandlers } from './strategies';\nimport type { CachedElement, FieldRenderer, RichTextRenderer } from './types';\nimport type { FlushStats, UpdateScheduler } from './update-scheduler';\n\n/** One accepted message on its way to the DOM. See ADR 0004. */\nexport interface UpdateTransaction {\n readonly revision: MessageRevision;\n readonly message: PayloadLivePreviewMessage;\n readonly locale: string | undefined;\n readonly schema: readonly PayloadFieldSchema[] | undefined;\n readonly schemaIndex: SchemaIndex | undefined;\n readonly receivedAt: number;\n /** A save in another document may change populated values only, so render everything. */\n readonly forceRender: boolean;\n /** Top-level fields whose value changed since the previous message, plus their dependents. */\n touched: ReadonlySet<string>;\n /** The connection's first message, where every field counts as changed. */\n baseline: boolean;\n /** Dependents of changed fields; re-applied even when their own value is unchanged. */\n invalidated: ReadonlySet<string>;\n /**\n * First binding whose value changed; revealed once its write landed. The\n * binding itself, not its field name: several documents on one page share\n * field names, and only this one belongs to the edited document.\n */\n revealTarget: CachedElement | undefined;\n /**\n * Identities the reveal ledger will record once this revision reaches its\n * reveal point — not before. A revision superseded on the way there never\n * revealed, so the ledger must still show the previous value: the message\n * that supersedes it is then the one that owes the reveal.\n */\n revealIdentities: [key: string, identity: string][];\n pendingFragments: number;\n routeRefreshed: boolean;\n cancelled: boolean;\n /** Terminal: the scheduled writes reached the DOM (or there were none). */\n completed: boolean;\n}\n\nexport interface RuntimeDeps {\n readonly emitter: EventEmitter;\n readonly cache: ElementCache;\n readonly observers: ObserverManager;\n readonly scheduler: UpdateScheduler;\n readonly bus: MessageBus;\n readonly connection: ConnectionState;\n readonly heartbeat: HeartbeatTimer;\n readonly renderers: Readonly<Record<string, FieldRenderer>>;\n readonly resolveRenderer: NonNullable<RuntimeOptions['resolveRenderer']>;\n readonly transformValue: RuntimeOptions['transformValue'];\n readonly renderRichText: RichTextRenderer | undefined;\n readonly sanitizerPolicy: SanitizerPolicyMode | undefined;\n readonly root: Document | Element;\n readonly readyTargets: () => readonly string[];\n readonly sendReady: (origins: readonly string[]) => void;\n readonly onHeartbeatTimeout: RuntimeOptions['onHeartbeatTimeout'];\n readonly log: (...args: unknown[]) => void;\n readonly warn: (...args: unknown[]) => void;\n readonly a11y: A11yAnnouncer | null;\n readonly merger: DataMerger | null;\n /** How long a burst of messages may share one merge; the scheduler's debounce window. */\n readonly mergeWindowMs: number;\n readonly scopeBindingsByOwner: boolean;\n readonly lockedOrigin: () => string | undefined;\n readonly skipUnchanged: boolean;\n readonly dependencies: Readonly<Record<string, readonly string[]>>;\n readonly strategies: StrategyHandlers;\n readonly revealEditedField: boolean;\n /** What to do about a patch the runtime knows cannot match the server's render. */\n readonly onUnfaithfulPatch: UnfaithfulPatchMode;\n /** Whether the first message is searched for bindings by value (ADR 0014). */\n readonly autoBind: AutoBindMode;\n /** The framework whose first commit the start waits for (ADR 0015); `undefined` on a page that declared none. */\n readonly hydration: HydrationMode | undefined;\n}\n\nexport class RuntimeState {\n started = false;\n /** Set by `suspend()`; lets `destroy()` finish a suspended instance. */\n suspended = false;\n /** Cancels a startup still waiting — for `DOMContentLoaded`, or for the framework's first commit (ADR 0015). */\n deferredStart: (() => void) | null = null;\n /** How far the wait for hydration got; `idle` on a page that declared none. */\n hydration: HydrationState = 'idle';\n activeUpdate: UpdateTransaction | null = null;\n locale: string | undefined = undefined;\n schema: readonly PayloadFieldSchema[] | undefined = undefined;\n schemaIndex: SchemaIndex | undefined = undefined;\n updateCount = 0;\n supersededCount = 0;\n completedCount = 0;\n skippedUnchangedCount = 0;\n lastFlush: FlushStats | null = null;\n readonly absentFields = new Set<string>();\n readonly warnedOrphanFields = new Set<string>();\n readonly warnedStrategy = new WeakSet<Element>();\n warnedUnattributableMessage = false;\n warnedVisibilityGate = false;\n warnedFragmentFallback = false;\n /** LP0503 is reported once: a drifting sender repeats the same shape on every keystroke. */\n warnedProtocolShape = false;\n /** LP0411 is reported once per element; the markup that causes it does not change. */\n readonly reportedUnfaithful = new WeakSet<Element>();\n /** Bindings whose first write has already been held against what the template printed (LP0412). */\n readonly checkedServerFormat = new WeakSet<Element>();\n /** Bindings this revision could not patch faithfully, drained by the flush that escalates them. */\n unfaithfulPatches: CachedElement[] = [];\n /** Every binding ever reported unfaithful, and how many of them a strategy was handed; `inspect().fidelity`. */\n unfaithfulCount = 0;\n escalatedCount = 0;\n readonly unfaithfulFields = new Set<string>();\n /** What the one auto-binding search cost, for `inspect()`; `undefined` until it ran. */\n autoBindSearchMs: number | undefined = undefined;\n /** What that search bound, looked for again after a route refresh (ADR 0014); `null` until it ran. */\n autoBindGuesses: KeptGuesses | null = null;\n\n /**\n * Whether the first message refused for coming from the wrong window has been\n * reported. `eventSourcePolicy` flipped from `'any'` to `'parent-or-opener'`\n * in 2.0, so a 1.x arrangement that posts from anywhere else stops working on\n * upgrade — silently, because a refusal only reaches the debug log.\n */\n warnedForeignSource = false;\n /** Identity of the value each element last applied; reset when the markup is re-rendered. */\n lastAppliedIdentity = new WeakMap<Element, string>();\n /** What each owned field was last seen with, for the reveal decision only. */\n readonly revealLedger = new RevealLedger();\n readonly fragmentStats = { rendered: 0, failed: 0, superseded: 0 };\n readonly routeStats = { refreshes: 0, failed: 0, refused: 0, loopStopped: 0 };\n fragmentController: AbortController | null = null;\n routeController: AbortController | null = null;\n /** The trailing run a refused refresh asked for; at most one, and always the newest. */\n routeRetry: ReturnType<typeof setTimeout> | null = null;\n /**\n * A trailing run a newer revision took over before it ran. That revision\n * plans from its own diff, which no longer names the field the older one\n * changed, so the debt is carried here until a refresh runs.\n */\n routeRefreshOwed = false;\n readonly readyTimers: ReturnType<typeof setTimeout>[] = [];\n readonly revealer = new FieldRevealer();\n readonly changes = new FieldChangeTracker();\n readonly merges = new MergeNeed();\n readonly protocol = new ProtocolTracker();\n readonly relationships = new RelationshipTracker();\n\n /** Read through a method: TypeScript keeps a narrowed `started` across the calls that can flip it. */\n isRunning(): boolean {\n return this.started;\n }\n\n /** Whether `transaction` may still touch the DOM; re-checked after every reentrant callback. */\n isCurrent(transaction: UpdateTransaction): boolean {\n return this.started && this.activeUpdate === transaction;\n }\n\n complete(transaction: UpdateTransaction): void {\n if (transaction.completed) return;\n transaction.completed = true;\n this.completedCount += 1;\n }\n\n /**\n * Abort in-flight strategy work; a newer revision or a stop supersedes it.\n * The trailing route refresh goes with it: the revision that asked for it is\n * no longer the one on screen, and the newer one runs it instead — its\n * message carries the older one's values too, so `routeRefreshOwed` makes\n * it plan the refresh its own diff would not.\n */\n abortStrategies(): void {\n if (this.routeRetry !== null) {\n clearTimeout(this.routeRetry);\n this.routeRetry = null;\n this.routeRefreshOwed = true;\n }\n for (const key of ['fragmentController', 'routeController'] as const) {\n const controller = this[key];\n if (controller === null) continue;\n this[key] = null;\n controller.abort();\n }\n }\n}\n","/**\n * Writes one scheduled value into its bound element: renderer resolution,\n * the attribute or renderer write, and the `elementUpdate` event. Every\n * consumer callback may accept a newer revision synchronously, so the\n * transaction is re-checked after each one (ADR 0004).\n */\n\nimport { definedOnly } from '@/types/defined-only';\nimport { sameRevision } from './message-bus';\nimport { lookupSchema, payloadTypeToRenderer } from '@schema/index';\nimport { applyAttributeBinding } from './attribute-binding';\nimport { reportServerFormatting, reportUnfaithfulPatch, watchServerFormatting } from './fidelity';\nimport { rendererUsesNoWriteOutcome } from './internal-outcome';\nimport { type RuntimeDeps, type RuntimeState, type UpdateTransaction } from './runtime-state';\nimport type { CachedElement, FieldRenderer, RenderContext, RendererKey } from './types';\nimport type { ScheduledUpdate } from './update-scheduler';\n\nexport class BindingWriter {\n /** The instance's share of every `RenderContext`, built once: a write allocates the context alone. */\n private readonly instanceContext: Pick<\n RenderContext,\n 'renderRichText' | 'sanitizerPolicy' | 'reportUnfaithful'\n >;\n\n constructor(\n private readonly deps: RuntimeDeps,\n private readonly state: RuntimeState,\n ) {\n this.instanceContext = definedOnly({\n renderRichText: deps.renderRichText,\n sanitizerPolicy: deps.sanitizerPolicy,\n // A renderer already holds its target, so one closure per instance says\n // as much as one per write and allocates nothing during an update.\n reportUnfaithful: (target: CachedElement, reason: string): void => {\n reportUnfaithfulPatch(deps, state, target, reason);\n },\n });\n }\n\n /** Scheduler callback. `false` means nothing reached the DOM. */\n apply(update: ScheduledUpdate): boolean {\n const { deps, state } = this;\n const transaction = state.activeUpdate;\n if (\n transaction === null ||\n update.revision === undefined ||\n !sameRevision(transaction.revision, update.revision) ||\n !state.isCurrent(transaction)\n ) {\n return false;\n }\n const { target, value } = update;\n const schemaEntry =\n transaction.schemaIndex !== undefined\n ? lookupSchema(transaction.schemaIndex, target.fieldName)\n : undefined;\n let type = resolveFieldType(target, schemaEntry?.type);\n // Payload 3.x sends no schema; a Lexical root is unmistakable.\n if (type === 'text' && target.explicitFieldType !== true && looksLikeLexicalRoot(value)) {\n type = 'richText';\n }\n let renderer: FieldRenderer | undefined;\n try {\n renderer = deps.resolveRenderer(type, target);\n } catch (error) {\n return this.fail(transaction, error);\n }\n if (!state.isCurrent(transaction)) return false;\n const emitElementUpdate = deps.emitter.listenerCount('elementUpdate') > 0;\n // Custom-element accessors run application code, so this is a boundary too.\n const previous = emitElementUpdate ? readElementSnapshot(target.element) : undefined;\n if (!state.isCurrent(transaction)) return false;\n const context: RenderContext = {\n allFields: update.allFields,\n locale: target.locale ?? transaction.locale,\n schema: schemaEntry,\n ...this.instanceContext,\n };\n // A boundary anchor stays out of layout and the accessibility tree while empty.\n if (target.hidesWhenEmpty === true) {\n target.element.toggleAttribute('hidden', isEmptyFieldValue(value));\n }\n try {\n if (target.targetAttribute !== undefined) {\n if (applyAttributeBinding(target.element, target.targetAttribute, value) === 'blocked') {\n deps.warn(\n `[live-preview] LP0401: refused to write \"${target.fieldName}\" into attribute \"${target.targetAttribute}\"`,\n );\n return false;\n }\n } else if (renderer !== undefined) {\n // Read before the write, because afterwards the template's own reading\n // of this value is gone (Z20). Costs nothing unless this is the first\n // write to a binding a formatting renderer owns.\n const shown = watchServerFormatting(deps, state, target, type);\n const outcome = invokeRenderer(renderer, target, value, context);\n if (outcome === false && rendererUsesNoWriteOutcome(renderer)) {\n // The renderer refused the value it was given, so the element still\n // shows what the server put there — right until the next edit makes\n // it stale. That is the moment to ask for better markup.\n reportUnfaithfulPatch(deps, state, target, `is a value ${renderer.name} cannot render`);\n return false;\n }\n if (shown !== undefined) reportServerFormatting(deps, target, shown);\n } else {\n deps.log('no renderer for', type);\n reportUnfaithfulPatch(deps, state, target, `has no renderer for \"${type}\"`);\n return false;\n }\n } catch (error) {\n return this.fail(transaction, error);\n }\n if (!state.isCurrent(transaction)) return false;\n if (emitElementUpdate) {\n void deps.emitter.emitWhile(\n 'elementUpdate',\n {\n element: target.element,\n fieldName: target.fieldName,\n previousValue: previous,\n nextValue: value,\n revision: transaction.revision.revision,\n receivedAt: transaction.receivedAt,\n source: 'patch',\n },\n () => state.isCurrent(transaction),\n );\n }\n // The first handler runs before emitWhile yields; a reentrant newer\n // revision must not count this write as applied.\n const applied = state.isCurrent(transaction);\n if (applied) {\n if (update.valueIdentity !== undefined) {\n state.lastAppliedIdentity.set(target.element, update.valueIdentity);\n } else {\n state.lastAppliedIdentity.delete(target.element);\n }\n }\n return applied;\n }\n\n private fail(transaction: UpdateTransaction, cause: unknown): false {\n if (!this.state.isCurrent(transaction)) return false;\n const error = cause instanceof Error ? cause : new Error(String(cause));\n void this.deps.emitter.emitWhile('error', { error, context: 'renderer', code: 'LP0603' }, () =>\n this.state.isCurrent(transaction),\n );\n return false;\n }\n}\n\n/** Explicit `data-payload-type` wins over the schema, which wins over tag heuristics. */\nfunction resolveFieldType(target: CachedElement, schemaType: string | undefined): RendererKey {\n if (target.explicitFieldType) return target.fieldType;\n if (schemaType !== undefined) {\n const mapped = payloadTypeToRenderer(schemaType);\n if (mapped !== undefined) return mapped;\n }\n return target.fieldType;\n}\n\n/** Built-in renderers may return exact `false` for a deliberate no-write; the public type stays `void`. */\nfunction invokeRenderer(\n renderer: FieldRenderer,\n target: CachedElement,\n value: unknown,\n context: RenderContext,\n): unknown {\n // eslint-disable-next-line @typescript-eslint/no-confusing-void-expression\n return renderer.render(target, value, context);\n}\n\n/** Same shape test as `isLexicalContent`, duplicated so core does not pull the Lexical renderer. */\nfunction looksLikeLexicalRoot(value: unknown): boolean {\n if (typeof value !== 'object' || value === null || !('root' in value)) return false;\n const root = value.root;\n return (\n typeof root === 'object' &&\n root !== null &&\n Array.isArray((root as { children?: unknown }).children)\n );\n}\n\nfunction readElementSnapshot(element: Element): unknown {\n if (element.tagName === 'INPUT' || element.tagName === 'TEXTAREA') {\n return (element as HTMLInputElement).value;\n }\n if (element.tagName === 'IMG') return (element as HTMLImageElement).src;\n return element.textContent;\n}\n\nfunction isEmptyFieldValue(value: unknown): boolean {\n if (value === null || value === undefined) return true;\n if (typeof value === 'string') return value.trim().length === 0;\n return Array.isArray(value) && value.length === 0;\n}\n","/**\n * One source → dependents map for `skipUnchanged`. Markup declares it the\n * other way round (`data-payload-depends=\"price\"` on the element bound to\n * `priceLabel`) because an author names what a binding needs; the runtime\n * option is keyed by source because the scheduler asks what changed.\n * @internal\n */\n\nexport type DependencyMap = Readonly<Record<string, readonly string[]>>;\n\n/**\n * Field names from an attribute value. Separators are commas and\n * whitespace; empty entries are dropped; order is kept, duplicates removed.\n * @internal\n */\nexport function parseDependencyList(value: string | null | undefined): readonly string[] {\n if (value === null || value === undefined) return [];\n const seen = new Set<string>();\n const names: string[] = [];\n for (const raw of value.split(/[\\s,]+/)) {\n const name = raw.trim();\n if (name.length === 0 || seen.has(name)) continue;\n seen.add(name);\n names.push(name);\n }\n return names;\n}\n\n/**\n * Merge dependency maps (source → dependents). Later maps add to earlier\n * ones; a dependent is listed once per source.\n * @internal\n */\nexport function mergeDependencyMaps(...maps: readonly DependencyMap[]): DependencyMap {\n const merged = new Map<string, Set<string>>();\n for (const map of maps) {\n for (const [source, dependents] of Object.entries(map)) {\n let bucket = merged.get(source);\n if (bucket === undefined) {\n bucket = new Set();\n merged.set(source, bucket);\n }\n for (const dependent of dependents) bucket.add(dependent);\n }\n }\n const result: Record<string, readonly string[]> = {};\n for (const [source, dependents] of merged) result[source] = [...dependents];\n return result;\n}\n\n/**\n * The map an element's `data-payload-depends` contributes: every declared\n * source points at this binding's field.\n * @internal\n */\nexport function dependencyMapFromBinding(\n fieldName: string,\n dependsOn: readonly string[],\n): DependencyMap {\n const map: Record<string, readonly string[]> = {};\n for (const source of dependsOn) {\n if (source === fieldName) continue;\n map[source] = [fieldName];\n }\n return map;\n}\n","/**\n * Hydrated islands own their subtree, so the runtime never patches inside one.\n * Instead every flush that carried a change dispatches `payload-live-preview:update`\n * on each island root with the update in `detail`, whether or not a binding\n * outside the islands was written. `data-payload-island=\"patch\"` opts back in.\n * @internal\n */\n\nexport const ISLAND_EVENT = 'payload-live-preview:update';\n/** @internal */\nexport const ISLAND_ATTRIBUTE = 'data-payload-island';\nexport const ISLAND_SELECTOR = `astro-island, [${ISLAND_ATTRIBUTE}]`;\n\nexport interface IslandUpdateDetail {\n readonly fields: Readonly<Record<string, unknown>>;\n readonly revision: number;\n readonly receivedAt: number;\n readonly locale: string | undefined;\n}\n\nfunction isIslandRoot(element: Element): boolean {\n return element.tagName.toLowerCase() === 'astro-island' || element.hasAttribute(ISLAND_ATTRIBUTE);\n}\n\nfunction islandAllowsPatching(island: Element): boolean {\n return island.getAttribute(ISLAND_ATTRIBUTE) === 'patch';\n}\n\n/** Whether `element` itself is an island root that did not opt into patching. */\nexport function isIslandBoundary(element: Element): boolean {\n return isIslandRoot(element) && !islandAllowsPatching(element);\n}\n\n/** Whether `element` (or an ancestor) is an island that did not opt into patching. @internal */\nexport function isInsideIsland(element: Element): boolean {\n let current: Element | null = element;\n while (current !== null) {\n if (isIslandBoundary(current)) return true;\n current = current.parentElement;\n }\n return false;\n}\n\n/** Island roots under `root` that receive update events. */\nexport function collectIslands(root: ParentNode): Element[] {\n const islands: Element[] = [];\n for (const island of root.querySelectorAll(ISLAND_SELECTOR)) {\n if (!islandAllowsPatching(island)) islands.push(island);\n }\n return islands;\n}\n\nexport function dispatchIslandUpdate(\n islands: readonly Element[],\n detail: IslandUpdateDetail,\n): number {\n for (const island of islands) {\n island.dispatchEvent(\n new CustomEvent<IslandUpdateDetail>(ISLAND_EVENT, { detail, bubbles: false }),\n );\n }\n return islands.length;\n}\n","/**\n * Maps field names to their bound elements so an update walks the cache, not\n * the DOM. Everything an update needs about a binding is resolved here, once,\n * at build time.\n */\n\nimport {\n dependencyMapFromBinding,\n mergeDependencyMaps,\n parseDependencyList,\n type DependencyMap,\n} from './dependencies';\nimport { collectIslands } from './islands';\nimport { enclosingFragment, resolveStrategy } from './strategies';\nimport type { CachedElement, ElementPredicate, FieldType, RendererKey } from './types';\n\nexport const FIELD_ATTRIBUTE = 'data-payload-field';\nexport const TYPE_ATTRIBUTE = 'data-payload-type';\nexport const TARGET_ATTRIBUTE_ATTRIBUTE = 'data-payload-attribute';\nexport const HREF_ATTRIBUTE = 'data-payload-href';\nexport const SRC_ATTRIBUTE = 'data-payload-src';\nexport const ALT_ATTRIBUTE = 'data-payload-alt';\nexport const ARRAY_TEMPLATE_ATTRIBUTE = 'data-payload-array-template';\nexport const ARRAY_SEPARATOR_ATTRIBUTE = 'data-payload-array-separator';\nexport const LOCALE_ATTRIBUTE = 'data-payload-locale';\nexport const FORMAT_ATTRIBUTE = 'data-payload-format';\nexport const RICH_TEXT_ATTRIBUTE = 'data-payload-richtext';\nexport const HTML_ATTRIBUTE = 'data-payload-html';\nexport const ARRAY_ATTRIBUTE = 'data-payload-array';\nexport const STRUCTURAL_ATTRIBUTE = 'data-payload-structural';\nexport const OWNER_ATTRIBUTE = 'data-payload-owner';\nexport const DEPENDS_ATTRIBUTE = 'data-payload-depends';\nexport const STRATEGY_ATTRIBUTE = 'data-payload-strategy';\nexport const BOUNDARY_ATTRIBUTE = 'data-payload-boundary';\n/**\n * Written by the runtime, never by a template: the value an auto-binding\n * matched on (ADR 0014). Its presence is what tells a guessed binding from a\n * declared one, in `inspect()` and in the overlay.\n */\nexport const GUESSED_ATTRIBUTE = 'data-payload-guessed';\nexport const INPUT_TYPE_ATTRIBUTE = 'type';\n\n/**\n * Attributes captured in a `CachedElement`. The mutation observer watches\n * exactly this list, so a snapshot can never go stale on a mounted element.\n */\nexport const BINDING_ATTRIBUTES: readonly string[] = [\n FIELD_ATTRIBUTE,\n TYPE_ATTRIBUTE,\n TARGET_ATTRIBUTE_ATTRIBUTE,\n HREF_ATTRIBUTE,\n SRC_ATTRIBUTE,\n ALT_ATTRIBUTE,\n ARRAY_TEMPLATE_ATTRIBUTE,\n ARRAY_SEPARATOR_ATTRIBUTE,\n LOCALE_ATTRIBUTE,\n RICH_TEXT_ATTRIBUTE,\n HTML_ATTRIBUTE,\n ARRAY_ATTRIBUTE,\n STRUCTURAL_ATTRIBUTE,\n OWNER_ATTRIBUTE,\n DEPENDS_ATTRIBUTE,\n STRATEGY_ATTRIBUTE,\n BOUNDARY_ATTRIBUTE,\n INPUT_TYPE_ATTRIBUTE,\n];\n\nconst FIELD_SELECTOR = `[${FIELD_ATTRIBUTE}]`;\nconst OWNER_SELECTOR = `[${OWNER_ATTRIBUTE}]`;\n\n/** The document a binding belongs to: its nearest `data-payload-owner`, itself included. */\nexport function resolveBindingOwner(element: Element): string | undefined {\n const owner = element.closest(OWNER_SELECTOR)?.getAttribute(OWNER_ATTRIBUTE);\n return owner === null || owner === undefined || owner.length === 0 ? undefined : owner;\n}\n\n/** `namespace:name` — a project renderer key can never be a typo of a built-in type. */\nconst CUSTOM_RENDERER_KEY = /^[a-z][a-z0-9-]*:[a-z][a-z0-9-]*$/i;\n\nconst VALID_FIELD_TYPES: ReadonlySet<FieldType> = new Set<FieldType>([\n 'text',\n 'textarea',\n 'richText',\n 'email',\n 'number',\n 'checkbox',\n 'date',\n 'select',\n 'radio',\n 'array',\n 'blocks',\n 'group',\n 'tabs',\n 'row',\n 'collapsible',\n 'relationship',\n 'upload',\n 'point',\n 'json',\n 'code',\n 'ui',\n 'html',\n 'url',\n 'image',\n 'structural-array',\n]);\n\nfunction isRendererKey(value: string): value is RendererKey {\n return VALID_FIELD_TYPES.has(value as FieldType) || CUSTOM_RENDERER_KEY.test(value);\n}\n\nexport interface CacheBuildStats {\n readonly elementCount: number;\n readonly fieldCount: number;\n readonly durationMs: number;\n}\n\nexport interface ElementCacheOptions {\n /** Restricts which elements are accepted. Defaults to all. */\n readonly filter?: ElementPredicate;\n}\n\n/**\n * Elements share a field name when the same field is rendered in several\n * places; within a field the order is DOM order.\n */\nexport class ElementCache {\n private readonly entriesByField = new Map<string, CachedElement[]>();\n private entryByElement = new WeakMap<Element, CachedElement>();\n private readonly filter: ElementPredicate;\n private count = 0;\n private dependencies: DependencyMap | null = null;\n private islandRoots: readonly Element[] = [];\n\n constructor(options: ElementCacheOptions = {}) {\n this.filter = options.filter ?? alwaysTrue;\n }\n\n /** Source → dependents declared with `data-payload-depends`; memoised until the cache changes. */\n dependencyMap(): DependencyMap {\n if (this.dependencies !== null) return this.dependencies;\n const maps: DependencyMap[] = [];\n for (const binding of this.values()) {\n if (binding.dependsOn !== undefined) {\n maps.push(dependencyMapFromBinding(binding.fieldName, binding.dependsOn));\n }\n }\n this.dependencies = mergeDependencyMaps(...maps);\n return this.dependencies;\n }\n\n /** Island roots under the last built root, for update events. */\n get islands(): readonly Element[] {\n return this.islandRoots;\n }\n\n buildFromRoot(root: ParentNode): CacheBuildStats {\n const t0 = performance.now();\n this.clear();\n let elementCount = 0;\n for (const element of root.querySelectorAll(FIELD_SELECTOR)) {\n if (this.add(element) !== undefined) elementCount += 1;\n }\n this.islandRoots = collectIslands(root);\n return {\n elementCount,\n fieldCount: this.entriesByField.size,\n durationMs: performance.now() - t0,\n };\n }\n\n /**\n * Insert or replace a single element's binding. Re-adding refreshes the\n * snapshot in place; an element that is now filtered or unbound is removed.\n */\n add(element: Element): CachedElement | undefined {\n // Resolve before mutating so a throwing filter leaves the old entry intact.\n const entry = this.filter(element) ? this.resolveBinding(element) : undefined;\n const previous = this.entryByElement.get(element);\n this.dependencies = null;\n if (entry === undefined) {\n if (previous !== undefined) this.removeEntry(element, previous);\n return undefined;\n }\n if (previous !== undefined && this.replaceEntry(previous, entry)) {\n this.entryByElement.set(element, entry);\n return entry;\n }\n if (previous !== undefined) this.removeEntry(element, previous);\n this.append(entry);\n this.entryByElement.set(element, entry);\n return entry;\n }\n\n /** Returns whether a binding was removed. */\n remove(element: Element): boolean {\n const entry = this.entryByElement.get(element);\n if (!entry) return false;\n this.dependencies = null;\n return this.removeEntry(element, entry);\n }\n\n get(fieldName: string): readonly CachedElement[] | undefined {\n return this.entriesByField.get(fieldName);\n }\n\n getByElement(element: Element): CachedElement | undefined {\n return this.entryByElement.get(element);\n }\n\n get fieldCount(): number {\n return this.entriesByField.size;\n }\n\n get elementCount(): number {\n return this.count;\n }\n\n entries(): IterableIterator<[string, readonly CachedElement[]]> {\n return this.entriesByField.entries() as IterableIterator<[string, readonly CachedElement[]]>;\n }\n\n *values(): IterableIterator<CachedElement> {\n for (const bucket of this.entriesByField.values()) yield* bucket;\n }\n\n has(element: Element): boolean {\n return this.entryByElement.has(element);\n }\n\n clear(): void {\n this.entriesByField.clear();\n // WeakMap cannot be cleared; a detached element must not observe stale membership.\n this.entryByElement = new WeakMap();\n this.count = 0;\n this.dependencies = null;\n this.islandRoots = [];\n }\n\n /** Replace in place when the field bucket is unchanged, preserving order. */\n private replaceEntry(previous: CachedElement, next: CachedElement): boolean {\n if (previous.fieldName !== next.fieldName) return false;\n const bucket = this.entriesByField.get(previous.fieldName);\n const index = bucket === undefined ? -1 : bucket.indexOf(previous);\n if (bucket === undefined || index < 0) return false;\n bucket[index] = next;\n return true;\n }\n\n private removeEntry(element: Element, entry: CachedElement): boolean {\n this.entryByElement.delete(element);\n const bucket = this.entriesByField.get(entry.fieldName);\n const index = bucket === undefined ? -1 : bucket.indexOf(entry);\n if (bucket === undefined || index < 0) return false;\n bucket.splice(index, 1);\n if (bucket.length === 0) this.entriesByField.delete(entry.fieldName);\n this.count -= 1;\n return true;\n }\n\n private append(entry: CachedElement): void {\n const bucket = this.entriesByField.get(entry.fieldName);\n if (bucket) bucket.push(entry);\n else this.entriesByField.set(entry.fieldName, [entry]);\n this.count += 1;\n }\n\n private resolveBinding(element: Element): CachedElement | undefined {\n const fieldName = element.getAttribute(FIELD_ATTRIBUTE);\n if (fieldName === null || fieldName.length === 0) return undefined;\n const explicit = element.getAttribute(TYPE_ATTRIBUTE);\n const targetAttribute = element.getAttribute(TARGET_ATTRIBUTE_ATTRIBUTE);\n const hrefField = element.getAttribute(HREF_ATTRIBUTE);\n const srcField = element.getAttribute(SRC_ATTRIBUTE);\n const altField = element.getAttribute(ALT_ATTRIBUTE);\n const arrayTemplate = element.getAttribute(ARRAY_TEMPLATE_ATTRIBUTE);\n const arraySeparator = element.getAttribute(ARRAY_SEPARATOR_ATTRIBUTE);\n const locale = element.getAttribute(LOCALE_ATTRIBUTE);\n const format = element.getAttribute(FORMAT_ATTRIBUTE);\n const owner = resolveBindingOwner(element);\n const dependsOn = parseDependencyList(element.getAttribute(DEPENDS_ATTRIBUTE));\n const strategy = element.getAttribute(STRATEGY_ATTRIBUTE);\n const guessed = element.getAttribute(GUESSED_ATTRIBUTE);\n const fragmentBoundary = enclosingFragment(element);\n return {\n element,\n fieldName,\n fieldType: resolveFieldType(element),\n explicitFieldType: explicit !== null && isRendererKey(explicit),\n strategyKind: resolveStrategy(element) ?? 'unknown',\n ...(fragmentBoundary !== null ? { fragmentBoundary } : {}),\n ...(targetAttribute !== null && targetAttribute.length > 0 ? { targetAttribute } : {}),\n ...(hrefField !== null && hrefField.length > 0 ? { hrefField } : {}),\n ...(srcField !== null && srcField.length > 0 ? { srcField } : {}),\n ...(altField !== null && altField.length > 0 ? { altField } : {}),\n ...(arrayTemplate !== null ? { arrayTemplate } : {}),\n ...(arraySeparator !== null ? { arraySeparator } : {}),\n ...(locale !== null && locale.length > 0 ? { locale } : {}),\n ...(format !== null && format.length > 0 ? { format } : {}),\n ...(owner !== undefined ? { owner } : {}),\n ...(dependsOn.length > 0 ? { dependsOn } : {}),\n ...(strategy !== null && strategy.length > 0 ? { strategy } : {}),\n ...(element.hasAttribute(BOUNDARY_ATTRIBUTE) ? { hidesWhenEmpty: true } : {}),\n ...(guessed !== null ? { guessed } : {}),\n };\n }\n}\n\n/** Explicit `data-payload-type`, then element heuristics, then `text`. */\nexport function resolveFieldType(element: Element): RendererKey {\n const explicit = element.getAttribute(TYPE_ATTRIBUTE);\n if (explicit !== null && isRendererKey(explicit)) return explicit;\n if (element.hasAttribute(RICH_TEXT_ATTRIBUTE)) return 'richText';\n if (element.hasAttribute(HTML_ATTRIBUTE)) return 'html';\n if (element.hasAttribute(STRUCTURAL_ATTRIBUTE)) return 'structural-array';\n if (element.hasAttribute(ARRAY_ATTRIBUTE)) return 'array';\n if (element.tagName === 'IMG') return 'image';\n if (element.tagName === 'A') return 'url';\n if (element.tagName === 'TIME') return 'date';\n if (element.tagName === 'INPUT') {\n const inputType = (element as HTMLInputElement).type;\n if (inputType === 'checkbox') return 'checkbox';\n if (inputType === 'number') return 'number';\n if (inputType === 'date' || inputType === 'datetime-local') return 'date';\n }\n return 'text';\n}\n\nfunction alwaysTrue(): boolean {\n return true;\n}\n","/**\n * Server-side merge for Payload 3.x, whose admin posts raw form values with\n * relationships as bare ids. Like the official client, the update is re-fetched\n * through the REST API with `X-Payload-HTTP-Method-Override: GET`, which\n * merges the form values into the stored document and returns it populated.\n * Only the newest request matters: a newer merge aborts the one in flight.\n */\n\nimport { isolateDiagnostic, noopDiagnostic } from './diagnostics';\n\nexport interface DataMergerOptions {\n /** Payload server origin, e.g. `https://cms.example.com`. */\n readonly serverURL: string;\n /** REST route prefix. Defaults to `/api`. */\n readonly apiRoute?: string;\n /** Population depth requested from the server. Defaults to `1`. */\n readonly depth?: number;\n readonly fetchFn?: typeof fetch;\n readonly log?: (...args: unknown[]) => void;\n}\n\nexport interface MergeRequest {\n readonly collectionSlug?: string | undefined;\n readonly globalSlug?: string | undefined;\n readonly data: Record<string, unknown>;\n readonly locale?: string | undefined;\n}\n\n/** `superseded`: a newer merge replaced this one. `unavailable`: fall back to the raw values. */\nexport type MergeResult =\n | { readonly status: 'merged'; readonly doc: Record<string, unknown> }\n | { readonly status: 'superseded' }\n | { readonly status: 'unavailable' };\n\nfunction hasControlCharacter(value: string): boolean {\n for (const character of value) {\n // An iterated character always has a code point; 0 keeps the type and fails closed.\n const codePoint = character.codePointAt(0) ?? 0;\n if (codePoint <= 0x1f || codePoint === 0x7f) return true;\n }\n return false;\n}\n\n/** One path segment: non-empty, bounded, not a dot segment, without separators or control characters. */\nfunction isPathSegment(value: string, maxLength: number): boolean {\n return (\n value.length > 0 &&\n value.length <= maxLength &&\n value !== '.' &&\n value !== '..' &&\n !value.includes('/') &&\n !value.includes('\\\\') &&\n !hasControlCharacter(value)\n );\n}\n\n/** A slug is one of Payload's own names; `?` and `#` never belong in one. */\nfunction isSafeSlug(value: string): boolean {\n return isPathSegment(value, 128) && !value.includes('?') && !value.includes('#');\n}\n\n/** An id comes from the form values; a string one is encoded, so `?` and `#` may appear. */\nfunction isSafeId(value: unknown): value is string | number {\n if (typeof value === 'number') return Number.isFinite(value);\n return typeof value === 'string' && isPathSegment(value, 512);\n}\n\n/**\n * Trailing slashes off a base URL, without a regular expression: `/\\/+$/`\n * backtracks over a long run of slashes and takes quadratic time on input the\n * page supplies (CodeQL js/polynomial-redos).\n */\nfunction withoutTrailingSlashes(value: string): string {\n let end = value.length;\n while (value.endsWith('/', end)) end -= 1;\n return value.slice(0, end);\n}\n\nexport class DataMerger {\n private readonly serverURL: string;\n private readonly apiRoute: string;\n private readonly depth: number;\n private readonly fetchFn: typeof fetch | undefined;\n private readonly log: (...args: unknown[]) => void;\n private inflight: AbortController | null = null;\n private attempt = 0;\n private destroyDepth = 0;\n\n constructor(options: DataMergerOptions) {\n this.serverURL = withoutTrailingSlashes(options.serverURL);\n const route = options.apiRoute ?? '/api';\n this.apiRoute = route.startsWith('/') ? route : `/${route}`;\n this.depth = options.depth ?? 1;\n this.fetchFn = options.fetchFn;\n this.log = isolateDiagnostic(options.log ?? noopDiagnostic);\n }\n\n /** Collections need an `id` in the form values; globals only their slug. */\n canMerge(request: MergeRequest): boolean {\n return this.endpointOf(request) !== null;\n }\n\n /**\n * The path under `apiRoute`, or `null` when no safe one exists. A request\n * accessor that throws counts as none, and so does a lone surrogate, which\n * `encodeURIComponent` refuses with a `URIError`.\n */\n private endpointOf(request: MergeRequest): string | null {\n try {\n // An empty global slug means \"collection document\" on the wire.\n const globalSlug = request.globalSlug;\n if (globalSlug) {\n return isSafeSlug(globalSlug) ? `globals/${encodeURIComponent(globalSlug)}` : null;\n }\n const collectionSlug = request.collectionSlug ?? '';\n const id: unknown = request.data['id'];\n if (!isSafeSlug(collectionSlug) || !isSafeId(id)) return null;\n return `${encodeURIComponent(collectionSlug)}/${encodeURIComponent(String(id))}`;\n } catch {\n return null;\n }\n }\n\n async merge(request: MergeRequest): Promise<MergeResult> {\n if (this.destroyDepth > 0) return { status: 'superseded' };\n // Claim the attempt before aborting: abort listeners and fetch shims are\n // reentrant, and a newer merge they start must win. Nothing but this class\n // aborts the signal, and only after the counter moved, so the counter\n // alone decides who was superseded.\n const attempt = (this.attempt += 1);\n const previous = this.inflight;\n this.inflight = null;\n let controller: AbortController | null = null;\n const superseded = (): boolean => this.attempt !== attempt;\n try {\n previous?.abort();\n if (superseded()) return { status: 'superseded' };\n // The endpoint reads the request's own values, which may be consumer\n // getters that start a newer merge before throwing.\n const endpoint = this.endpointOf(request);\n if (endpoint === null) {\n return superseded() ? { status: 'superseded' } : { status: 'unavailable' };\n }\n const fetchFn = this.fetchFn ?? (typeof fetch === 'function' ? fetch : undefined);\n if (fetchFn === undefined) return { status: 'unavailable' };\n controller = new AbortController();\n this.inflight = controller;\n const url = `${this.serverURL}${this.apiRoute}/${endpoint}`;\n const response = await fetchFn(url, {\n method: 'POST',\n credentials: 'include',\n headers: {\n 'Content-Type': 'application/json',\n 'X-Payload-HTTP-Method-Override': 'GET',\n },\n // The admin already flattens locales before posting; an absent locale\n // is left out of the JSON.\n body: JSON.stringify({\n data: request.data,\n depth: this.depth,\n flattenLocales: false,\n locale: request.locale,\n }),\n signal: controller.signal,\n });\n // A fetch shim may ignore the signal; the attempt is authoritative.\n if (superseded()) return { status: 'superseded' };\n if (!response.ok) {\n this.log('merge HTTP', response.status, url);\n return { status: 'unavailable' };\n }\n const merged: unknown = await response.json();\n if (superseded()) return { status: 'superseded' };\n if (merged === null || typeof merged !== 'object' || Array.isArray(merged)) {\n this.log('merge invalid', url);\n return { status: 'unavailable' };\n }\n return { status: 'merged', doc: merged as Record<string, unknown> };\n } catch (error) {\n if (superseded()) return { status: 'superseded' };\n this.log('merge exception', error);\n return { status: 'unavailable' };\n } finally {\n // Only the newest attempt's controller is ever in flight: a superseded\n // attempt's is gone already, and its successor's is left alone.\n if (this.inflight === controller) this.inflight = null;\n }\n }\n\n /** Abort any in-flight merge. The merger stays usable across a stop/start cycle. */\n destroy(): void {\n this.attempt += 1;\n const inflight = this.inflight;\n this.inflight = null;\n this.destroyDepth += 1;\n try {\n inflight?.abort();\n } finally {\n this.destroyDepth -= 1;\n }\n }\n}\n","/**\n * What the peer does, derived from the capabilities its messages showed —\n * the runtime never asks which Payload version it is talking to. Unknown\n * until the admin reveals its shape. See ADR 0010.\n */\nimport type { ProtocolCapability } from './protocol-version';\n\nexport type ProtocolProfileName = 'unknown' | 'payload-2' | 'payload-3';\n\nexport interface ProtocolProfile {\n readonly name: ProtocolProfileName;\n /** Where field types come from. */\n readonly fieldTyping: 'schema' | 'heuristic';\n /**\n * Who populates relationships. Payload 2.x's admin posts populated data\n * (it merges client-side with `fieldSchemaJSON`); Payload 3.x posts raw\n * form values and the runtime asks the REST API when `serverURL` is set.\n */\n readonly populatesRelationships: 'admin' | 'server';\n /** Whether the peer reports document saves and relationship edits. */\n readonly documentEvents: boolean;\n}\n\nconst PAYLOAD_2: ProtocolProfile = {\n name: 'payload-2',\n fieldTyping: 'schema',\n populatesRelationships: 'admin',\n documentEvents: false,\n};\nconst PAYLOAD_3: ProtocolProfile = {\n name: 'payload-3',\n fieldTyping: 'heuristic',\n populatesRelationships: 'server',\n documentEvents: true,\n};\nconst UNKNOWN: ProtocolProfile = {\n name: 'unknown',\n fieldTyping: 'heuristic',\n populatesRelationships: 'server',\n documentEvents: false,\n};\n\n/**\n * `schema-json` on the wire is the Payload 2.x signature: 3.x removed\n * `fieldSchemaJSON`. Document or relationship events are 3.x-only. Until\n * either shows, the peer is unknown and treated like 3.x for merging — the\n * conservative choice, because a needless REST merge costs a request while\n * a missing one loses populated relationships.\n */\nexport function detectProtocolProfile(observed: ReadonlySet<ProtocolCapability>): ProtocolProfile {\n if (observed.has('schema-json')) return PAYLOAD_2;\n if (observed.has('document-events') || observed.has('relationship-events')) return PAYLOAD_3;\n return UNKNOWN;\n}\n","/**\n * Mutation and intersection observers: ask the host to rebuild the cache when\n * bindings appear, vanish or change metadata, and track which bound elements\n * are in the viewport so off-screen writes can wait. Kept apart from cache and\n * scheduler so tests can run without the browser observer APIs.\n */\n\nimport { BINDING_ATTRIBUTES, FIELD_ATTRIBUTE, OWNER_ATTRIBUTE } from './cache';\n\nexport interface ObserverCallbacks {\n readonly onStructuralChange: () => void;\n readonly onVisibilityChange: (element: Element, isVisible: boolean) => void;\n}\n\nexport interface ObserverOptions {\n /** Debounce for mutation batches in ms. Default 100. */\n readonly mutationDebounceMs?: number;\n /** `rootMargin` for the IntersectionObserver. Default `200px`. */\n readonly intersectionRootMargin?: string;\n}\n\nconst DEFAULT_DEBOUNCE_MS = 100;\nconst DEFAULT_ROOT_MARGIN = '200px';\n/** `nodeType` is stable across realms; the global `Node` constructor is not. */\nconst ELEMENT_NODE = 1;\n\nexport class ObserverManager {\n private readonly callbacks: ObserverCallbacks;\n private readonly debounceMs: number;\n private readonly rootMargin: string;\n private readonly visible = new Set<Element>();\n private mutation: MutationObserver | null = null;\n private intersection: IntersectionObserver | null = null;\n private debounceTimer: ReturnType<typeof setTimeout> | null = null;\n /** Bumped by every start/stop so deliveries from an older lifetime are inert. */\n private generation = 0;\n\n constructor(callbacks: ObserverCallbacks, options: ObserverOptions = {}) {\n this.callbacks = callbacks;\n this.debounceMs = options.mutationDebounceMs ?? DEFAULT_DEBOUNCE_MS;\n this.rootMargin = options.intersectionRootMargin ?? DEFAULT_ROOT_MARGIN;\n }\n\n /** Observe `root`; a repeated start hands over cleanly. */\n start(root: Node): void {\n const previousGeneration = this.generation;\n this.stop();\n const generation = previousGeneration + 1;\n // A disconnect hook may have started a newer generation; it owns the lifecycle.\n if (this.generation !== generation) return;\n let mutation: MutationObserver | null = null;\n let intersection: IntersectionObserver | null = null;\n try {\n mutation = new MutationObserver((mutations) => {\n this.handleMutations(mutations, generation);\n });\n // Both resources exist before either is live, so a missing IntersectionObserver leaves nothing behind.\n intersection = new IntersectionObserver(\n (entries) => {\n this.handleIntersection(entries, generation);\n },\n { rootMargin: this.rootMargin, threshold: 0 },\n );\n mutation.observe(root, {\n childList: true,\n subtree: true,\n attributes: true,\n attributeFilter: [...BINDING_ATTRIBUTES],\n });\n } catch (error) {\n mutation?.disconnect();\n intersection?.disconnect();\n throw error;\n }\n if (this.generation !== generation) {\n mutation.disconnect();\n intersection.disconnect();\n return;\n }\n this.mutation = mutation;\n this.intersection = intersection;\n }\n\n observeElement(element: Element): void {\n this.intersection?.observe(element);\n }\n\n unobserveElement(element: Element): void {\n this.intersection?.unobserve(element);\n this.visible.delete(element);\n }\n\n /** Seed visibility (tests). */\n markVisible(element: Element, visible: boolean): void {\n if (visible) this.visible.add(element);\n else this.visible.delete(element);\n }\n\n isVisible(element: Element): boolean {\n return this.visible.has(element);\n }\n\n /** Disconnect everything; safe to repeat. */\n stop(): void {\n // Invalidate first so queued deliveries and the timer are inert before disconnecting.\n this.generation += 1;\n const timer = this.debounceTimer;\n const mutation = this.mutation;\n const intersection = this.intersection;\n this.debounceTimer = null;\n this.mutation = null;\n this.intersection = null;\n this.visible.clear();\n if (timer !== null) clearTimeout(timer);\n try {\n mutation?.disconnect();\n } finally {\n intersection?.disconnect();\n }\n }\n\n private handleMutations(mutations: readonly MutationRecord[], generation: number): void {\n if (!this.isCurrentGeneration(generation) || !hasStructuralImpact(mutations)) return;\n if (this.debounceTimer !== null) clearTimeout(this.debounceTimer);\n const timer = setTimeout(() => {\n if (!this.isCurrentGeneration(generation) || this.debounceTimer !== timer) return;\n this.debounceTimer = null;\n this.callbacks.onStructuralChange();\n }, this.debounceMs);\n this.debounceTimer = timer;\n }\n\n private handleIntersection(\n entries: readonly IntersectionObserverEntry[],\n generation: number,\n ): void {\n for (const entry of entries) {\n if (!this.isCurrentGeneration(generation)) return;\n const { target } = entry;\n if (entry.isIntersecting) {\n if (this.visible.has(target)) continue;\n this.visible.add(target);\n this.callbacks.onVisibilityChange(target, true);\n } else if (this.visible.has(target)) {\n this.visible.delete(target);\n this.callbacks.onVisibilityChange(target, false);\n }\n }\n }\n\n private isCurrentGeneration(generation: number): boolean {\n return this.generation === generation && this.intersection !== null;\n }\n}\n\n/** Whether a mutation batch can change what is bound; unrelated DOM activity never rebuilds. */\nfunction hasStructuralImpact(mutations: readonly MutationRecord[]): boolean {\n for (const m of mutations) {\n if (\n m.type === 'attributes' &&\n m.attributeName !== null &&\n BINDING_ATTRIBUTES.includes(m.attributeName)\n ) {\n // The field and owner attributes matter anywhere; other metadata (notably\n // the native `type`) only on an element that is a binding.\n if (\n m.attributeName === FIELD_ATTRIBUTE ||\n m.attributeName === OWNER_ATTRIBUTE ||\n (m.target.nodeType === ELEMENT_NODE && (m.target as Element).hasAttribute(FIELD_ATTRIBUTE))\n ) {\n return true;\n }\n }\n for (const node of m.addedNodes) if (containsTrackedElement(node)) return true;\n for (const node of m.removedNodes) if (containsTrackedElement(node)) return true;\n }\n return false;\n}\n\nfunction containsTrackedElement(node: Node): boolean {\n if (node.nodeType !== ELEMENT_NODE) return false;\n const element = node as Element;\n return (\n element.hasAttribute(FIELD_ATTRIBUTE) || element.querySelector(`[${FIELD_ATTRIBUTE}]`) !== null\n );\n}\n","/**\n * Waiting for React before the first write (ADR 0015).\n *\n * A page a framework hydrates is not final when it is parsed: the client\n * bundle arrives later, walks the server markup and compares it with what it\n * would have rendered. A value the runtime wrote in between is a mismatch —\n * React 19 throws, discards the tree under the nearest Suspense boundary,\n * renders it again on the client, and the write is gone with it. Measured on\n * the Next fixture on 2026-09-11: the write at 93 ms, React's fiber on the\n * bound element at 174 ms, `Hydration failed` at 180 ms.\n *\n * Neither Next nor React says when hydration is done. What React does expose,\n * since 16 and for its own DevTools, is its instrumentation protocol: when\n * `react-dom` evaluates it looks for `window.__REACT_DEVTOOLS_GLOBAL_HOOK__`,\n * calls `inject()` if the hook says `supportsFiber`, and from then on\n * `onCommitFiberRoot(rendererId, root)` after every commit — each call guarded\n * by `typeof … === 'function'` and a `try`. The first commit of a root that\n * holds a binding is the moment React has taken the markup over; everything\n * before it is too early, and a commit into a root without a binding (Next's\n * dev overlay commits three times before the app does) is not ours to wait for.\n *\n * Two bundles read this: the runtime, which arms the hook when it starts, and\n * the bootstrap for asset delivery (`./loader`, built armed), where the runtime\n * itself is fetched and may evaluate after `react-dom`. They share one window\n * slot, read late, the way the route-refresh seam does.\n */\n\n/** The framework whose first commit the start waits for; `./hydration-vue` reads the second. */\nexport type HydrationMode = 'react' | 'vue';\nexport type HydrationOutcome = 'committed' | 'timed-out';\nexport type HydrationState = 'idle' | 'waiting' | HydrationOutcome;\n\n/**\n * How long the runtime waits for the commit before it starts anyway and says\n * so (LP0607). A page whose React never commits is broken; a preview that never\n * connects would hide that, one that connects five seconds late and says why\n * does not. A hydration slower than this regenerates the tree once, as before.\n */\nexport const HYDRATION_WAIT_CAP_MS = 5000;\n\n/** Where the prelude and the runtime meet. */\nexport const HYDRATION_SLOT = '__livePreviewHydration';\n\n/**\n * `[data-payload-field]`, spelled out rather than imported from `./cache`: the\n * armed bootstrap bundles this module beside the loader, and the import dragged\n * the cache's other selectors into a script that is measured to the byte. A\n * test holds it equal to `FIELD_ATTRIBUTE`.\n */\nexport const BINDING_SELECTOR = '[data-payload-field]';\n\n/**\n * What the two bundles share. The bootstrap only records: every container\n * React committed into goes to `commits` until the runtime, which alone knows\n * what a binding is, sets `onCommit` and judges the backlog and everything\n * after. Recording rather than judging keeps the armed bootstrap to the bytes\n * the delivery budgets hold a bootstrap to.\n */\ninterface HydrationSignal extends HydrationWait {\n armed: boolean;\n commits: unknown[];\n onCommit: ((container: unknown) => void) | undefined;\n}\n\n/**\n * What a wait shares whichever framework it is for: whether the framework has\n * taken the tree over, and who is waiting to hear it. The Vue observer keeps\n * one of its own (`./hydration-vue`); the cap and the cancel are the same.\n */\nexport interface HydrationWait {\n committed: boolean;\n waiters: (() => void)[];\n}\n\n/** The root React hands the hook after a commit; `containerInfo` is the DOM node it rendered into. */\ninterface FiberRootLike {\n readonly containerInfo?: unknown;\n}\n\n/**\n * The part of React's hook this module touches; the rest belongs to React and\n * its DevTools. React itself guards every other call it makes on the hook with\n * `typeof … === 'function'`; Fast Refresh (`react-refresh`, which every\n * development server runs) additionally walks `renderers` when it attaches,\n * and throws on a hook without the map — measured on the Next fixture, where\n * a hook without it stopped the page from hydrating at all.\n */\ninterface DevToolsHook {\n supportsFiber?: boolean;\n renderers?: Map<number, unknown>;\n inject?: (internals: unknown) => number;\n onCommitFiberRoot?: (\n this: unknown,\n rendererId: number,\n root?: FiberRootLike,\n ...rest: unknown[]\n ) => void;\n}\n\ntype HookWindow = Window & {\n __REACT_DEVTOOLS_GLOBAL_HOOK__?: DevToolsHook;\n [HYDRATION_SLOT]?: HydrationSignal;\n};\n\nfunction signalSlot(): HydrationSignal | undefined {\n if (typeof window === 'undefined') return undefined;\n const w = window as HookWindow;\n return (w[HYDRATION_SLOT] ??= {\n armed: false,\n committed: false,\n commits: [],\n onCommit: undefined,\n waiters: [],\n });\n}\n\n/**\n * Arm before React evaluates: install the hook React injects into when the\n * page has none, or wrap `onCommitFiberRoot` on the one that is there — the\n * React DevTools extension injects its own at `document_start`, and it keeps\n * working because the previous function runs first. Idempotent.\n */\nexport function armReactCommitSignal(): void {\n const signal = signalSlot();\n if (signal === undefined || signal.armed) return;\n signal.armed = true;\n const w = window as HookWindow;\n const hook = (w.__REACT_DEVTOOLS_GLOBAL_HOOK__ ??= installedHook());\n const previous = hook.onCommitFiberRoot;\n hook.onCommitFiberRoot = function (this: unknown, rendererId, root, ...rest) {\n try {\n previous?.call(this, rendererId, root, ...rest);\n } catch {\n // The DevTools backend's failure is not ours to propagate; React would\n // swallow it too.\n }\n const container = root?.containerInfo;\n if (signal.onCommit === undefined) signal.commits.push(container);\n else signal.onCommit(container);\n };\n}\n\n/**\n * The hook React finds when the page has none: what `injectInternals` reads\n * (`supportsFiber`, `inject`) and what Fast Refresh reads (`renderers`, kept\n * the way DevTools keeps it — one id per renderer, so the two React copies a\n * development server runs are not one to it).\n */\nfunction installedHook(): DevToolsHook {\n const renderers = new Map<number, unknown>();\n return {\n supportsFiber: true,\n renderers,\n inject: (internals) => {\n const id = renderers.size + 1;\n renderers.set(id, internals);\n return id;\n },\n };\n}\n\n/** A Document, or a container with a binding inside — the tree the runtime writes into. */\nfunction ownsBindings(container: unknown): boolean {\n const node = container as Partial<Pick<Element, 'nodeType' | 'querySelector'>> | null | undefined;\n return node?.nodeType === 9 || node?.querySelector?.(BINDING_SELECTOR) != null;\n}\n\n/** The framework has taken the tree over: every waiter hears it, once. */\nexport function settle(signal: HydrationWait): void {\n signal.committed = true;\n const waiters = signal.waiters;\n signal.waiters = [];\n for (const waiter of waiters) waiter();\n}\n\nfunction forget(signal: HydrationWait, waiter: () => void): void {\n const index = signal.waiters.indexOf(waiter);\n if (index >= 0) signal.waiters.splice(index, 1);\n}\n\n/**\n * Call back once the signal settles, or after `capMs` without it. Returns\n * `null` without calling back when it already has — a bfcache restore does\n * not wait again — and otherwise a cancel for a runtime that stops waiting.\n */\nexport function awaitSettled(\n signal: HydrationWait,\n onSettled: (outcome: HydrationOutcome) => void,\n capMs: number,\n): (() => void) | null {\n if (signal.committed) return null;\n let timer: ReturnType<typeof setTimeout> | null = null;\n const waiter = (): void => {\n if (timer !== null) clearTimeout(timer);\n timer = null;\n onSettled('committed');\n };\n signal.waiters.push(waiter);\n timer = setTimeout(() => {\n timer = null;\n forget(signal, waiter);\n onSettled('timed-out');\n }, capMs);\n return () => {\n if (timer !== null) clearTimeout(timer);\n timer = null;\n forget(signal, waiter);\n };\n}\n\n/**\n * Call back once React has committed a root that holds a binding, or after\n * `capMs` without one. Arms the signal if nothing has yet.\n */\nexport function whenReactCommitted(\n onSettled: (outcome: HydrationOutcome) => void,\n capMs = HYDRATION_WAIT_CAP_MS,\n): (() => void) | null {\n armReactCommitSignal();\n const signal = signalSlot();\n if (signal === undefined) return null;\n if (signal.onCommit === undefined) {\n // The runtime is the one that can judge a commit; the bootstrap may have\n // recorded some before it ran. The backlog first, then every commit live.\n const judge = (container: unknown): void => {\n if (!signal.committed && ownsBindings(container)) settle(signal);\n };\n signal.onCommit = judge;\n for (const container of signal.commits.splice(0)) judge(container);\n }\n return awaitSettled(signal, onSettled, capMs);\n}\n","/**\n * Waiting for Vue before the first write (ADR 0015, addendum of 2026-09-11).\n *\n * Vue's `hydrate()` walks the server markup and repairs what differs from its\n * own render, in place and quietly (development logs `Hydration completed but\n * contains mismatches.`). A value the runtime wrote before that is a mismatch\n * and is put back. Measured on the Nuxt fixture on 2026-09-11: the write at\n * 25.5 ms, hydration at 93.7 ms, the server's values back in the same tick;\n * what put them right again was the admin answering the runtime's second\n * `ready` at 500 ms — and a real admin answers `ready` once.\n *\n * Vue says nothing when it is done. What `runtime-core` does, in every build\n * and right after `hydrate()` has returned, is `rootContainer.__vue_app__ = app`\n * (`apiCreateApp.ts`, `mount`): the property Vue DevTools and `app.unmount()`\n * find the app by. The assignment is the signal. An accessor on\n * `Element.prototype` sees it without polling, files the app on the element\n * as an own property exactly as the assignment would have, and settles once\n * the container holds a binding — a widget mounted beside the page is not\n * ours to wait for. A runtime that evaluates after the mount (asset delivery)\n * finds the own property on an ancestor of its first binding instead, so no\n * armed bootstrap is needed: the signal is state, not an event.\n *\n * A Nuxt app hands its `$nuxt` on the same object, and a page whose setup\n * awaits real time hydrates its subtree only when the root Suspense resolves\n * (measured: `__vue_app__` at 494 ms, the subtree at 895 ms). Nuxt marks that\n * with `isHydrating`, cleared synchronously when the Suspense resolves and\n * before `app:suspense:resolve` runs — so an app still hydrating at the\n * mount is waited for through that hook, and one that is not settles at once.\n *\n * Not used, and why: `data-v-app` is set by `createApp().mount` only, never by\n * `createSSRApp()`'s (measured, and in `runtime-dom`); the DevTools hook\n * (`__VUE_DEVTOOLS_GLOBAL_HOOK__`, `app:init`) exists in development builds and\n * under `__VUE_PROD_DEVTOOLS__` only; a MutationObserver sees nothing on a\n * clean hydration; `window.useNuxtApp` is Nuxt's, set before the mount, and\n * `useNuxtApp()` needs Nuxt's context to answer from outside a component.\n */\n\nimport {\n BINDING_SELECTOR,\n HYDRATION_WAIT_CAP_MS,\n awaitSettled,\n settle,\n type HydrationOutcome,\n type HydrationWait,\n} from './hydration';\n\n/** Where runtime-core leaves the app on its container. */\nexport const VUE_APP_PROPERTY = '__vue_app__';\n\n/** One slot on the window, so a second copy of the runtime shares the state rather than the accessor. */\nexport const VUE_HYDRATION_SLOT = '__livePreviewVueHydration';\n\n/** The Nuxt hook that runs once the root Suspense has resolved, its subtree hydrated. */\nconst NUXT_HYDRATED_HOOK = 'app:suspense:resolve';\n\ninterface VueMountSignal extends HydrationWait {\n armed: boolean;\n}\n\n/** The two things read off a Nuxt app: whether it is still hydrating, and the hook that ends it. */\ninterface NuxtAppLike {\n readonly isHydrating?: boolean;\n readonly hook?: (name: string, fn: () => void) => unknown;\n}\n\ntype VueWindow = Window & { [VUE_HYDRATION_SLOT]?: VueMountSignal };\n\nfunction signalSlot(): VueMountSignal | undefined {\n if (typeof window === 'undefined') return undefined;\n const w = window as VueWindow;\n return (w[VUE_HYDRATION_SLOT] ??= { armed: false, committed: false, waiters: [] });\n}\n\n/** Vue's assignment lands as an own property; only that counts, never the accessor. */\nfunction mountedApp(node: Node): unknown {\n return Object.prototype.hasOwnProperty.call(node, VUE_APP_PROPERTY)\n ? (node as unknown as Record<string, unknown>)[VUE_APP_PROPERTY]\n : undefined;\n}\n\n/**\n * Arm before Vue mounts: the accessor on `Element.prototype` that turns the\n * mount into a signal. Idempotent, and it leaves a seam another copy of the\n * runtime — or a tool — already holds alone; the slot is shared either way,\n * and the accessor reads it live rather than closing over one.\n */\nexport function armVueMountSignal(): void {\n const signal = signalSlot();\n if (signal === undefined || signal.armed) return;\n signal.armed = true;\n const proto = Element.prototype;\n if (Object.getOwnPropertyDescriptor(proto, VUE_APP_PROPERTY) !== undefined) return;\n Object.defineProperty(proto, VUE_APP_PROPERTY, {\n configurable: true,\n get: () => undefined,\n set(this: Element, app: unknown) {\n Object.defineProperty(this, VUE_APP_PROPERTY, {\n value: app,\n writable: true,\n configurable: true,\n enumerable: true,\n });\n const live = signalSlot();\n if (live === undefined || live.committed || this.querySelector(BINDING_SELECTOR) === null) {\n return;\n }\n settleOnceHydrated(live, app);\n },\n });\n}\n\n/** Mounted, and — for a Nuxt app whose Suspense is still pending — hydrated too. */\nfunction settleOnceHydrated(signal: VueMountSignal, app: unknown): void {\n const nuxt = (app as { $nuxt?: NuxtAppLike } | null | undefined)?.$nuxt;\n if (nuxt?.isHydrating === true && typeof nuxt.hook === 'function') {\n nuxt.hook(NUXT_HYDRATED_HOOK, () => {\n if (!signal.committed) settle(signal);\n });\n return;\n }\n settle(signal);\n}\n\n/** Whether an app already sits on an ancestor of a binding under `root` — the runtime came after Vue. */\nfunction mountedAround(root: Document | Element): boolean {\n for (let node = root.querySelector(BINDING_SELECTOR); node !== null; node = node.parentElement) {\n if (mountedApp(node) !== undefined) return true;\n }\n return false;\n}\n\n/**\n * Call back once Vue has mounted — and, on Nuxt, hydrated — an app around a\n * binding of `root`, or after `capMs` without one. Arms the signal if nothing\n * has yet; `null` when it already happened.\n */\nexport function whenVueMounted(\n root: Document | Element,\n onSettled: (outcome: HydrationOutcome) => void,\n capMs = HYDRATION_WAIT_CAP_MS,\n): (() => void) | null {\n armVueMountSignal();\n const signal = signalSlot();\n if (signal === undefined) return null;\n if (!signal.committed && mountedAround(root)) settle(signal);\n return awaitSettled(signal, onSettled, capMs);\n}\n","/**\n * When the runtime may start: after the document has parsed, and on a page\n * that declares hydration after the framework's first commit — React's, or\n * Vue's mount — or the cap (ADR 0015).\n *\n * `lifecycle.ts` owns the resources a start acquires and how a failed one is\n * rolled back; this module owns only the waiting. It moved out when the\n * second wait pushed the lifecycle past its 500 lines, and it stays a chain of\n * plain functions over a small host so that a stage running after `start()`\n * has returned still rolls back and reports the way a synchronous failure\n * throws — the host's `later` is that seam, and `defer` is how `release()`\n * abandons whichever wait is in progress.\n */\n\nimport {\n HYDRATION_WAIT_CAP_MS,\n armReactCommitSignal,\n whenReactCommitted,\n type HydrationMode,\n type HydrationOutcome,\n type HydrationState,\n} from './hydration';\nimport { armVueMountSignal, whenVueMounted } from './hydration-vue';\n\n/** What the startup chain needs from the runtime. */\nexport interface StartupHost {\n readonly root: Document | Element;\n readonly hydration: HydrationMode | undefined;\n /** Whether the runtime is still meant to start; a stop in between abandons the chain. */\n isRunning(): boolean;\n /** Keeps the way to abandon the wait in progress, for `release()`. */\n defer(cancel: () => void): void;\n /** Runs a stage after `start()` has returned: a throw is rolled back and reported, not lost. */\n later(step: () => void): void;\n /** Records how far the wait for hydration got, for `inspect()`. */\n hydrated(state: HydrationState): void;\n warn(message: string): void;\n /** Acquires the resources; throws into the caller when synchronous. */\n startNow(): void;\n}\n\n/**\n * Synchronous when nothing is pending. Otherwise the host is handed a cancel\n * and the chain continues through `later` once the wait ends.\n */\nexport function startWhenReady(host: StartupHost): void {\n // Armed before anything defers: the framework may evaluate before DOMContentLoaded.\n if (host.hydration === 'react') armReactCommitSignal();\n else if (host.hydration === 'vue') armVueMountSignal();\n const { root } = host;\n if (!isDocumentRoot(root) || root.readyState !== 'loading') {\n startAfterParse(host);\n return;\n }\n const onReady = (): void => {\n if (!host.isRunning()) return;\n host.later(() => {\n startAfterParse(host);\n });\n };\n root.addEventListener('DOMContentLoaded', onReady, { once: true });\n host.defer(() => {\n root.removeEventListener('DOMContentLoaded', onReady);\n });\n}\n\n/** A page a framework hydrates is not final until the framework has committed. */\nfunction startAfterParse(host: StartupHost): void {\n if (host.hydration === undefined) {\n host.startNow();\n return;\n }\n const onSettled = (outcome: HydrationOutcome): void => {\n host.later(() => {\n startHydrated(host, outcome);\n });\n };\n const pending =\n host.hydration === 'react'\n ? whenReactCommitted(onSettled)\n : whenVueMounted(host.root, onSettled);\n // Already committed — a bfcache restore does not wait again.\n if (pending === null) {\n startHydrated(host, 'committed');\n return;\n }\n host.defer(pending);\n host.hydrated('waiting');\n}\n\nfunction startHydrated(host: StartupHost, outcome: HydrationOutcome): void {\n host.hydrated(outcome);\n if (outcome === 'timed-out') {\n host.warn(\n `[live-preview] LP0607: no ${host.hydration === 'react' ? 'React commit' : 'Vue mount'} in ${String(HYDRATION_WAIT_CAP_MS)} ms; started without waiting for hydration.`,\n );\n }\n host.startNow();\n}\n\n/** Node types are stable across realms; global constructors are not. */\nfunction isDocumentRoot(root: Document | Element): root is Document {\n return root.nodeType === 9;\n}\n","/** Connection status and the heartbeat that decides a disconnect. */\n\nexport type ConnectionStatus = 'disconnected' | 'connecting' | 'connected';\n\nexport interface HeartbeatOptions {\n /**\n * Silence before declaring a timeout. `0` disables the timer, which is right\n * for the stock Payload protocol: it sends messages only on edits, so any\n * idle timeout would report false disconnects.\n */\n readonly timeoutMs?: number;\n readonly onTimeout: () => void;\n}\n\nexport class HeartbeatTimer {\n private readonly timeoutMs: number;\n private readonly onTimeout: () => void;\n private handle: ReturnType<typeof setTimeout> | null = null;\n private lastKick = 0;\n\n constructor(options: HeartbeatOptions) {\n this.timeoutMs = options.timeoutMs ?? 0;\n this.onTimeout = options.onTimeout;\n }\n\n /** Called on every valid message; re-arms the timeout. */\n kick(): void {\n this.lastKick = Date.now();\n if (this.timeoutMs <= 0) return;\n if (this.handle !== null) clearTimeout(this.handle);\n const handle = setTimeout(() => {\n if (this.handle !== handle) return;\n this.handle = null;\n this.onTimeout();\n }, this.timeoutMs);\n this.handle = handle;\n }\n\n stop(): void {\n if (this.handle === null) return;\n clearTimeout(this.handle);\n this.handle = null;\n }\n\n get lastKickAt(): number {\n return this.lastKick;\n }\n\n get pending(): boolean {\n return this.handle !== null;\n }\n}\n\nexport class ConnectionState {\n private current: ConnectionStatus = 'disconnected';\n\n get status(): ConnectionStatus {\n return this.current;\n }\n\n /** Returns whether the status changed. */\n markConnected(): boolean {\n return this.transition('connected');\n }\n\n markDisconnected(): boolean {\n return this.transition('disconnected');\n }\n\n private transition(next: ConnectionStatus): boolean {\n if (this.current === next) return false;\n this.current = next;\n return true;\n }\n}\n","/**\n * Auto-binding (ADR 0014). On the connection's first message the document and\n * the DOM are two views of the same state, so a scalar field's value can be\n * looked for in the page: where it stands as the whole content of exactly one\n * element — its only text node, or one attribute the writer may set — that\n * element is bound to the field as if `data-payload-field` had been written\n * there. No match, several, a partial one, one split across nodes: nothing,\n * and the field stays unbound, which since Z3 escalates instead of degrading.\n *\n * Two jobs, two exports. `findUniqueBindings` is the search, the exclusions and\n * the candidate rule, and reads the DOM only. `adoptUniqueBindings` writes the\n * winners onto their elements as the attributes a template would have carried,\n * plus `data-payload-guessed` holding the value that matched, and registers\n * them with the cache. Stamping is what lets a cache rebuild find a guess again\n * the way it finds any binding, and what lets `inspect()` and the overlay tell\n * a guess from a declaration.\n */\n\nimport { isWritableAttribute } from './attribute-binding';\nimport { isBindingInScope } from './binding-owner';\nimport {\n ALT_ATTRIBUTE,\n FIELD_ATTRIBUTE,\n GUESSED_ATTRIBUTE,\n HREF_ATTRIBUTE,\n TARGET_ATTRIBUTE_ATTRIBUTE,\n TYPE_ATTRIBUTE,\n resolveBindingOwner,\n} from './cache';\nimport { isIslandBoundary } from './islands';\nimport type { RuntimeDeps, RuntimeState } from './runtime-state';\nimport { stripLocaleSuffix, SYSTEM_FIELD_NAMES, type OwnerScope } from './unbound-fields';\n\n/** `'unique'` searches once, on the first message; `'off'` (the default) never. */\nexport type AutoBindMode = 'off' | 'unique';\n\n/** An author's no: the element and everything under it is never guessed into. */\nexport const NO_BIND_ATTRIBUTE = 'data-payload-no-bind';\n/** The morph's boundary (`src/core/morph.ts`) is this search's boundary too: a subtree the site scripts itself. */\nconst OWNED_ATTRIBUTE = 'data-payload-owned';\n\n/**\n * Below this many characters a value is not looked for at all. Measured, not\n * chosen: on the trap corpus (`tests/fixtures/auto-bind-traps`) 13 is the\n * shortest floor at which no trap binds — at 12 the byline `Ada Lovelace`,\n * printed by a related post and never by the template, is a unique match in\n * the wrong place. The shortest value the shipped fixtures bind that a unique\n * match finds is `Visit Payload`, 13. So the floor separates the corpus with\n * no margin either way; what it is for are the short tokens ADR 0014 names,\n * and a phrase that occurs exactly once and in the wrong place is kept out by\n * nothing but its rarity.\n */\nexport const AUTO_BIND_MIN_LENGTH = 13;\n\nconst BOOLEAN_WORDS: ReadonlySet<string> = new Set(['true', 'false', 'yes', 'no', 'on', 'off']);\n/** Digits with the separators a date, a time, a price or a phone number carry. */\nconst NUMERIC = /^[\\d\\s.,:+/-]+$/u;\n/** A single lower-case token: an enum value, a slug, a code. */\nconst ENUM_TOKEN = /^[a-z][a-z0-9_-]*$/u;\n/** `de`, `de-AT`, `zh_Hant`, `sr-Latn-RS`. */\nconst LOCALE_CODE = /^[a-z]{2,3}(?:[-_][A-Za-z0-9]{2,8})*$/u;\n\n/** Elements whose text is code, metadata or a form value, not content. */\nconst SKIPPED_TAGS: ReadonlySet<string> = new Set([\n 'SCRIPT',\n 'STYLE',\n 'TEMPLATE',\n 'TITLE',\n 'NOSCRIPT',\n 'TEXTAREA',\n 'SELECT',\n 'OPTION',\n 'INPUT',\n 'IFRAME',\n]);\nconst HTML_NAMESPACE = 'http://www.w3.org/1999/xhtml';\n\nexport interface AutoBindCandidate {\n readonly element: Element;\n readonly fieldName: string;\n /** The value that matched: the text, or the attribute's value. */\n readonly matched: string;\n /** The attribute whose whole value matched; absent for a text match. */\n readonly attribute?: string;\n /** The `data-payload-*` attributes a template would have written for this binding. */\n readonly stamps: Readonly<Record<string, string>>;\n}\n\n/** A value's owner: the field, and whether it is an upload (matched by its `url` against an `<img>`). */\nexport interface Claim {\n readonly field: string;\n readonly media: boolean;\n}\n\n/**\n * What the baseline search adopted, kept for the server re-render a route\n * refresh morphs the page toward: that markup carries no stamp, so the guesses\n * are looked for again there — these fields, by these values — and nothing\n * else is. ADR 0014 §1 still holds for everything the baseline did not find.\n */\nexport interface KeptGuesses {\n /** The fields the guesses bound, a folded second field (`data-payload-href`, `data-payload-alt`) included. */\n readonly fields: ReadonlySet<string>;\n /** The texts they were found by, each claiming its field. */\n readonly values: ReadonlyMap<string, Claim>;\n}\n\n/** Whether a scalar is worth looking for: the short and shapeless ones match by accident. */\nexport function isBindableValue(value: unknown, minLength = AUTO_BIND_MIN_LENGTH): value is string {\n if (typeof value !== 'string') return false;\n const text = value.trim();\n if (text.length < minLength) return false;\n if (NUMERIC.test(text) || BOOLEAN_WORDS.has(text.toLowerCase())) return false;\n return !ENUM_TOKEN.test(text) && !LOCALE_CODE.test(text);\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\n/**\n * The values to look for, keyed by the exact text a match must equal. A value\n * two fields share maps to `null`: the element would be unique, the field not.\n * Groups are opened one level under the dotted name a binding would carry; an\n * upload is looked for by its `url`; a document with an `id` and no `url` is\n * another document, and its scalars are not this one's.\n */\nexport function bindableValues(\n fields: Readonly<Record<string, unknown>>,\n locale: string | undefined,\n minLength = AUTO_BIND_MIN_LENGTH,\n): Map<string, Claim | null> {\n const values = new Map<string, Claim | null>();\n const claim = (text: string, field: string, media: boolean): void => {\n values.set(text, values.has(text) ? null : { field, media });\n };\n for (const [rawName, value] of Object.entries(fields)) {\n if (SYSTEM_FIELD_NAMES.has(rawName)) continue;\n const name = stripLocaleSuffix(rawName, locale);\n if (isBindableValue(value, minLength)) {\n claim(value.trim(), name, false);\n } else if (isRecord(value)) {\n if (typeof value['url'] === 'string') {\n claim(value['url'], name, true);\n } else if (!('id' in value) && !('_id' in value)) {\n for (const [child, childValue] of Object.entries(value)) {\n if (SYSTEM_FIELD_NAMES.has(child) || !isBindableValue(childValue, minLength)) continue;\n claim(childValue.trim(), `${name}.${child}`, false);\n }\n }\n }\n }\n return values;\n}\n\n/** Where the search stops: nothing at or under this element may be claimed. */\nfunction isBoundary(element: Element): boolean {\n if (element.namespaceURI !== HTML_NAMESPACE || SKIPPED_TAGS.has(element.tagName)) return true;\n if (\n element.hasAttribute(FIELD_ATTRIBUTE) ||\n element.hasAttribute(NO_BIND_ATTRIBUTE) ||\n element.hasAttribute(OWNED_ATTRIBUTE) ||\n isIslandBoundary(element)\n ) {\n return true;\n }\n const editable = element.getAttribute('contenteditable');\n return editable !== null && editable !== 'false';\n}\n\n/**\n * The element's whole text, when it is exactly one text node — comments and\n * whitespace-only nodes aside — and no element. A second text node is a value\n * split across nodes; an element child is markup a text write would destroy.\n */\nfunction soleText(element: Element): string | undefined {\n let text: string | undefined;\n for (let child = element.firstChild; child !== null; child = child.nextSibling) {\n if (child.nodeType === 1) return undefined;\n if (child.nodeType !== 3) continue;\n const data = (child as Text).data.trim();\n if (data.length === 0) continue;\n if (text !== undefined) return undefined;\n text = data;\n }\n return text;\n}\n\n/** No second rule beyond the writer's own; `value` is the visitor's, and `data-payload-*` is ours. */\nfunction isCandidateAttribute(name: string): boolean {\n return isWritableAttribute(name) && !name.startsWith('data-payload-') && name !== 'value';\n}\n\ninterface ElementHits {\n /** The field whose value is the element's whole text. */\n text?: string;\n /** Attribute name → the field whose value it carries. */\n readonly attributes: Map<string, Claim>;\n}\n\ninterface Search {\n readonly values: ReadonlyMap<string, Claim | null>;\n readonly byElement: Map<Element, ElementHits>;\n /** Every element a field was found on; a field with more than one is ambiguous. */\n readonly byField: Map<string, Set<Element>>;\n}\n\nfunction record(search: Search, element: Element, claim: Claim): ElementHits {\n let hits = search.byElement.get(element);\n if (hits === undefined) {\n hits = { attributes: new Map() };\n search.byElement.set(element, hits);\n }\n let elements = search.byField.get(claim.field);\n if (elements === undefined) {\n elements = new Set();\n search.byField.set(claim.field, elements);\n }\n elements.add(element);\n return hits;\n}\n\n/**\n * One pass, depth first, in document order; the element under a boundary is\n * never looked at. Sibling pointers rather than `children` and `attributes`:\n * the live collections cost twenty times the walk in jsdom, where the\n * interaction gate measures this, and nothing in a browser.\n */\nfunction walk(element: Element, search: Search): void {\n for (let child = element.firstElementChild; child !== null; child = child.nextElementSibling) {\n if (isBoundary(child)) continue;\n const text = soleText(child);\n const textClaim = text === undefined ? undefined : search.values.get(text);\n if (textClaim != null && !textClaim.media) {\n record(search, child, textClaim).text = textClaim.field;\n }\n for (const name of child.getAttributeNames()) {\n if (!isCandidateAttribute(name)) continue;\n const claim = search.values.get(child.getAttribute(name) ?? '');\n if (claim == null) continue;\n // An upload is matched by its file, and an `<img>` is the one element that renders one.\n if (claim.media && (child.tagName !== 'IMG' || name !== 'src')) continue;\n record(search, child, claim).attributes.set(name, claim);\n }\n walk(child, search);\n }\n}\n\n/**\n * What a template would have written for this element. One binding per\n * element: the text wins, and the two idioms a template has for a second\n * field on the same element — `data-payload-href` on a link, `data-payload-alt`\n * on an image — are used when the second field matched that attribute.\n */\nfunction shape(\n element: Element,\n text: string | undefined,\n attributes: ReadonlyMap<string, string>,\n): AutoBindCandidate | undefined {\n const tag = element.tagName;\n if (text !== undefined) {\n const stamps: Record<string, string> = { [FIELD_ATTRIBUTE]: text };\n if (tag === 'A') {\n const href = attributes.get('href');\n // The url renderer derives the href from the text; a guess that never\n // matched the href must not clear it, so the text renderer is named.\n if (href === undefined) stamps[TYPE_ATTRIBUTE] = 'text';\n else if (href !== text) stamps[HREF_ATTRIBUTE] = href;\n }\n return { element, fieldName: text, matched: soleText(element) ?? '', stamps };\n }\n if (tag === 'IMG') {\n const src = attributes.get('src');\n if (src !== undefined) {\n const alt = attributes.get('alt');\n return {\n element,\n fieldName: src,\n matched: element.getAttribute('src') ?? '',\n attribute: 'src',\n stamps: {\n [FIELD_ATTRIBUTE]: src,\n ...(alt !== undefined && alt !== src ? { [ALT_ATTRIBUTE]: alt } : {}),\n },\n };\n }\n }\n // A link whose text did not match keeps its text: only the attribute is written.\n const first = attributes.entries().next();\n if (first.done) return undefined;\n const [name, field] = first.value;\n return {\n element,\n fieldName: field,\n matched: element.getAttribute(name) ?? '',\n attribute: name,\n stamps: { [FIELD_ATTRIBUTE]: field, [TARGET_ATTRIBUTE_ATTRIBUTE]: name },\n };\n}\n\n/**\n * The bindings the page allows, in document order: for every field found on\n * exactly one element, that element with the attributes a template would have\n * given it. `root` is searched as a whole; the caller decides that a document's\n * root is its body.\n */\nexport function findUniqueBindings(\n root: Element,\n fields: Readonly<Record<string, unknown>>,\n locale: string | undefined,\n minLength = AUTO_BIND_MIN_LENGTH,\n): AutoBindCandidate[] {\n return searchUnique(root, bindableValues(fields, locale, minLength));\n}\n\n/** The search proper, over a value table already decided on. */\nfunction searchUnique(\n root: Element,\n values: ReadonlyMap<string, Claim | null>,\n): AutoBindCandidate[] {\n const search: Search = { values, byElement: new Map(), byField: new Map() };\n if (values.size > 0 && !isBoundary(root)) walk(root, search);\n const unique = (field: string): boolean => search.byField.get(field)?.size === 1;\n const candidates: AutoBindCandidate[] = [];\n for (const [element, hits] of search.byElement) {\n const text = hits.text !== undefined && unique(hits.text) ? hits.text : undefined;\n const attributes = new Map<string, string>();\n for (const [name, claim] of hits.attributes) {\n if (unique(claim.field)) attributes.set(name, claim.field);\n }\n const candidate = shape(element, text, attributes);\n if (candidate !== undefined) candidates.push(candidate);\n }\n return candidates;\n}\n\n/** A document's root is its body: a binding in `<head>` needs the attribute and the route strategy. */\nfunction searchRoot(root: Document | Element): Element | null {\n return root.nodeType === 9 ? (root as Document).body : (root as Element);\n}\n\n/**\n * Run the search once and make its winners bindings. Returns how many. The\n * stamps land on the elements first, so the cache resolves each guess exactly\n * as it resolves a declared binding — and so the mutation observer's rebuild,\n * which the stamps themselves trigger, finds them again.\n */\nexport function adoptUniqueBindings(\n deps: RuntimeDeps,\n state: RuntimeState,\n fields: Readonly<Record<string, unknown>>,\n locale: string | undefined,\n ownerKeys: OwnerScope,\n): number {\n const started = performance.now();\n const root = searchRoot(deps.root);\n const values = bindableValues(fields, locale);\n const adopted =\n root === null ? [] : adopt(deps, searchUnique(root, values), ownerKeys, 'on the first message');\n state.autoBindGuesses = keep(values, adopted);\n state.autoBindSearchMs = performance.now() - started;\n return adopted.length;\n}\n\n/**\n * After a server render — a route refresh, or a fragment in its boundary: the\n * server's markup carries no stamp, so the guesses the baseline made are gone\n * from what it rendered. Look for them again, by the value\n * each was found by and by the field's value in this revision — the server\n * may have rendered either, the document as it was saved or a draft it\n * autosaved since. A field found by both, on two elements, is ambiguous and\n * stays unbound. Nothing the baseline did not bind is looked for: a second\n * baseline would be a second chance at a wrong match, and the first one is\n * the only moment the page is known to show the document (ADR 0014 §1).\n */\nexport function restoreUniqueBindings(\n deps: RuntimeDeps,\n state: RuntimeState,\n fields: Readonly<Record<string, unknown>>,\n locale: string | undefined,\n ownerKeys: OwnerScope,\n): number {\n const kept = state.autoBindGuesses;\n const root = searchRoot(deps.root);\n if (kept === null || kept.fields.size === 0 || root === null) return 0;\n const values = new Map<string, Claim | null>(kept.values);\n for (const [text, claim] of bindableValues(fields, locale)) {\n if (claim === null || !kept.fields.has(claim.field)) continue;\n const known = values.get(text);\n if (known === undefined) values.set(text, claim);\n else if (known?.field !== claim.field) values.set(text, null);\n }\n return adopt(deps, searchUnique(root, values), ownerKeys, 'after a server render').length;\n}\n\n/** Stamp the candidates, register them, say so; returns the ones that became bindings. */\nfunction adopt(\n deps: RuntimeDeps,\n candidates: readonly AutoBindCandidate[],\n ownerKeys: OwnerScope,\n when: string,\n): AutoBindCandidate[] {\n const adopted: AutoBindCandidate[] = [];\n for (const candidate of candidates) {\n const { element } = candidate;\n if (element.hasAttribute(FIELD_ATTRIBUTE)) continue;\n // Under owner scoping a guess outside the message's document would never\n // be written to; better to leave it unbound than to bind it to nothing.\n if (ownerKeys !== false && !isBindingInScope(resolveBindingOwner(element), ownerKeys)) continue;\n for (const [name, value] of Object.entries(candidate.stamps)) element.setAttribute(name, value);\n element.setAttribute(GUESSED_ATTRIBUTE, candidate.matched);\n if (deps.cache.add(element) === undefined) {\n // The cache's own filter refused it; a stamp that is not a binding must not stay.\n for (const name of Object.keys(candidate.stamps)) element.removeAttribute(name);\n element.removeAttribute(GUESSED_ATTRIBUTE);\n continue;\n }\n deps.observers.observeElement(element);\n deps.log(\n 'autoBind',\n candidate.fieldName,\n '→',\n `<${element.tagName.toLowerCase()}>`,\n candidate.attribute ?? 'text',\n JSON.stringify(candidate.matched),\n when,\n );\n adopted.push(candidate);\n }\n return adopted;\n}\n\n/** The fields the adopted guesses bound, and the values that found them. */\nfunction keep(\n values: ReadonlyMap<string, Claim | null>,\n adopted: readonly AutoBindCandidate[],\n): KeptGuesses {\n const fields = new Set<string>();\n for (const { fieldName, stamps } of adopted) {\n fields.add(fieldName);\n for (const name of [HREF_ATTRIBUTE, ALT_ATTRIBUTE]) {\n const folded = stamps[name];\n if (folded !== undefined) fields.add(folded);\n }\n }\n const kept = new Map<string, Claim>();\n for (const [text, claim] of values) {\n if (claim !== null && fields.has(claim.field)) kept.set(text, claim);\n }\n return { fields, values: kept };\n}\n","/**\n * Field-path resolution for bindings and sibling-field metadata, prototype-safe,\n * and the identity of everything one binding renders — which is the same\n * question one step later, because the siblings are part of the answer.\n */\n\nimport type { CachedElement } from './types';\nimport { valueIdentity } from './value-identity';\n\nconst BLOCKED_KEYS: ReadonlySet<string> = new Set(['__proto__', 'prototype', 'constructor']);\n\n/**\n * Resolve a dotted field path, preferring a `_<locale>` suffix when one is\n * active. Prototype-chain properties and pollution-prone segments never resolve.\n */\nexport function resolveFieldValue(\n fields: Record<string, unknown>,\n path: string,\n locale: string | undefined,\n preferLocale = false,\n): unknown {\n if (preferLocale && locale !== undefined) {\n const localized = readOwn(fields, `${path}_${locale}`);\n if (localized !== undefined) return localized;\n }\n const direct = readOwn(fields, path);\n if (direct !== undefined) return direct;\n\n if (path.includes('.')) {\n let current: unknown = fields;\n let resolved = true;\n for (const segment of path.split('.')) {\n if (BLOCKED_KEYS.has(segment) || current === null || typeof current !== 'object') {\n resolved = false;\n break;\n }\n current = readOwn(current as Record<string, unknown>, segment);\n if (current === undefined) {\n resolved = false;\n break;\n }\n }\n if (resolved) return current;\n }\n\n return locale === undefined ? undefined : readOwn(fields, `${path}_${locale}`);\n}\n\nfunction readOwn(object: Record<string, unknown>, key: string): unknown {\n if (BLOCKED_KEYS.has(key) || !Object.prototype.hasOwnProperty.call(object, key)) {\n return undefined;\n }\n return object[key];\n}\n\n/**\n * The value a binding renders. A binding that names its own locale reads that\n * locale and nothing else; one that does not falls back to the message locale.\n */\nexport function bindingValue(\n fields: Record<string, unknown>,\n target: { readonly locale?: string | undefined },\n fieldName: string,\n fallbackLocale: string | undefined,\n): unknown {\n return resolveFieldValue(\n fields,\n fieldName,\n target.locale ?? fallbackLocale,\n target.locale !== undefined,\n );\n}\n\n/** Identity of everything a binding renders: its value plus any sibling href/src/alt fields. */\nexport function bindingIdentity(\n target: CachedElement,\n value: unknown,\n fields: Record<string, unknown>,\n locale: string | undefined,\n): string | undefined {\n const own = valueIdentity(value);\n if (own === undefined) return undefined;\n const siblings = [target.hrefField, target.srcField, target.altField];\n let combined = own;\n for (const sibling of siblings) {\n if (sibling === undefined || sibling.length === 0) continue;\n const resolved = bindingValue(fields, target, sibling, locale);\n const identity = valueIdentity(resolved);\n if (identity === undefined) return undefined;\n combined += `|${sibling}=${identity}`;\n }\n return combined;\n}\n","/**\n * LP0201: a scalar field arrived for which the page has no binding. The usual\n * cause is a template that renders the anchor only when the field is non-empty.\n *\n * Reported once per field name, because the cause is the markup rather than the\n * edit. `onUnfaithfulPatch` acts on the same fact per revision; both read the\n * addressability rules from `unbound-fields.ts`.\n */\n\nimport type { ElementCache } from './cache';\nimport {\n createFieldAddressability,\n ownsAnyBinding,\n stripLocaleSuffix,\n SYSTEM_FIELD_NAMES,\n type FieldAddressability,\n type OwnerScope,\n} from './unbound-fields';\n\nexport interface OrphanDiagnosticContext {\n readonly cache: ElementCache;\n readonly warned: Set<string>;\n readonly warn: (...args: unknown[]) => void;\n}\n\nexport function diagnoseOrphanFields(\n context: OrphanDiagnosticContext,\n fields: Readonly<Record<string, unknown>>,\n locale: string | undefined,\n ownerKeys: OwnerScope,\n): void {\n const { cache } = context;\n if (cache.fieldCount === 0) return;\n // With scoping on, a page that renders none of this document is normal.\n if (ownerKeys !== false && !ownsAnyBinding(cache, ownerKeys)) return;\n const isAddressable = createFieldAddressability(cache, locale, ownerKeys);\n for (const [rawName, value] of Object.entries(fields)) {\n if (SYSTEM_FIELD_NAMES.has(rawName)) continue;\n // Only scalars: an unbound relationship or block array is a template\n // decision, not the missing anchor this code is about.\n if (isBindableScalar(value)) {\n report(context, isAddressable, rawName, locale);\n continue;\n }\n if (!isPlainObject(value) || isAddressable(rawName)) continue;\n // A group with no anchor anywhere. `admission.priceFrom` is as bindable as\n // `slug` and was reported as neither, so the report names the scalar\n // instead of staying silent about the object around it. One level only:\n // deeper the shape is a rich-text tree more often than a group, and an\n // array's missing anchor stays a template decision at every depth.\n //\n // Restrained to a group the predicate above already calls unaddressable,\n // which is what keeps this in step with `onUnfaithfulPatch`: it escalates\n // on exactly these fields, and this says the same thing more precisely.\n const group = stripLocaleSuffix(rawName, locale);\n for (const [childName, childValue] of Object.entries(value)) {\n if (!isBindableScalar(childValue) || SYSTEM_FIELD_NAMES.has(childName)) continue;\n report(context, isAddressable, `${group}.${childName}`, locale);\n }\n }\n}\n\nfunction report(\n context: OrphanDiagnosticContext,\n isAddressable: FieldAddressability,\n name: string,\n locale: string | undefined,\n): void {\n const { warned, warn } = context;\n if (warned.has(name) || isAddressable(name)) return;\n warned.add(name);\n warn(\n `[live-preview] LP0201: no <… data-payload-field=\"${stripLocaleSuffix(name, locale)}\"> for field \"${name}\"; ` +\n 'render the anchor unconditionally so edits to an empty field have somewhere to land.',\n );\n}\n\nfunction isBindableScalar(value: unknown): boolean {\n const type = typeof value;\n return type === 'string' || type === 'number' || type === 'boolean' || type === 'bigint';\n}\n\n/** A group, as opposed to an array or a null: the one shape worth looking into. */\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n","/**\n * Trusted Types: every HTML sink routes through one policy, `payload-live-preview`,\n * whose `createHTML` is the identity — what reaches a sink is already sanitized\n * or escaped. Without the API, strings pass through untouched.\n */\n\n/** The subset of the Trusted Types API this module needs. */\nexport interface TrustedHtmlPolicyLike {\n createHTML(input: string): unknown;\n}\n\ninterface TrustedTypesFactoryLike {\n createPolicy(\n name: string,\n rules: { createHTML: (input: string) => string },\n ): TrustedHtmlPolicyLike;\n}\n\n/** @internal */\nexport const TRUSTED_TYPES_POLICY_NAME = 'payload-live-preview';\n\n// Held on the realm, not in this module: every package entry is its own bundle\n// with its own copy of this file, and a page's `trusted-types` directive allows\n// the name once. A second copy that asked for it again would be refused and fall\n// back to strings; instead every copy shares the one policy, and a policy set\n// through one entry reaches the others.\nconst SLOT: unique symbol = Symbol.for('payload-live-preview.trusted-types');\ninterface SharedPolicies {\n override?: TrustedHtmlPolicyLike | null | undefined;\n auto?: TrustedHtmlPolicyLike | null | undefined;\n}\ninterface Realm {\n [SLOT]?: SharedPolicies | undefined;\n}\nfunction shared(): SharedPolicies {\n const realm = globalThis as Realm;\n const existing = realm[SLOT];\n if (existing !== undefined) return existing;\n const created: SharedPolicies = {};\n realm[SLOT] = created;\n return created;\n}\n\n/**\n * Use `policy` for every sink, `null` to assign plain strings, `undefined` to\n * return to the auto-created package policy.\n */\nexport function setTrustedTypesPolicy(policy: TrustedHtmlPolicyLike | null | undefined): void {\n shared().override = policy;\n}\n\nfunction factory(): TrustedTypesFactoryLike | undefined {\n const candidate = (globalThis as { trustedTypes?: unknown }).trustedTypes;\n if (typeof candidate !== 'object' || candidate === null) return undefined;\n const create = (candidate as { createPolicy?: unknown }).createPolicy;\n return typeof create === 'function' ? (candidate as TrustedTypesFactoryLike) : undefined;\n}\n\nfunction resolvePolicy(): TrustedHtmlPolicyLike | null {\n const policies = shared();\n if (policies.override !== undefined) return policies.override;\n if (policies.auto !== undefined) return policies.auto;\n const api = factory();\n try {\n policies.auto =\n api === undefined\n ? null\n : api.createPolicy(TRUSTED_TYPES_POLICY_NAME, { createHTML: (input) => input });\n } catch {\n // The site's `trusted-types` directive does not list this name; the\n // sink assignment will surface the enforcement error.\n policies.auto = null;\n }\n return policies.auto;\n}\n\n/** `html` as a `TrustedHTML` when a policy exists, else the string. Typed `string` for `innerHTML`. @internal */\nexport function trustedHtml(html: string): string {\n const policy = resolvePolicy();\n if (policy === null) return html;\n return policy.createHTML(html) as string;\n}\n\n/** Test hook: forget the auto-created policy. */\nexport function __resetTrustedTypesForTests(): void {\n (globalThis as Realm)[SLOT] = undefined;\n}\n","/**\n * Keyed DOM morph: edits a live element toward a freshly rendered one while\n * keeping the live nodes, and with them focus, selection, scroll, playback and\n * listeners. Custom elements, islands, `contenteditable` and\n * `data-payload-owned` subtrees are boundaries the morph never enters.\n * See ADR 0008.\n */\n\nimport { ISLAND_ATTRIBUTE } from './islands';\n\nexport { ISLAND_ATTRIBUTE };\n/** @internal */\nexport const OWNED_ATTRIBUTE = 'data-payload-owned';\n\n/** Attributes the CMS controls only when the template names them (ADR 0008 §3). */\nconst STATE_ATTRIBUTES: ReadonlySet<string> = new Set(['open', 'value', 'checked', 'selected']);\n\nexport interface MorphOptions {\n /** Attributes that key child elements for pairing, tried in order; unkeyed children pair by position. */\n readonly keyAttributes: readonly string[];\n /** Called once per parent when two children share a key; the later ones pair by position. */\n readonly onDuplicateKey?: (parent: Element, key: string) => void;\n /** Elements whose attributes are synchronised but whose children are left alone (nested structural slots). */\n readonly retainChildrenOf?: (live: Element, rendered: Element) => boolean;\n}\n\n/** Empty attribute values (boolean markers such as `data-payload-island`) are not keys. */\nfunction keyOf(element: Element, options: MorphOptions): string | undefined {\n for (const attribute of options.keyAttributes) {\n const value = element.getAttribute(attribute);\n if (value !== null && value.length > 0) return `${attribute}=${value}`;\n }\n return undefined;\n}\n\n/** @internal */\nexport function isMorphBoundary(element: Element): boolean {\n if (element.tagName.toLowerCase().includes('-')) return true;\n if (element.hasAttribute(ISLAND_ATTRIBUTE) || element.hasAttribute(OWNED_ATTRIBUTE)) return true;\n const editable = element.getAttribute('contenteditable');\n return editable !== null && editable !== 'false';\n}\n\n/** Whether `live` can be edited toward `rendered` instead of being replaced by it. @internal */\nexport function isMorphCompatible(live: Element, rendered: Element): boolean {\n return (\n live.tagName === rendered.tagName &&\n live.namespaceURI === rendered.namespaceURI &&\n !isMorphBoundary(live) &&\n !isMorphBoundary(rendered)\n );\n}\n\n/**\n * Morph `live` toward `rendered`. Returns `live` when it was retained, or\n * `rendered` when the two are incompatible and the caller must replace.\n * `rendered` is consumed: its children may move into `live`.\n */\nexport function morphElement(live: Element, rendered: Element, options: MorphOptions): Element {\n if (!isMorphCompatible(live, rendered)) return rendered;\n const focus = captureFocus(live);\n syncAttributes(live, rendered);\n if (options.retainChildrenOf?.(live, rendered) !== true) morphChildren(live, rendered, options);\n restoreFocus(focus);\n return live;\n}\n\n/** Match attributes, except that state-bearing ones change only when `rendered` carries them. */\nexport function syncAttributes(live: Element, rendered: Element): void {\n for (const attribute of Array.from(live.attributes)) {\n if (rendered.hasAttribute(attribute.name)) continue;\n if (STATE_ATTRIBUTES.has(attribute.name.toLowerCase())) continue;\n live.removeAttribute(attribute.name);\n }\n for (const attribute of Array.from(rendered.attributes)) {\n if (live.getAttribute(attribute.name) !== attribute.value) {\n live.setAttribute(attribute.name, attribute.value);\n }\n }\n}\n\nfunction morphChildren(live: Element, rendered: Element, options: MorphOptions): void {\n const liveKeyed = indexKeyed(live, options);\n const keyedElements = new Set<Node>(liveKeyed.values());\n const liveUnkeyed = Array.from(live.childNodes).filter((node) => !keyedElements.has(node));\n const claimed = new Set<Node>();\n const usedKeys = new Set<string>();\n const renderedNodes = Array.from(rendered.childNodes);\n let cursor: Node | null = live.firstChild;\n let unkeyedIndex = 0;\n\n for (let i = 0; i < renderedNodes.length; i += 1) {\n const next = renderedNodes[i] as Node;\n let kept: Node | null = null;\n let key = next instanceof Element ? keyOf(next, options) : undefined;\n // A repeated key on the rendered side pairs positionally like a live duplicate.\n if (key !== undefined && usedKeys.has(key)) key = undefined;\n if (key !== undefined) {\n usedKeys.add(key);\n const candidate = liveKeyed.get(key);\n if (candidate !== undefined && !claimed.has(candidate)) {\n kept = reconcile(candidate, next, options) === candidate ? candidate : null;\n if (kept === null) {\n candidate.replaceWith(next);\n claimed.add(next);\n cursor = next.nextSibling;\n continue;\n }\n }\n } else {\n while (unkeyedIndex < liveUnkeyed.length) {\n const candidate = liveUnkeyed[unkeyedIndex] as Node;\n unkeyedIndex += 1;\n if (claimed.has(candidate)) continue;\n if (sameKind(candidate, next)) {\n kept = reconcile(candidate, next, options) === candidate ? candidate : null;\n if (kept === null) {\n live.replaceChild(next, candidate);\n claimed.add(next);\n cursor = next.nextSibling;\n }\n break;\n }\n if (candidate instanceof Element) {\n // `next` is a text/comment, or an element whose kind the following\n // rendered node matches: an insertion, so the live element stays for it.\n const following = renderedNodes[i + 1];\n if (\n !(next instanceof Element) ||\n (following !== undefined && sameKind(candidate, following))\n ) {\n unkeyedIndex -= 1;\n break;\n }\n live.replaceChild(next, candidate);\n claimed.add(next);\n cursor = next.nextSibling;\n break;\n }\n if (!(next instanceof Element)) {\n // Text vs comment: replace rather than rewrite one node type's value into the other.\n live.replaceChild(next, candidate);\n claimed.add(next);\n cursor = next.nextSibling;\n break;\n }\n // A surplus live text/comment before the element `next` needs; removed below.\n }\n if (kept === null && claimed.has(next)) continue;\n }\n\n const node: Node = kept ?? next;\n claimed.add(node);\n // Whitespace-only text the template did not render is surplus. Stepping the\n // cursor over it keeps a retained element where it is: `insertBefore` on a\n // node already in the tree is a remove-and-insert, which blurs a focused input.\n while (cursor !== null && cursor !== node && !claimed.has(cursor) && isBlankText(cursor)) {\n cursor = cursor.nextSibling;\n }\n if (node !== cursor) live.insertBefore(node, cursor);\n cursor = node.nextSibling;\n }\n\n for (const child of Array.from(live.childNodes)) {\n if (!claimed.has(child)) child.remove();\n }\n}\n\n/** Retain `candidate` when it can be edited toward `next`; otherwise report `next`. */\nfunction reconcile(candidate: Node, next: Node, options: MorphOptions): Node {\n if (candidate instanceof Element && next instanceof Element) {\n // A compatible boundary stays exactly as it is (ADR 0008 §4).\n if (isMorphBoundary(candidate) && isMorphBoundary(next)) return candidate;\n return morphElement(candidate, next, options);\n }\n if (candidate.nodeValue !== next.nodeValue) candidate.nodeValue = next.nodeValue;\n return candidate;\n}\n\nfunction isBlankText(node: Node): boolean {\n return node.nodeType === Node.TEXT_NODE && (node.nodeValue ?? '').trim().length === 0;\n}\n\nfunction sameKind(a: Node, b: Node): boolean {\n if (a.nodeType !== b.nodeType) return false;\n if (a instanceof Element && b instanceof Element) {\n return a.tagName === b.tagName && a.namespaceURI === b.namespaceURI;\n }\n return true;\n}\n\n/** First element per key; later duplicates are left as they are and pair positionally. */\nfunction indexKeyed(parent: Element, options: MorphOptions): Map<string, Element> {\n const keyed = new Map<string, Element>();\n let duplicate: string | undefined;\n for (const child of Array.from(parent.children)) {\n const key = keyOf(child, options);\n if (key === undefined) continue;\n if (keyed.has(key)) {\n duplicate ??= key.slice(key.indexOf('=') + 1);\n continue;\n }\n keyed.set(key, child);\n }\n if (duplicate !== undefined) options.onDuplicateKey?.(parent, duplicate);\n return keyed;\n}\n\ninterface FocusSnapshot {\n readonly element: HTMLElement;\n readonly selection: readonly [number | null, number | null] | null;\n}\n\n/** A keyed move is a remove-and-insert, which blurs; remember what had focus. */\nfunction captureFocus(live: Element): FocusSnapshot | null {\n const active = live.ownerDocument.activeElement;\n if (!(active instanceof HTMLElement) || !live.contains(active)) return null;\n const selection =\n active instanceof HTMLInputElement || active instanceof HTMLTextAreaElement\n ? ([active.selectionStart, active.selectionEnd] as const)\n : null;\n return { element: active, selection };\n}\n\nfunction restoreFocus(snapshot: FocusSnapshot | null): void {\n if (snapshot === null) return;\n const { element, selection } = snapshot;\n if (element.ownerDocument.activeElement === element || !element.isConnected) return;\n try {\n element.focus({ preventScroll: true });\n const [start, end] = selection ?? [null, null];\n if (start !== null && end !== null) {\n (element as HTMLInputElement).setSelectionRange(start, end);\n }\n } catch {\n // Not focusable any more; nothing to restore.\n }\n}\n","/**\n * LP0409 — what the strict sanitizer removed that the 1.x default kept.\n *\n * `sanitizerPolicy` defaults to `'strict'` since 2.0; before that it was\n * `'compat'`, which let `id` and every `data-*` through, and `name` only where\n * a per-tag list allowed it. The difference\n * only shows when a binding *writes* markup, so a project that upgrades and\n * whose rich text carries its own hooks loses them at the moment an editor\n * types — silently, and in the preview only. Measured on a real consumer: a\n * `data-partner-scroll` attribute driving a CSS selector disappeared on the\n * first write, with nothing said anywhere.\n *\n * So it is said here: once per attribute name per page, with the reason that\n * applies to that name rather than one sentence covering three different\n * decisions. This is a report, never a behaviour — the attribute stays removed.\n */\n\n/**\n * `console.warn` behind a try/catch rather than `@core/diagnostics`: `security`\n * is a leaf layer and may not import `core` (scripts/architecture-rules.ts), and\n * the shared helper's extra work — tolerating a logger that returns a thenable —\n * is for consumer-supplied loggers. This sink is fixed.\n */\nfunction warn(message: string): void {\n try {\n console.warn(message);\n } catch {\n // A diagnostic must never become a second failure.\n }\n}\n\nconst reported = new Set<string>();\n\n/** The binding prefix, restated rather than imported: this module must not pull the applier in. */\nconst BINDING_PREFIX = 'data-payload-';\n\nfunction reason(name: string): string {\n if (name.startsWith(BINDING_PREFIX)) {\n return (\n 'A binding inside CMS content is refused by design — an editor could otherwise ' +\n 'aim a write at any element on the page (docs/security.md)'\n );\n }\n if (name === 'id' || name === 'name') {\n return (\n 'CMS content that can name an element can shadow a global of that name — ' +\n 'DOM clobbering, refused by design (docs/security.md)'\n );\n }\n return (\n 'List it in `allowedDataAttributes` if the page needs it, or set ' +\n \"`sanitizerPolicy: 'compat'` to keep every `data-*` as 1.x did\"\n );\n}\n\n/**\n * Report one removal. Only for attributes `'compat'` would have kept: everything\n * else the sanitizer drops was refused in 1.x too and is not news to anyone.\n */\nexport function reportDroppedAttribute(name: string): void {\n if (reported.has(name)) return;\n reported.add(name);\n warn(\n `[live-preview] LP0409: the strict sanitizer removed \\`${name}\\` from written markup; ` +\n `the 1.x default (\\`sanitizerPolicy: 'compat'\\`) kept it. ${reason(name)}.`,\n );\n}\n\n/** Test seam: the report is once per page, and a test is not a page. */\nexport function resetDroppedAttributeReports(): void {\n reported.clear();\n}\n","/**\n * HTML sanitizer built on the host parser (`<template>`): allow-listed tags\n * and attributes, validated URLs, hardened external links, no `style`.\n * Needs a DOM; string-only sanitizers are historically brittle.\n */\n\nimport { trustedHtml } from './trusted-types';\nimport { isSafeUrl, isExternalHttpUrl } from './url-validator';\nimport { reportDroppedAttribute } from './sanitizer-report';\n\ndeclare const __INLINE_BUILD__: boolean | undefined;\n\n/** Tags kept with their content. Others are unwrapped unless in `REMOVE_COMPLETELY`. */\nconst ALLOWED_TAGS: ReadonlySet<string> = new Set([\n 'p',\n 'br',\n 'strong',\n 'b',\n 'em',\n 'i',\n 'u',\n 's',\n 'strike',\n 'mark',\n 'small',\n 'h1',\n 'h2',\n 'h3',\n 'h4',\n 'h5',\n 'h6',\n 'ul',\n 'ol',\n 'li',\n 'dl',\n 'dt',\n 'dd',\n 'blockquote',\n 'code',\n 'pre',\n 'kbd',\n 'samp',\n 'var',\n 'a',\n 'span',\n 'div',\n 'section',\n 'article',\n 'aside',\n 'header',\n 'footer',\n 'nav',\n 'figure',\n 'figcaption',\n 'img',\n 'picture',\n 'source',\n 'audio',\n 'video',\n 'sub',\n 'sup',\n 'hr',\n 'time',\n 'abbr',\n 'cite',\n 'q',\n 'table',\n 'thead',\n 'tbody',\n 'tfoot',\n 'tr',\n 'th',\n 'td',\n 'caption',\n 'colgroup',\n 'col',\n]);\n\n/** Tags `allowFormControls` re-admits for author templates; `form` is deliberately not one. */\nconst FORM_CONTROLS: ReadonlySet<string> = new Set([\n 'input',\n 'button',\n 'textarea',\n 'select',\n 'option',\n 'label',\n]);\n\n/** Removed with their children: the content itself is the hazard. */\nconst REMOVE_COMPLETELY: ReadonlySet<string> = new Set([\n 'script',\n 'style',\n 'iframe',\n 'object',\n 'embed',\n 'link',\n 'meta',\n 'base',\n 'form',\n 'input',\n 'button',\n 'select',\n 'textarea',\n 'svg',\n 'math',\n 'template',\n 'frame',\n 'frameset',\n 'noframes',\n 'noscript',\n]);\n\nconst ATTR_GLOBAL: ReadonlySet<string> = new Set([\n 'id',\n 'class',\n 'lang',\n 'dir',\n 'title',\n 'role',\n 'tabindex',\n]);\n\nconst ATTR_ARIA_PREFIX = 'aria-';\nconst ATTR_DATA_PREFIX = 'data-';\nconst BINDING_DATA_PREFIX = 'data-payload-';\n\nconst ATTR_BY_TAG: Readonly<Record<string, ReadonlySet<string>>> = {\n a: new Set(['href', 'target', 'rel', 'download', 'hreflang', 'type']),\n img: new Set(['src', 'srcset', 'sizes', 'alt', 'width', 'height', 'loading', 'decoding']),\n picture: new Set([]),\n source: new Set(['src', 'srcset', 'sizes', 'type', 'media']),\n audio: new Set(['src', 'controls', 'autoplay', 'loop', 'muted', 'preload']),\n video: new Set([\n 'src',\n 'poster',\n 'controls',\n 'autoplay',\n 'loop',\n 'muted',\n 'preload',\n 'width',\n 'height',\n 'playsinline',\n ]),\n time: new Set(['datetime']),\n abbr: new Set(['title']),\n q: new Set(['cite']),\n blockquote: new Set(['cite']),\n table: new Set(['summary']),\n th: new Set(['colspan', 'rowspan', 'scope', 'headers', 'abbr']),\n td: new Set(['colspan', 'rowspan', 'headers']),\n col: new Set(['span']),\n colgroup: new Set(['span']),\n ol: new Set(['start', 'reversed', 'type']),\n li: new Set(['value']),\n code: new Set(['class']),\n pre: new Set(['class']),\n};\n\nconst URL_ATTRIBUTES: ReadonlySet<string> = new Set(['href', 'src', 'cite', 'poster']);\n\n// Numeric nodeType constants keep an injected SSR document independent of a\n// browser-global `Node` constructor.\nconst ELEMENT_NODE = 1;\nconst COMMENT_NODE = 8;\n\n/** Thrown by `sanitizeHtml()` when no `document` is available (SSR without `setSanitizerDocument()`). */\nexport class SanitizerEnvironmentError extends Error {\n override readonly name = 'SanitizerEnvironmentError';\n}\n\n/**\n * `'strict'` (default) strips `id`, `name` and `data-payload-*` and passes\n * other `data-*` only via `allowedDataAttributes`; `'compat'` keeps them.\n */\nexport type SanitizerPolicyMode = 'compat' | 'strict';\n\nexport interface SanitizeOptions {\n /** Overrides the module default set by `setSanitizerPolicy()`. */\n readonly policy?: SanitizerPolicyMode;\n /** `data-*` attributes (full names) that pass under `'strict'`; `data-payload-*` never does. */\n readonly allowedDataAttributes?: readonly string[];\n /**\n * Keep `input`, `button`, `textarea`, `select`, `option` and `label` — only\n * for markup the page author wrote, never for CMS content. `form`,\n * handlers, `style` and unsafe URLs stay dropped.\n */\n readonly allowFormControls?: boolean;\n /** Extra tags to allow. Lower-case, untrimmed. */\n readonly additionalAllowedTags?: readonly string[];\n /**\n * Extra per-tag attributes, lower-case. Cannot re-admit handlers, `style`,\n * or — under `'strict'` — `id`, `name` and `data-payload-*`.\n */\n readonly additionalAllowedAttributes?: Readonly<Record<string, readonly string[]>>;\n /**\n * The input is a page-author item template, so `'strict'` keeps the\n * applier's reconciliation attributes (`TEMPLATE_ATTRIBUTES`) and nothing\n * else — every other `data-payload-*` is still stripped, so a template can\n * never add a binding.\n */\n readonly templateMode?: boolean;\n}\n\n/** What `templateMode` keeps under `'strict'`. */\nconst TEMPLATE_ATTRIBUTES: ReadonlySet<string> = new Set([\n 'id',\n 'name',\n 'data-payload-key',\n 'data-payload-nested-key',\n 'data-payload-nested-template',\n]);\n\ninterface ResolvedPolicy {\n readonly allowedTags: ReadonlySet<string>;\n readonly allowFormControls: boolean;\n readonly templateMode: boolean;\n readonly mode: SanitizerPolicyMode;\n readonly allowedData: ReadonlySet<string>;\n readonly attrByTag: ReadonlyMap<string, ReadonlySet<string>>;\n}\n\nlet defaultMode: SanitizerPolicyMode = 'strict';\n\n/**\n * The default for calls without an explicit `policy`, per package entry. A\n * runtime carries its own `sanitizerPolicy` and never writes here (ADR 0002).\n */\nexport function setSanitizerPolicy(mode: SanitizerPolicyMode): void {\n defaultMode = mode;\n}\n\n/** `instancePolicy` sits between a per-call `options.policy` and the process default. */\nfunction resolvePolicy(\n options: SanitizeOptions | undefined,\n instancePolicy: SanitizerPolicyMode | undefined,\n): ResolvedPolicy {\n const mode = options?.policy ?? instancePolicy ?? defaultMode;\n if (!options) {\n const attrMap = new Map<string, ReadonlySet<string>>();\n for (const [tag, attrs] of Object.entries(ATTR_BY_TAG)) attrMap.set(tag, attrs);\n return {\n allowedTags: ALLOWED_TAGS,\n attrByTag: attrMap,\n allowFormControls: false,\n templateMode: false,\n mode,\n allowedData: new Set(),\n };\n }\n const allowed = new Set(ALLOWED_TAGS);\n options.additionalAllowedTags?.forEach((tag) => allowed.add(tag));\n if (options.allowFormControls === true) for (const tag of FORM_CONTROLS) allowed.add(tag);\n const attrMap = new Map<string, ReadonlySet<string>>();\n for (const [tag, attrs] of Object.entries(ATTR_BY_TAG)) attrMap.set(tag, attrs);\n for (const [tag, attrs] of Object.entries(options.additionalAllowedAttributes ?? {})) {\n const merged = new Set(attrMap.get(tag));\n for (const attr of attrs) merged.add(attr);\n attrMap.set(tag, merged);\n }\n return {\n allowedTags: allowed,\n attrByTag: attrMap,\n allowFormControls: options.allowFormControls === true,\n templateMode: options.templateMode === true,\n mode,\n allowedData: new Set(options.allowedDataAttributes?.map((name) => name.toLowerCase())),\n };\n}\n\n/** The `Document` surface the sanitizer needs; jsdom, linkedom and happy-dom all provide it. */\nexport interface SanitizerDocument {\n createElement: (tagName: string) => {\n innerHTML: string;\n readonly content: ParentNode;\n };\n}\n\n// Held on the realm, not in this module: every package entry is its own bundle\n// with its own copy of this file, and a document supplied through the root has\n// to reach the rich text `payload-live-preview/lexical` renders.\nconst DOCUMENT_SLOT: unique symbol = Symbol.for('payload-live-preview.sanitizer-document');\n\ninterface DocumentSlot {\n [DOCUMENT_SLOT]?: SanitizerDocument | undefined;\n}\n\n/** Supply a `Document` for SSR, e.g. linkedom's `parseHTML(...).document`; `null` clears it, for every entry. */\nexport function setSanitizerDocument(doc: SanitizerDocument | null): void {\n (globalThis as DocumentSlot)[DOCUMENT_SLOT] = doc ?? undefined;\n}\n\n/**\n * Sanitize `html`; malformed input is recovered by the parser first.\n *\n * @throws {SanitizerEnvironmentError} when no DOM is available.\n */\nexport function sanitizeHtml(html: string, options?: SanitizeOptions): string {\n return sanitizeHtmlWithPolicy(html, undefined, options);\n}\n\n/**\n * The runtime's entry: `policy` is one instance's, applied unless `options`\n * carry their own, so two clients on a page never share a policy through\n * this module. Not public — a direct caller has `options.policy`.\n */\nexport function sanitizeHtmlWithPolicy(\n html: string,\n policy: SanitizerPolicyMode | undefined,\n options?: SanitizeOptions,\n): string {\n const doc = resolveDocument();\n if (!doc) throw environmentError();\n if (html === '') return '';\n\n const resolved = resolvePolicy(options, policy);\n const template = doc.createElement('template');\n // The sanitizer's own parse is a sink too: under Trusted Types it needs the policy.\n template.innerHTML = trustedHtml(html);\n sanitizeFragment(template.content, resolved);\n return template.innerHTML;\n}\n\n// Read the define at each branch rather than through a helper: a bundler\n// folds the substituted literal in place, but will not inline a call, and the\n// SSR-only class and override must not reach the browser runtime.\nfunction environmentError(): Error {\n if (typeof __INLINE_BUILD__ !== 'undefined' && __INLINE_BUILD__) {\n return new Error('sanitizeHtml needs a DOM');\n }\n return new SanitizerEnvironmentError(\n 'sanitizeHtml needs a DOM; provide one with setSanitizerDocument() during SSR.',\n );\n}\n\nfunction resolveDocument(): SanitizerDocument | undefined {\n if (typeof __INLINE_BUILD__ === 'undefined' || !__INLINE_BUILD__) {\n const override = (globalThis as DocumentSlot)[DOCUMENT_SLOT];\n if (override) return override;\n }\n if (typeof document === 'undefined') return undefined;\n return document;\n}\n\n/** Whether a DOM is available — the global or an injected one — for callers that treat sanitizing as optional. */\nexport function hasSanitizerDocument(): boolean {\n return resolveDocument() !== undefined;\n}\n\nfunction sanitizeFragment(node: ParentNode, policy: ResolvedPolicy): void {\n // Snapshot: children are mutated during the walk.\n for (const child of Array.from(node.childNodes)) {\n if (child.nodeType === ELEMENT_NODE) {\n sanitizeElement(child as Element, policy);\n } else if (child.nodeType === COMMENT_NODE) {\n child.remove();\n }\n }\n}\n\nfunction sanitizeElement(element: Element, policy: ResolvedPolicy): void {\n const tag = element.tagName.toLowerCase();\n\n if (REMOVE_COMPLETELY.has(tag) && !(policy.allowFormControls && FORM_CONTROLS.has(tag))) {\n element.remove();\n return;\n }\n\n if (!policy.allowedTags.has(tag)) {\n sanitizeFragment(element, policy);\n element.replaceWith(...element.childNodes);\n return;\n }\n\n sanitizeAttributes(element, tag, policy);\n if (tag === 'a') hardenAnchor(element);\n sanitizeFragment(element, policy);\n}\n\nfunction sanitizeAttributes(element: Element, tag: string, policy: ResolvedPolicy): void {\n const tagAttrs = policy.attrByTag.get(tag);\n\n for (const attr of Array.from(element.attributes)) {\n const name = attr.name.toLowerCase();\n if (name.startsWith('on') || name === 'style') {\n element.removeAttribute(attr.name);\n continue;\n }\n if (policy.mode === 'strict') {\n if (policy.templateMode && TEMPLATE_ATTRIBUTES.has(name)) continue;\n // DOM clobbering and binding injection (docs/security.md §5c). Checked\n // before the allow-list so an extension cannot re-admit them.\n if (name === 'id' || name === 'name' || name.startsWith(BINDING_DATA_PREFIX)) {\n element.removeAttribute(attr.name);\n // `compat` kept `name` only where a per-tag list allowed it, so only\n // there did the upgrade change anything to report.\n if (name !== 'name' || tagAttrs?.has(name) === true) reportDroppedAttribute(name);\n continue;\n }\n if (name.startsWith(ATTR_DATA_PREFIX)) {\n if (!policy.allowedData.has(name)) {\n element.removeAttribute(attr.name);\n reportDroppedAttribute(name);\n }\n continue;\n }\n if (ATTR_GLOBAL.has(name) || name.startsWith(ATTR_ARIA_PREFIX)) continue;\n } else if (\n ATTR_GLOBAL.has(name) ||\n name.startsWith(ATTR_ARIA_PREFIX) ||\n name.startsWith(ATTR_DATA_PREFIX)\n ) {\n continue;\n }\n if (tagAttrs?.has(name)) {\n if (URL_ATTRIBUTES.has(name) && !isSafeUrl(attr.value)) {\n element.removeAttribute(attr.name);\n } else if (name === 'srcset' && !isSafeSrcset(attr.value)) {\n element.removeAttribute(attr.name);\n }\n continue;\n }\n element.removeAttribute(attr.name);\n }\n}\n\n/** Every `srcset` candidate must pass; partial rewriting would silently change what renders. */\nfunction isSafeSrcset(value: string): boolean {\n for (const candidate of value.split(',')) {\n const trimmed = candidate.trim();\n if (trimmed.length === 0) continue;\n // The URL ends at the first whitespace; what follows is the descriptor.\n const [url = trimmed] = trimmed.split(/\\s/, 1);\n if (!isSafeUrl(url)) return false;\n }\n return true;\n}\n\nfunction hardenAnchor(anchor: Element): void {\n const href = anchor.getAttribute('href');\n if (href === null || !isExternalHttpUrl(href)) return;\n anchor.setAttribute('rel', 'noopener noreferrer');\n if (!anchor.hasAttribute('target')) anchor.setAttribute('target', '_blank');\n}\n\n/** The built-in allow-lists, for documentation and tests. */\nexport const SANITIZER_POLICY = Object.freeze({\n allowedTags: ALLOWED_TAGS,\n removeCompletely: REMOVE_COMPLETELY,\n globalAttributes: ATTR_GLOBAL,\n attributesByTag: ATTR_BY_TAG,\n urlAttributes: URL_ATTRIBUTES,\n});\n","/** HTML and CSS escaping primitives (OWASP XSS Prevention Cheat Sheet). DOM-free. */\n\nconst HTML_ESCAPES: Readonly<Record<string, string>> = Object.freeze({\n '&': '&',\n '<': '<',\n '>': '>',\n '\"': '"',\n \"'\": ''',\n '/': '/',\n '`': '`',\n '=': '=',\n});\n\nconst HTML_ESCAPE_PATTERN = /[&<>\"'/`=]/g;\n\n/** Escape `text` for an element body or a *quoted* attribute value; strings only, and unquoted attributes are not covered. */\nexport function escapeHtml(text: string): string {\n // The character class and the map are coupled: every match is a key.\n // eslint-disable-next-line @typescript-eslint/non-nullable-type-assertion-style\n return text.replace(HTML_ESCAPE_PATTERN, (char) => HTML_ESCAPES[char] as string);\n}\n\n/** Escape a value for a CSS `url(...)` literal; this stops the break-out, not the scheme, so pair it with `isSafeUrl()`. */\nexport function escapeCssUrl(value: string): string {\n return value.replace(/['\"()\\\\]/g, '\\\\$&');\n}\n\nconst ATTR_ESCAPES: Readonly<Record<string, string>> = Object.freeze({\n '&': '&',\n '<': '<',\n '>': '>',\n '\"': '"',\n \"'\": ''',\n});\n\nconst ATTR_ESCAPE_PATTERN = /[&<>\"']/g;\n\n/** Escape a value for a *quoted* HTML attribute, leaving URL characters intact; it validates no scheme, so run `isSafeUrl()` on `href`/`src` first. @internal */\nexport function escapeHtmlAttribute(value: string): string {\n // The character class and the map are coupled: every match is a key.\n // eslint-disable-next-line @typescript-eslint/non-nullable-type-assertion-style\n return value.replace(ATTR_ESCAPE_PATTERN, (char) => ATTR_ESCAPES[char] as string);\n}\n\n/** `escapeHtml()` then newlines to `<br>`; the order is what makes it safe. */\nexport function escapeAndLinebreak(text: string): string {\n return escapeHtml(text).replace(/\\r\\n|\\r|\\n/g, '<br>');\n}\n","/**\n * One array item out of one template: the interpolation, and the attributes the\n * template cannot know about.\n *\n * A replacement value is data, not template syntax: one `replace()` per key\n * would re-interpret `{{index}}` text that an earlier value introduced, and\n * would apply `String.replace`'s `$` semantics to CMS content.\n */\n\nimport { escapeHtml } from '@security/escape';\nimport { isWritableAttribute } from './attribute-binding';\n\nconst PLACEHOLDER_PATTERN = /\\{\\{([\\s\\S]*?)\\}\\}/g;\n\n/** The runtime's own annotations; a rebuilt item gets its own, never a copy. */\nconst BINDING_ATTRIBUTE_PREFIX = 'data-payload-';\n\n/** An attribute name and its value, as they travel from an old item to a new one. */\nexport type InheritedAttribute = readonly [name: string, value: string];\n\nfunction hasOwn(record: object, key: PropertyKey): boolean {\n return Object.prototype.hasOwnProperty.call(record, key);\n}\n\n/**\n * Every key any item carries. A placeholder naming one of these is a field of\n * this array, so a row that happens to lack it renders as nothing; a\n * placeholder no row can fill is a typo in the template and stays visible.\n */\nexport function collectTemplateKeys(items: readonly unknown[]): ReadonlySet<string> {\n const keys = new Set<string>();\n for (const item of items) {\n if (typeof item !== 'object' || item === null) continue;\n for (const key of Object.keys(item)) keys.add(key);\n }\n return keys;\n}\n\nexport function interpolateArrayTemplate(\n template: string,\n item: unknown,\n index: number,\n stringify: (value: unknown) => string,\n knownKeys?: ReadonlySet<string>,\n): string {\n const record = typeof item === 'object' && item !== null ? item : null;\n\n return template.replace(PLACEHOLDER_PATTERN, (placeholder, key: string) => {\n // Preserve the established object-field precedence when an object itself\n // has an `index` or `value` property. Otherwise these are reserved tokens.\n if (record !== null && hasOwn(record, key)) {\n return escapeHtml(stringify(Reflect.get(record, key)));\n }\n if (record === null && key === 'value') return escapeHtml(stringify(item));\n if (key === 'index') return String(index);\n // A field other rows carry: this one simply has none. Writing the\n // placeholder would print template syntax on the page, which is what an\n // editor sees the moment a row is added and not every field is filled in.\n if (record !== null && knownKeys?.has(key) === true) return '';\n return placeholder;\n });\n}\n\n/**\n * What the items already in `container` all carry, and an item rebuilt from the\n * template therefore has to carry too.\n *\n * A framework's scoped styles hang on a marker its compiler writes into the\n * markup — Astro's `data-astro-cid-…`, Vue's `data-v-…`, Svelte's class — and\n * the author's `data-payload-array-template` has none of it. The rebuilt list\n * then renders unstyled next to the one the server sent, while the write itself\n * succeeds, so nothing in the runtime can notice. Naming no framework is the\n * point: what identifies these attributes is that every item of the list has\n * them with the same value, which per-row state by definition does not.\n */\nexport function sharedItemAttributes(container: Element): readonly InheritedAttribute[] {\n const items = container.children;\n const first = items[0];\n if (first === undefined) return [];\n const shared: InheritedAttribute[] = [];\n for (const { name, value } of Array.from(first.attributes)) {\n if (!isWritableAttribute(name) || name.startsWith(BINDING_ATTRIBUTE_PREFIX)) continue;\n let everyItem = true;\n for (let index = 1; index < items.length && everyItem; index += 1) {\n everyItem = items[index]?.getAttribute(name) === value;\n }\n if (everyItem) shared.push([name, value]);\n }\n return shared;\n}\n\n/** Give a rebuilt item what its predecessors shared; the template's own value wins. */\nexport function inheritItemAttributes(item: Element, shared: readonly InheritedAttribute[]): void {\n for (const [name, value] of shared) {\n if (!item.hasAttribute(name)) item.setAttribute(name, value);\n }\n}\n","/** Value coercion shared by the field renderers. */\n\n/** Display string for any value: primitives as-is, objects as JSON, `null`/`undefined` as `''`. */\nexport function safeStringify(value: unknown): string {\n if (value === null || value === undefined) return '';\n if (typeof value === 'string') return value;\n if (typeof value === 'number' || typeof value === 'boolean' || typeof value === 'bigint') {\n return String(value);\n }\n try {\n return JSON.stringify(value);\n } catch {\n return '';\n }\n}\n\n/** The three values every renderer treats as \"clear\" (docs/renderers.md, value semantics). */\nexport function isEmptyValue(value: unknown): value is null | undefined | '' {\n return value === null || value === undefined || value === '';\n}\n","/**\n * LRU discipline for a module-scoped lookup `Map` (ADR 0003 §3). Functions\n * over the caller's own `Map` rather than a wrapper class: the inline bundle\n * mangles function names but not property names, so a class would pay for\n * every `this.entries` in full. A `Map` iterates in insertion order, which a\n * touch on every hit turns into recency order. Values are never `undefined`,\n * and a write follows a miss — a key already present keeps its position.\n */\n\n/** Read and touch: a hit becomes the newest entry. */\nexport function lruGet<K, V>(map: Map<K, V>, key: K): V | undefined {\n const value = map.get(key);\n if (value !== undefined) {\n map.delete(key);\n map.set(key, value);\n }\n return value;\n}\n\n/** Write as the newest entry, dropping the oldest ones past `limit`; returns `value`. */\nexport function lruSet<K, V>(map: Map<K, V>, key: K, value: V, limit: number): V {\n map.set(key, value);\n lruTrim(map, limit);\n return value;\n}\n\n/** Drop the oldest entries until `limit` holds. */\nexport function lruTrim<K>(map: Map<K, unknown>, limit: number): void {\n for (const oldest of map.keys()) {\n if (map.size <= limit) break;\n map.delete(oldest);\n }\n}\n","/**\n * Sanitizer options for item templates (`data-payload-array-template`,\n * nested templates). A template is the page author's markup and every\n * interpolated value is escaped to text before the sanitizer runs, so it may\n * carry form controls and custom elements the rich-text policy refuses.\n * Event handlers, `style` and unsafe URLs are still stripped.\n *\n * Some entries below are already admitted by the sanitizer through another\n * route — `video` and `audio` by the tag allow-list, `select` by\n * `allowFormControls`, `name` by `templateMode`, and `controls`, `muted`,\n * `loop`, `poster` and `src` by the per-tag attribute map. They are kept\n * because this list states what a template may contain, and an allow-list\n * that depends on a second list staying unchanged is the more fragile of the\n * two arrangements. Mutating those entries changes nothing observable, so\n * they survive mutation testing by construction; the behaviour they describe\n * is pinned in `tests/unit/core/template-sanitize.test.ts` instead.\n */\n\nimport type { SanitizeOptions } from '@security/sanitizer';\nimport { lruGet, lruSet } from './lru';\n\nconst TEMPLATE_EXTRA_TAGS: readonly string[] = [\n 'input',\n 'textarea',\n 'select',\n 'option',\n 'button',\n 'label',\n 'details',\n 'summary',\n 'dialog',\n 'video',\n 'audio',\n 'progress',\n 'meter',\n];\n\nconst TEMPLATE_EXTRA_ATTRIBUTES: readonly string[] = [\n 'type',\n 'name',\n 'placeholder',\n 'open',\n 'disabled',\n 'readonly',\n 'required',\n 'checked',\n 'selected',\n 'value',\n 'min',\n 'max',\n 'step',\n 'rows',\n 'cols',\n 'for',\n 'controls',\n 'muted',\n 'loop',\n 'poster',\n 'src',\n];\n\nconst CUSTOM_TAG_PATTERN = /<([a-z][a-z0-9]*(?:-[a-z0-9]+)+)\\b/gi;\n\n// 64 like the intl cache: more than a page declares, and a nested template is\n// interpolated with its parent's, so an outer value or `{{index}}` that lands\n// in it mints a key per item and per keystroke (ADR 0003 §3).\nexport const TEMPLATE_CACHE_LIMIT = 64;\nconst optionsByTemplate = new Map<string, SanitizeOptions>();\n\n/** Options for one template; memoised per template string. */\nexport function templateSanitizeOptions(template: string): SanitizeOptions {\n const cached = lruGet(optionsByTemplate, template);\n if (cached !== undefined) return cached;\n const tags = new Set(TEMPLATE_EXTRA_TAGS);\n for (const match of template.matchAll(CUSTOM_TAG_PATTERN)) {\n const tag = match[1]?.toLowerCase();\n if (tag !== undefined) tags.add(tag);\n }\n const attributes: Record<string, readonly string[]> = {};\n for (const tag of tags) attributes[tag] = TEMPLATE_EXTRA_ATTRIBUTES;\n const options: SanitizeOptions = {\n additionalAllowedTags: [...tags],\n additionalAllowedAttributes: attributes,\n allowFormControls: true,\n templateMode: true,\n };\n return lruSet(optionsByTemplate, template, options, TEMPLATE_CACHE_LIMIT);\n}\n","/**\n * Applies an `ArrayPatch[]` diff to a container as keyed DOM operations\n * instead of rebuilding the list, so consumer state on surviving children is\n * kept. Items are paired by `data-payload-key` (the item `id`); items without\n * one pair by position. Nested arrays reconcile recursively through\n * `data-payload-nested-key` slots. See ADR 0008.\n */\n\nimport { sanitizeHtmlWithPolicy, type SanitizerPolicyMode } from '@security/sanitizer';\nimport { trustedHtml } from '@security/trusted-types';\nimport {\n collectTemplateKeys,\n inheritItemAttributes,\n interpolateArrayTemplate,\n sharedItemAttributes,\n type InheritedAttribute,\n} from './array-template';\nimport { safeStringify } from '@field-types/utils';\nimport { diffArray, type ArrayPatch } from '@schema/diff';\nimport { morphElement } from './morph';\nimport { templateSanitizeOptions } from './template-sanitize';\n\n/** @internal */\nexport const KEY_ATTRIBUTE = 'data-payload-key';\nconst NESTED_KEY_ATTRIBUTE = 'data-payload-nested-key';\nconst NESTED_TEMPLATE_ATTRIBUTE = 'data-payload-nested-template';\n\n/** Last value seen per item key, per container; owned by the caller so instances never share it. @internal */\nexport type StructuralStore = WeakMap<Element, Map<string, unknown>>;\n\n/** @internal */\nexport function createStructuralStore(): StructuralStore {\n return new WeakMap<Element, Map<string, unknown>>();\n}\n\n/** @internal */\nexport interface StructuralApplyOptions {\n readonly template: string;\n readonly container: Element;\n readonly patches: readonly ArrayPatch[];\n /** The full new array; inserts and replaces render by index from it. */\n readonly nextItems: readonly unknown[];\n /** Pass the same store across renders so nested arrays diff incrementally. */\n readonly store: StructuralStore;\n /** Re-render existing items even when unchanged. */\n readonly forceRender?: boolean;\n /** The instance's policy for item markup; absent, the process default applies. */\n readonly sanitizerPolicy?: SanitizerPolicyMode | undefined;\n /** Edit a changed item in place instead of replacing it. Default `true`. */\n readonly morph?: boolean;\n /** Reported once per container when two items share a key (`LP0405`). */\n readonly onDuplicateKey?: (container: Element, key: string) => void;\n}\n\n/**\n * Returns `true` for a DOM mutation, `false` for an already-current tree, and\n * `null` when an item's markup has no sanitized element root — preflighted\n * before any mutation, so the previous DOM and memory stay intact.\n * @internal\n */\nexport function applyStructuralPatches(options: StructuralApplyOptions): boolean | null {\n const plan = prepareStructuralPlan(options.container, options.patches, options);\n if (plan === null) return null;\n return commitStructuralPlan(plan, options.store, {\n morph: options.morph ?? true,\n onDuplicateKey: options.onDuplicateKey,\n });\n}\n\n// Plan records are tuples: many are created per recursive render, and named\n// keys would repeat in the inline bundle.\ntype StructuralPlan = readonly [\n container: Element,\n entries: readonly ReconciliationEntry[],\n nextItems: readonly unknown[],\n];\ntype ReconciliationEntry = readonly [\n index: number,\n live: Element | null,\n rendered: Element | undefined,\n nestedSlots: readonly NestedSlotPlan[],\n /** A `replace` patch: a different item, never morphed toward. */\n replace: boolean,\n];\ntype NestedSlotPlan = readonly [\n live: Element | null,\n rendered: Element,\n children: StructuralPlan | undefined,\n];\n\n// One per container, not per item, so — unlike the tuples above — named keys\n// cost the inline bundle nothing per render.\ntype RenderEnv = Pick<\n StructuralApplyOptions,\n 'template' | 'nextItems' | 'forceRender' | 'store' | 'sanitizerPolicy'\n>;\n\ninterface CommitOptions {\n readonly morph: boolean;\n readonly onDuplicateKey: ((container: Element, key: string) => void) | undefined;\n}\n\n/** A rendered slot that still carries a nested template keeps its children for its own plan. */\nfunction isManagedNestedSlot(_live: Element, rendered: Element): boolean {\n return (\n rendered.hasAttribute(NESTED_KEY_ATTRIBUTE) && rendered.hasAttribute(NESTED_TEMPLATE_ATTRIBUTE)\n );\n}\n\n/** Materialise the whole recursive replacement tree before touching live DOM. */\nfunction prepareStructuralPlan(\n container: Element,\n patches: readonly ArrayPatch[],\n env: RenderEnv,\n): StructuralPlan | null {\n const entries = prepareReconciliation(container, createPatchPlan(patches), env);\n return entries === null ? null : [container, entries, env.nextItems];\n}\n\nfunction commitStructuralPlan(\n plan: StructuralPlan,\n store: StructuralStore,\n options: CommitOptions,\n): boolean {\n const [container, entries, nextItems] = plan;\n const claimed = new Set<Element>();\n let mutated = false;\n for (const [index, live, rendered, nestedSlots, replace] of entries) {\n let node = live;\n if (rendered !== undefined) {\n // Morph a compatible live item in place; otherwise transplant its live\n // nested slots into the rendered item and swap.\n const retained =\n options.morph && !replace && live !== null\n ? morphElement(live, rendered, {\n keyAttributes: [KEY_ATTRIBUTE, NESTED_KEY_ATTRIBUTE],\n retainChildrenOf: isManagedNestedSlot,\n ...(options.onDuplicateKey !== undefined\n ? { onDuplicateKey: options.onDuplicateKey }\n : {}),\n }) === live\n : false;\n if (!retained) {\n for (const [liveSlot, renderedSlot] of nestedSlots) {\n if (liveSlot === null) continue;\n synchronizeAttributes(liveSlot, renderedSlot);\n renderedSlot.replaceWith(liveSlot);\n }\n }\n for (const [, , children] of nestedSlots) {\n if (children !== undefined) commitStructuralPlan(children, store, options);\n }\n if (retained) {\n mutated = true;\n } else {\n if (live !== null) {\n live.replaceWith(rendered);\n mutated = true;\n }\n node = rendered;\n }\n }\n if (node === null) continue;\n const before = container.children[index] ?? null;\n if (node !== before) {\n container.insertBefore(node, before);\n mutated = true;\n }\n claimed.add(node);\n }\n // `nextItems` is the source of truth; this also drops SSR children the first value did not carry.\n for (const child of Array.from(container.children)) {\n if (claimed.has(child)) continue;\n child.remove();\n mutated = true;\n }\n const memory = getMemory(container, store);\n memory.clear();\n for (const value of nextItems) rememberItem(memory, value);\n return mutated;\n}\n\n/**\n * Pair every final item with a live child (by key, else by position) and\n * render what needs rendering. Patch indices describe `next`, live indices\n * move during reconciliation, so keyed nodes are resolved from the DOM first.\n */\nfunction prepareReconciliation(\n container: Element,\n plan: PatchPlan,\n env: RenderEnv,\n): readonly ReconciliationEntry[] | null {\n const { template, nextItems, forceRender = false, store, sanitizerPolicy } = env;\n const memory = store.get(container);\n // Read before anything is rendered: what the current items share is what the\n // template cannot say, and an inserted item has no predecessor of its own.\n const shared = sharedItemAttributes(container);\n const templateKeys = collectTemplateKeys(nextItems);\n const initialChildren = Array.from(container.children);\n const keyedChildren = indexByAttribute(initialChildren, KEY_ATTRIBUTE);\n const reserved = new Set<Element>();\n const entries: ReconciliationEntry[] = [];\n for (let index = 0; index < nextItems.length; index += 1) {\n const value = nextItems[index];\n const key = readKey(value);\n let live =\n key === undefined\n ? (initialChildren[index] ?? null)\n : (takeIndexedElement(keyedChildren, key) ?? null);\n if (live !== null && reserved.has(live)) live = null;\n if (live !== null) reserved.add(live);\n const replace = plan.replaces.has(index);\n const needsRender = forceRender || plan.renders.has(index) || live === null;\n const rendered = needsRender\n ? renderItem(\n container.ownerDocument,\n template,\n value,\n index,\n sanitizerPolicy,\n shared,\n templateKeys,\n )\n : undefined;\n if (rendered === null) return null;\n const nestedSlots =\n rendered === undefined\n ? []\n : prepareNestedSlots(\n replace ? null : live,\n rendered,\n value,\n key === undefined ? undefined : memory?.get(key),\n env,\n );\n if (nestedSlots === null) return null;\n entries.push([index, live, rendered, nestedSlots, replace]);\n }\n return entries;\n}\n\ninterface PatchPlan {\n readonly renders: ReadonlySet<number>;\n readonly replaces: ReadonlySet<number>;\n}\n\nfunction createPatchPlan(patches: readonly ArrayPatch[]): PatchPlan {\n const renders = new Set<number>();\n const replaces = new Set<number>();\n for (const patch of patches) {\n if (patch.kind === 'insert' || patch.kind === 'update') renders.add(patch.index);\n else if (patch.kind === 'replace') {\n renders.add(patch.index);\n replaces.add(patch.index);\n }\n }\n return { renders, replaces };\n}\n\n/** Plan each direct nested slot; a failure at any depth aborts before commit. */\nfunction prepareNestedSlots(\n oldItem: Element | null,\n newItem: Element,\n nextValue: unknown,\n prevValue: unknown,\n env: RenderEnv,\n): readonly NestedSlotPlan[] | null {\n const oldSlots = oldItem === null ? [] : findDirectNestedSlots(oldItem);\n const oldSlotsByKey = indexByAttribute(oldSlots, NESTED_KEY_ATTRIBUTE);\n const plans: NestedSlotPlan[] = [];\n for (const newSlot of findDirectNestedSlots(newItem)) {\n const key = newSlot.getAttribute(NESTED_KEY_ATTRIBUTE);\n if (key === null) continue;\n const oldSlot = takeIndexedElement(oldSlotsByKey, key) ?? null;\n const nextTemplate = newSlot.getAttribute(NESTED_TEMPLATE_ATTRIBUTE);\n // Without a nested template the slot's rendered static content is authoritative.\n const liveSlot = nextTemplate ? oldSlot : null;\n const previousTemplate = liveSlot?.getAttribute(NESTED_TEMPLATE_ATTRIBUTE) ?? null;\n let children: StructuralPlan | undefined;\n if (nextTemplate) {\n const nextNested = readNestedArray(nextValue, key);\n if (nextNested !== undefined || liveSlot !== null) {\n const resolvedNext = nextNested ?? [];\n const prevNested = liveSlot === null ? [] : (readNestedArray(prevValue, key) ?? []);\n const patches = diffArray(prevNested, resolvedNext);\n const templateChanged = liveSlot !== null && previousTemplate !== nextTemplate;\n if (patches.length > 0 || templateChanged) {\n children =\n prepareStructuralPlan(liveSlot ?? newSlot, patches, {\n template: nextTemplate,\n nextItems: resolvedNext,\n forceRender: templateChanged,\n store: env.store,\n sanitizerPolicy: env.sanitizerPolicy,\n }) ?? undefined;\n if (children === undefined) return null;\n }\n }\n }\n plans.push([liveSlot, newSlot, children]);\n }\n return plans;\n}\n\n/** Only the outermost nested slots: a transplanted slot owns the recursion below it. */\nfunction findDirectNestedSlots(item: Element): readonly Element[] {\n return Array.from(item.querySelectorAll(`[${NESTED_KEY_ATTRIBUTE}]`)).filter((slot) => {\n let ancestor = slot.parentElement;\n while (ancestor !== null && ancestor !== item) {\n if (ancestor.hasAttribute(NESTED_KEY_ATTRIBUTE)) return false;\n ancestor = ancestor.parentElement;\n }\n return ancestor === item;\n });\n}\n\nfunction synchronizeAttributes(target: Element, source: Element): void {\n for (const attribute of Array.from(target.attributes)) {\n if (!source.hasAttribute(attribute.name)) target.removeAttribute(attribute.name);\n }\n for (const attribute of Array.from(source.attributes)) {\n if (target.getAttribute(attribute.name) !== attribute.value) {\n target.setAttribute(attribute.name, attribute.value);\n }\n }\n}\n\nfunction readNestedArray(value: unknown, key: string): readonly unknown[] | undefined {\n if (typeof value !== 'object' || value === null) return undefined;\n const nested = (value as Record<string, unknown>)[key];\n return Array.isArray(nested) ? (nested as readonly unknown[]) : undefined;\n}\n\nfunction getMemory(container: Element, store: StructuralStore): Map<string, unknown> {\n let map = store.get(container);\n if (!map) {\n map = new Map();\n store.set(container, map);\n }\n return map;\n}\n\nfunction rememberItem(memory: Map<string, unknown>, value: unknown): void {\n const key = readKey(value);\n if (key !== undefined) memory.set(key, value);\n}\n\nfunction readKey(value: unknown): string | undefined {\n if (typeof value !== 'object' || value === null) return undefined;\n const id = (value as Record<string, unknown>)['id'];\n return typeof id === 'string' || typeof id === 'number' ? String(id) : undefined;\n}\n\nfunction indexByAttribute(elements: readonly Element[], attribute: string): Map<string, Element[]> {\n const indexed = new Map<string, Element[]>();\n // Reverse order so pop() yields duplicates in DOM order.\n for (let index = elements.length - 1; index >= 0; index -= 1) {\n const element = elements[index];\n if (element === undefined) continue;\n const key = element.getAttribute(attribute);\n if (key === null) continue;\n const bucket = indexed.get(key);\n if (bucket === undefined) indexed.set(key, [element]);\n else bucket.push(element);\n }\n return indexed;\n}\n\nfunction takeIndexedElement(indexed: Map<string, Element[]>, key: string): Element | undefined {\n return indexed.get(key)?.pop();\n}\n\n/** Render one item; its `id` is stamped as `data-payload-key` so later diffs find it. */\nfunction renderItem(\n ownerDocument: Document,\n template: string,\n value: unknown,\n index: number,\n policy: SanitizerPolicyMode | undefined,\n shared: readonly InheritedAttribute[],\n knownKeys: ReadonlySet<string>,\n): Element | null {\n const filled = interpolateArrayTemplate(template, value, index, safeStringify, knownKeys);\n const safe = sanitizeHtmlWithPolicy(filled, policy, templateSanitizeOptions(template));\n const host = ownerDocument.createElement('template');\n host.innerHTML = trustedHtml(safe);\n const first = host.content.firstElementChild;\n if (!first) return null;\n // Before the morph, which strips from the live item every attribute the\n // rendered one lacks: the marker has to be on this side to survive.\n inheritItemAttributes(first, shared);\n const key = readKey(value);\n if (key !== undefined) first.setAttribute(KEY_ATTRIBUTE, key);\n return first;\n}\n","/**\n * The two warnings a binding's strategy can produce, kept apart from the runner\n * that usually issues them: the lean profile has no runner (see ./profile) and\n * still owes a page these answers, because both describe the markup, not the\n * strategy machinery.\n */\n\nimport type { RuntimeDeps, RuntimeState } from './runtime-state';\nimport type { CachedElement } from './types';\n\n/** LP0806, once: a fragment boundary with no handler is patched instead. */\nexport function warnFragmentFallback(\n deps: RuntimeDeps,\n state: RuntimeState,\n target: CachedElement,\n): void {\n if (state.warnedFragmentFallback) return;\n state.warnedFragmentFallback = true;\n deps.warn(\n `[live-preview] LP0806: \"${target.fieldName}\" asks for the fragment strategy but no handler is configured; patching instead`,\n );\n}\n\n/** LP0407, once per element: an unknown strategy is left alone, not guessed at. */\nexport function warnUnsupportedStrategy(\n deps: RuntimeDeps,\n state: RuntimeState,\n target: CachedElement,\n): void {\n if (state.warnedStrategy.has(target.element)) return;\n state.warnedStrategy.add(target.element);\n deps.warn(\n `[live-preview] LP0407: \"${target.fieldName}\" asks for strategy \"${String(target.strategy)}\"; only patch, fragment and route exist`,\n );\n}\n","/**\n * Runs the fragment and route strategies for a revision. A strategy that\n * throws or rejects is treated as failed, never left to reject the runtime.\n */\n\nimport type { PayloadLivePreviewData } from '@/types/payload-protocol';\nimport { trustedHtml } from '@security/trusted-types';\nimport { reportUnboundChange } from './fidelity';\nimport { bindingValue } from './field-value';\nimport { morphElement } from './morph';\nimport type { RuntimeDeps, RuntimeState, UpdateTransaction } from './runtime-state';\nimport type { FragmentContext, FragmentStrategy, RouteOutcome, RouteStrategy } from './strategies';\nimport { KEY_ATTRIBUTE } from './structural-applier';\nimport { warnFragmentFallback, warnUnsupportedStrategy } from './strategy-warnings';\nimport { unboundChangedFields, type OwnerScope } from './unbound-fields';\nimport type { CachedElement } from './types';\n\n/** What the pipeline lends the runner. */\nexport interface StrategyHost {\n readonly reapply: (transaction: UpdateTransaction, data: PayloadLivePreviewData) => void;\n readonly transform: (\n target: CachedElement,\n value: unknown,\n allFields: Record<string, unknown>,\n isCurrent: () => boolean,\n ) => unknown;\n readonly rebuildCache: () => void;\n /** A server render — the route, or a fragment boundary — dropped the stamps a guess lives by; look for the baseline's guesses again (ADR 0014). */\n readonly restoreGuesses: (transaction: UpdateTransaction, data: PayloadLivePreviewData) => void;\n /** Scroll to the binding this revision marked, if it has not been revealed yet. */\n readonly revealPending: (transaction: UpdateTransaction) => void;\n}\n\nexport interface FragmentPlan {\n readonly boundaries: readonly Element[];\n readonly strategy: FragmentStrategy;\n /** Whether a binding sits inside a boundary the strategy renders this revision. */\n readonly covers: (target: CachedElement) => boolean;\n}\n\nexport class StrategyRunner {\n constructor(\n private readonly deps: RuntimeDeps,\n private readonly state: RuntimeState,\n private readonly host: StrategyHost,\n ) {}\n\n planFragments(touched: ReadonlySet<string>): FragmentPlan | null {\n const strategy = this.deps.strategies.fragment;\n if (strategy === undefined) return null;\n return planBoundaries(strategy, strategy.plan(this.deps.root, touched));\n }\n\n /**\n * Hand the bindings this revision could not patch faithfully to a server:\n * the fragment strategy when a boundary covers every one of them, the route\n * otherwise. All of them or none — a boundary renders its own region, so a\n * finding outside every boundary is only answered by the whole route.\n *\n * A revision that already refreshed the route is left alone: the second\n * request would fetch the bytes the first one just brought.\n */\n escalateUnfaithful(\n transaction: UpdateTransaction,\n data: PayloadLivePreviewData,\n targets: readonly CachedElement[],\n ): void {\n if (transaction.routeRefreshed) return;\n const { fragment, route } = this.deps.strategies;\n const boundaries = fragment === undefined ? undefined : coveringBoundaries(targets);\n if (fragment !== undefined && boundaries !== undefined) {\n this.state.escalatedCount += targets.length;\n transaction.pendingFragments += boundaries.length;\n void this.runFragments(transaction, data, planBoundaries(fragment, boundaries));\n return;\n }\n if (route === undefined) return;\n this.state.escalatedCount += targets.length;\n void this.refreshRoute(transaction, data, route);\n }\n\n /**\n * Whether this revision changed a field the page cannot patch — one with no\n * anchor anywhere, which is also how a section the template renders only\n * under a condition looks from here. The whole route is then the only honest\n * answer.\n *\n * Asked of every revision rather than only where a refresh could follow it,\n * because the finding is the same one under every mode and on a page with no\n * strategy — and that page is what `inspect().fidelity` is read on. What the\n * mode still decides is what is *done*: `'warn'` adds no line of its own\n * (LP0201 already names the field) and `'ignore'` keeps the stale value,\n * exactly as before; only the ledger sees them now.\n *\n * The baseline message is skipped, because there every field counts as\n * changed and the page has just been rendered from them anyway — and so is\n * the re-apply after a refresh, which would otherwise report it all twice.\n */\n hasUnboundChange(transaction: UpdateTransaction, ownerKeys: OwnerScope): boolean {\n const { deps, state } = this;\n if (transaction.baseline || transaction.routeRefreshed) return false;\n const unbound = unboundChangedFields(\n deps.cache,\n transaction.touched,\n transaction.locale,\n ownerKeys,\n );\n let answered = 0;\n for (const fieldName of unbound) if (reportUnboundChange(state, fieldName)) answered += 1;\n const [first] = unbound;\n if (first === undefined || deps.onUnfaithfulPatch !== 'escalate') return false;\n if (deps.strategies.route === undefined) return false;\n deps.log('route', 'LP0807', `field \"${first}\" has no binding; refreshing the route`);\n state.escalatedCount += answered;\n return true;\n }\n\n /** Whether a touched field is bound to an element the route owns. */\n hasRouteBinding(touched: ReadonlySet<string>): boolean {\n for (const [fieldName, bindings] of this.deps.cache.entries()) {\n if (!touched.has(fieldName)) continue;\n if (bindings.some((target) => target.strategyKind === 'route')) return true;\n }\n return false;\n }\n\n async runFragments(\n transaction: UpdateTransaction,\n data: PayloadLivePreviewData,\n plan: FragmentPlan,\n ): Promise<void> {\n const { deps, state } = this;\n const controller = new AbortController();\n state.fragmentController = controller;\n const isCurrent = (): boolean => state.isCurrent(transaction) && !controller.signal.aborted;\n const { emitter } = deps;\n const { message } = transaction;\n const revision = transaction.revision.revision;\n const receivedAt = transaction.receivedAt;\n const context: FragmentContext = {\n root: deps.root,\n revision,\n receivedAt,\n fields: data.fields,\n locale: transaction.locale,\n collectionSlug:\n typeof message.collectionSlug === 'string' ? message.collectionSlug : undefined,\n globalSlug: typeof message.globalSlug === 'string' ? message.globalSlug : undefined,\n signal: controller.signal,\n isCurrent,\n log: (code, detail) => {\n deps.log('fragment', code, detail);\n },\n morph: (boundary, html) => {\n morphFragment(boundary, html);\n },\n patch: (boundary) => {\n this.patchFallback(transaction, data, boundary);\n },\n rendered: (element, id, key) => {\n transaction.pendingFragments -= 1;\n void emitter.emitWhile(\n 'fragmentRender',\n { element, id, key, status: 'rendered', revision, receivedAt },\n isCurrent,\n );\n },\n failed: (element, id, key, code, reason) => {\n transaction.pendingFragments -= 1;\n const detail = `fragment \"${id}\" fell back to patch: ${reason}`;\n // Logged where the failure is, not where an exception would have been:\n // the supplied strategy answers a timeout or a refusal with an outcome\n // and never throws, so the `catch` around `render()` below is not on\n // this path and its LP0801 reached no log sink at all.\n deps.log('fragment', code, detail);\n void emitter.emitWhile(\n 'error',\n { error: new Error(detail), context: 'fragment', code },\n isCurrent,\n );\n void emitter.emitWhile(\n 'fragmentRender',\n { element, id, key, status: 'failed', code, revision, receivedAt },\n isCurrent,\n );\n },\n };\n let report = { rendered: 0, failed: 0, superseded: 0 };\n try {\n report = await plan.strategy.render(context, plan.boundaries);\n } catch (error) {\n deps.log('fragment', 'LP0801', error);\n if (isCurrent()) {\n for (const boundary of plan.boundaries) this.patchFallback(transaction, data, boundary);\n report = { rendered: 0, failed: plan.boundaries.length, superseded: 0 };\n }\n }\n state.fragmentStats.rendered += report.rendered;\n state.fragmentStats.failed += report.failed;\n state.fragmentStats.superseded += report.superseded;\n if (!isCurrent()) return;\n if (state.fragmentController === controller) state.fragmentController = null;\n transaction.pendingFragments = 0;\n // A rendered boundary holds the server's markup, which carries no stamp: the\n // guesses in it go back on, as after a refresh, before the revision counts\n // as complete. Without this a guess in a boundary did not outlive the first\n // message, which renders the boundary as well.\n if (report.rendered > 0) this.host.restoreGuesses(transaction, data);\n if (deps.scheduler.pendingCount === 0) state.complete(transaction);\n // The edited field may be one the server just rendered: its element is only\n // in place now, so this is the earliest point it can be scrolled to.\n this.host.revealPending(transaction);\n if (!isCurrent()) return;\n if (report.rendered === 0 || emitter.listenerCount('afterUpdate') === 0) return;\n void emitter.emitWhile(\n 'afterUpdate',\n {\n data,\n updatedCount: report.rendered,\n durationMs: Date.now() - receivedAt,\n revision,\n receivedAt,\n source: 'fragment',\n },\n isCurrent,\n );\n }\n\n /** Refresh the route once per revision, then re-apply the revision onto the fresh markup. */\n async refreshRoute(\n transaction: UpdateTransaction,\n data: PayloadLivePreviewData,\n strategy: RouteStrategy,\n ): Promise<void> {\n const { deps, state } = this;\n if (transaction.routeRefreshed) {\n state.routeStats.loopStopped += 1;\n deps.log(\n 'route',\n 'LP0805',\n `revision ${String(transaction.revision.revision)} asked for a second refresh`,\n );\n return;\n }\n // A refusal counts as asked as well: the trailing run below is this\n // revision's one refresh, and nothing else may start a second.\n transaction.routeRefreshed = true;\n await this.runRoute(transaction, data, strategy);\n }\n\n /**\n * The trailing run of a refused refresh: the strategy's window closes and the\n * request it held back runs, once. It cannot loop — a refresh re-renders the\n * page from the server and produces no message, so nothing asks again.\n */\n private armRouteRetry(\n transaction: UpdateTransaction,\n data: PayloadLivePreviewData,\n strategy: RouteStrategy,\n delayMs: number,\n ): void {\n const { state } = this;\n if (state.routeRetry !== null) clearTimeout(state.routeRetry);\n state.routeRetry = setTimeout(() => {\n state.routeRetry = null;\n if (!state.isCurrent(transaction)) return;\n void this.runRoute(transaction, data, strategy);\n }, delayMs);\n }\n\n /** One trip through the strategy, whether the revision asked for it or the window did. */\n private async runRoute(\n transaction: UpdateTransaction,\n data: PayloadLivePreviewData,\n strategy: RouteStrategy,\n ): Promise<void> {\n const { deps, state } = this;\n const stats = state.routeStats;\n const controller = new AbortController();\n state.routeController = controller;\n const isCurrent = (): boolean => state.isCurrent(transaction) && !controller.signal.aborted;\n let outcome: RouteOutcome;\n try {\n outcome = await strategy.refresh({\n revision: transaction.revision.revision,\n receivedAt: transaction.receivedAt,\n signal: controller.signal,\n isCurrent,\n log: (code, detail) => {\n deps.log('route', code, detail);\n },\n retryAfter: (delayMs) => {\n this.armRouteRetry(transaction, data, strategy, delayMs);\n },\n });\n } catch (error) {\n deps.log('route', 'LP0801', error);\n outcome = 'failed';\n }\n if (!isCurrent()) return;\n if (state.routeController === controller) state.routeController = null;\n if (outcome === 'refreshed') {\n stats.refreshes += 1;\n // The route rendered the saved document; nothing on the page is \"last applied\" any more.\n state.lastAppliedIdentity = new WeakMap();\n // The fresh markup carries no stamp: the guesses go back on before the\n // cache is rebuilt from it, or the rebuild would not know them.\n this.host.restoreGuesses(transaction, data);\n this.host.rebuildCache();\n if (!isCurrent()) return;\n this.host.reapply(transaction, data);\n if (deps.emitter.listenerCount('afterUpdate') > 0) {\n void deps.emitter.emitWhile(\n 'afterUpdate',\n {\n data,\n // The server re-rendered the whole route, so every binding now on\n // the page carries fresh markup; the unsaved fields scheduled just\n // above report themselves in their own `patch` batch.\n updatedCount: deps.cache.elementCount,\n durationMs: Date.now() - transaction.receivedAt,\n revision: transaction.revision.revision,\n receivedAt: transaction.receivedAt,\n source: 'route',\n },\n isCurrent,\n );\n }\n return;\n }\n // A refusal is a pause, not a breakage; counting the two together is how\n // `failed: 3` came to stand in an inspection where nothing was wrong.\n if (outcome === 'failed') stats.failed += 1;\n else if (outcome === 'refused') stats.refused += 1;\n // Either way the page shows what it can now: the window holds back the\n // server, not the bindings this revision could already have written.\n this.host.reapply(transaction, data);\n }\n\n /** LP0806, once: a fragment boundary with no handler is patched instead. */\n warnFragmentFallback(target: CachedElement): void {\n warnFragmentFallback(this.deps, this.state, target);\n }\n\n /** LP0407, once per element: an unknown strategy is left alone, not guessed at. */\n warnUnsupportedStrategy(target: CachedElement): void {\n warnUnsupportedStrategy(this.deps, this.state, target);\n }\n\n /** The deterministic fallback: patch the boundary's own bindings from the same revision. */\n private patchFallback(\n transaction: UpdateTransaction,\n data: PayloadLivePreviewData,\n boundary: Element,\n ): void {\n for (const [fieldName, bindings] of this.deps.cache.entries()) {\n for (const target of bindings) {\n if (target.fragmentBoundary !== boundary) continue;\n const value = bindingValue(data.fields, target, fieldName, transaction.locale);\n if (value === undefined) continue;\n this.deps.scheduler.schedule({\n target,\n value: this.host.transform(target, value, data.fields, () => true),\n allFields: data.fields,\n revision: transaction.revision,\n data,\n });\n }\n }\n }\n}\n\n/** The distinct boundaries around `targets`, or `undefined` when one sits outside them all. */\nfunction coveringBoundaries(targets: readonly CachedElement[]): Element[] | undefined {\n const boundaries: Element[] = [];\n for (const target of targets) {\n const boundary = target.fragmentBoundary;\n if (boundary === undefined) return undefined;\n if (!boundaries.includes(boundary)) boundaries.push(boundary);\n }\n return boundaries;\n}\n\n/** A plan over boundaries already chosen, whichever question chose them. */\nfunction planBoundaries(strategy: FragmentStrategy, boundaries: readonly Element[]): FragmentPlan {\n const covered = new Set(boundaries);\n return {\n boundaries,\n strategy,\n covers: (target) =>\n target.fragmentBoundary !== undefined && covered.has(target.fragmentBoundary),\n };\n}\n\n/** Morph server-rendered HTML into the boundary, keeping focus and visitor state. */\nfunction morphFragment(boundary: Element, html: string): void {\n const template = boundary.ownerDocument.createElement('template');\n template.innerHTML = trustedHtml(html);\n const rendered = boundary.cloneNode(false) as Element;\n rendered.append(template.content);\n morphElement(boundary, rendered, { keyAttributes: [KEY_ATTRIBUTE] });\n}\n","/**\n * The plugin boundary on a value's way to its binding. Transforms are consumer\n * code: their result is frozen into the scheduler entry, an error is reported\n * as LP0602 and the original value kept, and a thenable is a contract error —\n * a transform that awaits would hand the scheduler a promise to render.\n */\n\nimport type { RuntimeDeps } from './runtime-state';\nimport { observeThenableResult } from './thenable';\nimport type { CachedElement } from './types';\n\n/** Never awaited: every consumer callback may accept a newer revision synchronously (ADR 0004). */\nexport function transformForBinding(\n deps: RuntimeDeps,\n target: CachedElement,\n originalValue: unknown,\n allFields: Record<string, unknown>,\n isCurrent: () => boolean,\n): unknown {\n const transform = deps.transformValue;\n if (transform === undefined) return originalValue;\n try {\n const transformed = transform(\n target.fieldName,\n originalValue,\n { element: target.element, allFields },\n isCurrent,\n );\n const returnedThenable = observeThenableResult(transformed);\n if (!isCurrent()) return originalValue;\n if (returnedThenable) {\n throw new TypeError(\n `Transform for \"${target.fieldName}\" returned a thenable; transforms must be synchronous`,\n );\n }\n return transformed;\n } catch (err) {\n if (!isCurrent()) return originalValue;\n const error = err instanceof Error ? err : new Error(String(err));\n void deps.emitter.emit('error', { error, context: 'transform', code: 'LP0602' });\n return originalValue;\n }\n}\n","/**\n * From an accepted message to scheduled writes: merge, diff, plan the\n * strategies, schedule each binding, and finish the revision on flush.\n */\n\nimport type { PayloadLivePreviewData, PayloadLivePreviewMessage } from '@/types/payload-protocol';\nimport { buildSchemaIndex } from '@schema/index';\nimport { adoptUniqueBindings, restoreUniqueBindings } from './auto-bind';\nimport { isBindingInScope, messageOwnerKeys, readDocumentId } from './binding-owner';\nimport type { MergeResult } from './data-merger';\nimport { mergeDependencyMaps } from './dependencies';\nimport { bindingIdentity, bindingValue } from './field-value';\nimport { dispatchIslandUpdate } from './islands';\nimport { type MessageRevision, sameRevision } from './message-bus';\nimport { diagnoseOrphanFields } from './orphan-diagnostics';\nimport { reportOmittedFeature } from './profile';\nimport { detectProtocolProfile } from './protocol-profile';\nimport { observeCapabilities } from './protocol-version';\nimport { owesForceRender } from './relationship-tracker';\nimport type { RevealWindow } from './reveal';\nimport { type RuntimeDeps, type RuntimeState, type UpdateTransaction } from './runtime-state';\nimport { resolveStrategy } from './strategies';\nimport { StrategyRunner } from './strategy-runner';\nimport { createLeanStrategyRunner, type StrategyRunnerLike } from './strategy-runner-lean';\nimport { transformForBinding } from './transform-value';\nimport type { CachedElement } from './types';\nimport type { FlushStats, ScheduledUpdate } from './update-scheduler';\n\n/** A refinement moved no field: it completes values the revision already applied. */\nconst NOTHING_CHANGED: ReadonlySet<string> = new Set();\n\nexport class UpdatePipeline {\n private readonly strategies: StrategyRunnerLike;\n\n constructor(\n private readonly deps: RuntimeDeps,\n private readonly state: RuntimeState,\n rebuildCache: () => void,\n ) {\n // The profile decides, and esbuild folds the branch: the lean build drops\n // the real runner and everything only it reached — the morph, the fragment\n // client's server half, the route refresh (./profile, build-flags.d.ts).\n this.strategies =\n typeof __LEAN_BUILD__ !== 'undefined' && __LEAN_BUILD__\n ? createLeanStrategyRunner(deps, state)\n : new StrategyRunner(deps, state, {\n reapply: (transaction, data) => {\n this.scheduleAllFields(transaction, data);\n },\n transform: (target, value, allFields, isCurrent) =>\n transformForBinding(deps, target, value, allFields, isCurrent),\n rebuildCache,\n restoreGuesses: (transaction, data) => {\n this.restoreGuesses(transaction, data);\n },\n revealPending: (transaction) => {\n this.revealPending(transaction);\n },\n });\n }\n\n /** Message-bus callback for every shape-valid update. */\n handleUpdate(\n message: PayloadLivePreviewMessage,\n origin: string,\n revision: MessageRevision | undefined,\n ): void {\n const { deps, state } = this;\n deps.heartbeat.kick();\n state.protocol.observe(observeCapabilities(message), deps.log);\n if (message.data === undefined) {\n if (message.protocolVersion !== undefined) {\n state.protocol.applyVersion(message.protocolVersion, deps.log);\n }\n return;\n }\n if (revision === undefined) return;\n // A level, not an edge: the panel repeats its last document event in every\n // message and never clears it, so only a changed event about a document\n // other than this one is news (LP-1).\n const relationshipEdit = state.relationships.edit(message);\n if (relationshipEdit !== null) {\n void deps.emitter.emit('relationshipUpdate', {\n detail: relationshipEdit,\n timestamp: Date.now(),\n });\n }\n if (typeof message.locale === 'string') state.locale = message.locale;\n if (Array.isArray(message.fieldSchemaJSON)) {\n state.schema = message.fieldSchemaJSON;\n state.schemaIndex = buildSchemaIndex(message.fieldSchemaJSON);\n }\n const transaction: UpdateTransaction = {\n revision,\n message,\n locale: state.locale,\n schema: state.schema,\n schemaIndex: state.schemaIndex,\n receivedAt: Date.now(),\n forceRender: relationshipEdit !== null || owesForceRender(state.activeUpdate),\n touched: new Set(),\n baseline: false,\n invalidated: new Set(),\n revealTarget: undefined,\n revealIdentities: [],\n pendingFragments: 0,\n routeRefreshed: false,\n cancelled: false,\n completed: false,\n };\n // Acceptance is the single supersession point. Only a revision that never\n // reached its terminal state counts as superseded.\n const previous = state.activeUpdate;\n state.abortStrategies();\n if (previous !== null && !previous.completed) state.supersededCount += 1;\n state.activeUpdate = transaction;\n deps.scheduler.acceptRevision(revision);\n state.updateCount += 1;\n if (message.protocolVersion !== undefined) {\n state.protocol.applyVersion(message.protocolVersion, deps.log);\n if (!state.isCurrent(transaction)) return;\n }\n if (deps.connection.markConnected()) {\n deps.a11y?.announceConnected();\n void deps.emitter.emit('connect', { origin, timestamp: Date.now() });\n if (!state.isCurrent(transaction)) return;\n deps.log('connection', 'disconnected', '→', 'connected');\n if (!state.isCurrent(transaction)) return;\n }\n // Nothing awaits this, so an unexpected throw would leave the page as an\n // unhandled rejection — a console error the host cannot attribute, and a\n // process exit under `--unhandled-rejections=strict`.\n void this.processUpdate(transaction).catch((error: unknown) => {\n deps.log('update failed:', error);\n });\n }\n\n private async processUpdate(transaction: UpdateTransaction): Promise<void> {\n const { deps, state } = this;\n const fields = await this.resolveIncomingFields(transaction);\n if (fields === null || !state.isCurrent(transaction)) return;\n const data = this.dataFor(transaction, fields);\n if (deps.emitter.listenerCount('beforeUpdate') > 0) {\n const completed = await deps.emitter.emitWhile(\n 'beforeUpdate',\n {\n data,\n revision: transaction.revision.revision,\n receivedAt: transaction.receivedAt,\n source: 'patch',\n cancel: (): void => {\n transaction.cancelled = true;\n deps.scheduler.cancelRevision(transaction.revision);\n },\n },\n () => !transaction.cancelled && state.isCurrent(transaction),\n );\n if (!completed || transaction.cancelled || !state.isCurrent(transaction)) return;\n }\n this.applyFields(transaction, data, false);\n }\n\n private dataFor(\n transaction: UpdateTransaction,\n fields: Record<string, unknown>,\n ): PayloadLivePreviewData {\n const { message } = transaction;\n return {\n fields,\n ...(transaction.schema !== undefined ? { schema: transaction.schema } : {}),\n ...(typeof message.globalSlug === 'string' ? { globalSlug: message.globalSlug } : {}),\n ...(typeof message.collectionSlug === 'string'\n ? { collectionSlug: message.collectionSlug }\n : {}),\n ...(transaction.locale !== undefined ? { locale: transaction.locale } : {}),\n };\n }\n\n /**\n * Diff against what the page last showed, then schedule. A refinement is the\n * populated answer to values this revision already applied: it keeps the diff\n * in step without letting population count as an edit, because no strategy\n * may be planned a second time for one message.\n */\n private applyFields(\n transaction: UpdateTransaction,\n data: PayloadLivePreviewData,\n refined: boolean,\n ): void {\n const { deps, state } = this;\n const dependencies = mergeDependencyMaps(deps.dependencies, deps.cache.dependencyMap());\n const changes = state.changes.diff(data.fields, dependencies);\n if (changes.baseline && !refined && deps.autoBind !== 'off') {\n // Once, on the message that describes what the server rendered (ADR 0014\n // §1). The lean profile leaves the search out; esbuild folds the branch.\n if (typeof __LEAN_BUILD__ !== 'undefined' && __LEAN_BUILD__) {\n reportOmittedFeature('auto-binding');\n } else {\n const scope = this.ownerKeysForUpdate(transaction, data.fields);\n adoptUniqueBindings(deps, state, data.fields, transaction.locale, scope);\n }\n }\n transaction.baseline = changes.baseline;\n transaction.invalidated = refined ? NOTHING_CHANGED : changes.invalidated;\n transaction.touched = refined\n ? NOTHING_CHANGED\n : new Set([...changes.changed, ...changes.invalidated]);\n this.scheduleAllFields(transaction, data);\n }\n\n /** The document to render: merged when the server has something to add, else the message's own values; `null` when superseded. */\n private async resolveIncomingFields(\n transaction: UpdateTransaction,\n ): Promise<Record<string, unknown> | null> {\n const { deps, state } = this;\n const raw = transaction.message.data ?? {};\n if (deps.merger === null) return raw;\n // A Payload 2.x admin posts populated relationships itself.\n if (detectProtocolProfile(state.protocol.observed).populatesRelationships === 'admin') {\n return raw;\n }\n const plan = state.merges.decide(deps, transaction);\n if (!plan.merge) return plan.fields;\n const { message } = transaction;\n const coalesced = state.merges.request(deps.merger, deps.mergeWindowMs, {\n collectionSlug: message.collectionSlug,\n globalSlug: message.globalSlug,\n data: raw,\n locale: transaction.locale,\n });\n // A request the burst shares is not one the page waits for: it renders what\n // it already has, and the answer refines it when the window closes.\n if (!coalesced.leading) {\n void this.applyMerged(transaction, coalesced.result).catch((error: unknown) => {\n deps.log('update failed:', error);\n });\n return plan.fields;\n }\n const result = await coalesced.result;\n if (!state.isCurrent(transaction)) return null;\n if (result.status === 'merged') {\n state.merges.recordMerged(result.doc);\n return result.doc;\n }\n if (result.status === 'superseded') return null;\n return plan.fields;\n }\n\n /** Whoever is still current when the shared merge lands gets the populated document. */\n private async applyMerged(\n transaction: UpdateTransaction,\n pending: Promise<MergeResult>,\n ): Promise<void> {\n const { state } = this;\n const result = await pending;\n if (result.status !== 'merged' || !state.isCurrent(transaction)) return;\n state.merges.recordMerged(result.doc);\n this.applyFields(transaction, this.dataFor(transaction, result.doc), true);\n }\n\n scheduleAllFields(transaction: UpdateTransaction, data: PayloadLivePreviewData): void {\n const { deps, state } = this;\n if (!state.isCurrent(transaction)) return;\n const isCurrent = (): boolean => state.isCurrent(transaction);\n const ownerKeys = this.ownerKeysForUpdate(transaction, data.fields);\n const { touched } = transaction;\n // A revision that touches the route refreshes it first; the re-apply lands on the fresh markup.\n const route = deps.strategies.route;\n const unbound = this.strategies.hasUnboundChange(transaction, ownerKeys);\n // The refresh an older revision was refused and this one took over: owed\n // whatever this revision's own diff says, and settled by the run below. A\n // baseline never carries it: the debt needs a refresh before it, which the\n // baseline itself never plans.\n const owed = state.routeRefreshOwed;\n if (\n route !== undefined &&\n !transaction.routeRefreshed &&\n (unbound ||\n owed ||\n route.plan(deps.root, touched) ||\n this.strategies.hasRouteBinding(touched))\n ) {\n state.routeRefreshOwed = false;\n void this.strategies.refreshRoute(transaction, data, route);\n return;\n }\n const plan = this.strategies.planFragments(touched);\n // Only `skipUnchanged` needs it now; the reveal keeps its own ledger.\n const trackIdentity = deps.skipUnchanged;\n let scheduled = 0;\n for (const [fieldName, bindings] of deps.cache.entries()) {\n if (!isCurrent()) return;\n for (const target of bindings) {\n if (ownerKeys !== false && !isBindingInScope(target.owner, ownerKeys)) continue;\n // A binding inside a boundary the server renders is patched only as the\n // fallback — but it can still be the field being edited, so the reveal\n // has to notice it here, before the boundary is re-rendered.\n if (plan?.covers(target) === true) {\n // Resolving the value is only worth it when something reveals.\n if (deps.revealEditedField) {\n const raw = bindingValue(data.fields, target, fieldName, transaction.locale);\n state.revealLedger.note(transaction, target, raw);\n }\n continue;\n }\n const kind = target.strategyKind ?? resolveStrategy(target.element) ?? 'unknown';\n if (kind === 'unknown') {\n this.strategies.warnUnsupportedStrategy(target);\n continue;\n }\n if (kind === 'fragment' && plan === null) this.strategies.warnFragmentFallback(target);\n const value = bindingValue(data.fields, target, fieldName, transaction.locale);\n if (value === undefined) {\n state.absentFields.add(fieldName);\n continue;\n }\n // Noted before `skipUnchanged` can skip the write: the reveal ledger is\n // its own record, and a binding whose write is unchanged since the last\n // one that landed may still be the field whose reveal was superseded.\n if (deps.revealEditedField) state.revealLedger.note(transaction, target, value);\n if (!isCurrent()) return;\n const transformed = transformForBinding(deps, target, value, data.fields, isCurrent);\n if (!isCurrent()) return;\n // A binding renders its own value *and* the sibling fields bound to\n // href/src/alt, so its identity must cover them: otherwise an edit to\n // the sibling alone looks unchanged and the link or image stays stale.\n const identity = trackIdentity\n ? bindingIdentity(target, transformed, data.fields, transaction.locale)\n : undefined;\n const last = state.lastAppliedIdentity.get(target.element);\n if (\n !transaction.forceRender &&\n deps.skipUnchanged &&\n identity !== undefined &&\n last === identity &&\n !transaction.invalidated.has(fieldName)\n ) {\n state.skippedUnchangedCount += 1;\n continue;\n }\n const update: ScheduledUpdate = {\n target,\n value: transformed,\n allFields: data.fields,\n revision: transaction.revision,\n data,\n valueIdentity: identity,\n };\n deps.scheduler.schedule(update);\n scheduled += 1;\n }\n }\n diagnoseOrphanFields(\n { cache: deps.cache, warned: state.warnedOrphanFields, warn: deps.warn },\n data.fields,\n transaction.locale,\n ownerKeys,\n );\n if (plan !== null && plan.boundaries.length > 0) {\n transaction.pendingFragments = plan.boundaries.length;\n void this.strategies.runFragments(transaction, data, plan);\n }\n // Nothing to flush is still this revision reaching its end — and its reveal\n // point: every write may be unchanged while the reveal is still owed. The\n // islands still hear it: a page whose bindings all sit inside them schedules\n // nothing, and the event is how they learn of the edit at all.\n if (scheduled === 0 && transaction.pendingFragments === 0) {\n state.complete(transaction);\n this.revealPending(transaction);\n this.notifyIslands(transaction, data);\n }\n }\n\n /** Islands hear every revision that carried a change, whether or not a write landed outside them. */\n private notifyIslands(transaction: UpdateTransaction, data: PayloadLivePreviewData): void {\n if (transaction.touched.size === 0) return;\n dispatchIslandUpdate(this.deps.cache.islands, {\n fields: data.fields,\n revision: transaction.revision.revision,\n receivedAt: transaction.receivedAt,\n locale: transaction.locale,\n });\n }\n\n /**\n * A server render — the route, or a fragment boundary — replaced markup\n * without the stamps a guess lives by; look for the baseline's guesses\n * again, and for nothing else (ADR 0014).\n */\n private restoreGuesses(transaction: UpdateTransaction, data: PayloadLivePreviewData): void {\n const { deps, state } = this;\n if (deps.autoBind === 'off' || state.autoBindGuesses === null) return;\n // Nothing reaches this in the lean build, which renders no route and no\n // fragment. A folded branch, not an early return: esbuild drops the branch\n // before linking and a statement after `return` only after it, and the\n // search's module was in the lean artifact until the guard took this shape.\n if (!(typeof __LEAN_BUILD__ !== 'undefined' && __LEAN_BUILD__)) {\n const scope = this.ownerKeysForUpdate(transaction, data.fields);\n restoreUniqueBindings(deps, state, data.fields, transaction.locale, scope);\n }\n }\n\n /** Owner keys this update may address; `false` when scoping is off, `null` when the message names no document. */\n private ownerKeysForUpdate(\n transaction: UpdateTransaction,\n fields: Record<string, unknown>,\n ): readonly string[] | null | false {\n const { deps, state } = this;\n if (!deps.scopeBindingsByOwner) return false;\n const { message } = transaction;\n const keys = messageOwnerKeys({\n globalSlug: typeof message.globalSlug === 'string' ? message.globalSlug : undefined,\n collectionSlug:\n typeof message.collectionSlug === 'string' ? message.collectionSlug : undefined,\n documentId: readDocumentId(fields),\n });\n if (keys === null && !state.warnedUnattributableMessage) {\n state.warnedUnattributableMessage = true;\n deps.warn(\n '[live-preview] LP0202: scopeBindingsByOwner: update names no document; nothing applied',\n );\n }\n return keys;\n }\n\n /** Scheduler callback after every flush, including one that applied nothing. */\n onFlush(stats: FlushStats): void {\n const { deps, state } = this;\n state.lastFlush = stats;\n if (stats.deferred > 0 && !state.warnedVisibilityGate) {\n state.warnedVisibilityGate = true;\n deps.warn(\n `[live-preview] LP0301: visibility gate held ${String(stats.deferred)} off-screen update(s) until scrolled into view; see visibilityGateThreshold`,\n );\n }\n const { revision, data } = stats;\n if (revision === undefined) return;\n const transaction = state.activeUpdate;\n if (\n transaction === null ||\n !state.isCurrent(transaction) ||\n !sameRevision(transaction.revision, revision)\n ) {\n return;\n }\n if (transaction.pendingFragments === 0) state.complete(transaction);\n const isCurrent = (): boolean =>\n state.isCurrent(transaction) && sameRevision(transaction.revision, revision);\n // Reveal before the applied check: the edited element may be exactly the\n // off-screen one the visibility gate deferred, and scrolling to it is what replays it.\n this.revealPending(transaction);\n if (!isCurrent()) return;\n // Before the applied check, because a flush that applied nothing is exactly\n // the one whose every renderer refused its value.\n const unfaithful = state.unfaithfulPatches;\n if (unfaithful.length > 0) {\n state.unfaithfulPatches = [];\n if (data !== undefined) this.strategies.escalateUnfaithful(transaction, data, unfaithful);\n if (!isCurrent()) return;\n }\n if (data === undefined) return;\n if (stats.applied > 0) deps.a11y?.announceUpdate(stats.applied);\n if (!isCurrent()) return;\n // With `skipUnchanged` a field only an island shows writes nothing here,\n // and the island must still hear about it.\n this.notifyIslands(transaction, data);\n if (!isCurrent() || stats.applied === 0 || deps.emitter.listenerCount('afterUpdate') === 0) {\n return;\n }\n void deps.emitter.emitWhile(\n 'afterUpdate',\n {\n data,\n updatedCount: stats.applied,\n durationMs: stats.durationMs,\n revision: revision.revision,\n receivedAt: transaction.receivedAt,\n source: 'patch',\n },\n isCurrent,\n );\n }\n\n /**\n * Reveal the binding this revision marked, once. Called from the patch flush\n * and again once fragments land, because only one of the two runs for any\n * given field, and a fragment-rendered element is in place only afterwards.\n */\n revealPending(transaction: UpdateTransaction): void {\n const target = this.state.revealLedger.commit(transaction);\n if (target === undefined) return;\n try {\n this.revealBinding(target);\n } catch (error) {\n this.deps.log('reveal', error);\n }\n }\n\n /**\n * Scroll one field's bound element into view; the admin-focus path (tier 2)\n * names a field, so it takes the first binding — a focus message carries no\n * document identity to choose between several.\n */\n revealField(fieldName: string): 'revealed' | 'already-visible' | 'skipped-same' | 'no-element' {\n const target = this.deps.cache.get(fieldName)?.[0];\n if (target === undefined) return 'no-element';\n return this.revealBinding(target);\n }\n\n private revealBinding(\n target: CachedElement,\n ): 'revealed' | 'already-visible' | 'skipped-same' | 'no-element' {\n const { element } = target;\n const win = element.ownerDocument.defaultView as RevealWindow | null;\n if (win === null) return 'no-element';\n // Keyed by document as well as field: two documents on one page have their\n // own `title`, and revealing one must not count as revealing the other.\n const key = `${target.owner ?? ''} ${target.fieldName}`;\n return this.state.revealer.reveal(key, element, win);\n }\n}\n","/**\n * The strategy runner the lean profile gets instead of the real one: it plans\n * nothing, renders nothing, and says so once per feature (LP0104). Its purpose\n * is that the pipeline needs no branch of its own — it holds a runner either\n * way, and the profile decides which.\n *\n * Because this module names the real runner only as a type, the lean build\n * drops that file and everything only it referenced: the morph, the fragment\n * protocol client's server half, and the route refresh.\n */\n\nimport { reportUnboundChange } from './fidelity';\nimport { reportOmittedFeature } from './profile';\nimport type { StrategyRunner } from './strategy-runner';\nimport { warnFragmentFallback, warnUnsupportedStrategy } from './strategy-warnings';\nimport type { RuntimeDeps, RuntimeState, UpdateTransaction } from './runtime-state';\nimport { unboundChangedFields, type OwnerScope } from './unbound-fields';\nimport type { CachedElement } from './types';\n\n/** What `UpdatePipeline` calls on a runner; both profiles satisfy it. */\nexport type StrategyRunnerLike = Pick<\n StrategyRunner,\n | 'planFragments'\n | 'escalateUnfaithful'\n | 'hasUnboundChange'\n | 'hasRouteBinding'\n | 'runFragments'\n | 'refreshRoute'\n | 'warnFragmentFallback'\n | 'warnUnsupportedStrategy'\n>;\n\nexport function createLeanStrategyRunner(\n deps: RuntimeDeps,\n state: RuntimeState,\n): StrategyRunnerLike {\n return {\n planFragments: (): null => null,\n // Nothing to escalate to. The pipeline still drains its queue, so a page\n // that keeps producing findings does not keep producing entries.\n escalateUnfaithful: (): void => undefined,\n // Nothing here to escalate to, and the finding is still worth recording:\n // a page that changes a field it does not bind is the page\n // `inspect().fidelity` is read on, and `escalated` staying 0 beside it is\n // the truth about this profile rather than silence about the change.\n hasUnboundChange: (transaction: UpdateTransaction, ownerKeys: OwnerScope): boolean => {\n if (transaction.baseline) return false;\n const unbound = unboundChangedFields(\n deps.cache,\n transaction.touched,\n transaction.locale,\n ownerKeys,\n );\n for (const fieldName of unbound) reportUnboundChange(state, fieldName);\n return false;\n },\n hasRouteBinding: (): boolean => false,\n runFragments: (): Promise<void> => Promise.resolve(),\n // A page that carries a route prelude anyway (it can be injected by hand)\n // still gets no refresh here: this runtime has no code for one.\n refreshRoute: (): Promise<void> => {\n reportOmittedFeature('route refreshes');\n return Promise.resolve();\n },\n warnFragmentFallback: (target: CachedElement): void => {\n reportOmittedFeature('server-rendered fragments');\n warnFragmentFallback(deps, state, target);\n },\n warnUnsupportedStrategy: (target: CachedElement): void => {\n warnUnsupportedStrategy(deps, state, target);\n },\n };\n}\n","/**\n * Debounce, frame batching and off-screen replay for scheduled writes. The\n * first write of a quiet phase does not wait for the window: it goes out on the\n * next frame and opens the window that batches the rest of the burst, so an\n * isolated keystroke costs a frame instead of a whole debounce. The scheduler\n * never touches the DOM; the injected `apply` callback does.\n */\n\nimport type { PayloadLivePreviewData } from '@/types/payload-protocol';\nimport { usesNoWriteOutcome } from './internal-outcome';\nimport { type MessageRevision, sameRevision } from './message-bus';\nimport type { CachedElement } from './types';\n\nexport interface ScheduledUpdate {\n readonly target: CachedElement;\n readonly value: unknown;\n readonly allFields: Record<string, unknown>;\n /** Revision revision; runtime-produced entries always carry one. */\n readonly revision?: MessageRevision | undefined;\n readonly data?: PayloadLivePreviewData | undefined;\n /** `valueIdentity(value)`, computed once by the pipeline for skip and reveal. */\n readonly valueIdentity?: string | undefined;\n}\n\nexport type ApplyUpdate = (update: ScheduledUpdate) => void;\n\nexport interface UpdateSchedulerOptions {\n /** Debounce window in ms; the write that opens it does not wait for it. Default 50. */\n readonly debounceMs?: number;\n /** Longest a flush may be postponed by continuous scheduling. Default `4 * debounceMs`. */\n readonly maxWaitMs?: number;\n /** Deferred writes replay when the host reports the element visible via `notifyVisible()`. */\n readonly isVisible: (element: Element) => boolean;\n /** Apply every write immediately regardless of visibility. Default `false`. */\n readonly disableVisibilityGate?: boolean;\n /** Cached-element count above which the gate activates. Default 50. */\n readonly visibilityGateThreshold?: number;\n readonly getCacheSize: () => number;\n readonly onFlush?: (stats: FlushStats) => void;\n /** Frame scheduler; defaults to `requestAnimationFrame`. Tests inject a synchronous one. */\n readonly scheduleFrame?: (callback: FrameRequestCallback) => number;\n readonly cancelFrame?: (handle: number) => void;\n}\n\nexport interface FlushStats {\n readonly applied: number;\n /** Field names applied, in order; `applied` alone cannot say which binding stayed stale. */\n readonly appliedFields: readonly string[];\n readonly deferred: number;\n readonly durationMs: number;\n readonly revision?: MessageRevision;\n readonly data?: PayloadLivePreviewData;\n}\n\n/** Exported so the merge behind a burst of writes can share the window that batches them. */\nexport const DEFAULT_DEBOUNCE_MS = 50;\n/** Exported so `pll doctor` can prove its own copy of the number has not drifted. */\nexport const DEFAULT_VISIBILITY_THRESHOLD = 50;\n\ninterface BufferEntry {\n target: CachedElement;\n value: unknown;\n allFields: Record<string, unknown>;\n revision: MessageRevision | undefined;\n data: PayloadLivePreviewData | undefined;\n valueIdentity: string | undefined;\n}\n\nexport class UpdateScheduler {\n private readonly apply: ApplyUpdate;\n private readonly debounceMs: number;\n private readonly maxWaitMs: number;\n private readonly isVisible: (element: Element) => boolean;\n private readonly gateThresholdValue: number;\n private readonly gateDisabled: boolean;\n private readonly getCacheSize: () => number;\n private readonly onFlush: ((stats: FlushStats) => void) | undefined;\n private readonly scheduleFrame: (callback: FrameRequestCallback) => number;\n private readonly cancelFrame: (handle: number) => void;\n private pending = new Map<Element, BufferEntry>();\n private readonly replay = new Map<Element, BufferEntry>();\n private readonly activeFlushes = new Set<Map<Element, BufferEntry>>();\n private debounceTimer: ReturnType<typeof setTimeout> | null = null;\n private debounceToken = 0;\n private deadlineTimer: ReturnType<typeof setTimeout> | null = null;\n private frameHandle: number | null = null;\n private frameToken = 0;\n /** End of the window the leading write opened; inside it a write waits for the debounce. */\n private windowUntil = 0;\n private activeRevision: MessageRevision | null = null;\n private activeRevisionCancelled = false;\n\n constructor(apply: ApplyUpdate, options: UpdateSchedulerOptions) {\n this.apply = apply;\n this.debounceMs = options.debounceMs ?? DEFAULT_DEBOUNCE_MS;\n this.maxWaitMs = options.maxWaitMs ?? this.debounceMs * 4;\n this.isVisible = options.isVisible;\n this.gateThresholdValue = options.visibilityGateThreshold ?? DEFAULT_VISIBILITY_THRESHOLD;\n this.gateDisabled = options.disableVisibilityGate ?? false;\n this.getCacheSize = options.getCacheSize;\n this.onFlush = options.onFlush;\n this.scheduleFrame =\n options.scheduleFrame ??\n (typeof requestAnimationFrame === 'function'\n ? requestAnimationFrame.bind(globalThis)\n : (callback) =>\n setTimeout(() => {\n callback(performance.now());\n }, 0) as unknown as number);\n this.cancelFrame =\n options.cancelFrame ??\n (typeof cancelAnimationFrame === 'function'\n ? cancelAnimationFrame.bind(globalThis)\n : (handle) => {\n clearTimeout(handle as unknown as ReturnType<typeof setTimeout>);\n });\n }\n\n /** Queue a write; a later write for the same element replaces it until the flush. */\n schedule(update: ScheduledUpdate): void {\n if (update.revision !== undefined) {\n if (this.activeRevisionCancelled) return;\n if (this.activeRevision === null || !sameRevision(update.revision, this.activeRevision)) {\n return;\n }\n }\n const existing = this.pending.get(update.target.element);\n if (existing) {\n existing.value = update.value;\n existing.allFields = update.allFields;\n existing.revision = update.revision;\n existing.data = update.data;\n existing.valueIdentity = update.valueIdentity;\n } else {\n this.pending.set(update.target.element, {\n target: update.target,\n value: update.value,\n allFields: update.allFields,\n revision: update.revision,\n data: update.data,\n valueIdentity: update.valueIdentity,\n });\n }\n this.armDebounce();\n }\n\n /**\n * Make `revision` the sole revision allowed to schedule, flush or replay.\n * Older buffered work is dropped even if the new revision is later cancelled.\n */\n acceptRevision(revision: MessageRevision): void {\n if (this.activeRevision !== null && sameRevision(revision, this.activeRevision)) return;\n if (this.activeRevision !== null && compareRevision(revision, this.activeRevision) < 0) return;\n this.cancelScheduledWork();\n this.clearWork();\n this.activeRevision = revision;\n this.activeRevisionCancelled = false;\n }\n\n /** Cancel buffered work for exactly one revision without reviving its predecessor. */\n cancelRevision(revision: MessageRevision): void {\n if (this.activeRevision === null || !sameRevision(revision, this.activeRevision)) return;\n this.cancelScheduledWork();\n this.clearWork();\n this.activeRevisionCancelled = true;\n }\n\n /** Flush immediately, bypassing the debounce. */\n flushNow(): FlushStats {\n this.cancelScheduledWork();\n return this.flush();\n }\n\n /** Apply the buffered value for an element that scrolled into view. */\n notifyVisible(element: Element): void {\n const entry = this.replay.get(element);\n if (!entry) return;\n this.replay.delete(element);\n if (!this.isCurrent(entry)) return;\n const t0 = performance.now();\n const applied = this.didApply(entry) ? 1 : 0;\n this.onFlush?.(\n this.statsFor(\n entry,\n applied,\n 0,\n performance.now() - t0,\n applied === 1 ? [entry.target.fieldName] : [],\n ),\n );\n }\n\n /**\n * Point buffered work at a rebuilt cache entry for the same element and\n * field. A different field or locale is a different binding: drop the work.\n */\n retarget(target: CachedElement): void {\n this.retargetBuffer(this.pending, target);\n this.retargetBuffer(this.replay, target);\n for (const flush of this.activeFlushes) this.retargetBuffer(flush, target);\n }\n\n forget(element: Element): void {\n this.pending.delete(element);\n this.replay.delete(element);\n for (const flush of this.activeFlushes) flush.delete(element);\n }\n\n /** Cancel timers and drop buffered state without draining it. */\n destroy(): void {\n this.cancelScheduledWork();\n this.clearWork();\n this.activeRevision = null;\n this.activeRevisionCancelled = false;\n // A restarted scheduler is a quiet page again, not the tail of a burst.\n this.windowUntil = 0;\n }\n\n get pendingCount(): number {\n return this.pending.size;\n }\n\n get replayCount(): number {\n return this.replay.size;\n }\n\n get gateThreshold(): number {\n return this.gateThresholdValue;\n }\n\n get gateActive(): boolean {\n return !this.gateDisabled && this.getCacheSize() > this.gateThresholdValue;\n }\n\n private armDebounce(): void {\n const now = Date.now();\n const opensTheWindow = now >= this.windowUntil;\n this.windowUntil = now + this.debounceMs;\n // The debounce coalesces a burst, and the write that opens one is not yet a\n // burst: it costs a frame, and the window it opens batches what follows.\n // With the merge gone from the common path (see `MergeNeed`), that frame is\n // the whole distance between a keystroke and the page.\n if (opensTheWindow) {\n this.requestFrame();\n return;\n }\n const token = (this.debounceToken += 1);\n const timer = this.debounceTimer;\n this.debounceTimer = null;\n if (timer !== null) clearTimeout(timer);\n // clearTimeout is a host boundary; a reentrant schedule owns a newer token.\n if (this.debounceToken !== token) return;\n const next = setTimeout(() => {\n if (this.debounceToken !== token) return;\n this.debounceTimer = null;\n // The window a leading write opened is usually already empty when it\n // closes; flushing then would report a write nobody made.\n if (this.pending.size > 0) this.requestFrame();\n }, this.debounceMs);\n if (this.debounceToken === token) this.debounceTimer = next;\n // Continuous scheduling (key repeat) must not postpone the flush forever.\n if (this.deadlineTimer === null && this.maxWaitMs > this.debounceMs) {\n this.deadlineTimer = setTimeout(() => {\n this.deadlineTimer = null;\n if (this.pending.size > 0) this.requestFrame();\n }, this.maxWaitMs);\n }\n }\n\n private requestFrame(): void {\n const token = (this.frameToken += 1);\n const handle = this.frameHandle;\n this.frameHandle = null;\n if (handle !== null) this.cancelFrame(handle);\n if (this.frameToken !== token) return;\n let completed = false;\n const next = this.scheduleFrame(() => {\n if (this.frameToken !== token) return;\n completed = true;\n this.frameHandle = null;\n this.flush();\n });\n // An injected scheduler may run the callback synchronously; never publish a spent handle.\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n if (!completed && this.frameToken === token) this.frameHandle = next;\n }\n\n private flush(): FlushStats {\n const t0 = performance.now();\n this.clearDeadline();\n const gateActive = this.gateActive;\n const pending = this.pending;\n this.pending = new Map();\n let applied = 0;\n const appliedFields: string[] = [];\n let deferred = 0;\n let batchEntry: BufferEntry | undefined;\n this.activeFlushes.add(pending);\n try {\n for (const entry of pending.values()) {\n if (!this.isCurrent(entry)) continue;\n const visible = !gateActive || this.isVisible(entry.target.element);\n // The visibility callback is consumer code and may change the revision.\n if (!this.isCurrent(entry)) continue;\n batchEntry ??= entry;\n if (!visible) {\n this.replay.set(entry.target.element, entry);\n deferred += 1;\n continue;\n }\n this.replay.delete(entry.target.element);\n if (this.didApply(entry)) {\n applied += 1;\n appliedFields.push(entry.target.fieldName);\n }\n }\n } finally {\n this.activeFlushes.delete(pending);\n }\n const stats = this.statsFor(\n batchEntry,\n applied,\n deferred,\n performance.now() - t0,\n appliedFields,\n );\n this.onFlush?.(stats);\n return stats;\n }\n\n private isCurrent(entry: BufferEntry): boolean {\n return (\n entry.revision === undefined ||\n (!this.activeRevisionCancelled &&\n this.activeRevision !== null &&\n sameRevision(entry.revision, this.activeRevision))\n );\n }\n\n private didApply(entry: BufferEntry): boolean {\n // Only a runtime-marked callback may report exact `false` as \"no write\".\n // eslint-disable-next-line @typescript-eslint/no-confusing-void-expression\n const outcome: unknown = this.apply(entry);\n return outcome !== false || !usesNoWriteOutcome(this.apply);\n }\n\n private retargetBuffer(buffer: Map<Element, BufferEntry>, target: CachedElement): void {\n const entry = buffer.get(target.element);\n if (entry === undefined) return;\n if (entry.target.fieldName !== target.fieldName || entry.target.locale !== target.locale) {\n buffer.delete(target.element);\n return;\n }\n entry.target = target;\n }\n\n private clearWork(): void {\n this.pending.clear();\n this.replay.clear();\n for (const flush of this.activeFlushes) flush.clear();\n }\n\n private statsFor(\n entry: BufferEntry | undefined,\n applied: number,\n deferred: number,\n durationMs: number,\n appliedFields: readonly string[],\n ): FlushStats {\n return {\n applied,\n appliedFields,\n deferred,\n durationMs,\n ...(entry?.revision !== undefined ? { revision: entry.revision } : {}),\n ...(entry?.data !== undefined ? { data: entry.data } : {}),\n };\n }\n\n private clearDeadline(): void {\n if (this.deadlineTimer === null) return;\n clearTimeout(this.deadlineTimer);\n this.deadlineTimer = null;\n }\n\n private cancelScheduledWork(): void {\n const debounceTimer = this.debounceTimer;\n const frameHandle = this.frameHandle;\n // Revoke tokens before calling host cancellation, so a hook that\n // schedules newer work is not clobbered by this older cleanup.\n this.debounceToken += 1;\n this.frameToken += 1;\n this.debounceTimer = null;\n this.frameHandle = null;\n this.clearDeadline();\n if (debounceTimer !== null) clearTimeout(debounceTimer);\n if (frameHandle !== null) this.cancelFrame(frameHandle);\n }\n}\n\nfunction compareRevision(a: MessageRevision, b: MessageRevision): number {\n if (a.generation !== b.generation) return a.generation - b.generation;\n return a.revision - b.revision;\n}\n","/**\n * `LivePreviewRuntime` builds the primitives, owns their lifecycle and hands\n * accepted messages to the update pipeline. It never speaks postMessage\n * itself and never walks the DOM during an update. See ADR 0004.\n */\n\nimport { createA11y, defaultSendReady } from './runtime-wiring';\nimport { BindingWriter } from './binding-writer';\nimport { ElementCache } from './cache';\nimport { DataMerger } from './data-merger';\nimport type { DiagnosticCode } from './diagnostic-codes';\nimport { isolateDiagnostic, noopDiagnostic, safeConsoleWarn } from './diagnostics';\nimport { resolveUnfaithfulPatchMode } from './fidelity';\nimport { buildInspection } from './inspection/snapshot';\nimport type { LivePreviewInspection } from './inspection/types';\nimport { markNoWriteCallback } from './internal-outcome';\nimport { isInsideIsland } from './islands';\nimport { MessageBus } from './message-bus';\nimport { ObserverManager } from './observers';\nimport type { ProtocolNegotiation } from './protocol-version';\nimport type { RuntimeOptions } from './runtime-options';\nimport { RuntimeState, type RuntimeDeps } from './runtime-state';\nimport { startWhenReady, type StartupHost } from './startup';\nimport { ConnectionState, HeartbeatTimer } from './state';\nimport type { CachedElement } from './types';\nimport { UpdatePipeline } from './update-pipeline';\nimport { DEFAULT_DEBOUNCE_MS, UpdateScheduler } from './update-scheduler';\n\nexport type { RuntimeOptions } from './runtime-options';\nexport { resolveFieldValue } from './field-value';\n\n/** Re-broadcast `ready` a few times to absorb admin-side init latency. */\nconst READY_RETRY_DELAYS_MS = [0, 500, 1000, 2000] as const;\n\nexport class LivePreviewRuntime {\n private readonly deps: RuntimeDeps;\n private readonly state = new RuntimeState();\n private readonly pipeline: UpdatePipeline;\n private readonly writer: BindingWriter;\n /** Watches `<html>` for a swapped `<body>` so the observers follow it. */\n private rootSentinel: MutationObserver | null = null;\n private observedRoot: Node | null = null;\n\n constructor(options: RuntimeOptions) {\n const { emitter, renderers } = options;\n const log = options.log === undefined ? noopDiagnostic : isolateDiagnostic(options.log);\n const warn = options.warn === undefined ? safeConsoleWarn : isolateDiagnostic(options.warn);\n const root = options.root ?? (typeof document !== 'undefined' ? document : undefined);\n // Without a document there is nothing to bind. Failing here names the\n // option; the alternative is a TypeError from the first DOM read in start().\n if (root === undefined) throw new Error('LivePreviewRuntime: no document; pass options.root');\n // Bindings inside a hydrated island are the island's business (ADR 0008 §4).\n const cache = new ElementCache({ filter: (element) => !isInsideIsland(element) });\n const observers = new ObserverManager(\n {\n onStructuralChange: () => {\n this.rebuildCache();\n },\n onVisibilityChange: (element, visible) => {\n if (visible) scheduler.notifyVisible(element);\n },\n },\n options.intersectionRootMargin !== undefined\n ? { intersectionRootMargin: options.intersectionRootMargin }\n : {},\n );\n const scheduler = new UpdateScheduler(\n markNoWriteCallback((update) => this.writer.apply(update)),\n {\n ...(options.debounceMs !== undefined ? { debounceMs: options.debounceMs } : {}),\n ...(options.disableVisibilityGate !== undefined\n ? { disableVisibilityGate: options.disableVisibilityGate }\n : {}),\n ...(options.visibilityGateThreshold !== undefined\n ? { visibilityGateThreshold: options.visibilityGateThreshold }\n : {}),\n isVisible: (element) => observers.isVisible(element),\n getCacheSize: () => cache.elementCount,\n onFlush: (stats) => {\n this.pipeline.onFlush(stats);\n },\n },\n );\n const bus = new MessageBus(options.originMatcher, {\n onUpdate: (message, origin, revision) => {\n this.pipeline.handleUpdate(message, origin, revision);\n },\n onDocumentEvent: () => {\n this.state.protocol.observe(['document-events'], log);\n void emitter.emit('documentSave', { timestamp: Date.now() });\n },\n onFocusField: (field) => {\n if (this.deps.revealEditedField) this.pipeline.revealField(field);\n },\n onInvalid: (reason, origin) => {\n if (reason === 'token') {\n const error = new Error(`Preview token rejected (origin: ${origin})`);\n void emitter.emit('error', { error, context: 'token', code: 'LP0502' });\n }\n // A trusted origin sending a shape this runtime does not know is\n // protocol drift, not an attack — and the only place it is visible is\n // here, so it is said out loud once rather than only under `debug`.\n if ((reason === 'shape' || reason === 'type') && !this.state.warnedProtocolShape) {\n this.state.warnedProtocolShape = true;\n warn(\n `[live-preview] LP0503: ${origin} posted a message this runtime does not recognise ` +\n `(${reason === 'type' ? 'unknown message type' : 'unexpected shape'}); it was ` +\n 'ignored. A newer Payload or a custom sender: check that the versions match.',\n );\n }\n // The one refusal reason whose default changed in 2.0. A page whose\n // admin posts from somewhere other than the window that framed or\n // opened it simply stops updating, and the cause is invisible unless\n // `debug` happens to be on — so it is said once, like LP0503.\n if (reason === 'source' && !this.state.warnedForeignSource) {\n this.state.warnedForeignSource = true;\n warn(\n `[live-preview] LP0501: a message from ${origin} was ignored because it did not come ` +\n 'from the window that framed or opened this page. `eventSourcePolicy` is ' +\n \"'parent-or-opener' by default since 2.0, where 1.x accepted any window on a \" +\n \"trusted origin. Set `eventSourcePolicy: 'any'` if the admin posts from elsewhere.\",\n );\n }\n log('LP0501 message rejected:', reason, origin);\n },\n ...(options.validateToken !== undefined ? { validateToken: options.validateToken } : {}),\n ...(options.eventSourcePolicy !== undefined\n ? { sourcePolicy: options.eventSourcePolicy }\n : {}),\n });\n const merge = options.dataMerge;\n this.deps = {\n emitter,\n cache,\n observers,\n scheduler,\n bus,\n connection: new ConnectionState(),\n heartbeat: new HeartbeatTimer({\n ...(options.heartbeatMs !== undefined ? { timeoutMs: options.heartbeatMs } : {}),\n onTimeout: () => {\n this.onHeartbeatTimeout();\n },\n }),\n renderers,\n resolveRenderer: options.resolveRenderer ?? ((fieldType) => renderers[fieldType]),\n transformValue: options.transformValue,\n renderRichText: options.renderRichText,\n sanitizerPolicy: options.sanitizerPolicy,\n root,\n readyTargets:\n typeof options.readyTargets === 'function'\n ? options.readyTargets\n : (\n (targets) => (): readonly string[] =>\n targets\n )(options.readyTargets),\n sendReady: options.sendReady ?? defaultSendReady,\n onHeartbeatTimeout: options.onHeartbeatTimeout,\n log,\n warn,\n a11y: createA11y(options),\n merger:\n merge === undefined\n ? null\n : new DataMerger({\n serverURL: merge.serverURL,\n ...(merge.apiRoute !== undefined ? { apiRoute: merge.apiRoute } : {}),\n ...(merge.depth !== undefined ? { depth: merge.depth } : {}),\n ...(merge.fetchFn !== undefined ? { fetchFn: merge.fetchFn } : {}),\n log,\n }),\n mergeWindowMs: options.debounceMs ?? DEFAULT_DEBOUNCE_MS,\n scopeBindingsByOwner: options.scopeBindingsByOwner === true,\n lockedOrigin: options.lockedOrigin ?? ((): undefined => undefined),\n skipUnchanged: options.skipUnchanged === true,\n dependencies: options.dependencies ?? {},\n strategies: options.strategies ?? {},\n revealEditedField: options.revealEditedField === true,\n onUnfaithfulPatch: resolveUnfaithfulPatchMode(options),\n autoBind: options.autoBind ?? 'off',\n hydration: options.hydration,\n };\n this.writer = new BindingWriter(this.deps, this.state);\n this.pipeline = new UpdatePipeline(this.deps, this.state, () => {\n this.rebuildCache();\n });\n }\n\n /**\n * Build the cache, attach observers and listeners, broadcast `ready`.\n * Returns `false` when already started. While the document is still\n * parsing the real start waits for `DOMContentLoaded`; on a page that\n * declares hydration it then waits for React's first commit as well\n * (ADR 0015), so the first write lands on markup React keeps.\n */\n start(): boolean {\n const { state } = this;\n if (state.isRunning()) return false;\n state.started = true;\n state.suspended = false;\n try {\n startWhenReady(this.startupHost());\n return true;\n } catch (error) {\n this.rollbackFailedStart();\n throw error;\n }\n }\n\n /** The runtime as the startup chain sees it (./startup). */\n private startupHost(): StartupHost {\n const { state, deps } = this;\n return {\n root: deps.root,\n hydration: deps.hydration,\n isRunning: () => state.isRunning(),\n defer: (cancel) => {\n state.deferredStart = cancel;\n },\n later: (step) => {\n state.deferredStart = null;\n try {\n step();\n } catch (error) {\n // start() already returned; roll back and report through the error event.\n this.rollbackFailedStart();\n this.reportError(error, 'startup', 'LP0605');\n }\n },\n hydrated: (hydration) => {\n state.hydration = hydration;\n },\n warn: deps.warn,\n startNow: () => {\n this.startNow();\n },\n };\n }\n\n private startNow(): void {\n const { state, deps } = this;\n if (!state.isRunning()) return;\n const observerRoot: Node | null = isDocumentRoot(deps.root)\n ? readDocumentBody(deps.root)\n : deps.root;\n if (observerRoot === null) throw new Error('LivePreviewRuntime: document.body unavailable');\n deps.observers.start(observerRoot);\n this.observedRoot = observerRoot;\n this.watchRootReplacement();\n // Observers first: the cache scan registers its elements with them.\n this.buildCacheAndObserve();\n if (!state.isRunning()) return;\n deps.bus.attach();\n void deps.emitter.emitWhile('init', { timestamp: Date.now() }, () => state.isRunning());\n if (!state.isRunning()) return;\n for (const delay of READY_RETRY_DELAYS_MS) {\n if (!state.isRunning()) return;\n if (delay === 0) {\n deps.sendReady(deps.readyTargets());\n } else {\n state.readyTimers.push(\n setTimeout(() => {\n if (state.isRunning()) this.sendReadyAfterStart();\n }, delay),\n );\n }\n }\n }\n\n /**\n * Release the message ingress and observers but keep the configuration, so\n * `start()` brings the same instance back — what a back/forward-cache\n * restore needs, since it re-runs no scripts.\n */\n suspend(): boolean {\n if (!this.state.isRunning()) return false;\n const wasConnected = this.release();\n this.state.suspended = true;\n if (wasConnected) {\n void this.deps.emitter.emit('disconnect', { reason: 'unload', timestamp: Date.now() });\n }\n return true;\n }\n\n destroy(): void {\n const { state, deps } = this;\n if (!state.isRunning() && !state.suspended) return;\n const wasConnected = state.isRunning() ? this.release() : false;\n state.suspended = false;\n if (wasConnected) {\n void deps.emitter.emit('disconnect', { reason: 'destroy', timestamp: Date.now() });\n }\n deps.a11y?.detach();\n void deps.emitter.emit('destroy', { timestamp: Date.now() });\n }\n\n /** Invalidate first, then release everything startup may have acquired. */\n private release(): boolean {\n const { state, deps } = this;\n state.activeUpdate = null;\n state.started = false;\n const deferredStart = state.deferredStart;\n state.deferredStart = null;\n if (deferredStart !== null) this.runCleanup(deferredStart);\n for (const handle of state.readyTimers) {\n this.runCleanup(() => {\n clearTimeout(handle);\n });\n }\n state.readyTimers.length = 0;\n this.runCleanup(() => {\n deps.heartbeat.stop();\n });\n this.runCleanup(() => {\n deps.bus.detach();\n });\n state.abortStrategies();\n this.runCleanup(() => {\n this.rootSentinel?.disconnect();\n this.rootSentinel = null;\n this.observedRoot = null;\n });\n this.runCleanup(() => {\n deps.observers.stop();\n });\n this.runCleanup(() => {\n deps.scheduler.destroy();\n });\n this.runCleanup(() => {\n deps.merger?.destroy();\n state.merges.destroy();\n });\n deps.cache.clear();\n return deps.connection.markDisconnected();\n }\n\n private rollbackFailedStart(): void {\n this.release();\n this.runCleanup(() => {\n this.deps.a11y?.detach();\n });\n }\n\n private runCleanup(cleanup: () => void): void {\n try {\n cleanup();\n } catch (error) {\n this.deps.log('cleanup failed:', error);\n }\n }\n\n /** Re-scan the DOM and re-register every binding. */\n refreshCache(): void {\n if (!this.state.isRunning()) return;\n this.state.revealer.reset();\n if (!this.followReplacedRoot()) this.rebuildCache();\n }\n\n /** Some routers swap `document.body` on navigation, leaving observers on a detached node. */\n private watchRootReplacement(): void {\n const { root } = this.deps;\n if (!isDocumentRoot(root) || typeof MutationObserver === 'undefined') return;\n this.rootSentinel?.disconnect();\n this.rootSentinel = new MutationObserver(() => {\n this.followReplacedRoot();\n });\n this.rootSentinel.observe(root.documentElement, { childList: true });\n }\n\n /** Rebind observers and cache to a replaced body; returns whether it did. */\n private followReplacedRoot(): boolean {\n const { root } = this.deps;\n if (!this.state.isRunning() || !isDocumentRoot(root)) return false;\n const body = readDocumentBody(root);\n if (body === null || body === this.observedRoot) return false;\n this.observedRoot = body;\n this.deps.observers.start(body);\n this.rebuildCache();\n return true;\n }\n\n get status(): 'disconnected' | 'connecting' | 'connected' {\n return this.deps.connection.status;\n }\n\n get cache(): ElementCache {\n return this.deps.cache;\n }\n\n get updateCount(): number {\n return this.state.updateCount;\n }\n\n /** Negotiated protocol view, `min(library, remote)`. */\n get protocol(): ProtocolNegotiation {\n return this.state.protocol.negotiation;\n }\n\n /** Point-in-time read of runtime state for diagnosing a preview that is not updating. */\n inspect(): LivePreviewInspection {\n return buildInspection(this.deps, this.state);\n }\n\n private buildCacheAndObserve(): void {\n const { state, deps } = this;\n if (!state.isRunning()) return;\n const stats = deps.cache.buildFromRoot(deps.root);\n deps.log('cache', stats);\n if (!state.isRunning()) return;\n void deps.emitter.emitWhile('cacheRefresh', stats, () => state.isRunning());\n if (!state.isRunning()) return;\n for (const entry of deps.cache.values()) {\n if (!state.isRunning()) return;\n deps.observers.observeElement(entry.element);\n }\n }\n\n private rebuildCache(): void {\n const { state, deps } = this;\n if (!state.isRunning()) return;\n const previous = new Map<Element, CachedElement>();\n for (const entry of deps.cache.values()) {\n previous.set(entry.element, entry);\n deps.observers.unobserveElement(entry.element);\n }\n this.buildCacheAndObserve();\n if (!state.isRunning()) return;\n // Buffered work survives only while the same element is bound to the same field.\n for (const entry of deps.cache.values()) {\n const before = previous.get(entry.element);\n if (before?.fieldName === entry.fieldName) deps.scheduler.retarget(entry);\n else deps.scheduler.forget(entry.element);\n previous.delete(entry.element);\n }\n for (const removed of previous.values()) deps.scheduler.forget(removed.element);\n }\n\n private onHeartbeatTimeout(): void {\n const { state, deps } = this;\n if (!state.isRunning()) return;\n deps.bus.advanceGeneration();\n const active = state.activeUpdate;\n state.activeUpdate = null;\n if (active !== null) deps.scheduler.cancelRevision(active.revision);\n deps.merger?.destroy();\n state.merges.destroy();\n const wasConnected = deps.connection.markDisconnected();\n // Release the origin lock before the disconnect event: a listener may\n // reconnect from another allow-listed origin synchronously.\n try {\n deps.onHeartbeatTimeout?.();\n } catch (error) {\n deps.log('heartbeat:', error);\n }\n if (!state.isRunning()) return;\n if (wasConnected && this.isIdleDisconnected()) {\n deps.a11y?.announceDisconnected();\n void deps.emitter.emitWhile('disconnect', { reason: 'timeout', timestamp: Date.now() }, () =>\n this.isIdleDisconnected(),\n );\n if (!state.isRunning()) return;\n if (this.isIdleDisconnected()) deps.log('connection', 'connected', '→', 'disconnected');\n if (!state.isRunning()) return;\n }\n this.sendReadyAfterStart();\n }\n\n /** Later handshake retries are best-effort and must not escape timer callbacks. */\n private sendReadyAfterStart(): void {\n try {\n this.deps.sendReady(this.deps.readyTargets());\n } catch (error) {\n this.reportError(error, 'ready', 'LP0606');\n }\n }\n\n private reportError(cause: unknown, context: string, code: DiagnosticCode): void {\n const error = cause instanceof Error ? cause : new Error(String(cause));\n void this.deps.emitter.emit('error', { error, context, code });\n }\n\n private isIdleDisconnected(): boolean {\n return (\n this.state.isRunning() &&\n this.deps.connection.status === 'disconnected' &&\n this.state.activeUpdate === null\n );\n }\n}\n\n/** Node types are stable across realms; global constructors are not. */\nfunction isDocumentRoot(root: Document | Element): root is Document {\n return root.nodeType === 9;\n}\n\n/** lib.dom types body as present; a head-time document has none yet. */\nfunction readDocumentBody(root: Document): HTMLElement | null {\n return root.body;\n}\n","/** Assembles the `inspect()` snapshot. Reads state only; sends nothing anywhere. */\n\nimport { VERSION } from '../../version';\nimport { detectProtocolProfile } from '../protocol-profile';\nimport type { RuntimeDeps, RuntimeState } from '../runtime-state';\nimport type { LivePreviewInspection } from './types';\n\nexport function buildInspection(deps: RuntimeDeps, state: RuntimeState): LivePreviewInspection {\n const { cache, scheduler } = deps;\n const negotiation = state.protocol.negotiation;\n const active = state.activeUpdate;\n const flush = state.lastFlush;\n const fieldNames: string[] = [];\n const owners = new Set<string>();\n const guessed: { field: string; matched: string; attribute: string | undefined }[] = [];\n for (const [fieldName, bindings] of cache.entries()) {\n fieldNames.push(fieldName);\n for (const binding of bindings) {\n if (binding.owner !== undefined) owners.add(binding.owner);\n if (binding.guessed !== undefined) {\n guessed.push({\n field: fieldName,\n matched: binding.guessed,\n attribute:\n binding.targetAttribute ?? (binding.element.tagName === 'IMG' ? 'src' : undefined),\n });\n }\n }\n }\n return {\n version: VERSION,\n started: state.started,\n status: deps.connection.status,\n origins: { trusted: [...deps.readyTargets()], locked: deps.lockedOrigin() },\n protocol: {\n ours: negotiation.ours,\n theirs: negotiation.theirs,\n negotiated: negotiation.negotiated,\n capabilities: [...negotiation.capabilities].sort(),\n observed: [...negotiation.observed].sort(),\n profile: detectProtocolProfile(negotiation.observed).name,\n },\n revisions: {\n accepted: state.updateCount,\n superseded: state.supersededCount,\n completed: state.completedCount,\n skippedUnchanged: state.skippedUnchangedCount,\n active: active === null ? undefined : active.revision.revision,\n },\n bindings: {\n elements: cache.elementCount,\n fields: cache.fieldCount,\n fieldNames: fieldNames.sort(),\n absentFields: [...state.absentFields].sort(),\n orphanFields: [...state.warnedOrphanFields].sort(),\n ownerScoped: deps.scopeBindingsByOwner,\n owners: [...owners].sort(),\n guessed: guessed.sort((left, right) => left.field.localeCompare(right.field)),\n autoBind: { mode: deps.autoBind, searchMs: state.autoBindSearchMs },\n },\n route: { handler: deps.strategies.route !== undefined, ...state.routeStats },\n fidelity: {\n mode: deps.onUnfaithfulPatch,\n unfaithful: state.unfaithfulCount,\n escalated: state.escalatedCount,\n fields: [...state.unfaithfulFields].sort(),\n },\n hydration: { mode: deps.hydration ?? 'off', state: state.hydration },\n fragments: {\n handler: deps.strategies.fragment !== undefined,\n inFlight: active?.pendingFragments ?? 0,\n ...state.fragmentStats,\n },\n scheduler: {\n pending: scheduler.pendingCount,\n deferred: scheduler.replayCount,\n visibilityGateThreshold: scheduler.gateThreshold,\n visibilityGateActive: scheduler.gateActive,\n lastFlush:\n flush === null\n ? undefined\n : {\n applied: flush.applied,\n appliedFields: flush.appliedFields,\n deferred: flush.deferred,\n durationMs: flush.durationMs,\n },\n },\n plugins: [],\n renderers: Object.keys(deps.renderers).sort(),\n };\n}\n","/**\n * Per-instance typed emitter: handlers run sequentially in registration order,\n * may be async, and a throwing one is logged and isolated. See ADR 0002.\n */\n\nimport type { EventHandler, LivePreviewEventMap, Unsubscribe } from './types';\nimport { safeConsoleError } from '@core/diagnostics';\n\ntype AnyHandler = EventHandler<unknown>;\n\n// `object`, not `Record<string, unknown>`: interfaces with readonly and\n// exact-optional properties must be usable as maps.\nexport class EventEmitter<TMap extends object = LivePreviewEventMap> {\n readonly #regular = new Map<keyof TMap, Set<AnyHandler>>();\n readonly #once = new Map<keyof TMap, Set<AnyHandler>>();\n\n on<E extends keyof TMap>(event: E, handler: EventHandler<TMap[E]>): Unsubscribe {\n return this.#register(this.#regular, event, handler as AnyHandler);\n }\n\n once<E extends keyof TMap>(event: E, handler: EventHandler<TMap[E]>): Unsubscribe {\n return this.#register(this.#once, event, handler as AnyHandler);\n }\n\n off<E extends keyof TMap>(event: E, handler: EventHandler<TMap[E]>): void {\n this.#remove(this.#regular, event, handler as AnyHandler);\n this.#remove(this.#once, event, handler as AnyHandler);\n }\n\n /** Dispatch to every handler: regular ones first, then `once` handlers. */\n async emit<E extends keyof TMap>(event: E, payload: TMap[E]): Promise<void> {\n await this.#emitSequential(event, payload);\n }\n\n /**\n * Dispatch while `shouldContinue()` holds — checked around every handler, so\n * an obsolete transaction cannot resume across an await.\n * @internal\n */\n async emitWhile<E extends keyof TMap>(\n event: E,\n payload: TMap[E],\n shouldContinue: () => boolean,\n ): Promise<boolean> {\n return this.#emitSequential(event, payload, shouldContinue);\n }\n\n async #emitSequential<E extends keyof TMap>(\n event: E,\n payload: TMap[E],\n shouldContinue?: () => boolean,\n ): Promise<boolean> {\n const eligible = (): boolean => shouldContinue?.() ?? true;\n if (!eligible()) return false;\n const regular = this.#regular.get(event);\n if (regular) {\n for (const handler of [...regular]) {\n if (!eligible()) return false;\n await this.#invoke(handler, payload, event);\n if (!eligible()) return false;\n }\n }\n if (!eligible()) return false;\n const once = this.#once.get(event);\n if (once && once.size > 0) {\n const snapshot = [...once];\n this.#once.delete(event);\n for (const handler of snapshot) {\n if (!eligible()) return false;\n await this.#invoke(handler, payload, event);\n if (!eligible()) return false;\n }\n }\n return eligible();\n }\n\n /** Registered handlers for `event`, `on` and `once` together. */\n listenerCount(event: keyof TMap): number {\n return (this.#regular.get(event)?.size ?? 0) + (this.#once.get(event)?.size ?? 0);\n }\n\n /** Remove every handler, or only those of `event`. */\n removeAllListeners(event?: keyof TMap): void {\n if (event === undefined) {\n this.#regular.clear();\n this.#once.clear();\n return;\n }\n this.#regular.delete(event);\n this.#once.delete(event);\n }\n\n /** Event names with at least one handler. */\n eventNames(): (keyof TMap)[] {\n const names = new Set<keyof TMap>();\n for (const key of this.#regular.keys()) names.add(key);\n for (const key of this.#once.keys()) names.add(key);\n return [...names];\n }\n\n #register(\n bucket: Map<keyof TMap, Set<AnyHandler>>,\n event: keyof TMap,\n handler: AnyHandler,\n ): Unsubscribe {\n let set = bucket.get(event);\n if (!set) {\n set = new Set();\n bucket.set(event, set);\n }\n set.add(handler);\n return () => {\n this.#remove(bucket, event, handler);\n };\n }\n\n #remove(bucket: Map<keyof TMap, Set<AnyHandler>>, event: keyof TMap, handler: AnyHandler): void {\n const set = bucket.get(event);\n if (set === undefined) return;\n set.delete(handler);\n if (set.size === 0) bucket.delete(event);\n }\n\n async #invoke(handler: AnyHandler, payload: unknown, event: keyof TMap): Promise<void> {\n try {\n await handler(payload);\n } catch (err) {\n const label =\n typeof event === 'string' || typeof event === 'number' ? String(event) : '<event>';\n safeConsoleError(`[live-preview] LP0601: handler for \"${label}\" threw:`, err);\n }\n }\n}\n","/**\n * Where the runtime is running: framed, opened, or on a developer's machine.\n * Nothing reads bundler-injected variables; a Vite consumer passes\n * `import.meta.env.X` explicitly (docs/astro.md).\n * @internal\n */\n\nexport function isInIframe(): boolean {\n if (typeof window === 'undefined') return false;\n try {\n return window.self !== window.top;\n } catch {\n // A cross-origin parent throws on the comparison; that is an iframe.\n return true;\n }\n}\n\n/** @internal */\nexport function isInPopup(): boolean {\n if (typeof window === 'undefined') return false;\n return window.opener != null;\n}\n\n/** An iframe or a popup; top-level navigation never starts the preview. @internal */\nexport function isInPreviewContext(): boolean {\n return isInIframe() || isInPopup();\n}\n\n/** Under Node, `NODE_ENV !== 'production'`; in a browser the hostname, which is the only signal a bundle has. @internal */\nexport function isDevMode(): boolean {\n const nodeEnv = readNodeEnv();\n if (nodeEnv !== undefined) return nodeEnv !== 'production';\n if (typeof window !== 'undefined') {\n const host = window.location.hostname;\n return host === 'localhost' || host === '127.0.0.1';\n }\n return false;\n}\n\nfunction readNodeEnv(): string | undefined {\n if (typeof process === 'undefined') return undefined;\n const value = process.env['NODE_ENV'];\n return typeof value === 'string' ? value : undefined;\n}\n","/**\n * Which admin origins the runtime trusts: explicit ones always, the\n * `document.referrer` origin only when none is configured, any localhost port\n * in development. See docs/security.md §1.\n */\n\nimport { isDevMode, isInIframe } from './environment';\n\nconst LOCALHOST_PATTERN = /^https?:\\/\\/(localhost|127\\.0\\.0\\.1)(?::\\d+)?$/i;\nconst VALID_ORIGIN_PATTERN = /^https?:\\/\\/[^/?#\\s]+$/i;\n\n/** Ports the handshake broadcasts to when the localhost pattern is on; matching itself is unrestricted. */\nconst LOCALHOST_HANDSHAKE_PORTS: readonly number[] = [\n 3000, 3001, 3333, 4000, 4321, 5000, 5173, 5174, 8000, 8080, 8888, 9000,\n];\n\nexport interface OriginDetectorOptions {\n /** Explicit origins to trust. Always allowed. */\n readonly additionalOrigins?: readonly string[];\n /** Set to `false` to ignore `document.referrer`. */\n readonly enableReferrerDetection?: boolean;\n /** Set to `false` to ignore the localhost pattern even in development. */\n readonly enableLocalhostMatching?: boolean;\n /** Override dev-mode detection. */\n readonly forceDevMode?: boolean;\n /** Override `document.referrer` for tests. */\n readonly referrer?: string;\n}\n\nconst enum OriginSlot {\n ExplicitOrigins,\n ReferrerOrigin,\n AllowLocalhost,\n ReferrerWasAvailable,\n LockedOrigin,\n}\n\ntype OriginState = [\n explicitOrigins: ReadonlySet<string>,\n referrerOrigin: string | undefined,\n allowLocalhost: boolean,\n referrerWasAvailable: boolean,\n lockedOrigin: string | undefined,\n];\n\n/** The trusted-origin policy: the union of the candidate sources, narrowed to one by `lockOrigin()`. */\nexport class OriginDetector {\n readonly #state: OriginState;\n\n constructor(options: OriginDetectorOptions = {}) {\n const explicit = new Set<string>();\n for (const origin of options.additionalOrigins ?? []) {\n const normalised = normaliseOrigin(origin);\n if (normalised !== undefined) explicit.add(normalised);\n }\n let referrerOrigin: string | undefined;\n if (options.enableReferrerDetection ?? true) {\n const referrer =\n options.referrer ?? (typeof document !== 'undefined' ? document.referrer : '');\n if (referrer.length > 0) {\n try {\n const origin = new URL(referrer).origin;\n if (origin && origin !== 'null') referrerOrigin = origin;\n } catch {\n // opaque referrer\n }\n }\n }\n const allowLocalhost =\n (options.enableLocalhostMatching ?? true) && (options.forceDevMode ?? isDevMode());\n this.#state = [\n explicit,\n referrerOrigin,\n allowLocalhost,\n referrerOrigin !== undefined,\n undefined,\n ];\n }\n\n /** Whether `origin` is trusted: the locked origin alone once locked, otherwise the policy above. */\n matches(origin: string): boolean {\n if (origin.length === 0 || origin === 'null') return false;\n if (this.#state[OriginSlot.LockedOrigin] !== undefined) {\n return origin === this.#state[OriginSlot.LockedOrigin];\n }\n if (this.#state[OriginSlot.ExplicitOrigins].has(origin)) return true;\n // The referrer is a fallback, not a union member: any embedder lands there.\n if (\n this.#state[OriginSlot.ExplicitOrigins].size === 0 &&\n this.#state[OriginSlot.ReferrerOrigin] !== undefined &&\n origin === this.#state[OriginSlot.ReferrerOrigin]\n ) {\n return true;\n }\n if (this.#state[OriginSlot.AllowLocalhost] && LOCALHOST_PATTERN.test(origin)) return true;\n return false;\n }\n\n /** Narrow trust to `origin`; refused (`false`) when it is not currently trusted. */\n lockOrigin(origin: string): boolean {\n if (!this.matches(origin)) return false;\n this.#state[OriginSlot.LockedOrigin] = origin;\n return true;\n }\n\n /** Release the lock (heartbeat timeout) so another allow-listed origin may reconnect. Returns the previous lock. */\n unlockOrigin(): string | undefined {\n const previous = this.#state[OriginSlot.LockedOrigin];\n this.#state[OriginSlot.LockedOrigin] = undefined;\n return previous;\n }\n\n get lockedOrigin(): string | undefined {\n return this.#state[OriginSlot.LockedOrigin];\n }\n\n /** Every origin the `ready` handshake is broadcast to; the localhost pattern expands to the common dev ports. */\n enumerate(): string[] {\n if (this.#state[OriginSlot.LockedOrigin] !== undefined) {\n return [this.#state[OriginSlot.LockedOrigin]];\n }\n const result = new Set<string>(this.#state[OriginSlot.ExplicitOrigins]);\n if (\n this.#state[OriginSlot.ExplicitOrigins].size === 0 &&\n this.#state[OriginSlot.ReferrerOrigin] !== undefined\n ) {\n result.add(this.#state[OriginSlot.ReferrerOrigin]);\n }\n if (this.#state[OriginSlot.AllowLocalhost]) {\n for (const port of LOCALHOST_HANDSHAKE_PORTS) {\n result.add(`http://localhost:${String(port)}`);\n result.add(`http://127.0.0.1:${String(port)}`);\n }\n }\n return [...result];\n }\n\n /** Whether `document.referrer` contributed an origin (absent under `Referrer-Policy: no-referrer`). */\n get referrerWasAvailable(): boolean {\n return this.#state[OriginSlot.ReferrerWasAvailable];\n }\n\n /** Framed, outside development, with no trusted origin at all: the host should warn (LP0101). */\n get isProductionUnconfigured(): boolean {\n if (!isInIframe()) return false;\n if (this.#state[OriginSlot.ExplicitOrigins].size > 0) return false;\n if (this.#state[OriginSlot.AllowLocalhost]) return false;\n if (this.#state[OriginSlot.ReferrerOrigin] !== undefined) return false;\n return true;\n }\n\n /** The referrer is the only trust source, so any framing site may drive the preview (LP0102). */\n get isReferrerOnlyTrust(): boolean {\n if (this.#state[OriginSlot.ExplicitOrigins].size > 0) return false;\n if (this.#state[OriginSlot.AllowLocalhost]) return false;\n return this.#state[OriginSlot.ReferrerOrigin] !== undefined;\n }\n}\n\n/** The canonical `http(s)://host[:port]` form of `value`, or `undefined` when it is not one. */\nexport function normaliseOrigin(value: string): string | undefined {\n const trimmed = value.trim();\n if (trimmed.length === 0) return undefined;\n try {\n const url = new URL(trimmed);\n if (url.protocol !== 'http:' && url.protocol !== 'https:') return undefined;\n if (!VALID_ORIGIN_PATTERN.test(url.origin)) return undefined;\n return url.origin;\n } catch {\n return undefined;\n }\n}\n","/**\n * Registration-local resource scope: every listener, transform, renderer\n * layer and cleanup a plugin registers is staged here until `init` commits\n * and released together, in reverse order, when the plugin goes. See ADR 0005.\n */\n\nimport { observeThenableResult } from '@core/thenable';\nimport type { PluginDisposer } from './types';\n\nexport type ResourceKind = 'transform' | 'renderer' | 'subscription' | 'cleanup';\n\ninterface ScopedResource {\n readonly kind: ResourceKind;\n readonly acquire: (() => PluginDisposer | undefined) | undefined;\n readonly finalize: (() => void) | undefined;\n cleanup: PluginDisposer | undefined;\n disposed: boolean;\n}\n\nexport const noopDisposer: PluginDisposer = () => undefined;\n\nexport class ResourceScope {\n readonly #pluginName: string;\n readonly #log: (...args: unknown[]) => void;\n // Insertion order gives commit/reverse-teardown order; short-lived entries\n // (once listeners) leave immediately instead of accumulating until removal.\n readonly #resources = new Set<ScopedResource>();\n #state: 'staging' | 'committing' | 'active' | 'closed' = 'staging';\n\n constructor(pluginName: string, log: (...args: unknown[]) => void) {\n this.#pluginName = pluginName;\n this.#log = log;\n }\n\n assertOpen(): void {\n if (this.#state === 'closed') {\n throw new Error(`Plugin context for \"${this.#pluginName}\" is no longer active`);\n }\n }\n\n get active(): boolean {\n return this.#state === 'active';\n }\n\n /** Whether a retained context still belongs to this registration. */\n eligible(): boolean {\n return this.#state !== 'closed';\n }\n\n /** Own a resource the plugin itself already acquired. */\n own(cleanup: PluginDisposer): PluginDisposer {\n this.assertOpen();\n return this.#track({\n kind: 'cleanup',\n acquire: undefined,\n finalize: undefined,\n cleanup,\n disposed: false,\n });\n }\n\n /** Stage a manager-owned resource; an active scope acquires it at once. */\n stage(\n kind: ResourceKind,\n acquire: () => PluginDisposer | undefined,\n finalize?: () => void,\n ): PluginDisposer {\n this.assertOpen();\n const resource: ScopedResource = {\n kind,\n acquire,\n finalize,\n cleanup: undefined,\n disposed: false,\n };\n const dispose = this.#track(resource);\n if (this.#state === 'active') {\n try {\n this.#activate(resource);\n } catch (error) {\n this.#dispose(resource);\n throw error;\n }\n }\n return dispose;\n }\n\n /** Live resources by kind, what `inspect().plugins` reports. */\n counts(): Record<ResourceKind, number> {\n const counts: Record<ResourceKind, number> = {\n transform: 0,\n renderer: 0,\n subscription: 0,\n cleanup: 0,\n };\n for (const resource of this.#resources) counts[resource.kind] += 1;\n return counts;\n }\n\n /** Publish every staged resource at once after `init` succeeded. */\n commit(): void {\n if (this.#state !== 'staging') {\n throw new Error(`Plugin context for \"${this.#pluginName}\" cannot be committed`);\n }\n this.#state = 'committing';\n try {\n for (const resource of this.#resources) this.#activate(resource);\n this.#state = 'active';\n } catch (error) {\n this.close();\n throw error;\n }\n }\n\n close(): void {\n if (this.#state === 'closed') return;\n this.#state = 'closed';\n for (const resource of [...this.#resources].reverse()) this.#dispose(resource);\n this.#resources.clear();\n }\n\n #track(resource: ScopedResource): PluginDisposer {\n this.#resources.add(resource);\n return (): void => {\n this.#dispose(resource);\n };\n }\n\n #activate(resource: ScopedResource): void {\n if (resource.disposed || resource.cleanup !== undefined || resource.acquire === undefined) {\n return;\n }\n const cleanup = resource.acquire();\n resource.cleanup = cleanup ?? noopDisposer;\n }\n\n #dispose(resource: ScopedResource): void {\n if (resource.disposed) return;\n resource.disposed = true;\n this.#resources.delete(resource);\n const cleanup = resource.cleanup;\n resource.cleanup = undefined;\n if (cleanup !== undefined) {\n try {\n // A `void` cleanup may still return a thenable; observe it without awaiting.\n const cleanupWithResult: () => unknown = cleanup;\n if (observeThenableResult(cleanupWithResult())) {\n this.#log(\n `plugin \"${this.#pluginName}\" cleanup returned a Promise/thenable; cleanups must be synchronous`,\n );\n }\n } catch (error) {\n this.#log(`plugin \"${this.#pluginName}\" cleanup failed:`, error);\n }\n }\n try {\n resource.finalize?.();\n } catch (error) {\n this.#log(`plugin \"${this.#pluginName}\" cleanup failed:`, error);\n }\n }\n}\n","/**\n * Event facade handed to a plugin: subscriptions are owned by the plugin's\n * scope, emits go to the client's emitter. It implements the emitter surface\n * without extending it, so no unused base emitter is allocated per plugin.\n */\n\nimport type { EventEmitter } from '@events/emitter';\nimport type { EventHandler, LivePreviewEventMap, Unsubscribe } from '@events/types';\nimport { noopDisposer, type ResourceScope } from './resource-scope';\nimport type { PluginEvents } from './types';\n\ninterface OwnedSubscription {\n readonly kind: 'on' | 'once';\n readonly event: keyof LivePreviewEventMap;\n readonly handler: EventHandler<unknown>;\n dispose: Unsubscribe;\n}\n\nexport class ScopedPluginEvents implements PluginEvents {\n readonly #events: EventEmitter;\n readonly #scope: ResourceScope;\n readonly #subscriptions = new Set<OwnedSubscription>();\n\n constructor(events: EventEmitter, scope: ResourceScope) {\n this.#events = events;\n this.#scope = scope;\n }\n\n on<E extends keyof LivePreviewEventMap>(\n event: E,\n handler: EventHandler<LivePreviewEventMap[E]>,\n ): Unsubscribe {\n return this.#subscribe('on', event, handler);\n }\n\n once<E extends keyof LivePreviewEventMap>(\n event: E,\n handler: EventHandler<LivePreviewEventMap[E]>,\n ): Unsubscribe {\n return this.#subscribe('once', event, handler);\n }\n\n off<E extends keyof LivePreviewEventMap>(\n event: E,\n handler: EventHandler<LivePreviewEventMap[E]>,\n ): void {\n const untypedHandler = handler as EventHandler<unknown>;\n for (const subscription of [...this.#subscriptions]) {\n if (subscription.event === event && subscription.handler === untypedHandler) {\n subscription.dispose();\n }\n }\n }\n\n emit<E extends keyof LivePreviewEventMap>(\n event: E,\n payload: LivePreviewEventMap[E],\n ): Promise<void> {\n this.#scope.assertOpen();\n return this.#events.emit(event, payload);\n }\n\n emitWhile<E extends keyof LivePreviewEventMap>(\n event: E,\n payload: LivePreviewEventMap[E],\n shouldContinue: () => boolean,\n ): Promise<boolean> {\n this.#scope.assertOpen();\n return this.#events.emitWhile(event, payload, () => {\n if (!this.#scope.eligible()) return false;\n const callerEligible = shouldContinue();\n // The predicate is plugin code and may close this scope re-entrantly.\n if (!this.#scope.eligible()) return false;\n return callerEligible;\n });\n }\n\n listenerCount(event: keyof LivePreviewEventMap): number {\n let count = 0;\n for (const subscription of this.#subscriptions) {\n if (subscription.event === event) count += 1;\n }\n return count;\n }\n\n removeAllListeners(event?: keyof LivePreviewEventMap): void {\n for (const subscription of [...this.#subscriptions]) {\n if (event === undefined || subscription.event === event) subscription.dispose();\n }\n }\n\n eventNames(): (keyof LivePreviewEventMap)[] {\n const names = new Set<keyof LivePreviewEventMap>();\n for (const subscription of this.#subscriptions) names.add(subscription.event);\n return [...names];\n }\n\n #subscribe<E extends keyof LivePreviewEventMap>(\n kind: 'on' | 'once',\n event: E,\n handler: EventHandler<LivePreviewEventMap[E]>,\n ): Unsubscribe {\n this.#scope.assertOpen();\n\n const untypedHandler = handler as EventHandler<unknown>;\n const existing = [...this.#subscriptions].find(\n (subscription) =>\n subscription.kind === kind &&\n subscription.event === event &&\n subscription.handler === untypedHandler,\n );\n if (existing !== undefined) return existing.dispose;\n\n // A distinct wrapper per scope: two plugins passing the same handler\n // reference must be revocable independently in the Set-based emitter.\n let dispose = noopDisposer;\n let subscriptionActive = true;\n const wrapped: EventHandler<LivePreviewEventMap[E]> = async (payload) => {\n if (!this.#scope.active || !subscriptionActive) return;\n // Mirror the base emitter, which drops a once bucket before dispatch.\n if (kind === 'once') dispose();\n await handler(payload);\n };\n const subscription: OwnedSubscription = {\n kind,\n event,\n handler: untypedHandler,\n dispose: noopDisposer,\n };\n dispose = this.#scope.stage(\n 'subscription',\n () => this.#events[kind](event, wrapped),\n () => {\n subscriptionActive = false;\n this.#subscriptions.delete(subscription);\n },\n );\n subscription.dispose = dispose;\n this.#subscriptions.add(subscription);\n return dispose;\n }\n}\n","/**\n * Per-instance plugin manager. Mutations run through one call-order queue;\n * while a queue-held hook is pending, a requested mutation takes the direct\n * path because that hook may be awaiting it. See ADR 0005.\n */\n\nimport type { FieldRenderer } from '@core/types';\nimport type { PluginInspection } from '@core/inspection/types';\nimport { LIBRARY_PROTOCOL_VERSION } from '@core/protocol-version';\nimport { VERSION } from '@/version';\nimport { incompatibilityOf } from './compat';\nimport { isolateDiagnostic } from '@core/diagnostics';\nimport { observeThenableResult } from '@core/thenable';\nimport type { EventEmitter } from '@events/emitter';\nimport { ResourceScope } from './resource-scope';\nimport { ScopedPluginEvents } from './scoped-events';\nimport type { FieldTransform, LivePreviewPlugin, PluginContext } from './types';\n\nexport interface PluginManagerOptions {\n readonly events: EventEmitter;\n readonly config: Readonly<Record<string, unknown>>;\n /** Add one renderer layer to the host; may return the layer's disposer. */\n readonly registerFieldRenderer: (renderer: FieldRenderer) => void;\n /** Receives transform contract failures for the runtime's `error` event. */\n readonly onTransformError?: (error: Error) => unknown;\n readonly log: (...args: unknown[]) => void;\n}\n\ninterface PluginRegistration {\n readonly plugin: LivePreviewPlugin;\n readonly scope: ResourceScope;\n}\n\ninterface InitializingPluginRegistration {\n readonly scope: ResourceScope;\n cancelled: boolean;\n}\n\ninterface TransformRegistration {\n readonly transform: FieldTransform;\n active: boolean;\n}\n\nfunction isPluginDisposer(value: unknown): value is (() => void) | undefined {\n return typeof value === 'function';\n}\n\nexport class PluginManager {\n readonly #events: EventEmitter;\n readonly #config: Readonly<Record<string, unknown>>;\n // The public callback type is void; the client host returns its layer disposer through it.\n readonly #registerRenderer: (renderer: FieldRenderer) => unknown;\n readonly #onTransformError: ((error: Error) => void) | undefined;\n readonly #log: (...args: unknown[]) => void;\n readonly #plugins = new Map<string, PluginRegistration>();\n readonly #initializing = new Map<string, InitializingPluginRegistration>();\n readonly #teardowns = new Map<string, Promise<void>>();\n readonly #destroying = new Set<string>();\n readonly #transforms = new Map<string, TransformRegistration[]>();\n #mutationQueue: Promise<void> = Promise.resolve();\n // Hooks awaited by the queue entry in flight. Hooks started on the direct\n // path never hold the queue, so they must not open it for others.\n #queuedHooks = 0;\n\n constructor(options: PluginManagerOptions) {\n this.#events = options.events;\n this.#config = options.config;\n this.#registerRenderer = options.registerFieldRenderer;\n this.#log = isolateDiagnostic(options.log);\n const onTransformError = options.onTransformError;\n this.#onTransformError =\n onTransformError === undefined\n ? undefined\n : isolateDiagnostic((...args: unknown[]): unknown => {\n // Private and single-callered: `applyTransforms` normalizes to an\n // Error before it reports one.\n const error = args[0] as Error;\n try {\n return onTransformError(error);\n } catch (reportError) {\n this.#log('transform error reporter failed:', reportError);\n return undefined;\n }\n });\n }\n\n /** Register a plugin transactionally; concurrent mutations run in call order. */\n register(plugin: LivePreviewPlugin): Promise<void> {\n if (this.#queuedHooks > 0) return this.#registerNow(plugin, false);\n return this.#enqueue(() => this.#registerNow(plugin, true));\n }\n\n /** Remove one plugin and every resource its registration created. */\n unregister(name: string): Promise<void> {\n if (this.#queuedHooks > 0) return this.#unregisterNow(name, false);\n return this.#enqueue(async () => {\n await this.#unregisterNow(name, true);\n });\n }\n\n /** Destroy every registration; one failure never strands another. */\n destroyAll(): Promise<void> {\n if (this.#queuedHooks > 0) return this.#destroyAllNow(false);\n return this.#enqueue(async () => {\n await this.#destroyAllNow(true);\n });\n }\n\n /** Apply active transforms in registration order; a failure returns the original value. */\n applyTransforms(\n fieldName: string,\n value: unknown,\n context: { readonly element: Element; readonly allFields: Record<string, unknown> },\n isCurrent?: () => boolean,\n ): unknown {\n const registrations = this.#transforms.get(fieldName);\n if (registrations === undefined || registrations.length === 0) return value;\n\n let result: unknown = value;\n for (const registration of [...registrations]) {\n if (!registration.active) continue;\n const { transform } = registration;\n if (isCurrent?.() === false) return value;\n try {\n result = transform(result, {\n fieldName,\n element: context.element,\n allFields: context.allFields,\n });\n const returnedThenable = observeThenableResult(result);\n // A transform may synchronously let a newer message in; then its\n // result belongs to a superseded revision and is not reported.\n if (isCurrent?.() === false) return value;\n if (returnedThenable) {\n throw new TypeError(\n `Transform for \"${fieldName}\" returned a Promise/thenable; transforms must be synchronous`,\n );\n }\n } catch (error) {\n if (isCurrent?.() === false) return value;\n const normalized = error instanceof Error ? error : new Error(String(error));\n this.#log(`transform for \"${fieldName}\" failed:`, normalized);\n this.#onTransformError?.(normalized);\n return value;\n }\n }\n return result;\n }\n\n list(): readonly string[] {\n return [...this.#plugins.keys()];\n }\n\n /** Every plugin with its state and live registrations (`inspect().plugins`). */\n snapshot(): readonly PluginInspection[] {\n const entries: PluginInspection[] = [];\n const describe = (\n name: string,\n version: string | undefined,\n state: PluginInspection['state'],\n scope: ResourceScope,\n ): PluginInspection => {\n const counts = scope.counts();\n return {\n name,\n version,\n state,\n registrations: {\n transforms: counts.transform,\n renderers: counts.renderer,\n subscriptions: counts.subscription,\n cleanups: counts.cleanup,\n },\n };\n };\n for (const [name, initializing] of this.#initializing) {\n entries.push(describe(name, undefined, 'initializing', initializing.scope));\n }\n for (const [name, registration] of this.#plugins) {\n entries.push(describe(name, registration.plugin.version, 'active', registration.scope));\n }\n // A name with a pending teardown left `#plugins` before the teardown began.\n for (const name of this.#teardowns.keys()) {\n entries.push({\n name,\n version: undefined,\n state: 'tearing-down',\n registrations: { transforms: 0, renderers: 0, subscriptions: 0, cleanups: 0 },\n });\n }\n return entries;\n }\n\n get size(): number {\n return this.#plugins.size;\n }\n\n async #registerNow(plugin: LivePreviewPlugin, queued: boolean): Promise<void> {\n if (\n this.#plugins.has(plugin.name) ||\n this.#initializing.has(plugin.name) ||\n this.#teardowns.has(plugin.name)\n ) {\n this.#log(`plugin \"${plugin.name}\" already registered`);\n return;\n }\n\n const incompatibility = incompatibilityOf(plugin.compat, VERSION, LIBRARY_PROTOCOL_VERSION);\n if (incompatibility !== undefined) {\n this.#refuse(plugin.name, incompatibility);\n return;\n }\n const scope = new ResourceScope(plugin.name, this.#log);\n const context = this.#createContext(plugin.name, scope);\n const initializing: InitializingPluginRegistration = { scope, cancelled: false };\n this.#initializing.set(plugin.name, initializing);\n try {\n await this.#runHook(() => plugin.init(context), queued);\n if (initializing.cancelled) return;\n scope.commit();\n } catch (error) {\n scope.close();\n if (!initializing.cancelled) this.#log(`plugin \"${plugin.name}\" init failed:`, error);\n return;\n } finally {\n if (this.#initializing.get(plugin.name) === initializing) {\n this.#initializing.delete(plugin.name);\n }\n }\n\n this.#plugins.set(plugin.name, { plugin, scope });\n this.#log(`plugin \"${plugin.name}\" registered`);\n }\n\n /** A refused plugin is an integration mistake; it reaches the `error` event, not only the log. */\n #refuse(name: string, reason: string): void {\n const message = `plugin \"${name}\" refused: ${reason}`;\n this.#log(message);\n void this.#events.emit('error', {\n error: new Error(message),\n context: 'plugin',\n code: 'LP0103',\n });\n }\n\n #createContext(pluginName: string, scope: ResourceScope): PluginContext {\n return {\n events: new ScopedPluginEvents(this.#events, scope),\n registerFieldRenderer: (renderer) => {\n scope.stage('renderer', () => {\n const result = this.#registerRenderer(renderer);\n return isPluginDisposer(result) ? result : undefined;\n });\n },\n registerTransform: (fieldName, transform) => {\n const registration: TransformRegistration = { transform, active: false };\n scope.stage('transform', () => {\n registration.active = true;\n const existing = this.#transforms.get(fieldName);\n if (existing === undefined) this.#transforms.set(fieldName, [registration]);\n else existing.push(registration);\n\n return () => {\n registration.active = false;\n const current = this.#transforms.get(fieldName);\n if (current === undefined) return;\n const index = current.indexOf(registration);\n if (index >= 0) current.splice(index, 1);\n if (current.length === 0) this.#transforms.delete(fieldName);\n };\n });\n },\n registerCleanup: (cleanup) => {\n scope.own(cleanup);\n },\n getConfig: () => this.#config,\n log: (...args) => {\n this.#log(`[${pluginName}]`, ...args);\n },\n };\n }\n\n #unregisterNow(name: string, queued: boolean): Promise<void> {\n const initializing = this.#initializing.get(name);\n if (initializing !== undefined) {\n initializing.cancelled = true;\n initializing.scope.close();\n return Promise.resolve();\n }\n\n const existingTeardown = this.#teardowns.get(name);\n if (existingTeardown !== undefined) {\n // A destroy hook removing its own name cannot await the teardown that\n // awaits it; its resources are already revoked, so this is complete.\n if (this.#destroying.has(name)) return Promise.resolve();\n return queued ? this.#holdQueue(existingTeardown) : existingTeardown;\n }\n const registration = this.#plugins.get(name);\n if (registration === undefined) return Promise.resolve();\n\n // Revoke before consumer code runs: a throwing destroy keeps no access,\n // and a same-name registration from inside destroy stays a duplicate.\n this.#plugins.delete(name);\n registration.scope.close();\n const teardown = Promise.resolve().then(() =>\n this.#destroyPlugin(name, registration.plugin, queued),\n );\n this.#teardowns.set(name, teardown);\n void teardown.then(() => {\n if (this.#teardowns.get(name) === teardown) this.#teardowns.delete(name);\n });\n return teardown;\n }\n\n async #destroyPlugin(name: string, plugin: LivePreviewPlugin, queued: boolean): Promise<void> {\n if (plugin.destroy === undefined) return;\n this.#destroying.add(name);\n try {\n await this.#runHook(() => plugin.destroy?.(), queued);\n } catch (error) {\n this.#log(`plugin \"${name}\" destroy failed:`, error);\n } finally {\n this.#destroying.delete(name);\n }\n }\n\n async #destroyAllNow(queued: boolean): Promise<void> {\n for (const initializing of this.#initializing.values()) {\n initializing.cancelled = true;\n initializing.scope.close();\n }\n const names = [...this.#plugins.keys()];\n for (const name of names) await this.#unregisterNow(name, queued);\n }\n\n async #runHook(hook: () => void | Promise<void>, queued: boolean): Promise<void> {\n if (!queued) {\n await hook();\n return;\n }\n await this.#holdQueue(Promise.resolve().then(hook));\n }\n\n async #holdQueue(pending: Promise<void>): Promise<void> {\n this.#queuedHooks += 1;\n try {\n await pending;\n } finally {\n this.#queuedHooks -= 1;\n }\n }\n\n #enqueue(operation: () => void | Promise<void>): Promise<void> {\n const result = this.#mutationQueue.then(operation);\n // Keep the tail usable after an escaped error; the caller still sees it on `result`.\n this.#mutationQueue = result.catch((error: unknown) => {\n this.#log('plugin manager mutation failed:', error);\n });\n return result;\n }\n}\n","/**\n * Plugin compatibility claims. The range grammar is the subset a plugin\n * author writes (`*`, `1.2.3`, `^`, `~`, `>=`, `>`, `<`, `<=`, space-joined\n * conjunctions, `||` alternatives); prerelease tags are ignored.\n */\n\nexport interface PluginCompatibility {\n /** A semver range the runtime's `VERSION` must satisfy, e.g. `>=2.0.0`. */\n readonly runtime?: string;\n /** The highest postMessage protocol version the plugin understands. */\n readonly protocol?: number;\n}\n\ntype Version = readonly [number, number, number];\n\nfunction parseVersion(text: string): Version | undefined {\n const match = /^v?(\\d+)\\.(\\d+)\\.(\\d+)/.exec(text.trim());\n if (match === null) return undefined;\n return [Number(match[1]), Number(match[2]), Number(match[3])];\n}\n\nfunction compare(a: Version, b: Version): number {\n for (let index = 0; index < 3; index += 1) {\n const delta = (a[index] ?? 0) - (b[index] ?? 0);\n if (delta !== 0) return delta;\n }\n return 0;\n}\n\nfunction satisfiesComparator(version: Version, comparator: string): boolean {\n const trimmed = comparator.trim();\n if (trimmed === '' || trimmed === '*') return true;\n const match = /^(\\^|~|>=|<=|>|<|=)?\\s*v?(\\d+)\\.(\\d+)\\.(\\d+)/.exec(trimmed);\n if (match === null) return false;\n const operator = match[1] ?? '=';\n const target: Version = [Number(match[2]), Number(match[3]), Number(match[4])];\n const order = compare(version, target);\n switch (operator) {\n case '=':\n return order === 0;\n case '>':\n return order > 0;\n case '>=':\n return order >= 0;\n case '<':\n return order < 0;\n case '<=':\n return order <= 0;\n case '~':\n return order >= 0 && version[0] === target[0] && version[1] === target[1];\n case '^':\n if (order < 0) return false;\n if (target[0] > 0) return version[0] === target[0];\n if (target[1] > 0) return version[0] === 0 && version[1] === target[1];\n return version[0] === 0 && version[1] === 0 && version[2] === target[2];\n default:\n return false;\n }\n}\n\n/** Whether `version` satisfies `range`; anything unparsable never satisfies. */\nexport function satisfiesRange(version: string, range: string): boolean {\n const parsed = parseVersion(version);\n if (parsed === undefined) return false;\n const alternatives = range.split('||');\n return alternatives.some((alternative) => {\n const comparators = alternative\n .trim()\n .split(/\\s+/)\n .filter((part) => part.length > 0);\n if (comparators.length === 0) return alternative.trim() === '' && range.trim() === '';\n return comparators.every((comparator) => satisfiesComparator(parsed, comparator));\n });\n}\n\n/** Why a plugin was refused, or `undefined` when it fits. */\nexport function incompatibilityOf(\n compat: PluginCompatibility | undefined,\n runtimeVersion: string,\n protocolVersion: number,\n): string | undefined {\n if (compat === undefined) return undefined;\n if (compat.runtime !== undefined && !satisfiesRange(runtimeVersion, compat.runtime)) {\n return `declares runtime ${compat.runtime}, this runtime is ${runtimeVersion}`;\n }\n if (compat.protocol !== undefined) {\n if (!Number.isInteger(compat.protocol) || compat.protocol < 1) {\n return `declares an invalid protocol version ${String(compat.protocol)}`;\n }\n if (compat.protocol < protocolVersion) {\n return `declares protocol ${String(compat.protocol)}, this runtime speaks ${String(protocolVersion)}`;\n }\n }\n return undefined;\n}\n","/**\n * Per-client renderer layers: built-ins are the base, plugin registrations\n * stack above per field type, and removing a layer by identity reveals the\n * one beneath. See ADR 0005.\n */\n\nimport type { FieldRenderer, RendererKey } from '@core/types';\nimport type { PluginDisposer } from './types';\n\ninterface RendererLayer {\n readonly renderer: FieldRenderer;\n}\n\nexport class RendererRegistry {\n readonly #base: Readonly<Record<string, FieldRenderer>>;\n readonly #active: Record<string, FieldRenderer>;\n readonly #layers = new Map<RendererKey, RendererLayer[]>();\n\n constructor(base: Readonly<Record<string, FieldRenderer>>) {\n this.#base = base;\n this.#active = { ...base };\n }\n\n /** Stable live map, retained for the runtime's `renderers` option. */\n get renderers(): Readonly<Record<string, FieldRenderer>> {\n return this.#active;\n }\n\n resolve(fieldType: RendererKey): FieldRenderer | undefined {\n return this.#active[fieldType];\n }\n\n register(renderer: FieldRenderer): PluginDisposer {\n const fieldType = renderer.name;\n const layer: RendererLayer = { renderer };\n const stack = this.#layers.get(fieldType);\n if (stack === undefined) this.#layers.set(fieldType, [layer]);\n else stack.push(layer);\n this.#active[fieldType] = renderer;\n\n let active = true;\n return () => {\n if (!active) return;\n active = false;\n\n const current = this.#layers.get(fieldType);\n if (current === undefined) return;\n const index = current.indexOf(layer);\n if (index < 0) return;\n const wasTop = index === current.length - 1;\n current.splice(index, 1);\n if (current.length === 0) this.#layers.delete(fieldType);\n if (!wasTop) return;\n\n const previousLayer = current.at(-1);\n const previousRenderer = previousLayer?.renderer ?? this.#base[fieldType];\n if (previousRenderer === undefined) Reflect.deleteProperty(this.#active, fieldType);\n else this.#active[fieldType] = previousRenderer;\n };\n }\n}\n","/** Attribute helpers shared by the block-level node renderers. */\n\nimport type { LexicalNode } from './types';\n\nconst ALIGNMENT_NUMERIC: Readonly<Record<number, string>> = {\n 1: 'left',\n 2: 'center',\n 3: 'right',\n 4: 'justify',\n};\n\nconst ALIGNMENT_STRING = new Set(['left', 'center', 'right', 'justify', 'start', 'end']);\n\n/** Alignment of a block node; Payload emits it as a string or as Lexical's numeric format. */\nexport function resolveAlignment(node: LexicalNode): string | undefined {\n const fmt = node.format;\n if (typeof fmt === 'string' && ALIGNMENT_STRING.has(fmt)) return fmt;\n if (typeof fmt === 'number') return ALIGNMENT_NUMERIC[fmt];\n return undefined;\n}\n\nexport function resolveIndent(node: LexicalNode): number {\n const indent = node.indent;\n return typeof indent === 'number' && indent > 0 ? indent : 0;\n}\n\nexport function dirAttribute(node: LexicalNode): string {\n if (node.direction === 'rtl') return ' dir=\"rtl\"';\n if (node.direction === 'ltr') return ' dir=\"ltr\"';\n return '';\n}\n\n/**\n * Alignment and indent as `lp-align-*` / `lp-indent-N` classes. The sanitizer\n * strips `style` under every policy, so inline CSS would never reach the page.\n */\nexport function layoutClassAttribute(node: LexicalNode): string {\n const align = resolveAlignment(node);\n const indent = resolveIndent(node);\n const classes: string[] = [];\n if (align !== undefined) classes.push(`lp-align-${align}`);\n if (indent > 0) classes.push(`lp-indent-${String(indent)}`);\n return classes.length === 0 ? '' : ` class=\"${classes.join(' ')}\"`;\n}\n","import type { NodeRenderer } from '../registry';\nimport { dirAttribute, layoutClassAttribute } from '../utils';\n\nconst paragraphRenderer: NodeRenderer = (node, ctx): string => {\n const children = ctx.renderChildren(node.children ?? []);\n return `<p${dirAttribute(node)}${layoutClassAttribute(node)}>${children}</p>`;\n};\n\nexport { paragraphRenderer };\n","/** `heading` renderer; an unknown `tag` (transient editor states emit them) falls back to `h2`. */\n\nimport type { NodeRenderer } from '../registry';\nimport { dirAttribute, layoutClassAttribute } from '../utils';\n\nconst VALID_TAGS = new Set(['h1', 'h2', 'h3', 'h4', 'h5', 'h6']);\n\nconst headingRenderer: NodeRenderer = (node, ctx): string => {\n const tagRaw = typeof node['tag'] === 'string' ? node['tag'].toLowerCase() : 'h2';\n const tag = VALID_TAGS.has(tagRaw) ? tagRaw : 'h2';\n const children = ctx.renderChildren(node.children ?? []);\n return `<${tag}${dirAttribute(node)}${layoutClassAttribute(node)}>${children}</${tag}>`;\n};\n\nexport { headingRenderer };\n","/**\n * Value-shape helpers shared by the Lexical node renderers and the field\n * renderers. They live here because `field-types` may import `lexical`, never\n * the reverse (scripts/architecture-policy.ts).\n */\n\nexport interface MediaShape {\n readonly id?: string | number;\n readonly url?: string;\n readonly alt?: string;\n readonly filename?: string;\n readonly mimeType?: string;\n readonly width?: number;\n readonly height?: number;\n readonly sizes?: Readonly<\n Record<string, { readonly url?: string; readonly width?: number; readonly height?: number }>\n >;\n}\n\nexport interface RelationShape {\n readonly id?: string | number;\n readonly title?: string;\n readonly name?: string;\n readonly slug?: string;\n readonly url?: string;\n}\n\nexport function asRecord(value: unknown): Record<string, unknown> | undefined {\n return typeof value === 'object' && value !== null\n ? (value as Record<string, unknown>)\n : undefined;\n}\n\nexport function readMedia(value: unknown): MediaShape | undefined {\n return asRecord(value);\n}\n\n/** Reduce `value` to `[a-z0-9_-]` so it can be a class-name fragment without escaping. */\nexport function sanitizeIdent(value: string): string {\n return value.replace(/[^a-zA-Z0-9_-]/g, '-').toLowerCase();\n}\n\nfunction nonEmpty(value: unknown): string | undefined {\n return typeof value === 'string' && value.length > 0 ? value : undefined;\n}\n\n/** Label precedence for a populated relation: `title`, `name`, `slug`, then `id`. */\nexport function pickRelationLabel(value: RelationShape): string | undefined {\n const label = nonEmpty(value.title) ?? nonEmpty(value.name) ?? nonEmpty(value.slug);\n if (label !== undefined) return label;\n return value.id === undefined ? undefined : String(value.id);\n}\n","/**\n * `link` / `autolink` renderer. Payload 3.x serialises links as\n * `{ fields: { linkType, url, newTab, doc } }`; vanilla Lexical puts `url`\n * and `target` on the node itself. Both shapes are read, Payload's first.\n */\n\nimport { escapeHtml, escapeHtmlAttribute } from '@security/escape';\nimport { isExternalHttpUrl, isSafeUrl } from '@security/url-validator';\nimport type { NodeRenderer } from '../registry';\nimport type { LexicalNode } from '../types';\nimport { asRecord } from '../value-shapes';\n\nconst BLANK_TARGET = ' target=\"_blank\" rel=\"noopener noreferrer\"';\n\nconst linkRenderer: NodeRenderer = (node, ctx): string => {\n const children = ctx.renderChildren(node.children ?? []);\n const fields = asRecord(node['fields']);\n const url = resolveUrl(node, fields);\n if (url === undefined || !isSafeUrl(url)) return children;\n const titleAttr =\n typeof node['title'] === 'string' ? ` title=\"${escapeHtml(node['title'])}\"` : '';\n return `<a href=\"${escapeHtmlAttribute(url)}\"${targetAttribute(node, fields, url)}${titleAttr}>${children}</a>`;\n};\n\nfunction resolveUrl(\n node: LexicalNode,\n fields: Record<string, unknown> | undefined,\n): string | undefined {\n if (fields?.['linkType'] === 'internal') return internalUrl(fields['doc']);\n const url = fields?.['url'] ?? node['url'];\n return typeof url === 'string' && url.length > 0 ? url : undefined;\n}\n\n/** An internal link needs the populated document; a bare id has no route to offer. */\nfunction internalUrl(doc: unknown): string | undefined {\n const value = asRecord(asRecord(doc)?.['value']);\n const url = value?.['url'];\n if (typeof url === 'string' && url.length > 0) return url;\n const slug = value?.['slug'];\n return typeof slug === 'string' && slug.length > 0 ? `/${slug}` : undefined;\n}\n\n/** `_blank` always carries `noopener noreferrer`, whichever side asked for it. */\nfunction targetAttribute(\n node: LexicalNode,\n fields: Record<string, unknown> | undefined,\n url: string,\n): string {\n if (fields?.['newTab'] === true || isExternalHttpUrl(url)) return BLANK_TARGET;\n const target = typeof node['target'] === 'string' ? node['target'] : '';\n if (target === '') return '';\n if (target === '_blank') return BLANK_TARGET;\n return ` target=\"${escapeHtml(target)}\"`;\n}\n\nexport { linkRenderer };\n","/** `code` (fenced block) and `code-highlight` (token span) renderers. */\n\nimport { escapeHtml } from '@security/escape';\nimport type { NodeRenderer } from '../registry';\nimport type { LexicalNode } from '../types';\nimport { sanitizeIdent } from '../value-shapes';\n\nconst codeRenderer: NodeRenderer = (node): string => {\n const language = sanitizeIdent(typeof node['language'] === 'string' ? node['language'] : '');\n const langClass = language === '' ? '' : ` class=\"language-${language}\"`;\n return `<pre><code${langClass}>${escapeHtml(extractText(node))}</code></pre>`;\n};\n\nconst codeHighlightRenderer: NodeRenderer = (node): string => {\n const text = typeof node.text === 'string' ? node.text : '';\n const highlight =\n typeof node['highlightType'] === 'string'\n ? ` class=\"token-${sanitizeIdent(node['highlightType'])}\"`\n : '';\n return `<span${highlight}>${escapeHtml(text)}</span>`;\n};\n\nexport { codeRenderer, codeHighlightRenderer };\n\nfunction extractText(node: LexicalNode): string {\n if (typeof node.text === 'string') return node.text;\n if (!node.children) return '';\n let out = '';\n for (const child of node.children) out += extractText(child);\n return out;\n}\n","/**\n * `upload` renderer: `<img>` for image (or unknown) MIME types, `<video>` /\n * `<audio>` for media, a download link otherwise. An unsafe URL renders nothing.\n */\n\nimport { escapeHtml, escapeHtmlAttribute } from '@security/escape';\nimport { isSafeUrl } from '@security/url-validator';\nimport type { NodeRenderer } from '../registry';\nimport { readMedia, type MediaShape } from '../value-shapes';\n\nconst uploadRenderer: NodeRenderer = (node): string => {\n const value = readMedia(node['value']);\n if (value === undefined) return '';\n const url = value.url;\n if (typeof url !== 'string' || !isSafeUrl(url)) return '';\n\n const mime = typeof value.mimeType === 'string' ? value.mimeType : '';\n if (mime.startsWith('video/')) return renderVideo(value, url);\n if (mime.startsWith('audio/')) return renderAudio(value, url);\n if (mime === '' || mime.startsWith('image/')) return renderImage(value, url);\n return renderFallbackLink(value, url);\n};\n\nexport { uploadRenderer };\n\nfunction dimensionAttributes(value: MediaShape): string {\n const width = typeof value.width === 'number' ? ` width=\"${String(value.width)}\"` : '';\n const height = typeof value.height === 'number' ? ` height=\"${String(value.height)}\"` : '';\n return `${width}${height}`;\n}\n\nfunction typeAttribute(value: MediaShape): string {\n return typeof value.mimeType === 'string' ? ` type=\"${escapeHtmlAttribute(value.mimeType)}\"` : '';\n}\n\nfunction renderImage(value: MediaShape, url: string): string {\n const alt = typeof value.alt === 'string' ? escapeHtml(value.alt) : '';\n return `<img src=\"${escapeHtmlAttribute(url)}\" alt=\"${alt}\"${dimensionAttributes(value)} loading=\"lazy\" decoding=\"async\">`;\n}\n\nfunction renderVideo(value: MediaShape, url: string): string {\n return `<video controls${dimensionAttributes(value)}><source src=\"${escapeHtmlAttribute(url)}\"${typeAttribute(value)}></video>`;\n}\n\nfunction renderAudio(value: MediaShape, url: string): string {\n return `<audio controls><source src=\"${escapeHtmlAttribute(url)}\"${typeAttribute(value)}></audio>`;\n}\n\nfunction renderFallbackLink(value: MediaShape, url: string): string {\n const label = typeof value.filename === 'string' ? escapeHtml(value.filename) : escapeHtml(url);\n return `<a href=\"${escapeHtmlAttribute(url)}\" target=\"_blank\" rel=\"noopener noreferrer\">${label}</a>`;\n}\n","/** `relationship` renderer: a link when the populated document carries a URL, a span otherwise. */\n\nimport { escapeHtml, escapeHtmlAttribute } from '@security/escape';\nimport { isSafeUrl } from '@security/url-validator';\nimport type { NodeRenderer } from '../registry';\nimport { asRecord, pickRelationLabel, sanitizeIdent, type RelationShape } from '../value-shapes';\n\nconst relationshipRenderer: NodeRenderer = (node): string => {\n const relationTo = typeof node['relationTo'] === 'string' ? node['relationTo'] : '';\n const value = asRecord(node['value']) as RelationShape | undefined;\n const label = escapeHtml((value && pickRelationLabel(value)) ?? `#${relationTo}`);\n const slug = sanitizeIdent(relationTo);\n const classAttr =\n slug === '' ? ' class=\"lp-relation\"' : ` class=\"lp-relation lp-relation--${slug}\"`;\n const url = value?.url;\n if (typeof url === 'string' && isSafeUrl(url)) {\n return `<a href=\"${escapeHtmlAttribute(url)}\"${classAttr}>${label}</a>`;\n }\n return `<span${classAttr}>${label}</span>`;\n};\n\nexport { relationshipRenderer };\n","/** Block-renderer registry keyed by Payload block slug; consulted by the `block` and `inlineBlock` nodes. */\n\nimport type { LexicalNode } from '../types';\n\nexport interface BlockRenderContext {\n /** Render nested Lexical content through the node registry. */\n readonly renderChildren: (children: readonly LexicalNode[]) => string;\n}\n\n/** Receives the block's `fields` (with `blockType`) and returns HTML. */\nexport type BlockRenderer = (\n fields: Record<string, unknown>,\n context: BlockRenderContext,\n) => string;\n\nconst registry = new Map<string, BlockRenderer>();\n\n/** Register or replace the renderer for `blockType`. */\nexport function registerBlockRenderer(blockType: string, renderer: BlockRenderer): void {\n registry.set(blockType, renderer);\n}\n\n/** @internal */\nexport function lookupBlockRenderer(blockType: string): BlockRenderer | undefined {\n return registry.get(blockType);\n}\n\n/** @internal */\nexport function registeredBlockTypes(): readonly string[] {\n return [...registry.keys()];\n}\n\n/** Test-only: clear the registry. */\nexport function __resetBlockRegistryForTests(): void {\n registry.clear();\n}\n","/**\n * `block` and `inlineBlock` renderers for Payload's BlocksFeature. The block\n * registry is consulted first; without a renderer for the slug the node becomes\n * an empty, class-tagged element a consumer can style or replace.\n *\n * That element is a placeholder, not a rendering. `UNRENDERED_BLOCK_SELECTOR`\n * names it so the write path can keep the markup the server already rendered\n * for the block in its place, instead of replacing a figure and its image with\n * an empty div (LP0410). Whether that succeeds is decided there, not here: this\n * renderer only tells the context which slug it had no renderer for, and the\n * write says what became of it (LP0410 kept, LP0413 lost).\n */\n\nimport { lookupBlockRenderer } from '../blocks/registry';\nimport type { NodeRenderer, RenderNodeContext } from '../registry';\nimport type { LexicalNode } from '../types';\nimport { asRecord, sanitizeIdent } from '../value-shapes';\n\n/**\n * The placeholders above, in the rendered tree. Both are empty by construction,\n * and a registered renderer's output is not: it carries the block's content and\n * its own class (`lp-block-callout`, …).\n */\nexport const UNRENDERED_BLOCK_SELECTOR = '.lp-block:empty,.lp-inline-block:empty';\n\nfunction renderBlockNode(\n node: LexicalNode,\n ctx: RenderNodeContext,\n tag: 'div' | 'span',\n baseClass: string,\n): string {\n const fields = asRecord(node['fields']) ?? {};\n const blockType = typeof fields['blockType'] === 'string' ? fields['blockType'] : '';\n const slug = sanitizeIdent(blockType);\n const classes = slug === '' ? baseClass : `${baseClass} ${baseClass}--${slug}`;\n if (blockType !== '') {\n const custom = lookupBlockRenderer(blockType) ?? lookupBlockRenderer(slug);\n if (custom) return custom(fields, { renderChildren: ctx.renderChildren });\n // The real slug is known only here — the class carries `sanitizeIdent(slug)`,\n // and a hint that names the wrong one to register is no hint.\n ctx.onUnrenderedBlock?.(blockType, classes);\n }\n return `<${tag} class=\"${classes}\"></${tag}>`;\n}\n\nconst blockRenderer: NodeRenderer = (node, ctx) => renderBlockNode(node, ctx, 'div', 'lp-block');\n\nconst inlineBlockRenderer: NodeRenderer = (node, ctx) =>\n renderBlockNode(node, ctx, 'span', 'lp-inline-block');\n\nexport { blockRenderer, inlineBlockRenderer };\n","/** `table` / `tablerow` / `tablecell` renderers for the `@lexical/table` shapes Payload's table feature emits. */\n\nimport type { NodeRenderer } from '../registry';\nimport { dirAttribute } from '../utils';\n\n// `@lexical/table` TableCellHeaderStates: ROW marks a cell in a header row, COLUMN one in a header column.\nconst HEADER_ROW = 1;\nconst HEADER_COLUMN = 2;\n\nconst tableRenderer: NodeRenderer = (node, ctx) =>\n `<table${dirAttribute(node)}><tbody>${ctx.renderChildren(node.children ?? [])}</tbody></table>`;\n\nconst tableRowRenderer: NodeRenderer = (node, ctx) =>\n `<tr>${ctx.renderChildren(node.children ?? [])}</tr>`;\n\nconst tableCellRenderer: NodeRenderer = (node, ctx): string => {\n const header = typeof node['headerState'] === 'number' ? node['headerState'] : 0;\n const tag = (header & (HEADER_ROW | HEADER_COLUMN)) === 0 ? 'td' : 'th';\n const scope =\n header === HEADER_ROW ? ' scope=\"col\"' : header === HEADER_COLUMN ? ' scope=\"row\"' : '';\n return `<${tag}${scope}${spanAttribute('colspan', node['colSpan'])}${spanAttribute('rowspan', node['rowSpan'])}>${ctx.renderChildren(node.children ?? [])}</${tag}>`;\n};\n\nfunction spanAttribute(name: string, value: unknown): string {\n return typeof value === 'number' && value > 1 ? ` ${name}=\"${String(value)}\"` : '';\n}\n\nexport { tableRenderer, tableRowRenderer, tableCellRenderer };\n","import type { NodeRenderer } from '../registry';\nimport { textRenderer } from './text';\nimport { paragraphRenderer } from './paragraph';\nimport { headingRenderer } from './heading';\nimport { listRenderer, listItemRenderer } from './list';\nimport { linkRenderer } from './link';\nimport { quoteRenderer } from './quote';\nimport { codeRenderer, codeHighlightRenderer } from './code';\nimport { linebreakRenderer, horizontalRuleRenderer, tabRenderer } from './linebreak';\nimport { uploadRenderer } from './upload';\nimport { relationshipRenderer } from './relationship';\nimport { blockRenderer, inlineBlockRenderer } from './block';\nimport { tableCellRenderer, tableRenderer, tableRowRenderer } from './table';\n\n// A value table instead of `register()` calls at import time: a consumer that\n// never renders Lexical content must not carry these under `sideEffects: false`.\nexport const BUILTIN_NODE_RENDERERS: Readonly<Record<string, NodeRenderer>> = {\n text: textRenderer,\n paragraph: paragraphRenderer,\n heading: headingRenderer,\n list: listRenderer,\n listitem: listItemRenderer,\n link: linkRenderer,\n autolink: linkRenderer,\n quote: quoteRenderer,\n code: codeRenderer,\n 'code-highlight': codeHighlightRenderer,\n linebreak: linebreakRenderer,\n horizontalrule: horizontalRuleRenderer,\n tab: tabRenderer,\n upload: uploadRenderer,\n relationship: relationshipRenderer,\n block: blockRenderer,\n inlineBlock: inlineBlockRenderer,\n table: tableRenderer,\n tablerow: tableRowRenderer,\n tablecell: tableCellRenderer,\n};\n","/** `text` renderer. Format flags wrap in a fixed order so equal input gives byte-equal output. */\n\nimport { escapeHtml } from '@security/escape';\nimport type { LexicalNode } from '../types';\nimport { TextFormat } from '../types';\nimport type { NodeRenderer } from '../registry';\n\nconst textRenderer: NodeRenderer = (node: LexicalNode): string => {\n const raw = typeof node.text === 'string' ? node.text : '';\n let out = escapeHtml(raw);\n const format = typeof node.format === 'number' ? node.format : 0;\n if ((format & TextFormat.CODE) !== 0) out = `<code>${out}</code>`;\n if ((format & TextFormat.BOLD) !== 0) out = `<strong>${out}</strong>`;\n if ((format & TextFormat.ITALIC) !== 0) out = `<em>${out}</em>`;\n if ((format & TextFormat.UNDERLINE) !== 0) out = `<u>${out}</u>`;\n if ((format & TextFormat.STRIKETHROUGH) !== 0) out = `<s>${out}</s>`;\n if ((format & TextFormat.SUBSCRIPT) !== 0) out = `<sub>${out}</sub>`;\n if ((format & TextFormat.SUPERSCRIPT) !== 0) out = `<sup>${out}</sup>`;\n if ((format & TextFormat.HIGHLIGHT) !== 0) out = `<mark>${out}</mark>`;\n return out;\n};\n\nexport { textRenderer };\n","/**\n * Lexical document types. Only `type` and `children` are required; every\n * other property is forwarded opaquely to the renderer for that node type.\n */\n\n/** Lexical text-format bitmask; flags combine (`BOLD | ITALIC === 3`). @internal */\nexport const TextFormat = {\n BOLD: 1,\n ITALIC: 2,\n STRIKETHROUGH: 4,\n UNDERLINE: 8,\n CODE: 16,\n SUBSCRIPT: 32,\n SUPERSCRIPT: 64,\n HIGHLIGHT: 128,\n} as const;\n\nexport interface LexicalNode {\n readonly type: string;\n readonly version?: number;\n readonly format?: number | string;\n readonly indent?: number;\n readonly direction?: 'ltr' | 'rtl' | null;\n readonly children?: readonly LexicalNode[];\n readonly text?: string;\n readonly [extra: string]: unknown;\n}\n\nexport interface LexicalRoot {\n readonly root: {\n readonly type?: string;\n readonly children: readonly LexicalNode[];\n readonly direction?: 'ltr' | 'rtl' | null;\n readonly format?: number | string;\n readonly indent?: number;\n readonly [extra: string]: unknown;\n };\n}\n","/** `list` / `listitem` renderers: `bullet` → `<ul>`, `number` → `<ol>`, `check` → `<ul role=\"list\">` with `aria-checked` items. */\n\nimport { escapeHtml } from '@security/escape';\nimport type { NodeRenderer } from '../registry';\nimport { dirAttribute, layoutClassAttribute } from '../utils';\n\nconst listRenderer: NodeRenderer = (node, ctx): string => {\n const listType = typeof node['listType'] === 'string' ? node['listType'] : 'bullet';\n const tag = listType === 'number' ? 'ol' : 'ul';\n const startAttr =\n listType === 'number' && typeof node['start'] === 'number' && node['start'] > 1\n ? ` start=\"${String(node['start'])}\"`\n : '';\n const checkAttr = listType === 'check' ? ' role=\"list\"' : '';\n const children = ctx.renderChildren(node.children ?? []);\n return `<${tag}${dirAttribute(node)}${layoutClassAttribute(node)}${startAttr}${checkAttr}>${children}</${tag}>`;\n};\n\nconst listItemRenderer: NodeRenderer = (node, ctx): string => {\n const children = ctx.renderChildren(node.children ?? []);\n if (typeof node['checked'] === 'boolean') {\n const state = node['checked'] ? 'true' : 'false';\n return `<li role=\"checkbox\" aria-checked=\"${state}\"${layoutClassAttribute(node)}>${children}</li>`;\n }\n const valueAttr =\n typeof node['value'] === 'number' ? ` value=\"${escapeHtml(String(node['value']))}\"` : '';\n return `<li${dirAttribute(node)}${layoutClassAttribute(node)}${valueAttr}>${children}</li>`;\n};\n\nexport { listRenderer, listItemRenderer };\n","import type { NodeRenderer } from '../registry';\nimport { dirAttribute, layoutClassAttribute } from '../utils';\n\nconst quoteRenderer: NodeRenderer = (node, ctx): string => {\n const children = ctx.renderChildren(node.children ?? []);\n return `<blockquote${dirAttribute(node)}${layoutClassAttribute(node)}>${children}</blockquote>`;\n};\n\nexport { quoteRenderer };\n","import type { NodeRenderer } from '../registry';\n\nconst linebreakRenderer: NodeRenderer = () => '<br>';\nconst horizontalRuleRenderer: NodeRenderer = () => '<hr>';\nconst tabRenderer: NodeRenderer = () => '\\t';\n\nexport { linebreakRenderer, horizontalRuleRenderer, tabRenderer };\n","/** Node-renderer registry: consumer registrations layered over the built-in table. */\n\nimport type { LexicalNode } from './types';\nimport { BUILTIN_NODE_RENDERERS } from './nodes/builtin';\n\nexport interface RenderNodeContext {\n /** Render child nodes through the registry. */\n readonly renderChildren: (children: readonly LexicalNode[]) => string;\n /** Text alignment of a block node, or `undefined`. */\n readonly resolveAlignment: (node: LexicalNode) => string | undefined;\n /** Indent level of a node, `0` when none. */\n readonly resolveIndent: (node: LexicalNode) => number;\n /**\n * Where a `block` or `inlineBlock` without a renderer is reported, with the\n * slug Payload sent and the class of the placeholder written in its place.\n * `undefined` on a plain `lexicalToHtml()` call; the `richText` write sets it.\n */\n readonly onUnrenderedBlock?: ((blockType: string, placeholderClass: string) => void) | undefined;\n}\n\nexport type NodeRenderer = (node: LexicalNode, context: RenderNodeContext) => string;\n\nconst registry = new Map<string, NodeRenderer>();\n\n/** Register or replace the renderer for `type`. */\nexport function register(type: string, renderer: NodeRenderer): void {\n registry.set(type, renderer);\n}\n\n/** @internal */\nexport function lookup(type: string): NodeRenderer | undefined {\n return registry.get(type) ?? BUILTIN_NODE_RENDERERS[type];\n}\n\nexport function registeredTypes(): readonly string[] {\n return [...new Set([...Object.keys(BUILTIN_NODE_RENDERERS), ...registry.keys()])];\n}\n\n/** Test-only: drop consumer registrations. */\nexport function __resetForTests(): void {\n registry.clear();\n}\n","/**\n * Lexical → HTML. Each node dispatches to the renderer registered for its\n * `type`; an unknown node renders its children so content is never lost.\n */\n\nimport { sanitizeHtml, hasSanitizerDocument } from '@security/sanitizer';\nimport { lookup, type RenderNodeContext } from './registry';\nimport type { LexicalNode, LexicalRoot } from './types';\nimport { resolveAlignment, resolveIndent } from './utils';\n\nexport interface LexicalRenderOptions {\n /** Pass the result through `sanitizeHtml()` (default `true`). */\n readonly sanitize?: boolean;\n /**\n * Called for every `block` or `inlineBlock` the registry has no renderer\n * for, with the block's slug as Payload sent it and the class its empty\n * placeholder carries. The `richText` write listens: it is the one caller\n * that later knows whether the server's markup for the block survived, so\n * the diagnostic is spoken there (LP0410, LP0413), not here.\n */\n readonly onUnrenderedBlock?: (blockType: string, placeholderClass: string) => void;\n}\n\nlet warnedNoSanitizer = false;\n\n/** @internal */\nexport function isLexicalContent(value: unknown): value is LexicalRoot {\n if (typeof value !== 'object' || value === null) return false;\n if (!('root' in value)) return false;\n const root = value.root;\n if (typeof root !== 'object' || root === null) return false;\n if (!('children' in root)) return false;\n return Array.isArray(root.children);\n}\n\n/** Render a Lexical document to HTML; without `setSanitizerDocument()` the result is unsanitised and warns once. */\nexport function lexicalToHtml(content: LexicalRoot, options: LexicalRenderOptions = {}): string {\n if (!isLexicalContent(content)) return '';\n const html = createContext(options.onUnrenderedBlock).renderChildren(content.root.children);\n if (options.sanitize === false) return html;\n if (hasSanitizerDocument()) return sanitizeHtml(html);\n warnNoSanitizerOnce();\n return html;\n}\n\n/** Plain text of a document, paragraphs separated by `\\n`. */\nexport function lexicalToPlainText(content: LexicalRoot): string {\n if (!isLexicalContent(content)) return '';\n return content.root.children.map(extractPlainText).join('\\n').trim();\n}\n\n/** Test-only: allow the SSR warning to fire again. */\nexport function __resetSanitizerWarningForTests(): void {\n warnedNoSanitizer = false;\n}\n\n/**\n * One context per document: `renderChildren` closes over it so a nested\n * block — a `block` inside a list item, an `inlineBlock` inside a paragraph —\n * reports to the same listener as a top-level one.\n */\nfunction createContext(\n onUnrenderedBlock: RenderNodeContext['onUnrenderedBlock'],\n): RenderNodeContext {\n const context: RenderNodeContext = {\n renderChildren: (children) => {\n let out = '';\n for (const child of children) out += renderNode(child, context);\n return out;\n },\n resolveAlignment,\n resolveIndent,\n onUnrenderedBlock,\n };\n return context;\n}\n\nfunction renderNode(node: LexicalNode, context: RenderNodeContext): string {\n const renderer = lookup(node.type);\n if (renderer) return renderer(node, context);\n return node.children !== undefined ? context.renderChildren(node.children) : '';\n}\n\nfunction extractPlainText(node: LexicalNode): string {\n if (typeof node.text === 'string') return node.text;\n if (node.type === 'linebreak') return '\\n';\n if (node.children === undefined) return '';\n let out = '';\n for (const child of node.children) out += extractPlainText(child);\n return out;\n}\n\n// This layer may not import `@core/diagnostics` (architecture policy), so the\n// warn-once lives here; a hostile or absent console must not break rendering.\nfunction warnNoSanitizerOnce(): void {\n if (warnedNoSanitizer) return;\n warnedNoSanitizer = true;\n try {\n console.warn(\n '[live-preview] lexicalToHtml() has no sanitizer document and returned unsanitised HTML; ' +\n 'call setSanitizerDocument() (linkedom/jsdom) for server rendering, see \"HTML sanitization\" in docs/security.md.',\n );\n } catch {\n // Diagnostics never become a second failure.\n }\n}\n","/**\n * `text` / `textarea` renderer. An element with structured children is left\n * alone (warned once) unless it opts in with `data-payload-text`, so a styled\n * wrapper is not destroyed by a value meant for its text node.\n */\n\nimport { isLexicalContent, lexicalToPlainText } from '@lexical/render';\nimport { trustedHtml } from '@security/trusted-types';\nimport { escapeAndLinebreak } from '@security/escape';\nimport { safeConsoleWarn } from '@core/diagnostics';\nimport { markNoWriteCallback } from '@core/internal-outcome';\nimport type { FieldRenderer, RendererKey } from '@core/types';\n\nconst TEXT_OPT_IN_ATTRIBUTE = 'data-payload-text';\n\n/** Build the renderer with its own warn-once state; one per client (ADR 0002). */\nexport function createTextRenderer(name: RendererKey = 'text'): FieldRenderer {\n const warnedElements = new WeakSet<Element>();\n\n return {\n name,\n render: /* @__PURE__ */ markNoWriteCallback((target, value) => {\n const element = target.element;\n const text = toPlainString(value);\n if (element.tagName === 'INPUT' || element.tagName === 'TEXTAREA') {\n (element as HTMLInputElement | HTMLTextAreaElement).value = text;\n return;\n }\n if (hasForeignChildren(element) && !element.hasAttribute(TEXT_OPT_IN_ATTRIBUTE)) {\n warnOnce(warnedElements, element, target.fieldName);\n return false;\n }\n if (text.includes('\\n') || text.includes('\\r')) {\n element.innerHTML = trustedHtml(escapeAndLinebreak(text));\n return;\n }\n element.textContent = text;\n return;\n }),\n };\n}\n\n// `<br>` is this renderer's own multiline output, not a consumer wrapper;\n// counting it froze every multiline binding after its first write.\nfunction hasForeignChildren(element: Element): boolean {\n return element.querySelector(':scope > :not(br)') !== null;\n}\n\nfunction warnOnce(warnedElements: WeakSet<Element>, element: Element, fieldName: string): void {\n if (warnedElements.has(element)) return;\n warnedElements.add(element);\n safeConsoleWarn(\n `[live-preview] LP0402: Skipping text update for \"${fieldName}\": ` +\n `<${element.tagName.toLowerCase()}> has structured children. Move ` +\n `data-payload-field to the value element, or add data-payload-text to replace them.`,\n );\n}\n\nfunction toPlainString(value: unknown): string {\n if (value === null || value === undefined) return '';\n if (isLexicalContent(value)) return lexicalToPlainText(value);\n if (typeof value === 'string') return value;\n if (typeof value === 'number' || typeof value === 'boolean') return String(value);\n return JSON.stringify(value);\n}\n","/**\n * `richText` renderer: a Lexical root or an HTML string. A project\n * `renderRichText` takes precedence; its output is sanitised like every\n * other HTML write.\n *\n * The Lexical write keeps the markup the server rendered for a block the\n * registry cannot render, rather than replacing it with the empty placeholder\n * the node renderer produces for one, and it keeps the wrapper a template put\n * around the whole field. The verdict is spoken here, after the write, because\n * only the write knows it: LP0410 when the server's markup stands, LP0413 when\n * the two trees did not line up and it is gone — and the second goes through\n * `context.reportUnfaithful` too, which is the case `onUnfaithfulPatch`\n * escalates.\n */\n\nimport { isLexicalContent, lexicalToHtml } from '@lexical/render';\nimport { UNRENDERED_BLOCK_SELECTOR } from '@lexical/nodes/block';\nimport { trustedHtml } from '@security/trusted-types';\nimport { sanitizeHtmlWithPolicy } from '@security/sanitizer';\nimport { FIELD_ATTRIBUTE } from '@core/cache';\nimport { safeConsoleWarn } from '@core/diagnostics';\nimport { markNoWriteCallback } from '@core/internal-outcome';\nimport type { CachedElement, FieldRenderer, RenderContext } from '@core/types';\nimport { isEmptyValue } from './utils';\n\n/** Block slugs already reported, one set per verdict: a block kept once may still be lost later. */\nconst warnedKept = new Set<string>();\nconst warnedLost = new Set<string>();\n\n/** The containers a template wraps rich text in; Lexical renders none of them for content. */\nconst WRAPPER_TAGS: ReadonlySet<string> = new Set(['DIV', 'SECTION', 'ARTICLE']);\n\nconst richTextRenderer: FieldRenderer = {\n name: 'richText',\n render: /* @__PURE__ */ markNoWriteCallback((target, value, context) => {\n const element = target.element;\n if (isEmptyValue(value)) {\n element.textContent = '';\n return;\n }\n const policy = context.sanitizerPolicy;\n if (context.renderRichText !== undefined) {\n const html = context.renderRichText(value, {\n fieldName: target.fieldName,\n element,\n locale: context.locale,\n });\n element.innerHTML = trustedHtml(sanitizeHtmlWithPolicy(html, policy));\n return;\n }\n if (isLexicalContent(value)) {\n // Slug by placeholder class: the class is what the write finds standing.\n const unrendered = new Map<string, string>();\n const lexical = lexicalToHtml(value, {\n // Lexical would otherwise sanitise with the process default; the sink\n // below does it with the instance's policy instead.\n sanitize: false,\n onUnrenderedBlock: (blockType, placeholderClass) => {\n unrendered.set(placeholderClass, blockType);\n },\n });\n const verdicts = writeKeepingUnrenderedBlocks(\n element,\n sanitizeHtmlWithPolicy(lexical, policy),\n );\n for (const [placeholderClass, lost] of verdicts) {\n const blockType = unrendered.get(placeholderClass);\n if (blockType !== undefined) reportUnrenderedBlock(target, context, blockType, lost);\n }\n return;\n }\n if (typeof value === 'string') {\n element.innerHTML = trustedHtml(sanitizeHtmlWithPolicy(value, policy));\n return;\n }\n return false;\n }),\n};\n\n/**\n * Write `html` into `element`, but move the live element standing where an\n * unrendered block's placeholder stands over into the new tree first. Every\n * pairing is resolved before the first move: a move takes a child out of the\n * live element, which would shift the position each later one is read at.\n *\n * Returns a verdict per placeholder class: `false` where a live element that\n * was not itself a placeholder took the placeholder's place, `true` where one\n * is still standing over markup the element had — the descent found no\n * counterpart, so this write lost what the server drew for that block. No\n * verdict where there was nothing to keep: a container the page left empty,\n * or a placeholder an earlier write put there, whose loss was reported then.\n */\nfunction writeKeepingUnrenderedBlocks(\n element: Element,\n html: string,\n): ReadonlyMap<string, boolean> {\n const rendered = element.cloneNode(false) as Element;\n rendered.innerHTML = trustedHtml(html);\n const target = wrapperOf(element, rendered) ?? element;\n const verdicts = new Map<string, boolean>();\n const placeholders = rendered.querySelectorAll(UNRENDERED_BLOCK_SELECTOR);\n if (placeholders.length > 0 && target.firstElementChild !== null) {\n const pairs: [placeholder: Element, live: Element][] = [];\n pairUnrenderedBlocks(target, rendered, pairs);\n for (const [placeholder, live] of pairs) {\n placeholder.replaceWith(live);\n if (!live.matches(UNRENDERED_BLOCK_SELECTOR)) verdicts.set(placeholder.className, false);\n }\n // A placeholder the moves left in the tree is one no live element answered for.\n for (const placeholder of placeholders) {\n if (placeholder.parentNode !== null) verdicts.set(placeholder.className, true);\n }\n }\n target.replaceChildren(...rendered.childNodes);\n return verdicts;\n}\n\n/**\n * The one wrapper a template puts around rich text when the server renders it\n * — `<div class=\"prose\">` around the blocks, the usual Tailwind shape — or\n * `null` when the rendered document is written straight into `element`. The\n * wrapper stays, because the typography hangs on its class, and the pairing\n * runs inside it, where the blocks are; without this the live tree had one\n * child where the rendered one had five, and the descent stopped before it\n * reached the block (measured on the demo, Z29).\n *\n * A wrapper is the element's only child, of a kind Lexical does not render\n * content as, with no binding of its own, standing where the rendered document\n * has several elements — and unlike every one of them: a `<div>` a registered\n * block renders is content, and the paragraph typed after it must not be\n * written into it. One rendered element says nothing either way, and the\n * positional pairing already answers for that case.\n */\nfunction wrapperOf(element: Element, rendered: Element): Element | null {\n const child = element.firstElementChild;\n if (child?.nextElementSibling !== null || rendered.children.length < 2) return null;\n if (!WRAPPER_TAGS.has(child.tagName) || child.hasAttribute(FIELD_ATTRIBUTE)) return null;\n for (const block of rendered.children) {\n if (block.tagName === child.tagName && block.className === child.className) return null;\n }\n return child;\n}\n\n/**\n * Pair each placeholder with the live element in its position. Both trees\n * describe the same document, so position is the only key there is — the server\n * writes no id to match on. Descent stops where the child counts differ: the\n * two do not line up there, nothing is kept, and the placeholder is written,\n * which is what this renderer did before.\n */\nfunction pairUnrenderedBlocks(\n live: Element,\n rendered: Element,\n kept: [placeholder: Element, live: Element][],\n): void {\n if (live.children.length !== rendered.children.length) return;\n let liveChild = live.firstElementChild;\n let renderedChild = rendered.firstElementChild;\n // Nothing moves until every pairing is known, so walking siblings is stable.\n while (liveChild !== null && renderedChild !== null) {\n if (renderedChild.matches(UNRENDERED_BLOCK_SELECTOR)) kept.push([renderedChild, liveChild]);\n else pairUnrenderedBlocks(liveChild, renderedChild, kept);\n liveChild = liveChild.nextElementSibling;\n renderedChild = renderedChild.nextElementSibling;\n }\n}\n\n/**\n * Say what became of a block nobody registered a renderer for, once per slug\n * and verdict. Not through the runtime's `warn` option: a renderer has no\n * channel to it, and `RenderContext` carries the one thing that matters more —\n * the report that lets a strategy redraw the region the write just degraded.\n */\nfunction reportUnrenderedBlock(\n target: CachedElement,\n context: RenderContext,\n blockType: string,\n lost: boolean,\n): void {\n if (lost) {\n context.reportUnfaithful?.(target, `lost the markup the server drew for block \"${blockType}\"`);\n }\n const warned = lost ? warnedLost : warnedKept;\n if (warned.has(blockType)) return;\n warned.add(blockType);\n safeConsoleWarn(\n `[live-preview] ${\n lost\n ? `LP0413: no renderer for block \"${blockType}\", and the markup the server rendered for it is lost.`\n : `LP0410: no renderer for block \"${blockType}\"; keeping what the server rendered for it.`\n } Register one with registerBlockRenderer().`,\n );\n}\n\n/** Test-only: let LP0410 and LP0413 fire again. */\nexport function __resetBlockWarningsForTests(): void {\n warnedKept.clear();\n warnedLost.clear();\n}\n\nexport { richTextRenderer };\n","/** `html` renderer (`data-payload-type=\"html\"`): the value is sanitised, then injected. */\n\nimport { sanitizeHtmlWithPolicy } from '@security/sanitizer';\nimport { trustedHtml } from '@security/trusted-types';\nimport type { FieldRenderer } from '@core/types';\nimport { isEmptyValue, safeStringify } from './utils';\n\nconst htmlRenderer: FieldRenderer = {\n name: 'html',\n render(target, value, context) {\n if (isEmptyValue(value)) {\n target.element.textContent = '';\n return;\n }\n const html = typeof value === 'string' ? value : safeStringify(value);\n target.element.innerHTML = trustedHtml(sanitizeHtmlWithPolicy(html, context.sanitizerPolicy));\n },\n};\n\nexport { htmlRenderer };\n","/** URL acceptance shared by the renderers that write `href` / `src`: one LP0401 warning per element. */\n\nimport { safeConsoleWarn } from '@core/diagnostics';\nimport { isSafeUrl } from '@security/url-validator';\n\n// Keyed by element so a second client on the same page does not repeat the warning.\nconst warned = new WeakSet<Element>();\n\nexport type UrlOutcome =\n | { readonly kind: 'none' }\n | { readonly kind: 'unsafe' }\n | { readonly kind: 'safe'; readonly url: string };\n\n/** `none` when there is no URL to write, `unsafe` (warned once) when it fails `isSafeUrl`. */\nexport function acceptUrl(element: Element, fieldName: string, candidate: unknown): UrlOutcome {\n if (typeof candidate !== 'string' || candidate.length === 0) return { kind: 'none' };\n if (isSafeUrl(candidate)) return { kind: 'safe', url: candidate };\n if (!warned.has(element)) {\n warned.add(element);\n safeConsoleWarn(\n `[live-preview] LP0401: refused an unsafe URL for \"${fieldName}\" on ` +\n `<${element.tagName.toLowerCase()}>; the attribute was cleared.`,\n );\n }\n return { kind: 'unsafe' };\n}\n","/**\n * `url` renderer and the factory the `email` renderer shares. On an `<a>` the\n * value (or the `data-payload-href` sibling) becomes `href`; the value is\n * always the visible text.\n */\n\nimport { resolveFieldValue } from '@core/field-value';\nimport type { FieldRenderer, RendererKey } from '@core/types';\nimport { acceptUrl } from './unsafe-url';\nimport { isEmptyValue, safeStringify } from './utils';\n\n/** Build the link renderer named `name`; `toHref` derives the URL from the field value. */\nexport function createLinkRenderer(\n name: RendererKey,\n toHref: (value: string) => string = (value) => value,\n): FieldRenderer {\n return {\n name,\n render(target, value, context) {\n const element = target.element;\n if (isEmptyValue(value)) {\n clear(element);\n return;\n }\n const text = safeStringify(value);\n if (element.tagName === 'INPUT' || element.tagName === 'TEXTAREA') {\n (element as HTMLInputElement | HTMLTextAreaElement).value = text;\n return;\n }\n if (element.tagName === 'A') {\n const hrefField = target.hrefField;\n const candidate =\n hrefField === undefined || hrefField.length === 0\n ? toHref(text)\n : resolveFieldValue(\n context.allFields,\n hrefField,\n context.locale,\n target.locale !== undefined,\n );\n const outcome = acceptUrl(element, target.fieldName, candidate);\n if (outcome.kind === 'safe') element.setAttribute('href', outcome.url);\n else if (outcome.kind === 'unsafe') element.removeAttribute('href');\n }\n element.textContent = text;\n },\n };\n}\n\nfunction clear(element: Element): void {\n if (element.tagName === 'INPUT' || element.tagName === 'TEXTAREA') {\n (element as HTMLInputElement | HTMLTextAreaElement).value = '';\n return;\n }\n element.removeAttribute('href');\n element.textContent = '';\n}\n\nexport const urlRenderer: FieldRenderer = createLinkRenderer('url');\n","/** `email` renderer: a bare address becomes a `mailto:` link, a value with a scheme is used as written. */\n\nimport type { FieldRenderer } from '@core/types';\nimport { createLinkRenderer } from './url';\n\nconst HAS_SCHEME = /^[a-zA-Z][a-zA-Z0-9+.-]*:/;\n\nfunction mailtoHref(value: string): string {\n const trimmed = value.trim();\n if (HAS_SCHEME.test(trimmed) || !trimmed.includes('@')) return trimmed;\n return `mailto:${trimmed}`;\n}\n\nexport const emailRenderer: FieldRenderer = createLinkRenderer('email', mailtoHref);\n","/** `<img>` writes shared by the image and upload renderers. */\n\nimport { isSafeUrl } from '@security/url-validator';\nimport type { MediaShape } from '@lexical/value-shapes';\n\nconst IMAGE_SOURCE_ATTRIBUTES = ['src', 'srcset', 'sizes'] as const;\n\nexport function clearImage(img: HTMLImageElement): void {\n for (const name of IMAGE_SOURCE_ATTRIBUTES) img.removeAttribute(name);\n}\n\n/**\n * A server-rendered `srcset` would keep winning over a new `src`, so it is\n * rebuilt from the media's `sizes` or removed together with `sizes`.\n */\nexport function writeImage(\n img: HTMLImageElement,\n url: string,\n media: MediaShape | undefined,\n): void {\n img.src = url;\n const srcset = buildSrcset(media);\n if (srcset === undefined) {\n img.removeAttribute('srcset');\n img.removeAttribute('sizes');\n return;\n }\n img.setAttribute('srcset', srcset);\n}\n\nfunction buildSrcset(media: MediaShape | undefined): string | undefined {\n if (media?.sizes === undefined) return undefined;\n const candidates: string[] = [];\n for (const size of Object.values(media.sizes)) {\n if (typeof size.url !== 'string' || typeof size.width !== 'number' || !isSafeUrl(size.url)) {\n continue;\n }\n candidates.push(`${srcsetUrl(size.url)} ${String(size.width)}w`);\n }\n if (candidates.length === 0) return undefined;\n if (typeof media.width === 'number' && typeof media.url === 'string' && isSafeUrl(media.url)) {\n candidates.push(`${srcsetUrl(media.url)} ${String(media.width)}w`);\n }\n return candidates.join(', ');\n}\n\n// Commas and whitespace delimit srcset candidates and cannot appear raw in a URL there.\nfunction srcsetUrl(url: string): string {\n return url.replace(/[\\s,]/g, encodeURIComponent);\n}\n","/**\n * `image` renderer: `src`/`alt`/`srcset` on an `<img>`, a CSS background on\n * anything else. The value is a media object, a URL string, or resolved from\n * the `data-payload-src` / `data-payload-alt` sibling fields.\n */\n\nimport { escapeCssUrl } from '@security/escape';\nimport { resolveFieldValue } from '@core/field-value';\nimport { markNoWriteCallback } from '@core/internal-outcome';\nimport type { CachedElement, FieldRenderer, RenderContext } from '@core/types';\nimport { readMedia, type MediaShape } from '@lexical/value-shapes';\nimport { clearImage, writeImage } from './media';\nimport { acceptUrl } from './unsafe-url';\nimport { isEmptyValue } from './utils';\n\nconst imageRenderer: FieldRenderer = {\n name: 'image',\n render: /* @__PURE__ */ markNoWriteCallback((target, value, context) => {\n const element = target.element;\n if (isEmptyValue(value)) {\n clear(element);\n return;\n }\n const preferLocale = target.locale !== undefined;\n const { media, candidate } = pickSource(target, value, context, preferLocale);\n const outcome = acceptUrl(element, target.fieldName, candidate);\n if (outcome.kind === 'none') return false;\n if (outcome.kind === 'unsafe') {\n clear(element);\n return;\n }\n if (element.tagName === 'IMG') {\n const img = element as HTMLImageElement;\n writeImage(img, outcome.url, media);\n const alt = pickAlt(media, target.altField, context.allFields, context.locale, preferLocale);\n if (alt !== undefined) img.alt = alt;\n return;\n }\n (element as HTMLElement).style.backgroundImage = `url('${escapeCssUrl(outcome.url)}')`;\n return;\n }),\n};\n\nfunction clear(element: Element): void {\n if (element.tagName === 'IMG') clearImage(element as HTMLImageElement);\n else (element as HTMLElement).style.backgroundImage = '';\n}\n\nfunction pickSource(\n target: CachedElement,\n value: unknown,\n context: RenderContext,\n preferLocale: boolean,\n): { readonly media: MediaShape | undefined; readonly candidate: unknown } {\n const source =\n target.srcField !== undefined && target.srcField.length > 0\n ? resolveFieldValue(context.allFields, target.srcField, context.locale, preferLocale)\n : value;\n const media = readMedia(source);\n return { media, candidate: media === undefined ? source : media.url };\n}\n\nfunction pickAlt(\n media: MediaShape | undefined,\n altField: string | undefined,\n allFields: Record<string, unknown>,\n locale: string | undefined,\n preferLocale: boolean,\n): string | undefined {\n if (altField !== undefined && altField.length > 0) {\n const sibling = resolveFieldValue(allFields, altField, locale, preferLocale);\n return typeof sibling === 'string' ? sibling : undefined;\n }\n return media?.alt;\n}\n\nexport { imageRenderer };\n","/** `upload` renderer: an image on `<img>`, a download link on `<a>`, an injected link elsewhere. */\n\nimport { escapeHtml, escapeHtmlAttribute } from '@security/escape';\nimport { trustedHtml } from '@security/trusted-types';\nimport { markNoWriteCallback } from '@core/internal-outcome';\nimport type { FieldRenderer } from '@core/types';\nimport { readMedia } from '@lexical/value-shapes';\nimport { clearImage, writeImage } from './media';\nimport { acceptUrl } from './unsafe-url';\nimport { isEmptyValue } from './utils';\n\nconst uploadRenderer: FieldRenderer = {\n name: 'upload',\n render: /* @__PURE__ */ markNoWriteCallback((target, value) => {\n const element = target.element;\n if (isEmptyValue(value)) {\n clear(element);\n return;\n }\n const media = readMedia(value);\n if (media === undefined) return false;\n const outcome = acceptUrl(element, target.fieldName, media.url);\n if (outcome.kind === 'none') return false;\n if (outcome.kind === 'unsafe') {\n clear(element);\n return;\n }\n const url = outcome.url;\n if (element.tagName === 'IMG') {\n const img = element as HTMLImageElement;\n writeImage(img, url, media);\n if (media.alt !== undefined) img.alt = media.alt;\n return;\n }\n if (element.tagName === 'A') {\n element.setAttribute('href', url);\n element.textContent = media.filename ?? url;\n return;\n }\n const label = escapeHtml(media.filename ?? url);\n element.innerHTML = trustedHtml(`<a href=\"${escapeHtmlAttribute(url)}\">${label}</a>`);\n return;\n }),\n};\n\nfunction clear(element: Element): void {\n if (element.tagName === 'IMG') {\n clearImage(element as HTMLImageElement);\n return;\n }\n element.removeAttribute('href');\n element.textContent = '';\n}\n\nexport { uploadRenderer };\n","/** `relationship` renderer: the relation's label as text; on an `<a>` a populated `url` becomes `href`. */\n\nimport type { FieldRenderer } from '@core/types';\nimport { asRecord, pickRelationLabel, type RelationShape } from '@lexical/value-shapes';\nimport { acceptUrl } from './unsafe-url';\nimport { isEmptyValue, safeStringify } from './utils';\n\nconst relationshipRenderer: FieldRenderer = {\n name: 'relationship',\n render(target, value) {\n const element = target.element;\n if (isEmptyValue(value)) {\n element.removeAttribute('href');\n element.textContent = '';\n return;\n }\n if (element.tagName === 'A' && !Array.isArray(value)) {\n const outcome = acceptUrl(element, target.fieldName, asRecord(value)?.['url']);\n if (outcome.kind === 'safe') element.setAttribute('href', outcome.url);\n else if (outcome.kind === 'unsafe') element.removeAttribute('href');\n }\n element.textContent = Array.isArray(value) ? value.map(label).join(', ') : label(value);\n },\n};\n\nfunction label(value: unknown): string {\n const record = asRecord(value) as RelationShape | undefined;\n if (record === undefined) return safeStringify(value);\n return pickRelationLabel(record) ?? '';\n}\n\nexport { relationshipRenderer };\n","/**\n * `select` / `radio` renderer. Form controls receive option values; other\n * elements show the option labels from the field schema when the admin sent\n * one, else the values.\n */\n\nimport type { FieldRenderer, RenderContext } from '@core/types';\nimport { asRecord } from '@lexical/value-shapes';\nimport { isEmptyValue, safeStringify } from './utils';\n\nconst selectRenderer: FieldRenderer = {\n name: 'select',\n render(target, value, context) {\n const element = target.element;\n const values = isEmptyValue(value) ? [] : toValues(value);\n if (element.tagName === 'SELECT') {\n writeSelect(element as HTMLSelectElement, values);\n return;\n }\n if (element.tagName === 'INPUT' && (element as HTMLInputElement).type === 'radio') {\n const radio = element as HTMLInputElement;\n radio.checked = values.includes(radio.value);\n return;\n }\n element.textContent = values.map((item) => labelFor(item, context)).join(', ');\n },\n};\n\nfunction toValues(value: unknown): readonly string[] {\n if (Array.isArray(value)) return value.map(safeStringify);\n return [safeStringify(value)];\n}\n\n// `.value = 'a, b'` on a multiple select selects nothing; options are set one by one.\nfunction writeSelect(select: HTMLSelectElement, values: readonly string[]): void {\n if (select.multiple) {\n for (const option of Array.from(select.options)) {\n option.selected = values.includes(option.value);\n }\n return;\n }\n select.value = values[0] ?? '';\n}\n\nfunction labelFor(value: string, context: RenderContext): string {\n const options = context.schema?.['options'];\n if (!Array.isArray(options)) return value;\n for (const option of options) {\n const record = asRecord(option);\n if (record === undefined || safeStringify(record['value']) !== value) continue;\n return typeof record['label'] === 'string' ? record['label'] : value;\n }\n return value;\n}\n\nexport { selectRenderer };\n","/** `checkbox` renderer: `checked` on an input, `aria-checked` where present, `true`/`false` text otherwise. */\n\nimport type { FieldRenderer } from '@core/types';\n\nconst FALSE_STRINGS = new Set(['', 'false', '0', 'off', 'no']);\n\nconst checkboxRenderer: FieldRenderer = {\n name: 'checkbox',\n render(target, value) {\n const element = target.element;\n const checked = toBoolean(value);\n if (element.tagName === 'INPUT' && (element as HTMLInputElement).type === 'checkbox') {\n (element as HTMLInputElement).checked = checked;\n return;\n }\n if (element.hasAttribute('aria-checked')) {\n element.setAttribute('aria-checked', checked ? 'true' : 'false');\n return;\n }\n element.textContent = checked ? 'true' : 'false';\n },\n};\n\n// Form state and query parameters arrive as strings; `Boolean('false')` is not an answer.\nfunction toBoolean(value: unknown): boolean {\n if (typeof value === 'boolean') return value;\n if (typeof value === 'string') return !FALSE_STRINGS.has(value.trim().toLowerCase());\n if (typeof value === 'number') return value !== 0;\n return value !== null && value !== undefined;\n}\n\nexport { checkboxRenderer };\n","/**\n * Memoised `Intl` formatters, keyed by locale and options. Constructing them\n * per call dominates render time for arrays of many numeric or date fields,\n * and a formatter is a pure function of its key, so one instance is safe to\n * share across the page. Bounded so a language switcher cannot grow it without\n * limit.\n */\n\nimport { lruGet, lruSet, lruTrim } from './lru';\n\nconst NUMBER_CACHE = new Map<string, Intl.NumberFormat>();\nconst DATE_CACHE = new Map<string, Intl.DateTimeFormat>();\n\nconst DEFAULT_MAX_ENTRIES = 64;\n\nlet maxEntries = DEFAULT_MAX_ENTRIES;\n\n/** Internal test helper — purges every cached formatter. */\nexport function __resetIntlCache(): void {\n NUMBER_CACHE.clear();\n DATE_CACHE.clear();\n maxEntries = DEFAULT_MAX_ENTRIES;\n}\n\n/** Adjust the LRU bound. Returns the previous value. */\nexport function setIntlCacheLimit(limit: number): number {\n if (!Number.isFinite(limit) || limit < 1) return maxEntries;\n const previous = maxEntries;\n maxEntries = Math.floor(limit);\n lruTrim(NUMBER_CACHE, maxEntries);\n lruTrim(DATE_CACHE, maxEntries);\n return previous;\n}\n\n/** Cache occupancy, for tests and dev observability. */\nexport function intlCacheSize(): { readonly numbers: number; readonly dates: number } {\n return { numbers: NUMBER_CACHE.size, dates: DATE_CACHE.size };\n}\n\nexport function getNumberFormat(\n locale: string | undefined,\n options?: Intl.NumberFormatOptions,\n): Intl.NumberFormat {\n const key = buildKey(locale, options);\n return (\n lruGet(NUMBER_CACHE, key) ??\n lruSet(NUMBER_CACHE, key, new Intl.NumberFormat(locale, options), maxEntries)\n );\n}\n\nexport function getDateTimeFormat(\n locale: string | undefined,\n options?: Intl.DateTimeFormatOptions,\n): Intl.DateTimeFormat {\n const key = buildKey(locale, options);\n return (\n lruGet(DATE_CACHE, key) ??\n lruSet(DATE_CACHE, key, new Intl.DateTimeFormat(locale, options), maxEntries)\n );\n}\n\nfunction buildKey(locale: string | undefined, options: unknown): string {\n // Stable key order so equivalent option objects share a slot, and an empty\n // one collapses to the bare-locale key.\n const localePart = locale ?? '';\n if (options === undefined || options === null) return localePart;\n const serialised = stableStringify(options);\n if (serialised === '{}') return localePart;\n return `${localePart}|${serialised}`;\n}\n\nfunction stableStringify(value: unknown): string {\n if (value === null || typeof value !== 'object') return JSON.stringify(value);\n if (Array.isArray(value)) {\n return `[${value.map((v) => stableStringify(v)).join(',')}]`;\n }\n const record = value as Record<string, unknown>;\n const keys = Object.keys(record).sort();\n const parts: string[] = [];\n for (const key of keys) {\n const inner = record[key];\n if (inner === undefined) continue;\n parts.push(`${JSON.stringify(key)}:${stableStringify(inner)}`);\n }\n return `{${parts.join(',')}}`;\n}\n","/**\n * `data-payload-format`: a closed vocabulary deciding how a date or a number is\n * written. Without it a bound price shows the raw amount and a bound date an\n * ISO instant, so a template that formats on the server has to leave both\n * unbound — which is where an edit becomes invisible.\n *\n * Closed on purpose. Anything a consumer could pass here would be code running\n * inside the preview, and the runtime takes no code from the page. Two\n * renderers read it, so the parsing lives beside them rather than in either.\n *\n * `relative` (\"in 3 days\") is deliberately absent: choosing the unit and its\n * rounding is policy, not formatting, and two readers will want different\n * answers. A project that needs it renders it on the server behind a fragment.\n */\n\nimport { safeConsoleWarn } from '@core/diagnostics';\n\n/** What a renderer does with a parsed vocabulary entry. */\nexport type ValueFormat =\n | { readonly kind: 'date'; readonly options: Intl.DateTimeFormatOptions }\n | { readonly kind: 'number'; readonly options: Intl.NumberFormatOptions };\n\nconst DATE_STYLES = new Set(['short', 'medium', 'long', 'full']);\nconst TIME_STYLES = new Set(['short', 'medium', 'long', 'full']);\n\n/** ISO 4217: three letters, and `Intl` rejects anything else at construction. */\nconst CURRENCY_CODE = /^[A-Za-z]{3}$/u;\nconst FRACTION_DIGITS = /^[0-4]$/u;\n\n/**\n * `undefined` for a spec this vocabulary does not contain — the caller then\n * keeps its own default formatting and reports LP0408 once for that element.\n */\nexport function parseValueFormat(spec: string): ValueFormat | undefined {\n const separator = spec.indexOf(':');\n const name = separator === -1 ? spec : spec.slice(0, separator);\n const argument = separator === -1 ? undefined : spec.slice(separator + 1);\n\n switch (name) {\n case 'date':\n if (argument === undefined) return dateFormat({ dateStyle: 'medium' });\n return DATE_STYLES.has(argument)\n ? dateFormat({ dateStyle: argument as Intl.DateTimeFormatOptions['dateStyle'] })\n : undefined;\n case 'time':\n if (argument === undefined) return dateFormat({ timeStyle: 'short' });\n return TIME_STYLES.has(argument)\n ? dateFormat({ timeStyle: argument as Intl.DateTimeFormatOptions['timeStyle'] })\n : undefined;\n case 'datetime':\n // The bare form is the renderer's own default, so `datetime` changes\n // nothing and exists to be written down next to the others.\n if (argument === undefined) return dateFormat({ dateStyle: 'medium', timeStyle: 'short' });\n return DATE_STYLES.has(argument)\n ? dateFormat({\n dateStyle: argument as Intl.DateTimeFormatOptions['dateStyle'],\n timeStyle: argument === 'short' ? 'short' : 'medium',\n })\n : undefined;\n case 'number':\n if (argument === undefined) return numberFormat({});\n if (!FRACTION_DIGITS.test(argument)) return undefined;\n return numberFormat({\n minimumFractionDigits: Number(argument),\n maximumFractionDigits: Number(argument),\n });\n case 'currency':\n if (argument === undefined || !CURRENCY_CODE.test(argument)) return undefined;\n return numberFormat({ style: 'currency', currency: argument.toUpperCase() });\n case 'percent':\n return argument === undefined ? numberFormat({ style: 'percent' }) : undefined;\n default:\n return undefined;\n }\n}\n\nfunction dateFormat(options: Intl.DateTimeFormatOptions): ValueFormat {\n return { kind: 'date', options };\n}\n\nfunction numberFormat(options: Intl.NumberFormatOptions): ValueFormat {\n return { kind: 'number', options };\n}\n\nconst warned = new WeakSet<Element>();\n\n/** Reported once per element: the markup is the cause, and it does not change. */\nexport function warnUnknownFormat(element: Element, fieldName: string, spec: string): void {\n if (warned.has(element)) return;\n warned.add(element);\n safeConsoleWarn(\n `[live-preview] LP0408: data-payload-format=\"${spec}\" on \"${fieldName}\" is not a ` +\n 'known format; the default formatting was used. Known: date, date:short|medium|long|full, ' +\n 'time, datetime, number, number:0-4, currency:XXX, percent.',\n );\n}\n\n/**\n * The options a renderer should use, or `undefined` to keep its own default —\n * which is also the answer when the spec belongs to the other renderer, so\n * `currency:EUR` on a date changes nothing rather than breaking it.\n */\nexport function formatOptionsFor<K extends ValueFormat['kind']>(\n kind: K,\n spec: string | undefined,\n element: Element,\n fieldName: string,\n): Extract<ValueFormat, { kind: K }>['options'] | undefined {\n if (spec === undefined || spec === '') return undefined;\n const parsed = parseValueFormat(spec);\n if (parsed === undefined) {\n warnUnknownFormat(element, fieldName, spec);\n return undefined;\n }\n if (parsed.kind !== kind) return undefined;\n return parsed.options;\n}\n","/**\n * `date` renderer. `<time>` gets an ISO `datetime` plus a localised label;\n * date inputs get the value in the visitor's local time zone, because that is\n * what the control displays.\n */\n\nimport { detectInitialLocale } from '@detection/locale';\nimport { getDateTimeFormat } from '@core/intl-cache';\nimport type { CachedElement, FieldRenderer, RenderContext } from '@core/types';\nimport { isEmptyValue, safeStringify } from './utils';\nimport { formatOptionsFor } from './value-format';\n\nconst dateRenderer: FieldRenderer = {\n name: 'date',\n render(target, value, context) {\n const element = target.element;\n if (isEmptyValue(value)) {\n if (element.tagName === 'INPUT') (element as HTMLInputElement).value = '';\n else {\n element.removeAttribute('datetime');\n element.textContent = '';\n }\n return;\n }\n const raw = typeof value === 'number' ? value : safeStringify(value);\n const date = new Date(raw);\n const valid = !Number.isNaN(date.getTime());\n const fallback = String(raw);\n if (element.tagName === 'INPUT') {\n (element as HTMLInputElement).value = valid\n ? formatForInput((element as HTMLInputElement).type, date)\n : fallback;\n return;\n }\n if (element.tagName === 'TIME') {\n element.setAttribute('datetime', valid ? date.toISOString() : fallback);\n }\n element.textContent = valid ? formatDate(date, target, context) : fallback;\n },\n};\n\nconst DEFAULT_DATE_OPTIONS: Intl.DateTimeFormatOptions = {\n dateStyle: 'medium',\n timeStyle: 'short',\n};\n\nfunction formatDate(date: Date, target: CachedElement, context: RenderContext): string {\n const locale = target.locale ?? context.locale ?? detectInitialLocale();\n const options =\n formatOptionsFor('date', target.format, target.element, target.fieldName) ??\n DEFAULT_DATE_OPTIONS;\n try {\n return getDateTimeFormat(locale, options).format(date);\n } catch {\n return date.toISOString();\n }\n}\n\n/** Value for `<input type=\"date|datetime-local|time\">` in local time; other inputs get the ISO instant. */\nexport function formatForInput(type: string, date: Date): string {\n const day = `${String(date.getFullYear()).padStart(4, '0')}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}`;\n const clock = `${pad(date.getHours())}:${pad(date.getMinutes())}`;\n if (type === 'date') return day;\n if (type === 'datetime-local') return `${day}T${clock}`;\n if (type === 'time') return clock;\n return date.toISOString();\n}\n\nfunction pad(value: number): string {\n return String(value).padStart(2, '0');\n}\n\nexport { dateRenderer };\n","/** `number` renderer: raw value on inputs, `Intl.NumberFormat` elsewhere. */\n\nimport { detectInitialLocale } from '@detection/locale';\nimport { getNumberFormat } from '@core/intl-cache';\nimport type { CachedElement, FieldRenderer, RenderContext } from '@core/types';\nimport { isEmptyValue, safeStringify } from './utils';\nimport { formatOptionsFor } from './value-format';\n\nconst numberRenderer: FieldRenderer = {\n name: 'number',\n render(target, value, context) {\n const element = target.element;\n if (isEmptyValue(value)) {\n if (element.tagName === 'INPUT') (element as HTMLInputElement).value = '';\n else element.textContent = '';\n return;\n }\n const num = typeof value === 'number' ? value : Number(safeStringify(value));\n if (Number.isNaN(num)) {\n element.textContent = safeStringify(value);\n return;\n }\n if (element.tagName === 'INPUT') {\n (element as HTMLInputElement).value = String(num);\n return;\n }\n element.textContent = format(num, target, context);\n },\n};\n\nfunction format(num: number, target: CachedElement, context: RenderContext): string {\n const locale = target.locale ?? context.locale ?? detectInitialLocale();\n const options = formatOptionsFor('number', target.format, target.element, target.fieldName);\n try {\n return getNumberFormat(locale, options).format(num);\n } catch {\n // An `Intl` option this build rejects — an unknown currency, say.\n return String(num);\n }\n}\n\nexport { numberRenderer };\n","/**\n * `array` / `blocks` renderer. With `data-payload-array-template` each item\n * is interpolated into the template (`{{key}}`, `{{value}}`, `{{index}}`);\n * without one, items are joined by `data-payload-array-separator`.\n */\n\nimport { sanitizeHtmlWithPolicy } from '@security/sanitizer';\nimport { trustedHtml } from '@security/trusted-types';\nimport {\n collectTemplateKeys,\n inheritItemAttributes,\n interpolateArrayTemplate,\n sharedItemAttributes,\n} from '@core/array-template';\nimport { markNoWriteCallback } from '@core/internal-outcome';\nimport { templateSanitizeOptions } from '@core/template-sanitize';\nimport type { FieldRenderer } from '@core/types';\nimport { isEmptyValue, safeStringify } from './utils';\n\nconst arrayRenderer: FieldRenderer = {\n name: 'array',\n render: /* @__PURE__ */ markNoWriteCallback((target, value, context) => {\n const element = target.element;\n if (isEmptyValue(value)) {\n element.textContent = '';\n return;\n }\n if (!Array.isArray(value)) return false;\n const template = target.arrayTemplate;\n if (template !== undefined && template.length > 0) {\n const html = renderTemplate(template, value);\n const policy = context.sanitizerPolicy;\n const templateOptions = templateSanitizeOptions(template);\n // Read before the write: the items about to be replaced are the only\n // record of what the server put on them.\n const shared = sharedItemAttributes(element);\n element.innerHTML = trustedHtml(sanitizeHtmlWithPolicy(html, policy, templateOptions));\n for (const item of Array.from(element.children)) inheritItemAttributes(item, shared);\n return;\n }\n element.textContent = value.map(safeStringify).join(target.arraySeparator ?? ', ');\n return;\n }),\n};\n\nfunction renderTemplate(template: string, items: readonly unknown[]): string {\n const knownKeys = collectTemplateKeys(items);\n let out = '';\n for (let i = 0; i < items.length; i += 1) {\n out += interpolateArrayTemplate(template, items[i], i, safeStringify, knownKeys);\n }\n return out;\n}\n\nexport { arrayRenderer };\n","/**\n * `structural-array` renderer (`data-payload-structural`): diffs the previous\n * and next item lists and patches the container through the keyed morph\n * (ADR 0008). All diff memory lives in the closure, one per client.\n */\n\nimport { safeConsoleWarn } from '@core/diagnostics';\nimport { markNoWriteCallback } from '@core/internal-outcome';\nimport {\n applyStructuralPatches,\n createStructuralStore,\n KEY_ATTRIBUTE,\n type StructuralStore,\n} from '@core/structural-applier';\nimport { diffArray } from '@schema/diff';\nimport type { FieldRenderer } from '@core/types';\nimport { isEmptyValue } from './utils';\n\ninterface StructuralRenderState {\n readonly values: readonly unknown[];\n readonly template: string;\n readonly domSnapshot: readonly (string | null)[];\n}\n\ntype WarnedCodes = WeakMap<Element, Set<string>>;\n\n/** @internal */\nexport function createStructuralArrayRenderer(): FieldRenderer {\n const states = new WeakMap<Element, StructuralRenderState>();\n const warnedContainers = new WeakSet<Element>();\n const warnedKeys: WarnedCodes = new WeakMap();\n const store: StructuralStore = createStructuralStore();\n\n return {\n name: 'structural-array',\n render: /* @__PURE__ */ markNoWriteCallback((target, rawValue, context) => {\n const value = isEmptyValue(rawValue) ? [] : rawValue;\n if (!Array.isArray(value)) return false;\n const container = target.element;\n const template = target.arrayTemplate;\n if (template === undefined || template.length === 0) {\n warnMissingTemplate(warnedContainers, container, target.fieldName);\n return false;\n }\n const previousState = states.get(container);\n const domSnapshot = readDomKeySnapshot(container);\n const previous = previousState?.values ?? valuesFromDomSnapshot(domSnapshot);\n const patches = diffArray(previous, value);\n const forceRender = needsForcedRender(previousState, template, domSnapshot);\n if (patches.length === 0 && !forceRender) {\n states.set(container, { values: value.slice(), template, domSnapshot });\n return false;\n }\n warnAboutKeys(warnedKeys, container, target.fieldName, previousState?.values, value);\n const applied = applyStructuralPatches({\n template,\n container,\n patches,\n nextItems: value,\n store,\n forceRender,\n sanitizerPolicy: context.sanitizerPolicy,\n onDuplicateKey: (owner, key) => {\n warnDuplicateKey(warnedKeys, owner, target.fieldName, key);\n },\n });\n if (applied === null) return false;\n states.set(container, {\n values: value.slice(),\n template,\n domSnapshot: readDomKeySnapshot(container),\n });\n return applied ? undefined : false;\n }),\n };\n}\n\nfunction needsForcedRender(\n previous: StructuralRenderState | undefined,\n template: string,\n domSnapshot: readonly (string | null)[],\n): boolean {\n if (previous === undefined) return true;\n return previous.template !== template || !sameDomKeySnapshot(previous.domSnapshot, domSnapshot);\n}\n\n// SSR markup exists before any in-memory snapshot; its direct-child keys let\n// the first update reconcile instead of appending a second copy.\nfunction readDomKeySnapshot(container: Element): readonly (string | null)[] {\n return Array.from(container.children, (child) => child.getAttribute(KEY_ATTRIBUTE));\n}\n\nfunction valuesFromDomSnapshot(snapshot: readonly (string | null)[]): readonly unknown[] {\n return snapshot.map((key, position) =>\n key === null ? { __payloadDomPosition: position } : { id: key },\n );\n}\n\nfunction sameDomKeySnapshot(\n previous: readonly (string | null)[],\n current: readonly (string | null)[],\n): boolean {\n if (previous.length !== current.length) return false;\n return previous.every((key, index) => key === current[index]);\n}\n\nfunction warnMissingTemplate(\n warnedContainers: WeakSet<Element>,\n container: Element,\n fieldName: string,\n): void {\n if (warnedContainers.has(container)) return;\n warnedContainers.add(container);\n safeConsoleWarn(\n `[live-preview] LP0403: Skipping structural update for \"${fieldName}\": ` +\n `<${container.tagName.toLowerCase()} data-payload-structural> needs ` +\n `data-payload-array-template (for example \"<li>{{label}}</li>\").`,\n );\n}\n\nfunction itemKey(value: unknown): string | undefined {\n if (typeof value !== 'object' || value === null) return undefined;\n const id = (value as Record<string, unknown>)['id'];\n return typeof id === 'string' || typeof id === 'number' ? String(id) : undefined;\n}\n\n/** Key problems degrade the morph, they do not break it; each is announced once per container (ADR 0008 §5). */\nfunction warnAboutKeys(\n warned: WarnedCodes,\n container: Element,\n fieldName: string,\n previous: readonly unknown[] | undefined,\n next: readonly unknown[],\n): void {\n const nextKeys = next.map(itemKey);\n const seen = new Set<string>();\n const duplicate = nextKeys.find((key) => {\n if (key === undefined) return false;\n if (seen.has(key)) return true;\n seen.add(key);\n return false;\n });\n if (duplicate !== undefined) warnDuplicateKey(warned, container, fieldName, duplicate);\n if (nextKeys.some((key) => key === undefined)) {\n warnOnce(\n warned,\n container,\n 'LP0404',\n `LP0404: an item of \"${fieldName}\" has no id and pairs by ` +\n 'position, so an insert re-renders every row after it. Give items a stable id.',\n );\n }\n if (previous?.length === next.length && next.length > 1) {\n const previousKeys = new Set(previous.map(itemKey).filter((key) => key !== undefined));\n const stable = nextKeys.some((key) => key !== undefined && previousKeys.has(key));\n if (previousKeys.size > 0 && !stable) {\n warnOnce(\n warned,\n container,\n 'LP0406',\n `LP0406: every key of \"${fieldName}\" changed at once; the ` +\n 'source generates ids per message, so no item can be retained across updates.',\n );\n }\n }\n}\n\n// Reached from the pre-diff check and from the morph's nested-slot check; one site, one message.\nfunction warnDuplicateKey(\n warned: WarnedCodes,\n owner: Element,\n fieldName: string,\n key: string,\n): void {\n warnOnce(\n warned,\n owner,\n 'LP0405',\n `LP0405: two items of \"${fieldName}\" share the key \"${key}\"; later ones pair by ` +\n 'position. Make `id` unique per item.',\n );\n}\n\nfunction warnOnce(warned: WarnedCodes, container: Element, code: string, message: string): void {\n let codes = warned.get(container);\n if (codes === undefined) {\n codes = new Set();\n warned.set(container, codes);\n }\n if (codes.has(code)) return;\n codes.add(code);\n safeConsoleWarn(`[live-preview] ${message}`);\n}\n","/**\n * Explicit renderer overrides, layered above the defaults each time a map is\n * built. The registry never retains the defaults, so stateful ones can be\n * recreated per client.\n */\n\nimport type { FieldRenderer, RendererKey } from '@core/types';\n\nconst builtinRenderers = new Map<RendererKey, FieldRenderer>();\n\nexport function buildBuiltinRenderers(\n defaults: readonly FieldRenderer[] = [],\n): Readonly<Record<string, FieldRenderer>> {\n const out: Record<string, FieldRenderer> = {};\n for (const renderer of defaults) out[renderer.name] = renderer;\n for (const [type, renderer] of builtinRenderers) out[type] = renderer;\n return Object.freeze(out);\n}\n\n/** Register or replace an override for maps built afterwards. */\nexport function registerBuiltinRenderer(renderer: FieldRenderer): void {\n builtinRenderers.set(renderer.name, renderer);\n}\n\n/** Test-only: clear the overrides. */\nexport function __resetBuiltinRenderersForTests(): void {\n builtinRenderers.clear();\n}\n","/** Built-in field renderers, assembled as values so `sideEffects: false` bundlers keep them all. */\n\nimport type { FieldRenderer } from '@core/types';\nimport { createTextRenderer } from './text';\nimport { richTextRenderer } from './rich-text';\nimport { htmlRenderer } from './html';\nimport { urlRenderer } from './url';\nimport { emailRenderer } from './email';\nimport { imageRenderer } from './image';\nimport { uploadRenderer } from './upload';\nimport { relationshipRenderer } from './relationship';\nimport { selectRenderer } from './select';\nimport { checkboxRenderer } from './checkbox';\nimport { dateRenderer } from './date';\nimport { numberRenderer } from './number';\nimport { arrayRenderer } from './array';\nimport { createStructuralArrayRenderer } from './structural-array';\nimport {\n buildBuiltinRenderers as buildRegistry,\n registerBuiltinRenderer,\n __resetBuiltinRenderersForTests,\n} from './registry';\nimport { reportOmittedFeature } from '@core/profile';\n\n/**\n * The array renderers carry the keyed morph, the structural applier and the item\n * templates — the largest optional cluster in the runtime. The lean profile\n * answers a page that needs them with LP0104 instead (@core/profile).\n */\nfunction arrayRenderers(): readonly FieldRenderer[] {\n return typeof __LEAN_BUILD__ !== 'undefined' && __LEAN_BUILD__\n ? [\n omittedRenderer('array', 'structural arrays'),\n omittedRenderer('blocks', 'structural arrays'),\n ]\n : [arrayRenderer, { ...arrayRenderer, name: 'blocks' }];\n}\n\n/** A renderer that only explains itself: the lean profile does not carry this field type. */\nfunction omittedRenderer(name: FieldRenderer['name'], feature: 'structural arrays'): FieldRenderer {\n return {\n name,\n render() {\n reportOmittedFeature(feature);\n },\n };\n}\n\n/** One renderer map per client; the stateful text and structural renderers are created fresh each call. @internal */\nexport function buildBuiltinRenderers(): Readonly<Record<string, FieldRenderer>> {\n // Built per call: a module-level table would pin every renderer into any\n // consumer importing an unrelated symbol from the root barrel.\n const stateless: readonly FieldRenderer[] = [\n richTextRenderer,\n htmlRenderer,\n urlRenderer,\n emailRenderer,\n imageRenderer,\n uploadRenderer,\n relationshipRenderer,\n selectRenderer,\n { ...selectRenderer, name: 'radio' },\n checkboxRenderer,\n dateRenderer,\n numberRenderer,\n ...arrayRenderers(),\n ];\n\n return buildRegistry([\n createTextRenderer('text'),\n createTextRenderer('textarea'),\n ...stateless,\n ...(typeof __LEAN_BUILD__ !== 'undefined' && __LEAN_BUILD__\n ? []\n : [createStructuralArrayRenderer()]),\n ]);\n}\n\nexport { registerBuiltinRenderer, __resetBuiltinRenderersForTests };\nexport type { PayloadMedia, PayloadRelationship } from './types';\n","/**\n * The two defaults profiles, row by row. 2.0 ships `v2`; `defaults: 'v1'` opts\n * back into the 1.x table for a staged migration. Each row belongs to exactly\n * one side — the adapter's request decision or the browser runtime — and a\n * test asserts the profile assigns every readiness row that has an option, so\n * a row added later cannot be forgotten. See ADR 0007.\n *\n * It lives in the leaf `types` domain, like `merge-depth.ts`, because the\n * inline generator resolves the profile too, and the generator is server-side\n * code that may not reach the browser runtime in `core`.\n */\n\n/** `'v2'` is the 2.0 default; `'v1'` is the 1.x table. */\nexport type DefaultsProfile = 'v1' | 'v2';\n\n/** How the runtime decides which windows may post updates. */\nexport type EventSourcePolicy = 'any' | 'parent-or-opener';\n\n/** Readiness rows that are options, keyed by the option they set. */\nexport const READINESS_ROWS = Object.freeze({\n strict: 'production response changes require an authorized context',\n previewSignals: 'query-only intent signal',\n disableReferrerDetection: 'referrer trust off',\n eventSourcePolicy: 'messages must come from parent/opener',\n skipUnchanged: 'skip unchanged bindings by default',\n sanitizerPolicy: 'hardened sanitizer id/data-* policy',\n} as const);\n\n/** Options an adapter's request decision reads from the profile. */\nexport interface AdapterProfileDefaults {\n readonly strict: boolean;\n readonly previewSignals: readonly ('query' | 'fetch-dest' | 'referer')[];\n}\n\n/** Options the browser runtime reads from the profile (through the inline configuration). */\nexport interface RuntimeProfileDefaults {\n readonly disableReferrerDetection: boolean;\n readonly eventSourcePolicy: EventSourcePolicy;\n readonly skipUnchanged: boolean;\n readonly sanitizerPolicy: 'compat' | 'strict';\n}\n\nexport const V2_ADAPTER_DEFAULTS: AdapterProfileDefaults = Object.freeze({\n strict: true,\n previewSignals: Object.freeze(['query'] as const),\n});\n\nexport const V2_RUNTIME_DEFAULTS: RuntimeProfileDefaults = Object.freeze({\n disableReferrerDetection: true,\n eventSourcePolicy: 'parent-or-opener',\n skipUnchanged: true,\n sanitizerPolicy: 'strict',\n});\n\n/** The 1.x table, spelled out so the profiles compare row by row. */\nexport const V1_ADAPTER_DEFAULTS: AdapterProfileDefaults = Object.freeze({\n strict: false,\n previewSignals: Object.freeze(['query', 'fetch-dest', 'referer'] as const),\n});\n\nexport const V1_RUNTIME_DEFAULTS: RuntimeProfileDefaults = Object.freeze({\n disableReferrerDetection: false,\n eventSourcePolicy: 'any',\n skipUnchanged: false,\n sanitizerPolicy: 'compat',\n});\n\n/** Only an explicit `'v1'` opts out; everything else gets the hardened rows. */\nexport function adapterDefaultsFor(profile: DefaultsProfile | undefined): AdapterProfileDefaults {\n return profile === 'v1' ? V1_ADAPTER_DEFAULTS : V2_ADAPTER_DEFAULTS;\n}\n\nexport function runtimeDefaultsFor(profile: DefaultsProfile | undefined): RuntimeProfileDefaults {\n return profile === 'v1' ? V1_RUNTIME_DEFAULTS : V2_RUNTIME_DEFAULTS;\n}\n","/**\n * `LivePreviewClient`: a `LivePreviewRuntime` with its own emitter, plugin\n * manager and renderer registry. A page that only needs a working preview uses\n * `generateInlineScript()` instead.\n */\n\nimport { assertMergeDepthExplicit } from '@/types/merge-depth';\nimport { LivePreviewRuntime, type RuntimeOptions } from '@core/lifecycle';\nimport type { LivePreviewInspection } from '@core/inspection/types';\nimport type { CachedElement, RendererKey } from '@core/types';\nimport { EventEmitter } from '@events/emitter';\nimport { OriginDetector } from '@detection/origin';\nimport { PluginManager } from '@plugins/manager';\nimport { RendererRegistry } from '@plugins/renderer-registry';\nimport type { LivePreviewPlugin } from '@plugins/types';\nimport { isDevMode, isInPreviewContext } from '@detection/environment';\nimport { buildBuiltinRenderers } from '@field-types/index';\nimport { definedOnly } from '@/types/defined-only';\nimport { withProfileDefaults, type LivePreviewClientConfig } from './config';\nimport { noopDiagnostic, safeConsoleDebug } from '@core/diagnostics';\n\n/** `T` with every property optional and `undefined`-able, for literals built from optional inputs. */\ntype Loose<T> = { readonly [K in keyof T]?: T[K] | undefined };\n\nfunction invert(value: boolean | undefined): boolean | undefined {\n return value === undefined ? undefined : !value;\n}\n\nexport class LivePreviewClient {\n readonly #emitter = new EventEmitter();\n readonly #detector: OriginDetector;\n readonly #rendererRegistry: RendererRegistry;\n readonly #runtime: LivePreviewRuntime;\n readonly #plugins: PluginManager;\n readonly #log: (...args: unknown[]) => void;\n #started = false;\n #destroyed = false;\n #tornDown = false;\n #destroyPromise: Promise<void> | null = null;\n\n constructor(rawConfig: LivePreviewClientConfig = {}) {\n const config = withProfileDefaults(rawConfig);\n const serverURL = config.serverURL ?? '';\n assertMergeDepthExplicit({\n defaults: rawConfig.defaults,\n serverURL,\n mergeDepth: config.mergeDepth,\n });\n const debug = config.debug ?? isDevMode();\n this.#log = debug\n ? (...args): void => {\n safeConsoleDebug('[live-preview]', ...args);\n }\n : noopDiagnostic;\n\n this.#detector = new OriginDetector(\n definedOnly({\n additionalOrigins: config.allowedOrigins,\n enableReferrerDetection: invert(config.disableReferrerDetection),\n enableLocalhostMatching: invert(config.disableLocalhostMatching),\n }),\n );\n\n if (this.#detector.isProductionUnconfigured) {\n this.#log('no trusted origin could be detected — set allowedOrigins');\n }\n\n this.#rendererRegistry = new RendererRegistry(buildBuiltinRenderers());\n\n this.#plugins = new PluginManager({\n events: this.#emitter,\n config: Object.freeze({ ...config }),\n registerFieldRenderer: (renderer) => this.#rendererRegistry.register(renderer),\n onTransformError: (error) => {\n void this.#emitter.emit('error', { error, context: 'transform', code: 'LP0602' });\n },\n log: this.#log,\n });\n\n this.#runtime = new LivePreviewRuntime(\n definedOnly({\n root: config.root,\n renderers: this.#rendererRegistry.renderers,\n resolveRenderer: (fieldType: RendererKey, target: CachedElement) =>\n config.resolveRenderer?.(fieldType, target) ?? this.#rendererRegistry.resolve(fieldType),\n renderRichText: config.renderRichText,\n sanitizerPolicy: config.sanitizerPolicy,\n transformValue: (\n fieldName: string,\n value: unknown,\n context: { readonly element: Element; readonly allFields: Record<string, unknown> },\n isCurrent?: () => boolean,\n ) => this.#plugins.applyTransforms(fieldName, value, context, isCurrent),\n originMatcher: (origin: string) => this.#detector.matches(origin),\n // Read per handshake, not once: after a lock, a bfcache restore must\n // re-broadcast to the locked origin alone, not every pre-lock candidate.\n readyTargets: () => this.#detector.enumerate(),\n emitter: this.#emitter,\n dataMerge:\n serverURL === ''\n ? undefined\n : definedOnly({\n serverURL,\n apiRoute: config.apiRoute,\n depth: config.mergeDepth,\n fetchFn: config.mergeFetch,\n }),\n debounceMs: config.debounceMs,\n heartbeatMs: config.heartbeatMs,\n intersectionRootMargin: config.intersectionRootMargin,\n scopeBindingsByOwner: config.scopeBindingsByOwner,\n skipUnchanged: config.skipUnchanged,\n revealEditedField: config.revealEditedField,\n autoBind: config.autoBind,\n eventSourcePolicy: config.eventSourcePolicy,\n dependencies: config.dependencies,\n strategies: config.strategies,\n disableVisibilityGate: config.disableVisibilityGate,\n visibilityGateThreshold: config.visibilityGateThreshold,\n enableA11y: config.enableA11y,\n a11yLocale: config.a11yLocale,\n onHeartbeatTimeout: () => {\n this.#detector.unlockOrigin();\n },\n lockedOrigin: () => this.#detector.lockedOrigin,\n validateToken: config.validateToken,\n log: this.#log,\n } satisfies Loose<RuntimeOptions>),\n );\n\n this.#emitter.on('connect', (e) => {\n this.#detector.lockOrigin(e.origin);\n });\n\n if (config.autoStart !== false) {\n this.start();\n }\n }\n\n /**\n * Start the runtime: `true` while eligible and started or scheduled for DOM\n * readiness, `false` once destroyed or outside a preview context.\n */\n start(): boolean {\n if (this.#destroyed) return false;\n if (this.#started) {\n // A deferred DOM-ready startup can fail after this returned and roll\n // itself back; this call retries it.\n this.#runtime.start();\n return true;\n }\n if (!isInPreviewContext()) return false;\n const started = this.#runtime.start();\n if (started) this.#started = true;\n return started;\n }\n\n /**\n * Release the message ingress, keeping plugins and renderers, for `pagehide`:\n * a bfcache restore re-runs no script, so an attached client would return\n * bound to a frozen page. `false` when nothing was running.\n */\n suspend(): boolean {\n if (this.#destroyed || !this.#started) return false;\n return this.#runtime.suspend();\n }\n\n /** Reacquire after `suspend()`: the same path as `start()`, because a restored document needs the same rebuild. */\n resume(): boolean {\n if (this.#destroyed || !this.#started) return false;\n return this.#runtime.start();\n }\n\n /** Stop the runtime and tear down every plugin. Idempotent; concurrent callers share one promise. */\n destroy(): Promise<void> {\n if (this.#destroyPromise !== null) return this.#destroyPromise;\n this.#destroyed = true;\n let resolveDestroy!: () => void;\n let rejectDestroy!: (reason: unknown) => void;\n const inFlight = new Promise<void>((resolve, reject) => {\n resolveDestroy = resolve;\n rejectDestroy = reject;\n });\n // Published before the teardown: a `destroy` handler calling destroy()\n // re-entrantly must get this same promise.\n this.#destroyPromise = inFlight;\n const finish = (): void => {\n this.#emitter.removeAllListeners();\n this.#tornDown = true;\n };\n try {\n this.#runtime.destroy();\n void this.#plugins.destroyAll().finally(finish).then(resolveDestroy, rejectDestroy);\n } catch (error) {\n finish();\n rejectDestroy(error);\n }\n return inFlight;\n }\n\n async use(plugin: LivePreviewPlugin): Promise<void> {\n if (this.#destroyed) throw new Error('LivePreviewClient: already destroyed');\n await this.#plugins.register(plugin);\n }\n\n /** Unregister a plugin and release everything its registration owned. Still allowed from a destroy hook during teardown. */\n async unuse(name: string): Promise<void> {\n if (this.#tornDown) throw new Error('LivePreviewClient: already destroyed');\n await this.#plugins.unregister(name);\n }\n\n refreshCache(): void {\n this.#runtime.refreshCache();\n }\n\n get events(): EventEmitter {\n return this.#emitter;\n }\n\n /** Names of the registered plugins. */\n get plugins(): readonly string[] {\n return this.#plugins.list();\n }\n\n get status(): 'disconnected' | 'connecting' | 'connected' {\n return this.#runtime.status;\n }\n\n /**\n * Point-in-time read of runtime state, no I/O: `bindings.orphanFields` when a\n * field refuses to update, `scheduler.deferred` when updates stop below the fold.\n */\n inspect(): LivePreviewInspection {\n return { ...this.#runtime.inspect(), plugins: this.#plugins.snapshot() };\n }\n\n /** Number of accepted updates so far. */\n get updateCount(): number {\n return this.#runtime.updateCount;\n }\n\n /** `true` once `destroy()` has been called. */\n get destroyed(): boolean {\n return this.#destroyed;\n }\n}\n\n/** A started client, or `null` when the page is not a preview context. */\nexport function initLivePreview(config: LivePreviewClientConfig = {}): LivePreviewClient | null {\n const client = new LivePreviewClient({ ...config, autoStart: false });\n return client.start() ? client : null;\n}\n\nexport type { LivePreviewClientConfig } from './config';\n","/**\n * Content-Security-Policy helpers: nonce generation, directive builders and\n * the header merge every adapter uses. Isomorphic; needs only Web Crypto.\n */\n\nconst DEFAULT_NONCE_BYTES = 16;\n\n/** CSP3's exact whitespace set: HTAB, LF, FF, CR, and SPACE. */\nconst CSP_ASCII_WHITESPACE = /[\\t\\n\\f\\r ]+/;\n\n/** Reads one code unit; an index past the end yields NaN, which matches nothing. */\nfunction isCspWhitespace(value: string, index: number): boolean {\n const code = value.charCodeAt(index);\n return code === 9 || code === 10 || code === 12 || code === 13 || code === 32;\n}\n\n/**\n * Trim CSP whitespace by scanning from both ends.\n *\n * The obvious `/^\\s+|\\s+$/` is superlinear by construction: for a long run the\n * trailing alternative is retried at every position. V8 happens to optimise the\n * shape away, but this header can come from a consumer's own response and this\n * module runs in every engine, so the guarantee has to come from the algorithm\n * rather than from one engine's optimiser.\n */\nfunction trimCspWhitespace(value: string): string {\n let start = 0;\n let end = value.length;\n while (start < end && isCspWhitespace(value, start)) start += 1;\n while (end > start && isCspWhitespace(value, end - 1)) end -= 1;\n return start === 0 && end === value.length ? value : value.slice(start, end);\n}\n\n/** CSP names are ASCII; Unicode case folding must not create directives. */\nfunction asciiLowercase(value: string): string {\n return value.replace(/[A-Z]/g, (character) => character.toLowerCase());\n}\n\n/** The one Web Crypto method this module calls; accepts Node's `webcrypto` without a cast. */\ninterface WebCryptoLike {\n getRandomValues: <T extends ArrayBufferView | null>(array: T) => T;\n}\n\nlet cryptoOverride: WebCryptoLike | undefined;\n\n/** Supply a Web Crypto implementation for runtimes without `globalThis.crypto`; `null` clears it. @internal */\nexport function setCspCrypto(crypto: WebCryptoLike | null): void {\n cryptoOverride = crypto ?? undefined;\n}\n\n/** A base64url nonce of `bytes` random bytes (default 16); throws without Web Crypto, since a predictable nonce silently defeats the CSP. @internal */\nexport function generateCspNonce(bytes: number = DEFAULT_NONCE_BYTES): string {\n if (!Number.isInteger(bytes) || bytes < 8) {\n throw new RangeError(`generateCspNonce: bytes must be an integer >= 8, got ${String(bytes)}`);\n }\n const crypto = resolveCrypto();\n if (!crypto) {\n throw new Error(\n 'generateCspNonce: Web Crypto is unavailable. On Node 18 call setCspCrypto(webcrypto) ' +\n \"once at startup, or run with --experimental-global-webcrypto. We won't fabricate \" +\n 'a predictable nonce — that would silently defeat the entire CSP.',\n );\n }\n const buffer = new Uint8Array(bytes);\n crypto.getRandomValues(buffer);\n return base64UrlEncode(buffer);\n}\n\nfunction resolveCrypto(): WebCryptoLike | undefined {\n if (cryptoOverride?.getRandomValues) return cryptoOverride;\n const fromGlobal = (globalThis as { crypto?: WebCryptoLike }).crypto;\n if (fromGlobal?.getRandomValues) return fromGlobal;\n return undefined;\n}\n\nfunction base64UrlEncode(bytes: Uint8Array): string {\n let binary = '';\n for (const byte of bytes) binary += String.fromCharCode(byte);\n const base64 = typeof btoa === 'function' ? btoa(binary) : Buffer.from(bytes).toString('base64');\n return base64.replaceAll('+', '-').replaceAll('/', '_').replaceAll('=', '');\n}\n\n/** A `frame-ancestors` source: `'self'`, `'none'`, or an origin. */\nexport type FrameAncestorSource = string;\n\nexport interface FrameAncestorsOptions {\n readonly self?: boolean;\n readonly origins?: readonly string[];\n readonly allowNone?: boolean;\n}\n\n/** The `frame-ancestors` value: `'self'` and the origins, deduplicated; `'none'` when empty. */\nexport function buildFrameAncestors(options: FrameAncestorsOptions = {}): string {\n const { self = true, origins = [], allowNone = false } = options;\n const seen = new Set<string>();\n const out: FrameAncestorSource[] = [];\n if (allowNone && !self && origins.length === 0) return \"'none'\";\n if (self) {\n out.push(\"'self'\");\n seen.add(\"'self'\");\n }\n for (const origin of origins) {\n const trimmed = origin.trim();\n if (trimmed.length === 0 || seen.has(trimmed)) continue;\n seen.add(trimmed);\n out.push(trimmed);\n }\n return out.length > 0 ? out.join(' ') : \"'none'\";\n}\n\n/**\n * A `script-src` value permitting one nonce plus optional extra sources.\n * `'strict-dynamic'` is opt-in: it makes CSP 3 browsers ignore `'self'` and\n * host sources, so every script on the page must then carry the nonce.\n * @internal\n */\nexport function buildScriptSrcWithNonce(\n nonce: string,\n options: {\n readonly self?: boolean;\n readonly extra?: readonly string[];\n readonly strictDynamic?: boolean;\n } = {},\n): string {\n if (nonce.length === 0) throw new RangeError('buildScriptSrcWithNonce: nonce is empty');\n const { self = true, extra = [], strictDynamic = false } = options;\n const parts: string[] = [];\n if (self) parts.push(\"'self'\");\n parts.push(`'nonce-${nonce}'`);\n if (strictDynamic) parts.push(\"'strict-dynamic'\");\n for (const e of extra) {\n const trimmed = e.trim();\n if (trimmed.length > 0) parts.push(trimmed);\n }\n return parts.join(' ');\n}\n\n/** `union` (default) adds sources to an existing directive; `replace` overwrites it. */\nexport interface CspDirectiveMerge {\n readonly value: string;\n readonly mode?: 'union' | 'replace';\n}\n\n/**\n * Merge directives into an existing `Content-Security-Policy` header value.\n * Commas separate policies (that is how `Headers.get()` joins repeated\n * headers); each is merged, because a browser enforces every policy and\n * widening only the last would leave the others blocking.\n */\nexport function mergeCspHeader(\n existing: string,\n additions: Readonly<Record<string, string | CspDirectiveMerge>>,\n): string {\n const policies = existing.split(',').filter((policy) => policy.trim().length > 0);\n if (policies.length === 0) return mergeCspPolicy('', additions);\n return policies.map((policy) => mergeCspPolicy(policy, additions)).join(', ');\n}\n\nfunction mergeCspPolicy(\n existing: string,\n additions: Readonly<Record<string, string | CspDirectiveMerge>>,\n): string {\n const directives = new Map<string, string>();\n for (const part of existing.split(';')) {\n const trimmed = trimCspWhitespace(part);\n if (trimmed.length === 0) continue;\n const whitespaceIndex = trimmed.search(CSP_ASCII_WHITESPACE);\n const name = asciiLowercase(whitespaceIndex < 0 ? trimmed : trimmed.slice(0, whitespaceIndex));\n // CSP3 §2.2.1: a user agent ignores later duplicates, so a looser\n // duplicate must not become the policy that is serialized.\n if (directives.has(name)) continue;\n const value = whitespaceIndex < 0 ? '' : trimCspWhitespace(trimmed.slice(whitespaceIndex));\n directives.set(name, value);\n }\n\n for (const [rawName, rawAddition] of Object.entries(additions)) {\n const name = asciiLowercase(rawName);\n const addition: CspDirectiveMerge =\n typeof rawAddition === 'string' ? { value: rawAddition } : rawAddition;\n const mode = addition.mode ?? 'union';\n const current = directives.get(name);\n if (mode === 'replace' || current === undefined || current.length === 0) {\n directives.set(name, addition.value);\n continue;\n }\n const seen = new Set<string>();\n const merged: string[] = [];\n for (const token of [\n ...current.split(CSP_ASCII_WHITESPACE),\n ...addition.value.split(CSP_ASCII_WHITESPACE),\n ]) {\n if (token.length === 0 || seen.has(token)) continue;\n seen.add(token);\n merged.push(token);\n }\n // `'none'` cannot coexist with other sources.\n const withoutNone = merged.filter((token) => token !== \"'none'\");\n directives.set(name, (withoutNone.length > 0 ? withoutNone : merged).join(' '));\n }\n\n const out: string[] = [];\n for (const [name, value] of directives) {\n out.push(value.length === 0 ? name : `${name} ${value}`);\n }\n return out.join('; ');\n}\n","/**\n * `LivePreviewClient` configuration. Defaults are the 2.0 rows; `defaults: 'v1'`\n * restores the 1.x values named per option (ADR 0007).\n */\n\nimport type { CachedElement, FieldRenderer, RendererKey, RichTextRenderer } from '@core/types';\nimport type { StrategyHandlers } from '@core/strategies';\nimport {\n runtimeDefaultsFor,\n type DefaultsProfile,\n type EventSourcePolicy,\n} from '@/types/defaults-profile';\n\nexport interface LivePreviewClientConfig {\n /** Explicit trusted admin origins. */\n readonly allowedOrigins?: readonly string[];\n /** Payload origin; every update is then re-fetched through the REST API so relations arrive populated. Requires `mergeDepth`. */\n readonly serverURL?: string;\n /** REST route prefix used with `serverURL`. Default `/api`. */\n readonly apiRoute?: string;\n /** Population depth used with `serverURL`. Required with it; `defaults: 'v1'` falls back to `1`. */\n readonly mergeDepth?: number;\n /** Custom fetch for the `serverURL` merge request: attach auth headers or route through a proxy. */\n readonly mergeFetch?: typeof fetch;\n /** Verbose console output. Defaults to dev-mode detection. */\n readonly debug?: boolean;\n /** Debounce window for incoming updates. Default 50 ms. */\n readonly debounceMs?: number;\n /** Heartbeat timeout in ms; `0` disables it (default), because the admin posts only on edits. */\n readonly heartbeatMs?: number;\n /** IntersectionObserver `rootMargin`. Default `200px`. */\n readonly intersectionRootMargin?: string;\n /** Update only bindings under a matching `data-payload-owner`; an unowned binding is then never updated. Default `false`. */\n readonly scopeBindingsByOwner?: boolean;\n /** Skip a binding whose value did not change. Default `true`; `defaults: 'v1'` sets `false`. */\n readonly skipUnchanged?: boolean;\n /** Scroll the preview to the field being edited when its value changes. Default `false`. */\n readonly revealEditedField?: boolean;\n /**\n * Find bindings by value on the connection's first message: a scalar whose\n * value is the whole content of exactly one element is bound to it as if\n * `data-payload-field` stood there; every guess is stamped `data-payload-guessed`\n * and listed in `inspect().bindings.guessed`. Default `'off'`.\n */\n readonly autoBind?: 'off' | 'unique';\n /** Fields whose change re-applies other bindings regardless of their own value: `{ price: ['priceLabel'] }`. Used with `skipUnchanged`. */\n readonly dependencies?: Readonly<Record<string, readonly string[]>>;\n /** Strategy handlers beyond patching; `createFragmentStrategy()` from `payload-live-preview/fragment` builds one. */\n readonly strategies?: StrategyHandlers;\n /** Apply every update regardless of visibility. Default `false`. */\n readonly disableVisibilityGate?: boolean;\n /** Cache size above which off-screen updates wait for intersection. Default `50`. */\n readonly visibilityGateThreshold?: number;\n /** Mount an `aria-live` region for connections, applied updates and heartbeat disconnects. Default `true`. */\n readonly enableA11y?: boolean;\n /** Locale of the announcement strings. Defaults to the detected locale. */\n readonly a11yLocale?: string;\n /** Document root. Default `document`. */\n readonly root?: Document | Element;\n /** Renderer resolution ahead of the registry; return `undefined` to fall through. */\n readonly resolveRenderer?: (\n fieldType: RendererKey,\n target: CachedElement,\n ) => FieldRenderer | undefined;\n /** The project's rich-text renderer, shared with SSR. Its output is sanitized. */\n readonly renderRichText?: RichTextRenderer;\n /** Ignore `document.referrer` as an origin source. Default `true`; `defaults: 'v1'` sets `false`. */\n readonly disableReferrerDetection?: boolean;\n /** Disable the dev-mode localhost matcher. Default `false`. */\n readonly disableLocalhostMatching?: boolean;\n /** Which windows may post updates. Default `'parent-or-opener'`; `defaults: 'v1'` sets `'any'`. */\n readonly eventSourcePolicy?: EventSourcePolicy;\n /**\n * Sanitizer policy for this client's rich text and HTML writes. Default\n * `'strict'`; `defaults: 'v1'` sets `'compat'`. Per instance: it leaves the\n * process default that `setSanitizerPolicy()` sets for direct `sanitizeHtml()` calls alone.\n */\n readonly sanitizerPolicy?: 'compat' | 'strict';\n /** `'v2'` (default) is the 2.0 table; `'v1'` restores every 1.x row at once. Explicit options win. */\n readonly defaults?: DefaultsProfile;\n /** Start the runtime in the constructor. Default `true`. */\n readonly autoStart?: boolean;\n /** Preview-token validator; every update must then carry a `previewToken` it approves. Stock Payload sends none. */\n readonly validateToken?: (\n token: string | undefined,\n origin: string,\n ) => boolean | Promise<boolean>;\n}\n\n/** The configuration with the `defaults` profile applied: explicit options win, `'v1'` changes nothing. */\nexport function withProfileDefaults(config: LivePreviewClientConfig): LivePreviewClientConfig {\n // `'v1'` fills the rows too: the runtime's own fallbacks are the 2.0 values\n // since the default flip, so leaving the config alone would hand a v1 client\n // the strict sanitizer and `skipUnchanged` it opted out of.\n const rows = runtimeDefaultsFor(config.defaults);\n return {\n ...config,\n skipUnchanged: config.skipUnchanged ?? rows.skipUnchanged,\n disableReferrerDetection: config.disableReferrerDetection ?? rows.disableReferrerDetection,\n eventSourcePolicy: config.eventSourcePolicy ?? rows.eventSourcePolicy,\n sanitizerPolicy: config.sanitizerPolicy ?? rows.sanitizerPolicy,\n };\n}\n","/**\n * The one rule shared by the adapters, the client and the inline generator:\n * `serverURL` needs an explicit `mergeDepth` under the 2.0 defaults (ADR 0007,\n * entry 10). It lives in the leaf `types` domain because the inline generator\n * is server-side code that may not reach the browser runtime in `core`, and\n * three copies of the check had already drifted in what they treated as\n * \"no server\" and \"no depth\".\n */\n\nimport type { DefaultsProfile } from '@/types/defaults-profile';\n\n/**\n * The population depth is a deliberate choice; the 1.x default of 1 stays only\n * behind `defaults: 'v1'`. An empty `serverURL` fetches nothing and owes no\n * depth; `null` counts as omitted because the inline wire config carries it.\n */\nexport function assertMergeDepthExplicit(options: {\n readonly defaults?: DefaultsProfile | undefined;\n readonly serverURL?: string | undefined;\n readonly mergeDepth?: number | null | undefined;\n}): void {\n if (options.defaults === 'v1') return;\n if ((options.serverURL ?? '') === '' || options.mergeDepth != null) return;\n throw new Error(\n 'payload-live-preview: `serverURL` needs an explicit `mergeDepth` under the 2.0 defaults — ' +\n \"choose the population depth deliberately (0 for none), or pass `defaults: 'v1'` to keep \" +\n 'the 1.x default of 1 while migrating (ADR 0007, entry 10).',\n );\n}\n","/**\n * The authorized preview context's shape and brand, in the leaf `types` domain\n * so producer and consumers recognise the same context. See ADR 0006.\n */\n\n/**\n * The brand key, in the type and on the object.\n *\n * This was a `unique symbol` until 2026-08-30. A `unique symbol` is nominal per\n * *declaration*, and the published entries each carry their own declaration\n * file — so `AuthorizedPreviewContext` from the root barrel was a different\n * type from the one in `./server` or in an adapter, and the documented flow\n * (authorize once, hand the context to the adapter hook and to the draft read)\n * did not type-check in any combination a consumer can write.\n *\n * That is the same trap the runtime brand below already avoids by using\n * `Symbol.for` rather than `Symbol()`; the lesson simply had not reached the\n * type. A shared string literal is identical in every bundle for the same\n * reason a registry symbol is.\n *\n * It is not what makes a context trustworthy. `isAuthorizedPreviewContext`\n * decides that, on the registry symbol and on `Object.isFrozen`, and every\n * consumption point calls it — the adapter policy, the draft read and the\n * binding emitter. Writing this key by hand buys nothing.\n */\nexport const AUTHORIZED_PREVIEW_BRAND_KEY = 'payload-live-preview.authorized-preview-context';\n\nexport type PreviewAuthorizationStrategyName = 'payload-session' | 'signed-token' | 'verifier';\n\n/** What a context is bound to; every field is optional because every strategy binds differently. */\nexport interface AuthorizedPreviewScope {\n /** The site origin the credential was issued for. */\n readonly audience?: string;\n /** The request pathname the credential is valid for. */\n readonly path?: string;\n readonly locale?: string;\n}\n\n/** The verdict of a successful `authorizePreviewRequest()`: frozen, branded, produced only there. Carry it, do not rebuild it. */\nexport interface AuthorizedPreviewContext {\n readonly [AUTHORIZED_PREVIEW_BRAND_KEY]: true;\n readonly strategy: PreviewAuthorizationStrategyName;\n /** The user id, token subject, or whatever the verifier named. */\n readonly subject: string | undefined;\n /** Unix milliseconds. */\n readonly authorizedAt: number;\n /** Unix milliseconds, or `undefined` when the strategy does not know. */\n readonly expiresAt: number | undefined;\n readonly scope: AuthorizedPreviewScope;\n /** The minimal request material a draft read forwards to Payload — one verified cookie, never the whole `Cookie` header. */\n readonly payloadHeaders: Readonly<Record<string, string>>;\n}\n\n// A registry symbol: entries are separate bundles, and a per-bundle `Symbol()`\n// would refuse the other's contexts in the package while unit tests passed.\nconst BRAND = Symbol.for(AUTHORIZED_PREVIEW_BRAND_KEY);\n\n/** Whether `value` was produced by `authorizePreviewRequest()`; a copy or JSON round trip is not. */\nexport function isAuthorizedPreviewContext(value: unknown): value is AuthorizedPreviewContext {\n return (\n typeof value === 'object' &&\n value !== null &&\n (value as Record<PropertyKey, unknown>)[BRAND] === true &&\n Object.isFrozen(value)\n );\n}\n\n/** Internal: the one place a context is made. */\nexport function createAuthorizedPreviewContext(\n fields: Omit<AuthorizedPreviewContext, typeof AUTHORIZED_PREVIEW_BRAND_KEY>,\n): AuthorizedPreviewContext {\n const context = Object.freeze({\n ...fields,\n scope: Object.freeze({ ...fields.scope }),\n payloadHeaders: Object.freeze({ ...fields.payloadHeaders }),\n [BRAND]: true,\n [AUTHORIZED_PREVIEW_BRAND_KEY]: true,\n });\n // No cast: the frozen object carries the brand key the interface declares.\n return context;\n}\n","/**\n * What each capability tells the runtime, for `inspect()` and consumer\n * diagnostics. Kept out of the runtime module so the inline bundle ships the\n * rules and not this prose. See ADR 0010.\n */\nimport type { ProtocolCapability } from './protocol-version';\n\nexport interface CapabilityDocumentation {\n /** The runtime behaviour that depends on the capability. */\n readonly gates: string;\n /** What the runtime does without it. */\n readonly fallback: string;\n}\n\nexport const CAPABILITY_DOCUMENTATION: Readonly<\n Record<ProtocolCapability, CapabilityDocumentation>\n> = {\n basic: {\n gates: 'data updates are applied to bound elements',\n fallback: 'none — every peer has it',\n },\n 'schema-json': {\n gates: 'field typing from fieldSchemaJSON (Payload 2.x) and the payload-2 profile',\n fallback: 'field types come from DOM heuristics and Lexical auto-detection',\n },\n locale: {\n gates:\n 'locale-aware field resolution (`title_de` before `title`) and the locale on island events',\n fallback: 'bindings resolve the unsuffixed field value',\n },\n 'preview-token': {\n gates: 'per-message token validation (library extension)',\n fallback: 'messages carry no token; validateToken cannot be satisfied',\n },\n 'nested-arrays': {\n gates: 'keyed array diffs below the top level',\n fallback: 'array updates replace the whole array',\n },\n 'recursive-diffs': {\n gates: 'recursive object diffs',\n fallback: 'nested objects re-render as a unit',\n },\n 'document-events': {\n gates: 'the `documentSave` runtime event, the document-save plugin and the payload-3 profile',\n fallback: 'no documentSave event; a save is not distinguishable from an edit',\n },\n 'relationship-events': {\n gates:\n 'the `relationshipUpdate` runtime event and an unconditional re-render of the update that carries it',\n fallback: 'a related document edited in a drawer shows up on the next data update only',\n },\n};\n","/**\n * The seam between a host framework's own router and the route strategy.\n *\n * The route strategy answers a revision by fetching the route and morphing it\n * into the living page. On a page whose DOM belongs to a reconciler that is\n * working against the framework, and it was seen to break once: `removeChild`\n * on `null` inside React's commit phase, over markup this package had patched.\n * A host that re-renders the route itself does the same job without the morph\n * and without the second HTML request, so it is given the chance to.\n *\n * Why a named slot on `window` and not a reference: the runtime is an inline\n * script that builds its strategy before any application code has hydrated, so\n * there is nothing to hand a component; `window.__livePreview`, the only other\n * public surface, is created later and not at all outside a preview; and the\n * two richer extension points — plugins and events — are reachable only through\n * the programmatic client, which a page using an adapter does not have. One\n * slot, written by whoever mounts and read at the moment of a refresh, is the\n * smallest thing that survives both orders of arrival.\n */\n\n/**\n * A host's own route refresh. It must settle once the fresh markup is\n * committed: the runtime re-applies the revision on top of it, and doing that\n * against the markup being replaced would write into nodes about to be dropped.\n */\nexport type RouteRefresh = () => void | Promise<void>;\n\n/** Read late, so it does not matter whether the runtime or the component came first. */\nconst SLOT = '__livePreviewRouteRefresh';\n\ntype WindowSlot = Record<string, RouteRefresh | undefined>;\n\nfunction slot(): WindowSlot | undefined {\n return typeof window === 'undefined' ? undefined : (window as unknown as WindowSlot);\n}\n\n/**\n * Lend the runtime the host's route refresh; the return value undoes it, for a\n * component's cleanup. A later registration wins, and undoing one that has\n * already been replaced does nothing — two components on one page would\n * otherwise take the slot from each other on unmount.\n */\nexport function registerRouteRefresh(refresh: RouteRefresh): () => void {\n const target = slot();\n if (target === undefined) return () => undefined;\n target[SLOT] = refresh;\n return () => {\n // Cleared rather than deleted: the slot is read through `?.` anyway, and\n // removing the key buys nothing a lint rule would not have to be argued out of.\n if (target[SLOT] === refresh) target[SLOT] = undefined;\n };\n}\n\n/** The registered refresh, or `undefined` on a page that registered none. */\nexport function readRouteRefresh(): RouteRefresh | undefined {\n return slot()?.[SLOT];\n}\n","/**\n * Every diagnostic code the runtime and tools emit, so a consumer can branch\n * on `e.code` instead of matching message text. A code is never reused for a\n * different meaning; a retired one stays reserved.\n *\n * Browser-side reporting sites write the literal (`code: 'LP0603'`) rather than\n * reading it from this record: the frozen table would then ship in the inline\n * runtime for the sake of six characters — it did, 1 287 B in every page, for\n * the one read Z6 left in the strategy runner, and `diagnostic-codes.test.ts`\n * now holds the artifact free of it. Server-side tools may import it.\n */\n\n/**\n * Every diagnostic code the runtime can report, by name.\n *\n * ```ts\n * client.events.on('error', (e) => {\n * if (e.code === DIAGNOSTIC_CODES.TransformThrew) reportToSentry(e.error);\n * });\n * ```\n */\nexport const DIAGNOSTIC_CODES = Object.freeze({\n /** No trusted origin configured in production; nothing will be accepted. */\n NoTrustedOrigin: 'LP0101',\n /** Origin trust rests on `document.referrer`, so any framing site is trusted. */\n ReferrerOnlyTrust: 'LP0102',\n /** A plugin declares a runtime range this runtime does not satisfy; it was refused. */\n PluginIncompatible: 'LP0103',\n /** The page carries the lean runtime and needs a feature that profile leaves out. */\n ProfileFeatureOmitted: 'LP0104',\n\n /** An update named a field with no binding anchor on the page. */\n OrphanField: 'LP0201',\n /** Owner scoping is on and the update names no document it could belong to. */\n UnattributableUpdate: 'LP0202',\n\n /** The visibility gate held offscreen writes back until they scroll into view. */\n VisibilityGateDeferred: 'LP0301',\n\n /** A value was refused because the attribute or the value itself is unsafe. */\n UnsafeAttributeWrite: 'LP0401',\n /** A text element has structured children, so replacing its text was skipped. */\n TextTargetHasChildren: 'LP0402',\n /** A structural container has no array template, so the update was skipped. */\n MissingArrayTemplate: 'LP0403',\n /** A structural item has no `id`; it pairs positionally, so an insert re-renders every row after it. */\n StructuralItemUnkeyed: 'LP0404',\n /** Two structural items share a key; later ones pair positionally. */\n StructuralDuplicateKey: 'LP0405',\n /** Every structural key changed while the length did not; the source generates keys per message. */\n StructuralUnstableKeys: 'LP0406',\n /** A binding asks for a delivery strategy this release does not have; it is left unchanged. */\n UnsupportedStrategy: 'LP0407',\n /** `data-payload-format` names a format the vocabulary does not contain; the default formatting was used instead. */\n UnknownValueFormat: 'LP0408',\n /** The strict sanitizer removed an attribute the 1.x `'compat'` policy kept. */\n SanitizerDroppedAttribute: 'LP0409',\n /** A Lexical block has no renderer; the markup the server rendered for it is kept instead. */\n UnrenderedBlockKept: 'LP0410',\n /** A patch cannot reach what the server would have drawn; `onUnfaithfulPatch` decided what happens next. */\n UnfaithfulPatch: 'LP0411',\n /** The first write to a date, number or checkbox binding replaced a different reading of the same value. */\n ServerFormatReplaced: 'LP0412',\n /** A Lexical block has no renderer, and the write could not keep the markup the server rendered for it; it is gone. */\n UnrenderedBlockLost: 'LP0413',\n\n /** A message was rejected before it reached the update pipeline. */\n MessageRejected: 'LP0501',\n /** A preview token was rejected. */\n TokenRejected: 'LP0502',\n /** A trusted origin sent a message this protocol version does not recognise. */\n ProtocolShapeUnknown: 'LP0503',\n\n /** A consumer event handler threw. */\n HandlerThrew: 'LP0601',\n /** A consumer transform threw; the original value was kept. */\n TransformThrew: 'LP0602',\n /** A renderer threw while writing a value. */\n RendererThrew: 'LP0603',\n // LP0604 is reserved and unassigned; codes are never reused or renumbered.\n /** Runtime startup failed. */\n StartupFailed: 'LP0605',\n /** Sending the ready handshake failed. */\n ReadyFailed: 'LP0606',\n /** The page declared hydration, but no React commit or Vue mount came within the cap; the runtime started without waiting. */\n HydrationWaitTimedOut: 'LP0607',\n\n /** The audit found no runtime in a response that carried preview intent. */\n AuditRuntimeMissing: 'LP0701',\n /** The preview response declares no `frame-ancestors`. */\n AuditNoFrameAncestors: 'LP0702',\n /** `X-Frame-Options` forbids framing, which no CSP can undo; `SAMEORIGIN` forbids it from another origin only. */\n AuditFrameOptionsBlocks: 'LP0703',\n /** Binding attributes are served to anonymous visitors. */\n AuditBindingsExposed: 'LP0704',\n /** More bindings than the default visibility gate will write eagerly. */\n AuditGateThresholdExceeded: 'LP0705',\n /** Owner markers exist, but some bindings are outside all of them. */\n AuditUnownedBindings: 'LP0706',\n /** The preview response carries no bindings at all. */\n AuditNoBindings: 'LP0707',\n /** The URL did not return an HTML page, so nothing else can be judged. */\n AuditNotAPage: 'LP0708',\n /** A fragment request failed (network, timeout, server error); the boundary was patched instead. */\n FragmentRequestFailed: 'LP0801',\n /** The fragment response had the wrong content type or shape; the boundary was patched instead. */\n FragmentResponseInvalid: 'LP0802',\n /** The fragment endpoint refused the preview (not authorized); the boundary was patched instead. */\n FragmentUnauthorized: 'LP0803',\n /** A fragment response arrived for a revision that was already superseded and was discarded. */\n FragmentSuperseded: 'LP0804',\n /** A route refresh was refused: the loop guard, or the strategy's minimum interval. */\n RouteRefreshLoop: 'LP0805',\n /** A boundary asks for the fragment strategy but no fragment handler is configured; it is patched. */\n FragmentStrategyUnavailable: 'LP0806',\n /** A revision changed a field with no binding; `onUnfaithfulPatch` refreshed the route. */\n UnboundChangeRefresh: 'LP0807',\n /** A readiness row is not yet at its 2.0 value; `pll doctor --v2` reports it. */\n V2ReadinessGap: 'LP0709',\n /** The preview runtime is served to anonymous visitors, not only inside the admin frame. */\n RuntimeOnPublicPage: 'LP0710',\n} as const);\n\n/** A diagnostic code, as it appears in log output and on the `error` event. */\nexport type DiagnosticCode = (typeof DIAGNOSTIC_CODES)[keyof typeof DIAGNOSTIC_CODES];\n","/**\n * Typed helpers emitting the `data-payload-*` attributes the runtime reads.\n * `bindByPath` records the path through a Proxy, so a rename follows.\n */\n\nimport type { FieldName } from './paths';\n\n/** A spreadable attribute record: `<h1 {...bind<Homepage>('heroTitle')}>`. */\nexport interface FieldBindingAttributes {\n readonly 'data-payload-field': string;\n readonly 'data-payload-attribute'?: string;\n readonly 'data-payload-type'?: string;\n readonly 'data-payload-richtext'?: string;\n readonly 'data-payload-html'?: string;\n readonly 'data-payload-locale'?: string;\n readonly 'data-payload-alt'?: string;\n readonly 'data-payload-href'?: string;\n readonly 'data-payload-array-template'?: string;\n}\n\nexport interface BindOptions {\n /** Attribute to write instead of the text content, e.g. `'src'` for `<img>`. */\n readonly attribute?: string;\n /** Explicit field type, bypassing schema detection. */\n readonly type?: string;\n /** Mark the binding as Lexical rich text; needed only when the initial render is empty. */\n readonly richtext?: boolean;\n /** Render the value as sanitised HTML rather than text. */\n readonly html?: boolean;\n /** Lock this element to one locale, overriding the message locale. */\n readonly locale?: string;\n /** Field whose value becomes the image `alt`. */\n readonly alt?: string;\n /** Field whose value becomes the link `href`. */\n readonly href?: string;\n /** Markup per array item with `{{value}}` placeholders. */\n readonly arrayTemplate?: string;\n}\n\n/** `bind<Homepage>('heroTitle')`; without `T` any string is accepted. */\nexport function bind<T = Record<string, unknown>>(\n field: FieldName<T>,\n options?: BindOptions,\n): FieldBindingAttributes {\n return buildAttributes(field, options);\n}\n\n/** `bindByPath<Homepage>(d => d.slides[0].title)` → `slides.title`; array indices are dropped because bindings resolve against the schema. */\n// `T` is used once, by design: the caller names the document type so the\n// picker is checked against it instead of against an untyped `d`.\n// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-parameters\nexport function bindByPath<T = Record<string, unknown>>(\n picker: (data: T) => unknown,\n options?: BindOptions,\n): FieldBindingAttributes {\n const path = recordPath(picker);\n if (path.length === 0) {\n throw new Error(\n 'bindByPath: the picker did not read any field — return data.<field> instead of a constant',\n );\n }\n return buildAttributes(path.join('.'), options);\n}\n\nfunction buildAttributes(field: string, options: BindOptions | undefined): FieldBindingAttributes {\n if (field.length === 0) {\n throw new Error('bind: field name must be a non-empty string');\n }\n const attrs: {\n 'data-payload-field': string;\n 'data-payload-attribute'?: string;\n 'data-payload-type'?: string;\n 'data-payload-richtext'?: string;\n 'data-payload-html'?: string;\n 'data-payload-locale'?: string;\n 'data-payload-alt'?: string;\n 'data-payload-href'?: string;\n 'data-payload-array-template'?: string;\n } = { 'data-payload-field': field };\n if (options?.attribute !== undefined) attrs['data-payload-attribute'] = options.attribute;\n if (options?.type !== undefined) attrs['data-payload-type'] = options.type;\n // Presence attributes: the runtime tests for the attribute, not its value.\n if (options?.richtext === true) attrs['data-payload-richtext'] = '';\n if (options?.html === true) attrs['data-payload-html'] = '';\n if (options?.locale !== undefined) attrs['data-payload-locale'] = options.locale;\n if (options?.alt !== undefined) attrs['data-payload-alt'] = options.alt;\n if (options?.href !== undefined) attrs['data-payload-href'] = options.href;\n if (options?.arrayTemplate !== undefined) {\n attrs['data-payload-array-template'] = options.arrayTemplate;\n }\n return attrs;\n}\n\nfunction recordPath(picker: (data: never) => unknown): string[] {\n const path: string[] = [];\n const proxy: unknown = new Proxy(\n {},\n {\n get(_target, prop: string | symbol): unknown {\n if (typeof prop === 'symbol') return undefined;\n if (/^\\d+$/.test(prop)) return proxy;\n path.push(prop);\n return proxy;\n },\n },\n );\n try {\n picker(proxy as never);\n } catch {\n // A picker doing math or JSX on the proxy throws after recording the path it meant.\n }\n return path;\n}\n","/**\n * Binding helpers gated on one authorization verdict per request: the\n * attributes publish the content model, so an unauthorized response carries\n * none and a binding is suppressed whole, never in part. See ADR 0006.\n */\n\nimport {\n isAuthorizedPreviewContext,\n type AuthorizedPreviewContext,\n} from '@/types/authorized-preview';\nimport { bind, bindByPath, type BindOptions, type FieldBindingAttributes } from './bind';\nimport type { FieldName } from './paths';\n\nexport interface OwnerBindingAttributes {\n readonly 'data-payload-owner': string;\n}\n\n/** The attributes marking a server-rendered boundary (ADR 0011, docs/hybrid.md). */\nexport interface FragmentBoundaryAttributes {\n readonly 'data-payload-fragment': string;\n readonly 'data-payload-fragment-key'?: string;\n readonly 'data-payload-depends'?: string;\n}\n\nexport interface FragmentBoundaryOptions {\n /** Distinguishes boundaries when one registry id renders several on a page. */\n readonly key?: string;\n /** The fields that re-render the boundary. Without it, every update does. */\n readonly dependsOn?: readonly string[];\n}\n\n/**\n * Stricter than the endpoint's own check, which accepts either case: an id is\n * written here, and one that only differs in case from the registry key is a\n * boundary that silently never renders.\n */\nconst REGISTRY_ID = /^[a-z][a-z0-9-]{0,63}$/u;\nconst MAX_KEY_LENGTH = 128;\n\n/** No attributes at all: an unauthorized response is byte-identical to one that never knew about live preview. */\nexport type SuppressedBinding = Readonly<Record<string, never>>;\n\nconst SUPPRESSED: SuppressedBinding = Object.freeze({});\n\n/** The verdict from `authorizePreviewRequest()`, or `null` for a public response. Only a branded context authorizes emission. */\nexport interface PreviewBindingsOptions {\n readonly authorization: AuthorizedPreviewContext | null;\n /** Document this subtree belongs to, emitted as `data-payload-owner`; needed with `scopeBindingsByOwner`. */\n readonly owner?: string;\n}\n\n/** Request-scoped binding helpers carrying one authorization decision. */\nexport interface PreviewBindings {\n readonly authorized: boolean;\n /** Typed field binding, or nothing while unauthorized. */\n bind: <T = Record<string, unknown>>(\n field: FieldName<T>,\n options?: BindOptions,\n ) => FieldBindingAttributes | SuppressedBinding;\n /** Rename-safe field binding, or nothing while unauthorized. */\n // `T` names the caller's document type; see bindByPath in ./bind.\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-parameters\n bindByPath: <T = Record<string, unknown>>(\n picker: (data: T) => unknown,\n options?: BindOptions,\n ) => FieldBindingAttributes | SuppressedBinding;\n /** Owner marker for this subtree, or nothing while unauthorized or without an owner. */\n owner: () => OwnerBindingAttributes | SuppressedBinding;\n /**\n * A server-rendered boundary, or nothing while unauthorized — the id and the\n * fields it depends on describe the content model as much as a binding does.\n * The registry behind `id` is the endpoint's (docs/hybrid.md).\n */\n boundary: (\n id: string,\n options?: FragmentBoundaryOptions,\n ) => FragmentBoundaryAttributes | SuppressedBinding;\n}\n\n/** Built whether or not the response is authorized, so a bad id fails everywhere, not only in preview. */\nfunction boundaryAttributes(\n id: string,\n options: FragmentBoundaryOptions,\n): FragmentBoundaryAttributes {\n if (!REGISTRY_ID.test(id)) {\n throw new RangeError(\n `createPreviewBindings().boundary(): \"${id}\" is not a registry id — lowercase, starting ` +\n 'with a letter, then letters, digits or hyphens (max 64). The runtime would post it and ' +\n 'the endpoint would refuse it.',\n );\n }\n const key = options.key;\n if (key !== undefined && (key.length === 0 || key.length > MAX_KEY_LENGTH)) {\n throw new RangeError(\n `createPreviewBindings().boundary(): the key for \"${id}\" must be 1 to ${String(MAX_KEY_LENGTH)} characters.`,\n );\n }\n const dependsOn = options.dependsOn ?? [];\n return {\n 'data-payload-fragment': id,\n ...(key !== undefined ? { 'data-payload-fragment-key': key } : {}),\n ...(dependsOn.length > 0 ? { 'data-payload-depends': dependsOn.join(',') } : {}),\n };\n}\n\n/** Request-scoped `bind`, `bindByPath` and `owner`, all suppressed unless `authorization` is a real context. */\nexport function createPreviewBindings(options: PreviewBindingsOptions): PreviewBindings {\n // A copied or hand-written context is a public response.\n const authorized = isAuthorizedPreviewContext(options.authorization);\n const owner = options.owner !== undefined && options.owner.length > 0 ? options.owner : undefined;\n\n return Object.freeze({\n authorized,\n bind: <T = Record<string, unknown>>(\n field: FieldName<T>,\n bindOptions?: BindOptions,\n ): FieldBindingAttributes | SuppressedBinding =>\n authorized ? bind<T>(field, bindOptions) : SUPPRESSED,\n // `T` names the caller's document type; see bindByPath in ./bind.\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-parameters\n bindByPath: <T = Record<string, unknown>>(\n picker: (data: T) => unknown,\n bindOptions?: BindOptions,\n ): FieldBindingAttributes | SuppressedBinding =>\n authorized ? bindByPath<T>(picker, bindOptions) : SUPPRESSED,\n owner: (): OwnerBindingAttributes | SuppressedBinding =>\n authorized && owner !== undefined ? { 'data-payload-owner': owner } : SUPPRESSED,\n boundary: (\n id: string,\n boundaryOptions: FragmentBoundaryOptions = {},\n ): FragmentBoundaryAttributes | SuppressedBinding => {\n const attributes = boundaryAttributes(id, boundaryOptions);\n return authorized ? attributes : SUPPRESSED;\n },\n });\n}\n","/**\n * Narrow public entry — the minimum API for sites that only need to\n * receive postMessage updates and apply them to the DOM.\n *\n * Consumers who import from `payload-live-preview/core`\n * get a bundle that **does not** include:\n *\n * - the built-in plugin constructors (`@plugins/built-in/*`)\n * - the inline-script generator and the embedded runtime source\n * - the framework adapters\n *\n * The client still includes its built-in field renderers, including Lexical\n * rendering. The omitted exports add weight without being needed on a typical\n * production page. The full entry (`payload-live-preview`) re-exports them for\n * users who want the convenience.\n *\n * @packageDocumentation\n */\n\nexport { VERSION } from './version';\n/** @internal */\nexport const CORE_ENTRY = true;\n\n// High-level client — without the heavyweight built-in plugins.\nexport { LivePreviewClient } from './client';\nexport { initLivePreview, type LivePreviewClientConfig } from './client';\n\n// Security primitives (consumers building their own CSP)\nexport {\n buildFrameAncestors,\n buildScriptSrcWithNonce,\n generateCspNonce,\n setCspCrypto,\n isSafeUrl,\n isExternalHttpUrl,\n sanitizeHtml,\n setSanitizerDocument,\n escapeHtml,\n escapeHtmlAttribute,\n type FrameAncestorsOptions,\n type SanitizerDocument,\n} from './security';\n\n// Events\nexport { EventEmitter } from './events';\nexport { type EventHandler, type LivePreviewEventMap, type Unsubscribe } from './events';\n\n// Detection helpers\nexport { OriginDetector } from './detection';\nexport {\n detectInitialLocale,\n isInIframe,\n isInPopup,\n isInPreviewContext,\n isDevMode,\n} from './detection';\n\n// Protocol negotiation — needed for any consumer that wants to branch\n// on capabilities.\nexport {\n LIBRARY_PROTOCOL_VERSION,\n hasCapability,\n negotiateProtocol,\n} from './core/protocol-version';\nexport type { ProtocolCapability, ProtocolNegotiation } from './core/protocol-version';\nexport { CAPABILITY_DECLARATIONS, PROTOCOL_CAPABILITIES } from './core/protocol-version';\nexport type { CapabilityDeclaration, CapabilitySource } from './core/protocol-version';\nexport { CAPABILITY_DOCUMENTATION } from './core/protocol-capability-docs';\nexport type { CapabilityDocumentation } from './core/protocol-capability-docs';\nexport { detectProtocolProfile } from './core/protocol-profile';\nexport type { ProtocolProfile, ProtocolProfileName } from './core/protocol-profile';\nexport type {\n InspectionBindings,\n InspectionOrigins,\n InspectionProtocol,\n InspectionRevisions,\n PluginInspection,\n InspectionFidelity,\n InspectionFragments,\n InspectionRoute,\n InspectionScheduler,\n LivePreviewInspection,\n} from './core/inspection/types';\nexport type {\n FragmentContext,\n FragmentReport,\n FragmentStrategy,\n RouteContext,\n RouteOutcome,\n RouteStrategy,\n StrategyHandlers,\n UpdateSource,\n} from './core/strategies';\nexport { registerRouteRefresh, type RouteRefresh } from './core/route-refresh';\nexport type { PayloadDocumentEventDetail } from './types/payload-protocol';\nexport { DIAGNOSTIC_CODES, type DiagnosticCode } from './core/diagnostic-codes';\nexport type { ConnectionStatus } from './core/state';\n\n// Typed binding DSL — small enough to live in the core slice\nexport { bind, bindByPath, createPreviewBindings } from './dsl';\nexport type { DefaultsProfile, EventSourcePolicy } from './types/defaults-profile';\n// The branded verdict `createPreviewBindings({ authorization })` accepts. The\n// producer (`authorizePreviewRequest`) lives on the root entry; the guard is a\n// few lines and belongs wherever the type is accepted.\nexport {\n AUTHORIZED_PREVIEW_BRAND_KEY,\n isAuthorizedPreviewContext,\n type AuthorizedPreviewContext,\n type AuthorizedPreviewScope,\n type PreviewAuthorizationStrategyName,\n} from './types/authorized-preview';\nexport type {\n BindOptions,\n FieldBindingAttributes,\n FieldName,\n FieldPath,\n FragmentBoundaryAttributes,\n FragmentBoundaryOptions,\n OwnerBindingAttributes,\n PreviewBindings,\n PreviewBindingsOptions,\n SuppressedBinding,\n ValueAt,\n} from './dsl';\n\n// Core types\nexport type {\n CachedElement,\n CustomRendererKey,\n FieldRenderer,\n FieldType,\n RenderContext,\n RendererKey,\n RichTextRenderer,\n} from './core/types';\n\n// Payload protocol types\nexport type {\n PayloadFieldCondition,\n PayloadFieldSchema,\n PayloadFieldType,\n PayloadLivePreviewData,\n PayloadLivePreviewMessage,\n} from './types/payload-protocol';\nexport type { PluginCompatibility } from './plugins';\nexport type { SanitizerPolicyMode } from './security';\n\n// Island interoperability — the bridge event and the boundary test (docs/renderers.md, islands).\nexport { ISLAND_EVENT, isInsideIsland, type IslandUpdateDetail } from './core/islands';\n"],"mappings":"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TtN,GAA0B,SAATA,EAEjB,+HAKF,+HAGJ,CAWkE6G,CAAO7G,OAEzE,CCrDA,IAAMo0B,kBAAA,IAAwCpyB,IAAI,CAChD,IACA,KACA,SACA,IACA,KACA,IACA,IACA,IACA,SACA,OACA,QACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,aACA,OACA,MACA,MACA,OACA,MACA,IACA,OACA,MACA,UACA,UACA,QACA,SACA,SACA,MACA,SACA,aACA,MACA,UACA,SACA,QACA,QACA,MACA,MACA,KACA,OACA,OACA,OACA,IACA,QACA,QACA,QACA,QACA,KACA,KACA,KACA,UACA,WACA,QAIIqyB,kBAAA,IAAyCryB,IAAI,CACjD,QACA,SACA,WACA,SACA,SACA,UAIIsyB,kBAAA,IAA6CtyB,IAAI,CACrD,SACA,QACA,SACA,SACA,QACA,OACA,OACA,OACA,OACA,QACA,SACA,SACA,WACA,MACA,OACA,WACA,QACA,WACA,WACA,aAGIuyB,kBAAA,IAAuCvyB,IAAI,CAC/C,KACA,QACA,OACA,MACA,QACA,OACA,aAGIwyB,GAAmB,QACnBC,GAAmB,QAGnBC,GAA6D,CACjE9xB,iBAAG,IAAIZ,IAAI,CAAC,OAAQ,SAAU,MAAO,WAAY,WAAY,SAC7D2yB,mBAAK,IAAI3yB,IAAI,CAAC,MAAO,SAAU,QAAS,MAAO,QAAS,SAAU,UAAW,aAC7E4yB,uBAAS,IAAI5yB,IAAI,IACjBgF,sBAAA,IAAYhF,IAAI,CAAC,MAAO,SAAU,QAAS,OAAQ,UACnD6yB,qBAAO,IAAI7yB,IAAI,CAAC,MAAO,WAAY,WAAY,OAAQ,QAAS,YAChE8yB,qBAAA,IAAW9yB,IAAI,CACb,MACA,SACA,WACA,WACA,OACA,QACA,UACA,QACA,SACA,gBAEF+yB,oBAAM,IAAI/yB,IAAI,CAAC,aACfgzB,oBAAM,IAAIhzB,IAAI,CAAC,UACfizB,iBAAG,IAAIjzB,IAAI,CAAC,SACZkzB,0BAAY,IAAIlzB,IAAI,CAAC,SACrBmzB,qBAAO,IAAInzB,IAAI,CAAC,YAChBozB,kBAAA,IAAQpzB,IAAI,CAAC,UAAW,UAAW,QAAS,UAAW,SACvDqzB,kBAAI,IAAIrzB,IAAI,CAAC,UAAW,UAAW,YACnCszB,mBAAK,IAAItzB,IAAI,CAAC,SACduzB,wBAAU,IAAIvzB,IAAI,CAAC,SACnBwzB,kBAAI,IAAIxzB,IAAI,CAAC,QAAS,WAAY,SAClCyzB,kBAAI,IAAIzzB,IAAI,CAAC,UACb2K,oBAAM,IAAI3K,IAAI,CAAC,UACf0zB,mBAAK,IAAI1zB,IAAI,CAAC,WAGV2L,sBAA0C3L,IAAI,CAAC,OAAQ,MAAO,OAAQ,WAQ/D2zB,GAAN,cAAwCvX,MAC3Bpe,KAAO,6BAqCrB41B,kBAAA,IAA+C5zB,IAAI,CACvD,KACA,OACA,mBACA,0BACA,iCAuEI6zB,kBAA+B9F,OAAOC,IAAI,2CAgBzC,SAAS8F,aAAa5F,EAAc9nB,GACzC,OAAO2tB,GAAuB7F,OAAM,EAAW9nB,EACjD,CAOO,SAAS2tB,GACd7F,EACAC,EACA/nB,GAEA,MAAMuM,EAAMqhB,KACZ,IAAKrhB,EAAK,KAesB,oBAArBshB,kBAAoCA,iBACtC,IAAI7X,MAAM,4BAEZ,IAAIuX,GACT,iFAlBF,GAAa,KAATzF,EAAa,MAAO,GAExB,MAAMzd,EAlFR,SACErK,EACA8tB,GAEA,MAAM3nB,EAAOnG,GAAS+nB,QAAU+F,GAfK,SAgBrC,IAAK9tB,EAAS,CACZ,MAAM+tB,qBAAc7sB,IACpB,UAAYskB,EAAKwI,KAAUx1B,OAAOqI,QAAQyrB,IAAcyB,EAAQv4B,IAAIgwB,EAAKwI,GACzE,MAAO,CACLC,YAAajC,GACbkC,UAAWH,EACXI,mBAAmB,EACnBC,cAAc,EACdjoB,OACAkoB,2BAAA,IAAiBz0B,IAErB,CACA,MAAM00B,EAAU,IAAI10B,IAAIoyB,IAExB,GADAhsB,EAAQuuB,uBAAuBC,QAAShJ,GAAQ8I,EAAQt0B,IAAIwrB,KAC1B,IAA9BxlB,EAAQmuB,kBAA4B,UAAW3I,KAAOyG,GAAeqC,EAAQt0B,IAAIwrB,GACrF,MAAMuI,iBAAA,IAAc7sB,IACpB,UAAYskB,EAAKwI,KAAUx1B,OAAOqI,QAAQyrB,IAAcyB,EAAQv4B,IAAIgwB,EAAKwI,GACzE,UAAYxI,EAAKwI,KAAUx1B,OAAOqI,QAAQb,EAAQyuB,6BAA+B,IAAK,CACpF,MAAMtY,EAAS,IAAIvc,IAAIm0B,EAAQ34B,IAAIowB,IACnC,UAAWkJ,KAAQV,EAAO7X,EAAOnc,IAAI00B,GACrCX,EAAQv4B,IAAIgwB,EAAKrP,EACnB,CACA,MAAO,CACL8X,YAAaK,EACbJ,UAAWH,EACXI,mBAAiD,IAA9BnuB,EAAQmuB,kBAC3BC,cAAuC,IAAzBpuB,EAAQouB,aACtBjoB,OACAkoB,YAAa,IAAIz0B,IAAIoG,EAAQ2uB,uBAAuBvY,IAAKxe,GAASA,EAAKgd,gBAE3E,CA+CmBkU,CAAc9oB,EAAS+nB,GAClC6G,EAAWriB,EAAIzW,cAAc,YAInC,OAFA84B,EAASC,UAAYhH,GAAYC,GACjCgH,GAAiBF,EAASG,QAAS1kB,GAC5BukB,EAASC,SAClB,CAcA,SAASjB,KACP,GAAgC,oBAArBC,mBAAqCA,iBAAkB,CAChE,MAAMvF,EAAYJ,WAA4BuF,IAC9C,GAAInF,EAAU,OAAOA,CACvB,CACA,GAAwB,oBAAbh1B,SACX,OAAOA,QACT,CAOA,SAASw7B,GAAiB9P,EAAkB+I,GAE1C,UAAW1D,KAASltB,MAAMsL,KAAKuc,EAAKyL,YA5LjB,IA6LbpG,EAAMhkB,SACR2uB,GAAgB3K,EAAkB0D,GA7LnB,IA8LN1D,EAAMhkB,UACfgkB,EAAM9vB,QAGZ,CAEA,SAASy6B,GAAgB35B,EAAkB0yB,GACzC,MAAMvC,EAAMnwB,EAAQoR,QAAQmO,cAE5B,IAAIsX,GAAkBnyB,IAAIyrB,IAAUuC,EAAOoG,mBAAqBlC,GAAclyB,IAAIyrB,GAAlF,CAKA,IAAKuC,EAAOkG,YAAYl0B,IAAIyrB,GAG1B,OAFAsJ,GAAiBz5B,EAAS0yB,QAC1B1yB,EAAQ41B,eAAe51B,EAAQo1B,aASnC,SAA4Bp1B,EAAkBmwB,EAAauC,GACzD,MAAMkH,EAAWlH,EAAOmG,UAAU94B,IAAIowB,GAEtC,UAAWkJ,KAAQv3B,MAAMsL,KAAKpN,EAAQipB,YAAa,CACjD,MAAM1mB,EAAO82B,EAAK92B,KAAKgd,cACvB,GAAIhd,EAAKsN,WAAW,OAAkB,UAATtN,EAC3BvC,EAAQwf,gBAAgB6Z,EAAK92B,UAD/B,CAIA,GAAoB,WAAhBmwB,EAAO5hB,KAAmB,CAC5B,GAAI4hB,EAAOqG,cAAgBZ,GAAoBzzB,IAAInC,GAAO,SAG1D,GAAa,OAATA,GAA0B,SAATA,GAAmBA,EAAKsN,WA5QvB,iBA4QwD,CAC5E7P,EAAQwf,gBAAgB6Z,EAAK92B,MAGhB,SAATA,IAA2C,IAAxBq3B,GAAUl1B,IAAInC,IAAUm0B,GAA6Bn0B,GAC5E,QACF,CACA,GAAIA,EAAKsN,WAAWmnB,IAAmB,CAChCtE,EAAOsG,YAAYt0B,IAAInC,KAC1BvC,EAAQwf,gBAAgB6Z,EAAK92B,MAC7Bm0B,GAAuBn0B,IAEzB,QACF,CACA,GAAIu0B,GAAYpyB,IAAInC,IAASA,EAAKsN,WAAWknB,IAAmB,QAClE,SACED,GAAYpyB,IAAInC,IAChBA,EAAKsN,WAAWknB,KAChBx0B,EAAKsN,WAAWmnB,IAEhB,SAEE4C,GAAUl1B,IAAInC,GACZ2N,GAAexL,IAAInC,KAAUkN,UAAU4pB,EAAKh3B,OAC9CrC,EAAQwf,gBAAgB6Z,EAAK92B,MACX,WAATA,GAAsBs3B,GAAaR,EAAKh3B,QACjDrC,EAAQwf,gBAAgB6Z,EAAK92B,MAIjCvC,EAAQwf,gBAAgB6Z,EAAK92B,KAnC7B,CAoCF,CACF,CAlDEu3B,CAAmB95B,EAASmwB,EAAKuC,GACrB,MAARvC,GA+DN,SAAsB4J,GACpB,MAAM1J,EAAO0J,EAAO37B,aAAa,QACpB,OAATiyB,GAAkBrgB,kBAAkBqgB,KACxC0J,EAAOp5B,aAAa,MAAO,uBACtBo5B,EAAOtY,aAAa,WAAWsY,EAAOp5B,aAAa,SAAU,UACpE,CApEmBq5B,CAAah6B,GAC9By5B,GAAiBz5B,EAAS0yB,EAV1B,MAFE1yB,EAAQd,QAaZ,CAkDA,SAAS26B,GAAax3B,GACpB,UAAWwuB,KAAaxuB,EAAM0iB,MAAM,KAAM,CACxC,MAAMpV,EAAUkhB,EAAUjhB,OAC1B,GAAuB,IAAnBD,EAAQtR,OAAc,SAE1B,MAAOqR,EAAMC,GAAWA,EAAQoV,MAAM,KAAM,GAC5C,IAAKtV,UAAUC,GAAM,OAAO,CAC9B,CACA,OAAO,CACT,CClbA,IAAMuqB,GAAiD92B,OAAO+2B,OAAO,CACnE,IAAK,QACL,IAAK,OACL,IAAK,OACL,IAAK,SACL,IAAK,SACL,IAAK,SACL,IAAK,SACL,IAAK,WAGDC,GAAsB,cAGrB,SAASC,WAAWpsB,GAGzB,OAAOA,EAAK1B,QAAQ6tB,GAAsBE,GAASJ,GAAaI,GAClE,CAOA,IAAMC,GAAiDn3B,OAAO+2B,OAAO,CACnE,IAAK,QACL,IAAK,OACL,IAAK,OACL,IAAK,SACL,IAAK,WAGDK,GAAsB,WAGrB,SAASC,oBAAoBn4B,GAGlC,OAAOA,EAAMiK,QAAQiuB,GAAsBF,GAASC,GAAaD,GACnE,CC9BA,IAAMI,GAAsB,sBAiBrB,SAASC,GAAoBC,GAClC,MAAMh3B,iBAAA,IAAWY,IACjB,UAAWiI,KAAQmuB,EACjB,GAAoB,iBAATnuB,GAA8B,OAATA,EAChC,UAAWjB,KAAOpI,OAAOQ,KAAK6I,GAAO7I,EAAKgB,IAAI4G,GAEhD,OAAO5H,CACT,CAEO,SAASi3B,GACdrB,EACA/sB,EACAL,EACAqF,EACAqpB,GAEA,MAAMv4B,EAAyB,iBAATkK,GAA8B,OAATA,EAAgBA,EAAO,KAElE,OAAO+sB,EAASjtB,QAAQmuB,GAAqB,CAACK,EAAavvB,IAG1C,OAAXjJ,GA9BR,SAAgBA,EAAgBiJ,GAC9B,OAAOpI,OAAOD,UAAUob,eAAeC,KAAKjc,EAAQiJ,EACtD,CA4B2BwvB,CAAOz4B,EAAQiJ,GAC7B6uB,WAAW5oB,EAAU7J,QAAQ5H,IAAIuC,EAAQiJ,KAEnC,OAAXjJ,GAA2B,UAARiJ,EAAwB6uB,WAAW5oB,EAAUhF,IACxD,UAARjB,EAAwBrK,OAAOiL,GAIpB,OAAX7J,IAA2C,IAAxBu4B,GAAWn2B,IAAI6G,GAAsB,GACrDuvB,EAEX,CAcO,SAASE,GAAqB3P,GACnC,MAAMsP,EAAQtP,EAAU3M,SAClB8R,EAAQmK,EAAM,GACpB,QAAc,IAAVnK,EAAqB,MAAO,GAChC,MAAMwC,EAA+B,GACrC,UAAWzwB,KAAEA,EAAAF,MAAMA,KAAWP,MAAMsL,KAAKojB,EAAMvH,YAAa,CAC1D,IAAK9Y,EAAoB5N,IAASA,EAAKsN,WAlEV,iBAkEgD,SAC7E,IAAIorB,GAAY,EAChB,QAAS9uB,EAAQ,EAAGA,EAAQwuB,EAAMt8B,QAAU48B,EAAW9uB,GAAS,EAC9D8uB,EAAYN,EAAMxuB,IAAQ/N,aAAamE,KAAUF,EAE/C44B,GAAWjI,EAAO5wB,KAAK,CAACG,EAAMF,GACpC,CACA,OAAO2wB,CACT,CAGO,SAASkI,GAAsB1uB,EAAewmB,GACnD,UAAYzwB,EAAMF,KAAU2wB,EACrBxmB,EAAKiV,aAAalf,IAAOiK,EAAK7L,aAAa4B,EAAMF,EAE1D,CC7FO,SAAS84B,GAAc94B,GAC5B,GAAIA,QAAuC,MAAO,GAClD,GAAqB,iBAAVA,EAAoB,OAAOA,EACtC,GAAqB,iBAAVA,GAAuC,kBAAVA,GAAwC,iBAAVA,EACpE,OAAOnB,OAAOmB,GAEhB,IACE,OAAOkP,KAAKC,UAAUnP,EACxB,OACE,MAAO,EACT,CACF,CAGO,SAAS+4B,GAAa/4B,GAC3B,OAAOA,SAAmD,KAAVA,CAClD,CCTO,SAASg5B,GAAata,EAAgBxV,GAC3C,MAAMlJ,EAAQ0e,EAAIhhB,IAAIwL,GAKtB,YAJc,IAAVlJ,IACF0e,EAAI3f,OAAOmK,GACXwV,EAAI5gB,IAAIoL,EAAKlJ,IAERA,CACT,CAGO,SAASi5B,GAAava,EAAgBxV,EAAQlJ,EAAUk5B,GAG7D,OAFAxa,EAAI5gB,IAAIoL,EAAKlJ,GAMR,SAAoB0e,EAAsBwa,GAC/C,UAAWC,KAAUza,EAAIpd,OAAQ,CAC/B,GAAIod,EAAIqD,MAAQmX,EAAO,MACvBxa,EAAI3f,OAAOo6B,EACb,CACF,CAVEC,CAAQ1a,EAAKwa,GACNl5B,CACT,CCHA,IAAMq5B,GAAyC,CAC7C,QACA,WACA,SACA,SACA,SACA,QACA,UACA,UACA,SACA,QACA,QACA,WACA,SAGIC,GAA+C,CACnD,OACA,OACA,cACA,OACA,WACA,WACA,WACA,UACA,WACA,QACA,MACA,MACA,OACA,OACA,OACA,MACA,WACA,QACA,OACA,SACA,OAGIC,GAAqB,uCAMrBC,kBAAA,IAAwBhwB,IAGvB,SAASiwB,GAAwBvC,GACtC,MAAMwC,EAASV,GAAOQ,GAAmBtC,GACzC,QAAe,IAAXwC,EAAsB,OAAOA,EACjC,MAAMC,EAAO,IAAIz3B,IAAIm3B,IACrB,UAAWO,KAAS1C,EAAS2C,SAASN,IAAqB,CACzD,MAAMzL,EAAM8L,EAAM,IAAI1c,mBACV,IAAR4Q,GAAmB6L,EAAKr3B,IAAIwrB,EAClC,CACA,MAAMlH,EAAgD,GACtD,UAAWkH,KAAO6L,EAAM/S,EAAWkH,GAAOwL,GAC1C,MAAMhxB,EAA2B,CAC/BuuB,sBAAuB,IAAI8C,GAC3B5C,4BAA6BnQ,EAC7B6P,mBAAmB,EACnBC,cAAc,GAEhB,OAAOuC,GAAOO,GAAmBtC,EAAU5uB,EApBT,GAqBpC,CChEO,IAAMwxB,GAAgB,mBACvBC,GAAuB,0BACvBC,GAA4B,+BAmC3B,SAASC,GAAuB3xB,GACrC,MAAM4xB,EAAOC,GAAsB7xB,EAAQ0gB,UAAW1gB,EAAQmC,QAASnC,GACvE,OAAa,OAAT4xB,EAAsB,KACnBE,GAAqBF,EAAM5xB,EAAQ+xB,MAAO,CAC/CC,MAAOhyB,EAAQgyB,QAAS,EACxB3H,eAAgBrqB,EAAQqqB,gBAE5B,CAoCA,SAAS4H,GAAoBC,EAAgBzgB,GAC3C,OACEA,EAASqF,aAAa2a,KAAyBhgB,EAASqF,aAAa4a,GAEzE,CAGA,SAASG,GACPnR,EACAve,EACAgwB,GAEA,MAAMtxB,EAwER,SACE6f,EACAkR,EACAO,GAEA,MAAMvD,SAAEA,EAAAwD,UAAUA,EAAA5mB,YAAWA,GAAc,EAAAumB,MAAOA,EAAA7e,gBAAOA,GAAoBif,EACvEE,EAASN,EAAM38B,IAAIsrB,GAGnB2H,EAASgI,GAAqB3P,GAC9B4R,EAAevC,GAAoBqC,GACnCG,EAAkBp7B,MAAMsL,KAAKie,EAAU3M,UACvCye,EAAgBC,GAAiBF,EAAiBf,IAClDkB,iBAAA,IAAe94B,IACfiH,EAAiC,GACvC,QAASW,EAAQ,EAAGA,EAAQ4wB,EAAU1+B,OAAQ8N,GAAS,EAAG,CACxD,MAAM9J,EAAQ06B,EAAU5wB,GAClBZ,EAAM+xB,GAAQj7B,GACpB,IAAIkqB,OACM,IAARhhB,EACK2xB,EAAgB/wB,IAAU,KAC1BoxB,GAAmBJ,EAAe5xB,IAAQ,KACpC,OAATghB,GAAiB8Q,EAAS34B,IAAI6nB,KAAOA,EAAO,MACnC,OAATA,GAAe8Q,EAAS14B,IAAI4nB,GAChC,MAAMjgB,EAAUiwB,EAAKiB,SAAS94B,IAAIyH,GAE5BiQ,EADcjG,GAAeomB,EAAKkB,QAAQ/4B,IAAIyH,IAAmB,OAATogB,EAE1DmR,GACErS,EAAU9qB,cACVg5B,EACAl3B,EACA8J,EACA0R,EACAmV,EACAiK,QAEF,EACJ,GAAiB,OAAb7gB,EAAmB,OAAO,KAC9B,MAAMuhB,OACS,IAAbvhB,EACI,GACAwhB,GACEtxB,EAAU,KAAOigB,EACjBnQ,EACA/Z,OACQ,IAARkJ,OAAoB,EAAYyxB,GAAQj9B,IAAIwL,GAC5CuxB,GAER,GAAoB,OAAhBa,EAAsB,OAAO,KACjCnyB,EAAQpJ,KAAK,CAAC+J,EAAOogB,EAAMnQ,EAAUuhB,EAAarxB,GACpD,CACA,OAAOd,CACT,CA5HkBqyB,CAAsBxS,EAmIxC,SAAyBve,GACvB,MAAM2wB,iBAAA,IAAcl5B,IACdi5B,iBAAA,IAAej5B,IACrB,UAAWu5B,KAAShxB,EACC,WAAfgxB,EAAM3wB,MAAoC,WAAf2wB,EAAM3wB,KAAmBswB,EAAQ94B,IAAIm5B,EAAM3xB,OAClD,YAAf2xB,EAAM3wB,OACbswB,EAAQ94B,IAAIm5B,EAAM3xB,OAClBqxB,EAAS74B,IAAIm5B,EAAM3xB,QAGvB,MAAO,CAAEsxB,UAASD,WACpB,CA9ImDO,CAAgBjxB,GAAUgwB,GAC3E,OAAmB,OAAZtxB,EAAmB,KAAO,CAAC6f,EAAW7f,EAASsxB,EAAIC,UAC5D,CAEA,SAASN,GACPF,EACAG,EACA/xB,GAEA,MAAO0gB,EAAW7f,EAASuxB,GAAaR,EAClClH,iBAAA,IAAc9wB,IACpB,IAAIy5B,GAAU,EACd,UAAY7xB,EAAOogB,EAAMnQ,EAAUuhB,EAAarxB,KAAYd,EAAS,CACnE,IAAIme,EAAO4C,EACX,QAAiB,IAAbnQ,EAAwB,CAG1B,MAAM6hB,KACJtzB,EAAQgyB,OAAUrwB,GAAoB,OAATigB,IACzBuH,GAAavH,EAAMnQ,EAAU,CAC3BwX,cAAe,CAACuI,GAAeC,IAC/BxH,iBAAkBgI,WACa,IAA3BjyB,EAAQqqB,eACR,CAAEA,eAAgBrqB,EAAQqqB,gBAC1B,OACCzI,EAEb,IAAK0R,EACH,UAAYC,EAAUC,KAAiBR,EACpB,OAAbO,IACJE,GAAsBF,EAAUC,GAChCA,EAAavI,YAAYsI,IAG7B,UAAW,EAAKxf,KAAaif,OACV,IAAbjf,GAAwB+d,GAAqB/d,EAAUge,EAAO/xB,GAEhEszB,EACFD,GAAU,GAEG,OAATzR,IACFA,EAAKqJ,YAAYxZ,GACjB4hB,GAAU,GAEZrU,EAAOvN,EAEX,CACA,GAAa,OAATuN,EAAe,SACnB,MAAMzJ,EAASmL,EAAU3M,SAASvS,IAAU,KACxCwd,IAASzJ,IACXmL,EAAU4K,aAAatM,EAAMzJ,GAC7B8d,GAAU,GAEZ3I,EAAQ1wB,IAAIglB,EACd,CAEA,UAAWqF,KAASltB,MAAMsL,KAAKie,EAAU3M,UACnC2W,EAAQ3wB,IAAIsqB,KAChBA,EAAM9vB,SACN8+B,GAAU,GAEZ,MAAMhB,EA6JR,SAAmB3R,EAAoBqR,GACrC,IAAI3b,EAAM2b,EAAM38B,IAAIsrB,GAKpB,OAJKtK,IACHA,iBAAA,IAAUlV,IACV6wB,EAAMv8B,IAAIkrB,EAAWtK,IAEhBA,CACT,CApKiBsd,CAAUhT,EAAWqR,GACpCM,EAAOjZ,QACP,UAAW1hB,KAAS06B,EAAWuB,GAAatB,EAAQ36B,GACpD,OAAO27B,CACT,CAgFA,SAASJ,GACPW,EACAC,EACAje,EACAke,EACA3B,GAEA,MACM4B,EAAgBtB,GADO,OAAZmB,EAAmB,GAAKI,GAAsBJ,GACdnC,IAC3CwC,EAA0B,GAChC,UAAWC,KAAWF,GAAsBH,GAAU,CACpD,MAAMjzB,EAAMszB,EAAQzgC,aAAag+B,IACjC,GAAY,OAAR7wB,EAAc,SAClB,MAAMuzB,EAAUvB,GAAmBmB,EAAenzB,IAAQ,KACpDwzB,EAAeF,EAAQzgC,aAAai+B,IAEpC6B,EAAWa,EAAeD,EAAU,KACpCE,EAAmBd,GAAU9/B,aAAai+B,KAA8B,KAC9E,IAAI3d,EACJ,GAAIqgB,EAAc,CAChB,MAAME,EAAaC,GAAgB3e,EAAWhV,GAC9C,QAAmB,IAAf0zB,GAAyC,OAAbf,EAAmB,CACjD,MAAMiB,EAAeF,GAAc,GAE7BnyB,EAAUH,EADgB,OAAbuxB,EAAoB,GAAMgB,GAAgBT,EAAWlzB,IAAQ,GAC1C4zB,GAChCC,EAA+B,OAAblB,GAAqBc,IAAqBD,EAClE,IAAIjyB,EAAQzO,OAAS,GAAK+gC,KACxB1gB,EACE8d,GAAsB0B,GAAYW,EAAS/xB,EAAS,CAClDysB,SAAUwF,EACVhC,UAAWoC,EACXhpB,YAAaipB,EACb1C,MAAOI,EAAIJ,MACX7e,gBAAiBif,EAAIjf,wBACjB,OACS,IAAba,GAAwB,OAAO,IAEvC,CACF,CACAkgB,EAAMx8B,KAAK,CAAC87B,EAAUW,EAASngB,GACjC,CACA,OAAOkgB,CACT,CAGA,SAASD,GAAsBnyB,GAC7B,OAAO1K,MAAMsL,KAAKZ,EAAKyX,iBAAiB,IAAImY,QAA0BxkB,OAAQ0C,IAC5E,IAAI+kB,EAAW/kB,EAAKsH,cACpB,KAAoB,OAAbyd,GAAqBA,IAAa7yB,GAAM,CAC7C,GAAI6yB,EAAS5d,aAAa2a,IAAuB,OAAO,EACxDiD,EAAWA,EAASzd,aACtB,CACA,OAAOyd,IAAa7yB,GAExB,CAEA,SAAS4xB,GAAsBr4B,EAAiBwD,GAC9C,UAAW+V,KAAaxd,MAAMsL,KAAKrH,EAAOkjB,YACnC1f,EAAOkY,aAAanC,EAAU/c,OAAOwD,EAAOyZ,gBAAgBF,EAAU/c,MAE7E,UAAW+c,KAAaxd,MAAMsL,KAAK7D,EAAO0f,YACpCljB,EAAO3H,aAAakhB,EAAU/c,QAAU+c,EAAUjd,OACpD0D,EAAOpF,aAAa2e,EAAU/c,KAAM+c,EAAUjd,MAGpD,CAEA,SAAS68B,GAAgB78B,EAAgBkJ,GACvC,GAAqB,iBAAVlJ,GAAgC,OAAVA,EAAgB,OACjD,MAAMi9B,EAAUj9B,EAAkCkJ,GAClD,OAAOzJ,MAAMC,QAAQu9B,GAAWA,OAAgC,CAClE,CAWA,SAAShB,GAAatB,EAA8B36B,GAClD,MAAMkJ,EAAM+xB,GAAQj7B,QACR,IAARkJ,GAAmByxB,EAAO78B,IAAIoL,EAAKlJ,EACzC,CAEA,SAASi7B,GAAQj7B,GACf,GAAqB,iBAAVA,GAAgC,OAAVA,EAAgB,OACjD,MAAM3B,EAAM2B,EAAsC,GAClD,MAAqB,iBAAP3B,GAAiC,iBAAPA,EAAkBQ,OAAOR,QAAM,CACzE,CAEA,SAAS08B,GAAiBxN,EAA8BtQ,GACtD,MAAMigB,iBAAA,IAAc1zB,IAEpB,QAASM,EAAQyjB,EAASvxB,OAAS,EAAG8N,GAAS,EAAGA,GAAS,EAAG,CAC5D,MAAMnM,EAAU4vB,EAASzjB,GACzB,QAAgB,IAAZnM,EAAuB,SAC3B,MAAMuL,EAAMvL,EAAQ5B,aAAakhB,GACjC,GAAY,OAAR/T,EAAc,SAClB,MAAMyV,EAASue,EAAQx/B,IAAIwL,QACZ,IAAXyV,EAAsBue,EAAQp/B,IAAIoL,EAAK,CAACvL,IACvCghB,EAAO5e,KAAKpC,EACnB,CACA,OAAOu/B,CACT,CAEA,SAAShC,GAAmBgC,EAAiCh0B,GAC3D,OAAOg0B,EAAQx/B,IAAIwL,IAAMi0B,KAC3B,CAGA,SAAS9B,GACPn9B,EACAg5B,EACAl3B,EACA8J,EACAumB,EACAM,EACA6H,GAEA,MACM4E,EAAOnH,GADEsC,GAAyBrB,EAAUl3B,EAAO8J,EAAOgvB,GAAeN,GACnCnI,EAAQoJ,GAAwBvC,IACtE1M,EAAOtsB,EAAcE,cAAc,YACzCosB,EAAK2M,UAAYhH,GAAYiN,GAC7B,MAAMjP,EAAQ3D,EAAK6M,QAAQ5J,kBAC3B,IAAKU,EAAO,OAAO,KAGnB0K,GAAsB1K,EAAOwC,GAC7B,MAAMznB,EAAM+xB,GAAQj7B,GAEpB,YADY,IAARkJ,GAAmBilB,EAAM7vB,aAAaw7B,GAAe5wB,GAClDilB,CACT,CC/XO,SAASkP,GACdlvB,EACAC,EACA1K,GAEI0K,EAAMiL,yBACVjL,EAAMiL,wBAAyB,EAC/BlL,EAAKrG,KACH,2BAA2BpE,EAAO8K,4FAEtC,CAGO,SAAS8uB,GACdnvB,EACAC,EACA1K,GAEI0K,EAAM8K,eAAe7W,IAAIqB,EAAO/F,WACpCyQ,EAAM8K,eAAe5W,IAAIoB,EAAO/F,SAChCwQ,EAAKrG,KACH,2BAA2BpE,EAAO8K,iCAAiC3P,OAAO6E,EAAOkf,oDAErF,CCMO,IAAM2a,GAAN,MACL,WAAAvgC,CACmBmR,EACAC,EACAoc,GAFAntB,KAAA8Q,OACA9Q,KAAA+Q,QACA/Q,KAAAmtB,MAChB,CAHgBrc,KACAC,MACAoc,KAGnB,aAAAgT,CAAcprB,GACZ,MAAMwQ,EAAWvlB,KAAK8Q,KAAKsF,WAAWC,SACtC,YAAiB,IAAbkP,EAA+B,KAC5B6a,GAAe7a,EAAUA,EAASsX,KAAK78B,KAAK8Q,KAAKzF,KAAM0J,GAChE,CAWA,kBAAAsrB,CACE3qB,EACA3T,EACAoF,GAEA,GAAIuO,EAAY4qB,eAAgB,OAChC,MAAMjqB,SAAEA,EAAAwQ,MAAUA,GAAU7mB,KAAK8Q,KAAKsF,WAChCmqB,OAA0B,IAAblqB,OAAyB,EAgThD,SAA4BlP,GAC1B,MAAMo5B,EAAwB,GAC9B,UAAWl6B,KAAUc,EAAS,CAC5B,MAAMq5B,EAAWn6B,EAAOof,iBACxB,QAAiB,IAAb+a,EAAwB,OACvBD,EAAW7sB,SAAS8sB,IAAWD,EAAW79B,KAAK89B,EACtD,CACA,OAAOD,CACT,CAxT4DE,CAAmBt5B,GAC3E,QAAiB,IAAbkP,QAAyC,IAAfkqB,EAI5B,OAHAvgC,KAAK+Q,MAAMoL,gBAAkBhV,EAAQxI,OACrC+W,EAAYgrB,kBAAoBH,EAAW5hC,YACtCqB,KAAK2gC,aAAajrB,EAAa3T,EAAMq+B,GAAe/pB,EAAUkqB,SAGvD,IAAV1Z,IACJ7mB,KAAK+Q,MAAMoL,gBAAkBhV,EAAQxI,OAChCqB,KAAK4gC,aAAalrB,EAAa3T,EAAM8kB,GAC5C,CAmBA,gBAAAga,CAAiBnrB,EAAgC3B,GAC/C,MAAMjD,KAAEA,EAAAC,MAAMA,GAAU/Q,KACxB,GAAI0V,EAAYjD,UAAYiD,EAAY4qB,eAAgB,OAAO,EAC/D,MAAMrrB,EAAUH,GACdhE,EAAKgD,MACL4B,EAAYX,QACZW,EAAY9V,OACZmU,GAEF,IAAI+sB,EAAW,EACf,UAAW3vB,KAAa8D,EAAa1D,EAAoBR,EAAOI,KAAY2vB,GAAY,GACxF,MAAOhQ,GAAS7b,EAChB,YAAc,IAAV6b,GAAkD,aAA3BhgB,EAAKH,wBACF,IAA1BG,EAAKsF,WAAWyQ,QACpB/V,EAAKO,IAAI,QAAS,SAAU,UAAUyf,2CACtC/f,EAAMoL,gBAAkB2kB,GACjB,EACT,CAGA,eAAAC,CAAgBhsB,GACd,UAAY5D,EAAW6C,KAAahU,KAAK8Q,KAAKgD,MAAMhI,UAClD,GAAKiJ,EAAQ/P,IAAImM,IACb6C,EAASC,KAAM5N,GAAmC,UAAxBA,EAAOqf,cAA2B,OAAO,EAEzE,OAAO,CACT,CAEA,kBAAMib,CACJjrB,EACA3T,EACA86B,GAEA,MAAM/rB,KAAEA,EAAAC,MAAMA,GAAU/Q,KAClB8d,EAAa,IAAIqJ,gBACvBpW,EAAMkM,mBAAqBa,EAC3B,MAAMH,EAAY,IAAe5M,EAAM4M,UAAUjI,KAAiBoI,EAAW2J,OAAOuZ,SAC9ErrB,QAAEA,GAAY7E,GACdnP,QAAEA,GAAY+T,EACd9P,EAAW8P,EAAY9P,SAASA,SAChCkb,EAAapL,EAAYoL,WACzBxB,EAA2B,CAC/BjU,KAAMyF,EAAKzF,KACXzF,WACAkb,aACA/d,OAAQhB,EAAKgB,OACbnD,OAAQ8V,EAAY9V,OACpBsZ,eACoC,iBAA3BvX,EAAQuX,eAA8BvX,EAAQuX,oBAAiB,EACxED,WAA0C,iBAAvBtX,EAAQsX,WAA0BtX,EAAQsX,gBAAa,EAC1EwO,OAAQ3J,EAAW2J,OACnB9J,YACAtM,IAAK,CAAC7B,EAAMyxB,KACVnwB,EAAKO,IAAI,WAAY7B,EAAMyxB,IAE7BhE,MAAO,CAACuD,EAAUzN,MAkPxB,SAAuByN,EAAmBzN,GACxC,MAAM8G,EAAW2G,EAAS3/B,cAAcE,cAAc,YACtD84B,EAASC,UAAYhH,GAAYC,GACjC,MAAMrW,EAAW8jB,EAASU,WAAU,GACpCxkB,EAASqI,OAAO8U,EAASG,SACzB5F,GAAaoM,EAAU9jB,EAAU,CAAEwX,cAAe,CAACuI,KACrD,CAvPQ0E,CAAcX,EAAUzN,IAE1BqL,MAAQoC,IACNxgC,KAAKohC,cAAc1rB,EAAa3T,EAAMy+B,IAExC9jB,SAAU,CAACpc,EAASU,EAAI6K,KACtB6J,EAAYgrB,kBAAoB,EAC3B/qB,EAAQgL,UACX,iBACA,CAAErgB,UAASU,KAAI6K,MAAK6L,OAAQ,WAAY9R,WAAUkb,cAClDnD,IAGJhB,OAAQ,CAACrc,EAASU,EAAI6K,EAAK2D,EAAM9F,KAC/BgM,EAAYgrB,kBAAoB,EAChC,MAAMO,EAAS,aAAajgC,0BAA2B0I,IAKvDoH,EAAKO,IAAI,WAAY7B,EAAMyxB,GACtBtrB,EAAQgL,UACX,QACA,CAAE5Z,MAAO,IAAIka,MAAMggB,GAAS3hB,QAAS,WAAY9P,QACjDmO,GAEGhI,EAAQgL,UACX,iBACA,CAAErgB,UAASU,KAAI6K,MAAK6L,OAAQ,SAAUlI,OAAM5J,WAAUkb,cACtDnD,KAIN,IAAI6U,EAAS,CAAE9V,SAAU,EAAGC,OAAQ,EAAGC,WAAY,GACnD,IACE4V,QAAeqK,EAAKtX,SAASlF,OAAOf,EAASud,EAAK0D,WACpD,OAASx5B,GAEP,GADA+J,EAAKO,IAAI,WAAY,SAAUtK,GAC3B4W,IAAa,CACf,UAAW6iB,KAAY3D,EAAK0D,WAAAvgC,KAAiBohC,cAAc1rB,EAAa3T,EAAMy+B,GAC9EhO,EAAS,CAAE9V,SAAU,EAAGC,OAAQkgB,EAAK0D,WAAW5hC,OAAQie,WAAY,EACtE,CACF,CACA7L,EAAM0L,cAAcC,UAAY8V,EAAO9V,SACvC3L,EAAM0L,cAAcE,QAAU6V,EAAO7V,OACrC5L,EAAM0L,cAAcG,YAAc4V,EAAO5V,WACpCe,MACD5M,EAAMkM,qBAAuBa,IAAY/M,EAAMkM,mBAAqB,MACxEvH,EAAYgrB,iBAAmB,EAK3BlO,EAAO9V,SAAW,GAAA1c,KAAQmtB,KAAKkU,eAAe3rB,EAAa3T,GAC3B,IAAhC+O,EAAKwwB,UAAUC,cAAoBxwB,EAAM6M,SAASlI,GAGtD1V,KAAKmtB,KAAKqU,cAAc9rB,GACnBiI,KACmB,IAApB6U,EAAO9V,UAA2D,IAAzC/G,EAAQE,cAAc,gBAC9CF,EAAQgL,UACX,cACA,CACE5e,OACA0/B,aAAcjP,EAAO9V,SACrBiI,WAAY3N,KAAKD,MAAQ+J,EACzBlb,WACAkb,aACAjX,OAAQ,YAEV8T,GAEJ,CAGA,kBAAMijB,CACJlrB,EACA3T,EACAwjB,GAEA,MAAMzU,KAAEA,EAAAC,MAAMA,GAAU/Q,KACxB,GAAI0V,EAAY4qB,eAOd,OANAvvB,EAAM8L,WAAWG,aAAe,OAChClM,EAAKO,IACH,QACA,SACA,YAAY7P,OAAOkU,EAAY9P,SAASA,wCAM5C8P,EAAY4qB,gBAAiB,QACvBtgC,KAAK0hC,SAAShsB,EAAa3T,EAAMwjB,EACzC,CAOQ,aAAAoc,CACNjsB,EACA3T,EACAwjB,EACAqc,GAEA,MAAM7wB,MAAEA,GAAU/Q,KACO,OAArB+Q,EAAMoM,YAAqB7d,aAAayR,EAAMoM,YAClDpM,EAAMoM,WAAalb,WAAW,KAC5B8O,EAAMoM,WAAa,KACdpM,EAAM4M,UAAUjI,IAChB1V,KAAK0hC,SAAShsB,EAAa3T,EAAMwjB,IACrCqc,EACL,CAGA,cAAcF,CACZhsB,EACA3T,EACAwjB,GAEA,MAAMzU,KAAEA,EAAAC,MAAMA,GAAU/Q,KAClB6hC,EAAQ9wB,EAAM8L,WACdiB,EAAa,IAAIqJ,gBACvBpW,EAAMmM,gBAAkBY,EACxB,MAAMH,EAAY,IAAe5M,EAAM4M,UAAUjI,KAAiBoI,EAAW2J,OAAOuZ,QACpF,IAAI5gB,EACJ,IACEA,QAAgBmF,EAASuc,QAAQ,CAC/Bl8B,SAAU8P,EAAY9P,SAASA,SAC/Bkb,WAAYpL,EAAYoL,WACxB2G,OAAQ3J,EAAW2J,OACnB9J,YACAtM,IAAK,CAAC7B,EAAMyxB,KACVnwB,EAAKO,IAAI,QAAS7B,EAAMyxB,IAE1Bc,WAAaH,IACX5hC,KAAK2hC,cAAcjsB,EAAa3T,EAAMwjB,EAAUqc,KAGtD,OAAS76B,GACP+J,EAAKO,IAAI,QAAS,SAAUtK,GAC5BqZ,EAAU,QACZ,CACA,GAAKzC,IAAL,CAEA,GADI5M,EAAMmM,kBAAoBY,IAAY/M,EAAMmM,gBAAkB,MAClD,cAAZkD,EAAyB,CAQ3B,GAPAyhB,EAAM/kB,WAAa,EAEnB/L,EAAMwL,mCAAA,IAA0Brd,QAGhCc,KAAKmtB,KAAKkU,eAAe3rB,EAAa3T,GACtC/B,KAAKmtB,KAAK6U,gBACLrkB,IAAa,OAmBlB,OAlBA3d,KAAKmtB,KAAK8U,QAAQvsB,EAAa3T,QAC3B+O,EAAK6E,QAAQE,cAAc,eAAiB,GACzC/E,EAAK6E,QAAQgL,UAChB,cACA,CACE5e,OAIA0/B,aAAc3wB,EAAKgD,MAAMwQ,aACzBK,WAAY3N,KAAKD,MAAQrB,EAAYoL,WACrClb,SAAU8P,EAAY9P,SAASA,SAC/Bkb,WAAYpL,EAAYoL,WACxBjX,OAAQ,SAEV8T,GAIN,CAGgB,WAAZyC,EAAsByhB,EAAMllB,QAAU,EACrB,YAAZyD,IAAuByhB,EAAM9kB,SAAW,GAGjD/c,KAAKmtB,KAAK8U,QAAQvsB,EAAa3T,EArCb,CAsCpB,CAGA,oBAAAi+B,CAAqB35B,GACnB25B,GAAqBhgC,KAAK8Q,KAAM9Q,KAAK+Q,MAAO1K,EAC9C,CAGA,uBAAA45B,CAAwB55B,GACtB45B,GAAwBjgC,KAAK8Q,KAAM9Q,KAAK+Q,MAAO1K,EACjD,CAGQ,aAAA+6B,CACN1rB,EACA3T,EACAy+B,GAEA,UAAYrvB,EAAW6C,KAAahU,KAAK8Q,KAAKgD,MAAMhI,UAClD,UAAWzF,KAAU2N,EAAU,CAC7B,GAAI3N,EAAOof,mBAAqB+a,EAAU,SAC1C,MAAM79B,EAAQsvB,GAAalwB,EAAKgB,OAAQsD,EAAQ8K,EAAWuE,EAAY9V,aACzD,IAAV+C,GACJ3C,KAAK8Q,KAAKwwB,UAAUY,SAAS,CAC3B77B,SACA1D,MAAO3C,KAAKmtB,KAAKgV,UAAU97B,EAAQ1D,EAAOZ,EAAKgB,OAAQ,KAAM,GAC7Dwc,UAAWxd,EAAKgB,OAChB6C,SAAU8P,EAAY9P,SACtB7D,QAEJ,CAEJ,GAeF,SAASq+B,GAAe7a,EAA4Bgb,GAClD,MAAM6B,EAAU,IAAIv9B,IAAI07B,GACxB,MAAO,CACLA,aACAhb,WACA8c,OAASh8B,QACqB,IAA5BA,EAAOof,kBAAkC2c,EAAQp9B,IAAIqB,EAAOof,kBAElE,CC5XO,SAAS6c,GACdxxB,EACAzK,EACAk8B,EACAhjB,EACA5B,GAEA,MAAMwkB,EAAYrxB,EAAK0xB,eACvB,QAAkB,IAAdL,EAAyB,OAAOI,EACpC,IACE,MAAME,EAAcN,EAClB97B,EAAO8K,UACPoxB,EACA,CAAEjiC,QAAS+F,EAAO/F,QAASif,aAC3B5B,GAEI+kB,EAAmBv9B,EAAsBs9B,GAC/C,IAAK9kB,IAAa,OAAO4kB,EACzB,GAAIG,EACF,MAAM,IAAIC,UACR,kBAAkBt8B,EAAO8K,kEAG7B,OAAOsxB,CACT,OAASG,GACP,IAAKjlB,IAAa,OAAO4kB,EACzB,MAAMx7B,EAAQ67B,aAAe3hB,MAAQ2hB,EAAM,IAAI3hB,MAAMzf,OAAOohC,IAE5D,OADK9xB,EAAK6E,QAAQktB,KAAK,QAAS,CAAE97B,QAAOuY,QAAS,YAAa9P,KAAM,WAC9D+yB,CACT,CACF,CCbA,IAAMO,kBAAA,IAA2Cj+B,IAEpCk+B,GAAN,MAGL,WAAApjC,CACmBmR,EACAC,EACjBixB,GAFiBhiC,KAAA8Q,OACA9Q,KAAA+Q,QAMjB/Q,KAAKoW,WACuB,oBAAnBlL,gBAAkCA,eCXxC,SACL4F,EACAC,GAEA,MAAO,CACLovB,cAAe,IAAY,KAG3BE,mBAAoB,OAKpBQ,iBAAkB,CAACnrB,EAAgC3B,KACjD,GAAI2B,EAAYjD,SAAU,OAAO,EACjC,MAAMwC,EAAUH,GACdhE,EAAKgD,MACL4B,EAAYX,QACZW,EAAY9V,OACZmU,GAEF,UAAW5C,KAAa8D,EAAS1D,EAAoBR,EAAOI,GAC5D,OAAO,GAET4vB,gBAAiB,KAAe,EAChCJ,aAAc,IAAqBt7B,QAAQC,UAG3Cs7B,aAAc,KACZ91B,EAAqB,mBACdzF,QAAQC,WAEjB06B,qBAAuB35B,IACrByE,EAAqB,6BACrBk1B,GAAqBlvB,EAAMC,EAAO1K,IAEpC45B,wBAA0B55B,IACxB45B,GAAwBnvB,EAAMC,EAAO1K,IAG3C,CD5BU28B,CAAyBlyB,EAAMC,GAC/B,IAAImvB,GAAepvB,EAAMC,EAAO,CAC9BkxB,QAAS,CAACvsB,EAAa3T,KACrB/B,KAAKijC,kBAAkBvtB,EAAa3T,IAEtCogC,UAAW,CAAC97B,EAAQ1D,EAAO4c,EAAW5B,IACpC2kB,GAAoBxxB,EAAMzK,EAAQ1D,EAAO4c,EAAW5B,GACtDqkB,eACAX,eAAgB,CAAC3rB,EAAa3T,KAC5B/B,KAAKqhC,eAAe3rB,EAAa3T,IAEnCy/B,cAAgB9rB,IACd1V,KAAKwhC,cAAc9rB,KAG/B,CAxBmB5E,KACAC,MAJFqF,WA8BjB,YAAA8sB,CACEvhC,EACAgF,EACAf,GAEA,MAAMkL,KAAEA,EAAAC,MAAMA,GAAU/Q,KAGxB,GAFA8Q,EAAKqyB,UAAU/U,OACfrd,EAAMV,SAAS2H,QpDoBZ,SAA6BrW,GAMlC,MAAMiD,EAA6B,GAUnC,OATIxC,MAAMC,QAAQV,EAAQwG,kBAAkBvD,EAAKlC,KAAK,eACxB,iBAAnBf,EAAQ/B,QAAqBgF,EAAKlC,KAAK,UACd,iBAAzBf,EAAQyH,cAA2BxE,EAAKlC,KAAK,iBAEL,iBAA1Cf,EAAQiX,+BAC2B,OAA1CjX,EAAQiX,+BAERhU,EAAKlC,KAAK,uBAELkC,CACT,CoDrC2Bw+B,CAAoBzhC,GAAUmP,EAAKO,UACrC,IAAjB1P,EAAQI,KAIV,iBAHgC,IAA5BJ,EAAQ4F,iBACVwJ,EAAMV,SAAS+H,aAAazW,EAAQ4F,gBAAiBuJ,EAAKO,MAI9D,QAAiB,IAAbzL,EAAwB,OAI5B,MAAMy9B,EAAmBtyB,EAAM0M,cAAc9E,KAAKhX,GACzB,OAArB0hC,GACGvyB,EAAK6E,QAAQktB,KAAK,qBAAsB,CAC3C5B,OAAQoC,EACRC,UAAWtsB,KAAKD,QAGU,iBAAnBpV,EAAQ/B,SAAqBmR,EAAMnR,OAAS+B,EAAQ/B,QAC3DwC,MAAMC,QAAQV,EAAQwG,mBACxB4I,EAAM1E,OAAS1K,EAAQwG,gBACvB4I,EAAM4F,YAAc3K,EAAiBrK,EAAQwG,kBAE/C,MAAMuN,EAAiC,CACrC9P,WACAjE,UACA/B,OAAQmR,EAAMnR,OACdyM,OAAQ0E,EAAM1E,OACdsK,YAAa5F,EAAM4F,YACnBmK,WAAY9J,KAAKD,MACjBN,YAAkC,OAArB4sB,GAA6B9qB,GAAgBxH,EAAMsK,cAChEtG,uBAAA,IAAalQ,IACb4N,UAAU,EACVG,2BAAA,IAAiB/N,IACjBiW,kBAAc,EACdD,iBAAkB,GAClB6lB,iBAAkB,EAClBJ,gBAAgB,EAChBiD,WAAW,EACX/qB,WAAW,GAIPlG,EAAWvB,EAAMsK,aAMvB,GALAtK,EAAM8M,kBACW,OAAbvL,GAAsBA,EAASkG,YAAAzH,EAAiBwK,iBAAmB,GACvExK,EAAMsK,aAAe3F,EACrB5E,EAAKwwB,UAAUkC,eAAe59B,GAC9BmL,EAAMuK,aAAe,OACW,IAA5B3Z,EAAQ4F,kBACVwJ,EAAMV,SAAS+H,aAAazW,EAAQ4F,gBAAiBuJ,EAAKO,KACrDN,EAAM4M,UAAUjI,IAFvB,CAIA,GAAI5E,EAAK2yB,WAAWlV,gBAAiB,CAGnC,GAFAzd,EAAK4yB,MAAMviC,oBACN2P,EAAK6E,QAAQktB,KAAK,UAAW,CAAEl8B,SAAQ28B,UAAWtsB,KAAKD,SACvDhG,EAAM4M,UAAUjI,GAAc,OAEnC,GADA5E,EAAKO,IAAI,aAAc,eAAgB,IAAK,cACvCN,EAAM4M,UAAUjI,GAAc,MACrC,CAIK1V,KAAK2jC,cAAcjuB,GAAanQ,MAAOwB,IAC1C+J,EAAKO,IAAI,iBAAkBtK,IAZ7B,CAcF,CAEA,mBAAc48B,CAAcjuB,GAC1B,MAAM5E,KAAEA,EAAAC,MAAMA,GAAU/Q,KAClB+C,QAAe/C,KAAK4jC,sBAAsBluB,GAChD,GAAe,OAAX3S,IAAoBgO,EAAM4M,UAAUjI,GAAc,OACtD,MAAM3T,EAAO/B,KAAK6jC,QAAQnuB,EAAa3S,GACnC+N,EAAK6E,QAAQE,cAAc,gBAAkB,WACvB/E,EAAK6E,QAAQgL,UACnC,eACA,CACE5e,OACA6D,SAAU8P,EAAY9P,SAASA,SAC/Bkb,WAAYpL,EAAYoL,WACxBjX,OAAQ,QACRi6B,OAAQ,KACNpuB,EAAY6tB,WAAY,EACxBzyB,EAAKwwB,UAAUyC,eAAeruB,EAAY9P,YAG9C,KAAO8P,EAAY6tB,WAAaxyB,EAAM4M,UAAUjI,KAEhCA,EAAY6tB,YAAcxyB,EAAM4M,UAAUjI,KAE9D1V,KAAKgkC,YAAYtuB,EAAa3T,GAAM,EACtC,CAEQ,OAAA8hC,CACNnuB,EACA3S,GAEA,MAAMpB,QAAEA,GAAY+T,EACpB,MAAO,CACL3S,iBAC2B,IAAvB2S,EAAYrJ,OAAuB,CAAEA,OAAQqJ,EAAYrJ,QAAW,MACtC,iBAAvB1K,EAAQsX,WAA0B,CAAEA,WAAYtX,EAAQsX,YAAe,MAC5C,iBAA3BtX,EAAQuX,eACf,CAAEA,eAAgBvX,EAAQuX,gBAC1B,WACuB,IAAvBxD,EAAY9V,OAAuB,CAAEA,OAAQ8V,EAAY9V,QAAW,GAE5E,CAQQ,WAAAokC,CACNtuB,EACA3T,EACAkiC,GAEA,MAAMnzB,KAAEA,EAAAC,MAAMA,GAAU/Q,KAClBwS,EAAe0O,GAAoBpQ,EAAK0B,aAAc1B,EAAKgD,MAAMmQ,iBACjE1G,EAAUxM,EAAMwM,QAAQhL,KAAKxQ,EAAKgB,OAAQyP,GAChD,GAAI+K,EAAQ9K,WAAawxB,GAA6B,QAAlBnzB,EAAKozB,SAGvC,GAA8B,oBAAnBh5B,gBAAkCA,eAC3CJ,EAAqB,oBAChB,CACL,MAAMq5B,EAAQnkC,KAAKokC,mBAAmB1uB,EAAa3T,EAAKgB,ShBqJzD,SACL+N,EACAC,EACAhO,EACAnD,EACAmU,GAEA,MAAMkH,EAAUmJ,YAAYrN,MACtB1L,EAAO+lB,GAAWtgB,EAAKzF,MACvByK,EAASoZ,GAAensB,EAAQnD,GAChC2xB,EACK,OAATlmB,EAAgB,GAAKgmB,GAAMvgB,EAAMkgB,GAAa3lB,EAAMyK,GAAS/B,EAAW,wBAC1EhD,EAAMsL,gBA0ER,SACEvG,EACAyb,GAEA,MAAMxuB,iBAAA,IAAa8B,IACnB,UAAWsM,UAAEA,EAAAuf,OAAWA,KAAYa,EAAS,CAC3CxuB,EAAOkC,IAAIkM,GACX,UAAWtO,IAAQ,CAACyf,GAAgBE,IAAgB,CAClD,MAAM6hB,EAAS3T,EAAO7tB,QACP,IAAXwhC,GAAsBthC,EAAOkC,IAAIo/B,EACvC,CACF,CACA,MAAMrO,iBAAA,IAAW7pB,IACjB,UAAYmC,EAAM6gB,KAAUrZ,EACZ,OAAVqZ,GAAkBpsB,EAAOiC,IAAImqB,EAAMnnB,QAAQguB,EAAKv1B,IAAI6N,EAAM6gB,GAEhE,MAAO,CAAEpsB,SAAQ+S,OAAQkgB,EAC3B,CA3F0BsO,CAAKxuB,EAAQyb,GACrCxgB,EAAMqL,iBAAmBgI,YAAYrN,MAAQkE,EACtCsW,EAAQ5yB,MACjB,CgBnKQ4lC,CAAoBzzB,EAAMC,EAAOhP,EAAKgB,OAAQ2S,EAAY9V,OAAQukC,EACpE,CAEFzuB,EAAYjD,SAAW8K,EAAQ9K,SAC/BiD,EAAY9C,YAAcqxB,EAAUnB,GAAkBvlB,EAAQ3K,YAC9D8C,EAAYX,QAAUkvB,EAClBnB,kBACA,IAAIj+B,IAAI,IAAI0Y,EAAQ7K,WAAY6K,EAAQ3K,cAC5C5S,KAAKijC,kBAAkBvtB,EAAa3T,EACtC,CAGA,2BAAc6hC,CACZluB,GAEA,MAAM5E,KAAEA,EAAAC,MAAMA,GAAU/Q,KAClBmC,EAAMuT,EAAY/T,QAAQI,MAAQ,GACxC,GAAoB,OAAhB+O,EAAK+F,OAAiB,OAAO1U,EAEjC,GAA8E,UAA1E8lB,sBAAsBlX,EAAMV,SAAStM,UAAU8jB,uBACjD,OAAO1lB,EAET,MAAM06B,EAAO9rB,EAAMyM,OAAO/H,OAAO3E,EAAM4E,GACvC,IAAKmnB,EAAKrmB,MAAO,OAAOqmB,EAAK95B,OAC7B,MAAMpB,QAAEA,GAAY+T,EACd8uB,EAAYzzB,EAAMyM,OAAO5G,QAAQ9F,EAAK+F,OAAQ/F,EAAK2zB,cAAe,CACtEvrB,eAAgBvX,EAAQuX,eACxBD,WAAYtX,EAAQsX,WACpBlX,KAAMI,EACNvC,OAAQ8V,EAAY9V,SAItB,IAAK4kC,EAAUttB,QAIb,OAHKlX,KAAK0kC,YAAYhvB,EAAa8uB,EAAUrhC,QAAQoC,MAAOwB,IAC1D+J,EAAKO,IAAI,iBAAkBtK,KAEtB81B,EAAK95B,OAEd,MAAMI,QAAeqhC,EAAUrhC,OAC/B,OAAK4N,EAAM4M,UAAUjI,GACC,WAAlBvS,EAAOuU,QACT3G,EAAMyM,OAAOjG,aAAapU,EAAOqU,KAC1BrU,EAAOqU,KAEM,eAAlBrU,EAAOuU,OAAgC,KACpCmlB,EAAK95B,OAN8B,IAO5C,CAGA,iBAAc2hC,CACZhvB,EACA1M,GAEA,MAAM+H,MAAEA,GAAU/Q,KACZmD,QAAe6F,EACC,WAAlB7F,EAAOuU,QAAwB3G,EAAM4M,UAAUjI,KACnD3E,EAAMyM,OAAOjG,aAAapU,EAAOqU,KACjCxX,KAAKgkC,YAAYtuB,EAAa1V,KAAK6jC,QAAQnuB,EAAavS,EAAOqU,MAAM,GACvE,CAEA,iBAAAyrB,CAAkBvtB,EAAgC3T,GAChD,MAAM+O,KAAEA,EAAAC,MAAMA,GAAU/Q,KACxB,IAAK+Q,EAAM4M,UAAUjI,GAAc,OACnC,MAAMiI,EAAY,IAAe5M,EAAM4M,UAAUjI,GAC3C3B,EAAY/T,KAAKokC,mBAAmB1uB,EAAa3T,EAAKgB,SACtDgS,QAAEA,GAAYW,EAEdmR,EAAQ/V,EAAKsF,WAAWyQ,MACxB5R,EAAUjV,KAAKoW,WAAWyqB,iBAAiBnrB,EAAa3B,GAKxD4wB,EAAO5zB,EAAMqM,iBACnB,QACY,IAAVyJ,IACCnR,EAAY4qB,iBACZrrB,GACC0vB,GACA9d,EAAMgW,KAAK/rB,EAAKzF,KAAM0J,IACtB/U,KAAKoW,WAAW2qB,gBAAgBhsB,IAIlC,OAFAhE,EAAMqM,kBAAmB,OACpBpd,KAAKoW,WAAWwqB,aAAalrB,EAAa3T,EAAM8kB,GAGvD,MAAMgW,EAAO78B,KAAKoW,WAAW+pB,cAAcprB,GAErC6vB,EAAgB9zB,EAAK+zB,cAC3B,IAAIC,EAAY,EAChB,UAAY3zB,EAAW6C,KAAalD,EAAKgD,MAAMhI,UAAW,CACxD,IAAK6R,IAAa,OAClB,UAAWtX,KAAU2N,EAAU,CAC7B,IAAkB,IAAdD,IAAwBP,GAAiBnN,EAAOoN,MAAOM,GAAY,SAIvE,IAA6B,IAAzB8oB,GAAMwF,OAAOh8B,GAAkB,CAEjC,GAAIyK,EAAKi0B,kBAAmB,CAC1B,MAAM5iC,EAAM8vB,GAAalwB,EAAKgB,OAAQsD,EAAQ8K,EAAWuE,EAAY9V,QACrEmR,EAAMyL,aAAa7B,KAAKjF,EAAarP,EAAQlE,EAC/C,CACA,QACF,CACA,MAAMsL,EAAOpH,EAAOqf,cAAgBvS,GAAgB9M,EAAO/F,UAAY,UACvE,GAAa,YAATmN,EAAoB,CACtBzN,KAAKoW,WAAW6pB,wBAAwB55B,GACxC,QACF,CACa,aAAToH,GAAgC,OAATovB,GAAe78B,KAAKoW,WAAW4pB,qBAAqB35B,GAC/E,MAAM1D,EAAQsvB,GAAalwB,EAAKgB,OAAQsD,EAAQ8K,EAAWuE,EAAY9V,QACvE,QAAc,IAAV+C,EAAqB,CACvBoO,EAAM4K,aAAa1W,IAAIkM,GACvB,QACF,CAKA,GADIL,EAAKi0B,mBAAmBh0B,EAAMyL,aAAa7B,KAAKjF,EAAarP,EAAQ1D,IACpEgb,IAAa,OAClB,MAAM8kB,EAAcH,GAAoBxxB,EAAMzK,EAAQ1D,EAAOZ,EAAKgB,OAAQ4a,GAC1E,IAAKA,IAAa,OAIlB,MAAMhL,EAAWiyB,EACbzS,GAAgB9rB,EAAQo8B,EAAa1gC,EAAKgB,OAAQ2S,EAAY9V,aAC9D,EACEolC,EAAOj0B,EAAMwL,oBAAoBlc,IAAIgG,EAAO/F,SAClD,IACGoV,EAAYe,aACb3F,EAAK+zB,oBACQ,IAAblyB,GACAqyB,IAASryB,IACR+C,EAAY9C,YAAY5N,IAAImM,GAC7B,CACAJ,EAAM0K,uBAAyB,EAC/B,QACF,CACA,MAAM6C,EAA0B,CAC9BjY,SACA1D,MAAO8/B,EACPljB,UAAWxd,EAAKgB,OAChB6C,SAAU8P,EAAY9P,SACtB7D,OACAqQ,cAAeO,GAEjB7B,EAAKwwB,UAAUY,SAAS5jB,GACxBwmB,GAAa,CACf,CACF,EdtUG,SACLxlB,EACAvc,EACAnD,EACAmU,GAEA,MAAMD,MAAEA,GAAUwL,EAClB,GAAyB,IAArBxL,EAAM2Q,WAAkB,OAE5B,IAAkB,IAAd1Q,IpBiDC,SAAwBD,EAAqBC,GAClD,UAAWG,KAAWJ,EAAMgC,SAC1B,GAAItC,GAAiBU,EAAQT,MAAOM,GAAY,OAAO,EAEzD,OAAO,CACT,CoBtD8BkxB,CAAenxB,EAAOC,GAAY,OAC9D,MAAMiB,EAAgBP,GAA0BX,EAAOlU,EAAQmU,GAC/D,UAAYsb,EAAS1sB,KAAUc,OAAOqI,QAAQ/I,GAAS,CACrD,GAAI6Q,GAAmB5O,IAAIqqB,GAAU,SAGrC,GAAIqD,GAAiB/vB,GAAQ,CAC3B6vB,GAAOlT,EAAStK,EAAeqa,EAASzvB,GACxC,QACF,CACA,IAAK2D,GAAcZ,IAAUqS,EAAcqa,GAAU,SAUrD,MAAMrgB,EAAQsF,GAAkB+a,EAASzvB,GACzC,UAAYslC,EAAW3V,KAAe9rB,OAAOqI,QAAQnJ,GAC9C+vB,GAAiBnD,KAAe3b,GAAmB5O,IAAIkgC,IAC5D1S,GAAOlT,EAAStK,EAAe,GAAGhG,KAASk2B,IAAatlC,EAE5D,CACF,EcoSIulC,CACE,CAAErxB,MAAOhD,EAAKgD,MAAO2e,OAAQ1hB,EAAM6K,mBAAoBnR,KAAMqG,EAAKrG,MAClE1I,EAAKgB,OACL2S,EAAY9V,OACZmU,GAEW,OAAT8oB,GAAiBA,EAAK0D,WAAW5hC,OAAS,IAC5C+W,EAAYgrB,iBAAmB7D,EAAK0D,WAAW5hC,OAC1CqB,KAAKoW,WAAWuqB,aAAajrB,EAAa3T,EAAM86B,IAMrC,IAAdiI,GAAoD,IAAjCpvB,EAAYgrB,mBACjC3vB,EAAM6M,SAASlI,GACf1V,KAAKwhC,cAAc9rB,GACnB1V,KAAKolC,cAAc1vB,EAAa3T,GAEpC,CAGQ,aAAAqjC,CAAc1vB,EAAgC3T,GACnB,IAA7B2T,EAAYX,QAAQ2P,MzBnUrB,SACL9O,EACAqrB,GAEA,UAAWpf,KAAUjM,EACnBiM,EAAOwjB,cACL,IAAIC,YAAgC7jB,GAAc,CAAEwf,SAAQsE,SAAS,KAGlE3vB,EAAQjX,MACjB,CyB0TI6mC,CAAqBxlC,KAAK8Q,KAAKgD,MAAM8B,QAAS,CAC5C7S,OAAQhB,EAAKgB,OACb6C,SAAU8P,EAAY9P,SAASA,SAC/Bkb,WAAYpL,EAAYoL,WACxBlhB,OAAQ8V,EAAY9V,QAExB,CAOQ,cAAAyhC,CAAe3rB,EAAgC3T,GACrD,MAAM+O,KAAEA,EAAAC,MAAMA,GAAU/Q,KACxB,GAAsB,QAAlB8Q,EAAKozB,UAAgD,OAA1BnzB,EAAMsL,kBAKL,oBAAnBnR,iBAAkCA,gBAAiB,CAC9D,MAAMi5B,EAAQnkC,KAAKokC,mBAAmB1uB,EAAa3T,EAAKgB,ShBtBvD,SACL+N,EACAC,EACAhO,EACAnD,EACAmU,GAEA,MAAMiiB,EAAOjlB,EAAMsL,gBACbhR,EAAO+lB,GAAWtgB,EAAKzF,MAC7B,GAAa,OAAT2qB,GAAsC,IAArBA,EAAKjzB,OAAO2hB,MAAuB,OAATrZ,EAAe,OAAO,EACrE,MAAMyK,EAAS,IAAI3J,IAA0B6pB,EAAKlgB,QAClD,UAAYxH,EAAM6gB,KAAUD,GAAensB,EAAQnD,GAAS,CAC1D,GAAc,OAAVuvB,IAAmB6G,EAAKjzB,OAAOiC,IAAImqB,EAAMnnB,OAAQ,SACrD,MAAMy9B,EAAQ3vB,EAAOzV,IAAIiO,QACX,IAAVm3B,EAAqB3vB,EAAOrV,IAAI6N,EAAM6gB,GACjCsW,GAAOz9B,QAAUmnB,EAAMnnB,OAAO8N,EAAOrV,IAAI6N,EAAM,KAC1D,CACO+iB,GAAMvgB,EAAMkgB,GAAa3lB,EAAMyK,GAAS/B,EAAW,yBAAyBpV,MACrF,CgBKM+mC,CAAsB50B,EAAMC,EAAOhP,EAAKgB,OAAQ2S,EAAY9V,OAAQukC,EACtE,CACF,CAGQ,kBAAAC,CACN1uB,EACA3S,GAEA,MAAM+N,KAAEA,EAAAC,MAAMA,GAAU/Q,KACxB,IAAK8Q,EAAK60B,qBAAsB,OAAO,EACvC,MAAMhkC,QAAEA,GAAY+T,EACdzR,EnCpXH,SAA0B0O,GAC/B,GAAIY,GAASZ,EAASsG,YAAU,MAAU,EAtBbhW,EAsB6B0P,EAASsG,WArB5D,UAAUhW,MADZ,IAAwBA,EAuB7B,IAAKsQ,GAASZ,EAASuG,gBAAiB,OAAO,KAC/C,MAAM0sB,EAAgBvyB,GAAmBV,EAASuG,gBAClD,OAAO3F,GAASZ,EAASW,YACrB,CAACsyB,EAAevyB,GAAmBV,EAASuG,eAAgBvG,EAASW,aACrE,CAACsyB,EACP,CmC6WiBC,CAAiB,CAC5B5sB,WAA0C,iBAAvBtX,EAAQsX,WAA0BtX,EAAQsX,gBAAa,EAC1EC,eACoC,iBAA3BvX,EAAQuX,eAA8BvX,EAAQuX,oBAAiB,EACxE5F,WAAYK,GAAe5Q,KAQ7B,OANa,OAATkB,GAAkB8M,EAAM+K,8BAC1B/K,EAAM+K,6BAA8B,EACpChL,EAAKrG,KACH,2FAGGxG,CACT,CAGA,OAAA6hC,CAAQjE,GACN,MAAM/wB,KAAEA,EAAAC,MAAMA,GAAU/Q,KACxB+Q,EAAM2K,UAAYmmB,EACdA,EAAMkE,SAAW,IAAMh1B,EAAMgL,uBAC/BhL,EAAMgL,sBAAuB,EAC7BjL,EAAKrG,KACH,+CAA+CjJ,OAAOqgC,EAAMkE,yFAGhE,MAAMngC,SAAEA,EAAA7D,KAAUA,GAAS8/B,EAC3B,QAAiB,IAAbj8B,EAAwB,OAC5B,MAAM8P,EAAc3E,EAAMsK,aAC1B,GACkB,OAAhB3F,IACC3E,EAAM4M,UAAUjI,KAChBlQ,EAAakQ,EAAY9P,SAAUA,GAEpC,OAEmC,IAAjC8P,EAAYgrB,kBAAwB3vB,EAAM6M,SAASlI,GACvD,MAAMiI,EAAY,IAChB5M,EAAM4M,UAAUjI,IAAgBlQ,EAAakQ,EAAY9P,SAAUA,GAIrE,GADA5F,KAAKwhC,cAAc9rB,IACdiI,IAAa,OAGlB,MAAMqoB,EAAaj1B,EAAMO,kBACrB00B,EAAWrnC,OAAS,IACtBoS,EAAMO,kBAAoB,QACb,IAATvP,GAAoB/B,KAAKoW,WAAWiqB,mBAAmB3qB,EAAa3T,EAAMikC,IACzEroB,WAEM,IAAT5b,IACA8/B,EAAM9gB,QAAU,GAAAjQ,EAAQ4yB,MAAMpiC,eAAeugC,EAAM9gB,SAClDpD,MAGL3d,KAAKolC,cAAc1vB,EAAa3T,GAC3B4b,KAAiC,IAAlBkkB,EAAM9gB,SAA+D,IAA9CjQ,EAAK6E,QAAQE,cAAc,gBAGjE/E,EAAK6E,QAAQgL,UAChB,cACA,CACE5e,OACA0/B,aAAcI,EAAM9gB,QACpB4D,WAAYkd,EAAMld,WAClB/e,SAAUA,EAASA,SACnBkb,WAAYpL,EAAYoL,WACxBjX,OAAQ,SAEV8T,IAEJ,CAOA,aAAA6jB,CAAc9rB,GACZ,MAAMrP,EAASrG,KAAK+Q,MAAMyL,aAAazB,OAAOrF,GAC9C,QAAe,IAAXrP,EACJ,IACErG,KAAKimC,cAAc5/B,EACrB,OAASU,GACP/G,KAAK8Q,KAAKO,IAAI,SAAUtK,EAC1B,CACF,CAOA,WAAAm/B,CAAY/0B,GACV,MAAM9K,EAASrG,KAAK8Q,KAAKgD,MAAMzT,IAAI8Q,KAAa,GAChD,YAAe,IAAX9K,EAA6B,aAC1BrG,KAAKimC,cAAc5/B,EAC5B,CAEQ,aAAA4/B,CACN5/B,GAEA,MAAM/F,QAAEA,GAAY+F,EACdiT,EAAMhZ,EAAQO,cAAcslC,YAClC,GAAY,OAAR7sB,EAAc,MAAO,aAGzB,MAAMzN,EAAM,GAAGxF,EAAOoN,OAAS,MAAMpN,EAAO8K,YAC5C,OAAOnR,KAAK+Q,MAAMuM,SAAS3D,OAAO9N,EAAKvL,EAASgZ,EAClD,GEncW8sB,GAAN,MACY/nB,MACA+J,WACAie,UACAvc,UACAwc,mBACAC,aACAC,aACAV,QACAW,cACAC,YACT19B,uBAAA,IAAcmD,IACLw6B,sBAAA,IAAax6B,IACby6B,6BAAA,IAAoB/hC,IAC7B4jB,cAAsD,KACtDoe,cAAgB,EAChBC,cAAsD,KACtDC,YAA6B,KAC7BC,WAAa,EAEbC,YAAc,EACdC,eAAyC,KACzCC,yBAA0B,EAElC,WAAAxnC,CAAY0e,EAAoBpT,GAC9BjL,KAAKqe,MAAQA,EACbre,KAAKooB,WAAand,EAAQmd,YAvCK,GAwC/BpoB,KAAKqmC,UAAYp7B,EAAQo7B,WAA+B,EAAlBrmC,KAAKooB,WAC3CpoB,KAAK8pB,UAAY7e,EAAQ6e,UACzB9pB,KAAKsmC,mBAAqBr7B,EAAQm8B,yBAxCM,GAyCxCpnC,KAAKumC,aAAet7B,EAAQo8B,wBAAyB,EACrDrnC,KAAKwmC,aAAev7B,EAAQu7B,aAC5BxmC,KAAK8lC,QAAU76B,EAAQ66B,QACvB9lC,KAAKymC,cACHx7B,EAAQw7B,gBAC0B,mBAA1Ba,sBACJA,sBAAsBC,KAAKpU,YAC1BhhB,GACClQ,WAAW,KACTkQ,EAASiS,YAAYrN,QACpB,IACX/W,KAAK0mC,YACHz7B,EAAQy7B,cACyB,mBAAzBc,qBACJA,qBAAqBD,KAAKpU,YACzBjF,IACC5uB,aAAa4uB,IAEvB,CAGA,QAAAgU,CAAS5jB,GACP,QAAwB,IAApBA,EAAO1Y,SAAwB,CACjC,GAAI5F,KAAKmnC,wBAAyB,OAClC,GAA4B,OAAxBnnC,KAAKknC,iBAA4B1hC,EAAa8Y,EAAO1Y,SAAU5F,KAAKknC,gBACtE,MAEJ,CACA,MAAM9T,EAAWpzB,KAAKgJ,QAAQ3I,IAAIie,EAAOjY,OAAO/F,SAC5C8yB,GACFA,EAASzwB,MAAQ2b,EAAO3b,MACxBywB,EAAS7T,UAAYjB,EAAOiB,UAC5B6T,EAASxtB,SAAW0Y,EAAO1Y,SAC3BwtB,EAASrxB,KAAOuc,EAAOvc,KACvBqxB,EAAShhB,cAAgBkM,EAAOlM,eAEhCpS,KAAKgJ,QAAQvI,IAAI6d,EAAOjY,OAAO/F,QAAS,CACtC+F,OAAQiY,EAAOjY,OACf1D,MAAO2b,EAAO3b,MACd4c,UAAWjB,EAAOiB,UAClB3Z,SAAU0Y,EAAO1Y,SACjB7D,KAAMuc,EAAOvc,KACbqQ,cAAekM,EAAOlM,gBAG1BpS,KAAKynC,aACP,CAMA,cAAAjE,CAAe59B,GA0PjB,IAAyBH,EAAoBC,EAzPb,OAAxB1F,KAAKknC,gBAA2B1hC,EAAaI,EAAU5F,KAAKknC,iBACpC,OAAxBlnC,KAAKknC,iBAwPYzhC,EAxP+BG,EAwPXF,EAxPqB1F,KAAKknC,gBAyPjEzhC,EAAEE,aAAeD,EAAEC,WAAmBF,EAAEE,WAAaD,EAAEC,WACpDF,EAAEG,SAAWF,EAAEE,UA1PiE,KACrF5F,KAAK0nC,sBACL1nC,KAAK2nC,YACL3nC,KAAKknC,eAAiBthC,EACtB5F,KAAKmnC,yBAA0B,EACjC,CAGA,cAAApD,CAAen+B,GACe,OAAxB5F,KAAKknC,gBAA4B1hC,EAAaI,EAAU5F,KAAKknC,kBACjElnC,KAAK0nC,sBACL1nC,KAAK2nC,YACL3nC,KAAKmnC,yBAA0B,EACjC,CAGA,QAAAS,GAEE,OADA5nC,KAAK0nC,sBACE1nC,KAAKsX,OACd,CAGA,aAAAuwB,CAAcvnC,GACZ,MAAMiC,EAAQvC,KAAK2mC,OAAOtmC,IAAIC,GAC9B,IAAKiC,EAAO,OAEZ,GADAvC,KAAK2mC,OAAOjlC,OAAOpB,IACdN,KAAK2d,UAAUpb,GAAQ,OAC5B,MAAM4hB,EAAKC,YAAYrN,MACjBgK,EAAU/gB,KAAK8nC,SAASvlC,GAAS,EAAI,EAC3CvC,KAAK8lC,UACH9lC,KAAK+nC,SACHxlC,EACAwe,EACA,EACAqD,YAAYrN,MAAQoN,EACR,IAAZpD,EAAgB,CAACxe,EAAM8D,OAAO8K,WAAa,IAGjD,CAMA,QAAA62B,CAAS3hC,GACPrG,KAAKioC,eAAejoC,KAAKgJ,QAAS3C,GAClCrG,KAAKioC,eAAejoC,KAAK2mC,OAAQtgC,GACjC,UAAWiR,KAAStX,KAAK4mC,cAAe5mC,KAAKioC,eAAe3wB,EAAOjR,EACrE,CAEA,MAAAylB,CAAOxrB,GACLN,KAAKgJ,QAAQtH,OAAOpB,GACpBN,KAAK2mC,OAAOjlC,OAAOpB,GACnB,UAAWgX,KAAStX,KAAK4mC,cAAetvB,EAAM5V,OAAOpB,EACvD,CAGA,OAAAmX,GACEzX,KAAK0nC,sBACL1nC,KAAK2nC,YACL3nC,KAAKknC,eAAiB,KACtBlnC,KAAKmnC,yBAA0B,EAE/BnnC,KAAKinC,YAAc,CACrB,CAEA,gBAAI1F,GACF,OAAOvhC,KAAKgJ,QAAQ0b,IACtB,CAEA,eAAIwjB,GACF,OAAOloC,KAAK2mC,OAAOjiB,IACrB,CAEA,iBAAIyjB,GACF,OAAOnoC,KAAKsmC,kBACd,CAEA,cAAI8B,GACF,OAAQpoC,KAAKumC,cAAgBvmC,KAAKwmC,eAAiBxmC,KAAKsmC,kBAC1D,CAEQ,WAAAmB,GACN,MAAM1wB,EAAMC,KAAKD,MACXsxB,EAAiBtxB,GAAO/W,KAAKinC,YAMnC,GALAjnC,KAAKinC,YAAclwB,EAAM/W,KAAKooB,WAK1BigB,EAEF,YADAroC,KAAKsoC,eAGP,MAAMC,EAASvoC,KAAK6mC,eAAiB,EAC/BxnC,EAAQW,KAAKyoB,cAInB,GAHAzoB,KAAKyoB,cAAgB,KACP,OAAVppB,GAAgBC,aAAaD,GAE7BW,KAAK6mC,gBAAkB0B,EAAO,OAClC,MAAMr/B,EAAOjH,WAAW,KAClBjC,KAAK6mC,gBAAkB0B,IAC3BvoC,KAAKyoB,cAAgB,KAGjBzoB,KAAKgJ,QAAQ0b,KAAO,GAAA1kB,KAAQsoC,iBAC/BtoC,KAAKooB,YACJpoB,KAAK6mC,gBAAkB0B,IAAOvoC,KAAKyoB,cAAgBvf,GAE5B,OAAvBlJ,KAAK8mC,eAA0B9mC,KAAKqmC,UAAYrmC,KAAKooB,aACvDpoB,KAAK8mC,cAAgB7kC,WAAW,KAC9BjC,KAAK8mC,cAAgB,KACjB9mC,KAAKgJ,QAAQ0b,KAAO,GAAA1kB,KAAQsoC,gBAC/BtoC,KAAKqmC,WAEZ,CAEQ,YAAAiC,GACN,MAAMC,EAASvoC,KAAKgnC,YAAc,EAC5B9Y,EAASluB,KAAK+mC,YAGpB,GAFA/mC,KAAK+mC,YAAc,KACJ,OAAX7Y,GAAiBluB,KAAK0mC,YAAYxY,GAClCluB,KAAKgnC,aAAeuB,EAAO,OAC/B,IAAI/vB,GAAY,EAChB,MAAMtP,EAAOlJ,KAAKymC,cAAc,KAC1BzmC,KAAKgnC,aAAeuB,IACxB/vB,GAAY,EACZxY,KAAK+mC,YAAc,KACnB/mC,KAAKsX,WAIFkB,GAAaxY,KAAKgnC,aAAeuB,IAAAvoC,KAAY+mC,YAAc79B,EAClE,CAEQ,KAAAoO,GACN,MAAM6M,EAAKC,YAAYrN,MACvB/W,KAAKwoC,gBACL,MAAMJ,EAAapoC,KAAKooC,WAClBp/B,EAAUhJ,KAAKgJ,QACrBhJ,KAAKgJ,uBAAA,IAAcmD,IACnB,IAAI4U,EAAU,EACd,MAAM0nB,EAA0B,GAChC,IACIC,EADA3C,EAAW,EAEf/lC,KAAK4mC,cAAc3hC,IAAI+D,GACvB,IACE,UAAWzG,KAASyG,EAAQ8M,SAAU,CACpC,IAAK9V,KAAK2d,UAAUpb,GAAQ,SAC5B,MAAM+lB,GAAW8f,GAAcpoC,KAAK8pB,UAAUvnB,EAAM8D,OAAO/F,SAEtDN,KAAK2d,UAAUpb,KACpBmmC,IAAenmC,EACV+lB,GAKLtoB,KAAK2mC,OAAOjlC,OAAOa,EAAM8D,OAAO/F,SAC5BN,KAAK8nC,SAASvlC,KAChBwe,GAAW,EACX0nB,EAAc/lC,KAAKH,EAAM8D,OAAO8K,cAPhCnR,KAAK2mC,OAAOlmC,IAAI8B,EAAM8D,OAAO/F,QAASiC,GACtCwjC,GAAY,GAQhB,CACF,SACE/lC,KAAK4mC,cAAcllC,OAAOsH,EAC5B,CACA,MAAM64B,EAAQ7hC,KAAK+nC,SACjBW,EACA3nB,EACAglB,EACA3hB,YAAYrN,MAAQoN,EACpBskB,GAGF,OADAzoC,KAAK8lC,UAAUjE,GACRA,CACT,CAEQ,SAAAlkB,CAAUpb,GAChB,YACqB,IAAnBA,EAAMqD,WACJ5F,KAAKmnC,yBACmB,OAAxBnnC,KAAKknC,gBACL1hC,EAAajD,EAAMqD,SAAU5F,KAAKknC,eAExC,CAEQ,QAAAY,CAASvlC,GAIf,OAAmB,IADMvC,KAAKqe,MAAM9b,KzCpUL4P,EyCqUiBnS,KAAKqe,OzCpUhDrM,EAAiBhN,IAAImN,IADvB,IAA4BA,CyCsUjC,CAEQ,cAAA81B,CAAeU,EAAmCtiC,GACxD,MAAM9D,EAAQomC,EAAOtoC,IAAIgG,EAAO/F,cAClB,IAAViC,IACAA,EAAM8D,OAAO8K,YAAc9K,EAAO8K,WAAa5O,EAAM8D,OAAOzG,SAAWyG,EAAOzG,OAIlF2C,EAAM8D,OAASA,EAHbsiC,EAAOjnC,OAAO2E,EAAO/F,SAIzB,CAEQ,SAAAqnC,GACN3nC,KAAKgJ,QAAQqb,QACbrkB,KAAK2mC,OAAOtiB,QACZ,UAAW/M,KAAStX,KAAK4mC,cAAetvB,EAAM+M,OAChD,CAEQ,QAAA0jB,CACNxlC,EACAwe,EACAglB,EACAphB,EACA8jB,GAEA,MAAO,CACL1nB,UACA0nB,gBACA1C,WACAphB,qBACwB,IAApBpiB,GAAOqD,SAAyB,CAAEA,SAAUrD,EAAMqD,UAAa,WAC/C,IAAhBrD,GAAOR,KAAqB,CAAEA,KAAMQ,EAAMR,MAAS,GAE3D,CAEQ,aAAAymC,GACqB,OAAvBxoC,KAAK8mC,gBACTxnC,aAAaU,KAAK8mC,eAClB9mC,KAAK8mC,cAAgB,KACvB,CAEQ,mBAAAY,GACN,MAAMjf,EAAgBzoB,KAAKyoB,cACrBse,EAAc/mC,KAAK+mC,YAGzB/mC,KAAK6mC,eAAiB,EACtB7mC,KAAKgnC,YAAc,EACnBhnC,KAAKyoB,cAAgB,KACrBzoB,KAAK+mC,YAAc,KACnB/mC,KAAKwoC,gBACiB,OAAlB/f,GAAwBnpB,aAAampB,GACrB,OAAhBse,GAAsB/mC,KAAK0mC,YAAYK,EAC7C,GC7WI6B,GAAwB,CAAC,EAAG,IAAK,IAAM,KAEhCC,GAAN,MACY/3B,KACAC,MAAQ,IAAIiK,GACZ8tB,SACAC,OAETC,aAAwC,KACxCC,aAA4B,KAEpC,WAAAtpC,CAAYsL,GACV,MAAM0K,QAAEA,EAAAwV,UAASA,GAAclgB,EACzBoG,OAAsB,IAAhBpG,EAAQoG,IAAoBhH,EAAiBF,EAAkBc,EAAQoG,KAC7E5G,OAAwB,IAAjBQ,EAAQR,KAAqBD,EAAkBL,EAAkBc,EAAQR,MAChFY,EAAOJ,EAAQI,OAA6B,oBAAb9M,SAA2BA,cAAW,GAG3E,QAAa,IAAT8M,EAAoB,MAAM,IAAI4V,MAAM,sDAExC,MAAMnN,EAAQ,IAAI8P,GAAa,CAAE1L,OAAS5X,IAAa2hB,eAAe3hB,KAChEkxB,EAAY,IAAItJ,GACpB,CACEoC,mBAAoB,KAClBtqB,KAAKgiC,gBAEPxX,mBAAoB,CAAClqB,EAASgoB,KACxBA,GAASgZ,EAAUuG,cAAcvnC,UAGN,IAAnC2K,EAAQ0d,uBACJ,CAAEA,uBAAwB1d,EAAQ0d,wBAClC,IAEA2Y,EAAY,IAAI8E,GACpBl0B,EAAqBoM,GAAWte,KAAK+oC,OAAO1qB,MAAMC,IAClD,SAC6B,IAAvBrT,EAAQmd,WAA2B,CAAEA,WAAYnd,EAAQmd,YAAe,WACtC,IAAlCnd,EAAQo8B,sBACR,CAAEA,sBAAuBp8B,EAAQo8B,uBACjC,WACoC,IAApCp8B,EAAQm8B,wBACR,CAAEA,wBAAyBn8B,EAAQm8B,yBACnC,GACJtd,UAAYxpB,GAAYkxB,EAAU1H,UAAUxpB,GAC5CkmC,aAAc,IAAM1yB,EAAMwQ,aAC1BwhB,QAAUjE,IACR7hC,KAAK8oC,SAAShD,QAAQjE,MAItBqH,EAAM,IAAIrjC,EAAWoF,EAAQk+B,cAAe,CAChD1/B,SAAU,CAAC9H,EAASgF,EAAQf,KAC1B5F,KAAK8oC,SAAS5F,aAAavhC,EAASgF,EAAQf,IAE9C2C,gBAAiB,KACfvI,KAAK+Q,MAAMV,SAAS2H,QAAQ,CAAC,mBAAoB3G,GAC5CsE,EAAQktB,KAAK,eAAgB,CAAES,UAAWtsB,KAAKD,SAEtDtO,aAAeT,IACThI,KAAK8Q,KAAKi0B,mBAAmB/kC,KAAK8oC,SAAS5C,YAAYl+B,IAE7D2B,UAAW,CAACD,EAAQ/C,KAClB,GAAe,UAAX+C,EAAoB,CACtB,MAAM3C,EAAQ,IAAIka,MAAM,mCAAmCta,MACtDgP,EAAQktB,KAAK,QAAS,CAAE97B,QAAOuY,QAAS,QAAS9P,KAAM,UAC9D,CAIgB,UAAX9F,GAAiC,SAAXA,GAAuB1J,KAAK+Q,MAAMkL,sBAC3Djc,KAAK+Q,MAAMkL,qBAAsB,EACjCxR,EACE,0BAA0B9D,uDACT,SAAX+C,EAAoB,uBAAyB,4GAQxC,WAAXA,GAAwB1J,KAAK+Q,MAAMuL,sBACrCtc,KAAK+Q,MAAMuL,qBAAsB,EACjC7R,EACE,yCAAyC9D,oRAM7C0K,EAAI,2BAA4B3H,EAAQ/C,YAEZ,IAA1BsE,EAAQnC,cAA8B,CAAEA,cAAemC,EAAQnC,eAAkB,WACnD,IAA9BmC,EAAQm+B,kBACR,CAAEx/B,aAAcqB,EAAQm+B,mBACxB,KAEA5yB,EAAQvL,EAAQo+B,UACtBrpC,KAAK8Q,KAAO,CACV6E,UACA7B,QACA0d,YACA8P,YACA4H,MACAzF,WAAY,IAAInV,GAChB6U,UAAW,IAAIpV,GAAe,SACA,IAAxB9iB,EAAQq+B,YAA4B,CAAEtb,UAAW/iB,EAAQq+B,aAAgB,GAC7Erb,UAAW,KACTjuB,KAAKupC,wBAGTpe,YACAjM,gBAAiBjU,EAAQiU,iBAAA,CAAqBrH,GAAcsT,EAAUtT,IACtE2qB,eAAgBv3B,EAAQu3B,eACxBtkB,eAAgBjT,EAAQiT,eACxBC,gBAAiBlT,EAAQkT,gBACzB9S,OACAm+B,aACkC,mBAAzBv+B,EAAQu+B,aACXv+B,EAAQu+B,4BAEN,CAACriC,GAAY,IACXA,EADF,CAEA8D,EAAQu+B,cAChBtiC,UAAW+D,EAAQ/D,WAAawE,EAChC69B,mBAAoBt+B,EAAQs+B,mBAC5Bl4B,MACA5G,OACAi5B,KAAM14B,EAAWC,GACjB4L,YACY,IAAVL,EACI,KACA,IAAI2P,GAAW,CACbC,UAAW5P,EAAM4P,kBACM,IAAnB5P,EAAM6P,SAAyB,CAAEA,SAAU7P,EAAM6P,UAAa,WAC9C,IAAhB7P,EAAM8P,MAAsB,CAAEA,MAAO9P,EAAM8P,OAAU,WACnC,IAAlB9P,EAAM+P,QAAwB,CAAEA,QAAS/P,EAAM+P,SAAY,GAC/DlV,QAERozB,cAAex5B,EAAQmd,YDrHM,GCsH7Bud,sBAAuD,IAAjC16B,EAAQ06B,qBAC9B8D,aAAcx+B,EAAQw+B,cAAA,MAAkC,GACxD5E,eAAyC,IAA1B55B,EAAQ45B,cACvBryB,aAAcvH,EAAQuH,cAAgB,GACtC4D,WAAYnL,EAAQmL,YAAc,GAClC2uB,mBAAiD,IAA9B95B,EAAQ85B,kBAC3Bp0B,kBAAmBD,EAA2BzF,GAC9Ci5B,SAAUj5B,EAAQi5B,UAAY,MAC9B9oB,UAAWnQ,EAAQmQ,WAErBpb,KAAK+oC,OAAS,IAAI/qB,GAAche,KAAK8Q,KAAM9Q,KAAK+Q,OAChD/Q,KAAK8oC,SAAW,IAAI/F,GAAe/iC,KAAK8Q,KAAM9Q,KAAK+Q,MAAO,KACxD/Q,KAAKgiC,gBAET,CASA,KAAApZ,GACE,MAAM7X,MAAEA,GAAU/Q,KAClB,GAAI+Q,EAAM2M,YAAa,OAAO,EAC9B3M,EAAMkK,SAAU,EAChBlK,EAAMmK,WAAY,EAClB,IAEE,OrB9JC,SAAwBiS,GAEN,UAAnBA,EAAK/R,UAAuB4P,KACJ,QAAnBmC,EAAK/R,WAAqBgR,KACnC,MAAM/gB,KAAEA,GAAS8hB,EACjB,IAmDF,SAAwB9hB,GACtB,OAAyB,IAAlBA,EAAKC,QACd,CArDOC,CAAeF,IAA6B,YAApBA,EAAKq+B,WAEhC,YADAxc,GAAgBC,GAGlB,MAAMwc,EAAU,KACTxc,EAAKzP,aACVyP,EAAKE,MAAM,KACTH,GAAgBC,MAGpB9hB,EAAKvE,iBAAiB,mBAAoB6iC,EAAS,CAAEC,MAAM,IAC3Dzc,EAAKU,MAAM,KACTxiB,EAAKrE,oBAAoB,mBAAoB2iC,IAEjD,CqB0IME,CAAe7pC,KAAK8pC,gBACb,CACT,OAAS/iC,GAEP,MADA/G,KAAK+pC,sBACChjC,CACR,CACF,CAGQ,WAAA+iC,GACN,MAAM/4B,MAAEA,EAAAD,KAAOA,GAAS9Q,KACxB,MAAO,CACLqL,KAAMyF,EAAKzF,KACX+P,UAAWtK,EAAKsK,UAChBsC,UAAW,IAAM3M,EAAM2M,YACvBmQ,MAAQiW,IACN/yB,EAAMoK,cAAgB2oB,GAExBzW,MAAQ2c,IACNj5B,EAAMoK,cAAgB,KACtB,IACE6uB,GACF,OAASjjC,GAEP/G,KAAK+pC,sBACL/pC,KAAKiqC,YAAYljC,EAAO,UAAW,SACrC,GAEF+mB,SAAW1S,IACTrK,EAAMqK,UAAYA,GAEpB3Q,KAAMqG,EAAKrG,KACX2iB,SAAU,KACRptB,KAAKotB,YAGX,CAEQ,QAAAA,GACN,MAAMrc,MAAEA,EAAAD,KAAOA,GAAS9Q,KACxB,IAAK+Q,EAAM2M,YAAa,OACxB,MAAMwsB,EAA4B3+B,GAAeuF,EAAKzF,MAClD8+B,GAAiBr5B,EAAKzF,MACtByF,EAAKzF,KACT,GAAqB,OAAjB6+B,EAAuB,MAAM,IAAIjpB,MAAM,iDAM3C,GALAnQ,EAAK0gB,UAAU5I,MAAMshB,GACrBlqC,KAAKipC,aAAeiB,EACpBlqC,KAAKoqC,uBAELpqC,KAAKqqC,uBACAt5B,EAAM2M,cACX5M,EAAKo4B,IAAI9iC,SACJ0K,EAAK6E,QAAQgL,UAAU,OAAQ,CAAE2iB,UAAWtsB,KAAKD,OAAS,IAAMhG,EAAM2M,aACtE3M,EAAM2M,aACX,UAAW4sB,KAAS1B,GAAuB,CACzC,IAAK73B,EAAM2M,YAAa,OACV,IAAV4sB,EACFx5B,EAAK5J,UAAU4J,EAAK04B,gBAEpBz4B,EAAMsM,YAAY3a,KAChBT,WAAW,KACL8O,EAAM2M,aAAa1d,KAAKuqC,uBAC3BD,GAGT,CACF,CAOA,OAAAE,GACE,IAAKxqC,KAAK+Q,MAAM2M,YAAa,OAAO,EACpC,MAAM+sB,EAAezqC,KAAK0qC,UAK1B,OAJA1qC,KAAK+Q,MAAMmK,WAAY,EACnBuvB,GACGzqC,KAAK8Q,KAAK6E,QAAQktB,KAAK,aAAc,CAAEn5B,OAAQ,SAAU45B,UAAWtsB,KAAKD,SAEzE,CACT,CAEA,OAAAU,GACE,MAAM1G,MAAEA,EAAAD,KAAOA,GAAS9Q,KACxB,IAAK+Q,EAAM2M,cAAgB3M,EAAMmK,UAAW,OAC5C,MAAMuvB,IAAe15B,EAAM2M,aAAc1d,KAAK0qC,UAC9C35B,EAAMmK,WAAY,EACduvB,GACG35B,EAAK6E,QAAQktB,KAAK,aAAc,CAAEn5B,OAAQ,UAAW45B,UAAWtsB,KAAKD,QAE5EjG,EAAK4yB,MAAMjiC,SACNqP,EAAK6E,QAAQktB,KAAK,UAAW,CAAES,UAAWtsB,KAAKD,OACtD,CAGQ,OAAA2zB,GACN,MAAM35B,MAAEA,EAAAD,KAAOA,GAAS9Q,KACxB+Q,EAAMsK,aAAe,KACrBtK,EAAMkK,SAAU,EAChB,MAAME,EAAgBpK,EAAMoK,cAC5BpK,EAAMoK,cAAgB,KACA,OAAlBA,GAAwBnb,KAAK2qC,WAAWxvB,GAC5C,UAAW+S,KAAUnd,EAAMsM,YACzBrd,KAAK2qC,WAAW,KACdrrC,aAAa4uB,KA2BjB,OAxBAnd,EAAMsM,YAAY1e,OAAS,EAC3BqB,KAAK2qC,WAAW,KACd75B,EAAKqyB,UAAUra,SAEjB9oB,KAAK2qC,WAAW,KACd75B,EAAKo4B,IAAIznC,WAEXsP,EAAM8M,kBACN7d,KAAK2qC,WAAW,KACd3qC,KAAKgpC,cAAcvf,aACnBzpB,KAAKgpC,aAAe,KACpBhpC,KAAKipC,aAAe,OAEtBjpC,KAAK2qC,WAAW,KACd75B,EAAK0gB,UAAU1I,SAEjB9oB,KAAK2qC,WAAW,KACd75B,EAAKwwB,UAAU7pB,YAEjBzX,KAAK2qC,WAAW,KACd75B,EAAK+F,QAAQY,UACb1G,EAAMyM,OAAO/F,YAEf3G,EAAKgD,MAAMuQ,QACJvT,EAAK2yB,WAAWhV,kBACzB,CAEQ,mBAAAsb,GACN/pC,KAAK0qC,UACL1qC,KAAK2qC,WAAW,KACd3qC,KAAK8Q,KAAK4yB,MAAMjiC,UAEpB,CAEQ,UAAAkpC,CAAWC,GACjB,IACEA,GACF,OAAS7jC,GACP/G,KAAK8Q,KAAKO,IAAI,kBAAmBtK,EACnC,CACF,CAGA,YAAA8jC,GACO7qC,KAAK+Q,MAAM2M,cAChB1d,KAAK+Q,MAAMuM,SAASvK,QACf/S,KAAK8qC,sBAAmB9qC,KAAQgiC,eACvC,CAGQ,oBAAAoI,GACN,MAAM/+B,KAAEA,GAASrL,KAAK8Q,KACjBvF,GAAeF,IAAqC,oBAArB0d,mBACpC/oB,KAAKgpC,cAAcvf,aACnBzpB,KAAKgpC,aAAe,IAAIjgB,iBAAiB,KACvC/oB,KAAK8qC,uBAEP9qC,KAAKgpC,aAAahxB,QAAQ3M,EAAK5M,gBAAiB,CAAE4qB,WAAW,IAC/D,CAGQ,kBAAAyhB,GACN,MAAMz/B,KAAEA,GAASrL,KAAK8Q,KACtB,IAAK9Q,KAAK+Q,MAAM2M,cAAgBnS,GAAeF,GAAO,OAAO,EAC7D,MAAMjL,EAAO+pC,GAAiB9+B,GAC9B,OAAa,OAATjL,GAAiBA,IAASJ,KAAKipC,eACnCjpC,KAAKipC,aAAe7oC,EACpBJ,KAAK8Q,KAAK0gB,UAAU5I,MAAMxoB,GAC1BJ,KAAKgiC,gBACE,EACT,CAEA,UAAItqB,GACF,OAAO1X,KAAK8Q,KAAK2yB,WAAW/rB,MAC9B,CAEA,SAAI5D,GACF,OAAO9T,KAAK8Q,KAAKgD,KACnB,CAEA,eAAIwH,GACF,OAAOtb,KAAK+Q,MAAMuK,WACpB,CAGA,YAAIjL,GACF,OAAOrQ,KAAK+Q,MAAMV,SAAS0H,WAC7B,CAGA,OAAAgzB,GACE,OC1YG,SAAyBj6B,EAAmBC,GACjD,MAAM+C,MAAEA,EAAAwtB,UAAOA,GAAcxwB,EACvBiH,EAAchH,EAAMV,SAAS0H,YAC7Bwc,EAASxjB,EAAMsK,aACf/D,EAAQvG,EAAM2K,UACdsvB,EAAuB,GACvBC,iBAAA,IAAapmC,IACb2gB,EAA+E,GACrF,UAAYrU,EAAW6C,KAAaF,EAAMhI,UAAW,CACnDk/B,EAAWtoC,KAAKyO,GAChB,UAAW+C,KAAWF,OACE,IAAlBE,EAAQT,OAAqBw3B,EAAOhmC,IAAIiP,EAAQT,YAC5B,IAApBS,EAAQsR,SACVA,EAAQ9iB,KAAK,CACXsF,MAAOmJ,EACPyf,QAAS1c,EAAQsR,QACjB5F,UACE1L,EAAQyL,kBAAgD,QAA5BzL,EAAQ5T,QAAQoR,QAAoB,WAAQ,IAIlF,CACA,MAAO,CACLw5B,QAAS7sC,EACT4c,QAASlK,EAAMkK,QACfvD,OAAQ5G,EAAK2yB,WAAW/rB,OACxBtQ,QAAS,CAAE+jC,QAAS,IAAIr6B,EAAK04B,gBAAiB4B,OAAQt6B,EAAK24B,gBAC3Dp5B,SAAU,CACRnL,KAAM6S,EAAY7S,KAClBf,OAAQ4T,EAAY5T,OACpBO,WAAYqT,EAAYrT,WACxBI,aAAc,IAAIiT,EAAYjT,cAAcumC,OAC5CtnC,SAAU,IAAIgU,EAAYhU,UAAUsnC,OACpCC,QAASrjB,sBAAsBlQ,EAAYhU,UAAUlB,MAEvD0oC,UAAW,CACTC,SAAUz6B,EAAMuK,YAChBsB,WAAY7L,EAAMwK,gBAClB/C,UAAWzH,EAAMyK,eACjBiwB,iBAAkB16B,EAAM0K,sBACxB8Y,OAAmB,OAAXA,OAAkB,EAAYA,EAAO3uB,SAASA,UAExDoO,SAAU,CACRkc,SAAUpc,EAAMwQ,aAChBvhB,OAAQ+Q,EAAM2Q,WACdumB,WAAYA,EAAWK,OACvB1vB,aAAc,IAAI5K,EAAM4K,cAAc0vB,OACtCK,aAAc,IAAI36B,EAAM6K,oBAAoByvB,OAC5CM,YAAa76B,EAAK60B,qBAClBsF,OAAQ,IAAIA,GAAQI,OACpB7lB,QAASA,EAAQ6lB,KAAK,CAACjxB,EAAMD,IAAUC,EAAKpS,MAAM4jC,cAAczxB,EAAMnS,QACtEk8B,SAAU,CAAE9yB,KAAMN,EAAKozB,SAAU2H,SAAU96B,EAAMqL,mBAEnDyK,MAAO,CAAE7c,aAAmC,IAA1B8G,EAAKsF,WAAWyQ,SAAwB9V,EAAM8L,YAChEivB,SAAU,CACR16B,KAAMN,EAAKH,kBACXq1B,WAAYj1B,EAAME,gBAClB86B,UAAWh7B,EAAMoL,eACjBpZ,OAAQ,IAAIgO,EAAMG,kBAAkBm6B,QAEtCjwB,UAAW,CAAEhK,KAAMN,EAAKsK,WAAa,MAAOrK,MAAOA,EAAMqK,WACzD4wB,UAAW,CACThiC,aAAsC,IAA7B8G,EAAKsF,WAAWC,SACzB41B,SAAU1X,GAAQmM,kBAAoB,KACnC3vB,EAAM0L,eAEX6kB,UAAW,CACTt4B,QAASs4B,EAAUC,aACnBwE,SAAUzE,EAAU4G,YACpBd,wBAAyB9F,EAAU6G,cACnC+D,qBAAsB5K,EAAU8G,WAChC1sB,UACY,OAAVpE,OACI,EACA,CACEyJ,QAASzJ,EAAMyJ,QACf0nB,cAAenxB,EAAMmxB,cACrB1C,SAAUzuB,EAAMyuB,SAChBphB,WAAYrN,EAAMqN,aAG5BwnB,QAAS,GACThhB,UAAW1nB,OAAOQ,KAAK6M,EAAKqa,WAAWkgB,OAE3C,CDsTWe,CAAgBpsC,KAAK8Q,KAAM9Q,KAAK+Q,MACzC,CAEQ,oBAAAs5B,GACN,MAAMt5B,MAAEA,EAAAD,KAAOA,GAAS9Q,KACxB,IAAK+Q,EAAM2M,YAAa,OACxB,MAAMmkB,EAAQ/wB,EAAKgD,MAAMoQ,cAAcpT,EAAKzF,MAE5C,GADAyF,EAAKO,IAAI,QAASwwB,GACb9wB,EAAM2M,cACN5M,EAAK6E,QAAQgL,UAAU,eAAgBkhB,EAAO,IAAM9wB,EAAM2M,aAC1D3M,EAAM2M,aACX,UAAWnb,KAASuO,EAAKgD,MAAMgC,SAAU,CACvC,IAAK/E,EAAM2M,YAAa,OACxB5M,EAAK0gB,UAAU9H,eAAennB,EAAMjC,QACtC,CACF,CAEQ,YAAA0hC,GACN,MAAMjxB,MAAEA,EAAAD,KAAOA,GAAS9Q,KACxB,IAAK+Q,EAAM2M,YAAa,OACxB,MAAMpL,iBAAA,IAAenG,IACrB,UAAW5J,KAASuO,EAAKgD,MAAMgC,SAC7BxD,EAAS7R,IAAI8B,EAAMjC,QAASiC,GAC5BuO,EAAK0gB,UAAU7H,iBAAiBpnB,EAAMjC,SAGxC,GADAN,KAAKqqC,uBACAt5B,EAAM2M,YAAX,CAEA,UAAWnb,KAASuO,EAAKgD,MAAMgC,SAAU,CACvC,MAAM0K,EAASlO,EAASjS,IAAIkC,EAAMjC,SAC9BkgB,GAAQrP,YAAc5O,EAAM4O,UAAWL,EAAKwwB,UAAU0G,SAASzlC,GAC9DuO,EAAKwwB,UAAUxV,OAAOvpB,EAAMjC,SACjCgS,EAAS5Q,OAAOa,EAAMjC,QACxB,CACA,UAAW+rC,KAAW/5B,EAASwD,SAAOhF,EAAQwwB,UAAUxV,OAAOugB,EAAQ/rC,QAR/C,CAS1B,CAEQ,kBAAAipC,GACN,MAAMx4B,MAAEA,EAAAD,KAAOA,GAAS9Q,KACxB,IAAK+Q,EAAM2M,YAAa,OACxB5M,EAAKo4B,IAAIjiC,oBACT,MAAMstB,EAASxjB,EAAMsK,aACrBtK,EAAMsK,aAAe,KACN,OAAXkZ,GAAiBzjB,EAAKwwB,UAAUyC,eAAexP,EAAO3uB,UAC1DkL,EAAK+F,QAAQY,UACb1G,EAAMyM,OAAO/F,UACb,MAAMgzB,EAAe35B,EAAK2yB,WAAWhV,mBAGrC,IACE3d,EAAKy4B,sBACP,OAASxiC,GACP+J,EAAKO,IAAI,aAActK,EACzB,CACA,GAAKgK,EAAM2M,YAAX,CACA,GAAI+sB,GAAgBzqC,KAAKssC,qBAAsB,CAK7C,GAJAx7B,EAAK4yB,MAAMriC,uBACNyP,EAAK6E,QAAQgL,UAAU,aAAc,CAAEjX,OAAQ,UAAW45B,UAAWtsB,KAAKD,OAAS,IACtF/W,KAAKssC,uBAEFv7B,EAAM2M,YAAa,OAExB,GADI1d,KAAKssC,sBAAsBx7B,EAAKO,IAAI,aAAc,YAAa,IAAK,iBACnEN,EAAM2M,YAAa,MAC1B,CACA1d,KAAKuqC,qBAVmB,CAW1B,CAGQ,mBAAAA,GACN,IACEvqC,KAAK8Q,KAAK5J,UAAUlH,KAAK8Q,KAAK04B,eAChC,OAASziC,GACP/G,KAAKiqC,YAAYljC,EAAO,QAAS,SACnC,CACF,CAEQ,WAAAkjC,CAAYjpB,EAAgB1B,EAAiB9P,GACnD,MAAMzI,EAAQia,aAAiBC,MAAQD,EAAQ,IAAIC,MAAMzf,OAAOwf,IAC3DhhB,KAAK8Q,KAAK6E,QAAQktB,KAAK,QAAS,CAAE97B,QAAOuY,UAAS9P,QACzD,CAEQ,kBAAA88B,GACN,OACEtsC,KAAK+Q,MAAM2M,aACqB,iBAAhC1d,KAAK8Q,KAAK2yB,WAAW/rB,QACO,OAA5B1X,KAAK+Q,MAAMsK,YAEf,GAIF,SAAS9P,GAAeF,GACtB,OAAyB,IAAlBA,EAAKC,QACd,CAGA,SAAS6+B,GAAiB9+B,GACxB,OAAOA,EAAKjL,IACd,CEveO,IAAMmsC,aAAN,MACIC,kBAAA,IAAergC,IACfy9B,kBAAA,IAAYz9B,IAErB,EAAAsgC,CAAyBhmC,EAAUuD,GACjC,OAAOhK,MAAK0sC,EAAU1sC,MAAKwsC,EAAU/lC,EAAOuD,EAC9C,CAEA,IAAA4/B,CAA2BnjC,EAAUuD,GACnC,OAAOhK,MAAK0sC,EAAU1sC,MAAK4pC,EAAOnjC,EAAOuD,EAC3C,CAEA,GAAA2iC,CAA0BlmC,EAAUuD,GAClChK,MAAKR,EAAQQ,MAAKwsC,EAAU/lC,EAAOuD,GACnChK,MAAKR,EAAQQ,MAAK4pC,EAAOnjC,EAAOuD,EAClC,CAGA,UAAM64B,CAA2Bp8B,EAAUY,SACnCrH,MAAK4sC,EAAgBnmC,EAAOY,EACpC,CAOA,eAAMsZ,CACJla,EACAY,EACAwlC,GAEA,OAAO7sC,MAAK4sC,EAAgBnmC,EAAOY,EAASwlC,EAC9C,CAEA,OAAMD,CACJnmC,EACAY,EACAwlC,GAEA,MAAMC,EAAW,IAAeD,QAAsB,EACtD,IAAKC,IAAY,OAAO,EACxB,MAAMN,EAAUxsC,MAAKwsC,EAASnsC,IAAIoG,GAClC,GAAI+lC,EACF,UAAWxiC,IAAW,IAAIwiC,GAAU,CAClC,IAAKM,IAAY,OAAO,EAExB,SADM9sC,MAAK+sC,EAAQ/iC,EAAS3C,EAASZ,IAChCqmC,IAAY,OAAO,CAC1B,CAEF,IAAKA,IAAY,OAAO,EACxB,MAAMlD,EAAO5pC,MAAK4pC,EAAMvpC,IAAIoG,GAC5B,GAAImjC,GAAQA,EAAKllB,KAAO,EAAG,CACzB,MAAM+R,EAAW,IAAImT,GACrB5pC,MAAK4pC,EAAMloC,OAAO+E,GAClB,UAAWuD,KAAWysB,EAAU,CAC9B,IAAKqW,IAAY,OAAO,EAExB,SADM9sC,MAAK+sC,EAAQ/iC,EAAS3C,EAASZ,IAChCqmC,IAAY,OAAO,CAC1B,CACF,CACA,OAAOA,GACT,CAGA,aAAAj3B,CAAcpP,GACZ,OAAQzG,MAAKwsC,EAASnsC,IAAIoG,IAAQie,MAAQ,IAAM1kB,MAAK4pC,EAAMvpC,IAAIoG,IAAQie,MAAQ,EACjF,CAGA,kBAAAsoB,CAAmBvmC,GACjB,QAAc,IAAVA,EAGF,OAFAzG,MAAKwsC,EAASnoB,aACdrkB,MAAK4pC,EAAMvlB,QAGbrkB,MAAKwsC,EAAS9qC,OAAO+E,GACrBzG,MAAK4pC,EAAMloC,OAAO+E,EACpB,CAGA,UAAAwmC,GACE,MAAMr4B,iBAAA,IAAY/P,IAClB,UAAWgH,KAAO7L,MAAKwsC,EAASvoC,OAAQ2Q,EAAM3P,IAAI4G,GAClD,UAAWA,KAAO7L,MAAK4pC,EAAM3lC,OAAQ2Q,EAAM3P,IAAI4G,GAC/C,MAAO,IAAI+I,EACb,CAEA,EAAA83B,CACEprB,EACA7a,EACAuD,GAEA,IAAIvJ,EAAM6gB,EAAOjhB,IAAIoG,GAMrB,OALKhG,IACHA,iBAAA,IAAUoE,IACVyc,EAAO7gB,IAAIgG,EAAOhG,IAEpBA,EAAIwE,IAAI+E,GACD,KACLhK,MAAKR,EAAQ8hB,EAAQ7a,EAAOuD,GAEhC,CAEA,EAAAxK,CAAQ8hB,EAA0C7a,EAAmBuD,GACnE,MAAMvJ,EAAM6gB,EAAOjhB,IAAIoG,QACX,IAARhG,IACJA,EAAIiB,OAAOsI,GACM,IAAbvJ,EAAIikB,MAAYpD,EAAO5f,OAAO+E,GACpC,CAEA,OAAMsmC,CAAQ/iC,EAAqB3C,EAAkBZ,GACnD,UACQuD,EAAQ3C,EAChB,OAASu7B,GACP,MAAMsK,EACa,iBAAVzmC,GAAuC,iBAAVA,EAAqBjF,OAAOiF,GAAS,UAC3E6D,EAAiB,uCAAuC4iC,YAAiBtK,EAC3E,CACF,GC5HK,SAASuK,aACd,GAAsB,oBAAX7mC,OAAwB,OAAO,EAC1C,IACE,OAAOA,OAAO8mC,OAAS9mC,OAAO0T,GAChC,OAEE,OAAO,CACT,CACF,CAGO,SAASqzB,YACd,MAAsB,oBAAX/mC,QACa,MAAjBA,OAAOyD,MAChB,CAGO,SAASujC,qBACd,OAAOH,cAAgBE,WACzB,CAGO,SAASE,YACd,MAAMC,EASR,WACE,GAAuB,oBAAZC,QAAyB,OACpC,MAAM9qC,EAAQ8qC,QAAQrQ,IAAc,SACpC,MAAwB,iBAAVz6B,EAAqBA,OAAQ,CAC7C,CAbkB+qC,GAChB,QAAgB,IAAZF,EAAuB,MAAmB,eAAZA,EAClC,GAAsB,oBAAXlnC,OAAwB,CACjC,MAAM6mB,EAAO7mB,OAAOqnC,SAASC,SAC7B,MAAgB,cAATzgB,GAAiC,cAATA,CACjC,CACA,OAAO,CACT,CC7BA,IAAM0gB,GAAoB,kDACpBC,GAAuB,0BAGvBC,GAA+C,CACnD,IAAM,KAAM,KAAM,IAAM,KAAM,IAAM,KAAM,KAAM,IAAM,KAAM,KAAM,KAiCvDC,eAAN,MACIj9B,GAET,WAAApR,CAAYsL,EAAiC,IAC3C,MAAMmI,iBAAA,IAAevO,IACrB,UAAW8B,KAAUsE,EAAQgjC,mBAAqB,GAAI,CACpD,MAAMC,EAAaC,GAAgBxnC,QAChB,IAAfunC,GAA0B96B,EAASnO,IAAIipC,EAC7C,CACA,IAAIE,EACJ,GAAInjC,EAAQojC,yBAA2B,EAAM,CAC3C,MAAMC,EACJrjC,EAAQqjC,WAAiC,oBAAb/vC,SAA2BA,SAAS+vC,SAAW,IAC7E,GAAIA,EAAS3vC,OAAS,EACpB,IACE,MAAMgI,EAAS,IAAIyJ,IAAIk+B,GAAU3nC,OAC7BA,GAAqB,SAAXA,IAAmBynC,EAAiBznC,EACpD,OAEA,CAEJ,CACA,MAAM4nC,GACHtjC,EAAQujC,0BAA2B,KAAUvjC,EAAQwjC,cAAgBlB,aACxEvtC,MAAK+Q,EAAS,CACZqC,EACAg7B,EACAG,OACmB,IAAnBH,OACA,EAEJ,CAGA,OAAA50B,CAAQ7S,GACN,OAAsB,IAAlBA,EAAOhI,QAA2B,SAAXgI,SACkB,IAAzC3G,MAAK+Q,EAAO,GACPpK,IAAW3G,MAAK+Q,EAAO,KAE5B/Q,MAAK+Q,EAAO,GAA4B/L,IAAI2B,IAGG,IAAjD3G,MAAK+Q,EAAO,GAA4B2T,WACG,IAA3C1kB,MAAK+Q,EAAO,IACZpK,IAAW3G,MAAK+Q,EAAO,OAIrB/Q,MAAK+Q,EAAO,KAA8B88B,GAAkB5tC,KAAK0G,IAEvE,CAGA,UAAA+nC,CAAW/nC,GACT,QAAK3G,KAAKwZ,QAAQ7S,KAClB3G,MAAK+Q,EAAO,GAA2BpK,GAChC,EACT,CAGA,YAAAgoC,GACE,MAAMr8B,EAAWtS,MAAK+Q,EAAO,GAE7B,OADA/Q,MAAK+Q,EAAO,QAA2B,EAChCuB,CACT,CAEA,gBAAIm3B,GACF,OAAOzpC,MAAK+Q,EAAO,EACrB,CAGA,SAAA69B,GACE,QAA6C,IAAzC5uC,MAAK+Q,EAAO,GACd,MAAO,CAAC/Q,MAAK+Q,EAAO,IAEtB,MAAM5N,EAAS,IAAI0B,IAAY7E,MAAK+Q,EAAO,IAO3C,GALmD,IAAjD/Q,MAAK+Q,EAAO,GAA4B2T,WACG,IAA3C1kB,MAAK+Q,EAAO,IAEZ5N,EAAO8B,IAAIjF,MAAK+Q,EAAO,IAErB/Q,MAAK+Q,EAAO,GACd,UAAW89B,KAAQd,GACjB5qC,EAAO8B,IAAI,oBAAoBzD,OAAOqtC,MACtC1rC,EAAO8B,IAAI,oBAAoBzD,OAAOqtC,MAG1C,MAAO,IAAI1rC,EACb,CAGA,wBAAI2rC,GACF,OAAO9uC,MAAK+Q,EAAO,EACrB,CAGA,4BAAIg+B,GACF,SAAK5B,cACDntC,MAAK+Q,EAAO,GAA4B2T,KAAO,GAC/C1kB,MAAK+Q,EAAO,SAC+B,IAA3C/Q,MAAK+Q,EAAO,GAElB,CAGA,uBAAIi+B,GACF,QAAIhvC,MAAK+Q,EAAO,GAA4B2T,KAAO,GAC/C1kB,MAAK+Q,EAAO,SACkC,IAA3C/Q,MAAK+Q,EAAO,GACrB,GAIK,SAASo9B,GAAgBxrC,GAC9B,MAAMsN,EAAUtN,EAAMuN,OACtB,GAAuB,IAAnBD,EAAQtR,OACZ,IACE,MAAMqR,EAAM,IAAII,IAAIH,GACpB,GAAqB,UAAjBD,EAAIK,UAAyC,WAAjBL,EAAIK,SAAuB,OAC3D,IAAKy9B,GAAqB7tC,KAAK+P,EAAIrJ,QAAS,OAC5C,OAAOqJ,EAAIrJ,MACb,OACE,MACF,CACF,CCxJO,IAAMsoC,GAA+B,OAE/BC,GAAN,MACIC,GACA99B,GAGA+9B,kBAAA,IAAiBvqC,IAC1BkM,GAAyD,UAEzD,WAAApR,CAAYwvC,EAAoB99B,GAC9BrR,MAAKmvC,EAAcA,EACnBnvC,MAAKqR,EAAOA,CACd,CAEA,UAAAg+B,GACE,GAAoB,WAAhBrvC,MAAK+Q,EACP,MAAM,IAAIkQ,MAAM,uBAAuBjhB,MAAKmvC,yBAEhD,CAEA,UAAI5a,GACF,MAAuB,WAAhBv0B,MAAK+Q,CACd,CAGA,QAAA+7B,GACE,MAAuB,WAAhB9sC,MAAK+Q,CACd,CAGA,GAAAqhB,CAAIwY,GAEF,OADA5qC,KAAKqvC,aACErvC,MAAKsvC,EAAO,CACjB7hC,KAAM,UACN8hC,aAAS,EACTC,cAAU,EACV5E,UACA6E,UAAU,GAEd,CAGA,KAAAC,CACEjiC,EACA8hC,EACAC,GAEAxvC,KAAKqvC,aACL,MAAMM,EAA2B,CAC/BliC,OACA8hC,UACAC,WACA5E,aAAS,EACT6E,UAAU,GAENG,EAAU5vC,MAAKsvC,EAAOK,GAC5B,GAAoB,WAAhB3vC,MAAK+Q,EACP,IACE/Q,MAAK6vC,EAAUF,EACjB,OAAS5oC,GAEP,MADA/G,MAAK4vC,EAASD,GACR5oC,CACR,CAEF,OAAO6oC,CACT,CAGA,MAAAE,GACE,MAAMA,EAAuC,CAC3C3N,UAAW,EACX3jB,SAAU,EACVuxB,aAAc,EACdnF,QAAS,GAEX,UAAW+E,KAAY3vC,MAAKovC,EAAYU,EAAOH,EAASliC,OAAS,EACjE,OAAOqiC,CACT,CAGA,MAAA/0B,GACE,GAAoB,YAAhB/a,MAAK+Q,EACP,MAAM,IAAIkQ,MAAM,uBAAuBjhB,MAAKmvC,0BAE9CnvC,MAAK+Q,EAAS,aACd,IACE,UAAW4+B,KAAY3vC,MAAKovC,EAAYpvC,MAAK6vC,EAAUF,GACvD3vC,MAAK+Q,EAAS,QAChB,OAAShK,GAEP,MADA/G,KAAKgwC,QACCjpC,CACR,CACF,CAEA,KAAAipC,GACE,GAAoB,WAAhBhwC,MAAK+Q,EAAT,CACA/Q,MAAK+Q,EAAS,SACd,UAAW4+B,IAAY,IAAI3vC,MAAKovC,GAAYa,UAAWjwC,MAAK4vC,EAASD,GACrE3vC,MAAKovC,EAAW/qB,OAHc,CAIhC,CAEA,EAAAirB,CAAOK,GAEL,OADA3vC,MAAKovC,EAAWnqC,IAAI0qC,GACb,KACL3vC,MAAK4vC,EAASD,GAElB,CAEA,EAAAE,CAAUF,GACR,GAAIA,EAASF,eAAiC,IAArBE,EAAS/E,cAA8C,IAArB+E,EAASJ,QAClE,OAEF,MAAM3E,EAAU+E,EAASJ,UACzBI,EAAS/E,QAAUA,GAAWqE,EAChC,CAEA,EAAAW,CAASD,GACP,GAAIA,EAASF,SAAU,OACvBE,EAASF,UAAW,EACpBzvC,MAAKovC,EAAW1tC,OAAOiuC,GACvB,MAAM/E,EAAU+E,EAAS/E,QAEzB,GADA+E,EAAS/E,aAAU,OACH,IAAZA,EACF,IAGMzlC,EADqCylC,MAEvC5qC,MAAKqR,EACH,WAAWrR,MAAKmvC,uEAGtB,OAASpoC,GACP/G,MAAKqR,EAAK,WAAWrR,MAAKmvC,qBAAgCpoC,EAC5D,CAEF,IACE4oC,EAASH,YACX,OAASzoC,GACP/G,MAAKqR,EAAK,WAAWrR,MAAKmvC,qBAAgCpoC,EAC5D,CACF,GC9IWmpC,GAAN,MACIC,GACAhM,GACAiM,kBAAA,IAAqBvrC,IAE9B,WAAAlF,CAAYwwC,EAAsBhM,GAChCnkC,MAAKmwC,EAAUA,EACfnwC,MAAKmkC,EAASA,CAChB,CAEA,EAAAsI,CACEhmC,EACAuD,GAEA,OAAOhK,MAAKqwC,EAAW,KAAM5pC,EAAOuD,EACtC,CAEA,IAAA4/B,CACEnjC,EACAuD,GAEA,OAAOhK,MAAKqwC,EAAW,OAAQ5pC,EAAOuD,EACxC,CAEA,GAAA2iC,CACElmC,EACAuD,GAEA,MAAMsmC,EAAiBtmC,EACvB,UAAW+lC,IAAgB,IAAI/vC,MAAKowC,GAC9BL,EAAatpC,QAAUA,GAASspC,EAAa/lC,UAAYsmC,GAC3DP,EAAaH,SAGnB,CAEA,IAAA/M,CACEp8B,EACAY,GAGA,OADArH,MAAKmkC,EAAOkL,aACLrvC,MAAKmwC,EAAQtN,KAAKp8B,EAAOY,EAClC,CAEA,SAAAsZ,CACEla,EACAY,EACAwlC,GAGA,OADA7sC,MAAKmkC,EAAOkL,aACLrvC,MAAKmwC,EAAQxvB,UAAUla,EAAOY,EAAS,KAC5C,IAAKrH,MAAKmkC,EAAO2I,WAAY,OAAO,EACpC,MAAMyD,EAAiB1D,IAEvB,QAAK7sC,MAAKmkC,EAAO2I,YACVyD,GAEX,CAEA,aAAA16B,CAAcpP,GACZ,IAAIlF,EAAQ,EACZ,UAAWwuC,KAAgB/vC,MAAKowC,EAC1BL,EAAatpC,QAAUA,IAAOlF,GAAS,GAE7C,OAAOA,CACT,CAEA,kBAAAyrC,CAAmBvmC,GACjB,UAAWspC,IAAgB,IAAI/vC,MAAKowC,QACpB,IAAV3pC,GAAuBspC,EAAatpC,QAAUA,GAAAspC,EAAoBH,SAE1E,CAEA,UAAA3C,GACE,MAAMr4B,iBAAA,IAAY/P,IAClB,UAAWkrC,KAAgB/vC,MAAKowC,EAAgBx7B,EAAM3P,IAAI8qC,EAAatpC,OACvE,MAAO,IAAImO,EACb,CAEA,EAAAy7B,CACE5iC,EACAhH,EACAuD,GAEAhK,MAAKmkC,EAAOkL,aAEZ,MAAMiB,EAAiBtmC,EACjBopB,EAAW,IAAIpzB,MAAKowC,GAAgBI,KACvCT,GACCA,EAAatiC,OAASA,GACtBsiC,EAAatpC,QAAUA,GACvBspC,EAAa/lC,UAAYsmC,GAE7B,QAAiB,IAAbld,EAAwB,OAAOA,EAASwc,QAI5C,IAAIA,EAAUX,GACVwB,GAAqB,EACzB,MAAMC,EAAgDC,MAAOtpC,IACtDrH,MAAKmkC,EAAO5P,QAAWkc,IAEf,SAAThjC,GAAiBmiC,UACf5lC,EAAQ3C,KAEV0oC,EAAkC,CACtCtiC,OACAhH,QACAuD,QAASsmC,EACTV,QAASX,IAYX,OAVAW,EAAU5vC,MAAKmkC,EAAOuL,MACpB,eACA,IAAM1vC,MAAKmwC,EAAQ1iC,GAAMhH,EAAOiqC,GAChC,KACED,GAAqB,EACrBzwC,MAAKowC,EAAe1uC,OAAOquC,KAG/BA,EAAaH,QAAUA,EACvB5vC,MAAKowC,EAAenrC,IAAI8qC,GACjBH,CACT,GC7FWgB,GAAN,MACIT,GACAU,GAEAC,GACAC,GACA1/B,GACA86B,kBAAA,IAAehgC,IACf6kC,kBAAA,IAAoB7kC,IACpB8kC,kBAAA,IAAiB9kC,IACjB+kC,kBAAA,IAAkBrsC,IAClBssC,kBAAA,IAAkBhlC,IAC3BilC,GAAgC/rC,QAAQC,UAGxC+rC,GAAe,EAEf,WAAA1xC,CAAYsL,GACVjL,MAAKmwC,EAAUllC,EAAQklC,OACvBnwC,MAAK6wC,EAAU5lC,EAAQ4lC,OACvB7wC,MAAK8wC,EAAoB7lC,EAAQqmC,sBACjCtxC,MAAKqR,EAAOlH,EAAkBc,EAAQoG,KACtC,MAAM0/B,EAAmB9lC,EAAQ8lC,iBACjC/wC,MAAK+wC,OACkB,IAArBA,OACI,EACA5mC,EAAkB,IAAIF,KAGpB,MAAMlD,EAAQkD,EAAK,GACnB,IACE,OAAO8mC,EAAiBhqC,EAC1B,OAASkjC,GAEP,YADAjqC,MAAKqR,EAAK,mCAAoC44B,EAEhD,GAEV,CAGA,QAAAyC,CAAS6E,GACP,OAAIvxC,MAAKqxC,EAAe,EAAUrxC,MAAKwxC,EAAaD,GAAQ,GACrDvxC,MAAKmJ,EAAS,IAAMnJ,MAAKwxC,EAAaD,GAAQ,GACvD,CAGA,UAAAE,CAAW5uC,GACT,OAAI7C,MAAKqxC,EAAe,EAAUrxC,MAAK0xC,EAAe7uC,GAAM,GACrD7C,MAAKmJ,EAASwnC,gBACb3wC,MAAK0xC,EAAe7uC,GAAM,IAEpC,CAGA,UAAA8uC,GACE,OAAI3xC,MAAKqxC,EAAe,EAAUrxC,MAAK4xC,GAAe,GAC/C5xC,MAAKmJ,EAASwnC,gBACb3wC,MAAK4xC,GAAe,IAE9B,CAGA,eAAAC,CACE1gC,EACAxO,EACA2c,EACA3B,GAEA,MAAMm0B,EAAgB9xC,MAAKmxC,EAAY9wC,IAAI8Q,GAC3C,QAAsB,IAAlB2gC,GAAwD,IAAzBA,EAAcnzC,OAAc,OAAOgE,EAEtE,IAAIQ,EAAkBR,EACtB,UAAWovC,IAAgB,IAAID,GAAgB,CAC7C,IAAKC,EAAaxd,OAAQ,SAC1B,MAAM4N,UAAEA,GAAc4P,EACtB,IAAsB,IAAlBp0B,MAAyB,OAAOhb,EACpC,IACEQ,EAASg/B,EAAUh/B,EAAQ,CACzBgO,YACA7Q,QAASgf,EAAQhf,QACjBif,UAAWD,EAAQC,YAErB,MAAMmjB,EAAmBv9B,EAAsBhC,GAG/C,IAAsB,IAAlBwa,MAAyB,OAAOhb,EACpC,GAAI+/B,EACF,MAAM,IAAIC,UACR,kBAAkBxxB,iEAGxB,OAASpK,GACP,IAAsB,IAAlB4W,MAAyB,OAAOhb,EACpC,MAAMoF,EAAahB,aAAiBka,MAAQla,EAAQ,IAAIka,MAAMzf,OAAOuF,IAGrE,OAFA/G,MAAKqR,EAAK,kBAAkBF,aAAsBpJ,GAClD/H,MAAK+wC,IAAoBhpC,GAClBpF,CACT,CACF,CACA,OAAOQ,CACT,CAEA,IAAA6uC,GACE,MAAO,IAAIhyC,MAAKmsC,EAASloC,OAC3B,CAGA,QAAAwyB,GACE,MAAM3qB,EAA8B,GAC9BmmC,EAAW,CACfpvC,EACAqoC,EACAn6B,EACAozB,KAEA,MAAM2L,EAAS3L,EAAM2L,SACrB,MAAO,CACLjtC,OACAqoC,UACAn6B,QACA+gC,cAAe,CACbX,WAAYrB,EAAO3N,UACnBhX,UAAW2kB,EAAOtxB,SAClB4xB,cAAeN,EAAOC,aACtBmC,SAAUpC,EAAOlF,WAIvB,UAAY/nC,EAAMmuC,KAAiBhxC,MAAKgxC,EACtCllC,EAAQpJ,KAAKuvC,EAASpvC,OAAM,EAAW,eAAgBmuC,EAAa7M,QAEtE,UAAYthC,EAAMkvC,KAAiB/xC,MAAKmsC,EACtCrgC,EAAQpJ,KAAKuvC,EAASpvC,EAAMkvC,EAAaR,OAAOrG,QAAS,SAAU6G,EAAa5N,QAGlF,UAAWthC,KAAQ7C,MAAKixC,EAAWhtC,OACjC6H,EAAQpJ,KAAK,CACXG,OACAqoC,aAAS,EACTn6B,MAAO,eACP+gC,cAAe,CAAEX,WAAY,EAAGhmB,UAAW,EAAGilB,cAAe,EAAG8B,SAAU,KAG9E,OAAOpmC,CACT,CAEA,QAAI4Y,GACF,OAAO1kB,MAAKmsC,EAASznB,IACvB,CAEA,OAAM8sB,CAAaD,EAA2Bh8B,GAC5C,GACEvV,MAAKmsC,EAASnnC,IAAIusC,EAAO1uC,OACzB7C,MAAKgxC,EAAchsC,IAAIusC,EAAO1uC,OAC9B7C,MAAKixC,EAAWjsC,IAAIusC,EAAO1uC,MAG3B,YADA7C,MAAKqR,EAAK,WAAWkgC,EAAO1uC,4BAI9B,MAAMsvC,ECnIH,SACLC,EACAC,GAGA,QAAe,IAAXD,EAAJ,CACA,QAAuB,IAAnBA,EAAOE,UArBN,SAAwBpH,EAAiBqH,GAC9C,MAAM/vC,EA/CR,SAAsB8L,GACpB,MAAMiuB,EAAQ,yBAAyBiW,KAAKlkC,EAAK4B,QACjD,GAAc,OAAVqsB,EACJ,MAAO,CAACl4B,OAAOk4B,EAAM,IAAKl4B,OAAOk4B,EAAM,IAAKl4B,OAAOk4B,EAAM,IAC3D,CA2CiBkW,CAAavH,GAC5B,YAAe,IAAX1oC,GACiB+vC,EAAMltB,MAAM,MACbpR,KAAMy+B,IACxB,MAAMC,EAAcD,EACjBxiC,OACAmV,MAAM,OACNnN,OAAQ06B,GAASA,EAAKj0C,OAAS,GAClC,OAA2B,IAAvBg0C,EAAYh0C,OAA4C,KAAvB+zC,EAAYxiC,QAAkC,KAAjBqiC,EAAMriC,OACjEyiC,EAAYxlC,MAAO0lC,GA1C9B,SAA6B3H,EAAkB2H,GAC7C,MAAM5iC,EAAU4iC,EAAW3iC,OAC3B,GAAgB,KAAZD,GAA8B,MAAZA,EAAiB,OAAO,EAC9C,MAAMssB,EAAQ,+CAA+CiW,KAAKviC,GAClE,GAAc,OAAVssB,EAAgB,OAAO,EAC3B,MAAMuW,EAAWvW,EAAM,IAAM,IACvBl2B,EAAkB,CAAChC,OAAOk4B,EAAM,IAAKl4B,OAAOk4B,EAAM,IAAKl4B,OAAOk4B,EAAM,KACpEwW,EAfR,SAAiBttC,EAAYC,GAC3B,QAAS+G,EAAQ,EAAGA,EAAQ,EAAGA,GAAS,EAAG,CACzC,MAAMumC,GAASvtC,EAAEgH,IAAU,IAAM/G,EAAE+G,IAAU,GAC7C,GAAc,IAAVumC,EAAa,OAAOA,CAC1B,CACA,OAAO,CACT,CASgBC,CAAQ/H,EAAS7kC,GAC/B,OAAQysC,GACN,IAAK,IACH,OAAiB,IAAVC,EACT,IAAK,IACH,OAAOA,EAAQ,EACjB,IAAK,KACH,OAAOA,GAAS,EAClB,IAAK,IACH,OAAOA,EAAQ,EACjB,IAAK,KACH,OAAOA,GAAS,EAClB,IAAK,IACH,OAAOA,GAAS,GAAK7H,EAAQ,KAAO7kC,EAAO,IAAM6kC,EAAQ,KAAO7kC,EAAO,GACzE,IAAK,IACH,QAAI0sC,EAAQ,KACR1sC,EAAO,GAAK,EAAU6kC,EAAQ,KAAO7kC,EAAO,GAC5CA,EAAO,GAAK,EAAyB,IAAf6kC,EAAQ,IAAYA,EAAQ,KAAO7kC,EAAO,GAC9C,IAAf6kC,EAAQ,IAA2B,IAAfA,EAAQ,IAAYA,EAAQ,KAAO7kC,EAAO,IACvE,QACE,OAAO,EAEb,CAa6C6sC,CAAoB1wC,EAAQqwC,KAEzE,CASuCM,CAAed,EAAgBD,EAAOE,SACzE,MAAO,oBAAoBF,EAAOE,4BAA4BD,IAEhE,QAAwB,IAApBD,EAAO/hC,SAAwB,CACjC,IAAKhM,OAAO+uC,UAAUhB,EAAO/hC,WAAa+hC,EAAO/hC,SAAW,EAC1D,MAAO,wCAAwC7O,OAAO4wC,EAAO/hC,YAE/D,GAAI+hC,EAAO/hC,S/DlFyB,E+DmFlC,MAAO,qBAAqB7O,OAAO4wC,EAAO/hC,kCAAkC7O,O/DnF1C,I+DqFtC,CAXiC,CAanC,CDiH4B6xC,CAAkB9B,EAAOa,OAAQ/zC,GACzD,QAAwB,IAApB8zC,EAEF,YADAnyC,MAAKszC,EAAQ/B,EAAO1uC,KAAMsvC,GAG5B,MAAMhO,EAAQ,IAAI+K,GAAcqC,EAAO1uC,KAAM7C,MAAKqR,GAC5CiO,EAAUtf,MAAKuzC,EAAehC,EAAO1uC,KAAMshC,GAC3C6M,EAA+C,CAAE7M,QAAOZ,WAAW,GACzEvjC,MAAKgxC,EAAcvwC,IAAI8wC,EAAO1uC,KAAMmuC,GACpC,IAEE,SADMhxC,MAAKwzC,EAAS,IAAMjC,EAAOkC,KAAKn0B,GAAU/J,GAC5Cy7B,EAAazN,UAAW,OAC5BY,EAAMppB,QACR,OAAShU,GAGP,OAFAo9B,EAAM6L,aACDgB,EAAazN,WAAWvjC,MAAKqR,EAAK,WAAWkgC,EAAO1uC,qBAAsBkE,GAEjF,SACM/G,MAAKgxC,EAAc3wC,IAAIkxC,EAAO1uC,QAAUmuC,GAC1ChxC,MAAKgxC,EAActvC,OAAO6vC,EAAO1uC,KAErC,CAEA7C,MAAKmsC,EAAS1rC,IAAI8wC,EAAO1uC,KAAM,CAAE0uC,SAAQpN,UACzCnkC,MAAKqR,EAAK,WAAWkgC,EAAO1uC,mBAC9B,CAGA,EAAAywC,CAAQzwC,EAAc6G,GACpB,MAAM/H,EAAU,WAAWkB,eAAkB6G,IAC7C1J,MAAKqR,EAAK1P,GACL3B,MAAKmwC,EAAQtN,KAAK,QAAS,CAC9B97B,MAAO,IAAIka,MAAMtf,GACjB2d,QAAS,SACT9P,KAAM,UAEV,CAEA,EAAA+jC,CAAepE,EAAoBhL,GACjC,MAAO,CACLgM,OAAQ,IAAID,GAAmBlwC,MAAKmwC,EAAShM,GAC7CmN,sBAAwB9yB,IACtB2lB,EAAMuL,MAAM,WAAY,KACtB,MAAMvsC,EAASnD,MAAK8wC,EAAkBtyB,GACtC,MA/MgB,mBA+MQrb,EAAUA,OAAS,KAG/CuwC,kBAAmB,CAACviC,EAAWgxB,KAC7B,MAAM4P,EAAsC,CAAE5P,YAAW5N,QAAQ,GACjE4P,EAAMuL,MAAM,YAAa,KACvBqC,EAAaxd,QAAS,EACtB,MAAMnB,EAAWpzB,MAAKmxC,EAAY9wC,IAAI8Q,GAItC,YAHiB,IAAbiiB,EAAwBpzB,MAAKmxC,EAAY1wC,IAAI0Q,EAAW,CAAC4gC,IACxD3e,EAAS1wB,KAAKqvC,GAEZ,KACLA,EAAaxd,QAAS,EACtB,MAAMjc,EAAUtY,MAAKmxC,EAAY9wC,IAAI8Q,GACrC,QAAgB,IAAZmH,EAAuB,OAC3B,MAAM7L,EAAQ6L,EAAQ2M,QAAQ8sB,GAC1BtlC,GAAS,GAAG6L,EAAQ4M,OAAOzY,EAAO,GACf,IAAnB6L,EAAQ3Z,QAAcqB,MAAKmxC,EAAYzvC,OAAOyP,OAIxDwiC,gBAAkB/I,IAChBzG,EAAM/R,IAAIwY,IAEZgJ,UAAW,IAAM5zC,MAAK6wC,EACtBx/B,IAAK,IAAIpH,KACPjK,MAAKqR,EAAK,IAAI89B,QAAkBllC,IAGtC,CAEA,EAAAynC,CAAe7uC,EAAc0S,GAC3B,MAAMy7B,EAAehxC,MAAKgxC,EAAc3wC,IAAIwC,GAC5C,QAAqB,IAAjBmuC,EAGF,OAFAA,EAAazN,WAAY,EACzByN,EAAa7M,MAAM6L,QACZ3qC,QAAQC,UAGjB,MAAMuuC,EAAmB7zC,MAAKixC,EAAW5wC,IAAIwC,GAC7C,QAAyB,IAArBgxC,EAGF,OAAI7zC,MAAKkxC,EAAYlsC,IAAInC,GAAcwC,QAAQC,UACxCiQ,EAASvV,MAAK8zC,EAAWD,GAAoBA,EAEtD,MAAM9B,EAAe/xC,MAAKmsC,EAAS9rC,IAAIwC,GACvC,QAAqB,IAAjBkvC,EAA4B,OAAO1sC,QAAQC,UAI/CtF,MAAKmsC,EAASzqC,OAAOmB,GACrBkvC,EAAa5N,MAAM6L,QACnB,MAAM+D,EAAW1uC,QAAQC,UAAUF,KAAK,IACtCpF,MAAKg0C,EAAenxC,EAAMkvC,EAAaR,OAAQh8B,IAMjD,OAJAvV,MAAKixC,EAAWxwC,IAAIoC,EAAMkxC,GACrBA,EAAS3uC,KAAK,KACbpF,MAAKixC,EAAW5wC,IAAIwC,KAAUkxC,GAAU/zC,MAAKixC,EAAWvvC,OAAOmB,KAE9DkxC,CACT,CAEA,OAAMC,CAAenxC,EAAc0uC,EAA2Bh8B,GAC5D,QAAuB,IAAnBg8B,EAAO95B,QAAX,CACAzX,MAAKkxC,EAAYjsC,IAAIpC,GACrB,UACQ7C,MAAKwzC,EAAS,IAAMjC,EAAO95B,YAAalC,EAChD,OAASxO,GACP/G,MAAKqR,EAAK,WAAWxO,qBAAyBkE,EAChD,SACE/G,MAAKkxC,EAAYxvC,OAAOmB,EAC1B,CARkC,CASpC,CAEA,OAAM+uC,CAAer8B,GACnB,UAAWy7B,KAAgBhxC,MAAKgxC,EAAcl7B,SAC5Ck7B,EAAazN,WAAY,EACzByN,EAAa7M,MAAM6L,QAErB,MAAMp7B,EAAQ,IAAI5U,MAAKmsC,EAASloC,QAChC,UAAWpB,KAAQ+R,QAAa5U,MAAK0xC,EAAe7uC,EAAM0S,EAC5D,CAEA,OAAMi+B,CAASvoB,EAAkC1V,GAC1CA,QAICvV,MAAK8zC,EAAWzuC,QAAQC,UAAUF,KAAK6lB,UAHrCA,GAIV,CAEA,OAAM6oB,CAAW9qC,GACfhJ,MAAKqxC,GAAgB,EACrB,UACQroC,CACR,SACEhJ,MAAKqxC,GAAgB,CACvB,CACF,CAEA,EAAAloC,CAAS8qC,GACP,MAAM9wC,EAASnD,MAAKoxC,EAAehsC,KAAK6uC,GAKxC,OAHAj0C,MAAKoxC,EAAiBjuC,EAAOoC,MAAOwB,IAClC/G,MAAKqR,EAAK,kCAAmCtK,KAExC5D,CACT,GE1VW+wC,GAAN,MACIv/B,GACA4f,GACA4f,kBAAA,IAAchoC,IAEvB,WAAAxM,CAAYgV,GACV3U,MAAK2U,EAAQA,EACb3U,MAAKu0B,EAAU,IAAK5f,EACtB,CAGA,aAAIwW,GACF,OAAOnrB,MAAKu0B,CACd,CAEA,OAAAjvB,CAAQuS,GACN,OAAO7X,MAAKu0B,EAAQ1c,EACtB,CAEA,QAAA60B,CAASluB,GACP,MAAM3G,EAAY2G,EAAS3b,KACrBuxC,EAAuB,CAAE51B,YACzB61B,EAAQr0C,MAAKm0C,EAAQ9zC,IAAIwX,QACjB,IAAVw8B,EAAqBr0C,MAAKm0C,EAAQ1zC,IAAIoX,EAAW,CAACu8B,IACjDC,EAAM3xC,KAAK0xC,GAChBp0C,MAAKu0B,EAAQ1c,GAAa2G,EAE1B,IAAI+V,GAAS,EACb,MAAO,KACL,IAAKA,EAAQ,OACbA,GAAS,EAET,MAAMjc,EAAUtY,MAAKm0C,EAAQ9zC,IAAIwX,GACjC,QAAgB,IAAZS,EAAuB,OAC3B,MAAM7L,EAAQ6L,EAAQ2M,QAAQmvB,GAC9B,GAAI3nC,EAAQ,EAAG,OACf,MAAM6nC,EAAS7nC,IAAU6L,EAAQ3Z,OAAS,EAG1C,GAFA2Z,EAAQ4M,OAAOzY,EAAO,GACC,IAAnB6L,EAAQ3Z,QAAcqB,MAAKm0C,EAAQzyC,OAAOmW,IACzCy8B,EAAQ,OAEb,MAAMC,EAAgBj8B,EAAQk8B,IAAG,GAC3BC,EAAmBF,GAAe/1B,UAAYxe,MAAK2U,EAAMkD,QACtC,IAArB48B,EAAgCxsC,QAAQC,eAAelI,MAAKu0B,EAAS1c,GACpE7X,MAAKu0B,EAAQ1c,GAAa48B,EAEnC,GCvDIC,GAAsD,CAC1D,EAAG,OACH,EAAG,SACH,EAAG,QACH,EAAG,WAGCC,kBAAmB,IAAI9vC,IAAI,CAAC,OAAQ,SAAU,QAAS,UAAW,QAAS,QAG1E,SAAS+vC,GAAiB3qB,GAC/B,MAAM4qB,EAAM5qB,EAAK/J,OACjB,MAAmB,iBAAR20B,GAAoBF,GAAiB3vC,IAAI6vC,GAAaA,EAC9C,iBAARA,EAAyBH,GAAkBG,QAAtD,CAEF,CAEO,SAASC,GAAc7qB,GAC5B,MAAM8qB,EAAS9qB,EAAK8qB,OACpB,MAAyB,iBAAXA,GAAuBA,EAAS,EAAIA,EAAS,CAC7D,CAEO,SAASC,GAAa/qB,GAC3B,MAAuB,QAAnBA,EAAKgrB,UAA4B,aACd,QAAnBhrB,EAAKgrB,UAA4B,aAC9B,EACT,CAMO,SAASC,GAAqBjrB,GACnC,MAAMkrB,EAAQP,GAAiB3qB,GACzB8qB,EAASD,GAAc7qB,GACvBmrB,EAAoB,GAG1B,YAFc,IAAVD,GAAqBC,EAAQ1yC,KAAK,YAAYyyC,KAC9CJ,EAAS,GAAGK,EAAQ1yC,KAAK,aAAalB,OAAOuzC,MACvB,IAAnBK,EAAQz2C,OAAe,GAAK,WAAWy2C,EAAQj9B,KAAK,OAC7D,CCxCA,ICEMk9B,kBAAa,IAAIxwC,IAAI,CAAC,KAAM,KAAM,KAAM,KAAM,KAAM,OCsBnD,SAASywC,GAAS3yC,GACvB,MAAwB,iBAAVA,GAAgC,OAAVA,EAC/BA,OACD,CACN,CAEO,SAAS4yC,GAAU5yC,GACxB,OAAO2yC,GAAS3yC,EAClB,CAGO,SAAS6yC,GAAc7yC,GAC5B,OAAOA,EAAMiK,QAAQ,kBAAmB,KAAKiT,aAC/C,CAEA,SAAStM,GAAS5Q,GAChB,MAAwB,iBAAVA,GAAsBA,EAAMhE,OAAS,EAAIgE,OAAQ,CACjE,CAGO,SAAS8yC,GAAkB9yC,GAChC,MAAMuqC,EAAQ35B,GAAS5Q,EAAM+yC,QAAUniC,GAAS5Q,EAAME,OAAS0Q,GAAS5Q,EAAMM,MAC9E,YAAc,IAAViqC,EAA4BA,OACZ,IAAbvqC,EAAM3B,QAAmB,EAAYQ,OAAOmB,EAAM3B,GAC3D,CCvCA,IAAM20C,GAAe,6CAEfC,GAA6B,CAAC3rB,EAAM4rB,KACxC,MAAM72B,EAAW62B,EAAIC,eAAe7rB,EAAKjL,UAAY,IAC/Cjc,EAASuyC,GAASrrB,EAAa,QAC/Bja,EAOR,SACEia,EACAlnB,GAEA,GAA6B,aAAzBA,GAAmB,SAAM,OAM/B,SAAqByU,GACnB,MAAM7U,EAAQ2yC,GAASA,GAAS99B,IAAc,OACxCxH,EAAMrN,GAAa,IACzB,GAAmB,iBAARqN,GAAoBA,EAAIrR,OAAS,EAAG,OAAOqR,EACtD,MAAM/M,EAAON,GAAc,KAC3B,MAAuB,iBAATM,GAAqBA,EAAKtE,OAAS,EAAI,IAAIsE,SAAS,CACpE,CAZkD8yC,CAAYhzC,EAAY,KACxE,MAAMiN,EAAMjN,GAAc,KAAKknB,EAAU,IACzC,MAAsB,iBAARja,GAAoBA,EAAIrR,OAAS,EAAIqR,OAAM,CAC3D,CAdcgmC,CAAW/rB,EAAMlnB,GAC7B,QAAY,IAARiN,IAAsBD,UAAUC,GAAM,OAAOgP,EACjD,MAAMi3B,EACqB,iBAAlBhsB,EAAY,MAAiB,WAAWyQ,WAAWzQ,EAAY,UAAQ,GAChF,MAAO,YAAY6Q,oBAAoB9qB,MAsBzC,SACEia,EACAlnB,EACAiN,GAEA,IAA2B,IAAvBjN,GAAiB,QAAcuN,kBAAkBN,GAAM,OAAO2lC,GAClE,MAAMtvC,EAAmC,iBAAnB4jB,EAAa,OAAiBA,EAAa,OAAI,GACrE,MAAe,KAAX5jB,EAAsB,GACX,WAAXA,EAA4BsvC,GACzB,YAAYjb,WAAWr0B,KAChC,CAhCiDsZ,CAAgBsK,EAAMlnB,EAAQiN,KAAOimC,KAAaj3B,SCGnG,SAASk3B,GAAYjsB,GACnB,GAAyB,iBAAdA,EAAK3b,KAAS,OAAiB2b,EAAK3b,KAC/C,IAAK2b,EAAKjL,SAAU,MAAO,GAC3B,IAAI1c,EAAM,GACV,UAAWgtB,KAASrF,EAAKjL,SAAU1c,GAAO4zC,GAAY5mB,GACtD,OAAOhtB,CACT,CCLA,SAAS6zC,GAAoBxzC,GAG3B,MAAO,GAF8B,iBAAhBA,EAAMyzC,MAAqB,WAAW50C,OAAOmB,EAAMyzC,UAAY,KAC7C,iBAAjBzzC,EAAM0zC,OAAsB,YAAY70C,OAAOmB,EAAM0zC,WAAa,IAE1F,CAEA,SAASC,GAAc3zC,GACrB,MAAiC,iBAAnBA,EAAM4zC,SAAwB,UAAUzb,oBAAoBn4B,EAAM4zC,aAAe,EACjG,CC1BA,ICQMC,kBAAA,IAAerqC,IAQd,SAASsqC,GAAoBzpC,GAClC,OAAOwpC,GAASn2C,IAAI2M,EACtB,CCFO,IAAM0pC,GAA4B,yCAEzC,SAASC,GACP1sB,EACA4rB,EACAplB,EACAmmB,GAEA,MAAM7zC,EAASuyC,GAASrrB,EAAa,SAAM,GACrCjd,EAA2C,iBAAxBjK,EAAkB,UAAiBA,EAAkB,UAAI,GAC5EE,EAAOuyC,GAAcxoC,GACrBooC,EAAmB,KAATnyC,EAAc2zC,EAAY,GAAGA,KAAaA,MAAc3zC,IACxE,GAAkB,KAAd+J,EAAkB,CACpB,MAAM6pC,EAASJ,GAAoBzpC,IAAcypC,GAAoBxzC,GACrE,GAAI4zC,EAAA,OAAeA,EAAO9zC,EAAQ,CAAE+yC,eAAgBD,EAAIC,iBAGxDD,EAAIiB,oBAAoB9pC,EAAWooC,EACrC,CACA,MAAO,IAAI3kB,YAAc2kB,QAAc3kB,IACzC,CCpBA,SAASsmB,GAAcl0C,EAAcF,GACnC,MAAwB,iBAAVA,GAAsBA,EAAQ,EAAI,IAAIE,MAASrB,OAAOmB,MAAY,EAClF,CCTO,IAAMq0C,GAAiE,CAC5E1oC,KCVkC2b,IAElC,IAAI3nB,EAAMo4B,WADuB,iBAAdzQ,EAAK3b,KAAoB2b,EAAK3b,KAAO,IAExD,MAAM4R,EAAgC,iBAAhB+J,EAAK/J,OAAsB+J,EAAK/J,OAAS,EAS/D,SCRM,GDADA,KAAiC5d,EAAM,SAASA,eCJ/C,EDKD4d,KAAiC5d,EAAM,WAAWA,iBCJ/C,EDKH4d,KAAmC5d,EAAM,OAAOA,aCH1C,EDIN4d,KAAsC5d,EAAM,MAAMA,YCLxC,EDMV4d,KAA0C5d,EAAM,MAAMA,YCHhD,GDIN4d,KAAsC5d,EAAM,QAAQA,cCH5C,GDIR4d,KAAwC5d,EAAM,QAAQA,cCHhD,IDIN4d,KAAsC5d,EAAM,SAASA,YACnDA,GDDP20C,UVfsC,CAAChtB,EAAM4rB,KAC7C,MAAM72B,EAAW62B,EAAIC,eAAe7rB,EAAKjL,UAAY,IACrD,MAAO,KAAKg2B,GAAa/qB,KAAQirB,GAAqBjrB,MAASjL,SUc/Dk4B,QTZoC,CAACjtB,EAAM4rB,KAC3C,MAAMsB,EAAgC,iBAAhBltB,EAAU,IAAiBA,EAAU,IAAEpK,cAAgB,KACvE4Q,EAAM4kB,GAAWrwC,IAAImyC,GAAUA,EAAS,KACxCn4B,EAAW62B,EAAIC,eAAe7rB,EAAKjL,UAAY,IACrD,MAAO,IAAIyR,IAAMukB,GAAa/qB,KAAQirB,GAAqBjrB,MAASjL,MAAayR,MSSjFuhB,KGdiC,CAAC/nB,EAAM4rB,KACxC,MAAMuB,EAAuC,iBAArBntB,EAAe,SAAiBA,EAAe,SAAI,SACrEwG,EAAmB,WAAb2mB,EAAwB,KAAO,KACrCC,EACS,WAAbD,GAAkD,iBAAlBntB,EAAY,OAAkBA,EAAY,MAAI,EAC1E,WAAWzoB,OAAOyoB,EAAY,UAC9B,GACAqtB,EAAyB,UAAbF,EAAuB,eAAiB,GACpDp4B,EAAW62B,EAAIC,eAAe7rB,EAAKjL,UAAY,IACrD,MAAO,IAAIyR,IAAMukB,GAAa/qB,KAAQirB,GAAqBjrB,KAAQotB,IAAYC,KAAat4B,MAAayR,MHMzG8mB,SGHqC,CAACttB,EAAM4rB,KAC5C,MAAM72B,EAAW62B,EAAIC,eAAe7rB,EAAKjL,UAAY,IACrD,GAA+B,kBAApBiL,EAAc,QAEvB,MAAO,qCADOA,EAAc,QAAI,OAAS,WACYirB,GAAqBjrB,MAASjL,SAErF,MAAMw4B,EACqB,iBAAlBvtB,EAAY,MAAiB,WAAWyQ,WAAWl5B,OAAOyoB,EAAY,WAAS,GACxF,MAAO,MAAM+qB,GAAa/qB,KAAQirB,GAAqBjrB,KAAQutB,KAAax4B,UHJ5Ey4B,KAAM7B,GACN8B,SAAU9B,GACV+B,MIrBkC,CAAC1tB,EAAM4rB,KACzC,MAAM72B,EAAW62B,EAAIC,eAAe7rB,EAAKjL,UAAY,IACrD,MAAO,cAAcg2B,GAAa/qB,KAAQirB,GAAqBjrB,MAASjL,kBJoBxExP,KNlBkCya,IAClC,MAAMnrB,EAAW02C,GAA0C,iBAArBvrB,EAAe,SAAiBA,EAAe,SAAI,IAEzF,MAAO,aADwB,KAAbnrB,EAAkB,GAAK,oBAAoBA,QAC5B47B,WAAWwb,GAAYjsB,oBMgBxD,iBNb2CA,IAC3C,MAAM3b,EAA4B,iBAAd2b,EAAK3b,KAAoB2b,EAAK3b,KAAO,GAKzD,MAAO,QAH4B,iBAA1B2b,EAAoB,cACvB,iBAAiBurB,GAAcvrB,EAAoB,kBACnD,MACsByQ,WAAWpsB,aMQvCspC,UKzBsC,IAAM,OL0B5CC,eKzB2C,IAAM,OL0BjDC,IKzBgC,IAAM,KL0BtCzoC,OLpBoC4a,IACpC,MAAMtnB,EAAQ4yC,GAAUtrB,EAAY,OACpC,QAAc,IAAVtnB,EAAqB,MAAO,GAChC,MAAMqN,EAAMrN,EAAMqN,IAClB,GAAmB,iBAARA,IAAqBD,UAAUC,GAAM,MAAO,GAEvD,MAAM+nC,EAAiC,iBAAnBp1C,EAAM4zC,SAAwB5zC,EAAM4zC,SAAW,GACnE,OAAIwB,EAAK5nC,WAAW,UAuBtB,SAAqBxN,EAAmBqN,GACtC,MAAO,kBAAkBmmC,GAAoBxzC,mBAAuBm4B,oBAAoB9qB,MAAQsmC,GAAc3zC,aAChH,CAzBwCq1C,CAAYr1C,EAAOqN,GACrD+nC,EAAK5nC,WAAW,UA0BtB,SAAqBxN,EAAmBqN,GACtC,MAAO,gCAAgC8qB,oBAAoB9qB,MAAQsmC,GAAc3zC,aACnF,CA5BwCs1C,CAAYt1C,EAAOqN,GAC5C,KAAT+nC,GAAeA,EAAK5nC,WAAW,UAgBrC,SAAqBxN,EAAmBqN,GACtC,MAAM6gB,EAA2B,iBAAdluB,EAAMkuB,IAAmB6J,WAAW/3B,EAAMkuB,KAAO,GACpE,MAAO,aAAaiK,oBAAoB9qB,YAAc6gB,KAAOslB,GAAoBxzC,qCACnF,CAnBuDu1C,CAAYv1C,EAAOqN,GA6B1E,SAA4BrN,EAAmBqN,GAC7C,MAAMk9B,EAAkC,iBAAnBvqC,EAAMw1C,SAAwBzd,WAAW/3B,EAAMw1C,UAAYzd,WAAW1qB,GAC3F,MAAO,YAAY8qB,oBAAoB9qB,iDAAmDk9B,OAC5F,CA/BSkL,CAAmBz1C,EAAOqN,IKWjCZ,aJxB0C6a,IAC1C,MAAMouB,EAA2C,iBAAvBpuB,EAAiB,WAAiBA,EAAiB,WAAI,GAC3EtnB,EAAQ2yC,GAASrrB,EAAY,OAC7BijB,EAAQxS,YAAY/3B,GAAS8yC,GAAkB9yC,KAAW,IAAI01C,KAC9Dp1C,EAAOuyC,GAAc6C,GACrBC,EACK,KAATr1C,EAAc,uBAAyB,oCAAoCA,KACvE+M,EAAMrN,GAAOqN,IACnB,MAAmB,iBAARA,GAAoBD,UAAUC,GAChC,YAAY8qB,oBAAoB9qB,MAAQsoC,KAAapL,QAEvD,QAAQoL,KAAapL,YIc5B3gC,MFakC,CAAC0d,EAAM4rB,IAAQc,GAAgB1sB,EAAM4rB,EAAK,MAAO,YEZnF0C,YFcwC,CAACtuB,EAAM4rB,IAC/Cc,GAAgB1sB,EAAM4rB,EAAK,OAAQ,mBEdnC7d,MDzBkC,CAAC/N,EAAM4rB,IACzC,SAASb,GAAa/qB,aAAgB4rB,EAAIC,eAAe7rB,EAAKjL,UAAY,sBCyB1Ew5B,SDvBqC,CAACvuB,EAAM4rB,IAC5C,OAAOA,EAAIC,eAAe7rB,EAAKjL,UAAY,WCuB3Cy5B,UDrBsC,CAACxuB,EAAM4rB,KAC7C,MAAM6C,EAAwC,iBAAxBzuB,EAAkB,YAAiBA,EAAkB,YAAI,EACzEwG,EAAO,EAAAioB,EAAsD,KAAP,KAG5D,MAAO,IAAIjoB,IAdM,IAafioB,EAAwB,eAZN,IAYuBA,EAA2B,eAAiB,KAC9D3B,GAAc,UAAW9sB,EAAc,WAAK8sB,GAAc,UAAW9sB,EAAc,YAAM4rB,EAAIC,eAAe7rB,EAAKjL,UAAY,QAAQyR,OOE1J+lB,sBAAerqC,ICCjBwsC,IAAoB,EAGjB,SAASC,GAAiBj2C,GAC/B,GAAqB,iBAAVA,GAAgC,OAAVA,EAAgB,OAAO,EACxD,KAAM,SAAUA,GAAQ,OAAO,EAC/B,MAAM0I,EAAO1I,EAAM0I,KACnB,MAAoB,iBAATA,GAA8B,OAATA,GAC1B,aAAcA,GACbjJ,MAAMC,QAAQgJ,EAAK2T,SAC5B,CA4CA,SAAS65B,GAAW5uB,EAAmB3K,GACrC,MAAMd,GDhDe1b,ECgDGmnB,EAAKnnB,KD/CtB0zC,GAASn2C,IAAIyC,IAASk0C,GAAuBl0C,IAD/C,IAAgBA,ECiDrB,OAAI0b,EAAiBA,EAASyL,EAAM3K,QACX,IAAlB2K,EAAKjL,SAAyBM,EAAQw2B,eAAe7rB,EAAKjL,UAAY,EAC/E,CAEA,SAAS85B,GAAiB7uB,GACxB,GAAyB,iBAAdA,EAAK3b,KAAS,OAAiB2b,EAAK3b,KAC/C,GAAkB,cAAd2b,EAAKnnB,KAAsB,MAAO,KACtC,QAAsB,IAAlBmnB,EAAKjL,SAAwB,MAAO,GACxC,IAAI1c,EAAM,GACV,UAAWgtB,KAASrF,EAAKjL,SAAU1c,GAAOw2C,GAAiBxpB,GAC3D,OAAOhtB,CACT,CC1EO,SAASy2C,GAAmBl2C,EAAoB,QACrD,MAAMm2C,iBAAA,IAAqB/mC,QAE3B,MAAO,CACLpP,OACAwd,sBAAwBnO,EAAoB,CAAC7L,EAAQ1D,KACnD,MAAMrC,EAAU+F,EAAO/F,QACjBgO,EAmCZ,SAAuB3L,GACrB,OAAIA,QAA8C,GAC9Ci2C,GAAiBj2C,GDbhBi2C,GAD4B5e,ECcsBr3B,GDZhDq3B,EAAQ3uB,KAAK2T,SAASqC,IAAIy3B,IAAkB3gC,KAAK,MAAMjI,OADvB,GCclB,iBAAVvN,EAA2BA,EACjB,iBAAVA,GAAuC,kBAAVA,EAA4BnB,OAAOmB,GACpEkP,KAAKC,UAAUnP,GDjBjB,IAA4Bq3B,CCkBnC,CAzCmBif,CAAct2C,GAC3B,GAAwB,UAApBrC,EAAQoR,SAA2C,aAApBpR,EAAQoR,QAI3C,OAgBN,SAA4BpR,GAC1B,OAAsD,OAA/CA,EAAQgW,cAAc,oBAC/B,CAlBU4iC,CAAmB54C,KAAaA,EAAQyhB,aAfpB,sBAmC9B,SAAkBi3B,EAAkC14C,EAAkB6Q,GAChE6nC,EAAeh0C,IAAI1E,KACvB04C,EAAe/zC,IAAI3E,GACnBkK,EACE,oDAAoD2G,QAC9C7Q,EAAQoR,QAAQmO,mIAG1B,CA3BQs5B,CAASH,EAAgB14C,EAAS+F,EAAO8K,YAClC,QAEL7C,EAAKoF,SAAS,OAASpF,EAAKoF,SAAS,MACvCpT,EAAQw5B,UAAYhH,GzCYrB,SAA4BxkB,GACjC,OAAOosB,WAAWpsB,GAAM1B,QAAQ,cAAe,OACjD,CyCdwCwsC,CAAmB9qC,IAGrDhO,EAAQqR,YAAcrD,GAXnBhO,EAAmDqC,MAAQ2L,IAepE,CCdA,IAAM+qC,kBAAA,IAAiBx0C,IACjBy0C,kBAAA,IAAiBz0C,IAGjB00C,kBAAoC,IAAI10C,IAAI,CAAC,MAAO,UAAW,YAE/D20C,GAAkC,CACtC32C,KAAM,WACNwd,sBAAwBnO,EAAoB,CAAC7L,EAAQ1D,EAAO2c,KAC1D,MAAMhf,EAAU+F,EAAO/F,QACvB,GAAIo7B,GAAa/4B,GAEf,YADArC,EAAQqR,YAAc,IAGxB,MAAMqhB,EAAS1T,EAAQnB,gBACvB,QAA+B,IAA3BmB,EAAQpB,eAA8B,CACxC,MAAM6U,EAAOzT,EAAQpB,eAAevb,EAAO,CACzCwO,UAAW9K,EAAO8K,UAClB7Q,UACAV,OAAQ0f,EAAQ1f,SAGlB,YADAU,EAAQw5B,UAAYhH,GAAY8F,GAAuB7F,EAAMC,IAE/D,CACA,GAAI4lB,GAAiBj2C,GAAQ,CAE3B,MAAM82C,iBAAA,IAAiBttC,IASjButC,EA+BZ,SACEp5C,EACAyyB,GAEA,MAAMrW,EAAWpc,EAAQ4gC,WAAU,GACnCxkB,EAASod,UAAYhH,GAAYC,GACjC,MAAM1sB,EAmCR,SAAmB/F,EAAkBoc,GACnC,MAAM4S,EAAQhvB,EAAQ8vB,kBACtB,GAAkC,OAA9Bd,GAAOe,oBAA+B3T,EAASsC,SAASrgB,OAAS,EAAG,OAAO,KAC/E,IAAK46C,GAAav0C,IAAIsqB,EAAM5d,UAAY4d,EAAMvN,aAAaI,IAAkB,OAAO,KACpF,UAAW5V,KAASmQ,EAASsC,SAC3B,GAAIzS,EAAMmF,UAAY4d,EAAM5d,SAAWnF,EAAMotC,YAAcrqB,EAAMqqB,UAAW,OAAO,KAErF,OAAOrqB,CACT,CA3CiBsqB,CAAUt5C,EAASoc,IAAapc,EACzCo5C,iBAAA,IAAevtC,IACf0tC,EAAen9B,EAAS6H,iBAAiBmyB,IAC/C,GAAImD,EAAal7C,OAAS,GAAkC,OAA7B0H,EAAO+pB,kBAA4B,CAChE,MAAM0pB,EAAiD,GACvDC,GAAqB1zC,EAAQqW,EAAUo9B,GACvC,UAAY1e,EAAavO,KAASitB,EAChC1e,EAAYlF,YAAYrJ,GACnBA,EAAKrT,QAAQk9B,KAA4BgD,EAASj5C,IAAI26B,EAAYue,WAAW,GAGpF,UAAWve,KAAeye,EACO,OAA3Bze,EAAYx5B,YAAe83C,EAAej5C,IAAI26B,EAAYue,WAAW,EAE7E,CAEA,OADAtzC,EAAO2zC,mBAAmBt9B,EAASgZ,YAC5BgkB,CACT,CAtDuBO,CACf35C,EACAs4B,GF3BD,SAAuBoB,EAAsB/uB,EAAgC,IAClF,IAAK2tC,GAAiB5e,GAAU,MAAO,GACvC,MAAMjH,EAuBR,SACE+jB,GAEA,MAAMx3B,EAA6B,CACjCw2B,eAAiB92B,IACf,IAAI1c,EAAM,GACV,UAAWgtB,KAAStQ,EAAU1c,GAAOu2C,GAAWvpB,EAAOhQ,GACvD,OAAOhd,GAETsyC,oBACAE,iBACAgC,qBAEF,OAAOx3B,CACT,CArCei0B,CAActoC,EAAQ6rC,mBAAmBhB,eAAe9b,EAAQ3uB,KAAK2T,UAClF,OAAyB,IAArB/T,EAAQivC,SAA2BnnB,OzCmTV,IAAtB8F,KyClT4BF,aAAa5F,IAsDlD,WACE,IAAI4lB,GAAJ,CACAA,IAAoB,EACpB,IACEpuC,QAAQE,KACN,0MAGJ,OAEA,CATuB,CAUzB,CAhEE0vC,GACOpnB,EACT,CEUsBqnB,CAAcz3C,EAAO,CAGnCu3C,UAAU,EACVpD,kBAAmB,CAAC9pC,EAAWqtC,KAC7BZ,EAAWh5C,IAAI45C,EAAkBrtC,MAKHgmB,IAElC,UAAYqnB,EAAkBC,KAASZ,EAAU,CAC/C,MAAM1sC,EAAYysC,EAAWp5C,IAAIg6C,QACf,IAAdrtC,GAAyButC,GAAsBl0C,EAAQiZ,EAAStS,EAAWstC,EACjF,CACA,MACF,CACA,GAAqB,iBAAV33C,EAIX,OAAO,EAHLrC,EAAQw5B,UAAYhH,GAAY8F,GAAuBj2B,EAAOqwB,OA8EpE,SAAS+mB,GACPltB,EACAnQ,EACAsZ,GAEA,GAAInJ,EAAK7N,SAASrgB,SAAW+d,EAASsC,SAASrgB,OAAQ,OACvD,IAAI67C,EAAY3tB,EAAKuD,kBACjBqqB,EAAgB/9B,EAAS0T,kBAE7B,KAAqB,OAAdoqB,GAAwC,OAAlBC,GACvBA,EAAcjhC,QAAQk9B,IAAyB1gB,EAAQtzB,KAAK,CAAC+3C,EAAeD,IAC3ET,GAAqBS,EAAWC,EAAezkB,GACpDwkB,EAAYA,EAAUnqB,mBACtBoqB,EAAgBA,EAAcpqB,kBAElC,CAQA,SAASkqB,GACPl0C,EACAiZ,EACAtS,EACAstC,GAEIA,GACFh7B,EAAQlB,mBAAmB/X,EAAQ,8CAA8C2G,MAEnF,MAAMylB,EAAS6nB,EAAOhB,GAAaD,GAC/B5mB,EAAOztB,IAAIgI,KACfylB,EAAOxtB,IAAI+H,GACXxC,EACE,kBACE8vC,EACI,kCAAkCttC,yDAClC,kCAAkCA,6FAG5C,CCzLA,IAAM0tC,GAA8B,CAClC73C,KAAM,OACN,MAAAwd,CAAOha,EAAQ1D,EAAO2c,GACpB,GAAIoc,GAAa/4B,GAEf,YADA0D,EAAO/F,QAAQqR,YAAc,IAG/B,MAAMohB,EAAwB,iBAAVpwB,EAAqBA,EAAQ84B,GAAc94B,GAC/D0D,EAAO/F,QAAQw5B,UAAYhH,GAAY8F,GAAuB7F,EAAMzT,EAAQnB,iBAC9E,GCVIsU,kBAAA,IAAaxgB,QAQZ,SAAS0oC,GAAUr6C,EAAkB6Q,EAAmBggB,GAC7D,MAAyB,iBAAdA,GAA+C,IAArBA,EAAUxyB,OAAqB,CAAE8O,KAAM,QACxEsC,UAAUohB,GAAmB,CAAE1jB,KAAM,OAAQuC,IAAKmhB,IACjDsB,GAAOztB,IAAI1E,KACdmyB,GAAOxtB,IAAI3E,GACXkK,EACE,qDAAqD2G,UAC/C7Q,EAAQoR,QAAQmO,+CAGnB,CAAEpS,KAAM,UACjB,CCbO,SAASmtC,GACd/3C,EACAg4C,EAAqCl4C,GAAUA,GAE/C,MAAO,CACLE,OACA,MAAAwd,CAAOha,EAAQ1D,EAAO2c,GACpB,MAAMhf,EAAU+F,EAAO/F,QACvB,GAAIo7B,GAAa/4B,GAEf,YA2BR,SAAerC,GACW,UAApBA,EAAQoR,SAA2C,aAApBpR,EAAQoR,SAI3CpR,EAAQwf,gBAAgB,QACxBxf,EAAQqR,YAAc,IAJnBrR,EAAmDqC,MAAQ,EAKhE,CAnCQ0hB,CAAM/jB,GAGR,MAAMgO,EAAOmtB,GAAc94B,GAC3B,GAAwB,UAApBrC,EAAQoR,SAA2C,aAApBpR,EAAQoR,QAA3C,CAIA,GAAwB,MAApBpR,EAAQoR,QAAiB,CAC3B,MAAMuE,EAAY5P,EAAO4P,UACnBkb,OACU,IAAdlb,GAAgD,IAArBA,EAAUtX,OACjCk8C,EAAOvsC,GACPojB,GACEpS,EAAQC,UACRtJ,EACAqJ,EAAQ1f,YACU,IAAlByG,EAAOzG,QAETwgB,EAAUu6B,GAAUr6C,EAAS+F,EAAO8K,UAAWggB,GAChC,SAAjB/Q,EAAQ3S,KAASnN,EAAgBW,aAAa,OAAQmf,EAAQpQ,KACxC,WAAjBoQ,EAAQ3S,MAAmBnN,EAAQwf,gBAAgB,OAC9D,CACAxf,EAAQqR,YAAcrD,CAhBtB,MAFGhO,EAAmDqC,MAAQ2L,CAmBhE,EAEJ,CAWO,IAAMwsC,GAA6BF,GAAmB,OCrDvDG,GAAa,4BAQNC,GAA+BJ,GAAmB,QAN/D,SAAoBj4C,GAClB,MAAMsN,EAAUtN,EAAMuN,OACtB,OAAI6qC,GAAW96C,KAAKgQ,KAAaA,EAAQyD,SAAS,KAAazD,EACxD,UAAUA,GACnB,GCNMgrC,GAA0B,CAAC,MAAO,SAAU,SAE3C,SAASC,GAAW1jB,GACzB,UAAW30B,KAAQo4C,GAAyBzjB,EAAI1X,gBAAgBjd,EAClE,CAMO,SAASs4C,GACd3jB,EACAxnB,EACAof,GAEAoI,EAAInY,IAAMrP,EACV,MAAMorC,EASR,SAAqBhsB,GACnB,QAAqB,IAAjBA,GAAOisB,MAAqB,OAChC,MAAMnqB,EAAuB,GAC7B,UAAWxM,KAAQjhB,OAAOqS,OAAOsZ,EAAMisB,OACb,iBAAb32B,EAAK1U,KAA0C,iBAAf0U,EAAK0xB,OAAuBrmC,UAAU2U,EAAK1U,MAGtFkhB,EAAWxuB,KAAK,GAAG44C,GAAU52B,EAAK1U,QAAQxO,OAAOkjB,EAAK0xB,WAExD,OAA0B,IAAtBllB,EAAWvyB,QACY,iBAAhBywB,EAAMgnB,OAA2C,iBAAdhnB,EAAMpf,KAAoBD,UAAUqf,EAAMpf,MACtFkhB,EAAWxuB,KAAK,GAAG44C,GAAUlsB,EAAMpf,QAAQxO,OAAO4tB,EAAMgnB,WAEnDllB,EAAW/Y,KAAK,YAJvB,CAKF,CAvBiBojC,CAAYnsB,GAC3B,QAAe,IAAXgsB,EAGF,OAFA5jB,EAAI1X,gBAAgB,eACpB0X,EAAI1X,gBAAgB,SAGtB0X,EAAIv2B,aAAa,SAAUm6C,EAC7B,CAmBA,SAASE,GAAUtrC,GACjB,OAAOA,EAAIpD,QAAQ,SAAUoa,mBAC/B,CClCA,IAAMw0B,GAA+B,CACnC34C,KAAM,QACNwd,sBAAwBnO,EAAoB,CAAC7L,EAAQ1D,EAAO2c,KAC1D,MAAMhf,EAAU+F,EAAO/F,QACvB,GAAIo7B,GAAa/4B,GAEf,YADA0hB,GAAM/jB,GAGR,MAAMqxB,OAAiC,IAAlBtrB,EAAOzG,QACtBwvB,MAAEA,EAAA+B,UAAOA,GAwBnB,SACE9qB,EACA1D,EACA2c,EACAqS,GAEA,MAAM9nB,OACgB,IAApBxD,EAAO6P,UAA0B7P,EAAO6P,SAASvX,OAAS,EACtD+yB,GAAkBpS,EAAQC,UAAWlZ,EAAO6P,SAAUoJ,EAAQ1f,OAAQ+xB,GACtEhvB,EACAysB,EAAQmmB,GAAU1rC,GACxB,MAAO,CAAEulB,QAAO+B,eAAqB,IAAV/B,EAAsBvlB,EAASulB,EAAMpf,IAClE,CApCiCyrC,CAAWp1C,EAAQ1D,EAAO2c,EAASqS,GAC1DvR,EAAUu6B,GAAUr6C,EAAS+F,EAAO8K,UAAWggB,GACrD,GAAqB,SAAjB/Q,EAAQ3S,KAAiB,OAAO,EACpC,GAAqB,WAAjB2S,EAAQ3S,KAAZ,CAIA,GAAwB,QAApBnN,EAAQoR,QAAmB,CAC7B,MAAM8lB,EAAMl3B,EACZ66C,GAAW3jB,EAAKpX,EAAQpQ,IAAKof,GAC7B,MAAMyB,EA4BZ,SACEzB,EACAjZ,EACAoJ,EACA3f,EACA+xB,GAEA,QAAiB,IAAbxb,GAA0BA,EAASxX,OAAS,EAAG,CACjD,MAAM4zB,EAAUb,GAAkBnS,EAAWpJ,EAAUvW,EAAQ+xB,GAC/D,MAA0B,iBAAZY,EAAuBA,OAAU,CACjD,CACA,OAAOnD,GAAOyB,GAChB,CAxCkB6qB,CAAQtsB,EAAO/oB,EAAO8P,SAAUmJ,EAAQC,UAAWD,EAAQ1f,OAAQ+xB,GAE/E,iBADY,IAARd,IAAmB2G,EAAI3G,IAAMA,GAEnC,CACCvwB,EAAwBq7C,MAAMC,gBAAkB,QhDf9C,SAAsBj5C,GAC3B,OAAOA,EAAMiK,QAAQ,YAAa,OACpC,CgDa6DivC,CAAaz7B,EAAQpQ,QAR9E,MAFEqU,GAAM/jB,MAeZ,SAAS+jB,GAAM/jB,GACW,QAApBA,EAAQoR,QAAmBwpC,GAAW56C,GACpCA,EAAwBq7C,MAAMC,gBAAkB,EACxD,CCnCA,IAAME,GAAgC,CACpCj5C,KAAM,SACNwd,sBAAwBnO,EAAoB,CAAC7L,EAAQ1D,KACnD,MAAMrC,EAAU+F,EAAO/F,QACvB,GAAIo7B,GAAa/4B,GAEf,YADA0hB,GAAM/jB,GAGR,MAAM8uB,EAAQmmB,GAAU5yC,GACxB,QAAc,IAAVysB,EAAqB,OAAO,EAChC,MAAMhP,EAAUu6B,GAAUr6C,EAAS+F,EAAO8K,UAAWie,EAAMpf,KAC3D,GAAqB,SAAjBoQ,EAAQ3S,KAAiB,OAAO,EACpC,GAAqB,WAAjB2S,EAAQ3S,KAEV,YADA4W,GAAM/jB,GAGR,MAAM0P,EAAMoQ,EAAQpQ,IACpB,GAAwB,QAApB1P,EAAQoR,QAAmB,CAC7B,MAAM8lB,EAAMl3B,EAGZ,OAFA66C,GAAW3jB,EAAKxnB,EAAKof,aACH,IAAdA,EAAMyB,MAAmB2G,EAAI3G,IAAMzB,EAAMyB,KAE/C,CACA,GAAwB,MAApBvwB,EAAQoR,QAGV,OAFApR,EAAQW,aAAa,OAAQ+O,QAC7B1P,EAAQqR,YAAcyd,EAAM+oB,UAAYnoC,GAG1C,MAAMk9B,EAAQxS,WAAWtL,EAAM+oB,UAAYnoC,GAC3C1P,EAAQw5B,UAAYhH,GAAY,YAAYgI,oBAAoB9qB,OAASk9B,YAK7E,SAAS7oB,GAAM/jB,GACW,QAApBA,EAAQoR,SAIZpR,EAAQwf,gBAAgB,QACxBxf,EAAQqR,YAAc,IAJpBupC,GAAW56C,EAKf,CC7CA,IAAMy7C,GAAsC,CAC1Cl5C,KAAM,eACN,MAAAwd,CAAOha,EAAQ1D,GACb,MAAMrC,EAAU+F,EAAO/F,QACvB,GAAIo7B,GAAa/4B,GAGf,OAFArC,EAAQwf,gBAAgB,aACxBxf,EAAQqR,YAAc,IAGxB,GAAwB,MAApBrR,EAAQoR,UAAoBtP,MAAMC,QAAQM,GAAQ,CACpD,MAAMyd,EAAUu6B,GAAUr6C,EAAS+F,EAAO8K,UAAWmkC,GAAS3yC,IAAc,KACvD,SAAjByd,EAAQ3S,KAASnN,EAAgBW,aAAa,OAAQmf,EAAQpQ,KACxC,WAAjBoQ,EAAQ3S,MAAmBnN,EAAQwf,gBAAgB,OAC9D,CACAxf,EAAQqR,YAAcvP,MAAMC,QAAQM,GAASA,EAAM0e,IAAI6rB,IAAO/0B,KAAK,MAAQ+0B,GAAMvqC,EACnF,GAGF,SAASuqC,GAAMvqC,GACb,MAAMC,EAAS0yC,GAAS3yC,GACxB,YAAe,IAAXC,EAA6B64B,GAAc94B,GACxC8yC,GAAkB7yC,IAAW,EACtC,CCnBA,IAAMo5C,GAAgC,CACpCn5C,KAAM,SACN,MAAAwd,CAAOha,EAAQ1D,EAAO2c,GACpB,MAAMhf,EAAU+F,EAAO/F,QACjBwV,EAAS4lB,GAAa/4B,GAAS,GAczC,SAAkBA,GAChB,OAAIP,MAAMC,QAAQM,GAAeA,EAAM0e,IAAIoa,IACpC,CAACA,GAAc94B,GACxB,CAjB8Cs5C,CAASt5C,GACnD,GAAwB,WAApBrC,EAAQoR,QAAZ,CAIA,GAAwB,UAApBpR,EAAQoR,SAA8D,UAAtCpR,EAA6BwC,KAAkB,CACjF,MAAMgM,EAAQxO,EAEd,YADAwO,EAAMotC,QAAUpmC,EAAOpC,SAAS5E,EAAMnM,OAExC,CACArC,EAAQqR,YAAcmE,EAAOuL,IAAKvU,GAoBtC,SAAkBnK,EAAe2c,GAC/B,MAAMrU,EAAUqU,EAAQjT,QAAkB,QAC1C,IAAKjK,MAAMC,QAAQ4I,GAAU,OAAOtI,EACpC,UAAWw5C,KAAUlxC,EAAS,CAC5B,MAAMrI,EAAS0yC,GAAS6G,GACxB,QAAe,IAAXv5C,GAAwB64B,GAAc74B,EAAc,SAAOD,EAC/D,MAAkC,iBAApBC,EAAc,MAAiBA,EAAc,MAAID,CACjE,CACA,OAAOA,CACT,CA7B+Cy5C,CAAStvC,EAAMwS,IAAUnH,KAAK,KANzE,MAgBJ,SAAqBtJ,EAA2BiH,GAC9C,GAAIjH,EAAOwtC,SACT,UAAWF,KAAU/5C,MAAMsL,KAAKmB,EAAO5D,SACrCkxC,EAAOG,SAAWxmC,EAAOpC,SAASyoC,EAAOx5C,YAI7CkM,EAAOlM,MAAQmT,EAAO,IAAM,EAC9B,CA1BMymC,CAAYj8C,EAA8BwV,EAS9C,GCrBI0mC,kBAAA,IAAoB33C,IAAI,CAAC,GAAI,QAAS,IAAK,MAAO,OAElD43C,GAAkC,CACtC55C,KAAM,WACN,MAAAwd,CAAOha,EAAQ1D,GACb,MAAMrC,EAAU+F,EAAO/F,QACjB47C,EAcV,SAAmBv5C,GACjB,MAAqB,kBAAVA,EAA4BA,EAClB,iBAAVA,GAA4B65C,GAAcx3C,IAAIrC,EAAMuN,OAAO2P,eACjD,iBAAVld,EAAqC,IAAVA,EAC/BA,OACT,CAnBoB+5C,CAAU/5C,GACF,UAApBrC,EAAQoR,SAA8D,aAAtCpR,EAA6BwC,KAI7DxC,EAAQyhB,aAAa,gBACvBzhB,EAAQW,aAAa,eAAgBi7C,EAAU,OAAS,SAG1D57C,EAAQqR,YAAcuqC,EAAU,OAAS,QAPtC57C,EAA6B47C,QAAUA,CAQ5C,GCVIS,kBAAA,IAAmBxwC,IACnBywC,kBAAA,IAAiBzwC,IAkDvB,SAAS0wC,GAASj9C,EAA4BqL,GAG5C,MAAM6xC,EAAal9C,GAAU,GAC7B,GAAIqL,QAA2C,OAAO6xC,EACtD,MAAMC,EAAaC,GAAgB/xC,GACnC,MAAmB,OAAf8xC,EAA4BD,EACzB,GAAGA,KAAcC,GAC1B,CAEA,SAASC,GAAgBr6C,GACvB,GAAc,OAAVA,GAAmC,iBAAVA,EAAoB,OAAOkP,KAAKC,UAAUnP,GACvE,GAAIP,MAAMC,QAAQM,GAChB,MAAO,IAAIA,EAAM0e,IAAK1Z,GAAMq1C,GAAgBr1C,IAAIwQ,KAAK,QAEvD,MAAMvV,EAASD,EACTsB,EAAOR,OAAOQ,KAAKrB,GAAQyoC,OAC3B4R,EAAkB,GACxB,UAAWpxC,KAAO5H,EAAM,CACtB,MAAMi5C,EAAQt6C,EAAOiJ,QACP,IAAVqxC,GACJD,EAAMv6C,KAAK,GAAGmP,KAAKC,UAAUjG,MAAQmxC,GAAgBE,KACvD,CACA,MAAO,IAAID,EAAM9kC,KAAK,OACxB,CC/DA,IAAMglC,kBAAA,IAAkBt4C,IAAI,CAAC,QAAS,SAAU,OAAQ,SAClDu4C,kBAAA,IAAkBv4C,IAAI,CAAC,QAAS,SAAU,OAAQ,SAGlDw4C,GAAgB,iBAChBC,GAAkB,WAiDxB,SAASC,GAAWtyC,GAClB,MAAO,CAAEwC,KAAM,OAAQxC,UACzB,CAEA,SAASuyC,GAAavyC,GACpB,MAAO,CAAEwC,KAAM,SAAUxC,UAC3B,CAEA,IAAMwnB,sBAAaxgB,QAkBZ,SAASwrC,GACdhwC,EACAiwC,EACAp9C,EACA6Q,GAEA,QAAa,IAATusC,GAA+B,KAATA,EAAa,OACvC,MAAMl7C,EA5ED,SAA0Bk7C,GAC/B,MAAMC,EAAYD,EAAKz4B,QAAQ,KACzBpiB,GAAqB,IAAd86C,EAAmBD,EAAOA,EAAK3rC,MAAM,EAAG4rC,GAC/CC,GAAyB,IAAdD,OAAmB,EAAYD,EAAK3rC,MAAM4rC,EAAY,GAEvE,OAAQ96C,GACN,IAAK,OACH,YAAiB,IAAb+6C,EAA+BL,GAAW,CAAEM,UAAW,WACpDV,GAAYn4C,IAAI44C,GACnBL,GAAW,CAAEM,UAAWD,SACxB,EACN,IAAK,OACH,YAAiB,IAAbA,EAA+BL,GAAW,CAAEO,UAAW,UACpDV,GAAYp4C,IAAI44C,GACnBL,GAAW,CAAEO,UAAWF,SACxB,EACN,IAAK,WAGH,YAAiB,IAAbA,EAA+BL,GAAW,CAAEM,UAAW,SAAUC,UAAW,UACzEX,GAAYn4C,IAAI44C,GACnBL,GAAW,CACTM,UAAWD,EACXE,UAAwB,UAAbF,EAAuB,QAAU,gBAE9C,EACN,IAAK,SACH,QAAiB,IAAbA,EAAwB,OAAOJ,GAAa,IAChD,IAAKF,GAAgBr9C,KAAK29C,GAAW,OACrC,OAAOJ,GAAa,CAClBO,sBAAuB15C,OAAOu5C,GAC9BI,sBAAuB35C,OAAOu5C,KAElC,IAAK,WACH,QAAiB,IAAbA,IAA2BP,GAAcp9C,KAAK29C,GAAW,OAC7D,OAAOJ,GAAa,CAAE7B,MAAO,WAAYsC,SAAUL,EAASM,gBAC9D,IAAK,UACH,YAAoB,IAAbN,EAAyBJ,GAAa,CAAE7B,MAAO,iBAAe,EACvE,QACE,OAEN,CAmCiBwC,CAAiBT,GAChC,QAAe,IAAXl7C,GAIJ,GAAIA,EAAOiL,OAASA,EACpB,OAAOjL,EAAOyI,aA5BT,SAA2B3K,EAAkB6Q,EAAmBusC,GACjEjrB,GAAOztB,IAAI1E,KACfmyB,GAAOxtB,IAAI3E,GACXkK,EACE,+CAA+CkzC,UAAavsC,mKAIhE,CAgBIitC,CAAkB99C,EAAS6Q,EAAWusC,EAK1C,CCxGA,IAAMW,GAA8B,CAClCx7C,KAAM,OACN,MAAAwd,CAAOha,EAAQ1D,EAAO2c,GACpB,MAAMhf,EAAU+F,EAAO/F,QACvB,GAAIo7B,GAAa/4B,GAMf,YALwB,UAApBrC,EAAQoR,QAAsBpR,EAA6BqC,MAAQ,IAErErC,EAAQwf,gBAAgB,YACxBxf,EAAQqR,YAAc,KAI1B,MAAMxP,EAAuB,iBAAVQ,EAAqBA,EAAQ84B,GAAc94B,GACxDiM,EAAO,IAAIoI,KAAK7U,GAChBm8C,GAASj6C,OAAOk6C,MAAM3vC,EAAK4vC,WAC3BC,EAAWj9C,OAAOW,GACA,UAApB7B,EAAQoR,SAMY,SAApBpR,EAAQoR,SACVpR,EAAQW,aAAa,WAAYq9C,EAAQ1vC,EAAK8vC,cAAgBD,GAEhEn+C,EAAQqR,YAAc2sC,EAS1B,SAAoB1vC,EAAYvI,EAAuBiZ,GACrD,MAAM1f,EAASyG,EAAOzG,QAAU0f,EAAQ1f,QAAUtB,sBAC5C2M,EACJwyC,GAAiB,OAAQp3C,EAAO6Z,OAAQ7Z,EAAO/F,QAAS+F,EAAO8K,YAC/DwtC,GACF,IACE,OFFG,SACL/+C,EACAqL,GAEA,MAAMY,EAAMgxC,GAASj9C,EAAQqL,GAC7B,OACE0wB,GAAOihB,GAAY/wC,IACnB+vB,GAAOghB,GAAY/wC,EAAK,IAAI+yC,KAAKC,eAAej/C,EAAQqL,GA5ChC,GA8C5B,CEPW6zC,CAAkBl/C,EAAQqL,GAASiV,OAAOtR,EACnD,OACE,OAAOA,EAAK8vC,aACd,CACF,CAnBkCK,CAAWnwC,EAAMvI,EAAQiZ,GAAWm/B,GAR/Dn+C,EAA6BqC,MAAQ27C,EA8BrC,SAAwBx7C,EAAc8L,GAC3C,MAAMowC,EAAM,GAAGx9C,OAAOoN,EAAKqwC,eAAeC,SAAS,EAAG,QAAQC,GAAIvwC,EAAKwwC,WAAa,MAAMD,GAAIvwC,EAAKywC,aAC7FC,EAAQ,GAAGH,GAAIvwC,EAAK2wC,eAAeJ,GAAIvwC,EAAK4wC,gBAClD,MAAa,SAAT18C,EAAwBk8C,EACf,mBAATl8C,EAAkC,GAAGk8C,KAAOM,IACnC,SAATx8C,EAAwBw8C,EACrB1wC,EAAK8vC,aACd,CApCUe,CAAgBn/C,EAA6BwC,KAAM8L,GACnD6vC,CAOR,GAGIE,GAAmD,CACvDd,UAAW,SACXC,UAAW,SAyBb,SAASqB,GAAIx8C,GACX,OAAOnB,OAAOmB,GAAOu8C,SAAS,EAAG,IACnC,CC9DA,IAAMQ,GAAgC,CACpC78C,KAAM,SACN,MAAAwd,CAAOha,EAAQ1D,EAAO2c,GACpB,MAAMhf,EAAU+F,EAAO/F,QACvB,GAAIo7B,GAAa/4B,GAGf,YAFwB,UAApBrC,EAAQoR,QAAsBpR,EAA6BqC,MAAQ,GAAArC,EAC1DqR,YAAc,IAG7B,MAAMguC,EAAuB,iBAAVh9C,EAAqBA,EAAQ0B,OAAOo3B,GAAc94B,IACjE0B,OAAOk6C,MAAMoB,GACfr/C,EAAQqR,YAAc8pB,GAAc94B,GAGd,UAApBrC,EAAQoR,QAIZpR,EAAQqR,YAIZ,SAAgBguC,EAAat5C,EAAuBiZ,GAClD,MAAM1f,EAASyG,EAAOzG,QAAU0f,EAAQ1f,QAAUtB,sBAC5C2M,EAAUwyC,GAAiB,SAAUp3C,EAAO6Z,OAAQ7Z,EAAO/F,QAAS+F,EAAO8K,WACjF,IACE,OHKG,SACLvR,EACAqL,GAEA,MAAMY,EAAMgxC,GAASj9C,EAAQqL,GAC7B,OACE0wB,GAAOghB,GAAc9wC,IACrB+vB,GAAO+gB,GAAc9wC,EAAK,IAAI+yC,KAAKgB,aAAahgD,EAAQqL,GAjChC,GAmC5B,CGdW40C,CAAgBjgD,EAAQqL,GAASiV,OAAOy/B,EACjD,OAEE,OAAOn+C,OAAOm+C,EAChB,CACF,CAb0Bz/B,CAAOy/B,EAAKt5C,EAAQiZ,GAHvChf,EAA6BqC,MAAQnB,OAAOm+C,EAIjD,GCRIG,GAA+B,CACnCj9C,KAAM,QACNwd,sBAAwBnO,EAAoB,CAAC7L,EAAQ1D,EAAO2c,KAC1D,MAAMhf,EAAU+F,EAAO/F,QACvB,GAAIo7B,GAAa/4B,GAEf,YADArC,EAAQqR,YAAc,IAGxB,IAAKvP,MAAMC,QAAQM,GAAQ,OAAO,EAClC,MAAMk3B,EAAWxzB,EAAO8e,cACxB,QAAiB,IAAb0U,GAA0BA,EAASl7B,OAAS,EAAG,CACjD,MAAMo0B,EAeZ,SAAwB8G,EAAkBoB,GACxC,MAAME,EAAYH,GAAoBC,GACtC,IAAI34B,EAAM,GACV,QAASgL,EAAI,EAAGA,EAAI2tB,EAAMt8B,OAAQ2O,GAAK,EACrChL,GAAO44B,GAAyBrB,EAAUoB,EAAM3tB,GAAIA,EAAGmuB,GAAeN,GAExE,OAAO74B,CACT,CAtBmBy9C,CAAelmB,EAAUl3B,GAChCqwB,EAAS1T,EAAQnB,gBACjB6hC,EAAkB5jB,GAAwBvC,GAG1CvG,EAASgI,GAAqBh7B,GACpCA,EAAQw5B,UAAYhH,GAAY8F,GAAuB7F,EAAMC,EAAQgtB,IACrE,UAAWlzC,KAAQ1K,MAAMsL,KAAKpN,EAAQ0e,UAAWwc,GAAsB1uB,EAAMwmB,GAC7E,MACF,CACAhzB,EAAQqR,YAAchP,EAAM0e,IAAIoa,IAAetjB,KAAK9R,EAAO+e,gBAAkB,SCb1E,SAAS66B,KACd,MAAMC,iBAAA,IAAahhD,QACbihD,iBAAA,IAAuBluC,QACvBmuC,iBAAA,IAA8BlhD,QAC9B89B,iBrDCN,IAAW99B,QqDCX,MAAO,CACL2D,KAAM,mBACNwd,sBAAwBnO,EAAoB,CAAC7L,EAAQg6C,EAAU/gC,KAC7D,MAAM3c,EAAQ+4B,GAAa2kB,GAAY,GAAKA,EAC5C,IAAKj+C,MAAMC,QAAQM,GAAQ,OAAO,EAClC,MAAMgpB,EAAYtlB,EAAO/F,QACnBu5B,EAAWxzB,EAAO8e,cACxB,QAAiB,IAAb0U,GAA8C,IAApBA,EAASl7B,OAErC,OAgER,SACEwhD,EACAx0B,EACAxa,GAEIgvC,EAAiBn7C,IAAI2mB,KACzBw0B,EAAiBl7C,IAAI0mB,GACrBnhB,EACE,0DAA0D2G,QACpDwa,EAAUja,QAAQmO,gHAG5B,CA7EQygC,CAAoBH,EAAkBx0B,EAAWtlB,EAAO8K,YACjD,EAET,MAAMovC,EAAgBL,EAAO7/C,IAAIsrB,GAC3B60B,EAAcC,GAAmB90B,GAEjCve,EAAUH,EADCszC,GAAezqC,QAAgC0qC,EA+CpDn/B,IAAI,CAACxV,EAAK60C,IAChB,OAAR70C,EAAe,CAAE80C,qBAAsBD,GAAa,CAAE1/C,GAAI6K,IA/CpBlJ,GAC9B8T,EA6BZ,SACEnE,EACAunB,EACA2mB,GAEA,YAAiB,IAAbluC,GACGA,EAASunB,WAAaA,IAe/B,SACEvnB,EACAgG,GAEA,OAAIhG,EAAS3T,SAAW2Z,EAAQ3Z,QACzB2T,EAASnF,MAAM,CAACtB,EAAKY,IAAUZ,IAAQyM,EAAQ7L,GACxD,CArB4Cm0C,CAAmBtuC,EAASkuC,YAAaA,EACrF,CApC0BK,CAAkBN,EAAe1mB,EAAU2mB,GAC/D,GAAuB,IAAnBpzC,EAAQzO,SAAiB8X,EAE3B,OADAypC,EAAOz/C,IAAIkrB,EAAW,CAAE7V,OAAQnT,EAAMoP,QAAS8nB,WAAU2mB,iBAClD,GA4Ef,SACE/tB,EACA9G,EACAxa,EACAmB,EACApJ,GAEA,MAAM43C,EAAW53C,EAAKmY,IAAI0/B,IACpBn8C,iBAAA,IAAWC,IACXwwB,EAAYyrB,EAAStQ,KAAM3kC,UACnB,IAARA,IACAjH,EAAKI,IAAI6G,KACbjH,EAAKK,IAAI4G,GACF,KAYT,QAVkB,IAAdwpB,GAAyB2rB,GAAiBvuB,EAAQ9G,EAAWxa,EAAWkkB,GACxEyrB,EAAS7sC,KAAMpI,QAAgB,IAARA,IACzBstC,GACE1mB,EACA9G,EACA,SACA,uBAAuBxa,2GAIvBmB,GAAU3T,SAAWuK,EAAKvK,QAAUuK,EAAKvK,OAAS,EAAG,CACvD,MAAMsiD,EAAe,IAAIp8C,IAAIyN,EAAS+O,IAAI0/B,IAAS7oC,OAAQrM,QAAgB,IAARA,IAC7Dq1C,EAASJ,EAAS7sC,KAAMpI,QAAgB,IAARA,GAAqBo1C,EAAaj8C,IAAI6G,IACxEo1C,EAAav8B,KAAO,IAAMw8B,GAC5B/H,GACE1mB,EACA9G,EACA,SACA,yBAAyBxa,uGAI/B,CACF,CAhHMgwC,CAAcf,EAAYz0B,EAAWtlB,EAAO8K,UAAWovC,GAAezqC,OAAQnT,GAC9E,MAAMoe,EAAU6b,GAAuB,CACrC/C,WACAlO,YACAve,UACAiwB,UAAW16B,EACXq6B,QACAvmB,cACA0H,gBAAiBmB,EAAQnB,gBACzBmX,eAAgB,CAAC7hB,EAAO5H,KACtBm1C,GAAiBZ,EAAY3sC,EAAOpN,EAAO8K,UAAWtF,MAG1D,OAAgB,OAAZkV,IACJm/B,EAAOz/C,IAAIkrB,EAAW,CACpB7V,OAAQnT,EAAMoP,QACd8nB,WACA2mB,YAAaC,GAAmB90B,OAE3B5K,QAAU,KAGvB,CAaA,SAAS0/B,GAAmB90B,GAC1B,OAAOvpB,MAAMsL,KAAKie,EAAU3M,SAAWsQ,GAAUA,EAAM5wB,aAAa+9B,IACtE,CA8BA,SAASskB,GAAQp+C,GACf,GAAqB,iBAAVA,GAAgC,OAAVA,EAAgB,OACjD,MAAM3B,EAAM2B,EAAsC,GAClD,MAAqB,iBAAP3B,GAAiC,iBAAPA,EAAkBQ,OAAOR,QAAM,CACzE,CA4CA,SAASggD,GACPvuB,EACAhf,EACAtC,EACAtF,GAEAstC,GACE1mB,EACAhf,EACA,SACA,yBAAyBtC,qBAA6BtF,gEAG1D,CAEA,SAASstC,GAAS1mB,EAAqB9G,EAAoBnc,EAAc7N,GACvE,IAAIy/C,EAAQ3uB,EAAOpyB,IAAIsrB,QACT,IAAVy1B,IACFA,iBAAA,IAAYv8C,IACZ4tB,EAAOhyB,IAAIkrB,EAAWy1B,IAEpBA,EAAMp8C,IAAIwK,KACd4xC,EAAMn8C,IAAIuK,GACVhF,EAAgB,kBAAkB7I,KACpC,CCxLA,IAAM0/C,kBAAA,IAAuBl1C,IC+B7B,SAASm1C,GAAgBz+C,EAA6BkI,GACpD,MAAO,CACLlI,OACA,MAAAwd,GACEvV,EAAqBC,EACvB,EAEJ,CCCO,IAAMw2C,GAA8C99C,OAAO+2B,OAAO,CACvEgnB,0BAA0B,EAC1BpY,kBAAmB,mBACnBvE,eAAe,EACf1mB,gBAAiB,WASNsjC,GAA8Ch+C,OAAO+2B,OAAO,CACvEgnB,0BAA0B,EAC1BpY,kBAAmB,MACnBvE,eAAe,EACf1mB,gBAAiB,WCxCnB,SAASujC,GAAO/+C,GACd,YAAiB,IAAVA,OAAsB,GAAaA,CAC5C,CAEO,ICeHg/C,GDfSC,kBAAN,MACIjsC,GAAW,IAAI42B,aACfsV,GACAC,GACAxP,GACAnG,GACA96B,GACT4J,IAAW,EACX8mC,IAAa,EACbC,IAAY,EACZC,GAAwC,KAExC,WAAAtiD,CAAYuiD,EAAqC,IAC/C,MAAMrR,EEiDH,SAA6BA,GAIlC,MAAMsR,EHrBa,OGqBatR,EAAOuR,SHrBbX,GAAsBF,GGsBhD,MAAO,IACF1Q,EACHhM,cAAegM,EAAOhM,eAAiBsd,EAAKtd,cAC5C2c,yBAA0B3Q,EAAO2Q,0BAA4BW,EAAKX,yBAClEpY,kBAAmByH,EAAOzH,mBAAqB+Y,EAAK/Y,kBACpDjrB,gBAAiB0yB,EAAO1yB,iBAAmBgkC,EAAKhkC,gBAEpD,CF7DmBkkC,CAAoBH,GAC7B97B,EAAYyqB,EAAOzqB,WAAa,IG1BnC,SAAkCnb,GAKvC,GAAyB,OAArBA,EAAQm3C,UACsB,MAA7Bn3C,EAAQmb,WAAa,KAAoC,MAAtBnb,EAAQq3C,WAChD,MAAM,IAAIrhC,MACR,+OAIJ,CHeIshC,CAAyB,CACvBH,SAAUF,EAAUE,SACpBh8B,YACAk8B,WAAYzR,EAAOyR,aAErB,MAAM33C,EAAQkmC,EAAOlmC,OAAS4iC,YAC9BvtC,MAAKqR,EAAO1G,EACR,IAAIV,KACFS,EAAiB,oBAAqBT,IAExCI,EAEJrK,MAAK6hD,EAAY,IAAI7T,eACnBpiC,EAAY,CACVqiC,kBAAmB4C,EAAO2R,eAC1BnU,wBAAyBqT,GAAO7Q,EAAO2Q,0BACvChT,wBAAyBkT,GAAO7Q,EAAO4R,6BAIvCziD,MAAK6hD,EAAU9S,0BACjB/uC,MAAKqR,EAAK,4DAGZrR,MAAK8hD,EAAoB,IAAI5N,GFlB1B,WAGL,MAAMwO,EAAsC,CAC1ClJ,GACAkB,GACAI,GACAE,GACAQ,GACAM,GACAC,GACAC,GACA,IAAKA,GAAgBn5C,KAAM,SAC3B45C,GACA4B,GACAqB,MAlC+B,oBAAnBx0C,gBAAkCA,eAC5C,CACEo2C,GAAgB,QAAS,qBACzBA,GAAgB,SAAU,sBAE5B,CAACxB,GAAe,IAAKA,GAAej9C,KAAM,YAiC9C,OD1DK,SACLu/C,EAAqC,IAErC,MAAM9/C,EAAqC,GAC3C,UAAWkc,KAAY4jC,EAAU9/C,EAAIkc,EAAS3b,MAAQ2b,EACtD,UAAY1b,EAAM0b,KAAa6iC,GAAkB/+C,EAAIQ,GAAQ0b,EAC7D,OAAO/a,OAAO+2B,OAAOl4B,EACvB,CCmDSqgD,CAAc,CACnB5J,GAAmB,QACnBA,GAAmB,eAChB2J,KAC2B,oBAAnBx3C,gBAAkCA,eACzC,GACA,CAAC+0C,OAET,CETkD0C,IAE9C3iD,MAAKmsC,EAAW,IAAIyE,GAAc,CAChCT,OAAQnwC,MAAK2V,EACbk7B,OAAQptC,OAAO+2B,OAAO,IAAKqW,IAC3BS,sBAAwB9yB,GAAaxe,MAAK8hD,EAAkBpV,SAASluB,GACrEuyB,iBAAmBhqC,IACZ/G,MAAK2V,EAASktB,KAAK,QAAS,CAAE97B,QAAOuY,QAAS,YAAa9P,KAAM,YAExE6B,IAAKrR,MAAKqR,IAGZrR,MAAKsyC,EAAW,IAAIzJ,GAClBj9B,EAAY,CACVP,KAAMwlC,EAAOxlC,KACb8f,UAAWnrB,MAAK8hD,EAAkB32B,UAClCjM,gBAAiB,CAACrH,EAAwBxR,IACxCwqC,EAAO3xB,kBAAkBrH,EAAWxR,IAAWrG,MAAK8hD,EAAkBx8C,QAAQuS,GAChFqG,eAAgB2yB,EAAO3yB,eACvBC,gBAAiB0yB,EAAO1yB,gBACxBqkB,eAAgB,CACdrxB,EACAxO,EACA2c,EACA3B,IACG3d,MAAKmsC,EAAS0F,gBAAgB1gC,EAAWxO,EAAO2c,EAAS3B,GAC9DwrB,cAAgBxiC,GAAmB3G,MAAK6hD,EAAUroC,QAAQ7S,GAG1D6iC,aAAc,IAAMxpC,MAAK6hD,EAAUjT,YACnCj5B,QAAS3V,MAAK2V,EACd0zB,UACgB,KAAdjjB,OACI,EACAxa,EAAY,CACVwa,YACAC,SAAUwqB,EAAOxqB,SACjBC,MAAOuqB,EAAOyR,WACd/7B,QAASsqB,EAAO+R,aAExBx6B,WAAYyoB,EAAOzoB,WACnBkhB,YAAauH,EAAOvH,YACpB3gB,uBAAwBkoB,EAAOloB,uBAC/Bgd,qBAAsBkL,EAAOlL,qBAC7Bd,cAAegM,EAAOhM,cACtBE,kBAAmB8L,EAAO9L,kBAC1Bb,SAAU2M,EAAO3M,SACjBkF,kBAAmByH,EAAOzH,kBAC1B52B,aAAcq+B,EAAOr+B,aACrB4D,WAAYy6B,EAAOz6B,WACnBixB,sBAAuBwJ,EAAOxJ,sBAC9BD,wBAAyByJ,EAAOzJ,wBAChCj8B,WAAY0lC,EAAO1lC,WACnBK,WAAYqlC,EAAOrlC,WACnB+9B,mBAAoB,KAClBvpC,MAAK6hD,EAAUlT,gBAEjBlF,aAAc,IAAMzpC,MAAK6hD,EAAUpY,aACnC3gC,cAAe+nC,EAAO/nC,cACtBuI,IAAKrR,MAAKqR,KAIdrR,MAAK2V,EAAS82B,GAAG,UAAYoW,IAC3B7iD,MAAK6hD,EAAUnT,WAAWmU,EAAEl8C,WAGL,IAArBkqC,EAAOiS,WACT9iD,KAAK4oB,OAET,CAMA,KAAAA,GACE,GAAI5oB,MAAK+hD,EAAY,OAAO,EAC5B,GAAI/hD,MAAKib,EAIP,OADAjb,MAAKsyC,EAAS1pB,SACP,EAET,IAAK0kB,qBAAsB,OAAO,EAClC,MAAMryB,EAAUjb,MAAKsyC,EAAS1pB,QAE9B,OADI3N,IAAAjb,MAAcib,GAAW,GACtBA,CACT,CAOA,OAAAuvB,GACE,QAAIxqC,MAAK+hD,IAAe/hD,MAAKib,IACtBjb,MAAKsyC,EAAS9H,SACvB,CAGA,MAAAuY,GACE,QAAI/iD,MAAK+hD,IAAe/hD,MAAKib,IACtBjb,MAAKsyC,EAAS1pB,OACvB,CAGA,OAAAnR,GACE,GAA6B,OAAzBzX,MAAKiiD,EAA0B,OAAOjiD,MAAKiiD,EAE/C,IAAIe,EACAC,EAFJjjD,MAAK+hD,GAAa,EAGlB,MAAM9V,EAAW,IAAI5mC,QAAc,CAACC,EAAS49C,KAC3CF,EAAiB19C,EACjB29C,EAAgBC,IAIlBljD,MAAKiiD,EAAkBhW,EACvB,MAAMkX,EAAS,KACbnjD,MAAK2V,EAASq3B,qBACdhtC,MAAKgiD,GAAY,GAEnB,IACEhiD,MAAKsyC,EAAS76B,UACTzX,MAAKmsC,EAASwF,aAAayR,QAAQD,GAAQ/9C,KAAK49C,EAAgBC,EACvE,OAASl8C,GACPo8C,IACAF,EAAcl8C,EAChB,CACA,OAAOklC,CACT,CAEA,SAAMoX,CAAI9R,GACR,GAAIvxC,MAAK+hD,EAAY,MAAM,IAAI9gC,MAAM,8CAC/BjhB,MAAKmsC,EAASO,SAAS6E,EAC/B,CAGA,WAAM+R,CAAMzgD,GACV,GAAI7C,MAAKgiD,EAAW,MAAM,IAAI/gC,MAAM,8CAC9BjhB,MAAKmsC,EAASsF,WAAW5uC,EACjC,CAEA,YAAAgoC,GACE7qC,MAAKsyC,EAASzH,cAChB,CAEA,UAAIsF,GACF,OAAOnwC,MAAK2V,CACd,CAGA,WAAIw2B,GACF,OAAOnsC,MAAKmsC,EAAS6F,MACvB,CAEA,UAAIt6B,GACF,OAAO1X,MAAKsyC,EAAS56B,MACvB,CAMA,OAAAqzB,GACE,MAAO,IAAK/qC,MAAKsyC,EAASvH,UAAWoB,QAASnsC,MAAKmsC,EAAS1V,WAC9D,CAGA,eAAInb,GACF,OAAOtb,MAAKsyC,EAASh3B,WACvB,CAGA,aAAIymC,GACF,OAAO/hD,MAAK+hD,CACd,GI3NWwB,GAA+B,kDA8BtCC,GAAQ5wB,OAAOC,IAAI0wB,IAGlB,SAASE,2BAA2B9gD,GACzC,MACmB,iBAAVA,GACG,OAAVA,IACmD,IAAlDA,EAAuC6gD,KACxC//C,OAAOigD,SAAS/gD,EAEpB,CCnDO,ICcDgwB,GAAO,4BCPAgxB,GAAmBlgD,OAAO+2B,OAAO,CAE5CopB,gBAAiB,SAEjBC,kBAAmB,SAEnBC,mBAAoB,SAEpBC,sBAAuB,SAGvBC,YAAa,SAEbC,qBAAsB,SAGtBC,uBAAwB,SAGxBC,qBAAsB,SAEtBC,sBAAuB,SAEvBC,qBAAsB,SAEtBC,sBAAuB,SAEvBC,uBAAwB,SAExBC,uBAAwB,SAExBC,oBAAqB,SAErBC,mBAAoB,SAEpBC,0BAA2B,SAE3BC,oBAAqB,SAErBC,gBAAiB,SAEjBC,qBAAsB,SAEtBC,oBAAqB,SAGrBC,gBAAiB,SAEjBC,cAAe,SAEfC,qBAAsB,SAGtBC,aAAc,SAEdC,eAAgB,SAEhBC,cAAe,SAGfC,cAAe,SAEfC,YAAa,SAEbC,sBAAuB,SAGvBC,oBAAqB,SAErBC,sBAAuB,SAEvBC,wBAAyB,SAEzBC,qBAAsB,SAEtBC,2BAA4B,SAE5BC,qBAAsB,SAEtBC,gBAAiB,SAEjBC,cAAe,SAEfC,sBAAuB,SAEvBC,wBAAyB,SAEzBC,qBAAsB,SAEtBC,mBAAoB,SAEpBC,iBAAkB,SAElBC,4BAA6B,SAE7BC,qBAAsB,SAEtBC,eAAgB,SAEhBC,oBAAqB,WChFhB,SAASlf,KACdv/B,EACAiD,GAEA,OAAOy7C,GAAgB1+C,EAAOiD,EAChC,CAMO,SAAS07C,WACdC,EACA37C,GAEA,MAAMqB,EAsCR,SAAoBs6C,GAClB,MAAMt6C,EAAiB,GACjBu6C,EAAiB,IAAIC,MACzB,GACA,CACE,GAAAzmD,CAAI0mD,EAASC,GACX,GAAoB,iBAATA,EACX,MAAI,QAAQ/mD,KAAK+mD,IACjB16C,EAAK5J,KAAKskD,GADqBH,CAGjC,IAGJ,IACED,EAAOC,EACT,OAEA,CACA,OAAOv6C,CACT,CAzDe26C,CAAWL,GACxB,GAAoB,IAAhBt6C,EAAK3N,OACP,MAAM,IAAIsiB,MACR,6FAGJ,OAAOylC,GAAgBp6C,EAAK6L,KAAK,KAAMlN,EACzC,CAEA,SAASy7C,GAAgB1+C,EAAeiD,GACtC,GAAqB,IAAjBjD,EAAMrJ,OACR,MAAM,IAAIsiB,MAAM,+CAElB,MAAMgY,EAUF,CAAE,qBAAsBjxB,GAY5B,YAX2B,IAAvBiD,GAAS2U,YAAyBqZ,EAAM,0BAA4BhuB,EAAQ2U,gBAC1D,IAAlB3U,GAASnI,OAAoBm2B,EAAM,qBAAuBhuB,EAAQnI,OAE5C,IAAtBmI,GAASi8C,WAAmBjuB,EAAM,yBAA2B,KAC3C,IAAlBhuB,GAAS8nB,OAAekG,EAAM,qBAAuB,SACjC,IAApBhuB,GAASrL,SAAsBq5B,EAAM,uBAAyBhuB,EAAQrL,aACrD,IAAjBqL,GAAS4lB,MAAmBoI,EAAM,oBAAsBhuB,EAAQ4lB,UAC9C,IAAlB5lB,GAAS0lB,OAAoBsI,EAAM,qBAAuBhuB,EAAQ0lB,WACvC,IAA3B1lB,GAASka,gBACX8T,EAAM,+BAAiChuB,EAAQka,eAE1C8T,CACT,CCvDA,IAAMkuB,GAAc,0BAMdC,GAAgC3jD,OAAO+2B,OAAO,I,2GJ1BhD,CACF32B,MAAO,CACLwjD,MAAO,6CACP5I,SAAU,4BAEZ,cAAe,CACb4I,MAAO,4EACP5I,SAAU,mEAEZ7+C,OAAQ,CACNynD,MACE,4FACF5I,SAAU,+CAEZ,gBAAiB,CACf4I,MAAO,mDACP5I,SAAU,8DAEZ,gBAAiB,CACf4I,MAAO,wCACP5I,SAAU,yCAEZ,kBAAmB,CACjB4I,MAAO,yBACP5I,SAAU,sCAEZ,kBAAmB,CACjB4I,MAAO,uFACP5I,SAAU,qEAEZ,sBAAuB,CACrB4I,MACE,sGACF5I,SAAU,gF,oBK5BY,E,uHnHdc,E,gN0GqFjC,SAAS6I,oBAAoBr8C,EAAiC,IACnE,MAAMmiC,KAAEA,GAAO,EAAAhmC,QAAMA,EAAU,GAACmgD,UAAGA,GAAY,GAAUt8C,EACnDrG,iBAAA,IAAWC,IACXvC,EAA6B,GACnC,GAAIilD,IAAcna,GAA2B,IAAnBhmC,EAAQzI,OAAc,MAAO,SACnDyuC,IACF9qC,EAAII,KAAK,UACTkC,EAAKK,IAAI,WAEX,UAAW0B,KAAUS,EAAS,CAC5B,MAAM6I,EAAUtJ,EAAOuJ,OACA,IAAnBD,EAAQtR,QAAgBiG,EAAKI,IAAIiL,KACrCrL,EAAKK,IAAIgL,GACT3N,EAAII,KAAKuN,GACX,CACA,OAAO3N,EAAI3D,OAAS,EAAI2D,EAAI6V,KAAK,KAAO,QAC1C,E,gCAQO,SAASqvC,wBACdC,EACAx8C,EAII,IAEJ,GAAqB,IAAjBw8C,EAAM9oD,OAAc,MAAM,IAAI+oD,WAAW,2CAC7C,MAAMta,KAAEA,GAAO,EAAAua,MAAMA,EAAQ,GAACC,cAAGA,GAAgB,GAAU38C,EACrDgyC,EAAkB,GACpB7P,GAAM6P,EAAMv6C,KAAK,UACrBu6C,EAAMv6C,KAAK,UAAU+kD,MACjBG,GAAe3K,EAAMv6C,KAAK,oBAC9B,UAAWmgD,KAAK8E,EAAO,CACrB,MAAM13C,EAAU4yC,EAAE3yC,OACdD,EAAQtR,OAAS,GAAGs+C,EAAMv6C,KAAKuN,EACrC,CACA,OAAOgtC,EAAM9kC,KAAK,IACpB,E,8BQ7BO,SAAS0vC,sBAAsB58C,GAEpC,MAAM68C,EAAarE,2BAA2Bx4C,EAAQ88C,eAChDt0C,OAA0B,IAAlBxI,EAAQwI,OAAuBxI,EAAQwI,MAAM9U,OAAS,EAAIsM,EAAQwI,WAAQ,EAExF,OAAOhQ,OAAO+2B,OAAO,CACnBstB,aACAvgB,KAAM,CACJv/B,EACAggD,IAEAF,EAAavgB,KAAQv/B,EAAOggD,GAAeZ,GAG7CT,WAAY,CACVC,EACAoB,IAEAF,EAAanB,WAAcC,EAAQoB,GAAeZ,GACpD3zC,MAAO,IACLq0C,QAAwB,IAAVr0C,EAAsB,CAAE,qBAAsBA,GAAU2zC,GACxE5mB,SAAU,CACRx/B,EACAinD,EAA2C,MAE3C,MAAM1+B,EAnDZ,SACEvoB,EACAiK,GAEA,IAAKk8C,GAAYlnD,KAAKe,GACpB,MAAM,IAAI0mD,WACR,wCAAwC1mD,sKAK5C,MAAM6K,EAAMZ,EAAQY,IACpB,QAAY,IAARA,IAAqC,IAAfA,EAAIlN,QAAgBkN,EAAIlN,OAvD7B,KAwDnB,MAAM,IAAI+oD,WACR,oDAAoD1mD,mBAAoBQ,OAzDvD,oBA4DrB,MAAMggB,EAAYvW,EAAQuW,WAAa,GACvC,MAAO,CACL,wBAAyBxgB,UACb,IAAR6K,EAAoB,CAAE,4BAA6BA,GAAQ,MAC3D2V,EAAU7iB,OAAS,EAAI,CAAE,uBAAwB6iB,EAAUrJ,KAAK,MAAS,GAEjF,CA4ByB+vC,CAAmBlnD,EAAIinD,GAC1C,OAAOH,EAAav+B,EAAa69B,KAGvC,E,2MRpFO,SAASe,iBAAiBC,EA9CL,IA+C1B,IAAK/jD,OAAO+uC,UAAUgV,IAAUA,EAAQ,EACtC,MAAM,IAAIV,WAAW,wDAAwDlmD,OAAO4mD,MAEtF,MAAMC,EAaR,WACE,GAAI1G,IAAgB2G,gBAAiB,OAAO3G,GAC5C,MAAM4G,EAAcp1B,WAA0Ck1B,OAC9D,OAAIE,GAAYD,gBAAwBC,OACxC,CACF,CAlBiBC,GACf,IAAKH,EACH,MAAM,IAAIpnC,MACR,0OAKJ,MAAM0nB,EAAS,IAAI8f,WAAWL,GAE9B,OADAC,EAAOC,gBAAgB3f,GAWzB,SAAyByf,GACvB,IAAIM,EAAS,GACb,UAAWC,KAAQP,EAAOM,GAAUlnD,OAAOonD,aAAaD,GAExD,OAD+B,mBAATE,KAAsBA,KAAKH,GAAUI,OAAOp7C,KAAK06C,GAAOW,SAAS,WACzEC,WAAW,IAAK,KAAKA,WAAW,IAAK,KAAKA,WAAW,IAAK,GAC1E,CAfSC,CAAgBtgB,EACzB,E,sB1GeO,SAASugB,cACdnxC,EACAhT,GAEA,OAAOgT,EAAYjT,aAAaE,IAAID,EACtC,E,wByGkKO,SAASokD,gBAAgBtY,EAAkC,IAChE,MAAMuY,EAAS,IAAIxH,kBAAkB,IAAK/Q,EAAQiS,WAAW,IAC7D,OAAOsG,EAAOxgC,QAAUwgC,EAAS,IACnC,E,yXMjNO,SAASC,qBAAqBvnB,GACnC,MAAMz7B,EAVmB,oBAAXC,YAAyB,EAAaA,OAWpD,YAAe,IAAXD,EAA6B,QACjCA,EAAOssB,IAAQmP,EACR,KAGDz7B,EAAOssB,MAAUmP,IAASz7B,EAAOssB,SAAQ,IAEjD,E,uDLLO,SAAS22B,aAAajB,GAC3B1G,GAAiB0G,QAAU,CAC7B,E,6BhEgPO,SAASkB,qBAAqB/xC,GAClC2b,WAA4BuF,IAAiBlhB,QAAO,CACvD","ignoreList":[]}
|