@himetrica/replaykit 0.1.0 → 0.2.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/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/replaykit.global.js +3 -3
- package/dist/replaykit.global.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../node_modules/@rrweb/types/dist/types.js","../node_modules/@rrweb/utils/dist/utils.js","../node_modules/@rrweb/rrweb-snapshot/src/utils.ts","../node_modules/@rrweb/rrweb-snapshot/src/snapshot.ts","../node_modules/@rrweb/rrdom/src/document.ts","../node_modules/@rrweb/rrweb/src/utils.ts","../node_modules/@rrweb/rrweb/src/record/mutation.ts","../node_modules/@rrweb/rrweb/src/record/error-handler.ts","../node_modules/@rrweb/rrweb/src/record/observer.ts","../node_modules/@rrweb/rrweb/src/record/cross-origin-iframe-mirror.ts","../node_modules/@rrweb/rrweb/src/record/iframe-manager.ts","../node_modules/@rrweb/rrweb/src/record/shadow-dom-manager.ts","../node_modules/node_modules/base64-arraybuffer/dist/base64-arraybuffer.es5.js","../node_modules/@rrweb/rrweb/src/record/observers/canvas/serialize-args.ts","../node_modules/@rrweb/rrweb/src/record/observers/canvas/2d.ts","../node_modules/@rrweb/rrweb/src/record/observers/canvas/canvas.ts","../node_modules/@rrweb/rrweb/src/record/observers/canvas/webgl.ts","../node_modules/@rrweb/rrweb/src/record/observers/canvas/canvas-manager.ts","../node_modules/@rrweb/rrweb/src/record/stylesheet-manager.ts","../node_modules/@rrweb/rrweb/src/record/processed-node-manager.ts","../node_modules/@rrweb/rrweb/src/record/index.ts","../src/index.ts","../src/state.ts","../src/env.ts","../src/identity.ts","../src/match.ts","../src/buffer.ts","../src/detect.ts","../src/decide.ts","../src/transport.ts","../src/signal-queue.ts","../src/signals-dom.ts","../src/recorder.ts","../src/uploader.ts","../src/client.ts","../src/global.ts"],"sourcesContent":["var EventType = /* @__PURE__ */ ((EventType2) => {\n EventType2[EventType2[\"DomContentLoaded\"] = 0] = \"DomContentLoaded\";\n EventType2[EventType2[\"Load\"] = 1] = \"Load\";\n EventType2[EventType2[\"FullSnapshot\"] = 2] = \"FullSnapshot\";\n EventType2[EventType2[\"IncrementalSnapshot\"] = 3] = \"IncrementalSnapshot\";\n EventType2[EventType2[\"Meta\"] = 4] = \"Meta\";\n EventType2[EventType2[\"Custom\"] = 5] = \"Custom\";\n EventType2[EventType2[\"Plugin\"] = 6] = \"Plugin\";\n EventType2[EventType2[\"Asset\"] = 7] = \"Asset\";\n return EventType2;\n})(EventType || {});\nvar IncrementalSource = /* @__PURE__ */ ((IncrementalSource2) => {\n IncrementalSource2[IncrementalSource2[\"Mutation\"] = 0] = \"Mutation\";\n IncrementalSource2[IncrementalSource2[\"MouseMove\"] = 1] = \"MouseMove\";\n IncrementalSource2[IncrementalSource2[\"MouseInteraction\"] = 2] = \"MouseInteraction\";\n IncrementalSource2[IncrementalSource2[\"Scroll\"] = 3] = \"Scroll\";\n IncrementalSource2[IncrementalSource2[\"ViewportResize\"] = 4] = \"ViewportResize\";\n IncrementalSource2[IncrementalSource2[\"Input\"] = 5] = \"Input\";\n IncrementalSource2[IncrementalSource2[\"TouchMove\"] = 6] = \"TouchMove\";\n IncrementalSource2[IncrementalSource2[\"MediaInteraction\"] = 7] = \"MediaInteraction\";\n IncrementalSource2[IncrementalSource2[\"StyleSheetRule\"] = 8] = \"StyleSheetRule\";\n IncrementalSource2[IncrementalSource2[\"CanvasMutation\"] = 9] = \"CanvasMutation\";\n IncrementalSource2[IncrementalSource2[\"Font\"] = 10] = \"Font\";\n IncrementalSource2[IncrementalSource2[\"Log\"] = 11] = \"Log\";\n IncrementalSource2[IncrementalSource2[\"Drag\"] = 12] = \"Drag\";\n IncrementalSource2[IncrementalSource2[\"StyleDeclaration\"] = 13] = \"StyleDeclaration\";\n IncrementalSource2[IncrementalSource2[\"Selection\"] = 14] = \"Selection\";\n IncrementalSource2[IncrementalSource2[\"AdoptedStyleSheet\"] = 15] = \"AdoptedStyleSheet\";\n IncrementalSource2[IncrementalSource2[\"CustomElement\"] = 16] = \"CustomElement\";\n return IncrementalSource2;\n})(IncrementalSource || {});\nvar MouseInteractions = /* @__PURE__ */ ((MouseInteractions2) => {\n MouseInteractions2[MouseInteractions2[\"MouseUp\"] = 0] = \"MouseUp\";\n MouseInteractions2[MouseInteractions2[\"MouseDown\"] = 1] = \"MouseDown\";\n MouseInteractions2[MouseInteractions2[\"Click\"] = 2] = \"Click\";\n MouseInteractions2[MouseInteractions2[\"ContextMenu\"] = 3] = \"ContextMenu\";\n MouseInteractions2[MouseInteractions2[\"DblClick\"] = 4] = \"DblClick\";\n MouseInteractions2[MouseInteractions2[\"Focus\"] = 5] = \"Focus\";\n MouseInteractions2[MouseInteractions2[\"Blur\"] = 6] = \"Blur\";\n MouseInteractions2[MouseInteractions2[\"TouchStart\"] = 7] = \"TouchStart\";\n MouseInteractions2[MouseInteractions2[\"TouchMove_Departed\"] = 8] = \"TouchMove_Departed\";\n MouseInteractions2[MouseInteractions2[\"TouchEnd\"] = 9] = \"TouchEnd\";\n MouseInteractions2[MouseInteractions2[\"TouchCancel\"] = 10] = \"TouchCancel\";\n return MouseInteractions2;\n})(MouseInteractions || {});\nvar PointerTypes = /* @__PURE__ */ ((PointerTypes2) => {\n PointerTypes2[PointerTypes2[\"Mouse\"] = 0] = \"Mouse\";\n PointerTypes2[PointerTypes2[\"Pen\"] = 1] = \"Pen\";\n PointerTypes2[PointerTypes2[\"Touch\"] = 2] = \"Touch\";\n return PointerTypes2;\n})(PointerTypes || {});\nvar CanvasContext = /* @__PURE__ */ ((CanvasContext2) => {\n CanvasContext2[CanvasContext2[\"2D\"] = 0] = \"2D\";\n CanvasContext2[CanvasContext2[\"WebGL\"] = 1] = \"WebGL\";\n CanvasContext2[CanvasContext2[\"WebGL2\"] = 2] = \"WebGL2\";\n return CanvasContext2;\n})(CanvasContext || {});\nvar MediaInteractions = /* @__PURE__ */ ((MediaInteractions2) => {\n MediaInteractions2[MediaInteractions2[\"Play\"] = 0] = \"Play\";\n MediaInteractions2[MediaInteractions2[\"Pause\"] = 1] = \"Pause\";\n MediaInteractions2[MediaInteractions2[\"Seeked\"] = 2] = \"Seeked\";\n MediaInteractions2[MediaInteractions2[\"VolumeChange\"] = 3] = \"VolumeChange\";\n MediaInteractions2[MediaInteractions2[\"RateChange\"] = 4] = \"RateChange\";\n return MediaInteractions2;\n})(MediaInteractions || {});\nvar ReplayerEvents = /* @__PURE__ */ ((ReplayerEvents2) => {\n ReplayerEvents2[\"Start\"] = \"start\";\n ReplayerEvents2[\"Pause\"] = \"pause\";\n ReplayerEvents2[\"Resume\"] = \"resume\";\n ReplayerEvents2[\"Resize\"] = \"resize\";\n ReplayerEvents2[\"Finish\"] = \"finish\";\n ReplayerEvents2[\"FullsnapshotRebuilded\"] = \"fullsnapshot-rebuilded\";\n ReplayerEvents2[\"LoadStylesheetStart\"] = \"load-stylesheet-start\";\n ReplayerEvents2[\"LoadStylesheetEnd\"] = \"load-stylesheet-end\";\n ReplayerEvents2[\"SkipStart\"] = \"skip-start\";\n ReplayerEvents2[\"SkipEnd\"] = \"skip-end\";\n ReplayerEvents2[\"MouseInteraction\"] = \"mouse-interaction\";\n ReplayerEvents2[\"EventCast\"] = \"event-cast\";\n ReplayerEvents2[\"CustomEvent\"] = \"custom-event\";\n ReplayerEvents2[\"Flush\"] = \"flush\";\n ReplayerEvents2[\"StateChange\"] = \"state-change\";\n ReplayerEvents2[\"PlayBack\"] = \"play-back\";\n ReplayerEvents2[\"Destroy\"] = \"destroy\";\n return ReplayerEvents2;\n})(ReplayerEvents || {});\nvar NodeType = /* @__PURE__ */ ((NodeType2) => {\n NodeType2[NodeType2[\"Document\"] = 0] = \"Document\";\n NodeType2[NodeType2[\"DocumentType\"] = 1] = \"DocumentType\";\n NodeType2[NodeType2[\"Element\"] = 2] = \"Element\";\n NodeType2[NodeType2[\"Text\"] = 3] = \"Text\";\n NodeType2[NodeType2[\"CDATA\"] = 4] = \"CDATA\";\n NodeType2[NodeType2[\"Comment\"] = 5] = \"Comment\";\n return NodeType2;\n})(NodeType || {});\nexport {\n CanvasContext,\n EventType,\n IncrementalSource,\n MediaInteractions,\n MouseInteractions,\n NodeType,\n PointerTypes,\n ReplayerEvents\n};\n//# sourceMappingURL=types.js.map\n","const testableAccessors = {\n Node: [\n \"childNodes\",\n \"parentNode\",\n \"parentElement\",\n \"textContent\",\n \"ownerDocument\",\n \"firstChild\",\n \"lastChild\",\n \"nextSibling\",\n \"previousSibling\"\n ],\n ShadowRoot: [\"host\", \"styleSheets\"],\n Element: [\"shadowRoot\", \"querySelector\", \"querySelectorAll\"],\n MutationObserver: []\n};\nconst testableMethods = {\n Node: [\"contains\", \"getRootNode\"],\n ShadowRoot: [\"getSelection\"],\n Element: [],\n MutationObserver: [\"constructor\"]\n};\nconst untaintedBasePrototype = {};\nconst untaintedBaseIframeCleanup = {};\nconst isAngularZonePresent = () => {\n return !!globalThis.Zone;\n};\nfunction getUntaintedPrototype(key) {\n if (untaintedBasePrototype[key])\n return untaintedBasePrototype[key];\n const defaultObj = globalThis[key];\n const defaultPrototype = defaultObj.prototype;\n const accessorNames = key in testableAccessors ? testableAccessors[key] : void 0;\n const isUntaintedAccessors = Boolean(\n accessorNames && // @ts-expect-error 2345\n accessorNames.every(\n (accessor) => {\n var _a, _b;\n return Boolean(\n (_b = (_a = Object.getOwnPropertyDescriptor(defaultPrototype, accessor)) == null ? void 0 : _a.get) == null ? void 0 : _b.toString().includes(\"[native code]\")\n );\n }\n )\n );\n const methodNames = key in testableMethods ? testableMethods[key] : void 0;\n const isUntaintedMethods = Boolean(\n methodNames && methodNames.every(\n // @ts-expect-error 2345\n (method) => {\n var _a;\n return typeof defaultPrototype[method] === \"function\" && ((_a = defaultPrototype[method]) == null ? void 0 : _a.toString().includes(\"[native code]\"));\n }\n )\n );\n if (isUntaintedAccessors && isUntaintedMethods && !isAngularZonePresent()) {\n untaintedBasePrototype[key] = defaultObj.prototype;\n return defaultObj.prototype;\n }\n try {\n const iframeEl = document.createElement(\"iframe\");\n iframeEl.style.display = \"none\";\n document.body.appendChild(iframeEl);\n const win = iframeEl.contentWindow;\n if (!win) return defaultObj.prototype;\n const untaintedObject = win[key].prototype;\n if (!untaintedObject) {\n iframeEl.remove();\n return defaultPrototype;\n }\n const ua = navigator.userAgent;\n if (ua.includes(\"Safari\") && !ua.includes(\"Chrome\")) {\n iframeEl.classList.add(\"rr-block\");\n iframeEl.setAttribute(\"__rrwebUntaintedMutationObserver\", \"\");\n untaintedBaseIframeCleanup[key] = () => iframeEl.remove();\n } else {\n iframeEl.remove();\n }\n return untaintedBasePrototype[key] = untaintedObject;\n } catch {\n return defaultPrototype;\n }\n}\nconst untaintedAccessorCache = {};\nfunction getUntaintedAccessor(key, instance, accessor) {\n var _a, _b;\n const cached = (_a = untaintedAccessorCache[key]) == null ? void 0 : _a[accessor];\n if (cached) return cached.call(instance);\n const untaintedPrototype = getUntaintedPrototype(key);\n const untaintedAccessor = (_b = Object.getOwnPropertyDescriptor(\n untaintedPrototype,\n accessor\n )) == null ? void 0 : _b.get;\n if (!untaintedAccessor) return instance[accessor];\n (untaintedAccessorCache[key] || (untaintedAccessorCache[key] = {}))[accessor] = untaintedAccessor;\n return untaintedAccessor.call(instance);\n}\nconst untaintedMethodCache = {};\nfunction getUntaintedMethod(key, instance, method) {\n const cacheKey = `${key}.${String(method)}`;\n if (untaintedMethodCache[cacheKey])\n return untaintedMethodCache[cacheKey].bind(\n instance\n );\n const untaintedPrototype = getUntaintedPrototype(key);\n const untaintedMethod = untaintedPrototype[method];\n if (typeof untaintedMethod !== \"function\") return instance[method];\n untaintedMethodCache[cacheKey] = untaintedMethod;\n return untaintedMethod.bind(instance);\n}\nfunction ownerDocument(n) {\n return getUntaintedAccessor(\"Node\", n, \"ownerDocument\");\n}\nfunction childNodes(n) {\n return getUntaintedAccessor(\"Node\", n, \"childNodes\");\n}\nfunction parentNode(n) {\n return getUntaintedAccessor(\"Node\", n, \"parentNode\");\n}\nfunction parentElement(n) {\n return getUntaintedAccessor(\"Node\", n, \"parentElement\");\n}\nfunction textContent(n) {\n return getUntaintedAccessor(\"Node\", n, \"textContent\");\n}\nfunction firstChild(n) {\n return getUntaintedAccessor(\"Node\", n, \"firstChild\");\n}\nfunction lastChild(n) {\n return getUntaintedAccessor(\"Node\", n, \"lastChild\");\n}\nfunction nextSibling(n) {\n return getUntaintedAccessor(\"Node\", n, \"nextSibling\");\n}\nfunction previousSibling(n) {\n return getUntaintedAccessor(\"Node\", n, \"previousSibling\");\n}\nfunction contains(n, other) {\n return getUntaintedMethod(\"Node\", n, \"contains\")(other);\n}\nfunction getRootNode(n) {\n return getUntaintedMethod(\"Node\", n, \"getRootNode\")();\n}\nfunction host(n) {\n if (!n || !(\"host\" in n)) return null;\n return getUntaintedAccessor(\"ShadowRoot\", n, \"host\");\n}\nfunction styleSheets(n) {\n return n.styleSheets;\n}\nfunction shadowRoot(n) {\n if (!n || !(\"shadowRoot\" in n)) return null;\n return getUntaintedAccessor(\"Element\", n, \"shadowRoot\");\n}\nfunction querySelector(n, selectors) {\n return getUntaintedAccessor(\"Element\", n, \"querySelector\")(selectors);\n}\nfunction querySelectorAll(n, selectors) {\n return getUntaintedAccessor(\"Element\", n, \"querySelectorAll\")(selectors);\n}\nfunction mutationObserverCtor() {\n return [\n getUntaintedPrototype(\"MutationObserver\").constructor,\n untaintedBaseIframeCleanup[\"MutationObserver\"] ?? (() => {\n })\n ];\n}\nlet nowTimestamp = Date.now;\nif (!/* @__PURE__ */ /[1-9][0-9]{12}/.test(Date.now().toString())) {\n nowTimestamp = () => (/* @__PURE__ */ new Date()).getTime();\n}\nfunction patch(source, name, replacement) {\n try {\n if (!(name in source)) {\n return () => {\n };\n }\n const original = source[name];\n const wrapped = replacement(original);\n if (typeof wrapped === \"function\") {\n wrapped.prototype = wrapped.prototype || {};\n Object.defineProperties(wrapped, {\n __rrweb_original__: {\n enumerable: false,\n value: original\n }\n });\n }\n source[name] = wrapped;\n return () => {\n source[name] = original;\n };\n } catch {\n return () => {\n };\n }\n}\nconst index = {\n ownerDocument,\n childNodes,\n parentNode,\n parentElement,\n textContent,\n firstChild,\n lastChild,\n nextSibling,\n previousSibling,\n contains,\n getRootNode,\n host,\n styleSheets,\n shadowRoot,\n querySelector,\n querySelectorAll,\n nowTimestamp,\n mutationObserverCtor,\n patch\n};\nexport {\n childNodes,\n contains,\n index as default,\n firstChild,\n getRootNode,\n getUntaintedAccessor,\n getUntaintedMethod,\n getUntaintedPrototype,\n host,\n isAngularZonePresent,\n lastChild,\n mutationObserverCtor,\n nextSibling,\n nowTimestamp,\n ownerDocument,\n parentElement,\n parentNode,\n patch,\n previousSibling,\n querySelector,\n querySelectorAll,\n shadowRoot,\n styleSheets,\n textContent\n};\n//# sourceMappingURL=utils.js.map\n","/**\n * Legacy shared utility module.\n *\n * This file currently contains helpers used by both snapshot and rebuild paths\n * and is also part of the public API surface, re-exported from index.ts.\n *\n * Migration intent:\n * - snapshot.ts should consume snapshot-domain helpers via snapshot-utils.ts\n * - rebuild.ts should consume rebuild-domain helpers via rebuild-utils.ts\n * - when safe, split internals into snapshot-only / rebuild-only / shared\n * modules while keeping this module as a compatibility shim for external users\n */\nimport type {\n idNodeMap,\n MaskInputFn,\n MaskInputOptions,\n nodeMetaMap,\n} from './types';\n\nimport { NodeType } from '@rrweb/types';\nimport type {\n IMirror,\n serializedNodeWithId,\n serializedNode,\n documentNode,\n documentTypeNode,\n textNode,\n elementNode,\n} from '@rrweb/types';\nimport dom from '@rrweb/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 * serialize the css rules from the .sheet property\n * for <link rel=\"stylesheet\"> elements, this is the only way of getting the rules without a FETCH\n * for <style> elements, this is less preferable to looking at childNodes[0].textContent\n * (which will include vendor prefixed rules which may not be used or visible to the recorded browser,\n * but which might be needed by the replayer browser)\n * however, at snapshot time, we don't know whether the style element has suffered\n * any programmatic manipulation prior to the snapshot, in which case the .sheet would be more up to date\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 (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 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 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 // 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}\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 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 filePathNoHash = filePath.split('#')[0];\n const maybeHash = filePath.substring(filePathNoHash.length);\n const stack = href.split('#')[0].split('/');\n const parts = filePathNoHash.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('/')}${maybeHash}${maybeQuote})`;\n },\n );\n}\n\nconst cssNormalizeBase = '(?:/\\\\*[^*]*\\\\*/)|[\\\\s;]'; // whitespace\nconst cssNormalizeRe = new RegExp(`${cssNormalizeBase}|\\\\b(0)px?`, 'g');\nconst cssNormalizeReNoPx = new RegExp(cssNormalizeBase, 'g');\n\n/**\n * Intention is to normalize by remove spaces, semicolons and CSS comments\n * so that we can compare css as authored vs. output of stringifyStylesheet\n */\nexport function normalizeCssString(\n cssText: string,\n /**\n * _testNoPxNorm: only used as part of the 'substring matching going from many to none'\n * test case so that it will trigger a failure if the conditions that let to the creation of that test arise again\n */\n _testNoPxNorm = false,\n): string {\n return _testNoPxNorm\n ? cssText.replace(cssNormalizeReNoPx, '')\n : cssText.replace(cssNormalizeRe, '$1');\n}\n\n/**\n * Maps the output of stringifyStylesheet to individual text nodes of a <style> element\n * which occurs when javascript is used to append to the style element\n * and may also occur when browsers opt to break up large text nodes\n * performance needs to be considered, see e.g. #1603\n */\nexport function splitCssText(\n cssText: string,\n style: HTMLStyleElement,\n _testNoPxNorm = false,\n): string[] {\n const childNodes = Array.from(style.childNodes);\n const splits: string[] = [];\n let iterCount = 0;\n if (childNodes.length > 1 && cssText && typeof cssText === 'string') {\n let cssTextNorm = normalizeCssString(cssText, _testNoPxNorm);\n const normFactor = cssTextNorm.length / cssText.length;\n for (let i = 1; i < childNodes.length; i++) {\n if (\n childNodes[i].textContent &&\n typeof childNodes[i].textContent === 'string'\n ) {\n const textContentNorm = normalizeCssString(\n childNodes[i].textContent!,\n _testNoPxNorm,\n );\n const jLimit = 100; // how many iterations for the first part of searching\n let j = 3;\n for (; j < textContentNorm.length; j++) {\n if (\n // keep consuming css identifiers (to get a decent chunk more quickly)\n textContentNorm[j].match(/[a-zA-Z0-9]/) ||\n // substring needs to be unique to this section\n textContentNorm.indexOf(textContentNorm.substring(0, j), 1) !== -1\n ) {\n continue;\n }\n break;\n }\n for (; j < textContentNorm.length; j++) {\n let startSubstring = textContentNorm.substring(0, j);\n // this substring should appears only once in overall text too\n let cssNormSplits = cssTextNorm.split(startSubstring);\n let splitNorm = -1;\n if (cssNormSplits.length === 2) {\n splitNorm = cssNormSplits[0].length;\n } else if (\n cssNormSplits.length > 2 &&\n cssNormSplits[0] === '' &&\n childNodes[i - 1].textContent !== ''\n ) {\n // this childNode has same starting content as previous\n splitNorm = cssTextNorm.indexOf(startSubstring, 1);\n } else if (cssNormSplits.length === 1) {\n // try to roll back to get multiple matches again\n startSubstring = startSubstring.substring(\n 0,\n startSubstring.length - 1,\n );\n cssNormSplits = cssTextNorm.split(startSubstring);\n if (cssNormSplits.length <= 1) {\n // no split possible\n splits.push(cssText);\n return splits;\n }\n j = jLimit + 1; // trigger end of search\n } else if (j === textContentNorm.length - 1) {\n // we're about to end loop without a split point\n splitNorm = cssTextNorm.indexOf(startSubstring);\n }\n if (cssNormSplits.length >= 2 && j > jLimit) {\n const prevTextContent = childNodes[i - 1].textContent;\n if (prevTextContent && typeof prevTextContent === 'string') {\n // pick the first matching point which respects the previous chunk's approx size\n const prevMinLength = normalizeCssString(prevTextContent).length;\n splitNorm = cssTextNorm.indexOf(startSubstring, prevMinLength);\n }\n if (splitNorm === -1) {\n // fall back to pick the first matching point of many\n splitNorm = cssNormSplits[0].length;\n }\n }\n if (splitNorm !== -1) {\n // find the split point in the original text\n let k = Math.floor(splitNorm / normFactor);\n for (; k > 0 && k < cssText.length; ) {\n iterCount += 1;\n if (iterCount > 50 * childNodes.length) {\n // quit for performance purposes\n splits.push(cssText);\n return splits;\n }\n const normPart = normalizeCssString(\n cssText.substring(0, k),\n _testNoPxNorm,\n );\n if (normPart.length === splitNorm) {\n splits.push(cssText.substring(0, k));\n cssText = cssText.substring(k);\n cssTextNorm = cssTextNorm.substring(splitNorm);\n break;\n } else if (normPart.length < splitNorm) {\n k += Math.max(\n 1,\n Math.floor((splitNorm - normPart.length) / normFactor),\n );\n } else {\n k -= Math.max(\n 1,\n Math.floor((normPart.length - splitNorm) * normFactor),\n );\n }\n }\n break;\n }\n }\n }\n }\n }\n splits.push(cssText); // either the full thing if no splits were found, or the last split\n return splits;\n}\n\nexport function markCssSplits(\n cssText: string,\n style: HTMLStyleElement,\n): string {\n return splitCssText(cssText, style).join('/* rr_split */');\n}\n","import type {\n MaskInputOptions,\n SlimDOMOptions,\n MaskTextFn,\n MaskInputFn,\n KeepIframeSrcFn,\n ICanvas,\n DialogAttributes,\n} from './types';\nimport { NodeType } from '@rrweb/types';\nimport type {\n serializedNode,\n serializedNodeWithId,\n serializedElementNodeWithId,\n elementNode,\n attributes,\n mediaAttributes,\n DataURLOptions,\n} from '@rrweb/types';\nimport {\n Mirror,\n is2DCanvasBlank,\n isElement,\n isShadowRoot,\n maskInputValue,\n isNativeShadowDom,\n stringifyStylesheet,\n getInputType,\n toLowerCase,\n extractFileExtension,\n absolutifyURLs,\n markCssSplits,\n} from './snapshot-utils';\nimport dom from '@rrweb/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]+/;\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 a.setAttribute('href', customHref);\n return a.href;\n}\n\nexport function transformAttribute(\n doc: Document,\n tagName: Lowercase<string>,\n name: Lowercase<string>,\n value: string | null,\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 // href starts with a # is an id pointer for svg\n return absoluteToDoc(doc, value);\n } else if (name === 'xlink:href' && value[0] !== '#') {\n // xlink:href starts with # is an id pointer\n return absoluteToDoc(doc, value);\n } else if (name === 'background' && ['table', 'td', 'th'].includes(tagName)) {\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: Lowercase<string>,\n name: string,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n _value: unknown,\n): boolean {\n return (\n ['video', 'audio'].includes(tagName) && toLowerCase(name) === 'autoplay'\n );\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;\n if (isElement(node)) {\n el = node;\n if (!dom.childNodes(el).length) {\n // optimisation: we can avoid any of the below checks on leaf elements\n // as masking is applied to child text nodes only\n return false;\n }\n } else if (dom.parentElement(node) === null) {\n // should warn? maybe a text node isn't attached to a parent node yet?\n return false;\n } else {\n el = dom.parentElement(node)!;\n }\n try {\n if (typeof maskTextClass === 'string') {\n if (checkAncestors) {\n if (el.closest(`.${maskTextClass}`)) return true;\n } else {\n if (el.classList.contains(maskTextClass)) return true;\n }\n } else {\n if (classMatchesRegex(el, maskTextClass, checkAncestors)) return true;\n }\n if (maskTextSelector) {\n if (checkAncestors) {\n if (el.closest(maskTextSelector)) return true;\n } else {\n if (el.matches(maskTextSelector)) return true;\n }\n }\n } catch (e) {\n //\n }\n return false;\n}\n\n// https://stackoverflow.com/a/36155560\nfunction onceIframeLoaded(\n iframeEl: HTMLIFrameElement,\n listener: () => unknown,\n iframeLoadTimeout: number,\n) {\n const win = iframeEl.contentWindow;\n if (!win) {\n return;\n }\n // document is loading\n let fired = false;\n\n let readyState: DocumentReadyState;\n try {\n readyState = win.document.readyState;\n } catch (error) {\n return;\n }\n if (readyState !== 'complete') {\n const timer = setTimeout(() => {\n if (!fired) {\n listener();\n fired = true;\n }\n }, iframeLoadTimeout);\n iframeEl.addEventListener('load', () => {\n clearTimeout(timer);\n fired = true;\n listener();\n });\n return;\n }\n // check blank frame for Chrome\n const blankUrl = 'about:blank';\n if (\n win.location.href !== blankUrl ||\n iframeEl.src === blankUrl ||\n iframeEl.src === ''\n ) {\n // iframe was already loaded, make sure we wait to trigger the listener\n // till _after_ the mutation that found this iframe has had time to process\n setTimeout(listener, 0);\n\n return iframeEl.addEventListener('load', listener); // keep listing for future loads\n }\n // use default listener\n iframeEl.addEventListener('load', listener);\n}\n\nfunction onceStylesheetLoaded(\n link: HTMLLinkElement,\n listener: () => unknown,\n styleSheetLoadTimeout: number,\n) {\n let fired = false;\n let styleSheetLoaded: StyleSheet | null;\n try {\n styleSheetLoaded = link.sheet;\n } catch (error) {\n return;\n }\n\n if (styleSheetLoaded) return;\n\n const timer = setTimeout(() => {\n if (!fired) {\n listener();\n fired = true;\n }\n }, styleSheetLoadTimeout);\n\n link.addEventListener('load', () => {\n clearTimeout(timer);\n fired = true;\n listener();\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 keepIframeSrcFn: KeepIframeSrcFn;\n /**\n * `newlyAddedElement: true` skips scrollTop and scrollLeft check\n */\n newlyAddedElement?: boolean;\n cssCaptured?: 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 keepIframeSrcFn,\n newlyAddedElement = false,\n cssCaptured = 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 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 cssCaptured,\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 cssCaptured?: boolean;\n },\n): serializedNode {\n const { needsMask, maskTextFn, rootId, cssCaptured } = 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 textContent: string | null = '';\n const isStyle = parentTagName === 'STYLE' ? true : undefined;\n const isScript = parentTagName === 'SCRIPT' ? true : undefined;\n if (isScript) {\n textContent = 'SCRIPT_PLACEHOLDER';\n } else if (!cssCaptured) {\n textContent = dom.textContent(n);\n if (isStyle && textContent) {\n // mutation only: we don't need to use stringifyStylesheet\n // as a <style> text node mutation obliterates any previous\n // programmatic rule manipulation (.insertRule etc.)\n // so the current textContent represents the most up to date state\n textContent = absolutifyURLs(textContent, getHref(options.doc));\n }\n }\n if (!isStyle && !isScript && textContent && needsMask) {\n textContent = maskTextFn\n ? maskTextFn(textContent, dom.parentElement(n))\n : textContent.replace(/[\\S]/g, '*');\n }\n\n return {\n type: NodeType.Text,\n textContent: textContent || '',\n rootId,\n };\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 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 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 }\n // remote css\n if (tagName === 'link' && inlineStylesheet) {\n //TODO: maybe replace this `.styleSheets` with original one\n const stylesheet = Array.from(doc.styleSheets).find((s) => {\n return s.href === (n as HTMLLinkElement).href;\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 if (tagName === 'style' && (n as HTMLStyleElement).sheet) {\n let cssText = stringifyStylesheet(\n (n as HTMLStyleElement).sheet as CSSStyleSheet,\n );\n if (cssText) {\n if (n.childNodes.length > 1) {\n cssText = markCssSplits(cssText, n as HTMLStyleElement);\n }\n attributes._cssText = cssText;\n }\n }\n // form fields\n if (['input', 'textarea', 'select'].includes(tagName)) {\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 (attributes as DialogAttributes).rr_open_mode = n.matches('dialog:modal')\n ? 'modal'\n : 'non-modal';\n }\n\n // canvas image data\n if (tagName === 'canvas' && recordCanvas) {\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 image.removeEventListener('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 (['audio', 'video'].includes(tagName)) {\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 } = n.getBoundingClientRect();\n attributes = {\n class: attributes.class,\n rr_width: `${width}px`,\n rr_height: `${height}px`,\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\nexport function slimDOMDefaults(\n _slimDOMOptions: SlimDOMOptions | 'all' | true | false | undefined,\n) {\n if (_slimDOMOptions === true || _slimDOMOptions === 'all') {\n // if true: set of sensible options that should not throw away any information\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 // the following are off for slimDOMOptions === true,\n // as they destroy some (hidden) info:\n headMetaAuthorship: _slimDOMOptions === 'all',\n headMetaDescKeywords: _slimDOMOptions === 'all',\n headTitleMutations: _slimDOMOptions === 'all',\n };\n } else if (_slimDOMOptions) {\n return _slimDOMOptions;\n }\n return {};\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 lowerIfExists(sn.attributes.rel) === 'icon' ||\n lowerIfExists(sn.attributes.rel) === 'apple-touch-icon' ||\n lowerIfExists(sn.attributes.rel) === 'shortcut icon')))\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 (lowerIfExists(sn.attributes.name) === 'robots' ||\n lowerIfExists(sn.attributes.name) === 'googlebot' ||\n lowerIfExists(sn.attributes.name) === 'bingbot')\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 (lowerIfExists(sn.attributes.name) === 'author' ||\n lowerIfExists(sn.attributes.name) === 'generator' ||\n lowerIfExists(sn.attributes.name) === 'framework' ||\n lowerIfExists(sn.attributes.name) === 'publisher' ||\n lowerIfExists(sn.attributes.name) === 'progid' ||\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 (lowerIfExists(sn.attributes.name) === 'google-site-verification' ||\n lowerIfExists(sn.attributes.name) === 'yandex-verification' ||\n lowerIfExists(sn.attributes.name) === 'csrf-token' ||\n lowerIfExists(sn.attributes.name) === 'p:domain_verify' ||\n lowerIfExists(sn.attributes.name) === 'verify-v1' ||\n lowerIfExists(sn.attributes.name) === 'verification' ||\n lowerIfExists(sn.attributes.name) === 'shopify-checkout-api-token')\n ) {\n return true;\n }\n }\n }\n return 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 preserveWhiteSpace?: boolean;\n onSerialize?: (n: Node) => unknown;\n onIframeLoad?: (\n iframeNode: HTMLIFrameElement,\n node: serializedElementNodeWithId,\n ) => unknown;\n iframeLoadTimeout?: number;\n onStylesheetLoad?: (\n linkNode: HTMLLinkElement,\n node: serializedElementNodeWithId,\n ) => unknown;\n stylesheetLoadTimeout?: number;\n cssCaptured?: boolean;\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 onSerialize,\n onIframeLoad,\n iframeLoadTimeout = 5000,\n onStylesheetLoad,\n stylesheetLoadTimeout = 5000,\n keepIframeSrcFn = () => false,\n newlyAddedElement = false,\n cssCaptured = false,\n } = options;\n let { needsMask } = options;\n let { preserveWhiteSpace = true } = options;\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 keepIframeSrcFn,\n newlyAddedElement,\n cssCaptured,\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.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 preserveWhiteSpace,\n onSerialize,\n onIframeLoad,\n iframeLoadTimeout,\n onStylesheetLoad,\n stylesheetLoadTimeout,\n keepIframeSrcFn,\n cssCaptured: false,\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 if (\n serializedNode.type === NodeType.Element &&\n (serializedNode as elementNode).attributes._cssText !== undefined &&\n typeof serializedNode.attributes._cssText === 'string'\n ) {\n bypassOptions.cssCaptured = true;\n }\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 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 preserveWhiteSpace,\n onSerialize,\n onIframeLoad,\n iframeLoadTimeout,\n onStylesheetLoad,\n stylesheetLoadTimeout,\n keepIframeSrcFn,\n });\n\n if (serializedIframeNode) {\n onIframeLoad(\n n as HTMLIFrameElement,\n serializedIframeNode as serializedElementNodeWithId,\n );\n }\n }\n },\n iframeLoadTimeout,\n );\n }\n\n // <link rel=stylesheet href=...>\n if (\n serializedNode.type === NodeType.Element &&\n serializedNode.tagName === 'link' &&\n typeof serializedNode.attributes.rel === 'string' &&\n (serializedNode.attributes.rel === 'stylesheet' ||\n (serializedNode.attributes.rel === 'preload' &&\n typeof serializedNode.attributes.href === 'string' &&\n extractFileExtension(serializedNode.attributes.href) === 'css'))\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 preserveWhiteSpace,\n onSerialize,\n onIframeLoad,\n iframeLoadTimeout,\n onStylesheetLoad,\n stylesheetLoadTimeout,\n keepIframeSrcFn,\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\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 preserveWhiteSpace?: boolean;\n onSerialize?: (n: Node) => unknown;\n onIframeLoad?: (\n iframeNode: HTMLIFrameElement,\n node: serializedElementNodeWithId,\n ) => unknown;\n iframeLoadTimeout?: number;\n onStylesheetLoad?: (\n linkNode: HTMLLinkElement,\n node: serializedElementNodeWithId,\n ) => unknown;\n stylesheetLoadTimeout?: number;\n keepIframeSrcFn?: KeepIframeSrcFn;\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 maskAllInputs = false,\n maskTextFn,\n maskInputFn,\n slimDOM = false,\n dataURLOptions,\n preserveWhiteSpace,\n onSerialize,\n onIframeLoad,\n iframeLoadTimeout,\n onStylesheetLoad,\n stylesheetLoadTimeout,\n keepIframeSrcFn = () => false,\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 = slimDOMDefaults(slimDOM);\n\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 preserveWhiteSpace,\n onSerialize,\n onIframeLoad,\n iframeLoadTimeout,\n onStylesheetLoad,\n stylesheetLoadTimeout,\n keepIframeSrcFn,\n newlyAddedElement: false,\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","import { NodeType as RRNodeType } from '@rrweb/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 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 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 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","import type {\n throttleOptions,\n listenerHandler,\n hookResetter,\n blockClass,\n addedNodeMutation,\n DocumentDimension,\n IWindow,\n DeprecatedMirror,\n textMutation,\n IMirror,\n} from '@rrweb/types';\nimport type { Mirror, SlimDOMOptions } from 'rrweb-snapshot';\nimport { isShadowRoot, IGNORED_NODE, classMatchesRegex } from 'rrweb-snapshot';\nimport { RRNode, RRIFrameElement, BaseRRNode } from 'rrdom';\nimport dom from '@rrweb/utils';\nexport { nowTimestamp } from '@rrweb/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 () => target.removeEventListener(type, fn, options);\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 d.set!.call(this, value);\n }, 0);\n if (original && original.set) {\n original.set.call(this, value);\n }\n },\n },\n );\n return () => hookSetter(target, key, original || {}, true);\n}\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) {\n return false;\n }\n const el = closestElementOfNode(node);\n\n if (!el) {\n return false;\n }\n\n try {\n if (typeof blockClass === 'string') {\n if (el.classList.contains(blockClass)) return true;\n if (checkAncestors && el.closest('.' + blockClass) !== null) return true;\n } else {\n if (classMatchesRegex(el, blockClass, checkAncestors)) return true;\n }\n } catch (e) {\n // e\n }\n if (blockSelector) {\n if (el.matches(blockSelector)) return true;\n if (checkAncestors && el.closest(blockSelector) !== null) return 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\n/**\n * Traverses a CSSRuleList to find a nested rule at the given position.\n *\n * Returns null instead of throwing if the rule doesn't exist. This is important\n * because during replay:\n * - StyleDeclaration events may reference rules added dynamically that don't\n * exist yet due to timing/ordering issues\n * - StyleSheetRule events that create rules may not have been processed yet\n * - Constructed/adopted stylesheets may not be fully synchronized\n *\n * @param rules - The CSSRuleList to traverse\n * @param position - Array of indices, e.g., [0, 1, 0] for rules[0].cssRules[1].cssRules[0]\n * @returns The nested rule, or null if not found\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 = dom.ownerDocument(n);\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 = dom.ownerDocument(n);\n if (!doc) return false;\n return dom.contains(doc, n) || shadowHostInDom(n);\n}\n","import {\n serializeNodeWithId,\n transformAttribute,\n IGNORED_NODE,\n ignoreAttribute,\n isShadowRoot,\n needMaskingText,\n maskInputValue,\n isNativeShadowDom,\n getInputType,\n toLowerCase,\n} from 'rrweb-snapshot';\nimport type { observerParam, MutationBufferParam } from '../types';\nimport type {\n mutationRecord,\n textCursor,\n attributeCursor,\n removedNodeMutation,\n addedNodeMutation,\n} from '@rrweb/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 '@rrweb/utils';\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 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\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 '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 }\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 this.shadowDomManager.reset();\n this.canvasManager.reset();\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 while (this.mapRemoves.length) {\n this.mirror.removeNodeFromMap(this.mapRemoves.shift()!);\n }\n\n for (const n of this.movedSet) {\n const parentNode = dom.parentNode(n);\n if (\n this.removesSubTreeCache.has(parentNode as Node) &&\n !this.movedSet.has(parentNode as Node)\n ) {\n continue;\n }\n this.addedSet.add(n);\n }\n\n let n: Node | null = null;\n let parentNode: Node | null = null;\n let parentId = -1;\n let nextSibling: Node | null = null;\n let ancestorBad = false;\n const missingParents = new Set<Node>();\n const iter = this.addedSet.values();\n let curr = iter.next();\n while (this.addedSet.size) {\n if (n !== null && this.addedSet.has(dom.previousSibling(n) as Node)) {\n // reuse parentNode, parentId, ancestorBad\n nextSibling = n; // n is a good next sibling\n n = dom.previousSibling(n) as Node;\n } else {\n if (!this.addedSet.has(curr.value as Node)) {\n // having the `iter` here rather than picking directly from this.addedSet\n // ensures we don't get caught re-traversing 'tombstones' in the Set\n // (we reuse curr in multiple iterations until it's ancestors and nextSiblings are serialized)\n curr = iter.next();\n }\n n = curr.value as Node;\n\n // eslint-disable-next-line no-constant-condition\n while (true) {\n parentNode = dom.parentNode(n);\n if (this.addedSet.has(parentNode as Node)) {\n // start at top of added tree so as not to serialize children before their parents (parentId requirement)\n n = parentNode as Node;\n continue;\n }\n break;\n }\n\n if (missingParents.has(parentNode as Node)) {\n parentNode = null;\n } else if (parentNode) {\n // we have a new parentNode for a 'row' of DOM children\n // perf: we reuse these calculations across all child nodes\n\n if (!inDom(parentNode)) {\n ancestorBad = true;\n } else {\n ancestorBad =\n isSelfOrAncestorInSet(this.droppedSet, parentNode) ||\n this.removesSubTreeCache.has(parentNode);\n\n if (ancestorBad && isSelfOrAncestorInSet(this.movedSet, n)) {\n // not bad, just moved\n ancestorBad = false;\n }\n }\n\n if (this.addedSet.has(dom.lastChild(parentNode) as Node)) {\n // jump instead of crawling nextSibling to nextSibling\n n = dom.lastChild(parentNode) as Node;\n nextSibling = null;\n } else {\n // eslint-disable-next-line no-constant-condition\n while (true) {\n nextSibling = dom.nextSibling(n);\n if (this.addedSet.has(nextSibling as Node)) {\n // keep going as we can't serialize a node before it's next sibling (nextId requirement)\n n = nextSibling as Node;\n continue;\n }\n break;\n }\n }\n\n parentId = isShadowRoot(parentNode)\n ? this.mirror.getId(getShadowHost(n))\n : this.mirror.getId(parentNode);\n\n // If the node is the direct child of a shadow root, we treat the shadow host as its parent node.\n if (\n parentId === -1 &&\n parentNode.nodeType === Node.DOCUMENT_FRAGMENT_NODE\n ) {\n const shadowHost = dom.host(parentNode as ShadowRoot);\n parentId = this.mirror.getId(shadowHost);\n }\n }\n }\n\n this.addedSet.delete(n); // don't re-iterate\n\n if (!parentNode || parentId === -1) {\n missingParents.add(n); // ensure any added child nodes can also early-out\n continue;\n } else if (ancestorBad) {\n // it's possible we could unify missingParents and this.droppedSet\n // but would need to check the subtleties\n this.droppedSet.add(n);\n continue;\n }\n\n let cssCaptured = false;\n if (n.nodeType === Node.TEXT_NODE) {\n const parentTag = (parentNode as Element).tagName;\n if (parentTag === 'TEXTAREA') {\n // genTextAreaValueMutation already called via parent\n continue;\n } else if (parentTag === 'STYLE' && addedIds.has(parentId)) {\n // css content will be recorded via parent's _cssText attribute when\n // mutation adds entire <style> element\n cssCaptured = true;\n }\n }\n\n let nextId = nextSibling ? this.mirror.getId(nextSibling) : null;\n while (nextId === IGNORED_NODE) {\n nextSibling = nextSibling && dom.nextSibling(nextSibling);\n nextId = nextSibling && this.mirror.getId(nextSibling);\n }\n if (nextId === -1) {\n // sibling not included in addedNodes, but\n // no id as not yet serialized?\n console.warn(\n \"Couldn't record new node. Couldn't find mirror id for nextSibling:\",\n nextSibling,\n );\n n = null; // don't iterate to previousSibling as we haven't successful serialized this node\n continue;\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 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 as Node)) {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n this.shadowDomManager.addShadowRoot(\n dom.shadowRoot(n as Node)!,\n this.doc,\n );\n }\n },\n onIframeLoad: (iframe, childSn) => {\n this.iframeManager.attachIframe(iframe, childSn);\n this.shadowDomManager.observeAttachShadow(iframe);\n },\n onStylesheetLoad: (link, childSn) => {\n this.stylesheetManager.attachLinkElement(link, childSn);\n },\n cssCaptured,\n });\n if (sn) {\n adds.push({\n parentId,\n nextId,\n node: sn,\n });\n addedIds.add(sn.id);\n }\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 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 const tagNameLower = toLowerCase(target.tagName);\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 tagNameLower === '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 tagNameLower === 'input' &&\n (m.oldValue || '').toLowerCase() === 'password'\n ) {\n target.setAttribute('data-rr-is-password', 'true');\n }\n\n if (!ignoreAttribute(tagNameLower, attributeName, value)) {\n // overwrite attribute if the mutations was triggered in same time\n item.attributes[attributeName] = transformAttribute(\n this.doc,\n tagNameLower,\n toLowerCase(attributeName),\n value,\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.setAttribute('style', 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) || 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 isSelfOrAncestorInSet(set: Set<Node>, n: Node): boolean {\n if (set.size === 0) return false;\n return _isSelfOrAncestorInSet(set, n);\n}\n\nfunction _isSelfOrAncestorInSet(set: Set<Node>, n: Node): boolean {\n if (set.has(n)) {\n return true;\n }\n const parent = dom.parentNode(n);\n if (!parent) {\n return false;\n }\n return _isSelfOrAncestorInSet(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","import {\n type MaskInputOptions,\n maskInputValue,\n Mirror,\n getInputType,\n toLowerCase,\n} from 'rrweb-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 '@rrweb/utils';\nimport type { observerParam, MutationBufferParam } from '../types';\nimport {\n IncrementalSource,\n MouseInteractions,\n PointerTypes,\n MediaInteractions,\n} from '@rrweb/types';\nimport type {\n mutationCallBack,\n mousemoveCallBack,\n mousePosition,\n mouseInteractionCallBack,\n listenerHandler,\n scrollCallback,\n styleSheetRuleCallback,\n viewportResizeCallback,\n inputValue,\n inputCallback,\n hookResetter,\n hooksParam,\n Arguments,\n mediaInteractionCallback,\n canvasMutationCallback,\n fontCallback,\n fontParam,\n styleDeclarationCallback,\n IWindow,\n SelectionRange,\n selectionCallback,\n customElementCallback,\n} from '@rrweb/types';\nimport MutationBuffer from './mutation';\nimport { callbackWrapper } from './error-handler';\nimport dom, { mutationObserverCtor } from '@rrweb/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): [MutationObserver, () => void] {\n const mutationBuffer = new MutationBuffer();\n mutationBuffers.push(mutationBuffer);\n // see mutation.ts for details\n mutationBuffer.init(options);\n const [ObserverCtor, iframeCleanup] = mutationObserverCtor();\n const observer = new (ObserverCtor as new (\n callback: MutationCallback,\n ) => MutationObserver)(\n callbackWrapper(mutationBuffer.processMutations.bind(mutationBuffer)),\n );\n observer.observe(rootEl, {\n attributes: true,\n attributeOldValue: true,\n characterData: true,\n characterDataOldValue: true,\n childList: true,\n subtree: true,\n });\n return [observer, iframeCleanup];\n}\n\nfunction initMoveObserver({\n mousemoveCb,\n sampling,\n doc,\n mirror,\n}: observerParam): listenerHandler {\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 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 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 const handlers = [\n on('mousemove', updatePosition, doc),\n on('touchmove', updatePosition, doc),\n on('drag', updatePosition, doc),\n ];\n return callbackWrapper(() => {\n handlers.forEach((h) => h());\n });\n}\n\nfunction initMouseInteractionObserver({\n mouseInteractionCb,\n doc,\n mirror,\n blockClass,\n blockSelector,\n sampling,\n}: observerParam): listenerHandler {\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 const handlers: listenerHandler[] = [];\n let currentPointerType: PointerTypes | null = null;\n const getHandler = (eventKey: keyof typeof MouseInteractions) => {\n return (event: MouseEvent | TouchEvent | PointerEvent) => {\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 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 handlers.push(on(eventName, handler, doc));\n });\n return callbackWrapper(() => {\n handlers.forEach((h) => h());\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 const updatePosition = callbackWrapper(\n throttle<UIEvent>(\n callbackWrapper((evt) => {\n const target = getEventTarget(evt);\n if (\n !target ||\n isBlocked(target as Node, blockClass, blockSelector, true)\n ) {\n return;\n }\n const id = mirror.getId(target as Node);\n if (target === doc && doc.defaultView) {\n const scrollLeftTop = getWindowScroll(doc.defaultView);\n scrollCb({\n id,\n x: scrollLeftTop.left,\n y: scrollLeftTop.top,\n });\n } else {\n scrollCb({\n id,\n x: (target as HTMLElement).scrollLeft,\n y: (target as HTMLElement).scrollTop,\n });\n }\n }),\n sampling.scroll || 100,\n ),\n );\n return on('scroll', updatePosition, doc);\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\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 function eventHandler(event: Event) {\n let target = getEventTarget(event) as HTMLElement | null;\n const userTriggered = event.isTrusted;\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 const events = sampling.input === 'last' ? ['change'] : ['input', 'change'];\n const handlers: Array<listenerHandler | hookResetter> = events.map(\n (eventName) => on(eventName, callbackWrapper(eventHandler), doc),\n );\n const currentWindow = doc.defaultView;\n if (!currentWindow) {\n return () => {\n handlers.forEach((h) => h());\n };\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 handlers.push(\n ...hookProperties.map((p) =>\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 return callbackWrapper(() => {\n handlers.forEach((h) => h());\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 // eslint-disable-next-line @typescript-eslint/unbound-method\n const insertRule = win.CSSStyleSheet.prototype.insertRule;\n win.CSSStyleSheet.prototype.insertRule = 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 // Support for deprecated addRule method\n win.CSSStyleSheet.prototype.addRule = 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, [rule, index]);\n };\n\n // eslint-disable-next-line @typescript-eslint/unbound-method\n const deleteRule = win.CSSStyleSheet.prototype.deleteRule;\n win.CSSStyleSheet.prototype.deleteRule = 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 // Support for deprecated removeRule method\n win.CSSStyleSheet.prototype.removeRule = function (\n this: CSSStyleSheet,\n index: number,\n ) {\n return win.CSSStyleSheet.prototype.deleteRule.apply(this, [index]);\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 win.CSSStyleSheet.prototype.replace = 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 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 win.CSSStyleSheet.prototype.replaceSync = 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 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 type.prototype.insertRule = new Proxy(\n unmodifiedFunctions[typeKey].insertRule,\n {\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 type.prototype.deleteRule = new Proxy(\n unmodifiedFunctions[typeKey].deleteRule,\n {\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 return callbackWrapper(() => {\n win.CSSStyleSheet.prototype.insertRule = insertRule;\n win.CSSStyleSheet.prototype.deleteRule = deleteRule;\n replace && (win.CSSStyleSheet.prototype.replace = replace);\n replaceSync && (win.CSSStyleSheet.prototype.replaceSync = replaceSync);\n Object.entries(supportedNestedCSSRuleTypes).forEach(([typeKey, type]) => {\n type.prototype.insertRule = unmodifiedFunctions[typeKey].insertRule;\n type.prototype.deleteRule = unmodifiedFunctions[typeKey].deleteRule;\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 const result = originalPropertyDescriptor.set?.call(this, sheets);\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 // eslint-disable-next-line @typescript-eslint/unbound-method\n const setProperty = win.CSSStyleDeclaration.prototype.setProperty;\n win.CSSStyleDeclaration.prototype.setProperty = 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 // eslint-disable-next-line @typescript-eslint/unbound-method\n const removeProperty = win.CSSStyleDeclaration.prototype.removeProperty;\n win.CSSStyleDeclaration.prototype.removeProperty = 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 return callbackWrapper(() => {\n win.CSSStyleDeclaration.prototype.setProperty = setProperty;\n win.CSSStyleDeclaration.prototype.removeProperty = removeProperty;\n });\n}\n\nfunction initMediaInteractionObserver({\n mediaInteractionCb,\n blockClass,\n blockSelector,\n mirror,\n sampling,\n doc,\n}: observerParam): listenerHandler {\n const handler = callbackWrapper((type: MediaInteractions) =>\n throttle(\n callbackWrapper((event: Event) => {\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 const handlers = [\n on('play', handler(MediaInteractions.Play), doc),\n on('pause', handler(MediaInteractions.Pause), doc),\n on('seeked', handler(MediaInteractions.Seeked), doc),\n on('volumechange', handler(MediaInteractions.VolumeChange), doc),\n on('ratechange', handler(MediaInteractions.RateChange), doc),\n ];\n return callbackWrapper(() => {\n handlers.forEach((h) => h());\n });\n}\n\nfunction initFontObserver({ fontCb, doc }: observerParam): listenerHandler {\n const win = doc.defaultView as IWindow;\n if (!win) {\n return () => {\n //\n };\n }\n\n const handlers: listenerHandler[] = [];\n\n const fontMap = new WeakMap<FontFace, fontParam>();\n\n const originalFontFace = win.FontFace;\n win.FontFace = function FontFace(\n family: string,\n source: string | ArrayBufferLike,\n descriptors?: FontFaceDescriptors,\n ) {\n const fontFace = new originalFontFace(family, source, descriptors);\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 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 handlers.push(() => {\n win.FontFace = originalFontFace;\n });\n handlers.push(restoreHandler);\n\n return callbackWrapper(() => {\n handlers.forEach((h) => h());\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 let mutationObserver: MutationObserver | undefined;\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n let cleanupMutationIframe: () => void = () => {};\n if (o.recordDOM) {\n [mutationObserver, cleanupMutationIframe] = initMutationObserver(o, o.doc);\n }\n const mousemoveHandler = initMoveObserver(o);\n const mouseInteractionHandler = initMouseInteractionObserver(o);\n const scrollHandler = initScrollObserver(o);\n const viewportResizeHandler = initViewportResizeObserver(o, {\n win: currentWindow,\n });\n const inputHandler = initInputObserver(o);\n const mediaInteractionHandler = initMediaInteractionObserver(o);\n\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n let styleSheetObserver = () => {};\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n let adoptedStyleSheetObserver = () => {};\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n let styleDeclarationObserver = () => {};\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n let fontObserver = () => {};\n if (o.recordDOM) {\n styleSheetObserver = initStyleSheetObserver(o, { win: currentWindow });\n adoptedStyleSheetObserver = initAdoptedStyleSheetObserver(o, o.doc);\n styleDeclarationObserver = initStyleDeclarationObserver(o, {\n win: currentWindow,\n });\n if (o.collectFonts) {\n fontObserver = initFontObserver(o);\n }\n }\n const selectionObserver = initSelectionObserver(o);\n const customElementObserver = initCustomElementObserver(o);\n\n // plugins\n const pluginHandlers: listenerHandler[] = [];\n for (const plugin of o.plugins) {\n pluginHandlers.push(\n plugin.observer(plugin.callback, currentWindow, plugin.options),\n );\n }\n\n return callbackWrapper(() => {\n mutationBuffers.forEach((b) => b.reset());\n mutationObserver?.disconnect();\n cleanupMutationIframe();\n mousemoveHandler();\n mouseInteractionHandler();\n scrollHandler();\n viewportResizeHandler();\n inputHandler();\n mediaInteractionHandler();\n styleSheetObserver();\n adoptedStyleSheetObserver();\n styleDeclarationObserver();\n fontObserver();\n selectionObserver();\n customElementObserver();\n pluginHandlers.forEach((h) => h());\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","import type { ICrossOriginIframeMirror } from '@rrweb/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","import type { Mirror } from 'rrweb-snapshot';\nimport { genId } from 'rrweb-snapshot';\nimport type { CrossOriginIframeMessageEvent } from '../types';\nimport CrossOriginIframeMirror from './cross-origin-iframe-mirror';\nimport { EventType, NodeType, IncrementalSource } from '@rrweb/types';\nimport type {\n eventWithTime,\n eventWithoutTime,\n serializedNodeWithId,\n mutationCallBack,\n} from '@rrweb/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 stylesheetManager: StylesheetManager;\n private recordCrossOriginIframes: boolean;\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 if (this.recordCrossOriginIframes) {\n window.addEventListener('message', this.handleMessage.bind(this));\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 addLoadListener(cb: (iframeEl: HTMLIFrameElement) => unknown) {\n this.loadListener = cb;\n }\n\n public attachIframe(\n iframeEl: HTMLIFrameElement,\n childSn: serializedNodeWithId,\n ) {\n this.mutationCb({\n adds: [\n {\n parentId: this.mirror.getId(iframeEl),\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 if (this.recordCrossOriginIframes)\n iframeEl.contentWindow?.addEventListener(\n 'message',\n this.handleMessage.bind(this),\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 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","import type { MutationBufferParam } from '../types';\nimport type {\n mutationCallBack,\n scrollCallback,\n SamplingStrategy,\n} from '@rrweb/types';\nimport {\n initMutationObserver,\n initScrollObserver,\n initAdoptedStyleSheetObserver,\n} from './observer';\nimport { inDom } from '../utils';\nimport type { Mirror } from 'rrweb-snapshot';\nimport { isNativeShadowDom } from 'rrweb-snapshot';\nimport dom, { patch } from '@rrweb/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 private restoreHandlers: (() => 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 const [observer] = initMutationObserver(\n {\n ...this.bypassOptions,\n doc,\n mutationCb: this.mutationCb,\n mirror: this.mirror,\n shadowDomManager: this,\n },\n shadowRoot,\n );\n this.restoreHandlers.push(() => observer.disconnect());\n this.restoreHandlers.push(\n 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 setTimeout(() => {\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 initAdoptedStyleSheetObserver(\n {\n mirror: this.mirror,\n stylesheetManager: this.bypassOptions.stylesheetManager,\n },\n shadowRoot,\n ),\n );\n }, 0);\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 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 public reset() {\n this.restoreHandlers.forEach((handler) => {\n try {\n handler();\n } catch (e) {\n //\n }\n });\n this.restoreHandlers = [];\n this.shadowDoms = new WeakSet();\n }\n}\n","/*\n * base64-arraybuffer 1.0.2 <https://github.com/niklasvh/base64-arraybuffer>\n * Copyright (c) 2022 Niklas von Hertzen <https://hertzen.com>\n * Released under MIT License\n */\nvar chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';\n// Use a lookup table to find the index.\nvar lookup = typeof Uint8Array === 'undefined' ? [] : new Uint8Array(256);\nfor (var i = 0; i < chars.length; i++) {\n lookup[chars.charCodeAt(i)] = i;\n}\nvar encode = function (arraybuffer) {\n var bytes = new Uint8Array(arraybuffer), i, len = bytes.length, base64 = '';\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 if (len % 3 === 2) {\n base64 = base64.substring(0, base64.length - 1) + '=';\n }\n else if (len % 3 === 1) {\n base64 = base64.substring(0, base64.length - 2) + '==';\n }\n return base64;\n};\nvar decode = function (base64) {\n var bufferLength = base64.length * 0.75, len = base64.length, i, p = 0, encoded1, encoded2, encoded3, encoded4;\n if (base64[base64.length - 1] === '=') {\n bufferLength--;\n if (base64[base64.length - 2] === '=') {\n bufferLength--;\n }\n }\n var arraybuffer = new ArrayBuffer(bufferLength), bytes = new Uint8Array(arraybuffer);\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 bytes[p++] = (encoded1 << 2) | (encoded2 >> 4);\n bytes[p++] = ((encoded2 & 15) << 4) | (encoded3 >> 2);\n bytes[p++] = ((encoded3 & 3) << 6) | (encoded4 & 63);\n }\n return arraybuffer;\n};\n\nexport { decode, encode };\n//# sourceMappingURL=base64-arraybuffer.es5.js.map\n","import { encode } from 'base64-arraybuffer';\nimport type { IWindow, CanvasArg } from '@rrweb/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): CanvasArg {\n if (value instanceof Array) {\n return value.map((arg) => serializeArg(arg, win, ctx));\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),\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(); // heavy on large canvas\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: [serializeArg(value.data, win, ctx), value.width, value.height],\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)],\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) => {\n return args.map((arg) => serializeArg(arg, win, ctx));\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","import {\n type blockClass,\n CanvasContext,\n type canvasManagerMutationCallback,\n type IWindow,\n type listenerHandler,\n} from '@rrweb/types';\nimport { hookSetter, isBlocked } from '../../../utils';\nimport { patch } from '@rrweb/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): 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(args, win, this);\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","import type { ICanvas } from 'rrweb-snapshot';\nimport type { blockClass, IWindow, listenerHandler } from '@rrweb/types';\nimport { isBlocked } from '../../../utils';\nimport { patch } from '@rrweb/utils';\n\nfunction getNormalizedContextName(contextType: string) {\n return contextType === 'experimental-webgl' ? 'webgl' : contextType;\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 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 if (!isBlocked(this, blockClass, blockSelector, true)) {\n const ctxName = getNormalizedContextName(contextType);\n if (!('__context' in this)) (this as ICanvas).__context = ctxName;\n\n if (\n setPreserveDrawingBufferToTrue &&\n ['webgl', 'webgl2'].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 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","import {\n type blockClass,\n CanvasContext,\n type canvasManagerMutationCallback,\n type canvasMutationWithType,\n type IWindow,\n type listenerHandler,\n} from '@rrweb/types';\nimport { hookSetter, isBlocked } from '../../../utils';\nimport { patch } from '@rrweb/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): 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);\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): 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 ),\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 ),\n );\n }\n\n return () => {\n handlers.forEach((h) => h());\n };\n}\n","import type { ICanvas, Mirror } from 'rrweb-snapshot';\nimport type {\n blockClass,\n canvasManagerMutationCallback,\n canvasMutationCallback,\n canvasMutationCommand,\n canvasMutationWithType,\n IWindow,\n listenerHandler,\n CanvasArg,\n DataURLOptions,\n} from '@rrweb/types';\nimport { isBlocked } from '../../../utils';\nimport { CanvasContext } from '@rrweb/types';\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\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\n public reset() {\n this.pendingCanvasMutations.clear();\n this.resetObservers && this.resetObservers();\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 }) {\n const {\n sampling = 'all',\n win,\n blockClass,\n blockSelector,\n recordCanvas,\n dataURLOptions,\n } = options;\n this.mutationCb = options.mutationCb;\n this.mirror = options.mirror;\n\n if (recordCanvas && sampling === 'all')\n this.initCanvasMutationObserver(win, blockClass, blockSelector);\n if (recordCanvas && typeof sampling === 'number')\n this.initCanvasFPSObserver(sampling, win, blockClass, blockSelector, {\n dataURLOptions,\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 },\n ) {\n const canvasContextReset = initCanvasContextObserver(\n win,\n blockClass,\n blockSelector,\n true,\n );\n const snapshotInProgressMap: Map<number, boolean> = new Map();\n const worker =\n new ImageBitmapDataURLWorker() as ImageBitmapDataURLRequestWorker;\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, width, height } = e.data;\n this.mutationCb({\n id,\n type: CanvasContext['2D'],\n commands: [\n {\n property: 'clearRect', // wipe canvas\n args: [0, 0, width, height],\n },\n {\n property: 'drawImage', // draws (semi-transparent) image\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 ],\n },\n ],\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 win.document.querySelectorAll('canvas').forEach((canvas) => {\n if (!isBlocked(canvas, blockClass, blockSelector, true)) {\n matchedCanvas.push(canvas);\n }\n });\n return matchedCanvas;\n };\n\n const takeCanvasSnapshots = (timestamp: DOMHighResTimeStamp) => {\n if (\n lastSnapshotTime &&\n timestamp - lastSnapshotTime < timeBetweenSnapshots\n ) {\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 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((canvas as ICanvas).__context) as\n | WebGLRenderingContext\n | WebGL2RenderingContext\n | null;\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 const bitmap = await createImageBitmap(canvas);\n worker.postMessage(\n {\n id,\n bitmap,\n width: canvas.width,\n height: canvas.height,\n dataURLOptions: options.dataURLOptions,\n },\n [bitmap],\n );\n });\n rafId = requestAnimationFrame(takeCanvasSnapshots);\n };\n\n rafId = requestAnimationFrame(takeCanvasSnapshots);\n\n this.resetObservers = () => {\n canvasContextReset();\n cancelAnimationFrame(rafId);\n };\n }\n\n private initCanvasMutationObserver(\n win: IWindow,\n blockClass: blockClass,\n blockSelector: string | null,\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 );\n\n const canvasWebGL1and2Reset = initCanvasWebGLMutationObserver(\n this.processMutation.bind(this),\n win,\n blockClass,\n blockSelector,\n );\n\n this.resetObservers = () => {\n canvasContextReset();\n canvas2DReset();\n canvasWebGL1and2Reset();\n };\n }\n\n private startPendingCanvasMutationFlusher() {\n requestAnimationFrame(() => this.flushPendingCanvasMutations());\n }\n\n private startRAFTimestamping() {\n const setLatestRAFTimestamp = (timestamp: DOMHighResTimeStamp) => {\n this.rafStamps.latestId = timestamp;\n requestAnimationFrame(setLatestRAFTimestamp);\n };\n 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 requestAnimationFrame(() => this.flushPendingCanvasMutations());\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","import { stringifyRule } from 'rrweb-snapshot';\nimport type {\n elementNode,\n serializedNodeWithId,\n adoptedStyleSheetCallback,\n adoptedStyleSheetParam,\n attributeMutation,\n mutationCallBack,\n} from '@rrweb/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 }\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","import {\n snapshot,\n slimDOMDefaults,\n type MaskInputOptions,\n createMirror,\n} from 'rrweb-snapshot';\nimport { initObservers, mutationBuffers } 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 IncrementalSource,\n type listenerHandler,\n type mutationCallbackParam,\n type scrollCallback,\n type canvasMutationParam,\n type adoptedStyleSheetParam,\n} from '@rrweb/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 callbackWrapper,\n registerErrorHandler,\n unregisterErrorHandler,\n} from './error-handler';\nimport dom from '@rrweb/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();\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 = {},\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 errorHandler,\n } = options;\n\n registerErrorHandler(errorHandler);\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 // 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(_slimDOMOptions);\n\n polyfill();\n\n let lastFullSnapshotEvent: eventWithTime;\n let incrementalSnapshotCount = 0;\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 wrappedEmit = (r: eventWithoutTime, isCheckout?: boolean) => {\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 e.data.source === IncrementalSource.Mutation\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 takeFullSnapshot(true);\n }\n }\n };\n\n const wrappedMutationEmit = (m: mutationCallbackParam) => {\n wrappedEmit({\n type: EventType.IncrementalSnapshot,\n data: {\n source: IncrementalSource.Mutation,\n ...m,\n },\n });\n };\n const wrappedScrollEmit: scrollCallback = (p) =>\n wrappedEmit({\n type: EventType.IncrementalSnapshot,\n data: {\n source: IncrementalSource.Scroll,\n ...p,\n },\n });\n const wrappedCanvasMutationEmit = (p: canvasMutationParam) =>\n wrappedEmit({\n type: EventType.IncrementalSnapshot,\n data: {\n source: IncrementalSource.CanvasMutation,\n ...p,\n },\n });\n\n const wrappedAdoptedStyleSheetEmit = (a: adoptedStyleSheetParam) =>\n wrappedEmit({\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 const iframeManager = new IframeManager({\n mirror,\n mutationCb: wrappedMutationEmit,\n stylesheetManager: stylesheetManager,\n recordCrossOriginIframes,\n wrappedEmit,\n });\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 canvasManager = new CanvasManager({\n recordCanvas,\n mutationCb: wrappedCanvasMutationEmit,\n win: window,\n blockClass,\n blockSelector,\n mirror,\n sampling: sampling.canvas,\n dataURLOptions,\n });\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 inlineImages,\n sampling,\n slimDOMOptions,\n iframeManager,\n stylesheetManager,\n canvasManager,\n keepIframeSrcFn,\n processedNodeManager,\n },\n mirror,\n });\n\n takeFullSnapshot = (isCheckout = false) => {\n if (!recordDOM) {\n return;\n }\n wrappedEmit(\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 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(dom.shadowRoot(n as Node)!, document);\n }\n },\n onIframeLoad: (iframe, childSn) => {\n iframeManager.attachIframe(iframe, childSn);\n shadowDomManager.observeAttachShadow(iframe);\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 wrappedEmit(\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\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 try {\n const handlers: listenerHandler[] = [];\n\n const observe = (doc: Document) => {\n return callbackWrapper(initObservers)(\n {\n mutationCb: wrappedMutationEmit,\n mousemoveCb: (positions, source) =>\n wrappedEmit({\n type: EventType.IncrementalSnapshot,\n data: {\n source,\n positions,\n },\n }),\n mouseInteractionCb: (d) =>\n wrappedEmit({\n type: EventType.IncrementalSnapshot,\n data: {\n source: IncrementalSource.MouseInteraction,\n ...d,\n },\n }),\n scrollCb: wrappedScrollEmit,\n viewportResizeCb: (d) =>\n wrappedEmit({\n type: EventType.IncrementalSnapshot,\n data: {\n source: IncrementalSource.ViewportResize,\n ...d,\n },\n }),\n inputCb: (v) =>\n wrappedEmit({\n type: EventType.IncrementalSnapshot,\n data: {\n source: IncrementalSource.Input,\n ...v,\n },\n }),\n mediaInteractionCb: (p) =>\n wrappedEmit({\n type: EventType.IncrementalSnapshot,\n data: {\n source: IncrementalSource.MediaInteraction,\n ...p,\n },\n }),\n styleSheetRuleCb: (r) =>\n wrappedEmit({\n type: EventType.IncrementalSnapshot,\n data: {\n source: IncrementalSource.StyleSheetRule,\n ...r,\n },\n }),\n styleDeclarationCb: (r) =>\n wrappedEmit({\n type: EventType.IncrementalSnapshot,\n data: {\n source: IncrementalSource.StyleDeclaration,\n ...r,\n },\n }),\n canvasMutationCb: wrappedCanvasMutationEmit,\n fontCb: (p) =>\n wrappedEmit({\n type: EventType.IncrementalSnapshot,\n data: {\n source: IncrementalSource.Font,\n ...p,\n },\n }),\n selectionCb: (p) => {\n wrappedEmit({\n type: EventType.IncrementalSnapshot,\n data: {\n source: IncrementalSource.Selection,\n ...p,\n },\n });\n },\n customElementCb: (c) => {\n wrappedEmit({\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 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 plugins:\n plugins\n ?.filter((p) => p.observer)\n ?.map((p) => ({\n observer: p.observer!,\n options: p.options,\n callback: (payload: object) =>\n wrappedEmit({\n type: EventType.Plugin,\n data: {\n plugin: p.name,\n payload,\n },\n }),\n })) || [],\n },\n hooks,\n );\n };\n\n iframeManager.addLoadListener((iframeEl) => {\n try {\n handlers.push(observe(iframeEl.contentDocument!));\n } catch (error) {\n // TODO: handle internal error\n console.warn(error);\n }\n });\n\n const init = () => {\n takeFullSnapshot();\n handlers.push(observe(document));\n recording = true;\n };\n if (['interactive', 'complete'].includes(document.readyState)) {\n init();\n } else {\n handlers.push(\n on('DOMContentLoaded', () => {\n wrappedEmit({\n type: EventType.DomContentLoaded,\n data: {},\n });\n if (recordAfter === 'DOMContentLoaded') init();\n }),\n );\n handlers.push(\n on(\n 'load',\n () => {\n wrappedEmit({\n type: EventType.Load,\n data: {},\n });\n if (recordAfter === 'load') init();\n },\n window,\n ),\n );\n }\n return () => {\n handlers.forEach((handler) => {\n try {\n handler();\n } catch (error) {\n const msg = String(error).toLowerCase();\n /**\n * https://github.com/rrweb-io/rrweb/pull/1695\n * This error can occur in a known scenario:\n * If an iframe is initially same-origin and observed, but later its \n location is changed in an opaque way to a cross-origin URL (perhaps within the iframe via its `document.location` or a redirect) \n * attempting to execute the handler in the stop record function will \n throw a \"cannot access cross-origin frame\" error.\n * This error is expected and can be safely ignored.\n */\n if (!msg.includes('cross-origin')) {\n console.warn(error);\n }\n }\n });\n processedNodeManager.destroy();\n recording = false;\n unregisterErrorHandler();\n };\n } catch (error) {\n // TODO: handle internal error\n console.warn(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","// @himetrica/replaykit: session replay and friction signals for the web.\n//\n// import * as ReplayKit from \"@himetrica/replaykit\";\n// ReplayKit.init({ apiKey: \"hm_...\" });\n//\n// Needs the Himetrica tracker on the same page: recordings and signals belong to the\n// tracker's visitor and session. What is recorded, and when, is configured per\n// project in the dashboard; the SDK reads it from /init on every page.\n\nimport { ReplayKitClient, type ReplayKitOptions } from \"./client\";\n\nexport type { ReplayKitOptions } from \"./client\";\nexport type { ReplayKitSignal, ReplayKitSignalType, ReplayKitTrigger } from \"./protocol\";\n\nlet client: ReplayKitClient | null = null;\n\n/** Starts ReplayKit. A second call is ignored. */\nexport function init(options: ReplayKitOptions): void {\n if (client) return;\n client = new ReplayKitClient(options);\n client.start();\n}\n\n/** Record this session from now on (and keep the pre-trigger buffer). */\nexport function start(): void {\n client?.manualStart();\n}\n\n/**\n * Mark this moment as worth a recording, like an error would. `reason` is for your\n * own debugging (logged with `debug: true`); the recording is tagged \"manual\".\n */\nexport function trigger(reason?: string): void {\n client?.manualStart(reason);\n}\n\n/** Stop recording for the rest of the session. What was captured is still uploaded. */\nexport function stop(): void {\n client?.manualStop();\n}\n\n/**\n * The visitor's answer to your consent banner. With \"require consent\" on in the\n * project, nothing is recorded until consent(true). consent(false) stops and drops\n * what was not uploaded yet. Remembered on this device.\n */\nexport function consent(granted: boolean): void {\n if (client) client.consent(granted);\n else {\n try {\n localStorage.setItem(\"hm_rk_consent\", granted ? \"1\" : \"0\");\n } catch {\n // Storage unavailable.\n }\n }\n}\n\n/** Id of the recording running on this page, if any. */\nexport function getRecordingId(): string | null {\n return client?.recordingId() ?? null;\n}\n\n/** Stops everything and removes the listeners (tests, SPA teardown). */\nexport function shutdown(): void {\n client?.destroy();\n client = null;\n}\n","// Per-session recording state, in sessionStorage so it follows the session across the\n// pages of a multi-page site (each page load is a new SDK instance).\n//\n// Keyed to the tracker session id: when the tracker rolls a new session (30 min idle,\n// new UTM...), the stored state belongs to the old one and is discarded.\n\nimport type { Env } from \"./env\";\nimport type { ReplayKitRecordingStats, ReplayKitTrigger } from \"./protocol\";\n\nexport type StopReason = \"quota\" | \"manual\" | \"limit\" | \"off\";\n\nexport interface SessionState {\n sid: string;\n /** Recording id, set once a trigger fired; absent while only buffering. */\n rid?: string;\n /** Next chunk sequence number to upload. */\n seq: number;\n trigger?: ReplayKitTrigger;\n /** Set when recording must not (re)start for the rest of the session. */\n stopped?: StopReason;\n stats?: ReplayKitRecordingStats;\n}\n\nconst KEY = \"hm_rk_state\";\n\nexport class StateStore {\n private cache: SessionState | null = null;\n\n constructor(private readonly env: Env) {}\n\n load(sid: string): SessionState {\n if (this.cache?.sid === sid) return this.cache;\n let s: SessionState | null = null;\n try {\n const raw = this.env.getSession(KEY);\n if (raw) s = JSON.parse(raw) as SessionState;\n } catch {\n s = null;\n }\n if (!s || s.sid !== sid || typeof s.seq !== \"number\") s = { sid, seq: 0 };\n this.cache = s;\n return s;\n }\n\n save(s: SessionState): void {\n this.cache = s;\n try {\n this.env.setSession(KEY, JSON.stringify(s));\n } catch {\n // In-memory copy still drives this page.\n }\n }\n}\n\nexport function emptyStats(now: number, entryUrl: string): ReplayKitRecordingStats {\n return { startedAt: now, endedAt: now, activeMs: 0, clicks: 0, rageClicks: 0, deadClicks: 0, errors: 0, pages: 1, entryUrl };\n}\n","// Browser globals behind one interface, like ErrorKit's env.ts.\n//\n// Network, storage, timers and the clock go through an Env, so the transport, the\n// uploader and the client run in plain Node under node:test with fakes. DOM wiring\n// (listeners, rrweb) stays in signals-dom.ts / recorder.ts and is not unit-tested.\n\nexport interface FetchResult {\n status: number;\n headers: { get(name: string): string | null };\n json(): Promise<unknown>;\n}\n\nexport interface Env {\n now(): number;\n uuid(): string;\n fetch?: (url: string, init: RequestInit) => Promise<FetchResult>;\n sendBeacon?: (url: string, body: string) => boolean;\n getLocal(key: string): string | null;\n setLocal(key: string, value: string | null): void;\n getSession(key: string): string | null;\n setSession(key: string, value: string | null): void;\n getCookie(name: string): string | null;\n /** Async key/value store that survives a page load (IndexedDB). Missing = nothing carried across pages. */\n store?: KvStore;\n /** gzip; undefined when CompressionStream is unavailable (recording is then skipped). */\n gzip?: (text: string) => Promise<Blob>;\n setTimer(fn: () => void, ms: number): unknown;\n clearTimer(handle: unknown): void;\n}\n\nexport interface KvStore {\n get<T>(key: string): Promise<T | undefined>;\n set(key: string, value: unknown): Promise<void>;\n del(key: string): Promise<void>;\n}\n\nexport const isBrowser = typeof window !== \"undefined\" && typeof document !== \"undefined\";\n\nexport function uuidV4(): string {\n const c = (globalThis as { crypto?: Crypto }).crypto;\n if (c && typeof c.randomUUID === \"function\") {\n try {\n return c.randomUUID();\n } catch {\n // randomUUID throws on insecure origins in some browsers; fall through.\n }\n }\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, (ch) => {\n const r = (Math.random() * 16) | 0;\n return (ch === \"x\" ? r : (r & 0x3) | 0x8).toString(16);\n });\n}\n\n// Storage throws in Safari private mode, sandboxed iframes and under storage policies.\nfunction safeGet(storage: () => Storage, key: string): string | null {\n try {\n return storage().getItem(key);\n } catch {\n return null;\n }\n}\n\nfunction safeSet(storage: () => Storage, key: string, value: string | null): void {\n try {\n if (value === null) storage().removeItem(key);\n else storage().setItem(key, value);\n } catch {\n // Unavailable or full: in-memory state still works for this page.\n }\n}\n\n/** One IndexedDB object store used as a key/value map. Every failure degrades to \"nothing stored\". */\nfunction indexedDbStore(): KvStore | undefined {\n if (typeof indexedDB === \"undefined\") return undefined;\n let dbp: Promise<IDBDatabase> | null = null;\n const open = () =>\n (dbp ??= new Promise<IDBDatabase>((resolve, reject) => {\n const req = indexedDB.open(\"himetrica-replaykit\", 1);\n req.onupgradeneeded = () => req.result.createObjectStore(\"kv\");\n req.onsuccess = () => resolve(req.result);\n req.onerror = () => reject(req.error);\n }));\n const run = <T>(mode: IDBTransactionMode, fn: (s: IDBObjectStore) => IDBRequest | void): Promise<T | undefined> =>\n open()\n .then(\n (db) =>\n new Promise<T | undefined>((resolve) => {\n const tx = db.transaction(\"kv\", mode);\n const req = fn(tx.objectStore(\"kv\"));\n tx.oncomplete = () => resolve(req ? (req.result as T) : undefined);\n tx.onerror = tx.onabort = () => resolve(undefined);\n }),\n )\n .catch(() => undefined);\n return {\n get: <T>(key: string) => run<T>(\"readonly\", (s) => s.get(key)),\n set: (key, value) => run<void>(\"readwrite\", (s) => void s.put(value, key)).then(() => undefined),\n del: (key) => run<void>(\"readwrite\", (s) => void s.delete(key)).then(() => undefined),\n };\n}\n\nfunction gzipFn(): Env[\"gzip\"] {\n if (typeof CompressionStream === \"undefined\" || typeof Blob === \"undefined\" || typeof Response === \"undefined\") return undefined;\n return (text) => new Response(new Blob([text]).stream().pipeThrough(new CompressionStream(\"gzip\"))).blob();\n}\n\nexport function browserEnv(): Env {\n const originalFetch = typeof fetch === \"function\" ? fetch.bind(globalThis) : undefined;\n const nav = typeof navigator !== \"undefined\" ? navigator : undefined;\n return {\n now: () => Date.now(),\n uuid: () => uuidV4(),\n fetch: originalFetch as Env[\"fetch\"],\n sendBeacon:\n nav && typeof nav.sendBeacon === \"function\"\n ? (url, body) => {\n try {\n return nav.sendBeacon(url, new Blob([body], { type: \"text/plain\" }));\n } catch {\n return false;\n }\n }\n : undefined,\n getLocal: (key) => safeGet(() => localStorage, key),\n setLocal: (key, value) => safeSet(() => localStorage, key, value),\n getSession: (key) => safeGet(() => sessionStorage, key),\n setSession: (key, value) => safeSet(() => sessionStorage, key, value),\n getCookie: (name) => {\n try {\n const match = document.cookie.match(new RegExp(\"(?:^|; )\" + name.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\") + \"=([^;]*)\"));\n return match ? decodeURIComponent(match[1]) : null;\n } catch {\n return null;\n }\n },\n store: indexedDbStore(),\n gzip: gzipFn(),\n setTimer: (fn, ms) => setTimeout(fn, ms),\n clearTimer: (h) => clearTimeout(h as ReturnType<typeof setTimeout>),\n };\n}\n","// Identity bridge with the analytics tracker, strictly READ-ONLY (same approach as\n// ErrorKit's browser/identity.ts).\n//\n// The tracker (tracker-js / tracker.js) stores the ids in:\n// visitor cookie hm_vid (cookieDomain mode) or localStorage hm_visitor_id\n// session cookie hm_sid (cookieDomain mode) or sessionStorage hm_session_id\n// We read those keys and never write them. window.himetrica.getSessionId() is NOT\n// called: in the tracker it refreshes the session timestamp.\n//\n// A recording or a signal is only worth something tied to the tracker's visitor and\n// session, so without the tracker on the page ReplayKit stays idle.\n\nimport type { Env } from \"./env\";\n\nexport interface Identity {\n visitorId?: string;\n sessionId?: string;\n}\n\nexport function readIdentity(env: Env): Identity {\n const visitorId = env.getCookie(\"hm_vid\") || env.getLocal(\"hm_visitor_id\") || undefined;\n const sessionId = env.getCookie(\"hm_sid\") || env.getSession(\"hm_session_id\") || undefined;\n return { visitorId, sessionId };\n}\n","// Pure helpers the recording decision is made of: path globs and the session sample.\n\n/**\n * Path glob, as the project config writes them: `*` matches any run of characters\n * (slashes included), everything else is literal. A pattern without `*` is a prefix\n * on a segment boundary: `/checkout` matches `/checkout` and `/checkout/step-2`, not\n * `/checkouts`. Matched against the pathname only, case-insensitive.\n */\nexport function matchPath(pattern: string, pathname: string): boolean {\n const p = pattern.trim().toLowerCase();\n if (!p) return false;\n const path = (pathname || \"/\").toLowerCase();\n if (!p.includes(\"*\")) {\n const base = p.endsWith(\"/\") && p.length > 1 ? p.slice(0, -1) : p;\n return path === base || path.startsWith(base.endsWith(\"/\") ? base : base + \"/\");\n }\n const re = new RegExp(\"^\" + p.split(\"*\").map(escapeRegExp).join(\".*\") + \"$\");\n return re.test(path);\n}\n\nexport function matchAny(patterns: readonly string[], pathname: string): boolean {\n for (const p of patterns) if (matchPath(p, pathname)) return true;\n return false;\n}\n\nfunction escapeRegExp(s: string): string {\n return s.replace(/[.+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\n/**\n * Deterministic [0, 1) from the session id (cyrb53). Every page of a session gets the\n * same draw, so a sampled session is recorded across all its pages, and the server\n * could recompute it.\n */\nexport function sampleDraw(sessionId: string): number {\n let h1 = 0xdeadbeef;\n let h2 = 0x41c6ce57;\n for (let i = 0; i < sessionId.length; i++) {\n const ch = sessionId.charCodeAt(i);\n h1 = Math.imul(h1 ^ ch, 2654435761);\n h2 = Math.imul(h2 ^ ch, 1597334677);\n }\n h1 = Math.imul(h1 ^ (h1 >>> 16), 2246822507) ^ Math.imul(h2 ^ (h2 >>> 13), 3266489909);\n h2 = Math.imul(h2 ^ (h2 >>> 16), 2246822507) ^ Math.imul(h1 ^ (h1 >>> 13), 3266489909);\n const n = 4294967296 * (2097151 & h2) + (h1 >>> 0);\n return n / 9007199254740992;\n}\n\nexport function inSample(sessionId: string, rate: number): boolean {\n if (!(rate > 0)) return false;\n if (rate >= 1) return true;\n return sampleDraw(sessionId) < rate;\n}\n\n/** URL without query and hash: queries carry tokens and emails, never sent. */\nexport function stripUrl(href: string): string {\n const cut = href.search(/[?#]/);\n return cut === -1 ? href : href.slice(0, cut);\n}\n","// The pre-trigger ring buffer.\n//\n// rrweb can only replay from a full snapshot: a Meta event (type 4) followed by a\n// FullSnapshot (type 2). The recorder takes one every CHECKOUT_MS, so the buffer can\n// always be cut at the last checkout that is older than the window and still start\n// with a replayable page. The cut keeps BUFFER_WINDOW_MS..BUFFER_WINDOW_MS+CHECKOUT_MS\n// of history before the trigger.\n\nexport interface RrEvent {\n type: number;\n timestamp: number;\n data?: unknown;\n}\n\nexport const EVENT_FULL_SNAPSHOT = 2;\nexport const EVENT_META = 4;\nexport const EVENT_CUSTOM = 5;\n/** rrweb custom event the SDK adds on SPA URL changes (rrweb only emits Meta on page loads/checkouts). */\nexport const PAGE_TAG = \"replaykit:page\";\n\n/**\n * Pages shown in a run of events, in order: Meta hrefs (page loads, and every\n * checkout repeats the current one) plus PAGE_TAG custom events. Query/fragment\n * stripped, back-to-back repeats folded, `prev` = last page already reported for\n * this recording (so a checkout's repeated Meta is not a new page). Capped at `max`.\n */\nexport function pagesOf(events: RrEvent[], prev: string, max: number): Array<{ url: string; ts: number }> {\n const out: Array<{ url: string; ts: number }> = [];\n let last = prev;\n for (const e of events) {\n let href: unknown;\n if (e.type === EVENT_META) href = (e.data as { href?: unknown } | undefined)?.href;\n else if (e.type === EVENT_CUSTOM) {\n const d = e.data as { tag?: unknown; payload?: { href?: unknown } } | undefined;\n if (d?.tag === PAGE_TAG) href = d.payload?.href;\n }\n if (typeof href !== \"string\" || !href) continue;\n const cut = href.search(/[?#]/);\n const url = (cut === -1 ? href : href.slice(0, cut)).slice(0, 500);\n if (url === last) continue;\n last = url;\n out.push({ url, ts: e.timestamp });\n if (out.length >= max) break;\n }\n return out;\n}\n\nexport const BUFFER_WINDOW_MS = 30_000;\nexport const CHECKOUT_MS = 30_000;\n\n/** Index of the Meta event that opens the snapshot the event list may start from. */\nfunction snapshotStart(events: RrEvent[], i: number): number {\n // rrweb emits Meta right before FullSnapshot; keep the Meta so the player knows the viewport.\n return i > 0 && events[i - 1].type === EVENT_META ? i - 1 : i;\n}\n\n/**\n * Drops everything before the most recent full snapshot whose timestamp is at or\n * before `now - windowMs`. If no snapshot is that old, nothing is dropped (the buffer\n * is still shorter than the window). A list that does not start with a snapshot (the\n * head was lost) is cut at its first snapshot, since nothing before it can replay.\n */\nexport function trimBuffer(events: RrEvent[], now: number, windowMs = BUFFER_WINDOW_MS): RrEvent[] {\n const cutoff = now - windowMs;\n let keepFrom = -1;\n let firstSnapshot = -1;\n for (let i = 0; i < events.length; i++) {\n if (events[i].type !== EVENT_FULL_SNAPSHOT) continue;\n if (firstSnapshot === -1) firstSnapshot = i;\n if (events[i].timestamp <= cutoff) keepFrom = i;\n else break;\n }\n if (keepFrom === -1) keepFrom = firstSnapshot;\n if (keepFrom === -1) return [];\n const start = snapshotStart(events, keepFrom);\n return start === 0 ? events : events.slice(start);\n}\n\n/** Rough serialized size, to cut chunks without stringifying on every event. */\nexport function approxBytes(e: RrEvent): number {\n // Mutations and snapshots dominate; JSON.stringify per event is acceptable: events\n // are stringified once here and the chunk is re-stringified once at flush.\n try {\n return JSON.stringify(e).length;\n } catch {\n return 0;\n }\n}\n","// Friction detectors, DOM-free so node:test can drive them with plain numbers.\n// signals-dom.ts feeds them real clicks and reports what they decide.\n\nexport interface ClickPoint {\n x: number;\n y: number;\n ts: number;\n /** Stable key of the clicked element (its selector), so a burst on one button counts even if the mouse drifts. */\n target: string;\n}\n\n/** 3+ clicks within RAGE_WINDOW_MS, on the same element or within RAGE_RADIUS_PX of the first. */\nexport const RAGE_MIN_CLICKS = 3;\nexport const RAGE_WINDOW_MS = 1000;\nexport const RAGE_RADIUS_PX = 30;\n\nexport interface RageBurst {\n first: ClickPoint;\n count: number;\n lastTs: number;\n}\n\n/**\n * Feeds clicks in order. `onClick` returns \"trigger\" on the click that turns a burst\n * into a rage click (the 3rd), so recording starts right away; the finished burst\n * (with its final count) comes out of `onClick` of the next unrelated click or of\n * `flush(now)` once the window has passed.\n */\nexport class RageDetector {\n private burst: RageBurst | null = null;\n\n onClick(c: ClickPoint): { trigger: boolean; finished: RageBurst | null } {\n const b = this.burst;\n if (b && c.ts - b.lastTs <= RAGE_WINDOW_MS && near(b.first, c)) {\n b.count++;\n b.lastTs = c.ts;\n return { trigger: b.count === RAGE_MIN_CLICKS, finished: null };\n }\n const finished = b && b.count >= RAGE_MIN_CLICKS ? b : null;\n this.burst = { first: c, count: 1, lastTs: c.ts };\n return { trigger: false, finished };\n }\n\n /** The burst that ended (quiet for the window) before `now`, if it was a rage click. */\n flush(now: number): RageBurst | null {\n const b = this.burst;\n if (!b || now - b.lastTs <= RAGE_WINDOW_MS) return null;\n this.burst = null;\n return b.count >= RAGE_MIN_CLICKS ? b : null;\n }\n\n /** Clicks of the current burst so far (a rage burst is not also a dead click). */\n currentCount(): number {\n return this.burst?.count ?? 0;\n }\n}\n\nfunction near(a: ClickPoint, b: ClickPoint): boolean {\n if (a.target && a.target === b.target) return true;\n return Math.abs(a.x - b.x) <= RAGE_RADIUS_PX && Math.abs(a.y - b.y) <= RAGE_RADIUS_PX;\n}\n\n/** How long after a click something must happen for the click not to be \"dead\". */\nexport const DEAD_CLICK_WAIT_MS = 500;\n\nexport interface ClickTargetFacts {\n /** Lowercase tag name of the clicked element. */\n tag: string;\n /** The element or an ancestor is a link/button/[role=button…]/[onclick]/summary. */\n insideInteractive: boolean;\n /** Text fields, selects, labels, contenteditable: a click there focuses, nothing else to expect. */\n isFormField: boolean;\n /** Computed cursor is \"pointer\": the page tells the user it is clickable. */\n pointerCursor: boolean;\n /** Text is selected after the click (the user was selecting, not clicking). */\n hasSelection: boolean;\n}\n\n/**\n * A click can only be dead when the element promised something: it is (inside) an\n * interactive element or shows a pointer cursor. A click on plain text or on a\n * background is not friction, whatever happens after it.\n */\nexport function isDeadClickCandidate(f: ClickTargetFacts): boolean {\n if (f.isFormField || f.hasSelection) return false;\n if (f.tag === \"html\" || f.tag === \"body\") return false;\n return f.insideInteractive || f.pointerCursor;\n}\n\nexport interface AfterClickReaction {\n /** DOM mutations observed in the wait window. */\n mutations: number;\n urlChanged: boolean;\n scrolled: boolean;\n focusChanged: boolean;\n /** The page is unloading (a navigation or a download started). */\n unloading: boolean;\n}\n\n/** Nothing reacted within DEAD_CLICK_WAIT_MS: the click was dead. */\nexport function isDeadClick(r: AfterClickReaction): boolean {\n return r.mutations === 0 && !r.urlChanged && !r.scrolled && !r.focusChanged && !r.unloading;\n}\n\n/** Active time: input gaps up to ACTIVE_GAP_MS count, longer gaps are idle. */\nexport const ACTIVE_GAP_MS = 5000;\n\nexport function activeIncrement(lastInputTs: number, ts: number): number {\n if (!lastInputTs) return 0;\n const gap = ts - lastInputTs;\n return gap > 0 && gap <= ACTIVE_GAP_MS ? gap : 0;\n}\n","// What this page does about recording, from what /init said and the session state.\n// Pure, so the whole decision table is unit-tested.\n\nimport type { ReplayKitTrigger } from \"./protocol\";\nimport type { SessionState } from \"./state\";\n\nexport type PageMode =\n /** Nothing is recorded on this page (signals may still flow). */\n | { kind: \"off\" }\n /** requireConsent and the banner has not said yes yet. */\n | { kind: \"wait_consent\" }\n /** A recording of this session is already running: continue it. */\n | { kind: \"continue\" }\n /** Start a recording now, for this reason. */\n | { kind: \"start\"; trigger: ReplayKitTrigger }\n /** Keep the pre-trigger buffer and wait for a trigger. */\n | { kind: \"buffer\" };\n\nexport interface DecideInput {\n /** /init answered record: true. */\n record: boolean;\n /** CompressionStream exists (chunks are gzip'd in the browser). */\n canGzip: boolean;\n state: SessionState;\n /** Path is in excludePaths. */\n excluded: boolean;\n requireConsent: boolean;\n /** Consent stored by ReplayKit.consent(): true, false, or never given. */\n consent: boolean | null;\n forceTrigger: ReplayKitTrigger | null;\n sampled: boolean;\n /** Path matched checkoutPaths and \"checkout\" is an enabled trigger. */\n checkout: boolean;\n}\n\nexport function decidePage(i: DecideInput): PageMode {\n // An explicit ReplayKit.consent(false) wins even when the project does not require consent.\n if (!i.record || !i.canGzip || i.state.stopped || i.excluded || i.consent === false) return { kind: \"off\" };\n if (i.requireConsent && i.consent !== true) return { kind: \"wait_consent\" };\n if (i.state.rid) return { kind: \"continue\" };\n if (i.forceTrigger) return { kind: \"start\", trigger: i.forceTrigger };\n if (i.checkout) return { kind: \"start\", trigger: \"checkout\" };\n if (i.sampled) return { kind: \"start\", trigger: \"sample\" };\n return { kind: \"buffer\" };\n}\n","// Calls to the ingest (POST {apiUrl}/api/t/r/<op>?apiKey=...), text/plain JSON so\n// they are \"simple\" CORS requests with no preflight, plus the PUT of a chunk to R2.\n//\n// Every response is reduced to an outcome the client acts on (see the contract in\n// packages/shared/src/replaykit.ts):\n// ok 2xx\n// drop 400/413: this body is unusable, forget it\n// stop 401: bad key / origin not allowed, ReplayKit stops for this page\n// off 403: rollout, plan or this op is off for the project\n// quota 429: no more recordings this session (signals continue)\n// retry 5xx, network error, or no fetch at all\n\nimport type { Env } from \"./env\";\nimport type {\n ReplayKitChunkRequest,\n ReplayKitChunkResponse,\n ReplayKitInitRequest,\n ReplayKitInitResponse,\n ReplayKitSignalsRequest,\n} from \"./protocol\";\n\nexport type Outcome = \"ok\" | \"drop\" | \"stop\" | \"off\" | \"quota\" | \"retry\";\n\nexport function outcomeOf(status: number): Outcome {\n if (status >= 200 && status < 300) return \"ok\";\n if (status === 401) return \"stop\";\n if (status === 403) return \"off\";\n if (status === 429) return \"quota\";\n if (status === 400 || status === 413 || status === 404 || status === 422) return \"drop\";\n return \"retry\";\n}\n\nexport interface Result<T> {\n outcome: Outcome;\n data?: T;\n}\n\nexport class Api {\n constructor(\n private readonly env: Env,\n private readonly apiUrl: string,\n private readonly apiKey: string,\n ) {}\n\n url(op: \"init\" | \"chunk\" | \"signals\"): string {\n return `${this.apiUrl}/api/t/r/${op}?apiKey=${encodeURIComponent(this.apiKey)}`;\n }\n\n init(body: ReplayKitInitRequest): Promise<Result<ReplayKitInitResponse>> {\n return this.post<ReplayKitInitResponse>(\"init\", body, true);\n }\n\n chunk(body: ReplayKitChunkRequest): Promise<Result<ReplayKitChunkResponse>> {\n return this.post<ReplayKitChunkResponse>(\"chunk\", body, true);\n }\n\n signals(body: ReplayKitSignalsRequest): Promise<Result<void>> {\n return this.post<void>(\"signals\", body, false);\n }\n\n /** On page hide: fire-and-forget. False when the beacon could not be queued. */\n beaconSignals(body: ReplayKitSignalsRequest): boolean {\n return !!this.env.sendBeacon?.(this.url(\"signals\"), JSON.stringify(body));\n }\n\n /** PUT the gzip'd chunk to the presigned R2 URL. R2 answers 200; 403 = URL expired or bad signature. */\n async put(url: string, blob: Blob): Promise<Outcome> {\n if (!this.env.fetch) return \"retry\";\n try {\n const res = await this.env.fetch(url, { method: \"PUT\", body: blob, headers: { \"Content-Type\": \"application/gzip\" } });\n if (res.status >= 200 && res.status < 300) return \"ok\";\n // An expired/rejected signature is fixed by asking for a new URL, not by dropping the chunk.\n return res.status === 400 || res.status === 413 ? \"drop\" : \"retry\";\n } catch {\n return \"retry\";\n }\n }\n\n private async post<T>(op: \"init\" | \"chunk\" | \"signals\", body: unknown, wantJson: boolean): Promise<Result<T>> {\n if (!this.env.fetch) return { outcome: \"retry\" };\n try {\n const res = await this.env.fetch(this.url(op), {\n method: \"POST\",\n body: JSON.stringify(body),\n headers: { \"Content-Type\": \"text/plain\" },\n keepalive: false,\n credentials: \"omit\",\n });\n const outcome = outcomeOf(res.status);\n if (outcome !== \"ok\" || !wantJson) return { outcome };\n try {\n return { outcome, data: (await res.json()) as T };\n } catch {\n return { outcome: \"retry\" };\n }\n } catch {\n return { outcome: \"retry\" };\n }\n }\n}\n\nexport const BASE_BACKOFF_MS = 2_000;\nexport const MAX_BACKOFF_MS = 60_000;\n\nexport function backoff(failures: number): number {\n return Math.min(MAX_BACKOFF_MS, BASE_BACKOFF_MS * 2 ** Math.max(0, failures - 1));\n}\n","// Signals out: batched POST /api/t/r/signals every FLUSH_MS (or at a full batch),\n// sendBeacon for whatever is left when the page hides.\n//\n// Signals are cheap and never count against the quota, but a page in a rage loop\n// should not turn into a request loop: at most MAX_PER_PAGE signals per page load,\n// a full batch per request, and identical signals within DEDUPE_MS folded.\n\nimport type { Env } from \"./env\";\nimport { REPLAYKIT_MAX_SIGNALS_PER_BATCH, type ReplayKitSignal } from \"./protocol\";\nimport { backoff, type Api } from \"./transport\";\n\nexport const SIGNAL_FLUSH_MS = 5_000;\nexport const MAX_PER_PAGE = 200;\nconst MAX_QUEUED = 500;\nconst DEDUPE_MS = 2_000;\n\nexport class SignalQueue {\n private queue: ReplayKitSignal[] = [];\n private timer: unknown = null;\n private sentThisPage = 0;\n private failures = 0;\n private busy = false;\n private last = new Map<string, number>();\n /** Ingest said no (403 off, 401 bad key): nothing more this page. */\n disabled = false;\n /** Init has not answered yet: keep collecting, send nothing. */\n held = true;\n\n constructor(\n private readonly env: Env,\n private readonly api: Api,\n private readonly ids: () => { sid: string; vid: string; rid?: string },\n ) {}\n\n add(s: ReplayKitSignal): void {\n if (this.disabled || this.sentThisPage + this.queue.length >= MAX_PER_PAGE) return;\n const key = `${s.type}|${s.url}|${s.selector || \"\"}|${s.detail || \"\"}`;\n const prev = this.last.get(key);\n if (prev !== undefined && s.ts - prev < DEDUPE_MS) return;\n this.last.set(key, s.ts);\n this.queue.push(s);\n if (this.queue.length > MAX_QUEUED) this.queue.shift();\n if (this.held) return;\n if (this.queue.length >= REPLAYKIT_MAX_SIGNALS_PER_BATCH) this.schedule(0);\n else if (!this.timer) this.schedule(SIGNAL_FLUSH_MS);\n }\n\n /** Init answered: start sending (signals on) or drop everything (off). */\n release(enabled: boolean): void {\n this.held = false;\n if (!enabled) {\n this.disable();\n return;\n }\n if (this.queue.length) this.schedule(0);\n }\n\n disable(): void {\n this.disabled = true;\n this.queue = [];\n if (this.timer) this.env.clearTimer(this.timer);\n this.timer = null;\n }\n\n private schedule(ms: number): void {\n if (this.timer) this.env.clearTimer(this.timer);\n this.timer = this.env.setTimer(() => {\n this.timer = null;\n void this.flush();\n }, ms);\n }\n\n async flush(): Promise<void> {\n if (this.busy || this.held || this.disabled) return;\n this.busy = true;\n try {\n while (this.queue.length && !this.disabled) {\n const batch = this.queue.slice(0, REPLAYKIT_MAX_SIGNALS_PER_BATCH);\n const r = await this.api.signals({ ...this.ids(), signals: batch });\n if (r.outcome === \"ok\" || r.outcome === \"drop\" || r.outcome === \"quota\") {\n // 429 on signals would be a server bug (they never count): drop the batch, don't loop.\n this.queue.splice(0, batch.length);\n this.sentThisPage += batch.length;\n this.failures = 0;\n continue;\n }\n if (r.outcome === \"off\" || r.outcome === \"stop\") {\n this.disable();\n return;\n }\n this.failures++;\n this.schedule(backoff(this.failures));\n return;\n }\n } finally {\n this.busy = false;\n }\n }\n\n /** Page hide: beacon what is left (no status to read; a lost beacon loses a few signals). */\n beacon(): void {\n if (this.held || this.disabled || !this.queue.length) return;\n while (this.queue.length) {\n const batch = this.queue.slice(0, REPLAYKIT_MAX_SIGNALS_PER_BATCH);\n if (!this.api.beaconSignals({ ...this.ids(), signals: batch })) return;\n this.queue.splice(0, batch.length);\n this.sentThisPage += batch.length;\n }\n }\n\n get size(): number {\n return this.queue.length;\n }\n}\n","// DOM side of the friction signals: listeners that turn real clicks, errors,\n// navigations and forms into ReplayKitSignal values. The decisions themselves\n// (what is a rage click, what is a dead click) live in detect.ts.\n//\n// Passive capture-phase listeners only; nothing is patched. The MutationObserver a\n// dead-click check needs is attached for DEAD_CLICK_WAIT_MS after a candidate click\n// and disconnected right after, so a quiet page costs nothing.\n//\n// Never sent: what was typed. A clicked element's text is only read when it is not a\n// field and not masked (.hm-mask, [data-hm-mask], or maskAllText).\n\nimport {\n DEAD_CLICK_WAIT_MS,\n isDeadClick,\n isDeadClickCandidate,\n RAGE_WINDOW_MS,\n RageDetector,\n type ClickTargetFacts,\n} from \"./detect\";\nimport { stripUrl } from \"./match\";\nimport type { ReplayKitSignal } from \"./protocol\";\n\nexport interface SignalHooks {\n now(): number;\n /** Text of clicked elements is withheld (config maskAllText). */\n maskAllText(): boolean;\n signal(s: ReplayKitSignal): void;\n /** A trigger fired: the 3rd click of a rage burst, or a JS error. */\n trigger(t: \"rage_click\" | \"error\"): void;\n /** Any click / key / scroll, for active time and click counts. */\n input(kind: \"click\" | \"key\" | \"scroll\", ts: number): void;\n /** The URL changed without a page load (SPA navigation). */\n navigated(url: string): void;\n}\n\nconst INTERACTIVE = 'a[href],button,summary,[role=\"button\"],[role=\"link\"],[role=\"tab\"],[role=\"menuitem\"],[role=\"checkbox\"],[role=\"switch\"],[role=\"option\"],[onclick]';\nconst FIELD = \"input,textarea,select,label,option,[contenteditable],[contenteditable=true]\";\nconst MASKED = \".hm-mask,[data-hm-mask],[data-hm-block],.hm-block\";\nconst MAX_TEXT = 80;\nconst MAX_DETAIL = 200;\n\n/** Short CSS path: up to 3 levels, stops at an id. Hashed class names (css-1x2y3z) are skipped. */\nexport function selectorOf(el: Element | null): string {\n const parts: string[] = [];\n let cur: Element | null = el;\n for (let depth = 0; cur && depth < 3 && cur.nodeType === 1; depth++) {\n const tag = cur.tagName.toLowerCase();\n if (tag === \"html\" || tag === \"body\") break;\n if (cur.id && /^[A-Za-z][\\w-]{0,40}$/.test(cur.id) && !/\\d{3,}/.test(cur.id)) {\n parts.unshift(`${tag}#${cur.id}`);\n break;\n }\n const classes = (typeof cur.className === \"string\" ? cur.className : \"\")\n .split(/\\s+/)\n .filter((c) => c && c.length < 30 && !/\\d{3,}|^css-|^sc-|__/.test(c))\n .slice(0, 2);\n parts.unshift(tag + classes.map((c) => \".\" + c).join(\"\"));\n cur = cur.parentElement;\n }\n return parts.join(\" > \");\n}\n\nfunction visibleText(el: Element, maskAll: boolean): string | undefined {\n if (maskAll || el.closest(MASKED) || el.closest(FIELD)) return undefined;\n const t = ((el as HTMLElement).innerText ?? el.textContent ?? \"\").replace(/\\s+/g, \" \").trim();\n if (!t) return (el.getAttribute(\"aria-label\") || el.getAttribute(\"title\") || undefined)?.slice(0, MAX_TEXT);\n return t.slice(0, MAX_TEXT);\n}\n\nfunction targetFacts(el: Element): ClickTargetFacts {\n let pointer = false;\n try {\n pointer = getComputedStyle(el).cursor === \"pointer\";\n } catch {\n pointer = false;\n }\n const sel = typeof getSelection === \"function\" ? getSelection() : null;\n return {\n tag: el.tagName.toLowerCase(),\n insideInteractive: !!el.closest(INTERACTIVE),\n isFormField: !!el.closest(FIELD),\n pointerCursor: pointer,\n hasSelection: !!sel && !sel.isCollapsed && sel.toString().trim().length > 0,\n };\n}\n\n/** The element a click \"means\": the nearest interactive ancestor, else the target itself. */\nfunction clickedElement(target: EventTarget | null): Element | null {\n const el = target instanceof Element ? target : target instanceof Node ? target.parentElement : null;\n if (!el) return null;\n return el.closest(INTERACTIVE) || el;\n}\n\nexport class SignalCollector {\n private rage = new RageDetector();\n private rageEl: Element | null = null;\n private rageTimer: ReturnType<typeof setTimeout> | null = null;\n private lastHref = \"\";\n private hrefTimer: ReturnType<typeof setInterval> | null = null;\n private unloading = false;\n private lastScrollInput = 0;\n private forms = new Map<HTMLFormElement, Set<string>>();\n private errorsSeen = new Set<string>();\n private off: Array<() => void> = [];\n\n constructor(private readonly h: SignalHooks) {}\n\n start(): void {\n this.lastHref = location.href;\n const on = <K extends keyof WindowEventMap>(type: K, fn: (e: WindowEventMap[K]) => void, target: Window | Document = window) => {\n const opts = { capture: true, passive: true };\n target.addEventListener(type, fn as EventListener, opts);\n this.off.push(() => target.removeEventListener(type, fn as EventListener, opts));\n };\n on(\"click\", (e) => this.onClick(e));\n on(\"keydown\", () => this.h.input(\"key\", this.h.now()));\n on(\"scroll\", () => {\n const now = this.h.now();\n if (now - this.lastScrollInput > 250) {\n this.lastScrollInput = now;\n this.h.input(\"scroll\", now);\n }\n });\n on(\"error\", (e) => this.onError(e.message || (e.error as Error | undefined)?.message || \"\"));\n on(\"unhandledrejection\", (e) => {\n const r = e.reason as { message?: string } | string | undefined;\n this.onError(typeof r === \"string\" ? r : r?.message || \"Unhandled promise rejection\");\n });\n on(\"popstate\", () => this.backNav());\n on(\"input\", (e) => this.onField(e.target));\n on(\"change\", (e) => this.onField(e.target));\n on(\"submit\", (e) => {\n if (e.target instanceof HTMLFormElement) this.forms.delete(e.target);\n });\n on(\"pageshow\", () => {\n this.unloading = false;\n });\n // SPA navigations: no patching of history, a cheap href poll instead.\n this.hrefTimer = setInterval(() => this.checkHref(), 1000);\n // Arrived here with the back/forward button.\n try {\n const nav = performance.getEntriesByType(\"navigation\")[0] as PerformanceNavigationTiming | undefined;\n if (nav?.type === \"back_forward\") this.emit({ type: \"back_nav\", detail: stripUrl(location.href) });\n } catch {\n // Navigation Timing unavailable.\n }\n }\n\n stop(): void {\n for (const f of this.off) f();\n this.off = [];\n if (this.hrefTimer) clearInterval(this.hrefTimer);\n if (this.rageTimer) clearTimeout(this.rageTimer);\n this.hrefTimer = this.rageTimer = null;\n }\n\n /** Called by the client on pagehide, before it beacons the queue: report what the page leaves behind. */\n pageHide(): void {\n this.unloading = true;\n this.flushForms();\n this.flushRage(true);\n }\n\n private emit(s: Omit<ReplayKitSignal, \"ts\" | \"url\"> & { ts?: number }): void {\n this.h.signal({ ts: s.ts ?? this.h.now(), url: stripUrl(location.href), ...s } as ReplayKitSignal);\n }\n\n private checkHref(): void {\n const href = location.href;\n if (href === this.lastHref) return;\n const prev = this.lastHref;\n this.lastHref = href;\n if (stripUrl(href) !== stripUrl(prev)) this.h.navigated(stripUrl(href));\n }\n\n private onClick(e: MouseEvent): void {\n const ts = this.h.now();\n this.h.input(\"click\", ts);\n const el = clickedElement(e.target);\n if (!el) return;\n const selector = selectorOf(el);\n const r = this.rage.onClick({ x: e.clientX, y: e.clientY, ts, target: selector });\n if (r.finished) this.reportRage(r.finished.count, r.finished.first.ts);\n if (r.trigger) this.h.trigger(\"rage_click\");\n this.rageEl = this.rage.currentCount() === 1 ? el : this.rageEl;\n if (this.rageTimer) clearTimeout(this.rageTimer);\n this.rageTimer = setTimeout(() => this.flushRage(false), RAGE_WINDOW_MS + 50);\n if (this.rage.currentCount() === 1) this.watchDeadClick(el, selector, ts);\n }\n\n private flushRage(force: boolean): void {\n const b = this.rage.flush(force ? Number.MAX_SAFE_INTEGER : this.h.now());\n if (b) this.reportRage(b.count, b.first.ts);\n }\n\n private reportRage(count: number, ts: number): void {\n const el = this.rageEl;\n this.emit({ type: \"rage_click\", ts, count, selector: el ? selectorOf(el) : undefined, text: el ? visibleText(el, this.h.maskAllText()) : undefined });\n }\n\n private watchDeadClick(el: Element, selector: string, ts: number): void {\n if (!isDeadClickCandidate(targetFacts(el))) return;\n const hrefBefore = location.href;\n const scrollBefore = `${scrollX},${scrollY}`;\n const focusBefore = document.activeElement;\n let mutations = 0;\n let mo: MutationObserver | null = null;\n try {\n mo = new MutationObserver((list) => {\n mutations += list.length;\n });\n mo.observe(document.documentElement, { subtree: true, childList: true, attributes: true, characterData: true });\n } catch {\n return;\n }\n setTimeout(() => {\n mo?.disconnect();\n // Part of a rage burst: reported as a rage click, not also as a dead one.\n if (this.rage.currentCount() > 1) return;\n const dead = isDeadClick({\n mutations,\n urlChanged: location.href !== hrefBefore,\n scrolled: `${scrollX},${scrollY}` !== scrollBefore,\n focusChanged: document.activeElement !== focusBefore && document.activeElement !== el,\n unloading: this.unloading,\n });\n if (dead) this.emit({ type: \"dead_click\", ts, selector, text: visibleText(el, this.h.maskAllText()) });\n }, DEAD_CLICK_WAIT_MS);\n }\n\n private onError(message: string): void {\n const detail = (message || \"Error\").slice(0, MAX_DETAIL);\n if (this.errorsSeen.has(detail)) return;\n this.errorsSeen.add(detail);\n this.emit({ type: \"error\", detail });\n this.h.trigger(\"error\");\n }\n\n private backNav(): void {\n this.emit({ type: \"back_nav\", detail: stripUrl(location.href) });\n this.checkHref();\n }\n\n private onField(target: EventTarget | null): void {\n if (!(target instanceof Element)) return;\n const form = target.closest(\"form\");\n if (!form) return;\n const key = target.getAttribute(\"name\") || target.id || selectorOf(target);\n let set = this.forms.get(form);\n if (!set) this.forms.set(form, (set = new Set()));\n set.add(key);\n }\n\n /** Forms touched and never submitted, reported when the page goes away. */\n private flushForms(): void {\n for (const [form, fields] of this.forms) {\n if (!form.isConnected && fields.size === 0) continue;\n this.emit({ type: \"form_abandon\", selector: selectorOf(form), count: fields.size });\n }\n this.forms.clear();\n }\n}\n","// rrweb, loaded only when this page may record.\n//\n// The ESM build turns the dynamic import into a separate chunk, so a page that only\n// sends signals never downloads rrweb (~24 KB gzip). The IIFE build bundles it.\n//\n// Privacy defaults that config cannot turn off:\n// - every input value is masked (maskAllInputs), passwords and card fields included;\n// - card fields ([autocomplete^=\"cc-\"]) and [data-hm-block] / .hm-block are blocked:\n// replaced by an empty box of the same size, their content never leaves the page;\n// - text marked .hm-mask / [data-hm-mask] is masked; maskAllText masks every text node;\n// - canvas, cross-origin iframes and inlined images are not recorded.\n\nimport type { RrEvent } from \"./buffer\";\nimport { CHECKOUT_MS, PAGE_TAG } from \"./buffer\";\n\nexport interface RecorderOptions {\n blockSelectors: string[];\n maskAllText: boolean;\n emit(e: RrEvent): void;\n}\n\ntype RecordFn = typeof import(\"@rrweb/record\").record;\n\nconst BASE_BLOCK = ['[data-hm-block]', \".hm-block\", '[autocomplete^=\"cc-\"]', 'input[type=\"password\"]'];\nconst BASE_MASK = \".hm-mask,[data-hm-mask]\";\n\nlet recordFn: Promise<RecordFn> | null = null;\n\nfunction loadRecord(): Promise<RecordFn> {\n return (recordFn ??= import(\"@rrweb/record\").then((m) => m.record));\n}\n\n/** Drops selectors the browser rejects: one bad entry in the config must not stop rrweb. */\nexport function validSelectors(list: string[]): string[] {\n return list.filter((s) => {\n if (!s || typeof s !== \"string\") return false;\n try {\n document.createDocumentFragment().querySelector(s);\n return true;\n } catch {\n return false;\n }\n });\n}\n\nexport class Recorder {\n private stopFn: (() => void) | undefined;\n private record: RecordFn | null = null;\n private stopped = false;\n\n async start(o: RecorderOptions): Promise<boolean> {\n try {\n this.record = await loadRecord();\n } catch {\n return false;\n }\n if (this.stopped) return false;\n try {\n this.stopFn = this.record({\n emit: (e) => o.emit(e as unknown as RrEvent),\n checkoutEveryNms: CHECKOUT_MS,\n maskAllInputs: true,\n maskInputOptions: { password: true },\n maskTextSelector: o.maskAllText ? \"*\" : BASE_MASK,\n blockSelector: validSelectors([...BASE_BLOCK, ...o.blockSelectors]).join(\",\"),\n recordCanvas: false,\n recordCrossOriginIframes: false,\n inlineImages: false,\n collectFonts: false,\n slimDOMOptions: { script: true, comment: true, headFavicon: true, headWhitespace: true, headMetaSocial: true, headMetaRobots: true, headMetaHttpEquiv: true, headMetaVerification: true, headMetaAuthorship: true },\n sampling: { mousemove: 50, scroll: 150, input: \"last\" },\n }) ?? undefined;\n return !!this.stopFn;\n } catch {\n return false;\n }\n }\n\n /** New full snapshot right now (the first event of a fresh recording must be one). */\n snapshot(): void {\n try {\n this.record?.takeFullSnapshot(true);\n } catch {\n // Not recording.\n }\n }\n\n /** Marks an SPA URL change in the stream (the player and the page list read it). */\n page(href: string): void {\n try {\n this.record?.addCustomEvent(PAGE_TAG, { href });\n } catch {\n // Not recording.\n }\n }\n\n stop(): void {\n this.stopped = true;\n try {\n this.stopFn?.();\n } catch {\n // Already stopped.\n }\n this.stopFn = undefined;\n }\n}\n","// Live recording upload: rrweb events → gzip'd chunk → presigned PUT straight to R2.\n//\n// Per chunk: POST /api/t/r/chunk (the API answers with a presigned URL and, on seq 0,\n// opens the recording and counts it in the quota), then PUT the gzip to R2. Nothing\n// of the recording passes through our servers.\n//\n// A chunk goes out every FLUSH_MS or once FLUSH_BYTES of raw JSON piled up. The two\n// requests cannot be trusted to finish while a page unloads, so on page hide the\n// unsent events (queued and in flight) are written to IndexedDB instead, and the\n// next page of the same session uploads them before its own. A session that never\n// comes back loses its last few seconds; nothing else is lost.\n//\n// seq advances only after R2 accepted the PUT, so a retry re-uses the same seq and\n// overwrites the same object: retries are idempotent end to end.\n\nimport type { Env } from \"./env\";\nimport { approxBytes, pagesOf, type RrEvent } from \"./buffer\";\nimport { REPLAYKIT_MAX_CHUNK_BYTES, REPLAYKIT_MAX_CHUNKS, REPLAYKIT_MAX_PAGES_PER_CHUNK, type ReplayKitChunkFile } from \"./protocol\";\nimport type { StateStore, SessionState, StopReason } from \"./state\";\nimport { backoff, type Api } from \"./transport\";\n\nexport const FLUSH_MS = 30_000;\nexport const FLUSH_BYTES = 256 * 1024;\n\nconst pendingKey = (sid: string) => `rk:pending:${sid}`;\n\ninterface Pending {\n rid: string;\n events: RrEvent[];\n}\n\nexport interface UploaderHooks {\n /** Recording must stop (quota, ReplayKit off for the project, chunk limit, unusable chunk). */\n onStop(reason: StopReason): void;\n /** Right before a chunk is requested: write the running stats into the session state. */\n beforeChunk?(): void;\n}\n\nexport class Uploader {\n private queue: RrEvent[] = [];\n private inflight: RrEvent[] = [];\n private queuedBytes = 0;\n private timer: unknown = null;\n private retryTimer: unknown = null;\n private failures = 0;\n private busy = false;\n private stopped = false;\n /** Bumped by pause(); a flush that started before it must not touch the new state. */\n private epoch = 0;\n /** A copy of the unsent events was parked in IndexedDB (page hidden); keep it in step with what lands. */\n private parked = false;\n /** Last page reported for `lastPageRid`: a checkout's repeated Meta href is not a new page. */\n private lastPage = \"\";\n private lastPageRid = \"\";\n\n constructor(\n private readonly env: Env,\n private readonly api: Api,\n private readonly states: StateStore,\n private readonly ids: { sid: string; vid: string },\n private readonly hooks: UploaderHooks,\n ) {}\n\n private state(): SessionState {\n return this.states.load(this.ids.sid);\n }\n\n /** Prepends what the previous page of this session could not send. */\n async restorePending(): Promise<void> {\n const store = this.env.store;\n if (!store) return;\n const p = await store.get<Pending>(pendingKey(this.ids.sid));\n if (!p) return;\n await store.del(pendingKey(this.ids.sid));\n const s = this.state();\n if (!s.rid || p.rid !== s.rid || !Array.isArray(p.events) || p.events.length === 0) return;\n this.queue = p.events.concat(this.queue);\n this.queuedBytes += p.events.reduce((n, e) => n + approxBytes(e), 0);\n this.schedule(0);\n }\n\n add(e: RrEvent): void {\n if (this.stopped) return;\n this.queue.push(e);\n this.queuedBytes += approxBytes(e);\n if (this.queuedBytes >= FLUSH_BYTES) this.schedule(0);\n else if (!this.timer) this.schedule(FLUSH_MS);\n }\n\n addMany(events: RrEvent[]): void {\n for (const e of events) this.add(e);\n }\n\n private schedule(ms: number): void {\n if (this.timer) this.env.clearTimer(this.timer);\n this.timer = this.env.setTimer(() => {\n this.timer = null;\n void this.flush();\n }, ms);\n }\n\n /** Uploads everything queued, one chunk at a time. Resolves when the queue is empty or blocked. */\n async flush(): Promise<void> {\n if (this.busy || this.stopped) return;\n const epoch = this.epoch;\n this.busy = true;\n try {\n while (!this.stopped && epoch === this.epoch && (this.inflight.length > 0 || this.queue.length > 0)) {\n if (this.inflight.length === 0) {\n this.inflight = this.queue;\n this.queue = [];\n this.queuedBytes = 0;\n }\n const ok = await this.sendInflight();\n if (!ok) return;\n }\n } finally {\n this.busy = false;\n }\n }\n\n /** True when the in-flight events are done with (sent or dropped); false to wait for a retry. */\n private async sendInflight(): Promise<boolean> {\n this.hooks.beforeChunk?.();\n const s = this.state();\n if (!s.rid || !s.trigger || !s.stats) return false;\n if (s.seq >= REPLAYKIT_MAX_CHUNKS) {\n this.stop(\"limit\");\n return false;\n }\n const gzip = this.env.gzip;\n if (!gzip) {\n this.stop(\"off\");\n return false;\n }\n const file: ReplayKitChunkFile = { v: 1, rid: s.rid, seq: s.seq, events: this.inflight };\n const blob = await gzip(JSON.stringify(file));\n if (blob.size > REPLAYKIT_MAX_CHUNK_BYTES) {\n // Too big for one chunk: send the first half now, the rest goes back to the head of the queue.\n if (this.inflight.length > 1) {\n const half = Math.ceil(this.inflight.length / 2);\n this.queue = this.inflight.slice(half).concat(this.queue);\n this.inflight = this.inflight.slice(0, half);\n return true;\n }\n // One event over 2 MB gzip'd (a giant full snapshot): unreplayable either way.\n this.stop(\"limit\");\n return false;\n }\n const prevPage = this.lastPageRid === s.rid ? this.lastPage : \"\";\n const pages = pagesOf(this.inflight, prevPage, REPLAYKIT_MAX_PAGES_PER_CHUNK);\n const presign = await this.api.chunk({ rid: s.rid, sid: this.ids.sid, vid: this.ids.vid, seq: s.seq, bytes: blob.size, trigger: s.trigger, stats: s.stats, pages });\n if (presign.outcome === \"drop\") {\n this.inflight = [];\n return true;\n }\n if (presign.outcome === \"quota\") return this.stop(\"quota\"), false;\n if (presign.outcome === \"off\" || presign.outcome === \"stop\") return this.stop(\"off\"), false;\n if (presign.outcome !== \"ok\" || !presign.data?.url) return this.retryLater(), false;\n const put = await this.api.put(presign.data.url, blob);\n if (put === \"drop\") {\n this.inflight = [];\n return true;\n }\n if (put !== \"ok\") return this.retryLater(), false;\n this.failures = 0;\n this.inflight = [];\n if (pages.length) {\n this.lastPage = pages[pages.length - 1].url;\n this.lastPageRid = s.rid;\n }\n const cur = this.state();\n if (cur.rid === s.rid) this.states.save({ ...cur, seq: s.seq + 1 });\n // Hidden tab whose upload still went through: the parked copy must not replay it on the next page.\n if (this.parked) {\n if (this.queue.length) this.persist();\n else this.unpersist();\n }\n return true;\n }\n\n private retryLater(): void {\n this.failures++;\n if (this.retryTimer) this.env.clearTimer(this.retryTimer);\n this.retryTimer = this.env.setTimer(() => {\n this.retryTimer = null;\n void this.flush();\n }, backoff(this.failures));\n }\n\n private stop(reason: StopReason): void {\n this.stopped = true;\n this.queue = [];\n this.inflight = [];\n this.queuedBytes = 0;\n this.clearTimers();\n this.hooks.onStop(reason);\n }\n\n private clearTimers(): void {\n if (this.timer) this.env.clearTimer(this.timer);\n if (this.retryTimer) this.env.clearTimer(this.retryTimer);\n this.timer = this.retryTimer = null;\n }\n\n /** Page hide: park unsent events for the next page of this session. */\n persist(): void {\n const store = this.env.store;\n const s = this.state();\n const events = this.inflight.concat(this.queue);\n if (!store || !s.rid || events.length === 0 || this.stopped) return;\n this.parked = true;\n void store.set(pendingKey(this.ids.sid), { rid: s.rid, events } satisfies Pending);\n }\n\n /** The page came back into view: whatever was parked is still in memory, drop the copy. */\n unpersist(): void {\n if (!this.parked) return;\n this.parked = false;\n void this.env.store?.del(pendingKey(this.ids.sid));\n }\n\n /** Stop without a reason the server gave (manual stop, consent withdrawn): drop what is queued. */\n discard(): void {\n this.epoch++;\n this.stopped = true;\n this.queue = [];\n this.inflight = [];\n this.queuedBytes = 0;\n this.clearTimers();\n this.unpersist();\n }\n\n get pendingEvents(): number {\n return this.queue.length + this.inflight.length;\n }\n}\n","// The ReplayKit client: one per page load.\n//\n// 1. waits for the tracker's visitor and session ids (read-only, identity.ts);\n// 2. starts the signal listeners at once, so errors during startup are caught,\n// holding what they find until /init answers;\n// 3. POST /api/t/r/init: signals on/off, recordings on/off, the project's config and\n// a server-side trigger (\"paying\");\n// 4. decides the page (decide.ts): off, continue the session's recording, start\n// one, or keep a pre-trigger buffer and wait for a trigger.\n//\n// Conditional recording: in buffer mode rrweb runs into an in-memory ring buffer cut\n// at full snapshots (buffer.ts), parked in IndexedDB when the page hides so a trigger\n// on the next page of the session still shows the page before. A trigger promotes\n// the buffer into a recording: a recording id is minted, the buffer becomes the\n// first chunk and every later event streams through the uploader.\n\nimport { emptyStats, StateStore, type SessionState, type StopReason } from \"./state\";\nimport { browserEnv, isBrowser, type Env } from \"./env\";\nimport { readIdentity } from \"./identity\";\nimport { inSample, matchAny, stripUrl } from \"./match\";\nimport { trimBuffer, BUFFER_WINDOW_MS, CHECKOUT_MS, EVENT_FULL_SNAPSHOT, type RrEvent } from \"./buffer\";\nimport { activeIncrement } from \"./detect\";\nimport { decidePage } from \"./decide\";\nimport { Api, backoff } from \"./transport\";\nimport { SignalQueue } from \"./signal-queue\";\nimport { SignalCollector } from \"./signals-dom\";\nimport { Recorder } from \"./recorder\";\nimport { Uploader } from \"./uploader\";\nimport type { ReplayKitClientConfig, ReplayKitInitResponse, ReplayKitRecordingStats, ReplayKitSignal, ReplayKitTrigger } from \"./protocol\";\n\nexport interface ReplayKitOptions {\n /** Your project's public API key (the same one the tracker uses). */\n apiKey: string;\n /** Defaults to https://app.himetrica.com. */\n apiUrl?: string;\n /** Run on localhost (off by default, like the tracker). */\n allowLocalhost?: boolean;\n /** Log decisions to the console. */\n debug?: boolean;\n}\n\nconst CONSENT_KEY = \"hm_rk_consent\";\nconst bufferKey = (sid: string) => `rk:buf:${sid}`;\nconst IDENTITY_POLL_MS = 500;\nconst IDENTITY_WAIT_MS = 15_000;\nconst INIT_ATTEMPTS = 3;\n\ntype Mode = \"idle\" | \"off\" | \"wait_consent\" | \"buffer\" | \"live\";\n\ninterface ParkedBuffer {\n at: number;\n events: RrEvent[];\n}\n\nexport class ReplayKitClient {\n private readonly env: Env;\n private readonly api: Api;\n private readonly states: StateStore;\n private ids: { sid: string; vid: string } | null = null;\n private queue: SignalQueue | null = null;\n private collector: SignalCollector | null = null;\n private recorder: Recorder | null = null;\n private uploader: Uploader | null = null;\n private init: ReplayKitInitResponse | null = null;\n private config: ReplayKitClientConfig | null = null;\n private mode: Mode = \"idle\";\n private buffer: RrEvent[] = [];\n /** Clicks, signals and input times while buffering, folded into the stats on promotion. */\n private recent: Array<{ k: \"click\" | \"rage\" | \"dead\" | \"error\" | \"input\"; ts: number }> = [];\n private stats: ReplayKitRecordingStats | null = null;\n private lastInputTs = 0;\n /** A trigger that fired before /init answered. */\n private earlyTrigger: ReplayKitTrigger | null = null;\n private destroyed = false;\n private offWindow: Array<() => void> = [];\n\n constructor(private readonly options: ReplayKitOptions, env: Env = browserEnv()) {\n this.env = env;\n const apiUrl = (options.apiUrl || \"https://app.himetrica.com\").replace(/\\/+$/, \"\");\n this.api = new Api(env, apiUrl, options.apiKey);\n this.states = new StateStore(env);\n }\n\n private log(...args: unknown[]): void {\n if (this.options.debug) console.debug(\"[ReplayKit]\", ...args);\n }\n\n /** Starts everything. Safe to call once per page; no-op outside a browser. */\n start(): void {\n if (!isBrowser || !this.options.apiKey) return;\n const host = location.hostname;\n if (!this.options.allowLocalhost && (host === \"localhost\" || host === \"127.0.0.1\" || host === \"[::1]\" || host.endsWith(\".localhost\"))) {\n this.log(\"localhost: idle (allowLocalhost to enable)\");\n return;\n }\n const started = this.env.now();\n const tryIds = () => {\n if (this.destroyed) return;\n const id = readIdentity(this.env);\n if (id.sessionId && id.visitorId) {\n this.ids = { sid: id.sessionId, vid: id.visitorId };\n this.boot();\n } else if (this.env.now() - started < IDENTITY_WAIT_MS) {\n this.env.setTimer(tryIds, IDENTITY_POLL_MS);\n } else {\n this.log(\"no tracker ids on this page: idle\");\n }\n };\n tryIds();\n }\n\n private boot(): void {\n const ids = this.ids!;\n this.queue = new SignalQueue(this.env, this.api, () => ({ ...ids, rid: this.mode === \"live\" ? this.state().rid : undefined }));\n this.collector = new SignalCollector({\n now: () => this.env.now(),\n maskAllText: () => this.config?.maskAllText ?? true,\n signal: (s) => this.onSignal(s),\n trigger: (t) => this.trigger(t),\n input: (kind, ts) => this.onInput(kind, ts),\n navigated: (url) => this.onNavigate(url),\n });\n this.collector.start();\n this.listenPage();\n void this.callInit(1);\n }\n\n private state(): SessionState {\n return this.states.load(this.ids!.sid);\n }\n\n private async callInit(attempt: number): Promise<void> {\n const ids = this.ids!;\n const r = await this.api.init({ sid: ids.sid, vid: ids.vid, url: stripUrl(location.href) });\n if (this.destroyed) return;\n if (r.outcome === \"ok\" && r.data) return this.applyInit(r.data);\n if (r.outcome === \"retry\" && attempt < INIT_ATTEMPTS) {\n this.env.setTimer(() => void this.callInit(attempt + 1), backoff(attempt));\n return;\n }\n this.log(\"init refused:\", r.outcome);\n if (r.outcome === \"quota\") {\n // Quota is about recordings; signals never count.\n this.queue?.release(true);\n this.mode = \"off\";\n return;\n }\n this.shutdown();\n }\n\n private applyInit(res: ReplayKitInitResponse): void {\n this.init = res;\n this.config = res.config;\n this.queue!.release(res.signals);\n if (!res.signals && !res.record) {\n this.shutdown();\n return;\n }\n this.decide();\n }\n\n private consentValue(): boolean | null {\n const v = this.env.getLocal(CONSENT_KEY);\n return v === \"1\" ? true : v === \"0\" ? false : null;\n }\n\n private triggerEnabled(t: ReplayKitTrigger): boolean {\n if (t === \"manual\" || t === \"sample\") return true;\n return !!this.config?.triggers.includes(t as ReplayKitClientConfig[\"triggers\"][number]);\n }\n\n private pathExcluded(): boolean {\n return matchAny(this.config?.excludePaths ?? [], location.pathname);\n }\n\n private onCheckoutPath(): boolean {\n return this.triggerEnabled(\"checkout\") && matchAny(this.config?.checkoutPaths ?? [], location.pathname);\n }\n\n private decide(): void {\n if (!this.init || !this.config) return;\n const s = this.state();\n const mode = decidePage({\n record: this.init.record,\n canGzip: !!this.env.gzip,\n state: s,\n excluded: this.pathExcluded(),\n requireConsent: this.config.requireConsent,\n consent: this.consentValue(),\n forceTrigger: this.init.forceTrigger,\n sampled: inSample(this.ids!.sid, this.config.sampleRate),\n checkout: this.onCheckoutPath(),\n });\n this.log(\"page:\", mode.kind, mode.kind === \"start\" ? mode.trigger : \"\");\n if (mode.kind === \"off\" || mode.kind === \"wait_consent\") {\n this.mode = mode.kind;\n return;\n }\n if (mode.kind === \"continue\") {\n this.mode = \"live\";\n const st = s.stats ?? emptyStats(this.env.now(), stripUrl(location.href));\n this.stats = { ...st, pages: st.pages + 1 };\n this.makeUploader();\n void this.uploader!.restorePending();\n void this.startRecorder();\n return;\n }\n this.mode = \"buffer\";\n void this.restoreParkedBuffer().then(async () => {\n if (this.mode !== \"buffer\") return;\n // rrweb emits the page's full snapshot synchronously on start: it lands in the buffer\n // before a promotion, so the first chunk always opens with a replayable page.\n await this.startRecorder();\n if (this.mode !== \"buffer\") return;\n const t = mode.kind === \"start\" ? mode.trigger : this.earlyTrigger;\n this.earlyTrigger = null;\n if (t && this.triggerEnabled(t)) this.promote(t);\n });\n }\n\n private async restoreParkedBuffer(): Promise<void> {\n const store = this.env.store;\n if (!store) return;\n const key = bufferKey(this.ids!.sid);\n const parked = await store.get<ParkedBuffer>(key);\n if (!parked) return;\n void store.del(key);\n const fresh = this.env.now() - parked.at < BUFFER_WINDOW_MS + CHECKOUT_MS;\n if (fresh && Array.isArray(parked.events) && parked.events.length) this.buffer = parked.events.concat(this.buffer);\n }\n\n private async startRecorder(): Promise<void> {\n if (this.recorder) return;\n const rec = (this.recorder = new Recorder());\n const ok = await rec.start({\n blockSelectors: this.config?.blockSelectors ?? [],\n maskAllText: this.config?.maskAllText ?? false,\n emit: (e) => this.onEvent(e),\n });\n if (!ok && this.recorder === rec) {\n this.log(\"rrweb failed to start\");\n this.recorder = null;\n this.mode = \"off\";\n }\n }\n\n private onEvent(e: RrEvent): void {\n if (this.mode === \"buffer\") {\n this.buffer.push(e);\n // Trim only when a new checkout lands: the only moment a cut point appears.\n if (e.type === EVENT_FULL_SNAPSHOT) this.buffer = trimBuffer(this.buffer, this.env.now());\n return;\n }\n if (this.mode === \"live\" && this.uploader) {\n if (this.stats) this.stats.endedAt = Math.max(this.stats.endedAt, e.timestamp);\n this.uploader.add(e);\n }\n }\n\n private makeUploader(): void {\n this.uploader = new Uploader(this.env, this.api, this.states, this.ids!, {\n onStop: (reason) => this.stopRecording(reason),\n beforeChunk: () => this.saveStats(),\n });\n }\n\n private saveStats(): void {\n if (!this.stats || this.mode !== \"live\") return;\n const s = this.state();\n if (s.rid) this.states.save({ ...s, stats: this.stats });\n }\n\n /** A trigger fired: turn the buffer into a recording, or remember it until /init answers. */\n trigger(t: ReplayKitTrigger): void {\n if (this.destroyed || !this.ids) return;\n if (!this.init) {\n if (!this.earlyTrigger) this.earlyTrigger = t;\n return;\n }\n if (this.mode !== \"buffer\" || !this.triggerEnabled(t)) return;\n if (!this.recorder) {\n // Still restoring the parked buffer: the buffer setup promotes it when it is done.\n this.earlyTrigger ??= t;\n return;\n }\n this.promote(t);\n }\n\n private promote(t: ReplayKitTrigger): void {\n const now = this.env.now();\n // The buffer starts at a full snapshot; recordings begin there, so stats do too.\n const events = this.buffer;\n this.buffer = [];\n const startedAt = events.length ? events[0].timestamp : now;\n const stats = emptyStats(startedAt, stripUrl(location.href));\n stats.endedAt = events.length ? events[events.length - 1].timestamp : now;\n let last = 0;\n for (const r of this.recent) {\n if (r.ts < startedAt) continue;\n if (r.k === \"click\") stats.clicks++;\n else if (r.k === \"rage\") stats.rageClicks++;\n else if (r.k === \"dead\") stats.deadClicks++;\n else if (r.k === \"error\") stats.errors++;\n if (r.k === \"click\" || r.k === \"input\") {\n stats.activeMs += activeIncrement(last, r.ts);\n last = r.ts;\n }\n }\n this.recent = [];\n this.stats = stats;\n this.states.save({ ...this.state(), rid: this.env.uuid(), seq: 0, trigger: t, stats, stopped: undefined });\n this.mode = \"live\";\n this.log(\"recording:\", t);\n this.makeUploader();\n this.uploader!.addMany(events);\n if (!events.length) this.recorder?.snapshot();\n // Open the recording right away: short sessions that end soon after a trigger are the interesting ones.\n void this.uploader!.flush();\n }\n\n private stopRecording(reason: StopReason): void {\n this.log(\"recording stopped:\", reason);\n this.recorder?.stop();\n this.recorder = null;\n this.mode = \"off\";\n this.buffer = [];\n const s = this.state();\n this.states.save({ ...s, stopped: reason });\n }\n\n private onSignal(s: ReplayKitSignal): void {\n if (this.mode === \"live\" && this.stats) {\n if (s.type === \"rage_click\") this.stats.rageClicks++;\n else if (s.type === \"dead_click\") this.stats.deadClicks++;\n else if (s.type === \"error\") this.stats.errors++;\n } else if (this.mode === \"buffer\" || this.mode === \"idle\") {\n const k = s.type === \"rage_click\" ? \"rage\" : s.type === \"dead_click\" ? \"dead\" : s.type === \"error\" ? \"error\" : null;\n if (k) this.pushRecent(k, s.ts);\n }\n this.queue?.add(s);\n }\n\n private onInput(kind: \"click\" | \"key\" | \"scroll\", ts: number): void {\n if (this.mode === \"live\" && this.stats) {\n this.stats.activeMs += activeIncrement(this.lastInputTs, ts);\n if (kind === \"click\") this.stats.clicks++;\n } else if (this.mode === \"buffer\" || this.mode === \"idle\") {\n this.pushRecent(kind === \"click\" ? \"click\" : \"input\", ts);\n }\n this.lastInputTs = ts;\n }\n\n private pushRecent(k: \"click\" | \"rage\" | \"dead\" | \"error\" | \"input\", ts: number): void {\n this.recent.push({ k, ts });\n if (this.recent.length > 1000) this.recent.splice(0, this.recent.length - 1000);\n }\n\n private onNavigate(url: string): void {\n if (!this.init || !this.config) return;\n if (this.mode === \"live\" && this.stats) this.stats.pages++;\n const excluded = this.pathExcluded();\n if (excluded && (this.mode === \"live\" || this.mode === \"buffer\")) {\n // SPA route that must not be recorded: pause rrweb, keep the session's state.\n this.recorder?.stop();\n this.recorder = null;\n if (this.mode === \"buffer\") this.buffer = [];\n void this.uploader?.flush();\n this.mode = \"off\";\n return;\n }\n if (!excluded && this.mode === \"off\" && !this.state().stopped) {\n // Back from an excluded route: decide again (continues the recording or rebuffers).\n this.uploader = null;\n this.decide();\n return;\n }\n // Excluded routes never reach here: their URL is not written into the stream.\n this.recorder?.page(url);\n if (this.onCheckoutPath()) this.trigger(\"checkout\");\n }\n\n private listenPage(): void {\n const hide = (unloading: boolean) => {\n if (unloading) this.collector?.pageHide();\n this.queue?.beacon();\n if (this.mode === \"live\") {\n this.saveStats();\n this.uploader?.persist();\n } else if (this.mode === \"buffer\" && this.buffer.length && this.env.store) {\n const events = trimBuffer(this.buffer, this.env.now());\n void this.env.store.set(bufferKey(this.ids!.sid), { at: this.env.now(), events } satisfies ParkedBuffer);\n }\n };\n const onVis = () => {\n if (document.visibilityState === \"hidden\") hide(false);\n else this.uploader?.unpersist();\n };\n const onHide = () => hide(true);\n document.addEventListener(\"visibilitychange\", onVis);\n window.addEventListener(\"pagehide\", onHide);\n this.offWindow.push(\n () => document.removeEventListener(\"visibilitychange\", onVis),\n () => window.removeEventListener(\"pagehide\", onHide),\n );\n }\n\n // ── Public API ────────────────────────────────────────────\n\n /** Start recording this session now (ReplayKit.start()). Still subject to /init, consent and excludePaths. */\n manualStart(reason?: string): void {\n if (!this.ids) return;\n if (reason) this.log(\"manual trigger:\", reason);\n if (this.state().stopped === \"manual\") {\n // Started again after ReplayKit.stop(): a new recording, decided like a fresh page.\n this.states.save({ ...this.state(), stopped: undefined, rid: undefined, seq: 0, trigger: undefined, stats: undefined });\n this.uploader = null;\n this.earlyTrigger = \"manual\";\n this.decide();\n return;\n }\n this.trigger(\"manual\");\n }\n\n /** Stop recording for the rest of the session; what was captured is still uploaded. */\n manualStop(): void {\n if (!this.ids) return;\n this.recorder?.stop();\n this.recorder = null;\n this.buffer = [];\n if (this.mode === \"live\") {\n this.saveStats();\n void this.uploader?.flush();\n }\n this.mode = \"off\";\n this.states.save({ ...this.state(), stopped: \"manual\" });\n }\n\n /** The visitor's answer to the customer's consent banner. Stored on this device. */\n consent(granted: boolean): void {\n this.env.setLocal(CONSENT_KEY, granted ? \"1\" : \"0\");\n if (!this.ids) return;\n if (granted) {\n if (this.mode === \"wait_consent\") this.decide();\n return;\n }\n // Withdrawn: stop now and drop everything not uploaded yet.\n this.recorder?.stop();\n this.recorder = null;\n this.buffer = [];\n this.uploader?.discard();\n void this.env.store?.del(bufferKey(this.ids.sid));\n this.mode = \"off\";\n }\n\n recordingId(): string | null {\n return this.mode === \"live\" ? (this.ids ? this.state().rid ?? null : null) : null;\n }\n\n private shutdown(): void {\n this.collector?.stop();\n this.queue?.disable();\n this.recorder?.stop();\n this.recorder = null;\n this.mode = \"off\";\n }\n\n destroy(): void {\n this.destroyed = true;\n this.shutdown();\n for (const f of this.offWindow) f();\n this.offWindow = [];\n }\n}\n","// Script-tag build: dist/replaykit.global.js.\n//\n// <script src=\"https://cdn.../replaykit.global.js\" data-api-key=\"hm_...\"></script>\n//\n// Exposes window.ReplayKit (same API as the npm entry) and initializes itself from\n// the data attributes of its own <script> tag. Without data-api-key it only exposes\n// the API, so the page can call ReplayKit.init({...}) itself. Load it after the\n// Himetrica tracker.\n\nimport * as ReplayKit from \"./index\";\n\ndeclare global {\n interface Window {\n ReplayKit?: typeof ReplayKit;\n }\n}\n\nif (typeof window !== \"undefined\") {\n window.ReplayKit = ReplayKit;\n const script = document.currentScript as HTMLScriptElement | null;\n const data = script?.dataset;\n if (data?.apiKey) {\n ReplayKit.init({\n apiKey: data.apiKey,\n apiUrl: data.apiUrl || undefined,\n allowLocalhost: data.allowLocalhost === \"true\",\n debug: data.debug === \"true\",\n });\n }\n}\n"],"mappings":"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","names":["getUntaintedPrototype","key","untaintedBasePrototype","defaultObj","defaultPrototype","accessorNames","testableAccessors","isUntaintedAccessors","accessor","_a","_b","methodNames","testableMethods","isUntaintedMethods","method","isAngularZonePresent","iframeEl","win","untaintedObject","ua","untaintedBaseIframeCleanup","e","getUntaintedAccessor","instance","cached","untaintedAccessorCache","untaintedPrototype","untaintedAccessor","getUntaintedMethod","cacheKey","untaintedMethodCache","untaintedMethod","ownerDocument","n","childNodes","parentNode","parentElement","textContent","firstChild","lastChild","nextSibling","previousSibling","contains","other","getRootNode","host","styleSheets","shadowRoot","querySelector","selectors","querySelectorAll","mutationObserverCtor","patch","source","name","replacement","original","wrapped","isElement","isShadowRoot","hostEl","dom","isNativeShadowDom","fixBrowserCompatibilityIssuesInCSS","cssText","escapeImportStatement","rule","statement","stringifyStylesheet","s","rules","sheetHref","stringifiedRules","stringifyRule","error","isCSSImportRule","importStringified","absolutifyURLs","ruleStringified","isCSSStyleRule","fixSafariColons","cssStringified","regex","createMirror","Mirror","maskInputValue","element","maskInputOptions","tagName","type","value","maskInputFn","text","actualType","toLowerCase","str","is2DCanvasBlank","canvas","ctx","chunkSize","x","y","getImageData","originalGetImageData","ORIGINAL_ATTRIBUTE_NAME","pixel","getInputType","extractFileExtension","path","baseURL","url","err","match","extractOrigin","origin","href","URL_IN_CSS_REF","quote1","path1","quote2","path2","path3","filePath","maybeQuote","URL_PROTOCOL_MATCH","URL_WWW_MATCH","DATA_URI","filePathNoHash","maybeHash","stack","parts","part","normalizeCssString","_testNoPxNorm","cssNormalizeReNoPx","cssNormalizeRe","splitCssText","style","splits","iterCount","cssTextNorm","normFactor","i","textContentNorm","jLimit","j","startSubstring","cssNormSplits","splitNorm","prevTextContent","prevMinLength","k","normPart","markCssSplits","genId","_id","getValidTagName","processedTagName","tagNameRegex","getAbsoluteSrcsetString","doc","attributeValue","pos","collectCharacters","regEx","chars","output","SRCSET_COMMAS_OR_SPACES","SRCSET_NOT_SPACES","absoluteToDoc","descriptorsStr","inParens","c","getHref","isSVGElement","el","customHref","a","cachedDocument","transformAttribute","ignoreAttribute","_value","_isBlockedElement","blockClass","blockSelector","eIndex","className","classMatchesRegex","node","checkAncestors","needMaskingText","maskTextClass","maskTextSelector","onceIframeLoaded","listener","iframeLoadTimeout","fired","readyState","timer","blankUrl","onceStylesheetLoaded","link","styleSheetLoadTimeout","styleSheetLoaded","serializeNode","options","mirror","needsMask","inlineStylesheet","maskTextFn","dataURLOptions","inlineImages","recordCanvas","keepIframeSrcFn","newlyAddedElement","cssCaptured","rootId","getRootId","NodeType","serializeElementNode","serializeTextNode","docId","parent","parentTagName","isStyle","isScript","needBlock","attributes","len","attr","stylesheet","checked","canvasDataURL","blankCanvas","blankCanvasDataURL","canvasService","canvasCtx","image","imageSrc","priorCrossOrigin","recordInlineImage","mediaAttributes","width","height","isCustomElement","lowerIfExists","maybeAttr","slimDOMDefaults","_slimDOMOptions","slimDOMExcluded","sn","slimDOMOptions","serializeNodeWithId","skipChild","onSerialize","onIframeLoad","onStylesheetLoad","stylesheetLoadTimeout","preserveWhiteSpace","_serializedNode","id","IGNORED_NODE","serializedNode","recordChild","shadowRootEl","bypassOptions","childN","serializedChildNode","iframeDoc","serializedIframeNode","serializedLinkNode","snapshot","maskAllInputs","slimDOM","on","fn","target","throttle","func","wait","timeout","previous","args","now","remaining","context","hookSetter","d","isRevoked","getWindowScroll","_c","_d","getWindowHeight","getWindowWidth","closestElementOfNode","isBlocked","isSerialized","isIgnored","isAncestorRemoved","legacy_isTouchEvent","event","polyfill","isSerializedIframe","isSerializedStylesheet","hasShadowRoot","BaseRRNode","getShadowHost","shadowHost","getRootShadowHost","rootShadowHost","shadowHostInDom","inDom","deepDelete","addsSet","processRemoves","cache","queue","next","isSelfOrAncestorInSet","set","_isSelfOrAncestorInSet","registerErrorHandler","handler","errorHandler","unregisterErrorHandler","getEventTarget","initMutationObserver","rootEl","mutationBuffer","MutationBuffer","mutationBuffers","ObserverCtor","iframeCleanup","observer","callbackWrapper","initMoveObserver","mousemoveCb","sampling","threshold","callbackThreshold","positions","timeBaseline","wrappedCb","totalOffset","p","updatePosition","evt","clientX","clientY","nowTimestamp","IncrementalSource","handlers","initMouseInteractionObserver","mouseInteractionCb","disableMap","currentPointerType","getHandler","eventKey","pointerType","thisEventKey","PointerTypes","MouseInteractions","__spreadValues","eventName","h","initScrollObserver","scrollCb","scrollLeftTop","initViewportResizeObserver","viewportResizeCb","lastH","lastW","updateDimension","initInputObserver","inputCb","ignoreClass","ignoreSelector","userTriggeredOnInput","eventHandler","userTriggered","INPUT_TAGS","isChecked","cbWithDedup","v","lastInputValue","lastInputValueMap","__spreadProps","currentWindow","propertyDescriptor","hookProperties","getNestedCSSRulePositions","recurse","childRule","hasNestedCSSRule","index","getIdAndStyleId","sheet","styleMirror","styleId","initStyleSheetObserver","styleSheetRuleCb","stylesheetManager","insertRule","thisArg","argumentsList","selector","styleBlock","deleteRule","replace","replaceSync","supportedNestedCSSRuleTypes","canMonkeyPatchNestedCSSRule","unmodifiedFunctions","typeKey","initAdoptedStyleSheetObserver","hostId","patchTarget","originalPropertyDescriptor","sheets","result","initStyleDeclarationObserver","styleDeclarationCb","ignoreCSSAttributes","setProperty","property","priority","removeProperty","initMediaInteractionObserver","mediaInteractionCb","currentTime","volume","muted","playbackRate","loop","MediaInteractions","initFontObserver","fontCb","fontMap","originalFontFace","family","descriptors","fontFace","restoreHandler","initSelectionObserver","param","selectionCb","collapsed","updateSelection","selection","ranges","count","range","startContainer","startOffset","endContainer","endOffset","initCustomElementObserver","customElementCb","constructor","mergeHooks","o","hooks","mutationCb","canvasMutationCb","initObservers","mutationObserver","cleanupMutationIframe","mousemoveHandler","mouseInteractionHandler","scrollHandler","viewportResizeHandler","inputHandler","mediaInteractionHandler","styleSheetObserver","adoptedStyleSheetObserver","styleDeclarationObserver","fontObserver","selectionObserver","customElementObserver","pluginHandlers","plugin","b","prop","variableListFor","ctor","contextMap","canvasVarMap","serializeArg","arg","base64","encode","src","isInstanceOfWebGLObject","saveWebGLVar","initCanvas2DMutationObserver","cb","props2D","recordArgs","serializeArgs","CanvasContext","hookHandler","getNormalizedContextName","contextType","initCanvasContextObserver","setPreserveDrawingBufferToTrue","ctxName","contextAttributes","patchGLPrototype","prototype","props","mutation","initCanvasWebGLMutationObserver","record","emit","checkoutEveryNms","checkoutEveryNth","_maskInputOptions","packFn","mousemoveWait","recordDOM","recordCrossOriginIframes","recordAfter","collectFonts","plugins","inEmittingFrame","passEmitsToParent","lastFullSnapshotEvent","incrementalSnapshotCount","eventProcessor","wrappedEmit","r","isCheckout","EventType","buf","message","exceedCount","exceedTime","takeFullSnapshot","wrappedMutationEmit","m","wrappedScrollEmit","wrappedCanvasMutationEmit","wrappedAdoptedStyleSheetEmit","StylesheetManager","iframeManager","IframeManager","processedNodeManager","ProcessedNodeManager","canvasManager","CanvasManager","shadowDomManager","ShadowDomManager","iframe","childSn","linkEl","observe","payload","init","recording","cssNormalizeBase","DEPARTED_MIRROR_ACCESS_WARNING","_mirror","StyleSheetMirror","moveKey","CrossOriginIframeMirror","lookup","EventType2","IncrementalSource2","MouseInteractions2","PointerTypes2","CanvasContext2","MediaInteractions2","NodeType2","__publicField","childNode","meta","oldNode","_BaseRRNode","_args","childIterator","_newChild","_refChild","_node","receiver","newId","parentId","mutations","adds","addedIds","ancestorBad","missingParents","iter","curr","parentTag","nextId","currentN","attribute","diffAsStr","unchangedAsStr","textarea","item","cn","tagNameLower","attributeName","old","pname","newValue","newPriority","nodeId","targetId","rest","generateIdFn","remoteId","idToRemoteMap","remoteToIdMap","idToRemoteIdMap","remoteIdToIdMap","map","ids","crossOriginMessageEvent","transformedEvent","iframeMirror","obj","keys","child","iframeElement","manager","option","sRoot","arraybuffer","bytes","list","fps","canvasContextReset","snapshotInProgressMap","worker","ImageBitmapDataURLWorker","timeBetweenSnapshots","lastSnapshotTime","rafId","getCanvas","matchedCanvas","takeCanvasSnapshots","timestamp","bitmap","canvas2DReset","canvasWebGL1and2Reset","setLatestRAFTimestamp","_values","valuesWithType","values","__objRest","adoptedStyleSheetData","styles","_linkEl","thisBuffer","buffers","buffer","cleanFrame","tag","src_exports","__export","consent","getRecordingId","init","shutdown","start","stop","trigger","KEY","StateStore","env","sid","_a","s","raw","e","emptyStats","now","entryUrl","isBrowser","uuidV4","c","ch","safeGet","storage","key","e","safeSet","value","indexedDbStore","dbp","open","resolve","reject","req","run","mode","fn","db","tx","s","gzipFn","text","browserEnv","originalFetch","nav","url","body","name","match","ms","h","readIdentity","env","visitorId","sessionId","matchPath","pattern","pathname","p","path","base","escapeRegExp","matchAny","patterns","s","sampleDraw","sessionId","h1","h2","i","ch","inSample","rate","stripUrl","href","cut","PAGE_TAG","pagesOf","events","prev","max","_a","_b","out","last","e","href","d","cut","url","BUFFER_WINDOW_MS","CHECKOUT_MS","snapshotStart","i","trimBuffer","now","windowMs","cutoff","keepFrom","firstSnapshot","start","approxBytes","RageDetector","c","b","near","finished","now","_a","_b","a","DEAD_CLICK_WAIT_MS","isDeadClickCandidate","f","isDeadClick","r","ACTIVE_GAP_MS","activeIncrement","lastInputTs","ts","gap","decidePage","i","outcomeOf","status","Api","env","apiUrl","apiKey","op","body","_a","_b","url","blob","res","e","wantJson","outcome","BASE_BACKOFF_MS","MAX_BACKOFF_MS","backoff","failures","SIGNAL_FLUSH_MS","MAX_PER_PAGE","MAX_QUEUED","DEDUPE_MS","SignalQueue","env","api","ids","s","key","prev","enabled","ms","batch","__spreadProps","__spreadValues","backoff","INTERACTIVE","FIELD","MASKED","MAX_TEXT","MAX_DETAIL","selectorOf","el","parts","cur","depth","tag","classes","c","visibleText","maskAll","_a","_b","_c","t","targetFacts","pointer","e","sel","clickedElement","target","SignalCollector","h","RageDetector","on","type","fn","opts","now","r","nav","stripUrl","f","s","__spreadValues","href","prev","ts","selector","force","b","count","isDeadClickCandidate","hrefBefore","scrollBefore","focusBefore","mutations","mo","list","isDeadClick","DEAD_CLICK_WAIT_MS","message","detail","form","key","set","fields","BASE_BLOCK","BASE_MASK","recordFn","loadRecord","m","validSelectors","list","s","e","Recorder","o","_a","CHECKOUT_MS","href","PAGE_TAG","FLUSH_MS","FLUSH_BYTES","pendingKey","sid","Uploader","env","api","states","ids","hooks","store","p","s","e","approxBytes","events","ms","epoch","_a","_b","_c","gzip","file","blob","half","prevPage","pages","pagesOf","presign","put","cur","__spreadProps","__spreadValues","backoff","reason","CONSENT_KEY","bufferKey","sid","IDENTITY_POLL_MS","IDENTITY_WAIT_MS","INIT_ATTEMPTS","ReplayKitClient","options","env","browserEnv","apiUrl","Api","StateStore","args","isBrowser","host","started","tryIds","id","readIdentity","ids","SignalQueue","__spreadProps","__spreadValues","SignalCollector","_a","_b","s","t","kind","ts","url","attempt","r","stripUrl","backoff","res","v","matchAny","mode","decidePage","inSample","st","emptyStats","store","key","parked","BUFFER_WINDOW_MS","CHECKOUT_MS","_c","_d","rec","Recorder","e","trimBuffer","Uploader","reason","now","events","startedAt","stats","last","activeIncrement","k","excluded","hide","unloading","onVis","onHide","granted","f","client","init","options","ReplayKitClient","start","trigger","reason","stop","consent","granted","getRecordingId","_a","shutdown","src_exports","script","data","init"]}
|
|
1
|
+
{"version":3,"sources":["../node_modules/@rrweb/types/dist/types.js","../node_modules/@rrweb/utils/dist/utils.js","../node_modules/@rrweb/rrweb-snapshot/src/utils.ts","../node_modules/@rrweb/rrweb-snapshot/src/snapshot.ts","../node_modules/@rrweb/rrdom/src/document.ts","../node_modules/@rrweb/rrweb/src/utils.ts","../node_modules/@rrweb/rrweb/src/record/mutation.ts","../node_modules/@rrweb/rrweb/src/record/error-handler.ts","../node_modules/@rrweb/rrweb/src/record/observer.ts","../node_modules/@rrweb/rrweb/src/record/cross-origin-iframe-mirror.ts","../node_modules/@rrweb/rrweb/src/record/iframe-manager.ts","../node_modules/@rrweb/rrweb/src/record/shadow-dom-manager.ts","../node_modules/node_modules/base64-arraybuffer/dist/base64-arraybuffer.es5.js","../node_modules/@rrweb/rrweb/src/record/observers/canvas/serialize-args.ts","../node_modules/@rrweb/rrweb/src/record/observers/canvas/2d.ts","../node_modules/@rrweb/rrweb/src/record/observers/canvas/canvas.ts","../node_modules/@rrweb/rrweb/src/record/observers/canvas/webgl.ts","../node_modules/@rrweb/rrweb/src/record/observers/canvas/canvas-manager.ts","../node_modules/@rrweb/rrweb/src/record/stylesheet-manager.ts","../node_modules/@rrweb/rrweb/src/record/processed-node-manager.ts","../node_modules/@rrweb/rrweb/src/record/index.ts","../src/index.ts","../src/state.ts","../src/env.ts","../src/identity.ts","../src/match.ts","../src/buffer.ts","../src/detect.ts","../src/decide.ts","../src/transport.ts","../src/signal-queue.ts","../src/signals-dom.ts","../src/recorder.ts","../src/uploader.ts","../src/client.ts","../src/global.ts"],"sourcesContent":["var EventType = /* @__PURE__ */ ((EventType2) => {\n EventType2[EventType2[\"DomContentLoaded\"] = 0] = \"DomContentLoaded\";\n EventType2[EventType2[\"Load\"] = 1] = \"Load\";\n EventType2[EventType2[\"FullSnapshot\"] = 2] = \"FullSnapshot\";\n EventType2[EventType2[\"IncrementalSnapshot\"] = 3] = \"IncrementalSnapshot\";\n EventType2[EventType2[\"Meta\"] = 4] = \"Meta\";\n EventType2[EventType2[\"Custom\"] = 5] = \"Custom\";\n EventType2[EventType2[\"Plugin\"] = 6] = \"Plugin\";\n EventType2[EventType2[\"Asset\"] = 7] = \"Asset\";\n return EventType2;\n})(EventType || {});\nvar IncrementalSource = /* @__PURE__ */ ((IncrementalSource2) => {\n IncrementalSource2[IncrementalSource2[\"Mutation\"] = 0] = \"Mutation\";\n IncrementalSource2[IncrementalSource2[\"MouseMove\"] = 1] = \"MouseMove\";\n IncrementalSource2[IncrementalSource2[\"MouseInteraction\"] = 2] = \"MouseInteraction\";\n IncrementalSource2[IncrementalSource2[\"Scroll\"] = 3] = \"Scroll\";\n IncrementalSource2[IncrementalSource2[\"ViewportResize\"] = 4] = \"ViewportResize\";\n IncrementalSource2[IncrementalSource2[\"Input\"] = 5] = \"Input\";\n IncrementalSource2[IncrementalSource2[\"TouchMove\"] = 6] = \"TouchMove\";\n IncrementalSource2[IncrementalSource2[\"MediaInteraction\"] = 7] = \"MediaInteraction\";\n IncrementalSource2[IncrementalSource2[\"StyleSheetRule\"] = 8] = \"StyleSheetRule\";\n IncrementalSource2[IncrementalSource2[\"CanvasMutation\"] = 9] = \"CanvasMutation\";\n IncrementalSource2[IncrementalSource2[\"Font\"] = 10] = \"Font\";\n IncrementalSource2[IncrementalSource2[\"Log\"] = 11] = \"Log\";\n IncrementalSource2[IncrementalSource2[\"Drag\"] = 12] = \"Drag\";\n IncrementalSource2[IncrementalSource2[\"StyleDeclaration\"] = 13] = \"StyleDeclaration\";\n IncrementalSource2[IncrementalSource2[\"Selection\"] = 14] = \"Selection\";\n IncrementalSource2[IncrementalSource2[\"AdoptedStyleSheet\"] = 15] = \"AdoptedStyleSheet\";\n IncrementalSource2[IncrementalSource2[\"CustomElement\"] = 16] = \"CustomElement\";\n return IncrementalSource2;\n})(IncrementalSource || {});\nvar MouseInteractions = /* @__PURE__ */ ((MouseInteractions2) => {\n MouseInteractions2[MouseInteractions2[\"MouseUp\"] = 0] = \"MouseUp\";\n MouseInteractions2[MouseInteractions2[\"MouseDown\"] = 1] = \"MouseDown\";\n MouseInteractions2[MouseInteractions2[\"Click\"] = 2] = \"Click\";\n MouseInteractions2[MouseInteractions2[\"ContextMenu\"] = 3] = \"ContextMenu\";\n MouseInteractions2[MouseInteractions2[\"DblClick\"] = 4] = \"DblClick\";\n MouseInteractions2[MouseInteractions2[\"Focus\"] = 5] = \"Focus\";\n MouseInteractions2[MouseInteractions2[\"Blur\"] = 6] = \"Blur\";\n MouseInteractions2[MouseInteractions2[\"TouchStart\"] = 7] = \"TouchStart\";\n MouseInteractions2[MouseInteractions2[\"TouchMove_Departed\"] = 8] = \"TouchMove_Departed\";\n MouseInteractions2[MouseInteractions2[\"TouchEnd\"] = 9] = \"TouchEnd\";\n MouseInteractions2[MouseInteractions2[\"TouchCancel\"] = 10] = \"TouchCancel\";\n return MouseInteractions2;\n})(MouseInteractions || {});\nvar PointerTypes = /* @__PURE__ */ ((PointerTypes2) => {\n PointerTypes2[PointerTypes2[\"Mouse\"] = 0] = \"Mouse\";\n PointerTypes2[PointerTypes2[\"Pen\"] = 1] = \"Pen\";\n PointerTypes2[PointerTypes2[\"Touch\"] = 2] = \"Touch\";\n return PointerTypes2;\n})(PointerTypes || {});\nvar CanvasContext = /* @__PURE__ */ ((CanvasContext2) => {\n CanvasContext2[CanvasContext2[\"2D\"] = 0] = \"2D\";\n CanvasContext2[CanvasContext2[\"WebGL\"] = 1] = \"WebGL\";\n CanvasContext2[CanvasContext2[\"WebGL2\"] = 2] = \"WebGL2\";\n return CanvasContext2;\n})(CanvasContext || {});\nvar MediaInteractions = /* @__PURE__ */ ((MediaInteractions2) => {\n MediaInteractions2[MediaInteractions2[\"Play\"] = 0] = \"Play\";\n MediaInteractions2[MediaInteractions2[\"Pause\"] = 1] = \"Pause\";\n MediaInteractions2[MediaInteractions2[\"Seeked\"] = 2] = \"Seeked\";\n MediaInteractions2[MediaInteractions2[\"VolumeChange\"] = 3] = \"VolumeChange\";\n MediaInteractions2[MediaInteractions2[\"RateChange\"] = 4] = \"RateChange\";\n return MediaInteractions2;\n})(MediaInteractions || {});\nvar ReplayerEvents = /* @__PURE__ */ ((ReplayerEvents2) => {\n ReplayerEvents2[\"Start\"] = \"start\";\n ReplayerEvents2[\"Pause\"] = \"pause\";\n ReplayerEvents2[\"Resume\"] = \"resume\";\n ReplayerEvents2[\"Resize\"] = \"resize\";\n ReplayerEvents2[\"Finish\"] = \"finish\";\n ReplayerEvents2[\"FullsnapshotRebuilded\"] = \"fullsnapshot-rebuilded\";\n ReplayerEvents2[\"LoadStylesheetStart\"] = \"load-stylesheet-start\";\n ReplayerEvents2[\"LoadStylesheetEnd\"] = \"load-stylesheet-end\";\n ReplayerEvents2[\"SkipStart\"] = \"skip-start\";\n ReplayerEvents2[\"SkipEnd\"] = \"skip-end\";\n ReplayerEvents2[\"MouseInteraction\"] = \"mouse-interaction\";\n ReplayerEvents2[\"EventCast\"] = \"event-cast\";\n ReplayerEvents2[\"CustomEvent\"] = \"custom-event\";\n ReplayerEvents2[\"Flush\"] = \"flush\";\n ReplayerEvents2[\"StateChange\"] = \"state-change\";\n ReplayerEvents2[\"PlayBack\"] = \"play-back\";\n ReplayerEvents2[\"Destroy\"] = \"destroy\";\n return ReplayerEvents2;\n})(ReplayerEvents || {});\nvar NodeType = /* @__PURE__ */ ((NodeType2) => {\n NodeType2[NodeType2[\"Document\"] = 0] = \"Document\";\n NodeType2[NodeType2[\"DocumentType\"] = 1] = \"DocumentType\";\n NodeType2[NodeType2[\"Element\"] = 2] = \"Element\";\n NodeType2[NodeType2[\"Text\"] = 3] = \"Text\";\n NodeType2[NodeType2[\"CDATA\"] = 4] = \"CDATA\";\n NodeType2[NodeType2[\"Comment\"] = 5] = \"Comment\";\n return NodeType2;\n})(NodeType || {});\nexport {\n CanvasContext,\n EventType,\n IncrementalSource,\n MediaInteractions,\n MouseInteractions,\n NodeType,\n PointerTypes,\n ReplayerEvents\n};\n//# sourceMappingURL=types.js.map\n","const testableAccessors = {\n Node: [\n \"childNodes\",\n \"parentNode\",\n \"parentElement\",\n \"textContent\",\n \"ownerDocument\",\n \"firstChild\",\n \"lastChild\",\n \"nextSibling\",\n \"previousSibling\"\n ],\n ShadowRoot: [\"host\", \"styleSheets\"],\n Element: [\"shadowRoot\", \"querySelector\", \"querySelectorAll\"],\n MutationObserver: []\n};\nconst testableMethods = {\n Node: [\"contains\", \"getRootNode\"],\n ShadowRoot: [\"getSelection\"],\n Element: [],\n MutationObserver: [\"constructor\"]\n};\nconst untaintedBasePrototype = {};\nconst untaintedBaseIframeCleanup = {};\nconst isAngularZonePresent = () => {\n return !!globalThis.Zone;\n};\nfunction getUntaintedPrototype(key) {\n if (untaintedBasePrototype[key])\n return untaintedBasePrototype[key];\n const defaultObj = globalThis[key];\n const defaultPrototype = defaultObj.prototype;\n const accessorNames = key in testableAccessors ? testableAccessors[key] : void 0;\n const isUntaintedAccessors = Boolean(\n accessorNames && // @ts-expect-error 2345\n accessorNames.every(\n (accessor) => {\n var _a, _b;\n return Boolean(\n (_b = (_a = Object.getOwnPropertyDescriptor(defaultPrototype, accessor)) == null ? void 0 : _a.get) == null ? void 0 : _b.toString().includes(\"[native code]\")\n );\n }\n )\n );\n const methodNames = key in testableMethods ? testableMethods[key] : void 0;\n const isUntaintedMethods = Boolean(\n methodNames && methodNames.every(\n // @ts-expect-error 2345\n (method) => {\n var _a;\n return typeof defaultPrototype[method] === \"function\" && ((_a = defaultPrototype[method]) == null ? void 0 : _a.toString().includes(\"[native code]\"));\n }\n )\n );\n if (isUntaintedAccessors && isUntaintedMethods && !isAngularZonePresent()) {\n untaintedBasePrototype[key] = defaultObj.prototype;\n return defaultObj.prototype;\n }\n try {\n const iframeEl = document.createElement(\"iframe\");\n iframeEl.style.display = \"none\";\n document.body.appendChild(iframeEl);\n const win = iframeEl.contentWindow;\n if (!win) return defaultObj.prototype;\n const untaintedObject = win[key].prototype;\n if (!untaintedObject) {\n iframeEl.remove();\n return defaultPrototype;\n }\n const ua = navigator.userAgent;\n if (ua.includes(\"Safari\") && !ua.includes(\"Chrome\")) {\n iframeEl.classList.add(\"rr-block\");\n iframeEl.setAttribute(\"__rrwebUntaintedMutationObserver\", \"\");\n untaintedBaseIframeCleanup[key] = () => iframeEl.remove();\n } else {\n iframeEl.remove();\n }\n return untaintedBasePrototype[key] = untaintedObject;\n } catch {\n return defaultPrototype;\n }\n}\nconst untaintedAccessorCache = {};\nfunction getUntaintedAccessor(key, instance, accessor) {\n var _a, _b;\n const cached = (_a = untaintedAccessorCache[key]) == null ? void 0 : _a[accessor];\n if (cached) return cached.call(instance);\n const untaintedPrototype = getUntaintedPrototype(key);\n const untaintedAccessor = (_b = Object.getOwnPropertyDescriptor(\n untaintedPrototype,\n accessor\n )) == null ? void 0 : _b.get;\n if (!untaintedAccessor) return instance[accessor];\n (untaintedAccessorCache[key] || (untaintedAccessorCache[key] = {}))[accessor] = untaintedAccessor;\n return untaintedAccessor.call(instance);\n}\nconst untaintedMethodCache = {};\nfunction getUntaintedMethod(key, instance, method) {\n const cacheKey = `${key}.${String(method)}`;\n if (untaintedMethodCache[cacheKey])\n return untaintedMethodCache[cacheKey].bind(\n instance\n );\n const untaintedPrototype = getUntaintedPrototype(key);\n const untaintedMethod = untaintedPrototype[method];\n if (typeof untaintedMethod !== \"function\") return instance[method];\n untaintedMethodCache[cacheKey] = untaintedMethod;\n return untaintedMethod.bind(instance);\n}\nfunction ownerDocument(n) {\n return getUntaintedAccessor(\"Node\", n, \"ownerDocument\");\n}\nfunction childNodes(n) {\n return getUntaintedAccessor(\"Node\", n, \"childNodes\");\n}\nfunction parentNode(n) {\n return getUntaintedAccessor(\"Node\", n, \"parentNode\");\n}\nfunction parentElement(n) {\n return getUntaintedAccessor(\"Node\", n, \"parentElement\");\n}\nfunction textContent(n) {\n return getUntaintedAccessor(\"Node\", n, \"textContent\");\n}\nfunction firstChild(n) {\n return getUntaintedAccessor(\"Node\", n, \"firstChild\");\n}\nfunction lastChild(n) {\n return getUntaintedAccessor(\"Node\", n, \"lastChild\");\n}\nfunction nextSibling(n) {\n return getUntaintedAccessor(\"Node\", n, \"nextSibling\");\n}\nfunction previousSibling(n) {\n return getUntaintedAccessor(\"Node\", n, \"previousSibling\");\n}\nfunction contains(n, other) {\n return getUntaintedMethod(\"Node\", n, \"contains\")(other);\n}\nfunction getRootNode(n) {\n return getUntaintedMethod(\"Node\", n, \"getRootNode\")();\n}\nfunction host(n) {\n if (!n || !(\"host\" in n)) return null;\n return getUntaintedAccessor(\"ShadowRoot\", n, \"host\");\n}\nfunction styleSheets(n) {\n return n.styleSheets;\n}\nfunction shadowRoot(n) {\n if (!n || !(\"shadowRoot\" in n)) return null;\n return getUntaintedAccessor(\"Element\", n, \"shadowRoot\");\n}\nfunction querySelector(n, selectors) {\n return getUntaintedAccessor(\"Element\", n, \"querySelector\")(selectors);\n}\nfunction querySelectorAll(n, selectors) {\n return getUntaintedAccessor(\"Element\", n, \"querySelectorAll\")(selectors);\n}\nfunction mutationObserverCtor() {\n return [\n getUntaintedPrototype(\"MutationObserver\").constructor,\n untaintedBaseIframeCleanup[\"MutationObserver\"] ?? (() => {\n })\n ];\n}\nlet nowTimestamp = Date.now;\nif (!/* @__PURE__ */ /[1-9][0-9]{12}/.test(Date.now().toString())) {\n nowTimestamp = () => (/* @__PURE__ */ new Date()).getTime();\n}\nfunction patch(source, name, replacement) {\n try {\n if (!(name in source)) {\n return () => {\n };\n }\n const original = source[name];\n const wrapped = replacement(original);\n if (typeof wrapped === \"function\") {\n wrapped.prototype = wrapped.prototype || {};\n Object.defineProperties(wrapped, {\n __rrweb_original__: {\n enumerable: false,\n value: original\n }\n });\n }\n source[name] = wrapped;\n return () => {\n source[name] = original;\n };\n } catch {\n return () => {\n };\n }\n}\nconst index = {\n ownerDocument,\n childNodes,\n parentNode,\n parentElement,\n textContent,\n firstChild,\n lastChild,\n nextSibling,\n previousSibling,\n contains,\n getRootNode,\n host,\n styleSheets,\n shadowRoot,\n querySelector,\n querySelectorAll,\n nowTimestamp,\n mutationObserverCtor,\n patch\n};\nexport {\n childNodes,\n contains,\n index as default,\n firstChild,\n getRootNode,\n getUntaintedAccessor,\n getUntaintedMethod,\n getUntaintedPrototype,\n host,\n isAngularZonePresent,\n lastChild,\n mutationObserverCtor,\n nextSibling,\n nowTimestamp,\n ownerDocument,\n parentElement,\n parentNode,\n patch,\n previousSibling,\n querySelector,\n querySelectorAll,\n shadowRoot,\n styleSheets,\n textContent\n};\n//# sourceMappingURL=utils.js.map\n","/**\n * Legacy shared utility module.\n *\n * This file currently contains helpers used by both snapshot and rebuild paths\n * and is also part of the public API surface, re-exported from index.ts.\n *\n * Migration intent:\n * - snapshot.ts should consume snapshot-domain helpers via snapshot-utils.ts\n * - rebuild.ts should consume rebuild-domain helpers via rebuild-utils.ts\n * - when safe, split internals into snapshot-only / rebuild-only / shared\n * modules while keeping this module as a compatibility shim for external users\n */\nimport type {\n idNodeMap,\n MaskInputFn,\n MaskInputOptions,\n nodeMetaMap,\n} from './types';\n\nimport { NodeType } from '@rrweb/types';\nimport type {\n IMirror,\n serializedNodeWithId,\n serializedNode,\n documentNode,\n documentTypeNode,\n textNode,\n elementNode,\n} from '@rrweb/types';\nimport dom from '@rrweb/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 * serialize the css rules from the .sheet property\n * for <link rel=\"stylesheet\"> elements, this is the only way of getting the rules without a FETCH\n * for <style> elements, this is less preferable to looking at childNodes[0].textContent\n * (which will include vendor prefixed rules which may not be used or visible to the recorded browser,\n * but which might be needed by the replayer browser)\n * however, at snapshot time, we don't know whether the style element has suffered\n * any programmatic manipulation prior to the snapshot, in which case the .sheet would be more up to date\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 (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 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 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 // 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}\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 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 filePathNoHash = filePath.split('#')[0];\n const maybeHash = filePath.substring(filePathNoHash.length);\n const stack = href.split('#')[0].split('/');\n const parts = filePathNoHash.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('/')}${maybeHash}${maybeQuote})`;\n },\n );\n}\n\nconst cssNormalizeBase = '(?:/\\\\*[^*]*\\\\*/)|[\\\\s;]'; // whitespace\nconst cssNormalizeRe = new RegExp(`${cssNormalizeBase}|\\\\b(0)px?`, 'g');\nconst cssNormalizeReNoPx = new RegExp(cssNormalizeBase, 'g');\n\n/**\n * Intention is to normalize by remove spaces, semicolons and CSS comments\n * so that we can compare css as authored vs. output of stringifyStylesheet\n */\nexport function normalizeCssString(\n cssText: string,\n /**\n * _testNoPxNorm: only used as part of the 'substring matching going from many to none'\n * test case so that it will trigger a failure if the conditions that let to the creation of that test arise again\n */\n _testNoPxNorm = false,\n): string {\n return _testNoPxNorm\n ? cssText.replace(cssNormalizeReNoPx, '')\n : cssText.replace(cssNormalizeRe, '$1');\n}\n\n/**\n * Maps the output of stringifyStylesheet to individual text nodes of a <style> element\n * which occurs when javascript is used to append to the style element\n * and may also occur when browsers opt to break up large text nodes\n * performance needs to be considered, see e.g. #1603\n */\nexport function splitCssText(\n cssText: string,\n style: HTMLStyleElement,\n _testNoPxNorm = false,\n): string[] {\n const childNodes = Array.from(style.childNodes);\n const splits: string[] = [];\n let iterCount = 0;\n if (childNodes.length > 1 && cssText && typeof cssText === 'string') {\n let cssTextNorm = normalizeCssString(cssText, _testNoPxNorm);\n const normFactor = cssTextNorm.length / cssText.length;\n for (let i = 1; i < childNodes.length; i++) {\n if (\n childNodes[i].textContent &&\n typeof childNodes[i].textContent === 'string'\n ) {\n const textContentNorm = normalizeCssString(\n childNodes[i].textContent!,\n _testNoPxNorm,\n );\n const jLimit = 100; // how many iterations for the first part of searching\n let j = 3;\n for (; j < textContentNorm.length; j++) {\n if (\n // keep consuming css identifiers (to get a decent chunk more quickly)\n textContentNorm[j].match(/[a-zA-Z0-9]/) ||\n // substring needs to be unique to this section\n textContentNorm.indexOf(textContentNorm.substring(0, j), 1) !== -1\n ) {\n continue;\n }\n break;\n }\n for (; j < textContentNorm.length; j++) {\n let startSubstring = textContentNorm.substring(0, j);\n // this substring should appears only once in overall text too\n let cssNormSplits = cssTextNorm.split(startSubstring);\n let splitNorm = -1;\n if (cssNormSplits.length === 2) {\n splitNorm = cssNormSplits[0].length;\n } else if (\n cssNormSplits.length > 2 &&\n cssNormSplits[0] === '' &&\n childNodes[i - 1].textContent !== ''\n ) {\n // this childNode has same starting content as previous\n splitNorm = cssTextNorm.indexOf(startSubstring, 1);\n } else if (cssNormSplits.length === 1) {\n // try to roll back to get multiple matches again\n startSubstring = startSubstring.substring(\n 0,\n startSubstring.length - 1,\n );\n cssNormSplits = cssTextNorm.split(startSubstring);\n if (cssNormSplits.length <= 1) {\n // no split possible\n splits.push(cssText);\n return splits;\n }\n j = jLimit + 1; // trigger end of search\n } else if (j === textContentNorm.length - 1) {\n // we're about to end loop without a split point\n splitNorm = cssTextNorm.indexOf(startSubstring);\n }\n if (cssNormSplits.length >= 2 && j > jLimit) {\n const prevTextContent = childNodes[i - 1].textContent;\n if (prevTextContent && typeof prevTextContent === 'string') {\n // pick the first matching point which respects the previous chunk's approx size\n const prevMinLength = normalizeCssString(prevTextContent).length;\n splitNorm = cssTextNorm.indexOf(startSubstring, prevMinLength);\n }\n if (splitNorm === -1) {\n // fall back to pick the first matching point of many\n splitNorm = cssNormSplits[0].length;\n }\n }\n if (splitNorm !== -1) {\n // find the split point in the original text\n let k = Math.floor(splitNorm / normFactor);\n for (; k > 0 && k < cssText.length; ) {\n iterCount += 1;\n if (iterCount > 50 * childNodes.length) {\n // quit for performance purposes\n splits.push(cssText);\n return splits;\n }\n const normPart = normalizeCssString(\n cssText.substring(0, k),\n _testNoPxNorm,\n );\n if (normPart.length === splitNorm) {\n splits.push(cssText.substring(0, k));\n cssText = cssText.substring(k);\n cssTextNorm = cssTextNorm.substring(splitNorm);\n break;\n } else if (normPart.length < splitNorm) {\n k += Math.max(\n 1,\n Math.floor((splitNorm - normPart.length) / normFactor),\n );\n } else {\n k -= Math.max(\n 1,\n Math.floor((normPart.length - splitNorm) * normFactor),\n );\n }\n }\n break;\n }\n }\n }\n }\n }\n splits.push(cssText); // either the full thing if no splits were found, or the last split\n return splits;\n}\n\nexport function markCssSplits(\n cssText: string,\n style: HTMLStyleElement,\n): string {\n return splitCssText(cssText, style).join('/* rr_split */');\n}\n","import type {\n MaskInputOptions,\n SlimDOMOptions,\n MaskTextFn,\n MaskInputFn,\n KeepIframeSrcFn,\n ICanvas,\n DialogAttributes,\n} from './types';\nimport { NodeType } from '@rrweb/types';\nimport type {\n serializedNode,\n serializedNodeWithId,\n serializedElementNodeWithId,\n elementNode,\n attributes,\n mediaAttributes,\n DataURLOptions,\n} from '@rrweb/types';\nimport {\n Mirror,\n is2DCanvasBlank,\n isElement,\n isShadowRoot,\n maskInputValue,\n isNativeShadowDom,\n stringifyStylesheet,\n getInputType,\n toLowerCase,\n extractFileExtension,\n absolutifyURLs,\n markCssSplits,\n} from './snapshot-utils';\nimport dom from '@rrweb/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]+/;\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 a.setAttribute('href', customHref);\n return a.href;\n}\n\nexport function transformAttribute(\n doc: Document,\n tagName: Lowercase<string>,\n name: Lowercase<string>,\n value: string | null,\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 // href starts with a # is an id pointer for svg\n return absoluteToDoc(doc, value);\n } else if (name === 'xlink:href' && value[0] !== '#') {\n // xlink:href starts with # is an id pointer\n return absoluteToDoc(doc, value);\n } else if (name === 'background' && ['table', 'td', 'th'].includes(tagName)) {\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: Lowercase<string>,\n name: string,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n _value: unknown,\n): boolean {\n return (\n ['video', 'audio'].includes(tagName) && toLowerCase(name) === 'autoplay'\n );\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;\n if (isElement(node)) {\n el = node;\n if (!dom.childNodes(el).length) {\n // optimisation: we can avoid any of the below checks on leaf elements\n // as masking is applied to child text nodes only\n return false;\n }\n } else if (dom.parentElement(node) === null) {\n // should warn? maybe a text node isn't attached to a parent node yet?\n return false;\n } else {\n el = dom.parentElement(node)!;\n }\n try {\n if (typeof maskTextClass === 'string') {\n if (checkAncestors) {\n if (el.closest(`.${maskTextClass}`)) return true;\n } else {\n if (el.classList.contains(maskTextClass)) return true;\n }\n } else {\n if (classMatchesRegex(el, maskTextClass, checkAncestors)) return true;\n }\n if (maskTextSelector) {\n if (checkAncestors) {\n if (el.closest(maskTextSelector)) return true;\n } else {\n if (el.matches(maskTextSelector)) return true;\n }\n }\n } catch (e) {\n //\n }\n return false;\n}\n\n// https://stackoverflow.com/a/36155560\nfunction onceIframeLoaded(\n iframeEl: HTMLIFrameElement,\n listener: () => unknown,\n iframeLoadTimeout: number,\n) {\n const win = iframeEl.contentWindow;\n if (!win) {\n return;\n }\n // document is loading\n let fired = false;\n\n let readyState: DocumentReadyState;\n try {\n readyState = win.document.readyState;\n } catch (error) {\n return;\n }\n if (readyState !== 'complete') {\n const timer = setTimeout(() => {\n if (!fired) {\n listener();\n fired = true;\n }\n }, iframeLoadTimeout);\n iframeEl.addEventListener('load', () => {\n clearTimeout(timer);\n fired = true;\n listener();\n });\n return;\n }\n // check blank frame for Chrome\n const blankUrl = 'about:blank';\n if (\n win.location.href !== blankUrl ||\n iframeEl.src === blankUrl ||\n iframeEl.src === ''\n ) {\n // iframe was already loaded, make sure we wait to trigger the listener\n // till _after_ the mutation that found this iframe has had time to process\n setTimeout(listener, 0);\n\n return iframeEl.addEventListener('load', listener); // keep listing for future loads\n }\n // use default listener\n iframeEl.addEventListener('load', listener);\n}\n\nfunction onceStylesheetLoaded(\n link: HTMLLinkElement,\n listener: () => unknown,\n styleSheetLoadTimeout: number,\n) {\n let fired = false;\n let styleSheetLoaded: StyleSheet | null;\n try {\n styleSheetLoaded = link.sheet;\n } catch (error) {\n return;\n }\n\n if (styleSheetLoaded) return;\n\n const timer = setTimeout(() => {\n if (!fired) {\n listener();\n fired = true;\n }\n }, styleSheetLoadTimeout);\n\n link.addEventListener('load', () => {\n clearTimeout(timer);\n fired = true;\n listener();\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 keepIframeSrcFn: KeepIframeSrcFn;\n /**\n * `newlyAddedElement: true` skips scrollTop and scrollLeft check\n */\n newlyAddedElement?: boolean;\n cssCaptured?: 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 keepIframeSrcFn,\n newlyAddedElement = false,\n cssCaptured = 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 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 cssCaptured,\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 cssCaptured?: boolean;\n },\n): serializedNode {\n const { needsMask, maskTextFn, rootId, cssCaptured } = 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 textContent: string | null = '';\n const isStyle = parentTagName === 'STYLE' ? true : undefined;\n const isScript = parentTagName === 'SCRIPT' ? true : undefined;\n if (isScript) {\n textContent = 'SCRIPT_PLACEHOLDER';\n } else if (!cssCaptured) {\n textContent = dom.textContent(n);\n if (isStyle && textContent) {\n // mutation only: we don't need to use stringifyStylesheet\n // as a <style> text node mutation obliterates any previous\n // programmatic rule manipulation (.insertRule etc.)\n // so the current textContent represents the most up to date state\n textContent = absolutifyURLs(textContent, getHref(options.doc));\n }\n }\n if (!isStyle && !isScript && textContent && needsMask) {\n textContent = maskTextFn\n ? maskTextFn(textContent, dom.parentElement(n))\n : textContent.replace(/[\\S]/g, '*');\n }\n\n return {\n type: NodeType.Text,\n textContent: textContent || '',\n rootId,\n };\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 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 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 }\n // remote css\n if (tagName === 'link' && inlineStylesheet) {\n //TODO: maybe replace this `.styleSheets` with original one\n const stylesheet = Array.from(doc.styleSheets).find((s) => {\n return s.href === (n as HTMLLinkElement).href;\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 if (tagName === 'style' && (n as HTMLStyleElement).sheet) {\n let cssText = stringifyStylesheet(\n (n as HTMLStyleElement).sheet as CSSStyleSheet,\n );\n if (cssText) {\n if (n.childNodes.length > 1) {\n cssText = markCssSplits(cssText, n as HTMLStyleElement);\n }\n attributes._cssText = cssText;\n }\n }\n // form fields\n if (['input', 'textarea', 'select'].includes(tagName)) {\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 (attributes as DialogAttributes).rr_open_mode = n.matches('dialog:modal')\n ? 'modal'\n : 'non-modal';\n }\n\n // canvas image data\n if (tagName === 'canvas' && recordCanvas) {\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 image.removeEventListener('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 (['audio', 'video'].includes(tagName)) {\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 } = n.getBoundingClientRect();\n attributes = {\n class: attributes.class,\n rr_width: `${width}px`,\n rr_height: `${height}px`,\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\nexport function slimDOMDefaults(\n _slimDOMOptions: SlimDOMOptions | 'all' | true | false | undefined,\n) {\n if (_slimDOMOptions === true || _slimDOMOptions === 'all') {\n // if true: set of sensible options that should not throw away any information\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 // the following are off for slimDOMOptions === true,\n // as they destroy some (hidden) info:\n headMetaAuthorship: _slimDOMOptions === 'all',\n headMetaDescKeywords: _slimDOMOptions === 'all',\n headTitleMutations: _slimDOMOptions === 'all',\n };\n } else if (_slimDOMOptions) {\n return _slimDOMOptions;\n }\n return {};\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 lowerIfExists(sn.attributes.rel) === 'icon' ||\n lowerIfExists(sn.attributes.rel) === 'apple-touch-icon' ||\n lowerIfExists(sn.attributes.rel) === 'shortcut icon')))\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 (lowerIfExists(sn.attributes.name) === 'robots' ||\n lowerIfExists(sn.attributes.name) === 'googlebot' ||\n lowerIfExists(sn.attributes.name) === 'bingbot')\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 (lowerIfExists(sn.attributes.name) === 'author' ||\n lowerIfExists(sn.attributes.name) === 'generator' ||\n lowerIfExists(sn.attributes.name) === 'framework' ||\n lowerIfExists(sn.attributes.name) === 'publisher' ||\n lowerIfExists(sn.attributes.name) === 'progid' ||\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 (lowerIfExists(sn.attributes.name) === 'google-site-verification' ||\n lowerIfExists(sn.attributes.name) === 'yandex-verification' ||\n lowerIfExists(sn.attributes.name) === 'csrf-token' ||\n lowerIfExists(sn.attributes.name) === 'p:domain_verify' ||\n lowerIfExists(sn.attributes.name) === 'verify-v1' ||\n lowerIfExists(sn.attributes.name) === 'verification' ||\n lowerIfExists(sn.attributes.name) === 'shopify-checkout-api-token')\n ) {\n return true;\n }\n }\n }\n return 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 preserveWhiteSpace?: boolean;\n onSerialize?: (n: Node) => unknown;\n onIframeLoad?: (\n iframeNode: HTMLIFrameElement,\n node: serializedElementNodeWithId,\n ) => unknown;\n iframeLoadTimeout?: number;\n onStylesheetLoad?: (\n linkNode: HTMLLinkElement,\n node: serializedElementNodeWithId,\n ) => unknown;\n stylesheetLoadTimeout?: number;\n cssCaptured?: boolean;\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 onSerialize,\n onIframeLoad,\n iframeLoadTimeout = 5000,\n onStylesheetLoad,\n stylesheetLoadTimeout = 5000,\n keepIframeSrcFn = () => false,\n newlyAddedElement = false,\n cssCaptured = false,\n } = options;\n let { needsMask } = options;\n let { preserveWhiteSpace = true } = options;\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 keepIframeSrcFn,\n newlyAddedElement,\n cssCaptured,\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.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 preserveWhiteSpace,\n onSerialize,\n onIframeLoad,\n iframeLoadTimeout,\n onStylesheetLoad,\n stylesheetLoadTimeout,\n keepIframeSrcFn,\n cssCaptured: false,\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 if (\n serializedNode.type === NodeType.Element &&\n (serializedNode as elementNode).attributes._cssText !== undefined &&\n typeof serializedNode.attributes._cssText === 'string'\n ) {\n bypassOptions.cssCaptured = true;\n }\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 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 preserveWhiteSpace,\n onSerialize,\n onIframeLoad,\n iframeLoadTimeout,\n onStylesheetLoad,\n stylesheetLoadTimeout,\n keepIframeSrcFn,\n });\n\n if (serializedIframeNode) {\n onIframeLoad(\n n as HTMLIFrameElement,\n serializedIframeNode as serializedElementNodeWithId,\n );\n }\n }\n },\n iframeLoadTimeout,\n );\n }\n\n // <link rel=stylesheet href=...>\n if (\n serializedNode.type === NodeType.Element &&\n serializedNode.tagName === 'link' &&\n typeof serializedNode.attributes.rel === 'string' &&\n (serializedNode.attributes.rel === 'stylesheet' ||\n (serializedNode.attributes.rel === 'preload' &&\n typeof serializedNode.attributes.href === 'string' &&\n extractFileExtension(serializedNode.attributes.href) === 'css'))\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 preserveWhiteSpace,\n onSerialize,\n onIframeLoad,\n iframeLoadTimeout,\n onStylesheetLoad,\n stylesheetLoadTimeout,\n keepIframeSrcFn,\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\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 preserveWhiteSpace?: boolean;\n onSerialize?: (n: Node) => unknown;\n onIframeLoad?: (\n iframeNode: HTMLIFrameElement,\n node: serializedElementNodeWithId,\n ) => unknown;\n iframeLoadTimeout?: number;\n onStylesheetLoad?: (\n linkNode: HTMLLinkElement,\n node: serializedElementNodeWithId,\n ) => unknown;\n stylesheetLoadTimeout?: number;\n keepIframeSrcFn?: KeepIframeSrcFn;\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 maskAllInputs = false,\n maskTextFn,\n maskInputFn,\n slimDOM = false,\n dataURLOptions,\n preserveWhiteSpace,\n onSerialize,\n onIframeLoad,\n iframeLoadTimeout,\n onStylesheetLoad,\n stylesheetLoadTimeout,\n keepIframeSrcFn = () => false,\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 = slimDOMDefaults(slimDOM);\n\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 preserveWhiteSpace,\n onSerialize,\n onIframeLoad,\n iframeLoadTimeout,\n onStylesheetLoad,\n stylesheetLoadTimeout,\n keepIframeSrcFn,\n newlyAddedElement: false,\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","import { NodeType as RRNodeType } from '@rrweb/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 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 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 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","import type {\n throttleOptions,\n listenerHandler,\n hookResetter,\n blockClass,\n addedNodeMutation,\n DocumentDimension,\n IWindow,\n DeprecatedMirror,\n textMutation,\n IMirror,\n} from '@rrweb/types';\nimport type { Mirror, SlimDOMOptions } from 'rrweb-snapshot';\nimport { isShadowRoot, IGNORED_NODE, classMatchesRegex } from 'rrweb-snapshot';\nimport { RRNode, RRIFrameElement, BaseRRNode } from 'rrdom';\nimport dom from '@rrweb/utils';\nexport { nowTimestamp } from '@rrweb/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 () => target.removeEventListener(type, fn, options);\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 d.set!.call(this, value);\n }, 0);\n if (original && original.set) {\n original.set.call(this, value);\n }\n },\n },\n );\n return () => hookSetter(target, key, original || {}, true);\n}\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) {\n return false;\n }\n const el = closestElementOfNode(node);\n\n if (!el) {\n return false;\n }\n\n try {\n if (typeof blockClass === 'string') {\n if (el.classList.contains(blockClass)) return true;\n if (checkAncestors && el.closest('.' + blockClass) !== null) return true;\n } else {\n if (classMatchesRegex(el, blockClass, checkAncestors)) return true;\n }\n } catch (e) {\n // e\n }\n if (blockSelector) {\n if (el.matches(blockSelector)) return true;\n if (checkAncestors && el.closest(blockSelector) !== null) return 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\n/**\n * Traverses a CSSRuleList to find a nested rule at the given position.\n *\n * Returns null instead of throwing if the rule doesn't exist. This is important\n * because during replay:\n * - StyleDeclaration events may reference rules added dynamically that don't\n * exist yet due to timing/ordering issues\n * - StyleSheetRule events that create rules may not have been processed yet\n * - Constructed/adopted stylesheets may not be fully synchronized\n *\n * @param rules - The CSSRuleList to traverse\n * @param position - Array of indices, e.g., [0, 1, 0] for rules[0].cssRules[1].cssRules[0]\n * @returns The nested rule, or null if not found\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 = dom.ownerDocument(n);\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 = dom.ownerDocument(n);\n if (!doc) return false;\n return dom.contains(doc, n) || shadowHostInDom(n);\n}\n","import {\n serializeNodeWithId,\n transformAttribute,\n IGNORED_NODE,\n ignoreAttribute,\n isShadowRoot,\n needMaskingText,\n maskInputValue,\n isNativeShadowDom,\n getInputType,\n toLowerCase,\n} from 'rrweb-snapshot';\nimport type { observerParam, MutationBufferParam } from '../types';\nimport type {\n mutationRecord,\n textCursor,\n attributeCursor,\n removedNodeMutation,\n addedNodeMutation,\n} from '@rrweb/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 '@rrweb/utils';\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 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\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 '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 }\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 this.shadowDomManager.reset();\n this.canvasManager.reset();\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 while (this.mapRemoves.length) {\n this.mirror.removeNodeFromMap(this.mapRemoves.shift()!);\n }\n\n for (const n of this.movedSet) {\n const parentNode = dom.parentNode(n);\n if (\n this.removesSubTreeCache.has(parentNode as Node) &&\n !this.movedSet.has(parentNode as Node)\n ) {\n continue;\n }\n this.addedSet.add(n);\n }\n\n let n: Node | null = null;\n let parentNode: Node | null = null;\n let parentId = -1;\n let nextSibling: Node | null = null;\n let ancestorBad = false;\n const missingParents = new Set<Node>();\n const iter = this.addedSet.values();\n let curr = iter.next();\n while (this.addedSet.size) {\n if (n !== null && this.addedSet.has(dom.previousSibling(n) as Node)) {\n // reuse parentNode, parentId, ancestorBad\n nextSibling = n; // n is a good next sibling\n n = dom.previousSibling(n) as Node;\n } else {\n if (!this.addedSet.has(curr.value as Node)) {\n // having the `iter` here rather than picking directly from this.addedSet\n // ensures we don't get caught re-traversing 'tombstones' in the Set\n // (we reuse curr in multiple iterations until it's ancestors and nextSiblings are serialized)\n curr = iter.next();\n }\n n = curr.value as Node;\n\n // eslint-disable-next-line no-constant-condition\n while (true) {\n parentNode = dom.parentNode(n);\n if (this.addedSet.has(parentNode as Node)) {\n // start at top of added tree so as not to serialize children before their parents (parentId requirement)\n n = parentNode as Node;\n continue;\n }\n break;\n }\n\n if (missingParents.has(parentNode as Node)) {\n parentNode = null;\n } else if (parentNode) {\n // we have a new parentNode for a 'row' of DOM children\n // perf: we reuse these calculations across all child nodes\n\n if (!inDom(parentNode)) {\n ancestorBad = true;\n } else {\n ancestorBad =\n isSelfOrAncestorInSet(this.droppedSet, parentNode) ||\n this.removesSubTreeCache.has(parentNode);\n\n if (ancestorBad && isSelfOrAncestorInSet(this.movedSet, n)) {\n // not bad, just moved\n ancestorBad = false;\n }\n }\n\n if (this.addedSet.has(dom.lastChild(parentNode) as Node)) {\n // jump instead of crawling nextSibling to nextSibling\n n = dom.lastChild(parentNode) as Node;\n nextSibling = null;\n } else {\n // eslint-disable-next-line no-constant-condition\n while (true) {\n nextSibling = dom.nextSibling(n);\n if (this.addedSet.has(nextSibling as Node)) {\n // keep going as we can't serialize a node before it's next sibling (nextId requirement)\n n = nextSibling as Node;\n continue;\n }\n break;\n }\n }\n\n parentId = isShadowRoot(parentNode)\n ? this.mirror.getId(getShadowHost(n))\n : this.mirror.getId(parentNode);\n\n // If the node is the direct child of a shadow root, we treat the shadow host as its parent node.\n if (\n parentId === -1 &&\n parentNode.nodeType === Node.DOCUMENT_FRAGMENT_NODE\n ) {\n const shadowHost = dom.host(parentNode as ShadowRoot);\n parentId = this.mirror.getId(shadowHost);\n }\n }\n }\n\n this.addedSet.delete(n); // don't re-iterate\n\n if (!parentNode || parentId === -1) {\n missingParents.add(n); // ensure any added child nodes can also early-out\n continue;\n } else if (ancestorBad) {\n // it's possible we could unify missingParents and this.droppedSet\n // but would need to check the subtleties\n this.droppedSet.add(n);\n continue;\n }\n\n let cssCaptured = false;\n if (n.nodeType === Node.TEXT_NODE) {\n const parentTag = (parentNode as Element).tagName;\n if (parentTag === 'TEXTAREA') {\n // genTextAreaValueMutation already called via parent\n continue;\n } else if (parentTag === 'STYLE' && addedIds.has(parentId)) {\n // css content will be recorded via parent's _cssText attribute when\n // mutation adds entire <style> element\n cssCaptured = true;\n }\n }\n\n let nextId = nextSibling ? this.mirror.getId(nextSibling) : null;\n while (nextId === IGNORED_NODE) {\n nextSibling = nextSibling && dom.nextSibling(nextSibling);\n nextId = nextSibling && this.mirror.getId(nextSibling);\n }\n if (nextId === -1) {\n // sibling not included in addedNodes, but\n // no id as not yet serialized?\n console.warn(\n \"Couldn't record new node. Couldn't find mirror id for nextSibling:\",\n nextSibling,\n );\n n = null; // don't iterate to previousSibling as we haven't successful serialized this node\n continue;\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 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 as Node)) {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n this.shadowDomManager.addShadowRoot(\n dom.shadowRoot(n as Node)!,\n this.doc,\n );\n }\n },\n onIframeLoad: (iframe, childSn) => {\n this.iframeManager.attachIframe(iframe, childSn);\n this.shadowDomManager.observeAttachShadow(iframe);\n },\n onStylesheetLoad: (link, childSn) => {\n this.stylesheetManager.attachLinkElement(link, childSn);\n },\n cssCaptured,\n });\n if (sn) {\n adds.push({\n parentId,\n nextId,\n node: sn,\n });\n addedIds.add(sn.id);\n }\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 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 const tagNameLower = toLowerCase(target.tagName);\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 tagNameLower === '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 tagNameLower === 'input' &&\n (m.oldValue || '').toLowerCase() === 'password'\n ) {\n target.setAttribute('data-rr-is-password', 'true');\n }\n\n if (!ignoreAttribute(tagNameLower, attributeName, value)) {\n // overwrite attribute if the mutations was triggered in same time\n item.attributes[attributeName] = transformAttribute(\n this.doc,\n tagNameLower,\n toLowerCase(attributeName),\n value,\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.setAttribute('style', 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) || 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 isSelfOrAncestorInSet(set: Set<Node>, n: Node): boolean {\n if (set.size === 0) return false;\n return _isSelfOrAncestorInSet(set, n);\n}\n\nfunction _isSelfOrAncestorInSet(set: Set<Node>, n: Node): boolean {\n if (set.has(n)) {\n return true;\n }\n const parent = dom.parentNode(n);\n if (!parent) {\n return false;\n }\n return _isSelfOrAncestorInSet(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","import {\n type MaskInputOptions,\n maskInputValue,\n Mirror,\n getInputType,\n toLowerCase,\n} from 'rrweb-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 '@rrweb/utils';\nimport type { observerParam, MutationBufferParam } from '../types';\nimport {\n IncrementalSource,\n MouseInteractions,\n PointerTypes,\n MediaInteractions,\n} from '@rrweb/types';\nimport type {\n mutationCallBack,\n mousemoveCallBack,\n mousePosition,\n mouseInteractionCallBack,\n listenerHandler,\n scrollCallback,\n styleSheetRuleCallback,\n viewportResizeCallback,\n inputValue,\n inputCallback,\n hookResetter,\n hooksParam,\n Arguments,\n mediaInteractionCallback,\n canvasMutationCallback,\n fontCallback,\n fontParam,\n styleDeclarationCallback,\n IWindow,\n SelectionRange,\n selectionCallback,\n customElementCallback,\n} from '@rrweb/types';\nimport MutationBuffer from './mutation';\nimport { callbackWrapper } from './error-handler';\nimport dom, { mutationObserverCtor } from '@rrweb/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): [MutationObserver, () => void] {\n const mutationBuffer = new MutationBuffer();\n mutationBuffers.push(mutationBuffer);\n // see mutation.ts for details\n mutationBuffer.init(options);\n const [ObserverCtor, iframeCleanup] = mutationObserverCtor();\n const observer = new (ObserverCtor as new (\n callback: MutationCallback,\n ) => MutationObserver)(\n callbackWrapper(mutationBuffer.processMutations.bind(mutationBuffer)),\n );\n observer.observe(rootEl, {\n attributes: true,\n attributeOldValue: true,\n characterData: true,\n characterDataOldValue: true,\n childList: true,\n subtree: true,\n });\n return [observer, iframeCleanup];\n}\n\nfunction initMoveObserver({\n mousemoveCb,\n sampling,\n doc,\n mirror,\n}: observerParam): listenerHandler {\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 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 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 const handlers = [\n on('mousemove', updatePosition, doc),\n on('touchmove', updatePosition, doc),\n on('drag', updatePosition, doc),\n ];\n return callbackWrapper(() => {\n handlers.forEach((h) => h());\n });\n}\n\nfunction initMouseInteractionObserver({\n mouseInteractionCb,\n doc,\n mirror,\n blockClass,\n blockSelector,\n sampling,\n}: observerParam): listenerHandler {\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 const handlers: listenerHandler[] = [];\n let currentPointerType: PointerTypes | null = null;\n const getHandler = (eventKey: keyof typeof MouseInteractions) => {\n return (event: MouseEvent | TouchEvent | PointerEvent) => {\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 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 handlers.push(on(eventName, handler, doc));\n });\n return callbackWrapper(() => {\n handlers.forEach((h) => h());\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 const updatePosition = callbackWrapper(\n throttle<UIEvent>(\n callbackWrapper((evt) => {\n const target = getEventTarget(evt);\n if (\n !target ||\n isBlocked(target as Node, blockClass, blockSelector, true)\n ) {\n return;\n }\n const id = mirror.getId(target as Node);\n if (target === doc && doc.defaultView) {\n const scrollLeftTop = getWindowScroll(doc.defaultView);\n scrollCb({\n id,\n x: scrollLeftTop.left,\n y: scrollLeftTop.top,\n });\n } else {\n scrollCb({\n id,\n x: (target as HTMLElement).scrollLeft,\n y: (target as HTMLElement).scrollTop,\n });\n }\n }),\n sampling.scroll || 100,\n ),\n );\n return on('scroll', updatePosition, doc);\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\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 function eventHandler(event: Event) {\n let target = getEventTarget(event) as HTMLElement | null;\n const userTriggered = event.isTrusted;\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 const events = sampling.input === 'last' ? ['change'] : ['input', 'change'];\n const handlers: Array<listenerHandler | hookResetter> = events.map(\n (eventName) => on(eventName, callbackWrapper(eventHandler), doc),\n );\n const currentWindow = doc.defaultView;\n if (!currentWindow) {\n return () => {\n handlers.forEach((h) => h());\n };\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 handlers.push(\n ...hookProperties.map((p) =>\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 return callbackWrapper(() => {\n handlers.forEach((h) => h());\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 // eslint-disable-next-line @typescript-eslint/unbound-method\n const insertRule = win.CSSStyleSheet.prototype.insertRule;\n win.CSSStyleSheet.prototype.insertRule = 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 // Support for deprecated addRule method\n win.CSSStyleSheet.prototype.addRule = 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, [rule, index]);\n };\n\n // eslint-disable-next-line @typescript-eslint/unbound-method\n const deleteRule = win.CSSStyleSheet.prototype.deleteRule;\n win.CSSStyleSheet.prototype.deleteRule = 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 // Support for deprecated removeRule method\n win.CSSStyleSheet.prototype.removeRule = function (\n this: CSSStyleSheet,\n index: number,\n ) {\n return win.CSSStyleSheet.prototype.deleteRule.apply(this, [index]);\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 win.CSSStyleSheet.prototype.replace = 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 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 win.CSSStyleSheet.prototype.replaceSync = 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 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 type.prototype.insertRule = new Proxy(\n unmodifiedFunctions[typeKey].insertRule,\n {\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 type.prototype.deleteRule = new Proxy(\n unmodifiedFunctions[typeKey].deleteRule,\n {\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 return callbackWrapper(() => {\n win.CSSStyleSheet.prototype.insertRule = insertRule;\n win.CSSStyleSheet.prototype.deleteRule = deleteRule;\n replace && (win.CSSStyleSheet.prototype.replace = replace);\n replaceSync && (win.CSSStyleSheet.prototype.replaceSync = replaceSync);\n Object.entries(supportedNestedCSSRuleTypes).forEach(([typeKey, type]) => {\n type.prototype.insertRule = unmodifiedFunctions[typeKey].insertRule;\n type.prototype.deleteRule = unmodifiedFunctions[typeKey].deleteRule;\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 const result = originalPropertyDescriptor.set?.call(this, sheets);\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 // eslint-disable-next-line @typescript-eslint/unbound-method\n const setProperty = win.CSSStyleDeclaration.prototype.setProperty;\n win.CSSStyleDeclaration.prototype.setProperty = 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 // eslint-disable-next-line @typescript-eslint/unbound-method\n const removeProperty = win.CSSStyleDeclaration.prototype.removeProperty;\n win.CSSStyleDeclaration.prototype.removeProperty = 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 return callbackWrapper(() => {\n win.CSSStyleDeclaration.prototype.setProperty = setProperty;\n win.CSSStyleDeclaration.prototype.removeProperty = removeProperty;\n });\n}\n\nfunction initMediaInteractionObserver({\n mediaInteractionCb,\n blockClass,\n blockSelector,\n mirror,\n sampling,\n doc,\n}: observerParam): listenerHandler {\n const handler = callbackWrapper((type: MediaInteractions) =>\n throttle(\n callbackWrapper((event: Event) => {\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 const handlers = [\n on('play', handler(MediaInteractions.Play), doc),\n on('pause', handler(MediaInteractions.Pause), doc),\n on('seeked', handler(MediaInteractions.Seeked), doc),\n on('volumechange', handler(MediaInteractions.VolumeChange), doc),\n on('ratechange', handler(MediaInteractions.RateChange), doc),\n ];\n return callbackWrapper(() => {\n handlers.forEach((h) => h());\n });\n}\n\nfunction initFontObserver({ fontCb, doc }: observerParam): listenerHandler {\n const win = doc.defaultView as IWindow;\n if (!win) {\n return () => {\n //\n };\n }\n\n const handlers: listenerHandler[] = [];\n\n const fontMap = new WeakMap<FontFace, fontParam>();\n\n const originalFontFace = win.FontFace;\n win.FontFace = function FontFace(\n family: string,\n source: string | ArrayBufferLike,\n descriptors?: FontFaceDescriptors,\n ) {\n const fontFace = new originalFontFace(family, source, descriptors);\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 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 handlers.push(() => {\n win.FontFace = originalFontFace;\n });\n handlers.push(restoreHandler);\n\n return callbackWrapper(() => {\n handlers.forEach((h) => h());\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 let mutationObserver: MutationObserver | undefined;\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n let cleanupMutationIframe: () => void = () => {};\n if (o.recordDOM) {\n [mutationObserver, cleanupMutationIframe] = initMutationObserver(o, o.doc);\n }\n const mousemoveHandler = initMoveObserver(o);\n const mouseInteractionHandler = initMouseInteractionObserver(o);\n const scrollHandler = initScrollObserver(o);\n const viewportResizeHandler = initViewportResizeObserver(o, {\n win: currentWindow,\n });\n const inputHandler = initInputObserver(o);\n const mediaInteractionHandler = initMediaInteractionObserver(o);\n\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n let styleSheetObserver = () => {};\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n let adoptedStyleSheetObserver = () => {};\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n let styleDeclarationObserver = () => {};\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n let fontObserver = () => {};\n if (o.recordDOM) {\n styleSheetObserver = initStyleSheetObserver(o, { win: currentWindow });\n adoptedStyleSheetObserver = initAdoptedStyleSheetObserver(o, o.doc);\n styleDeclarationObserver = initStyleDeclarationObserver(o, {\n win: currentWindow,\n });\n if (o.collectFonts) {\n fontObserver = initFontObserver(o);\n }\n }\n const selectionObserver = initSelectionObserver(o);\n const customElementObserver = initCustomElementObserver(o);\n\n // plugins\n const pluginHandlers: listenerHandler[] = [];\n for (const plugin of o.plugins) {\n pluginHandlers.push(\n plugin.observer(plugin.callback, currentWindow, plugin.options),\n );\n }\n\n return callbackWrapper(() => {\n mutationBuffers.forEach((b) => b.reset());\n mutationObserver?.disconnect();\n cleanupMutationIframe();\n mousemoveHandler();\n mouseInteractionHandler();\n scrollHandler();\n viewportResizeHandler();\n inputHandler();\n mediaInteractionHandler();\n styleSheetObserver();\n adoptedStyleSheetObserver();\n styleDeclarationObserver();\n fontObserver();\n selectionObserver();\n customElementObserver();\n pluginHandlers.forEach((h) => h());\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","import type { ICrossOriginIframeMirror } from '@rrweb/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","import type { Mirror } from 'rrweb-snapshot';\nimport { genId } from 'rrweb-snapshot';\nimport type { CrossOriginIframeMessageEvent } from '../types';\nimport CrossOriginIframeMirror from './cross-origin-iframe-mirror';\nimport { EventType, NodeType, IncrementalSource } from '@rrweb/types';\nimport type {\n eventWithTime,\n eventWithoutTime,\n serializedNodeWithId,\n mutationCallBack,\n} from '@rrweb/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 stylesheetManager: StylesheetManager;\n private recordCrossOriginIframes: boolean;\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 if (this.recordCrossOriginIframes) {\n window.addEventListener('message', this.handleMessage.bind(this));\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 addLoadListener(cb: (iframeEl: HTMLIFrameElement) => unknown) {\n this.loadListener = cb;\n }\n\n public attachIframe(\n iframeEl: HTMLIFrameElement,\n childSn: serializedNodeWithId,\n ) {\n this.mutationCb({\n adds: [\n {\n parentId: this.mirror.getId(iframeEl),\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 if (this.recordCrossOriginIframes)\n iframeEl.contentWindow?.addEventListener(\n 'message',\n this.handleMessage.bind(this),\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 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","import type { MutationBufferParam } from '../types';\nimport type {\n mutationCallBack,\n scrollCallback,\n SamplingStrategy,\n} from '@rrweb/types';\nimport {\n initMutationObserver,\n initScrollObserver,\n initAdoptedStyleSheetObserver,\n} from './observer';\nimport { inDom } from '../utils';\nimport type { Mirror } from 'rrweb-snapshot';\nimport { isNativeShadowDom } from 'rrweb-snapshot';\nimport dom, { patch } from '@rrweb/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 private restoreHandlers: (() => 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 const [observer] = initMutationObserver(\n {\n ...this.bypassOptions,\n doc,\n mutationCb: this.mutationCb,\n mirror: this.mirror,\n shadowDomManager: this,\n },\n shadowRoot,\n );\n this.restoreHandlers.push(() => observer.disconnect());\n this.restoreHandlers.push(\n 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 setTimeout(() => {\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 initAdoptedStyleSheetObserver(\n {\n mirror: this.mirror,\n stylesheetManager: this.bypassOptions.stylesheetManager,\n },\n shadowRoot,\n ),\n );\n }, 0);\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 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 public reset() {\n this.restoreHandlers.forEach((handler) => {\n try {\n handler();\n } catch (e) {\n //\n }\n });\n this.restoreHandlers = [];\n this.shadowDoms = new WeakSet();\n }\n}\n","/*\n * base64-arraybuffer 1.0.2 <https://github.com/niklasvh/base64-arraybuffer>\n * Copyright (c) 2022 Niklas von Hertzen <https://hertzen.com>\n * Released under MIT License\n */\nvar chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';\n// Use a lookup table to find the index.\nvar lookup = typeof Uint8Array === 'undefined' ? [] : new Uint8Array(256);\nfor (var i = 0; i < chars.length; i++) {\n lookup[chars.charCodeAt(i)] = i;\n}\nvar encode = function (arraybuffer) {\n var bytes = new Uint8Array(arraybuffer), i, len = bytes.length, base64 = '';\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 if (len % 3 === 2) {\n base64 = base64.substring(0, base64.length - 1) + '=';\n }\n else if (len % 3 === 1) {\n base64 = base64.substring(0, base64.length - 2) + '==';\n }\n return base64;\n};\nvar decode = function (base64) {\n var bufferLength = base64.length * 0.75, len = base64.length, i, p = 0, encoded1, encoded2, encoded3, encoded4;\n if (base64[base64.length - 1] === '=') {\n bufferLength--;\n if (base64[base64.length - 2] === '=') {\n bufferLength--;\n }\n }\n var arraybuffer = new ArrayBuffer(bufferLength), bytes = new Uint8Array(arraybuffer);\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 bytes[p++] = (encoded1 << 2) | (encoded2 >> 4);\n bytes[p++] = ((encoded2 & 15) << 4) | (encoded3 >> 2);\n bytes[p++] = ((encoded3 & 3) << 6) | (encoded4 & 63);\n }\n return arraybuffer;\n};\n\nexport { decode, encode };\n//# sourceMappingURL=base64-arraybuffer.es5.js.map\n","import { encode } from 'base64-arraybuffer';\nimport type { IWindow, CanvasArg } from '@rrweb/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): CanvasArg {\n if (value instanceof Array) {\n return value.map((arg) => serializeArg(arg, win, ctx));\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),\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(); // heavy on large canvas\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: [serializeArg(value.data, win, ctx), value.width, value.height],\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)],\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) => {\n return args.map((arg) => serializeArg(arg, win, ctx));\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","import {\n type blockClass,\n CanvasContext,\n type canvasManagerMutationCallback,\n type IWindow,\n type listenerHandler,\n} from '@rrweb/types';\nimport { hookSetter, isBlocked } from '../../../utils';\nimport { patch } from '@rrweb/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): 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(args, win, this);\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","import type { ICanvas } from 'rrweb-snapshot';\nimport type { blockClass, IWindow, listenerHandler } from '@rrweb/types';\nimport { isBlocked } from '../../../utils';\nimport { patch } from '@rrweb/utils';\n\nfunction getNormalizedContextName(contextType: string) {\n return contextType === 'experimental-webgl' ? 'webgl' : contextType;\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 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 if (!isBlocked(this, blockClass, blockSelector, true)) {\n const ctxName = getNormalizedContextName(contextType);\n if (!('__context' in this)) (this as ICanvas).__context = ctxName;\n\n if (\n setPreserveDrawingBufferToTrue &&\n ['webgl', 'webgl2'].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 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","import {\n type blockClass,\n CanvasContext,\n type canvasManagerMutationCallback,\n type canvasMutationWithType,\n type IWindow,\n type listenerHandler,\n} from '@rrweb/types';\nimport { hookSetter, isBlocked } from '../../../utils';\nimport { patch } from '@rrweb/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): 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);\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): 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 ),\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 ),\n );\n }\n\n return () => {\n handlers.forEach((h) => h());\n };\n}\n","import type { ICanvas, Mirror } from 'rrweb-snapshot';\nimport type {\n blockClass,\n canvasManagerMutationCallback,\n canvasMutationCallback,\n canvasMutationCommand,\n canvasMutationWithType,\n IWindow,\n listenerHandler,\n CanvasArg,\n DataURLOptions,\n} from '@rrweb/types';\nimport { isBlocked } from '../../../utils';\nimport { CanvasContext } from '@rrweb/types';\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\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\n public reset() {\n this.pendingCanvasMutations.clear();\n this.resetObservers && this.resetObservers();\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 }) {\n const {\n sampling = 'all',\n win,\n blockClass,\n blockSelector,\n recordCanvas,\n dataURLOptions,\n } = options;\n this.mutationCb = options.mutationCb;\n this.mirror = options.mirror;\n\n if (recordCanvas && sampling === 'all')\n this.initCanvasMutationObserver(win, blockClass, blockSelector);\n if (recordCanvas && typeof sampling === 'number')\n this.initCanvasFPSObserver(sampling, win, blockClass, blockSelector, {\n dataURLOptions,\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 },\n ) {\n const canvasContextReset = initCanvasContextObserver(\n win,\n blockClass,\n blockSelector,\n true,\n );\n const snapshotInProgressMap: Map<number, boolean> = new Map();\n const worker =\n new ImageBitmapDataURLWorker() as ImageBitmapDataURLRequestWorker;\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, width, height } = e.data;\n this.mutationCb({\n id,\n type: CanvasContext['2D'],\n commands: [\n {\n property: 'clearRect', // wipe canvas\n args: [0, 0, width, height],\n },\n {\n property: 'drawImage', // draws (semi-transparent) image\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 ],\n },\n ],\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 win.document.querySelectorAll('canvas').forEach((canvas) => {\n if (!isBlocked(canvas, blockClass, blockSelector, true)) {\n matchedCanvas.push(canvas);\n }\n });\n return matchedCanvas;\n };\n\n const takeCanvasSnapshots = (timestamp: DOMHighResTimeStamp) => {\n if (\n lastSnapshotTime &&\n timestamp - lastSnapshotTime < timeBetweenSnapshots\n ) {\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 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((canvas as ICanvas).__context) as\n | WebGLRenderingContext\n | WebGL2RenderingContext\n | null;\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 const bitmap = await createImageBitmap(canvas);\n worker.postMessage(\n {\n id,\n bitmap,\n width: canvas.width,\n height: canvas.height,\n dataURLOptions: options.dataURLOptions,\n },\n [bitmap],\n );\n });\n rafId = requestAnimationFrame(takeCanvasSnapshots);\n };\n\n rafId = requestAnimationFrame(takeCanvasSnapshots);\n\n this.resetObservers = () => {\n canvasContextReset();\n cancelAnimationFrame(rafId);\n };\n }\n\n private initCanvasMutationObserver(\n win: IWindow,\n blockClass: blockClass,\n blockSelector: string | null,\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 );\n\n const canvasWebGL1and2Reset = initCanvasWebGLMutationObserver(\n this.processMutation.bind(this),\n win,\n blockClass,\n blockSelector,\n );\n\n this.resetObservers = () => {\n canvasContextReset();\n canvas2DReset();\n canvasWebGL1and2Reset();\n };\n }\n\n private startPendingCanvasMutationFlusher() {\n requestAnimationFrame(() => this.flushPendingCanvasMutations());\n }\n\n private startRAFTimestamping() {\n const setLatestRAFTimestamp = (timestamp: DOMHighResTimeStamp) => {\n this.rafStamps.latestId = timestamp;\n requestAnimationFrame(setLatestRAFTimestamp);\n };\n 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 requestAnimationFrame(() => this.flushPendingCanvasMutations());\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","import { stringifyRule } from 'rrweb-snapshot';\nimport type {\n elementNode,\n serializedNodeWithId,\n adoptedStyleSheetCallback,\n adoptedStyleSheetParam,\n attributeMutation,\n mutationCallBack,\n} from '@rrweb/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 }\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","import {\n snapshot,\n slimDOMDefaults,\n type MaskInputOptions,\n createMirror,\n} from 'rrweb-snapshot';\nimport { initObservers, mutationBuffers } 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 IncrementalSource,\n type listenerHandler,\n type mutationCallbackParam,\n type scrollCallback,\n type canvasMutationParam,\n type adoptedStyleSheetParam,\n} from '@rrweb/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 callbackWrapper,\n registerErrorHandler,\n unregisterErrorHandler,\n} from './error-handler';\nimport dom from '@rrweb/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();\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 = {},\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 errorHandler,\n } = options;\n\n registerErrorHandler(errorHandler);\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 // 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(_slimDOMOptions);\n\n polyfill();\n\n let lastFullSnapshotEvent: eventWithTime;\n let incrementalSnapshotCount = 0;\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 wrappedEmit = (r: eventWithoutTime, isCheckout?: boolean) => {\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 e.data.source === IncrementalSource.Mutation\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 takeFullSnapshot(true);\n }\n }\n };\n\n const wrappedMutationEmit = (m: mutationCallbackParam) => {\n wrappedEmit({\n type: EventType.IncrementalSnapshot,\n data: {\n source: IncrementalSource.Mutation,\n ...m,\n },\n });\n };\n const wrappedScrollEmit: scrollCallback = (p) =>\n wrappedEmit({\n type: EventType.IncrementalSnapshot,\n data: {\n source: IncrementalSource.Scroll,\n ...p,\n },\n });\n const wrappedCanvasMutationEmit = (p: canvasMutationParam) =>\n wrappedEmit({\n type: EventType.IncrementalSnapshot,\n data: {\n source: IncrementalSource.CanvasMutation,\n ...p,\n },\n });\n\n const wrappedAdoptedStyleSheetEmit = (a: adoptedStyleSheetParam) =>\n wrappedEmit({\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 const iframeManager = new IframeManager({\n mirror,\n mutationCb: wrappedMutationEmit,\n stylesheetManager: stylesheetManager,\n recordCrossOriginIframes,\n wrappedEmit,\n });\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 canvasManager = new CanvasManager({\n recordCanvas,\n mutationCb: wrappedCanvasMutationEmit,\n win: window,\n blockClass,\n blockSelector,\n mirror,\n sampling: sampling.canvas,\n dataURLOptions,\n });\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 inlineImages,\n sampling,\n slimDOMOptions,\n iframeManager,\n stylesheetManager,\n canvasManager,\n keepIframeSrcFn,\n processedNodeManager,\n },\n mirror,\n });\n\n takeFullSnapshot = (isCheckout = false) => {\n if (!recordDOM) {\n return;\n }\n wrappedEmit(\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 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(dom.shadowRoot(n as Node)!, document);\n }\n },\n onIframeLoad: (iframe, childSn) => {\n iframeManager.attachIframe(iframe, childSn);\n shadowDomManager.observeAttachShadow(iframe);\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 wrappedEmit(\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\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 try {\n const handlers: listenerHandler[] = [];\n\n const observe = (doc: Document) => {\n return callbackWrapper(initObservers)(\n {\n mutationCb: wrappedMutationEmit,\n mousemoveCb: (positions, source) =>\n wrappedEmit({\n type: EventType.IncrementalSnapshot,\n data: {\n source,\n positions,\n },\n }),\n mouseInteractionCb: (d) =>\n wrappedEmit({\n type: EventType.IncrementalSnapshot,\n data: {\n source: IncrementalSource.MouseInteraction,\n ...d,\n },\n }),\n scrollCb: wrappedScrollEmit,\n viewportResizeCb: (d) =>\n wrappedEmit({\n type: EventType.IncrementalSnapshot,\n data: {\n source: IncrementalSource.ViewportResize,\n ...d,\n },\n }),\n inputCb: (v) =>\n wrappedEmit({\n type: EventType.IncrementalSnapshot,\n data: {\n source: IncrementalSource.Input,\n ...v,\n },\n }),\n mediaInteractionCb: (p) =>\n wrappedEmit({\n type: EventType.IncrementalSnapshot,\n data: {\n source: IncrementalSource.MediaInteraction,\n ...p,\n },\n }),\n styleSheetRuleCb: (r) =>\n wrappedEmit({\n type: EventType.IncrementalSnapshot,\n data: {\n source: IncrementalSource.StyleSheetRule,\n ...r,\n },\n }),\n styleDeclarationCb: (r) =>\n wrappedEmit({\n type: EventType.IncrementalSnapshot,\n data: {\n source: IncrementalSource.StyleDeclaration,\n ...r,\n },\n }),\n canvasMutationCb: wrappedCanvasMutationEmit,\n fontCb: (p) =>\n wrappedEmit({\n type: EventType.IncrementalSnapshot,\n data: {\n source: IncrementalSource.Font,\n ...p,\n },\n }),\n selectionCb: (p) => {\n wrappedEmit({\n type: EventType.IncrementalSnapshot,\n data: {\n source: IncrementalSource.Selection,\n ...p,\n },\n });\n },\n customElementCb: (c) => {\n wrappedEmit({\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 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 plugins:\n plugins\n ?.filter((p) => p.observer)\n ?.map((p) => ({\n observer: p.observer!,\n options: p.options,\n callback: (payload: object) =>\n wrappedEmit({\n type: EventType.Plugin,\n data: {\n plugin: p.name,\n payload,\n },\n }),\n })) || [],\n },\n hooks,\n );\n };\n\n iframeManager.addLoadListener((iframeEl) => {\n try {\n handlers.push(observe(iframeEl.contentDocument!));\n } catch (error) {\n // TODO: handle internal error\n console.warn(error);\n }\n });\n\n const init = () => {\n takeFullSnapshot();\n handlers.push(observe(document));\n recording = true;\n };\n if (['interactive', 'complete'].includes(document.readyState)) {\n init();\n } else {\n handlers.push(\n on('DOMContentLoaded', () => {\n wrappedEmit({\n type: EventType.DomContentLoaded,\n data: {},\n });\n if (recordAfter === 'DOMContentLoaded') init();\n }),\n );\n handlers.push(\n on(\n 'load',\n () => {\n wrappedEmit({\n type: EventType.Load,\n data: {},\n });\n if (recordAfter === 'load') init();\n },\n window,\n ),\n );\n }\n return () => {\n handlers.forEach((handler) => {\n try {\n handler();\n } catch (error) {\n const msg = String(error).toLowerCase();\n /**\n * https://github.com/rrweb-io/rrweb/pull/1695\n * This error can occur in a known scenario:\n * If an iframe is initially same-origin and observed, but later its \n location is changed in an opaque way to a cross-origin URL (perhaps within the iframe via its `document.location` or a redirect) \n * attempting to execute the handler in the stop record function will \n throw a \"cannot access cross-origin frame\" error.\n * This error is expected and can be safely ignored.\n */\n if (!msg.includes('cross-origin')) {\n console.warn(error);\n }\n }\n });\n processedNodeManager.destroy();\n recording = false;\n unregisterErrorHandler();\n };\n } catch (error) {\n // TODO: handle internal error\n console.warn(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","// @himetrica/replaykit: session replay and friction signals for the web.\n//\n// import * as ReplayKit from \"@himetrica/replaykit\";\n// ReplayKit.init({ apiKey: \"hm_...\" });\n//\n// Needs the Himetrica tracker on the same page: recordings and signals belong to the\n// tracker's visitor and session. What is recorded, and when, is configured per\n// project in the dashboard; the SDK reads it from /init on every page.\n\nimport { ReplayKitClient, type ReplayKitOptions } from \"./client\";\n\nexport type { ReplayKitOptions } from \"./client\";\nexport type { ReplayKitSignal, ReplayKitSignalType, ReplayKitTrigger } from \"./protocol\";\n\nlet client: ReplayKitClient | null = null;\n\n/** Starts ReplayKit. A second call is ignored. */\nexport function init(options: ReplayKitOptions): void {\n if (client) return;\n client = new ReplayKitClient(options);\n client.start();\n}\n\n/** Record this session from now on (and keep the pre-trigger buffer). */\nexport function start(): void {\n client?.manualStart();\n}\n\n/**\n * Mark this moment as worth a recording, like an error would. `reason` is for your\n * own debugging (logged with `debug: true`); the recording is tagged \"manual\".\n */\nexport function trigger(reason?: string): void {\n client?.manualStart(reason);\n}\n\n/** Stop recording for the rest of the session. What was captured is still uploaded. */\nexport function stop(): void {\n client?.manualStop();\n}\n\n/**\n * The visitor's answer to your consent banner. With \"require consent\" on in the\n * project, nothing is recorded until consent(true). consent(false) stops and drops\n * what was not uploaded yet. Remembered on this device.\n */\nexport function consent(granted: boolean): void {\n if (client) client.consent(granted);\n else {\n try {\n localStorage.setItem(\"hm_rk_consent\", granted ? \"1\" : \"0\");\n } catch {\n // Storage unavailable.\n }\n }\n}\n\n/** Id of the recording running on this page, if any. */\nexport function getRecordingId(): string | null {\n return client?.recordingId() ?? null;\n}\n\n/** Stops everything and removes the listeners (tests, SPA teardown). */\nexport function shutdown(): void {\n client?.destroy();\n client = null;\n}\n","// Per-session recording state, in sessionStorage so it follows the session across the\n// pages of a multi-page site (each page load is a new SDK instance).\n//\n// Keyed to the tracker session id: when the tracker rolls a new session (30 min idle,\n// new UTM...), the stored state belongs to the old one and is discarded.\n\nimport type { Env } from \"./env\";\nimport type { ReplayKitRecordingStats, ReplayKitTrigger } from \"./protocol\";\n\nexport type StopReason = \"quota\" | \"manual\" | \"limit\" | \"off\";\n\nexport interface SessionState {\n sid: string;\n /** Recording id, set once a trigger fired; absent while only buffering. */\n rid?: string;\n /** Next chunk sequence number to upload. */\n seq: number;\n trigger?: ReplayKitTrigger;\n /** Set when recording must not (re)start for the rest of the session. */\n stopped?: StopReason;\n stats?: ReplayKitRecordingStats;\n /** Visible tab time of the session's earlier pages, for the minimum duration. */\n visibleMs?: number;\n}\n\nconst KEY = \"hm_rk_state\";\n\nexport class StateStore {\n private cache: SessionState | null = null;\n\n constructor(private readonly env: Env) {}\n\n load(sid: string): SessionState {\n if (this.cache?.sid === sid) return this.cache;\n let s: SessionState | null = null;\n try {\n const raw = this.env.getSession(KEY);\n if (raw) s = JSON.parse(raw) as SessionState;\n } catch {\n s = null;\n }\n if (!s || s.sid !== sid || typeof s.seq !== \"number\") s = { sid, seq: 0 };\n this.cache = s;\n return s;\n }\n\n save(s: SessionState): void {\n this.cache = s;\n try {\n this.env.setSession(KEY, JSON.stringify(s));\n } catch {\n // In-memory copy still drives this page.\n }\n }\n}\n\nexport function emptyStats(now: number, entryUrl: string): ReplayKitRecordingStats {\n return { startedAt: now, endedAt: now, activeMs: 0, clicks: 0, rageClicks: 0, deadClicks: 0, errors: 0, pages: 1, entryUrl };\n}\n","// Browser globals behind one interface, like ErrorKit's env.ts.\n//\n// Network, storage, timers and the clock go through an Env, so the transport, the\n// uploader and the client run in plain Node under node:test with fakes. DOM wiring\n// (listeners, rrweb) stays in signals-dom.ts / recorder.ts and is not unit-tested.\n\nexport interface FetchResult {\n status: number;\n headers: { get(name: string): string | null };\n json(): Promise<unknown>;\n}\n\nexport interface Env {\n now(): number;\n uuid(): string;\n fetch?: (url: string, init: RequestInit) => Promise<FetchResult>;\n sendBeacon?: (url: string, body: string) => boolean;\n getLocal(key: string): string | null;\n setLocal(key: string, value: string | null): void;\n getSession(key: string): string | null;\n setSession(key: string, value: string | null): void;\n getCookie(name: string): string | null;\n /** Async key/value store that survives a page load (IndexedDB). Missing = nothing carried across pages. */\n store?: KvStore;\n /** gzip; undefined when CompressionStream is unavailable (recording is then skipped). */\n gzip?: (text: string) => Promise<Blob>;\n setTimer(fn: () => void, ms: number): unknown;\n clearTimer(handle: unknown): void;\n}\n\nexport interface KvStore {\n get<T>(key: string): Promise<T | undefined>;\n set(key: string, value: unknown): Promise<void>;\n del(key: string): Promise<void>;\n}\n\nexport const isBrowser = typeof window !== \"undefined\" && typeof document !== \"undefined\";\n\nexport function uuidV4(): string {\n const c = (globalThis as { crypto?: Crypto }).crypto;\n if (c && typeof c.randomUUID === \"function\") {\n try {\n return c.randomUUID();\n } catch {\n // randomUUID throws on insecure origins in some browsers; fall through.\n }\n }\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, (ch) => {\n const r = (Math.random() * 16) | 0;\n return (ch === \"x\" ? r : (r & 0x3) | 0x8).toString(16);\n });\n}\n\n// Storage throws in Safari private mode, sandboxed iframes and under storage policies.\nfunction safeGet(storage: () => Storage, key: string): string | null {\n try {\n return storage().getItem(key);\n } catch {\n return null;\n }\n}\n\nfunction safeSet(storage: () => Storage, key: string, value: string | null): void {\n try {\n if (value === null) storage().removeItem(key);\n else storage().setItem(key, value);\n } catch {\n // Unavailable or full: in-memory state still works for this page.\n }\n}\n\n/** One IndexedDB object store used as a key/value map. Every failure degrades to \"nothing stored\". */\nfunction indexedDbStore(): KvStore | undefined {\n if (typeof indexedDB === \"undefined\") return undefined;\n let dbp: Promise<IDBDatabase> | null = null;\n const open = () =>\n (dbp ??= new Promise<IDBDatabase>((resolve, reject) => {\n const req = indexedDB.open(\"himetrica-replaykit\", 1);\n req.onupgradeneeded = () => req.result.createObjectStore(\"kv\");\n req.onsuccess = () => resolve(req.result);\n req.onerror = () => reject(req.error);\n }));\n const run = <T>(mode: IDBTransactionMode, fn: (s: IDBObjectStore) => IDBRequest | void): Promise<T | undefined> =>\n open()\n .then(\n (db) =>\n new Promise<T | undefined>((resolve) => {\n const tx = db.transaction(\"kv\", mode);\n const req = fn(tx.objectStore(\"kv\"));\n tx.oncomplete = () => resolve(req ? (req.result as T) : undefined);\n tx.onerror = tx.onabort = () => resolve(undefined);\n }),\n )\n .catch(() => undefined);\n return {\n get: <T>(key: string) => run<T>(\"readonly\", (s) => s.get(key)),\n set: (key, value) => run<void>(\"readwrite\", (s) => void s.put(value, key)).then(() => undefined),\n del: (key) => run<void>(\"readwrite\", (s) => void s.delete(key)).then(() => undefined),\n };\n}\n\nfunction gzipFn(): Env[\"gzip\"] {\n if (typeof CompressionStream === \"undefined\" || typeof Blob === \"undefined\" || typeof Response === \"undefined\") return undefined;\n return (text) => new Response(new Blob([text]).stream().pipeThrough(new CompressionStream(\"gzip\"))).blob();\n}\n\nexport function browserEnv(): Env {\n const originalFetch = typeof fetch === \"function\" ? fetch.bind(globalThis) : undefined;\n const nav = typeof navigator !== \"undefined\" ? navigator : undefined;\n return {\n now: () => Date.now(),\n uuid: () => uuidV4(),\n fetch: originalFetch as Env[\"fetch\"],\n sendBeacon:\n nav && typeof nav.sendBeacon === \"function\"\n ? (url, body) => {\n try {\n return nav.sendBeacon(url, new Blob([body], { type: \"text/plain\" }));\n } catch {\n return false;\n }\n }\n : undefined,\n getLocal: (key) => safeGet(() => localStorage, key),\n setLocal: (key, value) => safeSet(() => localStorage, key, value),\n getSession: (key) => safeGet(() => sessionStorage, key),\n setSession: (key, value) => safeSet(() => sessionStorage, key, value),\n getCookie: (name) => {\n try {\n const match = document.cookie.match(new RegExp(\"(?:^|; )\" + name.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\") + \"=([^;]*)\"));\n return match ? decodeURIComponent(match[1]) : null;\n } catch {\n return null;\n }\n },\n store: indexedDbStore(),\n gzip: gzipFn(),\n setTimer: (fn, ms) => setTimeout(fn, ms),\n clearTimer: (h) => clearTimeout(h as ReturnType<typeof setTimeout>),\n };\n}\n","// Identity bridge with the analytics tracker, strictly READ-ONLY (same approach as\n// ErrorKit's browser/identity.ts).\n//\n// The tracker (tracker-js / tracker.js) stores the ids in:\n// visitor cookie hm_vid (cookieDomain mode) or localStorage hm_visitor_id\n// session cookie hm_sid (cookieDomain mode) or sessionStorage hm_session_id\n// We read those keys and never write them. window.himetrica.getSessionId() is NOT\n// called: in the tracker it refreshes the session timestamp.\n//\n// A recording or a signal is only worth something tied to the tracker's visitor and\n// session, so without the tracker on the page ReplayKit stays idle.\n\nimport type { Env } from \"./env\";\n\nexport interface Identity {\n visitorId?: string;\n sessionId?: string;\n}\n\nexport function readIdentity(env: Env): Identity {\n const visitorId = env.getCookie(\"hm_vid\") || env.getLocal(\"hm_visitor_id\") || undefined;\n const sessionId = env.getCookie(\"hm_sid\") || env.getSession(\"hm_session_id\") || undefined;\n return { visitorId, sessionId };\n}\n","// Pure helpers the recording decision is made of: path globs and the session sample.\n\n/**\n * Path glob, as the project config writes them: `*` matches any run of characters\n * (slashes included), everything else is literal. A pattern without `*` is a prefix\n * on a segment boundary: `/checkout` matches `/checkout` and `/checkout/step-2`, not\n * `/checkouts`. Matched against the pathname only, case-insensitive.\n */\nexport function matchPath(pattern: string, pathname: string): boolean {\n const p = pattern.trim().toLowerCase();\n if (!p) return false;\n const path = (pathname || \"/\").toLowerCase();\n if (!p.includes(\"*\")) {\n const base = p.endsWith(\"/\") && p.length > 1 ? p.slice(0, -1) : p;\n return path === base || path.startsWith(base.endsWith(\"/\") ? base : base + \"/\");\n }\n const re = new RegExp(\"^\" + p.split(\"*\").map(escapeRegExp).join(\".*\") + \"$\");\n return re.test(path);\n}\n\nexport function matchAny(patterns: readonly string[], pathname: string): boolean {\n for (const p of patterns) if (matchPath(p, pathname)) return true;\n return false;\n}\n\nfunction escapeRegExp(s: string): string {\n return s.replace(/[.+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\n/**\n * Deterministic [0, 1) from the session id (cyrb53). Every page of a session gets the\n * same draw, so a sampled session is recorded across all its pages, and the server\n * could recompute it.\n */\nexport function sampleDraw(sessionId: string): number {\n let h1 = 0xdeadbeef;\n let h2 = 0x41c6ce57;\n for (let i = 0; i < sessionId.length; i++) {\n const ch = sessionId.charCodeAt(i);\n h1 = Math.imul(h1 ^ ch, 2654435761);\n h2 = Math.imul(h2 ^ ch, 1597334677);\n }\n h1 = Math.imul(h1 ^ (h1 >>> 16), 2246822507) ^ Math.imul(h2 ^ (h2 >>> 13), 3266489909);\n h2 = Math.imul(h2 ^ (h2 >>> 16), 2246822507) ^ Math.imul(h1 ^ (h1 >>> 13), 3266489909);\n const n = 4294967296 * (2097151 & h2) + (h1 >>> 0);\n return n / 9007199254740992;\n}\n\nexport function inSample(sessionId: string, rate: number): boolean {\n if (!(rate > 0)) return false;\n if (rate >= 1) return true;\n return sampleDraw(sessionId) < rate;\n}\n\n/** URL without query and hash: queries carry tokens and emails, never sent. */\nexport function stripUrl(href: string): string {\n const cut = href.search(/[?#]/);\n return cut === -1 ? href : href.slice(0, cut);\n}\n","// The pre-trigger ring buffer.\n//\n// rrweb can only replay from a full snapshot: a Meta event (type 4) followed by a\n// FullSnapshot (type 2). The recorder takes one every CHECKOUT_MS, so the buffer can\n// always be cut at the last checkout that is older than the window and still start\n// with a replayable page. The cut keeps BUFFER_WINDOW_MS..BUFFER_WINDOW_MS+CHECKOUT_MS\n// of history before the trigger.\n\nexport interface RrEvent {\n type: number;\n timestamp: number;\n data?: unknown;\n}\n\nexport const EVENT_FULL_SNAPSHOT = 2;\nexport const EVENT_META = 4;\nexport const EVENT_CUSTOM = 5;\n/** rrweb custom event the SDK adds on SPA URL changes (rrweb only emits Meta on page loads/checkouts). */\nexport const PAGE_TAG = \"replaykit:page\";\n\n/**\n * Pages shown in a run of events, in order: Meta hrefs (page loads, and every\n * checkout repeats the current one) plus PAGE_TAG custom events. Query/fragment\n * stripped, back-to-back repeats folded, `prev` = last page already reported for\n * this recording (so a checkout's repeated Meta is not a new page). Capped at `max`.\n */\nexport function pagesOf(events: RrEvent[], prev: string, max: number): Array<{ url: string; ts: number }> {\n const out: Array<{ url: string; ts: number }> = [];\n let last = prev;\n for (const e of events) {\n let href: unknown;\n if (e.type === EVENT_META) href = (e.data as { href?: unknown } | undefined)?.href;\n else if (e.type === EVENT_CUSTOM) {\n const d = e.data as { tag?: unknown; payload?: { href?: unknown } } | undefined;\n if (d?.tag === PAGE_TAG) href = d.payload?.href;\n }\n if (typeof href !== \"string\" || !href) continue;\n const cut = href.search(/[?#]/);\n const url = (cut === -1 ? href : href.slice(0, cut)).slice(0, 500);\n if (url === last) continue;\n last = url;\n out.push({ url, ts: e.timestamp });\n if (out.length >= max) break;\n }\n return out;\n}\n\nexport const BUFFER_WINDOW_MS = 30_000;\nexport const CHECKOUT_MS = 30_000;\n\n/** Index of the Meta event that opens the snapshot the event list may start from. */\nfunction snapshotStart(events: RrEvent[], i: number): number {\n // rrweb emits Meta right before FullSnapshot; keep the Meta so the player knows the viewport.\n return i > 0 && events[i - 1].type === EVENT_META ? i - 1 : i;\n}\n\n/**\n * Drops everything before the most recent full snapshot whose timestamp is at or\n * before `now - windowMs`. If no snapshot is that old, nothing is dropped (the buffer\n * is still shorter than the window). A list that does not start with a snapshot (the\n * head was lost) is cut at its first snapshot, since nothing before it can replay.\n */\nexport function trimBuffer(events: RrEvent[], now: number, windowMs = BUFFER_WINDOW_MS): RrEvent[] {\n const cutoff = now - windowMs;\n let keepFrom = -1;\n let firstSnapshot = -1;\n for (let i = 0; i < events.length; i++) {\n if (events[i].type !== EVENT_FULL_SNAPSHOT) continue;\n if (firstSnapshot === -1) firstSnapshot = i;\n if (events[i].timestamp <= cutoff) keepFrom = i;\n else break;\n }\n if (keepFrom === -1) keepFrom = firstSnapshot;\n if (keepFrom === -1) return [];\n const start = snapshotStart(events, keepFrom);\n return start === 0 ? events : events.slice(start);\n}\n\n/** Rough serialized size, to cut chunks without stringifying on every event. */\nexport function approxBytes(e: RrEvent): number {\n // Mutations and snapshots dominate; JSON.stringify per event is acceptable: events\n // are stringified once here and the chunk is re-stringified once at flush.\n try {\n return JSON.stringify(e).length;\n } catch {\n return 0;\n }\n}\n","// Friction detectors, DOM-free so node:test can drive them with plain numbers.\n// signals-dom.ts feeds them real clicks and reports what they decide.\n\nexport interface ClickPoint {\n x: number;\n y: number;\n ts: number;\n /** Stable key of the clicked element (its selector), so a burst on one button counts even if the mouse drifts. */\n target: string;\n}\n\n/** 3+ clicks within RAGE_WINDOW_MS, on the same element or within RAGE_RADIUS_PX of the first. */\nexport const RAGE_MIN_CLICKS = 3;\nexport const RAGE_WINDOW_MS = 1000;\nexport const RAGE_RADIUS_PX = 30;\n\nexport interface RageBurst {\n first: ClickPoint;\n count: number;\n lastTs: number;\n}\n\n/**\n * Feeds clicks in order. `onClick` returns \"trigger\" on the click that turns a burst\n * into a rage click (the 3rd), so recording starts right away; the finished burst\n * (with its final count) comes out of `onClick` of the next unrelated click or of\n * `flush(now)` once the window has passed.\n */\nexport class RageDetector {\n private burst: RageBurst | null = null;\n\n onClick(c: ClickPoint): { trigger: boolean; finished: RageBurst | null } {\n const b = this.burst;\n if (b && c.ts - b.lastTs <= RAGE_WINDOW_MS && near(b.first, c)) {\n b.count++;\n b.lastTs = c.ts;\n return { trigger: b.count === RAGE_MIN_CLICKS, finished: null };\n }\n const finished = b && b.count >= RAGE_MIN_CLICKS ? b : null;\n this.burst = { first: c, count: 1, lastTs: c.ts };\n return { trigger: false, finished };\n }\n\n /** The burst that ended (quiet for the window) before `now`, if it was a rage click. */\n flush(now: number): RageBurst | null {\n const b = this.burst;\n if (!b || now - b.lastTs <= RAGE_WINDOW_MS) return null;\n this.burst = null;\n return b.count >= RAGE_MIN_CLICKS ? b : null;\n }\n\n /** Clicks of the current burst so far (a rage burst is not also a dead click). */\n currentCount(): number {\n return this.burst?.count ?? 0;\n }\n}\n\nfunction near(a: ClickPoint, b: ClickPoint): boolean {\n if (a.target && a.target === b.target) return true;\n return Math.abs(a.x - b.x) <= RAGE_RADIUS_PX && Math.abs(a.y - b.y) <= RAGE_RADIUS_PX;\n}\n\n/** How long after a click something must happen for the click not to be \"dead\". */\nexport const DEAD_CLICK_WAIT_MS = 500;\n\nexport interface ClickTargetFacts {\n /** Lowercase tag name of the clicked element. */\n tag: string;\n /** The element or an ancestor is a link/button/[role=button…]/[onclick]/summary. */\n insideInteractive: boolean;\n /** Text fields, selects, labels, contenteditable: a click there focuses, nothing else to expect. */\n isFormField: boolean;\n /** Computed cursor is \"pointer\": the page tells the user it is clickable. */\n pointerCursor: boolean;\n /** Text is selected after the click (the user was selecting, not clicking). */\n hasSelection: boolean;\n}\n\n/**\n * A click can only be dead when the element promised something: it is (inside) an\n * interactive element or shows a pointer cursor. A click on plain text or on a\n * background is not friction, whatever happens after it.\n */\nexport function isDeadClickCandidate(f: ClickTargetFacts): boolean {\n if (f.isFormField || f.hasSelection) return false;\n if (f.tag === \"html\" || f.tag === \"body\") return false;\n return f.insideInteractive || f.pointerCursor;\n}\n\nexport interface AfterClickReaction {\n /** DOM mutations observed in the wait window. */\n mutations: number;\n urlChanged: boolean;\n scrolled: boolean;\n focusChanged: boolean;\n /** The page is unloading (a navigation or a download started). */\n unloading: boolean;\n}\n\n/** Nothing reacted within DEAD_CLICK_WAIT_MS: the click was dead. */\nexport function isDeadClick(r: AfterClickReaction): boolean {\n return r.mutations === 0 && !r.urlChanged && !r.scrolled && !r.focusChanged && !r.unloading;\n}\n\n/** Active time: input gaps up to ACTIVE_GAP_MS count, longer gaps are idle. */\nexport const ACTIVE_GAP_MS = 5000;\n\nexport function activeIncrement(lastInputTs: number, ts: number): number {\n if (!lastInputTs) return 0;\n const gap = ts - lastInputTs;\n return gap > 0 && gap <= ACTIVE_GAP_MS ? gap : 0;\n}\n","// What this page does about recording, from what /init said and the session state.\n// Pure, so the whole decision table is unit-tested.\n\nimport type { ReplayKitTrigger } from \"./protocol\";\nimport type { SessionState } from \"./state\";\n\nexport type PageMode =\n /** Nothing is recorded on this page (signals may still flow). */\n | { kind: \"off\" }\n /** requireConsent and the banner has not said yes yet. */\n | { kind: \"wait_consent\" }\n /** A recording of this session is already running: continue it. */\n | { kind: \"continue\" }\n /** Start a recording now, for this reason. */\n | { kind: \"start\"; trigger: ReplayKitTrigger }\n /** Keep the pre-trigger buffer and wait for a trigger. */\n | { kind: \"buffer\" };\n\nexport interface DecideInput {\n /** /init answered record: true. */\n record: boolean;\n /** CompressionStream exists (chunks are gzip'd in the browser). */\n canGzip: boolean;\n state: SessionState;\n /** Path is in excludePaths. */\n excluded: boolean;\n requireConsent: boolean;\n /** Consent stored by ReplayKit.consent(): true, false, or never given. */\n consent: boolean | null;\n forceTrigger: ReplayKitTrigger | null;\n sampled: boolean;\n /** Path matched checkoutPaths and \"checkout\" is an enabled trigger. */\n checkout: boolean;\n}\n\n/** Triggers that open a recording however short the visit is (same list as the API's). */\nexport const MIN_DURATION_EXEMPT: readonly ReplayKitTrigger[] = [\"error\", \"rage_click\", \"manual\"];\n\n/**\n * How long trigger `t` still has to wait before it may open a recording, given how long the\n * session has been on screen. 0 = open it now. A bounce never reaches the minimum, so it never\n * opens a recording nor costs quota; an error or a rage click does not wait.\n */\nexport function waitBeforeRecording(t: ReplayKitTrigger, visibleMs: number, minDurationMs: number): number {\n if (minDurationMs <= 0 || MIN_DURATION_EXEMPT.includes(t)) return 0;\n return Math.max(0, minDurationMs - visibleMs);\n}\n\nexport function decidePage(i: DecideInput): PageMode {\n // An explicit ReplayKit.consent(false) wins even when the project does not require consent.\n if (!i.record || !i.canGzip || i.state.stopped || i.excluded || i.consent === false) return { kind: \"off\" };\n if (i.requireConsent && i.consent !== true) return { kind: \"wait_consent\" };\n if (i.state.rid) return { kind: \"continue\" };\n if (i.forceTrigger) return { kind: \"start\", trigger: i.forceTrigger };\n if (i.checkout) return { kind: \"start\", trigger: \"checkout\" };\n if (i.sampled) return { kind: \"start\", trigger: \"sample\" };\n return { kind: \"buffer\" };\n}\n","// Calls to the ingest (POST {apiUrl}/api/t/r/<op>?apiKey=...), text/plain JSON so\n// they are \"simple\" CORS requests with no preflight, plus the PUT of a chunk to R2.\n//\n// Every response is reduced to an outcome the client acts on (see the contract in\n// packages/shared/src/replaykit.ts):\n// ok 2xx\n// drop 400/413: this body is unusable, forget it\n// stop 401: bad key / origin not allowed, ReplayKit stops for this page\n// off 403: rollout, plan or this op is off for the project\n// quota 429: no more recordings this session (signals continue)\n// retry 5xx, network error, or no fetch at all\n\nimport type { Env } from \"./env\";\nimport type {\n ReplayKitChunkRequest,\n ReplayKitChunkResponse,\n ReplayKitInitRequest,\n ReplayKitInitResponse,\n ReplayKitSignalsRequest,\n} from \"./protocol\";\n\nexport type Outcome = \"ok\" | \"drop\" | \"stop\" | \"off\" | \"quota\" | \"retry\";\n\nexport function outcomeOf(status: number): Outcome {\n if (status >= 200 && status < 300) return \"ok\";\n if (status === 401) return \"stop\";\n if (status === 403) return \"off\";\n if (status === 429) return \"quota\";\n if (status === 400 || status === 413 || status === 404 || status === 422) return \"drop\";\n return \"retry\";\n}\n\nexport interface Result<T> {\n outcome: Outcome;\n data?: T;\n}\n\nexport class Api {\n constructor(\n private readonly env: Env,\n private readonly apiUrl: string,\n private readonly apiKey: string,\n ) {}\n\n url(op: \"init\" | \"chunk\" | \"signals\"): string {\n return `${this.apiUrl}/api/t/r/${op}?apiKey=${encodeURIComponent(this.apiKey)}`;\n }\n\n init(body: ReplayKitInitRequest): Promise<Result<ReplayKitInitResponse>> {\n return this.post<ReplayKitInitResponse>(\"init\", body, true);\n }\n\n chunk(body: ReplayKitChunkRequest): Promise<Result<ReplayKitChunkResponse>> {\n return this.post<ReplayKitChunkResponse>(\"chunk\", body, true);\n }\n\n signals(body: ReplayKitSignalsRequest): Promise<Result<void>> {\n return this.post<void>(\"signals\", body, false);\n }\n\n /** On page hide: fire-and-forget. False when the beacon could not be queued. */\n beaconSignals(body: ReplayKitSignalsRequest): boolean {\n return !!this.env.sendBeacon?.(this.url(\"signals\"), JSON.stringify(body));\n }\n\n /** PUT the gzip'd chunk to the presigned R2 URL. R2 answers 200; 403 = URL expired or bad signature. */\n async put(url: string, blob: Blob): Promise<Outcome> {\n if (!this.env.fetch) return \"retry\";\n try {\n const res = await this.env.fetch(url, { method: \"PUT\", body: blob, headers: { \"Content-Type\": \"application/gzip\" } });\n if (res.status >= 200 && res.status < 300) return \"ok\";\n // An expired/rejected signature is fixed by asking for a new URL, not by dropping the chunk.\n return res.status === 400 || res.status === 413 ? \"drop\" : \"retry\";\n } catch {\n return \"retry\";\n }\n }\n\n private async post<T>(op: \"init\" | \"chunk\" | \"signals\", body: unknown, wantJson: boolean): Promise<Result<T>> {\n if (!this.env.fetch) return { outcome: \"retry\" };\n try {\n const res = await this.env.fetch(this.url(op), {\n method: \"POST\",\n body: JSON.stringify(body),\n headers: { \"Content-Type\": \"text/plain\" },\n keepalive: false,\n credentials: \"omit\",\n });\n const outcome = outcomeOf(res.status);\n if (outcome !== \"ok\" || !wantJson) return { outcome };\n try {\n return { outcome, data: (await res.json()) as T };\n } catch {\n return { outcome: \"retry\" };\n }\n } catch {\n return { outcome: \"retry\" };\n }\n }\n}\n\nexport const BASE_BACKOFF_MS = 2_000;\nexport const MAX_BACKOFF_MS = 60_000;\n\nexport function backoff(failures: number): number {\n return Math.min(MAX_BACKOFF_MS, BASE_BACKOFF_MS * 2 ** Math.max(0, failures - 1));\n}\n","// Signals out: batched POST /api/t/r/signals every FLUSH_MS (or at a full batch),\n// sendBeacon for whatever is left when the page hides.\n//\n// Signals are cheap and never count against the quota, but a page in a rage loop\n// should not turn into a request loop: at most MAX_PER_PAGE signals per page load,\n// a full batch per request, and identical signals within DEDUPE_MS folded.\n\nimport type { Env } from \"./env\";\nimport { REPLAYKIT_MAX_SIGNALS_PER_BATCH, type ReplayKitSignal } from \"./protocol\";\nimport { backoff, type Api } from \"./transport\";\n\nexport const SIGNAL_FLUSH_MS = 5_000;\nexport const MAX_PER_PAGE = 200;\nconst MAX_QUEUED = 500;\nconst DEDUPE_MS = 2_000;\n\nexport class SignalQueue {\n private queue: ReplayKitSignal[] = [];\n private timer: unknown = null;\n private sentThisPage = 0;\n private failures = 0;\n private busy = false;\n private last = new Map<string, number>();\n /** Ingest said no (403 off, 401 bad key): nothing more this page. */\n disabled = false;\n /** Init has not answered yet: keep collecting, send nothing. */\n held = true;\n\n constructor(\n private readonly env: Env,\n private readonly api: Api,\n private readonly ids: () => { sid: string; vid: string; rid?: string },\n ) {}\n\n add(s: ReplayKitSignal): void {\n if (this.disabled || this.sentThisPage + this.queue.length >= MAX_PER_PAGE) return;\n const key = `${s.type}|${s.url}|${s.selector || \"\"}|${s.detail || \"\"}`;\n const prev = this.last.get(key);\n if (prev !== undefined && s.ts - prev < DEDUPE_MS) return;\n this.last.set(key, s.ts);\n this.queue.push(s);\n if (this.queue.length > MAX_QUEUED) this.queue.shift();\n if (this.held) return;\n if (this.queue.length >= REPLAYKIT_MAX_SIGNALS_PER_BATCH) this.schedule(0);\n else if (!this.timer) this.schedule(SIGNAL_FLUSH_MS);\n }\n\n /** Init answered: start sending (signals on) or drop everything (off). */\n release(enabled: boolean): void {\n this.held = false;\n if (!enabled) {\n this.disable();\n return;\n }\n if (this.queue.length) this.schedule(0);\n }\n\n disable(): void {\n this.disabled = true;\n this.queue = [];\n if (this.timer) this.env.clearTimer(this.timer);\n this.timer = null;\n }\n\n private schedule(ms: number): void {\n if (this.timer) this.env.clearTimer(this.timer);\n this.timer = this.env.setTimer(() => {\n this.timer = null;\n void this.flush();\n }, ms);\n }\n\n async flush(): Promise<void> {\n if (this.busy || this.held || this.disabled) return;\n this.busy = true;\n try {\n while (this.queue.length && !this.disabled) {\n const batch = this.queue.slice(0, REPLAYKIT_MAX_SIGNALS_PER_BATCH);\n const r = await this.api.signals({ ...this.ids(), signals: batch });\n if (r.outcome === \"ok\" || r.outcome === \"drop\" || r.outcome === \"quota\") {\n // 429 on signals would be a server bug (they never count): drop the batch, don't loop.\n this.queue.splice(0, batch.length);\n this.sentThisPage += batch.length;\n this.failures = 0;\n continue;\n }\n if (r.outcome === \"off\" || r.outcome === \"stop\") {\n this.disable();\n return;\n }\n this.failures++;\n this.schedule(backoff(this.failures));\n return;\n }\n } finally {\n this.busy = false;\n }\n }\n\n /** Page hide: beacon what is left (no status to read; a lost beacon loses a few signals). */\n beacon(): void {\n if (this.held || this.disabled || !this.queue.length) return;\n while (this.queue.length) {\n const batch = this.queue.slice(0, REPLAYKIT_MAX_SIGNALS_PER_BATCH);\n if (!this.api.beaconSignals({ ...this.ids(), signals: batch })) return;\n this.queue.splice(0, batch.length);\n this.sentThisPage += batch.length;\n }\n }\n\n get size(): number {\n return this.queue.length;\n }\n}\n","// DOM side of the friction signals: listeners that turn real clicks, errors,\n// navigations and forms into ReplayKitSignal values. The decisions themselves\n// (what is a rage click, what is a dead click) live in detect.ts.\n//\n// Passive capture-phase listeners only; nothing is patched. The MutationObserver a\n// dead-click check needs is attached for DEAD_CLICK_WAIT_MS after a candidate click\n// and disconnected right after, so a quiet page costs nothing.\n//\n// Never sent: what was typed. A clicked element's text is only read when it is not a\n// field and not masked (.hm-mask, [data-hm-mask], or maskAllText).\n\nimport {\n DEAD_CLICK_WAIT_MS,\n isDeadClick,\n isDeadClickCandidate,\n RAGE_WINDOW_MS,\n RageDetector,\n type ClickTargetFacts,\n} from \"./detect\";\nimport { stripUrl } from \"./match\";\nimport type { ReplayKitSignal } from \"./protocol\";\n\nexport interface SignalHooks {\n now(): number;\n /** Text of clicked elements is withheld (config maskAllText). */\n maskAllText(): boolean;\n signal(s: ReplayKitSignal): void;\n /** A trigger fired: the 3rd click of a rage burst, or a JS error. */\n trigger(t: \"rage_click\" | \"error\"): void;\n /** Any click / key / scroll, for active time and click counts. */\n input(kind: \"click\" | \"key\" | \"scroll\", ts: number): void;\n /** The URL changed without a page load (SPA navigation). */\n navigated(url: string): void;\n}\n\nconst INTERACTIVE = 'a[href],button,summary,[role=\"button\"],[role=\"link\"],[role=\"tab\"],[role=\"menuitem\"],[role=\"checkbox\"],[role=\"switch\"],[role=\"option\"],[onclick]';\nconst FIELD = \"input,textarea,select,label,option,[contenteditable],[contenteditable=true]\";\nconst MASKED = \".hm-mask,[data-hm-mask],[data-hm-block],.hm-block\";\nconst MAX_TEXT = 80;\nconst MAX_DETAIL = 200;\n\n/** Short CSS path: up to 3 levels, stops at an id. Hashed class names (css-1x2y3z) are skipped. */\nexport function selectorOf(el: Element | null): string {\n const parts: string[] = [];\n let cur: Element | null = el;\n for (let depth = 0; cur && depth < 3 && cur.nodeType === 1; depth++) {\n const tag = cur.tagName.toLowerCase();\n if (tag === \"html\" || tag === \"body\") break;\n if (cur.id && /^[A-Za-z][\\w-]{0,40}$/.test(cur.id) && !/\\d{3,}/.test(cur.id)) {\n parts.unshift(`${tag}#${cur.id}`);\n break;\n }\n const classes = (typeof cur.className === \"string\" ? cur.className : \"\")\n .split(/\\s+/)\n .filter((c) => c && c.length < 30 && !/\\d{3,}|^css-|^sc-|__/.test(c))\n .slice(0, 2);\n parts.unshift(tag + classes.map((c) => \".\" + c).join(\"\"));\n cur = cur.parentElement;\n }\n return parts.join(\" > \");\n}\n\nfunction visibleText(el: Element, maskAll: boolean): string | undefined {\n if (maskAll || el.closest(MASKED) || el.closest(FIELD)) return undefined;\n const t = ((el as HTMLElement).innerText ?? el.textContent ?? \"\").replace(/\\s+/g, \" \").trim();\n if (!t) return (el.getAttribute(\"aria-label\") || el.getAttribute(\"title\") || undefined)?.slice(0, MAX_TEXT);\n return t.slice(0, MAX_TEXT);\n}\n\nfunction targetFacts(el: Element): ClickTargetFacts {\n let pointer = false;\n try {\n pointer = getComputedStyle(el).cursor === \"pointer\";\n } catch {\n pointer = false;\n }\n const sel = typeof getSelection === \"function\" ? getSelection() : null;\n return {\n tag: el.tagName.toLowerCase(),\n insideInteractive: !!el.closest(INTERACTIVE),\n isFormField: !!el.closest(FIELD),\n pointerCursor: pointer,\n hasSelection: !!sel && !sel.isCollapsed && sel.toString().trim().length > 0,\n };\n}\n\n/** The element a click \"means\": the nearest interactive ancestor, else the target itself. */\nfunction clickedElement(target: EventTarget | null): Element | null {\n const el = target instanceof Element ? target : target instanceof Node ? target.parentElement : null;\n if (!el) return null;\n return el.closest(INTERACTIVE) || el;\n}\n\nexport class SignalCollector {\n private rage = new RageDetector();\n private rageEl: Element | null = null;\n private rageTimer: ReturnType<typeof setTimeout> | null = null;\n private lastHref = \"\";\n private hrefTimer: ReturnType<typeof setInterval> | null = null;\n private unloading = false;\n private lastScrollInput = 0;\n private forms = new Map<HTMLFormElement, Set<string>>();\n private errorsSeen = new Set<string>();\n private off: Array<() => void> = [];\n\n constructor(private readonly h: SignalHooks) {}\n\n start(): void {\n this.lastHref = location.href;\n const on = <K extends keyof WindowEventMap>(type: K, fn: (e: WindowEventMap[K]) => void, target: Window | Document = window) => {\n const opts = { capture: true, passive: true };\n target.addEventListener(type, fn as EventListener, opts);\n this.off.push(() => target.removeEventListener(type, fn as EventListener, opts));\n };\n on(\"click\", (e) => this.onClick(e));\n on(\"keydown\", () => this.h.input(\"key\", this.h.now()));\n on(\"scroll\", () => {\n const now = this.h.now();\n if (now - this.lastScrollInput > 250) {\n this.lastScrollInput = now;\n this.h.input(\"scroll\", now);\n }\n });\n on(\"error\", (e) => this.onError(e.message || (e.error as Error | undefined)?.message || \"\"));\n on(\"unhandledrejection\", (e) => {\n const r = e.reason as { message?: string } | string | undefined;\n this.onError(typeof r === \"string\" ? r : r?.message || \"Unhandled promise rejection\");\n });\n on(\"popstate\", () => this.backNav());\n on(\"input\", (e) => this.onField(e.target));\n on(\"change\", (e) => this.onField(e.target));\n on(\"submit\", (e) => {\n if (e.target instanceof HTMLFormElement) this.forms.delete(e.target);\n });\n on(\"pageshow\", () => {\n this.unloading = false;\n });\n // SPA navigations: no patching of history, a cheap href poll instead.\n this.hrefTimer = setInterval(() => this.checkHref(), 1000);\n // Arrived here with the back/forward button.\n try {\n const nav = performance.getEntriesByType(\"navigation\")[0] as PerformanceNavigationTiming | undefined;\n if (nav?.type === \"back_forward\") this.emit({ type: \"back_nav\", detail: stripUrl(location.href) });\n } catch {\n // Navigation Timing unavailable.\n }\n }\n\n stop(): void {\n for (const f of this.off) f();\n this.off = [];\n if (this.hrefTimer) clearInterval(this.hrefTimer);\n if (this.rageTimer) clearTimeout(this.rageTimer);\n this.hrefTimer = this.rageTimer = null;\n }\n\n /** Called by the client on pagehide, before it beacons the queue: report what the page leaves behind. */\n pageHide(): void {\n this.unloading = true;\n this.flushForms();\n this.flushRage(true);\n }\n\n private emit(s: Omit<ReplayKitSignal, \"ts\" | \"url\"> & { ts?: number }): void {\n this.h.signal({ ts: s.ts ?? this.h.now(), url: stripUrl(location.href), ...s } as ReplayKitSignal);\n }\n\n private checkHref(): void {\n const href = location.href;\n if (href === this.lastHref) return;\n const prev = this.lastHref;\n this.lastHref = href;\n if (stripUrl(href) !== stripUrl(prev)) this.h.navigated(stripUrl(href));\n }\n\n private onClick(e: MouseEvent): void {\n const ts = this.h.now();\n this.h.input(\"click\", ts);\n const el = clickedElement(e.target);\n if (!el) return;\n const selector = selectorOf(el);\n const r = this.rage.onClick({ x: e.clientX, y: e.clientY, ts, target: selector });\n if (r.finished) this.reportRage(r.finished.count, r.finished.first.ts);\n if (r.trigger) this.h.trigger(\"rage_click\");\n this.rageEl = this.rage.currentCount() === 1 ? el : this.rageEl;\n if (this.rageTimer) clearTimeout(this.rageTimer);\n this.rageTimer = setTimeout(() => this.flushRage(false), RAGE_WINDOW_MS + 50);\n if (this.rage.currentCount() === 1) this.watchDeadClick(el, selector, ts);\n }\n\n private flushRage(force: boolean): void {\n const b = this.rage.flush(force ? Number.MAX_SAFE_INTEGER : this.h.now());\n if (b) this.reportRage(b.count, b.first.ts);\n }\n\n private reportRage(count: number, ts: number): void {\n const el = this.rageEl;\n this.emit({ type: \"rage_click\", ts, count, selector: el ? selectorOf(el) : undefined, text: el ? visibleText(el, this.h.maskAllText()) : undefined });\n }\n\n private watchDeadClick(el: Element, selector: string, ts: number): void {\n if (!isDeadClickCandidate(targetFacts(el))) return;\n const hrefBefore = location.href;\n const scrollBefore = `${scrollX},${scrollY}`;\n const focusBefore = document.activeElement;\n let mutations = 0;\n let mo: MutationObserver | null = null;\n try {\n mo = new MutationObserver((list) => {\n mutations += list.length;\n });\n mo.observe(document.documentElement, { subtree: true, childList: true, attributes: true, characterData: true });\n } catch {\n return;\n }\n setTimeout(() => {\n mo?.disconnect();\n // Part of a rage burst: reported as a rage click, not also as a dead one.\n if (this.rage.currentCount() > 1) return;\n const dead = isDeadClick({\n mutations,\n urlChanged: location.href !== hrefBefore,\n scrolled: `${scrollX},${scrollY}` !== scrollBefore,\n focusChanged: document.activeElement !== focusBefore && document.activeElement !== el,\n unloading: this.unloading,\n });\n if (dead) this.emit({ type: \"dead_click\", ts, selector, text: visibleText(el, this.h.maskAllText()) });\n }, DEAD_CLICK_WAIT_MS);\n }\n\n private onError(message: string): void {\n const detail = (message || \"Error\").slice(0, MAX_DETAIL);\n if (this.errorsSeen.has(detail)) return;\n this.errorsSeen.add(detail);\n this.emit({ type: \"error\", detail });\n this.h.trigger(\"error\");\n }\n\n private backNav(): void {\n this.emit({ type: \"back_nav\", detail: stripUrl(location.href) });\n this.checkHref();\n }\n\n private onField(target: EventTarget | null): void {\n if (!(target instanceof Element)) return;\n const form = target.closest(\"form\");\n if (!form) return;\n const key = target.getAttribute(\"name\") || target.id || selectorOf(target);\n let set = this.forms.get(form);\n if (!set) this.forms.set(form, (set = new Set()));\n set.add(key);\n }\n\n /** Forms touched and never submitted, reported when the page goes away. */\n private flushForms(): void {\n for (const [form, fields] of this.forms) {\n if (!form.isConnected && fields.size === 0) continue;\n this.emit({ type: \"form_abandon\", selector: selectorOf(form), count: fields.size });\n }\n this.forms.clear();\n }\n}\n","// rrweb, loaded only when this page may record.\n//\n// The ESM build turns the dynamic import into a separate chunk, so a page that only\n// sends signals never downloads rrweb (~24 KB gzip). The IIFE build bundles it.\n//\n// Privacy defaults that config cannot turn off:\n// - every input value is masked (maskAllInputs), passwords and card fields included;\n// - card fields ([autocomplete^=\"cc-\"]) and [data-hm-block] / .hm-block are blocked:\n// replaced by an empty box of the same size, their content never leaves the page;\n// - text marked .hm-mask / [data-hm-mask] is masked; maskAllText masks every text node;\n// - canvas, cross-origin iframes and inlined images are not recorded.\n\nimport type { RrEvent } from \"./buffer\";\nimport { CHECKOUT_MS, PAGE_TAG } from \"./buffer\";\n\nexport interface RecorderOptions {\n blockSelectors: string[];\n maskAllText: boolean;\n emit(e: RrEvent): void;\n}\n\ntype RecordFn = typeof import(\"@rrweb/record\").record;\n\nconst BASE_BLOCK = ['[data-hm-block]', \".hm-block\", '[autocomplete^=\"cc-\"]', 'input[type=\"password\"]'];\nconst BASE_MASK = \".hm-mask,[data-hm-mask]\";\n\nlet recordFn: Promise<RecordFn> | null = null;\n\nfunction loadRecord(): Promise<RecordFn> {\n return (recordFn ??= import(\"@rrweb/record\").then((m) => m.record));\n}\n\n/** Drops selectors the browser rejects: one bad entry in the config must not stop rrweb. */\nexport function validSelectors(list: string[]): string[] {\n return list.filter((s) => {\n if (!s || typeof s !== \"string\") return false;\n try {\n document.createDocumentFragment().querySelector(s);\n return true;\n } catch {\n return false;\n }\n });\n}\n\nexport class Recorder {\n private stopFn: (() => void) | undefined;\n private record: RecordFn | null = null;\n private stopped = false;\n\n async start(o: RecorderOptions): Promise<boolean> {\n try {\n this.record = await loadRecord();\n } catch {\n return false;\n }\n if (this.stopped) return false;\n try {\n this.stopFn = this.record({\n emit: (e) => o.emit(e as unknown as RrEvent),\n checkoutEveryNms: CHECKOUT_MS,\n maskAllInputs: true,\n maskInputOptions: { password: true },\n maskTextSelector: o.maskAllText ? \"*\" : BASE_MASK,\n blockSelector: validSelectors([...BASE_BLOCK, ...o.blockSelectors]).join(\",\"),\n recordCanvas: false,\n recordCrossOriginIframes: false,\n inlineImages: false,\n collectFonts: false,\n slimDOMOptions: { script: true, comment: true, headFavicon: true, headWhitespace: true, headMetaSocial: true, headMetaRobots: true, headMetaHttpEquiv: true, headMetaVerification: true, headMetaAuthorship: true },\n sampling: { mousemove: 50, scroll: 150, input: \"last\" },\n }) ?? undefined;\n return !!this.stopFn;\n } catch {\n return false;\n }\n }\n\n /** New full snapshot right now (the first event of a fresh recording must be one). */\n snapshot(): void {\n try {\n this.record?.takeFullSnapshot(true);\n } catch {\n // Not recording.\n }\n }\n\n /** Marks an SPA URL change in the stream (the player and the page list read it). */\n page(href: string): void {\n try {\n this.record?.addCustomEvent(PAGE_TAG, { href });\n } catch {\n // Not recording.\n }\n }\n\n stop(): void {\n this.stopped = true;\n try {\n this.stopFn?.();\n } catch {\n // Already stopped.\n }\n this.stopFn = undefined;\n }\n}\n","// Live recording upload: rrweb events → gzip'd chunk → presigned PUT straight to R2.\n//\n// Per chunk: POST /api/t/r/chunk (the API answers with a presigned URL and, on seq 0,\n// opens the recording and counts it in the quota), then PUT the gzip to R2. Nothing\n// of the recording passes through our servers.\n//\n// A chunk goes out every FLUSH_MS or once FLUSH_BYTES of raw JSON piled up. The two\n// requests cannot be trusted to finish while a page unloads, so on page hide the\n// unsent events (queued and in flight) are written to IndexedDB instead, and the\n// next page of the same session uploads them before its own. A session that never\n// comes back loses its last few seconds; nothing else is lost.\n//\n// seq advances only after R2 accepted the PUT, so a retry re-uses the same seq and\n// overwrites the same object: retries are idempotent end to end.\n\nimport type { Env } from \"./env\";\nimport { approxBytes, pagesOf, type RrEvent } from \"./buffer\";\nimport { REPLAYKIT_MAX_CHUNK_BYTES, REPLAYKIT_MAX_CHUNKS, REPLAYKIT_MAX_PAGES_PER_CHUNK, type ReplayKitChunkFile } from \"./protocol\";\nimport type { StateStore, SessionState, StopReason } from \"./state\";\nimport { backoff, type Api } from \"./transport\";\n\nexport const FLUSH_MS = 30_000;\nexport const FLUSH_BYTES = 256 * 1024;\n\nconst pendingKey = (sid: string) => `rk:pending:${sid}`;\n\ninterface Pending {\n rid: string;\n events: RrEvent[];\n}\n\nexport interface UploaderHooks {\n /** Recording must stop (quota, ReplayKit off for the project, chunk limit, unusable chunk). */\n onStop(reason: StopReason): void;\n /** Right before a chunk is requested: write the running stats into the session state. */\n beforeChunk?(): void;\n}\n\nexport class Uploader {\n private queue: RrEvent[] = [];\n private inflight: RrEvent[] = [];\n private queuedBytes = 0;\n private timer: unknown = null;\n private retryTimer: unknown = null;\n private failures = 0;\n private busy = false;\n private stopped = false;\n /** Bumped by pause(); a flush that started before it must not touch the new state. */\n private epoch = 0;\n /** A copy of the unsent events was parked in IndexedDB (page hidden); keep it in step with what lands. */\n private parked = false;\n /** Last page reported for `lastPageRid`: a checkout's repeated Meta href is not a new page. */\n private lastPage = \"\";\n private lastPageRid = \"\";\n\n constructor(\n private readonly env: Env,\n private readonly api: Api,\n private readonly states: StateStore,\n private readonly ids: { sid: string; vid: string },\n private readonly hooks: UploaderHooks,\n ) {}\n\n private state(): SessionState {\n return this.states.load(this.ids.sid);\n }\n\n /** Prepends what the previous page of this session could not send. */\n async restorePending(): Promise<void> {\n const store = this.env.store;\n if (!store) return;\n const p = await store.get<Pending>(pendingKey(this.ids.sid));\n if (!p) return;\n await store.del(pendingKey(this.ids.sid));\n const s = this.state();\n if (!s.rid || p.rid !== s.rid || !Array.isArray(p.events) || p.events.length === 0) return;\n this.queue = p.events.concat(this.queue);\n this.queuedBytes += p.events.reduce((n, e) => n + approxBytes(e), 0);\n this.schedule(0);\n }\n\n add(e: RrEvent): void {\n if (this.stopped) return;\n this.queue.push(e);\n this.queuedBytes += approxBytes(e);\n if (this.queuedBytes >= FLUSH_BYTES) this.schedule(0);\n else if (!this.timer) this.schedule(FLUSH_MS);\n }\n\n addMany(events: RrEvent[]): void {\n for (const e of events) this.add(e);\n }\n\n private schedule(ms: number): void {\n if (this.timer) this.env.clearTimer(this.timer);\n this.timer = this.env.setTimer(() => {\n this.timer = null;\n void this.flush();\n }, ms);\n }\n\n /** Uploads everything queued, one chunk at a time. Resolves when the queue is empty or blocked. */\n async flush(): Promise<void> {\n if (this.busy || this.stopped) return;\n const epoch = this.epoch;\n this.busy = true;\n try {\n while (!this.stopped && epoch === this.epoch && (this.inflight.length > 0 || this.queue.length > 0)) {\n if (this.inflight.length === 0) {\n this.inflight = this.queue;\n this.queue = [];\n this.queuedBytes = 0;\n }\n const ok = await this.sendInflight();\n if (!ok) return;\n }\n } finally {\n this.busy = false;\n }\n }\n\n /** True when the in-flight events are done with (sent or dropped); false to wait for a retry. */\n private async sendInflight(): Promise<boolean> {\n this.hooks.beforeChunk?.();\n const s = this.state();\n if (!s.rid || !s.trigger || !s.stats) return false;\n if (s.seq >= REPLAYKIT_MAX_CHUNKS) {\n this.stop(\"limit\");\n return false;\n }\n const gzip = this.env.gzip;\n if (!gzip) {\n this.stop(\"off\");\n return false;\n }\n const file: ReplayKitChunkFile = { v: 1, rid: s.rid, seq: s.seq, events: this.inflight };\n const blob = await gzip(JSON.stringify(file));\n if (blob.size > REPLAYKIT_MAX_CHUNK_BYTES) {\n // Too big for one chunk: send the first half now, the rest goes back to the head of the queue.\n if (this.inflight.length > 1) {\n const half = Math.ceil(this.inflight.length / 2);\n this.queue = this.inflight.slice(half).concat(this.queue);\n this.inflight = this.inflight.slice(0, half);\n return true;\n }\n // One event over 2 MB gzip'd (a giant full snapshot): unreplayable either way.\n this.stop(\"limit\");\n return false;\n }\n const prevPage = this.lastPageRid === s.rid ? this.lastPage : \"\";\n const pages = pagesOf(this.inflight, prevPage, REPLAYKIT_MAX_PAGES_PER_CHUNK);\n const presign = await this.api.chunk({ rid: s.rid, sid: this.ids.sid, vid: this.ids.vid, seq: s.seq, bytes: blob.size, trigger: s.trigger, stats: s.stats, pages });\n if (presign.outcome === \"drop\") {\n this.inflight = [];\n return true;\n }\n if (presign.outcome === \"quota\") return this.stop(\"quota\"), false;\n if (presign.outcome === \"off\" || presign.outcome === \"stop\") return this.stop(\"off\"), false;\n if (presign.outcome !== \"ok\" || !presign.data?.url) return this.retryLater(), false;\n const put = await this.api.put(presign.data.url, blob);\n if (put === \"drop\") {\n this.inflight = [];\n return true;\n }\n if (put !== \"ok\") return this.retryLater(), false;\n this.failures = 0;\n this.inflight = [];\n if (pages.length) {\n this.lastPage = pages[pages.length - 1].url;\n this.lastPageRid = s.rid;\n }\n const cur = this.state();\n if (cur.rid === s.rid) this.states.save({ ...cur, seq: s.seq + 1 });\n // Hidden tab whose upload still went through: the parked copy must not replay it on the next page.\n if (this.parked) {\n if (this.queue.length) this.persist();\n else this.unpersist();\n }\n return true;\n }\n\n private retryLater(): void {\n this.failures++;\n if (this.retryTimer) this.env.clearTimer(this.retryTimer);\n this.retryTimer = this.env.setTimer(() => {\n this.retryTimer = null;\n void this.flush();\n }, backoff(this.failures));\n }\n\n private stop(reason: StopReason): void {\n this.stopped = true;\n this.queue = [];\n this.inflight = [];\n this.queuedBytes = 0;\n this.clearTimers();\n this.hooks.onStop(reason);\n }\n\n private clearTimers(): void {\n if (this.timer) this.env.clearTimer(this.timer);\n if (this.retryTimer) this.env.clearTimer(this.retryTimer);\n this.timer = this.retryTimer = null;\n }\n\n /** Page hide: park unsent events for the next page of this session. */\n persist(): void {\n const store = this.env.store;\n const s = this.state();\n const events = this.inflight.concat(this.queue);\n if (!store || !s.rid || events.length === 0 || this.stopped) return;\n this.parked = true;\n void store.set(pendingKey(this.ids.sid), { rid: s.rid, events } satisfies Pending);\n }\n\n /** The page came back into view: whatever was parked is still in memory, drop the copy. */\n unpersist(): void {\n if (!this.parked) return;\n this.parked = false;\n void this.env.store?.del(pendingKey(this.ids.sid));\n }\n\n /** Stop without a reason the server gave (manual stop, consent withdrawn): drop what is queued. */\n discard(): void {\n this.epoch++;\n this.stopped = true;\n this.queue = [];\n this.inflight = [];\n this.queuedBytes = 0;\n this.clearTimers();\n this.unpersist();\n }\n\n get pendingEvents(): number {\n return this.queue.length + this.inflight.length;\n }\n}\n","// The ReplayKit client: one per page load.\n//\n// 1. waits for the tracker's visitor and session ids (read-only, identity.ts);\n// 2. starts the signal listeners at once, so errors during startup are caught,\n// holding what they find until /init answers;\n// 3. POST /api/t/r/init: signals on/off, recordings on/off, the project's config and\n// a server-side trigger (\"paying\");\n// 4. decides the page (decide.ts): off, continue the session's recording, start\n// one, or keep a pre-trigger buffer and wait for a trigger.\n//\n// Conditional recording: in buffer mode rrweb runs into an in-memory ring buffer cut\n// at full snapshots (buffer.ts), parked in IndexedDB when the page hides so a trigger\n// on the next page of the session still shows the page before. A trigger promotes\n// the buffer into a recording: a recording id is minted, the buffer becomes the\n// first chunk and every later event streams through the uploader.\n\nimport { emptyStats, StateStore, type SessionState, type StopReason } from \"./state\";\nimport { browserEnv, isBrowser, type Env } from \"./env\";\nimport { readIdentity } from \"./identity\";\nimport { inSample, matchAny, stripUrl } from \"./match\";\nimport { trimBuffer, BUFFER_WINDOW_MS, CHECKOUT_MS, EVENT_FULL_SNAPSHOT, type RrEvent } from \"./buffer\";\nimport { activeIncrement } from \"./detect\";\nimport { decidePage, waitBeforeRecording } from \"./decide\";\nimport { Api, backoff } from \"./transport\";\nimport { SignalQueue } from \"./signal-queue\";\nimport { SignalCollector } from \"./signals-dom\";\nimport { Recorder } from \"./recorder\";\nimport { Uploader } from \"./uploader\";\nimport type { ReplayKitClientConfig, ReplayKitInitResponse, ReplayKitRecordingStats, ReplayKitSignal, ReplayKitTrigger } from \"./protocol\";\n\nexport interface ReplayKitOptions {\n /** Your project's public API key (the same one the tracker uses). */\n apiKey: string;\n /** Defaults to https://app.himetrica.com. */\n apiUrl?: string;\n /** Run on localhost (off by default, like the tracker). */\n allowLocalhost?: boolean;\n /** Log decisions to the console. */\n debug?: boolean;\n}\n\nconst CONSENT_KEY = \"hm_rk_consent\";\nconst bufferKey = (sid: string) => `rk:buf:${sid}`;\nconst IDENTITY_POLL_MS = 500;\nconst IDENTITY_WAIT_MS = 15_000;\nconst INIT_ATTEMPTS = 3;\n\ntype Mode = \"idle\" | \"off\" | \"wait_consent\" | \"buffer\" | \"live\";\n\ninterface ParkedBuffer {\n at: number;\n events: RrEvent[];\n}\n\nexport class ReplayKitClient {\n private readonly env: Env;\n private readonly api: Api;\n private readonly states: StateStore;\n private ids: { sid: string; vid: string } | null = null;\n private queue: SignalQueue | null = null;\n private collector: SignalCollector | null = null;\n private recorder: Recorder | null = null;\n private uploader: Uploader | null = null;\n private init: ReplayKitInitResponse | null = null;\n private config: ReplayKitClientConfig | null = null;\n private mode: Mode = \"idle\";\n private buffer: RrEvent[] = [];\n /** Clicks, signals and input times while buffering, folded into the stats on promotion. */\n private recent: Array<{ k: \"click\" | \"rage\" | \"dead\" | \"error\" | \"input\"; ts: number }> = [];\n private stats: ReplayKitRecordingStats | null = null;\n private lastInputTs = 0;\n /** A trigger that fired before /init answered. */\n private earlyTrigger: ReplayKitTrigger | null = null;\n /** A trigger waiting for the session to reach minDurationMs on screen. */\n private pending: ReplayKitTrigger | null = null;\n /** Bumped on every wait scheduled, so only the latest timer acts. */\n private pendingGen = 0;\n /** Visible time of the session's earlier pages (state.visibleMs, read once ids are known). */\n private baseVisibleMs = 0;\n /** Visible time of this page so far, excluding the current visible stretch. */\n private pageVisibleMs = 0;\n /** Start of the current visible stretch, null while the tab is hidden. */\n private visibleSince: number | null = null;\n private destroyed = false;\n private offWindow: Array<() => void> = [];\n\n constructor(private readonly options: ReplayKitOptions, env: Env = browserEnv()) {\n this.env = env;\n const apiUrl = (options.apiUrl || \"https://app.himetrica.com\").replace(/\\/+$/, \"\");\n this.api = new Api(env, apiUrl, options.apiKey);\n this.states = new StateStore(env);\n }\n\n private log(...args: unknown[]): void {\n if (this.options.debug) console.debug(\"[ReplayKit]\", ...args);\n }\n\n /** Starts everything. Safe to call once per page; no-op outside a browser. */\n start(): void {\n if (!isBrowser || !this.options.apiKey) return;\n const host = location.hostname;\n if (!this.options.allowLocalhost && (host === \"localhost\" || host === \"127.0.0.1\" || host === \"[::1]\" || host.endsWith(\".localhost\"))) {\n this.log(\"localhost: idle (allowLocalhost to enable)\");\n return;\n }\n this.trackVisibility();\n const started = this.env.now();\n const tryIds = () => {\n if (this.destroyed) return;\n const id = readIdentity(this.env);\n if (id.sessionId && id.visitorId) {\n this.ids = { sid: id.sessionId, vid: id.visitorId };\n this.boot();\n } else if (this.env.now() - started < IDENTITY_WAIT_MS) {\n this.env.setTimer(tryIds, IDENTITY_POLL_MS);\n } else {\n this.log(\"no tracker ids on this page: idle\");\n }\n };\n tryIds();\n }\n\n private boot(): void {\n const ids = this.ids!;\n this.baseVisibleMs = this.states.load(ids.sid).visibleMs ?? 0;\n this.queue = new SignalQueue(this.env, this.api, () => ({ ...ids, rid: this.mode === \"live\" ? this.state().rid : undefined }));\n this.collector = new SignalCollector({\n now: () => this.env.now(),\n maskAllText: () => this.config?.maskAllText ?? true,\n signal: (s) => this.onSignal(s),\n trigger: (t) => this.trigger(t),\n input: (kind, ts) => this.onInput(kind, ts),\n navigated: (url) => this.onNavigate(url),\n });\n this.collector.start();\n this.listenPage();\n void this.callInit(1);\n }\n\n private state(): SessionState {\n return this.states.load(this.ids!.sid);\n }\n\n private async callInit(attempt: number): Promise<void> {\n const ids = this.ids!;\n const r = await this.api.init({ sid: ids.sid, vid: ids.vid, url: stripUrl(location.href) });\n if (this.destroyed) return;\n if (r.outcome === \"ok\" && r.data) return this.applyInit(r.data);\n if (r.outcome === \"retry\" && attempt < INIT_ATTEMPTS) {\n this.env.setTimer(() => void this.callInit(attempt + 1), backoff(attempt));\n return;\n }\n this.log(\"init refused:\", r.outcome);\n if (r.outcome === \"quota\") {\n // Quota is about recordings; signals never count.\n this.queue?.release(true);\n this.mode = \"off\";\n return;\n }\n this.shutdown();\n }\n\n private applyInit(res: ReplayKitInitResponse): void {\n this.init = res;\n this.config = res.config;\n this.queue!.release(res.signals);\n if (!res.signals && !res.record) {\n this.shutdown();\n return;\n }\n this.decide();\n }\n\n private consentValue(): boolean | null {\n const v = this.env.getLocal(CONSENT_KEY);\n return v === \"1\" ? true : v === \"0\" ? false : null;\n }\n\n private triggerEnabled(t: ReplayKitTrigger): boolean {\n if (t === \"manual\" || t === \"sample\") return true;\n return !!this.config?.triggers.includes(t as ReplayKitClientConfig[\"triggers\"][number]);\n }\n\n private pathExcluded(): boolean {\n return matchAny(this.config?.excludePaths ?? [], location.pathname);\n }\n\n private onCheckoutPath(): boolean {\n return this.triggerEnabled(\"checkout\") && matchAny(this.config?.checkoutPaths ?? [], location.pathname);\n }\n\n private decide(): void {\n if (!this.init || !this.config) return;\n const s = this.state();\n const mode = decidePage({\n record: this.init.record,\n canGzip: !!this.env.gzip,\n state: s,\n excluded: this.pathExcluded(),\n requireConsent: this.config.requireConsent,\n consent: this.consentValue(),\n forceTrigger: this.init.forceTrigger,\n sampled: inSample(this.ids!.sid, this.config.sampleRate),\n checkout: this.onCheckoutPath(),\n });\n this.log(\"page:\", mode.kind, mode.kind === \"start\" ? mode.trigger : \"\");\n if (mode.kind === \"off\" || mode.kind === \"wait_consent\") {\n this.mode = mode.kind;\n return;\n }\n if (mode.kind === \"continue\") {\n this.mode = \"live\";\n const st = s.stats ?? emptyStats(this.env.now(), stripUrl(location.href));\n this.stats = { ...st, pages: st.pages + 1 };\n this.makeUploader();\n void this.uploader!.restorePending();\n void this.startRecorder();\n return;\n }\n this.mode = \"buffer\";\n void this.restoreParkedBuffer().then(async () => {\n if (this.mode !== \"buffer\") return;\n // rrweb emits the page's full snapshot synchronously on start: it lands in the buffer\n // before a promotion, so the first chunk always opens with a replayable page.\n await this.startRecorder();\n if (this.mode !== \"buffer\") return;\n const t = mode.kind === \"start\" ? mode.trigger : this.earlyTrigger;\n this.earlyTrigger = null;\n if (t && this.triggerEnabled(t)) this.requestPromote(t);\n });\n }\n\n private async restoreParkedBuffer(): Promise<void> {\n const store = this.env.store;\n if (!store) return;\n const key = bufferKey(this.ids!.sid);\n const parked = await store.get<ParkedBuffer>(key);\n if (!parked) return;\n void store.del(key);\n const fresh = this.env.now() - parked.at < BUFFER_WINDOW_MS + CHECKOUT_MS;\n if (fresh && Array.isArray(parked.events) && parked.events.length) this.buffer = parked.events.concat(this.buffer);\n }\n\n private async startRecorder(): Promise<void> {\n if (this.recorder) return;\n const rec = (this.recorder = new Recorder());\n const ok = await rec.start({\n blockSelectors: this.config?.blockSelectors ?? [],\n maskAllText: this.config?.maskAllText ?? false,\n emit: (e) => this.onEvent(e),\n });\n if (!ok && this.recorder === rec) {\n this.log(\"rrweb failed to start\");\n this.recorder = null;\n this.mode = \"off\";\n }\n }\n\n private onEvent(e: RrEvent): void {\n if (this.mode === \"buffer\") {\n this.buffer.push(e);\n // Trim only when a new checkout lands: the only moment a cut point appears.\n if (e.type === EVENT_FULL_SNAPSHOT) this.buffer = trimBuffer(this.buffer, this.env.now());\n return;\n }\n if (this.mode === \"live\" && this.uploader) {\n if (this.stats) this.stats.endedAt = Math.max(this.stats.endedAt, e.timestamp);\n this.uploader.add(e);\n }\n }\n\n private makeUploader(): void {\n this.uploader = new Uploader(this.env, this.api, this.states, this.ids!, {\n onStop: (reason) => this.stopRecording(reason),\n beforeChunk: () => this.saveStats(),\n });\n }\n\n private saveStats(): void {\n if (!this.stats || this.mode !== \"live\") return;\n const s = this.state();\n if (s.rid) this.states.save({ ...s, stats: this.stats });\n }\n\n /** A trigger fired: turn the buffer into a recording, or remember it until /init answers. */\n trigger(t: ReplayKitTrigger): void {\n if (this.destroyed || !this.ids) return;\n if (!this.init) {\n if (!this.earlyTrigger) this.earlyTrigger = t;\n return;\n }\n if (this.mode !== \"buffer\" || !this.triggerEnabled(t)) return;\n if (!this.recorder) {\n // Still restoring the parked buffer: the buffer setup promotes it when it is done.\n this.earlyTrigger ??= t;\n return;\n }\n this.requestPromote(t);\n }\n\n // ── Minimum duration ──────────────────────────────────────\n\n private trackVisibility(): void {\n if (document.visibilityState === \"visible\") this.visibleSince = this.env.now();\n const onVis = () => {\n const now = this.env.now();\n if (document.visibilityState === \"hidden\") {\n if (this.visibleSince !== null) this.pageVisibleMs += now - this.visibleSince;\n this.visibleSince = null;\n } else if (this.visibleSince === null) {\n this.visibleSince = now;\n // Hidden tabs do not count: the wait resumes where it stopped.\n if (this.pending) this.schedulePending();\n }\n };\n document.addEventListener(\"visibilitychange\", onVis);\n this.offWindow.push(() => document.removeEventListener(\"visibilitychange\", onVis));\n }\n\n /** Session time on screen: earlier pages + this one, the current visible stretch included. */\n private visibleMs(): number {\n const live = this.visibleSince !== null ? this.env.now() - this.visibleSince : 0;\n return this.baseVisibleMs + this.pageVisibleMs + live;\n }\n\n /** Open the recording now, or once the session has been on screen for minDurationMs. */\n private requestPromote(t: ReplayKitTrigger): void {\n const wait = waitBeforeRecording(t, this.visibleMs(), this.config?.minDurationMs ?? 0);\n if (wait === 0) {\n this.pending = null;\n this.promote(t);\n return;\n }\n // The first waiting trigger is the one the recording reports.\n this.pending ??= t;\n this.log(\"waiting for the minimum duration:\", t, wait, \"ms\");\n this.schedulePending();\n }\n\n private schedulePending(): void {\n const t = this.pending;\n if (!t) return;\n const gen = ++this.pendingGen;\n const wait = waitBeforeRecording(t, this.visibleMs(), this.config?.minDurationMs ?? 0);\n this.env.setTimer(() => {\n if (gen !== this.pendingGen || this.pending !== t || this.mode !== \"buffer\" || this.destroyed) return;\n // Hidden meanwhile: the visibilitychange handler reschedules when the tab comes back.\n if (this.visibleSince === null) return;\n this.requestPromote(t);\n }, Math.max(wait, 50));\n }\n\n private promote(t: ReplayKitTrigger): void {\n const now = this.env.now();\n // The buffer starts at a full snapshot; recordings begin there, so stats do too.\n const events = this.buffer;\n this.buffer = [];\n const startedAt = events.length ? events[0].timestamp : now;\n const stats = emptyStats(startedAt, stripUrl(location.href));\n // The visit lasted until now even if the page was quiet: a recording opened after the\n // minimum duration must not read as shorter than it (the API hides short ones).\n stats.endedAt = Math.max(events.length ? events[events.length - 1].timestamp : now, now);\n this.pending = null;\n let last = 0;\n for (const r of this.recent) {\n if (r.ts < startedAt) continue;\n if (r.k === \"click\") stats.clicks++;\n else if (r.k === \"rage\") stats.rageClicks++;\n else if (r.k === \"dead\") stats.deadClicks++;\n else if (r.k === \"error\") stats.errors++;\n if (r.k === \"click\" || r.k === \"input\") {\n stats.activeMs += activeIncrement(last, r.ts);\n last = r.ts;\n }\n }\n this.recent = [];\n this.stats = stats;\n this.states.save({ ...this.state(), rid: this.env.uuid(), seq: 0, trigger: t, stats, stopped: undefined });\n this.mode = \"live\";\n this.log(\"recording:\", t);\n this.makeUploader();\n this.uploader!.addMany(events);\n if (!events.length) this.recorder?.snapshot();\n // Open the recording right away: short sessions that end soon after a trigger are the interesting ones.\n void this.uploader!.flush();\n }\n\n private stopRecording(reason: StopReason): void {\n this.log(\"recording stopped:\", reason);\n this.recorder?.stop();\n this.recorder = null;\n this.mode = \"off\";\n this.buffer = [];\n const s = this.state();\n this.states.save({ ...s, stopped: reason });\n }\n\n private onSignal(s: ReplayKitSignal): void {\n if (this.mode === \"live\" && this.stats) {\n if (s.type === \"rage_click\") this.stats.rageClicks++;\n else if (s.type === \"dead_click\") this.stats.deadClicks++;\n else if (s.type === \"error\") this.stats.errors++;\n } else if (this.mode === \"buffer\" || this.mode === \"idle\") {\n const k = s.type === \"rage_click\" ? \"rage\" : s.type === \"dead_click\" ? \"dead\" : s.type === \"error\" ? \"error\" : null;\n if (k) this.pushRecent(k, s.ts);\n }\n this.queue?.add(s);\n }\n\n private onInput(kind: \"click\" | \"key\" | \"scroll\", ts: number): void {\n if (this.mode === \"live\" && this.stats) {\n this.stats.activeMs += activeIncrement(this.lastInputTs, ts);\n if (kind === \"click\") this.stats.clicks++;\n } else if (this.mode === \"buffer\" || this.mode === \"idle\") {\n this.pushRecent(kind === \"click\" ? \"click\" : \"input\", ts);\n }\n this.lastInputTs = ts;\n }\n\n private pushRecent(k: \"click\" | \"rage\" | \"dead\" | \"error\" | \"input\", ts: number): void {\n this.recent.push({ k, ts });\n if (this.recent.length > 1000) this.recent.splice(0, this.recent.length - 1000);\n }\n\n private onNavigate(url: string): void {\n if (!this.init || !this.config) return;\n if (this.mode === \"live\" && this.stats) this.stats.pages++;\n const excluded = this.pathExcluded();\n if (excluded && (this.mode === \"live\" || this.mode === \"buffer\")) {\n // SPA route that must not be recorded: pause rrweb, keep the session's state.\n this.recorder?.stop();\n this.recorder = null;\n if (this.mode === \"buffer\") this.buffer = [];\n void this.uploader?.flush();\n this.mode = \"off\";\n return;\n }\n if (!excluded && this.mode === \"off\" && !this.state().stopped) {\n // Back from an excluded route: decide again (continues the recording or rebuffers).\n this.uploader = null;\n this.decide();\n return;\n }\n // Excluded routes never reach here: their URL is not written into the stream.\n this.recorder?.page(url);\n if (this.onCheckoutPath()) this.trigger(\"checkout\");\n }\n\n private listenPage(): void {\n const hide = (unloading: boolean) => {\n if (unloading) this.collector?.pageHide();\n // The next page of the session continues the minimum-duration count from here.\n this.states.save({ ...this.state(), visibleMs: this.visibleMs() });\n this.queue?.beacon();\n if (this.mode === \"live\") {\n this.saveStats();\n this.uploader?.persist();\n } else if (this.mode === \"buffer\" && this.buffer.length && this.env.store) {\n const events = trimBuffer(this.buffer, this.env.now());\n void this.env.store.set(bufferKey(this.ids!.sid), { at: this.env.now(), events } satisfies ParkedBuffer);\n }\n };\n const onVis = () => {\n if (document.visibilityState === \"hidden\") hide(false);\n else this.uploader?.unpersist();\n };\n const onHide = () => hide(true);\n document.addEventListener(\"visibilitychange\", onVis);\n window.addEventListener(\"pagehide\", onHide);\n this.offWindow.push(\n () => document.removeEventListener(\"visibilitychange\", onVis),\n () => window.removeEventListener(\"pagehide\", onHide),\n );\n }\n\n // ── Public API ────────────────────────────────────────────\n\n /** Start recording this session now (ReplayKit.start()). Still subject to /init, consent and excludePaths. */\n manualStart(reason?: string): void {\n if (!this.ids) return;\n if (reason) this.log(\"manual trigger:\", reason);\n if (this.state().stopped === \"manual\") {\n // Started again after ReplayKit.stop(): a new recording, decided like a fresh page.\n this.states.save({ ...this.state(), stopped: undefined, rid: undefined, seq: 0, trigger: undefined, stats: undefined });\n this.uploader = null;\n this.earlyTrigger = \"manual\";\n this.decide();\n return;\n }\n this.trigger(\"manual\");\n }\n\n /** Stop recording for the rest of the session; what was captured is still uploaded. */\n manualStop(): void {\n if (!this.ids) return;\n this.recorder?.stop();\n this.recorder = null;\n this.buffer = [];\n if (this.mode === \"live\") {\n this.saveStats();\n void this.uploader?.flush();\n }\n this.mode = \"off\";\n this.states.save({ ...this.state(), stopped: \"manual\" });\n }\n\n /** The visitor's answer to the customer's consent banner. Stored on this device. */\n consent(granted: boolean): void {\n this.env.setLocal(CONSENT_KEY, granted ? \"1\" : \"0\");\n if (!this.ids) return;\n if (granted) {\n if (this.mode === \"wait_consent\") this.decide();\n return;\n }\n // Withdrawn: stop now and drop everything not uploaded yet.\n this.recorder?.stop();\n this.recorder = null;\n this.buffer = [];\n this.uploader?.discard();\n void this.env.store?.del(bufferKey(this.ids.sid));\n this.mode = \"off\";\n }\n\n recordingId(): string | null {\n return this.mode === \"live\" ? (this.ids ? this.state().rid ?? null : null) : null;\n }\n\n private shutdown(): void {\n this.collector?.stop();\n this.queue?.disable();\n this.recorder?.stop();\n this.recorder = null;\n this.mode = \"off\";\n }\n\n destroy(): void {\n this.destroyed = true;\n this.shutdown();\n for (const f of this.offWindow) f();\n this.offWindow = [];\n }\n}\n","// Script-tag build: dist/replaykit.global.js.\n//\n// <script src=\"https://cdn.../replaykit.global.js\" data-api-key=\"hm_...\"></script>\n//\n// Exposes window.ReplayKit (same API as the npm entry) and initializes itself from\n// the data attributes of its own <script> tag. Without data-api-key it only exposes\n// the API, so the page can call ReplayKit.init({...}) itself. Load it after the\n// Himetrica tracker.\n\nimport * as ReplayKit from \"./index\";\n\ndeclare global {\n interface Window {\n ReplayKit?: typeof ReplayKit;\n }\n}\n\nif (typeof window !== \"undefined\") {\n window.ReplayKit = ReplayKit;\n const script = document.currentScript as HTMLScriptElement | null;\n const data = script?.dataset;\n if (data?.apiKey) {\n ReplayKit.init({\n apiKey: data.apiKey,\n apiUrl: data.apiUrl || undefined,\n allowLocalhost: data.allowLocalhost === \"true\",\n debug: data.debug === \"true\",\n });\n }\n}\n"],"mappings":"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","names":["getUntaintedPrototype","key","untaintedBasePrototype","defaultObj","defaultPrototype","accessorNames","testableAccessors","isUntaintedAccessors","accessor","_a","_b","methodNames","testableMethods","isUntaintedMethods","method","isAngularZonePresent","iframeEl","win","untaintedObject","ua","untaintedBaseIframeCleanup","e","getUntaintedAccessor","instance","cached","untaintedAccessorCache","untaintedPrototype","untaintedAccessor","getUntaintedMethod","cacheKey","untaintedMethodCache","untaintedMethod","ownerDocument","n","childNodes","parentNode","parentElement","textContent","firstChild","lastChild","nextSibling","previousSibling","contains","other","getRootNode","host","styleSheets","shadowRoot","querySelector","selectors","querySelectorAll","mutationObserverCtor","patch","source","name","replacement","original","wrapped","isElement","isShadowRoot","hostEl","dom","isNativeShadowDom","fixBrowserCompatibilityIssuesInCSS","cssText","escapeImportStatement","rule","statement","stringifyStylesheet","s","rules","sheetHref","stringifiedRules","stringifyRule","error","isCSSImportRule","importStringified","absolutifyURLs","ruleStringified","isCSSStyleRule","fixSafariColons","cssStringified","regex","createMirror","Mirror","maskInputValue","element","maskInputOptions","tagName","type","value","maskInputFn","text","actualType","toLowerCase","str","is2DCanvasBlank","canvas","ctx","chunkSize","x","y","getImageData","originalGetImageData","ORIGINAL_ATTRIBUTE_NAME","pixel","getInputType","extractFileExtension","path","baseURL","url","err","match","extractOrigin","origin","href","URL_IN_CSS_REF","quote1","path1","quote2","path2","path3","filePath","maybeQuote","URL_PROTOCOL_MATCH","URL_WWW_MATCH","DATA_URI","filePathNoHash","maybeHash","stack","parts","part","normalizeCssString","_testNoPxNorm","cssNormalizeReNoPx","cssNormalizeRe","splitCssText","style","splits","iterCount","cssTextNorm","normFactor","i","textContentNorm","jLimit","j","startSubstring","cssNormSplits","splitNorm","prevTextContent","prevMinLength","k","normPart","markCssSplits","genId","_id","getValidTagName","processedTagName","tagNameRegex","getAbsoluteSrcsetString","doc","attributeValue","pos","collectCharacters","regEx","chars","output","SRCSET_COMMAS_OR_SPACES","SRCSET_NOT_SPACES","absoluteToDoc","descriptorsStr","inParens","c","getHref","isSVGElement","el","customHref","a","cachedDocument","transformAttribute","ignoreAttribute","_value","_isBlockedElement","blockClass","blockSelector","eIndex","className","classMatchesRegex","node","checkAncestors","needMaskingText","maskTextClass","maskTextSelector","onceIframeLoaded","listener","iframeLoadTimeout","fired","readyState","timer","blankUrl","onceStylesheetLoaded","link","styleSheetLoadTimeout","styleSheetLoaded","serializeNode","options","mirror","needsMask","inlineStylesheet","maskTextFn","dataURLOptions","inlineImages","recordCanvas","keepIframeSrcFn","newlyAddedElement","cssCaptured","rootId","getRootId","NodeType","serializeElementNode","serializeTextNode","docId","parent","parentTagName","isStyle","isScript","needBlock","attributes","len","attr","stylesheet","checked","canvasDataURL","blankCanvas","blankCanvasDataURL","canvasService","canvasCtx","image","imageSrc","priorCrossOrigin","recordInlineImage","mediaAttributes","width","height","isCustomElement","lowerIfExists","maybeAttr","slimDOMDefaults","_slimDOMOptions","slimDOMExcluded","sn","slimDOMOptions","serializeNodeWithId","skipChild","onSerialize","onIframeLoad","onStylesheetLoad","stylesheetLoadTimeout","preserveWhiteSpace","_serializedNode","id","IGNORED_NODE","serializedNode","recordChild","shadowRootEl","bypassOptions","childN","serializedChildNode","iframeDoc","serializedIframeNode","serializedLinkNode","snapshot","maskAllInputs","slimDOM","on","fn","target","throttle","func","wait","timeout","previous","args","now","remaining","context","hookSetter","d","isRevoked","getWindowScroll","_c","_d","getWindowHeight","getWindowWidth","closestElementOfNode","isBlocked","isSerialized","isIgnored","isAncestorRemoved","legacy_isTouchEvent","event","polyfill","isSerializedIframe","isSerializedStylesheet","hasShadowRoot","BaseRRNode","getShadowHost","shadowHost","getRootShadowHost","rootShadowHost","shadowHostInDom","inDom","deepDelete","addsSet","processRemoves","cache","queue","next","isSelfOrAncestorInSet","set","_isSelfOrAncestorInSet","registerErrorHandler","handler","errorHandler","unregisterErrorHandler","getEventTarget","initMutationObserver","rootEl","mutationBuffer","MutationBuffer","mutationBuffers","ObserverCtor","iframeCleanup","observer","callbackWrapper","initMoveObserver","mousemoveCb","sampling","threshold","callbackThreshold","positions","timeBaseline","wrappedCb","totalOffset","p","updatePosition","evt","clientX","clientY","nowTimestamp","IncrementalSource","handlers","initMouseInteractionObserver","mouseInteractionCb","disableMap","currentPointerType","getHandler","eventKey","pointerType","thisEventKey","PointerTypes","MouseInteractions","__spreadValues","eventName","h","initScrollObserver","scrollCb","scrollLeftTop","initViewportResizeObserver","viewportResizeCb","lastH","lastW","updateDimension","initInputObserver","inputCb","ignoreClass","ignoreSelector","userTriggeredOnInput","eventHandler","userTriggered","INPUT_TAGS","isChecked","cbWithDedup","v","lastInputValue","lastInputValueMap","__spreadProps","currentWindow","propertyDescriptor","hookProperties","getNestedCSSRulePositions","recurse","childRule","hasNestedCSSRule","index","getIdAndStyleId","sheet","styleMirror","styleId","initStyleSheetObserver","styleSheetRuleCb","stylesheetManager","insertRule","thisArg","argumentsList","selector","styleBlock","deleteRule","replace","replaceSync","supportedNestedCSSRuleTypes","canMonkeyPatchNestedCSSRule","unmodifiedFunctions","typeKey","initAdoptedStyleSheetObserver","hostId","patchTarget","originalPropertyDescriptor","sheets","result","initStyleDeclarationObserver","styleDeclarationCb","ignoreCSSAttributes","setProperty","property","priority","removeProperty","initMediaInteractionObserver","mediaInteractionCb","currentTime","volume","muted","playbackRate","loop","MediaInteractions","initFontObserver","fontCb","fontMap","originalFontFace","family","descriptors","fontFace","restoreHandler","initSelectionObserver","param","selectionCb","collapsed","updateSelection","selection","ranges","count","range","startContainer","startOffset","endContainer","endOffset","initCustomElementObserver","customElementCb","constructor","mergeHooks","o","hooks","mutationCb","canvasMutationCb","initObservers","mutationObserver","cleanupMutationIframe","mousemoveHandler","mouseInteractionHandler","scrollHandler","viewportResizeHandler","inputHandler","mediaInteractionHandler","styleSheetObserver","adoptedStyleSheetObserver","styleDeclarationObserver","fontObserver","selectionObserver","customElementObserver","pluginHandlers","plugin","b","prop","variableListFor","ctor","contextMap","canvasVarMap","serializeArg","arg","base64","encode","src","isInstanceOfWebGLObject","saveWebGLVar","initCanvas2DMutationObserver","cb","props2D","recordArgs","serializeArgs","CanvasContext","hookHandler","getNormalizedContextName","contextType","initCanvasContextObserver","setPreserveDrawingBufferToTrue","ctxName","contextAttributes","patchGLPrototype","prototype","props","mutation","initCanvasWebGLMutationObserver","record","emit","checkoutEveryNms","checkoutEveryNth","_maskInputOptions","packFn","mousemoveWait","recordDOM","recordCrossOriginIframes","recordAfter","collectFonts","plugins","inEmittingFrame","passEmitsToParent","lastFullSnapshotEvent","incrementalSnapshotCount","eventProcessor","wrappedEmit","r","isCheckout","EventType","buf","message","exceedCount","exceedTime","takeFullSnapshot","wrappedMutationEmit","m","wrappedScrollEmit","wrappedCanvasMutationEmit","wrappedAdoptedStyleSheetEmit","StylesheetManager","iframeManager","IframeManager","processedNodeManager","ProcessedNodeManager","canvasManager","CanvasManager","shadowDomManager","ShadowDomManager","iframe","childSn","linkEl","observe","payload","init","recording","cssNormalizeBase","DEPARTED_MIRROR_ACCESS_WARNING","_mirror","StyleSheetMirror","moveKey","CrossOriginIframeMirror","lookup","EventType2","IncrementalSource2","MouseInteractions2","PointerTypes2","CanvasContext2","MediaInteractions2","NodeType2","__publicField","childNode","meta","oldNode","_BaseRRNode","_args","childIterator","_newChild","_refChild","_node","receiver","newId","parentId","mutations","adds","addedIds","ancestorBad","missingParents","iter","curr","parentTag","nextId","currentN","attribute","diffAsStr","unchangedAsStr","textarea","item","cn","tagNameLower","attributeName","old","pname","newValue","newPriority","nodeId","targetId","rest","generateIdFn","remoteId","idToRemoteMap","remoteToIdMap","idToRemoteIdMap","remoteIdToIdMap","map","ids","crossOriginMessageEvent","transformedEvent","iframeMirror","obj","keys","child","iframeElement","manager","option","sRoot","arraybuffer","bytes","list","fps","canvasContextReset","snapshotInProgressMap","worker","ImageBitmapDataURLWorker","timeBetweenSnapshots","lastSnapshotTime","rafId","getCanvas","matchedCanvas","takeCanvasSnapshots","timestamp","bitmap","canvas2DReset","canvasWebGL1and2Reset","setLatestRAFTimestamp","_values","valuesWithType","values","__objRest","adoptedStyleSheetData","styles","_linkEl","thisBuffer","buffers","buffer","cleanFrame","tag","src_exports","__export","consent","getRecordingId","init","shutdown","start","stop","trigger","KEY","StateStore","env","sid","_a","s","raw","e","emptyStats","now","entryUrl","isBrowser","uuidV4","c","ch","safeGet","storage","key","e","safeSet","value","indexedDbStore","dbp","open","resolve","reject","req","run","mode","fn","db","tx","s","gzipFn","text","browserEnv","originalFetch","nav","url","body","name","match","ms","h","readIdentity","env","visitorId","sessionId","matchPath","pattern","pathname","p","path","base","escapeRegExp","matchAny","patterns","s","sampleDraw","sessionId","h1","h2","i","ch","inSample","rate","stripUrl","href","cut","PAGE_TAG","pagesOf","events","prev","max","_a","_b","out","last","e","href","d","cut","url","BUFFER_WINDOW_MS","CHECKOUT_MS","snapshotStart","i","trimBuffer","now","windowMs","cutoff","keepFrom","firstSnapshot","start","approxBytes","RageDetector","c","b","near","finished","now","_a","_b","a","DEAD_CLICK_WAIT_MS","isDeadClickCandidate","f","isDeadClick","r","ACTIVE_GAP_MS","activeIncrement","lastInputTs","ts","gap","MIN_DURATION_EXEMPT","waitBeforeRecording","visibleMs","minDurationMs","decidePage","i","outcomeOf","status","Api","env","apiUrl","apiKey","op","body","_a","_b","url","blob","res","e","wantJson","outcome","BASE_BACKOFF_MS","MAX_BACKOFF_MS","backoff","failures","SIGNAL_FLUSH_MS","MAX_PER_PAGE","MAX_QUEUED","DEDUPE_MS","SignalQueue","env","api","ids","s","key","prev","enabled","ms","batch","__spreadProps","__spreadValues","backoff","INTERACTIVE","FIELD","MASKED","MAX_TEXT","MAX_DETAIL","selectorOf","el","parts","cur","depth","tag","classes","c","visibleText","maskAll","_a","_b","_c","t","targetFacts","pointer","e","sel","clickedElement","target","SignalCollector","h","RageDetector","on","type","fn","opts","now","r","nav","stripUrl","f","s","__spreadValues","href","prev","ts","selector","force","b","count","isDeadClickCandidate","hrefBefore","scrollBefore","focusBefore","mutations","mo","list","isDeadClick","DEAD_CLICK_WAIT_MS","message","detail","form","key","set","fields","BASE_BLOCK","BASE_MASK","recordFn","loadRecord","m","validSelectors","list","s","e","Recorder","o","_a","CHECKOUT_MS","href","PAGE_TAG","FLUSH_MS","FLUSH_BYTES","pendingKey","sid","Uploader","env","api","states","ids","hooks","store","p","s","e","approxBytes","events","ms","epoch","_a","_b","_c","gzip","file","blob","half","prevPage","pages","pagesOf","presign","put","cur","__spreadProps","__spreadValues","backoff","reason","CONSENT_KEY","bufferKey","sid","IDENTITY_POLL_MS","IDENTITY_WAIT_MS","INIT_ATTEMPTS","ReplayKitClient","options","env","browserEnv","apiUrl","Api","StateStore","args","isBrowser","host","started","tryIds","id","readIdentity","_a","ids","SignalQueue","__spreadProps","__spreadValues","SignalCollector","_b","s","t","kind","ts","url","attempt","r","stripUrl","backoff","res","v","matchAny","mode","decidePage","inSample","st","emptyStats","store","key","parked","BUFFER_WINDOW_MS","CHECKOUT_MS","_c","_d","rec","Recorder","e","trimBuffer","Uploader","reason","onVis","now","live","wait","waitBeforeRecording","gen","events","startedAt","stats","last","activeIncrement","k","excluded","hide","unloading","onHide","granted","f","client","init","options","ReplayKitClient","start","trigger","reason","stop","consent","granted","getRecordingId","_a","shutdown","src_exports","script","data","init"]}
|