@elu-labs/analytics-browser 1.410.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +245 -0
- package/NOTICE-ELU +6 -0
- package/README.md +200 -0
- package/THIRD_PARTY_NOTICES.txt +48 -0
- package/dist/cold-session.mjs +3 -0
- package/dist/cold-session.mjs.map +1 -0
- package/dist/elu.js +3 -0
- package/dist/elu.js.map +1 -0
- package/dist/index.d.ts +122 -0
- package/dist/main.cjs +3 -0
- package/dist/main.cjs.map +1 -0
- package/dist/module.mjs +3 -0
- package/dist/module.mjs.map +1 -0
- package/dist/recorder.js +2 -0
- package/dist/recorder.js.map +1 -0
- package/dist/recorder.mjs +3 -0
- package/dist/recorder.mjs.map +1 -0
- package/dist/storage.js +3 -0
- package/dist/storage.js.map +1 -0
- package/package.json +33 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recorder.js","sources":["elu-js/packages/rrweb/rrweb/src/record/cleanup.ts","elu-js/packages/rrweb/types/src/index.ts","elu-js/packages/rrweb/utils/src/browser-detection.ts","elu-js/packages/rrweb/utils/src/index.ts","elu-js/packages/rrweb/rrweb-snapshot/src/utils.ts","elu-js/packages/rrweb/rrweb-snapshot/src/snapshot.ts","dependencies/picocolors/1.1.1/picocolors.browser.js","dependencies/postcss/8.5.16/lib/css-syntax-error.js","dependencies/postcss/8.5.16/lib/stringifier.js","dependencies/postcss/8.5.16/lib/stringify.js","dependencies/postcss/8.5.16/lib/symbols.js","dependencies/postcss/8.5.16/lib/node.js","dependencies/postcss/8.5.16/lib/comment.js","dependencies/postcss/8.5.16/lib/declaration.js","dependencies/postcss/8.5.16/lib/container.js","dependencies/postcss/8.5.16/lib/at-rule.js","dependencies/postcss/8.5.16/lib/document.js","dependencies/nanoid/3.3.15/non-secure/index.cjs","dependencies/postcss/8.5.16/lib/previous-map.js","dependencies/postcss/8.5.16/lib/input.js","dependencies/postcss/8.5.16/lib/root.js","dependencies/postcss/8.5.16/lib/list.js","dependencies/postcss/8.5.16/lib/rule.js","dependencies/postcss/8.5.16/lib/map-generator.js","dependencies/postcss/8.5.16/lib/tokenize.js","dependencies/postcss/8.5.16/lib/parser.js","dependencies/postcss/8.5.16/lib/parse.js","dependencies/postcss/8.5.16/lib/warning.js","dependencies/postcss/8.5.16/lib/result.js","dependencies/postcss/8.5.16/lib/warn-once.js","dependencies/postcss/8.5.16/lib/lazy-result.js","dependencies/postcss/8.5.16/lib/postcss.js","dependencies/postcss/8.5.16/lib/fromJSON.js","dependencies/postcss/8.5.16/lib/processor.js","dependencies/postcss/8.5.16/lib/no-work-result.js","dependencies/postcss-safe-parser/7.0.1/lib/safe-parse.js","dependencies/postcss-safe-parser/7.0.1/lib/safe-parser.js","dependencies/postcss/8.5.16/lib/postcss.mjs","elu-js/packages/rrweb/rrdom/src/document.ts","elu-js/packages/rrweb/rrweb/src/utils.ts","elu-js/packages/rrweb/rrweb/src/record/mutation.ts","elu-js/packages/rrweb/rrweb/src/record/error-handler.ts","elu-js/packages/rrweb/rrweb/src/record/observer.ts","elu-js/packages/rrweb/rrweb/src/record/cross-origin-iframe-mirror.ts","elu-js/packages/rrweb/rrweb/src/record/iframe-manager.ts","elu-js/packages/rrweb/rrweb/src/record/shadow-dom-manager.ts","elu-js/packages/rrweb/rrweb/src/record/observers/canvas/canvas-mask.ts","dependencies/base64-arraybuffer/1.0.2/dist/base64-arraybuffer.es5.js.map#sources/0","elu-js/packages/rrweb/rrweb/src/record/observers/canvas/serialize-args.ts","elu-js/packages/rrweb/rrweb/src/record/observers/canvas/canvas.ts","elu-js/packages/rrweb/rrweb/src/record/observers/canvas/webgl.ts","elu-js/packages/rrweb/rrweb/src/record/index.ts","elu-js/packages/rrweb/rrweb/src/record/observers/canvas/canvas-manager.ts","elu-js/packages/rrweb/rrweb/src/record/observers/canvas/2d.ts","elu-js/packages/rrweb/rrweb/src/record/stylesheet-manager.ts","elu-js/packages/rrweb/rrweb/src/record/processed-node-manager.ts","elu-js/packages/browser/scripts/runtime/deflated-text-data.ts","elu-js/packages/browser/src/elu-http-v1/validation.ts","elu-js/packages/browser/src/elu-http-v1/transport.ts","elu-js/packages/browser/src/elu-http-v1/exact-timestamp.ts","elu-js/packages/browser/src/elu-http-v1/privacy-state.ts","elu-js/packages/browser/src/elu-http-v1/replay/dom-masker.ts","elu-js/packages/browser/src/elu-http-v1/replay/digest.ts","elu-js/packages/browser/src/elu-http-v1/replay/errors.ts","elu-js/packages/browser/src/elu-http-v1/replay/canonical-payload-json.ts","elu-js/packages/browser/src/elu-http-v1/replay/masking-profile.ts","elu-js/packages/browser/src/elu-http-v1/replay/recorder-masking.ts","elu-js/packages/browser/src/elu-http-v1/replay/recorder-adapter.ts","elu-js/packages/browser/src/elu-http-v1/replay/schedule.ts","elu-js/packages/browser/src/elu-http-v1/indexeddb-storage.ts","elu-js/packages/browser/src/elu-http-v1/durable-state.ts","dependencies/fflate/0.4.8/esm/browser.js","elu-js/packages/browser/src/elu-http-v1/replay/base64.ts","elu-js/packages/browser/src/elu-http-v1/replay/masking-proof.ts","elu-js/packages/browser/src/elu-http-v1/replay/codec.ts","elu-js/packages/browser/src/elu-http-v1/replay/request.ts","elu-js/packages/browser/src/elu-http-v1/replay/seal-chunk.ts","elu-js/packages/browser/src/elu-http-v1/replay/session-driver.ts","elu-js/packages/browser/recorder-entry/index.ts"],"sourcesContent":["import type { listenerHandler } from '@elu-labs/recorder-types';\n\nexport class RecorderCleanupError extends Error {\n constructor() {\n super('Recorder cleanup incomplete');\n this.name = 'RecorderCleanupError';\n }\n}\n\n/** Snapshot is a lower-level package, so its cleanup failure crosses by the same safe name. */\nexport const isRecorderCleanupError = (error: unknown): boolean =>\n error instanceof RecorderCleanupError ||\n (!!error &&\n typeof error === 'object' &&\n (error as { name?: unknown }).name === 'RecorderCleanupError');\n\n/** Acquisitions are unwound once, in reverse order, including after a partial start. */\nexport function createRecorderCleanup() {\n const handlers: listenerHandler[] = [];\n let closed = false;\n let failed = false;\n const attempt = (handler: listenerHandler) => {\n try {\n handler();\n } catch {\n failed = true;\n }\n };\n const assertComplete = () => {\n // Do not expose captured DOM content or allow a retry to hide a failed teardown.\n if (failed) throw new RecorderCleanupError();\n };\n const close = () => {\n closed = true;\n while (handlers.length) attempt(handlers.pop()!);\n assertComplete();\n };\n return {\n close,\n poison() {\n failed = true;\n },\n add(handler: listenerHandler) {\n if (closed) {\n attempt(handler);\n assertComplete();\n } else handlers.push(handler);\n },\n replace<T extends object, K extends keyof T>(\n target: T,\n key: K,\n value: T[K],\n ) {\n if (closed) throw new RecorderCleanupError();\n const descriptor = Object.getOwnPropertyDescriptor(target, key);\n // Register before a host setter is invoked: it may mutate and then throw.\n this.add(() => {\n if (descriptor) Object.defineProperty(target, key, descriptor);\n else if (!Reflect.deleteProperty(target, key))\n throw new Error('Recorder patch restoration failed');\n });\n target[key] = value;\n },\n };\n}\n\nexport function acquireRecorderCleanup(\n acquire: (cleanup: ReturnType<typeof createRecorderCleanup>) => void,\n): listenerHandler {\n const cleanup = createRecorderCleanup();\n try {\n acquire(cleanup);\n return cleanup.close;\n } catch (error) {\n if (isRecorderCleanupError(error)) cleanup.poison();\n cleanup.close();\n throw error;\n }\n}\n","export enum EventType {\n DomContentLoaded,\n Load,\n FullSnapshot,\n IncrementalSnapshot,\n Meta,\n Custom,\n Plugin,\n}\n\nexport type domContentLoadedEvent = {\n type: EventType.DomContentLoaded;\n data: unknown;\n};\n\nexport type loadedEvent = {\n type: EventType.Load;\n data: unknown;\n};\n\nexport type fullSnapshotEvent = {\n type: EventType.FullSnapshot;\n data: {\n node: serializedNodeWithId;\n initialOffset: {\n top: number;\n left: number;\n };\n };\n};\n\nexport type incrementalSnapshotEvent = {\n type: EventType.IncrementalSnapshot;\n data: incrementalData;\n};\n\nexport type metaEvent = {\n type: EventType.Meta;\n data: {\n href: string;\n width: number;\n height: number;\n };\n};\n\nexport type customEvent<T = unknown> = {\n type: EventType.Custom;\n data: {\n tag: string;\n payload: T;\n };\n};\n\n/**\n * Reserved custom-event tag emitted by the recorder when an element enters or\n * exits the native Fullscreen API. Native fullscreen is rendered by the UA\n * `:fullscreen` pseudo-class with no DOM mutation, so rrweb captures nothing —\n * this event lets the replayer re-apply fullscreen layout on playback.\n */\nexport const FullscreenCustomEventTag = 'rrweb/fullscreen';\n\nexport type fullscreenEventPayload = {\n /** mirror id of the element that went fullscreen */\n id: number;\n enter: boolean;\n};\n\nexport type pluginEvent<T = unknown> = {\n type: EventType.Plugin;\n data: {\n plugin: string;\n payload: T;\n };\n};\n\nexport enum IncrementalSource {\n Mutation,\n MouseMove,\n MouseInteraction,\n Scroll,\n ViewportResize,\n Input,\n TouchMove,\n MediaInteraction,\n StyleSheetRule,\n CanvasMutation,\n Font,\n Log,\n Drag,\n StyleDeclaration,\n Selection,\n AdoptedStyleSheet,\n CustomElement,\n}\n\nexport type mutationData = {\n source: IncrementalSource.Mutation;\n} & mutationCallbackParam;\n\nexport type mousemoveData = {\n source:\n | IncrementalSource.MouseMove\n | IncrementalSource.TouchMove\n | IncrementalSource.Drag;\n positions: mousePosition[];\n};\n\nexport type mouseInteractionData = {\n source: IncrementalSource.MouseInteraction;\n} & mouseInteractionParam;\n\nexport type scrollData = {\n source: IncrementalSource.Scroll;\n} & scrollPosition;\n\nexport type viewportResizeData = {\n source: IncrementalSource.ViewportResize;\n} & viewportResizeDimension;\n\nexport type inputData = {\n source: IncrementalSource.Input;\n id: number;\n} & inputValue;\n\nexport type mediaInteractionData = {\n source: IncrementalSource.MediaInteraction;\n} & mediaInteractionParam;\n\nexport type styleSheetRuleData = {\n source: IncrementalSource.StyleSheetRule;\n} & styleSheetRuleParam;\n\nexport type styleDeclarationData = {\n source: IncrementalSource.StyleDeclaration;\n} & styleDeclarationParam;\n\nexport type canvasMutationData = {\n source: IncrementalSource.CanvasMutation;\n} & canvasMutationParam;\n\nexport type fontData = {\n source: IncrementalSource.Font;\n} & fontParam;\n\nexport type selectionData = {\n source: IncrementalSource.Selection;\n} & selectionParam;\n\nexport type adoptedStyleSheetData = {\n source: IncrementalSource.AdoptedStyleSheet;\n} & adoptedStyleSheetParam;\n\nexport type customElementData = {\n source: IncrementalSource.CustomElement;\n} & customElementParam;\n\nexport type incrementalData =\n | mutationData\n | mousemoveData\n | mouseInteractionData\n | scrollData\n | viewportResizeData\n | inputData\n | mediaInteractionData\n | styleSheetRuleData\n | canvasMutationData\n | fontData\n | selectionData\n | styleDeclarationData\n | adoptedStyleSheetData\n | customElementData;\n\nexport type eventWithoutTime =\n | domContentLoadedEvent\n | loadedEvent\n | fullSnapshotEvent\n | incrementalSnapshotEvent\n | metaEvent\n | customEvent\n | pluginEvent;\n\n/**\n * @deprecated intended for internal use\n * a synonym for eventWithoutTime\n */\nexport type event = eventWithoutTime;\n\nexport type eventWithTime = eventWithoutTime & {\n timestamp: number;\n delay?: number;\n};\n\nexport type canvasEventWithTime = eventWithTime & {\n type: EventType.IncrementalSnapshot;\n data: canvasMutationData;\n};\n\nexport type blockClass = string | RegExp;\n\nexport type maskTextClass = string | RegExp;\n\nexport type SamplingStrategy = Partial<{\n /**\n * false means not to record mouse/touch move events\n * number is the throttle threshold of recording mouse/touch move\n */\n mousemove: boolean | number;\n /**\n * number is the throttle threshold of mouse/touch move callback\n */\n mousemoveCallback: number;\n /**\n * false means not to record mouse interaction events\n * can also specify record some kinds of mouse interactions\n */\n mouseInteraction: boolean | Record<string, boolean | undefined>;\n /**\n * number is the throttle threshold of recording scroll\n */\n scroll: number;\n /**\n * number is the throttle threshold of recording media interactions\n */\n media: number;\n /**\n * 'all' will record all the input events\n * 'last' will only record the last input value while input a sequence of chars\n */\n input: 'all' | 'last';\n /**\n * 'all' will record every single canvas call\n * number between 1 and 60, will record an image snapshots in a web-worker a (maximum) number of times per second.\n * Number only supported where [`OffscreenCanvas`](http://mdn.io/offscreencanvas) is supported.\n */\n canvas: 'all' | number;\n}>;\n\nexport interface ICrossOriginIframeMirror {\n getId(\n iframe: HTMLIFrameElement,\n remoteId: number,\n parentToRemoteMap?: Map<number, number>,\n remoteToParentMap?: Map<number, number>,\n ): number;\n getIds(iframe: HTMLIFrameElement, remoteId: number[]): number[];\n getRemoteId(\n iframe: HTMLIFrameElement,\n parentId: number,\n map?: Map<number, number>,\n ): number;\n getRemoteIds(iframe: HTMLIFrameElement, parentId: number[]): number[];\n reset(iframe?: HTMLIFrameElement): void;\n}\n\nexport type RecordPlugin<TOptions = unknown> = {\n name: string;\n observer?: (\n cb: (...args: Array<unknown>) => void,\n win: IWindow,\n options: TOptions,\n ) => listenerHandler;\n eventProcessor?: <TExtend>(event: eventWithTime) => eventWithTime & TExtend;\n getMirror?: (mirrors: {\n nodeMirror: IMirror<Node>;\n crossOriginIframeMirror: ICrossOriginIframeMirror;\n crossOriginIframeStyleMirror: ICrossOriginIframeMirror;\n }) => void;\n options: TOptions;\n};\n\nexport type hooksParam = {\n mutation?: mutationCallBack;\n mousemove?: mousemoveCallBack;\n mouseInteraction?: mouseInteractionCallBack;\n scroll?: scrollCallback;\n viewportResize?: viewportResizeCallback;\n input?: inputCallback;\n mediaInteaction?: mediaInteractionCallback;\n styleSheetRule?: styleSheetRuleCallback;\n styleDeclaration?: styleDeclarationCallback;\n canvasMutation?: canvasMutationCallback;\n font?: fontCallback;\n selection?: selectionCallback;\n customElement?: customElementCallback;\n};\n\n// https://dom.spec.whatwg.org/#interface-mutationrecord\nexport type mutationRecord = Readonly<{\n type: string;\n target: Node;\n oldValue: string | null;\n addedNodes: NodeList;\n removedNodes: NodeList;\n attributeName: string | null;\n}>;\n\nexport type textCursor = {\n node: Node;\n value: string | null;\n};\nexport type textMutation = {\n id: number;\n value: string | null;\n};\n\nexport type styleOMValue = {\n [key: string]: styleValueWithPriority | string | false;\n};\n\nexport type styleValueWithPriority = [string, string];\n\nexport type attributeCursor = {\n node: Node;\n attributes: {\n [key: string]: string | styleOMValue | null;\n };\n styleDiff: styleOMValue;\n _unchangedStyles: styleOMValue;\n};\nexport type attributeMutation = {\n id: number;\n attributes: {\n [key: string]: string | styleOMValue | null;\n };\n};\n\nexport type removedNodeMutation = {\n parentId: number;\n id: number;\n isShadow?: boolean;\n};\n\nexport type addedNodeMutation = {\n parentId: number;\n // Newly recorded mutations will not have previousId any more, just for compatibility\n previousId?: number | null;\n nextId: number | null;\n node: serializedNodeWithId;\n};\n\nexport type mutationCallbackParam = {\n texts: textMutation[];\n attributes: attributeMutation[];\n removes: removedNodeMutation[];\n adds: addedNodeMutation[];\n isAttachIframe?: true;\n};\n\nexport type mutationCallBack = (m: mutationCallbackParam) => void;\n\nexport type mousemoveCallBack = (\n p: mousePosition[],\n source:\n | IncrementalSource.MouseMove\n | IncrementalSource.TouchMove\n | IncrementalSource.Drag,\n) => void;\n\nexport type mousePosition = {\n x: number;\n y: number;\n id: number;\n timeOffset: number;\n};\n\nexport type mouseMovePos = {\n x: number;\n y: number;\n id: number;\n debugData: incrementalData;\n};\n\nexport enum MouseInteractions {\n MouseUp,\n MouseDown,\n Click,\n ContextMenu,\n DblClick,\n Focus,\n Blur,\n TouchStart,\n TouchMove_Departed, // we will start a separate observer for touch move event\n TouchEnd,\n TouchCancel,\n}\n\nexport enum PointerTypes {\n Mouse,\n Pen,\n Touch,\n}\n\nexport enum CanvasContext {\n '2D',\n WebGL,\n WebGL2,\n}\n\nexport type SerializedCanvasArg =\n | {\n rr_type: 'ArrayBuffer';\n base64: string; // base64\n }\n | {\n rr_type: 'Blob';\n data: Array<CanvasArg>;\n type?: string;\n }\n | {\n rr_type: string;\n src: string; // url of image\n }\n | {\n rr_type: string;\n args: Array<CanvasArg>;\n }\n | {\n rr_type: string;\n index: number;\n };\n\nexport type CanvasArg =\n | SerializedCanvasArg\n | string\n | number\n | boolean\n | null\n | CanvasArg[];\n\ntype mouseInteractionParam = {\n type: MouseInteractions;\n id: number;\n x?: number;\n y?: number;\n pointerType?: PointerTypes;\n};\n\nexport type mouseInteractionCallBack = (d: mouseInteractionParam) => void;\n\nexport type scrollPosition = {\n id: number;\n x: number;\n y: number;\n};\n\nexport type scrollCallback = (p: scrollPosition) => void;\n\nexport type styleSheetAddRule = {\n rule: string;\n index?: number | number[];\n};\n\nexport type styleSheetDeleteRule = {\n index: number | number[];\n};\n\nexport type styleSheetRuleParam = {\n id?: number;\n styleId?: number;\n removes?: styleSheetDeleteRule[];\n adds?: styleSheetAddRule[];\n replace?: string;\n replaceSync?: string;\n};\n\nexport type styleSheetRuleCallback = (s: styleSheetRuleParam) => void;\n\nexport type adoptedStyleSheetParam = {\n // id indicates the node id of document or shadow DOMs' host element.\n id: number;\n // New CSSStyleSheets which have never appeared before.\n styles?: {\n styleId: number;\n rules: styleSheetAddRule[];\n }[];\n // StyleSheet ids to be adopted.\n styleIds: number[];\n};\n\nexport type adoptedStyleSheetCallback = (a: adoptedStyleSheetParam) => void;\n\nexport type styleDeclarationParam = {\n id?: number;\n styleId?: number;\n index: number[];\n set?: {\n property: string;\n value: string | null;\n priority: string | undefined;\n };\n remove?: {\n property: string;\n };\n};\n\nexport type styleDeclarationCallback = (s: styleDeclarationParam) => void;\n\nexport type canvasMutationCommand = {\n property: string;\n args: Array<unknown>;\n setter?: true;\n};\n\nexport type canvasMutationParam =\n | {\n id: number;\n type: CanvasContext;\n commands: canvasMutationCommand[];\n displayWidth?: number;\n displayHeight?: number;\n }\n | ({\n id: number;\n type: CanvasContext;\n displayWidth?: number;\n displayHeight?: number;\n } & canvasMutationCommand);\n\nexport type canvasMutationWithType = {\n type: CanvasContext;\n} & canvasMutationCommand;\n\nexport type canvasMutationCallback = (p: canvasMutationParam) => void;\n\nexport type canvasManagerMutationCallback = (\n target: HTMLCanvasElement,\n p: canvasMutationWithType,\n) => void;\n\nexport type CanvasMaskRegion = {\n x: number;\n y: number;\n width: number;\n height: number;\n};\n\nexport type CanvasMasking = {\n // CSS-pixel regions relative to the canvas element, re-read every frame.\n // `undefined` means no provider is configured; `null` means a configured\n // provider could not compute this frame, which skips it\n regionsFn?: (\n canvas: HTMLCanvasElement,\n ) => CanvasMaskRegion[] | null | undefined;\n // re-evaluated at each DOM snapshot/serialization, like `regionsFn`. When it\n // returns true, DOM snapshots skip canvas pixel serialization (`rr_dataURL`)\n // entirely — that path never sees the mask regions, so serializing there\n // would leak unmasked pixels. The masked frame stream repaints the canvas\n // instead\n configured?: () => boolean;\n};\n\nexport type ImageBitmapDataURLWorkerParams = {\n id: number;\n bitmap: ImageBitmap;\n // the size the bitmap is encoded at (may be downscaled from the display size)\n width: number;\n height: number;\n // the canvas display size the encoded frame should be drawn back to on replay; carried\n // through the worker so the reply knows it without the main thread holding per-id state.\n displayWidth: number;\n displayHeight: number;\n dataURLOptions: DataURLOptions;\n // capture-resolution pixels, painted over before the frame is encoded\n maskRegions?: CanvasMaskRegion[];\n};\n\nexport type ImageBitmapDataURLWorkerResetParams = {\n // sent when the recorder takes a full snapshot: node ids survive full\n // snapshots, so without dropping the remembered fingerprints an idle canvas\n // would never re-emit a frame and a seek rebuilt from that snapshot would\n // find nothing to repaint it from\n resetFrameDedup: true;\n};\n\nexport type ImageBitmapDataURLWorkerMessage =\n | ImageBitmapDataURLWorkerParams\n | ImageBitmapDataURLWorkerResetParams;\n\nexport type ImageBitmapDataURLWorkerResponse =\n | {\n id: number;\n }\n | {\n id: number;\n type: string;\n base64: string;\n // the display size to draw the (possibly downscaled) frame back to on replay\n displayWidth: number;\n displayHeight: number;\n };\n\nexport type fontParam = {\n family: string;\n fontSource: string;\n buffer: boolean;\n descriptors?: FontFaceDescriptors;\n};\n\nexport type fontCallback = (p: fontParam) => void;\n\nexport type viewportResizeDimension = {\n width: number;\n height: number;\n};\n\nexport type viewportResizeCallback = (d: viewportResizeDimension) => void;\n\nexport type inputValue = {\n text: string;\n isChecked: boolean;\n\n // `userTriggered` indicates if this event was triggered directly by user (userTriggered: true)\n // or was triggered indirectly (userTriggered: false)\n // Example of `userTriggered` in action:\n // User clicks on radio element (userTriggered: true) which triggers the other radio element to change (userTriggered: false)\n userTriggered?: boolean;\n};\n\nexport type inputCallback = (v: inputValue & { id: number }) => void;\n\nexport enum MediaInteractions {\n Play,\n Pause,\n Seeked,\n VolumeChange,\n RateChange,\n}\n\nexport type mediaInteractionParam = {\n type: MediaInteractions;\n id: number;\n currentTime?: number;\n volume?: number;\n muted?: boolean;\n loop?: boolean;\n playbackRate?: number;\n};\n\nexport type mediaInteractionCallback = (p: mediaInteractionParam) => void;\n\nexport type DocumentDimension = {\n x: number;\n y: number;\n // scale value relative to its parent iframe\n relativeScale: number;\n // scale value relative to the root iframe\n absoluteScale: number;\n};\n\nexport type SelectionRange = {\n start: number;\n startOffset: number;\n end: number;\n endOffset: number;\n};\n\nexport type selectionParam = {\n ranges: Array<SelectionRange>;\n};\n\nexport type selectionCallback = (p: selectionParam) => void;\n\nexport type customElementParam = {\n define?: {\n name: string;\n };\n};\n\nexport type customElementCallback = (c: customElementParam) => void;\n\n/**\n * @deprecated\n */\ninterface INode extends Node {\n __sn: serializedNodeWithId;\n}\n\nexport type DeprecatedMirror = {\n map: {\n [key: number]: INode;\n };\n getId: (n: Node) => number;\n getNode: (id: number) => INode | null;\n removeNodeFromMap: (n: Node) => void;\n has: (id: number) => boolean;\n reset: () => void;\n};\n\nexport type throttleOptions = {\n leading?: boolean;\n trailing?: boolean;\n};\n\nexport type listenerHandler = () => void;\nexport type hookResetter = () => void;\n\nexport type playerMetaData = {\n startTime: number;\n endTime: number;\n totalTime: number;\n};\n\nexport type actionWithDelay = {\n doAction: () => void;\n delay: number;\n};\n\nexport type Handler = (event?: unknown) => void;\n\nexport type Emitter = {\n on(type: string, handler: Handler): void;\n emit(type: string, event?: unknown): void;\n off(type: string, handler: Handler): void;\n};\n\nexport type Arguments<T> = T extends (...payload: infer U) => unknown\n ? U\n : unknown;\n\nexport enum ReplayerEvents {\n Start = 'start',\n Pause = 'pause',\n /**\n * @deprecated use Play instead\n */\n Resume = 'resume',\n Resize = 'resize',\n Finish = 'finish',\n FullsnapshotRebuilded = 'fullsnapshot-rebuilded',\n LoadStylesheetStart = 'load-stylesheet-start',\n LoadStylesheetEnd = 'load-stylesheet-end',\n SkipStart = 'skip-start',\n SkipEnd = 'skip-end',\n MouseInteraction = 'mouse-interaction',\n EventCast = 'event-cast',\n CustomEvent = 'custom-event',\n Flush = 'flush',\n StateChange = 'state-change',\n PlayBack = 'play-back',\n Destroy = 'destroy',\n}\n\nexport type KeepIframeSrcFn = (src: string) => boolean;\n\ndeclare global {\n interface Window {\n FontFace: typeof FontFace;\n }\n}\n\nexport type IWindow = Window & typeof globalThis;\n\nexport type Optional<T, K extends keyof T> = Pick<Partial<T>, K> & Omit<T, K>;\n\nexport type GetTypedKeys<Obj extends object, ValueType> = TakeTypeHelper<\n Obj,\n ValueType\n>[keyof TakeTypeHelper<Obj, ValueType>];\nexport type TakeTypeHelper<Obj extends object, ValueType> = {\n [K in keyof Obj]: Obj[K] extends ValueType ? K : never;\n};\n\nexport type TakeTypedKeyValues<Obj extends object, Type> = Pick<\n Obj,\n TakeTypeHelper<Obj, Type>[keyof TakeTypeHelper<Obj, Type>]\n>;\n\nexport enum NodeType {\n Document,\n DocumentType,\n Element,\n Text,\n CDATA,\n Comment,\n}\n\nexport type documentNode = {\n type: NodeType.Document;\n childNodes: serializedNodeWithId[];\n compatMode?: string;\n};\n\nexport type documentTypeNode = {\n type: NodeType.DocumentType;\n name: string;\n publicId: string;\n systemId: string;\n};\n\ntype cssTextKeyAttr = {\n _cssText?: string;\n};\n\nexport type attributes = cssTextKeyAttr & {\n [key: string]:\n | string\n | number // properties e.g. rr_scrollLeft or rr_mediaCurrentTime\n | true // e.g. checked on <input type=\"radio\">\n | null; // an indication that an attribute was removed (during a mutation)\n};\n\nexport type legacyAttributes = {\n /**\n * @deprecated old bug in rrweb was causing these to always be set\n * @see https://github.com/rrweb-io/rrweb/pull/651\n */\n selected: false;\n};\n\nexport type mediaAttributes = {\n rr_mediaState: 'played' | 'paused';\n rr_mediaCurrentTime: number;\n /**\n * for backwards compatibility this is optional but should always be set\n */\n rr_mediaPlaybackRate?: number;\n /**\n * for backwards compatibility this is optional but should always be set\n */\n rr_mediaMuted?: boolean;\n /**\n * for backwards compatibility this is optional but should always be set\n */\n rr_mediaLoop?: boolean;\n /**\n * for backwards compatibility this is optional but should always be set\n */\n rr_mediaVolume?: number;\n};\n\nexport type elementNode = {\n type: NodeType.Element;\n tagName: string;\n attributes: attributes;\n childNodes: serializedNodeWithId[];\n isSVG?: true;\n needBlock?: boolean;\n // This is a custom element or not.\n isCustom?: true;\n};\n\nexport type textNode = {\n type: NodeType.Text;\n textContent: string;\n /**\n * @deprecated styles are now always snapshotted against parent <style> element\n * style mutations can still happen via an added textNode, but they don't need this attribute for correct replay\n */\n isStyle?: true;\n};\n\nexport type cdataNode = {\n type: NodeType.CDATA;\n textContent: '';\n};\n\nexport type commentNode = {\n type: NodeType.Comment;\n textContent: string;\n};\n\nexport type serializedNode = (\n | documentNode\n | documentTypeNode\n | elementNode\n | textNode\n | cdataNode\n | commentNode\n) & {\n rootId?: number;\n isShadowHost?: boolean;\n isShadow?: boolean;\n};\n\nexport type serializedNodeWithId = serializedNode & { id: number };\n\nexport type serializedElementNodeWithId = Extract<\n serializedNodeWithId,\n Record<'type', NodeType.Element>\n>;\n\nexport interface IMirror<TNode> {\n getId(n: TNode | undefined | null): number;\n\n getNode(id: number): TNode | null;\n\n getIds(): number[];\n\n getMeta(n: TNode): serializedNodeWithId | null;\n\n removeNodeFromMap(n: TNode): void;\n\n has(id: number): boolean;\n\n hasNode(node: TNode): boolean;\n\n add(n: TNode, meta: serializedNodeWithId): void;\n\n replace(id: number, n: TNode): void;\n\n reset(): void;\n}\n\nexport type DataURLOptions = Partial<{\n type: string;\n quality: number;\n maxBase64ImageLength: number;\n}>;\n\n// Types for @rrweb/packer\nexport type PackFn = (event: eventWithTime) => string;\nexport type UnpackFn = (raw: string) => eventWithTime;\n","// Recorder browser detection. Original license terms are retained in THIRD_PARTY_NOTICES.txt.\nexport function includes(str: string, needle: string): boolean\nexport function includes<T>(arr: T[], needle: T): boolean\nexport function includes(str: unknown[] | string, needle: unknown): boolean {\n return (str as any).indexOf(needle) !== -1\n}\n\nexport function isWebKit(userAgent: string): boolean {\n return includes(userAgent, 'AppleWebKit') && !includes(userAgent, 'Chrome')\n}\n","// Modified by ELU. See NOTICE-ELU and THIRD_PARTY_NOTICES.txt.\n\n// Portions of this file are derived from getsentry/sentry-javascript\n// Copyright (c) 2012 Functional Software, Inc. dba Sentry\n// Licensed under the MIT License: https://github.com/getsentry/sentry-javascript/blob/develop/LICENSE\n\nimport { isWebKit } from './browser-detection';\n\ntype PrototypeOwner = Node | ShadowRoot | MutationObserver | Element;\ntype TypeofPrototypeOwner =\n | typeof Node\n | typeof ShadowRoot\n | typeof MutationObserver\n | typeof Element;\n\ntype BasePrototypeCache = {\n Node: typeof Node.prototype;\n ShadowRoot: typeof ShadowRoot.prototype;\n MutationObserver: typeof MutationObserver.prototype;\n Element: typeof Element.prototype;\n};\n\nconst testableAccessors = {\n Node: ['childNodes', 'parentNode', 'parentElement', 'textContent'] as const,\n ShadowRoot: ['host', 'styleSheets'] as const,\n Element: ['shadowRoot'] as const,\n MutationObserver: [] as const,\n} as const;\n\nconst testableMethods = {\n Node: ['contains', 'getRootNode'] as const,\n ShadowRoot: ['getSelection'],\n Element: ['querySelector', 'querySelectorAll'],\n MutationObserver: ['constructor'],\n} as const;\n\nconst untaintedBasePrototype: Partial<BasePrototypeCache> = {};\n\ntype WindowWithZone = typeof globalThis & {\n Zone?: {\n __symbol__?: (key: string) => string;\n };\n};\n\ntype WindowWithUnpatchedSymbols = typeof globalThis &\n Record<string, TypeofPrototypeOwner>;\n\n/*\nAngular zone patches many things and can pass the untainted checks below, causing performance issues\nAngular zone, puts the unpatched originals on the window, and the names for hose on the zone object.\nSo, we get the unpatched versions from the window object if they exist.\nYou can rename Zone, but this is a good enough proxy to avoid going to an iframe to get the untainted versions.\nsee: https://github.com/angular/angular/issues/26948\n*/\nfunction angularZoneUnpatchedAlternative(key: keyof BasePrototypeCache) {\n const angularUnpatchedVersionSymbol = (\n globalThis as WindowWithZone\n )?.Zone?.__symbol__?.(key);\n if (\n angularUnpatchedVersionSymbol &&\n (globalThis as WindowWithUnpatchedSymbols)[angularUnpatchedVersionSymbol]\n ) {\n return (globalThis as WindowWithUnpatchedSymbols)[\n angularUnpatchedVersionSymbol\n ];\n } else {\n return undefined;\n }\n}\n\nexport function getUntaintedPrototype<T extends keyof BasePrototypeCache>(\n key: T,\n): BasePrototypeCache[T] {\n if (untaintedBasePrototype[key])\n return untaintedBasePrototype[key] as BasePrototypeCache[T];\n\n const candidate =\n angularZoneUnpatchedAlternative(key) ||\n (globalThis[key] as TypeofPrototypeOwner);\n const defaultPrototype = candidate.prototype as BasePrototypeCache[T];\n\n // use list of testable accessors to check if the prototype is tainted\n const accessorNames =\n key in testableAccessors ? testableAccessors[key] : undefined;\n const isUntaintedAccessors = Boolean(\n accessorNames &&\n accessorNames.every((accessor) =>\n Boolean(\n Object.getOwnPropertyDescriptor(defaultPrototype, accessor)\n ?.get?.toString()\n .includes('[native code]'),\n ),\n ),\n );\n\n const methodNames = key in testableMethods ? testableMethods[key] : undefined;\n const isUntaintedMethods = Boolean(\n methodNames &&\n methodNames.every(\n // @ts-expect-error 2345\n (method: keyof typeof defaultPrototype) =>\n typeof defaultPrototype[method] === 'function' &&\n defaultPrototype[method]?.toString().includes('[native code]'),\n ),\n );\n\n if (isUntaintedAccessors && isUntaintedMethods) {\n untaintedBasePrototype[key] = candidate.prototype as BasePrototypeCache[T];\n return candidate.prototype as BasePrototypeCache[T];\n }\n\n const iframeEl = document.createElement('iframe');\n iframeEl.style.display = 'none';\n let keepIframeAttached = false;\n try {\n document.body.appendChild(iframeEl);\n const win = iframeEl.contentWindow;\n if (!win) return candidate.prototype as BasePrototypeCache[T];\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any\n const untaintedObject = (win as any)[key]\n .prototype as BasePrototypeCache[T];\n\n if (!untaintedObject) return defaultPrototype;\n\n // WebKit tears down an iframe's ScriptExecutionContext when it is detached\n // from the DOM, and MutationObserver.deliver() silently drops callbacks when\n // its scriptExecutionContext() is null (webkit.org/b/179224), so prototypes\n // taken from a detached iframe stop working on WebKit.\n // Adapted from upstream rrweb #1854, with one difference: the iframe stays\n // attached for the lifetime of the page instead of being removed on recorder\n // teardown. Observers are torn down per-document here (e.g. a same-origin\n // iframe being removed), and the cached prototype must outlive any one of\n // them; removing the shared iframe on the first teardown - or reusing the\n // cache after a stop/restart cycle - would silently break the survivors.\n if (isWebKit(navigator.userAgent)) {\n // Keep both the default and compatibility block classes so the recorder\n // never serializes this iframe, whichever configuration is in use.\n iframeEl.classList.add('rr-block', 'ph-no-capture');\n iframeEl.setAttribute('__rrwebUntaintedPrototype', key);\n keepIframeAttached = true;\n }\n\n return (untaintedBasePrototype[key] = untaintedObject);\n } catch {\n return defaultPrototype;\n } finally {\n if (!keepIframeAttached && iframeEl.parentNode) {\n document.body.removeChild(iframeEl);\n }\n }\n}\n\nconst untaintedAccessorCache: Record<\n string,\n (this: PrototypeOwner, ...args: unknown[]) => unknown\n> = {};\n\nexport function getUntaintedAccessor<\n K extends keyof BasePrototypeCache,\n T extends keyof BasePrototypeCache[K],\n>(\n key: K,\n instance: BasePrototypeCache[K],\n accessor: T,\n): BasePrototypeCache[K][T] {\n const cacheKey = `${key}.${String(accessor)}`;\n if (untaintedAccessorCache[cacheKey])\n return untaintedAccessorCache[cacheKey].call(\n instance,\n ) as BasePrototypeCache[K][T];\n\n const untaintedPrototype = getUntaintedPrototype(key);\n // eslint-disable-next-line @typescript-eslint/unbound-method\n const untaintedAccessor = Object.getOwnPropertyDescriptor(\n untaintedPrototype,\n accessor,\n )?.get;\n\n if (!untaintedAccessor) return instance[accessor];\n\n untaintedAccessorCache[cacheKey] = untaintedAccessor;\n\n return untaintedAccessor.call(instance) as BasePrototypeCache[K][T];\n}\n\ntype BaseMethod<K extends keyof BasePrototypeCache> = (\n this: BasePrototypeCache[K],\n ...args: unknown[]\n) => unknown;\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst untaintedMethodCache: Record<string, BaseMethod<any>> = {};\nexport function getUntaintedMethod<\n K extends keyof BasePrototypeCache,\n T extends keyof BasePrototypeCache[K],\n>(\n key: K,\n instance: BasePrototypeCache[K],\n method: T,\n): BasePrototypeCache[K][T] {\n const cacheKey = `${key}.${String(method)}`;\n if (untaintedMethodCache[cacheKey])\n return untaintedMethodCache[cacheKey].bind(\n instance,\n ) as BasePrototypeCache[K][T];\n\n const untaintedPrototype = getUntaintedPrototype(key);\n const untaintedMethod = untaintedPrototype[method];\n\n if (typeof untaintedMethod !== 'function') return instance[method];\n\n untaintedMethodCache[cacheKey] = untaintedMethod as BaseMethod<K>;\n\n return untaintedMethod.bind(instance) as BasePrototypeCache[K][T];\n}\n\nexport function childNodes(n: Node): NodeListOf<Node> {\n return getUntaintedAccessor('Node', n, 'childNodes');\n}\n\nexport function parentNode(n: Node): ParentNode | null {\n return getUntaintedAccessor('Node', n, 'parentNode');\n}\n\nexport function parentElement(n: Node): HTMLElement | null {\n return getUntaintedAccessor('Node', n, 'parentElement');\n}\n\nexport function textContent(n: Node): string | null {\n return getUntaintedAccessor('Node', n, 'textContent');\n}\n\nexport function contains(n: Node, other: Node): boolean {\n return getUntaintedMethod('Node', n, 'contains')(other);\n}\n\nexport function getRootNode(n: Node): Node {\n return getUntaintedMethod('Node', n, 'getRootNode')();\n}\n\nexport function host(n: ShadowRoot): Element | null {\n if (!n || !('host' in n)) return null;\n return getUntaintedAccessor('ShadowRoot', n, 'host');\n}\n\nexport function styleSheets(n: ShadowRoot): StyleSheetList {\n return n.styleSheets;\n}\n\nexport function shadowRoot(n: Node): ShadowRoot | null {\n if (!n || !('shadowRoot' in n)) return null;\n return getUntaintedAccessor('Element', n as Element, 'shadowRoot');\n}\n\nexport function querySelector(n: Element, selectors: string): Element | null {\n return getUntaintedMethod('Element', n, 'querySelector')(selectors);\n}\n\nexport function querySelectorAll(\n n: Element,\n selectors: string,\n): NodeListOf<Element> {\n return getUntaintedMethod('Element', n, 'querySelectorAll')(selectors);\n}\n\nexport function mutationObserverCtor(): (typeof MutationObserver)['prototype']['constructor'] {\n return getUntaintedPrototype('MutationObserver').constructor;\n}\n\n// Each call to `patch` installs a \"layer\" in the wrapper chain. A wrapper calls\n// down through its layer's mutable `next` reference rather than closing over the\n// original directly, so that any layer can later be spliced out of the chain —\n// even when newer wrappers sit on top of it.\n//\n// Without this, restoring a patch only worked when it was still on top of the\n// chain (`source[name] === wrapped`). rrweb patches shared globals such as\n// `Element.prototype.attachShadow` (shadow-dom-manager) and the observers, and\n// multiple recorder instances or repeated start/stop cycles wrap the same global\n// more than once. Restores then routinely ran out of order and silently no-op'd.\n// Each leaked wrapper stayed in the call path, and repeated cycles grew the chain\n// without bound until a real call walked a chain deep enough to overflow the call\n// stack (\"RangeError: Maximum call stack size exceeded\").\ninterface PatchLayer {\n next: (...args: unknown[]) => unknown;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction isFunction(value: any): value is (...args: any[]) => any {\n return typeof value === 'function';\n}\n\n// copy from https://github.com/getsentry/sentry-javascript/blob/b2109071975af8bf0316d3b5b38f519bdaf5dc15/packages/utils/src/object.ts\nexport function patch(\n source: { [key: string]: any },\n name: string,\n replacement: (...args: unknown[]) => unknown,\n): () => void {\n try {\n if (!(name in source)) {\n return () => {\n //\n };\n }\n\n const original = source[name] as (...args: unknown[]) => unknown;\n\n const layer: PatchLayer = {\n next: original,\n };\n\n // The wrapper receives this stable delegate instead of `original`, so the\n // function it actually calls can be re-pointed when a lower layer is removed.\n const callNext = function (this: unknown, ...args: unknown[]) {\n return layer.next.apply(this, args);\n };\n\n const wrapped = replacement(callNext);\n\n // Make sure it's a function first, as we need to attach an empty prototype for `defineProperties` to work\n // otherwise it'll throw \"TypeError: Object.defineProperties called on non-object\"\n if (typeof wrapped === 'function') {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n wrapped.prototype = wrapped.prototype || {};\n Object.defineProperties(wrapped, {\n __rrweb_original__: {\n enumerable: false,\n value: original,\n },\n __rrweb_layer__: {\n enumerable: false,\n value: layer,\n },\n });\n }\n\n source[name] = wrapped;\n\n return () => {\n // If we're still on top, hand back whatever we currently delegate to\n // (lower layers may already have been removed, so this is not necessarily\n // the `original` we captured at install time).\n if (source[name] === wrapped) {\n source[name] = layer.next;\n return;\n }\n\n // Otherwise newer wrappers sit on top of us. Find the rrweb layer directly\n // above us and re-point it past us, removing our wrapper from the call path\n // without disturbing the newer wrappers.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let current: any = source[name];\n while (isFunction(current) && (current as any).__rrweb_layer__) {\n const currentLayer = (current as any).__rrweb_layer__ as PatchLayer;\n if (currentLayer.next === wrapped) {\n currentLayer.next = layer.next;\n return;\n }\n current = currentLayer.next;\n }\n\n // If we get here we're buried under a non-rrweb wrapper that closed over\n // us directly, or we've already been removed / replaced wholesale. There's\n // nothing safe to do, so leave the chain untouched.\n };\n } catch {\n return () => {\n //\n };\n // This can throw when multiple instrumentation layers try to wrap the same global object,\n // such as XMLHttpRequest, and redefine the same non-configurable wrapper marker.\n }\n}\n\nexport default {\n childNodes,\n parentNode,\n parentElement,\n textContent,\n contains,\n getRootNode,\n host,\n styleSheets,\n shadowRoot,\n querySelector,\n querySelectorAll,\n mutationObserver: mutationObserverCtor,\n patch,\n};\n","// Modified by ELU. See NOTICE-ELU and THIRD_PARTY_NOTICES.txt.\n\nimport type {\n idNodeMap,\n MaskInputFn,\n MaskInputOptions,\n nodeMetaMap,\n} from './types';\n\nimport { NodeType } from '@elu-labs/recorder-types';\nimport type {\n IMirror,\n serializedNodeWithId,\n serializedNode,\n documentNode,\n documentTypeNode,\n textNode,\n elementNode,\n} from '@elu-labs/recorder-types';\nimport dom from '@elu-labs/recorder-utils';\n\nexport function isElement(n: Node): n is Element {\n return n.nodeType === n.ELEMENT_NODE;\n}\n\nexport function isShadowRoot(n: Node): n is ShadowRoot {\n const hostEl: Element | null =\n // anchor and textarea elements also have a `host` property\n // but only shadow roots have a `mode` property\n (n && 'host' in n && 'mode' in n && dom.host(n as ShadowRoot)) || null;\n return Boolean(\n hostEl && 'shadowRoot' in hostEl && dom.shadowRoot(hostEl) === n,\n );\n}\n\n/**\n * To fix the issue https://github.com/rrweb-io/rrweb/issues/933.\n * Some websites use polyfilled shadow dom and this function is used to detect this situation.\n */\nexport function isNativeShadowDom(shadowRoot: ShadowRoot): boolean {\n return Object.prototype.toString.call(shadowRoot) === '[object ShadowRoot]';\n}\n\n/**\n * Browsers sometimes destructively modify the css rules they receive.\n * This function tries to rectify the modifications the browser made to make it more cross platform compatible.\n * @param cssText - output of `CSSStyleRule.cssText`\n * @returns `cssText` with browser inconsistencies fixed.\n */\nfunction fixBrowserCompatibilityIssuesInCSS(cssText: string): string {\n /**\n * Chrome outputs `-webkit-background-clip` as `background-clip` in `CSSStyleRule.cssText`.\n * But then Chrome ignores `background-clip` as css input.\n * Re-introduce `-webkit-background-clip` to fix this issue.\n */\n if (\n cssText.includes(' background-clip: text;') &&\n !cssText.includes(' -webkit-background-clip: text;')\n ) {\n cssText = cssText.replace(\n /\\sbackground-clip:\\s*text;/g,\n ' -webkit-background-clip: text; background-clip: text;',\n );\n }\n return cssText;\n}\n\n// Remove this declaration once typescript has added `CSSImportRule.supportsText` to the lib.\ndeclare interface CSSImportRule extends CSSRule {\n readonly href: string;\n readonly layerName: string | null;\n readonly media: MediaList;\n readonly styleSheet: CSSStyleSheet;\n /**\n * experimental API, currently only supported in firefox\n * https://developer.mozilla.org/en-US/docs/Web/API/CSSImportRule/supportsText\n */\n readonly supportsText?: string | null;\n}\n\n/**\n * Browsers sometimes incorrectly escape `@import` on `.cssText` statements.\n * This function tries to correct the escaping.\n * more info: https://bugs.chromium.org/p/chromium/issues/detail?id=1472259\n * @param cssImportRule\n * @returns `cssText` with browser inconsistencies fixed, or null if not applicable.\n */\nexport function escapeImportStatement(rule: CSSImportRule): string {\n const { cssText } = rule;\n if (cssText.split('\"').length < 3) return cssText;\n\n const statement = ['@import', `url(${JSON.stringify(rule.href)})`];\n if (rule.layerName === '') {\n statement.push(`layer`);\n } else if (rule.layerName) {\n statement.push(`layer(${rule.layerName})`);\n }\n if (rule.supportsText) {\n statement.push(`supports(${rule.supportsText})`);\n }\n if (rule.media.length) {\n statement.push(rule.media.mediaText);\n }\n return statement.join(' ') + ';';\n}\n\n/**\n * Detects empty property values produced by browser CSSOM serialization of\n * shorthands that contain `var()`. When a stylesheet has e.g.\n *\n * .card { padding: var(--p); padding-bottom: var(--pb); }\n *\n * browsers store the shorthand's longhands with empty token lists per the\n * CSS Custom Properties spec, and `CSSStyleRule.cssText` re-emits them as\n * `padding-top: ; padding-right: ; padding-left: ;`. That output silently\n * strips the layout from the rule on replay. Same class of bug as\n * rrweb-io/rrweb#1667. Custom properties (`--foo: ;`) are intentionally\n * allowed to be empty and are excluded.\n */\nexport function hasEmptyShorthandLonghand(css: string): boolean {\n // The optional leading `-` admits vendor-prefixed longhands\n // (e.g. `-webkit-mask-image: ;`) while still excluding custom\n // properties (`--foo: ;`), since the second char must be a letter.\n return /(?:^|[\\s;{}])-?[a-zA-Z][\\w-]*\\s*:\\s*;/.test(css);\n}\n\nexport function stringifyStylesheet(s: CSSStyleSheet): string | null {\n try {\n const rules = s.rules || s.cssRules;\n if (!rules) {\n return null;\n }\n let sheetHref = s.href;\n if (!sheetHref && s.ownerNode) {\n // an inline <style> element\n sheetHref = s.ownerNode.baseURI;\n }\n const stringifiedRules = Array.from(rules, (rule: CSSRule) =>\n stringifyRule(rule, sheetHref),\n ).join('');\n return fixBrowserCompatibilityIssuesInCSS(stringifiedRules);\n } catch (error) {\n return null;\n }\n}\n\nexport function stringifyRule(rule: CSSRule, sheetHref: string | null): string {\n if (isCSSImportRule(rule)) {\n let importStringified;\n try {\n importStringified =\n // for same-origin stylesheets,\n // we can access the imported stylesheet rules directly\n stringifyStylesheet(rule.styleSheet) ||\n // work around browser issues with the raw string `@import url(...)` statement\n escapeImportStatement(rule);\n } catch (error) {\n importStringified = rule.cssText;\n }\n // if importStringified is not null,\n // there should be a stylesheet and a rule here,\n // but we avoid errors in this method by checking for null\n // see https://github.com/rrweb-io/rrweb/pull/1686\n try {\n if (importStringified && rule.styleSheet?.href) {\n // url()s within the imported stylesheet are relative to _that_ sheet's href\n return absolutifyURLs(importStringified, rule.styleSheet.href);\n }\n } catch {\n // swallow this, we'll return null\n }\n return importStringified;\n } else {\n let ruleStringified = rule.cssText;\n if (isCSSStyleRule(rule) && rule.selectorText.includes(':')) {\n // Safari does not escape selectors with : properly\n // see https://bugs.webkit.org/show_bug.cgi?id=184604\n ruleStringified = fixSafariColons(ruleStringified);\n }\n if (sheetHref) {\n return absolutifyURLs(ruleStringified, sheetHref);\n }\n return ruleStringified;\n }\n}\n\nexport function fixSafariColons(cssStringified: string): string {\n // Replace e.g. [aa:bb] with [aa\\\\:bb]\n const regex = /(\\[(?:[\\w-]+)[^\\\\])(:(?:[\\w-]+)\\])/gm;\n return cssStringified.replace(regex, '$1\\\\$2');\n}\n\nexport function isCSSImportRule(rule: CSSRule): rule is CSSImportRule {\n return 'styleSheet' in rule;\n}\n\nexport function isCSSStyleRule(rule: CSSRule): rule is CSSStyleRule {\n return 'selectorText' in rule;\n}\n\nexport class Mirror implements IMirror<Node> {\n private idNodeMap: idNodeMap = new Map();\n private nodeMetaMap: nodeMetaMap = new WeakMap();\n\n getId(n: Node | undefined | null): number {\n if (!n) return -1;\n\n const id = this.getMeta(n)?.id;\n\n // if n is not a serialized Node, use -1 as its id.\n return id ?? -1;\n }\n\n getNode(id: number): Node | null {\n return this.idNodeMap.get(id) || null;\n }\n\n getIds(): number[] {\n return Array.from(this.idNodeMap.keys());\n }\n\n getMeta(n: Node): serializedNodeWithId | null {\n return this.nodeMetaMap.get(n) || null;\n }\n\n // removes the node from idNodeMap\n // doesn't remove the node from nodeMetaMap\n removeNodeFromMap(n: Node) {\n const id = this.getId(n);\n this.idNodeMap.delete(id);\n\n if (n.childNodes) {\n n.childNodes.forEach((childNode) =>\n this.removeNodeFromMap(childNode as unknown as Node),\n );\n }\n\n if (isElement(n)) {\n const shadowRootEl = dom.shadowRoot(n);\n if (shadowRootEl) {\n this.removeNodeFromMap(shadowRootEl as unknown as Node);\n }\n\n if (n.nodeName === 'IFRAME' && (n as HTMLIFrameElement).contentDocument) {\n this.removeNodeFromMap(\n (n as HTMLIFrameElement).contentDocument as unknown as Node,\n );\n }\n }\n }\n has(id: number): boolean {\n return this.idNodeMap.has(id);\n }\n\n hasNode(node: Node): boolean {\n return this.nodeMetaMap.has(node);\n }\n\n add(n: Node, meta: serializedNodeWithId) {\n const id = meta.id;\n this.idNodeMap.set(id, n);\n this.nodeMetaMap.set(n, meta);\n }\n\n replace(id: number, n: Node) {\n const oldNode = this.getNode(id);\n if (oldNode) {\n const meta = this.nodeMetaMap.get(oldNode);\n if (meta) this.nodeMetaMap.set(n, meta);\n }\n this.idNodeMap.set(id, n);\n }\n\n reset() {\n this.idNodeMap = new Map();\n this.nodeMetaMap = new WeakMap();\n }\n}\n\nexport function createMirror(): Mirror {\n return new Mirror();\n}\n\nexport function maskInputValue({\n element,\n maskInputOptions,\n tagName,\n type,\n value,\n maskInputFn,\n}: {\n element: HTMLElement;\n maskInputOptions: MaskInputOptions;\n tagName: string;\n type: string | null;\n value: string | null;\n maskInputFn?: MaskInputFn;\n}): string {\n let text = value || '';\n const actualType = type && toLowerCase(type);\n\n if (\n maskInputOptions[tagName.toLowerCase() as keyof MaskInputOptions] ||\n (actualType && maskInputOptions[actualType as keyof MaskInputOptions])\n ) {\n if (maskInputFn) {\n text = maskInputFn(text, element);\n } else {\n text = '*'.repeat(text.length);\n }\n }\n return text;\n}\n\nexport function toLowerCase<T extends string>(str: T): Lowercase<T> {\n return str.toLowerCase() as unknown as Lowercase<T>;\n}\n\nconst ORIGINAL_ATTRIBUTE_NAME = '__rrweb_original__';\ntype PatchedGetImageData = {\n [ORIGINAL_ATTRIBUTE_NAME]: CanvasImageData['getImageData'];\n} & CanvasImageData['getImageData'];\n\nexport function is2DCanvasBlank(canvas: HTMLCanvasElement): boolean {\n const ctx = canvas.getContext('2d');\n if (!ctx) return true;\n\n const chunkSize = 50;\n\n // get chunks of the canvas and check if it is blank\n for (let x = 0; x < canvas.width; x += chunkSize) {\n for (let y = 0; y < canvas.height; y += chunkSize) {\n // eslint-disable-next-line @typescript-eslint/unbound-method\n const getImageData = ctx.getImageData as PatchedGetImageData;\n const originalGetImageData =\n ORIGINAL_ATTRIBUTE_NAME in getImageData\n ? getImageData[ORIGINAL_ATTRIBUTE_NAME]\n : getImageData;\n // by getting the canvas in chunks we avoid an expensive\n // `getImageData` call that retrieves everything\n // even if we can already tell from the first chunk(s) that\n // the canvas isn't blank\n const pixelBuffer = new Uint32Array(\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-member-access\n originalGetImageData.call(\n ctx,\n x,\n y,\n Math.min(chunkSize, canvas.width - x),\n Math.min(chunkSize, canvas.height - y),\n ).data.buffer,\n );\n if (pixelBuffer.some((pixel) => pixel !== 0)) return false;\n }\n }\n return true;\n}\n\nexport function isNodeMetaEqual(a: serializedNode, b: serializedNode): boolean {\n if (!a || !b || a.type !== b.type) return false;\n if (a.type === NodeType.Document)\n return a.compatMode === (b as documentNode).compatMode;\n else if (a.type === NodeType.DocumentType)\n return (\n a.name === (b as documentTypeNode).name &&\n a.publicId === (b as documentTypeNode).publicId &&\n a.systemId === (b as documentTypeNode).systemId\n );\n else if (\n a.type === NodeType.Comment ||\n a.type === NodeType.Text ||\n a.type === NodeType.CDATA\n )\n return a.textContent === (b as textNode).textContent;\n else if (a.type === NodeType.Element)\n return (\n a.tagName === (b as elementNode).tagName &&\n JSON.stringify(a.attributes) ===\n JSON.stringify((b as elementNode).attributes) &&\n a.isSVG === (b as elementNode).isSVG &&\n a.needBlock === (b as elementNode).needBlock\n );\n return false;\n}\n\n/**\n * Get the type of an input element.\n * This takes care of the case where a password input is changed to a text input.\n * In this case, we continue to consider this of type password, in order to avoid leaking sensitive data\n * where passwords should be masked.\n */\nexport function getInputType(element: HTMLElement): Lowercase<string> | null {\n try {\n // when omitting the type of input element(e.g. <input />), the type is treated as text\n const type = (element as HTMLInputElement).type;\n\n return element.hasAttribute('data-rr-is-password')\n ? 'password'\n : type\n ? // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion\n toLowerCase(type)\n : null;\n } catch {\n // reading the native `type` accessor / `hasAttribute` on a non-native\n // `this` (a proxy or cross-realm object) throws 'Illegal invocation';\n // treat it as an untyped element rather than letting the error propagate\n return null;\n }\n}\n\n/**\n * Extracts the file extension from an a path, considering search parameters and fragments.\n * @param path - Path to file\n * @param baseURL - [optional] Base URL of the page, used to resolve relative paths. Defaults to current page URL.\n */\nexport function extractFileExtension(\n path: string,\n baseURL?: string,\n): string | null {\n let url;\n try {\n url = new URL(path, baseURL ?? window.location.href);\n } catch (err) {\n return null;\n }\n const regex = /\\.([0-9a-z]+)(?:$)/i;\n const match = url.pathname.match(regex);\n return match?.[1] ?? null;\n}\n\nfunction extractOrigin(url: string): string {\n let origin = '';\n if (url.indexOf('//') > -1) {\n origin = url.split('/').slice(0, 3).join('/');\n } else {\n origin = url.split('/')[0];\n }\n origin = origin.split('?')[0];\n return origin;\n}\n\nconst URL_IN_CSS_REF = /url\\((?:(')([^']*)'|(\")(.*?)\"|([^)]*))\\)/gm;\nconst URL_PROTOCOL_MATCH = /^(?:[a-z+]+:)?\\/\\//i;\nconst URL_WWW_MATCH = /^www\\..*/i;\nconst DATA_URI = /^(data:)([^,]*),(.*)/i;\nexport function absolutifyURLs(cssText: string | null, href: string): string {\n // codeql[js/polynomial-redos] Bounded CSS text; worst case is recorder slowdown, no exploit.\n return (cssText || '').replace(\n URL_IN_CSS_REF,\n (\n origin: string,\n quote1: string,\n path1: string,\n quote2: string,\n path2: string,\n path3: string,\n ) => {\n const filePath = path1 || path2 || path3;\n const maybeQuote = quote1 || quote2 || '';\n if (!filePath) {\n return origin;\n }\n if (URL_PROTOCOL_MATCH.test(filePath) || URL_WWW_MATCH.test(filePath)) {\n return `url(${maybeQuote}${filePath}${maybeQuote})`;\n }\n if (DATA_URI.test(filePath)) {\n return `url(${maybeQuote}${filePath}${maybeQuote})`;\n }\n if (filePath[0] === '/') {\n return `url(${maybeQuote}${\n extractOrigin(href) + filePath\n }${maybeQuote})`;\n }\n const stack = href.split('/');\n const parts = filePath.split('/');\n stack.pop();\n for (const part of parts) {\n if (part === '.') {\n continue;\n } else if (part === '..') {\n stack.pop();\n } else {\n stack.push(part);\n }\n }\n return `url(${maybeQuote}${stack.join('/')}${maybeQuote})`;\n },\n );\n}\n\nconst STRIPED_PLACEHOLDER_SVG =\n 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgogIDxkZWZzPgogICAgPHBhdHRlcm4gaWQ9InN0cmlwZXMiIHBhdHRlcm5Vbml0cz0idXNlclNwYWNlT25Vc2UiIHdpZHRoPSIxNiIgaGVpZ2h0PSIxNiI+CiAgICAgIDxyZWN0IHdpZHRoPSIxNiIgaGVpZ2h0PSIxNiIgZmlsbD0iYmxhY2siLz4KICAgICAgPHBhdGggZD0iTTggMEgxNkwwIDE2VjhMOCAwWiIgZmlsbD0iIzJEMkQyRCIvPgogICAgICA8cGF0aCBkPSJNMTYgOFYxNkg4TDE2IDhaIiBmaWxsPSIjMkQyRDJEIi8+CiAgICA8L3BhdHRlcm4+CiAgPC9kZWZzPgogIDxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjc3RyaXBlcykiLz4KPC9zdmc+Cg==';\n\nconst MAX_IMAGE_DIMENSION_FOR_RECOMPRESSION = 4096;\n\nexport function recompressBase64Image(\n img: HTMLImageElement,\n dataURL: string,\n type?: string,\n quality?: number,\n): string {\n if (!img.complete || img.naturalWidth === 0) {\n return dataURL;\n }\n\n // don't recompress very large images to avoid performance issues\n if (\n img.naturalWidth > MAX_IMAGE_DIMENSION_FOR_RECOMPRESSION ||\n img.naturalHeight > MAX_IMAGE_DIMENSION_FOR_RECOMPRESSION\n ) {\n return dataURL;\n }\n\n try {\n const canvas = document.createElement('canvas');\n canvas.width = img.naturalWidth;\n canvas.height = img.naturalHeight;\n const ctx = canvas.getContext('2d');\n\n if (!ctx) {\n return dataURL;\n }\n\n ctx.drawImage(img, 0, 0);\n const recompressed = canvas.toDataURL(type || 'image/webp', quality ?? 0.4);\n\n return recompressed;\n } catch (err) {\n return dataURL;\n }\n}\n\nexport function checkDataURLSize(\n dataURL: string,\n maxLength: number | undefined,\n): string {\n if (!maxLength || dataURL.length <= maxLength) {\n return dataURL;\n }\n\n return STRIPED_PLACEHOLDER_SVG;\n}\n","// Modified by ELU. See NOTICE-ELU and THIRD_PARTY_NOTICES.txt.\n\nimport type {\n MaskInputOptions,\n SlimDOMOptions,\n MaskTextFn,\n MaskInputFn,\n KeepIframeSrcFn,\n ICanvas,\n DialogAttributes,\n} from './types';\nimport { NodeType } from '@elu-labs/recorder-types';\nimport type {\n serializedNode,\n serializedNodeWithId,\n serializedElementNodeWithId,\n elementNode,\n attributes,\n mediaAttributes,\n DataURLOptions,\n} from '@elu-labs/recorder-types';\nimport {\n Mirror,\n is2DCanvasBlank,\n isElement,\n isShadowRoot,\n maskInputValue,\n isNativeShadowDom,\n stringifyStylesheet,\n hasEmptyShorthandLonghand,\n getInputType,\n toLowerCase,\n extractFileExtension,\n checkDataURLSize,\n recompressBase64Image,\n absolutifyURLs,\n} from './utils';\nimport dom from '@elu-labs/recorder-utils';\n\nlet _id = 1;\nconst tagNameRegex = new RegExp('[^a-z0-9-_:]');\n\nexport const IGNORED_NODE = -2;\n\nexport function genId(): number {\n return _id++;\n}\n\nfunction getValidTagName(element: HTMLElement): Lowercase<string> {\n if (element instanceof HTMLFormElement) {\n return 'form';\n }\n\n const processedTagName = toLowerCase(element.tagName);\n\n if (tagNameRegex.test(processedTagName)) {\n // if the tag name is odd and we cannot extract\n // anything from the string, then we return a\n // generic div\n return 'div';\n }\n\n return processedTagName;\n}\n\nlet canvasService: HTMLCanvasElement | null;\nlet canvasCtx: CanvasRenderingContext2D | null;\n\n// eslint-disable-next-line no-control-regex\nconst SRCSET_NOT_SPACES = /^[^ \\t\\n\\r\\u000c]+/; // Don't use \\s, to avoid matching non-breaking space\n// eslint-disable-next-line no-control-regex\nconst SRCSET_COMMAS_OR_SPACES = /^[, \\t\\n\\r\\u000c]+/;\n\nfunction getAbsoluteSrcsetString(doc: Document, attributeValue: string) {\n /*\n run absoluteToDoc over every url in the srcset\n\n this is adapted from https://github.com/albell/parse-srcset/\n without the parsing of the descriptors (we return these as-is)\n parce-srcset is in turn based on\n https://html.spec.whatwg.org/multipage/embedded-content.html#parse-a-srcset-attribute\n */\n if (attributeValue.trim() === '') {\n return attributeValue;\n }\n\n let pos = 0;\n\n function collectCharacters(regEx: RegExp) {\n let chars: string;\n const match = regEx.exec(attributeValue.substring(pos));\n if (match) {\n chars = match[0];\n pos += chars.length;\n return chars;\n }\n return '';\n }\n\n const output = [];\n // eslint-disable-next-line no-constant-condition\n while (true) {\n collectCharacters(SRCSET_COMMAS_OR_SPACES);\n if (pos >= attributeValue.length) {\n break;\n }\n // don't split on commas within urls\n let url = collectCharacters(SRCSET_NOT_SPACES);\n if (url.slice(-1) === ',') {\n // aside: according to spec more than one comma at the end is a parse error, but we ignore that\n url = absoluteToDoc(doc, url.substring(0, url.length - 1));\n // the trailing comma splits the srcset, so the interpretion is that\n // another url will follow, and the descriptor is empty\n output.push(url);\n } else {\n let descriptorsStr = '';\n url = absoluteToDoc(doc, url);\n let inParens = false;\n // eslint-disable-next-line no-constant-condition\n while (true) {\n const c = attributeValue.charAt(pos);\n if (c === '') {\n output.push((url + descriptorsStr).trim());\n break;\n } else if (!inParens) {\n if (c === ',') {\n pos += 1;\n output.push((url + descriptorsStr).trim());\n break; // parse the next url\n } else if (c === '(') {\n inParens = true;\n }\n } else {\n // in parenthesis; ignore commas\n // (parenthesis may be supported by future additions to spec)\n if (c === ')') {\n inParens = false;\n }\n }\n descriptorsStr += c;\n pos += 1;\n }\n }\n }\n return output.join(', ');\n}\n\nconst cachedDocument = new WeakMap<Document, HTMLAnchorElement>();\n\nexport function absoluteToDoc(doc: Document, attributeValue: string): string {\n if (!attributeValue || attributeValue.trim() === '') {\n return attributeValue;\n }\n\n return getHref(doc, attributeValue);\n}\n\nfunction isSVGElement(el: Element): boolean {\n return Boolean(el.tagName === 'svg' || (el as SVGElement).ownerSVGElement);\n}\n\nfunction getHref(doc: Document, customHref?: string) {\n let a = cachedDocument.get(doc);\n if (!a) {\n a = doc.createElement('a');\n cachedDocument.set(doc, a);\n }\n if (!customHref) {\n customHref = '';\n } else if (customHref.startsWith('blob:') || customHref.startsWith('data:')) {\n return customHref;\n }\n // note: using `new URL` is slower. See #1434 or https://jsbench.me/uqlud17rxo/1\n // codeql[js/xss-through-dom] Detached <a>; only used to resolve URLs via the .href getter.\n a.setAttribute('href', customHref);\n return a.href;\n}\n\nfunction capDataURLSize(\n dataURL: string,\n dataURLOptions?: DataURLOptions,\n): string {\n if (dataURLOptions?.maxBase64ImageLength) {\n return checkDataURLSize(dataURL, dataURLOptions.maxBase64ImageLength);\n }\n return dataURL;\n}\n\nexport function transformAttribute(\n doc: Document,\n tagName: Lowercase<string>,\n name: Lowercase<string>,\n value: string | null,\n element?: HTMLElement,\n dataURLOptions?: DataURLOptions,\n): string | null {\n if (!value) {\n return value;\n }\n\n // relative path in attribute\n if (\n name === 'src' ||\n (name === 'href' && !(tagName === 'use' && value[0] === '#'))\n ) {\n // Prefer the loaded sheet's href — survives baseURI changes from SPA pushState.\n if (tagName === 'link' && element) {\n const sheetHref = (element as HTMLLinkElement).sheet?.href;\n if (sheetHref) {\n return sheetHref;\n }\n }\n // href starts with a # is an id pointer for svg\n const transformedValue = absoluteToDoc(doc, value);\n\n if (transformedValue.startsWith('data:')) {\n if (tagName === 'img' && element) {\n let processedDataURL = transformedValue;\n\n if (dataURLOptions?.type || dataURLOptions?.quality !== undefined) {\n processedDataURL = recompressBase64Image(\n element as HTMLImageElement,\n transformedValue,\n dataURLOptions.type,\n dataURLOptions.quality,\n );\n }\n\n return capDataURLSize(processedDataURL, dataURLOptions);\n }\n\n if (tagName === 'image') {\n return capDataURLSize(transformedValue, dataURLOptions);\n }\n }\n\n return transformedValue;\n } else if (name === 'xlink:href' && value[0] !== '#') {\n // xlink:href starts with # is an id pointer\n const transformedValue = absoluteToDoc(doc, value);\n if (tagName === 'image' && transformedValue.startsWith('data:')) {\n return capDataURLSize(transformedValue, dataURLOptions);\n }\n return transformedValue;\n } else if (\n name === 'background' &&\n (tagName === 'table' || tagName === 'td' || tagName === 'th')\n ) {\n return absoluteToDoc(doc, value);\n } else if (name === 'srcset') {\n return getAbsoluteSrcsetString(doc, value);\n } else if (name === 'style') {\n return absolutifyURLs(value, getHref(doc));\n } else if (tagName === 'object' && name === 'data') {\n return absoluteToDoc(doc, value);\n }\n\n return value;\n}\n\nexport function ignoreAttribute(\n tagName: string,\n name: string,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n _value: unknown,\n): boolean {\n return (tagName === 'video' || tagName === 'audio') && name === 'autoplay';\n}\n\nexport function _isBlockedElement(\n element: HTMLElement,\n blockClass: string | RegExp,\n blockSelector: string | null,\n): boolean {\n try {\n if (typeof blockClass === 'string') {\n if (element.classList.contains(blockClass)) {\n return true;\n }\n } else {\n for (let eIndex = element.classList.length; eIndex--; ) {\n const className = element.classList[eIndex];\n if (blockClass.test(className)) {\n return true;\n }\n }\n }\n if (blockSelector) {\n return element.matches(blockSelector);\n }\n } catch (e) {\n //\n }\n\n return false;\n}\n\nexport function classMatchesRegex(\n node: Node | null,\n regex: RegExp,\n checkAncestors: boolean,\n): boolean {\n if (!node) return false;\n if (node.nodeType !== node.ELEMENT_NODE) {\n if (!checkAncestors) return false;\n return classMatchesRegex(dom.parentNode(node), regex, checkAncestors);\n }\n\n for (let eIndex = (node as HTMLElement).classList.length; eIndex--; ) {\n const className = (node as HTMLElement).classList[eIndex];\n if (regex.test(className)) {\n return true;\n }\n }\n if (!checkAncestors) return false;\n return classMatchesRegex(dom.parentNode(node), regex, checkAncestors);\n}\n\nexport function needMaskingText(\n node: Node,\n maskTextClass: string | RegExp,\n maskTextSelector: string | null,\n checkAncestors: boolean,\n): boolean {\n let el: Element | null;\n if (isElement(node)) {\n el = node;\n // Shadow-only hosts still contain text in their composed subtree.\n if (!dom.childNodes(el).length && !dom.shadowRoot(el)) return false;\n } else {\n el = dom.parentElement(node);\n if (!el) {\n const parent = dom.parentNode(node);\n if (parent && isShadowRoot(parent)) el = dom.host(parent);\n }\n }\n try {\n while (el) {\n if (typeof maskTextClass === 'string') {\n if (\n checkAncestors\n ? el.closest(`.${maskTextClass}`)\n : el.classList.contains(maskTextClass)\n )\n return true;\n } else if (classMatchesRegex(el, maskTextClass, checkAncestors))\n return true;\n if (\n maskTextSelector &&\n (checkAncestors\n ? el.closest(maskTextSelector)\n : el.matches(maskTextSelector))\n )\n return true;\n if (!checkAncestors) return false;\n // closest() ends at a shadow root. Continue from its host, including nested roots.\n const root = dom.getRootNode(el);\n el = isShadowRoot(root) ? dom.host(root) : null;\n }\n } catch {\n // Invalid selectors retain the existing helper behavior; the owned adapter rejects them at start.\n }\n return false;\n}\n\n// Returns a disposer that removes the load listener and clears any pending\n// timer — call it if the iframe is detached before the listener fires.\n// https://stackoverflow.com/a/36155560\nfunction removeEventListenerSafely(\n target: Pick<EventTarget, 'removeEventListener'>,\n type: string,\n listener: EventListenerOrEventListenerObject,\n): void {\n const removeEventListener = target.removeEventListener;\n if (typeof removeEventListener !== 'function') return;\n removeEventListener.call(target, type, listener);\n}\n\nfunction onceIframeLoaded(\n iframeEl: HTMLIFrameElement,\n listener: () => unknown,\n iframeLoadTimeout: number,\n): () => void {\n const noop = () => {};\n const win = iframeEl.contentWindow;\n if (!win) {\n return noop;\n }\n let readyState: DocumentReadyState;\n try {\n readyState = win.document.readyState;\n } catch (error) {\n return noop;\n }\n\n // Re-fire on any later load so iframe.src navigations get their fresh\n // contentDocument serialized too. Used by both branches below.\n const onSubsequentLoad = () => listener();\n\n if (readyState !== 'complete') {\n let fired = false;\n let timer: ReturnType<typeof setTimeout> | null = null;\n const fireOnce = () => {\n if (fired) return;\n fired = true;\n if (timer !== null) {\n clearTimeout(timer);\n timer = null;\n }\n removeEventListenerSafely(iframeEl, 'load', onInitialLoad);\n iframeEl.addEventListener('load', onSubsequentLoad);\n listener();\n };\n const onInitialLoad = () => fireOnce();\n timer = setTimeout(fireOnce, iframeLoadTimeout);\n iframeEl.addEventListener('load', onInitialLoad);\n return () => {\n if (timer !== null) {\n clearTimeout(timer);\n timer = null;\n }\n if (fired) {\n removeEventListenerSafely(iframeEl, 'load', onSubsequentLoad);\n } else {\n fired = true;\n removeEventListenerSafely(iframeEl, 'load', onInitialLoad);\n }\n };\n }\n\n // readyState === 'complete' but Chrome reports about:blank during the\n // initial transition to a non-blank src; serializing now would emit the\n // blank doc and re-emit when the real load completes.\n const blankUrl = 'about:blank';\n let winLocationHref: string;\n try {\n winLocationHref = win.location.href;\n } catch {\n return noop;\n }\n if (\n winLocationHref !== blankUrl ||\n iframeEl.src === blankUrl ||\n iframeEl.src === ''\n ) {\n // Genuinely loaded — fire on the next tick so the host mutation that\n // surfaced this iframe has time to commit; also re-fire on later loads.\n const initialTimer = setTimeout(listener, 0);\n iframeEl.addEventListener('load', onSubsequentLoad);\n return () => {\n clearTimeout(initialTimer);\n removeEventListenerSafely(iframeEl, 'load', onSubsequentLoad);\n };\n }\n // Transient blank during navigation — wait for the real load.\n iframeEl.addEventListener('load', onSubsequentLoad);\n return () => {\n removeEventListenerSafely(iframeEl, 'load', onSubsequentLoad);\n };\n}\n\nconst stylesheetLoadTracked = new Map<HTMLLinkElement, { abort(): void }>();\n\nexport function resetStylesheetLoadTracking(): void {\n let failed = false;\n for (const controller of [...stylesheetLoadTracked.values()].reverse()) {\n try {\n controller.abort();\n } catch {\n failed = true;\n }\n }\n if (failed) {\n const error = new Error('Recorder stylesheet cleanup incomplete');\n error.name = 'RecorderCleanupError';\n throw error;\n }\n}\n\nfunction onceStylesheetLoaded(\n link: HTMLLinkElement,\n listener: () => unknown,\n styleSheetLoadTimeout: number,\n) {\n if (stylesheetLoadTracked.has(link)) return;\n let styleSheetLoaded: StyleSheet | null;\n try {\n styleSheetLoaded = link.sheet;\n } catch {\n return;\n }\n if (styleSheetLoaded) return;\n\n let closed = false;\n let fired = false;\n let failed = false;\n let installed = false;\n let timer: ReturnType<typeof setTimeout> | undefined;\n const controller = {\n abort() {\n closed = true;\n if (timer !== undefined) {\n const pending = timer;\n timer = undefined;\n try {\n clearTimeout(pending);\n } catch {\n failed = true;\n }\n }\n if (installed) {\n installed = false;\n try {\n link.removeEventListener('load', fire);\n } catch {\n failed = true;\n }\n }\n if (!failed && stylesheetLoadTracked.get(link) === controller)\n stylesheetLoadTracked.delete(link);\n if (failed) {\n const error = new Error('Recorder stylesheet cleanup incomplete');\n error.name = 'RecorderCleanupError';\n throw error;\n }\n },\n };\n const fire = () => {\n if (closed || fired) return;\n fired = true;\n try {\n listener();\n } finally {\n controller.abort();\n }\n };\n // Own the lease before the first host acquisition can throw. No delayed callback survives stop.\n stylesheetLoadTracked.set(link, controller);\n try {\n timer = setTimeout(fire, styleSheetLoadTimeout);\n installed = true;\n link.addEventListener('load', fire, { once: true });\n } catch (error) {\n controller.abort();\n throw error;\n }\n}\n\nfunction serializeNode(\n n: Node,\n options: {\n doc: Document;\n mirror: Mirror;\n blockClass: string | RegExp;\n blockSelector: string | null;\n needsMask: boolean;\n inlineStylesheet: boolean;\n maskInputOptions: MaskInputOptions;\n maskTextFn: MaskTextFn | undefined;\n maskInputFn: MaskInputFn | undefined;\n dataURLOptions?: DataURLOptions;\n inlineImages: boolean;\n recordCanvas: boolean;\n canvasMaskingConfigured: (() => boolean) | undefined;\n keepIframeSrcFn: KeepIframeSrcFn;\n /**\n * `newlyAddedElement: true` skips scrollTop and scrollLeft check\n */\n newlyAddedElement?: boolean;\n },\n): serializedNode | false {\n const {\n doc,\n mirror,\n blockClass,\n blockSelector,\n needsMask,\n inlineStylesheet,\n maskInputOptions = {},\n maskTextFn,\n maskInputFn,\n dataURLOptions = {},\n inlineImages,\n recordCanvas,\n canvasMaskingConfigured,\n keepIframeSrcFn,\n newlyAddedElement = false,\n } = options;\n // Only record root id when document object is not the base document\n const rootId = getRootId(doc, mirror);\n switch (n.nodeType) {\n case n.DOCUMENT_NODE:\n if ((n as Document).compatMode !== 'CSS1Compat') {\n return {\n type: NodeType.Document,\n childNodes: [],\n compatMode: (n as Document).compatMode, // probably \"BackCompat\"\n };\n } else {\n return {\n type: NodeType.Document,\n childNodes: [],\n };\n }\n case n.DOCUMENT_TYPE_NODE:\n return {\n type: NodeType.DocumentType,\n name: (n as DocumentType).name,\n publicId: (n as DocumentType).publicId,\n systemId: (n as DocumentType).systemId,\n rootId,\n };\n case n.ELEMENT_NODE:\n return serializeElementNode(n as HTMLElement, {\n doc,\n blockClass,\n blockSelector,\n inlineStylesheet,\n maskInputOptions,\n maskInputFn,\n dataURLOptions,\n inlineImages,\n recordCanvas,\n canvasMaskingConfigured,\n keepIframeSrcFn,\n newlyAddedElement,\n rootId,\n });\n case n.TEXT_NODE:\n return serializeTextNode(n as Text, {\n doc,\n needsMask,\n maskTextFn,\n rootId,\n });\n case n.CDATA_SECTION_NODE:\n return {\n type: NodeType.CDATA,\n textContent: '',\n rootId,\n };\n case n.COMMENT_NODE:\n return {\n type: NodeType.Comment,\n textContent: dom.textContent(n as Comment) || '',\n rootId,\n };\n default:\n return false;\n }\n}\n\nfunction getRootId(doc: Document, mirror: Mirror): number | undefined {\n if (!mirror.hasNode(doc)) return undefined;\n const docId = mirror.getId(doc);\n return docId === 1 ? undefined : docId;\n}\n\nfunction serializeTextNode(\n n: Text,\n options: {\n doc: Document;\n needsMask: boolean;\n maskTextFn: MaskTextFn | undefined;\n rootId: number | undefined;\n },\n): serializedNode {\n const { needsMask, maskTextFn, rootId } = options;\n // The parent node may not be a html element which has a tagName attribute.\n // So just let it be undefined which is ok in this use case.\n const parent = dom.parentNode(n);\n const parentTagName = parent && (parent as HTMLElement).tagName;\n let text = dom.textContent(n);\n const isStyle = parentTagName === 'STYLE' ? true : undefined;\n const isScript = parentTagName === 'SCRIPT' ? true : undefined;\n if (isStyle && text) {\n try {\n // try to read style sheet\n if (n.nextSibling || n.previousSibling) {\n // This is not the only child of the stylesheet.\n // We can't read all of the sheet's .cssRules and expect them\n // to _only_ include the current rule(s) added by the text node.\n // So we'll be conservative and keep textContent as-is.\n } else if ((parent as HTMLStyleElement).sheet?.cssRules) {\n const stringified = stringifyStylesheet(\n (parent as HTMLStyleElement).sheet!,\n );\n // Browsers serialize shorthand-with-var() as empty longhands, which\n // silently drops layout rules on replay. Keep the original textContent\n // when stringifyStylesheet would emit that corruption.\n if (stringified && !hasEmptyShorthandLonghand(stringified)) {\n text = stringified;\n }\n }\n } catch (err) {\n console.warn(\n `Cannot get CSS styles from text's parentNode. Error: ${err as string}`,\n n,\n );\n }\n text = absolutifyURLs(text, getHref(options.doc));\n }\n if (isScript) {\n text = 'SCRIPT_PLACEHOLDER';\n }\n if (!isStyle && !isScript && text && needsMask) {\n text = maskTextFn\n ? maskTextFn(text, dom.parentElement(n))\n : text.replace(/[\\S]/g, '*');\n }\n\n return {\n type: NodeType.Text,\n textContent: text || '',\n isStyle,\n rootId,\n };\n}\n\nfunction findStylesheet(doc: Document, href: string) {\n return Array.from(doc.styleSheets).find((s) => s.href === href);\n}\n\n/**\n * in production, we've seen elements like\n * `<link type=\"text/css\" rel=\"stylesheet\" id=\"dark-mode-custom-link\"></link>`\n * while HTMLLinkElement suggests an href is always present\n * the w3c spec is less specific\n * and regardless we've seen at least one instance of this in the wild\n * let's be defensive and make sure this is typed as possibly undefined\n */\nfunction hrefFrom(n: unknown): string | undefined {\n return (n as HTMLLinkElement).href;\n}\n\nfunction serializeElementNode(\n n: HTMLElement,\n options: {\n doc: Document;\n blockClass: string | RegExp;\n blockSelector: string | null;\n inlineStylesheet: boolean;\n maskInputOptions: MaskInputOptions;\n maskInputFn: MaskInputFn | undefined;\n dataURLOptions?: DataURLOptions;\n inlineImages: boolean;\n recordCanvas: boolean;\n canvasMaskingConfigured: (() => boolean) | undefined;\n keepIframeSrcFn: KeepIframeSrcFn;\n /**\n * `newlyAddedElement: true` skips scrollTop and scrollLeft check\n */\n newlyAddedElement?: boolean;\n rootId: number | undefined;\n },\n): serializedNode | false {\n const {\n doc,\n blockClass,\n blockSelector,\n inlineStylesheet,\n maskInputOptions = {},\n maskInputFn,\n dataURLOptions = {},\n inlineImages,\n recordCanvas,\n canvasMaskingConfigured,\n keepIframeSrcFn,\n newlyAddedElement = false,\n rootId,\n } = options;\n const needBlock = _isBlockedElement(n, blockClass, blockSelector);\n const tagName = getValidTagName(n);\n let attributes: attributes = {};\n const len = n.attributes.length;\n for (let i = 0; i < len; i++) {\n const attr = n.attributes[i];\n if (!ignoreAttribute(tagName, attr.name, attr.value)) {\n attributes[attr.name] = transformAttribute(\n doc,\n tagName,\n toLowerCase(attr.name),\n attr.value,\n n,\n dataURLOptions,\n );\n }\n }\n // remote css\n if (tagName === 'link' && inlineStylesheet) {\n // Direct sheet reference survives baseURI drift; href lookup is the fallback.\n let stylesheet: CSSStyleSheet | null | undefined = (n as HTMLLinkElement)\n .sheet;\n if (!stylesheet) {\n const href: string | undefined = hrefFrom(n);\n if (href) {\n stylesheet = findStylesheet(doc, href);\n if (!stylesheet && href.includes('.css')) {\n const rootDomain = window.location.origin;\n const stylesheetPath = href.replace(window.location.href, '');\n const potentialStylesheetHref = rootDomain + '/' + stylesheetPath;\n stylesheet = findStylesheet(doc, potentialStylesheetHref);\n }\n }\n }\n let cssText: string | null = null;\n if (stylesheet) {\n cssText = stringifyStylesheet(stylesheet);\n }\n if (cssText) {\n delete attributes.rel;\n delete attributes.href;\n attributes._cssText = cssText;\n }\n }\n // dynamic stylesheet\n if (\n tagName === 'style' &&\n (n as HTMLStyleElement).sheet &&\n // TODO: Currently we only try to get dynamic stylesheet when it is an empty style element\n !(n.innerText || dom.textContent(n) || '').trim().length\n ) {\n const cssText = stringifyStylesheet(\n (n as HTMLStyleElement).sheet as CSSStyleSheet,\n );\n if (cssText) {\n attributes._cssText = cssText;\n }\n }\n // form fields\n if (tagName === 'input' || tagName === 'textarea' || tagName === 'select') {\n const value = (n as HTMLInputElement | HTMLTextAreaElement).value;\n const checked = (n as HTMLInputElement).checked;\n if (\n attributes.type !== 'radio' &&\n attributes.type !== 'checkbox' &&\n attributes.type !== 'submit' &&\n attributes.type !== 'button' &&\n value\n ) {\n attributes.value = maskInputValue({\n element: n,\n type: getInputType(n),\n tagName,\n value,\n maskInputOptions,\n maskInputFn,\n });\n } else if (checked) {\n attributes.checked = checked;\n }\n }\n if (tagName === 'option') {\n if ((n as HTMLOptionElement).selected && !maskInputOptions['select']) {\n attributes.selected = true;\n } else {\n // ignore the html attribute (which corresponds to DOM (n as HTMLOptionElement).defaultSelected)\n // if it's already been changed\n delete attributes.selected;\n }\n }\n\n if (tagName === 'dialog' && (n as HTMLDialogElement).open) {\n // register what type of dialog is this\n // `modal` or `non-modal`\n // this is used to trigger `showModal()` or `show()` on replay (outside of rrweb-snapshot, in rrweb)\n try {\n (attributes as DialogAttributes).rr_open_mode = n.matches('dialog:modal')\n ? 'modal'\n : 'non-modal';\n } catch {\n // likely this is safari not able to deal with the `:modal` selector\n // we can't detect whether the dialog is modal or non-modal open, so have to guess\n // hopefully this is only safari 15.4 and 15.5\n attributes.rr_open_mode = 'modal';\n attributes.ph_rr_could_not_detect_modal = true;\n }\n }\n\n // canvas image data\n // when a canvas mask provider is configured, canvas pixels only ever reach\n // the payload through the masked frame stream — serializing them here would\n // bypass the masking\n if (tagName === 'canvas' && recordCanvas && !canvasMaskingConfigured?.()) {\n if ((n as ICanvas).__context === '2d') {\n // only record this on 2d canvas\n if (!is2DCanvasBlank(n as HTMLCanvasElement)) {\n attributes.rr_dataURL = (n as HTMLCanvasElement).toDataURL(\n dataURLOptions.type,\n dataURLOptions.quality,\n );\n }\n } else if (!('__context' in n)) {\n // context is unknown, better not call getContext to trigger it\n const canvasDataURL = (n as HTMLCanvasElement).toDataURL(\n dataURLOptions.type,\n dataURLOptions.quality,\n );\n\n // create blank canvas of same dimensions\n const blankCanvas = doc.createElement('canvas');\n blankCanvas.width = (n as HTMLCanvasElement).width;\n blankCanvas.height = (n as HTMLCanvasElement).height;\n const blankCanvasDataURL = blankCanvas.toDataURL(\n dataURLOptions.type,\n dataURLOptions.quality,\n );\n\n // no need to save dataURL if it's the same as blank canvas\n if (canvasDataURL !== blankCanvasDataURL) {\n attributes.rr_dataURL = canvasDataURL;\n }\n }\n }\n // save image offline\n if (tagName === 'img' && inlineImages) {\n if (!canvasService) {\n canvasService = doc.createElement('canvas');\n canvasCtx = canvasService.getContext('2d');\n }\n const image = n as HTMLImageElement;\n const imageSrc: string =\n image.currentSrc || image.getAttribute('src') || '<unknown-src>';\n const priorCrossOrigin = image.crossOrigin;\n const recordInlineImage = () => {\n removeEventListenerSafely(image, 'load', recordInlineImage);\n try {\n canvasService!.width = image.naturalWidth;\n canvasService!.height = image.naturalHeight;\n canvasCtx!.drawImage(image, 0, 0);\n attributes.rr_dataURL = canvasService!.toDataURL(\n dataURLOptions.type,\n dataURLOptions.quality,\n );\n } catch (err) {\n if (image.crossOrigin !== 'anonymous') {\n image.crossOrigin = 'anonymous';\n if (image.complete && image.naturalWidth !== 0)\n recordInlineImage(); // too early due to image reload\n else image.addEventListener('load', recordInlineImage);\n return;\n } else {\n console.warn(\n `Cannot inline img src=${imageSrc}! Error: ${err as string}`,\n );\n }\n }\n if (image.crossOrigin === 'anonymous') {\n priorCrossOrigin\n ? (attributes.crossOrigin = priorCrossOrigin)\n : image.removeAttribute('crossorigin');\n }\n };\n // The image content may not have finished loading yet.\n if (image.complete && image.naturalWidth !== 0) recordInlineImage();\n else image.addEventListener('load', recordInlineImage);\n }\n // media elements\n if (tagName === 'audio' || tagName === 'video') {\n const mediaAttributes = attributes as mediaAttributes;\n mediaAttributes.rr_mediaState = (n as HTMLMediaElement).paused\n ? 'paused'\n : 'played';\n mediaAttributes.rr_mediaCurrentTime = (n as HTMLMediaElement).currentTime;\n mediaAttributes.rr_mediaPlaybackRate = (n as HTMLMediaElement).playbackRate;\n mediaAttributes.rr_mediaMuted = (n as HTMLMediaElement).muted;\n mediaAttributes.rr_mediaLoop = (n as HTMLMediaElement).loop;\n mediaAttributes.rr_mediaVolume = (n as HTMLMediaElement).volume;\n }\n // Scroll\n if (!newlyAddedElement) {\n // `scrollTop` and `scrollLeft` are expensive calls because they trigger reflow.\n // Since `scrollTop` & `scrollLeft` are always 0 when an element is added to the DOM.\n // And scrolls also get picked up by rrweb's ScrollObserver\n // So we can safely skip the `scrollTop/Left` calls for newly added elements\n if (n.scrollLeft) {\n attributes.rr_scrollLeft = n.scrollLeft;\n }\n if (n.scrollTop) {\n attributes.rr_scrollTop = n.scrollTop;\n }\n }\n // block element\n if (needBlock) {\n const { width, height, left, top } = n.getBoundingClientRect();\n const computed = doc.defaultView?.getComputedStyle(n);\n attributes = {\n class: attributes.class,\n rr_width: `${width}px`,\n rr_height: `${height}px`,\n rr_left: `${Math.floor(left + (doc.defaultView?.scrollX || 0))}px`,\n rr_top: `${Math.floor(top + (doc.defaultView?.scrollY || 0))}px`,\n };\n // Captured so rebuild can keep originally-in-flow placeholders in flow\n // instead of forcing `position: absolute` and collapsing sibling layout.\n if (computed) {\n // JSDOM-style envs return '' for unset computed values; normalize to the CSS default.\n attributes.rr_position = computed.position || 'static';\n if (computed.transform && computed.transform !== 'none') {\n attributes.rr_transform = computed.transform;\n }\n // Any inline-level box has its in-flow slot rebuilt as the tag's default\n // display once style is stripped, which collapses width/height. Capture\n // so rebuild can restore (promote plain `inline` → `inline-block`).\n if (computed.display && computed.display.startsWith('inline')) {\n attributes.rr_display = computed.display;\n }\n }\n }\n // iframe\n if (tagName === 'iframe' && !keepIframeSrcFn(attributes.src as string)) {\n if (!(n as HTMLIFrameElement).contentDocument) {\n // we can't record it directly as we can't see into it\n // preserve the src attribute so a decision can be taken at replay time\n attributes.rr_src = attributes.src;\n }\n delete attributes.src; // prevent auto loading\n }\n\n let isCustomElement: true | undefined;\n try {\n if (customElements.get(tagName)) isCustomElement = true;\n } catch (e) {\n // In case old browsers don't support customElements\n }\n\n return {\n type: NodeType.Element,\n tagName,\n attributes,\n childNodes: [],\n isSVG: isSVGElement(n as Element) || undefined,\n needBlock,\n rootId,\n isCustom: isCustomElement,\n };\n}\n\nfunction lowerIfExists(\n maybeAttr: string | number | boolean | undefined | null,\n): string {\n if (maybeAttr === undefined || maybeAttr === null) {\n return '';\n } else {\n return (maybeAttr as string).toLowerCase();\n }\n}\n\nfunction slimDOMExcluded(\n sn: serializedNode,\n slimDOMOptions: SlimDOMOptions,\n): boolean {\n if (slimDOMOptions.comment && sn.type === NodeType.Comment) {\n // TODO: convert IE conditional comments to real nodes\n return true;\n } else if (sn.type === NodeType.Element) {\n if (\n slimDOMOptions.script &&\n // script tag\n (sn.tagName === 'script' ||\n // (module)preload link\n (sn.tagName === 'link' &&\n ((sn.attributes.rel === 'preload' && sn.attributes.as === 'script') ||\n sn.attributes.rel === 'modulepreload')) ||\n // prefetch link\n (sn.tagName === 'link' &&\n sn.attributes.rel === 'prefetch' &&\n typeof sn.attributes.href === 'string' &&\n extractFileExtension(sn.attributes.href) === 'js'))\n ) {\n return true;\n } else if (\n slimDOMOptions.headFavicon &&\n ((sn.tagName === 'link' && sn.attributes.rel === 'shortcut icon') ||\n (sn.tagName === 'meta' &&\n (lowerIfExists(sn.attributes.name).match(\n /^msapplication-tile(image|color)$/,\n ) ||\n lowerIfExists(sn.attributes.name) === 'application-name' ||\n ['icon', 'apple-touch-icon', 'shortcut icon'].includes(\n lowerIfExists(sn.attributes.rel),\n ))))\n ) {\n return true;\n } else if (sn.tagName === 'meta') {\n if (\n slimDOMOptions.headMetaDescKeywords &&\n lowerIfExists(sn.attributes.name).match(/^description|keywords$/)\n ) {\n return true;\n } else if (\n slimDOMOptions.headMetaSocial &&\n (lowerIfExists(sn.attributes.property).match(/^(og|twitter|fb):/) || // og = opengraph (facebook)\n lowerIfExists(sn.attributes.name).match(/^(og|twitter):/) ||\n lowerIfExists(sn.attributes.name) === 'pinterest')\n ) {\n return true;\n } else if (\n slimDOMOptions.headMetaRobots &&\n ['robots', 'googlebot', 'bingbot'].includes(\n lowerIfExists(sn.attributes.name),\n )\n ) {\n return true;\n } else if (\n slimDOMOptions.headMetaHttpEquiv &&\n sn.attributes['http-equiv'] !== undefined\n ) {\n // e.g. X-UA-Compatible, Content-Type, Content-Language,\n // cache-control, X-Translated-By\n return true;\n } else if (\n slimDOMOptions.headMetaAuthorship &&\n (['author', 'generator', 'framework', 'publisher', 'progid'].includes(\n lowerIfExists(sn.attributes.name),\n ) ||\n lowerIfExists(sn.attributes.property).match(/^article:/) ||\n lowerIfExists(sn.attributes.property).match(/^product:/))\n ) {\n return true;\n } else if (\n slimDOMOptions.headMetaVerification &&\n [\n 'google-site-verification',\n 'yandex-verification',\n 'csrf-token',\n 'p:domain_verify',\n 'verify-v1',\n 'verification',\n 'shopify-checkout-api-token',\n ].includes(lowerIfExists(sn.attributes.name))\n ) {\n return true;\n }\n }\n }\n return false;\n}\n\nexport const DEFAULT_MAX_DEPTH = 50;\n\nlet _maxDepthWarned = false;\nlet _maxDepthReached = false;\n\nexport function wasMaxDepthReached(): boolean {\n return _maxDepthReached;\n}\n\nexport function resetMaxDepthState(): void {\n _maxDepthReached = false;\n _maxDepthWarned = false;\n}\n\nexport function serializeNodeWithId(\n n: Node,\n options: {\n doc: Document;\n mirror: Mirror;\n blockClass: string | RegExp;\n blockSelector: string | null;\n maskTextClass: string | RegExp;\n maskTextSelector: string | null;\n skipChild: boolean;\n inlineStylesheet: boolean;\n newlyAddedElement?: boolean;\n maskInputOptions?: MaskInputOptions;\n needsMask?: boolean;\n maskTextFn: MaskTextFn | undefined;\n maskInputFn: MaskInputFn | undefined;\n slimDOMOptions: SlimDOMOptions;\n dataURLOptions?: DataURLOptions;\n keepIframeSrcFn?: KeepIframeSrcFn;\n inlineImages?: boolean;\n recordCanvas?: boolean;\n canvasMaskingConfigured?: () => boolean;\n preserveWhiteSpace?: boolean;\n onSerialize?: (n: Node) => unknown;\n onIframeLoad?: (\n iframeNode: HTMLIFrameElement,\n node: serializedElementNodeWithId,\n ) => unknown;\n iframeLoadTimeout?: number;\n onIframeListenerRegistered?: (\n iframeNode: HTMLIFrameElement,\n disposer: () => void,\n ) => void;\n onStylesheetLoad?: (\n linkNode: HTMLLinkElement,\n node: serializedElementNodeWithId,\n ) => unknown;\n stylesheetLoadTimeout?: number;\n depth?: number;\n maxDepth?: number;\n onMaxDepthReached?: () => void;\n },\n): serializedNodeWithId | null {\n const {\n doc,\n mirror,\n blockClass,\n blockSelector,\n maskTextClass,\n maskTextSelector,\n skipChild = false,\n inlineStylesheet = true,\n maskInputOptions = {},\n maskTextFn,\n maskInputFn,\n slimDOMOptions,\n dataURLOptions = {},\n inlineImages = false,\n recordCanvas = false,\n canvasMaskingConfigured,\n onSerialize,\n onIframeLoad,\n iframeLoadTimeout = 5000,\n onIframeListenerRegistered,\n onStylesheetLoad,\n stylesheetLoadTimeout = 5000,\n keepIframeSrcFn = () => false,\n newlyAddedElement = false,\n depth = 0,\n maxDepth = DEFAULT_MAX_DEPTH,\n } = options;\n let { needsMask } = options;\n let { preserveWhiteSpace = true } = options;\n\n if (depth >= maxDepth) {\n _maxDepthReached = true;\n if (!_maxDepthWarned) {\n _maxDepthWarned = true;\n console.warn(\n `[rrweb-snapshot] DOM tree depth exceeded max depth of ${maxDepth}. ` +\n `Children beyond this depth will not be recorded. ` +\n `This may indicate deeply nested DOM structures.`,\n );\n }\n return null;\n }\n\n if (!needsMask) {\n // perf: if needsMask = true, children won't also need to check\n const checkAncestors = needsMask === undefined; // if false, we've already checked ancestors\n needsMask = needMaskingText(\n n as Element,\n maskTextClass,\n maskTextSelector,\n checkAncestors,\n );\n }\n\n const _serializedNode = serializeNode(n, {\n doc,\n mirror,\n blockClass,\n blockSelector,\n needsMask,\n inlineStylesheet,\n maskInputOptions,\n maskTextFn,\n maskInputFn,\n dataURLOptions,\n inlineImages,\n recordCanvas,\n canvasMaskingConfigured,\n keepIframeSrcFn,\n newlyAddedElement,\n });\n if (!_serializedNode) {\n // TODO: dev only\n console.warn(n, 'not serialized');\n return null;\n }\n\n let id: number | undefined;\n if (mirror.hasNode(n)) {\n // Reuse the previous id\n id = mirror.getId(n);\n } else if (\n slimDOMExcluded(_serializedNode, slimDOMOptions) ||\n (!preserveWhiteSpace &&\n _serializedNode.type === NodeType.Text &&\n !_serializedNode.isStyle &&\n // codeql[js/polynomial-redos] Bounded DOM text node; worst case is recorder slowdown, no exploit.\n !_serializedNode.textContent.replace(/^\\s+|\\s+$/gm, '').length)\n ) {\n id = IGNORED_NODE;\n } else {\n id = genId();\n }\n\n const serializedNode = Object.assign(_serializedNode, { id });\n // add IGNORED_NODE to mirror to track nextSiblings\n mirror.add(n, serializedNode);\n\n if (id === IGNORED_NODE) {\n return null; // slimDOM\n }\n\n if (onSerialize) {\n onSerialize(n);\n }\n let recordChild = !skipChild;\n if (serializedNode.type === NodeType.Element) {\n recordChild = recordChild && !serializedNode.needBlock;\n // this property was not needed in replay side\n delete serializedNode.needBlock;\n const shadowRootEl = dom.shadowRoot(n);\n if (shadowRootEl && isNativeShadowDom(shadowRootEl))\n serializedNode.isShadowHost = true;\n }\n if (\n (serializedNode.type === NodeType.Document ||\n serializedNode.type === NodeType.Element) &&\n recordChild\n ) {\n if (\n slimDOMOptions.headWhitespace &&\n serializedNode.type === NodeType.Element &&\n serializedNode.tagName === 'head'\n // would impede performance: || getComputedStyle(n)['white-space'] === 'normal'\n ) {\n preserveWhiteSpace = false;\n }\n const bypassOptions = {\n doc,\n mirror,\n blockClass,\n blockSelector,\n needsMask,\n maskTextClass,\n maskTextSelector,\n skipChild,\n inlineStylesheet,\n maskInputOptions,\n maskTextFn,\n maskInputFn,\n slimDOMOptions,\n dataURLOptions,\n inlineImages,\n recordCanvas,\n canvasMaskingConfigured,\n preserveWhiteSpace,\n onSerialize,\n onIframeLoad,\n iframeLoadTimeout,\n onIframeListenerRegistered,\n onStylesheetLoad,\n stylesheetLoadTimeout,\n keepIframeSrcFn,\n depth: depth + 1,\n maxDepth,\n };\n\n if (\n serializedNode.type === NodeType.Element &&\n serializedNode.tagName === 'textarea' &&\n (serializedNode as elementNode).attributes.value !== undefined\n ) {\n // value parameter in DOM reflects the correct value, so ignore childNode\n } else {\n for (const childN of Array.from(dom.childNodes(n))) {\n const serializedChildNode = serializeNodeWithId(childN, bypassOptions);\n if (serializedChildNode) {\n serializedNode.childNodes.push(serializedChildNode);\n }\n }\n }\n\n let shadowRootEl: ShadowRoot | null = null;\n if (isElement(n) && (shadowRootEl = dom.shadowRoot(n))) {\n for (const childN of Array.from(dom.childNodes(shadowRootEl))) {\n const serializedChildNode = serializeNodeWithId(childN, bypassOptions);\n if (serializedChildNode) {\n isNativeShadowDom(shadowRootEl) &&\n (serializedChildNode.isShadow = true);\n serializedNode.childNodes.push(serializedChildNode);\n }\n }\n }\n }\n\n const parent = dom.parentNode(n);\n if (parent && isShadowRoot(parent) && isNativeShadowDom(parent)) {\n serializedNode.isShadow = true;\n }\n\n if (\n serializedNode.type === NodeType.Element &&\n serializedNode.tagName === 'iframe'\n ) {\n const iframeDisposer = onceIframeLoaded(\n n as HTMLIFrameElement,\n () => {\n const iframeDoc = (n as HTMLIFrameElement).contentDocument;\n if (iframeDoc && onIframeLoad) {\n const serializedIframeNode = serializeNodeWithId(iframeDoc, {\n doc: iframeDoc,\n mirror,\n blockClass,\n blockSelector,\n needsMask,\n maskTextClass,\n maskTextSelector,\n skipChild: false,\n inlineStylesheet,\n maskInputOptions,\n maskTextFn,\n maskInputFn,\n slimDOMOptions,\n dataURLOptions,\n inlineImages,\n recordCanvas,\n canvasMaskingConfigured,\n preserveWhiteSpace,\n onSerialize,\n onIframeLoad,\n iframeLoadTimeout,\n onIframeListenerRegistered,\n onStylesheetLoad,\n stylesheetLoadTimeout,\n keepIframeSrcFn,\n depth: depth + 1,\n maxDepth,\n });\n\n if (serializedIframeNode) {\n onIframeLoad(\n n as HTMLIFrameElement,\n serializedIframeNode as serializedElementNodeWithId,\n );\n }\n }\n },\n iframeLoadTimeout,\n );\n onIframeListenerRegistered?.(n as HTMLIFrameElement, iframeDisposer);\n }\n\n // <link rel=stylesheet href=...>\n if (\n serializedNode.type === NodeType.Element &&\n serializedNode.tagName === 'link' &&\n serializedNode.attributes.rel === 'stylesheet'\n ) {\n onceStylesheetLoaded(\n n as HTMLLinkElement,\n () => {\n if (onStylesheetLoad) {\n const serializedLinkNode = serializeNodeWithId(n, {\n doc,\n mirror,\n blockClass,\n blockSelector,\n needsMask,\n maskTextClass,\n maskTextSelector,\n skipChild: false,\n inlineStylesheet,\n maskInputOptions,\n maskTextFn,\n maskInputFn,\n slimDOMOptions,\n dataURLOptions,\n inlineImages,\n recordCanvas,\n canvasMaskingConfigured,\n preserveWhiteSpace,\n onSerialize,\n onIframeLoad,\n iframeLoadTimeout,\n onStylesheetLoad,\n stylesheetLoadTimeout,\n keepIframeSrcFn,\n depth,\n maxDepth,\n });\n\n if (serializedLinkNode) {\n onStylesheetLoad(\n n as HTMLLinkElement,\n serializedLinkNode as serializedElementNodeWithId,\n );\n }\n }\n },\n stylesheetLoadTimeout,\n );\n }\n\n return serializedNode;\n}\n\nexport function slimDOMDefaults(\n slimDOM: 'all' | boolean | SlimDOMOptions,\n): SlimDOMOptions {\n if (slimDOM === true || slimDOM === 'all') {\n return {\n script: true,\n comment: true,\n headFavicon: true,\n headWhitespace: true,\n headMetaSocial: true,\n headMetaRobots: true,\n headMetaHttpEquiv: true,\n headMetaVerification: true,\n headMetaAuthorship: slimDOM === 'all',\n headMetaDescKeywords: slimDOM === 'all',\n headTitleMutations: slimDOM === 'all',\n };\n }\n if (slimDOM === false) {\n return {};\n }\n return slimDOM;\n}\n\nfunction snapshot(\n n: Document,\n options?: {\n mirror?: Mirror;\n blockClass?: string | RegExp;\n blockSelector?: string | null;\n maskTextClass?: string | RegExp;\n maskTextSelector?: string | null;\n inlineStylesheet?: boolean;\n maskAllInputs?: boolean | MaskInputOptions;\n maskTextFn?: MaskTextFn;\n maskInputFn?: MaskInputFn;\n slimDOM?: 'all' | boolean | SlimDOMOptions;\n dataURLOptions?: DataURLOptions;\n inlineImages?: boolean;\n recordCanvas?: boolean;\n canvasMaskingConfigured?: () => boolean;\n preserveWhiteSpace?: boolean;\n onSerialize?: (n: Node) => unknown;\n onIframeLoad?: (\n iframeNode: HTMLIFrameElement,\n node: serializedElementNodeWithId,\n ) => unknown;\n iframeLoadTimeout?: number;\n onIframeListenerRegistered?: (\n iframeNode: HTMLIFrameElement,\n disposer: () => void,\n ) => void;\n onStylesheetLoad?: (\n linkNode: HTMLLinkElement,\n node: serializedElementNodeWithId,\n ) => unknown;\n stylesheetLoadTimeout?: number;\n keepIframeSrcFn?: KeepIframeSrcFn;\n maxDepth?: number;\n },\n): serializedNodeWithId | null {\n const {\n mirror = new Mirror(),\n blockClass = 'rr-block',\n blockSelector = null,\n maskTextClass = 'rr-mask',\n maskTextSelector = null,\n inlineStylesheet = true,\n inlineImages = false,\n recordCanvas = false,\n canvasMaskingConfigured,\n maskAllInputs = false,\n maskTextFn,\n maskInputFn,\n slimDOM = false,\n dataURLOptions,\n preserveWhiteSpace,\n onSerialize,\n onIframeLoad,\n iframeLoadTimeout,\n onIframeListenerRegistered,\n onStylesheetLoad,\n stylesheetLoadTimeout,\n keepIframeSrcFn = () => false,\n maxDepth,\n } = options || {};\n const maskInputOptions: MaskInputOptions =\n maskAllInputs === true\n ? {\n color: true,\n date: true,\n 'datetime-local': true,\n email: true,\n month: true,\n number: true,\n range: true,\n search: true,\n tel: true,\n text: true,\n time: true,\n url: true,\n week: true,\n textarea: true,\n select: true,\n password: true,\n }\n : maskAllInputs === false\n ? {\n password: true,\n }\n : maskAllInputs;\n const slimDOMOptions: SlimDOMOptions = slimDOMDefaults(slimDOM);\n return serializeNodeWithId(n, {\n doc: n,\n mirror,\n blockClass,\n blockSelector,\n maskTextClass,\n maskTextSelector,\n skipChild: false,\n inlineStylesheet,\n maskInputOptions,\n maskTextFn,\n maskInputFn,\n slimDOMOptions,\n dataURLOptions,\n inlineImages,\n recordCanvas,\n canvasMaskingConfigured,\n preserveWhiteSpace,\n onSerialize,\n onIframeLoad,\n iframeLoadTimeout,\n onIframeListenerRegistered,\n onStylesheetLoad,\n stylesheetLoadTimeout,\n keepIframeSrcFn,\n newlyAddedElement: false,\n maxDepth,\n });\n}\n\nexport function visitSnapshot(\n node: serializedNodeWithId,\n onVisit: (node: serializedNodeWithId) => unknown,\n) {\n function walk(current: serializedNodeWithId) {\n onVisit(current);\n if (\n current.type === NodeType.Document ||\n current.type === NodeType.Element\n ) {\n current.childNodes.forEach(walk);\n }\n }\n\n walk(node);\n}\n\nexport function cleanupSnapshot() {\n // allow a new recording to start numbering nodes from scratch\n _id = 1;\n}\n\nexport default snapshot;\n","var x=String;\nvar create=function() {return {isColorSupported:false,reset:x,bold:x,dim:x,italic:x,underline:x,inverse:x,hidden:x,strikethrough:x,black:x,red:x,green:x,yellow:x,blue:x,magenta:x,cyan:x,white:x,gray:x,bgBlack:x,bgRed:x,bgGreen:x,bgYellow:x,bgBlue:x,bgMagenta:x,bgCyan:x,bgWhite:x,blackBright:x,redBright:x,greenBright:x,yellowBright:x,blueBright:x,magentaBright:x,cyanBright:x,whiteBright:x,bgBlackBright:x,bgRedBright:x,bgGreenBright:x,bgYellowBright:x,bgBlueBright:x,bgMagentaBright:x,bgCyanBright:x,bgWhiteBright:x}};\nmodule.exports=create();\nmodule.exports.createColors = create;\n","'use strict'\n\nlet pico = require('picocolors')\n\nlet terminalHighlight = require('./terminal-highlight')\n\nclass CssSyntaxError extends Error {\n constructor(message, line, column, source, file, plugin) {\n super(message)\n this.name = 'CssSyntaxError'\n this.reason = message\n\n if (file) {\n this.file = file\n }\n if (source) {\n this.source = source\n }\n if (plugin) {\n this.plugin = plugin\n }\n if (typeof line !== 'undefined' && typeof column !== 'undefined') {\n if (typeof line === 'number') {\n this.line = line\n this.column = column\n } else {\n this.line = line.line\n this.column = line.column\n this.endLine = column.line\n this.endColumn = column.column\n }\n }\n\n this.setMessage()\n\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, CssSyntaxError)\n }\n }\n\n setMessage() {\n this.message = this.plugin ? this.plugin + ': ' : ''\n this.message += this.file ? this.file : '<css input>'\n if (typeof this.line !== 'undefined') {\n this.message += ':' + this.line + ':' + this.column\n }\n this.message += ': ' + this.reason\n }\n\n showSourceCode(color) {\n if (!this.source) return ''\n\n let css = this.source\n if (color == null) color = pico.isColorSupported\n\n let aside = text => text\n let mark = text => text\n let highlight = text => text\n if (color) {\n let { bold, gray, red } = pico.createColors(true)\n mark = text => bold(red(text))\n aside = text => gray(text)\n if (terminalHighlight) {\n highlight = text => terminalHighlight(text)\n }\n }\n\n let lines = css.split(/\\r?\\n/)\n let start = Math.max(this.line - 3, 0)\n let end = Math.min(this.line + 2, lines.length)\n let maxWidth = String(end).length\n\n return lines\n .slice(start, end)\n .map((line, index) => {\n let number = start + 1 + index\n let gutter = ' ' + (' ' + number).slice(-maxWidth) + ' | '\n if (number === this.line) {\n if (line.length > 160) {\n let padding = 20\n let subLineStart = Math.max(0, this.column - padding)\n let subLineEnd = Math.max(\n this.column + padding,\n this.endColumn + padding\n )\n let subLine = line.slice(subLineStart, subLineEnd)\n\n let spacing =\n aside(gutter.replace(/\\d/g, ' ')) +\n line\n .slice(0, Math.min(this.column - 1, padding - 1))\n .replace(/[^\\t]/g, ' ')\n\n return (\n mark('>') +\n aside(gutter) +\n highlight(subLine) +\n '\\n ' +\n spacing +\n mark('^')\n )\n }\n\n let spacing =\n aside(gutter.replace(/\\d/g, ' ')) +\n line.slice(0, this.column - 1).replace(/[^\\t]/g, ' ')\n\n return (\n mark('>') +\n aside(gutter) +\n highlight(line) +\n '\\n ' +\n spacing +\n mark('^')\n )\n }\n\n return ' ' + aside(gutter) + highlight(line)\n })\n .join('\\n')\n }\n\n toString() {\n let code = this.showSourceCode()\n if (code) {\n code = '\\n\\n' + code + '\\n'\n }\n return this.name + ': ' + this.message + code\n }\n}\n\nmodule.exports = CssSyntaxError\nCssSyntaxError.default = CssSyntaxError\n","'use strict'\n\n// Escapes sequences that could break out of an HTML <style> context.\n// Uses CSS unicode escaping (\\3c = '<') which is valid CSS and parsed\n// correctly by all compliant CSS consumers.\nconst STYLE_TAG = /(<)(\\/?style\\b)/gi\nconst COMMENT_OPEN = /(<)(!--)/g\n\nfunction escapeHTMLInCSS(str) {\n if (typeof str !== 'string') return str\n if (!str.includes('<')) return str\n return str.replace(STYLE_TAG, '\\\\3c $2').replace(COMMENT_OPEN, '\\\\3c $2')\n}\n\nconst DEFAULT_RAW = {\n after: '\\n',\n beforeClose: '\\n',\n beforeComment: '\\n',\n beforeDecl: '\\n',\n beforeOpen: ' ',\n beforeRule: '\\n',\n colon: ': ',\n commentLeft: ' ',\n commentRight: ' ',\n emptyBody: '',\n indent: ' ',\n semicolon: false\n}\n\nfunction capitalize(str) {\n return str[0].toUpperCase() + str.slice(1)\n}\n\nclass Stringifier {\n constructor(builder) {\n this.builder = builder\n }\n\n atrule(node, semicolon) {\n let raws = node.raws\n let name = '@' + node.name\n let params = node.params ? this.rawValue(node, 'params') : ''\n\n if (typeof raws.afterName !== 'undefined') {\n name += raws.afterName\n } else if (params) {\n name += ' '\n }\n\n if (node.nodes) {\n this.block(node, name + params)\n } else {\n let end = (raws.between || '') + (semicolon ? ';' : '')\n this.builder(escapeHTMLInCSS(name + params + end), node)\n }\n }\n\n beforeAfter(node, detect) {\n let value\n if (node.type === 'decl') {\n value = this.raw(node, null, 'beforeDecl')\n } else if (node.type === 'comment') {\n value = this.raw(node, null, 'beforeComment')\n } else if (detect === 'before') {\n value = this.raw(node, null, 'beforeRule')\n } else {\n value = this.raw(node, null, 'beforeClose')\n }\n\n let buf = node.parent\n let depth = 0\n while (buf && buf.type !== 'root') {\n depth += 1\n buf = buf.parent\n }\n\n if (value.includes('\\n')) {\n let indent = this.raw(node, null, 'indent')\n if (indent.length) {\n for (let step = 0; step < depth; step++) value += indent\n }\n }\n\n return value\n }\n\n block(node, start) {\n let between = this.raw(node, 'between', 'beforeOpen')\n this.builder(escapeHTMLInCSS(start + between) + '{', node, 'start')\n\n let after\n if (node.nodes && node.nodes.length) {\n this.body(node)\n after = this.raw(node, 'after')\n } else {\n after = this.raw(node, 'after', 'emptyBody')\n }\n\n if (after) this.builder(escapeHTMLInCSS(after))\n this.builder('}', node, 'end')\n }\n\n body(node) {\n let nodes = node.nodes\n let last = nodes.length - 1\n while (last > 0) {\n if (nodes[last].type !== 'comment') break\n last -= 1\n }\n\n let semicolon = this.raw(node, 'semicolon')\n let isDocument = node.type === 'document'\n for (let i = 0; i < nodes.length; i++) {\n let child = nodes[i]\n let before = this.raw(child, 'before')\n if (before) this.builder(isDocument ? before : escapeHTMLInCSS(before))\n this.stringify(child, last !== i || semicolon)\n }\n }\n\n comment(node) {\n let left = this.raw(node, 'left', 'commentLeft')\n let right = this.raw(node, 'right', 'commentRight')\n this.builder(escapeHTMLInCSS('/*' + left + node.text + right + '*/'), node)\n }\n\n decl(node, semicolon) {\n let raws = node.raws\n let between = this.raw(node, 'between', 'colon')\n\n let string = node.prop + between + this.rawValue(node, 'value')\n\n if (node.important) {\n string += raws.important || ' !important'\n }\n\n if (semicolon) string += ';'\n this.builder(escapeHTMLInCSS(string), node)\n }\n\n document(node) {\n this.body(node)\n }\n\n raw(node, own, detect) {\n let value\n if (!detect) detect = own\n\n // Already had\n if (own) {\n value = node.raws[own]\n if (typeof value !== 'undefined') return value\n }\n\n let parent = node.parent\n\n if (detect === 'before') {\n // Hack for first rule in CSS\n if (!parent || (parent.type === 'root' && parent.first === node)) {\n return ''\n }\n\n // `root` nodes in `document` should use only their own raws\n if (parent && parent.type === 'document') {\n return ''\n }\n }\n\n // Floating child without parent\n if (!parent) return DEFAULT_RAW[detect]\n\n // Detect style by other nodes\n let root = node.root()\n let cache = root.rawCache || (root.rawCache = {})\n if (typeof cache[detect] !== 'undefined') {\n return cache[detect]\n }\n\n if (detect === 'before' || detect === 'after') {\n return this.beforeAfter(node, detect)\n } else {\n let method = 'raw' + capitalize(detect)\n if (this[method]) {\n value = this[method](root, node)\n } else {\n root.walk(i => {\n value = i.raws[own]\n if (typeof value !== 'undefined') return false\n })\n }\n }\n\n if (typeof value === 'undefined') value = DEFAULT_RAW[detect]\n\n cache[detect] = value\n return value\n }\n\n rawBeforeClose(root) {\n let value\n root.walk(i => {\n if (i.nodes && i.nodes.length > 0) {\n if (typeof i.raws.after !== 'undefined') {\n value = i.raws.after\n if (value.includes('\\n')) {\n value = value.replace(/[^\\n]+$/, '')\n }\n return false\n }\n }\n })\n if (value) value = value.replace(/\\S/g, '')\n return value\n }\n\n rawBeforeComment(root, node) {\n let value\n root.walkComments(i => {\n if (typeof i.raws.before !== 'undefined') {\n value = i.raws.before\n if (value.includes('\\n')) {\n value = value.replace(/[^\\n]+$/, '')\n }\n return false\n }\n })\n if (typeof value === 'undefined') {\n value = this.raw(node, null, 'beforeDecl')\n } else if (value) {\n value = value.replace(/\\S/g, '')\n }\n return value\n }\n\n rawBeforeDecl(root, node) {\n let value\n root.walkDecls(i => {\n if (typeof i.raws.before !== 'undefined') {\n value = i.raws.before\n if (value.includes('\\n')) {\n value = value.replace(/[^\\n]+$/, '')\n }\n return false\n }\n })\n if (typeof value === 'undefined') {\n value = this.raw(node, null, 'beforeRule')\n } else if (value) {\n value = value.replace(/\\S/g, '')\n }\n return value\n }\n\n rawBeforeOpen(root) {\n let value\n root.walk(i => {\n if (i.type !== 'decl') {\n value = i.raws.between\n if (typeof value !== 'undefined') return false\n }\n })\n return value\n }\n\n rawBeforeRule(root) {\n let value\n root.walk(i => {\n if (i.nodes && (i.parent !== root || root.first !== i)) {\n if (typeof i.raws.before !== 'undefined') {\n value = i.raws.before\n if (value.includes('\\n')) {\n value = value.replace(/[^\\n]+$/, '')\n }\n return false\n }\n }\n })\n if (value) value = value.replace(/\\S/g, '')\n return value\n }\n\n rawColon(root) {\n let value\n root.walkDecls(i => {\n if (typeof i.raws.between !== 'undefined') {\n value = i.raws.between.replace(/[^\\s:]/g, '')\n return false\n }\n })\n return value\n }\n\n rawEmptyBody(root) {\n let value\n root.walk(i => {\n if (i.nodes && i.nodes.length === 0) {\n value = i.raws.after\n if (typeof value !== 'undefined') return false\n }\n })\n return value\n }\n\n rawIndent(root) {\n if (root.raws.indent) return root.raws.indent\n let value\n root.walk(i => {\n let p = i.parent\n if (p && p !== root && p.parent && p.parent === root) {\n if (typeof i.raws.before !== 'undefined') {\n let parts = i.raws.before.split('\\n')\n value = parts[parts.length - 1]\n value = value.replace(/\\S/g, '')\n return false\n }\n }\n })\n return value\n }\n\n rawSemicolon(root) {\n let value\n root.walk(i => {\n if (i.nodes && i.nodes.length && i.last.type === 'decl') {\n value = i.raws.semicolon\n if (typeof value !== 'undefined') return false\n }\n })\n return value\n }\n\n rawValue(node, prop) {\n let value = node[prop]\n let raw = node.raws[prop]\n if (raw && raw.value === value) {\n return raw.raw\n }\n\n return value\n }\n\n root(node) {\n this.body(node)\n if (node.raws.after) {\n let after = node.raws.after\n let isDocument = node.parent && node.parent.type === 'document'\n this.builder(isDocument ? after : escapeHTMLInCSS(after))\n }\n }\n\n rule(node) {\n this.block(node, this.rawValue(node, 'selector'))\n if (node.raws.ownSemicolon) {\n this.builder(escapeHTMLInCSS(node.raws.ownSemicolon), node, 'end')\n }\n }\n\n stringify(node, semicolon) {\n /* c8 ignore start */\n if (!this[node.type]) {\n throw new Error(\n 'Unknown AST node type ' +\n node.type +\n '. ' +\n 'Maybe you need to change PostCSS stringifier.'\n )\n }\n /* c8 ignore stop */\n this[node.type](node, semicolon)\n }\n}\n\nmodule.exports = Stringifier\nStringifier.default = Stringifier\n","'use strict'\n\nlet Stringifier = require('./stringifier')\n\nfunction stringify(node, builder) {\n let str = new Stringifier(builder)\n str.stringify(node)\n}\n\nmodule.exports = stringify\nstringify.default = stringify\n","'use strict'\n\nmodule.exports.isClean = Symbol('isClean')\n\nmodule.exports.my = Symbol('my')\n","'use strict'\n\nlet CssSyntaxError = require('./css-syntax-error')\nlet Stringifier = require('./stringifier')\nlet stringify = require('./stringify')\nlet { isClean, my } = require('./symbols')\n\nfunction cloneNode(obj, parent) {\n let cloned = new obj.constructor()\n\n for (let i in obj) {\n if (!Object.prototype.hasOwnProperty.call(obj, i)) {\n /* c8 ignore next 2 */\n continue\n }\n if (i === 'proxyCache') continue\n let value = obj[i]\n let type = typeof value\n\n if (i === 'parent' && type === 'object') {\n if (parent) cloned[i] = parent\n } else if (i === 'source') {\n cloned[i] = value\n } else if (Array.isArray(value)) {\n cloned[i] = value.map(j => cloneNode(j, cloned))\n } else {\n if (type === 'object' && value !== null) value = cloneNode(value)\n cloned[i] = value\n }\n }\n\n return cloned\n}\n\nfunction sourceOffset(inputCSS, position) {\n // Not all custom syntaxes support `offset` in `source.start` and `source.end`\n if (position && typeof position.offset !== 'undefined') {\n return position.offset\n }\n\n let column = 1\n let line = 1\n let offset = 0\n\n for (let i = 0; i < inputCSS.length; i++) {\n if (line === position.line && column === position.column) {\n offset = i\n break\n }\n\n if (inputCSS[i] === '\\n') {\n column = 1\n line += 1\n } else {\n column += 1\n }\n }\n\n return offset\n}\n\nclass Node {\n get proxyOf() {\n return this\n }\n\n constructor(defaults = {}) {\n this.raws = {}\n this[isClean] = false\n this[my] = true\n\n for (let name in defaults) {\n if (name === 'nodes') {\n this.nodes = []\n for (let node of defaults[name]) {\n // Clone only nodes that already belong to another tree, so passing a\n // freshly created (parent-less) node adopts that instance instead of\n // a copy and keeps the caller's reference usable. See #1987.\n if (typeof node.clone === 'function' && node.parent) {\n this.append(node.clone())\n } else {\n this.append(node)\n }\n }\n } else {\n this[name] = defaults[name]\n }\n }\n }\n\n addToError(error) {\n error.postcssNode = this\n if (error.stack && this.source && /\\n\\s{4}at /.test(error.stack)) {\n let s = this.source\n error.stack = error.stack.replace(\n /\\n\\s{4}at /,\n `$&${s.input.from}:${s.start.line}:${s.start.column}$&`\n )\n }\n return error\n }\n\n after(add) {\n this.parent.insertAfter(this, add)\n return this\n }\n\n assign(overrides = {}) {\n for (let name in overrides) {\n this[name] = overrides[name]\n }\n return this\n }\n\n before(add) {\n this.parent.insertBefore(this, add)\n return this\n }\n\n cleanRaws(keepBetween) {\n delete this.raws.before\n delete this.raws.after\n if (!keepBetween) delete this.raws.between\n }\n\n clone(overrides = {}) {\n let cloned = cloneNode(this)\n for (let name in overrides) {\n cloned[name] = overrides[name]\n }\n return cloned\n }\n\n cloneAfter(overrides = {}) {\n let cloned = this.clone(overrides)\n this.parent.insertAfter(this, cloned)\n return cloned\n }\n\n cloneBefore(overrides = {}) {\n let cloned = this.clone(overrides)\n this.parent.insertBefore(this, cloned)\n return cloned\n }\n\n error(message, opts = {}) {\n if (this.source) {\n let { end, start } = this.rangeBy(opts)\n return this.source.input.error(\n message,\n { column: start.column, line: start.line },\n { column: end.column, line: end.line },\n opts\n )\n }\n return new CssSyntaxError(message)\n }\n\n getProxyProcessor() {\n return {\n get(node, prop) {\n if (prop === 'proxyOf') {\n return node\n } else if (prop === 'root') {\n return () => node.root().toProxy()\n } else {\n return node[prop]\n }\n },\n\n set(node, prop, value) {\n if (node[prop] === value) return true\n node[prop] = value\n if (\n prop === 'prop' ||\n prop === 'value' ||\n prop === 'name' ||\n prop === 'params' ||\n prop === 'important' ||\n /* c8 ignore next */\n prop === 'text'\n ) {\n node.markDirty()\n }\n return true\n }\n }\n }\n\n /* c8 ignore next 3 */\n markClean() {\n this[isClean] = true\n }\n\n markDirty() {\n if (this[isClean]) {\n this[isClean] = false\n let next = this\n while ((next = next.parent)) {\n next[isClean] = false\n }\n }\n }\n\n next() {\n if (!this.parent) return undefined\n let index = this.parent.index(this)\n return this.parent.nodes[index + 1]\n }\n\n positionBy(opts = {}) {\n let inputString =\n 'document' in this.source.input\n ? this.source.input.document\n : this.source.input.css\n let pos = {\n column: this.source.start.column,\n line: this.source.start.line,\n offset: sourceOffset(inputString, this.source.start)\n }\n if (opts.index) {\n pos = this.positionInside(opts.index)\n } else if (opts.word) {\n let stringRepresentation = inputString.slice(\n sourceOffset(inputString, this.source.start),\n sourceOffset(inputString, this.source.end)\n )\n let index = stringRepresentation.indexOf(opts.word)\n if (index !== -1) pos = this.positionInside(index)\n }\n return pos\n }\n\n positionInside(index) {\n let column = this.source.start.column\n let line = this.source.start.line\n let inputString =\n 'document' in this.source.input\n ? this.source.input.document\n : this.source.input.css\n let offset = sourceOffset(inputString, this.source.start)\n let end = offset + index\n\n for (let i = offset; i < end; i++) {\n if (inputString[i] === '\\n') {\n column = 1\n line += 1\n } else {\n column += 1\n }\n }\n\n return { column, line, offset: end }\n }\n\n prev() {\n if (!this.parent) return undefined\n let index = this.parent.index(this)\n return this.parent.nodes[index - 1]\n }\n\n rangeBy(opts = {}) {\n let inputString =\n 'document' in this.source.input\n ? this.source.input.document\n : this.source.input.css\n let start = {\n column: this.source.start.column,\n line: this.source.start.line,\n offset: sourceOffset(inputString, this.source.start)\n }\n let end = this.source.end\n ? {\n column: this.source.end.column + 1,\n line: this.source.end.line,\n offset:\n typeof this.source.end.offset === 'number'\n ? // `source.end.offset` is exclusive, so we don't need to add 1\n this.source.end.offset\n : // Since line/column in this.source.end is inclusive,\n // the `sourceOffset(... , this.source.end)` returns an inclusive offset.\n // So, we add 1 to convert it to exclusive.\n sourceOffset(inputString, this.source.end) + 1\n }\n : {\n column: start.column + 1,\n line: start.line,\n offset: start.offset + 1\n }\n\n if (opts.word) {\n let stringRepresentation = inputString.slice(\n sourceOffset(inputString, this.source.start),\n sourceOffset(inputString, this.source.end)\n )\n let index = stringRepresentation.indexOf(opts.word)\n if (index !== -1) {\n start = this.positionInside(index)\n end = this.positionInside(index + opts.word.length)\n }\n } else {\n if (opts.start) {\n start = {\n column: opts.start.column,\n line: opts.start.line,\n offset: sourceOffset(inputString, opts.start)\n }\n } else if (typeof opts.index === 'number') {\n start = this.positionInside(opts.index)\n }\n\n if (opts.end) {\n end = {\n column: opts.end.column,\n line: opts.end.line,\n offset: sourceOffset(inputString, opts.end)\n }\n } else if (typeof opts.endIndex === 'number') {\n end = this.positionInside(opts.endIndex)\n } else if (typeof opts.index === 'number') {\n end = this.positionInside(opts.index + 1)\n }\n }\n\n if (\n end.line < start.line ||\n (end.line === start.line && end.column <= start.column)\n ) {\n end = {\n column: start.column + 1,\n line: start.line,\n offset: start.offset + 1\n }\n }\n\n return { end, start }\n }\n\n raw(prop, defaultType) {\n let str = new Stringifier()\n return str.raw(this, prop, defaultType)\n }\n\n remove() {\n if (this.parent) {\n this.parent.removeChild(this)\n }\n this.parent = undefined\n return this\n }\n\n replaceWith(...nodes) {\n if (this.parent) {\n let bookmark = this\n let foundSelf = false\n for (let node of nodes) {\n if (node === this) {\n foundSelf = true\n } else if (foundSelf) {\n this.parent.insertAfter(bookmark, node)\n bookmark = node\n } else {\n this.parent.insertBefore(bookmark, node)\n }\n }\n\n if (!foundSelf) {\n this.remove()\n }\n }\n\n return this\n }\n\n root() {\n let result = this\n while (result.parent && result.parent.type !== 'document') {\n result = result.parent\n }\n return result\n }\n\n toJSON(_, inputs) {\n let fixed = {}\n let emitInputs = inputs == null\n inputs = inputs || new Map()\n let inputsNextIndex = 0\n\n for (let name in this) {\n if (!Object.prototype.hasOwnProperty.call(this, name)) {\n /* c8 ignore next 2 */\n continue\n }\n if (name === 'parent' || name === 'proxyCache') continue\n let value = this[name]\n\n if (Array.isArray(value)) {\n fixed[name] = value.map(i => {\n if (typeof i === 'object' && i.toJSON) {\n return i.toJSON(null, inputs)\n } else {\n return i\n }\n })\n } else if (typeof value === 'object' && value.toJSON) {\n fixed[name] = value.toJSON(null, inputs)\n } else if (name === 'source') {\n if (value == null) continue\n let inputId = inputs.get(value.input)\n if (inputId == null) {\n inputId = inputsNextIndex\n inputs.set(value.input, inputsNextIndex)\n inputsNextIndex++\n }\n fixed[name] = {\n end: value.end,\n inputId,\n start: value.start\n }\n } else {\n fixed[name] = value\n }\n }\n\n if (emitInputs) {\n fixed.inputs = [...inputs.keys()].map(input => input.toJSON())\n }\n\n return fixed\n }\n\n toProxy() {\n if (!this.proxyCache) {\n this.proxyCache = new Proxy(this, this.getProxyProcessor())\n }\n return this.proxyCache\n }\n\n toString(stringifier = stringify) {\n if (stringifier.stringify) stringifier = stringifier.stringify\n let result = ''\n stringifier(this, i => {\n result += i\n })\n return result\n }\n\n warn(result, text, opts = {}) {\n let data = { node: this }\n for (let i in opts) data[i] = opts[i]\n return result.warn(text, data)\n }\n}\n\nmodule.exports = Node\nNode.default = Node\n","'use strict'\n\nlet Node = require('./node')\n\nclass Comment extends Node {\n constructor(defaults) {\n super(defaults)\n this.type = 'comment'\n }\n}\n\nmodule.exports = Comment\nComment.default = Comment\n","'use strict'\n\nlet Node = require('./node')\n\nclass Declaration extends Node {\n get variable() {\n return this.prop.startsWith('--') || this.prop[0] === '$'\n }\n\n constructor(defaults) {\n if (\n defaults &&\n typeof defaults.value !== 'undefined' &&\n typeof defaults.value !== 'string'\n ) {\n defaults = { ...defaults, value: String(defaults.value) }\n }\n super(defaults)\n this.type = 'decl'\n }\n}\n\nmodule.exports = Declaration\nDeclaration.default = Declaration\n","'use strict'\n\nlet Comment = require('./comment')\nlet Declaration = require('./declaration')\nlet Node = require('./node')\nlet { isClean, my } = require('./symbols')\n\nlet AtRule, parse, Root, Rule\n\nfunction cleanSource(nodes) {\n return nodes.map(i => {\n if (i.nodes) i.nodes = cleanSource(i.nodes)\n delete i.source\n return i\n })\n}\n\nfunction markTreeDirty(node) {\n node[isClean] = false\n if (node.proxyOf.nodes) {\n for (let i of node.proxyOf.nodes) {\n markTreeDirty(i)\n }\n }\n}\n\nclass Container extends Node {\n get first() {\n if (!this.proxyOf.nodes) return undefined\n return this.proxyOf.nodes[0]\n }\n\n get last() {\n if (!this.proxyOf.nodes) return undefined\n return this.proxyOf.nodes[this.proxyOf.nodes.length - 1]\n }\n\n append(...children) {\n for (let child of children) {\n let nodes = this.normalize(child, this.last)\n for (let node of nodes) this.proxyOf.nodes.push(node)\n }\n\n this.markDirty()\n\n return this\n }\n\n cleanRaws(keepBetween) {\n super.cleanRaws(keepBetween)\n if (this.nodes) {\n for (let node of this.nodes) node.cleanRaws(keepBetween)\n }\n }\n\n each(callback) {\n if (!this.proxyOf.nodes) return undefined\n let iterator = this.getIterator()\n\n let index, result\n while (this.indexes[iterator] < this.proxyOf.nodes.length) {\n index = this.indexes[iterator]\n result = callback(this.proxyOf.nodes[index], index)\n if (result === false) break\n\n this.indexes[iterator] += 1\n }\n\n delete this.indexes[iterator]\n return result\n }\n\n every(condition) {\n return this.nodes.every(condition)\n }\n\n getIterator() {\n if (!this.lastEach) this.lastEach = 0\n if (!this.indexes) this.indexes = {}\n\n this.lastEach += 1\n let iterator = this.lastEach\n this.indexes[iterator] = 0\n\n return iterator\n }\n\n getProxyProcessor() {\n return {\n get(node, prop) {\n if (prop === 'proxyOf') {\n return node\n } else if (!node[prop]) {\n return node[prop]\n } else if (\n prop === 'each' ||\n (typeof prop === 'string' && prop.startsWith('walk'))\n ) {\n return (...args) => {\n return node[prop](\n ...args.map(i => {\n if (typeof i === 'function') {\n return (child, index) => i(child.toProxy(), index)\n } else {\n return i\n }\n })\n )\n }\n } else if (prop === 'every' || prop === 'some') {\n return cb => {\n return node[prop]((child, ...other) =>\n cb(child.toProxy(), ...other)\n )\n }\n } else if (prop === 'root') {\n return () => node.root().toProxy()\n } else if (prop === 'nodes') {\n return node.nodes.map(i => i.toProxy())\n } else if (prop === 'first' || prop === 'last') {\n return node[prop].toProxy()\n } else {\n return node[prop]\n }\n },\n\n set(node, prop, value) {\n if (node[prop] === value) return true\n node[prop] = value\n if (prop === 'name' || prop === 'params' || prop === 'selector') {\n node.markDirty()\n }\n return true\n }\n }\n }\n\n index(child) {\n if (typeof child === 'number') return child\n if (child.proxyOf) child = child.proxyOf\n return this.proxyOf.nodes.indexOf(child)\n }\n\n insertAfter(exist, add) {\n let existIndex = this.index(exist)\n let nodes = this.normalize(add, this.proxyOf.nodes[existIndex]).reverse()\n existIndex = this.index(exist)\n for (let node of nodes) this.proxyOf.nodes.splice(existIndex + 1, 0, node)\n\n let index\n for (let id in this.indexes) {\n index = this.indexes[id]\n if (existIndex < index) {\n this.indexes[id] = index + nodes.length\n }\n }\n\n this.markDirty()\n\n return this\n }\n\n insertBefore(exist, add) {\n let existIndex = this.index(exist)\n let type = existIndex === 0 ? 'prepend' : false\n let nodes = this.normalize(\n add,\n this.proxyOf.nodes[existIndex],\n type\n ).reverse()\n existIndex = this.index(exist)\n for (let node of nodes) this.proxyOf.nodes.splice(existIndex, 0, node)\n\n let index\n for (let id in this.indexes) {\n index = this.indexes[id]\n if (existIndex <= index) {\n this.indexes[id] = index + nodes.length\n }\n }\n\n this.markDirty()\n\n return this\n }\n\n normalize(nodes, sample) {\n if (typeof nodes === 'string') {\n nodes = cleanSource(parse(nodes).nodes)\n } else if (typeof nodes === 'undefined') {\n nodes = []\n } else if (Array.isArray(nodes)) {\n nodes = nodes.slice(0)\n for (let i of nodes) {\n if (i.parent) i.parent.removeChild(i, 'ignore')\n }\n } else if (nodes.type === 'root' && this.type !== 'document') {\n nodes = nodes.nodes.slice(0)\n for (let i of nodes) {\n if (i.parent) i.parent.removeChild(i, 'ignore')\n }\n } else if (nodes.type) {\n nodes = [nodes]\n } else if (nodes.prop) {\n if (typeof nodes.value === 'undefined') {\n throw new Error('Value field is missed in node creation')\n } else if (typeof nodes.value !== 'string') {\n nodes.value = String(nodes.value)\n }\n nodes = [new Declaration(nodes)]\n } else if (nodes.selector || nodes.selectors) {\n nodes = [new Rule(nodes)]\n } else if (nodes.name) {\n nodes = [new AtRule(nodes)]\n } else if (nodes.text) {\n nodes = [new Comment(nodes)]\n } else {\n throw new Error('Unknown node type in node creation')\n }\n\n let processed = nodes.map(i => {\n /* c8 ignore next */\n if (!i[my]) Container.rebuild(i)\n i = i.proxyOf\n if (i.parent) i.parent.removeChild(i)\n if (i[isClean]) markTreeDirty(i)\n\n if (!i.raws) i.raws = {}\n if (typeof i.raws.before === 'undefined') {\n if (sample && typeof sample.raws.before !== 'undefined') {\n i.raws.before = sample.raws.before.replace(/\\S/g, '')\n }\n }\n i.parent = this.proxyOf\n return i\n })\n\n return processed\n }\n\n prepend(...children) {\n children = children.reverse()\n for (let child of children) {\n let nodes = this.normalize(child, this.first, 'prepend').reverse()\n for (let node of nodes) this.proxyOf.nodes.unshift(node)\n for (let id in this.indexes) {\n this.indexes[id] = this.indexes[id] + nodes.length\n }\n }\n\n this.markDirty()\n\n return this\n }\n\n push(child) {\n child.parent = this\n this.proxyOf.nodes.push(child)\n return this\n }\n\n removeAll() {\n for (let node of this.proxyOf.nodes) node.parent = undefined\n this.proxyOf.nodes = []\n\n this.markDirty()\n\n return this\n }\n\n removeChild(child) {\n child = this.index(child)\n this.proxyOf.nodes[child].parent = undefined\n this.proxyOf.nodes.splice(child, 1)\n\n let index\n for (let id in this.indexes) {\n index = this.indexes[id]\n if (index >= child) {\n this.indexes[id] = index - 1\n }\n }\n\n this.markDirty()\n\n return this\n }\n\n replaceValues(pattern, opts, callback) {\n if (!callback) {\n callback = opts\n opts = {}\n }\n\n this.walkDecls(decl => {\n if (opts.props && !opts.props.includes(decl.prop)) return\n if (opts.fast && !decl.value.includes(opts.fast)) return\n\n decl.value = decl.value.replace(pattern, callback)\n })\n\n this.markDirty()\n\n return this\n }\n\n some(condition) {\n return this.nodes.some(condition)\n }\n\n walk(callback) {\n return this.each((child, i) => {\n let result\n try {\n result = callback(child, i)\n } catch (e) {\n throw child.addToError(e)\n }\n if (result !== false && child.walk) {\n result = child.walk(callback)\n }\n\n return result\n })\n }\n\n walkAtRules(name, callback) {\n if (!callback) {\n callback = name\n return this.walk((child, i) => {\n if (child.type === 'atrule') {\n return callback(child, i)\n }\n })\n }\n if (name instanceof RegExp) {\n return this.walk((child, i) => {\n if (child.type === 'atrule' && name.test(child.name)) {\n return callback(child, i)\n }\n })\n }\n return this.walk((child, i) => {\n if (child.type === 'atrule' && child.name === name) {\n return callback(child, i)\n }\n })\n }\n\n walkComments(callback) {\n return this.walk((child, i) => {\n if (child.type === 'comment') {\n return callback(child, i)\n }\n })\n }\n\n walkDecls(prop, callback) {\n if (!callback) {\n callback = prop\n return this.walk((child, i) => {\n if (child.type === 'decl') {\n return callback(child, i)\n }\n })\n }\n if (prop instanceof RegExp) {\n return this.walk((child, i) => {\n if (child.type === 'decl' && prop.test(child.prop)) {\n return callback(child, i)\n }\n })\n }\n return this.walk((child, i) => {\n if (child.type === 'decl' && child.prop === prop) {\n return callback(child, i)\n }\n })\n }\n\n walkRules(selector, callback) {\n if (!callback) {\n callback = selector\n\n return this.walk((child, i) => {\n if (child.type === 'rule') {\n return callback(child, i)\n }\n })\n }\n if (selector instanceof RegExp) {\n return this.walk((child, i) => {\n if (child.type === 'rule' && selector.test(child.selector)) {\n return callback(child, i)\n }\n })\n }\n return this.walk((child, i) => {\n if (child.type === 'rule' && child.selector === selector) {\n return callback(child, i)\n }\n })\n }\n}\n\nContainer.registerParse = dependant => {\n parse = dependant\n}\n\nContainer.registerRule = dependant => {\n Rule = dependant\n}\n\nContainer.registerAtRule = dependant => {\n AtRule = dependant\n}\n\nContainer.registerRoot = dependant => {\n Root = dependant\n}\n\nmodule.exports = Container\nContainer.default = Container\n\n/* c8 ignore start */\nContainer.rebuild = node => {\n if (node.type === 'atrule') {\n Object.setPrototypeOf(node, AtRule.prototype)\n } else if (node.type === 'rule') {\n Object.setPrototypeOf(node, Rule.prototype)\n } else if (node.type === 'decl') {\n Object.setPrototypeOf(node, Declaration.prototype)\n } else if (node.type === 'comment') {\n Object.setPrototypeOf(node, Comment.prototype)\n } else if (node.type === 'root') {\n Object.setPrototypeOf(node, Root.prototype)\n }\n\n node[my] = true\n\n if (node.nodes) {\n node.nodes.forEach(child => {\n Container.rebuild(child)\n })\n }\n}\n/* c8 ignore stop */\n","'use strict'\n\nlet Container = require('./container')\n\nclass AtRule extends Container {\n constructor(defaults) {\n super(defaults)\n this.type = 'atrule'\n }\n\n append(...children) {\n if (!this.proxyOf.nodes) this.nodes = []\n return super.append(...children)\n }\n\n prepend(...children) {\n if (!this.proxyOf.nodes) this.nodes = []\n return super.prepend(...children)\n }\n}\n\nmodule.exports = AtRule\nAtRule.default = AtRule\n\nContainer.registerAtRule(AtRule)\n","'use strict'\n\nlet Container = require('./container')\n\nlet LazyResult, Processor\n\nclass Document extends Container {\n constructor(defaults) {\n // type needs to be passed to super, otherwise child roots won't be normalized correctly\n super({ type: 'document', ...defaults })\n\n if (!this.nodes) {\n this.nodes = []\n }\n }\n\n toResult(opts = {}) {\n let lazy = new LazyResult(new Processor(), this, opts)\n\n return lazy.stringify()\n }\n}\n\nDocument.registerLazyResult = dependant => {\n LazyResult = dependant\n}\n\nDocument.registerProcessor = dependant => {\n Processor = dependant\n}\n\nmodule.exports = Document\nDocument.default = Document\n","let urlAlphabet =\n 'useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict'\n\nlet customAlphabet = (alphabet, defaultSize = 21) => {\n return (size = defaultSize) => {\n let id = ''\n let i = size | 0\n while (i--) {\n id += alphabet[(Math.random() * alphabet.length) | 0]\n }\n return id\n }\n}\n\nlet nanoid = (size = 21) => {\n let id = ''\n let i = size | 0\n while (i--) {\n id += urlAlphabet[(Math.random() * 64) | 0]\n }\n return id\n}\n\nmodule.exports = { nanoid, customAlphabet }\n","'use strict'\n\nlet { existsSync, readFileSync } = require('fs')\nlet { dirname, join } = require('path')\nlet { SourceMapConsumer, SourceMapGenerator } = require('source-map-js')\n\nfunction fromBase64(str) {\n if (Buffer) {\n return Buffer.from(str, 'base64').toString()\n } else {\n /* c8 ignore next 2 */\n return window.atob(str)\n }\n}\n\nclass PreviousMap {\n constructor(css, opts) {\n if (opts.map === false) return\n if (opts.unsafeMap) this.unsafeMap = true\n this.loadAnnotation(css)\n this.inline = this.startWith(this.annotation, 'data:')\n\n let prev = opts.map ? opts.map.prev : undefined\n let text = this.loadMap(opts.from, prev)\n if (!this.mapFile && opts.from) {\n this.mapFile = opts.from\n }\n if (this.mapFile) this.root = dirname(this.mapFile)\n if (text) this.text = text\n }\n\n consumer() {\n if (!this.consumerCache) {\n this.consumerCache = new SourceMapConsumer(this.json || this.text)\n }\n return this.consumerCache\n }\n\n decodeInline(text) {\n let baseCharsetUri = /^data:application\\/json;charset=utf-?8;base64,/\n let baseUri = /^data:application\\/json;base64,/\n let charsetUri = /^data:application\\/json;charset=utf-?8,/\n let uri = /^data:application\\/json,/\n\n let uriMatch = text.match(charsetUri) || text.match(uri)\n if (uriMatch) {\n return decodeURIComponent(text.substr(uriMatch[0].length))\n }\n\n let baseUriMatch = text.match(baseCharsetUri) || text.match(baseUri)\n if (baseUriMatch) {\n return fromBase64(text.substr(baseUriMatch[0].length))\n }\n\n let encoding = text.slice('data:application/json;'.length)\n encoding = encoding.slice(0, encoding.indexOf(','))\n throw new Error('Unsupported source map encoding ' + encoding)\n }\n\n getAnnotationURL(sourceMapString) {\n return sourceMapString.replace(/^\\/\\*\\s*# sourceMappingURL=/, '').trim()\n }\n\n isMap(map) {\n if (typeof map !== 'object') return false\n return (\n typeof map.mappings === 'string' ||\n typeof map._mappings === 'string' ||\n Array.isArray(map.sections)\n )\n }\n\n loadAnnotation(css) {\n let comments = css.match(/\\/\\*\\s*# sourceMappingURL=/g)\n if (!comments) return\n\n // sourceMappingURLs from comments, strings, etc.\n let start = css.lastIndexOf(comments.pop())\n let end = css.indexOf('*/', start)\n\n if (start > -1 && end > -1) {\n // Locate the last sourceMappingURL to avoid pickin\n this.annotation = this.getAnnotationURL(css.substring(start, end))\n }\n }\n\n loadFile(path, cssFile, trusted) {\n /* c8 ignore next 5 */\n if (!trusted && !this.unsafeMap) {\n if (!/\\.map$/i.test(path)) {\n return undefined\n }\n }\n this.root = dirname(path)\n if (existsSync(path)) {\n this.mapFile = path\n return readFileSync(path, 'utf-8').toString().trim()\n }\n }\n\n loadMap(file, prev) {\n if (prev === false) return false\n\n if (prev) {\n if (typeof prev === 'string') {\n return prev\n } else if (typeof prev === 'function') {\n let prevPath = prev(file)\n if (prevPath) {\n let map = this.loadFile(prevPath, file, true)\n if (!map) {\n throw new Error(\n 'Unable to load previous source map: ' + prevPath.toString()\n )\n }\n return map\n }\n } else if (prev instanceof SourceMapConsumer) {\n return SourceMapGenerator.fromSourceMap(prev).toString()\n } else if (prev instanceof SourceMapGenerator) {\n return prev.toString()\n } else if (this.isMap(prev)) {\n return JSON.stringify(prev)\n } else {\n throw new Error(\n 'Unsupported previous source map format: ' + prev.toString()\n )\n }\n } else if (this.inline) {\n return this.decodeInline(this.annotation)\n } else if (this.annotation) {\n let map = this.annotation\n if (file) map = join(dirname(file), map)\n let unknown = this.loadFile(map, file, false)\n if (unknown) {\n try {\n /* c8 ignore next 4 */\n this.json = JSON.parse(unknown.replace(/^\\)]}'[^\\n]*\\n/, ''))\n } catch {\n return undefined\n }\n }\n return unknown\n }\n }\n\n startWith(string, start) {\n if (!string) return false\n return string.substr(0, start.length) === start\n }\n\n withContent() {\n return !!(\n this.consumer().sourcesContent &&\n this.consumer().sourcesContent.length > 0\n )\n }\n}\n\nmodule.exports = PreviousMap\nPreviousMap.default = PreviousMap\n","'use strict'\n\nlet { nanoid } = require('nanoid/non-secure')\nlet { isAbsolute, resolve } = require('path')\nlet { SourceMapConsumer, SourceMapGenerator } = require('source-map-js')\nlet { fileURLToPath, pathToFileURL } = require('url')\n\nlet CssSyntaxError = require('./css-syntax-error')\nlet PreviousMap = require('./previous-map')\nlet terminalHighlight = require('./terminal-highlight')\n\nlet lineToIndexCache = Symbol('lineToIndexCache')\n\nlet sourceMapAvailable = Boolean(SourceMapConsumer && SourceMapGenerator)\nlet pathAvailable = Boolean(resolve && isAbsolute)\n\nfunction getLineToIndex(input) {\n if (input[lineToIndexCache]) return input[lineToIndexCache]\n let lines = input.css.split('\\n')\n let lineToIndex = new Array(lines.length)\n let prevIndex = 0\n\n for (let i = 0, l = lines.length; i < l; i++) {\n lineToIndex[i] = prevIndex\n prevIndex += lines[i].length + 1\n }\n\n input[lineToIndexCache] = lineToIndex\n return lineToIndex\n}\n\nclass Input {\n get from() {\n return this.file || this.id\n }\n\n constructor(css, opts = {}) {\n if (\n css === null ||\n typeof css === 'undefined' ||\n (typeof css === 'object' && !css.toString)\n ) {\n throw new Error(`PostCSS received ${css} instead of CSS string`)\n }\n\n this.css = css.toString()\n\n if (this.css[0] === '\\uFEFF' || this.css[0] === '\\uFFFE') {\n this.hasBOM = true\n this.css = this.css.slice(1)\n } else {\n this.hasBOM = false\n }\n\n this.document = this.css\n if (opts.document) this.document = opts.document.toString()\n\n if (opts.from) {\n if (\n !pathAvailable ||\n /^\\w+:\\/\\//.test(opts.from) ||\n isAbsolute(opts.from)\n ) {\n this.file = opts.from\n } else {\n this.file = resolve(opts.from)\n }\n }\n\n if (pathAvailable && sourceMapAvailable) {\n let map = new PreviousMap(this.css, opts)\n if (map.text) {\n this.map = map\n let file = map.consumer().file\n if (!this.file && file) this.file = this.mapResolve(file)\n }\n }\n\n if (!this.file) {\n this.id = '<input css ' + nanoid(6) + '>'\n }\n if (this.map) this.map.file = this.from\n }\n\n error(message, line, column, opts = {}) {\n let endColumn, endLine, endOffset, offset, result\n\n if (line && typeof line === 'object') {\n let start = line\n let end = column\n if (typeof start.offset === 'number') {\n offset = start.offset\n let pos = this.fromOffset(offset)\n line = pos.line\n column = pos.col\n } else {\n line = start.line\n column = start.column\n offset = this.fromLineAndColumn(line, column)\n }\n if (typeof end.offset === 'number') {\n endOffset = end.offset\n let pos = this.fromOffset(endOffset)\n endLine = pos.line\n endColumn = pos.col\n } else {\n endLine = end.line\n endColumn = end.column\n endOffset = this.fromLineAndColumn(end.line, end.column)\n }\n } else if (!column) {\n offset = line\n let pos = this.fromOffset(offset)\n line = pos.line\n column = pos.col\n } else {\n offset = this.fromLineAndColumn(line, column)\n }\n\n let origin = this.origin(line, column, endLine, endColumn)\n if (origin) {\n result = new CssSyntaxError(\n message,\n origin.endLine === undefined\n ? origin.line\n : { column: origin.column, line: origin.line },\n origin.endLine === undefined\n ? origin.column\n : { column: origin.endColumn, line: origin.endLine },\n origin.source,\n origin.file,\n opts.plugin\n )\n } else {\n result = new CssSyntaxError(\n message,\n endLine === undefined ? line : { column, line },\n endLine === undefined ? column : { column: endColumn, line: endLine },\n this.css,\n this.file,\n opts.plugin\n )\n }\n\n result.input = {\n column,\n endColumn,\n endLine,\n endOffset,\n line,\n offset,\n source: this.css\n }\n if (this.file) {\n if (pathToFileURL) {\n result.input.url = pathToFileURL(this.file).toString()\n }\n result.input.file = this.file\n }\n\n return result\n }\n\n fromLineAndColumn(line, column) {\n let lineToIndex = getLineToIndex(this)\n let index = lineToIndex[line - 1]\n return index + column - 1\n }\n\n fromOffset(offset) {\n let lineToIndex = getLineToIndex(this)\n let lastLine = lineToIndex[lineToIndex.length - 1]\n\n let min = 0\n if (offset >= lastLine) {\n min = lineToIndex.length - 1\n } else {\n let max = lineToIndex.length - 2\n let mid\n while (min < max) {\n mid = min + ((max - min) >> 1)\n if (offset < lineToIndex[mid]) {\n max = mid - 1\n } else if (offset >= lineToIndex[mid + 1]) {\n min = mid + 1\n } else {\n min = mid\n break\n }\n }\n }\n return {\n col: offset - lineToIndex[min] + 1,\n line: min + 1\n }\n }\n\n mapResolve(file) {\n if (/^\\w+:\\/\\//.test(file)) {\n return file\n }\n return resolve(this.map.consumer().sourceRoot || this.map.root || '.', file)\n }\n\n origin(line, column, endLine, endColumn) {\n if (!this.map) return false\n let consumer = this.map.consumer()\n\n let from = consumer.originalPositionFor({ column: column - 1, line })\n if (!from.source) return false\n\n let to\n if (typeof endLine === 'number') {\n to = consumer.originalPositionFor({\n column: endColumn - 1,\n line: endLine\n })\n }\n\n let fromUrl\n\n if (isAbsolute(from.source)) {\n fromUrl = pathToFileURL(from.source)\n } else {\n fromUrl = new URL(\n from.source,\n this.map.consumer().sourceRoot || pathToFileURL(this.map.mapFile)\n )\n }\n\n let result = {\n column: from.column + 1,\n endColumn: to && to.column + 1,\n endLine: to && to.line,\n line: from.line,\n url: fromUrl.toString()\n }\n\n if (fromUrl.protocol === 'file:') {\n if (fileURLToPath) {\n result.file = fileURLToPath(fromUrl)\n } else {\n /* c8 ignore next 2 */\n throw new Error(`file: protocol is not available in this PostCSS build`)\n }\n }\n\n let source = consumer.sourceContentFor(from.source)\n if (source) result.source = source\n\n return result\n }\n\n toJSON() {\n let json = {}\n for (let name of ['hasBOM', 'css', 'file', 'id']) {\n if (this[name] != null) {\n json[name] = this[name]\n }\n }\n if (this.map) {\n json.map = { ...this.map }\n if (json.map.consumerCache) {\n json.map.consumerCache = undefined\n }\n }\n return json\n }\n}\n\nmodule.exports = Input\nInput.default = Input\n\nif (terminalHighlight && terminalHighlight.registerInput) {\n terminalHighlight.registerInput(Input)\n}\n","'use strict'\n\nlet Container = require('./container')\n\nlet LazyResult, Processor\n\nclass Root extends Container {\n constructor(defaults) {\n super(defaults)\n this.type = 'root'\n if (!this.nodes) this.nodes = []\n }\n\n normalize(child, sample, type) {\n let nodes = super.normalize(child)\n\n if (sample) {\n if (type === 'prepend') {\n if (this.nodes.length > 1) {\n sample.raws.before = this.nodes[1].raws.before\n } else {\n delete sample.raws.before\n }\n } else if (this.first !== sample) {\n for (let node of nodes) {\n node.raws.before = sample.raws.before\n }\n }\n }\n\n return nodes\n }\n\n removeChild(child, ignore) {\n let index = this.index(child)\n\n if (!ignore && index === 0 && this.nodes.length > 1) {\n this.nodes[1].raws.before = this.nodes[index].raws.before\n }\n\n return super.removeChild(child)\n }\n\n toResult(opts = {}) {\n let lazy = new LazyResult(new Processor(), this, opts)\n return lazy.stringify()\n }\n}\n\nRoot.registerLazyResult = dependant => {\n LazyResult = dependant\n}\n\nRoot.registerProcessor = dependant => {\n Processor = dependant\n}\n\nmodule.exports = Root\nRoot.default = Root\n\nContainer.registerRoot(Root)\n","'use strict'\n\nlet list = {\n comma(string) {\n return list.split(string, [','], true)\n },\n\n space(string) {\n let spaces = [' ', '\\n', '\\t']\n return list.split(string, spaces)\n },\n\n split(string, separators, last) {\n let array = []\n let current = ''\n let split = false\n\n let func = 0\n let inQuote = false\n let prevQuote = ''\n let escape = false\n\n for (let letter of string) {\n if (escape) {\n escape = false\n } else if (letter === '\\\\') {\n escape = true\n } else if (inQuote) {\n if (letter === prevQuote) {\n inQuote = false\n }\n } else if (letter === '\"' || letter === \"'\") {\n inQuote = true\n prevQuote = letter\n } else if (letter === '(') {\n func += 1\n } else if (letter === ')') {\n if (func > 0) func -= 1\n } else if (func === 0) {\n if (separators.includes(letter)) split = true\n }\n\n if (split) {\n if (current !== '') array.push(current.trim())\n current = ''\n split = false\n } else {\n current += letter\n }\n }\n\n if (last || current !== '') array.push(current.trim())\n return array\n }\n}\n\nmodule.exports = list\nlist.default = list\n","'use strict'\n\nlet Container = require('./container')\nlet list = require('./list')\n\nclass Rule extends Container {\n get selectors() {\n return list.comma(this.selector)\n }\n\n set selectors(values) {\n let match = this.selector ? this.selector.match(/,\\s*/) : null\n let sep = match ? match[0] : ',' + this.raw('between', 'beforeOpen')\n this.selector = values.join(sep)\n }\n\n constructor(defaults) {\n super(defaults)\n this.type = 'rule'\n if (!this.nodes) this.nodes = []\n }\n}\n\nmodule.exports = Rule\nRule.default = Rule\n\nContainer.registerRule(Rule)\n","'use strict'\n\nlet { dirname, relative, resolve, sep } = require('path')\nlet { SourceMapConsumer, SourceMapGenerator } = require('source-map-js')\nlet { pathToFileURL } = require('url')\n\nlet Input = require('./input')\n\nlet sourceMapAvailable = Boolean(SourceMapConsumer && SourceMapGenerator)\nlet pathAvailable = Boolean(dirname && resolve && relative && sep)\n\nclass MapGenerator {\n constructor(stringify, root, opts, cssString) {\n this.stringify = stringify\n this.mapOpts = opts.map || {}\n this.root = root\n this.opts = opts\n this.css = cssString\n this.originalCSS = cssString\n this.usesFileUrls = !this.mapOpts.from && this.mapOpts.absolute\n\n this.memoizedFileURLs = new Map()\n this.memoizedPaths = new Map()\n this.memoizedURLs = new Map()\n }\n\n addAnnotation() {\n let content\n\n if (this.isInline()) {\n content =\n 'data:application/json;base64,' + this.toBase64(this.map.toString())\n } else if (typeof this.mapOpts.annotation === 'string') {\n content = this.mapOpts.annotation\n } else if (typeof this.mapOpts.annotation === 'function') {\n content = this.mapOpts.annotation(this.opts.to, this.root)\n } else {\n content = this.outputFile() + '.map'\n }\n let eol = '\\n'\n if (this.css.includes('\\r\\n')) eol = '\\r\\n'\n\n this.css += eol + '/*# sourceMappingURL=' + content + ' */'\n }\n\n applyPrevMaps() {\n for (let prev of this.previous()) {\n let from = this.toUrl(this.path(prev.file))\n let root = prev.root || dirname(prev.file)\n let map\n\n if (this.mapOpts.sourcesContent === false) {\n map = new SourceMapConsumer(prev.text)\n if (map.sourcesContent) {\n map.sourcesContent = null\n }\n } else {\n map = prev.consumer()\n }\n\n this.map.applySourceMap(map, from, this.toUrl(this.path(root)))\n }\n }\n\n clearAnnotation() {\n if (this.mapOpts.annotation === false) return\n\n if (this.root) {\n let node\n for (let i = this.root.nodes.length - 1; i >= 0; i--) {\n node = this.root.nodes[i]\n if (node.type !== 'comment') continue\n if (node.text.startsWith('# sourceMappingURL=')) {\n this.root.removeChild(i)\n }\n }\n } else if (this.css) {\n let startIndex\n while ((startIndex = this.css.lastIndexOf('/*#')) !== -1) {\n let endIndex = this.css.indexOf('*/', startIndex + 3)\n if (endIndex === -1) break\n while (startIndex > 0 && this.css[startIndex - 1] === '\\n') {\n startIndex--\n }\n this.css = this.css.slice(0, startIndex) + this.css.slice(endIndex + 2)\n }\n }\n }\n\n generate() {\n this.clearAnnotation()\n if (pathAvailable && sourceMapAvailable && this.isMap()) {\n return this.generateMap()\n } else {\n let result = ''\n this.stringify(this.root, i => {\n result += i\n })\n return [result]\n }\n }\n\n generateMap() {\n if (this.root) {\n this.generateString()\n } else if (this.previous().length === 1) {\n let prev = this.previous()[0].consumer()\n prev.file = this.outputFile()\n this.map = SourceMapGenerator.fromSourceMap(prev, {\n ignoreInvalidMapping: true\n })\n } else {\n this.map = new SourceMapGenerator({\n file: this.outputFile(),\n ignoreInvalidMapping: true\n })\n this.map.addMapping({\n generated: { column: 0, line: 1 },\n original: { column: 0, line: 1 },\n source: this.opts.from\n ? this.toUrl(this.path(this.opts.from))\n : '<no source>'\n })\n }\n\n if (this.isSourcesContent()) this.setSourcesContent()\n if (this.root && this.previous().length > 0) this.applyPrevMaps()\n if (this.isAnnotation()) this.addAnnotation()\n\n if (this.isInline()) {\n return [this.css]\n } else {\n return [this.css, this.map]\n }\n }\n\n generateString() {\n this.css = ''\n this.map = new SourceMapGenerator({\n file: this.outputFile(),\n ignoreInvalidMapping: true\n })\n\n let line = 1\n let column = 1\n\n let noSource = '<no source>'\n let mapping = {\n generated: { column: 0, line: 0 },\n original: { column: 0, line: 0 },\n source: ''\n }\n\n let last, lines\n this.stringify(this.root, (str, node, type) => {\n this.css += str\n\n if (node && type !== 'end') {\n mapping.generated.line = line\n mapping.generated.column = column - 1\n if (node.source && node.source.start) {\n mapping.source = this.sourcePath(node)\n mapping.original.line = node.source.start.line\n mapping.original.column = node.source.start.column - 1\n this.map.addMapping(mapping)\n } else {\n mapping.source = noSource\n mapping.original.line = 1\n mapping.original.column = 0\n this.map.addMapping(mapping)\n }\n }\n\n lines = str.match(/\\n/g)\n if (lines) {\n line += lines.length\n last = str.lastIndexOf('\\n')\n column = str.length - last\n } else {\n column += str.length\n }\n\n if (node && type !== 'start') {\n let p = node.parent || { raws: {} }\n let childless =\n node.type === 'decl' || (node.type === 'atrule' && !node.nodes)\n if (!childless || node !== p.last || p.raws.semicolon) {\n if (node.source && node.source.end) {\n mapping.source = this.sourcePath(node)\n mapping.original.line = node.source.end.line\n mapping.original.column = node.source.end.column - 1\n mapping.generated.line = line\n mapping.generated.column = column - 2\n this.map.addMapping(mapping)\n } else {\n mapping.source = noSource\n mapping.original.line = 1\n mapping.original.column = 0\n mapping.generated.line = line\n mapping.generated.column = column - 1\n this.map.addMapping(mapping)\n }\n }\n }\n })\n }\n\n isAnnotation() {\n if (this.isInline()) {\n return true\n }\n if (typeof this.mapOpts.annotation !== 'undefined') {\n return this.mapOpts.annotation\n }\n if (this.previous().length) {\n return this.previous().some(i => i.annotation)\n }\n return true\n }\n\n isInline() {\n if (typeof this.mapOpts.inline !== 'undefined') {\n return this.mapOpts.inline\n }\n\n let annotation = this.mapOpts.annotation\n if (typeof annotation !== 'undefined' && annotation !== true) {\n return false\n }\n\n if (this.previous().length) {\n return this.previous().some(i => i.inline)\n }\n return true\n }\n\n isMap() {\n if (typeof this.opts.map !== 'undefined') {\n return !!this.opts.map\n }\n return this.previous().length > 0\n }\n\n isSourcesContent() {\n if (typeof this.mapOpts.sourcesContent !== 'undefined') {\n return this.mapOpts.sourcesContent\n }\n if (this.previous().length) {\n return this.previous().some(i => i.withContent())\n }\n return true\n }\n\n outputFile() {\n if (this.opts.to) {\n return this.path(this.opts.to)\n } else if (this.opts.from) {\n return this.path(this.opts.from)\n } else {\n return 'to.css'\n }\n }\n\n path(file) {\n if (this.mapOpts.absolute) return file\n if (file.charCodeAt(0) === 60 /* `<` */) return file\n if (/^\\w+:\\/\\//.test(file)) return file\n let cached = this.memoizedPaths.get(file)\n if (cached) return cached\n\n let from = this.opts.to ? dirname(this.opts.to) : '.'\n\n if (typeof this.mapOpts.annotation === 'string') {\n from = dirname(resolve(from, this.mapOpts.annotation))\n }\n\n let path = relative(from, file)\n this.memoizedPaths.set(file, path)\n\n return path\n }\n\n previous() {\n if (!this.previousMaps) {\n this.previousMaps = []\n if (this.root) {\n this.root.walk(node => {\n if (node.source && node.source.input.map) {\n let map = node.source.input.map\n if (!this.previousMaps.includes(map)) {\n this.previousMaps.push(map)\n }\n }\n })\n } else {\n let input = new Input(this.originalCSS, this.opts)\n if (input.map) this.previousMaps.push(input.map)\n }\n }\n\n return this.previousMaps\n }\n\n setSourcesContent() {\n let already = {}\n if (this.root) {\n this.root.walk(node => {\n if (node.source) {\n let from = node.source.input.from\n if (from && !already[from]) {\n already[from] = true\n let fromUrl = this.usesFileUrls\n ? this.toFileUrl(from)\n : this.toUrl(this.path(from))\n this.map.setSourceContent(fromUrl, node.source.input.css)\n }\n }\n })\n } else if (this.css) {\n let from = this.opts.from\n ? this.toUrl(this.path(this.opts.from))\n : '<no source>'\n this.map.setSourceContent(from, this.css)\n }\n }\n\n sourcePath(node) {\n if (this.mapOpts.from) {\n return this.toUrl(this.mapOpts.from)\n } else if (this.usesFileUrls) {\n return this.toFileUrl(node.source.input.from)\n } else {\n return this.toUrl(this.path(node.source.input.from))\n }\n }\n\n toBase64(str) {\n if (Buffer) {\n return Buffer.from(str).toString('base64')\n } else {\n return window.btoa(unescape(encodeURIComponent(str)))\n }\n }\n\n toFileUrl(path) {\n let cached = this.memoizedFileURLs.get(path)\n if (cached) return cached\n\n if (pathToFileURL) {\n let fileURL = pathToFileURL(path).toString()\n this.memoizedFileURLs.set(path, fileURL)\n\n return fileURL\n } else {\n throw new Error(\n '`map.absolute` option is not available in this PostCSS build'\n )\n }\n }\n\n toUrl(path) {\n let cached = this.memoizedURLs.get(path)\n if (cached) return cached\n\n if (sep === '\\\\') {\n path = path.replace(/\\\\/g, '/')\n }\n\n let url = encodeURI(path).replace(/[#?]/g, encodeURIComponent)\n this.memoizedURLs.set(path, url)\n\n return url\n }\n}\n\nmodule.exports = MapGenerator\n","'use strict'\n\nconst SINGLE_QUOTE = \"'\".charCodeAt(0)\nconst DOUBLE_QUOTE = '\"'.charCodeAt(0)\nconst BACKSLASH = '\\\\'.charCodeAt(0)\nconst SLASH = '/'.charCodeAt(0)\nconst NEWLINE = '\\n'.charCodeAt(0)\nconst SPACE = ' '.charCodeAt(0)\nconst FEED = '\\f'.charCodeAt(0)\nconst TAB = '\\t'.charCodeAt(0)\nconst CR = '\\r'.charCodeAt(0)\nconst OPEN_SQUARE = '['.charCodeAt(0)\nconst CLOSE_SQUARE = ']'.charCodeAt(0)\nconst OPEN_PARENTHESES = '('.charCodeAt(0)\nconst CLOSE_PARENTHESES = ')'.charCodeAt(0)\nconst OPEN_CURLY = '{'.charCodeAt(0)\nconst CLOSE_CURLY = '}'.charCodeAt(0)\nconst SEMICOLON = ';'.charCodeAt(0)\nconst ASTERISK = '*'.charCodeAt(0)\nconst COLON = ':'.charCodeAt(0)\nconst AT = '@'.charCodeAt(0)\n\nconst RE_AT_END = /[\\t\\n\\f\\r \"#'()/;[\\\\\\]{}]/g\nconst RE_WORD_END = /[\\t\\n\\f\\r !\"#'():;@[\\\\\\]{}]|\\/(?=\\*)/g\nconst RE_BAD_BRACKET = /.[\\r\\n\"'(/\\\\]/\nconst RE_HEX_ESCAPE = /[\\da-f]/i\n\nmodule.exports = function tokenizer(input, options = {}) {\n let css = input.css.valueOf()\n let ignore = options.ignoreErrors\n\n let code, content, escape, next, quote\n let currentToken, escaped, escapePos, n, prev\n\n let length = css.length\n let pos = 0\n let buffer = []\n let returned = []\n let lastBadParen = -1\n\n function position() {\n return pos\n }\n\n function unclosed(what) {\n throw input.error('Unclosed ' + what, pos)\n }\n\n function endOfFile() {\n return returned.length === 0 && pos >= length\n }\n\n function nextToken(opts) {\n if (returned.length) return returned.pop()\n if (pos >= length) return\n\n let ignoreUnclosed = opts ? opts.ignoreUnclosed : false\n\n code = css.charCodeAt(pos)\n\n switch (code) {\n case NEWLINE:\n case SPACE:\n case TAB:\n case CR:\n case FEED: {\n next = pos\n do {\n next += 1\n code = css.charCodeAt(next)\n } while (\n code === SPACE ||\n code === NEWLINE ||\n code === TAB ||\n code === CR ||\n code === FEED\n )\n\n currentToken = ['space', css.slice(pos, next)]\n pos = next - 1\n break\n }\n\n case OPEN_SQUARE:\n case CLOSE_SQUARE:\n case OPEN_CURLY:\n case CLOSE_CURLY:\n case COLON:\n case SEMICOLON:\n case CLOSE_PARENTHESES: {\n let controlChar = String.fromCharCode(code)\n currentToken = [controlChar, controlChar, pos]\n break\n }\n\n case OPEN_PARENTHESES: {\n prev = buffer.length ? buffer.pop()[1] : ''\n n = css.charCodeAt(pos + 1)\n if (\n prev === 'url' &&\n n !== SINGLE_QUOTE &&\n n !== DOUBLE_QUOTE &&\n n !== SPACE &&\n n !== NEWLINE &&\n n !== TAB &&\n n !== FEED &&\n n !== CR\n ) {\n next = pos\n do {\n escaped = false\n next = css.indexOf(')', next + 1)\n if (next === -1) {\n if (ignore || ignoreUnclosed) {\n next = pos\n break\n } else {\n unclosed('bracket')\n }\n }\n escapePos = next\n while (css.charCodeAt(escapePos - 1) === BACKSLASH) {\n escapePos -= 1\n escaped = !escaped\n }\n } while (escaped)\n\n currentToken = ['brackets', css.slice(pos, next + 1), pos, next]\n\n pos = next\n } else if (pos <= lastBadParen) {\n currentToken = ['(', '(', pos]\n } else {\n next = css.indexOf(')', pos + 1)\n content = css.slice(pos, next + 1)\n\n if (next === -1 || RE_BAD_BRACKET.test(content)) {\n lastBadParen = next === -1 ? length : next\n currentToken = ['(', '(', pos]\n } else {\n currentToken = ['brackets', content, pos, next]\n pos = next\n }\n }\n\n break\n }\n\n case SINGLE_QUOTE:\n case DOUBLE_QUOTE: {\n quote = code === SINGLE_QUOTE ? \"'\" : '\"'\n next = pos\n do {\n escaped = false\n next = css.indexOf(quote, next + 1)\n if (next === -1) {\n if (ignore || ignoreUnclosed) {\n next = pos + 1\n break\n } else {\n unclosed('string')\n }\n }\n escapePos = next\n while (css.charCodeAt(escapePos - 1) === BACKSLASH) {\n escapePos -= 1\n escaped = !escaped\n }\n } while (escaped)\n\n currentToken = ['string', css.slice(pos, next + 1), pos, next]\n pos = next\n break\n }\n\n case AT: {\n RE_AT_END.lastIndex = pos + 1\n RE_AT_END.test(css)\n if (RE_AT_END.lastIndex === 0) {\n next = css.length - 1\n } else {\n next = RE_AT_END.lastIndex - 2\n }\n\n currentToken = ['at-word', css.slice(pos, next + 1), pos, next]\n\n pos = next\n break\n }\n\n case BACKSLASH: {\n next = pos\n escape = true\n while (css.charCodeAt(next + 1) === BACKSLASH) {\n next += 1\n escape = !escape\n }\n code = css.charCodeAt(next + 1)\n if (\n escape &&\n code !== SLASH &&\n code !== SPACE &&\n code !== NEWLINE &&\n code !== TAB &&\n code !== CR &&\n code !== FEED\n ) {\n next += 1\n if (RE_HEX_ESCAPE.test(css.charAt(next))) {\n while (RE_HEX_ESCAPE.test(css.charAt(next + 1))) {\n next += 1\n }\n if (css.charCodeAt(next + 1) === SPACE) {\n next += 1\n }\n }\n }\n\n currentToken = ['word', css.slice(pos, next + 1), pos, next]\n\n pos = next\n break\n }\n\n default: {\n if (code === SLASH && css.charCodeAt(pos + 1) === ASTERISK) {\n next = css.indexOf('*/', pos + 2) + 1\n if (next === 0) {\n if (ignore || ignoreUnclosed) {\n next = css.length\n } else {\n unclosed('comment')\n }\n }\n\n currentToken = ['comment', css.slice(pos, next + 1), pos, next]\n pos = next\n } else {\n RE_WORD_END.lastIndex = pos + 1\n RE_WORD_END.test(css)\n if (RE_WORD_END.lastIndex === 0) {\n next = css.length - 1\n } else {\n next = RE_WORD_END.lastIndex - 2\n }\n\n currentToken = ['word', css.slice(pos, next + 1), pos, next]\n buffer.push(currentToken)\n pos = next\n }\n\n break\n }\n }\n\n pos++\n return currentToken\n }\n\n function back(token) {\n returned.push(token)\n }\n\n return {\n back,\n endOfFile,\n nextToken,\n position\n }\n}\n","'use strict'\n\nlet AtRule = require('./at-rule')\nlet Comment = require('./comment')\nlet Declaration = require('./declaration')\nlet Root = require('./root')\nlet Rule = require('./rule')\nlet tokenizer = require('./tokenize')\n\nconst SAFE_COMMENT_NEIGHBOR = {\n empty: true,\n space: true\n}\n\nfunction findLastWithPosition(tokens) {\n for (let i = tokens.length - 1; i >= 0; i--) {\n let token = tokens[i]\n let pos = token[3] || token[2]\n if (pos) return pos\n }\n}\n\nfunction tokensToString(tokens, from, to) {\n let result = ''\n for (let i = from; i < to; i++) result += tokens[i][1]\n return result\n}\n\nclass Parser {\n constructor(input) {\n this.input = input\n\n this.root = new Root()\n this.current = this.root\n this.spaces = ''\n this.semicolon = false\n\n this.createTokenizer()\n this.root.source = { input, start: { column: 1, line: 1, offset: 0 } }\n }\n\n atrule(token) {\n let node = new AtRule()\n node.name = token[1].slice(1)\n if (node.name === '') {\n this.unnamedAtrule(node, token)\n }\n this.init(node, token[2])\n\n let type\n let prev\n let shift\n let last = false\n let open = false\n let params = []\n let brackets = []\n\n while (!this.tokenizer.endOfFile()) {\n token = this.tokenizer.nextToken()\n type = token[0]\n\n if (type === '(' || type === '[') {\n brackets.push(type === '(' ? ')' : ']')\n } else if (type === '{' && brackets.length > 0) {\n brackets.push('}')\n } else if (type === brackets[brackets.length - 1]) {\n brackets.pop()\n }\n\n if (brackets.length === 0) {\n if (type === ';') {\n node.source.end = this.getPosition(token[2])\n node.source.end.offset++\n this.semicolon = true\n break\n } else if (type === '{') {\n open = true\n break\n } else if (type === '}') {\n if (params.length > 0) {\n shift = params.length - 1\n prev = params[shift]\n while (prev && prev[0] === 'space') {\n prev = params[--shift]\n }\n if (prev) {\n node.source.end = this.getPosition(prev[3] || prev[2])\n node.source.end.offset++\n }\n }\n this.end(token)\n break\n } else {\n params.push(token)\n }\n } else {\n params.push(token)\n }\n\n if (this.tokenizer.endOfFile()) {\n last = true\n break\n }\n }\n\n node.raws.between = this.spacesAndCommentsFromEnd(params)\n if (params.length) {\n node.raws.afterName = this.spacesAndCommentsFromStart(params)\n this.raw(node, 'params', params)\n if (last) {\n token = params[params.length - 1]\n node.source.end = this.getPosition(token[3] || token[2])\n node.source.end.offset++\n this.spaces = node.raws.between\n node.raws.between = ''\n }\n } else {\n node.raws.afterName = ''\n node.params = ''\n }\n\n if (open) {\n node.nodes = []\n this.current = node\n }\n }\n\n checkMissedSemicolon(tokens) {\n let colon = this.colon(tokens)\n if (colon === false) return\n\n let founded = 0\n let token\n for (let j = colon - 1; j >= 0; j--) {\n token = tokens[j]\n if (token[0] !== 'space') {\n founded += 1\n if (founded === 2) break\n }\n }\n // If the token is a word, e.g. `!important`, `red` or any other valid\n // property's value. Then we need to return the colon after that word\n // token. [3] is the \"end\" colon of that word. And because we need it\n // after that one we do +1 to get the next one.\n throw this.input.error(\n 'Missed semicolon',\n token[0] === 'word' ? token[3] + 1 : token[2]\n )\n }\n\n colon(tokens) {\n let brackets = 0\n let prev, token, type\n for (let [i, element] of tokens.entries()) {\n token = element\n type = token[0]\n\n if (type === '(') {\n brackets += 1\n }\n if (type === ')') {\n brackets -= 1\n }\n if (brackets === 0 && type === ':') {\n if (!prev) {\n this.doubleColon(token)\n } else if (prev[0] === 'word' && prev[1] === 'progid') {\n continue\n } else {\n return i\n }\n }\n\n prev = token\n }\n return false\n }\n\n comment(token) {\n let node = new Comment()\n this.init(node, token[2])\n node.source.end = this.getPosition(token[3] || token[2])\n node.source.end.offset++\n\n let text = token[1].slice(2, -2)\n if (!text.trim()) {\n node.text = ''\n node.raws.left = text\n node.raws.right = ''\n } else {\n let match = text.match(/^(\\s*)([^]*\\S)(\\s*)$/)\n node.text = match[2]\n node.raws.left = match[1]\n node.raws.right = match[3]\n }\n }\n\n createTokenizer() {\n this.tokenizer = tokenizer(this.input)\n }\n\n decl(tokens, customProperty) {\n let node = new Declaration()\n this.init(node, tokens[0][2])\n\n let last = tokens[tokens.length - 1]\n if (last[0] === ';') {\n this.semicolon = true\n tokens.pop()\n }\n\n node.source.end = this.getPosition(\n last[3] || last[2] || findLastWithPosition(tokens)\n )\n node.source.end.offset++\n\n let start = 0\n while (tokens[start][0] !== 'word') {\n if (start === tokens.length - 1) this.unknownWord([tokens[start]])\n start++\n }\n node.raws.before += tokensToString(tokens, 0, start)\n node.source.start = this.getPosition(tokens[start][2])\n\n let propStart = start\n while (start < tokens.length) {\n let type = tokens[start][0]\n if (type === ':' || type === 'space' || type === 'comment') {\n break\n }\n start++\n }\n node.prop = tokensToString(tokens, propStart, start)\n\n let betweenStart = start\n let token\n while (start < tokens.length) {\n token = tokens[start]\n start++\n if (token[0] === ':') break\n if (token[0] === 'word' && /\\w/.test(token[1])) {\n this.unknownWord([token])\n }\n }\n node.raws.between = tokensToString(tokens, betweenStart, start)\n\n if (node.prop[0] === '_' || node.prop[0] === '*') {\n node.raws.before += node.prop[0]\n node.prop = node.prop.slice(1)\n }\n\n let firstSpacesStart = start\n while (start < tokens.length) {\n let next = tokens[start][0]\n if (next !== 'space' && next !== 'comment') break\n start++\n }\n let firstSpaces = tokens.slice(firstSpacesStart, start)\n\n tokens = tokens.slice(start)\n\n this.precheckMissedSemicolon(tokens)\n\n for (let i = tokens.length - 1; i >= 0; i--) {\n token = tokens[i]\n if (token[1].toLowerCase() === '!important') {\n node.important = true\n let string = this.stringFrom(tokens, i)\n string = this.spacesFromEnd(tokens) + string\n if (string !== ' !important') node.raws.important = string\n break\n } else if (token[1].toLowerCase() === 'important') {\n let cache = tokens.slice(0)\n let str = ''\n for (let j = i; j > 0; j--) {\n let type = cache[j][0]\n if (str.trim().startsWith('!') && type !== 'space') {\n break\n }\n str = cache.pop()[1] + str\n }\n if (str.trim().startsWith('!')) {\n node.important = true\n node.raws.important = str\n tokens = cache\n }\n }\n\n if (token[0] !== 'space' && token[0] !== 'comment') {\n break\n }\n }\n\n let hasWord = tokens.some(i => i[0] !== 'space' && i[0] !== 'comment')\n\n if (hasWord) {\n node.raws.between += firstSpaces.map(i => i[1]).join('')\n firstSpaces = []\n }\n this.raw(node, 'value', firstSpaces.concat(tokens), customProperty)\n\n if (node.value.includes(':') && !customProperty) {\n this.checkMissedSemicolon(tokens)\n }\n }\n\n doubleColon(token) {\n throw this.input.error(\n 'Double colon',\n { offset: token[2] },\n { offset: token[2] + token[1].length }\n )\n }\n\n emptyRule(token) {\n let node = new Rule()\n this.init(node, token[2])\n node.selector = ''\n node.raws.between = ''\n this.current = node\n }\n\n end(token) {\n if (this.current.nodes && this.current.nodes.length) {\n this.current.raws.semicolon = this.semicolon\n }\n this.semicolon = false\n\n this.current.raws.after = (this.current.raws.after || '') + this.spaces\n this.spaces = ''\n\n if (this.current.parent) {\n this.current.source.end = this.getPosition(token[2])\n this.current.source.end.offset++\n this.current = this.current.parent\n } else {\n this.unexpectedClose(token)\n }\n }\n\n endFile() {\n if (this.current.parent) this.unclosedBlock()\n if (this.current.nodes && this.current.nodes.length) {\n this.current.raws.semicolon = this.semicolon\n }\n this.current.raws.after = (this.current.raws.after || '') + this.spaces\n this.root.source.end = this.getPosition(this.tokenizer.position())\n }\n\n freeSemicolon(token) {\n this.spaces += token[1]\n if (this.current.nodes) {\n let prev = this.current.nodes[this.current.nodes.length - 1]\n if (prev && prev.type === 'rule' && !prev.raws.ownSemicolon) {\n prev.raws.ownSemicolon = this.spaces\n this.spaces = ''\n prev.source.end = this.getPosition(token[2])\n prev.source.end.offset += prev.raws.ownSemicolon.length\n }\n }\n }\n\n // Helpers\n\n getPosition(offset) {\n let pos = this.input.fromOffset(offset)\n return {\n column: pos.col,\n line: pos.line,\n offset\n }\n }\n\n init(node, offset) {\n this.current.push(node)\n node.source = {\n input: this.input,\n start: this.getPosition(offset)\n }\n node.raws.before = this.spaces\n this.spaces = ''\n if (node.type !== 'comment') this.semicolon = false\n }\n\n other(start) {\n let end = false\n let type = null\n let colon = false\n let bracket = null\n let brackets = []\n let customProperty = start[1].startsWith('--')\n\n let tokens = []\n let token = start\n while (token) {\n type = token[0]\n tokens.push(token)\n\n if (type === '(' || type === '[') {\n if (!bracket) bracket = token\n brackets.push(type === '(' ? ')' : ']')\n } else if (customProperty && colon && type === '{') {\n if (!bracket) bracket = token\n brackets.push('}')\n } else if (brackets.length === 0) {\n if (type === ';') {\n if (colon) {\n this.decl(tokens, customProperty)\n return\n } else {\n break\n }\n } else if (type === '{') {\n this.rule(tokens)\n return\n } else if (type === '}') {\n this.tokenizer.back(tokens.pop())\n end = true\n break\n } else if (type === ':') {\n colon = true\n }\n } else if (type === brackets[brackets.length - 1]) {\n brackets.pop()\n if (brackets.length === 0) bracket = null\n }\n\n token = this.tokenizer.nextToken()\n }\n\n if (this.tokenizer.endOfFile()) end = true\n if (brackets.length > 0) this.unclosedBracket(bracket)\n\n if (end && colon) {\n if (!customProperty) {\n while (tokens.length) {\n token = tokens[tokens.length - 1][0]\n if (token !== 'space' && token !== 'comment') break\n this.tokenizer.back(tokens.pop())\n }\n }\n this.decl(tokens, customProperty)\n } else {\n this.unknownWord(tokens)\n }\n }\n\n parse() {\n let token\n while (!this.tokenizer.endOfFile()) {\n token = this.tokenizer.nextToken()\n\n switch (token[0]) {\n case 'space':\n this.spaces += token[1]\n break\n\n case ';':\n this.freeSemicolon(token)\n break\n\n case '}':\n this.end(token)\n break\n\n case 'comment':\n this.comment(token)\n break\n\n case 'at-word':\n this.atrule(token)\n break\n\n case '{':\n this.emptyRule(token)\n break\n\n default:\n this.other(token)\n break\n }\n }\n this.endFile()\n }\n\n precheckMissedSemicolon(/* tokens */) {\n // Hook for Safe Parser\n }\n\n raw(node, prop, tokens, customProperty) {\n let token, type\n let length = tokens.length\n let value = ''\n let clean = true\n let next, prev\n\n for (let i = 0; i < length; i += 1) {\n token = tokens[i]\n type = token[0]\n if (type === 'space' && i === length - 1 && !customProperty) {\n clean = false\n } else if (type === 'comment') {\n prev = tokens[i - 1] ? tokens[i - 1][0] : 'empty'\n next = tokens[i + 1] ? tokens[i + 1][0] : 'empty'\n if (!SAFE_COMMENT_NEIGHBOR[prev] && !SAFE_COMMENT_NEIGHBOR[next]) {\n if (value.slice(-1) === ',') {\n clean = false\n } else {\n value += token[1]\n }\n } else {\n clean = false\n }\n } else {\n value += token[1]\n }\n }\n if (!clean) {\n let raw = tokens.reduce((all, i) => all + i[1], '')\n node.raws[prop] = { raw, value }\n }\n node[prop] = value\n }\n\n rule(tokens) {\n tokens.pop()\n\n let node = new Rule()\n this.init(node, tokens[0][2])\n\n node.raws.between = this.spacesAndCommentsFromEnd(tokens)\n this.raw(node, 'selector', tokens)\n this.current = node\n }\n\n spacesAndCommentsFromEnd(tokens) {\n let lastTokenType\n let spaces = ''\n while (tokens.length) {\n lastTokenType = tokens[tokens.length - 1][0]\n if (lastTokenType !== 'space' && lastTokenType !== 'comment') break\n spaces = tokens.pop()[1] + spaces\n }\n return spaces\n }\n\n // Errors\n\n spacesAndCommentsFromStart(tokens) {\n let next\n let spaces = ''\n while (tokens.length) {\n next = tokens[0][0]\n if (next !== 'space' && next !== 'comment') break\n spaces += tokens.shift()[1]\n }\n return spaces\n }\n\n spacesFromEnd(tokens) {\n let lastTokenType\n let spaces = ''\n while (tokens.length) {\n lastTokenType = tokens[tokens.length - 1][0]\n if (lastTokenType !== 'space') break\n spaces = tokens.pop()[1] + spaces\n }\n return spaces\n }\n\n stringFrom(tokens, from) {\n let result = ''\n for (let i = from; i < tokens.length; i++) {\n result += tokens[i][1]\n }\n tokens.splice(from, tokens.length - from)\n return result\n }\n\n unclosedBlock() {\n let pos = this.current.source.start\n throw this.input.error('Unclosed block', pos.line, pos.column)\n }\n\n unclosedBracket(bracket) {\n throw this.input.error(\n 'Unclosed bracket',\n { offset: bracket[2] },\n { offset: bracket[2] + 1 }\n )\n }\n\n unexpectedClose(token) {\n throw this.input.error(\n 'Unexpected }',\n { offset: token[2] },\n { offset: token[2] + 1 }\n )\n }\n\n unknownWord(tokens) {\n throw this.input.error(\n 'Unknown word ' + tokens[0][1],\n { offset: tokens[0][2] },\n { offset: tokens[0][2] + tokens[0][1].length }\n )\n }\n\n unnamedAtrule(node, token) {\n throw this.input.error(\n 'At-rule without name',\n { offset: token[2] },\n { offset: token[2] + token[1].length }\n )\n }\n}\n\nmodule.exports = Parser\n","'use strict'\n\nlet Container = require('./container')\nlet Input = require('./input')\nlet Parser = require('./parser')\n\nfunction parse(css, opts) {\n let input = new Input(css, opts)\n let parser = new Parser(input)\n try {\n parser.parse()\n } catch (e) {\n if (process.env.NODE_ENV !== 'production') {\n if (e.name === 'CssSyntaxError' && opts && opts.from) {\n if (/\\.scss$/i.test(opts.from)) {\n e.message +=\n '\\nYou tried to parse SCSS with ' +\n 'the standard CSS parser; ' +\n 'try again with the postcss-scss parser'\n } else if (/\\.sass/i.test(opts.from)) {\n e.message +=\n '\\nYou tried to parse Sass with ' +\n 'the standard CSS parser; ' +\n 'try again with the postcss-sass parser'\n } else if (/\\.less$/i.test(opts.from)) {\n e.message +=\n '\\nYou tried to parse Less with ' +\n 'the standard CSS parser; ' +\n 'try again with the postcss-less parser'\n }\n }\n }\n throw e\n }\n\n return parser.root\n}\n\nmodule.exports = parse\nparse.default = parse\n\nContainer.registerParse(parse)\n","'use strict'\n\nclass Warning {\n constructor(text, opts = {}) {\n this.type = 'warning'\n this.text = text\n\n if (opts.node && opts.node.source) {\n let range = opts.node.rangeBy(opts)\n this.line = range.start.line\n this.column = range.start.column\n this.endLine = range.end.line\n this.endColumn = range.end.column\n }\n\n for (let opt in opts) this[opt] = opts[opt]\n }\n\n toString() {\n if (this.node) {\n return this.node.error(this.text, {\n index: this.index,\n plugin: this.plugin,\n word: this.word\n }).message\n }\n\n if (this.plugin) {\n return this.plugin + ': ' + this.text\n }\n\n return this.text\n }\n}\n\nmodule.exports = Warning\nWarning.default = Warning\n","'use strict'\n\nlet Warning = require('./warning')\n\nclass Result {\n get content() {\n return this.css\n }\n\n constructor(processor, root, opts) {\n this.processor = processor\n this.messages = []\n this.root = root\n this.opts = opts\n this.css = ''\n this.map = undefined\n }\n\n toString() {\n return this.css\n }\n\n warn(text, opts = {}) {\n if (!opts.plugin) {\n if (this.lastPlugin && this.lastPlugin.postcssPlugin) {\n opts.plugin = this.lastPlugin.postcssPlugin\n }\n }\n\n let warning = new Warning(text, opts)\n this.messages.push(warning)\n\n return warning\n }\n\n warnings() {\n return this.messages.filter(i => i.type === 'warning')\n }\n}\n\nmodule.exports = Result\nResult.default = Result\n","/* eslint-disable no-console */\n'use strict'\n\nlet printed = {}\n\nmodule.exports = function warnOnce(message) {\n if (printed[message]) return\n printed[message] = true\n\n if (typeof console !== 'undefined' && console.warn) {\n console.warn(message)\n }\n}\n","'use strict'\n\nlet Container = require('./container')\nlet Document = require('./document')\nlet MapGenerator = require('./map-generator')\nlet parse = require('./parse')\nlet Result = require('./result')\nlet Root = require('./root')\nlet stringify = require('./stringify')\nlet { isClean, my } = require('./symbols')\nlet warnOnce = require('./warn-once')\n\nconst TYPE_TO_CLASS_NAME = {\n atrule: 'AtRule',\n comment: 'Comment',\n decl: 'Declaration',\n document: 'Document',\n root: 'Root',\n rule: 'Rule'\n}\n\nconst PLUGIN_PROPS = {\n AtRule: true,\n AtRuleExit: true,\n Comment: true,\n CommentExit: true,\n Declaration: true,\n DeclarationExit: true,\n Document: true,\n DocumentExit: true,\n Once: true,\n OnceExit: true,\n postcssPlugin: true,\n prepare: true,\n Root: true,\n RootExit: true,\n Rule: true,\n RuleExit: true\n}\n\nconst NOT_VISITORS = {\n Once: true,\n postcssPlugin: true,\n prepare: true\n}\n\nconst CHILDREN = 0\n\nfunction isPromise(obj) {\n return typeof obj === 'object' && typeof obj.then === 'function'\n}\n\nfunction getEvents(node) {\n let key = false\n let type = TYPE_TO_CLASS_NAME[node.type]\n if (node.type === 'decl') {\n key = node.prop.toLowerCase()\n } else if (node.type === 'atrule') {\n key = node.name.toLowerCase()\n }\n\n if (key && node.append) {\n return [\n type,\n type + '-' + key,\n CHILDREN,\n type + 'Exit',\n type + 'Exit-' + key\n ]\n } else if (key) {\n return [type, type + '-' + key, type + 'Exit', type + 'Exit-' + key]\n } else if (node.append) {\n return [type, CHILDREN, type + 'Exit']\n } else {\n return [type, type + 'Exit']\n }\n}\n\nfunction toStack(node) {\n let events\n if (node.type === 'document') {\n events = ['Document', CHILDREN, 'DocumentExit']\n } else if (node.type === 'root') {\n events = ['Root', CHILDREN, 'RootExit']\n } else {\n events = getEvents(node)\n }\n\n return {\n eventIndex: 0,\n events,\n iterator: 0,\n node,\n visitorIndex: 0,\n visitors: []\n }\n}\n\nfunction cleanMarks(node) {\n node[isClean] = false\n if (node.nodes) node.nodes.forEach(i => cleanMarks(i))\n return node\n}\n\nlet postcss = {}\n\nclass LazyResult {\n get content() {\n return this.stringify().content\n }\n\n get css() {\n return this.stringify().css\n }\n\n get map() {\n return this.stringify().map\n }\n\n get messages() {\n return this.sync().messages\n }\n\n get opts() {\n return this.result.opts\n }\n\n get processor() {\n return this.result.processor\n }\n\n get root() {\n return this.sync().root\n }\n\n get [Symbol.toStringTag]() {\n return 'LazyResult'\n }\n\n constructor(processor, css, opts) {\n this.stringified = false\n this.processed = false\n\n let root\n if (\n typeof css === 'object' &&\n css !== null &&\n (css.type === 'root' || css.type === 'document')\n ) {\n root = cleanMarks(css)\n } else if (css instanceof LazyResult || css instanceof Result) {\n root = cleanMarks(css.root)\n if (css.map) {\n if (typeof opts.map === 'undefined') opts.map = {}\n if (!opts.map.inline) opts.map.inline = false\n opts.map.prev = css.map\n }\n } else {\n let parser = parse\n if (opts.syntax) parser = opts.syntax.parse\n if (opts.parser) parser = opts.parser\n if (parser.parse) parser = parser.parse\n\n try {\n root = parser(css, opts)\n } catch (error) {\n this.processed = true\n this.error = error\n }\n\n if (root && !root[my]) {\n /* c8 ignore next 2 */\n Container.rebuild(root)\n }\n }\n\n this.result = new Result(processor, root, opts)\n this.helpers = { ...postcss, postcss, result: this.result }\n this.plugins = this.processor.plugins.map(plugin => {\n if (typeof plugin === 'object' && plugin.prepare) {\n return { ...plugin, ...plugin.prepare(this.result) }\n } else {\n return plugin\n }\n })\n }\n\n async() {\n if (this.error) return Promise.reject(this.error)\n if (this.processed) return Promise.resolve(this.result)\n if (!this.processing) {\n this.processing = this.runAsync()\n }\n return this.processing\n }\n\n catch(onRejected) {\n return this.async().catch(onRejected)\n }\n\n finally(onFinally) {\n return this.async().then(onFinally, onFinally)\n }\n\n getAsyncError() {\n throw new Error('Use process(css).then(cb) to work with async plugins')\n }\n\n handleError(error, node) {\n let plugin = this.result.lastPlugin\n try {\n if (node) node.addToError(error)\n this.error = error\n if (error.name === 'CssSyntaxError' && !error.plugin) {\n error.plugin = plugin.postcssPlugin\n error.setMessage()\n } else if (plugin.postcssVersion) {\n if (process.env.NODE_ENV !== 'production') {\n let pluginName = plugin.postcssPlugin\n let pluginVer = plugin.postcssVersion\n let runtimeVer = this.result.processor.version\n let a = pluginVer.split('.')\n let b = runtimeVer.split('.')\n\n if (a[0] !== b[0] || parseInt(a[1]) > parseInt(b[1])) {\n // eslint-disable-next-line no-console\n console.error(\n 'Unknown error from PostCSS plugin. Your current PostCSS ' +\n 'version is ' +\n runtimeVer +\n ', but ' +\n pluginName +\n ' uses ' +\n pluginVer +\n '. Perhaps this is the source of the error below.'\n )\n }\n }\n }\n } catch (err) {\n /* c8 ignore next 3 */\n // eslint-disable-next-line no-console\n if (console && console.error) console.error(err)\n }\n return error\n }\n\n prepareVisitors() {\n this.listeners = {}\n let add = (plugin, type, cb) => {\n if (!this.listeners[type]) this.listeners[type] = []\n this.listeners[type].push([plugin, cb])\n }\n for (let plugin of this.plugins) {\n if (typeof plugin === 'object') {\n for (let event in plugin) {\n if (!PLUGIN_PROPS[event] && /^[A-Z]/.test(event)) {\n throw new Error(\n `Unknown event ${event} in ${plugin.postcssPlugin}. ` +\n `Try to update PostCSS (${this.processor.version} now).`\n )\n }\n if (!NOT_VISITORS[event]) {\n if (typeof plugin[event] === 'object') {\n for (let filter in plugin[event]) {\n if (filter === '*') {\n add(plugin, event, plugin[event][filter])\n } else {\n add(\n plugin,\n event + '-' + filter.toLowerCase(),\n plugin[event][filter]\n )\n }\n }\n } else if (typeof plugin[event] === 'function') {\n add(plugin, event, plugin[event])\n }\n }\n }\n }\n }\n this.hasListener = Object.keys(this.listeners).length > 0\n }\n\n async runAsync() {\n this.plugin = 0\n for (let i = 0; i < this.plugins.length; i++) {\n let plugin = this.plugins[i]\n let promise = this.runOnRoot(plugin)\n if (isPromise(promise)) {\n try {\n await promise\n } catch (error) {\n throw this.handleError(error)\n }\n }\n }\n\n this.prepareVisitors()\n if (this.hasListener) {\n let root = this.result.root\n while (!root[isClean]) {\n root[isClean] = true\n let stack = [toStack(root)]\n while (stack.length > 0) {\n let promise = this.visitTick(stack)\n if (isPromise(promise)) {\n try {\n await promise\n } catch (e) {\n let node = stack[stack.length - 1].node\n throw this.handleError(e, node)\n }\n }\n }\n }\n\n if (this.listeners.OnceExit) {\n for (let [plugin, visitor] of this.listeners.OnceExit) {\n this.result.lastPlugin = plugin\n try {\n if (root.type === 'document') {\n let roots = root.nodes.map(subRoot =>\n visitor(subRoot, this.helpers)\n )\n\n await Promise.all(roots)\n } else {\n await visitor(root, this.helpers)\n }\n } catch (e) {\n throw this.handleError(e)\n }\n }\n }\n }\n\n this.processed = true\n return this.stringify()\n }\n\n runOnRoot(plugin) {\n this.result.lastPlugin = plugin\n try {\n if (typeof plugin === 'object' && plugin.Once) {\n if (this.result.root.type === 'document') {\n let roots = this.result.root.nodes.map(root =>\n plugin.Once(root, this.helpers)\n )\n\n if (isPromise(roots[0])) {\n return Promise.all(roots)\n }\n\n return roots\n }\n\n return plugin.Once(this.result.root, this.helpers)\n } else if (typeof plugin === 'function') {\n return plugin(this.result.root, this.result)\n }\n } catch (error) {\n throw this.handleError(error)\n }\n }\n\n stringify() {\n if (this.error) throw this.error\n if (this.stringified) return this.result\n this.stringified = true\n\n this.sync()\n\n let opts = this.result.opts\n let str = stringify\n if (opts.syntax) str = opts.syntax.stringify\n if (opts.stringifier) str = opts.stringifier\n if (str.stringify) str = str.stringify\n\n let rootSource = this.result.root.source\n if (\n opts.map === undefined &&\n !(rootSource && rootSource.input && rootSource.input.map)\n ) {\n let result = ''\n str(this.result.root, i => {\n result += i\n })\n this.result.css = result\n return this.result\n }\n\n let map = new MapGenerator(str, this.result.root, this.result.opts)\n let data = map.generate()\n this.result.css = data[0]\n this.result.map = data[1]\n\n return this.result\n }\n\n sync() {\n if (this.error) throw this.error\n if (this.processed) return this.result\n this.processed = true\n\n if (this.processing) {\n throw this.getAsyncError()\n }\n\n for (let plugin of this.plugins) {\n let promise = this.runOnRoot(plugin)\n if (isPromise(promise)) {\n throw this.getAsyncError()\n }\n }\n\n this.prepareVisitors()\n if (this.hasListener) {\n let root = this.result.root\n while (!root[isClean]) {\n root[isClean] = true\n this.walkSync(root)\n }\n if (this.listeners.OnceExit) {\n if (root.type === 'document') {\n for (let subRoot of root.nodes) {\n this.visitSync(this.listeners.OnceExit, subRoot)\n }\n } else {\n this.visitSync(this.listeners.OnceExit, root)\n }\n }\n }\n\n return this.result\n }\n\n then(onFulfilled, onRejected) {\n if (process.env.NODE_ENV !== 'production') {\n if (!('from' in this.opts)) {\n warnOnce(\n 'Without `from` option PostCSS could generate wrong source map ' +\n 'and will not find Browserslist config. Set it to CSS file path ' +\n 'or to `undefined` to prevent this warning.'\n )\n }\n }\n return this.async().then(onFulfilled, onRejected)\n }\n\n toString() {\n return this.css\n }\n\n visitSync(visitors, node) {\n for (let [plugin, visitor] of visitors) {\n this.result.lastPlugin = plugin\n let promise\n try {\n promise = visitor(node, this.helpers)\n } catch (e) {\n throw this.handleError(e, node.proxyOf)\n }\n if (node.type !== 'root' && node.type !== 'document' && !node.parent) {\n return true\n }\n if (isPromise(promise)) {\n throw this.getAsyncError()\n }\n }\n }\n\n visitTick(stack) {\n let visit = stack[stack.length - 1]\n let { node, visitors } = visit\n\n if (node.type !== 'root' && node.type !== 'document' && !node.parent) {\n stack.pop()\n return\n }\n\n if (visitors.length > 0 && visit.visitorIndex < visitors.length) {\n let [plugin, visitor] = visitors[visit.visitorIndex]\n visit.visitorIndex += 1\n if (visit.visitorIndex === visitors.length) {\n visit.visitors = []\n visit.visitorIndex = 0\n }\n this.result.lastPlugin = plugin\n try {\n return visitor(node.toProxy(), this.helpers)\n } catch (e) {\n throw this.handleError(e, node)\n }\n }\n\n if (visit.iterator !== 0) {\n let iterator = visit.iterator\n let child\n while ((child = node.nodes[node.indexes[iterator]])) {\n node.indexes[iterator] += 1\n if (!child[isClean]) {\n child[isClean] = true\n stack.push(toStack(child))\n return\n }\n }\n visit.iterator = 0\n delete node.indexes[iterator]\n }\n\n let events = visit.events\n while (visit.eventIndex < events.length) {\n let event = events[visit.eventIndex]\n visit.eventIndex += 1\n if (event === CHILDREN) {\n if (node.nodes && node.nodes.length) {\n node[isClean] = true\n visit.iterator = node.getIterator()\n }\n return\n } else if (this.listeners[event]) {\n visit.visitors = this.listeners[event]\n return\n }\n }\n stack.pop()\n }\n\n walkSync(node) {\n node[isClean] = true\n let events = getEvents(node)\n for (let event of events) {\n if (event === CHILDREN) {\n if (node.nodes) {\n node.each(child => {\n if (!child[isClean]) this.walkSync(child)\n })\n }\n } else {\n let visitors = this.listeners[event]\n if (visitors) {\n if (this.visitSync(visitors, node.toProxy())) return\n }\n }\n }\n }\n\n warnings() {\n return this.sync().warnings()\n }\n}\n\nLazyResult.registerPostcss = dependant => {\n postcss = dependant\n}\n\nmodule.exports = LazyResult\nLazyResult.default = LazyResult\n\nRoot.registerLazyResult(LazyResult)\nDocument.registerLazyResult(LazyResult)\n","'use strict'\n\nlet AtRule = require('./at-rule')\nlet Comment = require('./comment')\nlet Container = require('./container')\nlet CssSyntaxError = require('./css-syntax-error')\nlet Declaration = require('./declaration')\nlet Document = require('./document')\nlet fromJSON = require('./fromJSON')\nlet Input = require('./input')\nlet LazyResult = require('./lazy-result')\nlet list = require('./list')\nlet Node = require('./node')\nlet parse = require('./parse')\nlet Processor = require('./processor')\nlet Result = require('./result.js')\nlet Root = require('./root')\nlet Rule = require('./rule')\nlet stringify = require('./stringify')\nlet Warning = require('./warning')\n\nfunction postcss(...plugins) {\n if (plugins.length === 1 && Array.isArray(plugins[0])) {\n plugins = plugins[0]\n }\n return new Processor(plugins)\n}\n\npostcss.plugin = function plugin(name, initializer) {\n let warningPrinted = false\n function creator(...args) {\n // eslint-disable-next-line no-console\n if (console && console.warn && !warningPrinted) {\n warningPrinted = true\n // eslint-disable-next-line no-console\n console.warn(\n name +\n ': postcss.plugin was deprecated. Migration guide:\\n' +\n 'https://evilmartians.com/chronicles/postcss-8-plugin-migration'\n )\n if (process.env.LANG && process.env.LANG.startsWith('cn')) {\n /* c8 ignore next 7 */\n // eslint-disable-next-line no-console\n console.warn(\n name +\n ': 里面 postcss.plugin 被弃用. 迁移指南:\\n' +\n 'https://www.w3ctech.com/topic/2226'\n )\n }\n }\n let transformer = initializer(...args)\n transformer.postcssPlugin = name\n transformer.postcssVersion = new Processor().version\n return transformer\n }\n\n let cache\n Object.defineProperty(creator, 'postcss', {\n get() {\n if (!cache) cache = creator()\n return cache\n }\n })\n\n creator.process = function (css, processOpts, pluginOpts) {\n return postcss([creator(pluginOpts)]).process(css, processOpts)\n }\n\n return creator\n}\n\npostcss.stringify = stringify\npostcss.parse = parse\npostcss.fromJSON = fromJSON\npostcss.list = list\n\npostcss.comment = defaults => new Comment(defaults)\npostcss.atRule = defaults => new AtRule(defaults)\npostcss.decl = defaults => new Declaration(defaults)\npostcss.rule = defaults => new Rule(defaults)\npostcss.root = defaults => new Root(defaults)\npostcss.document = defaults => new Document(defaults)\n\npostcss.CssSyntaxError = CssSyntaxError\npostcss.Declaration = Declaration\npostcss.Container = Container\npostcss.Processor = Processor\npostcss.Document = Document\npostcss.Comment = Comment\npostcss.Warning = Warning\npostcss.AtRule = AtRule\npostcss.Result = Result\npostcss.Input = Input\npostcss.Rule = Rule\npostcss.Root = Root\npostcss.Node = Node\n\nLazyResult.registerPostcss(postcss)\n\nmodule.exports = postcss\npostcss.default = postcss\n","'use strict'\n\nlet AtRule = require('./at-rule')\nlet Comment = require('./comment')\nlet Declaration = require('./declaration')\nlet Input = require('./input')\nlet PreviousMap = require('./previous-map')\nlet Root = require('./root')\nlet Rule = require('./rule')\n\nfunction fromJSON(json, inputs) {\n if (Array.isArray(json)) return json.map(n => fromJSON(n))\n\n let { inputs: ownInputs, ...defaults } = json\n if (ownInputs) {\n inputs = []\n for (let input of ownInputs) {\n let inputHydrated = { ...input, __proto__: Input.prototype }\n if (inputHydrated.map) {\n inputHydrated.map = {\n ...inputHydrated.map,\n __proto__: PreviousMap.prototype\n }\n }\n inputs.push(inputHydrated)\n }\n }\n // Rehydrate children separately and attach them after construction.\n // Passing them through the container constructor would re-run insertion\n // spacing normalization and overwrite each child's own `raws.before`.\n let nodes\n if (defaults.nodes) {\n nodes = json.nodes.map(n => fromJSON(n, inputs))\n delete defaults.nodes\n }\n if (defaults.source) {\n let { inputId, ...source } = defaults.source\n defaults.source = source\n if (inputId != null) {\n defaults.source.input = inputs[inputId]\n }\n }\n\n let node\n if (defaults.type === 'root') {\n node = new Root(defaults)\n } else if (defaults.type === 'decl') {\n node = new Declaration(defaults)\n } else if (defaults.type === 'rule') {\n node = new Rule(defaults)\n } else if (defaults.type === 'comment') {\n node = new Comment(defaults)\n } else if (defaults.type === 'atrule') {\n node = new AtRule(defaults)\n } else {\n throw new Error('Unknown node type: ' + json.type)\n }\n\n if (nodes) {\n node.nodes = nodes\n for (let child of nodes) child.parent = node\n }\n\n return node\n}\n\nmodule.exports = fromJSON\nfromJSON.default = fromJSON\n","'use strict'\n\nlet Document = require('./document')\nlet LazyResult = require('./lazy-result')\nlet NoWorkResult = require('./no-work-result')\nlet Root = require('./root')\n\nclass Processor {\n constructor(plugins = []) {\n this.version = '8.5.16'\n this.plugins = this.normalize(plugins)\n }\n\n normalize(plugins) {\n let normalized = []\n for (let i of plugins) {\n if (i.postcss === true) {\n i = i()\n } else if (i.postcss) {\n i = i.postcss\n }\n\n if (typeof i === 'object' && Array.isArray(i.plugins)) {\n normalized = normalized.concat(i.plugins)\n } else if (typeof i === 'object' && i.postcssPlugin) {\n normalized.push(i)\n } else if (typeof i === 'function') {\n normalized.push(i)\n } else if (typeof i === 'object' && (i.parse || i.stringify)) {\n if (process.env.NODE_ENV !== 'production') {\n throw new Error(\n 'PostCSS syntaxes cannot be used as plugins. Instead, please use ' +\n 'one of the syntax/parser/stringifier options as outlined ' +\n 'in your PostCSS runner documentation.'\n )\n }\n } else {\n throw new Error(i + ' is not a PostCSS plugin')\n }\n }\n return normalized\n }\n\n process(css, opts = {}) {\n if (\n !this.plugins.length &&\n !opts.parser &&\n !opts.stringifier &&\n !opts.syntax\n ) {\n return new NoWorkResult(this, css, opts)\n } else {\n return new LazyResult(this, css, opts)\n }\n }\n\n use(plugin) {\n this.plugins = this.plugins.concat(this.normalize([plugin]))\n return this\n }\n}\n\nmodule.exports = Processor\nProcessor.default = Processor\n\nRoot.registerProcessor(Processor)\nDocument.registerProcessor(Processor)\n","'use strict'\n\nlet MapGenerator = require('./map-generator')\nlet parse = require('./parse')\nlet Result = require('./result')\nlet stringify = require('./stringify')\nlet warnOnce = require('./warn-once')\n\nclass NoWorkResult {\n get content() {\n return this.result.css\n }\n\n get css() {\n return this.result.css\n }\n\n get map() {\n return this.result.map\n }\n\n get messages() {\n return []\n }\n\n get opts() {\n return this.result.opts\n }\n\n get processor() {\n return this.result.processor\n }\n\n get root() {\n if (this._root) {\n return this._root\n }\n\n let root\n let parser = parse\n\n try {\n root = parser(this._css, this._opts)\n } catch (error) {\n this.error = error\n }\n\n if (this.error) {\n throw this.error\n } else {\n this._root = root\n return root\n }\n }\n\n get [Symbol.toStringTag]() {\n return 'NoWorkResult'\n }\n\n constructor(processor, css, opts) {\n css = css.toString()\n this.stringified = false\n\n this._processor = processor\n this._css = css\n this._opts = opts\n this._map = undefined\n\n let str = stringify\n this.result = new Result(this._processor, undefined, this._opts)\n this.result.css = css\n\n let self = this\n Object.defineProperty(this.result, 'root', {\n get() {\n return self.root\n }\n })\n\n let map = new MapGenerator(str, undefined, this._opts, css)\n if (map.isMap()) {\n let [generatedCSS, generatedMap] = map.generate()\n if (generatedCSS) {\n this.result.css = generatedCSS\n }\n if (generatedMap) {\n this.result.map = generatedMap\n }\n } else {\n map.clearAnnotation()\n this.result.css = map.css\n }\n }\n\n async() {\n if (this.error) return Promise.reject(this.error)\n return Promise.resolve(this.result)\n }\n\n catch(onRejected) {\n return this.async().catch(onRejected)\n }\n\n finally(onFinally) {\n return this.async().then(onFinally, onFinally)\n }\n\n sync() {\n if (this.error) throw this.error\n return this.result\n }\n\n then(onFulfilled, onRejected) {\n if (process.env.NODE_ENV !== 'production') {\n if (!('from' in this._opts)) {\n warnOnce(\n 'Without `from` option PostCSS could generate wrong source map ' +\n 'and will not find Browserslist config. Set it to CSS file path ' +\n 'or to `undefined` to prevent this warning.'\n )\n }\n }\n\n return this.async().then(onFulfilled, onRejected)\n }\n\n toString() {\n return this._css\n }\n\n warnings() {\n return []\n }\n}\n\nmodule.exports = NoWorkResult\nNoWorkResult.default = NoWorkResult\n","let { Input } = require('postcss')\n\nlet SafeParser = require('./safe-parser')\n\nmodule.exports = function safeParse(css, opts) {\n let input = new Input(css, opts)\n\n let parser = new SafeParser(input)\n parser.parse()\n\n return parser.root\n}\n","let Comment = require('postcss/lib/comment')\nlet Parser = require('postcss/lib/parser')\nlet tokenizer = require('postcss/lib/tokenize')\n\nclass SafeParser extends Parser {\n checkMissedSemicolon() {}\n\n comment(token) {\n let node = new Comment()\n this.init(node, token[2])\n let pos =\n this.input.fromOffset(token[3]) ||\n this.input.fromOffset(this.input.css.length - 1)\n node.source.end = {\n column: pos.col,\n line: pos.line,\n offset: token[3] + 1\n }\n\n let text = token[1].slice(2)\n if (text.slice(-2) === '*/') text = text.slice(0, -2)\n\n if (/^\\s*$/.test(text)) {\n node.text = ''\n node.raws.left = text\n node.raws.right = ''\n } else {\n let match = text.match(/^(\\s*)([^]*\\S)(\\s*)$/)\n node.text = match[2]\n node.raws.left = match[1]\n node.raws.right = match[3]\n }\n }\n\n createTokenizer() {\n this.tokenizer = tokenizer(this.input, { ignoreErrors: true })\n }\n\n decl(tokens) {\n if (tokens.length > 1 && tokens.some(i => i[0] === 'word')) {\n super.decl(tokens)\n }\n }\n\n doubleColon() {}\n\n endFile() {\n if (this.current.nodes && this.current.nodes.length) {\n this.current.raws.semicolon = this.semicolon\n }\n this.current.raws.after = (this.current.raws.after || '') + this.spaces\n\n while (this.current.parent) {\n this.current = this.current.parent\n this.current.raws.after = ''\n }\n this.root.source.end = this.getPosition(this.tokenizer.position())\n }\n\n precheckMissedSemicolon(tokens) {\n let colon = this.colon(tokens)\n if (colon === false) return\n\n let nextStart, prevEnd\n for (nextStart = colon - 1; nextStart >= 0; nextStart--) {\n if (tokens[nextStart][0] === 'word') break\n }\n if (nextStart === 0 || nextStart < 0) return\n\n for (prevEnd = nextStart - 1; prevEnd >= 0; prevEnd--) {\n if (tokens[prevEnd][0] !== 'space') {\n prevEnd += 1\n break\n }\n }\n\n let other = tokens.slice(nextStart)\n let spaces = tokens.slice(prevEnd, nextStart)\n tokens.splice(prevEnd, tokens.length - prevEnd)\n this.spaces = spaces.map(i => i[1]).join('')\n\n this.decl(other)\n }\n\n unclosedBracket() {}\n\n unexpectedClose() {\n this.current.raws.after += '}'\n }\n\n unknownWord(tokens) {\n this.spaces += tokens.map(i => i[1]).join('')\n }\n\n unnamedAtrule(node) {\n node.name = ''\n }\n}\n\nmodule.exports = SafeParser\n","import postcss from './postcss.js'\n\nexport default postcss\n\nexport const stringify = postcss.stringify\nexport const fromJSON = postcss.fromJSON\nexport const plugin = postcss.plugin\nexport const parse = postcss.parse\nexport const list = postcss.list\n\nexport const document = postcss.document\nexport const comment = postcss.comment\nexport const atRule = postcss.atRule\nexport const rule = postcss.rule\nexport const decl = postcss.decl\nexport const root = postcss.root\n\nexport const CssSyntaxError = postcss.CssSyntaxError\nexport const Declaration = postcss.Declaration\nexport const Container = postcss.Container\nexport const Processor = postcss.Processor\nexport const Document = postcss.Document\nexport const Comment = postcss.Comment\nexport const Warning = postcss.Warning\nexport const AtRule = postcss.AtRule\nexport const Result = postcss.Result\nexport const Input = postcss.Input\nexport const Rule = postcss.Rule\nexport const Root = postcss.Root\nexport const Node = postcss.Node\n","// Modified by ELU. See NOTICE-ELU and THIRD_PARTY_NOTICES.txt.\n\nimport { NodeType as RRNodeType } from '@elu-labs/recorder-types';\nimport { parseCSSText, camelize, toCSSText } from './style';\nexport interface IRRNode {\n parentElement: IRRNode | null;\n parentNode: IRRNode | null;\n ownerDocument: IRRDocument;\n readonly childNodes: IRRNode[];\n readonly ELEMENT_NODE: number;\n readonly TEXT_NODE: number;\n // corresponding nodeType value of standard HTML Node\n readonly nodeType: number;\n readonly nodeName: string; // https://dom.spec.whatwg.org/#dom-node-nodename\n readonly RRNodeType: RRNodeType;\n\n firstChild: IRRNode | null;\n\n lastChild: IRRNode | null;\n\n previousSibling: IRRNode | null;\n\n nextSibling: IRRNode | null;\n\n // If the node is a document or a doctype, textContent returns null.\n textContent: string | null;\n\n contains(node: IRRNode): boolean;\n\n appendChild(newChild: IRRNode): IRRNode;\n\n insertBefore(newChild: IRRNode, refChild: IRRNode | null): IRRNode;\n\n removeChild(node: IRRNode): IRRNode;\n\n toString(): string;\n}\nexport interface IRRDocument extends IRRNode {\n documentElement: IRRElement | null;\n\n body: IRRElement | null;\n\n head: IRRElement | null;\n\n implementation: IRRDocument;\n\n firstElementChild: IRRElement | null;\n\n readonly nodeName: '#document';\n\n compatMode: 'BackCompat' | 'CSS1Compat';\n\n createDocument(\n _namespace: string | null,\n _qualifiedName: string | null,\n _doctype?: DocumentType | null,\n ): IRRDocument;\n\n createDocumentType(\n qualifiedName: string,\n publicId: string,\n systemId: string,\n ): IRRDocumentType;\n\n createElement(tagName: string): IRRElement;\n\n createElementNS(_namespaceURI: string, qualifiedName: string): IRRElement;\n\n createTextNode(data: string): IRRText;\n\n createComment(data: string): IRRComment;\n\n createCDATASection(data: string): IRRCDATASection;\n\n open(): void;\n\n close(): void;\n\n write(content: string): void;\n}\nexport interface IRRElement extends IRRNode {\n tagName: string;\n attributes: Record<string, string>;\n shadowRoot: IRRElement | null;\n scrollLeft?: number;\n scrollTop?: number;\n id: string;\n className: string;\n classList: ClassList;\n style: CSSStyleDeclaration;\n\n attachShadow(init: ShadowRootInit): IRRElement;\n\n getAttribute(name: string): string | null;\n\n setAttribute(name: string, attribute: string): void;\n\n setAttributeNS(\n namespace: string | null,\n qualifiedName: string,\n value: string,\n ): void;\n\n removeAttribute(name: string): void;\n\n dispatchEvent(event: Event): boolean;\n}\nexport interface IRRDocumentType extends IRRNode {\n readonly name: string;\n readonly publicId: string;\n readonly systemId: string;\n}\nexport interface IRRText extends IRRNode {\n readonly nodeName: '#text';\n data: string;\n}\nexport interface IRRComment extends IRRNode {\n readonly nodeName: '#comment';\n data: string;\n}\nexport interface IRRCDATASection extends IRRNode {\n readonly nodeName: '#cdata-section';\n data: string;\n}\n\n/**\n * This is designed as an abstract class so it should never be instantiated.\n */\nexport abstract class BaseRRNode implements IRRNode {\n public parentElement: IRRNode | null = null;\n public parentNode: IRRNode | null = null;\n public ownerDocument!: IRRDocument;\n public firstChild: IRRNode | null = null;\n public lastChild: IRRNode | null = null;\n public previousSibling: IRRNode | null = null;\n public nextSibling: IRRNode | null = null;\n\n public abstract textContent: string | null;\n\n public readonly ELEMENT_NODE: number = NodeType.ELEMENT_NODE;\n public readonly TEXT_NODE: number = NodeType.TEXT_NODE;\n // corresponding nodeType value of standard HTML Node\n public readonly nodeType!: number;\n public readonly nodeName!: string;\n public readonly RRNodeType!: RRNodeType;\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any\n constructor(..._args: any[]) {\n //\n }\n\n public get childNodes(): IRRNode[] {\n const childNodes: IRRNode[] = [];\n let childIterator: IRRNode | null = this.firstChild;\n while (childIterator) {\n childNodes.push(childIterator);\n childIterator = childIterator.nextSibling;\n }\n return childNodes;\n }\n\n public contains(node: IRRNode) {\n if (!(node instanceof BaseRRNode)) return false;\n else if (node.ownerDocument !== this.ownerDocument) return false;\n else if (node === this) return true;\n\n while (node.parentNode) {\n if (node.parentNode === this) return true;\n node = node.parentNode;\n }\n return false;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n public appendChild(_newChild: IRRNode): IRRNode {\n throw new Error(\n `RRDomException: Failed to execute 'appendChild' on 'RRNode': This RRNode type does not support this method.`,\n );\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n public insertBefore(_newChild: IRRNode, _refChild: IRRNode | null): IRRNode {\n throw new Error(\n `RRDomException: Failed to execute 'insertBefore' on 'RRNode': This RRNode type does not support this method.`,\n );\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n public removeChild(_node: IRRNode): IRRNode {\n throw new Error(\n `RRDomException: Failed to execute 'removeChild' on 'RRNode': This RRNode type does not support this method.`,\n );\n }\n\n public toString(): string {\n return 'RRNode';\n }\n}\n\nexport class BaseRRDocument extends BaseRRNode implements IRRDocument {\n public readonly nodeType: number = NodeType.DOCUMENT_NODE;\n public readonly nodeName = '#document' as const;\n public readonly compatMode: 'BackCompat' | 'CSS1Compat' = 'CSS1Compat';\n public readonly RRNodeType = RRNodeType.Document;\n public textContent: string | null = null;\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n constructor(...args: any[]) {\n super(args);\n this.ownerDocument = this;\n }\n\n public get documentElement(): IRRElement | null {\n return (\n (this.childNodes.find(\n (node) =>\n node.RRNodeType === RRNodeType.Element &&\n (node as IRRElement).tagName === 'HTML',\n ) as IRRElement) || null\n );\n }\n\n public get body(): IRRElement | null {\n return (\n (this.documentElement?.childNodes.find(\n (node) =>\n node.RRNodeType === RRNodeType.Element &&\n (node as IRRElement).tagName === 'BODY',\n ) as IRRElement) || null\n );\n }\n\n public get head(): IRRElement | null {\n return (\n (this.documentElement?.childNodes.find(\n (node) =>\n node.RRNodeType === RRNodeType.Element &&\n (node as IRRElement).tagName === 'HEAD',\n ) as IRRElement) || null\n );\n }\n\n public get implementation(): IRRDocument {\n return this;\n }\n\n public get firstElementChild(): IRRElement | null {\n return this.documentElement;\n }\n\n public appendChild(newChild: IRRNode): IRRNode {\n const nodeType = newChild.RRNodeType;\n if (\n nodeType === RRNodeType.Element ||\n nodeType === RRNodeType.DocumentType\n ) {\n if (this.childNodes.some((s) => s.RRNodeType === nodeType)) {\n throw new Error(\n `RRDomException: Failed to execute 'appendChild' on 'RRNode': Only one ${\n nodeType === RRNodeType.Element ? 'RRElement' : 'RRDoctype'\n } on RRDocument allowed.`,\n );\n }\n }\n\n const child = appendChild(this, newChild);\n child.parentElement = null;\n return child;\n }\n\n public insertBefore(newChild: IRRNode, refChild: IRRNode | null): IRRNode {\n const nodeType = newChild.RRNodeType;\n if (\n nodeType === RRNodeType.Element ||\n nodeType === RRNodeType.DocumentType\n ) {\n if (this.childNodes.some((s) => s.RRNodeType === nodeType)) {\n throw new Error(\n `RRDomException: Failed to execute 'insertBefore' on 'RRNode': Only one ${\n nodeType === RRNodeType.Element ? 'RRElement' : 'RRDoctype'\n } on RRDocument allowed.`,\n );\n }\n }\n\n const child = insertBefore(this, newChild, refChild);\n child.parentElement = null;\n return child;\n }\n\n public removeChild(node: IRRNode): IRRNode {\n return removeChild(this, node);\n }\n\n public open() {\n this.firstChild = null;\n this.lastChild = null;\n }\n\n public close() {\n //\n }\n\n /**\n * Adhoc implementation for setting xhtml namespace in rebuilt.ts (rrweb-snapshot).\n * There are two lines used this function:\n * 1. doc.write('\\<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"\"\\>')\n * 2. doc.write('\\<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\" \"\"\\>')\n */\n public write(content: string) {\n let publicId;\n if (\n content ===\n '<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"\">'\n )\n publicId = '-//W3C//DTD XHTML 1.0 Transitional//EN';\n else if (\n content ===\n '<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\" \"\">'\n )\n publicId = '-//W3C//DTD HTML 4.0 Transitional//EN';\n if (publicId) {\n const doctype = this.createDocumentType('html', publicId, '');\n this.open();\n this.appendChild(doctype);\n }\n }\n\n createDocument(\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n _namespace: string | null,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n _qualifiedName: string | null,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n _doctype?: DocumentType | null,\n ): IRRDocument {\n return new BaseRRDocument();\n }\n\n createDocumentType(\n qualifiedName: string,\n publicId: string,\n systemId: string,\n ): IRRDocumentType {\n const doctype = new BaseRRDocumentType(qualifiedName, publicId, systemId);\n doctype.ownerDocument = this;\n return doctype;\n }\n\n createElement(tagName: string): IRRElement {\n const element = new BaseRRElement(tagName);\n element.ownerDocument = this;\n return element;\n }\n\n createElementNS(_namespaceURI: string, qualifiedName: string): IRRElement {\n return this.createElement(qualifiedName);\n }\n\n createTextNode(data: string): IRRText {\n const text = new BaseRRText(data);\n text.ownerDocument = this;\n return text;\n }\n\n createComment(data: string): IRRComment {\n const comment = new BaseRRComment(data);\n comment.ownerDocument = this;\n return comment;\n }\n\n createCDATASection(data: string): IRRCDATASection {\n const CDATASection = new BaseRRCDATASection(data);\n CDATASection.ownerDocument = this;\n return CDATASection;\n }\n\n toString() {\n return 'RRDocument';\n }\n}\n\nexport class BaseRRDocumentType extends BaseRRNode implements IRRDocumentType {\n public readonly nodeType: number = NodeType.DOCUMENT_TYPE_NODE;\n public readonly RRNodeType = RRNodeType.DocumentType;\n declare readonly nodeName: string;\n public readonly name: string;\n public readonly publicId: string;\n public readonly systemId: string;\n public textContent: string | null = null;\n\n constructor(qualifiedName: string, publicId: string, systemId: string) {\n super();\n this.name = qualifiedName;\n this.publicId = publicId;\n this.systemId = systemId;\n this.nodeName = qualifiedName;\n }\n\n toString() {\n return 'RRDocumentType';\n }\n}\n\nexport class BaseRRElement extends BaseRRNode implements IRRElement {\n public readonly nodeType: number = NodeType.ELEMENT_NODE;\n public readonly RRNodeType = RRNodeType.Element;\n declare readonly nodeName: string;\n public tagName: string;\n public attributes: Record<string, string> = {};\n public shadowRoot: IRRElement | null = null;\n public scrollLeft?: number;\n public scrollTop?: number;\n\n constructor(tagName: string) {\n super();\n this.tagName = tagName.toUpperCase();\n this.nodeName = tagName.toUpperCase();\n }\n\n public get textContent(): string {\n let result = '';\n this.childNodes.forEach((node) => (result += node.textContent));\n return result;\n }\n\n public set textContent(textContent: string) {\n this.firstChild = null;\n this.lastChild = null;\n this.appendChild(this.ownerDocument.createTextNode(textContent));\n }\n\n public get classList(): ClassList {\n return new ClassList(\n this.attributes.class as string | undefined,\n (newClassName) => {\n this.attributes.class = newClassName;\n },\n );\n }\n\n public get id() {\n return this.attributes.id || '';\n }\n\n public get className() {\n return this.attributes.class || '';\n }\n\n public get style() {\n const style = (\n this.attributes.style ? parseCSSText(this.attributes.style) : {}\n ) as CSSStyleDeclaration;\n const hyphenateRE = /\\B([A-Z])/g;\n style.setProperty = (\n name: string,\n value: string | null,\n priority?: string | null,\n ) => {\n if (hyphenateRE.test(name)) return;\n const normalizedName = camelize(name);\n if (!value) delete style[normalizedName];\n else style[normalizedName] = value;\n if (priority === 'important') style[normalizedName] += ' !important';\n this.attributes.style = toCSSText(style);\n };\n style.removeProperty = (name: string) => {\n if (hyphenateRE.test(name)) return '';\n const normalizedName = camelize(name);\n const value = style[normalizedName] || '';\n delete style[normalizedName];\n this.attributes.style = toCSSText(style);\n return value;\n };\n return style;\n }\n\n public getAttribute(name: string): string | null {\n if (this.attributes[name] === undefined) return null;\n return this.attributes[name];\n }\n\n public setAttribute(name: string, attribute: string) {\n this.attributes[name] = attribute;\n }\n\n public setAttributeNS(\n _namespace: string | null,\n qualifiedName: string,\n value: string,\n ): void {\n this.setAttribute(qualifiedName, value);\n }\n\n public removeAttribute(name: string) {\n delete this.attributes[name];\n }\n\n public appendChild(newChild: IRRNode): IRRNode {\n return appendChild(this, newChild);\n }\n\n public insertBefore(newChild: IRRNode, refChild: IRRNode | null): IRRNode {\n return insertBefore(this, newChild, refChild);\n }\n\n public removeChild(node: IRRNode): IRRNode {\n return removeChild(this, node);\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n public attachShadow(_init: ShadowRootInit): IRRElement {\n const shadowRoot = this.ownerDocument.createElement('SHADOWROOT');\n this.shadowRoot = shadowRoot;\n return shadowRoot;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n public dispatchEvent(_event: Event) {\n return true;\n }\n\n toString() {\n let attributeString = '';\n for (const attribute in this.attributes) {\n attributeString += `${attribute}=\"${this.attributes[attribute]}\" `;\n }\n return `${this.tagName} ${attributeString}`;\n }\n}\n\nexport class BaseRRMediaElement extends BaseRRElement {\n public currentTime?: number;\n public volume?: number;\n public paused?: boolean;\n public muted?: boolean;\n public playbackRate?: number;\n public loop?: boolean;\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n attachShadow(_init: ShadowRootInit): IRRElement {\n throw new Error(\n `RRDomException: Failed to execute 'attachShadow' on 'RRElement': This RRElement does not support attachShadow`,\n );\n }\n public play() {\n this.paused = false;\n }\n public pause() {\n this.paused = true;\n }\n}\n\nexport class BaseRRDialogElement extends BaseRRElement {\n public readonly tagName = 'DIALOG' as const;\n public readonly nodeName = 'DIALOG' as const;\n\n get isModal() {\n return this.getAttribute('rr_open_mode') === 'modal';\n }\n get open() {\n return this.getAttribute('open') !== null;\n }\n public close() {\n this.removeAttribute('open');\n this.removeAttribute('rr_open_mode');\n }\n public show() {\n this.setAttribute('open', '');\n this.setAttribute('rr_open_mode', 'non-modal');\n }\n public showModal() {\n this.setAttribute('open', '');\n this.setAttribute('rr_open_mode', 'modal');\n }\n}\n\nexport class BaseRRText extends BaseRRNode implements IRRText {\n public readonly nodeType: number = NodeType.TEXT_NODE;\n public readonly nodeName = '#text' as const;\n public readonly RRNodeType = RRNodeType.Text;\n public data: string;\n\n constructor(data: string) {\n super();\n this.data = data;\n }\n\n public get textContent(): string {\n return this.data;\n }\n\n public set textContent(textContent: string) {\n // codeql[js/xss-through-dom] Virtual-DOM data store; never reinterpreted as HTML.\n this.data = textContent;\n }\n\n toString() {\n return `RRText text=${JSON.stringify(this.data)}`;\n }\n}\n\nexport class BaseRRComment extends BaseRRNode implements IRRComment {\n public readonly nodeType: number = NodeType.COMMENT_NODE;\n public readonly nodeName = '#comment' as const;\n public readonly RRNodeType = RRNodeType.Comment;\n public data: string;\n\n constructor(data: string) {\n super();\n this.data = data;\n }\n\n public get textContent(): string {\n return this.data;\n }\n\n public set textContent(textContent: string) {\n // codeql[js/xss-through-dom] Virtual-DOM data store; never reinterpreted as HTML.\n this.data = textContent;\n }\n\n toString() {\n return `RRComment text=${JSON.stringify(this.data)}`;\n }\n}\n\nexport class BaseRRCDATASection extends BaseRRNode implements IRRCDATASection {\n public readonly nodeName = '#cdata-section' as const;\n public readonly nodeType: number = NodeType.CDATA_SECTION_NODE;\n public readonly RRNodeType = RRNodeType.CDATA;\n public data: string;\n\n constructor(data: string) {\n super();\n this.data = data;\n }\n\n public get textContent(): string {\n return this.data;\n }\n\n public set textContent(textContent: string) {\n // codeql[js/xss-through-dom] Virtual-DOM data store; never reinterpreted as HTML.\n this.data = textContent;\n }\n\n toString() {\n return `RRCDATASection data=${JSON.stringify(this.data)}`;\n }\n}\n\nexport class ClassList {\n private onChange: ((newClassText: string) => void) | undefined;\n classes: string[] = [];\n\n constructor(\n classText?: string,\n onChange?: ((newClassText: string) => void) | undefined,\n ) {\n if (classText) {\n const classes = classText.trim().split(/\\s+/);\n this.classes.push(...classes);\n }\n this.onChange = onChange;\n }\n\n add = (...classNames: string[]) => {\n for (const item of classNames) {\n const className = String(item);\n if (this.classes.indexOf(className) >= 0) continue;\n this.classes.push(className);\n }\n this.onChange && this.onChange(this.classes.join(' '));\n };\n\n remove = (...classNames: string[]) => {\n this.classes = this.classes.filter(\n (item) => classNames.indexOf(item) === -1,\n );\n this.onChange && this.onChange(this.classes.join(' '));\n };\n}\n\nexport type CSSStyleDeclaration = Record<string, string> & {\n setProperty: (\n name: string,\n value: string | null,\n priority?: string | null,\n ) => void;\n removeProperty: (name: string) => string;\n};\n\nfunction appendChild(parent: IRRNode, newChild: IRRNode) {\n if (newChild.parentNode) newChild.parentNode.removeChild(newChild);\n\n if (parent.lastChild) {\n parent.lastChild.nextSibling = newChild;\n newChild.previousSibling = parent.lastChild;\n } else {\n parent.firstChild = newChild;\n newChild.previousSibling = null;\n }\n parent.lastChild = newChild;\n newChild.nextSibling = null;\n newChild.parentNode = parent;\n newChild.parentElement = parent;\n newChild.ownerDocument = parent.ownerDocument;\n return newChild;\n}\n\nfunction insertBefore(\n parent: IRRNode,\n newChild: IRRNode,\n refChild: IRRNode | null,\n) {\n if (!refChild) return appendChild(parent, newChild);\n\n if (refChild.parentNode !== parent)\n throw new Error(\n \"Failed to execute 'insertBefore' on 'RRNode': The RRNode before which the new node is to be inserted is not a child of this RRNode.\",\n );\n\n if (newChild === refChild) return newChild;\n if (newChild.parentNode) newChild.parentNode.removeChild(newChild);\n\n newChild.previousSibling = refChild.previousSibling;\n refChild.previousSibling = newChild;\n newChild.nextSibling = refChild;\n\n if (newChild.previousSibling) newChild.previousSibling.nextSibling = newChild;\n else parent.firstChild = newChild;\n\n newChild.parentElement = parent;\n newChild.parentNode = parent;\n newChild.ownerDocument = parent.ownerDocument;\n return newChild;\n}\n\nfunction removeChild(parent: IRRNode, child: IRRNode) {\n if (child.parentNode !== parent)\n throw new Error(\n \"Failed to execute 'removeChild' on 'RRNode': The RRNode to be removed is not a child of this RRNode.\",\n );\n if (child.previousSibling)\n child.previousSibling.nextSibling = child.nextSibling;\n else parent.firstChild = child.nextSibling;\n if (child.nextSibling)\n child.nextSibling.previousSibling = child.previousSibling;\n else parent.lastChild = child.previousSibling;\n child.previousSibling = null;\n child.nextSibling = null;\n child.parentElement = null;\n child.parentNode = null;\n return child;\n}\n\n// Enumerate nodeType value of standard HTML Node.\nexport enum NodeType {\n PLACEHOLDER, // This isn't a node type. Enum type value starts from zero but NodeType value starts from 1.\n ELEMENT_NODE,\n ATTRIBUTE_NODE,\n TEXT_NODE,\n CDATA_SECTION_NODE,\n ENTITY_REFERENCE_NODE,\n ENTITY_NODE,\n PROCESSING_INSTRUCTION_NODE,\n COMMENT_NODE,\n DOCUMENT_NODE,\n DOCUMENT_TYPE_NODE,\n DOCUMENT_FRAGMENT_NODE,\n}\n","// Modified by ELU. See NOTICE-ELU and THIRD_PARTY_NOTICES.txt.\n\nimport type {\n throttleOptions,\n listenerHandler,\n hookResetter,\n blockClass,\n addedNodeMutation,\n DocumentDimension,\n IWindow,\n DeprecatedMirror,\n textMutation,\n IMirror,\n} from '@elu-labs/recorder-types';\nimport type { Mirror, SlimDOMOptions } from '@elu-labs/recorder-snapshot';\nimport {\n isShadowRoot,\n IGNORED_NODE,\n classMatchesRegex,\n} from '@elu-labs/recorder-snapshot';\nimport { RRNode, RRIFrameElement, BaseRRNode } from '@elu-labs/recorder-dom';\nimport dom from '@elu-labs/recorder-utils';\n\nexport function on(\n type: string,\n fn: EventListenerOrEventListenerObject,\n target: Document | IWindow = document,\n): listenerHandler {\n const options = { capture: true, passive: true };\n target.addEventListener(type, fn, options);\n return () => removeEventListenerSafely(target, type, fn, options);\n}\n\nexport function removeEventListenerSafely(\n target: Pick<EventTarget, 'removeEventListener'>,\n type: string,\n fn: EventListenerOrEventListenerObject,\n options?: boolean | EventListenerOptions,\n): void {\n callSafely(() => {\n const removeEventListener = target.removeEventListener;\n if (typeof removeEventListener !== 'function') {\n return;\n }\n if (options === undefined) {\n removeEventListener.call(target, type, fn);\n return;\n }\n removeEventListener.call(target, type, fn, options);\n });\n}\n\n// https://github.com/rrweb-io/rrweb/pull/1695\n// If an iframe is initially same-origin and observed, but later its\n// location changes to a cross-origin URL (e.g. via document.location\n// or a redirect), accessing properties on its contentWindow throws a\n// SecurityError. This applies to cleanup calls like removeEventListener\n// as well as the handler callbacks returned by `on()` above.\nexport function callSafely(fn: () => void): void {\n try {\n fn();\n } catch (error) {\n if (!(error instanceof DOMException && error.name === 'SecurityError')) {\n throw error;\n }\n }\n}\n\n// https://github.com/rrweb-io/rrweb/pull/407\nconst DEPARTED_MIRROR_ACCESS_WARNING =\n 'Please stop import mirror directly. Instead of that,' +\n '\\r\\n' +\n 'now you can use replayer.getMirror() to access the mirror instance of a replayer,' +\n '\\r\\n' +\n 'or you can use record.mirror to access the mirror instance during recording.';\n/** @deprecated */\nexport let _mirror: DeprecatedMirror = {\n map: {},\n getId() {\n console.error(DEPARTED_MIRROR_ACCESS_WARNING);\n return -1;\n },\n getNode() {\n console.error(DEPARTED_MIRROR_ACCESS_WARNING);\n return null;\n },\n removeNodeFromMap() {\n console.error(DEPARTED_MIRROR_ACCESS_WARNING);\n },\n has() {\n console.error(DEPARTED_MIRROR_ACCESS_WARNING);\n return false;\n },\n reset() {\n console.error(DEPARTED_MIRROR_ACCESS_WARNING);\n },\n};\nif (typeof window !== 'undefined' && window.Proxy && window.Reflect) {\n _mirror = new Proxy(_mirror, {\n get(target, prop, receiver) {\n if (prop === 'map') {\n console.error(DEPARTED_MIRROR_ACCESS_WARNING);\n }\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n return Reflect.get(target, prop, receiver);\n },\n });\n}\n\n// copy from underscore and modified\nexport function throttle<T>(\n func: (arg: T) => void,\n wait: number,\n options: throttleOptions = {},\n) {\n let timeout: ReturnType<typeof setTimeout> | null = null;\n let previous = 0;\n return function (...args: T[]) {\n const now = Date.now();\n if (!previous && options.leading === false) {\n previous = now;\n }\n const remaining = wait - (now - previous);\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-this-alias\n const context = this;\n if (remaining <= 0 || remaining > wait) {\n if (timeout) {\n clearTimeout(timeout);\n timeout = null;\n }\n previous = now;\n func.apply(context, args);\n } else if (!timeout && options.trailing !== false) {\n timeout = setTimeout(() => {\n previous = options.leading === false ? 0 : Date.now();\n timeout = null;\n func.apply(context, args);\n }, remaining);\n }\n };\n}\n\nexport function hookSetter<T>(\n target: T,\n key: string | number | symbol,\n d: PropertyDescriptor,\n isRevoked?: boolean,\n win = window,\n): hookResetter {\n const original = win.Object.getOwnPropertyDescriptor(target, key);\n win.Object.defineProperty(\n target,\n key,\n isRevoked\n ? d\n : {\n set(value) {\n // put hooked setter into event loop to avoid of set latency\n setTimeout(() => {\n // the accessors read inside `d.set` throw 'Illegal invocation'\n // when `this` is not a genuine native element (e.g. a proxy);\n // the page cannot observe this deferred call, so drop the\n // update rather than throw\n try {\n d.set!.call(this, value);\n } catch {\n // noop\n }\n }, 0);\n if (original && original.set) {\n // Runs synchronously in the page's assignment, so a throw escapes\n // to the host page. A proxy or `setPrototypeOf` fake sits on the\n // prototype chain, so `instanceof` can't screen `this`; the native\n // getter fails the same brand check as the setter. Probe it: a\n // throw means `this` isn't a real element (skip), else forward and\n // let a genuine setter throw (e.g. a file input) propagate. With\n // no getter to probe, forward unguarded rather than drop a real\n // write.\n if (original.get) {\n try {\n original.get.call(this);\n } catch {\n return;\n }\n }\n original.set.call(this, value);\n }\n },\n },\n );\n return () => hookSetter(target, key, original || {}, true);\n}\n\n// guard against old third party libraries which redefine Date.now\nlet nowTimestamp = Date.now;\n\nif (!(/*@__PURE__*/ /[1-9][0-9]{12}/.test(Date.now().toString()))) {\n // they have already redefined it! use a fallback\n nowTimestamp = () => new Date().getTime();\n}\nexport { nowTimestamp };\n\nexport function getWindowScroll(win: Window) {\n const doc = win.document;\n return {\n left: doc.scrollingElement\n ? doc.scrollingElement.scrollLeft\n : win.pageXOffset !== undefined\n ? win.pageXOffset\n : doc.documentElement.scrollLeft ||\n (doc?.body && dom.parentElement(doc.body)?.scrollLeft) ||\n doc?.body?.scrollLeft ||\n 0,\n top: doc.scrollingElement\n ? doc.scrollingElement.scrollTop\n : win.pageYOffset !== undefined\n ? win.pageYOffset\n : doc?.documentElement.scrollTop ||\n (doc?.body && dom.parentElement(doc.body)?.scrollTop) ||\n doc?.body?.scrollTop ||\n 0,\n };\n}\n\nexport function getWindowHeight(): number {\n return (\n window.innerHeight ||\n (document.documentElement && document.documentElement.clientHeight) ||\n (document.body && document.body.clientHeight)\n );\n}\n\nexport function getWindowWidth(): number {\n return (\n window.innerWidth ||\n (document.documentElement && document.documentElement.clientWidth) ||\n (document.body && document.body.clientWidth)\n );\n}\n\n/**\n * Returns the given node as an HTMLElement if it is one, otherwise the parent node as an HTMLElement\n * @param node - node to check\n * @returns HTMLElement or null\n */\n\nexport function closestElementOfNode(node: Node | null): HTMLElement | null {\n if (!node) {\n return null;\n }\n const el: HTMLElement | null =\n node.nodeType === node.ELEMENT_NODE\n ? (node as HTMLElement)\n : dom.parentElement(node);\n return el;\n}\n\n/**\n * Checks if the given element set to be blocked by rrweb\n * @param node - node to check\n * @param blockClass - class name to check\n * @param blockSelector - css selectors to check\n * @param checkAncestors - whether to search through parent nodes for the block class\n * @returns true/false if the node was blocked or not\n */\nexport function isBlocked(\n node: Node | null,\n blockClass: blockClass,\n blockSelector: string | null,\n checkAncestors: boolean,\n): boolean {\n if (!node) return false;\n let el = closestElementOfNode(node);\n let searchAncestors = checkAncestors;\n if (!el) {\n const root = dom.getRootNode(node);\n if (!isShadowRoot(root)) return false;\n el = dom.host(root) as HTMLElement;\n searchAncestors = true;\n }\n while (el) {\n try {\n if (typeof blockClass === 'string') {\n if (el.classList.contains(blockClass)) return true;\n if (searchAncestors && el.closest('.' + blockClass) !== null)\n return true;\n } else if (classMatchesRegex(el, blockClass, searchAncestors))\n return true;\n } catch {\n // Retain the existing invalid block-class behavior.\n }\n if (blockSelector) {\n if (el.matches(blockSelector)) return true;\n if (searchAncestors && el.closest(blockSelector) !== null) return true;\n }\n const root = dom.getRootNode(el);\n if (!isShadowRoot(root)) return false;\n // Shadow mutation buffers have no serialized light-parent witness. The host's\n // blocking policy must apply even when the local mutation check skips ancestors.\n el = dom.host(root) as HTMLElement;\n searchAncestors = true;\n }\n return false;\n}\n\nexport function isSerialized(n: Node, mirror: Mirror): boolean {\n return mirror.getId(n) !== -1;\n}\n\nexport function isIgnored(\n n: Node,\n mirror: Mirror,\n slimDOMOptions: SlimDOMOptions,\n): boolean {\n if ((n as Element).tagName === 'TITLE' && slimDOMOptions.headTitleMutations) {\n // we do this check here but not in rrweb-snapshot\n // to block mutations/animations on the title.\n // the headTitleMutations option isn't intended to block recording of the initial value\n return true;\n }\n // The main part of the slimDOM check happens in\n // rrweb-snapshot::serializeNodeWithId\n return mirror.getId(n) === IGNORED_NODE;\n}\n\nexport function isAncestorRemoved(target: Node, mirror: Mirror): boolean {\n if (isShadowRoot(target)) {\n return false;\n }\n const id = mirror.getId(target);\n if (!mirror.has(id)) {\n return true;\n }\n const parent = dom.parentNode(target);\n if (parent && parent.nodeType === target.DOCUMENT_NODE) {\n return false;\n }\n // if the root is not document, it means the node is not in the DOM tree anymore\n if (!parent) {\n return true;\n }\n return isAncestorRemoved(parent, mirror);\n}\n\nexport function legacy_isTouchEvent(\n event: MouseEvent | TouchEvent | PointerEvent,\n): event is TouchEvent {\n return Boolean((event as TouchEvent).changedTouches);\n}\n\nexport function polyfill(win = window) {\n if ('NodeList' in win && !win.NodeList.prototype.forEach) {\n // eslint-disable-next-line @typescript-eslint/unbound-method\n win.NodeList.prototype.forEach = Array.prototype\n .forEach as unknown as NodeList['forEach'];\n }\n\n if ('DOMTokenList' in win && !win.DOMTokenList.prototype.forEach) {\n // eslint-disable-next-line @typescript-eslint/unbound-method\n win.DOMTokenList.prototype.forEach = Array.prototype\n .forEach as unknown as DOMTokenList['forEach'];\n }\n}\n\ntype ResolveTree = {\n value: addedNodeMutation;\n children: ResolveTree[];\n parent: ResolveTree | null;\n};\n\nexport function queueToResolveTrees(queue: addedNodeMutation[]): ResolveTree[] {\n const queueNodeMap: Record<number, ResolveTree> = {};\n const putIntoMap = (\n m: addedNodeMutation,\n parent: ResolveTree | null,\n ): ResolveTree => {\n const nodeInTree: ResolveTree = {\n value: m,\n parent,\n children: [],\n };\n queueNodeMap[m.node.id] = nodeInTree;\n return nodeInTree;\n };\n\n const queueNodeTrees: ResolveTree[] = [];\n for (const mutation of queue) {\n const { nextId, parentId } = mutation;\n if (nextId && nextId in queueNodeMap) {\n const nextInTree = queueNodeMap[nextId];\n if (nextInTree.parent) {\n const idx = nextInTree.parent.children.indexOf(nextInTree);\n nextInTree.parent.children.splice(\n idx,\n 0,\n putIntoMap(mutation, nextInTree.parent),\n );\n } else {\n const idx = queueNodeTrees.indexOf(nextInTree);\n queueNodeTrees.splice(idx, 0, putIntoMap(mutation, null));\n }\n continue;\n }\n if (parentId in queueNodeMap) {\n const parentInTree = queueNodeMap[parentId];\n parentInTree.children.push(putIntoMap(mutation, parentInTree));\n continue;\n }\n queueNodeTrees.push(putIntoMap(mutation, null));\n }\n\n return queueNodeTrees;\n}\n\nexport function iterateResolveTree(\n tree: ResolveTree,\n cb: (mutation: addedNodeMutation) => unknown,\n) {\n cb(tree.value);\n /**\n * The resolve tree was designed to reflect the DOM layout,\n * but we need append next sibling first, so we do a reverse\n * loop here.\n */\n for (let i = tree.children.length - 1; i >= 0; i--) {\n iterateResolveTree(tree.children[i], cb);\n }\n}\n\nexport type AppendedIframe = {\n mutationInQueue: addedNodeMutation;\n builtNode: HTMLIFrameElement | RRIFrameElement;\n};\n\nexport function isSerializedIframe<TNode extends Node | RRNode>(\n n: TNode,\n mirror: IMirror<TNode>,\n): boolean {\n return Boolean(n.nodeName === 'IFRAME' && mirror.getMeta(n));\n}\n\nexport function isSerializedStylesheet<TNode extends Node | RRNode>(\n n: TNode,\n mirror: IMirror<TNode>,\n): boolean {\n return Boolean(\n n.nodeName === 'LINK' &&\n n.nodeType === n.ELEMENT_NODE &&\n (n as HTMLElement).getAttribute &&\n (n as HTMLElement).getAttribute('rel') === 'stylesheet' &&\n mirror.getMeta(n),\n );\n}\n\nexport function getBaseDimension(\n node: Node,\n rootIframe: Node,\n): DocumentDimension {\n const frameElement = node.ownerDocument?.defaultView?.frameElement;\n if (!frameElement || frameElement === rootIframe) {\n return {\n x: 0,\n y: 0,\n relativeScale: 1,\n absoluteScale: 1,\n };\n }\n\n const frameDimension = frameElement.getBoundingClientRect();\n const frameBaseDimension = getBaseDimension(frameElement, rootIframe);\n // the iframe element may have a scale transform\n const relativeScale = frameDimension.height / frameElement.clientHeight;\n return {\n x:\n frameDimension.x * frameBaseDimension.relativeScale +\n frameBaseDimension.x,\n y:\n frameDimension.y * frameBaseDimension.relativeScale +\n frameBaseDimension.y,\n relativeScale,\n absoluteScale: frameBaseDimension.absoluteScale * relativeScale,\n };\n}\n\nexport function hasShadowRoot<T extends Node | RRNode>(\n n: T,\n): n is T & { shadowRoot: ShadowRoot } {\n if (!n) return false;\n if (n instanceof BaseRRNode && 'shadowRoot' in n) {\n return Boolean(n.shadowRoot);\n }\n return Boolean(dom.shadowRoot(n as unknown as Element));\n}\n\nexport function getNestedRule(\n rules: CSSRuleList,\n position: number[],\n): CSSGroupingRule | null {\n const rule = rules?.[position[0]] as CSSGroupingRule | null;\n if (!rule) {\n return null;\n }\n if (position.length === 1) {\n return rule;\n } else {\n return getNestedRule(rule.cssRules, position.slice(1));\n }\n}\n\nexport function getPositionsAndIndex(nestedIndex: number[]) {\n const positions = [...nestedIndex];\n const index = positions.pop();\n return { positions, index };\n}\n\n/**\n * Returns the latest mutation in the queue for each node.\n * @param mutations - mutations The text mutations to filter.\n * @returns The filtered text mutations.\n */\nexport function uniqueTextMutations(mutations: textMutation[]): textMutation[] {\n const idSet = new Set<number>();\n const uniqueMutations: textMutation[] = [];\n\n for (let i = mutations.length; i--; ) {\n const mutation = mutations[i];\n if (!idSet.has(mutation.id)) {\n uniqueMutations.push(mutation);\n idSet.add(mutation.id);\n }\n }\n\n return uniqueMutations;\n}\n\nexport class StyleSheetMirror {\n private id = 1;\n private styleIDMap = new WeakMap<CSSStyleSheet, number>();\n private idStyleMap = new Map<number, CSSStyleSheet>();\n\n getId(stylesheet: CSSStyleSheet): number {\n return this.styleIDMap.get(stylesheet) ?? -1;\n }\n\n has(stylesheet: CSSStyleSheet): boolean {\n return this.styleIDMap.has(stylesheet);\n }\n\n /**\n * @returns If the stylesheet is in the mirror, returns the id of the stylesheet. If not, return the new assigned id.\n */\n add(stylesheet: CSSStyleSheet, id?: number): number {\n if (this.has(stylesheet)) return this.getId(stylesheet);\n let newId: number;\n if (id === undefined) {\n newId = this.id++;\n } else newId = id;\n this.styleIDMap.set(stylesheet, newId);\n this.idStyleMap.set(newId, stylesheet);\n return newId;\n }\n\n getStyle(id: number): CSSStyleSheet | null {\n return this.idStyleMap.get(id) || null;\n }\n\n reset(): void {\n this.styleIDMap = new WeakMap();\n this.idStyleMap = new Map();\n this.id = 1;\n }\n\n generateId(): number {\n return this.id++;\n }\n}\n\n/**\n * Get the direct shadow host of a node in shadow dom. Returns null if it is not in a shadow dom.\n */\nexport function getShadowHost(n: Node): Element | null {\n let shadowHost: Element | null = null;\n if (\n 'getRootNode' in n &&\n dom.getRootNode(n)?.nodeType === Node.DOCUMENT_FRAGMENT_NODE &&\n dom.host(dom.getRootNode(n) as ShadowRoot)\n )\n shadowHost = dom.host(dom.getRootNode(n) as ShadowRoot);\n return shadowHost;\n}\n\n/**\n * Get the root shadow host of a node in nested shadow doms. Returns the node itself if it is not in a shadow dom.\n */\nexport function getRootShadowHost(n: Node): Node {\n let rootShadowHost: Node = n;\n\n let shadowHost: Element | null;\n // If n is in a nested shadow dom.\n while ((shadowHost = getShadowHost(rootShadowHost)))\n rootShadowHost = shadowHost;\n\n return rootShadowHost;\n}\n\nexport function shadowHostInDom(n: Node): boolean {\n const doc = n.ownerDocument;\n if (!doc) return false;\n const shadowHost = getRootShadowHost(n);\n return dom.contains(doc, shadowHost);\n}\n\nexport function inDom(n: Node): boolean {\n const doc = n.ownerDocument;\n if (!doc) return false;\n return dom.contains(doc, n) || shadowHostInDom(n);\n}\n","// Modified by ELU. See NOTICE-ELU and THIRD_PARTY_NOTICES.txt.\n\nimport {\n serializeNodeWithId,\n transformAttribute,\n IGNORED_NODE,\n ignoreAttribute,\n isShadowRoot,\n needMaskingText,\n maskInputValue,\n Mirror,\n isNativeShadowDom,\n getInputType,\n toLowerCase,\n} from '@elu-labs/recorder-snapshot';\nimport type { observerParam, MutationBufferParam } from '../types';\nimport type {\n mutationRecord,\n textCursor,\n attributeCursor,\n removedNodeMutation,\n addedNodeMutation,\n Optional,\n} from '@elu-labs/recorder-types';\nimport {\n isBlocked,\n isAncestorRemoved,\n isIgnored,\n isSerialized,\n hasShadowRoot,\n isSerializedIframe,\n isSerializedStylesheet,\n inDom,\n getShadowHost,\n closestElementOfNode,\n} from '../utils';\nimport dom from '@elu-labs/recorder-utils';\n\ntype DoubleLinkedListNode = {\n previous: DoubleLinkedListNode | null;\n next: DoubleLinkedListNode | null;\n value: NodeInLinkedList;\n};\ntype NodeInLinkedList = Node & {\n __ln: DoubleLinkedListNode;\n};\n\nfunction isNodeInLinkedList(n: Node | NodeInLinkedList): n is NodeInLinkedList {\n return '__ln' in n;\n}\n\nclass DoubleLinkedList {\n public length = 0;\n public head: DoubleLinkedListNode | null = null;\n public tail: DoubleLinkedListNode | null = null;\n\n public get(position: number) {\n if (position >= this.length) {\n throw new Error('Position outside of list range');\n }\n\n let current = this.head;\n for (let index = 0; index < position; index++) {\n current = current?.next || null;\n }\n return current;\n }\n\n public addNode(n: Node) {\n const node: DoubleLinkedListNode = {\n value: n as NodeInLinkedList,\n previous: null,\n next: null,\n };\n (n as NodeInLinkedList).__ln = node;\n if (n.previousSibling && isNodeInLinkedList(n.previousSibling)) {\n const current = n.previousSibling.__ln.next;\n node.next = current;\n node.previous = n.previousSibling.__ln;\n n.previousSibling.__ln.next = node;\n if (current) {\n current.previous = node;\n }\n } else if (\n n.nextSibling &&\n isNodeInLinkedList(n.nextSibling) &&\n n.nextSibling.__ln.previous\n ) {\n const current = n.nextSibling.__ln.previous;\n node.previous = current;\n node.next = n.nextSibling.__ln;\n n.nextSibling.__ln.previous = node;\n if (current) {\n current.next = node;\n }\n } else {\n if (this.head) {\n this.head.previous = node;\n }\n node.next = this.head;\n this.head = node;\n }\n if (node.next === null) {\n this.tail = node;\n }\n this.length++;\n }\n\n public removeNode(n: NodeInLinkedList) {\n const current = n.__ln;\n if (!this.head) {\n return;\n }\n\n if (!current.previous) {\n this.head = current.next;\n if (this.head) {\n this.head.previous = null;\n } else {\n this.tail = null;\n }\n } else {\n current.previous.next = current.next;\n if (current.next) {\n current.next.previous = current.previous;\n } else {\n this.tail = current.previous;\n }\n }\n if (n.__ln) {\n delete (n as Optional<NodeInLinkedList, '__ln'>).__ln;\n }\n this.length--;\n }\n}\n\nconst moveKey = (id: number, parentId: number) => `${id}@${parentId}`;\n\n/**\n * controls behaviour of a MutationObserver\n */\nexport default class MutationBuffer {\n private frozen = false;\n private locked = false;\n\n private texts: textCursor[] = [];\n private attributes: attributeCursor[] = [];\n private attributeMap = new WeakMap<Node, attributeCursor>();\n private removes: removedNodeMutation[] = [];\n private mapRemoves: Node[] = [];\n\n private movedMap: Record<string, true> = {};\n\n /**\n * the browser MutationObserver emits multiple mutations after\n * a delay for performance reasons, making tracing added nodes hard\n * in our `processMutations` callback function.\n * For example, if we append an element el_1 into body, and then append\n * another element el_2 into el_1, these two mutations may be passed to the\n * callback function together when the two operations were done.\n * Generally we need to trace child nodes of newly added nodes, but in this\n * case if we count el_2 as el_1's child node in the first mutation record,\n * then we will count el_2 again in the second mutation record which was\n * duplicated.\n * To avoid of duplicate counting added nodes, we use a Set to store\n * added nodes and its child nodes during iterate mutation records. Then\n * collect added nodes from the Set which have no duplicate copy. But\n * this also causes newly added nodes will not be serialized with id ASAP,\n * which means all the id related calculation should be lazy too.\n */\n private addedSet = new Set<Node>();\n private movedSet = new Set<Node>();\n private droppedSet = new Set<Node>();\n private removesSubTreeCache = new Set<Node>();\n\n private mutationCb: observerParam['mutationCb'];\n private blockClass: observerParam['blockClass'];\n private blockSelector: observerParam['blockSelector'];\n private maskTextClass: observerParam['maskTextClass'];\n private maskTextSelector: observerParam['maskTextSelector'];\n private inlineStylesheet: observerParam['inlineStylesheet'];\n private maskInputOptions: observerParam['maskInputOptions'];\n private maskTextFn: observerParam['maskTextFn'];\n private maskInputFn: observerParam['maskInputFn'];\n private keepIframeSrcFn: observerParam['keepIframeSrcFn'];\n private recordCanvas: observerParam['recordCanvas'];\n private canvasMaskingConfigured: observerParam['canvasMaskingConfigured'];\n private inlineImages: observerParam['inlineImages'];\n private slimDOMOptions: observerParam['slimDOMOptions'];\n private dataURLOptions: observerParam['dataURLOptions'];\n private doc: observerParam['doc'];\n private mirror: observerParam['mirror'];\n private iframeManager: observerParam['iframeManager'];\n private stylesheetManager: observerParam['stylesheetManager'];\n private shadowDomManager: observerParam['shadowDomManager'];\n private canvasManager: observerParam['canvasManager'];\n private processedNodeManager: observerParam['processedNodeManager'];\n private unattachedDoc: HTMLDocument;\n private canvasManagerReleased = false;\n\n public init(options: MutationBufferParam) {\n (\n [\n 'mutationCb',\n 'blockClass',\n 'blockSelector',\n 'maskTextClass',\n 'maskTextSelector',\n 'inlineStylesheet',\n 'maskInputOptions',\n 'maskTextFn',\n 'maskInputFn',\n 'keepIframeSrcFn',\n 'recordCanvas',\n 'canvasMaskingConfigured',\n 'inlineImages',\n 'slimDOMOptions',\n 'dataURLOptions',\n 'doc',\n 'mirror',\n 'iframeManager',\n 'stylesheetManager',\n 'shadowDomManager',\n 'canvasManager',\n 'processedNodeManager',\n ] as const\n ).forEach((key) => {\n // just a type trick, the runtime result is correct\n this[key] = options[key] as never;\n });\n // Balanced by releaseCanvasManager() in reset().\n this.canvasManager.acquire();\n }\n\n public freeze() {\n this.frozen = true;\n this.canvasManager.freeze();\n }\n\n public unfreeze() {\n this.frozen = false;\n this.canvasManager.unfreeze();\n this.emit();\n }\n\n public isFrozen() {\n return this.frozen;\n }\n\n public lock() {\n this.locked = true;\n this.canvasManager.lock();\n }\n\n public unlock() {\n this.locked = false;\n this.canvasManager.unlock();\n this.emit();\n }\n\n public reset() {\n // Don't reset the shared shadowDomManager here — that would disconnect every shadow-root observer on the page when any single buffer is torn down.\n this.releaseCanvasManager();\n }\n\n // Idempotent so teardown can run twice (iframe pagehide + stop); shadow restore handlers call this directly, not reset(), per the recursion-guard unit test.\n public releaseCanvasManager() {\n if (this.canvasManagerReleased) {\n return;\n }\n this.canvasManagerReleased = true;\n this.canvasManager.reset();\n // Don't null `this.doc` here — a MutationObserver callback queued before\n // the observer was disconnected can still drain through `emit`, which\n // passes `this.doc` to `serializeNodeWithId`. Splicing the buffer out of\n // `mutationBuffers[]` + removing the cleanup closure from `handlers[]`\n // releases the only strong refs to the buffer; GC handles the rest.\n }\n\n public bufferDoc(): Document {\n return this.doc;\n }\n\n public destroy() {\n while (this.mapRemoves.length) {\n this.mirror.removeNodeFromMap(this.mapRemoves.shift()!);\n }\n }\n\n public processMutations = (mutations: mutationRecord[]) => {\n mutations.forEach(this.processMutation); // adds mutations to the buffer\n this.emit(); // clears buffer if not locked/frozen\n };\n\n public emit = () => {\n if (this.frozen || this.locked) {\n return;\n }\n\n // delay any modification of the mirror until this function\n // so that the mirror for takeFullSnapshot doesn't get mutated while it's event is being processed\n\n const adds: addedNodeMutation[] = [];\n const addedIds = new Set<number>();\n\n /**\n * Sometimes child node may be pushed before its newly added\n * parent, so we init a queue to store these nodes.\n */\n const addList = new DoubleLinkedList();\n const getNextId = (n: Node): number | null => {\n let ns: Node | null = n;\n let nextId: number | null = IGNORED_NODE; // slimDOM: ignored\n while (nextId === IGNORED_NODE) {\n ns = ns && ns.nextSibling;\n nextId = ns && this.mirror.getId(ns);\n }\n return nextId;\n };\n const pushAdd = (n: Node) => {\n const parent = dom.parentNode(n);\n if (!parent || !inDom(n) || (parent as Element).tagName === 'TEXTAREA') {\n return;\n }\n const parentId = isShadowRoot(parent)\n ? this.mirror.getId(getShadowHost(n))\n : this.mirror.getId(parent);\n const nextId = getNextId(n);\n if (parentId === -1 || nextId === -1) {\n return addList.addNode(n);\n }\n const sn = serializeNodeWithId(n, {\n doc: this.doc,\n mirror: this.mirror,\n blockClass: this.blockClass,\n blockSelector: this.blockSelector,\n maskTextClass: this.maskTextClass,\n maskTextSelector: this.maskTextSelector,\n skipChild: true,\n newlyAddedElement: true,\n inlineStylesheet: this.inlineStylesheet,\n maskInputOptions: this.maskInputOptions,\n maskTextFn: this.maskTextFn,\n maskInputFn: this.maskInputFn,\n slimDOMOptions: this.slimDOMOptions,\n dataURLOptions: this.dataURLOptions,\n recordCanvas: this.recordCanvas,\n canvasMaskingConfigured: this.canvasMaskingConfigured,\n inlineImages: this.inlineImages,\n onSerialize: (currentN) => {\n if (isSerializedIframe(currentN, this.mirror)) {\n this.iframeManager.addIframe(currentN as HTMLIFrameElement);\n }\n if (isSerializedStylesheet(currentN, this.mirror)) {\n this.stylesheetManager.trackLinkElement(\n currentN as HTMLLinkElement,\n );\n }\n if (hasShadowRoot(n)) {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n this.shadowDomManager.addShadowRoot(dom.shadowRoot(n)!, this.doc);\n }\n },\n onIframeLoad: (iframe, childSn) => {\n this.iframeManager.attachIframe(iframe, childSn);\n this.shadowDomManager.observeAttachShadow(iframe);\n },\n onIframeListenerRegistered: (\n iframe: HTMLIFrameElement,\n disposer: () => void,\n ) => {\n this.iframeManager.registerLoadListenerDisposer(iframe, disposer);\n },\n onStylesheetLoad: (link, childSn) => {\n this.stylesheetManager.attachLinkElement(link, childSn);\n },\n });\n if (sn) {\n adds.push({\n parentId,\n nextId,\n node: sn,\n });\n addedIds.add(sn.id);\n }\n };\n\n // Drain mapRemoves before pushAdd so the mirror only holds nodes that\n // are still live. Reparent detection in record/index.ts depends on this\n // order — it resolves an `add`'s fresh id back to an element via\n // `mirror.getNode` and matches it against the iframe behind the removed\n // id. Reorder this and iframe moves will look like remove+add to that\n // path, tearing down observers on a still-live iframe.\n while (this.mapRemoves.length) {\n this.mirror.removeNodeFromMap(this.mapRemoves.shift()!);\n }\n\n for (const n of this.movedSet) {\n if (\n isParentRemoved(this.removesSubTreeCache, n, this.mirror) &&\n !this.movedSet.has(dom.parentNode(n)!)\n ) {\n continue;\n }\n pushAdd(n);\n }\n\n for (const n of this.addedSet) {\n if (\n !isAncestorInSet(this.droppedSet, n) &&\n !isParentRemoved(this.removesSubTreeCache, n, this.mirror)\n ) {\n pushAdd(n);\n } else if (isAncestorInSet(this.movedSet, n)) {\n pushAdd(n);\n } else {\n this.droppedSet.add(n);\n }\n }\n\n let candidate: DoubleLinkedListNode | null = null;\n while (addList.length) {\n let node: DoubleLinkedListNode | null = null;\n if (candidate) {\n const parentId = this.mirror.getId(dom.parentNode(candidate.value));\n const nextId = getNextId(candidate.value);\n if (parentId !== -1 && nextId !== -1) {\n node = candidate;\n }\n }\n if (!node) {\n let tailNode = addList.tail;\n while (tailNode) {\n const _node = tailNode;\n tailNode = tailNode.previous;\n // ensure _node is defined before attempting to find value\n if (_node) {\n const parentId = this.mirror.getId(dom.parentNode(_node.value));\n const nextId = getNextId(_node.value);\n\n if (nextId === -1) continue;\n // nextId !== -1 && parentId !== -1\n else if (parentId !== -1) {\n node = _node;\n break;\n }\n // nextId !== -1 && parentId === -1 This branch can happen if the node is the child of shadow root\n else {\n const unhandledNode = _node.value;\n const parent = dom.parentNode(unhandledNode);\n // If the node is the direct child of a shadow root, we treat the shadow host as its parent node.\n if (parent && parent.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {\n const shadowHost = dom.host(parent as ShadowRoot);\n const parentId = this.mirror.getId(shadowHost);\n if (parentId !== -1) {\n node = _node;\n break;\n }\n }\n }\n }\n }\n }\n if (!node) {\n /**\n * If all nodes in queue could not find a serialized parent,\n * it may be a bug or corner case. We need to escape the\n * dead while loop at once.\n */\n while (addList.head) {\n addList.removeNode(addList.head.value);\n }\n break;\n }\n candidate = node.previous;\n addList.removeNode(node.value);\n pushAdd(node.value);\n }\n\n const payload = {\n texts: this.texts\n .map((text) => {\n const n = text.node;\n const parent = dom.parentNode(n);\n if (parent && (parent as Element).tagName === 'TEXTAREA') {\n // the node is being ignored as it isn't in the mirror, so shift mutation to attributes on parent textarea\n this.genTextAreaValueMutation(parent as HTMLTextAreaElement);\n }\n return {\n id: this.mirror.getId(n),\n value: text.value,\n };\n })\n // no need to include them on added elements, as they have just been serialized with up to date attribubtes\n .filter((text) => !addedIds.has(text.id))\n // text mutation's id was not in the mirror map means the target node has been removed\n .filter((text) => this.mirror.has(text.id)),\n attributes: this.attributes\n .map((attribute) => {\n const { attributes } = attribute;\n if (typeof attributes.style === 'string') {\n const diffAsStr = JSON.stringify(attribute.styleDiff);\n const unchangedAsStr = JSON.stringify(attribute._unchangedStyles);\n // check if the style diff is actually shorter than the regular string based mutation\n // (which was the whole point of #464 'compact style mutation').\n if (diffAsStr.length < attributes.style.length) {\n // also: CSSOM fails badly when var() is present on shorthand properties, so only proceed with\n // the compact style mutation if these have all been accounted for\n if (\n (diffAsStr + unchangedAsStr).split('var(').length ===\n attributes.style.split('var(').length\n ) {\n attributes.style = attribute.styleDiff;\n }\n }\n }\n return {\n id: this.mirror.getId(attribute.node),\n attributes: attributes,\n };\n })\n // no need to include them on added elements, as they have just been serialized with up to date attribubtes\n .filter((attribute) => !addedIds.has(attribute.id))\n // attribute mutation's id was not in the mirror map means the target node has been removed\n .filter((attribute) => this.mirror.has(attribute.id)),\n removes: this.removes,\n adds,\n };\n // payload may be empty if the mutations happened in some blocked elements\n if (\n !payload.texts.length &&\n !payload.attributes.length &&\n !payload.removes.length &&\n !payload.adds.length\n ) {\n return;\n }\n\n // reset\n this.texts = [];\n this.attributes = [];\n this.attributeMap = new WeakMap<Node, attributeCursor>();\n this.removes = [];\n this.addedSet = new Set<Node>();\n this.movedSet = new Set<Node>();\n this.droppedSet = new Set<Node>();\n this.removesSubTreeCache = new Set<Node>();\n this.movedMap = {};\n\n this.mutationCb(payload);\n };\n\n public bufferBelongsToIframe = (iframeEl: HTMLIFrameElement) => {\n return this.doc === iframeEl.contentDocument;\n };\n\n private genTextAreaValueMutation = (textarea: HTMLTextAreaElement) => {\n let item = this.attributeMap.get(textarea);\n if (!item) {\n item = {\n node: textarea,\n attributes: {},\n styleDiff: {},\n _unchangedStyles: {},\n };\n this.attributes.push(item);\n this.attributeMap.set(textarea, item);\n }\n const value = Array.from(\n dom.childNodes(textarea),\n (cn) => dom.textContent(cn) || '',\n ).join('');\n item.attributes.value = maskInputValue({\n element: textarea,\n maskInputOptions: this.maskInputOptions,\n tagName: textarea.tagName,\n type: getInputType(textarea),\n value,\n maskInputFn: this.maskInputFn,\n });\n };\n\n private processMutation = (m: mutationRecord) => {\n if (isIgnored(m.target, this.mirror, this.slimDOMOptions)) {\n return;\n }\n switch (m.type) {\n case 'characterData': {\n const value = dom.textContent(m.target);\n\n if (\n !isBlocked(m.target, this.blockClass, this.blockSelector, false) &&\n value !== m.oldValue\n ) {\n this.texts.push({\n value:\n needMaskingText(\n m.target,\n this.maskTextClass,\n this.maskTextSelector,\n true, // checkAncestors\n ) && value\n ? this.maskTextFn\n ? this.maskTextFn(value, closestElementOfNode(m.target))\n : value.replace(/[\\S]/g, '*')\n : value,\n node: m.target,\n });\n }\n break;\n }\n case 'attributes': {\n const target = m.target as HTMLElement;\n let attributeName = m.attributeName as string;\n let value = (m.target as HTMLElement).getAttribute(attributeName);\n\n if (attributeName === 'value') {\n const type = getInputType(target);\n\n value = maskInputValue({\n element: target,\n maskInputOptions: this.maskInputOptions,\n tagName: target.tagName,\n type,\n value,\n maskInputFn: this.maskInputFn,\n });\n }\n if (\n isBlocked(m.target, this.blockClass, this.blockSelector, false) ||\n value === m.oldValue\n ) {\n return;\n }\n\n let item = this.attributeMap.get(m.target);\n if (\n target.tagName === 'IFRAME' &&\n attributeName === 'src' &&\n !this.keepIframeSrcFn(value as string)\n ) {\n if (!(target as HTMLIFrameElement).contentDocument) {\n // we can't record it directly as we can't see into it\n // preserve the src attribute so a decision can be taken at replay time\n attributeName = 'rr_src';\n } else {\n return;\n }\n }\n if (!item) {\n item = {\n node: m.target,\n attributes: {},\n styleDiff: {},\n _unchangedStyles: {},\n };\n this.attributes.push(item);\n this.attributeMap.set(m.target, item);\n }\n\n // Keep this property on inputs that used to be password inputs\n // This is used to ensure we do not unmask value when using e.g. a \"Show password\" type button\n if (\n attributeName === 'type' &&\n target.tagName === 'INPUT' &&\n (m.oldValue || '').toLowerCase() === 'password'\n ) {\n target.setAttribute('data-rr-is-password', 'true');\n }\n\n if (!ignoreAttribute(target.tagName, attributeName, value)) {\n // overwrite attribute if the mutations was triggered in same time\n item.attributes[attributeName] = transformAttribute(\n this.doc,\n toLowerCase(target.tagName),\n toLowerCase(attributeName),\n value,\n target,\n this.dataURLOptions,\n );\n if (attributeName === 'style') {\n if (!this.unattachedDoc) {\n try {\n // avoid upsetting original document from a Content Security point of view\n this.unattachedDoc =\n document.implementation.createHTMLDocument();\n } catch (e) {\n // fallback to more direct method\n this.unattachedDoc = this.doc;\n }\n }\n const old = this.unattachedDoc.createElement('span');\n if (m.oldValue) {\n old.style.cssText = m.oldValue;\n }\n for (const pname of Array.from(target.style)) {\n const newValue = target.style.getPropertyValue(pname);\n const newPriority = target.style.getPropertyPriority(pname);\n if (\n newValue !== old.style.getPropertyValue(pname) ||\n newPriority !== old.style.getPropertyPriority(pname)\n ) {\n if (newPriority === '') {\n item.styleDiff[pname] = newValue;\n } else {\n item.styleDiff[pname] = [newValue, newPriority];\n }\n } else {\n // for checking\n item._unchangedStyles[pname] = [newValue, newPriority];\n }\n }\n for (const pname of Array.from(old.style)) {\n if (target.style.getPropertyValue(pname) === '') {\n // \"if not set, returns the empty string\"\n item.styleDiff[pname] = false; // delete\n }\n }\n } else if (attributeName === 'open' && target.tagName === 'DIALOG') {\n if (target.matches('dialog:modal')) {\n item.attributes['rr_open_mode'] = 'modal';\n } else {\n item.attributes['rr_open_mode'] = 'non-modal';\n }\n }\n }\n break;\n }\n case 'childList': {\n /**\n * Parent is blocked, ignore all child mutations\n */\n if (isBlocked(m.target, this.blockClass, this.blockSelector, true))\n return;\n\n if ((m.target as Element).tagName === 'TEXTAREA') {\n // children would be ignored in genAdds as they aren't in the mirror\n this.genTextAreaValueMutation(m.target as HTMLTextAreaElement);\n return; // any removedNodes won't have been in mirror either\n }\n\n m.addedNodes.forEach((n) => this.genAdds(n, m.target));\n m.removedNodes.forEach((n) => {\n const nodeId = this.mirror.getId(n);\n const parentId = isShadowRoot(m.target)\n ? this.mirror.getId(dom.host(m.target))\n : this.mirror.getId(m.target);\n if (\n isBlocked(m.target, this.blockClass, this.blockSelector, false) ||\n isIgnored(n, this.mirror, this.slimDOMOptions) ||\n !isSerialized(n, this.mirror)\n ) {\n return;\n }\n // removed node has not been serialized yet, just remove it from the Set\n if (this.addedSet.has(n)) {\n deepDelete(this.addedSet, n);\n this.droppedSet.add(n);\n } else if (this.addedSet.has(m.target) && nodeId === -1) {\n /**\n * If target was newly added and removed child node was\n * not serialized, it means the child node has been removed\n * before callback fired, so we can ignore it because\n * newly added node will be serialized without child nodes.\n * TODO: verify this\n */\n } else if (isAncestorRemoved(m.target, this.mirror)) {\n /**\n * If parent id was not in the mirror map any more, it\n * means the parent node has already been removed. So\n * the node is also removed which we do not need to track\n * and replay.\n */\n } else if (\n this.movedSet.has(n) &&\n this.movedMap[moveKey(nodeId, parentId)]\n ) {\n deepDelete(this.movedSet, n);\n } else {\n this.removes.push({\n parentId,\n id: nodeId,\n isShadow:\n isShadowRoot(m.target) && isNativeShadowDom(m.target)\n ? true\n : undefined,\n });\n processRemoves(n, this.removesSubTreeCache);\n }\n this.mapRemoves.push(n);\n });\n break;\n }\n default:\n break;\n }\n };\n\n /**\n * Make sure you check if `n`'s parent is blocked before calling this function\n * */\n private genAdds = (n: Node, target?: Node) => {\n // this node was already recorded in other buffer, ignore it\n if (this.processedNodeManager.inOtherBuffer(n, this)) return;\n\n // if n is added to set, there is no need to travel it and its' children again\n if (this.addedSet.has(n)) {\n // re-insert n so the addedSet iteration order in the `emit` phase matches\n // the latest DOM order; a stale position makes emit's out-of-order\n // deferral list do far more work on large batches (upstream rrweb #1302).\n // this only moves n itself - already-present children keep their earlier\n // positions and aren't re-appended here, but emit's addList deferral\n // re-derives parentId/nextId, so parent-before-child order still comes\n // out correct.\n this.addedSet.delete(n);\n this.addedSet.add(n);\n return;\n }\n if (this.movedSet.has(n)) return;\n\n if (this.mirror.hasNode(n)) {\n if (isIgnored(n, this.mirror, this.slimDOMOptions)) {\n return;\n }\n this.movedSet.add(n);\n let targetId: number | null = null;\n if (target && this.mirror.hasNode(target)) {\n targetId = this.mirror.getId(target);\n }\n if (targetId && targetId !== -1) {\n this.movedMap[moveKey(this.mirror.getId(n), targetId)] = true;\n }\n } else {\n this.addedSet.add(n);\n this.droppedSet.delete(n);\n }\n\n // if this node is blocked `serializeNode` will turn it into a placeholder element\n // but we have to remove it's children otherwise they will be added as placeholders too\n if (!isBlocked(n, this.blockClass, this.blockSelector, false)) {\n dom.childNodes(n).forEach((childN) => this.genAdds(childN));\n if (hasShadowRoot(n)) {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n dom.childNodes(dom.shadowRoot(n)!).forEach((childN) => {\n this.processedNodeManager.add(childN, this);\n this.genAdds(childN, n);\n });\n }\n }\n };\n}\n\n/**\n * Some utils to handle the mutation observer DOM records.\n * It should be more clear to extend the native data structure\n * like Set and Map, but currently Typescript does not support\n * that.\n */\nfunction deepDelete(addsSet: Set<Node>, n: Node) {\n addsSet.delete(n);\n dom.childNodes(n).forEach((childN) => deepDelete(addsSet, childN));\n}\n\nfunction processRemoves(n: Node, cache: Set<Node>) {\n const queue = [n];\n\n while (queue.length) {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const next = queue.pop()!;\n if (cache.has(next)) continue;\n cache.add(next);\n dom.childNodes(next).forEach((n) => queue.push(n));\n }\n\n return;\n}\n\nfunction isParentRemoved(removes: Set<Node>, n: Node, mirror: Mirror): boolean {\n if (removes.size === 0) return false;\n return _isParentRemoved(removes, n, mirror);\n}\n\nfunction _isParentRemoved(\n removes: Set<Node>,\n n: Node,\n _mirror: Mirror,\n): boolean {\n const node: ParentNode | null = dom.parentNode(n);\n if (!node) return false;\n return removes.has(node);\n}\n\nfunction isAncestorInSet(set: Set<Node>, n: Node): boolean {\n if (set.size === 0) return false;\n return _isAncestorInSet(set, n);\n}\n\nfunction _isAncestorInSet(set: Set<Node>, n: Node): boolean {\n const parent = dom.parentNode(n);\n if (!parent) {\n return false;\n }\n if (set.has(parent)) {\n return true;\n }\n return _isAncestorInSet(set, parent);\n}\n","import type { ErrorHandler } from '../types';\n\ntype Callback = (...args: unknown[]) => unknown;\n\nlet errorHandler: ErrorHandler | undefined;\n\nexport function registerErrorHandler(handler: ErrorHandler | undefined) {\n errorHandler = handler;\n}\n\nexport function unregisterErrorHandler() {\n errorHandler = undefined;\n}\n\n/**\n * Wrap callbacks in a wrapper that allows to pass errors to a configured `errorHandler` method.\n */\nexport const callbackWrapper = <T extends Callback>(cb: T): T => {\n if (!errorHandler) {\n return cb;\n }\n\n const rrwebWrapped = ((...rest: unknown[]) => {\n try {\n return cb(...rest);\n } catch (error) {\n if (errorHandler && errorHandler(error) === true) {\n return;\n }\n\n throw error;\n }\n }) as unknown as T;\n\n return rrwebWrapped;\n};\n","// Modified by ELU. See NOTICE-ELU and THIRD_PARTY_NOTICES.txt.\n\nimport { createRecorderCleanup, acquireRecorderCleanup } from './cleanup';\nimport {\n type MaskInputOptions,\n maskInputValue,\n Mirror,\n getInputType,\n toLowerCase,\n} from '@elu-labs/recorder-snapshot';\nimport type { FontFaceSet } from 'css-font-loading-module';\nimport {\n throttle,\n on,\n hookSetter,\n getWindowScroll,\n getWindowHeight,\n getWindowWidth,\n isBlocked,\n legacy_isTouchEvent,\n StyleSheetMirror,\n nowTimestamp,\n} from '../utils';\nimport { patch } from '@elu-labs/recorder-utils';\nimport type { observerParam, MutationBufferParam } from '../types';\nimport {\n IncrementalSource,\n MouseInteractions,\n PointerTypes,\n MediaInteractions,\n} from '@elu-labs/recorder-types';\nimport type {\n mutationCallBack,\n mousemoveCallBack,\n mousePosition,\n mouseInteractionCallBack,\n listenerHandler,\n scrollCallback,\n styleSheetRuleCallback,\n viewportResizeCallback,\n inputValue,\n inputCallback,\n hooksParam,\n Arguments,\n mediaInteractionCallback,\n canvasMutationCallback,\n fontCallback,\n fontParam,\n styleDeclarationCallback,\n IWindow,\n SelectionRange,\n selectionCallback,\n customElementCallback,\n} from '@elu-labs/recorder-types';\nimport MutationBuffer from './mutation';\nimport { callbackWrapper } from './error-handler';\nimport dom, { mutationObserverCtor } from '@elu-labs/recorder-utils';\n\nexport const mutationBuffers: MutationBuffer[] = [];\n\n// Event.path is non-standard and used in some older browsers\ntype NonStandardEvent = Omit<Event, 'composedPath'> & {\n path: EventTarget[];\n};\n\nfunction getEventTarget(event: Event | NonStandardEvent): EventTarget | null {\n try {\n if ('composedPath' in event) {\n const path = event.composedPath();\n if (path.length) {\n return path[0];\n }\n } else if ('path' in event && event.path.length) {\n return event.path[0];\n }\n } catch {\n // fallback to `event.target` below\n }\n\n return event && event.target;\n}\n\nexport function initMutationObserver(\n options: MutationBufferParam,\n rootEl: Node,\n): { observer: MutationObserver; buffer: MutationBuffer } {\n const cleanup = createRecorderCleanup();\n const mutationBuffer = new MutationBuffer();\n mutationBuffers.push(mutationBuffer);\n cleanup.add(() => {\n const index = mutationBuffers.indexOf(mutationBuffer);\n if (index !== -1) mutationBuffers.splice(index, 1);\n });\n cleanup.add(() => mutationBuffer.destroy());\n // init() can acquire a canvas reference before a later host operation throws.\n cleanup.add(() => mutationBuffer.reset());\n try {\n mutationBuffer.init(options);\n const observer = new (mutationObserverCtor() as new (\n callback: MutationCallback,\n ) => MutationObserver)(\n callbackWrapper(mutationBuffer.processMutations.bind(mutationBuffer)),\n );\n cleanup.add(() => observer.disconnect());\n const mutationObserverInit: MutationObserverInit = {\n attributes: true,\n attributeOldValue: true,\n characterData: true,\n characterDataOldValue: true,\n childList: true,\n subtree: true,\n };\n if (options.attributeFilter && options.attributeFilter.length > 0)\n mutationObserverInit.attributeFilter = options.attributeFilter;\n observer.observe(rootEl, mutationObserverInit);\n return { observer, buffer: mutationBuffer };\n } catch (error) {\n cleanup.close();\n throw error;\n }\n}\n\nfunction initMoveObserver({\n mousemoveCb,\n sampling,\n doc,\n mirror,\n}: observerParam): listenerHandler {\n let active = true;\n if (sampling.mousemove === false) {\n return () => {\n //\n };\n }\n\n const threshold =\n typeof sampling.mousemove === 'number' ? sampling.mousemove : 50;\n const callbackThreshold =\n typeof sampling.mousemoveCallback === 'number'\n ? sampling.mousemoveCallback\n : 500;\n\n let positions: mousePosition[] = [];\n let timeBaseline: number | null;\n const wrappedCb = throttle(\n callbackWrapper(\n (\n source:\n | IncrementalSource.MouseMove\n | IncrementalSource.TouchMove\n | IncrementalSource.Drag,\n ) => {\n if (!active) return;\n const totalOffset = Date.now() - timeBaseline!;\n mousemoveCb(\n positions.map((p) => {\n p.timeOffset -= totalOffset;\n return p;\n }),\n source,\n );\n positions = [];\n timeBaseline = null;\n },\n ),\n callbackThreshold,\n );\n const updatePosition = callbackWrapper(\n throttle<MouseEvent | TouchEvent | DragEvent>(\n callbackWrapper((evt) => {\n if (!active) return;\n const target = getEventTarget(evt);\n // 'legacy' here as we could switch to https://developer.mozilla.org/en-US/docs/Web/API/Element/pointermove_event\n const { clientX, clientY } = legacy_isTouchEvent(evt)\n ? evt.changedTouches[0]\n : evt;\n if (!timeBaseline) {\n timeBaseline = nowTimestamp();\n }\n positions.push({\n x: clientX,\n y: clientY,\n id: mirror.getId(target as Node),\n timeOffset: nowTimestamp() - timeBaseline,\n });\n // it is possible DragEvent is undefined even on devices\n // that support event 'drag'\n wrappedCb(\n typeof DragEvent !== 'undefined' && evt instanceof DragEvent\n ? IncrementalSource.Drag\n : evt instanceof MouseEvent\n ? IncrementalSource.MouseMove\n : IncrementalSource.TouchMove,\n );\n }),\n threshold,\n {\n trailing: false,\n },\n ),\n );\n return acquireRecorderCleanup((cleanup) => {\n cleanup.add(() => {\n active = false;\n });\n cleanup.add(on('mousemove', updatePosition, doc));\n cleanup.add(on('touchmove', updatePosition, doc));\n cleanup.add(on('drag', updatePosition, doc));\n });\n}\n\nfunction initMouseInteractionObserver({\n mouseInteractionCb,\n doc,\n mirror,\n blockClass,\n blockSelector,\n sampling,\n}: observerParam): listenerHandler {\n let active = true;\n if (sampling.mouseInteraction === false) {\n return () => {\n //\n };\n }\n const disableMap: Record<string, boolean | undefined> =\n sampling.mouseInteraction === true ||\n sampling.mouseInteraction === undefined\n ? {}\n : sampling.mouseInteraction;\n\n let currentPointerType: PointerTypes | null = null;\n const getHandler = (eventKey: keyof typeof MouseInteractions) => {\n return (event: MouseEvent | TouchEvent | PointerEvent) => {\n if (!active) return;\n const target = getEventTarget(event) as Node;\n if (isBlocked(target, blockClass, blockSelector, true)) {\n return;\n }\n let pointerType: PointerTypes | null = null;\n let thisEventKey = eventKey;\n if ('pointerType' in event) {\n switch (event.pointerType) {\n case 'mouse':\n pointerType = PointerTypes.Mouse;\n break;\n case 'touch':\n pointerType = PointerTypes.Touch;\n break;\n case 'pen':\n pointerType = PointerTypes.Pen;\n break;\n }\n if (pointerType === PointerTypes.Touch) {\n if (MouseInteractions[eventKey] === MouseInteractions.MouseDown) {\n // we are actually listening on 'pointerdown'\n thisEventKey = 'TouchStart';\n } else if (\n MouseInteractions[eventKey] === MouseInteractions.MouseUp\n ) {\n // we are actually listening on 'pointerup'\n thisEventKey = 'TouchEnd';\n }\n } else if (pointerType === PointerTypes.Pen) {\n // TODO: these will get incorrectly emitted as MouseDown/MouseUp\n }\n } else if (legacy_isTouchEvent(event)) {\n pointerType = PointerTypes.Touch;\n }\n if (pointerType !== null) {\n currentPointerType = pointerType;\n if (\n (thisEventKey.startsWith('Touch') &&\n pointerType === PointerTypes.Touch) ||\n (thisEventKey.startsWith('Mouse') &&\n pointerType === PointerTypes.Mouse)\n ) {\n // don't output redundant info\n pointerType = null;\n }\n } else if (MouseInteractions[eventKey] === MouseInteractions.Click) {\n pointerType = currentPointerType;\n currentPointerType = null; // cleanup as we've used it\n }\n const e = legacy_isTouchEvent(event) ? event.changedTouches[0] : event;\n if (!e) {\n return;\n }\n const id = mirror.getId(target);\n const { clientX, clientY } = e;\n callbackWrapper(mouseInteractionCb)({\n type: MouseInteractions[thisEventKey],\n id,\n x: clientX,\n y: clientY,\n ...(pointerType !== null && { pointerType }),\n });\n };\n };\n return acquireRecorderCleanup((cleanup) => {\n cleanup.add(() => {\n active = false;\n });\n Object.keys(MouseInteractions)\n .filter(\n (key) =>\n Number.isNaN(Number(key)) &&\n !key.endsWith('_Departed') &&\n disableMap[key] !== false,\n )\n .forEach((eventKey: keyof typeof MouseInteractions) => {\n let eventName = toLowerCase(eventKey);\n const handler = getHandler(eventKey);\n if (window.PointerEvent) {\n switch (MouseInteractions[eventKey]) {\n case MouseInteractions.MouseDown:\n case MouseInteractions.MouseUp:\n eventName = eventName.replace(\n 'mouse',\n 'pointer',\n ) as unknown as typeof eventName;\n break;\n case MouseInteractions.TouchStart:\n case MouseInteractions.TouchEnd:\n // these are handled by pointerdown/pointerup\n return;\n }\n }\n cleanup.add(on(eventName, handler, doc));\n });\n });\n}\n\nexport function initScrollObserver({\n scrollCb,\n doc,\n mirror,\n blockClass,\n blockSelector,\n sampling,\n}: Pick<\n observerParam,\n 'scrollCb' | 'doc' | 'mirror' | 'blockClass' | 'blockSelector' | 'sampling'\n>): listenerHandler {\n let active = true;\n // Dedupe scroll and scrollend — both fire for one gesture.\n const lastEmitted = new Map<number, string>();\n const emitScrollPosition = (evt: Event) => {\n if (!active) return;\n const target = getEventTarget(evt);\n if (!target || isBlocked(target as Node, blockClass, blockSelector, true)) {\n return;\n }\n const id = mirror.getId(target as Node);\n let x: number;\n let y: number;\n if (target === doc && doc.defaultView) {\n const scrollLeftTop = getWindowScroll(doc.defaultView);\n x = scrollLeftTop.left;\n y = scrollLeftTop.top;\n } else {\n x = (target as HTMLElement).scrollLeft;\n y = (target as HTMLElement).scrollTop;\n }\n const key = `${x},${y}`;\n if (lastEmitted.get(id) === key) {\n return;\n }\n lastEmitted.set(id, key);\n scrollCb({ id, x, y });\n };\n const updatePosition = callbackWrapper(\n throttle<UIEvent>(\n callbackWrapper((evt) => emitScrollPosition(evt)),\n sampling.scroll || 100,\n ),\n );\n return acquireRecorderCleanup((cleanup) => {\n cleanup.add(() => {\n active = false;\n });\n cleanup.add(on('scroll', updatePosition, doc));\n // scrollend captures the resting offset when scroll alone recorded 0.\n if ('onscrollend' in doc) {\n cleanup.add(on('scrollend', callbackWrapper(emitScrollPosition), doc));\n }\n });\n}\n\nfunction initViewportResizeObserver(\n { viewportResizeCb }: observerParam,\n { win }: { win: IWindow },\n): listenerHandler {\n let lastH = -1;\n let lastW = -1;\n const updateDimension = callbackWrapper(\n throttle(\n callbackWrapper(() => {\n const height = getWindowHeight();\n const width = getWindowWidth();\n if (lastH !== height || lastW !== width) {\n viewportResizeCb({\n width: Number(width),\n height: Number(height),\n });\n lastH = height;\n lastW = width;\n }\n }),\n 200,\n ),\n );\n return on('resize', updateDimension, win);\n}\n\n// `knownDocs` matches buffers whose iframe.contentDocument has been swapped\n// before removal — bufferBelongsToIframe alone misses them.\nexport function findAndRemoveIframeBuffer(\n iframeEl: HTMLIFrameElement,\n knownDocs?: Set<Document>,\n) {\n for (let i = mutationBuffers.length - 1; i >= 0; i--) {\n const buf = mutationBuffers[i];\n if (!buf) continue;\n let match = buf.bufferBelongsToIframe(iframeEl);\n if (!match && knownDocs && knownDocs.has(buf.bufferDoc())) {\n match = true;\n }\n if (match) {\n buf.reset();\n mutationBuffers.splice(i, 1);\n }\n }\n}\n\nexport const INPUT_TAGS = ['INPUT', 'TEXTAREA', 'SELECT'];\nconst lastInputValueMap: WeakMap<EventTarget, inputValue> = new WeakMap();\nfunction initInputObserver({\n inputCb,\n doc,\n mirror,\n blockClass,\n blockSelector,\n ignoreClass,\n ignoreSelector,\n maskInputOptions,\n maskInputFn,\n sampling,\n userTriggeredOnInput,\n}: observerParam): listenerHandler {\n let active = true;\n function eventHandler(event: Event) {\n if (!active) return;\n let target = getEventTarget(event) as HTMLElement | null;\n const userTriggered = event.isTrusted;\n // Reading a native accessor (tagName/value/checked/type) on a non-native\n // `this` — e.g. a proxy, custom element, or cross-realm object reaching us\n // through the hooked setter's mock event — throws 'Illegal invocation'.\n // Bail out unless the target is a genuine element in this document's realm.\n const view = doc.defaultView;\n if (target && view && !(target instanceof view.HTMLElement)) {\n return;\n }\n const tagName = target && target.tagName;\n\n /**\n * If a site changes the value 'selected' of an option element, the value of its parent element, usually a select element, will be changed as well.\n * We can treat this change as a value change of the select element the current target belongs to.\n */\n if (target && tagName === 'OPTION') {\n target = dom.parentElement(target);\n }\n if (\n !target ||\n !tagName ||\n INPUT_TAGS.indexOf(tagName) < 0 ||\n isBlocked(target as Node, blockClass, blockSelector, true)\n ) {\n return;\n }\n\n if (\n target.classList.contains(ignoreClass) ||\n (ignoreSelector && target.matches(ignoreSelector))\n ) {\n return;\n }\n let text = (target as HTMLInputElement).value;\n let isChecked = false;\n const type: Lowercase<string> = getInputType(target) || '';\n\n if (type === 'radio' || type === 'checkbox') {\n isChecked = (target as HTMLInputElement).checked;\n } else if (\n maskInputOptions[tagName.toLowerCase() as keyof MaskInputOptions] ||\n maskInputOptions[type as keyof MaskInputOptions]\n ) {\n text = maskInputValue({\n element: target,\n maskInputOptions,\n tagName,\n type,\n value: text,\n maskInputFn,\n });\n }\n cbWithDedup(\n target,\n userTriggeredOnInput\n ? { text, isChecked, userTriggered }\n : { text, isChecked },\n );\n // if a radio was checked\n // the other radios with the same name attribute will be unchecked.\n const name: string | undefined = (target as HTMLInputElement).name;\n if (type === 'radio' && name && isChecked) {\n doc\n .querySelectorAll(`input[type=\"radio\"][name=\"${name}\"]`)\n .forEach((el) => {\n if (el !== target) {\n const text = (el as HTMLInputElement).value;\n cbWithDedup(\n el,\n userTriggeredOnInput\n ? { text, isChecked: !isChecked, userTriggered: false }\n : { text, isChecked: !isChecked },\n );\n }\n });\n }\n }\n function cbWithDedup(target: EventTarget, v: inputValue) {\n const lastInputValue = lastInputValueMap.get(target);\n if (\n !lastInputValue ||\n lastInputValue.text !== v.text ||\n lastInputValue.isChecked !== v.isChecked\n ) {\n lastInputValueMap.set(target, v);\n const id = mirror.getId(target as Node);\n callbackWrapper(inputCb)({\n ...v,\n id,\n });\n }\n }\n return acquireRecorderCleanup((cleanup) => {\n cleanup.add(() => {\n active = false;\n });\n const events = sampling.input === 'last' ? ['change'] : ['input', 'change'];\n for (const eventName of events)\n cleanup.add(on(eventName, callbackWrapper(eventHandler), doc));\n const currentWindow = doc.defaultView;\n if (!currentWindow) {\n return;\n }\n const propertyDescriptor = currentWindow.Object.getOwnPropertyDescriptor(\n currentWindow.HTMLInputElement.prototype,\n 'value',\n );\n const hookProperties: Array<[HTMLElement, string]> = [\n [currentWindow.HTMLInputElement.prototype, 'value'],\n [currentWindow.HTMLInputElement.prototype, 'checked'],\n [currentWindow.HTMLSelectElement.prototype, 'value'],\n [currentWindow.HTMLTextAreaElement.prototype, 'value'],\n // Some UI library use selectedIndex to set select value\n [currentWindow.HTMLSelectElement.prototype, 'selectedIndex'],\n [currentWindow.HTMLOptionElement.prototype, 'selected'],\n ];\n if (propertyDescriptor && propertyDescriptor.set) {\n for (const p of hookProperties) {\n const descriptor = currentWindow.Object.getOwnPropertyDescriptor(\n p[0],\n p[1],\n );\n cleanup.add(() => {\n if (descriptor)\n currentWindow.Object.defineProperty(p[0], p[1], descriptor);\n else Reflect.deleteProperty(p[0], p[1]);\n });\n hookSetter<HTMLElement>(\n p[0],\n p[1],\n {\n set() {\n // mock to a normal event\n callbackWrapper(eventHandler)({\n target: this as EventTarget,\n isTrusted: false, // userTriggered to false as this could well be programmatic\n } as Event);\n },\n },\n false,\n currentWindow,\n );\n }\n }\n });\n}\n\ntype GroupingCSSRule =\n | CSSGroupingRule\n | CSSMediaRule\n | CSSSupportsRule\n | CSSConditionRule;\ntype GroupingCSSRuleTypes =\n | typeof CSSGroupingRule\n | typeof CSSMediaRule\n | typeof CSSSupportsRule\n | typeof CSSConditionRule;\n\nfunction getNestedCSSRulePositions(rule: CSSRule): number[] {\n const positions: number[] = [];\n function recurse(childRule: CSSRule, pos: number[]) {\n if (\n (hasNestedCSSRule('CSSGroupingRule') &&\n childRule.parentRule instanceof CSSGroupingRule) ||\n (hasNestedCSSRule('CSSMediaRule') &&\n childRule.parentRule instanceof CSSMediaRule) ||\n (hasNestedCSSRule('CSSSupportsRule') &&\n childRule.parentRule instanceof CSSSupportsRule) ||\n (hasNestedCSSRule('CSSConditionRule') &&\n childRule.parentRule instanceof CSSConditionRule)\n ) {\n const rules = Array.from(\n (childRule.parentRule as GroupingCSSRule).cssRules,\n );\n const index = rules.indexOf(childRule);\n pos.unshift(index);\n return recurse(childRule.parentRule, pos);\n } else if (childRule.parentStyleSheet) {\n const rules = Array.from(childRule.parentStyleSheet.cssRules);\n const index = rules.indexOf(childRule);\n pos.unshift(index);\n }\n return pos;\n }\n return recurse(rule, positions);\n}\n\n/**\n * For StyleSheets in Element, this function retrieves id of its host element.\n * For adopted StyleSheets, this function retrieves its styleId from a styleMirror.\n */\nfunction getIdAndStyleId(\n sheet: CSSStyleSheet | undefined | null,\n mirror: Mirror,\n styleMirror: StyleSheetMirror,\n): {\n styleId?: number;\n id?: number;\n} {\n let id, styleId;\n if (!sheet) return {};\n if (sheet.ownerNode) id = mirror.getId(sheet.ownerNode as Node);\n else styleId = styleMirror.getId(sheet);\n return {\n styleId,\n id,\n };\n}\n\nfunction initStyleSheetObserver(\n { styleSheetRuleCb, mirror, stylesheetManager }: observerParam,\n { win }: { win: IWindow },\n): listenerHandler {\n if (!win.CSSStyleSheet || !win.CSSStyleSheet.prototype) {\n // If, for whatever reason, CSSStyleSheet is not available, we skip the observation of stylesheets.\n return () => {\n // Do nothing\n };\n }\n\n return acquireRecorderCleanup((cleanup) => {\n // eslint-disable-next-line @typescript-eslint/unbound-method\n const insertRule = win.CSSStyleSheet.prototype.insertRule;\n cleanup.replace(\n win.CSSStyleSheet.prototype,\n 'insertRule',\n new Proxy(insertRule, {\n apply: callbackWrapper(\n (\n target: typeof insertRule,\n thisArg: CSSStyleSheet,\n argumentsList: [string, number | undefined],\n ) => {\n const [rule, index] = argumentsList;\n\n const { id, styleId } = getIdAndStyleId(\n thisArg,\n mirror,\n stylesheetManager.styleMirror,\n );\n\n if ((id && id !== -1) || (styleId && styleId !== -1)) {\n styleSheetRuleCb({\n id,\n styleId,\n adds: [{ rule, index }],\n });\n }\n return target.apply(thisArg, argumentsList);\n },\n ),\n }),\n );\n\n // Support for deprecated addRule method\n cleanup.replace(\n win.CSSStyleSheet.prototype,\n 'addRule',\n function (\n this: CSSStyleSheet,\n selector: string,\n styleBlock: string,\n index: number = this.cssRules.length,\n ) {\n const rule = `${selector} { ${styleBlock} }`;\n return win.CSSStyleSheet.prototype.insertRule.apply(this, [\n rule,\n index,\n ]);\n },\n );\n\n // eslint-disable-next-line @typescript-eslint/unbound-method\n const deleteRule = win.CSSStyleSheet.prototype.deleteRule;\n cleanup.replace(\n win.CSSStyleSheet.prototype,\n 'deleteRule',\n new Proxy(deleteRule, {\n apply: callbackWrapper(\n (\n target: typeof deleteRule,\n thisArg: CSSStyleSheet,\n argumentsList: [number],\n ) => {\n const [index] = argumentsList;\n\n const { id, styleId } = getIdAndStyleId(\n thisArg,\n mirror,\n stylesheetManager.styleMirror,\n );\n\n if ((id && id !== -1) || (styleId && styleId !== -1)) {\n styleSheetRuleCb({\n id,\n styleId,\n removes: [{ index }],\n });\n }\n return target.apply(thisArg, argumentsList);\n },\n ),\n }),\n );\n\n // Support for deprecated removeRule method\n cleanup.replace(\n win.CSSStyleSheet.prototype,\n 'removeRule',\n function (this: CSSStyleSheet, index: number) {\n return win.CSSStyleSheet.prototype.deleteRule.apply(this, [index]);\n },\n );\n\n let replace: (text: string) => Promise<CSSStyleSheet>;\n\n if (win.CSSStyleSheet.prototype.replace) {\n // eslint-disable-next-line @typescript-eslint/unbound-method\n replace = win.CSSStyleSheet.prototype.replace;\n cleanup.replace(\n win.CSSStyleSheet.prototype,\n 'replace',\n new Proxy(replace, {\n apply: callbackWrapper(\n (\n target: typeof replace,\n thisArg: CSSStyleSheet,\n argumentsList: [string],\n ) => {\n const [text] = argumentsList;\n\n const { id, styleId } = getIdAndStyleId(\n thisArg,\n mirror,\n stylesheetManager.styleMirror,\n );\n\n if ((id && id !== -1) || (styleId && styleId !== -1)) {\n styleSheetRuleCb({\n id,\n styleId,\n replace: text,\n });\n }\n return target.apply(thisArg, argumentsList);\n },\n ),\n }),\n );\n }\n\n let replaceSync: (text: string) => void;\n if (win.CSSStyleSheet.prototype.replaceSync) {\n // eslint-disable-next-line @typescript-eslint/unbound-method\n replaceSync = win.CSSStyleSheet.prototype.replaceSync;\n cleanup.replace(\n win.CSSStyleSheet.prototype,\n 'replaceSync',\n new Proxy(replaceSync, {\n apply: callbackWrapper(\n (\n target: typeof replaceSync,\n thisArg: CSSStyleSheet,\n argumentsList: [string],\n ) => {\n const [text] = argumentsList;\n\n const { id, styleId } = getIdAndStyleId(\n thisArg,\n mirror,\n stylesheetManager.styleMirror,\n );\n\n if ((id && id !== -1) || (styleId && styleId !== -1)) {\n styleSheetRuleCb({\n id,\n styleId,\n replaceSync: text,\n });\n }\n return target.apply(thisArg, argumentsList);\n },\n ),\n }),\n );\n }\n\n const supportedNestedCSSRuleTypes: {\n [key: string]: GroupingCSSRuleTypes;\n } = {};\n if (canMonkeyPatchNestedCSSRule('CSSGroupingRule')) {\n supportedNestedCSSRuleTypes.CSSGroupingRule = win.CSSGroupingRule;\n } else {\n // Some browsers (Safari) don't support CSSGroupingRule\n // https://caniuse.com/?search=cssgroupingrule\n // fall back to monkey patching classes that would have inherited from CSSGroupingRule\n\n if (canMonkeyPatchNestedCSSRule('CSSMediaRule')) {\n supportedNestedCSSRuleTypes.CSSMediaRule = win.CSSMediaRule;\n }\n if (canMonkeyPatchNestedCSSRule('CSSConditionRule')) {\n supportedNestedCSSRuleTypes.CSSConditionRule = win.CSSConditionRule;\n }\n if (canMonkeyPatchNestedCSSRule('CSSSupportsRule')) {\n supportedNestedCSSRuleTypes.CSSSupportsRule = win.CSSSupportsRule;\n }\n }\n\n const unmodifiedFunctions: {\n [key: string]: {\n insertRule: (rule: string, index?: number) => number;\n deleteRule: (index: number) => void;\n };\n } = {};\n\n Object.entries(supportedNestedCSSRuleTypes).forEach(([typeKey, type]) => {\n unmodifiedFunctions[typeKey] = {\n // eslint-disable-next-line @typescript-eslint/unbound-method\n insertRule: type.prototype.insertRule,\n // eslint-disable-next-line @typescript-eslint/unbound-method\n deleteRule: type.prototype.deleteRule,\n };\n\n cleanup.replace(\n type.prototype,\n 'insertRule',\n new Proxy(unmodifiedFunctions[typeKey].insertRule, {\n apply: callbackWrapper(\n (\n target: typeof insertRule,\n thisArg: CSSRule,\n argumentsList: [string, number | undefined],\n ) => {\n const [rule, index] = argumentsList;\n\n const { id, styleId } = getIdAndStyleId(\n thisArg.parentStyleSheet,\n mirror,\n stylesheetManager.styleMirror,\n );\n\n if ((id && id !== -1) || (styleId && styleId !== -1)) {\n styleSheetRuleCb({\n id,\n styleId,\n adds: [\n {\n rule,\n index: [\n ...getNestedCSSRulePositions(thisArg),\n index || 0, // defaults to 0\n ],\n },\n ],\n });\n }\n return target.apply(thisArg, argumentsList);\n },\n ),\n }),\n );\n\n cleanup.replace(\n type.prototype,\n 'deleteRule',\n new Proxy(unmodifiedFunctions[typeKey].deleteRule, {\n apply: callbackWrapper(\n (\n target: typeof deleteRule,\n thisArg: CSSRule,\n argumentsList: [number],\n ) => {\n const [index] = argumentsList;\n\n const { id, styleId } = getIdAndStyleId(\n thisArg.parentStyleSheet,\n mirror,\n stylesheetManager.styleMirror,\n );\n\n if ((id && id !== -1) || (styleId && styleId !== -1)) {\n styleSheetRuleCb({\n id,\n styleId,\n removes: [\n { index: [...getNestedCSSRulePositions(thisArg), index] },\n ],\n });\n }\n return target.apply(thisArg, argumentsList);\n },\n ),\n }),\n );\n });\n });\n}\n\nexport function initAdoptedStyleSheetObserver(\n {\n mirror,\n stylesheetManager,\n }: Pick<observerParam, 'mirror' | 'stylesheetManager'>,\n host: Document | ShadowRoot,\n): listenerHandler {\n let hostId: number | null = null;\n // host of adoptedStyleSheets is outermost document or IFrame's document\n if (host.nodeName === '#document') hostId = mirror.getId(host);\n // The host is a ShadowRoot.\n else hostId = mirror.getId(dom.host(host as ShadowRoot));\n\n const patchTarget =\n host.nodeName === '#document'\n ? (host as Document).defaultView?.Document\n : host.ownerDocument?.defaultView?.ShadowRoot;\n const originalPropertyDescriptor = patchTarget?.prototype\n ? Object.getOwnPropertyDescriptor(\n patchTarget?.prototype,\n 'adoptedStyleSheets',\n )\n : undefined;\n if (\n hostId === null ||\n hostId === -1 ||\n !patchTarget ||\n !originalPropertyDescriptor\n )\n return () => {\n //\n };\n\n // Patch adoptedStyleSheets by overriding the original one.\n Object.defineProperty(host, 'adoptedStyleSheets', {\n configurable: originalPropertyDescriptor.configurable,\n enumerable: originalPropertyDescriptor.enumerable,\n get(): CSSStyleSheet[] {\n return originalPropertyDescriptor.get?.call(this) as CSSStyleSheet[];\n },\n set(sheets: CSSStyleSheet[]) {\n let result: unknown;\n try {\n result = originalPropertyDescriptor.set?.call(this, sheets);\n } catch (e) {\n // Assigning a `CSSStyleSheet` that was constructed in a different\n // document/realm makes the browser reject the assignment with\n // `NotAllowedError` (\"Sharing constructed stylesheets in multiple\n // documents is not allowed\"). That is the host page's own invalid\n // operation, but because our patched setter sits on the call stack\n // the exception would otherwise be attributed to the recorder and\n // churn fingerprints in error tracking. The browser rejects the\n // assignment atomically, so recording simply degrades (we skip the\n // adoption below). Contain only this specific, unactionable case;\n // re-throw everything else so genuine host-page failures are\n // preserved (mirrors `callSafely` in ../utils).\n //\n // Match on the standardized `name` rather than `instanceof\n // DOMException`: when this observer is installed on a (same-origin)\n // iframe document the native setter throws the iframe realm's\n // `DOMException`, which fails an `instanceof` check against the\n // recorder realm's constructor. The cross-document sharing error we\n // want to contain is exactly that cross-realm case, so a name check\n // is what keeps iframe recordings protected too.\n if (\n !!e &&\n typeof e === 'object' &&\n (e as { name?: unknown }).name === 'NotAllowedError'\n ) {\n return;\n }\n throw e;\n }\n if (hostId !== null && hostId !== -1) {\n try {\n stylesheetManager.adoptStyleSheets(sheets, hostId);\n } catch (e) {\n // for safety\n }\n }\n return result;\n },\n });\n\n return callbackWrapper(() => {\n Object.defineProperty(host, 'adoptedStyleSheets', {\n configurable: originalPropertyDescriptor.configurable,\n enumerable: originalPropertyDescriptor.enumerable,\n // eslint-disable-next-line @typescript-eslint/unbound-method\n get: originalPropertyDescriptor.get,\n // eslint-disable-next-line @typescript-eslint/unbound-method\n set: originalPropertyDescriptor.set,\n });\n });\n}\n\nfunction initStyleDeclarationObserver(\n {\n styleDeclarationCb,\n mirror,\n ignoreCSSAttributes,\n stylesheetManager,\n }: observerParam,\n { win }: { win: IWindow },\n): listenerHandler {\n return acquireRecorderCleanup((cleanup) => {\n // eslint-disable-next-line @typescript-eslint/unbound-method\n const setProperty = win.CSSStyleDeclaration.prototype.setProperty;\n cleanup.replace(\n win.CSSStyleDeclaration.prototype,\n 'setProperty',\n new Proxy(setProperty, {\n apply: callbackWrapper(\n (\n target: typeof setProperty,\n thisArg: CSSStyleDeclaration,\n argumentsList: [string, string, string],\n ) => {\n const [property, value, priority] = argumentsList;\n\n // ignore this mutation if we do not care about this css attribute\n if (ignoreCSSAttributes.has(property)) {\n return setProperty.apply(thisArg, [property, value, priority]);\n }\n const { id, styleId } = getIdAndStyleId(\n thisArg.parentRule?.parentStyleSheet,\n mirror,\n stylesheetManager.styleMirror,\n );\n if ((id && id !== -1) || (styleId && styleId !== -1)) {\n styleDeclarationCb({\n id,\n styleId,\n set: {\n property,\n value,\n priority,\n },\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n index: getNestedCSSRulePositions(thisArg.parentRule!),\n });\n }\n return target.apply(thisArg, argumentsList);\n },\n ),\n }),\n );\n\n // eslint-disable-next-line @typescript-eslint/unbound-method\n const removeProperty = win.CSSStyleDeclaration.prototype.removeProperty;\n cleanup.replace(\n win.CSSStyleDeclaration.prototype,\n 'removeProperty',\n new Proxy(removeProperty, {\n apply: callbackWrapper(\n (\n target: typeof removeProperty,\n thisArg: CSSStyleDeclaration,\n argumentsList: [string],\n ) => {\n const [property] = argumentsList;\n\n // ignore this mutation if we do not care about this css attribute\n if (ignoreCSSAttributes.has(property)) {\n return removeProperty.apply(thisArg, [property]);\n }\n const { id, styleId } = getIdAndStyleId(\n thisArg.parentRule?.parentStyleSheet,\n mirror,\n stylesheetManager.styleMirror,\n );\n if ((id && id !== -1) || (styleId && styleId !== -1)) {\n styleDeclarationCb({\n id,\n styleId,\n remove: {\n property,\n },\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n index: getNestedCSSRulePositions(thisArg.parentRule!),\n });\n }\n return target.apply(thisArg, argumentsList);\n },\n ),\n }),\n );\n });\n}\n\nfunction initMediaInteractionObserver({\n mediaInteractionCb,\n blockClass,\n blockSelector,\n mirror,\n sampling,\n doc,\n}: observerParam): listenerHandler {\n let active = true;\n const handler = callbackWrapper((type: MediaInteractions) =>\n throttle(\n callbackWrapper((event: Event) => {\n if (!active) return;\n const target = getEventTarget(event);\n if (\n !target ||\n isBlocked(target as Node, blockClass, blockSelector, true)\n ) {\n return;\n }\n const { currentTime, volume, muted, playbackRate, loop } =\n target as HTMLMediaElement;\n mediaInteractionCb({\n type,\n id: mirror.getId(target as Node),\n currentTime,\n volume,\n muted,\n playbackRate,\n loop,\n });\n }),\n sampling.media || 500,\n ),\n );\n return acquireRecorderCleanup((cleanup) => {\n cleanup.add(() => {\n active = false;\n });\n cleanup.add(on('play', handler(MediaInteractions.Play), doc));\n cleanup.add(on('pause', handler(MediaInteractions.Pause), doc));\n cleanup.add(on('seeked', handler(MediaInteractions.Seeked), doc));\n cleanup.add(\n on('volumechange', handler(MediaInteractions.VolumeChange), doc),\n );\n cleanup.add(on('ratechange', handler(MediaInteractions.RateChange), doc));\n });\n}\n\nfunction initFontObserver({ fontCb, doc }: observerParam): listenerHandler {\n let active = true;\n const win = doc.defaultView as IWindow;\n if (!win) {\n return () => {\n //\n };\n }\n\n return acquireRecorderCleanup((cleanup) => {\n cleanup.add(() => {\n active = false;\n });\n\n const fontMap = new WeakMap<FontFace, fontParam>();\n\n const originalFontFace = win.FontFace;\n cleanup.replace(win, 'FontFace', function FontFace(\n family: string,\n source: string | ArrayBufferLike,\n descriptors?: FontFaceDescriptors,\n ) {\n const fontFace = new originalFontFace(\n family,\n source as string | BufferSource,\n descriptors,\n );\n fontMap.set(fontFace, {\n family,\n buffer: typeof source !== 'string',\n descriptors,\n fontSource:\n typeof source === 'string'\n ? source\n : JSON.stringify(Array.from(new Uint8Array(source))),\n });\n return fontFace;\n } as unknown as typeof FontFace);\n\n const restoreHandler = patch(\n doc.fonts,\n 'add',\n function (original: (font: FontFace) => void) {\n return function (this: FontFaceSet, fontFace: FontFace) {\n setTimeout(\n callbackWrapper(() => {\n if (!active) return;\n const p = fontMap.get(fontFace);\n if (p) {\n fontCb(p);\n fontMap.delete(fontFace);\n }\n }),\n 0,\n );\n return original.apply(this, [fontFace]);\n };\n },\n );\n\n cleanup.add(restoreHandler);\n });\n}\n\nfunction initSelectionObserver(param: observerParam): listenerHandler {\n const { doc, mirror, blockClass, blockSelector, selectionCb } = param;\n let collapsed = true;\n\n const updateSelection = callbackWrapper(() => {\n const selection = doc.getSelection();\n\n if (!selection || (collapsed && selection?.isCollapsed)) return;\n\n collapsed = selection.isCollapsed || false;\n\n const ranges: SelectionRange[] = [];\n const count = selection.rangeCount || 0;\n\n for (let i = 0; i < count; i++) {\n const range = selection.getRangeAt(i);\n\n const { startContainer, startOffset, endContainer, endOffset } = range;\n\n const blocked =\n isBlocked(startContainer, blockClass, blockSelector, true) ||\n isBlocked(endContainer, blockClass, blockSelector, true);\n\n if (blocked) continue;\n\n ranges.push({\n start: mirror.getId(startContainer),\n startOffset,\n end: mirror.getId(endContainer),\n endOffset,\n });\n }\n\n selectionCb({ ranges });\n });\n\n updateSelection();\n\n return on('selectionchange', updateSelection);\n}\n\nfunction initCustomElementObserver({\n doc,\n customElementCb,\n}: observerParam): listenerHandler {\n const win = doc.defaultView as IWindow;\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n if (!win || !win.customElements) return () => {};\n const restoreHandler = patch(\n win.customElements,\n 'define',\n function (\n original: (\n name: string,\n constructor: CustomElementConstructor,\n options?: ElementDefinitionOptions,\n ) => void,\n ) {\n return function (\n name: string,\n constructor: CustomElementConstructor,\n options?: ElementDefinitionOptions,\n ) {\n try {\n customElementCb({\n define: {\n name,\n },\n });\n } catch (e) {\n console.warn(`Custom element callback failed for ${name}`);\n }\n return original.apply(this, [name, constructor, options]);\n };\n },\n );\n return restoreHandler;\n}\n\nfunction mergeHooks(o: observerParam, hooks: hooksParam) {\n const {\n mutationCb,\n mousemoveCb,\n mouseInteractionCb,\n scrollCb,\n viewportResizeCb,\n inputCb,\n mediaInteractionCb,\n styleSheetRuleCb,\n styleDeclarationCb,\n canvasMutationCb,\n fontCb,\n selectionCb,\n customElementCb,\n } = o;\n o.mutationCb = (...p: Arguments<mutationCallBack>) => {\n if (hooks.mutation) {\n hooks.mutation(...p);\n }\n mutationCb(...p);\n };\n o.mousemoveCb = (...p: Arguments<mousemoveCallBack>) => {\n if (hooks.mousemove) {\n hooks.mousemove(...p);\n }\n mousemoveCb(...p);\n };\n o.mouseInteractionCb = (...p: Arguments<mouseInteractionCallBack>) => {\n if (hooks.mouseInteraction) {\n hooks.mouseInteraction(...p);\n }\n mouseInteractionCb(...p);\n };\n o.scrollCb = (...p: Arguments<scrollCallback>) => {\n if (hooks.scroll) {\n hooks.scroll(...p);\n }\n scrollCb(...p);\n };\n o.viewportResizeCb = (...p: Arguments<viewportResizeCallback>) => {\n if (hooks.viewportResize) {\n hooks.viewportResize(...p);\n }\n viewportResizeCb(...p);\n };\n o.inputCb = (...p: Arguments<inputCallback>) => {\n if (hooks.input) {\n hooks.input(...p);\n }\n inputCb(...p);\n };\n o.mediaInteractionCb = (...p: Arguments<mediaInteractionCallback>) => {\n if (hooks.mediaInteaction) {\n hooks.mediaInteaction(...p);\n }\n mediaInteractionCb(...p);\n };\n o.styleSheetRuleCb = (...p: Arguments<styleSheetRuleCallback>) => {\n if (hooks.styleSheetRule) {\n hooks.styleSheetRule(...p);\n }\n styleSheetRuleCb(...p);\n };\n o.styleDeclarationCb = (...p: Arguments<styleDeclarationCallback>) => {\n if (hooks.styleDeclaration) {\n hooks.styleDeclaration(...p);\n }\n styleDeclarationCb(...p);\n };\n o.canvasMutationCb = (...p: Arguments<canvasMutationCallback>) => {\n if (hooks.canvasMutation) {\n hooks.canvasMutation(...p);\n }\n canvasMutationCb(...p);\n };\n o.fontCb = (...p: Arguments<fontCallback>) => {\n if (hooks.font) {\n hooks.font(...p);\n }\n fontCb(...p);\n };\n o.selectionCb = (...p: Arguments<selectionCallback>) => {\n if (hooks.selection) {\n hooks.selection(...p);\n }\n selectionCb(...p);\n };\n o.customElementCb = (...c: Arguments<customElementCallback>) => {\n if (hooks.customElement) {\n hooks.customElement(...c);\n }\n customElementCb(...c);\n };\n}\n\nexport function initObservers(\n o: observerParam,\n hooks: hooksParam = {},\n): listenerHandler {\n const currentWindow = o.doc.defaultView; // basically document.window\n if (!currentWindow) {\n return () => {\n //\n };\n }\n\n mergeHooks(o, hooks);\n return acquireRecorderCleanup((cleanup) => {\n cleanup.add(() => o.shadowDomManager.resetForDoc(o.doc));\n if (o.recordDOM) {\n const { observer, buffer } = initMutationObserver(o, o.doc);\n cleanup.add(() => {\n const index = mutationBuffers.indexOf(buffer);\n if (index !== -1) mutationBuffers.splice(index, 1);\n });\n cleanup.add(() => buffer.destroy());\n cleanup.add(() => buffer.reset());\n cleanup.add(() => observer.disconnect());\n }\n cleanup.add(initMoveObserver(o));\n cleanup.add(initMouseInteractionObserver(o));\n cleanup.add(initScrollObserver(o));\n cleanup.add(initViewportResizeObserver(o, { win: currentWindow }));\n cleanup.add(initInputObserver(o));\n cleanup.add(initMediaInteractionObserver(o));\n if (o.recordDOM) {\n cleanup.add(initStyleSheetObserver(o, { win: currentWindow }));\n cleanup.add(initAdoptedStyleSheetObserver(o, o.doc));\n cleanup.add(initStyleDeclarationObserver(o, { win: currentWindow }));\n if (o.collectFonts) cleanup.add(initFontObserver(o));\n }\n cleanup.add(initSelectionObserver(o));\n cleanup.add(initCustomElementObserver(o));\n for (const plugin of o.plugins)\n cleanup.add(\n plugin.observer(plugin.callback, currentWindow, plugin.options),\n );\n });\n}\n\ntype CSSGroupingProp =\n | 'CSSGroupingRule'\n | 'CSSMediaRule'\n | 'CSSSupportsRule'\n | 'CSSConditionRule';\n\nfunction hasNestedCSSRule(prop: CSSGroupingProp): boolean {\n return typeof window[prop] !== 'undefined';\n}\n\nfunction canMonkeyPatchNestedCSSRule(prop: CSSGroupingProp): boolean {\n return Boolean(\n typeof window[prop] !== 'undefined' &&\n // Note: Generally, this check _shouldn't_ be necessary\n // However, in some scenarios (e.g. jsdom) this can sometimes fail, so we check for it here\n window[prop].prototype &&\n 'insertRule' in window[prop].prototype &&\n 'deleteRule' in window[prop].prototype,\n );\n}\n","// Modified by ELU. See NOTICE-ELU and THIRD_PARTY_NOTICES.txt.\n\nimport type { ICrossOriginIframeMirror } from '@elu-labs/recorder-types';\nexport default class CrossOriginIframeMirror\n implements ICrossOriginIframeMirror\n{\n private iframeIdToRemoteIdMap: WeakMap<\n HTMLIFrameElement,\n Map<number, number>\n > = new WeakMap();\n private iframeRemoteIdToIdMap: WeakMap<\n HTMLIFrameElement,\n Map<number, number>\n > = new WeakMap();\n\n constructor(private generateIdFn: () => number) {}\n\n getId(\n iframe: HTMLIFrameElement,\n remoteId: number,\n idToRemoteMap?: Map<number, number>,\n remoteToIdMap?: Map<number, number>,\n ): number {\n const idToRemoteIdMap = idToRemoteMap || this.getIdToRemoteIdMap(iframe);\n const remoteIdToIdMap = remoteToIdMap || this.getRemoteIdToIdMap(iframe);\n\n let id = idToRemoteIdMap.get(remoteId);\n if (!id) {\n id = this.generateIdFn();\n idToRemoteIdMap.set(remoteId, id);\n remoteIdToIdMap.set(id, remoteId);\n }\n return id;\n }\n\n getIds(iframe: HTMLIFrameElement, remoteId: number[]): number[] {\n const idToRemoteIdMap = this.getIdToRemoteIdMap(iframe);\n const remoteIdToIdMap = this.getRemoteIdToIdMap(iframe);\n return remoteId.map((id) =>\n this.getId(iframe, id, idToRemoteIdMap, remoteIdToIdMap),\n );\n }\n\n getRemoteId(\n iframe: HTMLIFrameElement,\n id: number,\n map?: Map<number, number>,\n ): number {\n const remoteIdToIdMap = map || this.getRemoteIdToIdMap(iframe);\n\n if (typeof id !== 'number') return id;\n\n const remoteId = remoteIdToIdMap.get(id);\n if (!remoteId) return -1;\n return remoteId;\n }\n\n getRemoteIds(iframe: HTMLIFrameElement, ids: number[]): number[] {\n const remoteIdToIdMap = this.getRemoteIdToIdMap(iframe);\n\n return ids.map((id) => this.getRemoteId(iframe, id, remoteIdToIdMap));\n }\n\n reset(iframe?: HTMLIFrameElement) {\n if (!iframe) {\n this.iframeIdToRemoteIdMap = new WeakMap();\n this.iframeRemoteIdToIdMap = new WeakMap();\n return;\n }\n this.iframeIdToRemoteIdMap.delete(iframe);\n this.iframeRemoteIdToIdMap.delete(iframe);\n }\n\n private getIdToRemoteIdMap(iframe: HTMLIFrameElement) {\n let idToRemoteIdMap = this.iframeIdToRemoteIdMap.get(iframe);\n if (!idToRemoteIdMap) {\n idToRemoteIdMap = new Map();\n this.iframeIdToRemoteIdMap.set(iframe, idToRemoteIdMap);\n }\n return idToRemoteIdMap;\n }\n\n private getRemoteIdToIdMap(iframe: HTMLIFrameElement) {\n let remoteIdToIdMap = this.iframeRemoteIdToIdMap.get(iframe);\n if (!remoteIdToIdMap) {\n remoteIdToIdMap = new Map();\n this.iframeRemoteIdToIdMap.set(iframe, remoteIdToIdMap);\n }\n return remoteIdToIdMap;\n }\n}\n","// Modified by ELU. See NOTICE-ELU and THIRD_PARTY_NOTICES.txt.\n\nimport type { Mirror } from '@elu-labs/recorder-snapshot';\nimport { genId } from '@elu-labs/recorder-snapshot';\nimport type { CrossOriginIframeMessageEvent } from '../types';\nimport { callSafely, removeEventListenerSafely } from '../utils';\nimport CrossOriginIframeMirror from './cross-origin-iframe-mirror';\nimport { findAndRemoveIframeBuffer } from './observer';\nimport { EventType, NodeType, IncrementalSource } from '@elu-labs/recorder-types';\nimport type {\n eventWithTime,\n eventWithoutTime,\n serializedNodeWithId,\n mutationCallBack,\n} from '@elu-labs/recorder-types';\nimport type { StylesheetManager } from './stylesheet-manager';\n\nexport class IframeManager {\n private iframes: WeakMap<HTMLIFrameElement, true> = new WeakMap();\n private crossOriginIframeMap: WeakMap<MessageEventSource, HTMLIFrameElement> =\n new WeakMap();\n public crossOriginIframeMirror = new CrossOriginIframeMirror(genId);\n public crossOriginIframeStyleMirror: CrossOriginIframeMirror;\n public crossOriginIframeRootIdMap: WeakMap<HTMLIFrameElement, number> =\n new WeakMap();\n private mirror: Mirror;\n private mutationCb: mutationCallBack;\n private wrappedEmit: (e: eventWithoutTime, isCheckout?: boolean) => void;\n private loadListener?: (iframeEl: HTMLIFrameElement) => unknown;\n private pageHideListener?: (iframeEl: HTMLIFrameElement) => unknown;\n private stylesheetManager: StylesheetManager;\n private recordCrossOriginIframes: boolean;\n private messageHandler: (message: MessageEvent) => void;\n // Strong Map — keys pin Windows; every entry must be deleted on detach.\n private nestedIframeListeners: Map<Window, (message: MessageEvent) => void> =\n new Map();\n // Originals captured per iframe so cleanup survives iframe.src swaps.\n private attachedWindows: WeakMap<HTMLIFrameElement, Set<Window>> =\n new WeakMap();\n private attachedDocuments: WeakMap<HTMLIFrameElement, Set<Document>> =\n new WeakMap();\n private attachedIframes: Map<\n number,\n { element: HTMLIFrameElement; content: serializedNodeWithId }\n > = new Map();\n // Set per element — one iframe collects multiple disposers across loads.\n private loadListenerDisposers: WeakMap<HTMLIFrameElement, Set<() => void>> =\n new WeakMap();\n // Fallback for iframes removed before first load — mirror entry is gone\n // by then, but we still need the element to dispose its load listener.\n private iframeElementsById: Map<number, HTMLIFrameElement> = new Map();\n // Set per element — same multi-load reasoning as loadListenerDisposers.\n private pageHideHandlers: WeakMap<\n HTMLIFrameElement,\n Set<{ win: Window; handler: () => void }>\n > = new WeakMap();\n\n constructor(options: {\n mirror: Mirror;\n mutationCb: mutationCallBack;\n stylesheetManager: StylesheetManager;\n recordCrossOriginIframes: boolean;\n wrappedEmit: (e: eventWithoutTime, isCheckout?: boolean) => void;\n }) {\n this.mutationCb = options.mutationCb;\n this.wrappedEmit = options.wrappedEmit;\n this.stylesheetManager = options.stylesheetManager;\n this.recordCrossOriginIframes = options.recordCrossOriginIframes;\n this.crossOriginIframeStyleMirror = new CrossOriginIframeMirror(\n this.stylesheetManager.styleMirror.generateId.bind(\n this.stylesheetManager.styleMirror,\n ),\n );\n this.mirror = options.mirror;\n this.messageHandler = this.handleMessage.bind(this);\n if (this.recordCrossOriginIframes) {\n window.addEventListener('message', this.messageHandler);\n }\n }\n\n public addIframe(iframeEl: HTMLIFrameElement) {\n this.iframes.set(iframeEl, true);\n if (iframeEl.contentWindow)\n this.crossOriginIframeMap.set(iframeEl.contentWindow, iframeEl);\n }\n\n public registerLoadListenerDisposer(\n iframeEl: HTMLIFrameElement,\n disposer: () => void,\n ) {\n let bucket = this.loadListenerDisposers.get(iframeEl);\n if (!bucket) {\n bucket = new Set();\n this.loadListenerDisposers.set(iframeEl, bucket);\n }\n bucket.add(disposer);\n const id = this.mirror.getId(iframeEl);\n if (id !== -1) this.iframeElementsById.set(id, iframeEl);\n }\n\n // Used by the record-loop to distinguish reparenting from removal.\n public getIframeElementById(iframeId: number): HTMLIFrameElement | null {\n return (\n this.attachedIframes.get(iframeId)?.element ??\n this.iframeElementsById.get(iframeId) ??\n null\n );\n }\n\n // Drops the id mapping for a moved iframe; element-keyed state survives.\n public forgetIframeId(iframeId: number) {\n this.attachedIframes.delete(iframeId);\n this.iframeElementsById.delete(iframeId);\n }\n\n private disposeLoadListeners(iframeEl: HTMLIFrameElement) {\n const bucket = this.loadListenerDisposers.get(iframeEl);\n if (!bucket) return;\n bucket.forEach((d) => callSafely(d));\n this.loadListenerDisposers.delete(iframeEl);\n }\n\n private removePageHideListener(iframeEl: HTMLIFrameElement) {\n const bucket = this.pageHideHandlers.get(iframeEl);\n if (!bucket) return;\n bucket.forEach(({ win, handler }) => {\n removeEventListenerSafely(win, 'pagehide', handler);\n });\n this.pageHideHandlers.delete(iframeEl);\n }\n\n public addLoadListener(cb: (iframeEl: HTMLIFrameElement) => unknown) {\n this.loadListener = cb;\n }\n\n public addPageHideListener(cb: (iframeEl: HTMLIFrameElement) => unknown) {\n this.pageHideListener = cb;\n }\n\n public removeLoadListener() {\n this.loadListener = undefined;\n }\n\n private trackIframeContent(\n iframeEl: HTMLIFrameElement,\n content: serializedNodeWithId,\n ): number {\n const iframeId = this.mirror.getId(iframeEl);\n this.attachedIframes.set(iframeId, { element: iframeEl, content });\n return iframeId;\n }\n\n public attachIframe(\n iframeEl: HTMLIFrameElement,\n childSn: serializedNodeWithId,\n ) {\n const iframeId = this.trackIframeContent(iframeEl, childSn);\n // Accumulate every contentDocument across loads (blank → src → blank).\n if (iframeEl.contentDocument) {\n let docs = this.attachedDocuments.get(iframeEl);\n if (!docs) {\n docs = new Set();\n this.attachedDocuments.set(iframeEl, docs);\n }\n docs.add(iframeEl.contentDocument);\n }\n this.mutationCb({\n adds: [\n {\n parentId: iframeId,\n nextId: null,\n node: childSn,\n },\n ],\n removes: [],\n texts: [],\n attributes: [],\n isAttachIframe: true,\n });\n\n // Receive messages (events) coming from cross-origin iframes that are nested in this same-origin iframe.\n const win = iframeEl.contentWindow;\n if (\n this.recordCrossOriginIframes &&\n win &&\n !this.nestedIframeListeners.has(win)\n ) {\n const nestedHandler = this.handleMessage.bind(this);\n callSafely(() => {\n win.addEventListener('message', nestedHandler);\n this.nestedIframeListeners.set(win, nestedHandler);\n // Track per-iframe so detach finds it even after a contentWindow swap.\n let wins = this.attachedWindows.get(iframeEl);\n if (!wins) {\n wins = new Set();\n this.attachedWindows.set(iframeEl, wins);\n }\n wins.add(win);\n });\n }\n\n callSafely(() => {\n const pageHideWindow = iframeEl.contentWindow;\n if (!pageHideWindow) return;\n let bucket = this.pageHideHandlers.get(iframeEl);\n // Reparented / re-attached iframes call attachIframe again on the same\n // Window; skip if we already registered a handler for it.\n if (bucket) {\n for (const entry of bucket) {\n if (entry.win === pageHideWindow) return;\n }\n }\n const handler = () => {\n this.pageHideListener?.(iframeEl);\n if (iframeEl.contentDocument) {\n this.mirror.removeNodeFromMap(iframeEl.contentDocument);\n }\n if (iframeEl.contentWindow) {\n this.crossOriginIframeMap.delete(iframeEl.contentWindow);\n }\n };\n pageHideWindow.addEventListener('pagehide', handler);\n if (!bucket) {\n bucket = new Set();\n this.pageHideHandlers.set(iframeEl, bucket);\n }\n bucket.add({ win: pageHideWindow, handler });\n });\n\n this.loadListener?.(iframeEl);\n\n if (\n iframeEl.contentDocument &&\n iframeEl.contentDocument.adoptedStyleSheets &&\n iframeEl.contentDocument.adoptedStyleSheets.length > 0\n )\n this.stylesheetManager.adoptStyleSheets(\n iframeEl.contentDocument.adoptedStyleSheets,\n this.mirror.getId(iframeEl.contentDocument),\n );\n }\n private handleMessage(message: MessageEvent | CrossOriginIframeMessageEvent) {\n const crossOriginMessageEvent = message as CrossOriginIframeMessageEvent;\n if (\n crossOriginMessageEvent.data.type !== 'rrweb' ||\n // To filter out the rrweb messages which are forwarded by some sites.\n crossOriginMessageEvent.origin !== crossOriginMessageEvent.data.origin\n )\n return;\n\n const iframeSourceWindow = message.source;\n if (!iframeSourceWindow) return;\n\n const iframeEl = this.crossOriginIframeMap.get(message.source);\n if (!iframeEl) return;\n\n const transformedEvent = this.transformCrossOriginEvent(\n iframeEl,\n crossOriginMessageEvent.data.event,\n );\n\n if (transformedEvent)\n this.wrappedEmit(\n transformedEvent,\n crossOriginMessageEvent.data.isCheckout,\n );\n }\n\n private transformCrossOriginEvent(\n iframeEl: HTMLIFrameElement,\n e: eventWithTime,\n ): eventWithTime | false {\n switch (e.type) {\n case EventType.FullSnapshot: {\n this.crossOriginIframeMirror.reset(iframeEl);\n this.crossOriginIframeStyleMirror.reset(iframeEl);\n /**\n * Replaces the original id of the iframe with a new set of unique ids\n */\n this.replaceIdOnNode(e.data.node, iframeEl);\n const rootId = e.data.node.id;\n this.crossOriginIframeRootIdMap.set(iframeEl, rootId);\n this.patchRootIdOnNode(e.data.node, rootId);\n this.trackIframeContent(iframeEl, e.data.node);\n return {\n timestamp: e.timestamp,\n type: EventType.IncrementalSnapshot,\n data: {\n source: IncrementalSource.Mutation,\n adds: [\n {\n parentId: this.mirror.getId(iframeEl),\n nextId: null,\n node: e.data.node,\n },\n ],\n removes: [],\n texts: [],\n attributes: [],\n isAttachIframe: true,\n },\n };\n }\n case EventType.Meta:\n case EventType.Load:\n case EventType.DomContentLoaded: {\n return false;\n }\n case EventType.Plugin: {\n return e;\n }\n case EventType.Custom: {\n this.replaceIds(\n e.data.payload as {\n id?: unknown;\n parentId?: unknown;\n previousId?: unknown;\n nextId?: unknown;\n },\n iframeEl,\n ['id', 'parentId', 'previousId', 'nextId'],\n );\n return e;\n }\n case EventType.IncrementalSnapshot: {\n switch (e.data.source) {\n case IncrementalSource.Mutation: {\n e.data.adds.forEach((n) => {\n this.replaceIds(n, iframeEl, [\n 'parentId',\n 'nextId',\n 'previousId',\n ]);\n this.replaceIdOnNode(n.node, iframeEl);\n const rootId = this.crossOriginIframeRootIdMap.get(iframeEl);\n rootId && this.patchRootIdOnNode(n.node, rootId);\n });\n e.data.removes.forEach((n) => {\n this.replaceIds(n, iframeEl, ['parentId', 'id']);\n });\n e.data.attributes.forEach((n) => {\n this.replaceIds(n, iframeEl, ['id']);\n });\n e.data.texts.forEach((n) => {\n this.replaceIds(n, iframeEl, ['id']);\n });\n return e;\n }\n case IncrementalSource.Drag:\n case IncrementalSource.TouchMove:\n case IncrementalSource.MouseMove: {\n e.data.positions.forEach((p) => {\n this.replaceIds(p, iframeEl, ['id']);\n });\n return e;\n }\n case IncrementalSource.ViewportResize: {\n // can safely ignore these events\n return false;\n }\n case IncrementalSource.MediaInteraction:\n case IncrementalSource.MouseInteraction:\n case IncrementalSource.Scroll:\n case IncrementalSource.CanvasMutation:\n case IncrementalSource.Input: {\n this.replaceIds(e.data, iframeEl, ['id']);\n return e;\n }\n case IncrementalSource.StyleSheetRule:\n case IncrementalSource.StyleDeclaration: {\n this.replaceIds(e.data, iframeEl, ['id']);\n this.replaceStyleIds(e.data, iframeEl, ['styleId']);\n return e;\n }\n case IncrementalSource.Font: {\n // fine as-is no modification needed\n return e;\n }\n case IncrementalSource.Selection: {\n e.data.ranges.forEach((range) => {\n this.replaceIds(range, iframeEl, ['start', 'end']);\n });\n return e;\n }\n case IncrementalSource.AdoptedStyleSheet: {\n this.replaceIds(e.data, iframeEl, ['id']);\n this.replaceStyleIds(e.data, iframeEl, ['styleIds']);\n e.data.styles?.forEach((style) => {\n this.replaceStyleIds(style, iframeEl, ['styleId']);\n });\n return e;\n }\n }\n }\n }\n return false;\n }\n\n private replace<T extends Record<string, unknown>>(\n iframeMirror: CrossOriginIframeMirror,\n obj: T,\n iframeEl: HTMLIFrameElement,\n keys: Array<keyof T>,\n ): T {\n for (const key of keys) {\n if (!Array.isArray(obj[key]) && typeof obj[key] !== 'number') continue;\n if (Array.isArray(obj[key])) {\n obj[key] = iframeMirror.getIds(\n iframeEl,\n obj[key] as number[],\n ) as T[keyof T];\n } else {\n (obj[key] as number) = iframeMirror.getId(iframeEl, obj[key] as number);\n }\n }\n\n return obj;\n }\n\n private replaceIds<T extends Record<string, unknown>>(\n obj: T,\n iframeEl: HTMLIFrameElement,\n keys: Array<keyof T>,\n ): T {\n return this.replace(this.crossOriginIframeMirror, obj, iframeEl, keys);\n }\n\n private replaceStyleIds<T extends Record<string, unknown>>(\n obj: T,\n iframeEl: HTMLIFrameElement,\n keys: Array<keyof T>,\n ): T {\n return this.replace(this.crossOriginIframeStyleMirror, obj, iframeEl, keys);\n }\n\n private replaceIdOnNode(\n node: serializedNodeWithId,\n iframeEl: HTMLIFrameElement,\n ) {\n this.replaceIds(node, iframeEl, ['id', 'rootId']);\n if ('childNodes' in node) {\n node.childNodes.forEach((child) => {\n this.replaceIdOnNode(child, iframeEl);\n });\n }\n }\n\n private patchRootIdOnNode(node: serializedNodeWithId, rootId: number) {\n if (node.type !== NodeType.Document && !node.rootId) node.rootId = rootId;\n if ('childNodes' in node) {\n node.childNodes.forEach((child) => {\n this.patchRootIdOnNode(child, rootId);\n });\n }\n }\n\n public removeIframeById(iframeId: number) {\n const entry = this.attachedIframes.get(iframeId);\n // attachedIframes / mirror may both be empty for iframes removed\n // before first load; iframeElementsById covers that case.\n const iframe =\n entry?.element ||\n this.iframeElementsById.get(iframeId) ||\n (this.mirror.getNode(iframeId) as HTMLIFrameElement | null);\n\n this.iframeElementsById.delete(iframeId);\n\n if (iframe) {\n const win = iframe.contentWindow;\n\n // Clear listeners for every Window this iframe ever held — host\n // may have swapped iframe.src before removal.\n const capturedWins = this.attachedWindows.get(iframe);\n if (capturedWins) {\n capturedWins.forEach((capturedWin) => {\n const handler = this.nestedIframeListeners.get(capturedWin);\n if (handler) {\n removeEventListenerSafely(capturedWin, 'message', handler);\n this.nestedIframeListeners.delete(capturedWin);\n }\n this.crossOriginIframeMap.delete(capturedWin);\n });\n this.attachedWindows.delete(iframe);\n }\n // Legacy/test path: nestedIframeListeners populated without\n // attachIframe (preserves SecurityError handling from #163).\n if (win && this.nestedIframeListeners.has(win)) {\n const handler = this.nestedIframeListeners.get(win)!;\n removeEventListenerSafely(win, 'message', handler);\n this.nestedIframeListeners.delete(win);\n }\n\n if (win) {\n this.crossOriginIframeMap.delete(win);\n }\n this.iframes.delete(iframe);\n\n this.disposeLoadListeners(iframe);\n this.removePageHideListener(iframe);\n\n // Walk captured docs so mirror.idNodeMap drops them even after\n // an iframe.src swap, then splice their MutationBuffers.\n const capturedDocs = this.attachedDocuments.get(iframe);\n if (capturedDocs) {\n capturedDocs.forEach((doc) => {\n callSafely(() => this.mirror.removeNodeFromMap(doc));\n });\n callSafely(() => findAndRemoveIframeBuffer(iframe, capturedDocs));\n this.attachedDocuments.delete(iframe);\n }\n }\n\n if (entry) {\n this.attachedIframes.delete(iframeId);\n }\n }\n\n // Catches iframes removed inside a removed subtree (only the\n // ancestor's id appears in m.removes).\n public cleanupDetachedIframes() {\n if (this.attachedIframes.size === 0) return;\n const orphaned: number[] = [];\n this.attachedIframes.forEach((_entry, iframeId) => {\n if (!this.mirror.has(iframeId)) {\n orphaned.push(iframeId);\n }\n });\n orphaned.forEach((iframeId) => this.removeIframeById(iframeId));\n }\n\n public reattachIframes() {\n this.attachedIframes.forEach(({ content }, iframeId) => {\n // Verify the iframe ID is still in the mirror (still being tracked by rrweb)\n // If removed, the mirror would have been cleaned up via removeNodeFromMap()\n if (!this.mirror.has(iframeId)) {\n this.attachedIframes.delete(iframeId);\n return;\n }\n\n this.mutationCb({\n adds: [\n {\n parentId: iframeId,\n nextId: null,\n node: content,\n },\n ],\n removes: [],\n texts: [],\n attributes: [],\n isAttachIframe: true,\n });\n });\n }\n\n public destroy() {\n if (this.recordCrossOriginIframes) {\n removeEventListenerSafely(window, 'message', this.messageHandler);\n }\n\n // Clean up nested iframe listeners\n this.nestedIframeListeners.forEach((handler, contentWindow) => {\n removeEventListenerSafely(contentWindow, 'message', handler);\n });\n this.nestedIframeListeners.clear();\n\n // WeakMaps aren't iterable, so enumerate tracked iframes via the\n // id-keyed Maps and dispose pending load listeners + pagehide\n // handlers before dropping the WeakMaps. Otherwise stopRecording()\n // would leave DOM listeners + onceIframeLoaded timers live, allowing\n // a late iframe load to call wrappedEmit after recording stopped.\n const tracked = new Set<HTMLIFrameElement>();\n this.iframeElementsById.forEach((el) => tracked.add(el));\n this.attachedIframes.forEach(({ element }) => tracked.add(element));\n tracked.forEach((iframe) => {\n this.disposeLoadListeners(iframe);\n this.removePageHideListener(iframe);\n });\n\n this.crossOriginIframeMirror.reset();\n this.crossOriginIframeStyleMirror.reset();\n this.attachedIframes.clear();\n\n this.crossOriginIframeMap = new WeakMap();\n this.iframes = new WeakMap();\n this.crossOriginIframeRootIdMap = new WeakMap();\n this.loadListenerDisposers = new WeakMap();\n this.pageHideHandlers = new WeakMap();\n this.attachedDocuments = new WeakMap();\n this.attachedWindows = new WeakMap();\n this.iframeElementsById = new Map();\n }\n}\n","// Modified by ELU. See NOTICE-ELU and THIRD_PARTY_NOTICES.txt.\n\nimport { createRecorderCleanup, RecorderCleanupError } from './cleanup';\nimport type { MutationBufferParam } from '../types';\nimport type {\n mutationCallBack,\n scrollCallback,\n SamplingStrategy,\n} from '@elu-labs/recorder-types';\nimport {\n initMutationObserver,\n initScrollObserver,\n initAdoptedStyleSheetObserver,\n mutationBuffers,\n} from './observer';\nimport { inDom } from '../utils';\nimport type { Mirror } from '@elu-labs/recorder-snapshot';\nimport { isNativeShadowDom } from '@elu-labs/recorder-snapshot';\nimport dom, { patch } from '@elu-labs/recorder-utils';\n\ntype BypassOptions = Omit<\n MutationBufferParam,\n 'doc' | 'mutationCb' | 'mirror' | 'shadowDomManager'\n> & {\n sampling: SamplingStrategy;\n};\n\nexport class ShadowDomManager {\n private shadowDoms = new WeakSet<ShadowRoot>();\n private mutationCb: mutationCallBack;\n private scrollCb: scrollCallback;\n private bypassOptions: BypassOptions;\n private mirror: Mirror;\n // Handlers are tagged with the document that owns their shadow root so a\n // single iframe can be torn down without disconnecting the rest of the page.\n private generation = {};\n private documentGenerations = new WeakMap<Document, object>();\n private cleanupFailed = false;\n private restoreHandlers: { doc: Document; handler: () => void }[] = [];\n\n constructor(options: {\n mutationCb: mutationCallBack;\n scrollCb: scrollCallback;\n bypassOptions: BypassOptions;\n mirror: Mirror;\n }) {\n this.mutationCb = options.mutationCb;\n this.scrollCb = options.scrollCb;\n this.bypassOptions = options.bypassOptions;\n this.mirror = options.mirror;\n\n this.init();\n }\n\n public init() {\n this.reset();\n // Patch 'attachShadow' to observe newly added shadow doms.\n this.patchAttachShadow(Element, document);\n }\n\n public addShadowRoot(shadowRoot: ShadowRoot, doc: Document) {\n if (!isNativeShadowDom(shadowRoot)) return;\n if (this.shadowDoms.has(shadowRoot)) return;\n this.shadowDoms.add(shadowRoot);\n // Derive the owning document from the host so a shadow root nested in an\n // iframe is keyed to that iframe's document, not whatever the caller passed\n // (takeFullSnapshot's onSerialize hands us the top-level document).\n const ownerDoc = dom.host(shadowRoot)?.ownerDocument ?? doc;\n const { observer, buffer } = initMutationObserver(\n {\n ...this.bypassOptions,\n doc: ownerDoc,\n mutationCb: this.mutationCb,\n mirror: this.mirror,\n shadowDomManager: this,\n },\n shadowRoot,\n );\n this.restoreHandlers.push({\n doc: ownerDoc,\n handler: () => {\n const cleanup = createRecorderCleanup();\n cleanup.add(() => {\n const index = mutationBuffers.indexOf(buffer);\n if (index !== -1) mutationBuffers.splice(index, 1);\n });\n cleanup.add(() => buffer.destroy());\n // Release directly to avoid resetting other shadow roots.\n cleanup.add(() => buffer.releaseCanvasManager());\n cleanup.add(() => observer.disconnect());\n cleanup.close();\n },\n });\n this.restoreHandlers.push({\n doc: ownerDoc,\n handler: initScrollObserver({\n ...this.bypassOptions,\n scrollCb: this.scrollCb,\n // https://gist.github.com/praveenpuglia/0832da687ed5a5d7a0907046c9ef1813\n // scroll is not allowed to pass the boundary, so we need to listen the shadow document\n doc: shadowRoot as unknown as Document,\n mirror: this.mirror,\n }),\n });\n // Defer this to avoid adoptedStyleSheet events being created before the full snapshot is created or attachShadow action is recorded.\n const generation = this.generation;\n let documentGeneration = this.documentGenerations.get(ownerDoc);\n if (!documentGeneration) {\n documentGeneration = {};\n this.documentGenerations.set(ownerDoc, documentGeneration);\n }\n const timer = setTimeout(() => {\n if (\n generation !== this.generation ||\n documentGeneration !== this.documentGenerations.get(ownerDoc)\n )\n return;\n if (\n shadowRoot.adoptedStyleSheets &&\n shadowRoot.adoptedStyleSheets.length > 0\n )\n this.bypassOptions.stylesheetManager.adoptStyleSheets(\n shadowRoot.adoptedStyleSheets,\n this.mirror.getId(dom.host(shadowRoot)),\n );\n this.restoreHandlers.push({\n doc: ownerDoc,\n handler: initAdoptedStyleSheetObserver(\n {\n mirror: this.mirror,\n stylesheetManager: this.bypassOptions.stylesheetManager,\n },\n shadowRoot,\n ),\n });\n }, 0);\n this.restoreHandlers.push({\n doc: ownerDoc,\n handler: () => clearTimeout(timer),\n });\n }\n\n /**\n * Monkey patch 'attachShadow' of an IFrameElement to observe newly added shadow doms.\n */\n public observeAttachShadow(iframeElement: HTMLIFrameElement) {\n if (!iframeElement.contentWindow || !iframeElement.contentDocument) return;\n\n this.patchAttachShadow(\n (\n iframeElement.contentWindow as Window & {\n Element: { prototype: Element };\n }\n ).Element,\n iframeElement.contentDocument,\n );\n }\n\n /**\n * Patch 'attachShadow' to observe newly added shadow doms.\n */\n private patchAttachShadow(\n element: {\n prototype: Element;\n },\n doc: Document,\n ) {\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const manager = this;\n this.restoreHandlers.push({\n doc,\n handler: patch(\n element.prototype,\n 'attachShadow',\n function (original: (init: ShadowRootInit) => ShadowRoot) {\n return function (this: Element, option: ShadowRootInit) {\n const sRoot = original.call(this, option);\n // For the shadow dom elements in the document, monitor their dom mutations.\n // For shadow dom elements that aren't in the document yet,\n // we start monitoring them once their shadow dom host is appended to the document.\n const shadowRootEl = dom.shadowRoot(this);\n if (shadowRootEl && inDom(this))\n manager.addShadowRoot(shadowRootEl, doc);\n return sRoot;\n };\n },\n ),\n });\n }\n\n private disposeHandlers(entries: { doc: Document; handler: () => void }[]) {\n const cleanup = createRecorderCleanup();\n for (const { handler } of entries) cleanup.add(handler);\n try {\n cleanup.close();\n } catch {\n this.cleanupFailed = true;\n }\n if (this.cleanupFailed) throw new RecorderCleanupError();\n }\n\n public reset() {\n this.generation = {};\n this.documentGenerations = new WeakMap();\n const entries = this.restoreHandlers;\n this.restoreHandlers = [];\n this.shadowDoms = new WeakSet();\n this.disposeHandlers(entries);\n }\n\n // A document reset fences pending work for that document without touching its siblings.\n public resetForDoc(doc: Document) {\n this.documentGenerations.set(doc, {});\n const entries = this.restoreHandlers.filter((entry) => entry.doc === doc);\n this.restoreHandlers = this.restoreHandlers.filter(\n (entry) => entry.doc !== doc,\n );\n this.disposeHandlers(entries);\n }\n}\n","// Modified by ELU. See NOTICE-ELU and THIRD_PARTY_NOTICES.txt.\n\nimport type { CanvasMaskRegion, CanvasMasking } from '@elu-labs/recorder-types';\n\nexport const SKIP_FRAME = 'skip-frame' as const;\n\nexport type FrameMaskResult =\n | CanvasMaskRegion[]\n | typeof SKIP_FRAME\n | undefined;\n\n// regions come back in CSS pixels relative to the canvas and are scaled to\n// capture-resolution pixels here\nexport function computeFrameMaskRegions(\n masking: CanvasMasking | undefined,\n canvas: HTMLCanvasElement,\n captureWidth: number,\n captureHeight: number,\n displayWidth: number,\n displayHeight: number,\n): FrameMaskResult {\n if (!masking || typeof masking.regionsFn !== 'function') {\n return undefined;\n }\n\n let regions: CanvasMaskRegion[] | null | undefined;\n try {\n regions = masking.regionsFn(canvas);\n } catch {\n return SKIP_FRAME;\n }\n\n if (regions === undefined) {\n return undefined;\n }\n if (!Array.isArray(regions) || !regions.every(isValidRegion)) {\n return SKIP_FRAME;\n }\n\n const sx = captureWidth / displayWidth;\n const sy = captureHeight / displayHeight;\n // zero-area regions mask nothing, but outward rounding would inflate one at\n // a fractional offset into a 1px stripe — drop them before scaling\n return regions.filter((r) => r.width > 0 && r.height > 0).map((r) => {\n const left = Math.floor(r.x * sx);\n const top = Math.floor(r.y * sy);\n return {\n x: left,\n y: top,\n width: Math.ceil((r.x + r.width) * sx) - left,\n height: Math.ceil((r.y + r.height) * sy) - top,\n };\n });\n}\n\nfunction isValidRegion(r: unknown): r is CanvasMaskRegion {\n if (typeof r !== 'object' || r === null) {\n return false;\n }\n const { x, y, width, height } = r as CanvasMaskRegion;\n return (\n Number.isFinite(x) &&\n Number.isFinite(y) &&\n Number.isFinite(width) &&\n Number.isFinite(height) &&\n width >= 0 &&\n height >= 0\n );\n}\n","const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';\n\n// Use a lookup table to find the index.\nconst lookup = typeof Uint8Array === 'undefined' ? [] : new Uint8Array(256);\nfor (let i = 0; i < chars.length; i++) {\n lookup[chars.charCodeAt(i)] = i;\n}\n\nexport const encode = (arraybuffer: ArrayBuffer): string => {\n let bytes = new Uint8Array(arraybuffer),\n i,\n len = bytes.length,\n base64 = '';\n\n for (i = 0; i < len; i += 3) {\n base64 += chars[bytes[i] >> 2];\n base64 += chars[((bytes[i] & 3) << 4) | (bytes[i + 1] >> 4)];\n base64 += chars[((bytes[i + 1] & 15) << 2) | (bytes[i + 2] >> 6)];\n base64 += chars[bytes[i + 2] & 63];\n }\n\n if (len % 3 === 2) {\n base64 = base64.substring(0, base64.length - 1) + '=';\n } else if (len % 3 === 1) {\n base64 = base64.substring(0, base64.length - 2) + '==';\n }\n\n return base64;\n};\n\nexport const decode = (base64: string): ArrayBuffer => {\n let bufferLength = base64.length * 0.75,\n len = base64.length,\n i,\n p = 0,\n encoded1,\n encoded2,\n encoded3,\n encoded4;\n\n if (base64[base64.length - 1] === '=') {\n bufferLength--;\n if (base64[base64.length - 2] === '=') {\n bufferLength--;\n }\n }\n\n const arraybuffer = new ArrayBuffer(bufferLength),\n bytes = new Uint8Array(arraybuffer);\n\n for (i = 0; i < len; i += 4) {\n encoded1 = lookup[base64.charCodeAt(i)];\n encoded2 = lookup[base64.charCodeAt(i + 1)];\n encoded3 = lookup[base64.charCodeAt(i + 2)];\n encoded4 = lookup[base64.charCodeAt(i + 3)];\n\n bytes[p++] = (encoded1 << 2) | (encoded2 >> 4);\n bytes[p++] = ((encoded2 & 15) << 4) | (encoded3 >> 2);\n bytes[p++] = ((encoded3 & 3) << 6) | (encoded4 & 63);\n }\n\n return arraybuffer;\n};\n","// Modified by ELU. See NOTICE-ELU and THIRD_PARTY_NOTICES.txt.\n\nimport { encode } from 'base64-arraybuffer';\nimport type { IWindow, CanvasArg, DataURLOptions } from '@elu-labs/recorder-types';\n\n// TODO: unify with `replay/webgl.ts`\ntype CanvasVarMap = Map<string, unknown[]>;\nconst canvasVarMap: Map<RenderingContext, CanvasVarMap> = new Map();\nexport function variableListFor(ctx: RenderingContext, ctor: string) {\n let contextMap = canvasVarMap.get(ctx);\n if (!contextMap) {\n contextMap = new Map();\n canvasVarMap.set(ctx, contextMap);\n }\n if (!contextMap.has(ctor)) {\n contextMap.set(ctor, []);\n }\n return contextMap.get(ctor) as unknown[];\n}\n\nexport const saveWebGLVar = (\n value: unknown,\n win: IWindow,\n ctx: RenderingContext,\n): number | void => {\n if (\n !value ||\n !(isInstanceOfWebGLObject(value, win) || typeof value === 'object')\n )\n return;\n\n const name = value.constructor.name;\n const list = variableListFor(ctx, name);\n let index = list.indexOf(value);\n\n if (index === -1) {\n index = list.length;\n list.push(value);\n }\n return index;\n};\n\n// from webgl-recorder: https://github.com/evanw/webgl-recorder/blob/bef0e65596e981ee382126587e2dcbe0fc7748e2/webgl-recorder.js#L50-L77\nexport function serializeArg(\n value: unknown,\n win: IWindow,\n ctx: RenderingContext,\n dataURLOptions: DataURLOptions,\n): CanvasArg {\n if (value instanceof Array) {\n return value.map((arg) => serializeArg(arg, win, ctx, dataURLOptions));\n } else if (value === null) {\n return value;\n } else if (\n value instanceof Float32Array ||\n value instanceof Float64Array ||\n value instanceof Int32Array ||\n value instanceof Uint32Array ||\n value instanceof Uint8Array ||\n value instanceof Uint16Array ||\n value instanceof Int16Array ||\n value instanceof Int8Array ||\n value instanceof Uint8ClampedArray\n ) {\n const name = value.constructor.name;\n return {\n rr_type: name,\n args: [Object.values(value)],\n };\n } else if (\n // SharedArrayBuffer disabled on most browsers due to spectre.\n // More info: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer/SharedArrayBuffer\n // value instanceof SharedArrayBuffer ||\n value instanceof ArrayBuffer\n ) {\n const name = value.constructor.name as 'ArrayBuffer';\n const base64 = encode(value);\n\n return {\n rr_type: name,\n base64,\n };\n } else if (value instanceof DataView) {\n const name = value.constructor.name;\n return {\n rr_type: name,\n args: [\n serializeArg(value.buffer, win, ctx, dataURLOptions),\n value.byteOffset,\n value.byteLength,\n ],\n };\n } else if (value instanceof HTMLImageElement) {\n const name = value.constructor.name;\n const { src } = value;\n return {\n rr_type: name,\n src,\n };\n } else if (value instanceof HTMLCanvasElement) {\n const name = 'HTMLImageElement';\n // TODO: move `toDataURL` to web worker if possible\n const src = value.toDataURL(dataURLOptions.type, dataURLOptions.quality);\n return {\n rr_type: name,\n src,\n };\n } else if (value instanceof ImageData) {\n const name = value.constructor.name;\n return {\n rr_type: name,\n args: [\n serializeArg(value.data, win, ctx, dataURLOptions),\n value.width,\n value.height,\n ],\n };\n // } else if (value instanceof Blob) {\n // const name = value.constructor.name;\n // return {\n // rr_type: name,\n // data: [serializeArg(await value.arrayBuffer(), win, ctx, dataURLOptions)],\n // type: value.type,\n // };\n } else if (isInstanceOfWebGLObject(value, win) || typeof value === 'object') {\n const name = value.constructor.name;\n const index = saveWebGLVar(value, win, ctx) as number;\n\n return {\n rr_type: name,\n index: index,\n };\n }\n\n return value as unknown as CanvasArg;\n}\n\nexport const serializeArgs = (\n args: Array<unknown>,\n win: IWindow,\n ctx: RenderingContext,\n dataURLOptions: DataURLOptions,\n) => {\n return args.map((arg) => serializeArg(arg, win, ctx, dataURLOptions));\n};\n\nexport const isInstanceOfWebGLObject = (\n value: unknown,\n win: IWindow,\n): value is\n | WebGLActiveInfo\n | WebGLBuffer\n | WebGLFramebuffer\n | WebGLProgram\n | WebGLRenderbuffer\n | WebGLShader\n | WebGLShaderPrecisionFormat\n | WebGLTexture\n | WebGLUniformLocation\n | WebGLVertexArrayObject => {\n const webGLConstructorNames: string[] = [\n 'WebGLActiveInfo',\n 'WebGLBuffer',\n 'WebGLFramebuffer',\n 'WebGLProgram',\n 'WebGLRenderbuffer',\n 'WebGLShader',\n 'WebGLShaderPrecisionFormat',\n 'WebGLTexture',\n 'WebGLUniformLocation',\n 'WebGLVertexArrayObject',\n // In old Chrome versions, value won't be an instanceof WebGLVertexArrayObject.\n 'WebGLVertexArrayObjectOES',\n ];\n const supportedWebGLConstructorNames = webGLConstructorNames.filter(\n (name: string) => typeof win[name as keyof Window] === 'function',\n );\n return Boolean(\n supportedWebGLConstructorNames.find(\n (name: string) => value instanceof win[name as keyof Window],\n ),\n );\n};\n","// Modified by ELU. See NOTICE-ELU and THIRD_PARTY_NOTICES.txt.\n\nimport type { ICanvas } from '@elu-labs/recorder-snapshot';\nimport type {\n blockClass,\n IWindow,\n listenerHandler,\n} from '@elu-labs/recorder-types';\nimport { isBlocked } from '../../../utils';\nimport { patch } from '@elu-labs/recorder-utils';\n\nconst WEBGL_CONTEXT_NAMES = ['webgl', 'webgl2'];\n\ntype GPUCanvasConfigurationLike = {\n usage?: number;\n};\n\ntype GPUTextureUsageLike = {\n COPY_SRC: number;\n RENDER_ATTACHMENT: number;\n};\n\ntype WebGPUCanvasLike = {\n nodeType?: number;\n __context?: string;\n};\n\ntype WebGPUCanvasContextLike = {\n canvas?: unknown;\n configure?: (configuration: GPUCanvasConfigurationLike) => void;\n};\n\nfunction getNormalizedContextName(contextType: string) {\n return contextType === 'experimental-webgl' ? 'webgl' : contextType;\n}\n\nfunction getRequiredWebGPUTextureUsage(win: IWindow) {\n const textureUsage = (\n win as IWindow & { GPUTextureUsage?: GPUTextureUsageLike }\n ).GPUTextureUsage;\n\n if (!textureUsage) {\n return null;\n }\n\n return textureUsage.COPY_SRC | textureUsage.RENDER_ATTACHMENT;\n}\n\nfunction getCanvasFromWebGPUContext(\n context: WebGPUCanvasContextLike,\n): WebGPUCanvasLike | null {\n const { canvas } = context;\n\n if (!canvas || typeof canvas !== 'object') {\n return null;\n }\n\n return canvas as WebGPUCanvasLike;\n}\n\nfunction isCanvasNode(\n canvas: WebGPUCanvasLike,\n): canvas is ICanvas | HTMLCanvasElement {\n return 'nodeType' in canvas;\n}\n\nfunction initCanvasWebGPUContextObserver(\n win: IWindow,\n blockClass: blockClass,\n blockSelector: string | null,\n): listenerHandler | undefined {\n const GPUCanvasContext = (\n win as IWindow & {\n GPUCanvasContext?: {\n prototype?: WebGPUCanvasContextLike;\n };\n }\n ).GPUCanvasContext;\n\n if (\n !GPUCanvasContext?.prototype ||\n typeof GPUCanvasContext.prototype.configure !== 'function'\n ) {\n return;\n }\n\n return patch(\n GPUCanvasContext.prototype,\n 'configure',\n function (\n original: (\n this: WebGPUCanvasContextLike,\n configuration: GPUCanvasConfigurationLike,\n ) => void,\n ) {\n return function (\n this: WebGPUCanvasContextLike,\n configuration: GPUCanvasConfigurationLike,\n ) {\n const canvas = getCanvasFromWebGPUContext(this);\n\n if (\n !canvas ||\n (isCanvasNode(canvas) &&\n isBlocked(canvas, blockClass, blockSelector, true))\n ) {\n return original.call(this, configuration);\n }\n\n if (isCanvasNode(canvas) && !('__context' in canvas)) {\n (canvas as ICanvas).__context = 'webgpu';\n }\n\n const requiredUsage = getRequiredWebGPUTextureUsage(win);\n if (requiredUsage === null || !configuration) {\n return original.call(this, configuration);\n }\n\n return original.call(this, {\n ...configuration,\n // WebGPU does not implicitly keep RENDER_ATTACHMENT when usage is set,\n // so include both flags needed for drawing and snapshot reads.\n usage:\n typeof configuration.usage === 'number'\n ? configuration.usage | requiredUsage\n : requiredUsage,\n });\n };\n },\n );\n}\n\nexport default function initCanvasContextObserver(\n win: IWindow,\n blockClass: blockClass,\n blockSelector: string | null,\n setPreserveDrawingBufferToTrue: boolean,\n): listenerHandler {\n const handlers: listenerHandler[] = [];\n try {\n if (setPreserveDrawingBufferToTrue) {\n const restoreWebGPUConfigureHandler = initCanvasWebGPUContextObserver(\n win,\n blockClass,\n blockSelector,\n );\n if (restoreWebGPUConfigureHandler) {\n handlers.push(restoreWebGPUConfigureHandler);\n }\n }\n\n const restoreHandler = patch(\n win.HTMLCanvasElement.prototype,\n 'getContext',\n function (\n original: (\n this: ICanvas | HTMLCanvasElement,\n contextType: string,\n ...args: Array<unknown>\n ) => void,\n ) {\n return function (\n this: ICanvas | HTMLCanvasElement,\n contextType: string,\n ...args: Array<unknown>\n ) {\n const ctxName = getNormalizedContextName(contextType);\n if (!isBlocked(this, blockClass, blockSelector, true)) {\n if (!('__context' in this)) (this as ICanvas).__context = ctxName;\n\n if (\n setPreserveDrawingBufferToTrue &&\n WEBGL_CONTEXT_NAMES.includes(ctxName)\n ) {\n if (args[0] && typeof args[0] === 'object') {\n const contextAttributes = args[0] as WebGLContextAttributes;\n if (!contextAttributes.preserveDrawingBuffer) {\n contextAttributes.preserveDrawingBuffer = true;\n }\n } else {\n args.splice(0, 1, {\n preserveDrawingBuffer: true,\n });\n }\n }\n }\n\n return original.apply(this, [contextType, ...args]);\n };\n },\n );\n handlers.push(restoreHandler);\n } catch {\n console.error('failed to patch HTMLCanvasElement.prototype.getContext');\n }\n return () => {\n handlers.forEach((h) => h());\n };\n}\n","// Modified by ELU. See NOTICE-ELU and THIRD_PARTY_NOTICES.txt.\n\nimport {\n type blockClass,\n CanvasContext,\n type canvasManagerMutationCallback,\n type canvasMutationWithType,\n type IWindow,\n type listenerHandler,\n type DataURLOptions,\n} from '@elu-labs/recorder-types';\nimport { hookSetter, isBlocked } from '../../../utils';\nimport { patch } from '@elu-labs/recorder-utils';\nimport { saveWebGLVar, serializeArgs } from './serialize-args';\n\nfunction patchGLPrototype(\n prototype: WebGLRenderingContext | WebGL2RenderingContext,\n type: CanvasContext,\n cb: canvasManagerMutationCallback,\n blockClass: blockClass,\n blockSelector: string | null,\n win: IWindow,\n dataURLOptions: DataURLOptions,\n): listenerHandler[] {\n const handlers: listenerHandler[] = [];\n\n const props = Object.getOwnPropertyNames(prototype);\n\n for (const prop of props) {\n if (\n //prop.startsWith('get') || // e.g. getProgramParameter, but too risky\n [\n 'isContextLost',\n 'canvas',\n 'drawingBufferWidth',\n 'drawingBufferHeight',\n ].includes(prop)\n ) {\n // skip read only propery/functions\n continue;\n }\n try {\n if (typeof prototype[prop as keyof typeof prototype] !== 'function') {\n continue;\n }\n const restoreHandler = patch(\n prototype,\n prop,\n function (\n original: (this: typeof prototype, ...args: Array<unknown>) => void,\n ) {\n return function (this: typeof prototype, ...args: Array<unknown>) {\n const result = original.apply(this, args);\n saveWebGLVar(result, win, this);\n if (\n 'tagName' in this.canvas &&\n !isBlocked(this.canvas, blockClass, blockSelector, true)\n ) {\n const recordArgs = serializeArgs(args, win, this, dataURLOptions);\n const mutation: canvasMutationWithType = {\n type,\n property: prop,\n args: recordArgs,\n };\n // TODO: this could potentially also be an OffscreenCanvas as well as HTMLCanvasElement\n cb(this.canvas, mutation);\n }\n\n return result;\n };\n },\n );\n handlers.push(restoreHandler);\n } catch {\n const hookHandler = hookSetter<typeof prototype>(prototype, prop, {\n set(v) {\n // TODO: this could potentially also be an OffscreenCanvas as well as HTMLCanvasElement\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n cb(this.canvas as HTMLCanvasElement, {\n type,\n property: prop,\n args: [v],\n setter: true,\n });\n },\n });\n handlers.push(hookHandler);\n }\n }\n\n return handlers;\n}\n\nexport default function initCanvasWebGLMutationObserver(\n cb: canvasManagerMutationCallback,\n win: IWindow,\n blockClass: blockClass,\n blockSelector: string | null,\n dataURLOptions: DataURLOptions,\n): listenerHandler {\n const handlers: listenerHandler[] = [];\n\n if (typeof win.WebGLRenderingContext !== 'undefined') {\n handlers.push(\n ...patchGLPrototype(\n win.WebGLRenderingContext.prototype,\n CanvasContext.WebGL,\n cb,\n blockClass,\n blockSelector,\n win,\n dataURLOptions,\n ),\n );\n }\n\n if (typeof win.WebGL2RenderingContext !== 'undefined') {\n handlers.push(\n ...patchGLPrototype(\n win.WebGL2RenderingContext.prototype,\n CanvasContext.WebGL2,\n cb,\n blockClass,\n blockSelector,\n win,\n dataURLOptions,\n ),\n );\n }\n\n return () => {\n handlers.forEach((h) => h());\n };\n}\n","// Modified by ELU. See NOTICE-ELU and THIRD_PARTY_NOTICES.txt.\n\nimport { createRecorderCleanup, isRecorderCleanupError } from './cleanup';\nimport {\n snapshot,\n resetStylesheetLoadTracking,\n type MaskInputOptions,\n slimDOMDefaults,\n createMirror,\n} from '@elu-labs/recorder-snapshot';\nimport {\n initObservers,\n mutationBuffers,\n findAndRemoveIframeBuffer,\n} from './observer';\nimport {\n on,\n getWindowWidth,\n getWindowHeight,\n getWindowScroll,\n polyfill,\n hasShadowRoot,\n isSerializedIframe,\n isSerializedStylesheet,\n nowTimestamp,\n} from '../utils';\nimport type { recordOptions } from '../types';\nimport {\n EventType,\n type eventWithoutTime,\n type eventWithTime,\n FullscreenCustomEventTag,\n type fullscreenEventPayload,\n IncrementalSource,\n type listenerHandler,\n type mutationCallbackParam,\n type scrollCallback,\n type canvasMutationParam,\n type adoptedStyleSheetParam,\n} from '@elu-labs/recorder-types';\nimport type { CrossOriginIframeMessageEventContent } from '../types';\nimport { IframeManager } from './iframe-manager';\nimport { ShadowDomManager } from './shadow-dom-manager';\nimport { CanvasManager } from './observers/canvas/canvas-manager';\nimport { StylesheetManager } from './stylesheet-manager';\nimport ProcessedNodeManager from './processed-node-manager';\nimport {\n registerErrorHandler,\n unregisterErrorHandler,\n} from './error-handler';\nimport dom from '@elu-labs/recorder-utils';\n\nlet wrappedEmit!: (e: eventWithoutTime, isCheckout?: boolean) => void;\n\nlet takeFullSnapshot!: (isCheckout?: boolean) => void;\nlet canvasManager!: CanvasManager;\nlet recording = false;\n\n// Multiple tools (i.e. MooTools, Prototype.js) override Array.from and drop support for the 2nd parameter\n// Try to pull a clean implementation from a newly created iframe\ntry {\n if (Array.from([1], (x) => x * 2)[0] !== 2) {\n const cleanFrame = document.createElement('iframe');\n document.body.appendChild(cleanFrame);\n // eslint-disable-next-line @typescript-eslint/unbound-method -- Array.from is static and doesn't rely on binding\n Array.from = cleanFrame.contentWindow?.Array.from || Array.from;\n document.body.removeChild(cleanFrame);\n }\n} catch (err) {\n console.debug('Unable to override Array.from', err);\n}\n\nconst mirror = createMirror();\n\n// incremental sources which fire without user interaction (e.g. a looping\n// background video, a JS animation) and so must not unfreeze a frozen page\n// (upstream rrweb #1697). Hoisted so the check does not allocate per event.\nconst nonUserInitiatedSources = new Set<IncrementalSource>([\n IncrementalSource.Mutation,\n IncrementalSource.MediaInteraction, // often automatic e.g. background video loop\n IncrementalSource.StyleSheetRule,\n IncrementalSource.CanvasMutation,\n IncrementalSource.Font,\n IncrementalSource.Log,\n IncrementalSource.StyleDeclaration,\n IncrementalSource.AdoptedStyleSheet,\n]);\nfunction record<T = eventWithTime>(\n options: recordOptions<T> = {},\n): listenerHandler | undefined {\n const {\n emit,\n checkoutEveryNms,\n checkoutEveryNth,\n blockClass = 'rr-block',\n blockSelector = null,\n ignoreClass = 'rr-ignore',\n ignoreSelector = null,\n maskTextClass = 'rr-mask',\n maskTextSelector = null,\n inlineStylesheet = true,\n maskAllInputs,\n maskInputOptions: _maskInputOptions,\n slimDOMOptions: _slimDOMOptions,\n maskInputFn,\n maskTextFn,\n hooks,\n packFn,\n sampling = {},\n dataURLOptions: _dataURLOptions = {},\n canvasResolutionScale,\n canvasMasking,\n mousemoveWait,\n recordDOM = true,\n recordCanvas = false,\n recordCrossOriginIframes = false,\n recordAfter = options.recordAfter === 'DOMContentLoaded'\n ? options.recordAfter\n : 'load',\n userTriggeredOnInput = false,\n collectFonts = false,\n inlineImages = false,\n plugins,\n keepIframeSrcFn = () => false,\n ignoreCSSAttributes = new Set([]),\n attributeFilter,\n errorHandler,\n } = options;\n\n const dataURLOptions = {\n type: 'image/webp',\n quality: 0.4,\n maxBase64ImageLength: 1048576,\n ..._dataURLOptions,\n };\n\n const inEmittingFrame = recordCrossOriginIframes\n ? window.parent === window\n : true;\n\n let passEmitsToParent = false;\n if (!inEmittingFrame) {\n try {\n // throws if parent is cross-origin\n if (window.parent.document) {\n passEmitsToParent = false; // if parent is same origin we collect iframe events from the parent\n }\n } catch (e) {\n passEmitsToParent = true;\n }\n }\n\n // runtime checks for user options\n if (inEmittingFrame && !emit) {\n throw new Error('emit function is required');\n }\n if (!inEmittingFrame && !passEmitsToParent) {\n return () => {\n /* no-op since in this case we don't need to record anything from this frame in particular */\n };\n }\n // move departed options to new options\n if (mousemoveWait !== undefined && sampling.mousemove === undefined) {\n sampling.mousemove = mousemoveWait;\n }\n\n const cleanup = createRecorderCleanup();\n let closed = false;\n const handlers: listenerHandler[] = [];\n const dispose = () => {\n closed = true;\n recording = false;\n cleanup.close();\n };\n // Handle acquisitions after synchronous emit callbacks requested stop.\n const own = (handler: listenerHandler) => {\n if (closed) cleanup.add(handler);\n else handlers.push(handler);\n };\n const failed = (error: unknown) => {\n if (isRecorderCleanupError(error)) cleanup.poison();\n dispose();\n if (errorHandler) errorHandler(error);\n else console.warn(error);\n };\n try {\n registerErrorHandler(errorHandler);\n cleanup.add(unregisterErrorHandler);\n cleanup.add(() => mirror.reset());\n cleanup.add(resetStylesheetLoadTracking);\n // reset mirror in case `record` this was called earlier\n mirror.reset();\n\n const maskInputOptions: MaskInputOptions =\n maskAllInputs === true\n ? {\n color: true,\n date: true,\n 'datetime-local': true,\n email: true,\n month: true,\n number: true,\n range: true,\n search: true,\n tel: true,\n text: true,\n time: true,\n url: true,\n week: true,\n textarea: true,\n select: true,\n password: true,\n }\n : _maskInputOptions !== undefined\n ? _maskInputOptions\n : { password: true };\n\n const slimDOMOptions = slimDOMDefaults(\n _slimDOMOptions !== undefined ? _slimDOMOptions : false,\n );\n\n polyfill();\n\n let lastFullSnapshotEvent: eventWithTime;\n let incrementalSnapshotCount = 0;\n // Set per id — one iframe id can collect several cleanups across loads.\n const iframeObserverCleanups = new Map<number, Set<listenerHandler>>();\n\n // Forward-declared; assigned inside the try{} block where `handlers` is\n // in scope. Optional-typed so a premature call is a no-op rather than a\n // silently-swallowed cleanup — the try-block runs synchronously after the\n // managers are constructed, but the types make that invariant explicit.\n let runAndDetachIframeCleanup: ((iframeId: number) => void) | undefined;\n let cleanupDetachedIframeObservers: (() => void) | undefined;\n\n const eventProcessor = (e: eventWithTime): T => {\n for (const plugin of plugins || []) {\n if (plugin.eventProcessor) {\n e = plugin.eventProcessor(e);\n }\n }\n if (\n packFn &&\n // Disable packing events which will be emitted to parent frames.\n !passEmitsToParent\n ) {\n e = packFn(e) as unknown as eventWithTime;\n }\n return e as unknown as T;\n };\n const emitForRecording = (r: eventWithoutTime, isCheckout?: boolean) => {\n if (closed) return;\n const e = r as eventWithTime;\n e.timestamp = nowTimestamp();\n if (\n mutationBuffers[0]?.isFrozen() &&\n e.type !== EventType.FullSnapshot &&\n !(\n e.type === EventType.IncrementalSnapshot &&\n nonUserInitiatedSources.has(e.data.source)\n )\n ) {\n // we've got a user initiated event so first we need to apply\n // all DOM changes that have been buffering during paused state\n mutationBuffers.forEach((buf) => buf.unfreeze());\n }\n\n if (inEmittingFrame) {\n emit?.(eventProcessor(e), isCheckout);\n } else if (passEmitsToParent) {\n const message: CrossOriginIframeMessageEventContent<T> = {\n type: 'rrweb',\n event: eventProcessor(e),\n origin: window.location.origin,\n isCheckout,\n };\n window.parent.postMessage(message, '*');\n }\n\n if (e.type === EventType.FullSnapshot) {\n lastFullSnapshotEvent = e;\n incrementalSnapshotCount = 0;\n } else if (e.type === EventType.IncrementalSnapshot) {\n // attach iframe should be considered as full snapshot\n if (\n e.data.source === IncrementalSource.Mutation &&\n e.data.isAttachIframe\n ) {\n return;\n }\n\n incrementalSnapshotCount++;\n const exceedCount =\n checkoutEveryNth && incrementalSnapshotCount >= checkoutEveryNth;\n const exceedTime =\n checkoutEveryNms &&\n e.timestamp - lastFullSnapshotEvent.timestamp > checkoutEveryNms;\n if (exceedCount || exceedTime) {\n snapshotForRecording(true);\n }\n }\n };\n wrappedEmit = emitForRecording;\n\n const wrappedMutationEmit = (m: mutationCallbackParam) => {\n // Clean up removed iframes (same-origin too). Detect reparenting by id\n // AND by element identity — MutationBuffer.emit clears mirror entries\n // before re-serializing adds, so a moved iframe may have a fresh id.\n if (m.removes && m.removes.length > 0) {\n const addedIds =\n m.adds.length > 0 ? new Set(m.adds.map((add) => add.node.id)) : null;\n const addedIframeElements = new Set<HTMLIFrameElement>();\n if (m.adds.length > 0) {\n for (const add of m.adds) {\n const node = mirror.getNode(add.node.id);\n if (node && (node as Element).nodeName === 'IFRAME') {\n addedIframeElements.add(node as HTMLIFrameElement);\n }\n }\n }\n\n m.removes.forEach(({ id }) => {\n if (addedIds && addedIds.has(id)) return;\n const removedIframe = iframeManager.getIframeElementById(id);\n if (removedIframe && addedIframeElements.has(removedIframe)) {\n // Reparent: keep observers/listeners; just drop stale id mapping.\n iframeManager.forgetIframeId(id);\n return;\n }\n runAndDetachIframeCleanup?.(id);\n iframeManager.removeIframeById(id);\n });\n\n // Catch iframes removed inside a removed subtree (only the ancestor's\n // id appears in m.removes). Disconnect observers before iframeManager\n // releases the buffers, matching the order of the direct-remove path\n // above so a queued mutation can't land on a freed buffer.\n cleanupDetachedIframeObservers?.();\n iframeManager.cleanupDetachedIframes();\n }\n\n emitForRecording({\n type: EventType.IncrementalSnapshot,\n data: {\n source: IncrementalSource.Mutation,\n ...m,\n },\n });\n };\n const wrappedScrollEmit: scrollCallback = (p) =>\n emitForRecording({\n type: EventType.IncrementalSnapshot,\n data: {\n source: IncrementalSource.Scroll,\n ...p,\n },\n });\n const wrappedCanvasMutationEmit = (p: canvasMutationParam) =>\n emitForRecording({\n type: EventType.IncrementalSnapshot,\n data: {\n source: IncrementalSource.CanvasMutation,\n ...p,\n },\n });\n\n const wrappedAdoptedStyleSheetEmit = (a: adoptedStyleSheetParam) =>\n emitForRecording({\n type: EventType.IncrementalSnapshot,\n data: {\n source: IncrementalSource.AdoptedStyleSheet,\n ...a,\n },\n });\n\n const stylesheetManager = new StylesheetManager({\n mutationCb: wrappedMutationEmit,\n adoptedStyleSheetCb: wrappedAdoptedStyleSheetEmit,\n });\n\n cleanup.add(() => stylesheetManager.reset());\n\n const iframeManager = new IframeManager({\n mirror,\n mutationCb: wrappedMutationEmit,\n stylesheetManager: stylesheetManager,\n recordCrossOriginIframes,\n wrappedEmit: emitForRecording,\n });\n\n cleanup.add(() => iframeManager.destroy());\n\n /**\n * Exposes mirror to the plugins\n */\n for (const plugin of plugins || []) {\n if (plugin.getMirror)\n plugin.getMirror({\n nodeMirror: mirror,\n crossOriginIframeMirror: iframeManager.crossOriginIframeMirror,\n crossOriginIframeStyleMirror:\n iframeManager.crossOriginIframeStyleMirror,\n });\n }\n\n const processedNodeManager = new ProcessedNodeManager();\n\n cleanup.add(() => processedNodeManager.destroy());\n\n const canvasMaskingConfigured = canvasMasking?.configured;\n\n canvasManager = new CanvasManager({\n recordCanvas,\n mutationCb: wrappedCanvasMutationEmit,\n win: window,\n blockClass,\n blockSelector,\n mirror,\n sampling: sampling.canvas,\n dataURLOptions,\n resolutionScale: canvasResolutionScale,\n canvasMasking,\n });\n\n cleanup.add(() => canvasManager.reset());\n\n const shadowDomManager = new ShadowDomManager({\n mutationCb: wrappedMutationEmit,\n scrollCb: wrappedScrollEmit,\n bypassOptions: {\n blockClass,\n blockSelector,\n maskTextClass,\n maskTextSelector,\n inlineStylesheet,\n maskInputOptions,\n dataURLOptions,\n maskTextFn,\n maskInputFn,\n recordCanvas,\n canvasMaskingConfigured,\n inlineImages,\n sampling,\n slimDOMOptions,\n iframeManager,\n stylesheetManager,\n canvasManager,\n keepIframeSrcFn,\n processedNodeManager,\n attributeFilter,\n },\n mirror,\n });\n\n cleanup.add(() => shadowDomManager.reset());\n\n const snapshotForRecording = (isCheckout = false) => {\n if (closed) return;\n if (!recordDOM) {\n return;\n }\n emitForRecording(\n {\n type: EventType.Meta,\n data: {\n href: window.location.href,\n width: getWindowWidth(),\n height: getWindowHeight(),\n },\n },\n isCheckout,\n );\n\n // When we take a full snapshot, old tracked StyleSheets need to be removed.\n stylesheetManager.reset();\n\n shadowDomManager.init();\n\n mutationBuffers.forEach((buf) => buf.lock()); // don't allow any mirror modifications during snapshotting\n const node = snapshot(document, {\n mirror,\n blockClass,\n blockSelector,\n maskTextClass,\n maskTextSelector,\n inlineStylesheet,\n maskAllInputs: maskInputOptions,\n maskTextFn,\n maskInputFn,\n slimDOM: slimDOMOptions,\n dataURLOptions,\n recordCanvas,\n canvasMaskingConfigured,\n inlineImages,\n onSerialize: (n) => {\n if (isSerializedIframe(n, mirror)) {\n iframeManager.addIframe(n as HTMLIFrameElement);\n }\n if (isSerializedStylesheet(n, mirror)) {\n stylesheetManager.trackLinkElement(n as HTMLLinkElement);\n }\n if (hasShadowRoot(n)) {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n shadowDomManager.addShadowRoot(\n dom.shadowRoot(n as Node)!,\n document,\n );\n }\n },\n onIframeLoad: (iframe, childSn) => {\n iframeManager.attachIframe(iframe, childSn);\n shadowDomManager.observeAttachShadow(iframe);\n },\n onIframeListenerRegistered: (\n iframe: HTMLIFrameElement,\n disposer: () => void,\n ) => {\n iframeManager.registerLoadListenerDisposer(iframe, disposer);\n },\n onStylesheetLoad: (linkEl, childSn) => {\n stylesheetManager.attachLinkElement(linkEl, childSn);\n },\n keepIframeSrcFn,\n });\n\n if (!node) {\n return console.warn('Failed to snapshot the document');\n }\n\n emitForRecording(\n {\n type: EventType.FullSnapshot,\n data: {\n node,\n initialOffset: getWindowScroll(window),\n },\n },\n isCheckout,\n );\n mutationBuffers.forEach((buf) => buf.unlock()); // generate & emit any mutations that happened during snapshotting, as can now apply against the newly built mirror\n canvasManager.onFullSnapshot();\n\n if (recordCrossOriginIframes) {\n iframeManager.reattachIframes();\n }\n\n // Some old browsers don't support adoptedStyleSheets.\n if (document.adoptedStyleSheets && document.adoptedStyleSheets.length > 0)\n stylesheetManager.adoptStyleSheets(\n document.adoptedStyleSheets,\n mirror.getId(document),\n );\n };\n\n takeFullSnapshot = snapshotForRecording;\n cleanup.add(() => iframeObserverCleanups.clear());\n cleanup.add(() => {\n const acquired = createRecorderCleanup();\n for (const handler of handlers) acquired.add(handler);\n handlers.length = 0;\n acquired.close();\n });\n\n // Disposes per-iframe observer cleanups and unlinks them from `handlers`.\n runAndDetachIframeCleanup = (iframeId: number) => {\n const cleanups = iframeObserverCleanups.get(iframeId);\n if (!cleanups) return;\n const detached = createRecorderCleanup();\n cleanups.forEach((cleanup) => {\n detached.add(cleanup);\n const idx = handlers.indexOf(cleanup);\n if (idx !== -1) handlers.splice(idx, 1);\n });\n iframeObserverCleanups.delete(iframeId);\n detached.close();\n };\n\n cleanupDetachedIframeObservers = () => {\n for (const [iframeId] of iframeObserverCleanups) {\n const iframe = mirror.getNode(iframeId) as HTMLIFrameElement | null;\n if (!iframe) {\n runAndDetachIframeCleanup?.(iframeId);\n continue;\n }\n try {\n if (!iframe.contentDocument || !iframe.contentDocument.defaultView) {\n runAndDetachIframeCleanup?.(iframeId);\n }\n } catch {\n runAndDetachIframeCleanup?.(iframeId);\n }\n }\n };\n\n const observe = (doc: Document) => {\n return initObservers(\n {\n mutationCb: wrappedMutationEmit,\n mousemoveCb: (positions, source) =>\n emitForRecording({\n type: EventType.IncrementalSnapshot,\n data: {\n source,\n positions,\n },\n }),\n mouseInteractionCb: (d) =>\n emitForRecording({\n type: EventType.IncrementalSnapshot,\n data: {\n source: IncrementalSource.MouseInteraction,\n ...d,\n },\n }),\n scrollCb: wrappedScrollEmit,\n viewportResizeCb: (d) =>\n emitForRecording({\n type: EventType.IncrementalSnapshot,\n data: {\n source: IncrementalSource.ViewportResize,\n ...d,\n },\n }),\n inputCb: (v) =>\n emitForRecording({\n type: EventType.IncrementalSnapshot,\n data: {\n source: IncrementalSource.Input,\n ...v,\n },\n }),\n mediaInteractionCb: (p) =>\n emitForRecording({\n type: EventType.IncrementalSnapshot,\n data: {\n source: IncrementalSource.MediaInteraction,\n ...p,\n },\n }),\n styleSheetRuleCb: (r) =>\n emitForRecording({\n type: EventType.IncrementalSnapshot,\n data: {\n source: IncrementalSource.StyleSheetRule,\n ...r,\n },\n }),\n styleDeclarationCb: (r) =>\n emitForRecording({\n type: EventType.IncrementalSnapshot,\n data: {\n source: IncrementalSource.StyleDeclaration,\n ...r,\n },\n }),\n canvasMutationCb: wrappedCanvasMutationEmit,\n fontCb: (p) =>\n emitForRecording({\n type: EventType.IncrementalSnapshot,\n data: {\n source: IncrementalSource.Font,\n ...p,\n },\n }),\n selectionCb: (p) => {\n emitForRecording({\n type: EventType.IncrementalSnapshot,\n data: {\n source: IncrementalSource.Selection,\n ...p,\n },\n });\n },\n customElementCb: (c) => {\n emitForRecording({\n type: EventType.IncrementalSnapshot,\n data: {\n source: IncrementalSource.CustomElement,\n ...c,\n },\n });\n },\n blockClass,\n ignoreClass,\n ignoreSelector,\n maskTextClass,\n maskTextSelector,\n maskInputOptions,\n inlineStylesheet,\n sampling,\n recordDOM,\n recordCanvas,\n canvasMaskingConfigured,\n inlineImages,\n userTriggeredOnInput,\n collectFonts,\n doc,\n maskInputFn,\n maskTextFn,\n keepIframeSrcFn,\n blockSelector,\n slimDOMOptions,\n dataURLOptions,\n mirror,\n iframeManager,\n stylesheetManager,\n shadowDomManager,\n processedNodeManager,\n canvasManager,\n ignoreCSSAttributes,\n attributeFilter,\n plugins:\n plugins\n ?.filter((p) => p.observer)\n ?.map((p) => ({\n observer: p.observer!,\n options: p.options,\n callback: (payload: object) =>\n emitForRecording({\n type: EventType.Plugin,\n data: {\n plugin: p.name,\n payload,\n },\n }),\n })) || [],\n },\n hooks,\n );\n };\n\n const loadListener = (iframeEl: HTMLIFrameElement) => {\n if (closed) return;\n try {\n const iframeId = mirror.getId(iframeEl);\n const cleanup = observe(iframeEl.contentDocument!);\n own(cleanup);\n // Accumulate cleanups across iframe navigations.\n if (iframeId !== -1) {\n let bucket = iframeObserverCleanups.get(iframeId);\n if (!bucket) {\n bucket = new Set();\n iframeObserverCleanups.set(iframeId, bucket);\n }\n bucket.add(cleanup);\n }\n } catch (error) {\n failed(error);\n }\n };\n iframeManager.addLoadListener(loadListener);\n\n iframeManager.addPageHideListener((iframeEl) => {\n const iframeId = mirror.getId(iframeEl);\n runAndDetachIframeCleanup?.(iframeId);\n findAndRemoveIframeBuffer(iframeEl);\n });\n\n // Native fullscreen produces no DOM mutation (the browser styles the element\n // via the UA `:fullscreen` pseudo-class), so we record the transition as a\n // custom event the replayer can act on. We track the last id because on exit\n // `fullscreenElement` is already null.\n let lastFullscreenId = -1;\n const emitFullscreen = (payload: fullscreenEventPayload) =>\n emitForRecording({\n type: EventType.Custom,\n data: { tag: FullscreenCustomEventTag, payload },\n });\n const emitFullscreenChange = () => {\n const doc = document as Document & {\n webkitFullscreenElement?: Element | null;\n mozFullScreenElement?: Element | null;\n msFullscreenElement?: Element | null;\n };\n const fullscreenEl =\n doc.fullscreenElement ??\n doc.webkitFullscreenElement ??\n doc.mozFullScreenElement ??\n doc.msFullscreenElement ??\n null;\n // -1 covers both \"no element is fullscreen\" and \"fullscreen element is\n // blocked/ignored\" (not in the mirror); both clear any prior fullscreen.\n const id = fullscreenEl ? mirror.getId(fullscreenEl) : -1;\n if (id === lastFullscreenId) return; // no change\n // Exit the previous element first. The browser can switch fullscreen\n // directly from one element to another without passing through null, so\n // this also fires on a direct switch — not just on a plain exit.\n if (lastFullscreenId !== -1) {\n emitFullscreen({ id: lastFullscreenId, enter: false });\n }\n lastFullscreenId = id;\n if (id !== -1) {\n emitFullscreen({ id, enter: true });\n }\n };\n\n let initialized = false;\n const init = () => {\n if (closed || initialized) return;\n initialized = true;\n snapshotForRecording();\n if (closed) return;\n own(observe(document));\n own(on('fullscreenchange', emitFullscreenChange));\n own(on('webkitfullscreenchange', emitFullscreenChange));\n own(on('mozfullscreenchange', emitFullscreenChange));\n own(on('MSFullscreenChange', emitFullscreenChange));\n recording = true;\n };\n if (['interactive', 'complete'].includes(document.readyState)) {\n init();\n } else {\n own(\n on('DOMContentLoaded', () => {\n if (closed) return;\n try {\n emitForRecording({\n type: EventType.DomContentLoaded,\n data: {},\n });\n if (recordAfter === 'DOMContentLoaded') init();\n } catch (error) {\n failed(error);\n }\n }),\n );\n own(\n on(\n 'load',\n () => {\n if (closed) return;\n try {\n emitForRecording({\n type: EventType.Load,\n data: {},\n });\n if (recordAfter === 'load') init();\n } catch (error) {\n failed(error);\n }\n },\n window,\n ),\n );\n }\n return dispose;\n } catch (error) {\n failed(error);\n }\n}\n\nrecord.addCustomEvent = <T>(tag: string, payload: T) => {\n if (!recording) {\n throw new Error('please add custom event after start recording');\n }\n wrappedEmit({\n type: EventType.Custom,\n data: {\n tag,\n payload,\n },\n });\n};\n\nrecord.freezePage = () => {\n mutationBuffers.forEach((buf) => buf.freeze());\n};\n\nrecord.takeFullSnapshot = (isCheckout?: boolean) => {\n if (!recording) {\n throw new Error('please take full snapshot after start recording');\n }\n takeFullSnapshot(isCheckout);\n};\n\nrecord.mirror = mirror;\n\nexport default record;\n","// Modified by ELU. See NOTICE-ELU and THIRD_PARTY_NOTICES.txt.\n\nimport type { ICanvas, Mirror } from '@elu-labs/recorder-snapshot';\nimport type {\n blockClass,\n canvasManagerMutationCallback,\n canvasMutationCallback,\n canvasMutationCommand,\n canvasMutationWithType,\n IWindow,\n listenerHandler,\n CanvasArg,\n CanvasMasking,\n DataURLOptions,\n} from '@elu-labs/recorder-types';\nimport { isBlocked } from '../../../utils';\nimport { CanvasContext } from '@elu-labs/recorder-types';\nimport { computeFrameMaskRegions, SKIP_FRAME } from './canvas-mask';\nimport initCanvas2DMutationObserver from './2d';\nimport initCanvasContextObserver from './canvas';\nimport initCanvasWebGLMutationObserver from './webgl';\nimport ImageBitmapDataURLWorker from '../../workers/image-bitmap-data-url-worker?worker&inline';\nimport type { ImageBitmapDataURLRequestWorker } from '../../workers/image-bitmap-data-url-worker';\n\nexport type RafStamps = { latestId: number; invokeId: number | null };\n\ntype pendingCanvasMutationsMap = Map<\n HTMLCanvasElement,\n canvasMutationWithType[]\n>;\n\n// Lower bound for resolutionScale, so a misconfiguration cannot capture at a\n// degenerate resolution, even when the caller does not clamp the option.\nconst MIN_CANVAS_RESOLUTION_SCALE = 0.1;\n\nexport class CanvasManager {\n private pendingCanvasMutations: pendingCanvasMutationsMap = new Map();\n private rafStamps: RafStamps = { latestId: 0, invokeId: null };\n private mirror: Mirror;\n\n private mutationCb: canvasMutationCallback;\n private resetObservers?: listenerHandler;\n private frozen = false;\n private locked = false;\n private rafIdTimestamp: number | null = null;\n private rafIdFlush: number | null = null;\n private refCount = 0;\n private torndown = false;\n private resetFrameDedup: (() => void) | null = null;\n\n // Node ids are reused across full snapshots, so the encode worker's dedup\n // map would otherwise keep suppressing an idle canvas forever — leaving the\n // new snapshot's epoch without any frame to repaint that canvas from after\n // a seek. Called after each full snapshot so every canvas re-emits one frame.\n public onFullSnapshot() {\n this.resetFrameDedup?.();\n }\n\n // Shared by the main document and every iframe/shadow-root observer, so reference-count\n // teardown: a single root cleaning up must not unpatch getContext / stop the FPS loop globally.\n public acquire() {\n this.refCount += 1;\n }\n\n public reset() {\n if (this.refCount > 0) {\n this.refCount -= 1;\n }\n if (this.refCount > 0) {\n return;\n }\n this.teardown();\n }\n\n private teardown() {\n if (this.torndown) {\n return;\n }\n this.torndown = true;\n this.pendingCanvasMutations.clear();\n this.resetObservers && this.resetObservers();\n if (this.rafIdTimestamp !== null) {\n cancelAnimationFrame(this.rafIdTimestamp);\n this.rafIdTimestamp = null;\n }\n if (this.rafIdFlush !== null) {\n cancelAnimationFrame(this.rafIdFlush);\n this.rafIdFlush = null;\n }\n }\n\n public freeze() {\n this.frozen = true;\n }\n\n public unfreeze() {\n this.frozen = false;\n }\n\n public lock() {\n this.locked = true;\n }\n\n public unlock() {\n this.locked = false;\n }\n\n constructor(options: {\n recordCanvas: boolean;\n mutationCb: canvasMutationCallback;\n win: IWindow;\n blockClass: blockClass;\n blockSelector: string | null;\n mirror: Mirror;\n sampling?: 'all' | number;\n dataURLOptions: DataURLOptions;\n // fraction of the canvas display size to capture frames at, clamped to\n // [MIN_CANVAS_RESOLUTION_SCALE, 1]; the frame is upscaled back to its display size on replay,\n // so playback dimensions/aspect are unchanged, just softer. invalid/unset defaults to 1\n // (full resolution).\n resolutionScale?: number;\n canvasMasking?: CanvasMasking;\n }) {\n const {\n sampling = 'all',\n win,\n blockClass,\n blockSelector,\n recordCanvas,\n dataURLOptions,\n resolutionScale,\n canvasMasking,\n } = options;\n this.mutationCb = options.mutationCb;\n this.mirror = options.mirror;\n\n if (recordCanvas && sampling === 'all')\n this.initCanvasMutationObserver(\n win,\n blockClass,\n blockSelector,\n dataURLOptions,\n );\n if (recordCanvas && typeof sampling === 'number')\n this.initCanvasFPSObserver(sampling, win, blockClass, blockSelector, {\n dataURLOptions,\n resolutionScale,\n canvasMasking,\n });\n }\n\n private processMutation: canvasManagerMutationCallback = (\n target,\n mutation,\n ) => {\n const newFrame =\n this.rafStamps.invokeId &&\n this.rafStamps.latestId !== this.rafStamps.invokeId;\n if (newFrame || !this.rafStamps.invokeId)\n this.rafStamps.invokeId = this.rafStamps.latestId;\n\n if (!this.pendingCanvasMutations.has(target)) {\n this.pendingCanvasMutations.set(target, []);\n }\n\n this.pendingCanvasMutations.get(target)!.push(mutation);\n };\n\n private initCanvasFPSObserver(\n fps: number,\n win: IWindow,\n blockClass: blockClass,\n blockSelector: string | null,\n options: {\n dataURLOptions: DataURLOptions;\n resolutionScale?: number;\n canvasMasking?: CanvasMasking;\n },\n ) {\n if (!('OffscreenCanvas' in win)) {\n return;\n }\n\n // fraction of the canvas display size to capture frames at, clamped to\n // [MIN_CANVAS_RESOLUTION_SCALE, 1]; invalid/unset means full resolution.\n const scale =\n typeof options.resolutionScale === 'number' &&\n Number.isFinite(options.resolutionScale)\n ? Math.min(\n 1,\n Math.max(MIN_CANVAS_RESOLUTION_SCALE, options.resolutionScale),\n )\n : 1;\n\n const canvasContextReset = initCanvasContextObserver(\n win,\n blockClass,\n blockSelector,\n true,\n );\n const snapshotInProgressMap: Map<number, boolean> = new Map();\n\n // The inline worker is materialized by the bundler as a `blob:` object URL and loaded via\n // `importScripts(blobURL)` inside the worker. A strict page CSP (worker-src/script-src blob:),\n // an ad blocker, or a transient network hiccup can make that load fail — synchronously as a\n // thrown error here, or asynchronously as a worker error event. Either way, quietly disable\n // canvas snapshotting instead of letting an uncaught NetworkError escape and pollute error\n // tracking; the rest of session replay keeps working.\n let worker: ImageBitmapDataURLRequestWorker;\n try {\n worker = new ImageBitmapDataURLWorker() as ImageBitmapDataURLRequestWorker;\n } catch {\n return;\n }\n\n let workerErrored = false;\n worker.onerror = () => {\n workerErrored = true;\n // stop the capture loop; nothing can be encoded without the worker.\n cancelAnimationFrame(rafId);\n worker.terminate?.();\n this.resetFrameDedup = null;\n };\n this.resetFrameDedup = () => {\n worker.postMessage({ resetFrameDedup: true });\n };\n worker.onmessage = (e) => {\n const { id } = e.data;\n snapshotInProgressMap.set(id, false);\n\n if (!('base64' in e.data)) return;\n\n const { base64, type, displayWidth, displayHeight } = e.data;\n // the encoded image may be downscaled; draw it stretched back to the canvas's display\n // size — carried through the worker with the frame, so playback keeps the original\n // dimensions and aspect ratio, just softer.\n const dw = displayWidth;\n const dh = displayHeight;\n this.mutationCb({\n id,\n type: CanvasContext['2D'],\n commands: [\n {\n property: 'clearRect', // wipe canvas\n args: [0, 0, dw, dh],\n },\n {\n property: 'drawImage', // draws (semi-transparent) image, stretched to display size\n args: [\n {\n rr_type: 'ImageBitmap',\n args: [\n {\n rr_type: 'Blob',\n data: [{ rr_type: 'ArrayBuffer', base64 }],\n type,\n },\n ],\n } as CanvasArg,\n 0,\n 0,\n dw,\n dh,\n ],\n },\n ],\n displayWidth: dw,\n displayHeight: dh,\n });\n };\n\n const timeBetweenSnapshots = 1000 / fps;\n let lastSnapshotTime = 0;\n let rafId: number;\n\n const getCanvas = (): HTMLCanvasElement[] => {\n const matchedCanvas: HTMLCanvasElement[] = [];\n const searchCanvas = (haystack: ParentNode) => {\n try {\n haystack.querySelectorAll('canvas').forEach((canvas) => {\n if (!isBlocked(canvas, blockClass, blockSelector, true)) {\n matchedCanvas.push(canvas);\n }\n });\n haystack.querySelectorAll('*').forEach((elem) => {\n if (elem.shadowRoot) {\n searchCanvas(elem.shadowRoot);\n }\n });\n } catch {\n // Don't let traversal errors cancel the rAF loop.\n }\n };\n searchCanvas(win.document);\n return matchedCanvas;\n };\n\n const takeCanvasSnapshots = (timestamp: DOMHighResTimeStamp) => {\n // the worker failed to load (e.g. CSP blocked the blob script); stop capturing.\n if (workerErrored) {\n return;\n }\n if (lastSnapshotTime && timestamp - lastSnapshotTime < timeBetweenSnapshots) {\n rafId = requestAnimationFrame(takeCanvasSnapshots);\n return;\n }\n lastSnapshotTime = timestamp;\n\n getCanvas()\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n .forEach(async (canvas: HTMLCanvasElement) => {\n const id = this.mirror.getId(canvas);\n if (snapshotInProgressMap.get(id)) return;\n\n // The browser throws if the canvas is 0 in size\n // Uncaught (in promise) DOMException: Failed to execute 'createImageBitmap' on 'Window': The source image width is 0.\n // Assuming the same happens with height\n if (canvas.width === 0 || canvas.height === 0) return;\n\n snapshotInProgressMap.set(id, true);\n try {\n if (['webgl', 'webgl2'].includes((canvas as ICanvas).__context)) {\n // if the canvas hasn't been modified recently,\n // its contents won't be in memory and `createImageBitmap`\n // will return a transparent imageBitmap\n\n const context = canvas.getContext(\n (canvas as ICanvas).__context,\n ) as WebGLRenderingContext | WebGL2RenderingContext | null;\n // Snapshotting a lost context produces a transparent bitmap\n // that poisons the worker's fingerprint dedup map; skip it.\n if (context?.isContextLost?.()) {\n snapshotInProgressMap.set(id, false);\n return;\n }\n if (\n context?.getContextAttributes()?.preserveDrawingBuffer === false\n ) {\n // Hack to load canvas back into memory so `createImageBitmap` can grab it's contents.\n // Context: https://twitter.com/Juice10/status/1499775271758704643\n // Preferably we set `preserveDrawingBuffer` to true, but that's not always possible,\n // especially when canvas is loaded before rrweb.\n // This hack can wipe the background color of the canvas in the (unlikely) event that\n // the canvas background was changed but clear was not called directly afterwards.\n // Example of this hack having negative side effect: https://visgl.github.io/react-map-gl/examples/layers\n context.clear(context.COLOR_BUFFER_BIT);\n }\n }\n // createImageBitmap throws if resizing to 0\n // Fallback to intrinsic size if canvas has not yet rendered\n const displayWidth = canvas.clientWidth || canvas.width;\n const displayHeight = canvas.clientHeight || canvas.height;\n // capture at a (optionally downscaled) resolution; replay upscales it back to the\n // display size, so playback dimensions/aspect are unchanged, just softer.\n const captureWidth = Math.max(1, Math.round(displayWidth * scale));\n const captureHeight = Math.max(1, Math.round(displayHeight * scale));\n // computed before the await so regions and display dims describe\n // the same frame even if the canvas resizes mid-snapshot\n const maskRegions = computeFrameMaskRegions(\n options.canvasMasking,\n canvas,\n captureWidth,\n captureHeight,\n displayWidth,\n displayHeight,\n );\n if (maskRegions === SKIP_FRAME) {\n snapshotInProgressMap.set(id, false);\n return;\n }\n const bitmap = await createImageBitmap(\n canvas,\n // only ask for a quality resampling filter when we're actually downscaling;\n // at full resolution this keeps capture identical to before.\n scale < 1\n ? {\n resizeWidth: captureWidth,\n resizeHeight: captureHeight,\n resizeQuality: 'medium',\n }\n : { resizeWidth: captureWidth, resizeHeight: captureHeight },\n );\n // pass the display size through with the frame so the worker's reply can draw it\n // back to the right dimensions — no per-id state retained on the main thread.\n worker.postMessage(\n {\n id,\n bitmap,\n width: captureWidth,\n height: captureHeight,\n displayWidth,\n displayHeight,\n dataURLOptions: options.dataURLOptions,\n maskRegions,\n },\n [bitmap],\n );\n } catch {\n snapshotInProgressMap.set(id, false);\n }\n });\n rafId = requestAnimationFrame(takeCanvasSnapshots);\n };\n\n rafId = requestAnimationFrame(takeCanvasSnapshots);\n\n this.resetObservers = () => {\n canvasContextReset();\n cancelAnimationFrame(rafId);\n // a dedicated worker is not terminated by becoming unreachable; without\n // this, every recorder restart leaks a worker thread plus its\n // capture-resolution OffscreenCanvas\n worker.terminate?.();\n this.resetFrameDedup = null;\n };\n }\n\n private initCanvasMutationObserver(\n win: IWindow,\n blockClass: blockClass,\n blockSelector: string | null,\n dataURLOptions: DataURLOptions,\n ): void {\n this.startRAFTimestamping();\n this.startPendingCanvasMutationFlusher();\n\n const canvasContextReset = initCanvasContextObserver(\n win,\n blockClass,\n blockSelector,\n false,\n );\n const canvas2DReset = initCanvas2DMutationObserver(\n this.processMutation.bind(this),\n win,\n blockClass,\n blockSelector,\n dataURLOptions,\n );\n\n const canvasWebGL1and2Reset = initCanvasWebGLMutationObserver(\n this.processMutation.bind(this),\n win,\n blockClass,\n blockSelector,\n dataURLOptions,\n );\n\n this.resetObservers = () => {\n canvasContextReset();\n canvas2DReset();\n canvasWebGL1and2Reset();\n };\n }\n\n private startPendingCanvasMutationFlusher() {\n this.rafIdFlush = requestAnimationFrame(() =>\n this.flushPendingCanvasMutations(),\n );\n }\n\n private startRAFTimestamping() {\n const setLatestRAFTimestamp = (timestamp: DOMHighResTimeStamp) => {\n this.rafStamps.latestId = timestamp;\n this.rafIdTimestamp = requestAnimationFrame(setLatestRAFTimestamp);\n };\n this.rafIdTimestamp = requestAnimationFrame(setLatestRAFTimestamp);\n }\n\n flushPendingCanvasMutations() {\n this.pendingCanvasMutations.forEach(\n (_values: canvasMutationCommand[], canvas: HTMLCanvasElement) => {\n const id = this.mirror.getId(canvas);\n this.flushPendingCanvasMutationFor(canvas, id);\n },\n );\n this.rafIdFlush = requestAnimationFrame(() =>\n this.flushPendingCanvasMutations(),\n );\n }\n\n flushPendingCanvasMutationFor(canvas: HTMLCanvasElement, id: number) {\n if (this.frozen || this.locked) {\n return;\n }\n\n const valuesWithType = this.pendingCanvasMutations.get(canvas);\n if (!valuesWithType || id === -1) return;\n\n const values = valuesWithType.map((value) => {\n const { type, ...rest } = value;\n return rest;\n });\n const { type } = valuesWithType[0];\n\n this.mutationCb({ id, type, commands: values });\n\n this.pendingCanvasMutations.delete(canvas);\n }\n}\n","// Modified by ELU. See NOTICE-ELU and THIRD_PARTY_NOTICES.txt.\n\nimport {\n type blockClass,\n CanvasContext,\n type canvasManagerMutationCallback,\n type IWindow,\n type listenerHandler,\n type DataURLOptions,\n} from '@elu-labs/recorder-types';\nimport { hookSetter, isBlocked } from '../../../utils';\nimport { patch } from '@elu-labs/recorder-utils';\nimport { serializeArgs } from './serialize-args';\n\nexport default function initCanvas2DMutationObserver(\n cb: canvasManagerMutationCallback,\n win: IWindow,\n blockClass: blockClass,\n blockSelector: string | null,\n dataURLOptions: DataURLOptions,\n): listenerHandler {\n const handlers: listenerHandler[] = [];\n const props2D = Object.getOwnPropertyNames(\n win.CanvasRenderingContext2D.prototype,\n );\n for (const prop of props2D) {\n try {\n if (\n typeof win.CanvasRenderingContext2D.prototype[\n prop as keyof CanvasRenderingContext2D\n ] !== 'function'\n ) {\n continue;\n }\n const restoreHandler = patch(\n win.CanvasRenderingContext2D.prototype,\n prop,\n function (\n original: (\n this: CanvasRenderingContext2D,\n ...args: unknown[]\n ) => void,\n ) {\n return function (\n this: CanvasRenderingContext2D,\n ...args: Array<unknown>\n ) {\n if (!isBlocked(this.canvas, blockClass, blockSelector, true)) {\n // Using setTimeout as toDataURL can be heavy\n // and we'd rather not block the main thread\n setTimeout(() => {\n const recordArgs = serializeArgs(\n args,\n win,\n this,\n dataURLOptions,\n );\n cb(this.canvas, {\n type: CanvasContext['2D'],\n property: prop,\n args: recordArgs,\n });\n }, 0);\n }\n return original.apply(this, args);\n };\n },\n );\n handlers.push(restoreHandler);\n } catch {\n const hookHandler = hookSetter<CanvasRenderingContext2D>(\n win.CanvasRenderingContext2D.prototype,\n prop,\n {\n set(v) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-member-access\n cb(this.canvas, {\n type: CanvasContext['2D'],\n property: prop,\n args: [v],\n setter: true,\n });\n },\n },\n );\n handlers.push(hookHandler);\n }\n }\n return () => {\n handlers.forEach((h) => h());\n };\n}\n","// Modified by ELU. See NOTICE-ELU and THIRD_PARTY_NOTICES.txt.\n\nimport {\n resetStylesheetLoadTracking,\n stringifyRule,\n} from '@elu-labs/recorder-snapshot';\nimport type {\n elementNode,\n serializedNodeWithId,\n adoptedStyleSheetCallback,\n adoptedStyleSheetParam,\n attributeMutation,\n mutationCallBack,\n} from '@elu-labs/recorder-types';\nimport { StyleSheetMirror } from '../utils';\n\nexport class StylesheetManager {\n private trackedLinkElements: WeakSet<HTMLLinkElement> = new WeakSet();\n private mutationCb: mutationCallBack;\n private adoptedStyleSheetCb: adoptedStyleSheetCallback;\n public styleMirror = new StyleSheetMirror();\n\n constructor(options: {\n mutationCb: mutationCallBack;\n adoptedStyleSheetCb: adoptedStyleSheetCallback;\n }) {\n this.mutationCb = options.mutationCb;\n this.adoptedStyleSheetCb = options.adoptedStyleSheetCb;\n }\n\n public attachLinkElement(\n linkEl: HTMLLinkElement,\n childSn: serializedNodeWithId,\n ) {\n if ('_cssText' in (childSn as elementNode).attributes)\n this.mutationCb({\n adds: [],\n removes: [],\n texts: [],\n attributes: [\n {\n id: childSn.id,\n attributes: (childSn as elementNode)\n .attributes as attributeMutation['attributes'],\n },\n ],\n });\n\n this.trackLinkElement(linkEl);\n }\n\n public trackLinkElement(linkEl: HTMLLinkElement) {\n if (this.trackedLinkElements.has(linkEl)) return;\n\n this.trackedLinkElements.add(linkEl);\n this.trackStylesheetInLinkElement(linkEl);\n }\n\n public adoptStyleSheets(\n sheets: CSSStyleSheet[] | readonly CSSStyleSheet[],\n hostId: number,\n ) {\n if (sheets.length === 0) return;\n const adoptedStyleSheetData: adoptedStyleSheetParam = {\n id: hostId,\n styleIds: [] as number[],\n };\n const styles: NonNullable<adoptedStyleSheetParam['styles']> = [];\n for (const sheet of sheets) {\n let styleId;\n if (!this.styleMirror.has(sheet)) {\n styleId = this.styleMirror.add(sheet);\n styles.push({\n styleId,\n rules: Array.from(sheet.rules || CSSRule, (r, index) => ({\n rule: stringifyRule(r, sheet.href),\n index,\n })),\n });\n } else styleId = this.styleMirror.getId(sheet);\n adoptedStyleSheetData.styleIds.push(styleId);\n }\n if (styles.length > 0) adoptedStyleSheetData.styles = styles;\n this.adoptedStyleSheetCb(adoptedStyleSheetData);\n }\n\n public reset() {\n this.styleMirror.reset();\n this.trackedLinkElements = new WeakSet();\n resetStylesheetLoadTracking();\n }\n\n // TODO: take snapshot on stylesheet reload by applying event listener\n private trackStylesheetInLinkElement(_linkEl: HTMLLinkElement) {\n // linkEl.addEventListener('load', () => {\n // // re-loaded, maybe take another snapshot?\n // });\n }\n}\n","import type MutationBuffer from './mutation';\n\n/**\n * Keeps a log of nodes that could show up in multiple mutation buffer but shouldn't be handled twice.\n */\nexport default class ProcessedNodeManager {\n private nodeMap: WeakMap<Node, Set<MutationBuffer>> = new WeakMap();\n\n private active = false;\n\n public inOtherBuffer(node: Node, thisBuffer: MutationBuffer) {\n const buffers = this.nodeMap.get(node);\n return (\n buffers && Array.from(buffers).some((buffer) => buffer !== thisBuffer)\n );\n }\n\n public add(node: Node, buffer: MutationBuffer) {\n if (!this.active) {\n this.active = true;\n requestAnimationFrame(() => {\n this.nodeMap = new WeakMap();\n this.active = false;\n });\n }\n this.nodeMap.set(node, (this.nodeMap.get(node) || new Set()).add(buffer));\n }\n\n public destroy() {\n // cleanup no longer needed\n }\n}\n","/** Decodes build-owned ASCII JSON data. It never evaluates or imports source code. */\nexport const unpackV1DeflatedTextData = (encoded: string, expectedBytes: number, expectedCount: number): readonly string[] => {\n const invalid = (): never => { throw new Error('Invalid internal text data') }\n if (!Number.isSafeInteger(expectedBytes) || expectedBytes < 1 || expectedBytes > 1_000_000 || !Number.isSafeInteger(expectedCount) || expectedCount < 1 || expectedCount > 10_000 || encoded.length > 2_000_000 || encoded.length % 4 !== 0) invalid()\n const padding = encoded.endsWith('==') ? 2 : encoded.endsWith('=') ? 1 : 0\n const bytes = new Uint8Array((encoded.length / 4) * 3 - padding)\n const alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'\n let byteCount = 0\n let bits = 0\n let value = 0\n for (let index = 0; index < encoded.length - padding; index++) {\n const digit = alphabet.indexOf(encoded.charAt(index))\n if (digit < 0) invalid()\n value = (value << 6) | digit\n bits += 6\n if (bits >= 8) { bits -= 8; bytes[byteCount++] = (value >>> bits) & 255 }\n }\n if (bits && (value & ((1 << bits) - 1))) invalid()\n\n const output = new Uint8Array(expectedBytes)\n let written = 0\n let position = 0\n const read = (count: number): number => {\n if (position + count > bytes.length * 8) invalid()\n const offset = position >>> 3\n const result = ((bytes[offset] | (bytes[offset + 1] << 8) | (bytes[offset + 2] << 16)) >>> (position & 7)) & ((1 << count) - 1)\n position += count\n return result\n }\n type Tree = { counts: Uint16Array; symbols: Uint16Array; maximum: number }\n // Code-length trees must be complete. Data trees may have one one-bit symbol;\n // the distance tree alone may be empty when the block contains no match.\n const tree = (lengths: Uint8Array, single: boolean, empty: boolean): Tree => {\n const counts = new Uint16Array(16)\n let maximum = 0\n for (let index = 0; index < lengths.length; index++) {\n const length = lengths[index]\n if (length > 15) invalid()\n if (length) { counts[length]++; maximum = Math.max(maximum, length) }\n }\n let remaining = 1\n for (let length = 1; length <= 15; length++) {\n remaining = remaining * 2 - counts[length]\n if (remaining < 0) invalid()\n }\n if (!maximum ? !empty : remaining && !(single && maximum === 1 && counts[1] === 1)) invalid()\n const offsets = new Uint16Array(16)\n for (let length = 1; length < 15; length++) offsets[length + 1] = offsets[length] + counts[length]\n const symbols = new Uint16Array(lengths.length)\n for (let symbol = 0; symbol < lengths.length; symbol++) {\n const length = lengths[symbol]\n if (length) symbols[offsets[length]++] = symbol\n }\n return { counts, symbols, maximum }\n }\n const symbol = (codes: Tree): number => {\n let code = 0\n let first = 0\n let index = 0\n for (let length = 1; length <= codes.maximum; length++) {\n code = (code << 1) | read(1)\n const count = codes.counts[length]\n if (code >= first && code - first < count) return codes.symbols[index + code - first]\n index += count\n first = (first + count) << 1\n }\n return invalid()\n }\n let final = 0\n let blocks = 0\n let fixedLiterals: Tree | undefined\n let fixedDistances: Tree | undefined\n while (!final) {\n // Build-owned tables allow at most 1,024 blocks, including empty blocks.\n if (++blocks > 1024) invalid()\n final = read(1)\n const kind = read(2)\n if (kind === 0) {\n // Stored blocks start at the next byte; these alignment bits carry no data.\n position = (position + 7) & ~7\n const length = read(16)\n if ((length ^ read(16)) !== 65535 || written + length > expectedBytes || position + length * 8 > bytes.length * 8) invalid()\n output.set(bytes.subarray(position >>> 3, (position >>> 3) + length), written)\n written += length\n position += length * 8\n } else {\n let literals: Tree\n let distances: Tree\n if (kind === 1) {\n if (!fixedLiterals || !fixedDistances) {\n const lengths = new Uint8Array(288)\n for (let index = 0; index < lengths.length; index++) lengths[index] = index < 144 ? 8 : index < 256 ? 9 : index < 280 ? 7 : 8\n fixedLiterals = tree(lengths, false, false)\n const distanceLengths = new Uint8Array(32)\n for (let index = 0; index < distanceLengths.length; index++) distanceLengths[index] = 5\n fixedDistances = tree(distanceLengths, false, false)\n }\n literals = fixedLiterals\n distances = fixedDistances\n } else if (kind === 2) {\n const literalCount = read(5) + 257\n const distanceCount = read(5) + 1\n const codeCount = read(4) + 4\n if (literalCount > 286) invalid()\n const order = [16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]\n const codeLengths = new Uint8Array(19)\n for (let index = 0; index < codeCount; index++) codeLengths[order[index]] = read(3)\n const codeTree = tree(codeLengths, false, false)\n const lengths = new Uint8Array(literalCount + distanceCount)\n let index = 0\n while (index < lengths.length) {\n const length = symbol(codeTree)\n if (length < 16) lengths[index++] = length\n else {\n if (length === 16 && !index) invalid()\n const repeated = length === 16 ? lengths[index - 1] : 0\n const count = length === 16 ? read(2) + 3 : length === 17 ? read(3) + 3 : read(7) + 11\n if (index + count > lengths.length) invalid()\n for (let end = index + count; index < end; index++) lengths[index] = repeated\n }\n }\n if (!lengths[256]) invalid()\n literals = tree(lengths.subarray(0, literalCount), true, false)\n distances = tree(lengths.subarray(literalCount), true, true)\n } else return invalid()\n for (;;) {\n const next = symbol(literals)\n if (next === 256) break\n if (next < 256) {\n if (written === expectedBytes) invalid()\n output[written++] = next\n } else {\n if (next > 285) invalid()\n const index = next - 257\n const extra = (index >>> 2) - 1\n const length = index < 8 ? index + 3 : index === 28 ? 258 : (((index & 3) + 4) << extra) + 3 + read(extra)\n const distanceSymbol = symbol(distances)\n if (distanceSymbol > 29) invalid()\n const distanceExtra = (distanceSymbol >>> 1) - 1\n const distance = distanceSymbol < 4 ? distanceSymbol + 1 : (((distanceSymbol & 1) + 2) << distanceExtra) + 1 + read(distanceExtra)\n if (distance > written || written + length > expectedBytes) invalid()\n // Overlapping matches deliberately read the bytes just written.\n for (let index = 0; index < length; index++) { output[written] = output[written - distance]; written++ }\n }\n }\n }\n }\n // A raw stream has no trailer. Ignore only its final byte's unused alignment bits.\n if (written !== expectedBytes || Math.ceil(position / 8) !== bytes.length) invalid()\n let decoded = ''\n // Keep native apply argument lists bounded on older supported browsers.\n for (let offset = 0; offset < written; offset += 4096) decoded += String.fromCharCode.apply(null, output.subarray(offset, Math.min(offset + 4096, written)) as unknown as number[])\n const texts: unknown = JSON.parse(decoded)\n if (!Array.isArray(texts) || texts.length !== expectedCount || texts.some(text => typeof text !== 'string')) invalid()\n return Object.freeze(texts as string[])\n}\n","const { isArray } = Array\nexport const isArrayValue = (value: unknown): value is unknown[] => isArray(value)\n\nexport const isRecordValue = (value: unknown): value is Record<string, unknown> =>\n typeof value === 'object' && value != null && !isArrayValue(value)\n\nexport const isStringValue = (value: unknown): value is string => typeof value === 'string'\n\nexport const isBooleanValue = (value: unknown): value is boolean => value === true || value === false\n\nexport const isFunctionValue = (value: unknown): value is (...args: never[]) => unknown => {\n switch (typeof value) {\n case 'function':\n return true\n default:\n return false\n }\n}\n\nexport const unicodeCodePointLength = (value: string): number | null => {\n let length = 0\n for (let index = 0; index < value.length; index += 1) {\n const code = value.charCodeAt(index)\n if (code >= 0xd800 && code <= 0xdbff) {\n const next = value.charCodeAt(index + 1)\n if (index + 1 >= value.length || next < 0xdc00 || next > 0xdfff) {\n return null\n }\n index += 1\n } else if (code >= 0xdc00 && code <= 0xdfff) {\n return null\n }\n length += 1\n }\n return length\n}\n\nexport const isNumberValue = (value: unknown): value is number => {\n switch (typeof value) {\n case 'number':\n return Number.isFinite(value)\n default:\n return false\n }\n}\n\nexport const isNonNegativeInteger = (value: unknown): value is number =>\n isNumberValue(value) && Number.isSafeInteger(value) && value >= 0\n\nexport const isNullValue = (value: unknown): value is null => Object.is(value, null)\n\nexport const hasOwn = (value: Record<string, unknown>, key: string): boolean =>\n Object.prototype.hasOwnProperty.call(value, key)\n\nexport const hasOwnIndex = (value: readonly unknown[], index: number): boolean =>\n Object.prototype.hasOwnProperty.call(value, index)\n\nexport const hasOnlyKeys = (value: Record<string, unknown>, allowedKeys: readonly string[]): boolean => {\n const allowed = new Set(allowedKeys)\n return Object.keys(value).every((key) => allowed.has(key))\n}\n\nexport const utf8ByteLength = (value: string): number => {\n let bytes = 0\n for (let index = 0; index < value.length; index += 1) {\n const code = value.charCodeAt(index)\n if (code <= 0x7f) {\n bytes += 1\n } else if (code <= 0x7ff) {\n bytes += 2\n } else if (code >= 0xd800 && code <= 0xdbff && index + 1 < value.length) {\n const next = value.charCodeAt(index + 1)\n if (next >= 0xdc00 && next <= 0xdfff) {\n bytes += 4\n index += 1\n } else {\n bytes += 3\n }\n } else {\n bytes += 3\n }\n }\n return bytes\n}\n\nexport const parseBoundedJson = (\n rawJson: string,\n maximumBytes: number,\n field: string\n): { readonly value: unknown; readonly serialized: string } => {\n if (!isStringValue(rawJson)) {\n throw new Error(`${field} must be raw JSON text`)\n }\n if (utf8ByteLength(rawJson) > maximumBytes) {\n throw new Error(`${field} exceeds the ${maximumBytes}-byte limit`)\n }\n\n let value: unknown\n try {\n value = JSON.parse(rawJson)\n } catch {\n throw new Error(`${field} must be valid JSON`)\n }\n\n const serialized = JSON.stringify(value)\n if (!isStringValue(serialized)) {\n throw new Error(`${field} must be a JSON value`)\n }\n return { value, serialized }\n}\n\n/**\n * Shares native freezing without caching the intrinsic or changing its overloads.\n * Assumes native Object.freeze semantics; every value is still frozen exactly once.\n */\nexport const freezeV1Value: typeof Object.freeze = <T>(value: T): Readonly<T> => Object.freeze(value)\n","import type {\n V1BatchRequest,\n V1BeaconPostRequest,\n V1ConfigDocumentVersion,\n V1ConfigHttpRequest,\n V1EndpointName,\n V1EndpointSet,\n V1FlagsRequest,\n V1NormalPostRequest,\n V1PostRequest,\n V1ReplayRequest,\n V1ValidatedEndpointSet,\n} from './types'\nimport {\n freezeV1Value,\n hasOnlyKeys,\n hasOwn,\n isNullValue,\n isRecordValue,\n isStringValue,\n unicodeCodePointLength,\n} from './validation'\n\nexport const V1_CONFIG_ORIGIN = 'https://elu.dev'\nconst INGEST_ORIGIN = 'https://ingest.elu.dev'\nconst ASSETS_ORIGIN = 'https://assets.elu.dev'\nconst SITE_KEY_QUERY_PARAMETER = 'site_key'\nconst BEACON_CONTENT_TYPE = 'text/plain;charset=UTF-8'\nconst MALFORMED_PERCENT_ESCAPE_PATTERN = /%(?![0-9A-Fa-f]{2})/\nconst RFC3986_FORBIDDEN_RAW_CHARACTER_PATTERN = /[\"<>\\\\^`{|}]/\nconst ABSOLUTE_URL_RAW_PATH_PATTERN = /^[A-Za-z][A-Za-z0-9+.-]*:\\/\\/[^/?#]+([^?#]*)/\n\nconst hasCharacterOutsideVisibleAscii = (value: string): boolean => {\n for (let index = 0; index < value.length; index += 1) {\n const code = value.charCodeAt(index)\n if (code <= 0x20 || code >= 0x7f) {\n return true\n }\n }\n return false\n}\n\nexport const V1_ENDPOINT_ORIGIN_ALLOWLIST: Readonly<Record<V1EndpointName, readonly string[]>> = freezeV1Value({\n events: freezeV1Value([INGEST_ORIGIN]),\n replay: freezeV1Value([INGEST_ORIGIN]),\n flags: freezeV1Value([INGEST_ORIGIN]),\n assets: freezeV1Value([ASSETS_ORIGIN]),\n})\nexport const V1_ENDPOINT_PATHS: Readonly<Record<V1EndpointName, string>> = freezeV1Value({\n events: '/v1/events',\n replay: '/v1/replay',\n flags: '/v1/flags',\n assets: '/sdk/',\n})\n/**\n * Config v2 keeps the v1 event and flag roles and moves replay to its own major. The standalone\n * replay endpoint does not accept replay v1, so a v2 document must never advertise the v1 path and a\n * v1 document must never advertise the v2 path.\n */\nexport const V2_ENDPOINT_PATHS: Readonly<Record<V1EndpointName, string>> = freezeV1Value({\n events: '/v1/events',\n replay: '/v2/replay',\n flags: '/v1/flags',\n assets: '/sdk/',\n})\nconst ENDPOINT_PATHS_BY_CONFIG_VERSION: Readonly<\n Record<V1ConfigDocumentVersion, Readonly<Record<V1EndpointName, string>>>\n> = freezeV1Value({ 1: V1_ENDPOINT_PATHS, 2: V2_ENDPOINT_PATHS })\nconst CONFIG_PATH_PREFIX_BY_VERSION: Readonly<Record<V1ConfigDocumentVersion, string>> = freezeV1Value({\n 1: '/sdk/v1/',\n 2: '/sdk/v2/',\n})\n\nexport class V1TransportConfigurationError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'V1TransportConfigurationError'\n }\n}\n\nconst assertSiteKey = (siteKey: string): void => {\n if (!isStringValue(siteKey) || siteKey.length === 0) {\n throw new V1TransportConfigurationError('site key must be a non-empty string')\n }\n if (isNullValue(unicodeCodePointLength(siteKey))) {\n throw new V1TransportConfigurationError('site key must not contain an unpaired Unicode surrogate')\n }\n if (siteKey === '.' || siteKey === '..') {\n throw new V1TransportConfigurationError('site key must not be a URL path dot segment')\n }\n for (let index = 0; index < siteKey.length; index += 1) {\n const codePoint = siteKey.charCodeAt(index)\n if (codePoint <= 31 || codePoint === 127) {\n throw new V1TransportConfigurationError('site key must not contain ASCII control characters')\n }\n }\n}\n\n/** Validates a site key from an authorized delivery snapshot. */\nexport const validateV1SiteKey = (value: unknown): string => {\n if (!isStringValue(value)) {\n throw new V1TransportConfigurationError('site key must be a string')\n }\n assertSiteKey(value)\n return value\n}\n\nconst validateEndpoint = (\n name: V1EndpointName,\n value: unknown,\n expectedPath: string = V1_ENDPOINT_PATHS[name]\n): string => {\n if (!isStringValue(value)) {\n throw new V1TransportConfigurationError(`${name} endpoint must be a string`)\n }\n if (isNullValue(unicodeCodePointLength(value))) {\n throw new V1TransportConfigurationError(`${name} endpoint must not contain an unpaired Unicode surrogate`)\n }\n if (hasCharacterOutsideVisibleAscii(value)) {\n throw new V1TransportConfigurationError(\n `${name} endpoint must contain only visible ASCII characters; encode non-ASCII bytes`\n )\n }\n if (MALFORMED_PERCENT_ESCAPE_PATTERN.test(value)) {\n throw new V1TransportConfigurationError(`${name} endpoint contains a malformed percent escape`)\n }\n if (RFC3986_FORBIDDEN_RAW_CHARACTER_PATTERN.test(value)) {\n throw new V1TransportConfigurationError(`${name} endpoint contains a character forbidden in an RFC 3986 URI`)\n }\n\n // URL parsers normalize dot segments before exposing pathname. Compare the configured bytes so\n // a path such as /v1/../v1/events cannot acquire an allowlisted path through normalization.\n const rawPath = ABSOLUTE_URL_RAW_PATH_PATTERN.exec(value)?.[1]\n if (rawPath !== expectedPath) {\n throw new V1TransportConfigurationError(`${name} endpoint path is not allowlisted`)\n }\n\n let parsed: URL\n try {\n // The trust check requires native absolute-URL parsing and fails closed when it is unavailable.\n // eslint-disable-next-line compat/compat\n parsed = new URL(value)\n } catch {\n throw new V1TransportConfigurationError(`${name} endpoint must be an absolute URL`)\n }\n\n if (parsed.protocol !== 'https:') {\n throw new V1TransportConfigurationError(`${name} endpoint must use HTTPS`)\n }\n if (parsed.username || parsed.password) {\n throw new V1TransportConfigurationError(`${name} endpoint must not contain user information`)\n }\n if (!V1_ENDPOINT_ORIGIN_ALLOWLIST[name].includes(parsed.origin)) {\n throw new V1TransportConfigurationError(`${name} endpoint origin is not allowlisted`)\n }\n if (parsed.pathname !== expectedPath) {\n throw new V1TransportConfigurationError(`${name} endpoint path is not allowlisted`)\n }\n if (parsed.searchParams.has(SITE_KEY_QUERY_PARAMETER)) {\n throw new V1TransportConfigurationError(`${name} endpoint must not define the reserved site_key parameter`)\n }\n if (value.includes('#')) {\n throw new V1TransportConfigurationError(`${name} endpoint must not contain a fragment`)\n }\n\n return parsed.href\n}\n\n/** Validates an event endpoint from an authorized delivery snapshot. */\nexport const validateV1EventsEndpoint = (value: unknown): string => validateEndpoint('events', value)\n\n/** Validates the standalone replay role of a v2 config; the v1 replay path is not interchangeable. */\nexport const validateV2ReplayEndpoint = (value: unknown): string =>\n validateEndpoint('replay', value, V2_ENDPOINT_PATHS.replay)\n\n/** Validates only the flags transport role for the independent flag authorization projection. */\nexport const validateV1FlagsEndpoint = (value: unknown): string => validateEndpoint('flags', value)\n\n/** Validates the configured asset base; this is an endpoint check, not loading authority. */\nexport const validateV1AssetsEndpoint = (value: unknown): string => validateEndpoint('assets', value)\n\n/**\n * Resolves transport endpoints from a config that has already passed the config manager's\n * complete schema, status, expiry, privacy, and feature-gate checks. This function validates\n * only exact endpoint shape, role path, and origin; it is not a config authorization decision.\n */\nconst validateEnabledConfigEndpoints = (\n value: unknown,\n configVersion: V1ConfigDocumentVersion\n): V1ValidatedEndpointSet => {\n if (!isRecordValue(value)) {\n throw new V1TransportConfigurationError('enabled config endpoint set must be an object')\n }\n if (!hasOnlyKeys(value, ['events', 'replay', 'flags', 'assets'])) {\n throw new V1TransportConfigurationError('enabled config endpoint set contains an unsupported endpoint')\n }\n const paths = ENDPOINT_PATHS_BY_CONFIG_VERSION[configVersion]\n\n const endpoints: V1EndpointSet = {\n events: validateEndpoint('events', value.events, paths.events),\n flags: validateEndpoint('flags', value.flags, paths.flags),\n ...(hasOwn(value, 'replay') ? { replay: validateEndpoint('replay', value.replay, paths.replay) } : {}),\n ...(hasOwn(value, 'assets') ? { assets: validateEndpoint('assets', value.assets, paths.assets) } : {}),\n }\n return freezeV1Value(endpoints) as V1ValidatedEndpointSet\n}\n\nexport const validateV1EnabledConfigEndpoints = (value: unknown): V1ValidatedEndpointSet =>\n validateEnabledConfigEndpoints(value, 1)\n\n/** The v2 endpoint set differs from v1 only in the replay role, which must use the v2 replay path. */\nexport const validateV2EnabledConfigEndpoints = (value: unknown): V1ValidatedEndpointSet =>\n validateEnabledConfigEndpoints(value, 2)\n\nconst serializeBody = (body: unknown): string => {\n const serialized = JSON.stringify(body)\n if (!isStringValue(serialized)) {\n throw new V1TransportConfigurationError('request body must be JSON serializable')\n }\n return serialized\n}\n\nconst resolvePostEndpoint = (endpoints: V1ValidatedEndpointSet, name: 'events' | 'replay' | 'flags'): string => {\n const endpoint = endpoints[name]\n if (!endpoint) {\n throw new V1TransportConfigurationError(`${name} endpoint is not advertised by the enabled config`)\n }\n return endpoint\n}\n\nconst buildNormalPostRequest = (siteKey: string, endpoint: string, body: unknown): V1NormalPostRequest => {\n assertSiteKey(siteKey)\n const headers: V1NormalPostRequest['init']['headers'] = freezeV1Value({\n Authorization: `Bearer ${siteKey}`,\n 'Content-Type': 'application/json',\n })\n const init: V1NormalPostRequest['init'] = freezeV1Value({\n method: 'POST',\n mode: 'cors',\n credentials: 'omit',\n headers,\n body: serializeBody(body),\n })\n return freezeV1Value({ delivery: 'normal', url: endpoint, init })\n}\n\nconst buildBeaconPostRequest = (siteKey: string, endpoint: string, body: unknown): V1BeaconPostRequest => {\n assertSiteKey(siteKey)\n // Config endpoint validation already required native URL parsing and an exact allowlisted origin.\n // eslint-disable-next-line compat/compat\n const url = new URL(endpoint)\n url.searchParams.set(SITE_KEY_QUERY_PARAMETER, siteKey)\n return freezeV1Value({\n delivery: 'beacon',\n url: url.href,\n body: new Blob([serializeBody(body)], { type: BEACON_CONTENT_TYPE }),\n })\n}\n\nconst buildPostRequest = (\n siteKey: string,\n endpoints: V1ValidatedEndpointSet,\n endpointName: 'events' | 'replay',\n body: unknown,\n delivery: 'normal' | 'beacon'\n): V1PostRequest => {\n const endpoint = resolvePostEndpoint(endpoints, endpointName)\n return delivery === 'beacon'\n ? buildBeaconPostRequest(siteKey, endpoint, body)\n : buildNormalPostRequest(siteKey, endpoint, body)\n}\n\nconst buildConfigRequest = (siteKey: string, configVersion: V1ConfigDocumentVersion): V1ConfigHttpRequest => {\n assertSiteKey(siteKey)\n const encodedSiteKey = encodeURIComponent(siteKey)\n const init: V1ConfigHttpRequest['init'] = freezeV1Value({\n method: 'GET',\n mode: 'cors',\n credentials: 'omit',\n })\n return freezeV1Value({\n delivery: 'normal',\n url: `${V1_CONFIG_ORIGIN}${CONFIG_PATH_PREFIX_BY_VERSION[configVersion]}${encodedSiteKey}/config`,\n init,\n })\n}\n\nexport const buildV1ConfigRequest = (siteKey: string): V1ConfigHttpRequest => buildConfigRequest(siteKey, 1)\n\n/** The owned standalone handshake. The site key is the only credential and travels in the path. */\nexport const buildV2ConfigRequest = (siteKey: string): V1ConfigHttpRequest => buildConfigRequest(siteKey, 2)\n\nexport function buildV1EventsRequest(\n siteKey: string,\n endpoints: V1ValidatedEndpointSet,\n request: V1BatchRequest\n): V1NormalPostRequest\nexport function buildV1EventsRequest(\n siteKey: string,\n endpoints: V1ValidatedEndpointSet,\n request: V1BatchRequest,\n delivery: 'normal'\n): V1NormalPostRequest\nexport function buildV1EventsRequest(\n siteKey: string,\n endpoints: V1ValidatedEndpointSet,\n request: V1BatchRequest,\n delivery: 'beacon'\n): V1BeaconPostRequest\nexport function buildV1EventsRequest(\n siteKey: string,\n endpoints: V1ValidatedEndpointSet,\n request: V1BatchRequest,\n delivery: 'normal' | 'beacon' = 'normal'\n): V1PostRequest {\n return buildPostRequest(siteKey, endpoints, 'events', request, delivery)\n}\n\n/** Builds a request from an already-authorized event endpoint snapshot. */\nexport function buildV1EventsRequestForEndpoint(\n siteKey: string,\n eventsEndpoint: string,\n request: V1BatchRequest,\n delivery: 'normal'\n): V1NormalPostRequest\nexport function buildV1EventsRequestForEndpoint(\n siteKey: string,\n eventsEndpoint: string,\n request: V1BatchRequest,\n delivery: 'beacon'\n): V1BeaconPostRequest\nexport function buildV1EventsRequestForEndpoint(\n siteKey: string,\n eventsEndpoint: string,\n request: V1BatchRequest,\n delivery: 'normal' | 'beacon'\n): V1PostRequest {\n const endpoint = validateV1EventsEndpoint(eventsEndpoint)\n return delivery === 'beacon'\n ? buildBeaconPostRequest(siteKey, endpoint, request)\n : buildNormalPostRequest(siteKey, endpoint, request)\n}\n\nexport function buildV1ReplayRequest(\n siteKey: string,\n endpoints: V1ValidatedEndpointSet,\n request: V1ReplayRequest\n): V1NormalPostRequest\nexport function buildV1ReplayRequest(\n siteKey: string,\n endpoints: V1ValidatedEndpointSet,\n request: V1ReplayRequest,\n delivery: 'normal'\n): V1NormalPostRequest\nexport function buildV1ReplayRequest(\n siteKey: string,\n endpoints: V1ValidatedEndpointSet,\n request: V1ReplayRequest,\n delivery: 'beacon'\n): V1BeaconPostRequest\nexport function buildV1ReplayRequest(\n siteKey: string,\n endpoints: V1ValidatedEndpointSet,\n request: V1ReplayRequest,\n delivery: 'normal' | 'beacon' = 'normal'\n): V1PostRequest {\n return buildPostRequest(siteKey, endpoints, 'replay', request, delivery)\n}\n\nexport const buildV1FlagsRequest = (\n siteKey: string,\n endpoints: V1ValidatedEndpointSet,\n request: V1FlagsRequest\n): V1NormalPostRequest => buildNormalPostRequest(siteKey, resolvePostEndpoint(endpoints, 'flags'), request)\n","import { freezeV1Value, isNullValue, isNumberValue, isStringValue, unicodeCodePointLength } from './validation'\n\nconst RFC3339_PATTERN = /^(\\d{4})-(\\d{2})-(\\d{2})[Tt](\\d{2}):(\\d{2}):(\\d{2})(?:\\.(\\d+))?(?:[Zz]|([+-])(\\d{2}):(\\d{2}))$/\nconst SECONDS_PER_DAY = 86_400\n\nexport interface V1ExactTimestamp {\n readonly source: string\n readonly epochDay: number\n readonly secondOfDay: number\n /** True when source used RFC 3339 second 60; secondOfDay names the preceding :59 second. */\n readonly leapSecond: boolean\n readonly fractionalDigits: string\n}\n\nconst fail = (field: string, message: string): never => {\n throw new Error(`${field} ${message}`)\n}\n\nconst daysInMonth = (year: number, month: number): number => {\n const date = new Date(0)\n date.setUTCFullYear(year, month, 0)\n return date.getUTCDate()\n}\n\nconst splitEpochSecond = (epochSecond: number): Readonly<{ epochDay: number; secondOfDay: number }> => {\n const epochDay = Math.floor(epochSecond / SECONDS_PER_DAY)\n return freezeV1Value({ epochDay, secondOfDay: epochSecond - epochDay * SECONDS_PER_DAY })\n}\n\nexport const parseV1ExactTimestamp = (\n value: unknown,\n field: string,\n maximumUnicodeScalars = 65_536\n): V1ExactTimestamp => {\n if (!isStringValue(value)) return fail(field, 'must be an RFC 3339 date-time string')\n const scalarLength = unicodeCodePointLength(value)\n if (isNullValue(scalarLength) || scalarLength < 1 || scalarLength > maximumUnicodeScalars) {\n return fail(field, `must contain between 1 and ${maximumUnicodeScalars} Unicode scalars`)\n }\n const match = RFC3339_PATTERN.exec(value)\n if (!match) return fail(field, 'must be an RFC 3339 date-time')\n const year = Number(match[1])\n const month = Number(match[2])\n const day = Number(match[3])\n const hour = Number(match[4])\n const minute = Number(match[5])\n const second = Number(match[6])\n const fractionalDigits = (match[7] ?? '').replace(/0+$/, '')\n const offsetHour = match[9] ? Number(match[9]) : 0\n const offsetMinute = match[10] ? Number(match[10]) : 0\n if (\n month < 1 ||\n month > 12 ||\n day < 1 ||\n day > daysInMonth(year, month) ||\n hour > 23 ||\n minute > 59 ||\n second > 60 ||\n offsetHour > 23 ||\n offsetMinute > 59\n ) {\n fail(field, 'must be a valid RFC 3339 date-time')\n }\n\n const local = new Date(0)\n local.setUTCFullYear(year, month - 1, day)\n local.setUTCHours(hour, minute, Math.min(second, 59), 0)\n const localEpochSecond = local.getTime() / 1000\n const offsetDirection = match[8] === '-' ? -1 : 1\n const offsetSeconds = offsetDirection * (offsetHour * 60 + offsetMinute) * 60\n const epochSecond = localEpochSecond - offsetSeconds\n if (!isNumberValue(epochSecond) || !Number.isSafeInteger(epochSecond)) {\n fail(field, 'is outside the supported epoch range')\n }\n\n const leapSecond = second === 60\n if (leapSecond) {\n const nextUtcSecond = new Date((epochSecond + 1) * 1000)\n const isLeapBoundary =\n nextUtcSecond.getUTCHours() === 0 &&\n nextUtcSecond.getUTCMinutes() === 0 &&\n nextUtcSecond.getUTCSeconds() === 0 &&\n nextUtcSecond.getUTCDate() === 1 &&\n (nextUtcSecond.getUTCMonth() === 0 || nextUtcSecond.getUTCMonth() === 6)\n if (!isLeapBoundary) fail(field, 'must use second 60 only at a shifted UTC June or December leap boundary')\n }\n\n const split = splitEpochSecond(epochSecond)\n return freezeV1Value({ source: value, ...split, leapSecond, fractionalDigits })\n}\n\nexport const compareV1ExactTimestamps = (left: V1ExactTimestamp, right: V1ExactTimestamp): number => {\n if (left.epochDay !== right.epochDay) return left.epochDay < right.epochDay ? -1 : 1\n if (left.secondOfDay !== right.secondOfDay) return left.secondOfDay < right.secondOfDay ? -1 : 1\n if (left.leapSecond !== right.leapSecond) return left.leapSecond ? 1 : -1\n const maximumDigits = Math.max(left.fractionalDigits.length, right.fractionalDigits.length)\n for (let index = 0; index < maximumDigits; index += 1) {\n const leftDigit = left.fractionalDigits.charCodeAt(index) || 48\n const rightDigit = right.fractionalDigits.charCodeAt(index) || 48\n if (leftDigit !== rightDigit) return leftDigit < rightDigit ? -1 : 1\n }\n return 0\n}\n\nexport const v1ExactTimestampToApproximateMs = (value: V1ExactTimestamp): number =>\n (value.epochDay * SECONDS_PER_DAY + value.secondOfDay + (value.leapSecond ? 1 : 0)) * 1000 +\n Number((value.fractionalDigits + '000').slice(0, 3))\n\nexport const assertV1WallNow = (nowMs: number, field = 'nowMs'): void => {\n if (!isNumberValue(nowMs) || !Number.isSafeInteger(nowMs) || !Number.isFinite(new Date(nowMs).getTime())) {\n fail(field, 'must be a valid integer epoch timestamp')\n }\n}\n\nexport const v1ExactTimestampFromEpochMs = (nowMs: number, field = 'nowMs'): V1ExactTimestamp => {\n assertV1WallNow(nowMs, field)\n const epochSecond = Math.floor(nowMs / 1000)\n const milliseconds = nowMs - epochSecond * 1000\n const split = splitEpochSecond(epochSecond)\n return freezeV1Value({\n source: new Date(nowMs).toISOString(),\n ...split,\n leapSecond: false,\n fractionalDigits: String(milliseconds).padStart(3, '0').replace(/0+$/, ''),\n })\n}\n\nexport const sameV1ExactTimestamp = (left: V1ExactTimestamp, right: V1ExactTimestamp): boolean =>\n compareV1ExactTimestamps(left, right) === 0\n","import type { V1ActivePolicyProjection, V1ReplayTransportSelection, V1Sha256 } from './config-manager'\nimport { V1_MAX_PRIVACY_STATE_BYTES } from './config-manager'\nimport { parseV1ExactTimestamp } from './exact-timestamp'\nimport { parseV1StrictCanonicalJson } from './strict-canonical-json'\nimport {\n freezeV1Value,\n hasOnlyKeys,\n hasOwn,\n isBooleanValue,\n isFunctionValue,\n isNonNegativeInteger,\n isNullValue,\n isRecordValue,\n isStringValue,\n} from './validation'\n\nexport const V1_EU_TIMEZONE_EVALUATOR = 'elu-eu-timezone-v1'\n\n/**\n * EU/EEA territories whose IANA zone does not sit under the `Europe/` prefix. Together with that\n * prefix this is the complete `elu-eu-timezone-v1` block set shared by every platform; it knowingly\n * over-blocks some non-EU European zones so all platforms decide identically.\n */\nexport const V1_EU_TIMEZONE_EXTRAS: readonly string[] = freezeV1Value([\n 'Asia/Nicosia',\n 'Asia/Famagusta',\n 'Atlantic/Canary',\n 'Atlantic/Madeira',\n 'Atlantic/Azores',\n 'Atlantic/Reykjavik',\n 'Atlantic/Faroe',\n 'Africa/Ceuta',\n 'America/Cayenne',\n 'America/Guadeloupe',\n 'America/Martinique',\n 'Indian/Reunion',\n 'Indian/Mayotte',\n])\n\nconst EU_TIMEZONE_PREFIX = 'Europe/'\nconst SHA256_HEX_PATTERN = /^[a-fA-F0-9]{64}$/\n\nexport type V1RegionDecision = 'allow' | 'block'\n\nexport interface V1OnDeviceDecision {\n readonly decision: 'allow' | 'block' | 'unknown'\n readonly source: 'not-evaluated' | 'device-region' | 'local-consent' | 'remote-kill-switch'\n readonly reason?: string\n readonly evaluatedAt?: string\n}\n\nexport interface V1EffectiveMasking {\n readonly text: 'all' | 'sensitive'\n readonly inputs: 'all' | 'sensitive'\n readonly images: 'block' | 'allow'\n readonly secureInputsMasked: true\n readonly platformFallbackApplied: boolean\n}\n\nexport interface V1PrivacyIdentityWitness {\n readonly contextRevision: number\n readonly optedOut: boolean\n}\n\nexport interface V1PrivacyReplayInputs {\n readonly sampled: boolean\n readonly maskingValidated: boolean\n readonly sessionEligible: boolean\n readonly budgetRemainingSeconds: number\n readonly transport: V1ReplayTransportSelection | null\n}\n\nexport interface V1PrivacyStateInput {\n readonly policy: V1ActivePolicyProjection\n readonly identity: V1PrivacyIdentityWitness\n readonly onDeviceDecision: V1OnDeviceDecision\n readonly replay: V1PrivacyReplayInputs\n}\n\nexport interface V1ProducedPrivacyState {\n /** Exact document bytes to hand to config authorization and capture-authority submission. */\n readonly document: string\n readonly effectivePolicyHash: `sha256:${string}`\n readonly captureAllowed: boolean\n readonly replayAllowed: boolean\n readonly onDeviceDecision: V1OnDeviceDecision\n readonly effectiveMasking: V1EffectiveMasking\n}\n\n/** Replay inputs for a runtime without a recorder: every replay condition is false and no transport is selected. */\nexport const V1_NO_REPLAY_CAPABILITY: V1PrivacyReplayInputs = freezeV1Value({\n sampled: false,\n maskingValidated: false,\n sessionEligible: false,\n budgetRemainingSeconds: 0,\n transport: null,\n})\n\nexport class V1PrivacyStateError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'V1PrivacyStateError'\n }\n}\n\nconst fail = (message: string): never => {\n throw new V1PrivacyStateError(message)\n}\n\n/**\n * The `elu-eu-timezone-v1` decision. An empty or unreadable zone blocks: the evaluator fails closed\n * rather than guessing, and only an exact allowlisted comparison lets capture proceed.\n */\nexport const evaluateV1EuTimezone = (timeZone: unknown): V1RegionDecision => {\n if (!isStringValue(timeZone) || timeZone.length === 0) return 'block'\n if (timeZone.startsWith(EU_TIMEZONE_PREFIX)) return 'block'\n if (V1_EU_TIMEZONE_EXTRAS.includes(timeZone)) return 'block'\n return 'allow'\n}\n\n/** Reads the IANA zone the browser resolves for this device, or null when it cannot be read. */\nexport const readV1BrowserTimeZone = (): string | null => {\n try {\n const intl = typeof globalThis === 'undefined' ? undefined : globalThis.Intl\n if (!intl || !isFunctionValue(intl.DateTimeFormat)) return null\n const zone = intl.DateTimeFormat().resolvedOptions().timeZone\n return isStringValue(zone) && zone.length > 0 ? zone : null\n } catch {\n return null\n }\n}\n\nconst assertEvaluatedAt = (value: string): string =>\n parseV1ExactTimestamp(value, 'privacy decision evaluatedAt', V1_MAX_PRIVACY_STATE_BYTES).source\n\n/**\n * Applies the server region policy on the device. `allow` needs no evaluation, `block` is a remote\n * decision the device only records, and `block-eu-on-device` runs the timezone evaluator against the\n * supplied zone at the supplied wall time.\n */\nexport const evaluateV1RegionPolicy = (\n mode: V1ActivePolicyProjection['privacy']['regionMode'],\n timeZone: string | null,\n evaluatedAt: string\n): V1OnDeviceDecision => {\n const at = assertEvaluatedAt(evaluatedAt)\n switch (mode) {\n case 'allow':\n return freezeV1Value({ decision: 'allow', source: 'not-evaluated' })\n case 'block':\n return freezeV1Value({\n decision: 'block',\n source: 'remote-kill-switch',\n reason: 'regional-policy',\n evaluatedAt: at,\n })\n case 'block-eu-on-device': {\n const decision = evaluateV1EuTimezone(timeZone)\n return decision === 'allow'\n ? freezeV1Value({ decision, source: 'device-region', evaluatedAt: at })\n : freezeV1Value({ decision, source: 'device-region', reason: 'regional-policy', evaluatedAt: at })\n }\n default:\n return fail('privacy region mode is unsupported')\n }\n}\n\n/**\n * Projects the server masking policy onto what this browser can enforce. When a policy rule uses a\n * dialect the browser cannot interpret, the equal-or-stricter fallback masks everything instead of\n * silently applying a partial profile; otherwise the policy profile applies as served. Secure inputs\n * are masked under every profile.\n */\nexport const projectV1BrowserMasking = (privacy: V1ActivePolicyProjection['privacy']): V1EffectiveMasking =>\n privacy.requiresBrowserPlatformFallback\n ? freezeV1Value({\n text: 'all',\n inputs: 'all',\n images: 'block',\n secureInputsMasked: true,\n platformFallbackApplied: true,\n })\n : freezeV1Value({\n text: privacy.masking.text,\n inputs: privacy.masking.inputs,\n images: privacy.masking.images,\n secureInputsMasked: true,\n platformFallbackApplied: false,\n })\n\nconst validateDecision = (value: V1OnDeviceDecision): V1OnDeviceDecision => {\n const record = value as unknown\n if (!isRecordValue(record) || !hasOnlyKeys(record, ['decision', 'source', 'reason', 'evaluatedAt'])) {\n return fail('privacy on-device decision contains an unsupported field')\n }\n if (record.decision !== 'allow' && record.decision !== 'block' && record.decision !== 'unknown') {\n return fail('privacy on-device decision is unsupported')\n }\n if (\n record.source !== 'not-evaluated' &&\n record.source !== 'device-region' &&\n record.source !== 'local-consent' &&\n record.source !== 'remote-kill-switch'\n ) {\n return fail('privacy on-device decision source is unsupported')\n }\n if (hasOwn(record, 'reason') && (!isStringValue(record.reason) || record.reason.length > 256)) {\n return fail('privacy on-device decision reason must be a string of at most 256 characters')\n }\n if (hasOwn(record, 'evaluatedAt')) {\n if (!isStringValue(record.evaluatedAt)) return fail('privacy on-device decision evaluatedAt must be a string')\n assertEvaluatedAt(record.evaluatedAt)\n }\n return freezeV1Value({\n decision: record.decision,\n source: record.source,\n ...(hasOwn(record, 'reason') ? { reason: record.reason as string } : {}),\n ...(hasOwn(record, 'evaluatedAt') ? { evaluatedAt: record.evaluatedAt as string } : {}),\n })\n}\n\nconst validateIdentityWitness = (value: V1PrivacyIdentityWitness): V1PrivacyIdentityWitness => {\n const record = value as unknown\n if (!isRecordValue(record) || !hasOnlyKeys(record, ['contextRevision', 'optedOut'])) {\n return fail('privacy identity witness contains an unsupported field')\n }\n if (!isNonNegativeInteger(record.contextRevision)) {\n return fail('privacy identity witness contextRevision must be a non-negative safe integer')\n }\n if (!isBooleanValue(record.optedOut)) return fail('privacy identity witness optedOut must be a boolean')\n return freezeV1Value({ contextRevision: record.contextRevision, optedOut: record.optedOut })\n}\n\nconst validateReplayInputs = (value: V1PrivacyReplayInputs): V1PrivacyReplayInputs => {\n const record = value as unknown\n if (\n !isRecordValue(record) ||\n !hasOnlyKeys(record, ['sampled', 'maskingValidated', 'sessionEligible', 'budgetRemainingSeconds', 'transport'])\n ) {\n return fail('privacy replay inputs contain an unsupported field')\n }\n if (\n !isBooleanValue(record.sampled) ||\n !isBooleanValue(record.maskingValidated) ||\n !isBooleanValue(record.sessionEligible)\n ) {\n return fail('privacy replay gates must be booleans')\n }\n if (!isNonNegativeInteger(record.budgetRemainingSeconds) || record.budgetRemainingSeconds > 86_400) {\n return fail('privacy replay budget must be an integer between 0 and 86400 seconds')\n }\n let transport: V1ReplayTransportSelection | null = null\n if (!isNullValue(record.transport)) {\n const selection = record.transport\n if (!isRecordValue(selection) || !hasOnlyKeys(selection, ['codec', 'compression'])) {\n return fail('privacy replay transport contains an unsupported field')\n }\n if (!isStringValue(selection.codec) || (selection.compression !== 'none' && selection.compression !== 'gzip')) {\n return fail('privacy replay transport is invalid')\n }\n transport = freezeV1Value({ codec: selection.codec, compression: selection.compression })\n }\n return freezeV1Value({\n sampled: record.sampled,\n maskingValidated: record.maskingValidated,\n sessionEligible: record.sessionEligible,\n budgetRemainingSeconds: record.budgetRemainingSeconds,\n transport,\n })\n}\n\nconst isAdvertisedTransport = (\n policy: V1ActivePolicyProjection,\n transport: V1ReplayTransportSelection | null\n): transport is V1ReplayTransportSelection =>\n !isNullValue(transport) &&\n policy.replayTransports.some(\n (candidate) => candidate.codec === transport.codec && candidate.compression === transport.compression\n )\n\n/**\n * Produces the effective on-device privacy document for one policy, identity witness, region\n * decision, and replay conditions. The derived allow booleans follow the contract exactly, the\n * masking profile is the browser projection, and `effectivePolicyHash` covers the canonical form of\n * every other member, so config authorization can recompute and compare it byte for byte.\n */\nexport const produceV1PrivacyState = async (\n input: V1PrivacyStateInput,\n sha256: V1Sha256\n): Promise<V1ProducedPrivacyState> => {\n const record = input as unknown\n if (!isRecordValue(record) || !hasOnlyKeys(record, ['policy', 'identity', 'onDeviceDecision', 'replay'])) {\n return fail('privacy state input contains an unsupported field')\n }\n if (!isFunctionValue(sha256)) return fail('privacy state producer requires a sha256 function')\n const policy = input.policy\n if (!isRecordValue(policy) || !isRecordValue(policy.privacy) || !isRecordValue(policy.features)) {\n return fail('privacy state input policy projection is invalid')\n }\n const identity = validateIdentityWitness(input.identity)\n const onDeviceDecision = validateDecision(input.onDeviceDecision)\n const replay = validateReplayInputs(input.replay)\n const effectiveMasking = projectV1BrowserMasking(policy.privacy)\n\n const captureAllowed =\n policy.features.capture &&\n policy.privacy.captureEnabled &&\n onDeviceDecision.decision === 'allow' &&\n !identity.optedOut\n const advertised = isAdvertisedTransport(policy, replay.transport)\n const replayAllowed =\n captureAllowed &&\n policy.features.replay &&\n policy.privacy.replayEnabled &&\n replay.sampled &&\n replay.maskingValidated &&\n replay.sessionEligible &&\n replay.budgetRemainingSeconds > 0 &&\n advertised\n\n const withoutHash: Record<string, unknown> = {\n schemaVersion: 1,\n policyRevision: policy.privacy.revision,\n contextRevision: identity.contextRevision,\n onDeviceDecision: { ...onDeviceDecision },\n captureAllowed,\n replayAllowed,\n replaySampled: replay.sampled,\n identityOptedOut: identity.optedOut,\n maskingValidated: replay.maskingValidated,\n replaySessionEligible: replay.sessionEligible,\n replayBudgetRemainingSeconds: replay.budgetRemainingSeconds,\n replayTransport:\n advertised && replay.transport\n ? { codec: replay.transport.codec, compression: replay.transport.compression, advertised: true }\n : null,\n effectiveMasking: { ...effectiveMasking },\n }\n let canonical: string\n try {\n canonical = parseV1StrictCanonicalJson(\n JSON.stringify(withoutHash),\n V1_MAX_PRIVACY_STATE_BYTES,\n 'privacy state'\n ).canonical\n } catch (error) {\n return fail(error instanceof Error ? error.message : 'privacy state could not be canonicalized')\n }\n let digest: unknown\n try {\n digest = await sha256(canonical)\n } catch {\n digest = null\n }\n if (!isStringValue(digest) || !SHA256_HEX_PATTERN.test(digest)) {\n return fail('privacy state hash is unavailable')\n }\n const effectivePolicyHash = `sha256:${digest.toLowerCase()}` as const\n const document = JSON.stringify({ ...withoutHash, effectivePolicyHash })\n const verified = parseV1StrictCanonicalJson(document, V1_MAX_PRIVACY_STATE_BYTES, 'privacy state')\n if (verified.objectWithoutPropertyCanonical('effectivePolicyHash') !== canonical) {\n return fail('privacy state hash does not cover the produced document')\n }\n return freezeV1Value({\n document,\n effectivePolicyHash,\n captureAllowed,\n replayAllowed,\n onDeviceDecision,\n effectiveMasking,\n })\n}\n","import type { V2MaskingProfile } from './types'\n\n/**\n * The second redaction, applied to every recorded event before it is sealed.\n *\n * The recorder is already configured from the same profile, so in the ordinary case this finds\n * nothing left to remove. It exists because \"the recorder was configured correctly\" is an\n * assumption, and a sealed payload should not depend on one: this pass removes the categories the\n * profile forbids whatever the recorder did, so the proof describes bytes that were redacted here.\n *\n * It is a deny pass, not a verifier. It cannot tell masked text from text that happens to look\n * masked, and it does not try — it removes.\n */\n\n/** rrweb serialized node kinds. Numeric, because that is what travels on the wire. */\nconst NODE_TYPE_ELEMENT = 2\nconst NODE_TYPE_TEXT = 3\nconst NODE_TYPE_COMMENT = 5\n\n/** rrweb event kinds and mutation sources, likewise numeric on the wire. */\nconst EVENT_TYPE_FULL_SNAPSHOT = 2\nconst EVENT_TYPE_INCREMENTAL = 3\nconst INCREMENTAL_SOURCE_MUTATION = 0\nconst INCREMENTAL_SOURCE_INPUT = 5\n\n/** Input types whose value is sensitive even when the policy only masks sensitive inputs. */\nconst SENSITIVE_INPUT_TYPES = new Set(['password', 'email', 'tel', 'hidden'])\n\n/** Attributes that carry an image's content rather than its layout. */\nconst IMAGE_CONTENT_ATTRIBUTES = ['src', 'srcset']\n\nconst IMAGE_TAG_NAMES = new Set(['img', 'picture', 'source'])\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === 'object' && value !== null && !Array.isArray(value)\n\nconst maskAttributes = (\n tagName: string,\n attributes: Record<string, unknown>,\n profile: V2MaskingProfile\n): Record<string, unknown> => {\n const masked: Record<string, unknown> = { ...attributes }\n const inputType = typeof masked.type === 'string' ? masked.type.toLowerCase() : ''\n const maskValue =\n profile.inputRule === 'all' || SENSITIVE_INPUT_TYPES.has(inputType) || tagName === 'textarea'\n if (maskValue && 'value' in masked) {\n delete masked.value\n }\n if (profile.imageRule === 'block' && IMAGE_TAG_NAMES.has(tagName)) {\n for (const attribute of IMAGE_CONTENT_ATTRIBUTES) {\n if (attribute in masked) delete masked[attribute]\n }\n }\n return masked\n}\n\n/** Recursively redacts one serialized node and everything under it. */\nconst maskNode = (node: unknown, profile: V2MaskingProfile): unknown => {\n if (!isRecord(node)) return node\n const masked: Record<string, unknown> = { ...node }\n const type = masked.type\n\n if (type === NODE_TYPE_COMMENT) {\n // A comment is never replayed and can carry anything a template put there.\n masked.textContent = ''\n } else if (type === NODE_TYPE_TEXT && profile.textRule === 'all') {\n // Style text is not customer content and blanking it breaks the rendered replay.\n if (masked.isStyle !== true) masked.textContent = ''\n } else if (type === NODE_TYPE_ELEMENT) {\n const tagName = typeof masked.tagName === 'string' ? masked.tagName.toLowerCase() : ''\n if (isRecord(masked.attributes)) {\n masked.attributes = maskAttributes(tagName, masked.attributes, profile)\n }\n }\n\n if (Array.isArray(masked.childNodes)) {\n masked.childNodes = masked.childNodes.map((child) => maskNode(child, profile))\n }\n return masked\n}\n\nconst maskMutation = (data: Record<string, unknown>, profile: V2MaskingProfile): Record<string, unknown> => {\n const masked: Record<string, unknown> = { ...data }\n if (profile.textRule === 'all' && Array.isArray(masked.texts)) {\n masked.texts = masked.texts.map((text) => (isRecord(text) ? { ...text, value: '' } : text))\n }\n if (Array.isArray(masked.attributes)) {\n masked.attributes = masked.attributes.map((entry) => {\n if (!isRecord(entry) || !isRecord(entry.attributes)) return entry\n // A mutation names no tag, so the value rule is applied at its broadest here.\n return { ...entry, attributes: maskAttributes('', entry.attributes, profile) }\n })\n }\n if (Array.isArray(masked.adds)) {\n masked.adds = masked.adds.map((add) =>\n isRecord(add) ? { ...add, node: maskNode(add.node, profile) } : add\n )\n }\n return masked\n}\n\n/**\n * The masker the sealing stage runs over every event. Pure: it copies what it changes and returns\n * the input untouched when there is nothing of the forbidden kind in it.\n */\nexport const maskV2BrowserDomEvent = (event: unknown, profile: V2MaskingProfile): unknown => {\n if (!isRecord(event)) return event\n const data = event.data\n if (!isRecord(data)) return event\n\n if (event.type === EVENT_TYPE_FULL_SNAPSHOT) {\n return { ...event, data: { ...data, node: maskNode(data.node, profile) } }\n }\n if (event.type !== EVENT_TYPE_INCREMENTAL) {\n return event\n }\n if (data.source === INCREMENTAL_SOURCE_MUTATION) {\n return { ...event, data: maskMutation(data, profile) }\n }\n if (data.source === INCREMENTAL_SOURCE_INPUT) {\n // The typed value. Masked whenever inputs are, and always for a sensitive field.\n const masked: Record<string, unknown> = { ...data }\n if (profile.inputRule === 'all' && typeof masked.text === 'string') masked.text = ''\n return { ...event, data: masked }\n }\n return event\n}\n","import { isStringValue } from '../validation'\nimport type { V2ReplaySha256, V2Sha256Hash } from './types'\n\nconst SHA256_HEX_PATTERN = /^[a-f0-9]{64}$/\n\n/** Lowercase-hex SHA-256 over the Web Crypto API; null when no digest provider is available. */\nexport const defaultV2ReplaySha256: V2ReplaySha256 = async (value) => {\n const cryptoApi = typeof globalThis === 'undefined' ? undefined : globalThis.crypto\n if (!cryptoApi?.subtle) {\n return null\n }\n try {\n const digest = await cryptoApi.subtle.digest('SHA-256', value)\n let hexadecimal = ''\n for (const byte of new Uint8Array(digest)) {\n hexadecimal += byte.toString(16).padStart(2, '0')\n }\n return hexadecimal\n } catch {\n return null\n }\n}\n\nexport const sha256Hex = async (value: Uint8Array, sha256: V2ReplaySha256 = defaultV2ReplaySha256): Promise<string> => {\n const digest = await sha256(value)\n if (!isStringValue(digest) || !SHA256_HEX_PATTERN.test(digest.toLowerCase())) {\n throw new Error('SHA-256 digest generation is unavailable')\n }\n return digest.toLowerCase()\n}\n\nexport const isV2Sha256Hash = (value: unknown): value is V2Sha256Hash =>\n isStringValue(value) && /^sha256:[a-f0-9]{64}$/.test(value)\n\nexport const utf8Encode = (value: string): Uint8Array => new TextEncoder().encode(value)\n\n/** Strict UTF-8 decode; malformed bytes throw rather than becoming replacement characters. */\nexport const utf8Decode = (value: Uint8Array): string => new TextDecoder('utf-8', { fatal: true }).decode(value)\n","import type { V2ReplayPayloadAdmissionCode } from './types'\n\n/**\n * A replay payload that cannot be admitted. Every code is a permanent local rejection: the bytes are\n * never persisted, retried, or acknowledged.\n */\nexport class V2ReplayPayloadAdmissionError extends Error {\n readonly code: V2ReplayPayloadAdmissionCode\n\n constructor(code: V2ReplayPayloadAdmissionCode, message: string) {\n super(message)\n this.name = 'V2ReplayPayloadAdmissionError'\n this.code = code\n }\n}\n\nexport class V2MaskingProfileError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'V2MaskingProfileError'\n }\n}\n\nexport class V2MaskingProofError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'V2MaskingProofError'\n }\n}\n\nexport class V2ReplayRequestError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'V2ReplayRequestError'\n }\n}\n\nexport class V2ReplayAcknowledgementError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'V2ReplayAcknowledgementError'\n }\n}\n","import { parseV1StrictCanonicalJson, V1StrictJsonError } from '../strict-canonical-json'\nimport {\n freezeV1Value,\n hasOwnIndex,\n isArrayValue,\n isFunctionValue,\n isNullValue,\n unicodeCodePointLength,\n utf8ByteLength,\n} from '../validation'\nimport { utf8Encode } from './digest'\nimport { V2ReplayPayloadAdmissionError } from './errors'\nimport type { V2ReplayPayloadLimits } from './types'\n\n/** Engine-side ceilings for one decoded replay payload. */\nexport const V2_REPLAY_MAX_DECODED_BYTES = 16_777_216\nexport const V2_REPLAY_MAX_LOGICAL_RECORDS = 10_000\nexport const V2_REPLAY_MAX_JSON_NESTING_DEPTH = 256\n\nexport const V2_REPLAY_PAYLOAD_LIMITS: V2ReplayPayloadLimits = freezeV1Value({\n maximumReplayDecodedBytes: V2_REPLAY_MAX_DECODED_BYTES,\n maximumReplayLogicalRecords: V2_REPLAY_MAX_LOGICAL_RECORDS,\n maximumJsonNestingDepth: V2_REPLAY_MAX_JSON_NESTING_DEPTH,\n})\n\nexport interface V2CanonicalReplayRecords {\n readonly canonical: string\n readonly bytes: Uint8Array\n readonly logicalRecords: number\n readonly nestingDepth: number\n}\n\nexport interface V2AdmittedReplayRecords {\n readonly records: readonly unknown[]\n readonly logicalRecords: number\n readonly nestingDepth: number\n}\n\nfunction fail(code: V2ReplayPayloadAdmissionError['code'], message: string): never {\n throw new V2ReplayPayloadAdmissionError(code, message)\n}\n\nconst isPlainObject = (value: object): value is Record<string, unknown> => {\n const prototype = Object.getPrototypeOf(value)\n return isNullValue(prototype) || prototype === Object.prototype\n}\n\nconst assertUnicode = (value: string, path: string): void => {\n if (isNullValue(unicodeCodePointLength(value))) {\n fail('invalid-unicode', `${path} contains an unpaired Unicode surrogate`)\n }\n}\n\n/** Serialization semantics for values JSON cannot carry: omitted as object members, null as array elements. */\nconst isOmittedValue = (value: unknown): boolean =>\n typeof value === 'undefined' || isFunctionValue(value) || typeof value === 'symbol'\n\ninterface CanonicalWalk {\n depth: number\n}\n\nconst walk = (\n value: unknown,\n depth: number,\n path: string,\n maximumNestingDepth: number,\n state: CanonicalWalk\n): string => {\n if (isNullValue(value)) return 'null'\n switch (typeof value) {\n case 'string':\n assertUnicode(value, path)\n return JSON.stringify(value)\n case 'number':\n if (!Number.isFinite(value)) fail('invalid-codec-json', `${path} must be a finite number`)\n // ECMAScript number formatting is the binary64 fallback of elu-canonical-json-v1; -0 prints as 0.\n return JSON.stringify(value)\n case 'boolean':\n return value ? 'true' : 'false'\n case 'object':\n break\n default:\n return fail('invalid-codec-json', `${path} has an unsupported ${typeof value} value`)\n }\n\n const containerDepth = depth + 1\n if (containerDepth > maximumNestingDepth) {\n fail('json-nesting-limit', `${path} exceeds the maximum JSON nesting depth of ${maximumNestingDepth}`)\n }\n if (containerDepth > state.depth) state.depth = containerDepth\n\n if (isArrayValue(value)) {\n const parts: string[] = []\n for (let index = 0; index < value.length; index += 1) {\n if (!hasOwnIndex(value, index)) fail('invalid-codec-json', `${path}[${index}] is a sparse array hole`)\n const element = value[index]\n parts.push(\n isOmittedValue(element)\n ? 'null'\n : walk(element, containerDepth, `${path}[${index}]`, maximumNestingDepth, state)\n )\n }\n return `[${parts.join(',')}]`\n }\n if (!isPlainObject(value as object)) {\n return fail('invalid-codec-json', `${path} must be a plain JSON object or array`)\n }\n const record = value as Record<string, unknown>\n const keys = Object.keys(record).sort()\n const members: string[] = []\n for (const key of keys) {\n const member = record[key]\n if (isOmittedValue(member)) continue\n assertUnicode(key, `${path}.${key}`)\n members.push(\n `${JSON.stringify(key)}:${walk(member, containerDepth, `${path}.${key}`, maximumNestingDepth, state)}`\n )\n }\n return `{${members.join(',')}}`\n}\n\n/**\n * Canonicalizes an in-memory JSON value: members sorted by UTF-16 code unit order, no whitespace,\n * ECMAScript number formatting, and a container nesting ceiling counted from the root container.\n */\nexport const canonicalV2JsonValue = (\n value: unknown,\n field: string,\n maximumNestingDepth: number = V2_REPLAY_MAX_JSON_NESTING_DEPTH\n): string => {\n if (isOmittedValue(value)) fail('invalid-codec-json', `${field} must be a JSON value`)\n return walk(value, 0, field, maximumNestingDepth, { depth: 0 })\n}\n\n/** Canonical UTF-8 bytes of an ordered array of masked replay records, bounded by the payload limits. */\nexport const canonicalV2ReplayRecords = (\n records: unknown,\n field: string,\n limits: V2ReplayPayloadLimits = V2_REPLAY_PAYLOAD_LIMITS\n): V2CanonicalReplayRecords => {\n if (!isArrayValue(records)) fail('invalid-codec-shape', `${field} must be an array of replay records`)\n if (records.length > limits.maximumReplayLogicalRecords) {\n fail(\n 'logical-record-limit',\n `${field} carries ${records.length} records; the maximum is ${limits.maximumReplayLogicalRecords}`\n )\n }\n const state: CanonicalWalk = { depth: 0 }\n const canonical = walk(records, 0, field, limits.maximumJsonNestingDepth, state)\n const byteLength = utf8ByteLength(canonical)\n if (byteLength > limits.maximumReplayDecodedBytes) {\n fail(\n 'decoded-byte-limit',\n `${field} serializes to ${byteLength} bytes; the maximum is ${limits.maximumReplayDecodedBytes}`\n )\n }\n return freezeV1Value({\n canonical,\n bytes: utf8Encode(canonical),\n logicalRecords: records.length,\n nestingDepth: state.depth,\n })\n}\n\nconst measureNestingDepth = (value: unknown, depth: number): number => {\n if (isNullValue(value) || typeof value !== 'object') return depth\n let deepest = depth + 1\n const children = isArrayValue(value)\n ? value\n : Object.keys(value).map((key) => (value as Record<string, unknown>)[key])\n for (const child of children) {\n const measured = measureNestingDepth(child, depth + 1)\n if (measured > deepest) deepest = measured\n }\n return deepest\n}\n\n/**\n * Admits decoded payload text the way the engine does: strict JSON, no duplicate keys, canonical\n * bytes only, a top-level array, and the nesting and record ceilings.\n */\nexport const admitV2CanonicalPayloadText = (\n text: string,\n limits: V2ReplayPayloadLimits = V2_REPLAY_PAYLOAD_LIMITS\n): V2AdmittedReplayRecords => {\n let parsed\n try {\n parsed = parseV1StrictCanonicalJson(\n text,\n limits.maximumReplayDecodedBytes,\n 'replay payload',\n limits.maximumJsonNestingDepth\n )\n } catch (error) {\n const reason = error instanceof V1StrictJsonError ? error.reason : 'syntax'\n const message = error instanceof Error ? error.message : 'replay payload is not strict JSON'\n if (reason === 'nesting-depth') fail('json-nesting-limit', message)\n if (reason === 'unicode') fail('invalid-unicode', message)\n if (reason === 'size') fail('decoded-byte-limit', message)\n return fail('invalid-codec-json', message)\n }\n if (!isArrayValue(parsed.value)) fail('invalid-codec-shape', 'replay payload must be a JSON array')\n if (parsed.canonical !== text) fail('noncanonical-codec-json', 'replay payload is not canonical JSON')\n const records = parsed.value as readonly unknown[]\n if (records.length > limits.maximumReplayLogicalRecords) {\n fail(\n 'logical-record-limit',\n `replay payload carries ${records.length} records; the maximum is ${limits.maximumReplayLogicalRecords}`\n )\n }\n return freezeV1Value({\n records,\n logicalRecords: records.length,\n nestingDepth: measureNestingDepth(records, 0),\n })\n}\n","import {\n freezeV1Value,\n hasOnlyKeys,\n hasOwn,\n hasOwnIndex,\n isArrayValue,\n isBooleanValue,\n isNullValue,\n isRecordValue,\n isStringValue,\n unicodeCodePointLength,\n} from '../validation'\nimport { canonicalV2JsonValue } from './canonical-payload-json'\nimport { sha256Hex, utf8Encode } from './digest'\nimport { V2MaskingProfileError } from './errors'\nimport type {\n V2MaskingImageRule,\n V2MaskingInputRule,\n V2MaskingInvalidationAction,\n V2MaskingProfile,\n V2MaskingRequirementComparison,\n V2MaskingTextRule,\n V2ReplaySha256,\n V2Sha256Hash,\n} from './types'\n\nexport const V2_MASKING_PROFILE_SCHEMA_VERSION = 1\nexport const V2_BROWSER_MASKING_DIALECT = 'elu-css-selector-v1'\nexport const V2_MASKING_MAX_SELECTORS = 128\nexport const V2_MASKING_MAX_SELECTOR_LENGTH = 512\n\nconst PROFILE_KEYS = [\n 'schemaVersion',\n 'targetDialect',\n 'textRule',\n 'inputRule',\n 'imageRule',\n 'secureInputsMasked',\n 'platformFallbackApplied',\n 'resolvedMaskSelectors',\n 'resolvedBlockSelectors',\n] as const\nconst POLICY_MASKING_KEYS = ['text', 'inputs', 'images', 'secureInputsMasked', 'platformRules'] as const\nconst PLATFORM_RULE_KEYS = ['platform', 'action', 'targetDialect', 'target'] as const\nconst TEXT_RULES: readonly V2MaskingTextRule[] = ['all', 'sensitive']\nconst INPUT_RULES: readonly V2MaskingInputRule[] = ['all', 'sensitive']\nconst IMAGE_RULES: readonly V2MaskingImageRule[] = ['block', 'allow']\n\nfunction fail(message: string): never {\n throw new V2MaskingProfileError(message)\n}\n\nconst assertRule = <T extends string>(value: unknown, allowed: readonly T[], field: string): T => {\n if (!isStringValue(value) || !allowed.includes(value as T)) {\n fail(`${field} must be one of ${allowed.join(', ')}`)\n }\n return value as T\n}\n\nconst assertSelector = (value: unknown, field: string): string => {\n const length = isStringValue(value) ? unicodeCodePointLength(value) : null\n if (isNullValue(length) || length < 1 || length > V2_MASKING_MAX_SELECTOR_LENGTH) {\n return fail(`${field} must be a selector of 1 to ${V2_MASKING_MAX_SELECTOR_LENGTH} Unicode scalars`)\n }\n return value as string\n}\n\n/** Sorted by UTF-16 code unit order with duplicates removed, so equal rule sets canonicalize identically. */\nconst normalizeSelectors = (values: unknown, field: string): readonly string[] => {\n if (!isArrayValue(values)) fail(`${field} must be an array of selectors`)\n const selectors = new Set<string>()\n for (let index = 0; index < values.length; index += 1) {\n if (!hasOwnIndex(values, index)) fail(`${field} must not be sparse`)\n selectors.add(assertSelector(values[index], `${field}[${index}]`))\n }\n if (selectors.size > V2_MASKING_MAX_SELECTORS) {\n fail(`${field} may carry at most ${V2_MASKING_MAX_SELECTORS} selectors`)\n }\n return freezeV1Value([...selectors].sort())\n}\n\n/** Validates a closed masking-profile object and returns its frozen normalized form. */\nexport const buildV2MaskingProfile = (input: unknown): V2MaskingProfile => {\n if (!isRecordValue(input) || !hasOnlyKeys(input, PROFILE_KEYS)) {\n fail('masking profile must contain only schema-defined fields')\n }\n for (const key of PROFILE_KEYS) {\n if (!hasOwn(input, key)) fail(`masking profile ${key} is required`)\n }\n if (input.schemaVersion !== V2_MASKING_PROFILE_SCHEMA_VERSION) {\n fail(`masking profile schemaVersion must be ${V2_MASKING_PROFILE_SCHEMA_VERSION}`)\n }\n if (input.targetDialect !== V2_BROWSER_MASKING_DIALECT) {\n fail(`masking profile targetDialect must be ${V2_BROWSER_MASKING_DIALECT}`)\n }\n if (input.secureInputsMasked !== true) fail('masking profile secureInputsMasked must be true')\n if (!isBooleanValue(input.platformFallbackApplied)) {\n fail('masking profile platformFallbackApplied must be a boolean')\n }\n return freezeV1Value({\n schemaVersion: V2_MASKING_PROFILE_SCHEMA_VERSION,\n targetDialect: V2_BROWSER_MASKING_DIALECT,\n textRule: assertRule(input.textRule, TEXT_RULES, 'masking profile textRule'),\n inputRule: assertRule(input.inputRule, INPUT_RULES, 'masking profile inputRule'),\n imageRule: assertRule(input.imageRule, IMAGE_RULES, 'masking profile imageRule'),\n secureInputsMasked: true,\n platformFallbackApplied: input.platformFallbackApplied,\n resolvedMaskSelectors: normalizeSelectors(input.resolvedMaskSelectors, 'masking profile resolvedMaskSelectors'),\n resolvedBlockSelectors: normalizeSelectors(\n input.resolvedBlockSelectors,\n 'masking profile resolvedBlockSelectors'\n ),\n })\n}\n\nexport interface V2MaskingProfileResolution {\n /** True when the recorder had to fall back to a coarser platform masking mode. */\n readonly platformFallbackApplied?: boolean\n}\n\n/**\n * Projects the server privacy policy's masking block onto the browser: the text, input, and image\n * rules plus every browser rule in the recognized selector dialect. Rules for other platforms are not\n * the browser's to apply; a browser rule in an unrecognized dialect cannot be honored and fails closed.\n */\nexport const resolveV2MaskingProfile = (\n masking: unknown,\n resolution: V2MaskingProfileResolution = {}\n): V2MaskingProfile => {\n if (!isRecordValue(masking) || !hasOnlyKeys(masking, POLICY_MASKING_KEYS)) {\n fail('policy masking must contain only schema-defined fields')\n }\n const maskSelectors: string[] = []\n const blockSelectors: string[] = []\n if (hasOwn(masking, 'platformRules')) {\n if (!isArrayValue(masking.platformRules)) fail('policy masking platformRules must be an array')\n masking.platformRules.forEach((rule, index) => {\n const field = `policy masking platformRules[${index}]`\n if (!isRecordValue(rule) || !hasOnlyKeys(rule, PLATFORM_RULE_KEYS)) {\n fail(`${field} must contain only schema-defined fields`)\n }\n if (rule.platform !== 'browser' && rule.platform !== 'android' && rule.platform !== 'ios') {\n fail(`${field} platform is unsupported`)\n }\n if (rule.action !== 'mask' && rule.action !== 'block') fail(`${field} action is unsupported`)\n if (!isStringValue(rule.targetDialect)) fail(`${field} targetDialect must be a string`)\n const target = assertSelector(rule.target, `${field} target`)\n if (rule.platform !== 'browser') return\n if (rule.targetDialect !== V2_BROWSER_MASKING_DIALECT) {\n fail(`${field} uses the unrecognized browser masking dialect ${rule.targetDialect}`)\n }\n ;(rule.action === 'mask' ? maskSelectors : blockSelectors).push(target)\n })\n }\n return buildV2MaskingProfile({\n schemaVersion: V2_MASKING_PROFILE_SCHEMA_VERSION,\n targetDialect: V2_BROWSER_MASKING_DIALECT,\n textRule: masking.text,\n inputRule: masking.inputs,\n imageRule: masking.images,\n secureInputsMasked: masking.secureInputsMasked,\n platformFallbackApplied: resolution.platformFallbackApplied === true,\n resolvedMaskSelectors: maskSelectors,\n resolvedBlockSelectors: blockSelectors,\n })\n}\n\n/** Canonical JSON of the closed profile: sorted members, no whitespace. */\nexport const canonicalV2MaskingProfile = (profile: V2MaskingProfile): string =>\n canonicalV2JsonValue(buildV2MaskingProfile(profile), 'masking profile')\n\nexport const canonicalV2MaskingProfileBytes = (profile: V2MaskingProfile): Uint8Array =>\n utf8Encode(canonicalV2MaskingProfile(profile))\n\n/** The profile hash bound into every replay chunk and its request identity. */\nexport const hashV2MaskingProfile = async (profile: V2MaskingProfile, sha256?: V2ReplaySha256): Promise<V2Sha256Hash> =>\n `sha256:${await sha256Hex(canonicalV2MaskingProfileBytes(profile), sha256)}`\n\nconst RULE_STRENGTH = {\n text: { sensitive: 1, all: 2 },\n input: { sensitive: 1, all: 2 },\n image: { allow: 1, block: 2 },\n} as const\n\ntype DimensionOrder = -1 | 0 | 1\n\nconst orderStrength = (applied: number, required: number): DimensionOrder =>\n applied === required ? 0 : applied > required ? 1 : -1\n\n/** 1 when the applied set covers every required selector, -1 when it is covered, 0 when equal, null otherwise. */\nconst orderSelectors = (applied: readonly string[], required: readonly string[]): DimensionOrder | null => {\n const appliedSet = new Set(applied)\n const requiredSet = new Set(required)\n const appliedCoversRequired = required.every((selector) => appliedSet.has(selector))\n const requiredCoversApplied = applied.every((selector) => requiredSet.has(selector))\n if (appliedCoversRequired && requiredCoversApplied) return 0\n if (appliedCoversRequired) return 1\n if (requiredCoversApplied) return -1\n return null\n}\n\n/**\n * Relates a newly required profile to the profile a sealed chunk was masked with. Serialized bytes\n * cannot be remasked, so a requirement that is stricter on any dimension, or not comparable with the\n * applied rules (a different dialect, fallback mode, or selector sets that neither contain the other),\n * makes the sealed bytes unlawful; an equal or looser requirement leaves them lawful.\n */\nexport const compareV2MaskingRequirement = (\n applied: V2MaskingProfile,\n required: V2MaskingProfile\n): V2MaskingRequirementComparison => {\n const appliedProfile = buildV2MaskingProfile(applied)\n const requiredProfile = buildV2MaskingProfile(required)\n if (\n appliedProfile.schemaVersion !== requiredProfile.schemaVersion ||\n appliedProfile.targetDialect !== requiredProfile.targetDialect ||\n appliedProfile.platformFallbackApplied !== requiredProfile.platformFallbackApplied\n ) {\n return 'incomparable'\n }\n const orders = [\n orderStrength(RULE_STRENGTH.text[appliedProfile.textRule], RULE_STRENGTH.text[requiredProfile.textRule]),\n orderStrength(RULE_STRENGTH.input[appliedProfile.inputRule], RULE_STRENGTH.input[requiredProfile.inputRule]),\n orderStrength(RULE_STRENGTH.image[appliedProfile.imageRule], RULE_STRENGTH.image[requiredProfile.imageRule]),\n orderSelectors(appliedProfile.resolvedMaskSelectors, requiredProfile.resolvedMaskSelectors),\n orderSelectors(appliedProfile.resolvedBlockSelectors, requiredProfile.resolvedBlockSelectors),\n ]\n if (orders.some((order) => isNullValue(order))) return 'incomparable'\n const appliedIsStricterSomewhere = orders.some((order) => order === 1)\n const requiredIsStricterSomewhere = orders.some((order) => order === -1)\n if (appliedIsStricterSomewhere && requiredIsStricterSomewhere) return 'incomparable'\n if (requiredIsStricterSomewhere) return 'stricter'\n if (appliedIsStricterSomewhere) return 'looser'\n return 'equal'\n}\n\nexport const v2MaskingInvalidationAction = (comparison: V2MaskingRequirementComparison): V2MaskingInvalidationAction =>\n comparison === 'equal' || comparison === 'looser' ? 'preserve' : 'purge'\n","import { V2MaskingProfileError } from './errors'\nimport type { V2MaskingProfile } from './types'\n\n/**\n * The recorder options a masking profile requires.\n *\n * Masking happens where the DOM is read, not after: the recorder is configured from the profile so\n * unmasked text and input values never enter memory, let alone a queue. The masking stage that\n * seals a proof then checks what it was given rather than being the first thing to redact it.\n */\nexport interface V2RecorderMaskingOptions {\n /** Every input type, password included. */\n readonly maskAllInputs: boolean\n /** Named explicitly rather than inherited: secure inputs are masked because we say so. */\n readonly maskInputOptions?: Readonly<{ password: true }>\n /** Omitted rather than empty — an empty selector is not \"match nothing\". */\n readonly maskTextSelector?: string\n readonly blockSelector?: string\n}\n\n/**\n * Elements whose recorded content is the image itself. A blocked element is replaced by a\n * placeholder, so blocking is how \"do not record this\" is expressed to the recorder.\n *\n * Video is deliberately absent: the policy rule is about images, and a moving-picture rule would be\n * its own field rather than something inferred here.\n */\nconst IMAGE_ELEMENT_SELECTORS = Object.freeze(['img', 'picture', 'svg', 'canvas'])\n\nconst selectorList = (selectors: readonly string[]): string | undefined =>\n selectors.length > 0 ? selectors.join(', ') : undefined\n\n/**\n * Projects a resolved masking profile onto the recorder's options.\n *\n * Every branch here is the stricter reading. `sensitive` text masks only what the profile resolved\n * rather than nothing, `sensitive` inputs still mask passwords, and blocking images adds to the\n * profile's block selectors rather than replacing them.\n */\nexport const resolveV2RecorderMaskingOptions = (profile: V2MaskingProfile): V2RecorderMaskingOptions => {\n if (profile.secureInputsMasked !== true) {\n throw new V2MaskingProfileError('a masking profile must mask secure inputs')\n }\n const maskAllInputs = profile.inputRule === 'all'\n const maskTextSelector =\n profile.textRule === 'all' ? '*' : selectorList(profile.resolvedMaskSelectors)\n const blockSelector = selectorList([\n ...profile.resolvedBlockSelectors,\n ...(profile.imageRule === 'block' ? IMAGE_ELEMENT_SELECTORS : []),\n ])\n return Object.freeze({\n maskAllInputs,\n // rrweb defaults to masking passwords when it is not masking everything, but a default is\n // not a guarantee: the profile promises secure inputs are masked, so say it.\n ...(maskAllInputs ? {} : { maskInputOptions: Object.freeze({ password: true as const }) }),\n ...(maskTextSelector === undefined ? {} : { maskTextSelector }),\n ...(blockSelector === undefined ? {} : { blockSelector }),\n })\n}\n","/* eslint-disable compat/compat, elu-client/no-direct-null-check, elu-client/no-direct-undefined-check -- Isolated recorder ownership and nullable native teardown handles. */\n\nimport { isArrayValue } from '../validation'\nimport { V1_NO_REPLAY_CAPABILITY } from '../privacy-state'\nimport type { V1PrivacyReplayInputs } from '../privacy-state'\nimport { maskV2BrowserDomEvent } from './dom-masker'\nimport { buildV2MaskingProfile } from './masking-profile'\nimport { resolveV2RecorderMaskingOptions } from './recorder-masking'\nimport type { V2RecorderMaskingOptions } from './recorder-masking'\nimport type { V2MaskingProfile } from './types'\n\nexport interface V2RecorderEngineOptions extends V2RecorderMaskingOptions {\n readonly emit: (event: unknown) => void\n readonly maskInputOptions: Readonly<{ password: true; email: true; tel: true; textarea: true }>\n readonly maskInputFn: (value: string, element: HTMLElement) => string\n readonly maskTextFn: () => string\n readonly recordCanvas: false\n readonly recordCrossOriginIframes: false\n readonly inlineImages: false\n readonly collectFonts: false\n readonly recordDOM: true\n readonly plugins: readonly never[]\n readonly keepIframeSrcFn: () => false\n readonly recordAfter: 'DOMContentLoaded'\n readonly errorHandler: () => true\n}\n\n/** Only the clean lazy entry supplies this function; it never comes from a provider global. */\nexport type V2RecorderEngine = (options: V2RecorderEngineOptions) => (() => void) | undefined\nexport type V2RecorderFailure = 'engine-start' | 'engine-stop' | 'invalid-event' | 'capacity' | 'sink'\n\nexport interface V2RecorderAdapterOptions {\n readonly engine: V2RecorderEngine\n readonly document: Pick<Document, 'querySelector'>\n readonly profile: V2MaskingProfile\n /** Actual sampling/session/budget and an already selected transport; no codec is invented here. */\n readonly eligibility: () => Omit<V1PrivacyReplayInputs, 'maskingValidated'>\n /** The current composition's synchronous replay authorization/identity/privacy witness. */\n readonly isCurrent: () => boolean\n /** Must notify synchronously when that witness is withdrawn, including independent lease expiry. */\n readonly subscribeToRestrictions: (revoke: () => void) => () => void\n readonly record: (event: unknown, atMs: number, byteLength: number) => Promise<void>\n readonly maximumEventBytes: number\n readonly maximumPendingBytes: number\n readonly maximumPendingEvents: number\n readonly onFailure?: (reason: V2RecorderFailure) => void\n}\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === 'object' && value !== null && !isArrayValue(value)\n\n/** A serialized mutation cannot attest its input type or selector context. Deny form values. */\nconst denyFormValues = (value: unknown): unknown => {\n if (isArrayValue(value)) return value.map(denyFormValues)\n if (!isRecord(value)) return value\n const result: Record<string, unknown> = {}\n for (const key of Object.keys(value)) result[key] = denyFormValues(value[key])\n if (isRecord(result.attributes)) delete result.attributes.value\n if (result.type === 3 && isRecord(result.data) && result.data.source === 5) result.data.text = ''\n return result\n}\n\nconst boundedPositive = (value: number, maximum: number): boolean =>\n Number.isSafeInteger(value) && value > 0 && value <= maximum\n\n/**\n * Owns one recorder generation. Masking precedes bounded serialization, and only isolated masked\n * snapshots enter its queue. The composition remains the final durable admission authority.\n */\nexport const createV2RecorderAdapter = (options: V2RecorderAdapterOptions) => {\n const profile = buildV2MaskingProfile(options.profile)\n if (\n !boundedPositive(options.maximumEventBytes, 8_388_608) ||\n !boundedPositive(options.maximumPendingBytes, 16_777_216) ||\n options.maximumPendingBytes < options.maximumEventBytes ||\n !boundedPositive(options.maximumPendingEvents, 1_000)\n )\n throw new Error('invalid recorder queue limits')\n // rrweb catches selector errors and silently leaves text visible. Reject before installation.\n for (const selector of [...profile.resolvedMaskSelectors, ...profile.resolvedBlockSelectors])\n options.document.querySelector(selector)\n const base = resolveV2RecorderMaskingOptions(profile)\n const blockSelector = [base.blockSelector, 'input[type=\"hidden\"]', 'iframe', 'object', 'embed']\n .filter((selector) => selector !== undefined)\n .join(', ')\n options.document.querySelector(blockSelector)\n let closed = false\n let running = false\n let draining = false\n let acquiring = false\n let cleanupHealthy = true\n let generation: object = {}\n let stopEngine: (() => void) | null = null\n let unsubscribe: (() => void) | null = null\n let pendingEvents = 0\n let pendingBytes = 0\n let lastTimestamp: number | null = null\n let tail: Promise<void> = Promise.resolve()\n\n const report = (reason: V2RecorderFailure): void => {\n try {\n options.onFailure?.(reason)\n } catch {\n /* Never report raw event content. */\n }\n }\n const capability = (): V1PrivacyReplayInputs => {\n if (closed) return V1_NO_REPLAY_CAPABILITY\n try {\n const current = options.eligibility()\n if (\n !Number.isSafeInteger(current.budgetRemainingSeconds) ||\n current.budgetRemainingSeconds < 0 ||\n current.budgetRemainingSeconds > 86_400\n )\n return V1_NO_REPLAY_CAPABILITY\n return Object.freeze({\n sampled: current.sampled === true,\n sessionEligible: current.sessionEligible === true,\n budgetRemainingSeconds: current.budgetRemainingSeconds,\n transport: current.transport,\n maskingValidated: true,\n })\n } catch {\n return V1_NO_REPLAY_CAPABILITY\n }\n }\n const eligible = (): boolean => {\n const current = capability()\n return (\n current.sampled &&\n current.sessionEligible &&\n current.budgetRemainingSeconds > 0 &&\n current.transport !== null &&\n options.isCurrent()\n )\n }\n const dispose = (action: (() => void) | null): void => {\n try {\n action?.()\n } catch {\n cleanupHealthy = false\n closed = true\n generation = {}\n report('engine-stop')\n }\n }\n const detachEngine = (): void => {\n const action = stopEngine\n stopEngine = null\n dispose(action)\n }\n const detachSubscription = (): void => {\n const action = unsubscribe\n unsubscribe = null\n dispose(action)\n }\n const stop = (): Promise<void> => {\n generation = {}\n running = false\n draining = false\n detachSubscription()\n detachEngine()\n return tail\n }\n /** Close raw intake first, but keep isolated masked tasks under their original authority. */\n const quiesce = (): Promise<void> => {\n if (closed) return stop()\n const epoch = generation\n running = false\n draining = true\n detachEngine()\n if (!cleanupHealthy) return stop()\n return tail.then(() => {\n if (generation !== epoch) return\n draining = false\n detachSubscription()\n })\n }\n const fail = (reason: V2RecorderFailure): void => {\n closed = true\n void stop()\n report(reason)\n }\n const current = (epoch: object, maskedTail = false): boolean => {\n try {\n return (running || (maskedTail && draining)) && !closed && generation === epoch && eligible()\n } catch {\n return false\n }\n }\n const emit = (epoch: object, event: unknown): void => {\n // A late observer callback after lawful quiescence cannot discard its masked tail.\n if (!running) return\n if (!current(epoch)) {\n if (generation === epoch) void stop()\n return\n }\n if (pendingEvents >= options.maximumPendingEvents || pendingBytes >= options.maximumPendingBytes) {\n fail('capacity')\n return\n }\n let isolated: unknown\n let atMs: number\n let byteLength: number\n try {\n if (!isRecord(event) || !Number.isSafeInteger(event.timestamp) || (event.timestamp as number) < 0)\n throw new Error('invalid recorder timestamp')\n atMs = event.timestamp as number\n if (lastTimestamp !== null && atMs < lastTimestamp) throw new Error('recorder clock regressed')\n const masked = denyFormValues(maskV2BrowserDomEvent(event, profile))\n const serialized = JSON.stringify(masked)\n if (serialized === undefined || serialized.length > options.maximumEventBytes) {\n fail('capacity')\n return\n }\n byteLength = new TextEncoder().encode(serialized).byteLength\n if (byteLength > options.maximumEventBytes || pendingBytes + byteLength > options.maximumPendingBytes) {\n fail('capacity')\n return\n }\n isolated = JSON.parse(serialized)\n } catch {\n fail('invalid-event')\n return\n }\n if (!current(epoch)) {\n void stop()\n return\n }\n lastTimestamp = atMs\n pendingEvents += 1\n pendingBytes += byteLength\n const delivery = tail\n .then(async () => {\n if (!current(epoch, true)) {\n if (generation === epoch) void stop()\n return\n }\n await options.record(isolated, atMs, byteLength)\n })\n .catch(() => {\n if (generation === epoch) fail('sink')\n })\n .then(() => {\n pendingEvents -= 1\n pendingBytes -= byteLength\n })\n tail = delivery\n }\n const start = (): boolean => {\n if (closed || running || draining || acquiring || !cleanupHealthy || pendingEvents > 0) return false\n try {\n if (!eligible()) return false\n } catch {\n return false\n }\n const epoch = {}\n generation = epoch\n lastTimestamp = null\n running = true\n try {\n acquiring = true\n const stopSubscription = options.subscribeToRestrictions(() => {\n if (generation === epoch) void stop()\n })\n acquiring = false\n if (!current(epoch)) {\n dispose(stopSubscription)\n return false\n }\n unsubscribe = stopSubscription\n acquiring = true\n const cleanup = options.engine({\n ...base,\n // Route normal input types through the selector-aware hook. Radio/checkbox value\n // emissions bypass that hook in rrweb and are denied before queue serialization.\n maskAllInputs: true,\n maskInputOptions: { password: true, email: true, tel: true, textarea: true },\n maskInputFn: (value, element) => {\n const type = element.getAttribute('type')?.toLowerCase()\n if (\n profile.inputRule === 'all' ||\n ['password', 'email', 'tel', 'hidden'].includes(type ?? '') ||\n element.tagName === 'TEXTAREA'\n )\n return ''\n for (const selector of profile.resolvedMaskSelectors) if (element.closest(selector)) return ''\n return value\n },\n maskTextFn: () => '',\n blockSelector,\n recordCanvas: false,\n recordCrossOriginIframes: false,\n inlineImages: false,\n collectFonts: false,\n recordDOM: true,\n plugins: [] as never[],\n keepIframeSrcFn: () => false,\n recordAfter: 'DOMContentLoaded',\n errorHandler: () => {\n if (generation === epoch) fail('engine-start')\n return true\n },\n emit: (event) => emit(epoch, event),\n })\n acquiring = false\n if (typeof cleanup !== 'function') {\n cleanupHealthy = false\n fail('engine-start')\n return false\n }\n if (!current(epoch)) {\n dispose(cleanup)\n return false\n }\n stopEngine = cleanup\n return true\n } catch {\n // An engine that throws before returning its disposer cannot prove cleanup.\n if (acquiring) cleanupHealthy = false\n acquiring = false\n fail('engine-start')\n return false\n }\n }\n return Object.freeze({\n profile,\n capability,\n start,\n quiesce,\n stop,\n /** Only true after every acquisition, disposer and original masked sink has settled. */\n cleanupIsProven: (): boolean =>\n cleanupHealthy &&\n !acquiring &&\n !running &&\n !draining &&\n stopEngine === null &&\n unsubscribe === null &&\n pendingEvents === 0,\n settled: (): Promise<void> => tail,\n close: (): Promise<void> => {\n closed = true\n return stop()\n },\n })\n}\n","import { freezeV1Value } from '../validation'\n\n/**\n * When one recorded stretch ends and the next begins.\n *\n * Every boundary here comes from the configuration document rather than from a constant: how long a\n * session may idle, how long it may run, how short a replay is worth keeping, and how many bytes a\n * chunk may carry. The state machine is pure — it is given each event's instant and size and returns\n * what to do — so a boundary is a decision that can be read back rather than a timer that fired.\n */\n\nexport interface V2ReplaySchedulePolicy {\n /** No activity for this long ends the session. */\n readonly idleTimeoutSeconds: number\n /** A session may not run longer than this, however active it is. */\n readonly maximumDurationSeconds: number\n /** A replay shorter than this is not worth delivering. */\n readonly minimumDurationSeconds: number\n /** The chunk ceiling from the document, in bytes. */\n readonly replayChunkBytes: number\n}\n\nexport interface V2ReplayScheduleState {\n /** Null before the first event of a session. */\n readonly sessionStartedAtMs: number | null\n readonly lastActivityAtMs: number | null\n readonly chunkStartedAtMs: number | null\n readonly chunkBytes: number\n readonly chunkEvents: number\n readonly sequence: number\n}\n\nexport type V2ReplayScheduleAction =\n | /** Add the event to the open chunk. */ 'buffer'\n | /** Seal the open chunk, then start a new one holding this event. */ 'cut-chunk'\n | /** Seal the open chunk and end the session; this event opens a new replay. */ 'cut-session'\n\nexport interface V2ReplayScheduleDecision {\n readonly action: V2ReplayScheduleAction\n /** True when the stretch being sealed is too short to be worth delivering. */\n readonly discardSealedChunk: boolean\n readonly state: V2ReplayScheduleState\n}\n\nexport const initialV2ReplayScheduleState = (): V2ReplayScheduleState =>\n freezeV1Value({\n sessionStartedAtMs: null,\n lastActivityAtMs: null,\n chunkStartedAtMs: null,\n chunkBytes: 0,\n chunkEvents: 0,\n sequence: 0,\n })\n\nconst openChunk = (state: V2ReplayScheduleState, atMs: number, bytes: number, sequence: number) =>\n freezeV1Value({\n sessionStartedAtMs: state.sessionStartedAtMs,\n lastActivityAtMs: atMs,\n chunkStartedAtMs: atMs,\n chunkBytes: bytes,\n chunkEvents: 1,\n sequence,\n })\n\n/**\n * Decides where one event falls.\n *\n * The order of the checks is the policy: a session that has idled out or run its maximum ends before\n * anything else is considered, because a chunk cut inside a session that should already have closed\n * would carry the new activity under the old replay's identity.\n */\nexport const advanceV2ReplaySchedule = (\n state: V2ReplayScheduleState,\n event: { readonly atMs: number; readonly byteLength: number },\n policy: V2ReplaySchedulePolicy\n): V2ReplayScheduleDecision => {\n const { atMs, byteLength } = event\n\n // The first event of a session opens it; there is nothing to seal.\n if (state.sessionStartedAtMs === null || state.lastActivityAtMs === null) {\n return freezeV1Value({\n action: 'buffer' as const,\n discardSealedChunk: false,\n state: freezeV1Value({\n ...openChunk(state, atMs, byteLength, 0),\n sessionStartedAtMs: atMs,\n }),\n })\n }\n\n const idleForMs = atMs - state.lastActivityAtMs\n const sessionAgeMs = atMs - state.sessionStartedAtMs\n const endsSession =\n idleForMs >= policy.idleTimeoutSeconds * 1000 || sessionAgeMs >= policy.maximumDurationSeconds * 1000\n\n if (endsSession) {\n // What is sealed is the stretch that just ended, so its length decides whether it is kept.\n const sealedMs = state.lastActivityAtMs - (state.sessionStartedAtMs ?? state.lastActivityAtMs)\n return freezeV1Value({\n action: 'cut-session' as const,\n discardSealedChunk: sealedMs < policy.minimumDurationSeconds * 1000,\n state: freezeV1Value({\n ...openChunk(state, atMs, byteLength, 0),\n sessionStartedAtMs: atMs,\n }),\n })\n }\n\n // A chunk that cannot hold this event is sealed and the event opens the next one. An event\n // larger than the whole ceiling still gets its own chunk rather than being dropped here; the\n // sealing stage refuses it, which is where a payload that cannot be sent belongs.\n if (state.chunkEvents > 0 && state.chunkBytes + byteLength > policy.replayChunkBytes) {\n return freezeV1Value({\n action: 'cut-chunk' as const,\n discardSealedChunk: false,\n state: openChunk(state, atMs, byteLength, state.sequence + 1),\n })\n }\n\n return freezeV1Value({\n action: 'buffer' as const,\n discardSealedChunk: false,\n state: freezeV1Value({\n ...state,\n lastActivityAtMs: atMs,\n chunkStartedAtMs: state.chunkStartedAtMs ?? atMs,\n chunkBytes: state.chunkBytes + byteLength,\n chunkEvents: state.chunkEvents + 1,\n }),\n })\n}\n","/* eslint-disable compat/compat, elu-client/no-direct-null-check -- Native IndexedDB is asynchronous and this runtime fails closed without Promise; its open state uses exact null checks. */\n\nimport type {\n V1DurableCommitOutcome,\n V1DurableRecordVisitor,\n V1DurableStorage,\n V1DurableStorageMode,\n V1DurableStorageTransaction,\n} from './durable-storage'\nimport { V1DurableStorageError } from './durable-storage'\nimport { freezeV1Value, isArrayValue } from './validation'\nimport { initializeV1IndexedDBConnection } from './indexeddb-initialization'\n\nexport const V1_INDEXED_DB_NAME = 'elu-sdk-v1'\n/** Schema versions of the shared database: base stores, plus the flag cache, plus the replay stores. */\nexport const V1_INDEXED_DB_VERSION = 1\nexport const V1_INDEXED_DB_FLAG_VERSION = 2\nexport const V1_INDEXED_DB_REPLAY_VERSION = 3\n\nexport const V1_INSTALLATIONS_STORE = 'installations'\nexport const V1_RECORDS_STORE = 'records'\nexport const V1_FLAG_CACHE_STORE = 'flagCache'\nexport const V2_REPLAY_CHUNKS_STORE = 'replayChunks'\nexport const V2_REPLAY_STREAMS_STORE = 'replayStreams'\nexport const V2_REPLAY_RESOLUTIONS_STORE = 'replayResolutions'\n/** Unique index on [siteKey, replayId, chunkId] over live replay chunks. */\nexport const V2_REPLAY_CHUNK_INDEX = 'chunk'\n/** Unique index on [siteKey, replayId, sequence] over live chunks and over retained resolutions. */\nexport const V2_REPLAY_SEQUENCE_INDEX = 'sequence'\nconst INSTALLATIONS_STORE = V1_INSTALLATIONS_STORE\nconst RECORDS_STORE = V1_RECORDS_STORE\nconst STORE_NAMES = [INSTALLATIONS_STORE, RECORDS_STORE] as const\n\nconst requestResult = <T>(request: IDBRequest<T>): Promise<T> =>\n new Promise((resolve, reject) => {\n request.onsuccess = () => resolve(request.result)\n request.onerror = () => reject(request.error ?? new Error('IndexedDB request failed'))\n })\n\ntype V1IndexedDBCompletion = Readonly<{ status: 'committed' }> | Readonly<{ status: 'aborted'; error: Error }>\n\nconst transactionCompletion = (transaction: IDBTransaction): Promise<V1IndexedDBCompletion> =>\n new Promise((resolve) => {\n let observedError: Error | null = null\n transaction.oncomplete = () => resolve(freezeV1Value({ status: 'committed' }))\n transaction.onerror = () => {\n observedError = transaction.error ?? new Error('IndexedDB transaction failed')\n }\n transaction.onabort = () =>\n resolve(\n freezeV1Value({\n status: 'aborted',\n error: transaction.error ?? observedError ?? new Error('IndexedDB transaction aborted'),\n })\n )\n })\n\nconst keyPathMatches = (actual: string | string[] | null, expected: string | readonly string[]): boolean => {\n if (typeof expected === 'string') {\n return actual === expected\n }\n if (!isArrayValue(actual) || actual.length !== expected.length) {\n return false\n }\n return expected.every((part, index) => actual[index] === part)\n}\n\nclass V1NativeIndexedDBTransaction implements V1DurableStorageTransaction {\n private readonly _installations: IDBObjectStore\n private readonly _records: IDBObjectStore\n private readonly _keyRange: typeof IDBKeyRange\n\n constructor(transaction: IDBTransaction, keyRange: typeof IDBKeyRange) {\n this._installations = transaction.objectStore(INSTALLATIONS_STORE)\n this._records = transaction.objectStore(RECORDS_STORE)\n this._keyRange = keyRange\n }\n\n getInstallation(siteKey: string): Promise<unknown | undefined> {\n return requestResult(this._installations.get(siteKey))\n }\n\n async addInstallation(value: unknown): Promise<void> {\n await requestResult(this._installations.add(value))\n }\n\n async putInstallation(value: unknown): Promise<void> {\n await requestResult(this._installations.put(value))\n }\n\n scanAllRecords(siteKey: string, visit: V1DurableRecordVisitor): Promise<void> {\n return this._scan(\n this._records.openCursor(this._keyRange.bound([siteKey], [siteKey, []])),\n Number.MAX_SAFE_INTEGER,\n visit\n )\n }\n\n scanRecordPrefix(\n siteKey: string,\n startSequence: number,\n maximumCount: number,\n visit: V1DurableRecordVisitor\n ): Promise<void> {\n if (maximumCount === 0) {\n return Promise.resolve()\n }\n return this._scan(\n this._records.openCursor(\n this._keyRange.bound([siteKey, startSequence], [siteKey, Number.MAX_SAFE_INTEGER])\n ),\n maximumCount,\n visit\n )\n }\n\n async addRecord(value: unknown): Promise<void> {\n await requestResult(this._records.add(value))\n }\n\n async deleteRecord(siteKey: string, sequence: number): Promise<void> {\n await requestResult(this._records.delete([siteKey, sequence]))\n }\n\n private _scan(\n request: IDBRequest<IDBCursorWithValue | null>,\n maximumCount: number,\n visit: V1DurableRecordVisitor\n ): Promise<void> {\n return new Promise((resolve, reject) => {\n let visited = 0\n request.onerror = () => reject(request.error ?? new Error('IndexedDB cursor failed'))\n request.onsuccess = () => {\n const cursor = request.result\n if (!cursor || visited >= maximumCount) {\n resolve()\n return\n }\n try {\n visited += 1\n if (!visit(cursor.value) || visited >= maximumCount) {\n resolve()\n return\n }\n cursor.continue()\n } catch (error) {\n reject(error)\n }\n }\n })\n }\n}\n\nclass V1NativeIndexedDBStorage implements V1DurableStorage {\n private readonly _database: IDBDatabase\n private readonly _keyRange: typeof IDBKeyRange\n private _closed = false\n\n constructor(database: IDBDatabase, keyRange: typeof IDBKeyRange) {\n this._database = database\n this._keyRange = keyRange\n this._database.onversionchange = () => this.close()\n }\n\n async runTransaction<T>(\n mode: V1DurableStorageMode,\n operation: (transaction: V1DurableStorageTransaction) => Promise<T>\n ): Promise<T> {\n if (this._closed) {\n throw new V1DurableStorageError('closed', 'IndexedDB storage is closed')\n }\n\n if (mode === 'readwrite') {\n const outcome = await this.runTransactionWithCommitOutcome(operation)\n if (outcome.status === 'committed') return outcome.value\n throw outcome.error\n }\n\n let transaction: IDBTransaction\n try {\n transaction = this._database.transaction([...STORE_NAMES], mode)\n } catch {\n throw new V1DurableStorageError('unavailable', 'IndexedDB transaction could not be opened')\n }\n const completion = transactionCompletion(transaction)\n try {\n const result = await operation(new V1NativeIndexedDBTransaction(transaction, this._keyRange))\n const outcome = await completion\n if (outcome.status === 'committed') return result\n throw outcome.error\n } catch (error) {\n try {\n transaction.abort()\n } catch {\n // The transaction may already have aborted or completed.\n }\n await completion\n throw error\n }\n }\n\n async runTransactionWithCommitOutcome<T>(\n operation: (transaction: V1DurableStorageTransaction) => Promise<T>\n ): Promise<V1DurableCommitOutcome<T>> {\n if (this._closed) {\n return freezeV1Value({\n status: 'proven-not-committed',\n error: new V1DurableStorageError('closed', 'IndexedDB storage is closed'),\n })\n }\n\n let transaction: IDBTransaction\n try {\n transaction = this._database.transaction([...STORE_NAMES], 'readwrite')\n } catch {\n return freezeV1Value({\n status: 'proven-not-committed',\n error: new V1DurableStorageError('unavailable', 'IndexedDB transaction could not be opened'),\n })\n }\n const completion = transactionCompletion(transaction)\n let value: T\n try {\n value = await operation(new V1NativeIndexedDBTransaction(transaction, this._keyRange))\n } catch (error) {\n try {\n transaction.abort()\n } catch {\n // A transaction that completed while the callback awaited unrelated work is ambiguous.\n }\n const completed = await completion\n const normalized = error instanceof Error ? error : new Error('IndexedDB operation failed')\n return completed.status === 'aborted'\n ? freezeV1Value({ status: 'proven-not-committed', error: normalized })\n : freezeV1Value({ status: 'unknown', error: normalized })\n }\n\n const completed = await completion\n return completed.status === 'committed'\n ? freezeV1Value({ status: 'committed', value })\n : freezeV1Value({ status: 'proven-not-committed', error: completed.error })\n }\n\n close(): void {\n if (!this._closed) {\n this._closed = true\n this._database.close()\n }\n }\n}\n\nexport type V1IndexedDBSchema = 'base' | 'flags' | 'replay'\n\nexport interface V1OpenIndexedDBDatabaseOptions {\n /** The schema the caller needs; the database is upgraded to that version only when it is older. */\n readonly schema: V1IndexedDBSchema\n /** Lazy owners may inspect an existing schema, but must never close active peers with an upgrade. */\n readonly upgradePolicy?: 'allow' | 'require-existing'\n readonly factory?: IDBFactory | null\n /** How long a version upgrade may stay blocked by other connections before it fails closed. */\n readonly upgradeTimeoutMs?: number\n}\n\ninterface V1IndexedDBIndexDefinition {\n readonly name: string\n readonly keyPath: readonly string[]\n readonly unique: boolean\n}\n\ninterface V1IndexedDBStoreDefinition {\n readonly name: string\n readonly keyPath: string | readonly string[]\n /** The schema version that introduces the store. */\n readonly version: number\n readonly indexes: readonly V1IndexedDBIndexDefinition[]\n}\n\nconst SCHEMA_VERSIONS: Readonly<Record<V1IndexedDBSchema, number>> = freezeV1Value({\n base: V1_INDEXED_DB_VERSION,\n flags: V1_INDEXED_DB_FLAG_VERSION,\n replay: V1_INDEXED_DB_REPLAY_VERSION,\n})\n\nconst STORE_DEFINITIONS: readonly V1IndexedDBStoreDefinition[] = freezeV1Value([\n { name: INSTALLATIONS_STORE, keyPath: 'siteKey', version: 1, indexes: [] },\n { name: RECORDS_STORE, keyPath: ['siteKey', 'sequence'], version: 1, indexes: [] },\n { name: V1_FLAG_CACHE_STORE, keyPath: ['siteNamespaceDigest', 'recordKind'], version: 2, indexes: [] },\n {\n name: V2_REPLAY_CHUNKS_STORE,\n keyPath: ['siteKey', 'enqueueOrdinal'],\n version: 3,\n indexes: [\n { name: V2_REPLAY_CHUNK_INDEX, keyPath: ['siteKey', 'replayId', 'chunkId'], unique: true },\n { name: V2_REPLAY_SEQUENCE_INDEX, keyPath: ['siteKey', 'replayId', 'sequence'], unique: true },\n ],\n },\n { name: V2_REPLAY_STREAMS_STORE, keyPath: ['siteKey', 'replayId'], version: 3, indexes: [] },\n {\n name: V2_REPLAY_RESOLUTIONS_STORE,\n keyPath: ['siteKey', 'replayId', 'chunkId'],\n version: 3,\n indexes: [{ name: V2_REPLAY_SEQUENCE_INDEX, keyPath: ['siteKey', 'replayId', 'sequence'], unique: true }],\n },\n])\n\nconst DEFAULT_UPGRADE_TIMEOUT_MS = 5_000\nconst MAXIMUM_UPGRADE_TIMEOUT_MS = 60_000\n\nconst storeKeyPath = (definition: V1IndexedDBStoreDefinition): string | string[] =>\n typeof definition.keyPath === 'string' ? definition.keyPath : [...definition.keyPath]\n\nconst storesAtVersion = (version: number): readonly V1IndexedDBStoreDefinition[] =>\n STORE_DEFINITIONS.filter((store) => store.version <= version)\n\nconst unsupported = (message: string): V1DurableStorageError => new V1DurableStorageError('unsupported', message)\n\nconst storeNames = (names: DOMStringList): string[] => {\n const result: string[] = []\n for (let index = 0; index < names.length; index += 1) {\n const name = names.item(index)\n if (name !== null) result.push(name)\n }\n return result.sort()\n}\n\n/**\n * Checks that the stores the transaction can see are exactly the stores of the given schema version,\n * with the expected key paths and indexes. Used both on an open connection and inside an upgrade\n * transaction, where it proves the pre-upgrade schema before anything is added.\n */\nconst validateStores = (\n names: DOMStringList,\n objectStore: (name: string) => IDBObjectStore,\n version: number,\n what: string\n): void => {\n const expected = storesAtVersion(version)\n const actual = storeNames(names)\n const expectedNames = expected.map((store) => store.name).sort()\n if (actual.length !== expectedNames.length || actual.some((name, index) => name !== expectedNames[index])) {\n throw unsupported(`IndexedDB ${what} schema does not match version ${version}`)\n }\n for (const definition of expected) {\n const store = objectStore(definition.name)\n if (!keyPathMatches(store.keyPath, definition.keyPath)) {\n throw unsupported(`IndexedDB ${what} key paths are incompatible`)\n }\n const indexNames = storeNames(store.indexNames)\n const expectedIndexNames = definition.indexes.map((index) => index.name).sort()\n if (\n indexNames.length !== expectedIndexNames.length ||\n indexNames.some((name, position) => name !== expectedIndexNames[position])\n ) {\n throw unsupported(`IndexedDB ${what} indexes are incompatible`)\n }\n for (const definitionIndex of definition.indexes) {\n const index = store.index(definitionIndex.name)\n if (!keyPathMatches(index.keyPath, definitionIndex.keyPath) || index.unique !== definitionIndex.unique) {\n throw unsupported(`IndexedDB ${what} index key paths are incompatible`)\n }\n }\n }\n}\n\n/** Validates a connection against the closed schema of its own version; any other version fails closed. */\nexport const validateV1IndexedDBSchema = (database: IDBDatabase): void => {\n if (\n database.version !== V1_INDEXED_DB_VERSION &&\n database.version !== V1_INDEXED_DB_FLAG_VERSION &&\n database.version !== V1_INDEXED_DB_REPLAY_VERSION\n ) {\n throw unsupported('IndexedDB schema version is unsupported')\n }\n const expectedNames = storesAtVersion(database.version).map((store) => store.name)\n if (storeNames(database.objectStoreNames).join(',') !== [...expectedNames].sort().join(',')) {\n throw unsupported(`IndexedDB schema does not match version ${database.version}`)\n }\n let transaction: IDBTransaction\n try {\n transaction = database.transaction(expectedNames, 'readonly')\n } catch {\n throw unsupported('IndexedDB stores cannot be opened')\n }\n try {\n validateStores(database.objectStoreNames, (name) => transaction.objectStore(name), database.version, 'stored')\n } catch (error) {\n try {\n transaction.abort()\n } catch {\n // A completed read transaction needs no cleanup.\n }\n throw error\n }\n}\n\nconst applyUpgrade = (\n database: IDBDatabase,\n transaction: IDBTransaction,\n oldVersion: number,\n newVersion: number\n): void => {\n if (\n (oldVersion !== V1_INDEXED_DB_VERSION && oldVersion !== V1_INDEXED_DB_FLAG_VERSION) ||\n newVersion <= oldVersion ||\n newVersion > V1_INDEXED_DB_REPLAY_VERSION\n ) {\n throw unsupported('IndexedDB upgrade path is unsupported')\n }\n validateStores(database.objectStoreNames, (name) => transaction.objectStore(name), oldVersion, 'pre-upgrade')\n for (const definition of STORE_DEFINITIONS) {\n if (definition.version <= oldVersion || definition.version > newVersion) continue\n const store = database.createObjectStore(definition.name, { keyPath: storeKeyPath(definition) })\n for (const index of definition.indexes) {\n store.createIndex(index.name, [...index.keyPath], { unique: index.unique })\n }\n }\n}\n\nconst resolveFactory = (factory: IDBFactory | null | undefined): IDBFactory | undefined =>\n typeof factory === 'undefined'\n ? typeof globalThis === 'undefined'\n ? undefined\n : globalThis.indexedDB\n : (factory ?? undefined)\n\ntype V1InspectOutcome =\n | Readonly<{ status: 'ready'; database: IDBDatabase }>\n | Readonly<{ status: 'older'; version: number }>\n\n/**\n * Opens the database without a version and reports whether it already satisfies the requested schema.\n * A missing database is created at version 1 for the base schema only; the flag and replay schemas\n * need an installation to exist first, so they abort the creation and fail closed. Inspection never\n * requests a version change, so a blocked open here is unexpected and fails immediately.\n */\nconst inspectDatabase = (\n factory: IDBFactory,\n schema: V1IndexedDBSchema,\n allowCreation = true\n): Promise<V1InspectOutcome> =>\n new Promise((resolve, reject) => {\n let request: IDBOpenDBRequest\n try {\n request = factory.open(V1_INDEXED_DB_NAME)\n } catch {\n reject(new V1DurableStorageError('unavailable', 'IndexedDB open was denied'))\n return\n }\n let settled = false\n let upgradeFailure: V1DurableStorageError | null = null\n const rejectOnce = (error: V1DurableStorageError): void => {\n if (!settled) {\n settled = true\n reject(error)\n }\n }\n request.onupgradeneeded = (event) => {\n const database = request.result\n if (event.oldVersion !== 0 || schema !== 'base' || !allowCreation) {\n upgradeFailure = unsupported(\n schema === 'base'\n ? 'IndexedDB schema version is unsupported'\n : 'IndexedDB has no base schema to extend'\n )\n request.transaction?.abort()\n return\n }\n if (database.objectStoreNames.length !== 0) {\n upgradeFailure = unsupported('IndexedDB contains an unexpected v1 schema')\n request.transaction?.abort()\n return\n }\n for (const definition of storesAtVersion(V1_INDEXED_DB_VERSION)) {\n database.createObjectStore(definition.name, { keyPath: storeKeyPath(definition) })\n }\n }\n request.onblocked = () => rejectOnce(new V1DurableStorageError('blocked', 'IndexedDB open is blocked'))\n request.onerror = () => {\n const code = request.error?.name === 'VersionError' ? 'unsupported' : 'unavailable'\n rejectOnce(upgradeFailure ?? new V1DurableStorageError(code, 'IndexedDB could not be opened'))\n }\n request.onsuccess = () => {\n const database = request.result\n if (settled) {\n database.close()\n return\n }\n settled = true\n try {\n validateV1IndexedDBSchema(database)\n } catch (error) {\n database.close()\n reject(\n error instanceof V1DurableStorageError ? error : unsupported('IndexedDB schema validation failed')\n )\n return\n }\n if (database.version >= SCHEMA_VERSIONS[schema]) {\n database.onversionchange = () => database.close()\n resolve(freezeV1Value({ status: 'ready', database }))\n return\n }\n database.close()\n resolve(freezeV1Value({ status: 'older', version: database.version }))\n }\n })\n\ntype V1UpgradeOutcome = Readonly<{ status: 'ready'; database: IDBDatabase }> | Readonly<{ status: 'overtaken' }>\n\n/**\n * Requests exactly the schema version the caller needs. The upgrade callback trusts oldVersion, not\n * the earlier inspection, so a concurrent lower upgrade by another connection is extended rather\n * than raced. A VersionError means another connection already moved past the requested version;\n * the caller inspects once more and accepts it when it is a known schema.\n */\nconst upgradeDatabase = (\n factory: IDBFactory,\n schema: V1IndexedDBSchema,\n upgradeTimeoutMs: number\n): Promise<V1UpgradeOutcome> =>\n new Promise((resolve, reject) => {\n const version = SCHEMA_VERSIONS[schema]\n let request: IDBOpenDBRequest\n try {\n request = factory.open(V1_INDEXED_DB_NAME, version)\n } catch {\n reject(new V1DurableStorageError('unavailable', 'IndexedDB open was denied'))\n return\n }\n let settled = false\n let upgradeFailure: V1DurableStorageError | null = null\n let blockedTimer: ReturnType<typeof setTimeout> | null = null\n const clearBlockedTimer = (): void => {\n if (blockedTimer !== null) {\n clearTimeout(blockedTimer)\n blockedTimer = null\n }\n }\n const settle = (outcome: () => void): void => {\n if (settled) return\n settled = true\n clearBlockedTimer()\n outcome()\n }\n const abortUpgrade = (): void => {\n try {\n request.transaction?.abort()\n } catch {\n // The upgrade transaction may not exist yet or may already have completed.\n }\n }\n request.onblocked = () => {\n if (settled || blockedTimer !== null) return\n blockedTimer = setTimeout(() => {\n abortUpgrade()\n settle(() => reject(new V1DurableStorageError('blocked', 'IndexedDB upgrade remained blocked')))\n }, upgradeTimeoutMs)\n }\n request.onupgradeneeded = (event) => {\n clearBlockedTimer()\n if (settled) {\n // The caller already gave up; a late upgrade must not change the schema behind it.\n abortUpgrade()\n return\n }\n try {\n const transaction = request.transaction ?? fail(unsupported('IndexedDB upgrade transaction is missing'))\n applyUpgrade(request.result, transaction, event.oldVersion, event.newVersion ?? version)\n } catch (error) {\n upgradeFailure =\n error instanceof V1DurableStorageError ? error : unsupported('IndexedDB upgrade failed')\n abortUpgrade()\n }\n }\n request.onerror = () => {\n if (upgradeFailure === null && request.error?.name === 'VersionError') {\n settle(() => resolve(freezeV1Value({ status: 'overtaken' })))\n return\n }\n settle(() =>\n reject(upgradeFailure ?? new V1DurableStorageError('unavailable', 'IndexedDB could not be opened'))\n )\n }\n request.onsuccess = () => {\n const database = request.result\n if (settled) {\n database.close()\n return\n }\n try {\n validateV1IndexedDBSchema(database)\n } catch (error) {\n database.close()\n settle(() =>\n reject(\n error instanceof V1DurableStorageError\n ? error\n : unsupported('IndexedDB schema validation failed')\n )\n )\n return\n }\n database.onversionchange = () => database.close()\n settle(() => resolve(freezeV1Value({ status: 'ready', database })))\n }\n })\n\nfunction fail(error: V1DurableStorageError): never {\n throw error\n}\n\n/**\n * The one opener every internal owner of `elu-sdk-v1` goes through. It inspects the current version\n * first, without requesting one, and upgrades only when the database is older than the schema the\n * caller needs: v1 to v2 adds the flag cache, v1 or v2 to v3 adds the replay stores, and every\n * existing store keeps its rows. It never requests a lower version, a future or foreign schema fails\n * closed, and a blocked upgrade or an unexpected version change leaves the database untouched.\n */\nexport const openV1IndexedDBDatabase = async (options: V1OpenIndexedDBDatabaseOptions): Promise<IDBDatabase> => {\n const schema = options.schema\n if (schema !== 'base' && schema !== 'flags' && schema !== 'replay') {\n throw new V1DurableStorageError('unavailable', 'IndexedDB schema request is invalid')\n }\n const upgradePolicy = options.upgradePolicy ?? 'allow'\n if (upgradePolicy !== 'allow' && upgradePolicy !== 'require-existing') {\n throw new V1DurableStorageError('unavailable', 'IndexedDB upgrade policy is invalid')\n }\n const upgradeTimeoutMs = options.upgradeTimeoutMs ?? DEFAULT_UPGRADE_TIMEOUT_MS\n if (\n !Number.isSafeInteger(upgradeTimeoutMs) ||\n upgradeTimeoutMs < 1 ||\n upgradeTimeoutMs > MAXIMUM_UPGRADE_TIMEOUT_MS\n ) {\n throw new V1DurableStorageError('unavailable', 'IndexedDB upgrade timeout is invalid')\n }\n const factory = resolveFactory(options.factory)\n if (!factory) {\n throw new V1DurableStorageError('unavailable', 'IndexedDB is unavailable')\n }\n\n const inspected = await inspectDatabase(factory, schema, upgradePolicy === 'allow')\n if (inspected.status === 'ready') return inspected.database\n if (upgradePolicy === 'require-existing') {\n throw unsupported('IndexedDB required schema has not been prepared')\n }\n\n const upgraded = await upgradeDatabase(factory, schema, upgradeTimeoutMs)\n if (upgraded.status === 'ready') return upgraded.database\n\n const reinspected = await inspectDatabase(factory, schema)\n if (reinspected.status === 'ready') return reinspected.database\n throw unsupported('IndexedDB schema changed during upgrade')\n}\n\n/**\n * Initializes an owner after overlapping opens have settled. The connection lifecycle helper keeps\n * its version-change observer independent of the owner's handler and only retries proven loss.\n */\nexport const initializeV1IndexedDBDatabase = async <T>(\n options: V1OpenIndexedDBDatabaseOptions,\n initialize: (database: IDBDatabase) => Promise<T>,\n lostConnection: (error: unknown) => boolean\n): Promise<T> => {\n const factory = resolveFactory(options.factory)\n if (!factory) throw new V1DurableStorageError('unavailable', 'IndexedDB is unavailable')\n return initializeV1IndexedDBConnection({\n factory,\n open: () => openV1IndexedDBDatabase({ ...options, factory }),\n initialize,\n lostConnection,\n })\n}\n\nexport const openV1IndexedDBStorage = async (\n factory?: IDBFactory | null,\n keyRangeFactory?: typeof IDBKeyRange | null\n): Promise<V1DurableStorage> => {\n const indexedDBKeyRange =\n typeof keyRangeFactory === 'undefined'\n ? typeof globalThis === 'undefined'\n ? undefined\n : globalThis.IDBKeyRange\n : (keyRangeFactory ?? undefined)\n if (!resolveFactory(factory) || !indexedDBKeyRange) {\n throw new V1DurableStorageError('unavailable', 'IndexedDB is unavailable')\n }\n const database = await openV1IndexedDBDatabase({ schema: 'base', factory })\n return new V1NativeIndexedDBStorage(database, indexedDBKeyRange)\n}\n","/* eslint-disable compat/compat -- Durable storage requires native Promise and IndexedDB support. */\n\nimport type {\n V1BatchRecord,\n V1Event,\n V1IdentityReference,\n V1JsonObject,\n V1JsonValue,\n V1Mutation,\n V1MutationChange,\n V1MutationSubject,\n V1VersionContext,\n} from './types'\nimport type {\n V1DurableCommitOutcome,\n V1DurableStorage,\n V1DurableStorageFactory,\n V1DurableStorageTransaction,\n} from './durable-storage'\nimport { V1DurableStorageError } from './durable-storage'\nimport type { V1CaptureCandidateEvaluation, V1Sha256 } from './config-manager'\nimport { V1ConfigManager } from './config-manager'\nimport { openV1IndexedDBStorage } from './indexeddb-storage'\nimport { initialV2ReplayInstallationCounters, validateV2ReplayInstallationCounters } from './replay/installation'\nimport type { V2ReplayInstallationCounters } from './replay/installation'\nimport { v1FlagJsonFromUnknown } from './feature-flags/json'\nimport type { V1FlagEvaluationContext } from './feature-flags/types'\nimport {\n freezeV1Value,\n hasOnlyKeys,\n hasOwn,\n hasOwnIndex,\n isArrayValue,\n isBooleanValue,\n isFunctionValue,\n isNonNegativeInteger,\n isNullValue,\n isNumberValue,\n isRecordValue,\n isStringValue,\n parseBoundedJson,\n unicodeCodePointLength,\n utf8ByteLength,\n} from './validation'\n\nexport const V1_DURABLE_STORAGE_SCHEMA_VERSION = 1\nexport const V1_MAX_DURABLE_QUEUE_COUNT = 10_000\nexport const V1_MAX_DURABLE_QUEUE_BYTES = 268_435_456\n\nconst V1_MAX_CAPTURE_PROPERTY_COUNT = 256\nconst V1_MAX_CAPTURE_PROPERTIES_BYTES = 1_048_576\n\nconst IDENTITY_KEYS = [\n 'schemaVersion',\n 'revision',\n 'contextRevision',\n 'anonymousId',\n 'userId',\n 'groups',\n 'superProperties',\n 'session',\n 'optedOut',\n 'updatedAt',\n 'migration',\n 'flagContext',\n] as const\nconst IDENTITY_REQUIRED_KEYS = IDENTITY_KEYS.filter((key) => key !== 'migration' && key !== 'flagContext')\nconst SESSION_KEYS = [\n 'id',\n 'startedAt',\n 'lastActivityAt',\n 'timeoutSeconds',\n 'maximumDurationSeconds',\n 'lifecycle',\n 'backgroundedAt',\n] as const\nconst MIGRATION_KEYS = ['sourceSchema', 'completedAt'] as const\nconst INSTALLATION_KEYS = [\n 'storageSchemaVersion',\n 'siteKey',\n 'identity',\n 'streamId',\n 'nextSequence',\n 'headSequence',\n 'queuedCount',\n 'queuedBytes',\n 'authorityBarrier',\n 'flagAuthorityInitialized',\n 'replay',\n] as const\nconst INSTALLATION_REQUIRED_KEYS = INSTALLATION_KEYS.filter(\n (key) => key !== 'authorityBarrier' && key !== 'flagAuthorityInitialized' && key !== 'replay'\n)\nconst FLAG_CONTEXT_KEYS = ['schemaVersion', 'personProperties', 'groupProperties'] as const\nconst AUTHORITY_BARRIER_KEYS = [\n 'kind',\n 'terminalScope',\n 'configIssuedAt',\n 'configSemanticHash',\n 'policySourceHash',\n 'contextRevision',\n 'decisionHash',\n] as const\nconst AUTHORITY_BARRIER_REQUIRED_KEYS = AUTHORITY_BARRIER_KEYS.filter((key) => key !== 'terminalScope')\nconst STORED_RECORD_KEYS = [\n 'storageSchemaVersion',\n 'siteKey',\n 'streamId',\n 'sequence',\n 'kind',\n 'recordId',\n 'captureVersions',\n 'payloadJson',\n 'payloadBytes',\n] as const\nconst EVENT_KEYS = [\n 'schemaVersion',\n 'eventId',\n 'streamId',\n 'sequence',\n 'contextRevision',\n 'kind',\n 'name',\n 'occurredAt',\n 'identity',\n 'sessionId',\n 'properties',\n 'groups',\n 'versions',\n] as const\nconst EVENT_DRAFT_KEYS = ['kind', 'name', 'occurredAt', 'expectedSessionId', 'properties', 'versions'] as const\nconst MUTATION_KEYS = ['mutationId', 'sequence', 'contextRevision', 'occurredAt', 'subject', 'change'] as const\nconst MUTATION_DRAFT_KEYS = ['occurredAt', 'change', 'versions'] as const\nconst IDENTITY_REFERENCE_KEYS = ['anonymousId', 'userId', 'revision'] as const\nconst MUTATION_SUBJECT_KEYS = ['anonymousId', 'userId', 'identityRevision'] as const\nconst VERSION_KEYS = ['schemaVersion', 'contractVersion', 'platform', 'runtime', 'facade', 'build'] as const\nconst VERSION_REQUIRED_KEYS = VERSION_KEYS.filter((key) => key !== 'build')\nconst RUNTIME_VERSION_KEYS = ['name', 'version'] as const\nconst FACADE_VERSION_KEYS = ['name', 'version'] as const\nconst ACKNOWLEDGEMENT_KEYS = ['siteKey', 'streamId', 'records'] as const\nconst SESSION_UPDATE_KEYS = ['type', 'expectedCurrentSessionId', 'session'] as const\nconst ACKNOWLEDGEMENT_REFERENCE_KEYS = ['sequence', 'kind', 'recordId'] as const\nconst RFC3339_PATTERN = /^(\\d{4})-(\\d{2})-(\\d{2})[Tt](\\d{2}):(\\d{2}):(\\d{2})(?:\\.(\\d+))?(?:[Zz]|([+-])(\\d{2}):(\\d{2}))$/\nconst SHA256_PATTERN = /^sha256:[a-f0-9]{64}$/\nconst RUNTIME_NAME_PATTERN = /^elu-[a-z0-9-]+$/\nconst FACADE_NAME_PATTERN = /^[A-Za-z][A-Za-z0-9._-]+$/\n\nexport interface V1PersistedSessionState {\n readonly id: string\n readonly startedAt: string\n readonly lastActivityAt: string\n readonly timeoutSeconds: number\n readonly maximumDurationSeconds: 86_400\n readonly lifecycle: 'active' | 'background'\n readonly backgroundedAt: string | null\n}\n\nexport interface V1PersistedMigrationState {\n readonly sourceSchema: string\n readonly completedAt: string\n}\n\nexport interface V1PersistedIdentityState {\n readonly schemaVersion: 1\n readonly revision: number\n readonly contextRevision: number\n readonly anonymousId: string\n readonly userId: string | null\n readonly groups: Readonly<Record<string, string>>\n readonly superProperties: V1JsonObject\n readonly session: V1PersistedSessionState | null\n readonly optedOut: boolean\n readonly updatedAt: string\n readonly migration?: V1PersistedMigrationState\n readonly flagContext?: V1PersistedFlagContext\n}\n\nexport interface V1PersistedFlagContext {\n readonly schemaVersion: 1\n readonly personProperties: V1JsonObject\n readonly groupProperties: Readonly<Record<string, V1JsonObject>>\n}\n\nexport interface V1DurableEventDraft {\n readonly kind: V1Event['kind']\n readonly name: string\n readonly occurredAt: string\n /** Causality assertion only; the persisted session remains authoritative. */\n readonly expectedSessionId: string\n readonly properties: V1JsonObject\n readonly versions: V1VersionContext\n}\n\nexport interface V1DurableMutationDraft {\n readonly occurredAt: string\n readonly change: V1MutationChange\n readonly versions: V1VersionContext\n}\n\nexport type V1DurableEventSessionUpdate =\n | Readonly<{ type: 'preserve' }>\n | Readonly<{\n type: 'replace'\n /** Compare-and-swap assertion for the transaction-current pre-transition session. */\n expectedCurrentSessionId: string | null\n session: V1PersistedSessionState\n }>\n\nexport type V1DurableLocalChange =\n | Readonly<{ type: 'setOptedOut'; optedOut: boolean; occurredAt: string }>\n | Readonly<{ type: 'resetGroups'; occurredAt: string }>\n | Readonly<{ type: 'resetIdentity'; anonymousId: string; occurredAt: string }>\n | Readonly<{\n type: 'setSuperProperties'\n set: V1JsonObject\n setOnce: V1JsonObject\n unset: readonly string[]\n occurredAt: string\n }>\n | Readonly<{\n type: 'replaceSession'\n expectedCurrentSessionId: string | null\n session: V1PersistedSessionState\n }>\n | Readonly<{ type: 'clearSession'; expectedCurrentSessionId: string | null; occurredAt: string }>\n /** Replaces the persisted flag evaluation context; a null member leaves that member unchanged. */\n | Readonly<{\n type: 'setFlagContext'\n personProperties: V1JsonObject | null\n groupProperties: Readonly<Record<string, V1JsonObject>> | null\n /** Merges the person properties into the transaction-current member instead of replacing it. */\n mergePersonProperties?: boolean\n /** Merges each named group type into the transaction-current member instead of replacing it. */\n mergeGroupProperties?: boolean\n /** Group types dropped from the transaction-current member before the group properties apply. */\n unsetGroupTypes?: readonly string[]\n occurredAt: string\n }>\n\nexport interface V1DurableRecordReference {\n readonly sequence: number\n readonly kind: 'event' | 'mutation'\n readonly recordId: string\n}\n\nexport interface V1DurableQueueRecord extends V1DurableRecordReference {\n readonly siteKey: string\n readonly streamId: string\n /** Capture-time SDK/facade metadata; deliberately excluded from the canonical payload bytes. */\n readonly captureVersions: V1VersionContext\n readonly batchRecord: V1BatchRecord\n readonly payloadJson: string\n /** Exact canonical V1BatchRecord bytes. Request-envelope overhead is intentionally separate. */\n readonly payloadBytes: number\n}\n\nexport interface V1DurableStateSnapshot {\n readonly siteKey: string\n readonly identity: V1PersistedIdentityState\n readonly streamId: string\n readonly nextSequence: number\n readonly headSequence: number\n readonly queuedCount: number\n readonly queuedBytes: number\n}\n\nexport interface V1DurableCaptureState {\n readonly state: V1DurableStateSnapshot\n readonly authorized: boolean\n /** Validated transaction observation; later replay writes must compare it to their current row. */\n readonly authorityBarrier: V1InstallationRow['authorityBarrier']\n}\n\nexport interface V1CaptureAdmissionDecision {\n readonly authorized: boolean\n /** A clock-terminal barrier must commit in the caller's current transaction before it returns. */\n readonly terminalInstallation: V1InstallationRow | null\n}\n\n/** Synchronous so replay can check authority inside its existing owner-row transaction. */\nexport type V1CaptureAdmissionGuard = (installation: unknown) => V1CaptureAdmissionDecision\n\nexport interface V1DurableAppendResult {\n readonly state: V1DurableStateSnapshot\n readonly records: readonly V1DurableQueueRecord[]\n}\n\nexport interface V1DurableRuntimeLimits {\n readonly maxCount: number\n readonly maxBytes: number\n}\n\nexport interface V1DurableRuntimeOptions {\n readonly siteKey: string\n readonly limits: V1DurableRuntimeLimits\n readonly storageFactory?: V1DurableStorageFactory\n readonly captureRuntime?: V1CaptureRuntimeOptions\n}\n\nexport interface V1CaptureRuntimeClock {\n readonly wallNow: () => string\n readonly monotonicNowMs: () => number\n}\n\nexport interface V1CaptureRuntimeOptions {\n readonly sha256?: V1Sha256\n readonly clock?: V1CaptureRuntimeClock\n readonly createSessionId?: () => string\n}\n\nexport interface V1CaptureActivityCommand {\n /** Session-eligible activity kinds; diagnostics never touch the capture session. */\n readonly kind: 'capture' | 'screen' | 'exception'\n readonly name: string\n readonly occurredAt: string\n readonly properties: V1JsonObject\n readonly versions: V1VersionContext\n}\n\nexport type V1CaptureAuthorityUpdateResult =\n | Readonly<{ status: 'authorized'; ownerEpoch: number }>\n | Readonly<{ status: 'terminal'; reason: string }>\n | Readonly<{ status: 'stale'; reason: string }>\n\nexport interface V1CaptureLifecycleWindowTarget {\n addEventListener(type: string, listener: () => void): void\n removeEventListener(type: string, listener: () => void): void\n}\n\nexport interface V1CaptureLifecycleDocumentTarget extends V1CaptureLifecycleWindowTarget {\n readonly hidden: boolean\n}\n\nexport interface V1DurableInitialState {\n readonly identity: V1PersistedIdentityState\n readonly streamId: string\n}\n\nexport interface V1DurableAcknowledgement {\n readonly siteKey: string\n readonly streamId: string\n readonly records: readonly V1DurableRecordReference[]\n}\n\nexport type V1DurableStateErrorCode =\n | 'invalid-input'\n | 'not-initialized'\n | 'queue-full'\n | 'head-record-too-large'\n | 'sequence-exhausted'\n | 'corrupt-storage'\n | 'unsupported-storage'\n | 'capture-not-authorized'\n | 'commit-unknown'\n\nexport class V1DurableStateError extends Error {\n readonly code: V1DurableStateErrorCode\n\n constructor(code: V1DurableStateErrorCode, message: string) {\n super(message)\n this.name = 'V1DurableStateError'\n this.code = code\n }\n}\n\nclass V1CaptureConfigTerminalError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'V1CaptureConfigTerminalError'\n }\n}\n\nexport interface V1InstallationRow extends V1DurableStateSnapshot {\n readonly storageSchemaVersion: 1\n readonly authorityBarrier: V1PersistedAuthorityBarrier | null\n readonly flagAuthorityInitialized?: true\n /** Present once the replay store has activated; counted with the event queue at admission. */\n readonly replay?: V2ReplayInstallationCounters\n}\n\ninterface V1PersistedAuthorityBarrier {\n readonly kind: 'authorized' | 'terminal'\n readonly terminalScope: 'config' | 'context' | null\n readonly configIssuedAt: string | null\n readonly configSemanticHash: `sha256:${string}` | null\n readonly policySourceHash: `sha256:${string}` | null\n readonly contextRevision: number | null\n readonly decisionHash: `sha256:${string}` | null\n}\n\ninterface V1CaptureSourceClock {\n readonly sourceToken: object\n readonly expiresAt: string\n readonly installedWallAt: string\n readonly monotonicStartedAtUs: number\n readonly monotonicBudgetUs: number\n}\n\n/** Owner-local issuance age survives executable identity and lifecycle replacement. */\ninterface V1CaptureSourceIssuance {\n readonly token: object\n readonly configIssuedAt: string\n readonly configSemanticHash: `sha256:${string}`\n readonly installedWallAt: string\n readonly observedWallFloor: string\n readonly monotonicStartedAtUs: number\n readonly monotonicBudgetUs: number | null\n readonly denied: boolean\n}\n\ninterface V1ExecutableCaptureAuthority extends V1CaptureSourceClock {\n readonly ownerEpoch: number\n readonly barrier: V1PersistedAuthorityBarrier\n readonly configSiteId: string\n readonly streamId: string\n readonly identityRevision: number\n readonly contextRevision: number\n readonly identityOptedOut: false\n readonly lifecycleEpoch: number\n readonly idleTimeoutSeconds: number\n readonly maximumDurationSeconds: 86_400\n}\n\ninterface V1StoredRecordRow {\n readonly storageSchemaVersion: 1\n readonly siteKey: string\n readonly streamId: string\n readonly sequence: number\n readonly kind: 'event' | 'mutation'\n readonly recordId: string\n readonly captureVersions: V1VersionContext\n readonly payloadJson: string\n readonly payloadBytes: number\n}\n\ninterface V1EncodedRecord {\n readonly stored: V1StoredRecordRow\n readonly exposed: V1DurableQueueRecord\n}\n\ntype V1NormalizedEventDraft = V1DurableEventDraft\n\ntype V1NormalizedMutationDraft = V1DurableMutationDraft\n\nconst fail = (code: V1DurableStateErrorCode, message: string): never => {\n throw new V1DurableStateError(code, message)\n}\n\nconst failInput = (message: string): never => fail('invalid-input', message)\nconst failCorrupt = (message: string): never => fail('corrupt-storage', message)\n\nconst assertExactRecord = (\n value: unknown,\n allowedKeys: readonly string[],\n requiredKeys: readonly string[],\n field: string,\n failure: (message: string) => never\n): Record<string, unknown> => {\n if (!isRecordValue(value) || Object.getPrototypeOf(value) !== Object.prototype) {\n failure(`${field} must be a plain object`)\n }\n if (!hasOnlyKeys(value, allowedKeys)) {\n failure(`${field} contains an unsupported field`)\n }\n for (const key of requiredKeys) {\n if (!hasOwn(value, key)) {\n failure(`${field}.${key} is required`)\n }\n }\n return value\n}\n\nconst assertString = (\n value: unknown,\n field: string,\n minimumLength: number,\n maximumLength: number,\n failure: (message: string) => never\n): string => {\n if (!isStringValue(value)) {\n failure(`${field} must be a string`)\n }\n const length = unicodeCodePointLength(value)\n if (isNullValue(length)) {\n failure(`${field} contains an unpaired Unicode surrogate`)\n }\n if (length < minimumLength || length > maximumLength) {\n failure(`${field} must contain between ${minimumLength} and ${maximumLength} Unicode code points`)\n }\n return value\n}\n\nconst assertIdentifier = (\n value: unknown,\n field: string,\n maximumLength: number,\n failure: (message: string) => never\n): string => assertString(value, field, 1, maximumLength, failure)\n\n// Closed field delegation retains the original validator and evaluation order.\nconst assertIdentifierField = (value: unknown, key: string, field: string, maximumLength: number, failure: (message: string) => never): string =>\n assertIdentifier(value, `${field}.${key}`, maximumLength, failure)\n\nconst assertInteger = (\n value: unknown,\n field: string,\n minimum: number,\n maximum: number,\n failure: (message: string) => never\n): number => {\n if (!isNonNegativeInteger(value) || value < minimum || value > maximum) {\n failure(`${field} must be an integer between ${minimum} and ${maximum}`)\n }\n return value\n}\n\n// Closed field delegation retains the original validator and evaluation order.\nconst assertIntegerField = (value: unknown, key: string, field: string, minimum: number, maximum: number, failure: (message: string) => never): number =>\n assertInteger(value, `${field}.${key}`, minimum, maximum, failure)\n\nconst assertBoolean = (value: unknown, field: string, failure: (message: string) => never): boolean => {\n if (!isBooleanValue(value)) {\n failure(`${field} must be a boolean`)\n }\n return value\n}\n\n// Closed field delegation retains the original validator and evaluation order.\nconst assertBooleanField = (value: unknown, key: string, field: string, failure: (message: string) => never): boolean =>\n assertBoolean(value, `${field}.${key}`, failure)\n\nconst daysInMonth = (year: number, month: number): number => {\n const date = new Date(0)\n date.setUTCFullYear(year, month, 0)\n return date.getUTCDate()\n}\n\ninterface V1ParsedDateTime {\n readonly source: string\n /** Ordinary POSIX second, or the preceding :59 second when leapSecond is true. */\n readonly epochSecond: number\n readonly leapSecond: boolean\n readonly fractionalDigits: string\n}\n\nconst parseDateTime = (value: unknown, field: string, failure: (message: string) => never): V1ParsedDateTime => {\n const source = assertString(value, field, 1, 128, failure)\n const match = RFC3339_PATTERN.exec(source)\n if (!match) {\n failure(`${field} must be an RFC 3339 date-time`)\n }\n const year = Number(match[1])\n const month = Number(match[2])\n const day = Number(match[3])\n const hour = Number(match[4])\n const minute = Number(match[5])\n const second = Number(match[6])\n const offsetHour = match[9] ? Number(match[9]) : 0\n const offsetMinute = match[10] ? Number(match[10]) : 0\n if (\n month < 1 ||\n month > 12 ||\n day < 1 ||\n day > daysInMonth(year, month) ||\n hour > 23 ||\n minute > 59 ||\n second > 60 ||\n offsetHour > 23 ||\n offsetMinute > 59\n ) {\n failure(`${field} must be a valid RFC 3339 date-time`)\n }\n const local = new Date(0)\n local.setUTCFullYear(year, month - 1, day)\n local.setUTCHours(hour, minute, Math.min(second, 59), 0)\n const localEpochSecond = local.getTime() / 1000\n const offsetDirection = match[8] === '-' ? -1 : 1\n const offsetSeconds = offsetDirection * (offsetHour * 60 + offsetMinute) * 60\n const epochSecond = localEpochSecond - offsetSeconds\n if (!isNumberValue(epochSecond) || !Number.isSafeInteger(epochSecond)) {\n failure(`${field} is outside the supported epoch range`)\n }\n if (second === 60) {\n const nextUtcSecond = new Date((epochSecond + 1) * 1000)\n const isLeapBoundary =\n nextUtcSecond.getUTCHours() === 0 &&\n nextUtcSecond.getUTCMinutes() === 0 &&\n nextUtcSecond.getUTCSeconds() === 0 &&\n nextUtcSecond.getUTCDate() === 1 &&\n (nextUtcSecond.getUTCMonth() === 0 || nextUtcSecond.getUTCMonth() === 6)\n if (!isLeapBoundary) {\n failure(`${field} must use second 60 only at a shifted UTC June or December leap boundary`)\n }\n }\n return freezeV1Value({\n source,\n epochSecond,\n leapSecond: second === 60,\n fractionalDigits: match[7] ?? '',\n })\n}\n\nconst assertDateTime = (value: unknown, field: string, failure: (message: string) => never): string =>\n parseDateTime(value, field, failure).source\n\n// Closed field delegation retains the original validator and evaluation order.\nconst assertDateTimeField = (value: unknown, key: string, field: string, failure: (message: string) => never): string =>\n assertDateTime(value, `${field}.${key}`, failure)\n\n/** Exact RFC 3339 comparison shared by durable state and batch delivery. */\nexport const compareV1DateTimes = (left: string, right: string): number => {\n const parsedLeft = parseDateTime(left, 'left date-time', failInput)\n const parsedRight = parseDateTime(right, 'right date-time', failInput)\n if (parsedLeft.epochSecond !== parsedRight.epochSecond) {\n return parsedLeft.epochSecond < parsedRight.epochSecond ? -1 : 1\n }\n if (parsedLeft.leapSecond !== parsedRight.leapSecond) {\n return parsedLeft.leapSecond ? 1 : -1\n }\n const width = Math.max(parsedLeft.fractionalDigits.length, parsedRight.fractionalDigits.length)\n const leftFraction = parsedLeft.fractionalDigits.padEnd(width, '0')\n const rightFraction = parsedRight.fractionalDigits.padEnd(width, '0')\n return leftFraction === rightFraction ? 0 : leftFraction < rightFraction ? -1 : 1\n}\n\n/** Exact age predicate shared by durable state and batch delivery. */\nexport const hasV1ElapsedAtLeastSeconds = (later: string, earlier: string, minimumSeconds: number): boolean => {\n const parsedLater = parseDateTime(later, 'later date-time', failInput)\n const parsedEarlier = parseDateTime(earlier, 'earlier date-time', failInput)\n const wholeSecondDifference = parsedLater.epochSecond - parsedEarlier.epochSecond + (parsedLater.leapSecond ? 1 : 0)\n if (wholeSecondDifference !== minimumSeconds) {\n return wholeSecondDifference > minimumSeconds\n }\n const width = Math.max(parsedLater.fractionalDigits.length, parsedEarlier.fractionalDigits.length)\n return parsedLater.fractionalDigits.padEnd(width, '0') >= parsedEarlier.fractionalDigits.padEnd(width, '0')\n}\n\n/**\n * Conservative whole-millisecond duration for a strict later/earlier pair. The later fractional\n * component is floored so a monotonic authorization cap never extends past exact RFC 3339 expiry.\n */\nexport const v1MillisecondsBetween = (later: string, earlier: string): number => {\n const parsedLater = parseDateTime(later, 'later date-time', failInput)\n const parsedEarlier = parseDateTime(earlier, 'earlier date-time', failInput)\n const millisecondFloor = (value: V1ParsedDateTime): number =>\n (value.epochSecond + (value.leapSecond ? 1 : 0)) * 1_000 +\n Number(value.fractionalDigits.slice(0, 3).padEnd(3, '0'))\n return millisecondFloor(parsedLater) - millisecondFloor(parsedEarlier)\n}\n\nexport const v1MicrosecondsBetween = (later: string, earlier: string): number => {\n const parsedLater = parseDateTime(later, 'later date-time', failInput)\n const parsedEarlier = parseDateTime(earlier, 'earlier date-time', failInput)\n const laterSecond = parsedLater.epochSecond + (parsedLater.leapSecond ? 1 : 0)\n const earlierSecond = parsedEarlier.epochSecond + (parsedEarlier.leapSecond ? 1 : 0)\n const secondDifference = laterSecond - earlierSecond\n if (!Number.isSafeInteger(secondDifference) || !Number.isSafeInteger(secondDifference * 1_000_000)) {\n return failInput('date-time duration exceeds the exact microsecond range')\n }\n const laterMicroseconds = Number(parsedLater.fractionalDigits.slice(0, 6).padEnd(6, '0'))\n const earlierMicroseconds = Number(parsedEarlier.fractionalDigits.slice(0, 6).padEnd(6, '0'))\n const residualWidth = Math.max(\n Math.max(0, parsedLater.fractionalDigits.length - 6),\n Math.max(0, parsedEarlier.fractionalDigits.length - 6)\n )\n const laterResidual = parsedLater.fractionalDigits.slice(6).padEnd(residualWidth, '0')\n const earlierResidual = parsedEarlier.fractionalDigits.slice(6).padEnd(residualWidth, '0')\n const residualFloorAdjustment = laterResidual < earlierResidual ? -1 : 0\n const result = secondDifference * 1_000_000 + laterMicroseconds - earlierMicroseconds + residualFloorAdjustment\n return Number.isSafeInteger(result) ? result : failInput('date-time duration exceeds the exact microsecond range')\n}\n\nconst validateHash = (\n value: unknown,\n field: string,\n nullable: boolean,\n failure: (message: string) => never\n): `sha256:${string}` | null => {\n if (nullable && isNullValue(value)) return null\n const hash = assertString(value, field, 71, 71, failure)\n if (!SHA256_PATTERN.test(hash)) failure(`${field} must be a lowercase SHA-256 identity`)\n return hash as `sha256:${string}`\n}\n\n// Closed field delegation retains the original validator and evaluation order.\nconst validateHashField = (value: unknown, key: string, field: string, nullable: boolean, failure: (message: string) => never): `sha256:${string}` | null =>\n validateHash(value, `${field}.${key}`, nullable, failure)\n\nconst validateAuthorityBarrier = (\n value: unknown,\n field: string,\n failure: (message: string) => never\n): V1PersistedAuthorityBarrier | null => {\n if (isNullValue(value)) return null\n const barrier = assertExactRecord(value, AUTHORITY_BARRIER_KEYS, AUTHORITY_BARRIER_REQUIRED_KEYS, field, failure)\n const kind =\n barrier.kind === 'authorized'\n ? 'authorized'\n : barrier.kind === 'terminal'\n ? 'terminal'\n : failure(`${field}.kind is unsupported`)\n const terminalScope = hasOwn(barrier, 'terminalScope')\n ? isNullValue(barrier.terminalScope)\n ? null\n : barrier.terminalScope === 'config' || barrier.terminalScope === 'context'\n ? barrier.terminalScope\n : failure(`${field}.terminalScope is unsupported`)\n : kind === 'terminal'\n ? 'config'\n : null\n const configIssuedAt = isNullValue(barrier.configIssuedAt)\n ? null\n : assertDateTimeField(barrier.configIssuedAt, \"configIssuedAt\", field, failure)\n const configSemanticHash = validateHashField(barrier.configSemanticHash, \"configSemanticHash\", field, true, failure)\n const policySourceHash = validateHashField(barrier.policySourceHash, \"policySourceHash\", field, true, failure)\n const contextRevision = isNullValue(barrier.contextRevision)\n ? null\n : assertIntegerField(barrier.contextRevision, \"contextRevision\", field, 0, Number.MAX_SAFE_INTEGER, failure)\n const decisionHash = validateHashField(barrier.decisionHash, \"decisionHash\", field, true, failure)\n if (isNullValue(configIssuedAt) !== isNullValue(configSemanticHash)) {\n failure(`${field} config boundary must be wholly present or absent`)\n }\n if (\n kind === 'authorized' &&\n (!configIssuedAt || !configSemanticHash || !policySourceHash || isNullValue(contextRevision) || !decisionHash)\n ) {\n failure(`${field} authorized state must contain the complete decision fingerprint`)\n }\n if ((kind === 'authorized' && !isNullValue(terminalScope)) || (kind === 'terminal' && isNullValue(terminalScope))) {\n failure(`${field} terminal scope does not match its barrier kind`)\n }\n return freezeV1Value({\n kind,\n terminalScope,\n configIssuedAt,\n configSemanticHash,\n policySourceHash,\n contextRevision,\n decisionHash,\n })\n}\n\nconst normalizeJsonValue = (\n value: unknown,\n field: string,\n failure: (message: string) => never,\n ancestors: WeakSet<object> = new WeakSet(),\n depth = 0\n): V1JsonValue => {\n if (depth > 64) {\n failure(`${field} exceeds the maximum JSON nesting depth`)\n }\n if (isNullValue(value) || isBooleanValue(value) || isStringValue(value)) {\n if (isStringValue(value) && isNullValue(unicodeCodePointLength(value))) {\n failure(`${field} contains an unpaired Unicode surrogate`)\n }\n return value\n }\n if (isNumberValue(value)) {\n return Object.is(value, -0) ? 0 : value\n }\n if (typeof value !== 'object' || isNullValue(value)) {\n failure(`${field} is outside the JSON value domain`)\n }\n if (ancestors.has(value)) {\n failure(`${field} contains a JSON cycle`)\n }\n ancestors.add(value)\n\n if (isArrayValue(value)) {\n const ownNames = Object.getOwnPropertyNames(value).filter((name) => name !== 'length')\n if (ownNames.length !== value.length) {\n failure(`${field} must be a dense JSON array without extra properties`)\n }\n const result: V1JsonValue[] = []\n for (let index = 0; index < value.length; index += 1) {\n if (!hasOwnIndex(value, index)) {\n failure(`${field} must not be sparse`)\n }\n const descriptor = Object.getOwnPropertyDescriptor(value, String(index))\n if (!descriptor || !hasOwn(descriptor as unknown as Record<string, unknown>, 'value')) {\n failure(`${field}[${index}] must be a data property`)\n }\n result.push(normalizeJsonValue(value[index], `${field}[${index}]`, failure, ancestors, depth + 1))\n }\n ancestors.delete(value)\n return freezeV1Value(result)\n }\n\n if (Object.getPrototypeOf(value) !== Object.prototype) {\n failure(`${field} must be a plain JSON object`)\n }\n const objectValue = value as Record<string, unknown>\n if (Object.getOwnPropertySymbols(value).length !== 0) {\n failure(`${field} must not contain symbol properties`)\n }\n const keys = Object.keys(value)\n if (Object.getOwnPropertyNames(value).length !== keys.length) {\n failure(`${field} must not contain hidden properties`)\n }\n const result: Record<string, V1JsonValue> = {}\n for (const key of keys) {\n if (isNullValue(unicodeCodePointLength(key))) {\n failure(`${field} contains an invalid Unicode property name`)\n }\n const descriptor = Object.getOwnPropertyDescriptor(value, key)\n if (!descriptor || !hasOwn(descriptor as unknown as Record<string, unknown>, 'value')) {\n failure(`${field}.${key} must be a data property`)\n }\n Object.defineProperty(result, key, {\n value: normalizeJsonValue(objectValue[key], `${field}.${key}`, failure, ancestors, depth + 1),\n enumerable: true,\n configurable: true,\n writable: true,\n })\n }\n ancestors.delete(value)\n return freezeV1Value(result)\n}\n\nconst normalizeJsonObject = (value: unknown, field: string, failure: (message: string) => never): V1JsonObject => {\n const normalized = normalizeJsonValue(value, field, failure)\n if (!isRecordValue(normalized)) {\n failure(`${field} must be a JSON object`)\n }\n return normalized as V1JsonObject\n}\n\n// Closed field delegation retains the original validator and evaluation order.\nconst normalizeJsonObjectField = (value: unknown, key: string, field: string, failure: (message: string) => never): V1JsonObject =>\n normalizeJsonObject(value, `${field}.${key}`, failure)\n\nconst validateGroups = (\n value: unknown,\n field: string,\n failure: (message: string) => never\n): Readonly<Record<string, string>> => {\n const groups = normalizeJsonObject(value, field, failure)\n const keys = Object.keys(groups)\n if (keys.length > 64) {\n failure(`${field} must not contain more than 64 groups`)\n }\n const result: Record<string, string> = {}\n for (const key of keys) {\n Object.defineProperty(result, key, {\n value: assertIdentifier(groups[key], `${field}.${key}`, 512, failure),\n enumerable: true,\n configurable: true,\n writable: true,\n })\n }\n return freezeV1Value(result)\n}\n\nconst validateFlagProperties = (value: unknown, field: string, failure: (message: string) => never): V1JsonObject => {\n const properties = normalizeJsonObject(value, field, failure)\n if (Object.keys(properties).length > 1_024) failure(`${field} must not contain more than 1024 properties`)\n try {\n if (v1FlagJsonFromUnknown(properties, field).kind !== 'object') failure(`${field} must be an object`)\n } catch (error) {\n failure(error instanceof Error ? error.message : `${field} is outside the flag JSON domain`)\n }\n return properties\n}\n\nconst validateFlagContext = (\n value: unknown,\n field: string,\n failure: (message: string) => never\n): V1PersistedFlagContext => {\n const context = assertExactRecord(value, FLAG_CONTEXT_KEYS, FLAG_CONTEXT_KEYS, field, failure)\n if (context.schemaVersion !== 1) failure(`${field}.schemaVersion must be 1`)\n const rawGroups = normalizeJsonObjectField(context.groupProperties, \"groupProperties\", field, failure)\n const groupTypes = Object.keys(rawGroups)\n if (groupTypes.length > 64) failure(`${field}.groupProperties must not contain more than 64 group types`)\n const groupProperties: Record<string, V1JsonObject> = {}\n for (const groupType of groupTypes) {\n Object.defineProperty(groupProperties, groupType, {\n value: validateFlagProperties(rawGroups[groupType], `${field}.groupProperties.${groupType}`, failure),\n enumerable: true,\n configurable: true,\n writable: true,\n })\n }\n return freezeV1Value({\n schemaVersion: 1,\n personProperties: validateFlagProperties(context.personProperties, `${field}.personProperties`, failure),\n groupProperties: freezeV1Value(groupProperties),\n })\n}\n\nconst emptyFlagContext = (): V1PersistedFlagContext =>\n freezeV1Value({\n schemaVersion: 1,\n personProperties: freezeV1Value({}),\n groupProperties: freezeV1Value({}),\n })\n\nconst flagContextHasValues = (context: V1PersistedFlagContext | undefined): boolean =>\n Boolean(\n context && (Object.keys(context.personProperties).length > 0 || Object.keys(context.groupProperties).length > 0)\n )\n\nconst validateSession = (\n value: unknown,\n field: string,\n failure: (message: string) => never\n): V1PersistedSessionState | null => {\n if (isNullValue(value)) {\n return null\n }\n const session = assertExactRecord(value, SESSION_KEYS, SESSION_KEYS, field, failure)\n const lifecycle = session.lifecycle\n if (lifecycle !== 'active' && lifecycle !== 'background') {\n failure(`${field}.lifecycle is unsupported`)\n }\n const backgroundedAt = isNullValue(session.backgroundedAt)\n ? null\n : assertDateTimeField(session.backgroundedAt, \"backgroundedAt\", field, failure)\n const result: V1PersistedSessionState = {\n id: assertIdentifierField(session.id, \"id\", field, 256, failure),\n startedAt: assertDateTimeField(session.startedAt, \"startedAt\", field, failure),\n lastActivityAt: assertDateTimeField(session.lastActivityAt, \"lastActivityAt\", field, failure),\n timeoutSeconds: assertIntegerField(session.timeoutSeconds, \"timeoutSeconds\", field, 60, 36_000, failure),\n maximumDurationSeconds: assertIntegerField(session.maximumDurationSeconds, \"maximumDurationSeconds\", field, 86_400, 86_400, failure) as 86_400,\n lifecycle,\n backgroundedAt,\n }\n if (compareV1DateTimes(result.lastActivityAt, result.startedAt) < 0) {\n failure(`${field}.lastActivityAt must not precede ${field}.startedAt`)\n }\n if (hasV1ElapsedAtLeastSeconds(result.lastActivityAt, result.startedAt, result.maximumDurationSeconds)) {\n failure(`${field}.lastActivityAt must precede the session maximum-duration boundary`)\n }\n if (result.lifecycle === 'active' && result.backgroundedAt) {\n failure(`${field}.backgroundedAt must be null while the session is active`)\n }\n if (result.lifecycle === 'background') {\n if (!result.backgroundedAt) {\n failure(`${field}.backgroundedAt is required while the session is backgrounded`)\n }\n if (compareV1DateTimes(result.backgroundedAt, result.lastActivityAt) < 0) {\n failure(`${field}.backgroundedAt must not precede ${field}.lastActivityAt`)\n }\n }\n return freezeV1Value(result)\n}\n\n// Closed field delegation retains the original validator and evaluation order.\nconst validateSessionField = (value: unknown, key: string, field: string, failure: (message: string) => never): V1PersistedSessionState | null =>\n validateSession(value, `${field}.${key}`, failure)\n\nconst validateMigration = (\n value: unknown,\n field: string,\n failure: (message: string) => never\n): V1PersistedMigrationState => {\n const migration = assertExactRecord(value, MIGRATION_KEYS, MIGRATION_KEYS, field, failure)\n return freezeV1Value({\n sourceSchema: assertIdentifierField(migration.sourceSchema, \"sourceSchema\", field, 128, failure),\n completedAt: assertDateTimeField(migration.completedAt, \"completedAt\", field, failure),\n })\n}\n\nconst validateIdentity = (\n value: unknown,\n field: string,\n failure: (message: string) => never\n): V1PersistedIdentityState => {\n const normalized = normalizeJsonObject(value, field, failure)\n const identity = assertExactRecord(normalized, IDENTITY_KEYS, IDENTITY_REQUIRED_KEYS, field, failure)\n if (identity.schemaVersion !== 1) {\n failure(`${field}.schemaVersion must be 1`)\n }\n const userId = isNullValue(identity.userId)\n ? null\n : assertIdentifierField(identity.userId, \"userId\", field, 512, failure)\n const result: V1PersistedIdentityState = {\n schemaVersion: 1,\n revision: assertIntegerField(identity.revision, \"revision\", field, 0, Number.MAX_SAFE_INTEGER, failure),\n contextRevision: assertIntegerField(identity.contextRevision, \"contextRevision\", field, 0, Number.MAX_SAFE_INTEGER, failure),\n anonymousId: assertIdentifierField(identity.anonymousId, \"anonymousId\", field, 256, failure),\n userId,\n groups: validateGroups(identity.groups, `${field}.groups`, failure),\n superProperties: normalizeJsonObjectField(identity.superProperties, \"superProperties\", field, failure),\n session: validateSessionField(identity.session, \"session\", field, failure),\n optedOut: assertBooleanField(identity.optedOut, \"optedOut\", field, failure),\n updatedAt: assertDateTimeField(identity.updatedAt, \"updatedAt\", field, failure),\n ...(hasOwn(identity, 'migration')\n ? { migration: validateMigration(identity.migration, `${field}.migration`, failure) }\n : {}),\n ...(hasOwn(identity, 'flagContext')\n ? { flagContext: validateFlagContext(identity.flagContext, `${field}.flagContext`, failure) }\n : {}),\n }\n if (result.revision > result.contextRevision) {\n failure(`${field}.revision must not exceed ${field}.contextRevision`)\n }\n if (\n result.session &&\n (compareV1DateTimes(result.updatedAt, result.session.lastActivityAt) < 0 ||\n (result.session.backgroundedAt && compareV1DateTimes(result.updatedAt, result.session.backgroundedAt) < 0))\n ) {\n failure(`${field}.updatedAt must not precede session activity`)\n }\n return freezeV1Value(result)\n}\n\nconst validateIdentityReference = (\n value: unknown,\n field: string,\n failure: (message: string) => never\n): V1IdentityReference => {\n const identity = assertExactRecord(value, IDENTITY_REFERENCE_KEYS, IDENTITY_REFERENCE_KEYS, field, failure)\n return freezeV1Value({\n anonymousId: assertIdentifierField(identity.anonymousId, \"anonymousId\", field, 256, failure),\n userId: isNullValue(identity.userId)\n ? null\n : assertIdentifierField(identity.userId, \"userId\", field, 512, failure),\n revision: assertIntegerField(identity.revision, \"revision\", field, 0, Number.MAX_SAFE_INTEGER, failure),\n })\n}\n\nconst validateMutationSubject = (\n value: unknown,\n field: string,\n failure: (message: string) => never\n): V1MutationSubject => {\n const subject = assertExactRecord(value, MUTATION_SUBJECT_KEYS, MUTATION_SUBJECT_KEYS, field, failure)\n return freezeV1Value({\n anonymousId: assertIdentifierField(subject.anonymousId, \"anonymousId\", field, 256, failure),\n userId: isNullValue(subject.userId) ? null : assertIdentifierField(subject.userId, \"userId\", field, 512, failure),\n identityRevision: assertIntegerField(subject.identityRevision, \"identityRevision\", field, 0, Number.MAX_SAFE_INTEGER, failure),\n })\n}\n\nconst validatePropertyNames = (\n value: unknown,\n field: string,\n failure: (message: string) => never\n): readonly string[] => {\n if (!isArrayValue(value) || value.length > 256) {\n failure(`${field} must be an array of at most 256 property names`)\n }\n const names: string[] = []\n const seen = new Set<string>()\n for (let index = 0; index < value.length; index += 1) {\n if (!hasOwnIndex(value, index)) {\n failure(`${field} must not be sparse`)\n }\n const name = assertIdentifier(value[index], `${field}[${index}]`, 512, failure)\n if (seen.has(name)) {\n failure(`${field} must contain unique property names`)\n }\n seen.add(name)\n names.push(name)\n }\n return freezeV1Value(names)\n}\n\n// Closed field delegation retains the original validator and evaluation order.\nconst validatePropertyNamesField = (value: unknown, key: string, field: string, failure: (message: string) => never): readonly string[] =>\n validatePropertyNames(value, `${field}.${key}`, failure)\n\nconst validateMutationChange = (\n value: unknown,\n field: string,\n failure: (message: string) => never\n): V1MutationChange => {\n const change = normalizeJsonObject(value, field, failure)\n switch (change.type) {\n case 'identify': {\n const parsed = assertExactRecord(\n change,\n ['type', 'userId', 'set', 'setOnce'],\n ['type', 'userId', 'set', 'setOnce'],\n field,\n failure\n )\n return freezeV1Value({\n type: 'identify',\n userId: assertIdentifierField(parsed.userId, \"userId\", field, 512, failure),\n set: normalizeJsonObjectField(parsed.set, \"set\", field, failure),\n setOnce: normalizeJsonObjectField(parsed.setOnce, \"setOnce\", field, failure),\n })\n }\n case 'linkAlias': {\n const parsed = assertExactRecord(\n change,\n ['type', 'aliasId', 'canonicalId'],\n ['type', 'aliasId', 'canonicalId'],\n field,\n failure\n )\n return freezeV1Value({\n type: 'linkAlias',\n aliasId: assertIdentifierField(parsed.aliasId, \"aliasId\", field, 512, failure),\n canonicalId: assertIdentifierField(parsed.canonicalId, \"canonicalId\", field, 512, failure),\n })\n }\n case 'setPersonProperties': {\n const parsed = assertExactRecord(\n change,\n ['type', 'set', 'setOnce', 'unset'],\n ['type', 'set', 'setOnce', 'unset'],\n field,\n failure\n )\n return freezeV1Value({\n type: 'setPersonProperties',\n set: normalizeJsonObjectField(parsed.set, \"set\", field, failure),\n setOnce: normalizeJsonObjectField(parsed.setOnce, \"setOnce\", field, failure),\n unset: validatePropertyNamesField(parsed.unset, \"unset\", field, failure),\n })\n }\n case 'associateGroup': {\n const parsed = assertExactRecord(\n change,\n ['type', 'groupType', 'groupKey'],\n ['type', 'groupType', 'groupKey'],\n field,\n failure\n )\n return freezeV1Value({\n type: 'associateGroup',\n groupType: assertIdentifierField(parsed.groupType, \"groupType\", field, 256, failure),\n groupKey: assertIdentifierField(parsed.groupKey, \"groupKey\", field, 512, failure),\n })\n }\n case 'setGroupProperties': {\n const parsed = assertExactRecord(\n change,\n ['type', 'groupType', 'groupKey', 'set', 'setOnce', 'unset'],\n ['type', 'groupType', 'groupKey', 'set', 'setOnce', 'unset'],\n field,\n failure\n )\n return freezeV1Value({\n type: 'setGroupProperties',\n groupType: assertIdentifierField(parsed.groupType, \"groupType\", field, 256, failure),\n groupKey: assertIdentifierField(parsed.groupKey, \"groupKey\", field, 512, failure),\n set: normalizeJsonObjectField(parsed.set, \"set\", field, failure),\n setOnce: normalizeJsonObjectField(parsed.setOnce, \"setOnce\", field, failure),\n unset: validatePropertyNamesField(parsed.unset, \"unset\", field, failure),\n })\n }\n default:\n return failure(`${field}.type is unsupported`)\n }\n}\n\nconst validateVersions = (value: unknown, field: string, failure: (message: string) => never): V1VersionContext => {\n const versions = assertExactRecord(value, VERSION_KEYS, VERSION_REQUIRED_KEYS, field, failure)\n if (versions.schemaVersion !== 1 || versions.contractVersion !== '1.0.0' || versions.platform !== 'browser') {\n failure(`${field} is not a browser v1 version context`)\n }\n const runtime = assertExactRecord(\n versions.runtime,\n RUNTIME_VERSION_KEYS,\n RUNTIME_VERSION_KEYS,\n `${field}.runtime`,\n failure\n )\n const facade = assertExactRecord(\n versions.facade,\n FACADE_VERSION_KEYS,\n FACADE_VERSION_KEYS,\n `${field}.facade`,\n failure\n )\n const runtimeName = assertIdentifier(runtime.name, `${field}.runtime.name`, V1_MAX_DURABLE_QUEUE_BYTES, failure)\n if (!RUNTIME_NAME_PATTERN.test(runtimeName)) {\n failure(`${field}.runtime.name must match the v1 runtime identifier pattern`)\n }\n const facadeName = assertIdentifier(facade.name, `${field}.facade.name`, V1_MAX_DURABLE_QUEUE_BYTES, failure)\n if (!FACADE_NAME_PATTERN.test(facadeName)) {\n failure(`${field}.facade.name must match the v1 facade identifier pattern`)\n }\n const result: V1VersionContext = {\n schemaVersion: 1,\n contractVersion: '1.0.0',\n platform: 'browser',\n runtime: freezeV1Value({\n name: runtimeName as `elu-${string}`,\n version: assertIdentifier(runtime.version, `${field}.runtime.version`, 64, failure),\n }),\n facade: freezeV1Value({\n name: facadeName,\n version: assertIdentifier(facade.version, `${field}.facade.version`, 64, failure),\n }),\n ...(hasOwn(versions, 'build')\n ? { build: assertIdentifierField(versions.build, \"build\", field, 128, failure) }\n : {}),\n }\n return freezeV1Value(result)\n}\n\n// Closed field delegation retains the original validator and evaluation order.\nconst validateVersionsField = (value: unknown, key: string, field: string, failure: (message: string) => never): V1VersionContext =>\n validateVersions(value, `${field}.${key}`, failure)\n\nconst sameVersionContext = (left: V1VersionContext, right: V1VersionContext): boolean =>\n left.schemaVersion === right.schemaVersion &&\n left.contractVersion === right.contractVersion &&\n left.platform === right.platform &&\n left.runtime.name === right.runtime.name &&\n left.runtime.version === right.runtime.version &&\n left.facade.name === right.facade.name &&\n left.facade.version === right.facade.version &&\n left.build === right.build\n\nconst validateEvent = (\n value: unknown,\n expected: V1DurableRecordReference & Readonly<{ streamId: string }>,\n field: string,\n failure: (message: string) => never\n): V1Event => {\n const event = assertExactRecord(value, EVENT_KEYS, EVENT_KEYS, field, failure)\n if (event.schemaVersion !== 1) {\n failure(`${field}.schemaVersion must be 1`)\n }\n if (\n event.eventId !== expected.recordId ||\n event.streamId !== expected.streamId ||\n event.sequence !== expected.sequence\n ) {\n failure(`${field} identity does not match its stored queue row`)\n }\n if (\n event.kind !== 'capture' &&\n event.kind !== 'screen' &&\n event.kind !== 'exception' &&\n event.kind !== 'diagnostic'\n ) {\n failure(`${field}.kind is unsupported`)\n }\n return freezeV1Value({\n schemaVersion: 1,\n eventId: assertIdentifierField(event.eventId, \"eventId\", field, 256, failure),\n streamId: assertIdentifierField(event.streamId, \"streamId\", field, 256, failure),\n sequence: assertIntegerField(event.sequence, \"sequence\", field, 0, Number.MAX_SAFE_INTEGER, failure),\n contextRevision: assertIntegerField(event.contextRevision, \"contextRevision\", field, 0, Number.MAX_SAFE_INTEGER, failure),\n kind: event.kind,\n name: assertIdentifierField(event.name, \"name\", field, 512, failure),\n occurredAt: assertDateTimeField(event.occurredAt, \"occurredAt\", field, failure),\n identity: validateIdentityReference(event.identity, `${field}.identity`, failure),\n sessionId: assertIdentifierField(event.sessionId, \"sessionId\", field, 256, failure),\n properties: normalizeJsonObjectField(event.properties, \"properties\", field, failure),\n groups: validateGroups(event.groups, `${field}.groups`, failure),\n versions: validateVersionsField(event.versions, \"versions\", field, failure),\n })\n}\n\nconst validateMutation = (\n value: unknown,\n expected: V1DurableRecordReference,\n field: string,\n failure: (message: string) => never\n): V1Mutation => {\n const mutation = assertExactRecord(value, MUTATION_KEYS, MUTATION_KEYS, field, failure)\n if (mutation.mutationId !== expected.recordId || mutation.sequence !== expected.sequence) {\n failure(`${field} identity does not match its stored queue row`)\n }\n return freezeV1Value({\n mutationId: assertIdentifierField(mutation.mutationId, \"mutationId\", field, 256, failure),\n sequence: assertIntegerField(mutation.sequence, \"sequence\", field, 0, Number.MAX_SAFE_INTEGER, failure),\n contextRevision: assertIntegerField(mutation.contextRevision, \"contextRevision\", field, 0, Number.MAX_SAFE_INTEGER, failure),\n occurredAt: assertDateTimeField(mutation.occurredAt, \"occurredAt\", field, failure),\n subject: validateMutationSubject(mutation.subject, `${field}.subject`, failure),\n change: validateMutationChange(mutation.change, `${field}.change`, failure),\n })\n}\n\nconst validateInstallation = (value: unknown, siteKey: string): V1InstallationRow => {\n const installation = assertExactRecord(\n value,\n INSTALLATION_KEYS,\n INSTALLATION_REQUIRED_KEYS,\n 'stored installation',\n failCorrupt\n )\n if (installation.storageSchemaVersion !== V1_DURABLE_STORAGE_SCHEMA_VERSION) {\n fail('unsupported-storage', 'stored installation schema version is unsupported')\n }\n if (installation.siteKey !== siteKey) {\n failCorrupt('stored installation site key does not match its storage scope')\n }\n const nextSequence = assertInteger(\n installation.nextSequence,\n 'stored installation nextSequence',\n 0,\n Number.MAX_SAFE_INTEGER,\n failCorrupt\n )\n const headSequence = assertInteger(\n installation.headSequence,\n 'stored installation headSequence',\n 0,\n Number.MAX_SAFE_INTEGER,\n failCorrupt\n )\n const queuedCount = assertInteger(\n installation.queuedCount,\n 'stored installation queuedCount',\n 0,\n V1_MAX_DURABLE_QUEUE_COUNT,\n failCorrupt\n )\n if (headSequence > nextSequence || nextSequence - headSequence !== queuedCount) {\n failCorrupt('stored installation sequence counters are inconsistent')\n }\n const row: V1InstallationRow = freezeV1Value({\n storageSchemaVersion: 1,\n siteKey: assertIdentifier(installation.siteKey, 'stored installation siteKey', 128, failCorrupt),\n identity: validateIdentity(installation.identity, 'stored installation identity', failCorrupt),\n streamId: assertIdentifier(installation.streamId, 'stored installation streamId', 256, failCorrupt),\n nextSequence,\n headSequence,\n queuedCount,\n queuedBytes: assertInteger(\n installation.queuedBytes,\n 'stored installation queuedBytes',\n 0,\n V1_MAX_DURABLE_QUEUE_BYTES,\n failCorrupt\n ),\n authorityBarrier: hasOwn(installation, 'authorityBarrier')\n ? validateAuthorityBarrier(\n installation.authorityBarrier,\n 'stored installation authorityBarrier',\n failCorrupt\n )\n : null,\n ...(hasOwn(installation, 'flagAuthorityInitialized')\n ? installation.flagAuthorityInitialized === true\n ? { flagAuthorityInitialized: true as const }\n : failCorrupt('stored installation flagAuthorityInitialized must be true when present')\n : {}),\n ...(hasOwn(installation, 'replay')\n ? {\n replay: validateV2ReplayInstallationCounters(\n installation.replay,\n 'stored installation replay',\n failCorrupt,\n { siteKey: installation.siteKey, streamId: installation.streamId }\n ),\n }\n : {}),\n })\n return row\n}\n\n/** Internal bridge used by the unwired flag store to share the durable identity authority. */\nexport const validateV1FlagInstallation = (value: unknown, siteKey: string): V1InstallationRow =>\n validateInstallation(value, siteKey)\n\n/** Internal bridge used by the unwired replay store to read the shared installation row. */\nexport const validateV1ReplayInstallation = (value: unknown, siteKey: string): V1InstallationRow =>\n validateInstallation(value, siteKey)\n\n/** Adds only the zeroed replay counters; every other installation field is preserved. */\nexport const initializeV1ReplayInstallation = (value: unknown, siteKey: string): V1InstallationRow => {\n const current = validateInstallation(value, siteKey)\n return current.replay\n ? current\n : validateInstallation({ ...current, replay: initialV2ReplayInstallationCounters() }, siteKey)\n}\n\n/** Adds only the lazy empty flag context and marker; all queue/session fields are preserved. */\nexport const initializeV1FlagInstallation = (value: unknown, siteKey: string): V1InstallationRow => {\n const current = validateInstallation(value, siteKey)\n return validateInstallation(\n {\n ...current,\n identity: current.identity.flagContext\n ? current.identity\n : freezeV1Value({ ...current.identity, flagContext: emptyFlagContext() }),\n flagAuthorityInitialized: true,\n },\n siteKey\n )\n}\n\nconst requireFlagJsonObject = (\n value: unknown,\n field: string\n): ReturnType<typeof v1FlagJsonFromUnknown> & {\n readonly kind: 'object'\n} => {\n const node = v1FlagJsonFromUnknown(value, field)\n if (node.kind !== 'object') return failCorrupt(`${field} must be an object`)\n return node\n}\n\n/** Builds a detached flag context from the transaction-current installation row. */\nexport const v1FlagEvaluationContextFromInstallation = (\n value: unknown,\n siteKey: string,\n versionsValue: unknown\n): V1FlagEvaluationContext => {\n const installation = validateInstallation(value, siteKey)\n const versions = validateVersions(versionsValue, 'flag versions', failCorrupt)\n const context = installation.identity.flagContext ?? emptyFlagContext()\n const associatedGroupProperties: Record<string, V1JsonObject> = {}\n for (const groupType of Object.keys(installation.identity.groups)) {\n const properties = context.groupProperties[groupType]\n if (properties) {\n Object.defineProperty(associatedGroupProperties, groupType, {\n value: properties,\n enumerable: true,\n configurable: true,\n writable: true,\n })\n }\n }\n return freezeV1Value({\n identity: freezeV1Value({\n anonymousId: installation.identity.anonymousId,\n userId: installation.identity.userId,\n revision: installation.identity.revision,\n }),\n contextRevision: installation.identity.contextRevision,\n optedOut: installation.identity.optedOut,\n personProperties: requireFlagJsonObject(context.personProperties, 'flag personProperties'),\n groups: requireFlagJsonObject(installation.identity.groups, 'flag groups'),\n groupProperties: requireFlagJsonObject(freezeV1Value(associatedGroupProperties), 'flag groupProperties'),\n versions: requireFlagJsonObject(versions, 'flag versions'),\n })\n}\n\nconst validateStoredRecord = (\n value: unknown,\n installation: V1InstallationRow,\n expectedSequence: number\n): V1DurableQueueRecord => {\n const stored = assertExactRecord(value, STORED_RECORD_KEYS, STORED_RECORD_KEYS, 'stored record', failCorrupt)\n if (stored.storageSchemaVersion !== V1_DURABLE_STORAGE_SCHEMA_VERSION) {\n fail('unsupported-storage', 'stored record schema version is unsupported')\n }\n if (stored.siteKey !== installation.siteKey || stored.streamId !== installation.streamId) {\n failCorrupt('stored record scope does not match its installation')\n }\n if (stored.sequence !== expectedSequence) {\n failCorrupt('stored records are not one contiguous ordered prefix')\n }\n const kind =\n stored.kind === 'event'\n ? 'event'\n : stored.kind === 'mutation'\n ? 'mutation'\n : failCorrupt('stored record kind is unsupported')\n const recordId = assertIdentifier(stored.recordId, 'stored record recordId', 256, failCorrupt)\n const sequence = assertInteger(stored.sequence, 'stored record sequence', 0, Number.MAX_SAFE_INTEGER, failCorrupt)\n const captureVersions = validateVersions(stored.captureVersions, 'stored record captureVersions', failCorrupt)\n const payloadBytes = assertInteger(\n stored.payloadBytes,\n 'stored record payloadBytes',\n 1,\n V1_MAX_DURABLE_QUEUE_BYTES,\n failCorrupt\n )\n const payloadJson = assertString(\n stored.payloadJson,\n 'stored record payloadJson',\n 1,\n V1_MAX_DURABLE_QUEUE_BYTES,\n failCorrupt\n )\n if (utf8ByteLength(payloadJson) !== payloadBytes) {\n failCorrupt('stored record payload byte count is inconsistent')\n }\n\n let parsed: { readonly value: unknown; readonly serialized: string }\n try {\n parsed = parseBoundedJson(payloadJson, V1_MAX_DURABLE_QUEUE_BYTES, 'stored record payload')\n } catch {\n return failCorrupt('stored record payload is not valid bounded JSON')\n }\n if (parsed.serialized !== payloadJson) {\n failCorrupt('stored record payload is not in the stable JSON encoding')\n }\n const wrapper = assertExactRecord(\n parsed.value,\n kind === 'event' ? ['kind', 'event'] : ['kind', 'mutation'],\n kind === 'event' ? ['kind', 'event'] : ['kind', 'mutation'],\n 'stored batch record',\n failCorrupt\n )\n if (wrapper.kind !== kind) {\n failCorrupt('stored batch record kind does not match its queue row')\n }\n const reference: V1DurableRecordReference = freezeV1Value({ sequence, kind, recordId })\n const batchRecord: V1BatchRecord =\n kind === 'event'\n ? freezeV1Value({\n kind: 'event',\n event: validateEvent(\n wrapper.event,\n { ...reference, streamId: installation.streamId },\n 'stored event',\n failCorrupt\n ),\n })\n : freezeV1Value({\n kind: 'mutation',\n mutation: validateMutation(wrapper.mutation, reference, 'stored mutation', failCorrupt),\n })\n if (JSON.stringify(batchRecord) !== payloadJson) {\n failCorrupt('stored batch record is not in the canonical v1 encoding')\n }\n if (batchRecord.kind === 'event' && !sameVersionContext(captureVersions, batchRecord.event.versions)) {\n failCorrupt('stored event capture versions do not match its payload versions')\n }\n return freezeV1Value({\n ...reference,\n siteKey: installation.siteKey,\n streamId: installation.streamId,\n captureVersions,\n batchRecord,\n payloadJson,\n payloadBytes,\n })\n}\n\nconst snapshotFromRow = (row: V1InstallationRow): V1DurableStateSnapshot =>\n freezeV1Value({\n siteKey: row.siteKey,\n identity: row.identity,\n streamId: row.streamId,\n nextSequence: row.nextSequence,\n headSequence: row.headSequence,\n queuedCount: row.queuedCount,\n queuedBytes: row.queuedBytes,\n })\n\nconst auditStoredQueue = async (transaction: V1DurableStorageTransaction, row: V1InstallationRow): Promise<void> => {\n let queuedCount = 0\n let queuedBytes = 0\n await transaction.scanAllRecords(row.siteKey, (rawRecord) => {\n if (queuedCount >= row.queuedCount) {\n return failCorrupt('stored queue contains more records than its counter')\n }\n const record = validateStoredRecord(rawRecord, row, row.headSequence + queuedCount)\n if (!Number.isSafeInteger(queuedBytes + record.payloadBytes)) {\n failCorrupt('stored queue byte counter is exhausted')\n }\n queuedBytes += record.payloadBytes\n queuedCount += 1\n return true\n })\n if (queuedCount !== row.queuedCount) {\n failCorrupt('stored queue count does not match its records')\n }\n if (queuedBytes !== row.queuedBytes) {\n failCorrupt('stored queue byte count does not match its records')\n }\n}\n\ninterface V1AuditedInstallation {\n readonly row: V1InstallationRow\n readonly requiresMigrationWrite: boolean\n}\n\nconst readAuditedState = async (\n transaction: V1DurableStorageTransaction,\n siteKey: string\n): Promise<V1AuditedInstallation | null> => {\n const installation = await transaction.getInstallation(siteKey)\n if (typeof installation === 'undefined') {\n let hasOrphanRecord = false\n await transaction.scanAllRecords(siteKey, () => {\n hasOrphanRecord = true\n return false\n })\n if (hasOrphanRecord) {\n failCorrupt('stored records exist without an installation')\n }\n return null\n }\n let row = validateInstallation(installation, siteKey)\n await auditStoredQueue(transaction, row)\n const legacyBarrier = !hasOwn(installation as Record<string, unknown>, 'authorityBarrier')\n const rawBarrier = (installation as Record<string, unknown>).authorityBarrier\n const legacyBarrierScope = isRecordValue(rawBarrier) && !hasOwn(rawBarrier, 'terminalScope')\n const legacyOptedOutSession = row.identity.optedOut && !isNullValue(row.identity.session)\n if (legacyOptedOutSession) {\n row = freezeV1Value({\n ...row,\n identity: validateIdentity({ ...row.identity, session: null }, 'migrated opted-out identity', failCorrupt),\n })\n }\n return freezeV1Value({\n row,\n requiresMigrationWrite: legacyBarrier || legacyBarrierScope || legacyOptedOutSession,\n })\n}\n\nconst readInstallation = async (\n transaction: V1DurableStorageTransaction,\n siteKey: string\n): Promise<V1InstallationRow> => {\n const installation = await transaction.getInstallation(siteKey)\n if (typeof installation === 'undefined') {\n return failCorrupt('installation disappeared after initialization')\n }\n return validateInstallation(installation, siteKey)\n}\n\nconst normalizeDraftArray = (value: unknown, field: string): readonly unknown[] => {\n const values = isArrayValue(value) ? value : failInput(`${field} must be an array of 1 to 100 records`)\n if (values.length < 1 || values.length > 100) {\n failInput(`${field} must be an array of 1 to 100 records`)\n }\n for (let index = 0; index < values.length; index += 1) {\n if (!hasOwnIndex(values, index)) {\n failInput(`${field} must not be sparse`)\n }\n }\n return values\n}\n\nconst normalizeEventDrafts = (value: unknown): readonly V1NormalizedEventDraft[] => {\n const values = normalizeDraftArray(value, 'event drafts')\n return freezeV1Value(\n values.map((value, index) => {\n const field = `event draft ${index}`\n const normalized = normalizeJsonObject(value, field, failInput)\n const draft = assertExactRecord(normalized, EVENT_DRAFT_KEYS, EVENT_DRAFT_KEYS, field, failInput)\n const kind: V1Event['kind'] =\n draft.kind === 'capture' ||\n draft.kind === 'screen' ||\n draft.kind === 'exception' ||\n draft.kind === 'diagnostic'\n ? draft.kind\n : failInput(`${field}.kind is unsupported`)\n return freezeV1Value({\n kind,\n name: assertIdentifierField(draft.name, \"name\", field, 512, failInput),\n occurredAt: assertDateTimeField(draft.occurredAt, \"occurredAt\", field, failInput),\n expectedSessionId: assertIdentifierField(draft.expectedSessionId, \"expectedSessionId\", field, 256, failInput),\n properties: normalizeJsonObjectField(draft.properties, \"properties\", field, failInput),\n versions: validateVersionsField(draft.versions, \"versions\", field, failInput),\n })\n })\n )\n}\n\nconst normalizeMutationDrafts = (value: unknown): readonly V1NormalizedMutationDraft[] => {\n const values = normalizeDraftArray(value, 'mutation drafts')\n return freezeV1Value(\n values.map((value, index) => {\n const field = `mutation draft ${index}`\n const normalized = normalizeJsonObject(value, field, failInput)\n const draft = assertExactRecord(normalized, MUTATION_DRAFT_KEYS, MUTATION_DRAFT_KEYS, field, failInput)\n return freezeV1Value({\n occurredAt: assertDateTimeField(draft.occurredAt, \"occurredAt\", field, failInput),\n change: validateMutationChange(draft.change, `${field}.change`, failInput),\n versions: validateVersionsField(draft.versions, \"versions\", field, failInput),\n })\n })\n )\n}\n\nconst normalizeSessionUpdate = (value: unknown): V1DurableEventSessionUpdate => {\n const normalized = normalizeJsonObject(value, 'event session update', failInput)\n if (normalized.type === 'preserve') {\n assertExactRecord(normalized, ['type'], ['type'], 'event session update', failInput)\n return freezeV1Value({ type: 'preserve' })\n }\n if (normalized.type === 'replace') {\n const update = assertExactRecord(\n normalized,\n SESSION_UPDATE_KEYS,\n SESSION_UPDATE_KEYS,\n 'event session update',\n failInput\n )\n const session = validateSessionField(update.session, \"session\", \"event session update\", failInput)\n if (!session) {\n return failInput('event session update.session must not be null')\n }\n const expectedCurrentSessionId = isNullValue(update.expectedCurrentSessionId)\n ? null\n : assertIdentifierField(update.expectedCurrentSessionId, \"expectedCurrentSessionId\", \"event session update\", 256, failInput)\n return freezeV1Value({ type: 'replace', expectedCurrentSessionId, session })\n }\n return failInput('event session update.type is unsupported')\n}\n\nconst normalizeLocalChange = (value: unknown): V1DurableLocalChange => {\n const normalized = normalizeJsonObject(value, 'local change', failInput)\n const occurredAt = (): string => assertDateTimeField(normalized.occurredAt, \"occurredAt\", \"local change\", failInput)\n switch (normalized.type) {\n case 'setOptedOut': {\n const change = assertExactRecord(\n normalized,\n ['type', 'optedOut', 'occurredAt'],\n ['type', 'optedOut', 'occurredAt'],\n 'local change',\n failInput\n )\n return freezeV1Value({\n type: 'setOptedOut',\n optedOut: assertBooleanField(change.optedOut, \"optedOut\", \"local change\", failInput),\n occurredAt: occurredAt(),\n })\n }\n case 'resetGroups':\n assertExactRecord(normalized, ['type', 'occurredAt'], ['type', 'occurredAt'], 'local change', failInput)\n return freezeV1Value({ type: 'resetGroups', occurredAt: occurredAt() })\n case 'resetIdentity': {\n const change = assertExactRecord(\n normalized,\n ['type', 'anonymousId', 'occurredAt'],\n ['type', 'anonymousId', 'occurredAt'],\n 'local change',\n failInput\n )\n return freezeV1Value({\n type: 'resetIdentity',\n anonymousId: assertIdentifierField(change.anonymousId, \"anonymousId\", \"local change\", 256, failInput),\n occurredAt: occurredAt(),\n })\n }\n case 'setSuperProperties': {\n const change = assertExactRecord(\n normalized,\n ['type', 'set', 'setOnce', 'unset', 'occurredAt'],\n ['type', 'set', 'setOnce', 'unset', 'occurredAt'],\n 'local change',\n failInput\n )\n return freezeV1Value({\n type: 'setSuperProperties',\n set: normalizeJsonObjectField(change.set, \"set\", \"local change\", failInput),\n setOnce: normalizeJsonObjectField(change.setOnce, \"setOnce\", \"local change\", failInput),\n unset: validatePropertyNamesField(change.unset, \"unset\", \"local change\", failInput),\n occurredAt: occurredAt(),\n })\n }\n case 'replaceSession': {\n const change = assertExactRecord(\n normalized,\n ['type', 'expectedCurrentSessionId', 'session'],\n ['type', 'expectedCurrentSessionId', 'session'],\n 'local change',\n failInput\n )\n const session = validateSessionField(change.session, \"session\", \"local change\", failInput)\n if (!session) {\n return failInput('local change.session must not be null')\n }\n return freezeV1Value({\n type: 'replaceSession',\n expectedCurrentSessionId: isNullValue(change.expectedCurrentSessionId)\n ? null\n : assertIdentifier(\n change.expectedCurrentSessionId,\n 'local change.expectedCurrentSessionId',\n 256,\n failInput\n ),\n session,\n })\n }\n case 'clearSession': {\n const change = assertExactRecord(\n normalized,\n ['type', 'expectedCurrentSessionId', 'occurredAt'],\n ['type', 'expectedCurrentSessionId', 'occurredAt'],\n 'local change',\n failInput\n )\n return freezeV1Value({\n type: 'clearSession',\n expectedCurrentSessionId: isNullValue(change.expectedCurrentSessionId)\n ? null\n : assertIdentifier(\n change.expectedCurrentSessionId,\n 'local change.expectedCurrentSessionId',\n 256,\n failInput\n ),\n occurredAt: occurredAt(),\n })\n }\n case 'setFlagContext': {\n const change = assertExactRecord(\n normalized,\n [\n 'type',\n 'personProperties',\n 'groupProperties',\n 'mergePersonProperties',\n 'mergeGroupProperties',\n 'unsetGroupTypes',\n 'occurredAt',\n ],\n ['type', 'personProperties', 'groupProperties', 'occurredAt'],\n 'local change',\n failInput\n )\n const groupProperties = isNullValue(change.groupProperties)\n ? null\n : validateFlagContext(\n { schemaVersion: 1, personProperties: {}, groupProperties: change.groupProperties },\n 'local change',\n failInput\n ).groupProperties\n return freezeV1Value({\n type: 'setFlagContext',\n personProperties: isNullValue(change.personProperties)\n ? null\n : validateFlagProperties(change.personProperties, 'local change.personProperties', failInput),\n groupProperties,\n ...(hasOwn(change, 'mergePersonProperties')\n ? {\n mergePersonProperties: assertBooleanField(change.mergePersonProperties, \"mergePersonProperties\", \"local change\", failInput),\n }\n : {}),\n ...(hasOwn(change, 'mergeGroupProperties')\n ? {\n mergeGroupProperties: assertBooleanField(change.mergeGroupProperties, \"mergeGroupProperties\", \"local change\", failInput),\n }\n : {}),\n ...(hasOwn(change, 'unsetGroupTypes')\n ? {\n unsetGroupTypes: validatePropertyNamesField(change.unsetGroupTypes, \"unsetGroupTypes\", \"local change\", failInput),\n }\n : {}),\n occurredAt: occurredAt(),\n })\n }\n default:\n return failInput('local change.type is unsupported')\n }\n}\n\nconst streamFingerprint = (streamId: string): string => {\n const moduli = [4_294_967_291, 4_294_967_279, 4_294_967_231, 4_294_967_197] as const\n const multipliers = [131, 137, 139, 149] as const\n const hashes = [2_166_136_261, 2_166_136_247, 2_166_136_229, 2_166_136_213]\n for (let index = 0; index < streamId.length; index += 1) {\n const code = streamId.charCodeAt(index)\n for (let part = 0; part < hashes.length; part += 1) {\n hashes[part] = (hashes[part] * multipliers[part] + code + part) % moduli[part]\n }\n }\n return hashes.map((hash) => hash.toString(16).padStart(8, '0')).join('')\n}\n\nconst recordIdFor = (kind: 'event' | 'mutation', streamId: string, sequence: number): string =>\n `elu_${kind === 'event' ? 'e' : 'm'}_${streamFingerprint(streamId)}_${sequence.toString(36)}`\n\nconst incrementStateCounter = (value: number, field: string): number => {\n if (value >= Number.MAX_SAFE_INTEGER) {\n return fail('sequence-exhausted', `${field} is exhausted`)\n }\n return value + 1\n}\n\nconst requireTimestampNotBefore = (candidate: string, current: string, field: string): void => {\n if (compareV1DateTimes(candidate, current) < 0) {\n failInput(`${field} must not move persisted time backward`)\n }\n}\n\nconst requireCurrentSessionId = (\n current: V1PersistedIdentityState,\n expectedCurrentSessionId: string | null,\n field: string\n): void => {\n if (expectedCurrentSessionId !== (current.session?.id ?? null)) {\n failInput(`${field} lost its current-session compare-and-swap`)\n }\n}\n\nconst copyGroupsWithAssociation = (\n groups: Readonly<Record<string, string>>,\n groupType: string,\n groupKey: string\n): Readonly<Record<string, string>> => {\n const result: Record<string, string> = {}\n for (const key of Object.keys(groups)) {\n Object.defineProperty(result, key, {\n value: groups[key],\n enumerable: true,\n configurable: true,\n writable: true,\n })\n }\n Object.defineProperty(result, groupType, {\n value: groupKey,\n enumerable: true,\n configurable: true,\n writable: true,\n })\n return freezeV1Value(result)\n}\n\nconst applyJsonProperties = (\n current: V1JsonObject,\n set: V1JsonObject,\n setOnce: V1JsonObject,\n unset: readonly string[]\n): V1JsonObject => {\n const result: Record<string, V1JsonValue> = {}\n const define = (key: string, value: V1JsonValue): void => {\n Object.defineProperty(result, key, { value, enumerable: true, configurable: true, writable: true })\n }\n for (const key of Object.keys(current)) define(key, current[key])\n for (const key of unset) delete result[key]\n for (const key of Object.keys(setOnce)) {\n if (!hasOwn(result, key)) define(key, setOnce[key])\n }\n for (const key of Object.keys(set)) define(key, set[key])\n return freezeV1Value(result)\n}\n\nconst copyFlagGroupProperties = (\n groups: Readonly<Record<string, V1JsonObject>>,\n groupType: string,\n properties: V1JsonObject | null\n): Readonly<Record<string, V1JsonObject>> => {\n const result: Record<string, V1JsonObject> = {}\n for (const key of Object.keys(groups)) {\n if (key !== groupType) {\n Object.defineProperty(result, key, {\n value: groups[key],\n enumerable: true,\n configurable: true,\n writable: true,\n })\n }\n }\n if (properties) {\n Object.defineProperty(result, groupType, {\n value: properties,\n enumerable: true,\n configurable: true,\n writable: true,\n })\n }\n return freezeV1Value(result)\n}\n\nconst mergeFlagGroupProperties = (\n current: Readonly<Record<string, V1JsonObject>>,\n overlay: Readonly<Record<string, V1JsonObject>>\n): Readonly<Record<string, V1JsonObject>> => {\n let result = current\n for (const groupType of Object.keys(overlay)) {\n result = copyFlagGroupProperties(\n result,\n groupType,\n applyJsonProperties(result[groupType] ?? freezeV1Value({}), overlay[groupType], freezeV1Value({}), [])\n )\n }\n return result\n}\n\nconst withFlagContext = (\n current: V1PersistedIdentityState,\n update: (context: V1PersistedFlagContext) => V1PersistedFlagContext\n): Readonly<{ flagContext?: V1PersistedFlagContext }> =>\n current.flagContext ? freezeV1Value({ flagContext: update(current.flagContext) }) : freezeV1Value({})\n\nconst updatePersonFlagContext = (\n context: V1PersistedFlagContext,\n set: V1JsonObject,\n setOnce: V1JsonObject,\n unset: readonly string[]\n): V1PersistedFlagContext =>\n freezeV1Value({\n ...context,\n personProperties: applyJsonProperties(context.personProperties, set, setOnce, unset),\n })\n\nconst mergeEventProperties = (\n superProperties: V1JsonObject,\n eventProperties: V1JsonObject,\n versions: V1VersionContext\n): V1JsonObject => {\n const merged = applyJsonProperties(superProperties, eventProperties, freezeV1Value({}), freezeV1Value([]))\n return applyJsonProperties(\n merged,\n freezeV1Value({\n $elu_contract_version: versions.contractVersion,\n $elu_sdk_version: versions.runtime.version,\n $elu_facade_version: versions.facade.version,\n }),\n freezeV1Value({}),\n freezeV1Value([])\n )\n}\n\nconst validateSessionTransition = (\n current: V1PersistedIdentityState,\n session: V1PersistedSessionState,\n eventEligible: boolean\n): V1PersistedIdentityState => {\n if (eventEligible && session.lifecycle !== 'active') {\n failInput('event session must be active')\n }\n if ((!current.session || current.session.id !== session.id) && session.lifecycle !== 'active') {\n failInput('a replacement session must begin in the active lifecycle')\n }\n const transitionAt = session.backgroundedAt ?? session.lastActivityAt\n requireTimestampNotBefore(transitionAt, current.updatedAt, 'session activity')\n if (current.session) {\n if (current.session.id === session.id) {\n if (current.session.startedAt !== session.startedAt) {\n failInput('a retained session ID must keep its original startedAt')\n }\n requireTimestampNotBefore(session.lastActivityAt, current.session.lastActivityAt, 'session lastActivityAt')\n if (\n hasV1ElapsedAtLeastSeconds(\n session.lastActivityAt,\n current.session.lastActivityAt,\n Math.min(current.session.timeoutSeconds, session.timeoutSeconds)\n )\n ) {\n failInput('a retained session must remain before its idle timeout')\n }\n } else {\n requireTimestampNotBefore(\n session.startedAt,\n current.session.lastActivityAt,\n 'replacement session startedAt'\n )\n }\n }\n return validateIdentity({ ...current, session, updatedAt: transitionAt }, 'derived session identity', failInput)\n}\n\nconst applyMutation = (\n current: V1PersistedIdentityState,\n draft: V1NormalizedMutationDraft\n): V1PersistedIdentityState => {\n requireTimestampNotBefore(draft.occurredAt, current.updatedAt, 'mutation occurredAt')\n const contextRevision = incrementStateCounter(current.contextRevision, 'identity context revision')\n const base = { ...current, contextRevision, updatedAt: draft.occurredAt }\n const change = draft.change\n switch (change.type) {\n case 'identify': {\n const identityChanged = change.userId !== current.userId\n return validateIdentity(\n {\n ...base,\n ...withFlagContext(current, (context) =>\n updatePersonFlagContext(context, change.set, change.setOnce, freezeV1Value([]))\n ),\n userId: change.userId,\n revision: identityChanged\n ? incrementStateCounter(current.revision, 'identity revision')\n : current.revision,\n },\n 'derived identify identity',\n failInput\n )\n }\n case 'linkAlias':\n return validateIdentity(base, 'derived mutation identity', failInput)\n case 'setPersonProperties':\n return validateIdentity(\n {\n ...base,\n ...withFlagContext(current, (context) =>\n updatePersonFlagContext(context, change.set, change.setOnce, change.unset)\n ),\n },\n 'derived person properties identity',\n failInput\n )\n case 'associateGroup':\n return validateIdentity(\n {\n ...base,\n groups: copyGroupsWithAssociation(current.groups, change.groupType, change.groupKey),\n ...(current.groups[change.groupType] !== change.groupKey\n ? withFlagContext(current, (context) =>\n freezeV1Value({\n ...context,\n groupProperties: copyFlagGroupProperties(\n context.groupProperties,\n change.groupType,\n null\n ),\n })\n )\n : {}),\n },\n 'derived group identity',\n failInput\n )\n case 'setGroupProperties':\n if (current.groups[change.groupType] !== change.groupKey) {\n return failInput('group properties mutation must match the persisted group association')\n }\n return validateIdentity(\n {\n ...base,\n ...withFlagContext(current, (context) => {\n const properties = applyJsonProperties(\n context.groupProperties[change.groupType] ?? freezeV1Value({}),\n change.set,\n change.setOnce,\n change.unset\n )\n return freezeV1Value({\n ...context,\n groupProperties: copyFlagGroupProperties(\n context.groupProperties,\n change.groupType,\n properties\n ),\n })\n }),\n },\n 'derived group properties identity',\n failInput\n )\n }\n}\n\nconst applyLocalChange = (\n current: V1PersistedIdentityState,\n change: V1DurableLocalChange\n): V1PersistedIdentityState => {\n switch (change.type) {\n case 'replaceSession':\n requireCurrentSessionId(current, change.expectedCurrentSessionId, 'local session replacement')\n return validateSessionTransition(current, change.session, false)\n case 'clearSession':\n requireCurrentSessionId(current, change.expectedCurrentSessionId, 'local session clear')\n requireTimestampNotBefore(change.occurredAt, current.updatedAt, 'local change occurredAt')\n return validateIdentity(\n { ...current, session: null, updatedAt: change.occurredAt },\n 'derived local identity',\n failInput\n )\n case 'setOptedOut': {\n requireTimestampNotBefore(change.occurredAt, current.updatedAt, 'local change occurredAt')\n const optChanged = change.optedOut !== current.optedOut\n const flagContextWasCleared = change.optedOut && flagContextHasValues(current.flagContext)\n return validateIdentity(\n {\n ...current,\n optedOut: change.optedOut,\n session: change.optedOut ? null : current.session,\n contextRevision:\n optChanged || flagContextWasCleared\n ? incrementStateCounter(current.contextRevision, 'identity context revision')\n : current.contextRevision,\n ...(change.optedOut && current.flagContext ? { flagContext: emptyFlagContext() } : {}),\n updatedAt: change.occurredAt,\n },\n 'derived local identity',\n failInput\n )\n }\n case 'resetGroups':\n requireTimestampNotBefore(change.occurredAt, current.updatedAt, 'local change occurredAt')\n return validateIdentity(\n {\n ...current,\n groups: freezeV1Value({}),\n ...(current.flagContext\n ? { flagContext: freezeV1Value({ ...current.flagContext, groupProperties: freezeV1Value({}) }) }\n : {}),\n contextRevision: incrementStateCounter(current.contextRevision, 'identity context revision'),\n updatedAt: change.occurredAt,\n },\n 'derived local identity',\n failInput\n )\n case 'resetIdentity':\n requireTimestampNotBefore(change.occurredAt, current.updatedAt, 'local change occurredAt')\n if (change.anonymousId === current.anonymousId) {\n return failInput('resetIdentity must rotate the anonymous ID')\n }\n return validateIdentity(\n {\n ...current,\n revision: incrementStateCounter(current.revision, 'identity revision'),\n contextRevision: incrementStateCounter(current.contextRevision, 'identity context revision'),\n anonymousId: change.anonymousId,\n userId: null,\n groups: freezeV1Value({}),\n superProperties: freezeV1Value({}),\n ...(current.flagContext ? { flagContext: emptyFlagContext() } : {}),\n session: null,\n updatedAt: change.occurredAt,\n },\n 'derived reset identity',\n failInput\n )\n case 'setSuperProperties':\n requireTimestampNotBefore(change.occurredAt, current.updatedAt, 'local change occurredAt')\n return validateIdentity(\n {\n ...current,\n contextRevision: incrementStateCounter(current.contextRevision, 'identity context revision'),\n superProperties: applyJsonProperties(\n current.superProperties,\n change.set,\n change.setOnce,\n change.unset\n ),\n updatedAt: change.occurredAt,\n },\n 'derived local identity',\n failInput\n )\n case 'setFlagContext': {\n requireTimestampNotBefore(change.occurredAt, current.updatedAt, 'local change occurredAt')\n const context = current.flagContext ?? emptyFlagContext()\n let personProperties = context.personProperties\n if (change.personProperties) {\n personProperties = change.mergePersonProperties\n ? applyJsonProperties(context.personProperties, change.personProperties, freezeV1Value({}), [])\n : change.personProperties\n }\n let groupProperties = context.groupProperties\n if (change.unsetGroupTypes) {\n for (const groupType of change.unsetGroupTypes) {\n groupProperties = copyFlagGroupProperties(groupProperties, groupType, null)\n }\n }\n if (change.groupProperties) {\n groupProperties = change.mergeGroupProperties\n ? mergeFlagGroupProperties(groupProperties, change.groupProperties)\n : change.groupProperties\n }\n return validateIdentity(\n {\n ...current,\n contextRevision: incrementStateCounter(current.contextRevision, 'identity context revision'),\n flagContext: freezeV1Value({\n schemaVersion: 1,\n personProperties,\n groupProperties,\n }),\n updatedAt: change.occurredAt,\n },\n 'derived local identity',\n failInput\n )\n }\n }\n}\n\nconst storedRecordFromBatch = (\n batchRecord: V1BatchRecord,\n kind: 'event' | 'mutation',\n recordId: string,\n captureVersions: V1VersionContext,\n installation: V1InstallationRow,\n sequence: number\n): { readonly stored: V1StoredRecordRow; readonly exposed: V1DurableQueueRecord } => {\n const reference: V1DurableRecordReference = freezeV1Value({\n sequence,\n kind,\n recordId,\n })\n const payloadJson = JSON.stringify(batchRecord)\n const payloadBytes = utf8ByteLength(payloadJson)\n const stored: V1StoredRecordRow = freezeV1Value({\n storageSchemaVersion: 1,\n siteKey: installation.siteKey,\n streamId: installation.streamId,\n sequence,\n kind,\n recordId,\n captureVersions,\n payloadJson,\n payloadBytes,\n })\n const exposed: V1DurableQueueRecord = freezeV1Value({\n ...reference,\n siteKey: installation.siteKey,\n streamId: installation.streamId,\n captureVersions,\n batchRecord,\n payloadJson,\n payloadBytes,\n })\n return freezeV1Value({ stored, exposed })\n}\n\nconst encodeEventDraft = (\n draft: V1NormalizedEventDraft,\n installation: V1InstallationRow,\n sequence: number\n): { readonly stored: V1StoredRecordRow; readonly exposed: V1DurableQueueRecord } => {\n const session = installation.identity.session\n if (!session || session.lifecycle !== 'active') {\n return failInput('events require an active persisted session')\n }\n if (draft.expectedSessionId !== session.id) {\n return failInput('event session expectation does not match the persisted session')\n }\n if (\n compareV1DateTimes(draft.occurredAt, session.startedAt) < 0 ||\n compareV1DateTimes(draft.occurredAt, session.lastActivityAt) > 0\n ) {\n return failInput('event occurredAt must fall within the persisted session activity window')\n }\n const recordId = recordIdFor('event', installation.streamId, sequence)\n const reference = freezeV1Value({ sequence, kind: 'event' as const, recordId })\n const event = validateEvent(\n {\n schemaVersion: 1,\n eventId: recordId,\n streamId: installation.streamId,\n sequence,\n contextRevision: installation.identity.contextRevision,\n kind: draft.kind,\n name: draft.name,\n occurredAt: draft.occurredAt,\n identity: {\n anonymousId: installation.identity.anonymousId,\n userId: installation.identity.userId,\n revision: installation.identity.revision,\n },\n sessionId: session.id,\n properties: mergeEventProperties(installation.identity.superProperties, draft.properties, draft.versions),\n groups: installation.identity.groups,\n versions: draft.versions,\n },\n { ...reference, streamId: installation.streamId },\n 'derived event',\n failInput\n )\n return storedRecordFromBatch(\n freezeV1Value({ kind: 'event', event }),\n 'event',\n recordId,\n event.versions,\n installation,\n sequence\n )\n}\n\nconst validateEventCausality = (\n lowerBound: string,\n session: V1PersistedSessionState | null,\n drafts: readonly V1NormalizedEventDraft[]\n): void => {\n if (!session || session.lifecycle !== 'active') {\n return failInput('events require an active persisted session')\n }\n let previousOccurredAt = lowerBound\n for (let index = 0; index < drafts.length; index += 1) {\n const draft = drafts[index]\n if (draft.expectedSessionId !== session.id) {\n failInput(`event draft ${index} session expectation does not match the persisted session`)\n }\n requireTimestampNotBefore(draft.occurredAt, previousOccurredAt, `event draft ${index} occurredAt`)\n if (\n compareV1DateTimes(draft.occurredAt, session.startedAt) < 0 ||\n compareV1DateTimes(draft.occurredAt, session.lastActivityAt) > 0\n ) {\n failInput(`event draft ${index} occurredAt must fall within the persisted session activity window`)\n }\n previousOccurredAt = draft.occurredAt\n }\n}\n\nconst encodeMutationDraft = (\n draft: V1NormalizedMutationDraft,\n installation: V1InstallationRow,\n sequence: number\n): { readonly stored: V1StoredRecordRow; readonly exposed: V1DurableQueueRecord } => {\n const recordId = recordIdFor('mutation', installation.streamId, sequence)\n const mutation = validateMutation(\n {\n mutationId: recordId,\n sequence,\n contextRevision: installation.identity.contextRevision,\n occurredAt: draft.occurredAt,\n subject: {\n anonymousId: installation.identity.anonymousId,\n userId: installation.identity.userId,\n identityRevision: installation.identity.revision,\n },\n change: draft.change,\n },\n freezeV1Value({ sequence, kind: 'mutation', recordId }),\n 'derived mutation',\n failInput\n )\n return storedRecordFromBatch(\n freezeV1Value({ kind: 'mutation', mutation }),\n 'mutation',\n recordId,\n draft.versions,\n installation,\n sequence\n )\n}\n\nconst normalizeReferences = (value: unknown): readonly V1DurableRecordReference[] => {\n const values = isArrayValue(value)\n ? value\n : failInput('acknowledgement references must be an array of at most 1000 records')\n if (values.length > 1000) failInput('acknowledgement references must be an array of at most 1000 records')\n const references: V1DurableRecordReference[] = []\n for (let index = 0; index < values.length; index += 1) {\n if (!hasOwnIndex(values, index)) {\n failInput('acknowledgement references must not be sparse')\n }\n const reference = assertExactRecord(\n values[index],\n ACKNOWLEDGEMENT_REFERENCE_KEYS,\n ACKNOWLEDGEMENT_REFERENCE_KEYS,\n `acknowledgement reference ${index}`,\n failInput\n )\n const kind =\n reference.kind === 'event'\n ? 'event'\n : reference.kind === 'mutation'\n ? 'mutation'\n : failInput(`acknowledgement reference ${index}.kind is unsupported`)\n const sequence = assertInteger(\n reference.sequence,\n `acknowledgement reference ${index}.sequence`,\n 0,\n Number.MAX_SAFE_INTEGER,\n failInput\n )\n if (index > 0 && sequence !== references[index - 1].sequence + 1) {\n failInput('acknowledgement references must be contiguous and ordered')\n }\n references.push(\n freezeV1Value({\n sequence,\n kind,\n recordId: assertIdentifier(\n reference.recordId,\n `acknowledgement reference ${index}.recordId`,\n 256,\n failInput\n ),\n })\n )\n }\n return freezeV1Value(references)\n}\n\nconst normalizeAcknowledgement = (value: unknown): V1DurableAcknowledgement => {\n const normalized = normalizeJsonObject(value, 'acknowledgement', failInput)\n const acknowledgement = assertExactRecord(\n normalized,\n ACKNOWLEDGEMENT_KEYS,\n ACKNOWLEDGEMENT_KEYS,\n 'acknowledgement',\n failInput\n )\n return freezeV1Value({\n siteKey: assertIdentifierField(acknowledgement.siteKey, \"siteKey\", \"acknowledgement\", 128, failInput),\n streamId: assertIdentifierField(acknowledgement.streamId, \"streamId\", \"acknowledgement\", 256, failInput),\n records: normalizeReferences(acknowledgement.records),\n })\n}\n\nconst sameReference = (left: V1DurableRecordReference, right: V1DurableRecordReference): boolean =>\n left.sequence === right.sequence && left.kind === right.kind && left.recordId === right.recordId\n\ninterface V1NormalizedRuntimeOptions {\n readonly siteKey: string\n readonly limits: V1DurableRuntimeLimits\n readonly storageFactory: V1DurableStorageFactory\n readonly captureRuntime: Readonly<{\n readonly sha256?: V1Sha256\n readonly clock: V1CaptureRuntimeClock\n readonly createSessionId: () => string\n }>\n}\n\nconst defaultCaptureClock: V1CaptureRuntimeClock = freezeV1Value({\n wallNow: (): string => new Date().toISOString(),\n monotonicNowMs: (): number => {\n const clock = typeof globalThis === 'undefined' ? undefined : globalThis.performance\n return clock ? clock.now() : Number.NaN\n },\n})\n\n/** Lowercase hex from platform randomness; fails closed when the platform offers none. */\nexport const v1SecureRandomHex = (byteCount: number, purpose: string): string => {\n const cryptoApi = typeof globalThis === 'undefined' ? undefined : globalThis.crypto\n if (!cryptoApi || !isFunctionValue(cryptoApi.getRandomValues)) {\n return failInput(`secure randomness is unavailable for ${purpose}`)\n }\n const bytes = new Uint8Array(byteCount)\n cryptoApi.getRandomValues(bytes)\n let hexadecimal = ''\n for (const byte of bytes) hexadecimal += byte.toString(16).padStart(2, '0')\n return hexadecimal\n}\n\nconst defaultSessionId = (): string => `elu_s_${v1SecureRandomHex(16, 'capture session creation')}`\n\n/** Mints a fresh anonymous identity from 128 bits of platform randomness; never derived from other state. */\nexport const createV1AnonymousId = (): string => `anon_${v1SecureRandomHex(16, 'anonymous identity creation')}`\n\n/** Mints the installation stream identity that events and mutations share for the life of the install. */\nexport const createV1StreamId = (): string => `stream_${v1SecureRandomHex(16, 'stream identity creation')}`\n\n/**\n * The identity a fresh install persists before its first event: no user, groups, super properties,\n * or session, opted in, at revision zero. Callers mint the anonymous ID once and persist this row\n * atomically; later constructions read the persisted row instead of minting again.\n */\nexport const createV1FreshInstallIdentity = (anonymousId: string, updatedAt: string): V1PersistedIdentityState =>\n validateIdentity(\n {\n schemaVersion: 1,\n revision: 0,\n contextRevision: 0,\n anonymousId,\n userId: null,\n groups: {},\n superProperties: {},\n session: null,\n optedOut: false,\n updatedAt,\n },\n 'fresh install identity',\n failInput\n )\n\nconst validateOptions = (value: V1DurableRuntimeOptions): V1NormalizedRuntimeOptions => {\n const options = assertExactRecord(\n value,\n ['siteKey', 'limits', 'storageFactory', 'captureRuntime'],\n ['siteKey', 'limits'],\n 'options',\n failInput\n )\n const limits = assertExactRecord(\n options.limits,\n ['maxCount', 'maxBytes'],\n ['maxCount', 'maxBytes'],\n 'options.limits',\n failInput\n )\n const storageFactoryCandidate = hasOwn(options, 'storageFactory') ? options.storageFactory : openV1IndexedDBStorage\n const storageFactory: V1DurableStorageFactory = isFunctionValue(storageFactoryCandidate)\n ? (storageFactoryCandidate as V1DurableStorageFactory)\n : failInput('options.storageFactory must be a function')\n const captureRuntime = hasOwn(options, 'captureRuntime')\n ? assertExactRecord(\n options.captureRuntime,\n ['sha256', 'clock', 'createSessionId'],\n [],\n 'options.captureRuntime',\n failInput\n )\n : {}\n const clock = hasOwn(captureRuntime, 'clock')\n ? assertExactRecord(\n captureRuntime.clock,\n ['wallNow', 'monotonicNowMs'],\n ['wallNow', 'monotonicNowMs'],\n 'options.captureRuntime.clock',\n failInput\n )\n : defaultCaptureClock\n if (!isFunctionValue(clock.wallNow) || !isFunctionValue(clock.monotonicNowMs)) {\n failInput('options.captureRuntime.clock functions are required')\n }\n if (hasOwn(captureRuntime, 'sha256') && !isFunctionValue(captureRuntime.sha256)) {\n failInput('options.captureRuntime.sha256 must be a function')\n }\n const createSessionId = hasOwn(captureRuntime, 'createSessionId')\n ? captureRuntime.createSessionId\n : defaultSessionId\n if (!isFunctionValue(createSessionId)) failInput('options.captureRuntime.createSessionId must be a function')\n return freezeV1Value({\n siteKey: assertIdentifierField(options.siteKey, \"siteKey\", \"options\", 128, failInput),\n limits: freezeV1Value({\n maxCount: assertIntegerField(limits.maxCount, \"maxCount\", \"options.limits\", 1, V1_MAX_DURABLE_QUEUE_COUNT, failInput),\n maxBytes: assertIntegerField(limits.maxBytes, \"maxBytes\", \"options.limits\", 1, V1_MAX_DURABLE_QUEUE_BYTES, failInput),\n }),\n storageFactory,\n captureRuntime: freezeV1Value({\n ...(hasOwn(captureRuntime, 'sha256') ? { sha256: captureRuntime.sha256 as V1Sha256 } : {}),\n clock: freezeV1Value({\n wallNow: clock.wallNow as () => string,\n monotonicNowMs: clock.monotonicNowMs as () => number,\n }),\n createSessionId: createSessionId as () => string,\n }),\n })\n}\n\nconst sameAuthorityBarrier = (\n left: V1PersistedAuthorityBarrier | null,\n right: V1PersistedAuthorityBarrier | null\n): boolean =>\n left === right ||\n (!!left &&\n !!right &&\n left.kind === right.kind &&\n left.terminalScope === right.terminalScope &&\n left.configIssuedAt === right.configIssuedAt &&\n left.configSemanticHash === right.configSemanticHash &&\n left.policySourceHash === right.policySourceHash &&\n left.contextRevision === right.contextRevision &&\n left.decisionHash === right.decisionHash)\n\nconst terminalBarrierFrom = (\n boundary: Pick<\n V1PersistedAuthorityBarrier,\n 'configIssuedAt' | 'configSemanticHash' | 'policySourceHash' | 'contextRevision' | 'decisionHash'\n >,\n terminalScope: 'config' | 'context'\n): V1PersistedAuthorityBarrier => freezeV1Value({ kind: 'terminal', terminalScope, ...boundary })\n\nconst terminalBarrierAtCurrentConfig = (\n current: V1PersistedAuthorityBarrier | null,\n terminalScope: 'config' | 'context' = 'config'\n): V1PersistedAuthorityBarrier =>\n terminalBarrierFrom(\n {\n configIssuedAt: current?.configIssuedAt ?? null,\n configSemanticHash: current?.configSemanticHash ?? null,\n policySourceHash: current?.policySourceHash ?? null,\n contextRevision: current?.contextRevision ?? null,\n decisionHash: current?.decisionHash ?? null,\n },\n terminalScope\n )\n\nconst mergeAuthorityBarrier = (\n current: V1PersistedAuthorityBarrier | null,\n incoming: V1PersistedAuthorityBarrier\n): V1PersistedAuthorityBarrier => {\n if (!current) return incoming\n if (!incoming.configIssuedAt || !incoming.configSemanticHash) {\n return terminalBarrierAtCurrentConfig(current, 'config')\n }\n if (!current.configIssuedAt || !current.configSemanticHash) return incoming\n const configOrder = compareV1DateTimes(incoming.configIssuedAt, current.configIssuedAt)\n if (configOrder < 0) return current\n if (configOrder > 0) return incoming\n if (incoming.configSemanticHash !== current.configSemanticHash) {\n return terminalBarrierAtCurrentConfig(current, 'config')\n }\n if (current.kind === 'terminal' && current.terminalScope === 'config') return current\n if (incoming.kind === 'terminal' && incoming.terminalScope === 'config') {\n return terminalBarrierFrom(\n {\n configIssuedAt: current.configIssuedAt,\n configSemanticHash: current.configSemanticHash,\n policySourceHash: current.policySourceHash,\n contextRevision: current.contextRevision,\n decisionHash: incoming.decisionHash ?? current.decisionHash,\n },\n 'config'\n )\n }\n if (incoming.policySourceHash !== current.policySourceHash) {\n return terminalBarrierAtCurrentConfig(current, 'config')\n }\n const currentContext = current.contextRevision ?? -1\n const incomingContext = incoming.contextRevision ?? currentContext\n if (incomingContext < currentContext) return current\n if (incomingContext > currentContext) return freezeV1Value({ ...incoming, contextRevision: incomingContext })\n if (current.kind === 'terminal' || incoming.kind === 'terminal') {\n return terminalBarrierFrom(\n {\n configIssuedAt: current.configIssuedAt,\n configSemanticHash: current.configSemanticHash,\n policySourceHash: current.policySourceHash,\n contextRevision: current.contextRevision,\n decisionHash:\n incoming.kind === 'terminal'\n ? (incoming.decisionHash ?? current.decisionHash)\n : current.decisionHash,\n },\n 'context'\n )\n }\n if (incoming.decisionHash !== current.decisionHash) {\n return terminalBarrierFrom(\n {\n configIssuedAt: current.configIssuedAt,\n configSemanticHash: current.configSemanticHash,\n policySourceHash: current.policySourceHash,\n contextRevision: current.contextRevision,\n decisionHash: current.decisionHash,\n },\n 'context'\n )\n }\n return incoming\n}\n\nconst barrierForEvaluation = (evaluation: V1CaptureCandidateEvaluation): V1PersistedAuthorityBarrier => {\n if (evaluation.status === 'authorized') {\n return freezeV1Value({\n kind: 'authorized',\n terminalScope: null,\n configIssuedAt: evaluation.configIssuedAt,\n configSemanticHash: evaluation.configSemanticHash,\n policySourceHash: evaluation.policySourceHash,\n contextRevision: evaluation.contextRevision,\n decisionHash: evaluation.decisionHash,\n })\n }\n if (evaluation.status === 'stale') return failInput('stale evaluation has no authority barrier')\n return freezeV1Value({\n kind: 'terminal',\n terminalScope: evaluation.terminalScope,\n configIssuedAt: evaluation.trustedBoundary?.configIssuedAt ?? null,\n configSemanticHash: evaluation.trustedBoundary?.configSemanticHash ?? null,\n policySourceHash: evaluation.trustedBoundary?.policySourceHash ?? null,\n contextRevision: evaluation.contextRevision,\n decisionHash: evaluation.decisionHash,\n })\n}\n\nconst normalizeCaptureCommand = (value: V1CaptureActivityCommand): V1CaptureActivityCommand => {\n const normalized = normalizeJsonObject(value, 'capture command', failInput)\n const command = assertExactRecord(\n normalized,\n ['kind', 'name', 'occurredAt', 'properties', 'versions'],\n ['kind', 'name', 'occurredAt', 'properties', 'versions'],\n 'capture command',\n failInput\n )\n const kind =\n command.kind === 'capture'\n ? 'capture'\n : command.kind === 'screen'\n ? 'screen'\n : command.kind === 'exception'\n ? 'exception'\n : failInput('capture command.kind must be capture, screen, or exception')\n const properties = normalizeJsonObjectField(command.properties, \"properties\", \"capture command\", failInput)\n if (Object.keys(properties).length > V1_MAX_CAPTURE_PROPERTY_COUNT) {\n return failInput(`capture command.properties must contain at most ${V1_MAX_CAPTURE_PROPERTY_COUNT} properties`)\n }\n if (utf8ByteLength(JSON.stringify(properties)) > V1_MAX_CAPTURE_PROPERTIES_BYTES) {\n return failInput(\n `capture command.properties must serialize to at most ${V1_MAX_CAPTURE_PROPERTIES_BYTES} UTF-8 bytes`\n )\n }\n return freezeV1Value({\n kind,\n name: assertIdentifierField(command.name, \"name\", \"capture command\", 512, failInput),\n occurredAt: assertDateTimeField(command.occurredAt, \"occurredAt\", \"capture command\", failInput),\n properties,\n versions: validateVersionsField(command.versions, \"versions\", \"capture command\", failInput),\n })\n}\n\nconst captureWallNow = (clock: V1CaptureRuntimeClock): { readonly text: string; readonly milliseconds: number } => {\n let raw: unknown\n try {\n raw = clock.wallNow()\n } catch {\n return failInput('capture wall clock threw while being sampled')\n }\n const text = assertDateTime(raw, 'capture wall clock', failInput)\n const milliseconds = Date.parse(text)\n if (!Number.isSafeInteger(milliseconds)) failInput('capture wall clock cannot be represented safely')\n return freezeV1Value({ text, milliseconds })\n}\n\nconst captureMonotonicUs = (clock: V1CaptureRuntimeClock, rounding: 'floor' | 'ceil'): number => {\n let milliseconds: unknown\n try {\n milliseconds = clock.monotonicNowMs()\n } catch {\n return failInput('capture monotonic clock threw while being sampled')\n }\n if (!isNumberValue(milliseconds) || milliseconds < 0) {\n failInput('capture monotonic clock is unavailable')\n }\n const sampledMilliseconds = milliseconds as number\n const microseconds =\n rounding === 'floor' ? Math.floor(sampledMilliseconds * 1000) : Math.ceil(sampledMilliseconds * 1000)\n if (!Number.isSafeInteger(microseconds)) failInput('capture monotonic clock exceeds the exact range')\n return microseconds\n}\n\nconst durableWallFloor = (identity: V1PersistedIdentityState): string => {\n let floor = identity.updatedAt\n if (identity.session && compareV1DateTimes(identity.session.lastActivityAt, floor) > 0) {\n floor = identity.session.lastActivityAt\n }\n if (identity.session?.backgroundedAt && compareV1DateTimes(identity.session.backgroundedAt, floor) > 0) {\n floor = identity.session.backgroundedAt\n }\n return floor\n}\n\nconst planCaptureSession = (\n identity: V1PersistedIdentityState,\n occurredAt: string,\n authority: V1ExecutableCaptureAuthority,\n createSessionId: () => string\n): V1PersistedSessionState => {\n requireTimestampNotBefore(occurredAt, identity.updatedAt, 'capture occurredAt')\n const current = identity.session\n const mustRotate =\n !current ||\n hasV1ElapsedAtLeastSeconds(\n occurredAt,\n current.lastActivityAt,\n Math.min(current.timeoutSeconds, authority.idleTimeoutSeconds)\n ) ||\n hasV1ElapsedAtLeastSeconds(occurredAt, current.startedAt, authority.maximumDurationSeconds)\n if (mustRotate) {\n return freezeV1Value({\n id: assertIdentifier(createSessionId(), 'generated capture session ID', 256, failInput),\n startedAt: occurredAt,\n lastActivityAt: occurredAt,\n timeoutSeconds: authority.idleTimeoutSeconds,\n maximumDurationSeconds: 86_400,\n lifecycle: 'active',\n backgroundedAt: null,\n })\n }\n return freezeV1Value({\n ...current,\n lastActivityAt: occurredAt,\n timeoutSeconds: Math.min(current.timeoutSeconds, authority.idleTimeoutSeconds),\n lifecycle: 'active',\n backgroundedAt: null,\n })\n}\n\n/** Durable queue implementation used by the browser SDK. */\nexport class V1DurableState {\n private readonly _siteKey: string\n private readonly _limits: V1DurableRuntimeLimits\n private readonly _storageFactory: V1DurableStorageFactory\n private readonly _configManager: V1ConfigManager\n private readonly _captureClock: V1CaptureRuntimeClock\n private readonly _createSessionId: () => string\n private _storage: V1DurableStorage | null = null\n private _snapshot: V1DurableStateSnapshot | null = null\n private _poisoned: Error | null = null\n private _tail: Promise<void> = Promise.resolve()\n private _captureAuthority: V1ExecutableCaptureAuthority | null = null\n private _captureAdmissionDecision: object = {}\n private _sealedReplaySourceDecision: object = {}\n private _captureSourceIssuance: V1CaptureSourceIssuance | null = null\n private _captureTerminalIntent: V1PersistedAuthorityBarrier | null = null\n private _captureOwnerEpoch = 0\n private _captureLifecycleEpoch = 0\n private _captureLifecycleProtected = false\n private _captureLifecycleCleanup: (() => void) | null = null\n private _captureConfigSiteId: string | null = null\n // A lost/expired source never restores the larger constructor default. This restriction is\n // not capture authority; every append also compares its exact source with the current row.\n private _queuePolicy: Readonly<{ configIssuedAt: string; configSemanticHash: string; maxBytes: number }> | null = null\n\n constructor(options: V1DurableRuntimeOptions) {\n const normalized = validateOptions(options)\n this._siteKey = normalized.siteKey\n this._limits = normalized.limits\n this._storageFactory = normalized.storageFactory\n this._configManager = new V1ConfigManager(\n normalized.captureRuntime.sha256 ? { sha256: normalized.captureRuntime.sha256 } : {}\n )\n this._captureClock = normalized.captureRuntime.clock\n this._createSessionId = normalized.captureRuntime.createSessionId\n }\n\n initialize(createInitialState: () => V1DurableInitialState): Promise<V1DurableStateSnapshot> {\n return this._serialize(async () => {\n if (this._storage && this._snapshot) {\n return this._snapshot\n }\n // Validate the initializer without invoking it before durable storage is known to be available.\n if (!isFunctionValue(createInitialState)) {\n return failInput('initial state factory must be a function')\n }\n\n this._poisoned = null\n const storage = await this._storageFactory()\n\n try {\n const snapshot = await storage.runTransaction('readwrite', async (transaction) => {\n const existing = await readAuditedState(transaction, this._siteKey)\n if (existing) {\n if (existing.requiresMigrationWrite) await transaction.putInstallation(existing.row)\n return snapshotFromRow(existing.row)\n }\n\n const initial = assertExactRecord(\n createInitialState(),\n ['identity', 'streamId'],\n ['identity', 'streamId'],\n 'initial state',\n failInput\n )\n const row: V1InstallationRow = freezeV1Value({\n storageSchemaVersion: 1,\n siteKey: this._siteKey,\n identity: validateIdentity(initial.identity, 'initial state identity', failInput),\n streamId: assertIdentifier(initial.streamId, 'initial state streamId', 256, failInput),\n nextSequence: 0,\n headSequence: 0,\n queuedCount: 0,\n queuedBytes: 0,\n authorityBarrier: null,\n })\n await transaction.addInstallation(row)\n return snapshotFromRow(row)\n })\n this._storage = storage\n this._snapshot = snapshot\n return snapshot\n } catch (error) {\n storage.close()\n this._rememberFatalFailure(error)\n throw error\n }\n })\n }\n\n installCaptureLifecycleProtection(\n windowTarget: V1CaptureLifecycleWindowTarget,\n documentTarget: V1CaptureLifecycleDocumentTarget\n ): Promise<boolean> {\n return this._serialize(async () => {\n const previousCleanup = this._captureLifecycleCleanup\n this._captureLifecycleCleanup = null\n this._captureLifecycleProtected = false\n this._captureAuthority = null\n try {\n previousCleanup?.()\n } catch {\n // Authority is already cleared; stale observer cleanup is best effort.\n }\n\n if (documentTarget.hidden) return false\n\n const lifecycleEpochBeforeInstall = this._captureLifecycleEpoch\n const invalidate = (): void => {\n this._invalidateCaptureAuthorityForLifecycleNow()\n }\n const invalidateWhenHidden = (): void => {\n if (documentTarget.hidden) invalidate()\n }\n const windowEvents = ['freeze', 'pagehide', 'pageshow', 'resume'] as const\n try {\n for (const event of windowEvents) {\n // Internal security-only target abstraction; the public browser helper is deliberately not wired.\n // eslint-disable-next-line elu-client/no-add-event-listener\n windowTarget.addEventListener(event, invalidate)\n }\n // eslint-disable-next-line elu-client/no-add-event-listener\n documentTarget.addEventListener('visibilitychange', invalidateWhenHidden)\n } catch {\n for (const event of windowEvents) {\n try {\n windowTarget.removeEventListener(event, invalidate)\n } catch {\n // Best-effort cleanup after a partially installed security observer.\n }\n }\n try {\n documentTarget.removeEventListener('visibilitychange', invalidateWhenHidden)\n } catch {\n // Best-effort cleanup after a partially installed security observer.\n }\n return false\n }\n const cleanup = (): void => {\n for (const event of windowEvents) {\n try {\n windowTarget.removeEventListener(event, invalidate)\n } catch {\n // Best-effort cleanup; authority is invalidated before this callback runs.\n }\n }\n try {\n documentTarget.removeEventListener('visibilitychange', invalidateWhenHidden)\n } catch {\n // Best-effort cleanup; authority is invalidated before this callback runs.\n }\n }\n if (documentTarget.hidden || this._captureLifecycleEpoch !== lifecycleEpochBeforeInstall) {\n cleanup()\n return false\n }\n this._captureLifecycleCleanup = cleanup\n this._captureLifecycleProtected = true\n return true\n })\n }\n\n invalidateCaptureAuthorityForLifecycle(): Promise<void> {\n try {\n this._invalidateCaptureAuthorityForLifecycleNow()\n return Promise.resolve()\n } catch (error) {\n return Promise.reject(error)\n }\n }\n\n submitCaptureAuthority(\n configInput: string,\n privacyInput: string | undefined\n ): Promise<V1CaptureAuthorityUpdateResult> {\n this._captureAdmissionDecision = {}\n this._sealedReplaySourceDecision = {}\n return this._serialize(async () => {\n const storage = this._requireStorage()\n if (this._captureTerminalIntent) await this._readCaptureState(storage)\n const witness = await storage.runTransaction('readonly', async (transaction) =>\n readInstallation(transaction, this._siteKey)\n )\n let initialWall: ReturnType<typeof captureWallNow>\n let initialMonotonicUs: number\n try {\n initialWall = captureWallNow(this._captureClock)\n initialMonotonicUs = captureMonotonicUs(this._captureClock, 'floor')\n } catch {\n return this._persistConfigTerminal(storage, 'capture clock discontinuity during authority submission')\n }\n const evaluation = await this._configManager.evaluateCaptureCandidate(\n configInput,\n privacyInput,\n freezeV1Value({\n contextRevision: witness.identity.contextRevision,\n optedOut: witness.identity.optedOut,\n }),\n initialWall.milliseconds\n )\n if (evaluation.status === 'stale') return evaluation\n this._rememberCaptureSourceIssuance(\n evaluation,\n initialWall.text,\n initialMonotonicUs,\n durableWallFloor(witness.identity)\n )\n\n const candidateSiteId = evaluation.configSiteId\n if (candidateSiteId) {\n if (this._captureConfigSiteId && this._captureConfigSiteId !== candidateSiteId) {\n this._captureAuthority = null\n return freezeV1Value({\n status: 'terminal',\n reason: 'config site identity changed during the owner lifetime',\n })\n } else if (!this._captureConfigSiteId) {\n this._captureConfigSiteId = candidateSiteId\n }\n }\n const queueBytes = this._configManager.activeQueueByteLimit(initialWall.milliseconds)\n const source = evaluation.status === 'authorized' ? evaluation : evaluation.trustedBoundary\n if (queueBytes !== null && source) {\n this._queuePolicy = freezeV1Value({\n configIssuedAt: source.configIssuedAt,\n configSemanticHash: source.configSemanticHash,\n maxBytes: Math.min(this._limits.maxBytes, queueBytes),\n })\n }\n if (evaluation.status === 'authorized' && !this._captureLifecycleProtected) {\n this._captureAuthority = null\n return freezeV1Value({\n status: 'terminal',\n reason: 'browser lifecycle protection is not installed',\n })\n }\n return this._installCaptureEvaluation(storage, witness, evaluation)\n })\n }\n\n captureActivity(command: V1CaptureActivityCommand): Promise<V1DurableAppendResult> {\n return this._snapshotAndSerialize(\n () => normalizeCaptureCommand(command),\n async (normalized) => {\n const storage = this._requireStorage()\n type V1CaptureTransactionResult =\n | Readonly<{ status: 'captured'; value: V1DurableAppendResult }>\n | Readonly<{ status: 'terminal'; row: V1InstallationRow; reason: string }>\n const attempt = (): Promise<V1DurableCommitOutcome<V1CaptureTransactionResult>> =>\n storage.runTransactionWithCommitOutcome<V1CaptureTransactionResult>(async (transaction) => {\n const current = await readInstallation(transaction, this._siteKey)\n let authority: V1ExecutableCaptureAuthority\n try {\n authority = this._requireCaptureAuthority(current)\n } catch (error) {\n if (!(error instanceof V1CaptureConfigTerminalError)) throw error\n const merged = mergeAuthorityBarrier(\n current.authorityBarrier,\n terminalBarrierAtCurrentConfig(current.authorityBarrier, 'config')\n )\n const row: V1InstallationRow = freezeV1Value({ ...current, authorityBarrier: merged })\n if (!sameAuthorityBarrier(current.authorityBarrier, merged)) {\n await transaction.putInstallation(row)\n }\n return freezeV1Value({ status: 'terminal', row, reason: error.message })\n }\n const session = planCaptureSession(\n current.identity,\n normalized.occurredAt,\n authority,\n this._createSessionId\n )\n const identity = validateSessionTransition(current.identity, session, true)\n const eventRow: V1InstallationRow = freezeV1Value({ ...current, identity })\n const draft: V1NormalizedEventDraft = freezeV1Value({\n ...normalized,\n expectedSessionId: session.id,\n })\n const encoded = [encodeEventDraft(draft, eventRow, current.nextSequence)]\n return freezeV1Value({\n status: 'captured',\n value: await this._commitAppend(transaction, current, identity, encoded),\n })\n })\n\n let outcome = await attempt()\n if (outcome.status === 'proven-not-committed' && !(outcome.error instanceof V1DurableStateError)) {\n outcome = await attempt()\n }\n if (outcome.status === 'unknown') {\n this._captureAuthority = null\n throw new V1DurableStateError('commit-unknown', 'capture commit outcome is unknown')\n }\n if (outcome.status === 'proven-not-committed') throw outcome.error\n if (outcome.value.status === 'terminal') {\n this._captureAuthority = null\n this._snapshot = snapshotFromRow(outcome.value.row)\n return fail('capture-not-authorized', outcome.value.reason)\n }\n this._snapshot = outcome.value.value.state\n return outcome.value.value\n }\n )\n }\n\n registerCaptureSuperProperties(properties: V1JsonObject, occurredAt: string): Promise<V1DurableAppendResult> {\n return this.applyLocal({\n type: 'setSuperProperties',\n set: properties,\n setOnce: freezeV1Value({}),\n unset: freezeV1Value([]),\n occurredAt,\n })\n }\n\n unregisterCaptureSuperProperties(\n properties: readonly string[],\n occurredAt: string\n ): Promise<V1DurableAppendResult> {\n return this.applyLocal({\n type: 'setSuperProperties',\n set: freezeV1Value({}),\n setOnce: freezeV1Value({}),\n unset: properties,\n occurredAt,\n })\n }\n\n setCaptureOptedOut(optedOut: boolean, occurredAt: string): Promise<V1DurableAppendResult> {\n return this.applyLocal({ type: 'setOptedOut', optedOut, occurredAt })\n }\n\n appendEvents(\n sessionUpdate: V1DurableEventSessionUpdate,\n eventDrafts: readonly V1DurableEventDraft[]\n ): Promise<V1DurableAppendResult> {\n return this._snapshotAndSerialize(\n () =>\n freezeV1Value({\n sessionUpdate: normalizeSessionUpdate(sessionUpdate),\n drafts: normalizeEventDrafts(eventDrafts),\n }),\n this._appendTransactionOperation<Readonly<{ sessionUpdate: ReturnType<typeof normalizeSessionUpdate>; drafts: readonly V1NormalizedEventDraft[] }>>(\n (transaction, current, { sessionUpdate: normalizedUpdate, drafts }) => {\nif (current.nextSequence > Number.MAX_SAFE_INTEGER - drafts.length) {\n return fail('sequence-exhausted', 'queue sequence space is exhausted')\n }\nlet identity = current.identity\nif (normalizedUpdate.type === 'replace') {\n requireCurrentSessionId(\n current.identity,\n normalizedUpdate.expectedCurrentSessionId,\n 'event session replacement'\n )\n identity = validateSessionTransition(current.identity, normalizedUpdate.session, true)\n }\nvalidateEventCausality(current.identity.updatedAt, identity.session, drafts)\nconst eventRow: V1InstallationRow = freezeV1Value({\n ...current,\n identity,\n })\nconst encoded = drafts.map((draft, index) =>\n encodeEventDraft(draft, eventRow, current.nextSequence + index)\n )\nreturn this._commitAppend(transaction, current, identity, encoded)\n },\n (result) => {\nthis._snapshot = result.state\nthis._captureAuthority = null\nreturn result\n }\n )\n )\n }\n\n appendMutations(mutationDrafts: readonly V1DurableMutationDraft[]): Promise<V1DurableAppendResult> {\n return this._snapshotAndSerialize(\n () => {\n const drafts = normalizeMutationDrafts(mutationDrafts)\n this._captureAdmissionDecision = {}\n this._captureAuthority = null\n return drafts\n },\n this._appendTransactionOperation<readonly V1NormalizedMutationDraft[]>(\n (transaction, current, drafts) => {\nif (current.nextSequence > Number.MAX_SAFE_INTEGER - drafts.length) {\n return fail('sequence-exhausted', 'queue sequence space is exhausted')\n }\nlet identity = current.identity\nconst encoded: V1EncodedRecord[] = []\nfor (let index = 0; index < drafts.length; index += 1) {\n identity = applyMutation(identity, drafts[index])\n const mutationRow: V1InstallationRow = freezeV1Value({ ...current, identity })\n encoded.push(encodeMutationDraft(drafts[index], mutationRow, current.nextSequence + index))\n }\nreturn this._commitAppend(transaction, current, identity, encoded)\n },\n (result) => {\nthis._snapshot = result.state\nthis._captureAuthority = null\nreturn result\n }\n )\n )\n }\n\n applyLocal(change: V1DurableLocalChange): Promise<V1DurableAppendResult> {\n return this._snapshotAndSerialize(\n () => {\n const normalized = normalizeLocalChange(change)\n this._captureAdmissionDecision = {}\n if (\n normalized.type === 'setOptedOut' ||\n normalized.type === 'resetGroups' ||\n normalized.type === 'resetIdentity' ||\n normalized.type === 'setSuperProperties' ||\n normalized.type === 'setFlagContext'\n )\n this._captureAuthority = null\n return normalized\n },\n this._appendTransactionOperation<ReturnType<typeof normalizeLocalChange>>(\n (transaction, current, normalizedChange) => {\nconst identity = applyLocalChange(current.identity, normalizedChange)\nreturn this._commitAppend(transaction, current, identity, [])\n },\n (result, normalizedChange) => {\nthis._snapshot = result.state\nif (\n normalizedChange.type === 'setOptedOut' ||\n normalizedChange.type === 'resetGroups' ||\n normalizedChange.type === 'resetIdentity' ||\n normalizedChange.type === 'setSuperProperties' ||\n normalizedChange.type === 'setFlagContext'\n ) {\n this._captureAuthority = null\n }\nreturn result\n }\n )\n )\n }\n\n peek(maxCount: number, maxRecordBytes: number): Promise<readonly V1DurableQueueRecord[]> {\n return this._serialize(async () => {\n const count = assertInteger(maxCount, 'peek maxCount', 0, 1000, failInput)\n const recordBytes = assertInteger(\n maxRecordBytes,\n 'peek maxRecordBytes',\n 0,\n V1_MAX_DURABLE_QUEUE_BYTES,\n failInput\n )\n const storage = this._requireStorage()\n try {\n const result = await storage.runTransaction('readonly', async (transaction) => {\n const current = await readInstallation(transaction, this._siteKey)\n const prefix: V1DurableQueueRecord[] = []\n let prefixBytes = 0\n let visited = 0\n let stoppedForBytes = false\n const requestedCount = Math.min(count, current.queuedCount)\n await transaction.scanRecordPrefix(\n this._siteKey,\n current.headSequence,\n requestedCount,\n (rawRecord) => {\n const record = validateStoredRecord(rawRecord, current, current.headSequence + visited)\n visited += 1\n if (prefixBytes + record.payloadBytes > recordBytes) {\n if (prefix.length === 0) {\n return fail(\n 'head-record-too-large',\n 'live queue head exceeds the requested record-byte budget'\n )\n }\n stoppedForBytes = true\n return false\n }\n prefix.push(record)\n prefixBytes += record.payloadBytes\n return true\n }\n )\n if (!stoppedForBytes && visited !== requestedCount) {\n return failCorrupt('stored queue ended before its bounded live prefix')\n }\n return freezeV1Value({ state: snapshotFromRow(current), prefix: freezeV1Value(prefix) })\n })\n this._snapshot = result.state\n return result.prefix\n } catch (error) {\n this._rememberFatalFailure(error)\n throw error\n }\n })\n }\n\n acknowledge(value: V1DurableAcknowledgement): Promise<V1DurableStateSnapshot> {\n return this._snapshotAndSerialize(\n () => normalizeAcknowledgement(value),\n async (acknowledgement) => {\n if (acknowledgement.siteKey !== this._siteKey) {\n return failInput('acknowledgement site key does not match this durable runtime')\n }\n const storage = this._requireStorage()\n try {\n const snapshot = await storage.runTransaction('readwrite', async (transaction) => {\n const current = await readInstallation(transaction, this._siteKey)\n if (acknowledgement.streamId !== current.streamId) {\n return failInput('acknowledgement stream does not match the live queue')\n }\n if (acknowledgement.records.length === 0) {\n return snapshotFromRow(current)\n }\n\n for (const reference of acknowledgement.records) {\n if (\n reference.recordId !== recordIdFor(reference.kind, current.streamId, reference.sequence)\n ) {\n return failInput(\n 'acknowledgement contains a record ID not derived from its stream prefix'\n )\n }\n }\n\n const firstSequence = acknowledgement.records[0].sequence\n const lastSequence = acknowledgement.records[acknowledgement.records.length - 1].sequence\n if (lastSequence < current.headSequence) {\n return snapshotFromRow(current)\n }\n if (firstSequence !== current.headSequence) {\n return failInput('acknowledgement is not the exact current queue prefix')\n }\n if (acknowledgement.records.length > current.queuedCount) {\n return failInput('acknowledgement extends beyond the live queue')\n }\n\n let visited = 0\n let deletedBytes = 0\n await transaction.scanRecordPrefix(\n this._siteKey,\n current.headSequence,\n acknowledgement.records.length,\n (rawRecord) => {\n const record = validateStoredRecord(rawRecord, current, current.headSequence + visited)\n if (!sameReference(acknowledgement.records[visited], record)) {\n return failInput('acknowledgement does not exactly match the live queue prefix')\n }\n deletedBytes += record.payloadBytes\n visited += 1\n return true\n }\n )\n if (visited !== acknowledgement.records.length) {\n return failCorrupt('stored queue ended before the acknowledged live prefix')\n }\n if (\n deletedBytes > current.queuedBytes ||\n (acknowledgement.records.length === current.queuedCount &&\n deletedBytes !== current.queuedBytes)\n ) {\n return failCorrupt('stored queue byte count does not match the acknowledged prefix')\n }\n\n for (const reference of acknowledgement.records) {\n await transaction.deleteRecord(this._siteKey, reference.sequence)\n }\n const nextRow: V1InstallationRow = freezeV1Value({\n ...current,\n headSequence: current.headSequence + acknowledgement.records.length,\n queuedCount: current.queuedCount - acknowledgement.records.length,\n queuedBytes: current.queuedBytes - deletedBytes,\n })\n await transaction.putInstallation(nextRow)\n return snapshotFromRow(nextRow)\n })\n this._snapshot = snapshot\n return snapshot\n } catch (error) {\n this._rememberFatalFailure(error)\n throw error\n }\n }\n )\n }\n\n /**\n * Captures this exact local authority decision. The caller supplies the transaction-current\n * installation, never snapshot(). A renewal, lifecycle boundary, close, changed identity or\n * cross-realm barrier invalidates the guard; it does not authorize a chunk's own identity.\n */\n captureAdmissionGuard(): V1CaptureAdmissionGuard {\n const authority = this._captureAuthority\n const decision = this._captureAdmissionDecision\n return (installation) => {\n const denied = freezeV1Value({ authorized: false, terminalInstallation: null })\n if (this._captureTerminalIntent && this._storage && !this._poisoned) {\n const current = validateInstallation(installation, this._siteKey)\n return freezeV1Value({\n authorized: false,\n terminalInstallation: freezeV1Value({\n ...current,\n authorityBarrier: mergeAuthorityBarrier(current.authorityBarrier, this._captureTerminalIntent),\n }),\n })\n }\n if (\n !authority ||\n decision !== this._captureAdmissionDecision ||\n this._poisoned ||\n !this._storage ||\n this._captureAuthority !== authority\n )\n return denied\n const current = validateInstallation(installation, this._siteKey)\n try {\n const authorized = this._requireCaptureAuthority(current) === authority\n const session = current.identity.session\n const now = captureWallNow(this._captureClock).text\n if (\n !session ||\n session.lifecycle !== 'active' ||\n compareV1DateTimes(now, session.lastActivityAt) < 0 ||\n hasV1ElapsedAtLeastSeconds(\n now,\n session.lastActivityAt,\n Math.min(session.timeoutSeconds, authority.idleTimeoutSeconds)\n ) ||\n hasV1ElapsedAtLeastSeconds(now, session.startedAt, authority.maximumDurationSeconds)\n )\n return denied\n return freezeV1Value({\n authorized,\n terminalInstallation: null,\n })\n } catch (error) {\n this._captureAuthority = null\n if (error instanceof V1CaptureConfigTerminalError) {\n this._captureTerminalIntent = terminalBarrierAtCurrentConfig(current.authorityBarrier, 'config')\n return freezeV1Value({\n authorized: false,\n terminalInstallation: freezeV1Value({\n ...current,\n authorityBarrier: mergeAuthorityBarrier(\n current.authorityBarrier,\n this._captureTerminalIntent\n ),\n }),\n })\n }\n if (error instanceof V1DurableStateError && error.code === 'capture-not-authorized') return denied\n throw error\n }\n }\n }\n\n /**\n * Original local source lease only. This consumes the same clock/lifecycle validator as capture\n * admission; it grants no transaction-current identity, session or cross-tab storage authority.\n */\n captureSourceGuard(): () => boolean {\n return this.captureSourceLease().isCurrent\n }\n\n /** Scheduling projection of this exact original lease; it never installs or renews authority. */\n captureSourceLease(): Readonly<{ isCurrent(): boolean; remainingMicroseconds(): number }> {\n const authority = this._captureAuthority\n const decision = this._captureAdmissionDecision\n const remainingMicroseconds = (): number => {\n if (\n !authority ||\n this._captureAuthority !== authority ||\n this._captureAdmissionDecision !== decision ||\n this._captureTerminalIntent ||\n this._poisoned ||\n !this._storage\n )\n return 0\n try {\n this._requireCaptureLifecycle(authority)\n return this._requireCaptureSourceClock(authority)\n } catch (error) {\n this._captureAuthority = null\n if (error instanceof V1CaptureConfigTerminalError) {\n this._captureTerminalIntent = terminalBarrierAtCurrentConfig(authority.barrier, 'config')\n }\n return 0\n }\n }\n return freezeV1Value({ isCurrent: () => remainingMicroseconds() > 0, remainingMicroseconds })\n }\n\n /**\n * Restriction for already-sealed replay, bound to the exact installed source. Local identity or\n * session changes do not extend or revoke that source's clock. This grants no fresh capture or\n * storage authority; the caller must separately check the transaction-current config witness.\n */\n sealedReplaySourceGuard(): () => boolean {\n const authority = this._captureAuthority\n const sourceDecision = this._sealedReplaySourceDecision\n let denied = !authority\n return () => {\n if (\n denied ||\n !authority ||\n this._sealedReplaySourceDecision !== sourceDecision ||\n this._captureTerminalIntent?.terminalScope === 'config' ||\n this._poisoned ||\n !this._storage ||\n this._snapshot?.identity.optedOut ||\n this._snapshot?.streamId !== authority.streamId\n )\n return false\n try {\n this._requireCaptureLifecycle(authority)\n this._requireCaptureSourceClock(authority)\n return true\n } catch (error) {\n denied = true\n if (error instanceof V1CaptureConfigTerminalError) {\n this._captureAuthority = null\n this._captureTerminalIntent = terminalBarrierAtCurrentConfig(authority.barrier, 'config')\n }\n return false\n }\n }\n }\n\n /** Reads the owner inside a transaction; a cached snapshot is never authority for replay. */\n readCaptureState(): Promise<V1DurableCaptureState> {\n return this._serialize(() => this._readCaptureState(this._requireStorage()))\n }\n\n private async _readCaptureState(storage: V1DurableStorage): Promise<V1DurableCaptureState> {\n const authority = this._captureAuthority\n const decision = this._captureAdmissionDecision\n type CaptureRead = V1DurableCaptureState &\n Readonly<{ installation: V1InstallationRow; terminalIntent: V1PersistedAuthorityBarrier | null }>\n const attempt = (): Promise<V1DurableCommitOutcome<CaptureRead>> =>\n storage.runTransactionWithCommitOutcome(async (transaction) => {\n const current = await readInstallation(transaction, this._siteKey)\n if (!this._captureTerminalIntent) {\n try {\n this._requireCaptureAuthority(current)\n return freezeV1Value({\n state: snapshotFromRow(current),\n authorityBarrier: current.authorityBarrier,\n installation: current,\n authorized: true,\n terminalIntent: null,\n })\n } catch (error) {\n if (error instanceof V1CaptureConfigTerminalError) {\n // Close local admission immediately, retaining the exact barrier until commit.\n this._captureAuthority = null\n this._captureTerminalIntent = terminalBarrierAtCurrentConfig(\n current.authorityBarrier,\n 'config'\n )\n } else if (error instanceof V1DurableStateError && error.code === 'capture-not-authorized') {\n return freezeV1Value({\n state: snapshotFromRow(current),\n authorityBarrier: current.authorityBarrier,\n installation: current,\n authorized: false,\n terminalIntent: null,\n })\n } else {\n throw error\n }\n }\n }\n const terminalIntent = this._captureTerminalIntent!\n const barrier = mergeAuthorityBarrier(current.authorityBarrier, terminalIntent)\n const row: V1InstallationRow = freezeV1Value({ ...current, authorityBarrier: barrier })\n if (!sameAuthorityBarrier(current.authorityBarrier, barrier)) await transaction.putInstallation(row)\n return freezeV1Value({\n state: snapshotFromRow(row),\n authorityBarrier: row.authorityBarrier,\n installation: row,\n authorized: false,\n terminalIntent,\n })\n })\n let outcome = await attempt()\n if (outcome.status === 'proven-not-committed' && !(outcome.error instanceof V1DurableStateError)) {\n outcome = await attempt()\n }\n if (outcome.status !== 'committed') {\n this._captureAuthority = null\n if (outcome.status === 'unknown') {\n throw new V1DurableStateError('commit-unknown', 'capture state read commit outcome is unknown')\n }\n this._rememberFatalFailure(outcome.error)\n throw outcome.error\n }\n if (this._captureTerminalIntent === outcome.value.terminalIntent) this._captureTerminalIntent = null\n this._snapshot = outcome.value.state\n let authorized = Boolean(\n outcome.value.authorized &&\n authority &&\n this._captureAuthority === authority &&\n this._captureAdmissionDecision === decision &&\n !this._captureTerminalIntent\n )\n if (authorized) {\n // A commit may wait while consent changes, close is queued, or either clock expires.\n try {\n authorized = this._requireCaptureAuthority(outcome.value.installation) === authority\n } catch (error) {\n this._captureAuthority = null\n if (error instanceof V1CaptureConfigTerminalError) {\n this._captureTerminalIntent = terminalBarrierAtCurrentConfig(\n outcome.value.installation.authorityBarrier,\n 'config'\n )\n // The retained intent makes this a bounded second read which only persists denial.\n return this._readCaptureState(storage)\n }\n if (!(error instanceof V1DurableStateError && error.code === 'capture-not-authorized')) throw error\n authorized = false\n }\n }\n if (!authorized) this._captureAuthority = null\n return freezeV1Value({\n state: outcome.value.state,\n authorityBarrier: outcome.value.authorityBarrier,\n authorized,\n })\n }\n\n snapshot(): V1DurableStateSnapshot {\n if (this._poisoned) {\n throw this._poisoned\n }\n if (!this._snapshot) {\n return fail('not-initialized', 'durable state is not initialized')\n }\n return this._snapshot\n }\n\n close(): Promise<void> {\n this._sealedReplaySourceDecision = {}\n this._captureAdmissionDecision = {}\n this._captureAuthority = null\n return this._serialize(async () => {\n const cleanup = this._captureLifecycleCleanup\n this._captureLifecycleCleanup = null\n this._captureLifecycleProtected = false\n this._captureAuthority = null\n this._captureConfigSiteId = null\n this._configManager.clear()\n try {\n cleanup?.()\n } catch {\n // Best-effort listener cleanup must not prevent storage shutdown.\n }\n this._storage?.close()\n this._storage = null\n this._snapshot = null\n this._poisoned = null\n })\n }\n\n private async _persistConfigTerminal(\n storage: V1DurableStorage,\n reason: string\n ): Promise<V1CaptureAuthorityUpdateResult> {\n const attempt = (): Promise<V1DurableCommitOutcome<V1InstallationRow>> =>\n storage.runTransactionWithCommitOutcome(async (transaction) => {\n const current = await readInstallation(transaction, this._siteKey)\n const merged = mergeAuthorityBarrier(\n current.authorityBarrier,\n terminalBarrierAtCurrentConfig(current.authorityBarrier, 'config')\n )\n const row: V1InstallationRow = freezeV1Value({ ...current, authorityBarrier: merged })\n if (!sameAuthorityBarrier(current.authorityBarrier, merged)) await transaction.putInstallation(row)\n return row\n })\n\n let outcome = await attempt()\n if (outcome.status === 'proven-not-committed' && !(outcome.error instanceof V1DurableStateError)) {\n outcome = await attempt()\n }\n this._captureAuthority = null\n if (outcome.status === 'unknown') {\n throw new V1DurableStateError('commit-unknown', 'config terminal barrier commit outcome is unknown')\n }\n if (outcome.status === 'proven-not-committed') throw outcome.error\n this._snapshot = snapshotFromRow(outcome.value)\n return freezeV1Value({ status: 'terminal', reason })\n }\n\n private _rememberCaptureSourceIssuance(\n evaluation: Exclude<V1CaptureCandidateEvaluation, Readonly<{ status: 'stale'; reason: string }>>,\n installedWallAt: string,\n monotonicStartedAtUs: number,\n observedWallFloor: string\n ): void {\n const boundary = evaluation.status === 'authorized' ? evaluation : evaluation.trustedBoundary\n if (!boundary) return\n const previous = this._captureSourceIssuance\n // Only the config manager's validated newer issuance can replace this clock. Equal\n // timestamps with conflicting content are terminal at that manager, never a new lease.\n if (previous && compareV1DateTimes(boundary.configIssuedAt, previous.configIssuedAt) <= 0) return\n this._captureSourceIssuance = freezeV1Value({\n token: {},\n configIssuedAt: boundary.configIssuedAt,\n configSemanticHash: boundary.configSemanticHash,\n installedWallAt,\n observedWallFloor,\n monotonicStartedAtUs,\n monotonicBudgetUs: null,\n denied: false,\n })\n }\n\n private _sourceClockForCapture(\n evaluation: Extract<V1CaptureCandidateEvaluation, { status: 'authorized' }>,\n identity: V1PersistedIdentityState\n ): V1CaptureSourceClock {\n const source = this._captureSourceIssuance\n if (\n !source ||\n source.denied ||\n source.configIssuedAt !== evaluation.configIssuedAt ||\n source.configSemanticHash !== evaluation.configSemanticHash\n ) {\n throw new V1CaptureConfigTerminalError('capture source issuance is unavailable')\n }\n try {\n const initialBudget = Math.max(\n 0,\n Math.min(\n v1MicrosecondsBetween(evaluation.expiresAt, source.installedWallAt),\n v1MicrosecondsBetween(evaluation.expiresAt, evaluation.configIssuedAt),\n v1MicrosecondsBetween(evaluation.expiresAt, source.observedWallFloor)\n )\n )\n const elapsed = captureMonotonicUs(this._captureClock, 'ceil') - source.monotonicStartedAtUs\n // Translate a newer durable wall floor to an absolute deadline on the ORIGINAL monotonic\n // axis. Subtracting it directly from the total budget would charge normal elapsed time twice.\n const floorDeadline =\n elapsed + Math.max(0, v1MicrosecondsBetween(evaluation.expiresAt, durableWallFloor(identity)))\n if (!Number.isSafeInteger(floorDeadline)) {\n this._captureSourceIssuance = freezeV1Value({ ...source, denied: true })\n throw new V1CaptureConfigTerminalError('capture source clock deadline is unsafe')\n }\n const monotonicBudgetUs = Math.min(source.monotonicBudgetUs ?? initialBudget, initialBudget, floorDeadline)\n this._captureSourceIssuance = freezeV1Value({ ...source, monotonicBudgetUs })\n const clock = freezeV1Value({\n sourceToken: source.token,\n expiresAt: evaluation.expiresAt,\n installedWallAt: source.installedWallAt,\n monotonicStartedAtUs: source.monotonicStartedAtUs,\n monotonicBudgetUs,\n })\n this._requireCaptureSourceClock(clock)\n return clock\n } catch (error) {\n if (this._captureSourceIssuance?.token === source.token) {\n this._captureSourceIssuance = freezeV1Value({ ...this._captureSourceIssuance, denied: true })\n }\n throw error\n }\n }\n\n private async _installCaptureEvaluation(\n storage: V1DurableStorage,\n witness: V1InstallationRow,\n evaluation: Exclude<V1CaptureCandidateEvaluation, Readonly<{ status: 'stale'; reason: string }>>\n ): Promise<V1CaptureAuthorityUpdateResult> {\n interface V1InstallResult {\n readonly row: V1InstallationRow\n readonly authority: V1ExecutableCaptureAuthority | null\n readonly reason: string\n }\n const originalBarrier = barrierForEvaluation(evaluation)\n const prospectiveOwnerEpoch = incrementStateCounter(this._captureOwnerEpoch, 'capture owner epoch')\n const attempt = () =>\n storage.runTransactionWithCommitOutcome<V1InstallResult>(async (transaction) => {\n const current = await readInstallation(transaction, this._siteKey)\n let incoming = originalBarrier\n let executable: V1ExecutableCaptureAuthority | null = null\n let reason = evaluation.status === 'terminal' ? evaluation.reason : 'capture authority conflict'\n\n if (evaluation.status === 'authorized') {\n const witnessMatches =\n current.streamId === witness.streamId &&\n current.identity.revision === witness.identity.revision &&\n current.identity.contextRevision === witness.identity.contextRevision &&\n current.identity.optedOut === witness.identity.optedOut &&\n current.identity.contextRevision === evaluation.contextRevision &&\n !current.identity.optedOut\n if (!witnessMatches) {\n incoming = terminalBarrierFrom(\n {\n configIssuedAt: evaluation.configIssuedAt,\n configSemanticHash: evaluation.configSemanticHash,\n policySourceHash: evaluation.policySourceHash,\n contextRevision: evaluation.contextRevision,\n decisionHash: evaluation.decisionHash,\n },\n 'context'\n )\n reason = 'identity or consent witness changed before authority installation'\n } else if (this._captureConfigSiteId !== evaluation.configSiteId) {\n incoming = terminalBarrierFrom(\n {\n configIssuedAt: evaluation.configIssuedAt,\n configSemanticHash: evaluation.configSemanticHash,\n policySourceHash: evaluation.policySourceHash,\n contextRevision: evaluation.contextRevision,\n decisionHash: evaluation.decisionHash,\n },\n 'config'\n )\n reason = 'config site identity does not match the owner pin'\n } else {\n try {\n const source = this._sourceClockForCapture(evaluation, current.identity)\n executable = freezeV1Value({\n ...source,\n ownerEpoch: prospectiveOwnerEpoch,\n barrier: incoming,\n configSiteId: evaluation.configSiteId,\n streamId: current.streamId,\n identityRevision: current.identity.revision,\n contextRevision: current.identity.contextRevision,\n identityOptedOut: false,\n lifecycleEpoch: this._captureLifecycleEpoch,\n idleTimeoutSeconds: evaluation.idleTimeoutSeconds,\n maximumDurationSeconds: 86_400,\n })\n reason = 'authorized'\n } catch {\n incoming = terminalBarrierFrom(\n {\n configIssuedAt: evaluation.configIssuedAt,\n configSemanticHash: evaluation.configSemanticHash,\n policySourceHash: evaluation.policySourceHash,\n contextRevision: evaluation.contextRevision,\n decisionHash: evaluation.decisionHash,\n },\n 'config'\n )\n reason = 'capture clock discontinuity during authority installation'\n }\n }\n }\n\n const merged = mergeAuthorityBarrier(current.authorityBarrier, incoming)\n if (!sameAuthorityBarrier(merged, incoming) || merged.kind !== 'authorized') executable = null\n if (!sameAuthorityBarrier(merged, incoming) && evaluation.status === 'authorized') {\n reason = 'persisted authority boundary rejected the candidate'\n }\n const row: V1InstallationRow = freezeV1Value({ ...current, authorityBarrier: merged })\n if (!sameAuthorityBarrier(current.authorityBarrier, merged)) await transaction.putInstallation(row)\n return freezeV1Value({ row, authority: executable, reason })\n })\n\n let outcome = await attempt()\n if (outcome.status === 'proven-not-committed' && !(outcome.error instanceof V1DurableStateError)) {\n outcome = await attempt()\n }\n if (outcome.status === 'unknown') {\n this._captureAuthority = null\n throw new V1DurableStateError('commit-unknown', 'authority barrier commit outcome is unknown')\n }\n if (outcome.status === 'proven-not-committed') throw outcome.error\n this._captureOwnerEpoch = prospectiveOwnerEpoch\n this._captureAuthority = outcome.value.authority\n this._snapshot = snapshotFromRow(outcome.value.row)\n if (outcome.value.authority) {\n try {\n this._requireCaptureSourceClock(outcome.value.authority)\n } catch (error) {\n if (!(error instanceof V1CaptureConfigTerminalError)) throw error\n this._captureAuthority = null\n this._captureTerminalIntent = terminalBarrierAtCurrentConfig(\n outcome.value.row.authorityBarrier,\n 'config'\n )\n await this._readCaptureState(storage)\n return freezeV1Value({ status: 'terminal', reason: 'capture source expired before publication' })\n }\n }\n return outcome.value.authority\n ? freezeV1Value({ status: 'authorized', ownerEpoch: prospectiveOwnerEpoch })\n : freezeV1Value({ status: 'terminal', reason: outcome.value.reason })\n }\n\n private _requireCaptureAuthority(current: V1InstallationRow): V1ExecutableCaptureAuthority {\n const authority = this._captureAuthority\n const reject = (message: string): never => {\n this._captureAuthority = null\n return fail('capture-not-authorized', message)\n }\n if (!authority) return reject('capture authority is absent')\n this._requireCaptureLifecycle(authority)\n if (\n authority.configSiteId !== this._captureConfigSiteId ||\n authority.streamId !== current.streamId ||\n authority.identityRevision !== current.identity.revision ||\n authority.contextRevision !== current.identity.contextRevision ||\n authority.identityOptedOut !== current.identity.optedOut ||\n current.identity.optedOut\n ) {\n return reject('capture authority identity, consent, site, or stream witness changed')\n }\n if (!sameAuthorityBarrier(authority.barrier, current.authorityBarrier)) {\n return reject('capture authority no longer matches the persisted cross-tab barrier')\n }\n\n this._requireCaptureSourceClock(authority)\n return authority\n }\n\n private _requireCaptureLifecycle(authority: V1ExecutableCaptureAuthority): void {\n if (!this._captureLifecycleProtected || authority.lifecycleEpoch !== this._captureLifecycleEpoch) {\n this._captureAuthority = null\n return fail('capture-not-authorized', 'capture authority crossed a page lifecycle boundary')\n }\n }\n\n private _requireCaptureSourceClock(authority: V1CaptureSourceClock): number {\n const configTerminal = (message: string): never => {\n const source = this._captureSourceIssuance\n if (source?.token === authority.sourceToken) {\n this._captureSourceIssuance = freezeV1Value({ ...source, denied: true })\n }\n throw new V1CaptureConfigTerminalError(message)\n }\n if (this._captureSourceIssuance?.token === authority.sourceToken && this._captureSourceIssuance.denied) {\n return configTerminal('capture source clock was already denied')\n }\n let wall: ReturnType<typeof captureWallNow>\n let monotonicNowUs: number\n try {\n wall = captureWallNow(this._captureClock)\n monotonicNowUs = captureMonotonicUs(this._captureClock, 'ceil')\n } catch {\n return configTerminal('capture clock discontinuity while validating authority')\n }\n if (compareV1DateTimes(wall.text, authority.expiresAt) >= 0) {\n return configTerminal('capture authority reached its wall-clock expiry')\n }\n if (monotonicNowUs < authority.monotonicStartedAtUs) {\n return configTerminal('capture monotonic clock moved backward')\n }\n const monotonicElapsed = monotonicNowUs - authority.monotonicStartedAtUs\n if (monotonicElapsed >= authority.monotonicBudgetUs) {\n return configTerminal('capture authority reached its monotonic expiry')\n }\n let wallElapsed: number\n try {\n wallElapsed = v1MicrosecondsBetween(wall.text, authority.installedWallAt)\n } catch {\n return configTerminal('capture wall-clock duration is unsafe')\n }\n if (wallElapsed < 0 || Math.abs(wallElapsed - monotonicElapsed) > 1_000_000) {\n return configTerminal('capture wall and monotonic clocks observed a lifecycle discontinuity')\n }\n return Math.max(\n 0,\n Math.min(\n authority.monotonicBudgetUs - monotonicElapsed,\n v1MicrosecondsBetween(authority.expiresAt, wall.text)\n )\n )\n }\n\n private async _commitAppend(\n transaction: V1DurableStorageTransaction,\n current: V1InstallationRow,\n identity: V1PersistedIdentityState,\n encoded: readonly V1EncodedRecord[]\n ): Promise<V1DurableAppendResult> {\n let addedBytes = 0\n for (const record of encoded) {\n if (!Number.isSafeInteger(addedBytes + record.stored.payloadBytes)) {\n return fail('queue-full', 'record bytes exceed the queue counter range')\n }\n addedBytes += record.stored.payloadBytes\n }\n const nextCount = current.queuedCount + encoded.length\n const nextBytes = current.queuedBytes + addedBytes\n // The limits are aggregate per site: live replay chunks share the count and byte budget.\n const aggregateCount = nextCount + (current.replay?.replayQueuedCount ?? 0)\n const aggregateBytes = nextBytes + (current.replay?.replayQueuedBytes ?? 0)\n const policy = this._queuePolicy\n if (\n encoded.length > 0 &&\n (policy || current.authorityBarrier) &&\n (!policy || current.authorityBarrier?.configIssuedAt !== policy.configIssuedAt ||\n current.authorityBarrier?.configSemanticHash !== policy.configSemanticHash)\n ) {\n return fail('queue-full', 'queue policy no longer matches the transaction-current configuration')\n }\n if (\n encoded.length > 0 &&\n (!Number.isSafeInteger(aggregateCount) ||\n !Number.isSafeInteger(aggregateBytes) ||\n aggregateCount > this._limits.maxCount ||\n aggregateBytes > (policy?.maxBytes ?? this._limits.maxBytes))\n ) {\n return fail('queue-full', 'newest append exceeds the durable queue limit')\n }\n\n const nextRow: V1InstallationRow = freezeV1Value({\n ...current,\n identity,\n nextSequence: current.nextSequence + encoded.length,\n queuedCount: nextCount,\n queuedBytes: nextBytes,\n })\n for (const record of encoded) {\n await transaction.addRecord(record.stored)\n }\n await transaction.putInstallation(nextRow)\n return freezeV1Value({\n state: snapshotFromRow(nextRow),\n records: freezeV1Value(encoded.map((record) => record.exposed)),\n })\n }\n\n private _appendTransactionOperation<TInput>(\n encode: (transaction: V1DurableStorageTransaction, current: V1InstallationRow, input: TInput) => Promise<V1DurableAppendResult>,\n publish: (result: V1DurableAppendResult, input: TInput) => V1DurableAppendResult\n ): (input: TInput) => Promise<V1DurableAppendResult> {\n // A callback factory shares the existing two await boundaries. It does not wrap\n // an awaited prefix in another async helper or extend transaction lifetime.\n return async (input) => {\n const storage = this._requireStorage()\n try {\n const result = await storage.runTransaction('readwrite', async (transaction) => {\n const current = await readInstallation(transaction, this._siteKey)\n return encode(transaction, current, input)\n })\n return publish(result, input)\n } catch (error) {\n this._rememberFatalFailure(error)\n throw error\n }\n }\n }\n\n private _requireStorage(): V1DurableStorage {\n if (this._poisoned) {\n throw this._poisoned\n }\n if (!this._storage) {\n return fail('not-initialized', 'durable state is not initialized')\n }\n return this._storage\n }\n\n private _invalidateCaptureAuthorityForLifecycleNow(): void {\n this._captureAuthority = null\n this._captureLifecycleEpoch = incrementStateCounter(this._captureLifecycleEpoch, 'capture lifecycle epoch')\n }\n\n private _rememberFatalFailure(error: unknown): void {\n const isFatalStateError =\n error instanceof V1DurableStateError &&\n (error.code === 'corrupt-storage' || error.code === 'unsupported-storage')\n const isFatalStorageError =\n error instanceof V1DurableStorageError && (error.code === 'unsupported' || error.code === 'closed')\n if (isFatalStateError || isFatalStorageError) {\n this._storage?.close()\n this._storage = null\n this._snapshot = null\n this._poisoned = error instanceof Error ? error : new Error('durable state failed closed')\n }\n }\n\n private _serialize<T>(operation: () => Promise<T>): Promise<T> {\n const result = this._tail.then(operation)\n this._tail = result.then(\n () => undefined,\n () => undefined\n )\n return result\n }\n\n private _snapshotAndSerialize<TInput, TResult>(\n snapshot: () => TInput,\n operation: (input: TInput) => Promise<TResult>\n ): Promise<TResult> {\n let input: TInput\n try {\n input = snapshot()\n } catch (error) {\n return this._serialize(async () => {\n throw error\n })\n }\n return this._serialize(() => operation(input))\n }\n}\n","// DEFLATE is a complex format; to read this code, you should probably check the RFC first:\n// https://tools.ietf.org/html/rfc1951\n// You may also wish to take a look at the guide I made about this program:\n// https://gist.github.com/101arrowz/253f31eb5abc3d9275ab943003ffecad\n// Much of the following code is similar to that of UZIP.js:\n// https://github.com/photopea/UZIP.js\n// Many optimizations have been made, so the bundle size is ultimately smaller but performance is similar.\n// Sometimes 0 will appear where -1 would be more appropriate. This is because using a uint\n// is better for memory in most engines (I *think*).\nvar ch2 = {};\nvar wk = (function (c, id, msg, transfer, cb) {\n var u = ch2[id] || (ch2[id] = URL.createObjectURL(new Blob([c], { type: 'text/javascript' })));\n var w = new Worker(u);\n w.onerror = function (e) { return cb(e.error, null); };\n w.onmessage = function (e) { return cb(null, e.data); };\n w.postMessage(msg, transfer);\n return w;\n});\n\n// aliases for shorter compressed code (most minifers don't do this)\nvar u8 = Uint8Array, u16 = Uint16Array, u32 = Uint32Array;\n// fixed length extra bits\nvar fleb = new u8([0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, /* unused */ 0, 0, /* impossible */ 0]);\n// fixed distance extra bits\n// see fleb note\nvar fdeb = new u8([0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, /* unused */ 0, 0]);\n// code length index map\nvar clim = new u8([16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]);\n// get base, reverse index map from extra bits\nvar freb = function (eb, start) {\n var b = new u16(31);\n for (var i = 0; i < 31; ++i) {\n b[i] = start += 1 << eb[i - 1];\n }\n // numbers here are at max 18 bits\n var r = new u32(b[30]);\n for (var i = 1; i < 30; ++i) {\n for (var j = b[i]; j < b[i + 1]; ++j) {\n r[j] = ((j - b[i]) << 5) | i;\n }\n }\n return [b, r];\n};\nvar _a = freb(fleb, 2), fl = _a[0], revfl = _a[1];\n// we can ignore the fact that the other numbers are wrong; they never happen anyway\nfl[28] = 258, revfl[258] = 28;\nvar _b = freb(fdeb, 0), fd = _b[0], revfd = _b[1];\n// map of value to reverse (assuming 16 bits)\nvar rev = new u16(32768);\nfor (var i = 0; i < 32768; ++i) {\n // reverse table algorithm from SO\n var x = ((i & 0xAAAA) >>> 1) | ((i & 0x5555) << 1);\n x = ((x & 0xCCCC) >>> 2) | ((x & 0x3333) << 2);\n x = ((x & 0xF0F0) >>> 4) | ((x & 0x0F0F) << 4);\n rev[i] = (((x & 0xFF00) >>> 8) | ((x & 0x00FF) << 8)) >>> 1;\n}\n// create huffman tree from u8 \"map\": index -> code length for code index\n// mb (max bits) must be at most 15\n// TODO: optimize/split up?\nvar hMap = (function (cd, mb, r) {\n var s = cd.length;\n // index\n var i = 0;\n // u16 \"map\": index -> # of codes with bit length = index\n var l = new u16(mb);\n // length of cd must be 288 (total # of codes)\n for (; i < s; ++i)\n ++l[cd[i] - 1];\n // u16 \"map\": index -> minimum code for bit length = index\n var le = new u16(mb);\n for (i = 0; i < mb; ++i) {\n le[i] = (le[i - 1] + l[i - 1]) << 1;\n }\n var co;\n if (r) {\n // u16 \"map\": index -> number of actual bits, symbol for code\n co = new u16(1 << mb);\n // bits to remove for reverser\n var rvb = 15 - mb;\n for (i = 0; i < s; ++i) {\n // ignore 0 lengths\n if (cd[i]) {\n // num encoding both symbol and bits read\n var sv = (i << 4) | cd[i];\n // free bits\n var r_1 = mb - cd[i];\n // start value\n var v = le[cd[i] - 1]++ << r_1;\n // m is end value\n for (var m = v | ((1 << r_1) - 1); v <= m; ++v) {\n // every 16 bit value starting with the code yields the same result\n co[rev[v] >>> rvb] = sv;\n }\n }\n }\n }\n else {\n co = new u16(s);\n for (i = 0; i < s; ++i)\n co[i] = rev[le[cd[i] - 1]++] >>> (15 - cd[i]);\n }\n return co;\n});\n// fixed length tree\nvar flt = new u8(288);\nfor (var i = 0; i < 144; ++i)\n flt[i] = 8;\nfor (var i = 144; i < 256; ++i)\n flt[i] = 9;\nfor (var i = 256; i < 280; ++i)\n flt[i] = 7;\nfor (var i = 280; i < 288; ++i)\n flt[i] = 8;\n// fixed distance tree\nvar fdt = new u8(32);\nfor (var i = 0; i < 32; ++i)\n fdt[i] = 5;\n// fixed length map\nvar flm = /*#__PURE__*/ hMap(flt, 9, 0), flrm = /*#__PURE__*/ hMap(flt, 9, 1);\n// fixed distance map\nvar fdm = /*#__PURE__*/ hMap(fdt, 5, 0), fdrm = /*#__PURE__*/ hMap(fdt, 5, 1);\n// find max of array\nvar max = function (a) {\n var m = a[0];\n for (var i = 1; i < a.length; ++i) {\n if (a[i] > m)\n m = a[i];\n }\n return m;\n};\n// read d, starting at bit p and mask with m\nvar bits = function (d, p, m) {\n var o = (p / 8) >> 0;\n return ((d[o] | (d[o + 1] << 8)) >>> (p & 7)) & m;\n};\n// read d, starting at bit p continuing for at least 16 bits\nvar bits16 = function (d, p) {\n var o = (p / 8) >> 0;\n return ((d[o] | (d[o + 1] << 8) | (d[o + 2] << 16)) >>> (p & 7));\n};\n// get end of byte\nvar shft = function (p) { return ((p / 8) >> 0) + (p & 7 && 1); };\n// typed array slice - allows garbage collector to free original reference,\n// while being more compatible than .slice\nvar slc = function (v, s, e) {\n if (s == null || s < 0)\n s = 0;\n if (e == null || e > v.length)\n e = v.length;\n // can't use .constructor in case user-supplied\n var n = new (v instanceof u16 ? u16 : v instanceof u32 ? u32 : u8)(e - s);\n n.set(v.subarray(s, e));\n return n;\n};\n// expands raw DEFLATE data\nvar inflt = function (dat, buf, st) {\n // source length\n var sl = dat.length;\n // have to estimate size\n var noBuf = !buf || st;\n // no state\n var noSt = !st || st.i;\n if (!st)\n st = {};\n // Assumes roughly 33% compression ratio average\n if (!buf)\n buf = new u8(sl * 3);\n // ensure buffer can fit at least l elements\n var cbuf = function (l) {\n var bl = buf.length;\n // need to increase size to fit\n if (l > bl) {\n // Double or set to necessary, whichever is greater\n var nbuf = new u8(Math.max(bl * 2, l));\n nbuf.set(buf);\n buf = nbuf;\n }\n };\n // last chunk bitpos bytes\n var final = st.f || 0, pos = st.p || 0, bt = st.b || 0, lm = st.l, dm = st.d, lbt = st.m, dbt = st.n;\n // total bits\n var tbts = sl * 8;\n do {\n if (!lm) {\n // BFINAL - this is only 1 when last chunk is next\n st.f = final = bits(dat, pos, 1);\n // type: 0 = no compression, 1 = fixed huffman, 2 = dynamic huffman\n var type = bits(dat, pos + 1, 3);\n pos += 3;\n if (!type) {\n // go to end of byte boundary\n var s = shft(pos) + 4, l = dat[s - 4] | (dat[s - 3] << 8), t = s + l;\n if (t > sl) {\n if (noSt)\n throw 'unexpected EOF';\n break;\n }\n // ensure size\n if (noBuf)\n cbuf(bt + l);\n // Copy over uncompressed data\n buf.set(dat.subarray(s, t), bt);\n // Get new bitpos, update byte count\n st.b = bt += l, st.p = pos = t * 8;\n continue;\n }\n else if (type == 1)\n lm = flrm, dm = fdrm, lbt = 9, dbt = 5;\n else if (type == 2) {\n // literal lengths\n var hLit = bits(dat, pos, 31) + 257, hcLen = bits(dat, pos + 10, 15) + 4;\n var tl = hLit + bits(dat, pos + 5, 31) + 1;\n pos += 14;\n // length+distance tree\n var ldt = new u8(tl);\n // code length tree\n var clt = new u8(19);\n for (var i = 0; i < hcLen; ++i) {\n // use index map to get real code\n clt[clim[i]] = bits(dat, pos + i * 3, 7);\n }\n pos += hcLen * 3;\n // code lengths bits\n var clb = max(clt), clbmsk = (1 << clb) - 1;\n if (!noSt && pos + tl * (clb + 7) > tbts)\n break;\n // code lengths map\n var clm = hMap(clt, clb, 1);\n for (var i = 0; i < tl;) {\n var r = clm[bits(dat, pos, clbmsk)];\n // bits read\n pos += r & 15;\n // symbol\n var s = r >>> 4;\n // code length to copy\n if (s < 16) {\n ldt[i++] = s;\n }\n else {\n // copy count\n var c = 0, n = 0;\n if (s == 16)\n n = 3 + bits(dat, pos, 3), pos += 2, c = ldt[i - 1];\n else if (s == 17)\n n = 3 + bits(dat, pos, 7), pos += 3;\n else if (s == 18)\n n = 11 + bits(dat, pos, 127), pos += 7;\n while (n--)\n ldt[i++] = c;\n }\n }\n // length tree distance tree\n var lt = ldt.subarray(0, hLit), dt = ldt.subarray(hLit);\n // max length bits\n lbt = max(lt);\n // max dist bits\n dbt = max(dt);\n lm = hMap(lt, lbt, 1);\n dm = hMap(dt, dbt, 1);\n }\n else\n throw 'invalid block type';\n if (pos > tbts)\n throw 'unexpected EOF';\n }\n // Make sure the buffer can hold this + the largest possible addition\n // Maximum chunk size (practically, theoretically infinite) is 2^17;\n if (noBuf)\n cbuf(bt + 131072);\n var lms = (1 << lbt) - 1, dms = (1 << dbt) - 1;\n var mxa = lbt + dbt + 18;\n while (noSt || pos + mxa < tbts) {\n // bits read, code\n var c = lm[bits16(dat, pos) & lms], sym = c >>> 4;\n pos += c & 15;\n if (pos > tbts)\n throw 'unexpected EOF';\n if (!c)\n throw 'invalid length/literal';\n if (sym < 256)\n buf[bt++] = sym;\n else if (sym == 256) {\n lm = null;\n break;\n }\n else {\n var add = sym - 254;\n // no extra bits needed if less\n if (sym > 264) {\n // index\n var i = sym - 257, b = fleb[i];\n add = bits(dat, pos, (1 << b) - 1) + fl[i];\n pos += b;\n }\n // dist\n var d = dm[bits16(dat, pos) & dms], dsym = d >>> 4;\n if (!d)\n throw 'invalid distance';\n pos += d & 15;\n var dt = fd[dsym];\n if (dsym > 3) {\n var b = fdeb[dsym];\n dt += bits16(dat, pos) & ((1 << b) - 1), pos += b;\n }\n if (pos > tbts)\n throw 'unexpected EOF';\n if (noBuf)\n cbuf(bt + 131072);\n var end = bt + add;\n for (; bt < end; bt += 4) {\n buf[bt] = buf[bt - dt];\n buf[bt + 1] = buf[bt + 1 - dt];\n buf[bt + 2] = buf[bt + 2 - dt];\n buf[bt + 3] = buf[bt + 3 - dt];\n }\n bt = end;\n }\n }\n st.l = lm, st.p = pos, st.b = bt;\n if (lm)\n final = 1, st.m = lbt, st.d = dm, st.n = dbt;\n } while (!final);\n return bt == buf.length ? buf : slc(buf, 0, bt);\n};\n// starting at p, write the minimum number of bits that can hold v to d\nvar wbits = function (d, p, v) {\n v <<= p & 7;\n var o = (p / 8) >> 0;\n d[o] |= v;\n d[o + 1] |= v >>> 8;\n};\n// starting at p, write the minimum number of bits (>8) that can hold v to d\nvar wbits16 = function (d, p, v) {\n v <<= p & 7;\n var o = (p / 8) >> 0;\n d[o] |= v;\n d[o + 1] |= v >>> 8;\n d[o + 2] |= v >>> 16;\n};\n// creates code lengths from a frequency table\nvar hTree = function (d, mb) {\n // Need extra info to make a tree\n var t = [];\n for (var i = 0; i < d.length; ++i) {\n if (d[i])\n t.push({ s: i, f: d[i] });\n }\n var s = t.length;\n var t2 = t.slice();\n if (!s)\n return [new u8(0), 0];\n if (s == 1) {\n var v = new u8(t[0].s + 1);\n v[t[0].s] = 1;\n return [v, 1];\n }\n t.sort(function (a, b) { return a.f - b.f; });\n // after i2 reaches last ind, will be stopped\n // freq must be greater than largest possible number of symbols\n t.push({ s: -1, f: 25001 });\n var l = t[0], r = t[1], i0 = 0, i1 = 1, i2 = 2;\n t[0] = { s: -1, f: l.f + r.f, l: l, r: r };\n // efficient algorithm from UZIP.js\n // i0 is lookbehind, i2 is lookahead - after processing two low-freq\n // symbols that combined have high freq, will start processing i2 (high-freq,\n // non-composite) symbols instead\n // see https://reddit.com/r/photopea/comments/ikekht/uzipjs_questions/\n while (i1 != s - 1) {\n l = t[t[i0].f < t[i2].f ? i0++ : i2++];\n r = t[i0 != i1 && t[i0].f < t[i2].f ? i0++ : i2++];\n t[i1++] = { s: -1, f: l.f + r.f, l: l, r: r };\n }\n var maxSym = t2[0].s;\n for (var i = 1; i < s; ++i) {\n if (t2[i].s > maxSym)\n maxSym = t2[i].s;\n }\n // code lengths\n var tr = new u16(maxSym + 1);\n // max bits in tree\n var mbt = ln(t[i1 - 1], tr, 0);\n if (mbt > mb) {\n // more algorithms from UZIP.js\n // TODO: find out how this code works (debt)\n // ind debt\n var i = 0, dt = 0;\n // left cost\n var lft = mbt - mb, cst = 1 << lft;\n t2.sort(function (a, b) { return tr[b.s] - tr[a.s] || a.f - b.f; });\n for (; i < s; ++i) {\n var i2_1 = t2[i].s;\n if (tr[i2_1] > mb) {\n dt += cst - (1 << (mbt - tr[i2_1]));\n tr[i2_1] = mb;\n }\n else\n break;\n }\n dt >>>= lft;\n while (dt > 0) {\n var i2_2 = t2[i].s;\n if (tr[i2_2] < mb)\n dt -= 1 << (mb - tr[i2_2]++ - 1);\n else\n ++i;\n }\n for (; i >= 0 && dt; --i) {\n var i2_3 = t2[i].s;\n if (tr[i2_3] == mb) {\n --tr[i2_3];\n ++dt;\n }\n }\n mbt = mb;\n }\n return [new u8(tr), mbt];\n};\n// get the max length and assign length codes\nvar ln = function (n, l, d) {\n return n.s == -1\n ? Math.max(ln(n.l, l, d + 1), ln(n.r, l, d + 1))\n : (l[n.s] = d);\n};\n// length codes generation\nvar lc = function (c) {\n var s = c.length;\n // Note that the semicolon was intentional\n while (s && !c[--s])\n ;\n var cl = new u16(++s);\n // ind num streak\n var cli = 0, cln = c[0], cls = 1;\n var w = function (v) { cl[cli++] = v; };\n for (var i = 1; i <= s; ++i) {\n if (c[i] == cln && i != s)\n ++cls;\n else {\n if (!cln && cls > 2) {\n for (; cls > 138; cls -= 138)\n w(32754);\n if (cls > 2) {\n w(cls > 10 ? ((cls - 11) << 5) | 28690 : ((cls - 3) << 5) | 12305);\n cls = 0;\n }\n }\n else if (cls > 3) {\n w(cln), --cls;\n for (; cls > 6; cls -= 6)\n w(8304);\n if (cls > 2)\n w(((cls - 3) << 5) | 8208), cls = 0;\n }\n while (cls--)\n w(cln);\n cls = 1;\n cln = c[i];\n }\n }\n return [cl.subarray(0, cli), s];\n};\n// calculate the length of output from tree, code lengths\nvar clen = function (cf, cl) {\n var l = 0;\n for (var i = 0; i < cl.length; ++i)\n l += cf[i] * cl[i];\n return l;\n};\n// writes a fixed block\n// returns the new bit pos\nvar wfblk = function (out, pos, dat) {\n // no need to write 00 as type: TypedArray defaults to 0\n var s = dat.length;\n var o = shft(pos + 2);\n out[o] = s & 255;\n out[o + 1] = s >>> 8;\n out[o + 2] = out[o] ^ 255;\n out[o + 3] = out[o + 1] ^ 255;\n for (var i = 0; i < s; ++i)\n out[o + i + 4] = dat[i];\n return (o + 4 + s) * 8;\n};\n// writes a block\nvar wblk = function (dat, out, final, syms, lf, df, eb, li, bs, bl, p) {\n wbits(out, p++, final);\n ++lf[256];\n var _a = hTree(lf, 15), dlt = _a[0], mlb = _a[1];\n var _b = hTree(df, 15), ddt = _b[0], mdb = _b[1];\n var _c = lc(dlt), lclt = _c[0], nlc = _c[1];\n var _d = lc(ddt), lcdt = _d[0], ndc = _d[1];\n var lcfreq = new u16(19);\n for (var i = 0; i < lclt.length; ++i)\n lcfreq[lclt[i] & 31]++;\n for (var i = 0; i < lcdt.length; ++i)\n lcfreq[lcdt[i] & 31]++;\n var _e = hTree(lcfreq, 7), lct = _e[0], mlcb = _e[1];\n var nlcc = 19;\n for (; nlcc > 4 && !lct[clim[nlcc - 1]]; --nlcc)\n ;\n var flen = (bl + 5) << 3;\n var ftlen = clen(lf, flt) + clen(df, fdt) + eb;\n var dtlen = clen(lf, dlt) + clen(df, ddt) + eb + 14 + 3 * nlcc + clen(lcfreq, lct) + (2 * lcfreq[16] + 3 * lcfreq[17] + 7 * lcfreq[18]);\n if (flen <= ftlen && flen <= dtlen)\n return wfblk(out, p, dat.subarray(bs, bs + bl));\n var lm, ll, dm, dl;\n wbits(out, p, 1 + (dtlen < ftlen)), p += 2;\n if (dtlen < ftlen) {\n lm = hMap(dlt, mlb, 0), ll = dlt, dm = hMap(ddt, mdb, 0), dl = ddt;\n var llm = hMap(lct, mlcb, 0);\n wbits(out, p, nlc - 257);\n wbits(out, p + 5, ndc - 1);\n wbits(out, p + 10, nlcc - 4);\n p += 14;\n for (var i = 0; i < nlcc; ++i)\n wbits(out, p + 3 * i, lct[clim[i]]);\n p += 3 * nlcc;\n var lcts = [lclt, lcdt];\n for (var it = 0; it < 2; ++it) {\n var clct = lcts[it];\n for (var i = 0; i < clct.length; ++i) {\n var len = clct[i] & 31;\n wbits(out, p, llm[len]), p += lct[len];\n if (len > 15)\n wbits(out, p, (clct[i] >>> 5) & 127), p += clct[i] >>> 12;\n }\n }\n }\n else {\n lm = flm, ll = flt, dm = fdm, dl = fdt;\n }\n for (var i = 0; i < li; ++i) {\n if (syms[i] > 255) {\n var len = (syms[i] >>> 18) & 31;\n wbits16(out, p, lm[len + 257]), p += ll[len + 257];\n if (len > 7)\n wbits(out, p, (syms[i] >>> 23) & 31), p += fleb[len];\n var dst = syms[i] & 31;\n wbits16(out, p, dm[dst]), p += dl[dst];\n if (dst > 3)\n wbits16(out, p, (syms[i] >>> 5) & 8191), p += fdeb[dst];\n }\n else {\n wbits16(out, p, lm[syms[i]]), p += ll[syms[i]];\n }\n }\n wbits16(out, p, lm[256]);\n return p + ll[256];\n};\n// deflate options (nice << 13) | chain\nvar deo = /*#__PURE__*/ new u32([65540, 131080, 131088, 131104, 262176, 1048704, 1048832, 2114560, 2117632]);\n// empty\nvar et = /*#__PURE__*/ new u8(0);\n// compresses data into a raw DEFLATE buffer\nvar dflt = function (dat, lvl, plvl, pre, post, lst) {\n var s = dat.length;\n var o = new u8(pre + s + 5 * (1 + Math.floor(s / 7000)) + post);\n // writing to this writes to the output buffer\n var w = o.subarray(pre, o.length - post);\n var pos = 0;\n if (!lvl || s < 8) {\n for (var i = 0; i <= s; i += 65535) {\n // end\n var e = i + 65535;\n if (e < s) {\n // write full block\n pos = wfblk(w, pos, dat.subarray(i, e));\n }\n else {\n // write final block\n w[i] = lst;\n pos = wfblk(w, pos, dat.subarray(i, s));\n }\n }\n }\n else {\n var opt = deo[lvl - 1];\n var n = opt >>> 13, c = opt & 8191;\n var msk_1 = (1 << plvl) - 1;\n // prev 2-byte val map curr 2-byte val map\n var prev = new u16(32768), head = new u16(msk_1 + 1);\n var bs1_1 = Math.ceil(plvl / 3), bs2_1 = 2 * bs1_1;\n var hsh = function (i) { return (dat[i] ^ (dat[i + 1] << bs1_1) ^ (dat[i + 2] << bs2_1)) & msk_1; };\n // 24576 is an arbitrary number of maximum symbols per block\n // 424 buffer for last block\n var syms = new u32(25000);\n // length/literal freq distance freq\n var lf = new u16(288), df = new u16(32);\n // l/lcnt exbits index l/lind waitdx bitpos\n var lc_1 = 0, eb = 0, i = 0, li = 0, wi = 0, bs = 0;\n for (; i < s; ++i) {\n // hash value\n var hv = hsh(i);\n // index mod 32768\n var imod = i & 32767;\n // previous index with this value\n var pimod = head[hv];\n prev[imod] = pimod;\n head[hv] = imod;\n // We always should modify head and prev, but only add symbols if\n // this data is not yet processed (\"wait\" for wait index)\n if (wi <= i) {\n // bytes remaining\n var rem = s - i;\n if ((lc_1 > 7000 || li > 24576) && rem > 423) {\n pos = wblk(dat, w, 0, syms, lf, df, eb, li, bs, i - bs, pos);\n li = lc_1 = eb = 0, bs = i;\n for (var j = 0; j < 286; ++j)\n lf[j] = 0;\n for (var j = 0; j < 30; ++j)\n df[j] = 0;\n }\n // len dist chain\n var l = 2, d = 0, ch_1 = c, dif = (imod - pimod) & 32767;\n if (rem > 2 && hv == hsh(i - dif)) {\n var maxn = Math.min(n, rem) - 1;\n var maxd = Math.min(32767, i);\n // max possible length\n // not capped at dif because decompressors implement \"rolling\" index population\n var ml = Math.min(258, rem);\n while (dif <= maxd && --ch_1 && imod != pimod) {\n if (dat[i + l] == dat[i + l - dif]) {\n var nl = 0;\n for (; nl < ml && dat[i + nl] == dat[i + nl - dif]; ++nl)\n ;\n if (nl > l) {\n l = nl, d = dif;\n // break out early when we reach \"nice\" (we are satisfied enough)\n if (nl > maxn)\n break;\n // now, find the rarest 2-byte sequence within this\n // length of literals and search for that instead.\n // Much faster than just using the start\n var mmd = Math.min(dif, nl - 2);\n var md = 0;\n for (var j = 0; j < mmd; ++j) {\n var ti = (i - dif + j + 32768) & 32767;\n var pti = prev[ti];\n var cd = (ti - pti + 32768) & 32767;\n if (cd > md)\n md = cd, pimod = ti;\n }\n }\n }\n // check the previous match\n imod = pimod, pimod = prev[imod];\n dif += (imod - pimod + 32768) & 32767;\n }\n }\n // d will be nonzero only when a match was found\n if (d) {\n // store both dist and len data in one Uint32\n // Make sure this is recognized as a len/dist with 28th bit (2^28)\n syms[li++] = 268435456 | (revfl[l] << 18) | revfd[d];\n var lin = revfl[l] & 31, din = revfd[d] & 31;\n eb += fleb[lin] + fdeb[din];\n ++lf[257 + lin];\n ++df[din];\n wi = i + l;\n ++lc_1;\n }\n else {\n syms[li++] = dat[i];\n ++lf[dat[i]];\n }\n }\n }\n pos = wblk(dat, w, lst, syms, lf, df, eb, li, bs, i - bs, pos);\n // this is the easiest way to avoid needing to maintain state\n if (!lst)\n pos = wfblk(w, pos, et);\n }\n return slc(o, 0, pre + shft(pos) + post);\n};\n// CRC32 table\nvar crct = /*#__PURE__*/ (function () {\n var t = new u32(256);\n for (var i = 0; i < 256; ++i) {\n var c = i, k = 9;\n while (--k)\n c = ((c & 1) && 0xEDB88320) ^ (c >>> 1);\n t[i] = c;\n }\n return t;\n})();\n// CRC32\nvar crc = function () {\n var c = 0xFFFFFFFF;\n return {\n p: function (d) {\n // closures have awful performance\n var cr = c;\n for (var i = 0; i < d.length; ++i)\n cr = crct[(cr & 255) ^ d[i]] ^ (cr >>> 8);\n c = cr;\n },\n d: function () { return c ^ 0xFFFFFFFF; }\n };\n};\n// Alder32\nvar adler = function () {\n var a = 1, b = 0;\n return {\n p: function (d) {\n // closures have awful performance\n var n = a, m = b;\n var l = d.length;\n for (var i = 0; i != l;) {\n var e = Math.min(i + 5552, l);\n for (; i < e; ++i)\n n += d[i], m += n;\n n %= 65521, m %= 65521;\n }\n a = n, b = m;\n },\n d: function () { return ((a >>> 8) << 16 | (b & 255) << 8 | (b >>> 8)) + ((a & 255) << 23) * 2; }\n };\n};\n;\n// deflate with opts\nvar dopt = function (dat, opt, pre, post, st) {\n return dflt(dat, opt.level == null ? 6 : opt.level, opt.mem == null ? Math.ceil(Math.max(8, Math.min(13, Math.log(dat.length))) * 1.5) : (12 + opt.mem), pre, post, !st);\n};\n// Walmart object spread\nvar mrg = function (a, b) {\n var o = {};\n for (var k in a)\n o[k] = a[k];\n for (var k in b)\n o[k] = b[k];\n return o;\n};\n// worker clone\n// This is possibly the craziest part of the entire codebase, despite how simple it may seem.\n// The only parameter to this function is a closure that returns an array of variables outside of the function scope.\n// We're going to try to figure out the variable names used in the closure as strings because that is crucial for workerization.\n// We will return an object mapping of true variable name to value (basically, the current scope as a JS object).\n// The reason we can't just use the original variable names is minifiers mangling the toplevel scope.\n// This took me three weeks to figure out how to do.\nvar wcln = function (fn, fnStr, td) {\n var dt = fn();\n var st = fn.toString();\n var ks = st.slice(st.indexOf('[') + 1, st.lastIndexOf(']')).replace(/ /g, '').split(',');\n for (var i = 0; i < dt.length; ++i) {\n var v = dt[i], k = ks[i];\n if (typeof v == 'function') {\n fnStr += ';' + k + '=';\n var st_1 = v.toString();\n if (v.prototype) {\n // for global objects\n if (st_1.indexOf('[native code]') != -1) {\n var spInd = st_1.indexOf(' ', 8) + 1;\n fnStr += st_1.slice(spInd, st_1.indexOf('(', spInd));\n }\n else {\n fnStr += st_1;\n for (var t in v.prototype)\n fnStr += ';' + k + '.prototype.' + t + '=' + v.prototype[t].toString();\n }\n }\n else\n fnStr += st_1;\n }\n else\n td[k] = v;\n }\n return [fnStr, td];\n};\nvar ch = [];\n// clone bufs\nvar cbfs = function (v) {\n var tl = [];\n for (var k in v) {\n if (v[k] instanceof u8 || v[k] instanceof u16 || v[k] instanceof u32)\n tl.push((v[k] = new v[k].constructor(v[k])).buffer);\n }\n return tl;\n};\n// use a worker to execute code\nvar wrkr = function (fns, init, id, cb) {\n var _a;\n if (!ch[id]) {\n var fnStr = '', td_1 = {}, m = fns.length - 1;\n for (var i = 0; i < m; ++i)\n _a = wcln(fns[i], fnStr, td_1), fnStr = _a[0], td_1 = _a[1];\n ch[id] = wcln(fns[m], fnStr, td_1);\n }\n var td = mrg({}, ch[id][1]);\n return wk(ch[id][0] + ';onmessage=function(e){for(var k in e.data)self[k]=e.data[k];onmessage=' + init.toString() + '}', id, td, cbfs(td), cb);\n};\n// base async inflate fn\nvar bInflt = function () { return [u8, u16, u32, fleb, fdeb, clim, fl, fd, flrm, fdrm, rev, hMap, max, bits, bits16, shft, slc, inflt, inflateSync, pbf, gu8]; };\nvar bDflt = function () { return [u8, u16, u32, fleb, fdeb, clim, revfl, revfd, flm, flt, fdm, fdt, rev, deo, et, hMap, wbits, wbits16, hTree, ln, lc, clen, wfblk, wblk, shft, slc, dflt, dopt, deflateSync, pbf]; };\n// gzip extra\nvar gze = function () { return [gzh, gzhl, wbytes, crc, crct]; };\n// gunzip extra\nvar guze = function () { return [gzs, gzl]; };\n// zlib extra\nvar zle = function () { return [zlh, wbytes, adler]; };\n// unzlib extra\nvar zule = function () { return [zlv]; };\n// post buf\nvar pbf = function (msg) { return postMessage(msg, [msg.buffer]); };\n// get u8\nvar gu8 = function (o) { return o && o.size && new u8(o.size); };\n// async helper\nvar cbify = function (dat, opts, fns, init, id, cb) {\n var w = wrkr(fns, init, id, function (err, dat) {\n w.terminate();\n cb(err, dat);\n });\n if (!opts.consume)\n dat = new u8(dat);\n w.postMessage([dat, opts], [dat.buffer]);\n return function () { w.terminate(); };\n};\n// auto stream\nvar astrm = function (strm) {\n strm.ondata = function (dat, final) { return postMessage([dat, final], [dat.buffer]); };\n return function (ev) { return strm.push(ev.data[0], ev.data[1]); };\n};\n// async stream attach\nvar astrmify = function (fns, strm, opts, init, id) {\n var t;\n var w = wrkr(fns, init, id, function (err, dat) {\n if (err)\n w.terminate(), strm.ondata.call(strm, err);\n else {\n if (dat[1])\n w.terminate();\n strm.ondata.call(strm, err, dat[0], dat[1]);\n }\n });\n w.postMessage(opts);\n strm.push = function (d, f) {\n if (t)\n throw 'stream finished';\n if (!strm.ondata)\n throw 'no stream handler';\n w.postMessage([d, t = f], [d.buffer]);\n };\n strm.terminate = function () { w.terminate(); };\n};\n// read 2 bytes\nvar b2 = function (d, b) { return d[b] | (d[b + 1] << 8); };\n// read 4 bytes\nvar b4 = function (d, b) { return (d[b] | (d[b + 1] << 8) | (d[b + 2] << 16)) + (d[b + 3] << 23) * 2; };\n// write bytes\nvar wbytes = function (d, b, v) {\n for (; v; ++b)\n d[b] = v, v >>>= 8;\n};\n// gzip header\nvar gzh = function (c, o) {\n var fn = o.filename;\n c[0] = 31, c[1] = 139, c[2] = 8, c[8] = o.level < 2 ? 4 : o.level == 9 ? 2 : 0, c[9] = 3; // assume Unix\n if (o.mtime != 0)\n wbytes(c, 4, Math.floor(new Date(o.mtime || Date.now()) / 1000));\n if (fn) {\n c[3] = 8;\n for (var i = 0; i <= fn.length; ++i)\n c[i + 10] = fn.charCodeAt(i);\n }\n};\n// gzip footer: -8 to -4 = CRC, -4 to -0 is length\n// gzip start\nvar gzs = function (d) {\n if (d[0] != 31 || d[1] != 139 || d[2] != 8)\n throw 'invalid gzip data';\n var flg = d[3];\n var st = 10;\n if (flg & 4)\n st += d[10] | (d[11] << 8) + 2;\n for (var zs = (flg >> 3 & 1) + (flg >> 4 & 1); zs > 0; zs -= !d[st++])\n ;\n return st + (flg & 2);\n};\n// gzip length\nvar gzl = function (d) {\n var l = d.length;\n return (d[l - 4] | d[l - 3] << 8 | d[l - 2] << 16) + (2 * (d[l - 1] << 23));\n};\n// gzip header length\nvar gzhl = function (o) { return 10 + ((o.filename && (o.filename.length + 1)) || 0); };\n// zlib header\nvar zlh = function (c, o) {\n var lv = o.level, fl = lv == 0 ? 0 : lv < 6 ? 1 : lv == 9 ? 3 : 2;\n c[0] = 120, c[1] = (fl << 6) | (fl ? (32 - 2 * fl) : 1);\n};\n// zlib valid\nvar zlv = function (d) {\n if ((d[0] & 15) != 8 || (d[0] >>> 4) > 7 || ((d[0] << 8 | d[1]) % 31))\n throw 'invalid zlib data';\n if (d[1] & 32)\n throw 'invalid zlib data: preset dictionaries not supported';\n};\nfunction AsyncCmpStrm(opts, cb) {\n if (!cb && typeof opts == 'function')\n cb = opts, opts = {};\n this.ondata = cb;\n return opts;\n}\n// zlib footer: -4 to -0 is Adler32\n/**\n * Streaming DEFLATE compression\n */\nvar Deflate = /*#__PURE__*/ (function () {\n function Deflate(opts, cb) {\n if (!cb && typeof opts == 'function')\n cb = opts, opts = {};\n this.ondata = cb;\n this.o = opts || {};\n }\n Deflate.prototype.p = function (c, f) {\n this.ondata(dopt(c, this.o, 0, 0, !f), f);\n };\n /**\n * Pushes a chunk to be deflated\n * @param chunk The chunk to push\n * @param final Whether this is the last chunk\n */\n Deflate.prototype.push = function (chunk, final) {\n if (this.d)\n throw 'stream finished';\n if (!this.ondata)\n throw 'no stream handler';\n this.d = final;\n this.p(chunk, final || false);\n };\n return Deflate;\n}());\nexport { Deflate };\n/**\n * Asynchronous streaming DEFLATE compression\n */\nvar AsyncDeflate = /*#__PURE__*/ (function () {\n function AsyncDeflate(opts, cb) {\n astrmify([\n bDflt,\n function () { return [astrm, Deflate]; }\n ], this, AsyncCmpStrm.call(this, opts, cb), function (ev) {\n var strm = new Deflate(ev.data);\n onmessage = astrm(strm);\n }, 6);\n }\n return AsyncDeflate;\n}());\nexport { AsyncDeflate };\nexport function deflate(data, opts, cb) {\n if (!cb)\n cb = opts, opts = {};\n if (typeof cb != 'function')\n throw 'no callback';\n return cbify(data, opts, [\n bDflt,\n ], function (ev) { return pbf(deflateSync(ev.data[0], ev.data[1])); }, 0, cb);\n}\n/**\n * Compresses data with DEFLATE without any wrapper\n * @param data The data to compress\n * @param opts The compression options\n * @returns The deflated version of the data\n */\nexport function deflateSync(data, opts) {\n if (opts === void 0) { opts = {}; }\n return dopt(data, opts, 0, 0);\n}\n/**\n * Streaming DEFLATE decompression\n */\nvar Inflate = /*#__PURE__*/ (function () {\n /**\n * Creates an inflation stream\n * @param cb The callback to call whenever data is inflated\n */\n function Inflate(cb) {\n this.s = {};\n this.p = new u8(0);\n this.ondata = cb;\n }\n Inflate.prototype.e = function (c) {\n if (this.d)\n throw 'stream finished';\n if (!this.ondata)\n throw 'no stream handler';\n var l = this.p.length;\n var n = new u8(l + c.length);\n n.set(this.p), n.set(c, l), this.p = n;\n };\n Inflate.prototype.c = function (final) {\n this.d = this.s.i = final || false;\n var bts = this.s.b;\n var dt = inflt(this.p, this.o, this.s);\n this.ondata(slc(dt, bts, this.s.b), this.d);\n this.o = slc(dt, this.s.b - 32768), this.s.b = this.o.length;\n this.p = slc(this.p, (this.s.p / 8) >> 0), this.s.p &= 7;\n };\n /**\n * Pushes a chunk to be inflated\n * @param chunk The chunk to push\n * @param final Whether this is the final chunk\n */\n Inflate.prototype.push = function (chunk, final) {\n this.e(chunk), this.c(final);\n };\n return Inflate;\n}());\nexport { Inflate };\n/**\n * Asynchronous streaming DEFLATE decompression\n */\nvar AsyncInflate = /*#__PURE__*/ (function () {\n /**\n * Creates an asynchronous inflation stream\n * @param cb The callback to call whenever data is deflated\n */\n function AsyncInflate(cb) {\n this.ondata = cb;\n astrmify([\n bInflt,\n function () { return [astrm, Inflate]; }\n ], this, 0, function () {\n var strm = new Inflate();\n onmessage = astrm(strm);\n }, 7);\n }\n return AsyncInflate;\n}());\nexport { AsyncInflate };\nexport function inflate(data, opts, cb) {\n if (!cb)\n cb = opts, opts = {};\n if (typeof cb != 'function')\n throw 'no callback';\n return cbify(data, opts, [\n bInflt\n ], function (ev) { return pbf(inflateSync(ev.data[0], gu8(ev.data[1]))); }, 1, cb);\n}\n/**\n * Expands DEFLATE data with no wrapper\n * @param data The data to decompress\n * @param out Where to write the data. Saves memory if you know the decompressed size and provide an output buffer of that length.\n * @returns The decompressed version of the data\n */\nexport function inflateSync(data, out) {\n return inflt(data, out);\n}\n// before you yell at me for not just using extends, my reason is that TS inheritance is hard to workerize.\n/**\n * Streaming GZIP compression\n */\nvar Gzip = /*#__PURE__*/ (function () {\n function Gzip(opts, cb) {\n this.c = crc();\n this.l = 0;\n this.v = 1;\n Deflate.call(this, opts, cb);\n }\n /**\n * Pushes a chunk to be GZIPped\n * @param chunk The chunk to push\n * @param final Whether this is the last chunk\n */\n Gzip.prototype.push = function (chunk, final) {\n Deflate.prototype.push.call(this, chunk, final);\n };\n Gzip.prototype.p = function (c, f) {\n this.c.p(c);\n this.l += c.length;\n var raw = dopt(c, this.o, this.v && gzhl(this.o), f && 8, !f);\n if (this.v)\n gzh(raw, this.o), this.v = 0;\n if (f)\n wbytes(raw, raw.length - 8, this.c.d()), wbytes(raw, raw.length - 4, this.l);\n this.ondata(raw, f);\n };\n return Gzip;\n}());\nexport { Gzip };\n/**\n * Asynchronous streaming GZIP compression\n */\nvar AsyncGzip = /*#__PURE__*/ (function () {\n function AsyncGzip(opts, cb) {\n astrmify([\n bDflt,\n gze,\n function () { return [astrm, Deflate, Gzip]; }\n ], this, AsyncCmpStrm.call(this, opts, cb), function (ev) {\n var strm = new Gzip(ev.data);\n onmessage = astrm(strm);\n }, 8);\n }\n return AsyncGzip;\n}());\nexport { AsyncGzip };\nexport function gzip(data, opts, cb) {\n if (!cb)\n cb = opts, opts = {};\n if (typeof cb != 'function')\n throw 'no callback';\n return cbify(data, opts, [\n bDflt,\n gze,\n function () { return [gzipSync]; }\n ], function (ev) { return pbf(gzipSync(ev.data[0], ev.data[1])); }, 2, cb);\n}\n/**\n * Compresses data with GZIP\n * @param data The data to compress\n * @param opts The compression options\n * @returns The gzipped version of the data\n */\nexport function gzipSync(data, opts) {\n if (opts === void 0) { opts = {}; }\n var c = crc(), l = data.length;\n c.p(data);\n var d = dopt(data, opts, gzhl(opts), 8), s = d.length;\n return gzh(d, opts), wbytes(d, s - 8, c.d()), wbytes(d, s - 4, l), d;\n}\n/**\n * Streaming GZIP decompression\n */\nvar Gunzip = /*#__PURE__*/ (function () {\n /**\n * Creates a GUNZIP stream\n * @param cb The callback to call whenever data is inflated\n */\n function Gunzip(cb) {\n this.v = 1;\n Inflate.call(this, cb);\n }\n /**\n * Pushes a chunk to be GUNZIPped\n * @param chunk The chunk to push\n * @param final Whether this is the last chunk\n */\n Gunzip.prototype.push = function (chunk, final) {\n Inflate.prototype.e.call(this, chunk);\n if (this.v) {\n var s = gzs(this.p);\n if (s >= this.p.length && !final)\n return;\n this.p = this.p.subarray(s), this.v = 0;\n }\n if (final) {\n if (this.p.length < 8)\n throw 'invalid gzip stream';\n this.p = this.p.subarray(0, -8);\n }\n // necessary to prevent TS from using the closure value\n // This allows for workerization to function correctly\n Inflate.prototype.c.call(this, final);\n };\n return Gunzip;\n}());\nexport { Gunzip };\n/**\n * Asynchronous streaming GZIP decompression\n */\nvar AsyncGunzip = /*#__PURE__*/ (function () {\n /**\n * Creates an asynchronous GUNZIP stream\n * @param cb The callback to call whenever data is deflated\n */\n function AsyncGunzip(cb) {\n this.ondata = cb;\n astrmify([\n bInflt,\n guze,\n function () { return [astrm, Inflate, Gunzip]; }\n ], this, 0, function () {\n var strm = new Gunzip();\n onmessage = astrm(strm);\n }, 9);\n }\n return AsyncGunzip;\n}());\nexport { AsyncGunzip };\nexport function gunzip(data, opts, cb) {\n if (!cb)\n cb = opts, opts = {};\n if (typeof cb != 'function')\n throw 'no callback';\n return cbify(data, opts, [\n bInflt,\n guze,\n function () { return [gunzipSync]; }\n ], function (ev) { return pbf(gunzipSync(ev.data[0])); }, 3, cb);\n}\n/**\n * Expands GZIP data\n * @param data The data to decompress\n * @param out Where to write the data. GZIP already encodes the output size, so providing this doesn't save memory.\n * @returns The decompressed version of the data\n */\nexport function gunzipSync(data, out) {\n return inflt(data.subarray(gzs(data), -8), out || new u8(gzl(data)));\n}\n/**\n * Streaming Zlib compression\n */\nvar Zlib = /*#__PURE__*/ (function () {\n function Zlib(opts, cb) {\n this.c = adler();\n this.v = 1;\n Deflate.call(this, opts, cb);\n }\n /**\n * Pushes a chunk to be zlibbed\n * @param chunk The chunk to push\n * @param final Whether this is the last chunk\n */\n Zlib.prototype.push = function (chunk, final) {\n Deflate.prototype.push.call(this, chunk, final);\n };\n Zlib.prototype.p = function (c, f) {\n this.c.p(c);\n var raw = dopt(c, this.o, this.v && 2, f && 4, !f);\n if (this.v)\n zlh(raw, this.o), this.v = 0;\n if (f)\n wbytes(raw, raw.length - 4, this.c.d());\n this.ondata(raw, f);\n };\n return Zlib;\n}());\nexport { Zlib };\n/**\n * Asynchronous streaming Zlib compression\n */\nvar AsyncZlib = /*#__PURE__*/ (function () {\n function AsyncZlib(opts, cb) {\n astrmify([\n bDflt,\n zle,\n function () { return [astrm, Deflate, Zlib]; }\n ], this, AsyncCmpStrm.call(this, opts, cb), function (ev) {\n var strm = new Zlib(ev.data);\n onmessage = astrm(strm);\n }, 10);\n }\n return AsyncZlib;\n}());\nexport { AsyncZlib };\nexport function zlib(data, opts, cb) {\n if (!cb)\n cb = opts, opts = {};\n if (typeof cb != 'function')\n throw 'no callback';\n return cbify(data, opts, [\n bDflt,\n zle,\n function () { return [zlibSync]; }\n ], function (ev) { return pbf(zlibSync(ev.data[0], ev.data[1])); }, 4, cb);\n}\n/**\n * Compress data with Zlib\n * @param data The data to compress\n * @param opts The compression options\n * @returns The zlib-compressed version of the data\n */\nexport function zlibSync(data, opts) {\n if (opts === void 0) { opts = {}; }\n var a = adler();\n a.p(data);\n var d = dopt(data, opts, 2, 4);\n return zlh(d, opts), wbytes(d, d.length - 4, a.d()), d;\n}\n/**\n * Streaming Zlib decompression\n */\nvar Unzlib = /*#__PURE__*/ (function () {\n /**\n * Creates a Zlib decompression stream\n * @param cb The callback to call whenever data is inflated\n */\n function Unzlib(cb) {\n this.v = 1;\n Inflate.call(this, cb);\n }\n /**\n * Pushes a chunk to be unzlibbed\n * @param chunk The chunk to push\n * @param final Whether this is the last chunk\n */\n Unzlib.prototype.push = function (chunk, final) {\n Inflate.prototype.e.call(this, chunk);\n if (this.v) {\n if (this.p.length < 2 && !final)\n return;\n this.p = this.p.subarray(2), this.v = 0;\n }\n if (final) {\n if (this.p.length < 4)\n throw 'invalid zlib stream';\n this.p = this.p.subarray(0, -4);\n }\n // necessary to prevent TS from using the closure value\n // This allows for workerization to function correctly\n Inflate.prototype.c.call(this, final);\n };\n return Unzlib;\n}());\nexport { Unzlib };\n/**\n * Asynchronous streaming Zlib decompression\n */\nvar AsyncUnzlib = /*#__PURE__*/ (function () {\n /**\n * Creates an asynchronous Zlib decompression stream\n * @param cb The callback to call whenever data is deflated\n */\n function AsyncUnzlib(cb) {\n this.ondata = cb;\n astrmify([\n bInflt,\n zule,\n function () { return [astrm, Inflate, Unzlib]; }\n ], this, 0, function () {\n var strm = new Unzlib();\n onmessage = astrm(strm);\n }, 11);\n }\n return AsyncUnzlib;\n}());\nexport { AsyncUnzlib };\nexport function unzlib(data, opts, cb) {\n if (!cb)\n cb = opts, opts = {};\n if (typeof cb != 'function')\n throw 'no callback';\n return cbify(data, opts, [\n bInflt,\n zule,\n function () { return [unzlibSync]; }\n ], function (ev) { return pbf(unzlibSync(ev.data[0], gu8(ev.data[1]))); }, 5, cb);\n}\n/**\n * Expands Zlib data\n * @param data The data to decompress\n * @param out Where to write the data. Saves memory if you know the decompressed size and provide an output buffer of that length.\n * @returns The decompressed version of the data\n */\nexport function unzlibSync(data, out) {\n return inflt((zlv(data), data.subarray(2, -4)), out);\n}\n// Default algorithm for compression (used because having a known output size allows faster decompression)\nexport { gzip as compress, AsyncGzip as AsyncCompress };\n// Default algorithm for compression (used because having a known output size allows faster decompression)\nexport { gzipSync as compressSync, Gzip as Compress };\n/**\n * Streaming GZIP, Zlib, or raw DEFLATE decompression\n */\nvar Decompress = /*#__PURE__*/ (function () {\n /**\n * Creates a decompression stream\n * @param cb The callback to call whenever data is decompressed\n */\n function Decompress(cb) {\n this.G = Gunzip;\n this.I = Inflate;\n this.Z = Unzlib;\n this.ondata = cb;\n }\n /**\n * Pushes a chunk to be decompressed\n * @param chunk The chunk to push\n * @param final Whether this is the last chunk\n */\n Decompress.prototype.push = function (chunk, final) {\n if (!this.ondata)\n throw 'no stream handler';\n if (!this.s) {\n if (this.p && this.p.length) {\n var n = new u8(this.p.length + chunk.length);\n n.set(this.p), n.set(chunk, this.p.length);\n }\n else\n this.p = chunk;\n if (this.p.length > 2) {\n var _this_1 = this;\n var cb = function () { _this_1.ondata.apply(_this_1, arguments); };\n this.s = (this.p[0] == 31 && this.p[1] == 139 && this.p[2] == 8)\n ? new this.G(cb)\n : ((this.p[0] & 15) != 8 || (this.p[0] >> 4) > 7 || ((this.p[0] << 8 | this.p[1]) % 31))\n ? new this.I(cb)\n : new this.Z(cb);\n this.s.push(this.p, final);\n this.p = null;\n }\n }\n else\n this.s.push(chunk, final);\n };\n return Decompress;\n}());\nexport { Decompress };\n/**\n * Asynchronous streaming GZIP, Zlib, or raw DEFLATE decompression\n */\nvar AsyncDecompress = /*#__PURE__*/ (function () {\n /**\n * Creates an asynchronous decompression stream\n * @param cb The callback to call whenever data is decompressed\n */\n function AsyncDecompress(cb) {\n this.G = AsyncGunzip;\n this.I = AsyncInflate;\n this.Z = AsyncUnzlib;\n this.ondata = cb;\n }\n /**\n * Pushes a chunk to be decompressed\n * @param chunk The chunk to push\n * @param final Whether this is the last chunk\n */\n AsyncDecompress.prototype.push = function (chunk, final) {\n Decompress.prototype.push.call(this, chunk, final);\n };\n return AsyncDecompress;\n}());\nexport { AsyncDecompress };\nexport function decompress(data, opts, cb) {\n if (!cb)\n cb = opts, opts = {};\n if (typeof cb != 'function')\n throw 'no callback';\n return (data[0] == 31 && data[1] == 139 && data[2] == 8)\n ? gunzip(data, opts, cb)\n : ((data[0] & 15) != 8 || (data[0] >> 4) > 7 || ((data[0] << 8 | data[1]) % 31))\n ? inflate(data, opts, cb)\n : unzlib(data, opts, cb);\n}\n/**\n * Expands compressed GZIP, Zlib, or raw DEFLATE data, automatically detecting the format\n * @param data The data to decompress\n * @param out Where to write the data. Saves memory if you know the decompressed size and provide an output buffer of that length.\n * @returns The decompressed version of the data\n */\nexport function decompressSync(data, out) {\n return (data[0] == 31 && data[1] == 139 && data[2] == 8)\n ? gunzipSync(data, out)\n : ((data[0] & 15) != 8 || (data[0] >> 4) > 7 || ((data[0] << 8 | data[1]) % 31))\n ? inflateSync(data, out)\n : unzlibSync(data, out);\n}\n// flatten a directory structure\nvar fltn = function (d, p, t, o) {\n for (var k in d) {\n var val = d[k], n = p + k;\n if (val instanceof u8)\n t[n] = [val, o];\n else if (Array.isArray(val))\n t[n] = [val[0], mrg(o, val[1])];\n else\n fltn(val, n + '/', t, o);\n }\n};\n/**\n * Converts a string into a Uint8Array for use with compression/decompression methods\n * @param str The string to encode\n * @param latin1 Whether or not to interpret the data as Latin-1. This should\n * not need to be true unless decoding a binary string.\n * @returns The string encoded in UTF-8/Latin-1 binary\n */\nexport function strToU8(str, latin1) {\n var l = str.length;\n if (!latin1 && typeof TextEncoder != 'undefined')\n return new TextEncoder().encode(str);\n var ar = new u8(str.length + (str.length >>> 1));\n var ai = 0;\n var w = function (v) { ar[ai++] = v; };\n for (var i = 0; i < l; ++i) {\n if (ai + 5 > ar.length) {\n var n = new u8(ai + 8 + ((l - i) << 1));\n n.set(ar);\n ar = n;\n }\n var c = str.charCodeAt(i);\n if (c < 128 || latin1)\n w(c);\n else if (c < 2048)\n w(192 | (c >>> 6)), w(128 | (c & 63));\n else if (c > 55295 && c < 57344)\n c = 65536 + (c & 1023 << 10) | (str.charCodeAt(++i) & 1023),\n w(240 | (c >>> 18)), w(128 | ((c >>> 12) & 63)), w(128 | ((c >>> 6) & 63)), w(128 | (c & 63));\n else\n w(224 | (c >>> 12)), w(128 | ((c >>> 6) & 63)), w(128 | (c & 63));\n }\n return slc(ar, 0, ai);\n}\n/**\n * Converts a Uint8Array to a string\n * @param dat The data to decode to string\n * @param latin1 Whether or not to interpret the data as Latin-1. This should\n * not need to be true unless encoding to binary string.\n * @returns The original UTF-8/Latin-1 string\n */\nexport function strFromU8(dat, latin1) {\n var r = '';\n if (!latin1 && typeof TextDecoder != 'undefined')\n return new TextDecoder().decode(dat);\n for (var i = 0; i < dat.length;) {\n var c = dat[i++];\n if (c < 128 || latin1)\n r += String.fromCharCode(c);\n else if (c < 224)\n r += String.fromCharCode((c & 31) << 6 | (dat[i++] & 63));\n else if (c < 240)\n r += String.fromCharCode((c & 15) << 12 | (dat[i++] & 63) << 6 | (dat[i++] & 63));\n else\n c = ((c & 15) << 18 | (dat[i++] & 63) << 12 | (dat[i++] & 63) << 6 | (dat[i++] & 63)) - 65536,\n r += String.fromCharCode(55296 | (c >> 10), 56320 | (c & 1023));\n }\n return r;\n}\n;\n// skip local zip header\nvar slzh = function (d, b) { return b + 30 + b2(d, b + 26) + b2(d, b + 28); };\n// read zip header\nvar zh = function (d, b, z) {\n var fnl = b2(d, b + 28), fn = strFromU8(d.subarray(b + 46, b + 46 + fnl), !(b2(d, b + 8) & 2048)), es = b + 46 + fnl;\n var _a = z ? z64e(d, es) : [b4(d, b + 20), b4(d, b + 24), b4(d, b + 42)], sc = _a[0], su = _a[1], off = _a[2];\n return [b2(d, b + 10), sc, su, fn, es + b2(d, b + 30) + b2(d, b + 32), off];\n};\n// read zip64 extra field\nvar z64e = function (d, b) {\n for (; b2(d, b) != 1; b += 4 + b2(d, b + 2))\n ;\n return [b4(d, b + 12), b4(d, b + 4), b4(d, b + 20)];\n};\n// write zip header\nvar wzh = function (d, b, c, cmp, su, fn, u, o, ce, t) {\n var fl = fn.length, l = cmp.length;\n wbytes(d, b, ce != null ? 0x2014B50 : 0x4034B50), b += 4;\n if (ce != null)\n d[b] = 20, b += 2;\n d[b] = 20, b += 2; // spec compliance? what's that?\n d[b++] = (t == 8 && (o.level == 1 ? 6 : o.level < 6 ? 4 : o.level == 9 ? 2 : 0)), d[b++] = u && 8;\n d[b] = t, b += 2;\n var dt = new Date(o.mtime || Date.now()), y = dt.getFullYear() - 1980;\n if (y < 0 || y > 119)\n throw 'date not in range 1980-2099';\n wbytes(d, b, ((y << 24) * 2) | ((dt.getMonth() + 1) << 21) | (dt.getDate() << 16) | (dt.getHours() << 11) | (dt.getMinutes() << 5) | (dt.getSeconds() >>> 1));\n b += 4;\n wbytes(d, b, c);\n wbytes(d, b + 4, l);\n wbytes(d, b + 8, su);\n wbytes(d, b + 12, fl), b += 16; // skip extra field, comment\n if (ce != null)\n wbytes(d, b += 10, ce), b += 4;\n d.set(fn, b);\n b += fl;\n if (ce == null)\n d.set(cmp, b);\n};\n// write zip footer (end of central directory)\nvar wzf = function (o, b, c, d, e) {\n wbytes(o, b, 0x6054B50); // skip disk\n wbytes(o, b + 8, c);\n wbytes(o, b + 10, c);\n wbytes(o, b + 12, d);\n wbytes(o, b + 16, e);\n};\nexport function zip(data, opts, cb) {\n if (!cb)\n cb = opts, opts = {};\n if (typeof cb != 'function')\n throw 'no callback';\n var r = {};\n fltn(data, '', r, opts);\n var k = Object.keys(r);\n var lft = k.length, o = 0, tot = 0;\n var slft = lft, files = new Array(lft);\n var term = [];\n var tAll = function () {\n for (var i = 0; i < term.length; ++i)\n term[i]();\n };\n var cbf = function () {\n var out = new u8(tot + 22), oe = o, cdl = tot - o;\n tot = 0;\n for (var i = 0; i < slft; ++i) {\n var f = files[i];\n try {\n wzh(out, tot, f.c, f.d, f.m, f.n, f.u, f.p, null, f.t);\n wzh(out, o, f.c, f.d, f.m, f.n, f.u, f.p, tot, f.t), o += 46 + f.n.length, tot += 30 + f.n.length + f.d.length;\n }\n catch (e) {\n return cb(e, null);\n }\n }\n wzf(out, o, files.length, cdl, oe);\n cb(null, out);\n };\n if (!lft)\n cbf();\n var _loop_1 = function (i) {\n var fn = k[i];\n var _a = r[fn], file = _a[0], p = _a[1];\n var c = crc(), m = file.length;\n c.p(file);\n var n = strToU8(fn), s = n.length;\n var t = p.level == 0 ? 0 : 8;\n var cbl = function (e, d) {\n if (e) {\n tAll();\n cb(e, null);\n }\n else {\n var l = d.length;\n files[i] = {\n t: t,\n d: d,\n m: m,\n c: c.d(),\n u: fn.length != l,\n n: n,\n p: p\n };\n o += 30 + s + l;\n tot += 76 + 2 * s + l;\n if (!--lft)\n cbf();\n }\n };\n if (n.length > 65535)\n cbl('filename too long', null);\n if (!t)\n cbl(null, file);\n else if (m < 160000) {\n try {\n cbl(null, deflateSync(file, p));\n }\n catch (e) {\n cbl(e, null);\n }\n }\n else\n term.push(deflate(file, p, cbl));\n };\n // Cannot use lft because it can decrease\n for (var i = 0; i < slft; ++i) {\n _loop_1(i);\n }\n return tAll;\n}\n/**\n * Synchronously creates a ZIP file. Prefer using `zip` for better performance\n * with more than one file.\n * @param data The directory structure for the ZIP archive\n * @param opts The main options, merged with per-file options\n * @returns The generated ZIP archive\n */\nexport function zipSync(data, opts) {\n if (opts === void 0) { opts = {}; }\n var r = {};\n var files = [];\n fltn(data, '', r, opts);\n var o = 0;\n var tot = 0;\n for (var fn in r) {\n var _a = r[fn], file = _a[0], p = _a[1];\n var t = p.level == 0 ? 0 : 8;\n var n = strToU8(fn), s = n.length;\n if (n.length > 65535)\n throw 'filename too long';\n var d = t ? deflateSync(file, p) : file, l = d.length;\n var c = crc();\n c.p(file);\n files.push({\n t: t,\n d: d,\n m: file.length,\n c: c.d(),\n u: fn.length != s,\n n: n,\n o: o,\n p: p\n });\n o += 30 + s + l;\n tot += 76 + 2 * s + l;\n }\n var out = new u8(tot + 22), oe = o, cdl = tot - o;\n for (var i = 0; i < files.length; ++i) {\n var f = files[i];\n wzh(out, f.o, f.c, f.d, f.m, f.n, f.u, f.p, null, f.t);\n wzh(out, o, f.c, f.d, f.m, f.n, f.u, f.p, f.o, f.t), o += 46 + f.n.length;\n }\n wzf(out, o, files.length, cdl, oe);\n return out;\n}\n/**\n * Asynchronously decompresses a ZIP archive\n * @param data The raw compressed ZIP file\n * @param cb The callback to call with the decompressed files\n * @returns A function that can be used to immediately terminate the unzipping\n */\nexport function unzip(data, cb) {\n if (typeof cb != 'function')\n throw 'no callback';\n var term = [];\n var tAll = function () {\n for (var i = 0; i < term.length; ++i)\n term[i]();\n };\n var files = {};\n var e = data.length - 22;\n for (; b4(data, e) != 0x6054B50; --e) {\n if (!e || data.length - e > 65558) {\n cb('invalid zip file', null);\n return;\n }\n }\n ;\n var lft = b2(data, e + 8);\n if (!lft)\n cb(null, {});\n var c = lft;\n var o = b4(data, e + 16);\n var z = o == 4294967295;\n if (z) {\n e = b4(data, e - 12);\n if (b4(data, e) != 0x6064B50)\n throw 'invalid zip file';\n c = lft = b4(data, e + 32);\n o = b4(data, e + 48);\n }\n var _loop_2 = function (i) {\n var _a = zh(data, o, z), c_1 = _a[0], sc = _a[1], su = _a[2], fn = _a[3], no = _a[4], off = _a[5], b = slzh(data, off);\n o = no;\n var cbl = function (e, d) {\n if (e) {\n tAll();\n cb(e, null);\n }\n else {\n files[fn] = d;\n if (!--lft)\n cb(null, files);\n }\n };\n if (!c_1)\n cbl(null, slc(data, b, b + sc));\n else if (c_1 == 8) {\n var infl = data.subarray(b, b + sc);\n if (sc < 320000) {\n try {\n cbl(null, inflateSync(infl, new u8(su)));\n }\n catch (e) {\n cbl(e, null);\n }\n }\n else\n term.push(inflate(infl, { size: su }, cbl));\n }\n else\n cbl('unknown compression type ' + c_1, null);\n };\n for (var i = 0; i < c; ++i) {\n _loop_2(i);\n }\n return tAll;\n}\n/**\n * Synchronously decompresses a ZIP archive. Prefer using `unzip` for better\n * performance with more than one file.\n * @param data The raw compressed ZIP file\n * @returns The decompressed files\n */\nexport function unzipSync(data) {\n var files = {};\n var e = data.length - 22;\n for (; b4(data, e) != 0x6054B50; --e) {\n if (!e || data.length - e > 65558)\n throw 'invalid zip file';\n }\n ;\n var c = b2(data, e + 8);\n if (!c)\n return {};\n var o = b4(data, e + 16);\n var z = o == 4294967295;\n if (z) {\n e = b4(data, e - 12);\n if (b4(data, e) != 0x6064B50)\n throw 'invalid zip file';\n c = b4(data, e + 32);\n o = b4(data, e + 48);\n }\n for (var i = 0; i < c; ++i) {\n var _a = zh(data, o, z), c_2 = _a[0], sc = _a[1], su = _a[2], fn = _a[3], no = _a[4], off = _a[5], b = slzh(data, off);\n o = no;\n if (!c_2)\n files[fn] = slc(data, b, b + sc);\n else if (c_2 == 8)\n files[fn] = inflateSync(data.subarray(b, b + sc), new u8(su));\n else\n throw 'unknown compression type ' + c_2;\n }\n return files;\n}\n","import { V2ReplayPayloadAdmissionError } from './errors'\n\nconst ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'\nconst CANONICAL_PATTERN = /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/\nconst decodeTable = new Int16Array(128).fill(-1)\nfor (let index = 0; index < ALPHABET.length; index += 1) {\n decodeTable[ALPHABET.charCodeAt(index)] = index\n}\n\n/** RFC 4648 standard alphabet with required padding. */\nexport const encodeBase64 = (bytes: Uint8Array): string => {\n let output = ''\n let index = 0\n for (; index + 2 < bytes.length; index += 3) {\n const triple = (bytes[index] << 16) | (bytes[index + 1] << 8) | bytes[index + 2]\n output +=\n ALPHABET[triple >> 18] +\n ALPHABET[(triple >> 12) & 63] +\n ALPHABET[(triple >> 6) & 63] +\n ALPHABET[triple & 63]\n }\n const remaining = bytes.length - index\n if (remaining === 1) {\n const value = bytes[index] << 16\n output += ALPHABET[value >> 18] + ALPHABET[(value >> 12) & 63] + '=='\n } else if (remaining === 2) {\n const value = (bytes[index] << 16) | (bytes[index + 1] << 8)\n output += ALPHABET[value >> 18] + ALPHABET[(value >> 12) & 63] + ALPHABET[(value >> 6) & 63] + '='\n }\n return output\n}\n\n/**\n * Strict decoder: only the standard alphabet, padding exactly where required, and a decoded value whose\n * canonical re-encoding reproduces the input byte for byte.\n */\nexport const decodeCanonicalBase64 = (value: string): Uint8Array => {\n if (typeof value !== 'string' || value.length === 0 || /[^A-Za-z0-9+/=]/.test(value)) {\n throw new V2ReplayPayloadAdmissionError('invalid-base64', 'payload is not standard base64')\n }\n if (!CANONICAL_PATTERN.test(value)) {\n throw new V2ReplayPayloadAdmissionError('noncanonical-base64', 'payload base64 padding is not canonical')\n }\n const padding = value.endsWith('==') ? 2 : value.endsWith('=') ? 1 : 0\n const output = new Uint8Array((value.length / 4) * 3 - padding)\n let offset = 0\n for (let index = 0; index < value.length; index += 4) {\n const first = decodeTable[value.charCodeAt(index)]\n const second = decodeTable[value.charCodeAt(index + 1)]\n const third = decodeTable[value.charCodeAt(index + 2)]\n const fourth = decodeTable[value.charCodeAt(index + 3)]\n const quad = (first << 18) | (second << 12) | ((third < 0 ? 0 : third) << 6) | (fourth < 0 ? 0 : fourth)\n output[offset++] = quad >> 16\n if (third >= 0) output[offset++] = (quad >> 8) & 0xff\n if (fourth >= 0) output[offset++] = quad & 0xff\n }\n if (encodeBase64(output) !== value) {\n throw new V2ReplayPayloadAdmissionError('noncanonical-base64', 'payload base64 has non-zero padding bits')\n }\n return output\n}\n","import { isArrayValue, isFunctionValue } from '../validation'\nimport { canonicalV2ReplayRecords, V2_REPLAY_PAYLOAD_LIMITS } from './canonical-payload-json'\nimport { isV2Sha256Hash } from './digest'\nimport { V2MaskingProofError } from './errors'\nimport { buildV2MaskingProfile } from './masking-profile'\nimport type { V2MaskingProfile, V2ReplayPayloadLimits, V2Sha256Hash } from './types'\n\n/** Applies the effective masking profile to one raw recorder event and returns the masked event. */\nexport type V2ReplayEventMasker = (event: unknown, profile: V2MaskingProfile) => unknown\n\nexport interface V2MaskingStageInput {\n readonly profile: V2MaskingProfile\n readonly profileHash: V2Sha256Hash\n readonly events: readonly unknown[]\n readonly limits?: V2ReplayPayloadLimits\n}\n\nconst SEAL = Symbol('elu-replay-masking-seal')\n\n/**\n * The sealed output of the masking stage and the only value the payload codec serializes. Masking\n * runs inside the stage, the masked records are canonicalized here, and the resulting text is what\n * gets compressed; nothing that bypassed the stage can reach compression, persistence, or transport.\n */\nexport class V2MaskingProof {\n readonly profile: V2MaskingProfile\n readonly profileHash: V2Sha256Hash\n readonly canonicalPayload: string\n readonly payloadByteLength: number\n readonly logicalRecords: number\n readonly nestingDepth: number\n\n private constructor(\n seal: symbol,\n profile: V2MaskingProfile,\n profileHash: V2Sha256Hash,\n canonicalPayload: string,\n payloadByteLength: number,\n logicalRecords: number,\n nestingDepth: number\n ) {\n if (seal !== SEAL) throw new V2MaskingProofError('masking proofs are sealed by the masking stage only')\n this.profile = profile\n this.profileHash = profileHash\n this.canonicalPayload = canonicalPayload\n this.payloadByteLength = payloadByteLength\n this.logicalRecords = logicalRecords\n this.nestingDepth = nestingDepth\n Object.freeze(this)\n }\n\n /** Runs the masker over every raw event in order and seals the masked, canonicalized result. */\n static seal(masker: V2ReplayEventMasker, input: V2MaskingStageInput): V2MaskingProof {\n if (!isFunctionValue(masker)) throw new V2MaskingProofError('masking stage requires a masker')\n if (!isArrayValue(input.events)) throw new V2MaskingProofError('masking stage requires an event array')\n const profile = buildV2MaskingProfile(input.profile)\n if (!isV2Sha256Hash(input.profileHash)) {\n throw new V2MaskingProofError('masking stage requires the sha256 profile hash')\n }\n const masked = input.events.map((event) => masker(event, profile))\n const canonical = canonicalV2ReplayRecords(\n masked,\n 'masked replay records',\n input.limits ?? V2_REPLAY_PAYLOAD_LIMITS\n )\n return new V2MaskingProof(\n SEAL,\n profile,\n input.profileHash,\n canonical.canonical,\n canonical.bytes.length,\n canonical.logicalRecords,\n canonical.nestingDepth\n )\n }\n}\n\nexport const isV2MaskingProof = (value: unknown): value is V2MaskingProof => value instanceof V2MaskingProof\n","import { gzipSync, Inflate } from 'fflate'\nimport { decodeCanonicalBase64, encodeBase64 } from './base64'\nimport { admitV2CanonicalPayloadText, V2_REPLAY_PAYLOAD_LIMITS } from './canonical-payload-json'\nimport { utf8Encode } from './digest'\nimport { V2ReplayPayloadAdmissionError } from './errors'\nimport { isV2MaskingProof, V2MaskingProof } from './masking-proof'\nimport type { V2ReplayCodec, V2ReplayCompression, V2ReplayContentEncoding, V2ReplayPayloadLimits } from './types'\n\n/**\n * elu-browser-dom-v1: the canonical JSON array of masked DOM recording events, gzip-compressed exactly\n * once, carried as base64. The outer envelope describes the inner payload only; HTTP transfer stays\n * identity-encoded.\n */\nexport const V2_BROWSER_DOM_CODEC: V2ReplayCodec = 'elu-browser-dom-v1'\nexport const V2_BROWSER_DOM_COMPRESSION: V2ReplayCompression = 'gzip'\nexport const V2_REPLAY_CONTENT_ENCODING: V2ReplayContentEncoding = 'base64'\n\nconst GZIP_MAGIC_FIRST = 0x1f\nconst GZIP_MAGIC_SECOND = 0x8b\nconst GZIP_DEFLATE_METHOD = 8\nconst GZIP_FIXED_HEADER_BYTES = 10\nconst GZIP_TRAILER_BYTES = 8\nconst GZIP_MINIMUM_BYTES = GZIP_FIXED_HEADER_BYTES + GZIP_TRAILER_BYTES\nconst GZIP_FLAG_HEADER_CRC = 0x02\nconst GZIP_FLAG_EXTRA = 0x04\nconst GZIP_FLAG_NAME = 0x08\nconst GZIP_FLAG_COMMENT = 0x10\nconst GZIP_RESERVED_FLAGS = 0xe0\n\nexport interface V2EncodedReplayPayload {\n readonly codec: V2ReplayCodec\n readonly compression: V2ReplayCompression\n readonly contentEncoding: V2ReplayContentEncoding\n readonly payload: string\n readonly compressedByteLength: number\n readonly decodedByteLength: number\n readonly logicalRecords: number\n readonly proof: V2MaskingProof\n}\n\nexport interface V2AdmittedReplayPayload {\n readonly decoded: Uint8Array\n readonly decodedByteLength: number\n readonly logicalRecords: number\n readonly nestingDepth: number\n readonly records: readonly unknown[]\n}\n\nfunction fail(code: V2ReplayPayloadAdmissionError['code'], message: string): never {\n throw new V2ReplayPayloadAdmissionError(code, message)\n}\n\n/** Serializes a sealed masking proof: compress once, then base64. Nothing else is accepted. */\nexport const encodeV2BrowserDomPayload = (proof: V2MaskingProof): V2EncodedReplayPayload => {\n if (!isV2MaskingProof(proof)) {\n throw new V2ReplayPayloadAdmissionError(\n 'invalid-codec-shape',\n 'payload serialization requires a sealed masking proof'\n )\n }\n const decoded = utf8Encode(proof.canonicalPayload)\n let compressed: Uint8Array\n try {\n // A zero mtime keeps the member header free of capture-time metadata.\n compressed = gzipSync(decoded, { mtime: 0 })\n } catch {\n return fail('invalid-gzip', 'payload compression failed')\n }\n return Object.freeze({\n codec: V2_BROWSER_DOM_CODEC,\n compression: V2_BROWSER_DOM_COMPRESSION,\n contentEncoding: V2_REPLAY_CONTENT_ENCODING,\n payload: encodeBase64(compressed),\n compressedByteLength: compressed.length,\n decodedByteLength: decoded.length,\n logicalRecords: proof.logicalRecords,\n proof,\n })\n}\n\nconst CRC_TABLE = (() => {\n const table = new Int32Array(256)\n for (let index = 0; index < 256; index += 1) {\n let value = index\n for (let bit = 0; bit < 8; bit += 1) {\n value = value & 1 ? (value >>> 1) ^ 0xedb88320 : value >>> 1\n }\n table[index] = value\n }\n return table\n})()\n\nconst crc32 = (chunks: readonly Uint8Array[]): number => {\n let crc = -1\n for (const chunk of chunks) {\n for (let index = 0; index < chunk.length; index += 1) {\n crc = CRC_TABLE[(crc ^ chunk[index]) & 0xff] ^ (crc >>> 8)\n }\n }\n return (crc ^ -1) >>> 0\n}\n\nconst readUint32LittleEndian = (bytes: Uint8Array, offset: number): number =>\n (bytes[offset] | (bytes[offset + 1] << 8) | (bytes[offset + 2] << 16) | (bytes[offset + 3] << 24)) >>> 0\n\nconst gzipHeaderLength = (payload: Uint8Array): number => {\n if (\n payload.length < GZIP_MINIMUM_BYTES ||\n payload[0] !== GZIP_MAGIC_FIRST ||\n payload[1] !== GZIP_MAGIC_SECOND ||\n payload[2] !== GZIP_DEFLATE_METHOD\n ) {\n fail('invalid-gzip', 'payload is not a gzip member')\n }\n const flags = payload[3]\n if ((flags & GZIP_RESERVED_FLAGS) !== 0) fail('invalid-gzip', 'gzip header uses reserved flags')\n let offset = GZIP_FIXED_HEADER_BYTES\n if ((flags & GZIP_FLAG_EXTRA) !== 0) {\n if (offset + 2 > payload.length) fail('invalid-gzip', 'gzip extra field is truncated')\n offset += 2 + (payload[offset] | (payload[offset + 1] << 8))\n if (offset > payload.length) fail('invalid-gzip', 'gzip extra field is truncated')\n }\n for (const flag of [GZIP_FLAG_NAME, GZIP_FLAG_COMMENT]) {\n if ((flags & flag) === 0) continue\n while (offset < payload.length && payload[offset] !== 0) offset += 1\n if (offset >= payload.length) fail('invalid-gzip', 'gzip header string is unterminated')\n offset += 1\n }\n if ((flags & GZIP_FLAG_HEADER_CRC) !== 0) offset += 2\n if (offset + GZIP_TRAILER_BYTES > payload.length) fail('invalid-gzip', 'gzip member is truncated')\n return offset\n}\n\n/** The inflater's post-completion state: unconsumed input bytes and the bit offset into the first of them. */\ninterface InflateProgress {\n readonly p: Uint8Array\n readonly s: { readonly p?: number }\n}\n\n/**\n * Input slice for the counting pass below. The inflater emits what each slice\n * decodes to before it accepts the next one, so a member that would expand past\n * the decoded-byte ceiling is refused after at most one slice's worth of\n * expansion instead of after the whole member has been materialized.\n */\nconst INFLATE_GUARD_SLICE_BYTES = 4096\n\n/**\n * Refuse a member whose decoded size would exceed the ceiling without holding\n * the decoded bytes. The pass only counts: every slice is pushed as non-final,\n * so a malformed member or trailing data is left for the strict pass to\n * classify, and only the decoded-byte ceiling is reported from here. The\n * inflater may defer a block whose header straddles a slice boundary, so the\n * count can trail the true size by a few hundred kilobytes; the strict pass\n * still applies the exact ceiling to what it decodes.\n */\nconst refuseOversizedMember = (body: Uint8Array, maximumDecodedBytes: number): void => {\n let counted = 0\n const guard = new Inflate((chunk) => {\n counted += chunk.length\n if (counted > maximumDecodedBytes) {\n fail('decoded-byte-limit', `decoded payload exceeds ${maximumDecodedBytes} bytes`)\n }\n })\n try {\n for (let offset = 0; offset < body.length; offset += INFLATE_GUARD_SLICE_BYTES) {\n guard.push(body.subarray(offset, Math.min(offset + INFLATE_GUARD_SLICE_BYTES, body.length)), false)\n }\n } catch (error) {\n if (error instanceof V2ReplayPayloadAdmissionError) throw error\n }\n}\n\nconst inflateSingleMember = (payload: Uint8Array, headerLength: number, maximumDecodedBytes: number): Uint8Array => {\n const body = payload.subarray(headerLength, payload.length - GZIP_TRAILER_BYTES)\n refuseOversizedMember(body, maximumDecodedBytes)\n const chunks: Uint8Array[] = []\n let produced = 0\n const inflater = new Inflate((chunk) => {\n produced += chunk.length\n if (produced > maximumDecodedBytes) {\n fail('decoded-byte-limit', `decoded payload exceeds ${maximumDecodedBytes} bytes`)\n }\n chunks.push(chunk)\n })\n try {\n inflater.push(body, true)\n } catch (error) {\n if (error instanceof V2ReplayPayloadAdmissionError) throw error\n return fail('invalid-gzip', 'gzip member does not inflate')\n }\n\n const progress = inflater as unknown as InflateProgress\n const remaining = progress.p\n const bitOffset = progress.s?.p\n if (!ArrayBuffer.isView(remaining) || typeof bitOffset !== 'number' || remaining.length > body.length) {\n return fail('invalid-gzip', 'gzip member end position is unavailable')\n }\n const consumed = body.length - remaining.length + ((bitOffset & 7) !== 0 ? 1 : 0)\n const trailerOffset = headerLength + consumed\n if (trailerOffset + GZIP_TRAILER_BYTES > payload.length) fail('invalid-gzip', 'gzip trailer is truncated')\n if (readUint32LittleEndian(payload, trailerOffset) !== crc32(chunks)) {\n fail('invalid-gzip', 'gzip CRC-32 does not match the decoded bytes')\n }\n if (readUint32LittleEndian(payload, trailerOffset + 4) !== produced % 0x1_0000_0000) {\n fail('invalid-gzip', 'gzip ISIZE does not match the decoded length')\n }\n if (trailerOffset + GZIP_TRAILER_BYTES !== payload.length) {\n fail('trailing-gzip-data', 'payload carries bytes after the single gzip member')\n }\n\n const decoded = new Uint8Array(produced)\n let offset = 0\n for (const chunk of chunks) {\n decoded.set(chunk, offset)\n offset += chunk.length\n }\n return decoded\n}\n\n/**\n * Admits one base64 payload exactly as the engine does, in this order: strict canonical base64, a\n * single gzip member with the decoded-byte ceiling, no nested compression, strict canonical JSON\n * within the nesting ceiling, and the logical-record ceiling. Any failure is permanent.\n */\nexport const admitV2BrowserDomPayload = (\n payload: string,\n limits: V2ReplayPayloadLimits = V2_REPLAY_PAYLOAD_LIMITS\n): V2AdmittedReplayPayload => {\n const compressed = decodeCanonicalBase64(payload)\n const decoded = inflateSingleMember(compressed, gzipHeaderLength(compressed), limits.maximumReplayDecodedBytes)\n if (decoded.length >= 2 && decoded[0] === GZIP_MAGIC_FIRST && decoded[1] === GZIP_MAGIC_SECOND) {\n fail('nested-compression', 'decoded payload is itself gzip-compressed')\n }\n let text: string\n try {\n text = new TextDecoder('utf-8', { fatal: true, ignoreBOM: true }).decode(decoded)\n } catch {\n return fail('invalid-unicode', 'decoded payload is not UTF-8')\n }\n const admitted = admitV2CanonicalPayloadText(text, limits)\n return Object.freeze({\n decoded,\n decodedByteLength: decoded.length,\n logicalRecords: admitted.logicalRecords,\n nestingDepth: admitted.nestingDepth,\n records: admitted.records,\n })\n}\n","import { V2_REPLAY_REQUEST_ID_PATTERN } from './storage-constants'\nimport { compareV1ExactTimestamps, parseV1ExactTimestamp } from '../exact-timestamp'\nimport {\n freezeV1Value,\n hasOnlyKeys,\n hasOwn,\n isBooleanValue,\n isNonNegativeInteger,\n isNullValue,\n isRecordValue,\n isStringValue,\n unicodeCodePointLength,\n} from '../validation'\nimport { canonicalV2JsonValue } from './canonical-payload-json'\nimport type { V2EncodedReplayPayload } from './codec'\nimport { isV2Sha256Hash, sha256Hex, utf8Encode } from './digest'\nimport { V2ReplayRequestError } from './errors'\nimport { isV2MaskingProof } from './masking-proof'\nimport type {\n V2ReplayChunk,\n V2ReplayIdentity,\n V2ReplayPrivacyProof,\n V2ReplayRequest,\n V2ReplaySha256,\n V2Sha256Hash,\n V2VersionContext,\n} from './types'\n\n/** Domain separator hashed ahead of the canonical chunk to derive a replay request identity. */\nexport const V2_REPLAY_REQUEST_ID_DOMAIN = 'elu-sdk-replay-request-v2'\nexport const V2_REPLAY_CONTRACT_VERSION = '2.0.0'\n/** Hard ceiling on the exact UTF-8 bytes of one complete replay request. */\nexport const V2_MAX_REPLAY_REQUEST_BYTES = 5_242_880\n\nexport { V2_REPLAY_REQUEST_ID_PATTERN } from './storage-constants'\nconst CODEC_PATTERN = /^elu-[a-z0-9][a-z0-9.-]{0,63}$/\nconst RUNTIME_NAME_PATTERN = /^elu-[a-z0-9-]+$/\nconst FACADE_NAME_PATTERN = /^[A-Za-z][A-Za-z0-9._-]+$/\nconst BASE64_PATTERN = /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/\nconst CHUNK_KEYS = [\n 'schemaVersion',\n 'replayId',\n 'sessionId',\n 'chunkId',\n 'sequence',\n 'startedAt',\n 'endedAt',\n 'identity',\n 'contextRevision',\n 'codec',\n 'compression',\n 'contentEncoding',\n 'payload',\n 'privacy',\n 'versions',\n] as const\nconst IDENTITY_KEYS = ['anonymousId', 'userId', 'revision'] as const\nconst PRIVACY_KEYS = [\n 'policyRevision',\n 'effectivePolicyHash',\n 'maskingProfileHash',\n 'appliedBeforeSerialization',\n 'secureInputsMasked',\n 'platformFallbackApplied',\n] as const\nconst VERSIONS_KEYS = ['schemaVersion', 'contractVersion', 'platform', 'runtime', 'facade', 'build'] as const\nconst NAMED_VERSION_KEYS = ['name', 'version'] as const\nconst REQUEST_KEYS = ['schemaVersion', 'requestId', 'chunk'] as const\n\nfunction fail(message: string): never {\n throw new V2ReplayRequestError(message)\n}\n\nconst assertBoundedString = (value: unknown, field: string, maximum: number, minimum = 1): string => {\n const length = isStringValue(value) ? unicodeCodePointLength(value) : null\n if (isNullValue(length) || length < minimum || length > maximum) {\n return fail(`${field} must be a string of ${minimum} to ${maximum} Unicode scalars`)\n }\n return value as string\n}\n\nconst assertSafeCount = (value: unknown, field: string): number => {\n if (!isNonNegativeInteger(value)) fail(`${field} must be a safe non-negative integer`)\n return value as number\n}\n\nconst assertHash = (value: unknown, field: string): V2Sha256Hash => {\n if (!isV2Sha256Hash(value)) fail(`${field} must be a lowercase sha256 hash`)\n return value as V2Sha256Hash\n}\n\nconst assertKeys = (value: unknown, keys: readonly string[], field: string, optional: readonly string[] = []) => {\n if (!isRecordValue(value) || !hasOnlyKeys(value, keys)) fail(`${field} must contain only schema-defined fields`)\n for (const key of keys) {\n if (!optional.includes(key) && !hasOwn(value, key)) fail(`${field} ${key} is required`)\n }\n return value\n}\n\nconst validateIdentity = (value: unknown, field: string): V2ReplayIdentity => {\n const identity = assertKeys(value, IDENTITY_KEYS, field)\n return freezeV1Value({\n anonymousId: assertBoundedString(identity.anonymousId, `${field} anonymousId`, 256),\n userId: isNullValue(identity.userId) ? null : assertBoundedString(identity.userId, `${field} userId`, 512),\n revision: assertSafeCount(identity.revision, `${field} revision`),\n })\n}\n\nconst validatePrivacy = (value: unknown, field: string): V2ReplayPrivacyProof => {\n const privacy = assertKeys(value, PRIVACY_KEYS, field)\n if (privacy.appliedBeforeSerialization !== true) fail(`${field} appliedBeforeSerialization must be true`)\n if (privacy.secureInputsMasked !== true) fail(`${field} secureInputsMasked must be true`)\n if (!isBooleanValue(privacy.platformFallbackApplied)) fail(`${field} platformFallbackApplied must be a boolean`)\n return freezeV1Value({\n policyRevision: assertBoundedString(privacy.policyRevision, `${field} policyRevision`, 128),\n effectivePolicyHash: assertHash(privacy.effectivePolicyHash, `${field} effectivePolicyHash`),\n maskingProfileHash: assertHash(privacy.maskingProfileHash, `${field} maskingProfileHash`),\n appliedBeforeSerialization: true,\n secureInputsMasked: true,\n platformFallbackApplied: privacy.platformFallbackApplied,\n })\n}\n\nconst validateNamedVersion = (value: unknown, field: string, namePattern: RegExp) => {\n const named = assertKeys(value, NAMED_VERSION_KEYS, field)\n const name = assertBoundedString(named.name, `${field} name`, 256)\n if (!namePattern.test(name)) fail(`${field} name is invalid`)\n return freezeV1Value({ name, version: assertBoundedString(named.version, `${field} version`, 64) })\n}\n\nexport const validateV2VersionContext = (value: unknown, field = 'replay versions'): V2VersionContext => {\n const versions = assertKeys(value, VERSIONS_KEYS, field, ['build'])\n if (versions.schemaVersion !== 2) fail(`${field} schemaVersion must be 2`)\n if (versions.contractVersion !== V2_REPLAY_CONTRACT_VERSION) {\n fail(`${field} contractVersion must be ${V2_REPLAY_CONTRACT_VERSION}`)\n }\n if (versions.platform !== 'browser' && versions.platform !== 'android' && versions.platform !== 'ios') {\n fail(`${field} platform is unsupported`)\n }\n const runtime = validateNamedVersion(versions.runtime, `${field} runtime`, RUNTIME_NAME_PATTERN)\n const facade = validateNamedVersion(versions.facade, `${field} facade`, FACADE_NAME_PATTERN)\n return freezeV1Value({\n schemaVersion: 2,\n contractVersion: V2_REPLAY_CONTRACT_VERSION,\n platform: versions.platform,\n runtime: runtime as V2VersionContext['runtime'],\n facade,\n ...(hasOwn(versions, 'build') ? { build: assertBoundedString(versions.build, `${field} build`, 128) } : {}),\n })\n}\n\n/** Validates a complete replay chunk envelope against the frozen v2 schema and returns a frozen copy. */\nexport const validateV2ReplayChunk = (value: unknown, field = 'replay chunk'): V2ReplayChunk => {\n const chunk = assertKeys(value, CHUNK_KEYS, field)\n if (chunk.schemaVersion !== 2) fail(`${field} schemaVersion must be 2`)\n const startedAt = assertBoundedString(chunk.startedAt, `${field} startedAt`, 64)\n const endedAt = assertBoundedString(chunk.endedAt, `${field} endedAt`, 64)\n const started = parseV1ExactTimestamp(startedAt, `${field} startedAt`, 64)\n const ended = parseV1ExactTimestamp(endedAt, `${field} endedAt`, 64)\n if (compareV1ExactTimestamps(started, ended) > 0) fail(`${field} endedAt must not precede startedAt`)\n const codec = assertBoundedString(chunk.codec, `${field} codec`, 68)\n if (!CODEC_PATTERN.test(codec)) fail(`${field} codec is invalid`)\n if (chunk.compression !== 'none' && chunk.compression !== 'gzip') fail(`${field} compression is unsupported`)\n if (chunk.contentEncoding !== 'base64') fail(`${field} contentEncoding must be base64`)\n if (!isStringValue(chunk.payload) || chunk.payload.length === 0 || !BASE64_PATTERN.test(chunk.payload)) {\n fail(`${field} payload must be non-empty canonical base64`)\n }\n return freezeV1Value({\n schemaVersion: 2,\n replayId: assertBoundedString(chunk.replayId, `${field} replayId`, 256),\n sessionId: assertBoundedString(chunk.sessionId, `${field} sessionId`, 256),\n chunkId: assertBoundedString(chunk.chunkId, `${field} chunkId`, 256),\n sequence: assertSafeCount(chunk.sequence, `${field} sequence`),\n startedAt,\n endedAt,\n identity: validateIdentity(chunk.identity, `${field} identity`),\n contextRevision: assertSafeCount(chunk.contextRevision, `${field} contextRevision`),\n codec: codec as `elu-${string}`,\n compression: chunk.compression,\n contentEncoding: 'base64',\n payload: chunk.payload,\n privacy: validatePrivacy(chunk.privacy, `${field} privacy`),\n versions: validateV2VersionContext(chunk.versions, `${field} versions`),\n })\n}\n\nexport interface V2ReplayChunkInput {\n readonly replayId: string\n readonly sessionId: string\n readonly chunkId: string\n readonly sequence: number\n readonly startedAt: string\n readonly endedAt: string\n readonly identity: V2ReplayIdentity\n readonly contextRevision: number\n readonly payload: V2EncodedReplayPayload\n readonly policyRevision: string\n readonly effectivePolicyHash: V2Sha256Hash\n readonly versions: V2VersionContext\n}\n\n/**\n * Builds the outer envelope around an encoded payload. The privacy proof constants and the masking\n * profile hash come from the sealed proof inside the payload; callers cannot supply them.\n */\nexport const buildV2ReplayChunk = (input: V2ReplayChunkInput): V2ReplayChunk => {\n if (!isRecordValue(input) || !isRecordValue(input.payload) || !isV2MaskingProof(input.payload.proof)) {\n fail('replay chunk requires a payload encoded from a sealed masking proof')\n }\n const { payload } = input\n return validateV2ReplayChunk({\n schemaVersion: 2,\n replayId: input.replayId,\n sessionId: input.sessionId,\n chunkId: input.chunkId,\n sequence: input.sequence,\n startedAt: input.startedAt,\n endedAt: input.endedAt,\n identity: input.identity,\n contextRevision: input.contextRevision,\n codec: payload.codec,\n compression: payload.compression,\n contentEncoding: payload.contentEncoding,\n payload: payload.payload,\n privacy: {\n policyRevision: input.policyRevision,\n effectivePolicyHash: input.effectivePolicyHash,\n maskingProfileHash: payload.proof.profileHash,\n appliedBeforeSerialization: true,\n secureInputsMasked: true,\n platformFallbackApplied: payload.proof.profile.platformFallbackApplied,\n },\n versions: input.versions,\n })\n}\n\nexport const validateV2ReplayRequest = (value: unknown, field = 'replay request'): V2ReplayRequest => {\n const request = assertKeys(value, REQUEST_KEYS, field)\n if (request.schemaVersion !== 2) fail(`${field} schemaVersion must be 2`)\n if (!isStringValue(request.requestId) || !V2_REPLAY_REQUEST_ID_PATTERN.test(request.requestId)) {\n fail(`${field} requestId must be request_ followed by a lowercase sha256 digest`)\n }\n return freezeV1Value({\n schemaVersion: 2,\n requestId: request.requestId,\n chunk: validateV2ReplayChunk(request.chunk, `${field} chunk`),\n })\n}\n\n/** Strict canonical UTF-8 bytes of the complete chunk envelope. */\nexport const canonicalV2ReplayChunkBytes = (chunk: V2ReplayChunk): Uint8Array =>\n utf8Encode(canonicalV2JsonValue(validateV2ReplayChunk(chunk), 'replay chunk'))\n\n/** `UTF8(domain) || 0x00 || uint32be(len(canonicalChunk)) || canonicalChunk` */\nexport const v2ReplayRequestIdentityMaterial = (canonicalChunk: Uint8Array): Uint8Array => {\n const domain = utf8Encode(V2_REPLAY_REQUEST_ID_DOMAIN)\n const material = new Uint8Array(domain.length + 1 + 4 + canonicalChunk.length)\n material.set(domain, 0)\n material[domain.length] = 0\n const length = canonicalChunk.length\n material[domain.length + 1] = (length >>> 24) & 0xff\n material[domain.length + 2] = (length >>> 16) & 0xff\n material[domain.length + 3] = (length >>> 8) & 0xff\n material[domain.length + 4] = length & 0xff\n material.set(canonicalChunk, domain.length + 5)\n return material\n}\n\nexport interface V2ReplayRequestIdentity {\n readonly requestId: string\n readonly canonicalChunk: Uint8Array\n}\n\nexport const deriveV2ReplayRequestId = async (\n chunk: V2ReplayChunk,\n sha256?: V2ReplaySha256\n): Promise<V2ReplayRequestIdentity> => {\n const canonicalChunk = canonicalV2ReplayChunkBytes(chunk)\n const digest = await sha256Hex(v2ReplayRequestIdentityMaterial(canonicalChunk), sha256)\n return freezeV1Value({ requestId: `request_${digest}`, canonicalChunk })\n}\n\nexport interface V2PreparedReplayRequest {\n /** Local capture witness; deliberately excluded from request bytes and request identity. */\n readonly captureProtocolGeneration: string\n readonly request: V2ReplayRequest\n /** The exact bytes every attempt sends; they are persisted and never regenerated on retry. */\n readonly canonicalRequest: Uint8Array\n readonly canonicalRequestSha256: V2Sha256Hash\n readonly byteLength: number\n}\n\nexport interface V2ReplayRequestOptions {\n readonly captureProtocolGeneration: string\n readonly sha256?: V2ReplaySha256\n /** `limits.replayChunkBytes` from the current config; the hard ceiling applies regardless. */\n readonly replayChunkBytes?: number\n}\n\n/** `min(config.replayChunkBytes, 5242880)`; a missing config limit leaves only the hard ceiling. */\nexport const effectiveV2ReplayRequestLimit = (replayChunkBytes?: number): number => {\n if (typeof replayChunkBytes === 'undefined') return V2_MAX_REPLAY_REQUEST_BYTES\n if (!isNonNegativeInteger(replayChunkBytes) || replayChunkBytes < 1) {\n return fail('replayChunkBytes must be a positive safe integer')\n }\n return Math.min(replayChunkBytes, V2_MAX_REPLAY_REQUEST_BYTES)\n}\n\n/** Derives the request identity, canonicalizes the complete request, and applies the exact byte limit. */\nexport const prepareV2ReplayRequest = async (\n chunk: V2ReplayChunk,\n options: V2ReplayRequestOptions\n): Promise<V2PreparedReplayRequest> => {\n if (!isRecordValue(options)) fail('replay request options must include captureProtocolGeneration')\n const captureProtocolGeneration = assertBoundedString(\n options.captureProtocolGeneration,\n 'captureProtocolGeneration',\n 128\n )\n const limit = effectiveV2ReplayRequestLimit(options.replayChunkBytes)\n const validated = validateV2ReplayChunk(chunk)\n const identity = await deriveV2ReplayRequestId(validated, options.sha256)\n const request: V2ReplayRequest = freezeV1Value({\n schemaVersion: 2,\n requestId: identity.requestId,\n chunk: validated,\n })\n const canonicalRequest = utf8Encode(canonicalV2JsonValue(request, 'replay request'))\n if (canonicalRequest.length > limit) {\n fail(`replay request is ${canonicalRequest.length} bytes; the effective limit is ${limit}`)\n }\n const digest = await sha256Hex(canonicalRequest, options.sha256)\n return freezeV1Value({\n captureProtocolGeneration,\n request,\n canonicalRequest,\n canonicalRequestSha256: `sha256:${digest}` as V2Sha256Hash,\n byteLength: canonicalRequest.length,\n })\n}\n","import { encodeV2BrowserDomPayload } from './codec'\nimport { maskV2BrowserDomEvent } from './dom-masker'\nimport { V2MaskingProof } from './masking-proof'\nimport { buildV2ReplayChunk, prepareV2ReplayRequest } from './request'\nimport type { V2MaskingProfile, V2ReplayIdentity, V2ReplaySha256, V2Sha256Hash, V2VersionContext } from './types'\nimport type { V2PreparedReplayRequest } from './request'\n\n/**\n * One recorded stretch of a session, on its way to the queue.\n *\n * This is the whole path from events to a request the store will accept, in one place and in one\n * order: mask, seal, encode, envelope, prepare. Splitting it would let a caller seal a proof over\n * events this module never masked, which is the one sequence the proof exists to rule out.\n */\nexport interface V2SealReplayChunkInput {\n /** Events as the recorder produced them, in order. */\n readonly events: readonly unknown[]\n readonly profile: V2MaskingProfile\n readonly profileHash: V2Sha256Hash\n readonly replayId: string\n readonly sessionId: string\n readonly chunkId: string\n readonly sequence: number\n readonly startedAt: string\n readonly endedAt: string\n readonly identity: V2ReplayIdentity\n readonly contextRevision: number\n readonly captureProtocolGeneration: string\n readonly policyRevision: string\n readonly effectivePolicyHash: V2Sha256Hash\n readonly versions: V2VersionContext\n /** The document's replay chunk ceiling; a chunk over it is refused rather than trimmed. */\n readonly replayChunkBytes?: number\n readonly sha256?: V2ReplaySha256\n}\n\n/**\n * Masks, seals, encodes and prepares one chunk.\n *\n * The masking pass runs here rather than at the call site so a proof can only ever cover events this\n * function masked. `V2MaskingProof.seal` applies the masker to every event itself, so passing the\n * masker rather than pre-masked events is what makes the proof's claim true by construction.\n */\nexport const sealV2ReplayChunk = async (input: V2SealReplayChunkInput): Promise<V2PreparedReplayRequest> => {\n const proof = V2MaskingProof.seal(maskV2BrowserDomEvent, {\n profile: input.profile,\n profileHash: input.profileHash,\n events: input.events,\n })\n const payload = encodeV2BrowserDomPayload(proof)\n const chunk = buildV2ReplayChunk({\n replayId: input.replayId,\n sessionId: input.sessionId,\n chunkId: input.chunkId,\n sequence: input.sequence,\n startedAt: input.startedAt,\n endedAt: input.endedAt,\n identity: input.identity,\n contextRevision: input.contextRevision,\n payload,\n policyRevision: input.policyRevision,\n effectivePolicyHash: input.effectivePolicyHash,\n versions: input.versions,\n })\n return prepareV2ReplayRequest(chunk, {\n captureProtocolGeneration: input.captureProtocolGeneration,\n ...(input.replayChunkBytes === undefined ? {} : { replayChunkBytes: input.replayChunkBytes }),\n ...(input.sha256 === undefined ? {} : { sha256: input.sha256 }),\n })\n}\n","/* eslint-disable compat/compat -- The internal replay driver requires native Promise support. */\n\nimport { advanceV2ReplaySchedule, initialV2ReplayScheduleState } from './schedule'\nimport { V1_MAX_DURABLE_QUEUE_BYTES, V1_MAX_DURABLE_QUEUE_COUNT } from '../durable-state'\nimport { isNullValue } from '../validation'\nimport type { V2ReplaySchedulePolicy, V2ReplayScheduleState } from './schedule'\nimport { sealV2ReplayChunk } from './seal-chunk'\nimport type { V2SealReplayChunkInput } from './seal-chunk'\nimport type { V2PreparedReplayRequest } from './request'\n\n/**\n * Turns a stream of recorded events into sealed chunks.\n *\n * The recorder is injected rather than imported. That is not only for tests: importing it here would\n * pull the whole recorder into the served bundle, which is why the inherited core loads its own\n * lazily. Whoever supplies one decides how it arrives.\n *\n * Nothing here starts recording on its own, and nothing here delivers. It buffers what it is given,\n * asks the schedule where the boundaries fall, and hands sealed chunks to a sink.\n */\n\n/** What the driver needs to name and stamp a chunk. Supplied per chunk, not held. */\nexport interface V2ReplayChunkIdentitySource {\n readonly replayId: () => string\n readonly chunkId: () => string\n readonly instant: (atMs: number) => string\n}\n\nexport type V2SealedChunkSink = (\n prepared: V2PreparedReplayRequest,\n context: { readonly discarded: boolean; readonly sequence: number }\n) => Promise<void>\n\nexport interface V2ReplaySessionDriverOptions {\n readonly policy: V2ReplaySchedulePolicy\n /** Separate memory ceiling, not a reservation of the durable event/replay queue. */\n readonly maximumBufferedBytes: number\n readonly identity: V2ReplayChunkIdentitySource\n /**\n * Everything the sealing stage needs that does not change between chunks. The chunk ceiling is\n * deliberately not among them: it comes from the schedule, so one document cannot schedule to\n * one size and seal against another.\n */\n readonly seal: Omit<\n V2SealReplayChunkInput,\n 'events' | 'replayId' | 'sessionId' | 'chunkId' | 'sequence' | 'startedAt' | 'endedAt' | 'replayChunkBytes'\n >\n readonly sessionId: string\n readonly sink: V2SealedChunkSink\n /** A terminal failure discards the driver; the owner must stop its recorder. */\n readonly onSealFailure?: (error: unknown, terminal: boolean) => void\n /** Original stream's sealing/sink has settled; no later suffix may use this replay identity. */\n readonly onReplayClosed?: (replayId: string) => Promise<void>\n}\n\ninterface OpenChunk {\n readonly events: unknown[]\n readonly startedAtMs: number\n endedAtMs: number\n estimatedBytes: number\n}\n\nexport interface V2ReplaySessionDriver {\n /** Offers one recorded event. Sealing happens when a boundary says so. */\n record(event: unknown, atMs: number, byteLength: number): Promise<void>\n /** Seals what is open, retaining an ineligible prefix until real activity qualifies it. */\n flush(): Promise<void>\n /** Includes held prefixes and work queued behind asynchronous sealing. */\n hasBufferedWork(): boolean\n /**\n * Immediately discards buffered/queued work and prevents any further sink calls. A sink call\n * already in progress is awaited; its persisted rows need the owner's separate purge barrier.\n * Rebinding identity or privacy requires a new driver after that barrier completes.\n */\n close(): Promise<void>\n}\n\nexport const createV2ReplaySessionDriver = (options: V2ReplaySessionDriverOptions): V2ReplaySessionDriver => {\n if (!Number.isSafeInteger(options.maximumBufferedBytes) || options.maximumBufferedBytes < 1) {\n throw new Error('replay buffer ceiling must be a positive safe integer')\n }\n const byteLimit = Math.min(options.maximumBufferedBytes, V1_MAX_DURABLE_QUEUE_BYTES)\n let state: V2ReplayScheduleState = initialV2ReplayScheduleState()\n let open: OpenChunk | null = null\n let closed = false\n let replayId = options.identity.replayId()\n let closedReplay: Promise<void> | null = null\n let closePromise: Promise<void> | null = null\n const closeReplay = (): Promise<void> => {\n if (!closedReplay) {\n const originalReplayId = replayId\n closedReplay = Promise.resolve().then(() => options.onReplayClosed?.(originalReplayId))\n }\n return closedReplay\n }\n let qualified = options.policy.minimumDurationSeconds === 0\n let emitted = false\n let held: Array<{ prepared: V2PreparedReplayRequest; sequence: number }> = []\n let heldBytes = 0\n // Recorder-supplied size is an ingress estimate; prepared bytes below are exact.\n // Counting pending/open events also bounds closures retained behind slow hashing.\n let ingressBytes = 0\n let ingressCount = 0\n // Chunk work is serialized: a boundary must finish sealing what it closed before the next\n // event can open anything, or two chunks could claim one sequence.\n let tail: Promise<void> = Promise.resolve()\n\n const report = (error: unknown, terminal = false): void => {\n try {\n options.onSealFailure?.(error ?? new Error('replay driver failed without an error value'), terminal)\n } catch {\n // A diagnostic observer cannot strand queued work.\n }\n }\n const discardHeld = (): void => {\n held = []\n heldBytes = 0\n }\n const stop = (): void => {\n closed = true\n open = null\n discardHeld()\n ingressBytes = 0\n ingressCount = 0\n }\n const fail = (error: unknown): void => {\n stop()\n report(error, true)\n }\n const drainHeld = async (): Promise<void> => {\n while (!closed && qualified && held.length > 0) {\n const next = held.shift()!\n heldBytes -= next.prepared.byteLength\n try {\n await options.sink(next.prepared, { discarded: false, sequence: next.sequence })\n emitted = true\n } catch (error) {\n // Never release later deltas after losing the held prefix's baseline.\n fail(error)\n }\n }\n }\n\n const sealOpen = async (discarded: boolean, sequence: number): Promise<void> => {\n const closing = open\n open = null\n if (closed || !closing || closing.events.length === 0) return\n if (discarded) {\n ingressBytes -= closing.estimatedBytes\n ingressCount -= closing.events.length\n return\n }\n try {\n const prepared = await sealV2ReplayChunk({\n ...options.seal,\n // One ceiling, the schedule's, so a chunk is sealed against the size it was cut to.\n replayChunkBytes: options.policy.replayChunkBytes,\n events: closing.events,\n replayId,\n sessionId: options.sessionId,\n chunkId: options.identity.chunkId(),\n sequence,\n startedAt: options.identity.instant(closing.startedAtMs),\n endedAt: options.identity.instant(closing.endedAtMs),\n })\n // Closing while hashing/sealing must not hand stale identity or privacy to the sink.\n if (!closed && !discarded) {\n if (!qualified) {\n if (prepared.byteLength > byteLimit - heldBytes || held.length >= V1_MAX_DURABLE_QUEUE_COUNT) {\n fail(new Error('replay minimum-duration buffer capacity exceeded'))\n } else {\n held.push({ prepared, sequence })\n heldBytes += prepared.byteLength\n }\n } else {\n await options.sink(prepared, { discarded: false, sequence })\n emitted = true\n }\n }\n } catch (error) {\n // A chunk that cannot be sealed is lost, and the session goes on. Failing the whole\n // recorder over one unsendable stretch would lose the rest of the session too.\n if (!closed) {\n if (!qualified || (options.policy.minimumDurationSeconds > 0 && !emitted)) fail(error)\n else report(error)\n }\n } finally {\n ingressBytes = Math.max(0, ingressBytes - closing.estimatedBytes)\n ingressCount = Math.max(0, ingressCount - closing.events.length)\n }\n }\n\n const append = (event: unknown, atMs: number, byteLength: number): void => {\n if (open) {\n open.events.push(event)\n open.endedAtMs = atMs\n open.estimatedBytes += byteLength\n return\n }\n open = { events: [event], startedAtMs: atMs, endedAtMs: atMs, estimatedBytes: byteLength }\n }\n\n return {\n record(event: unknown, atMs: number, byteLength: number): Promise<void> {\n if (closed) return Promise.resolve()\n if (\n !Number.isFinite(atMs) ||\n atMs < 0 ||\n (!isNullValue(state.lastActivityAtMs) && atMs < state.lastActivityAtMs) ||\n !Number.isSafeInteger(byteLength) ||\n byteLength < 1\n ) {\n fail(new Error('invalid replay ingress observation'))\n return tail\n }\n if (byteLength > byteLimit - ingressBytes || ingressCount >= V1_MAX_DURABLE_QUEUE_COUNT) {\n fail(new Error('replay ingress buffer capacity exceeded'))\n return tail\n }\n ingressBytes += byteLength\n ingressCount += 1\n const decision = advanceV2ReplaySchedule(state, { atMs, byteLength }, options.policy)\n const sealedSequence = state.sequence\n state = decision.state\n tail = tail.then(async () => {\n if (closed) return\n if (decision.action !== 'buffer') {\n await sealOpen(decision.discardSealedChunk, sealedSequence)\n if (closed) return\n // A session boundary starts a new replay; a chunk boundary stays in this one.\n if (decision.action === 'cut-session') {\n try {\n await closeReplay()\n } catch (error) {\n fail(error)\n throw error\n }\n if (closed) return\n discardHeld()\n qualified = options.policy.minimumDurationSeconds === 0\n emitted = false\n replayId = options.identity.replayId()\n closedReplay = null\n }\n }\n append(event, atMs, byteLength)\n // Use this queued event's immutable decision, never the globally advanced state.\n if (\n !qualified &&\n !isNullValue(decision.state.sessionStartedAtMs) &&\n atMs - decision.state.sessionStartedAtMs >= options.policy.minimumDurationSeconds * 1000\n ) {\n qualified = true\n await drainHeld()\n }\n })\n return tail\n },\n flush(): Promise<void> {\n if (closed) return Promise.resolve()\n const sequence = state.sequence\n if (state.chunkEvents > 0) {\n // Reserve the next sequence at invocation, like record(), so events queued after\n // this flush cannot reuse the identity of the chunk it is about to seal.\n state = Object.freeze({\n ...state,\n chunkStartedAtMs: null,\n chunkBytes: 0,\n chunkEvents: 0,\n sequence: state.sequence + 1,\n })\n }\n tail = tail.then(() => sealOpen(false, sequence))\n return tail\n },\n hasBufferedWork(): boolean {\n return !closed && (ingressCount > 0 || held.length > 0 || !isNullValue(open))\n },\n close(): Promise<void> {\n // This barrier is synchronous even when prior digest or sink work is still pending.\n stop()\n if (!closePromise) closePromise = tail.then(closeReplay, async (error) => {\n await closeReplay()\n throw error\n })\n return closePromise\n },\n }\n}\n","import { record } from '../../rrweb/rrweb/src/entries/record'\nimport { createV2RecorderAdapter } from '../src/elu-http-v1/replay/recorder-adapter'\nimport type { V2RecorderEngine } from '../src/elu-http-v1/replay/recorder-adapter'\nimport type { V1OwnedRecorderFactory } from '../src/elu-http-v1/browser-recorder-loader'\nimport { createV2ReplaySessionDriver } from '../src/elu-http-v1/replay/cold-session-entry'\n\n// Separate script/npm copies and separately evaluated immutable assets share this document lease.\n// It is internal DOM metadata, not a public window API. A collision refuses recording.\nconst OWNER_PROPERTY = '__eluOwnedRecorderLeaseV1'\ntype RecorderDocument = Document & { [OWNER_PROPERTY]?: object }\n\n/** A failed disposer deliberately leaves this module occupied until the page is discarded. */\nconst ownedRecord: V2RecorderEngine = (options) => {\n const ownerDocument = document as RecorderDocument\n if (OWNER_PROPERTY in ownerDocument) throw new Error('Recorder is already owned')\n const owner = {}\n Object.defineProperty(ownerDocument, OWNER_PROPERTY, { value: owner, configurable: true })\n let released = false\n const release = () => {\n if (released) return\n if (ownerDocument[OWNER_PROPERTY] !== owner) throw new Error('Recorder ownership changed')\n delete ownerDocument[OWNER_PROPERTY]\n released = true\n }\n // record() unwinds partial acquisition before returning undefined. If it throws, cleanup\n // could not be proven and ownership stays poisoned; a second recorder must not overlap it.\n const stop = record({ ...options, plugins: [] })\n if (typeof stop !== 'function') {\n release()\n return undefined\n }\n return () => {\n stop()\n release()\n }\n}\n\n/** Internal lazy-module export. It installs no globals and selects no codec or provider. */\nexport const createEluOwnedRecorder: V1OwnedRecorderFactory = (options) => {\n const adapter = createV2RecorderAdapter({ ...options, engine: ownedRecord, document })\n if (options.installSessionDriver) {\n let installed = false\n try {\n // The original owner supplies the one-shot grant-bound slot. The asset never sees\n // raw storage or issues another source/session lease, and starts no recorder here.\n installed =\n options.isCurrent() &&\n options.installSessionDriver(createV2ReplaySessionDriver) &&\n options.isCurrent()\n } finally {\n // A normal refusal returns an inert adapter whose cleanup can be joined by the owner.\n // A throwing installer still propagates: its unknown partial work must stay poisoned.\n if (!installed) void adapter.close()\n }\n }\n return adapter\n}\n"],"names":["RecorderCleanupError","Error","constructor","super","this","name","isRecorderCleanupError","error","createRecorderCleanup","handlers","closed","failed","attempt","handler","_unused","assertComplete","close","length","pop","poison","add","push","replace","target","key","value","descriptor","Object","getOwnPropertyDescriptor","defineProperty","Reflect","deleteProperty","acquireRecorderCleanup","acquire","cleanup","EventType","IncrementalSource","MouseInteractions","PointerTypes","CanvasContext","MediaInteractions","NodeType","includes","str","needle","indexOf","testableAccessors","Node","ShadowRoot","Element","MutationObserver","testableMethods","untaintedBasePrototype","getUntaintedPrototype","candidate","_Zone","angularUnpatchedVersionSymbol","globalThis","Zone","__symbol__","angularZoneUnpatchedAlternative","defaultPrototype","prototype","accessorNames","undefined","isUntaintedAccessors","Boolean","every","accessor","_Object$getOwnPropert","get","toString","methodNames","isUntaintedMethods","method","_defaultPrototype$met","iframeEl","document","createElement","style","display","userAgent","keepIframeAttached","body","appendChild","win","contentWindow","untaintedObject","navigator","classList","setAttribute","parentNode","removeChild","untaintedAccessorCache","getUntaintedAccessor","instance","_Object$getOwnPropert2","cacheKey","String","call","untaintedPrototype","untaintedAccessor","untaintedMethodCache","getUntaintedMethod","bind","untaintedMethod","mutationObserverCtor","patch","source","replacement","original","layer","next","wrapped","_len","arguments","args","Array","_key","apply","defineProperties","__rrweb_original__","enumerable","__rrweb_layer__","current","currentLayer","_unused2","dom","childNodes","n","parentElement","textContent","contains","other","getRootNode","host","styleSheets","shadowRoot","querySelector","selectors","querySelectorAll","mutationObserver","isElement","nodeType","ELEMENT_NODE","isShadowRoot","hostEl","isNativeShadowDom","stringifyStylesheet","s","rules","cssRules","sheetHref","href","ownerNode","baseURI","stringifiedRules","from","rule","stringifyRule","join","cssText","isCSSImportRule","importStringified","styleSheet","split","statement","JSON","stringify","layerName","supportsText","media","mediaText","escapeImportStatement","_rule$styleSheet","absolutifyURLs","regex","ruleStringified","isCSSStyleRule","selectorText","Mirror","idNodeMap","Map","nodeMetaMap","WeakMap","getId","_this$getMeta","id","getMeta","getNode","getIds","keys","removeNodeFromMap","delete","forEach","childNode","shadowRootEl","nodeName","contentDocument","has","hasNode","node","meta","set","oldNode","reset","maskInputValue","_ref","element","maskInputOptions","tagName","type","maskInputFn","text","actualType","toLowerCase","repeat","ORIGINAL_ATTRIBUTE_NAME","getInputType","hasAttribute","URL_IN_CSS_REF","URL_PROTOCOL_MATCH","URL_WWW_MATCH","DATA_URI","origin","quote1","path1","quote2","path2","path3","url","filePath","maybeQuote","test","slice","stack","parts","part","canvasService","canvasCtx","STRIPED_PLACEHOLDER_SVG","MAX_IMAGE_DIMENSION_FOR_RECOMPRESSION","_id","tagNameRegex","RegExp","IGNORED_NODE","genId","SRCSET_NOT_SPACES","SRCSET_COMMAS_OR_SPACES","cachedDocument","absoluteToDoc","doc","attributeValue","trim","getHref","customHref","a","startsWith","capDataURLSize","dataURL","dataURLOptions","maxBase64ImageLength","maxLength","checkDataURLSize","transformAttribute","_sheet","sheet","transformedValue","processedDataURL","quality","img","complete","naturalWidth","naturalHeight","canvas","width","height","ctx","getContext","drawImage","toDataURL","err","recompressBase64Image","pos","collectCharacters","regEx","chars","match","exec","substring","output","descriptorsStr","inParens","c","charAt","getAbsoluteSrcsetString","ignoreAttribute","_value","classMatchesRegex","checkAncestors","eIndex","className","needMaskingText","maskTextClass","maskTextSelector","el","parent","closest","matches","root","removeEventListenerSafely","listener","removeEventListener","stylesheetLoadTracked","resetStylesheetLoadTracking","controller","values","reverse","abort","_unused3","findStylesheet","find","lowerIfExists","maybeAttr","DEFAULT_MAX_DEPTH","_maxDepthWarned","serializeNodeWithId","options","mirror","blockClass","blockSelector","_options$skipChild","skipChild","_options$inlineStyles","inlineStylesheet","_options$maskInputOpt3","maskTextFn","slimDOMOptions","_options$dataURLOptio3","_options$inlineImages","inlineImages","_options$recordCanvas","recordCanvas","canvasMaskingConfigured","onSerialize","onIframeLoad","_options$iframeLoadTi","iframeLoadTimeout","onIframeListenerRegistered","onStylesheetLoad","_options$stylesheetLo","stylesheetLoadTimeout","_options$keepIframeSr","keepIframeSrcFn","_options$newlyAddedEl3","newlyAddedElement","_options$depth","depth","_options$maxDepth","maxDepth","needsMask","_options$preserveWhit","preserveWhiteSpace","console","warn","_serializedNode","_options$maskInputOpt","_options$dataURLOptio","_options$newlyAddedEl","rootId","docId","getRootId","DOCUMENT_NODE","compatMode","Document","DOCUMENT_TYPE_NODE","DocumentType","publicId","systemId","isCustomElement","_options$maskInputOpt2","_options$dataURLOptio2","_options$newlyAddedEl2","needBlock","e","_isBlockedElement","HTMLFormElement","processedTagName","getValidTagName","attributes","len","i","attr","stylesheet","hrefFrom","window","location","rel","_cssText","innerText","checked","selected","open","rr_open_mode","_unused7","ph_rr_could_not_detect_modal","__context","x","y","getImageData","originalGetImageData","Uint32Array","Math","min","data","buffer","some","pixel","is2DCanvasBlank","rr_dataURL","canvasDataURL","blankCanvas","image","imageSrc","currentSrc","getAttribute","priorCrossOrigin","crossOrigin","recordInlineImage","addEventListener","removeAttribute","mediaAttributes","rr_mediaState","paused","rr_mediaCurrentTime","currentTime","rr_mediaPlaybackRate","playbackRate","rr_mediaMuted","muted","rr_mediaLoop","loop","rr_mediaVolume","volume","scrollLeft","rr_scrollLeft","scrollTop","rr_scrollTop","_doc$defaultView","_doc$defaultView2","_doc$defaultView3","_n$getBoundingClientR","getBoundingClientRect","left","top","computed","defaultView","getComputedStyle","class","rr_width","rr_height","rr_left","floor","scrollX","rr_top","scrollY","rr_position","position","transform","rr_transform","rr_display","src","rr_src","customElements","isSVG","ownerSVGElement","isCustom","serializeElementNode","TEXT_NODE","parentTagName","isStyle","isScript","_sheet2","nextSibling","previousSibling","stringified","Text","serializeTextNode","CDATA_SECTION_NODE","CDATA","COMMENT_NODE","Comment","serializeNode","sn","comment","script","as","path","baseURL","_match$","URL","pathname","extractFileExtension","headFavicon","headMetaDescKeywords","headMetaSocial","property","headMetaRobots","headMetaHttpEquiv","headMetaAuthorship","headMetaVerification","slimDOMExcluded","serializedNode","assign","recordChild","isShadowHost","headWhitespace","bypassOptions","childN","serializedChildNode","isShadow","iframeDisposer","readyState","noop","onSubsequentLoad","fired","timer","fireOnce","clearTimeout","onInitialLoad","setTimeout","winLocationHref","blankUrl","initialTimer","onceIframeLoaded","iframeDoc","serializedIframeNode","link","styleSheetLoadTimeout","styleSheetLoaded","_unused4","installed","pending","_unused5","fire","_unused6","serializedLinkNode","once","onceStylesheetLoaded","slimDOMDefaults","slimDOM","headTitleMutations","create","isColorSupported","bold","dim","italic","underline","inverse","hidden","strikethrough","black","red","green","yellow","blue","magenta","cyan","white","gray","bgBlack","bgRed","bgGreen","bgYellow","bgBlue","bgMagenta","bgCyan","bgWhite","blackBright","redBright","greenBright","yellowBright","blueBright","magentaBright","cyanBright","whiteBright","bgBlackBright","bgRedBright","bgGreenBright","bgYellowBright","bgBlueBright","bgMagentaBright","bgCyanBright","bgWhiteBright","picocolors_browserModule","exports","createColors","pico","require$$0","terminalHighlight","require$$1","CssSyntaxError","message","line","column","file","plugin","reason","endLine","endColumn","setMessage","captureStackTrace","showSourceCode","color","css","aside","mark","highlight","_pico$createColors","lines","start","max","end","maxWidth","map","index","number","gutter","subLineStart","subLineEnd","subLine","spacing","padding","code","cssSyntaxError","default","STYLE_TAG","COMMENT_OPEN","escapeHTMLInCSS","DEFAULT_RAW","after","beforeClose","beforeComment","beforeDecl","beforeOpen","beforeRule","colon","commentLeft","commentRight","emptyBody","indent","semicolon","Stringifier","builder","atrule","raws","params","rawValue","afterName","nodes","block","between","beforeAfter","detect","raw","buf","step","last","isDocument","child","before","right","decl","string","prop","important","own","first","cache","rawCache","toUpperCase","walk","rawBeforeClose","rawBeforeComment","walkComments","rawBeforeDecl","walkDecls","rawBeforeOpen","rawBeforeRule","rawColon","rawEmptyBody","rawIndent","p","rawSemicolon","ownSemicolon","stringifier","stringify_1","symbols","isClean","Symbol","my","require$$2","_require$$","require$$3","cloneNode","obj","cloned","hasOwnProperty","isArray","j","sourceOffset","inputCSS","offset","proxyOf","defaults","clone","append","addToError","postcssNode","input","insertAfter","overrides","insertBefore","cleanRaws","keepBetween","cloneAfter","cloneBefore","opts","_this$rangeBy","rangeBy","getProxyProcessor","toProxy","markDirty","markClean","positionBy","inputString","positionInside","word","prev","endIndex","defaultType","remove","replaceWith","bookmark","foundSelf","result","toJSON","_","inputs","fixed","emitInputs","inputsNextIndex","inputId","proxyCache","Proxy","Declaration","variable","_extends","declaration","AtRule","parse","Root","Rule","cleanSource","markTreeDirty","Container","children","normalize","each","callback","iterator","getIterator","indexes","condition","lastEach","_len2","_key2","cb","_len3","_key3","exist","existIndex","splice","sample","selector","processed","rebuild","prepend","_len4","_key4","unshift","removeAll","replaceValues","pattern","props","fast","walkAtRules","walkRules","registerParse","dependant","registerRule","registerAtRule","registerRoot","container","setPrototypeOf","atRule","LazyResult","Processor","toResult","registerLazyResult","registerProcessor","nonSecure","nanoid","size","random","customAlphabet","alphabet","defaultSize","existsSync","readFileSync","dirname","SourceMapConsumer","SourceMapGenerator","PreviousMap","unsafeMap","loadAnnotation","inline","startWith","annotation","loadMap","mapFile","consumer","consumerCache","json","decodeInline","uriMatch","decodeURIComponent","substr","baseUriMatch","Buffer","atob","encoding","getAnnotationURL","sourceMapString","isMap","mappings","_mappings","sections","comments","lastIndexOf","loadFile","cssFile","trusted","fromSourceMap","prevPath","unknown","withContent","sourcesContent","previousMap","isAbsolute","resolve","fileURLToPath","pathToFileURL","require$$4","require$$5","require$$6","lineToIndexCache","sourceMapAvailable","pathAvailable","getLineToIndex","lineToIndex","prevIndex","l","Input","hasBOM","mapResolve","endOffset","fromOffset","col","fromLineAndColumn","mid","sourceRoot","to","fromUrl","originalPositionFor","protocol","sourceContentFor","registerInput","ignore","list","comma","space","separators","array","func","inQuote","prevQuote","escape","letter","list_1","sep","relative","mapGenerator","cssString","mapOpts","originalCSS","usesFileUrls","absolute","memoizedFileURLs","memoizedPaths","memoizedURLs","addAnnotation","content","isInline","toBase64","outputFile","eol","applyPrevMaps","previous","toUrl","applySourceMap","clearAnnotation","startIndex","generate","generateMap","generateString","ignoreInvalidMapping","addMapping","generated","isSourcesContent","setSourcesContent","isAnnotation","noSource","mapping","sourcePath","charCodeAt","cached","previousMaps","already","toFileUrl","setSourceContent","btoa","unescape","encodeURIComponent","fileURL","encodeURI","SINGLE_QUOTE","DOUBLE_QUOTE","BACKSLASH","SLASH","NEWLINE","SPACE","FEED","TAB","CR","OPEN_SQUARE","CLOSE_SQUARE","OPEN_PARENTHESES","CLOSE_PARENTHESES","OPEN_CURLY","CLOSE_CURLY","SEMICOLON","ASTERISK","COLON","AT","RE_AT_END","RE_WORD_END","RE_BAD_BRACKET","RE_HEX_ESCAPE","tokenize","quote","currentToken","escaped","escapePos","valueOf","ignoreErrors","returned","lastBadParen","unclosed","what","back","token","endOfFile","nextToken","ignoreUnclosed","controlChar","fromCharCode","lastIndex","tokenizer","SAFE_COMMENT_NEIGHBOR","empty","tokensToString","tokens","parser","spaces","createTokenizer","shift","unnamedAtrule","init","brackets","getPosition","spacesAndCommentsFromEnd","spacesAndCommentsFromStart","checkMissedSemicolon","founded","_ref2","entries","doubleColon","customProperty","findLastWithPosition","unknownWord","propStart","betweenStart","firstSpacesStart","firstSpaces","precheckMissedSemicolon","stringFrom","spacesFromEnd","hasWord","concat","emptyRule","unexpectedClose","endFile","unclosedBlock","freeSemicolon","bracket","unclosedBracket","clean","reduce","all","lastTokenType","Parser","process","env","NODE_ENV","parse_1","Warning","range","opt","warning","Result","processor","messages","lastPlugin","postcssPlugin","warnings","filter","printed","warnOnce","MapGenerator","require$$7","require$$8","TYPE_TO_CLASS_NAME","PLUGIN_PROPS","AtRuleExit","CommentExit","DeclarationExit","DocumentExit","Once","OnceExit","prepare","RootExit","RuleExit","NOT_VISITORS","CHILDREN","isPromise","then","getEvents","toStack","eventIndex","events","visitorIndex","visitors","cleanMarks","postcss","sync","toStringTag","syntax","helpers","plugins","async","Promise","reject","processing","runAsync","catch","onRejected","finally","onFinally","getAsyncError","handleError","postcssVersion","pluginName","pluginVer","runtimeVer","version","b","parseInt","prepareVisitors","listeners","event","hasListener","_this","_asyncToGenerator","promise","runOnRoot","visitTick","_loop","visitor","roots","subRoot","rootSource","walkSync","visitSync","onFulfilled","_ref4","visit","_visitors$visit$visit","registerPostcss","lazyResult","fromJSON","ownInputs","_objectWithoutPropertiesLoose","_excluded","inputHydrated","__proto__","_defaults$source","_excluded2","fromJSON_1","require$$9","require$$10","require$$11","NoWorkResult","_root","_css","_opts","_processor","_map","self","_map$generate","generatedCSS","generatedMap","noWorkResult","normalized","use","require$$12","require$$13","require$$14","require$$15","require$$16","require$$17","initializer","warningPrinted","creator","LANG","transformer","processOpts","pluginOpts","postcss_1","SafeParser","safeParser","nextStart","prevEnd","safeParse","BaseRRNode","ownerDocument","firstChild","lastChild","RRNodeType","childIterator","_newChild","_refChild","_node","on","fn","capture","passive","callSafely","DOMException","DEPARTED_MIRROR_ACCESS_WARNING","_mirror","throttle","wait","timeout","now","Date","leading","remaining","context","trailing","hookSetter","d","isRevoked","receiver","nowTimestamp","getWindowScroll","_dom$parentElement","_doc$body","_dom$parentElement2","_doc$body2","scrollingElement","pageXOffset","documentElement","pageYOffset","getWindowHeight","innerHeight","clientHeight","getWindowWidth","innerWidth","clientWidth","closestElementOfNode","isBlocked","searchAncestors","isIgnored","isAncestorRemoved","legacy_isTouchEvent","changedTouches","isSerializedIframe","isSerializedStylesheet","hasShadowRoot","getTime","StyleSheetMirror","styleIDMap","idStyleMap","_this$styleIDMap$get","newId","getStyle","generateId","getShadowHost","_dom$getRootNode","shadowHost","DOCUMENT_FRAGMENT_NODE","inDom","rootShadowHost","getRootShadowHost","shadowHostInDom","isNodeInLinkedList","DoubleLinkedList","head","tail","_current","addNode","__ln","removeNode","errorHandler","moveKey","parentId","MutationBuffer","frozen","locked","texts","attributeMap","removes","mapRemoves","movedMap","addedSet","Set","movedSet","droppedSet","removesSubTreeCache","mutationCb","iframeManager","stylesheetManager","shadowDomManager","canvasManager","processedNodeManager","unattachedDoc","canvasManagerReleased","processMutations","mutations","processMutation","emit","adds","addedIds","addList","getNextId","ns","nextId","pushAdd","currentN","addIframe","trackLinkElement","addShadowRoot","iframe","childSn","attachIframe","observeAttachShadow","disposer","registerLoadListenerDisposer","attachLinkElement","isParentRemoved","isAncestorInSet","tailNode","unhandledNode","payload","genTextAreaValueMutation","attribute","diffAsStr","styleDiff","unchangedAsStr","_unchangedStyles","bufferBelongsToIframe","textarea","item","cn","m","oldValue","attributeName","implementation","createHTMLDocument","old","pname","newValue","getPropertyValue","newPriority","getPropertyPriority","addedNodes","genAdds","removedNodes","nodeId","isSerialized","deepDelete","queue","processRemoves","inOtherBuffer","targetId","freeze","unfreeze","isFrozen","lock","unlock","releaseCanvasManager","bufferDoc","destroy","addsSet","_isParentRemoved","_isAncestorInSet","registerErrorHandler","unregisterErrorHandler","callbackWrapper","mutationBuffers","getEventTarget","composedPath","initMutationObserver","rootEl","mutationBuffer","observer","disconnect","mutationObserverInit","attributeOldValue","characterData","characterDataOldValue","childList","subtree","attributeFilter","observe","initScrollObserver","scrollCb","sampling","active","lastEmitted","emitScrollPosition","evt","scrollLeftTop","updatePosition","scroll","findAndRemoveIframeBuffer","knownDocs","INPUT_TAGS","lastInputValueMap","getNestedCSSRulePositions","recurse","childRule","hasNestedCSSRule","parentRule","CSSGroupingRule","CSSMediaRule","CSSSupportsRule","CSSConditionRule","parentStyleSheet","getIdAndStyleId","styleMirror","styleId","initAdoptedStyleSheetObserver","_ref1","_defaultView","_host$ownerDocument","hostId","patchTarget","originalPropertyDescriptor","configurable","_originalPropertyDesc","sheets","_originalPropertyDesc2","adoptStyleSheets","initObservers","o","hooks","currentWindow","mousemoveCb","mouseInteractionCb","viewportResizeCb","inputCb","mediaInteractionCb","styleSheetRuleCb","styleDeclarationCb","canvasMutationCb","fontCb","selectionCb","customElementCb","mutation","mousemove","mouseInteraction","viewportResize","mediaInteaction","styleSheetRule","styleDeclaration","canvasMutation","font","selection","customElement","mergeHooks","resetForDoc","recordDOM","_initMutationObserver","_ref6","lastH","lastW","timeBaseline","threshold","callbackThreshold","mousemoveCallback","positions","wrappedCb","totalOffset","timeOffset","clientX","clientY","DragEvent","Drag","MouseEvent","MouseMove","TouchMove","initMoveObserver","_ref3","disableMap","currentPointerType","Number","isNaN","endsWith","eventKey","eventName","pointerType","thisEventKey","Mouse","Touch","Pen","MouseDown","MouseUp","Click","getHandler","PointerEvent","TouchStart","TouchEnd","initMouseInteractionObserver","_ref7","ignoreClass","ignoreSelector","userTriggeredOnInput","eventHandler","userTriggered","isTrusted","view","HTMLElement","isChecked","cbWithDedup","v","lastInputValue","propertyDescriptor","HTMLInputElement","hookProperties","HTMLSelectElement","HTMLTextAreaElement","HTMLOptionElement","initInputObserver","_ref12","_ref13","Play","Pause","Seeked","VolumeChange","RateChange","initMediaInteractionObserver","_ref8","_ref9","CSSStyleSheet","insertRule","thisArg","argumentsList","_getIdAndStyleId","styleBlock","replaceSync","deleteRule","_getIdAndStyleId2","_getIdAndStyleId3","_getIdAndStyleId4","supportedNestedCSSRuleTypes","canMonkeyPatchNestedCSSRule","unmodifiedFunctions","_ref0","typeKey","_getIdAndStyleId5","_getIdAndStyleId6","initStyleSheetObserver","_ref10","_ref11","ignoreCSSAttributes","setProperty","CSSStyleDeclaration","_thisArg$parentRule","priority","_getIdAndStyleId7","removeProperty","_thisArg$parentRule2","_getIdAndStyleId8","initStyleDeclarationObserver","collectFonts","_ref14","fontMap","originalFontFace","FontFace","family","descriptors","fontFace","fontSource","Uint8Array","restoreHandler","fonts","initFontObserver","param","collapsed","updateSelection","getSelection","isCollapsed","ranges","count","rangeCount","getRangeAt","startContainer","startOffset","endContainer","initSelectionObserver","_ref15","define","initCustomElementObserver","CrossOriginIframeMirror","generateIdFn","iframeIdToRemoteIdMap","iframeRemoteIdToIdMap","remoteId","idToRemoteMap","remoteToIdMap","idToRemoteIdMap","getIdToRemoteIdMap","remoteIdToIdMap","getRemoteIdToIdMap","getRemoteId","getRemoteIds","ids","IframeManager","iframes","crossOriginIframeMap","crossOriginIframeMirror","crossOriginIframeStyleMirror","crossOriginIframeRootIdMap","wrappedEmit","loadListener","pageHideListener","recordCrossOriginIframes","messageHandler","nestedIframeListeners","attachedWindows","attachedDocuments","attachedIframes","loadListenerDisposers","iframeElementsById","pageHideHandlers","handleMessage","bucket","getIframeElementById","iframeId","_this$attachedIframes","_this$attachedIframes2","forgetIframeId","disposeLoadListeners","removePageHideListener","addLoadListener","addPageHideListener","removeLoadListener","trackIframeContent","_this$loadListener","docs","isAttachIframe","nestedHandler","wins","pageHideWindow","entry","_this$pageHideListene","adoptedStyleSheets","crossOriginMessageEvent","transformedEvent","transformCrossOriginEvent","isCheckout","FullSnapshot","replaceIdOnNode","patchRootIdOnNode","timestamp","IncrementalSnapshot","Mutation","Meta","Load","DomContentLoaded","Plugin","Custom","replaceIds","ViewportResize","MediaInteraction","MouseInteraction","Scroll","CanvasMutation","StyleSheetRule","StyleDeclaration","replaceStyleIds","Font","Selection","AdoptedStyleSheet","_e$data$styles","styles","iframeMirror","removeIframeById","capturedWins","capturedWin","capturedDocs","cleanupDetachedIframes","orphaned","_entry","reattachIframes","clear","tracked","ShadowDomManager","shadowDoms","WeakSet","generation","documentGenerations","cleanupFailed","restoreHandlers","patchAttachShadow","_dom$host$ownerDocume","_dom$host","ownerDoc","documentGeneration","iframeElement","manager","option","sRoot","disposeHandlers","SKIP_FRAME","isValidRegion","r","isFinite","lookup","canvasVarMap","saveWebGLVar","isInstanceOfWebGLObject","ctor","contextMap","variableListFor","serializeArg","arg","Float32Array","Float64Array","Int32Array","Uint16Array","Int16Array","Int8Array","Uint8ClampedArray","rr_type","ArrayBuffer","base64","arraybuffer","bytes","encode","DataView","byteOffset","byteLength","HTMLImageElement","HTMLCanvasElement","ImageData","serializeArgs","supportedWebGLConstructorNames","WEBGL_CONTEXT_NAMES","isCanvasNode","initCanvasContextObserver","setPreserveDrawingBufferToTrue","restoreWebGPUConfigureHandler","GPUCanvasContext","configure","configuration","getCanvasFromWebGPUContext","requiredUsage","textureUsage","GPUTextureUsage","COPY_SRC","RENDER_ATTACHMENT","getRequiredWebGPUTextureUsage","usage","initCanvasWebGPUContextObserver","contextType","ctxName","getNormalizedContextName","contextAttributes","preserveDrawingBuffer","h","patchGLPrototype","getOwnPropertyNames","recordArgs","hookHandler","setter","takeFullSnapshot","CanvasManager","onFullSnapshot","_this$resetFrameDedup","resetFrameDedup","refCount","teardown","torndown","pendingCanvasMutations","resetObservers","rafIdTimestamp","cancelAnimationFrame","rafIdFlush","rafStamps","latestId","invokeId","_options$sampling","resolutionScale","canvasMasking","initCanvasMutationObserver","initCanvasFPSObserver","fps","worker","scale","canvasContextReset","snapshotInProgressMap","ImageBitmapDataURLWorker","workerErrored","onerror","rafId","terminate","postMessage","onmessage","_e$data","dw","displayWidth","dh","displayHeight","commands","timeBetweenSnapshots","lastSnapshotTime","takeCanvasSnapshots","getCanvas","matchedCanvas","searchCanvas","haystack","elem","_context$getContextAt","isContextLost","getContextAttributes","COLOR_BUFFER_BIT","captureWidth","round","captureHeight","maskRegions","masking","regionsFn","regions","sx","sy","ceil","computeFrameMaskRegions","bitmap","createImageBitmap","resizeWidth","resizeHeight","resizeQuality","_x","requestAnimationFrame","startRAFTimestamping","startPendingCanvasMutationFlusher","canvas2DReset","props2D","CanvasRenderingContext2D","initCanvas2DMutationObserver","canvasWebGL1and2Reset","WebGLRenderingContext","WebGL","WebGL2RenderingContext","WebGL2","initCanvasWebGLMutationObserver","flushPendingCanvasMutations","setLatestRAFTimestamp","_values","flushPendingCanvasMutationFor","valuesWithType","StylesheetManager","trackedLinkElements","adoptedStyleSheetCb","linkEl","trackStylesheetInLinkElement","adoptedStyleSheetData","styleIds","CSSRule","_linkEl","ProcessedNodeManager","nodeMap","thisBuffer","buffers","recording","_cleanFrame$contentWi","cleanFrame","debug","nonUserInitiatedSources","Log","record","_options","checkoutEveryNms","checkoutEveryNth","_options$blockClass","_options$blockSelecto","_options$ignoreClass","_options$ignoreSelect","_options$maskTextClas","_options$maskTextSele","maskAllInputs","_maskInputOptions","_slimDOMOptions","packFn","_dataURLOptions","canvasResolutionScale","mousemoveWait","_options$recordDOM","_options$recordCrossO","_options$recordAfter","recordAfter","_options$userTriggere","_options$collectFonts","_options$ignoreCSSAtt","inEmittingFrame","passEmitsToParent","dispose","lastFullSnapshotEvent","date","email","month","search","tel","time","week","select","password","NodeList","DOMTokenList","runAndDetachIframeCleanup","cleanupDetachedIframeObservers","incrementalSnapshotCount","iframeObserverCleanups","eventProcessor","emitForRecording","_mutationBuffers$","exceedCount","exceedTime","snapshotForRecording","wrappedMutationEmit","addedIframeElements","removedIframe","wrappedScrollEmit","wrappedCanvasMutationEmit","getMirror","nodeMirror","configured","_ref$mirror","_ref$blockClass","_ref$blockSelector","_ref$maskTextClass","_ref$maskTextSelector","_ref$inlineStylesheet","_ref$inlineImages","_ref$recordCanvas","_ref$maskAllInputs","_ref$slimDOM","_ref$keepIframeSrcFn","snapshot","initialOffset","acquired","cleanups","detached","idx","_plugins$filter","CustomElement","lastFullscreenId","emitFullscreen","tag","emitFullscreenChange","_ref5","_doc$fullscreenElemen","fullscreenEl","fullscreenElement","webkitFullscreenElement","mozFullScreenElement","msFullscreenElement","enter","initialized","addCustomEvent","freezePage","unpackV1DeflatedTextData","encoded","expectedBytes","expectedCount","invalid","isSafeInteger","byteCount","bits","digit","fixedLiterals","fixedDistances","written","read","tree","lengths","single","counts","maximum","offsets","symbol","codes","final","blocks","kind","subarray","literals","distances","distanceLengths","literalCount","distanceCount","codeCount","order","codeLengths","codeTree","repeated","extra","distanceSymbol","distanceExtra","distance","decoded","readV1EagerText","v1MemberKeys","v1MemberKey0","v1MemberKey2","v1MemberKey3","v1MemberKey7","v1MemberKey8","v1MemberKey22","v1MemberKey23","v1MemberKey34","v1MemberKey37","v1MemberKey38","v1MemberKey45","v1MemberKey48","v1MemberKey52","v1MemberKey53","v1MemberKey60","v1MemberKey65","v1MemberKey67","v1MemberKey81","v1MemberKey83","v1MemberKey85","v1MemberKey86","v1MemberKey91","v1MemberKey95","v1MemberKey111","v1MemberKey113","v1MemberKey118","v1MemberKey132","v1MemberKey133","v1MemberKey134","v1MemberKey135","v1MemberKey136","v1MemberKey139","v1MemberKey147","v1MemberKey151","v1MemberKey170","v1MemberKey171","v1MemberKey180","v1MemberKey183","v1MemberKey195","v1MemberKey196","v1MemberKey203","v1MemberKey212","v1MemberKey215","v1MemberKey216","v1MemberKey217","v1MemberKey220","v1MemberKey221","v1MemberKey225","v1MemberKey228","v1MemberKey230","v1MemberKey232","v1MemberKey233","v1MemberKey236","v1MemberKey238","v1MemberKey240","v1MemberKey244","v1MemberKey252","v1MemberKey253","v1MemberKey262","v1MemberKey269","v1MemberKey272","v1MemberKey275","v1MemberKey284","v1MemberKey289","v1MemberKey305","v1MemberKey308","v1MemberKey317","v1MemberKey323","v1MemberKey324","v1MemberKey334","v1MemberKey348","v1MemberKey351","isArrayValue","isRecordValue","isStringValue","isBooleanValue","isFunctionValue","unicodeCodePointLength","isNumberValue","isNonNegativeInteger","isNullValue","is","hasOwn","hasOwnIndex","hasOnlyKeys","allowedKeys","allowed","freezeV1Value","V1_SHARED_LITERAL_020","V1_SHARED_LITERAL_024","INGEST_ORIGIN","assets","V1_ENDPOINT_PATHS","V2_ENDPOINT_PATHS","readV1SharedText","RFC3339_PATTERN","fail","field","parseV1ExactTimestamp","maximumUnicodeScalars","scalarLength","year","day","hour","minute","second","fractionalDigits","offsetHour","offsetMinute","daysInMonth","getUTCDate","local","setUTCHours","epochSecond","leapSecond","nextUtcSecond","getUTCHours","getUTCMinutes","getUTCSeconds","getUTCMonth","epochDay","splitEpochSecond","V1_NO_REPLAY_CAPABILITY","sampled","SENSITIVE_INPUT_TYPES","IMAGE_CONTENT_ATTRIBUTES","IMAGE_TAG_NAMES","isRecord","maskAttributes","profile","masked","inputType","inputRule","imageRule","maskNode","textRule","maskMutation","maskV2BrowserDomEvent","SHA256_HEX_PATTERN","defaultV2ReplaySha256","cryptoApi","crypto","subtle","digest","hexadecimal","byte","padStart","sha256Hex","sha256","_x2","_x3","isV2Sha256Hash","utf8Encode","TextEncoder","V2ReplayPayloadAdmissionError","V2MaskingProfileError","V2MaskingProofError","V2ReplayRequestError","V2_REPLAY_PAYLOAD_LIMITS","maximumReplayDecodedBytes","maximumJsonNestingDepth","assertUnicode","isOmittedValue","maximumNestingDepth","state","containerDepth","isPlainObject","sort","members","member","canonicalV2JsonValue","V2_BROWSER_MASKING_DIALECT","PROFILE_KEYS","TEXT_RULES","INPUT_RULES","IMAGE_RULES","assertRule","assertSelector","normalizeSelectors","buildV2MaskingProfile","IMAGE_ELEMENT_SELECTORS","selectorList","denyFormValues","boundedPositive","openChunk","atMs","sequence","chunkStartedAtMs","chunkBytes","chunkEvents","V2_REPLAY_SEQUENCE_INDEX","RECORDS_STORE","base","keyPath","unique","wallNow","monotonicNowMs","clock","performance","NaN","u8","u16","u32","fleb","fdeb","clim","freb","eb","_a","fl","revfl","revfd","rev","hMap","cd","mb","co","le","rvb","sv","r_1","flt","fdt","flm","fdm","shft","wbits","wbits16","hTree","t","f","t2","i0","i1","i2","maxSym","tr","mbt","ln","dt","lft","cst","i2_1","i2_2","i2_3","lc","cl","cli","cln","cls","w","clen","cf","wfblk","out","dat","wblk","syms","lf","df","li","bs","bl","dlt","mlb","_b","ddt","mdb","_c","lclt","nlc","_d","lcdt","ndc","lcfreq","_e","lct","mlcb","nlcc","lm","ll","dm","dl","flen","ftlen","dtlen","llm","lcts","it","clct","dst","deo","crct","k","wbytes","gzipSync","cr","crc","pre","filename","lvl","plvl","post","lst","msk_1","bs1_1","bs2_1","hsh","lc_1","wi","hv","imod","pimod","rem","ch_1","dif","maxn","maxd","ml","nl","mmd","md","ti","lin","din","slc","dflt","level","mem","log","mtime","gzh","ALPHABET","decodeTable","fill","encodeBase64","triple","SEAL","V2MaskingProof","seal","profileHash","canonicalPayload","payloadByteLength","logicalRecords","nestingDepth","masker","_input$v1MemberKey","canonical","records","limits","utf8ByteLength","canonicalV2ReplayRecords","isV2MaskingProof","table","bit","V2_REPLAY_CONTRACT_VERSION","V2_MAX_REPLAY_REQUEST_BYTES","CODEC_PATTERN","RUNTIME_NAME_PATTERN","FACADE_NAME_PATTERN","BASE64_PATTERN","CHUNK_KEYS","IDENTITY_KEYS","PRIVACY_KEYS","VERSIONS_KEYS","NAMED_VERSION_KEYS","assertBoundedString","minimum","assertSafeCount","assertHash","assertKeys","optional","validateIdentity","identity","validatePrivacy","privacy","appliedBeforeSerialization","validateNamedVersion","namePattern","named","validateV2VersionContext","versions","runtime","facade","build","validateV2ReplayChunk","chunk","startedAt","endedAt","compareV1ExactTimestamps","maximumDigits","leftDigit","rightDigit","codec","contentEncoding","deriveV2ReplayRequestId","canonicalChunk","canonicalV2ReplayChunkBytes","domain","material","v2ReplayRequestIdentityMaterial","prepareV2ReplayRequest","replayChunkBytes","captureProtocolGeneration","limit","validated","request","canonicalRequest","canonicalRequestSha256","_x4","sealV2ReplayChunk","proof","compressed","compressedByteLength","decodedByteLength","encodeV2BrowserDomPayload","buildV2ReplayChunk","createV2ReplaySessionDriver","byteLimit","replayId","closedReplay","closePromise","closeReplay","originalReplayId","onReplayClosed","qualified","policy","emitted","held","heldBytes","ingressBytes","ingressCount","report","terminal","onSealFailure","discardHeld","stop","drainHeld","prepared","sink","discarded","sealOpen","closing","estimatedBytes","instant","startedAtMs","endedAtMs","decision","advanceV2ReplaySchedule","_state$chunkStartedAt","action","discardSealedChunk","idleForMs","sessionAgeMs","_state$v1MemberKey","sealedMs","sealedSequence","flush","hasBufferedWork","OWNER_PROPERTY","ownedRecord","owner","released","release","adapter","maximumEventBytes","maximumPendingBytes","maximumPendingEvents","resolveV2RecorderMaskingOptions","running","draining","acquiring","cleanupHealthy","stopEngine","unsubscribe","pendingEvents","pendingBytes","lastTimestamp","onFailure","capability","eligibility","eligible","detachEngine","detachSubscription","epoch","maskedTail","stopSubscription","subscribeToRestrictions","engine","_element$getAttribute","isolated","serialized","delivery","quiesce","cleanupIsProven","settled","createV2RecorderAdapter","installSessionDriver","isCurrent"],"mappings":"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StzC,IAAU,GAAK,EACxBhmB,EAASgmB,EAAQ,EAAIA,EAAQ,EAAc,KAAVA,EAAe,IAAqC,GAAf,GAAL,EAARA,IAAmBszC,GAAavB,EAAKuB,GAC9FC,EAAiBjB,EAAOO,GAC1BU,EAAiB,IAAIhC,IACzB,IAAMiC,GAAiBD,IAAmB,GAAK,EACzCE,EAAWF,EAAiB,EAAIA,EAAiB,EAAoD,GAAvB,GAAL,EAAjBA,IAA4BC,GAAqBzB,EAAKyB,IAChHC,EAAW3B,GAAWA,EAAU93D,EAASq3D,IAAeE,IAE5D,IAAK,IAAIvxC,EAAQ,EAAGA,EAAQhmB,EAAQgmB,IAAW/U,EAAO6mD,GAAW7mD,EAAO6mD,EAAU2B,GAAW3B,GACjG,CACJ,CACJ,CACJ,CAEIA,IAAYT,GAAiB1+C,KAAKg2C,KAAKzyC,EAAW,KAAOusC,EAAMzoD,QAAQu3D,IAG3E,IAFA,IAAImC,EAAU,GAELnuC,EAAS,EAAGA,EAASusC,EAASvsC,GAAU,KAAMmuC,GAAWz0D,OAAOw3B,aAAan2B,MAAM,KAAM2K,EAAO0nD,SAASptC,EAAQ5S,KAAKC,IAAI2S,EAAS,KAAMusC,KAClJ,IAAM7qB,EAAiB3jC,KAAKilB,MAAMmrC,GAElC,OADKtzD,MAAM+kB,QAAQ8hB,IAAUA,EAAMjtC,SAAWs3D,IAAiBrqB,EAAMl0B,MAAK3M,GAAwB,iBAATA,KAAoBmrD,IACtG72D,OAAOmxC,OAAO5E,EAAkB,E,G,I,K,G,G,+4c,M,O,G,I,G,G,miG,K,K,G,G,G,G,G,I,G,G,G,G,G,G,G,G,G,G,G,G,I,G,G,G,G,G,G,G,G,G,I,G,I,G,I,G,I,G,I,G,I,G,I,G,I,G,I,G,I,G,I,G,I,I,G,G,I,G,G,I,G,I,G,I,G,I,G,I,G,I,G,I,G,I,G,I,G,I,G,I,I,G,G,I,G,I,G,I,I,G,G,I,G,G,I,G,I,G,I,G,I,G,I,G,I,G,I,I,G,G,I,G,I,G,I,I,G,G,I,G,I,G,I,G,I,I,G,G,I,G,G,I,G,I,G,I,G,I,G,I,G,I,G,I,I,G,G,I,G,I,G,I,G,I,G,I,I,G,G,I,G,I,I,G,G,I,G,I,G,I,G,I,G,I,G,I,G,I,G,I,G,I,G,I,G,I,G,I,G,I,G,I,I,G,G,I,G,I,I,G,G,I,G,I,I,G,G,I,G,G,I,G,I,G,I,G,I,G,I,I,G,G,I,G,I,G,I,G,I,I,G,G,I,G,I,G,I,G,I,G,I,G,K,G,K,G,K,G,K,G,K,G,K,G,K,G,K,G,K,G,K,G,K,I,G,G,K,G,K,I,G,G,K,G,K,G,K,G,K,G,K,I,G,G,K,G,K,G,K,G,K,G,K,G,K,G,K,G,K,G,K,G,K,G,K,G,K,G,K,G,K,I,G,G,K,G,G,K,G,G,K,G,G,K,G,G,K,G,K,G,K,I,G,G,K,G,K,G,K,G,K,G,K,G,K,G,K,G,K,I,G,G,K,G,K,G,K,G,K,I,G,G,K,G,K,G,K,G,K,G,K,G,K,G,K,G,K,G,K,G,K,G,K,G,K,G,K,G,K,G,K,G,K,G,K,G,K,G,K,I,G,G,K,G,G,K,G,K,G,K,G,K,G,K,G,K,G,K,G,K,G,K,I,G,G,K,G,K,G,K,I,G,G,K,G,K,G,K,G,K,G,K,G,K,G,K,G,K,G,K,G,K,G,K,G,K,I,G,G,K,G,G,K,G,K,G,K,G,K,G,K,G,K,G,K,I,G,G,K,G,K,G,K,G,K,G,K,G,K,G,K,G,K,G,K,I,G,G,K,G,K,G,K,I,G,G,K,G,G,K,G,G,K,G,K,G,K,I,G,G,K,G,G,K,G,K,G,K,G,K,I,G,G,K,G,K,G,K,I,G,G,K,G,K,I,G,G,K,G,K,I,G,G,K,G,G,K,G,K,G,K,I,G,G,K,G,K,I,G,G,K,G,K,I,G,G,K,G,K,G,K,G,K,I,G,G,K,G,K,G,K,G,K,G,K,G,K,G,K,G,K,I,G,G,K,G,G,K,G,K,G,K,G,K,G,K,G,K,G,K,G,K,G,K,I,G,G,K,G,K,G,K,G,K,G,K,G,K,G,K,I,G,G,K,G,K,G,K,I,G,G,K,G,K,G,K,I,G,G,K,G,K,G,K,G,K,G,K,G,K,G,K,G,K,G,K,I,G,G,K,G,K,G,K,G,K,G,K,I,G,G,K,G,K,G,K,G,K,G,K,G,K,G,K,G,K,G,K,G,K,G,K,G,K,G,K,G,K,G,K,G,K,I,G,G,K,G,K,G,K,I,G,G,K,G,K,G,K,G,K,G,K,G,K,G,K,G,K,G,K,I,G,G,K,G,K,G,K,G,K,G,K,G,K,I,G,G,K,G,G,K,G,K,G,K,G,K,G,K,G,K,G,K,G,K,G,K,G,K,I,G,G,K,G,K,G,K,G,K,G,K,G,K,G,K,G,K,G,K,G,K,G,K,G,K,G,K,G,K,I,G,G,K,G,K,G,K,I,G,G,K,G,KC1J3C,IAAQ9hB,GAAY/kB,MAAZ+kB,QACKkzC,GAAgB79D,GAAuC2qB,GAAQ3qB,GAE/D89D,GAAiB99D,GACT,iBAAVA,GAA+B,MAATA,IAAkB69D,GAAa79D,GAEnD+9D,GAAiB/9D,GAAqD,iBAAVA,EAE5Dg+D,GAAkBh+D,IAA+C,IAAVA,IAA4B,IAAVA,EAEzEi+D,GAAmBj+D,GAEnB,mBADMA,EAQNk+D,GAA0Bl+D,IAEnC,IADA,IAAIR,EAAS,EACJgmB,EAAQ,EAAGA,EAAQxlB,E,IAAcwlB,GAAS,EAAG,CAClD,IAAMQ,EAAOhmB,E,IAAiBwlB,GAC9B,GAAIQ,GAAQ,OAAUA,GAAQ,MAAQ,CAClC,IAAMzgB,EAAOvF,E,IAAiBwlB,EAAQ,GACtC,GAAIA,EAAQ,GAAKxlB,E,KAAgBuF,EAAO,OAAUA,EAAO,MACrD,OAAO,KAEXigB,GAAS,CACb,MAAO,GAAIQ,GAAQ,OAAUA,GAAQ,MACjC,OAAO,KAEXxmB,GAAU,CACd,CACA,OAAOA,CAAM,EAGJ2+D,GAAiBn+D,GAEjB,iBADMA,GAEA84C,O,IAAgB94C,GAMtBo+D,GAAwBp+D,GACjCm+D,GAAcn+D,IAAU84C,O,IAAqB94C,IAAUA,GAAS,EAEvDq+D,GAAer+D,GAAkCE,OAAOo+D,GAAGt+D,EAAO,MAElEu+D,GAASA,CAACv+D,EAAgCD,IACnDG,OAAOmC,U,IAAyBqC,KAAK1E,EAAOD,GAEnCy+D,GAAcA,CAACx+D,EAA2BwlB,IACnDtlB,OAAOmC,U,IAAyBqC,KAAK1E,EAAOwlB,GAEnCi5C,GAAcA,CAACz+D,EAAgC0+D,KACxD,IAAMC,EAAU,IAAI5xB,IAAI2xB,GACxB,OAAOx+D,OAAOoK,KAAKtK,GAAO0C,OAAO3C,GAAQ4+D,EAAQ7zD,IAAI/K,IAAK,EAwDjD6+D,GAA0C5+D,GAA0BE,OAAOmxC,OAAOrxC,G,G,G,2nD,K,I,G,G,G,G,G,G,G,G,G,G,G,G,G,G,G,G,G,G,G,G,G,I,G,I,G,I,G,I,G,I,G,I,G,I,G,I,G,I,I,G,G,I,G,I,G,I,G,I,I,G,G,I,G,I,G,I,G,I,G,I,G,I,G,I,G,I,G,I,G,I,G,I,G,I,G,I,G,I,G,I,G,I,G,I,G,I,G,I,G,I,G,I,G,I,G,I,G,I,G,I,G,I,G,I,G,I,G,I,G,I,G,I,G,I,G,I,G,I,G,I,G,I,G,I,G,I,G,I,G,I,G,I,G,I,G,I,G,I,G,I,G,I,G,I,G,I,G,I,G,I,G,I,G,I,G,I,G,I,G,I,G,I,G,I,G,I,G,I,G,I,G,I,G,IC3F/F,IAAM++D,G,yBAkB2FH,GAAc,C,C,IACnGA,GAAc,CAACG,K,C,IACfH,GAAc,CAACG,K,C,IAChBH,GAAc,CAACG,KACtBC,OAAQJ,GAAc,C,6BAEnB,I,GAAMK,GAA8DL,GAAc,C,C,IAC7E,a,C,IACA,a,C,IACD,YACPI,OAAQ,UAOCE,GAA8DN,GAAc,C,C,IAC7E,a,C,IACA,a,C,IACD,YACPI,OAAQ,UAIRJ,GAAc,CAAE,EAAGK,GAAmB,EAAGC,KAC4CN,GAAc,CACnG,EAAG,WACH,EAAG,a,I,G,I,K,G,G,2gD,K,K,G,ICpEDQ,GAAkB,iGAYlBC,GAAOA,CAACC,EAAer7C,KACzB,MAAM,IAAIzlB,MAAS8gE,EAAK,IAAIr7C,EAAU,EAc7Bs7C,GAAwB,SACjCv/D,EACAs/D,EACAE,GACmB,IAAA9hD,EACnB,IAAKqgD,GAAc/9D,GAAQ,OAAOq/D,GAAKC,E,G,KACvC,IAAMG,EAAevB,GAAuBl+D,GAC5C,GAAIq+D,GAAYoB,IAAiBA,EAAe,GAAKA,EAAeD,EAChE,OAAOH,GAAKC,EAAK,8BAAgCE,sBAErD,IAAMlvD,EAAQ8uD,GAAgB7uD,KAAKvQ,GACnC,IAAKsQ,EAAO,OAAO+uD,GAAKC,E,G,KACxB,IAAMI,EAAO5mB,OAAOxoC,EAAM,IACpBwiD,EAAQha,OAAOxoC,EAAM,IACrBqvD,EAAM7mB,OAAOxoC,EAAM,IACnBsvD,EAAO9mB,OAAOxoC,EAAM,IACpBuvD,EAAS/mB,OAAOxoC,EAAM,IACtBwvD,EAAShnB,OAAOxoC,EAAM,IACtByvD,UAAmBriD,EAACpN,E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","x_google_ignoreList":[6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,47,71]}
|