posthog-js 1.396.2 → 1.396.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/dist/all-external-dependencies.js +1 -1
  2. package/dist/all-external-dependencies.js.map +1 -1
  3. package/dist/array.full.es5.js +1 -1
  4. package/dist/array.full.js +1 -1
  5. package/dist/array.full.js.map +1 -1
  6. package/dist/array.full.no-external.js +1 -1
  7. package/dist/array.full.no-external.js.map +1 -1
  8. package/dist/array.js +1 -1
  9. package/dist/array.no-external.js +1 -1
  10. package/dist/customizations.full.js +1 -1
  11. package/dist/default-extensions.js +1 -1
  12. package/dist/extension-bundles.js +1 -1
  13. package/dist/lazy-recorder.js +1 -1
  14. package/dist/main.js +1 -1
  15. package/dist/module.full.js +1 -1
  16. package/dist/module.full.js.map +1 -1
  17. package/dist/module.full.no-external.js +1 -1
  18. package/dist/module.full.no-external.js.map +1 -1
  19. package/dist/module.js +1 -1
  20. package/dist/module.no-external.js +1 -1
  21. package/dist/module.slim.js +1 -1
  22. package/dist/module.slim.no-external.js +1 -1
  23. package/dist/posthog-recorder.js +1 -1
  24. package/dist/product-tours.js +1 -1
  25. package/dist/src/entrypoints/web-vitals-with-attribution.d.ts +19 -0
  26. package/dist/src/entrypoints/web-vitals.d.ts +18 -0
  27. package/dist/surveys.js +1 -1
  28. package/dist/web-vitals-with-attribution.js +1 -1
  29. package/dist/web-vitals-with-attribution.js.map +1 -1
  30. package/dist/web-vitals.js +1 -1
  31. package/dist/web-vitals.js.map +1 -1
  32. package/lib/package.json +1 -1
  33. package/lib/src/entrypoints/web-vitals-with-attribution.d.ts +19 -0
  34. package/lib/src/entrypoints/web-vitals-with-attribution.js +3 -0
  35. package/lib/src/entrypoints/web-vitals-with-attribution.js.map +1 -1
  36. package/lib/src/entrypoints/web-vitals.d.ts +18 -0
  37. package/lib/src/entrypoints/web-vitals.js +3 -0
  38. package/lib/src/entrypoints/web-vitals.js.map +1 -1
  39. package/lib/src/utils/array-at-polyfill.d.ts +0 -0
  40. package/lib/src/utils/array-at-polyfill.js +33 -0
  41. package/lib/src/utils/array-at-polyfill.js.map +1 -0
  42. package/lib/tsconfig.tsbuildinfo +1 -1
  43. package/package.json +3 -3
@@ -1 +1 @@
1
- {"version":3,"file":"all-external-dependencies.js","sources":["../../rrweb/record/dist/rrweb-record.js","../../rrweb/plugins/rrweb-plugin-console-record/dist/rrweb-plugin-console-record.js","../../core/dist/types.mjs","../../core/dist/utils/string-utils.mjs","../../core/dist/utils/type-utils.mjs","../../core/dist/utils/user-agent-utils.mjs","../../core/dist/utils/index.mjs","../../core/dist/error-tracking/chunk-ids.mjs","../../core/dist/surveys/validation.mjs","../../core/dist/error-tracking/parsers/base.mjs","../../core/dist/error-tracking/parsers/safari.mjs","../../core/dist/error-tracking/parsers/chrome.mjs","../../core/dist/error-tracking/parsers/gecko.mjs","../../core/dist/error-tracking/parsers/index.mjs","../../core/dist/error-tracking/coercers/string-coercer.mjs","../../core/dist/error-tracking/types.mjs","../../core/dist/error-tracking/coercers/utils.mjs","../src/utils/globals.ts","../src/utils/type-utils.ts","../src/utils/logger.ts","../src/utils/index.ts","../src/utils/request-utils.ts","../src/extensions/replay/rrweb-plugins/patch.ts","../src/extensions/replay/external/denylist.ts","../src/constants.ts","../src/utils/element-utils.ts","../src/autocapture-utils.ts","../src/extensions/replay/external/config.ts","../src/extensions/replay/external/network-plugin.ts","../src/entrypoints/recorder.ts","../../../../../../setup-pnpm/node_modules/.bin/store/v11/links/@/preact/10.29.2/709c6912f2b0d7793dc053c28909b888bf8faab7b62175b401a5a5d6126a5d6e/node_modules/preact/dist/preact.module.js","../../../../../../setup-pnpm/node_modules/.bin/store/v11/links/@/preact/10.29.2/709c6912f2b0d7793dc053c28909b888bf8faab7b62175b401a5a5d6126a5d6e/node_modules/preact/hooks/dist/hooks.module.js","../src/posthog-surveys-types.ts","../../core/dist/surveys/events.mjs","../../core/dist/surveys/translations.mjs","../src/utils/survey-utils.ts","../src/uuidv7.ts","../src/utils/regex-utils.ts","../src/utils/property-utils.ts","../src/storage.ts","../src/extensions/utils/stylesheet-loader.ts","../src/extensions/surveys/surveys-extension-utils.tsx","../src/utils/url-targeting-utils.ts","../src/extensions/utils/matcher-utils.ts","../src/extensions/surveys/icons.tsx","../src/extensions/surveys/components/PostHogLogo.tsx","../src/extensions/surveys/components/BottomSection.tsx","../src/extensions/surveys/components/QuestionHeader.tsx","../src/extensions/surveys/components/ConfirmationMessage.tsx","../src/extensions/surveys/components/QuestionTypes.tsx","../src/utils/survey-branching.ts","../src/utils/survey-translations.ts","../src/utils/event-utils.ts","../src/extensions/surveys.tsx","../src/utils/survey-url-prefill.ts","../src/entrypoints/surveys.ts","../src/entrypoints/logs.ts","../src/posthog-exceptions.ts","../src/entrypoints/exception-autocapture.ts","../../core/dist/error-tracking/error-properties-builder.mjs","../../core/dist/error-tracking/coercers/dom-exception-coercer.mjs","../../core/dist/error-tracking/coercers/promise-rejection-event.mjs","../../core/dist/error-tracking/coercers/error-event-coercer.mjs","../../core/dist/error-tracking/coercers/error-coercer.mjs","../../core/dist/error-tracking/coercers/event-coercer.mjs","../../core/dist/error-tracking/coercers/object-coercer.mjs","../../core/dist/error-tracking/coercers/primitive-coercer.mjs","../src/entrypoints/tracing-headers.ts","../../../../../../setup-pnpm/node_modules/.bin/store/v11/links/@/web-vitals/5.3.0/120eca503d77c3b42026842da37a8f53d118236d4139208278d10bd5cf0a52ed/node_modules/web-vitals/dist/web-vitals.js","../src/entrypoints/web-vitals.ts","../src/autocapture.ts","../src/utils/prototype-utils.ts","../src/entrypoints/dead-clicks-autocapture.ts"],"sourcesContent":["var __defProp = Object.defineProperty;\nvar __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;\nvar __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== \"symbol\" ? key + \"\" : key, value);\nvar _a;\nvar 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 return EventType2;\n})(EventType || {});\nconst FullscreenCustomEventTag = \"rrweb/fullscreen\";\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 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 || {});\nconst testableAccessors = {\n Node: [\"childNodes\", \"parentNode\", \"parentElement\", \"textContent\"],\n ShadowRoot: [\"host\", \"styleSheets\"],\n Element: [\"shadowRoot\"],\n MutationObserver: []\n};\nconst testableMethods = {\n Node: [\"contains\", \"getRootNode\"],\n ShadowRoot: [\"getSelection\"],\n Element: [\"querySelector\", \"querySelectorAll\"],\n MutationObserver: [\"constructor\"]\n};\nconst untaintedBasePrototype = {};\nfunction angularZoneUnpatchedAlternative(key) {\n var _a2, _b;\n const angularUnpatchedVersionSymbol = (_b = (_a2 = globalThis == null ? void 0 : globalThis.Zone) == null ? void 0 : _a2.__symbol__) == null ? void 0 : _b.call(_a2, key);\n if (angularUnpatchedVersionSymbol && globalThis[angularUnpatchedVersionSymbol]) {\n return globalThis[angularUnpatchedVersionSymbol];\n } else {\n return void 0;\n }\n}\nfunction getUntaintedPrototype(key) {\n if (untaintedBasePrototype[key])\n return untaintedBasePrototype[key];\n const candidate = angularZoneUnpatchedAlternative(key) || globalThis[key];\n const defaultPrototype = candidate.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 _a2, _b;\n return Boolean(\n (_b = (_a2 = Object.getOwnPropertyDescriptor(defaultPrototype, accessor)) == null ? void 0 : _a2.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 _a2;\n return typeof defaultPrototype[method] === \"function\" && ((_a2 = defaultPrototype[method]) == null ? void 0 : _a2.toString().includes(\"[native code]\"));\n }\n )\n );\n if (isUntaintedAccessors && isUntaintedMethods) {\n untaintedBasePrototype[key] = candidate.prototype;\n return candidate.prototype;\n }\n const iframeEl = document.createElement(\"iframe\");\n try {\n document.body.appendChild(iframeEl);\n const win = iframeEl.contentWindow;\n if (!win) return candidate.prototype;\n const untaintedObject = win[key].prototype;\n if (!untaintedObject) return defaultPrototype;\n return untaintedBasePrototype[key] = untaintedObject;\n } catch {\n return defaultPrototype;\n } finally {\n if (iframeEl.parentNode) {\n document.body.removeChild(iframeEl);\n }\n }\n}\nconst untaintedAccessorCache = {};\nfunction getUntaintedAccessor(key, instance, accessor) {\n var _a2;\n const cacheKey = `${key}.${String(accessor)}`;\n if (untaintedAccessorCache[cacheKey])\n return untaintedAccessorCache[cacheKey].call(\n instance\n );\n const untaintedPrototype = getUntaintedPrototype(key);\n const untaintedAccessor = (_a2 = Object.getOwnPropertyDescriptor(\n untaintedPrototype,\n accessor\n )) == null ? void 0 : _a2.get;\n if (!untaintedAccessor) return instance[accessor];\n untaintedAccessorCache[cacheKey] = 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 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 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 getUntaintedMethod(\"Element\", n, \"querySelector\")(selectors);\n}\nfunction querySelectorAll(n, selectors) {\n return getUntaintedMethod(\"Element\", n, \"querySelectorAll\")(selectors);\n}\nfunction mutationObserverCtor() {\n return getUntaintedPrototype(\"MutationObserver\").constructor;\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 childNodes,\n parentNode,\n parentElement,\n textContent,\n contains,\n getRootNode,\n host,\n styleSheets,\n shadowRoot,\n querySelector,\n querySelectorAll,\n mutationObserver: mutationObserverCtor,\n patch\n};\nfunction isElement(n) {\n return n.nodeType === n.ELEMENT_NODE;\n}\nfunction isShadowRoot(n) {\n const hostEl = (\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 && index.host(n) || null\n );\n return Boolean(\n hostEl && \"shadowRoot\" in hostEl && index.shadowRoot(hostEl) === n\n );\n}\nfunction isNativeShadowDom(shadowRoot2) {\n return Object.prototype.toString.call(shadowRoot2) === \"[object ShadowRoot]\";\n}\nfunction fixBrowserCompatibilityIssuesInCSS(cssText) {\n if (cssText.includes(\" background-clip: text;\") && !cssText.includes(\" -webkit-background-clip: text;\")) {\n cssText = cssText.replace(\n /\\sbackground-clip:\\s*text;/g,\n \" -webkit-background-clip: text; background-clip: text;\"\n );\n }\n return cssText;\n}\nfunction escapeImportStatement(rule) {\n const { cssText } = rule;\n if (cssText.split('\"').length < 3) return cssText;\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}\nfunction hasEmptyShorthandLonghand(css) {\n return /(?:^|[\\s;{}])-?[a-zA-Z][\\w-]*\\s*:\\s*;/.test(css);\n}\nfunction stringifyStylesheet(s) {\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 sheetHref = s.ownerNode.baseURI;\n }\n const stringifiedRules = Array.from(\n rules,\n (rule) => stringifyRule(rule, sheetHref)\n ).join(\"\");\n return fixBrowserCompatibilityIssuesInCSS(stringifiedRules);\n } catch (error) {\n return null;\n }\n}\nfunction stringifyRule(rule, sheetHref) {\n var _a2;\n if (isCSSImportRule(rule)) {\n let importStringified;\n try {\n importStringified = // for same-origin stylesheets,\n // we can access the imported stylesheet rules directly\n stringifyStylesheet(rule.styleSheet) || // work around browser issues with the raw string `@import url(...)` statement\n escapeImportStatement(rule);\n } catch (error) {\n importStringified = rule.cssText;\n }\n try {\n if (importStringified && ((_a2 = rule.styleSheet) == null ? void 0 : _a2.href)) {\n return absolutifyURLs(importStringified, rule.styleSheet.href);\n }\n } catch {\n }\n return importStringified;\n } else {\n let ruleStringified = rule.cssText;\n if (isCSSStyleRule(rule) && rule.selectorText.includes(\":\")) {\n ruleStringified = fixSafariColons(ruleStringified);\n }\n if (sheetHref) {\n return absolutifyURLs(ruleStringified, sheetHref);\n }\n return ruleStringified;\n }\n}\nfunction fixSafariColons(cssStringified) {\n const regex = /(\\[(?:[\\w-]+)[^\\\\])(:(?:[\\w-]+)\\])/gm;\n return cssStringified.replace(regex, \"$1\\\\$2\");\n}\nfunction isCSSImportRule(rule) {\n return \"styleSheet\" in rule;\n}\nfunction isCSSStyleRule(rule) {\n return \"selectorText\" in rule;\n}\nclass Mirror {\n constructor() {\n __publicField(this, \"idNodeMap\", /* @__PURE__ */ new Map());\n __publicField(this, \"nodeMetaMap\", /* @__PURE__ */ new WeakMap());\n }\n getId(n) {\n var _a2;\n if (!n) return -1;\n const id = (_a2 = this.getMeta(n)) == null ? void 0 : _a2.id;\n return id ?? -1;\n }\n getNode(id) {\n return this.idNodeMap.get(id) || null;\n }\n getIds() {\n return Array.from(this.idNodeMap.keys());\n }\n getMeta(n) {\n return this.nodeMetaMap.get(n) || null;\n }\n // removes the node from idNodeMap\n // doesn't remove the node from nodeMetaMap\n removeNodeFromMap(n) {\n const id = this.getId(n);\n this.idNodeMap.delete(id);\n if (n.childNodes) {\n n.childNodes.forEach(\n (childNode) => this.removeNodeFromMap(childNode)\n );\n }\n if (isElement(n)) {\n const shadowRootEl = index.shadowRoot(n);\n if (shadowRootEl) {\n this.removeNodeFromMap(shadowRootEl);\n }\n if (n.nodeName === \"IFRAME\" && n.contentDocument) {\n this.removeNodeFromMap(\n n.contentDocument\n );\n }\n }\n }\n has(id) {\n return this.idNodeMap.has(id);\n }\n hasNode(node) {\n return this.nodeMetaMap.has(node);\n }\n add(n, meta) {\n const id = meta.id;\n this.idNodeMap.set(id, n);\n this.nodeMetaMap.set(n, meta);\n }\n replace(id, n) {\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 reset() {\n this.idNodeMap = /* @__PURE__ */ new Map();\n this.nodeMetaMap = /* @__PURE__ */ new WeakMap();\n }\n}\nfunction createMirror() {\n return new Mirror();\n}\nfunction maskInputValue({\n element,\n maskInputOptions,\n tagName,\n type,\n value,\n maskInputFn\n}) {\n let text = value || \"\";\n const actualType = type && toLowerCase(type);\n if (maskInputOptions[tagName.toLowerCase()] || actualType && maskInputOptions[actualType]) {\n if (maskInputFn) {\n text = maskInputFn(text, element);\n } else {\n text = \"*\".repeat(text.length);\n }\n }\n return text;\n}\nfunction toLowerCase(str) {\n return str.toLowerCase();\n}\nconst ORIGINAL_ATTRIBUTE_NAME = \"__rrweb_original__\";\nfunction is2DCanvasBlank(canvas) {\n const ctx = canvas.getContext(\"2d\");\n if (!ctx) return true;\n const chunkSize = 50;\n for (let x = 0; x < canvas.width; x += chunkSize) {\n for (let y = 0; y < canvas.height; y += chunkSize) {\n const getImageData = ctx.getImageData;\n const originalGetImageData = ORIGINAL_ATTRIBUTE_NAME in getImageData ? getImageData[ORIGINAL_ATTRIBUTE_NAME] : getImageData;\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}\nfunction getInputType(element) {\n const type = element.type;\n return element.hasAttribute(\"data-rr-is-password\") ? \"password\" : type ? (\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion\n toLowerCase(type)\n ) : null;\n}\nfunction extractFileExtension(path, baseURL) {\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 == null ? void 0 : match[1]) ?? null;\n}\nfunction extractOrigin(url) {\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}\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;\nfunction absolutifyURLs(cssText, href) {\n return (cssText || \"\").replace(\n URL_IN_CSS_REF,\n (origin, quote1, path1, quote2, path2, path3) => {\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}${extractOrigin(href) + filePath}${maybeQuote})`;\n }\n const stack = href.split(\"/\");\n const parts = filePath.split(\"/\");\n stack.pop();\n for (const part of parts) {\n if (part === \".\") {\n continue;\n } else if (part === \"..\") {\n stack.pop();\n } else {\n stack.push(part);\n }\n }\n return `url(${maybeQuote}${stack.join(\"/\")}${maybeQuote})`;\n }\n );\n}\nconst STRIPED_PLACEHOLDER_SVG = \"data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgogIDxkZWZzPgogICAgPHBhdHRlcm4gaWQ9InN0cmlwZXMiIHBhdHRlcm5Vbml0cz0idXNlclNwYWNlT25Vc2UiIHdpZHRoPSIxNiIgaGVpZ2h0PSIxNiI+CiAgICAgIDxyZWN0IHdpZHRoPSIxNiIgaGVpZ2h0PSIxNiIgZmlsbD0iYmxhY2siLz4KICAgICAgPHBhdGggZD0iTTggMEgxNkwwIDE2VjhMOCAwWiIgZmlsbD0iIzJEMkQyRCIvPgogICAgICA8cGF0aCBkPSJNMTYgOFYxNkg4TDE2IDhaIiBmaWxsPSIjMkQyRDJEIi8+CiAgICA8L3BhdHRlcm4+CiAgPC9kZWZzPgogIDxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjc3RyaXBlcykiLz4KPC9zdmc+Cg==\";\nconst MAX_IMAGE_DIMENSION_FOR_RECOMPRESSION = 4096;\nfunction recompressBase64Image(img, dataURL, type, quality) {\n if (!img.complete || img.naturalWidth === 0) {\n return dataURL;\n }\n if (img.naturalWidth > MAX_IMAGE_DIMENSION_FOR_RECOMPRESSION || img.naturalHeight > MAX_IMAGE_DIMENSION_FOR_RECOMPRESSION) {\n return dataURL;\n }\n try {\n const canvas = document.createElement(\"canvas\");\n canvas.width = img.naturalWidth;\n canvas.height = img.naturalHeight;\n const ctx = canvas.getContext(\"2d\");\n if (!ctx) {\n return dataURL;\n }\n ctx.drawImage(img, 0, 0);\n const recompressed = canvas.toDataURL(type || \"image/webp\", quality ?? 0.4);\n return recompressed;\n } catch (err) {\n return dataURL;\n }\n}\nfunction checkDataURLSize(dataURL, maxLength) {\n if (!maxLength || dataURL.length <= maxLength) {\n return dataURL;\n }\n return STRIPED_PLACEHOLDER_SVG;\n}\nlet _id = 1;\nconst tagNameRegex = new RegExp(\"[^a-z0-9-_:]\");\nconst IGNORED_NODE = -2;\nfunction genId() {\n return _id++;\n}\nfunction getValidTagName(element) {\n if (element instanceof HTMLFormElement) {\n return \"form\";\n }\n const processedTagName = toLowerCase(element.tagName);\n if (tagNameRegex.test(processedTagName)) {\n return \"div\";\n }\n return processedTagName;\n}\nlet canvasService;\nlet canvasCtx;\nconst SRCSET_NOT_SPACES = /^[^ \\t\\n\\r\\u000c]+/;\nconst SRCSET_COMMAS_OR_SPACES = /^[, \\t\\n\\r\\u000c]+/;\nfunction getAbsoluteSrcsetString(doc, attributeValue) {\n if (attributeValue.trim() === \"\") {\n return attributeValue;\n }\n let pos = 0;\n function collectCharacters(regEx) {\n let chars2;\n const match = regEx.exec(attributeValue.substring(pos));\n if (match) {\n chars2 = match[0];\n pos += chars2.length;\n return chars2;\n }\n return \"\";\n }\n const output = [];\n while (true) {\n collectCharacters(SRCSET_COMMAS_OR_SPACES);\n if (pos >= attributeValue.length) {\n break;\n }\n let url = collectCharacters(SRCSET_NOT_SPACES);\n if (url.slice(-1) === \",\") {\n url = absoluteToDoc(doc, url.substring(0, url.length - 1));\n output.push(url);\n } else {\n let descriptorsStr = \"\";\n url = absoluteToDoc(doc, url);\n let inParens = false;\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;\n } else if (c === \"(\") {\n inParens = true;\n }\n } else {\n if (c === \")\") {\n inParens = false;\n }\n }\n descriptorsStr += c;\n pos += 1;\n }\n }\n }\n return output.join(\", \");\n}\nconst cachedDocument = /* @__PURE__ */ new WeakMap();\nfunction absoluteToDoc(doc, attributeValue) {\n if (!attributeValue || attributeValue.trim() === \"\") {\n return attributeValue;\n }\n return getHref(doc, attributeValue);\n}\nfunction isSVGElement(el) {\n return Boolean(el.tagName === \"svg\" || el.ownerSVGElement);\n}\nfunction getHref(doc, customHref) {\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 a.setAttribute(\"href\", customHref);\n return a.href;\n}\nfunction capDataURLSize(dataURL, dataURLOptions) {\n if (dataURLOptions == null ? void 0 : dataURLOptions.maxBase64ImageLength) {\n return checkDataURLSize(dataURL, dataURLOptions.maxBase64ImageLength);\n }\n return dataURL;\n}\nfunction transformAttribute(doc, tagName, name, value, element, dataURLOptions) {\n var _a2;\n if (!value) {\n return value;\n }\n if (name === \"src\" || name === \"href\" && !(tagName === \"use\" && value[0] === \"#\")) {\n if (tagName === \"link\" && element) {\n const sheetHref = (_a2 = element.sheet) == null ? void 0 : _a2.href;\n if (sheetHref) {\n return sheetHref;\n }\n }\n const transformedValue = absoluteToDoc(doc, value);\n if (transformedValue.startsWith(\"data:\")) {\n if (tagName === \"img\" && element) {\n let processedDataURL = transformedValue;\n if ((dataURLOptions == null ? void 0 : dataURLOptions.type) || (dataURLOptions == null ? void 0 : dataURLOptions.quality) !== void 0) {\n processedDataURL = recompressBase64Image(\n element,\n transformedValue,\n dataURLOptions.type,\n dataURLOptions.quality\n );\n }\n return capDataURLSize(processedDataURL, dataURLOptions);\n }\n if (tagName === \"image\") {\n return capDataURLSize(transformedValue, dataURLOptions);\n }\n }\n return transformedValue;\n } else if (name === \"xlink:href\" && value[0] !== \"#\") {\n const transformedValue = absoluteToDoc(doc, value);\n if (tagName === \"image\" && transformedValue.startsWith(\"data:\")) {\n return capDataURLSize(transformedValue, dataURLOptions);\n }\n return transformedValue;\n } else if (name === \"background\" && (tagName === \"table\" || tagName === \"td\" || tagName === \"th\")) {\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 return value;\n}\nfunction ignoreAttribute(tagName, name, _value) {\n return (tagName === \"video\" || tagName === \"audio\") && name === \"autoplay\";\n}\nfunction _isBlockedElement(element, blockClass, blockSelector) {\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 return false;\n}\nfunction classMatchesRegex(node, regex, checkAncestors) {\n if (!node) return false;\n if (node.nodeType !== node.ELEMENT_NODE) {\n if (!checkAncestors) return false;\n return classMatchesRegex(index.parentNode(node), regex, checkAncestors);\n }\n for (let eIndex = node.classList.length; eIndex--; ) {\n const className = node.classList[eIndex];\n if (regex.test(className)) {\n return true;\n }\n }\n if (!checkAncestors) return false;\n return classMatchesRegex(index.parentNode(node), regex, checkAncestors);\n}\nfunction needMaskingText(node, maskTextClass, maskTextSelector, checkAncestors) {\n let el;\n if (isElement(node)) {\n el = node;\n if (!index.childNodes(el).length) {\n return false;\n }\n } else if (index.parentElement(node) === null) {\n return false;\n } else {\n el = index.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 return false;\n}\nfunction onceIframeLoaded(iframeEl, listener, iframeLoadTimeout) {\n const noop = () => {\n };\n const win = iframeEl.contentWindow;\n if (!win) {\n return noop;\n }\n let readyState;\n try {\n readyState = win.document.readyState;\n } catch (error) {\n return noop;\n }\n const onSubsequentLoad = () => listener();\n if (readyState !== \"complete\") {\n let fired = false;\n let timer = null;\n const fireOnce = () => {\n if (fired) return;\n fired = true;\n if (timer !== null) {\n clearTimeout(timer);\n timer = null;\n }\n iframeEl.removeEventListener(\"load\", onInitialLoad);\n iframeEl.addEventListener(\"load\", onSubsequentLoad);\n listener();\n };\n const onInitialLoad = () => fireOnce();\n timer = setTimeout(fireOnce, iframeLoadTimeout);\n iframeEl.addEventListener(\"load\", onInitialLoad);\n return () => {\n if (timer !== null) {\n clearTimeout(timer);\n timer = null;\n }\n if (fired) {\n iframeEl.removeEventListener(\"load\", onSubsequentLoad);\n } else {\n fired = true;\n iframeEl.removeEventListener(\"load\", onInitialLoad);\n }\n };\n }\n const blankUrl = \"about:blank\";\n let winLocationHref;\n try {\n winLocationHref = win.location.href;\n } catch {\n return noop;\n }\n if (winLocationHref !== blankUrl || iframeEl.src === blankUrl || iframeEl.src === \"\") {\n const initialTimer = setTimeout(listener, 0);\n iframeEl.addEventListener(\"load\", onSubsequentLoad);\n return () => {\n clearTimeout(initialTimer);\n iframeEl.removeEventListener(\"load\", onSubsequentLoad);\n };\n }\n iframeEl.addEventListener(\"load\", onSubsequentLoad);\n return () => {\n iframeEl.removeEventListener(\"load\", onSubsequentLoad);\n };\n}\nconst stylesheetLoadTracked = /* @__PURE__ */ new Map();\nfunction resetStylesheetLoadTracking() {\n stylesheetLoadTracked.forEach((controller) => controller.abort());\n stylesheetLoadTracked.clear();\n}\nfunction onceStylesheetLoaded(link, listener, styleSheetLoadTimeout) {\n if (stylesheetLoadTracked.has(link)) return;\n let styleSheetLoaded;\n try {\n styleSheetLoaded = link.sheet;\n } catch (error) {\n return;\n }\n if (styleSheetLoaded) return;\n const controller = new AbortController();\n let fired = false;\n const fire = () => {\n if (fired) return;\n fired = true;\n try {\n listener();\n } finally {\n stylesheetLoadTracked.delete(link);\n controller.abort();\n }\n };\n const timer = setTimeout(fire, styleSheetLoadTimeout);\n controller.signal.addEventListener(\"abort\", () => clearTimeout(timer), {\n once: true\n });\n link.addEventListener(\"load\", fire, {\n signal: controller.signal,\n once: true\n });\n stylesheetLoadTracked.set(link, controller);\n}\nfunction serializeNode(n, options) {\n const {\n doc,\n mirror: mirror2,\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 } = options;\n const rootId = getRootId(doc, mirror2);\n switch (n.nodeType) {\n case n.DOCUMENT_NODE:\n if (n.compatMode !== \"CSS1Compat\") {\n return {\n type: NodeType.Document,\n childNodes: [],\n compatMode: n.compatMode\n // 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.name,\n publicId: n.publicId,\n systemId: n.systemId,\n rootId\n };\n case n.ELEMENT_NODE:\n return serializeElementNode(n, {\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, {\n doc,\n needsMask,\n maskTextFn,\n rootId\n });\n case n.CDATA_SECTION_NODE:\n return {\n type: NodeType.CDATA,\n textContent: \"\",\n rootId\n };\n case n.COMMENT_NODE:\n return {\n type: NodeType.Comment,\n textContent: index.textContent(n) || \"\",\n rootId\n };\n default:\n return false;\n }\n}\nfunction getRootId(doc, mirror2) {\n if (!mirror2.hasNode(doc)) return void 0;\n const docId = mirror2.getId(doc);\n return docId === 1 ? void 0 : docId;\n}\nfunction serializeTextNode(n, options) {\n var _a2;\n const { needsMask, maskTextFn, rootId } = options;\n const parent = index.parentNode(n);\n const parentTagName = parent && parent.tagName;\n let text = index.textContent(n);\n const isStyle = parentTagName === \"STYLE\" ? true : void 0;\n const isScript = parentTagName === \"SCRIPT\" ? true : void 0;\n if (isStyle && text) {\n try {\n if (n.nextSibling || n.previousSibling) {\n } else if ((_a2 = parent.sheet) == null ? void 0 : _a2.cssRules) {\n const stringified = stringifyStylesheet(\n parent.sheet\n );\n if (stringified && !hasEmptyShorthandLonghand(stringified)) {\n text = stringified;\n }\n }\n } catch (err) {\n console.warn(\n `Cannot get CSS styles from text's parentNode. Error: ${err}`,\n n\n );\n }\n text = absolutifyURLs(text, getHref(options.doc));\n }\n if (isScript) {\n text = \"SCRIPT_PLACEHOLDER\";\n }\n if (!isStyle && !isScript && text && needsMask) {\n text = maskTextFn ? maskTextFn(text, index.parentElement(n)) : text.replace(/[\\S]/g, \"*\");\n }\n return {\n type: NodeType.Text,\n textContent: text || \"\",\n isStyle,\n rootId\n };\n}\nfunction findStylesheet(doc, href) {\n return Array.from(doc.styleSheets).find((s) => s.href === href);\n}\nfunction hrefFrom(n) {\n return n.href;\n}\nfunction serializeElementNode(n, options) {\n var _a2, _b, _c;\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 = {};\n const len = n.attributes.length;\n for (let i = 0; i < len; i++) {\n const attr = n.attributes[i];\n if (!ignoreAttribute(tagName, attr.name, attr.value)) {\n attributes[attr.name] = transformAttribute(\n doc,\n tagName,\n toLowerCase(attr.name),\n attr.value,\n n,\n dataURLOptions\n );\n }\n }\n if (tagName === \"link\" && inlineStylesheet) {\n let stylesheet = n.sheet;\n if (!stylesheet) {\n const href = hrefFrom(n);\n if (href) {\n stylesheet = findStylesheet(doc, href);\n if (!stylesheet && href.includes(\".css\")) {\n const rootDomain = window.location.origin;\n const stylesheetPath = href.replace(window.location.href, \"\");\n const potentialStylesheetHref = rootDomain + \"/\" + stylesheetPath;\n stylesheet = findStylesheet(doc, potentialStylesheetHref);\n }\n }\n }\n let cssText = 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.sheet && // TODO: Currently we only try to get dynamic stylesheet when it is an empty style element\n !(n.innerText || index.textContent(n) || \"\").trim().length) {\n const cssText = stringifyStylesheet(\n n.sheet\n );\n if (cssText) {\n attributes._cssText = cssText;\n }\n }\n if (tagName === \"input\" || tagName === \"textarea\" || tagName === \"select\") {\n const value = n.value;\n const checked = n.checked;\n if (attributes.type !== \"radio\" && attributes.type !== \"checkbox\" && attributes.type !== \"submit\" && attributes.type !== \"button\" && value) {\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.selected && !maskInputOptions[\"select\"]) {\n attributes.selected = true;\n } else {\n delete attributes.selected;\n }\n }\n if (tagName === \"dialog\" && n.open) {\n try {\n attributes.rr_open_mode = n.matches(\"dialog:modal\") ? \"modal\" : \"non-modal\";\n } catch {\n attributes.rr_open_mode = \"modal\";\n attributes.ph_rr_could_not_detect_modal = true;\n }\n }\n if (tagName === \"canvas\" && recordCanvas) {\n if (n.__context === \"2d\") {\n if (!is2DCanvasBlank(n)) {\n attributes.rr_dataURL = n.toDataURL(\n dataURLOptions.type,\n dataURLOptions.quality\n );\n }\n } else if (!(\"__context\" in n)) {\n const canvasDataURL = n.toDataURL(\n dataURLOptions.type,\n dataURLOptions.quality\n );\n const blankCanvas = doc.createElement(\"canvas\");\n blankCanvas.width = n.width;\n blankCanvas.height = n.height;\n const blankCanvasDataURL = blankCanvas.toDataURL(\n dataURLOptions.type,\n dataURLOptions.quality\n );\n if (canvasDataURL !== blankCanvasDataURL) {\n attributes.rr_dataURL = canvasDataURL;\n }\n }\n }\n if (tagName === \"img\" && inlineImages) {\n if (!canvasService) {\n canvasService = doc.createElement(\"canvas\");\n canvasCtx = canvasService.getContext(\"2d\");\n }\n const image = n;\n const imageSrc = 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();\n else image.addEventListener(\"load\", recordInlineImage);\n return;\n } else {\n console.warn(\n `Cannot inline img src=${imageSrc}! Error: ${err}`\n );\n }\n }\n if (image.crossOrigin === \"anonymous\") {\n priorCrossOrigin ? attributes.crossOrigin = priorCrossOrigin : image.removeAttribute(\"crossorigin\");\n }\n };\n if (image.complete && image.naturalWidth !== 0) recordInlineImage();\n else image.addEventListener(\"load\", recordInlineImage);\n }\n if (tagName === \"audio\" || tagName === \"video\") {\n const mediaAttributes = attributes;\n mediaAttributes.rr_mediaState = n.paused ? \"paused\" : \"played\";\n mediaAttributes.rr_mediaCurrentTime = n.currentTime;\n mediaAttributes.rr_mediaPlaybackRate = n.playbackRate;\n mediaAttributes.rr_mediaMuted = n.muted;\n mediaAttributes.rr_mediaLoop = n.loop;\n mediaAttributes.rr_mediaVolume = n.volume;\n }\n if (!newlyAddedElement) {\n if (n.scrollLeft) {\n attributes.rr_scrollLeft = n.scrollLeft;\n }\n if (n.scrollTop) {\n attributes.rr_scrollTop = n.scrollTop;\n }\n }\n if (needBlock) {\n const { width, height, left, top } = n.getBoundingClientRect();\n const computed = (_a2 = doc.defaultView) == null ? void 0 : _a2.getComputedStyle(n);\n attributes = {\n class: attributes.class,\n rr_width: `${width}px`,\n rr_height: `${height}px`,\n rr_left: `${Math.floor(left + (((_b = doc.defaultView) == null ? void 0 : _b.scrollX) || 0))}px`,\n rr_top: `${Math.floor(top + (((_c = doc.defaultView) == null ? void 0 : _c.scrollY) || 0))}px`\n };\n if (computed) {\n attributes.rr_position = computed.position || \"static\";\n if (computed.transform && computed.transform !== \"none\") {\n attributes.rr_transform = computed.transform;\n }\n if (computed.display && computed.display.startsWith(\"inline\")) {\n attributes.rr_display = computed.display;\n }\n }\n }\n if (tagName === \"iframe\" && !keepIframeSrcFn(attributes.src)) {\n if (!n.contentDocument) {\n attributes.rr_src = attributes.src;\n }\n delete attributes.src;\n }\n let isCustomElement;\n try {\n if (customElements.get(tagName)) isCustomElement = true;\n } catch (e) {\n }\n return {\n type: NodeType.Element,\n tagName,\n attributes,\n childNodes: [],\n isSVG: isSVGElement(n) || void 0,\n needBlock,\n rootId,\n isCustom: isCustomElement\n };\n}\nfunction lowerIfExists(maybeAttr) {\n if (maybeAttr === void 0 || maybeAttr === null) {\n return \"\";\n } else {\n return maybeAttr.toLowerCase();\n }\n}\nfunction slimDOMExcluded(sn, slimDOMOptions) {\n if (slimDOMOptions.comment && sn.type === NodeType.Comment) {\n return true;\n } else if (sn.type === NodeType.Element) {\n if (slimDOMOptions.script && // script tag\n (sn.tagName === \"script\" || // (module)preload link\n sn.tagName === \"link\" && (sn.attributes.rel === \"preload\" && sn.attributes.as === \"script\" || sn.attributes.rel === \"modulepreload\") || // prefetch link\n sn.tagName === \"link\" && sn.attributes.rel === \"prefetch\" && typeof sn.attributes.href === \"string\" && extractFileExtension(sn.attributes.href) === \"js\")) {\n return true;\n } else if (slimDOMOptions.headFavicon && (sn.tagName === \"link\" && sn.attributes.rel === \"shortcut icon\" || sn.tagName === \"meta\" && (lowerIfExists(sn.attributes.name).match(\n /^msapplication-tile(image|color)$/\n ) || lowerIfExists(sn.attributes.name) === \"application-name\" || [\"icon\", \"apple-touch-icon\", \"shortcut icon\"].includes(\n lowerIfExists(sn.attributes.rel)\n )))) {\n return true;\n } else if (sn.tagName === \"meta\") {\n if (slimDOMOptions.headMetaDescKeywords && lowerIfExists(sn.attributes.name).match(/^description|keywords$/)) {\n return true;\n } else if (slimDOMOptions.headMetaSocial && (lowerIfExists(sn.attributes.property).match(/^(og|twitter|fb):/) || // og = opengraph (facebook)\n lowerIfExists(sn.attributes.name).match(/^(og|twitter):/) || lowerIfExists(sn.attributes.name) === \"pinterest\")) {\n return true;\n } else if (slimDOMOptions.headMetaRobots && [\"robots\", \"googlebot\", \"bingbot\"].includes(\n lowerIfExists(sn.attributes.name)\n )) {\n return true;\n } else if (slimDOMOptions.headMetaHttpEquiv && sn.attributes[\"http-equiv\"] !== void 0) {\n return true;\n } else if (slimDOMOptions.headMetaAuthorship && ([\"author\", \"generator\", \"framework\", \"publisher\", \"progid\"].includes(\n lowerIfExists(sn.attributes.name)\n ) || lowerIfExists(sn.attributes.property).match(/^article:/) || lowerIfExists(sn.attributes.property).match(/^product:/))) {\n return true;\n } else if (slimDOMOptions.headMetaVerification && [\n \"google-site-verification\",\n \"yandex-verification\",\n \"csrf-token\",\n \"p:domain_verify\",\n \"verify-v1\",\n \"verification\",\n \"shopify-checkout-api-token\"\n ].includes(lowerIfExists(sn.attributes.name))) {\n return true;\n }\n }\n }\n return false;\n}\nconst DEFAULT_MAX_DEPTH = 50;\nlet _maxDepthWarned = false;\nlet _maxDepthReached = false;\nfunction wasMaxDepthReached() {\n return _maxDepthReached;\n}\nfunction resetMaxDepthState() {\n _maxDepthReached = false;\n _maxDepthWarned = false;\n}\nfunction serializeNodeWithId(n, options) {\n const {\n doc,\n mirror: mirror2,\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 = 5e3,\n onIframeListenerRegistered,\n onStylesheetLoad,\n stylesheetLoadTimeout = 5e3,\n keepIframeSrcFn = () => false,\n newlyAddedElement = false,\n depth = 0,\n maxDepth = DEFAULT_MAX_DEPTH\n } = options;\n let { needsMask } = options;\n let { preserveWhiteSpace = true } = options;\n if (depth >= maxDepth) {\n _maxDepthReached = true;\n if (!_maxDepthWarned) {\n _maxDepthWarned = true;\n console.warn(\n `[rrweb-snapshot] DOM tree depth exceeded max depth of ${maxDepth}. Children beyond this depth will not be recorded. This may indicate deeply nested DOM structures.`\n );\n }\n return null;\n }\n if (!needsMask) {\n const checkAncestors = needsMask === void 0;\n needsMask = needMaskingText(\n n,\n maskTextClass,\n maskTextSelector,\n checkAncestors\n );\n }\n const _serializedNode = serializeNode(n, {\n doc,\n mirror: mirror2,\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 });\n if (!_serializedNode) {\n console.warn(n, \"not serialized\");\n return null;\n }\n let id;\n if (mirror2.hasNode(n)) {\n id = mirror2.getId(n);\n } else if (slimDOMExcluded(_serializedNode, slimDOMOptions) || !preserveWhiteSpace && _serializedNode.type === NodeType.Text && !_serializedNode.isStyle && // codeql[js/polynomial-redos] Bounded DOM text node; worst case is recorder slowdown, no exploit.\n !_serializedNode.textContent.replace(/^\\s+|\\s+$/gm, \"\").length) {\n id = IGNORED_NODE;\n } else {\n id = genId();\n }\n const serializedNode = Object.assign(_serializedNode, { id });\n mirror2.add(n, serializedNode);\n if (id === IGNORED_NODE) {\n return null;\n }\n if (onSerialize) {\n onSerialize(n);\n }\n let recordChild = !skipChild;\n if (serializedNode.type === NodeType.Element) {\n recordChild = recordChild && !serializedNode.needBlock;\n delete serializedNode.needBlock;\n const shadowRootEl = index.shadowRoot(n);\n if (shadowRootEl && isNativeShadowDom(shadowRootEl))\n serializedNode.isShadowHost = true;\n }\n if ((serializedNode.type === NodeType.Document || serializedNode.type === NodeType.Element) && recordChild) {\n if (slimDOMOptions.headWhitespace && serializedNode.type === NodeType.Element && serializedNode.tagName === \"head\") {\n preserveWhiteSpace = false;\n }\n const bypassOptions = {\n doc,\n mirror: mirror2,\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 onIframeListenerRegistered,\n onStylesheetLoad,\n stylesheetLoadTimeout,\n keepIframeSrcFn,\n depth: depth + 1,\n maxDepth\n };\n if (serializedNode.type === NodeType.Element && serializedNode.tagName === \"textarea\" && serializedNode.attributes.value !== void 0) ;\n else {\n for (const childN of Array.from(index.childNodes(n))) {\n const serializedChildNode = serializeNodeWithId(childN, bypassOptions);\n if (serializedChildNode) {\n serializedNode.childNodes.push(serializedChildNode);\n }\n }\n }\n let shadowRootEl = null;\n if (isElement(n) && (shadowRootEl = index.shadowRoot(n))) {\n for (const childN of Array.from(index.childNodes(shadowRootEl))) {\n const serializedChildNode = serializeNodeWithId(childN, bypassOptions);\n if (serializedChildNode) {\n isNativeShadowDom(shadowRootEl) && (serializedChildNode.isShadow = true);\n serializedNode.childNodes.push(serializedChildNode);\n }\n }\n }\n }\n const parent = index.parentNode(n);\n if (parent && isShadowRoot(parent) && isNativeShadowDom(parent)) {\n serializedNode.isShadow = true;\n }\n if (serializedNode.type === NodeType.Element && serializedNode.tagName === \"iframe\") {\n const iframeDisposer = onceIframeLoaded(\n n,\n () => {\n const iframeDoc = n.contentDocument;\n if (iframeDoc && onIframeLoad) {\n const serializedIframeNode = serializeNodeWithId(iframeDoc, {\n doc: iframeDoc,\n mirror: mirror2,\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 onIframeListenerRegistered,\n onStylesheetLoad,\n stylesheetLoadTimeout,\n keepIframeSrcFn,\n depth: depth + 1,\n maxDepth\n });\n if (serializedIframeNode) {\n onIframeLoad(\n n,\n serializedIframeNode\n );\n }\n }\n },\n iframeLoadTimeout\n );\n onIframeListenerRegistered == null ? void 0 : onIframeListenerRegistered(n, iframeDisposer);\n }\n if (serializedNode.type === NodeType.Element && serializedNode.tagName === \"link\" && serializedNode.attributes.rel === \"stylesheet\") {\n onceStylesheetLoaded(\n n,\n () => {\n if (onStylesheetLoad) {\n const serializedLinkNode = serializeNodeWithId(n, {\n doc,\n mirror: mirror2,\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 depth,\n maxDepth\n });\n if (serializedLinkNode) {\n onStylesheetLoad(\n n,\n serializedLinkNode\n );\n }\n }\n },\n stylesheetLoadTimeout\n );\n }\n return serializedNode;\n}\nfunction slimDOMDefaults(slimDOM) {\n if (slimDOM === true || slimDOM === \"all\") {\n return {\n script: true,\n comment: true,\n headFavicon: true,\n headWhitespace: true,\n headMetaSocial: true,\n headMetaRobots: true,\n headMetaHttpEquiv: true,\n headMetaVerification: true,\n headMetaAuthorship: slimDOM === \"all\",\n headMetaDescKeywords: slimDOM === \"all\",\n headTitleMutations: slimDOM === \"all\"\n };\n }\n if (slimDOM === false) {\n return {};\n }\n return slimDOM;\n}\nfunction snapshot(n, options) {\n const {\n mirror: mirror2 = 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 onIframeListenerRegistered,\n onStylesheetLoad,\n stylesheetLoadTimeout,\n keepIframeSrcFn = () => false,\n maxDepth\n } = options || {};\n const maskInputOptions = maskAllInputs === true ? {\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 } : maskAllInputs === false ? {\n password: true\n } : maskAllInputs;\n const slimDOMOptions = slimDOMDefaults(slimDOM);\n return serializeNodeWithId(n, {\n doc: n,\n mirror: mirror2,\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 onIframeListenerRegistered,\n onStylesheetLoad,\n stylesheetLoadTimeout,\n keepIframeSrcFn,\n newlyAddedElement: false,\n maxDepth\n });\n}\nclass BaseRRNode {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any\n constructor(..._args) {\n __publicField(this, \"parentElement\", null);\n __publicField(this, \"parentNode\", null);\n __publicField(this, \"ownerDocument\");\n __publicField(this, \"firstChild\", null);\n __publicField(this, \"lastChild\", null);\n __publicField(this, \"previousSibling\", null);\n __publicField(this, \"nextSibling\", null);\n __publicField(this, \"ELEMENT_NODE\", 1);\n __publicField(this, \"TEXT_NODE\", 3);\n // corresponding nodeType value of standard HTML Node\n __publicField(this, \"nodeType\");\n __publicField(this, \"nodeName\");\n __publicField(this, \"RRNodeType\");\n }\n get childNodes() {\n const childNodes2 = [];\n let childIterator = this.firstChild;\n while (childIterator) {\n childNodes2.push(childIterator);\n childIterator = childIterator.nextSibling;\n }\n return childNodes2;\n }\n contains(node) {\n if (!(node instanceof BaseRRNode)) return false;\n else if (node.ownerDocument !== this.ownerDocument) return false;\n else if (node === this) return true;\n while (node.parentNode) {\n if (node.parentNode === this) return true;\n node = node.parentNode;\n }\n return false;\n }\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n appendChild(_newChild) {\n throw new Error(\n `RRDomException: Failed to execute 'appendChild' on 'RRNode': This RRNode type does not support this method.`\n );\n }\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n insertBefore(_newChild, _refChild) {\n throw new Error(\n `RRDomException: Failed to execute 'insertBefore' on 'RRNode': This RRNode type does not support this method.`\n );\n }\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n removeChild(_node) {\n throw new Error(\n `RRDomException: Failed to execute 'removeChild' on 'RRNode': This RRNode type does not support this method.`\n );\n }\n toString() {\n return \"RRNode\";\n }\n}\nfunction on(type, fn, target = document) {\n const options = { capture: true, passive: true };\n target.addEventListener(type, fn, options);\n return () => target.removeEventListener(type, fn, options);\n}\nfunction callSafely(fn) {\n try {\n fn();\n } catch (error) {\n if (!(error instanceof DOMException && error.name === \"SecurityError\")) {\n throw error;\n }\n }\n}\nconst DEPARTED_MIRROR_ACCESS_WARNING = \"Please stop import mirror directly. Instead of that,\\r\\nnow you can use replayer.getMirror() to access the mirror instance of a replayer,\\r\\nor you can use record.mirror to access the mirror instance during recording.\";\nlet _mirror = {\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 return Reflect.get(target, prop, receiver);\n }\n });\n}\nfunction throttle(func, wait, options = {}) {\n let timeout = null;\n let previous = 0;\n return function(...args) {\n const now = Date.now();\n if (!previous && options.leading === false) {\n previous = now;\n }\n const remaining = wait - (now - previous);\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}\nfunction hookSetter(target, key, d, isRevoked, win = window) {\n const original = win.Object.getOwnPropertyDescriptor(target, key);\n win.Object.defineProperty(\n target,\n key,\n isRevoked ? d : {\n set(value) {\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}\nlet nowTimestamp = Date.now;\nif (!/* @__PURE__ */ /[1-9][0-9]{12}/.test(Date.now().toString())) {\n nowTimestamp = () => (/* @__PURE__ */ new Date()).getTime();\n}\nfunction getWindowScroll(win) {\n var _a2, _b, _c, _d;\n const doc = win.document;\n return {\n left: doc.scrollingElement ? doc.scrollingElement.scrollLeft : win.pageXOffset !== void 0 ? win.pageXOffset : doc.documentElement.scrollLeft || (doc == null ? void 0 : doc.body) && ((_a2 = index.parentElement(doc.body)) == null ? void 0 : _a2.scrollLeft) || ((_b = doc == null ? void 0 : doc.body) == null ? void 0 : _b.scrollLeft) || 0,\n top: doc.scrollingElement ? doc.scrollingElement.scrollTop : win.pageYOffset !== void 0 ? win.pageYOffset : (doc == null ? void 0 : doc.documentElement.scrollTop) || (doc == null ? void 0 : doc.body) && ((_c = index.parentElement(doc.body)) == null ? void 0 : _c.scrollTop) || ((_d = doc == null ? void 0 : doc.body) == null ? void 0 : _d.scrollTop) || 0\n };\n}\nfunction getWindowHeight() {\n return window.innerHeight || document.documentElement && document.documentElement.clientHeight || document.body && document.body.clientHeight;\n}\nfunction getWindowWidth() {\n return window.innerWidth || document.documentElement && document.documentElement.clientWidth || document.body && document.body.clientWidth;\n}\nfunction closestElementOfNode(node) {\n if (!node) {\n return null;\n }\n const el = node.nodeType === node.ELEMENT_NODE ? node : index.parentElement(node);\n return el;\n}\nfunction isBlocked(node, blockClass, blockSelector, checkAncestors) {\n if (!node) {\n return false;\n }\n const el = closestElementOfNode(node);\n if (!el) {\n return false;\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 }\n if (blockSelector) {\n if (el.matches(blockSelector)) return true;\n if (checkAncestors && el.closest(blockSelector) !== null) return true;\n }\n return false;\n}\nfunction isSerialized(n, mirror2) {\n return mirror2.getId(n) !== -1;\n}\nfunction isIgnored(n, mirror2, slimDOMOptions) {\n if (n.tagName === \"TITLE\" && slimDOMOptions.headTitleMutations) {\n return true;\n }\n return mirror2.getId(n) === IGNORED_NODE;\n}\nfunction isAncestorRemoved(target, mirror2) {\n if (isShadowRoot(target)) {\n return false;\n }\n const id = mirror2.getId(target);\n if (!mirror2.has(id)) {\n return true;\n }\n const parent = index.parentNode(target);\n if (parent && parent.nodeType === target.DOCUMENT_NODE) {\n return false;\n }\n if (!parent) {\n return true;\n }\n return isAncestorRemoved(parent, mirror2);\n}\nfunction legacy_isTouchEvent(event) {\n return Boolean(event.changedTouches);\n}\nfunction polyfill(win = window) {\n if (\"NodeList\" in win && !win.NodeList.prototype.forEach) {\n win.NodeList.prototype.forEach = Array.prototype.forEach;\n }\n if (\"DOMTokenList\" in win && !win.DOMTokenList.prototype.forEach) {\n win.DOMTokenList.prototype.forEach = Array.prototype.forEach;\n }\n}\nfunction isSerializedIframe(n, mirror2) {\n return Boolean(n.nodeName === \"IFRAME\" && mirror2.getMeta(n));\n}\nfunction isSerializedStylesheet(n, mirror2) {\n return Boolean(\n n.nodeName === \"LINK\" && n.nodeType === n.ELEMENT_NODE && n.getAttribute && n.getAttribute(\"rel\") === \"stylesheet\" && mirror2.getMeta(n)\n );\n}\nfunction hasShadowRoot(n) {\n if (!n) return false;\n if (n instanceof BaseRRNode && \"shadowRoot\" in n) {\n return Boolean(n.shadowRoot);\n }\n return Boolean(index.shadowRoot(n));\n}\nclass StyleSheetMirror {\n constructor() {\n __publicField(this, \"id\", 1);\n __publicField(this, \"styleIDMap\", /* @__PURE__ */ new WeakMap());\n __publicField(this, \"idStyleMap\", /* @__PURE__ */ new Map());\n }\n getId(stylesheet) {\n return this.styleIDMap.get(stylesheet) ?? -1;\n }\n has(stylesheet) {\n return this.styleIDMap.has(stylesheet);\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, id) {\n if (this.has(stylesheet)) return this.getId(stylesheet);\n let newId;\n if (id === void 0) {\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 getStyle(id) {\n return this.idStyleMap.get(id) || null;\n }\n reset() {\n this.styleIDMap = /* @__PURE__ */ new WeakMap();\n this.idStyleMap = /* @__PURE__ */ new Map();\n this.id = 1;\n }\n generateId() {\n return this.id++;\n }\n}\nfunction getShadowHost(n) {\n var _a2;\n let shadowHost = null;\n if (\"getRootNode\" in n && ((_a2 = index.getRootNode(n)) == null ? void 0 : _a2.nodeType) === Node.DOCUMENT_FRAGMENT_NODE && index.host(index.getRootNode(n)))\n shadowHost = index.host(index.getRootNode(n));\n return shadowHost;\n}\nfunction getRootShadowHost(n) {\n let rootShadowHost = n;\n let shadowHost;\n while (shadowHost = getShadowHost(rootShadowHost))\n rootShadowHost = shadowHost;\n return rootShadowHost;\n}\nfunction shadowHostInDom(n) {\n const doc = n.ownerDocument;\n if (!doc) return false;\n const shadowHost = getRootShadowHost(n);\n return index.contains(doc, shadowHost);\n}\nfunction inDom(n) {\n const doc = n.ownerDocument;\n if (!doc) return false;\n return index.contains(doc, n) || shadowHostInDom(n);\n}\nfunction isNodeInLinkedList(n) {\n return \"__ln\" in n;\n}\nclass DoubleLinkedList {\n constructor() {\n __publicField(this, \"length\", 0);\n __publicField(this, \"head\", null);\n __publicField(this, \"tail\", null);\n }\n get(position) {\n if (position >= this.length) {\n throw new Error(\"Position outside of list range\");\n }\n let current = this.head;\n for (let index2 = 0; index2 < position; index2++) {\n current = (current == null ? void 0 : current.next) || null;\n }\n return current;\n }\n addNode(n) {\n const node = {\n value: n,\n previous: null,\n next: null\n };\n n.__ln = node;\n if (n.previousSibling && isNodeInLinkedList(n.previousSibling)) {\n const current = n.previousSibling.__ln.next;\n node.next = current;\n node.previous = n.previousSibling.__ln;\n n.previousSibling.__ln.next = node;\n if (current) {\n current.previous = node;\n }\n } else if (n.nextSibling && isNodeInLinkedList(n.nextSibling) && n.nextSibling.__ln.previous) {\n const current = n.nextSibling.__ln.previous;\n node.previous = current;\n node.next = n.nextSibling.__ln;\n n.nextSibling.__ln.previous = node;\n if (current) {\n current.next = node;\n }\n } else {\n if (this.head) {\n this.head.previous = node;\n }\n node.next = this.head;\n this.head = node;\n }\n if (node.next === null) {\n this.tail = node;\n }\n this.length++;\n }\n removeNode(n) {\n const current = n.__ln;\n if (!this.head) {\n return;\n }\n if (!current.previous) {\n this.head = current.next;\n if (this.head) {\n this.head.previous = null;\n } else {\n this.tail = null;\n }\n } else {\n current.previous.next = current.next;\n if (current.next) {\n current.next.previous = current.previous;\n } else {\n this.tail = current.previous;\n }\n }\n if (n.__ln) {\n delete n.__ln;\n }\n this.length--;\n }\n}\nconst moveKey = (id, parentId) => `${id}@${parentId}`;\nclass MutationBuffer {\n constructor() {\n __publicField(this, \"frozen\", false);\n __publicField(this, \"locked\", false);\n __publicField(this, \"texts\", []);\n __publicField(this, \"attributes\", []);\n __publicField(this, \"attributeMap\", /* @__PURE__ */ new WeakMap());\n __publicField(this, \"removes\", []);\n __publicField(this, \"mapRemoves\", []);\n __publicField(this, \"movedMap\", {});\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 __publicField(this, \"addedSet\", /* @__PURE__ */ new Set());\n __publicField(this, \"movedSet\", /* @__PURE__ */ new Set());\n __publicField(this, \"droppedSet\", /* @__PURE__ */ new Set());\n __publicField(this, \"removesSubTreeCache\", /* @__PURE__ */ new Set());\n __publicField(this, \"mutationCb\");\n __publicField(this, \"blockClass\");\n __publicField(this, \"blockSelector\");\n __publicField(this, \"maskTextClass\");\n __publicField(this, \"maskTextSelector\");\n __publicField(this, \"inlineStylesheet\");\n __publicField(this, \"maskInputOptions\");\n __publicField(this, \"maskTextFn\");\n __publicField(this, \"maskInputFn\");\n __publicField(this, \"keepIframeSrcFn\");\n __publicField(this, \"recordCanvas\");\n __publicField(this, \"inlineImages\");\n __publicField(this, \"slimDOMOptions\");\n __publicField(this, \"dataURLOptions\");\n __publicField(this, \"doc\");\n __publicField(this, \"mirror\");\n __publicField(this, \"iframeManager\");\n __publicField(this, \"stylesheetManager\");\n __publicField(this, \"shadowDomManager\");\n __publicField(this, \"canvasManager\");\n __publicField(this, \"processedNodeManager\");\n __publicField(this, \"unattachedDoc\");\n __publicField(this, \"canvasManagerReleased\", false);\n __publicField(this, \"processMutations\", (mutations) => {\n mutations.forEach(this.processMutation);\n this.emit();\n });\n __publicField(this, \"emit\", () => {\n if (this.frozen || this.locked) {\n return;\n }\n const adds = [];\n const addedIds = /* @__PURE__ */ new Set();\n const addList = new DoubleLinkedList();\n const getNextId = (n) => {\n let ns = n;\n let nextId = IGNORED_NODE;\n while (nextId === IGNORED_NODE) {\n ns = ns && ns.nextSibling;\n nextId = ns && this.mirror.getId(ns);\n }\n return nextId;\n };\n const pushAdd = (n) => {\n const parent = index.parentNode(n);\n if (!parent || !inDom(n) || parent.tagName === \"TEXTAREA\") {\n return;\n }\n const parentId = isShadowRoot(parent) ? this.mirror.getId(getShadowHost(n)) : this.mirror.getId(parent);\n const nextId = getNextId(n);\n if (parentId === -1 || nextId === -1) {\n return addList.addNode(n);\n }\n const sn = serializeNodeWithId(n, {\n doc: this.doc,\n mirror: this.mirror,\n blockClass: this.blockClass,\n blockSelector: this.blockSelector,\n maskTextClass: this.maskTextClass,\n maskTextSelector: this.maskTextSelector,\n skipChild: true,\n newlyAddedElement: true,\n inlineStylesheet: this.inlineStylesheet,\n maskInputOptions: this.maskInputOptions,\n maskTextFn: this.maskTextFn,\n maskInputFn: this.maskInputFn,\n slimDOMOptions: this.slimDOMOptions,\n dataURLOptions: this.dataURLOptions,\n recordCanvas: this.recordCanvas,\n inlineImages: this.inlineImages,\n onSerialize: (currentN) => {\n if (isSerializedIframe(currentN, this.mirror)) {\n this.iframeManager.addIframe(currentN);\n }\n if (isSerializedStylesheet(currentN, this.mirror)) {\n this.stylesheetManager.trackLinkElement(\n currentN\n );\n }\n if (hasShadowRoot(n)) {\n this.shadowDomManager.addShadowRoot(index.shadowRoot(n), this.doc);\n }\n },\n onIframeLoad: (iframe, childSn) => {\n this.iframeManager.attachIframe(iframe, childSn);\n this.shadowDomManager.observeAttachShadow(iframe);\n },\n onIframeListenerRegistered: (iframe, disposer) => {\n this.iframeManager.registerLoadListenerDisposer(iframe, disposer);\n },\n onStylesheetLoad: (link, childSn) => {\n this.stylesheetManager.attachLinkElement(link, childSn);\n }\n });\n if (sn) {\n adds.push({\n parentId,\n nextId,\n node: sn\n });\n addedIds.add(sn.id);\n }\n };\n while (this.mapRemoves.length) {\n this.mirror.removeNodeFromMap(this.mapRemoves.shift());\n }\n for (const n of this.movedSet) {\n if (isParentRemoved(this.removesSubTreeCache, n, this.mirror) && !this.movedSet.has(index.parentNode(n))) {\n continue;\n }\n pushAdd(n);\n }\n for (const n of this.addedSet) {\n if (!isAncestorInSet(this.droppedSet, n) && !isParentRemoved(this.removesSubTreeCache, n, this.mirror)) {\n pushAdd(n);\n } else if (isAncestorInSet(this.movedSet, n)) {\n pushAdd(n);\n } else {\n this.droppedSet.add(n);\n }\n }\n let candidate = null;\n while (addList.length) {\n let node = null;\n if (candidate) {\n const parentId = this.mirror.getId(index.parentNode(candidate.value));\n const nextId = getNextId(candidate.value);\n if (parentId !== -1 && nextId !== -1) {\n node = candidate;\n }\n }\n if (!node) {\n let tailNode = addList.tail;\n while (tailNode) {\n const _node = tailNode;\n tailNode = tailNode.previous;\n if (_node) {\n const parentId = this.mirror.getId(index.parentNode(_node.value));\n const nextId = getNextId(_node.value);\n if (nextId === -1) continue;\n else if (parentId !== -1) {\n node = _node;\n break;\n } else {\n const unhandledNode = _node.value;\n const parent = index.parentNode(unhandledNode);\n if (parent && parent.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {\n const shadowHost = index.host(parent);\n const parentId2 = this.mirror.getId(shadowHost);\n if (parentId2 !== -1) {\n node = _node;\n break;\n }\n }\n }\n }\n }\n }\n if (!node) {\n while (addList.head) {\n addList.removeNode(addList.head.value);\n }\n break;\n }\n candidate = node.previous;\n addList.removeNode(node.value);\n pushAdd(node.value);\n }\n const payload = {\n texts: this.texts.map((text) => {\n const n = text.node;\n const parent = index.parentNode(n);\n if (parent && parent.tagName === \"TEXTAREA\") {\n this.genTextAreaValueMutation(parent);\n }\n return {\n id: this.mirror.getId(n),\n value: text.value\n };\n }).filter((text) => !addedIds.has(text.id)).filter((text) => this.mirror.has(text.id)),\n attributes: this.attributes.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 if (diffAsStr.length < attributes.style.length) {\n if ((diffAsStr + unchangedAsStr).split(\"var(\").length === attributes.style.split(\"var(\").length) {\n attributes.style = attribute.styleDiff;\n }\n }\n }\n return {\n id: this.mirror.getId(attribute.node),\n attributes\n };\n }).filter((attribute) => !addedIds.has(attribute.id)).filter((attribute) => this.mirror.has(attribute.id)),\n removes: this.removes,\n adds\n };\n if (!payload.texts.length && !payload.attributes.length && !payload.removes.length && !payload.adds.length) {\n return;\n }\n this.texts = [];\n this.attributes = [];\n this.attributeMap = /* @__PURE__ */ new WeakMap();\n this.removes = [];\n this.addedSet = /* @__PURE__ */ new Set();\n this.movedSet = /* @__PURE__ */ new Set();\n this.droppedSet = /* @__PURE__ */ new Set();\n this.removesSubTreeCache = /* @__PURE__ */ new Set();\n this.movedMap = {};\n this.mutationCb(payload);\n });\n __publicField(this, \"bufferBelongsToIframe\", (iframeEl) => {\n return this.doc === iframeEl.contentDocument;\n });\n __publicField(this, \"genTextAreaValueMutation\", (textarea) => {\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 index.childNodes(textarea),\n (cn) => index.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 __publicField(this, \"processMutation\", (m) => {\n if (isIgnored(m.target, this.mirror, this.slimDOMOptions)) {\n return;\n }\n switch (m.type) {\n case \"characterData\": {\n const value = index.textContent(m.target);\n if (!isBlocked(m.target, this.blockClass, this.blockSelector, false) && value !== m.oldValue) {\n this.texts.push({\n value: needMaskingText(\n m.target,\n this.maskTextClass,\n this.maskTextSelector,\n true\n // checkAncestors\n ) && value ? this.maskTextFn ? this.maskTextFn(value, closestElementOfNode(m.target)) : value.replace(/[\\S]/g, \"*\") : value,\n node: m.target\n });\n }\n break;\n }\n case \"attributes\": {\n const target = m.target;\n let attributeName = m.attributeName;\n let value = m.target.getAttribute(attributeName);\n if (attributeName === \"value\") {\n const type = getInputType(target);\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 (isBlocked(m.target, this.blockClass, this.blockSelector, false) || value === m.oldValue) {\n return;\n }\n let item = this.attributeMap.get(m.target);\n if (target.tagName === \"IFRAME\" && attributeName === \"src\" && !this.keepIframeSrcFn(value)) {\n if (!target.contentDocument) {\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 if (attributeName === \"type\" && target.tagName === \"INPUT\" && (m.oldValue || \"\").toLowerCase() === \"password\") {\n target.setAttribute(\"data-rr-is-password\", \"true\");\n }\n if (!ignoreAttribute(target.tagName, attributeName)) {\n item.attributes[attributeName] = transformAttribute(\n this.doc,\n toLowerCase(target.tagName),\n toLowerCase(attributeName),\n value,\n target,\n this.dataURLOptions\n );\n if (attributeName === \"style\") {\n if (!this.unattachedDoc) {\n try {\n this.unattachedDoc = document.implementation.createHTMLDocument();\n } catch (e) {\n this.unattachedDoc = this.doc;\n }\n }\n const old = this.unattachedDoc.createElement(\"span\");\n if (m.oldValue) {\n old.style.cssText = m.oldValue;\n }\n for (const pname of Array.from(target.style)) {\n const newValue = target.style.getPropertyValue(pname);\n const newPriority = target.style.getPropertyPriority(pname);\n if (newValue !== old.style.getPropertyValue(pname) || newPriority !== old.style.getPropertyPriority(pname)) {\n if (newPriority === \"\") {\n item.styleDiff[pname] = newValue;\n } else {\n item.styleDiff[pname] = [newValue, newPriority];\n }\n } else {\n item._unchangedStyles[pname] = [newValue, newPriority];\n }\n }\n for (const pname of Array.from(old.style)) {\n if (target.style.getPropertyValue(pname) === \"\") {\n item.styleDiff[pname] = false;\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 if (isBlocked(m.target, this.blockClass, this.blockSelector, true))\n return;\n if (m.target.tagName === \"TEXTAREA\") {\n this.genTextAreaValueMutation(m.target);\n return;\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) ? this.mirror.getId(index.host(m.target)) : this.mirror.getId(m.target);\n if (isBlocked(m.target, this.blockClass, this.blockSelector, false) || isIgnored(n, this.mirror, this.slimDOMOptions) || !isSerialized(n, this.mirror)) {\n return;\n }\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 else if (isAncestorRemoved(m.target, this.mirror)) ;\n else if (this.movedSet.has(n) && this.movedMap[moveKey(nodeId, parentId)]) {\n deepDelete(this.movedSet, n);\n } else {\n this.removes.push({\n parentId,\n id: nodeId,\n isShadow: isShadowRoot(m.target) && isNativeShadowDom(m.target) ? true : void 0\n });\n processRemoves(n, this.removesSubTreeCache);\n }\n this.mapRemoves.push(n);\n });\n break;\n }\n }\n });\n /**\n * Make sure you check if `n`'s parent is blocked before calling this function\n * */\n __publicField(this, \"genAdds\", (n, target) => {\n if (this.processedNodeManager.inOtherBuffer(n, this)) return;\n if (this.addedSet.has(n) || this.movedSet.has(n)) return;\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 = 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 if (!isBlocked(n, this.blockClass, this.blockSelector, false)) {\n index.childNodes(n).forEach((childN) => this.genAdds(childN));\n if (hasShadowRoot(n)) {\n index.childNodes(index.shadowRoot(n)).forEach((childN) => {\n this.processedNodeManager.add(childN, this);\n this.genAdds(childN, n);\n });\n }\n }\n });\n }\n init(options) {\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 ].forEach((key) => {\n this[key] = options[key];\n });\n this.canvasManager.acquire();\n }\n freeze() {\n this.frozen = true;\n this.canvasManager.freeze();\n }\n unfreeze() {\n this.frozen = false;\n this.canvasManager.unfreeze();\n this.emit();\n }\n isFrozen() {\n return this.frozen;\n }\n lock() {\n this.locked = true;\n this.canvasManager.lock();\n }\n unlock() {\n this.locked = false;\n this.canvasManager.unlock();\n this.emit();\n }\n reset() {\n this.shadowDomManager.reset();\n this.releaseCanvasManager();\n }\n // Releases at most once even if reset() runs twice (iframe pagehide + stop). Separate from\n // reset() so shadow-root teardown can release without re-entering shadowDomManager.reset().\n releaseCanvasManager() {\n if (this.canvasManagerReleased) {\n return;\n }\n this.canvasManagerReleased = true;\n this.canvasManager.reset();\n }\n bufferDoc() {\n return this.doc;\n }\n destroy() {\n while (this.mapRemoves.length) {\n this.mirror.removeNodeFromMap(this.mapRemoves.shift());\n }\n }\n}\nfunction deepDelete(addsSet, n) {\n addsSet.delete(n);\n index.childNodes(n).forEach((childN) => deepDelete(addsSet, childN));\n}\nfunction processRemoves(n, cache) {\n const queue = [n];\n while (queue.length) {\n const next = queue.pop();\n if (cache.has(next)) continue;\n cache.add(next);\n index.childNodes(next).forEach((n2) => queue.push(n2));\n }\n return;\n}\nfunction isParentRemoved(removes, n, mirror2) {\n if (removes.size === 0) return false;\n return _isParentRemoved(removes, n);\n}\nfunction _isParentRemoved(removes, n, _mirror2) {\n const node = index.parentNode(n);\n if (!node) return false;\n return removes.has(node);\n}\nfunction isAncestorInSet(set, n) {\n if (set.size === 0) return false;\n return _isAncestorInSet(set, n);\n}\nfunction _isAncestorInSet(set, n) {\n const parent = index.parentNode(n);\n if (!parent) {\n return false;\n }\n if (set.has(parent)) {\n return true;\n }\n return _isAncestorInSet(set, parent);\n}\nlet errorHandler;\nfunction registerErrorHandler(handler) {\n errorHandler = handler;\n}\nfunction unregisterErrorHandler() {\n errorHandler = void 0;\n}\nconst callbackWrapper = (cb) => {\n if (!errorHandler) {\n return cb;\n }\n const rrwebWrapped = ((...rest) => {\n try {\n return cb(...rest);\n } catch (error) {\n if (errorHandler && errorHandler(error) === true) {\n return;\n }\n throw error;\n }\n });\n return rrwebWrapped;\n};\nconst mutationBuffers = [];\nfunction getEventTarget(event) {\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 }\n return event && event.target;\n}\nfunction initMutationObserver(options, rootEl) {\n const mutationBuffer = new MutationBuffer();\n mutationBuffers.push(mutationBuffer);\n mutationBuffer.init(options);\n const observer = new (mutationObserverCtor())(\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, buffer: mutationBuffer };\n}\nfunction initMoveObserver({\n mousemoveCb,\n sampling,\n doc,\n mirror: mirror2\n}) {\n if (sampling.mousemove === false) {\n return () => {\n };\n }\n const threshold = typeof sampling.mousemove === \"number\" ? sampling.mousemove : 50;\n const callbackThreshold = typeof sampling.mousemoveCallback === \"number\" ? sampling.mousemoveCallback : 500;\n let positions = [];\n let timeBaseline;\n const wrappedCb = throttle(\n callbackWrapper(\n (source) => {\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(\n callbackWrapper((evt) => {\n const target = getEventTarget(evt);\n const { clientX, clientY } = legacy_isTouchEvent(evt) ? evt.changedTouches[0] : evt;\n if (!timeBaseline) {\n timeBaseline = nowTimestamp();\n }\n positions.push({\n x: clientX,\n y: clientY,\n id: mirror2.getId(target),\n timeOffset: nowTimestamp() - timeBaseline\n });\n wrappedCb(\n typeof DragEvent !== \"undefined\" && evt instanceof DragEvent ? IncrementalSource.Drag : evt instanceof MouseEvent ? IncrementalSource.MouseMove : 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}\nfunction initMouseInteractionObserver({\n mouseInteractionCb,\n doc,\n mirror: mirror2,\n blockClass,\n blockSelector,\n sampling\n}) {\n if (sampling.mouseInteraction === false) {\n return () => {\n };\n }\n const disableMap = sampling.mouseInteraction === true || sampling.mouseInteraction === void 0 ? {} : sampling.mouseInteraction;\n const handlers = [];\n let currentPointerType = null;\n const getHandler = (eventKey) => {\n return (event) => {\n const target = getEventTarget(event);\n if (isBlocked(target, blockClass, blockSelector, true)) {\n return;\n }\n let pointerType = 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 thisEventKey = \"TouchStart\";\n } else if (MouseInteractions[eventKey] === MouseInteractions.MouseUp) {\n thisEventKey = \"TouchEnd\";\n }\n } else if (pointerType === PointerTypes.Pen) ;\n } else if (legacy_isTouchEvent(event)) {\n pointerType = PointerTypes.Touch;\n }\n if (pointerType !== null) {\n currentPointerType = pointerType;\n if (thisEventKey.startsWith(\"Touch\") && pointerType === PointerTypes.Touch || thisEventKey.startsWith(\"Mouse\") && pointerType === PointerTypes.Mouse) {\n pointerType = null;\n }\n } else if (MouseInteractions[eventKey] === MouseInteractions.Click) {\n pointerType = currentPointerType;\n currentPointerType = null;\n }\n const e = legacy_isTouchEvent(event) ? event.changedTouches[0] : event;\n if (!e) {\n return;\n }\n const id = mirror2.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).filter(\n (key) => Number.isNaN(Number(key)) && !key.endsWith(\"_Departed\") && disableMap[key] !== false\n ).forEach((eventKey) => {\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 );\n break;\n case MouseInteractions.TouchStart:\n case MouseInteractions.TouchEnd:\n return;\n }\n }\n handlers.push(on(eventName, handler, doc));\n });\n return callbackWrapper(() => {\n handlers.forEach((h) => h());\n });\n}\nfunction initScrollObserver({\n scrollCb,\n doc,\n mirror: mirror2,\n blockClass,\n blockSelector,\n sampling\n}) {\n const lastEmitted = /* @__PURE__ */ new Map();\n const emitScrollPosition = (evt) => {\n const target = getEventTarget(evt);\n if (!target || isBlocked(target, blockClass, blockSelector, true)) {\n return;\n }\n const id = mirror2.getId(target);\n let x;\n let y;\n if (target === doc && doc.defaultView) {\n const scrollLeftTop = getWindowScroll(doc.defaultView);\n x = scrollLeftTop.left;\n y = scrollLeftTop.top;\n } else {\n x = target.scrollLeft;\n y = target.scrollTop;\n }\n const key = `${x},${y}`;\n if (lastEmitted.get(id) === key) {\n return;\n }\n lastEmitted.set(id, key);\n scrollCb({ id, x, y });\n };\n const updatePosition = callbackWrapper(\n throttle(\n callbackWrapper((evt) => emitScrollPosition(evt)),\n sampling.scroll || 100\n )\n );\n const handlers = [on(\"scroll\", updatePosition, doc)];\n if (\"onscrollend\" in doc) {\n handlers.push(on(\"scrollend\", callbackWrapper(emitScrollPosition), doc));\n }\n return () => handlers.forEach((h) => h());\n}\nfunction initViewportResizeObserver({ viewportResizeCb }, { win }) {\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}\nfunction findAndRemoveIframeBuffer(iframeEl, knownDocs) {\n for (let i = mutationBuffers.length - 1; i >= 0; i--) {\n const buf = mutationBuffers[i];\n if (!buf) continue;\n let match = buf.bufferBelongsToIframe(iframeEl);\n if (!match && knownDocs && knownDocs.has(buf.bufferDoc())) {\n match = true;\n }\n if (match) {\n buf.reset();\n mutationBuffers.splice(i, 1);\n }\n }\n}\nconst INPUT_TAGS = [\"INPUT\", \"TEXTAREA\", \"SELECT\"];\nconst lastInputValueMap = /* @__PURE__ */ new WeakMap();\nfunction initInputObserver({\n inputCb,\n doc,\n mirror: mirror2,\n blockClass,\n blockSelector,\n ignoreClass,\n ignoreSelector,\n maskInputOptions,\n maskInputFn,\n sampling,\n userTriggeredOnInput\n}) {\n function eventHandler(event) {\n let target = getEventTarget(event);\n const userTriggered = event.isTrusted;\n const tagName = target && target.tagName;\n if (target && tagName === \"OPTION\") {\n target = index.parentElement(target);\n }\n if (!target || !tagName || INPUT_TAGS.indexOf(tagName) < 0 || isBlocked(target, blockClass, blockSelector, true)) {\n return;\n }\n if (target.classList.contains(ignoreClass) || ignoreSelector && target.matches(ignoreSelector)) {\n return;\n }\n let text = target.value;\n let isChecked = false;\n const type = getInputType(target) || \"\";\n if (type === \"radio\" || type === \"checkbox\") {\n isChecked = target.checked;\n } else if (maskInputOptions[tagName.toLowerCase()] || maskInputOptions[type]) {\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 ? { text, isChecked, userTriggered } : { text, isChecked }\n );\n const name = target.name;\n if (type === \"radio\" && name && isChecked) {\n doc.querySelectorAll(`input[type=\"radio\"][name=\"${name}\"]`).forEach((el) => {\n if (el !== target) {\n const text2 = el.value;\n cbWithDedup(\n el,\n userTriggeredOnInput ? { text: text2, isChecked: !isChecked, userTriggered: false } : { text: text2, isChecked: !isChecked }\n );\n }\n });\n }\n }\n function cbWithDedup(target, v) {\n const lastInputValue = lastInputValueMap.get(target);\n if (!lastInputValue || lastInputValue.text !== v.text || lastInputValue.isChecked !== v.isChecked) {\n lastInputValueMap.set(target, v);\n const id = mirror2.getId(target);\n callbackWrapper(inputCb)({\n ...v,\n id\n });\n }\n }\n const events = sampling.input === \"last\" ? [\"change\"] : [\"input\", \"change\"];\n const handlers = 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 = [\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(\n (p) => hookSetter(\n p[0],\n p[1],\n {\n set() {\n callbackWrapper(eventHandler)({\n target: this,\n isTrusted: false\n // userTriggered to false as this could well be programmatic\n });\n }\n },\n false,\n currentWindow\n )\n )\n );\n }\n return callbackWrapper(() => {\n handlers.forEach((h) => h());\n });\n}\nfunction getNestedCSSRulePositions(rule) {\n const positions = [];\n function recurse(childRule, pos) {\n if (hasNestedCSSRule(\"CSSGroupingRule\") && childRule.parentRule instanceof CSSGroupingRule || hasNestedCSSRule(\"CSSMediaRule\") && childRule.parentRule instanceof CSSMediaRule || hasNestedCSSRule(\"CSSSupportsRule\") && childRule.parentRule instanceof CSSSupportsRule || hasNestedCSSRule(\"CSSConditionRule\") && childRule.parentRule instanceof CSSConditionRule) {\n const rules = Array.from(\n childRule.parentRule.cssRules\n );\n const index2 = rules.indexOf(childRule);\n pos.unshift(index2);\n return recurse(childRule.parentRule, pos);\n } else if (childRule.parentStyleSheet) {\n const rules = Array.from(childRule.parentStyleSheet.cssRules);\n const index2 = rules.indexOf(childRule);\n pos.unshift(index2);\n }\n return pos;\n }\n return recurse(rule, positions);\n}\nfunction getIdAndStyleId(sheet, mirror2, styleMirror) {\n let id, styleId;\n if (!sheet) return {};\n if (sheet.ownerNode) id = mirror2.getId(sheet.ownerNode);\n else styleId = styleMirror.getId(sheet);\n return {\n styleId,\n id\n };\n}\nfunction initStyleSheetObserver({ styleSheetRuleCb, mirror: mirror2, stylesheetManager }, { win }) {\n if (!win.CSSStyleSheet || !win.CSSStyleSheet.prototype) {\n return () => {\n };\n }\n const insertRule = win.CSSStyleSheet.prototype.insertRule;\n win.CSSStyleSheet.prototype.insertRule = new Proxy(insertRule, {\n apply: callbackWrapper(\n (target, thisArg, argumentsList) => {\n const [rule, index2] = argumentsList;\n const { id, styleId } = getIdAndStyleId(\n thisArg,\n mirror2,\n stylesheetManager.styleMirror\n );\n if (id && id !== -1 || styleId && styleId !== -1) {\n styleSheetRuleCb({\n id,\n styleId,\n adds: [{ rule, index: index2 }]\n });\n }\n return target.apply(thisArg, argumentsList);\n }\n )\n });\n win.CSSStyleSheet.prototype.addRule = function(selector, styleBlock, index2 = this.cssRules.length) {\n const rule = `${selector} { ${styleBlock} }`;\n return win.CSSStyleSheet.prototype.insertRule.apply(this, [rule, index2]);\n };\n const deleteRule = win.CSSStyleSheet.prototype.deleteRule;\n win.CSSStyleSheet.prototype.deleteRule = new Proxy(deleteRule, {\n apply: callbackWrapper(\n (target, thisArg, argumentsList) => {\n const [index2] = argumentsList;\n const { id, styleId } = getIdAndStyleId(\n thisArg,\n mirror2,\n stylesheetManager.styleMirror\n );\n if (id && id !== -1 || styleId && styleId !== -1) {\n styleSheetRuleCb({\n id,\n styleId,\n removes: [{ index: index2 }]\n });\n }\n return target.apply(thisArg, argumentsList);\n }\n )\n });\n win.CSSStyleSheet.prototype.removeRule = function(index2) {\n return win.CSSStyleSheet.prototype.deleteRule.apply(this, [index2]);\n };\n let replace;\n if (win.CSSStyleSheet.prototype.replace) {\n replace = win.CSSStyleSheet.prototype.replace;\n win.CSSStyleSheet.prototype.replace = new Proxy(replace, {\n apply: callbackWrapper(\n (target, thisArg, argumentsList) => {\n const [text] = argumentsList;\n const { id, styleId } = getIdAndStyleId(\n thisArg,\n mirror2,\n stylesheetManager.styleMirror\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 let replaceSync;\n if (win.CSSStyleSheet.prototype.replaceSync) {\n replaceSync = win.CSSStyleSheet.prototype.replaceSync;\n win.CSSStyleSheet.prototype.replaceSync = new Proxy(replaceSync, {\n apply: callbackWrapper(\n (target, thisArg, argumentsList) => {\n const [text] = argumentsList;\n const { id, styleId } = getIdAndStyleId(\n thisArg,\n mirror2,\n stylesheetManager.styleMirror\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 const supportedNestedCSSRuleTypes = {};\n if (canMonkeyPatchNestedCSSRule(\"CSSGroupingRule\")) {\n supportedNestedCSSRuleTypes.CSSGroupingRule = win.CSSGroupingRule;\n } else {\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 const unmodifiedFunctions = {};\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 type.prototype.insertRule = new Proxy(\n unmodifiedFunctions[typeKey].insertRule,\n {\n apply: callbackWrapper(\n (target, thisArg, argumentsList) => {\n const [rule, index2] = argumentsList;\n const { id, styleId } = getIdAndStyleId(\n thisArg.parentStyleSheet,\n mirror2,\n stylesheetManager.styleMirror\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 index2 || 0\n // defaults to 0\n ]\n }\n ]\n });\n }\n return target.apply(thisArg, argumentsList);\n }\n )\n }\n );\n type.prototype.deleteRule = new Proxy(\n unmodifiedFunctions[typeKey].deleteRule,\n {\n apply: callbackWrapper(\n (target, thisArg, argumentsList) => {\n const [index2] = argumentsList;\n const { id, styleId } = getIdAndStyleId(\n thisArg.parentStyleSheet,\n mirror2,\n stylesheetManager.styleMirror\n );\n if (id && id !== -1 || styleId && styleId !== -1) {\n styleSheetRuleCb({\n id,\n styleId,\n removes: [\n { index: [...getNestedCSSRulePositions(thisArg), index2] }\n ]\n });\n }\n return target.apply(thisArg, argumentsList);\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}\nfunction initAdoptedStyleSheetObserver({\n mirror: mirror2,\n stylesheetManager\n}, host2) {\n var _a2, _b, _c;\n let hostId = null;\n if (host2.nodeName === \"#document\") hostId = mirror2.getId(host2);\n else hostId = mirror2.getId(index.host(host2));\n const patchTarget = host2.nodeName === \"#document\" ? (_a2 = host2.defaultView) == null ? void 0 : _a2.Document : (_c = (_b = host2.ownerDocument) == null ? void 0 : _b.defaultView) == null ? void 0 : _c.ShadowRoot;\n const originalPropertyDescriptor = (patchTarget == null ? void 0 : patchTarget.prototype) ? Object.getOwnPropertyDescriptor(\n patchTarget == null ? void 0 : patchTarget.prototype,\n \"adoptedStyleSheets\"\n ) : void 0;\n if (hostId === null || hostId === -1 || !patchTarget || !originalPropertyDescriptor)\n return () => {\n };\n Object.defineProperty(host2, \"adoptedStyleSheets\", {\n configurable: originalPropertyDescriptor.configurable,\n enumerable: originalPropertyDescriptor.enumerable,\n get() {\n var _a3;\n return (_a3 = originalPropertyDescriptor.get) == null ? void 0 : _a3.call(this);\n },\n set(sheets) {\n var _a3;\n const result = (_a3 = originalPropertyDescriptor.set) == null ? void 0 : _a3.call(this, sheets);\n if (hostId !== null && hostId !== -1) {\n try {\n stylesheetManager.adoptStyleSheets(sheets, hostId);\n } catch (e) {\n }\n }\n return result;\n }\n });\n return callbackWrapper(() => {\n Object.defineProperty(host2, \"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}\nfunction initStyleDeclarationObserver({\n styleDeclarationCb,\n mirror: mirror2,\n ignoreCSSAttributes,\n stylesheetManager\n}, { win }) {\n const setProperty = win.CSSStyleDeclaration.prototype.setProperty;\n win.CSSStyleDeclaration.prototype.setProperty = new Proxy(setProperty, {\n apply: callbackWrapper(\n (target, thisArg, argumentsList) => {\n var _a2;\n const [property, value, priority] = argumentsList;\n if (ignoreCSSAttributes.has(property)) {\n return setProperty.apply(thisArg, [property, value, priority]);\n }\n const { id, styleId } = getIdAndStyleId(\n (_a2 = thisArg.parentRule) == null ? void 0 : _a2.parentStyleSheet,\n mirror2,\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 const removeProperty = win.CSSStyleDeclaration.prototype.removeProperty;\n win.CSSStyleDeclaration.prototype.removeProperty = new Proxy(removeProperty, {\n apply: callbackWrapper(\n (target, thisArg, argumentsList) => {\n var _a2;\n const [property] = argumentsList;\n if (ignoreCSSAttributes.has(property)) {\n return removeProperty.apply(thisArg, [property]);\n }\n const { id, styleId } = getIdAndStyleId(\n (_a2 = thisArg.parentRule) == null ? void 0 : _a2.parentStyleSheet,\n mirror2,\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 return callbackWrapper(() => {\n win.CSSStyleDeclaration.prototype.setProperty = setProperty;\n win.CSSStyleDeclaration.prototype.removeProperty = removeProperty;\n });\n}\nfunction initMediaInteractionObserver({\n mediaInteractionCb,\n blockClass,\n blockSelector,\n mirror: mirror2,\n sampling,\n doc\n}) {\n const handler = callbackWrapper(\n (type) => throttle(\n callbackWrapper((event) => {\n const target = getEventTarget(event);\n if (!target || isBlocked(target, blockClass, blockSelector, true)) {\n return;\n }\n const { currentTime, volume, muted, playbackRate, loop } = target;\n mediaInteractionCb({\n type,\n id: mirror2.getId(target),\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}\nfunction initFontObserver({ fontCb, doc }) {\n const win = doc.defaultView;\n if (!win) {\n return () => {\n };\n }\n const handlers = [];\n const fontMap = /* @__PURE__ */ new WeakMap();\n const originalFontFace = win.FontFace;\n win.FontFace = function FontFace(family, source, descriptors) {\n const fontFace = new originalFontFace(\n family,\n source,\n descriptors\n );\n fontMap.set(fontFace, {\n family,\n buffer: typeof source !== \"string\",\n descriptors,\n fontSource: typeof source === \"string\" ? source : JSON.stringify(Array.from(new Uint8Array(source)))\n });\n return fontFace;\n };\n const restoreHandler = patch(\n doc.fonts,\n \"add\",\n function(original) {\n return function(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 handlers.push(() => {\n win.FontFace = originalFontFace;\n });\n handlers.push(restoreHandler);\n return callbackWrapper(() => {\n handlers.forEach((h) => h());\n });\n}\nfunction initSelectionObserver(param) {\n const { doc, mirror: mirror2, blockClass, blockSelector, selectionCb } = param;\n let collapsed = true;\n const updateSelection = callbackWrapper(() => {\n const selection = doc.getSelection();\n if (!selection || collapsed && (selection == null ? void 0 : selection.isCollapsed)) return;\n collapsed = selection.isCollapsed || false;\n const ranges = [];\n const count = selection.rangeCount || 0;\n for (let i = 0; i < count; i++) {\n const range = selection.getRangeAt(i);\n const { startContainer, startOffset, endContainer, endOffset } = range;\n const blocked = isBlocked(startContainer, blockClass, blockSelector, true) || isBlocked(endContainer, blockClass, blockSelector, true);\n if (blocked) continue;\n ranges.push({\n start: mirror2.getId(startContainer),\n startOffset,\n end: mirror2.getId(endContainer),\n endOffset\n });\n }\n selectionCb({ ranges });\n });\n updateSelection();\n return on(\"selectionchange\", updateSelection);\n}\nfunction initCustomElementObserver({\n doc,\n customElementCb\n}) {\n const win = doc.defaultView;\n if (!win || !win.customElements) return () => {\n };\n const restoreHandler = patch(\n win.customElements,\n \"define\",\n function(original) {\n return function(name, constructor, options) {\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}\nfunction mergeHooks(o, hooks) {\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) => {\n if (hooks.mutation) {\n hooks.mutation(...p);\n }\n mutationCb(...p);\n };\n o.mousemoveCb = (...p) => {\n if (hooks.mousemove) {\n hooks.mousemove(...p);\n }\n mousemoveCb(...p);\n };\n o.mouseInteractionCb = (...p) => {\n if (hooks.mouseInteraction) {\n hooks.mouseInteraction(...p);\n }\n mouseInteractionCb(...p);\n };\n o.scrollCb = (...p) => {\n if (hooks.scroll) {\n hooks.scroll(...p);\n }\n scrollCb(...p);\n };\n o.viewportResizeCb = (...p) => {\n if (hooks.viewportResize) {\n hooks.viewportResize(...p);\n }\n viewportResizeCb(...p);\n };\n o.inputCb = (...p) => {\n if (hooks.input) {\n hooks.input(...p);\n }\n inputCb(...p);\n };\n o.mediaInteractionCb = (...p) => {\n if (hooks.mediaInteaction) {\n hooks.mediaInteaction(...p);\n }\n mediaInteractionCb(...p);\n };\n o.styleSheetRuleCb = (...p) => {\n if (hooks.styleSheetRule) {\n hooks.styleSheetRule(...p);\n }\n styleSheetRuleCb(...p);\n };\n o.styleDeclarationCb = (...p) => {\n if (hooks.styleDeclaration) {\n hooks.styleDeclaration(...p);\n }\n styleDeclarationCb(...p);\n };\n o.canvasMutationCb = (...p) => {\n if (hooks.canvasMutation) {\n hooks.canvasMutation(...p);\n }\n canvasMutationCb(...p);\n };\n o.fontCb = (...p) => {\n if (hooks.font) {\n hooks.font(...p);\n }\n fontCb(...p);\n };\n o.selectionCb = (...p) => {\n if (hooks.selection) {\n hooks.selection(...p);\n }\n selectionCb(...p);\n };\n o.customElementCb = (...c) => {\n if (hooks.customElement) {\n hooks.customElement(...c);\n }\n customElementCb(...c);\n };\n}\nfunction initObservers(o, hooks = {}) {\n const currentWindow = o.doc.defaultView;\n if (!currentWindow) {\n return () => {\n };\n }\n mergeHooks(o, hooks);\n let mutationObserver;\n let mutationBuffer;\n if (o.recordDOM) {\n const result = initMutationObserver(o, o.doc);\n mutationObserver = result.observer;\n mutationBuffer = result.buffer;\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 let styleSheetObserver = () => {\n };\n let adoptedStyleSheetObserver = () => {\n };\n let styleDeclarationObserver = () => {\n };\n let fontObserver = () => {\n };\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 const pluginHandlers = [];\n for (const plugin of o.plugins) {\n pluginHandlers.push(\n plugin.observer(plugin.callback, currentWindow, plugin.options)\n );\n }\n return callbackWrapper(() => {\n if (mutationBuffer) {\n mutationBuffer.destroy();\n mutationBuffer.reset();\n const index2 = mutationBuffers.indexOf(mutationBuffer);\n if (index2 !== -1) {\n mutationBuffers.splice(index2, 1);\n }\n }\n mutationObserver == null ? void 0 : mutationObserver.disconnect();\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}\nfunction hasNestedCSSRule(prop) {\n return typeof window[prop] !== \"undefined\";\n}\nfunction canMonkeyPatchNestedCSSRule(prop) {\n return Boolean(\n typeof window[prop] !== \"undefined\" && // 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 && \"insertRule\" in window[prop].prototype && \"deleteRule\" in window[prop].prototype\n );\n}\nclass CrossOriginIframeMirror {\n constructor(generateIdFn) {\n __publicField(this, \"iframeIdToRemoteIdMap\", /* @__PURE__ */ new WeakMap());\n __publicField(this, \"iframeRemoteIdToIdMap\", /* @__PURE__ */ new WeakMap());\n this.generateIdFn = generateIdFn;\n }\n getId(iframe, remoteId, idToRemoteMap, remoteToIdMap) {\n const idToRemoteIdMap = idToRemoteMap || this.getIdToRemoteIdMap(iframe);\n const remoteIdToIdMap = remoteToIdMap || this.getRemoteIdToIdMap(iframe);\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 getIds(iframe, remoteId) {\n const idToRemoteIdMap = this.getIdToRemoteIdMap(iframe);\n const remoteIdToIdMap = this.getRemoteIdToIdMap(iframe);\n return remoteId.map(\n (id) => this.getId(iframe, id, idToRemoteIdMap, remoteIdToIdMap)\n );\n }\n getRemoteId(iframe, id, map) {\n const remoteIdToIdMap = map || this.getRemoteIdToIdMap(iframe);\n if (typeof id !== \"number\") return id;\n const remoteId = remoteIdToIdMap.get(id);\n if (!remoteId) return -1;\n return remoteId;\n }\n getRemoteIds(iframe, ids) {\n const remoteIdToIdMap = this.getRemoteIdToIdMap(iframe);\n return ids.map((id) => this.getRemoteId(iframe, id, remoteIdToIdMap));\n }\n reset(iframe) {\n if (!iframe) {\n this.iframeIdToRemoteIdMap = /* @__PURE__ */ new WeakMap();\n this.iframeRemoteIdToIdMap = /* @__PURE__ */ new WeakMap();\n return;\n }\n this.iframeIdToRemoteIdMap.delete(iframe);\n this.iframeRemoteIdToIdMap.delete(iframe);\n }\n getIdToRemoteIdMap(iframe) {\n let idToRemoteIdMap = this.iframeIdToRemoteIdMap.get(iframe);\n if (!idToRemoteIdMap) {\n idToRemoteIdMap = /* @__PURE__ */ new Map();\n this.iframeIdToRemoteIdMap.set(iframe, idToRemoteIdMap);\n }\n return idToRemoteIdMap;\n }\n getRemoteIdToIdMap(iframe) {\n let remoteIdToIdMap = this.iframeRemoteIdToIdMap.get(iframe);\n if (!remoteIdToIdMap) {\n remoteIdToIdMap = /* @__PURE__ */ new Map();\n this.iframeRemoteIdToIdMap.set(iframe, remoteIdToIdMap);\n }\n return remoteIdToIdMap;\n }\n}\nclass IframeManager {\n constructor(options) {\n __publicField(this, \"iframes\", /* @__PURE__ */ new WeakMap());\n __publicField(this, \"crossOriginIframeMap\", /* @__PURE__ */ new WeakMap());\n __publicField(this, \"crossOriginIframeMirror\", new CrossOriginIframeMirror(genId));\n __publicField(this, \"crossOriginIframeStyleMirror\");\n __publicField(this, \"crossOriginIframeRootIdMap\", /* @__PURE__ */ new WeakMap());\n __publicField(this, \"mirror\");\n __publicField(this, \"mutationCb\");\n __publicField(this, \"wrappedEmit\");\n __publicField(this, \"loadListener\");\n __publicField(this, \"pageHideListener\");\n __publicField(this, \"stylesheetManager\");\n __publicField(this, \"recordCrossOriginIframes\");\n __publicField(this, \"messageHandler\");\n // Strong Map — keys pin Windows; every entry must be deleted on detach.\n __publicField(this, \"nestedIframeListeners\", /* @__PURE__ */ new Map());\n // Originals captured per iframe so cleanup survives iframe.src swaps.\n __publicField(this, \"attachedWindows\", /* @__PURE__ */ new WeakMap());\n __publicField(this, \"attachedDocuments\", /* @__PURE__ */ new WeakMap());\n __publicField(this, \"attachedIframes\", /* @__PURE__ */ new Map());\n // Set per element — one iframe collects multiple disposers across loads.\n __publicField(this, \"loadListenerDisposers\", /* @__PURE__ */ new WeakMap());\n // Fallback for iframes removed before first load — mirror entry is gone\n // by then, but we still need the element to dispose its load listener.\n __publicField(this, \"iframeElementsById\", /* @__PURE__ */ new Map());\n // Set per element — same multi-load reasoning as loadListenerDisposers.\n __publicField(this, \"pageHideHandlers\", /* @__PURE__ */ new WeakMap());\n this.mutationCb = options.mutationCb;\n this.wrappedEmit = options.wrappedEmit;\n this.stylesheetManager = options.stylesheetManager;\n this.recordCrossOriginIframes = options.recordCrossOriginIframes;\n this.crossOriginIframeStyleMirror = new CrossOriginIframeMirror(\n this.stylesheetManager.styleMirror.generateId.bind(\n this.stylesheetManager.styleMirror\n )\n );\n this.mirror = options.mirror;\n this.messageHandler = this.handleMessage.bind(this);\n if (this.recordCrossOriginIframes) {\n window.addEventListener(\"message\", this.messageHandler);\n }\n }\n addIframe(iframeEl) {\n this.iframes.set(iframeEl, true);\n if (iframeEl.contentWindow)\n this.crossOriginIframeMap.set(iframeEl.contentWindow, iframeEl);\n }\n registerLoadListenerDisposer(iframeEl, disposer) {\n let bucket = this.loadListenerDisposers.get(iframeEl);\n if (!bucket) {\n bucket = /* @__PURE__ */ new Set();\n this.loadListenerDisposers.set(iframeEl, bucket);\n }\n bucket.add(disposer);\n const id = this.mirror.getId(iframeEl);\n if (id !== -1) this.iframeElementsById.set(id, iframeEl);\n }\n // Used by the record-loop to distinguish reparenting from removal.\n getIframeElementById(iframeId) {\n var _a2;\n return ((_a2 = this.attachedIframes.get(iframeId)) == null ? void 0 : _a2.element) ?? this.iframeElementsById.get(iframeId) ?? null;\n }\n // Drops the id mapping for a moved iframe; element-keyed state survives.\n forgetIframeId(iframeId) {\n this.attachedIframes.delete(iframeId);\n this.iframeElementsById.delete(iframeId);\n }\n disposeLoadListeners(iframeEl) {\n const bucket = this.loadListenerDisposers.get(iframeEl);\n if (!bucket) return;\n bucket.forEach((d) => callSafely(d));\n this.loadListenerDisposers.delete(iframeEl);\n }\n removePageHideListener(iframeEl) {\n const bucket = this.pageHideHandlers.get(iframeEl);\n if (!bucket) return;\n bucket.forEach(({ win, handler }) => {\n callSafely(() => win.removeEventListener(\"pagehide\", handler));\n });\n this.pageHideHandlers.delete(iframeEl);\n }\n addLoadListener(cb) {\n this.loadListener = cb;\n }\n addPageHideListener(cb) {\n this.pageHideListener = cb;\n }\n removeLoadListener() {\n this.loadListener = void 0;\n }\n trackIframeContent(iframeEl, content) {\n const iframeId = this.mirror.getId(iframeEl);\n this.attachedIframes.set(iframeId, { element: iframeEl, content });\n return iframeId;\n }\n attachIframe(iframeEl, childSn) {\n var _a2;\n const iframeId = this.trackIframeContent(iframeEl, childSn);\n if (iframeEl.contentDocument) {\n let docs = this.attachedDocuments.get(iframeEl);\n if (!docs) {\n docs = /* @__PURE__ */ new Set();\n this.attachedDocuments.set(iframeEl, docs);\n }\n docs.add(iframeEl.contentDocument);\n }\n this.mutationCb({\n adds: [\n {\n parentId: iframeId,\n nextId: null,\n node: childSn\n }\n ],\n removes: [],\n texts: [],\n attributes: [],\n isAttachIframe: true\n });\n const win = iframeEl.contentWindow;\n if (this.recordCrossOriginIframes && win && !this.nestedIframeListeners.has(win)) {\n const nestedHandler = this.handleMessage.bind(this);\n callSafely(() => {\n win.addEventListener(\"message\", nestedHandler);\n this.nestedIframeListeners.set(win, nestedHandler);\n let wins = this.attachedWindows.get(iframeEl);\n if (!wins) {\n wins = /* @__PURE__ */ new Set();\n this.attachedWindows.set(iframeEl, wins);\n }\n wins.add(win);\n });\n }\n callSafely(() => {\n const pageHideWindow = iframeEl.contentWindow;\n if (!pageHideWindow) return;\n let bucket = this.pageHideHandlers.get(iframeEl);\n if (bucket) {\n for (const entry of bucket) {\n if (entry.win === pageHideWindow) return;\n }\n }\n const handler = () => {\n var _a3;\n (_a3 = this.pageHideListener) == null ? void 0 : _a3.call(this, iframeEl);\n if (iframeEl.contentDocument) {\n this.mirror.removeNodeFromMap(iframeEl.contentDocument);\n }\n if (iframeEl.contentWindow) {\n this.crossOriginIframeMap.delete(iframeEl.contentWindow);\n }\n };\n pageHideWindow.addEventListener(\"pagehide\", handler);\n if (!bucket) {\n bucket = /* @__PURE__ */ new Set();\n this.pageHideHandlers.set(iframeEl, bucket);\n }\n bucket.add({ win: pageHideWindow, handler });\n });\n (_a2 = this.loadListener) == null ? void 0 : _a2.call(this, iframeEl);\n if (iframeEl.contentDocument && iframeEl.contentDocument.adoptedStyleSheets && iframeEl.contentDocument.adoptedStyleSheets.length > 0)\n this.stylesheetManager.adoptStyleSheets(\n iframeEl.contentDocument.adoptedStyleSheets,\n this.mirror.getId(iframeEl.contentDocument)\n );\n }\n handleMessage(message) {\n const crossOriginMessageEvent = message;\n if (crossOriginMessageEvent.data.type !== \"rrweb\" || // To filter out the rrweb messages which are forwarded by some sites.\n crossOriginMessageEvent.origin !== crossOriginMessageEvent.data.origin)\n return;\n const iframeSourceWindow = message.source;\n if (!iframeSourceWindow) return;\n const iframeEl = this.crossOriginIframeMap.get(message.source);\n if (!iframeEl) return;\n const transformedEvent = this.transformCrossOriginEvent(\n iframeEl,\n crossOriginMessageEvent.data.event\n );\n if (transformedEvent)\n this.wrappedEmit(\n transformedEvent,\n crossOriginMessageEvent.data.isCheckout\n );\n }\n transformCrossOriginEvent(iframeEl, e) {\n var _a2;\n switch (e.type) {\n case EventType.FullSnapshot: {\n this.crossOriginIframeMirror.reset(iframeEl);\n this.crossOriginIframeStyleMirror.reset(iframeEl);\n this.replaceIdOnNode(e.data.node, iframeEl);\n const rootId = e.data.node.id;\n this.crossOriginIframeRootIdMap.set(iframeEl, rootId);\n this.patchRootIdOnNode(e.data.node, rootId);\n this.trackIframeContent(iframeEl, e.data.node);\n return {\n timestamp: e.timestamp,\n type: EventType.IncrementalSnapshot,\n data: {\n source: IncrementalSource.Mutation,\n adds: [\n {\n parentId: this.mirror.getId(iframeEl),\n nextId: null,\n node: e.data.node\n }\n ],\n removes: [],\n texts: [],\n attributes: [],\n isAttachIframe: true\n }\n };\n }\n case EventType.Meta:\n case EventType.Load:\n case EventType.DomContentLoaded: {\n return false;\n }\n case EventType.Plugin: {\n return e;\n }\n case EventType.Custom: {\n this.replaceIds(\n e.data.payload,\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 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 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 (_a2 = e.data.styles) == null ? void 0 : _a2.forEach((style) => {\n this.replaceStyleIds(style, iframeEl, [\"styleId\"]);\n });\n return e;\n }\n }\n }\n }\n return false;\n }\n replace(iframeMirror, obj, iframeEl, keys) {\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]\n );\n } else {\n obj[key] = iframeMirror.getId(iframeEl, obj[key]);\n }\n }\n return obj;\n }\n replaceIds(obj, iframeEl, keys) {\n return this.replace(this.crossOriginIframeMirror, obj, iframeEl, keys);\n }\n replaceStyleIds(obj, iframeEl, keys) {\n return this.replace(this.crossOriginIframeStyleMirror, obj, iframeEl, keys);\n }\n replaceIdOnNode(node, iframeEl) {\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 patchRootIdOnNode(node, rootId) {\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 removeIframeById(iframeId) {\n const entry = this.attachedIframes.get(iframeId);\n const iframe = (entry == null ? void 0 : entry.element) || this.iframeElementsById.get(iframeId) || this.mirror.getNode(iframeId);\n this.iframeElementsById.delete(iframeId);\n if (iframe) {\n const win = iframe.contentWindow;\n const capturedWins = this.attachedWindows.get(iframe);\n if (capturedWins) {\n capturedWins.forEach((capturedWin) => {\n const handler = this.nestedIframeListeners.get(capturedWin);\n if (handler) {\n callSafely(\n () => capturedWin.removeEventListener(\"message\", handler)\n );\n this.nestedIframeListeners.delete(capturedWin);\n }\n this.crossOriginIframeMap.delete(capturedWin);\n });\n this.attachedWindows.delete(iframe);\n }\n if (win && this.nestedIframeListeners.has(win)) {\n const handler = this.nestedIframeListeners.get(win);\n callSafely(() => win.removeEventListener(\"message\", handler));\n this.nestedIframeListeners.delete(win);\n }\n if (win) {\n this.crossOriginIframeMap.delete(win);\n }\n this.iframes.delete(iframe);\n this.disposeLoadListeners(iframe);\n this.removePageHideListener(iframe);\n const capturedDocs = this.attachedDocuments.get(iframe);\n if (capturedDocs) {\n capturedDocs.forEach((doc) => {\n callSafely(() => this.mirror.removeNodeFromMap(doc));\n });\n callSafely(() => findAndRemoveIframeBuffer(iframe, capturedDocs));\n this.attachedDocuments.delete(iframe);\n }\n }\n if (entry) {\n this.attachedIframes.delete(iframeId);\n }\n }\n // Catches iframes removed inside a removed subtree (only the\n // ancestor's id appears in m.removes).\n cleanupDetachedIframes() {\n if (this.attachedIframes.size === 0) return;\n const orphaned = [];\n this.attachedIframes.forEach((_entry, iframeId) => {\n if (!this.mirror.has(iframeId)) {\n orphaned.push(iframeId);\n }\n });\n orphaned.forEach((iframeId) => this.removeIframeById(iframeId));\n }\n reattachIframes() {\n this.attachedIframes.forEach(({ content }, iframeId) => {\n if (!this.mirror.has(iframeId)) {\n this.attachedIframes.delete(iframeId);\n return;\n }\n this.mutationCb({\n adds: [\n {\n parentId: iframeId,\n nextId: null,\n node: content\n }\n ],\n removes: [],\n texts: [],\n attributes: [],\n isAttachIframe: true\n });\n });\n }\n destroy() {\n if (this.recordCrossOriginIframes) {\n window.removeEventListener(\"message\", this.messageHandler);\n }\n this.nestedIframeListeners.forEach((handler, contentWindow) => {\n callSafely(() => contentWindow.removeEventListener(\"message\", handler));\n });\n this.nestedIframeListeners.clear();\n const tracked = /* @__PURE__ */ new Set();\n this.iframeElementsById.forEach((el) => tracked.add(el));\n this.attachedIframes.forEach(({ element }) => tracked.add(element));\n tracked.forEach((iframe) => {\n this.disposeLoadListeners(iframe);\n this.removePageHideListener(iframe);\n });\n this.crossOriginIframeMirror.reset();\n this.crossOriginIframeStyleMirror.reset();\n this.attachedIframes.clear();\n this.crossOriginIframeMap = /* @__PURE__ */ new WeakMap();\n this.iframes = /* @__PURE__ */ new WeakMap();\n this.crossOriginIframeRootIdMap = /* @__PURE__ */ new WeakMap();\n this.loadListenerDisposers = /* @__PURE__ */ new WeakMap();\n this.pageHideHandlers = /* @__PURE__ */ new WeakMap();\n this.attachedDocuments = /* @__PURE__ */ new WeakMap();\n this.attachedWindows = /* @__PURE__ */ new WeakMap();\n this.iframeElementsById = /* @__PURE__ */ new Map();\n }\n}\nclass ShadowDomManager {\n constructor(options) {\n __publicField(this, \"shadowDoms\", /* @__PURE__ */ new WeakSet());\n __publicField(this, \"mutationCb\");\n __publicField(this, \"scrollCb\");\n __publicField(this, \"bypassOptions\");\n __publicField(this, \"mirror\");\n __publicField(this, \"restoreHandlers\", []);\n this.mutationCb = options.mutationCb;\n this.scrollCb = options.scrollCb;\n this.bypassOptions = options.bypassOptions;\n this.mirror = options.mirror;\n this.init();\n }\n init() {\n this.reset();\n this.patchAttachShadow(Element, document);\n }\n addShadowRoot(shadowRoot2, doc) {\n if (!isNativeShadowDom(shadowRoot2)) return;\n if (this.shadowDoms.has(shadowRoot2)) return;\n this.shadowDoms.add(shadowRoot2);\n const { observer, buffer } = initMutationObserver(\n {\n ...this.bypassOptions,\n doc,\n mutationCb: this.mutationCb,\n mirror: this.mirror,\n shadowDomManager: this\n },\n shadowRoot2\n );\n this.restoreHandlers.push(() => {\n observer.disconnect();\n buffer.destroy();\n buffer.releaseCanvasManager();\n const index2 = mutationBuffers.indexOf(buffer);\n if (index2 !== -1) {\n mutationBuffers.splice(index2, 1);\n }\n });\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: shadowRoot2,\n mirror: this.mirror\n })\n );\n setTimeout(() => {\n if (shadowRoot2.adoptedStyleSheets && shadowRoot2.adoptedStyleSheets.length > 0)\n this.bypassOptions.stylesheetManager.adoptStyleSheets(\n shadowRoot2.adoptedStyleSheets,\n this.mirror.getId(index.host(shadowRoot2))\n );\n this.restoreHandlers.push(\n initAdoptedStyleSheetObserver(\n {\n mirror: this.mirror,\n stylesheetManager: this.bypassOptions.stylesheetManager\n },\n shadowRoot2\n )\n );\n }, 0);\n }\n /**\n * Monkey patch 'attachShadow' of an IFrameElement to observe newly added shadow doms.\n */\n observeAttachShadow(iframeElement) {\n if (!iframeElement.contentWindow || !iframeElement.contentDocument) return;\n this.patchAttachShadow(\n iframeElement.contentWindow.Element,\n iframeElement.contentDocument\n );\n }\n /**\n * Patch 'attachShadow' to observe newly added shadow doms.\n */\n patchAttachShadow(element, doc) {\n const manager = this;\n this.restoreHandlers.push(\n patch(\n element.prototype,\n \"attachShadow\",\n function(original) {\n return function(option) {\n const sRoot = original.call(this, option);\n const shadowRootEl = index.shadowRoot(this);\n if (shadowRootEl && inDom(this))\n manager.addShadowRoot(shadowRootEl, doc);\n return sRoot;\n };\n }\n )\n );\n }\n reset() {\n this.restoreHandlers.forEach((handler) => {\n try {\n handler();\n } catch (e) {\n }\n });\n this.restoreHandlers = [];\n this.shadowDoms = /* @__PURE__ */ new WeakSet();\n }\n}\nvar chars = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";\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 } else if (len % 3 === 1) {\n base64 = base64.substring(0, base64.length - 2) + \"==\";\n }\n return base64;\n};\nconst canvasVarMap = /* @__PURE__ */ new Map();\nfunction variableListFor(ctx, ctor) {\n let contextMap = canvasVarMap.get(ctx);\n if (!contextMap) {\n contextMap = /* @__PURE__ */ new Map();\n canvasVarMap.set(ctx, contextMap);\n }\n if (!contextMap.has(ctor)) {\n contextMap.set(ctor, []);\n }\n return contextMap.get(ctor);\n}\nconst saveWebGLVar = (value, win, ctx) => {\n if (!value || !(isInstanceOfWebGLObject(value, win) || typeof value === \"object\"))\n return;\n const name = value.constructor.name;\n const list = variableListFor(ctx, name);\n let index2 = list.indexOf(value);\n if (index2 === -1) {\n index2 = list.length;\n list.push(value);\n }\n return index2;\n};\nfunction serializeArg(value, win, ctx, dataURLOptions) {\n if (value instanceof Array) {\n return value.map((arg) => serializeArg(arg, win, ctx, dataURLOptions));\n } else if (value === null) {\n return value;\n } else if (value instanceof Float32Array || value instanceof Float64Array || value instanceof Int32Array || value instanceof Uint32Array || value instanceof Uint8Array || value instanceof Uint16Array || value instanceof Int16Array || value instanceof Int8Array || value instanceof Uint8ClampedArray) {\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;\n const base64 = encode(value);\n return {\n rr_type: name,\n base64\n };\n } else if (value instanceof DataView) {\n const name = value.constructor.name;\n return {\n rr_type: name,\n args: [\n serializeArg(value.buffer, win, ctx, dataURLOptions),\n value.byteOffset,\n value.byteLength\n ]\n };\n } else if (value instanceof HTMLImageElement) {\n const name = value.constructor.name;\n const { src } = value;\n return {\n rr_type: name,\n src\n };\n } else if (value instanceof HTMLCanvasElement) {\n const name = \"HTMLImageElement\";\n const src = value.toDataURL(dataURLOptions.type, dataURLOptions.quality);\n return {\n rr_type: name,\n src\n };\n } else if (value instanceof ImageData) {\n const name = value.constructor.name;\n return {\n rr_type: name,\n args: [\n serializeArg(value.data, win, ctx, dataURLOptions),\n value.width,\n value.height\n ]\n };\n } else if (isInstanceOfWebGLObject(value, win) || typeof value === \"object\") {\n const name = value.constructor.name;\n const index2 = saveWebGLVar(value, win, ctx);\n return {\n rr_type: name,\n index: index2\n };\n }\n return value;\n}\nconst serializeArgs = (args, win, ctx, dataURLOptions) => {\n return args.map((arg) => serializeArg(arg, win, ctx, dataURLOptions));\n};\nconst isInstanceOfWebGLObject = (value, win) => {\n const webGLConstructorNames = [\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) => typeof win[name] === \"function\"\n );\n return Boolean(\n supportedWebGLConstructorNames.find(\n (name) => value instanceof win[name]\n )\n );\n};\nfunction initCanvas2DMutationObserver(cb, win, blockClass, blockSelector, dataURLOptions) {\n const handlers = [];\n const props2D = Object.getOwnPropertyNames(\n win.CanvasRenderingContext2D.prototype\n );\n for (const prop of props2D) {\n try {\n if (typeof win.CanvasRenderingContext2D.prototype[prop] !== \"function\") {\n continue;\n }\n const restoreHandler = patch(\n win.CanvasRenderingContext2D.prototype,\n prop,\n function(original) {\n return function(...args) {\n if (!isBlocked(this.canvas, blockClass, blockSelector, true)) {\n setTimeout(() => {\n const recordArgs = serializeArgs(\n args,\n win,\n this,\n dataURLOptions\n );\n cb(this.canvas, {\n type: CanvasContext[\"2D\"],\n property: prop,\n args: recordArgs\n });\n }, 0);\n }\n return original.apply(this, args);\n };\n }\n );\n handlers.push(restoreHandler);\n } catch {\n const hookHandler = hookSetter(\n win.CanvasRenderingContext2D.prototype,\n prop,\n {\n set(v) {\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}\nconst WEBGL_CONTEXT_NAMES = [\"webgl\", \"webgl2\"];\nfunction getNormalizedContextName(contextType) {\n return contextType === \"experimental-webgl\" ? \"webgl\" : contextType;\n}\nfunction getRequiredWebGPUTextureUsage(win) {\n const textureUsage = win.GPUTextureUsage;\n if (!textureUsage) {\n return null;\n }\n return textureUsage.COPY_SRC | textureUsage.RENDER_ATTACHMENT;\n}\nfunction getCanvasFromWebGPUContext(context) {\n const { canvas } = context;\n if (!canvas || typeof canvas !== \"object\") {\n return null;\n }\n return canvas;\n}\nfunction isCanvasNode(canvas) {\n return \"nodeType\" in canvas;\n}\nfunction initCanvasWebGPUContextObserver(win, blockClass, blockSelector) {\n const GPUCanvasContext = win.GPUCanvasContext;\n if (!(GPUCanvasContext == null ? void 0 : GPUCanvasContext.prototype) || typeof GPUCanvasContext.prototype.configure !== \"function\") {\n return;\n }\n return patch(\n GPUCanvasContext.prototype,\n \"configure\",\n function(original) {\n return function(configuration) {\n const canvas = getCanvasFromWebGPUContext(this);\n if (!canvas || isCanvasNode(canvas) && isBlocked(canvas, blockClass, blockSelector, true)) {\n return original.call(this, configuration);\n }\n if (isCanvasNode(canvas) && !(\"__context\" in canvas)) {\n canvas.__context = \"webgpu\";\n }\n const requiredUsage = getRequiredWebGPUTextureUsage(win);\n if (requiredUsage === null || !configuration) {\n return original.call(this, configuration);\n }\n return original.call(this, {\n ...configuration,\n // WebGPU does not implicitly keep RENDER_ATTACHMENT when usage is set,\n // so include both flags needed for drawing and snapshot reads.\n usage: typeof configuration.usage === \"number\" ? configuration.usage | requiredUsage : requiredUsage\n });\n };\n }\n );\n}\nfunction initCanvasContextObserver(win, blockClass, blockSelector, setPreserveDrawingBufferToTrue) {\n const handlers = [];\n try {\n if (setPreserveDrawingBufferToTrue) {\n const restoreWebGPUConfigureHandler = initCanvasWebGPUContextObserver(\n win,\n blockClass,\n blockSelector\n );\n if (restoreWebGPUConfigureHandler) {\n handlers.push(restoreWebGPUConfigureHandler);\n }\n }\n const restoreHandler = patch(\n win.HTMLCanvasElement.prototype,\n \"getContext\",\n function(original) {\n return function(contextType, ...args) {\n const ctxName = getNormalizedContextName(contextType);\n if (!isBlocked(this, blockClass, blockSelector, true)) {\n if (!(\"__context\" in this)) this.__context = ctxName;\n if (setPreserveDrawingBufferToTrue && WEBGL_CONTEXT_NAMES.includes(ctxName)) {\n if (args[0] && typeof args[0] === \"object\") {\n const contextAttributes = args[0];\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}\nfunction patchGLPrototype(prototype, type, cb, blockClass, blockSelector, win, dataURLOptions) {\n const handlers = [];\n const props = Object.getOwnPropertyNames(prototype);\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 continue;\n }\n try {\n if (typeof prototype[prop] !== \"function\") {\n continue;\n }\n const restoreHandler = patch(\n prototype,\n prop,\n function(original) {\n return function(...args) {\n const result = original.apply(this, args);\n saveWebGLVar(result, win, this);\n if (\"tagName\" in this.canvas && !isBlocked(this.canvas, blockClass, blockSelector, true)) {\n const recordArgs = serializeArgs(args, win, this, dataURLOptions);\n const mutation = {\n type,\n property: prop,\n args: recordArgs\n };\n cb(this.canvas, mutation);\n }\n return result;\n };\n }\n );\n handlers.push(restoreHandler);\n } catch {\n const hookHandler = hookSetter(prototype, prop, {\n set(v) {\n cb(this.canvas, {\n type,\n property: prop,\n args: [v],\n setter: true\n });\n }\n });\n handlers.push(hookHandler);\n }\n }\n return handlers;\n}\nfunction initCanvasWebGLMutationObserver(cb, win, blockClass, blockSelector, dataURLOptions) {\n const handlers = [];\n if (typeof win.WebGLRenderingContext !== \"undefined\") {\n handlers.push(\n ...patchGLPrototype(\n win.WebGLRenderingContext.prototype,\n CanvasContext.WebGL,\n cb,\n blockClass,\n blockSelector,\n win,\n dataURLOptions\n )\n );\n }\n if (typeof win.WebGL2RenderingContext !== \"undefined\") {\n handlers.push(\n ...patchGLPrototype(\n win.WebGL2RenderingContext.prototype,\n CanvasContext.WebGL2,\n cb,\n blockClass,\n blockSelector,\n win,\n dataURLOptions\n )\n );\n }\n return () => {\n handlers.forEach((h) => h());\n };\n}\nconst jsContent = '(function() {\\n \"use strict\";\\n var chars = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";\\n var lookup = typeof Uint8Array === \"undefined\" ? [] : new Uint8Array(256);\\n for (var i = 0; i < chars.length; i++) {\\n lookup[chars.charCodeAt(i)] = i;\\n }\\n var encode = function(arraybuffer) {\\n var bytes = new Uint8Array(arraybuffer), i2, len = bytes.length, base64 = \"\";\\n for (i2 = 0; i2 < len; i2 += 3) {\\n base64 += chars[bytes[i2] >> 2];\\n base64 += chars[(bytes[i2] & 3) << 4 | bytes[i2 + 1] >> 4];\\n base64 += chars[(bytes[i2 + 1] & 15) << 2 | bytes[i2 + 2] >> 6];\\n base64 += chars[bytes[i2 + 2] & 63];\\n }\\n if (len % 3 === 2) {\\n base64 = base64.substring(0, base64.length - 1) + \"=\";\\n } else if (len % 3 === 1) {\\n base64 = base64.substring(0, base64.length - 2) + \"==\";\\n }\\n return base64;\\n };\\n const lastFingerprintMap = /* @__PURE__ */ new Map();\\n const transparentBlobMap = /* @__PURE__ */ new Map();\\n function fnv1aHash(buffer) {\\n const view = new Uint8Array(buffer);\\n let hash = 2166136261;\\n for (let i2 = 0; i2 < view.length; i2++) {\\n hash ^= view[i2];\\n hash = hash * 16777619 | 0;\\n }\\n return (hash >>> 0).toString(16);\\n }\\n async function getTransparentBlobFor(width, height, dataURLOptions) {\\n const id = `${width}-${height}`;\\n if (\"OffscreenCanvas\" in globalThis) {\\n if (transparentBlobMap.has(id)) return transparentBlobMap.get(id);\\n const offscreen = new OffscreenCanvas(width, height);\\n offscreen.getContext(\"2d\");\\n const blob = await offscreen.convertToBlob(dataURLOptions);\\n const arrayBuffer = await blob.arrayBuffer();\\n const base64 = encode(arrayBuffer);\\n transparentBlobMap.set(id, base64);\\n return base64;\\n } else {\\n return \"\";\\n }\\n }\\n const worker = self;\\n let reusableCanvas = null;\\n let reusableCtx = null;\\n worker.onmessage = async function(e) {\\n if (\"OffscreenCanvas\" in globalThis) {\\n const { id, bitmap, width, height, displayWidth, displayHeight, dataURLOptions } = e.data;\\n try {\\n const transparentBase64 = getTransparentBlobFor(\\n width,\\n height,\\n dataURLOptions\\n );\\n if (!reusableCanvas || reusableCanvas.width !== width || reusableCanvas.height !== height) {\\n reusableCanvas = new OffscreenCanvas(width, height);\\n reusableCtx = reusableCanvas.getContext(\"2d\");\\n }\\n reusableCtx.clearRect(0, 0, width, height);\\n reusableCtx.drawImage(bitmap, 0, 0);\\n bitmap.close();\\n const blob = await reusableCanvas.convertToBlob(dataURLOptions);\\n const type = blob.type;\\n const arrayBuffer = await blob.arrayBuffer();\\n const fingerprint = fnv1aHash(arrayBuffer);\\n if (!lastFingerprintMap.has(id)) {\\n const base642 = encode(arrayBuffer);\\n if (await transparentBase64 === base642) {\\n lastFingerprintMap.set(id, fingerprint);\\n return worker.postMessage({ id });\\n }\\n lastFingerprintMap.set(id, fingerprint);\\n worker.postMessage({ id, type, base64: base642, displayWidth, displayHeight });\\n return;\\n }\\n if (lastFingerprintMap.get(id) === fingerprint)\\n return worker.postMessage({ id });\\n const base64 = encode(arrayBuffer);\\n worker.postMessage({ id, type, base64, displayWidth, displayHeight });\\n lastFingerprintMap.set(id, fingerprint);\\n } catch {\\n worker.postMessage({ id });\\n }\\n } else {\\n e.data.bitmap.close();\\n return worker.postMessage({ id: e.data.id });\\n }\\n };\\n})();\\n//# sourceMappingURL=image-bitmap-data-url-worker-CSpkoNCs.js.map\\n';\nconst blob = typeof self !== \"undefined\" && self.Blob && new Blob([jsContent], { type: \"text/javascript;charset=utf-8\" });\nfunction WorkerWrapper(options) {\n let objURL;\n try {\n objURL = blob && (self.URL || self.webkitURL).createObjectURL(blob);\n if (!objURL) throw \"\";\n const worker = new Worker(objURL, {\n name: options == null ? void 0 : options.name\n });\n worker.addEventListener(\"error\", () => {\n (self.URL || self.webkitURL).revokeObjectURL(objURL);\n });\n return worker;\n } catch (e) {\n return new Worker(\n \"data:text/javascript;charset=utf-8,\" + encodeURIComponent(jsContent),\n {\n name: options == null ? void 0 : options.name\n }\n );\n } finally {\n objURL && (self.URL || self.webkitURL).revokeObjectURL(objURL);\n }\n}\nconst MIN_CANVAS_RESOLUTION_SCALE = 0.1;\nclass CanvasManager {\n constructor(options) {\n __publicField(this, \"pendingCanvasMutations\", /* @__PURE__ */ new Map());\n __publicField(this, \"rafStamps\", { latestId: 0, invokeId: null });\n __publicField(this, \"mirror\");\n __publicField(this, \"mutationCb\");\n __publicField(this, \"resetObservers\");\n __publicField(this, \"frozen\", false);\n __publicField(this, \"locked\", false);\n __publicField(this, \"rafIdTimestamp\", null);\n __publicField(this, \"rafIdFlush\", null);\n __publicField(this, \"refCount\", 0);\n __publicField(this, \"torndown\", false);\n __publicField(this, \"processMutation\", (target, mutation) => {\n const newFrame = this.rafStamps.invokeId && this.rafStamps.latestId !== this.rafStamps.invokeId;\n if (newFrame || !this.rafStamps.invokeId)\n this.rafStamps.invokeId = this.rafStamps.latestId;\n if (!this.pendingCanvasMutations.has(target)) {\n this.pendingCanvasMutations.set(target, []);\n }\n this.pendingCanvasMutations.get(target).push(mutation);\n });\n const {\n sampling = \"all\",\n win,\n blockClass,\n blockSelector,\n recordCanvas,\n dataURLOptions,\n resolutionScale\n } = options;\n this.mutationCb = options.mutationCb;\n this.mirror = options.mirror;\n if (recordCanvas && sampling === \"all\")\n this.initCanvasMutationObserver(\n win,\n blockClass,\n blockSelector,\n dataURLOptions\n );\n if (recordCanvas && typeof sampling === \"number\")\n this.initCanvasFPSObserver(sampling, win, blockClass, blockSelector, {\n dataURLOptions,\n resolutionScale\n });\n }\n // Shared by the main document and every iframe/shadow-root observer, so reference-count\n // teardown: a single root cleaning up must not unpatch getContext / stop the FPS loop globally.\n acquire() {\n this.refCount += 1;\n }\n reset() {\n if (this.refCount > 0) {\n this.refCount -= 1;\n }\n if (this.refCount > 0) {\n return;\n }\n this.teardown();\n }\n teardown() {\n if (this.torndown) {\n return;\n }\n this.torndown = true;\n this.pendingCanvasMutations.clear();\n this.resetObservers && this.resetObservers();\n if (this.rafIdTimestamp !== null) {\n cancelAnimationFrame(this.rafIdTimestamp);\n this.rafIdTimestamp = null;\n }\n if (this.rafIdFlush !== null) {\n cancelAnimationFrame(this.rafIdFlush);\n this.rafIdFlush = null;\n }\n }\n freeze() {\n this.frozen = true;\n }\n unfreeze() {\n this.frozen = false;\n }\n lock() {\n this.locked = true;\n }\n unlock() {\n this.locked = false;\n }\n initCanvasFPSObserver(fps, win, blockClass, blockSelector, options) {\n if (!(\"OffscreenCanvas\" in win)) {\n return;\n }\n const scale = typeof options.resolutionScale === \"number\" && Number.isFinite(options.resolutionScale) ? Math.min(\n 1,\n Math.max(MIN_CANVAS_RESOLUTION_SCALE, options.resolutionScale)\n ) : 1;\n const canvasContextReset = initCanvasContextObserver(\n win,\n blockClass,\n blockSelector,\n true\n );\n const snapshotInProgressMap = /* @__PURE__ */ new Map();\n const worker = new WorkerWrapper();\n worker.onmessage = (e) => {\n const { id } = e.data;\n snapshotInProgressMap.set(id, false);\n if (!(\"base64\" in e.data)) return;\n const { base64, type, displayWidth, displayHeight } = e.data;\n const dw = displayWidth;\n const dh = displayHeight;\n this.mutationCb({\n id,\n type: CanvasContext[\"2D\"],\n commands: [\n {\n property: \"clearRect\",\n // wipe canvas\n args: [0, 0, dw, dh]\n },\n {\n property: \"drawImage\",\n // draws (semi-transparent) image, stretched to display size\n args: [\n {\n rr_type: \"ImageBitmap\",\n args: [\n {\n rr_type: \"Blob\",\n data: [{ rr_type: \"ArrayBuffer\", base64 }],\n type\n }\n ]\n },\n 0,\n 0,\n dw,\n dh\n ]\n }\n ],\n displayWidth: dw,\n displayHeight: dh\n });\n };\n const timeBetweenSnapshots = 1e3 / fps;\n let lastSnapshotTime = 0;\n let rafId;\n const getCanvas = () => {\n const matchedCanvas = [];\n const searchCanvas = (haystack) => {\n try {\n haystack.querySelectorAll(\"canvas\").forEach((canvas) => {\n if (!isBlocked(canvas, blockClass, blockSelector, true)) {\n matchedCanvas.push(canvas);\n }\n });\n haystack.querySelectorAll(\"*\").forEach((elem) => {\n if (elem.shadowRoot) {\n searchCanvas(elem.shadowRoot);\n }\n });\n } catch {\n }\n };\n searchCanvas(win.document);\n return matchedCanvas;\n };\n const takeCanvasSnapshots = (timestamp) => {\n if (lastSnapshotTime && timestamp - lastSnapshotTime < timeBetweenSnapshots) {\n rafId = requestAnimationFrame(takeCanvasSnapshots);\n return;\n }\n lastSnapshotTime = timestamp;\n getCanvas().forEach(async (canvas) => {\n var _a2, _b;\n const id = this.mirror.getId(canvas);\n if (snapshotInProgressMap.get(id)) return;\n if (canvas.width === 0 || canvas.height === 0) return;\n snapshotInProgressMap.set(id, true);\n try {\n if ([\"webgl\", \"webgl2\"].includes(canvas.__context)) {\n const context = canvas.getContext(\n canvas.__context\n );\n if ((_a2 = context == null ? void 0 : context.isContextLost) == null ? void 0 : _a2.call(context)) {\n snapshotInProgressMap.set(id, false);\n return;\n }\n if (((_b = context == null ? void 0 : context.getContextAttributes()) == null ? void 0 : _b.preserveDrawingBuffer) === false) {\n context.clear(context.COLOR_BUFFER_BIT);\n }\n }\n const displayWidth = canvas.clientWidth || canvas.width;\n const displayHeight = canvas.clientHeight || canvas.height;\n const captureWidth = Math.max(1, Math.round(displayWidth * scale));\n const captureHeight = Math.max(1, Math.round(displayHeight * scale));\n const bitmap = await createImageBitmap(\n canvas,\n // only ask for a quality resampling filter when we're actually downscaling;\n // at full resolution this keeps capture identical to before.\n scale < 1 ? {\n resizeWidth: captureWidth,\n resizeHeight: captureHeight,\n resizeQuality: \"medium\"\n } : { resizeWidth: captureWidth, resizeHeight: captureHeight }\n );\n worker.postMessage(\n {\n id,\n bitmap,\n width: captureWidth,\n height: captureHeight,\n displayWidth,\n displayHeight,\n dataURLOptions: options.dataURLOptions\n },\n [bitmap]\n );\n } catch {\n snapshotInProgressMap.set(id, false);\n }\n });\n rafId = requestAnimationFrame(takeCanvasSnapshots);\n };\n rafId = requestAnimationFrame(takeCanvasSnapshots);\n this.resetObservers = () => {\n canvasContextReset();\n cancelAnimationFrame(rafId);\n };\n }\n initCanvasMutationObserver(win, blockClass, blockSelector, dataURLOptions) {\n this.startRAFTimestamping();\n this.startPendingCanvasMutationFlusher();\n const canvasContextReset = initCanvasContextObserver(\n win,\n blockClass,\n blockSelector,\n false\n );\n const canvas2DReset = initCanvas2DMutationObserver(\n this.processMutation.bind(this),\n win,\n blockClass,\n blockSelector,\n dataURLOptions\n );\n const canvasWebGL1and2Reset = initCanvasWebGLMutationObserver(\n this.processMutation.bind(this),\n win,\n blockClass,\n blockSelector,\n dataURLOptions\n );\n this.resetObservers = () => {\n canvasContextReset();\n canvas2DReset();\n canvasWebGL1and2Reset();\n };\n }\n startPendingCanvasMutationFlusher() {\n this.rafIdFlush = requestAnimationFrame(\n () => this.flushPendingCanvasMutations()\n );\n }\n startRAFTimestamping() {\n const setLatestRAFTimestamp = (timestamp) => {\n this.rafStamps.latestId = timestamp;\n this.rafIdTimestamp = requestAnimationFrame(setLatestRAFTimestamp);\n };\n this.rafIdTimestamp = requestAnimationFrame(setLatestRAFTimestamp);\n }\n flushPendingCanvasMutations() {\n this.pendingCanvasMutations.forEach(\n (_values, canvas) => {\n const id = this.mirror.getId(canvas);\n this.flushPendingCanvasMutationFor(canvas, id);\n }\n );\n this.rafIdFlush = requestAnimationFrame(\n () => this.flushPendingCanvasMutations()\n );\n }\n flushPendingCanvasMutationFor(canvas, id) {\n if (this.frozen || this.locked) {\n return;\n }\n const valuesWithType = this.pendingCanvasMutations.get(canvas);\n if (!valuesWithType || id === -1) return;\n const values = valuesWithType.map((value) => {\n const { type: type2, ...rest } = value;\n return rest;\n });\n const { type } = valuesWithType[0];\n this.mutationCb({ id, type, commands: values });\n this.pendingCanvasMutations.delete(canvas);\n }\n}\nclass StylesheetManager {\n constructor(options) {\n __publicField(this, \"trackedLinkElements\", /* @__PURE__ */ new WeakSet());\n __publicField(this, \"mutationCb\");\n __publicField(this, \"adoptedStyleSheetCb\");\n __publicField(this, \"styleMirror\", new StyleSheetMirror());\n this.mutationCb = options.mutationCb;\n this.adoptedStyleSheetCb = options.adoptedStyleSheetCb;\n }\n attachLinkElement(linkEl, childSn) {\n if (\"_cssText\" in childSn.attributes)\n this.mutationCb({\n adds: [],\n removes: [],\n texts: [],\n attributes: [\n {\n id: childSn.id,\n attributes: childSn.attributes\n }\n ]\n });\n this.trackLinkElement(linkEl);\n }\n trackLinkElement(linkEl) {\n if (this.trackedLinkElements.has(linkEl)) return;\n this.trackedLinkElements.add(linkEl);\n this.trackStylesheetInLinkElement(linkEl);\n }\n adoptStyleSheets(sheets, hostId) {\n if (sheets.length === 0) return;\n const adoptedStyleSheetData = {\n id: hostId,\n styleIds: []\n };\n const 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, index2) => ({\n rule: stringifyRule(r, sheet.href),\n index: index2\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 reset() {\n this.styleMirror.reset();\n this.trackedLinkElements = /* @__PURE__ */ new WeakSet();\n resetStylesheetLoadTracking();\n }\n // TODO: take snapshot on stylesheet reload by applying event listener\n trackStylesheetInLinkElement(_linkEl) {\n }\n}\nclass ProcessedNodeManager {\n constructor() {\n __publicField(this, \"nodeMap\", /* @__PURE__ */ new WeakMap());\n __publicField(this, \"active\", false);\n }\n inOtherBuffer(node, thisBuffer) {\n const buffers = this.nodeMap.get(node);\n return buffers && Array.from(buffers).some((buffer) => buffer !== thisBuffer);\n }\n add(node, buffer) {\n if (!this.active) {\n this.active = true;\n requestAnimationFrame(() => {\n this.nodeMap = /* @__PURE__ */ new WeakMap();\n this.active = false;\n });\n }\n this.nodeMap.set(node, (this.nodeMap.get(node) || /* @__PURE__ */ new Set()).add(buffer));\n }\n destroy() {\n }\n}\nlet wrappedEmit;\nlet takeFullSnapshot;\nlet canvasManager;\nlet recording = false;\ntry {\n if (Array.from([1], (x) => x * 2)[0] !== 2) {\n const cleanFrame = document.createElement(\"iframe\");\n document.body.appendChild(cleanFrame);\n Array.from = ((_a = cleanFrame.contentWindow) == null ? void 0 : _a.Array.from) || Array.from;\n document.body.removeChild(cleanFrame);\n }\n} catch (err) {\n console.debug(\"Unable to override Array.from\", err);\n}\nconst mirror = createMirror();\nfunction record(options = {}) {\n const {\n emit,\n checkoutEveryNms,\n checkoutEveryNth,\n blockClass = \"rr-block\",\n blockSelector = null,\n ignoreClass = \"rr-ignore\",\n ignoreSelector = null,\n maskTextClass = \"rr-mask\",\n maskTextSelector = null,\n inlineStylesheet = true,\n maskAllInputs,\n maskInputOptions: _maskInputOptions,\n slimDOMOptions: _slimDOMOptions,\n maskInputFn,\n maskTextFn,\n hooks,\n packFn,\n sampling = {},\n dataURLOptions: _dataURLOptions = {},\n canvasResolutionScale,\n mousemoveWait,\n recordDOM = true,\n recordCanvas = false,\n recordCrossOriginIframes = false,\n recordAfter = options.recordAfter === \"DOMContentLoaded\" ? options.recordAfter : \"load\",\n userTriggeredOnInput = false,\n collectFonts = false,\n inlineImages = false,\n plugins,\n keepIframeSrcFn = () => false,\n ignoreCSSAttributes = /* @__PURE__ */ new Set([]),\n errorHandler: errorHandler2\n } = options;\n registerErrorHandler(errorHandler2);\n const dataURLOptions = {\n type: \"image/webp\",\n quality: 0.4,\n maxBase64ImageLength: 1048576,\n ..._dataURLOptions\n };\n const inEmittingFrame = recordCrossOriginIframes ? window.parent === window : true;\n let passEmitsToParent = false;\n if (!inEmittingFrame) {\n try {\n if (window.parent.document) {\n passEmitsToParent = false;\n }\n } catch (e) {\n passEmitsToParent = true;\n }\n }\n if (inEmittingFrame && !emit) {\n throw new Error(\"emit function is required\");\n }\n if (!inEmittingFrame && !passEmitsToParent) {\n return () => {\n };\n }\n if (mousemoveWait !== void 0 && sampling.mousemove === void 0) {\n sampling.mousemove = mousemoveWait;\n }\n mirror.reset();\n const maskInputOptions = maskAllInputs === true ? {\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 } : _maskInputOptions !== void 0 ? _maskInputOptions : { password: true };\n const slimDOMOptions = slimDOMDefaults(\n _slimDOMOptions !== void 0 ? _slimDOMOptions : false\n );\n polyfill();\n let lastFullSnapshotEvent;\n let incrementalSnapshotCount = 0;\n const iframeObserverCleanups = /* @__PURE__ */ new Map();\n let runAndDetachIframeCleanup;\n let cleanupDetachedIframeObservers;\n const eventProcessor = (e) => {\n for (const plugin of plugins || []) {\n if (plugin.eventProcessor) {\n e = plugin.eventProcessor(e);\n }\n }\n if (packFn && // Disable packing events which will be emitted to parent frames.\n !passEmitsToParent) {\n e = packFn(e);\n }\n return e;\n };\n wrappedEmit = (r, isCheckout) => {\n var _a2;\n const e = r;\n e.timestamp = nowTimestamp();\n if (((_a2 = mutationBuffers[0]) == null ? void 0 : _a2.isFrozen()) && e.type !== EventType.FullSnapshot && !(e.type === EventType.IncrementalSnapshot && e.data.source === IncrementalSource.Mutation)) {\n mutationBuffers.forEach((buf) => buf.unfreeze());\n }\n if (inEmittingFrame) {\n emit == null ? void 0 : emit(eventProcessor(e), isCheckout);\n } else if (passEmitsToParent) {\n const message = {\n type: \"rrweb\",\n event: eventProcessor(e),\n origin: window.location.origin,\n isCheckout\n };\n window.parent.postMessage(message, \"*\");\n }\n if (e.type === EventType.FullSnapshot) {\n lastFullSnapshotEvent = e;\n incrementalSnapshotCount = 0;\n } else if (e.type === EventType.IncrementalSnapshot) {\n if (e.data.source === IncrementalSource.Mutation && e.data.isAttachIframe) {\n return;\n }\n incrementalSnapshotCount++;\n const exceedCount = checkoutEveryNth && incrementalSnapshotCount >= checkoutEveryNth;\n const exceedTime = checkoutEveryNms && e.timestamp - lastFullSnapshotEvent.timestamp > checkoutEveryNms;\n if (exceedCount || exceedTime) {\n takeFullSnapshot(true);\n }\n }\n };\n const wrappedMutationEmit = (m) => {\n if (m.removes && m.removes.length > 0) {\n const addedIds = m.adds.length > 0 ? new Set(m.adds.map((add) => add.node.id)) : null;\n const addedIframeElements = /* @__PURE__ */ new Set();\n if (m.adds.length > 0) {\n for (const add of m.adds) {\n const node = mirror.getNode(add.node.id);\n if (node && node.nodeName === \"IFRAME\") {\n addedIframeElements.add(node);\n }\n }\n }\n m.removes.forEach(({ id }) => {\n if (addedIds && addedIds.has(id)) return;\n const removedIframe = iframeManager.getIframeElementById(id);\n if (removedIframe && addedIframeElements.has(removedIframe)) {\n iframeManager.forgetIframeId(id);\n return;\n }\n runAndDetachIframeCleanup == null ? void 0 : runAndDetachIframeCleanup(id);\n iframeManager.removeIframeById(id);\n });\n cleanupDetachedIframeObservers == null ? void 0 : cleanupDetachedIframeObservers();\n iframeManager.cleanupDetachedIframes();\n }\n wrappedEmit({\n type: EventType.IncrementalSnapshot,\n data: {\n source: IncrementalSource.Mutation,\n ...m\n }\n });\n };\n const wrappedScrollEmit = (p) => wrappedEmit({\n type: EventType.IncrementalSnapshot,\n data: {\n source: IncrementalSource.Scroll,\n ...p\n }\n });\n const wrappedCanvasMutationEmit = (p) => wrappedEmit({\n type: EventType.IncrementalSnapshot,\n data: {\n source: IncrementalSource.CanvasMutation,\n ...p\n }\n });\n const wrappedAdoptedStyleSheetEmit = (a) => wrappedEmit({\n type: EventType.IncrementalSnapshot,\n data: {\n source: IncrementalSource.AdoptedStyleSheet,\n ...a\n }\n });\n const stylesheetManager = new StylesheetManager({\n mutationCb: wrappedMutationEmit,\n adoptedStyleSheetCb: wrappedAdoptedStyleSheetEmit\n });\n const iframeManager = new IframeManager({\n mirror,\n mutationCb: wrappedMutationEmit,\n stylesheetManager,\n recordCrossOriginIframes,\n wrappedEmit\n });\n for (const plugin of plugins || []) {\n if (plugin.getMirror)\n plugin.getMirror({\n nodeMirror: mirror,\n crossOriginIframeMirror: iframeManager.crossOriginIframeMirror,\n crossOriginIframeStyleMirror: iframeManager.crossOriginIframeStyleMirror\n });\n }\n const processedNodeManager = new ProcessedNodeManager();\n canvasManager = new CanvasManager({\n recordCanvas,\n mutationCb: wrappedCanvasMutationEmit,\n win: window,\n blockClass,\n blockSelector,\n mirror,\n sampling: sampling.canvas,\n dataURLOptions,\n resolutionScale: canvasResolutionScale\n });\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 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 stylesheetManager.reset();\n shadowDomManager.init();\n mutationBuffers.forEach((buf) => buf.lock());\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);\n }\n if (isSerializedStylesheet(n, mirror)) {\n stylesheetManager.trackLinkElement(n);\n }\n if (hasShadowRoot(n)) {\n shadowDomManager.addShadowRoot(index.shadowRoot(n), document);\n }\n },\n onIframeLoad: (iframe, childSn) => {\n iframeManager.attachIframe(iframe, childSn);\n shadowDomManager.observeAttachShadow(iframe);\n },\n onIframeListenerRegistered: (iframe, disposer) => {\n iframeManager.registerLoadListenerDisposer(iframe, disposer);\n },\n onStylesheetLoad: (linkEl, childSn) => {\n stylesheetManager.attachLinkElement(linkEl, childSn);\n },\n keepIframeSrcFn\n });\n if (!node) {\n return console.warn(\"Failed to snapshot the document\");\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());\n if (recordCrossOriginIframes) {\n iframeManager.reattachIframes();\n }\n if (document.adoptedStyleSheets && document.adoptedStyleSheets.length > 0)\n stylesheetManager.adoptStyleSheets(\n document.adoptedStyleSheets,\n mirror.getId(document)\n );\n };\n try {\n const handlers = [];\n runAndDetachIframeCleanup = (iframeId) => {\n const cleanups = iframeObserverCleanups.get(iframeId);\n if (!cleanups) return;\n cleanups.forEach((cleanup) => {\n callSafely(cleanup);\n const idx = handlers.indexOf(cleanup);\n if (idx !== -1) handlers.splice(idx, 1);\n });\n iframeObserverCleanups.delete(iframeId);\n };\n cleanupDetachedIframeObservers = () => {\n for (const [iframeId] of iframeObserverCleanups) {\n const iframe = mirror.getNode(iframeId);\n if (!iframe) {\n runAndDetachIframeCleanup == null ? void 0 : runAndDetachIframeCleanup(iframeId);\n continue;\n }\n try {\n if (!iframe.contentDocument || !iframe.contentDocument.defaultView) {\n runAndDetachIframeCleanup == null ? void 0 : runAndDetachIframeCleanup(iframeId);\n }\n } catch {\n runAndDetachIframeCleanup == null ? void 0 : runAndDetachIframeCleanup(iframeId);\n }\n }\n };\n const observe = (doc) => {\n var _a2;\n return callbackWrapper(initObservers)(\n {\n mutationCb: wrappedMutationEmit,\n mousemoveCb: (positions, source) => wrappedEmit({\n type: EventType.IncrementalSnapshot,\n data: {\n source,\n positions\n }\n }),\n mouseInteractionCb: (d) => wrappedEmit({\n type: EventType.IncrementalSnapshot,\n data: {\n source: IncrementalSource.MouseInteraction,\n ...d\n }\n }),\n scrollCb: wrappedScrollEmit,\n viewportResizeCb: (d) => wrappedEmit({\n type: EventType.IncrementalSnapshot,\n data: {\n source: IncrementalSource.ViewportResize,\n ...d\n }\n }),\n inputCb: (v) => wrappedEmit({\n type: EventType.IncrementalSnapshot,\n data: {\n source: IncrementalSource.Input,\n ...v\n }\n }),\n mediaInteractionCb: (p) => wrappedEmit({\n type: EventType.IncrementalSnapshot,\n data: {\n source: IncrementalSource.MediaInteraction,\n ...p\n }\n }),\n styleSheetRuleCb: (r) => wrappedEmit({\n type: EventType.IncrementalSnapshot,\n data: {\n source: IncrementalSource.StyleSheetRule,\n ...r\n }\n }),\n styleDeclarationCb: (r) => wrappedEmit({\n type: EventType.IncrementalSnapshot,\n data: {\n source: IncrementalSource.StyleDeclaration,\n ...r\n }\n }),\n canvasMutationCb: wrappedCanvasMutationEmit,\n fontCb: (p) => 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: ((_a2 = plugins == null ? void 0 : plugins.filter((p) => p.observer)) == null ? void 0 : _a2.map((p) => ({\n observer: p.observer,\n options: p.options,\n callback: (payload) => wrappedEmit({\n type: EventType.Plugin,\n data: {\n plugin: p.name,\n payload\n }\n })\n }))) || []\n },\n hooks\n );\n };\n const loadListener = (iframeEl) => {\n try {\n const iframeId = mirror.getId(iframeEl);\n const cleanup = observe(iframeEl.contentDocument);\n handlers.push(cleanup);\n if (iframeId !== -1) {\n let bucket = iframeObserverCleanups.get(iframeId);\n if (!bucket) {\n bucket = /* @__PURE__ */ new Set();\n iframeObserverCleanups.set(iframeId, bucket);\n }\n bucket.add(cleanup);\n }\n } catch (error) {\n console.warn(error);\n }\n };\n iframeManager.addLoadListener(loadListener);\n iframeManager.addPageHideListener((iframeEl) => {\n const iframeId = mirror.getId(iframeEl);\n runAndDetachIframeCleanup == null ? void 0 : runAndDetachIframeCleanup(iframeId);\n findAndRemoveIframeBuffer(iframeEl);\n });\n let lastFullscreenId = -1;\n const emitFullscreen = (payload) => wrappedEmit({\n type: EventType.Custom,\n data: { tag: FullscreenCustomEventTag, payload }\n });\n const emitFullscreenChange = () => {\n const doc = document;\n const fullscreenEl = doc.fullscreenElement ?? doc.webkitFullscreenElement ?? doc.mozFullScreenElement ?? doc.msFullscreenElement ?? null;\n const id = fullscreenEl ? mirror.getId(fullscreenEl) : -1;\n if (id === lastFullscreenId) return;\n if (lastFullscreenId !== -1) {\n emitFullscreen({ id: lastFullscreenId, enter: false });\n }\n lastFullscreenId = id;\n if (id !== -1) {\n emitFullscreen({ id, enter: true });\n }\n };\n const init = () => {\n takeFullSnapshot();\n handlers.push(observe(document));\n handlers.push(on(\"fullscreenchange\", emitFullscreenChange));\n handlers.push(on(\"webkitfullscreenchange\", emitFullscreenChange));\n handlers.push(on(\"mozfullscreenchange\", emitFullscreenChange));\n handlers.push(on(\"MSFullscreenChange\", emitFullscreenChange));\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((h) => callSafely(h));\n processedNodeManager.destroy();\n iframeManager.removeLoadListener();\n iframeManager.destroy();\n iframeObserverCleanups.clear();\n mirror.reset();\n recording = false;\n unregisterErrorHandler();\n };\n } catch (error) {\n console.warn(error);\n }\n}\nrecord.addCustomEvent = (tag, payload) => {\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};\nrecord.freezePage = () => {\n mutationBuffers.forEach((buf) => buf.freeze());\n};\nrecord.takeFullSnapshot = (isCheckout) => {\n if (!recording) {\n throw new Error(\"please take full snapshot after start recording\");\n }\n takeFullSnapshot(isCheckout);\n};\nrecord.mirror = mirror;\nexport {\n record,\n resetMaxDepthState,\n wasMaxDepthReached\n};\n//# sourceMappingURL=rrweb-record.js.map\n","var __defProp = Object.defineProperty;\nvar __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;\nvar __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== \"symbol\" ? key + \"\" : key, value);\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}\nclass StackFrame {\n constructor(obj) {\n __publicField(this, \"fileName\");\n __publicField(this, \"functionName\");\n __publicField(this, \"lineNumber\");\n __publicField(this, \"columnNumber\");\n this.fileName = obj.fileName || \"\";\n this.functionName = obj.functionName || \"\";\n this.lineNumber = obj.lineNumber;\n this.columnNumber = obj.columnNumber;\n }\n toString() {\n const lineNumber = this.lineNumber || \"\";\n const columnNumber = this.columnNumber || \"\";\n if (this.functionName)\n return `${this.functionName} (${this.fileName}:${lineNumber}:${columnNumber})`;\n return `${this.fileName}:${lineNumber}:${columnNumber}`;\n }\n}\nconst FIREFOX_SAFARI_STACK_REGEXP = /(^|@)\\S+:\\d+/;\nconst CHROME_IE_STACK_REGEXP = /^\\s*at .*(\\S+:\\d+|\\(native\\))/m;\nconst SAFARI_NATIVE_CODE_REGEXP = /^(eval@)?(\\[native code])?$/;\nconst ErrorStackParser = {\n /**\n * Given an Error object, extract the most information from it.\n */\n parse: function(error) {\n if (!error) {\n return [];\n }\n if (\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n typeof error.stacktrace !== \"undefined\" || // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n typeof error[\"opera#sourceloc\"] !== \"undefined\"\n ) {\n return this.parseOpera(\n error\n );\n } else if (error.stack && error.stack.match(CHROME_IE_STACK_REGEXP)) {\n return this.parseV8OrIE(error);\n } else if (error.stack) {\n return this.parseFFOrSafari(error);\n } else {\n return [];\n }\n },\n // Separate line and column numbers from a string of the form: (URI:Line:Column)\n extractLocation: function(urlLike) {\n if (urlLike.indexOf(\":\") === -1) {\n return [urlLike];\n }\n const regExp = /(.+?)(?::(\\d+))?(?::(\\d+))?$/;\n const parts = regExp.exec(urlLike.replace(/[()]/g, \"\"));\n if (!parts) throw new Error(`Cannot parse given url: ${urlLike}`);\n return [parts[1], parts[2] || void 0, parts[3] || void 0];\n },\n parseV8OrIE: function(error) {\n const filtered = error.stack.split(\"\\n\").filter(function(line) {\n return !!line.match(CHROME_IE_STACK_REGEXP);\n }, this);\n return filtered.map(function(line) {\n if (line.indexOf(\"(eval \") > -1) {\n line = line.replace(/eval code/g, \"eval\").replace(/(\\(eval at [^()]*)|(\\),.*$)/g, \"\");\n }\n let sanitizedLine = line.replace(/^\\s+/, \"\").replace(/\\(eval code/g, \"(\");\n const location = sanitizedLine.match(/ (\\((.+):(\\d+):(\\d+)\\)$)/);\n sanitizedLine = location ? sanitizedLine.replace(location[0], \"\") : sanitizedLine;\n const tokens = sanitizedLine.split(/\\s+/).slice(1);\n const locationParts = this.extractLocation(\n location ? location[1] : tokens.pop()\n );\n const functionName = tokens.join(\" \") || void 0;\n const fileName = [\"eval\", \"<anonymous>\"].indexOf(locationParts[0]) > -1 ? void 0 : locationParts[0];\n return new StackFrame({\n functionName,\n fileName,\n lineNumber: locationParts[1],\n columnNumber: locationParts[2]\n });\n }, this);\n },\n parseFFOrSafari: function(error) {\n const filtered = error.stack.split(\"\\n\").filter(function(line) {\n return !line.match(SAFARI_NATIVE_CODE_REGEXP);\n }, this);\n return filtered.map(function(line) {\n if (line.indexOf(\" > eval\") > -1) {\n line = line.replace(\n / line (\\d+)(?: > eval line \\d+)* > eval:\\d+:\\d+/g,\n \":$1\"\n );\n }\n if (line.indexOf(\"@\") === -1 && line.indexOf(\":\") === -1) {\n return new StackFrame({\n functionName: line\n });\n } else {\n const functionNameRegex = /((.*\".+\"[^@]*)?[^@]*)(?:@)/;\n const matches = line.match(functionNameRegex);\n const functionName = matches && matches[1] ? matches[1] : void 0;\n const locationParts = this.extractLocation(\n line.replace(functionNameRegex, \"\")\n );\n return new StackFrame({\n functionName,\n fileName: locationParts[0],\n lineNumber: locationParts[1],\n columnNumber: locationParts[2]\n });\n }\n }, this);\n },\n parseOpera: function(e) {\n if (!e.stacktrace || e.message.indexOf(\"\\n\") > -1 && e.message.split(\"\\n\").length > e.stacktrace.split(\"\\n\").length) {\n return this.parseOpera9(e);\n } else if (!e.stack) {\n return this.parseOpera10(e);\n } else {\n return this.parseOpera11(e);\n }\n },\n parseOpera9: function(e) {\n const lineRE = /Line (\\d+).*script (?:in )?(\\S+)/i;\n const lines = e.message.split(\"\\n\");\n const result = [];\n for (let i = 2, len = lines.length; i < len; i += 2) {\n const match = lineRE.exec(lines[i]);\n if (match) {\n result.push(\n new StackFrame({\n fileName: match[2],\n lineNumber: parseFloat(match[1])\n })\n );\n }\n }\n return result;\n },\n parseOpera10: function(e) {\n const lineRE = /Line (\\d+).*script (?:in )?(\\S+)(?:: In function (\\S+))?$/i;\n const lines = e.stacktrace.split(\"\\n\");\n const result = [];\n for (let i = 0, len = lines.length; i < len; i += 2) {\n const match = lineRE.exec(lines[i]);\n if (match) {\n result.push(\n new StackFrame({\n functionName: match[3] || void 0,\n fileName: match[2],\n lineNumber: parseFloat(match[1])\n })\n );\n }\n }\n return result;\n },\n // Opera 10.65+ Error.stack very similar to FF/Safari\n parseOpera11: function(error) {\n const filtered = error.stack.split(\"\\n\").filter(function(line) {\n return !!line.match(FIREFOX_SAFARI_STACK_REGEXP) && !line.match(/^Error created at/);\n }, this);\n return filtered.map(function(line) {\n const tokens = line.split(\"@\");\n const locationParts = this.extractLocation(tokens.pop());\n const functionCall = tokens.shift() || \"\";\n const functionName = functionCall.replace(/<anonymous function(: (\\w+))?>/, \"$2\").replace(/\\([^)]*\\)/g, \"\") || void 0;\n return new StackFrame({\n functionName,\n fileName: locationParts[0],\n lineNumber: locationParts[1],\n columnNumber: locationParts[2]\n });\n }, this);\n }\n};\nfunction pathToSelector(node) {\n if (!node || !node.outerHTML) {\n return \"\";\n }\n let path = \"\";\n while (node.parentElement) {\n let name = node.localName;\n if (!name) {\n break;\n }\n name = name.toLowerCase();\n const parent = node.parentElement;\n const domSiblings = [];\n if (parent.children && parent.children.length > 0) {\n for (let i = 0; i < parent.children.length; i++) {\n const sibling = parent.children[i];\n if (sibling.localName && sibling.localName.toLowerCase) {\n if (sibling.localName.toLowerCase() === name) {\n domSiblings.push(sibling);\n }\n }\n }\n }\n if (domSiblings.length > 1) {\n name += `:eq(${domSiblings.indexOf(node)})`;\n }\n path = name + (path ? \">\" + path : \"\");\n node = parent;\n }\n return path;\n}\nfunction isArray(obj) {\n return Array.isArray(obj);\n}\nfunction isObject(obj) {\n return typeof obj === \"object\" && obj !== null && !isArray(obj);\n}\nfunction isObjTooDeep(obj, limit) {\n if (limit === 0) {\n return true;\n }\n const keys = Object.keys(obj);\n for (const key of keys) {\n if (isObject(obj[key]) && isObjTooDeep(obj[key], limit - 1)) {\n return true;\n }\n }\n return false;\n}\nfunction stringify(obj, stringifyOptions) {\n const options = {\n numOfKeysLimit: 50,\n depthOfLimit: 4\n };\n Object.assign(options, stringifyOptions);\n const stack = [];\n const keys = [];\n return JSON.stringify(\n obj,\n function(key, value) {\n if (stack.length > 0) {\n const thisPos = stack.indexOf(this);\n ~thisPos ? stack.splice(thisPos + 1) : stack.push(this);\n ~thisPos ? keys.splice(thisPos, Infinity, key) : keys.push(key);\n if (~stack.indexOf(value)) {\n if (stack[0] === value) {\n value = \"[Circular ~]\";\n } else {\n value = \"[Circular ~.\" + keys.slice(0, stack.indexOf(value)).join(\".\") + \"]\";\n }\n }\n } else {\n stack.push(value);\n }\n if (value === null) return value;\n if (value === void 0) return \"undefined\";\n if (shouldIgnore(value)) {\n return toString(value);\n }\n if (typeof value === \"bigint\") {\n return value.toString() + \"n\";\n }\n if (value instanceof Event) {\n const eventResult = {};\n for (const eventKey in value) {\n const eventValue = value[eventKey];\n if (isArray(eventValue)) {\n eventResult[eventKey] = pathToSelector(\n eventValue.length ? eventValue[0] : null\n );\n } else {\n eventResult[eventKey] = eventValue;\n }\n }\n return eventResult;\n } else if (value instanceof Node) {\n if (value instanceof HTMLElement) {\n return value ? value.outerHTML : \"\";\n }\n return value.nodeName;\n } else if (value instanceof Error) {\n return value.stack ? value.stack + \"\\nEnd of stack for Error object\" : value.name + \": \" + value.message;\n }\n return value;\n }\n );\n function shouldIgnore(_obj) {\n if (isObject(_obj) && Object.keys(_obj).length > options.numOfKeysLimit) {\n return true;\n }\n if (typeof _obj === \"function\") {\n return true;\n }\n if (isObject(_obj) && isObjTooDeep(_obj, options.depthOfLimit)) {\n return true;\n }\n return false;\n }\n function toString(_obj) {\n let str = _obj.toString();\n if (options.stringLengthLimit && str.length > options.stringLengthLimit) {\n str = `${str.slice(0, options.stringLengthLimit)}...`;\n }\n return str;\n }\n}\nconst defaultLogOptions = {\n level: [\n \"assert\",\n \"clear\",\n \"count\",\n \"countReset\",\n \"debug\",\n \"dir\",\n \"dirxml\",\n \"error\",\n \"group\",\n \"groupCollapsed\",\n \"groupEnd\",\n \"info\",\n \"log\",\n \"table\",\n \"time\",\n \"timeEnd\",\n \"timeLog\",\n \"trace\",\n \"warn\"\n ],\n lengthThreshold: 1e3,\n logger: \"console\"\n};\nfunction initLogObserver(cb, win, options) {\n const logOptions = options ? Object.assign({}, defaultLogOptions, options) : defaultLogOptions;\n const loggerType = logOptions.logger;\n if (!loggerType) {\n return () => {\n };\n }\n let logger;\n if (typeof loggerType === \"string\") {\n logger = win[loggerType];\n } else {\n logger = loggerType;\n }\n let logCount = 0;\n let inStack = false;\n const cancelHandlers = [];\n if (logOptions.level.includes(\"error\")) {\n const errorHandler = (event) => {\n const message = event.message, error = event.error;\n const trace = ErrorStackParser.parse(error).map(\n (stackFrame) => stackFrame.toString()\n );\n const payload = [stringify(message, logOptions.stringifyOptions)];\n cb({\n level: \"error\",\n trace,\n payload\n });\n };\n win.addEventListener(\"error\", errorHandler);\n cancelHandlers.push(() => {\n win.removeEventListener(\"error\", errorHandler);\n });\n const unhandledrejectionHandler = (event) => {\n let error;\n let payload;\n if (event.reason instanceof Error) {\n error = event.reason;\n payload = [\n stringify(\n `Uncaught (in promise) ${error.name}: ${error.message}`,\n logOptions.stringifyOptions\n )\n ];\n } else {\n error = new Error();\n payload = [\n stringify(\"Uncaught (in promise)\", logOptions.stringifyOptions),\n stringify(event.reason, logOptions.stringifyOptions)\n ];\n }\n const trace = ErrorStackParser.parse(error).map(\n (stackFrame) => stackFrame.toString()\n );\n cb({\n level: \"error\",\n trace,\n payload\n });\n };\n win.addEventListener(\"unhandledrejection\", unhandledrejectionHandler);\n cancelHandlers.push(() => {\n win.removeEventListener(\"unhandledrejection\", unhandledrejectionHandler);\n });\n }\n for (const levelType of logOptions.level) {\n cancelHandlers.push(replace(logger, levelType));\n }\n return () => {\n cancelHandlers.forEach((h) => h());\n };\n function replace(_logger, level) {\n if (!_logger[level]) {\n return () => {\n };\n }\n return patch(\n _logger,\n level,\n (original) => {\n return (...args) => {\n original.apply(this, args);\n if (level === \"assert\" && !!args[0]) {\n return;\n }\n if (inStack) {\n return;\n }\n inStack = true;\n try {\n const trace = ErrorStackParser.parse(new Error()).map((stackFrame) => stackFrame.toString()).splice(1);\n const argsForPayload = level === \"assert\" ? args.slice(1) : args;\n const payload = argsForPayload.map(\n (s) => stringify(s, logOptions.stringifyOptions)\n );\n logCount++;\n if (logCount < logOptions.lengthThreshold) {\n cb({\n level,\n trace,\n payload\n });\n } else if (logCount === logOptions.lengthThreshold) {\n cb({\n level: \"warn\",\n trace: [],\n payload: [\n stringify(\"The number of log records reached the threshold.\")\n ]\n });\n }\n } catch (error) {\n original(\"rrweb logger error:\", error, ...args);\n } finally {\n inStack = false;\n }\n };\n }\n );\n }\n}\nconst PLUGIN_NAME = \"rrweb/console@1\";\nconst getRecordConsolePlugin = (options) => ({\n name: PLUGIN_NAME,\n observer: initLogObserver,\n options\n});\nexport {\n PLUGIN_NAME,\n getRecordConsolePlugin\n};\n//# sourceMappingURL=rrweb-plugin-console-record.js.map\n","var types_PostHogPersistedProperty = /*#__PURE__*/ function(PostHogPersistedProperty) {\n PostHogPersistedProperty[\"AnonymousId\"] = \"anonymous_id\";\n PostHogPersistedProperty[\"DistinctId\"] = \"distinct_id\";\n PostHogPersistedProperty[\"Props\"] = \"props\";\n PostHogPersistedProperty[\"EnablePersonProcessing\"] = \"enable_person_processing\";\n PostHogPersistedProperty[\"PersonMode\"] = \"person_mode\";\n PostHogPersistedProperty[\"FeatureFlagDetails\"] = \"feature_flag_details\";\n PostHogPersistedProperty[\"FeatureFlags\"] = \"feature_flags\";\n PostHogPersistedProperty[\"FeatureFlagPayloads\"] = \"feature_flag_payloads\";\n PostHogPersistedProperty[\"BootstrapFeatureFlagDetails\"] = \"bootstrap_feature_flag_details\";\n PostHogPersistedProperty[\"BootstrapFeatureFlags\"] = \"bootstrap_feature_flags\";\n PostHogPersistedProperty[\"BootstrapFeatureFlagPayloads\"] = \"bootstrap_feature_flag_payloads\";\n PostHogPersistedProperty[\"OverrideFeatureFlags\"] = \"override_feature_flags\";\n PostHogPersistedProperty[\"Queue\"] = \"queue\";\n PostHogPersistedProperty[\"LogsQueue\"] = \"logs_queue\";\n PostHogPersistedProperty[\"OptedOut\"] = \"opted_out\";\n PostHogPersistedProperty[\"SessionId\"] = \"session_id\";\n PostHogPersistedProperty[\"SessionStartTimestamp\"] = \"session_start_timestamp\";\n PostHogPersistedProperty[\"SessionLastTimestamp\"] = \"session_timestamp\";\n PostHogPersistedProperty[\"PersonProperties\"] = \"person_properties\";\n PostHogPersistedProperty[\"GroupProperties\"] = \"group_properties\";\n PostHogPersistedProperty[\"InstalledAppBuild\"] = \"installed_app_build\";\n PostHogPersistedProperty[\"InstalledAppVersion\"] = \"installed_app_version\";\n PostHogPersistedProperty[\"SessionReplay\"] = \"session_replay\";\n PostHogPersistedProperty[\"SessionReplayEventTriggerActivatedSession\"] = \"session_replay_event_trigger_activated_session\";\n PostHogPersistedProperty[\"SurveyLastSeenDate\"] = \"survey_last_seen_date\";\n PostHogPersistedProperty[\"SurveysSeen\"] = \"surveys_seen\";\n PostHogPersistedProperty[\"Surveys\"] = \"surveys\";\n PostHogPersistedProperty[\"RemoteConfig\"] = \"remote_config\";\n PostHogPersistedProperty[\"FlagsEndpointWasHit\"] = \"flags_endpoint_was_hit\";\n PostHogPersistedProperty[\"DeviceId\"] = \"device_id\";\n return PostHogPersistedProperty;\n}({});\nvar types_Compression = /*#__PURE__*/ function(Compression) {\n Compression[\"GZipJS\"] = \"gzip-js\";\n Compression[\"Base64\"] = \"base64\";\n return Compression;\n}({});\nconst FeatureFlagError = {\n ERRORS_WHILE_COMPUTING: 'errors_while_computing_flags',\n FLAG_MISSING: 'flag_missing',\n QUOTA_LIMITED: 'quota_limited',\n TIMEOUT: 'timeout',\n CONNECTION_ERROR: 'connection_error',\n UNKNOWN_ERROR: 'unknown_error',\n apiError: (status)=>`api_error_${status}`\n};\nvar types_SurveyPosition = /*#__PURE__*/ function(SurveyPosition) {\n SurveyPosition[\"TopLeft\"] = \"top_left\";\n SurveyPosition[\"TopCenter\"] = \"top_center\";\n SurveyPosition[\"TopRight\"] = \"top_right\";\n SurveyPosition[\"MiddleLeft\"] = \"middle_left\";\n SurveyPosition[\"MiddleCenter\"] = \"middle_center\";\n SurveyPosition[\"MiddleRight\"] = \"middle_right\";\n SurveyPosition[\"Left\"] = \"left\";\n SurveyPosition[\"Right\"] = \"right\";\n SurveyPosition[\"Center\"] = \"center\";\n return SurveyPosition;\n}({});\nvar types_SurveyWidgetType = /*#__PURE__*/ function(SurveyWidgetType) {\n SurveyWidgetType[\"Button\"] = \"button\";\n SurveyWidgetType[\"Tab\"] = \"tab\";\n SurveyWidgetType[\"Selector\"] = \"selector\";\n return SurveyWidgetType;\n}({});\nvar types_SurveyType = /*#__PURE__*/ function(SurveyType) {\n SurveyType[\"Popover\"] = \"popover\";\n SurveyType[\"API\"] = \"api\";\n SurveyType[\"Widget\"] = \"widget\";\n SurveyType[\"ExternalSurvey\"] = \"external_survey\";\n return SurveyType;\n}({});\nvar types_SurveyQuestionDescriptionContentType = /*#__PURE__*/ function(SurveyQuestionDescriptionContentType) {\n SurveyQuestionDescriptionContentType[\"Html\"] = \"html\";\n SurveyQuestionDescriptionContentType[\"Text\"] = \"text\";\n return SurveyQuestionDescriptionContentType;\n}({});\nvar types_SurveyValidationType = /*#__PURE__*/ function(SurveyValidationType) {\n SurveyValidationType[\"MinLength\"] = \"min_length\";\n SurveyValidationType[\"MaxLength\"] = \"max_length\";\n return SurveyValidationType;\n}({});\nvar types_SurveyRatingDisplay = /*#__PURE__*/ function(SurveyRatingDisplay) {\n SurveyRatingDisplay[\"Number\"] = \"number\";\n SurveyRatingDisplay[\"Emoji\"] = \"emoji\";\n return SurveyRatingDisplay;\n}({});\nvar types_SurveyQuestionType = /*#__PURE__*/ function(SurveyQuestionType) {\n SurveyQuestionType[\"Open\"] = \"open\";\n SurveyQuestionType[\"MultipleChoice\"] = \"multiple_choice\";\n SurveyQuestionType[\"SingleChoice\"] = \"single_choice\";\n SurveyQuestionType[\"Rating\"] = \"rating\";\n SurveyQuestionType[\"Link\"] = \"link\";\n return SurveyQuestionType;\n}({});\nvar types_SurveyQuestionBranchingType = /*#__PURE__*/ function(SurveyQuestionBranchingType) {\n SurveyQuestionBranchingType[\"NextQuestion\"] = \"next_question\";\n SurveyQuestionBranchingType[\"End\"] = \"end\";\n SurveyQuestionBranchingType[\"ResponseBased\"] = \"response_based\";\n SurveyQuestionBranchingType[\"SpecificQuestion\"] = \"specific_question\";\n return SurveyQuestionBranchingType;\n}({});\nvar types_SurveyMatchType = /*#__PURE__*/ function(SurveyMatchType) {\n SurveyMatchType[\"Regex\"] = \"regex\";\n SurveyMatchType[\"NotRegex\"] = \"not_regex\";\n SurveyMatchType[\"Exact\"] = \"exact\";\n SurveyMatchType[\"IsNot\"] = \"is_not\";\n SurveyMatchType[\"Icontains\"] = \"icontains\";\n SurveyMatchType[\"NotIcontains\"] = \"not_icontains\";\n return SurveyMatchType;\n}({});\nvar types_SurveySchedule = /*#__PURE__*/ function(SurveySchedule) {\n SurveySchedule[\"Once\"] = \"once\";\n SurveySchedule[\"Recurring\"] = \"recurring\";\n SurveySchedule[\"Always\"] = \"always\";\n return SurveySchedule;\n}({});\nvar types_ActionStepStringMatching = /*#__PURE__*/ function(ActionStepStringMatching) {\n ActionStepStringMatching[\"Contains\"] = \"contains\";\n ActionStepStringMatching[\"Exact\"] = \"exact\";\n ActionStepStringMatching[\"Regex\"] = \"regex\";\n return ActionStepStringMatching;\n}({});\nconst knownUnsafeEditableEvent = [\n '$snapshot',\n '$pageview',\n '$pageleave',\n '$set',\n 'survey dismissed',\n 'survey sent',\n 'survey shown',\n '$identify',\n '$groupidentify',\n '$create_alias',\n '$$client_ingestion_warning',\n '$web_experiment_applied',\n '$feature_enrollment_update',\n '$feature_flag_called'\n];\nconst knownUnsafeEditableEventProperty = [\n 'token'\n];\nexport { types_ActionStepStringMatching as ActionStepStringMatching, types_Compression as Compression, FeatureFlagError, types_PostHogPersistedProperty as PostHogPersistedProperty, types_SurveyMatchType as SurveyMatchType, types_SurveyPosition as SurveyPosition, types_SurveyQuestionBranchingType as SurveyQuestionBranchingType, types_SurveyQuestionDescriptionContentType as SurveyQuestionDescriptionContentType, types_SurveyQuestionType as SurveyQuestionType, types_SurveyRatingDisplay as SurveyRatingDisplay, types_SurveySchedule as SurveySchedule, types_SurveyType as SurveyType, types_SurveyValidationType as SurveyValidationType, types_SurveyWidgetType as SurveyWidgetType, knownUnsafeEditableEvent, knownUnsafeEditableEventProperty };\n","function includes(str, needle) {\n return -1 !== str.indexOf(needle);\n}\nconst trim = function(str) {\n return str.trim();\n};\nconst stripLeadingDollar = function(s) {\n return s.replace(/^\\$/, '');\n};\nfunction isDistinctIdStringLike(value) {\n return [\n 'distinct_id',\n 'distinctid'\n ].includes(value.toLowerCase());\n}\nfunction deepSortKeys(value) {\n if (null === value || 'object' != typeof value) return value;\n if (Array.isArray(value)) return value.map(deepSortKeys);\n return Object.keys(value).sort().reduce((acc, key)=>{\n acc[key] = deepSortKeys(value[key]);\n return acc;\n }, {});\n}\nfunction getPersonPropertiesHash(distinct_id, userPropertiesToSet, userPropertiesToSetOnce) {\n return JSON.stringify({\n distinct_id,\n userPropertiesToSet: userPropertiesToSet ? deepSortKeys(userPropertiesToSet) : void 0,\n userPropertiesToSetOnce: userPropertiesToSetOnce ? deepSortKeys(userPropertiesToSetOnce) : void 0\n });\n}\nexport { getPersonPropertiesHash, includes, isDistinctIdStringLike, stripLeadingDollar, trim };\n","import { knownUnsafeEditableEvent, knownUnsafeEditableEventProperty } from \"../types.mjs\";\nimport { includes } from \"./string-utils.mjs\";\nconst nativeIsArray = Array.isArray;\nconst ObjProto = Object.prototype;\nconst type_utils_hasOwnProperty = ObjProto.hasOwnProperty;\nconst type_utils_toString = ObjProto.toString;\nconst isArray = nativeIsArray || function(obj) {\n return '[object Array]' === type_utils_toString.call(obj);\n};\nconst isFunction = (x)=>'function' == typeof x;\nconst isNativeFunction = (x)=>isFunction(x) && -1 !== x.toString().indexOf('[native code]');\nconst isObject = (x)=>x === Object(x) && !isArray(x);\nconst isEmptyObject = (x)=>{\n if (isObject(x)) {\n for(const key in x)if (type_utils_hasOwnProperty.call(x, key)) return false;\n return true;\n }\n return false;\n};\nconst isUndefined = (x)=>void 0 === x;\nconst isString = (x)=>'[object String]' == type_utils_toString.call(x);\nconst isEmptyString = (x)=>isString(x) && 0 === x.trim().length;\nconst isNull = (x)=>null === x;\nconst isNullish = (x)=>isUndefined(x) || isNull(x);\nconst isNumber = (x)=>'[object Number]' == type_utils_toString.call(x) && x === x;\nconst isPositiveNumber = (value)=>isNumber(value) && value > 0;\nconst isBoolean = (x)=>'[object Boolean]' === type_utils_toString.call(x);\nconst isFormData = (x)=>x instanceof FormData;\nconst isFile = (x)=>x instanceof File;\nconst isPlainError = (x)=>x instanceof Error;\nconst isKnownUnsafeEditableEvent = (x)=>includes(knownUnsafeEditableEvent, x);\nconst isKnownUnsafeEditableEventProperty = (x)=>includes(knownUnsafeEditableEventProperty, x);\nfunction isPrimitive(value) {\n return null === value || 'object' != typeof value;\n}\nfunction isBuiltin(candidate, className) {\n return Object.prototype.toString.call(candidate) === `[object ${className}]`;\n}\nfunction isError(candidate) {\n switch(Object.prototype.toString.call(candidate)){\n case '[object Error]':\n case '[object Exception]':\n case '[object DOMException]':\n case '[object DOMError]':\n case '[object WebAssembly.Exception]':\n return true;\n default:\n return isInstanceOf(candidate, Error);\n }\n}\nfunction isErrorEvent(event) {\n return isBuiltin(event, 'ErrorEvent');\n}\nfunction isEvent(candidate) {\n return 'undefined' != typeof Event && isInstanceOf(candidate, Event);\n}\nfunction isPlainObject(candidate) {\n return isBuiltin(candidate, 'Object');\n}\nfunction isInstanceOf(candidate, base) {\n try {\n return candidate instanceof base;\n } catch {\n return false;\n }\n}\nconst yesLikeValues = [\n true,\n 'true',\n 1,\n '1',\n 'yes'\n];\nconst isYesLike = (val)=>includes(yesLikeValues, val);\nconst noLikeValues = [\n false,\n 'false',\n 0,\n '0',\n 'no'\n];\nconst isNoLike = (val)=>includes(noLikeValues, val);\nexport { type_utils_hasOwnProperty as hasOwnProperty, isArray, isBoolean, isBuiltin, isEmptyObject, isEmptyString, isError, isErrorEvent, isEvent, isFile, isFormData, isFunction, isKnownUnsafeEditableEvent, isKnownUnsafeEditableEventProperty, isNativeFunction, isNoLike, isNull, isNullish, isNumber, isObject, isPlainError, isPlainObject, isPositiveNumber, isPrimitive, isString, isUndefined, isYesLike, noLikeValues, yesLikeValues };\n","import { includes } from \"./string-utils.mjs\";\nimport { isFunction, isUndefined } from \"./type-utils.mjs\";\nconst FACEBOOK = 'Facebook';\nconst MOBILE = 'Mobile';\nconst IOS = 'iOS';\nconst ANDROID = 'Android';\nconst TABLET = 'Tablet';\nconst ANDROID_TABLET = ANDROID + ' ' + TABLET;\nconst IPAD = 'iPad';\nconst APPLE = 'Apple';\nconst APPLE_WATCH = APPLE + ' Watch';\nconst SAFARI = 'Safari';\nconst BLACKBERRY = 'BlackBerry';\nconst SAMSUNG = 'Samsung';\nconst SAMSUNG_BROWSER = SAMSUNG + 'Browser';\nconst SAMSUNG_INTERNET = SAMSUNG + ' Internet';\nconst CHROME = 'Chrome';\nconst CHROME_OS = CHROME + ' OS';\nconst CHROME_IOS = CHROME + ' ' + IOS;\nconst INTERNET_EXPLORER = 'Internet Explorer';\nconst INTERNET_EXPLORER_MOBILE = INTERNET_EXPLORER + ' ' + MOBILE;\nconst OPERA = 'Opera';\nconst OPERA_MINI = OPERA + ' Mini';\nconst EDGE = 'Edge';\nconst MICROSOFT_EDGE = 'Microsoft ' + EDGE;\nconst FIREFOX = 'Firefox';\nconst FIREFOX_IOS = FIREFOX + ' ' + IOS;\nconst NINTENDO = 'Nintendo';\nconst PLAYSTATION = 'PlayStation';\nconst XBOX = 'Xbox';\nconst ANDROID_MOBILE = ANDROID + ' ' + MOBILE;\nconst MOBILE_SAFARI = MOBILE + ' ' + SAFARI;\nconst WINDOWS = 'Windows';\nconst WINDOWS_PHONE = WINDOWS + ' Phone';\nconst NOKIA = 'Nokia';\nconst OUYA = 'Ouya';\nconst GENERIC = 'Generic';\nconst GENERIC_MOBILE = GENERIC + ' ' + MOBILE.toLowerCase();\nconst GENERIC_TABLET = GENERIC + ' ' + TABLET.toLowerCase();\nconst KONQUEROR = 'Konqueror';\nconst OCULUS_BROWSER = 'Oculus Browser';\nconst VIVALDI = 'Vivaldi';\nconst YANDEX = 'Yandex';\nconst WHALE = 'Whale';\nconst DUCKDUCKGO = 'DuckDuckGo';\nconst PALE_MOON = 'Pale Moon';\nconst WATERFOX = 'Waterfox';\nconst BRAVE = 'Brave';\nconst GOOGLE_SEARCH_APP = 'Google Search App';\nconst BROWSER_VERSION_REGEX_SUFFIX = '(\\\\d+(\\\\.\\\\d+)?)';\nconst DEFAULT_BROWSER_VERSION_REGEX = new RegExp('Version/' + BROWSER_VERSION_REGEX_SUFFIX);\nfunction browserFromHints(hints) {\n if (hints?.brave) return BRAVE;\n return null;\n}\nconst XBOX_REGEX = new RegExp(XBOX, 'i');\nconst PLAYSTATION_REGEX = new RegExp(PLAYSTATION + ' \\\\w+', 'i');\nconst NINTENDO_REGEX = new RegExp(NINTENDO + ' \\\\w+', 'i');\nconst BLACKBERRY_REGEX = new RegExp(BLACKBERRY + '|PlayBook|BB10', 'i');\nconst windowsVersionMap = {\n 'NT3.51': 'NT 3.11',\n 'NT4.0': 'NT 4.0',\n '5.0': '2000',\n '5.1': 'XP',\n '5.2': 'XP',\n '6.0': 'Vista',\n '6.1': '7',\n '6.2': '8',\n '6.3': '8.1',\n '6.4': '10',\n '10.0': '10'\n};\nfunction isSafari(userAgent) {\n return includes(userAgent, SAFARI) && !includes(userAgent, CHROME) && !includes(userAgent, ANDROID);\n}\nconst safariCheck = (ua, vendor)=>vendor && includes(vendor, APPLE) || isSafari(ua);\nconst detectBrowser = function(user_agent, vendor, hints, options) {\n vendor = vendor || '';\n const fromHints = browserFromHints(hints);\n if (fromHints) return fromHints;\n if (options?.detectGoogleSearchApp && includes(user_agent, 'GSA/')) return GOOGLE_SEARCH_APP;\n if (includes(user_agent, ' OPR/') && includes(user_agent, 'Mini')) return OPERA_MINI;\n if (includes(user_agent, ' OPR/')) return OPERA;\n if (BLACKBERRY_REGEX.test(user_agent)) return BLACKBERRY;\n if (includes(user_agent, 'IE' + MOBILE) || includes(user_agent, 'WPDesktop')) return INTERNET_EXPLORER_MOBILE;\n if (includes(user_agent, 'OculusBrowser')) return OCULUS_BROWSER;\n else if (includes(user_agent, SAMSUNG_BROWSER)) return SAMSUNG_INTERNET;\n else if (includes(user_agent, EDGE) || includes(user_agent, 'Edg/')) return MICROSOFT_EDGE;\n else if (includes(user_agent, VIVALDI + '/')) return VIVALDI;\n else if (includes(user_agent, 'YaBrowser/')) return YANDEX;\n else if (includes(user_agent, WHALE + '/')) return WHALE;\n else if (includes(user_agent, DUCKDUCKGO + '/') || includes(user_agent, 'Ddg/')) return DUCKDUCKGO;\n else if (includes(user_agent, 'FBIOS')) return FACEBOOK + ' ' + MOBILE;\n else if (includes(user_agent, 'UCWEB') || includes(user_agent, 'UCBrowser')) return 'UC Browser';\n else if (includes(user_agent, 'CriOS')) return CHROME_IOS;\n else if (includes(user_agent, 'CrMo')) return CHROME;\n else if (includes(user_agent, CHROME)) return CHROME;\n else if (includes(user_agent, ANDROID) && includes(user_agent, SAFARI)) return ANDROID_MOBILE;\n else if (includes(user_agent, 'FxiOS')) return FIREFOX_IOS;\n else if (includes(user_agent.toLowerCase(), KONQUEROR.toLowerCase())) return KONQUEROR;\n else if (includes(user_agent, BRAVE + '/')) return BRAVE;\n else if (safariCheck(user_agent, vendor)) return includes(user_agent, MOBILE) ? MOBILE_SAFARI : SAFARI;\n else if (includes(user_agent, 'PaleMoon/')) return PALE_MOON;\n else if (includes(user_agent, WATERFOX + '/')) return WATERFOX;\n else if (includes(user_agent, FIREFOX)) return FIREFOX;\n else if (includes(user_agent, 'MSIE') || includes(user_agent, 'Trident/')) return INTERNET_EXPLORER;\n else if (includes(user_agent, 'Gecko')) return FIREFOX;\n return '';\n};\nconst versionRegexes = {\n [INTERNET_EXPLORER_MOBILE]: [\n new RegExp('rv:' + BROWSER_VERSION_REGEX_SUFFIX)\n ],\n [MICROSOFT_EDGE]: [\n new RegExp(EDGE + '?\\\\/' + BROWSER_VERSION_REGEX_SUFFIX)\n ],\n [CHROME]: [\n new RegExp('(' + CHROME + '|CrMo)\\\\/' + BROWSER_VERSION_REGEX_SUFFIX)\n ],\n [CHROME_IOS]: [\n new RegExp('CriOS\\\\/' + BROWSER_VERSION_REGEX_SUFFIX)\n ],\n 'UC Browser': [\n new RegExp('(UCBrowser|UCWEB)\\\\/' + BROWSER_VERSION_REGEX_SUFFIX)\n ],\n [SAFARI]: [\n DEFAULT_BROWSER_VERSION_REGEX\n ],\n [MOBILE_SAFARI]: [\n DEFAULT_BROWSER_VERSION_REGEX\n ],\n [OPERA]: [\n new RegExp('(' + OPERA + '|OPR)\\\\/' + BROWSER_VERSION_REGEX_SUFFIX)\n ],\n [FIREFOX]: [\n new RegExp(FIREFOX + '\\\\/' + BROWSER_VERSION_REGEX_SUFFIX)\n ],\n [FIREFOX_IOS]: [\n new RegExp('FxiOS\\\\/' + BROWSER_VERSION_REGEX_SUFFIX)\n ],\n [KONQUEROR]: [\n new RegExp('Konqueror[:/]?' + BROWSER_VERSION_REGEX_SUFFIX, 'i')\n ],\n [BLACKBERRY]: [\n new RegExp(BLACKBERRY + ' ' + BROWSER_VERSION_REGEX_SUFFIX),\n DEFAULT_BROWSER_VERSION_REGEX\n ],\n [ANDROID_MOBILE]: [\n new RegExp('android\\\\s' + BROWSER_VERSION_REGEX_SUFFIX, 'i')\n ],\n [SAMSUNG_INTERNET]: [\n new RegExp(SAMSUNG_BROWSER + '\\\\/' + BROWSER_VERSION_REGEX_SUFFIX)\n ],\n [OCULUS_BROWSER]: [\n new RegExp('OculusBrowser\\\\/' + BROWSER_VERSION_REGEX_SUFFIX)\n ],\n [VIVALDI]: [\n new RegExp(VIVALDI + '\\\\/' + BROWSER_VERSION_REGEX_SUFFIX)\n ],\n [YANDEX]: [\n new RegExp('YaBrowser\\\\/' + BROWSER_VERSION_REGEX_SUFFIX)\n ],\n [WHALE]: [\n new RegExp(WHALE + '\\\\/' + BROWSER_VERSION_REGEX_SUFFIX)\n ],\n [BRAVE]: [\n new RegExp(BRAVE + '\\\\/' + BROWSER_VERSION_REGEX_SUFFIX)\n ],\n [DUCKDUCKGO]: [\n new RegExp('(DuckDuckGo|Ddg)\\\\/' + BROWSER_VERSION_REGEX_SUFFIX)\n ],\n [PALE_MOON]: [\n new RegExp('PaleMoon\\\\/' + BROWSER_VERSION_REGEX_SUFFIX)\n ],\n [WATERFOX]: [\n new RegExp(WATERFOX + '\\\\/' + BROWSER_VERSION_REGEX_SUFFIX)\n ],\n [GOOGLE_SEARCH_APP]: [\n new RegExp('GSA\\\\/' + BROWSER_VERSION_REGEX_SUFFIX)\n ],\n [INTERNET_EXPLORER]: [\n new RegExp('(rv:|MSIE )' + BROWSER_VERSION_REGEX_SUFFIX)\n ],\n Mozilla: [\n new RegExp('rv:' + BROWSER_VERSION_REGEX_SUFFIX)\n ]\n};\nconst detectBrowserVersion = function(userAgent, vendor, hints, options) {\n const browser = detectBrowser(userAgent, vendor, hints, options);\n const regexes = versionRegexes[browser];\n if (isUndefined(regexes)) return null;\n for(let i = 0; i < regexes.length; i++){\n const regex = regexes[i];\n const matches = userAgent.match(regex);\n if (matches) return parseFloat(matches[matches.length - 2]);\n }\n return null;\n};\nconst osMatchers = [\n [\n new RegExp(XBOX + '; ' + XBOX + ' (.*?)[);]', 'i'),\n (match)=>[\n XBOX,\n match && match[1] || ''\n ]\n ],\n [\n new RegExp(NINTENDO, 'i'),\n [\n NINTENDO,\n ''\n ]\n ],\n [\n new RegExp(PLAYSTATION, 'i'),\n [\n PLAYSTATION,\n ''\n ]\n ],\n [\n BLACKBERRY_REGEX,\n [\n BLACKBERRY,\n ''\n ]\n ],\n [\n new RegExp(WINDOWS, 'i'),\n (_, user_agent)=>{\n if (/Phone/.test(user_agent) || /WPDesktop/.test(user_agent)) return [\n WINDOWS_PHONE,\n ''\n ];\n if (new RegExp(MOBILE).test(user_agent) && !/IEMobile\\b/.test(user_agent)) return [\n WINDOWS + ' ' + MOBILE,\n ''\n ];\n const match = /Windows NT ([0-9.]+)/i.exec(user_agent);\n if (match && match[1]) {\n const version = match[1];\n let osVersion = windowsVersionMap[version] || '';\n if (/arm/i.test(user_agent)) osVersion = 'RT';\n return [\n WINDOWS,\n osVersion\n ];\n }\n return [\n WINDOWS,\n ''\n ];\n }\n ],\n [\n /((iPhone|iPad|iPod).*?OS (\\d+)_(\\d+)_?(\\d+)?|iPhone)/,\n (match)=>{\n if (match && match[3]) {\n const versionParts = [\n match[3],\n match[4],\n match[5] || '0'\n ];\n return [\n IOS,\n versionParts.join('.')\n ];\n }\n return [\n IOS,\n ''\n ];\n }\n ],\n [\n /(watch.*\\/(\\d+\\.\\d+\\.\\d+)|watch os,(\\d+\\.\\d+),)/i,\n (match)=>{\n let version = '';\n if (match && match.length >= 3) version = isUndefined(match[2]) ? match[3] : match[2];\n return [\n 'watchOS',\n version\n ];\n }\n ],\n [\n new RegExp('(' + ANDROID + ' (\\\\d+)\\\\.(\\\\d+)\\\\.?(\\\\d+)?|' + ANDROID + ')', 'i'),\n (match)=>{\n if (match && match[2]) {\n const versionParts = [\n match[2],\n match[3],\n match[4] || '0'\n ];\n return [\n ANDROID,\n versionParts.join('.')\n ];\n }\n return [\n ANDROID,\n ''\n ];\n }\n ],\n [\n /Mac OS X (\\d+)[_.](\\d+)[_.]?(\\d+)?/i,\n (match)=>{\n const result = [\n 'Mac OS X',\n ''\n ];\n if (match && match[1]) {\n const versionParts = [\n match[1],\n match[2],\n match[3] || '0'\n ];\n result[1] = versionParts.join('.');\n }\n return result;\n }\n ],\n [\n /Mac/i,\n [\n 'Mac OS X',\n ''\n ]\n ],\n [\n /CrOS/,\n [\n CHROME_OS,\n ''\n ]\n ],\n [\n /Linux|debian/i,\n [\n 'Linux',\n ''\n ]\n ]\n];\nconst detectOS = function(user_agent) {\n for(let i = 0; i < osMatchers.length; i++){\n const [rgex, resultOrFn] = osMatchers[i];\n const match = rgex.exec(user_agent);\n const result = match && (isFunction(resultOrFn) ? resultOrFn(match, user_agent) : resultOrFn);\n if (result) return result;\n }\n return [\n '',\n ''\n ];\n};\nconst detectDevice = function(user_agent) {\n if (NINTENDO_REGEX.test(user_agent)) return NINTENDO;\n if (PLAYSTATION_REGEX.test(user_agent)) return PLAYSTATION;\n if (XBOX_REGEX.test(user_agent)) return XBOX;\n if (new RegExp(OUYA, 'i').test(user_agent)) return OUYA;\n if (new RegExp('(' + WINDOWS_PHONE + '|WPDesktop)', 'i').test(user_agent)) return WINDOWS_PHONE;\n else if (/iPad/.test(user_agent)) return IPAD;\n else if (/iPod/.test(user_agent)) return 'iPod Touch';\n else if (/iPhone/.test(user_agent)) return 'iPhone';\n else if (/(watch)(?: ?os[,/]|\\d,\\d\\/)[\\d.]+/i.test(user_agent)) return APPLE_WATCH;\n else if (BLACKBERRY_REGEX.test(user_agent)) return BLACKBERRY;\n else if (/(kobo)\\s(ereader|touch)/i.test(user_agent)) return 'Kobo';\n else if (new RegExp(NOKIA, 'i').test(user_agent)) return NOKIA;\n else if (/(kf[a-z]{2}wi|aeo[c-r]{2})( bui|\\))/i.test(user_agent) || /(kf[a-z]+)( bui|\\)).+silk\\//i.test(user_agent)) return 'Kindle Fire';\n else if (/(Android|ZTE)/i.test(user_agent)) if (!(!new RegExp(MOBILE).test(user_agent) || /(9138B|TB782B|Nexus [97]|pixel c|HUAWEISHT|BTV|noble nook|smart ultra 6)/i.test(user_agent))) return ANDROID;\n else {\n if (/pixel[\\daxl ]{1,6}/i.test(user_agent) && !/pixel c/i.test(user_agent) || /(huaweimed-al00|tah-|APA|SM-G92|i980|zte|U304AA)/i.test(user_agent) || /lmy47v/i.test(user_agent) && !/QTAQZ3/i.test(user_agent)) return ANDROID;\n return ANDROID_TABLET;\n }\n else if (new RegExp('(pda|' + MOBILE + ')', 'i').test(user_agent)) return GENERIC_MOBILE;\n else if (new RegExp(TABLET, 'i').test(user_agent) && !new RegExp(TABLET + ' pc', 'i').test(user_agent)) return GENERIC_TABLET;\n else return '';\n};\nconst detectDeviceType = function(user_agent, options) {\n const device = detectDevice(user_agent);\n if (device === IPAD || device === ANDROID_TABLET || 'Kobo' === device || 'Kindle Fire' === device || device === GENERIC_TABLET) return TABLET;\n if (device === NINTENDO || device === XBOX || device === PLAYSTATION || device === OUYA) return 'Console';\n if (device === APPLE_WATCH) return 'Wearable';\n if (device) return MOBILE;\n if (options?.userAgentDataPlatform === 'Android' && (options?.maxTouchPoints ?? 0) > 0) {\n const shortSide = Math.min(options?.screenWidth ?? 0, options?.screenHeight ?? 0);\n const shortSideDp = shortSide / (options?.devicePixelRatio ?? 1);\n return shortSideDp >= 600 ? TABLET : MOBILE;\n }\n return 'Desktop';\n};\nexport { detectBrowser, detectBrowserVersion, detectDevice, detectDeviceType, detectOS };\n","export * from \"./bot-detection.mjs\";\nexport * from \"./bucketed-rate-limiter.mjs\";\nexport * from \"./number-utils.mjs\";\nexport * from \"./string-utils.mjs\";\nexport * from \"./type-utils.mjs\";\nexport * from \"./promise-queue.mjs\";\nexport * from \"./logger.mjs\";\nexport * from \"./user-agent-utils.mjs\";\nconst STRING_FORMAT = 'utf8';\nconst UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\nfunction isValidUUID(value) {\n return 'string' == typeof value && UUID_REGEX.test(value);\n}\nfunction getEventUuid(uuid, generateUuid) {\n return isValidUUID(uuid) ? uuid : generateUuid();\n}\nfunction assert(truthyValue, message) {\n if (!truthyValue || 'string' != typeof truthyValue || isEmpty(truthyValue)) throw new Error(message);\n}\nfunction isEmpty(truthyValue) {\n if (0 === truthyValue.trim().length) return true;\n return false;\n}\nfunction removeTrailingSlash(url) {\n return url?.replace(/\\/+$/, '');\n}\nfunction stripUrlHash(url) {\n if (!url) return url;\n return url.split('#')[0];\n}\nasync function retriable(fn, props) {\n let lastError = null;\n for(let i = 0; i < props.retryCount + 1; i++){\n if (i > 0) await new Promise((r)=>setTimeout(r, props.retryDelay));\n try {\n const res = await fn();\n return res;\n } catch (e) {\n lastError = e;\n if (!props.retryCheck(e)) throw e;\n }\n }\n throw lastError;\n}\nfunction currentTimestamp() {\n return new Date().getTime();\n}\nfunction currentISOTime() {\n return new Date().toISOString();\n}\nfunction safeSetTimeout(fn, timeout) {\n const t = setTimeout(fn, timeout);\n t?.unref && t?.unref();\n return t;\n}\nconst isPromise = (obj)=>obj && 'function' == typeof obj.then;\nconst isError = (x)=>x instanceof Error;\nfunction getFetch() {\n return 'undefined' != typeof fetch ? fetch : void 0 !== globalThis.fetch ? globalThis.fetch : void 0;\n}\nfunction allSettled(promises) {\n return Promise.all(promises.map((p)=>(p ?? Promise.resolve()).then((value)=>({\n status: 'fulfilled',\n value\n }), (reason)=>({\n status: 'rejected',\n reason\n }))));\n}\nexport { STRING_FORMAT, UUID_REGEX, allSettled, assert, currentISOTime, currentTimestamp, getEventUuid, getFetch, isError, isPromise, isValidUUID, removeTrailingSlash, retriable, safeSetTimeout, stripUrlHash };\n","let parsedStackResults;\nlet lastKeysCount;\nlet cachedFilenameChunkIds;\nfunction getFilenameToChunkIdMap(stackParser) {\n const chunkIdMap = globalThis._posthogChunkIds;\n if (!chunkIdMap) return;\n const chunkIdKeys = Object.keys(chunkIdMap);\n if (cachedFilenameChunkIds && chunkIdKeys.length === lastKeysCount) return cachedFilenameChunkIds;\n lastKeysCount = chunkIdKeys.length;\n cachedFilenameChunkIds = chunkIdKeys.reduce((acc, stackKey)=>{\n if (!parsedStackResults) parsedStackResults = {};\n const result = parsedStackResults[stackKey];\n if (result) acc[result[0]] = result[1];\n else {\n const parsedStack = stackParser(stackKey);\n for(let i = parsedStack.length - 1; i >= 0; i--){\n const stackFrame = parsedStack[i];\n const filename = stackFrame?.filename;\n const chunkId = chunkIdMap[stackKey];\n if (filename && chunkId) {\n acc[filename] = chunkId;\n parsedStackResults[stackKey] = [\n filename,\n chunkId\n ];\n break;\n }\n }\n }\n return acc;\n }, {});\n return cachedFilenameChunkIds;\n}\nexport { getFilenameToChunkIdMap };\n","import { SurveyValidationType } from \"../types.mjs\";\nfunction getValidationError(value, rules, optional) {\n const trimmed = value.trim();\n if (!optional && '' === trimmed) return 'This field is required';\n if ('' === trimmed) return false;\n if (rules && rules.length > 0) for (const rule of rules)switch(rule.type){\n case SurveyValidationType.MinLength:\n if (void 0 !== rule.value && trimmed.length < rule.value) return rule.errorMessage ?? `Please enter at least ${rule.value} characters`;\n break;\n case SurveyValidationType.MaxLength:\n if (void 0 !== rule.value && trimmed.length > rule.value) return rule.errorMessage ?? `Please enter no more than ${rule.value} characters`;\n break;\n }\n return false;\n}\nfunction getLengthFromRules(rules, type) {\n if (!rules) return;\n const rule = rules.find((r)=>r.type === type);\n return rule?.value;\n}\nfunction getRequirementsHint(minLength, maxLength) {\n const effectiveMin = 1 === minLength ? void 0 : minLength;\n if (effectiveMin && maxLength) return `Enter ${effectiveMin}-${maxLength} characters`;\n if (effectiveMin) {\n const plural = 1 === effectiveMin ? 'character' : 'characters';\n return `Enter at least ${effectiveMin} ${plural}`;\n }\n if (maxLength) {\n const plural = 1 === maxLength ? 'character' : 'characters';\n return `Maximum ${maxLength} ${plural}`;\n }\n}\nexport { getLengthFromRules, getRequirementsHint, getValidationError };\n","import { isUndefined } from \"../../utils/index.mjs\";\nconst UNKNOWN_FUNCTION = '?';\nfunction createFrame(platform, filename, func, lineno, colno) {\n const frame = {\n platform,\n filename,\n function: '<anonymous>' === func ? UNKNOWN_FUNCTION : func,\n in_app: true\n };\n if (!isUndefined(lineno)) frame.lineno = lineno;\n if (!isUndefined(colno)) frame.colno = colno;\n return frame;\n}\nexport { UNKNOWN_FUNCTION, createFrame };\n","import { UNKNOWN_FUNCTION } from \"./base.mjs\";\nconst extractSafariExtensionDetails = (func, filename)=>{\n const isSafariExtension = -1 !== func.indexOf('safari-extension');\n const isSafariWebExtension = -1 !== func.indexOf('safari-web-extension');\n return isSafariExtension || isSafariWebExtension ? [\n -1 !== func.indexOf('@') ? func.split('@')[0] : UNKNOWN_FUNCTION,\n isSafariExtension ? `safari-extension:${filename}` : `safari-web-extension:${filename}`\n ] : [\n func,\n filename\n ];\n};\nexport { extractSafariExtensionDetails };\n","import { UNKNOWN_FUNCTION, createFrame } from \"./base.mjs\";\nimport { extractSafariExtensionDetails } from \"./safari.mjs\";\nconst chromeRegexNoFnName = /^\\s*at (\\S+?)(?::(\\d+))(?::(\\d+))\\s*$/i;\nconst chromeRegex = /^\\s*at (?:(.+?\\)(?: \\[.+\\])?|.*?) ?\\((?:address at )?)?(?:async )?((?:<anonymous>|[-a-z]+:|.*bundle|\\/)?.*?)(?::(\\d+))?(?::(\\d+))?\\)?\\s*$/i;\nconst chromeEvalRegex = /\\((\\S*)(?::(\\d+))(?::(\\d+))\\)/;\nconst chromeStackLineParser = (line, platform)=>{\n const noFnParts = chromeRegexNoFnName.exec(line);\n if (noFnParts) {\n const [, filename, line, col] = noFnParts;\n return createFrame(platform, filename, UNKNOWN_FUNCTION, +line, +col);\n }\n const parts = chromeRegex.exec(line);\n if (parts) {\n const isEval = parts[2] && 0 === parts[2].indexOf('eval');\n if (isEval) {\n const subMatch = chromeEvalRegex.exec(parts[2]);\n if (subMatch) {\n parts[2] = subMatch[1];\n parts[3] = subMatch[2];\n parts[4] = subMatch[3];\n }\n }\n const [func, filename] = extractSafariExtensionDetails(parts[1] || UNKNOWN_FUNCTION, parts[2]);\n return createFrame(platform, filename, func, parts[3] ? +parts[3] : void 0, parts[4] ? +parts[4] : void 0);\n }\n};\nexport { chromeStackLineParser };\n","import { UNKNOWN_FUNCTION, createFrame } from \"./base.mjs\";\nimport { extractSafariExtensionDetails } from \"./safari.mjs\";\nconst geckoREgex = /^\\s*(.*?)(?:\\((.*?)\\))?(?:^|@)?((?:[-a-z]+)?:\\/.*?|\\[native code\\]|[^@]*(?:bundle|\\d+\\.js)|\\/[\\w\\-. /=]+)(?::(\\d+))?(?::(\\d+))?\\s*$/i;\nconst geckoEvalRegex = /(\\S+) line (\\d+)(?: > eval line \\d+)* > eval/i;\nconst geckoStackLineParser = (line, platform)=>{\n const parts = geckoREgex.exec(line);\n if (parts) {\n const isEval = parts[3] && parts[3].indexOf(' > eval') > -1;\n if (isEval) {\n const subMatch = geckoEvalRegex.exec(parts[3]);\n if (subMatch) {\n parts[1] = parts[1] || 'eval';\n parts[3] = subMatch[1];\n parts[4] = subMatch[2];\n parts[5] = '';\n }\n }\n let filename = parts[3];\n let func = parts[1] || UNKNOWN_FUNCTION;\n [func, filename] = extractSafariExtensionDetails(func, filename);\n return createFrame(platform, filename, func, parts[4] ? +parts[4] : void 0, parts[5] ? +parts[5] : void 0);\n }\n};\nexport { geckoStackLineParser };\n","import { UNKNOWN_FUNCTION } from \"./base.mjs\";\nimport { chromeStackLineParser } from \"./chrome.mjs\";\nimport { geckoStackLineParser } from \"./gecko.mjs\";\nimport { winjsStackLineParser } from \"./winjs.mjs\";\nimport { opera10StackLineParser, opera11StackLineParser } from \"./opera.mjs\";\nimport { nodeStackLineParser } from \"./node.mjs\";\nconst WEBPACK_ERROR_REGEXP = /\\(error: (.*)\\)/;\nconst STACKTRACE_FRAME_LIMIT = 50;\nfunction reverseAndStripFrames(stack) {\n if (!stack.length) return [];\n const localStack = Array.from(stack);\n localStack.reverse();\n return localStack.slice(0, STACKTRACE_FRAME_LIMIT).map((frame)=>({\n ...frame,\n filename: frame.filename || getLastStackFrame(localStack).filename,\n function: frame.function || UNKNOWN_FUNCTION\n }));\n}\nfunction getLastStackFrame(arr) {\n return arr[arr.length - 1] || {};\n}\nfunction createDefaultStackParser() {\n return createStackParser(\"web:javascript\", chromeStackLineParser, geckoStackLineParser);\n}\nfunction createStackParser(platform, ...parsers) {\n return (stack, skipFirstLines = 0)=>{\n const frames = [];\n const lines = stack.split('\\n');\n for(let i = skipFirstLines; i < lines.length; i++){\n const line = lines[i];\n if (line.length > 1024) continue;\n const cleanedLine = WEBPACK_ERROR_REGEXP.test(line) ? line.replace(WEBPACK_ERROR_REGEXP, '$1') : line;\n if (!cleanedLine.match(/\\S*Error: /)) {\n for (const parser of parsers){\n const frame = parser(cleanedLine, platform);\n if (frame) {\n frames.push(frame);\n break;\n }\n }\n if (frames.length >= STACKTRACE_FRAME_LIMIT) break;\n }\n }\n return reverseAndStripFrames(frames);\n };\n}\nexport { chromeStackLineParser, createDefaultStackParser, createStackParser, geckoStackLineParser, nodeStackLineParser, opera10StackLineParser, opera11StackLineParser, reverseAndStripFrames, winjsStackLineParser };\n","const ERROR_TYPES_PATTERN = /^(?:[Uu]ncaught (?:exception: )?)?(?:((?:Eval|Internal|Range|Reference|Syntax|Type|URI|)Error): )?(.*)$/i;\nclass StringCoercer {\n match(input) {\n return 'string' == typeof input;\n }\n coerce(input, ctx) {\n const [type, value] = this.getInfos(input);\n return {\n type: type ?? 'Error',\n value: value ?? input,\n stack: ctx.syntheticException?.stack,\n synthetic: true\n };\n }\n getInfos(candidate) {\n let type = 'Error';\n let value = candidate;\n const groups = candidate.match(ERROR_TYPES_PATTERN);\n if (groups) {\n type = groups[1];\n value = groups[2];\n }\n return [\n type,\n value\n ];\n }\n}\nexport { StringCoercer };\n","const severityLevels = [\n 'fatal',\n 'error',\n 'warning',\n 'log',\n 'info',\n 'debug'\n];\nexport { severityLevels };\n","function truncate(str, max = 0) {\n if ('string' != typeof str || 0 === max) return str;\n return str.length <= max ? str : `${str.slice(0, max)}...`;\n}\nfunction extractExceptionKeysForMessage(err, maxLength = 40) {\n const keys = Object.keys(err);\n keys.sort();\n if (!keys.length) return '[object has no keys]';\n for(let i = keys.length; i > 0; i--){\n const serialized = keys.slice(0, i).join(', ');\n if (!(serialized.length > maxLength)) {\n if (i === keys.length) return serialized;\n return serialized.length <= maxLength ? serialized : `${serialized.slice(0, maxLength)}...`;\n }\n }\n return '';\n}\nexport { extractExceptionKeysForMessage, truncate };\n","import type { PostHog } from '../posthog-core'\nimport { SessionIdManager } from '../sessionid'\nimport {\n DeadClicksAutoCaptureConfig,\n ExternalIntegrationKind,\n Properties,\n RemoteConfig,\n SiteAppLoader,\n SessionStartReason,\n} from '../types'\nimport type {\n ConversationsRemoteConfig,\n GetMessagesResponse,\n GetTicketsOptions,\n GetTicketsResponse,\n MarkAsReadResponse,\n RestoreFromTokenResponse,\n RequestRestoreLinkResponse,\n SendMessageResponse,\n UserProvidedTraits,\n} from '../posthog-conversations-types'\n// only importing types here, so won't affect the bundle\n// eslint-disable-next-line posthog-js/no-external-replay-imports\nimport type { SessionRecordingStatus, TriggerType } from '../extensions/replay/external/triggerMatching'\nimport type { TracingHeadersDistinctId, TracingHeadersHostnames } from '../extensions/tracing-headers-types'\nimport { eventWithTime } from '../extensions/replay/types/rrweb-types'\nimport { ErrorTracking } from '@posthog/core'\n\n/*\n * Global helpers to protect access to browser globals in a way that is safer for different targets\n * like DOM, SSR, Web workers etc.\n *\n * NOTE: Typically we want the \"window\" but globalThis works for both the typical browser context as\n * well as other contexts such as the web worker context. Window is still exported for any bits that explicitly require it.\n * If in doubt - export the global you need from this file and use that as an optional value. This way the code path is forced\n * to handle the case where the global is not available.\n */\n\n// eslint-disable-next-line no-restricted-globals\nconst win: (Window & typeof globalThis) | undefined = typeof window !== 'undefined' ? window : undefined\n\nexport type AssignableWindow = Window &\n typeof globalThis & {\n /*\n * Main PostHog instance\n */\n posthog: any\n\n /*\n * This is our contract between (potentially) lazily loaded extensions and the SDK\n */\n __PosthogExtensions__?: PostHogExtensions\n\n /**\n * When loading remote config, we assign it to this global configuration\n * for ease of sharing it with the rest of the SDK\n */\n _POSTHOG_REMOTE_CONFIG?: Record<\n string,\n {\n config: RemoteConfig\n siteApps: SiteAppLoader[]\n }\n >\n\n /**\n * If this is set on the window, our logger will log to the console\n * for ease of debugging. Used for testing purposes only.\n *\n * @see {Config.DEBUG} from config.ts\n */\n POSTHOG_DEBUG: any\n\n // Exposed by the browser\n doNotTrack: any\n\n // See entrypoints/customizations.full.ts\n posthogCustomizations: any\n\n /**\n * This is a legacy way to expose these functions, but we still need to support it for backwards compatibility\n * Can be removed once we drop support for 1.161.1\n *\n * See entrypoints/exception-autocapture.ts\n *\n * @deprecated use `__PosthogExtensions__.errorWrappingFunctions` instead\n */\n posthogErrorWrappingFunctions: any\n\n /**\n * This is a legacy way to expose these functions, but we still need to support it for backwards compatibility\n * Can be removed once we drop support for 1.161.1\n *\n * See entrypoints/posthog-recorder.ts\n *\n * @deprecated use `__PosthogExtensions__.rrweb` instead\n */\n rrweb: any\n\n /**\n * This is a legacy way to expose these functions, but we still need to support it for backwards compatibility\n * Can be removed once we drop support for 1.161.1\n *\n * See entrypoints/posthog-recorder.ts\n *\n * @deprecated use `__PosthogExtensions__.rrwebConsoleRecord` instead\n */\n rrwebConsoleRecord: any\n\n /**\n * This is a legacy way to expose these functions, but we still need to support it for backwards compatibility\n * Can be removed once we drop support for 1.161.1\n *\n * See entrypoints/posthog-recorder.ts\n *\n * @deprecated use `__PosthogExtensions__.getRecordNetworkPlugin` instead\n */\n getRecordNetworkPlugin: any\n\n /**\n * This is a legacy way to expose these functions, but we still need to support it for backwards compatibility\n * Can be removed once we drop support for 1.161.1\n *\n * See entrypoints/web-vitals.ts\n *\n * @deprecated use `__PosthogExtensions__.postHogWebVitalsCallbacks` instead\n */\n postHogWebVitalsCallbacks: any\n\n /**\n * This is a legacy way to expose these functions, but we still need to support it for backwards compatibility\n * Can be removed once we drop support for 1.161.1\n *\n * See entrypoints/tracing-headers.ts\n *\n * @deprecated use `__PosthogExtensions__.postHogTracingHeadersPatchFns` instead\n */\n postHogTracingHeadersPatchFns: any\n\n /**\n * This is a legacy way to expose these functions, but we still need to support it for backwards compatibility\n * Can be removed once we drop support for 1.161.1\n *\n * See entrypoints/surveys.ts\n *\n * @deprecated use `__PosthogExtensions__.generateSurveys` instead\n */\n extendPostHogWithSurveys: any\n\n /*\n * These are used to handle our toolbar state.\n * @see {Toolbar} from extensions/toolbar.ts\n */\n ph_load_toolbar: any\n ph_load_editor: any\n ph_toolbar_state: any\n } & Record<`__$$ph_site_app_${string}`, any>\n\n/**\n * This is our contract between (potentially) lazily loaded extensions and the SDK\n * changes to this interface can be breaking changes for users of the SDK\n */\n\nexport type ExternalExtensionKind = 'intercom-integration' | 'crisp-chat-integration'\n\nexport type PostHogExtensionKind =\n | 'toolbar'\n | 'exception-autocapture'\n | 'web-vitals'\n | 'web-vitals-with-attribution'\n | 'recorder'\n | 'lazy-recorder'\n | 'tracing-headers'\n | 'surveys'\n | 'logs'\n | 'conversations'\n | 'product-tours'\n | 'dead-clicks-autocapture'\n | 'remote-config'\n | ExternalExtensionKind\n\nexport interface LazyLoadedSessionRecordingInterface {\n start: (startReason?: SessionStartReason) => void\n stop: () => void\n discard: () => void\n sessionId: string\n status: SessionRecordingStatus\n onRRwebEmit: (rawEvent: eventWithTime) => void\n log: (message: string, level: 'log' | 'warn' | 'error') => void\n sdkDebugProperties: Properties\n overrideLinkedFlag: () => void\n overrideSampling: () => void\n overrideTrigger: (triggerType: TriggerType) => void\n isStarted: boolean\n tryAddCustomEvent(tag: string, payload: any): boolean\n}\n\nexport interface LazyLoadedDeadClicksAutocaptureInterface {\n start: (observerTarget: Node) => void\n stop: () => void\n}\n\nexport interface LazyLoadedConversationsInterface {\n // Widget control\n show: () => void\n hide: () => void\n isVisible: () => boolean\n\n // Lifecycle\n reset: () => void\n\n // Identity verification\n setIdentity: () => void\n clearIdentity: () => void\n\n // API methods\n sendMessage: (message: string, userTraits?: UserProvidedTraits, newTicket?: boolean) => Promise<SendMessageResponse>\n getMessages: (ticketId?: string, after?: string) => Promise<GetMessagesResponse>\n markAsRead: (ticketId?: string) => Promise<MarkAsReadResponse>\n getTickets: (options?: GetTicketsOptions) => Promise<GetTicketsResponse>\n requestRestoreLink: (email: string) => Promise<RequestRestoreLinkResponse>\n restoreFromToken: (restoreToken: string) => Promise<RestoreFromTokenResponse>\n restoreFromUrlToken: () => Promise<RestoreFromTokenResponse | null>\n getCurrentTicketId: () => string | null\n getWidgetSessionId: () => string\n}\n\ninterface PostHogExtensions {\n loadExternalDependency?: (\n posthog: PostHog,\n kind: PostHogExtensionKind,\n callback: (error?: string | Event, event?: Event) => void\n ) => void\n\n loadSiteApp?: (posthog: PostHog, appUrl: string, callback: (error?: string | Event, event?: Event) => void) => void\n\n errorWrappingFunctions?: {\n wrapOnError: (captureFn: (props: ErrorTracking.ErrorProperties) => void) => () => void\n wrapUnhandledRejection: (captureFn: (props: ErrorTracking.ErrorProperties) => void) => () => void\n wrapConsoleError: (captureFn: (props: ErrorTracking.ErrorProperties) => void) => () => void\n }\n rrweb?: { record: any; version: string; wasMaxDepthReached?: () => boolean; resetMaxDepthState?: () => void }\n rrwebPlugins?: { getRecordConsolePlugin: any; getRecordNetworkPlugin?: any }\n generateSurveys?: (posthog: PostHog, isSurveysEnabled: boolean) => any | undefined\n generateProductTours?: (posthog: PostHog, isEnabled: boolean) => any | undefined\n logs?: {\n initializeLogs?: (posthog: PostHog) => any | undefined\n }\n postHogWebVitalsCallbacks?: {\n onLCP: (metric: any) => void\n onCLS: (metric: any) => void\n onFCP: (metric: any) => void\n onINP: (metric: any) => void\n }\n /**\n * @deprecated\n *\n * this was introduced briefly, it is now always a no-op and only kept for backwards compatibility\n */\n loadWebVitalsCallbacks?: (useAttribution?: boolean) => PostHogExtensions['postHogWebVitalsCallbacks']\n tracingHeadersPatchFns?: {\n _patchFetch: (\n hostnames: TracingHeadersHostnames,\n distinctId: TracingHeadersDistinctId,\n sessionManager?: SessionIdManager\n ) => () => void\n _patchXHR: (\n hostnames: TracingHeadersHostnames,\n distinctId: TracingHeadersDistinctId,\n sessionManager?: SessionIdManager\n ) => () => void\n }\n initDeadClicksAutocapture?: (\n ph: PostHog,\n config: DeadClicksAutoCaptureConfig\n ) => LazyLoadedDeadClicksAutocaptureInterface\n integrations?: {\n [K in ExternalIntegrationKind]?: { start: (posthog: PostHog) => void; stop: () => void }\n }\n initSessionRecording?: (ph: PostHog) => LazyLoadedSessionRecordingInterface\n initConversations?: (config: ConversationsRemoteConfig, posthog: PostHog) => LazyLoadedConversationsInterface\n}\n\nconst global: typeof globalThis | undefined = typeof globalThis !== 'undefined' ? globalThis : win\n\n// React Native polyfills for posthog-js compatibility\nif (typeof self === 'undefined') {\n ;(global as any).self = global\n}\nif (typeof File === 'undefined') {\n ;(global as any).File = function () {}\n}\n\nexport const navigator = global?.navigator\nexport const document = global?.document\nexport const location = global?.location\nexport const fetch = global?.fetch\nexport const XMLHttpRequest =\n global?.XMLHttpRequest && 'withCredentials' in new global.XMLHttpRequest() ? global.XMLHttpRequest : undefined\nexport const AbortController = global?.AbortController\nexport const CompressionStream = global?.CompressionStream\nexport const userAgent = navigator?.userAgent\nexport const assignableWindow: AssignableWindow = win ?? ({} as any)\n\nexport { win as window }\n","import { window } from './globals'\n\n// When angular patches functions they pass the above `isNativeFunction` check (at least the MutationObserver)\nexport const isAngularZonePresent = (): boolean => {\n return !!(window as any).Zone\n}\n\nexport const isDocument = (x: unknown): x is Document => {\n // eslint-disable-next-line posthog-js/no-direct-document-check\n return x instanceof Document\n}\n","import Config from '../config'\nimport { isUndefined } from '@posthog/core'\nimport { assignableWindow, window } from './globals'\nimport type { Logger } from '@posthog/core'\n\ntype CreateLoggerOptions = {\n debugEnabled?: boolean\n}\n\ntype PosthogJsLogger = Omit<Logger, 'createLogger'> & {\n _log: (level: 'debug' | 'log' | 'warn' | 'error', ...args: any[]) => void\n uninitializedWarning: (methodName: string) => void\n createLogger: (prefix: string, options?: CreateLoggerOptions) => PosthogJsLogger\n}\n\nconst _createLogger = (prefix: string, { debugEnabled }: CreateLoggerOptions = {}): PosthogJsLogger => {\n const logger: PosthogJsLogger = {\n _log: (level: 'debug' | 'log' | 'warn' | 'error', ...args: any[]) => {\n if (\n window &&\n (Config.DEBUG || assignableWindow.POSTHOG_DEBUG || debugEnabled) &&\n !isUndefined(window.console) &&\n window.console\n ) {\n const consoleLog =\n '__rrweb_original__' in window.console[level]\n ? (window.console[level] as any)['__rrweb_original__']\n : window.console[level]\n\n // eslint-disable-next-line no-console\n consoleLog(prefix, ...args)\n }\n },\n\n debug: (...args: any[]) => {\n logger._log('debug', ...args)\n },\n\n info: (...args: any[]) => {\n logger._log('log', ...args)\n },\n\n warn: (...args: any[]) => {\n logger._log('warn', ...args)\n },\n\n error: (...args: any[]) => {\n logger._log('error', ...args)\n },\n\n critical: (...args: any[]) => {\n // Critical errors are always logged to the console\n // eslint-disable-next-line no-console\n console.error(prefix, ...args)\n },\n\n uninitializedWarning: (methodName: string) => {\n logger.error(`You must initialize PostHog before calling ${methodName}`)\n },\n\n createLogger: (additionalPrefix: string, options?: CreateLoggerOptions) =>\n _createLogger(`${prefix} ${additionalPrefix}`, options),\n }\n return logger\n}\n\nexport const logger = _createLogger('[PostHog.js]')\n\nexport const createLogger = logger.createLogger\n","import { PostHogConfig, Properties } from '../types'\nimport { logger } from './logger'\nimport { isFormData, isNullish, isNumber, isString, hasOwnProperty, isArray } from '@posthog/core'\n\nexport function find<T>(value: T[], predicate: (value: T) => boolean): T | undefined {\n for (let i = 0; i < value.length; i++) {\n if (predicate(value[i])) {\n return value[i]\n }\n }\n return undefined\n}\n\nexport function eachArray<E = any>(obj: E[] | null | undefined, iterator: (value: E, key: number) => void): void {\n if (isArray(obj)) {\n obj.forEach(iterator)\n }\n}\n\nexport function each(obj: any, iterator: (value: any, key: any) => void): void {\n if (isNullish(obj)) {\n return\n }\n if (isArray(obj)) {\n obj.forEach(iterator)\n return\n }\n if (isFormData(obj)) {\n obj.forEach((val: any, key: any) => iterator(val, key))\n return\n }\n for (const key in obj) {\n if (hasOwnProperty.call(obj, key)) {\n iterator(obj[key], key)\n }\n }\n}\n\nexport const extend = function (obj: Record<string, any>, ...args: Record<string, any>[]): Record<string, any> {\n for (const source of args) {\n for (const prop in source) {\n if (source[prop] !== void 0) {\n obj[prop] = source[prop]\n }\n }\n }\n return obj\n}\n\n/**\n * Object.entries() polyfill\n * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries\n */\nexport function entries<T = any>(obj: Record<string, T>): [string, T][] {\n const ownProps = Object.keys(obj)\n let i = ownProps.length\n const resArray = new Array(i) // preallocate the Array\n\n while (i--) {\n resArray[i] = [ownProps[i], obj[ownProps[i]]]\n }\n return resArray\n}\n\nexport const trySafe = function <T>(fn: () => T): T | undefined {\n try {\n return fn()\n } catch {\n return undefined\n }\n}\n\nexport const safewrap = function <F extends (...args: any[]) => any = (...args: any[]) => any>(f: F): F {\n return function (...args) {\n try {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n return f.apply(this, args)\n } catch (e) {\n logger.critical(\n 'Implementation error. Please turn on debug mode and open a ticket on https://app.posthog.com/home#panel=support%3Asupport%3A.'\n )\n logger.critical(e)\n }\n } as F\n}\n\n// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\nexport const safewrapClass = function (klass: Function, functions: string[]): void {\n for (let i = 0; i < functions.length; i++) {\n klass.prototype[functions[i]] = safewrap(klass.prototype[functions[i]])\n }\n}\n\nexport const stripEmptyProperties = function (p: Properties): Properties {\n const ret: Properties = {}\n each(p, function (v, k) {\n if ((isString(v) && v.length > 0) || isNumber(v)) {\n ret[k] = v\n }\n })\n return ret\n}\n\n/**\n * Deep copies an object.\n * It handles cycles by replacing all references to them with `undefined`\n * Also supports customizing native values\n *\n * @param value\n * @param customizer\n * @returns {{}|undefined|*}\n */\nfunction deepCircularCopy<T extends Record<string, any> = Record<string, any>>(\n value: T,\n customizer?: <K extends keyof T = keyof T>(value: T[K], key?: K) => T[K]\n): T | undefined {\n const COPY_IN_PROGRESS_SET = new Set()\n\n function internalDeepCircularCopy(value: T, key?: string): T | undefined {\n if (value !== Object(value)) return customizer ? customizer(value as any, key) : value // primitive value\n\n if (COPY_IN_PROGRESS_SET.has(value)) return undefined\n COPY_IN_PROGRESS_SET.add(value)\n let result: T\n\n if (isArray(value)) {\n result = [] as any as T\n eachArray(value, (it) => {\n result.push(internalDeepCircularCopy(it))\n })\n } else {\n result = {} as T\n each(value, (val, key) => {\n if (!COPY_IN_PROGRESS_SET.has(val)) {\n ;(result as any)[key] = internalDeepCircularCopy(val, key)\n }\n })\n }\n return result\n }\n return internalDeepCircularCopy(value)\n}\n\nexport function _copyAndTruncateStrings<T extends Record<string, any> = Record<string, any>>(\n object: T,\n maxStringLength: number\n): T {\n return deepCircularCopy(object, (value: any) => {\n if (isString(value)) {\n return (value as string).slice(0, maxStringLength)\n }\n return value\n }) as T\n}\n\n// NOTE: Update PostHogConfig docs if you change this list\n// We will not try to catch all bullets here, but we should make an effort to catch the most common ones\n// You should be highly against adding more to this list, because ultimately customers can configure\n// their `cross_subdomain_cookie` setting to anything they want.\nconst EXCLUDED_FROM_CROSS_SUBDOMAIN_COOKIE = ['herokuapp.com', 'vercel.app', 'netlify.app']\nexport function isCrossDomainCookie(documentLocation: Location | undefined) {\n const hostname = documentLocation?.hostname\n\n if (!isString(hostname)) {\n return false\n }\n // split and slice isn't a great way to match arbitrary domains,\n // but it's good enough for ensuring we only match herokuapp.com when it is the TLD\n // for the hostname\n const lastTwoParts = hostname.split('.').slice(-2).join('.')\n\n for (const excluded of EXCLUDED_FROM_CROSS_SUBDOMAIN_COOKIE) {\n if (lastTwoParts === excluded) {\n return false\n }\n }\n\n return true\n}\n\n// Use this instead of element.addEventListener to avoid eslint errors\n// this properly implements the default options for passive event listeners\nexport function addEventListener(\n element: Window | Document | Element | undefined,\n event: string,\n callback: EventListener,\n options?: AddEventListenerOptions\n): void {\n const { capture = false, passive = true } = options ?? {}\n\n // This is the only place where we are allowed to call this function\n // because the whole idea is that we should be calling this instead of the built-in one\n // eslint-disable-next-line posthog-js/no-add-event-listener\n element?.addEventListener(event, callback, { capture, passive })\n}\n\n/**\n * Helper to migrate deprecated config fields to new field names with appropriate warnings\n * @param config - The config object to check\n * @param newField - The new field name to use\n * @param oldField - The deprecated field name to check for\n * @param defaultValue - The default value if neither field is set\n * @param loggerInstance - Optional logger instance for deprecation warnings\n * @returns The value to use (new field takes precedence over old field)\n */\nexport function migrateConfigField<T>(\n config: Record<string, any>,\n newField: string,\n oldField: string,\n defaultValue: T,\n loggerInstance?: { warn: (message: string) => void }\n): T {\n const hasNewField = newField in config && !isNullish(config[newField])\n const hasOldField = oldField in config && !isNullish(config[oldField])\n\n if (hasNewField) {\n return config[newField]\n }\n\n if (hasOldField) {\n if (loggerInstance) {\n loggerInstance.warn(\n `Config field '${oldField}' is deprecated. Please use '${newField}' instead. ` +\n `The old field will be removed in a future major version.`\n )\n }\n return config[oldField]\n }\n\n return defaultValue\n}\n\nconst TOOLBAR_INTERNAL_INSTANCE_NAME = 'ph_toolbar_internal'\n\nexport function isToolbarInstance(config: Pick<PostHogConfig, 'name'>): boolean {\n return config.name === TOOLBAR_INTERNAL_INSTANCE_NAME\n}\n","import { each } from './'\n\nimport { isArray, isFile, isUndefined } from '@posthog/core'\nimport { logger } from './logger'\nimport { document } from './globals'\n\nconst localDomains = ['localhost', '127.0.0.1']\n\n/**\n * IE11 doesn't support `new URL`\n * so we can create an anchor element and use that to parse the URL\n * there's a lot of overlap between HTMLHyperlinkElementUtils and URL\n * meaning useful properties like `pathname` are available on both\n */\nexport const convertToURL = (url: string): HTMLAnchorElement | null => {\n const location = document?.createElement('a')\n if (isUndefined(location)) {\n return null\n }\n\n location.href = url\n return location\n}\n\nexport const formDataToQuery = function (formdata: Record<string, any> | FormData, arg_separator = '&'): string {\n let use_val: string\n let use_key: string\n const tph_arr: string[] = []\n\n each(formdata, function (val: File | string | undefined, key: string | undefined) {\n // the key might be literally the string undefined for e.g. if {undefined: 'something'}\n if (isUndefined(val) || isUndefined(key) || key === 'undefined') {\n return\n }\n\n use_val = encodeURIComponent(isFile(val) ? val.name : val.toString())\n use_key = encodeURIComponent(key)\n tph_arr[tph_arr.length] = use_key + '=' + use_val\n })\n\n return tph_arr.join(arg_separator)\n}\n\nexport const getQueryParam = function (url: string, param: string): string {\n const withoutHash: string = url.split('#')[0] || ''\n\n // Split only on the first ? to sort problem out for those with multiple ?s\n // and then remove them\n const queryParams: string = withoutHash.split(/\\?(.*)/)[1] || ''\n const cleanedQueryParams = queryParams.replace(/^\\?+/g, '')\n\n const queryParts = cleanedQueryParams.split('&')\n let keyValuePair\n\n for (let i = 0; i < queryParts.length; i++) {\n const parts = queryParts[i].split('=')\n if (parts[0] === param) {\n keyValuePair = parts\n break\n }\n }\n\n if (!isArray(keyValuePair) || keyValuePair.length < 2) {\n return ''\n } else {\n let result = keyValuePair[1]\n try {\n result = decodeURIComponent(result)\n } catch {\n logger.error('Skipping decoding for malformed query param: ' + result)\n }\n return result.replace(/\\+/g, ' ')\n }\n}\n\n// replace any query params in the url with the provided mask value. Tries to keep the URL as instant as possible,\n// including preserving malformed text in most cases\nexport const maskQueryParams = function <T extends string | undefined>(\n url: T,\n maskedParams: string[] | undefined,\n mask: string\n): T extends string ? string : undefined {\n if (!url || !maskedParams || !maskedParams.length) {\n return url as any\n }\n\n const splitHash = url.split('#')\n const withoutHash: string = splitHash[0] || ''\n const hash = splitHash[1]\n\n const splitQuery: string[] = withoutHash.split('?')\n const queryString: string = splitQuery[1]\n const urlWithoutQueryAndHash: string = splitQuery[0]\n const queryParts = (queryString || '').split('&')\n\n // use an array of strings rather than an object to preserve ordering and duplicates\n const paramStrings: string[] = []\n\n for (let i = 0; i < queryParts.length; i++) {\n const keyValuePair = queryParts[i].split('=')\n if (!isArray(keyValuePair)) {\n continue\n } else if (maskedParams.includes(keyValuePair[0])) {\n paramStrings.push(keyValuePair[0] + '=' + mask)\n } else {\n paramStrings.push(queryParts[i])\n }\n }\n\n let result = urlWithoutQueryAndHash\n if (queryString != null) {\n result += '?' + paramStrings.join('&')\n }\n if (hash != null) {\n result += '#' + hash\n }\n\n return result as any\n}\n\nexport const _getHashParam = function (hash: string, param: string): string | null {\n const matches = hash.match(new RegExp(param + '=([^&]*)'))\n return matches ? matches[1] : null\n}\n\nexport const isLocalhost = (): boolean => {\n return localDomains.includes(location.hostname)\n}\n","// Portions of this file are derived from getsentry/sentry-javascript\n// Copyright (c) 2012 Functional Software, Inc. dba Sentry\n// Licensed under the MIT License: https://github.com/getsentry/sentry-javascript/blob/develop/LICENSE\n\n// import { patch } from 'rrweb/typings/utils'\n// copied from https://github.com/rrweb-io/rrweb/blob/8aea5b00a4dfe5a6f59bd2ae72bb624f45e51e81/packages/rrweb/src/utils.ts#L129\nimport { isFunction } from '@posthog/core'\n\nexport function patch(\n source: { [key: string]: any },\n name: string,\n replacement: (...args: unknown[]) => unknown\n): () => void {\n try {\n if (!(name in source)) {\n return () => {\n //\n }\n }\n\n const original = source[name] as () => unknown\n const wrapped = replacement(original)\n\n // Make sure it's a function first, as we need to attach an empty prototype for `defineProperties` to work\n // otherwise it'll throw \"TypeError: Object.defineProperties called on non-object\"\n if (isFunction(wrapped)) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n wrapped.prototype = wrapped.prototype || {}\n Object.defineProperties(wrapped, {\n __posthog_wrapped__: {\n enumerable: false,\n value: true,\n },\n })\n }\n\n source[name] = wrapped\n\n return () => {\n if (source[name] === wrapped) {\n source[name] = original\n }\n }\n } catch {\n return () => {\n //\n }\n // This can throw when multiple instrumentation layers try to wrap the same global object,\n // such as XMLHttpRequest, and redefine the same non-configurable wrapper marker.\n }\n}\n","import { NetworkRecordOptions } from '../../../types'\n\nfunction hostnameFromURL(url: string | URL | RequestInfo): string | null {\n try {\n if (typeof url === 'string') {\n return new URL(url).hostname\n }\n if ('url' in url) {\n return new URL(url.url).hostname\n }\n return url.hostname\n } catch {\n return null\n }\n}\n\nexport function isHostOnDenyList(url: string | URL | Request, options: NetworkRecordOptions) {\n const hostname = hostnameFromURL(url)\n const defaultNotDenied = { hostname, isHostDenied: false }\n\n if (!options.payloadHostDenyList?.length || !hostname?.trim().length) {\n return defaultNotDenied\n }\n\n for (const deny of options.payloadHostDenyList) {\n if (hostname.endsWith(deny)) {\n return { hostname, isHostDenied: true }\n }\n }\n\n return defaultNotDenied\n}\n","/*\n * Constants\n */\n\n/* PROPERTY KEYS */\n\n// This key is deprecated, but we want to check for it to see whether aliasing is allowed.\nexport const PEOPLE_DISTINCT_ID_KEY = '$people_distinct_id'\nexport const DISTINCT_ID = 'distinct_id'\nexport const DEVICE_ID = '$device_id'\nexport const DEVICE_MODEL = '$device_model'\nexport const ALIAS_ID_KEY = '__alias'\nexport const CAMPAIGN_IDS_KEY = '__cmpns'\nexport const EVENT_TIMERS_KEY = '__timers'\nexport const AUTOCAPTURE_DISABLED_SERVER_SIDE = '$autocapture_disabled_server_side'\nexport const HEATMAPS_ENABLED_SERVER_SIDE = '$heatmaps_enabled_server_side'\nexport const EXCEPTION_CAPTURE_ENABLED_SERVER_SIDE = '$exception_capture_enabled_server_side'\nexport const ERROR_TRACKING_SUPPRESSION_RULES = '$error_tracking_suppression_rules'\nexport const ERROR_TRACKING_CAPTURE_EXTENSION_EXCEPTIONS = '$error_tracking_capture_extension_exceptions'\nexport const WEB_VITALS_ENABLED_SERVER_SIDE = '$web_vitals_enabled_server_side'\nexport const DEAD_CLICKS_ENABLED_SERVER_SIDE = '$dead_clicks_enabled_server_side'\nexport const PRODUCT_TOURS_ENABLED_SERVER_SIDE = '$product_tours_enabled_server_side'\nexport const WEB_VITALS_ALLOWED_METRICS = '$web_vitals_allowed_metrics'\nexport const SESSION_RECORDING_REMOTE_CONFIG = '$session_recording_remote_config'\n// @deprecated can be removed along with eager loaded replay\nexport const SESSION_RECORDING_ENABLED_SERVER_SIDE = '$session_recording_enabled_server_side'\n// @deprecated can be removed along with eager loaded replay\nexport const CONSOLE_LOG_RECORDING_ENABLED_SERVER_SIDE = '$console_log_recording_enabled_server_side'\n// @deprecated can be removed along with eager loaded replay\nexport const SESSION_RECORDING_NETWORK_PAYLOAD_CAPTURE = '$session_recording_network_payload_capture'\n// @deprecated can be removed along with eager loaded replay\nexport const SESSION_RECORDING_MASKING = '$session_recording_masking'\n// @deprecated can be removed along with eager loaded replay\nexport const SESSION_RECORDING_CANVAS_RECORDING = '$session_recording_canvas_recording'\n// @deprecated can be removed along with eager loaded replay\nexport const SESSION_RECORDING_SAMPLE_RATE = '$replay_sample_rate'\n// @deprecated can be removed along with eager loaded replay\nexport const SESSION_RECORDING_MINIMUM_DURATION = '$replay_minimum_duration'\n// @deprecated can be removed along with eager loaded replay\nexport const SESSION_RECORDING_SCRIPT_CONFIG = '$replay_script_config'\nexport const SESSION_RECORDING_OVERRIDE_SAMPLING = '$replay_override_sampling'\nexport const SESSION_RECORDING_OVERRIDE_LINKED_FLAG = '$replay_override_linked_flag'\nexport const SESSION_RECORDING_OVERRIDE_URL_TRIGGER = '$replay_override_url_trigger'\nexport const SESSION_RECORDING_OVERRIDE_EVENT_TRIGGER = '$replay_override_event_trigger'\nexport const SESSION_ID = '$sesid'\nexport const SESSION_RECORDING_IS_SAMPLED = '$session_is_sampled'\nexport const SESSION_RECORDING_PAST_MINIMUM_DURATION = '$session_past_minimum_duration'\nexport const SESSION_RECORDING_URL_TRIGGER_ACTIVATED_SESSION = '$session_recording_url_trigger_activated_session'\nexport const SESSION_RECORDING_EVENT_TRIGGER_ACTIVATED_SESSION = '$session_recording_event_trigger_activated_session'\n// V2 Trigger Groups: Per-group persistence key prefixes (suffix with group ID)\nexport const SESSION_RECORDING_TRIGGER_V2_GROUP_EVENT_PREFIX = '$posthog_sr_group_event_trigger_'\nexport const SESSION_RECORDING_TRIGGER_V2_GROUP_URL_PREFIX = '$posthog_sr_group_url_trigger_'\nexport const SESSION_RECORDING_TRIGGER_V2_GROUP_SAMPLING_PREFIX = '$posthog_sr_group_sampling_'\nexport const SESSION_RECORDING_FIRST_FULL_SNAPSHOT_TIMESTAMP = '$debug_first_full_snapshot_timestamp'\nexport const SESSION_RECORDING_FLUSHED_SIZE = '$sess_rec_flush_size'\nexport const ENABLED_FEATURE_FLAGS = '$enabled_feature_flags'\nexport const PERSISTENCE_ACTIVE_FEATURE_FLAGS = '$active_feature_flags'\nexport const PERSISTENCE_EARLY_ACCESS_FEATURES = '$early_access_features'\nexport const PERSISTENCE_FEATURE_FLAG_DETAILS = '$feature_flag_details'\nexport const PERSISTENCE_FEATURE_FLAG_PAYLOADS = '$feature_flag_payloads'\nexport const PERSISTENCE_FEATURE_FLAG_REQUEST_ID = '$feature_flag_request_id'\nexport const PERSISTENCE_OVERRIDE_FEATURE_FLAGS = '$override_feature_flags'\nexport const PERSISTENCE_OVERRIDE_FEATURE_FLAG_PAYLOADS = '$override_feature_flag_payloads'\nexport const STORED_PERSON_PROPERTIES_KEY = '$stored_person_properties'\nexport const STORED_GROUP_PROPERTIES_KEY = '$stored_group_properties'\nexport const SURVEYS = '$surveys'\nexport const SURVEYS_LOADED_AT = '$surveys_loaded_at'\nexport const SURVEYS_ACTIVATED = '$surveys_activated'\nexport const PRODUCT_TOURS = 'ph_product_tours'\nexport const PRODUCT_TOURS_ACTIVATED = '$product_tours_activated'\nexport const CONVERSATIONS = '$conversations'\nexport const CONVERSATIONS_LEGACY_WIDGET_SESSION_ID = '$conversations_widget_session_id'\nexport const CONVERSATIONS_LEGACY_TICKET_ID = '$conversations_ticket_id'\nexport const CONVERSATIONS_LEGACY_WIDGET_STATE = '$conversations_widget_state'\nexport const CONVERSATIONS_LEGACY_USER_TRAITS = '$conversations_user_traits'\nexport const FLAG_CALL_REPORTED = '$flag_call_reported'\nexport const FLAG_CALL_REPORTED_SESSION_ID = '$flag_call_reported_session_id'\nexport const PERSISTENCE_FEATURE_FLAG_ERRORS = '$feature_flag_errors'\nexport const PERSISTENCE_FEATURE_FLAG_EVALUATED_AT = '$feature_flag_evaluated_at'\nexport const USER_STATE = '$user_state'\nexport const CLIENT_SESSION_PROPS = '$client_session_props'\nexport const CAPTURE_RATE_LIMIT = '$capture_rate_limit'\n\n/** @deprecated Delete this when INITIAL_PERSON_INFO has been around for long enough to ignore backwards compat */\nexport const INITIAL_CAMPAIGN_PARAMS = '$initial_campaign_params'\n/** @deprecated Delete this when INITIAL_PERSON_INFO has been around for long enough to ignore backwards compat */\nexport const INITIAL_REFERRER_INFO = '$initial_referrer_info'\nexport const INITIAL_PERSON_INFO = '$initial_person_info'\nexport const ENABLE_PERSON_PROCESSING = '$epp'\nexport const TOOLBAR_ID = '__POSTHOG_TOOLBAR__'\nexport const TOOLBAR_CONTAINER_CLASS = 'toolbar-global-fade-container'\n\n/**\n * PREVIEW - MAY CHANGE WITHOUT WARNING - DO NOT USE IN PRODUCTION\n * Sentinel value for distinct id, device id, session id. Signals that the server should generate the value\n * */\nexport const COOKIELESS_SENTINEL_VALUE = '$posthog_cookieless'\nexport const COOKIELESS_MODE_FLAG_PROPERTY = '$cookieless_mode'\n\nexport const WEB_EXPERIMENTS = '$web_experiments'\n\nexport const SDK_DIST_CHANNEL = '$sdk_dist_channel'\nexport const SDK_DEBUG_EXTENSIONS_INIT_METHOD = '$sdk_debug_extensions_init_method'\nexport const SDK_DEBUG_EXTENSIONS_INIT_TIME_MS = '$sdk_debug_extensions_init_time_ms'\nexport const SDK_DEBUG_RECORDING_SCRIPT_NOT_LOADED = '$sdk_debug_recording_script_not_loaded'\nexport const SDK_DEBUG_REPLAY_EVENT_TRIGGER_STATUS = '$sdk_debug_replay_event_trigger_status'\nexport const SDK_DEBUG_REPLAY_LINKED_FLAG_TRIGGER_STATUS = '$sdk_debug_replay_linked_flag_trigger_status'\nexport const SDK_DEBUG_REPLAY_MATCHED_RECORDING_TRIGGER_GROUPS = '$sdk_debug_replay_matched_recording_trigger_groups'\nexport const SDK_DEBUG_REPLAY_REMOTE_TRIGGER_MATCHING_CONFIG = '$sdk_debug_replay_remote_trigger_matching_config'\nexport const SDK_DEBUG_REPLAY_TRIGGER_GROUPS_COUNT = '$sdk_debug_replay_trigger_groups_count'\nexport const SDK_DEBUG_REPLAY_URL_TRIGGER_STATUS = '$sdk_debug_replay_url_trigger_status'\nexport const SDK_DEBUG_REPLAY_RRWEB_ATTACHED = '$sdk_debug_rrweb_attached'\nexport const SDK_DEBUG_REPLAY_RRWEB_START_ATTEMPTED = '$sdk_debug_rrweb_start_attempted'\nexport const SESSION_RECORDING_START_REASON = '$session_recording_start_reason'\n\nexport const SURVEYS_REQUEST_TIMEOUT_MS = 10000\nexport const LOAD_EXT_NOT_FOUND = 'PostHog loadExternalDependency extension not found.'\n\n/* EVENT NAMES - interned to reduce bundle size */\n/* COOKIELESS MODE VALUES */\nexport const COOKIELESS_ON_REJECT = 'on_reject' as const\nexport const COOKIELESS_ALWAYS = 'always' as const\n\n/* USER STATE VALUES */\nexport const USER_STATE_ANONYMOUS = 'anonymous'\nexport const USER_STATE_IDENTIFIED = 'identified'\n\n/* PERSON PROFILE MODES */\nexport const PERSON_PROFILES_IDENTIFIED_ONLY = 'identified_only' as const\n\n/* DOM EVENT NAMES - interned to reduce bundle size */\nexport const DOM_EVENT_VISIBILITYCHANGE = 'visibilitychange'\nexport const DOM_EVENT_BEFOREUNLOAD = 'beforeunload'\n\nexport const EVENT_PAGEVIEW = '$pageview'\nexport const EVENT_PAGELEAVE = '$pageleave'\nexport const EVENT_IDENTIFY = '$identify'\nexport const EVENT_GROUPIDENTIFY = '$groupidentify'\n\n/* Z-INDEX HIERARCHY: tours > surveys > support */\nexport const Z_INDEX_TOURS = 2147483646\nexport const Z_INDEX_SURVEYS = 2147483645\nexport const Z_INDEX_CONVERSATIONS = 2147483644\n","import { TOOLBAR_CONTAINER_CLASS, TOOLBAR_ID } from '../constants'\n\n// Node.nodeType integer constants. We use the integers directly rather than\n// `Node.ELEMENT_NODE` etc. for browser portability (IE11) and to avoid a\n// runtime reference to the global `Node` in environments where it isn't defined.\nconst NODE_TYPE_ELEMENT = 1\nconst NODE_TYPE_TEXT = 3\nconst NODE_TYPE_DOCUMENT_FRAGMENT = 11\n\nexport function isElementInToolbar(el: EventTarget | null): boolean {\n if (el instanceof Element) {\n // closest isn't available in IE11, but we'll polyfill when bundling\n return el.id === TOOLBAR_ID || !!el.closest?.('.' + TOOLBAR_CONTAINER_CLASS)\n }\n return false\n}\n\n/*\n * Check whether an element has nodeType Node.ELEMENT_NODE\n * @param {Element} el - element to check\n * @returns {boolean} whether el is of the correct nodeType\n */\nexport function isElementNode(el: Node | Element | undefined | null): el is Element {\n return !!el && el.nodeType === NODE_TYPE_ELEMENT\n}\n\n/*\n * Check whether an element is of a given tag type.\n * Due to potential reference discrepancies (such as the webcomponents.js polyfill),\n * we want to match tagNames instead of specific references because something like\n * element === document.body won't always work because element might not be a native\n * element.\n * @param {Element} el - element to check\n * @param {string} tag - tag name (e.g., \"div\")\n * @returns {boolean} whether el is of the given tag type\n */\nexport function isTag(el: Element | undefined | null, tag: string): el is HTMLElement {\n return !!el && !!el.tagName && el.tagName.toLowerCase() === tag.toLowerCase()\n}\n\n/*\n * Check whether an element has nodeType Node.TEXT_NODE\n * @param {Element} el - element to check\n * @returns {boolean} whether el is of the correct nodeType\n */\nexport function isTextNode(el: Element | undefined | null): el is HTMLElement {\n return !!el && el.nodeType === NODE_TYPE_TEXT\n}\n\n/*\n * Check whether a node is a ShadowRoot — a DocumentFragment whose `host` is\n * a real Element. Plain DocumentFragments (e.g. <template> content) share\n * the same nodeType but have no `host`, so they are not ShadowRoots.\n * @param {Node|undefined|null} el - node to check\n * @returns {boolean} whether el is a ShadowRoot we can hop through to its host\n */\nexport function isShadowRoot(el: Node | ParentNode | undefined | null): el is ShadowRoot {\n return !!el && el.nodeType === NODE_TYPE_DOCUMENT_FRAGMENT && isElementNode((el as ShadowRoot).host)\n}\n","import { AutocaptureConfig, PostHogConfig, Properties } from './types'\nimport type { PostHog } from './posthog-core'\nimport { each, entries } from './utils'\n\nimport { isNullish, isString, isUndefined, isArray, isBoolean } from '@posthog/core'\nimport { logger } from './utils/logger'\nimport { window } from './utils/globals'\nimport { getTargetingUrl } from './utils/url-targeting-utils'\nimport { isElementNode, isShadowRoot, isTag, isTextNode } from './utils/element-utils'\nimport { includes, trim } from '@posthog/core'\n\nexport function splitClassString(s: string): string[] {\n return s ? trim(s).split(/\\s+/) : []\n}\n\nfunction checkForURLMatches(urlsList: (string | RegExp)[], instance?: PostHog): boolean {\n const url = getTargetingUrl(instance)\n return !!(url && urlsList && urlsList.some((regex) => url.match(regex)))\n}\n\n/*\n * Get the className of an element, accounting for edge cases where element.className is an object\n *\n * Because this is a string it can contain unexpected characters\n * So, this method safely splits the className and returns that array.\n */\nexport function getClassNames(el: Element): string[] {\n let className = ''\n switch (typeof el.className) {\n case 'string':\n className = el.className\n break\n // TODO: when is this ever used?\n case 'object': // handle cases where className might be SVGAnimatedString or some other type\n className =\n (el.className && 'baseVal' in el.className ? (el.className as any).baseVal : null) ||\n el.getAttribute('class') ||\n ''\n break\n default:\n className = ''\n }\n\n return splitClassString(className)\n}\n\nexport function makeSafeText(s: string | null | undefined): string | null {\n if (isNullish(s)) {\n return null\n }\n\n return (\n trim(s)\n // scrub potentially sensitive values\n .split(/(\\s+)/)\n .filter((s) => shouldCaptureValue(s))\n .join('')\n // normalize whitespace\n .replace(/[\\r\\n]/g, ' ')\n .replace(/[ ]+/g, ' ')\n // truncate\n .substring(0, 255)\n )\n}\n\n/*\n * Get the direct text content of an element, protecting against sensitive data collection.\n * Concats textContent of each of the element's text node children; this avoids potential\n * collection of sensitive data that could happen if we used element.textContent and the\n * element had sensitive child elements, since element.textContent includes child content.\n * Scrubs values that look like they could be sensitive (i.e. cc or ssn number).\n * @param {Element} el - element to get the text of\n * @returns {string} the element's direct text content\n */\nexport function getSafeText(el: Element): string {\n let elText = ''\n\n if (shouldCaptureElement(el) && !isSensitiveElement(el) && el.childNodes && el.childNodes.length) {\n each(el.childNodes, function (child) {\n if (isTextNode(child) && child.textContent) {\n elText += makeSafeText(child.textContent) ?? ''\n }\n })\n }\n\n return trim(elText)\n}\n\nexport function getEventTarget(e: Event): Element | null {\n // https://developer.mozilla.org/en-US/docs/Web/API/Event/target#Compatibility_notes\n if (isUndefined(e.target)) {\n return (e.srcElement as Element) || null\n } else {\n if ((e.target as HTMLElement)?.shadowRoot) {\n return (e.composedPath()[0] as Element) || null\n }\n return (e.target as Element) || null\n }\n}\n\nexport const autocaptureCompatibleElements = ['a', 'button', 'form', 'input', 'select', 'textarea', 'label']\n\n/*\n if there is no config, then all elements are allowed\n if there is a config, and there is an allow list, then only elements in the allow list are allowed\n assumes that some other code is checking this element's parents\n */\nfunction checkIfElementTreePassesElementAllowList(\n elements: Element[],\n autocaptureConfig: AutocaptureConfig | undefined\n): boolean {\n const allowlist = autocaptureConfig?.element_allowlist\n if (isUndefined(allowlist)) {\n // everything is allowed, when there is no allow list\n return true\n }\n\n // check each element in the tree\n // if any of the elements are in the allow list, then the tree is allowed\n for (const el of elements) {\n if (allowlist.some((elementType) => el.tagName.toLowerCase() === elementType)) {\n return true\n }\n }\n\n // otherwise there is an allow list and this element tree didn't match it\n return false\n}\n\nfunction elementMatchesCSSSelector(el: Element, selector: string): boolean {\n const matches =\n el.matches ||\n (el as any).matchesSelector ||\n (el as any).msMatchesSelector ||\n (el as any).mozMatchesSelector ||\n (el as any).webkitMatchesSelector ||\n (el as any).oMatchesSelector\n try {\n return matches ? matches.call(el, selector) : false\n } catch {\n return false\n }\n}\n\n/*\n if there is no selector list (i.e. it is undefined), then any elements matches\n if there is an empty list, then no elements match\n if there is a selector list, then check it against each element provided\n */\nfunction checkIfElementsMatchCSSSelector(elements: Element[], selectorList: string[] | undefined): boolean {\n if (isUndefined(selectorList)) {\n // everything is allowed, when there is no selector list\n return true\n }\n\n for (const el of elements) {\n if (selectorList.some((selector) => elementMatchesCSSSelector(el, selector))) {\n return true\n }\n }\n\n return false\n}\n\nexport function getParentElement(curEl: Element): Element | false {\n const parentNode = curEl.parentNode\n if (!parentNode || !isElementNode(parentNode)) return false\n return parentNode\n}\n\nconst DEFAULT_AUTOCAPTURE_IGNORE_LIST = ['.ph-no-autocapture', '[data-ph-no-autocapture]']\nconst DEFAULT_CONTENT_IGNORELIST = ['next', 'previous', 'prev', '>', '<']\n// +/- steppers are built to be clicked repeatedly; enabled from the 2026-05-30 config defaults\nexport const DEFAULT_CONTENT_IGNORELIST_WITH_STEPPERS = [...DEFAULT_CONTENT_IGNORELIST, '+', '-', '−', '–']\nconst MAX_CONTENT_IGNORELIST_ENTRIES = 10\n\ninterface ElementWithText {\n safeText: string\n ariaLabel: string\n}\n\n// symbol keywords (e.g. +, -, >) match exactly so we don't suppress \"sign-up\", \"5 > 3\", \"C++\", etc.\nconst matchesContentKeyword = (text: string, keyword: string): boolean =>\n /[a-z0-9]/i.test(keyword) ? text.includes(keyword) : text === keyword\n\nfunction shouldIgnoreByContent(\n contentIgnorelist: boolean | string[] | undefined,\n elementsWithText: ElementWithText[]\n): boolean {\n if (contentIgnorelist === false || isUndefined(contentIgnorelist)) {\n return false\n }\n\n let keywords: string[]\n if (contentIgnorelist === true) {\n keywords = DEFAULT_CONTENT_IGNORELIST\n } else if (isArray(contentIgnorelist)) {\n if (contentIgnorelist.length > MAX_CONTENT_IGNORELIST_ENTRIES) {\n logger.error(\n `[PostHog] content_ignorelist array cannot exceed ${MAX_CONTENT_IGNORELIST_ENTRIES} items. Use css_selector_ignorelist for more complex matching.`\n )\n return false\n }\n keywords = contentIgnorelist.map((k) => k.toLowerCase())\n } else {\n return false\n }\n\n return elementsWithText.some(({ safeText, ariaLabel }) => {\n return keywords.some(\n (keyword) => matchesContentKeyword(safeText, keyword) || matchesContentKeyword(ariaLabel, keyword)\n )\n })\n}\n\n// dead click capture does not run through autocapture's ph-no-capture check,\n// so we include it here so that ph-no-capture also suppresses dead click capture\nconst DEFAULT_DEAD_CLICK_IGNORE_LIST = ['.ph-no-deadclick', '.ph-no-capture']\nexport function shouldCaptureDeadClick(el: Element | null, _config: PostHogConfig['capture_dead_clicks']) {\n if (!window || cannotCheckForAutocapture(el)) {\n return false\n }\n\n const selectorIgnoreList = isBoolean(_config)\n ? DEFAULT_DEAD_CLICK_IGNORE_LIST\n : (_config?.css_selector_ignorelist ?? DEFAULT_DEAD_CLICK_IGNORE_LIST)\n\n const { targetElementList } = getElementAndParentsForElement(el, false)\n\n // we don't capture if we match the ignore list\n return !checkIfElementsMatchCSSSelector(targetElementList, selectorIgnoreList)\n}\n\n// autocapture check will already filter for ph-no-capture,\n// but we include it here to protect against future changes accidentally removing that check\nconst DEFAULT_RAGE_CLICK_IGNORE_LIST = ['.ph-no-rageclick', '.ph-no-capture']\n\nconst TEXT_SELECTION_INPUT_TYPES = ['', 'text', 'search', 'email', 'password', 'url', 'tel', 'number']\n\nfunction isContentEditableTarget(el: Element): boolean {\n if ((el as Partial<HTMLElement>).isContentEditable) {\n return true\n }\n const contentEditable = el.getAttribute?.('contenteditable')\n return contentEditable === 'true' || contentEditable === ''\n}\n\n// repeated fast clicks on a text-editing surface are double/triple-click text selection, not rage\nexport function isTextSelectionTarget(el: Element | null): boolean {\n if (!el || !isElementNode(el)) {\n return false\n }\n if (isTag(el, 'textarea')) {\n return true\n }\n if (isTag(el, 'input')) {\n return includes(TEXT_SELECTION_INPUT_TYPES, (el.getAttribute('type') || '').toLowerCase())\n }\n return isContentEditableTarget(el)\n}\n\nexport function shouldCaptureRageclick(el: Element | null, _config: PostHogConfig['rageclick']) {\n if (!window || cannotCheckForAutocapture(el)) {\n return false\n }\n\n let selectorIgnoreList: string[] | boolean\n let contentIgnorelist: boolean | string[] | undefined\n let ignoreTextSelection: boolean\n if (isBoolean(_config)) {\n selectorIgnoreList = _config ? DEFAULT_RAGE_CLICK_IGNORE_LIST : false\n // For backward compatibility, don't enable content or text-selection filtering for rageclick: true\n contentIgnorelist = undefined\n ignoreTextSelection = false\n } else {\n selectorIgnoreList = _config?.css_selector_ignorelist ?? DEFAULT_RAGE_CLICK_IGNORE_LIST\n contentIgnorelist = _config?.content_ignorelist\n ignoreTextSelection = _config?.ignore_text_selection ?? false\n }\n\n if (selectorIgnoreList === false) {\n return false\n }\n\n if (ignoreTextSelection && isTextSelectionTarget(el)) {\n return false\n }\n\n // Traverse DOM once and cache element data to avoid redundant calls to getSafeText\n const { targetElementList } = getElementAndParentsForElement(el, false)\n const elementsWithText: ElementWithText[] = targetElementList.map((element) => ({\n safeText: getSafeText(element).toLowerCase(),\n ariaLabel: element.getAttribute('aria-label')?.toLowerCase().trim() || '',\n }))\n\n if (shouldIgnoreByContent(contentIgnorelist, elementsWithText)) {\n return false\n }\n\n // we don't capture if we match the ignore list\n return !checkIfElementsMatchCSSSelector(targetElementList, selectorIgnoreList)\n}\n\nconst cannotCheckForAutocapture = (el: Element | null) => {\n return !el || isTag(el, 'html') || !isElementNode(el)\n}\n\nconst getElementAndParentsForElement = (el: Element, captureOnAnyElement: false | true | undefined) => {\n if (!window || cannotCheckForAutocapture(el)) {\n return { parentIsUsefulElement: false, targetElementList: [] }\n }\n\n let parentIsUsefulElement = false\n const targetElementList: Element[] = [el]\n let curEl: Element = el\n while (curEl.parentNode && !isTag(curEl, 'body')) {\n if (isShadowRoot(curEl.parentNode)) {\n targetElementList.push(curEl.parentNode.host)\n curEl = curEl.parentNode.host\n continue\n }\n const parentNode = getParentElement(curEl)\n if (!parentNode) break\n if (captureOnAnyElement || autocaptureCompatibleElements.indexOf(parentNode.tagName.toLowerCase()) > -1) {\n parentIsUsefulElement = true\n } else {\n const compStyles = window.getComputedStyle(parentNode)\n if (compStyles && compStyles.getPropertyValue('cursor') === 'pointer') {\n parentIsUsefulElement = true\n }\n }\n\n targetElementList.push(parentNode)\n curEl = parentNode\n }\n return { parentIsUsefulElement, targetElementList }\n}\n\n// dead-click skips a click only when the click target is — or is inside — an <a>.\n// Anchors navigate / download / open a new window via the browser, and we have no\n// observable signal for those actions (no DOM mutation, no scroll). For every other\n// element (button, input, select, textarea, label, custom JS-handled divs, etc.) we\n// rely on the existing mutation / scroll / selection / visibility observers — if the\n// app's JS handler ran, those catch the effect; if it didn't, dead-click correctly\n// surfaces the bug. A click on a broken <button> with no handler should still flag.\nexport function shouldSkipDeadClick(el: Element | null): boolean {\n if (!window || cannotCheckForAutocapture(el)) {\n return false\n }\n const { targetElementList } = getElementAndParentsForElement(el, false)\n return targetElementList.some((node) => isTag(node, 'a'))\n}\n\n/*\n * Check whether a DOM event should be \"captured\" or if it may contain sensitive data\n * using a variety of heuristics.\n * @param {Element} el - element to check\n * @param {Event} event - event to check\n * @param {Object} autocaptureConfig - autocapture config\n * @param {boolean} captureOnAnyElement - whether to capture on any element, clipboard autocapture doesn't restrict to \"clickable\" elements\n * @param {string[]} allowedEventTypes - event types to capture, normally just 'click', but some autocapture types react to different events, some elements have fixed events (e.g., form has \"submit\")\n * @returns {boolean} whether the event should be captured\n */\nexport function shouldCaptureDomEvent(\n el: Element,\n event: Event,\n autocaptureConfig: AutocaptureConfig | undefined = undefined,\n captureOnAnyElement?: boolean,\n allowedEventTypes?: string[],\n instance?: PostHog\n): boolean {\n if (!window || cannotCheckForAutocapture(el)) {\n return false\n }\n\n if (autocaptureConfig?.url_allowlist) {\n // if the current URL is not in the allow list, don't capture\n if (!checkForURLMatches(autocaptureConfig.url_allowlist, instance)) {\n return false\n }\n }\n\n if (autocaptureConfig?.url_ignorelist) {\n // if the current URL is in the ignore list, don't capture\n if (checkForURLMatches(autocaptureConfig.url_ignorelist, instance)) {\n return false\n }\n }\n\n if (autocaptureConfig?.dom_event_allowlist) {\n const allowlist = autocaptureConfig.dom_event_allowlist\n if (allowlist && !allowlist.some((eventType) => event.type === eventType)) {\n return false\n }\n }\n\n const { parentIsUsefulElement, targetElementList } = getElementAndParentsForElement(el, captureOnAnyElement)\n\n if (!checkIfElementTreePassesElementAllowList(targetElementList, autocaptureConfig)) {\n return false\n }\n\n if (!checkIfElementsMatchCSSSelector(targetElementList, autocaptureConfig?.css_selector_allowlist)) {\n return false\n }\n\n const selectorIgnoreList = autocaptureConfig?.css_selector_ignorelist ?? DEFAULT_AUTOCAPTURE_IGNORE_LIST\n if (checkIfElementsMatchCSSSelector(targetElementList, selectorIgnoreList)) {\n return false\n }\n\n const compStyles = window.getComputedStyle(el)\n if (compStyles && compStyles.getPropertyValue('cursor') === 'pointer' && event.type === 'click') {\n return true\n }\n\n const tag = el.tagName.toLowerCase()\n switch (tag) {\n case 'html':\n return false\n case 'form':\n return (allowedEventTypes || ['submit']).indexOf(event.type) >= 0\n case 'input':\n case 'select':\n case 'textarea':\n return (allowedEventTypes || ['change', 'click']).indexOf(event.type) >= 0\n default:\n if (parentIsUsefulElement) return (allowedEventTypes || ['click']).indexOf(event.type) >= 0\n return (\n (allowedEventTypes || ['click']).indexOf(event.type) >= 0 &&\n (autocaptureCompatibleElements.indexOf(tag) > -1 || el.getAttribute('contenteditable') === 'true')\n )\n }\n}\n\n/*\n * Check whether a DOM element should be \"captured\" or if it may contain sensitive data\n * using a variety of heuristics.\n * @param {Element} el - element to check\n * @returns {boolean} whether the element should be captured\n */\nexport function shouldCaptureElement(el: Element): boolean {\n for (let curEl = el; curEl.parentNode && !isTag(curEl, 'body'); curEl = curEl.parentNode as Element) {\n const classes = getClassNames(curEl)\n if (includes(classes, 'ph-sensitive') || includes(classes, 'ph-no-capture')) {\n return false\n }\n }\n\n if (includes(getClassNames(el), 'ph-include')) {\n return true\n }\n\n // don't include hidden or password fields\n const type = (el as HTMLInputElement).type || ''\n if (isString(type)) {\n // it's possible for el.type to be a DOM element if el is a form with a child input[name=\"type\"]\n switch (type.toLowerCase()) {\n case 'hidden':\n return false\n case 'password':\n return false\n }\n }\n\n // filter out data from fields that look like sensitive fields\n const name = (el as HTMLInputElement).name || el.id || ''\n // See https://github.com/posthog/posthog-js/issues/165\n // Under specific circumstances a bug caused .replace to be called on a DOM element\n // instead of a string, removing the element from the page. Ensure this issue is mitigated.\n if (isString(name)) {\n // it's possible for el.name or el.id to be a DOM element if el is a form with a child input[name=\"name\"]\n const sensitiveNameRegex =\n /^cc|cardnum|ccnum|creditcard|csc|cvc|cvv|exp|pass|pwd|routing|seccode|securitycode|securitynum|socialsec|socsec|ssn/i\n if (sensitiveNameRegex.test(name.replace(/[^a-zA-Z0-9]/g, ''))) {\n return false\n }\n }\n\n return true\n}\n\n/*\n * Check whether a DOM element is 'sensitive' and we should only capture limited data\n * @param {Element} el - element to check\n * @returns {boolean} whether the element should be captured\n */\nexport function isSensitiveElement(el: Element): boolean {\n // don't send data from inputs or similar elements since there will always be\n // a risk of clientside javascript placing sensitive data in attributes\n const allowedInputTypes = ['button', 'checkbox', 'submit', 'reset']\n if (\n (isTag(el, 'input') && !allowedInputTypes.includes((el as HTMLInputElement).type)) ||\n isTag(el, 'select') ||\n isTag(el, 'textarea') ||\n el.getAttribute('contenteditable') === 'true'\n ) {\n return true\n }\n return false\n}\n\n// Define the core pattern for matching credit card numbers\nconst coreCCPattern = `(4[0-9]{12}(?:[0-9]{3})?)|(5[1-5][0-9]{14})|(6(?:011|5[0-9]{2})[0-9]{12})|(3[47][0-9]{13})|(3(?:0[0-5]|[68][0-9])[0-9]{11})|((?:2131|1800|35[0-9]{3})[0-9]{11})`\n// Create the Anchored version of the regex by adding '^' at the start and '$' at the end\nconst anchoredCCRegex = new RegExp(`^(?:${coreCCPattern})$`)\n// The Unanchored version is essentially the core pattern, usable as is for partial matches\nconst unanchoredCCRegex = new RegExp(coreCCPattern)\n\n// Define the core pattern for matching SSNs with optional dashes\nconst coreSSNPattern = `\\\\d{3}-?\\\\d{2}-?\\\\d{4}`\n// Create the Anchored version of the regex by adding '^' at the start and '$' at the end\nconst anchoredSSNRegex = new RegExp(`^(${coreSSNPattern})$`)\n// The Unanchored version is essentially the core pattern itself, usable for partial matches\nconst unanchoredSSNRegex = new RegExp(`(${coreSSNPattern})`)\n\n/*\n * Check whether a string value should be \"captured\" or if it may contain sensitive data\n * using a variety of heuristics.\n * @param {string} value - string value to check\n * @param {boolean} anchorRegexes - whether to anchor the regexes to the start and end of the string\n * @returns {boolean} whether the element should be captured\n */\nexport function shouldCaptureValue(value: string, anchorRegexes = true): boolean {\n if (isNullish(value)) {\n return false\n }\n\n if (isString(value)) {\n value = trim(value)\n\n // check to see if input value looks like a credit card number\n // see: https://www.safaribooksonline.com/library/view/regular-expressions-cookbook/9781449327453/ch04s20.html\n const ccRegex = anchorRegexes ? anchoredCCRegex : unanchoredCCRegex\n if (ccRegex.test((value || '').replace(/[- ]/g, ''))) {\n return false\n }\n\n // check to see if input value looks like a social security number\n const ssnRegex = anchorRegexes ? anchoredSSNRegex : unanchoredSSNRegex\n if (ssnRegex.test(value)) {\n return false\n }\n }\n\n return true\n}\n\n/*\n * Check whether an attribute name is an Angular style attr (either _ngcontent or _nghost)\n * These update on each build and lead to noise in the element chain\n * More details on the attributes here: https://angular.io/guide/view-encapsulation\n * @param {string} attributeName - string value to check\n * @returns {boolean} whether the element is an angular tag\n */\nexport function isAngularStyleAttr(attributeName: string): boolean {\n if (isString(attributeName)) {\n return attributeName.substring(0, 10) === '_ngcontent' || attributeName.substring(0, 7) === '_nghost'\n }\n return false\n}\n\n/*\n * Iterate through children of a target element looking for span tags\n * and return the text content of the span tags, separated by spaces,\n * along with the direct text content of the target element\n * @param {Element} target - element to check\n * @returns {string} text content of the target element and its child span tags\n */\nexport function getDirectAndNestedSpanText(target: Element): string {\n let text = getSafeText(target)\n text = `${text} ${getNestedSpanText(target)}`.trim()\n return shouldCaptureValue(text) ? text : ''\n}\n\n/*\n * Iterate through children of a target element looking for span tags\n * and return the text content of the span tags, separated by spaces\n * @param {Element} target - element to check\n * @returns {string} text content of span tags\n */\nexport function getNestedSpanText(target: Element): string {\n let text = ''\n if (target && target.childNodes && target.childNodes.length) {\n each(target.childNodes, function (child) {\n if (child && child.tagName?.toLowerCase() === 'span') {\n try {\n const spanText = getSafeText(child)\n text = `${text} ${spanText}`.trim()\n\n if (child.childNodes && child.childNodes.length) {\n text = `${text} ${getNestedSpanText(child)}`.trim()\n }\n } catch (e) {\n logger.error('[AutoCapture]', e)\n }\n }\n })\n }\n return text\n}\n\n/*\nBack in the day storing events in Postgres we use Elements for autocapture events.\nNow we're using elements_chain. We used to do this parsing/processing during ingestion.\nThis code is just copied over from ingestion, but we should optimize it\nto create elements_chain string directly.\n*/\nexport function getElementsChainString(elements: Properties[]): string {\n return elementsToString(extractElements(elements))\n}\n\n// This interface is called 'Element' in plugin-scaffold https://github.com/PostHog/plugin-scaffold/blob/b07d3b879796ecc7e22deb71bf627694ba05386b/src/types.ts#L200\n// However 'Element' is a DOM Element when run in the browser, so we have to rename it\ninterface PHElement {\n text?: string\n tag_name?: string\n href?: string\n attr_id?: string\n attr_class?: string[]\n nth_child?: number\n nth_of_type?: number\n attributes?: Record<string, any>\n event_id?: number\n order?: number\n group_id?: number\n}\n\nfunction escapeQuotes(input: string): string {\n return input.replace(/\"|\\\\\"/g, '\\\\\"')\n}\n\nfunction elementsToString(elements: PHElement[]): string {\n const ret = elements.map((element) => {\n let el_string = ''\n if (element.tag_name) {\n el_string += element.tag_name\n }\n if (element.attr_class) {\n element.attr_class.sort()\n for (const single_class of element.attr_class) {\n el_string += `.${single_class.replace(/\"/g, '')}`\n }\n }\n const attributes: Record<string, any> = {\n ...(element.text ? { text: element.text } : {}),\n 'nth-child': element.nth_child ?? 0,\n 'nth-of-type': element.nth_of_type ?? 0,\n ...(element.href ? { href: element.href } : {}),\n ...(element.attr_id ? { attr_id: element.attr_id } : {}),\n ...element.attributes,\n }\n const sortedAttributes: Record<string, any> = {}\n entries(attributes)\n .sort(([a], [b]) => a.localeCompare(b))\n .forEach(\n ([key, value]) => (sortedAttributes[escapeQuotes(key.toString())] = escapeQuotes(value.toString()))\n )\n el_string += ':'\n el_string += entries(sortedAttributes)\n .map(([key, value]) => `${key}=\"${value}\"`)\n .join('')\n return el_string\n })\n return ret.join(';')\n}\n\nfunction extractElements(elements: Properties[]): PHElement[] {\n return elements.map((el) => {\n const response = {\n text: el['$el_text']?.slice(0, 400),\n tag_name: el['tag_name'],\n href: el['attr__href']?.slice(0, 2048),\n attr_class: extractAttrClass(el),\n attr_id: el['attr__id'],\n nth_child: el['nth_child'],\n nth_of_type: el['nth_of_type'],\n attributes: {} as { [id: string]: any },\n }\n\n entries(el)\n .filter(([key]) => key.indexOf('attr__') === 0)\n .forEach(([key, value]) => (response.attributes[key] = value))\n return response\n })\n}\n\nfunction extractAttrClass(el: Properties): PHElement['attr_class'] {\n const attr_class = el['attr__class']\n if (!attr_class) {\n return undefined\n } else if (isArray(attr_class)) {\n return attr_class\n } else {\n return splitClassString(attr_class)\n }\n}\n","import { CapturedNetworkRequest, NetworkRecordOptions, PostHogConfig } from '../../../types'\nimport { isFunction, isNullish, isString, isUndefined } from '@posthog/core'\nimport { convertToURL } from '../../../utils/request-utils'\nimport { logger } from '../../../utils/logger'\nimport { shouldCaptureValue } from '../../../autocapture-utils'\nimport { each } from '../../../utils'\n\nconst LOGGER_PREFIX = '[SessionRecording]'\n\nconst REDACTED = 'redacted'\n\n// the hard ceiling for a recorded request/response body — 1MB, even if a larger limit is configured\nexport const MAX_PAYLOAD_SIZE_BYTES = 1000000\n\n// the smallest of the 1MB ceiling or the configured limit if there is one\nexport function effectivePayloadLimitBytes(options: Pick<NetworkRecordOptions, 'payloadSizeLimitBytes'>): number {\n return Math.min(MAX_PAYLOAD_SIZE_BYTES, options.payloadSizeLimitBytes ?? MAX_PAYLOAD_SIZE_BYTES)\n}\n\nexport const defaultNetworkOptions: Required<NetworkRecordOptions> = {\n initiatorTypes: [\n 'audio',\n 'beacon',\n 'body',\n 'css',\n 'early-hint',\n 'embed',\n 'fetch',\n 'frame',\n 'iframe',\n 'icon',\n 'image',\n 'img',\n 'input',\n 'link',\n 'navigation',\n 'object',\n 'ping',\n 'script',\n 'track',\n 'video',\n 'xmlhttprequest',\n ],\n maskRequestFn: (data: CapturedNetworkRequest) => data,\n recordHeaders: false,\n recordBody: false,\n recordInitialRequests: false,\n recordPerformance: false,\n performanceEntryTypeToObserve: [\n // 'event', // This is too noisy as it covers all browser events\n 'first-input',\n // 'mark', // Mark is used too liberally. We would need to filter for specific marks\n // 'measure', // Measure is used too liberally. We would need to filter for specific measures\n 'navigation',\n 'paint',\n 'resource',\n ],\n payloadSizeLimitBytes: MAX_PAYLOAD_SIZE_BYTES,\n payloadHostDenyList: [\n '.lr-ingest.io',\n '.ingest.sentry.io',\n '.clarity.ms',\n // NB no leading dot here\n // GA4/gtag beacons go to *.google-analytics.com; with Google Signals on they also hit\n // analytics.google.com (region1.analytics.google.com/g/collect), so deny both\n 'google-analytics.com',\n 'analytics.google.com',\n // New Relic browser agent (bam + bam-cell)\n 'nr-data.net',\n // Datadog browser RUM intake\n 'datadoghq.com',\n 'datadoghq.eu',\n 'ddog-gov.com',\n // other third-party analytics / session-replay vendors whose telemetry has no replay value\n 'segment.io',\n 'rudderstack.com',\n 'amplitude.com',\n 'mixpanel.com',\n // Hotjar uses both .com and .io for data collection\n 'hotjar.com',\n 'hotjar.io',\n 'fullstory.com',\n ],\n streamNetworkBody: false,\n}\n\nconst HEADER_DENY_LIST = [\n 'authorization',\n 'x-forwarded-for',\n 'authorization',\n 'cookie',\n 'set-cookie',\n 'x-api-key',\n 'x-real-ip',\n 'remote-addr',\n 'forwarded',\n 'proxy-authorization',\n 'x-csrf-token',\n 'x-csrftoken',\n 'x-xsrf-token',\n]\n\nconst PAYLOAD_CONTENT_DENY_LIST = [\n 'password',\n 'secret',\n 'passwd',\n 'api_key',\n 'apikey',\n 'auth',\n 'credentials',\n 'mysql_pwd',\n 'privatekey',\n 'private_key',\n 'token',\n]\n\n// substrings that mark a header as credential-bearing - catches custom names\n// (e.g. x-gist-encoded-user-token) that aren't in the exact deny list above\nconst HEADER_DENY_SUBSTRINGS = [\n 'auth',\n 'token',\n 'secret',\n 'session',\n 'api-key',\n 'apikey',\n 'api_key',\n 'credential',\n 'password',\n 'passwd',\n 'cookie',\n 'csrf',\n 'xsrf',\n]\n\nconst isDeniedHeader = (header: string): boolean => {\n const lower = header.toLowerCase()\n return HEADER_DENY_LIST.includes(lower) || HEADER_DENY_SUBSTRINGS.some((s) => lower.includes(s))\n}\n\nconst redactDeniedHeaders = (headers: CapturedNetworkRequest['requestHeaders']): void => {\n if (!isNullish(headers)) {\n each(Object.keys(headers), (header) => {\n if (isDeniedHeader(header)) {\n headers[header] = REDACTED\n }\n })\n }\n}\n\n// we always remove headers on the deny list because we never want to capture this sensitive data.\n// applies to both request and response headers (e.g. set-cookie is a response header)\nconst removeAuthorizationHeader = (data: CapturedNetworkRequest): CapturedNetworkRequest => {\n redactDeniedHeaders(data.requestHeaders)\n redactDeniedHeaders(data.responseHeaders)\n return data\n}\n\nconst POSTHOG_PATHS_TO_IGNORE = ['/s/', '/e/', '/i/']\n// want to ignore posthog paths when capturing requests, or we can get trapped in a loop\n// because calls to PostHog would be reported using a call to PostHog which would be reported....\nconst ignorePostHogPaths = (\n data: CapturedNetworkRequest,\n apiHostConfig: PostHogConfig['api_host']\n): CapturedNetworkRequest | undefined => {\n const url = convertToURL(data.name)\n\n // we need to account for api host config as e.g. pathname could be /ingest/s/ and we want to ignore that\n let replaceValue = apiHostConfig.indexOf('http') === 0 ? convertToURL(apiHostConfig)?.pathname : apiHostConfig\n if (replaceValue === '/') {\n replaceValue = ''\n }\n const pathname = url?.pathname.replace(replaceValue || '', '')\n\n if (url && pathname && POSTHOG_PATHS_TO_IGNORE.some((path) => pathname.indexOf(path) === 0)) {\n return undefined\n }\n return data\n}\n\nfunction estimateBytes(payload: string): number {\n return new Blob([payload]).size\n}\n\nfunction enforcePayloadSizeLimit(\n payload: string | null | undefined,\n headers: Record<string, any> | undefined,\n limit: number,\n description: string\n): string | null | undefined {\n if (isNullish(payload)) {\n return payload\n }\n\n let requestContentLength: string | number = headers?.['content-length'] || estimateBytes(payload)\n if (isString(requestContentLength)) {\n requestContentLength = parseInt(requestContentLength)\n }\n\n if (requestContentLength > limit) {\n return LOGGER_PREFIX + ` ${description} body too large to record (${requestContentLength} bytes)`\n }\n\n return payload\n}\n\n// people can have arbitrarily large payloads on their site, but we don't want to ingest them\nconst limitPayloadSize = (\n options: NetworkRecordOptions\n): ((data: CapturedNetworkRequest | undefined) => CapturedNetworkRequest | undefined) => {\n const limit = effectivePayloadLimitBytes(options)\n\n return (data) => {\n if (data?.requestBody) {\n data.requestBody = enforcePayloadSizeLimit(data.requestBody, data.requestHeaders, limit, 'Request')\n }\n\n if (data?.responseBody) {\n data.responseBody = enforcePayloadSizeLimit(data.responseBody, data.responseHeaders, limit, 'Response')\n }\n\n return data\n }\n}\n\nfunction scrubPayload(payload: string | null | undefined, label: 'Request' | 'Response'): string | null | undefined {\n if (isNullish(payload)) {\n return payload\n }\n let scrubbed = payload\n\n if (!shouldCaptureValue(scrubbed, false)) {\n scrubbed = LOGGER_PREFIX + ' ' + label + ' body ' + REDACTED\n }\n each(PAYLOAD_CONTENT_DENY_LIST, (text) => {\n if (scrubbed?.length && scrubbed?.indexOf(text) !== -1) {\n scrubbed = LOGGER_PREFIX + ' ' + label + ' body ' + REDACTED + ' as might contain: ' + text\n }\n })\n\n return scrubbed\n}\n\nfunction scrubPayloads(capturedRequest: CapturedNetworkRequest | undefined): CapturedNetworkRequest | undefined {\n if (isUndefined(capturedRequest)) {\n return undefined\n }\n\n capturedRequest.requestBody = scrubPayload(capturedRequest.requestBody, 'Request')\n capturedRequest.responseBody = scrubPayload(capturedRequest.responseBody, 'Response')\n\n return capturedRequest\n}\n\n/**\n * whether a maskRequestFn is provided or not,\n * we ensure that we remove the denied header from requests\n * we _never_ want to record that header by accident\n * if someone complains then we'll add an opt-in to let them override it\n */\nexport const buildNetworkRequestOptions = (\n instanceConfig: PostHogConfig,\n remoteNetworkOptions: Pick<\n NetworkRecordOptions,\n 'recordHeaders' | 'recordBody' | 'recordPerformance' | 'payloadHostDenyList'\n >\n): NetworkRecordOptions => {\n const config: NetworkRecordOptions = {\n payloadSizeLimitBytes: defaultNetworkOptions.payloadSizeLimitBytes,\n performanceEntryTypeToObserve: [...defaultNetworkOptions.performanceEntryTypeToObserve],\n payloadHostDenyList: [\n ...(remoteNetworkOptions.payloadHostDenyList || []),\n ...defaultNetworkOptions.payloadHostDenyList,\n ],\n }\n // client can always disable despite remote options\n const canRecordHeaders =\n instanceConfig.session_recording.recordHeaders === false ? false : remoteNetworkOptions.recordHeaders\n const canRecordBody =\n instanceConfig.session_recording.recordBody === false ? false : remoteNetworkOptions.recordBody\n const canRecordPerformance =\n instanceConfig.capture_performance === false ? false : remoteNetworkOptions.recordPerformance\n\n const payloadLimiter = limitPayloadSize(config)\n\n const enforcedCleaningFn: NetworkRecordOptions['maskRequestFn'] = (d: CapturedNetworkRequest) =>\n payloadLimiter(ignorePostHogPaths(removeAuthorizationHeader(d), instanceConfig.api_host))\n\n const hasDeprecatedMaskFunction = isFunction(instanceConfig.session_recording.maskNetworkRequestFn)\n\n if (hasDeprecatedMaskFunction && isFunction(instanceConfig.session_recording.maskCapturedNetworkRequestFn)) {\n logger.warn(\n 'Both `maskNetworkRequestFn` and `maskCapturedNetworkRequestFn` are defined. `maskNetworkRequestFn` will be ignored.'\n )\n }\n\n if (hasDeprecatedMaskFunction) {\n instanceConfig.session_recording.maskCapturedNetworkRequestFn = (data: CapturedNetworkRequest) => {\n const cleanedURL = instanceConfig.session_recording.maskNetworkRequestFn!({ url: data.name })\n return {\n ...data,\n name: cleanedURL?.url,\n } as CapturedNetworkRequest\n }\n }\n\n config.maskRequestFn = isFunction(instanceConfig.session_recording.maskCapturedNetworkRequestFn)\n ? (data) => {\n const cleanedRequest = enforcedCleaningFn(data)\n return cleanedRequest\n ? (instanceConfig.session_recording.maskCapturedNetworkRequestFn?.(cleanedRequest) ?? undefined)\n : undefined\n }\n : (data) => scrubPayloads(enforcedCleaningFn(data))\n\n return {\n ...defaultNetworkOptions,\n ...config,\n recordHeaders: canRecordHeaders,\n recordBody: canRecordBody,\n recordPerformance: canRecordPerformance,\n recordInitialRequests: canRecordPerformance,\n streamNetworkBody: instanceConfig.session_recording.streamNetworkBody === true,\n }\n}\n","// Portions of this file are derived from getsentry/sentry-javascript\n// Copyright (c) 2012 Functional Software, Inc. dba Sentry\n// Licensed under the MIT License: https://github.com/getsentry/sentry-javascript/blob/develop/LICENSE\n\n/// <reference lib=\"dom\" />\n\n// rrweb/network@1 code starts\n// most of what is below here will be removed when rrweb release their code for this\n// see https://github.com/rrweb-io/rrweb/pull/1105\n\n// NB adopted from https://github.com/rrweb-io/rrweb/pull/1105 which looks like it will be accepted into rrweb\n// however, in the PR, it throws when the performance observer data is not available\n// and assumes it is running in a browser with the Request API (i.e. not IE11)\n// copying here so that we can use it before rrweb adopt it\n\nimport type { IWindow, listenerHandler, RecordPlugin } from '../types/rrweb-types'\nimport { CapturedNetworkRequest, Headers, InitiatorType, NetworkRecordOptions } from '../../../types'\nimport {\n isArray,\n isBoolean,\n isFormData,\n isFunction,\n isNull,\n isNullish,\n isString,\n isUndefined,\n isObject,\n} from '@posthog/core'\nimport { isDocument } from '../../../utils/type-utils'\nimport { createLogger } from '../../../utils/logger'\nimport { formDataToQuery } from '../../../utils/request-utils'\nimport { patch } from '../rrweb-plugins/patch'\nimport { isHostOnDenyList } from '../../../extensions/replay/external/denylist'\nimport { defaultNetworkOptions, effectivePayloadLimitBytes } from './config'\n\nconst logger = createLogger('[Recorder]')\n\nexport type NetworkData = {\n requests: CapturedNetworkRequest[]\n isInitial?: boolean\n}\n\ntype networkCallback = (data: NetworkData) => void\n\nconst isNavigationTiming = (entry: PerformanceEntry): entry is PerformanceNavigationTiming =>\n entry.entryType === 'navigation'\nconst isResourceTiming = (entry: PerformanceEntry): entry is PerformanceResourceTiming => entry.entryType === 'resource'\n\ntype ObservedPerformanceEntry = (PerformanceNavigationTiming | PerformanceResourceTiming) & {\n responseStatus?: number\n}\n\nexport function findLast<T>(array: Array<T>, predicate: (value: T) => boolean): T | undefined {\n const length = array.length\n for (let i = length - 1; i >= 0; i -= 1) {\n if (predicate(array[i])) {\n return array[i]\n }\n }\n return undefined\n}\n\nfunction initPerformanceObserver(cb: networkCallback, win: IWindow, options: Required<NetworkRecordOptions>) {\n // if we are only observing timings then we could have a single observer for all types, with buffer true,\n // but we are going to filter by initiatorType _if we are wrapping fetch and xhr as the wrapped functions\n // will deal with those.\n // so we have a block which captures requests from before fetch/xhr is wrapped\n // these are marked `isInitial` so playback can display them differently if needed\n // they will never have method/status/headers/body because they are pre-wrapping that provides that\n if (options.recordInitialRequests) {\n const initialPerformanceEntries = win.performance\n .getEntries()\n .filter(\n (entry): entry is ObservedPerformanceEntry =>\n isNavigationTiming(entry) ||\n (isResourceTiming(entry) && options.initiatorTypes.includes(entry.initiatorType as InitiatorType))\n )\n cb({\n requests: initialPerformanceEntries.flatMap((entry) =>\n prepareRequest({ entry, method: undefined, status: undefined, networkRequest: {}, isInitial: true })\n ),\n isInitial: true,\n })\n }\n const observer = new win.PerformanceObserver((entries) => {\n // if recordBody or recordHeaders is true then we don't want to record fetch or xhr here\n // as the wrapped functions will do that. Otherwise, this filter becomes a noop\n // because we do want to record them here\n const wrappedInitiatorFilter = (entry: ObservedPerformanceEntry) =>\n options.recordBody || options.recordHeaders\n ? entry.initiatorType !== 'xmlhttprequest' && entry.initiatorType !== 'fetch'\n : true\n\n const performanceEntries = entries.getEntries().filter(\n (entry): entry is ObservedPerformanceEntry =>\n isNavigationTiming(entry) ||\n (isResourceTiming(entry) &&\n options.initiatorTypes.includes(entry.initiatorType as InitiatorType) &&\n // TODO if we are _only_ capturing timing we don't want to filter initiator here\n wrappedInitiatorFilter(entry))\n )\n\n cb({\n requests: performanceEntries.flatMap((entry) =>\n prepareRequest({ entry, method: undefined, status: undefined, networkRequest: {} })\n ),\n })\n })\n // compat checked earlier\n // eslint-disable-next-line compat/compat\n const entryTypes = PerformanceObserver.supportedEntryTypes.filter((x) =>\n options.performanceEntryTypeToObserve.includes(x)\n )\n // initial records are gathered above, so we don't need to observe and buffer each type separately\n observer.observe({ entryTypes })\n return () => {\n observer.disconnect()\n }\n}\n\nfunction shouldRecordHeaders(type: 'request' | 'response', recordHeaders: NetworkRecordOptions['recordHeaders']) {\n return !!recordHeaders && (isBoolean(recordHeaders) || recordHeaders[type])\n}\n\nfunction isRequest(value: unknown): value is Request {\n if (typeof Request === 'undefined') {\n return false\n }\n if (value instanceof Request) {\n return true\n }\n try {\n return Object.prototype.toString.call(value) === '[object Request]'\n } catch {\n return false\n }\n}\n\n// binary/asset bodies are large and useless for replay debugging (and capturing an image body\n// duplicates what the recording already shows), so we never record them even when recordBody is on\nexport const NEVER_RECORD_BODY_CONTENT_TYPES = [\n 'image/',\n 'video/',\n 'audio/',\n 'font/',\n 'application/octet-stream',\n 'application/pdf',\n 'application/zip',\n 'application/wasm',\n]\n\nexport function shouldRecordBody({\n type,\n recordBody,\n headers,\n url,\n}: {\n type: 'request' | 'response'\n headers: Headers\n url: string | URL | RequestInfo\n recordBody: NetworkRecordOptions['recordBody']\n}) {\n function matchesContentType(contentTypes: string[]) {\n const contentTypeHeader = Object.keys(headers).find((key) => key.toLowerCase() === 'content-type')\n const contentType = contentTypeHeader && headers[contentTypeHeader]\n return contentTypes.some((ct) => contentType?.toLowerCase().includes(ct))\n }\n\n /**\n * particularly in canvas applications we see many requests to blob URLs\n * e.g. blob:https://video_url\n * these blob/object URLs are local to the browser, we can never capture that body\n * so we can just return false here\n */\n function isBlobURL(url: string | URL | RequestInfo) {\n try {\n if (typeof url === 'string') {\n return url.startsWith('blob:')\n }\n if (url instanceof URL) {\n return url.protocol === 'blob:'\n }\n if (isRequest(url)) {\n return isBlobURL(url.url)\n }\n return false\n } catch {\n return false\n }\n }\n if (!recordBody) return false\n if (isBlobURL(url)) return false\n // never record binary/asset bodies, regardless of the recordBody setting\n if (matchesContentType(NEVER_RECORD_BODY_CONTENT_TYPES)) return false\n if (isBoolean(recordBody)) return true\n if (isArray(recordBody)) return matchesContentType(recordBody)\n const recordBodyType = recordBody[type]\n if (isBoolean(recordBodyType)) return recordBodyType\n return matchesContentType(recordBodyType)\n}\n\nasync function getRequestPerformanceEntry(\n win: IWindow,\n initiatorType: string,\n url: string,\n start?: number,\n end?: number,\n attempt = 0\n): Promise<PerformanceResourceTiming | null> {\n if (attempt > 10) {\n logger.warn('Failed to get performance entry for request', { url, initiatorType })\n return null\n }\n const urlPerformanceEntries = win.performance.getEntriesByName(url) as PerformanceResourceTiming[]\n const performanceEntry = findLast(\n urlPerformanceEntries,\n (entry) =>\n isResourceTiming(entry) &&\n entry.initiatorType === initiatorType &&\n (isUndefined(start) || entry.startTime >= start) &&\n (isUndefined(end) || entry.startTime <= end)\n )\n if (!performanceEntry) {\n await new Promise((resolve) => setTimeout(resolve, 50 * attempt))\n return getRequestPerformanceEntry(win, initiatorType, url, start, end, attempt + 1)\n }\n return performanceEntry\n}\n\n/**\n * According to MDN https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/response\n * xhr response is typed as any but can be an ArrayBuffer, a Blob, a Document, a JavaScript object,\n * or a string, depending on the value of XMLHttpRequest.responseType, that contains the response entity body.\n *\n * XHR request body is Document | XMLHttpRequestBodyInit | null | undefined\n */\nfunction _tryReadXHRBody({\n body,\n options,\n url,\n}: {\n body: Document | XMLHttpRequestBodyInit | any | null | undefined\n options: NetworkRecordOptions\n url: string | URL | RequestInfo\n}): string | null {\n if (isNullish(body)) {\n return null\n }\n\n const { hostname, isHostDenied } = isHostOnDenyList(url, options)\n if (isHostDenied) {\n return hostname + ' is in deny list'\n }\n\n if (isString(body)) {\n return body\n }\n\n if (isDocument(body)) {\n return body.textContent\n }\n\n if (isFormData(body)) {\n return formDataToQuery(body)\n }\n\n if (isObject(body)) {\n try {\n return JSON.stringify(body)\n } catch {\n return '[SessionReplay] Failed to stringify response object'\n }\n }\n\n return '[SessionReplay] Cannot read body of type ' + toString.call(body)\n}\n\nfunction initXhrObserver(cb: networkCallback, win: IWindow, options: Required<NetworkRecordOptions>): listenerHandler {\n if (!options.initiatorTypes.includes('xmlhttprequest')) {\n return () => {\n //\n }\n }\n const recordRequestHeaders = shouldRecordHeaders('request', options.recordHeaders)\n const recordResponseHeaders = shouldRecordHeaders('response', options.recordHeaders)\n\n const restorePatch = patch(\n win.XMLHttpRequest.prototype,\n 'open',\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n (originalOpen: typeof XMLHttpRequest.prototype.open) => {\n return function (\n method: string,\n url: string | URL,\n async = true,\n username?: string | null,\n password?: string | null\n ) {\n // because this function is returned in its actual context `this` _is_ an XMLHttpRequest\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n const xhr = this as XMLHttpRequest\n\n // check IE earlier than this, we only initialize if Request is present\n // eslint-disable-next-line compat/compat\n const req = new Request(url)\n const networkRequest: Partial<CapturedNetworkRequest> = {}\n let start: number | undefined\n let end: number | undefined\n\n const requestHeaders: Headers = {}\n const originalSetRequestHeader = xhr.setRequestHeader.bind(xhr)\n xhr.setRequestHeader = (header: string, value: string) => {\n requestHeaders[header] = value\n return originalSetRequestHeader(header, value)\n }\n if (recordRequestHeaders) {\n networkRequest.requestHeaders = requestHeaders\n }\n\n const originalSend = xhr.send.bind(xhr)\n xhr.send = (body) => {\n if (\n shouldRecordBody({\n type: 'request',\n headers: requestHeaders,\n url,\n recordBody: options.recordBody,\n })\n ) {\n networkRequest.requestBody = _tryReadXHRBody({ body, options, url })\n }\n start = win.performance.now()\n return originalSend(body)\n }\n\n // Cleanup function to remove all event listeners and prevent memory leaks\n const cleanup = () => {\n xhr.removeEventListener('readystatechange', readyStateListener)\n xhr.removeEventListener('error', cleanup)\n xhr.removeEventListener('abort', cleanup)\n xhr.removeEventListener('timeout', cleanup)\n }\n\n const readyStateListener = () => {\n if (xhr.readyState !== xhr.DONE) {\n return\n }\n\n // Clean up all listeners immediately when done to prevent memory leaks\n cleanup()\n\n end = win.performance.now()\n const responseHeaders: Headers = {}\n const rawHeaders = xhr.getAllResponseHeaders()\n const headers = rawHeaders.trim().split(/[\\r\\n]+/)\n headers.forEach((line) => {\n const parts = line.split(': ')\n const header = parts.shift()\n const value = parts.join(': ')\n if (header) {\n responseHeaders[header] = value\n }\n })\n if (recordResponseHeaders) {\n networkRequest.responseHeaders = responseHeaders\n }\n if (\n shouldRecordBody({\n type: 'response',\n headers: responseHeaders,\n url,\n recordBody: options.recordBody,\n })\n ) {\n networkRequest.responseBody = _tryReadXHRBody({ body: xhr.response, options, url })\n }\n getRequestPerformanceEntry(win, 'xmlhttprequest', req.url, start, end)\n .then((entry) => {\n const requests = prepareRequest({\n entry,\n method: method,\n status: xhr?.status,\n networkRequest,\n start,\n end,\n url: url.toString(),\n initiatorType: 'xmlhttprequest',\n })\n cb({ requests })\n })\n .catch(() => {\n //\n })\n }\n\n // This is very tricky code, and making it passive won't bring many performance benefits,\n // so let's ignore the rule here.\n // eslint-disable-next-line posthog-js/no-add-event-listener\n xhr.addEventListener('readystatechange', readyStateListener)\n // Also clean up on error, abort, and timeout to prevent memory leaks\n // eslint-disable-next-line posthog-js/no-add-event-listener\n xhr.addEventListener('error', cleanup)\n // eslint-disable-next-line posthog-js/no-add-event-listener\n xhr.addEventListener('abort', cleanup)\n // eslint-disable-next-line posthog-js/no-add-event-listener\n xhr.addEventListener('timeout', cleanup)\n\n originalOpen.call(xhr, method, url.toString(), async, username, password)\n }\n }\n )\n return () => {\n restorePatch()\n }\n}\n\n/**\n * Check if this PerformanceEntry is either a PerformanceResourceTiming or a PerformanceNavigationTiming\n * NB PerformanceNavigationTiming extends PerformanceResourceTiming\n * Here we don't care which interface it implements as both expose `serverTimings`\n */\nconst exposesServerTiming = (event: PerformanceEntry | null): event is PerformanceResourceTiming =>\n !isNull(event) && (event.entryType === 'navigation' || event.entryType === 'resource')\n\nfunction prepareRequest({\n entry,\n method,\n status,\n networkRequest,\n isInitial,\n start,\n end,\n url,\n initiatorType,\n}: {\n entry: PerformanceResourceTiming | null\n method: string | undefined\n status: number | undefined\n networkRequest: Partial<CapturedNetworkRequest>\n isInitial?: boolean\n start?: number\n end?: number\n // if there is no performance observer entry, we still need to know the url\n url?: string\n // if there is no performance observer entry, we can provide the initiatorType\n initiatorType?: string\n}): CapturedNetworkRequest[] {\n start = entry ? entry.startTime : start\n end = entry ? entry.responseEnd : end\n\n // kudos to sentry javascript sdk for excellent background on why to use Date.now() here\n // https://github.com/getsentry/sentry-javascript/blob/e856e40b6e71a73252e788cd42b5260f81c9c88e/packages/utils/src/time.ts#L70\n // can't start observer if performance.now() is not available\n // eslint-disable-next-line compat/compat\n const timeOrigin = Math.floor(Date.now() - performance.now())\n // clickhouse can't ingest timestamps that are floats\n // (in this case representing fractions of a millisecond we don't care about anyway)\n // use timeOrigin if we really can't gather a start time\n const timestamp = Math.floor(timeOrigin + (start || 0))\n\n const entryJSON = entry ? entry.toJSON() : { name: url }\n\n const requests: CapturedNetworkRequest[] = [\n {\n ...entryJSON,\n startTime: isUndefined(start) ? undefined : Math.round(start),\n endTime: isUndefined(end) ? undefined : Math.round(end),\n timeOrigin,\n timestamp,\n method: method,\n initiatorType: initiatorType ? initiatorType : entry ? (entry.initiatorType as InitiatorType) : undefined,\n status,\n requestHeaders: networkRequest.requestHeaders,\n requestBody: networkRequest.requestBody,\n responseHeaders: networkRequest.responseHeaders,\n responseBody: networkRequest.responseBody,\n isInitial,\n },\n ]\n\n if (exposesServerTiming(entry)) {\n for (const timing of entry.serverTiming || []) {\n requests.push({\n timeOrigin,\n timestamp,\n startTime: Math.round(entry.startTime),\n name: timing.name,\n duration: timing.duration,\n // the spec has a closed list of possible types\n // https://developer.mozilla.org/en-US/docs/Web/API/PerformanceEntry/entryType\n // but, we need to know this was a server timing so that we know to\n // match it to the appropriate navigation or resource timing\n // that matching will have to be on timestamp and $current_url\n entryType: 'serverTiming',\n })\n }\n }\n\n return requests\n}\n\nconst contentTypePrefixDenyList = ['video/', 'audio/']\n\nfunction _checkForCannotReadResponseBody({\n r,\n options,\n url,\n}: {\n r: Response\n options: NetworkRecordOptions\n url: string | URL | RequestInfo\n}): string | null {\n if (r.headers.get('Transfer-Encoding') === 'chunked') {\n return 'Chunked Transfer-Encoding is not supported'\n }\n\n // `get` and `has` are case-insensitive\n // but return the header value with the casing that was supplied\n const contentType = r.headers.get('Content-Type')?.toLowerCase()\n const contentTypeIsDenied = contentTypePrefixDenyList.some((prefix) => contentType?.startsWith(prefix))\n if (contentType && contentTypeIsDenied) {\n return `Content-Type ${contentType} is not supported`\n }\n\n const { hostname, isHostDenied } = isHostOnDenyList(url, options)\n if (isHostDenied) {\n return hostname + ' is in deny list'\n }\n\n return null\n}\n\nfunction isReadableStreamBody(body: unknown): body is ReadableStream<Uint8Array> {\n return isObject(body) && isFunction(body.getReader) && isFunction(body.tee)\n}\n\n// reading a body must never hold up the page's request for long, so we cap every read attempt\nconst BODY_READ_TIMEOUT_MS = 500\nconst BODY_READ_TIMEOUT_MESSAGE = '[SessionReplay] Timeout while trying to read body'\nconst BODY_READ_FAILED_MESSAGE = '[SessionReplay] Failed to read body'\n\nfunction bodyReadFailedMessage(reason: unknown): string {\n return `${BODY_READ_FAILED_MESSAGE}: ${reason}`\n}\n\nfunction bodyTooLargeMessage(limitBytes: number): string {\n return `[SessionReplay] Body too large to record (> ${limitBytes} bytes)`\n}\n\n// when the body declares a content-length over the limit we can skip reading it entirely.\n// this trusts content-length the same way config.ts enforcePayloadSizeLimit does.\n// known accepted risk: for a compressed response content-length is the compressed size while the\n// streaming reader counts decoded bytes, so a body that is over the limit compressed but under it\n// decoded is dropped to the placeholder rather than recorded. it never breaks the page, so we accept it.\nexport function _contentLengthExceedsLimit(r: Request | Response, limitBytes: number): boolean {\n try {\n const headerValue = r.headers?.get?.('content-length')\n if (!headerValue) {\n return false\n }\n const contentLength = parseInt(headerValue, 10)\n return Number.isFinite(contentLength) && contentLength > limitBytes\n } catch {\n return false\n }\n}\n\nexport function _readBody(r: Request | Response, options: NetworkRecordOptions): Promise<string> {\n if (!options.streamNetworkBody) {\n return _tryReadBody(r)\n }\n const limitBytes = effectivePayloadLimitBytes(options)\n // skip the read for bodies the headers already tell us are over the limit\n if (_contentLengthExceedsLimit(r, limitBytes)) {\n return Promise.resolve(bodyTooLargeMessage(limitBytes))\n }\n return _tryReadBodyStreaming(r, limitBytes)\n}\n\nfunction _tryReadBody(r: Request | Response): Promise<string> {\n // there are now already multiple places where we're using Promise...\n // eslint-disable-next-line compat/compat\n return new Promise((resolve) => {\n const timeout = setTimeout(() => resolve(BODY_READ_TIMEOUT_MESSAGE), BODY_READ_TIMEOUT_MS)\n try {\n r.clone()\n .text()\n .then(\n (txt) => resolve(txt),\n (reason) => resolve(bodyReadFailedMessage(reason))\n )\n .finally(() => clearTimeout(timeout))\n } catch {\n clearTimeout(timeout)\n resolve(BODY_READ_FAILED_MESSAGE)\n }\n })\n}\n\nfunction concatChunks(chunks: Uint8Array[], totalBytes: number): Uint8Array {\n const merged = new Uint8Array(totalBytes)\n let offset = 0\n for (const chunk of chunks) {\n merged.set(chunk, offset)\n offset += chunk.byteLength\n }\n return merged\n}\n\n// Reads a clone of the body chunk by chunk, stopping as soon as the running total exceeds the\n// limit, so a very large body is never fully buffered. Like _tryReadBody it only ever reads a\n// clone (never the stream the page consumes) and is guaranteed to resolve, never reject.\nexport function _tryReadBodyStreaming(r: Request | Response, limitBytes: number): Promise<string> {\n // eslint-disable-next-line compat/compat\n return new Promise((resolve) => {\n let settled = false\n let reader: ReadableStreamDefaultReader<Uint8Array> | undefined\n\n function cancel(): void {\n try {\n void reader?.cancel()\n } catch {\n // the reader may already be released; nothing to clean up\n }\n }\n\n // resolving always releases the reader, so a slow/hung stream stops being pulled (and stops\n // buffering the clone) the moment we settle — whether via success, the cap, an error, or the timeout\n function done(value: string): void {\n if (settled) {\n return\n }\n settled = true\n clearTimeout(timeout)\n cancel()\n resolve(value)\n }\n\n const timeout = setTimeout(() => done(BODY_READ_TIMEOUT_MESSAGE), BODY_READ_TIMEOUT_MS)\n\n let clone: Request | Response\n try {\n clone = r.clone()\n } catch {\n done(BODY_READ_FAILED_MESSAGE)\n return\n }\n\n const body = clone.body\n // no readable stream (or no TextDecoder) available — fall back to the buffered read of the clone\n if (!isReadableStreamBody(body) || typeof TextDecoder === 'undefined') {\n try {\n clone.text().then(\n (txt) => done(txt),\n (reason) => done(bodyReadFailedMessage(reason))\n )\n } catch {\n done(BODY_READ_FAILED_MESSAGE)\n }\n return\n }\n\n try {\n reader = body.getReader()\n } catch {\n done(BODY_READ_FAILED_MESSAGE)\n return\n }\n\n const chunks: Uint8Array[] = []\n let received = 0\n\n function pump(): void {\n reader!.read().then(\n ({ done: streamDone, value }) => {\n // already resolved (e.g. the timeout fired) — stop reading and release the stream\n if (settled) {\n cancel()\n return\n }\n\n if (streamDone) {\n done(new TextDecoder().decode(concatChunks(chunks, received)))\n return\n }\n\n if (value) {\n if (received + value.byteLength > limitBytes) {\n done(bodyTooLargeMessage(limitBytes))\n return\n }\n received += value.byteLength\n chunks.push(value)\n }\n\n pump()\n },\n (reason) => done(bodyReadFailedMessage(reason))\n )\n }\n\n pump()\n })\n}\n\nasync function _tryReadRequestBody({\n r,\n options,\n url,\n}: {\n r: Request\n options: NetworkRecordOptions\n url: string | URL | RequestInfo\n}): Promise<string> {\n const { hostname, isHostDenied } = isHostOnDenyList(url, options)\n if (isHostDenied) {\n return Promise.resolve(hostname + ' is in deny list')\n }\n\n return _readBody(r, options)\n}\n\nasync function _tryReadResponseBody({\n r,\n options,\n url,\n}: {\n r: Response\n options: NetworkRecordOptions\n url: string | URL | RequestInfo\n}): Promise<string> {\n const cannotReadBodyReason: string | null = _checkForCannotReadResponseBody({ r, options, url })\n if (!isNull(cannotReadBodyReason)) {\n return Promise.resolve(cannotReadBodyReason)\n }\n\n return _readBody(r, options)\n}\n\nfunction initFetchObserver(\n cb: networkCallback,\n win: IWindow,\n options: Required<NetworkRecordOptions>\n): listenerHandler {\n if (!options.initiatorTypes.includes('fetch')) {\n return () => {\n //\n }\n }\n const recordRequestHeaders = shouldRecordHeaders('request', options.recordHeaders)\n const recordResponseHeaders = shouldRecordHeaders('response', options.recordHeaders)\n\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n const restorePatch = patch(win, 'fetch', (originalFetch: typeof fetch) => {\n return async function (url: URL | RequestInfo, init?: RequestInit | undefined) {\n // check IE earlier than this, we only initialize if Request is present\n // eslint-disable-next-line compat/compat\n const req = new Request(url, init)\n let res: Response | undefined\n const networkRequest: Partial<CapturedNetworkRequest> = {}\n let start: number | undefined\n let end: number | undefined\n\n try {\n const requestHeaders: Headers = {}\n req.headers.forEach((value: string, header: string | number) => {\n requestHeaders[header] = value\n })\n if (recordRequestHeaders) {\n networkRequest.requestHeaders = requestHeaders\n }\n // Check the caller-supplied body, not req.body: Request normalizes all non-null bodies\n // to a ReadableStream, but only an original ReadableStream would be locked by req.clone().text().\n const requestBodyIsReadableStream = isReadableStreamBody(init?.body)\n if (\n !requestBodyIsReadableStream &&\n shouldRecordBody({\n type: 'request',\n headers: requestHeaders,\n url,\n recordBody: options.recordBody,\n })\n ) {\n networkRequest.requestBody = await _tryReadRequestBody({ r: req, options, url })\n }\n\n start = win.performance.now()\n // Use `req` for recording metadata/body only. For fetch(url, init), do not pass this internally-created\n // Request downstream: it exposes request.body as a ReadableStream, and wrappers that forward that body\n // can trigger Safari's \"ReadableStream uploading is not supported\" error. For fetch(Request), we must\n // pass the cloned Request because constructing `req` may consume the original Request body.\n res = isRequest(url) ? await originalFetch(req) : await originalFetch(url, init)\n end = win.performance.now()\n\n const responseHeaders: Headers = {}\n res.headers.forEach((value: string, header: string | number) => {\n responseHeaders[header] = value\n })\n if (recordResponseHeaders) {\n networkRequest.responseHeaders = responseHeaders\n }\n if (\n shouldRecordBody({\n type: 'response',\n headers: responseHeaders,\n url,\n recordBody: options.recordBody,\n })\n ) {\n networkRequest.responseBody = await _tryReadResponseBody({ r: res, options, url })\n }\n\n return res\n } finally {\n getRequestPerformanceEntry(win, 'fetch', req.url, start, end)\n .then((entry) => {\n const requests = prepareRequest({\n entry,\n method: req.method,\n status: res?.status,\n networkRequest,\n start,\n end,\n url: req.url,\n initiatorType: 'fetch',\n })\n cb({ requests })\n })\n .catch(() => {\n //\n })\n }\n }\n })\n return () => {\n restorePatch()\n }\n}\n\nlet initialisedHandler: listenerHandler | null = null\n\nfunction initNetworkObserver(\n callback: networkCallback,\n win: IWindow, // top window or in an iframe\n options: NetworkRecordOptions\n): listenerHandler {\n if (!('performance' in win)) {\n return () => {\n //\n }\n }\n\n if (initialisedHandler) {\n logger.warn('Network observer already initialised, doing nothing')\n return () => {\n // the first caller should already have this handler and will be responsible for teardown\n }\n }\n\n const networkOptions = (\n options ? Object.assign({}, defaultNetworkOptions, options) : defaultNetworkOptions\n ) as Required<NetworkRecordOptions>\n\n const cb: networkCallback = (data) => {\n const requests: CapturedNetworkRequest[] = []\n data.requests.forEach((request) => {\n const maskedRequest = networkOptions.maskRequestFn(request)\n if (maskedRequest) {\n requests.push(maskedRequest)\n }\n })\n\n if (requests.length > 0) {\n callback({ ...data, requests })\n }\n }\n const performanceObserver = initPerformanceObserver(cb, win, networkOptions)\n\n // only wrap fetch and xhr if headers or body are being recorded\n let xhrObserver: listenerHandler = () => {}\n let fetchObserver: listenerHandler = () => {}\n if (networkOptions.recordHeaders || networkOptions.recordBody) {\n xhrObserver = initXhrObserver(cb, win, networkOptions)\n fetchObserver = initFetchObserver(cb, win, networkOptions)\n }\n\n initialisedHandler = () => {\n performanceObserver()\n xhrObserver()\n fetchObserver()\n initialisedHandler = null\n }\n return initialisedHandler\n}\n\n// use the plugin name so that when this functionality is adopted into rrweb\n// we can remove this plugin and use the core functionality with the same data\nexport const NETWORK_PLUGIN_NAME = 'rrweb/network@1'\n\n// TODO how should this be typed?\n// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-ignore\nexport const getRecordNetworkPlugin: (options?: NetworkRecordOptions) => RecordPlugin = (options) => {\n return {\n name: NETWORK_PLUGIN_NAME,\n observer: initNetworkObserver,\n options: options,\n }\n}\n\n// rrweb/networ@1 ends\n","// This file is kept only for backwards compatibility.\n// In almost every case, if you are manually importing a file you should use posthog-recorder instead.\n\nimport { record as rrwebRecord, wasMaxDepthReached, resetMaxDepthState } from '@posthog/rrweb-record'\nimport { getRecordConsolePlugin } from '@posthog/rrweb-plugin-console-record'\nimport { getRecordNetworkPlugin } from '../extensions/replay/external/network-plugin'\nimport { assignableWindow } from '../utils/globals'\n\nassignableWindow.__PosthogExtensions__ = assignableWindow.__PosthogExtensions__ || {}\nassignableWindow.__PosthogExtensions__.rrwebPlugins = { getRecordConsolePlugin, getRecordNetworkPlugin }\nassignableWindow.__PosthogExtensions__.rrweb = {\n record: rrwebRecord,\n version: 'v2',\n wasMaxDepthReached,\n resetMaxDepthState,\n}\n\n// we used to put all of these items directly on window, and now we put it on __PosthogExtensions__\n// but that means that old clients which lazily load this extension are looking in the wrong place\n// yuck,\n// so we also put them directly on the window\n// when 1.161.1 is the oldest version seen in production we can remove this\nassignableWindow.rrweb = { record: rrwebRecord, version: 'v2' }\nassignableWindow.rrwebConsoleRecord = { getRecordConsolePlugin }\nassignableWindow.getRecordNetworkPlugin = getRecordNetworkPlugin\n\nexport default rrwebRecord\n","var n,l,u,t,i,r,o,e,f,c,a,s,h,p,v,y,d={},w=[],_=/acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i,g=Array.isArray;function m(n,l){for(var u in l)n[u]=l[u];return n}function b(n){n&&n.parentNode&&n.parentNode.removeChild(n)}function k(l,u,t){var i,r,o,e={};for(o in u)\"key\"==o?i=u[o]:\"ref\"==o?r=u[o]:e[o]=u[o];if(arguments.length>2&&(e.children=arguments.length>3?n.call(arguments,2):t),\"function\"==typeof l&&null!=l.defaultProps)for(o in l.defaultProps)void 0===e[o]&&(e[o]=l.defaultProps[o]);return x(l,e,i,r,null)}function x(n,t,i,r,o){var e={type:n,props:t,key:i,ref:r,__k:null,__:null,__b:0,__e:null,__c:null,constructor:void 0,__v:null==o?++u:o,__i:-1,__u:0};return null==o&&null!=l.vnode&&l.vnode(e),e}function M(){return{current:null}}function S(n){return n.children}function C(n,l){this.props=n,this.context=l}function $(n,l){if(null==l)return n.__?$(n.__,n.__i+1):null;for(var u;l<n.__k.length;l++)if(null!=(u=n.__k[l])&&null!=u.__e)return u.__e;return\"function\"==typeof n.type?$(n):null}function I(n){if(n.__P&&n.__d){var u=n.__v,t=u.__e,i=[],r=[],o=m({},u);o.__v=u.__v+1,l.vnode&&l.vnode(o),q(n.__P,o,u,n.__n,n.__P.namespaceURI,32&u.__u?[t]:null,i,null==t?$(u):t,!!(32&u.__u),r),o.__v=u.__v,o.__.__k[o.__i]=o,D(i,o,r),u.__e=u.__=null,o.__e!=t&&P(o)}}function P(n){if(null!=(n=n.__)&&null!=n.__c)return n.__e=n.__c.base=null,n.__k.some(function(l){if(null!=l&&null!=l.__e)return n.__e=n.__c.base=l.__e}),P(n)}function A(n){(!n.__d&&(n.__d=!0)&&i.push(n)&&!H.__r++||r!=l.debounceRendering)&&((r=l.debounceRendering)||o)(H)}function H(){try{for(var n,l=1;i.length;)i.length>l&&i.sort(e),n=i.shift(),l=i.length,I(n)}finally{i.length=H.__r=0}}function L(n,l,u,t,i,r,o,e,f,c,a){var s,h,p,v,y,_,g,m=t&&t.__k||w,b=l.length;for(f=T(u,l,m,f,b),s=0;s<b;s++)null!=(p=u.__k[s])&&(h=-1!=p.__i&&m[p.__i]||d,p.__i=s,_=q(n,p,h,i,r,o,e,f,c,a),v=p.__e,p.ref&&h.ref!=p.ref&&(h.ref&&J(h.ref,null,p),a.push(p.ref,p.__c||v,p)),null==y&&null!=v&&(y=v),(g=!!(4&p.__u))||h.__k===p.__k?(f=j(p,f,n,g),g&&h.__e&&(h.__e=null)):\"function\"==typeof p.type&&void 0!==_?f=_:v&&(f=v.nextSibling),p.__u&=-7);return u.__e=y,f}function T(n,l,u,t,i){var r,o,e,f,c,a=u.length,s=a,h=0;for(n.__k=new Array(i),r=0;r<i;r++)null!=(o=l[r])&&\"boolean\"!=typeof o&&\"function\"!=typeof o?(\"string\"==typeof o||\"number\"==typeof o||\"bigint\"==typeof o||o.constructor==String?o=n.__k[r]=x(null,o,null,null,null):g(o)?o=n.__k[r]=x(S,{children:o},null,null,null):void 0===o.constructor&&o.__b>0?o=n.__k[r]=x(o.type,o.props,o.key,o.ref?o.ref:null,o.__v):n.__k[r]=o,f=r+h,o.__=n,o.__b=n.__b+1,e=null,-1!=(c=o.__i=O(o,u,f,s))&&(s--,(e=u[c])&&(e.__u|=2)),null==e||null==e.__v?(-1==c&&(i>a?h--:i<a&&h++),\"function\"!=typeof o.type&&(o.__u|=4)):c!=f&&(c==f-1?h--:c==f+1?h++:(c>f?h--:h++,o.__u|=4))):n.__k[r]=null;if(s)for(r=0;r<a;r++)null!=(e=u[r])&&0==(2&e.__u)&&(e.__e==t&&(t=$(e)),K(e,e));return t}function j(n,l,u,t){var i,r;if(\"function\"==typeof n.type){for(i=n.__k,r=0;i&&r<i.length;r++)i[r]&&(i[r].__=n,l=j(i[r],l,u,t));return l}n.__e!=l&&(t&&(l&&n.type&&!l.parentNode&&(l=$(n)),u.insertBefore(n.__e,l||null)),l=n.__e);do{l=l&&l.nextSibling}while(null!=l&&8==l.nodeType);return l}function F(n,l){return l=l||[],null==n||\"boolean\"==typeof n||(g(n)?n.some(function(n){F(n,l)}):l.push(n)),l}function O(n,l,u,t){var i,r,o,e=n.key,f=n.type,c=l[u],a=null!=c&&0==(2&c.__u);if(null===c&&null==e||a&&e==c.key&&f==c.type)return u;if(t>(a?1:0))for(i=u-1,r=u+1;i>=0||r<l.length;)if(null!=(c=l[o=i>=0?i--:r++])&&0==(2&c.__u)&&e==c.key&&f==c.type)return o;return-1}function z(n,l,u){\"-\"==l[0]?n.setProperty(l,null==u?\"\":u):n[l]=null==u?\"\":\"number\"!=typeof u||_.test(l)?u:u+\"px\"}function N(n,l,u,t,i){var r,o;n:if(\"style\"==l)if(\"string\"==typeof u)n.style.cssText=u;else{if(\"string\"==typeof t&&(n.style.cssText=t=\"\"),t)for(l in t)u&&l in u||z(n.style,l,\"\");if(u)for(l in u)t&&u[l]==t[l]||z(n.style,l,u[l])}else if(\"o\"==l[0]&&\"n\"==l[1])r=l!=(l=l.replace(s,\"$1\")),o=l.toLowerCase(),l=o in n||\"onFocusOut\"==l||\"onFocusIn\"==l?o.slice(2):l.slice(2),n.l||(n.l={}),n.l[l+r]=u,u?t?u[a]=t[a]:(u[a]=h,n.addEventListener(l,r?v:p,r)):n.removeEventListener(l,r?v:p,r);else{if(\"http://www.w3.org/2000/svg\"==i)l=l.replace(/xlink(H|:h)/,\"h\").replace(/sName$/,\"s\");else if(\"width\"!=l&&\"height\"!=l&&\"href\"!=l&&\"list\"!=l&&\"form\"!=l&&\"tabIndex\"!=l&&\"download\"!=l&&\"rowSpan\"!=l&&\"colSpan\"!=l&&\"role\"!=l&&\"popover\"!=l&&l in n)try{n[l]=null==u?\"\":u;break n}catch(n){}\"function\"==typeof u||(null==u||!1===u&&\"-\"!=l[4]?n.removeAttribute(l):n.setAttribute(l,\"popover\"==l&&1==u?\"\":u))}}function V(n){return function(u){if(this.l){var t=this.l[u.type+n];if(null==u[c])u[c]=h++;else if(u[c]<t[a])return;return t(l.event?l.event(u):u)}}}function q(n,u,t,i,r,o,e,f,c,a){var s,h,p,v,y,d,_,k,x,M,$,I,P,A,H,T=u.type;if(void 0!==u.constructor)return null;128&t.__u&&(c=!!(32&t.__u),o=[f=u.__e=t.__e]),(s=l.__b)&&s(u);n:if(\"function\"==typeof T)try{if(k=u.props,x=T.prototype&&T.prototype.render,M=(s=T.contextType)&&i[s.__c],$=s?M?M.props.value:s.__:i,t.__c?_=(h=u.__c=t.__c).__=h.__E:(x?u.__c=h=new T(k,$):(u.__c=h=new C(k,$),h.constructor=T,h.render=Q),M&&M.sub(h),h.state||(h.state={}),h.__n=i,p=h.__d=!0,h.__h=[],h._sb=[]),x&&null==h.__s&&(h.__s=h.state),x&&null!=T.getDerivedStateFromProps&&(h.__s==h.state&&(h.__s=m({},h.__s)),m(h.__s,T.getDerivedStateFromProps(k,h.__s))),v=h.props,y=h.state,h.__v=u,p)x&&null==T.getDerivedStateFromProps&&null!=h.componentWillMount&&h.componentWillMount(),x&&null!=h.componentDidMount&&h.__h.push(h.componentDidMount);else{if(x&&null==T.getDerivedStateFromProps&&k!==v&&null!=h.componentWillReceiveProps&&h.componentWillReceiveProps(k,$),u.__v==t.__v||!h.__e&&null!=h.shouldComponentUpdate&&!1===h.shouldComponentUpdate(k,h.__s,$)){u.__v!=t.__v&&(h.props=k,h.state=h.__s,h.__d=!1),u.__e=t.__e,u.__k=t.__k,u.__k.some(function(n){n&&(n.__=u)}),w.push.apply(h.__h,h._sb),h._sb=[],h.__h.length&&e.push(h);break n}null!=h.componentWillUpdate&&h.componentWillUpdate(k,h.__s,$),x&&null!=h.componentDidUpdate&&h.__h.push(function(){h.componentDidUpdate(v,y,d)})}if(h.context=$,h.props=k,h.__P=n,h.__e=!1,I=l.__r,P=0,x)h.state=h.__s,h.__d=!1,I&&I(u),s=h.render(h.props,h.state,h.context),w.push.apply(h.__h,h._sb),h._sb=[];else do{h.__d=!1,I&&I(u),s=h.render(h.props,h.state,h.context),h.state=h.__s}while(h.__d&&++P<25);h.state=h.__s,null!=h.getChildContext&&(i=m(m({},i),h.getChildContext())),x&&!p&&null!=h.getSnapshotBeforeUpdate&&(d=h.getSnapshotBeforeUpdate(v,y)),A=null!=s&&s.type===S&&null==s.key?E(s.props.children):s,f=L(n,g(A)?A:[A],u,t,i,r,o,e,f,c,a),h.base=u.__e,u.__u&=-161,h.__h.length&&e.push(h),_&&(h.__E=h.__=null)}catch(n){if(u.__v=null,c||null!=o)if(n.then){for(u.__u|=c?160:128;f&&8==f.nodeType&&f.nextSibling;)f=f.nextSibling;o[o.indexOf(f)]=null,u.__e=f}else{for(H=o.length;H--;)b(o[H]);B(u)}else u.__e=t.__e,u.__k=t.__k,n.then||B(u);l.__e(n,u,t)}else null==o&&u.__v==t.__v?(u.__k=t.__k,u.__e=t.__e):f=u.__e=G(t.__e,u,t,i,r,o,e,c,a);return(s=l.diffed)&&s(u),128&u.__u?void 0:f}function B(n){n&&(n.__c&&(n.__c.__e=!0),n.__k&&n.__k.some(B))}function D(n,u,t){for(var i=0;i<t.length;i++)J(t[i],t[++i],t[++i]);l.__c&&l.__c(u,n),n.some(function(u){try{n=u.__h,u.__h=[],n.some(function(n){n.call(u)})}catch(n){l.__e(n,u.__v)}})}function E(n){return\"object\"!=typeof n||null==n||n.__b>0?n:g(n)?n.map(E):void 0!==n.constructor?null:m({},n)}function G(u,t,i,r,o,e,f,c,a){var s,h,p,v,y,w,_,m=i.props||d,k=t.props,x=t.type;if(\"svg\"==x?o=\"http://www.w3.org/2000/svg\":\"math\"==x?o=\"http://www.w3.org/1998/Math/MathML\":o||(o=\"http://www.w3.org/1999/xhtml\"),null!=e)for(s=0;s<e.length;s++)if((y=e[s])&&\"setAttribute\"in y==!!x&&(x?y.localName==x:3==y.nodeType)){u=y,e[s]=null;break}if(null==u){if(null==x)return document.createTextNode(k);u=document.createElementNS(o,x,k.is&&k),c&&(l.__m&&l.__m(t,e),c=!1),e=null}if(null==x)m===k||c&&u.data==k||(u.data=k);else{if(e=\"textarea\"==x&&null!=k.defaultValue?null:e&&n.call(u.childNodes),!c&&null!=e)for(m={},s=0;s<u.attributes.length;s++)m[(y=u.attributes[s]).name]=y.value;for(s in m)y=m[s],\"dangerouslySetInnerHTML\"==s?p=y:\"children\"==s||s in k||\"value\"==s&&\"defaultValue\"in k||\"checked\"==s&&\"defaultChecked\"in k||N(u,s,null,y,o);for(s in k)y=k[s],\"children\"==s?v=y:\"dangerouslySetInnerHTML\"==s?h=y:\"value\"==s?w=y:\"checked\"==s?_=y:c&&\"function\"!=typeof y||m[s]===y||N(u,s,y,m[s],o);if(h)c||p&&(h.__html==p.__html||h.__html==u.innerHTML)||(u.innerHTML=h.__html),t.__k=[];else if(p&&(u.innerHTML=\"\"),L(\"template\"==t.type?u.content:u,g(v)?v:[v],t,i,r,\"foreignObject\"==x?\"http://www.w3.org/1999/xhtml\":o,e,f,e?e[0]:i.__k&&$(i,0),c,a),null!=e)for(s=e.length;s--;)b(e[s]);c&&\"textarea\"!=x||(s=\"value\",\"progress\"==x&&null==w?u.removeAttribute(\"value\"):null!=w&&(w!==u[s]||\"progress\"==x&&!w||\"option\"==x&&w!=m[s])&&N(u,s,w,m[s],o),s=\"checked\",null!=_&&_!=u[s]&&N(u,s,_,m[s],o))}return u}function J(n,u,t){try{if(\"function\"==typeof n){var i=\"function\"==typeof n.__u;i&&n.__u(),i&&null==u||(n.__u=n(u))}else n.current=u}catch(n){l.__e(n,t)}}function K(n,u,t){var i,r;if(l.unmount&&l.unmount(n),(i=n.ref)&&(i.current&&i.current!=n.__e||J(i,null,u)),null!=(i=n.__c)){if(i.componentWillUnmount)try{i.componentWillUnmount()}catch(n){l.__e(n,u)}i.base=i.__P=null}if(i=n.__k)for(r=0;r<i.length;r++)i[r]&&K(i[r],u,t||\"function\"!=typeof n.type);t||b(n.__e),n.__c=n.__=n.__e=void 0}function Q(n,l,u){return this.constructor(n,u)}function R(u,t,i){var r,o,e,f;t==document&&(t=document.documentElement),l.__&&l.__(u,t),o=(r=\"function\"==typeof i)?null:i&&i.__k||t.__k,e=[],f=[],q(t,u=(!r&&i||t).__k=k(S,null,[u]),o||d,d,t.namespaceURI,!r&&i?[i]:o?null:t.firstChild?n.call(t.childNodes):null,e,!r&&i?i:o?o.__e:t.firstChild,r,f),D(e,u,f)}function U(n,l){R(n,l,U)}function W(l,u,t){var i,r,o,e,f=m({},l.props);for(o in l.type&&l.type.defaultProps&&(e=l.type.defaultProps),u)\"key\"==o?i=u[o]:\"ref\"==o?r=u[o]:f[o]=void 0===u[o]&&null!=e?e[o]:u[o];return arguments.length>2&&(f.children=arguments.length>3?n.call(arguments,2):t),x(l.type,f,i||l.key,r||l.ref,null)}function X(n){function l(n){var u,t;return this.getChildContext||(u=new Set,(t={})[l.__c]=this,this.getChildContext=function(){return t},this.componentWillUnmount=function(){u=null},this.shouldComponentUpdate=function(n){this.props.value!=n.value&&u.forEach(function(n){n.__e=!0,A(n)})},this.sub=function(n){u.add(n);var l=n.componentWillUnmount;n.componentWillUnmount=function(){u&&u.delete(n),l&&l.call(n)}}),n.children}return l.__c=\"__cC\"+y++,l.__=n,l.Provider=l.__l=(l.Consumer=function(n,l){return n.children(l)}).contextType=l,l}n=w.slice,l={__e:function(n,l,u,t){for(var i,r,o;l=l.__;)if((i=l.__c)&&!i.__)try{if((r=i.constructor)&&null!=r.getDerivedStateFromError&&(i.setState(r.getDerivedStateFromError(n)),o=i.__d),null!=i.componentDidCatch&&(i.componentDidCatch(n,t||{}),o=i.__d),o)return i.__E=i}catch(l){n=l}throw n}},u=0,t=function(n){return null!=n&&void 0===n.constructor},C.prototype.setState=function(n,l){var u;u=null!=this.__s&&this.__s!=this.state?this.__s:this.__s=m({},this.state),\"function\"==typeof n&&(n=n(m({},u),this.props)),n&&m(u,n),null!=n&&this.__v&&(l&&this._sb.push(l),A(this))},C.prototype.forceUpdate=function(n){this.__v&&(this.__e=!0,n&&this.__h.push(n),A(this))},C.prototype.render=S,i=[],o=\"function\"==typeof Promise?Promise.prototype.then.bind(Promise.resolve()):setTimeout,e=function(n,l){return n.__v.__b-l.__v.__b},H.__r=0,f=Math.random().toString(8),c=\"__d\"+f,a=\"__a\"+f,s=/(PointerCapture)$|Capture$/i,h=0,p=V(!1),v=V(!0),y=0;export{C as Component,S as Fragment,W as cloneElement,X as createContext,k as createElement,M as createRef,k as h,U as hydrate,t as isValidElement,l as options,R as render,F as toChildArray};\n//# sourceMappingURL=preact.module.js.map\n","import{options as n}from\"preact\";var t,r,u,i,o=0,f=[],c=n,e=c.__b,a=c.__r,v=c.diffed,l=c.__c,m=c.unmount,s=c.__;function p(n,t){c.__h&&c.__h(r,n,o||t),o=0;var u=r.__H||(r.__H={__:[],__h:[]});return n>=u.__.length&&u.__.push({}),u.__[n]}function d(n){return o=1,h(D,n)}function h(n,u,i){var o=p(t++,2);if(o.t=n,!o.__c&&(o.__=[i?i(u):D(void 0,u),function(n){var t=o.__N?o.__N[0]:o.__[0],r=o.t(t,n);t!==r&&(o.__N=[r,o.__[1]],o.__c.setState({}))}],o.__c=r,!r.__f)){var f=function(n,t,r){if(!o.__c.__H)return!0;var u=o.__c.__H.__.filter(function(n){return n.__c});if(u.every(function(n){return!n.__N}))return!c||c.call(this,n,t,r);var i=o.__c.props!==n;return u.some(function(n){if(n.__N){var t=n.__[0];n.__=n.__N,n.__N=void 0,t!==n.__[0]&&(i=!0)}}),c&&c.call(this,n,t,r)||i};r.__f=!0;var c=r.shouldComponentUpdate,e=r.componentWillUpdate;r.componentWillUpdate=function(n,t,r){if(this.__e){var u=c;c=void 0,f(n,t,r),c=u}e&&e.call(this,n,t,r)},r.shouldComponentUpdate=f}return o.__N||o.__}function y(n,u){var i=p(t++,3);!c.__s&&C(i.__H,u)&&(i.__=n,i.u=u,r.__H.__h.push(i))}function _(n,u){var i=p(t++,4);!c.__s&&C(i.__H,u)&&(i.__=n,i.u=u,r.__h.push(i))}function A(n){return o=5,T(function(){return{current:n}},[])}function F(n,t,r){o=6,_(function(){if(\"function\"==typeof n){var r=n(t());return function(){n(null),r&&\"function\"==typeof r&&r()}}if(n)return n.current=t(),function(){return n.current=null}},null==r?r:r.concat(n))}function T(n,r){var u=p(t++,7);return C(u.__H,r)&&(u.__=n(),u.__H=r,u.__h=n),u.__}function q(n,t){return o=8,T(function(){return n},t)}function x(n){var u=r.context[n.__c],i=p(t++,9);return i.c=n,u?(null==i.__&&(i.__=!0,u.sub(r)),u.props.value):n.__}function P(n,t){c.useDebugValue&&c.useDebugValue(t?t(n):n)}function b(n){var u=p(t++,10),i=d();return u.__=n,r.componentDidCatch||(r.componentDidCatch=function(n,t){u.__&&u.__(n,t),i[1](n)}),[i[0],function(){i[1](void 0)}]}function g(){var n=p(t++,11);if(!n.__){for(var u=r.__v;null!==u&&!u.__m&&null!==u.__;)u=u.__;var i=u.__m||(u.__m=[0,0]);n.__=\"P\"+i[0]+\"-\"+i[1]++}return n.__}function j(){for(var n;n=f.shift();){var t=n.__H;if(n.__P&&t)try{t.__h.some(z),t.__h.some(B),t.__h=[]}catch(r){t.__h=[],c.__e(r,n.__v)}}}c.__b=function(n){r=null,e&&e(n)},c.__=function(n,t){n&&t.__k&&t.__k.__m&&(n.__m=t.__k.__m),s&&s(n,t)},c.__r=function(n){a&&a(n),t=0;var i=(r=n.__c).__H;i&&(u===r?(i.__h=[],r.__h=[],i.__.some(function(n){n.__N&&(n.__=n.__N),n.u=n.__N=void 0})):(i.__h.some(z),i.__h.some(B),i.__h=[],t=0)),u=r},c.diffed=function(n){v&&v(n);var t=n.__c;t&&t.__H&&(t.__H.__h.length&&(1!==f.push(t)&&i===c.requestAnimationFrame||((i=c.requestAnimationFrame)||w)(j)),t.__H.__.some(function(n){n.u&&(n.__H=n.u),n.u=void 0})),u=r=null},c.__c=function(n,t){t.some(function(n){try{n.__h.some(z),n.__h=n.__h.filter(function(n){return!n.__||B(n)})}catch(r){t.some(function(n){n.__h&&(n.__h=[])}),t=[],c.__e(r,n.__v)}}),l&&l(n,t)},c.unmount=function(n){m&&m(n);var t,r=n.__c;r&&r.__H&&(r.__H.__.some(function(n){try{z(n)}catch(n){t=n}}),r.__H=void 0,t&&c.__e(t,r.__v))};var k=\"function\"==typeof requestAnimationFrame;function w(n){var t,r=function(){clearTimeout(u),k&&cancelAnimationFrame(t),setTimeout(n)},u=setTimeout(r,35);k&&(t=requestAnimationFrame(r))}function z(n){var t=r,u=n.__c;\"function\"==typeof u&&(n.__c=void 0,u()),r=t}function B(n){var t=r;n.__c=n.__(),r=t}function C(n,t){return!n||n.length!==t.length||t.some(function(t,r){return t!==n[r]})}function D(n,t){return\"function\"==typeof t?t(n):t}export{q as useCallback,x as useContext,P as useDebugValue,y as useEffect,b as useErrorBoundary,g as useId,F as useImperativeHandle,_ as useLayoutEffect,T as useMemo,h as useReducer,A as useRef,d as useState};\n//# sourceMappingURL=hooks.module.js.map\n","/**\n * Having Survey types in types.ts was confusing tsc\n * and generating an invalid module.d.ts\n * See https://github.com/PostHog/posthog-js/issues/698\n */\n\nimport type { Properties, PropertyMatchType } from './types'\nimport type {\n SurveyAppearance as CoreSurveyAppearance,\n SurveyQuestionTranslation,\n SurveyResponseValue as CoreSurveyResponseValue,\n SurveyTranslation,\n SurveyValidationRule,\n} from '@posthog/core'\n\n// Extended operator type to include numeric operators not in PropertyMatchType\nexport type PropertyOperator = PropertyMatchType | 'gt' | 'lt'\n\nexport type PropertyFilters = {\n [propertyName: string]: {\n values: string[]\n operator: PropertyOperator\n }\n}\n\nexport interface SurveyEventWithFilters {\n name: string\n propertyFilters?: PropertyFilters\n}\n\n// Extends core SurveyAppearance with browser-specific fields\n// Omit 'position' from core because browser's SurveyPosition has additional values (e.g., NextToTrigger)\nexport interface SurveyAppearance extends Omit<CoreSurveyAppearance, 'position' | 'widgetType'> {\n // Browser-specific fields not in core\n /** @deprecated - not currently used */\n descriptionTextColor?: string\n ratingButtonHoverColor?: string\n whiteLabel?: boolean\n tabPosition?: SurveyTabPosition\n fontFamily?: string\n maxWidth?: string\n zIndex?: string\n disabledButtonOpacity?: string\n boxPadding?: string\n /** @deprecated Use inputBackground instead (inherited from core) */\n inputBackgroundColor?: string\n // Hide the X (cancel) button - defaults to false (show the button)\n hideCancelButton?: boolean\n // Browser's SurveyPosition has more options than core (e.g., NextToTrigger)\n position?: SurveyPosition\n widgetType?: SurveyWidgetType\n}\n\nexport type SurveyQuestion = BasicSurveyQuestion | LinkSurveyQuestion | RatingSurveyQuestion | MultipleSurveyQuestion\n\nexport type SurveyQuestionDescriptionContentType = 'html' | 'text'\n\ninterface SurveyQuestionBase {\n question: string\n id?: string\n description?: string | null\n descriptionContentType?: SurveyQuestionDescriptionContentType\n optional?: boolean\n buttonText?: string\n branching?: NextQuestionBranching | EndBranching | ResponseBasedBranching | SpecificQuestionBranching\n validation?: SurveyValidationRule[]\n translations?: Record<string, SurveyQuestionTranslation>\n}\n\nexport interface BasicSurveyQuestion extends SurveyQuestionBase {\n type: typeof SurveyQuestionType.Open\n}\n\nexport interface LinkSurveyQuestion extends SurveyQuestionBase {\n type: typeof SurveyQuestionType.Link\n link?: string | null\n}\n\nexport interface RatingSurveyQuestion extends SurveyQuestionBase {\n type: typeof SurveyQuestionType.Rating\n display: 'number' | 'emoji'\n scale: 2 | 3 | 5 | 7 | 10\n lowerBoundLabel: string\n upperBoundLabel: string\n skipSubmitButton?: boolean\n}\n\nexport interface MultipleSurveyQuestion extends SurveyQuestionBase {\n type: typeof SurveyQuestionType.SingleChoice | typeof SurveyQuestionType.MultipleChoice\n choices: string[]\n hasOpenChoice?: boolean\n shuffleOptions?: boolean\n skipSubmitButton?: boolean\n}\n\ninterface NextQuestionBranching {\n type: typeof SurveyQuestionBranchingType.NextQuestion\n}\n\ninterface EndBranching {\n type: typeof SurveyQuestionBranchingType.End\n}\n\ninterface ResponseBasedBranching {\n type: typeof SurveyQuestionBranchingType.ResponseBased\n responseValues: Record<string, any>\n}\n\ninterface SpecificQuestionBranching {\n type: typeof SurveyQuestionBranchingType.SpecificQuestion\n index: number\n}\n\nexport type SurveyCallback = (surveys: Survey[], context?: { isLoaded: boolean; error?: string }) => void\n\nexport interface SurveyElement {\n text?: string\n $el_text?: string\n tag_name?: string\n href?: string\n attr_id?: string\n attr_class?: string[]\n nth_child?: number\n nth_of_type?: number\n attributes?: Record<string, any>\n event_id?: number\n order?: number\n group_id?: number\n}\n\n// Re-export from @posthog/types to avoid duplication\nexport type { SurveyRenderReason } from '@posthog/types'\n\nexport interface Survey {\n // Sync this with the backend's SurveyAPISerializer!\n id: string\n name: string\n description?: string\n type: SurveyType\n translations?: Record<string, SurveyTranslation>\n feature_flag_keys:\n | {\n key: string\n value?: string\n }[]\n | null\n // the linked flag key is the flag key that is used to link the survey to a flag\n linked_flag_key: string | null\n targeting_flag_key: string | null\n // the internal targeting flag key is the flag key that is used to target users who have seen the survey\n // eg survey-targeting-<survey-id>\n internal_targeting_flag_key: string | null\n questions: SurveyQuestion[]\n appearance: SurveyAppearance | null\n conditions: {\n url?: string\n selector?: string\n seenSurveyWaitPeriodInDays?: number\n urlMatchType?: PropertyMatchType\n /** events that trigger surveys */\n events: {\n repeatedActivation?: boolean\n values: SurveyEventWithFilters[]\n } | null\n /** events that cancel \"pending\" (time-delayed) surveys */\n cancelEvents: {\n values: SurveyEventWithFilters[]\n } | null\n actions: {\n values: SurveyActionType[]\n } | null\n deviceTypes?: string[]\n deviceTypesMatchType?: PropertyMatchType\n linkedFlagVariant?: string\n } | null\n start_date: string | null\n end_date: string | null\n current_iteration: number | null\n current_iteration_start_date: string | null\n schedule?: SurveySchedule | null\n enable_partial_responses?: boolean | null\n}\n\nexport type SurveyWithTypeAndAppearance = Pick<Survey, 'id' | 'type' | 'appearance'>\n\nexport interface SurveyActionType {\n id: number\n name: string | null\n steps?: ActionStepType[]\n}\n\n/** Sync with plugin-server/src/types.ts */\nexport type ActionStepStringMatching = 'contains' | 'exact' | 'regex'\n\nexport interface ActionStepType {\n event?: string | null\n selector?: string | null\n /** pre-compiled regex pattern for matching selector against $elements_chain */\n selector_regex?: string | null\n /** @deprecated Only `selector` should be used now. */\n tag_name?: string\n text?: string | null\n /** @default StringMatching.Exact */\n text_matching?: ActionStepStringMatching | null\n href?: string | null\n /** @default ActionStepStringMatching.Exact */\n href_matching?: ActionStepStringMatching | null\n url?: string | null\n /** @default StringMatching.Contains */\n url_matching?: ActionStepStringMatching | null\n /** Property filters for action step matching */\n properties?: {\n key: string\n value?: string | number | boolean | (string | number | boolean)[] | null\n operator?: PropertyMatchType\n type?: string\n }[]\n}\n\ninterface DisplaySurveyOptionsBase {\n /**\n * Whether to bypass the survey's targeting and display conditions.\n * @default false\n */\n ignoreConditions: boolean\n\n /**\n * Whether to bypass the survey's configured popup delay.\n * @default false\n */\n ignoreDelay: boolean\n\n /**\n * How the survey should be displayed.\n * @default DisplaySurveyType.Popover\n */\n displayType: DisplaySurveyType\n\n /** Additional properties to include in all survey events (shown, sent, dismissed). */\n properties?: Properties\n\n /** Pre-filled responses by question index (0-based). Only supported for popover surveys. */\n initialResponses?: Record<number, SurveyResponseValue>\n}\n\n/** Options for displaying a survey as a popover. */\nexport interface DisplaySurveyPopoverOptions extends DisplaySurveyOptionsBase {\n displayType: typeof DisplaySurveyType.Popover\n /** Override the survey's configured position. */\n position?: SurveyPosition\n /** CSS selector for the element to position the survey next to (when position is NextToTrigger). */\n selector?: string\n /** When true, `survey shown` events will not be emitted automatically. */\n skipShownEvent?: boolean\n}\n\ninterface DisplaySurveyInlineOptions extends DisplaySurveyOptionsBase {\n displayType: typeof DisplaySurveyType.Inline\n /** CSS selector for the element where the inline survey should render. */\n selector: string\n}\n\n/** Options for `posthog.displaySurvey()`. */\nexport type DisplaySurveyOptions = DisplaySurveyPopoverOptions | DisplaySurveyInlineOptions\n\nexport interface SurveyConfig {\n /**\n * Prefill survey responses from matching URL parameters.\n *\n * @default undefined\n */\n prefillFromUrl?: boolean\n /**\n * @deprecated No longer used. Surveys will automatically advance past\n * prefilled questions with skipSubmitButton enabled. If partial response\n * collection is enabled, partial responses for pre-filled questions will\n * be submitted automatically on page load.\n */\n autoSubmitIfComplete?: boolean\n /**\n * @deprecated No longer used. Pre-filled responses are now sent\n * immediately when partial responses are enabled, or all required\n * questions have been pre-filled.\n */\n autoSubmitDelay?: number\n}\n\nexport type SurveyResponseValue = CoreSurveyResponseValue\n\n/**\n * Surveys related enums and constants.\n * We use const objects instead of TypeScript enums to allow for easier tree-shaking and to avoid issues with enum imports in JavaScript.\n */\n\nexport const SurveyEventType = {\n Activation: 'events',\n Cancellation: 'cancelEvents',\n} as const\nexport type SurveyEventType = (typeof SurveyEventType)[keyof typeof SurveyEventType]\n\nexport const SurveyWidgetType = {\n Button: 'button',\n Tab: 'tab',\n Selector: 'selector',\n} as const\nexport type SurveyWidgetType = (typeof SurveyWidgetType)[keyof typeof SurveyWidgetType]\n\nexport const SurveyPosition = {\n TopLeft: 'top_left',\n TopRight: 'top_right',\n TopCenter: 'top_center',\n MiddleLeft: 'middle_left',\n MiddleRight: 'middle_right',\n MiddleCenter: 'middle_center',\n Left: 'left',\n Center: 'center',\n Right: 'right',\n NextToTrigger: 'next_to_trigger',\n} as const\nexport type SurveyPosition = (typeof SurveyPosition)[keyof typeof SurveyPosition]\n\nexport const SurveyTabPosition = {\n Top: 'top',\n Left: 'left',\n Right: 'right',\n Bottom: 'bottom',\n} as const\nexport type SurveyTabPosition = (typeof SurveyTabPosition)[keyof typeof SurveyTabPosition]\n\nexport const SurveyType = {\n Popover: 'popover',\n API: 'api',\n Widget: 'widget',\n ExternalSurvey: 'external_survey',\n} as const\nexport type SurveyType = (typeof SurveyType)[keyof typeof SurveyType]\n\nexport const SurveyQuestionType = {\n Open: 'open',\n MultipleChoice: 'multiple_choice',\n SingleChoice: 'single_choice',\n Rating: 'rating',\n Link: 'link',\n} as const\nexport type SurveyQuestionType = (typeof SurveyQuestionType)[keyof typeof SurveyQuestionType]\n\nexport const SurveyQuestionBranchingType = {\n NextQuestion: 'next_question',\n End: 'end',\n ResponseBased: 'response_based',\n SpecificQuestion: 'specific_question',\n} as const\nexport type SurveyQuestionBranchingType = (typeof SurveyQuestionBranchingType)[keyof typeof SurveyQuestionBranchingType]\n\nexport const SurveySchedule = {\n Once: 'once',\n Recurring: 'recurring',\n Always: 'always',\n} as const\nexport type SurveySchedule = (typeof SurveySchedule)[keyof typeof SurveySchedule]\n\nexport const SurveyEventName = {\n SHOWN: 'survey shown',\n DISMISSED: 'survey dismissed',\n SENT: 'survey sent',\n ABANDONED: 'survey abandoned',\n} as const\nexport type SurveyEventName = (typeof SurveyEventName)[keyof typeof SurveyEventName]\n\nexport const SurveyEventProperties = {\n SURVEY_ID: '$survey_id',\n SURVEY_NAME: '$survey_name',\n SURVEY_RESPONSE: '$survey_response',\n SURVEY_ITERATION: '$survey_iteration',\n SURVEY_ITERATION_START_DATE: '$survey_iteration_start_date',\n SURVEY_PARTIALLY_COMPLETED: '$survey_partially_completed',\n SURVEY_SUBMISSION_ID: '$survey_submission_id',\n SURVEY_QUESTIONS: '$survey_questions',\n SURVEY_COMPLETED: '$survey_completed',\n PRODUCT_TOUR_ID: '$product_tour_id',\n SURVEY_LAST_SEEN_DATE: '$survey_last_seen_date',\n SURVEY_LANGUAGE: '$survey_language',\n} as const\nexport type SurveyEventProperties = (typeof SurveyEventProperties)[keyof typeof SurveyEventProperties]\n\nexport const DisplaySurveyType = {\n Popover: 'popover',\n Inline: 'inline',\n} as const\nexport type DisplaySurveyType = (typeof DisplaySurveyType)[keyof typeof DisplaySurveyType]\n","import { isArray, isNullish, isUndefined } from \"../utils/index.mjs\";\nconst SURVEY_LANGUAGE_PROPERTY = '$survey_language';\nfunction getSurveyResponseKey(questionId) {\n return `$survey_response_${questionId}`;\n}\nfunction getSurveyOldResponseKey(originalQuestionIndex) {\n return 0 === originalQuestionIndex ? '$survey_response' : `$survey_response_${originalQuestionIndex}`;\n}\nfunction getSurveyResponseValue(responses, questionId) {\n if (!questionId) return null;\n const response = responses[getSurveyResponseKey(questionId)];\n if (isArray(response)) return [\n ...response\n ];\n return response;\n}\nfunction buildSurveyResponseProperties(responses = {}, survey) {\n const oldFormatResponses = {};\n survey.questions.forEach((question)=>{\n if (isUndefined(question.originalQuestionIndex)) return;\n const oldResponseKey = getSurveyOldResponseKey(question.originalQuestionIndex);\n const response = getSurveyResponseValue(responses, question.id);\n if (!isUndefined(response)) oldFormatResponses[oldResponseKey] = response;\n });\n return {\n $survey_questions: survey.questions.map((question)=>({\n id: question.id,\n question: question.question,\n response: getSurveyResponseValue(responses, question.id)\n })),\n ...responses,\n ...oldFormatResponses\n };\n}\nfunction surveyHasResponses(responses = {}) {\n return Object.values(responses).some((response)=>!isNullish(response));\n}\nfunction getSurveyInteractionProperty(survey, action) {\n let surveyProperty = `$survey_${action}/${survey.id}`;\n if (survey.current_iteration && survey.current_iteration > 0) surveyProperty = `$survey_${action}/${survey.id}/${survey.current_iteration}`;\n return surveyProperty;\n}\nexport { SURVEY_LANGUAGE_PROPERTY, buildSurveyResponseProperties, getSurveyInteractionProperty, getSurveyOldResponseKey, getSurveyResponseKey, getSurveyResponseValue, surveyHasResponses };\n","import { isArray, isUndefined } from \"../utils/index.mjs\";\nfunction getTrimmedLanguage(value) {\n return 'string' == typeof value && value.trim() ? value.trim() : null;\n}\nfunction getLanguageFromStoredPersonProperties(storedPersonProperties) {\n if (!storedPersonProperties || 'object' != typeof storedPersonProperties || !('language' in storedPersonProperties)) return null;\n return getTrimmedLanguage(storedPersonProperties.language);\n}\nfunction detectSurveyLanguage({ overrideLanguage, storedPersonProperties, locale }, logger) {\n const explicitLanguage = getTrimmedLanguage(overrideLanguage);\n if (explicitLanguage) {\n logger?.info(`Using override display language: ${explicitLanguage}`);\n return explicitLanguage;\n }\n const personLanguage = getLanguageFromStoredPersonProperties(storedPersonProperties);\n if (personLanguage) {\n logger?.info(`Using person property language: ${personLanguage}`);\n return personLanguage;\n }\n const detectedLocale = getTrimmedLanguage(locale);\n if (detectedLocale) {\n logger?.info(`Using detected locale: ${detectedLocale}`);\n return detectedLocale;\n }\n logger?.info('No user language detected');\n return null;\n}\nfunction normalizeLanguageCode(languageCode) {\n return languageCode.toLowerCase();\n}\nfunction getBaseLanguage(languageCode) {\n return languageCode.split('-')[0];\n}\nfunction findBestTranslationMatch(translations, targetLanguage, logger) {\n if (!translations || !targetLanguage) return null;\n const normalizedTarget = normalizeLanguageCode(targetLanguage);\n const exactMatch = Object.keys(translations).find((key)=>normalizeLanguageCode(key) === normalizedTarget);\n if (exactMatch) {\n logger?.debug(`Found exact translation match: ${exactMatch}`);\n return exactMatch;\n }\n if (normalizedTarget.includes('-')) {\n const baseLanguage = getBaseLanguage(normalizedTarget);\n const baseMatch = Object.keys(translations).find((key)=>normalizeLanguageCode(key) === baseLanguage);\n if (baseMatch) {\n logger?.debug(`Found base language translation match: ${baseMatch} (from ${targetLanguage})`);\n return baseMatch;\n }\n }\n return null;\n}\nfunction isTranslatedChoices(questionTranslation) {\n return isArray(questionTranslation.choices);\n}\nfunction hasAppearanceTranslation(translation) {\n return !isUndefined(translation.thankYouMessageHeader) || !isUndefined(translation.thankYouMessageDescription) || !isUndefined(translation.thankYouMessageCloseButtonText) || !isUndefined(translation.submitButtonText) || !isUndefined(translation.backButtonText);\n}\nfunction mergeQuestionTranslation(question, targetLanguage, logger) {\n const translationKey = findBestTranslationMatch(question.translations, targetLanguage, logger);\n if (!translationKey) return {\n question,\n matchedKey: null,\n hasChanges: false\n };\n const questionTranslation = question.translations?.[translationKey];\n if (!questionTranslation) return {\n question,\n matchedKey: null,\n hasChanges: false\n };\n const translated = {\n ...question\n };\n let hasChanges = false;\n if (!isUndefined(questionTranslation.question)) {\n translated.question = questionTranslation.question;\n hasChanges = true;\n }\n if (!isUndefined(questionTranslation.description)) {\n translated.description = questionTranslation.description;\n hasChanges = true;\n }\n if (!isUndefined(questionTranslation.buttonText)) {\n translated.buttonText = questionTranslation.buttonText;\n hasChanges = true;\n }\n if ('link' in translated && !isUndefined(questionTranslation.link)) {\n translated.link = questionTranslation.link;\n hasChanges = true;\n }\n if ('lowerBoundLabel' in translated && !isUndefined(questionTranslation.lowerBoundLabel)) {\n translated.lowerBoundLabel = questionTranslation.lowerBoundLabel;\n hasChanges = true;\n }\n if ('upperBoundLabel' in translated && !isUndefined(questionTranslation.upperBoundLabel)) {\n translated.upperBoundLabel = questionTranslation.upperBoundLabel;\n hasChanges = true;\n }\n if ('choices' in translated && isTranslatedChoices(questionTranslation)) {\n translated.choices = questionTranslation.choices;\n hasChanges = true;\n }\n return {\n question: hasChanges ? translated : question,\n matchedKey: hasChanges ? translationKey : null,\n hasChanges\n };\n}\nfunction applySurveyTranslation(survey, targetLanguage, logger) {\n const translationKey = findBestTranslationMatch(survey.translations, targetLanguage, logger);\n const translated = {\n ...survey\n };\n let hasTranslation = false;\n if (translationKey) {\n const translation = survey.translations?.[translationKey];\n if (translation) {\n logger?.info(`Applying survey-level translation for language: ${translationKey}`);\n if (!isUndefined(translation.name)) {\n translated.name = translation.name;\n hasTranslation = true;\n }\n if (translated.appearance) {\n translated.appearance = {\n ...translated.appearance\n };\n if (!isUndefined(translation.thankYouMessageHeader)) {\n translated.appearance.thankYouMessageHeader = translation.thankYouMessageHeader;\n hasTranslation = true;\n }\n if (!isUndefined(translation.thankYouMessageDescription)) {\n translated.appearance.thankYouMessageDescription = translation.thankYouMessageDescription;\n hasTranslation = true;\n }\n if (!isUndefined(translation.thankYouMessageCloseButtonText)) {\n translated.appearance.thankYouMessageCloseButtonText = translation.thankYouMessageCloseButtonText;\n hasTranslation = true;\n }\n if (!isUndefined(translation.submitButtonText)) {\n translated.appearance.submitButtonText = translation.submitButtonText;\n hasTranslation = true;\n }\n if (!isUndefined(translation.backButtonText)) {\n translated.appearance.backButtonText = translation.backButtonText;\n hasTranslation = true;\n }\n } else if (hasAppearanceTranslation(translation)) hasTranslation = true;\n }\n }\n const translatedResults = survey.questions.map((question)=>mergeQuestionTranslation(question, targetLanguage, logger));\n const translatedQuestions = translatedResults.map((result)=>result.question);\n const anyQuestionTranslated = translatedResults.some((result)=>result.hasChanges);\n let questionMatchedKey = null;\n if (!translationKey) questionMatchedKey = translatedResults.find((result)=>result.matchedKey)?.matchedKey || null;\n if (anyQuestionTranslated) {\n translated.questions = translatedQuestions;\n hasTranslation = true;\n logger?.info(`Applied question-level translations for language: ${targetLanguage}`);\n }\n return {\n survey: translated,\n matchedKey: hasTranslation ? translationKey || questionMatchedKey : null\n };\n}\nexport { applySurveyTranslation, detectSurveyLanguage, findBestTranslationMatch, getBaseLanguage, getLanguageFromStoredPersonProperties, normalizeLanguageCode };\n","import { DisplaySurveyOptions, Survey, SurveyType, DisplaySurveyType } from '../posthog-surveys-types'\nimport { createLogger } from '../utils/logger'\n\nexport { getSurveyInteractionProperty } from '@posthog/core/surveys'\n\nexport const SURVEY_LOGGER = createLogger('[Surveys]')\n\nexport function isSurveyRunning(survey: Survey): boolean {\n return !!(survey.start_date && !survey.end_date)\n}\n\nexport function doesSurveyActivateByEvent(survey: Pick<Survey, 'conditions'>): boolean {\n return !!survey.conditions?.events?.values?.length\n}\n\nexport function doesSurveyActivateByAction(survey: Pick<Survey, 'conditions'>): boolean {\n return !!survey.conditions?.actions?.values?.length\n}\n\nexport const SURVEY_SEEN_PREFIX = 'seenSurvey_'\nexport const SURVEY_IN_PROGRESS_PREFIX = 'inProgressSurvey_'\nexport const SURVEY_ABANDONED_PREFIX = 'abandonedSurvey_'\n\nconst getSurveyStorageKey = (prefix: string, survey: Pick<Survey, 'id' | 'current_iteration'>): string => {\n let key = `${prefix}${survey.id}`\n if (survey.current_iteration && survey.current_iteration > 0) {\n key = `${prefix}${survey.id}_${survey.current_iteration}`\n }\n return key\n}\n\nexport const getSurveySeenKey = (survey: Pick<Survey, 'id' | 'current_iteration'>): string => {\n return getSurveyStorageKey(SURVEY_SEEN_PREFIX, survey)\n}\n\nexport const getSurveyAbandonedKey = (survey: Pick<Survey, 'id' | 'current_iteration'>): string => {\n return getSurveyStorageKey(SURVEY_ABANDONED_PREFIX, survey)\n}\n\nexport const setSurveySeenOnLocalStorage = (survey: Pick<Survey, 'id' | 'current_iteration'>) => {\n try {\n const surveySeenKey = getSurveySeenKey(survey)\n const isSurveySeen = localStorage.getItem(surveySeenKey)\n // if survey is already seen, no need to set it again\n if (isSurveySeen) {\n return\n }\n\n localStorage.setItem(surveySeenKey, 'true')\n } catch (error) {\n SURVEY_LOGGER.error('Failed to persist survey seen state', error)\n }\n}\n\n// These surveys are relevant for the getActiveMatchingSurveys method. They are used to\n// display surveys in our customer's application. Any new in-app survey type should be added here.\nexport const IN_APP_SURVEY_TYPES: SurveyType[] = [SurveyType.Popover, SurveyType.Widget, SurveyType.API]\n\nexport const DEFAULT_DISPLAY_SURVEY_OPTIONS: DisplaySurveyOptions = {\n ignoreConditions: false,\n ignoreDelay: false,\n displayType: DisplaySurveyType.Popover,\n}\n","/**\n * uuidv7: An experimental implementation of the proposed UUID Version 7\n *\n * @license Apache-2.0\n * @copyright 2021-2023 LiosK\n * @packageDocumentation\n *\n * from https://github.com/LiosK/uuidv7/blob/e501462ea3d23241de13192ceae726956f9b3b7d/src/index.ts\n */\n\n// polyfill for IE11\nimport { window } from './utils/globals'\n\nimport { isNumber, isUndefined } from '@posthog/core'\n\nif (!Math.trunc) {\n Math.trunc = function (v) {\n return v < 0 ? Math.ceil(v) : Math.floor(v)\n }\n}\n\n// polyfill for IE11\nif (!Number.isInteger) {\n Number.isInteger = function (value) {\n return isNumber(value) && isFinite(value) && Math.floor(value) === value\n }\n}\n\n/** Represents a UUID as a 16-byte byte array. */\nexport class UUID {\n /** @param bytes - The 16-byte byte array representation. */\n constructor(readonly bytes: Readonly<Uint8Array>) {\n if (bytes.length !== 16) {\n throw new TypeError('not 128-bit length')\n }\n }\n\n /**\n * Builds a byte array from UUIDv7 field values.\n *\n * @param unixTsMs - A 48-bit `unix_ts_ms` field value.\n * @param randA - A 12-bit `rand_a` field value.\n * @param randBHi - The higher 30 bits of 62-bit `rand_b` field value.\n * @param randBLo - The lower 32 bits of 62-bit `rand_b` field value.\n */\n static fromFieldsV7(unixTsMs: number, randA: number, randBHi: number, randBLo: number): UUID {\n if (\n !Number.isInteger(unixTsMs) ||\n !Number.isInteger(randA) ||\n !Number.isInteger(randBHi) ||\n !Number.isInteger(randBLo) ||\n unixTsMs < 0 ||\n randA < 0 ||\n randBHi < 0 ||\n randBLo < 0 ||\n unixTsMs > 0xffff_ffff_ffff ||\n randA > 0xfff ||\n randBHi > 0x3fff_ffff ||\n randBLo > 0xffff_ffff\n ) {\n throw new RangeError('invalid field value')\n }\n\n const bytes = new Uint8Array(16)\n bytes[0] = unixTsMs / 2 ** 40\n bytes[1] = unixTsMs / 2 ** 32\n bytes[2] = unixTsMs / 2 ** 24\n bytes[3] = unixTsMs / 2 ** 16\n bytes[4] = unixTsMs / 2 ** 8\n bytes[5] = unixTsMs\n bytes[6] = 0x70 | (randA >>> 8)\n bytes[7] = randA\n bytes[8] = 0x80 | (randBHi >>> 24)\n bytes[9] = randBHi >>> 16\n bytes[10] = randBHi >>> 8\n bytes[11] = randBHi\n bytes[12] = randBLo >>> 24\n bytes[13] = randBLo >>> 16\n bytes[14] = randBLo >>> 8\n bytes[15] = randBLo\n return new UUID(bytes)\n }\n\n /** @returns The 8-4-4-4-12 canonical hexadecimal string representation. */\n toString(): string {\n let text = ''\n for (let i = 0; i < this.bytes.length; i++) {\n text = text + (this.bytes[i] >>> 4).toString(16) + (this.bytes[i] & 0xf).toString(16)\n if (i === 3 || i === 5 || i === 7 || i === 9) {\n text += '-'\n }\n }\n\n if (text.length !== 36) {\n // We saw one customer whose bundling code was mangling the UUID generation\n // rather than accept a bad UUID, we throw an error here.\n throw new Error('Invalid UUIDv7 was generated')\n }\n return text\n }\n\n /** Creates an object from `this`. */\n clone(): UUID {\n return new UUID(this.bytes.slice(0))\n }\n\n /** Returns true if `this` is equivalent to `other`. */\n equals(other: UUID): boolean {\n return this.compareTo(other) === 0\n }\n\n /**\n * Returns a negative integer, zero, or positive integer if `this` is less\n * than, equal to, or greater than `other`, respectively.\n */\n compareTo(other: UUID): number {\n for (let i = 0; i < 16; i++) {\n const diff = this.bytes[i] - other.bytes[i]\n if (diff !== 0) {\n return Math.sign(diff)\n }\n }\n return 0\n }\n}\n\n/** Encapsulates the monotonic counter state. */\nclass V7Generator {\n private _timestamp = 0\n private _counter = 0\n private readonly _random = new DefaultRandom()\n\n /**\n * Generates a new UUIDv7 object from the current timestamp, or resets the\n * generator upon significant timestamp rollback.\n *\n * This method returns monotonically increasing UUIDs unless the up-to-date\n * timestamp is significantly (by ten seconds or more) smaller than the one\n * embedded in the immediately preceding UUID. If such a significant clock\n * rollback is detected, this method resets the generator and returns a new\n * UUID based on the current timestamp.\n */\n generate(): UUID {\n const value = this.generateOrAbort()\n if (!isUndefined(value)) {\n return value\n } else {\n // reset state and resume\n this._timestamp = 0\n const valueAfterReset = this.generateOrAbort()\n if (isUndefined(valueAfterReset)) {\n throw new Error('Could not generate UUID after timestamp reset')\n }\n return valueAfterReset\n }\n }\n\n /**\n * Generates a new UUIDv7 object from the current timestamp, or returns\n * `undefined` upon significant timestamp rollback.\n *\n * This method returns monotonically increasing UUIDs unless the up-to-date\n * timestamp is significantly (by ten seconds or more) smaller than the one\n * embedded in the immediately preceding UUID. If such a significant clock\n * rollback is detected, this method aborts and returns `undefined`.\n */\n generateOrAbort(): UUID | undefined {\n const MAX_COUNTER = 0x3ff_ffff_ffff\n const ROLLBACK_ALLOWANCE = 10_000 // 10 seconds\n\n const ts = Date.now()\n if (ts > this._timestamp) {\n this._timestamp = ts\n this._resetCounter()\n } else if (ts + ROLLBACK_ALLOWANCE > this._timestamp) {\n // go on with previous timestamp if new one is not much smaller\n this._counter++\n if (this._counter > MAX_COUNTER) {\n // increment timestamp at counter overflow\n this._timestamp++\n this._resetCounter()\n }\n } else {\n // abort if clock went backwards to unbearable extent\n return undefined\n }\n\n return UUID.fromFieldsV7(\n this._timestamp,\n Math.trunc(this._counter / 2 ** 30),\n this._counter & (2 ** 30 - 1),\n this._random.nextUint32()\n )\n }\n\n /** Initializes the counter at a 42-bit random integer. */\n private _resetCounter(): void {\n this._counter = this._random.nextUint32() * 0x400 + (this._random.nextUint32() & 0x3ff)\n }\n}\n\n/** A global flag to force use of cryptographically strong RNG. */\ndeclare const UUIDV7_DENY_WEAK_RNG: boolean\n\n/** Stores `crypto.getRandomValues()` available in the environment. */\nlet getRandomValues: <T extends Uint8Array | Uint32Array>(buffer: T) => T = (buffer) => {\n // fall back on Math.random() unless the flag is set to true\n // TRICKY: don't use the isUndefined method here as can't pass the reference\n if (typeof UUIDV7_DENY_WEAK_RNG !== 'undefined' && UUIDV7_DENY_WEAK_RNG) {\n throw new Error('no cryptographically strong RNG available')\n }\n\n for (let i = 0; i < buffer.length; i++) {\n buffer[i] = Math.trunc(Math.random() * 0x1_0000) * 0x1_0000 + Math.trunc(Math.random() * 0x1_0000)\n }\n return buffer\n}\n\n// detect Web Crypto API\nif (window && !isUndefined(window.crypto) && crypto.getRandomValues) {\n getRandomValues = (buffer) => crypto.getRandomValues(buffer)\n}\n\n/**\n * Wraps `crypto.getRandomValues()` and compatibles to enable buffering; this\n * uses a small buffer by default to avoid unbearable throughput decline in some\n * environments as well as the waste of time and space for unused values.\n */\nclass DefaultRandom {\n private readonly _buffer = new Uint32Array(8)\n private _cursor = Infinity\n nextUint32(): number {\n if (this._cursor >= this._buffer.length) {\n getRandomValues(this._buffer)\n this._cursor = 0\n }\n return this._buffer[this._cursor++]\n }\n}\n\nlet defaultGenerator: V7Generator | undefined\n\n/**\n * Generates a UUIDv7 string.\n *\n * @returns The 8-4-4-4-12 canonical hexadecimal string representation\n * (\"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\").\n */\nexport const uuidv7 = (): string => uuidv7obj().toString()\n\n/** Generates a UUIDv7 object. */\nconst uuidv7obj = (): UUID => (defaultGenerator || (defaultGenerator = new V7Generator())).generate()\n\nexport const uuid7ToTimestampMs = (uuid: string): number => {\n // remove hyphens\n const hex = uuid.replace(/-/g, '')\n // ensure that it's a version 7 UUID\n if (hex.length !== 32) {\n throw new Error('Not a valid UUID')\n }\n if (hex[12] !== '7') {\n throw new Error('Not a UUIDv7')\n }\n // the first 6 bytes are the timestamp, which means that we can read only the first 12 hex characters\n return parseInt(hex.substring(0, 12), 16)\n}\n","export const isValidRegex = function (str: string): boolean {\n try {\n new RegExp(str)\n } catch {\n return false\n }\n return true\n}\n\nexport const isMatchingRegex = function (value: string, pattern: string): boolean {\n if (!isValidRegex(pattern)) return false\n\n try {\n return new RegExp(pattern).test(value)\n } catch {\n return false\n }\n}\n","import { isArray, isNull, isUndefined } from '@posthog/core'\nimport { jsonStringify } from '../request'\nimport { PropertyFilters, PropertyOperator } from '../posthog-surveys-types'\nimport type { Properties, SessionRecordingTriggerPropertyFilter } from '../types'\nimport { isMatchingRegex } from './regex-utils'\n\nexport function getPersonPropertiesHash(\n distinct_id: string,\n userPropertiesToSet?: Properties,\n userPropertiesToSetOnce?: Properties\n): string {\n return jsonStringify({ distinct_id, userPropertiesToSet, userPropertiesToSetOnce })\n}\n\nexport const propertyComparisons: Record<PropertyOperator, (targets: string[], values: string[]) => boolean> = {\n exact: (targets, values) => values.some((value) => targets.some((target) => value === target)),\n is_not: (targets, values) => values.every((value) => targets.every((target) => value !== target)),\n regex: (targets, values) => values.some((value) => targets.some((target) => isMatchingRegex(value, target))),\n not_regex: (targets, values) => values.every((value) => targets.every((target) => !isMatchingRegex(value, target))),\n icontains: (targets, values) =>\n values.map(toLowerCase).some((value) => targets.map(toLowerCase).some((target) => value.includes(target))),\n not_icontains: (targets, values) =>\n values.map(toLowerCase).every((value) => targets.map(toLowerCase).every((target) => !value.includes(target))),\n gt: (targets, values) =>\n values.some((value) => {\n const numValue = parseFloat(value)\n return !isNaN(numValue) && targets.some((t) => numValue > parseFloat(t))\n }),\n lt: (targets, values) =>\n values.some((value) => {\n const numValue = parseFloat(value)\n return !isNaN(numValue) && targets.some((t) => numValue < parseFloat(t))\n }),\n}\n\nconst toLowerCase = (v: string): string => v.toLowerCase()\n\n// Operators whose semantics mean \"property is not X\". When the property being\n// filtered on is missing or null, these match — absence of the property\n// satisfies a \"not equal to X\" check. This aligns with how PostHog's feature\n// flag matchers (posthog/queries/base.py, rust/feature-flags) treat missing\n// properties for negative operators.\nconst NEGATIVE_OPERATORS: ReadonlySet<string> = new Set(['is_not', 'not_icontains', 'not_regex'])\n\n/**\n * Evaluate trigger property filters (WHERE clauses) against event and person properties.\n * All filters must match (implicit AND). Returns true if no filters are present.\n */\nexport function matchTriggerPropertyFilters(\n filters: SessionRecordingTriggerPropertyFilter[] | undefined,\n eventProperties: Properties | undefined,\n personProperties: Properties | undefined\n): boolean {\n if (!filters || filters.length === 0) {\n return true\n }\n\n return filters.every((filter) => {\n const source = filter.type === 'person' ? personProperties : eventProperties\n const propertyValue = source?.[filter.key]\n const operator = filter.operator || 'exact'\n\n // Missing or null property: for negative operators, absence counts as a\n // match (nothing can't equal EU, so \"is_not EU\" is satisfied). For\n // positive operators, we can't confirm a match without a value.\n if (isUndefined(propertyValue) || isNull(propertyValue)) {\n return NEGATIVE_OPERATORS.has(operator)\n }\n\n const comparisonFunction = propertyComparisons[operator as PropertyOperator]\n if (!comparisonFunction) {\n return false\n }\n\n if (isUndefined(filter.value) || isNull(filter.value)) {\n return false\n }\n\n // Normalize filter value and property value to string arrays for comparison\n const targetValues = isArray(filter.value) ? filter.value.map(String) : [String(filter.value)]\n const actualValues = isArray(propertyValue) ? propertyValue.map(String) : [String(propertyValue)]\n\n return comparisonFunction(targetValues, actualValues)\n })\n}\n\nexport function matchPropertyFilters(\n propertyFilters: PropertyFilters | undefined,\n eventProperties: Properties | undefined\n): boolean {\n // if there are no property filters, it means we're only matching on event name\n if (!propertyFilters) {\n return true\n }\n\n return Object.entries(propertyFilters).every(([propertyName, filter]) => {\n const eventPropertyValue = eventProperties?.[propertyName]\n\n if (isUndefined(eventPropertyValue) || isNull(eventPropertyValue)) {\n return false\n }\n\n // convert event property to string array for comparison\n const eventValues = [String(eventPropertyValue)]\n\n const comparisonFunction = propertyComparisons[filter.operator]\n if (!comparisonFunction) {\n return false\n }\n\n return comparisonFunction(filter.values, eventValues)\n })\n}\n","import { extend } from './utils'\nimport { PersistentStore, Properties } from './types'\nimport {\n DEVICE_ID,\n DISTINCT_ID,\n ENABLE_PERSON_PROCESSING,\n INITIAL_PERSON_INFO,\n SESSION_ID,\n SESSION_RECORDING_IS_SAMPLED,\n USER_STATE,\n} from './constants'\n\nimport { isNull, isUndefined } from '@posthog/core'\nimport { logger } from './utils/logger'\nimport { window, document } from './utils/globals'\nimport { uuidv7 } from './uuidv7'\n\n// we store the discovered subdomain in memory because it might be read multiple times\nlet firstNonPublicSubDomain = ''\n\n// helper to allow tests to clear this \"cache\"\nexport const resetSubDomainCache = () => {\n firstNonPublicSubDomain = ''\n}\n\n/**\n * Browsers don't offer a way to check if something is a public suffix\n * e.g. `.com.au`, `.io`, `.org.uk`\n *\n * But they do reject cookies set on public suffixes\n * Setting a cookie on `.co.uk` would mean it was sent for every `.co.uk` site visited\n *\n * So, we can use this to check if a domain is a public suffix\n * by trying to set a cookie on a subdomain of the provided hostname\n * until the browser accepts it\n *\n * inspired by https://github.com/AngusFu/browser-root-domain\n */\nexport function seekFirstNonPublicSubDomain(hostname: string, cookieJar = document): string {\n if (firstNonPublicSubDomain) {\n return firstNonPublicSubDomain\n }\n\n if (!cookieJar) {\n return ''\n }\n if (['localhost', '127.0.0.1'].includes(hostname)) return ''\n\n const list = hostname.split('.')\n let len = Math.min(list.length, 8) // paranoia - we know this number should be small\n const key = 'dmn_chk_' + uuidv7()\n\n while (!firstNonPublicSubDomain && len--) {\n const candidate = list.slice(len).join('.')\n const candidateCookieValue = key + '=1;domain=.' + candidate + ';path=/'\n\n // try to set cookie, include a short expiry in seconds since we'll check immediately\n cookieJar.cookie = candidateCookieValue + ';max-age=3'\n\n if (cookieJar.cookie.includes(key)) {\n // the cookie was accepted by the browser, remove the test cookie\n cookieJar.cookie = candidateCookieValue + ';max-age=0'\n firstNonPublicSubDomain = candidate\n }\n }\n\n return firstNonPublicSubDomain\n}\n\nconst DOMAIN_MATCH_REGEX = /[a-z0-9][a-z0-9-]+\\.[a-z]{2,}$/i\nconst originalCookieDomainFn = (hostname: string): string => {\n const matches = hostname.match(DOMAIN_MATCH_REGEX)\n return matches ? matches[0] : ''\n}\n\nexport function chooseCookieDomain(hostname: string, cross_subdomain: boolean | undefined): string {\n if (cross_subdomain) {\n // NOTE: Could we use this for cross domain tracking?\n let matchedSubDomain = seekFirstNonPublicSubDomain(hostname)\n\n if (!matchedSubDomain) {\n const originalMatch = originalCookieDomainFn(hostname)\n if (originalMatch !== matchedSubDomain) {\n logger.info('Warning: cookie subdomain discovery mismatch', originalMatch, matchedSubDomain)\n }\n matchedSubDomain = originalMatch\n }\n\n return matchedSubDomain ? '; domain=.' + matchedSubDomain : ''\n }\n return ''\n}\n\n// Methods partially borrowed from quirksmode.org/js/cookies.html\nexport const cookieStore: PersistentStore = {\n _is_supported: () => !!document,\n\n _error: function (msg) {\n logger.error('cookieStore error: ' + msg)\n },\n\n _get: function (name) {\n if (!document) {\n return\n }\n\n try {\n const nameEQ = name + '='\n const ca = document.cookie.split(';').filter((x) => x.length)\n for (let i = 0; i < ca.length; i++) {\n let c = ca[i]\n while (c.charAt(0) == ' ') {\n c = c.substring(1, c.length)\n }\n if (c.indexOf(nameEQ) === 0) {\n return decodeURIComponent(c.substring(nameEQ.length, c.length))\n }\n }\n } catch {}\n return null\n },\n\n _parse: function (name) {\n let cookie\n try {\n cookie = JSON.parse(cookieStore._get(name)) || {}\n } catch {\n // noop\n }\n return cookie\n },\n\n _set: function (name, value, days, cross_subdomain, is_secure) {\n if (!document) {\n return false\n }\n try {\n let expires = '',\n secure = ''\n\n const cdomain = chooseCookieDomain(document.location.hostname, cross_subdomain)\n\n if (days) {\n const date = new Date()\n date.setTime(date.getTime() + days * 24 * 60 * 60 * 1000)\n expires = '; expires=' + date.toUTCString()\n }\n\n if (is_secure) {\n secure = '; secure'\n }\n\n const new_cookie_val =\n name +\n '=' +\n encodeURIComponent(JSON.stringify(value)) +\n expires +\n '; SameSite=Lax; path=/' +\n cdomain +\n secure\n\n // 4096 bytes is the size at which some browsers (e.g. firefox) will not store a cookie, warn slightly before that\n if (new_cookie_val.length > 4096 * 0.9) {\n logger.warn('cookieStore warning: large cookie, len=' + new_cookie_val.length)\n }\n\n document.cookie = new_cookie_val\n return true\n } catch {\n return false\n }\n },\n\n _remove: function (name, cross_subdomain) {\n if (!document?.cookie) {\n return\n }\n try {\n cookieStore._set(name, '', -1, cross_subdomain)\n } catch {\n return\n }\n },\n}\n\nlet _localStorage_supported: boolean | null = null\nexport const resetLocalStorageSupported = () => {\n _localStorage_supported = null\n}\n\nexport const localStore: PersistentStore = {\n _is_supported: function () {\n if (!isNull(_localStorage_supported)) {\n return _localStorage_supported\n }\n\n let supported = true\n if (!isUndefined(window)) {\n try {\n const key = '__mplssupport__',\n val = 'xyz'\n localStore._set(key, val)\n if (localStore._get(key) !== '\"xyz\"') {\n supported = false\n }\n localStore._remove(key)\n } catch {\n supported = false\n }\n } else {\n supported = false\n }\n if (!supported) {\n logger.error('localStorage unsupported; falling back to cookie store')\n }\n\n _localStorage_supported = supported\n return supported\n },\n\n _error: function (msg) {\n logger.error('localStorage error: ' + msg)\n },\n\n _get: function (name) {\n try {\n return window?.localStorage.getItem(name)\n } catch (err) {\n localStore._error(err)\n }\n return null\n },\n\n _parse: function (name) {\n try {\n return JSON.parse(localStore._get(name)) || {}\n } catch {\n // noop\n }\n return null\n },\n\n _set: function (name, value) {\n try {\n window?.localStorage.setItem(name, JSON.stringify(value))\n return true\n } catch (err) {\n localStore._error(err)\n }\n return false\n },\n\n _remove: function (name) {\n try {\n window?.localStorage.removeItem(name)\n } catch (err) {\n localStore._error(err)\n }\n },\n}\n\n// Use localstorage for most data but still use cookie for COOKIE_PERSISTED_PROPERTIES\n// This solves issues with cookies having too much data in them causing headers too large\n// Also makes sure we don't have to send a ton of data to the server\nconst COOKIE_PERSISTED_PROPERTIES = [\n DEVICE_ID,\n DISTINCT_ID,\n SESSION_ID,\n SESSION_RECORDING_IS_SAMPLED,\n ENABLE_PERSON_PROCESSING,\n INITIAL_PERSON_INFO,\n USER_STATE,\n]\n\n/**\n * Creates a localPlusCookieStore instance with custom cookie-persisted properties.\n *\n * When `preferCookieOnConflict` is true, the cookie's values win over localStorage on\n * merge for any key both stores carry. Null/empty cookie values are filtered out\n * before the merge so a malformed legacy cookie cannot override valid localStorage\n * data. localStorage-only keys are unaffected. See the docs for\n * `__preview_cookie_wins_on_conflict` for context.\n */\nexport const createLocalPlusCookieStore = (\n customCookieProperties: readonly string[] = [],\n preferCookieOnConflict: boolean = false\n): PersistentStore => {\n const cookiePropertiesToPersist = [...COOKIE_PERSISTED_PROPERTIES, ...customCookieProperties]\n\n return {\n ...localStore,\n _parse: function (name) {\n try {\n let cookieProperties: Properties = {}\n try {\n // See if there's a cookie stored with data.\n cookieProperties = cookieStore._parse(name) || {}\n } catch {}\n const localStorageData: Properties = JSON.parse(localStore._get(name) || '{}')\n let value: Properties\n if (preferCookieOnConflict) {\n // Defensive: skip null / empty-string cookie values so a malformed\n // legacy cookie cannot wipe out valid localStorage data.\n const safeCookieProperties: Properties = {}\n for (const key in cookieProperties) {\n const v = cookieProperties[key]\n if (!isNull(v) && v !== '') {\n safeCookieProperties[key] = v\n }\n }\n value = extend(localStorageData, safeCookieProperties)\n } else {\n value = extend(cookieProperties, localStorageData)\n }\n localStore._set(name, value)\n return value\n } catch {\n // noop\n }\n return null\n },\n\n _set: function (name, value, days, cross_subdomain, is_secure, debug) {\n // The localStorage write is the durable one and reports its own\n // success. The cookie mirror is best-effort: a cookie failure must\n // not flip an already-landed localStorage write to `false`, or the\n // caller would treat the durable entry as un-persisted and re-write\n // it on every later save.\n const stored = localStore._set(name, value, undefined, undefined, debug)\n try {\n const cookiePersistedProperties: Record<string, any> = {}\n cookiePropertiesToPersist.forEach((key) => {\n if (value[key]) {\n cookiePersistedProperties[key] = value[key]\n }\n })\n\n if (Object.keys(cookiePersistedProperties).length) {\n cookieStore._set(name, cookiePersistedProperties, days, cross_subdomain, is_secure, debug)\n }\n } catch (err) {\n localStore._error(err)\n }\n return stored\n },\n\n _remove: function (name, cross_subdomain) {\n try {\n window?.localStorage.removeItem(name)\n cookieStore._remove(name, cross_subdomain)\n } catch (err) {\n localStore._error(err)\n }\n },\n }\n}\n\nconst memoryStorage: Properties = {}\n\n// Storage that only lasts the length of the pageview if we don't want to use cookies\nexport const memoryStore: PersistentStore = {\n _is_supported: function () {\n return true\n },\n\n _error: function (msg) {\n logger.error('memoryStorage error: ' + msg)\n },\n\n _get: function (name) {\n return memoryStorage[name] || null\n },\n\n _parse: function (name) {\n return memoryStorage[name] || null\n },\n\n _set: function (name, value) {\n memoryStorage[name] = value\n return true\n },\n\n _remove: function (name) {\n delete memoryStorage[name]\n },\n}\n\nlet sessionStorageSupported: boolean | null = null\nexport const resetSessionStorageSupported = () => {\n sessionStorageSupported = null\n}\n// Storage that only lasts the length of a tab/window. Survives page refreshes\nexport const sessionStore: PersistentStore = {\n _is_supported: function () {\n if (!isNull(sessionStorageSupported)) {\n return sessionStorageSupported\n }\n sessionStorageSupported = true\n if (!isUndefined(window)) {\n try {\n const key = '__support__',\n val = 'xyz'\n sessionStore._set(key, val)\n if (sessionStore._get(key) !== '\"xyz\"') {\n sessionStorageSupported = false\n }\n sessionStore._remove(key)\n } catch {\n sessionStorageSupported = false\n }\n } else {\n sessionStorageSupported = false\n }\n return sessionStorageSupported\n },\n\n _error: function (msg) {\n logger.error('sessionStorage error: ', msg)\n },\n\n _get: function (name) {\n try {\n return window?.sessionStorage.getItem(name)\n } catch (err) {\n sessionStore._error(err)\n }\n return null\n },\n\n _parse: function (name) {\n try {\n return JSON.parse(sessionStore._get(name)) || null\n } catch {\n // noop\n }\n return null\n },\n\n _set: function (name, value) {\n try {\n window?.sessionStorage.setItem(name, JSON.stringify(value))\n return true\n } catch (err) {\n sessionStore._error(err)\n }\n return false\n },\n\n _remove: function (name) {\n try {\n window?.sessionStorage.removeItem(name)\n } catch (err) {\n sessionStore._error(err)\n }\n },\n}\n","import { PostHog } from '../../posthog-core'\nimport { createLogger } from '../../utils/logger'\n\nconst logger = createLogger('[Stylesheet Loader]')\n\nexport const prepareStylesheet = (document: Document, innerText: string, posthog?: PostHog) => {\n // Forcing the existence of `document` requires this function to be called in a browser environment\n let stylesheet: HTMLStyleElement | null = document.createElement('style')\n stylesheet.innerText = innerText\n\n if (posthog?.config?.prepare_external_dependency_stylesheet) {\n stylesheet = posthog.config.prepare_external_dependency_stylesheet(stylesheet)\n }\n\n if (!stylesheet) {\n logger.error('prepare_external_dependency_stylesheet returned null')\n return null\n }\n\n return stylesheet\n}\n","import { VNode, cloneElement, createContext, type JSX } from 'preact'\nimport { PostHog } from '../../posthog-core'\nimport {\n MultipleSurveyQuestion,\n Survey,\n SurveyAppearance,\n SurveyEventName,\n SurveyEventProperties,\n SurveyPosition,\n SurveyQuestion,\n SurveySchedule,\n SurveyType,\n SurveyWidgetType,\n} from '../../posthog-surveys-types'\nimport { document as _document, window as _window } from '../../utils/globals'\nimport {\n getSurveyInteractionProperty,\n getSurveySeenKey,\n getSurveyAbandonedKey,\n SURVEY_LOGGER as logger,\n setSurveySeenOnLocalStorage,\n SURVEY_IN_PROGRESS_PREFIX,\n} from '../../utils/survey-utils'\nimport { isNullish, type SurveyResponses } from '@posthog/core'\nimport { buildSurveyResponseProperties, getSurveyResponseKey, surveyHasResponses } from '@posthog/core/surveys'\n\nimport { propertyComparisons } from '../../utils/property-utils'\nimport { getTargetingUrl } from '../../utils/url-targeting-utils'\nimport { localStore } from '../../storage'\nimport { Properties, PropertyMatchType } from '../../types'\nimport { Z_INDEX_SURVEYS } from '../../constants'\nimport { prepareStylesheet } from '../utils/stylesheet-loader'\n// We cast the types here which is dangerous but protected by the top level generateSurveys call\nconst window = _window as Window & typeof globalThis\nconst document = _document as Document\nimport surveyStyles from './survey.css'\nimport { useContext } from 'preact/hooks'\nimport { doesDeviceTypeMatch, hasPeriodPassed } from '../utils/matcher-utils'\n\nexport function getFontFamily(fontFamily?: string): string {\n if (fontFamily === 'inherit') {\n return 'inherit'\n }\n\n const defaultFontStack =\n 'BlinkMacSystemFont, \"Inter\", \"Segoe UI\", \"Roboto\", Helvetica, Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\"'\n return fontFamily ? `${fontFamily}, ${defaultFontStack}` : `-apple-system, ${defaultFontStack}`\n}\n\nexport { getSurveyResponseKey }\n\nconst BLACK_TEXT_COLOR = '#020617' // Maps out to text-slate-950 from tailwind colors. Intended for text use outside interactive elements like buttons\n\n// Keep in sync with defaultSurveyAppearance on the main app\nexport const defaultSurveyAppearance = {\n fontFamily: 'inherit',\n backgroundColor: '#eeeded',\n submitButtonColor: 'black',\n submitButtonTextColor: 'white',\n ratingButtonColor: 'white',\n ratingButtonActiveColor: 'black',\n borderColor: '#c9c6c6',\n placeholder: 'Start typing...',\n whiteLabel: false,\n displayThankYouMessage: true,\n thankYouMessageHeader: 'Thank you for your feedback!',\n position: SurveyPosition.Right,\n widgetType: SurveyWidgetType.Tab,\n widgetLabel: 'Feedback',\n widgetColor: 'black',\n zIndex: String(Z_INDEX_SURVEYS),\n disabledButtonOpacity: '0.6',\n maxWidth: '300px',\n textSubtleColor: '#939393',\n boxPadding: '20px 24px',\n boxShadow: '0 4px 12px rgba(0, 0, 0, 0.15)',\n borderRadius: '10px',\n shuffleQuestions: false,\n surveyPopupDelaySeconds: undefined,\n // Not customizable atm\n outlineColor: 'rgba(59, 130, 246, 0.8)',\n inputBackground: 'white',\n inputTextColor: BLACK_TEXT_COLOR,\n scrollbarThumbColor: 'var(--ph-survey-border-color)',\n scrollbarTrackColor: 'var(--ph-survey-background-color)',\n} as const\n\nconst BOTTOM_BORDER_SURVEY_POSITIONS: SurveyPosition[] = [\n SurveyPosition.Center,\n SurveyPosition.Left,\n SurveyPosition.Right,\n]\n\nexport const addSurveyCSSVariablesToElement = (\n element: HTMLElement,\n type: SurveyType,\n appearance?: SurveyAppearance | null\n) => {\n const effectiveAppearance = { ...defaultSurveyAppearance, ...appearance }\n const hostStyle = element.style\n\n const surveyHasBottomBorder =\n !BOTTOM_BORDER_SURVEY_POSITIONS.includes(effectiveAppearance.position) ||\n (type === SurveyType.Widget && appearance?.widgetType === SurveyWidgetType.Tab)\n\n hostStyle.setProperty('--ph-survey-font-family', getFontFamily(effectiveAppearance.fontFamily))\n hostStyle.setProperty('--ph-survey-box-padding', effectiveAppearance.boxPadding)\n hostStyle.setProperty('--ph-survey-max-width', effectiveAppearance.maxWidth)\n hostStyle.setProperty('--ph-survey-z-index', effectiveAppearance.zIndex)\n hostStyle.setProperty('--ph-survey-border-color', effectiveAppearance.borderColor)\n // Non-bottom surveys or tab surveys have the border bottom\n if (surveyHasBottomBorder) {\n hostStyle.setProperty('--ph-survey-border-radius', effectiveAppearance.borderRadius)\n hostStyle.setProperty('--ph-survey-border-bottom', '1.5px solid var(--ph-survey-border-color)')\n } else {\n hostStyle.setProperty('--ph-survey-border-bottom', 'none')\n hostStyle.setProperty(\n '--ph-survey-border-radius',\n `${effectiveAppearance.borderRadius} ${effectiveAppearance.borderRadius} 0 0`\n )\n }\n hostStyle.setProperty('--ph-survey-background-color', effectiveAppearance.backgroundColor)\n hostStyle.setProperty('--ph-survey-box-shadow', effectiveAppearance.boxShadow)\n hostStyle.setProperty('--ph-survey-disabled-button-opacity', effectiveAppearance.disabledButtonOpacity)\n hostStyle.setProperty('--ph-survey-submit-button-color', effectiveAppearance.submitButtonColor)\n hostStyle.setProperty(\n '--ph-survey-submit-button-text-color',\n appearance?.submitButtonTextColor || getContrastingTextColor(effectiveAppearance.submitButtonColor)\n )\n hostStyle.setProperty('--ph-survey-rating-bg-color', effectiveAppearance.ratingButtonColor)\n hostStyle.setProperty('--ph-survey-rating-active-bg-color', effectiveAppearance.ratingButtonActiveColor)\n // Active rating text is always auto-calculated for contrast with active background\n hostStyle.setProperty(\n '--ph-survey-rating-active-text-color',\n getContrastingTextColor(effectiveAppearance.ratingButtonActiveColor)\n )\n // Primary text color: use override if provided, otherwise auto-calculate from background\n hostStyle.setProperty(\n '--ph-survey-text-primary-color',\n appearance?.textColor || getContrastingTextColor(effectiveAppearance.backgroundColor)\n )\n hostStyle.setProperty('--ph-survey-text-subtle-color', effectiveAppearance.textSubtleColor)\n hostStyle.setProperty('--ph-widget-color', effectiveAppearance.widgetColor)\n hostStyle.setProperty('--ph-widget-text-color', getContrastingTextColor(effectiveAppearance.widgetColor))\n hostStyle.setProperty('--ph-widget-z-index', effectiveAppearance.zIndex)\n\n // Use user-provided inputBackground (or deprecated inputBackgroundColor for backwards compat)\n // Fallback to internal default, with slight adjustment for white backgrounds\n const userInputBg = appearance?.inputBackground || appearance?.inputBackgroundColor\n let inputBgColor = userInputBg || effectiveAppearance.inputBackground\n if (!userInputBg && effectiveAppearance.backgroundColor === 'white') {\n inputBgColor = '#f8f8f8'\n }\n hostStyle.setProperty('--ph-survey-input-background', inputBgColor)\n // Input text color applies to both text inputs and inactive rating buttons\n const inputTextColor = appearance?.inputTextColor || getContrastingTextColor(inputBgColor)\n hostStyle.setProperty('--ph-survey-input-text-color', inputTextColor)\n hostStyle.setProperty('--ph-survey-rating-text-color', inputTextColor)\n hostStyle.setProperty('--ph-survey-scrollbar-thumb-color', effectiveAppearance.scrollbarThumbColor)\n hostStyle.setProperty('--ph-survey-scrollbar-track-color', effectiveAppearance.scrollbarTrackColor)\n hostStyle.setProperty('--ph-survey-outline-color', effectiveAppearance.outlineColor)\n}\n\nfunction nameToHex(name: string) {\n return {\n aliceblue: '#f0f8ff',\n antiquewhite: '#faebd7',\n aqua: '#00ffff',\n aquamarine: '#7fffd4',\n azure: '#f0ffff',\n beige: '#f5f5dc',\n bisque: '#ffe4c4',\n black: '#000000',\n blanchedalmond: '#ffebcd',\n blue: '#0000ff',\n blueviolet: '#8a2be2',\n brown: '#a52a2a',\n burlywood: '#deb887',\n cadetblue: '#5f9ea0',\n chartreuse: '#7fff00',\n chocolate: '#d2691e',\n coral: '#ff7f50',\n cornflowerblue: '#6495ed',\n cornsilk: '#fff8dc',\n crimson: '#dc143c',\n cyan: '#00ffff',\n darkblue: '#00008b',\n darkcyan: '#008b8b',\n darkgoldenrod: '#b8860b',\n darkgray: '#a9a9a9',\n darkgreen: '#006400',\n darkkhaki: '#bdb76b',\n darkmagenta: '#8b008b',\n darkolivegreen: '#556b2f',\n darkorange: '#ff8c00',\n darkorchid: '#9932cc',\n darkred: '#8b0000',\n darksalmon: '#e9967a',\n darkseagreen: '#8fbc8f',\n darkslateblue: '#483d8b',\n darkslategray: '#2f4f4f',\n darkturquoise: '#00ced1',\n darkviolet: '#9400d3',\n deeppink: '#ff1493',\n deepskyblue: '#00bfff',\n dimgray: '#696969',\n dodgerblue: '#1e90ff',\n firebrick: '#b22222',\n floralwhite: '#fffaf0',\n forestgreen: '#228b22',\n fuchsia: '#ff00ff',\n gainsboro: '#dcdcdc',\n ghostwhite: '#f8f8ff',\n gold: '#ffd700',\n goldenrod: '#daa520',\n gray: '#808080',\n green: '#008000',\n greenyellow: '#adff2f',\n honeydew: '#f0fff0',\n hotpink: '#ff69b4',\n 'indianred ': '#cd5c5c',\n indigo: '#4b0082',\n ivory: '#fffff0',\n khaki: '#f0e68c',\n lavender: '#e6e6fa',\n lavenderblush: '#fff0f5',\n lawngreen: '#7cfc00',\n lemonchiffon: '#fffacd',\n lightblue: '#add8e6',\n lightcoral: '#f08080',\n lightcyan: '#e0ffff',\n lightgoldenrodyellow: '#fafad2',\n lightgrey: '#d3d3d3',\n lightgreen: '#90ee90',\n lightpink: '#ffb6c1',\n lightsalmon: '#ffa07a',\n lightseagreen: '#20b2aa',\n lightskyblue: '#87cefa',\n lightslategray: '#778899',\n lightsteelblue: '#b0c4de',\n lightyellow: '#ffffe0',\n lime: '#00ff00',\n limegreen: '#32cd32',\n linen: '#faf0e6',\n magenta: '#ff00ff',\n maroon: '#800000',\n mediumaquamarine: '#66cdaa',\n mediumblue: '#0000cd',\n mediumorchid: '#ba55d3',\n mediumpurple: '#9370d8',\n mediumseagreen: '#3cb371',\n mediumslateblue: '#7b68ee',\n mediumspringgreen: '#00fa9a',\n mediumturquoise: '#48d1cc',\n mediumvioletred: '#c71585',\n midnightblue: '#191970',\n mintcream: '#f5fffa',\n mistyrose: '#ffe4e1',\n moccasin: '#ffe4b5',\n navajowhite: '#ffdead',\n navy: '#000080',\n oldlace: '#fdf5e6',\n olive: '#808000',\n olivedrab: '#6b8e23',\n orange: '#ffa500',\n orangered: '#ff4500',\n orchid: '#da70d6',\n palegoldenrod: '#eee8aa',\n palegreen: '#98fb98',\n paleturquoise: '#afeeee',\n palevioletred: '#d87093',\n papayawhip: '#ffefd5',\n peachpuff: '#ffdab9',\n peru: '#cd853f',\n pink: '#ffc0cb',\n plum: '#dda0dd',\n powderblue: '#b0e0e6',\n purple: '#800080',\n red: '#ff0000',\n rosybrown: '#bc8f8f',\n royalblue: '#4169e1',\n saddlebrown: '#8b4513',\n salmon: '#fa8072',\n sandybrown: '#f4a460',\n seagreen: '#2e8b57',\n seashell: '#fff5ee',\n sienna: '#a0522d',\n silver: '#c0c0c0',\n skyblue: '#87ceeb',\n slateblue: '#6a5acd',\n slategray: '#708090',\n snow: '#fffafa',\n springgreen: '#00ff7f',\n steelblue: '#4682b4',\n tan: '#d2b48c',\n teal: '#008080',\n thistle: '#d8bfd8',\n tomato: '#ff6347',\n turquoise: '#40e0d0',\n violet: '#ee82ee',\n wheat: '#f5deb3',\n white: '#ffffff',\n whitesmoke: '#f5f5f5',\n yellow: '#ffff00',\n yellowgreen: '#9acd32',\n }[name.toLowerCase()]\n}\n\nexport function hex2rgb(c: string): string {\n if (c.startsWith('#')) {\n let hexColor = c.replace(/^#/, '')\n // Handle 3-character shorthand (e.g., #111 -> #111111, #abc -> #aabbcc)\n if (/^[0-9A-Fa-f]{3}$/.test(hexColor)) {\n hexColor = hexColor[0] + hexColor[0] + hexColor[1] + hexColor[1] + hexColor[2] + hexColor[2]\n }\n if (!/^[0-9A-Fa-f]{6}$/.test(hexColor)) {\n return 'rgb(255, 255, 255)'\n }\n const r = parseInt(hexColor.slice(0, 2), 16)\n const g = parseInt(hexColor.slice(2, 4), 16)\n const b = parseInt(hexColor.slice(4, 6), 16)\n return `rgb(${r},${g},${b})`\n }\n return 'rgb(255, 255, 255)'\n}\n\nexport function hexToRgba(hex: string, opacity: number): string {\n const rgb = hex2rgb(hex)\n const match = rgb.match(/^rgb\\((\\d+),(\\d+),(\\d+)\\)$/)\n if (!match) {\n return hex\n }\n return `rgba(${match[1]}, ${match[2]}, ${match[3]}, ${opacity})`\n}\n\nexport function getContrastingTextColor(color: string = defaultSurveyAppearance.backgroundColor) {\n let rgb\n if (color[0] === '#') {\n rgb = hex2rgb(color)\n }\n if (color.startsWith('rgb')) {\n rgb = color\n }\n // otherwise it's a color name\n const nameColorToHex = nameToHex(color)\n if (nameColorToHex) {\n rgb = hex2rgb(nameColorToHex)\n }\n if (!rgb) {\n return BLACK_TEXT_COLOR\n }\n const colorMatch = rgb.match(/^rgba?\\((\\d+),\\s*(\\d+),\\s*(\\d+)(?:,\\s*(\\d+(?:\\.\\d+)?))?\\)$/)\n if (colorMatch) {\n const r = parseInt(colorMatch[1])\n const g = parseInt(colorMatch[2])\n const b = parseInt(colorMatch[3])\n const hsp = Math.sqrt(0.299 * (r * r) + 0.587 * (g * g) + 0.114 * (b * b))\n return hsp > 127.5 ? BLACK_TEXT_COLOR : 'white'\n }\n return BLACK_TEXT_COLOR\n}\n\nexport function getSurveyStylesheet(posthog?: PostHog) {\n const stylesheet = prepareStylesheet(document, typeof surveyStyles === 'string' ? surveyStyles : '', posthog)\n stylesheet?.setAttribute('data-ph-survey-style', 'true')\n return stylesheet\n}\n\nexport const retrieveSurveyShadow = (\n survey: Pick<Survey, 'id' | 'appearance' | 'type'>,\n posthog?: PostHog,\n element?: Element\n) => {\n const widgetClassName = getSurveyContainerClass(survey)\n const existingDiv = document.querySelector(`.${widgetClassName}`)\n\n if (existingDiv && existingDiv.shadowRoot) {\n return {\n shadow: existingDiv.shadowRoot,\n isNewlyCreated: false,\n }\n }\n\n // If it doesn't exist, create it\n const div = document.createElement('div')\n addSurveyCSSVariablesToElement(div, survey.type, survey.appearance)\n div.className = widgetClassName\n const shadow = div.attachShadow({ mode: 'open' })\n const stylesheet = getSurveyStylesheet(posthog)\n if (stylesheet) {\n const existingStylesheet = shadow.querySelector('style')\n if (existingStylesheet) {\n shadow.removeChild(existingStylesheet)\n }\n shadow.appendChild(stylesheet)\n }\n ;(element ? element : document.body).appendChild(div)\n return {\n shadow,\n isNewlyCreated: true,\n }\n}\n\ninterface SendSurveyEventArgs {\n responses: SurveyResponses\n survey: Survey\n surveySubmissionId: string\n isSurveyCompleted: boolean\n posthog?: PostHog\n /** Additional properties to include in the survey event */\n properties?: Properties\n /** The language that was applied to the survey. */\n surveyLanguage?: string | null\n}\n\nexport const sendSurveyEvent = ({\n responses,\n survey,\n surveySubmissionId,\n posthog,\n isSurveyCompleted,\n properties,\n surveyLanguage,\n}: SendSurveyEventArgs) => {\n if (!posthog) {\n logger.error('[survey sent] event not captured, PostHog instance not found.')\n return\n }\n setSurveySeenOnLocalStorage(survey)\n posthog.capture(SurveyEventName.SENT, {\n [SurveyEventProperties.SURVEY_NAME]: survey.name,\n [SurveyEventProperties.SURVEY_ID]: survey.id,\n [SurveyEventProperties.SURVEY_ITERATION]: survey.current_iteration,\n [SurveyEventProperties.SURVEY_ITERATION_START_DATE]: survey.current_iteration_start_date,\n [SurveyEventProperties.SURVEY_SUBMISSION_ID]: surveySubmissionId,\n [SurveyEventProperties.SURVEY_COMPLETED]: isSurveyCompleted,\n ...(surveyLanguage && { [SurveyEventProperties.SURVEY_LANGUAGE]: surveyLanguage }),\n sessionRecordingUrl: posthog.get_session_replay_url?.(),\n ...buildSurveyResponseProperties(responses, survey),\n ...properties,\n $set: {\n [getSurveyInteractionProperty(survey, 'responded')]: true,\n },\n })\n if (isSurveyCompleted) {\n // Only dispatch PHSurveySent if the survey is completed, as that removes the survey from focus\n window.dispatchEvent(new CustomEvent('PHSurveySent', { detail: { surveyId: survey.id } }))\n clearInProgressSurveyState(survey)\n }\n}\n\nconst _buildSurveyEventProperties = (\n survey: Survey,\n inProgressSurvey: InProgressSurveyState | null,\n posthog: PostHog\n) => ({\n [SurveyEventProperties.SURVEY_NAME]: survey.name,\n [SurveyEventProperties.SURVEY_ID]: survey.id,\n [SurveyEventProperties.SURVEY_ITERATION]: survey.current_iteration,\n [SurveyEventProperties.SURVEY_ITERATION_START_DATE]: survey.current_iteration_start_date,\n [SurveyEventProperties.SURVEY_PARTIALLY_COMPLETED]: surveyHasResponses(inProgressSurvey?.responses),\n ...(inProgressSurvey?.surveyLanguage && {\n [SurveyEventProperties.SURVEY_LANGUAGE]: inProgressSurvey.surveyLanguage,\n }),\n sessionRecordingUrl: posthog.get_session_replay_url?.(),\n [SurveyEventProperties.SURVEY_SUBMISSION_ID]: inProgressSurvey?.surveySubmissionId,\n ...buildSurveyResponseProperties(inProgressSurvey?.responses, survey),\n})\n\nexport const dismissedSurveyEvent = (\n survey: Survey,\n posthog?: PostHog,\n readOnly?: boolean,\n surveyLanguage?: string | null\n) => {\n if (!posthog) {\n logger.error('[survey dismissed] event not captured, PostHog instance not found.')\n return\n }\n if (readOnly) {\n return\n }\n\n const inProgressSurvey = getInProgressSurveyState(survey)\n posthog.capture(SurveyEventName.DISMISSED, {\n ..._buildSurveyEventProperties(survey, inProgressSurvey, posthog),\n ...(surveyLanguage && { [SurveyEventProperties.SURVEY_LANGUAGE]: surveyLanguage }),\n $set: {\n [getSurveyInteractionProperty(survey, 'dismissed')]: true,\n },\n })\n clearInProgressSurveyState(survey)\n setSurveySeenOnLocalStorage(survey)\n window.dispatchEvent(new CustomEvent('PHSurveyClosed', { detail: { surveyId: survey.id } }))\n}\n\nexport const sendSurveyAbandonedEvent = (survey: Survey, posthog?: PostHog) => {\n if (!posthog) {\n logger.error('[survey abandoned] event not captured, PostHog instance not found.')\n return\n }\n\n const abandonedKey = getSurveyAbandonedKey(survey)\n try {\n if (localStorage.getItem(abandonedKey) === 'true') {\n return\n }\n } catch {\n // localStorage not available\n return\n }\n\n const inProgressSurvey = getInProgressSurveyState(survey)\n if (!inProgressSurvey) {\n return\n }\n\n try {\n localStorage.setItem(abandonedKey, 'true')\n } catch {\n // localStorage not available\n }\n\n posthog.capture(SurveyEventName.ABANDONED, _buildSurveyEventProperties(survey, inProgressSurvey, posthog), {\n transport: 'sendBeacon',\n })\n}\n\n// Use the Fisher-yates algorithm to shuffle this array\n// https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle\nexport const shuffle = (array: any[]) => {\n return array\n .map((a) => ({ sort: Math.floor(Math.random() * 10), value: a }))\n .sort((a, b) => a.sort - b.sort)\n .map((a) => a.value)\n}\n\nconst reverseIfUnshuffled = (unshuffled: any[], shuffled: any[]): any[] => {\n if (unshuffled.length === shuffled.length && unshuffled.every((val, index) => val === shuffled[index])) {\n return shuffled.reverse()\n }\n\n return shuffled\n}\n\nexport const getDisplayOrderChoices = (question: MultipleSurveyQuestion): string[] => {\n if (!question.shuffleOptions) {\n return question.choices\n }\n\n const displayOrderChoices = question.choices\n let openEndedChoice = ''\n if (question.hasOpenChoice) {\n // if the question has an open-ended choice, its always the last element in the choices array.\n openEndedChoice = displayOrderChoices.pop()!\n }\n\n const shuffledOptions = reverseIfUnshuffled(displayOrderChoices, shuffle(displayOrderChoices))\n\n if (question.hasOpenChoice) {\n question.choices.push(openEndedChoice)\n shuffledOptions.push(openEndedChoice)\n }\n\n return shuffledOptions\n}\n\nexport const getDisplayOrderQuestions = (survey: Survey): SurveyQuestion[] => {\n if (!survey.appearance || !survey.appearance.shuffleQuestions || survey.enable_partial_responses) {\n return survey.questions\n }\n\n return reverseIfUnshuffled(survey.questions, shuffle(survey.questions))\n}\n\nexport const hasEvents = (survey: Pick<Survey, 'conditions'>): boolean => {\n return survey.conditions?.events?.values?.length != undefined && survey.conditions?.events?.values?.length > 0\n}\n\nexport const canActivateRepeatedly = (\n survey: Pick<Survey, 'schedule' | 'conditions' | 'id' | 'current_iteration'>\n): boolean => {\n return (\n !!(survey.conditions?.events?.repeatedActivation && hasEvents(survey)) ||\n survey.schedule === SurveySchedule.Always ||\n isSurveyInProgress(survey)\n )\n}\n\n/**\n * getSurveySeen checks local storage for the surveySeen Key a\n * and overrides this value if the survey can be repeatedly activated by its events.\n * @param survey\n */\nexport const getSurveySeen = (survey: Survey): boolean => {\n const surveySeen = localStore._get(getSurveySeenKey(survey))\n if (surveySeen) {\n // if a survey has already been seen,\n // we will override it with the event repeated activation value.\n return !canActivateRepeatedly(survey)\n }\n\n return false\n}\n\nconst LAST_SEEN_SURVEY_DATE_KEY = 'lastSeenSurveyDate'\n\nexport const hasWaitPeriodPassed = (waitPeriodInDays: number | undefined): boolean => {\n const lastSeenSurveyDate = localStore._get(LAST_SEEN_SURVEY_DATE_KEY)\n return hasPeriodPassed(waitPeriodInDays, lastSeenSurveyDate)\n}\n\ninterface SurveyContextProps {\n isPreviewMode: boolean\n previewPageIndex: number | undefined\n onPopupSurveyDismissed: () => void\n isPopup: boolean\n onPreviewSubmit: (res: string | string[] | number | null) => void\n onPreviewBack: () => void\n surveySubmissionId: string\n /** Additional properties to include in all survey events */\n properties?: Properties\n /** The language that was applied to the survey. */\n surveyLanguage?: string | null\n}\n\nexport const SurveyContext = createContext<SurveyContextProps>({\n isPreviewMode: false,\n previewPageIndex: 0,\n onPopupSurveyDismissed: () => {},\n isPopup: true,\n onPreviewSubmit: () => {},\n onPreviewBack: () => {},\n surveySubmissionId: '',\n properties: undefined,\n surveyLanguage: null,\n})\n\nexport const useSurveyContext = () => {\n return useContext(SurveyContext)\n}\n\ninterface RenderProps {\n component: VNode<{ className: string }>\n children: string\n renderAsHtml?: boolean\n style?: JSX.CSSProperties\n}\n\nexport const renderChildrenAsTextOrHtml = ({ component, children, renderAsHtml, style }: RenderProps) => {\n return renderAsHtml\n ? cloneElement(component, {\n dangerouslySetInnerHTML: { __html: children },\n style,\n })\n : cloneElement(component, {\n children,\n style,\n })\n}\n\nfunction defaultMatchType(matchType?: PropertyMatchType): PropertyMatchType {\n return matchType ?? 'icontains'\n}\n\n// use urlMatchType to validate url condition, fallback to contains for backwards compatibility\nexport function doesSurveyUrlMatch(survey: Pick<Survey, 'conditions'>, posthog?: PostHog): boolean {\n if (!survey.conditions?.url) {\n return true\n }\n // honors the `get_current_url` config hook so apps that rewrite their URL can target surveys correctly\n const href = getTargetingUrl(posthog)\n if (!href) {\n // if we dont know the url, assume it is not a match\n return false\n }\n const targets = [survey.conditions.url]\n const matchType = defaultMatchType(survey.conditions?.urlMatchType)\n return propertyComparisons[matchType](targets, [href])\n}\n\nexport function doesSurveyDeviceTypesMatch(survey: Survey): boolean {\n return doesDeviceTypeMatch(survey.conditions?.deviceTypes, survey.conditions?.deviceTypesMatchType)\n}\n\nexport function doesSurveyMatchSelector(survey: Survey): boolean {\n if (!survey.conditions?.selector) {\n return true\n }\n return !!document?.querySelector(survey.conditions.selector)\n}\n\ninterface InProgressSurveyState {\n surveySubmissionId: string\n lastQuestionIndex: number\n // Indices the respondent has visited, in order, excluding the current one. Pushed on next, popped on back.\n // Optional for backwards compat with state persisted before the back-navigation feature.\n visitedIndices?: number[]\n responses: SurveyResponses\n surveyLanguage?: string | null\n}\n\nconst getInProgressSurveyStateKey = (survey: Pick<Survey, 'id' | 'current_iteration'>): string => {\n let key = `${SURVEY_IN_PROGRESS_PREFIX}${survey.id}`\n if (survey.current_iteration && survey.current_iteration > 0) {\n key = `${SURVEY_IN_PROGRESS_PREFIX}${survey.id}_${survey.current_iteration}`\n }\n return key\n}\n\nexport const setInProgressSurveyState = (\n survey: Pick<Survey, 'id' | 'current_iteration'>,\n state: InProgressSurveyState\n): void => {\n try {\n localStorage.setItem(getInProgressSurveyStateKey(survey), JSON.stringify(state))\n } catch (e) {\n logger.error('Error setting in-progress survey state in localStorage', e)\n }\n}\n\nexport const getInProgressSurveyState = (\n survey: Pick<Survey, 'id' | 'current_iteration'>\n): InProgressSurveyState | null => {\n try {\n const stateString = localStorage.getItem(getInProgressSurveyStateKey(survey))\n if (stateString) {\n return JSON.parse(stateString) as InProgressSurveyState\n }\n } catch (e) {\n logger.error('Error getting in-progress survey state from localStorage', e)\n }\n return null\n}\n\nexport const isSurveyInProgress = (survey: Pick<Survey, 'id' | 'current_iteration'>): boolean => {\n const state = getInProgressSurveyState(survey)\n return !isNullish(state?.surveySubmissionId)\n}\n\nexport const clearInProgressSurveyState = (survey: Pick<Survey, 'id' | 'current_iteration'>): void => {\n try {\n localStorage.removeItem(getInProgressSurveyStateKey(survey))\n } catch (e) {\n logger.error('Error clearing in-progress survey state from localStorage', e)\n }\n}\n\nexport function getSurveyContainerClass(survey: Pick<Survey, 'id'>, asSelector = false): string {\n const className = `PostHogSurvey-${survey.id}`\n return asSelector ? `.${className}` : className\n}\n\n/**\n * Get CSS position styles for a popover/modal based on SurveyPosition\n * Used by both surveys and product tours for consistent positioning\n */\nexport function getPopoverPosition(\n type?: SurveyType,\n position: SurveyPosition = SurveyPosition.Right,\n surveyWidgetType?: SurveyWidgetType\n): Record<string, string> {\n if (type === SurveyType.ExternalSurvey) {\n return {}\n }\n\n switch (position) {\n case SurveyPosition.TopLeft:\n return { top: '0', left: '0', transform: 'translate(30px, 30px)' }\n case SurveyPosition.TopRight:\n return { top: '0', right: '0', transform: 'translate(-30px, 30px)' }\n case SurveyPosition.TopCenter:\n return { top: '0', left: '50%', transform: 'translate(-50%, 30px)' }\n case SurveyPosition.MiddleLeft:\n return { top: '50%', left: '0', transform: 'translate(30px, -50%)' }\n case SurveyPosition.MiddleRight:\n return { top: '50%', right: '0', transform: 'translate(-30px, -50%)' }\n case SurveyPosition.MiddleCenter:\n return { top: '50%', left: '50%', transform: 'translate(-50%, -50%)' }\n case SurveyPosition.Left:\n return { left: '30px' }\n case SurveyPosition.Center:\n return { left: '50%', transform: 'translateX(-50%)' }\n default:\n case SurveyPosition.Right:\n return { right: type === SurveyType.Widget && surveyWidgetType === SurveyWidgetType.Tab ? '60px' : '30px' }\n }\n}\n","import type { PostHog } from '../posthog-core'\nimport { window } from './globals'\nimport { isFunction, isString, isUndefined } from '@posthog/core'\nimport { logger } from './logger'\n\n/**\n * Applies the `get_current_url` config hook to an already-resolved URL. Returns `defaultUrl`\n * unchanged when no override is configured, or if the override throws or returns a\n * non-string/empty value.\n *\n * Use this when the caller already has its own URL source (e.g. web experiments read\n * `window.location` via a mockable indirection); otherwise prefer `getTargetingUrl`.\n */\nexport function applyUrlTargetingOverride(instance: PostHog | undefined, defaultUrl: string): string {\n const override = instance?.config?.get_current_url\n if (!isFunction(override)) {\n return defaultUrl\n }\n\n try {\n const result = override(defaultUrl)\n return isString(result) && result ? result : defaultUrl\n } catch (e) {\n logger.error('Error in get_current_url, falling back to window.location.href', e)\n return defaultUrl\n }\n}\n\n/**\n * Resolves the URL used for client-side URL targeting: session replay URL triggers, the\n * session replay URL blocklist, survey URL conditions, product tour URL conditions, and web\n * experiment URL conditions.\n *\n * Defaults to `window.location.href`, but honors the `get_current_url` config hook so apps\n * that rewrite their URL (e.g. Electron/desktop builds, or `$current_url` rewrites in\n * `before_send`) can make targeting match the logical URL instead of the raw browser URL.\n *\n * Returns `undefined` when there is no URL available (e.g. non-browser environments).\n *\n * Called on every rrweb event by the replay URL triggers/blocklist, so a configured\n * `get_current_url` override should stay cheap.\n */\nexport function getTargetingUrl(instance: PostHog | undefined): string | undefined {\n const defaultUrl = window?.location?.href\n return isUndefined(defaultUrl) ? undefined : applyUrlTargetingOverride(instance, defaultUrl)\n}\n","import { detectDeviceType } from '@posthog/core'\nimport { navigator, userAgent, window } from '../../utils/globals'\nimport { propertyComparisons } from '../../utils/property-utils'\nimport { PropertyMatchType } from '../../types'\n\nexport function doesDeviceTypeMatch(deviceTypes?: string[], matchType?: PropertyMatchType): boolean {\n if (!deviceTypes || deviceTypes.length === 0) {\n return true\n }\n if (!userAgent) {\n return false\n }\n const deviceType = detectDeviceType(userAgent, {\n // eslint-disable-next-line compat/compat\n userAgentDataPlatform: navigator?.userAgentData?.platform,\n maxTouchPoints: navigator?.maxTouchPoints,\n screenWidth: window?.screen?.width,\n screenHeight: window?.screen?.height,\n devicePixelRatio: window?.devicePixelRatio,\n })\n return propertyComparisons[matchType ?? 'icontains'](deviceTypes, [deviceType])\n}\n\nexport function hasPeriodPassed(periodDays?: number, lastSeenDate?: string | Date | null): boolean {\n if (!periodDays || !lastSeenDate) {\n return true\n }\n\n const date = typeof lastSeenDate === 'string' ? new Date(lastSeenDate) : lastSeenDate\n\n const now = new Date()\n const diffMs = Math.abs(now.getTime() - date.getTime())\n const diffDays = Math.ceil(diffMs / (1000 * 3600 * 24))\n return diffDays > periodDays\n}\n","export const satisfiedEmoji = (\n <svg className=\"emoji-svg\" xmlns=\"http://www.w3.org/2000/svg\" height=\"48\" viewBox=\"0 -960 960 960\" width=\"48\">\n <path d=\"M626-533q22.5 0 38.25-15.75T680-587q0-22.5-15.75-38.25T626-641q-22.5 0-38.25 15.75T572-587q0 22.5 15.75 38.25T626-533Zm-292 0q22.5 0 38.25-15.75T388-587q0-22.5-15.75-38.25T334-641q-22.5 0-38.25 15.75T280-587q0 22.5 15.75 38.25T334-533Zm146 272q66 0 121.5-35.5T682-393h-52q-23 40-63 61.5T480.5-310q-46.5 0-87-21T331-393h-53q26 61 81 96.5T480-261Zm0 181q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Zm0-400Zm0 340q142.375 0 241.188-98.812Q820-337.625 820-480t-98.812-241.188Q622.375-820 480-820t-241.188 98.812Q140-622.375 140-480t98.812 241.188Q337.625-140 480-140Z\" />\n </svg>\n)\nexport const neutralEmoji = (\n <svg className=\"emoji-svg\" xmlns=\"http://www.w3.org/2000/svg\" height=\"48\" viewBox=\"0 -960 960 960\" width=\"48\">\n <path d=\"M626-533q22.5 0 38.25-15.75T680-587q0-22.5-15.75-38.25T626-641q-22.5 0-38.25 15.75T572-587q0 22.5 15.75 38.25T626-533Zm-292 0q22.5 0 38.25-15.75T388-587q0-22.5-15.75-38.25T334-641q-22.5 0-38.25 15.75T280-587q0 22.5 15.75 38.25T334-533Zm20 194h253v-49H354v49ZM480-80q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Zm0-400Zm0 340q142.375 0 241.188-98.812Q820-337.625 820-480t-98.812-241.188Q622.375-820 480-820t-241.188 98.812Q140-622.375 140-480t98.812 241.188Q337.625-140 480-140Z\" />\n </svg>\n)\nexport const dissatisfiedEmoji = (\n <svg className=\"emoji-svg\" xmlns=\"http://www.w3.org/2000/svg\" height=\"48\" viewBox=\"0 -960 960 960\" width=\"48\">\n <path d=\"M626-533q22.5 0 38.25-15.75T680-587q0-22.5-15.75-38.25T626-641q-22.5 0-38.25 15.75T572-587q0 22.5 15.75 38.25T626-533Zm-292 0q22.5 0 38.25-15.75T388-587q0-22.5-15.75-38.25T334-641q-22.5 0-38.25 15.75T280-587q0 22.5 15.75 38.25T334-533Zm146.174 116Q413-417 358.5-379.5T278-280h53q22-42 62.173-65t87.5-23Q528-368 567.5-344.5T630-280h52q-25-63-79.826-100-54.826-37-122-37ZM480-80q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Zm0-400Zm0 340q142.375 0 241.188-98.812Q820-337.625 820-480t-98.812-241.188Q622.375-820 480-820t-241.188 98.812Q140-622.375 140-480t98.812 241.188Q337.625-140 480-140Z\" />\n </svg>\n)\nexport const veryDissatisfiedEmoji = (\n <svg className=\"emoji-svg\" xmlns=\"http://www.w3.org/2000/svg\" height=\"48\" viewBox=\"0 -960 960 960\" width=\"48\">\n <path d=\"M480-417q-67 0-121.5 37.5T278-280h404q-25-63-80-100t-122-37Zm-183-72 50-45 45 45 31-36-45-45 45-45-31-36-45 45-50-45-31 36 45 45-45 45 31 36Zm272 0 44-45 51 45 31-36-45-45 45-45-31-36-51 45-44-45-31 36 44 45-44 45 31 36ZM480-80q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Zm0-400Zm0 340q142 0 241-99t99-241q0-142-99-241t-241-99q-142 0-241 99t-99 241q0 142 99 241t241 99Z\" />\n </svg>\n)\nexport const verySatisfiedEmoji = (\n <svg className=\"emoji-svg\" xmlns=\"http://www.w3.org/2000/svg\" height=\"48\" viewBox=\"0 -960 960 960\" width=\"48\">\n <path d=\"M479.504-261Q537-261 585.5-287q48.5-26 78.5-72.4 6-11.6-.75-22.6-6.75-11-20.25-11H316.918Q303-393 296.5-382t-.5 22.6q30 46.4 78.5 72.4 48.5 26 105.004 26ZM347-578l27 27q7.636 8 17.818 8Q402-543 410-551q8-8 8-18t-8-18l-42-42q-8.8-9-20.9-9-12.1 0-21.1 9l-42 42q-8 7.636-8 17.818Q276-559 284-551q8 8 18 8t18-8l27-27Zm267 0 27 27q7.714 8 18 8t18-8q8-7.636 8-17.818Q685-579 677-587l-42-42q-8.8-9-20.9-9-12.1 0-21.1 9l-42 42q-8 7.714-8 18t8 18q7.636 8 17.818 8Q579-543 587-551l27-27ZM480-80q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Zm0-400Zm0 340q142.375 0 241.188-98.812Q820-337.625 820-480t-98.812-241.188Q622.375-820 480-820t-241.188 98.812Q140-622.375 140-480t98.812 241.188Q337.625-140 480-140Z\" />\n </svg>\n)\nexport const thumbsUpEmoji = (\n <svg className=\"emoji-svg\" xmlns=\"http://www.w3.org/2000/svg\" height=\"48\" viewBox=\"0 0 24 24\" width=\"48\">\n <path d=\"M2 20h2c.55 0 1-.45 1-1v-9c0-.55-.45-1-1-1H2v11zm19.83-7.12c.11-.25.17-.52.17-.8V11c0-1.1-.9-2-2-2h-5.5l.92-4.65c.05-.22.02-.46-.08-.66-.23-.45-.52-.86-.88-1.22L14 2 7.59 8.41C7.21 8.79 7 9.3 7 9.83v7.84C7 18.95 8.05 20 9.34 20h8.11c.7 0 1.36-.37 1.72-.97l2.66-6.15z\" />\n </svg>\n)\nexport const thumbsDownEmoji = (\n <svg className=\"emoji-svg\" xmlns=\"http://www.w3.org/2000/svg\" height=\"48\" viewBox=\"0 0 24 24\" width=\"48\">\n <path d=\"M22 4h-2c-.55 0-1 .45-1 1v9c0 .55.45 1 1 1h2V4zM2.17 11.12c-.11.25-.17.52-.17.8V13c0 1.1.9 2 2 2h5.5l-.92 4.65c-.05.22-.02.46.08.66.23.45.52.86.88 1.22L10 22l6.41-6.41c.38-.38.59-.89.59-1.42V6.34C17 5.05 15.95 4 14.66 4H6.55c-.7 0-1.36.37-1.72.97l-2.66 6.15z\" />\n </svg>\n)\nexport const cancelSVG = ({ fill = 'currentColor' }: { fill?: string } = {}) => (\n <svg\n width=\"12\"\n height=\"12\"\n viewBox=\"0 0 12 12\"\n fill={fill}\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-labelledby=\"close-survey-title-adam\"\n >\n <title id=\"close-survey-title\" className=\"adam-testing\">\n Close survey\n </title>\n <path\n fill-rule=\"evenodd\"\n clip-rule=\"evenodd\"\n d=\"M0.164752 0.164752C0.384422 -0.0549175 0.740578 -0.0549175 0.960248 0.164752L6 5.20451L11.0398 0.164752C11.2594 -0.0549175 11.6156 -0.0549175 11.8352 0.164752C12.0549 0.384422 12.0549 0.740578 11.8352 0.960248L6.79549 6L11.8352 11.0398C12.0549 11.2594 12.0549 11.6156 11.8352 11.8352C11.6156 12.0549 11.2594 12.0549 11.0398 11.8352L6 6.79549L0.960248 11.8352C0.740578 12.0549 0.384422 12.0549 0.164752 11.8352C-0.0549175 11.6156 -0.0549175 11.2594 0.164752 11.0398L5.20451 6L0.164752 0.960248C-0.0549175 0.740578 -0.0549175 0.384422 0.164752 0.164752Z\"\n fill={fill}\n />\n </svg>\n)\nexport const IconPosthogLogo = (\n <svg width=\"77\" height=\"14\" viewBox=\"0 0 77 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <g clip-path=\"url(#clip0_2415_6911)\">\n <mask\n id=\"mask0_2415_6911\"\n style={{ maskType: 'luminance' }}\n maskUnits=\"userSpaceOnUse\"\n x=\"0\"\n y=\"0\"\n width=\"77\"\n height=\"14\"\n >\n <path d=\"M0.5 0H76.5V14H0.5V0Z\" fill=\"white\" />\n </mask>\n <g mask=\"url(#mask0_2415_6911)\">\n <path\n d=\"M5.77226 8.02931C5.59388 8.37329 5.08474 8.37329 4.90634 8.02931L4.4797 7.20672C4.41155 7.07535 4.41155 6.9207 4.4797 6.78933L4.90634 5.96669C5.08474 5.62276 5.59388 5.62276 5.77226 5.96669L6.19893 6.78933C6.26709 6.9207 6.26709 7.07535 6.19893 7.20672L5.77226 8.02931ZM5.77226 12.6946C5.59388 13.0386 5.08474 13.0386 4.90634 12.6946L4.4797 11.872C4.41155 11.7406 4.41155 11.586 4.4797 11.4546L4.90634 10.632C5.08474 10.288 5.59388 10.288 5.77226 10.632L6.19893 11.4546C6.26709 11.586 6.26709 11.7406 6.19893 11.872L5.77226 12.6946Z\"\n fill=\"#1D4AFF\"\n />\n <path\n d=\"M0.5 10.9238C0.5 10.508 1.02142 10.2998 1.32637 10.5938L3.54508 12.7327C3.85003 13.0267 3.63405 13.5294 3.20279 13.5294H0.984076C0.716728 13.5294 0.5 13.3205 0.5 13.0627V10.9238ZM0.5 8.67083C0.5 8.79459 0.551001 8.91331 0.641783 9.00081L5.19753 13.3927C5.28831 13.4802 5.41144 13.5294 5.53982 13.5294H8.0421C8.47337 13.5294 8.68936 13.0267 8.3844 12.7327L1.32637 5.92856C1.02142 5.63456 0.5 5.84278 0.5 6.25854V8.67083ZM0.5 4.00556C0.5 4.12932 0.551001 4.24802 0.641783 4.33554L10.0368 13.3927C10.1276 13.4802 10.2508 13.5294 10.3791 13.5294H12.8814C13.3127 13.5294 13.5287 13.0267 13.2237 12.7327L1.32637 1.26329C1.02142 0.969312 0.5 1.17752 0.5 1.59327V4.00556ZM5.33931 4.00556C5.33931 4.12932 5.39033 4.24802 5.4811 4.33554L14.1916 12.7327C14.4965 13.0267 15.0179 12.8185 15.0179 12.4028V9.99047C15.0179 9.86671 14.9669 9.74799 14.8762 9.66049L6.16568 1.26329C5.86071 0.969307 5.33931 1.17752 5.33931 1.59327V4.00556ZM11.005 1.26329C10.7 0.969307 10.1786 1.17752 10.1786 1.59327V4.00556C10.1786 4.12932 10.2296 4.24802 10.3204 4.33554L14.1916 8.06748C14.4965 8.36148 15.0179 8.15325 15.0179 7.7375V5.3252C15.0179 5.20144 14.9669 5.08272 14.8762 4.99522L11.005 1.26329Z\"\n fill=\"#F9BD2B\"\n />\n <path\n d=\"M21.0852 10.981L16.5288 6.58843C16.2238 6.29443 15.7024 6.50266 15.7024 6.91841V13.0627C15.7024 13.3205 15.9191 13.5294 16.1865 13.5294H23.2446C23.5119 13.5294 23.7287 13.3205 23.7287 13.0627V12.5032C23.7287 12.2455 23.511 12.0396 23.2459 12.0063C22.4323 11.9042 21.6713 11.546 21.0852 10.981ZM18.0252 12.0365C17.5978 12.0365 17.251 11.7021 17.251 11.2901C17.251 10.878 17.5978 10.5436 18.0252 10.5436C18.4527 10.5436 18.7996 10.878 18.7996 11.2901C18.7996 11.7021 18.4527 12.0365 18.0252 12.0365Z\"\n fill=\"currentColor\"\n />\n <path\n d=\"M0.5 13.0627C0.5 13.3205 0.716728 13.5294 0.984076 13.5294H3.20279C3.63405 13.5294 3.85003 13.0267 3.54508 12.7327L1.32637 10.5938C1.02142 10.2998 0.5 10.508 0.5 10.9238V13.0627ZM5.33931 5.13191L1.32637 1.26329C1.02142 0.969306 0.5 1.17752 0.5 1.59327V4.00556C0.5 4.12932 0.551001 4.24802 0.641783 4.33554L5.33931 8.86412V5.13191ZM1.32637 5.92855C1.02142 5.63455 0.5 5.84278 0.5 6.25853V8.67083C0.5 8.79459 0.551001 8.91331 0.641783 9.00081L5.33931 13.5294V9.79717L1.32637 5.92855Z\"\n fill=\"#1D4AFF\"\n />\n <path\n d=\"M10.1787 5.3252C10.1787 5.20144 10.1277 5.08272 10.0369 4.99522L6.16572 1.26329C5.8608 0.969306 5.33936 1.17752 5.33936 1.59327V4.00556C5.33936 4.12932 5.39037 4.24802 5.48114 4.33554L10.1787 8.86412V5.3252ZM5.33936 13.5294H8.04214C8.47341 13.5294 8.6894 13.0267 8.38443 12.7327L5.33936 9.79717V13.5294ZM5.33936 5.13191V8.67083C5.33936 8.79459 5.39037 8.91331 5.48114 9.00081L10.1787 13.5294V9.99047C10.1787 9.86671 10.1277 9.74803 10.0369 9.66049L5.33936 5.13191Z\"\n fill=\"#F54E00\"\n />\n <path\n d=\"M29.375 11.6667H31.3636V8.48772H33.0249C34.8499 8.48772 36.0204 7.4443 36.0204 5.83052C36.0204 4.21681 34.8499 3.17334 33.0249 3.17334H29.375V11.6667ZM31.3636 6.84972V4.81136H32.8236C33.5787 4.81136 34.0318 5.19958 34.0318 5.83052C34.0318 6.4615 33.5787 6.84972 32.8236 6.84972H31.3636ZM39.618 11.7637C41.5563 11.7637 42.9659 10.429 42.9659 8.60905C42.9659 6.78905 41.5563 5.45438 39.618 5.45438C37.6546 5.45438 36.2701 6.78905 36.2701 8.60905C36.2701 10.429 37.6546 11.7637 39.618 11.7637ZM38.1077 8.60905C38.1077 7.63838 38.7118 6.97105 39.618 6.97105C40.5116 6.97105 41.1157 7.63838 41.1157 8.60905C41.1157 9.57972 40.5116 10.2471 39.618 10.2471C38.7118 10.2471 38.1077 9.57972 38.1077 8.60905ZM46.1482 11.7637C47.6333 11.7637 48.6402 10.8658 48.6402 9.81025C48.6402 7.33505 45.2294 8.13585 45.2294 7.16518C45.2294 6.8983 45.5189 6.72843 45.9342 6.72843C46.3622 6.72843 46.8782 6.98318 47.0418 7.54132L48.527 6.94678C48.2375 6.06105 47.1677 5.45438 45.8713 5.45438C44.4743 5.45438 43.6058 6.25518 43.6058 7.21372C43.6058 9.53118 46.9663 8.88812 46.9663 9.84665C46.9663 10.1864 46.6391 10.417 46.1482 10.417C45.4434 10.417 44.9525 9.94376 44.8015 9.3735L43.3164 9.93158C43.6436 10.8537 44.6001 11.7637 46.1482 11.7637ZM53.4241 11.606L53.2982 10.0651C53.0843 10.1743 52.8074 10.2106 52.5808 10.2106C52.1278 10.2106 51.8257 9.89523 51.8257 9.34918V7.03172H53.3612V5.55145H51.8257V3.78001H49.9755V5.55145H48.9687V7.03172H49.9755V9.57972C49.9755 11.06 51.0202 11.7637 52.3921 11.7637C52.7696 11.7637 53.122 11.7031 53.4241 11.606ZM59.8749 3.17334V6.47358H56.376V3.17334H54.3874V11.6667H56.376V8.11158H59.8749V11.6667H61.8761V3.17334H59.8749ZM66.2899 11.7637C68.2281 11.7637 69.6378 10.429 69.6378 8.60905C69.6378 6.78905 68.2281 5.45438 66.2899 5.45438C64.3265 5.45438 62.942 6.78905 62.942 8.60905C62.942 10.429 64.3265 11.7637 66.2899 11.7637ZM64.7796 8.60905C64.7796 7.63838 65.3837 6.97105 66.2899 6.97105C67.1835 6.97105 67.7876 7.63838 67.7876 8.60905C67.7876 9.57972 67.1835 10.2471 66.2899 10.2471C65.3837 10.2471 64.7796 9.57972 64.7796 8.60905ZM73.2088 11.4725C73.901 11.4725 74.5177 11.242 74.845 10.8416V11.424C74.845 12.1034 74.2786 12.5767 73.4102 12.5767C72.7935 12.5767 72.2523 12.2854 72.1642 11.788L70.4776 12.0428C70.7042 13.1955 71.925 13.972 73.4102 13.972C75.361 13.972 76.6574 12.8679 76.6574 11.2298V5.55145H74.8324V6.07318C74.4926 5.69705 73.9136 5.45438 73.171 5.45438C71.409 5.45438 70.3014 6.61918 70.3014 8.46345C70.3014 10.3077 71.409 11.4725 73.2088 11.4725ZM72.1012 8.46345C72.1012 7.55345 72.655 6.97105 73.5109 6.97105C74.3793 6.97105 74.9331 7.55345 74.9331 8.46345C74.9331 9.37345 74.3793 9.95585 73.5109 9.95585C72.655 9.95585 72.1012 9.37345 72.1012 8.46345Z\"\n fill=\"currentColor\"\n />\n </g>\n </g>\n <defs>\n <clipPath id=\"clip0_2415_6911\">\n <rect width=\"76\" height=\"14\" fill=\"white\" transform=\"translate(0.5)\" />\n </clipPath>\n </defs>\n </svg>\n)\nexport const checkSVG = (\n <svg width=\"16\" height=\"12\" viewBox=\"0 0 16 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M5.30769 10.6923L4.77736 11.2226C4.91801 11.3633 5.10878 11.4423 5.30769 11.4423C5.5066 11.4423 5.69737 11.3633 5.83802 11.2226L5.30769 10.6923ZM15.5303 1.53033C15.8232 1.23744 15.8232 0.762563 15.5303 0.46967C15.2374 0.176777 14.7626 0.176777 14.4697 0.46967L15.5303 1.53033ZM1.53033 5.85429C1.23744 5.56139 0.762563 5.56139 0.46967 5.85429C0.176777 6.14718 0.176777 6.62205 0.46967 6.91495L1.53033 5.85429ZM5.83802 11.2226L15.5303 1.53033L14.4697 0.46967L4.77736 10.162L5.83802 11.2226ZM0.46967 6.91495L4.77736 11.2226L5.83802 10.162L1.53033 5.85429L0.46967 6.91495Z\"\n fill=\"currentColor\"\n />\n </svg>\n)\n","import { IconPosthogLogo } from '../icons'\n\ninterface PostHogLogoProps {\n urlParams?: Record<string, string>\n}\n\nexport function PostHogLogo({ urlParams }: PostHogLogoProps) {\n // Manual query string building for IE11/op_mini compatibility (no URLSearchParams)\n const queryString = urlParams\n ? Object.entries(urlParams)\n .map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`)\n .join('&')\n : ''\n\n return (\n <a\n href={`https://posthog.com/surveys${queryString ? `?${queryString}` : ''}`}\n target=\"_blank\"\n rel=\"noopener\"\n className=\"footer-branding\"\n >\n Survey by {IconPosthogLogo}\n </a>\n )\n}\n","import { window } from '../../../utils/globals'\n\nimport { SurveyAppearance } from '../../../posthog-surveys-types'\n\nimport { useContext } from 'preact/hooks'\nimport { SurveyContext } from '../surveys-extension-utils'\nimport { PostHogLogo } from './PostHogLogo'\n\nexport function BottomSection({\n text,\n submitDisabled,\n appearance,\n onSubmit,\n link,\n onPreviewSubmit,\n skipSubmitButton,\n canGoBack,\n onBack,\n}: {\n text: string\n submitDisabled: boolean\n appearance: SurveyAppearance\n onSubmit: () => void\n link?: string | null\n onPreviewSubmit?: () => void\n skipSubmitButton?: boolean\n canGoBack?: boolean\n onBack?: () => void\n}) {\n const { isPreviewMode } = useContext(SurveyContext)\n const showBackButton = !!canGoBack && !!onBack\n const submitButton = !skipSubmitButton && (\n <button\n className=\"form-submit\"\n disabled={submitDisabled}\n aria-label=\"Submit survey\"\n type=\"button\"\n onClick={() => {\n if (link) {\n window?.open(link)\n }\n if (isPreviewMode) {\n onPreviewSubmit?.()\n } else {\n onSubmit()\n }\n }}\n >\n {text}\n </button>\n )\n return (\n <div className=\"bottom-section\">\n {showBackButton ? (\n <div className=\"form-buttons form-buttons-with-back\">\n <button className=\"form-back\" type=\"button\" aria-label=\"Go to previous question\" onClick={onBack}>\n {appearance.backButtonText || 'Back'}\n </button>\n {submitButton}\n </div>\n ) : (\n submitButton\n )}\n {!appearance.whiteLabel && <PostHogLogo urlParams={{ utm_source: 'survey-footer' }} />}\n </div>\n )\n}\n","import { h } from 'preact'\nimport { useContext } from 'preact/hooks'\nimport { SurveyQuestion, SurveyQuestionType } from '../../../posthog-surveys-types'\nimport { cancelSVG } from '../icons'\nimport { SurveyContext, renderChildrenAsTextOrHtml } from '../surveys-extension-utils'\n\nexport function QuestionHeader({\n question,\n forceDisableHtml,\n htmlFor,\n}: {\n question: Pick<SurveyQuestion, 'question' | 'description' | 'descriptionContentType' | 'type'>\n forceDisableHtml: boolean\n htmlFor?: string\n}) {\n const TitleComponent = question.type === SurveyQuestionType.Open ? 'label' : 'h3'\n // Flag an empty header in JS rather than via :has(.survey-question:empty) in CSS,\n // which crashes some WebKit builds during text-node style invalidation.\n const isHeaderEmpty = !question.question && !question.description\n return (\n <div class={isHeaderEmpty ? 'question-header question-header--empty' : 'question-header'}>\n <TitleComponent className=\"survey-question\" htmlFor={htmlFor}>\n {question.question}\n </TitleComponent>\n {question.description &&\n renderChildrenAsTextOrHtml({\n component: h('p', { className: 'survey-question-description' }),\n children: question.description,\n renderAsHtml: !forceDisableHtml && question.descriptionContentType !== 'text',\n })}\n </div>\n )\n}\n\nexport function Cancel({ onClick }: { onClick: () => void }) {\n const { isPreviewMode } = useContext(SurveyContext)\n\n return (\n <button\n className=\"form-cancel\"\n onClick={onClick}\n disabled={isPreviewMode}\n aria-label=\"Close survey\"\n type=\"button\"\n >\n {cancelSVG({ fill: 'black' })}\n </button>\n )\n}\n","import { h } from 'preact'\nimport { SurveyAppearance, SurveyQuestionDescriptionContentType } from '../../../posthog-surveys-types'\nimport { renderChildrenAsTextOrHtml } from '../surveys-extension-utils'\nimport { BottomSection } from './BottomSection'\nimport { Cancel } from './QuestionHeader'\n\nimport { useContext, useEffect } from 'preact/hooks'\nimport { SurveyContext } from '../surveys-extension-utils'\nimport { addEventListener } from '../../../utils'\nimport { window as _window } from '../../../utils/globals'\n\n// We cast the types here which is dangerous but protected by the top level generateSurveys call\nconst window = _window as Window\n\nexport function ConfirmationMessage({\n header,\n description,\n contentType,\n forceDisableHtml,\n appearance,\n onClose,\n}: {\n header: string\n description: string\n forceDisableHtml: boolean\n contentType?: SurveyQuestionDescriptionContentType\n appearance: SurveyAppearance\n onClose: () => void\n}) {\n const { isPopup } = useContext(SurveyContext)\n\n useEffect(() => {\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === 'Enter' || event.key === 'Escape') {\n event.preventDefault()\n onClose()\n }\n }\n addEventListener(window, 'keydown', handleKeyDown as EventListener)\n return () => {\n window.removeEventListener('keydown', handleKeyDown)\n }\n }, [onClose])\n\n const renderCancelButton = isPopup && appearance.hideCancelButton !== true\n\n return (\n <div className=\"thank-you-message\" role=\"status\" tabIndex={0} aria-atomic=\"true\">\n {renderCancelButton && <Cancel onClick={() => onClose()} />}\n <h3 className=\"thank-you-message-header\">{header}</h3>\n {description &&\n renderChildrenAsTextOrHtml({\n component: h('p', { className: 'thank-you-message-body' }),\n children: description,\n renderAsHtml: !forceDisableHtml && contentType !== 'text',\n })}\n {isPopup && (\n <BottomSection\n text={appearance.thankYouMessageCloseButtonText || 'Close'}\n submitDisabled={false}\n appearance={appearance}\n onSubmit={() => onClose()}\n />\n )}\n </div>\n )\n}\n","import { Fragment, type JSX } from 'preact'\nimport { useEffect, useMemo, useRef, useState } from 'preact/hooks'\nimport {\n BasicSurveyQuestion,\n LinkSurveyQuestion,\n MultipleSurveyQuestion,\n RatingSurveyQuestion,\n SurveyAppearance,\n SurveyQuestionType,\n} from '../../../posthog-surveys-types'\nimport { isArray, isNull, isNumber, isString, SurveyValidationType } from '@posthog/core'\nimport { getValidationError, getLengthFromRules, getRequirementsHint } from '@posthog/core/surveys'\nimport {\n dissatisfiedEmoji,\n neutralEmoji,\n satisfiedEmoji,\n thumbsDownEmoji,\n thumbsUpEmoji,\n veryDissatisfiedEmoji,\n verySatisfiedEmoji,\n} from '../icons'\nimport { getDisplayOrderChoices, useSurveyContext } from '../surveys-extension-utils'\nimport { BottomSection } from './BottomSection'\nimport { QuestionHeader } from './QuestionHeader'\n\nexport interface CommonQuestionProps {\n forceDisableHtml: boolean\n appearance: SurveyAppearance\n onSubmit: (res: string | string[] | number | null) => void\n onPreviewSubmit: (res: string | string[] | number | null) => void\n initialValue?: string | string[] | number | null\n displayQuestionIndex: number\n canGoBack?: boolean\n onBack?: () => void\n}\n\ninterface OpenEndedInputState {\n isSelected: boolean\n inputValue: string\n}\n\nconst isValidStringArray = (value: unknown): value is string[] => {\n return isArray(value) && value.every((item) => isString(item))\n}\n\nconst initializeSelectedChoices = (\n initialValue: string | string[] | number | null | undefined,\n questionType: SurveyQuestionType\n): string | string[] | null => {\n if (isString(initialValue)) {\n return initialValue\n }\n if (isValidStringArray(initialValue)) {\n return initialValue\n }\n return questionType === SurveyQuestionType.SingleChoice ? null : []\n}\n\nconst initializeOpenEndedState = (\n initialValue: string | string[] | number | null | undefined,\n choices: string[]\n): OpenEndedInputState => {\n if (isString(initialValue) && !choices.includes(initialValue)) {\n return {\n isSelected: true,\n inputValue: initialValue,\n }\n }\n if (isValidStringArray(initialValue)) {\n const openEndedValue = initialValue.find((choice) => !choices.includes(choice))\n if (openEndedValue) {\n return {\n isSelected: true,\n inputValue: openEndedValue,\n }\n }\n }\n return {\n isSelected: false,\n inputValue: '',\n }\n}\n\nexport function OpenTextQuestion({\n question,\n forceDisableHtml,\n appearance,\n onSubmit,\n onPreviewSubmit,\n displayQuestionIndex,\n initialValue,\n canGoBack,\n onBack,\n}: CommonQuestionProps & {\n question: BasicSurveyQuestion\n}) {\n const { isPreviewMode } = useSurveyContext()\n const inputRef = useRef<HTMLTextAreaElement>(null)\n const [text, setText] = useState<string>(() => {\n if (isString(initialValue)) {\n return initialValue\n }\n return ''\n })\n useEffect(() => {\n setTimeout(() => {\n if (!isPreviewMode) {\n inputRef.current?.focus()\n }\n }, 100)\n }, [isPreviewMode])\n\n const htmlFor = `surveyQuestion${displayQuestionIndex}`\n\n // Validation logic\n const validationError = useMemo(() => {\n return getValidationError(text, question.validation, question.optional)\n }, [text, question.validation, question.optional])\n\n // Build requirements hint message\n const minLength = getLengthFromRules(question.validation, SurveyValidationType.MinLength)\n const maxLength = getLengthFromRules(question.validation, SurveyValidationType.MaxLength)\n const requirementsHint = useMemo(() => getRequirementsHint(minLength, maxLength), [minLength, maxLength])\n\n const handleSubmit = () => {\n if (validationError) {\n return\n }\n onSubmit(text.trim())\n }\n\n const handlePreviewSubmit = () => {\n if (validationError) {\n return\n }\n onPreviewSubmit(text.trim())\n }\n\n return (\n <Fragment>\n <div className=\"question-container\">\n <QuestionHeader question={question} forceDisableHtml={forceDisableHtml} htmlFor={htmlFor} />\n <textarea\n ref={inputRef}\n id={htmlFor}\n rows={4}\n placeholder={appearance?.placeholder}\n minLength={minLength}\n maxLength={maxLength}\n onInput={(e) => {\n setText(e.currentTarget.value)\n e.stopPropagation()\n }}\n onKeyDown={(e) => {\n e.stopPropagation()\n if (e.key === 'Enter' && (e.metaKey || e.ctrlKey) && !validationError) {\n e.preventDefault()\n isPreviewMode ? handlePreviewSubmit() : handleSubmit()\n }\n }}\n value={text}\n />\n {requirementsHint && <div className=\"validation-hint\">{requirementsHint}</div>}\n </div>\n <BottomSection\n text={question.buttonText || 'Submit'}\n submitDisabled={!!validationError}\n appearance={appearance}\n onSubmit={handleSubmit}\n onPreviewSubmit={handlePreviewSubmit}\n canGoBack={canGoBack}\n onBack={onBack}\n />\n </Fragment>\n )\n}\n\nexport function LinkQuestion({\n question,\n forceDisableHtml,\n appearance,\n onSubmit,\n onPreviewSubmit,\n canGoBack,\n onBack,\n}: CommonQuestionProps & {\n question: LinkSurveyQuestion\n}) {\n return (\n <Fragment>\n <div className=\"question-container\">\n <QuestionHeader question={question} forceDisableHtml={forceDisableHtml} />\n </div>\n <BottomSection\n text={question.buttonText || 'Submit'}\n submitDisabled={false}\n link={question.link}\n appearance={appearance}\n onSubmit={() => onSubmit('link clicked')}\n onPreviewSubmit={() => onPreviewSubmit('link clicked')}\n canGoBack={canGoBack}\n onBack={onBack}\n />\n </Fragment>\n )\n}\n\nexport function RatingQuestion({\n question,\n forceDisableHtml,\n displayQuestionIndex,\n appearance,\n onSubmit,\n onPreviewSubmit,\n initialValue,\n canGoBack,\n onBack,\n}: CommonQuestionProps & {\n question: RatingSurveyQuestion\n}) {\n const scale = question.scale\n const starting = question.scale === 10 ? 0 : 1\n const [rating, setRating] = useState<number | null>(() => {\n if (isNumber(initialValue)) {\n return initialValue\n }\n if (isArray(initialValue) && initialValue.length > 0 && isNumber(parseInt(initialValue[0]))) {\n return parseInt(initialValue[0])\n }\n if (isString(initialValue) && isNumber(parseInt(initialValue))) {\n return parseInt(initialValue)\n }\n return null\n })\n\n const isThumbSurvey = question.display === 'emoji' && question.scale === 2\n\n const { isPreviewMode } = useSurveyContext()\n\n const handleSubmit = (num: number) => {\n if (isPreviewMode) {\n return onPreviewSubmit(num)\n }\n return onSubmit(num)\n }\n\n return (\n <Fragment>\n <div className=\"question-container\">\n <QuestionHeader question={question} forceDisableHtml={forceDisableHtml} />\n <div className=\"rating-section\">\n <div className=\"rating-options\">\n {question.display === 'emoji' && (\n <div className={`rating-options-emoji${isThumbSurvey ? ' rating-options-emoji-2' : ''}`}>\n {emojiScaleLists[question.scale]?.map((emoji, idx) => {\n const active = idx + 1 === rating\n return (\n <button\n aria-label={`Rate ${idx + 1}`}\n className={`ratings-emoji question-${displayQuestionIndex}-rating-${idx} ${\n active ? 'rating-active' : ''\n }`}\n value={idx + 1}\n key={idx}\n type=\"button\"\n onClick={() => {\n const response = idx + 1\n setRating(response)\n if (question.skipSubmitButton) {\n handleSubmit(response)\n }\n }}\n >\n {emoji}\n </button>\n )\n })}\n </div>\n )}\n {question.display === 'number' && (\n <div\n className=\"rating-options-number\"\n style={{ gridTemplateColumns: `repeat(${scale - starting + 1}, minmax(0, 1fr))` }}\n >\n {getScaleNumbers(question.scale).map((number, idx) => {\n const active = rating === number\n return (\n <RatingButton\n key={idx}\n displayQuestionIndex={displayQuestionIndex}\n active={active}\n appearance={appearance}\n num={number}\n setActiveNumber={(response) => {\n setRating(response)\n if (question.skipSubmitButton) {\n handleSubmit(response)\n }\n }}\n />\n )\n })}\n </div>\n )}\n </div>\n {!isThumbSurvey && (\n <div className=\"rating-text\">\n <div>{question.lowerBoundLabel}</div>\n <div>{question.upperBoundLabel}</div>\n </div>\n )}\n </div>\n </div>\n <BottomSection\n text={question.buttonText || appearance?.submitButtonText || 'Submit'}\n submitDisabled={isNull(rating) && !question.optional}\n appearance={appearance}\n onSubmit={() => onSubmit(rating)}\n onPreviewSubmit={() => onPreviewSubmit(rating)}\n skipSubmitButton={question.skipSubmitButton}\n canGoBack={canGoBack}\n onBack={onBack}\n />\n </Fragment>\n )\n}\n\nexport function RatingButton({\n num,\n active,\n displayQuestionIndex,\n setActiveNumber,\n}: {\n num: number\n active: boolean\n displayQuestionIndex: number\n appearance: SurveyAppearance\n setActiveNumber: (num: number) => void\n}) {\n return (\n <button\n aria-label={`Rate ${num}`}\n className={`ratings-number question-${displayQuestionIndex}-rating-${num} ${active ? 'rating-active' : ''}`}\n type=\"button\"\n onClick={() => {\n setActiveNumber(num)\n }}\n >\n {num}\n </button>\n )\n}\n\nexport function MultipleChoiceQuestion({\n question,\n forceDisableHtml,\n displayQuestionIndex,\n appearance,\n onSubmit,\n onPreviewSubmit,\n initialValue,\n canGoBack,\n onBack,\n}: CommonQuestionProps & {\n question: MultipleSurveyQuestion\n}) {\n const openChoiceInputRef = useRef<HTMLInputElement>(null)\n const choices = useMemo(() => getDisplayOrderChoices(question), [question])\n const [selectedChoices, setSelectedChoices] = useState<string | string[] | null>(() =>\n initializeSelectedChoices(initialValue, question.type)\n )\n const [openEndedState, setOpenEndedState] = useState<OpenEndedInputState>(() =>\n initializeOpenEndedState(initialValue, choices)\n )\n\n const { isPreviewMode } = useSurveyContext()\n\n const isSingleChoiceQuestion = question.type === SurveyQuestionType.SingleChoice\n const isMultipleChoiceQuestion = question.type === SurveyQuestionType.MultipleChoice\n\n const shouldSkipSubmit = question.skipSubmitButton && isSingleChoiceQuestion && !question.hasOpenChoice\n\n const handleChoiceChange = (val: string, isOpenChoice: boolean) => {\n if (isOpenChoice) {\n const newOpenSelected = !openEndedState.isSelected\n setOpenEndedState((prev) => ({\n ...prev,\n isSelected: newOpenSelected,\n inputValue: newOpenSelected ? prev.inputValue : '',\n }))\n\n if (isSingleChoiceQuestion) {\n setSelectedChoices('')\n }\n\n // Focus the input when open choice is selected, slight delay because of the animation\n if (newOpenSelected) {\n setTimeout(() => openChoiceInputRef.current?.focus(), 75)\n }\n return\n }\n\n if (isSingleChoiceQuestion) {\n setSelectedChoices(val)\n // Deselect open choice when selecting another option\n setOpenEndedState((prev) => ({\n ...prev,\n isSelected: false,\n inputValue: '',\n }))\n\n if (shouldSkipSubmit) {\n onSubmit(val)\n if (isPreviewMode) {\n onPreviewSubmit(val)\n }\n }\n return\n }\n\n if (isMultipleChoiceQuestion && isArray(selectedChoices)) {\n if (selectedChoices.includes(val)) {\n setSelectedChoices(selectedChoices.filter((choice) => choice !== val))\n } else {\n setSelectedChoices([...selectedChoices, val])\n }\n }\n }\n\n const handleOpenEndedInputChange = (e: JSX.TargetedEvent<HTMLInputElement>) => {\n e.stopPropagation()\n const newValue = e.currentTarget.value\n\n setOpenEndedState((prev) => ({\n ...prev,\n inputValue: newValue,\n }))\n\n if (isSingleChoiceQuestion) {\n setSelectedChoices(newValue)\n }\n }\n\n const handleOpenEndedKeyDown = (e: JSX.TargetedKeyboardEvent<HTMLInputElement>) => {\n e.stopPropagation()\n\n // Handle Enter key to submit form if valid\n if (e.key === 'Enter' && !isSubmitDisabled()) {\n e.preventDefault()\n handleSubmit()\n }\n\n // Handle Escape key to clear input and deselect\n if (e.key === 'Escape') {\n e.preventDefault()\n setOpenEndedState((prev) => ({\n ...prev,\n isSelected: false,\n inputValue: '',\n }))\n if (isSingleChoiceQuestion) {\n setSelectedChoices(null)\n }\n }\n }\n\n const isSubmitDisabled = (): boolean => {\n if (question.optional) {\n return false\n }\n if (isNull(selectedChoices)) {\n return true\n }\n if (isArray(selectedChoices)) {\n if (!openEndedState.isSelected && selectedChoices.length === 0) {\n return true\n }\n }\n if (openEndedState.isSelected && openEndedState.inputValue.trim() === '') {\n return true\n }\n return false\n }\n\n const handleSubmit = () => {\n if (openEndedState.isSelected && isMultipleChoiceQuestion) {\n if (isArray(selectedChoices)) {\n isPreviewMode\n ? onPreviewSubmit([...selectedChoices, openEndedState.inputValue])\n : onSubmit([...selectedChoices, openEndedState.inputValue])\n }\n } else {\n isPreviewMode ? onPreviewSubmit(selectedChoices) : onSubmit(selectedChoices)\n }\n }\n\n return (\n <Fragment>\n <div className=\"question-container\">\n <QuestionHeader question={question} forceDisableHtml={forceDisableHtml} />\n <fieldset className=\"multiple-choice-options limit-height\">\n <legend className=\"sr-only\">\n {isMultipleChoiceQuestion ? ' Select all that apply' : ' Select one'}\n </legend>\n {choices.map((choice: string, idx: number) => {\n const isOpenChoice = !!question.hasOpenChoice && idx === question.choices.length - 1\n const inputId = `surveyQuestion${displayQuestionIndex}Choice${idx}`\n const openInputId = `${inputId}Open`\n\n const isChecked = isOpenChoice\n ? openEndedState.isSelected\n : isSingleChoiceQuestion\n ? selectedChoices === choice\n : isArray(selectedChoices) && selectedChoices.includes(choice)\n\n return (\n <label className={isOpenChoice ? 'choice-option-open' : ''} key={idx}>\n <div className=\"response-choice\">\n <input\n type={isSingleChoiceQuestion ? 'radio' : 'checkbox'}\n name={inputId}\n checked={isChecked}\n onChange={() => handleChoiceChange(choice, isOpenChoice)}\n id={inputId}\n aria-controls={openInputId}\n />\n <span>{isOpenChoice ? `${choice}:` : choice}</span>\n </div>\n {isOpenChoice && (\n <input\n type=\"text\"\n ref={openChoiceInputRef}\n id={openInputId}\n name={`question${displayQuestionIndex}Open`}\n value={openEndedState.inputValue}\n onKeyDown={handleOpenEndedKeyDown}\n onInput={handleOpenEndedInputChange}\n onClick={(e) => {\n // Ensure the checkbox/radio gets checked when clicking the input\n if (!openEndedState.isSelected) {\n handleChoiceChange(choice, true)\n }\n e.stopPropagation()\n }}\n aria-label={`${choice} - please specify`}\n />\n )}\n </label>\n )\n })}\n </fieldset>\n </div>\n <BottomSection\n text={question.buttonText || 'Submit'}\n submitDisabled={isSubmitDisabled()}\n appearance={appearance}\n onSubmit={handleSubmit}\n onPreviewSubmit={handleSubmit}\n skipSubmitButton={shouldSkipSubmit}\n canGoBack={canGoBack}\n onBack={onBack}\n />\n </Fragment>\n )\n}\n\nconst fiveScaleNumbers = [1, 2, 3, 4, 5]\nconst sevenScaleNumbers = [1, 2, 3, 4, 5, 6, 7]\nconst tenScaleNumbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\n\nconst emojiScaleLists: Partial<Record<RatingSurveyQuestion['scale'], JSX.Element[]>> = {\n 2: [thumbsUpEmoji, thumbsDownEmoji],\n 3: [dissatisfiedEmoji, neutralEmoji, satisfiedEmoji],\n 5: [veryDissatisfiedEmoji, dissatisfiedEmoji, neutralEmoji, satisfiedEmoji, verySatisfiedEmoji],\n}\n\nfunction getScaleNumbers(scale: number): number[] {\n switch (scale) {\n case 5:\n return fiveScaleNumbers\n case 7:\n return sevenScaleNumbers\n case 10:\n return tenScaleNumbers\n default:\n return fiveScaleNumbers\n }\n}\n","import { Survey, SurveyQuestionBranchingType, SurveyQuestionType } from '../posthog-surveys-types'\nimport { createLogger } from './logger'\n\nconst logger = createLogger('[Surveys]')\n\n/**\n * Get the rating bucket (detractors/passives/promoters or negative/neutral/positive)\n * based on the response value and scale.\n */\nexport function getRatingBucketForResponseValue(responseValue: number, scale: number): string {\n if (scale === 2) {\n if (responseValue < 1 || responseValue > 2) {\n throw new Error('The response must be in range 1-2')\n }\n return responseValue === 1 ? 'positive' : 'negative'\n } else if (scale === 3) {\n if (responseValue < 1 || responseValue > 3) {\n throw new Error('The response must be in range 1-3')\n }\n\n return responseValue === 1 ? 'negative' : responseValue === 2 ? 'neutral' : 'positive'\n } else if (scale === 5) {\n if (responseValue < 1 || responseValue > 5) {\n throw new Error('The response must be in range 1-5')\n }\n\n return responseValue <= 2 ? 'negative' : responseValue === 3 ? 'neutral' : 'positive'\n } else if (scale === 7) {\n if (responseValue < 1 || responseValue > 7) {\n throw new Error('The response must be in range 1-7')\n }\n\n return responseValue <= 3 ? 'negative' : responseValue === 4 ? 'neutral' : 'positive'\n } else if (scale === 10) {\n if (responseValue < 0 || responseValue > 10) {\n throw new Error('The response must be in range 0-10')\n }\n\n return responseValue <= 6 ? 'detractors' : responseValue <= 8 ? 'passives' : 'promoters'\n }\n\n throw new Error('The scale must be one of: 2, 3, 5, 7, 10')\n}\n\n/**\n * Determine the next survey step based on branching configuration.\n * Returns the next question index, or SurveyQuestionBranchingType.End if the survey should end.\n */\nexport function getNextSurveyStep(\n survey: Survey,\n currentQuestionIndex: number,\n response: string | string[] | number | null\n): number | typeof SurveyQuestionBranchingType.End {\n const question = survey.questions[currentQuestionIndex]\n const nextQuestionIndex = currentQuestionIndex + 1\n\n if (!question.branching?.type) {\n if (currentQuestionIndex === survey.questions.length - 1) {\n return SurveyQuestionBranchingType.End\n }\n\n return nextQuestionIndex\n }\n\n if (question.branching.type === SurveyQuestionBranchingType.End) {\n return SurveyQuestionBranchingType.End\n } else if (question.branching.type === SurveyQuestionBranchingType.SpecificQuestion) {\n if (Number.isInteger(question.branching.index)) {\n return question.branching.index\n }\n } else if (question.branching.type === SurveyQuestionBranchingType.ResponseBased) {\n // Single choice\n if (question.type === SurveyQuestionType.SingleChoice) {\n // KLUDGE: for now, look up the choiceIndex based on the response\n // TODO: once QuestionTypes.MultipleChoiceQuestion is refactored, pass the selected choiceIndex into this method\n let selectedChoiceIndex = question.choices.indexOf(`${response}`)\n\n if (selectedChoiceIndex === -1 && question.hasOpenChoice) {\n // if the response is not found in the choices, it must be the open choice,\n // which is always the last choice\n selectedChoiceIndex = question.choices.length - 1\n }\n\n if (question.branching?.responseValues?.hasOwnProperty(selectedChoiceIndex)) {\n const nextStep = question.branching.responseValues[selectedChoiceIndex]\n\n // Specific question\n if (Number.isInteger(nextStep)) {\n return nextStep\n }\n\n if (nextStep === SurveyQuestionBranchingType.End) {\n return SurveyQuestionBranchingType.End\n }\n\n return nextQuestionIndex\n }\n } else if (question.type === SurveyQuestionType.Rating) {\n if (typeof response !== 'number' || !Number.isInteger(response)) {\n throw new Error('The response type must be an integer')\n }\n\n const ratingBucket = getRatingBucketForResponseValue(response, question.scale)\n\n if (question.branching?.responseValues?.hasOwnProperty(ratingBucket)) {\n const nextStep = question.branching.responseValues[ratingBucket]\n\n // Specific question\n if (Number.isInteger(nextStep)) {\n return nextStep\n }\n\n if (nextStep === SurveyQuestionBranchingType.End) {\n return SurveyQuestionBranchingType.End\n }\n\n return nextQuestionIndex\n }\n }\n\n return nextQuestionIndex\n }\n\n logger.warn('Falling back to next question index due to unexpected branching type')\n return nextQuestionIndex\n}\n","import { PostHog } from '../posthog-core'\nimport { Survey } from '../posthog-surveys-types'\nimport { STORED_PERSON_PROPERTIES_KEY } from '../constants'\nimport { createLogger } from './logger'\nimport { getBrowserLanguage } from './event-utils'\nimport { isFunction } from '@posthog/core'\nimport { applySurveyTranslation, detectSurveyLanguage } from '@posthog/core/surveys'\n\nconst logger = createLogger('[SurveyTranslations]')\n\n/**\n * Detects the user's language using priority order:\n * 1. config.override_display_language (explicit override)\n * 2. person properties 'language' (allows programmatic control via posthog.identify())\n * 3. navigator.language (browser language)\n *\n * TODO: Consider adding dynamic language change detection in the future:\n * - Listen to 'languagechange' event on window (https://developer.mozilla.org/en-US/docs/Web/API/Window/languagechange_event)\n * - Listen to config changes (once we add config change events to PostHog core)\n * - Re-render survey when language changes mid-session\n *\n * @param instance - PostHog instance to retrieve config and person properties\n * @returns The detected language code (e.g., 'fr', 'es', 'en-US') or null if not found\n */\nexport function detectUserLanguage(instance: PostHog): string | null {\n return detectSurveyLanguage(\n {\n overrideLanguage: instance.config.override_display_language,\n storedPersonProperties: isFunction(instance.get_property)\n ? instance.get_property(STORED_PERSON_PROPERTIES_KEY)\n : undefined,\n locale: getBrowserLanguage(),\n },\n logger\n )\n}\n\n/**\n * Applies translations to a survey based on the user's language from person properties\n * @param survey - The original survey object\n * @param instance - PostHog instance to retrieve person properties\n * @returns An object containing the translated survey and the language used (or null if no translation applied)\n */\nexport function applySurveyTranslationForUser(\n survey: Survey,\n instance: PostHog\n): { survey: Survey; language: string | null } {\n const userLanguage = detectUserLanguage(instance)\n\n if (!userLanguage) {\n logger.info('No user language detected')\n return { survey, language: null }\n }\n\n const result = applySurveyTranslation(survey, userLanguage, logger)\n\n return {\n survey: result.survey,\n language: result.matchedKey,\n }\n}\n","import { convertToURL, getQueryParam, maskQueryParams } from './request-utils'\nimport { isNull, stripLeadingDollar, stripUrlHash } from '@posthog/core'\nimport { Properties } from '../types'\nimport Config from '../config'\nimport { SDK_DIST_CHANNEL } from '../constants'\nimport { each, extend, stripEmptyProperties } from './index'\nimport { document, location, userAgent, window } from './globals'\nimport {\n BrowserDetectionHints,\n detectBrowser,\n detectBrowserVersion,\n detectDevice,\n detectDeviceType,\n detectOS,\n} from '@posthog/core'\nimport { cookieStore } from '../storage'\n\nconst URL_REGEX_PREFIX = 'https?://(.*)'\n\n// CAMPAIGN_PARAMS and EVENT_TO_PERSON_PROPERTIES should be kept in sync with\n// https://github.com/PostHog/posthog/blob/master/plugin-server/src/utils/db/utils.ts#L60\n\n// The list of campaign parameters that could be considered personal data under e.g. GDPR.\n// These can be masked in URLs and properties before being sent to posthog.\nexport const PERSONAL_DATA_CAMPAIGN_PARAMS = [\n 'gclid', // google ads\n 'gclsrc', // google ads 360\n 'dclid', // google display ads\n 'gbraid', // google ads, web to app\n 'wbraid', // google ads, app to web\n 'fbclid', // facebook\n 'msclkid', // microsoft\n 'twclid', // twitter\n 'li_fat_id', // linkedin\n 'igshid', // instagram\n 'ttclid', // tiktok\n 'rdt_cid', // reddit\n 'epik', // pinterest\n 'qclid', // quora\n 'sccid', // snapchat\n 'irclid', // impact\n '_kx', // klaviyo\n]\n\nexport const CAMPAIGN_PARAMS = [\n 'utm_source',\n 'utm_medium',\n 'utm_campaign',\n 'utm_content',\n 'utm_term',\n 'gad_source', // google ads source\n 'mc_cid', // mailchimp campaign id\n ...PERSONAL_DATA_CAMPAIGN_PARAMS,\n]\n\nexport const EVENT_TO_PERSON_PROPERTIES = [\n // mobile params\n '$app_build',\n '$app_name',\n '$app_namespace',\n '$app_version',\n // web params\n '$browser',\n '$browser_version',\n '$device_type',\n '$current_url',\n '$pathname',\n '$os',\n '$os_name', // $os_name is a special case, it's treated as an alias of $os!\n '$os_version',\n '$referring_domain',\n '$referrer',\n '$screen_height',\n '$screen_width',\n '$viewport_height',\n '$viewport_width',\n '$raw_user_agent',\n]\n\nexport const MASKED = '<masked>'\n\n// Campaign params that can be read from the cookie store\nexport const COOKIE_CAMPAIGN_PARAMS = [\n 'li_fat_id', // linkedin\n]\n\nexport function getCampaignParams(\n customTrackedParams?: string[],\n maskPersonalDataProperties?: boolean,\n customPersonalDataProperties?: string[] | undefined\n): Record<string, string> {\n if (!document) {\n return {}\n }\n\n const paramsToMask = maskPersonalDataProperties\n ? [...PERSONAL_DATA_CAMPAIGN_PARAMS, ...(customPersonalDataProperties || [])]\n : []\n\n // Initially get campaign params from the URL\n const urlCampaignParams = _getCampaignParamsFromUrl(\n maskQueryParams(document.URL, paramsToMask, MASKED),\n customTrackedParams\n )\n\n // But we can also get some of them from the cookie store\n // For example: https://learn.microsoft.com/en-us/linkedin/marketing/conversions/enabling-first-party-cookies?view=li-lms-2025-05#reading-li_fat_id-from-cookies\n const cookieCampaignParams = _getCampaignParamsFromCookie()\n\n // Prefer the values found in the urlCampaignParams if possible\n // `extend` will override the values if found in the second argument\n return extend(cookieCampaignParams, urlCampaignParams)\n}\n\nfunction _getCampaignParamsFromUrl(url: string, customParams?: string[]): Record<string, string> {\n const campaign_keywords = CAMPAIGN_PARAMS.concat(customParams || [])\n\n const params: Record<string, any> = {}\n each(campaign_keywords, function (kwkey) {\n const kw = getQueryParam(url, kwkey)\n params[kwkey] = kw ? kw : null\n })\n\n return params\n}\n\nfunction _getCampaignParamsFromCookie(): Record<string, string> {\n const params: Record<string, any> = {}\n each(COOKIE_CAMPAIGN_PARAMS, function (kwkey) {\n const kw = cookieStore._get(kwkey)\n params[kwkey] = kw ? kw : null\n })\n\n return params\n}\n\nfunction _getSearchEngine(referrer: string): string | null {\n if (!referrer) {\n return null\n } else {\n if (referrer.search(URL_REGEX_PREFIX + 'google.([^/?]*)') === 0) {\n return 'google'\n } else if (referrer.search(URL_REGEX_PREFIX + 'bing.com') === 0) {\n return 'bing'\n } else if (referrer.search(URL_REGEX_PREFIX + 'yahoo.com') === 0) {\n return 'yahoo'\n } else if (referrer.search(URL_REGEX_PREFIX + 'duckduckgo.com') === 0) {\n return 'duckduckgo'\n } else {\n return null\n }\n }\n}\n\nfunction _getSearchInfoFromReferrer(referrer: string): Record<string, any> {\n const search = _getSearchEngine(referrer)\n const param = search != 'yahoo' ? 'q' : 'p'\n const ret: Record<string, any> = {}\n\n if (!isNull(search)) {\n ret['$search_engine'] = search\n\n const keyword = document ? getQueryParam(document.referrer, param) : ''\n if (keyword.length) {\n ret['ph_keyword'] = keyword\n }\n }\n\n return ret\n}\n\nexport function getSearchInfo(): Record<string, any> {\n const referrer = document?.referrer\n if (!referrer) {\n return {}\n }\n return _getSearchInfoFromReferrer(referrer)\n}\n\nexport function getBrowserLanguage(): string | undefined {\n return (\n navigator.language || // Any modern browser\n (navigator as Record<string, any>).userLanguage // IE11\n )\n}\n\nexport function getBrowserLanguagePrefix(): string | undefined {\n const lang = getBrowserLanguage()\n return typeof lang === 'string' ? lang.split('-')[0] : undefined\n}\n\nconst DIRECT = '$direct'\n\nexport function getReferrer(): string {\n return document?.referrer || DIRECT\n}\n\nexport function getReferringDomain(): string {\n if (!document?.referrer) {\n return DIRECT\n }\n return convertToURL(document.referrer)?.host || DIRECT\n}\n\nexport function getReferrerInfo(): Record<string, any> {\n return {\n $referrer: getReferrer(),\n $referring_domain: getReferringDomain(),\n }\n}\n\nexport function getPersonInfo(\n maskPersonalDataProperties?: boolean,\n customPersonalDataProperties?: string[],\n disableCaptureUrlHashes: boolean = false\n) {\n const paramsToMask = maskPersonalDataProperties\n ? [...PERSONAL_DATA_CAMPAIGN_PARAMS, ...(customPersonalDataProperties || [])]\n : []\n const href = disableCaptureUrlHashes ? stripUrlHash(location?.href) : location?.href\n const url = href?.substring(0, 1000)\n // we're being a bit more economical with bytes here because this is stored in the cookie\n return {\n r: getReferrer().substring(0, 1000),\n u: url ? maskQueryParams(url, paramsToMask, MASKED) : undefined,\n }\n}\n\nexport function getPersonPropsFromInfo(\n info: Record<string, any>,\n disableCaptureUrlHashes: boolean = false\n): Record<string, any> {\n const { r: referrer, u } = info\n const url = disableCaptureUrlHashes ? stripUrlHash(u) : u\n const referring_domain = referrer == null ? undefined : referrer == DIRECT ? DIRECT : convertToURL(referrer)?.host\n\n const props: Record<string, string | undefined> = {\n $referrer: referrer,\n $referring_domain: referring_domain,\n }\n if (url) {\n props['$current_url'] = url\n const location = convertToURL(url)\n props['$host'] = location?.host\n props['$pathname'] = location?.pathname\n const campaignParams = _getCampaignParamsFromUrl(url)\n extend(props, campaignParams)\n }\n if (referrer) {\n const searchInfo = _getSearchInfoFromReferrer(referrer)\n extend(props, searchInfo)\n }\n return props\n}\n\nexport function getInitialPersonPropsFromInfo(\n info: Record<string, any>,\n disableCaptureUrlHashes: boolean = false\n): Record<string, any> {\n const personProps = getPersonPropsFromInfo(info, disableCaptureUrlHashes)\n const props: Record<string, any> = {}\n each(personProps, function (val: any, key: string) {\n props[`$initial_${stripLeadingDollar(key)}`] = val\n })\n return props\n}\n\nexport function getTimezone(): string | undefined {\n try {\n return Intl.DateTimeFormat().resolvedOptions().timeZone\n } catch {\n return undefined\n }\n}\n\nexport function getTimezoneOffset(): number | undefined {\n try {\n return new Date().getTimezoneOffset()\n } catch {\n return undefined\n }\n}\n\n// Gathers signals that aren't in the UA string. Desktop / Android Brave is\n// Chromium-based and exposes `navigator.brave` rather than a UA marker. (Brave\n// on iOS is picked up via the `Brave/` UA marker by `detectBrowser` itself, so\n// no hint is needed there.)\nexport function getBrowserDetectionHints(): BrowserDetectionHints {\n const nav = typeof navigator !== 'undefined' ? (navigator as Record<string, any>) : undefined\n return nav?.brave ? { brave: true } : {}\n}\n\nexport function getEventProperties(\n maskPersonalDataProperties?: boolean,\n customPersonalDataProperties?: string[],\n detectGoogleSearchApp?: boolean,\n disableCaptureUrlHashes: boolean = false\n): Properties {\n if (!userAgent) {\n return {}\n }\n const paramsToMask = maskPersonalDataProperties\n ? [...PERSONAL_DATA_CAMPAIGN_PARAMS, ...(customPersonalDataProperties || [])]\n : []\n const [os_name, os_version] = detectOS(userAgent)\n const browserHints = getBrowserDetectionHints()\n const browserOptions = { detectGoogleSearchApp }\n\n const properties = extend(\n stripEmptyProperties({\n $os: os_name,\n $os_version: os_version,\n $browser: detectBrowser(userAgent, navigator.vendor, browserHints, browserOptions),\n $device: detectDevice(userAgent),\n $device_type: detectDeviceType(userAgent, {\n // eslint-disable-next-line compat/compat\n userAgentDataPlatform: navigator?.userAgentData?.platform,\n maxTouchPoints: navigator?.maxTouchPoints,\n screenWidth: window?.screen?.width,\n screenHeight: window?.screen?.height,\n devicePixelRatio: window?.devicePixelRatio,\n }),\n $timezone: getTimezone(),\n $timezone_offset: getTimezoneOffset(),\n }),\n {\n $current_url: maskQueryParams(\n disableCaptureUrlHashes ? stripUrlHash(location?.href) : location?.href,\n paramsToMask,\n MASKED\n ),\n $host: location?.host,\n $pathname: location?.pathname,\n $raw_user_agent: userAgent.length > 1000 ? userAgent.substring(0, 997) + '...' : userAgent,\n $browser_version: detectBrowserVersion(userAgent, navigator.vendor, browserHints, browserOptions),\n $browser_language: getBrowserLanguage(),\n $browser_language_prefix: getBrowserLanguagePrefix(),\n $screen_height: window?.screen.height,\n $screen_width: window?.screen.width,\n $viewport_height: window?.innerHeight,\n $viewport_width: window?.innerWidth,\n $lib: Config.LIB_NAME,\n $lib_version: Config.LIB_VERSION,\n $insert_id: Math.random().toString(36).substring(2, 10) + Math.random().toString(36).substring(2, 10),\n $time: Date.now() / 1000, // epoch time in seconds\n }\n )\n\n if (Config.SDK_DIST_CHANNEL) {\n properties[SDK_DIST_CHANNEL] = Config.SDK_DIST_CHANNEL\n }\n\n return properties\n}\n","import { type JSX, type RefObject, render, Fragment } from 'preact'\nimport { useContext, useEffect, useMemo, useRef, useState } from 'preact/hooks'\nimport { PostHog } from '../posthog-core'\nimport {\n DisplaySurveyPopoverOptions,\n Survey,\n SurveyCallback,\n SurveyEventName,\n SurveyEventProperties,\n SurveyPosition,\n SurveyQuestion,\n SurveyQuestionBranchingType,\n SurveyQuestionType,\n SurveyResponseValue,\n SurveySchedule,\n SurveyTabPosition,\n SurveyType,\n SurveyWidgetType,\n SurveyWithTypeAndAppearance,\n} from '../posthog-surveys-types'\nimport { addEventListener } from '../utils'\nimport { document as _document, window as _window } from '../utils/globals'\nimport {\n doesSurveyActivateByAction,\n doesSurveyActivateByEvent,\n IN_APP_SURVEY_TYPES,\n isSurveyRunning,\n SURVEY_LOGGER as logger,\n} from '../utils/survey-utils'\nimport { isArray, isNull, isUndefined } from '@posthog/core'\nimport { Properties } from '../types'\nimport { SURVEYS } from '../constants'\nimport { uuidv7 } from '../uuidv7'\nimport { ConfirmationMessage } from './surveys/components/ConfirmationMessage'\nimport { Cancel } from './surveys/components/QuestionHeader'\nimport {\n CommonQuestionProps,\n LinkQuestion,\n MultipleChoiceQuestion,\n OpenTextQuestion,\n RatingQuestion,\n} from './surveys/components/QuestionTypes'\nimport {\n canActivateRepeatedly,\n retrieveSurveyShadow,\n defaultSurveyAppearance,\n dismissedSurveyEvent,\n doesSurveyDeviceTypesMatch,\n doesSurveyMatchSelector,\n doesSurveyUrlMatch,\n getDisplayOrderQuestions,\n getInProgressSurveyState,\n getSurveyContainerClass,\n getSurveyResponseKey,\n getSurveySeen,\n hasWaitPeriodPassed,\n isSurveyInProgress,\n sendSurveyEvent,\n sendSurveyAbandonedEvent,\n setInProgressSurveyState,\n SurveyContext,\n getSurveyStylesheet,\n addSurveyCSSVariablesToElement,\n getPopoverPosition,\n} from './surveys/surveys-extension-utils'\nimport {\n extractPrefillParamsFromUrl,\n convertPrefillToResponses,\n calculatePrefillStartIndex,\n} from '../utils/survey-url-prefill'\nimport { getNextSurveyStep } from '../utils/survey-branching'\nimport { applySurveyTranslationForUser } from '../utils/survey-translations'\n\n// Re-export for surveys-preview entrypoint\nexport { getNextSurveyStep }\n\n// We cast the types here which is dangerous but protected by the top level generateSurveys call\nconst window = _window as Window & typeof globalThis\nconst document = _document as Document\n\nconst DISPATCH_FEEDBACK_WIDGET_EVENT = 'ph:show_survey_widget'\nconst WIDGET_LISTENER_ATTRIBUTE = 'PHWidgetSurveyClickListener'\n\nconst SURVEY_NEXT_TO_TRIGGER_PARAMS = {\n ESTIMATED_MIN_HEIGHT: 250,\n HORIZONTAL_PADDING: 20,\n TRIGGER_SPACING: 12,\n} as const\n\nfunction getNextToTriggerPosition(target: HTMLElement, surveyWidth: number): JSX.CSSProperties | null {\n try {\n const buttonRect = target.getBoundingClientRect()\n const viewportHeight = window.innerHeight\n const viewportWidth = window.innerWidth\n const estimatedMinSurveyHeight = SURVEY_NEXT_TO_TRIGGER_PARAMS.ESTIMATED_MIN_HEIGHT\n const buttonCenterX = buttonRect.left + buttonRect.width / 2\n let left = buttonCenterX - surveyWidth / 2\n const horizontalPadding = SURVEY_NEXT_TO_TRIGGER_PARAMS.HORIZONTAL_PADDING\n if (left + surveyWidth > viewportWidth - horizontalPadding) {\n left = viewportWidth - surveyWidth - horizontalPadding\n }\n if (left < horizontalPadding) {\n left = horizontalPadding\n }\n const spacing = SURVEY_NEXT_TO_TRIGGER_PARAMS.TRIGGER_SPACING\n const spaceBelow = viewportHeight - buttonRect.bottom\n const spaceAbove = buttonRect.top\n const showAbove = spaceBelow < estimatedMinSurveyHeight && spaceAbove > spaceBelow\n\n return {\n position: 'fixed',\n top: showAbove ? 'auto' : `${buttonRect.bottom + spacing}px`,\n left: `${left}px`,\n right: 'auto',\n bottom: showAbove ? `${viewportHeight - buttonRect.top + spacing}px` : 'auto',\n zIndex: defaultSurveyAppearance.zIndex,\n } satisfies JSX.CSSProperties\n } catch (error) {\n logger.warn('Failed to calculate trigger position:', error)\n return null\n }\n}\n\n// Keep in sync with posthog/constants.py on main repo\nconst SURVEY_TARGETING_FLAG_PREFIX = 'survey-targeting-'\n\nexport class SurveyManager {\n private _posthog: PostHog\n private _surveyInFocus: string | null\n private _surveyTimeouts: Map<string, NodeJS.Timeout> = new Map()\n private _widgetSelectorListeners: Map<string, { element: Element; listener: EventListener; survey: Survey }> =\n new Map()\n private _prefillHandledSurveys: Set<string> = new Set()\n\n constructor(posthog: PostHog) {\n this._posthog = posthog\n // This is used to track the survey that is currently in focus. We only show one survey at a time.\n this._surveyInFocus = null\n }\n\n public handlePageUnload = (): void => {\n // we don't use getSurveys to avoid adding extra API calls here.\n // if no surveys are cached, there's nothing to do anyways\n const surveys = this._posthog.get_property(SURVEYS) as Survey[] | undefined\n if (!surveys) {\n return\n }\n for (const survey of surveys) {\n if (isSurveyInProgress(survey)) {\n sendSurveyAbandonedEvent(survey, this._posthog)\n }\n }\n }\n\n private _clearSurveyTimeout(surveyId: string) {\n const timeout = this._surveyTimeouts.get(surveyId)\n if (timeout) {\n clearTimeout(timeout)\n this._surveyTimeouts.delete(surveyId)\n }\n }\n\n /**\n * cancel a \"pending\" survey, i.e. one that is waiting to be displayed in\n * the _surveyTimeouts queue\n */\n public cancelSurvey(surveyId: string): void {\n // only works for surveys in the _surveyTimeouts queue...\n if (!this._surveyTimeouts.has(surveyId)) {\n return\n }\n\n logger.info(`Cancelled pending survey ${surveyId}`)\n this._clearSurveyTimeout(surveyId)\n\n // release focus - it was claimed when the delay timer started.\n // \"focus\" != \"survey is displayed\"\n if (this._surveyInFocus === surveyId) {\n this._surveyInFocus = null\n }\n }\n\n public handlePopoverSurvey = (surveyParam: Survey, options?: DisplaySurveyPopoverOptions): void => {\n const { survey: translatedSurvey, language: surveyLanguage } = this._translateSurveyForRendering(surveyParam)\n\n // apply overrides for position / selector (needed for thumb surveys)\n const survey =\n options?.position || options?.selector\n ? {\n ...translatedSurvey,\n appearance: {\n ...translatedSurvey.appearance,\n ...(options.position && { position: options.position }),\n ...(options.selector && { widgetSelector: options.selector }),\n },\n }\n : translatedSurvey\n\n this._clearSurveyTimeout(survey.id)\n\n const { properties, initialResponses } = options ?? {}\n const hasPrefillData = initialResponses && Object.keys(initialResponses).length > 0\n const isSurveyCompleted = hasPrefillData\n ? this._handleInitialResponses(survey, initialResponses, properties, surveyLanguage)\n : false\n\n // if the survey is done (from prefill) and there is no thank-you, we can break early\n if (isSurveyCompleted && !survey.appearance?.displayThankYouMessage) {\n return\n }\n\n this._addSurveyToFocus(survey)\n\n // Calculate position style for NextToTrigger positioning\n let positionStyle: JSX.CSSProperties = {}\n if (survey.appearance?.position === SurveyPosition.NextToTrigger && survey.appearance?.widgetSelector) {\n const targetElement = document.querySelector(survey.appearance.widgetSelector) as HTMLElement | null\n if (targetElement) {\n positionStyle =\n getNextToTriggerPosition(\n targetElement,\n parseInt(survey.appearance?.maxWidth || defaultSurveyAppearance.maxWidth)\n ) || {}\n }\n }\n\n const delaySeconds = survey.appearance?.surveyPopupDelaySeconds || 0\n const { shadow } = retrieveSurveyShadow(survey, this._posthog)\n\n const surveyPopupProps: SurveyPopupProps = {\n posthog: this._posthog,\n survey: survey,\n removeSurveyFromFocus: this._removeSurveyFromFocus,\n properties: properties,\n style: positionStyle,\n isSurveyCompleted: isSurveyCompleted,\n skipShownEvent: options?.skipShownEvent,\n surveyLanguage,\n }\n\n if (delaySeconds <= 0) {\n return render(<SurveyPopup {...surveyPopupProps} />, shadow)\n }\n const timeoutId = setTimeout(() => {\n // remove survey to keep `_surveyTimeouts` as a true list of \"pending\" surveys\n this._surveyTimeouts.delete(survey.id)\n\n // Re-check the full display predicate, not just the URL: eligibility can change\n // during the delay (e.g. identify() reloads flags and the internal targeting flag\n // flips to false), and we must not show a survey that is no longer eligible by the\n // time the delay elapses.\n if (!this._shouldDisplaySurvey(survey)) {\n logger.info(`Survey ${survey.id} no longer eligible when its display delay elapsed; not displaying`)\n return this._removeSurveyFromFocus(survey)\n }\n // rendering with surveyPopupDelaySeconds = 0 because we're already handling the timeout here\n render(\n <SurveyPopup\n {...surveyPopupProps}\n survey={{\n ...survey,\n appearance: {\n ...survey.appearance,\n surveyPopupDelaySeconds: 0,\n },\n }}\n />,\n shadow\n )\n }, delaySeconds * 1000)\n this._surveyTimeouts.set(survey.id, timeoutId)\n }\n\n private _handleWidget = (survey: Survey): void => {\n const { survey: translatedSurvey, language: surveyLanguage } = this._translateSurveyForRendering(survey)\n // Ensure widget container exists if it doesn't\n const { shadow, isNewlyCreated } = retrieveSurveyShadow(translatedSurvey, this._posthog)\n\n // If the widget is already rendered, do nothing. Otherwise the widget will be re-rendered every second\n if (!isNewlyCreated) {\n return\n }\n\n render(\n <FeedbackWidget\n posthog={this._posthog}\n survey={translatedSurvey}\n surveyLanguage={surveyLanguage}\n key={survey.id}\n />,\n shadow\n )\n }\n\n private _removeWidgetSelectorListener = (survey: Pick<Survey, 'id' | 'type' | 'appearance'>): void => {\n this._removeSurveyFromDom(survey)\n const existing = this._widgetSelectorListeners.get(survey.id)\n if (existing) {\n existing.element.removeEventListener('click', existing.listener)\n existing.element.removeAttribute(WIDGET_LISTENER_ATTRIBUTE)\n this._widgetSelectorListeners.delete(survey.id)\n logger.info(`Removed click listener for survey ${survey.id}`)\n }\n }\n\n private _manageWidgetSelectorListener = (survey: Survey, selector: string): void => {\n const currentElement = document.querySelector(selector)\n const existingListenerData = this._widgetSelectorListeners.get(survey.id)\n\n if (!currentElement) {\n if (existingListenerData) {\n this._removeWidgetSelectorListener(survey)\n }\n return\n }\n\n this._handleWidget(survey)\n\n if (existingListenerData) {\n // Listener exists, check if element changed\n if (currentElement !== existingListenerData.element) {\n logger.info(`Selector element changed for survey ${survey.id}. Re-attaching listener.`)\n this._removeWidgetSelectorListener(survey)\n // Continue to attach listener to the new element below\n } else {\n // Element is the same, listener already attached, do nothing\n return\n }\n }\n\n // Element found, and no listener attached (or it was just removed from old element)\n if (!currentElement.hasAttribute(WIDGET_LISTENER_ATTRIBUTE)) {\n const listener = (event: Event) => {\n event.stopPropagation() // Prevent bubbling\n\n const positionStyles =\n survey.appearance?.position === SurveyPosition.NextToTrigger\n ? getNextToTriggerPosition(\n event.currentTarget as HTMLElement,\n parseInt(survey.appearance?.maxWidth || defaultSurveyAppearance.maxWidth)\n )\n : {}\n\n window.dispatchEvent(\n new CustomEvent(DISPATCH_FEEDBACK_WIDGET_EVENT, {\n detail: { surveyId: survey.id, position: positionStyles },\n })\n )\n }\n\n addEventListener(currentElement, 'click', listener)\n currentElement.setAttribute(WIDGET_LISTENER_ATTRIBUTE, 'true')\n this._widgetSelectorListeners.set(survey.id, { element: currentElement, listener, survey })\n logger.info(`Attached click listener for feedback button survey ${survey.id}`)\n }\n }\n\n /**\n * Sorts surveys by their appearance delay in ascending order. If a survey does not have an appearance delay,\n * it is considered to have a delay of 0.\n * @param surveys\n * @returns The surveys sorted by their appearance delay\n */\n private _sortSurveysByAppearanceDelay(surveys: Survey[]): Survey[] {\n return surveys.sort((a, b) => {\n const isSurveyInProgressA = isSurveyInProgress(a)\n const isSurveyInProgressB = isSurveyInProgress(b)\n if (isSurveyInProgressA && !isSurveyInProgressB) {\n return -1 // a comes before b (in progress surveys first)\n }\n if (!isSurveyInProgressA && isSurveyInProgressB) {\n return 1 // a comes after b (in progress surveys first)\n }\n const aIsAlways = a.schedule === SurveySchedule.Always\n const bIsAlways = b.schedule === SurveySchedule.Always\n\n if (aIsAlways && !bIsAlways) {\n return 1 // a comes after b\n }\n if (!aIsAlways && bIsAlways) {\n return -1 // a comes before b\n }\n // If both are Always or neither is Always, sort by delay\n return (a.appearance?.surveyPopupDelaySeconds || 0) - (b.appearance?.surveyPopupDelaySeconds || 0)\n })\n }\n\n public renderPopover = (survey: Survey): void => {\n const { survey: translatedSurvey, language: surveyLanguage } = this._translateSurveyForRendering(survey)\n const { shadow } = retrieveSurveyShadow(translatedSurvey, this._posthog)\n render(\n <SurveyPopup\n posthog={this._posthog}\n survey={translatedSurvey}\n removeSurveyFromFocus={this._removeSurveyFromFocus}\n surveyLanguage={surveyLanguage}\n />,\n shadow\n )\n }\n\n public renderSurvey = (survey: Survey, selector: Element, properties?: Properties): void => {\n const { survey: translatedSurvey, language: surveyLanguage } = this._translateSurveyForRendering(survey)\n let isSurveyCompleted = false\n if (this._posthog.config?.surveys?.prefillFromUrl) {\n isSurveyCompleted = this._handleUrlPrefill(translatedSurvey, surveyLanguage)\n }\n\n render(\n <SurveyPopup\n posthog={this._posthog}\n survey={translatedSurvey}\n removeSurveyFromFocus={this._removeSurveyFromFocus}\n isPopup={false}\n properties={properties}\n isSurveyCompleted={isSurveyCompleted}\n surveyLanguage={surveyLanguage}\n />,\n selector\n )\n }\n\n private _translateSurveyForRendering(survey: Survey): { survey: Survey; language: string | null } {\n // Rendering entry points accept the raw API survey. The translation helper is idempotent,\n // but keeping this central avoids each entry point growing its own language rules.\n return applySurveyTranslationForUser(survey, this._posthog)\n }\n\n private _handleUrlPrefill(survey: Survey, surveyLanguage?: string | null): boolean {\n // Only handle prefill once per survey session to avoid overwriting in-progress responses\n if (this._prefillHandledSurveys.has(survey.id)) {\n return false\n }\n\n const { params } = extractPrefillParamsFromUrl(window.location.search)\n\n if (Object.keys(params).length === 0) {\n return false\n }\n\n logger.info('[Survey Prefill] Detected URL prefill parameters')\n\n const result = this._processPrefillData(survey, params, surveyLanguage)\n if (!result) {\n return false\n }\n\n const { responses, submissionId, isSurveyCompleted, skippedResponses } = result\n\n /**\n * auto-submit some survey events on pageload only if:\n * 1) survey is complete, OR\n * 2) partial responses are enabled AND the skipped questions were set to auto-submit\n */\n const shouldAutoSubmitPrefilled = Object.keys(skippedResponses).length > 0 && survey.enable_partial_responses\n if (shouldAutoSubmitPrefilled || isSurveyCompleted) {\n sendSurveyEvent({\n responses: isSurveyCompleted ? responses : skippedResponses,\n survey,\n surveySubmissionId: submissionId,\n posthog: this._posthog,\n isSurveyCompleted,\n surveyLanguage,\n })\n }\n\n // Mark this survey as having been prefilled\n this._prefillHandledSurveys.add(survey.id)\n\n return isSurveyCompleted\n }\n\n /**\n * process prefilled responses for non-hosted surveys\n *\n * @returns boolean, true if the survey is completed\n */\n private _handleInitialResponses(\n survey: Survey,\n initialResponses: Record<number, SurveyResponseValue>,\n properties?: Properties,\n surveyLanguage?: string | null\n ): boolean {\n const prefillParams: { [key: number]: string[] } = {}\n for (const [indexStr, value] of Object.entries(initialResponses)) {\n const index = parseInt(indexStr)\n prefillParams[index] = isArray(value) ? value.map(String) : [String(value)]\n }\n\n logger.info('[Survey] Processing initial responses')\n\n const result = this._processPrefillData(survey, prefillParams, surveyLanguage)\n if (!result) {\n return false\n }\n\n const { responses, submissionId, isSurveyCompleted } = result\n\n // always capture immediately\n sendSurveyEvent({\n responses,\n survey,\n surveySubmissionId: submissionId,\n posthog: this._posthog,\n isSurveyCompleted,\n properties,\n surveyLanguage,\n })\n\n return isSurveyCompleted\n }\n\n private _processPrefillData(\n survey: Survey,\n prefillParams: Record<number, string[]>,\n surveyLanguage?: string | null\n ): {\n responses: Record<string, any>\n submissionId: string\n startQuestionIndex: number\n isSurveyCompleted: boolean\n skippedResponses: Record<string, any>\n } | null {\n try {\n const responses = convertPrefillToResponses(survey, prefillParams)\n\n if (Object.keys(responses).length === 0) {\n logger.warn('[Survey Prefill] No valid responses after conversion')\n return null\n }\n\n const submissionId = uuidv7()\n\n // calculate which question to start at based on prefilled questions\n const prefilledIndices = Object.keys(prefillParams).map((k) => parseInt(k, 10))\n const { startQuestionIndex, skippedResponses } = calculatePrefillStartIndex(\n survey,\n prefilledIndices,\n responses\n )\n const isSurveyCompleted = startQuestionIndex >= survey.questions.length\n\n setInProgressSurveyState(survey, {\n surveySubmissionId: submissionId,\n responses: responses,\n lastQuestionIndex: startQuestionIndex,\n surveyLanguage,\n })\n\n logger.info('[Survey Prefill] Stored prefilled responses in localStorage')\n\n return { responses, submissionId, startQuestionIndex, isSurveyCompleted, skippedResponses }\n } catch (error) {\n logger.error('[Survey Prefill] Error handling prefill:', error)\n return null\n }\n }\n\n private _isSurveyFeatureFlagEnabled(flagKey: string | null, flagVariant: string | undefined = undefined) {\n if (!flagKey) {\n return true\n }\n const isFeatureEnabled = !!this._posthog.featureFlags?.isFeatureEnabled(flagKey, {\n send_event: !flagKey.startsWith(SURVEY_TARGETING_FLAG_PREFIX),\n })\n let flagVariantCheck = true\n if (flagVariant) {\n const flagVariantValue = this._posthog.featureFlags?.getFeatureFlag(flagKey, { send_event: false })\n flagVariantCheck = flagVariantValue === flagVariant || flagVariant === 'any'\n }\n return isFeatureEnabled && flagVariantCheck\n }\n\n private _isSurveyConditionMatched(survey: Survey): boolean {\n if (!survey.conditions) {\n return true\n }\n return (\n doesSurveyUrlMatch(survey, this._posthog) &&\n doesSurveyDeviceTypesMatch(survey) &&\n doesSurveyMatchSelector(survey)\n )\n }\n\n private _internalFlagCheckSatisfied(survey: Survey): boolean {\n return (\n canActivateRepeatedly(survey) ||\n this._isSurveyFeatureFlagEnabled(survey.internal_targeting_flag_key) ||\n isSurveyInProgress(survey)\n )\n }\n\n public checkSurveyEligibility(survey: Survey): { eligible: boolean; reason?: string } {\n const eligibility = { eligible: true, reason: undefined as string | undefined }\n\n if (!isSurveyRunning(survey)) {\n eligibility.eligible = false\n eligibility.reason = `Survey is not running. It was completed on ${survey.end_date}`\n return eligibility\n }\n\n if (!IN_APP_SURVEY_TYPES.includes(survey.type)) {\n eligibility.eligible = false\n eligibility.reason = `Surveys of type ${survey.type} are never eligible to be shown in the app`\n return eligibility\n }\n\n const linkedFlagVariant = survey.conditions?.linkedFlagVariant\n if (!this._isSurveyFeatureFlagEnabled(survey.linked_flag_key, linkedFlagVariant)) {\n eligibility.eligible = false\n if (!linkedFlagVariant) {\n eligibility.reason = `Survey linked feature flag is not enabled`\n } else {\n eligibility.reason = `Survey linked feature flag is not enabled for variant ${linkedFlagVariant}`\n }\n return eligibility\n }\n\n if (!this._isSurveyFeatureFlagEnabled(survey.targeting_flag_key)) {\n eligibility.eligible = false\n eligibility.reason = `Survey targeting feature flag is not enabled`\n return eligibility\n }\n\n if (!this._internalFlagCheckSatisfied(survey)) {\n eligibility.eligible = false\n eligibility.reason =\n 'Survey internal targeting flag is not enabled and survey cannot activate repeatedly and survey is not in progress'\n return eligibility\n }\n\n if (!hasWaitPeriodPassed(survey.conditions?.seenSurveyWaitPeriodInDays)) {\n eligibility.eligible = false\n eligibility.reason = `Survey wait period has not passed`\n return eligibility\n }\n\n if (getSurveySeen(survey)) {\n eligibility.eligible = false\n eligibility.reason = `Survey has already been seen and it can't be activated again`\n return eligibility\n }\n\n return eligibility\n }\n\n /**\n * Surveys can be activated by events or actions. This method checks if the survey has events and actions,\n * and if so, it checks if the survey has been activated.\n * @param survey\n */\n private _hasActionOrEventTriggeredSurvey(survey: Survey): boolean {\n if (!doesSurveyActivateByEvent(survey) && !doesSurveyActivateByAction(survey)) {\n // If survey doesn't depend on events/actions, it's considered \"triggered\" by default\n return true\n }\n const surveysActivatedByEventsOrActions: string[] | undefined =\n this._posthog.surveys?._surveyEventReceiver?.getSurveys()\n return !!surveysActivatedByEventsOrActions?.includes(survey.id)\n }\n\n private _checkFlags(survey: Survey): boolean {\n if (!survey.feature_flag_keys?.length) {\n return true\n }\n\n return survey.feature_flag_keys.every(({ key, value }) => {\n if (!key || !value) {\n return true\n }\n return this._isSurveyFeatureFlagEnabled(value)\n })\n }\n\n /**\n * The full predicate for \"should this survey display right now\": eligibility (running,\n * type, linked/targeting/internal flags, wait period, already-seen) plus the URL/device/\n * selector conditions, the event/action trigger, and any feature-flag dependencies.\n *\n * Shared by the display loop and re-checked when a popover's delay timer fires, so a\n * survey that became ineligible *during* the delay (e.g. an identify() reloaded flags and\n * the internal targeting flag is now false) is not shown. Note this is purely an AND gate:\n * adding it can only ever suppress a display, never cause an extra one.\n */\n private _shouldDisplaySurvey(survey: Survey): boolean {\n return (\n this.checkSurveyEligibility(survey).eligible &&\n this._isSurveyConditionMatched(survey) &&\n this._hasActionOrEventTriggeredSurvey(survey) &&\n this._checkFlags(survey)\n )\n }\n\n public getActiveMatchingSurveys = (callback: SurveyCallback, forceReload = false): void => {\n this._posthog?.surveys?.getSurveys((surveys) => {\n const targetingMatchedSurveys = surveys.filter((survey) => this._shouldDisplaySurvey(survey))\n callback(targetingMatchedSurveys)\n }, forceReload)\n }\n\n public callSurveysAndEvaluateDisplayLogic = (forceReload: boolean = false): void => {\n this.getActiveMatchingSurveys((surveys) => {\n const inAppSurveysWithDisplayLogic = surveys.filter(\n (survey) => survey.type === SurveyType.Popover || survey.type === SurveyType.Widget\n )\n\n // Cancel any pending (delayed, not-yet-shown) survey whose eligibility changed since\n // it was queued — e.g. an identify() during the delay flipped its targeting flag.\n // This frees the popover focus promptly instead of waiting for a now-stale timer to\n // fire. Safe for already-shown surveys: their timer is gone, so cancelSurvey no-ops.\n const matchingIds = new Set(inAppSurveysWithDisplayLogic.map((survey) => survey.id))\n for (const pendingSurveyId of Array.from(this._surveyTimeouts.keys())) {\n if (!matchingIds.has(pendingSurveyId)) {\n this.cancelSurvey(pendingSurveyId)\n }\n }\n\n // Create a queue of surveys sorted by their appearance delay. We will evaluate the display logic\n // for each survey in the queue in order, and only display one survey at a time.\n const inAppSurveysQueue = this._sortSurveysByAppearanceDelay(inAppSurveysWithDisplayLogic)\n\n // Keep track of surveys processed this cycle to remove listeners for inactive ones\n const activeSelectorSurveys = new Set<string>()\n\n inAppSurveysQueue.forEach((survey) => {\n // Widget Type Logic\n if (survey.type === SurveyType.Widget) {\n if (survey.appearance?.widgetType === SurveyWidgetType.Tab) {\n this._handleWidget(survey)\n return\n }\n\n // For selector widget types, we need to manage the listener attachment/detachment dynamically\n if (\n survey.appearance?.widgetType === SurveyWidgetType.Selector &&\n survey.appearance?.widgetSelector\n ) {\n activeSelectorSurveys.add(survey.id)\n this._manageWidgetSelectorListener(survey, survey.appearance?.widgetSelector)\n }\n }\n\n // Popover Type Logic (only one shown at a time)\n if (isNull(this._surveyInFocus) && survey.type === SurveyType.Popover) {\n this.handlePopoverSurvey(survey)\n }\n })\n\n // Clean up listeners for surveys that are no longer active or matched\n this._widgetSelectorListeners.forEach(({ survey }) => {\n if (!activeSelectorSurveys.has(survey.id)) {\n this._removeWidgetSelectorListener(survey)\n }\n })\n }, forceReload)\n }\n\n private _addSurveyToFocus = (survey: Pick<Survey, 'id'>): void => {\n if (!isNull(this._surveyInFocus)) {\n logger.error(`Survey ${this._surveyInFocus} already in focus. Cannot add survey ${survey.id}.`)\n }\n this._surveyInFocus = survey.id\n }\n\n private _removeSurveyFromDom(survey: Pick<Survey, 'id' | 'type' | 'appearance'>): void {\n try {\n const shadowContainer = document.querySelector(getSurveyContainerClass(survey, true))\n if (shadowContainer?.shadowRoot) {\n render(null, shadowContainer.shadowRoot)\n }\n shadowContainer?.remove()\n } catch (error) {\n logger.warn(`Failed to remove survey ${survey.id} from DOM:`, error)\n }\n }\n\n private _removeSurveyFromFocus = (survey: SurveyWithTypeAndAppearance): void => {\n if (this._surveyInFocus !== survey.id) {\n logger.error(`Survey ${survey.id} is not in focus. Cannot remove survey ${survey.id}.`)\n }\n this._clearSurveyTimeout(survey.id)\n this._surveyInFocus = null\n this._removeSurveyFromDom(survey)\n }\n\n // Expose internal state and methods for testing\n public getTestAPI() {\n return {\n addSurveyToFocus: this._addSurveyToFocus,\n removeSurveyFromFocus: this._removeSurveyFromFocus,\n surveyInFocus: this._surveyInFocus,\n surveyTimeouts: this._surveyTimeouts,\n handleWidget: this._handleWidget,\n handlePopoverSurvey: this.handlePopoverSurvey,\n manageWidgetSelectorListener: this._manageWidgetSelectorListener,\n sortSurveysByAppearanceDelay: this._sortSurveysByAppearanceDelay,\n checkFlags: this._checkFlags.bind(this),\n isSurveyFeatureFlagEnabled: this._isSurveyFeatureFlagEnabled.bind(this),\n }\n }\n}\n\nconst DEFAULT_PREVIEW_POSITION_STYLES: JSX.CSSProperties = {\n position: 'relative',\n left: 'unset',\n right: 'unset',\n top: 'unset',\n bottom: 'unset',\n transform: 'unset',\n}\n\nexport const renderSurveysPreview = ({\n survey,\n parentElement,\n previewPageIndex,\n forceDisableHtml,\n onPreviewSubmit,\n onPreviewBack,\n positionStyles = DEFAULT_PREVIEW_POSITION_STYLES,\n}: {\n survey: Survey\n parentElement: HTMLElement\n previewPageIndex: number\n forceDisableHtml?: boolean\n onPreviewSubmit?: (res: string | string[] | number | null) => void\n onPreviewBack?: () => void\n posthog?: PostHog\n positionStyles?: JSX.CSSProperties\n}) => {\n const currentStyle = parentElement.querySelector('style[data-ph-survey-style]')\n if (currentStyle) {\n currentStyle.remove()\n }\n const stylesheet = getSurveyStylesheet()\n if (stylesheet) {\n parentElement.appendChild(stylesheet)\n addSurveyCSSVariablesToElement(parentElement, survey.type, survey.appearance)\n }\n render(\n <SurveyPopup\n survey={survey}\n forceDisableHtml={forceDisableHtml}\n style={positionStyles}\n onPreviewSubmit={onPreviewSubmit}\n onPreviewBack={onPreviewBack}\n previewPageIndex={previewPageIndex}\n removeSurveyFromFocus={() => {}}\n />,\n parentElement\n )\n}\n\nexport const renderFeedbackWidgetPreview = ({\n survey,\n root,\n forceDisableHtml,\n}: {\n survey: Survey\n root: HTMLElement\n forceDisableHtml?: boolean\n}) => {\n const stylesheet = getSurveyStylesheet()\n if (stylesheet) {\n root.appendChild(stylesheet)\n addSurveyCSSVariablesToElement(root, survey.type, survey.appearance)\n }\n\n render(<FeedbackWidget forceDisableHtml={forceDisableHtml} survey={survey} readOnly={true} />, root)\n}\n\n// This is the main exported function\nexport function generateSurveys(posthog: PostHog, isSurveysEnabled: boolean | undefined) {\n // NOTE: Important to ensure we never try and run surveys without a window environment\n if (!document || !window) {\n return\n }\n\n const surveyManager = new SurveyManager(posthog)\n if (posthog.config.disable_surveys_automatic_display) {\n logger.info('Surveys automatic display is disabled. Skipping call surveys and evaluate display logic.')\n return surveyManager\n }\n\n // NOTE: The `generateSurveys` function used to accept just a single parameter, without any `isSurveysEnabled` parameter.\n // To keep compatibility with old clients, we'll consider `undefined` the same as `true`\n if (isSurveysEnabled === false) {\n logger.info('There are no surveys to load or Surveys is disabled in the project settings.')\n return surveyManager\n }\n\n surveyManager.callSurveysAndEvaluateDisplayLogic(true)\n\n let intervalId: number | undefined\n\n const startInterval = () => {\n if (!isUndefined(intervalId)) {\n return\n }\n intervalId = setInterval(() => {\n surveyManager.callSurveysAndEvaluateDisplayLogic(false)\n }, 1000) as unknown as number\n }\n\n const stopInterval = () => {\n if (!isUndefined(intervalId)) {\n clearInterval(intervalId)\n intervalId = undefined\n }\n }\n\n startInterval()\n\n addEventListener(document, 'visibilitychange', () => {\n if (document.hidden) {\n stopInterval()\n } else {\n surveyManager.callSurveysAndEvaluateDisplayLogic(false)\n startInterval()\n }\n })\n\n return surveyManager\n}\n\ntype UseHideSurveyOnURLChangeProps = {\n survey: Pick<Survey, 'id' | 'conditions' | 'type' | 'appearance'>\n removeSurveyFromFocus?: (survey: SurveyWithTypeAndAppearance) => void\n setSurveyVisible: (visible: boolean) => void\n isPreviewMode?: boolean\n posthog?: PostHog\n}\n\n/**\n * This hook handles URL-based survey visibility after the initial mount.\n * The initial URL check is handled by the `getActiveMatchingSurveys` method in the `PostHogSurveys` class,\n * which ensures the URL matches before displaying a survey for the first time.\n * That is the method that is called every second to see if there's a matching survey.\n *\n * This separation of concerns means:\n * 1. Initial URL matching is done by `getActiveMatchingSurveys` before displaying the survey\n * 2. Subsequent URL changes are handled here to hide the survey as the user navigates\n */\nexport function useHideSurveyOnURLChange({\n survey,\n removeSurveyFromFocus = () => {},\n setSurveyVisible,\n isPreviewMode = false,\n posthog,\n}: UseHideSurveyOnURLChangeProps) {\n useEffect(() => {\n if (isPreviewMode || !survey.conditions?.url) {\n return\n }\n\n const checkUrlMatch = () => {\n const isSurveyTypeWidget = survey.type === SurveyType.Widget\n const doesSurveyMatchUrlCondition = doesSurveyUrlMatch(survey, posthog)\n const isSurveyWidgetTypeTab = survey.appearance?.widgetType === SurveyWidgetType.Tab && isSurveyTypeWidget\n\n if (doesSurveyMatchUrlCondition) {\n if (isSurveyWidgetTypeTab) {\n logger.info(`Showing survey ${survey.id} because it is a feedback button tab and URL matches`)\n setSurveyVisible(true)\n }\n return\n }\n\n logger.info(`Hiding survey ${survey.id} because URL does not match`)\n setSurveyVisible(false)\n return removeSurveyFromFocus(survey)\n }\n\n // Listen for browser back/forward browser history changes\n addEventListener(window, 'popstate', checkUrlMatch)\n // Listen for hash changes, for SPA frameworks that use hash-based routing\n // The hashchange event is fired when the fragment identifier of the URL has changed (the part of the URL beginning with and following the # symbol).\n addEventListener(window, 'hashchange', checkUrlMatch)\n\n // Listen for SPA navigation\n const originalPushState = window.history.pushState\n const originalReplaceState = window.history.replaceState\n\n window.history.pushState = function (...args) {\n originalPushState.apply(this, args)\n checkUrlMatch()\n }\n\n window.history.replaceState = function (...args) {\n originalReplaceState.apply(this, args)\n checkUrlMatch()\n }\n\n return () => {\n window.removeEventListener('popstate', checkUrlMatch)\n window.removeEventListener('hashchange', checkUrlMatch)\n window.history.pushState = originalPushState\n window.history.replaceState = originalReplaceState\n }\n }, [isPreviewMode, survey, removeSurveyFromFocus, setSurveyVisible, posthog])\n}\n\nexport function usePopupVisibility(\n survey: Survey,\n posthog: PostHog | undefined,\n millisecondDelay: number,\n isPreviewMode: boolean,\n removeSurveyFromFocus: (survey: SurveyWithTypeAndAppearance) => void,\n isPopup: boolean,\n surveyContainerRef?: RefObject<HTMLDivElement>,\n skipShownEvent?: boolean,\n surveyLanguage?: string | null\n) {\n const [isPopupVisible, setIsPopupVisible] = useState(\n isPreviewMode || millisecondDelay === 0 || survey.type === SurveyType.ExternalSurvey\n )\n const [isSurveySent, setIsSurveySent] = useState(false)\n\n const hidePopupWithViewTransition = () => {\n const removeDOMAndHidePopup = () => {\n if (isPopup) {\n removeSurveyFromFocus(survey)\n }\n setIsPopupVisible(false)\n }\n\n if (!document.startViewTransition) {\n removeDOMAndHidePopup()\n return\n }\n\n const transition = document.startViewTransition(() => {\n surveyContainerRef?.current?.remove()\n })\n\n transition.finished.then(() => {\n setTimeout(() => {\n removeDOMAndHidePopup()\n }, 100)\n })\n }\n\n const handleSurveyClosed = (event: CustomEvent) => {\n if (event.detail.surveyId !== survey.id) {\n return\n }\n hidePopupWithViewTransition()\n }\n\n useEffect(() => {\n if (!posthog) {\n logger.error('usePopupVisibility hook called without a PostHog instance.')\n return\n }\n if (isPreviewMode) {\n return\n }\n\n const handleSurveySent = (event: CustomEvent) => {\n if (event.detail.surveyId !== survey.id) {\n return\n }\n if (!survey.appearance?.displayThankYouMessage) {\n return hidePopupWithViewTransition()\n }\n setIsSurveySent(true)\n if (survey.appearance?.autoDisappear) {\n setTimeout(() => {\n hidePopupWithViewTransition()\n }, 5000)\n }\n }\n\n const showSurvey = () => {\n // check if the url is still matching, necessary for delayed surveys, as the URL may have changed\n if (!doesSurveyUrlMatch(survey, posthog)) {\n return\n }\n setIsPopupVisible(true)\n window.dispatchEvent(new Event('PHSurveyShown'))\n if (!skipShownEvent) {\n posthog.capture(SurveyEventName.SHOWN, {\n [SurveyEventProperties.SURVEY_NAME]: survey.name,\n [SurveyEventProperties.SURVEY_ID]: survey.id,\n [SurveyEventProperties.SURVEY_ITERATION]: survey.current_iteration,\n [SurveyEventProperties.SURVEY_ITERATION_START_DATE]: survey.current_iteration_start_date,\n ...(surveyLanguage && { [SurveyEventProperties.SURVEY_LANGUAGE]: surveyLanguage }),\n sessionRecordingUrl: posthog.get_session_replay_url?.(),\n })\n }\n try {\n localStorage.setItem('lastSeenSurveyDate', new Date().toISOString())\n } catch {\n // localStorage is not always available (e.g. in cross-origin iframes).\n }\n }\n\n addEventListener(window, 'PHSurveyClosed', handleSurveyClosed as EventListener)\n addEventListener(window, 'PHSurveySent', handleSurveySent as EventListener)\n\n if (millisecondDelay > 0) {\n // This path is only used for direct usage of SurveyPopup,\n // not for surveys managed by SurveyManager\n const timeoutId = setTimeout(showSurvey, millisecondDelay)\n return () => {\n clearTimeout(timeoutId)\n window.removeEventListener('PHSurveyClosed', handleSurveyClosed as EventListener)\n window.removeEventListener('PHSurveySent', handleSurveySent as EventListener)\n }\n } else {\n // This is the path used for surveys managed by SurveyManager\n showSurvey()\n return () => {\n window.removeEventListener('PHSurveyClosed', handleSurveyClosed as EventListener)\n window.removeEventListener('PHSurveySent', handleSurveySent as EventListener)\n }\n }\n }, [])\n\n useHideSurveyOnURLChange({\n survey,\n removeSurveyFromFocus,\n setSurveyVisible: setIsPopupVisible,\n isPreviewMode,\n posthog,\n })\n\n return { isPopupVisible, isSurveySent, setIsPopupVisible, hidePopupWithViewTransition }\n}\n\ninterface SurveyPopupProps {\n survey: Survey\n forceDisableHtml?: boolean\n posthog?: PostHog\n style?: JSX.CSSProperties\n previewPageIndex?: number | undefined\n removeSurveyFromFocus?: (survey: SurveyWithTypeAndAppearance) => void\n isPopup?: boolean\n onPreviewSubmit?: (res: string | string[] | number | null) => void\n onPreviewBack?: () => void\n onPopupSurveyDismissed?: () => void\n onCloseConfirmationMessage?: () => void\n /** Additional properties to include in all survey events */\n properties?: Properties\n /** if true, survey popup will only render if there is a thank-you message */\n isSurveyCompleted?: boolean\n /** When true, `survey shown` events will not be emitted automatically */\n skipShownEvent?: boolean\n /** The language that was applied to the survey. */\n surveyLanguage?: string | null\n}\n\nfunction getTabPositionStyles(position: SurveyTabPosition = SurveyTabPosition.Right): JSX.CSSProperties {\n switch (position) {\n case SurveyTabPosition.Top:\n return { top: '0', left: '50%', transform: 'translateX(-50%)' }\n case SurveyTabPosition.Left:\n return { top: '50%', left: '0', transform: 'rotate(90deg) translateY(-100%)', transformOrigin: 'left top' }\n case SurveyTabPosition.Bottom: // bottom center\n return { bottom: '0', left: '50%', transform: 'translateX(-50%)' }\n default:\n case SurveyTabPosition.Right:\n // not perfectly centered vertically, to avoid a \"breaking\" change\n return {\n top: '50%',\n right: '0',\n transform: 'rotate(-90deg) translateY(-100%)',\n transformOrigin: 'right top',\n }\n }\n}\n\nexport function SurveyPopup({\n survey,\n forceDisableHtml,\n posthog,\n style = {},\n previewPageIndex,\n removeSurveyFromFocus = () => {},\n isPopup = true,\n onPreviewSubmit = () => {},\n onPreviewBack = () => {},\n onPopupSurveyDismissed = () => {},\n onCloseConfirmationMessage = () => {},\n properties,\n isSurveyCompleted,\n skipShownEvent,\n surveyLanguage,\n}: SurveyPopupProps) {\n const surveyContainerRef = useRef<HTMLDivElement>(null)\n const isPreviewMode = Number.isInteger(previewPageIndex)\n // NB: The client-side code passes the millisecondDelay in seconds, but setTimeout expects milliseconds, so we multiply by 1000\n const surveyPopupDelayMilliseconds = survey.appearance?.surveyPopupDelaySeconds\n ? survey.appearance.surveyPopupDelaySeconds * 1000\n : 0\n const { isPopupVisible, isSurveySent, hidePopupWithViewTransition } = usePopupVisibility(\n survey,\n posthog,\n surveyPopupDelayMilliseconds,\n isPreviewMode,\n removeSurveyFromFocus,\n isPopup,\n surveyContainerRef,\n skipShownEvent,\n surveyLanguage\n )\n\n /**\n * show confirmation if:\n * 1) isSurveySent is true (completed via normal flow)\n * 2) we're on the preview page for it\n * 3) the target start question (from prefill) is >= the length of the survey\n */\n const shouldShowConfirmation =\n isSurveySent || previewPageIndex === survey.questions.length || isSurveyCompleted === true\n\n const surveyContextValue = useMemo(() => {\n const getInProgressSurvey = getInProgressSurveyState(survey)\n const surveySubmissionId = getInProgressSurvey?.surveySubmissionId || uuidv7()\n return {\n isPreviewMode,\n previewPageIndex: previewPageIndex,\n onPopupSurveyDismissed: () => {\n if (surveyLanguage) {\n dismissedSurveyEvent(survey, posthog, isPreviewMode, surveyLanguage)\n } else {\n dismissedSurveyEvent(survey, posthog, isPreviewMode)\n }\n onPopupSurveyDismissed()\n },\n isPopup: isPopup || false,\n surveySubmissionId,\n onPreviewSubmit,\n onPreviewBack,\n posthog,\n properties,\n surveyLanguage,\n }\n }, [\n isPreviewMode,\n previewPageIndex,\n isPopup,\n posthog,\n survey,\n onPopupSurveyDismissed,\n onPreviewSubmit,\n onPreviewBack,\n properties,\n surveyLanguage,\n ])\n\n if (!isPopupVisible) {\n return null\n }\n\n return (\n <SurveyContext.Provider value={surveyContextValue}>\n <div\n className=\"ph-survey\"\n style={{\n ...getPopoverPosition(survey.type, survey.appearance?.position, survey.appearance?.widgetType),\n ...style,\n }}\n ref={surveyContainerRef}\n >\n {!shouldShowConfirmation ? (\n <Questions survey={survey} forceDisableHtml={!!forceDisableHtml} posthog={posthog} />\n ) : (\n <ConfirmationMessage\n header={survey.appearance?.thankYouMessageHeader || 'Thank you!'}\n description={survey.appearance?.thankYouMessageDescription || ''}\n forceDisableHtml={!!forceDisableHtml}\n contentType={survey.appearance?.thankYouMessageDescriptionContentType}\n appearance={survey.appearance || defaultSurveyAppearance}\n onClose={() => {\n hidePopupWithViewTransition()\n onCloseConfirmationMessage()\n }}\n />\n )}\n </div>\n </SurveyContext.Provider>\n )\n}\n\nexport function Questions({\n survey,\n forceDisableHtml,\n posthog,\n}: {\n survey: Survey\n forceDisableHtml: boolean\n posthog?: PostHog\n}) {\n // Initialize responses from localStorage or empty object\n const [questionsResponses, setQuestionsResponses] = useState(() => {\n const inProgressSurveyData = getInProgressSurveyState(survey)\n if (inProgressSurveyData?.responses) {\n logger.info('Survey is already in progress, filling in initial responses')\n }\n return inProgressSurveyData?.responses || {}\n })\n const {\n previewPageIndex,\n onPopupSurveyDismissed,\n isPopup,\n onPreviewSubmit,\n onPreviewBack,\n surveySubmissionId,\n isPreviewMode,\n properties,\n surveyLanguage,\n } = useContext(SurveyContext)\n const [currentQuestionIndex, setCurrentQuestionIndex] = useState(() => {\n const inProgressSurveyData = getInProgressSurveyState(survey)\n return previewPageIndex || inProgressSurveyData?.lastQuestionIndex || 0\n })\n const [visitedIndices, setVisitedIndices] = useState<number[]>(() => {\n const inProgressSurveyData = getInProgressSurveyState(survey)\n return inProgressSurveyData?.visitedIndices ?? []\n })\n const surveyQuestions = useMemo(() => getDisplayOrderQuestions(survey), [survey])\n\n // Sync preview state\n useEffect(() => {\n if (isPreviewMode && !isUndefined(previewPageIndex)) {\n setCurrentQuestionIndex(previewPageIndex)\n }\n }, [previewPageIndex, isPreviewMode])\n\n const onNextButtonClick = ({\n res,\n displayQuestionIndex,\n questionId,\n }: {\n res: string | string[] | number | null\n displayQuestionIndex: number\n questionId?: string\n }) => {\n if (!posthog) {\n logger.error('onNextButtonClick called without a PostHog instance.')\n return\n }\n\n if (!questionId) {\n logger.error('onNextButtonClick called without a questionId.')\n return\n }\n\n const responseKey = getSurveyResponseKey(questionId)\n\n const newResponses = { ...questionsResponses, [responseKey]: res }\n setQuestionsResponses(newResponses)\n\n const nextStep = getNextSurveyStep(survey, displayQuestionIndex, res)\n const isSurveyCompleted = nextStep === SurveyQuestionBranchingType.End\n const newVisitedIndices = [...visitedIndices, displayQuestionIndex]\n\n if (!isSurveyCompleted) {\n setVisitedIndices(newVisitedIndices)\n setCurrentQuestionIndex(nextStep)\n setInProgressSurveyState(survey, {\n surveySubmissionId: surveySubmissionId,\n responses: newResponses,\n lastQuestionIndex: nextStep,\n visitedIndices: newVisitedIndices,\n surveyLanguage,\n })\n }\n\n // If partial responses are enabled, send the survey sent event with with the responses,\n // otherwise only send the event when the survey is completed\n if (survey.enable_partial_responses || isSurveyCompleted) {\n // Only emit responses for questions actually on the path the user took. This prunes\n // ghost answers from branches the user abandoned by backing up and choosing differently.\n const visitedResponseKeys = new Set(\n newVisitedIndices\n .map((i) => surveyQuestions[i]?.id)\n .filter((id): id is string => !!id)\n .map((id) => getSurveyResponseKey(id))\n )\n const responsesOnPath = Object.fromEntries(\n Object.entries(newResponses).filter(([key]) => visitedResponseKeys.has(key))\n )\n sendSurveyEvent({\n responses: responsesOnPath,\n survey,\n surveySubmissionId,\n isSurveyCompleted,\n posthog,\n properties,\n surveyLanguage,\n })\n }\n }\n\n const onBackButtonClick = () => {\n // In preview mode the parent owns navigation (via previewPageIndex), so delegate to it.\n if (isPreviewMode) {\n onPreviewBack()\n return\n }\n if (visitedIndices.length === 0) {\n return\n }\n const previousIndex = visitedIndices[visitedIndices.length - 1]\n const newVisitedIndices = visitedIndices.slice(0, -1)\n setVisitedIndices(newVisitedIndices)\n setCurrentQuestionIndex(previousIndex)\n setInProgressSurveyState(survey, {\n surveySubmissionId,\n responses: questionsResponses,\n lastQuestionIndex: previousIndex,\n visitedIndices: newVisitedIndices,\n surveyLanguage,\n })\n }\n\n const canGoBack =\n !!survey.appearance?.allowGoBack && (isPreviewMode ? (previewPageIndex ?? 0) > 0 : visitedIndices.length > 0)\n\n const currentQuestion = surveyQuestions.at(currentQuestionIndex)\n\n if (!currentQuestion) {\n return null\n }\n\n const renderCancelButton = isPopup && survey.appearance?.hideCancelButton !== true\n\n return (\n <form className=\"survey-form\" name=\"surveyForm\">\n {renderCancelButton && (\n <Cancel\n onClick={() => {\n onPopupSurveyDismissed()\n }}\n />\n )}\n <div className=\"survey-box\" data-question-index={currentQuestionIndex}>\n {getQuestionComponent({\n question: currentQuestion,\n forceDisableHtml,\n displayQuestionIndex: currentQuestionIndex,\n appearance: survey.appearance || defaultSurveyAppearance,\n onSubmit: (res) =>\n onNextButtonClick({\n res,\n displayQuestionIndex: currentQuestionIndex,\n questionId: currentQuestion.id,\n }),\n onPreviewSubmit,\n initialValue: currentQuestion.id\n ? questionsResponses[getSurveyResponseKey(currentQuestion.id)]\n : undefined,\n canGoBack,\n onBack: onBackButtonClick,\n })}\n </div>\n </form>\n )\n}\n\nexport function FeedbackWidget({\n survey,\n forceDisableHtml,\n posthog,\n readOnly,\n surveyLanguage,\n}: {\n survey: Survey\n forceDisableHtml?: boolean\n posthog?: PostHog\n readOnly?: boolean\n surveyLanguage?: string | null\n}): JSX.Element | null {\n const [isFeedbackButtonVisible, setIsFeedbackButtonVisible] = useState(true)\n const [showSurvey, setShowSurvey] = useState(false)\n const [styleOverrides, setStyleOverrides] = useState<JSX.CSSProperties>({})\n\n const toggleSurvey = () => {\n setShowSurvey(!showSurvey)\n }\n\n useEffect(() => {\n if (!posthog) {\n logger.error('FeedbackWidget called without a PostHog instance.')\n return\n }\n if (readOnly) {\n return\n }\n\n if (survey.appearance?.widgetType === 'tab') {\n setStyleOverrides({\n top: '50%',\n bottom: 'auto',\n })\n }\n const handleShowSurvey = (event: Event) => {\n const customEvent = event as CustomEvent\n // Check if the event is for this specific survey instance\n if (customEvent.detail?.surveyId === survey.id) {\n logger.info(`Received show event for feedback button survey ${survey.id}`)\n setStyleOverrides(customEvent.detail.position || {})\n toggleSurvey()\n }\n }\n\n addEventListener(window, DISPATCH_FEEDBACK_WIDGET_EVENT, handleShowSurvey)\n\n // Cleanup listener on component unmount\n return () => {\n window.removeEventListener(DISPATCH_FEEDBACK_WIDGET_EVENT, handleShowSurvey)\n }\n }, [\n posthog,\n readOnly,\n survey.id,\n survey.appearance?.widgetType,\n survey.appearance?.widgetSelector,\n survey.appearance?.borderColor,\n ])\n\n useHideSurveyOnURLChange({\n survey,\n setSurveyVisible: setIsFeedbackButtonVisible,\n posthog,\n })\n\n if (!isFeedbackButtonVisible) {\n return null\n }\n\n const resetShowSurvey = () => {\n // hide the feedback button after answering or closing the survey if it's not always show\n if (survey.schedule !== SurveySchedule.Always) {\n setIsFeedbackButtonVisible(false)\n }\n // important so our view transition has time to run\n setTimeout(() => {\n setShowSurvey(false)\n }, 200)\n }\n\n return (\n <Fragment>\n {survey.appearance?.widgetType === 'tab' && (\n <button\n className={`ph-survey-widget-tab ${survey.appearance?.tabPosition === SurveyTabPosition.Top ? 'widget-tab-top' : ''}`}\n onClick={toggleSurvey}\n disabled={readOnly}\n style={getTabPositionStyles(survey.appearance?.tabPosition)}\n >\n {survey.appearance?.widgetLabel || ''}\n </button>\n )}\n {showSurvey && (\n <SurveyPopup\n posthog={posthog}\n survey={survey}\n forceDisableHtml={forceDisableHtml}\n style={styleOverrides}\n onPopupSurveyDismissed={resetShowSurvey}\n onCloseConfirmationMessage={resetShowSurvey}\n surveyLanguage={surveyLanguage}\n />\n )}\n </Fragment>\n )\n}\n\ninterface GetQuestionComponentProps extends CommonQuestionProps {\n question: SurveyQuestion\n displayQuestionIndex: number\n}\n\nconst getQuestionComponent = ({\n question,\n forceDisableHtml,\n displayQuestionIndex,\n appearance,\n onSubmit,\n onPreviewSubmit,\n initialValue,\n canGoBack,\n onBack,\n}: GetQuestionComponentProps): JSX.Element | null => {\n const baseProps = {\n forceDisableHtml,\n appearance,\n onPreviewSubmit: (res: string | string[] | number | null) => {\n onPreviewSubmit(res)\n },\n onSubmit: (res: string | string[] | number | null) => {\n onSubmit(res)\n },\n initialValue,\n displayQuestionIndex,\n canGoBack,\n onBack,\n }\n\n switch (question.type) {\n case SurveyQuestionType.Open:\n return <OpenTextQuestion {...baseProps} question={question} key={question.id} />\n case SurveyQuestionType.Link:\n return <LinkQuestion {...baseProps} question={question} key={question.id} />\n case SurveyQuestionType.Rating:\n return <RatingQuestion {...baseProps} question={question} key={question.id} />\n case SurveyQuestionType.SingleChoice:\n case SurveyQuestionType.MultipleChoice:\n return <MultipleChoiceQuestion {...baseProps} question={question} key={question.id} />\n default:\n logger.error(`Unsupported question type: ${(question as any).type}`)\n return null\n }\n}\n","import { Survey, SurveyQuestion, SurveyQuestionBranchingType, SurveyQuestionType } from '../posthog-surveys-types'\nimport { getSurveyResponseKey } from '../extensions/surveys/surveys-extension-utils'\nimport { logger } from './logger'\nimport { isUndefined } from '@posthog/core'\nimport { getNextSurveyStep } from './survey-branching'\n\n/**\n * Extracted URL prefill parameters by question index\n */\nexport interface PrefillParams {\n [questionIndex: number]: string[]\n}\n\n/**\n * Extract prefill parameters from URL search string\n * Format: ?q0=1&q1=8&q2=0&q2=2&auto_submit=true\n * NOTE: Manual parsing for IE11/op_mini compatibility (no URLSearchParams)\n */\nexport function extractPrefillParamsFromUrl(searchString: string): {\n params: PrefillParams\n autoSubmit: boolean\n} {\n const params: PrefillParams = {}\n let autoSubmit = false\n\n // Remove leading ? if present\n const cleanSearch = searchString.replace(/^\\?/, '')\n if (!cleanSearch) {\n return { params, autoSubmit }\n }\n\n // Split by & to get key-value pairs\n const pairs = cleanSearch.split('&')\n\n for (const pair of pairs) {\n const [key, value] = pair.split('=')\n if (!key || isUndefined(value)) {\n continue\n }\n\n const decodedKey = decodeURIComponent(key)\n const decodedValue = decodeURIComponent(value)\n\n // Check for auto_submit parameter\n if (decodedKey === 'auto_submit' && decodedValue === 'true') {\n autoSubmit = true\n continue\n }\n\n // Check for question parameters (q0, q1, etc.)\n const match = decodedKey.match(/^q(\\d+)$/)\n if (match) {\n const questionIndex = parseInt(match[1], 10)\n if (!params[questionIndex]) {\n params[questionIndex] = []\n }\n params[questionIndex].push(decodedValue)\n }\n }\n\n return { params, autoSubmit }\n}\n\n/**\n * Convert URL prefill values to SDK response format\n */\nexport function convertPrefillToResponses(survey: Survey, prefillParams: PrefillParams): Record<string, any> {\n const responses: Record<string, any> = {}\n\n survey.questions.forEach((question: SurveyQuestion, index: number) => {\n if (!prefillParams[index] || !question.id) {\n return\n }\n\n const values = prefillParams[index]\n const responseKey = getSurveyResponseKey(question.id)\n\n try {\n switch (question.type) {\n case SurveyQuestionType.SingleChoice: {\n if (!question.choices || question.choices.length === 0) {\n logger.warn(`[Survey Prefill] Question ${index} has no choices`)\n return\n }\n const choiceIndex = parseInt(values[0], 10)\n if (isNaN(choiceIndex) || choiceIndex < 0 || choiceIndex >= question.choices.length) {\n logger.warn(`[Survey Prefill] Invalid choice index for q${index}: ${values[0]}`)\n return\n }\n responses[responseKey] = question.choices[choiceIndex]\n break\n }\n\n case SurveyQuestionType.MultipleChoice: {\n if (!question.choices || question.choices.length === 0) {\n logger.warn(`[Survey Prefill] Question ${index} has no choices`)\n return\n }\n const choiceIndices = values\n .map((v) => parseInt(v, 10))\n .filter((i) => !isNaN(i) && i >= 0 && i < question.choices.length)\n\n if (choiceIndices.length === 0) {\n logger.warn(`[Survey Prefill] No valid choices for q${index}`)\n return\n }\n\n // Remove duplicates and map to choice values\n const uniqueChoices = [...new Set(choiceIndices.map((i) => question.choices[i]))]\n if (uniqueChoices.length < choiceIndices.length) {\n logger.warn(`[Survey Prefill] Removed duplicate choices for q${index}`)\n }\n responses[responseKey] = uniqueChoices\n break\n }\n\n case SurveyQuestionType.Rating: {\n const rating = parseInt(values[0], 10)\n const scale = question.scale || 10\n\n if (isNaN(rating) || rating < 0 || rating > scale) {\n logger.warn(`[Survey Prefill] Invalid rating for q${index}: ${values[0]} (scale: 0-${scale})`)\n return\n }\n responses[responseKey] = rating\n break\n }\n\n default:\n logger.info(`[Survey Prefill] Question type ${question.type} does not support prefill`)\n }\n } catch (error) {\n logger.error(`[Survey Prefill] Error converting q${index}:`, error)\n }\n })\n\n return responses\n}\n\n/**\n * Calculate which question index to start at based on prefilled questions.\n * Advances past consecutive prefilled questions (starting from index 0)\n * that have skipSubmitButton enabled, respecting any branching logic configured\n * on those questions.\n *\n * @param survey - The full survey object (needed for branching logic)\n * @param prefilledIndices - Array of question indices that have been prefilled\n * @param responses - Map of response keys to response values\n * @returns Object with startQuestionIndex and map of questions which have been skipped\n */\nexport function calculatePrefillStartIndex(\n survey: Survey,\n prefilledIndices: number[],\n responses: Record<string, any>\n): { startQuestionIndex: number; skippedResponses: Record<string, any> } {\n let currentIndex = 0\n const skippedResponses: Record<string, any> = {}\n\n const MAX_ITERATIONS = survey.questions.length + 1\n const iterations = 0\n while (currentIndex < survey.questions.length && iterations < MAX_ITERATIONS) {\n // Stop if current question is not prefilled\n if (!prefilledIndices.includes(currentIndex)) {\n break\n }\n\n const question = survey.questions[currentIndex]\n\n // Only advance if the prefilled question has skipSubmitButton\n if (!question || !('skipSubmitButton' in question) || !question.skipSubmitButton) {\n // Show question if skipSubmitButton is false, even if prefilled\n break\n }\n\n // Record the skipped response\n if (question.id) {\n const responseKey = getSurveyResponseKey(question.id)\n if (!isUndefined(responses[responseKey])) {\n skippedResponses[responseKey] = responses[responseKey]\n }\n }\n\n // Use branching logic to determine the next question\n const response = question.id ? responses[getSurveyResponseKey(question.id)] : null\n const nextStep = getNextSurveyStep(survey, currentIndex, response)\n\n if (nextStep === SurveyQuestionBranchingType.End) {\n // Survey is complete - return questions.length to indicate completion\n return { startQuestionIndex: survey.questions.length, skippedResponses }\n }\n\n // Move to the next question (respecting branching)\n currentIndex = nextStep\n }\n\n return { startQuestionIndex: currentIndex, skippedResponses }\n}\n","import { generateSurveys } from '../extensions/surveys'\n\nimport { assignableWindow } from '../utils/globals'\n\nassignableWindow.__PosthogExtensions__ = assignableWindow.__PosthogExtensions__ || {}\nassignableWindow.__PosthogExtensions__.generateSurveys = generateSurveys\n\n// this used to be directly on window, but we moved it to __PosthogExtensions__\n// it is still on window for backwards compatibility\nassignableWindow.extendPostHogWithSurveys = generateSurveys\n\nexport default generateSurveys\n","import { assignableWindow } from '../utils/globals'\nimport { PostHog } from '../posthog-core'\nimport { isArray, isBoolean, isFunction, isNull, isNumber, isObject } from '@posthog/core'\nimport type { LogSeverityLevel } from '@posthog/types'\n\nconst LOG_BODY_SIZE_LIMIT = 10000\nconst LOG_ATTRIBUTES_LIMIT = 50\n\ntype StringifyBudget = {\n remaining: number\n truncated: boolean\n}\n\ntype AttributeCollector = {\n result: Record<string, any>\n keysRemaining: number\n sizeRemaining: number\n truncated: boolean\n seen: WeakSet<object>\n}\n\nconst appendWithLimit = (parts: string[], text: string, budget: StringifyBudget): boolean => {\n if (budget.remaining <= 0) {\n budget.truncated = true\n return false\n }\n\n if (text.length <= budget.remaining) {\n parts.push(text)\n budget.remaining -= text.length\n return true\n }\n\n parts.push(text.slice(0, budget.remaining))\n budget.remaining = 0\n budget.truncated = true\n return false\n}\n\nconst stringifyStringWithLimit = (value: string, parts: string[], budget: StringifyBudget): boolean => {\n const serialized = JSON.stringify(value)\n if (serialized.length <= budget.remaining) {\n return appendWithLimit(parts, serialized, budget)\n }\n\n budget.truncated = true\n if (budget.remaining < 2) {\n return false\n }\n\n let low = 0\n let high = Math.min(value.length, budget.remaining - 2)\n while (low < high) {\n const mid = Math.ceil((low + high) / 2)\n if (JSON.stringify(value.slice(0, mid)).length <= budget.remaining) {\n low = mid\n } else {\n high = mid - 1\n }\n }\n\n return appendWithLimit(parts, JSON.stringify(value.slice(0, low)), budget)\n}\n\nconst isJSONSerializablePrimitive = (value: any): boolean =>\n typeof value !== 'undefined' &&\n typeof value !== 'function' &&\n typeof value !== 'symbol' &&\n typeof value !== 'bigint'\n\nconst isNumberOrBoolean = (value: any): boolean => {\n try {\n return isNumber(value) || isBoolean(value)\n } catch {\n return false\n }\n}\n\nconst collectAttributeValue = (key: string, value: any, collector: AttributeCollector): void => {\n if (collector.truncated) {\n return\n }\n\n collector.keysRemaining -= 1\n collector.sizeRemaining -= String(value).length + key.length\n if (collector.keysRemaining <= 0 || collector.sizeRemaining <= 0) {\n collector.truncated = true\n collector.result['attributes_truncated'] = true\n return\n }\n\n collector.result[key] = value\n}\n\nconst collectFlattenedAttributes = (value: any, key: string, collector: AttributeCollector): void => {\n if (collector.truncated) {\n return\n }\n\n if (isObject(value)) {\n if (collector.seen.has(value)) {\n collectAttributeValue(key || 'circular', '[Circular]', collector)\n return\n }\n collector.seen.add(value)\n\n try {\n for (const childKey in value) {\n try {\n if (!Object.prototype.hasOwnProperty.call(value, childKey)) {\n continue\n }\n const childValue = value[childKey]\n collectFlattenedAttributes(childValue, key ? `${key}.${childKey}` : childKey, collector)\n if (collector.truncated) {\n return\n }\n } catch {\n continue\n }\n }\n } catch {\n // we'll omit this object's properties considering we can't enumerate them\n }\n return\n }\n\n collectAttributeValue(key, value, collector)\n}\n\nconst stringifyValueWithLimit = (\n value: any,\n parts: string[],\n budget: StringifyBudget,\n seen: WeakSet<object>,\n inArray = false,\n attributeCollector?: AttributeCollector\n): boolean => {\n if (!isJSONSerializablePrimitive(value)) {\n return inArray ? appendWithLimit(parts, 'null', budget) : true\n }\n\n if (isNull(value) || isNumberOrBoolean(value)) {\n return appendWithLimit(parts, JSON.stringify(value), budget)\n }\n\n if (typeof value === 'string') {\n return stringifyStringWithLimit(value, parts, budget)\n }\n\n if (!isObject(value) && !isArray(value)) {\n return appendWithLimit(parts, JSON.stringify(value), budget)\n }\n\n if (seen.has(value)) {\n return stringifyStringWithLimit('[Circular]', parts, budget)\n }\n seen.add(value)\n\n try {\n const toJSON = (value as any).toJSON\n if (isFunction(toJSON)) {\n return stringifyValueWithLimit(toJSON.call(value), parts, budget, seen, inArray)\n }\n } catch {\n // If toJSON can't be read or throws, fall through to safe property enumeration.\n }\n\n try {\n const objectTag = Object.prototype.toString.call(value)\n if (objectTag === '[object String]') {\n return stringifyStringWithLimit(String(value.valueOf()), parts, budget)\n }\n\n if (objectTag === '[object Number]' || objectTag === '[object Boolean]') {\n return appendWithLimit(parts, JSON.stringify(value.valueOf()), budget)\n }\n } catch {\n // If Object.prototype.toString or valueOf throws, fall through to safe property enumeration.\n }\n\n if (value instanceof Error) {\n const errorObject: Record<string, any> = {}\n try {\n for (const key in value) {\n if (Object.prototype.hasOwnProperty.call(value, key)) {\n errorObject[key] = value[key as keyof Error]\n }\n }\n } catch {}\n try {\n errorObject.name = value.name\n } catch {}\n try {\n errorObject.message = value.message\n } catch {}\n try {\n errorObject.stack = value.stack\n } catch {}\n return stringifyValueWithLimit(errorObject, parts, budget, seen, inArray, attributeCollector)\n }\n\n if (isArray(value)) {\n if (!appendWithLimit(parts, '[', budget)) {\n return false\n }\n for (let i = 0; i < value.length; i++) {\n if (i > 0 && !appendWithLimit(parts, ',', budget)) {\n return false\n }\n let item\n try {\n item = value[i]\n } catch {\n item = undefined\n }\n if (!stringifyValueWithLimit(item, parts, budget, seen, true)) {\n return false\n }\n }\n return appendWithLimit(parts, ']', budget)\n }\n\n if (!appendWithLimit(parts, '{', budget)) {\n return false\n }\n let isFirst = true\n try {\n for (const key in value) {\n if (!Object.prototype.hasOwnProperty.call(value, key)) {\n continue\n }\n if (budget.remaining <= 0) {\n budget.truncated = true\n return false\n }\n\n let propertyValue\n try {\n propertyValue = value[key]\n } catch {\n continue\n }\n if (attributeCollector) {\n try {\n collectFlattenedAttributes(propertyValue, key, attributeCollector)\n } catch {\n // we'll omit this object's attributes considering we can't read them safely\n }\n }\n\n if (!isJSONSerializablePrimitive(propertyValue)) {\n continue\n }\n\n const propertyPrefix = `${isFirst ? '' : ','}${JSON.stringify(key)}:`\n if (propertyPrefix.length >= budget.remaining) {\n budget.truncated = true\n return false\n }\n\n const partsBeforeProperty = parts.length\n const remainingBeforeProperty = budget.remaining\n const truncatedBeforeProperty = budget.truncated\n if (!appendWithLimit(parts, propertyPrefix, budget)) {\n return false\n }\n\n const partsBeforeValue = parts.length\n const serialized = stringifyValueWithLimit(propertyValue, parts, budget, seen, false)\n const truncatedAfterValue = budget.truncated\n if (parts.length === partsBeforeValue) {\n parts.length = partsBeforeProperty\n budget.remaining = remainingBeforeProperty\n budget.truncated = serialized ? truncatedBeforeProperty : truncatedAfterValue\n if (!serialized) {\n return false\n }\n continue\n }\n\n isFirst = false\n if (!serialized) {\n return false\n }\n }\n } catch {\n // we'll omit this object's properties considering we can't enumerate them\n }\n return appendWithLimit(parts, '}', budget)\n}\n\nconst stringifyArgsSafely = (\n args: any[],\n sizeLimit: number\n): { body: string; truncated: boolean; attributes: Record<string, any> } => {\n const parts: string[] = []\n const budget = { remaining: sizeLimit, truncated: false }\n const attributeCollector = isObject(args[0])\n ? {\n result: {} as Record<string, any>,\n keysRemaining: LOG_ATTRIBUTES_LIMIT,\n sizeRemaining: LOG_BODY_SIZE_LIMIT,\n truncated: false,\n seen: new WeakSet<object>([args[0]]),\n }\n : undefined\n\n for (let i = 0; i < args.length; i++) {\n if (i > 0 && !appendWithLimit(parts, ' ', budget)) {\n break\n }\n if (\n !stringifyValueWithLimit(\n args[i],\n parts,\n budget,\n new WeakSet<object>(),\n false,\n i === 0 ? attributeCollector : undefined\n )\n ) {\n break\n }\n }\n\n return {\n body: parts.join('') + (budget.truncated ? '...' : ''),\n truncated: budget.truncated,\n attributes: attributeCollector?.result || {},\n }\n}\n\ntype ConsoleLevel = 'debug' | 'log' | 'warn' | 'error' | 'info'\n\n// Console method → OTLP severity level. `log` and `info` both map to `info`;\n// the originating method is preserved separately via the `log.source` attribute.\nconst LEVEL_MAP: Record<ConsoleLevel, LogSeverityLevel> = {\n debug: 'debug',\n log: 'info',\n warn: 'warn',\n error: 'error',\n info: 'info',\n}\n\nconst initializeLogs = (posthog: PostHog) => {\n // `host` is carried here because the core SDK context has no equivalent. Session\n // attributes (window.id, sessionStartTimestamp, lastActivityTimestamp) are added\n // downstream by the core pipeline from the SDK context, alongside sessionId.\n const attributes: Record<string, string> = { host: assignableWindow.location.host }\n\n for (const level of Object.keys(LEVEL_MAP) as ConsoleLevel[]) {\n const logWrapper =\n (originalConsoleLog: any) =>\n (...args: any[]) => {\n try {\n if (args.length > 0 && posthog.is_capturing()) {\n const {\n body,\n truncated,\n attributes: flattenedAttributes,\n } = stringifyArgsSafely(args, LOG_BODY_SIZE_LIMIT)\n const logAttributes = {\n ...attributes,\n ...(truncated ? { body_truncated: 'true' } : {}),\n }\n // The core pipeline adds posthogDistinctId and url.full from the SDK context.\n posthog.logs?._captureConsoleLog({\n level: LEVEL_MAP[level],\n body,\n attributes: {\n 'log.source': `console.${level}`,\n ...logAttributes,\n ...flattenedAttributes,\n },\n })\n }\n } catch {\n // Capture must never break the page's own console output, so the\n // real console call below always runs even if capture throws.\n } finally {\n originalConsoleLog.apply(assignableWindow.console, args)\n }\n }\n\n const originalConsoleLog = assignableWindow.console[level]\n assignableWindow.console[level] = logWrapper(originalConsoleLog)\n }\n}\n\nassignableWindow.__PosthogExtensions__ = assignableWindow.__PosthogExtensions__ || {}\nassignableWindow.__PosthogExtensions__.logs = { initializeLogs }\n","import { ERROR_TRACKING_CAPTURE_EXTENSION_EXCEPTIONS, ERROR_TRACKING_SUPPRESSION_RULES } from './constants'\nimport { Extension } from './extensions/types'\nimport { PostHog } from './posthog-core'\nimport { CaptureResult, ErrorTrackingSuppressionRule, Properties, RemoteConfig } from './types'\nimport { createLogger } from './utils/logger'\nimport { propertyComparisons } from './utils/property-utils'\nimport { isString, isArray, isObject, ErrorTracking, isNullish } from '@posthog/core'\n\nconst logger = createLogger('[Error tracking]')\n\nexport function buildErrorPropertiesBuilder() {\n return new ErrorTracking.ErrorPropertiesBuilder(\n [\n new ErrorTracking.DOMExceptionCoercer(),\n new ErrorTracking.PromiseRejectionEventCoercer(),\n new ErrorTracking.ErrorEventCoercer(),\n new ErrorTracking.ErrorCoercer(),\n new ErrorTracking.EventCoercer(),\n new ErrorTracking.ObjectCoercer(),\n new ErrorTracking.StringCoercer(),\n new ErrorTracking.PrimitiveCoercer(),\n ],\n ErrorTracking.createDefaultStackParser()\n )\n}\nexport class PostHogExceptions implements Extension {\n private readonly _instance: PostHog\n private _suppressionRules: ErrorTrackingSuppressionRule[] = []\n private _errorPropertiesBuilder: ErrorTracking.ErrorPropertiesBuilder = buildErrorPropertiesBuilder()\n private _exceptionStepsBuffer: ErrorTracking.ExceptionStepsBuffer\n private _exceptionStepsConfig: ErrorTracking.ResolvedExceptionStepsConfig\n\n constructor(instance: PostHog) {\n this._instance = instance\n this._suppressionRules = this._instance.persistence?.get_property(ERROR_TRACKING_SUPPRESSION_RULES) ?? []\n this._exceptionStepsConfig = ErrorTracking.resolveExceptionStepsConfig(this._getExceptionStepsConfig())\n this._exceptionStepsBuffer = new ErrorTracking.ExceptionStepsBuffer(this._exceptionStepsConfig)\n }\n\n onConfigChange() {\n this._exceptionStepsConfig = ErrorTracking.resolveExceptionStepsConfig(this._getExceptionStepsConfig())\n this._exceptionStepsBuffer.setConfig(this._exceptionStepsConfig)\n }\n\n onRemoteConfig(response: RemoteConfig) {\n if (!('errorTracking' in response)) {\n return\n }\n\n const suppressionRules = response.errorTracking?.suppressionRules ?? []\n const captureExtensionExceptions = response.errorTracking?.captureExtensionExceptions\n\n // store this in-memory in case persistence is disabled\n this._suppressionRules = suppressionRules\n\n if (this._instance.persistence) {\n this._instance.persistence.register({\n [ERROR_TRACKING_SUPPRESSION_RULES]: this._suppressionRules,\n [ERROR_TRACKING_CAPTURE_EXTENSION_EXCEPTIONS]: captureExtensionExceptions,\n })\n }\n }\n\n private get _captureExtensionExceptions() {\n const enabled_server_side = !!this._instance.get_property(ERROR_TRACKING_CAPTURE_EXTENSION_EXCEPTIONS)\n const enabled_client_side = this._instance.config.error_tracking.captureExtensionExceptions\n return enabled_client_side ?? enabled_server_side ?? false\n }\n\n buildProperties(\n input: unknown,\n metadata?: { handled?: boolean; syntheticException?: Error }\n ): ErrorTracking.ErrorProperties {\n return this._errorPropertiesBuilder.buildFromUnknown(input, {\n syntheticException: metadata?.syntheticException,\n mechanism: {\n handled: metadata?.handled,\n },\n })\n }\n\n addExceptionStep(message: string, properties?: Properties): void {\n if (!this._exceptionStepsConfig.enabled) {\n return\n }\n\n try {\n if (!isString(message) || message.trim().length === 0) {\n logger.warn('Ignoring exception step because message must be a non-empty string')\n return\n }\n\n const userProperties = this._coerceExceptionStepProperties(properties)\n\n const { sanitizedProperties, droppedKeys } = ErrorTracking.stripReservedExceptionStepFields(userProperties)\n\n if (droppedKeys.length > 0) {\n logger.warn('Ignoring reserved exception step fields', { droppedKeys })\n }\n\n this._exceptionStepsBuffer.add({\n [ErrorTracking.EXCEPTION_STEP_INTERNAL_FIELDS.MESSAGE]: message,\n [ErrorTracking.EXCEPTION_STEP_INTERNAL_FIELDS.TIMESTAMP]: new Date().toISOString(),\n ...sanitizedProperties,\n })\n } catch (error) {\n logger.error('Failed to add exception step. Ignoring breadcrumb.', error)\n }\n }\n\n sendExceptionEvent(properties: Properties): CaptureResult | undefined {\n try {\n const exceptionList = properties.$exception_list\n\n if (this._isExceptionList(exceptionList)) {\n if (this._matchesSuppressionRule(exceptionList)) {\n this._addDroppedExceptionStep('Exception dropped: matched a suppression rule')\n logger.info('Skipping exception capture because a suppression rule matched')\n return\n }\n\n if (!this._captureExtensionExceptions && this._isExtensionException(exceptionList)) {\n this._addDroppedExceptionStep('Exception dropped: thrown by a browser extension')\n logger.info('Skipping exception capture because it was thrown by an extension')\n return\n }\n\n if (\n !this._instance.config.error_tracking.__capturePostHogExceptions &&\n this._isPostHogException(exceptionList)\n ) {\n this._addDroppedExceptionStep('Exception dropped: thrown by the PostHog SDK')\n logger.info('Skipping exception capture because it was thrown by the PostHog SDK')\n return\n }\n }\n\n const propertiesForExceptionCapture =\n this._exceptionStepsConfig.enabled && isNullish(properties.$exception_steps)\n ? this._addBufferedExceptionSteps(properties)\n : properties\n\n try {\n const result = this._instance.capture('$exception', propertiesForExceptionCapture, {\n _noTruncate: true,\n _batchKey: 'exceptionEvent',\n _originatedFromCaptureException: true,\n })\n\n if (result) {\n this._exceptionStepsBuffer.clear()\n }\n\n return result\n } catch (error) {\n logger.error('Failed to capture exception event. Dropping this exception.', error)\n this._exceptionStepsBuffer.clear()\n return\n }\n } catch (error) {\n logger.error('Failed to process exception event. Ignoring this exception.', error)\n return\n }\n }\n\n private _addBufferedExceptionSteps(properties: Properties): Properties {\n try {\n const exceptionSteps = this._exceptionStepsBuffer.getAttachable()\n\n if (exceptionSteps.length === 0) {\n return properties\n }\n\n return {\n ...properties,\n $exception_steps: exceptionSteps,\n }\n } catch (error) {\n logger.error('Failed to read buffered exception steps. Capturing exception without steps.', error)\n return properties\n }\n }\n\n private _addDroppedExceptionStep(message: string): void {\n if (this._exceptionStepsConfig.enabled) {\n this._exceptionStepsBuffer.add({\n [ErrorTracking.EXCEPTION_STEP_INTERNAL_FIELDS.MESSAGE]: message,\n [ErrorTracking.EXCEPTION_STEP_INTERNAL_FIELDS.TIMESTAMP]: new Date().toISOString(),\n })\n }\n }\n\n private _coerceExceptionStepProperties(properties?: Properties): Record<string, unknown> {\n if (!isObject(properties)) {\n return {}\n }\n\n return { ...(properties as Record<string, unknown>) }\n }\n\n private _getExceptionStepsConfig(): ErrorTracking.ExceptionStepsConfig {\n return this._instance.config.error_tracking?.exception_steps ?? {}\n }\n\n private _matchesSuppressionRule(exceptionList: ErrorTracking.ExceptionList): boolean {\n if (exceptionList.length === 0) {\n return false\n }\n\n const exceptionValues = exceptionList.reduce(\n (acc, { type, value }) => {\n if (isString(type) && type.length > 0) {\n acc['$exception_types'].push(type)\n }\n if (isString(value) && value.length > 0) {\n acc['$exception_values'].push(value)\n }\n return acc\n },\n {\n $exception_types: [] as string[],\n $exception_values: [] as string[],\n }\n )\n\n return this._suppressionRules.some((rule) => {\n const results = rule.values.map((v) => {\n const compare = propertyComparisons[v.operator]\n const targets = isArray(v.value) ? v.value : [v.value]\n const values = exceptionValues[v.key] ?? []\n return targets.length > 0 ? compare(targets, values) : false\n })\n return rule.type === 'OR' ? results.some(Boolean) : results.every(Boolean)\n })\n }\n\n private _isExtensionException(exceptionList: ErrorTracking.ExceptionList): boolean {\n const frames = exceptionList.flatMap((e) => e.stacktrace?.frames ?? [])\n return frames.some((f) => f.filename && f.filename.startsWith('chrome-extension://'))\n }\n\n private _isPostHogException(exceptionList: ErrorTracking.ExceptionList): boolean {\n if (exceptionList.length > 0) {\n const exception = exceptionList[0]\n const frames = exception.stacktrace?.frames ?? []\n const lastFrame = frames[frames.length - 1]\n return lastFrame?.filename?.includes('posthog.com/static') ?? false\n }\n\n return false\n }\n\n private _isExceptionList(candidate: unknown): candidate is ErrorTracking.ExceptionList {\n return !isNullish(candidate) && isArray(candidate)\n }\n}\n","import { assignableWindow, window } from '../utils/globals'\nimport { ErrorEventArgs } from '../types'\nimport { createLogger } from '../utils/logger'\nimport type { ErrorTracking } from '@posthog/core'\nimport { buildErrorPropertiesBuilder } from '../posthog-exceptions'\n\nconst logger = createLogger('[ExceptionAutocapture]')\nconst errorPropertiesBuilder = buildErrorPropertiesBuilder()\n\nconst wrapOnError = (captureFn: (props: ErrorTracking.ErrorProperties) => void) => {\n const win = window as any\n if (!win) {\n logger.info('window not available, cannot wrap onerror')\n }\n const originalOnError = win.onerror\n\n win.onerror = function (...args: ErrorEventArgs): boolean {\n const error = args[4]\n const event = args[0]\n const errorProperties = errorPropertiesBuilder.buildFromUnknown(error || event, {\n mechanism: { handled: false },\n })\n captureFn(errorProperties)\n return originalOnError?.(...args) ?? false\n }\n win.onerror.__POSTHOG_INSTRUMENTED__ = true\n\n return () => {\n delete win.onerror?.__POSTHOG_INSTRUMENTED__\n win.onerror = originalOnError\n }\n}\n\nconst wrapUnhandledRejection = (captureFn: (props: ErrorTracking.ErrorProperties) => void) => {\n const win = window as any\n if (!win) {\n logger.info('window not available, cannot wrap onUnhandledRejection')\n }\n\n const originalOnUnhandledRejection = win.onunhandledrejection\n\n win.onunhandledrejection = function (ev: PromiseRejectionEvent): boolean {\n const errorProperties = errorPropertiesBuilder.buildFromUnknown(ev, {\n mechanism: { handled: false },\n })\n captureFn(errorProperties)\n return originalOnUnhandledRejection?.(ev) ?? false\n }\n win.onunhandledrejection.__POSTHOG_INSTRUMENTED__ = true\n\n return () => {\n delete win.onunhandledrejection?.__POSTHOG_INSTRUMENTED__\n win.onunhandledrejection = originalOnUnhandledRejection\n }\n}\n\nconst wrapConsoleError = (captureFn: (props: ErrorTracking.ErrorProperties) => void) => {\n const con = console as any\n if (!con) {\n logger.info('console not available, cannot wrap console.error')\n }\n\n const originalConsoleError = con.error\n\n con.error = function (...args: any[]): void {\n let event\n if (args.length == 1) {\n event = args[0]\n } else {\n event = args.join(' ')\n }\n const error = args.find((arg) => arg instanceof Error)\n const errorProperties = errorPropertiesBuilder.buildFromUnknown(error || event, {\n mechanism: { handled: false },\n syntheticException: new Error('PostHog syntheticException'),\n skipFirstLines: 2,\n })\n captureFn(errorProperties)\n return originalConsoleError?.(...args)\n }\n con.error.__POSTHOG_INSTRUMENTED__ = true\n\n return () => {\n delete con.error?.__POSTHOG_INSTRUMENTED__\n con.error = originalConsoleError\n }\n}\n\nconst posthogErrorWrappingFunctions = {\n wrapOnError,\n wrapUnhandledRejection,\n wrapConsoleError,\n}\n\nassignableWindow.__PosthogExtensions__ = assignableWindow.__PosthogExtensions__ || {}\nassignableWindow.__PosthogExtensions__.errorWrappingFunctions = posthogErrorWrappingFunctions\n\n// we used to put these on window, and now we put them on __PosthogExtensions__\n// but that means that old clients which lazily load this extension are looking in the wrong place\n// yuck,\n// so we also put them directly on the window\n// when 1.161.1 is the oldest version seen in production we can remove this\nassignableWindow.posthogErrorWrappingFunctions = posthogErrorWrappingFunctions\n\nexport default posthogErrorWrappingFunctions\n","import { isArray } from \"../utils/index.mjs\";\nimport { getFilenameToChunkIdMap } from \"./chunk-ids.mjs\";\nconst MAX_CAUSE_RECURSION = 4;\nclass ErrorPropertiesBuilder {\n constructor(coercers, stackParser, modifiers = []){\n this.coercers = coercers;\n this.stackParser = stackParser;\n this.modifiers = modifiers;\n }\n buildFromUnknown(input, hint = {}) {\n const providedMechanism = hint && hint.mechanism;\n const mechanism = providedMechanism || {\n handled: true,\n type: 'generic'\n };\n const coercingContext = this.buildCoercingContext(mechanism, hint, 0);\n const exceptionWithCause = coercingContext.apply(input);\n const parsingContext = this.buildParsingContext(hint);\n const exceptionWithStack = this.parseStacktrace(exceptionWithCause, parsingContext);\n const exceptionList = this.convertToExceptionList(exceptionWithStack, mechanism);\n return {\n $exception_list: exceptionList,\n $exception_level: 'error'\n };\n }\n async modifyFrames(exceptionList) {\n for (const exc of exceptionList)if (exc.stacktrace && exc.stacktrace.frames && isArray(exc.stacktrace.frames)) exc.stacktrace.frames = await this.applyModifiers(exc.stacktrace.frames);\n return exceptionList;\n }\n coerceFallback(ctx) {\n return {\n type: 'Error',\n value: 'Unknown error',\n stack: ctx.syntheticException?.stack,\n synthetic: true\n };\n }\n parseStacktrace(err, ctx) {\n let cause;\n if (null != err.cause) cause = this.parseStacktrace(err.cause, ctx);\n let stack;\n if ('' != err.stack && null != err.stack) stack = this.applyChunkIds(this.stackParser(err.stack, err.synthetic ? ctx.skipFirstLines : 0), ctx.chunkIdMap);\n return {\n ...err,\n cause,\n stack\n };\n }\n applyChunkIds(frames, chunkIdMap) {\n return frames.map((frame)=>{\n if (frame.filename && chunkIdMap) frame.chunk_id = chunkIdMap[frame.filename];\n return frame;\n });\n }\n applyCoercers(input, ctx) {\n for (const adapter of this.coercers)if (adapter.match(input)) return adapter.coerce(input, ctx);\n return this.coerceFallback(ctx);\n }\n async applyModifiers(frames) {\n let newFrames = frames;\n for (const modifier of this.modifiers)newFrames = await modifier(newFrames);\n return newFrames;\n }\n convertToExceptionList(exceptionWithStack, mechanism) {\n const currentException = {\n type: exceptionWithStack.type,\n value: exceptionWithStack.value,\n mechanism: {\n type: mechanism.type ?? 'generic',\n handled: mechanism.handled ?? true,\n synthetic: exceptionWithStack.synthetic ?? false\n }\n };\n if (exceptionWithStack.stack) currentException.stacktrace = {\n type: 'raw',\n frames: exceptionWithStack.stack\n };\n const exceptionList = [\n currentException\n ];\n if (null != exceptionWithStack.cause) exceptionList.push(...this.convertToExceptionList(exceptionWithStack.cause, {\n ...mechanism,\n handled: true\n }));\n return exceptionList;\n }\n buildParsingContext(hint) {\n const context = {\n chunkIdMap: getFilenameToChunkIdMap(this.stackParser),\n skipFirstLines: hint.skipFirstLines ?? 1\n };\n return context;\n }\n buildCoercingContext(mechanism, hint, depth = 0) {\n const coerce = (input, depth)=>{\n if (!(depth <= MAX_CAUSE_RECURSION)) return;\n {\n const ctx = this.buildCoercingContext(mechanism, hint, depth);\n return this.applyCoercers(input, ctx);\n }\n };\n const context = {\n ...hint,\n syntheticException: 0 == depth ? hint.syntheticException : void 0,\n mechanism,\n apply: (input)=>coerce(input, depth),\n next: (input)=>coerce(input, depth + 1)\n };\n return context;\n }\n}\nexport { ErrorPropertiesBuilder };\n","import { isBuiltin, isString } from \"../../utils/index.mjs\";\nclass DOMExceptionCoercer {\n match(err) {\n return this.isDOMException(err) || this.isDOMError(err);\n }\n coerce(err, ctx) {\n const hasStack = isString(err.stack);\n return {\n type: this.getType(err),\n value: this.getValue(err),\n stack: hasStack ? err.stack : void 0,\n cause: err.cause ? ctx.next(err.cause) : void 0,\n synthetic: false\n };\n }\n getType(candidate) {\n return this.isDOMError(candidate) ? 'DOMError' : 'DOMException';\n }\n getValue(err) {\n const name = err.name || (this.isDOMError(err) ? 'DOMError' : 'DOMException');\n const message = err.message ? `${name}: ${err.message}` : name;\n return message;\n }\n isDOMException(err) {\n return isBuiltin(err, 'DOMException');\n }\n isDOMError(err) {\n return isBuiltin(err, 'DOMError');\n }\n}\nexport { DOMExceptionCoercer };\n","import { isBuiltin, isEvent, isPrimitive } from \"../../utils/index.mjs\";\nclass PromiseRejectionEventCoercer {\n match(err) {\n return isBuiltin(err, 'PromiseRejectionEvent') || this.isCustomEventWrappingRejection(err);\n }\n isCustomEventWrappingRejection(err) {\n if (!isEvent(err)) return false;\n try {\n const detail = err.detail;\n return null != detail && 'object' == typeof detail && 'reason' in detail;\n } catch {\n return false;\n }\n }\n coerce(err, ctx) {\n const reason = this.getUnhandledRejectionReason(err);\n if (isPrimitive(reason)) return {\n type: 'UnhandledRejection',\n value: `Non-Error promise rejection captured with value: ${String(reason)}`,\n stack: ctx.syntheticException?.stack,\n synthetic: true\n };\n return ctx.apply(reason);\n }\n getUnhandledRejectionReason(error) {\n try {\n if ('reason' in error) return error.reason;\n if ('detail' in error && null != error.detail && 'object' == typeof error.detail && 'reason' in error.detail) return error.detail.reason;\n } catch {}\n return error;\n }\n}\nexport { PromiseRejectionEventCoercer };\n","import { isErrorEvent } from \"../../utils/index.mjs\";\nclass ErrorEventCoercer {\n constructor(){}\n match(err) {\n return isErrorEvent(err) && void 0 != err.error;\n }\n coerce(err, ctx) {\n const exceptionLike = ctx.apply(err.error);\n if (!exceptionLike) return {\n type: 'ErrorEvent',\n value: err.message,\n stack: ctx.syntheticException?.stack,\n synthetic: true\n };\n return exceptionLike;\n }\n}\nexport { ErrorEventCoercer };\n","import { isPlainError } from \"../../utils/index.mjs\";\nclass ErrorCoercer {\n match(err) {\n return isPlainError(err);\n }\n coerce(err, ctx) {\n return {\n type: this.getType(err),\n value: this.getMessage(err, ctx),\n stack: this.getStack(err),\n cause: err.cause ? ctx.next(err.cause) : void 0,\n synthetic: false\n };\n }\n getType(err) {\n return err.name || err.constructor.name;\n }\n getMessage(err, _ctx) {\n const message = err.message;\n if (message.error && 'string' == typeof message.error.message) return String(message.error.message);\n return String(message);\n }\n getStack(err) {\n return err.stacktrace || err.stack || void 0;\n }\n}\nexport { ErrorCoercer };\n","import { isEvent } from \"../../utils/index.mjs\";\nimport { extractExceptionKeysForMessage } from \"./utils.mjs\";\nclass EventCoercer {\n match(err) {\n return isEvent(err);\n }\n coerce(evt, ctx) {\n const constructorName = evt.constructor.name;\n return {\n type: constructorName,\n value: `${constructorName} captured as exception with keys: ${extractExceptionKeysForMessage(evt)}`,\n stack: ctx.syntheticException?.stack,\n synthetic: true\n };\n }\n}\nexport { EventCoercer };\n","import { isEmptyString, isError, isEvent, isString } from \"../../utils/index.mjs\";\nimport { severityLevels } from \"../types.mjs\";\nimport { extractExceptionKeysForMessage } from \"./utils.mjs\";\nclass ObjectCoercer {\n match(candidate) {\n return 'object' == typeof candidate && null !== candidate;\n }\n coerce(candidate, ctx) {\n const errorProperty = this.getErrorPropertyFromObject(candidate);\n if (errorProperty) return ctx.apply(errorProperty);\n return {\n type: this.getType(candidate),\n value: this.getValue(candidate),\n stack: ctx.syntheticException?.stack,\n level: this.isSeverityLevel(candidate.level) ? candidate.level : 'error',\n synthetic: true\n };\n }\n getType(err) {\n return isEvent(err) ? err.constructor.name : 'Error';\n }\n getValue(err) {\n if ('name' in err && 'string' == typeof err.name) {\n let message = `'${err.name}' captured as exception`;\n if ('message' in err && 'string' == typeof err.message) message += ` with message: '${err.message}'`;\n return message;\n }\n if ('message' in err && 'string' == typeof err.message) return err.message;\n const className = this.getObjectClassName(err);\n const keys = extractExceptionKeysForMessage(err);\n return `${className && 'Object' !== className ? `'${className}'` : 'Object'} captured as exception with keys: ${keys}`;\n }\n isSeverityLevel(x) {\n return isString(x) && !isEmptyString(x) && severityLevels.indexOf(x) >= 0;\n }\n getErrorPropertyFromObject(obj) {\n for(const prop in obj)if (Object.prototype.hasOwnProperty.call(obj, prop)) {\n const value = obj[prop];\n if (isError(value)) return value;\n }\n }\n getObjectClassName(obj) {\n try {\n const prototype = Object.getPrototypeOf(obj);\n return prototype ? prototype.constructor.name : void 0;\n } catch (e) {\n return;\n }\n }\n}\nexport { ObjectCoercer };\n","import { isPrimitive } from \"../../utils/index.mjs\";\nclass PrimitiveCoercer {\n match(candidate) {\n return isPrimitive(candidate);\n }\n coerce(value, ctx) {\n return {\n type: 'Error',\n value: `Primitive value captured as exception: ${String(value)}`,\n stack: ctx.syntheticException?.stack,\n synthetic: true\n };\n }\n}\nexport { PrimitiveCoercer };\n","import { SessionIdManager } from '../sessionid'\nimport { patch } from '../extensions/replay/rrweb-plugins/patch'\nimport { assignableWindow, window } from '../utils/globals'\nimport { COOKIELESS_SENTINEL_VALUE } from '../constants'\nimport { isArray, isFunction, isNull, isUndefined } from '@posthog/core'\nimport type { TracingHeadersDistinctId, TracingHeadersHostnames } from '../extensions/tracing-headers-types'\n\nconst SESSION_ID_HEADER = 'X-POSTHOG-SESSION-ID'\nconst WINDOW_ID_HEADER = 'X-POSTHOG-WINDOW-ID'\nconst DISTINCT_ID_HEADER = 'X-POSTHOG-DISTINCT-ID'\nconst TRACING_HEADERS = [SESSION_ID_HEADER, WINDOW_ID_HEADER, DISTINCT_ID_HEADER]\nconst REQUEST_INIT_KEYS = [\n 'attributionReporting',\n 'body',\n 'browsingTopics',\n 'cache',\n 'credentials',\n 'dispatcher',\n 'duplex',\n 'integrity',\n 'keepalive',\n 'method',\n 'mode',\n 'priority',\n 'redirect',\n 'referrer',\n 'referrerPolicy',\n 'signal',\n 'window',\n]\n\nconst hasOwnProperty = (value: object, property: PropertyKey): boolean =>\n Object.prototype.hasOwnProperty.call(value, property)\n\nconst isObjectLike = (value: unknown): value is object =>\n (typeof value === 'object' && !isNull(value)) || isFunction(value)\n\nconst isRequest = (value: unknown): value is Request =>\n typeof Request !== 'undefined' &&\n (value instanceof Request || Object.prototype.toString.call(value) === '[object Request]')\n\nconst getRequestUrl = (url: URL | RequestInfo): string | undefined => {\n try {\n if (isRequest(url)) {\n return url.url\n }\n\n // eslint-disable-next-line compat/compat\n return new URL(url instanceof URL ? url.toString() : String(url), window?.location?.href).toString()\n } catch {\n return undefined\n }\n}\n\n// RequestInit is a WebIDL dictionary: native fetch reads known keys via property access, including inherited\n// and non-enumerable properties. Avoid `{ ...init, headers }`, which can drop body/signal/duplex/etc. Instead,\n// overlay only `headers` while forwarding every other lookup to the caller's original init object.\nconst createFetchInitWithHeaders = (init: RequestInit | undefined, headers: Headers): RequestInit | undefined => {\n if (isUndefined(init) || isNull(init)) {\n return { headers }\n }\n if (!isObjectLike(init)) {\n return undefined\n }\n\n const originalInit = init as RequestInit & Record<PropertyKey, unknown>\n\n if (typeof Proxy === 'undefined' || typeof Reflect === 'undefined') {\n // Older browsers without Proxy still get an inherited overlay, which preserves native fetch property lookup.\n const initWithHeaders = Object.create(originalInit) as RequestInit\n Object.defineProperty(initWithHeaders, 'headers', {\n configurable: true,\n enumerable: true,\n value: headers,\n writable: true,\n })\n return initWithHeaders\n }\n\n const target = { headers } as RequestInit & Record<PropertyKey, unknown>\n\n return new Proxy(target, {\n get(target, property) {\n if (hasOwnProperty(target, property)) {\n return Reflect.get(target, property)\n }\n return Reflect.get(originalInit, property, originalInit)\n },\n has(target, property) {\n return hasOwnProperty(target, property) || property in originalInit\n },\n ownKeys(target) {\n const keys = new Set<string | symbol>(Reflect.ownKeys(target))\n Reflect.ownKeys(originalInit).forEach((key) => keys.add(key))\n REQUEST_INIT_KEYS.forEach((key) => {\n if (key in originalInit) {\n keys.add(key)\n }\n })\n return Array.from(keys)\n },\n getOwnPropertyDescriptor(target, property) {\n const targetDescriptor = Reflect.getOwnPropertyDescriptor(target, property)\n if (targetDescriptor) {\n return targetDescriptor\n }\n if (typeof property === 'string' && REQUEST_INIT_KEYS.includes(property) && property in originalInit) {\n return {\n configurable: true,\n enumerable: true,\n get: () => Reflect.get(originalInit, property, originalInit),\n }\n }\n\n const descriptor = Reflect.getOwnPropertyDescriptor(originalInit, property)\n return descriptor ? { ...descriptor, configurable: true } : undefined\n },\n getPrototypeOf() {\n return Object.getPrototypeOf(originalInit)\n },\n }) as RequestInit\n}\n\nconst getDistinctId = (distinctId: TracingHeadersDistinctId): string | undefined =>\n isFunction(distinctId) ? distinctId() : distinctId\n\nconst addTracingHeaders = (\n hostnames: TracingHeadersHostnames,\n distinctId: TracingHeadersDistinctId,\n sessionManager: SessionIdManager | undefined,\n url: string,\n headers: Headers\n): boolean => {\n let reqHostname: string\n try {\n // we don't need to support IE11 here\n // eslint-disable-next-line compat/compat\n reqHostname = new URL(url).hostname\n } catch {\n // If the URL is invalid, we skip adding tracing headers\n return false\n }\n if (!hostnames) {\n return false\n }\n if (isArray(hostnames) && !hostnames.includes(reqHostname)) {\n return false\n }\n\n let hasAddedHeaders = false\n if (sessionManager) {\n const { sessionId, windowId } = sessionManager.checkAndGetSessionAndWindowId(true)\n headers.set(SESSION_ID_HEADER, sessionId)\n headers.set(WINDOW_ID_HEADER, windowId)\n hasAddedHeaders = true\n }\n const currentDistinctId = getDistinctId(distinctId)\n if (currentDistinctId && currentDistinctId !== COOKIELESS_SENTINEL_VALUE) {\n headers.set(DISTINCT_ID_HEADER, currentDistinctId)\n hasAddedHeaders = true\n }\n return hasAddedHeaders\n}\n\ntype FetchArgs = [URL | RequestInfo] | [URL | RequestInfo, RequestInit | undefined]\n\nconst patchFetch = (\n hostnames: TracingHeadersHostnames,\n distinctId: TracingHeadersDistinctId,\n sessionManager?: SessionIdManager\n): (() => void) => {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n return patch(window, 'fetch', (originalFetch: typeof fetch) => {\n return function (this: unknown, url: URL | RequestInfo, init?: RequestInit | undefined) {\n const originalArgs = (arguments.length > 1 ? [url, init] : [url]) as FetchArgs\n let fetchArgs = originalArgs\n\n try {\n const requestUrl = getRequestUrl(url)\n if (requestUrl) {\n if (isRequest(url)) {\n // For fetch(Request, init), construct a new Request so init overrides are applied and the\n // caller's Request is not mutated. For fetch(url, init), avoid this because it exposes string\n // bodies as ReadableStreams to downstream wrappers in Safari.\n // eslint-disable-next-line compat/compat\n const req = new Request(url, init)\n addTracingHeaders(hostnames, distinctId, sessionManager, req.url, req.headers)\n fetchArgs = [req]\n } else {\n const headers = new Headers(isObjectLike(init) ? init.headers : undefined)\n if (addTracingHeaders(hostnames, distinctId, sessionManager, requestUrl, headers)) {\n const initWithHeaders = createFetchInitWithHeaders(init, headers)\n if (initWithHeaders) {\n fetchArgs = [url, initWithHeaders]\n }\n }\n }\n }\n } catch {\n fetchArgs = originalArgs\n }\n\n return originalFetch.apply(this, fetchArgs)\n }\n })\n}\n\nconst patchXHR = (\n hostnames: TracingHeadersHostnames,\n distinctId: TracingHeadersDistinctId,\n sessionManager?: SessionIdManager\n): (() => void) => {\n return patch(\n // we can assert this is present because we've checked previously\n window!.XMLHttpRequest.prototype,\n 'open',\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n (originalOpen: typeof XMLHttpRequest.prototype.open) => {\n return function (\n method: string,\n url: string | URL,\n async = true,\n username?: string | null,\n password?: string | null\n ) {\n // because this function is returned in its actual context `this` _is_ an XMLHttpRequest\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n const xhr = this as XMLHttpRequest\n\n const headers = new Headers()\n const requestUrl = getRequestUrl(url)\n if (requestUrl) {\n addTracingHeaders(hostnames, distinctId, sessionManager, requestUrl, headers)\n }\n\n const result = originalOpen.call(xhr, method, url, async, username, password)\n\n TRACING_HEADERS.forEach((header) => {\n const value = headers.get(header)\n if (value) {\n try {\n xhr.setRequestHeader(header, value)\n } catch {\n // Do not let tracing header injection break the host app's XHR.\n }\n }\n })\n\n return result\n }\n }\n )\n}\n\nassignableWindow.__PosthogExtensions__ = assignableWindow.__PosthogExtensions__ || {}\nconst patchFns = {\n _patchFetch: patchFetch,\n _patchXHR: patchXHR,\n}\nassignableWindow.__PosthogExtensions__.tracingHeadersPatchFns = patchFns\n\n// we used to put tracingHeadersPatchFns on window, and now we put it on __PosthogExtensions__\n// but that means that old clients which lazily load this extension are looking in the wrong place\n// yuck,\n// so we also put it directly on the window\n// when 1.161.1 is the oldest version seen in production we can remove this\nassignableWindow.postHogTracingHeadersPatchFns = patchFns\n\nexport default patchFns\n","let e=-1;const t=t=>{addEventListener(\"pageshow\",n=>{n.persisted&&(e=n.timeStamp,t(n))},!0)},n=(e,t,n,i)=>{let s,o;return r=>{t.value>=0&&(r||i)&&(o=t.value-(s??0),(o||void 0===s)&&(s=t.value,t.delta=o,t.rating=((e,t)=>e>t[1]?\"poor\":e>t[0]?\"needs-improvement\":\"good\")(t.value,n),e(t)))}},i=e=>{requestAnimationFrame(()=>requestAnimationFrame(e))},s=()=>{const e=performance.getEntriesByType(\"navigation\")[0];if(e&&e.responseStart>0&&e.responseStart<performance.now())return e},o=()=>s()?.activationStart??0,r=(t,n=-1)=>{const i=s();let r=\"navigate\";e>=0?r=\"back-forward-cache\":i&&(document.prerendering||o()>0?r=\"prerender\":document.wasDiscarded?r=\"restore\":i.type&&(r=i.type.replace(/_/g,\"-\")));return{name:t,value:n,rating:\"good\",delta:0,entries:[],id:`v5-${Date.now()}-${Math.floor(8999999999999*Math.random())+1e12}`,navigationType:r}},c=new WeakMap;function a(e,t){let n=c.get(t);return n||(n=new WeakMap,c.set(t,n)),n.get(e)||n.set(e,new t),n.get(e)}class d{t;i=0;o=[];h(e){if(e.hadRecentInput)return;const t=this.o[0],n=this.o.at(-1);this.i&&t&&n&&e.startTime-n.startTime<1e3&&e.startTime-t.startTime<5e3?(this.i+=e.value,this.o.push(e)):(this.i=e.value,this.o=[e]),this.t?.(e)}}const h=(e,t,n={})=>{try{if(PerformanceObserver.supportedEntryTypes.includes(e)){const i=new PerformanceObserver(e=>{queueMicrotask(()=>{t(e.getEntries())})});return i.observe({type:e,buffered:!0,...n}),i}}catch{}},f=e=>{let t=!1;return()=>{t||(e(),t=!0)}};let l=-1;const u=new Set,m=()=>\"hidden\"!==document.visibilityState||document.prerendering?1/0:0,p=e=>{if(\"hidden\"===document.visibilityState){if(\"visibilitychange\"===e.type)for(const e of u)e();isFinite(l)||(l=\"visibilitychange\"===e.type?e.timeStamp:0,removeEventListener(\"prerenderingchange\",p,!0))}},g=()=>{if(l<0){const e=o(),n=document.prerendering?void 0:globalThis.performance.getEntriesByType(\"visibility-state\").find(t=>\"hidden\"===t.name&&t.startTime>=e)?.startTime;l=n??m(),addEventListener(\"visibilitychange\",p,!0),addEventListener(\"prerenderingchange\",p,!0),t(()=>{setTimeout(()=>{l=m()})})}return{get firstHiddenTime(){return l},onHidden(e){u.add(e)}}},v=e=>{document.prerendering?addEventListener(\"prerenderingchange\",e,!0):e()},y=[1800,3e3],T=(e,s={})=>{v(()=>{const c=g();let a,d=r(\"FCP\");const f=h(\"paint\",e=>{for(const t of e)\"first-contentful-paint\"===t.name&&(f.disconnect(),t.startTime<c.firstHiddenTime&&(d.value=Math.max(t.startTime-o(),0),d.entries.push(t),a(!0)))});f&&(a=n(e,d,y,s.reportAllChanges),t(t=>{d=r(\"FCP\"),a=n(e,d,y,s.reportAllChanges),i(()=>{d.value=performance.now()-t.timeStamp,a(!0)})}))})},E=[.1,.25],b=(e,s={})=>{const o=g();T(f(()=>{let c,f=r(\"CLS\",0);const l=a(s,d),u=e=>{for(const t of e)l.h(t);l.i>f.value&&(f.value=l.i,f.entries=l.o,c())},m=h(\"layout-shift\",u);m&&(c=n(e,f,E,s.reportAllChanges),o.onHidden(()=>{u(m.takeRecords()),c(!0)}),t(()=>{l.i=0,f=r(\"CLS\",0),c=n(e,f,E,s.reportAllChanges),i(c)}),setTimeout(c))}))};let L=0,P=1/0,_=0;const M=e=>{for(const t of e)t.interactionId&&(P=Math.min(P,t.interactionId),_=Math.max(_,t.interactionId),L=_?(_-P)/7+1:0)};let w;const C=()=>w?L:performance.interactionCount??0,I=()=>{\"interactionCount\"in performance||w||(w=h(\"event\",M,{durationThreshold:0}))};let F=0;class k{l=[];u=new Map;m;p;v(){F=C(),this.l.length=0,this.u.clear()}T(){const e=Math.min(this.l.length-1,Math.floor((C()-F)/50));return this.l[e]}h(e){if(this.m?.(e),!e.interactionId&&\"first-input\"!==e.entryType)return;const t=this.l.at(-1);let n=this.u.get(e.interactionId);if(n||this.l.length<10||e.duration>t.L){if(n?e.duration>n.L?(n.entries=[e],n.L=e.duration):e.duration===n.L&&e.startTime===n.entries[0].startTime&&n.entries.push(e):(n={id:e.interactionId,entries:[e],L:e.duration},this.u.set(n.id,n),this.l.push(n)),this.l.sort((e,t)=>t.L-e.L),this.l.length>10){const e=this.l.splice(10);for(const t of e)this.u.delete(t.id)}this.p?.(n)}}}const A=e=>{const t=globalThis.requestIdleCallback||setTimeout,n=globalThis.cancelIdleCallback||clearTimeout;if(\"hidden\"===document.visibilityState)e();else{const i=f(e);let s=-1;const o=()=>{n(s),i()};addEventListener(\"visibilitychange\",o,{once:!0,capture:!0}),s=t(()=>{removeEventListener(\"visibilitychange\",o,{capture:!0}),i()})}},B=[200,500],S=(e,i={})=>{if(!globalThis.PerformanceEventTiming||!(\"interactionId\"in PerformanceEventTiming.prototype))return;const s=g();v(()=>{I();let o,c=r(\"INP\");const d=a(i,k),f=e=>{A(()=>{for(const t of e)d.h(t);const t=d.T();t&&t.L!==c.value&&(c.value=t.L,c.entries=t.entries,o())})},l=h(\"event\",f,{durationThreshold:i.durationThreshold??40});o=n(e,c,B,i.reportAllChanges),l&&(l.observe({type:\"first-input\",buffered:!0}),s.onHidden(()=>{f(l.takeRecords()),o(!0)}),t(()=>{d.v(),c=r(\"INP\"),o=n(e,c,B,i.reportAllChanges)}))})};class q{m;h(e){this.m?.(e)}}const N=[2500,4e3],x=(e,s={})=>{v(()=>{const c=g();let d,l=r(\"LCP\");const u=a(s,q),m=e=>{s.reportAllChanges||(e=e.slice(-1));for(const t of e)u.h(t),t.startTime<c.firstHiddenTime&&(l.value=Math.max(t.startTime-o(),0),l.entries=[t],d())},p=h(\"largest-contentful-paint\",m);if(p){d=n(e,l,N,s.reportAllChanges);const o=f(()=>{m(p.takeRecords()),p.disconnect(),d(!0)}),c=e=>{e.isTrusted&&(A(o),removeEventListener(e.type,c,{capture:!0}))};for(const e of[\"keydown\",\"click\",\"visibilitychange\"])addEventListener(e,c,{capture:!0});t(t=>{l=r(\"LCP\"),d=n(e,l,N,s.reportAllChanges),i(()=>{l.value=performance.now()-t.timeStamp,d(!0)})})}})},H=[800,1800],O=e=>{document.prerendering?v(()=>O(e)):\"complete\"!==document.readyState?addEventListener(\"load\",()=>O(e),!0):setTimeout(e)},W=(e,i={})=>{let c=r(\"TTFB\"),a=n(e,c,H,i.reportAllChanges);O(()=>{const d=s();d&&(c.value=Math.max(d.responseStart-o(),0),c.entries=[d],a(!0),t(()=>{c=r(\"TTFB\",0),a=n(e,c,H,i.reportAllChanges),a(!0)}))})};export{E as CLSThresholds,y as FCPThresholds,B as INPThresholds,N as LCPThresholds,H as TTFBThresholds,b as onCLS,T as onFCP,S as onINP,x as onLCP,W as onTTFB};\n","/**\n * Web Vitals entrypoint (without attribution)\n *\n * This is the default, lighter bundle (~6KB) that captures core web vitals metrics\n * without attribution data. Attribution data includes debugging information like\n * which elements caused layout shifts, timing breakdowns, etc.\n *\n * We split this into two bundles because:\n * 1. Attribution code adds ~6KB to the bundle size\n * 2. Attribution can cause memory issues in SPAs (onCLS holds references to detached DOM elements)\n * 3. Most users only need aggregate metrics, not debugging attribution data\n *\n * For attribution data, use web-vitals-with-attribution.ts instead by setting:\n * capture_performance: { web_vitals_attribution: true }\n *\n * @see web-vitals-with-attribution.ts\n */\nimport { assignableWindow } from '../utils/globals'\n\nimport { onINP, onLCP, onCLS, onFCP } from 'web-vitals'\n\nconst postHogWebVitalsCallbacks = {\n onLCP,\n onCLS,\n onFCP,\n onINP,\n}\n\nassignableWindow.__PosthogExtensions__ = assignableWindow.__PosthogExtensions__ || {}\nassignableWindow.__PosthogExtensions__.postHogWebVitalsCallbacks = postHogWebVitalsCallbacks\n\n// we used to put posthogWebVitalsCallbacks on window, and now we put it on __PosthogExtensions__\n// but that means that old clients which lazily load this extension are looking in the wrong place\n// yuck,\n// so we also put it directly on the window\n// when 1.161.1 is the oldest version seen in production we can remove this\nassignableWindow.postHogWebVitalsCallbacks = postHogWebVitalsCallbacks\n// deprecated function kept for backwards compatibility\nassignableWindow.__PosthogExtensions__.loadWebVitalsCallbacks = () => postHogWebVitalsCallbacks\n\nexport default postHogWebVitalsCallbacks\n","import { addEventListener, each, extend } from './utils'\nimport {\n autocaptureCompatibleElements,\n getClassNames,\n getDirectAndNestedSpanText,\n getElementsChainString,\n getEventTarget,\n getSafeText,\n isAngularStyleAttr,\n isSensitiveElement,\n makeSafeText,\n shouldCaptureDomEvent,\n shouldCaptureElement,\n shouldCaptureRageclick,\n shouldCaptureValue,\n splitClassString,\n} from './autocapture-utils'\n\nimport RageClick from './extensions/rageclick'\nimport { AutocaptureConfig, EventName, Properties, RemoteConfig } from './types'\nimport { PostHog } from './posthog-core'\nimport { AUTOCAPTURE_DISABLED_SERVER_SIDE } from './constants'\n\nimport { isBoolean, isFunction, isNull, isObject, stripUrlHash } from '@posthog/core'\nimport { createLogger } from './utils/logger'\nimport { document, window } from './utils/globals'\nimport { convertToURL } from './utils/request-utils'\nimport { isElementNode, isShadowRoot, isTag, isTextNode } from './utils/element-utils'\nimport { includes } from '@posthog/core'\nimport type { Extension } from './extensions/types'\n\nconst COPY_AUTOCAPTURE_EVENT = '$copy_autocapture'\n\nconst logger = createLogger('[AutoCapture]')\n\nfunction limitText(length: number, text: string): string {\n if (text.length > length) {\n return text.slice(0, length) + '...'\n }\n return text\n}\n\nexport function getAugmentPropertiesFromElement(elem: Element): Properties {\n const shouldCaptureEl = shouldCaptureElement(elem)\n if (!shouldCaptureEl) {\n return {}\n }\n\n const props: Properties = {}\n\n each(elem.attributes, function (attr: Attr) {\n if (attr.name && attr.name.indexOf('data-ph-capture-attribute') === 0) {\n const propertyKey = attr.name.replace('data-ph-capture-attribute-', '')\n const propertyValue = attr.value\n if (propertyKey && propertyValue && shouldCaptureValue(propertyValue)) {\n props[propertyKey] = propertyValue\n }\n }\n })\n\n return props\n}\n\nexport function previousElementSibling(el: Element): Element | null {\n if (el.previousElementSibling) {\n return el.previousElementSibling\n }\n let _el: Element | null = el\n do {\n _el = _el.previousSibling as Element | null // resolves to ChildNode->Node, which is Element's parent class\n } while (_el && !isElementNode(_el))\n return _el\n}\n\nexport function getDefaultProperties(eventType: string): Properties {\n return {\n $event_type: eventType,\n $ce_version: 1,\n }\n}\n\nexport function getPropertiesFromElement(\n elem: Element,\n maskAllAttributes: boolean,\n maskText: boolean,\n elementAttributeIgnorelist: string[] | undefined,\n disableCaptureUrlHashes: boolean = false\n): Properties {\n const tag_name = elem.tagName.toLowerCase()\n const props: Properties = {\n tag_name: tag_name,\n }\n if (autocaptureCompatibleElements.indexOf(tag_name) > -1 && !maskText) {\n if (tag_name.toLowerCase() === 'a' || tag_name.toLowerCase() === 'button') {\n props['$el_text'] = limitText(1024, getDirectAndNestedSpanText(elem))\n } else {\n props['$el_text'] = limitText(1024, getSafeText(elem))\n }\n }\n\n const classes = getClassNames(elem)\n if (classes.length > 0)\n props['classes'] = classes.filter(function (c) {\n return c !== ''\n })\n\n // capture the deny list here because this not-a-class class makes it tricky to use this.config in the function below\n each(elem.attributes, function (attr: Attr) {\n // Only capture attributes we know are safe\n if (isSensitiveElement(elem) && ['name', 'id', 'class', 'aria-label'].indexOf(attr.name) === -1) return\n\n if (elementAttributeIgnorelist?.includes(attr.name)) return\n\n if (!maskAllAttributes && shouldCaptureValue(attr.value) && !isAngularStyleAttr(attr.name)) {\n let value = attr.value\n if (attr.name === 'class') {\n // html attributes can _technically_ contain linebreaks,\n // but we're very intolerant of them in the class string,\n // so we strip them.\n value = splitClassString(value).join(' ')\n }\n props['attr__' + attr.name] = limitText(\n 1024,\n attr.name === 'href' && disableCaptureUrlHashes ? stripUrlHash(value) : value\n )\n }\n })\n\n let nthChild = 1\n let nthOfType = 1\n let currentElem: Element | null = elem\n while ((currentElem = previousElementSibling(currentElem))) {\n // eslint-disable-line no-cond-assign\n nthChild++\n if (currentElem.tagName === elem.tagName) {\n nthOfType++\n }\n }\n props['nth_child'] = nthChild\n props['nth_of_type'] = nthOfType\n\n return props\n}\n\nexport function autocapturePropertiesForElement(\n target: Element,\n {\n e,\n maskAllElementAttributes,\n maskAllText,\n elementAttributeIgnoreList,\n elementsChainAsString,\n disableCaptureUrlHashes,\n }: {\n e: Event\n maskAllElementAttributes: boolean\n maskAllText: boolean\n elementAttributeIgnoreList?: string[] | undefined\n elementsChainAsString: boolean\n disableCaptureUrlHashes: boolean\n }\n): { props: Properties; explicitNoCapture?: boolean } {\n if (!isElementNode(target)) {\n return { props: {} }\n }\n\n const targetElementList: Element[] = [target]\n let curEl: Element = target\n while (curEl.parentNode && !isTag(curEl, 'body')) {\n if (isShadowRoot(curEl.parentNode)) {\n targetElementList.push(curEl.parentNode.host)\n curEl = curEl.parentNode.host\n continue\n }\n if (!isElementNode(curEl.parentNode)) {\n break\n }\n targetElementList.push(curEl.parentNode)\n curEl = curEl.parentNode\n }\n\n const elementsJson: Properties[] = []\n const autocaptureAugmentProperties: Properties = {}\n let href: string | false = false\n let explicitNoCapture = false\n\n each(targetElementList, (el) => {\n const shouldCaptureEl = shouldCaptureElement(el)\n\n // if the element or a parent element is an anchor tag\n // include the href as a property\n if (isTag(el, 'a')) {\n const hrefAttr = el.getAttribute('href')\n href =\n shouldCaptureEl && !!hrefAttr && shouldCaptureValue(hrefAttr)\n ? disableCaptureUrlHashes\n ? stripUrlHash(hrefAttr)\n : hrefAttr\n : false\n }\n\n // allow users to programmatically prevent capturing of elements by adding class 'ph-no-capture'\n const classes = getClassNames(el)\n if (includes(classes, 'ph-no-capture')) {\n explicitNoCapture = true\n }\n\n elementsJson.push(\n getPropertiesFromElement(\n el,\n maskAllElementAttributes,\n maskAllText,\n elementAttributeIgnoreList,\n disableCaptureUrlHashes\n )\n )\n\n const augmentProperties = getAugmentPropertiesFromElement(el)\n extend(autocaptureAugmentProperties, augmentProperties)\n })\n\n if (explicitNoCapture) {\n return { props: {}, explicitNoCapture }\n }\n\n if (!maskAllText) {\n // if the element is a button or anchor tag get the span text from any\n // children and include it as/with the text property on the parent element\n if (isTag(target, 'a') || isTag(target, 'button')) {\n elementsJson[0]['$el_text'] = getDirectAndNestedSpanText(target)\n } else {\n elementsJson[0]['$el_text'] = getSafeText(target)\n }\n }\n\n let externalHref: string | undefined\n if (href) {\n elementsJson[0]['attr__href'] = href\n const hrefHost = convertToURL(href)?.host\n const locationHost = window?.location?.host\n if (hrefHost && locationHost && hrefHost !== locationHost) {\n externalHref = href\n }\n }\n\n const props = extend(\n getDefaultProperties(e.type),\n // Sending \"$elements\" is deprecated. Only one client on US cloud uses this.\n !elementsChainAsString ? { $elements: elementsJson } : {},\n // Always send $elements_chain, as it's needed downstream in site app filtering\n { $elements_chain: getElementsChainString(elementsJson) },\n elementsJson[0]?.['$el_text'] ? { $el_text: elementsJson[0]?.['$el_text'] } : {},\n externalHref && e.type === 'click' ? { $external_click_url: externalHref } : {},\n autocaptureAugmentProperties\n )\n\n return { props }\n}\n\nexport class Autocapture implements Extension {\n instance: PostHog\n _initialized: boolean = false\n _isDisabledServerSide: boolean | null = null\n _elementSelectors: Set<string> | null\n rageclicks: RageClick\n _elementsChainAsString = false\n\n constructor(instance: PostHog) {\n this.instance = instance\n this.rageclicks = new RageClick(instance.config.rageclick)\n this._elementSelectors = null\n }\n\n initialize() {\n this.startIfEnabled()\n }\n\n private get _config(): AutocaptureConfig {\n const config = isObject(this.instance.config.autocapture) ? this.instance.config.autocapture : {}\n // precompile the regex\n config.url_allowlist = config.url_allowlist?.map((url) => new RegExp(url))\n config.url_ignorelist = config.url_ignorelist?.map((url) => new RegExp(url))\n return config\n }\n\n _addDomEventHandlers(): void {\n if (!this.isBrowserSupported()) {\n logger.info('Disabling Automatic Event Collection because this browser is not supported')\n return\n }\n\n if (!window || !document) {\n return\n }\n\n const handler = (e: Event) => {\n e = e || window?.event\n try {\n this._captureEvent(e)\n } catch (error) {\n logger.error('Failed to capture event', error)\n }\n }\n\n addEventListener(document, 'submit', handler, { capture: true })\n addEventListener(document, 'change', handler, { capture: true })\n addEventListener(document, 'click', handler, { capture: true })\n\n if (this._config.capture_copied_text) {\n const copiedTextHandler = (e: Event) => {\n e = e || window?.event\n try {\n this._captureEvent(e, COPY_AUTOCAPTURE_EVENT)\n } catch (error) {\n logger.error('Failed to capture copy/cut event', error)\n }\n }\n\n addEventListener(document, 'copy', copiedTextHandler, { capture: true })\n addEventListener(document, 'cut', copiedTextHandler, { capture: true })\n }\n }\n\n public startIfEnabled() {\n if (this.isEnabled && !this._initialized) {\n this._addDomEventHandlers()\n this._initialized = true\n }\n }\n\n public onRemoteConfig(response: RemoteConfig) {\n if (response.elementsChainAsString) {\n this._elementsChainAsString = response.elementsChainAsString\n }\n\n // NOTE: Unlike other extensions (heatmaps, web-vitals, etc.), we intentionally\n // DO NOT guard against missing autocapture_opt_out key here. Autocapture uses\n // a \"wait for server, then enable unless explicitly opted out\" model:\n // - Before remote config: autocapture disabled (isEnabled returns false)\n // - After remote config: enabled unless autocapture_opt_out is explicitly true\n // Missing/undefined key → !!undefined = false → autocapture enabled\n // This is intentional and different from opt-in features like heatmaps.\n if (this.instance.persistence) {\n this.instance.persistence.register({\n [AUTOCAPTURE_DISABLED_SERVER_SIDE]: !!response['autocapture_opt_out'],\n })\n }\n // store this in-memory in case persistence is disabled\n this._isDisabledServerSide = !!response['autocapture_opt_out']\n this.startIfEnabled()\n }\n\n public setElementSelectors(selectors: Set<string>): void {\n this._elementSelectors = selectors\n }\n\n public getElementSelectors(element: Element | null): string[] | null {\n const elementSelectors: string[] = []\n\n this._elementSelectors?.forEach((selector) => {\n const matchedElements = document?.querySelectorAll(selector)\n matchedElements?.forEach((matchedElement: Element) => {\n if (element === matchedElement) {\n elementSelectors.push(selector)\n }\n })\n })\n\n return elementSelectors\n }\n\n public get isEnabled(): boolean {\n const persistedServerDisabled = this.instance.persistence?.props[AUTOCAPTURE_DISABLED_SERVER_SIDE]\n const memoryDisabled = this._isDisabledServerSide\n\n if (isNull(memoryDisabled) && !isBoolean(persistedServerDisabled) && !this.instance._shouldDisableFlags()) {\n // We only enable if we know that the server has not disabled it (unless /flags is disabled)\n return false\n }\n\n const disabledServer = this._isDisabledServerSide ?? !!persistedServerDisabled\n const disabledClient = !this.instance.config.autocapture\n return !disabledClient && !disabledServer\n }\n\n private _captureEvent(e: Event, eventName: EventName = '$autocapture'): boolean | void {\n if (!this.isEnabled) {\n return\n }\n\n /*** Don't mess with this code without running IE8 tests on it ***/\n let target = getEventTarget(e)\n if (isTextNode(target)) {\n // defeat Safari bug (see: http://www.quirksmode.org/js/events_properties.html)\n target = (target.parentNode || null) as Element | null\n }\n\n if (eventName === '$autocapture' && e.type === 'click' && e instanceof MouseEvent) {\n if (\n !!this.instance.config.rageclick &&\n this.rageclicks?.isRageClick(e.clientX, e.clientY, e.timeStamp || new Date().getTime())\n ) {\n if (shouldCaptureRageclick(target, this.instance.config.rageclick)) {\n this._captureEvent(e, '$rageclick')\n }\n }\n }\n\n const isCopyAutocapture = eventName === COPY_AUTOCAPTURE_EVENT\n if (\n target &&\n shouldCaptureDomEvent(\n target,\n e,\n this._config,\n // mostly this method cares about the target element, but in the case of copy events,\n // we want some of the work this check does without insisting on the target element's type\n isCopyAutocapture,\n // we also don't want to restrict copy checks to clicks,\n // so we pass that knowledge in here, rather than add the logic inside the check\n isCopyAutocapture ? ['copy', 'cut'] : undefined,\n this.instance\n )\n ) {\n const { props, explicitNoCapture } = autocapturePropertiesForElement(target, {\n e,\n maskAllElementAttributes: this.instance.config.mask_all_element_attributes,\n maskAllText: this.instance.config.mask_all_text,\n elementAttributeIgnoreList: this._config.element_attribute_ignorelist,\n elementsChainAsString: this._elementsChainAsString,\n disableCaptureUrlHashes: this.instance.config.disable_capture_url_hashes,\n })\n\n if (explicitNoCapture) {\n return false\n }\n\n const elementSelectors = this.getElementSelectors(target)\n if (elementSelectors && elementSelectors.length > 0) {\n props['$element_selectors'] = elementSelectors\n }\n\n if (eventName === COPY_AUTOCAPTURE_EVENT) {\n // you can't read the data from the clipboard event,\n // but you can guess that you can read it from the window's current selection\n const selectedContent = makeSafeText(window?.getSelection()?.toString())\n const clipType = (e as ClipboardEvent).type || 'clipboard'\n if (!selectedContent) {\n return false\n }\n props['$selected_content'] = selectedContent\n props['$copy_type'] = clipType\n }\n\n this.instance.capture(eventName, props)\n return true\n }\n }\n\n isBrowserSupported(): boolean {\n return isFunction(document?.querySelectorAll)\n }\n}\n","// Portions of this file are derived from getsentry/sentry-javascript\n// Copyright (c) 2012 Functional Software, Inc. dba Sentry\n// Licensed under the MIT License: https://github.com/getsentry/sentry-javascript/blob/develop/LICENSE\n\n/**\n * Also adapted from https://github.com/PostHog/rrweb/blob/804380afbb1b9bed70b8792cb5a25d827f5c0cb5/packages/utils/src/index.ts#L31\n * after a number of performance reports from Angular users\n */\n\nimport { AssignableWindow } from './globals'\nimport { isAngularZonePresent } from './type-utils'\nimport { isFunction, isNativeFunction } from '@posthog/core'\nimport { logger } from './logger'\n\ninterface NativeImplementationsCache {\n MutationObserver: typeof MutationObserver\n}\n\nconst cachedImplementations: Partial<NativeImplementationsCache> = {}\n\nexport function getNativeImplementation<T extends keyof NativeImplementationsCache>(\n name: T,\n assignableWindow: AssignableWindow\n): NativeImplementationsCache[T] {\n const cached = cachedImplementations[name]\n if (cached) {\n return cached\n }\n\n let impl = assignableWindow[name] as NativeImplementationsCache[T]\n\n if (isNativeFunction(impl) && !isAngularZonePresent()) {\n return (cachedImplementations[name] = impl.bind(assignableWindow) as NativeImplementationsCache[T])\n }\n\n const document = assignableWindow.document\n if (document && isFunction(document.createElement)) {\n try {\n const sandbox = document.createElement('iframe')\n sandbox.hidden = true\n document.head.appendChild(sandbox)\n const contentWindow = sandbox.contentWindow\n if (contentWindow && (contentWindow as any)[name]) {\n impl = (contentWindow as any)[name] as NativeImplementationsCache[T]\n }\n document.head.removeChild(sandbox)\n } catch (e) {\n // Could not create sandbox iframe, just use assignableWindow.xxx\n logger.warn(`Could not create sandbox iframe for ${name} check, bailing to assignableWindow.${name}: `, e)\n }\n }\n\n // Sanity check: This _should_ not happen, but if it does, we just skip caching...\n // This can happen e.g. in tests where fetch may not be available in the env, or similar.\n if (!impl || !isFunction(impl)) {\n return impl\n }\n\n return (cachedImplementations[name] = impl.bind(assignableWindow) as NativeImplementationsCache[T])\n}\n\nexport function getNativeMutationObserverImplementation(assignableWindow: AssignableWindow): typeof MutationObserver {\n return getNativeImplementation('MutationObserver', assignableWindow)\n}\n","import { assignableWindow, document, LazyLoadedDeadClicksAutocaptureInterface } from '../utils/globals'\nimport { PostHog } from '../posthog-core'\nimport { isNull, isNumber, isUndefined } from '@posthog/core'\nimport { getEventTarget, shouldCaptureDeadClick, shouldSkipDeadClick } from '../autocapture-utils'\nimport { DeadClickCandidate, DeadClicksAutoCaptureConfig, Properties } from '../types'\nimport { autocapturePropertiesForElement } from '../autocapture'\nimport { isElementInToolbar, isElementNode, isTag } from '../utils/element-utils'\nimport { getNativeMutationObserverImplementation } from '../utils/prototype-utils'\nimport { addEventListener } from '../utils'\n\nfunction asClick(event: MouseEvent): DeadClickCandidate | null {\n const eventTarget = getEventTarget(event)\n if (eventTarget) {\n return {\n node: eventTarget,\n originalEvent: event,\n timestamp: Date.now(),\n }\n }\n return null\n}\n\nfunction hasModifierKey(event: MouseEvent): boolean {\n return event.ctrlKey || event.metaKey || event.altKey || event.shiftKey\n}\n\nfunction checkTimeout(value: number | undefined, thresholdMs: number) {\n return isNumber(value) && value >= thresholdMs\n}\n\nclass LazyLoadedDeadClicksAutocapture implements LazyLoadedDeadClicksAutocaptureInterface {\n private _mutationObserver: MutationObserver | undefined\n private _lastMutation: number | undefined\n private _lastSelectionChanged: number | undefined\n private _lastVisibilityChange: number | undefined\n private _clicks: DeadClickCandidate[] = []\n private _checkClickTimer: number | undefined\n private _config: Required<Omit<DeadClicksAutoCaptureConfig, 'css_selector_ignorelist'>> &\n Pick<DeadClicksAutoCaptureConfig, 'css_selector_ignorelist'>\n private _onCapture: (click: DeadClickCandidate, properties: Properties) => void\n\n private _defaultConfig = (defaultOnCapture: (click: DeadClickCandidate, properties: Properties) => void) => ({\n element_attribute_ignorelist: [],\n scroll_threshold_ms: 100,\n selection_change_threshold_ms: 100,\n mutation_threshold_ms: 2500,\n capture_clicks_with_modifier_keys: false,\n __onCapture: defaultOnCapture,\n })\n\n private _asRequiredConfig(\n providedConfig?: DeadClicksAutoCaptureConfig\n ): Required<Omit<DeadClicksAutoCaptureConfig, 'css_selector_ignorelist'>> &\n Pick<DeadClicksAutoCaptureConfig, 'css_selector_ignorelist'> {\n const defaultConfig = this._defaultConfig(providedConfig?.__onCapture || this._captureDeadClick.bind(this))\n return {\n element_attribute_ignorelist:\n providedConfig?.element_attribute_ignorelist ?? defaultConfig.element_attribute_ignorelist,\n scroll_threshold_ms: providedConfig?.scroll_threshold_ms ?? defaultConfig.scroll_threshold_ms,\n selection_change_threshold_ms:\n providedConfig?.selection_change_threshold_ms ?? defaultConfig.selection_change_threshold_ms,\n mutation_threshold_ms: providedConfig?.mutation_threshold_ms ?? defaultConfig.mutation_threshold_ms,\n capture_clicks_with_modifier_keys:\n providedConfig?.capture_clicks_with_modifier_keys ?? defaultConfig.capture_clicks_with_modifier_keys,\n css_selector_ignorelist: providedConfig?.css_selector_ignorelist,\n __onCapture: defaultConfig.__onCapture,\n }\n }\n\n constructor(\n readonly instance: PostHog,\n config?: DeadClicksAutoCaptureConfig\n ) {\n this._config = this._asRequiredConfig(config)\n this._onCapture = this._config.__onCapture\n }\n\n start(observerTarget: Node) {\n this._startClickObserver()\n this._startScrollObserver()\n this._startSelectionChangedObserver()\n this._startVisibilityChangeObserver()\n this._startMutationObserver(observerTarget)\n }\n\n private _startMutationObserver(observerTarget: Node) {\n if (!this._mutationObserver) {\n const NativeMutationObserver = getNativeMutationObserverImplementation(assignableWindow)\n this._mutationObserver = new NativeMutationObserver((mutations) => {\n this._onMutation(mutations)\n })\n this._mutationObserver.observe(observerTarget, {\n attributes: true,\n characterData: true,\n childList: true,\n subtree: true,\n })\n }\n }\n\n stop() {\n this._mutationObserver?.disconnect()\n this._mutationObserver = undefined\n assignableWindow.removeEventListener('click', this._onClick)\n assignableWindow.removeEventListener('scroll', this._onScroll, { capture: true })\n assignableWindow.removeEventListener('selectionchange', this._onSelectionChange)\n document?.removeEventListener('visibilitychange', this._onVisibilityChange)\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n private _onMutation(_mutations: MutationRecord[]): void {\n // we don't actually care about the content of the mutations, right now\n this._lastMutation = Date.now()\n }\n\n private _startClickObserver() {\n addEventListener(assignableWindow, 'click', this._onClick)\n }\n\n private _onClick = (event: Event): void => {\n const click = asClick(event as MouseEvent)\n if (!isNull(click) && !this._ignoreClick(click)) {\n this._clicks.push(click)\n }\n\n if (this._clicks.length && isUndefined(this._checkClickTimer)) {\n this._checkClickTimer = assignableWindow.setTimeout(() => {\n this._checkClicks()\n }, 1000)\n }\n }\n\n // `capture: true` is required to get scroll events for other scrollable elements\n // on the page, not just the window\n // see https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#usecapture\n //\n // `passive: true` is used to tell the browser that the scroll event handler will not call `preventDefault()`\n // This allows the browser to optimize scrolling performance by not waiting for our handling of the scroll event\n // see https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#passive\n private _startScrollObserver() {\n addEventListener(assignableWindow, 'scroll', this._onScroll, { capture: true })\n }\n\n private _onScroll = (): void => {\n const candidateNow = Date.now()\n // very naive throttle\n if (candidateNow % 50 === 0) {\n // we can see many scrolls between scheduled checks,\n // so we update scroll delay as we see them\n // to avoid false positives\n this._clicks.forEach((click) => {\n if (isUndefined(click.scrollDelayMs)) {\n click.scrollDelayMs = candidateNow - click.timestamp\n }\n })\n }\n }\n\n private _startSelectionChangedObserver() {\n addEventListener(assignableWindow, 'selectionchange', this._onSelectionChange)\n }\n\n private _onSelectionChange = (): void => {\n this._lastSelectionChanged = Date.now()\n }\n\n private _startVisibilityChangeObserver() {\n addEventListener(document, 'visibilitychange', this._onVisibilityChange)\n }\n\n private _onVisibilityChange = (): void => {\n if (document?.visibilityState === 'visible') {\n this._lastVisibilityChange = Date.now()\n }\n }\n\n private _ignoreClick(click: DeadClickCandidate | null): boolean {\n if (!click) {\n return true\n }\n\n if (!this._config.capture_clicks_with_modifier_keys && hasModifierKey(click.originalEvent)) {\n return true\n }\n\n if (isElementInToolbar(click.node)) {\n return true\n }\n\n const alreadyClickedInLastSecond = this._clicks.some((c) => {\n return c.node === click.node && Math.abs(c.timestamp - click.timestamp) < 1000\n })\n\n if (alreadyClickedInLastSecond) {\n return true\n }\n\n if (isTag(click.node, 'html') || !isElementNode(click.node) || shouldSkipDeadClick(click.node)) {\n return true\n }\n\n if (!shouldCaptureDeadClick(click.node, { css_selector_ignorelist: this._config.css_selector_ignorelist })) {\n return true\n }\n\n return false\n }\n\n private _checkClicks() {\n if (!this._clicks.length) {\n return\n }\n\n clearTimeout(this._checkClickTimer)\n this._checkClickTimer = undefined\n\n const clicksToCheck = this._clicks\n this._clicks = []\n\n for (const click of clicksToCheck) {\n click.mutationDelayMs =\n click.mutationDelayMs ??\n (this._lastMutation && click.timestamp <= this._lastMutation\n ? this._lastMutation - click.timestamp\n : undefined)\n click.absoluteDelayMs = Date.now() - click.timestamp\n click.selectionChangedDelayMs =\n this._lastSelectionChanged && click.timestamp <= this._lastSelectionChanged\n ? this._lastSelectionChanged - click.timestamp\n : undefined\n click.visibilityChangedDelayMs = this._lastVisibilityChange\n ? Math.abs(click.timestamp - this._lastVisibilityChange)\n : undefined\n\n const scrollTimeout = checkTimeout(click.scrollDelayMs, this._config.scroll_threshold_ms)\n const selectionChangedTimeout = checkTimeout(\n click.selectionChangedDelayMs,\n this._config.selection_change_threshold_ms\n )\n const mutationTimeout = checkTimeout(click.mutationDelayMs, this._config.mutation_threshold_ms)\n // we want to timeout eventually even if nothing else catches it...\n // we leave a little longer than the maximum threshold to give the other checks a chance to catch it\n const absoluteTimeout = checkTimeout(click.absoluteDelayMs, this._config.mutation_threshold_ms * 1.1)\n\n const hadScroll = isNumber(click.scrollDelayMs) && click.scrollDelayMs < this._config.scroll_threshold_ms\n const hadMutation =\n isNumber(click.mutationDelayMs) && click.mutationDelayMs < this._config.mutation_threshold_ms\n const hadSelectionChange =\n isNumber(click.selectionChangedDelayMs) &&\n click.selectionChangedDelayMs < this._config.selection_change_threshold_ms\n const hadVisibilityChange =\n isNumber(click.visibilityChangedDelayMs) &&\n click.visibilityChangedDelayMs < this._config.selection_change_threshold_ms\n\n if (hadScroll || hadMutation || hadSelectionChange || hadVisibilityChange) {\n continue\n }\n\n const visibilityChangedTimeout = checkTimeout(\n click.visibilityChangedDelayMs,\n this._config.selection_change_threshold_ms\n )\n\n if (\n scrollTimeout ||\n mutationTimeout ||\n absoluteTimeout ||\n selectionChangedTimeout ||\n visibilityChangedTimeout\n ) {\n this._onCapture(click, {\n $dead_click_last_mutation_timestamp: this._lastMutation,\n $dead_click_event_timestamp: click.timestamp,\n $dead_click_scroll_timeout: scrollTimeout,\n $dead_click_mutation_timeout: mutationTimeout,\n $dead_click_absolute_timeout: absoluteTimeout,\n $dead_click_selection_changed_timeout: selectionChangedTimeout,\n $dead_click_visibility_changed_timeout: visibilityChangedTimeout,\n })\n } else if (click.absoluteDelayMs < this._config.mutation_threshold_ms) {\n // keep waiting until next check\n this._clicks.push(click)\n }\n }\n\n if (this._clicks.length && isUndefined(this._checkClickTimer)) {\n this._checkClickTimer = assignableWindow.setTimeout(() => {\n this._checkClicks()\n }, 1000)\n }\n }\n\n private _captureDeadClick(click: DeadClickCandidate, properties: Properties) {\n // TODO need to check safe and captur-able as with autocapture\n // TODO autocaputure config\n this.instance.capture(\n '$dead_click',\n {\n ...properties,\n ...autocapturePropertiesForElement(click.node, {\n e: click.originalEvent,\n maskAllElementAttributes: this.instance.config.mask_all_element_attributes,\n maskAllText: this.instance.config.mask_all_text,\n elementAttributeIgnoreList: this._config.element_attribute_ignorelist,\n // TRICKY: it appears that we were moving to elementsChainAsString, but the UI still depends on elements, so :shrug:\n elementsChainAsString: false,\n disableCaptureUrlHashes: this.instance.config.disable_capture_url_hashes,\n }).props,\n $dead_click_scroll_delay_ms: click.scrollDelayMs,\n $dead_click_mutation_delay_ms: click.mutationDelayMs,\n $dead_click_absolute_delay_ms: click.absoluteDelayMs,\n $dead_click_selection_changed_delay_ms: click.selectionChangedDelayMs,\n $dead_click_visibility_changed_delay_ms: click.visibilityChangedDelayMs,\n },\n {\n timestamp: new Date(click.timestamp),\n }\n )\n }\n}\n\nassignableWindow.__PosthogExtensions__ = assignableWindow.__PosthogExtensions__ || {}\nassignableWindow.__PosthogExtensions__.initDeadClicksAutocapture = (ph, config) =>\n new LazyLoadedDeadClicksAutocapture(ph, config)\n\nexport default LazyLoadedDeadClicksAutocapture\n"],"names":["_a","EventType","EventType2","IncrementalSource","IncrementalSource2","MouseInteractions","MouseInteractions2","PointerTypes","PointerTypes2","CanvasContext","CanvasContext2","MediaInteractions","MediaInteractions2","NodeType","NodeType2","_a2","_b","_c","_d","_a3","source","name","replacement","original","wrapped","prototype","Object","defineProperties","__rrweb_original__","enumerable","value","_unused","types_SurveyValidationType","SurveyValidationType","includes","str","needle","indexOf","trim","ObjProto","type_utils_hasOwnProperty","hasOwnProperty","type_utils_toString","toString","isArray","Array","obj","call","isFunction","x","isObject","isUndefined","isString","isNull","isNullish","isNumber","isBoolean","isFormData","FormData","isPrimitive","isBuiltin","candidate","className","isEvent","Event","base","isInstanceOf","MOBILE","ANDROID","TABLET","ANDROID_TABLET","IPAD","APPLE_WATCH","APPLE","BLACKBERRY","NINTENDO","PLAYSTATION","XBOX","WINDOWS_PHONE","WINDOWS","NOKIA","OUYA","GENERIC","GENERIC_MOBILE","toLowerCase","GENERIC_TABLET","XBOX_REGEX","RegExp","PLAYSTATION_REGEX","NINTENDO_REGEX","BLACKBERRY_REGEX","stripUrlHash","url","split","parsedStackResults","lastKeysCount","cachedFilenameChunkIds","getLengthFromRules","rules","type","rule","find","r","getFilenameToChunkIdMap","stackParser","chunkIdMap","globalThis","_posthogChunkIds","chunkIdKeys","keys","length","reduce","acc","stackKey","result","parsedStack","i","stackFrame","filename","chunkId","UNKNOWN_FUNCTION","createFrame","platform","func","lineno","colno","frame","function","in_app","extractSafariExtensionDetails","isSafariExtension","isSafariWebExtension","chromeRegexNoFnName","chromeRegex","chromeEvalRegex","chromeStackLineParser","line","noFnParts","exec","col","parts","subMatch","geckoREgex","geckoEvalRegex","geckoStackLineParser","WEBPACK_ERROR_REGEXP","ERROR_TYPES_PATTERN","severityLevels","extractExceptionKeysForMessage","err","maxLength","sort","serialized","slice","join","win","window","undefined","global","self","File","navigator","document","XMLHttpRequest","userAgent","assignableWindow","isDocument","Document","_createLogger","prefix","_temp","debugEnabled","logger","_log","level","POSTHOG_DEBUG","console","consoleLog","_len","arguments","args","_key","debug","_len2","_key2","info","_len3","_key3","warn","_len4","_key4","error","_len5","_key5","critical","_len6","_key6","uninitializedWarning","methodName","createLogger","additionalPrefix","options","each","iterator","forEach","val","key","extend","prop","entries","ownProps","resArray","addEventListener","element","event","callback","capture","passive","formDataToQuery","formdata","arg_separator","use_val","use_key","tph_arr","encodeURIComponent","patch","__posthog_wrapped__","isHostOnDenyList","_options$payloadHostD","hostname","URL","hostnameFromURL","defaultNotDenied","isHostDenied","payloadHostDenyList","deny","endsWith","NODE_TYPE_ELEMENT","NODE_TYPE_TEXT","NODE_TYPE_DOCUMENT_FRAGMENT","isElementNode","el","nodeType","isTag","tag","tagName","isShadowRoot","host","splitClassString","s","getClassNames","baseVal","getAttribute","getSafeText","elText","shouldCaptureElement","isSensitiveElement","childNodes","child","_makeSafeText","isTextNode","textContent","filter","shouldCaptureValue","replace","substring","makeSafeText","autocaptureCompatibleElements","getParentElement","curEl","parentNode","DEFAULT_DEAD_CLICK_IGNORE_LIST","cannotCheckForAutocapture","getElementAndParentsForElement","captureOnAnyElement","parentIsUsefulElement","targetElementList","push","compStyles","getComputedStyle","getPropertyValue","classes","id","test","coreCCPattern","anchoredCCRegex","unanchoredCCRegex","coreSSNPattern","anchoredSSNRegex","unanchoredSSNRegex","anchorRegexes","getDirectAndNestedSpanText","target","text","getNestedSpanText","_child$tagName","spanText","e","escapeQuotes","input","extractAttrClass","attr_class","MAX_PAYLOAD_SIZE_BYTES","defaultNetworkOptions","initiatorTypes","maskRequestFn","data","recordHeaders","recordBody","recordInitialRequests","recordPerformance","performanceEntryTypeToObserve","payloadSizeLimitBytes","streamNetworkBody","isNavigationTiming","entry","entryType","isResourceTiming","shouldRecordHeaders","isRequest","Request","NEVER_RECORD_BODY_CONTENT_TYPES","shouldRecordBody","_ref","headers","matchesContentType","contentTypes","contentTypeHeader","contentType","some","ct","isBlobURL","startsWith","protocol","_unused2","recordBodyType","getRequestPerformanceEntry","_x","_x2","_x3","_x4","_x5","_x6","_getRequestPerformanceEntry","apply","this","_asyncToGenerator","initiatorType","start","end","attempt","performanceEntry","array","predicate","startTime","findLast","performance","getEntriesByName","Promise","resolve","setTimeout","_tryReadXHRBody","_ref2","body","JSON","stringify","_unused3","exposesServerTiming","prepareRequest","_ref3","method","status","networkRequest","isInitial","responseEnd","timeOrigin","Math","floor","Date","now","timestamp","requests","_extends","toJSON","round","endTime","requestHeaders","requestBody","responseHeaders","responseBody","timing","serverTiming","duration","contentTypePrefixDenyList","isReadableStreamBody","getReader","tee","BODY_READ_TIMEOUT_MS","BODY_READ_TIMEOUT_MESSAGE","BODY_READ_FAILED_MESSAGE","bodyReadFailedMessage","reason","bodyTooLargeMessage","limitBytes","_readBody","timeout","clone","then","txt","finally","clearTimeout","_unused5","_tryReadBody","_options$payloadSizeL","min","effectivePayloadLimitBytes","_r$headers","headerValue","get","contentLength","parseInt","Number","isFinite","_unused4","_contentLengthExceedsLimit","reader","settled","cancel","_reader","_unused6","done","_unused7","TextDecoder","_unused9","chunks","received","pump","read","_ref5","streamDone","decode","totalBytes","merged","Uint8Array","offset","chunk","set","byteLength","concatChunks","_unused8","_tryReadBodyStreaming","_tryReadRequestBody2","_ref6","_tryReadResponseBody2","_ref7","cannotReadBodyReason","_ref4","_r$headers$get","contentTypeIsDenied","_checkForCannotReadResponseBody","initialisedHandler","initNetworkObserver","networkOptions","assign","cb","request","maskedRequest","performanceObserver","initialPerformanceEntries","getEntries","flatMap","observer","PerformanceObserver","performanceEntries","wrappedInitiatorFilter","entryTypes","supportedEntryTypes","observe","disconnect","initPerformanceObserver","xhrObserver","fetchObserver","recordRequestHeaders","recordResponseHeaders","restorePatch","originalOpen","async","username","password","xhr","req","originalSetRequestHeader","setRequestHeader","bind","header","originalSend","send","cleanup","removeEventListener","readyStateListener","readyState","DONE","getAllResponseHeaders","shift","response","catch","initXhrObserver","originalFetch","_ref8","init","res","_x7","_tryReadRequestBody","_x8","_tryReadResponseBody","_res","_x9","_x0","initFetchObserver","getRecordNetworkPlugin","__PosthogExtensions__","rrwebPlugins","getRecordConsolePlugin","rrweb","record","rrwebRecord","version","wasMaxDepthReached","resetMaxDepthState","rrwebConsoleRecord","d","w","_","t","u","o","f","c","n","__b","a","__r","v","diffed","l","__c","m","unmount","__","p","__h","__H","D","__N","setState","__f","every","props","shouldComponentUpdate","componentWillUpdate","__e","h","y","__s","C","A","T","current","context","sub","j","__P","z","B","__v","__k","__m","requestAnimationFrame","k","cancelAnimationFrame","SurveyWidgetType","Tab","Selector","SurveyPosition","TopLeft","TopRight","TopCenter","MiddleLeft","MiddleRight","MiddleCenter","Left","Center","Right","NextToTrigger","SurveyTabPosition","Top","Bottom","SurveyType","Popover","API","Widget","ExternalSurvey","SurveyQuestionType","Open","MultipleChoice","SingleChoice","Rating","Link","SurveyQuestionBranchingType","End","ResponseBased","SpecificQuestion","SurveySchedule","SurveyEventName","SHOWN","DISMISSED","SENT","ABANDONED","SurveyEventProperties","SURVEY_ID","SURVEY_NAME","SURVEY_ITERATION","SURVEY_ITERATION_START_DATE","SURVEY_PARTIALLY_COMPLETED","SURVEY_SUBMISSION_ID","SURVEY_COMPLETED","SURVEY_LANGUAGE","getSurveyResponseKey","questionId","getSurveyResponseValue","responses","buildSurveyResponseProperties","survey","oldFormatResponses","questions","question","originalQuestionIndex","oldResponseKey","$survey_questions","map","getSurveyInteractionProperty","action","surveyProperty","current_iteration","getTrimmedLanguage","normalizeLanguageCode","languageCode","findBestTranslationMatch","translations","targetLanguage","normalizedTarget","exactMatch","baseLanguage","baseMatch","applySurveyTranslation","_translatedResults$fi","translationKey","translated","hasTranslation","_survey$translations","translation","appearance","thankYouMessageHeader","thankYouMessageDescription","thankYouMessageCloseButtonText","submitButtonText","backButtonText","hasAppearanceTranslation","translatedResults","_question$translation","matchedKey","hasChanges","questionTranslation","description","buttonText","link","lowerBoundLabel","upperBoundLabel","choices","isTranslatedChoices","mergeQuestionTranslation","translatedQuestions","anyQuestionTranslated","questionMatchedKey","SURVEY_LOGGER","SURVEY_IN_PROGRESS_PREFIX","getSurveyStorageKey","getSurveySeenKey","setSurveySeenOnLocalStorage","surveySeenKey","localStorage","getItem","setItem","IN_APP_SURVEY_TYPES","trunc","ceil","isInteger","UUID","constructor","bytes","TypeError","fromFieldsV7","unixTsMs","randA","randBHi","randBLo","RangeError","pow","Error","equals","other","compareTo","diff","sign","V7Generator","_timestamp","_counter","_random","DefaultRandom","generate","generateOrAbort","valueAfterReset","ts","_resetCounter","nextUint32","defaultGenerator","getRandomValues","buffer","UUIDV7_DENY_WEAK_RNG","random","crypto","_buffer","Uint32Array","_cursor","Infinity","uuidv7","uuidv7obj","isMatchingRegex","pattern","isValidRegex","propertyComparisons","exact","targets","values","is_not","regex","not_regex","icontains","not_icontains","gt","numValue","parseFloat","isNaN","lt","_localStorage_supported","localStore","_is_supported","supported","_set","_get","_remove","_error","msg","_parse","parse","removeItem","_window","_document","BLACK_TEXT_COLOR","defaultSurveyAppearance","fontFamily","backgroundColor","submitButtonColor","submitButtonTextColor","ratingButtonColor","ratingButtonActiveColor","borderColor","placeholder","whiteLabel","displayThankYouMessage","position","widgetType","widgetLabel","widgetColor","zIndex","String","disabledButtonOpacity","maxWidth","textSubtleColor","boxPadding","boxShadow","borderRadius","shuffleQuestions","surveyPopupDelaySeconds","outlineColor","inputBackground","inputTextColor","scrollbarThumbColor","scrollbarTrackColor","BOTTOM_BORDER_SURVEY_POSITIONS","hex2rgb","hexColor","getContrastingTextColor","color","rgb","nameColorToHex","aliceblue","antiquewhite","aqua","aquamarine","azure","beige","bisque","black","blanchedalmond","blue","blueviolet","brown","burlywood","cadetblue","chartreuse","chocolate","coral","cornflowerblue","cornsilk","crimson","cyan","darkblue","darkcyan","darkgoldenrod","darkgray","darkgreen","darkkhaki","darkmagenta","darkolivegreen","darkorange","darkorchid","darkred","darksalmon","darkseagreen","darkslateblue","darkslategray","darkturquoise","darkviolet","deeppink","deepskyblue","dimgray","dodgerblue","firebrick","floralwhite","forestgreen","fuchsia","gainsboro","ghostwhite","gold","goldenrod","gray","green","greenyellow","honeydew","hotpink","indigo","ivory","khaki","lavender","lavenderblush","lawngreen","lemonchiffon","lightblue","lightcoral","lightcyan","lightgoldenrodyellow","lightgrey","lightgreen","lightpink","lightsalmon","lightseagreen","lightskyblue","lightslategray","lightsteelblue","lightyellow","lime","limegreen","linen","magenta","maroon","mediumaquamarine","mediumblue","mediumorchid","mediumpurple","mediumseagreen","mediumslateblue","mediumspringgreen","mediumturquoise","mediumvioletred","midnightblue","mintcream","mistyrose","moccasin","navajowhite","navy","oldlace","olive","olivedrab","orange","orangered","orchid","palegoldenrod","palegreen","paleturquoise","palevioletred","papayawhip","peachpuff","peru","pink","plum","powderblue","purple","red","rosybrown","royalblue","saddlebrown","salmon","sandybrown","seagreen","seashell","sienna","silver","skyblue","slateblue","slategray","snow","springgreen","steelblue","tan","teal","thistle","tomato","turquoise","violet","wheat","white","whitesmoke","yellow","yellowgreen","colorMatch","match","g","b","sqrt","retrieveSurveyShadow","posthog","widgetClassName","getSurveyContainerClass","existingDiv","querySelector","shadowRoot","shadow","isNewlyCreated","div","createElement","addSurveyCSSVariablesToElement","effectiveAppearance","hostStyle","style","surveyHasBottomBorder","setProperty","defaultFontStack","getFontFamily","textColor","userInputBg","inputBackgroundColor","inputBgColor","attachShadow","mode","stylesheet","prepareStylesheet","innerText","_posthog$config","config","prepare_external_dependency_stylesheet","setAttribute","getSurveyStylesheet","existingStylesheet","removeChild","appendChild","sendSurveyEvent","surveySubmissionId","isSurveyCompleted","properties","surveyLanguage","current_iteration_start_date","sessionRecordingUrl","get_session_replay_url","$set","dispatchEvent","CustomEvent","detail","surveyId","clearInProgressSurveyState","_buildSurveyEventProperties","inProgressSurvey","dismissedSurveyEvent","readOnly","getInProgressSurveyState","sendSurveyAbandonedEvent","abandonedKey","getSurveyAbandonedKey","transport","shuffle","reverseIfUnshuffled","unshuffled","shuffled","index","reverse","getDisplayOrderQuestions","enable_partial_responses","canActivateRepeatedly","_survey$conditions3","conditions","events","repeatedActivation","_survey$conditions","_survey$conditions2","hasEvents","schedule","isSurveyInProgress","SurveyContext","createContext","isPreviewMode","previewPageIndex","onPopupSurveyDismissed","isPopup","onPreviewSubmit","onPreviewBack","useSurveyContext","useContext","renderChildrenAsTextOrHtml","component","children","renderAsHtml","cloneElement","dangerouslySetInnerHTML","__html","doesSurveyUrlMatch","_survey$conditions4","_survey$conditions5","instance","_window$location","defaultUrl","href","location","_instance$config","override","get_current_url","applyUrlTargetingOverride","matchType","defaultMatchType","urlMatchType","doesSurveyDeviceTypesMatch","_survey$conditions6","_survey$conditions7","deviceTypes","_navigator$userAgentD","_window$screen","_window$screen2","_options$maxTouchPoin","_options$screenWidth","_options$screenHeight","_options$devicePixelR","device","deviceType","userAgentDataPlatform","userAgentData","maxTouchPoints","screenWidth","screen","width","screenHeight","height","devicePixelRatio","user_agent","detectDevice","doesDeviceTypeMatch","deviceTypesMatchType","getInProgressSurveyStateKey","setInProgressSurveyState","state","stateString","asSelector","getPopoverPosition","surveyWidgetType","top","left","transform","right","satisfiedEmoji","_jsx","xmlns","viewBox","neutralEmoji","dissatisfiedEmoji","veryDissatisfiedEmoji","verySatisfiedEmoji","thumbsUpEmoji","thumbsDownEmoji","cancelSVG","fill","_jsxs","IconPosthogLogo","maskType","maskUnits","mask","PostHogLogo","urlParams","queryString","rel","BottomSection","submitDisabled","onSubmit","skipSubmitButton","canGoBack","onBack","showBackButton","submitButton","disabled","onClick","open","utm_source","QuestionHeader","forceDisableHtml","htmlFor","class","descriptionContentType","Cancel","ConfirmationMessage","onClose","useEffect","handleKeyDown","preventDefault","role","tabIndex","hideCancelButton","isValidStringArray","item","OpenTextQuestion","displayQuestionIndex","initialValue","inputRef","useRef","setText","useState","_inputRef$current","focus","validationError","useMemo","optional","_rule$errorMessage","_rule$errorMessage2","trimmed","MinLength","errorMessage","MaxLength","getValidationError","validation","minLength","requirementsHint","effectiveMin","getRequirementsHint","handleSubmit","handlePreviewSubmit","Fragment","ref","rows","onInput","currentTarget","stopPropagation","onKeyDown","metaKey","ctrlKey","LinkQuestion","RatingQuestion","_emojiScaleLists$ques","scale","starting","rating","setRating","isThumbSurvey","display","num","emojiScaleLists","emoji","idx","gridTemplateColumns","getScaleNumbers","number","RatingButton","active","setActiveNumber","MultipleChoiceQuestion","openChoiceInputRef","shuffleOptions","displayOrderChoices","openEndedChoice","hasOpenChoice","pop","shuffledOptions","getDisplayOrderChoices","selectedChoices","setSelectedChoices","initializeSelectedChoices","questionType","openEndedState","setOpenEndedState","initializeOpenEndedState","isSelected","inputValue","openEndedValue","choice","isSingleChoiceQuestion","isMultipleChoiceQuestion","shouldSkipSubmit","handleChoiceChange","isOpenChoice","newOpenSelected","prev","_openChoiceInputRef$c","handleOpenEndedInputChange","newValue","handleOpenEndedKeyDown","isSubmitDisabled","inputId","openInputId","isChecked","checked","onChange","fiveScaleNumbers","sevenScaleNumbers","tenScaleNumbers","getNextSurveyStep","currentQuestionIndex","_question$branching","nextQuestionIndex","branching","_question$branching2","selectedChoiceIndex","responseValues","nextStep","_question$branching3","ratingBucket","responseValue","getRatingBucketForResponseValue","applySurveyTranslationForUser","userLanguage","overrideLanguage","storedPersonProperties","locale","explicitLanguage","personLanguage","language","getLanguageFromStoredPersonProperties","detectedLocale","detectSurveyLanguage","override_display_language","get_property","detectUserLanguage","DISPATCH_FEEDBACK_WIDGET_EVENT","WIDGET_LISTENER_ATTRIBUTE","getNextToTriggerPosition","surveyWidth","buttonRect","getBoundingClientRect","viewportHeight","innerHeight","viewportWidth","innerWidth","spaceBelow","bottom","showAbove","SurveyManager","_this","_surveyTimeouts","Map","_widgetSelectorListeners","_prefillHandledSurveys","Set","handlePageUnload","surveys","_posthog","handlePopoverSurvey","surveyParam","_survey$appearance","_survey$appearance2","_survey$appearance3","_survey$appearance5","translatedSurvey","_translateSurveyForRendering","selector","widgetSelector","_clearSurveyTimeout","initialResponses","_handleInitialResponses","_addSurveyToFocus","positionStyle","_survey$appearance4","targetElement","delaySeconds","surveyPopupProps","removeSurveyFromFocus","_removeSurveyFromFocus","skipShownEvent","render","SurveyPopup","timeoutId","delete","_shouldDisplaySurvey","_handleWidget","FeedbackWidget","_removeWidgetSelectorListener","_removeSurveyFromDom","existing","listener","removeAttribute","_manageWidgetSelectorListener","currentElement","existingListenerData","hasAttribute","_survey$appearance6","_survey$appearance7","positionStyles","renderPopover","renderSurvey","_this$_posthog$config","prefillFromUrl","_handleUrlPrefill","getActiveMatchingSurveys","forceReload","_this$_posthog","getSurveys","targetingMatchedSurveys","callSurveysAndEvaluateDisplayLogic","inAppSurveysWithDisplayLogic","matchingIds","pendingSurveyId","from","has","cancelSurvey","inAppSurveysQueue","_sortSurveysByAppearanceDelay","activeSelectorSurveys","_survey$appearance8","_survey$appearance9","_survey$appearance0","_survey$appearance1","add","_surveyInFocus","_a$appearance","_b$appearance","isSurveyInProgressA","isSurveyInProgressB","aIsAlways","bIsAlways","params","searchString","autoSubmit","cleanSearch","pairs","pair","decodedKey","decodeURIComponent","decodedValue","questionIndex","extractPrefillParamsFromUrl","search","_processPrefillData","submissionId","skippedResponses","prefillParams","indexStr","responseKey","choiceIndex","choiceIndices","uniqueChoices","convertPrefillToResponses","prefilledIndices","startQuestionIndex","currentIndex","MAX_ITERATIONS","calculatePrefillStartIndex","lastQuestionIndex","_isSurveyFeatureFlagEnabled","flagKey","flagVariant","_this$_posthog$featur","_this$_posthog$featur2","isFeatureEnabled","featureFlags","send_event","flagVariantCheck","getFeatureFlag","_isSurveyConditionMatched","_survey$conditions8","doesSurveyMatchSelector","_internalFlagCheckSatisfied","internal_targeting_flag_key","checkSurveyEligibility","eligibility","eligible","start_date","end_date","isSurveyRunning","linkedFlagVariant","linked_flag_key","targeting_flag_key","periodDays","lastSeenDate","date","diffMs","abs","getTime","hasPeriodPassed","seenSurveyWaitPeriodInDays","getSurveySeen","_hasActionOrEventTriggeredSurvey","_this$_posthog$survey","doesSurveyActivateByEvent","actions","doesSurveyActivateByAction","surveysActivatedByEventsOrActions","_surveyEventReceiver","_checkFlags","_survey$feature_flag_","feature_flag_keys","shadowContainer","remove","getTestAPI","addSurveyToFocus","surveyInFocus","surveyTimeouts","handleWidget","manageWidgetSelectorListener","sortSurveysByAppearanceDelay","checkFlags","isSurveyFeatureFlagEnabled","generateSurveys","isSurveysEnabled","intervalId","surveyManager","disable_surveys_automatic_display","startInterval","setInterval","hidden","clearInterval","useHideSurveyOnURLChange","setSurveyVisible","checkUrlMatch","_survey$appearance10","isSurveyTypeWidget","doesSurveyMatchUrlCondition","isSurveyWidgetTypeTab","originalPushState","history","pushState","originalReplaceState","replaceState","getTabPositionStyles","transformOrigin","_survey$appearance13","_survey$appearance14","_survey$appearance15","_survey$appearance16","_survey$appearance17","_survey$appearance18","onCloseConfirmationMessage","surveyContainerRef","surveyPopupDelayMilliseconds","isPopupVisible","isSurveySent","hidePopupWithViewTransition","millisecondDelay","setIsPopupVisible","setIsSurveySent","removeDOMAndHidePopup","startViewTransition","_surveyContainerRef$c","finished","handleSurveyClosed","handleSurveySent","_survey$appearance11","_survey$appearance12","autoDisappear","showSurvey","toISOString","usePopupVisibility","shouldShowConfirmation","surveyContextValue","getInProgressSurvey","Provider","thankYouMessageDescriptionContentType","Questions","_survey$appearance19","_survey$appearance20","questionsResponses","setQuestionsResponses","inProgressSurveyData","setCurrentQuestionIndex","visitedIndices","setVisitedIndices","_inProgressSurveyData","surveyQuestions","allowGoBack","currentQuestion","at","getQuestionComponent","newResponses","newVisitedIndices","visitedResponseKeys","_surveyQuestions$i","responsesOnPath","fromEntries","_ref9","onNextButtonClick","onBackButtonClick","previousIndex","_ref0","_survey$appearance22","_survey$appearance23","_survey$appearance24","_survey$appearance25","_survey$appearance26","_survey$appearance27","_survey$appearance28","isFeedbackButtonVisible","setIsFeedbackButtonVisible","setShowSurvey","styleOverrides","setStyleOverrides","toggleSurvey","_survey$appearance21","handleShowSurvey","_customEvent$detail","customEvent","resetShowSurvey","tabPosition","_ref1","baseProps","_createElement","extendPostHogWithSurveys","appendWithLimit","budget","remaining","truncated","stringifyStringWithLimit","low","high","mid","isJSONSerializablePrimitive","collectAttributeValue","collector","keysRemaining","sizeRemaining","collectFlattenedAttributes","seen","childKey","stringifyValueWithLimit","inArray","attributeCollector","isNumberOrBoolean","objectTag","valueOf","errorObject","message","stack","_unused0","isFirst","propertyValue","_unused1","_unused10","propertyPrefix","partsBeforeProperty","remainingBeforeProperty","truncatedBeforeProperty","partsBeforeValue","truncatedAfterValue","_unused11","LEVEL_MAP","log","logs","initializeLogs","attributes","_loop","originalConsoleLog","is_capturing","_posthog$logs","flattenedAttributes","stringifyArgsSafely","sizeLimit","WeakSet","logAttributes","body_truncated","_captureConsoleLog","_unused12","errorPropertiesBuilder","coercers","modifiers","buildFromUnknown","hint","mechanism","handled","exceptionWithCause","buildCoercingContext","parsingContext","buildParsingContext","exceptionWithStack","parseStacktrace","$exception_list","convertToExceptionList","$exception_level","modifyFrames","exceptionList","exc","stacktrace","frames","applyModifiers","coerceFallback","ctx","_ctx$syntheticExcepti","syntheticException","synthetic","cause","applyChunkIds","skipFirstLines","chunk_id","applyCoercers","adapter","coerce","_this2","newFrames","modifier","_mechanism$type","_mechanism$handled","_exceptionWithStack$s","currentException","_hint$skipFirstLines","depth","next","isDOMException","isDOMError","hasStack","getType","getValue","isCustomEventWrappingRejection","getUnhandledRejectionReason","getMessage","getStack","_ctx","evt","constructorName","errorProperty","getErrorPropertyFromObject","isSeverityLevel","getObjectClassName","isEmptyString","getPrototypeOf","getInfos","groups","parsers","lines","cleanedLine","parser","localStack","arr","reverseAndStripFrames","createStackParser","posthogErrorWrappingFunctions","wrapOnError","captureFn","originalOnError","onerror","_originalOnError","errorProperties","__POSTHOG_INSTRUMENTED__","_win$onerror","wrapUnhandledRejection","originalOnUnhandledRejection","onunhandledrejection","ev","_originalOnUnhandledR","_win$onunhandledrejec","wrapConsoleError","con","originalConsoleError","arg","_con$error","errorWrappingFunctions","SESSION_ID_HEADER","WINDOW_ID_HEADER","DISTINCT_ID_HEADER","TRACING_HEADERS","REQUEST_INIT_KEYS","property","isObjectLike","getRequestUrl","addTracingHeaders","hostnames","distinctId","sessionManager","reqHostname","hasAddedHeaders","sessionId","windowId","checkAndGetSessionAndWindowId","currentDistinctId","getDistinctId","patchFns","_patchFetch","patchFetch","originalArgs","fetchArgs","requestUrl","Headers","initWithHeaders","createFetchInitWithHeaders","originalInit","Proxy","Reflect","create","defineProperty","configurable","writable","ownKeys","getOwnPropertyDescriptor","targetDescriptor","descriptor","_patchXHR","patchXHR","tracingHeadersPatchFns","postHogTracingHeadersPatchFns","persisted","timeStamp","delta","getEntriesByType","responseStart","_s$activationStart","_s","activationStart","prerendering","wasDiscarded","navigationType","WeakMap","_this$t","hadRecentInput","queueMicrotask","buffered","visibilityState","_globalThis$performan","firstHiddenTime","onHidden","max","reportAllChanges","E","L","P","M","interactionId","_performance$interact","interactionCount","F","clear","_this$m","_this$p","splice","requestIdleCallback","cancelIdleCallback","once","q","_this$m2","N","postHogWebVitalsCallbacks","onLCP","takeRecords","isTrusted","onCLS","onFCP","onINP","PerformanceEventTiming","_i$durationThreshold","durationThreshold","limitText","previousElementSibling","_el","previousSibling","autocapturePropertiesForElement","_elementsJson$","_elementsJson$2","maskAllElementAttributes","maskAllText","elementAttributeIgnoreList","disableCaptureUrlHashes","externalHref","elements","elementsJson","autocaptureAugmentProperties","explicitNoCapture","shouldCaptureEl","hrefAttr","elem","maskAllAttributes","maskText","elementAttributeIgnorelist","tag_name","attr","attributeName","nthChild","nthOfType","currentElem","getPropertiesFromElement","augmentProperties","propertyKey","getAugmentPropertiesFromElement","_convertToURL","hrefHost","locationHost","$event_type","$ce_version","$elements","$elements_chain","ret","_element$nth_child","_element$nth_of_type","el_string","single_class","nth_child","nth_of_type","attr_id","sortedAttributes","localeCompare","elementsToString","_el$$el_text","_el$attr__href","extractElements","$el_text","$external_click_url","loadWebVitalsCallbacks","cachedImplementations","getNativeMutationObserverImplementation","cached","impl","Zone","sandbox","head","contentWindow","getNativeImplementation","checkTimeout","thresholdMs","LazyLoadedDeadClicksAutocapture","_asRequiredConfig","providedConfig","_providedConfig$eleme","_providedConfig$scrol","_providedConfig$selec","_providedConfig$mutat","_providedConfig$captu","defaultConfig","_defaultConfig","__onCapture","_captureDeadClick","element_attribute_ignorelist","scroll_threshold_ms","selection_change_threshold_ms","mutation_threshold_ms","capture_clicks_with_modifier_keys","css_selector_ignorelist","_clicks","defaultOnCapture","_onClick","click","eventTarget","srcElement","_e$target","composedPath","getEventTarget","node","originalEvent","asClick","_ignoreClick","_checkClickTimer","_checkClicks","_onScroll","candidateNow","scrollDelayMs","_onSelectionChange","_lastSelectionChanged","_onVisibilityChange","_lastVisibilityChange","_config","_onCapture","observerTarget","_startClickObserver","_startScrollObserver","_startSelectionChangedObserver","_startVisibilityChangeObserver","_startMutationObserver","_mutationObserver","NativeMutationObserver","mutations","_onMutation","characterData","childList","subtree","stop","_this$_mutationObserv","_mutations","_lastMutation","altKey","shiftKey","Element","closest","alreadyClickedInLastSecond","shouldSkipDeadClick","_config$css_selector_","selectorIgnoreList","selectorList","_ret2","_loop2","matches","matchesSelector","msMatchesSelector","mozMatchesSelector","webkitMatchesSelector","oMatchesSelector","elementMatchesCSSSelector","checkIfElementsMatchCSSSelector","shouldCaptureDeadClick","clicksToCheck","_click$mutationDelayM","mutationDelayMs","absoluteDelayMs","selectionChangedDelayMs","visibilityChangedDelayMs","scrollTimeout","selectionChangedTimeout","mutationTimeout","absoluteTimeout","hadScroll","hadMutation","hadSelectionChange","hadVisibilityChange","visibilityChangedTimeout","$dead_click_last_mutation_timestamp","$dead_click_event_timestamp","$dead_click_scroll_timeout","$dead_click_mutation_timeout","$dead_click_absolute_timeout","$dead_click_selection_changed_timeout","$dead_click_visibility_changed_timeout","mask_all_element_attributes","mask_all_text","disable_capture_url_hashes","$dead_click_scroll_delay_ms","$dead_click_mutation_delay_ms","$dead_click_absolute_delay_ms","$dead_click_selection_changed_delay_ms","$dead_click_visibility_changed_delay_ms","initDeadClicksAutocapture","ph"],"mappings":"ijBAAAA,mKAAIC,EAA6B,CAACC,IAChCA,EAAWA,EAA6B,iBAAI,GAAK,mBACjDA,EAAWA,EAAiB,KAAI,GAAK,OACrCA,EAAWA,EAAyB,aAAI,GAAK,eAC7CA,EAAWA,EAAgC,oBAAI,GAAK,sBACpDA,EAAWA,EAAiB,KAAI,GAAK,OACrCA,EAAWA,EAAmB,OAAI,GAAK,SACvCA,EAAWA,EAAmB,OAAI,GAAK,SAChCA,GARwB,CAS9BD,GAAa,CAAA,GAEZE,EAAqC,CAACC,IACxCA,EAAmBA,EAA6B,SAAI,GAAK,WACzDA,EAAmBA,EAA8B,UAAI,GAAK,YAC1DA,EAAmBA,EAAqC,iBAAI,GAAK,mBACjEA,EAAmBA,EAA2B,OAAI,GAAK,SACvDA,EAAmBA,EAAmC,eAAI,GAAK,iBAC/DA,EAAmBA,EAA0B,MAAI,GAAK,QACtDA,EAAmBA,EAA8B,UAAI,GAAK,YAC1DA,EAAmBA,EAAqC,iBAAI,GAAK,mBACjEA,EAAmBA,EAAmC,eAAI,GAAK,iBAC/DA,EAAmBA,EAAmC,eAAI,GAAK,iBAC/DA,EAAmBA,EAAyB,KAAI,IAAM,OACtDA,EAAmBA,EAAwB,IAAI,IAAM,MACrDA,EAAmBA,EAAyB,KAAI,IAAM,OACtDA,EAAmBA,EAAqC,iBAAI,IAAM,mBAClEA,EAAmBA,EAA8B,UAAI,IAAM,YAC3DA,EAAmBA,EAAsC,kBAAI,IAAM,oBACnEA,EAAmBA,EAAkC,cAAI,IAAM,gBACxDA,GAlBgC,CAmBtCD,GAAqB,CAAA,GACpBE,EAAqC,CAACC,IACxCA,EAAmBA,EAA4B,QAAI,GAAK,UACxDA,EAAmBA,EAA8B,UAAI,GAAK,YAC1DA,EAAmBA,EAA0B,MAAI,GAAK,QACtDA,EAAmBA,EAAgC,YAAI,GAAK,cAC5DA,EAAmBA,EAA6B,SAAI,GAAK,WACzDA,EAAmBA,EAA0B,MAAI,GAAK,QACtDA,EAAmBA,EAAyB,KAAI,GAAK,OACrDA,EAAmBA,EAA+B,WAAI,GAAK,aAC3DA,EAAmBA,EAAuC,mBAAI,GAAK,qBACnEA,EAAmBA,EAA6B,SAAI,GAAK,WACzDA,EAAmBA,EAAgC,YAAI,IAAM,cACtDA,GAZgC,CAatCD,GAAqB,CAAA,GACpBE,EAAgC,CAACC,IACnCA,EAAcA,EAAqB,MAAI,GAAK,QAC5CA,EAAcA,EAAmB,IAAI,GAAK,MAC1CA,EAAcA,EAAqB,MAAI,GAAK,QACrCA,GAJ2B,CAKjCD,GAAgB,CAAA,GACfE,EAAiC,CAACC,IACpCA,EAAeA,EAAe,MAAQ,GAAK,KAC3CA,EAAeA,EAAsB,MAAI,GAAK,QAC9CA,EAAeA,EAAuB,OAAI,GAAK,SACxCA,GAJ4B,CAKlCD,GAAiB,CAAA,GAChBE,EAAqC,CAACC,IACxCA,EAAmBA,EAAyB,KAAI,GAAK,OACrDA,EAAmBA,EAA0B,MAAI,GAAK,QACtDA,EAAmBA,EAA2B,OAAI,GAAK,SACvDA,EAAmBA,EAAiC,aAAI,GAAK,eAC7DA,EAAmBA,EAA+B,WAAI,GAAK,aACpDA,GANgC,CAOtCD,GAAqB,CAAA,GAqBpBE,EAA4B,CAACC,IAC/BA,EAAUA,EAAoB,SAAI,GAAK,WACvCA,EAAUA,EAAwB,aAAI,GAAK,eAC3CA,EAAUA,EAAmB,QAAI,GAAK,UACtCA,EAAUA,EAAgB,KAAI,GAAK,OACnCA,EAAUA,EAAiB,MAAI,GAAK,QACpCA,EAAUA,EAAmB,QAAI,GAAK,UAC/BA,GAPuB,CAQ7BD,GAAY,CAAA,63FA7Ff,IAAAE,owBAAA,IAAAA,mwFAAA,IAAAA,o8GAAA,IAAAA,EAAAC,EAAAC,+4HAAA,IAAAF,8oRAAA,IAAAA,EAAAC,EAAAC,EAAAC,01EAAA,IAAAH,ulYAAAA,EAAAC,EAAAC,yeAAA,IAAAE,qDAAA,IAAAA,qhRAAA,IAAAJ,sZAAA,IAAAA,k+IAAAA,syBAAA,IAAAA,+qBAAA,IAAAI,mzBAAA,IAAAJ,iygBAAA,IAAAA,EAAAC,skMAAA,IAAAD,80IAAA,IAAAA,2xDAUiC,q5NC+HjC,SAAeK,EAAQC,EAAMC,GAC3B,IACE,KAAMD,KAAQD,GACZ,MAAO,OAGT,IAAMG,EAAWH,EAAOC,GAClBG,2eAAUF,CAAYC,GAW5B,MAVuB,mBAAZC,IACTA,EAAQC,UAAYD,EAAQC,WAAa,CAAA,EACzCC,OAAOC,iBAAiBH,EAAS,CAC/BI,mBAAoB,CAClBC,YAAY,EACZC,MAAOP,MAIbH,EAAOC,GAAQG,EACR,KACLJ,EAAOC,GAAQE,CAAA,CAEnB,CAAA,MAAAQ,GACE,MAAO,MAET,CACF,0ECrFIC,GAA2C,SAASC,GAGpD,OAFAA,EAAgC,UAAI,aACpCA,EAAgC,UAAI,aAC7BA,CACX,CAJ+C,CAI7C,ICjFF,SAASC,GAASC,EAAKC,GACnB,WAAcD,EAAIE,QAAQD,EAC9B,CACA,IAAME,GAAO,SAASH,GAClB,OAAOA,EAAIG,MACf,ECFMC,GAAWb,OAAOD,UAClBe,GAA4BD,GAASE,eACrCC,GAAsBH,GAASI,SAC/BC,GAJgBC,MAAMD,SAIK,SAASE,GACtC,MAAO,mBAAqBJ,GAAoBK,KAAKD,EACzD,EACME,GAAcC,GAAI,mBAAqBA,EAEvCC,GAAYD,GAAIA,IAAMvB,OAAOuB,KAAOL,GAAQK,GAQ5CE,GAAeF,QAAI,IAAWA,EAC9BG,GAAYH,GAAI,mBAAqBP,GAAoBK,KAAKE,GAE9DI,GAAUJ,GAAI,OAASA,EACvBK,GAAaL,GAAIE,GAAYF,IAAMI,GAAOJ,GAC1CM,GAAYN,GAAI,mBAAqBP,GAAoBK,KAAKE,IAAMA,GAAMA,EAE1EO,GAAaP,GAAI,qBAAuBP,GAAoBK,KAAKE,GACjEQ,GAAcR,GAAIA,aAAaS,SAKrC,SAASC,GAAY7B,GACjB,OAAO,OAASA,GAAS,iBAAmBA,CAChD,CACA,SAAS8B,GAAUC,EAAWC,GAC1B,MAAOpC,CAAOD,EAAUkB,SAASI,KAAKc,KAAU,WAAgBC,EAAS,GAC7E,CAgBA,SAASC,GAAQF,GACb,MAAO,oBAAsBG,OAKjC,SAAsBH,EAAWI,GAC7B,IACI,OAAOJ,aAAqBI,CAChC,CAAE,MAAAlC,GACE,OAAO,CACX,CACJ,CAX0CmC,CAAaL,EAAWG,MAClE,CCpDA,IAAMG,GAAS,SAETC,GAAU,UACVC,GAAS,SACTC,GAAiBF,GAAU,IAAMC,GACjCE,GAAO,OAEPC,GAAcC,cAEdC,GAAa,aAebC,GAAW,WACXC,GAAc,cACdC,GAAO,OAIPC,GAAgBC,gBAChBC,GAAQ,QACRC,GAAO,OACPC,GAAU,UACVC,GAAiBD,GAAU,IAAMf,GAAOiB,cACxCC,GAAiBH,GAAU,IAAMb,GAAOe,cAiBxCE,GAAa,IAAIC,OAAOV,GAAM,KAC9BW,GAAoB,IAAID,OAAOX,GAAc,QAAS,KACtDa,GAAiB,IAAIF,OAAOZ,GAAW,QAAS,KAChDe,GAAmB,IAAIH,OAAOb,GAAa,iBAAkB,KChCnE,SAASiB,GAAaC,GAClB,OAAKA,EACEA,EAAIC,MAAM,KAAK,GADLD,CAErB,CA2BA,ICxDIE,GACAC,GACAC,GCaJ,SAASC,GAAmBC,EAAOC,GAC/B,GAAKD,EAAL,CACA,IAAME,EAAOF,EAAMG,MAAMC,GAAIA,EAAEH,OAASA,IACxC,OAAW,MAAJC,OAAI,EAAJA,EAAMtE,KAFD,CAGhB,CDhBA,SAASyE,GAAwBC,GAC7B,IAAMC,EAAaC,WAAWC,iBAC9B,GAAKF,EAAL,CACA,IAAMG,EAAclF,OAAOmF,KAAKJ,GAChC,OAAIT,IAA0BY,EAAYE,SAAWf,KACrDA,GAAgBa,EAAYE,OAC5Bd,GAAyBY,EAAYG,QAAO,CAACC,EAAKC,KACzCnB,KAAoBA,GAAqB,CAAA,GAC9C,IAAMoB,EAASpB,GAAmBmB,GAClC,GAAIC,EAAQF,EAAIE,EAAO,IAAMA,EAAO,QAGhC,IADA,IAAMC,EAAcX,EAAYS,GACxBG,EAAID,EAAYL,OAAS,EAAGM,GAAK,EAAGA,IAAI,CAC5C,IAAMC,EAAaF,EAAYC,GACzBE,EAAqB,MAAVD,OAAU,EAAVA,EAAYC,SACvBC,EAAUd,EAAWQ,GAC3B,GAAIK,GAAYC,EAAS,CACrBP,EAAIM,GAAYC,EAChBzB,GAAmBmB,GAAY,CAC3BK,EACAC,GAEJ,KACJ,CACJ,CAEJ,OAAOP,CAAG,GACX,CAAA,IAvBwEhB,EAF1D,CA2BrB,CE/BA,IAAMwB,GAAmB,IACzB,SAASC,GAAYC,EAAUJ,EAAUK,EAAMC,EAAQC,GACnD,IAAMC,EAAQ,CACVJ,WACAJ,WACAS,SAAU,gBAAkBJ,EAAOH,GAAmBG,EACtDK,QAAQ,GAIZ,OAFK7E,GAAYyE,KAASE,EAAMF,OAASA,GACpCzE,GAAY0E,KAAQC,EAAMD,MAAQA,GAChCC,CACX,CCXA,IAAMG,GAAgCA,CAACN,EAAML,KACzC,IAAMY,GAAoB,IAAOP,EAAKtF,QAAQ,oBACxC8F,GAAuB,IAAOR,EAAKtF,QAAQ,wBACjD,OAAO6F,GAAqBC,EAAuB,MACxCR,EAAKtF,QAAQ,KAAOsF,EAAK9B,MAAM,KAAK,GAAK2B,GAChDU,EAAiB,oBAAuBZ,EAAQ,wBAA6BA,GAC7E,CACAK,EACAL,EACH,ECRCc,GAAsB,yCACtBC,GAAc,6IACdC,GAAkB,gCAClBC,GAAwBA,CAACC,EAAMd,KACjC,IAAMe,EAAYL,GAAoBM,KAAKF,GAC3C,GAAIC,EAAW,CACX,KAASnB,EAAUkB,EAAMG,GAAOF,EAChC,OAAOhB,GAAYC,EAAUJ,EAAUE,IAAmBgB,GAAOG,EACrE,CACA,IAAMC,EAAQP,GAAYK,KAAKF,GAC/B,GAAII,EAAO,CAEP,GADeA,EAAM,IAAM,IAAMA,EAAM,GAAGvG,QAAQ,QACtC,CACR,IAAMwG,EAAWP,GAAgBI,KAAKE,EAAM,IACxCC,IACAD,EAAM,GAAKC,EAAS,GACpBD,EAAM,GAAKC,EAAS,GACpBD,EAAM,GAAKC,EAAS,GAE5B,CACA,IAAOlB,EAAML,GAAYW,GAA8BW,EAAM,IAAMpB,GAAkBoB,EAAM,IAC3F,OAAOnB,GAAYC,EAAUJ,EAAUK,EAAMiB,EAAM,IAAMA,EAAM,QAAK,EAAQA,EAAM,IAAMA,EAAM,QAAK,EACvG,GCtBEE,GAAa,uIACbC,GAAiB,gDACjBC,GAAuBA,CAACR,EAAMd,KAChC,IAAMkB,EAAQE,GAAWJ,KAAKF,GAC9B,GAAII,EAAO,CAEP,GADeA,EAAM,IAAMA,EAAM,GAAGvG,QAAQ,YAAa,EAC7C,CACR,IAAMwG,EAAWE,GAAeL,KAAKE,EAAM,IACvCC,IACAD,EAAM,GAAKA,EAAM,IAAM,OACvBA,EAAM,GAAKC,EAAS,GACpBD,EAAM,GAAKC,EAAS,GACpBD,EAAM,GAAK,GAEnB,CACA,IAAItB,EAAWsB,EAAM,GACjBjB,EAAOiB,EAAM,IAAMpB,GAEvB,OADCG,EAAML,GAAYW,GAA8BN,EAAML,GAChDG,GAAYC,EAAUJ,EAAUK,EAAMiB,EAAM,IAAMA,EAAM,QAAK,EAAQA,EAAM,IAAMA,EAAM,QAAK,EACvG,GCfEK,GAAuB,kBCN7B,IAAMC,GAAsB,2GCA5B,IAAMC,GAAiB,CACnB,QACA,QACA,UACA,MACA,OACA,SCFJ,SAASC,GAA+BC,EAAKC,QAAS,IAATA,IAAAA,EAAY,IACrD,IAAMzC,EAAOnF,OAAOmF,KAAKwC,GAEzB,GADAxC,EAAK0C,QACA1C,EAAKC,OAAQ,MAAO,uBACzB,IAAI,IAAIM,EAAIP,EAAKC,OAAQM,EAAI,EAAGA,IAAI,CAChC,IAAMoC,EAAa3C,EAAK4C,MAAM,EAAGrC,GAAGsC,KAAK,MACzC,GAA0BJ,GAApBE,EAAW1C,OACb,OAAIM,IAAMP,EAAKC,OAAe0C,EACvBA,EAAW1C,OAAUwC,EAA4BE,EAAWC,MAAM,EAAGH,GAAU,MAA9CE,CAEhD,CACA,MAAO,EACX,CCuBA,IAAMG,GAAkE,oBAAXC,OAAyBA,YAASC,EAoPzFC,GAA8D,oBAAfpD,WAA6BA,WAAaiD,GAG3E,oBAATI,OACLD,GAAeC,KAAOD,IAER,oBAATE,OACLF,GAAeE,KAAO,WAAa,GAGlC,IAAMC,GAAkB,MAANH,QAAM,EAANA,GAAQG,UACpBC,GAAiB,MAANJ,QAAM,EAANA,GAAQI,eAI5BJ,IAAAA,GAAQK,gBAAuC,IAAIL,GAAOK,eAGvD,IAAMC,GAAqB,MAATH,QAAS,EAATA,GAAWG,UACvBC,GAAqCV,SAAAA,GAAQ,CAAA,ECvS7CW,GAAcrH,GAEhBA,aAAasH,SCMlBC,GAAgB,SAACC,EAAcC,GAAkE,IAAhEC,aAAEA,QAAmC,IAAAD,EAAG,CAAA,EAAEA,EACvEE,EAA0B,CAC5BC,CAeA,CAfOC,GACH,GACIlB,KACiBS,GAAiBU,eAAiBJ,KAClDxH,GAAYyG,GAAOoB,UACpBpB,GAAOoB,QACT,CAME,IALA,IAAMC,GACF,uBAAwBrB,GAAOoB,QAAQF,GAChClB,GAAOoB,QAAQF,GAAmC,mBACnDlB,GAAOoB,QAAQF,IAEzBI,EAAAC,UAAArE,OAZ6CsE,MAAIvI,MAAAqI,EAAA,EAAAA,OAAAG,EAAA,EAAAH,EAAAG,EAAAA,IAAJD,EAAIC,EAAA,GAAAF,UAAAE,GAajDJ,EAAWR,KAAWW,EAC1B,CACJ,EAEAE,KAEA,GAF2B,IAAA,IAAAC,EAAAJ,UAAArE,OAAhBsE,EAAI,IAAAvI,MAAA0I,GAAAC,EAAA,EAAAD,EAAAC,EAAAA,IAAJJ,EAAII,GAAAL,UAAAK,GACXZ,EAAOC,EAAK,WAAYO,EAC5B,EAEAK,IAEA,GAF0B,IAAA,IAAAC,EAAAP,UAAArE,OAAhBsE,EAAI,IAAAvI,MAAA6I,GAAAC,EAAA,EAAAD,EAAAC,EAAAA,IAAJP,EAAIO,GAAAR,UAAAQ,GACVf,EAAOC,EAAK,SAAUO,EAC1B,EAEAQ,IAEA,GAF0B,IAAA,IAAAC,EAAAV,UAAArE,OAAhBsE,EAAI,IAAAvI,MAAAgJ,GAAAC,EAAA,EAAAD,EAAAC,EAAAA,IAAJV,EAAIU,GAAAX,UAAAW,GACVlB,EAAOC,EAAK,UAAWO,EAC3B,EAEAW,KAEA,GAF2B,IAAA,IAAAC,EAAAb,UAAArE,OAAhBsE,EAAI,IAAAvI,MAAAmJ,GAAAC,EAAA,EAAAD,EAAAC,EAAAA,IAAJb,EAAIa,GAAAd,UAAAc,GACXrB,EAAOC,EAAK,WAAYO,EAC5B,EAEAc,QAIA,GAJ8B,IAAA,IAAAC,EAAAhB,UAAArE,OAAhBsE,EAAI,IAAAvI,MAAAsJ,GAAAC,EAAA,EAAAD,EAAAC,EAAAA,IAAJhB,EAAIgB,GAAAjB,UAAAiB,GAGdpB,QAAQe,MAAMtB,KAAWW,EAC7B,EAEAiB,oBAEA,CAFuBC,GACnB1B,EAAOmB,MAAK,8CAA+CO,EAAa,EAG5EC,aAAcA,CAACC,EAA0BC,IACrCjC,GAAiBC,EAAM,IAAI+B,EAAoBC,IAEvD,OAAO7B,CACX,EAEaA,GAASJ,GAAc,gBAEvB+B,GAAe3B,GAAO2B,aCjD5B,SAASG,GAAK5J,EAAU6J,GAC3B,IAAIrJ,GAAUR,GAGd,GAAIF,GAAQE,GACRA,EAAI8J,QAAQD,QAGhB,GAAIlJ,GAAWX,GACXA,EAAI8J,SAAQ,CAACC,EAAUC,IAAaH,EAASE,EAAKC,UAGtD,IAAK,IAAMA,KAAOhK,EACVL,GAAeM,KAAKD,EAAKgK,IACzBH,EAAS7J,EAAIgK,GAAMA,EAG/B,CAEO,IAAMC,GAAS,SAAUjK,GAA+E,IAAA,IAAAoI,EAAAC,UAAArE,OAAlDsE,MAAIvI,MAAAqI,EAAA,EAAAA,OAAAG,EAAA,EAAAH,EAAAG,EAAAA,IAAJD,EAAIC,EAAA,GAAAF,UAAAE,GAC7D,IAAK,IAAMjK,KAAUgK,EACjB,IAAK,IAAM4B,KAAQ5L,OACM,IAAjBA,EAAO4L,KACPlK,EAAIkK,GAAQ5L,EAAO4L,IAI/B,OAAOlK,CACX,EAMO,SAASmK,GAAiBnK,GAK7B,IAJA,IAAMoK,EAAWxL,OAAOmF,KAAK/D,GACzBsE,EAAI8F,EAASpG,OACXqG,EAAW,IAAItK,MAAMuE,GAEpBA,KACH+F,EAAS/F,GAAK,CAAC8F,EAAS9F,GAAItE,EAAIoK,EAAS9F,KAE7C,OAAO+F,CACX,CAyHO,SAASC,GACZC,EACAC,EACAC,EACAd,GAEA,IAAMe,QAAEA,GAAU,EAAKC,QAAEA,GAAU,GAAShB,QAAAA,EAAW,CAAA,EAKhD,MAAPY,GAAAA,EAASD,iBAAiBE,EAAOC,EAAU,CAAEC,UAASC,WAC1D,CCrLO,IAUMC,GAAkB,SAAUC,EAA0CC,GAC/E,IAAIC,EACAC,OAFwF,IAAbF,IAAAA,EAAgB,KAG/F,IAAMG,EAAoB,GAa1B,OAXArB,GAAKiB,GAAU,SAAUd,EAAgCC,GAEjD3J,GAAY0J,IAAQ1J,GAAY2J,IAAgB,cAARA,IAI5Ce,EAAUG,mBAA0BnB,ajBPX7C,KiBOkB6C,EAAIxL,KAAOwL,EAAIlK,YAC1DmL,EAAUE,mBAAmBlB,GAC7BiB,EAAQA,EAAQjH,QAAUgH,EAAU,IAAMD,EAC9C,IAEOE,EAAQrE,KAAKkE,EACxB,ECjCO,SAASK,GACZ7M,EACAC,EACAC,GAEA,IACI,KAAMD,KAAQD,GACV,MAAO,OAKX,IAAMG,EAAWH,EAAOC,GAClBG,EAAUF,EAAYC,GAiB5B,OAbIyB,GAAWxB,KAEXA,EAAQC,UAAYD,EAAQC,WAAa,CAAA,EACzCC,OAAOC,iBAAiBH,EAAS,CAC7B0M,oBAAqB,CACjBrM,YAAY,EACZC,OAAO,MAKnBV,EAAOC,GAAQG,EAER,KACCJ,EAAOC,KAAUG,IACjBJ,EAAOC,GAAQE,EACnB,CAER,CAAE,MAAAQ,GACE,MAAO,MAKX,CACJ,CClCO,SAASoM,GAAiBvI,EAA6B6G,GAA+B,IAAA2B,EACnFC,EAfV,SAAyBzI,GACrB,IACI,MAAmB,iBAARA,EACA,IAAI0I,IAAI1I,GAAKyI,SAEpB,QAASzI,EACF,IAAI0I,IAAI1I,EAAIA,KAAKyI,SAErBzI,EAAIyI,QACf,CAAE,MAAAtM,GACE,OAAO,IACX,CACJ,CAGqBwM,CAAgB3I,GAC3B4I,EAAmB,CAAEH,WAAUI,cAAc,GAEnD,GAAgC,OAA5BL,EAAC3B,EAAQiC,uBAARN,EAA6BtH,cAAWuH,IAAAA,EAAU/L,OAAOwE,OAC1D,OAAO0H,EAGX,IAAK,IAAMG,KAAQlC,EAAQiC,oBACvB,GAAIL,EAASO,SAASD,GAClB,MAAO,CAAEN,WAAUI,cAAc,GAIzC,OAAOD,CACX,CCgCO,IC1DDK,GAAoB,EACpBC,GAAiB,EACjBC,GAA8B,GAe7B,SAASC,GAAcC,GAC1B,QAASA,GAAMA,EAAGC,WAAaL,EACnC,CAYO,SAASM,GAAMF,EAAgCG,GAClD,QAASH,KAAQA,EAAGI,SAAWJ,EAAGI,QAAQjK,gBAAkBgK,EAAIhK,aACpE,CAkBO,SAASkK,GAAaL,GACzB,QAASA,GAAMA,EAAGC,WAAaH,IAA+BC,GAAeC,EAAkBM,KACnG,CC/CO,SAASC,GAAiBC,GAC7B,OAAOA,EAAInN,GAAKmN,GAAG5J,MAAM,OAAS,EACtC,CAaO,SAAS6J,GAAcT,GAC1B,IAAInL,EAAY,GAChB,cAAemL,EAAGnL,WACd,IAAK,SACDA,EAAYmL,EAAGnL,UACf,MAEJ,IAAK,SACDA,GACKmL,EAAGnL,WAAa,YAAamL,EAAGnL,UAAamL,EAAGnL,UAAkB6L,QAAU,OAC7EV,EAAGW,aAAa,UAChB,GACJ,MACJ,QACI9L,EAAY,GAGpB,OAAO0L,GAAiB1L,EAC5B,CA8BO,SAAS+L,GAAYZ,GACxB,IAAIa,EAAS,GAUb,OARIC,GAAqBd,KAAQe,GAAmBf,IAAOA,EAAGgB,YAAchB,EAAGgB,WAAWnJ,QACtF4F,GAAKuC,EAAGgB,YAAY,SAAUC,GACkB,IAAAC,GDlCjD,SAAoBlB,GACvB,QAASA,GAAMA,EAAGC,WAAaJ,EACnC,ECgCgBsB,CAAWF,IAAUA,EAAMG,cAC3BP,GAAyC,QAAnCK,EAlCf,SAAsBV,GACzB,OAAInM,GAAUmM,GACH,KAIPnN,GAAKmN,GAEA5J,MAAM,SACNyK,QAAQb,GAAMc,GAAmBd,KACjC/F,KAAK,IAEL8G,QAAQ,UAAW,KACnBA,QAAQ,QAAS,KAEjBC,UAAU,EAAG,IAE1B,CAiB0BC,CAAaR,EAAMG,oBAAY,IAAAF,EAAAA,EAAI,GAErD,IAGG7N,GAAKwN,EAChB,CAcO,IAAMa,GAAgC,CAAC,IAAK,SAAU,OAAQ,QAAS,SAAU,WAAY,SAgE7F,SAASC,GAAiBC,GAC7B,IAAMC,EAAaD,EAAMC,WACzB,SAAKA,IAAe9B,GAAc8B,KAC3BA,CACX,CAiDA,IAAMC,GAAiC,CAAC,mBAAoB,kBAsF5D,IAAMC,GAA6B/B,IACvBA,GAAME,GAAMF,EAAI,UAAYD,GAAcC,GAGhDgC,GAAiCA,CAAChC,EAAaiC,KACjD,IAAKtH,IAAUoH,GAA0B/B,GACrC,MAAO,CAAEkC,uBAAuB,EAAOC,kBAAmB,IAM9D,IAHA,IAAID,GAAwB,EACtBC,EAA+B,CAACnC,GAClC4B,EAAiB5B,EACd4B,EAAMC,aAAe3B,GAAM0B,EAAO,SACrC,GAAIvB,GAAauB,EAAMC,YACnBM,EAAkBC,KAAKR,EAAMC,WAAWvB,MACxCsB,EAAQA,EAAMC,WAAWvB,SAF7B,CAKA,IAAMuB,EAAaF,GAAiBC,GACpC,IAAKC,EAAY,MACjB,GAA2BH,GAA8BtO,QAAQyO,EAAWzB,QAAQjK,kBAChF+L,GAAwB,MACrB,CACH,IAAMG,EAAa1H,GAAO2H,iBAAiBT,GACvCQ,GAAwD,YAA1CA,EAAWE,iBAAiB,YAC1CL,GAAwB,EAEhC,CAEAC,EAAkBC,KAAKP,GACvBD,EAAQC,CAbR,CAeJ,MAAO,CAAEK,wBAAuBC,oBAAmB,EA0GhD,SAASrB,GAAqBd,GACjC,IAAK,IAAI4B,EAAQ5B,EAAI4B,EAAMC,aAAe3B,GAAM0B,EAAO,QAASA,EAAQA,EAAMC,WAAuB,CACjG,IAAMW,EAAU/B,GAAcmB,GAC9B,GAAI3O,GAASuP,EAAS,iBAAmBvP,GAASuP,EAAS,iBACvD,OAAO,CAEf,CAEA,GAAIvP,GAASwN,GAAcT,GAAK,cAC5B,OAAO,EAIX,IAAM9I,EAAQ8I,EAAwB9I,MAAQ,GAC9C,GAAI/C,GAAS+C,GAET,OAAQA,EAAKf,eACT,IAAK,SAEL,IAAK,WACD,OAAO,EAKnB,IAAM/D,EAAQ4N,EAAwB5N,MAAQ4N,EAAGyC,IAAM,GAIvD,OAAItO,GAAS/B,KAGL,uHACmBsQ,KAAKtQ,EAAKmP,QAAQ,gBAAiB,IAMlE,CAOO,SAASR,GAAmBf,GAI/B,SACKE,GAAMF,EAAI,WAFW,CAAC,SAAU,WAAY,SAAU,SAEb/M,SAAU+M,EAAwB9I,OAC5EgJ,GAAMF,EAAI,WACVE,GAAMF,EAAI,aAC6B,SAAvCA,EAAGW,aAAa,mBAKxB,CAGA,IAAMgC,GAAa,kKAEbC,GAAkB,IAAItM,OAAM,OAAQqM,SAEpCE,GAAoB,IAAIvM,OAAOqM,IAG/BG,GAAc,yBAEdC,GAAmB,IAAIzM,OAAM,KAAMwM,SAEnCE,GAAqB,IAAI1M,OAAM,IAAKwM,QASnC,SAASxB,GAAmBzO,EAAeoQ,GAC9C,QAD2D,IAAbA,IAAAA,GAAgB,GAC1D5O,GAAUxB,GACV,OAAO,EAGX,GAAIsB,GAAStB,GAAQ,CAMjB,GALAA,EAAQQ,GAAKR,IAIGoQ,EAAgBL,GAAkBC,IACtCH,MAAM7P,GAAS,IAAI0O,QAAQ,QAAS,KAC5C,OAAO,EAKX,IADiB0B,EAAgBF,GAAmBC,IACvCN,KAAK7P,GACd,OAAO,CAEf,CAEA,OAAO,CACX,CAuBO,SAASqQ,GAA2BC,GACvC,IAAIC,EAAOxC,GAAYuC,GAEvB,OAAO7B,GADP8B,GAAUA,EAAI,IAAIC,GAAkBF,IAAU9P,QACZ+P,EAAO,EAC7C,CAQO,SAASC,GAAkBF,GAC9B,IAAIC,EAAO,GAiBX,OAhBID,GAAUA,EAAOnC,YAAcmC,EAAOnC,WAAWnJ,QACjD4F,GAAK0F,EAAOnC,YAAY,SAAUC,GAAO,IAAAqC,EACrC,GAAIrC,GAA0C,UAApB,OAAbqC,EAAArC,EAAMb,cAAO,EAAbkD,EAAenN,eACxB,IACI,IAAMoN,EAAW3C,GAAYK,GAC7BmC,GAAUA,EAAI,IAAIG,GAAWlQ,OAEzB4N,EAAMD,YAAcC,EAAMD,WAAWnJ,SACrCuL,GAAUA,EAAI,IAAIC,GAAkBpC,IAAS5N,OAErD,CAAE,MAAOmQ,GACL7H,GAAOmB,MAAM,gBAAiB0G,EAClC,CAER,IAEGJ,CACX,CA4BA,SAASK,GAAaC,GAClB,OAAOA,EAAMnC,QAAQ,SAAU,MACnC,CAyDA,SAASoC,GAAiB3D,GACtB,IAAM4D,EAAa5D,EAAgB,YACnC,OAAK4D,EAEMjQ,GAAQiQ,GACRA,EAEArD,GAAiBqD,QAJxB,CAMR,CC5qBO,IAAMC,GAAyB,IAOzBC,GAAwD,CACjEC,eAAgB,CACZ,QACA,SACA,OACA,MACA,aACA,QACA,QACA,QACA,SACA,OACA,QACA,MACA,QACA,OACA,aACA,SACA,OACA,SACA,QACA,QACA,kBAEJC,cAAgBC,GAAiCA,EACjDC,eAAe,EACfC,YAAY,EACZC,uBAAuB,EACvBC,mBAAmB,EACnBC,8BAA+B,CAE3B,cAGA,aACA,QACA,YAEJC,sBAAuBV,GACvBpE,oBAAqB,CACjB,gBACA,oBACA,cAIA,uBACA,uBAEA,cAEA,gBACA,eACA,eAEA,aACA,kBACA,gBACA,eAEA,aACA,YACA,iBAEJ+E,mBAAmB,GChDjB7I,GAAS2B,GAAa,cAStBmH,GAAsBC,GACJ,eAApBA,EAAMC,UACJC,GAAoBF,GAAoF,aAApBA,EAAMC,UA0EhG,SAASE,GAAoB3N,EAA8BgN,GACvD,QAASA,IAAkB3P,GAAU2P,IAAkBA,EAAchN,GACzE,CAEA,SAAS4N,GAAUjS,GACf,GAAuB,oBAAZkS,QACP,OAAO,EAEX,GAAIlS,aAAiBkS,QACjB,OAAO,EAEX,IACI,MAAiD,qBAA1CtS,CAAOD,EAAUkB,SAASI,KAAKjB,EAC1C,CAAE,MAAAC,GACE,OAAO,CACX,CACJ,CAIO,IAAMkS,GAAkC,CAC3C,SACA,SACA,SACA,QACA,2BACA,kBACA,kBACA,oBAGG,SAASC,GAAgBC,GAU7B,IAV8BhO,KAC7BA,EAAIiN,WACJA,EAAUgB,QACVA,EAAOxO,IACPA,GAMHuO,EACG,SAASE,EAAmBC,GACxB,IAAMC,EAAoB7S,OAAOmF,KAAKuN,GAAS/N,MAAMyG,GAA8B,iBAAtBA,EAAI1H,gBAC3DoP,EAAcD,GAAqBH,EAAQG,GACjD,OAAOD,EAAaG,MAAMC,GAAkB,MAAXF,OAAW,EAAXA,EAAapP,cAAclD,SAASwS,IACzE,CAwBA,IAAKtB,EAAY,OAAO,EACxB,GAjBA,SAASuB,EAAU/O,GACf,IACI,MAAmB,iBAARA,EACAA,EAAIgP,WAAW,SAEtBhP,aAAe0I,IACS,UAAjB1I,EAAIiP,WAEXd,GAAUnO,IACH+O,EAAU/O,EAAIA,IAG7B,CAAE,MAAAkP,GACE,OAAO,CACX,CACJ,CAEIH,CAAU/O,GAAM,OAAO,EAE3B,GAAIyO,EAAmBJ,IAAkC,OAAO,EAChE,GAAIzQ,GAAU4P,GAAa,OAAO,EAClC,GAAIxQ,GAAQwQ,GAAa,OAAOiB,EAAmBjB,GACnD,IAAM2B,EAAiB3B,EAAWjN,GAClC,OAAI3C,GAAUuR,GAAwBA,EAC/BV,EAAmBU,EAC9B,CAAC,SAEcC,GAA0BC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,GAAA,OAAAC,GAAAC,MAAAC,KAAAtK,UAAA,CA4BzC,SAAAoK,KAFC,OAEDA,GAAAG,GA5BA,UACI/L,EACAgM,EACA/P,EACAgQ,EACAC,EACAC,GAEA,QAFO,IAAPA,IAAAA,EAAU,GAENA,EAAU,GAEV,OADAlL,GAAOgB,KAAK,8CAA+C,CAAEhG,MAAK+P,kBAC3D,KAEX,IACMI,EAlKH,SAAqBC,EAAiBC,GAEzC,IADA,IACS7O,EADM4O,EAAMlP,OACC,EAAGM,GAAK,EAAGA,GAAK,EAClC,GAkKIyM,GADHF,EAjKaqC,EAAM5O,KAmKhBuM,EAAMgC,gBAAkBA,IACvBxS,GAAYyS,IAAUjC,EAAMuC,WAAaN,KACzCzS,GAAY0S,IAA2BA,GAAnBlC,EAAMuC,WApK3B,OAAOF,EAAM5O,GAgKhBuM,KA5JT,CA0J6BwC,CADKxM,EAAIyM,YAAYC,iBAAiBzQ,IAS/D,OAAKmQ,UACK,IAAIO,SAASC,GAAYC,WAAWD,EAAS,GAAKT,KACjDd,GAA2BrL,EAAKgM,EAAe/P,EAAKgQ,EAAOC,EAAKC,EAAU,GAGzF,IAACP,GAAAC,MAAAC,KAAAtK,UAAA,CASD,SAASsL,GAAeC,GAQN,IAROC,KACrBA,EAAIlK,QACJA,EAAO7G,IACPA,GAKH8Q,EACG,GAAIpT,GAAUqT,GACV,OAAO,KAGX,IAAMtI,SAAEA,EAAQI,aAAEA,GAAiBN,GAAiBvI,EAAK6G,GACzD,GAAIgC,EACA,OAAOJ,EAAW,mBAGtB,GAAIjL,GAASuT,GACT,OAAOA,EAGX,GAAIrM,GAAWqM,GACX,OAAOA,EAAKtG,YAGhB,GAAI5M,GAAWkT,GACX,OAAOjJ,GAAgBiJ,GAG3B,GAAIzT,GAASyT,GACT,IACI,OAAOC,KAAKC,UAAUF,EAC1B,CAAE,MAAAG,GACE,MAAO,qDACX,CAGJ,MAAO,4CAA8CnU,SAASI,KAAK4T,EACvE,CAoJA,IAAMI,GAAuBzJ,IACxBjK,GAAOiK,KAA+B,eAApBA,EAAMsG,WAAkD,aAApBtG,EAAMsG,WAEjE,SAASoD,GAAcC,GAsBM,IAtBLtD,MACpBA,EAAKuD,OACLA,EAAMC,OACNA,EAAMC,eACNA,EAAcC,UACdA,EAASzB,MACTA,EAAKC,IACLA,EAAGjQ,IACHA,EAAG+P,cACHA,GAaHsB,EACGrB,EAAQjC,EAAQA,EAAMuC,UAAYN,EAClCC,EAAMlC,EAAQA,EAAM2D,YAAczB,EAMlC,IAAM0B,EAAaC,KAAKC,MAAMC,KAAKC,MAAQvB,YAAYuB,OAIjDC,EAAYJ,KAAKC,MAAMF,GAAc3B,GAAS,IAI9CiC,EAAqC,CAAAC,KAFzBnE,EAAQA,EAAMoE,SAAW,CAAE1W,KAAMuE,GAI/B,CACZsQ,UAAW/S,GAAYyS,QAAS/L,EAAY2N,KAAKQ,MAAMpC,GACvDqC,QAAS9U,GAAY0S,QAAOhM,EAAY2N,KAAKQ,MAAMnC,GACnD0B,aACAK,YACAV,OAAQA,EACRvB,cAAeA,IAAgChC,EAASA,EAAMgC,mBAAkC9L,GAChGsN,SACAe,eAAgBd,EAAec,eAC/BC,YAAaf,EAAee,YAC5BC,gBAAiBhB,EAAegB,gBAChCC,aAAcjB,EAAeiB,aAC7BhB,eAIR,GAAIN,GAAoBpD,GACpB,IAAK,IAAM2E,KAAU3E,EAAM4E,cAAgB,GACvCV,EAASxG,KAAK,CACVkG,aACAK,YACA1B,UAAWsB,KAAKQ,MAAMrE,EAAMuC,WAC5B7U,KAAMiX,EAAOjX,KACbmX,SAAUF,EAAOE,SAMjB5E,UAAW,iBAKvB,OAAOiE,CACX,CAEA,IAAMY,GAA4B,CAAC,SAAU,UA+B7C,SAASC,GAAqB/B,GAC1B,OAAOzT,GAASyT,IAAS3T,GAAW2T,EAAKgC,YAAc3V,GAAW2T,EAAKiC,IAC3E,CAGA,IAAMC,GAAuB,IACvBC,GAA4B,oDAC5BC,GAA2B,sCAEjC,SAASC,GAAsBC,GAC3B,OAAUF,QAA6BE,CAC3C,CAEA,SAASC,GAAoBC,GACzB,MAAA,+CAAsDA,EAAU,SACpE,CAoBO,SAASC,GAAU9S,EAAuBmG,GAC7C,IAAKA,EAAQgH,kBACT,OAUR,SAAsBnN,GAGlB,OAAO,IAAIgQ,SAASC,IAChB,IAAM8C,EAAU7C,YAAW,IAAMD,EAAQuC,KAA4BD,IACrE,IACIvS,EAAEgT,QACGjH,OACAkH,MACIC,GAAQjD,EAAQiD,KAChBP,GAAW1C,EAAQyC,GAAsBC,MAE7CQ,SAAQ,IAAMC,aAAaL,IACpC,CAAE,MAAAM,GACED,aAAaL,GACb9C,EAAQwC,GACZ,IAER,CA5Bea,CAAatT,GAExB,IAAM6S,ED9iBH,SAAoC1M,GAAsE,IAAAoN,EAC7G,OAAOrC,KAAKsC,IAAIhH,GAAqD,QAA/B+G,EAAEpN,EAAQ+G,iCAAqBqG,EAAAA,EAAI/G,GAC7E,CC4iBuBiH,CAA2BtN,GAE9C,OAnBG,SAAoCnG,EAAuB6S,GAC9D,IAAI,IAAAa,EACMC,EAAuB,OAAZD,EAAG1T,EAAE8N,UAAY,MAAd4F,EAAWE,SAAG,EAAdF,EAAWE,IAAM,kBACrC,IAAKD,EACD,OAAO,EAEX,IAAME,EAAgBC,SAASH,EAAa,IAC5C,OAAOI,OAAOC,SAASH,IAAkBA,EAAgBhB,CAC7D,CAAE,MAAAoB,GACE,OAAO,CACX,CACJ,CAQQC,CAA2BlU,EAAG6S,GACvB7C,QAAQC,QAAQ2C,GAAoBC,IAsC5C,SAA+B7S,EAAuB6S,GAEzD,OAAO,IAAI7C,SAASC,IAChB,IACIkE,EADAC,GAAU,EAGd,SAASC,IACL,IAAI,IAAAC,EACW,OAAXA,EAAKH,IAAAG,EAAQD,QACjB,CAAE,MAAAE,GACE,CAER,CAIA,SAASC,EAAKhZ,GACN4Y,IAGJA,GAAU,EACVhB,aAAaL,GACbsB,IACApE,EAAQzU,GACZ,CAEA,IAEIwX,EAFED,EAAU7C,YAAW,IAAMsE,EAAKhC,KAA4BD,IAGlE,IACIS,EAAQhT,EAAEgT,OACd,CAAE,MAAAyB,GAEE,YADAD,EAAK/B,GAET,CAEA,IAAMpC,EAAO2C,EAAM3C,KAEnB,GAAK+B,GAAqB/B,IAAgC,oBAAhBqE,YAA1C,CAYA,IACIP,EAAS9D,EAAKgC,WAClB,CAAE,MAAAsC,GAEE,YADAH,EAAK/B,GAET,CAEA,IAAMmC,EAAuB,GACzBC,EAAW,GAEf,SAASC,IACLX,EAAQY,OAAO9B,MACX+B,IAAiC,IAA9BR,KAAMS,EAAUzZ,MAAEA,GAAOwZ,EAExB,GAAIZ,EACAC,SAIJ,GAAIY,EACAT,GAAK,IAAIE,aAAcQ,OAnF/C,SAAsBN,EAAsBO,GACxC,IAAMC,EAAS,IAAIC,WAAWF,GAC1BG,EAAS,EACb,IAAK,IAAMC,KAASX,EAChBQ,EAAOI,IAAID,EAAOD,GAClBA,GAAUC,EAAME,WAEpB,OAAOL,CACX,CA2EsDM,CAAad,EAAQC,SADvD,CAKA,GAAIrZ,EAAO,CACP,GAAIqZ,EAAWrZ,EAAMia,WAAa5C,EAE9B,YADA2B,EAAK5B,GAAoBC,IAG7BgC,GAAYrZ,EAAMia,WAClBb,EAAO7J,KAAKvP,EAChB,CAEAsZ,GAXA,CAWM,IAETnC,GAAW6B,EAAK9B,GAAsBC,KAE/C,CAEAmC,EAzCA,MATI,IACI9B,EAAMjH,OAAOkH,MACRC,GAAQsB,EAAKtB,KACbP,GAAW6B,EAAK9B,GAAsBC,KAE/C,CAAE,MAAAgD,GACEnB,EAAK/B,GACT,CA2CE,GAEd,CA/HWmD,CAAsB5V,EAAG6S,EACpC,CAgIkC,SAAAgD,KAejC,OAfiCA,GAAAzG,GAAlC,UAAA0G,GAQoB,IARe9V,EAC/BA,EAACmG,QACDA,EAAO7G,IACPA,GAKHwW,GACS/N,SAAEA,EAAQI,aAAEA,GAAiBN,GAAiBvI,EAAK6G,GACzD,OAAIgC,EACO6H,QAAQC,QAAQlI,EAAW,oBAG/B+K,GAAU9S,EAAGmG,EACxB,IAAC0P,GAAA3G,MAAAC,KAAAtK,UAAA,CAEkC,SAAAkR,KAelC,OAfkCA,GAAA3G,GAAnC,UAAA4G,GAQoB,IARgBhW,EAChCA,EAACmG,QACDA,EAAO7G,IACPA,GAKH0W,EACSC,EApOV,SAAwCC,GAQtB,IAAAC,GARuBnW,EACrCA,EAACmG,QACDA,EAAO7G,IACPA,GAKH4W,EACG,GAA2C,YAAvClW,EAAE8N,QAAQ8F,IAAI,qBACd,MAAO,6CAKX,IAAM1F,EAA2C,OAAhCiI,EAAGnW,EAAE8N,QAAQ8F,IAAI,sBAAe,EAA7BuC,EAA+BrX,cAC7CsX,EAAsBjE,GAA0BhE,MAAMhK,GAAsB,MAAX+J,OAAW,EAAXA,EAAaI,WAAWnK,KAC/F,GAAI+J,GAAekI,EACf,MAAA,gBAAuBlI,EAAW,oBAGtC,IAAMnG,SAAEA,EAAQI,aAAEA,GAAiBN,GAAiBvI,EAAK6G,GACzD,OAAIgC,EACOJ,EAAW,mBAGf,IACX,CAyMgDsO,CAAgC,CAAErW,IAAGmG,UAAS7G,QAC1F,OAAKvC,GAAOkZ,GAILnD,GAAU9S,EAAGmG,GAHT6J,QAAQC,QAAQgG,EAI/B,IAACF,GAAA7G,MAAAC,KAAAtK,UAAA,CAuGD,IAAIyR,GAA6C,KAEjD,SAASC,GACLtP,EACA5D,EACA8C,GAEA,KAAM,gBAAiB9C,GACnB,MAAO,OAKX,GAAIiT,GAEA,OADAhS,GAAOgB,KAAK,uDACL,OAKX,IAAMkR,EACFrQ,EAAU/K,OAAOqb,OAAO,CAAA,EAAIhK,GAAuBtG,GAAWsG,GAG5DiK,EAAuB9J,IACzB,IAAM2E,EAAqC,GAC3C3E,EAAK2E,SAASjL,SAASqQ,IACnB,IAAMC,EAAgBJ,EAAe7J,cAAcgK,GAC/CC,GACArF,EAASxG,KAAK6L,EAClB,IAGArF,EAAS/Q,OAAS,GAClByG,EAAQuK,EAAA,CAAA,EAAM5E,EAAI,CAAE2E,aACxB,EAEEsF,EAjzBV,SAAiCH,EAAqBrT,EAAc8C,GAOhE,GAAIA,EAAQ4G,sBAAuB,CAC/B,IAAM+J,EAA4BzT,EAAIyM,YACjCiH,aACA/M,QACIqD,GACGD,GAAmBC,IAClBE,GAAiBF,IAAUlH,EAAQuG,eAAe9Q,SAASyR,EAAMgC,iBAE9EqH,EAAG,CACCnF,SAAUuF,EAA0BE,SAAS3J,GACzCqD,GAAe,CAAErD,QAAOuD,YAAQrN,EAAWsN,YAAQtN,EAAWuN,eAAgB,CAAA,EAAIC,WAAW,MAEjGA,WAAW,GAEnB,CACA,IAAMkG,EAAW,IAAI5T,EAAI6T,qBAAqBvQ,IAI1C,IAKMwQ,EAAqBxQ,EAAQoQ,aAAa/M,QAC3CqD,GACGD,GAAmBC,IAClBE,GAAiBF,IACdlH,EAAQuG,eAAe9Q,SAASyR,EAAMgC,gBATlBhC,KAC5BlH,EAAQ2G,aAAc3G,EAAQ0G,eACA,mBAAxBQ,EAAMgC,eAA8D,UAAxBhC,EAAMgC,cAShD+H,CAAuB/J,KAGnCqJ,EAAG,CACCnF,SAAU4F,EAAmBH,SAAS3J,GAClCqD,GAAe,CAAErD,QAAOuD,YAAQrN,EAAWsN,YAAQtN,EAAWuN,eAAgB,CAAA,OAEpF,IAIAuG,EAAaH,oBAAoBI,oBAAoBtN,QAAQrN,GAC/DwJ,EAAQ8G,8BAA8BrR,SAASe,KAInD,OADAsa,EAASM,QAAQ,CAAEF,eACZ,KACHJ,EAASO,YAAY,CAE7B,CAyvBgCC,CAAwBf,EAAIrT,EAAKmT,GAGzDkB,EAA+BA,OAC/BC,EAAiCA,OAYrC,OAXInB,EAAe3J,eAAiB2J,EAAe1J,cAC/C4K,EAhmBR,SAAyBhB,EAAqBrT,EAAc8C,GACxD,IAAKA,EAAQuG,eAAe9Q,SAAS,kBACjC,MAAO,OAIX,IAAMgc,EAAuBpK,GAAoB,UAAWrH,EAAQ0G,eAC9DgL,EAAwBrK,GAAoB,WAAYrH,EAAQ0G,eAEhEiL,EAAenQ,GACjBtE,EAAIQ,eAAe1I,UACnB,QAGC4c,GACU,SACHnH,EACAtR,EACA0Y,EACAC,EACAC,QAFK,IAALF,IAAAA,GAAQ,GAOR,IAMI1I,EACAC,EAPE4I,EAAMhJ,KAINiJ,EAAM,IAAI1K,QAAQpO,GAClBwR,EAAkD,CAAA,EAIlDc,EAA0B,CAAA,EAC1ByG,EAA2BF,EAAIG,iBAAiBC,KAAKJ,GAC3DA,EAAIG,iBAAmB,CAACE,EAAgBhd,KACpCoW,EAAe4G,GAAUhd,EAClB6c,EAAyBG,EAAQhd,IAExCoc,IACA9G,EAAec,eAAiBA,GAGpC,IAAM6G,EAAeN,EAAIO,KAAKH,KAAKJ,GACnCA,EAAIO,KAAQrI,IAEJzC,GAAiB,CACb/N,KAAM,UACNiO,QAAS8D,EACTtS,MACAwN,WAAY3G,EAAQ2G,eAGxBgE,EAAee,YAAc1B,GAAgB,CAAEE,OAAMlK,UAAS7G,SAElEgQ,EAAQjM,EAAIyM,YAAYuB,MACjBoH,EAAapI,IAIxB,IAAMsI,EAAUA,KACZR,EAAIS,oBAAoB,mBAAoBC,GAC5CV,EAAIS,oBAAoB,QAASD,GACjCR,EAAIS,oBAAoB,QAASD,GACjCR,EAAIS,oBAAoB,UAAWD,EAAQ,EAGzCE,EAAqBA,KACvB,GAAIV,EAAIW,aAAeX,EAAIY,KAA3B,CAKAJ,IAEApJ,EAAMlM,EAAIyM,YAAYuB,MACtB,IAAMS,EAA2B,CAAA,EACdqG,EAAIa,wBACIhd,OAAOuD,MAAM,WAChC+G,SAASpE,IACb,IAAMI,EAAQJ,EAAK3C,MAAM,MACnBiZ,EAASlW,EAAM2W,QACfzd,EAAQ8G,EAAMc,KAAK,MACrBoV,IACA1G,EAAgB0G,GAAUhd,EAC9B,IAEAqc,IACA/G,EAAegB,gBAAkBA,GAGjClE,GAAiB,CACb/N,KAAM,WACNiO,QAASgE,EACTxS,MACAwN,WAAY3G,EAAQ2G,eAGxBgE,EAAeiB,aAAe5B,GAAgB,CAAEE,KAAM8H,EAAIe,SAAU/S,UAAS7G,SAEjFoP,GAA2BrL,EAAK,iBAAkB+U,EAAI9Y,IAAKgQ,EAAOC,GAC7D0D,MAAM5F,IACH,IAAMkE,EAAWb,GAAe,CAC5BrD,QACAuD,OAAQA,EACRC,OAAW,MAAHsH,OAAG,EAAHA,EAAKtH,OACbC,iBACAxB,QACAC,MACAjQ,IAAKA,EAAIjD,WACTgT,cAAe,mBAEnBqH,EAAG,CAAEnF,YAAW,IAEnB4H,OAAM,QA5CX,CA8CM,EAMVhB,EAAIrR,iBAAiB,mBAAoB+R,GAGzCV,EAAIrR,iBAAiB,QAAS6R,GAE9BR,EAAIrR,iBAAiB,QAAS6R,GAE9BR,EAAIrR,iBAAiB,UAAW6R,GAEhCZ,EAAatb,KAAK0b,EAAKvH,EAAQtR,EAAIjD,WAAY2b,EAAOC,EAAUC,EACpE,IAGR,MAAO,KACHJ,GAAc,CAEtB,CAqdsBsB,CAAgB1C,EAAIrT,EAAKmT,GACvCmB,EAjJR,SACIjB,EACArT,EACA8C,GAEA,IAAKA,EAAQuG,eAAe9Q,SAAS,SACjC,MAAO,OAIX,IAAMgc,EAAuBpK,GAAoB,UAAWrH,EAAQ0G,eAC9DgL,EAAwBrK,GAAoB,WAAYrH,EAAQ0G,eAIhEiL,EAAenQ,GAAMtE,EAAK,SAAUgW,GACtC,WAAA,IAAAC,EAAAlK,GAAO,UAAgB9P,EAAwBia,GAG3C,IACIC,EAEAlK,EACAC,EAJE6I,EAAM,IAAI1K,QAAQpO,EAAKia,GAEvBzI,EAAkD,CAAA,EAIxD,IACI,IAAMc,EAA0B,CAAA,EAChCwG,EAAItK,QAAQxH,SAAQ,CAAC9K,EAAegd,KAChC5G,EAAe4G,GAAUhd,CAAK,IAE9Boc,IACA9G,EAAec,eAAiBA,IAIAQ,GAAyB,MAAJmH,OAAI,EAAJA,EAAMlJ,OAG3DzC,GAAiB,CACb/N,KAAM,UACNiO,QAAS8D,EACTtS,MACAwN,WAAY3G,EAAQ2G,eAGxBgE,EAAee,kBAjFlC,SAEiC4H,GAAA,OAAA5D,GAAA3G,MAAAC,KAAAtK,UAAA,CA+EqB6U,CAAoB,CAAE1Z,EAAGoY,EAAKjS,UAAS7G,SAG9EgQ,EAAQjM,EAAIyM,YAAYuB,MAKxBmI,EAAM/L,GAAUnO,SAAa+Z,EAAcjB,SAAaiB,EAAc/Z,EAAKia,GAC3EhK,EAAMlM,EAAIyM,YAAYuB,MAEtB,IAAMS,EAA2B,CAAA,EAkBjC,OAjBA0H,EAAI1L,QAAQxH,SAAQ,CAAC9K,EAAegd,KAChC1G,EAAgB0G,GAAUhd,CAAK,IAE/Bqc,IACA/G,EAAegB,gBAAkBA,GAGjClE,GAAiB,CACb/N,KAAM,WACNiO,QAASgE,EACTxS,MACAwN,WAAY3G,EAAQ2G,eAGxBgE,EAAeiB,mBA1FlC,SAEkC4H,GAAA,OAAA5D,GAAA7G,MAAAC,KAAAtK,UAAA,CAwFqB+U,CAAqB,CAAE5Z,EAAGwZ,EAAKrT,UAAS7G,SAGzEka,CACX,CAAC,QACG9K,GAA2BrL,EAAK,QAAS+U,EAAI9Y,IAAKgQ,EAAOC,GACpD0D,MAAM5F,IAAU,IAAAwM,EACPtI,EAAWb,GAAe,CAC5BrD,QACAuD,OAAQwH,EAAIxH,OACZC,OAAW,OAALgJ,EAAEL,QAAG,EAAHK,EAAKhJ,OACbC,iBACAxB,QACAC,MACAjQ,IAAK8Y,EAAI9Y,IACT+P,cAAe,UAEnBqH,EAAG,CAAEnF,YAAW,IAEnB4H,OAAM,QAGf,CACJ,IAAC,OAAA,SAAAW,EAAAC,GAAA,OAAAT,EAAApK,MAAAC,KAAAtK,UAAA,CAAA,CA9ED,KAgFJ,MAAO,KACHiT,GAAc,CAEtB,CA8CwBkC,CAAkBtD,EAAIrT,EAAKmT,IAG/CF,GAAqBA,KACjBO,IACAa,IACAC,IACArB,GAAqB,IAAI,CAGjC,CAIO,IAKM2D,GAA4E9T,IAC9E,CACHpL,KAP2B,kBAQ3Bkc,SAAUV,GACVpQ,QAASA,ICr4BjBpC,GAAiBmW,sBAAwBnW,GAAiBmW,uBAAyB,CAAA,EACnFnW,GAAiBmW,sBAAsBC,aAAe,CAAEC,0BAAwBH,2BAChFlW,GAAiBmW,sBAAsBG,MAAQ,CAC3CC,OAAQC,GACRC,QAAS,KACTC,0BACAC,kBAAAA,iBAQJ3W,GAAiBsW,MAAQ,CAAEC,OAAQC,GAAaC,QAAS,MACzDzW,GAAiB4W,mBAAqB,CAAEP,2BACxCrW,GAAiBkW,uBAAyBA,GCvBnC,iDAiBMW,GAAgC,CAAA,EAChCC,GAAY,GACZC,GACZ,+XALmB,uGAAA,mEAAA,QAAA,eAAA,SAAA,4BAAA,oCAAA,SAAA,+HAAA,oCAAA,qCAAA,oBAAA,8DAAA,wJAfQ,aAeR,OAAA,kBAfQ,wGAeR,gBAAA,oCAAA,gCAAA,SAAA,ydAAA,2JAAA,OAAA,oDAAA,+FAAA,oDAAA,MAAA,iDATG,IASH,SAAA,0EAXQ,qDAAA,cAWR,0BAAA,oBATG,wEASH,+HAAA,kCAAA,SAAA,qBAXQ,yDAWR,qTAAA,4CAAA,0FAAA,aATG,YASH,qGAAA,gCATG,6FASH,mBAAA,kiBAJS,0PAIT,sDAAA,mKAAA,kMAAA,KAbU,iBAFF,wWAeR,gCAAA,wJAAA,kCAAA,sDAAA,sEAAA,yCAAA,0FAAA,4PAAA,iEAAA,oWAAA,qEAAA,sEAAA,sBAAA,8FANM,2CAMN,wBAAA,QAAA,oCAbU,qEAaV,mHAAA,4GAbU,4TAaV,wKAJS,yCAEC,2CADC,gCAGX,gHAAA,cAAA,YAAA,kHAAA,QAAA,iEAAA,qBAAA,kCAAA,wOAAA,8VAHW,+DAGX,iFAAA,mCACK,2FAAA,0IADL,mKAAA,SAAA,0GAAA,wSAAA,oCAAA,wCAAA,6IAAA,sFAAA,2JAAA,qIAAA,6aCbpB,IAAIC,GAGA/a,GAGAgb,GAsBAla,GAnBAma,GAAc,EAGdC,GAAoB,GAGlBC,GAAuDC,GAEzDjP,GAAgBgP,GAAOE,IACvBC,GAAkBH,GAAOI,IACzBC,GAAeL,GAAQM,OACvBC,GAAYP,GAAOQ,IACnBC,GAAmBT,GAAQU,QAC3B1S,GAAUgS,GAAOW,GAiHrB,SAASC,GAAaX,EAAOL,GACxBI,GAAOa,KACVb,GAAOa,IAAOhc,GAAkBob,EAAOH,IAAeF,GAEvDE,GAAc,EAOd,IAAMD,EACLhb,GAAgBic,MACfjc,GAAgBic,IAAW,CAC3BH,GAAO,GACPE,IAAiB,KAOnB,OAJIZ,GAASJ,EAAKc,GAAOtb,QACxBwa,EAAKc,GAAO/Q,KAAK,CAAA,GAGXiQ,EAAKc,GAAOV,EACpB,CAOgB,SAAAR,GAASQ,GAExB,OADAH,GAAc,EAYR,SAAoBG,EAASJ,EAAcla,GAEjD,IAAMma,EAAYc,GAAahB,KAAgB,GAE/C,GADAE,EAAUF,EAAWK,GAChBH,EAASU,MACbV,EAASa,GAAU,CACVI,QAAA,EAA0BlB,GAElC,SAAAI,GACC,IAAML,EAAeE,EAASkB,IAC3BlB,EAASkB,IAAY,GACrBlB,EAASa,GAAQ,GACd9b,EAAYib,EAAUF,EAASA,EAAcK,GAE/CL,IAAiB/a,IACpBib,EAASkB,IAAc,CAACnc,EAAWib,EAASa,GAAQ,IACpDb,EAASU,IAAYS,SAAS,CAAA,GAEhC,GAGDnB,EAASU,IAAc3b,IAElBA,GAAgBqc,KAAmB,CAAA,IAgC9BnB,EAAT,SAAyBE,EAAGL,EAAG/a,GAC9B,IAAKib,EAASU,IAAAM,IAAqB,OAAA,EAEnC,IAAMjB,EAAaC,EAASU,IAAAM,IAAAH,GAA0B9R,QACrD,SAAAoR,GAAC,OAAIA,EAACO,GAAA,IAMP,GAHsBX,EAAWsB,OAAM,SAAAlB,GAAC,OAAKA,EAACe,GAAW,IAIxD,OAAOhB,GAAUA,EAAQ1e,KAAK0S,KAAMiM,EAAGL,EAAG/a,GAM3C,IAAIc,EAAema,EAASU,IAAYY,QAAUnB,EAUlD,OATAJ,EAAW7M,MAAK,SAAAiN,GACf,GAAIA,EAAQe,IAAa,CACxB,IAAMpB,EAAeK,EAAQU,GAAQ,GACrCV,EAAQU,GAAUV,EAAQe,IAC1Bf,EAAQe,WACJpB,IAAiBK,EAAQU,GAAQ,KAAIhb,GAAA,EAC1C,CACD,IAEOqa,GACJA,EAAQ1e,KAAK0S,KAAMiM,EAAGL,EAAG/a,IACzBc,CACJ,EA7DAd,GAAgBqc,KAAA,EAChB,IAAIlB,EAAUnb,GAAiBwc,sBACzBrQ,EAAUnM,GAAiByc,oBAKjCzc,GAAiByc,oBAAsB,SAAUrB,EAAGL,EAAG/a,GACtD,GAAImP,KAAIuN,IAAS,CAChB,IAAI1B,EAAMG,EAEVA,OAAA,EACAD,EAAgBE,EAAGL,EAAG/a,GACtBmb,EAAUH,CACX,CAEI7O,GAASA,EAAQ1P,KAAK0S,KAAMiM,EAAGL,EAAG/a,EACvC,EA8CAA,GAAiBwc,sBAAwBtB,CAC1C,CAGD,OAAOD,EAASkB,KAAelB,EAASa,EACzC,CAvGQa,CAAWT,GAAgBd,EACnC,CA6GgB,SAAAwB,GAAUxB,EAAUJ,GAEnC,IAAMla,EAAQib,GAAahB,KAAgB,IACtCI,GAAO0B,KAAiBC,GAAYhc,EAAKmb,IAAQjB,KACrDla,EAAKgb,GAAUV,EACfta,EAAMka,EAAeA,EAErBhb,GAAgBic,IAAAD,IAAyBjR,KAAKjK,GAEhD,CAmBO,SAASic,GAAO3B,GAEtB,OADAH,GAAc,EACP+B,IAAQ,WAAO,MAAA,CAAEC,QAAS7B,EAAc,GAAG,GACnD,CAiCO,SAAS4B,GAAQ5B,EAASpb,GAEhC,IAAMgb,EAAQe,GAAahB,KAAgB,GAO3C,OANI+B,GAAY9B,EAAKiB,IAAQjc,KAC5Bgb,EAAKc,GAAUV,IACfJ,EAAKiB,IAASjc,EACdgb,EAAKgB,IAAYZ,GAGXJ,EAAKc,EACb,CAegB,SAAAnf,GAAWye,GAC1B,IAAMJ,EAAWhb,GAAiBkd,QAAQ9B,EAAOO,KAK3C7a,EAAQib,GAAahB,KAAgB,GAK3C,OADAja,EAAKqa,EAAYC,EACZJ,GAEe,MAAhBla,EAAKgb,KACRhb,EAAKgb,IAAA,EACLd,EAASmC,IAAInd,KAEPgb,EAASuB,MAAM/gB,OANA4f,EAAOU,EAO9B,CA2DA,SAASsB,KAER,IADA,IAAIhC,EACIA,EAAYF,GAAkBjC,SAAU,CAC/C,IAAM8B,EAAQK,EAASa,IACvB,GAAKb,EAASiC,KAAgBtC,EAC9B,IACCA,EAAKiB,IAAiB7N,KAAKmP,IAC3BvC,EAAKiB,IAAiB7N,KAAKoP,IAC3BxC,EAAKiB,IAAmB,EAIzB,OAHShc,GACR+a,EAAKiB,IAAmB,GACxBb,GAAOuB,IAAa1c,EAAGob,EAASoC,IACjC,CACD,CACD,CA1aArC,GAAOE,IAAS,SAAAD,GACfpb,GAAmB,KACfmM,IAAeA,GAAciP,EAClC,EAEAD,GAAOW,GAAS,SAACV,EAAOL,GACnBK,GAASL,EAAS0C,KAAc1C,EAAS0C,IAAAC,MAC5CtC,EAAKsC,IAAS3C,EAAS0C,IAAAC,KAGpBvU,IAASA,GAAQiS,EAAOL,EAC7B,EAGAI,GAAOI,IAAW,SAAAH,GACbE,IAAiBA,GAAgBF,GAGrCL,GAAe,EAEf,IAAMja,GAHNd,GAAmBob,EAAKO,KAGMM,IAC1Bnb,IACCka,KAAsBhb,IACzBc,EAAKkb,IAAmB,GACxBhc,GAAgBgc,IAAoB,GACpClb,EAAKgb,GAAO3N,MAAK,SAAAiN,GACZA,EAAQe,MACXf,EAAQU,GAAUV,EAAQe,KAE3Bf,EAASJ,EAAeI,EAAQe,UACjC,MAEArb,EAAKkb,IAAiB7N,KAAKmP,IAC3Bxc,EAAKkb,IAAiB7N,KAAKoP,IAC3Bzc,EAAKkb,IAAmB,GACxBjB,GAAe,IAGjBC,GAAoBhb,EACrB,EAGAmb,GAAQM,OAAS,SAAAL,GACZI,IAAcA,GAAaJ,GAE/B,IAAML,EAAIK,EAAKO,IACXZ,GAAKA,EAACkB,MACLlB,EAACkB,IAAAD,IAAyBxb,SAgaR,IAha2B0a,GAAkBnQ,KAAKgQ,IAga7Cja,KAAYqa,GAAQwC,yBAC/C7c,GAAUqa,GAAQwC,wBACN9C,IAAgBuC,KAja5BrC,EAACkB,IAAAH,GAAe3N,MAAK,SAAAiN,GAChBA,EAASJ,IACZI,EAAQa,IAASb,EAASJ,GAE3BI,EAASJ,QACV,KAEDA,GAAoBhb,GAAmB,IACxC,EAIAmb,GAAOQ,IAAW,SAACP,EAAOL,GACzBA,EAAY5M,MAAK,SAAAiN,GAChB,IACCA,EAASY,IAAkB7N,KAAKmP,IAChClC,EAASY,IAAoBZ,EAASY,IAAkBhS,QAAO,SAAAoR,GAAE,OAChEA,EAAEU,IAAUyB,GAAanC,EAAU,GAQrC,OANSpb,GACR+a,EAAY5M,MAAK,SAAAiN,GACZA,EAACY,MAAmBZ,EAACY,IAAoB,GAC9C,IACAjB,EAAc,GACdI,GAAOuB,IAAa1c,EAAGob,EAASoC,IACjC,CACD,IAEI9B,IAAWA,GAAUN,EAAOL,EACjC,EAGAI,GAAQU,QAAU,SAAAT,GACbQ,IAAkBA,GAAiBR,GAEvC,IAEKL,EAFC/a,EAAIob,EAAKO,IACX3b,GAAKA,EAACic,MAETjc,EAACic,IAAAH,GAAe3N,MAAK,SAAAiN,GACpB,IACCkC,GAAclC,EAGf,OAFSA,GACRL,EAAaK,CACd,CACD,IACApb,EAACic,SAAA,EACGlB,GAAYI,GAAOuB,IAAa3B,EAAY/a,EAACwd,KAEnD,EA4UA,IAAII,GAA0C,mBAAzBD,sBAYrB,SAAS9C,GAAeO,GACvB,IAOIL,EAPE/a,EAAO,WACZoT,aAAa4H,GACT4C,IAASC,qBAAqB9C,GAClC7K,WAAWkL,EACZ,EACMJ,EAAU9K,WAAWlQ,EAlcR,IAqcf4d,KACH7C,EAAM4C,sBAAsB3d,GAE9B,CAqBA,SAASsd,GAAclC,GAGtB,IAAML,EAAO/a,GACTgb,EAAUI,EAAIO,IACI,mBAAXX,IACVI,EAAIO,SAAA,EACJX,KAGDhb,GAAmB+a,CACpB,CAOA,SAASwC,GAAanC,GAGrB,IAAML,EAAO/a,GACbob,EAAIO,IAAYP,EAAIU,KACpB9b,GAAmB+a,CACpB,CAOA,SAAS+B,GAAY1B,EAASL,GAC7B,OACEK,GACDA,EAAQ5a,SAAWua,EAAQva,QAC3Bua,EAAQ5M,MAAK,SAAC4M,EAAK/a,GAAU,OAAA+a,IAAQK,EAAQpb,EAAM,GAErD,CAQA,SAASkc,GAAed,EAAKL,GAC5B,MAAmB,mBAALA,EAAkBA,EAAEK,GAAOL,CAC1C,CC9PO,IAAM+C,GAAmB,CAE5BC,IAAK,MACLC,SAAU,YAIDC,GAAiB,CAC1BC,QAAS,WACTC,SAAU,YACVC,UAAW,aACXC,WAAY,cACZC,YAAa,eACbC,aAAc,gBACdC,KAAM,OACNC,OAAQ,SACRC,MAAO,QACPC,cAAe,mBAINC,GAAoB,CAC7BC,IAAK,MACLL,KAAM,OACNE,MAAO,QACPI,OAAQ,UAICC,GAAa,CACtBC,QAAS,UACTC,IAAK,MACLC,OAAQ,SACRC,eAAgB,mBAIPC,GAAqB,CAC9BC,KAAM,OACNC,eAAgB,kBAChBC,aAAc,gBACdC,OAAQ,SACRC,KAAM,QAIGC,GAA8B,CAEvCC,IAAK,MACLC,cAAe,iBACfC,iBAAkB,qBAITC,GAGD,SAICC,GAAkB,CAC3BC,MAAO,eACPC,UAAW,mBACXC,KAAM,cACNC,UAAW,oBAIFC,GAAwB,CACjCC,UAAW,aACXC,YAAa,eAEbC,iBAAkB,oBAClBC,4BAA6B,+BAC7BC,2BAA4B,8BAC5BC,qBAAsB,wBAEtBC,iBAAkB,oBAGlBC,gBAAiB,oBC3XrB,SAASC,GAAqBC,GAC1B,MAAA,oBAA2BA,CAC/B,CAIA,SAASC,GAAuBC,EAAWF,GACvC,IAAKA,EAAY,OAAO,KACxB,IAAM5H,EAAW8H,EAAUH,GAAqBC,IAChD,OAAIxkB,GAAQ4c,GAAkB,IACvBA,GAEAA,CACX,CACA,SAAS+H,GAA8BD,EAAgBE,QAAP,IAATF,IAAAA,EAAY,CAAA,GAC/C,IAAMG,EAAqB,CAAA,EAO3B,OANAD,EAAOE,UAAU9a,SAAS+a,IACtB,IAAIxkB,GAAYwkB,EAASC,uBAAzB,CACA,IAfyBA,EAenBC,EAdH,KADsBD,EAesBD,EAASC,uBAdvB,uCAAyCA,EAepEpI,EAAW6H,GAAuBC,EAAWK,EAASjW,IACvDvO,GAAYqc,KAAWiI,EAAmBI,GAAkBrI,EAHhB,CAGwB,IAE7E1H,EAAA,CACIgQ,kBAAmBN,EAAOE,UAAUK,KAAKJ,IAAQ,CACzCjW,GAAIiW,EAASjW,GACbiW,SAAUA,EAASA,SACnBnI,SAAU6H,GAAuBC,EAAWK,EAASjW,SAE1D4V,EACAG,EAEX,CAIA,SAASO,GAA6BR,EAAQS,GAC1C,IAAIC,EAAc,WAAcD,EAAM,IAAIT,EAAO9V,GAEjD,OADI8V,EAAOW,mBAAqBX,EAAOW,kBAAoB,IAAGD,EAAc,WAAcD,MAAUT,EAAO9V,GAAE,IAAI8V,EAAOW,mBACjHD,CACX,CCxCA,SAASE,GAAmBtmB,GACxB,MAAO,iBAAmBA,GAASA,EAAMQ,OAASR,EAAMQ,OAAS,IACrE,CAwBA,SAAS+lB,GAAsBC,GAC3B,OAAOA,EAAaljB,aACxB,CAIA,SAASmjB,GAAyBC,EAAcC,EAAgB7d,GAC5D,IAAK4d,IAAiBC,EAAgB,OAAO,KAC7C,IAAMC,EAAmBL,GAAsBI,GACzCE,EAAajnB,OAAOmF,KAAK2hB,GAAcniB,MAAMyG,GAAMub,GAAsBvb,KAAS4b,IACxF,GAAIC,EAEA,aADA/d,GAAAA,EAAQU,MAAK,kCAAmCqd,GACzCA,EAEX,GAAID,EAAiBxmB,SAAS,KAAM,CAChC,IAAM0mB,EAA+BF,EAXrB7iB,MAAM,KAAK,GAYrBgjB,EAAYnnB,OAAOmF,KAAK2hB,GAAcniB,MAAMyG,GAAMub,GAAsBvb,KAAS8b,IACvF,GAAIC,EAEA,OADM,MAANje,GAAAA,EAAQU,gDAAgDud,EAAS,UAAUJ,EAAc,KAClFI,CAEf,CACA,OAAO,IACX,CA0DA,SAASC,GAAuBtB,EAAQiB,EAAgB7d,GAAQ,IAAAme,EACtDC,EAAiBT,GAAyBf,EAAOgB,aAAcC,EAAgB7d,GAC/Eqe,EAAUnR,EAAA,CAAA,EACT0P,GAEH0B,GAAiB,EACrB,GAAIF,EAAgB,CAAA,IAAAG,EACVC,EAAiC,OAAtBD,EAAG3B,EAAOgB,mBAAY,EAAnBW,EAAsBH,GACtCI,UACAxe,GAAAA,EAAQa,KAAI,mDAAoDud,GAC3D7lB,GAAYimB,EAAY/nB,QACzB4nB,EAAW5nB,KAAO+nB,EAAY/nB,KAC9B6nB,GAAiB,GAEjBD,EAAWI,YACXJ,EAAWI,WAAUvR,KACdmR,EAAWI,YAEblmB,GAAYimB,EAAYE,yBACzBL,EAAWI,WAAWC,sBAAwBF,EAAYE,sBAC1DJ,GAAiB,GAEhB/lB,GAAYimB,EAAYG,8BACzBN,EAAWI,WAAWE,2BAA6BH,EAAYG,2BAC/DL,GAAiB,GAEhB/lB,GAAYimB,EAAYI,kCACzBP,EAAWI,WAAWG,+BAAiCJ,EAAYI,+BACnEN,GAAiB,GAEhB/lB,GAAYimB,EAAYK,oBACzBR,EAAWI,WAAWI,iBAAmBL,EAAYK,iBACrDP,GAAiB,GAEhB/lB,GAAYimB,EAAYM,kBACzBT,EAAWI,WAAWK,eAAiBN,EAAYM,eACnDR,GAAiB,IA1FrC,SAAkCE,GAC9B,QAAQjmB,GAAYimB,EAAYE,wBAA2BnmB,GAAYimB,EAAYG,6BAAgCpmB,GAAYimB,EAAYI,iCAAoCrmB,GAAYimB,EAAYK,mBAAsBtmB,GAAYimB,EAAYM,gBACzP,CA0FuBC,CAAyBP,KAAcF,GAAiB,GAE3E,CACA,IAAMU,EAAoBpC,EAAOE,UAAUK,KAAKJ,GA5FpD,SAAkCA,EAAUc,EAAgB7d,GAAQ,IAAAif,EAC1Db,EAAiBT,GAAyBZ,EAASa,aAAcC,EAAgB7d,GACvF,IAAKoe,EAAgB,MAAO,CACxBrB,WACAmC,WAAY,KACZC,YAAY,GAEhB,IAAMC,EAA2C,OAAxBH,EAAGlC,EAASa,mBAAY,EAArBqB,EAAwBb,GACpD,IAAKgB,EAAqB,MAAO,CAC7BrC,WACAmC,WAAY,KACZC,YAAY,GAEhB,IAAMd,EAAUnR,EAAA,CAAA,EACT6P,GAEHoC,GAAa,EA6BjB,OA5BK5mB,GAAY6mB,EAAoBrC,YACjCsB,EAAWtB,SAAWqC,EAAoBrC,SAC1CoC,GAAa,GAEZ5mB,GAAY6mB,EAAoBC,eACjChB,EAAWgB,YAAcD,EAAoBC,YAC7CF,GAAa,GAEZ5mB,GAAY6mB,EAAoBE,cACjCjB,EAAWiB,WAAaF,EAAoBE,WAC5CH,GAAa,GAEb,SAAUd,IAAe9lB,GAAY6mB,EAAoBG,QACzDlB,EAAWkB,KAAOH,EAAoBG,KACtCJ,GAAa,GAEb,oBAAqBd,IAAe9lB,GAAY6mB,EAAoBI,mBACpEnB,EAAWmB,gBAAkBJ,EAAoBI,gBACjDL,GAAa,GAEb,oBAAqBd,IAAe9lB,GAAY6mB,EAAoBK,mBACpEpB,EAAWoB,gBAAkBL,EAAoBK,gBACjDN,GAAa,GAEb,YAAad,GA/CrB,SAA6Be,GACzB,OAAOpnB,GAAQonB,EAAoBM,QACvC,CA6CmCC,CAAoBP,KAC/Cf,EAAWqB,QAAUN,EAAoBM,QACzCP,GAAa,GAEV,CACHpC,SAAUoC,EAAad,EAAatB,EACpCmC,WAAYC,EAAaf,EAAiB,KAC1Ce,aAER,CA0C+DS,CAAyB7C,EAAUc,EAAgB7d,KACxG6f,EAAsBb,EAAkB7B,KAAK7gB,GAASA,EAAOygB,WAC7D+C,EAAwBd,EAAkBnV,MAAMvN,GAASA,EAAO6iB,aAClEY,EAAqB,KAOzB,OANK3B,IAAgB2B,UAAqB5B,EAAAa,EAAkBvjB,MAAMa,GAASA,EAAO4iB,qBAAxCf,EAAqDe,aAAc,MACzGY,IACAzB,EAAWvB,UAAY+C,EACvBvB,GAAiB,QACjBte,GAAAA,EAAQa,KAAI,qDAAsDgd,IAE/D,CACHjB,OAAQyB,EACRa,WAAYZ,EAAiBF,GAAkB2B,EAAqB,KAE5E,CC9JO,IAAMC,GAAgBre,GAAa,aAe7Bse,GAA4B,oBAGnCC,GAAsBA,CAACrgB,EAAgB+c,KACzC,IAAI1a,EAAG,GAAMrC,EAAS+c,EAAO9V,GAI7B,OAHI8V,EAAOW,mBAAqBX,EAAOW,kBAAoB,IACvDrb,EAAG,GAAMrC,EAAS+c,EAAO9V,GAAE,IAAI8V,EAAOW,mBAEnCrb,CAAG,EAGDie,GAAoBvD,GACtBsD,GAbuB,cAaiBtD,GAOtCwD,GAA+BxD,IACxC,IACI,IAAMyD,EAAgBF,GAAiBvD,GAGvC,GAFqB0D,aAAaC,QAAQF,GAGtC,OAGJC,aAAaE,QAAQH,EAAe,OACxC,CAAE,MAAOlf,GACL6e,GAAc7e,MAAM,sCAAuCA,EAC/D,GAKSsf,GAAoC,CAAChG,GAAWC,QAASD,GAAWG,OAAQH,GAAWE,KCzC/F/N,KAAK8T,QACN9T,KAAK8T,MAAQ,SAAUxJ,GACnB,OAAW,EAAJA,EAAQtK,KAAK+T,KAAKzJ,GAAKtK,KAAKC,MAAMqK,EAC7C,GAICzH,OAAOmR,YACRnR,OAAOmR,UAAY,SAAU1pB,GACzB,OAAOyB,GAASzB,IAAUwY,SAASxY,IAAU0V,KAAKC,MAAM3V,KAAWA,CACvE,GAIG,MAAM2pB,GAETC,WAAAA,CAAqBC,GACjB,GAD8ClW,KAA7BkW,MAAAA,EACI,KAAjBA,EAAM7kB,OACN,MAAM,IAAI8kB,UAAU,qBAE5B,CAUA,mBAAOC,CAAaC,EAAkBC,EAAeC,EAAiBC,GAClE,IACK5R,OAAOmR,UAAUM,KACjBzR,OAAOmR,UAAUO,KACjB1R,OAAOmR,UAAUQ,KACjB3R,OAAOmR,UAAUS,IACP,EAAXH,GACQ,EAARC,GACU,EAAVC,GACU,EAAVC,GACAH,EAAW,gBACXC,EAAQ,MACRC,EAAU,YACVC,EAAU,WAEV,MAAM,IAAIC,WAAW,uBAGzB,IAAMP,EAAQ,IAAIhQ,WAAW,IAiB7B,OAhBAgQ,EAAM,GAAKG,EAAQtU,KAAA2U,IAAG,EAAK,IAC3BR,EAAM,GAAKG,EAAQtU,KAAA2U,IAAG,EAAK,IAC3BR,EAAM,GAAKG,EAAQtU,KAAA2U,IAAG,EAAK,IAC3BR,EAAM,GAAKG,EAAQtU,KAAA2U,IAAG,EAAK,IAC3BR,EAAM,GAAKG,EAAQtU,KAAA2U,IAAG,EAAK,GAC3BR,EAAM,GAAKG,EACXH,EAAM,GAAK,IAAQI,IAAU,EAC7BJ,EAAM,GAAKI,EACXJ,EAAM,GAAK,IAAQK,IAAY,GAC/BL,EAAM,GAAKK,IAAY,GACvBL,EAAM,IAAMK,IAAY,EACxBL,EAAM,IAAMK,EACZL,EAAM,IAAMM,IAAY,GACxBN,EAAM,IAAMM,IAAY,GACxBN,EAAM,IAAMM,IAAY,EACxBN,EAAM,IAAMM,EACL,IAAIR,GAAKE,EACpB,CAGAhpB,QAAAA,GAEI,IADA,IAAI0P,EAAO,GACFjL,EAAI,EAAOqO,KAAKkW,MAAM7kB,OAAfM,EAAuBA,IACnCiL,EAAOA,GAAQoD,KAAKkW,MAAMvkB,KAAO,GAAGzE,SAAS,KAAuB,GAAhB8S,KAAKkW,MAAMvkB,IAAUzE,SAAS,IACxE,IAANyE,GAAiB,IAANA,GAAiB,IAANA,GAAiB,IAANA,IACjCiL,GAAQ,KAIhB,GAAoB,KAAhBA,EAAKvL,OAGL,MAAM,IAAIslB,MAAM,gCAEpB,OAAO/Z,CACX,CAGAiH,KAAAA,GACI,OAAO,IAAImS,GAAKhW,KAAKkW,MAAMliB,MAAM,GACrC,CAGA4iB,MAAAA,CAAOC,GACH,OAAiC,IAA1B7W,KAAK8W,UAAUD,EAC1B,CAMAC,SAAAA,CAAUD,GACN,IAAK,IAAIllB,EAAI,EAAO,GAAJA,EAAQA,IAAK,CACzB,IAAMolB,EAAO/W,KAAKkW,MAAMvkB,GAAKklB,EAAMX,MAAMvkB,GACzC,GAAa,IAATolB,EACA,OAAOhV,KAAKiV,KAAKD,EAEzB,CACA,OAAO,CACX,EAIJ,MAAME,GAAYhB,WAAAA,GAAAjW,KACNkX,EAAa,EAAClX,KACdmX,EAAW,EAACnX,KACHoX,EAAU,IAAIC,EAAe,CAY9CC,QAAAA,GACI,IAAMjrB,EAAQ2T,KAAKuX,kBACnB,GAAK7pB,GAAYrB,GAEV,CAEH2T,KAAKkX,EAAa,EAClB,IAAMM,EAAkBxX,KAAKuX,kBAC7B,GAAI7pB,GAAY8pB,GACZ,MAAM,IAAIb,MAAM,iDAEpB,OAAOa,CACX,CATI,OAAOnrB,CAUf,CAWAkrB,eAAAA,GACI,IAGME,EAAKxV,KAAKC,MAChB,GAAIuV,EAAKzX,KAAKkX,EACVlX,KAAKkX,EAAaO,EAClBzX,KAAK0X,QACF,IAA8B1X,KAAKkX,GAA/BO,EANgB,IAgBvB,OARAzX,KAAKmX,IACDnX,KAAKmX,EAVO,gBAYZnX,KAAKkX,IACLlX,KAAK0X,IAKb,CAEA,OAAO1B,GAAKI,aACRpW,KAAKkX,EACLnV,KAAK8T,MAAM7V,KAAKmX,EAAQpV,KAAA2U,IAAG,EAAK,KAChC1W,KAAKmX,EAAYpV,KAAA2U,IAAA,EAAK,IAAK,EAC3B1W,KAAKoX,EAAQO,aAErB,CAGQD,CAAAA,GACJ1X,KAAKmX,EAAuC,KAA5BnX,KAAKoX,EAAQO,cAAoD,KAA5B3X,KAAKoX,EAAQO,aACtE,EAOJ,IAmCIC,GAnCAC,GAAyEC,IAGzE,GAAoC,oBAAzBC,sBAAwCA,qBAC/C,MAAM,IAAIpB,MAAM,6CAGpB,IAAK,IAAIhlB,EAAI,EAAOmmB,EAAOzmB,OAAXM,EAAmBA,IAC/BmmB,EAAOnmB,GAA4C,MAAvCoQ,KAAK8T,MAAsB,MAAhB9T,KAAKiW,UAAkCjW,KAAK8T,MAAsB,MAAhB9T,KAAKiW,UAElF,OAAOF,CAAM,EAIb3jB,KAAWzG,GAAYyG,GAAO8jB,SAAWA,OAAOJ,kBAChDA,GAAmBC,GAAWG,OAAOJ,gBAAgBC,IAQzD,MAAMT,GAAcpB,WAAAA,GAAAjW,KACCkY,EAAU,IAAIC,YAAY,GAAEnY,KACrCoY,EAAUC,GAAQ,CAC1BV,UAAAA,GAKI,OAJoB3X,KAAKkY,EAAQ7mB,OAA7B2O,KAAKoY,IACLP,GAAgB7X,KAAKkY,GACrBlY,KAAKoY,EAAU,GAEZpY,KAAKkY,EAAQlY,KAAKoY,IAC7B,EAWG,IAAME,GAASA,IAAcC,KAAYrrB,WAG1CqrB,GAAYA,KAAaX,KAAqBA,GAAmB,IAAIX,KAAgBK,WClP9EkB,GAAkB,SAAUnsB,EAAeosB,GACpD,IAVwB,SAAU/rB,GAClC,IACI,IAAIoD,OAAOpD,EACf,CAAE,MAAAJ,GACE,OAAO,CACX,CACA,OAAO,CACX,CAGSosB,CAAaD,GAAU,OAAO,EAEnC,IACI,OAAO,IAAI3oB,OAAO2oB,GAASvc,KAAK7P,EACpC,CAAE,MAAAgT,GACE,OAAO,CACX,CACJ,ECHasZ,GAAkG,CAC3GC,MAAOA,CAACC,EAASC,IAAWA,EAAO9Z,MAAM3S,GAAUwsB,EAAQ7Z,MAAMrC,GAAWtQ,IAAUsQ,MACtFoc,OAAQA,CAACF,EAASC,IAAWA,EAAO3L,OAAO9gB,GAAUwsB,EAAQ1L,OAAOxQ,GAAWtQ,IAAUsQ,MACzFqc,MAAOA,CAACH,EAASC,IAAWA,EAAO9Z,MAAM3S,GAAUwsB,EAAQ7Z,MAAMrC,GAAW6b,GAAgBnsB,EAAOsQ,OACnGsc,UAAWA,CAACJ,EAASC,IAAWA,EAAO3L,OAAO9gB,GAAUwsB,EAAQ1L,OAAOxQ,IAAY6b,GAAgBnsB,EAAOsQ,OAC1Guc,UAAWA,CAACL,EAASC,IACjBA,EAAOxG,IAAI3iB,IAAaqP,MAAM3S,GAAUwsB,EAAQvG,IAAI3iB,IAAaqP,MAAMrC,GAAWtQ,EAAMI,SAASkQ,OACrGwc,cAAeA,CAACN,EAASC,IACrBA,EAAOxG,IAAI3iB,IAAawd,OAAO9gB,GAAUwsB,EAAQvG,IAAI3iB,IAAawd,OAAOxQ,IAAYtQ,EAAMI,SAASkQ,OACxGyc,GAAIA,CAACP,EAASC,IACVA,EAAO9Z,MAAM3S,IACT,IAAMgtB,EAAWC,WAAWjtB,GAC5B,OAAQktB,MAAMF,IAAaR,EAAQ7Z,MAAM4M,GAAMyN,EAAWC,WAAW1N,IAAG,IAEhF4N,GAAIA,CAACX,EAASC,IACVA,EAAO9Z,MAAM3S,IACT,IAAMgtB,EAAWC,WAAWjtB,GAC5B,OAAQktB,MAAMF,IAAaR,EAAQ7Z,MAAM4M,GAAMyN,EAAWC,WAAW1N,IAAG,KAI9Ejc,GAAe0c,GAAsBA,EAAE1c,cCsJzC8pB,GAA0C,KAKjCC,GAA8B,CACvCC,CA2BA,GA1BI,IAAK/rB,GAAO6rB,IACR,OAAOA,GAGX,IAAIG,GAAY,EAChB,GAAKlsB,GAAYyG,IAabylB,GAAY,OAZZ,IACI,IAAMviB,EAAM,kBAEZqiB,GAAWG,EAAKxiB,EADN,OAEmB,UAAzBqiB,GAAWI,EAAKziB,KAChBuiB,GAAY,GAEhBF,GAAWK,EAAQ1iB,EACvB,CAAE,MAAA6M,GACE0V,GAAY,CAChB,CASJ,OALKA,GACDzkB,GAAOmB,MAAM,0DAGjBmjB,GAA0BG,EACnBA,CACX,EAEAI,CAEA,CAFkBC,GACd9kB,GAAOmB,MAAM,uBAAyB2jB,EAC1C,EAEAH,CAOA,CAPgBluB,GACZ,IACI,aAAOuI,UAAAA,GAAQshB,aAAaC,QAAQ9pB,EACxC,CAAE,MAAOgI,GACL8lB,GAAWM,EAAOpmB,EACtB,CACA,OAAO,IACX,EAEAsmB,CAOA,CAPkBtuB,GACd,IACI,OAAOuV,KAAKgZ,MAAMT,GAAWI,EAAKluB,KAAU,CAAA,CAChD,CAAE,MAAAwZ,GACE,CAEJ,OAAO,IACX,EAEAyU,CAQA,CARgBjuB,EAAMS,GAClB,IAEI,OADM,MAAN8H,IAAAA,GAAQshB,aAAaE,QAAQ/pB,EAAMuV,KAAKC,UAAU/U,KAC3C,CACX,CAAE,MAAOuH,GACL8lB,GAAWM,EAAOpmB,EACtB,CACA,OAAO,CACX,EAEAmmB,CAMA,CANmBnuB,GACf,IACU,MAANuI,IAAAA,GAAQshB,aAAa2E,WAAWxuB,EACpC,CAAE,MAAOgI,GACL8lB,GAAWM,EAAOpmB,EACtB,CACJ,GC/PEuB,GAAS2B,GAAa,uBC8BtB3C,GAASkmB,GACT5lB,GAAW6lB,GAiBXC,GAAmB,UAGZC,GAA0B,CACnCC,WAAY,UACZC,gBAAiB,UACjBC,kBAAmB,QACnBC,sBAAuB,QACvBC,kBAAmB,QACnBC,wBAAyB,QACzBC,YAAa,UACbC,YAAa,kBACbC,YAAY,EACZC,wBAAwB,EACxBrH,sBAAuB,+BACvBsH,SAAUrM,GAAeS,MACzB6L,WAAYzM,GAAiBC,IAC7ByM,YAAa,WACbC,YAAa,QACbC,OAAQC,OjBuEmB,YiBtE3BC,sBAAuB,MACvBC,SAAU,QACVC,gBAAiB,UACjBC,WAAY,YACZC,UAAW,iCACXC,aAAc,OACdC,kBAAkB,EAClBC,6BAAyB5nB,EAEzB6nB,aAAc,0BACdC,gBAAiB,QACjBC,eAAgB5B,GAChB6B,oBAAqB,gCACrBC,oBAAqB,qCAGnBC,GAAmD,CACrDxN,GAAeQ,OACfR,GAAeO,KACfP,GAAeS,OA0NZ,SAASgN,GAAQvQ,GACpB,GAAIA,EAAE7M,WAAW,KAAM,CACnB,IAAIqd,EAAWxQ,EAAEjR,QAAQ,KAAM,IAK/B,MAHI,mBAAmBmB,KAAKsgB,KACxBA,EAAWA,EAAS,GAAKA,EAAS,GAAKA,EAAS,GAAKA,EAAS,GAAKA,EAAS,GAAKA,EAAS,IAEzF,mBAAmBtgB,KAAKsgB,GAM7B,OAHU7X,SAAS6X,EAASxoB,MAAM,EAAG,GAAI,IAG1B,IAFL2Q,SAAS6X,EAASxoB,MAAM,EAAG,GAAI,IAErB,IADV2Q,SAAS6X,EAASxoB,MAAM,EAAG,GAAI,IAChB,IALd,oBAMf,CACA,MAAO,oBACX,CAWO,SAASyoB,GAAwBC,GACpC,IAAIC,OAD6C,IAAbD,IAAAA,EAAgBlC,GAAwBE,iBAE3D,MAAbgC,EAAM,KACNC,EAAMJ,GAAQG,IAEdA,EAAMvd,WAAW,SACjBwd,EAAMD,GAGV,IAAME,EApLC,CACHC,UAAW,UACXC,aAAc,UACdC,KAAM,UACNC,WAAY,UACZC,MAAO,UACPC,MAAO,UACPC,OAAQ,UACRC,MAAO,UACPC,eAAgB,UAChBC,KAAM,UACNC,WAAY,UACZC,MAAO,UACPC,UAAW,UACXC,UAAW,UACXC,WAAY,UACZC,UAAW,UACXC,MAAO,UACPC,eAAgB,UAChBC,SAAU,UACVC,QAAS,UACTC,KAAM,UACNC,SAAU,UACVC,SAAU,UACVC,cAAe,UACfC,SAAU,UACVC,UAAW,UACXC,UAAW,UACXC,YAAa,UACbC,eAAgB,UAChBC,WAAY,UACZC,WAAY,UACZC,QAAS,UACTC,WAAY,UACZC,aAAc,UACdC,cAAe,UACfC,cAAe,UACfC,cAAe,UACfC,WAAY,UACZC,SAAU,UACVC,YAAa,UACbC,QAAS,UACTC,WAAY,UACZC,UAAW,UACXC,YAAa,UACbC,YAAa,UACbC,QAAS,UACTC,UAAW,UACXC,WAAY,UACZC,KAAM,UACNC,UAAW,UACXC,KAAM,UACNC,MAAO,UACPC,YAAa,UACbC,SAAU,UACVC,QAAS,UACT,aAAc,UACdC,OAAQ,UACRC,MAAO,UACPC,MAAO,UACPC,SAAU,UACVC,cAAe,UACfC,UAAW,UACXC,aAAc,UACdC,UAAW,UACXC,WAAY,UACZC,UAAW,UACXC,qBAAsB,UACtBC,UAAW,UACXC,WAAY,UACZC,UAAW,UACXC,YAAa,UACbC,cAAe,UACfC,aAAc,UACdC,eAAgB,UAChBC,eAAgB,UAChBC,YAAa,UACbC,KAAM,UACNC,UAAW,UACXC,MAAO,UACPC,QAAS,UACTC,OAAQ,UACRC,iBAAkB,UAClBC,WAAY,UACZC,aAAc,UACdC,aAAc,UACdC,eAAgB,UAChBC,gBAAiB,UACjBC,kBAAmB,UACnBC,gBAAiB,UACjBC,gBAAiB,UACjBC,aAAc,UACdC,UAAW,UACXC,UAAW,UACXC,SAAU,UACVC,YAAa,UACbC,KAAM,UACNC,QAAS,UACTC,MAAO,UACPC,UAAW,UACXC,OAAQ,UACRC,UAAW,UACXC,OAAQ,UACRC,cAAe,UACfC,UAAW,UACXC,cAAe,UACfC,cAAe,UACfC,WAAY,UACZC,UAAW,UACXC,KAAM,UACNC,KAAM,UACNC,KAAM,UACNC,WAAY,UACZC,OAAQ,UACRC,IAAK,UACLC,UAAW,UACXC,UAAW,UACXC,YAAa,UACbC,OAAQ,UACRC,WAAY,UACZC,SAAU,UACVC,SAAU,UACVC,OAAQ,UACRC,OAAQ,UACRC,QAAS,UACTC,UAAW,UACXC,UAAW,UACXC,KAAM,UACNC,YAAa,UACbC,UAAW,UACXC,IAAK,UACLC,KAAM,UACNC,QAAS,UACTC,OAAQ,UACRC,UAAW,UACXC,OAAQ,UACRC,MAAO,UACPC,MAAO,UACPC,WAAY,UACZC,OAAQ,UACRC,YAAa,WAwCgB7I,EAvC1B/sB,eA2CP,GAHIitB,IACAD,EAAMJ,GAAQK,KAEbD,EACD,OAAOpC,GAEX,IAAMiL,EAAa7I,EAAI8I,MAAM,8DAC7B,GAAID,EAAY,CACZ,IAAM30B,EAAI8T,SAAS6gB,EAAW,IACxBE,EAAI/gB,SAAS6gB,EAAW,IACxBG,EAAIhhB,SAAS6gB,EAAW,IAE9B,OADYzjB,KAAK6jB,KAAc/0B,EAAIA,EAAb,KAA2B60B,EAAIA,EAAb,KAA2BC,EAAIA,EAAb,MAC7C,MAAQpL,GAAmB,OAC5C,CACA,OAAOA,EACX,CAQO,IAAMsL,GAAuBA,CAChC9T,EACA+T,EACAluB,KAEA,IAAMmuB,EAAkBC,GAAwBjU,GAC1CkU,EAAcxxB,GAASyxB,cAAa,IAAKH,GAE/C,GAAIE,GAAeA,EAAYE,WAC3B,MAAO,CACHC,OAAQH,EAAYE,WACpBE,gBAAgB,GAKxB,IAAMC,EAAM7xB,GAAS8xB,cAAc,OAnSOC,EAC1C5uB,EACAlH,EACAkjB,KAEA,IAAM6S,EAAmBpkB,KAAQmY,GAA4B5G,GACvD8S,EAAY9uB,EAAQ+uB,MAEpBC,GACDtK,GAA+B7vB,SAASg6B,EAAoBtL,WAC5DzqB,IAASkf,GAAWG,SAAoB,MAAV6D,OAAU,EAAVA,EAAYwH,cAAezM,GAAiBC,IAE/E8X,EAAUG,YAAY,0BAlEnB,SAAuBpM,GAC1B,GAAmB,YAAfA,EACA,MAAO,UAGX,IAAMqM,EACF,4IACJ,OAAOrM,EAAgBA,EAAU,KAAKqM,oBAAuCA,CACjF,CA0DqDC,CAAcN,EAAoBhM,aACnFiM,EAAUG,YAAY,0BAA2BJ,EAAoB7K,YACrE8K,EAAUG,YAAY,wBAAyBJ,EAAoB/K,UACnEgL,EAAUG,YAAY,sBAAuBJ,EAAoBlL,QACjEmL,EAAUG,YAAY,2BAA4BJ,EAAoB1L,aAElE6L,GACAF,EAAUG,YAAY,4BAA6BJ,EAAoB3K,cACvE4K,EAAUG,YAAY,4BAA6B,+CAEnDH,EAAUG,YAAY,4BAA6B,QACnDH,EAAUG,YACN,4BACGJ,EAAoB3K,aAAY,IAAI2K,EAAoB3K,sBAGnE4K,EAAUG,YAAY,+BAAgCJ,EAAoB/L,iBAC1EgM,EAAUG,YAAY,yBAA0BJ,EAAoB5K,WACpE6K,EAAUG,YAAY,sCAAuCJ,EAAoBhL,uBACjFiL,EAAUG,YAAY,kCAAmCJ,EAAoB9L,mBAC7E+L,EAAUG,YACN,wCACU,MAAVjT,OAAU,EAAVA,EAAYgH,wBAAyB6B,GAAwBgK,EAAoB9L,oBAErF+L,EAAUG,YAAY,8BAA+BJ,EAAoB5L,mBACzE6L,EAAUG,YAAY,qCAAsCJ,EAAoB3L,yBAEhF4L,EAAUG,YACN,uCACApK,GAAwBgK,EAAoB3L,0BAGhD4L,EAAUG,YACN,kCACU,MAAVjT,OAAU,EAAVA,EAAYoT,YAAavK,GAAwBgK,EAAoB/L,kBAEzEgM,EAAUG,YAAY,gCAAiCJ,EAAoB9K,iBAC3E+K,EAAUG,YAAY,oBAAqBJ,EAAoBnL,aAC/DoL,EAAUG,YAAY,yBAA0BpK,GAAwBgK,EAAoBnL,cAC5FoL,EAAUG,YAAY,sBAAuBJ,EAAoBlL,QAIjE,IAAM0L,GAAwB,MAAVrT,OAAU,EAAVA,EAAYsI,mBAA6B,MAAVtI,OAAU,EAAVA,EAAYsT,sBAC3DC,EAAeF,GAAeR,EAAoBvK,gBACjD+K,GAAuD,UAAxCR,EAAoB/L,kBACpCyM,EAAe,WAEnBT,EAAUG,YAAY,+BAAgCM,GAEtD,IAAMhL,GAA2B,MAAVvI,OAAU,EAAVA,EAAYuI,iBAAkBM,GAAwB0K,GAC7ET,EAAUG,YAAY,+BAAgC1K,GACtDuK,EAAUG,YAAY,gCAAiC1K,GACvDuK,EAAUG,YAAY,oCAAqCJ,EAAoBrK,qBAC/EsK,EAAUG,YAAY,oCAAqCJ,EAAoBpK,qBAC/EqK,EAAUG,YAAY,4BAA6BJ,EAAoBxK,aAAa,EAiOpFuK,CAA+BF,EAAKvU,EAAOrhB,KAAMqhB,EAAO6B,YACxD0S,EAAIj4B,UAAY03B,EAChB,IAAMK,EAASE,EAAIc,aAAa,CAAEC,KAAM,SAClCC,EA1BH,SAA6BxB,GAChC,IAAMwB,EDtWuBC,EAAC9yB,EAAoB+yB,EAAmB1B,KAAsB,IAAA2B,EAEvFH,EAAsC7yB,EAAS8xB,cAAc,SAOjE,OANAe,EAAWE,k0ZAEA,MAAP1B,GAAe,OAAR2B,EAAP3B,EAAS4B,SAATD,EAAiBE,yCACjBL,EAAaxB,EAAQ4B,OAAOC,uCAAuCL,IAGlEA,IACDnyB,GAAOmB,MAAM,wDACN,KAGM,ECwVEixB,CAAkB9yB,KAAgEqxB,GAErG,OADU,MAAVwB,GAAAA,EAAYM,aAAa,uBAAwB,QAC1CN,CACX,CAsBuBO,CAAoB/B,GACvC,GAAIwB,EAAY,CACZ,IAAMQ,EAAqB1B,EAAOF,cAAc,SAC5C4B,GACA1B,EAAO2B,YAAYD,GAEvB1B,EAAO4B,YAAYV,EACvB,CAEA,OADsB7yB,GAAa,KAAEuzB,YAAY1B,GAC1C,CACHF,SACAC,gBAAgB,EACnB,EAeQ4B,GAAkBvpB,IAQJ,IARKmT,UAC5BA,EAASE,OACTA,EAAMmW,mBACNA,EAAkBpC,QAClBA,EAAOqC,kBACPA,EAAiBC,WACjBA,EAAUC,eACVA,GACkB3pB,EACbonB,GAILvQ,GAA4BxD,GAC5B+T,EAAQ/tB,QAAQ6Y,GAAgBG,KAAI1O,EAAA,CAChC,CAAC4O,GAAsBE,aAAcY,EAAOnmB,KAC5C,CAACqlB,GAAsBC,WAAYa,EAAO9V,GAC1C,CAACgV,GAAsBG,kBAAmBW,EAAOW,kBACjD,CAACzB,GAAsBI,6BAA8BU,EAAOuW,6BAC5D,CAACrX,GAAsBM,sBAAuB2W,EAC9C,CAACjX,GAAsBO,kBAAmB2W,GACtCE,GAAkB,CAAE,CAACpX,GAAsBQ,iBAAkB4W,GAAgB,CACjFE,0BAAqBzC,EAAQ0C,8BAAR1C,EAAQ0C,0BAC1B1W,GAA8BD,EAAWE,GACzCqW,EAAU,CACbK,KAAM,CACF,CAAClW,GAA6BR,EAAQ,eAAe,MAGzDoW,IAEAh0B,GAAOu0B,cAAc,IAAIC,YAAY,eAAgB,CAAEC,OAAQ,CAAEC,SAAU9W,EAAO9V,OAClF6sB,GAA2B/W,KAtB3B5c,GAAOmB,MAAM,gEAuBjB,EAGEyyB,GAA8BA,CAChChX,EACAiX,EACAlD,KAAgBzjB,SAAA,CAEhB,CAAC4O,GAAsBE,aAAcY,EAAOnmB,KAC5C,CAACqlB,GAAsBC,WAAYa,EAAO9V,GAC1C,CAACgV,GAAsBG,kBAAmBW,EAAOW,kBACjD,CAACzB,GAAsBI,6BAA8BU,EAAOuW,6BAC5D,CAACrX,GAAsBK,6BR1aCO,EQ0a+D,MAAhBmX,OAAgB,EAAhBA,EAAkBnX,eR1axD,IAATA,IAAAA,EAAY,CAAA,GAC7B5lB,OAAO6sB,OAAOjH,GAAW7S,MAAM+K,IAAYlc,GAAUkc,QQ0axC,MAAhBif,OAAgB,EAAhBA,EAAkBX,iBAAkB,CACpC,CAACpX,GAAsBQ,iBAAkBuX,EAAiBX,gBAC7D,CACDE,0BAAqBzC,EAAQ0C,8BAAR1C,EAAQ0C,yBAC7B,CAACvX,GAAsBM,sBAAuC,MAAhByX,OAAgB,EAAhBA,EAAkBd,oBAC7DpW,GAA8C,MAAhBkX,OAAgB,EAAhBA,EAAkBnX,UAAWE,IRhblE,IAA4BF,CQib1B,EAEWoX,GAAuBA,CAChClX,EACA+T,EACAoD,EACAb,KAEA,GAAKvC,GAIL,IAAIoD,EAAJ,CAIA,IAAMF,EAAmBG,GAAyBpX,GAClD+T,EAAQ/tB,QAAQ6Y,GAAgBE,UAASzO,EAAA,CAAA,EAClC0mB,GAA4BhX,EAAQiX,EAAkBlD,GACrDuC,GAAkB,CAAE,CAACpX,GAAsBQ,iBAAkB4W,GAAgB,CACjFI,KAAM,CACF,CAAClW,GAA6BR,EAAQ,eAAe,MAG7D+W,GAA2B/W,GAC3BwD,GAA4BxD,GAC5B5d,GAAOu0B,cAAc,IAAIC,YAAY,iBAAkB,CAAEC,OAAQ,CAAEC,SAAU9W,EAAO9V,MAZpF,OALI9G,GAAOmB,MAAM,qEAiB2E,EAGnF8yB,GAA2BA,CAACrX,EAAgB+T,KACrD,GAAKA,EAAL,CAKA,IAAMuD,ENnd4BtX,IAC3BsD,GAf4B,mBAeiBtD,GMkd/BuX,CAAsBvX,GAC3C,IACI,GAA2C,SAAvC0D,aAAaC,QAAQ2T,GACrB,MAER,CAAE,MAAA/8B,GAEE,MACJ,CAEA,IAAM08B,EAAmBG,GAAyBpX,GAClD,GAAKiX,EAAL,CAIA,IACIvT,aAAaE,QAAQ0T,EAAc,OACvC,CAAE,MAAAhqB,GACE,CAGJymB,EAAQ/tB,QAAQ6Y,GAAgBI,UAAW+X,GAA4BhX,EAAQiX,EAAkBlD,GAAU,CACvGyD,UAAW,cATf,CAfA,MAFIp0B,GAAOmB,MAAM,qEA2Bf,EAKOkzB,GAAWjpB,GACbA,EACF+R,KAAKnG,IAAC,CAAQrY,KAAMiO,KAAKC,MAAsB,GAAhBD,KAAKiW,UAAgB3rB,MAAO8f,MAC3DrY,MAAK,CAACqY,EAAGwZ,IAAMxZ,EAAErY,KAAO6xB,EAAE7xB,OAC1Bwe,KAAKnG,GAAMA,EAAE9f,QAGhBo9B,GAAsBA,CAACC,EAAmBC,IACxCD,EAAWr4B,SAAWs4B,EAASt4B,QAAUq4B,EAAWvc,OAAM,CAAC/V,EAAKwyB,IAAUxyB,IAAQuyB,EAASC,KACpFD,EAASE,UAGbF,EAyBEG,GAA4B/X,GAChCA,EAAO6B,YAAe7B,EAAO6B,WAAWmI,mBAAoBhK,EAAOgY,yBAIjEN,GAAoB1X,EAAOE,UAAWuX,GAAQzX,EAAOE,YAHjDF,EAAOE,UAUT+X,GACTjY,IACU,IAAAkY,EACV,QACwB,OAAjBA,EAAAlY,EAAOmY,aAAkB,OAARD,EAAjBA,EAAmBE,UAAnBF,EAA2BG,qBARZrY,KAAgD,IAAAsY,EAAAC,EACtE,OAAoDl2B,OAA5B,OAAjBi2B,EAAAtY,EAAOmY,aAAkB,OAARG,EAAjBA,EAAmBF,SAAc,OAARE,EAAzBA,EAA2BvR,aAAM,EAAjCuR,EAAmCh5B,UAAwC,OAAjBi5B,EAAAvY,EAAOmY,oBAAUI,EAAjBA,EAAmBH,gBAAMG,EAAzBA,EAA2BxR,eAA3BwR,EAAmCj5B,QAAS,CAAC,EAOtDk5B,CAAUxY,KAC9DA,EAAOyY,WAAa7Z,IACpB8Z,GAAmB1Y,EAAO,EAyCrB2Y,iLXlmBO,2WWkmBSC,CAAkC,CAC3DC,eAAe,EACfC,iBAAkB,EAClBC,sBAA+B,GAAPA,EACxBC,SAAS,EACTC,eAAwB,GAAPA,EACjBC,aAAsB,GAAPA,EACf/C,mBAAoB,GACpBE,gBAAYh0B,EACZi0B,eAAgB,OAGP6C,GAAmBA,IACrBC,GAAWT,IAUTU,GAA6BnqB,IAA+D,IAA9DoqB,UAAEA,EAASC,SAAEA,EAAQC,aAAEA,EAAY5E,MAAEA,GAAoB1lB,EAChG,wKXznBqB,kIADL,MW2nBVuqB,CAAaH,EADZE,EACuB,CACpBE,wBAAyB,CAAEC,OAAQJ,GACnC3E,SAEoB,CACpB2E,WACA3E,SACF,EAQL,SAASgF,GAAmB5Z,EAAoC+T,GAA4B,IAAA8F,EAAAC,EAC/F,GAAsB,OAAlBD,EAAC7Z,EAAOmY,cAAP0B,EAAmBz7B,IACpB,OAAO,EAGX,ICrnB4B27B,EAAmDC,EACzEC,EDonBAC,GCrnBsBH,EDqnBChG,ECpnBvBkG,EAAmB,MAAN73B,IAAgB,OAAV43B,EAAN53B,GAAQ+3B,eAAQ,EAAhBH,EAAkBE,KAC9Bv+B,GAAYs+B,QAAc53B,EA/B9B,SAAmC03B,EAA+BE,GAA4B,IAAAG,EAC3FC,EAAmB,MAARN,GAAgB,OAARK,EAARL,EAAUpE,aAAM,EAAhByE,EAAkBE,gBACnC,IAAK9+B,GAAW6+B,GACZ,OAAOJ,EAGX,IACI,IAAMv6B,EAAS26B,EAASJ,GACxB,OAAOr+B,GAAS8D,IAAWA,EAASA,EAASu6B,CACjD,CAAE,MAAOhvB,GAEL,OADA7H,GAAOmB,MAAM,iEAAkE0G,GACxEgvB,CACX,CACJ,CAkBiDM,CAA0BR,EAAUE,IDonBjF,IAAKC,EAED,OAAO,EAEX,IAAMpT,EAAU,CAAC9G,EAAOmY,WAAW/5B,KAC7Bo8B,EAhBV,SAA0BA,GACtB,OAAOA,QAAAA,EAAa,WACxB,CAcsBC,CAAkC,OAAlBX,EAAC9Z,EAAOmY,iBAAU,EAAjB2B,EAAmBY,cACtD,OAAO9T,GAAoB4T,GAAW1T,EAAS,CAACoT,GACpD,CAEO,SAASS,GAA2B3a,GAAyB,IAAA4a,EAAAC,EAChE,OErqBG,SAA6BC,EAAwBN,GAAwC,IAAAO,EAAAC,EAAAC,EAChG,IAAKH,GAAsC,IAAvBA,EAAYx7B,OAC5B,OAAO,EAEX,IAAKsD,GACD,OAAO,EAEX,ItCgX0CqC,EAASi2B,EAMqCC,EAAAC,EAAAC,EALlFC,EsCjXAC,GtCgXoCt2B,EsChXK,CAE3Cu2B,sBAAgC,MAAT/4B,IAAwB,OAAfs4B,EAATt4B,GAAWg5B,oBAAa,EAAxBV,EAA0B76B,SACjDw7B,eAAyB,MAATj5B,QAAS,EAATA,GAAWi5B,eAC3BC,YAAmB,MAANv5B,IAAc,OAAR44B,EAAN54B,GAAQw5B,aAAM,EAAdZ,EAAgBa,MAC7BC,aAAoB,MAAN15B,IAAc,OAAR64B,EAAN74B,GAAQw5B,aAAM,EAAdX,EAAgBc,OAC9BC,iBAAwB,MAAN55B,QAAM,EAANA,GAAQ45B,mBtC2WxBV,EAxBW,SAASW,GAC1B,OAAIh+B,GAAekM,KAAK8xB,GAAoB9+B,GACxCa,GAAkBmM,KAAK8xB,GAAoB7+B,GAC3CU,GAAWqM,KAAK8xB,GAAoB5+B,GACpC,IAAIU,OAAON,GAAM,KAAK0M,KAAK8xB,GAAoBx+B,GAC/C,IAAIM,OAAO,IAAMT,GAAgB,cAAe,KAAK6M,KAAK8xB,GAAoB3+B,GACzE,OAAO6M,KAAK8xB,GAAoBl/B,GAChC,OAAOoN,KAAK8xB,GAAoB,aAChC,SAAS9xB,KAAK8xB,GAAoB,SAClC,qCAAqC9xB,KAAK8xB,GAAoBj/B,GAC9DkB,GAAiBiM,KAAK8xB,GAAoB/+B,GAC1C,2BAA2BiN,KAAK8xB,GAAoB,OACpD,IAAIl+B,OAAOP,GAAO,KAAK2M,KAAK8xB,GAAoBz+B,GAChD,uCAAuC2M,KAAK8xB,IAAe,+BAA+B9xB,KAAK8xB,GAAoB,cACnH,iBAAiB9xB,KAAK8xB,GAAoB,IAAIl+B,OAAOpB,IAAQwN,KAAK8xB,KAAe,4EAA4E9xB,KAAK8xB,IAEnK,sBAAsB9xB,KAAK8xB,KAAgB,WAAW9xB,KAAK8xB,IAAe,oDAAoD9xB,KAAK8xB,IAAe,UAAU9xB,KAAK8xB,KAAgB,UAAU9xB,KAAK8xB,GAFRr/B,GAGrLE,GAEF,IAAIiB,OAAO,QAAUpB,GAAS,IAAK,KAAKwN,KAAK8xB,GAAoBt+B,GACjE,IAAII,OAAOlB,GAAQ,KAAKsN,KAAK8xB,KAAgB,IAAIl+B,OAAOlB,GAAS,MAAO,KAAKsN,KAAK8xB,GAAoBp+B,GACnG,EAChB,CAEmBq+B,CsCjXqBt5B,OtCkXrB7F,IAAQu+B,IAAWx+B,IAAkB,SAAWw+B,GAAU,gBAAkBA,GAAUA,IAAWz9B,GAAuBhB,GACnIy+B,IAAWn+B,IAAYm+B,IAAWj+B,IAAQi+B,IAAWl+B,IAAek+B,IAAW79B,GAAa,UAC5F69B,IAAWt+B,GAAoB,WAC/Bs+B,EAAe3+B,GACoB,aAA5B,MAAPsI,OAAO,EAAPA,EAASu2B,yBAA+D,QAAxBN,EAAQ,MAAPj2B,OAAO,EAAPA,EAASy2B,sBAAc,IAAAR,EAAAA,EAAI,GAAK,EAG3D,IAFJlrB,KAAKsC,YAAG6oB,EAAQ,MAAPl2B,OAAO,EAAPA,EAAS02B,mBAAW,IAAAR,EAAAA,EAAI,UAACC,EAAS,MAAPn2B,OAAO,EAAPA,EAAS62B,oBAAY,IAAAV,EAAAA,EAAI,IACrB,QAA7BC,EAAW,MAAPp2B,OAAO,EAAPA,EAAS+2B,4BAAgBX,EAAAA,EAAI,GACzB1+B,GAATE,GAEzB,WsCnXP,OAAO+pB,GAAoB4T,QAAAA,EAAa,aAAaM,EAAa,CAACS,GACvE,CFqpBWY,QAAmBvB,EAAC5a,EAAOmY,mBAAPyC,EAAmBE,YAA8B,OAAnBD,EAAE7a,EAAOmY,iBAAU,EAAjB0C,EAAmBuB,qBAClF,CAmBA,IAAMC,GAA+Brc,IACjC,IAAI1a,EAAG,GAAM+d,GAA4BrD,EAAO9V,GAIhD,OAHI8V,EAAOW,mBAAqBX,EAAOW,kBAAoB,IACvDrb,EAAG,GAAM+d,GAA4BrD,EAAO9V,GAAE,IAAI8V,EAAOW,mBAEtDrb,CAAG,EAGDg3B,GAA2BA,CACpCtc,EACAuc,KAEA,IACI7Y,aAAaE,QAAQyY,GAA4Brc,GAAS5Q,KAAKC,UAAUktB,GAC7E,CAAE,MAAOtxB,GACL7H,GAAOmB,MAAM,yDAA0D0G,EAC3E,GAGSmsB,GACTpX,IAEA,IACI,IAAMwc,EAAc9Y,aAAaC,QAAQ0Y,GAA4Brc,IACrE,GAAIwc,EACA,OAAOptB,KAAKgZ,MAAMoU,EAE1B,CAAE,MAAOvxB,GACL7H,GAAOmB,MAAM,2DAA4D0G,EAC7E,CACA,OAAO,IAAI,EAGFytB,GAAsB1Y,IAC/B,IAAMuc,EAAQnF,GAAyBpX,GACvC,OAAQlkB,SAAUygC,SAAAA,EAAOpG,mBAAmB,EAGnCY,GAA8B/W,IACvC,IACI0D,aAAa2E,WAAWgU,GAA4Brc,GACxD,CAAE,MAAO/U,GACL7H,GAAOmB,MAAM,4DAA6D0G,EAC9E,GAGG,SAASgpB,GAAwBjU,EAA4Byc,QAAU,IAAVA,IAAAA,GAAa,GAC7E,IAAMngC,EAAS,iBAAoB0jB,EAAO9V,GAC1C,OAAOuyB,EAAU,IAAOngC,EAAcA,CAC1C,CAMO,SAASogC,GACZ/9B,EACAyqB,EACAuT,GAEA,QAHwB,IAAxBvT,IAAAA,EAA2BrM,GAAeS,OAGtC7e,IAASkf,GAAWI,eACpB,MAAO,CAAA,EAGX,OAAQmL,GACJ,KAAKrM,GAAeC,QAChB,MAAO,CAAE4f,IAAK,IAAKC,KAAM,IAAKC,UAAW,yBAC7C,KAAK/f,GAAeE,SAChB,MAAO,CAAE2f,IAAK,IAAKG,MAAO,IAAKD,UAAW,0BAC9C,KAAK/f,GAAeG,UAChB,MAAO,CAAE0f,IAAK,IAAKC,KAAM,MAAOC,UAAW,yBAC/C,KAAK/f,GAAeI,WAChB,MAAO,CAAEyf,IAAK,MAAOC,KAAM,IAAKC,UAAW,yBAC/C,KAAK/f,GAAeK,YAChB,MAAO,CAAEwf,IAAK,MAAOG,MAAO,IAAKD,UAAW,0BAChD,KAAK/f,GAAeM,aAChB,MAAO,CAAEuf,IAAK,MAAOC,KAAM,MAAOC,UAAW,yBACjD,KAAK/f,GAAeO,KAChB,MAAO,CAAEuf,KAAM,QACnB,KAAK9f,GAAeQ,OAChB,MAAO,CAAEsf,KAAM,MAAOC,UAAW,oBACrC,QAEI,MAAO,CAAEC,MAAOp+B,IAASkf,GAAWG,QAAU2e,IAAqB/f,GAAiBC,IAAM,OAAS,QAE/G,0WGnxBO,IAAMmgB,GACTC,GAAA,MAAA,CAAK3gC,UAAU,YAAY4gC,MAAM,6BAA6BnB,OAAO,KAAKoB,QAAQ,iBAAiBtB,MAAM,KAAItC,SACzG0D,GAAA,OAAA,CAAMvjB,EAAE,ksBAGH0jB,GACTH,GAAA,MAAA,CAAK3gC,UAAU,YAAY4gC,MAAM,6BAA6BnB,OAAO,KAAKoB,QAAQ,iBAAiBtB,MAAM,KAAItC,SACzG0D,GAAA,OAAA,CAAMvjB,EAAE,4mBAGH2jB,GACTJ,GAAA,MAAA,CAAK3gC,UAAU,YAAY4gC,MAAM,6BAA6BnB,OAAO,KAAKoB,QAAQ,iBAAiBtB,MAAM,KAAItC,SACzG0D,GAAA,OAAA,CAAMvjB,EAAE,2tBAGH4jB,GACTL,GAAA,MAAA,CAAK3gC,UAAU,YAAY4gC,MAAM,6BAA6BnB,OAAO,KAAKoB,QAAQ,iBAAiBtB,MAAM,KAAItC,SACzG0D,GAAA,OAAA,CAAMvjB,EAAE,igBAGH6jB,GACTN,GAAA,MAAA,CAAK3gC,UAAU,YAAY4gC,MAAM,6BAA6BnB,OAAO,KAAKoB,QAAQ,iBAAiBtB,MAAM,KAAItC,SACzG0D,GAAA,OAAA,CAAMvjB,EAAE,u0BAGH8jB,GACTP,GAAA,MAAA,CAAK3gC,UAAU,YAAY4gC,MAAM,6BAA6BnB,OAAO,KAAKoB,QAAQ,YAAYtB,MAAM,KAAItC,SACpG0D,GAAA,OAAA,CAAMvjB,EAAE,iRAGH+jB,GACTR,GAAA,MAAA,CAAK3gC,UAAU,YAAY4gC,MAAM,6BAA6BnB,OAAO,KAAKoB,QAAQ,YAAYtB,MAAM,KAAItC,SACpG0D,GAAA,OAAA,CAAMvjB,EAAE,yQAGHgkB,GAAY,SAAAx6B,GAAA,IAACy6B,KAAEA,EAAO,qBAAmC,IAAAz6B,EAAG,CAAA,EAAEA,EAAA,OACvE06B,GAAA,MAAA,CACI/B,MAAM,KACNE,OAAO,KACPoB,QAAQ,YACRQ,KAAMA,EACNT,MAAM,6BACN,kBAAgB,0BAAyB3D,UAEzC0D,GAAA,QAAA,CAAO/yB,GAAG,qBAAqB5N,UAAU,eAAci9B,SAAC,iBAGxD0D,GAAA,OAAA,CACI,YAAU,UACV,YAAU,UACVvjB,EAAE,0iBACFikB,KAAMA,MAER,EAEGE,GACTD,GAAA,MAAA,CAAK/B,MAAM,KAAKE,OAAO,KAAKoB,QAAQ,YAAYQ,KAAK,OAAOT,MAAM,6BAA4B3D,UAC1FqE,GAAA,IAAA,CAAG,YAAU,wBAAuBrE,UAChC0D,GAAA,OAAA,CACI/yB,GAAG,kBACH0qB,MAAO,CAAEkJ,SAAU,aACnBC,UAAU,iBACVtiC,EAAE,IACFigB,EAAE,IACFmgB,MAAM,KACNE,OAAO,KAAIxC,SAEX0D,GAAA,OAAA,CAAMvjB,EAAE,wBAAwBikB,KAAK,YAEzCC,GAAA,IAAA,CAAGI,KAAK,wBAAuBzE,UAC3B0D,GAAA,OAAA,CACIvjB,EAAE,uhBACFikB,KAAK,YAETV,GAAA,OAAA,CACIvjB,EAAE,spCACFikB,KAAK,YAETV,GAAA,OAAA,CACIvjB,EAAE,ofACFikB,KAAK,iBAETV,GAAA,OAAA,CACIvjB,EAAE,oeACFikB,KAAK,YAETV,GAAA,OAAA,CACIvjB,EAAE,mdACFikB,KAAK,YAETV,GAAA,OAAA,CACIvjB,EAAE,yoFACFikB,KAAK,uBAIjBV,GAAA,OAAA,CAAA1D,SACI0D,GAAA,WAAA,CAAU/yB,GAAG,kBAAiBqvB,SAC1B0D,GAAA,OAAA,CAAMpB,MAAM,KAAKE,OAAO,KAAK4B,KAAK,QAAQb,UAAU,0BC5F7D,SAASmB,GAAWtxB,GAAkC,IAAjCuxB,UAAEA,GAA6BvxB,EAEjDwxB,EAAcD,EACdhkC,OAAOuL,QAAQy4B,GACV3d,KAAIrR,IAAA,IAAE5J,EAAKhL,GAAM4U,EAAA,OAAQ1I,mBAAmBlB,OAAQkB,mBAAmBlM,EAAM,IAC7E4H,KAAK,KACV,GAEN,OACI07B,GAAA,IAAA,CACI1D,oCAAoCiE,EAAW,IAAOA,EAAgB,IACtEvzB,OAAO,SACPwzB,IAAI,WACJ9hC,UAAU,kBAAiBi9B,SAAA,CAC9B,aACcsE,KAGvB,CChBO,SAASQ,GAAa1xB,GAoB1B,IApB2B9B,KAC1BA,EAAIyzB,eACJA,EAAczc,WACdA,EAAU0c,SACVA,EAAQ5b,KACRA,EAAIsW,gBACJA,EAAeuF,iBACfA,EAAgBC,UAChBA,EAASC,OACTA,GAWH/xB,GACSksB,cAAEA,GAAkBO,GAAWT,IAC/BgG,IAAmBF,KAAeC,EAClCE,GAAgBJ,GAClBvB,GAAA,SAAA,CACI3gC,UAAU,cACVuiC,SAAUP,EACV,aAAW,gBACX3/B,KAAK,SACLmgC,OASA,GARQnc,UACAvgB,IAAAA,GAAQ28B,KAAKpc,IAEbkW,EACe,MAAfI,GAAAA,IAEAsF,GACJ,EACFhF,SAED1uB,IAGT,OACI+yB,GAAA,MAAA,CAAKthC,UAAU,iBAAgBi9B,SAAA,CAC1BoF,EACGf,GAAA,MAAA,CAAKthC,UAAU,sCAAqCi9B,UAChD0D,GAAA,SAAA,CAAQ3gC,UAAU,YAAYqC,KAAK,SAAS,aAAW,0BAA0BmgC,QAASJ,EAAOnF,SAC5F1X,EAAWK,gBAAkB,SAEjC0c,KAGLA,GAEF/c,EAAWqH,YAAc+T,GAACgB,GAAW,CAACC,UAAW,CAAEc,WAAY,qBAG7E,CC5DO,SAASC,GAActyB,GAQ3B,IAR4BwT,SAC3BA,EAAQ+e,iBACRA,EAAgBC,QAChBA,GAKHxyB,EAKG,OACIixB,GAAA,MAAA,CAAKwB,MAFcjf,EAASA,UAAaA,EAASsC,YAEqB,kBAA3C,yCAA6D8W,SAAA,CACrF0D,GANe9c,EAASxhB,OAASuf,GAAmBC,KAAO,QAAU,KAMtD,CAAC7hB,UAAU,kBAAkB6iC,QAASA,EAAQ5F,SACxDpZ,EAASA,WAEbA,EAASsC,aACN4W,GAA2B,CACvBC,UAAW7d,GAAE,IAAK,CAAEnf,UAAW,gCAC/Bi9B,SAAUpZ,EAASsC,YACnB+W,cAAe0F,GAAwD,SAApC/e,EAASkf,2BAIhE,CAEO,SAASC,GAAMpwB,GAAuC,IAAtC4vB,QAAEA,GAAkC5vB,GACjD2pB,cAAEA,GAAkBO,GAAWT,IAErC,OACIsE,GAAA,SAAA,CACI3gC,UAAU,cACVwiC,QAASA,EACTD,SAAUhG,EACV,aAAW,eACXl6B,KAAK,SAAQ46B,SAEZmE,GAAU,CAAEC,KAAM,WAG/B,CHwDIV,GAAA,MAAA,CAAKpB,MAAM,KAAKE,OAAO,KAAKoB,QAAQ,YAAYQ,KAAK,OAAOT,MAAM,6BAA4B3D,SAC1F0D,GAAA,OAAA,CACIvjB,EAAE,2jBACFikB,KAAK,mBI/FjB,IAAMv7B,GAASkmB,GAER,SAASiX,GAAmB5yB,GAchC,IAdiC2K,OAChCA,EAAMmL,YACNA,EAAWzV,YACXA,EAAWkyB,iBACXA,EAAgBrd,WAChBA,EAAU2d,QACVA,GAQH7yB,GACSqsB,QAAEA,GAAYI,GAAWT,IAiB/B,OAfA8G,IAAU,KACN,IAAMC,EAAiB55B,IACD,UAAdA,EAAMR,KAAiC,WAAdQ,EAAMR,MAC/BQ,EAAM65B,iBACNH,IACJ,EAGJ,OADA55B,GAAiBxD,GAAQ,UAAWs9B,GAC7B,KACHt9B,GAAOsV,oBAAoB,UAAWgoB,EAAc,CACvD,GACF,CAACF,IAKA5B,GAAA,MAAA,CAAKthC,UAAU,oBAAoBsjC,KAAK,SAASC,SAAU,EAAG,cAAY,OAAMtG,SAAA,CAHzDP,IAA2C,IAAhCnX,EAAWie,kBAIlB7C,GAACqC,GAAM,CAACR,QAASA,IAAMU,MAC9CvC,GAAA,KAAA,CAAI3gC,UAAU,2BAA0Bi9B,SAAEjiB,IACzCmL,GACG4W,GAA2B,CACvBC,UAAW7d,GAAE,IAAK,CAAEnf,UAAW,2BAC/Bi9B,SAAU9W,EACV+W,cAAe0F,GAAoC,SAAhBlyB,IAE1CgsB,GACGiE,GAACoB,GAAa,CACVxzB,KAAMgX,EAAWG,gCAAkC,QACnDsc,gBAAgB,EAChBzc,WAAYA,EACZ0c,SAAUA,IAAMiB,QAKpC,CCzBA,IAAMO,GAAsBzlC,GACjBc,GAAQd,IAAUA,EAAM8gB,OAAO4kB,GAASpkC,GAASokC,KAyCrD,SAASC,GAAgBtzB,GAY7B,IAZ8BwT,SAC7BA,EAAQ+e,iBACRA,EAAgBrd,WAChBA,EAAU0c,SACVA,EAAQtF,gBACRA,EAAeiH,qBACfA,EAAoBC,aACpBA,EAAY1B,UACZA,EAASC,OACTA,GAGH/xB,GACSksB,cAAEA,GAAkBM,KACpBiH,EAAWC,GAA4B,OACtCx1B,EAAMy1B,GAAWC,IAAiB,IACjC3kC,GAASukC,GACFA,EAEJ,KAEXV,IAAU,KACNzwB,YAAW,KACa,IAAAwxB,EAAf3H,UACD2H,EAAAJ,EAASrkB,UAATykB,EAAkBC,OACtB,GACD,IAAI,GACR,CAAC5H,IAEJ,IAAMsG,mBAA2Be,EAG3BQ,EAAkBC,IAAQ,IzClHpC,SAA4BrmC,EAAOoE,EAAOkiC,GAAU,IAAAC,EAAAC,EAC1CC,EAAUzmC,EAAMQ,OACtB,IAAK8lC,GAAY,KAAOG,EAAS,MAAO,yBACxC,GAAI,KAAOA,EAAS,OAAO,EAC3B,GAAIriC,GAASA,EAAMY,OAAS,EAAG,IAAK,IAAMV,KAAQF,EAAM,OAAOE,EAAKD,MAChE,KAAKlE,GAAqBumC,UACtB,QAAI,IAAWpiC,EAAKtE,OAA0BsE,EAAKtE,MAAtBymC,EAAQzhC,OAAqB,OAAwB,QAAxBuhC,EAAOjiC,EAAKqiC,oBAAY,IAAAJ,EAAAA,EAAA,yBAA6BjiC,EAAKtE,MAAK,cACzH,MACJ,KAAKG,GAAqBymC,UACtB,QAAI,IAAWtiC,EAAKtE,OAASymC,EAAQzhC,OAASV,EAAKtE,MAAO,OAAwB,QAAxBwmC,EAAOliC,EAAKqiC,oBAAY,IAAAH,EAAAA,EAAA,6BAAiCliC,EAAKtE,MAAK,cAGrI,OAAO,CACX,CyCsGe6mC,CAAmBt2B,EAAMsV,EAASihB,WAAYjhB,EAASygB,WAC/D,CAAC/1B,EAAMsV,EAASihB,WAAYjhB,EAASygB,WAGlCS,EAAY5iC,GAAmB0hB,EAASihB,WAAY3mC,GAAqBumC,WACzEl/B,EAAYrD,GAAmB0hB,EAASihB,WAAY3mC,GAAqBymC,WACzEI,EAAmBX,IAAQ,IzCtGrC,SAA6BU,EAAWv/B,GACpC,IAAMy/B,EAAe,IAAMF,OAAY,EAASA,EAChD,OAAIE,GAAgBz/B,EAAW,SAAgBy/B,MAAgBz/B,EAAS,cACpEy/B,EAEA,kBAAyBA,OADV,IAAMA,EAAe,YAAc,cAGlDz/B,EAEA,WAAkBA,OADH,IAAMA,EAAY,YAAc,mBADnD,CAIJ,CyC2F2C0/B,CAAoBH,EAAWv/B,IAAY,CAACu/B,EAAWv/B,IAExF2/B,EAAeA,KACbf,GAGJnC,EAAS1zB,EAAK/P,OAAO,EAGnB4mC,EAAsBA,KACpBhB,GAGJzH,EAAgBpuB,EAAK/P,OAAO,EAGhC,OACI8iC,GAAC+D,GAAQ,CAAApI,UACLqE,GAAA,MAAA,CAAKthC,UAAU,qBAAoBi9B,SAAA,CAC/B0D,GAACgC,GAAc,CAAC9e,SAAUA,EAAU+e,iBAAkBA,EAAkBC,QAASA,IACjFlC,GAAA,WAAA,CACI2E,IAAKxB,EACLl2B,GAAIi1B,EACJ0C,KAAM,EACN5Y,YAAuB,MAAVpH,OAAU,EAAVA,EAAYoH,YACzBoY,UAAWA,EACXv/B,UAAWA,EACXggC,OAGA,CAHU72B,GACNq1B,EAAQr1B,EAAE82B,cAAcznC,OACxB2Q,EAAE+2B,iBAAiB,EAEvBC,SAMA,CANYh3B,GACRA,EAAE+2B,kBACY,UAAV/2B,EAAE3F,MAAoB2F,EAAEi3B,UAAWj3B,EAAEk3B,SAAazB,IAClDz1B,EAAE00B,iBACF9G,EAAgB6I,IAAwBD,IAC5C,EAEJnnC,MAAOuQ,IAEVy2B,GAAoBrE,GAAA,MAAA,CAAK3gC,UAAU,kBAAiBi9B,SAAE+H,OAE3DrE,GAACoB,GAAa,CACVxzB,KAAMsV,EAASuC,YAAc,SAC7B4b,iBAAkBoC,EAClB7e,WAAYA,EACZ0c,SAAUkD,EACVxI,gBAAiByI,EACjBjD,UAAWA,EACXC,OAAQA,MAIxB,CAEO,SAAS0D,GAAYlzB,GAUzB,IAV0BiR,SACzBA,EAAQ+e,iBACRA,EAAgBrd,WAChBA,EAAU0c,SACVA,EAAQtF,gBACRA,EAAewF,UACfA,EAASC,OACTA,GAGHxvB,EACG,OACI0uB,GAAC+D,GAAQ,CAAApI,UACL0D,GAAA,MAAA,CAAK3gC,UAAU,qBAAoBi9B,SAC/B0D,GAACgC,GAAc,CAAC9e,SAAUA,EAAU+e,iBAAkBA,MAE1DjC,GAACoB,GAAa,CACVxzB,KAAMsV,EAASuC,YAAc,SAC7B4b,gBAAgB,EAChB3b,KAAMxC,EAASwC,KACfd,WAAYA,EACZ0c,SAAUA,IAAMA,EAAS,gBACzBtF,gBAAiBA,IAAMA,EAAgB,gBACvCwF,UAAWA,EACXC,OAAQA,MAIxB,CAEO,SAAS2D,GAAc5yB,GAY3B,IAAA6yB,GAZ4BniB,SAC3BA,EAAQ+e,iBACRA,EAAgBgB,qBAChBA,EAAoBre,WACpBA,EAAU0c,SACVA,EAAQtF,gBACRA,EAAekH,aACfA,EAAY1B,UACZA,EAASC,OACTA,GAGHjvB,EACS8yB,EAAQpiB,EAASoiB,MACjBC,EAA8B,KAAnBriB,EAASoiB,MAAe,EAAI,GACtCE,EAAQC,GAAanC,IAAwB,IAC5CxkC,GAASokC,GACFA,EAEP/kC,GAAQ+kC,IAAiBA,EAAa7gC,OAAS,GAAKvD,GAAS6W,SAASutB,EAAa,KAC5EvtB,SAASutB,EAAa,IAE7BvkC,GAASukC,IAAiBpkC,GAAS6W,SAASutB,IACrCvtB,SAASutB,GAEb,OAGLwC,EAAqC,UAArBxiB,EAASyiB,SAA0C,IAAnBziB,EAASoiB,OAEzD1J,cAAEA,GAAkBM,KAEpBsI,EAAgBoB,GACdhK,EACOI,EAAgB4J,GAEpBtE,EAASsE,GAGpB,OACIjF,GAAC+D,GAAQ,CAAApI,UACLqE,GAAA,MAAA,CAAKthC,UAAU,qBAAoBi9B,SAAA,CAC/B0D,GAACgC,GAAc,CAAC9e,SAAUA,EAAU+e,iBAAkBA,IACtDtB,GAAA,MAAA,CAAKthC,UAAU,iBAAgBi9B,UAC3BqE,GAAA,MAAA,CAAKthC,UAAU,iBAAgBi9B,UACL,UAArBpZ,EAASyiB,SACN3F,GAAA,MAAA,CAAK3gC,kCAAkCqmC,EAAgB,0BAA4B,IAAKpJ,SACpD,OADoD+I,EACnFQ,GAAgB3iB,EAASoiB,aAAM,EAA/BD,EAAiC/hB,KAAI,CAACwiB,EAAOC,IAGtC/F,GAAA,SAAA,CACI,aAAA,SAAoB+F,EAAM,GAC1B1mC,UAAS,0BAA4B4jC,EAAoB,WAAW8C,EAAG,KAJhEA,EAAM,IAAMP,EAKN,gBAAkB,IAE/BnoC,MAAO0oC,EAAM,EAEbrkC,KAAK,SACLmgC,OAMA,GALI,IAAM9mB,EAAWgrB,EAAM,EACvBN,EAAU1qB,GACNmI,EAASqe,kBACTiD,EAAazpB,EACjB,EACFuhB,SAEDwJ,GAVIC,OAgBH,WAArB7iB,EAASyiB,SACN3F,GAAA,MAAA,CACI3gC,UAAU,wBACVs4B,MAAO,CAAEqO,oBAAmB,WAAYV,EAAQC,EAAW,GAAC,qBAAsBjJ,SAEjF2J,GAAgB/iB,EAASoiB,OAAOhiB,KAAI,CAAC4iB,EAAQH,IAGtC/F,GAACmG,GAAY,CAETlD,qBAAsBA,EACtBmD,OALOZ,IAAWU,EAMlBthB,WAAYA,EACZghB,IAAKM,EACLG,eAKA,CALkBtrB,GACd0qB,EAAU1qB,GACNmI,EAASqe,kBACTiD,EAAazpB,EACjB,GATCgrB,WAiB3BL,GACE/E,GAAA,MAAA,CAAKthC,UAAU,cAAai9B,UACxB0D,GAAA,MAAA,CAAA1D,SAAMpZ,EAASyC,kBACfqa,GAAA,MAAA,CAAA1D,SAAMpZ,EAAS0C,2BAK/Boa,GAACoB,GAAa,CACVxzB,KAAMsV,EAASuC,aAAwB,MAAVb,OAAU,EAAVA,EAAYI,mBAAoB,SAC7Dqc,eAAgBziC,GAAO4mC,KAAYtiB,EAASygB,SAC5C/e,WAAYA,EACZ0c,SAAUA,IAAMA,EAASkE,GACzBxJ,gBAAiBA,IAAMA,EAAgBwJ,GACvCjE,iBAAkBre,EAASqe,iBAC3BC,UAAWA,EACXC,OAAQA,MAIxB,CAEO,SAAS0E,GAAYpuB,GAWzB,IAX0B6tB,IACzBA,EAAGQ,OACHA,EAAMnD,qBACNA,EAAoBoD,gBACpBA,GAOHtuB,EACG,OACIioB,GAAA,SAAA,CACI,aAAA,QAAoB4F,EACpBvmC,UAAS,2BAA6B4jC,EAAoB,WAAW2C,EAAG,KAAIQ,EAAS,gBAAkB,IACvG1kC,KAAK,SACLmgC,OAEA,GADIwE,EAAgBT,EAAI,EACtBtJ,SAEDsJ,GAGb,CAEO,SAASU,GAAsBzvB,GAYnC,IAZoCqM,SACnCA,EAAQ+e,iBACRA,EAAgBgB,qBAChBA,EAAoBre,WACpBA,EAAU0c,SACVA,EAAQtF,gBACRA,EAAekH,aACfA,EAAY1B,UACZA,EAASC,OACTA,GAGH5qB,EACS0vB,EAAqBnD,GAAyB,MAC9Cvd,EAAU6d,IAAQ,IRkLWxgB,KACnC,IAAKA,EAASsjB,eACV,OAAOtjB,EAAS2C,QAGpB,IAAM4gB,EAAsBvjB,EAAS2C,QACjC6gB,EAAkB,GAClBxjB,EAASyjB,gBAETD,EAAkBD,EAAoBG,OAG1C,IAAMC,EAAkBpM,GAAoBgM,EAAqBjM,GAAQiM,IAOzE,OALIvjB,EAASyjB,gBACTzjB,EAAS2C,QAAQjZ,KAAK85B,GACtBG,EAAgBj6B,KAAK85B,IAGlBG,CAAe,EQrMQC,CAAuB5jB,IAAW,CAACA,KAC1D6jB,EAAiBC,GAAsB1D,IAAmC,IAnUnD2D,EAC9B/D,EACAgE,IAEIvoC,GAASukC,IAGTJ,GAAmBI,GAFZA,EAKJgE,IAAiBjmB,GAAmBG,aAAe,KAAO,GA0T7D6lB,CAA0B/D,EAAchgB,EAASxhB,SAE9CylC,EAAgBC,GAAqB9D,IAA8B,IAzT7C+D,EAC7BnE,EACArd,KAEA,GAAIlnB,GAASukC,KAAkBrd,EAAQpoB,SAASylC,GAC5C,MAAO,CACHoE,YAAY,EACZC,WAAYrE,GAGpB,GAAIJ,GAAmBI,GAAe,CAClC,IAAMsE,EAAiBtE,EAAathC,MAAM6lC,IAAY5hB,EAAQpoB,SAASgqC,KACvE,GAAID,EACA,MAAO,CACHF,YAAY,EACZC,WAAYC,EAGxB,CACA,MAAO,CACHF,YAAY,EACZC,WAAY,GACf,EAoSGF,CAAyBnE,EAAcrd,MAGrC+V,cAAEA,GAAkBM,KAEpBwL,EAAyBxkB,EAASxhB,OAASuf,GAAmBG,aAC9DumB,EAA2BzkB,EAASxhB,OAASuf,GAAmBE,eAEhEymB,EAAmB1kB,EAASqe,kBAAoBmG,IAA2BxkB,EAASyjB,cAEpFkB,EAAqBA,CAACz/B,EAAa0/B,KACrC,GAAIA,EAAc,CACd,IAAMC,GAAmBZ,EAAeG,WAexC,OAdAF,GAAmBY,GAAI30B,KAChB20B,EAAI,CACPV,WAAYS,EACZR,WAAYQ,EAAkBC,EAAKT,WAAa,OAGhDG,GACAV,EAAmB,SAInBe,GACAh2B,YAAW,KAAA,IAAAk2B,EAAA,cAAAA,EAAM1B,EAAmBznB,gBAAnBmpB,EAA4BzE,OAAO,GAAE,IAG9D,CAEA,GAAIkE,EAeA,OAdAV,EAAmB5+B,GAEnBg/B,GAAmBY,GAAI30B,KAChB20B,EAAI,CACPV,YAAY,EACZC,WAAY,YAGZK,IACAtG,EAASl5B,GACLwzB,GACAI,EAAgB5zB,KAMxBu/B,GAA4BxpC,GAAQ4oC,KAChCA,EAAgBtpC,SAAS2K,GACzB4+B,EAAmBD,EAAgBl7B,QAAQ47B,GAAWA,IAAWr/B,KAEjE4+B,EAAmB,IAAID,EAAiB3+B,IAEhD,EAGE8/B,EAA8Bl6B,IAChCA,EAAE+2B,kBACF,IAAMoD,EAAWn6B,EAAE82B,cAAcznC,MAEjC+pC,GAAmBY,GAAI30B,KAChB20B,EAAI,CACPT,WAAYY,MAGZT,GACAV,EAAmBmB,EACvB,EAGEC,EAA0Bp6B,IAC5BA,EAAE+2B,kBAGY,UAAV/2B,EAAE3F,KAAoBggC,MACtBr6B,EAAE00B,iBACF8B,KAIU,WAAVx2B,EAAE3F,MACF2F,EAAE00B,iBACF0E,GAAmBY,GAAI30B,KAChB20B,EAAI,CACPV,YAAY,EACZC,WAAY,OAEZG,GACAV,EAAmB,MAE3B,EAGEqB,EAAmBA,MACjBnlB,EAASygB,WAGT/kC,GAAOmoC,MAGP5oC,GAAQ4oC,IACHI,EAAeG,YAAyC,IAA3BP,EAAgB1kC,WAIlD8kC,EAAeG,YAAmD,KAArCH,EAAeI,WAAW1pC,SAMzD2mC,EAAeA,KACb2C,EAAeG,YAAcK,EACzBxpC,GAAQ4oC,KACRnL,EACMI,EAAgB,IAAI+K,EAAiBI,EAAeI,aACpDjG,EAAS,IAAIyF,EAAiBI,EAAeI,cAGvD3L,EAAgBI,EAAgB+K,GAAmBzF,EAASyF,EAChE,EAGJ,OACIpG,GAAC+D,GAAQ,CAAApI,UACLqE,GAAA,MAAA,CAAKthC,UAAU,qBAAoBi9B,SAAA,CAC/B0D,GAACgC,GAAc,CAAC9e,SAAUA,EAAU+e,iBAAkBA,IACtDtB,GAAA,WAAA,CAAUthC,UAAU,uCAAsCi9B,UACtD0D,GAAA,SAAA,CAAQ3gC,UAAU,UAASi9B,SACtBqL,EAA2B,yBAA2B,gBAE1D9hB,EAAQvC,KAAI,CAACmkB,EAAgB1B,KAC1B,IAAM+B,IAAiB5kB,EAASyjB,eAAiBZ,IAAQ7iB,EAAS2C,QAAQxjB,OAAS,EAC7EimC,EAAO,iBAAoBrF,EAAoB,SAAS8C,EACxDwC,EAAiBD,EAAO,OAExBE,EAAYV,EACZX,EAAeG,WACfI,EACEX,IAAoBU,EACpBtpC,GAAQ4oC,IAAoBA,EAAgBtpC,SAASgqC,GAE7D,OACI9G,GAAA,QAAA,CAAOthC,UAAWyoC,EAAe,qBAAuB,GAAGxL,UACvDqE,GAAA,MAAA,CAAKthC,UAAU,kBAAiBi9B,UAC5B0D,GAAA,QAAA,CACIt+B,KAAMgmC,EAAyB,QAAU,WACzC9qC,KAAM0rC,EACNG,QAASD,EACTE,SAAUA,IAAMb,EAAmBJ,EAAQK,GAC3C76B,GAAIq7B,EACJ,gBAAeC,IAEnBvI,GAAA,OAAA,CAAA1D,SAAOwL,EAAkBL,EAAM,IAAMA,OAExCK,GACG9H,GAAA,QAAA,CACIt+B,KAAK,OACLijC,IAAK4B,EACLt5B,GAAIs7B,EACJ3rC,KAAI,WAAaqmC,EAAoB,OACrC5lC,MAAO8pC,EAAeI,WACtBvC,UAAWoD,EACXvD,QAASqD,EACTrG,OAMA,CANU7zB,GAEDm5B,EAAeG,YAChBO,EAAmBJ,GAAQ,GAE/Bz5B,EAAE+2B,iBAAiB,EAEvB,aAAe0C,EAAM,wBA5BgC1B,EA+BzD,UAKxB/F,GAACoB,GAAa,CACVxzB,KAAMsV,EAASuC,YAAc,SAC7B4b,eAAgBgH,IAChBzjB,WAAYA,EACZ0c,SAAUkD,EACVxI,gBAAiBwI,EACjBjD,iBAAkBqG,EAClBpG,UAAWA,EACXC,OAAQA,MAIxB,CAEA,IAAMkH,GAAmB,CAAC,EAAG,EAAG,EAAG,EAAG,GAChCC,GAAoB,CAAC,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,GACvCC,GAAkB,CAAC,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,IAEjDhD,GAAiF,CACnF,EAAG,CAACtF,GAAeC,IACnB,EAAG,CAACJ,GAAmBD,GAAcJ,IACrC,EAAG,CAACM,GAAuBD,GAAmBD,GAAcJ,GAAgBO,KAGhF,SAAS2F,GAAgBX,GACrB,OAAQA,GACJ,KAAK,EAML,QACI,OAAOqD,GALX,KAAK,EACD,OAAOC,GACX,KAAK,GACD,OAAOC,GAInB,CCxkBA,IAAM1iC,GAAS2B,GAAa,aA6CrB,SAASghC,GACZ/lB,EACAgmB,EACAhuB,GAC+C,IAAAiuB,EACzC9lB,EAAWH,EAAOE,UAAU8lB,GAC5BE,EAAoBF,EAAuB,EAEjD,GAAuB,OAAnBC,EAAC9lB,EAASgmB,aAATF,EAAoBtnC,KACrB,OAAIqnC,IAAyBhmB,EAAOE,UAAU5gB,OAAS,EAC5Ckf,GAA4BC,IAGhCynB,EAGX,GAAI/lB,EAASgmB,UAAUxnC,OAAS6f,GAA4BC,IACxD,OAAOD,GAA4BC,IAChC,GAAI0B,EAASgmB,UAAUxnC,OAAS6f,GAA4BG,kBAC/D,GAAI9L,OAAOmR,UAAU7D,EAASgmB,UAAUtO,OACpC,OAAO1X,EAASgmB,UAAUtO,WAE3B,GAAI1X,EAASgmB,UAAUxnC,OAAS6f,GAA4BE,cAAe,CAE9E,GAAIyB,EAASxhB,OAASuf,GAAmBG,aAAc,CAAA,IAAA+nB,EAG/CC,EAAsBlmB,EAAS2C,QAAQjoB,QAAO,GAAImd,GAQtD,IAN4B,IAAxBquB,GAA8BlmB,EAASyjB,gBAGvCyC,EAAsBlmB,EAAS2C,QAAQxjB,OAAS,GAG9B,OAAtB8mC,EAAIjmB,EAASgmB,mBAASC,EAAlBA,EAAoBE,iBAApBF,EAAoCnrC,eAAeorC,GAAsB,CACzE,IAAME,EAAWpmB,EAASgmB,UAAUG,eAAeD,GAGnD,OAAIxzB,OAAOmR,UAAUuiB,GACVA,EAGPA,IAAa/nB,GAA4BC,IAClCD,GAA4BC,IAGhCynB,CACX,CACJ,MAAO,GAAI/lB,EAASxhB,OAASuf,GAAmBI,OAAQ,CAAA,IAAAkoB,EACpD,GAAwB,iBAAbxuB,IAA0BnF,OAAOmR,UAAUhM,GAClD,MAAM,IAAI4M,MAAM,wCAGpB,IAAM6hB,EA7FX,SAAyCC,EAAuBnE,GACnE,GAAc,IAAVA,EAAa,CACb,GAAoB,EAAhBmE,GAAqBA,EAAgB,EACrC,MAAM,IAAI9hB,MAAM,qCAEpB,OAAyB,IAAlB8hB,EAAsB,WAAa,UAC9C,CAAO,GAAc,IAAVnE,EAAa,CACpB,GAAoB,EAAhBmE,GAAqBA,EAAgB,EACrC,MAAM,IAAI9hB,MAAM,qCAGpB,OAAyB,IAAlB8hB,EAAsB,WAA+B,IAAlBA,EAAsB,UAAY,UAChF,CAAO,GAAc,IAAVnE,EAAa,CACpB,GAAoB,EAAhBmE,GAAqBA,EAAgB,EACrC,MAAM,IAAI9hB,MAAM,qCAGpB,OAAO8hB,EAAiB,EAAmC,IAAlBA,EAAsB,UAAY,WAA/C,UAChC,CAAO,GAAc,IAAVnE,EAAa,CACpB,GAAoB,EAAhBmE,GAAqBA,EAAgB,EACrC,MAAM,IAAI9hB,MAAM,qCAGpB,OAAO8hB,EAAiB,EAAmC,IAAlBA,EAAsB,UAAY,WAA/C,UAChC,CAAO,GAAc,KAAVnE,EAAc,CACrB,GAAoB,EAAhBmE,GAAqBA,EAAgB,GACrC,MAAM,IAAI9hB,MAAM,sCAGpB,OAAO8hB,EAAiB,EAAmBA,EAAiB,EAAiB,YAAb,WAApC,YAChC,CAEA,MAAM,IAAI9hB,MAAM,2CACpB,CA4DiC+hB,CAAgC3uB,EAAUmI,EAASoiB,OAExE,GAAsB,OAAtBiE,EAAIrmB,EAASgmB,mBAASK,EAAlBA,EAAoBF,iBAApBE,EAAoCvrC,eAAewrC,GAAe,CAClE,IAAMF,EAAWpmB,EAASgmB,UAAUG,eAAeG,GAGnD,OAAI5zB,OAAOmR,UAAUuiB,GACVA,EAGPA,IAAa/nB,GAA4BC,IAClCD,GAA4BC,IAGhCynB,CACX,CACJ,CAEA,OAAOA,CACX,CAGA,OADA9iC,GAAOgB,KAAK,wEACL8hC,CACX,CCrHA,IAAM9iC,GAAS2B,GAAa,wBAmCrB,SAAS6hC,GACZ5mB,EACA+Z,GAEA,IAAM8M,EAvBH,SAA4B9M,GAC/B,OjBjBJ,SAA6BptB,EAAuDvJ,GAAQ,IAA9D0jC,iBAAEA,EAAgBC,uBAAEA,EAAsBC,OAAEA,GAAQr6B,EACxEs6B,EAAmBrmB,GAAmBkmB,GAC5C,GAAIG,EAEA,aADA7jC,GAAAA,EAAQa,KAAI,oCAAqCgjC,GAC1CA,EAEX,IAAMC,EAVV,SAA+CH,GAC3C,OAAKA,GAA0B,iBAAmBA,GAA4B,aAAcA,EACrFnmB,GAAmBmmB,EAAuBI,UAD2E,IAEhI,CAO2BC,CAAsCL,GAC7D,GAAIG,EAEA,aADA9jC,GAAAA,EAAQa,KAAI,mCAAoCijC,GACzCA,EAEX,IAAMG,EAAiBzmB,GAAmBomB,GAC1C,OAAIK,SACAjkC,GAAAA,EAAQa,KAAI,0BAA2BojC,GAChCA,UAEXjkC,GAAAA,EAAQa,KAAK,6BACN,KACX,CiBDWqjC,CACH,CACIR,iBAAkB/M,EAASpE,OAAO4R,0BAClCR,uBAAwBvrC,GAAWu+B,EAASyN,cACtCzN,EAASyN,a3BkCiB,kC2BjC1BnlC,EACN2kC,OCsJJvkC,UAAU0kC,UACT1kC,UAAkCokC,cDrJnCzjC,GAER,CAYyBqkC,CAAmB1N,GAExC,IAAK8M,EAED,OADAzjC,GAAOa,KAAK,6BACL,CAAE+b,SAAQmnB,SAAU,MAG/B,IAAMznC,EAAS4hB,GAAuBtB,EAAQ6mB,EAAczjC,IAE5D,MAAO,CACH4c,OAAQtgB,EAAOsgB,OACfmnB,SAAUznC,EAAO4iB,WAEzB,CEiBA,IAAMlgB,GAASkmB,GACT5lB,GAAW6lB,GAEXmf,GAAiC,wBACjCC,GAA4B,8BAQlC,SAASC,GAAyBh9B,EAAqBi9B,GACnD,IACI,IAAMC,EAAal9B,EAAOm9B,wBACpBC,EAAiB5lC,GAAO6lC,YACxBC,EAAgB9lC,GAAO+lC,WAGzBtL,EADkBiL,EAAWjL,KAAOiL,EAAWjM,MAAQ,EAChCgM,EAAc,EAErChL,EAAOgL,EAAcK,EAbT,KAcZrL,EAAOqL,EAAgBL,EAdX,OAgBZhL,IACAA,EAjBY,IAmBhB,IACMuL,EAAaJ,EAAiBF,EAAWO,OAEzCC,EAvBY,IAuBAF,GADCN,EAAWlL,IAC0CwL,EAExE,MAAO,CACHhf,SAAU,QACVwT,IAAK0L,EAAY,OAAYR,EAAWO,OAzB/B,GAyB+C,KACxDxL,KAASA,EAAI,KACbE,MAAO,OACPsL,OAAQC,EAAeN,EAAiBF,EAAWlL,IA5B1C,GA4BuD,KAAO,OACvEpT,OAAQf,GAAwBe,OAExC,CAAE,MAAOjlB,GAEL,OADAnB,GAAOgB,KAAK,wCAAyCG,GAC9C,IACX,CACJ,CAKO,MAAMgkC,GAQTrkB,WAAAA,CAAY6P,GAAkB,IAAAyU,EAAAv6B,KAAAA,KALtBw6B,EAA+C,IAAIC,IAAKz6B,KACxD06B,EACJ,IAAID,IAAKz6B,KACL26B,EAAsC,IAAIC,IAAK56B,KAQhD66B,iBAAmB,KAGtB,IAAMC,EAAU96B,KAAK+6B,SAASxB,a7B9Ef,Y6B+Ef,GAAKuB,EAGL,IAAK,IAAM/oB,KAAU+oB,EACbrQ,GAAmB1Y,IACnBqX,GAAyBrX,EAAQ/R,KAAK+6B,SAE9C,EACH/6B,KA8BMg7B,oBAAsB,CAACC,EAAqBjkC,KAAgD,IAAAkkC,EAAAC,EAAAC,EAAAC,GACvFtpB,OAAQupB,EAAkBpC,SAAU7Q,GAAmBroB,KAAKu7B,EAA6BN,GAG3FlpB,EACK,MAAP/a,GAAAA,EAASmkB,UAAmB,MAAPnkB,GAAAA,EAASwkC,SAAQn5B,KAEzBi5B,EAAgB,CACnB1nB,WAAUvR,EAAA,CAAA,EACHi5B,EAAiB1nB,WAChB5c,EAAQmkB,UAAY,CAAEA,SAAUnkB,EAAQmkB,UACxCnkB,EAAQwkC,UAAY,CAAEC,eAAgBzkC,EAAQwkC,aAG1DF,EAEVt7B,KAAK07B,EAAoB3pB,EAAO9V,IAEhC,IAAMmsB,WAAEA,EAAUuT,iBAAEA,GAAqB3kC,QAAAA,EAAW,CAAA,EAE9CmxB,KADiBwT,GAA2D,GAAvC1vC,OAAOmF,KAAKuqC,GAAkBtqC,SAEnE2O,KAAK47B,EAAwB7pB,EAAQ4pB,EAAkBvT,EAAYC,GAIzE,IAAIF,GAAuC,OAAlB+S,EAACnpB,EAAO6B,aAAPsnB,EAAmBhgB,uBAA7C,CAIAlb,KAAK67B,EAAkB9pB,GAGvB,IAAI+pB,EAAmC,CAAA,EACvC,IAAqB,OAAjBX,EAAAppB,EAAO6B,iBAAU,EAAjBunB,EAAmBhgB,YAAarM,GAAeU,eAAkC,OAArB4rB,EAAIrpB,EAAO6B,aAAPwnB,EAAmBK,eAAgB,CACnG,IACmBM,EADbC,EAAgBvnC,GAASyxB,cAAcnU,EAAO6B,WAAW6nB,gBAC3DO,IACAF,EACInC,GACIqC,EACAr3B,UAA0B,OAAjBo3B,EAAAhqB,EAAO6B,iBAAU,EAAjBmoB,EAAmBrgB,WAAYlB,GAAwBkB,YAC/D,CAAA,EAEjB,CAEA,IAAMugB,GAAgC,OAAjBZ,EAAAtpB,EAAO6B,iBAAU,EAAjBynB,EAAmBrf,0BAA2B,GAC7DoK,OAAEA,GAAWP,GAAqB9T,EAAQ/R,KAAK+6B,UAE/CmB,EAAqC,CACvCpW,QAAS9lB,KAAK+6B,SACdhpB,OAAQA,EACRoqB,sBAAuBn8B,KAAKo8B,EAC5BhU,WAAYA,EACZzB,MAAOmV,EACP3T,kBAAmBA,EACnBkU,eAAuB,MAAPrlC,OAAO,EAAPA,EAASqlC,eACzBhU,kBAGJ,GAAoB,GAAhB4T,EACA,OAAOK,GAAOtN,GAACuN,GAAWl6B,EAAA,CAAA,EAAK65B,IAAsB9V,GAEzD,IAAMoW,EAAYz7B,YAAW,KAQzB,GANAf,KAAKw6B,EAAgBiC,OAAO1qB,EAAO9V,KAM9B+D,KAAK08B,EAAqB3qB,GAE3B,OADA5c,GAAOa,KAAI,UAAW+b,EAAO9V,yEACtB+D,KAAKo8B,EAAuBrqB,GAGvCuqB,GACItN,GAACuN,GAAWl6B,KACJ65B,EAAgB,CACpBnqB,OAAM1P,EAAA,CAAA,EACC0P,EAAM,CACT6B,WAAUvR,EAAA,GACH0P,EAAO6B,WAAU,CACpBoI,wBAAyB,SAIrCoK,EACH,GACa,IAAf6V,GACHj8B,KAAKw6B,EAAgBn0B,IAAI0L,EAAO9V,GAAIugC,EA7DpC,CA6D8C,EACjDx8B,KAEO28B,EAAiB5qB,IACrB,IAAQA,OAAQupB,EAAkBpC,SAAU7Q,GAAmBroB,KAAKu7B,EAA6BxpB,IAE3FqU,OAAEA,EAAMC,eAAEA,GAAmBR,GAAqByV,EAAkBt7B,KAAK+6B,UAG1E1U,GAILiW,GACItN,GAAC4N,GAAc,CACX9W,QAAS9lB,KAAK+6B,SACdhpB,OAAQupB,EACRjT,eAAgBA,GACXtW,EAAO9V,IAEhBmqB,EACH,EACJpmB,KAEO68B,EAAiC9qB,IACrC/R,KAAK88B,EAAqB/qB,GAC1B,IAAMgrB,EAAW/8B,KAAK06B,EAAyBj2B,IAAIsN,EAAO9V,IACtD8gC,IACAA,EAASnlC,QAAQ6R,oBAAoB,QAASszB,EAASC,UACvDD,EAASnlC,QAAQqlC,gBAAgBvD,IACjC15B,KAAK06B,EAAyB+B,OAAO1qB,EAAO9V,IAC5C9G,GAAOa,KAAI,qCAAsC+b,EAAO9V,IAC5D,EACH+D,KAEOk9B,EAAgC,CAACnrB,EAAgBypB,KACrD,IAAM2B,EAAiB1oC,GAASyxB,cAAcsV,GACxC4B,EAAuBp9B,KAAK06B,EAAyBj2B,IAAIsN,EAAO9V,IAEtE,GAAKkhC,EAAL,CASA,GAFAn9B,KAAK28B,EAAc5qB,GAEfqrB,EAAsB,CAEtB,GAAID,IAAmBC,EAAqBxlC,QAMxC,OALAzC,GAAOa,KAAI,uCAAwC+b,EAAO9V,+BAC1D+D,KAAK68B,EAA8B9qB,EAM3C,CAGA,IAAKorB,EAAeE,aAAa3D,IAA4B,CACzD,IAAMsD,EAAYnlC,IAAiB,IAAAylC,EAAAC,EAC/B1lC,EAAMk8B,kBAEN,IAAMyJ,GACe,OAAjBF,EAAAvrB,EAAO6B,iBAAU,EAAjB0pB,EAAmBniB,YAAarM,GAAeU,cACzCmqB,GACI9hC,EAAMi8B,cACNnvB,UAA0B,OAAjB44B,EAAAxrB,EAAO6B,iBAAU,EAAjB2pB,EAAmB7hB,WAAYlB,GAAwBkB,WAEpE,CAAA,EAEVvnB,GAAOu0B,cACH,IAAIC,YAAY8Q,GAAgC,CAC5C7Q,OAAQ,CAAEC,SAAU9W,EAAO9V,GAAIkf,SAAUqiB,KAEhD,EAGL7lC,GAAiBwlC,EAAgB,QAASH,GAC1CG,EAAevV,aAAa8R,GAA2B,QACvD15B,KAAK06B,EAAyBr0B,IAAI0L,EAAO9V,GAAI,CAAErE,QAASulC,EAAgBH,WAAUjrB,WAClF5c,GAAOa,KAAI,sDAAuD+b,EAAO9V,GAC7E,CAxCA,MAJQmhC,GACAp9B,KAAK68B,EAA8B9qB,EA2C3C,EACH/R,KAgCMy9B,cAAiB1rB,IACpB,IAAQA,OAAQupB,EAAkBpC,SAAU7Q,GAAmBroB,KAAKu7B,EAA6BxpB,IAC3FqU,OAAEA,GAAWP,GAAqByV,EAAkBt7B,KAAK+6B,UAC/DuB,GACItN,GAACuN,GAAW,CACRzW,QAAS9lB,KAAK+6B,SACdhpB,OAAQupB,EACRa,sBAAuBn8B,KAAKo8B,EAC5B/T,eAAgBA,IAEpBjC,EACH,EACJpmB,KAEM09B,aAAe,CAAC3rB,EAAgBypB,EAAmBpT,KAAkC,IAAAuV,GAChF5rB,OAAQupB,EAAkBpC,SAAU7Q,GAAmBroB,KAAKu7B,EAA6BxpB,GAC7FoW,GAAoB,EACA,OAAxBwV,EAAI39B,KAAK+6B,SAASrT,gBAAMiW,EAApBA,EAAsB7C,UAAtB6C,EAA+BC,iBAC/BzV,EAAoBnoB,KAAK69B,GAAkBvC,EAAkBjT,IAGjEiU,GACItN,GAACuN,GAAW,CACRzW,QAAS9lB,KAAK+6B,SACdhpB,OAAQupB,EACRa,sBAAuBn8B,KAAKo8B,EAC5BrR,SAAS,EACT3C,WAAYA,EACZD,kBAAmBA,EACnBE,eAAgBA,IAEpBmT,EACH,EACJx7B,KAiRM89B,yBAA2B,SAAChmC,EAA0BimC,GAA8B,IAAAC,OAAnB,IAAXD,IAAAA,GAAc,UACvEC,EAAAzD,EAAKQ,WAAiB,OAATiD,EAAbA,EAAelD,UAAfkD,EAAwBC,YAAYnD,IAChC,IAAMoD,EAA0BpD,EAAQjgC,QAAQkX,GAAWwoB,EAAKmC,EAAqB3qB,KACrFja,EAASomC,EAAwB,GAClCH,EACP,EAAC/9B,KAEMm+B,mCAAqC,SAACJ,QAAoB,IAApBA,IAAAA,GAAuB,GAChExD,EAAKuD,0BAA0BhD,IAC3B,IAAMsD,EAA+BtD,EAAQjgC,QACxCkX,GAAWA,EAAOrhB,OAASkf,GAAWC,SAAWkC,EAAOrhB,OAASkf,GAAWG,SAO3EsuB,EAAc,IAAIzD,IAAIwD,EAA6B9rB,KAAKP,GAAWA,EAAO9V,MAChF,IAAK,IAAMqiC,KAAmBlxC,MAAMmxC,KAAKhE,EAAKC,EAAgBppC,QACrDitC,EAAYG,IAAIF,IACjB/D,EAAKkE,aAAaH,GAM1B,IAAMI,EAAoBnE,EAAKoE,GAA8BP,GAGvDQ,EAAwB,IAAIhE,IAElC8D,EAAkBvnC,SAAS4a,IAEvB,GAAIA,EAAOrhB,OAASkf,GAAWG,OAAQ,CAAA,IAAA8uB,EAAAC,EAAAC,EAUjCC,EATF,IAAqB,OAAjBH,EAAA9sB,EAAO6B,iBAAU,EAAjBirB,EAAmBzjB,cAAezM,GAAiBC,IAEnD,YADA2rB,EAAKoC,EAAc5qB,IAMF,OAAjB+sB,EAAA/sB,EAAO6B,iBAAU,EAAjBkrB,EAAmB1jB,cAAezM,GAAiBE,UAClC,OAD0CkwB,EAC3DhtB,EAAO6B,aAAPmrB,EAAmBtD,iBAEnBmD,EAAsBK,IAAIltB,EAAO9V,IACjCs+B,EAAK2C,EAA8BnrB,EAAyB,OAAnBitB,EAAEjtB,EAAO6B,iBAAU,EAAjBorB,EAAmBvD,gBAEtE,CAGI7tC,GAAO2sC,EAAK2E,KAAmBntB,EAAOrhB,OAASkf,GAAWC,SAC1D0qB,EAAKS,oBAAoBjpB,EAC7B,IAIJwoB,EAAKG,EAAyBvjC,SAAQuH,IAAgB,IAAfqT,OAAEA,GAAQrT,EACxCkgC,EAAsBJ,IAAIzsB,EAAO9V,KAClCs+B,EAAKsC,EAA8B9qB,EACvC,GACF,GACHgsB,EACP,EAAC/9B,KAEO67B,EAAqB9pB,IACpBnkB,GAAOoS,KAAKk/B,KACb/pC,GAAOmB,MAAK,UAAW0J,KAAKk/B,GAAc,wCAAwCntB,EAAO9V,GAAE,KAE/F+D,KAAKk/B,GAAiBntB,EAAO9V,EAAE,EAClC+D,KAcOo8B,EAA0BrqB,IAC1B/R,KAAKk/B,KAAmBntB,EAAO9V,IAC/B9G,GAAOmB,MAAK,UAAWyb,EAAO9V,GAAE,0CAA0C8V,EAAO9V,GAAE,KAEvF+D,KAAK07B,EAAoB3pB,EAAO9V,IAChC+D,KAAKk/B,GAAiB,KACtBl/B,KAAK88B,EAAqB/qB,EAAO,EAvoBjC/R,KAAK+6B,SAAWjV,EAEhB9lB,KAAKk/B,GAAiB,IAC1B,CAgBQxD,CAAAA,CAAoB7S,GACxB,IAAMjlB,EAAU5D,KAAKw6B,EAAgB/1B,IAAIokB,GACrCjlB,IACAK,aAAaL,GACb5D,KAAKw6B,EAAgBiC,OAAO5T,GAEpC,CAMO4V,YAAAA,CAAa5V,GAEX7oB,KAAKw6B,EAAgBgE,IAAI3V,KAI9B1zB,GAAOa,KAAI,4BAA6B6yB,GACxC7oB,KAAK07B,EAAoB7S,GAIrB7oB,KAAKk/B,KAAmBrW,IACxB7oB,KAAKk/B,GAAiB,MAE9B,CAuLQP,EAAAA,CAA8B7D,GAClC,OAAOA,EAAQhnC,MAAK,CAACqY,EAAGwZ,KAAM,IAAAwZ,EAAAC,EACpBC,EAAsB5U,GAAmBte,GACzCmzB,EAAsB7U,GAAmB9E,GAC/C,GAAI0Z,IAAwBC,EACxB,SAEJ,IAAKD,GAAuBC,EACxB,OAAO,EAEX,IAAMC,EAAYpzB,EAAEqe,WAAa7Z,GAC3B6uB,EAAY7Z,EAAE6E,WAAa7Z,GAEjC,OAAI4uB,IAAcC,EACP,GAEND,GAAaC,OAIE,OAAZL,EAAAhzB,EAAEyH,iBAAU,EAAZurB,EAAcnjB,0BAA2B,KAAkB,OAAZojB,EAAAzZ,EAAE/R,iBAAU,EAAZwrB,EAAcpjB,0BAA2B,EAAE,GAE1G,CAqCQuf,CAAAA,CAA6BxpB,GAGjC,OAAO4mB,GAA8B5mB,EAAQ/R,KAAK+6B,SACtD,CAEQ8C,EAAAA,CAAkB9rB,EAAgBsW,GAEtC,GAAIroB,KAAK26B,EAAuB6D,IAAIzsB,EAAO9V,IACvC,OAAO,EAGX,IAAMwjC,OAAEA,GChaT,SAAqCC,GAIxC,IAAMD,EAAwB,CAAA,EAC1BE,GAAa,EAGXC,EAAcF,EAAa3kC,QAAQ,MAAO,IAChD,IAAK6kC,EACD,MAAO,CAAEH,SAAQE,cAIrB,IAAME,EAAQD,EAAYxvC,MAAM,KAEhC,IAAK,IAAM0vC,KAAQD,EAAO,CACtB,IAAOxoC,EAAKhL,GAASyzC,EAAK1vC,MAAM,KAChC,GAAKiH,IAAO3J,GAAYrB,GAAxB,CAIA,IAAM0zC,EAAaC,mBAAmB3oC,GAChC4oC,EAAeD,mBAAmB3zC,GAGxC,GAAmB,gBAAf0zC,GAAiD,SAAjBE,EAApC,CAMA,IAAMxa,EAAQsa,EAAWta,MAAM,YAC/B,GAAIA,EAAO,CACP,IAAMya,EAAgBv7B,SAAS8gB,EAAM,GAAI,IACpCga,EAAOS,KACRT,EAAOS,GAAiB,IAE5BT,EAAOS,GAAetkC,KAAKqkC,EAC/B,CAVA,MAFIN,GAAa,CAPjB,CAoBJ,CAEA,MAAO,CAAEF,SAAQE,aACrB,CDqX2BQ,CAA4BhsC,GAAO+3B,SAASkU,QAE/D,GAAmC,IAA/Bn0C,OAAOmF,KAAKquC,GAAQpuC,OACpB,OAAO,EAGX8D,GAAOa,KAAK,oDAEZ,IAAMvE,EAASuO,KAAKqgC,GAAoBtuB,EAAQ0tB,EAAQpX,GACxD,IAAK52B,EACD,OAAO,EAGX,IAAMogB,UAAEA,EAASyuB,aAAEA,EAAYnY,kBAAEA,EAAiBoY,iBAAEA,GAAqB9uC,EAsBzE,OAfkCxF,OAAOmF,KAAKmvC,GAAkBlvC,OAAS,GAAK0gB,EAAOgY,0BACpD5B,IAC7BF,GAAgB,CACZpW,UAAWsW,EAAoBtW,EAAY0uB,EAC3CxuB,SACAmW,mBAAoBoY,EACpBxa,QAAS9lB,KAAK+6B,SACd5S,oBACAE,mBAKRroB,KAAK26B,EAAuBsE,IAAIltB,EAAO9V,IAEhCksB,CACX,CAOQyT,CAAAA,CACJ7pB,EACA4pB,EACAvT,EACAC,GAEA,IAAMmY,EAA6C,CAAA,EACnD,IAAK,IAAOC,EAAUp0C,KAAUJ,OAAOuL,QAAQmkC,GAE3C6E,EADc77B,SAAS87B,IACAtzC,GAAQd,GAASA,EAAMimB,IAAIkJ,QAAU,CAACA,OAAOnvB,IAGxE8I,GAAOa,KAAK,yCAEZ,IAAMvE,EAASuO,KAAKqgC,GAAoBtuB,EAAQyuB,EAAenY,GAC/D,IAAK52B,EACD,OAAO,EAGX,IAAMogB,UAAEA,EAASyuB,aAAEA,EAAYnY,kBAAEA,GAAsB12B,EAavD,OAVAw2B,GAAgB,CACZpW,YACAE,SACAmW,mBAAoBoY,EACpBxa,QAAS9lB,KAAK+6B,SACd5S,oBACAC,aACAC,mBAGGF,CACX,CAEQkY,EAAAA,CACJtuB,EACAyuB,EACAnY,GAQA,IACI,IAAMxW,EC1cX,SAAmCE,EAAgByuB,GACtD,IAAM3uB,EAAiC,CAAA,EAqEvC,OAnEAE,EAAOE,UAAU9a,SAAQ,CAAC+a,EAA0B0X,KAChD,GAAK4W,EAAc5W,IAAW1X,EAASjW,GAAvC,CAIA,IAAM6c,EAAS0nB,EAAc5W,GACvB8W,EAAchvB,GAAqBQ,EAASjW,IAElD,IACI,OAAQiW,EAASxhB,MACb,KAAKuf,GAAmBG,aACpB,IAAK8B,EAAS2C,SAAuC,IAA5B3C,EAAS2C,QAAQxjB,OAEtC,YADA8D,GAAOgB,KAAI,6BAA8ByzB,qBAG7C,IAAM+W,EAAch8B,SAASmU,EAAO,GAAI,IACxC,GAAIS,MAAMonB,IAA8B,EAAdA,GAAmBA,GAAezuB,EAAS2C,QAAQxjB,OAEzE,YADA8D,GAAOgB,KAAI,8CAA+CyzB,OAAU9Q,EAAO,IAG/EjH,EAAU6uB,GAAexuB,EAAS2C,QAAQ8rB,GAC1C,MAGJ,KAAK1wB,GAAmBE,eACpB,IAAK+B,EAAS2C,SAAuC,IAA5B3C,EAAS2C,QAAQxjB,OAEtC,YADA8D,GAAOgB,KAAI,6BAA8ByzB,qBAG7C,IAAMgX,EAAgB9nB,EACjBxG,KAAKjG,GAAM1H,SAAS0H,EAAG,MACvBxR,QAAQlJ,IAAO4nB,MAAM5nB,IAAMA,GAAK,GAASugB,EAAS2C,QAAQxjB,OAArBM,IAE1C,GAA6B,IAAzBivC,EAAcvvC,OAEd,YADA8D,GAAOgB,KAAI,0CAA2CyzB,GAK1D,IAAMiX,EAAgB,IAAI,IAAIjG,IAAIgG,EAActuB,KAAK3gB,GAAMugB,EAAS2C,QAAQljB,OACjDivC,EAAcvvC,OAArCwvC,EAAcxvC,QACd8D,GAAOgB,KAAI,mDAAoDyzB,GAEnE/X,EAAU6uB,GAAeG,EACzB,MAGJ,KAAK5wB,GAAmBI,OACpB,IAAMmkB,EAAS7vB,SAASmU,EAAO,GAAI,IAC7Bwb,EAAQpiB,EAASoiB,OAAS,GAEhC,GAAI/a,MAAMib,IAAoB,EAATA,GAAcA,EAASF,EAExC,YADAn/B,GAAOgB,KAAI,wCAAyCyzB,EAAK,KAAK9Q,EAAO,GAAE,cAAcwb,EAAK,KAG9FziB,EAAU6uB,GAAelM,EACzB,MAGJ,QACIr/B,GAAOa,KAAI,kCAAmCkc,EAASxhB,kCAEnE,CAAE,MAAO4F,GACLnB,GAAOmB,MAAK,sCAAuCszB,EAAK,IAAKtzB,EACjE,CA7DA,CA6DA,IAGGub,CACX,CDmY8BivB,CAA0B/uB,EAAQyuB,GAEpD,GAAsC,IAAlCv0C,OAAOmF,KAAKygB,GAAWxgB,OAEvB,OADA8D,GAAOgB,KAAK,wDACL,KAGX,IAAMmqC,EAAehoB,KAGfyoB,EAAmB90C,OAAOmF,KAAKovC,GAAeluB,KAAK7D,GAAM9J,SAAS8J,EAAG,OACrEuyB,mBAAEA,EAAkBT,iBAAEA,GCjYjC,SACHxuB,EACAgvB,EACAlvB,GAOA,IALA,IAAIovB,EAAe,EACbV,EAAwC,CAAA,EAExCW,EAAiBnvB,EAAOE,UAAU5gB,OAAS,EAE3B0gB,EAAOE,UAAU5gB,OAAhC4vC,GAAuDC,EAD3C,GAGVH,EAAiBt0C,SAASw0C,IAF2C,CAM1E,IAAM/uB,EAAWH,EAAOE,UAAUgvB,GAGlC,IAAK/uB,KAAc,qBAAsBA,KAAcA,EAASqe,iBAE5D,MAIJ,GAAIre,EAASjW,GAAI,CACb,IAAMykC,EAAchvB,GAAqBQ,EAASjW,IAC7CvO,GAAYmkB,EAAU6uB,MACvBH,EAAiBG,GAAe7uB,EAAU6uB,GAElD,CAGA,IACMpI,EAAWR,GAAkB/lB,EAAQkvB,EAD1B/uB,EAASjW,GAAK4V,EAAUH,GAAqBQ,EAASjW,KAAO,MAG9E,GAAIq8B,IAAa/nB,GAA4BC,IAEzC,MAAO,CAAEwwB,mBAAoBjvB,EAAOE,UAAU5gB,OAAQkvC,oBAI1DU,EAAe3I,CACnB,CAEA,MAAO,CAAE0I,mBAAoBC,EAAcV,mBAC/C,CDmV6DY,CAC7CpvB,EACAgvB,EACAlvB,GAEEsW,EAAoB6Y,GAAsBjvB,EAAOE,UAAU5gB,OAWjE,OATAg9B,GAAyBtc,EAAQ,CAC7BmW,mBAAoBoY,EACpBzuB,UAAWA,EACXuvB,kBAAmBJ,EACnB3Y,mBAGJlzB,GAAOa,KAAK,+DAEL,CAAE6b,YAAWyuB,eAAcU,qBAAoB7Y,oBAAmBoY,mBAC7E,CAAE,MAAOjqC,GAEL,OADAnB,GAAOmB,MAAM,2CAA4CA,GAClD,IACX,CACJ,CAEQ+qC,EAAAA,CAA4BC,EAAwBC,GAA6C,IAAAC,EACrG,QADuF,IAA/BD,IAAAA,OAAkCntC,IACrFktC,EACD,OAAO,EAEX,IAIiBG,EAJXC,IAA+C,OAA3BF,EAACxhC,KAAK+6B,SAAS4G,gBAAdH,EAA4BE,iBAAiBJ,EAAS,CAC7EM,YAAaN,EAAQniC,WAvbI,wBAybzB0iC,GAAmB,EAKvB,OAJIN,IAEAM,UADsBJ,EAAGzhC,KAAK+6B,SAAS4G,qBAAdF,EAA4BK,eAAeR,EAAS,CAAEM,YAAY,OACnDL,GAA+B,QAAhBA,GAEpDG,GAAoBG,CAC/B,CAEQE,EAAAA,CAA0BhwB,GAC9B,OAAKA,EAAOmY,YAIRyB,GAAmB5Z,EAAQ/R,KAAK+6B,WAChCrO,GAA2B3a,IZ0GhC,SAAiCA,GAAyB,IAAAiwB,EAC7D,OAAsB,OAAlBA,EAACjwB,EAAOmY,cAAP8X,EAAmBxG,YAGP,MAAR/mC,KAAAA,GAAUyxB,cAAcnU,EAAOmY,WAAWsR,UACvD,CY9GYyG,CAAwBlwB,EAEhC,CAEQmwB,EAAAA,CAA4BnwB,GAChC,OACIiY,GAAsBjY,IACtB/R,KAAKqhC,GAA4BtvB,EAAOowB,8BACxC1X,GAAmB1Y,EAE3B,CAEOqwB,sBAAAA,CAAuBrwB,GAAwD,IAAAsY,EAAAC,EAC5E+X,EAAc,CAAEC,UAAU,EAAM9+B,YAAQpP,GAE9C,IlB5kBD,SAAyB2d,GAC5B,SAAUA,EAAOwwB,YAAexwB,EAAOywB,SAC3C,CkB0kBaC,CAAgB1wB,GAGjB,OAFAswB,EAAYC,UAAW,EACvBD,EAAY7+B,OAAM,8CAAiDuO,EAAOywB,SACnEH,EAGX,IAAKzsB,GAAoBnpB,SAASslB,EAAOrhB,MAGrC,OAFA2xC,EAAYC,UAAW,EACvBD,EAAY7+B,OAAM,mBAAsBuO,EAAOrhB,KAAI,6CAC5C2xC,EAGX,IAAMK,EAAqC,OAApBrY,EAAGtY,EAAOmY,iBAAU,EAAjBG,EAAmBqY,kBAC7C,OAAK1iC,KAAKqhC,GAA4BtvB,EAAO4wB,gBAAiBD,GAUzD1iC,KAAKqhC,GAA4BtvB,EAAO6wB,oBAMxC5iC,KAAKkiC,GAA4BnwB,GVzlBvC,SAAyB8wB,EAAqBC,GACjD,IAAKD,IAAeC,EAChB,OAAO,EAGX,IAAMC,EAA+B,iBAAjBD,EAA4B,IAAI7gC,KAAK6gC,GAAgBA,EAEnE5gC,EAAM,IAAID,KACV+gC,EAASjhC,KAAKkhC,IAAI/gC,EAAIghC,UAAYH,EAAKG,WAE7C,OADiBnhC,KAAK+T,KAAKktB,EAAM,OACfH,CACtB,CF+jBWM,CYsBuC,OAAlB7Y,EAACvY,EAAOmY,iBAAU,EAAjBI,EAAmB8Y,2BZvBrB1pB,GAAWI,EAHR,uBAXJ/H,MACP2H,GAAWI,EAAKxE,GAAiBvD,MAIxCiY,GAAsBjY,GYsC1BsxB,CAActxB,IACdswB,EAAYC,UAAW,EACvBD,EAAY7+B,OAAM,+DACX6+B,GAGJA,GAXHA,EAAYC,UAAW,EACvBD,EAAY7+B,OAAM,oCACX6+B,IATPA,EAAYC,UAAW,EACvBD,EAAY7+B,OACR,oHACG6+B,IATPA,EAAYC,UAAW,EACvBD,EAAY7+B,OAAM,+CACX6+B,IAZPA,EAAYC,UAAW,EAInBD,EAAY7+B,OAHXk/B,EAGiB,yDAA4DA,EAF5D,4CAIfL,EA6Bf,CAOQiB,EAAAA,CAAiCvxB,GAAyB,IAAAwxB,EAC9D,IlBjoBD,SAAmCxxB,GAA6C,IAAAsY,EACnF,QAA0B,OAAlBA,EAACtY,EAAOmY,aAAkB,OAARG,EAAjBA,EAAmBF,SAAc,OAARE,EAAzBA,EAA2BvR,UAA3BuR,EAAmCh5B,OAChD,CkB+nBamyC,CAA0BzxB,KlB7nBhC,SAAoCA,GAA6C,IAAAuY,EACpF,QAA0B,OAAlBA,EAACvY,EAAOmY,aAAmB,OAATI,EAAjBA,EAAmBmZ,UAAe,OAARnZ,EAA1BA,EAA4BxR,UAA5BwR,EAAoCj5B,OACjD,CkB2nBmDqyC,CAA2B3xB,GAElE,OAAO,EAEX,IAAM4xB,EACmB,OADoCJ,EACzDvjC,KAAK+6B,SAASD,UAA6B,OAAtByI,EAArBA,EAAuBK,2BAAoB,EAA3CL,EAA6CtF,aACjD,QAA0C,MAAjC0F,IAAAA,EAAmCl3C,SAASslB,EAAO9V,IAChE,CAEQ4nC,EAAAA,CAAY9xB,GAAyB,IAAA+xB,EACzC,OAA6B,OAAzBA,EAAC/xB,EAAOgyB,qBAAPD,EAA0BzyC,QAIxB0gB,EAAOgyB,kBAAkB52B,OAAMlM,IAAoB,IAAnB5J,IAAEA,EAAGhL,MAAEA,GAAO4U,EACjD,OAAK5J,IAAQhL,GAGN2T,KAAKqhC,GAA4Bh1C,EAAM,GAEtD,CAYQqwC,CAAAA,CAAqB3qB,GACzB,OACI/R,KAAKoiC,uBAAuBrwB,GAAQuwB,UACpCtiC,KAAK+hC,GAA0BhwB,IAC/B/R,KAAKsjC,GAAiCvxB,IACtC/R,KAAK6jC,GAAY9xB,EAEzB,CAyEQ+qB,CAAAA,CAAqB/qB,GACzB,IACI,IAAMiyB,EAAkBvvC,GAASyxB,cAAcF,GAAwBjU,GAAQ,IAC5D,MAAfiyB,GAAAA,EAAiB7d,YACjBmW,GAAO,KAAM0H,EAAgB7d,YAElB,MAAf6d,GAAAA,EAAiBC,QACrB,CAAE,MAAO3tC,GACLnB,GAAOgB,KAAI,2BAA4B4b,EAAO9V,GAAE,aAAc3F,EAClE,CACJ,CAYO4tC,UAAAA,GACH,MAAO,CACHC,iBAAkBnkC,KAAK67B,EACvBM,sBAAuBn8B,KAAKo8B,EAC5BgI,cAAepkC,KAAKk/B,GACpBmF,eAAgBrkC,KAAKw6B,EACrB8J,aAActkC,KAAK28B,EACnB3B,oBAAqBh7B,KAAKg7B,oBAC1BuJ,6BAA8BvkC,KAAKk9B,EACnCsH,6BAA8BxkC,KAAK2+B,GACnC8F,WAAYzkC,KAAK6jC,GAAYz6B,KAAKpJ,MAClC0kC,2BAA4B1kC,KAAKqhC,GAA4Bj4B,KAAKpJ,MAE1E,EAwEG,SAAS2kC,GAAgB7e,EAAkB8e,GAE9C,GAAKnwC,IAAaN,GAAlB,CAIA,IAeI0wC,EAfEC,EAAgB,IAAIxK,GAAcxU,GACxC,GAAIA,EAAQ4B,OAAOqd,kCAEf,OADA5vC,GAAOa,KAAK,4FACL8uC,EAKX,IAAyB,IAArBF,EAEA,OADAzvC,GAAOa,KAAK,gFACL8uC,EAGXA,EAAc3G,oCAAmC,GAIjD,IAAM6G,EAAgBA,KACbt3C,GAAYm3C,KAGjBA,EAAaI,aAAY,KACrBH,EAAc3G,oCAAmC,EAAM,GACxD,KAA0B,EAqBjC,OAXA6G,IAEArtC,GAAiBlD,GAAU,oBAAoB,KACvCA,GAASywC,OATRx3C,GAAYm3C,KACbM,cAAcN,GACdA,OAAazwC,IAUb0wC,EAAc3G,oCAAmC,GACjD6G,IACJ,IAGGF,CA9CP,CA+CJ,CAoBO,SAASM,GAAwBv/B,GAMN,IANOkM,OACrCA,EAAMoqB,sBACNA,EAAwBA,SAAQkJ,iBAChCA,EAAgBza,cAChBA,GAAgB,EAAK9E,QACrBA,GAC4BjgB,EAC5B2rB,IAAU,KAAM,IAAAvH,EACZ,IAAIW,GAAmC,OAAlBX,EAAClY,EAAOmY,aAAPD,EAAmB95B,IAAzC,CAIA,IAAMm1C,EAAgBA,KAAM,IAAAC,EAClBC,EAAqBzzB,EAAOrhB,OAASkf,GAAWG,OAChD01B,EAA8B9Z,GAAmB5Z,EAAQ+T,GACzD4f,GAAyC,OAAjBH,EAAAxzB,EAAO6B,iBAAU,EAAjB2xB,EAAmBnqB,cAAezM,GAAiBC,KAAO42B,EAExF,IAAIC,EAUJ,OAFAtwC,GAAOa,KAAI,iBAAkB+b,EAAO9V,kCACpCopC,GAAiB,GACVlJ,EAAsBpqB,GATrB2zB,IACAvwC,GAAOa,KAAI,kBAAmB+b,EAAO9V,2DACrCopC,GAAiB,GAOW,EAIxC1tC,GAAiBxD,GAAQ,WAAYmxC,GAGrC3tC,GAAiBxD,GAAQ,aAAcmxC,GAGvC,IAAMK,EAAoBxxC,GAAOyxC,QAAQC,UACnCC,EAAuB3xC,GAAOyxC,QAAQG,aAY5C,OAVA5xC,GAAOyxC,QAAQC,UAAY,WAAmB,IAAA,IAAApwC,EAAAC,UAAArE,OAANsE,EAAI,IAAAvI,MAAAqI,GAAAG,EAAA,EAAAH,EAAAG,EAAAA,IAAJD,EAAIC,GAAAF,UAAAE,GACxC+vC,EAAkB5lC,MAAMC,KAAMrK,GAC9B2vC,GACJ,EAEAnxC,GAAOyxC,QAAQG,aAAe,WAAmB,IAAA,IAAAjwC,EAAAJ,UAAArE,OAANsE,EAAI,IAAAvI,MAAA0I,GAAAC,EAAA,EAAAD,EAAAC,EAAAA,IAAJJ,EAAII,GAAAL,UAAAK,GAC3C+vC,EAAqB/lC,MAAMC,KAAMrK,GACjC2vC,GACJ,EAEO,KACHnxC,GAAOsV,oBAAoB,WAAY67B,GACvCnxC,GAAOsV,oBAAoB,aAAc67B,GACzCnxC,GAAOyxC,QAAQC,UAAYF,EAC3BxxC,GAAOyxC,QAAQG,aAAeD,CAAoB,CA5CtD,CA6CC,GACF,CAAClb,EAAe7Y,EAAQoqB,EAAuBkJ,EAAkBvf,GACxE,CAwJA,SAASkgB,GAAqB7qB,GAC1B,YADqD,IAA3BA,IAAAA,EAA8B1L,GAAkBF,OAClE4L,GACJ,KAAK1L,GAAkBC,IACnB,MAAO,CAAEif,IAAK,IAAKC,KAAM,MAAOC,UAAW,oBAC/C,KAAKpf,GAAkBJ,KACnB,MAAO,CAAEsf,IAAK,MAAOC,KAAM,IAAKC,UAAW,kCAAmCoX,gBAAiB,YACnG,KAAKx2B,GAAkBE,OACnB,MAAO,CAAEyqB,OAAQ,IAAKxL,KAAM,MAAOC,UAAW,oBAClD,QAGI,MAAO,CACHF,IAAK,MACLG,MAAO,IACPD,UAAW,mCACXoX,gBAAiB,aAGjC,CAEO,SAAS1J,GAAW51B,GAgBN,IAAAu/B,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,GAhBOx0B,OACxBA,EAAMkf,iBACNA,EAAgBnL,QAChBA,EAAOa,MACPA,EAAQ,CAAA,EAAEkE,iBACVA,EAAgBsR,sBAChBA,EAAwBA,SAAQpR,QAChCA,GAAU,EAAIC,gBACdA,EAAkBA,SAAQC,cAC1BA,EAAgBA,SAAQH,uBACxBA,EAAyBA,SAAQ0b,2BACjCA,EAA6BA,SAAQpe,WACrCA,EAAUD,kBACVA,EAAiBkU,eACjBA,EAAchU,eACdA,GACe1hB,EACT8/B,EAAqBrU,GAAuB,MAC5CxH,EAAgBhmB,OAAOmR,UAAU8U,GAEjC6b,EAAgD,OAAjBR,EAAAn0B,EAAO6B,aAAPsyB,EAAmBlqB,wBACN,IAA5CjK,EAAO6B,WAAWoI,wBAClB,GACA2qB,eAAEA,EAAcC,aAAEA,EAAYC,4BAAEA,GAjMnC,SACH90B,EACA+T,EACAghB,EACAlc,EACAuR,EACApR,EACA0b,EACApK,EACAhU,GAEA,IAAOse,EAAgBI,GAAqBzU,GACxC1H,GAAsC,IAArBkc,GAA0B/0B,EAAOrhB,OAASkf,GAAWI,iBAEnE42B,EAAcI,GAAmB1U,IAAS,GAE3CuU,EAA8BA,KAChC,IAAMI,EAAwBA,KACtBlc,GACAoR,EAAsBpqB,GAE1Bg1B,GAAkB,EAAM,EAGvBtyC,GAASyyC,oBAKKzyC,GAASyyC,qBAAoB,KAAM,IAAAC,EAChC,MAAlBV,GAA2B,OAATU,EAAlBV,EAAoB34B,UAApBq5B,EAA6BlD,QAAQ,IAG9BmD,SAAStjC,MAAK,KACrB/C,YAAW,KACPkmC,GAAuB,GACxB,IAAI,IAXPA,GAYF,EAGAI,EAAsBxvC,IACpBA,EAAM+wB,OAAOC,WAAa9W,EAAO9V,IAGrC4qC,GAA6B,EAiFjC,OA9EArV,IAAU,KACN,GAAK1L,GAIL,IAAI8E,EAAJ,CAIA,IAAM0c,EAAoBzvC,IAAuB,IAAA0vC,EAAAC,EAC7C,GAAI3vC,EAAM+wB,OAAOC,WAAa9W,EAAO9V,GAArC,CAGA,GAAsB,OAAlBsrC,EAACx1B,EAAO6B,cAAP2zB,EAAmBrsB,uBACpB,OAAO2rB,IAEXG,GAAgB,GACK,OAArBQ,EAAIz1B,EAAO6B,aAAP4zB,EAAmBC,eACnB1mC,YAAW,KACP8lC,GAA6B,GAC9B,IARP,CASA,EAGEa,EAAaA,KAEf,GAAK/b,GAAmB5Z,EAAQ+T,GAAhC,CAGAihB,GAAkB,GAClB5yC,GAAOu0B,cAAc,IAAIn6B,MAAM,kBAC1B8tC,GACDvW,EAAQ/tB,QAAQ6Y,GAAgBC,MAAKxO,EAAA,CACjC,CAAC4O,GAAsBE,aAAcY,EAAOnmB,KAC5C,CAACqlB,GAAsBC,WAAYa,EAAO9V,GAC1C,CAACgV,GAAsBG,kBAAmBW,EAAOW,kBACjD,CAACzB,GAAsBI,6BAA8BU,EAAOuW,8BACxDD,GAAkB,CAAE,CAACpX,GAAsBQ,iBAAkB4W,GAAgB,CACjFE,0BAAqBzC,EAAQ0C,8BAAR1C,EAAQ0C,4BAGrC,IACI/S,aAAaE,QAAQ,sBAAsB,IAAI1T,MAAO0lC,cAC1D,CAAE,MAAAr7C,GACE,CAhBJ,CAgBI,EAOR,GAHAqL,GAAiBxD,GAAQ,iBAAkBkzC,GAC3C1vC,GAAiBxD,GAAQ,eAAgBmzC,GAErCR,EAAmB,EAAG,CAGtB,IAAMtK,EAAYz7B,WAAW2mC,EAAYZ,GACzC,MAAO,KACH7iC,aAAau4B,GACbroC,GAAOsV,oBAAoB,iBAAkB49B,GAC7ClzC,GAAOsV,oBAAoB,eAAgB69B,EAAkC,CAErF,CAGI,OADAI,IACO,KACHvzC,GAAOsV,oBAAoB,iBAAkB49B,GAC7ClzC,GAAOsV,oBAAoB,eAAgB69B,EAAkC,CA1DrF,OALInyC,GAAOmB,MAAM,6DAiEjB,GACD,IAEH8uC,GAAyB,CACrBrzB,SACAoqB,wBACAkJ,iBAAkB0B,EAClBnc,gBACA9E,YAGG,CAAE6gB,iBAAgBC,eAAcG,oBAAmBF,8BAC9D,CAmE0Ee,CAClE71B,EACA+T,EACA4gB,EACA9b,EACAuR,EACApR,EACA0b,EACApK,EACAhU,GASEwf,EACFjB,GAAgB/b,IAAqB9Y,EAAOE,UAAU5gB,SAAgC,IAAtB82B,EAE9D2f,EAAqBpV,IAAQ,KAC/B,IAAMqV,EAAsB5e,GAAyBpX,GAC/CmW,GAAwC,MAAnB6f,OAAmB,EAAnBA,EAAqB7f,qBAAsB5P,KACtE,MAAO,CACHsS,gBACAC,iBAAkBA,EAClBC,sBAOA,GANQzC,EACAY,GAAqBlX,EAAQ+T,EAAS8E,EAAevC,GAErDY,GAAqBlX,EAAQ+T,EAAS8E,GAE1CE,GAAwB,EAE5BC,QAASA,IAAW,EACpB7C,qBACA8C,kBACAC,gBACAnF,UACAsC,aACAC,iBACH,GACF,CACCuC,EACAC,EACAE,EACAjF,EACA/T,EACA+Y,EACAE,EACAC,EACA7C,EACAC,IAGJ,OAAKse,EAKD3X,GAACtE,GAAcsd,SAAQ,CAAC37C,MAAOy7C,EAAmBxc,SAC9C0D,GAAA,MAAA,CACI3gC,UAAU,YACVs4B,MAAKtkB,EAAA,GACEosB,GAAmB1c,EAAOrhB,KAAuB,OAAnBy1C,EAAEp0B,EAAO6B,iBAAU,EAAjBuyB,EAAmBhrB,SAA2B,OAAnBirB,EAAEr0B,EAAO6B,iBAAU,EAAjBwyB,EAAmBhrB,YAChFuL,GAEPgN,IAAK8S,EAAmBnb,SAEtBuc,EAGE7Y,GAACsC,GAAmB,CAChBjoB,QAAyB,OAAjBg9B,EAAAt0B,EAAO6B,iBAAU,EAAjByyB,EAAmBxyB,wBAAyB,aACpDW,aAA8B,OAAjB8xB,EAAAv0B,EAAO6B,iBAAU,EAAjB0yB,EAAmBxyB,6BAA8B,GAC9Dmd,mBAAoBA,EACpBlyB,YAA8B,OAAnBwnC,EAAEx0B,EAAO6B,iBAAU,EAAjB2yB,EAAmB0B,sCAChCr0B,WAAY7B,EAAO6B,YAAc4G,GACjC+W,OAGA,GAFIsV,IACAL,GAA4B,IAVpCxX,GAACkZ,GAAS,CAACn2B,OAAQA,EAAQkf,mBAAoBA,EAAkBnL,QAASA,QAd/E,IA+Bf,CAEO,SAASoiB,GAASrhC,GAQtB,IAAAshC,EAAAC,GARuBr2B,OACtBA,EAAMkf,iBACNA,EAAgBnL,QAChBA,GAKHjf,GAEUwhC,EAAoBC,GAAyBhW,IAAS,KACzD,IAAMiW,EAAuBpf,GAAyBpX,GAItD,OAHwB,MAApBw2B,GAAAA,EAAsB12B,WACtB1c,GAAOa,KAAK,gEAEW,MAApBuyC,OAAoB,EAApBA,EAAsB12B,YAAa,CAAA,CAAE,KAE1CgZ,iBACFA,EAAgBC,uBAChBA,EAAsBC,QACtBA,EAAOC,gBACPA,EAAeC,cACfA,EAAa/C,mBACbA,EAAkB0C,cAClBA,EAAaxC,WACbA,EAAUC,eACVA,GACA8C,GAAWT,KACRqN,EAAsByQ,GAA2BlW,IAAS,KAC7D,IAAMiW,EAAuBpf,GAAyBpX,GACtD,OAAO8Y,IAAwC,MAApB0d,OAAoB,EAApBA,EAAsBnH,oBAAqB,CAAC,KAEpEqH,EAAgBC,GAAqBpW,IAAmB,KAAM,IAAAqW,EAC3DJ,EAAuBpf,GAAyBpX,GACtD,OAA2C,QAA3C42B,EAA2B,MAApBJ,OAAoB,EAApBA,EAAsBE,sBAAc,IAAAE,EAAAA,EAAI,EAAE,IAE/CC,EAAkBlW,IAAQ,IAAM5I,GAAyB/X,IAAS,CAACA,IAGzEyf,IAAU,KACF5G,IAAkBl9B,GAAYm9B,IAC9B2d,EAAwB3d,EAC5B,GACD,CAACA,EAAkBD,IAEtB,IAwFM4F,IACiB,OAAlB2X,EAACp2B,EAAO6B,cAAPu0B,EAAmBU,eAAgBje,GAAiBC,QAAAA,EAAoB,GAAK,EAAI4d,EAAep3C,OAAS,GAEzGy3C,EAAkBF,EAAgBG,GAAGhR,GAE3C,OAAK+Q,EAODnZ,GAAA,OAAA,CAAMthC,UAAU,cAAczC,KAAK,aAAY0/B,SAAA,CAHxBP,IAAmD,KAAvB,OAAjBqd,EAAAr2B,EAAO6B,iBAAU,EAAjBw0B,EAAmBvW,mBAK7C7C,GAACqC,GAAM,CACHR,OAEA,GADI/F,GAAwB,IAIpCkE,GAAA,MAAA,CAAK3gC,UAAU,aAAa,sBAAqB0pC,EAAqBzM,SACjE0d,GAAqB,CAClB92B,SAAU42B,EACV7X,mBACAgB,qBAAsB8F,EACtBnkB,WAAY7B,EAAO6B,YAAc4G,GACjC8V,SAAWjmB,GAlHDF,KAQpB,IARqBE,IACvBA,EAAG4nB,qBACHA,EAAoBtgB,WACpBA,GAKHxH,EACG,GAAK2b,EAKL,GAAKnU,EAAL,CAKA,IAAM+uB,EAAchvB,GAAqBC,GAEnCs3B,EAAY5mC,EAAA,CAAA,EAAQgmC,EAAkB,CAAE3H,CAACA,GAAcr2B,IAC7Di+B,EAAsBW,GAEtB,IAAM3Q,EAAWR,GAAkB/lB,EAAQkgB,EAAsB5nB,GAC3D8d,EAAoBmQ,IAAa/nB,GAA4BC,IAC7D04B,EAAoB,IAAIT,EAAgBxW,GAgB9C,GAdK9J,IACDugB,EAAkBQ,GAClBV,EAAwBlQ,GACxBjK,GAAyBtc,EAAQ,CAC7BmW,mBAAoBA,EACpBrW,UAAWo3B,EACX7H,kBAAmB9I,EACnBmQ,eAAgBS,EAChB7gB,oBAMJtW,EAAOgY,0BAA4B5B,EAAmB,CAGtD,IAAMghB,EAAsB,IAAIvO,IAC5BsO,EACK52B,KAAK3gB,IAAC,IAAAy3C,EAAA,OAAuB,OAAvBA,EAAKR,EAAgBj3C,SAAE,EAAlBy3C,EAAoBntC,EAAE,IACjCpB,QAAQoB,KAAuBA,IAC/BqW,KAAKrW,GAAOyV,GAAqBzV,MAEpCotC,EAAkBp9C,OAAOq9C,YAC3Br9C,OAAOuL,QAAQyxC,GAAcpuC,QAAO0uC,IAAA,IAAElyC,GAAIkyC,EAAA,OAAKJ,EAAoB3K,IAAInnC,EAAI,KAE/E4wB,GAAgB,CACZpW,UAAWw3B,EACXt3B,SACAmW,qBACAC,oBACArC,UACAsC,aACAC,kBAER,CA9CA,MAFIlzB,GAAOmB,MAAM,uDALbnB,GAAOmB,MAAM,uDAqDjB,EAoDgBkzC,CAAkB,CACdn/B,MACA4nB,qBAAsB8F,EACtBpmB,WAAYm3B,EAAgB7sC,KAEpC+uB,kBACAkH,aAAc4W,EAAgB7sC,GACxBosC,EAAmB32B,GAAqBo3B,EAAgB7sC,UACxD7H,EACNo8B,YACAC,MAAQgZ,GAzDpB,GAAI7e,EACAK,SAGJ,GAA8B,IAA1Bwd,EAAep3C,OAAnB,CAGA,IAAMq4C,EAAgBjB,EAAeA,EAAep3C,OAAS,GACvD63C,EAAoBT,EAAez0C,MAAM,GAAG,GAClD00C,EAAkBQ,GAClBV,EAAwBkB,GACxBrb,GAAyBtc,EAAQ,CAC7BmW,qBACArW,UAAWw2B,EACXjH,kBAAmBsI,EACnBjB,eAAgBS,EAChB7gB,kBAVJ,CAWE,SASK,IAoCf,CAEO,SAASuU,GAAc+M,GAYP,IAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,GAZQn4B,OAC3BA,EAAMkf,iBACNA,EAAgBnL,QAChBA,EAAOoD,SACPA,EAAQb,eACRA,GAOHshB,GACUQ,EAAyBC,GAA8B9X,IAAS,IAChEoV,EAAY2C,GAAiB/X,IAAS,IACtCgY,EAAgBC,GAAqBjY,GAA4B,CAAA,GAElEkY,EAAeA,KACjBH,GAAe3C,EAAW,EAiD9B,GA9CAlW,IAAU,KAAM,IAAAiZ,EACZ,GAAK3kB,GAIL,IAAIoD,EAAJ,CAIsC,SAAjB,OAAjBuhB,EAAA14B,EAAO6B,iBAAU,EAAjB62B,EAAmBrvB,aACnBmvB,EAAkB,CACd5b,IAAK,MACLyL,OAAQ,SAGhB,IAAMsQ,EAAoB7yC,IAAiB,IAAA8yC,EACjCC,EAAc/yC,GAEE,OAAlB8yC,EAAAC,EAAYhiB,aAAM,EAAlB+hB,EAAoB9hB,YAAa9W,EAAO9V,KACxC9G,GAAOa,KAAI,kDAAmD+b,EAAO9V,IACrEsuC,EAAkBK,EAAYhiB,OAAOzN,UAAY,CAAA,GACjDqvB,IACJ,EAMJ,OAHA7yC,GAAiBxD,GAAQslC,GAAgCiR,GAGlD,KACHv2C,GAAOsV,oBAAoBgwB,GAAgCiR,EAAiB,CAtBhF,OALIv1C,GAAOmB,MAAM,oDA4BhB,GACF,CACCwvB,EACAoD,EACAnX,EAAO9V,GACU,OADR2tC,EACT73B,EAAO6B,iBAAU,EAAjBg2B,EAAmBxuB,kBAAUyuB,EAC7B93B,EAAO6B,mBAAPi2B,EAAmBpO,eACF,OADgBqO,EACjC/3B,EAAO6B,iBAAU,EAAjBk2B,EAAmB/uB,cAGvBqqB,GAAyB,CACrBrzB,SACAszB,iBAAkB+E,EAClBtkB,aAGCqkB,EACD,OAAO,KAGX,IAAMU,EAAkBA,KAEhB94B,EAAOyY,WAAa7Z,IACpBy5B,GAA2B,GAG/BrpC,YAAW,KACPspC,GAAc,EAAM,GACrB,IAAI,EAGX,OACI1a,GAAC+D,GAAQ,CAAApI,SAAA,CAC8B,SAAjB,OAAjBye,EAAAh4B,EAAO6B,iBAAU,EAAjBm2B,EAAmB3uB,aAChB4T,GAAA,SAAA,CACI3gC,oCAAoD,OAAjB27C,EAAAj4B,EAAO6B,iBAAU,EAAjBo2B,EAAmBc,eAAgBr7B,GAAkBC,IAAM,iBAAmB,IACjHmhB,QAAS2Z,EACT5Z,SAAU1H,EACVvC,MAAOqf,GAAsC,OAAlBiE,EAACl4B,EAAO6B,iBAAU,EAAjBq2B,EAAmBa,aAAaxf,UAE1C,OAAjB4e,EAAAn4B,EAAO6B,iBAAU,EAAjBs2B,EAAmB7uB,cAAe,KAG1CqsB,GACG1Y,GAACuN,GAAW,CACRzW,QAASA,EACT/T,OAAQA,EACRkf,iBAAkBA,EAClBtK,MAAO2jB,EACPxf,uBAAwB+f,EACxBrE,2BAA4BqE,EAC5BxiB,eAAgBA,MAKpC,CAOA,IAAM2gB,GAAuB+B,IAUwB,IAVvB74B,SAC1BA,EAAQ+e,iBACRA,EAAgBgB,qBAChBA,EAAoBre,WACpBA,EAAU0c,SACVA,EAAQtF,gBACRA,EAAekH,aACfA,EAAY1B,UACZA,EAASC,OACTA,GACwBsa,EAClBC,EAAY,CACd/Z,mBACArd,aACAoX,eAEA,CAFkB3gB,GACd2gB,EAAgB3gB,EAAI,EAExBimB,QAEA,CAFWjmB,GACPimB,EAASjmB,EAAI,EAEjB6nB,eACAD,uBACAzB,YACAC,UAGJ,OAAQve,EAASxhB,MACb,KAAKuf,GAAmBC,KACpB,OAAO+6B,GAACjZ,GAAgB3vB,KAAK2oC,EAAS,CAAE94B,SAAUA,EAAU7a,IAAK6a,EAASjW,MAC9E,KAAKgU,GAAmBK,KACpB,OAAO26B,GAAC9W,GAAY9xB,KAAK2oC,EAAS,CAAE94B,SAAUA,EAAU7a,IAAK6a,EAASjW,MAC1E,KAAKgU,GAAmBI,OACpB,OAAO46B,GAAC7W,GAAc/xB,KAAK2oC,EAAS,CAAE94B,SAAUA,EAAU7a,IAAK6a,EAASjW,MAC5E,KAAKgU,GAAmBG,aACxB,KAAKH,GAAmBE,eACpB,OAAO86B,GAAC3V,GAAsBjzB,KAAK2oC,EAAS,CAAE94B,SAAUA,EAAU7a,IAAK6a,EAASjW,MACpF,QAEI,OADA9G,GAAOmB,MAAK,8BAAgC4b,EAAiBxhB,MACtD,KACf,EE1kDJkE,GAAiBmW,sBAAwBnW,GAAiBmW,uBAAyB,CAAA,EACnFnW,GAAiBmW,sBAAsB45B,gBAAkBA,GAIzD/vC,GAAiBs2C,yBAA2BvG,GCJ5C,IAgBMwG,GAAkBA,CAACh4C,EAAiByJ,EAAcwuC,IAChDA,EAAOC,UAAa,EAKpBzuC,EAAKvL,OAAU+5C,EAAOC,WAM1Bl4C,EAAMyI,KAAKgB,EAAK5I,MAAM,EAAGo3C,EAAOC,YAChCD,EAAOC,UAAY,EACnBD,EAAOE,WAAY,GACZ,IARHn4C,EAAMyI,KAAKgB,GACXwuC,EAAOC,WAAazuC,EAAKvL,QAClB,IAPP+5C,EAAOE,WAAY,GACZ,GAeTC,GAA2BA,CAACl/C,EAAe8G,EAAiBi4C,KAC9D,IAAMr3C,EAAaoN,KAAKC,UAAU/U,GAClC,GAAyB++C,EAAOC,WAA5Bt3C,EAAW1C,OACX,OAAO85C,GAAgBh4C,EAAOY,EAAYq3C,GAI9C,GADAA,EAAOE,WAAY,EACI,EAAnBF,EAAOC,UACP,OAAO,EAKX,IAFA,IAAIG,EAAM,EACNC,EAAO1pC,KAAKsC,IAAIhY,EAAMgF,OAAQ+5C,EAAOC,UAAY,GACxCI,EAAND,GAAY,CACf,IAAME,EAAM3pC,KAAK+T,MAAM01B,EAAMC,GAAQ,GACjCtqC,KAAKC,UAAU/U,EAAM2H,MAAM,EAAG03C,IAAMr6C,OAAU+5C,EAAOC,UAGrDI,EAAOC,EAAM,EAFbF,EAAME,CAId,CAEA,OAAOP,GAAgBh4C,EAAOgO,KAAKC,UAAU/U,EAAM2H,MAAM,EAAGw3C,IAAOJ,EAAO,EAGxEO,GAA+Bt/C,QAChB,IAAVA,GACU,mBAAVA,GACU,iBAAVA,GACU,iBAAVA,EAULu/C,GAAwBA,CAACv0C,EAAahL,EAAYw/C,KACpD,IAAIA,EAAUP,UAAd,CAMA,GAFAO,EAAUC,eAAiB,EAC3BD,EAAUE,eAAiBvwB,OAAOnvB,GAAOgF,OAASgG,EAAIhG,OACvB,GAA3Bw6C,EAAUC,eAAiD,GAA3BD,EAAUE,cAG1C,OAFAF,EAAUP,WAAY,OACtBO,EAAUp6C,OAA6B,sBAAI,GAI/Co6C,EAAUp6C,OAAO4F,GAAOhL,CAVxB,CAU6B,EAG3B2/C,GAA6BA,CAAC3/C,EAAYgL,EAAaw0C,KACzD,IAAIA,EAAUP,UAId,GAAI79C,GAASpB,GAAb,CACI,GAAIw/C,EAAUI,KAAKzN,IAAInyC,GAEnB,YADAu/C,GAAsBv0C,GAAO,WAAY,aAAcw0C,GAG3DA,EAAUI,KAAKhN,IAAI5yC,GAEnB,IACI,IAAK,IAAM6/C,KAAY7/C,EACnB,IACI,IAAKJ,CAAOD,EAAUgB,eAAeM,KAAKjB,EAAO6/C,GAC7C,SAIJ,GADAF,GADmB3/C,EAAM6/C,GACc70C,EAASA,EAAG,IAAI60C,EAAaA,EAAUL,GAC1EA,EAAUP,UACV,MAER,CAAE,MAAAjsC,GACE,QACJ,CAER,CAAE,MAAAgC,GACE,CAGR,MAEAuqC,GAAsBv0C,EAAKhL,EAAOw/C,EAAU,EAG1CM,GAA0B,SAC5B9/C,EACA8G,EACAi4C,EACAa,EACAG,EACAC,GAEA,QAHO,IAAPD,IAAAA,GAAU,IAGLT,GAA4Bt/C,GAC7B,OAAO+/C,GAAUjB,GAAgBh4C,EAAO,OAAQi4C,GAGpD,GAAIx9C,GAAOvB,IAxEYA,KACvB,IACI,OAAOyB,GAASzB,IAAU0B,GAAU1B,EACxC,CAAE,MAAAC,GACE,OAAO,CACX,GAmEqBggD,CAAkBjgD,GACnC,OAAO8+C,GAAgBh4C,EAAOgO,KAAKC,UAAU/U,GAAQ++C,GAGzD,GAAqB,iBAAV/+C,EACP,OAAOk/C,GAAyBl/C,EAAO8G,EAAOi4C,GAGlD,IAAK39C,GAASpB,KAAWc,GAAQd,GAC7B,OAAO8+C,GAAgBh4C,EAAOgO,KAAKC,UAAU/U,GAAQ++C,GAGzD,GAAIa,EAAKzN,IAAInyC,GACT,OAAOk/C,GAAyB,aAAcp4C,EAAOi4C,GAEzDa,EAAKhN,IAAI5yC,GAET,IACI,IAAMiW,EAAUjW,EAAciW,OAC9B,GAAI/U,GAAW+U,GACX,OAAO6pC,GAAwB7pC,EAAOhV,KAAKjB,GAAQ8G,EAAOi4C,EAAQa,EAAMG,EAEhF,CAAE,MAAAtnC,GACE,CAGJ,IACI,IAAMynC,EAAYtgD,CAAOD,EAAUkB,SAASI,KAAKjB,GACjD,GAAkB,oBAAdkgD,EACA,OAAOhB,GAAyB/vB,OAAOnvB,EAAMmgD,WAAYr5C,EAAOi4C,GAGpE,GAAkB,oBAAdmB,GAAiD,qBAAdA,EACnC,OAAOpB,GAAgBh4C,EAAOgO,KAAKC,UAAU/U,EAAMmgD,WAAYpB,EAEvE,CAAE,MAAAlnC,GACE,CAGJ,GAAI7X,aAAiBsqB,MAAO,CACxB,IAAM81B,EAAmC,CAAA,EACzC,IACI,IAAK,IAAMp1C,KAAOhL,GACVJ,CAAOD,GAAUgB,eAAeM,KAAKjB,EAAOgL,KAC5Co1C,EAAYp1C,GAAOhL,EAAMgL,GAGrC,CAAE,MAAA+N,GAAO,CACT,IACIqnC,EAAY7gD,KAAOS,EAAMT,IAC7B,CAAE,MAAA0Z,GAAO,CACT,IACImnC,EAAYC,QAAUrgD,EAAMqgD,OAChC,CAAE,MAAAlmC,GAAO,CACT,IACIimC,EAAYE,MAAQtgD,EAAMsgD,KAC9B,CAAE,MAAAnnC,GAAO,CACT,OAAO2mC,GAAwBM,EAAat5C,EAAOi4C,EAAQa,EAAMG,EAASC,EAC9E,CAEA,GAAIl/C,GAAQd,GAAQ,CAChB,IAAK8+C,GAAgBh4C,EAAO,IAAKi4C,GAC7B,OAAO,EAEX,IAAK,IAAIz5C,EAAI,EAAOtF,EAAMgF,OAAVM,EAAkBA,IAAK,CACnC,GAAIA,EAAI,IAAMw5C,GAAgBh4C,EAAO,IAAKi4C,GACtC,OAAO,EAEX,IAAIrZ,OAAI,EACR,IACIA,EAAO1lC,EAAMsF,EACjB,CAAE,MAAAi7C,GACE7a,OAAO39B,CACX,CACA,IAAK+3C,GAAwBpa,EAAM5+B,EAAOi4C,EAAQa,GAAM,GACpD,OAAO,CAEf,CACA,OAAOd,GAAgBh4C,EAAO,IAAKi4C,EACvC,CAEA,IAAKD,GAAgBh4C,EAAO,IAAKi4C,GAC7B,OAAO,EAEX,IAAIyB,GAAU,EACd,IACI,IAAK,IAAMx1C,KAAOhL,EACd,GAAKJ,CAAOD,EAAUgB,eAAeM,KAAKjB,EAAOgL,GAAjD,CAGA,GAAwB,GAApB+zC,EAAOC,UAEP,OADAD,EAAOE,WAAY,GACZ,EAGX,IAAIwB,OAAa,EACjB,IACIA,EAAgBzgD,EAAMgL,EAC1B,CAAE,MAAA01C,GACE,QACJ,CACA,GAAIV,EACA,IACIL,GAA2Bc,EAAez1C,EAAKg1C,EACnD,CAAE,MAAAW,GACE,CAIR,GAAKrB,GAA4BmB,GAAjC,CAIA,IAAMG,GAAoBJ,EAAU,GAAK,KAAM1rC,KAAKC,UAAU/J,GAAI,IAClE,GAAI41C,EAAe57C,QAAU+5C,EAAOC,UAEhC,OADAD,EAAOE,WAAY,GACZ,EAGX,IAAM4B,EAAsB/5C,EAAM9B,OAC5B87C,EAA0B/B,EAAOC,UACjC+B,EAA0BhC,EAAOE,UACvC,IAAKH,GAAgBh4C,EAAO85C,EAAgB7B,GACxC,OAAO,EAGX,IAAMiC,EAAmBl6C,EAAM9B,OACzB0C,EAAao4C,GAAwBW,EAAe35C,EAAOi4C,EAAQa,GAAM,GACzEqB,EAAsBlC,EAAOE,UACnC,GAAIn4C,EAAM9B,SAAWg8C,GAWrB,GADAR,GAAU,GACL94C,EACD,OAAO,OARP,GAHAZ,EAAM9B,OAAS67C,EACf9B,EAAOC,UAAY8B,EACnB/B,EAAOE,UAAYv3C,EAAaq5C,EAA0BE,GACrDv5C,EACD,OAAO,CAvBf,CAtBA,CAuDR,CAAE,MAAAw5C,GACE,CAEJ,OAAOpC,GAAgBh4C,EAAO,IAAKi4C,EACvC,EA+CMoC,GAAoD,CACtD33C,MAAO,QACP43C,IAAK,OACLt3C,KAAM,OACNG,MAAO,QACPN,KAAM,QAgDVpB,GAAiBmW,sBAAwBnW,GAAiBmW,uBAAyB,CAAA,EACnFnW,GAAiBmW,sBAAsB2iC,KAAO,CAAEC,cAAAA,CA9CxB7nB,GAIpB,IAAM8nB,EAAqC,CAAE9zC,KAAMlF,GAAiBs3B,SAASpyB,MAAM+zC,EAAA,SAAAx4C,GAI1Ey4C,MAiCLl5C,GAAiBW,QAAQF,IAjCpBy4C,EAgCsBl5C,GAAiBW,QAAQF,GA/BhD,WAAoB,IAAA,IAAAI,EAAAC,UAAArE,OAAhBsE,EAAI,IAAAvI,MAAAqI,GAAAM,EAAA,EAAAN,EAAAM,EAAAA,IAAJJ,EAAII,GAAAL,UAAAK,GACJ,IACI,GAAIJ,EAAKtE,OAAS,GAAKy0B,EAAQioB,eAAgB,CAAA,IAAAC,GACrC9sC,KACFA,EAAIoqC,UACJA,EACAsC,WAAYK,GApEZC,EACxBv4C,EACAw4C,KAcA,IAZA,IAAMh7C,EAAkB,GAClBi4C,EAAS,CAAEC,UApSO,IAoSeC,WAAW,GAC5Ce,EAAqB5+C,GAASkI,EAAK,IACnC,CACIlE,OAAQ,CAAA,EACRq6C,cAvSe,GAwSfC,cAzSc,IA0SdT,WAAW,EACXW,KAAM,IAAImC,QAAgB,CAACz4C,EAAK,WAEpCvB,EAEGzC,EAAI,EAAOgE,EAAKtE,OAATM,IACJ,GAAJA,GAAUw5C,GAAgBh4C,EAAO,IAAKi4C,KAIrCe,GACGx2C,EAAKhE,GACLwB,EACAi4C,EACA,IAAIgD,SACJ,EACM,IAANz8C,EAAU06C,OAAqBj4C,GAXVzC,KAkBjC,MAAO,CACHuP,KAAM/N,EAAMc,KAAK,KAAOm3C,EAAOE,UAAY,MAAQ,IACnDA,UAAWF,EAAOE,UAClBsC,YAA8B,MAAlBvB,OAAkB,EAAlBA,EAAoB56C,SAAU,CAAA,EAC7C,EA+BuBy8C,CAAoBv4C,GAClB04C,EAAahsC,KACZurC,EACCtC,EAAY,CAAEgD,eAAgB,QAAW,IAGrC,OAAZN,EAAAloB,EAAQ4nB,OAARM,EAAcO,GAAmB,CAC7Bl5C,MAAOm4C,GAAUn4C,GACjB6L,OACA0sC,WAAUvrC,EAAA,CACN,aAAY,WAAahN,GACtBg5C,EACAJ,IAGf,CACJ,CAAE,MAAAO,GAEE,CACH,QACGV,EAAmB/tC,MAAMnL,GAAiBW,QAASI,EACvD,CACJ,EAIR,EApCA,IAAK,IAAMN,KAASpJ,OAAOmF,KAAKo8C,IAAUK,EAAAx4C,EAAA,GCvV/ByB,GAAa,oBCF5B,IAAM3B,GAAS2B,GAAa,0BACtB23C,GDIK,IERX,MACIx4B,WAAAA,CAAYy4B,EAAU39C,EAAa49C,QAAS,IAATA,IAAAA,EAAY,IAC3C3uC,KAAK0uC,SAAWA,EAChB1uC,KAAKjP,YAAcA,EACnBiP,KAAK2uC,UAAYA,CACrB,CACAC,gBAAAA,CAAiB1xC,EAAO2xC,QAAI,IAAJA,IAAAA,EAAO,CAAA,GAC3B,IACMC,EADoBD,GAAQA,EAAKC,WACA,CACnCC,SAAS,EACTr+C,KAAM,WAGJs+C,EADkBhvC,KAAKivC,qBAAqBH,EAAWD,EAAM,GACxB9uC,MAAM7C,GAC3CgyC,EAAiBlvC,KAAKmvC,oBAAoBN,GAC1CO,EAAqBpvC,KAAKqvC,gBAAgBL,EAAoBE,GAEpE,MAAO,CACHI,gBAFkBtvC,KAAKuvC,uBAAuBH,EAAoBN,GAGlEU,iBAAkB,QAE1B,CACMC,YAAAA,CAAaC,GAAe,IAAAnV,EAAAv6B,KAAA,OAAAC,GAAA,YAC9B,IAAK,IAAM0vC,KAAOD,EAAkBC,EAAIC,YAAcD,EAAIC,WAAWC,QAAU1iD,GAAQwiD,EAAIC,WAAWC,UAASF,EAAIC,WAAWC,aAAetV,EAAKuV,eAAeH,EAAIC,WAAWC,SAChL,OAAOH,CAAc,GAFSzvC,EAGlC,CACA8vC,cAAAA,CAAeC,GAAK,IAAAC,EAChB,MAAO,CACHv/C,KAAM,QACNrE,MAAO,gBACPsgD,MAA6B,OAAxBsD,EAAED,EAAIE,yBAAkB,EAAtBD,EAAwBtD,MAC/BwD,WAAW,EAEnB,CACAd,eAAAA,CAAgBz7C,EAAKo8C,GACjB,IAAII,EAEAzD,EAEJ,OAHI,MAAQ/4C,EAAIw8C,QAAOA,EAAQpwC,KAAKqvC,gBAAgBz7C,EAAIw8C,MAAOJ,IAE3D,IAAMp8C,EAAI+4C,OAAS,MAAQ/4C,EAAI+4C,QAAOA,EAAQ3sC,KAAKqwC,cAAcrwC,KAAKjP,YAAY6C,EAAI+4C,MAAO/4C,EAAIu8C,UAAYH,EAAIM,eAAiB,GAAIN,EAAIh/C,aAC9IqR,KACOzO,EAAG,CACNw8C,QACAzD,SAER,CACA0D,aAAAA,CAAcR,EAAQ7+C,GAClB,OAAO6+C,EAAOv9B,KAAKjgB,IACXA,EAAMR,UAAYb,IAAYqB,EAAMk+C,SAAWv/C,EAAWqB,EAAMR,WAC7DQ,IAEf,CACAm+C,aAAAA,CAActzC,EAAO8yC,GACjB,IAAK,IAAMS,KAAWzwC,KAAK0uC,SAAS,GAAI+B,EAAQhrB,MAAMvoB,GAAQ,OAAOuzC,EAAQC,OAAOxzC,EAAO8yC,GAC3F,OAAOhwC,KAAK+vC,eAAeC,EAC/B,CACMF,cAAAA,CAAeD,GAAQ,IAAAc,EAAA3wC,KAAA,OAAAC,GAAA,YACzB,IAAI2wC,EAAYf,EAChB,IAAK,IAAMgB,KAAYF,EAAKhC,UAAUiC,QAAkBC,EAASD,GACjE,OAAOA,CAAU,GAHQ3wC,EAI7B,CACAsvC,sBAAAA,CAAuBH,EAAoBN,GAAW,IAAAgC,EAAAC,EAAAC,EAC5CC,EAAmB,CACrBvgD,KAAM0+C,EAAmB1+C,KACzBrE,MAAO+iD,EAAmB/iD,MAC1ByiD,UAAW,CACPp+C,KAAoB,QAAhBogD,EAAEhC,EAAUp+C,YAAI,IAAAogD,EAAAA,EAAI,UACxB/B,QAA0B,QAAnBgC,EAAEjC,EAAUC,eAAO,IAAAgC,GAAAA,EAC1BZ,UAAuC,QAA9Ba,EAAE5B,EAAmBe,iBAAS,IAAAa,GAAAA,IAG3C5B,EAAmBzC,QAAOsE,EAAiBrB,WAAa,CACxDl/C,KAAM,MACNm/C,OAAQT,EAAmBzC,QAE/B,IAAM+C,EAAgB,CAClBuB,GAMJ,OAJI,MAAQ7B,EAAmBgB,OAAOV,EAAc9zC,QAAQoE,KAAKuvC,uBAAuBH,EAAmBgB,MAAK/tC,EAAA,CAAA,EACzGysC,EAAS,CACZC,SAAS,MAENW,CACX,CACAP,mBAAAA,CAAoBN,GAAM,IAAAqC,EAKtB,MAJgB,CACZlgD,WAAYF,GAAwBkP,KAAKjP,aACzCu/C,eAAmC,QAArBY,EAAErC,EAAKyB,sBAAc,IAAAY,EAAAA,EAAI,EAG/C,CACAjC,oBAAAA,CAAqBH,EAAWD,EAAMsC,QAAK,IAALA,IAAAA,EAAQ,GAC1C,IAAMT,EAASA,CAACxzC,EAAOi0C,KACnB,GA7FgB,GA6FVA,EAAN,CAEI,IAAMnB,EAAMhwC,KAAKivC,qBAAqBH,EAAWD,EAAMsC,GACvD,OAAOnxC,KAAKwwC,cAActzC,EAAO8yC,EAHA,CAIrC,EASJ,OAPa3tC,EAAA,CAAA,EACNwsC,EAAI,CACPqB,mBAAoB,GAAKiB,EAAQtC,EAAKqB,wBAAqB,EAC3DpB,YACA/uC,MAAQ7C,GAAQwzC,EAAOxzC,EAAOi0C,GAC9BC,KAAOl0C,GAAQwzC,EAAOxzC,EAAOi0C,EAAQ,IAG7C,GFjGI,CACI,IGZZ,MACI1rB,KAAAA,CAAM7xB,GACF,OAAOoM,KAAKqxC,eAAez9C,IAAQoM,KAAKsxC,WAAW19C,EACvD,CACA88C,MAAAA,CAAO98C,EAAKo8C,GACR,IAAMuB,EAAW5jD,GAASiG,EAAI+4C,OAC9B,MAAO,CACHj8C,KAAMsP,KAAKwxC,QAAQ59C,GACnBvH,MAAO2T,KAAKyxC,SAAS79C,GACrB+4C,MAAO4E,EAAW39C,EAAI+4C,WAAQ,EAC9ByD,MAAOx8C,EAAIw8C,MAAQJ,EAAIoB,KAAKx9C,EAAIw8C,YAAS,EACzCD,WAAW,EAEnB,CACAqB,OAAAA,CAAQpjD,GACJ,OAAO4R,KAAKsxC,WAAWljD,GAAa,WAAa,cACrD,CACAqjD,QAAAA,CAAS79C,GACL,IAAMhI,EAAOgI,EAAIhI,OAASoU,KAAKsxC,WAAW19C,GAAO,WAAa,gBAE9D,OADgBA,EAAI84C,QAAa9gD,EAAI,KAAKgI,EAAI84C,QAAY9gD,CAE9D,CACAylD,cAAAA,CAAez9C,GACX,OAAOzF,GAAUyF,EAAK,eAC1B,CACA09C,UAAAA,CAAW19C,GACP,OAAOzF,GAAUyF,EAAK,WAC1B,GHdQ,IIbZ,MACI6xB,KAAAA,CAAM7xB,GACF,OAAOzF,GAAUyF,EAAK,0BAA4BoM,KAAK0xC,+BAA+B99C,EAC1F,CACA89C,8BAAAA,CAA+B99C,GAC3B,IAAKtF,GAAQsF,GAAM,OAAO,EAC1B,IACI,IAAMg1B,EAASh1B,EAAIg1B,OACnB,OAAO,MAAQA,GAAU,iBAAmBA,GAAU,WAAYA,CACtE,CAAE,MAAAt8B,GACE,OAAO,CACX,CACJ,CACAokD,MAAAA,CAAO98C,EAAKo8C,GAAK,IAAAC,EACPzsC,EAASxD,KAAK2xC,4BAA4B/9C,GAChD,OAAI1F,GAAYsV,GAAgB,CAC5B9S,KAAM,qBACNrE,MAAK,oDAAsDmvB,OAAOhY,GAClEmpC,MAA6B,OAAxBsD,EAAED,EAAIE,yBAAkB,EAAtBD,EAAwBtD,MAC/BwD,WAAW,GAERH,EAAIjwC,MAAMyD,EACrB,CACAmuC,2BAAAA,CAA4Br7C,GACxB,IACI,GAAI,WAAYA,EAAO,OAAOA,EAAMkN,OACpC,GAAI,WAAYlN,GAAS,MAAQA,EAAMsyB,QAAU,iBAAmBtyB,EAAMsyB,QAAU,WAAYtyB,EAAMsyB,OAAQ,OAAOtyB,EAAMsyB,OAAOplB,MACtI,CAAE,MAAAnE,GAAQ,CACV,OAAO/I,CACX,GJfQ,IKdZ,MACI2f,WAAAA,GAAc,CACdwP,KAAAA,CAAM7xB,GACF,O1D+CGzF,G0D/CiByF,E1D+CA,e0D/CQ,MAAUA,EAAI0C,KAC9C,CACAo6C,MAAAA,CAAO98C,EAAKo8C,GAAK,IAAAC,EAEb,OADsBD,EAAIjwC,MAAMnM,EAAI0C,QACT,CACvB5F,KAAM,aACNrE,MAAOuH,EAAI84C,QACXC,MAA6B,OAAxBsD,EAAED,EAAIE,yBAAkB,EAAtBD,EAAwBtD,MAC/BwD,WAAW,EAGnB,GLCQ,IMfZ,MACI1qB,KAAAA,CAAM7xB,GACF,OAAoBA,a3D0BW+iB,K2DzBnC,CACA+5B,MAAAA,CAAO98C,EAAKo8C,GACR,MAAO,CACHt/C,KAAMsP,KAAKwxC,QAAQ59C,GACnBvH,MAAO2T,KAAK4xC,WAAWh+C,EAAKo8C,GAC5BrD,MAAO3sC,KAAK6xC,SAASj+C,GACrBw8C,MAAOx8C,EAAIw8C,MAAQJ,EAAIoB,KAAKx9C,EAAIw8C,YAAS,EACzCD,WAAW,EAEnB,CACAqB,OAAAA,CAAQ59C,GACJ,OAAOA,EAAIhI,MAAQgI,EAAIqiB,YAAYrqB,IACvC,CACAgmD,UAAAA,CAAWh+C,EAAKk+C,GACZ,IAAMpF,EAAU94C,EAAI84C,QACpB,OAAsElxB,OAAlEkxB,EAAQp2C,OAAS,iBAAmBo2C,EAAQp2C,MAAMo2C,QAAuBA,EAAQp2C,MAAMo2C,QAC7EA,EAClB,CACAmF,QAAAA,CAASj+C,GACL,OAAOA,EAAIg8C,YAAch8C,EAAI+4C,YAAS,CAC1C,GNPQ,IOfZ,MACIlnB,KAAAA,CAAM7xB,GACF,OAAOtF,GAAQsF,EACnB,CACA88C,MAAAA,CAAOqB,EAAK/B,GAAK,IAAAC,EACP+B,EAAkBD,EAAI97B,YAAYrqB,KACxC,MAAO,CACH8E,KAAMshD,EACN3lD,MAAU2lD,EAAe,qCAAqCr+C,GAA+Bo+C,GAC7FpF,MAA6B,OAAxBsD,EAAED,EAAIE,yBAAkB,EAAtBD,EAAwBtD,MAC/BwD,WAAW,EAEnB,GPIQ,IQfZ,MACI1qB,KAAAA,CAAMr3B,GACF,MAAO,iBAAmBA,GAAa,OAASA,CACpD,CACAsiD,MAAAA,CAAOtiD,EAAW4hD,GAAK,IAAAC,EACbgC,EAAgBjyC,KAAKkyC,2BAA2B9jD,GACtD,OAAI6jD,EAAsBjC,EAAIjwC,MAAMkyC,GAC7B,CACHvhD,KAAMsP,KAAKwxC,QAAQpjD,GACnB/B,MAAO2T,KAAKyxC,SAASrjD,GACrBu+C,MAA6B,OAAxBsD,EAAED,EAAIE,yBAAkB,EAAtBD,EAAwBtD,MAC/Bt3C,MAAO2K,KAAKmyC,gBAAgB/jD,EAAUiH,OAASjH,EAAUiH,MAAQ,QACjE86C,WAAW,EAEnB,CACAqB,OAAAA,CAAQ59C,GACJ,OAAOtF,GAAQsF,GAAOA,EAAIqiB,YAAYrqB,KAAO,OACjD,CACA6lD,QAAAA,CAAS79C,GACL,GAAI,SAAUA,GAAO,iBAAmBA,EAAIhI,KAAM,CAC9C,IAAI8gD,EAAO,IAAO94C,EAAIhI,KAAI,0BAE1B,MADI,YAAagI,GAAO,iBAAmBA,EAAI84C,UAASA,GAAO,mBAAuB94C,EAAI84C,QAAO,KAC1FA,CACX,CACA,GAAI,YAAa94C,GAAO,iBAAmBA,EAAI84C,QAAS,OAAO94C,EAAI84C,QACnE,IAAMr+C,EAAY2R,KAAKoyC,mBAAmBx+C,GAE1C,OAAUvF,GAAa,WAAaA,MAAgBA,EAAS,IAAM,UAAQ,qCAD9DsF,GAA+BC,EAEhD,CACAu+C,eAAAA,CAAgB3kD,GACZ,OAAOG,GAASH,K7DZDA,IAAIG,GAASH,IAAM,IAAMA,EAAEX,OAAOwE,O6DY1BghD,CAAc7kD,IAAMkG,GAAe9G,QAAQY,IAAM,CAC5E,CACA0kD,0BAAAA,CAA2B7kD,GACvB,IAAI,IAAMkK,KAAQlK,EAAI,GAAIpB,CAAOD,EAAUgB,eAAeM,KAAKD,EAAKkK,GAAO,CACvE,IAAMlL,EAAQgB,EAAIkK,GAClB,GAAYlL,a3DkBUsqB,M2DlBF,OAAOtqB,CAC/B,CACJ,CACA+lD,kBAAAA,CAAmB/kD,GACf,IACI,IAAMrB,EAAYC,OAAOqmD,eAAejlD,GACxC,OAAOrB,EAAYA,EAAUiqB,YAAYrqB,UAAO,CACpD,CAAE,MAAOoR,GACL,MACJ,CACJ,GR7BQ,I3ClBZ,MACIyoB,KAAAA,CAAMvoB,GACF,MAAO,iBAAmBA,CAC9B,CACAwzC,MAAAA,CAAOxzC,EAAO8yC,GAAK,IAAAC,GACRv/C,EAAMrE,GAAS2T,KAAKuyC,SAASr1C,GACpC,MAAO,CACHxM,KAAMA,QAAAA,EAAQ,QACdrE,MAAOA,QAAAA,EAAS6Q,EAChByvC,MAA6B,OAAxBsD,EAAED,EAAIE,yBAAkB,EAAtBD,EAAwBtD,MAC/BwD,WAAW,EAEnB,CACAoC,QAAAA,CAASnkD,GACL,IAAIsC,EAAO,QACPrE,EAAQ+B,EACNokD,EAASpkD,EAAUq3B,MAAMhyB,IAK/B,OAJI++C,IACA9hD,EAAO8hD,EAAO,GACdnmD,EAAQmmD,EAAO,IAEZ,CACH9hD,EACArE,EAER,G2CNQ,ISnBZ,MACIo5B,KAAAA,CAAMr3B,GACF,OAAOF,GAAYE,EACvB,CACAsiD,MAAAA,CAAOrkD,EAAO2jD,GAAK,IAAAC,EACf,MAAO,CACHv/C,KAAM,QACNrE,MAAK,0CAA4CmvB,OAAOnvB,GACxDsgD,MAA6B,OAAxBsD,EAAED,EAAIE,yBAAkB,EAAtBD,EAAwBtD,MAC/BwD,WAAW,EAEnB,IrDYJ,SAA2Bl+C,GAAsB,IAAA,IAAAwD,EAAAC,UAAArE,OAATohD,MAAOrlD,MAAAqI,EAAA,EAAAA,OAAAG,EAAA,EAAAH,EAAAG,EAAAA,IAAP68C,EAAO78C,EAAA,GAAAF,UAAAE,GAC3C,OAAO,SAAC+2C,EAAO2D,QAAc,IAAdA,IAAAA,EAAiB,GAG5B,IAFA,IAAMT,EAAS,GACT6C,EAAQ/F,EAAMv8C,MAAM,MAClBuB,EAAI2+C,EAAoBoC,EAAMrhD,OAAVM,EAAkBA,IAAI,CAC9C,IAAMoB,EAAO2/C,EAAM/gD,GACnB,GAAkB,MAAdoB,EAAK1B,OAAT,CACA,IAAMshD,EAAcn/C,GAAqB0I,KAAKnJ,GAAQA,EAAKgI,QAAQvH,GAAsB,MAAQT,EACjG,IAAK4/C,EAAYltB,MAAM,cAAe,CAClC,IAAK,IAAMmtB,KAAUH,EAAQ,CACzB,IAAMpgD,EAAQugD,EAAOD,EAAa1gD,GAClC,GAAII,EAAO,CACPw9C,EAAOj0C,KAAKvJ,GACZ,KACJ,CACJ,CACA,GAAIw9C,EAAOx+C,QAjCI,GAiC8B,KACjD,CAXwB,CAY5B,CACA,OAnCR,SAA+Bs7C,GAC3B,IAAKA,EAAMt7C,OAAQ,MAAO,GAC1B,IAAMwhD,EAAazlD,MAAMmxC,KAAKoO,GAE9B,OADAkG,EAAWhpB,UACJgpB,EAAW7+C,MAAM,EALG,IAKwBse,KAAKjgB,IAAKgQ,YAClDhQ,EAAK,CACRR,SAAUQ,EAAMR,WAIDihD,EAJ+BD,EAK/CC,EAAIA,EAAIzhD,OAAS,IAAM,CAAA,GALoCQ,SAC1DS,SAAUD,EAAMC,UAAYP,KAGxC,IAA2B+gD,CAFjB,GACV,CA0BeC,CAAsBlD,EACjC,CACJ,CAvBWmD,CAAkB,iBAAkBlgD,GAAuBS,K6CkEhE0/C,GAAgC,CAClCC,WAAAA,CAhFiBC,GACjB,IAAMj/C,EAAMC,GACPD,GACDiB,GAAOa,KAAK,6CAEhB,IAAMo9C,EAAkBl/C,EAAIm/C,QAa5B,OAXAn/C,EAAIm/C,QAAU,WAA4C,IAAA,IAAAC,EAAA79C,EAAAC,UAAArE,OAA/BsE,EAAI,IAAAvI,MAAAqI,GAAAG,EAAA,EAAAH,EAAAG,EAAAA,IAAJD,EAAIC,GAAAF,UAAAE,GAC3B,IAEM29C,EAAkB9E,GAAuBG,iBAFjCj5C,EAAK,IACLA,EAAK,GAC6D,CAC5Em5C,UAAW,CAAEC,SAAS,KAG1B,OADAoE,EAAUI,GACuB,QAAjCD,EAAsB,MAAfF,OAAe,EAAfA,KAAqBz9C,UAAK,IAAA29C,GAAAA,CACrC,EACAp/C,EAAIm/C,QAAQG,0BAA2B,EAEhC,KAAM,IAAAC,EACS,OAAlBA,EAAOv/C,EAAIm/C,iBAAJI,EAAaD,yBACpBt/C,EAAIm/C,QAAUD,CAAe,CAChC,EA4DDM,sBAAAA,CAzD4BP,GAC5B,IAAMj/C,EAAMC,GACPD,GACDiB,GAAOa,KAAK,0DAGhB,IAAM29C,EAA+Bz/C,EAAI0/C,qBAWzC,OATA1/C,EAAI0/C,qBAAuB,SAAUC,GAAoC,IAAAC,EAC/DP,EAAkB9E,GAAuBG,iBAAiBiF,EAAI,CAChE/E,UAAW,CAAEC,SAAS,KAG1B,OADAoE,EAAUI,GAC+B,QAAzCO,EAAmC,MAA5BH,OAA4B,EAA5BA,EAA+BE,UAAG,IAAAC,GAAAA,CAC7C,EACA5/C,EAAI0/C,qBAAqBJ,0BAA2B,EAE7C,KAAM,IAAAO,EACsB,OAA/BA,EAAO7/C,EAAI0/C,8BAAJG,EAA0BP,yBACjCt/C,EAAI0/C,qBAAuBD,CAA4B,CAC1D,EAsCDK,gBAAAA,CAnCsBb,GACtB,IAAMc,EAAM1+C,QACP0+C,GACD9+C,GAAOa,KAAK,oDAGhB,IAAMk+C,EAAuBD,EAAI39C,MAoBjC,OAlBA29C,EAAI39C,MAAQ,WACC,IAAT,IAAIuB,EAAK/B,EAAAJ,UAAArE,OADYsE,EAAI,IAAAvI,MAAA0I,GAAAC,EAAA,EAAAD,EAAAC,EAAAA,IAAJJ,EAAII,GAAAL,UAAAK,GAGrB8B,EADe,GAAflC,EAAKtE,OACGsE,EAAK,GAELA,EAAK1B,KAAK,KAEtB,IAAMqC,EAAQX,EAAK/E,MAAMujD,GAAQA,aAAex9B,QAC1C48B,EAAkB9E,GAAuBG,iBAAiBt4C,GAASuB,EAAO,CAC5Ei3C,UAAW,CAAEC,SAAS,GACtBmB,mBAAoB,IAAIv5B,MAAM,8BAC9B25B,eAAgB,IAGpB,OADA6C,EAAUI,GACiB,MAApBW,OAAoB,EAApBA,KAA0Bv+C,EACrC,EACAs+C,EAAI39C,MAAMk9C,0BAA2B,EAE9B,KAAM,IAAAY,EACO,OAAhBA,EAAOH,EAAI39C,eAAJ89C,EAAWZ,yBAClBS,EAAI39C,MAAQ49C,CAAoB,CACnC,GASLt/C,GAAiBmW,sBAAwBnW,GAAiBmW,uBAAyB,CAAA,EACnFnW,GAAiBmW,sBAAsBspC,uBAAyBpB,GAOhEr+C,GAAiBq+C,8BAAgCA,GS/FjD,IAAMqB,GAAoB,uBACpBC,GAAmB,sBACnBC,GAAqB,wBACrBC,GAAkB,CAACH,GAAmBC,GAAkBC,IACxDE,GAAoB,CACtB,uBACA,OACA,iBACA,QACA,cACA,aACA,SACA,YACA,YACA,SACA,OACA,WACA,WACA,WACA,iBACA,SACA,UAGE1nD,GAAiBA,CAACX,EAAesoD,KACnC1oD,CAAOD,EAAUgB,eAAeM,KAAKjB,EAAOsoD,IAE1CC,GAAgBvoD,GACA,iBAAVA,IAAuBuB,GAAOvB,IAAWkB,GAAWlB,GAE1DiS,GAAajS,GACI,oBAAZkS,UACNlS,aAAiBkS,SAAqD,qBAA1CtS,CAAOD,EAAUkB,SAASI,KAAKjB,IAE1DwoD,GAAiB1kD,IACnB,IAAI,IAAA47B,EACA,OAAIztB,GAAUnO,GACHA,EAAIA,IAIR,IAAI0I,IAAI1I,aAAe0I,IAAM1I,EAAIjD,WAAasuB,OAAOrrB,GAAY,MAANgE,IAAgB,OAAV43B,EAAN53B,GAAQ+3B,eAAQ,EAAhBH,EAAkBE,MAAM/+B,UAC9F,CAAE,MAAAZ,GACE,MACJ,GA2EEwoD,GAAoBA,CACtBC,EACAC,EACAC,EACA9kD,EACAwO,KAEA,IAAIu2C,EACJ,IAGIA,EAAc,IAAIr8C,IAAI1I,GAAKyI,QAC/B,CAAE,MAAAyG,GAEE,OAAO,CACX,CACA,IAAK01C,EACD,OAAO,EAEX,GAAI5nD,GAAQ4nD,KAAeA,EAAUtoD,SAASyoD,GAC1C,OAAO,EAGX,IAAIC,GAAkB,EACtB,GAAIF,EAAgB,CAChB,IAAMG,UAAEA,EAASC,SAAEA,GAAaJ,EAAeK,+BAA8B,GAC7E32C,EAAQ0H,IAAIiuC,GAAmBc,GAC/Bz2C,EAAQ0H,IAAIkuC,GAAkBc,GAC9BF,GAAkB,CACtB,CACA,IAAMI,EAjCaP,IACnBznD,GAAWynD,GAAcA,IAAeA,EAgCdQ,CAAcR,GAKxC,OAJIO,G3C7DiC,wB2C6DZA,IACrB52C,EAAQ0H,IAAImuC,GAAoBe,GAChCJ,GAAkB,GAEfA,CAAe,EAgG1BvgD,GAAiBmW,sBAAwBnW,GAAiBmW,uBAAyB,CAAA,EACnF,IAAM0qC,GAAW,CACbC,YA7FeC,CACfZ,EACAC,EACAC,IAIOz8C,GAAMrE,GAAQ,SAAU+V,GACpB,SAAyB/Z,EAAwBia,GACpD,IAAMwrC,EAAgBlgD,UAAUrE,OAAS,EAAI,CAAClB,EAAKia,GAAQ,CAACja,GACxD0lD,EAAYD,EAEhB,IACI,IAAME,EAAajB,GAAc1kD,GACjC,GAAI2lD,EACA,GAAIx3C,GAAUnO,GAAM,CAKhB,IAAM8Y,EAAM,IAAI1K,QAAQpO,EAAKia,GAC7B0qC,GAAkBC,EAAWC,EAAYC,EAAgBhsC,EAAI9Y,IAAK8Y,EAAItK,SACtEk3C,EAAY,CAAC5sC,EACjB,KAAO,CACH,IAAMtK,EAAU,IAAIo3C,QAAQnB,GAAaxqC,GAAQA,EAAKzL,aAAUvK,GAChE,GAAI0gD,GAAkBC,EAAWC,EAAYC,EAAgBa,EAAYn3C,GAAU,CAC/E,IAAMq3C,EAvICC,EAAC7rC,EAA+BzL,KAC/D,GAAIjR,GAAY0c,IAASxc,GAAOwc,GAC5B,MAAO,CAAEzL,WAEb,GAAKi2C,GAAaxqC,GAAlB,CAIA,IAAM8rC,EAAe9rC,EAErB,GAAqB,oBAAV+rC,OAA4C,oBAAZC,QAAyB,CAEhE,IAAMJ,EAAkB/pD,OAAOoqD,OAAOH,GAOtC,OANAjqD,OAAOqqD,eAAeN,EAAiB,UAAW,CAC9CO,cAAc,EACdnqD,YAAY,EACZC,MAAOsS,EACP63C,UAAU,IAEPR,CACX,CAIA,OAAO,IAAIG,MAFI,CAAEx3C,WAEQ,CACrB8F,IAAGA,CAAC9H,EAAQg4C,IACJ3nD,GAAe2P,EAAQg4C,GAChByB,QAAQ3xC,IAAI9H,EAAQg4C,GAExByB,QAAQ3xC,IAAIyxC,EAAcvB,EAAUuB,GAE/C1X,IAAGA,CAAC7hC,EAAQg4C,IACD3nD,GAAe2P,EAAQg4C,IAAaA,KAAYuB,EAE3DO,OAAAA,CAAQ95C,GACJ,IAAMvL,EAAO,IAAIwpC,IAAqBwb,QAAQK,QAAQ95C,IAOtD,OANAy5C,QAAQK,QAAQP,GAAc/+C,SAASE,GAAQjG,EAAK6tC,IAAI5nC,KACxDq9C,GAAkBv9C,SAASE,IACnBA,KAAO6+C,GACP9kD,EAAK6tC,IAAI5nC,EACb,IAEGjK,MAAMmxC,KAAKntC,EACtB,EACAslD,wBAAAA,CAAyB/5C,EAAQg4C,GAC7B,IAAMgC,EAAmBP,QAAQM,yBAAyB/5C,EAAQg4C,GAClE,GAAIgC,EACA,OAAOA,EAEX,GAAwB,iBAAbhC,GAAyBD,GAAkBjoD,SAASkoD,IAAaA,KAAYuB,EACpF,MAAO,CACHK,cAAc,EACdnqD,YAAY,EACZqY,GAA2D,GAAhD2xC,eAAQ3xC,IAAIyxC,EAAcvB,EAAUuB,KAIvD,IAAMU,EAAaR,QAAQM,yBAAyBR,EAAcvB,GAClE,OAAOiC,EAAUv0C,EAAA,CAAA,EAAQu0C,EAAU,CAAEL,cAAc,SAASniD,CAChE,EACAk+C,eAAcA,IACHrmD,OAAOqmD,eAAe4D,IAvDrC,CAyDE,EAwE8CD,CAA2B7rC,EAAMzL,GACrDq3C,IACAH,EAAY,CAAC1lD,EAAK6lD,GAE1B,CACJ,CAER,CAAE,MAAA30C,GACEw0C,EAAYD,CAChB,CAEA,OAAO1rC,EAAcnK,MAAMC,KAAM61C,EACrC,IAwDJgB,UApDaC,CACb/B,EACAC,EACAC,IAEOz8C,GAEHrE,GAAQO,eAAe1I,UACvB,QAGC4c,GACU,SACHnH,EACAtR,EACA0Y,EACAC,EACAC,QAFK,IAALF,IAAAA,GAAQ,GAOR,IAAMG,EAAMhJ,KAENrB,EAAU,IAAIo3C,QACdD,EAAajB,GAAc1kD,GAC7B2lD,GACAhB,GAAkBC,EAAWC,EAAYC,EAAgBa,EAAYn3C,GAGzE,IAAMlN,EAASmX,EAAatb,KAAK0b,EAAKvH,EAAQtR,EAAK0Y,EAAOC,EAAUC,GAapE,OAXA0rC,GAAgBt9C,SAASkS,IACrB,IAAMhd,EAAQsS,EAAQ8F,IAAI4E,GAC1B,GAAIhd,EACA,IACI2c,EAAIG,iBAAiBE,EAAQhd,EACjC,CAAE,MAAAyY,GACE,CAER,IAGGrT,CACX,KAUZmD,GAAiBmW,sBAAsBgsC,uBAAyBtB,GAOhE7gD,GAAiBoiD,8BAAgCvB,GC7QjD,IAAIz4C,IAAE,EAAS4O,GAAEA,IAAIjU,iBAAiB,YAAWsU,IAAIA,EAAEgrC,YAAYj6C,GAAEiP,EAAEirC,UAAUtrC,EAAEK,GAAG,IAAE,EAAG,EAAEA,GAAEA,CAACjP,EAAE4O,EAAEK,EAAEta,KAAK,IAAIqI,EAAE8R,EAAE,OAAOjb,IAAI+a,EAAEvf,OAAO,IAAIwE,GAAGc,MAAKma,EAAEF,EAAEvf,OAAO2N,QAAAA,EAAG,UAAO,IAASA,KAAKA,EAAE4R,EAAEvf,MAAMuf,EAAEurC,MAAMrrC,EAAEF,EAAE4oB,OAAO,EAAEx3B,EAAE4O,IAAI5O,EAAE4O,EAAE,GAAG,OAAO5O,EAAE4O,EAAE,GAAG,oBAAoB,OAAjD,CAAyDA,EAAEvf,MAAM4f,GAAGjP,EAAE4O,GAAI,CAAC,EAAEja,GAAEqL,IAAIwR,uBAAsB,IAAIA,sBAAsBxR,IAAG,EAAEhD,GAAEA,KAAK,IAAMgD,EAAE2D,YAAYy2C,iBAAiB,cAAc,GAAG,GAAGp6C,GAAGA,EAAEq6C,cAAc,GAAGr6C,EAAEq6C,cAAc12C,YAAYuB,MAAM,OAAOlF,CAAC,EAAE8O,GAAEA,KAAA,IAAAwrC,EAAAC,EAAA,OAAwB,QAAxBD,EAAO,OAAPC,EAAIv9C,WAAG,EAAHu9C,EAAKC,uBAAe,IAAAF,EAAAA,EAAE,CAAC,EAACzmD,GAAE,SAAC+a,EAAEK,QAAC,IAADA,IAAAA,GAAE,GAAM,IAAMta,EAAEqI,KAAQnJ,EAAE,WAA8J,OAAhJ,EAAHmM,GAA4BrL,IAAI8C,SAASgjD,cAAc3rC,KAAI,EAAEjb,EAAE,YAAY4D,SAASijD,aAAa7mD,EAAE,UAAUc,EAAEjB,OAAOG,EAAEc,EAAEjB,KAAKqK,QAAQ,KAAK,OAAvIlK,EAAE,qBAAkJ,CAACjF,KAAKggB,EAAEvf,MAAM4f,EAAEuoB,OAAO,OAAO2iB,MAAM,EAAE3/C,QAAQ,GAAGyE,GAAE,MAAOgG,KAAKC,MAAK,KAAIH,KAAKC,MAAM,cAAcD,KAAKiW,UAAU,MAAO2/B,eAAe9mD,EAAE,EAAEmb,GAAE,IAAI4rC,QAAQ,SAASzrC,GAAEnP,EAAE4O,GAAG,IAAIK,EAAED,GAAEvH,IAAImH,GAAG,OAAOK,IAAIA,EAAE,IAAI2rC,QAAQ5rC,GAAE3F,IAAIuF,EAAEK,IAAIA,EAAExH,IAAIzH,IAAIiP,EAAE5F,IAAIrJ,EAAE,IAAI4O,GAAGK,EAAExH,IAAIzH,EAAE,CAAC,MAAMyO,GAACwK,WAAAA,GAAAjW,KAAC4L,OAAC,EAAA5L,KAACrO,EAAE,EAACqO,KAAC8L,EAAE,EAAE,CAAC0B,CAAAA,CAAExQ,GAAE,IAAA66C,EAAC,IAAG76C,EAAE86C,eAAL,CAA2B,IAAMlsC,EAAE5L,KAAK8L,EAAE,GAAGG,EAAEjM,KAAK8L,EAAEi9B,IAAG,GAAI/oC,KAAKrO,GAAGia,GAAGK,GAA2B,IAAxBjP,EAAEyD,UAAUwL,EAAExL,WAAuC,IAAxBzD,EAAEyD,UAAUmL,EAAEnL,WAAeT,KAAKrO,GAAGqL,EAAE3Q,MAAM2T,KAAK8L,EAAElQ,KAAKoB,KAAKgD,KAAKrO,EAAEqL,EAAE3Q,MAAM2T,KAAK8L,EAAE,CAAC9O,IAAU,OAAP66C,EAAC73C,KAAK4L,IAALisC,EAAAvqD,KAAA0S,KAAShD,EAAtL,CAAwL,EAAE,IAA80D0O,GAAx0D8B,GAAE,SAACxQ,EAAE4O,EAAEK,QAAC,IAADA,IAAAA,EAAE,CAAA,GAAM,IAAI,GAAGlE,oBAAoBI,oBAAoB1b,SAASuQ,GAAG,CAAC,IAAMrL,EAAE,IAAIoW,qBAAoB/K,IAAI+6C,gBAAe,KAAKnsC,EAAE5O,EAAE4K,aAAa,GAAE,IAAG,OAAOjW,EAAEyW,QAAO/F,EAAA,CAAE3R,KAAKsM,EAAEg7C,UAAS,GAAM/rC,IAAIta,CAAC,CAAC,CAAC,MAAArF,GAAM,CAAC,EAAEyf,GAAE/O,IAAI,IAAI4O,GAAE,EAAG,MAAM,KAAKA,IAAI5O,IAAI4O,GAAE,EAAG,CAAC,EAAMW,IAAE,EAASV,GAAE,IAAI+uB,IAAInuB,GAAEA,IAAI,WAAWhY,SAASwjD,iBAAiBxjD,SAASgjD,aAAa,IAAI,EAAE7qC,GAAE5P,IAAI,GAAG,WAAWvI,SAASwjD,gBAAgB,CAAC,GAAG,qBAAqBj7C,EAAEtM,KAAK,IAAI,IAAMsM,KAAK6O,GAAE7O,IAAI6H,SAAS0H,MAAKA,GAAE,qBAAqBvP,EAAEtM,KAAKsM,EAAEk6C,UAAU,EAAEztC,oBAAoB,qBAAqBmD,IAAE,GAAI,GAAG8Y,GAAEA,KAAK,GAAK,EAAFnZ,GAAI,CAAA,IAAA2rC,EAAOl7C,EAAE8O,KAAIG,EAAExX,SAASgjD,cAA0H,OAAvGS,EAACjnD,WAAW0P,YAAYy2C,iBAAiB,oBAAoBxmD,MAAKgb,GAAG,WAAWA,EAAEhgB,MAAMggB,EAAEnL,WAAWzD,UAA3G,EAAOk7C,EAAwGz3C,UAAU8L,GAAEN,QAAAA,EAAGQ,KAAI9U,iBAAiB,mBAAmBiV,IAAE,GAAIjV,iBAAiB,qBAAqBiV,IAAE,GAAIhB,IAAE,KAAK7K,YAAW,KAAKwL,GAAEE,IAAG,GAAE,GAAE,CAAC,MAAM,CAAC,mBAAI0rC,GAAkB,OAAO5rC,EAAC,EAAE6rC,QAAAA,CAASp7C,GAAG6O,GAAEozB,IAAIjiC,EAAE,EAAE,EAAEqP,GAAErP,IAAIvI,SAASgjD,aAAa9/C,iBAAiB,qBAAqBqF,GAAE,GAAIA,GAAG,EAAEyQ,GAAE,CAAC,KAAK,KAAKI,GAAE,SAAC7Q,EAAEhD,QAAC,IAADA,IAAAA,EAAE,CAAA,GAAMqS,IAAE,KAAK,IAAgBF,EAAVH,EAAE0Z,KAAUja,EAAE5a,GAAE,OAAakb,EAAEyB,GAAE,SAAQxQ,IAAI,IAAI,IAAM4O,KAAK5O,EAAE,2BAA2B4O,EAAEhgB,OAAOmgB,EAAE1D,aAAyB2D,EAAEmsC,gBAAdvsC,EAAEnL,YAA8BgL,EAAEpf,MAAM0V,KAAKs2C,IAAIzsC,EAAEnL,UAAUqL,KAAI,GAAGL,EAAEjU,QAAQoE,KAAKgQ,GAAGO,GAAE,IAAK,IAAGJ,IAAII,EAAEF,GAAEjP,EAAEyO,EAAEgC,GAAEzT,EAAEs+C,kBAAkB1sC,IAAEA,IAAIH,EAAE5a,GAAE,OAAOsb,EAAEF,GAAEjP,EAAEyO,EAAEgC,GAAEzT,EAAEs+C,kBAAkB3mD,IAAE,KAAK8Z,EAAEpf,MAAMsU,YAAYuB,MAAM0J,EAAEsrC,UAAU/qC,GAAE,EAAG,GAAE,IAAG,GAAE,EAAEosC,GAAE,CAAC,GAAG,KAA8UC,GAAE,EAAEC,GAAE,IAAI9sC,GAAE,EAAQ+sC,GAAE17C,IAAI,IAAI,IAAM4O,KAAK5O,EAAE4O,EAAE+sC,gBAAgBF,GAAE12C,KAAKsC,IAAIo0C,GAAE7sC,EAAE+sC,eAAehtC,GAAE5J,KAAKs2C,IAAI1sC,GAAEC,EAAE+sC,eAAeH,GAAE7sC,IAAGA,GAAE8sC,IAAG,EAAE,EAAE,EAAE,EAAc9qC,GAAEA,KAAA,IAAAirC,EAAA,OAAIltC,GAAE8sC,GAA8B,QAA7BI,EAACj4C,YAAYk4C,wBAAgB,IAAAD,EAAAA,EAAE,CAAC,EAAyFE,GAAE,EAAE,MAAMrqC,GAACwH,WAAAA,GAAAjW,KAACuM,EAAE,GAAEvM,KAAC6L,EAAE,IAAI4uB,IAAGz6B,KAACyM,OAAC,EAAAzM,KAAC4M,OAAC,CAAA,CAACP,CAAAA,GAAIysC,GAAEnrC,KAAI3N,KAAKuM,EAAElb,OAAO,EAAE2O,KAAK6L,EAAEktC,OAAO,CAAClrC,CAAAA,GAAI,IAAM7Q,EAAE+E,KAAKsC,IAAIrE,KAAKuM,EAAElb,OAAO,EAAE0Q,KAAKC,OAAO2L,KAAImrC,IAAG,KAAK,OAAO94C,KAAKuM,EAAEvP,EAAE,CAACwQ,CAAAA,CAAExQ,GAAE,IAAAg8C,EAAC,UAAGA,EAAAh5C,KAAKyM,IAALusC,EAAA1rD,KAAA0S,KAAShD,GAAIA,EAAE27C,eAAe,gBAAgB37C,EAAEmB,UAAnD,CAAoE,IAAMyN,EAAE5L,KAAKuM,EAAEw8B,IAAG,GAAQ98B,EAAEjM,KAAK6L,EAAEpH,IAAIzH,EAAE27C,eAAe,GAAG1sC,GAAiB,GAAdjM,KAAKuM,EAAElb,QAAW2L,EAAE+F,SAAS6I,EAAE4sC,EAAE,CAAA,IAAAS,EAAC,GAAGhtC,EAAEjP,EAAE+F,SAASkJ,EAAEusC,GAAGvsC,EAAEzU,QAAQ,CAACwF,GAAGiP,EAAEusC,EAAEx7C,EAAE+F,UAAU/F,EAAE+F,WAAWkJ,EAAEusC,GAAGx7C,EAAEyD,YAAYwL,EAAEzU,QAAQ,GAAGiJ,WAAWwL,EAAEzU,QAAQoE,KAAKoB,IAAoDgD,KAAK6L,EAAExF,KAAvD4F,EAAE,CAAChQ,GAAGe,EAAE27C,cAAcnhD,QAAQ,CAACwF,GAAGw7C,EAAEx7C,EAAE+F,WAAuB9G,GAAGgQ,GAAGjM,KAAKuM,EAAE3Q,KAAKqQ,IAAIjM,KAAKuM,EAAEzY,MAAK,CAACkJ,EAAE4O,IAAIA,EAAE4sC,EAAEx7C,EAAEw7C,IAAGx4C,KAAKuM,EAAElb,OAAO,GAAG,CAAC,IAAM2L,EAAEgD,KAAKuM,EAAE2sC,OAAO,IAAI,IAAI,IAAMttC,KAAK5O,EAAEgD,KAAK6L,EAAE4wB,OAAO7wB,EAAE3P,GAAG,CAAO,OAANg9C,EAAAj5C,KAAK4M,IAALqsC,EAAA3rD,KAAA0S,KAASiM,EAAE,CAAhb,CAAib,EAAE,IAAM2B,GAAE5Q,IAAI,IAAM4O,EAAE3a,WAAWkoD,qBAAqBp4C,WAAWkL,EAAEhb,WAAWmoD,oBAAoBn1C,aAAa,GAAG,WAAWxP,SAASwjD,gBAAgBj7C,QAAQ,CAAC,IAAMrL,EAAEoa,GAAE/O,GAAOhD,GAAE,EAAS8R,EAAEA,KAAKG,EAAEjS,GAAGrI,GAAG,EAAEgG,iBAAiB,mBAAmBmU,EAAE,CAACutC,MAAK,EAAGthD,SAAQ,IAAKiC,EAAE4R,GAAE,KAAKnC,oBAAoB,mBAAmBqC,EAAE,CAAC/T,SAAQ,IAAKpG,GAAG,GAAE,GAAGyc,GAAE,CAAC,IAAI,KAA2gB,MAAMkrC,GAACrjC,WAAAA,GAAAjW,KAACyM,OAAC,CAAA,CAACe,CAAAA,CAAExQ,GAAE,IAAAu8C,EAAO,OAANA,EAAAv5C,KAAKyM,IAAL8sC,EAAAjsD,KAAA0S,KAAShD,EAAE,EAAE,IAAMw8C,GAAE,CAAC,KAAK,KCqBzoJC,GAA4B,MAC9BC,CDtBmpJ18C,EAAEhD,QAAC,IAADA,IAAAA,EAAE,CAAA,GAAMqS,IAAE,KAAK,IAAgBZ,EAAVO,EAAE0Z,KAAUnZ,EAAE1b,GAAE,OAAagb,EAAEM,GAAEnS,EAAEs/C,IAAG7sC,EAAEzP,IAAwC,IAAI,IAAM4O,KAA9C5R,EAAEs+C,mBAAmBt7C,EAAEA,EAAEhJ,OAAM,IAAoBgJ,GAAE6O,EAAE2B,EAAE5B,GAAeI,EAAEmsC,gBAAdvsC,EAAEnL,YAA8B8L,EAAElgB,MAAM0V,KAAKs2C,IAAIzsC,EAAEnL,UAAUqL,KAAI,GAAGS,EAAE/U,QAAQ,CAACoU,GAAGH,IAAI,EAAEmB,EAAEY,GAAE,2BAA2Bf,GAAG,GAAGG,EAAE,CAACnB,EAAEQ,GAAEjP,EAAEuP,EAAEitC,GAAEx/C,EAAEs+C,kBAAkB,IAAMxsC,EAAEC,IAAE,KAAKU,EAAEG,EAAE+sC,eAAe/sC,EAAEvE,aAAaoD,GAAE,EAAG,IAAGO,EAAEhP,IAAIA,EAAE48C,YAAYhsC,GAAE9B,GAAGrC,oBAAoBzM,EAAEtM,KAAKsb,EAAE,CAACjU,SAAQ,IAAK,EAAE,IAAI,IAAMiF,IAAI,CAAC,UAAU,QAAQ,oBAAoBrF,iBAAiBqF,EAAEgP,EAAE,CAACjU,SAAQ,IAAK6T,IAAEA,IAAIW,EAAE1b,GAAE,OAAO4a,EAAEQ,GAAEjP,EAAEuP,EAAEitC,GAAEx/C,EAAEs+C,kBAAkB3mD,IAAE,KAAK4a,EAAElgB,MAAMsU,YAAYuB,MAAM0J,EAAEsrC,UAAUzrC,GAAE,EAAG,GAAE,GAAE,IAAG,OCuB/uKouC,CDvBuhF78C,EAAEhD,QAAC,IAADA,IAAAA,EAAE,CAAA,GAAM,IAAM8R,EAAE4Z,KAAI7X,GAAE9B,IAAE,KAAK,IAAIC,EAAED,EAAElb,GAAE,MAAM,GAAS0b,EAAEJ,GAAEnS,EAAEyR,IAAGI,EAAE7O,IAAI,IAAI,IAAM4O,KAAK5O,EAAEuP,EAAEiB,EAAE5B,GAAGW,EAAE5a,EAAEoa,EAAE1f,QAAQ0f,EAAE1f,MAAMkgB,EAAE5a,EAAEoa,EAAEvU,QAAQ+U,EAAET,EAAEE,IAAI,EAAES,EAAEe,GAAE,eAAe3B,GAAGY,IAAIT,EAAEC,GAAEjP,EAAE+O,EAAEwsC,GAAEv+C,EAAEs+C,kBAAkBxsC,EAAEssC,UAAS,KAAKvsC,EAAEY,EAAEktC,eAAe3tC,GAAE,EAAG,IAAGJ,IAAE,KAAKW,EAAE5a,EAAE,EAAEoa,EAAElb,GAAE,MAAM,GAAGmb,EAAEC,GAAEjP,EAAE+O,EAAEwsC,GAAEv+C,EAAEs+C,kBAAkB3mD,GAAEqa,EAAE,IAAGjL,WAAWiL,GAAG,IAAG,QCwBv1F8tC,GACAC,KAAAA,CDzB8lI/8C,EAAErL,GAAQ,QAAP,IAADA,IAAAA,EAAE,CAAA,GAAUV,WAAW+oD,wBAA0B,kBAAkBA,uBAAuBhuD,UAAlF,CAAoG,IAAMgO,EAAE0rB,KAAIrZ,IAAE,KAAI,IAAA4tC,EAAzrC,qBAAqBt5C,aAAa+K,KAAIA,GAAE8B,GAAE,QAAQkrC,GAAE,CAACwB,kBAAkB,KAAunC,IAAIpuC,EAAEE,EAAEnb,GAAE,OAAa4a,EAAEU,GAAExa,EAAE8c,IAAG1C,EAAE/O,IAAI4Q,IAAE,KAAK,IAAI,IAAMhC,KAAK5O,EAAEyO,EAAE+B,EAAE5B,GAAG,IAAMA,EAAEH,EAAEoC,IAAIjC,GAAGA,EAAE4sC,IAAIxsC,EAAE3f,QAAQ2f,EAAE3f,MAAMuf,EAAE4sC,EAAExsC,EAAExU,QAAQoU,EAAEpU,QAAQsU,IAAI,GAAE,EAAES,EAAEiB,GAAE,QAAQzB,EAAE,CAACmuC,kBAAqC,QAApBD,EAACtoD,EAAEuoD,yBAAiB,IAAAD,EAAAA,EAAE,KAAKnuC,EAAEG,GAAEjP,EAAEgP,EAAEoC,GAAEzc,EAAE2mD,kBAAkB/rC,IAAIA,EAAEnE,QAAQ,CAAC1X,KAAK,cAAcsnD,UAAS,IAAKh+C,EAAEo+C,UAAS,KAAKrsC,EAAEQ,EAAEotC,eAAe7tC,GAAE,EAAG,IAAGF,IAAE,KAAKH,EAAEY,IAAIL,EAAEnb,GAAE,OAAOib,EAAEG,GAAEjP,EAAEgP,EAAEoC,GAAEzc,EAAE2mD,iBAAiB,IAAG,GAAxZ,CAA0Z,GEmCnmJ,SAAS6B,GAAU9oD,EAAgBuL,GAC/B,OAAIA,EAAKvL,OAASA,EACPuL,EAAK5I,MAAM,EAAG3C,GAAU,MAE5BuL,CACX,CAuBO,SAASw9C,GAAuB5gD,GACnC,GAAIA,EAAG4gD,uBACH,OAAO5gD,EAAG4gD,uBAEd,IAAIC,EAAsB7gD,EAC1B,GACI6gD,EAAMA,EAAIC,sBACLD,IAAQ9gD,GAAc8gD,IAC/B,OAAOA,CACX,CAwEO,SAASE,GACZ59C,EAAe+B,GAgBmC,IAAA87C,EAAAC,GAflDz9C,EACIA,EAAC09C,yBACDA,EAAwBC,YACxBA,EAAWC,2BACXA,EAA0BC,wBAE1BA,GAQHn8C,EAED,IAAKnF,GAAcoD,GACf,MAAO,CAAEyQ,MAAO,CAAA,GAKpB,IAFA,IAAMzR,EAA+B,CAACgB,GAClCvB,EAAiBuB,EACdvB,EAAMC,aAAe3B,GAAM0B,EAAO,SACrC,GAAIvB,GAAauB,EAAMC,YACnBM,EAAkBC,KAAKR,EAAMC,WAAWvB,MACxCsB,EAAQA,EAAMC,WAAWvB,SAF7B,CAKA,IAAKP,GAAc6B,EAAMC,YACrB,MAEJM,EAAkBC,KAAKR,EAAMC,YAC7BD,EAAQA,EAAMC,UALd,CAQJ,IAsDIy/C,EjD7NqB3qD,EACnB+7B,EKilB6B6uB,E4C3a7BC,EAA6B,GAC7BC,EAA2C,CAAA,EAC7ChvB,GAAuB,EACvBivB,GAAoB,EAqCxB,GAnCAjkD,GAAK0E,GAAoBnC,IACrB,IAAM2hD,EAAkB7gD,GAAqBd,GAI7C,GAAIE,GAAMF,EAAI,KAAM,CAChB,IAAM4hD,EAAW5hD,EAAGW,aAAa,QACjC8xB,KACIkvB,GAAqBC,GAAYtgD,GAAmBsgD,MAC9CP,EACI3qD,GAAakrD,GACbA,EAElB,CAII3uD,GADYwN,GAAcT,GACR,mBAClB0hD,GAAoB,GAGxBF,EAAap/C,KA9Hd,SACHy/C,EACAC,EACAC,EACAC,EACAX,QAAgC,IAAhCA,IAAAA,GAAmC,GAEnC,IAAMY,EAAWJ,EAAKzhD,QAAQjK,cACxByd,EAAoB,CACtBquC,SAAUA,GAEVvgD,GAA8BtO,QAAQ6uD,IAAY,IAAOF,IAErDnuC,EAAgB,SADW,MAA3BquC,EAAS9rD,eAAoD,WAA3B8rD,EAAS9rD,cACvBwqD,GAAU,KAAMz9C,GAA2B2+C,IAE3ClB,GAAU,KAAM//C,GAAYihD,KAIxD,IAAMr/C,EAAU/B,GAAcohD,GAC1Br/C,EAAQ3K,OAAS,IACjB+b,EAAe,QAAIpR,EAAQnB,QAAO,SAAUmR,GACxC,MAAa,KAANA,CACX,KAGJ/U,GAAKokD,EAAKzN,YAAY,SAAU8N,G5Cgc7B,IAA4BC,E4C9b3B,KAAIphD,GAAmB8gD,KAAsE,IAA7D,CAAC,OAAQ,KAAM,QAAS,cAAczuD,QAAQ8uD,EAAK9vD,SAErD,MAA1B4vD,IAAAA,EAA4B/uD,SAASivD,EAAK9vD,SAEzC0vD,GAAqBxgD,GAAmB4gD,EAAKrvD,U5C2blDsB,GAD2BguD,E4C1bqDD,EAAK9vD,O5C4b3C,eAAnC+vD,EAAc3gD,UAAU,EAAG,KAA0D,YAAlC2gD,EAAc3gD,UAAU,EAAG,I4C5bO,CACxF,IAAI3O,EAAQqvD,EAAKrvD,MACC,UAAdqvD,EAAK9vD,OAILS,EAAQ0N,GAAiB1N,GAAO4H,KAAK,MAEzCmZ,EAAM,SAAWsuC,EAAK9vD,MAAQuuD,GAC1B,KACc,SAAduB,EAAK9vD,MAAmBivD,EAA0B3qD,GAAa7D,GAASA,EAEhF,CACJ,IAKA,IAHA,IAAIuvD,EAAW,EACXC,EAAY,EACZC,EAA8BT,EAC1BS,EAAc1B,GAAuB0B,IAEzCF,IACIE,EAAYliD,UAAYyhD,EAAKzhD,SAC7BiiD,IAMR,OAHAzuC,EAAiB,UAAIwuC,EACrBxuC,EAAmB,YAAIyuC,EAEhBzuC,CACX,CAkEY2uC,CACIviD,EACAkhD,EACAC,EACAC,EACAC,IAIR,IAAMmB,EA/KP,SAAyCX,GAE5C,IADwB/gD,GAAqB+gD,GAEzC,MAAO,CAAA,EAGX,IAAMjuC,EAAoB,CAAA,EAY1B,OAVAnW,GAAKokD,EAAKzN,YAAY,SAAU8N,GAC5B,GAAIA,EAAK9vD,MAA2D,IAAnD8vD,EAAK9vD,KAAKgB,QAAQ,6BAAoC,CACnE,IAAMqvD,EAAcP,EAAK9vD,KAAKmP,QAAQ,6BAA8B,IAC9D+xC,EAAgB4O,EAAKrvD,MACvB4vD,GAAenP,GAAiBhyC,GAAmBgyC,KACnD1/B,EAAM6uC,GAAenP,EAE7B,CACJ,IAEO1/B,CACX,CA4JkC8uC,CAAgC1iD,GAC1DlC,GAAO2jD,EAA8Be,EAAkB,IAGvDd,EACA,MAAO,CAAE9tC,MAAO,CAAA,EAAI8tC,qBAcxB,GAXKP,IAIGK,EAAa,GAAa,SAD1BthD,GAAMiD,EAAQ,MAAQjD,GAAMiD,EAAQ,UACND,GAA2BC,GAE3BvC,GAAYuC,IAK9CsvB,EAAM,CAAA,IAAAkwB,EAAApwB,EACNivB,EAAa,GAAe,WAAI/uB,EAChC,IAAMmwB,EAA6B,OjDhOdjsD,EiDgOS87B,EjD/N5BC,EAAmB,MAARz3B,QAAQ,EAARA,GAAU8xB,cAAc,KiD+NvB41B,EjD9NdzuD,GAAYw+B,GACL,MAGXA,EAASD,KAAO97B,EACT+7B,SiDyNgC,EAAlBiwB,EAAoBriD,KAC/BuiD,EAAqB,MAANloD,IAAgB,OAAV43B,EAAN53B,GAAQ+3B,eAAQ,EAAhBH,EAAkBjyB,KACnCsiD,GAAYC,GAAgBD,IAAaC,IACzCvB,EAAe7uB,EAEvB,CAaA,MAAO,CAAE7e,MAXK9V,GA1KP,CACHglD,YA0KqBt/C,EAAEtM,KAzKvB6rD,YAAa,GA2KY,CAAEC,UAAWxB,GAEtC,CAAEyB,iB5CsW6B1B,E4CtWWC,E5C8XlD,SAA0BD,GACtB,IAAM2B,EAAM3B,EAASzoC,KAAK1a,IAAY,IAAA+kD,EAAAC,EAC9BC,EAAY,GAIhB,GAHIjlD,EAAQ6jD,WACRoB,GAAajlD,EAAQ6jD,UAErB7jD,EAAQwF,WAER,IAAK,IAAM0/C,KADXllD,EAAQwF,WAAWtJ,OACQ8D,EAAQwF,YAC/By/C,GAAS,IAAQC,EAAa/hD,QAAQ,KAAM,IAGpD,IAAM6yC,EAA+BvrC,KAC7BzK,EAAQgF,KAAO,CAAEA,KAAMhF,EAAQgF,MAAS,GAAE,CAC9C,YAA8B,QAAnB+/C,EAAE/kD,EAAQmlD,iBAAS,IAAAJ,EAAAA,EAAI,EAClC,cAAkC,QAArBC,EAAEhlD,EAAQolD,mBAAW,IAAAJ,EAAAA,EAAI,GAClChlD,EAAQq0B,KAAO,CAAEA,KAAMr0B,EAAQq0B,MAAS,CAAA,EACxCr0B,EAAQqlD,QAAU,CAAEA,QAASrlD,EAAQqlD,SAAY,CAAA,EAClDrlD,EAAQg2C,YAETsP,EAAwC,CAAA,EAU9C,OATA1lD,GAAQo2C,GACH95C,MAAK,CAAAmN,EAAAO,KAAA,IAAE2K,GAAElL,GAAG0kB,GAAEnkB,EAAA,OAAK2K,EAAEgxC,cAAcx3B,EAAE,IACrCxuB,SACG4P,IAAA,IAAE1P,EAAKhL,GAAM0a,EAAA,OAAMm2C,EAAiBjgD,GAAa5F,EAAInK,aAAe+P,GAAa5Q,EAAMa,WAAW,KAE1G2vD,GAAa,KACArlD,GAAQ0lD,GAChB5qC,KAAIzM,IAAA,IAAExO,EAAKhL,GAAMwZ,EAAA,OAAQxO,OAAQhL,EAAK,GAAA,IACtC4H,KAAK,GACM,IAEpB,OAAOyoD,EAAIzoD,KAAK,IACpB,CAxDWmpD,CA0DX,SAAyBrC,GACrB,OAAOA,EAASzoC,KAAK9Y,IAAO,IAAA6jD,EAAAC,EAClBvzC,EAAW,CACbnN,KAAoB,OAAhBygD,EAAE7jD,EAAa,eAAC,EAAd6jD,EAAgBrpD,MAAM,EAAG,KAC/BynD,SAAUjiD,EAAa,SACvByyB,KAAsB,OAAlBqxB,EAAE9jD,EAAe,iBAAC,EAAhB8jD,EAAkBtpD,MAAM,EAAG,MACjCoJ,WAAYD,GAAiB3D,GAC7ByjD,QAASzjD,EAAa,SACtBujD,UAAWvjD,EAAc,UACzBwjD,YAAaxjD,EAAgB,YAC7Bo0C,WAAY,CAAA,GAMhB,OAHAp2C,GAAQgC,GACHqB,QAAO8L,IAAA,IAAEtP,GAAIsP,EAAA,OAA+B,IAA1BtP,EAAIzK,QAAQ,SAAe,IAC7CuK,SAAQ0P,IAAA,IAAExP,EAAKhL,GAAMwa,EAAA,OAAMkD,EAAS6jC,WAAWv2C,GAAOhL,CAAK,IACzD0d,CAAQ,GAEvB,CA5E4BwzC,CAAgBxC,M4CtWrB,OAAfP,EAAAQ,EAAa,KAAbR,EAA4B,SAAI,CAAEgD,SAAyB,OAAjB/C,EAAEO,EAAa,SAAE,EAAfP,EAA4B,UAAM,CAAA,EAC9EK,GAA2B,UAAX99C,EAAEtM,KAAmB,CAAE+sD,oBAAqB3C,GAAiB,CAAA,EAC7EG,GAIR,CDrOArmD,GAAiBmW,sBAAwBnW,GAAiBmW,uBAAyB,CAAA,EACnFnW,GAAiBmW,sBAAsB0uC,0BAA4BA,GAOnE7kD,GAAiB6kD,0BAA4BA,GAE7C7kD,GAAiBmW,sBAAsB2yC,uBAAyB,IAAMjE,GCLvD3iD,GAAa,iBCf5B,IAAM6mD,GAA6D,CAAA,EA2C5D,SAASC,GAAwChpD,GACpD,OA1CG,SACHhJ,EACAgJ,GAEA,IAAMipD,EAASF,GAAsB/xD,GACrC,GAAIiyD,EACA,OAAOA,EAGX,InEnBsBrwD,EmEmBlBswD,EAAOlpD,EAAiBhJ,GAE5B,GnErB0B2B,GAAJC,EmEqBDswD,SnErB6BtwD,EAAEN,WAAWN,QAAQ,mBcN7DuH,GAAe4pD,KqD4BrB,OAAQJ,GAAsB/xD,GAAQkyD,EAAK10C,KAAKxU,GAGpD,IAAMH,EAAWG,EAAiBH,SAClC,GAAIA,GAAYlH,GAAWkH,EAAS8xB,eAChC,IACI,IAAMy3B,EAAUvpD,EAAS8xB,cAAc,UACvCy3B,EAAQ9Y,QAAS,EACjBzwC,EAASwpD,KAAKj2B,YAAYg2B,GAC1B,IAAME,EAAgBF,EAAQE,cAC1BA,GAAkBA,EAAsBtyD,KACxCkyD,EAAQI,EAAsBtyD,IAElC6I,EAASwpD,KAAKl2B,YAAYi2B,EAC9B,CAAE,MAAOhhD,GAEL7H,GAAOgB,KAAI,uCAAwCvK,yCAA2CA,EAAI,KAAMoR,EAC5G,CAKJ,OAAK8gD,GAASvwD,GAAWuwD,GAIjBH,GAAsB/xD,GAAQkyD,EAAK10C,KAAKxU,GAHrCkpD,CAIf,CAGWK,CAAwB,mBAAoBvpD,EACvD,CCrCA,SAASwpD,GAAa/xD,EAA2BgyD,GAC7C,OAAOvwD,GAASzB,IAAUA,GAASgyD,CACvC,CAEA,MAAMC,GAoBMC,EAAAA,CACJC,GAE6D,IAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EACvDC,EAAgB9+C,KAAK++C,IAA6B,MAAdP,OAAc,EAAdA,EAAgBQ,cAAeh/C,KAAKi/C,GAAkB71C,KAAKpJ,OACrG,MAAO,CACHk/C,6BACgD,QADpBT,QACxBD,SAAAA,EAAgBU,oCAA4B,IAAAT,EAAAA,EAAIK,EAAcI,6BAClEC,oBAAwD,QAArCT,QAAEF,SAAAA,EAAgBW,2BAAmB,IAAAT,EAAAA,EAAII,EAAcK,oBAC1EC,8BACiD,QADpBT,QACzBH,SAAAA,EAAgBY,qCAA6B,IAAAT,EAAAA,EAAIG,EAAcM,8BACnEC,sBAA4D,QAAvCT,QAAEJ,SAAAA,EAAgBa,6BAAqB,IAAAT,EAAAA,EAAIE,EAAcO,sBAC9EC,kCACqD,QADpBT,QAC7BL,SAAAA,EAAgBc,yCAAiC,IAAAT,EAAAA,EAAIC,EAAcQ,kCACvEC,wBAAuC,MAAdf,OAAc,EAAdA,EAAgBe,wBACzCP,YAAaF,EAAcE,YAEnC,CAEA/oC,WAAAA,CACa6V,EACTpE,GACF1nB,KArCMw/C,GAAgC,GAAEx/C,KAMlC++C,GAAkBU,IAA6E,CACnGP,6BAA8B,GAC9BC,oBAAqB,IACrBC,8BAA+B,IAC/BC,sBAAuB,KACvBC,mCAAmC,EACnCN,YAAaS,IACfz/C,KAuEM0/C,GAAY7nD,IAChB,IAAM8nD,EA9Gd,SAAiB9nD,GACb,IAAM+nD,E9C6EH,SAAwB5iD,GAE3B,OAAItP,GAAYsP,EAAEL,QACNK,EAAE6iD,YAA0B,KAEvB,OAAbC,EAAK9iD,EAAEL,SAAHmjD,EAA2B35B,WACnBnpB,EAAE+iD,eAAe,IAAkB,KAEvC/iD,EAAEL,QAAsB,KAJ7B,IAAAmjD,CAMX,C8CvFwBE,CAAenoD,GACnC,OAAI+nD,EACO,CACHK,KAAML,EACNM,cAAeroD,EACfsK,UAAWF,KAAKC,OAGjB,IACX,CAoGsBi+C,CAAQtoD,GACjBjK,GAAO+xD,IAAW3/C,KAAKogD,GAAaT,IACrC3/C,KAAKw/C,GAAQ5jD,KAAK+jD,GAGlB3/C,KAAKw/C,GAAQnuD,QAAU3D,GAAYsS,KAAKqgD,MACxCrgD,KAAKqgD,GAAmBzrD,GAAiBmM,YAAW,KAChDf,KAAKsgD,IAAc,GACpB,KACP,EACHtgD,KAaOugD,GAAY,KAChB,IAAMC,EAAev+C,KAAKC,MAEtBs+C,EAAe,IAAO,GAItBxgD,KAAKw/C,GAAQroD,SAASwoD,IACdjyD,GAAYiyD,EAAMc,iBAClBd,EAAMc,cAAgBD,EAAeb,EAAMx9C,UAC/C,GAER,EACHnC,KAMO0gD,GAAqB,KACzB1gD,KAAK2gD,GAAwB1+C,KAAKC,KAAK,EAC1ClC,KAMO4gD,GAAsB,KACQ,aAAtB,MAARnsD,QAAQ,EAARA,GAAUwjD,mBACVj4C,KAAK6gD,GAAwB5+C,KAAKC,MACtC,EACHlC,KAxGY8rB,SAAAA,EAGT9rB,KAAK8gD,GAAU9gD,KAAKu+C,GAAkB72B,GACtC1nB,KAAK+gD,WAAa/gD,KAAK8gD,GAAQ9B,WACnC,CAEA7+C,KAAAA,CAAM6gD,GACFhhD,KAAKihD,KACLjhD,KAAKkhD,KACLlhD,KAAKmhD,KACLnhD,KAAKohD,KACLphD,KAAKqhD,GAAuBL,EAChC,CAEQK,EAAAA,CAAuBL,GAC3B,IAAKhhD,KAAKshD,GAAmB,CACzB,IAAMC,EAAyB3D,GAAwChpD,IACvEoL,KAAKshD,GAAoB,IAAIC,GAAwBC,IACjDxhD,KAAKyhD,GAAYD,EAAU,IAE/BxhD,KAAKshD,GAAkBl5C,QAAQ44C,EAAgB,CAC3CpT,YAAY,EACZ8T,eAAe,EACfC,WAAW,EACXC,SAAS,GAEjB,CACJ,CAEAC,IAAAA,GAAO,IAAAC,SACHA,OAAKR,KAALQ,EAAwBz5C,aACxBrI,KAAKshD,QAAoBltD,EACzBQ,GAAiB6U,oBAAoB,QAASzJ,KAAK0/C,IACnD9qD,GAAiB6U,oBAAoB,SAAUzJ,KAAKugD,GAAW,CAAExoD,SAAS,IAC1EnD,GAAiB6U,oBAAoB,kBAAmBzJ,KAAK0gD,IACrD,MAARjsD,IAAAA,GAAUgV,oBAAoB,mBAAoBzJ,KAAK4gD,GAC3D,CAGQa,EAAAA,CAAYM,GAEhB/hD,KAAKgiD,GAAgB//C,KAAKC,KAC9B,CAEQ++C,EAAAA,GACJtpD,GAAiB/C,GAAkB,QAASoL,KAAK0/C,GACrD,CAsBQwB,EAAAA,GACJvpD,GAAiB/C,GAAkB,SAAUoL,KAAKugD,GAAW,CAAExoD,SAAS,GAC5E,CAiBQopD,EAAAA,GACJxpD,GAAiB/C,GAAkB,kBAAmBoL,KAAK0gD,GAC/D,CAMQU,EAAAA,GACJzpD,GAAiBlD,GAAU,mBAAoBuL,KAAK4gD,GACxD,CAQQR,EAAAA,CAAaT,GACjB,IAAKA,EACD,OAAO,EAGX,IAAK3/C,KAAK8gD,GAAQxB,qCA/JFznD,EA+JsD8nD,EAAMO,eA9JnEhsB,SAAWr8B,EAAMo8B,SAAWp8B,EAAMoqD,QAAUpqD,EAAMqqD,UA+JvD,OAAO,EAhKnB,IAAwBrqD,E/CbW2B,E+CgL3B,I/ChL2BA,E+CgLJmmD,EAAMM,gB/C/KfkC,UD+EI,wBC7EX3oD,EAAGyC,IAAiC,MAAVzC,EAAG4oD,SAAH5oD,EAAG4oD,QAAU,mC+C8K1C,OAAO,EAGX,IAAMC,EAA6BriD,KAAKw/C,GAAQxgD,MAAMgN,GAC3CA,EAAEi0C,OAASN,EAAMM,MAAkD,IAA1Cl+C,KAAKkhC,IAAIj3B,EAAE7J,UAAYw9C,EAAMx9C,aAGjE,SAAIkgD,IAIA3oD,GAAMimD,EAAMM,KAAM,SAAY1mD,GAAcomD,EAAMM,Q9CoJvD,SAA6BzmD,GAChC,IAAKrF,IAAUoH,GAA0B/B,GACrC,OAAO,EAEX,IAAMmC,kBAAEA,GAAsBH,GAA+BhC,GAC7D,OAAOmC,EAAkBqD,MAAMihD,GAASvmD,GAAMumD,EAAM,MACxD,C8C1JuEqC,CAAoB3C,EAAMM,O9CqB1F,SAAgCzmD,EAAoBsnD,GAA+C,IAAAyB,EACtG,IAAKpuD,IAAUoH,GAA0B/B,GACrC,OAAO,EAGX,IAAMgpD,EAAqBz0D,GAAU+yD,GAC/BxlD,WAA8BinD,EACtB,MAAPzB,OAAO,EAAPA,EAASvB,+BAAuB,IAAAgD,EAAAA,EAAIjnD,IAErCK,kBAAEA,GAAsBH,GAA+BhC,GAG7D,OAjFJ,SAAyCuhD,EAAqB0H,GAC1D,GAAI/0D,GAAY+0D,GAEZ,OAAO,EACV,IAMAC,EANAC,EAAA,SAAAnpD,GAGG,GAAIipD,EAAazjD,MAAMw8B,GA3B/B,SAAmChiC,EAAagiC,GAC5C,IAAMonB,EACFppD,EAAGopD,SACFppD,EAAWqpD,iBACXrpD,EAAWspD,mBACXtpD,EAAWupD,oBACXvpD,EAAWwpD,uBACXxpD,EAAWypD,iBAChB,IACI,QAAOL,GAAUA,EAAQt1D,KAAKkM,EAAIgiC,EACtC,CAAE,MAAAlvC,GACE,OAAO,CACX,CACJ,CAc4C42D,CAA0B1pD,EAAIgiC,KAAY,MAAA,CAAAnvB,GACnE,EAEf,EAJA,IAAK,IAAM7S,KAAMuhD,EAAQ,GAAA2H,EAAAC,EAAAnpD,GAAA,OAAAkpD,EAAAr2C,EAMzB,OAAO,CACX,CAoEY82C,CAAgCxnD,EAAmB6mD,EAC/D,C8C9BaY,CAAuBzD,EAAMM,KAAM,CAAEV,wBAAyBv/C,KAAK8gD,GAAQvB,0BAKpF,CAEQe,EAAAA,GACJ,GAAKtgD,KAAKw/C,GAAQnuD,OAAlB,CAIA4S,aAAajE,KAAKqgD,IAClBrgD,KAAKqgD,QAAmBjsD,EAExB,IAAMivD,EAAgBrjD,KAAKw/C,GAG3B,IAAK,IAAMG,KAFX3/C,KAAKw/C,GAAU,GAEK6D,GAAe,CAAA,IAAAC,EAC/B3D,EAAM4D,gBACmB,QADJD,EACjB3D,EAAM4D,uBAAe,IAAAD,EAAAA,EACpBtjD,KAAKgiD,IAAoChiD,KAAKgiD,IAAxBrC,EAAMx9C,UACvBnC,KAAKgiD,GAAgBrC,EAAMx9C,eAC3B/N,EACVurD,EAAM6D,gBAAkBvhD,KAAKC,MAAQy9C,EAAMx9C,UAC3Cw9C,EAAM8D,wBACFzjD,KAAK2gD,IAA4C3gD,KAAK2gD,IAAxBhB,EAAMx9C,UAC9BnC,KAAK2gD,GAAwBhB,EAAMx9C,eACnC/N,EACVurD,EAAM+D,yBAA2B1jD,KAAK6gD,GAChC9+C,KAAKkhC,IAAI0c,EAAMx9C,UAAYnC,KAAK6gD,SAChCzsD,EAEN,IAAMuvD,EAAgBvF,GAAauB,EAAMc,cAAezgD,KAAK8gD,GAAQ3B,qBAC/DyE,EAA0BxF,GAC5BuB,EAAM8D,wBACNzjD,KAAK8gD,GAAQ1B,+BAEXyE,EAAkBzF,GAAauB,EAAM4D,gBAAiBvjD,KAAK8gD,GAAQzB,uBAGnEyE,EAAkB1F,GAAauB,EAAM6D,gBAAsD,IAArCxjD,KAAK8gD,GAAQzB,uBAEnE0E,EAAYj2D,GAAS6xD,EAAMc,gBAAwCzgD,KAAK8gD,GAAQ3B,oBAAnCQ,EAAMc,cACnDuD,EACFl2D,GAAS6xD,EAAM4D,kBAA4CvjD,KAAK8gD,GAAQzB,sBAArCM,EAAM4D,gBACvCU,EACFn2D,GAAS6xD,EAAM8D,0BACiBzjD,KAAK8gD,GAAQ1B,8BAA7CO,EAAM8D,wBACJS,EACFp2D,GAAS6xD,EAAM+D,2BACkB1jD,KAAK8gD,GAAQ1B,8BAA9CO,EAAM+D,yBAEV,KAAIK,GAAaC,GAAeC,GAAsBC,GAAtD,CAIA,IAAMC,EAA2B/F,GAC7BuB,EAAM+D,yBACN1jD,KAAK8gD,GAAQ1B,+BAIbuE,GACAE,GACAC,GACAF,GACAO,EAEAnkD,KAAK+gD,WAAWpB,EAAO,CACnByE,oCAAqCpkD,KAAKgiD,GAC1CqC,4BAA6B1E,EAAMx9C,UACnCmiD,2BAA4BX,EAC5BY,6BAA8BV,EAC9BW,6BAA8BV,EAC9BW,sCAAuCb,EACvCc,uCAAwCP,IAEbnkD,KAAK8gD,GAAQzB,sBAArCM,EAAM6D,iBAEbxjD,KAAKw/C,GAAQ5jD,KAAK+jD,EAzBtB,CA2BJ,CAEI3/C,KAAKw/C,GAAQnuD,QAAU3D,GAAYsS,KAAKqgD,MACxCrgD,KAAKqgD,GAAmBzrD,GAAiBmM,YAAW,KAChDf,KAAKsgD,IAAc,GACpB,KA7EP,CA+EJ,CAEQrB,EAAAA,CAAkBU,EAA2Bv3B,GAGjDpoB,KAAK8rB,SAAS/zB,QACV,cAAasK,EAAA,CAAA,EAEN+lB,EACAmyB,GAAgCoF,EAAMM,KAAM,CAC3CjjD,EAAG2iD,EAAMO,cACTxF,yBAA0B16C,KAAK8rB,SAASpE,OAAOi9B,4BAC/ChK,YAAa36C,KAAK8rB,SAASpE,OAAOk9B,cAClChK,2BAA4B56C,KAAK8gD,GAAQ5B,6BAGzCrE,wBAAyB76C,KAAK8rB,SAASpE,OAAOm9B,6BAC/Cz3C,MAAK,CACR03C,4BAA6BnF,EAAMc,cACnCsE,8BAA+BpF,EAAM4D,gBACrCyB,8BAA+BrF,EAAM6D,gBACrCyB,uCAAwCtF,EAAM8D,wBAC9CyB,wCAAyCvF,EAAM+D,2BAEnD,CACIvhD,UAAW,IAAIF,KAAK09C,EAAMx9C,YAGtC,EAGJvN,GAAiBmW,sBAAwBnW,GAAiBmW,uBAAyB,CAAA,EACnFnW,GAAiBmW,sBAAsBo6C,0BAA4B,CAACC,EAAI19B,IACpE,IAAI42B,GAAgC8G,EAAI19B","x_google_ignoreList":[30,31,68]}
1
+ {"version":3,"file":"all-external-dependencies.js","sources":["../../rrweb/record/dist/rrweb-record.js","../../rrweb/plugins/rrweb-plugin-console-record/dist/rrweb-plugin-console-record.js","../../core/dist/types.mjs","../../core/dist/utils/string-utils.mjs","../../core/dist/utils/type-utils.mjs","../../core/dist/utils/user-agent-utils.mjs","../../core/dist/utils/index.mjs","../../core/dist/error-tracking/chunk-ids.mjs","../../core/dist/surveys/validation.mjs","../../core/dist/error-tracking/parsers/base.mjs","../../core/dist/error-tracking/parsers/safari.mjs","../../core/dist/error-tracking/parsers/chrome.mjs","../../core/dist/error-tracking/parsers/gecko.mjs","../../core/dist/error-tracking/parsers/index.mjs","../../core/dist/error-tracking/coercers/string-coercer.mjs","../../core/dist/error-tracking/types.mjs","../../core/dist/error-tracking/coercers/utils.mjs","../src/utils/globals.ts","../src/utils/type-utils.ts","../src/utils/logger.ts","../src/utils/index.ts","../src/utils/request-utils.ts","../src/extensions/replay/rrweb-plugins/patch.ts","../src/extensions/replay/external/denylist.ts","../src/constants.ts","../src/utils/element-utils.ts","../src/autocapture-utils.ts","../src/extensions/replay/external/config.ts","../src/extensions/replay/external/network-plugin.ts","../src/entrypoints/recorder.ts","../../../../../../setup-pnpm/node_modules/.bin/store/v11/links/@/preact/10.29.2/709c6912f2b0d7793dc053c28909b888bf8faab7b62175b401a5a5d6126a5d6e/node_modules/preact/dist/preact.module.js","../../../../../../setup-pnpm/node_modules/.bin/store/v11/links/@/preact/10.29.2/709c6912f2b0d7793dc053c28909b888bf8faab7b62175b401a5a5d6126a5d6e/node_modules/preact/hooks/dist/hooks.module.js","../src/posthog-surveys-types.ts","../../core/dist/surveys/events.mjs","../../core/dist/surveys/translations.mjs","../src/utils/survey-utils.ts","../src/uuidv7.ts","../src/utils/regex-utils.ts","../src/utils/property-utils.ts","../src/storage.ts","../src/extensions/utils/stylesheet-loader.ts","../src/extensions/surveys/surveys-extension-utils.tsx","../src/utils/url-targeting-utils.ts","../src/extensions/utils/matcher-utils.ts","../src/extensions/surveys/icons.tsx","../src/extensions/surveys/components/PostHogLogo.tsx","../src/extensions/surveys/components/BottomSection.tsx","../src/extensions/surveys/components/QuestionHeader.tsx","../src/extensions/surveys/components/ConfirmationMessage.tsx","../src/extensions/surveys/components/QuestionTypes.tsx","../src/utils/survey-branching.ts","../src/utils/survey-translations.ts","../src/utils/event-utils.ts","../src/extensions/surveys.tsx","../src/utils/survey-url-prefill.ts","../src/entrypoints/surveys.ts","../src/entrypoints/logs.ts","../src/posthog-exceptions.ts","../src/entrypoints/exception-autocapture.ts","../../core/dist/error-tracking/error-properties-builder.mjs","../../core/dist/error-tracking/coercers/dom-exception-coercer.mjs","../../core/dist/error-tracking/coercers/promise-rejection-event.mjs","../../core/dist/error-tracking/coercers/error-event-coercer.mjs","../../core/dist/error-tracking/coercers/error-coercer.mjs","../../core/dist/error-tracking/coercers/event-coercer.mjs","../../core/dist/error-tracking/coercers/object-coercer.mjs","../../core/dist/error-tracking/coercers/primitive-coercer.mjs","../src/entrypoints/tracing-headers.ts","../src/utils/array-at-polyfill.ts","../../../../../../setup-pnpm/node_modules/.bin/store/v11/links/@/web-vitals/5.3.0/120eca503d77c3b42026842da37a8f53d118236d4139208278d10bd5cf0a52ed/node_modules/web-vitals/dist/web-vitals.js","../src/entrypoints/web-vitals.ts","../src/autocapture.ts","../src/utils/prototype-utils.ts","../src/entrypoints/dead-clicks-autocapture.ts"],"sourcesContent":["var __defProp = Object.defineProperty;\nvar __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;\nvar __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== \"symbol\" ? key + \"\" : key, value);\nvar _a;\nvar 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 return EventType2;\n})(EventType || {});\nconst FullscreenCustomEventTag = \"rrweb/fullscreen\";\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 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 || {});\nconst testableAccessors = {\n Node: [\"childNodes\", \"parentNode\", \"parentElement\", \"textContent\"],\n ShadowRoot: [\"host\", \"styleSheets\"],\n Element: [\"shadowRoot\"],\n MutationObserver: []\n};\nconst testableMethods = {\n Node: [\"contains\", \"getRootNode\"],\n ShadowRoot: [\"getSelection\"],\n Element: [\"querySelector\", \"querySelectorAll\"],\n MutationObserver: [\"constructor\"]\n};\nconst untaintedBasePrototype = {};\nfunction angularZoneUnpatchedAlternative(key) {\n var _a2, _b;\n const angularUnpatchedVersionSymbol = (_b = (_a2 = globalThis == null ? void 0 : globalThis.Zone) == null ? void 0 : _a2.__symbol__) == null ? void 0 : _b.call(_a2, key);\n if (angularUnpatchedVersionSymbol && globalThis[angularUnpatchedVersionSymbol]) {\n return globalThis[angularUnpatchedVersionSymbol];\n } else {\n return void 0;\n }\n}\nfunction getUntaintedPrototype(key) {\n if (untaintedBasePrototype[key])\n return untaintedBasePrototype[key];\n const candidate = angularZoneUnpatchedAlternative(key) || globalThis[key];\n const defaultPrototype = candidate.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 _a2, _b;\n return Boolean(\n (_b = (_a2 = Object.getOwnPropertyDescriptor(defaultPrototype, accessor)) == null ? void 0 : _a2.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 _a2;\n return typeof defaultPrototype[method] === \"function\" && ((_a2 = defaultPrototype[method]) == null ? void 0 : _a2.toString().includes(\"[native code]\"));\n }\n )\n );\n if (isUntaintedAccessors && isUntaintedMethods) {\n untaintedBasePrototype[key] = candidate.prototype;\n return candidate.prototype;\n }\n const iframeEl = document.createElement(\"iframe\");\n try {\n document.body.appendChild(iframeEl);\n const win = iframeEl.contentWindow;\n if (!win) return candidate.prototype;\n const untaintedObject = win[key].prototype;\n if (!untaintedObject) return defaultPrototype;\n return untaintedBasePrototype[key] = untaintedObject;\n } catch {\n return defaultPrototype;\n } finally {\n if (iframeEl.parentNode) {\n document.body.removeChild(iframeEl);\n }\n }\n}\nconst untaintedAccessorCache = {};\nfunction getUntaintedAccessor(key, instance, accessor) {\n var _a2;\n const cacheKey = `${key}.${String(accessor)}`;\n if (untaintedAccessorCache[cacheKey])\n return untaintedAccessorCache[cacheKey].call(\n instance\n );\n const untaintedPrototype = getUntaintedPrototype(key);\n const untaintedAccessor = (_a2 = Object.getOwnPropertyDescriptor(\n untaintedPrototype,\n accessor\n )) == null ? void 0 : _a2.get;\n if (!untaintedAccessor) return instance[accessor];\n untaintedAccessorCache[cacheKey] = 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 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 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 getUntaintedMethod(\"Element\", n, \"querySelector\")(selectors);\n}\nfunction querySelectorAll(n, selectors) {\n return getUntaintedMethod(\"Element\", n, \"querySelectorAll\")(selectors);\n}\nfunction mutationObserverCtor() {\n return getUntaintedPrototype(\"MutationObserver\").constructor;\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 childNodes,\n parentNode,\n parentElement,\n textContent,\n contains,\n getRootNode,\n host,\n styleSheets,\n shadowRoot,\n querySelector,\n querySelectorAll,\n mutationObserver: mutationObserverCtor,\n patch\n};\nfunction isElement(n) {\n return n.nodeType === n.ELEMENT_NODE;\n}\nfunction isShadowRoot(n) {\n const hostEl = (\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 && index.host(n) || null\n );\n return Boolean(\n hostEl && \"shadowRoot\" in hostEl && index.shadowRoot(hostEl) === n\n );\n}\nfunction isNativeShadowDom(shadowRoot2) {\n return Object.prototype.toString.call(shadowRoot2) === \"[object ShadowRoot]\";\n}\nfunction fixBrowserCompatibilityIssuesInCSS(cssText) {\n if (cssText.includes(\" background-clip: text;\") && !cssText.includes(\" -webkit-background-clip: text;\")) {\n cssText = cssText.replace(\n /\\sbackground-clip:\\s*text;/g,\n \" -webkit-background-clip: text; background-clip: text;\"\n );\n }\n return cssText;\n}\nfunction escapeImportStatement(rule) {\n const { cssText } = rule;\n if (cssText.split('\"').length < 3) return cssText;\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}\nfunction hasEmptyShorthandLonghand(css) {\n return /(?:^|[\\s;{}])-?[a-zA-Z][\\w-]*\\s*:\\s*;/.test(css);\n}\nfunction stringifyStylesheet(s) {\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 sheetHref = s.ownerNode.baseURI;\n }\n const stringifiedRules = Array.from(\n rules,\n (rule) => stringifyRule(rule, sheetHref)\n ).join(\"\");\n return fixBrowserCompatibilityIssuesInCSS(stringifiedRules);\n } catch (error) {\n return null;\n }\n}\nfunction stringifyRule(rule, sheetHref) {\n var _a2;\n if (isCSSImportRule(rule)) {\n let importStringified;\n try {\n importStringified = // for same-origin stylesheets,\n // we can access the imported stylesheet rules directly\n stringifyStylesheet(rule.styleSheet) || // work around browser issues with the raw string `@import url(...)` statement\n escapeImportStatement(rule);\n } catch (error) {\n importStringified = rule.cssText;\n }\n try {\n if (importStringified && ((_a2 = rule.styleSheet) == null ? void 0 : _a2.href)) {\n return absolutifyURLs(importStringified, rule.styleSheet.href);\n }\n } catch {\n }\n return importStringified;\n } else {\n let ruleStringified = rule.cssText;\n if (isCSSStyleRule(rule) && rule.selectorText.includes(\":\")) {\n ruleStringified = fixSafariColons(ruleStringified);\n }\n if (sheetHref) {\n return absolutifyURLs(ruleStringified, sheetHref);\n }\n return ruleStringified;\n }\n}\nfunction fixSafariColons(cssStringified) {\n const regex = /(\\[(?:[\\w-]+)[^\\\\])(:(?:[\\w-]+)\\])/gm;\n return cssStringified.replace(regex, \"$1\\\\$2\");\n}\nfunction isCSSImportRule(rule) {\n return \"styleSheet\" in rule;\n}\nfunction isCSSStyleRule(rule) {\n return \"selectorText\" in rule;\n}\nclass Mirror {\n constructor() {\n __publicField(this, \"idNodeMap\", /* @__PURE__ */ new Map());\n __publicField(this, \"nodeMetaMap\", /* @__PURE__ */ new WeakMap());\n }\n getId(n) {\n var _a2;\n if (!n) return -1;\n const id = (_a2 = this.getMeta(n)) == null ? void 0 : _a2.id;\n return id ?? -1;\n }\n getNode(id) {\n return this.idNodeMap.get(id) || null;\n }\n getIds() {\n return Array.from(this.idNodeMap.keys());\n }\n getMeta(n) {\n return this.nodeMetaMap.get(n) || null;\n }\n // removes the node from idNodeMap\n // doesn't remove the node from nodeMetaMap\n removeNodeFromMap(n) {\n const id = this.getId(n);\n this.idNodeMap.delete(id);\n if (n.childNodes) {\n n.childNodes.forEach(\n (childNode) => this.removeNodeFromMap(childNode)\n );\n }\n if (isElement(n)) {\n const shadowRootEl = index.shadowRoot(n);\n if (shadowRootEl) {\n this.removeNodeFromMap(shadowRootEl);\n }\n if (n.nodeName === \"IFRAME\" && n.contentDocument) {\n this.removeNodeFromMap(\n n.contentDocument\n );\n }\n }\n }\n has(id) {\n return this.idNodeMap.has(id);\n }\n hasNode(node) {\n return this.nodeMetaMap.has(node);\n }\n add(n, meta) {\n const id = meta.id;\n this.idNodeMap.set(id, n);\n this.nodeMetaMap.set(n, meta);\n }\n replace(id, n) {\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 reset() {\n this.idNodeMap = /* @__PURE__ */ new Map();\n this.nodeMetaMap = /* @__PURE__ */ new WeakMap();\n }\n}\nfunction createMirror() {\n return new Mirror();\n}\nfunction maskInputValue({\n element,\n maskInputOptions,\n tagName,\n type,\n value,\n maskInputFn\n}) {\n let text = value || \"\";\n const actualType = type && toLowerCase(type);\n if (maskInputOptions[tagName.toLowerCase()] || actualType && maskInputOptions[actualType]) {\n if (maskInputFn) {\n text = maskInputFn(text, element);\n } else {\n text = \"*\".repeat(text.length);\n }\n }\n return text;\n}\nfunction toLowerCase(str) {\n return str.toLowerCase();\n}\nconst ORIGINAL_ATTRIBUTE_NAME = \"__rrweb_original__\";\nfunction is2DCanvasBlank(canvas) {\n const ctx = canvas.getContext(\"2d\");\n if (!ctx) return true;\n const chunkSize = 50;\n for (let x = 0; x < canvas.width; x += chunkSize) {\n for (let y = 0; y < canvas.height; y += chunkSize) {\n const getImageData = ctx.getImageData;\n const originalGetImageData = ORIGINAL_ATTRIBUTE_NAME in getImageData ? getImageData[ORIGINAL_ATTRIBUTE_NAME] : getImageData;\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}\nfunction getInputType(element) {\n const type = element.type;\n return element.hasAttribute(\"data-rr-is-password\") ? \"password\" : type ? (\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion\n toLowerCase(type)\n ) : null;\n}\nfunction extractFileExtension(path, baseURL) {\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 == null ? void 0 : match[1]) ?? null;\n}\nfunction extractOrigin(url) {\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}\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;\nfunction absolutifyURLs(cssText, href) {\n return (cssText || \"\").replace(\n URL_IN_CSS_REF,\n (origin, quote1, path1, quote2, path2, path3) => {\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}${extractOrigin(href) + filePath}${maybeQuote})`;\n }\n const stack = href.split(\"/\");\n const parts = filePath.split(\"/\");\n stack.pop();\n for (const part of parts) {\n if (part === \".\") {\n continue;\n } else if (part === \"..\") {\n stack.pop();\n } else {\n stack.push(part);\n }\n }\n return `url(${maybeQuote}${stack.join(\"/\")}${maybeQuote})`;\n }\n );\n}\nconst STRIPED_PLACEHOLDER_SVG = \"data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgogIDxkZWZzPgogICAgPHBhdHRlcm4gaWQ9InN0cmlwZXMiIHBhdHRlcm5Vbml0cz0idXNlclNwYWNlT25Vc2UiIHdpZHRoPSIxNiIgaGVpZ2h0PSIxNiI+CiAgICAgIDxyZWN0IHdpZHRoPSIxNiIgaGVpZ2h0PSIxNiIgZmlsbD0iYmxhY2siLz4KICAgICAgPHBhdGggZD0iTTggMEgxNkwwIDE2VjhMOCAwWiIgZmlsbD0iIzJEMkQyRCIvPgogICAgICA8cGF0aCBkPSJNMTYgOFYxNkg4TDE2IDhaIiBmaWxsPSIjMkQyRDJEIi8+CiAgICA8L3BhdHRlcm4+CiAgPC9kZWZzPgogIDxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjc3RyaXBlcykiLz4KPC9zdmc+Cg==\";\nconst MAX_IMAGE_DIMENSION_FOR_RECOMPRESSION = 4096;\nfunction recompressBase64Image(img, dataURL, type, quality) {\n if (!img.complete || img.naturalWidth === 0) {\n return dataURL;\n }\n if (img.naturalWidth > MAX_IMAGE_DIMENSION_FOR_RECOMPRESSION || img.naturalHeight > MAX_IMAGE_DIMENSION_FOR_RECOMPRESSION) {\n return dataURL;\n }\n try {\n const canvas = document.createElement(\"canvas\");\n canvas.width = img.naturalWidth;\n canvas.height = img.naturalHeight;\n const ctx = canvas.getContext(\"2d\");\n if (!ctx) {\n return dataURL;\n }\n ctx.drawImage(img, 0, 0);\n const recompressed = canvas.toDataURL(type || \"image/webp\", quality ?? 0.4);\n return recompressed;\n } catch (err) {\n return dataURL;\n }\n}\nfunction checkDataURLSize(dataURL, maxLength) {\n if (!maxLength || dataURL.length <= maxLength) {\n return dataURL;\n }\n return STRIPED_PLACEHOLDER_SVG;\n}\nlet _id = 1;\nconst tagNameRegex = new RegExp(\"[^a-z0-9-_:]\");\nconst IGNORED_NODE = -2;\nfunction genId() {\n return _id++;\n}\nfunction getValidTagName(element) {\n if (element instanceof HTMLFormElement) {\n return \"form\";\n }\n const processedTagName = toLowerCase(element.tagName);\n if (tagNameRegex.test(processedTagName)) {\n return \"div\";\n }\n return processedTagName;\n}\nlet canvasService;\nlet canvasCtx;\nconst SRCSET_NOT_SPACES = /^[^ \\t\\n\\r\\u000c]+/;\nconst SRCSET_COMMAS_OR_SPACES = /^[, \\t\\n\\r\\u000c]+/;\nfunction getAbsoluteSrcsetString(doc, attributeValue) {\n if (attributeValue.trim() === \"\") {\n return attributeValue;\n }\n let pos = 0;\n function collectCharacters(regEx) {\n let chars2;\n const match = regEx.exec(attributeValue.substring(pos));\n if (match) {\n chars2 = match[0];\n pos += chars2.length;\n return chars2;\n }\n return \"\";\n }\n const output = [];\n while (true) {\n collectCharacters(SRCSET_COMMAS_OR_SPACES);\n if (pos >= attributeValue.length) {\n break;\n }\n let url = collectCharacters(SRCSET_NOT_SPACES);\n if (url.slice(-1) === \",\") {\n url = absoluteToDoc(doc, url.substring(0, url.length - 1));\n output.push(url);\n } else {\n let descriptorsStr = \"\";\n url = absoluteToDoc(doc, url);\n let inParens = false;\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;\n } else if (c === \"(\") {\n inParens = true;\n }\n } else {\n if (c === \")\") {\n inParens = false;\n }\n }\n descriptorsStr += c;\n pos += 1;\n }\n }\n }\n return output.join(\", \");\n}\nconst cachedDocument = /* @__PURE__ */ new WeakMap();\nfunction absoluteToDoc(doc, attributeValue) {\n if (!attributeValue || attributeValue.trim() === \"\") {\n return attributeValue;\n }\n return getHref(doc, attributeValue);\n}\nfunction isSVGElement(el) {\n return Boolean(el.tagName === \"svg\" || el.ownerSVGElement);\n}\nfunction getHref(doc, customHref) {\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 a.setAttribute(\"href\", customHref);\n return a.href;\n}\nfunction capDataURLSize(dataURL, dataURLOptions) {\n if (dataURLOptions == null ? void 0 : dataURLOptions.maxBase64ImageLength) {\n return checkDataURLSize(dataURL, dataURLOptions.maxBase64ImageLength);\n }\n return dataURL;\n}\nfunction transformAttribute(doc, tagName, name, value, element, dataURLOptions) {\n var _a2;\n if (!value) {\n return value;\n }\n if (name === \"src\" || name === \"href\" && !(tagName === \"use\" && value[0] === \"#\")) {\n if (tagName === \"link\" && element) {\n const sheetHref = (_a2 = element.sheet) == null ? void 0 : _a2.href;\n if (sheetHref) {\n return sheetHref;\n }\n }\n const transformedValue = absoluteToDoc(doc, value);\n if (transformedValue.startsWith(\"data:\")) {\n if (tagName === \"img\" && element) {\n let processedDataURL = transformedValue;\n if ((dataURLOptions == null ? void 0 : dataURLOptions.type) || (dataURLOptions == null ? void 0 : dataURLOptions.quality) !== void 0) {\n processedDataURL = recompressBase64Image(\n element,\n transformedValue,\n dataURLOptions.type,\n dataURLOptions.quality\n );\n }\n return capDataURLSize(processedDataURL, dataURLOptions);\n }\n if (tagName === \"image\") {\n return capDataURLSize(transformedValue, dataURLOptions);\n }\n }\n return transformedValue;\n } else if (name === \"xlink:href\" && value[0] !== \"#\") {\n const transformedValue = absoluteToDoc(doc, value);\n if (tagName === \"image\" && transformedValue.startsWith(\"data:\")) {\n return capDataURLSize(transformedValue, dataURLOptions);\n }\n return transformedValue;\n } else if (name === \"background\" && (tagName === \"table\" || tagName === \"td\" || tagName === \"th\")) {\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 return value;\n}\nfunction ignoreAttribute(tagName, name, _value) {\n return (tagName === \"video\" || tagName === \"audio\") && name === \"autoplay\";\n}\nfunction _isBlockedElement(element, blockClass, blockSelector) {\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 return false;\n}\nfunction classMatchesRegex(node, regex, checkAncestors) {\n if (!node) return false;\n if (node.nodeType !== node.ELEMENT_NODE) {\n if (!checkAncestors) return false;\n return classMatchesRegex(index.parentNode(node), regex, checkAncestors);\n }\n for (let eIndex = node.classList.length; eIndex--; ) {\n const className = node.classList[eIndex];\n if (regex.test(className)) {\n return true;\n }\n }\n if (!checkAncestors) return false;\n return classMatchesRegex(index.parentNode(node), regex, checkAncestors);\n}\nfunction needMaskingText(node, maskTextClass, maskTextSelector, checkAncestors) {\n let el;\n if (isElement(node)) {\n el = node;\n if (!index.childNodes(el).length) {\n return false;\n }\n } else if (index.parentElement(node) === null) {\n return false;\n } else {\n el = index.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 return false;\n}\nfunction onceIframeLoaded(iframeEl, listener, iframeLoadTimeout) {\n const noop = () => {\n };\n const win = iframeEl.contentWindow;\n if (!win) {\n return noop;\n }\n let readyState;\n try {\n readyState = win.document.readyState;\n } catch (error) {\n return noop;\n }\n const onSubsequentLoad = () => listener();\n if (readyState !== \"complete\") {\n let fired = false;\n let timer = null;\n const fireOnce = () => {\n if (fired) return;\n fired = true;\n if (timer !== null) {\n clearTimeout(timer);\n timer = null;\n }\n iframeEl.removeEventListener(\"load\", onInitialLoad);\n iframeEl.addEventListener(\"load\", onSubsequentLoad);\n listener();\n };\n const onInitialLoad = () => fireOnce();\n timer = setTimeout(fireOnce, iframeLoadTimeout);\n iframeEl.addEventListener(\"load\", onInitialLoad);\n return () => {\n if (timer !== null) {\n clearTimeout(timer);\n timer = null;\n }\n if (fired) {\n iframeEl.removeEventListener(\"load\", onSubsequentLoad);\n } else {\n fired = true;\n iframeEl.removeEventListener(\"load\", onInitialLoad);\n }\n };\n }\n const blankUrl = \"about:blank\";\n let winLocationHref;\n try {\n winLocationHref = win.location.href;\n } catch {\n return noop;\n }\n if (winLocationHref !== blankUrl || iframeEl.src === blankUrl || iframeEl.src === \"\") {\n const initialTimer = setTimeout(listener, 0);\n iframeEl.addEventListener(\"load\", onSubsequentLoad);\n return () => {\n clearTimeout(initialTimer);\n iframeEl.removeEventListener(\"load\", onSubsequentLoad);\n };\n }\n iframeEl.addEventListener(\"load\", onSubsequentLoad);\n return () => {\n iframeEl.removeEventListener(\"load\", onSubsequentLoad);\n };\n}\nconst stylesheetLoadTracked = /* @__PURE__ */ new Map();\nfunction resetStylesheetLoadTracking() {\n stylesheetLoadTracked.forEach((controller) => controller.abort());\n stylesheetLoadTracked.clear();\n}\nfunction onceStylesheetLoaded(link, listener, styleSheetLoadTimeout) {\n if (stylesheetLoadTracked.has(link)) return;\n let styleSheetLoaded;\n try {\n styleSheetLoaded = link.sheet;\n } catch (error) {\n return;\n }\n if (styleSheetLoaded) return;\n const controller = new AbortController();\n let fired = false;\n const fire = () => {\n if (fired) return;\n fired = true;\n try {\n listener();\n } finally {\n stylesheetLoadTracked.delete(link);\n controller.abort();\n }\n };\n const timer = setTimeout(fire, styleSheetLoadTimeout);\n controller.signal.addEventListener(\"abort\", () => clearTimeout(timer), {\n once: true\n });\n link.addEventListener(\"load\", fire, {\n signal: controller.signal,\n once: true\n });\n stylesheetLoadTracked.set(link, controller);\n}\nfunction serializeNode(n, options) {\n const {\n doc,\n mirror: mirror2,\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 } = options;\n const rootId = getRootId(doc, mirror2);\n switch (n.nodeType) {\n case n.DOCUMENT_NODE:\n if (n.compatMode !== \"CSS1Compat\") {\n return {\n type: NodeType.Document,\n childNodes: [],\n compatMode: n.compatMode\n // 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.name,\n publicId: n.publicId,\n systemId: n.systemId,\n rootId\n };\n case n.ELEMENT_NODE:\n return serializeElementNode(n, {\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, {\n doc,\n needsMask,\n maskTextFn,\n rootId\n });\n case n.CDATA_SECTION_NODE:\n return {\n type: NodeType.CDATA,\n textContent: \"\",\n rootId\n };\n case n.COMMENT_NODE:\n return {\n type: NodeType.Comment,\n textContent: index.textContent(n) || \"\",\n rootId\n };\n default:\n return false;\n }\n}\nfunction getRootId(doc, mirror2) {\n if (!mirror2.hasNode(doc)) return void 0;\n const docId = mirror2.getId(doc);\n return docId === 1 ? void 0 : docId;\n}\nfunction serializeTextNode(n, options) {\n var _a2;\n const { needsMask, maskTextFn, rootId } = options;\n const parent = index.parentNode(n);\n const parentTagName = parent && parent.tagName;\n let text = index.textContent(n);\n const isStyle = parentTagName === \"STYLE\" ? true : void 0;\n const isScript = parentTagName === \"SCRIPT\" ? true : void 0;\n if (isStyle && text) {\n try {\n if (n.nextSibling || n.previousSibling) {\n } else if ((_a2 = parent.sheet) == null ? void 0 : _a2.cssRules) {\n const stringified = stringifyStylesheet(\n parent.sheet\n );\n if (stringified && !hasEmptyShorthandLonghand(stringified)) {\n text = stringified;\n }\n }\n } catch (err) {\n console.warn(\n `Cannot get CSS styles from text's parentNode. Error: ${err}`,\n n\n );\n }\n text = absolutifyURLs(text, getHref(options.doc));\n }\n if (isScript) {\n text = \"SCRIPT_PLACEHOLDER\";\n }\n if (!isStyle && !isScript && text && needsMask) {\n text = maskTextFn ? maskTextFn(text, index.parentElement(n)) : text.replace(/[\\S]/g, \"*\");\n }\n return {\n type: NodeType.Text,\n textContent: text || \"\",\n isStyle,\n rootId\n };\n}\nfunction findStylesheet(doc, href) {\n return Array.from(doc.styleSheets).find((s) => s.href === href);\n}\nfunction hrefFrom(n) {\n return n.href;\n}\nfunction serializeElementNode(n, options) {\n var _a2, _b, _c;\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 = {};\n const len = n.attributes.length;\n for (let i = 0; i < len; i++) {\n const attr = n.attributes[i];\n if (!ignoreAttribute(tagName, attr.name, attr.value)) {\n attributes[attr.name] = transformAttribute(\n doc,\n tagName,\n toLowerCase(attr.name),\n attr.value,\n n,\n dataURLOptions\n );\n }\n }\n if (tagName === \"link\" && inlineStylesheet) {\n let stylesheet = n.sheet;\n if (!stylesheet) {\n const href = hrefFrom(n);\n if (href) {\n stylesheet = findStylesheet(doc, href);\n if (!stylesheet && href.includes(\".css\")) {\n const rootDomain = window.location.origin;\n const stylesheetPath = href.replace(window.location.href, \"\");\n const potentialStylesheetHref = rootDomain + \"/\" + stylesheetPath;\n stylesheet = findStylesheet(doc, potentialStylesheetHref);\n }\n }\n }\n let cssText = 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.sheet && // TODO: Currently we only try to get dynamic stylesheet when it is an empty style element\n !(n.innerText || index.textContent(n) || \"\").trim().length) {\n const cssText = stringifyStylesheet(\n n.sheet\n );\n if (cssText) {\n attributes._cssText = cssText;\n }\n }\n if (tagName === \"input\" || tagName === \"textarea\" || tagName === \"select\") {\n const value = n.value;\n const checked = n.checked;\n if (attributes.type !== \"radio\" && attributes.type !== \"checkbox\" && attributes.type !== \"submit\" && attributes.type !== \"button\" && value) {\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.selected && !maskInputOptions[\"select\"]) {\n attributes.selected = true;\n } else {\n delete attributes.selected;\n }\n }\n if (tagName === \"dialog\" && n.open) {\n try {\n attributes.rr_open_mode = n.matches(\"dialog:modal\") ? \"modal\" : \"non-modal\";\n } catch {\n attributes.rr_open_mode = \"modal\";\n attributes.ph_rr_could_not_detect_modal = true;\n }\n }\n if (tagName === \"canvas\" && recordCanvas) {\n if (n.__context === \"2d\") {\n if (!is2DCanvasBlank(n)) {\n attributes.rr_dataURL = n.toDataURL(\n dataURLOptions.type,\n dataURLOptions.quality\n );\n }\n } else if (!(\"__context\" in n)) {\n const canvasDataURL = n.toDataURL(\n dataURLOptions.type,\n dataURLOptions.quality\n );\n const blankCanvas = doc.createElement(\"canvas\");\n blankCanvas.width = n.width;\n blankCanvas.height = n.height;\n const blankCanvasDataURL = blankCanvas.toDataURL(\n dataURLOptions.type,\n dataURLOptions.quality\n );\n if (canvasDataURL !== blankCanvasDataURL) {\n attributes.rr_dataURL = canvasDataURL;\n }\n }\n }\n if (tagName === \"img\" && inlineImages) {\n if (!canvasService) {\n canvasService = doc.createElement(\"canvas\");\n canvasCtx = canvasService.getContext(\"2d\");\n }\n const image = n;\n const imageSrc = 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();\n else image.addEventListener(\"load\", recordInlineImage);\n return;\n } else {\n console.warn(\n `Cannot inline img src=${imageSrc}! Error: ${err}`\n );\n }\n }\n if (image.crossOrigin === \"anonymous\") {\n priorCrossOrigin ? attributes.crossOrigin = priorCrossOrigin : image.removeAttribute(\"crossorigin\");\n }\n };\n if (image.complete && image.naturalWidth !== 0) recordInlineImage();\n else image.addEventListener(\"load\", recordInlineImage);\n }\n if (tagName === \"audio\" || tagName === \"video\") {\n const mediaAttributes = attributes;\n mediaAttributes.rr_mediaState = n.paused ? \"paused\" : \"played\";\n mediaAttributes.rr_mediaCurrentTime = n.currentTime;\n mediaAttributes.rr_mediaPlaybackRate = n.playbackRate;\n mediaAttributes.rr_mediaMuted = n.muted;\n mediaAttributes.rr_mediaLoop = n.loop;\n mediaAttributes.rr_mediaVolume = n.volume;\n }\n if (!newlyAddedElement) {\n if (n.scrollLeft) {\n attributes.rr_scrollLeft = n.scrollLeft;\n }\n if (n.scrollTop) {\n attributes.rr_scrollTop = n.scrollTop;\n }\n }\n if (needBlock) {\n const { width, height, left, top } = n.getBoundingClientRect();\n const computed = (_a2 = doc.defaultView) == null ? void 0 : _a2.getComputedStyle(n);\n attributes = {\n class: attributes.class,\n rr_width: `${width}px`,\n rr_height: `${height}px`,\n rr_left: `${Math.floor(left + (((_b = doc.defaultView) == null ? void 0 : _b.scrollX) || 0))}px`,\n rr_top: `${Math.floor(top + (((_c = doc.defaultView) == null ? void 0 : _c.scrollY) || 0))}px`\n };\n if (computed) {\n attributes.rr_position = computed.position || \"static\";\n if (computed.transform && computed.transform !== \"none\") {\n attributes.rr_transform = computed.transform;\n }\n if (computed.display && computed.display.startsWith(\"inline\")) {\n attributes.rr_display = computed.display;\n }\n }\n }\n if (tagName === \"iframe\" && !keepIframeSrcFn(attributes.src)) {\n if (!n.contentDocument) {\n attributes.rr_src = attributes.src;\n }\n delete attributes.src;\n }\n let isCustomElement;\n try {\n if (customElements.get(tagName)) isCustomElement = true;\n } catch (e) {\n }\n return {\n type: NodeType.Element,\n tagName,\n attributes,\n childNodes: [],\n isSVG: isSVGElement(n) || void 0,\n needBlock,\n rootId,\n isCustom: isCustomElement\n };\n}\nfunction lowerIfExists(maybeAttr) {\n if (maybeAttr === void 0 || maybeAttr === null) {\n return \"\";\n } else {\n return maybeAttr.toLowerCase();\n }\n}\nfunction slimDOMExcluded(sn, slimDOMOptions) {\n if (slimDOMOptions.comment && sn.type === NodeType.Comment) {\n return true;\n } else if (sn.type === NodeType.Element) {\n if (slimDOMOptions.script && // script tag\n (sn.tagName === \"script\" || // (module)preload link\n sn.tagName === \"link\" && (sn.attributes.rel === \"preload\" && sn.attributes.as === \"script\" || sn.attributes.rel === \"modulepreload\") || // prefetch link\n sn.tagName === \"link\" && sn.attributes.rel === \"prefetch\" && typeof sn.attributes.href === \"string\" && extractFileExtension(sn.attributes.href) === \"js\")) {\n return true;\n } else if (slimDOMOptions.headFavicon && (sn.tagName === \"link\" && sn.attributes.rel === \"shortcut icon\" || sn.tagName === \"meta\" && (lowerIfExists(sn.attributes.name).match(\n /^msapplication-tile(image|color)$/\n ) || lowerIfExists(sn.attributes.name) === \"application-name\" || [\"icon\", \"apple-touch-icon\", \"shortcut icon\"].includes(\n lowerIfExists(sn.attributes.rel)\n )))) {\n return true;\n } else if (sn.tagName === \"meta\") {\n if (slimDOMOptions.headMetaDescKeywords && lowerIfExists(sn.attributes.name).match(/^description|keywords$/)) {\n return true;\n } else if (slimDOMOptions.headMetaSocial && (lowerIfExists(sn.attributes.property).match(/^(og|twitter|fb):/) || // og = opengraph (facebook)\n lowerIfExists(sn.attributes.name).match(/^(og|twitter):/) || lowerIfExists(sn.attributes.name) === \"pinterest\")) {\n return true;\n } else if (slimDOMOptions.headMetaRobots && [\"robots\", \"googlebot\", \"bingbot\"].includes(\n lowerIfExists(sn.attributes.name)\n )) {\n return true;\n } else if (slimDOMOptions.headMetaHttpEquiv && sn.attributes[\"http-equiv\"] !== void 0) {\n return true;\n } else if (slimDOMOptions.headMetaAuthorship && ([\"author\", \"generator\", \"framework\", \"publisher\", \"progid\"].includes(\n lowerIfExists(sn.attributes.name)\n ) || lowerIfExists(sn.attributes.property).match(/^article:/) || lowerIfExists(sn.attributes.property).match(/^product:/))) {\n return true;\n } else if (slimDOMOptions.headMetaVerification && [\n \"google-site-verification\",\n \"yandex-verification\",\n \"csrf-token\",\n \"p:domain_verify\",\n \"verify-v1\",\n \"verification\",\n \"shopify-checkout-api-token\"\n ].includes(lowerIfExists(sn.attributes.name))) {\n return true;\n }\n }\n }\n return false;\n}\nconst DEFAULT_MAX_DEPTH = 50;\nlet _maxDepthWarned = false;\nlet _maxDepthReached = false;\nfunction wasMaxDepthReached() {\n return _maxDepthReached;\n}\nfunction resetMaxDepthState() {\n _maxDepthReached = false;\n _maxDepthWarned = false;\n}\nfunction serializeNodeWithId(n, options) {\n const {\n doc,\n mirror: mirror2,\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 = 5e3,\n onIframeListenerRegistered,\n onStylesheetLoad,\n stylesheetLoadTimeout = 5e3,\n keepIframeSrcFn = () => false,\n newlyAddedElement = false,\n depth = 0,\n maxDepth = DEFAULT_MAX_DEPTH\n } = options;\n let { needsMask } = options;\n let { preserveWhiteSpace = true } = options;\n if (depth >= maxDepth) {\n _maxDepthReached = true;\n if (!_maxDepthWarned) {\n _maxDepthWarned = true;\n console.warn(\n `[rrweb-snapshot] DOM tree depth exceeded max depth of ${maxDepth}. Children beyond this depth will not be recorded. This may indicate deeply nested DOM structures.`\n );\n }\n return null;\n }\n if (!needsMask) {\n const checkAncestors = needsMask === void 0;\n needsMask = needMaskingText(\n n,\n maskTextClass,\n maskTextSelector,\n checkAncestors\n );\n }\n const _serializedNode = serializeNode(n, {\n doc,\n mirror: mirror2,\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 });\n if (!_serializedNode) {\n console.warn(n, \"not serialized\");\n return null;\n }\n let id;\n if (mirror2.hasNode(n)) {\n id = mirror2.getId(n);\n } else if (slimDOMExcluded(_serializedNode, slimDOMOptions) || !preserveWhiteSpace && _serializedNode.type === NodeType.Text && !_serializedNode.isStyle && // codeql[js/polynomial-redos] Bounded DOM text node; worst case is recorder slowdown, no exploit.\n !_serializedNode.textContent.replace(/^\\s+|\\s+$/gm, \"\").length) {\n id = IGNORED_NODE;\n } else {\n id = genId();\n }\n const serializedNode = Object.assign(_serializedNode, { id });\n mirror2.add(n, serializedNode);\n if (id === IGNORED_NODE) {\n return null;\n }\n if (onSerialize) {\n onSerialize(n);\n }\n let recordChild = !skipChild;\n if (serializedNode.type === NodeType.Element) {\n recordChild = recordChild && !serializedNode.needBlock;\n delete serializedNode.needBlock;\n const shadowRootEl = index.shadowRoot(n);\n if (shadowRootEl && isNativeShadowDom(shadowRootEl))\n serializedNode.isShadowHost = true;\n }\n if ((serializedNode.type === NodeType.Document || serializedNode.type === NodeType.Element) && recordChild) {\n if (slimDOMOptions.headWhitespace && serializedNode.type === NodeType.Element && serializedNode.tagName === \"head\") {\n preserveWhiteSpace = false;\n }\n const bypassOptions = {\n doc,\n mirror: mirror2,\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 onIframeListenerRegistered,\n onStylesheetLoad,\n stylesheetLoadTimeout,\n keepIframeSrcFn,\n depth: depth + 1,\n maxDepth\n };\n if (serializedNode.type === NodeType.Element && serializedNode.tagName === \"textarea\" && serializedNode.attributes.value !== void 0) ;\n else {\n for (const childN of Array.from(index.childNodes(n))) {\n const serializedChildNode = serializeNodeWithId(childN, bypassOptions);\n if (serializedChildNode) {\n serializedNode.childNodes.push(serializedChildNode);\n }\n }\n }\n let shadowRootEl = null;\n if (isElement(n) && (shadowRootEl = index.shadowRoot(n))) {\n for (const childN of Array.from(index.childNodes(shadowRootEl))) {\n const serializedChildNode = serializeNodeWithId(childN, bypassOptions);\n if (serializedChildNode) {\n isNativeShadowDom(shadowRootEl) && (serializedChildNode.isShadow = true);\n serializedNode.childNodes.push(serializedChildNode);\n }\n }\n }\n }\n const parent = index.parentNode(n);\n if (parent && isShadowRoot(parent) && isNativeShadowDom(parent)) {\n serializedNode.isShadow = true;\n }\n if (serializedNode.type === NodeType.Element && serializedNode.tagName === \"iframe\") {\n const iframeDisposer = onceIframeLoaded(\n n,\n () => {\n const iframeDoc = n.contentDocument;\n if (iframeDoc && onIframeLoad) {\n const serializedIframeNode = serializeNodeWithId(iframeDoc, {\n doc: iframeDoc,\n mirror: mirror2,\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 onIframeListenerRegistered,\n onStylesheetLoad,\n stylesheetLoadTimeout,\n keepIframeSrcFn,\n depth: depth + 1,\n maxDepth\n });\n if (serializedIframeNode) {\n onIframeLoad(\n n,\n serializedIframeNode\n );\n }\n }\n },\n iframeLoadTimeout\n );\n onIframeListenerRegistered == null ? void 0 : onIframeListenerRegistered(n, iframeDisposer);\n }\n if (serializedNode.type === NodeType.Element && serializedNode.tagName === \"link\" && serializedNode.attributes.rel === \"stylesheet\") {\n onceStylesheetLoaded(\n n,\n () => {\n if (onStylesheetLoad) {\n const serializedLinkNode = serializeNodeWithId(n, {\n doc,\n mirror: mirror2,\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 depth,\n maxDepth\n });\n if (serializedLinkNode) {\n onStylesheetLoad(\n n,\n serializedLinkNode\n );\n }\n }\n },\n stylesheetLoadTimeout\n );\n }\n return serializedNode;\n}\nfunction slimDOMDefaults(slimDOM) {\n if (slimDOM === true || slimDOM === \"all\") {\n return {\n script: true,\n comment: true,\n headFavicon: true,\n headWhitespace: true,\n headMetaSocial: true,\n headMetaRobots: true,\n headMetaHttpEquiv: true,\n headMetaVerification: true,\n headMetaAuthorship: slimDOM === \"all\",\n headMetaDescKeywords: slimDOM === \"all\",\n headTitleMutations: slimDOM === \"all\"\n };\n }\n if (slimDOM === false) {\n return {};\n }\n return slimDOM;\n}\nfunction snapshot(n, options) {\n const {\n mirror: mirror2 = 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 onIframeListenerRegistered,\n onStylesheetLoad,\n stylesheetLoadTimeout,\n keepIframeSrcFn = () => false,\n maxDepth\n } = options || {};\n const maskInputOptions = maskAllInputs === true ? {\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 } : maskAllInputs === false ? {\n password: true\n } : maskAllInputs;\n const slimDOMOptions = slimDOMDefaults(slimDOM);\n return serializeNodeWithId(n, {\n doc: n,\n mirror: mirror2,\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 onIframeListenerRegistered,\n onStylesheetLoad,\n stylesheetLoadTimeout,\n keepIframeSrcFn,\n newlyAddedElement: false,\n maxDepth\n });\n}\nclass BaseRRNode {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any\n constructor(..._args) {\n __publicField(this, \"parentElement\", null);\n __publicField(this, \"parentNode\", null);\n __publicField(this, \"ownerDocument\");\n __publicField(this, \"firstChild\", null);\n __publicField(this, \"lastChild\", null);\n __publicField(this, \"previousSibling\", null);\n __publicField(this, \"nextSibling\", null);\n __publicField(this, \"ELEMENT_NODE\", 1);\n __publicField(this, \"TEXT_NODE\", 3);\n // corresponding nodeType value of standard HTML Node\n __publicField(this, \"nodeType\");\n __publicField(this, \"nodeName\");\n __publicField(this, \"RRNodeType\");\n }\n get childNodes() {\n const childNodes2 = [];\n let childIterator = this.firstChild;\n while (childIterator) {\n childNodes2.push(childIterator);\n childIterator = childIterator.nextSibling;\n }\n return childNodes2;\n }\n contains(node) {\n if (!(node instanceof BaseRRNode)) return false;\n else if (node.ownerDocument !== this.ownerDocument) return false;\n else if (node === this) return true;\n while (node.parentNode) {\n if (node.parentNode === this) return true;\n node = node.parentNode;\n }\n return false;\n }\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n appendChild(_newChild) {\n throw new Error(\n `RRDomException: Failed to execute 'appendChild' on 'RRNode': This RRNode type does not support this method.`\n );\n }\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n insertBefore(_newChild, _refChild) {\n throw new Error(\n `RRDomException: Failed to execute 'insertBefore' on 'RRNode': This RRNode type does not support this method.`\n );\n }\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n removeChild(_node) {\n throw new Error(\n `RRDomException: Failed to execute 'removeChild' on 'RRNode': This RRNode type does not support this method.`\n );\n }\n toString() {\n return \"RRNode\";\n }\n}\nfunction on(type, fn, target = document) {\n const options = { capture: true, passive: true };\n target.addEventListener(type, fn, options);\n return () => target.removeEventListener(type, fn, options);\n}\nfunction callSafely(fn) {\n try {\n fn();\n } catch (error) {\n if (!(error instanceof DOMException && error.name === \"SecurityError\")) {\n throw error;\n }\n }\n}\nconst DEPARTED_MIRROR_ACCESS_WARNING = \"Please stop import mirror directly. Instead of that,\\r\\nnow you can use replayer.getMirror() to access the mirror instance of a replayer,\\r\\nor you can use record.mirror to access the mirror instance during recording.\";\nlet _mirror = {\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 return Reflect.get(target, prop, receiver);\n }\n });\n}\nfunction throttle(func, wait, options = {}) {\n let timeout = null;\n let previous = 0;\n return function(...args) {\n const now = Date.now();\n if (!previous && options.leading === false) {\n previous = now;\n }\n const remaining = wait - (now - previous);\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}\nfunction hookSetter(target, key, d, isRevoked, win = window) {\n const original = win.Object.getOwnPropertyDescriptor(target, key);\n win.Object.defineProperty(\n target,\n key,\n isRevoked ? d : {\n set(value) {\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}\nlet nowTimestamp = Date.now;\nif (!/* @__PURE__ */ /[1-9][0-9]{12}/.test(Date.now().toString())) {\n nowTimestamp = () => (/* @__PURE__ */ new Date()).getTime();\n}\nfunction getWindowScroll(win) {\n var _a2, _b, _c, _d;\n const doc = win.document;\n return {\n left: doc.scrollingElement ? doc.scrollingElement.scrollLeft : win.pageXOffset !== void 0 ? win.pageXOffset : doc.documentElement.scrollLeft || (doc == null ? void 0 : doc.body) && ((_a2 = index.parentElement(doc.body)) == null ? void 0 : _a2.scrollLeft) || ((_b = doc == null ? void 0 : doc.body) == null ? void 0 : _b.scrollLeft) || 0,\n top: doc.scrollingElement ? doc.scrollingElement.scrollTop : win.pageYOffset !== void 0 ? win.pageYOffset : (doc == null ? void 0 : doc.documentElement.scrollTop) || (doc == null ? void 0 : doc.body) && ((_c = index.parentElement(doc.body)) == null ? void 0 : _c.scrollTop) || ((_d = doc == null ? void 0 : doc.body) == null ? void 0 : _d.scrollTop) || 0\n };\n}\nfunction getWindowHeight() {\n return window.innerHeight || document.documentElement && document.documentElement.clientHeight || document.body && document.body.clientHeight;\n}\nfunction getWindowWidth() {\n return window.innerWidth || document.documentElement && document.documentElement.clientWidth || document.body && document.body.clientWidth;\n}\nfunction closestElementOfNode(node) {\n if (!node) {\n return null;\n }\n const el = node.nodeType === node.ELEMENT_NODE ? node : index.parentElement(node);\n return el;\n}\nfunction isBlocked(node, blockClass, blockSelector, checkAncestors) {\n if (!node) {\n return false;\n }\n const el = closestElementOfNode(node);\n if (!el) {\n return false;\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 }\n if (blockSelector) {\n if (el.matches(blockSelector)) return true;\n if (checkAncestors && el.closest(blockSelector) !== null) return true;\n }\n return false;\n}\nfunction isSerialized(n, mirror2) {\n return mirror2.getId(n) !== -1;\n}\nfunction isIgnored(n, mirror2, slimDOMOptions) {\n if (n.tagName === \"TITLE\" && slimDOMOptions.headTitleMutations) {\n return true;\n }\n return mirror2.getId(n) === IGNORED_NODE;\n}\nfunction isAncestorRemoved(target, mirror2) {\n if (isShadowRoot(target)) {\n return false;\n }\n const id = mirror2.getId(target);\n if (!mirror2.has(id)) {\n return true;\n }\n const parent = index.parentNode(target);\n if (parent && parent.nodeType === target.DOCUMENT_NODE) {\n return false;\n }\n if (!parent) {\n return true;\n }\n return isAncestorRemoved(parent, mirror2);\n}\nfunction legacy_isTouchEvent(event) {\n return Boolean(event.changedTouches);\n}\nfunction polyfill(win = window) {\n if (\"NodeList\" in win && !win.NodeList.prototype.forEach) {\n win.NodeList.prototype.forEach = Array.prototype.forEach;\n }\n if (\"DOMTokenList\" in win && !win.DOMTokenList.prototype.forEach) {\n win.DOMTokenList.prototype.forEach = Array.prototype.forEach;\n }\n}\nfunction isSerializedIframe(n, mirror2) {\n return Boolean(n.nodeName === \"IFRAME\" && mirror2.getMeta(n));\n}\nfunction isSerializedStylesheet(n, mirror2) {\n return Boolean(\n n.nodeName === \"LINK\" && n.nodeType === n.ELEMENT_NODE && n.getAttribute && n.getAttribute(\"rel\") === \"stylesheet\" && mirror2.getMeta(n)\n );\n}\nfunction hasShadowRoot(n) {\n if (!n) return false;\n if (n instanceof BaseRRNode && \"shadowRoot\" in n) {\n return Boolean(n.shadowRoot);\n }\n return Boolean(index.shadowRoot(n));\n}\nclass StyleSheetMirror {\n constructor() {\n __publicField(this, \"id\", 1);\n __publicField(this, \"styleIDMap\", /* @__PURE__ */ new WeakMap());\n __publicField(this, \"idStyleMap\", /* @__PURE__ */ new Map());\n }\n getId(stylesheet) {\n return this.styleIDMap.get(stylesheet) ?? -1;\n }\n has(stylesheet) {\n return this.styleIDMap.has(stylesheet);\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, id) {\n if (this.has(stylesheet)) return this.getId(stylesheet);\n let newId;\n if (id === void 0) {\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 getStyle(id) {\n return this.idStyleMap.get(id) || null;\n }\n reset() {\n this.styleIDMap = /* @__PURE__ */ new WeakMap();\n this.idStyleMap = /* @__PURE__ */ new Map();\n this.id = 1;\n }\n generateId() {\n return this.id++;\n }\n}\nfunction getShadowHost(n) {\n var _a2;\n let shadowHost = null;\n if (\"getRootNode\" in n && ((_a2 = index.getRootNode(n)) == null ? void 0 : _a2.nodeType) === Node.DOCUMENT_FRAGMENT_NODE && index.host(index.getRootNode(n)))\n shadowHost = index.host(index.getRootNode(n));\n return shadowHost;\n}\nfunction getRootShadowHost(n) {\n let rootShadowHost = n;\n let shadowHost;\n while (shadowHost = getShadowHost(rootShadowHost))\n rootShadowHost = shadowHost;\n return rootShadowHost;\n}\nfunction shadowHostInDom(n) {\n const doc = n.ownerDocument;\n if (!doc) return false;\n const shadowHost = getRootShadowHost(n);\n return index.contains(doc, shadowHost);\n}\nfunction inDom(n) {\n const doc = n.ownerDocument;\n if (!doc) return false;\n return index.contains(doc, n) || shadowHostInDom(n);\n}\nfunction isNodeInLinkedList(n) {\n return \"__ln\" in n;\n}\nclass DoubleLinkedList {\n constructor() {\n __publicField(this, \"length\", 0);\n __publicField(this, \"head\", null);\n __publicField(this, \"tail\", null);\n }\n get(position) {\n if (position >= this.length) {\n throw new Error(\"Position outside of list range\");\n }\n let current = this.head;\n for (let index2 = 0; index2 < position; index2++) {\n current = (current == null ? void 0 : current.next) || null;\n }\n return current;\n }\n addNode(n) {\n const node = {\n value: n,\n previous: null,\n next: null\n };\n n.__ln = node;\n if (n.previousSibling && isNodeInLinkedList(n.previousSibling)) {\n const current = n.previousSibling.__ln.next;\n node.next = current;\n node.previous = n.previousSibling.__ln;\n n.previousSibling.__ln.next = node;\n if (current) {\n current.previous = node;\n }\n } else if (n.nextSibling && isNodeInLinkedList(n.nextSibling) && n.nextSibling.__ln.previous) {\n const current = n.nextSibling.__ln.previous;\n node.previous = current;\n node.next = n.nextSibling.__ln;\n n.nextSibling.__ln.previous = node;\n if (current) {\n current.next = node;\n }\n } else {\n if (this.head) {\n this.head.previous = node;\n }\n node.next = this.head;\n this.head = node;\n }\n if (node.next === null) {\n this.tail = node;\n }\n this.length++;\n }\n removeNode(n) {\n const current = n.__ln;\n if (!this.head) {\n return;\n }\n if (!current.previous) {\n this.head = current.next;\n if (this.head) {\n this.head.previous = null;\n } else {\n this.tail = null;\n }\n } else {\n current.previous.next = current.next;\n if (current.next) {\n current.next.previous = current.previous;\n } else {\n this.tail = current.previous;\n }\n }\n if (n.__ln) {\n delete n.__ln;\n }\n this.length--;\n }\n}\nconst moveKey = (id, parentId) => `${id}@${parentId}`;\nclass MutationBuffer {\n constructor() {\n __publicField(this, \"frozen\", false);\n __publicField(this, \"locked\", false);\n __publicField(this, \"texts\", []);\n __publicField(this, \"attributes\", []);\n __publicField(this, \"attributeMap\", /* @__PURE__ */ new WeakMap());\n __publicField(this, \"removes\", []);\n __publicField(this, \"mapRemoves\", []);\n __publicField(this, \"movedMap\", {});\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 __publicField(this, \"addedSet\", /* @__PURE__ */ new Set());\n __publicField(this, \"movedSet\", /* @__PURE__ */ new Set());\n __publicField(this, \"droppedSet\", /* @__PURE__ */ new Set());\n __publicField(this, \"removesSubTreeCache\", /* @__PURE__ */ new Set());\n __publicField(this, \"mutationCb\");\n __publicField(this, \"blockClass\");\n __publicField(this, \"blockSelector\");\n __publicField(this, \"maskTextClass\");\n __publicField(this, \"maskTextSelector\");\n __publicField(this, \"inlineStylesheet\");\n __publicField(this, \"maskInputOptions\");\n __publicField(this, \"maskTextFn\");\n __publicField(this, \"maskInputFn\");\n __publicField(this, \"keepIframeSrcFn\");\n __publicField(this, \"recordCanvas\");\n __publicField(this, \"inlineImages\");\n __publicField(this, \"slimDOMOptions\");\n __publicField(this, \"dataURLOptions\");\n __publicField(this, \"doc\");\n __publicField(this, \"mirror\");\n __publicField(this, \"iframeManager\");\n __publicField(this, \"stylesheetManager\");\n __publicField(this, \"shadowDomManager\");\n __publicField(this, \"canvasManager\");\n __publicField(this, \"processedNodeManager\");\n __publicField(this, \"unattachedDoc\");\n __publicField(this, \"canvasManagerReleased\", false);\n __publicField(this, \"processMutations\", (mutations) => {\n mutations.forEach(this.processMutation);\n this.emit();\n });\n __publicField(this, \"emit\", () => {\n if (this.frozen || this.locked) {\n return;\n }\n const adds = [];\n const addedIds = /* @__PURE__ */ new Set();\n const addList = new DoubleLinkedList();\n const getNextId = (n) => {\n let ns = n;\n let nextId = IGNORED_NODE;\n while (nextId === IGNORED_NODE) {\n ns = ns && ns.nextSibling;\n nextId = ns && this.mirror.getId(ns);\n }\n return nextId;\n };\n const pushAdd = (n) => {\n const parent = index.parentNode(n);\n if (!parent || !inDom(n) || parent.tagName === \"TEXTAREA\") {\n return;\n }\n const parentId = isShadowRoot(parent) ? this.mirror.getId(getShadowHost(n)) : this.mirror.getId(parent);\n const nextId = getNextId(n);\n if (parentId === -1 || nextId === -1) {\n return addList.addNode(n);\n }\n const sn = serializeNodeWithId(n, {\n doc: this.doc,\n mirror: this.mirror,\n blockClass: this.blockClass,\n blockSelector: this.blockSelector,\n maskTextClass: this.maskTextClass,\n maskTextSelector: this.maskTextSelector,\n skipChild: true,\n newlyAddedElement: true,\n inlineStylesheet: this.inlineStylesheet,\n maskInputOptions: this.maskInputOptions,\n maskTextFn: this.maskTextFn,\n maskInputFn: this.maskInputFn,\n slimDOMOptions: this.slimDOMOptions,\n dataURLOptions: this.dataURLOptions,\n recordCanvas: this.recordCanvas,\n inlineImages: this.inlineImages,\n onSerialize: (currentN) => {\n if (isSerializedIframe(currentN, this.mirror)) {\n this.iframeManager.addIframe(currentN);\n }\n if (isSerializedStylesheet(currentN, this.mirror)) {\n this.stylesheetManager.trackLinkElement(\n currentN\n );\n }\n if (hasShadowRoot(n)) {\n this.shadowDomManager.addShadowRoot(index.shadowRoot(n), this.doc);\n }\n },\n onIframeLoad: (iframe, childSn) => {\n this.iframeManager.attachIframe(iframe, childSn);\n this.shadowDomManager.observeAttachShadow(iframe);\n },\n onIframeListenerRegistered: (iframe, disposer) => {\n this.iframeManager.registerLoadListenerDisposer(iframe, disposer);\n },\n onStylesheetLoad: (link, childSn) => {\n this.stylesheetManager.attachLinkElement(link, childSn);\n }\n });\n if (sn) {\n adds.push({\n parentId,\n nextId,\n node: sn\n });\n addedIds.add(sn.id);\n }\n };\n while (this.mapRemoves.length) {\n this.mirror.removeNodeFromMap(this.mapRemoves.shift());\n }\n for (const n of this.movedSet) {\n if (isParentRemoved(this.removesSubTreeCache, n, this.mirror) && !this.movedSet.has(index.parentNode(n))) {\n continue;\n }\n pushAdd(n);\n }\n for (const n of this.addedSet) {\n if (!isAncestorInSet(this.droppedSet, n) && !isParentRemoved(this.removesSubTreeCache, n, this.mirror)) {\n pushAdd(n);\n } else if (isAncestorInSet(this.movedSet, n)) {\n pushAdd(n);\n } else {\n this.droppedSet.add(n);\n }\n }\n let candidate = null;\n while (addList.length) {\n let node = null;\n if (candidate) {\n const parentId = this.mirror.getId(index.parentNode(candidate.value));\n const nextId = getNextId(candidate.value);\n if (parentId !== -1 && nextId !== -1) {\n node = candidate;\n }\n }\n if (!node) {\n let tailNode = addList.tail;\n while (tailNode) {\n const _node = tailNode;\n tailNode = tailNode.previous;\n if (_node) {\n const parentId = this.mirror.getId(index.parentNode(_node.value));\n const nextId = getNextId(_node.value);\n if (nextId === -1) continue;\n else if (parentId !== -1) {\n node = _node;\n break;\n } else {\n const unhandledNode = _node.value;\n const parent = index.parentNode(unhandledNode);\n if (parent && parent.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {\n const shadowHost = index.host(parent);\n const parentId2 = this.mirror.getId(shadowHost);\n if (parentId2 !== -1) {\n node = _node;\n break;\n }\n }\n }\n }\n }\n }\n if (!node) {\n while (addList.head) {\n addList.removeNode(addList.head.value);\n }\n break;\n }\n candidate = node.previous;\n addList.removeNode(node.value);\n pushAdd(node.value);\n }\n const payload = {\n texts: this.texts.map((text) => {\n const n = text.node;\n const parent = index.parentNode(n);\n if (parent && parent.tagName === \"TEXTAREA\") {\n this.genTextAreaValueMutation(parent);\n }\n return {\n id: this.mirror.getId(n),\n value: text.value\n };\n }).filter((text) => !addedIds.has(text.id)).filter((text) => this.mirror.has(text.id)),\n attributes: this.attributes.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 if (diffAsStr.length < attributes.style.length) {\n if ((diffAsStr + unchangedAsStr).split(\"var(\").length === attributes.style.split(\"var(\").length) {\n attributes.style = attribute.styleDiff;\n }\n }\n }\n return {\n id: this.mirror.getId(attribute.node),\n attributes\n };\n }).filter((attribute) => !addedIds.has(attribute.id)).filter((attribute) => this.mirror.has(attribute.id)),\n removes: this.removes,\n adds\n };\n if (!payload.texts.length && !payload.attributes.length && !payload.removes.length && !payload.adds.length) {\n return;\n }\n this.texts = [];\n this.attributes = [];\n this.attributeMap = /* @__PURE__ */ new WeakMap();\n this.removes = [];\n this.addedSet = /* @__PURE__ */ new Set();\n this.movedSet = /* @__PURE__ */ new Set();\n this.droppedSet = /* @__PURE__ */ new Set();\n this.removesSubTreeCache = /* @__PURE__ */ new Set();\n this.movedMap = {};\n this.mutationCb(payload);\n });\n __publicField(this, \"bufferBelongsToIframe\", (iframeEl) => {\n return this.doc === iframeEl.contentDocument;\n });\n __publicField(this, \"genTextAreaValueMutation\", (textarea) => {\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 index.childNodes(textarea),\n (cn) => index.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 __publicField(this, \"processMutation\", (m) => {\n if (isIgnored(m.target, this.mirror, this.slimDOMOptions)) {\n return;\n }\n switch (m.type) {\n case \"characterData\": {\n const value = index.textContent(m.target);\n if (!isBlocked(m.target, this.blockClass, this.blockSelector, false) && value !== m.oldValue) {\n this.texts.push({\n value: needMaskingText(\n m.target,\n this.maskTextClass,\n this.maskTextSelector,\n true\n // checkAncestors\n ) && value ? this.maskTextFn ? this.maskTextFn(value, closestElementOfNode(m.target)) : value.replace(/[\\S]/g, \"*\") : value,\n node: m.target\n });\n }\n break;\n }\n case \"attributes\": {\n const target = m.target;\n let attributeName = m.attributeName;\n let value = m.target.getAttribute(attributeName);\n if (attributeName === \"value\") {\n const type = getInputType(target);\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 (isBlocked(m.target, this.blockClass, this.blockSelector, false) || value === m.oldValue) {\n return;\n }\n let item = this.attributeMap.get(m.target);\n if (target.tagName === \"IFRAME\" && attributeName === \"src\" && !this.keepIframeSrcFn(value)) {\n if (!target.contentDocument) {\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 if (attributeName === \"type\" && target.tagName === \"INPUT\" && (m.oldValue || \"\").toLowerCase() === \"password\") {\n target.setAttribute(\"data-rr-is-password\", \"true\");\n }\n if (!ignoreAttribute(target.tagName, attributeName)) {\n item.attributes[attributeName] = transformAttribute(\n this.doc,\n toLowerCase(target.tagName),\n toLowerCase(attributeName),\n value,\n target,\n this.dataURLOptions\n );\n if (attributeName === \"style\") {\n if (!this.unattachedDoc) {\n try {\n this.unattachedDoc = document.implementation.createHTMLDocument();\n } catch (e) {\n this.unattachedDoc = this.doc;\n }\n }\n const old = this.unattachedDoc.createElement(\"span\");\n if (m.oldValue) {\n old.style.cssText = m.oldValue;\n }\n for (const pname of Array.from(target.style)) {\n const newValue = target.style.getPropertyValue(pname);\n const newPriority = target.style.getPropertyPriority(pname);\n if (newValue !== old.style.getPropertyValue(pname) || newPriority !== old.style.getPropertyPriority(pname)) {\n if (newPriority === \"\") {\n item.styleDiff[pname] = newValue;\n } else {\n item.styleDiff[pname] = [newValue, newPriority];\n }\n } else {\n item._unchangedStyles[pname] = [newValue, newPriority];\n }\n }\n for (const pname of Array.from(old.style)) {\n if (target.style.getPropertyValue(pname) === \"\") {\n item.styleDiff[pname] = false;\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 if (isBlocked(m.target, this.blockClass, this.blockSelector, true))\n return;\n if (m.target.tagName === \"TEXTAREA\") {\n this.genTextAreaValueMutation(m.target);\n return;\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) ? this.mirror.getId(index.host(m.target)) : this.mirror.getId(m.target);\n if (isBlocked(m.target, this.blockClass, this.blockSelector, false) || isIgnored(n, this.mirror, this.slimDOMOptions) || !isSerialized(n, this.mirror)) {\n return;\n }\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 else if (isAncestorRemoved(m.target, this.mirror)) ;\n else if (this.movedSet.has(n) && this.movedMap[moveKey(nodeId, parentId)]) {\n deepDelete(this.movedSet, n);\n } else {\n this.removes.push({\n parentId,\n id: nodeId,\n isShadow: isShadowRoot(m.target) && isNativeShadowDom(m.target) ? true : void 0\n });\n processRemoves(n, this.removesSubTreeCache);\n }\n this.mapRemoves.push(n);\n });\n break;\n }\n }\n });\n /**\n * Make sure you check if `n`'s parent is blocked before calling this function\n * */\n __publicField(this, \"genAdds\", (n, target) => {\n if (this.processedNodeManager.inOtherBuffer(n, this)) return;\n if (this.addedSet.has(n) || this.movedSet.has(n)) return;\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 = 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 if (!isBlocked(n, this.blockClass, this.blockSelector, false)) {\n index.childNodes(n).forEach((childN) => this.genAdds(childN));\n if (hasShadowRoot(n)) {\n index.childNodes(index.shadowRoot(n)).forEach((childN) => {\n this.processedNodeManager.add(childN, this);\n this.genAdds(childN, n);\n });\n }\n }\n });\n }\n init(options) {\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 ].forEach((key) => {\n this[key] = options[key];\n });\n this.canvasManager.acquire();\n }\n freeze() {\n this.frozen = true;\n this.canvasManager.freeze();\n }\n unfreeze() {\n this.frozen = false;\n this.canvasManager.unfreeze();\n this.emit();\n }\n isFrozen() {\n return this.frozen;\n }\n lock() {\n this.locked = true;\n this.canvasManager.lock();\n }\n unlock() {\n this.locked = false;\n this.canvasManager.unlock();\n this.emit();\n }\n reset() {\n this.shadowDomManager.reset();\n this.releaseCanvasManager();\n }\n // Releases at most once even if reset() runs twice (iframe pagehide + stop). Separate from\n // reset() so shadow-root teardown can release without re-entering shadowDomManager.reset().\n releaseCanvasManager() {\n if (this.canvasManagerReleased) {\n return;\n }\n this.canvasManagerReleased = true;\n this.canvasManager.reset();\n }\n bufferDoc() {\n return this.doc;\n }\n destroy() {\n while (this.mapRemoves.length) {\n this.mirror.removeNodeFromMap(this.mapRemoves.shift());\n }\n }\n}\nfunction deepDelete(addsSet, n) {\n addsSet.delete(n);\n index.childNodes(n).forEach((childN) => deepDelete(addsSet, childN));\n}\nfunction processRemoves(n, cache) {\n const queue = [n];\n while (queue.length) {\n const next = queue.pop();\n if (cache.has(next)) continue;\n cache.add(next);\n index.childNodes(next).forEach((n2) => queue.push(n2));\n }\n return;\n}\nfunction isParentRemoved(removes, n, mirror2) {\n if (removes.size === 0) return false;\n return _isParentRemoved(removes, n);\n}\nfunction _isParentRemoved(removes, n, _mirror2) {\n const node = index.parentNode(n);\n if (!node) return false;\n return removes.has(node);\n}\nfunction isAncestorInSet(set, n) {\n if (set.size === 0) return false;\n return _isAncestorInSet(set, n);\n}\nfunction _isAncestorInSet(set, n) {\n const parent = index.parentNode(n);\n if (!parent) {\n return false;\n }\n if (set.has(parent)) {\n return true;\n }\n return _isAncestorInSet(set, parent);\n}\nlet errorHandler;\nfunction registerErrorHandler(handler) {\n errorHandler = handler;\n}\nfunction unregisterErrorHandler() {\n errorHandler = void 0;\n}\nconst callbackWrapper = (cb) => {\n if (!errorHandler) {\n return cb;\n }\n const rrwebWrapped = ((...rest) => {\n try {\n return cb(...rest);\n } catch (error) {\n if (errorHandler && errorHandler(error) === true) {\n return;\n }\n throw error;\n }\n });\n return rrwebWrapped;\n};\nconst mutationBuffers = [];\nfunction getEventTarget(event) {\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 }\n return event && event.target;\n}\nfunction initMutationObserver(options, rootEl) {\n const mutationBuffer = new MutationBuffer();\n mutationBuffers.push(mutationBuffer);\n mutationBuffer.init(options);\n const observer = new (mutationObserverCtor())(\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, buffer: mutationBuffer };\n}\nfunction initMoveObserver({\n mousemoveCb,\n sampling,\n doc,\n mirror: mirror2\n}) {\n if (sampling.mousemove === false) {\n return () => {\n };\n }\n const threshold = typeof sampling.mousemove === \"number\" ? sampling.mousemove : 50;\n const callbackThreshold = typeof sampling.mousemoveCallback === \"number\" ? sampling.mousemoveCallback : 500;\n let positions = [];\n let timeBaseline;\n const wrappedCb = throttle(\n callbackWrapper(\n (source) => {\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(\n callbackWrapper((evt) => {\n const target = getEventTarget(evt);\n const { clientX, clientY } = legacy_isTouchEvent(evt) ? evt.changedTouches[0] : evt;\n if (!timeBaseline) {\n timeBaseline = nowTimestamp();\n }\n positions.push({\n x: clientX,\n y: clientY,\n id: mirror2.getId(target),\n timeOffset: nowTimestamp() - timeBaseline\n });\n wrappedCb(\n typeof DragEvent !== \"undefined\" && evt instanceof DragEvent ? IncrementalSource.Drag : evt instanceof MouseEvent ? IncrementalSource.MouseMove : 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}\nfunction initMouseInteractionObserver({\n mouseInteractionCb,\n doc,\n mirror: mirror2,\n blockClass,\n blockSelector,\n sampling\n}) {\n if (sampling.mouseInteraction === false) {\n return () => {\n };\n }\n const disableMap = sampling.mouseInteraction === true || sampling.mouseInteraction === void 0 ? {} : sampling.mouseInteraction;\n const handlers = [];\n let currentPointerType = null;\n const getHandler = (eventKey) => {\n return (event) => {\n const target = getEventTarget(event);\n if (isBlocked(target, blockClass, blockSelector, true)) {\n return;\n }\n let pointerType = 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 thisEventKey = \"TouchStart\";\n } else if (MouseInteractions[eventKey] === MouseInteractions.MouseUp) {\n thisEventKey = \"TouchEnd\";\n }\n } else if (pointerType === PointerTypes.Pen) ;\n } else if (legacy_isTouchEvent(event)) {\n pointerType = PointerTypes.Touch;\n }\n if (pointerType !== null) {\n currentPointerType = pointerType;\n if (thisEventKey.startsWith(\"Touch\") && pointerType === PointerTypes.Touch || thisEventKey.startsWith(\"Mouse\") && pointerType === PointerTypes.Mouse) {\n pointerType = null;\n }\n } else if (MouseInteractions[eventKey] === MouseInteractions.Click) {\n pointerType = currentPointerType;\n currentPointerType = null;\n }\n const e = legacy_isTouchEvent(event) ? event.changedTouches[0] : event;\n if (!e) {\n return;\n }\n const id = mirror2.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).filter(\n (key) => Number.isNaN(Number(key)) && !key.endsWith(\"_Departed\") && disableMap[key] !== false\n ).forEach((eventKey) => {\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 );\n break;\n case MouseInteractions.TouchStart:\n case MouseInteractions.TouchEnd:\n return;\n }\n }\n handlers.push(on(eventName, handler, doc));\n });\n return callbackWrapper(() => {\n handlers.forEach((h) => h());\n });\n}\nfunction initScrollObserver({\n scrollCb,\n doc,\n mirror: mirror2,\n blockClass,\n blockSelector,\n sampling\n}) {\n const lastEmitted = /* @__PURE__ */ new Map();\n const emitScrollPosition = (evt) => {\n const target = getEventTarget(evt);\n if (!target || isBlocked(target, blockClass, blockSelector, true)) {\n return;\n }\n const id = mirror2.getId(target);\n let x;\n let y;\n if (target === doc && doc.defaultView) {\n const scrollLeftTop = getWindowScroll(doc.defaultView);\n x = scrollLeftTop.left;\n y = scrollLeftTop.top;\n } else {\n x = target.scrollLeft;\n y = target.scrollTop;\n }\n const key = `${x},${y}`;\n if (lastEmitted.get(id) === key) {\n return;\n }\n lastEmitted.set(id, key);\n scrollCb({ id, x, y });\n };\n const updatePosition = callbackWrapper(\n throttle(\n callbackWrapper((evt) => emitScrollPosition(evt)),\n sampling.scroll || 100\n )\n );\n const handlers = [on(\"scroll\", updatePosition, doc)];\n if (\"onscrollend\" in doc) {\n handlers.push(on(\"scrollend\", callbackWrapper(emitScrollPosition), doc));\n }\n return () => handlers.forEach((h) => h());\n}\nfunction initViewportResizeObserver({ viewportResizeCb }, { win }) {\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}\nfunction findAndRemoveIframeBuffer(iframeEl, knownDocs) {\n for (let i = mutationBuffers.length - 1; i >= 0; i--) {\n const buf = mutationBuffers[i];\n if (!buf) continue;\n let match = buf.bufferBelongsToIframe(iframeEl);\n if (!match && knownDocs && knownDocs.has(buf.bufferDoc())) {\n match = true;\n }\n if (match) {\n buf.reset();\n mutationBuffers.splice(i, 1);\n }\n }\n}\nconst INPUT_TAGS = [\"INPUT\", \"TEXTAREA\", \"SELECT\"];\nconst lastInputValueMap = /* @__PURE__ */ new WeakMap();\nfunction initInputObserver({\n inputCb,\n doc,\n mirror: mirror2,\n blockClass,\n blockSelector,\n ignoreClass,\n ignoreSelector,\n maskInputOptions,\n maskInputFn,\n sampling,\n userTriggeredOnInput\n}) {\n function eventHandler(event) {\n let target = getEventTarget(event);\n const userTriggered = event.isTrusted;\n const tagName = target && target.tagName;\n if (target && tagName === \"OPTION\") {\n target = index.parentElement(target);\n }\n if (!target || !tagName || INPUT_TAGS.indexOf(tagName) < 0 || isBlocked(target, blockClass, blockSelector, true)) {\n return;\n }\n if (target.classList.contains(ignoreClass) || ignoreSelector && target.matches(ignoreSelector)) {\n return;\n }\n let text = target.value;\n let isChecked = false;\n const type = getInputType(target) || \"\";\n if (type === \"radio\" || type === \"checkbox\") {\n isChecked = target.checked;\n } else if (maskInputOptions[tagName.toLowerCase()] || maskInputOptions[type]) {\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 ? { text, isChecked, userTriggered } : { text, isChecked }\n );\n const name = target.name;\n if (type === \"radio\" && name && isChecked) {\n doc.querySelectorAll(`input[type=\"radio\"][name=\"${name}\"]`).forEach((el) => {\n if (el !== target) {\n const text2 = el.value;\n cbWithDedup(\n el,\n userTriggeredOnInput ? { text: text2, isChecked: !isChecked, userTriggered: false } : { text: text2, isChecked: !isChecked }\n );\n }\n });\n }\n }\n function cbWithDedup(target, v) {\n const lastInputValue = lastInputValueMap.get(target);\n if (!lastInputValue || lastInputValue.text !== v.text || lastInputValue.isChecked !== v.isChecked) {\n lastInputValueMap.set(target, v);\n const id = mirror2.getId(target);\n callbackWrapper(inputCb)({\n ...v,\n id\n });\n }\n }\n const events = sampling.input === \"last\" ? [\"change\"] : [\"input\", \"change\"];\n const handlers = 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 = [\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(\n (p) => hookSetter(\n p[0],\n p[1],\n {\n set() {\n callbackWrapper(eventHandler)({\n target: this,\n isTrusted: false\n // userTriggered to false as this could well be programmatic\n });\n }\n },\n false,\n currentWindow\n )\n )\n );\n }\n return callbackWrapper(() => {\n handlers.forEach((h) => h());\n });\n}\nfunction getNestedCSSRulePositions(rule) {\n const positions = [];\n function recurse(childRule, pos) {\n if (hasNestedCSSRule(\"CSSGroupingRule\") && childRule.parentRule instanceof CSSGroupingRule || hasNestedCSSRule(\"CSSMediaRule\") && childRule.parentRule instanceof CSSMediaRule || hasNestedCSSRule(\"CSSSupportsRule\") && childRule.parentRule instanceof CSSSupportsRule || hasNestedCSSRule(\"CSSConditionRule\") && childRule.parentRule instanceof CSSConditionRule) {\n const rules = Array.from(\n childRule.parentRule.cssRules\n );\n const index2 = rules.indexOf(childRule);\n pos.unshift(index2);\n return recurse(childRule.parentRule, pos);\n } else if (childRule.parentStyleSheet) {\n const rules = Array.from(childRule.parentStyleSheet.cssRules);\n const index2 = rules.indexOf(childRule);\n pos.unshift(index2);\n }\n return pos;\n }\n return recurse(rule, positions);\n}\nfunction getIdAndStyleId(sheet, mirror2, styleMirror) {\n let id, styleId;\n if (!sheet) return {};\n if (sheet.ownerNode) id = mirror2.getId(sheet.ownerNode);\n else styleId = styleMirror.getId(sheet);\n return {\n styleId,\n id\n };\n}\nfunction initStyleSheetObserver({ styleSheetRuleCb, mirror: mirror2, stylesheetManager }, { win }) {\n if (!win.CSSStyleSheet || !win.CSSStyleSheet.prototype) {\n return () => {\n };\n }\n const insertRule = win.CSSStyleSheet.prototype.insertRule;\n win.CSSStyleSheet.prototype.insertRule = new Proxy(insertRule, {\n apply: callbackWrapper(\n (target, thisArg, argumentsList) => {\n const [rule, index2] = argumentsList;\n const { id, styleId } = getIdAndStyleId(\n thisArg,\n mirror2,\n stylesheetManager.styleMirror\n );\n if (id && id !== -1 || styleId && styleId !== -1) {\n styleSheetRuleCb({\n id,\n styleId,\n adds: [{ rule, index: index2 }]\n });\n }\n return target.apply(thisArg, argumentsList);\n }\n )\n });\n win.CSSStyleSheet.prototype.addRule = function(selector, styleBlock, index2 = this.cssRules.length) {\n const rule = `${selector} { ${styleBlock} }`;\n return win.CSSStyleSheet.prototype.insertRule.apply(this, [rule, index2]);\n };\n const deleteRule = win.CSSStyleSheet.prototype.deleteRule;\n win.CSSStyleSheet.prototype.deleteRule = new Proxy(deleteRule, {\n apply: callbackWrapper(\n (target, thisArg, argumentsList) => {\n const [index2] = argumentsList;\n const { id, styleId } = getIdAndStyleId(\n thisArg,\n mirror2,\n stylesheetManager.styleMirror\n );\n if (id && id !== -1 || styleId && styleId !== -1) {\n styleSheetRuleCb({\n id,\n styleId,\n removes: [{ index: index2 }]\n });\n }\n return target.apply(thisArg, argumentsList);\n }\n )\n });\n win.CSSStyleSheet.prototype.removeRule = function(index2) {\n return win.CSSStyleSheet.prototype.deleteRule.apply(this, [index2]);\n };\n let replace;\n if (win.CSSStyleSheet.prototype.replace) {\n replace = win.CSSStyleSheet.prototype.replace;\n win.CSSStyleSheet.prototype.replace = new Proxy(replace, {\n apply: callbackWrapper(\n (target, thisArg, argumentsList) => {\n const [text] = argumentsList;\n const { id, styleId } = getIdAndStyleId(\n thisArg,\n mirror2,\n stylesheetManager.styleMirror\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 let replaceSync;\n if (win.CSSStyleSheet.prototype.replaceSync) {\n replaceSync = win.CSSStyleSheet.prototype.replaceSync;\n win.CSSStyleSheet.prototype.replaceSync = new Proxy(replaceSync, {\n apply: callbackWrapper(\n (target, thisArg, argumentsList) => {\n const [text] = argumentsList;\n const { id, styleId } = getIdAndStyleId(\n thisArg,\n mirror2,\n stylesheetManager.styleMirror\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 const supportedNestedCSSRuleTypes = {};\n if (canMonkeyPatchNestedCSSRule(\"CSSGroupingRule\")) {\n supportedNestedCSSRuleTypes.CSSGroupingRule = win.CSSGroupingRule;\n } else {\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 const unmodifiedFunctions = {};\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 type.prototype.insertRule = new Proxy(\n unmodifiedFunctions[typeKey].insertRule,\n {\n apply: callbackWrapper(\n (target, thisArg, argumentsList) => {\n const [rule, index2] = argumentsList;\n const { id, styleId } = getIdAndStyleId(\n thisArg.parentStyleSheet,\n mirror2,\n stylesheetManager.styleMirror\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 index2 || 0\n // defaults to 0\n ]\n }\n ]\n });\n }\n return target.apply(thisArg, argumentsList);\n }\n )\n }\n );\n type.prototype.deleteRule = new Proxy(\n unmodifiedFunctions[typeKey].deleteRule,\n {\n apply: callbackWrapper(\n (target, thisArg, argumentsList) => {\n const [index2] = argumentsList;\n const { id, styleId } = getIdAndStyleId(\n thisArg.parentStyleSheet,\n mirror2,\n stylesheetManager.styleMirror\n );\n if (id && id !== -1 || styleId && styleId !== -1) {\n styleSheetRuleCb({\n id,\n styleId,\n removes: [\n { index: [...getNestedCSSRulePositions(thisArg), index2] }\n ]\n });\n }\n return target.apply(thisArg, argumentsList);\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}\nfunction initAdoptedStyleSheetObserver({\n mirror: mirror2,\n stylesheetManager\n}, host2) {\n var _a2, _b, _c;\n let hostId = null;\n if (host2.nodeName === \"#document\") hostId = mirror2.getId(host2);\n else hostId = mirror2.getId(index.host(host2));\n const patchTarget = host2.nodeName === \"#document\" ? (_a2 = host2.defaultView) == null ? void 0 : _a2.Document : (_c = (_b = host2.ownerDocument) == null ? void 0 : _b.defaultView) == null ? void 0 : _c.ShadowRoot;\n const originalPropertyDescriptor = (patchTarget == null ? void 0 : patchTarget.prototype) ? Object.getOwnPropertyDescriptor(\n patchTarget == null ? void 0 : patchTarget.prototype,\n \"adoptedStyleSheets\"\n ) : void 0;\n if (hostId === null || hostId === -1 || !patchTarget || !originalPropertyDescriptor)\n return () => {\n };\n Object.defineProperty(host2, \"adoptedStyleSheets\", {\n configurable: originalPropertyDescriptor.configurable,\n enumerable: originalPropertyDescriptor.enumerable,\n get() {\n var _a3;\n return (_a3 = originalPropertyDescriptor.get) == null ? void 0 : _a3.call(this);\n },\n set(sheets) {\n var _a3;\n const result = (_a3 = originalPropertyDescriptor.set) == null ? void 0 : _a3.call(this, sheets);\n if (hostId !== null && hostId !== -1) {\n try {\n stylesheetManager.adoptStyleSheets(sheets, hostId);\n } catch (e) {\n }\n }\n return result;\n }\n });\n return callbackWrapper(() => {\n Object.defineProperty(host2, \"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}\nfunction initStyleDeclarationObserver({\n styleDeclarationCb,\n mirror: mirror2,\n ignoreCSSAttributes,\n stylesheetManager\n}, { win }) {\n const setProperty = win.CSSStyleDeclaration.prototype.setProperty;\n win.CSSStyleDeclaration.prototype.setProperty = new Proxy(setProperty, {\n apply: callbackWrapper(\n (target, thisArg, argumentsList) => {\n var _a2;\n const [property, value, priority] = argumentsList;\n if (ignoreCSSAttributes.has(property)) {\n return setProperty.apply(thisArg, [property, value, priority]);\n }\n const { id, styleId } = getIdAndStyleId(\n (_a2 = thisArg.parentRule) == null ? void 0 : _a2.parentStyleSheet,\n mirror2,\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 const removeProperty = win.CSSStyleDeclaration.prototype.removeProperty;\n win.CSSStyleDeclaration.prototype.removeProperty = new Proxy(removeProperty, {\n apply: callbackWrapper(\n (target, thisArg, argumentsList) => {\n var _a2;\n const [property] = argumentsList;\n if (ignoreCSSAttributes.has(property)) {\n return removeProperty.apply(thisArg, [property]);\n }\n const { id, styleId } = getIdAndStyleId(\n (_a2 = thisArg.parentRule) == null ? void 0 : _a2.parentStyleSheet,\n mirror2,\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 return callbackWrapper(() => {\n win.CSSStyleDeclaration.prototype.setProperty = setProperty;\n win.CSSStyleDeclaration.prototype.removeProperty = removeProperty;\n });\n}\nfunction initMediaInteractionObserver({\n mediaInteractionCb,\n blockClass,\n blockSelector,\n mirror: mirror2,\n sampling,\n doc\n}) {\n const handler = callbackWrapper(\n (type) => throttle(\n callbackWrapper((event) => {\n const target = getEventTarget(event);\n if (!target || isBlocked(target, blockClass, blockSelector, true)) {\n return;\n }\n const { currentTime, volume, muted, playbackRate, loop } = target;\n mediaInteractionCb({\n type,\n id: mirror2.getId(target),\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}\nfunction initFontObserver({ fontCb, doc }) {\n const win = doc.defaultView;\n if (!win) {\n return () => {\n };\n }\n const handlers = [];\n const fontMap = /* @__PURE__ */ new WeakMap();\n const originalFontFace = win.FontFace;\n win.FontFace = function FontFace(family, source, descriptors) {\n const fontFace = new originalFontFace(\n family,\n source,\n descriptors\n );\n fontMap.set(fontFace, {\n family,\n buffer: typeof source !== \"string\",\n descriptors,\n fontSource: typeof source === \"string\" ? source : JSON.stringify(Array.from(new Uint8Array(source)))\n });\n return fontFace;\n };\n const restoreHandler = patch(\n doc.fonts,\n \"add\",\n function(original) {\n return function(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 handlers.push(() => {\n win.FontFace = originalFontFace;\n });\n handlers.push(restoreHandler);\n return callbackWrapper(() => {\n handlers.forEach((h) => h());\n });\n}\nfunction initSelectionObserver(param) {\n const { doc, mirror: mirror2, blockClass, blockSelector, selectionCb } = param;\n let collapsed = true;\n const updateSelection = callbackWrapper(() => {\n const selection = doc.getSelection();\n if (!selection || collapsed && (selection == null ? void 0 : selection.isCollapsed)) return;\n collapsed = selection.isCollapsed || false;\n const ranges = [];\n const count = selection.rangeCount || 0;\n for (let i = 0; i < count; i++) {\n const range = selection.getRangeAt(i);\n const { startContainer, startOffset, endContainer, endOffset } = range;\n const blocked = isBlocked(startContainer, blockClass, blockSelector, true) || isBlocked(endContainer, blockClass, blockSelector, true);\n if (blocked) continue;\n ranges.push({\n start: mirror2.getId(startContainer),\n startOffset,\n end: mirror2.getId(endContainer),\n endOffset\n });\n }\n selectionCb({ ranges });\n });\n updateSelection();\n return on(\"selectionchange\", updateSelection);\n}\nfunction initCustomElementObserver({\n doc,\n customElementCb\n}) {\n const win = doc.defaultView;\n if (!win || !win.customElements) return () => {\n };\n const restoreHandler = patch(\n win.customElements,\n \"define\",\n function(original) {\n return function(name, constructor, options) {\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}\nfunction mergeHooks(o, hooks) {\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) => {\n if (hooks.mutation) {\n hooks.mutation(...p);\n }\n mutationCb(...p);\n };\n o.mousemoveCb = (...p) => {\n if (hooks.mousemove) {\n hooks.mousemove(...p);\n }\n mousemoveCb(...p);\n };\n o.mouseInteractionCb = (...p) => {\n if (hooks.mouseInteraction) {\n hooks.mouseInteraction(...p);\n }\n mouseInteractionCb(...p);\n };\n o.scrollCb = (...p) => {\n if (hooks.scroll) {\n hooks.scroll(...p);\n }\n scrollCb(...p);\n };\n o.viewportResizeCb = (...p) => {\n if (hooks.viewportResize) {\n hooks.viewportResize(...p);\n }\n viewportResizeCb(...p);\n };\n o.inputCb = (...p) => {\n if (hooks.input) {\n hooks.input(...p);\n }\n inputCb(...p);\n };\n o.mediaInteractionCb = (...p) => {\n if (hooks.mediaInteaction) {\n hooks.mediaInteaction(...p);\n }\n mediaInteractionCb(...p);\n };\n o.styleSheetRuleCb = (...p) => {\n if (hooks.styleSheetRule) {\n hooks.styleSheetRule(...p);\n }\n styleSheetRuleCb(...p);\n };\n o.styleDeclarationCb = (...p) => {\n if (hooks.styleDeclaration) {\n hooks.styleDeclaration(...p);\n }\n styleDeclarationCb(...p);\n };\n o.canvasMutationCb = (...p) => {\n if (hooks.canvasMutation) {\n hooks.canvasMutation(...p);\n }\n canvasMutationCb(...p);\n };\n o.fontCb = (...p) => {\n if (hooks.font) {\n hooks.font(...p);\n }\n fontCb(...p);\n };\n o.selectionCb = (...p) => {\n if (hooks.selection) {\n hooks.selection(...p);\n }\n selectionCb(...p);\n };\n o.customElementCb = (...c) => {\n if (hooks.customElement) {\n hooks.customElement(...c);\n }\n customElementCb(...c);\n };\n}\nfunction initObservers(o, hooks = {}) {\n const currentWindow = o.doc.defaultView;\n if (!currentWindow) {\n return () => {\n };\n }\n mergeHooks(o, hooks);\n let mutationObserver;\n let mutationBuffer;\n if (o.recordDOM) {\n const result = initMutationObserver(o, o.doc);\n mutationObserver = result.observer;\n mutationBuffer = result.buffer;\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 let styleSheetObserver = () => {\n };\n let adoptedStyleSheetObserver = () => {\n };\n let styleDeclarationObserver = () => {\n };\n let fontObserver = () => {\n };\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 const pluginHandlers = [];\n for (const plugin of o.plugins) {\n pluginHandlers.push(\n plugin.observer(plugin.callback, currentWindow, plugin.options)\n );\n }\n return callbackWrapper(() => {\n if (mutationBuffer) {\n mutationBuffer.destroy();\n mutationBuffer.reset();\n const index2 = mutationBuffers.indexOf(mutationBuffer);\n if (index2 !== -1) {\n mutationBuffers.splice(index2, 1);\n }\n }\n mutationObserver == null ? void 0 : mutationObserver.disconnect();\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}\nfunction hasNestedCSSRule(prop) {\n return typeof window[prop] !== \"undefined\";\n}\nfunction canMonkeyPatchNestedCSSRule(prop) {\n return Boolean(\n typeof window[prop] !== \"undefined\" && // 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 && \"insertRule\" in window[prop].prototype && \"deleteRule\" in window[prop].prototype\n );\n}\nclass CrossOriginIframeMirror {\n constructor(generateIdFn) {\n __publicField(this, \"iframeIdToRemoteIdMap\", /* @__PURE__ */ new WeakMap());\n __publicField(this, \"iframeRemoteIdToIdMap\", /* @__PURE__ */ new WeakMap());\n this.generateIdFn = generateIdFn;\n }\n getId(iframe, remoteId, idToRemoteMap, remoteToIdMap) {\n const idToRemoteIdMap = idToRemoteMap || this.getIdToRemoteIdMap(iframe);\n const remoteIdToIdMap = remoteToIdMap || this.getRemoteIdToIdMap(iframe);\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 getIds(iframe, remoteId) {\n const idToRemoteIdMap = this.getIdToRemoteIdMap(iframe);\n const remoteIdToIdMap = this.getRemoteIdToIdMap(iframe);\n return remoteId.map(\n (id) => this.getId(iframe, id, idToRemoteIdMap, remoteIdToIdMap)\n );\n }\n getRemoteId(iframe, id, map) {\n const remoteIdToIdMap = map || this.getRemoteIdToIdMap(iframe);\n if (typeof id !== \"number\") return id;\n const remoteId = remoteIdToIdMap.get(id);\n if (!remoteId) return -1;\n return remoteId;\n }\n getRemoteIds(iframe, ids) {\n const remoteIdToIdMap = this.getRemoteIdToIdMap(iframe);\n return ids.map((id) => this.getRemoteId(iframe, id, remoteIdToIdMap));\n }\n reset(iframe) {\n if (!iframe) {\n this.iframeIdToRemoteIdMap = /* @__PURE__ */ new WeakMap();\n this.iframeRemoteIdToIdMap = /* @__PURE__ */ new WeakMap();\n return;\n }\n this.iframeIdToRemoteIdMap.delete(iframe);\n this.iframeRemoteIdToIdMap.delete(iframe);\n }\n getIdToRemoteIdMap(iframe) {\n let idToRemoteIdMap = this.iframeIdToRemoteIdMap.get(iframe);\n if (!idToRemoteIdMap) {\n idToRemoteIdMap = /* @__PURE__ */ new Map();\n this.iframeIdToRemoteIdMap.set(iframe, idToRemoteIdMap);\n }\n return idToRemoteIdMap;\n }\n getRemoteIdToIdMap(iframe) {\n let remoteIdToIdMap = this.iframeRemoteIdToIdMap.get(iframe);\n if (!remoteIdToIdMap) {\n remoteIdToIdMap = /* @__PURE__ */ new Map();\n this.iframeRemoteIdToIdMap.set(iframe, remoteIdToIdMap);\n }\n return remoteIdToIdMap;\n }\n}\nclass IframeManager {\n constructor(options) {\n __publicField(this, \"iframes\", /* @__PURE__ */ new WeakMap());\n __publicField(this, \"crossOriginIframeMap\", /* @__PURE__ */ new WeakMap());\n __publicField(this, \"crossOriginIframeMirror\", new CrossOriginIframeMirror(genId));\n __publicField(this, \"crossOriginIframeStyleMirror\");\n __publicField(this, \"crossOriginIframeRootIdMap\", /* @__PURE__ */ new WeakMap());\n __publicField(this, \"mirror\");\n __publicField(this, \"mutationCb\");\n __publicField(this, \"wrappedEmit\");\n __publicField(this, \"loadListener\");\n __publicField(this, \"pageHideListener\");\n __publicField(this, \"stylesheetManager\");\n __publicField(this, \"recordCrossOriginIframes\");\n __publicField(this, \"messageHandler\");\n // Strong Map — keys pin Windows; every entry must be deleted on detach.\n __publicField(this, \"nestedIframeListeners\", /* @__PURE__ */ new Map());\n // Originals captured per iframe so cleanup survives iframe.src swaps.\n __publicField(this, \"attachedWindows\", /* @__PURE__ */ new WeakMap());\n __publicField(this, \"attachedDocuments\", /* @__PURE__ */ new WeakMap());\n __publicField(this, \"attachedIframes\", /* @__PURE__ */ new Map());\n // Set per element — one iframe collects multiple disposers across loads.\n __publicField(this, \"loadListenerDisposers\", /* @__PURE__ */ new WeakMap());\n // Fallback for iframes removed before first load — mirror entry is gone\n // by then, but we still need the element to dispose its load listener.\n __publicField(this, \"iframeElementsById\", /* @__PURE__ */ new Map());\n // Set per element — same multi-load reasoning as loadListenerDisposers.\n __publicField(this, \"pageHideHandlers\", /* @__PURE__ */ new WeakMap());\n this.mutationCb = options.mutationCb;\n this.wrappedEmit = options.wrappedEmit;\n this.stylesheetManager = options.stylesheetManager;\n this.recordCrossOriginIframes = options.recordCrossOriginIframes;\n this.crossOriginIframeStyleMirror = new CrossOriginIframeMirror(\n this.stylesheetManager.styleMirror.generateId.bind(\n this.stylesheetManager.styleMirror\n )\n );\n this.mirror = options.mirror;\n this.messageHandler = this.handleMessage.bind(this);\n if (this.recordCrossOriginIframes) {\n window.addEventListener(\"message\", this.messageHandler);\n }\n }\n addIframe(iframeEl) {\n this.iframes.set(iframeEl, true);\n if (iframeEl.contentWindow)\n this.crossOriginIframeMap.set(iframeEl.contentWindow, iframeEl);\n }\n registerLoadListenerDisposer(iframeEl, disposer) {\n let bucket = this.loadListenerDisposers.get(iframeEl);\n if (!bucket) {\n bucket = /* @__PURE__ */ new Set();\n this.loadListenerDisposers.set(iframeEl, bucket);\n }\n bucket.add(disposer);\n const id = this.mirror.getId(iframeEl);\n if (id !== -1) this.iframeElementsById.set(id, iframeEl);\n }\n // Used by the record-loop to distinguish reparenting from removal.\n getIframeElementById(iframeId) {\n var _a2;\n return ((_a2 = this.attachedIframes.get(iframeId)) == null ? void 0 : _a2.element) ?? this.iframeElementsById.get(iframeId) ?? null;\n }\n // Drops the id mapping for a moved iframe; element-keyed state survives.\n forgetIframeId(iframeId) {\n this.attachedIframes.delete(iframeId);\n this.iframeElementsById.delete(iframeId);\n }\n disposeLoadListeners(iframeEl) {\n const bucket = this.loadListenerDisposers.get(iframeEl);\n if (!bucket) return;\n bucket.forEach((d) => callSafely(d));\n this.loadListenerDisposers.delete(iframeEl);\n }\n removePageHideListener(iframeEl) {\n const bucket = this.pageHideHandlers.get(iframeEl);\n if (!bucket) return;\n bucket.forEach(({ win, handler }) => {\n callSafely(() => win.removeEventListener(\"pagehide\", handler));\n });\n this.pageHideHandlers.delete(iframeEl);\n }\n addLoadListener(cb) {\n this.loadListener = cb;\n }\n addPageHideListener(cb) {\n this.pageHideListener = cb;\n }\n removeLoadListener() {\n this.loadListener = void 0;\n }\n trackIframeContent(iframeEl, content) {\n const iframeId = this.mirror.getId(iframeEl);\n this.attachedIframes.set(iframeId, { element: iframeEl, content });\n return iframeId;\n }\n attachIframe(iframeEl, childSn) {\n var _a2;\n const iframeId = this.trackIframeContent(iframeEl, childSn);\n if (iframeEl.contentDocument) {\n let docs = this.attachedDocuments.get(iframeEl);\n if (!docs) {\n docs = /* @__PURE__ */ new Set();\n this.attachedDocuments.set(iframeEl, docs);\n }\n docs.add(iframeEl.contentDocument);\n }\n this.mutationCb({\n adds: [\n {\n parentId: iframeId,\n nextId: null,\n node: childSn\n }\n ],\n removes: [],\n texts: [],\n attributes: [],\n isAttachIframe: true\n });\n const win = iframeEl.contentWindow;\n if (this.recordCrossOriginIframes && win && !this.nestedIframeListeners.has(win)) {\n const nestedHandler = this.handleMessage.bind(this);\n callSafely(() => {\n win.addEventListener(\"message\", nestedHandler);\n this.nestedIframeListeners.set(win, nestedHandler);\n let wins = this.attachedWindows.get(iframeEl);\n if (!wins) {\n wins = /* @__PURE__ */ new Set();\n this.attachedWindows.set(iframeEl, wins);\n }\n wins.add(win);\n });\n }\n callSafely(() => {\n const pageHideWindow = iframeEl.contentWindow;\n if (!pageHideWindow) return;\n let bucket = this.pageHideHandlers.get(iframeEl);\n if (bucket) {\n for (const entry of bucket) {\n if (entry.win === pageHideWindow) return;\n }\n }\n const handler = () => {\n var _a3;\n (_a3 = this.pageHideListener) == null ? void 0 : _a3.call(this, iframeEl);\n if (iframeEl.contentDocument) {\n this.mirror.removeNodeFromMap(iframeEl.contentDocument);\n }\n if (iframeEl.contentWindow) {\n this.crossOriginIframeMap.delete(iframeEl.contentWindow);\n }\n };\n pageHideWindow.addEventListener(\"pagehide\", handler);\n if (!bucket) {\n bucket = /* @__PURE__ */ new Set();\n this.pageHideHandlers.set(iframeEl, bucket);\n }\n bucket.add({ win: pageHideWindow, handler });\n });\n (_a2 = this.loadListener) == null ? void 0 : _a2.call(this, iframeEl);\n if (iframeEl.contentDocument && iframeEl.contentDocument.adoptedStyleSheets && iframeEl.contentDocument.adoptedStyleSheets.length > 0)\n this.stylesheetManager.adoptStyleSheets(\n iframeEl.contentDocument.adoptedStyleSheets,\n this.mirror.getId(iframeEl.contentDocument)\n );\n }\n handleMessage(message) {\n const crossOriginMessageEvent = message;\n if (crossOriginMessageEvent.data.type !== \"rrweb\" || // To filter out the rrweb messages which are forwarded by some sites.\n crossOriginMessageEvent.origin !== crossOriginMessageEvent.data.origin)\n return;\n const iframeSourceWindow = message.source;\n if (!iframeSourceWindow) return;\n const iframeEl = this.crossOriginIframeMap.get(message.source);\n if (!iframeEl) return;\n const transformedEvent = this.transformCrossOriginEvent(\n iframeEl,\n crossOriginMessageEvent.data.event\n );\n if (transformedEvent)\n this.wrappedEmit(\n transformedEvent,\n crossOriginMessageEvent.data.isCheckout\n );\n }\n transformCrossOriginEvent(iframeEl, e) {\n var _a2;\n switch (e.type) {\n case EventType.FullSnapshot: {\n this.crossOriginIframeMirror.reset(iframeEl);\n this.crossOriginIframeStyleMirror.reset(iframeEl);\n this.replaceIdOnNode(e.data.node, iframeEl);\n const rootId = e.data.node.id;\n this.crossOriginIframeRootIdMap.set(iframeEl, rootId);\n this.patchRootIdOnNode(e.data.node, rootId);\n this.trackIframeContent(iframeEl, e.data.node);\n return {\n timestamp: e.timestamp,\n type: EventType.IncrementalSnapshot,\n data: {\n source: IncrementalSource.Mutation,\n adds: [\n {\n parentId: this.mirror.getId(iframeEl),\n nextId: null,\n node: e.data.node\n }\n ],\n removes: [],\n texts: [],\n attributes: [],\n isAttachIframe: true\n }\n };\n }\n case EventType.Meta:\n case EventType.Load:\n case EventType.DomContentLoaded: {\n return false;\n }\n case EventType.Plugin: {\n return e;\n }\n case EventType.Custom: {\n this.replaceIds(\n e.data.payload,\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 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 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 (_a2 = e.data.styles) == null ? void 0 : _a2.forEach((style) => {\n this.replaceStyleIds(style, iframeEl, [\"styleId\"]);\n });\n return e;\n }\n }\n }\n }\n return false;\n }\n replace(iframeMirror, obj, iframeEl, keys) {\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]\n );\n } else {\n obj[key] = iframeMirror.getId(iframeEl, obj[key]);\n }\n }\n return obj;\n }\n replaceIds(obj, iframeEl, keys) {\n return this.replace(this.crossOriginIframeMirror, obj, iframeEl, keys);\n }\n replaceStyleIds(obj, iframeEl, keys) {\n return this.replace(this.crossOriginIframeStyleMirror, obj, iframeEl, keys);\n }\n replaceIdOnNode(node, iframeEl) {\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 patchRootIdOnNode(node, rootId) {\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 removeIframeById(iframeId) {\n const entry = this.attachedIframes.get(iframeId);\n const iframe = (entry == null ? void 0 : entry.element) || this.iframeElementsById.get(iframeId) || this.mirror.getNode(iframeId);\n this.iframeElementsById.delete(iframeId);\n if (iframe) {\n const win = iframe.contentWindow;\n const capturedWins = this.attachedWindows.get(iframe);\n if (capturedWins) {\n capturedWins.forEach((capturedWin) => {\n const handler = this.nestedIframeListeners.get(capturedWin);\n if (handler) {\n callSafely(\n () => capturedWin.removeEventListener(\"message\", handler)\n );\n this.nestedIframeListeners.delete(capturedWin);\n }\n this.crossOriginIframeMap.delete(capturedWin);\n });\n this.attachedWindows.delete(iframe);\n }\n if (win && this.nestedIframeListeners.has(win)) {\n const handler = this.nestedIframeListeners.get(win);\n callSafely(() => win.removeEventListener(\"message\", handler));\n this.nestedIframeListeners.delete(win);\n }\n if (win) {\n this.crossOriginIframeMap.delete(win);\n }\n this.iframes.delete(iframe);\n this.disposeLoadListeners(iframe);\n this.removePageHideListener(iframe);\n const capturedDocs = this.attachedDocuments.get(iframe);\n if (capturedDocs) {\n capturedDocs.forEach((doc) => {\n callSafely(() => this.mirror.removeNodeFromMap(doc));\n });\n callSafely(() => findAndRemoveIframeBuffer(iframe, capturedDocs));\n this.attachedDocuments.delete(iframe);\n }\n }\n if (entry) {\n this.attachedIframes.delete(iframeId);\n }\n }\n // Catches iframes removed inside a removed subtree (only the\n // ancestor's id appears in m.removes).\n cleanupDetachedIframes() {\n if (this.attachedIframes.size === 0) return;\n const orphaned = [];\n this.attachedIframes.forEach((_entry, iframeId) => {\n if (!this.mirror.has(iframeId)) {\n orphaned.push(iframeId);\n }\n });\n orphaned.forEach((iframeId) => this.removeIframeById(iframeId));\n }\n reattachIframes() {\n this.attachedIframes.forEach(({ content }, iframeId) => {\n if (!this.mirror.has(iframeId)) {\n this.attachedIframes.delete(iframeId);\n return;\n }\n this.mutationCb({\n adds: [\n {\n parentId: iframeId,\n nextId: null,\n node: content\n }\n ],\n removes: [],\n texts: [],\n attributes: [],\n isAttachIframe: true\n });\n });\n }\n destroy() {\n if (this.recordCrossOriginIframes) {\n window.removeEventListener(\"message\", this.messageHandler);\n }\n this.nestedIframeListeners.forEach((handler, contentWindow) => {\n callSafely(() => contentWindow.removeEventListener(\"message\", handler));\n });\n this.nestedIframeListeners.clear();\n const tracked = /* @__PURE__ */ new Set();\n this.iframeElementsById.forEach((el) => tracked.add(el));\n this.attachedIframes.forEach(({ element }) => tracked.add(element));\n tracked.forEach((iframe) => {\n this.disposeLoadListeners(iframe);\n this.removePageHideListener(iframe);\n });\n this.crossOriginIframeMirror.reset();\n this.crossOriginIframeStyleMirror.reset();\n this.attachedIframes.clear();\n this.crossOriginIframeMap = /* @__PURE__ */ new WeakMap();\n this.iframes = /* @__PURE__ */ new WeakMap();\n this.crossOriginIframeRootIdMap = /* @__PURE__ */ new WeakMap();\n this.loadListenerDisposers = /* @__PURE__ */ new WeakMap();\n this.pageHideHandlers = /* @__PURE__ */ new WeakMap();\n this.attachedDocuments = /* @__PURE__ */ new WeakMap();\n this.attachedWindows = /* @__PURE__ */ new WeakMap();\n this.iframeElementsById = /* @__PURE__ */ new Map();\n }\n}\nclass ShadowDomManager {\n constructor(options) {\n __publicField(this, \"shadowDoms\", /* @__PURE__ */ new WeakSet());\n __publicField(this, \"mutationCb\");\n __publicField(this, \"scrollCb\");\n __publicField(this, \"bypassOptions\");\n __publicField(this, \"mirror\");\n __publicField(this, \"restoreHandlers\", []);\n this.mutationCb = options.mutationCb;\n this.scrollCb = options.scrollCb;\n this.bypassOptions = options.bypassOptions;\n this.mirror = options.mirror;\n this.init();\n }\n init() {\n this.reset();\n this.patchAttachShadow(Element, document);\n }\n addShadowRoot(shadowRoot2, doc) {\n if (!isNativeShadowDom(shadowRoot2)) return;\n if (this.shadowDoms.has(shadowRoot2)) return;\n this.shadowDoms.add(shadowRoot2);\n const { observer, buffer } = initMutationObserver(\n {\n ...this.bypassOptions,\n doc,\n mutationCb: this.mutationCb,\n mirror: this.mirror,\n shadowDomManager: this\n },\n shadowRoot2\n );\n this.restoreHandlers.push(() => {\n observer.disconnect();\n buffer.destroy();\n buffer.releaseCanvasManager();\n const index2 = mutationBuffers.indexOf(buffer);\n if (index2 !== -1) {\n mutationBuffers.splice(index2, 1);\n }\n });\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: shadowRoot2,\n mirror: this.mirror\n })\n );\n setTimeout(() => {\n if (shadowRoot2.adoptedStyleSheets && shadowRoot2.adoptedStyleSheets.length > 0)\n this.bypassOptions.stylesheetManager.adoptStyleSheets(\n shadowRoot2.adoptedStyleSheets,\n this.mirror.getId(index.host(shadowRoot2))\n );\n this.restoreHandlers.push(\n initAdoptedStyleSheetObserver(\n {\n mirror: this.mirror,\n stylesheetManager: this.bypassOptions.stylesheetManager\n },\n shadowRoot2\n )\n );\n }, 0);\n }\n /**\n * Monkey patch 'attachShadow' of an IFrameElement to observe newly added shadow doms.\n */\n observeAttachShadow(iframeElement) {\n if (!iframeElement.contentWindow || !iframeElement.contentDocument) return;\n this.patchAttachShadow(\n iframeElement.contentWindow.Element,\n iframeElement.contentDocument\n );\n }\n /**\n * Patch 'attachShadow' to observe newly added shadow doms.\n */\n patchAttachShadow(element, doc) {\n const manager = this;\n this.restoreHandlers.push(\n patch(\n element.prototype,\n \"attachShadow\",\n function(original) {\n return function(option) {\n const sRoot = original.call(this, option);\n const shadowRootEl = index.shadowRoot(this);\n if (shadowRootEl && inDom(this))\n manager.addShadowRoot(shadowRootEl, doc);\n return sRoot;\n };\n }\n )\n );\n }\n reset() {\n this.restoreHandlers.forEach((handler) => {\n try {\n handler();\n } catch (e) {\n }\n });\n this.restoreHandlers = [];\n this.shadowDoms = /* @__PURE__ */ new WeakSet();\n }\n}\nvar chars = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";\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 } else if (len % 3 === 1) {\n base64 = base64.substring(0, base64.length - 2) + \"==\";\n }\n return base64;\n};\nconst canvasVarMap = /* @__PURE__ */ new Map();\nfunction variableListFor(ctx, ctor) {\n let contextMap = canvasVarMap.get(ctx);\n if (!contextMap) {\n contextMap = /* @__PURE__ */ new Map();\n canvasVarMap.set(ctx, contextMap);\n }\n if (!contextMap.has(ctor)) {\n contextMap.set(ctor, []);\n }\n return contextMap.get(ctor);\n}\nconst saveWebGLVar = (value, win, ctx) => {\n if (!value || !(isInstanceOfWebGLObject(value, win) || typeof value === \"object\"))\n return;\n const name = value.constructor.name;\n const list = variableListFor(ctx, name);\n let index2 = list.indexOf(value);\n if (index2 === -1) {\n index2 = list.length;\n list.push(value);\n }\n return index2;\n};\nfunction serializeArg(value, win, ctx, dataURLOptions) {\n if (value instanceof Array) {\n return value.map((arg) => serializeArg(arg, win, ctx, dataURLOptions));\n } else if (value === null) {\n return value;\n } else if (value instanceof Float32Array || value instanceof Float64Array || value instanceof Int32Array || value instanceof Uint32Array || value instanceof Uint8Array || value instanceof Uint16Array || value instanceof Int16Array || value instanceof Int8Array || value instanceof Uint8ClampedArray) {\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;\n const base64 = encode(value);\n return {\n rr_type: name,\n base64\n };\n } else if (value instanceof DataView) {\n const name = value.constructor.name;\n return {\n rr_type: name,\n args: [\n serializeArg(value.buffer, win, ctx, dataURLOptions),\n value.byteOffset,\n value.byteLength\n ]\n };\n } else if (value instanceof HTMLImageElement) {\n const name = value.constructor.name;\n const { src } = value;\n return {\n rr_type: name,\n src\n };\n } else if (value instanceof HTMLCanvasElement) {\n const name = \"HTMLImageElement\";\n const src = value.toDataURL(dataURLOptions.type, dataURLOptions.quality);\n return {\n rr_type: name,\n src\n };\n } else if (value instanceof ImageData) {\n const name = value.constructor.name;\n return {\n rr_type: name,\n args: [\n serializeArg(value.data, win, ctx, dataURLOptions),\n value.width,\n value.height\n ]\n };\n } else if (isInstanceOfWebGLObject(value, win) || typeof value === \"object\") {\n const name = value.constructor.name;\n const index2 = saveWebGLVar(value, win, ctx);\n return {\n rr_type: name,\n index: index2\n };\n }\n return value;\n}\nconst serializeArgs = (args, win, ctx, dataURLOptions) => {\n return args.map((arg) => serializeArg(arg, win, ctx, dataURLOptions));\n};\nconst isInstanceOfWebGLObject = (value, win) => {\n const webGLConstructorNames = [\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) => typeof win[name] === \"function\"\n );\n return Boolean(\n supportedWebGLConstructorNames.find(\n (name) => value instanceof win[name]\n )\n );\n};\nfunction initCanvas2DMutationObserver(cb, win, blockClass, blockSelector, dataURLOptions) {\n const handlers = [];\n const props2D = Object.getOwnPropertyNames(\n win.CanvasRenderingContext2D.prototype\n );\n for (const prop of props2D) {\n try {\n if (typeof win.CanvasRenderingContext2D.prototype[prop] !== \"function\") {\n continue;\n }\n const restoreHandler = patch(\n win.CanvasRenderingContext2D.prototype,\n prop,\n function(original) {\n return function(...args) {\n if (!isBlocked(this.canvas, blockClass, blockSelector, true)) {\n setTimeout(() => {\n const recordArgs = serializeArgs(\n args,\n win,\n this,\n dataURLOptions\n );\n cb(this.canvas, {\n type: CanvasContext[\"2D\"],\n property: prop,\n args: recordArgs\n });\n }, 0);\n }\n return original.apply(this, args);\n };\n }\n );\n handlers.push(restoreHandler);\n } catch {\n const hookHandler = hookSetter(\n win.CanvasRenderingContext2D.prototype,\n prop,\n {\n set(v) {\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}\nconst WEBGL_CONTEXT_NAMES = [\"webgl\", \"webgl2\"];\nfunction getNormalizedContextName(contextType) {\n return contextType === \"experimental-webgl\" ? \"webgl\" : contextType;\n}\nfunction getRequiredWebGPUTextureUsage(win) {\n const textureUsage = win.GPUTextureUsage;\n if (!textureUsage) {\n return null;\n }\n return textureUsage.COPY_SRC | textureUsage.RENDER_ATTACHMENT;\n}\nfunction getCanvasFromWebGPUContext(context) {\n const { canvas } = context;\n if (!canvas || typeof canvas !== \"object\") {\n return null;\n }\n return canvas;\n}\nfunction isCanvasNode(canvas) {\n return \"nodeType\" in canvas;\n}\nfunction initCanvasWebGPUContextObserver(win, blockClass, blockSelector) {\n const GPUCanvasContext = win.GPUCanvasContext;\n if (!(GPUCanvasContext == null ? void 0 : GPUCanvasContext.prototype) || typeof GPUCanvasContext.prototype.configure !== \"function\") {\n return;\n }\n return patch(\n GPUCanvasContext.prototype,\n \"configure\",\n function(original) {\n return function(configuration) {\n const canvas = getCanvasFromWebGPUContext(this);\n if (!canvas || isCanvasNode(canvas) && isBlocked(canvas, blockClass, blockSelector, true)) {\n return original.call(this, configuration);\n }\n if (isCanvasNode(canvas) && !(\"__context\" in canvas)) {\n canvas.__context = \"webgpu\";\n }\n const requiredUsage = getRequiredWebGPUTextureUsage(win);\n if (requiredUsage === null || !configuration) {\n return original.call(this, configuration);\n }\n return original.call(this, {\n ...configuration,\n // WebGPU does not implicitly keep RENDER_ATTACHMENT when usage is set,\n // so include both flags needed for drawing and snapshot reads.\n usage: typeof configuration.usage === \"number\" ? configuration.usage | requiredUsage : requiredUsage\n });\n };\n }\n );\n}\nfunction initCanvasContextObserver(win, blockClass, blockSelector, setPreserveDrawingBufferToTrue) {\n const handlers = [];\n try {\n if (setPreserveDrawingBufferToTrue) {\n const restoreWebGPUConfigureHandler = initCanvasWebGPUContextObserver(\n win,\n blockClass,\n blockSelector\n );\n if (restoreWebGPUConfigureHandler) {\n handlers.push(restoreWebGPUConfigureHandler);\n }\n }\n const restoreHandler = patch(\n win.HTMLCanvasElement.prototype,\n \"getContext\",\n function(original) {\n return function(contextType, ...args) {\n const ctxName = getNormalizedContextName(contextType);\n if (!isBlocked(this, blockClass, blockSelector, true)) {\n if (!(\"__context\" in this)) this.__context = ctxName;\n if (setPreserveDrawingBufferToTrue && WEBGL_CONTEXT_NAMES.includes(ctxName)) {\n if (args[0] && typeof args[0] === \"object\") {\n const contextAttributes = args[0];\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}\nfunction patchGLPrototype(prototype, type, cb, blockClass, blockSelector, win, dataURLOptions) {\n const handlers = [];\n const props = Object.getOwnPropertyNames(prototype);\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 continue;\n }\n try {\n if (typeof prototype[prop] !== \"function\") {\n continue;\n }\n const restoreHandler = patch(\n prototype,\n prop,\n function(original) {\n return function(...args) {\n const result = original.apply(this, args);\n saveWebGLVar(result, win, this);\n if (\"tagName\" in this.canvas && !isBlocked(this.canvas, blockClass, blockSelector, true)) {\n const recordArgs = serializeArgs(args, win, this, dataURLOptions);\n const mutation = {\n type,\n property: prop,\n args: recordArgs\n };\n cb(this.canvas, mutation);\n }\n return result;\n };\n }\n );\n handlers.push(restoreHandler);\n } catch {\n const hookHandler = hookSetter(prototype, prop, {\n set(v) {\n cb(this.canvas, {\n type,\n property: prop,\n args: [v],\n setter: true\n });\n }\n });\n handlers.push(hookHandler);\n }\n }\n return handlers;\n}\nfunction initCanvasWebGLMutationObserver(cb, win, blockClass, blockSelector, dataURLOptions) {\n const handlers = [];\n if (typeof win.WebGLRenderingContext !== \"undefined\") {\n handlers.push(\n ...patchGLPrototype(\n win.WebGLRenderingContext.prototype,\n CanvasContext.WebGL,\n cb,\n blockClass,\n blockSelector,\n win,\n dataURLOptions\n )\n );\n }\n if (typeof win.WebGL2RenderingContext !== \"undefined\") {\n handlers.push(\n ...patchGLPrototype(\n win.WebGL2RenderingContext.prototype,\n CanvasContext.WebGL2,\n cb,\n blockClass,\n blockSelector,\n win,\n dataURLOptions\n )\n );\n }\n return () => {\n handlers.forEach((h) => h());\n };\n}\nconst jsContent = '(function() {\\n \"use strict\";\\n var chars = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";\\n var lookup = typeof Uint8Array === \"undefined\" ? [] : new Uint8Array(256);\\n for (var i = 0; i < chars.length; i++) {\\n lookup[chars.charCodeAt(i)] = i;\\n }\\n var encode = function(arraybuffer) {\\n var bytes = new Uint8Array(arraybuffer), i2, len = bytes.length, base64 = \"\";\\n for (i2 = 0; i2 < len; i2 += 3) {\\n base64 += chars[bytes[i2] >> 2];\\n base64 += chars[(bytes[i2] & 3) << 4 | bytes[i2 + 1] >> 4];\\n base64 += chars[(bytes[i2 + 1] & 15) << 2 | bytes[i2 + 2] >> 6];\\n base64 += chars[bytes[i2 + 2] & 63];\\n }\\n if (len % 3 === 2) {\\n base64 = base64.substring(0, base64.length - 1) + \"=\";\\n } else if (len % 3 === 1) {\\n base64 = base64.substring(0, base64.length - 2) + \"==\";\\n }\\n return base64;\\n };\\n const lastFingerprintMap = /* @__PURE__ */ new Map();\\n const transparentBlobMap = /* @__PURE__ */ new Map();\\n function fnv1aHash(buffer) {\\n const view = new Uint8Array(buffer);\\n let hash = 2166136261;\\n for (let i2 = 0; i2 < view.length; i2++) {\\n hash ^= view[i2];\\n hash = hash * 16777619 | 0;\\n }\\n return (hash >>> 0).toString(16);\\n }\\n async function getTransparentBlobFor(width, height, dataURLOptions) {\\n const id = `${width}-${height}`;\\n if (\"OffscreenCanvas\" in globalThis) {\\n if (transparentBlobMap.has(id)) return transparentBlobMap.get(id);\\n const offscreen = new OffscreenCanvas(width, height);\\n offscreen.getContext(\"2d\");\\n const blob = await offscreen.convertToBlob(dataURLOptions);\\n const arrayBuffer = await blob.arrayBuffer();\\n const base64 = encode(arrayBuffer);\\n transparentBlobMap.set(id, base64);\\n return base64;\\n } else {\\n return \"\";\\n }\\n }\\n const worker = self;\\n let reusableCanvas = null;\\n let reusableCtx = null;\\n worker.onmessage = async function(e) {\\n if (\"OffscreenCanvas\" in globalThis) {\\n const { id, bitmap, width, height, displayWidth, displayHeight, dataURLOptions } = e.data;\\n try {\\n const transparentBase64 = getTransparentBlobFor(\\n width,\\n height,\\n dataURLOptions\\n );\\n if (!reusableCanvas || reusableCanvas.width !== width || reusableCanvas.height !== height) {\\n reusableCanvas = new OffscreenCanvas(width, height);\\n reusableCtx = reusableCanvas.getContext(\"2d\");\\n }\\n reusableCtx.clearRect(0, 0, width, height);\\n reusableCtx.drawImage(bitmap, 0, 0);\\n bitmap.close();\\n const blob = await reusableCanvas.convertToBlob(dataURLOptions);\\n const type = blob.type;\\n const arrayBuffer = await blob.arrayBuffer();\\n const fingerprint = fnv1aHash(arrayBuffer);\\n if (!lastFingerprintMap.has(id)) {\\n const base642 = encode(arrayBuffer);\\n if (await transparentBase64 === base642) {\\n lastFingerprintMap.set(id, fingerprint);\\n return worker.postMessage({ id });\\n }\\n lastFingerprintMap.set(id, fingerprint);\\n worker.postMessage({ id, type, base64: base642, displayWidth, displayHeight });\\n return;\\n }\\n if (lastFingerprintMap.get(id) === fingerprint)\\n return worker.postMessage({ id });\\n const base64 = encode(arrayBuffer);\\n worker.postMessage({ id, type, base64, displayWidth, displayHeight });\\n lastFingerprintMap.set(id, fingerprint);\\n } catch {\\n worker.postMessage({ id });\\n }\\n } else {\\n e.data.bitmap.close();\\n return worker.postMessage({ id: e.data.id });\\n }\\n };\\n})();\\n//# sourceMappingURL=image-bitmap-data-url-worker-CSpkoNCs.js.map\\n';\nconst blob = typeof self !== \"undefined\" && self.Blob && new Blob([jsContent], { type: \"text/javascript;charset=utf-8\" });\nfunction WorkerWrapper(options) {\n let objURL;\n try {\n objURL = blob && (self.URL || self.webkitURL).createObjectURL(blob);\n if (!objURL) throw \"\";\n const worker = new Worker(objURL, {\n name: options == null ? void 0 : options.name\n });\n worker.addEventListener(\"error\", () => {\n (self.URL || self.webkitURL).revokeObjectURL(objURL);\n });\n return worker;\n } catch (e) {\n return new Worker(\n \"data:text/javascript;charset=utf-8,\" + encodeURIComponent(jsContent),\n {\n name: options == null ? void 0 : options.name\n }\n );\n } finally {\n objURL && (self.URL || self.webkitURL).revokeObjectURL(objURL);\n }\n}\nconst MIN_CANVAS_RESOLUTION_SCALE = 0.1;\nclass CanvasManager {\n constructor(options) {\n __publicField(this, \"pendingCanvasMutations\", /* @__PURE__ */ new Map());\n __publicField(this, \"rafStamps\", { latestId: 0, invokeId: null });\n __publicField(this, \"mirror\");\n __publicField(this, \"mutationCb\");\n __publicField(this, \"resetObservers\");\n __publicField(this, \"frozen\", false);\n __publicField(this, \"locked\", false);\n __publicField(this, \"rafIdTimestamp\", null);\n __publicField(this, \"rafIdFlush\", null);\n __publicField(this, \"refCount\", 0);\n __publicField(this, \"torndown\", false);\n __publicField(this, \"processMutation\", (target, mutation) => {\n const newFrame = this.rafStamps.invokeId && this.rafStamps.latestId !== this.rafStamps.invokeId;\n if (newFrame || !this.rafStamps.invokeId)\n this.rafStamps.invokeId = this.rafStamps.latestId;\n if (!this.pendingCanvasMutations.has(target)) {\n this.pendingCanvasMutations.set(target, []);\n }\n this.pendingCanvasMutations.get(target).push(mutation);\n });\n const {\n sampling = \"all\",\n win,\n blockClass,\n blockSelector,\n recordCanvas,\n dataURLOptions,\n resolutionScale\n } = options;\n this.mutationCb = options.mutationCb;\n this.mirror = options.mirror;\n if (recordCanvas && sampling === \"all\")\n this.initCanvasMutationObserver(\n win,\n blockClass,\n blockSelector,\n dataURLOptions\n );\n if (recordCanvas && typeof sampling === \"number\")\n this.initCanvasFPSObserver(sampling, win, blockClass, blockSelector, {\n dataURLOptions,\n resolutionScale\n });\n }\n // Shared by the main document and every iframe/shadow-root observer, so reference-count\n // teardown: a single root cleaning up must not unpatch getContext / stop the FPS loop globally.\n acquire() {\n this.refCount += 1;\n }\n reset() {\n if (this.refCount > 0) {\n this.refCount -= 1;\n }\n if (this.refCount > 0) {\n return;\n }\n this.teardown();\n }\n teardown() {\n if (this.torndown) {\n return;\n }\n this.torndown = true;\n this.pendingCanvasMutations.clear();\n this.resetObservers && this.resetObservers();\n if (this.rafIdTimestamp !== null) {\n cancelAnimationFrame(this.rafIdTimestamp);\n this.rafIdTimestamp = null;\n }\n if (this.rafIdFlush !== null) {\n cancelAnimationFrame(this.rafIdFlush);\n this.rafIdFlush = null;\n }\n }\n freeze() {\n this.frozen = true;\n }\n unfreeze() {\n this.frozen = false;\n }\n lock() {\n this.locked = true;\n }\n unlock() {\n this.locked = false;\n }\n initCanvasFPSObserver(fps, win, blockClass, blockSelector, options) {\n if (!(\"OffscreenCanvas\" in win)) {\n return;\n }\n const scale = typeof options.resolutionScale === \"number\" && Number.isFinite(options.resolutionScale) ? Math.min(\n 1,\n Math.max(MIN_CANVAS_RESOLUTION_SCALE, options.resolutionScale)\n ) : 1;\n const canvasContextReset = initCanvasContextObserver(\n win,\n blockClass,\n blockSelector,\n true\n );\n const snapshotInProgressMap = /* @__PURE__ */ new Map();\n const worker = new WorkerWrapper();\n worker.onmessage = (e) => {\n const { id } = e.data;\n snapshotInProgressMap.set(id, false);\n if (!(\"base64\" in e.data)) return;\n const { base64, type, displayWidth, displayHeight } = e.data;\n const dw = displayWidth;\n const dh = displayHeight;\n this.mutationCb({\n id,\n type: CanvasContext[\"2D\"],\n commands: [\n {\n property: \"clearRect\",\n // wipe canvas\n args: [0, 0, dw, dh]\n },\n {\n property: \"drawImage\",\n // draws (semi-transparent) image, stretched to display size\n args: [\n {\n rr_type: \"ImageBitmap\",\n args: [\n {\n rr_type: \"Blob\",\n data: [{ rr_type: \"ArrayBuffer\", base64 }],\n type\n }\n ]\n },\n 0,\n 0,\n dw,\n dh\n ]\n }\n ],\n displayWidth: dw,\n displayHeight: dh\n });\n };\n const timeBetweenSnapshots = 1e3 / fps;\n let lastSnapshotTime = 0;\n let rafId;\n const getCanvas = () => {\n const matchedCanvas = [];\n const searchCanvas = (haystack) => {\n try {\n haystack.querySelectorAll(\"canvas\").forEach((canvas) => {\n if (!isBlocked(canvas, blockClass, blockSelector, true)) {\n matchedCanvas.push(canvas);\n }\n });\n haystack.querySelectorAll(\"*\").forEach((elem) => {\n if (elem.shadowRoot) {\n searchCanvas(elem.shadowRoot);\n }\n });\n } catch {\n }\n };\n searchCanvas(win.document);\n return matchedCanvas;\n };\n const takeCanvasSnapshots = (timestamp) => {\n if (lastSnapshotTime && timestamp - lastSnapshotTime < timeBetweenSnapshots) {\n rafId = requestAnimationFrame(takeCanvasSnapshots);\n return;\n }\n lastSnapshotTime = timestamp;\n getCanvas().forEach(async (canvas) => {\n var _a2, _b;\n const id = this.mirror.getId(canvas);\n if (snapshotInProgressMap.get(id)) return;\n if (canvas.width === 0 || canvas.height === 0) return;\n snapshotInProgressMap.set(id, true);\n try {\n if ([\"webgl\", \"webgl2\"].includes(canvas.__context)) {\n const context = canvas.getContext(\n canvas.__context\n );\n if ((_a2 = context == null ? void 0 : context.isContextLost) == null ? void 0 : _a2.call(context)) {\n snapshotInProgressMap.set(id, false);\n return;\n }\n if (((_b = context == null ? void 0 : context.getContextAttributes()) == null ? void 0 : _b.preserveDrawingBuffer) === false) {\n context.clear(context.COLOR_BUFFER_BIT);\n }\n }\n const displayWidth = canvas.clientWidth || canvas.width;\n const displayHeight = canvas.clientHeight || canvas.height;\n const captureWidth = Math.max(1, Math.round(displayWidth * scale));\n const captureHeight = Math.max(1, Math.round(displayHeight * scale));\n const bitmap = await createImageBitmap(\n canvas,\n // only ask for a quality resampling filter when we're actually downscaling;\n // at full resolution this keeps capture identical to before.\n scale < 1 ? {\n resizeWidth: captureWidth,\n resizeHeight: captureHeight,\n resizeQuality: \"medium\"\n } : { resizeWidth: captureWidth, resizeHeight: captureHeight }\n );\n worker.postMessage(\n {\n id,\n bitmap,\n width: captureWidth,\n height: captureHeight,\n displayWidth,\n displayHeight,\n dataURLOptions: options.dataURLOptions\n },\n [bitmap]\n );\n } catch {\n snapshotInProgressMap.set(id, false);\n }\n });\n rafId = requestAnimationFrame(takeCanvasSnapshots);\n };\n rafId = requestAnimationFrame(takeCanvasSnapshots);\n this.resetObservers = () => {\n canvasContextReset();\n cancelAnimationFrame(rafId);\n };\n }\n initCanvasMutationObserver(win, blockClass, blockSelector, dataURLOptions) {\n this.startRAFTimestamping();\n this.startPendingCanvasMutationFlusher();\n const canvasContextReset = initCanvasContextObserver(\n win,\n blockClass,\n blockSelector,\n false\n );\n const canvas2DReset = initCanvas2DMutationObserver(\n this.processMutation.bind(this),\n win,\n blockClass,\n blockSelector,\n dataURLOptions\n );\n const canvasWebGL1and2Reset = initCanvasWebGLMutationObserver(\n this.processMutation.bind(this),\n win,\n blockClass,\n blockSelector,\n dataURLOptions\n );\n this.resetObservers = () => {\n canvasContextReset();\n canvas2DReset();\n canvasWebGL1and2Reset();\n };\n }\n startPendingCanvasMutationFlusher() {\n this.rafIdFlush = requestAnimationFrame(\n () => this.flushPendingCanvasMutations()\n );\n }\n startRAFTimestamping() {\n const setLatestRAFTimestamp = (timestamp) => {\n this.rafStamps.latestId = timestamp;\n this.rafIdTimestamp = requestAnimationFrame(setLatestRAFTimestamp);\n };\n this.rafIdTimestamp = requestAnimationFrame(setLatestRAFTimestamp);\n }\n flushPendingCanvasMutations() {\n this.pendingCanvasMutations.forEach(\n (_values, canvas) => {\n const id = this.mirror.getId(canvas);\n this.flushPendingCanvasMutationFor(canvas, id);\n }\n );\n this.rafIdFlush = requestAnimationFrame(\n () => this.flushPendingCanvasMutations()\n );\n }\n flushPendingCanvasMutationFor(canvas, id) {\n if (this.frozen || this.locked) {\n return;\n }\n const valuesWithType = this.pendingCanvasMutations.get(canvas);\n if (!valuesWithType || id === -1) return;\n const values = valuesWithType.map((value) => {\n const { type: type2, ...rest } = value;\n return rest;\n });\n const { type } = valuesWithType[0];\n this.mutationCb({ id, type, commands: values });\n this.pendingCanvasMutations.delete(canvas);\n }\n}\nclass StylesheetManager {\n constructor(options) {\n __publicField(this, \"trackedLinkElements\", /* @__PURE__ */ new WeakSet());\n __publicField(this, \"mutationCb\");\n __publicField(this, \"adoptedStyleSheetCb\");\n __publicField(this, \"styleMirror\", new StyleSheetMirror());\n this.mutationCb = options.mutationCb;\n this.adoptedStyleSheetCb = options.adoptedStyleSheetCb;\n }\n attachLinkElement(linkEl, childSn) {\n if (\"_cssText\" in childSn.attributes)\n this.mutationCb({\n adds: [],\n removes: [],\n texts: [],\n attributes: [\n {\n id: childSn.id,\n attributes: childSn.attributes\n }\n ]\n });\n this.trackLinkElement(linkEl);\n }\n trackLinkElement(linkEl) {\n if (this.trackedLinkElements.has(linkEl)) return;\n this.trackedLinkElements.add(linkEl);\n this.trackStylesheetInLinkElement(linkEl);\n }\n adoptStyleSheets(sheets, hostId) {\n if (sheets.length === 0) return;\n const adoptedStyleSheetData = {\n id: hostId,\n styleIds: []\n };\n const 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, index2) => ({\n rule: stringifyRule(r, sheet.href),\n index: index2\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 reset() {\n this.styleMirror.reset();\n this.trackedLinkElements = /* @__PURE__ */ new WeakSet();\n resetStylesheetLoadTracking();\n }\n // TODO: take snapshot on stylesheet reload by applying event listener\n trackStylesheetInLinkElement(_linkEl) {\n }\n}\nclass ProcessedNodeManager {\n constructor() {\n __publicField(this, \"nodeMap\", /* @__PURE__ */ new WeakMap());\n __publicField(this, \"active\", false);\n }\n inOtherBuffer(node, thisBuffer) {\n const buffers = this.nodeMap.get(node);\n return buffers && Array.from(buffers).some((buffer) => buffer !== thisBuffer);\n }\n add(node, buffer) {\n if (!this.active) {\n this.active = true;\n requestAnimationFrame(() => {\n this.nodeMap = /* @__PURE__ */ new WeakMap();\n this.active = false;\n });\n }\n this.nodeMap.set(node, (this.nodeMap.get(node) || /* @__PURE__ */ new Set()).add(buffer));\n }\n destroy() {\n }\n}\nlet wrappedEmit;\nlet takeFullSnapshot;\nlet canvasManager;\nlet recording = false;\ntry {\n if (Array.from([1], (x) => x * 2)[0] !== 2) {\n const cleanFrame = document.createElement(\"iframe\");\n document.body.appendChild(cleanFrame);\n Array.from = ((_a = cleanFrame.contentWindow) == null ? void 0 : _a.Array.from) || Array.from;\n document.body.removeChild(cleanFrame);\n }\n} catch (err) {\n console.debug(\"Unable to override Array.from\", err);\n}\nconst mirror = createMirror();\nfunction record(options = {}) {\n const {\n emit,\n checkoutEveryNms,\n checkoutEveryNth,\n blockClass = \"rr-block\",\n blockSelector = null,\n ignoreClass = \"rr-ignore\",\n ignoreSelector = null,\n maskTextClass = \"rr-mask\",\n maskTextSelector = null,\n inlineStylesheet = true,\n maskAllInputs,\n maskInputOptions: _maskInputOptions,\n slimDOMOptions: _slimDOMOptions,\n maskInputFn,\n maskTextFn,\n hooks,\n packFn,\n sampling = {},\n dataURLOptions: _dataURLOptions = {},\n canvasResolutionScale,\n mousemoveWait,\n recordDOM = true,\n recordCanvas = false,\n recordCrossOriginIframes = false,\n recordAfter = options.recordAfter === \"DOMContentLoaded\" ? options.recordAfter : \"load\",\n userTriggeredOnInput = false,\n collectFonts = false,\n inlineImages = false,\n plugins,\n keepIframeSrcFn = () => false,\n ignoreCSSAttributes = /* @__PURE__ */ new Set([]),\n errorHandler: errorHandler2\n } = options;\n registerErrorHandler(errorHandler2);\n const dataURLOptions = {\n type: \"image/webp\",\n quality: 0.4,\n maxBase64ImageLength: 1048576,\n ..._dataURLOptions\n };\n const inEmittingFrame = recordCrossOriginIframes ? window.parent === window : true;\n let passEmitsToParent = false;\n if (!inEmittingFrame) {\n try {\n if (window.parent.document) {\n passEmitsToParent = false;\n }\n } catch (e) {\n passEmitsToParent = true;\n }\n }\n if (inEmittingFrame && !emit) {\n throw new Error(\"emit function is required\");\n }\n if (!inEmittingFrame && !passEmitsToParent) {\n return () => {\n };\n }\n if (mousemoveWait !== void 0 && sampling.mousemove === void 0) {\n sampling.mousemove = mousemoveWait;\n }\n mirror.reset();\n const maskInputOptions = maskAllInputs === true ? {\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 } : _maskInputOptions !== void 0 ? _maskInputOptions : { password: true };\n const slimDOMOptions = slimDOMDefaults(\n _slimDOMOptions !== void 0 ? _slimDOMOptions : false\n );\n polyfill();\n let lastFullSnapshotEvent;\n let incrementalSnapshotCount = 0;\n const iframeObserverCleanups = /* @__PURE__ */ new Map();\n let runAndDetachIframeCleanup;\n let cleanupDetachedIframeObservers;\n const eventProcessor = (e) => {\n for (const plugin of plugins || []) {\n if (plugin.eventProcessor) {\n e = plugin.eventProcessor(e);\n }\n }\n if (packFn && // Disable packing events which will be emitted to parent frames.\n !passEmitsToParent) {\n e = packFn(e);\n }\n return e;\n };\n wrappedEmit = (r, isCheckout) => {\n var _a2;\n const e = r;\n e.timestamp = nowTimestamp();\n if (((_a2 = mutationBuffers[0]) == null ? void 0 : _a2.isFrozen()) && e.type !== EventType.FullSnapshot && !(e.type === EventType.IncrementalSnapshot && e.data.source === IncrementalSource.Mutation)) {\n mutationBuffers.forEach((buf) => buf.unfreeze());\n }\n if (inEmittingFrame) {\n emit == null ? void 0 : emit(eventProcessor(e), isCheckout);\n } else if (passEmitsToParent) {\n const message = {\n type: \"rrweb\",\n event: eventProcessor(e),\n origin: window.location.origin,\n isCheckout\n };\n window.parent.postMessage(message, \"*\");\n }\n if (e.type === EventType.FullSnapshot) {\n lastFullSnapshotEvent = e;\n incrementalSnapshotCount = 0;\n } else if (e.type === EventType.IncrementalSnapshot) {\n if (e.data.source === IncrementalSource.Mutation && e.data.isAttachIframe) {\n return;\n }\n incrementalSnapshotCount++;\n const exceedCount = checkoutEveryNth && incrementalSnapshotCount >= checkoutEveryNth;\n const exceedTime = checkoutEveryNms && e.timestamp - lastFullSnapshotEvent.timestamp > checkoutEveryNms;\n if (exceedCount || exceedTime) {\n takeFullSnapshot(true);\n }\n }\n };\n const wrappedMutationEmit = (m) => {\n if (m.removes && m.removes.length > 0) {\n const addedIds = m.adds.length > 0 ? new Set(m.adds.map((add) => add.node.id)) : null;\n const addedIframeElements = /* @__PURE__ */ new Set();\n if (m.adds.length > 0) {\n for (const add of m.adds) {\n const node = mirror.getNode(add.node.id);\n if (node && node.nodeName === \"IFRAME\") {\n addedIframeElements.add(node);\n }\n }\n }\n m.removes.forEach(({ id }) => {\n if (addedIds && addedIds.has(id)) return;\n const removedIframe = iframeManager.getIframeElementById(id);\n if (removedIframe && addedIframeElements.has(removedIframe)) {\n iframeManager.forgetIframeId(id);\n return;\n }\n runAndDetachIframeCleanup == null ? void 0 : runAndDetachIframeCleanup(id);\n iframeManager.removeIframeById(id);\n });\n cleanupDetachedIframeObservers == null ? void 0 : cleanupDetachedIframeObservers();\n iframeManager.cleanupDetachedIframes();\n }\n wrappedEmit({\n type: EventType.IncrementalSnapshot,\n data: {\n source: IncrementalSource.Mutation,\n ...m\n }\n });\n };\n const wrappedScrollEmit = (p) => wrappedEmit({\n type: EventType.IncrementalSnapshot,\n data: {\n source: IncrementalSource.Scroll,\n ...p\n }\n });\n const wrappedCanvasMutationEmit = (p) => wrappedEmit({\n type: EventType.IncrementalSnapshot,\n data: {\n source: IncrementalSource.CanvasMutation,\n ...p\n }\n });\n const wrappedAdoptedStyleSheetEmit = (a) => wrappedEmit({\n type: EventType.IncrementalSnapshot,\n data: {\n source: IncrementalSource.AdoptedStyleSheet,\n ...a\n }\n });\n const stylesheetManager = new StylesheetManager({\n mutationCb: wrappedMutationEmit,\n adoptedStyleSheetCb: wrappedAdoptedStyleSheetEmit\n });\n const iframeManager = new IframeManager({\n mirror,\n mutationCb: wrappedMutationEmit,\n stylesheetManager,\n recordCrossOriginIframes,\n wrappedEmit\n });\n for (const plugin of plugins || []) {\n if (plugin.getMirror)\n plugin.getMirror({\n nodeMirror: mirror,\n crossOriginIframeMirror: iframeManager.crossOriginIframeMirror,\n crossOriginIframeStyleMirror: iframeManager.crossOriginIframeStyleMirror\n });\n }\n const processedNodeManager = new ProcessedNodeManager();\n canvasManager = new CanvasManager({\n recordCanvas,\n mutationCb: wrappedCanvasMutationEmit,\n win: window,\n blockClass,\n blockSelector,\n mirror,\n sampling: sampling.canvas,\n dataURLOptions,\n resolutionScale: canvasResolutionScale\n });\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 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 stylesheetManager.reset();\n shadowDomManager.init();\n mutationBuffers.forEach((buf) => buf.lock());\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);\n }\n if (isSerializedStylesheet(n, mirror)) {\n stylesheetManager.trackLinkElement(n);\n }\n if (hasShadowRoot(n)) {\n shadowDomManager.addShadowRoot(index.shadowRoot(n), document);\n }\n },\n onIframeLoad: (iframe, childSn) => {\n iframeManager.attachIframe(iframe, childSn);\n shadowDomManager.observeAttachShadow(iframe);\n },\n onIframeListenerRegistered: (iframe, disposer) => {\n iframeManager.registerLoadListenerDisposer(iframe, disposer);\n },\n onStylesheetLoad: (linkEl, childSn) => {\n stylesheetManager.attachLinkElement(linkEl, childSn);\n },\n keepIframeSrcFn\n });\n if (!node) {\n return console.warn(\"Failed to snapshot the document\");\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());\n if (recordCrossOriginIframes) {\n iframeManager.reattachIframes();\n }\n if (document.adoptedStyleSheets && document.adoptedStyleSheets.length > 0)\n stylesheetManager.adoptStyleSheets(\n document.adoptedStyleSheets,\n mirror.getId(document)\n );\n };\n try {\n const handlers = [];\n runAndDetachIframeCleanup = (iframeId) => {\n const cleanups = iframeObserverCleanups.get(iframeId);\n if (!cleanups) return;\n cleanups.forEach((cleanup) => {\n callSafely(cleanup);\n const idx = handlers.indexOf(cleanup);\n if (idx !== -1) handlers.splice(idx, 1);\n });\n iframeObserverCleanups.delete(iframeId);\n };\n cleanupDetachedIframeObservers = () => {\n for (const [iframeId] of iframeObserverCleanups) {\n const iframe = mirror.getNode(iframeId);\n if (!iframe) {\n runAndDetachIframeCleanup == null ? void 0 : runAndDetachIframeCleanup(iframeId);\n continue;\n }\n try {\n if (!iframe.contentDocument || !iframe.contentDocument.defaultView) {\n runAndDetachIframeCleanup == null ? void 0 : runAndDetachIframeCleanup(iframeId);\n }\n } catch {\n runAndDetachIframeCleanup == null ? void 0 : runAndDetachIframeCleanup(iframeId);\n }\n }\n };\n const observe = (doc) => {\n var _a2;\n return callbackWrapper(initObservers)(\n {\n mutationCb: wrappedMutationEmit,\n mousemoveCb: (positions, source) => wrappedEmit({\n type: EventType.IncrementalSnapshot,\n data: {\n source,\n positions\n }\n }),\n mouseInteractionCb: (d) => wrappedEmit({\n type: EventType.IncrementalSnapshot,\n data: {\n source: IncrementalSource.MouseInteraction,\n ...d\n }\n }),\n scrollCb: wrappedScrollEmit,\n viewportResizeCb: (d) => wrappedEmit({\n type: EventType.IncrementalSnapshot,\n data: {\n source: IncrementalSource.ViewportResize,\n ...d\n }\n }),\n inputCb: (v) => wrappedEmit({\n type: EventType.IncrementalSnapshot,\n data: {\n source: IncrementalSource.Input,\n ...v\n }\n }),\n mediaInteractionCb: (p) => wrappedEmit({\n type: EventType.IncrementalSnapshot,\n data: {\n source: IncrementalSource.MediaInteraction,\n ...p\n }\n }),\n styleSheetRuleCb: (r) => wrappedEmit({\n type: EventType.IncrementalSnapshot,\n data: {\n source: IncrementalSource.StyleSheetRule,\n ...r\n }\n }),\n styleDeclarationCb: (r) => wrappedEmit({\n type: EventType.IncrementalSnapshot,\n data: {\n source: IncrementalSource.StyleDeclaration,\n ...r\n }\n }),\n canvasMutationCb: wrappedCanvasMutationEmit,\n fontCb: (p) => 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: ((_a2 = plugins == null ? void 0 : plugins.filter((p) => p.observer)) == null ? void 0 : _a2.map((p) => ({\n observer: p.observer,\n options: p.options,\n callback: (payload) => wrappedEmit({\n type: EventType.Plugin,\n data: {\n plugin: p.name,\n payload\n }\n })\n }))) || []\n },\n hooks\n );\n };\n const loadListener = (iframeEl) => {\n try {\n const iframeId = mirror.getId(iframeEl);\n const cleanup = observe(iframeEl.contentDocument);\n handlers.push(cleanup);\n if (iframeId !== -1) {\n let bucket = iframeObserverCleanups.get(iframeId);\n if (!bucket) {\n bucket = /* @__PURE__ */ new Set();\n iframeObserverCleanups.set(iframeId, bucket);\n }\n bucket.add(cleanup);\n }\n } catch (error) {\n console.warn(error);\n }\n };\n iframeManager.addLoadListener(loadListener);\n iframeManager.addPageHideListener((iframeEl) => {\n const iframeId = mirror.getId(iframeEl);\n runAndDetachIframeCleanup == null ? void 0 : runAndDetachIframeCleanup(iframeId);\n findAndRemoveIframeBuffer(iframeEl);\n });\n let lastFullscreenId = -1;\n const emitFullscreen = (payload) => wrappedEmit({\n type: EventType.Custom,\n data: { tag: FullscreenCustomEventTag, payload }\n });\n const emitFullscreenChange = () => {\n const doc = document;\n const fullscreenEl = doc.fullscreenElement ?? doc.webkitFullscreenElement ?? doc.mozFullScreenElement ?? doc.msFullscreenElement ?? null;\n const id = fullscreenEl ? mirror.getId(fullscreenEl) : -1;\n if (id === lastFullscreenId) return;\n if (lastFullscreenId !== -1) {\n emitFullscreen({ id: lastFullscreenId, enter: false });\n }\n lastFullscreenId = id;\n if (id !== -1) {\n emitFullscreen({ id, enter: true });\n }\n };\n const init = () => {\n takeFullSnapshot();\n handlers.push(observe(document));\n handlers.push(on(\"fullscreenchange\", emitFullscreenChange));\n handlers.push(on(\"webkitfullscreenchange\", emitFullscreenChange));\n handlers.push(on(\"mozfullscreenchange\", emitFullscreenChange));\n handlers.push(on(\"MSFullscreenChange\", emitFullscreenChange));\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((h) => callSafely(h));\n processedNodeManager.destroy();\n iframeManager.removeLoadListener();\n iframeManager.destroy();\n iframeObserverCleanups.clear();\n mirror.reset();\n recording = false;\n unregisterErrorHandler();\n };\n } catch (error) {\n console.warn(error);\n }\n}\nrecord.addCustomEvent = (tag, payload) => {\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};\nrecord.freezePage = () => {\n mutationBuffers.forEach((buf) => buf.freeze());\n};\nrecord.takeFullSnapshot = (isCheckout) => {\n if (!recording) {\n throw new Error(\"please take full snapshot after start recording\");\n }\n takeFullSnapshot(isCheckout);\n};\nrecord.mirror = mirror;\nexport {\n record,\n resetMaxDepthState,\n wasMaxDepthReached\n};\n//# sourceMappingURL=rrweb-record.js.map\n","var __defProp = Object.defineProperty;\nvar __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;\nvar __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== \"symbol\" ? key + \"\" : key, value);\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}\nclass StackFrame {\n constructor(obj) {\n __publicField(this, \"fileName\");\n __publicField(this, \"functionName\");\n __publicField(this, \"lineNumber\");\n __publicField(this, \"columnNumber\");\n this.fileName = obj.fileName || \"\";\n this.functionName = obj.functionName || \"\";\n this.lineNumber = obj.lineNumber;\n this.columnNumber = obj.columnNumber;\n }\n toString() {\n const lineNumber = this.lineNumber || \"\";\n const columnNumber = this.columnNumber || \"\";\n if (this.functionName)\n return `${this.functionName} (${this.fileName}:${lineNumber}:${columnNumber})`;\n return `${this.fileName}:${lineNumber}:${columnNumber}`;\n }\n}\nconst FIREFOX_SAFARI_STACK_REGEXP = /(^|@)\\S+:\\d+/;\nconst CHROME_IE_STACK_REGEXP = /^\\s*at .*(\\S+:\\d+|\\(native\\))/m;\nconst SAFARI_NATIVE_CODE_REGEXP = /^(eval@)?(\\[native code])?$/;\nconst ErrorStackParser = {\n /**\n * Given an Error object, extract the most information from it.\n */\n parse: function(error) {\n if (!error) {\n return [];\n }\n if (\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n typeof error.stacktrace !== \"undefined\" || // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n typeof error[\"opera#sourceloc\"] !== \"undefined\"\n ) {\n return this.parseOpera(\n error\n );\n } else if (error.stack && error.stack.match(CHROME_IE_STACK_REGEXP)) {\n return this.parseV8OrIE(error);\n } else if (error.stack) {\n return this.parseFFOrSafari(error);\n } else {\n return [];\n }\n },\n // Separate line and column numbers from a string of the form: (URI:Line:Column)\n extractLocation: function(urlLike) {\n if (urlLike.indexOf(\":\") === -1) {\n return [urlLike];\n }\n const regExp = /(.+?)(?::(\\d+))?(?::(\\d+))?$/;\n const parts = regExp.exec(urlLike.replace(/[()]/g, \"\"));\n if (!parts) throw new Error(`Cannot parse given url: ${urlLike}`);\n return [parts[1], parts[2] || void 0, parts[3] || void 0];\n },\n parseV8OrIE: function(error) {\n const filtered = error.stack.split(\"\\n\").filter(function(line) {\n return !!line.match(CHROME_IE_STACK_REGEXP);\n }, this);\n return filtered.map(function(line) {\n if (line.indexOf(\"(eval \") > -1) {\n line = line.replace(/eval code/g, \"eval\").replace(/(\\(eval at [^()]*)|(\\),.*$)/g, \"\");\n }\n let sanitizedLine = line.replace(/^\\s+/, \"\").replace(/\\(eval code/g, \"(\");\n const location = sanitizedLine.match(/ (\\((.+):(\\d+):(\\d+)\\)$)/);\n sanitizedLine = location ? sanitizedLine.replace(location[0], \"\") : sanitizedLine;\n const tokens = sanitizedLine.split(/\\s+/).slice(1);\n const locationParts = this.extractLocation(\n location ? location[1] : tokens.pop()\n );\n const functionName = tokens.join(\" \") || void 0;\n const fileName = [\"eval\", \"<anonymous>\"].indexOf(locationParts[0]) > -1 ? void 0 : locationParts[0];\n return new StackFrame({\n functionName,\n fileName,\n lineNumber: locationParts[1],\n columnNumber: locationParts[2]\n });\n }, this);\n },\n parseFFOrSafari: function(error) {\n const filtered = error.stack.split(\"\\n\").filter(function(line) {\n return !line.match(SAFARI_NATIVE_CODE_REGEXP);\n }, this);\n return filtered.map(function(line) {\n if (line.indexOf(\" > eval\") > -1) {\n line = line.replace(\n / line (\\d+)(?: > eval line \\d+)* > eval:\\d+:\\d+/g,\n \":$1\"\n );\n }\n if (line.indexOf(\"@\") === -1 && line.indexOf(\":\") === -1) {\n return new StackFrame({\n functionName: line\n });\n } else {\n const functionNameRegex = /((.*\".+\"[^@]*)?[^@]*)(?:@)/;\n const matches = line.match(functionNameRegex);\n const functionName = matches && matches[1] ? matches[1] : void 0;\n const locationParts = this.extractLocation(\n line.replace(functionNameRegex, \"\")\n );\n return new StackFrame({\n functionName,\n fileName: locationParts[0],\n lineNumber: locationParts[1],\n columnNumber: locationParts[2]\n });\n }\n }, this);\n },\n parseOpera: function(e) {\n if (!e.stacktrace || e.message.indexOf(\"\\n\") > -1 && e.message.split(\"\\n\").length > e.stacktrace.split(\"\\n\").length) {\n return this.parseOpera9(e);\n } else if (!e.stack) {\n return this.parseOpera10(e);\n } else {\n return this.parseOpera11(e);\n }\n },\n parseOpera9: function(e) {\n const lineRE = /Line (\\d+).*script (?:in )?(\\S+)/i;\n const lines = e.message.split(\"\\n\");\n const result = [];\n for (let i = 2, len = lines.length; i < len; i += 2) {\n const match = lineRE.exec(lines[i]);\n if (match) {\n result.push(\n new StackFrame({\n fileName: match[2],\n lineNumber: parseFloat(match[1])\n })\n );\n }\n }\n return result;\n },\n parseOpera10: function(e) {\n const lineRE = /Line (\\d+).*script (?:in )?(\\S+)(?:: In function (\\S+))?$/i;\n const lines = e.stacktrace.split(\"\\n\");\n const result = [];\n for (let i = 0, len = lines.length; i < len; i += 2) {\n const match = lineRE.exec(lines[i]);\n if (match) {\n result.push(\n new StackFrame({\n functionName: match[3] || void 0,\n fileName: match[2],\n lineNumber: parseFloat(match[1])\n })\n );\n }\n }\n return result;\n },\n // Opera 10.65+ Error.stack very similar to FF/Safari\n parseOpera11: function(error) {\n const filtered = error.stack.split(\"\\n\").filter(function(line) {\n return !!line.match(FIREFOX_SAFARI_STACK_REGEXP) && !line.match(/^Error created at/);\n }, this);\n return filtered.map(function(line) {\n const tokens = line.split(\"@\");\n const locationParts = this.extractLocation(tokens.pop());\n const functionCall = tokens.shift() || \"\";\n const functionName = functionCall.replace(/<anonymous function(: (\\w+))?>/, \"$2\").replace(/\\([^)]*\\)/g, \"\") || void 0;\n return new StackFrame({\n functionName,\n fileName: locationParts[0],\n lineNumber: locationParts[1],\n columnNumber: locationParts[2]\n });\n }, this);\n }\n};\nfunction pathToSelector(node) {\n if (!node || !node.outerHTML) {\n return \"\";\n }\n let path = \"\";\n while (node.parentElement) {\n let name = node.localName;\n if (!name) {\n break;\n }\n name = name.toLowerCase();\n const parent = node.parentElement;\n const domSiblings = [];\n if (parent.children && parent.children.length > 0) {\n for (let i = 0; i < parent.children.length; i++) {\n const sibling = parent.children[i];\n if (sibling.localName && sibling.localName.toLowerCase) {\n if (sibling.localName.toLowerCase() === name) {\n domSiblings.push(sibling);\n }\n }\n }\n }\n if (domSiblings.length > 1) {\n name += `:eq(${domSiblings.indexOf(node)})`;\n }\n path = name + (path ? \">\" + path : \"\");\n node = parent;\n }\n return path;\n}\nfunction isArray(obj) {\n return Array.isArray(obj);\n}\nfunction isObject(obj) {\n return typeof obj === \"object\" && obj !== null && !isArray(obj);\n}\nfunction isObjTooDeep(obj, limit) {\n if (limit === 0) {\n return true;\n }\n const keys = Object.keys(obj);\n for (const key of keys) {\n if (isObject(obj[key]) && isObjTooDeep(obj[key], limit - 1)) {\n return true;\n }\n }\n return false;\n}\nfunction stringify(obj, stringifyOptions) {\n const options = {\n numOfKeysLimit: 50,\n depthOfLimit: 4\n };\n Object.assign(options, stringifyOptions);\n const stack = [];\n const keys = [];\n return JSON.stringify(\n obj,\n function(key, value) {\n if (stack.length > 0) {\n const thisPos = stack.indexOf(this);\n ~thisPos ? stack.splice(thisPos + 1) : stack.push(this);\n ~thisPos ? keys.splice(thisPos, Infinity, key) : keys.push(key);\n if (~stack.indexOf(value)) {\n if (stack[0] === value) {\n value = \"[Circular ~]\";\n } else {\n value = \"[Circular ~.\" + keys.slice(0, stack.indexOf(value)).join(\".\") + \"]\";\n }\n }\n } else {\n stack.push(value);\n }\n if (value === null) return value;\n if (value === void 0) return \"undefined\";\n if (shouldIgnore(value)) {\n return toString(value);\n }\n if (typeof value === \"bigint\") {\n return value.toString() + \"n\";\n }\n if (value instanceof Event) {\n const eventResult = {};\n for (const eventKey in value) {\n const eventValue = value[eventKey];\n if (isArray(eventValue)) {\n eventResult[eventKey] = pathToSelector(\n eventValue.length ? eventValue[0] : null\n );\n } else {\n eventResult[eventKey] = eventValue;\n }\n }\n return eventResult;\n } else if (value instanceof Node) {\n if (value instanceof HTMLElement) {\n return value ? value.outerHTML : \"\";\n }\n return value.nodeName;\n } else if (value instanceof Error) {\n return value.stack ? value.stack + \"\\nEnd of stack for Error object\" : value.name + \": \" + value.message;\n }\n return value;\n }\n );\n function shouldIgnore(_obj) {\n if (isObject(_obj) && Object.keys(_obj).length > options.numOfKeysLimit) {\n return true;\n }\n if (typeof _obj === \"function\") {\n return true;\n }\n if (isObject(_obj) && isObjTooDeep(_obj, options.depthOfLimit)) {\n return true;\n }\n return false;\n }\n function toString(_obj) {\n let str = _obj.toString();\n if (options.stringLengthLimit && str.length > options.stringLengthLimit) {\n str = `${str.slice(0, options.stringLengthLimit)}...`;\n }\n return str;\n }\n}\nconst defaultLogOptions = {\n level: [\n \"assert\",\n \"clear\",\n \"count\",\n \"countReset\",\n \"debug\",\n \"dir\",\n \"dirxml\",\n \"error\",\n \"group\",\n \"groupCollapsed\",\n \"groupEnd\",\n \"info\",\n \"log\",\n \"table\",\n \"time\",\n \"timeEnd\",\n \"timeLog\",\n \"trace\",\n \"warn\"\n ],\n lengthThreshold: 1e3,\n logger: \"console\"\n};\nfunction initLogObserver(cb, win, options) {\n const logOptions = options ? Object.assign({}, defaultLogOptions, options) : defaultLogOptions;\n const loggerType = logOptions.logger;\n if (!loggerType) {\n return () => {\n };\n }\n let logger;\n if (typeof loggerType === \"string\") {\n logger = win[loggerType];\n } else {\n logger = loggerType;\n }\n let logCount = 0;\n let inStack = false;\n const cancelHandlers = [];\n if (logOptions.level.includes(\"error\")) {\n const errorHandler = (event) => {\n const message = event.message, error = event.error;\n const trace = ErrorStackParser.parse(error).map(\n (stackFrame) => stackFrame.toString()\n );\n const payload = [stringify(message, logOptions.stringifyOptions)];\n cb({\n level: \"error\",\n trace,\n payload\n });\n };\n win.addEventListener(\"error\", errorHandler);\n cancelHandlers.push(() => {\n win.removeEventListener(\"error\", errorHandler);\n });\n const unhandledrejectionHandler = (event) => {\n let error;\n let payload;\n if (event.reason instanceof Error) {\n error = event.reason;\n payload = [\n stringify(\n `Uncaught (in promise) ${error.name}: ${error.message}`,\n logOptions.stringifyOptions\n )\n ];\n } else {\n error = new Error();\n payload = [\n stringify(\"Uncaught (in promise)\", logOptions.stringifyOptions),\n stringify(event.reason, logOptions.stringifyOptions)\n ];\n }\n const trace = ErrorStackParser.parse(error).map(\n (stackFrame) => stackFrame.toString()\n );\n cb({\n level: \"error\",\n trace,\n payload\n });\n };\n win.addEventListener(\"unhandledrejection\", unhandledrejectionHandler);\n cancelHandlers.push(() => {\n win.removeEventListener(\"unhandledrejection\", unhandledrejectionHandler);\n });\n }\n for (const levelType of logOptions.level) {\n cancelHandlers.push(replace(logger, levelType));\n }\n return () => {\n cancelHandlers.forEach((h) => h());\n };\n function replace(_logger, level) {\n if (!_logger[level]) {\n return () => {\n };\n }\n return patch(\n _logger,\n level,\n (original) => {\n return (...args) => {\n original.apply(this, args);\n if (level === \"assert\" && !!args[0]) {\n return;\n }\n if (inStack) {\n return;\n }\n inStack = true;\n try {\n const trace = ErrorStackParser.parse(new Error()).map((stackFrame) => stackFrame.toString()).splice(1);\n const argsForPayload = level === \"assert\" ? args.slice(1) : args;\n const payload = argsForPayload.map(\n (s) => stringify(s, logOptions.stringifyOptions)\n );\n logCount++;\n if (logCount < logOptions.lengthThreshold) {\n cb({\n level,\n trace,\n payload\n });\n } else if (logCount === logOptions.lengthThreshold) {\n cb({\n level: \"warn\",\n trace: [],\n payload: [\n stringify(\"The number of log records reached the threshold.\")\n ]\n });\n }\n } catch (error) {\n original(\"rrweb logger error:\", error, ...args);\n } finally {\n inStack = false;\n }\n };\n }\n );\n }\n}\nconst PLUGIN_NAME = \"rrweb/console@1\";\nconst getRecordConsolePlugin = (options) => ({\n name: PLUGIN_NAME,\n observer: initLogObserver,\n options\n});\nexport {\n PLUGIN_NAME,\n getRecordConsolePlugin\n};\n//# sourceMappingURL=rrweb-plugin-console-record.js.map\n","var types_PostHogPersistedProperty = /*#__PURE__*/ function(PostHogPersistedProperty) {\n PostHogPersistedProperty[\"AnonymousId\"] = \"anonymous_id\";\n PostHogPersistedProperty[\"DistinctId\"] = \"distinct_id\";\n PostHogPersistedProperty[\"Props\"] = \"props\";\n PostHogPersistedProperty[\"EnablePersonProcessing\"] = \"enable_person_processing\";\n PostHogPersistedProperty[\"PersonMode\"] = \"person_mode\";\n PostHogPersistedProperty[\"FeatureFlagDetails\"] = \"feature_flag_details\";\n PostHogPersistedProperty[\"FeatureFlags\"] = \"feature_flags\";\n PostHogPersistedProperty[\"FeatureFlagPayloads\"] = \"feature_flag_payloads\";\n PostHogPersistedProperty[\"BootstrapFeatureFlagDetails\"] = \"bootstrap_feature_flag_details\";\n PostHogPersistedProperty[\"BootstrapFeatureFlags\"] = \"bootstrap_feature_flags\";\n PostHogPersistedProperty[\"BootstrapFeatureFlagPayloads\"] = \"bootstrap_feature_flag_payloads\";\n PostHogPersistedProperty[\"OverrideFeatureFlags\"] = \"override_feature_flags\";\n PostHogPersistedProperty[\"Queue\"] = \"queue\";\n PostHogPersistedProperty[\"LogsQueue\"] = \"logs_queue\";\n PostHogPersistedProperty[\"OptedOut\"] = \"opted_out\";\n PostHogPersistedProperty[\"SessionId\"] = \"session_id\";\n PostHogPersistedProperty[\"SessionStartTimestamp\"] = \"session_start_timestamp\";\n PostHogPersistedProperty[\"SessionLastTimestamp\"] = \"session_timestamp\";\n PostHogPersistedProperty[\"PersonProperties\"] = \"person_properties\";\n PostHogPersistedProperty[\"GroupProperties\"] = \"group_properties\";\n PostHogPersistedProperty[\"InstalledAppBuild\"] = \"installed_app_build\";\n PostHogPersistedProperty[\"InstalledAppVersion\"] = \"installed_app_version\";\n PostHogPersistedProperty[\"SessionReplay\"] = \"session_replay\";\n PostHogPersistedProperty[\"SessionReplayEventTriggerActivatedSession\"] = \"session_replay_event_trigger_activated_session\";\n PostHogPersistedProperty[\"SurveyLastSeenDate\"] = \"survey_last_seen_date\";\n PostHogPersistedProperty[\"SurveysSeen\"] = \"surveys_seen\";\n PostHogPersistedProperty[\"Surveys\"] = \"surveys\";\n PostHogPersistedProperty[\"RemoteConfig\"] = \"remote_config\";\n PostHogPersistedProperty[\"FlagsEndpointWasHit\"] = \"flags_endpoint_was_hit\";\n PostHogPersistedProperty[\"DeviceId\"] = \"device_id\";\n return PostHogPersistedProperty;\n}({});\nvar types_Compression = /*#__PURE__*/ function(Compression) {\n Compression[\"GZipJS\"] = \"gzip-js\";\n Compression[\"Base64\"] = \"base64\";\n return Compression;\n}({});\nconst FeatureFlagError = {\n ERRORS_WHILE_COMPUTING: 'errors_while_computing_flags',\n FLAG_MISSING: 'flag_missing',\n QUOTA_LIMITED: 'quota_limited',\n TIMEOUT: 'timeout',\n CONNECTION_ERROR: 'connection_error',\n UNKNOWN_ERROR: 'unknown_error',\n apiError: (status)=>`api_error_${status}`\n};\nvar types_SurveyPosition = /*#__PURE__*/ function(SurveyPosition) {\n SurveyPosition[\"TopLeft\"] = \"top_left\";\n SurveyPosition[\"TopCenter\"] = \"top_center\";\n SurveyPosition[\"TopRight\"] = \"top_right\";\n SurveyPosition[\"MiddleLeft\"] = \"middle_left\";\n SurveyPosition[\"MiddleCenter\"] = \"middle_center\";\n SurveyPosition[\"MiddleRight\"] = \"middle_right\";\n SurveyPosition[\"Left\"] = \"left\";\n SurveyPosition[\"Right\"] = \"right\";\n SurveyPosition[\"Center\"] = \"center\";\n return SurveyPosition;\n}({});\nvar types_SurveyWidgetType = /*#__PURE__*/ function(SurveyWidgetType) {\n SurveyWidgetType[\"Button\"] = \"button\";\n SurveyWidgetType[\"Tab\"] = \"tab\";\n SurveyWidgetType[\"Selector\"] = \"selector\";\n return SurveyWidgetType;\n}({});\nvar types_SurveyType = /*#__PURE__*/ function(SurveyType) {\n SurveyType[\"Popover\"] = \"popover\";\n SurveyType[\"API\"] = \"api\";\n SurveyType[\"Widget\"] = \"widget\";\n SurveyType[\"ExternalSurvey\"] = \"external_survey\";\n return SurveyType;\n}({});\nvar types_SurveyQuestionDescriptionContentType = /*#__PURE__*/ function(SurveyQuestionDescriptionContentType) {\n SurveyQuestionDescriptionContentType[\"Html\"] = \"html\";\n SurveyQuestionDescriptionContentType[\"Text\"] = \"text\";\n return SurveyQuestionDescriptionContentType;\n}({});\nvar types_SurveyValidationType = /*#__PURE__*/ function(SurveyValidationType) {\n SurveyValidationType[\"MinLength\"] = \"min_length\";\n SurveyValidationType[\"MaxLength\"] = \"max_length\";\n return SurveyValidationType;\n}({});\nvar types_SurveyRatingDisplay = /*#__PURE__*/ function(SurveyRatingDisplay) {\n SurveyRatingDisplay[\"Number\"] = \"number\";\n SurveyRatingDisplay[\"Emoji\"] = \"emoji\";\n return SurveyRatingDisplay;\n}({});\nvar types_SurveyQuestionType = /*#__PURE__*/ function(SurveyQuestionType) {\n SurveyQuestionType[\"Open\"] = \"open\";\n SurveyQuestionType[\"MultipleChoice\"] = \"multiple_choice\";\n SurveyQuestionType[\"SingleChoice\"] = \"single_choice\";\n SurveyQuestionType[\"Rating\"] = \"rating\";\n SurveyQuestionType[\"Link\"] = \"link\";\n return SurveyQuestionType;\n}({});\nvar types_SurveyQuestionBranchingType = /*#__PURE__*/ function(SurveyQuestionBranchingType) {\n SurveyQuestionBranchingType[\"NextQuestion\"] = \"next_question\";\n SurveyQuestionBranchingType[\"End\"] = \"end\";\n SurveyQuestionBranchingType[\"ResponseBased\"] = \"response_based\";\n SurveyQuestionBranchingType[\"SpecificQuestion\"] = \"specific_question\";\n return SurveyQuestionBranchingType;\n}({});\nvar types_SurveyMatchType = /*#__PURE__*/ function(SurveyMatchType) {\n SurveyMatchType[\"Regex\"] = \"regex\";\n SurveyMatchType[\"NotRegex\"] = \"not_regex\";\n SurveyMatchType[\"Exact\"] = \"exact\";\n SurveyMatchType[\"IsNot\"] = \"is_not\";\n SurveyMatchType[\"Icontains\"] = \"icontains\";\n SurveyMatchType[\"NotIcontains\"] = \"not_icontains\";\n return SurveyMatchType;\n}({});\nvar types_SurveySchedule = /*#__PURE__*/ function(SurveySchedule) {\n SurveySchedule[\"Once\"] = \"once\";\n SurveySchedule[\"Recurring\"] = \"recurring\";\n SurveySchedule[\"Always\"] = \"always\";\n return SurveySchedule;\n}({});\nvar types_ActionStepStringMatching = /*#__PURE__*/ function(ActionStepStringMatching) {\n ActionStepStringMatching[\"Contains\"] = \"contains\";\n ActionStepStringMatching[\"Exact\"] = \"exact\";\n ActionStepStringMatching[\"Regex\"] = \"regex\";\n return ActionStepStringMatching;\n}({});\nconst knownUnsafeEditableEvent = [\n '$snapshot',\n '$pageview',\n '$pageleave',\n '$set',\n 'survey dismissed',\n 'survey sent',\n 'survey shown',\n '$identify',\n '$groupidentify',\n '$create_alias',\n '$$client_ingestion_warning',\n '$web_experiment_applied',\n '$feature_enrollment_update',\n '$feature_flag_called'\n];\nconst knownUnsafeEditableEventProperty = [\n 'token'\n];\nexport { types_ActionStepStringMatching as ActionStepStringMatching, types_Compression as Compression, FeatureFlagError, types_PostHogPersistedProperty as PostHogPersistedProperty, types_SurveyMatchType as SurveyMatchType, types_SurveyPosition as SurveyPosition, types_SurveyQuestionBranchingType as SurveyQuestionBranchingType, types_SurveyQuestionDescriptionContentType as SurveyQuestionDescriptionContentType, types_SurveyQuestionType as SurveyQuestionType, types_SurveyRatingDisplay as SurveyRatingDisplay, types_SurveySchedule as SurveySchedule, types_SurveyType as SurveyType, types_SurveyValidationType as SurveyValidationType, types_SurveyWidgetType as SurveyWidgetType, knownUnsafeEditableEvent, knownUnsafeEditableEventProperty };\n","function includes(str, needle) {\n return -1 !== str.indexOf(needle);\n}\nconst trim = function(str) {\n return str.trim();\n};\nconst stripLeadingDollar = function(s) {\n return s.replace(/^\\$/, '');\n};\nfunction isDistinctIdStringLike(value) {\n return [\n 'distinct_id',\n 'distinctid'\n ].includes(value.toLowerCase());\n}\nfunction deepSortKeys(value) {\n if (null === value || 'object' != typeof value) return value;\n if (Array.isArray(value)) return value.map(deepSortKeys);\n return Object.keys(value).sort().reduce((acc, key)=>{\n acc[key] = deepSortKeys(value[key]);\n return acc;\n }, {});\n}\nfunction getPersonPropertiesHash(distinct_id, userPropertiesToSet, userPropertiesToSetOnce) {\n return JSON.stringify({\n distinct_id,\n userPropertiesToSet: userPropertiesToSet ? deepSortKeys(userPropertiesToSet) : void 0,\n userPropertiesToSetOnce: userPropertiesToSetOnce ? deepSortKeys(userPropertiesToSetOnce) : void 0\n });\n}\nexport { getPersonPropertiesHash, includes, isDistinctIdStringLike, stripLeadingDollar, trim };\n","import { knownUnsafeEditableEvent, knownUnsafeEditableEventProperty } from \"../types.mjs\";\nimport { includes } from \"./string-utils.mjs\";\nconst nativeIsArray = Array.isArray;\nconst ObjProto = Object.prototype;\nconst type_utils_hasOwnProperty = ObjProto.hasOwnProperty;\nconst type_utils_toString = ObjProto.toString;\nconst isArray = nativeIsArray || function(obj) {\n return '[object Array]' === type_utils_toString.call(obj);\n};\nconst isFunction = (x)=>'function' == typeof x;\nconst isNativeFunction = (x)=>isFunction(x) && -1 !== x.toString().indexOf('[native code]');\nconst isObject = (x)=>x === Object(x) && !isArray(x);\nconst isEmptyObject = (x)=>{\n if (isObject(x)) {\n for(const key in x)if (type_utils_hasOwnProperty.call(x, key)) return false;\n return true;\n }\n return false;\n};\nconst isUndefined = (x)=>void 0 === x;\nconst isString = (x)=>'[object String]' == type_utils_toString.call(x);\nconst isEmptyString = (x)=>isString(x) && 0 === x.trim().length;\nconst isNull = (x)=>null === x;\nconst isNullish = (x)=>isUndefined(x) || isNull(x);\nconst isNumber = (x)=>'[object Number]' == type_utils_toString.call(x) && x === x;\nconst isPositiveNumber = (value)=>isNumber(value) && value > 0;\nconst isBoolean = (x)=>'[object Boolean]' === type_utils_toString.call(x);\nconst isFormData = (x)=>x instanceof FormData;\nconst isFile = (x)=>x instanceof File;\nconst isPlainError = (x)=>x instanceof Error;\nconst isKnownUnsafeEditableEvent = (x)=>includes(knownUnsafeEditableEvent, x);\nconst isKnownUnsafeEditableEventProperty = (x)=>includes(knownUnsafeEditableEventProperty, x);\nfunction isPrimitive(value) {\n return null === value || 'object' != typeof value;\n}\nfunction isBuiltin(candidate, className) {\n return Object.prototype.toString.call(candidate) === `[object ${className}]`;\n}\nfunction isError(candidate) {\n switch(Object.prototype.toString.call(candidate)){\n case '[object Error]':\n case '[object Exception]':\n case '[object DOMException]':\n case '[object DOMError]':\n case '[object WebAssembly.Exception]':\n return true;\n default:\n return isInstanceOf(candidate, Error);\n }\n}\nfunction isErrorEvent(event) {\n return isBuiltin(event, 'ErrorEvent');\n}\nfunction isEvent(candidate) {\n return 'undefined' != typeof Event && isInstanceOf(candidate, Event);\n}\nfunction isPlainObject(candidate) {\n return isBuiltin(candidate, 'Object');\n}\nfunction isInstanceOf(candidate, base) {\n try {\n return candidate instanceof base;\n } catch {\n return false;\n }\n}\nconst yesLikeValues = [\n true,\n 'true',\n 1,\n '1',\n 'yes'\n];\nconst isYesLike = (val)=>includes(yesLikeValues, val);\nconst noLikeValues = [\n false,\n 'false',\n 0,\n '0',\n 'no'\n];\nconst isNoLike = (val)=>includes(noLikeValues, val);\nexport { type_utils_hasOwnProperty as hasOwnProperty, isArray, isBoolean, isBuiltin, isEmptyObject, isEmptyString, isError, isErrorEvent, isEvent, isFile, isFormData, isFunction, isKnownUnsafeEditableEvent, isKnownUnsafeEditableEventProperty, isNativeFunction, isNoLike, isNull, isNullish, isNumber, isObject, isPlainError, isPlainObject, isPositiveNumber, isPrimitive, isString, isUndefined, isYesLike, noLikeValues, yesLikeValues };\n","import { includes } from \"./string-utils.mjs\";\nimport { isFunction, isUndefined } from \"./type-utils.mjs\";\nconst FACEBOOK = 'Facebook';\nconst MOBILE = 'Mobile';\nconst IOS = 'iOS';\nconst ANDROID = 'Android';\nconst TABLET = 'Tablet';\nconst ANDROID_TABLET = ANDROID + ' ' + TABLET;\nconst IPAD = 'iPad';\nconst APPLE = 'Apple';\nconst APPLE_WATCH = APPLE + ' Watch';\nconst SAFARI = 'Safari';\nconst BLACKBERRY = 'BlackBerry';\nconst SAMSUNG = 'Samsung';\nconst SAMSUNG_BROWSER = SAMSUNG + 'Browser';\nconst SAMSUNG_INTERNET = SAMSUNG + ' Internet';\nconst CHROME = 'Chrome';\nconst CHROME_OS = CHROME + ' OS';\nconst CHROME_IOS = CHROME + ' ' + IOS;\nconst INTERNET_EXPLORER = 'Internet Explorer';\nconst INTERNET_EXPLORER_MOBILE = INTERNET_EXPLORER + ' ' + MOBILE;\nconst OPERA = 'Opera';\nconst OPERA_MINI = OPERA + ' Mini';\nconst EDGE = 'Edge';\nconst MICROSOFT_EDGE = 'Microsoft ' + EDGE;\nconst FIREFOX = 'Firefox';\nconst FIREFOX_IOS = FIREFOX + ' ' + IOS;\nconst NINTENDO = 'Nintendo';\nconst PLAYSTATION = 'PlayStation';\nconst XBOX = 'Xbox';\nconst ANDROID_MOBILE = ANDROID + ' ' + MOBILE;\nconst MOBILE_SAFARI = MOBILE + ' ' + SAFARI;\nconst WINDOWS = 'Windows';\nconst WINDOWS_PHONE = WINDOWS + ' Phone';\nconst NOKIA = 'Nokia';\nconst OUYA = 'Ouya';\nconst GENERIC = 'Generic';\nconst GENERIC_MOBILE = GENERIC + ' ' + MOBILE.toLowerCase();\nconst GENERIC_TABLET = GENERIC + ' ' + TABLET.toLowerCase();\nconst KONQUEROR = 'Konqueror';\nconst OCULUS_BROWSER = 'Oculus Browser';\nconst VIVALDI = 'Vivaldi';\nconst YANDEX = 'Yandex';\nconst WHALE = 'Whale';\nconst DUCKDUCKGO = 'DuckDuckGo';\nconst PALE_MOON = 'Pale Moon';\nconst WATERFOX = 'Waterfox';\nconst BRAVE = 'Brave';\nconst GOOGLE_SEARCH_APP = 'Google Search App';\nconst BROWSER_VERSION_REGEX_SUFFIX = '(\\\\d+(\\\\.\\\\d+)?)';\nconst DEFAULT_BROWSER_VERSION_REGEX = new RegExp('Version/' + BROWSER_VERSION_REGEX_SUFFIX);\nfunction browserFromHints(hints) {\n if (hints?.brave) return BRAVE;\n return null;\n}\nconst XBOX_REGEX = new RegExp(XBOX, 'i');\nconst PLAYSTATION_REGEX = new RegExp(PLAYSTATION + ' \\\\w+', 'i');\nconst NINTENDO_REGEX = new RegExp(NINTENDO + ' \\\\w+', 'i');\nconst BLACKBERRY_REGEX = new RegExp(BLACKBERRY + '|PlayBook|BB10', 'i');\nconst windowsVersionMap = {\n 'NT3.51': 'NT 3.11',\n 'NT4.0': 'NT 4.0',\n '5.0': '2000',\n '5.1': 'XP',\n '5.2': 'XP',\n '6.0': 'Vista',\n '6.1': '7',\n '6.2': '8',\n '6.3': '8.1',\n '6.4': '10',\n '10.0': '10'\n};\nfunction isSafari(userAgent) {\n return includes(userAgent, SAFARI) && !includes(userAgent, CHROME) && !includes(userAgent, ANDROID);\n}\nconst safariCheck = (ua, vendor)=>vendor && includes(vendor, APPLE) || isSafari(ua);\nconst detectBrowser = function(user_agent, vendor, hints, options) {\n vendor = vendor || '';\n const fromHints = browserFromHints(hints);\n if (fromHints) return fromHints;\n if (options?.detectGoogleSearchApp && includes(user_agent, 'GSA/')) return GOOGLE_SEARCH_APP;\n if (includes(user_agent, ' OPR/') && includes(user_agent, 'Mini')) return OPERA_MINI;\n if (includes(user_agent, ' OPR/')) return OPERA;\n if (BLACKBERRY_REGEX.test(user_agent)) return BLACKBERRY;\n if (includes(user_agent, 'IE' + MOBILE) || includes(user_agent, 'WPDesktop')) return INTERNET_EXPLORER_MOBILE;\n if (includes(user_agent, 'OculusBrowser')) return OCULUS_BROWSER;\n else if (includes(user_agent, SAMSUNG_BROWSER)) return SAMSUNG_INTERNET;\n else if (includes(user_agent, EDGE) || includes(user_agent, 'Edg/')) return MICROSOFT_EDGE;\n else if (includes(user_agent, VIVALDI + '/')) return VIVALDI;\n else if (includes(user_agent, 'YaBrowser/')) return YANDEX;\n else if (includes(user_agent, WHALE + '/')) return WHALE;\n else if (includes(user_agent, DUCKDUCKGO + '/') || includes(user_agent, 'Ddg/')) return DUCKDUCKGO;\n else if (includes(user_agent, 'FBIOS')) return FACEBOOK + ' ' + MOBILE;\n else if (includes(user_agent, 'UCWEB') || includes(user_agent, 'UCBrowser')) return 'UC Browser';\n else if (includes(user_agent, 'CriOS')) return CHROME_IOS;\n else if (includes(user_agent, 'CrMo')) return CHROME;\n else if (includes(user_agent, CHROME)) return CHROME;\n else if (includes(user_agent, ANDROID) && includes(user_agent, SAFARI)) return ANDROID_MOBILE;\n else if (includes(user_agent, 'FxiOS')) return FIREFOX_IOS;\n else if (includes(user_agent.toLowerCase(), KONQUEROR.toLowerCase())) return KONQUEROR;\n else if (includes(user_agent, BRAVE + '/')) return BRAVE;\n else if (safariCheck(user_agent, vendor)) return includes(user_agent, MOBILE) ? MOBILE_SAFARI : SAFARI;\n else if (includes(user_agent, 'PaleMoon/')) return PALE_MOON;\n else if (includes(user_agent, WATERFOX + '/')) return WATERFOX;\n else if (includes(user_agent, FIREFOX)) return FIREFOX;\n else if (includes(user_agent, 'MSIE') || includes(user_agent, 'Trident/')) return INTERNET_EXPLORER;\n else if (includes(user_agent, 'Gecko')) return FIREFOX;\n return '';\n};\nconst versionRegexes = {\n [INTERNET_EXPLORER_MOBILE]: [\n new RegExp('rv:' + BROWSER_VERSION_REGEX_SUFFIX)\n ],\n [MICROSOFT_EDGE]: [\n new RegExp(EDGE + '?\\\\/' + BROWSER_VERSION_REGEX_SUFFIX)\n ],\n [CHROME]: [\n new RegExp('(' + CHROME + '|CrMo)\\\\/' + BROWSER_VERSION_REGEX_SUFFIX)\n ],\n [CHROME_IOS]: [\n new RegExp('CriOS\\\\/' + BROWSER_VERSION_REGEX_SUFFIX)\n ],\n 'UC Browser': [\n new RegExp('(UCBrowser|UCWEB)\\\\/' + BROWSER_VERSION_REGEX_SUFFIX)\n ],\n [SAFARI]: [\n DEFAULT_BROWSER_VERSION_REGEX\n ],\n [MOBILE_SAFARI]: [\n DEFAULT_BROWSER_VERSION_REGEX\n ],\n [OPERA]: [\n new RegExp('(' + OPERA + '|OPR)\\\\/' + BROWSER_VERSION_REGEX_SUFFIX)\n ],\n [FIREFOX]: [\n new RegExp(FIREFOX + '\\\\/' + BROWSER_VERSION_REGEX_SUFFIX)\n ],\n [FIREFOX_IOS]: [\n new RegExp('FxiOS\\\\/' + BROWSER_VERSION_REGEX_SUFFIX)\n ],\n [KONQUEROR]: [\n new RegExp('Konqueror[:/]?' + BROWSER_VERSION_REGEX_SUFFIX, 'i')\n ],\n [BLACKBERRY]: [\n new RegExp(BLACKBERRY + ' ' + BROWSER_VERSION_REGEX_SUFFIX),\n DEFAULT_BROWSER_VERSION_REGEX\n ],\n [ANDROID_MOBILE]: [\n new RegExp('android\\\\s' + BROWSER_VERSION_REGEX_SUFFIX, 'i')\n ],\n [SAMSUNG_INTERNET]: [\n new RegExp(SAMSUNG_BROWSER + '\\\\/' + BROWSER_VERSION_REGEX_SUFFIX)\n ],\n [OCULUS_BROWSER]: [\n new RegExp('OculusBrowser\\\\/' + BROWSER_VERSION_REGEX_SUFFIX)\n ],\n [VIVALDI]: [\n new RegExp(VIVALDI + '\\\\/' + BROWSER_VERSION_REGEX_SUFFIX)\n ],\n [YANDEX]: [\n new RegExp('YaBrowser\\\\/' + BROWSER_VERSION_REGEX_SUFFIX)\n ],\n [WHALE]: [\n new RegExp(WHALE + '\\\\/' + BROWSER_VERSION_REGEX_SUFFIX)\n ],\n [BRAVE]: [\n new RegExp(BRAVE + '\\\\/' + BROWSER_VERSION_REGEX_SUFFIX)\n ],\n [DUCKDUCKGO]: [\n new RegExp('(DuckDuckGo|Ddg)\\\\/' + BROWSER_VERSION_REGEX_SUFFIX)\n ],\n [PALE_MOON]: [\n new RegExp('PaleMoon\\\\/' + BROWSER_VERSION_REGEX_SUFFIX)\n ],\n [WATERFOX]: [\n new RegExp(WATERFOX + '\\\\/' + BROWSER_VERSION_REGEX_SUFFIX)\n ],\n [GOOGLE_SEARCH_APP]: [\n new RegExp('GSA\\\\/' + BROWSER_VERSION_REGEX_SUFFIX)\n ],\n [INTERNET_EXPLORER]: [\n new RegExp('(rv:|MSIE )' + BROWSER_VERSION_REGEX_SUFFIX)\n ],\n Mozilla: [\n new RegExp('rv:' + BROWSER_VERSION_REGEX_SUFFIX)\n ]\n};\nconst detectBrowserVersion = function(userAgent, vendor, hints, options) {\n const browser = detectBrowser(userAgent, vendor, hints, options);\n const regexes = versionRegexes[browser];\n if (isUndefined(regexes)) return null;\n for(let i = 0; i < regexes.length; i++){\n const regex = regexes[i];\n const matches = userAgent.match(regex);\n if (matches) return parseFloat(matches[matches.length - 2]);\n }\n return null;\n};\nconst osMatchers = [\n [\n new RegExp(XBOX + '; ' + XBOX + ' (.*?)[);]', 'i'),\n (match)=>[\n XBOX,\n match && match[1] || ''\n ]\n ],\n [\n new RegExp(NINTENDO, 'i'),\n [\n NINTENDO,\n ''\n ]\n ],\n [\n new RegExp(PLAYSTATION, 'i'),\n [\n PLAYSTATION,\n ''\n ]\n ],\n [\n BLACKBERRY_REGEX,\n [\n BLACKBERRY,\n ''\n ]\n ],\n [\n new RegExp(WINDOWS, 'i'),\n (_, user_agent)=>{\n if (/Phone/.test(user_agent) || /WPDesktop/.test(user_agent)) return [\n WINDOWS_PHONE,\n ''\n ];\n if (new RegExp(MOBILE).test(user_agent) && !/IEMobile\\b/.test(user_agent)) return [\n WINDOWS + ' ' + MOBILE,\n ''\n ];\n const match = /Windows NT ([0-9.]+)/i.exec(user_agent);\n if (match && match[1]) {\n const version = match[1];\n let osVersion = windowsVersionMap[version] || '';\n if (/arm/i.test(user_agent)) osVersion = 'RT';\n return [\n WINDOWS,\n osVersion\n ];\n }\n return [\n WINDOWS,\n ''\n ];\n }\n ],\n [\n /((iPhone|iPad|iPod).*?OS (\\d+)_(\\d+)_?(\\d+)?|iPhone)/,\n (match)=>{\n if (match && match[3]) {\n const versionParts = [\n match[3],\n match[4],\n match[5] || '0'\n ];\n return [\n IOS,\n versionParts.join('.')\n ];\n }\n return [\n IOS,\n ''\n ];\n }\n ],\n [\n /(watch.*\\/(\\d+\\.\\d+\\.\\d+)|watch os,(\\d+\\.\\d+),)/i,\n (match)=>{\n let version = '';\n if (match && match.length >= 3) version = isUndefined(match[2]) ? match[3] : match[2];\n return [\n 'watchOS',\n version\n ];\n }\n ],\n [\n new RegExp('(' + ANDROID + ' (\\\\d+)\\\\.(\\\\d+)\\\\.?(\\\\d+)?|' + ANDROID + ')', 'i'),\n (match)=>{\n if (match && match[2]) {\n const versionParts = [\n match[2],\n match[3],\n match[4] || '0'\n ];\n return [\n ANDROID,\n versionParts.join('.')\n ];\n }\n return [\n ANDROID,\n ''\n ];\n }\n ],\n [\n /Mac OS X (\\d+)[_.](\\d+)[_.]?(\\d+)?/i,\n (match)=>{\n const result = [\n 'Mac OS X',\n ''\n ];\n if (match && match[1]) {\n const versionParts = [\n match[1],\n match[2],\n match[3] || '0'\n ];\n result[1] = versionParts.join('.');\n }\n return result;\n }\n ],\n [\n /Mac/i,\n [\n 'Mac OS X',\n ''\n ]\n ],\n [\n /CrOS/,\n [\n CHROME_OS,\n ''\n ]\n ],\n [\n /Linux|debian/i,\n [\n 'Linux',\n ''\n ]\n ]\n];\nconst detectOS = function(user_agent) {\n for(let i = 0; i < osMatchers.length; i++){\n const [rgex, resultOrFn] = osMatchers[i];\n const match = rgex.exec(user_agent);\n const result = match && (isFunction(resultOrFn) ? resultOrFn(match, user_agent) : resultOrFn);\n if (result) return result;\n }\n return [\n '',\n ''\n ];\n};\nconst detectDevice = function(user_agent) {\n if (NINTENDO_REGEX.test(user_agent)) return NINTENDO;\n if (PLAYSTATION_REGEX.test(user_agent)) return PLAYSTATION;\n if (XBOX_REGEX.test(user_agent)) return XBOX;\n if (new RegExp(OUYA, 'i').test(user_agent)) return OUYA;\n if (new RegExp('(' + WINDOWS_PHONE + '|WPDesktop)', 'i').test(user_agent)) return WINDOWS_PHONE;\n else if (/iPad/.test(user_agent)) return IPAD;\n else if (/iPod/.test(user_agent)) return 'iPod Touch';\n else if (/iPhone/.test(user_agent)) return 'iPhone';\n else if (/(watch)(?: ?os[,/]|\\d,\\d\\/)[\\d.]+/i.test(user_agent)) return APPLE_WATCH;\n else if (BLACKBERRY_REGEX.test(user_agent)) return BLACKBERRY;\n else if (/(kobo)\\s(ereader|touch)/i.test(user_agent)) return 'Kobo';\n else if (new RegExp(NOKIA, 'i').test(user_agent)) return NOKIA;\n else if (/(kf[a-z]{2}wi|aeo[c-r]{2})( bui|\\))/i.test(user_agent) || /(kf[a-z]+)( bui|\\)).+silk\\//i.test(user_agent)) return 'Kindle Fire';\n else if (/(Android|ZTE)/i.test(user_agent)) if (!(!new RegExp(MOBILE).test(user_agent) || /(9138B|TB782B|Nexus [97]|pixel c|HUAWEISHT|BTV|noble nook|smart ultra 6)/i.test(user_agent))) return ANDROID;\n else {\n if (/pixel[\\daxl ]{1,6}/i.test(user_agent) && !/pixel c/i.test(user_agent) || /(huaweimed-al00|tah-|APA|SM-G92|i980|zte|U304AA)/i.test(user_agent) || /lmy47v/i.test(user_agent) && !/QTAQZ3/i.test(user_agent)) return ANDROID;\n return ANDROID_TABLET;\n }\n else if (new RegExp('(pda|' + MOBILE + ')', 'i').test(user_agent)) return GENERIC_MOBILE;\n else if (new RegExp(TABLET, 'i').test(user_agent) && !new RegExp(TABLET + ' pc', 'i').test(user_agent)) return GENERIC_TABLET;\n else return '';\n};\nconst detectDeviceType = function(user_agent, options) {\n const device = detectDevice(user_agent);\n if (device === IPAD || device === ANDROID_TABLET || 'Kobo' === device || 'Kindle Fire' === device || device === GENERIC_TABLET) return TABLET;\n if (device === NINTENDO || device === XBOX || device === PLAYSTATION || device === OUYA) return 'Console';\n if (device === APPLE_WATCH) return 'Wearable';\n if (device) return MOBILE;\n if (options?.userAgentDataPlatform === 'Android' && (options?.maxTouchPoints ?? 0) > 0) {\n const shortSide = Math.min(options?.screenWidth ?? 0, options?.screenHeight ?? 0);\n const shortSideDp = shortSide / (options?.devicePixelRatio ?? 1);\n return shortSideDp >= 600 ? TABLET : MOBILE;\n }\n return 'Desktop';\n};\nexport { detectBrowser, detectBrowserVersion, detectDevice, detectDeviceType, detectOS };\n","export * from \"./bot-detection.mjs\";\nexport * from \"./bucketed-rate-limiter.mjs\";\nexport * from \"./number-utils.mjs\";\nexport * from \"./string-utils.mjs\";\nexport * from \"./type-utils.mjs\";\nexport * from \"./promise-queue.mjs\";\nexport * from \"./logger.mjs\";\nexport * from \"./user-agent-utils.mjs\";\nconst STRING_FORMAT = 'utf8';\nconst UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\nfunction isValidUUID(value) {\n return 'string' == typeof value && UUID_REGEX.test(value);\n}\nfunction getEventUuid(uuid, generateUuid) {\n return isValidUUID(uuid) ? uuid : generateUuid();\n}\nfunction assert(truthyValue, message) {\n if (!truthyValue || 'string' != typeof truthyValue || isEmpty(truthyValue)) throw new Error(message);\n}\nfunction isEmpty(truthyValue) {\n if (0 === truthyValue.trim().length) return true;\n return false;\n}\nfunction removeTrailingSlash(url) {\n return url?.replace(/\\/+$/, '');\n}\nfunction stripUrlHash(url) {\n if (!url) return url;\n return url.split('#')[0];\n}\nasync function retriable(fn, props) {\n let lastError = null;\n for(let i = 0; i < props.retryCount + 1; i++){\n if (i > 0) await new Promise((r)=>setTimeout(r, props.retryDelay));\n try {\n const res = await fn();\n return res;\n } catch (e) {\n lastError = e;\n if (!props.retryCheck(e)) throw e;\n }\n }\n throw lastError;\n}\nfunction currentTimestamp() {\n return new Date().getTime();\n}\nfunction currentISOTime() {\n return new Date().toISOString();\n}\nfunction safeSetTimeout(fn, timeout) {\n const t = setTimeout(fn, timeout);\n t?.unref && t?.unref();\n return t;\n}\nconst isPromise = (obj)=>obj && 'function' == typeof obj.then;\nconst isError = (x)=>x instanceof Error;\nfunction getFetch() {\n return 'undefined' != typeof fetch ? fetch : void 0 !== globalThis.fetch ? globalThis.fetch : void 0;\n}\nfunction allSettled(promises) {\n return Promise.all(promises.map((p)=>(p ?? Promise.resolve()).then((value)=>({\n status: 'fulfilled',\n value\n }), (reason)=>({\n status: 'rejected',\n reason\n }))));\n}\nexport { STRING_FORMAT, UUID_REGEX, allSettled, assert, currentISOTime, currentTimestamp, getEventUuid, getFetch, isError, isPromise, isValidUUID, removeTrailingSlash, retriable, safeSetTimeout, stripUrlHash };\n","let parsedStackResults;\nlet lastKeysCount;\nlet cachedFilenameChunkIds;\nfunction getFilenameToChunkIdMap(stackParser) {\n const chunkIdMap = globalThis._posthogChunkIds;\n if (!chunkIdMap) return;\n const chunkIdKeys = Object.keys(chunkIdMap);\n if (cachedFilenameChunkIds && chunkIdKeys.length === lastKeysCount) return cachedFilenameChunkIds;\n lastKeysCount = chunkIdKeys.length;\n cachedFilenameChunkIds = chunkIdKeys.reduce((acc, stackKey)=>{\n if (!parsedStackResults) parsedStackResults = {};\n const result = parsedStackResults[stackKey];\n if (result) acc[result[0]] = result[1];\n else {\n const parsedStack = stackParser(stackKey);\n for(let i = parsedStack.length - 1; i >= 0; i--){\n const stackFrame = parsedStack[i];\n const filename = stackFrame?.filename;\n const chunkId = chunkIdMap[stackKey];\n if (filename && chunkId) {\n acc[filename] = chunkId;\n parsedStackResults[stackKey] = [\n filename,\n chunkId\n ];\n break;\n }\n }\n }\n return acc;\n }, {});\n return cachedFilenameChunkIds;\n}\nexport { getFilenameToChunkIdMap };\n","import { SurveyValidationType } from \"../types.mjs\";\nfunction getValidationError(value, rules, optional) {\n const trimmed = value.trim();\n if (!optional && '' === trimmed) return 'This field is required';\n if ('' === trimmed) return false;\n if (rules && rules.length > 0) for (const rule of rules)switch(rule.type){\n case SurveyValidationType.MinLength:\n if (void 0 !== rule.value && trimmed.length < rule.value) return rule.errorMessage ?? `Please enter at least ${rule.value} characters`;\n break;\n case SurveyValidationType.MaxLength:\n if (void 0 !== rule.value && trimmed.length > rule.value) return rule.errorMessage ?? `Please enter no more than ${rule.value} characters`;\n break;\n }\n return false;\n}\nfunction getLengthFromRules(rules, type) {\n if (!rules) return;\n const rule = rules.find((r)=>r.type === type);\n return rule?.value;\n}\nfunction getRequirementsHint(minLength, maxLength) {\n const effectiveMin = 1 === minLength ? void 0 : minLength;\n if (effectiveMin && maxLength) return `Enter ${effectiveMin}-${maxLength} characters`;\n if (effectiveMin) {\n const plural = 1 === effectiveMin ? 'character' : 'characters';\n return `Enter at least ${effectiveMin} ${plural}`;\n }\n if (maxLength) {\n const plural = 1 === maxLength ? 'character' : 'characters';\n return `Maximum ${maxLength} ${plural}`;\n }\n}\nexport { getLengthFromRules, getRequirementsHint, getValidationError };\n","import { isUndefined } from \"../../utils/index.mjs\";\nconst UNKNOWN_FUNCTION = '?';\nfunction createFrame(platform, filename, func, lineno, colno) {\n const frame = {\n platform,\n filename,\n function: '<anonymous>' === func ? UNKNOWN_FUNCTION : func,\n in_app: true\n };\n if (!isUndefined(lineno)) frame.lineno = lineno;\n if (!isUndefined(colno)) frame.colno = colno;\n return frame;\n}\nexport { UNKNOWN_FUNCTION, createFrame };\n","import { UNKNOWN_FUNCTION } from \"./base.mjs\";\nconst extractSafariExtensionDetails = (func, filename)=>{\n const isSafariExtension = -1 !== func.indexOf('safari-extension');\n const isSafariWebExtension = -1 !== func.indexOf('safari-web-extension');\n return isSafariExtension || isSafariWebExtension ? [\n -1 !== func.indexOf('@') ? func.split('@')[0] : UNKNOWN_FUNCTION,\n isSafariExtension ? `safari-extension:${filename}` : `safari-web-extension:${filename}`\n ] : [\n func,\n filename\n ];\n};\nexport { extractSafariExtensionDetails };\n","import { UNKNOWN_FUNCTION, createFrame } from \"./base.mjs\";\nimport { extractSafariExtensionDetails } from \"./safari.mjs\";\nconst chromeRegexNoFnName = /^\\s*at (\\S+?)(?::(\\d+))(?::(\\d+))\\s*$/i;\nconst chromeRegex = /^\\s*at (?:(.+?\\)(?: \\[.+\\])?|.*?) ?\\((?:address at )?)?(?:async )?((?:<anonymous>|[-a-z]+:|.*bundle|\\/)?.*?)(?::(\\d+))?(?::(\\d+))?\\)?\\s*$/i;\nconst chromeEvalRegex = /\\((\\S*)(?::(\\d+))(?::(\\d+))\\)/;\nconst chromeStackLineParser = (line, platform)=>{\n const noFnParts = chromeRegexNoFnName.exec(line);\n if (noFnParts) {\n const [, filename, line, col] = noFnParts;\n return createFrame(platform, filename, UNKNOWN_FUNCTION, +line, +col);\n }\n const parts = chromeRegex.exec(line);\n if (parts) {\n const isEval = parts[2] && 0 === parts[2].indexOf('eval');\n if (isEval) {\n const subMatch = chromeEvalRegex.exec(parts[2]);\n if (subMatch) {\n parts[2] = subMatch[1];\n parts[3] = subMatch[2];\n parts[4] = subMatch[3];\n }\n }\n const [func, filename] = extractSafariExtensionDetails(parts[1] || UNKNOWN_FUNCTION, parts[2]);\n return createFrame(platform, filename, func, parts[3] ? +parts[3] : void 0, parts[4] ? +parts[4] : void 0);\n }\n};\nexport { chromeStackLineParser };\n","import { UNKNOWN_FUNCTION, createFrame } from \"./base.mjs\";\nimport { extractSafariExtensionDetails } from \"./safari.mjs\";\nconst geckoREgex = /^\\s*(.*?)(?:\\((.*?)\\))?(?:^|@)?((?:[-a-z]+)?:\\/.*?|\\[native code\\]|[^@]*(?:bundle|\\d+\\.js)|\\/[\\w\\-. /=]+)(?::(\\d+))?(?::(\\d+))?\\s*$/i;\nconst geckoEvalRegex = /(\\S+) line (\\d+)(?: > eval line \\d+)* > eval/i;\nconst geckoStackLineParser = (line, platform)=>{\n const parts = geckoREgex.exec(line);\n if (parts) {\n const isEval = parts[3] && parts[3].indexOf(' > eval') > -1;\n if (isEval) {\n const subMatch = geckoEvalRegex.exec(parts[3]);\n if (subMatch) {\n parts[1] = parts[1] || 'eval';\n parts[3] = subMatch[1];\n parts[4] = subMatch[2];\n parts[5] = '';\n }\n }\n let filename = parts[3];\n let func = parts[1] || UNKNOWN_FUNCTION;\n [func, filename] = extractSafariExtensionDetails(func, filename);\n return createFrame(platform, filename, func, parts[4] ? +parts[4] : void 0, parts[5] ? +parts[5] : void 0);\n }\n};\nexport { geckoStackLineParser };\n","import { UNKNOWN_FUNCTION } from \"./base.mjs\";\nimport { chromeStackLineParser } from \"./chrome.mjs\";\nimport { geckoStackLineParser } from \"./gecko.mjs\";\nimport { winjsStackLineParser } from \"./winjs.mjs\";\nimport { opera10StackLineParser, opera11StackLineParser } from \"./opera.mjs\";\nimport { nodeStackLineParser } from \"./node.mjs\";\nconst WEBPACK_ERROR_REGEXP = /\\(error: (.*)\\)/;\nconst STACKTRACE_FRAME_LIMIT = 50;\nfunction reverseAndStripFrames(stack) {\n if (!stack.length) return [];\n const localStack = Array.from(stack);\n localStack.reverse();\n return localStack.slice(0, STACKTRACE_FRAME_LIMIT).map((frame)=>({\n ...frame,\n filename: frame.filename || getLastStackFrame(localStack).filename,\n function: frame.function || UNKNOWN_FUNCTION\n }));\n}\nfunction getLastStackFrame(arr) {\n return arr[arr.length - 1] || {};\n}\nfunction createDefaultStackParser() {\n return createStackParser(\"web:javascript\", chromeStackLineParser, geckoStackLineParser);\n}\nfunction createStackParser(platform, ...parsers) {\n return (stack, skipFirstLines = 0)=>{\n const frames = [];\n const lines = stack.split('\\n');\n for(let i = skipFirstLines; i < lines.length; i++){\n const line = lines[i];\n if (line.length > 1024) continue;\n const cleanedLine = WEBPACK_ERROR_REGEXP.test(line) ? line.replace(WEBPACK_ERROR_REGEXP, '$1') : line;\n if (!cleanedLine.match(/\\S*Error: /)) {\n for (const parser of parsers){\n const frame = parser(cleanedLine, platform);\n if (frame) {\n frames.push(frame);\n break;\n }\n }\n if (frames.length >= STACKTRACE_FRAME_LIMIT) break;\n }\n }\n return reverseAndStripFrames(frames);\n };\n}\nexport { chromeStackLineParser, createDefaultStackParser, createStackParser, geckoStackLineParser, nodeStackLineParser, opera10StackLineParser, opera11StackLineParser, reverseAndStripFrames, winjsStackLineParser };\n","const ERROR_TYPES_PATTERN = /^(?:[Uu]ncaught (?:exception: )?)?(?:((?:Eval|Internal|Range|Reference|Syntax|Type|URI|)Error): )?(.*)$/i;\nclass StringCoercer {\n match(input) {\n return 'string' == typeof input;\n }\n coerce(input, ctx) {\n const [type, value] = this.getInfos(input);\n return {\n type: type ?? 'Error',\n value: value ?? input,\n stack: ctx.syntheticException?.stack,\n synthetic: true\n };\n }\n getInfos(candidate) {\n let type = 'Error';\n let value = candidate;\n const groups = candidate.match(ERROR_TYPES_PATTERN);\n if (groups) {\n type = groups[1];\n value = groups[2];\n }\n return [\n type,\n value\n ];\n }\n}\nexport { StringCoercer };\n","const severityLevels = [\n 'fatal',\n 'error',\n 'warning',\n 'log',\n 'info',\n 'debug'\n];\nexport { severityLevels };\n","function truncate(str, max = 0) {\n if ('string' != typeof str || 0 === max) return str;\n return str.length <= max ? str : `${str.slice(0, max)}...`;\n}\nfunction extractExceptionKeysForMessage(err, maxLength = 40) {\n const keys = Object.keys(err);\n keys.sort();\n if (!keys.length) return '[object has no keys]';\n for(let i = keys.length; i > 0; i--){\n const serialized = keys.slice(0, i).join(', ');\n if (!(serialized.length > maxLength)) {\n if (i === keys.length) return serialized;\n return serialized.length <= maxLength ? serialized : `${serialized.slice(0, maxLength)}...`;\n }\n }\n return '';\n}\nexport { extractExceptionKeysForMessage, truncate };\n","import type { PostHog } from '../posthog-core'\nimport { SessionIdManager } from '../sessionid'\nimport {\n DeadClicksAutoCaptureConfig,\n ExternalIntegrationKind,\n Properties,\n RemoteConfig,\n SiteAppLoader,\n SessionStartReason,\n} from '../types'\nimport type {\n ConversationsRemoteConfig,\n GetMessagesResponse,\n GetTicketsOptions,\n GetTicketsResponse,\n MarkAsReadResponse,\n RestoreFromTokenResponse,\n RequestRestoreLinkResponse,\n SendMessageResponse,\n UserProvidedTraits,\n} from '../posthog-conversations-types'\n// only importing types here, so won't affect the bundle\n// eslint-disable-next-line posthog-js/no-external-replay-imports\nimport type { SessionRecordingStatus, TriggerType } from '../extensions/replay/external/triggerMatching'\nimport type { TracingHeadersDistinctId, TracingHeadersHostnames } from '../extensions/tracing-headers-types'\nimport { eventWithTime } from '../extensions/replay/types/rrweb-types'\nimport { ErrorTracking } from '@posthog/core'\n\n/*\n * Global helpers to protect access to browser globals in a way that is safer for different targets\n * like DOM, SSR, Web workers etc.\n *\n * NOTE: Typically we want the \"window\" but globalThis works for both the typical browser context as\n * well as other contexts such as the web worker context. Window is still exported for any bits that explicitly require it.\n * If in doubt - export the global you need from this file and use that as an optional value. This way the code path is forced\n * to handle the case where the global is not available.\n */\n\n// eslint-disable-next-line no-restricted-globals\nconst win: (Window & typeof globalThis) | undefined = typeof window !== 'undefined' ? window : undefined\n\nexport type AssignableWindow = Window &\n typeof globalThis & {\n /*\n * Main PostHog instance\n */\n posthog: any\n\n /*\n * This is our contract between (potentially) lazily loaded extensions and the SDK\n */\n __PosthogExtensions__?: PostHogExtensions\n\n /**\n * When loading remote config, we assign it to this global configuration\n * for ease of sharing it with the rest of the SDK\n */\n _POSTHOG_REMOTE_CONFIG?: Record<\n string,\n {\n config: RemoteConfig\n siteApps: SiteAppLoader[]\n }\n >\n\n /**\n * If this is set on the window, our logger will log to the console\n * for ease of debugging. Used for testing purposes only.\n *\n * @see {Config.DEBUG} from config.ts\n */\n POSTHOG_DEBUG: any\n\n // Exposed by the browser\n doNotTrack: any\n\n // See entrypoints/customizations.full.ts\n posthogCustomizations: any\n\n /**\n * This is a legacy way to expose these functions, but we still need to support it for backwards compatibility\n * Can be removed once we drop support for 1.161.1\n *\n * See entrypoints/exception-autocapture.ts\n *\n * @deprecated use `__PosthogExtensions__.errorWrappingFunctions` instead\n */\n posthogErrorWrappingFunctions: any\n\n /**\n * This is a legacy way to expose these functions, but we still need to support it for backwards compatibility\n * Can be removed once we drop support for 1.161.1\n *\n * See entrypoints/posthog-recorder.ts\n *\n * @deprecated use `__PosthogExtensions__.rrweb` instead\n */\n rrweb: any\n\n /**\n * This is a legacy way to expose these functions, but we still need to support it for backwards compatibility\n * Can be removed once we drop support for 1.161.1\n *\n * See entrypoints/posthog-recorder.ts\n *\n * @deprecated use `__PosthogExtensions__.rrwebConsoleRecord` instead\n */\n rrwebConsoleRecord: any\n\n /**\n * This is a legacy way to expose these functions, but we still need to support it for backwards compatibility\n * Can be removed once we drop support for 1.161.1\n *\n * See entrypoints/posthog-recorder.ts\n *\n * @deprecated use `__PosthogExtensions__.getRecordNetworkPlugin` instead\n */\n getRecordNetworkPlugin: any\n\n /**\n * This is a legacy way to expose these functions, but we still need to support it for backwards compatibility\n * Can be removed once we drop support for 1.161.1\n *\n * See entrypoints/web-vitals.ts\n *\n * @deprecated use `__PosthogExtensions__.postHogWebVitalsCallbacks` instead\n */\n postHogWebVitalsCallbacks: any\n\n /**\n * This is a legacy way to expose these functions, but we still need to support it for backwards compatibility\n * Can be removed once we drop support for 1.161.1\n *\n * See entrypoints/tracing-headers.ts\n *\n * @deprecated use `__PosthogExtensions__.postHogTracingHeadersPatchFns` instead\n */\n postHogTracingHeadersPatchFns: any\n\n /**\n * This is a legacy way to expose these functions, but we still need to support it for backwards compatibility\n * Can be removed once we drop support for 1.161.1\n *\n * See entrypoints/surveys.ts\n *\n * @deprecated use `__PosthogExtensions__.generateSurveys` instead\n */\n extendPostHogWithSurveys: any\n\n /*\n * These are used to handle our toolbar state.\n * @see {Toolbar} from extensions/toolbar.ts\n */\n ph_load_toolbar: any\n ph_load_editor: any\n ph_toolbar_state: any\n } & Record<`__$$ph_site_app_${string}`, any>\n\n/**\n * This is our contract between (potentially) lazily loaded extensions and the SDK\n * changes to this interface can be breaking changes for users of the SDK\n */\n\nexport type ExternalExtensionKind = 'intercom-integration' | 'crisp-chat-integration'\n\nexport type PostHogExtensionKind =\n | 'toolbar'\n | 'exception-autocapture'\n | 'web-vitals'\n | 'web-vitals-with-attribution'\n | 'recorder'\n | 'lazy-recorder'\n | 'tracing-headers'\n | 'surveys'\n | 'logs'\n | 'conversations'\n | 'product-tours'\n | 'dead-clicks-autocapture'\n | 'remote-config'\n | ExternalExtensionKind\n\nexport interface LazyLoadedSessionRecordingInterface {\n start: (startReason?: SessionStartReason) => void\n stop: () => void\n discard: () => void\n sessionId: string\n status: SessionRecordingStatus\n onRRwebEmit: (rawEvent: eventWithTime) => void\n log: (message: string, level: 'log' | 'warn' | 'error') => void\n sdkDebugProperties: Properties\n overrideLinkedFlag: () => void\n overrideSampling: () => void\n overrideTrigger: (triggerType: TriggerType) => void\n isStarted: boolean\n tryAddCustomEvent(tag: string, payload: any): boolean\n}\n\nexport interface LazyLoadedDeadClicksAutocaptureInterface {\n start: (observerTarget: Node) => void\n stop: () => void\n}\n\nexport interface LazyLoadedConversationsInterface {\n // Widget control\n show: () => void\n hide: () => void\n isVisible: () => boolean\n\n // Lifecycle\n reset: () => void\n\n // Identity verification\n setIdentity: () => void\n clearIdentity: () => void\n\n // API methods\n sendMessage: (message: string, userTraits?: UserProvidedTraits, newTicket?: boolean) => Promise<SendMessageResponse>\n getMessages: (ticketId?: string, after?: string) => Promise<GetMessagesResponse>\n markAsRead: (ticketId?: string) => Promise<MarkAsReadResponse>\n getTickets: (options?: GetTicketsOptions) => Promise<GetTicketsResponse>\n requestRestoreLink: (email: string) => Promise<RequestRestoreLinkResponse>\n restoreFromToken: (restoreToken: string) => Promise<RestoreFromTokenResponse>\n restoreFromUrlToken: () => Promise<RestoreFromTokenResponse | null>\n getCurrentTicketId: () => string | null\n getWidgetSessionId: () => string\n}\n\ninterface PostHogExtensions {\n loadExternalDependency?: (\n posthog: PostHog,\n kind: PostHogExtensionKind,\n callback: (error?: string | Event, event?: Event) => void\n ) => void\n\n loadSiteApp?: (posthog: PostHog, appUrl: string, callback: (error?: string | Event, event?: Event) => void) => void\n\n errorWrappingFunctions?: {\n wrapOnError: (captureFn: (props: ErrorTracking.ErrorProperties) => void) => () => void\n wrapUnhandledRejection: (captureFn: (props: ErrorTracking.ErrorProperties) => void) => () => void\n wrapConsoleError: (captureFn: (props: ErrorTracking.ErrorProperties) => void) => () => void\n }\n rrweb?: { record: any; version: string; wasMaxDepthReached?: () => boolean; resetMaxDepthState?: () => void }\n rrwebPlugins?: { getRecordConsolePlugin: any; getRecordNetworkPlugin?: any }\n generateSurveys?: (posthog: PostHog, isSurveysEnabled: boolean) => any | undefined\n generateProductTours?: (posthog: PostHog, isEnabled: boolean) => any | undefined\n logs?: {\n initializeLogs?: (posthog: PostHog) => any | undefined\n }\n postHogWebVitalsCallbacks?: {\n onLCP: (metric: any) => void\n onCLS: (metric: any) => void\n onFCP: (metric: any) => void\n onINP: (metric: any) => void\n }\n /**\n * @deprecated\n *\n * this was introduced briefly, it is now always a no-op and only kept for backwards compatibility\n */\n loadWebVitalsCallbacks?: (useAttribution?: boolean) => PostHogExtensions['postHogWebVitalsCallbacks']\n tracingHeadersPatchFns?: {\n _patchFetch: (\n hostnames: TracingHeadersHostnames,\n distinctId: TracingHeadersDistinctId,\n sessionManager?: SessionIdManager\n ) => () => void\n _patchXHR: (\n hostnames: TracingHeadersHostnames,\n distinctId: TracingHeadersDistinctId,\n sessionManager?: SessionIdManager\n ) => () => void\n }\n initDeadClicksAutocapture?: (\n ph: PostHog,\n config: DeadClicksAutoCaptureConfig\n ) => LazyLoadedDeadClicksAutocaptureInterface\n integrations?: {\n [K in ExternalIntegrationKind]?: { start: (posthog: PostHog) => void; stop: () => void }\n }\n initSessionRecording?: (ph: PostHog) => LazyLoadedSessionRecordingInterface\n initConversations?: (config: ConversationsRemoteConfig, posthog: PostHog) => LazyLoadedConversationsInterface\n}\n\nconst global: typeof globalThis | undefined = typeof globalThis !== 'undefined' ? globalThis : win\n\n// React Native polyfills for posthog-js compatibility\nif (typeof self === 'undefined') {\n ;(global as any).self = global\n}\nif (typeof File === 'undefined') {\n ;(global as any).File = function () {}\n}\n\nexport const navigator = global?.navigator\nexport const document = global?.document\nexport const location = global?.location\nexport const fetch = global?.fetch\nexport const XMLHttpRequest =\n global?.XMLHttpRequest && 'withCredentials' in new global.XMLHttpRequest() ? global.XMLHttpRequest : undefined\nexport const AbortController = global?.AbortController\nexport const CompressionStream = global?.CompressionStream\nexport const userAgent = navigator?.userAgent\nexport const assignableWindow: AssignableWindow = win ?? ({} as any)\n\nexport { win as window }\n","import { window } from './globals'\n\n// When angular patches functions they pass the above `isNativeFunction` check (at least the MutationObserver)\nexport const isAngularZonePresent = (): boolean => {\n return !!(window as any).Zone\n}\n\nexport const isDocument = (x: unknown): x is Document => {\n // eslint-disable-next-line posthog-js/no-direct-document-check\n return x instanceof Document\n}\n","import Config from '../config'\nimport { isUndefined } from '@posthog/core'\nimport { assignableWindow, window } from './globals'\nimport type { Logger } from '@posthog/core'\n\ntype CreateLoggerOptions = {\n debugEnabled?: boolean\n}\n\ntype PosthogJsLogger = Omit<Logger, 'createLogger'> & {\n _log: (level: 'debug' | 'log' | 'warn' | 'error', ...args: any[]) => void\n uninitializedWarning: (methodName: string) => void\n createLogger: (prefix: string, options?: CreateLoggerOptions) => PosthogJsLogger\n}\n\nconst _createLogger = (prefix: string, { debugEnabled }: CreateLoggerOptions = {}): PosthogJsLogger => {\n const logger: PosthogJsLogger = {\n _log: (level: 'debug' | 'log' | 'warn' | 'error', ...args: any[]) => {\n if (\n window &&\n (Config.DEBUG || assignableWindow.POSTHOG_DEBUG || debugEnabled) &&\n !isUndefined(window.console) &&\n window.console\n ) {\n const consoleLog =\n '__rrweb_original__' in window.console[level]\n ? (window.console[level] as any)['__rrweb_original__']\n : window.console[level]\n\n // eslint-disable-next-line no-console\n consoleLog(prefix, ...args)\n }\n },\n\n debug: (...args: any[]) => {\n logger._log('debug', ...args)\n },\n\n info: (...args: any[]) => {\n logger._log('log', ...args)\n },\n\n warn: (...args: any[]) => {\n logger._log('warn', ...args)\n },\n\n error: (...args: any[]) => {\n logger._log('error', ...args)\n },\n\n critical: (...args: any[]) => {\n // Critical errors are always logged to the console\n // eslint-disable-next-line no-console\n console.error(prefix, ...args)\n },\n\n uninitializedWarning: (methodName: string) => {\n logger.error(`You must initialize PostHog before calling ${methodName}`)\n },\n\n createLogger: (additionalPrefix: string, options?: CreateLoggerOptions) =>\n _createLogger(`${prefix} ${additionalPrefix}`, options),\n }\n return logger\n}\n\nexport const logger = _createLogger('[PostHog.js]')\n\nexport const createLogger = logger.createLogger\n","import { PostHogConfig, Properties } from '../types'\nimport { logger } from './logger'\nimport { isFormData, isNullish, isNumber, isString, hasOwnProperty, isArray } from '@posthog/core'\n\nexport function find<T>(value: T[], predicate: (value: T) => boolean): T | undefined {\n for (let i = 0; i < value.length; i++) {\n if (predicate(value[i])) {\n return value[i]\n }\n }\n return undefined\n}\n\nexport function eachArray<E = any>(obj: E[] | null | undefined, iterator: (value: E, key: number) => void): void {\n if (isArray(obj)) {\n obj.forEach(iterator)\n }\n}\n\nexport function each(obj: any, iterator: (value: any, key: any) => void): void {\n if (isNullish(obj)) {\n return\n }\n if (isArray(obj)) {\n obj.forEach(iterator)\n return\n }\n if (isFormData(obj)) {\n obj.forEach((val: any, key: any) => iterator(val, key))\n return\n }\n for (const key in obj) {\n if (hasOwnProperty.call(obj, key)) {\n iterator(obj[key], key)\n }\n }\n}\n\nexport const extend = function (obj: Record<string, any>, ...args: Record<string, any>[]): Record<string, any> {\n for (const source of args) {\n for (const prop in source) {\n if (source[prop] !== void 0) {\n obj[prop] = source[prop]\n }\n }\n }\n return obj\n}\n\n/**\n * Object.entries() polyfill\n * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries\n */\nexport function entries<T = any>(obj: Record<string, T>): [string, T][] {\n const ownProps = Object.keys(obj)\n let i = ownProps.length\n const resArray = new Array(i) // preallocate the Array\n\n while (i--) {\n resArray[i] = [ownProps[i], obj[ownProps[i]]]\n }\n return resArray\n}\n\nexport const trySafe = function <T>(fn: () => T): T | undefined {\n try {\n return fn()\n } catch {\n return undefined\n }\n}\n\nexport const safewrap = function <F extends (...args: any[]) => any = (...args: any[]) => any>(f: F): F {\n return function (...args) {\n try {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n return f.apply(this, args)\n } catch (e) {\n logger.critical(\n 'Implementation error. Please turn on debug mode and open a ticket on https://app.posthog.com/home#panel=support%3Asupport%3A.'\n )\n logger.critical(e)\n }\n } as F\n}\n\n// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\nexport const safewrapClass = function (klass: Function, functions: string[]): void {\n for (let i = 0; i < functions.length; i++) {\n klass.prototype[functions[i]] = safewrap(klass.prototype[functions[i]])\n }\n}\n\nexport const stripEmptyProperties = function (p: Properties): Properties {\n const ret: Properties = {}\n each(p, function (v, k) {\n if ((isString(v) && v.length > 0) || isNumber(v)) {\n ret[k] = v\n }\n })\n return ret\n}\n\n/**\n * Deep copies an object.\n * It handles cycles by replacing all references to them with `undefined`\n * Also supports customizing native values\n *\n * @param value\n * @param customizer\n * @returns {{}|undefined|*}\n */\nfunction deepCircularCopy<T extends Record<string, any> = Record<string, any>>(\n value: T,\n customizer?: <K extends keyof T = keyof T>(value: T[K], key?: K) => T[K]\n): T | undefined {\n const COPY_IN_PROGRESS_SET = new Set()\n\n function internalDeepCircularCopy(value: T, key?: string): T | undefined {\n if (value !== Object(value)) return customizer ? customizer(value as any, key) : value // primitive value\n\n if (COPY_IN_PROGRESS_SET.has(value)) return undefined\n COPY_IN_PROGRESS_SET.add(value)\n let result: T\n\n if (isArray(value)) {\n result = [] as any as T\n eachArray(value, (it) => {\n result.push(internalDeepCircularCopy(it))\n })\n } else {\n result = {} as T\n each(value, (val, key) => {\n if (!COPY_IN_PROGRESS_SET.has(val)) {\n ;(result as any)[key] = internalDeepCircularCopy(val, key)\n }\n })\n }\n return result\n }\n return internalDeepCircularCopy(value)\n}\n\nexport function _copyAndTruncateStrings<T extends Record<string, any> = Record<string, any>>(\n object: T,\n maxStringLength: number\n): T {\n return deepCircularCopy(object, (value: any) => {\n if (isString(value)) {\n return (value as string).slice(0, maxStringLength)\n }\n return value\n }) as T\n}\n\n// NOTE: Update PostHogConfig docs if you change this list\n// We will not try to catch all bullets here, but we should make an effort to catch the most common ones\n// You should be highly against adding more to this list, because ultimately customers can configure\n// their `cross_subdomain_cookie` setting to anything they want.\nconst EXCLUDED_FROM_CROSS_SUBDOMAIN_COOKIE = ['herokuapp.com', 'vercel.app', 'netlify.app']\nexport function isCrossDomainCookie(documentLocation: Location | undefined) {\n const hostname = documentLocation?.hostname\n\n if (!isString(hostname)) {\n return false\n }\n // split and slice isn't a great way to match arbitrary domains,\n // but it's good enough for ensuring we only match herokuapp.com when it is the TLD\n // for the hostname\n const lastTwoParts = hostname.split('.').slice(-2).join('.')\n\n for (const excluded of EXCLUDED_FROM_CROSS_SUBDOMAIN_COOKIE) {\n if (lastTwoParts === excluded) {\n return false\n }\n }\n\n return true\n}\n\n// Use this instead of element.addEventListener to avoid eslint errors\n// this properly implements the default options for passive event listeners\nexport function addEventListener(\n element: Window | Document | Element | undefined,\n event: string,\n callback: EventListener,\n options?: AddEventListenerOptions\n): void {\n const { capture = false, passive = true } = options ?? {}\n\n // This is the only place where we are allowed to call this function\n // because the whole idea is that we should be calling this instead of the built-in one\n // eslint-disable-next-line posthog-js/no-add-event-listener\n element?.addEventListener(event, callback, { capture, passive })\n}\n\n/**\n * Helper to migrate deprecated config fields to new field names with appropriate warnings\n * @param config - The config object to check\n * @param newField - The new field name to use\n * @param oldField - The deprecated field name to check for\n * @param defaultValue - The default value if neither field is set\n * @param loggerInstance - Optional logger instance for deprecation warnings\n * @returns The value to use (new field takes precedence over old field)\n */\nexport function migrateConfigField<T>(\n config: Record<string, any>,\n newField: string,\n oldField: string,\n defaultValue: T,\n loggerInstance?: { warn: (message: string) => void }\n): T {\n const hasNewField = newField in config && !isNullish(config[newField])\n const hasOldField = oldField in config && !isNullish(config[oldField])\n\n if (hasNewField) {\n return config[newField]\n }\n\n if (hasOldField) {\n if (loggerInstance) {\n loggerInstance.warn(\n `Config field '${oldField}' is deprecated. Please use '${newField}' instead. ` +\n `The old field will be removed in a future major version.`\n )\n }\n return config[oldField]\n }\n\n return defaultValue\n}\n\nconst TOOLBAR_INTERNAL_INSTANCE_NAME = 'ph_toolbar_internal'\n\nexport function isToolbarInstance(config: Pick<PostHogConfig, 'name'>): boolean {\n return config.name === TOOLBAR_INTERNAL_INSTANCE_NAME\n}\n","import { each } from './'\n\nimport { isArray, isFile, isUndefined } from '@posthog/core'\nimport { logger } from './logger'\nimport { document } from './globals'\n\nconst localDomains = ['localhost', '127.0.0.1']\n\n/**\n * IE11 doesn't support `new URL`\n * so we can create an anchor element and use that to parse the URL\n * there's a lot of overlap between HTMLHyperlinkElementUtils and URL\n * meaning useful properties like `pathname` are available on both\n */\nexport const convertToURL = (url: string): HTMLAnchorElement | null => {\n const location = document?.createElement('a')\n if (isUndefined(location)) {\n return null\n }\n\n location.href = url\n return location\n}\n\nexport const formDataToQuery = function (formdata: Record<string, any> | FormData, arg_separator = '&'): string {\n let use_val: string\n let use_key: string\n const tph_arr: string[] = []\n\n each(formdata, function (val: File | string | undefined, key: string | undefined) {\n // the key might be literally the string undefined for e.g. if {undefined: 'something'}\n if (isUndefined(val) || isUndefined(key) || key === 'undefined') {\n return\n }\n\n use_val = encodeURIComponent(isFile(val) ? val.name : val.toString())\n use_key = encodeURIComponent(key)\n tph_arr[tph_arr.length] = use_key + '=' + use_val\n })\n\n return tph_arr.join(arg_separator)\n}\n\nexport const getQueryParam = function (url: string, param: string): string {\n const withoutHash: string = url.split('#')[0] || ''\n\n // Split only on the first ? to sort problem out for those with multiple ?s\n // and then remove them\n const queryParams: string = withoutHash.split(/\\?(.*)/)[1] || ''\n const cleanedQueryParams = queryParams.replace(/^\\?+/g, '')\n\n const queryParts = cleanedQueryParams.split('&')\n let keyValuePair\n\n for (let i = 0; i < queryParts.length; i++) {\n const parts = queryParts[i].split('=')\n if (parts[0] === param) {\n keyValuePair = parts\n break\n }\n }\n\n if (!isArray(keyValuePair) || keyValuePair.length < 2) {\n return ''\n } else {\n let result = keyValuePair[1]\n try {\n result = decodeURIComponent(result)\n } catch {\n logger.error('Skipping decoding for malformed query param: ' + result)\n }\n return result.replace(/\\+/g, ' ')\n }\n}\n\n// replace any query params in the url with the provided mask value. Tries to keep the URL as instant as possible,\n// including preserving malformed text in most cases\nexport const maskQueryParams = function <T extends string | undefined>(\n url: T,\n maskedParams: string[] | undefined,\n mask: string\n): T extends string ? string : undefined {\n if (!url || !maskedParams || !maskedParams.length) {\n return url as any\n }\n\n const splitHash = url.split('#')\n const withoutHash: string = splitHash[0] || ''\n const hash = splitHash[1]\n\n const splitQuery: string[] = withoutHash.split('?')\n const queryString: string = splitQuery[1]\n const urlWithoutQueryAndHash: string = splitQuery[0]\n const queryParts = (queryString || '').split('&')\n\n // use an array of strings rather than an object to preserve ordering and duplicates\n const paramStrings: string[] = []\n\n for (let i = 0; i < queryParts.length; i++) {\n const keyValuePair = queryParts[i].split('=')\n if (!isArray(keyValuePair)) {\n continue\n } else if (maskedParams.includes(keyValuePair[0])) {\n paramStrings.push(keyValuePair[0] + '=' + mask)\n } else {\n paramStrings.push(queryParts[i])\n }\n }\n\n let result = urlWithoutQueryAndHash\n if (queryString != null) {\n result += '?' + paramStrings.join('&')\n }\n if (hash != null) {\n result += '#' + hash\n }\n\n return result as any\n}\n\nexport const _getHashParam = function (hash: string, param: string): string | null {\n const matches = hash.match(new RegExp(param + '=([^&]*)'))\n return matches ? matches[1] : null\n}\n\nexport const isLocalhost = (): boolean => {\n return localDomains.includes(location.hostname)\n}\n","// Portions of this file are derived from getsentry/sentry-javascript\n// Copyright (c) 2012 Functional Software, Inc. dba Sentry\n// Licensed under the MIT License: https://github.com/getsentry/sentry-javascript/blob/develop/LICENSE\n\n// import { patch } from 'rrweb/typings/utils'\n// copied from https://github.com/rrweb-io/rrweb/blob/8aea5b00a4dfe5a6f59bd2ae72bb624f45e51e81/packages/rrweb/src/utils.ts#L129\nimport { isFunction } from '@posthog/core'\n\nexport function patch(\n source: { [key: string]: any },\n name: string,\n replacement: (...args: unknown[]) => unknown\n): () => void {\n try {\n if (!(name in source)) {\n return () => {\n //\n }\n }\n\n const original = source[name] as () => unknown\n const wrapped = replacement(original)\n\n // Make sure it's a function first, as we need to attach an empty prototype for `defineProperties` to work\n // otherwise it'll throw \"TypeError: Object.defineProperties called on non-object\"\n if (isFunction(wrapped)) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n wrapped.prototype = wrapped.prototype || {}\n Object.defineProperties(wrapped, {\n __posthog_wrapped__: {\n enumerable: false,\n value: true,\n },\n })\n }\n\n source[name] = wrapped\n\n return () => {\n if (source[name] === wrapped) {\n source[name] = original\n }\n }\n } catch {\n return () => {\n //\n }\n // This can throw when multiple instrumentation layers try to wrap the same global object,\n // such as XMLHttpRequest, and redefine the same non-configurable wrapper marker.\n }\n}\n","import { NetworkRecordOptions } from '../../../types'\n\nfunction hostnameFromURL(url: string | URL | RequestInfo): string | null {\n try {\n if (typeof url === 'string') {\n return new URL(url).hostname\n }\n if ('url' in url) {\n return new URL(url.url).hostname\n }\n return url.hostname\n } catch {\n return null\n }\n}\n\nexport function isHostOnDenyList(url: string | URL | Request, options: NetworkRecordOptions) {\n const hostname = hostnameFromURL(url)\n const defaultNotDenied = { hostname, isHostDenied: false }\n\n if (!options.payloadHostDenyList?.length || !hostname?.trim().length) {\n return defaultNotDenied\n }\n\n for (const deny of options.payloadHostDenyList) {\n if (hostname.endsWith(deny)) {\n return { hostname, isHostDenied: true }\n }\n }\n\n return defaultNotDenied\n}\n","/*\n * Constants\n */\n\n/* PROPERTY KEYS */\n\n// This key is deprecated, but we want to check for it to see whether aliasing is allowed.\nexport const PEOPLE_DISTINCT_ID_KEY = '$people_distinct_id'\nexport const DISTINCT_ID = 'distinct_id'\nexport const DEVICE_ID = '$device_id'\nexport const DEVICE_MODEL = '$device_model'\nexport const ALIAS_ID_KEY = '__alias'\nexport const CAMPAIGN_IDS_KEY = '__cmpns'\nexport const EVENT_TIMERS_KEY = '__timers'\nexport const AUTOCAPTURE_DISABLED_SERVER_SIDE = '$autocapture_disabled_server_side'\nexport const HEATMAPS_ENABLED_SERVER_SIDE = '$heatmaps_enabled_server_side'\nexport const EXCEPTION_CAPTURE_ENABLED_SERVER_SIDE = '$exception_capture_enabled_server_side'\nexport const ERROR_TRACKING_SUPPRESSION_RULES = '$error_tracking_suppression_rules'\nexport const ERROR_TRACKING_CAPTURE_EXTENSION_EXCEPTIONS = '$error_tracking_capture_extension_exceptions'\nexport const WEB_VITALS_ENABLED_SERVER_SIDE = '$web_vitals_enabled_server_side'\nexport const DEAD_CLICKS_ENABLED_SERVER_SIDE = '$dead_clicks_enabled_server_side'\nexport const PRODUCT_TOURS_ENABLED_SERVER_SIDE = '$product_tours_enabled_server_side'\nexport const WEB_VITALS_ALLOWED_METRICS = '$web_vitals_allowed_metrics'\nexport const SESSION_RECORDING_REMOTE_CONFIG = '$session_recording_remote_config'\n// @deprecated can be removed along with eager loaded replay\nexport const SESSION_RECORDING_ENABLED_SERVER_SIDE = '$session_recording_enabled_server_side'\n// @deprecated can be removed along with eager loaded replay\nexport const CONSOLE_LOG_RECORDING_ENABLED_SERVER_SIDE = '$console_log_recording_enabled_server_side'\n// @deprecated can be removed along with eager loaded replay\nexport const SESSION_RECORDING_NETWORK_PAYLOAD_CAPTURE = '$session_recording_network_payload_capture'\n// @deprecated can be removed along with eager loaded replay\nexport const SESSION_RECORDING_MASKING = '$session_recording_masking'\n// @deprecated can be removed along with eager loaded replay\nexport const SESSION_RECORDING_CANVAS_RECORDING = '$session_recording_canvas_recording'\n// @deprecated can be removed along with eager loaded replay\nexport const SESSION_RECORDING_SAMPLE_RATE = '$replay_sample_rate'\n// @deprecated can be removed along with eager loaded replay\nexport const SESSION_RECORDING_MINIMUM_DURATION = '$replay_minimum_duration'\n// @deprecated can be removed along with eager loaded replay\nexport const SESSION_RECORDING_SCRIPT_CONFIG = '$replay_script_config'\nexport const SESSION_RECORDING_OVERRIDE_SAMPLING = '$replay_override_sampling'\nexport const SESSION_RECORDING_OVERRIDE_LINKED_FLAG = '$replay_override_linked_flag'\nexport const SESSION_RECORDING_OVERRIDE_URL_TRIGGER = '$replay_override_url_trigger'\nexport const SESSION_RECORDING_OVERRIDE_EVENT_TRIGGER = '$replay_override_event_trigger'\nexport const SESSION_ID = '$sesid'\nexport const SESSION_RECORDING_IS_SAMPLED = '$session_is_sampled'\nexport const SESSION_RECORDING_PAST_MINIMUM_DURATION = '$session_past_minimum_duration'\nexport const SESSION_RECORDING_URL_TRIGGER_ACTIVATED_SESSION = '$session_recording_url_trigger_activated_session'\nexport const SESSION_RECORDING_EVENT_TRIGGER_ACTIVATED_SESSION = '$session_recording_event_trigger_activated_session'\n// V2 Trigger Groups: Per-group persistence key prefixes (suffix with group ID)\nexport const SESSION_RECORDING_TRIGGER_V2_GROUP_EVENT_PREFIX = '$posthog_sr_group_event_trigger_'\nexport const SESSION_RECORDING_TRIGGER_V2_GROUP_URL_PREFIX = '$posthog_sr_group_url_trigger_'\nexport const SESSION_RECORDING_TRIGGER_V2_GROUP_SAMPLING_PREFIX = '$posthog_sr_group_sampling_'\nexport const SESSION_RECORDING_FIRST_FULL_SNAPSHOT_TIMESTAMP = '$debug_first_full_snapshot_timestamp'\nexport const SESSION_RECORDING_FLUSHED_SIZE = '$sess_rec_flush_size'\nexport const ENABLED_FEATURE_FLAGS = '$enabled_feature_flags'\nexport const PERSISTENCE_ACTIVE_FEATURE_FLAGS = '$active_feature_flags'\nexport const PERSISTENCE_EARLY_ACCESS_FEATURES = '$early_access_features'\nexport const PERSISTENCE_FEATURE_FLAG_DETAILS = '$feature_flag_details'\nexport const PERSISTENCE_FEATURE_FLAG_PAYLOADS = '$feature_flag_payloads'\nexport const PERSISTENCE_FEATURE_FLAG_REQUEST_ID = '$feature_flag_request_id'\nexport const PERSISTENCE_OVERRIDE_FEATURE_FLAGS = '$override_feature_flags'\nexport const PERSISTENCE_OVERRIDE_FEATURE_FLAG_PAYLOADS = '$override_feature_flag_payloads'\nexport const STORED_PERSON_PROPERTIES_KEY = '$stored_person_properties'\nexport const STORED_GROUP_PROPERTIES_KEY = '$stored_group_properties'\nexport const SURVEYS = '$surveys'\nexport const SURVEYS_LOADED_AT = '$surveys_loaded_at'\nexport const SURVEYS_ACTIVATED = '$surveys_activated'\nexport const PRODUCT_TOURS = 'ph_product_tours'\nexport const PRODUCT_TOURS_ACTIVATED = '$product_tours_activated'\nexport const CONVERSATIONS = '$conversations'\nexport const CONVERSATIONS_LEGACY_WIDGET_SESSION_ID = '$conversations_widget_session_id'\nexport const CONVERSATIONS_LEGACY_TICKET_ID = '$conversations_ticket_id'\nexport const CONVERSATIONS_LEGACY_WIDGET_STATE = '$conversations_widget_state'\nexport const CONVERSATIONS_LEGACY_USER_TRAITS = '$conversations_user_traits'\nexport const FLAG_CALL_REPORTED = '$flag_call_reported'\nexport const FLAG_CALL_REPORTED_SESSION_ID = '$flag_call_reported_session_id'\nexport const PERSISTENCE_FEATURE_FLAG_ERRORS = '$feature_flag_errors'\nexport const PERSISTENCE_FEATURE_FLAG_EVALUATED_AT = '$feature_flag_evaluated_at'\nexport const USER_STATE = '$user_state'\nexport const CLIENT_SESSION_PROPS = '$client_session_props'\nexport const CAPTURE_RATE_LIMIT = '$capture_rate_limit'\n\n/** @deprecated Delete this when INITIAL_PERSON_INFO has been around for long enough to ignore backwards compat */\nexport const INITIAL_CAMPAIGN_PARAMS = '$initial_campaign_params'\n/** @deprecated Delete this when INITIAL_PERSON_INFO has been around for long enough to ignore backwards compat */\nexport const INITIAL_REFERRER_INFO = '$initial_referrer_info'\nexport const INITIAL_PERSON_INFO = '$initial_person_info'\nexport const ENABLE_PERSON_PROCESSING = '$epp'\nexport const TOOLBAR_ID = '__POSTHOG_TOOLBAR__'\nexport const TOOLBAR_CONTAINER_CLASS = 'toolbar-global-fade-container'\n\n/**\n * PREVIEW - MAY CHANGE WITHOUT WARNING - DO NOT USE IN PRODUCTION\n * Sentinel value for distinct id, device id, session id. Signals that the server should generate the value\n * */\nexport const COOKIELESS_SENTINEL_VALUE = '$posthog_cookieless'\nexport const COOKIELESS_MODE_FLAG_PROPERTY = '$cookieless_mode'\n\nexport const WEB_EXPERIMENTS = '$web_experiments'\n\nexport const SDK_DIST_CHANNEL = '$sdk_dist_channel'\nexport const SDK_DEBUG_EXTENSIONS_INIT_METHOD = '$sdk_debug_extensions_init_method'\nexport const SDK_DEBUG_EXTENSIONS_INIT_TIME_MS = '$sdk_debug_extensions_init_time_ms'\nexport const SDK_DEBUG_RECORDING_SCRIPT_NOT_LOADED = '$sdk_debug_recording_script_not_loaded'\nexport const SDK_DEBUG_REPLAY_EVENT_TRIGGER_STATUS = '$sdk_debug_replay_event_trigger_status'\nexport const SDK_DEBUG_REPLAY_LINKED_FLAG_TRIGGER_STATUS = '$sdk_debug_replay_linked_flag_trigger_status'\nexport const SDK_DEBUG_REPLAY_MATCHED_RECORDING_TRIGGER_GROUPS = '$sdk_debug_replay_matched_recording_trigger_groups'\nexport const SDK_DEBUG_REPLAY_REMOTE_TRIGGER_MATCHING_CONFIG = '$sdk_debug_replay_remote_trigger_matching_config'\nexport const SDK_DEBUG_REPLAY_TRIGGER_GROUPS_COUNT = '$sdk_debug_replay_trigger_groups_count'\nexport const SDK_DEBUG_REPLAY_URL_TRIGGER_STATUS = '$sdk_debug_replay_url_trigger_status'\nexport const SDK_DEBUG_REPLAY_RRWEB_ATTACHED = '$sdk_debug_rrweb_attached'\nexport const SDK_DEBUG_REPLAY_RRWEB_START_ATTEMPTED = '$sdk_debug_rrweb_start_attempted'\nexport const SESSION_RECORDING_START_REASON = '$session_recording_start_reason'\n\nexport const SURVEYS_REQUEST_TIMEOUT_MS = 10000\nexport const LOAD_EXT_NOT_FOUND = 'PostHog loadExternalDependency extension not found.'\n\n/* EVENT NAMES - interned to reduce bundle size */\n/* COOKIELESS MODE VALUES */\nexport const COOKIELESS_ON_REJECT = 'on_reject' as const\nexport const COOKIELESS_ALWAYS = 'always' as const\n\n/* USER STATE VALUES */\nexport const USER_STATE_ANONYMOUS = 'anonymous'\nexport const USER_STATE_IDENTIFIED = 'identified'\n\n/* PERSON PROFILE MODES */\nexport const PERSON_PROFILES_IDENTIFIED_ONLY = 'identified_only' as const\n\n/* DOM EVENT NAMES - interned to reduce bundle size */\nexport const DOM_EVENT_VISIBILITYCHANGE = 'visibilitychange'\nexport const DOM_EVENT_BEFOREUNLOAD = 'beforeunload'\n\nexport const EVENT_PAGEVIEW = '$pageview'\nexport const EVENT_PAGELEAVE = '$pageleave'\nexport const EVENT_IDENTIFY = '$identify'\nexport const EVENT_GROUPIDENTIFY = '$groupidentify'\n\n/* Z-INDEX HIERARCHY: tours > surveys > support */\nexport const Z_INDEX_TOURS = 2147483646\nexport const Z_INDEX_SURVEYS = 2147483645\nexport const Z_INDEX_CONVERSATIONS = 2147483644\n","import { TOOLBAR_CONTAINER_CLASS, TOOLBAR_ID } from '../constants'\n\n// Node.nodeType integer constants. We use the integers directly rather than\n// `Node.ELEMENT_NODE` etc. for browser portability (IE11) and to avoid a\n// runtime reference to the global `Node` in environments where it isn't defined.\nconst NODE_TYPE_ELEMENT = 1\nconst NODE_TYPE_TEXT = 3\nconst NODE_TYPE_DOCUMENT_FRAGMENT = 11\n\nexport function isElementInToolbar(el: EventTarget | null): boolean {\n if (el instanceof Element) {\n // closest isn't available in IE11, but we'll polyfill when bundling\n return el.id === TOOLBAR_ID || !!el.closest?.('.' + TOOLBAR_CONTAINER_CLASS)\n }\n return false\n}\n\n/*\n * Check whether an element has nodeType Node.ELEMENT_NODE\n * @param {Element} el - element to check\n * @returns {boolean} whether el is of the correct nodeType\n */\nexport function isElementNode(el: Node | Element | undefined | null): el is Element {\n return !!el && el.nodeType === NODE_TYPE_ELEMENT\n}\n\n/*\n * Check whether an element is of a given tag type.\n * Due to potential reference discrepancies (such as the webcomponents.js polyfill),\n * we want to match tagNames instead of specific references because something like\n * element === document.body won't always work because element might not be a native\n * element.\n * @param {Element} el - element to check\n * @param {string} tag - tag name (e.g., \"div\")\n * @returns {boolean} whether el is of the given tag type\n */\nexport function isTag(el: Element | undefined | null, tag: string): el is HTMLElement {\n return !!el && !!el.tagName && el.tagName.toLowerCase() === tag.toLowerCase()\n}\n\n/*\n * Check whether an element has nodeType Node.TEXT_NODE\n * @param {Element} el - element to check\n * @returns {boolean} whether el is of the correct nodeType\n */\nexport function isTextNode(el: Element | undefined | null): el is HTMLElement {\n return !!el && el.nodeType === NODE_TYPE_TEXT\n}\n\n/*\n * Check whether a node is a ShadowRoot — a DocumentFragment whose `host` is\n * a real Element. Plain DocumentFragments (e.g. <template> content) share\n * the same nodeType but have no `host`, so they are not ShadowRoots.\n * @param {Node|undefined|null} el - node to check\n * @returns {boolean} whether el is a ShadowRoot we can hop through to its host\n */\nexport function isShadowRoot(el: Node | ParentNode | undefined | null): el is ShadowRoot {\n return !!el && el.nodeType === NODE_TYPE_DOCUMENT_FRAGMENT && isElementNode((el as ShadowRoot).host)\n}\n","import { AutocaptureConfig, PostHogConfig, Properties } from './types'\nimport type { PostHog } from './posthog-core'\nimport { each, entries } from './utils'\n\nimport { isNullish, isString, isUndefined, isArray, isBoolean } from '@posthog/core'\nimport { logger } from './utils/logger'\nimport { window } from './utils/globals'\nimport { getTargetingUrl } from './utils/url-targeting-utils'\nimport { isElementNode, isShadowRoot, isTag, isTextNode } from './utils/element-utils'\nimport { includes, trim } from '@posthog/core'\n\nexport function splitClassString(s: string): string[] {\n return s ? trim(s).split(/\\s+/) : []\n}\n\nfunction checkForURLMatches(urlsList: (string | RegExp)[], instance?: PostHog): boolean {\n const url = getTargetingUrl(instance)\n return !!(url && urlsList && urlsList.some((regex) => url.match(regex)))\n}\n\n/*\n * Get the className of an element, accounting for edge cases where element.className is an object\n *\n * Because this is a string it can contain unexpected characters\n * So, this method safely splits the className and returns that array.\n */\nexport function getClassNames(el: Element): string[] {\n let className = ''\n switch (typeof el.className) {\n case 'string':\n className = el.className\n break\n // TODO: when is this ever used?\n case 'object': // handle cases where className might be SVGAnimatedString or some other type\n className =\n (el.className && 'baseVal' in el.className ? (el.className as any).baseVal : null) ||\n el.getAttribute('class') ||\n ''\n break\n default:\n className = ''\n }\n\n return splitClassString(className)\n}\n\nexport function makeSafeText(s: string | null | undefined): string | null {\n if (isNullish(s)) {\n return null\n }\n\n return (\n trim(s)\n // scrub potentially sensitive values\n .split(/(\\s+)/)\n .filter((s) => shouldCaptureValue(s))\n .join('')\n // normalize whitespace\n .replace(/[\\r\\n]/g, ' ')\n .replace(/[ ]+/g, ' ')\n // truncate\n .substring(0, 255)\n )\n}\n\n/*\n * Get the direct text content of an element, protecting against sensitive data collection.\n * Concats textContent of each of the element's text node children; this avoids potential\n * collection of sensitive data that could happen if we used element.textContent and the\n * element had sensitive child elements, since element.textContent includes child content.\n * Scrubs values that look like they could be sensitive (i.e. cc or ssn number).\n * @param {Element} el - element to get the text of\n * @returns {string} the element's direct text content\n */\nexport function getSafeText(el: Element): string {\n let elText = ''\n\n if (shouldCaptureElement(el) && !isSensitiveElement(el) && el.childNodes && el.childNodes.length) {\n each(el.childNodes, function (child) {\n if (isTextNode(child) && child.textContent) {\n elText += makeSafeText(child.textContent) ?? ''\n }\n })\n }\n\n return trim(elText)\n}\n\nexport function getEventTarget(e: Event): Element | null {\n // https://developer.mozilla.org/en-US/docs/Web/API/Event/target#Compatibility_notes\n if (isUndefined(e.target)) {\n return (e.srcElement as Element) || null\n } else {\n if ((e.target as HTMLElement)?.shadowRoot) {\n return (e.composedPath()[0] as Element) || null\n }\n return (e.target as Element) || null\n }\n}\n\nexport const autocaptureCompatibleElements = ['a', 'button', 'form', 'input', 'select', 'textarea', 'label']\n\n/*\n if there is no config, then all elements are allowed\n if there is a config, and there is an allow list, then only elements in the allow list are allowed\n assumes that some other code is checking this element's parents\n */\nfunction checkIfElementTreePassesElementAllowList(\n elements: Element[],\n autocaptureConfig: AutocaptureConfig | undefined\n): boolean {\n const allowlist = autocaptureConfig?.element_allowlist\n if (isUndefined(allowlist)) {\n // everything is allowed, when there is no allow list\n return true\n }\n\n // check each element in the tree\n // if any of the elements are in the allow list, then the tree is allowed\n for (const el of elements) {\n if (allowlist.some((elementType) => el.tagName.toLowerCase() === elementType)) {\n return true\n }\n }\n\n // otherwise there is an allow list and this element tree didn't match it\n return false\n}\n\nfunction elementMatchesCSSSelector(el: Element, selector: string): boolean {\n const matches =\n el.matches ||\n (el as any).matchesSelector ||\n (el as any).msMatchesSelector ||\n (el as any).mozMatchesSelector ||\n (el as any).webkitMatchesSelector ||\n (el as any).oMatchesSelector\n try {\n return matches ? matches.call(el, selector) : false\n } catch {\n return false\n }\n}\n\n/*\n if there is no selector list (i.e. it is undefined), then any elements matches\n if there is an empty list, then no elements match\n if there is a selector list, then check it against each element provided\n */\nfunction checkIfElementsMatchCSSSelector(elements: Element[], selectorList: string[] | undefined): boolean {\n if (isUndefined(selectorList)) {\n // everything is allowed, when there is no selector list\n return true\n }\n\n for (const el of elements) {\n if (selectorList.some((selector) => elementMatchesCSSSelector(el, selector))) {\n return true\n }\n }\n\n return false\n}\n\nexport function getParentElement(curEl: Element): Element | false {\n const parentNode = curEl.parentNode\n if (!parentNode || !isElementNode(parentNode)) return false\n return parentNode\n}\n\nconst DEFAULT_AUTOCAPTURE_IGNORE_LIST = ['.ph-no-autocapture', '[data-ph-no-autocapture]']\nconst DEFAULT_CONTENT_IGNORELIST = ['next', 'previous', 'prev', '>', '<']\n// +/- steppers are built to be clicked repeatedly; enabled from the 2026-05-30 config defaults\nexport const DEFAULT_CONTENT_IGNORELIST_WITH_STEPPERS = [...DEFAULT_CONTENT_IGNORELIST, '+', '-', '−', '–']\nconst MAX_CONTENT_IGNORELIST_ENTRIES = 10\n\ninterface ElementWithText {\n safeText: string\n ariaLabel: string\n}\n\n// symbol keywords (e.g. +, -, >) match exactly so we don't suppress \"sign-up\", \"5 > 3\", \"C++\", etc.\nconst matchesContentKeyword = (text: string, keyword: string): boolean =>\n /[a-z0-9]/i.test(keyword) ? text.includes(keyword) : text === keyword\n\nfunction shouldIgnoreByContent(\n contentIgnorelist: boolean | string[] | undefined,\n elementsWithText: ElementWithText[]\n): boolean {\n if (contentIgnorelist === false || isUndefined(contentIgnorelist)) {\n return false\n }\n\n let keywords: string[]\n if (contentIgnorelist === true) {\n keywords = DEFAULT_CONTENT_IGNORELIST\n } else if (isArray(contentIgnorelist)) {\n if (contentIgnorelist.length > MAX_CONTENT_IGNORELIST_ENTRIES) {\n logger.error(\n `[PostHog] content_ignorelist array cannot exceed ${MAX_CONTENT_IGNORELIST_ENTRIES} items. Use css_selector_ignorelist for more complex matching.`\n )\n return false\n }\n keywords = contentIgnorelist.map((k) => k.toLowerCase())\n } else {\n return false\n }\n\n return elementsWithText.some(({ safeText, ariaLabel }) => {\n return keywords.some(\n (keyword) => matchesContentKeyword(safeText, keyword) || matchesContentKeyword(ariaLabel, keyword)\n )\n })\n}\n\n// dead click capture does not run through autocapture's ph-no-capture check,\n// so we include it here so that ph-no-capture also suppresses dead click capture\nconst DEFAULT_DEAD_CLICK_IGNORE_LIST = ['.ph-no-deadclick', '.ph-no-capture']\nexport function shouldCaptureDeadClick(el: Element | null, _config: PostHogConfig['capture_dead_clicks']) {\n if (!window || cannotCheckForAutocapture(el)) {\n return false\n }\n\n const selectorIgnoreList = isBoolean(_config)\n ? DEFAULT_DEAD_CLICK_IGNORE_LIST\n : (_config?.css_selector_ignorelist ?? DEFAULT_DEAD_CLICK_IGNORE_LIST)\n\n const { targetElementList } = getElementAndParentsForElement(el, false)\n\n // we don't capture if we match the ignore list\n return !checkIfElementsMatchCSSSelector(targetElementList, selectorIgnoreList)\n}\n\n// autocapture check will already filter for ph-no-capture,\n// but we include it here to protect against future changes accidentally removing that check\nconst DEFAULT_RAGE_CLICK_IGNORE_LIST = ['.ph-no-rageclick', '.ph-no-capture']\n\nconst TEXT_SELECTION_INPUT_TYPES = ['', 'text', 'search', 'email', 'password', 'url', 'tel', 'number']\n\nfunction isContentEditableTarget(el: Element): boolean {\n if ((el as Partial<HTMLElement>).isContentEditable) {\n return true\n }\n const contentEditable = el.getAttribute?.('contenteditable')\n return contentEditable === 'true' || contentEditable === ''\n}\n\n// repeated fast clicks on a text-editing surface are double/triple-click text selection, not rage\nexport function isTextSelectionTarget(el: Element | null): boolean {\n if (!el || !isElementNode(el)) {\n return false\n }\n if (isTag(el, 'textarea')) {\n return true\n }\n if (isTag(el, 'input')) {\n return includes(TEXT_SELECTION_INPUT_TYPES, (el.getAttribute('type') || '').toLowerCase())\n }\n return isContentEditableTarget(el)\n}\n\nexport function shouldCaptureRageclick(el: Element | null, _config: PostHogConfig['rageclick']) {\n if (!window || cannotCheckForAutocapture(el)) {\n return false\n }\n\n let selectorIgnoreList: string[] | boolean\n let contentIgnorelist: boolean | string[] | undefined\n let ignoreTextSelection: boolean\n if (isBoolean(_config)) {\n selectorIgnoreList = _config ? DEFAULT_RAGE_CLICK_IGNORE_LIST : false\n // For backward compatibility, don't enable content or text-selection filtering for rageclick: true\n contentIgnorelist = undefined\n ignoreTextSelection = false\n } else {\n selectorIgnoreList = _config?.css_selector_ignorelist ?? DEFAULT_RAGE_CLICK_IGNORE_LIST\n contentIgnorelist = _config?.content_ignorelist\n ignoreTextSelection = _config?.ignore_text_selection ?? false\n }\n\n if (selectorIgnoreList === false) {\n return false\n }\n\n if (ignoreTextSelection && isTextSelectionTarget(el)) {\n return false\n }\n\n // Traverse DOM once and cache element data to avoid redundant calls to getSafeText\n const { targetElementList } = getElementAndParentsForElement(el, false)\n const elementsWithText: ElementWithText[] = targetElementList.map((element) => ({\n safeText: getSafeText(element).toLowerCase(),\n ariaLabel: element.getAttribute('aria-label')?.toLowerCase().trim() || '',\n }))\n\n if (shouldIgnoreByContent(contentIgnorelist, elementsWithText)) {\n return false\n }\n\n // we don't capture if we match the ignore list\n return !checkIfElementsMatchCSSSelector(targetElementList, selectorIgnoreList)\n}\n\nconst cannotCheckForAutocapture = (el: Element | null) => {\n return !el || isTag(el, 'html') || !isElementNode(el)\n}\n\nconst getElementAndParentsForElement = (el: Element, captureOnAnyElement: false | true | undefined) => {\n if (!window || cannotCheckForAutocapture(el)) {\n return { parentIsUsefulElement: false, targetElementList: [] }\n }\n\n let parentIsUsefulElement = false\n const targetElementList: Element[] = [el]\n let curEl: Element = el\n while (curEl.parentNode && !isTag(curEl, 'body')) {\n if (isShadowRoot(curEl.parentNode)) {\n targetElementList.push(curEl.parentNode.host)\n curEl = curEl.parentNode.host\n continue\n }\n const parentNode = getParentElement(curEl)\n if (!parentNode) break\n if (captureOnAnyElement || autocaptureCompatibleElements.indexOf(parentNode.tagName.toLowerCase()) > -1) {\n parentIsUsefulElement = true\n } else {\n const compStyles = window.getComputedStyle(parentNode)\n if (compStyles && compStyles.getPropertyValue('cursor') === 'pointer') {\n parentIsUsefulElement = true\n }\n }\n\n targetElementList.push(parentNode)\n curEl = parentNode\n }\n return { parentIsUsefulElement, targetElementList }\n}\n\n// dead-click skips a click only when the click target is — or is inside — an <a>.\n// Anchors navigate / download / open a new window via the browser, and we have no\n// observable signal for those actions (no DOM mutation, no scroll). For every other\n// element (button, input, select, textarea, label, custom JS-handled divs, etc.) we\n// rely on the existing mutation / scroll / selection / visibility observers — if the\n// app's JS handler ran, those catch the effect; if it didn't, dead-click correctly\n// surfaces the bug. A click on a broken <button> with no handler should still flag.\nexport function shouldSkipDeadClick(el: Element | null): boolean {\n if (!window || cannotCheckForAutocapture(el)) {\n return false\n }\n const { targetElementList } = getElementAndParentsForElement(el, false)\n return targetElementList.some((node) => isTag(node, 'a'))\n}\n\n/*\n * Check whether a DOM event should be \"captured\" or if it may contain sensitive data\n * using a variety of heuristics.\n * @param {Element} el - element to check\n * @param {Event} event - event to check\n * @param {Object} autocaptureConfig - autocapture config\n * @param {boolean} captureOnAnyElement - whether to capture on any element, clipboard autocapture doesn't restrict to \"clickable\" elements\n * @param {string[]} allowedEventTypes - event types to capture, normally just 'click', but some autocapture types react to different events, some elements have fixed events (e.g., form has \"submit\")\n * @returns {boolean} whether the event should be captured\n */\nexport function shouldCaptureDomEvent(\n el: Element,\n event: Event,\n autocaptureConfig: AutocaptureConfig | undefined = undefined,\n captureOnAnyElement?: boolean,\n allowedEventTypes?: string[],\n instance?: PostHog\n): boolean {\n if (!window || cannotCheckForAutocapture(el)) {\n return false\n }\n\n if (autocaptureConfig?.url_allowlist) {\n // if the current URL is not in the allow list, don't capture\n if (!checkForURLMatches(autocaptureConfig.url_allowlist, instance)) {\n return false\n }\n }\n\n if (autocaptureConfig?.url_ignorelist) {\n // if the current URL is in the ignore list, don't capture\n if (checkForURLMatches(autocaptureConfig.url_ignorelist, instance)) {\n return false\n }\n }\n\n if (autocaptureConfig?.dom_event_allowlist) {\n const allowlist = autocaptureConfig.dom_event_allowlist\n if (allowlist && !allowlist.some((eventType) => event.type === eventType)) {\n return false\n }\n }\n\n const { parentIsUsefulElement, targetElementList } = getElementAndParentsForElement(el, captureOnAnyElement)\n\n if (!checkIfElementTreePassesElementAllowList(targetElementList, autocaptureConfig)) {\n return false\n }\n\n if (!checkIfElementsMatchCSSSelector(targetElementList, autocaptureConfig?.css_selector_allowlist)) {\n return false\n }\n\n const selectorIgnoreList = autocaptureConfig?.css_selector_ignorelist ?? DEFAULT_AUTOCAPTURE_IGNORE_LIST\n if (checkIfElementsMatchCSSSelector(targetElementList, selectorIgnoreList)) {\n return false\n }\n\n const compStyles = window.getComputedStyle(el)\n if (compStyles && compStyles.getPropertyValue('cursor') === 'pointer' && event.type === 'click') {\n return true\n }\n\n const tag = el.tagName.toLowerCase()\n switch (tag) {\n case 'html':\n return false\n case 'form':\n return (allowedEventTypes || ['submit']).indexOf(event.type) >= 0\n case 'input':\n case 'select':\n case 'textarea':\n return (allowedEventTypes || ['change', 'click']).indexOf(event.type) >= 0\n default:\n if (parentIsUsefulElement) return (allowedEventTypes || ['click']).indexOf(event.type) >= 0\n return (\n (allowedEventTypes || ['click']).indexOf(event.type) >= 0 &&\n (autocaptureCompatibleElements.indexOf(tag) > -1 || el.getAttribute('contenteditable') === 'true')\n )\n }\n}\n\n/*\n * Check whether a DOM element should be \"captured\" or if it may contain sensitive data\n * using a variety of heuristics.\n * @param {Element} el - element to check\n * @returns {boolean} whether the element should be captured\n */\nexport function shouldCaptureElement(el: Element): boolean {\n for (let curEl = el; curEl.parentNode && !isTag(curEl, 'body'); curEl = curEl.parentNode as Element) {\n const classes = getClassNames(curEl)\n if (includes(classes, 'ph-sensitive') || includes(classes, 'ph-no-capture')) {\n return false\n }\n }\n\n if (includes(getClassNames(el), 'ph-include')) {\n return true\n }\n\n // don't include hidden or password fields\n const type = (el as HTMLInputElement).type || ''\n if (isString(type)) {\n // it's possible for el.type to be a DOM element if el is a form with a child input[name=\"type\"]\n switch (type.toLowerCase()) {\n case 'hidden':\n return false\n case 'password':\n return false\n }\n }\n\n // filter out data from fields that look like sensitive fields\n const name = (el as HTMLInputElement).name || el.id || ''\n // See https://github.com/posthog/posthog-js/issues/165\n // Under specific circumstances a bug caused .replace to be called on a DOM element\n // instead of a string, removing the element from the page. Ensure this issue is mitigated.\n if (isString(name)) {\n // it's possible for el.name or el.id to be a DOM element if el is a form with a child input[name=\"name\"]\n const sensitiveNameRegex =\n /^cc|cardnum|ccnum|creditcard|csc|cvc|cvv|exp|pass|pwd|routing|seccode|securitycode|securitynum|socialsec|socsec|ssn/i\n if (sensitiveNameRegex.test(name.replace(/[^a-zA-Z0-9]/g, ''))) {\n return false\n }\n }\n\n return true\n}\n\n/*\n * Check whether a DOM element is 'sensitive' and we should only capture limited data\n * @param {Element} el - element to check\n * @returns {boolean} whether the element should be captured\n */\nexport function isSensitiveElement(el: Element): boolean {\n // don't send data from inputs or similar elements since there will always be\n // a risk of clientside javascript placing sensitive data in attributes\n const allowedInputTypes = ['button', 'checkbox', 'submit', 'reset']\n if (\n (isTag(el, 'input') && !allowedInputTypes.includes((el as HTMLInputElement).type)) ||\n isTag(el, 'select') ||\n isTag(el, 'textarea') ||\n el.getAttribute('contenteditable') === 'true'\n ) {\n return true\n }\n return false\n}\n\n// Define the core pattern for matching credit card numbers\nconst coreCCPattern = `(4[0-9]{12}(?:[0-9]{3})?)|(5[1-5][0-9]{14})|(6(?:011|5[0-9]{2})[0-9]{12})|(3[47][0-9]{13})|(3(?:0[0-5]|[68][0-9])[0-9]{11})|((?:2131|1800|35[0-9]{3})[0-9]{11})`\n// Create the Anchored version of the regex by adding '^' at the start and '$' at the end\nconst anchoredCCRegex = new RegExp(`^(?:${coreCCPattern})$`)\n// The Unanchored version is essentially the core pattern, usable as is for partial matches\nconst unanchoredCCRegex = new RegExp(coreCCPattern)\n\n// Define the core pattern for matching SSNs with optional dashes\nconst coreSSNPattern = `\\\\d{3}-?\\\\d{2}-?\\\\d{4}`\n// Create the Anchored version of the regex by adding '^' at the start and '$' at the end\nconst anchoredSSNRegex = new RegExp(`^(${coreSSNPattern})$`)\n// The Unanchored version is essentially the core pattern itself, usable for partial matches\nconst unanchoredSSNRegex = new RegExp(`(${coreSSNPattern})`)\n\n/*\n * Check whether a string value should be \"captured\" or if it may contain sensitive data\n * using a variety of heuristics.\n * @param {string} value - string value to check\n * @param {boolean} anchorRegexes - whether to anchor the regexes to the start and end of the string\n * @returns {boolean} whether the element should be captured\n */\nexport function shouldCaptureValue(value: string, anchorRegexes = true): boolean {\n if (isNullish(value)) {\n return false\n }\n\n if (isString(value)) {\n value = trim(value)\n\n // check to see if input value looks like a credit card number\n // see: https://www.safaribooksonline.com/library/view/regular-expressions-cookbook/9781449327453/ch04s20.html\n const ccRegex = anchorRegexes ? anchoredCCRegex : unanchoredCCRegex\n if (ccRegex.test((value || '').replace(/[- ]/g, ''))) {\n return false\n }\n\n // check to see if input value looks like a social security number\n const ssnRegex = anchorRegexes ? anchoredSSNRegex : unanchoredSSNRegex\n if (ssnRegex.test(value)) {\n return false\n }\n }\n\n return true\n}\n\n/*\n * Check whether an attribute name is an Angular style attr (either _ngcontent or _nghost)\n * These update on each build and lead to noise in the element chain\n * More details on the attributes here: https://angular.io/guide/view-encapsulation\n * @param {string} attributeName - string value to check\n * @returns {boolean} whether the element is an angular tag\n */\nexport function isAngularStyleAttr(attributeName: string): boolean {\n if (isString(attributeName)) {\n return attributeName.substring(0, 10) === '_ngcontent' || attributeName.substring(0, 7) === '_nghost'\n }\n return false\n}\n\n/*\n * Iterate through children of a target element looking for span tags\n * and return the text content of the span tags, separated by spaces,\n * along with the direct text content of the target element\n * @param {Element} target - element to check\n * @returns {string} text content of the target element and its child span tags\n */\nexport function getDirectAndNestedSpanText(target: Element): string {\n let text = getSafeText(target)\n text = `${text} ${getNestedSpanText(target)}`.trim()\n return shouldCaptureValue(text) ? text : ''\n}\n\n/*\n * Iterate through children of a target element looking for span tags\n * and return the text content of the span tags, separated by spaces\n * @param {Element} target - element to check\n * @returns {string} text content of span tags\n */\nexport function getNestedSpanText(target: Element): string {\n let text = ''\n if (target && target.childNodes && target.childNodes.length) {\n each(target.childNodes, function (child) {\n if (child && child.tagName?.toLowerCase() === 'span') {\n try {\n const spanText = getSafeText(child)\n text = `${text} ${spanText}`.trim()\n\n if (child.childNodes && child.childNodes.length) {\n text = `${text} ${getNestedSpanText(child)}`.trim()\n }\n } catch (e) {\n logger.error('[AutoCapture]', e)\n }\n }\n })\n }\n return text\n}\n\n/*\nBack in the day storing events in Postgres we use Elements for autocapture events.\nNow we're using elements_chain. We used to do this parsing/processing during ingestion.\nThis code is just copied over from ingestion, but we should optimize it\nto create elements_chain string directly.\n*/\nexport function getElementsChainString(elements: Properties[]): string {\n return elementsToString(extractElements(elements))\n}\n\n// This interface is called 'Element' in plugin-scaffold https://github.com/PostHog/plugin-scaffold/blob/b07d3b879796ecc7e22deb71bf627694ba05386b/src/types.ts#L200\n// However 'Element' is a DOM Element when run in the browser, so we have to rename it\ninterface PHElement {\n text?: string\n tag_name?: string\n href?: string\n attr_id?: string\n attr_class?: string[]\n nth_child?: number\n nth_of_type?: number\n attributes?: Record<string, any>\n event_id?: number\n order?: number\n group_id?: number\n}\n\nfunction escapeQuotes(input: string): string {\n return input.replace(/\"|\\\\\"/g, '\\\\\"')\n}\n\nfunction elementsToString(elements: PHElement[]): string {\n const ret = elements.map((element) => {\n let el_string = ''\n if (element.tag_name) {\n el_string += element.tag_name\n }\n if (element.attr_class) {\n element.attr_class.sort()\n for (const single_class of element.attr_class) {\n el_string += `.${single_class.replace(/\"/g, '')}`\n }\n }\n const attributes: Record<string, any> = {\n ...(element.text ? { text: element.text } : {}),\n 'nth-child': element.nth_child ?? 0,\n 'nth-of-type': element.nth_of_type ?? 0,\n ...(element.href ? { href: element.href } : {}),\n ...(element.attr_id ? { attr_id: element.attr_id } : {}),\n ...element.attributes,\n }\n const sortedAttributes: Record<string, any> = {}\n entries(attributes)\n .sort(([a], [b]) => a.localeCompare(b))\n .forEach(\n ([key, value]) => (sortedAttributes[escapeQuotes(key.toString())] = escapeQuotes(value.toString()))\n )\n el_string += ':'\n el_string += entries(sortedAttributes)\n .map(([key, value]) => `${key}=\"${value}\"`)\n .join('')\n return el_string\n })\n return ret.join(';')\n}\n\nfunction extractElements(elements: Properties[]): PHElement[] {\n return elements.map((el) => {\n const response = {\n text: el['$el_text']?.slice(0, 400),\n tag_name: el['tag_name'],\n href: el['attr__href']?.slice(0, 2048),\n attr_class: extractAttrClass(el),\n attr_id: el['attr__id'],\n nth_child: el['nth_child'],\n nth_of_type: el['nth_of_type'],\n attributes: {} as { [id: string]: any },\n }\n\n entries(el)\n .filter(([key]) => key.indexOf('attr__') === 0)\n .forEach(([key, value]) => (response.attributes[key] = value))\n return response\n })\n}\n\nfunction extractAttrClass(el: Properties): PHElement['attr_class'] {\n const attr_class = el['attr__class']\n if (!attr_class) {\n return undefined\n } else if (isArray(attr_class)) {\n return attr_class\n } else {\n return splitClassString(attr_class)\n }\n}\n","import { CapturedNetworkRequest, NetworkRecordOptions, PostHogConfig } from '../../../types'\nimport { isFunction, isNullish, isString, isUndefined } from '@posthog/core'\nimport { convertToURL } from '../../../utils/request-utils'\nimport { logger } from '../../../utils/logger'\nimport { shouldCaptureValue } from '../../../autocapture-utils'\nimport { each } from '../../../utils'\n\nconst LOGGER_PREFIX = '[SessionRecording]'\n\nconst REDACTED = 'redacted'\n\n// the hard ceiling for a recorded request/response body — 1MB, even if a larger limit is configured\nexport const MAX_PAYLOAD_SIZE_BYTES = 1000000\n\n// the smallest of the 1MB ceiling or the configured limit if there is one\nexport function effectivePayloadLimitBytes(options: Pick<NetworkRecordOptions, 'payloadSizeLimitBytes'>): number {\n return Math.min(MAX_PAYLOAD_SIZE_BYTES, options.payloadSizeLimitBytes ?? MAX_PAYLOAD_SIZE_BYTES)\n}\n\nexport const defaultNetworkOptions: Required<NetworkRecordOptions> = {\n initiatorTypes: [\n 'audio',\n 'beacon',\n 'body',\n 'css',\n 'early-hint',\n 'embed',\n 'fetch',\n 'frame',\n 'iframe',\n 'icon',\n 'image',\n 'img',\n 'input',\n 'link',\n 'navigation',\n 'object',\n 'ping',\n 'script',\n 'track',\n 'video',\n 'xmlhttprequest',\n ],\n maskRequestFn: (data: CapturedNetworkRequest) => data,\n recordHeaders: false,\n recordBody: false,\n recordInitialRequests: false,\n recordPerformance: false,\n performanceEntryTypeToObserve: [\n // 'event', // This is too noisy as it covers all browser events\n 'first-input',\n // 'mark', // Mark is used too liberally. We would need to filter for specific marks\n // 'measure', // Measure is used too liberally. We would need to filter for specific measures\n 'navigation',\n 'paint',\n 'resource',\n ],\n payloadSizeLimitBytes: MAX_PAYLOAD_SIZE_BYTES,\n payloadHostDenyList: [\n '.lr-ingest.io',\n '.ingest.sentry.io',\n '.clarity.ms',\n // NB no leading dot here\n // GA4/gtag beacons go to *.google-analytics.com; with Google Signals on they also hit\n // analytics.google.com (region1.analytics.google.com/g/collect), so deny both\n 'google-analytics.com',\n 'analytics.google.com',\n // New Relic browser agent (bam + bam-cell)\n 'nr-data.net',\n // Datadog browser RUM intake\n 'datadoghq.com',\n 'datadoghq.eu',\n 'ddog-gov.com',\n // other third-party analytics / session-replay vendors whose telemetry has no replay value\n 'segment.io',\n 'rudderstack.com',\n 'amplitude.com',\n 'mixpanel.com',\n // Hotjar uses both .com and .io for data collection\n 'hotjar.com',\n 'hotjar.io',\n 'fullstory.com',\n ],\n streamNetworkBody: false,\n}\n\nconst HEADER_DENY_LIST = [\n 'authorization',\n 'x-forwarded-for',\n 'authorization',\n 'cookie',\n 'set-cookie',\n 'x-api-key',\n 'x-real-ip',\n 'remote-addr',\n 'forwarded',\n 'proxy-authorization',\n 'x-csrf-token',\n 'x-csrftoken',\n 'x-xsrf-token',\n]\n\nconst PAYLOAD_CONTENT_DENY_LIST = [\n 'password',\n 'secret',\n 'passwd',\n 'api_key',\n 'apikey',\n 'auth',\n 'credentials',\n 'mysql_pwd',\n 'privatekey',\n 'private_key',\n 'token',\n]\n\n// substrings that mark a header as credential-bearing - catches custom names\n// (e.g. x-gist-encoded-user-token) that aren't in the exact deny list above\nconst HEADER_DENY_SUBSTRINGS = [\n 'auth',\n 'token',\n 'secret',\n 'session',\n 'api-key',\n 'apikey',\n 'api_key',\n 'credential',\n 'password',\n 'passwd',\n 'cookie',\n 'csrf',\n 'xsrf',\n]\n\nconst isDeniedHeader = (header: string): boolean => {\n const lower = header.toLowerCase()\n return HEADER_DENY_LIST.includes(lower) || HEADER_DENY_SUBSTRINGS.some((s) => lower.includes(s))\n}\n\nconst redactDeniedHeaders = (headers: CapturedNetworkRequest['requestHeaders']): void => {\n if (!isNullish(headers)) {\n each(Object.keys(headers), (header) => {\n if (isDeniedHeader(header)) {\n headers[header] = REDACTED\n }\n })\n }\n}\n\n// we always remove headers on the deny list because we never want to capture this sensitive data.\n// applies to both request and response headers (e.g. set-cookie is a response header)\nconst removeAuthorizationHeader = (data: CapturedNetworkRequest): CapturedNetworkRequest => {\n redactDeniedHeaders(data.requestHeaders)\n redactDeniedHeaders(data.responseHeaders)\n return data\n}\n\nconst POSTHOG_PATHS_TO_IGNORE = ['/s/', '/e/', '/i/']\n// want to ignore posthog paths when capturing requests, or we can get trapped in a loop\n// because calls to PostHog would be reported using a call to PostHog which would be reported....\nconst ignorePostHogPaths = (\n data: CapturedNetworkRequest,\n apiHostConfig: PostHogConfig['api_host']\n): CapturedNetworkRequest | undefined => {\n const url = convertToURL(data.name)\n\n // we need to account for api host config as e.g. pathname could be /ingest/s/ and we want to ignore that\n let replaceValue = apiHostConfig.indexOf('http') === 0 ? convertToURL(apiHostConfig)?.pathname : apiHostConfig\n if (replaceValue === '/') {\n replaceValue = ''\n }\n const pathname = url?.pathname.replace(replaceValue || '', '')\n\n if (url && pathname && POSTHOG_PATHS_TO_IGNORE.some((path) => pathname.indexOf(path) === 0)) {\n return undefined\n }\n return data\n}\n\nfunction estimateBytes(payload: string): number {\n return new Blob([payload]).size\n}\n\nfunction enforcePayloadSizeLimit(\n payload: string | null | undefined,\n headers: Record<string, any> | undefined,\n limit: number,\n description: string\n): string | null | undefined {\n if (isNullish(payload)) {\n return payload\n }\n\n let requestContentLength: string | number = headers?.['content-length'] || estimateBytes(payload)\n if (isString(requestContentLength)) {\n requestContentLength = parseInt(requestContentLength)\n }\n\n if (requestContentLength > limit) {\n return LOGGER_PREFIX + ` ${description} body too large to record (${requestContentLength} bytes)`\n }\n\n return payload\n}\n\n// people can have arbitrarily large payloads on their site, but we don't want to ingest them\nconst limitPayloadSize = (\n options: NetworkRecordOptions\n): ((data: CapturedNetworkRequest | undefined) => CapturedNetworkRequest | undefined) => {\n const limit = effectivePayloadLimitBytes(options)\n\n return (data) => {\n if (data?.requestBody) {\n data.requestBody = enforcePayloadSizeLimit(data.requestBody, data.requestHeaders, limit, 'Request')\n }\n\n if (data?.responseBody) {\n data.responseBody = enforcePayloadSizeLimit(data.responseBody, data.responseHeaders, limit, 'Response')\n }\n\n return data\n }\n}\n\nfunction scrubPayload(payload: string | null | undefined, label: 'Request' | 'Response'): string | null | undefined {\n if (isNullish(payload)) {\n return payload\n }\n let scrubbed = payload\n\n if (!shouldCaptureValue(scrubbed, false)) {\n scrubbed = LOGGER_PREFIX + ' ' + label + ' body ' + REDACTED\n }\n each(PAYLOAD_CONTENT_DENY_LIST, (text) => {\n if (scrubbed?.length && scrubbed?.indexOf(text) !== -1) {\n scrubbed = LOGGER_PREFIX + ' ' + label + ' body ' + REDACTED + ' as might contain: ' + text\n }\n })\n\n return scrubbed\n}\n\nfunction scrubPayloads(capturedRequest: CapturedNetworkRequest | undefined): CapturedNetworkRequest | undefined {\n if (isUndefined(capturedRequest)) {\n return undefined\n }\n\n capturedRequest.requestBody = scrubPayload(capturedRequest.requestBody, 'Request')\n capturedRequest.responseBody = scrubPayload(capturedRequest.responseBody, 'Response')\n\n return capturedRequest\n}\n\n/**\n * whether a maskRequestFn is provided or not,\n * we ensure that we remove the denied header from requests\n * we _never_ want to record that header by accident\n * if someone complains then we'll add an opt-in to let them override it\n */\nexport const buildNetworkRequestOptions = (\n instanceConfig: PostHogConfig,\n remoteNetworkOptions: Pick<\n NetworkRecordOptions,\n 'recordHeaders' | 'recordBody' | 'recordPerformance' | 'payloadHostDenyList'\n >\n): NetworkRecordOptions => {\n const config: NetworkRecordOptions = {\n payloadSizeLimitBytes: defaultNetworkOptions.payloadSizeLimitBytes,\n performanceEntryTypeToObserve: [...defaultNetworkOptions.performanceEntryTypeToObserve],\n payloadHostDenyList: [\n ...(remoteNetworkOptions.payloadHostDenyList || []),\n ...defaultNetworkOptions.payloadHostDenyList,\n ],\n }\n // client can always disable despite remote options\n const canRecordHeaders =\n instanceConfig.session_recording.recordHeaders === false ? false : remoteNetworkOptions.recordHeaders\n const canRecordBody =\n instanceConfig.session_recording.recordBody === false ? false : remoteNetworkOptions.recordBody\n const canRecordPerformance =\n instanceConfig.capture_performance === false ? false : remoteNetworkOptions.recordPerformance\n\n const payloadLimiter = limitPayloadSize(config)\n\n const enforcedCleaningFn: NetworkRecordOptions['maskRequestFn'] = (d: CapturedNetworkRequest) =>\n payloadLimiter(ignorePostHogPaths(removeAuthorizationHeader(d), instanceConfig.api_host))\n\n const hasDeprecatedMaskFunction = isFunction(instanceConfig.session_recording.maskNetworkRequestFn)\n\n if (hasDeprecatedMaskFunction && isFunction(instanceConfig.session_recording.maskCapturedNetworkRequestFn)) {\n logger.warn(\n 'Both `maskNetworkRequestFn` and `maskCapturedNetworkRequestFn` are defined. `maskNetworkRequestFn` will be ignored.'\n )\n }\n\n if (hasDeprecatedMaskFunction) {\n instanceConfig.session_recording.maskCapturedNetworkRequestFn = (data: CapturedNetworkRequest) => {\n const cleanedURL = instanceConfig.session_recording.maskNetworkRequestFn!({ url: data.name })\n return {\n ...data,\n name: cleanedURL?.url,\n } as CapturedNetworkRequest\n }\n }\n\n config.maskRequestFn = isFunction(instanceConfig.session_recording.maskCapturedNetworkRequestFn)\n ? (data) => {\n const cleanedRequest = enforcedCleaningFn(data)\n return cleanedRequest\n ? (instanceConfig.session_recording.maskCapturedNetworkRequestFn?.(cleanedRequest) ?? undefined)\n : undefined\n }\n : (data) => scrubPayloads(enforcedCleaningFn(data))\n\n return {\n ...defaultNetworkOptions,\n ...config,\n recordHeaders: canRecordHeaders,\n recordBody: canRecordBody,\n recordPerformance: canRecordPerformance,\n recordInitialRequests: canRecordPerformance,\n streamNetworkBody: instanceConfig.session_recording.streamNetworkBody === true,\n }\n}\n","// Portions of this file are derived from getsentry/sentry-javascript\n// Copyright (c) 2012 Functional Software, Inc. dba Sentry\n// Licensed under the MIT License: https://github.com/getsentry/sentry-javascript/blob/develop/LICENSE\n\n/// <reference lib=\"dom\" />\n\n// rrweb/network@1 code starts\n// most of what is below here will be removed when rrweb release their code for this\n// see https://github.com/rrweb-io/rrweb/pull/1105\n\n// NB adopted from https://github.com/rrweb-io/rrweb/pull/1105 which looks like it will be accepted into rrweb\n// however, in the PR, it throws when the performance observer data is not available\n// and assumes it is running in a browser with the Request API (i.e. not IE11)\n// copying here so that we can use it before rrweb adopt it\n\nimport type { IWindow, listenerHandler, RecordPlugin } from '../types/rrweb-types'\nimport { CapturedNetworkRequest, Headers, InitiatorType, NetworkRecordOptions } from '../../../types'\nimport {\n isArray,\n isBoolean,\n isFormData,\n isFunction,\n isNull,\n isNullish,\n isString,\n isUndefined,\n isObject,\n} from '@posthog/core'\nimport { isDocument } from '../../../utils/type-utils'\nimport { createLogger } from '../../../utils/logger'\nimport { formDataToQuery } from '../../../utils/request-utils'\nimport { patch } from '../rrweb-plugins/patch'\nimport { isHostOnDenyList } from '../../../extensions/replay/external/denylist'\nimport { defaultNetworkOptions, effectivePayloadLimitBytes } from './config'\n\nconst logger = createLogger('[Recorder]')\n\nexport type NetworkData = {\n requests: CapturedNetworkRequest[]\n isInitial?: boolean\n}\n\ntype networkCallback = (data: NetworkData) => void\n\nconst isNavigationTiming = (entry: PerformanceEntry): entry is PerformanceNavigationTiming =>\n entry.entryType === 'navigation'\nconst isResourceTiming = (entry: PerformanceEntry): entry is PerformanceResourceTiming => entry.entryType === 'resource'\n\ntype ObservedPerformanceEntry = (PerformanceNavigationTiming | PerformanceResourceTiming) & {\n responseStatus?: number\n}\n\nexport function findLast<T>(array: Array<T>, predicate: (value: T) => boolean): T | undefined {\n const length = array.length\n for (let i = length - 1; i >= 0; i -= 1) {\n if (predicate(array[i])) {\n return array[i]\n }\n }\n return undefined\n}\n\nfunction initPerformanceObserver(cb: networkCallback, win: IWindow, options: Required<NetworkRecordOptions>) {\n // if we are only observing timings then we could have a single observer for all types, with buffer true,\n // but we are going to filter by initiatorType _if we are wrapping fetch and xhr as the wrapped functions\n // will deal with those.\n // so we have a block which captures requests from before fetch/xhr is wrapped\n // these are marked `isInitial` so playback can display them differently if needed\n // they will never have method/status/headers/body because they are pre-wrapping that provides that\n if (options.recordInitialRequests) {\n const initialPerformanceEntries = win.performance\n .getEntries()\n .filter(\n (entry): entry is ObservedPerformanceEntry =>\n isNavigationTiming(entry) ||\n (isResourceTiming(entry) && options.initiatorTypes.includes(entry.initiatorType as InitiatorType))\n )\n cb({\n requests: initialPerformanceEntries.flatMap((entry) =>\n prepareRequest({ entry, method: undefined, status: undefined, networkRequest: {}, isInitial: true })\n ),\n isInitial: true,\n })\n }\n const observer = new win.PerformanceObserver((entries) => {\n // if recordBody or recordHeaders is true then we don't want to record fetch or xhr here\n // as the wrapped functions will do that. Otherwise, this filter becomes a noop\n // because we do want to record them here\n const wrappedInitiatorFilter = (entry: ObservedPerformanceEntry) =>\n options.recordBody || options.recordHeaders\n ? entry.initiatorType !== 'xmlhttprequest' && entry.initiatorType !== 'fetch'\n : true\n\n const performanceEntries = entries.getEntries().filter(\n (entry): entry is ObservedPerformanceEntry =>\n isNavigationTiming(entry) ||\n (isResourceTiming(entry) &&\n options.initiatorTypes.includes(entry.initiatorType as InitiatorType) &&\n // TODO if we are _only_ capturing timing we don't want to filter initiator here\n wrappedInitiatorFilter(entry))\n )\n\n cb({\n requests: performanceEntries.flatMap((entry) =>\n prepareRequest({ entry, method: undefined, status: undefined, networkRequest: {} })\n ),\n })\n })\n // compat checked earlier\n // eslint-disable-next-line compat/compat\n const entryTypes = PerformanceObserver.supportedEntryTypes.filter((x) =>\n options.performanceEntryTypeToObserve.includes(x)\n )\n // initial records are gathered above, so we don't need to observe and buffer each type separately\n observer.observe({ entryTypes })\n return () => {\n observer.disconnect()\n }\n}\n\nfunction shouldRecordHeaders(type: 'request' | 'response', recordHeaders: NetworkRecordOptions['recordHeaders']) {\n return !!recordHeaders && (isBoolean(recordHeaders) || recordHeaders[type])\n}\n\nfunction isRequest(value: unknown): value is Request {\n if (typeof Request === 'undefined') {\n return false\n }\n if (value instanceof Request) {\n return true\n }\n try {\n return Object.prototype.toString.call(value) === '[object Request]'\n } catch {\n return false\n }\n}\n\n// binary/asset bodies are large and useless for replay debugging (and capturing an image body\n// duplicates what the recording already shows), so we never record them even when recordBody is on\nexport const NEVER_RECORD_BODY_CONTENT_TYPES = [\n 'image/',\n 'video/',\n 'audio/',\n 'font/',\n 'application/octet-stream',\n 'application/pdf',\n 'application/zip',\n 'application/wasm',\n]\n\nexport function shouldRecordBody({\n type,\n recordBody,\n headers,\n url,\n}: {\n type: 'request' | 'response'\n headers: Headers\n url: string | URL | RequestInfo\n recordBody: NetworkRecordOptions['recordBody']\n}) {\n function matchesContentType(contentTypes: string[]) {\n const contentTypeHeader = Object.keys(headers).find((key) => key.toLowerCase() === 'content-type')\n const contentType = contentTypeHeader && headers[contentTypeHeader]\n return contentTypes.some((ct) => contentType?.toLowerCase().includes(ct))\n }\n\n /**\n * particularly in canvas applications we see many requests to blob URLs\n * e.g. blob:https://video_url\n * these blob/object URLs are local to the browser, we can never capture that body\n * so we can just return false here\n */\n function isBlobURL(url: string | URL | RequestInfo) {\n try {\n if (typeof url === 'string') {\n return url.startsWith('blob:')\n }\n if (url instanceof URL) {\n return url.protocol === 'blob:'\n }\n if (isRequest(url)) {\n return isBlobURL(url.url)\n }\n return false\n } catch {\n return false\n }\n }\n if (!recordBody) return false\n if (isBlobURL(url)) return false\n // never record binary/asset bodies, regardless of the recordBody setting\n if (matchesContentType(NEVER_RECORD_BODY_CONTENT_TYPES)) return false\n if (isBoolean(recordBody)) return true\n if (isArray(recordBody)) return matchesContentType(recordBody)\n const recordBodyType = recordBody[type]\n if (isBoolean(recordBodyType)) return recordBodyType\n return matchesContentType(recordBodyType)\n}\n\nasync function getRequestPerformanceEntry(\n win: IWindow,\n initiatorType: string,\n url: string,\n start?: number,\n end?: number,\n attempt = 0\n): Promise<PerformanceResourceTiming | null> {\n if (attempt > 10) {\n logger.warn('Failed to get performance entry for request', { url, initiatorType })\n return null\n }\n const urlPerformanceEntries = win.performance.getEntriesByName(url) as PerformanceResourceTiming[]\n const performanceEntry = findLast(\n urlPerformanceEntries,\n (entry) =>\n isResourceTiming(entry) &&\n entry.initiatorType === initiatorType &&\n (isUndefined(start) || entry.startTime >= start) &&\n (isUndefined(end) || entry.startTime <= end)\n )\n if (!performanceEntry) {\n await new Promise((resolve) => setTimeout(resolve, 50 * attempt))\n return getRequestPerformanceEntry(win, initiatorType, url, start, end, attempt + 1)\n }\n return performanceEntry\n}\n\n/**\n * According to MDN https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/response\n * xhr response is typed as any but can be an ArrayBuffer, a Blob, a Document, a JavaScript object,\n * or a string, depending on the value of XMLHttpRequest.responseType, that contains the response entity body.\n *\n * XHR request body is Document | XMLHttpRequestBodyInit | null | undefined\n */\nfunction _tryReadXHRBody({\n body,\n options,\n url,\n}: {\n body: Document | XMLHttpRequestBodyInit | any | null | undefined\n options: NetworkRecordOptions\n url: string | URL | RequestInfo\n}): string | null {\n if (isNullish(body)) {\n return null\n }\n\n const { hostname, isHostDenied } = isHostOnDenyList(url, options)\n if (isHostDenied) {\n return hostname + ' is in deny list'\n }\n\n if (isString(body)) {\n return body\n }\n\n if (isDocument(body)) {\n return body.textContent\n }\n\n if (isFormData(body)) {\n return formDataToQuery(body)\n }\n\n if (isObject(body)) {\n try {\n return JSON.stringify(body)\n } catch {\n return '[SessionReplay] Failed to stringify response object'\n }\n }\n\n return '[SessionReplay] Cannot read body of type ' + toString.call(body)\n}\n\nfunction initXhrObserver(cb: networkCallback, win: IWindow, options: Required<NetworkRecordOptions>): listenerHandler {\n if (!options.initiatorTypes.includes('xmlhttprequest')) {\n return () => {\n //\n }\n }\n const recordRequestHeaders = shouldRecordHeaders('request', options.recordHeaders)\n const recordResponseHeaders = shouldRecordHeaders('response', options.recordHeaders)\n\n const restorePatch = patch(\n win.XMLHttpRequest.prototype,\n 'open',\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n (originalOpen: typeof XMLHttpRequest.prototype.open) => {\n return function (\n method: string,\n url: string | URL,\n async = true,\n username?: string | null,\n password?: string | null\n ) {\n // because this function is returned in its actual context `this` _is_ an XMLHttpRequest\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n const xhr = this as XMLHttpRequest\n\n // check IE earlier than this, we only initialize if Request is present\n // eslint-disable-next-line compat/compat\n const req = new Request(url)\n const networkRequest: Partial<CapturedNetworkRequest> = {}\n let start: number | undefined\n let end: number | undefined\n\n const requestHeaders: Headers = {}\n const originalSetRequestHeader = xhr.setRequestHeader.bind(xhr)\n xhr.setRequestHeader = (header: string, value: string) => {\n requestHeaders[header] = value\n return originalSetRequestHeader(header, value)\n }\n if (recordRequestHeaders) {\n networkRequest.requestHeaders = requestHeaders\n }\n\n const originalSend = xhr.send.bind(xhr)\n xhr.send = (body) => {\n if (\n shouldRecordBody({\n type: 'request',\n headers: requestHeaders,\n url,\n recordBody: options.recordBody,\n })\n ) {\n networkRequest.requestBody = _tryReadXHRBody({ body, options, url })\n }\n start = win.performance.now()\n return originalSend(body)\n }\n\n // Cleanup function to remove all event listeners and prevent memory leaks\n const cleanup = () => {\n xhr.removeEventListener('readystatechange', readyStateListener)\n xhr.removeEventListener('error', cleanup)\n xhr.removeEventListener('abort', cleanup)\n xhr.removeEventListener('timeout', cleanup)\n }\n\n const readyStateListener = () => {\n if (xhr.readyState !== xhr.DONE) {\n return\n }\n\n // Clean up all listeners immediately when done to prevent memory leaks\n cleanup()\n\n end = win.performance.now()\n const responseHeaders: Headers = {}\n const rawHeaders = xhr.getAllResponseHeaders()\n const headers = rawHeaders.trim().split(/[\\r\\n]+/)\n headers.forEach((line) => {\n const parts = line.split(': ')\n const header = parts.shift()\n const value = parts.join(': ')\n if (header) {\n responseHeaders[header] = value\n }\n })\n if (recordResponseHeaders) {\n networkRequest.responseHeaders = responseHeaders\n }\n if (\n shouldRecordBody({\n type: 'response',\n headers: responseHeaders,\n url,\n recordBody: options.recordBody,\n })\n ) {\n networkRequest.responseBody = _tryReadXHRBody({ body: xhr.response, options, url })\n }\n getRequestPerformanceEntry(win, 'xmlhttprequest', req.url, start, end)\n .then((entry) => {\n const requests = prepareRequest({\n entry,\n method: method,\n status: xhr?.status,\n networkRequest,\n start,\n end,\n url: url.toString(),\n initiatorType: 'xmlhttprequest',\n })\n cb({ requests })\n })\n .catch(() => {\n //\n })\n }\n\n // This is very tricky code, and making it passive won't bring many performance benefits,\n // so let's ignore the rule here.\n // eslint-disable-next-line posthog-js/no-add-event-listener\n xhr.addEventListener('readystatechange', readyStateListener)\n // Also clean up on error, abort, and timeout to prevent memory leaks\n // eslint-disable-next-line posthog-js/no-add-event-listener\n xhr.addEventListener('error', cleanup)\n // eslint-disable-next-line posthog-js/no-add-event-listener\n xhr.addEventListener('abort', cleanup)\n // eslint-disable-next-line posthog-js/no-add-event-listener\n xhr.addEventListener('timeout', cleanup)\n\n originalOpen.call(xhr, method, url.toString(), async, username, password)\n }\n }\n )\n return () => {\n restorePatch()\n }\n}\n\n/**\n * Check if this PerformanceEntry is either a PerformanceResourceTiming or a PerformanceNavigationTiming\n * NB PerformanceNavigationTiming extends PerformanceResourceTiming\n * Here we don't care which interface it implements as both expose `serverTimings`\n */\nconst exposesServerTiming = (event: PerformanceEntry | null): event is PerformanceResourceTiming =>\n !isNull(event) && (event.entryType === 'navigation' || event.entryType === 'resource')\n\nfunction prepareRequest({\n entry,\n method,\n status,\n networkRequest,\n isInitial,\n start,\n end,\n url,\n initiatorType,\n}: {\n entry: PerformanceResourceTiming | null\n method: string | undefined\n status: number | undefined\n networkRequest: Partial<CapturedNetworkRequest>\n isInitial?: boolean\n start?: number\n end?: number\n // if there is no performance observer entry, we still need to know the url\n url?: string\n // if there is no performance observer entry, we can provide the initiatorType\n initiatorType?: string\n}): CapturedNetworkRequest[] {\n start = entry ? entry.startTime : start\n end = entry ? entry.responseEnd : end\n\n // kudos to sentry javascript sdk for excellent background on why to use Date.now() here\n // https://github.com/getsentry/sentry-javascript/blob/e856e40b6e71a73252e788cd42b5260f81c9c88e/packages/utils/src/time.ts#L70\n // can't start observer if performance.now() is not available\n // eslint-disable-next-line compat/compat\n const timeOrigin = Math.floor(Date.now() - performance.now())\n // clickhouse can't ingest timestamps that are floats\n // (in this case representing fractions of a millisecond we don't care about anyway)\n // use timeOrigin if we really can't gather a start time\n const timestamp = Math.floor(timeOrigin + (start || 0))\n\n const entryJSON = entry ? entry.toJSON() : { name: url }\n\n const requests: CapturedNetworkRequest[] = [\n {\n ...entryJSON,\n startTime: isUndefined(start) ? undefined : Math.round(start),\n endTime: isUndefined(end) ? undefined : Math.round(end),\n timeOrigin,\n timestamp,\n method: method,\n initiatorType: initiatorType ? initiatorType : entry ? (entry.initiatorType as InitiatorType) : undefined,\n status,\n requestHeaders: networkRequest.requestHeaders,\n requestBody: networkRequest.requestBody,\n responseHeaders: networkRequest.responseHeaders,\n responseBody: networkRequest.responseBody,\n isInitial,\n },\n ]\n\n if (exposesServerTiming(entry)) {\n for (const timing of entry.serverTiming || []) {\n requests.push({\n timeOrigin,\n timestamp,\n startTime: Math.round(entry.startTime),\n name: timing.name,\n duration: timing.duration,\n // the spec has a closed list of possible types\n // https://developer.mozilla.org/en-US/docs/Web/API/PerformanceEntry/entryType\n // but, we need to know this was a server timing so that we know to\n // match it to the appropriate navigation or resource timing\n // that matching will have to be on timestamp and $current_url\n entryType: 'serverTiming',\n })\n }\n }\n\n return requests\n}\n\nconst contentTypePrefixDenyList = ['video/', 'audio/']\n\nfunction _checkForCannotReadResponseBody({\n r,\n options,\n url,\n}: {\n r: Response\n options: NetworkRecordOptions\n url: string | URL | RequestInfo\n}): string | null {\n if (r.headers.get('Transfer-Encoding') === 'chunked') {\n return 'Chunked Transfer-Encoding is not supported'\n }\n\n // `get` and `has` are case-insensitive\n // but return the header value with the casing that was supplied\n const contentType = r.headers.get('Content-Type')?.toLowerCase()\n const contentTypeIsDenied = contentTypePrefixDenyList.some((prefix) => contentType?.startsWith(prefix))\n if (contentType && contentTypeIsDenied) {\n return `Content-Type ${contentType} is not supported`\n }\n\n const { hostname, isHostDenied } = isHostOnDenyList(url, options)\n if (isHostDenied) {\n return hostname + ' is in deny list'\n }\n\n return null\n}\n\nfunction isReadableStreamBody(body: unknown): body is ReadableStream<Uint8Array> {\n return isObject(body) && isFunction(body.getReader) && isFunction(body.tee)\n}\n\n// reading a body must never hold up the page's request for long, so we cap every read attempt\nconst BODY_READ_TIMEOUT_MS = 500\nconst BODY_READ_TIMEOUT_MESSAGE = '[SessionReplay] Timeout while trying to read body'\nconst BODY_READ_FAILED_MESSAGE = '[SessionReplay] Failed to read body'\n\nfunction bodyReadFailedMessage(reason: unknown): string {\n return `${BODY_READ_FAILED_MESSAGE}: ${reason}`\n}\n\nfunction bodyTooLargeMessage(limitBytes: number): string {\n return `[SessionReplay] Body too large to record (> ${limitBytes} bytes)`\n}\n\n// when the body declares a content-length over the limit we can skip reading it entirely.\n// this trusts content-length the same way config.ts enforcePayloadSizeLimit does.\n// known accepted risk: for a compressed response content-length is the compressed size while the\n// streaming reader counts decoded bytes, so a body that is over the limit compressed but under it\n// decoded is dropped to the placeholder rather than recorded. it never breaks the page, so we accept it.\nexport function _contentLengthExceedsLimit(r: Request | Response, limitBytes: number): boolean {\n try {\n const headerValue = r.headers?.get?.('content-length')\n if (!headerValue) {\n return false\n }\n const contentLength = parseInt(headerValue, 10)\n return Number.isFinite(contentLength) && contentLength > limitBytes\n } catch {\n return false\n }\n}\n\nexport function _readBody(r: Request | Response, options: NetworkRecordOptions): Promise<string> {\n if (!options.streamNetworkBody) {\n return _tryReadBody(r)\n }\n const limitBytes = effectivePayloadLimitBytes(options)\n // skip the read for bodies the headers already tell us are over the limit\n if (_contentLengthExceedsLimit(r, limitBytes)) {\n return Promise.resolve(bodyTooLargeMessage(limitBytes))\n }\n return _tryReadBodyStreaming(r, limitBytes)\n}\n\nfunction _tryReadBody(r: Request | Response): Promise<string> {\n // there are now already multiple places where we're using Promise...\n // eslint-disable-next-line compat/compat\n return new Promise((resolve) => {\n const timeout = setTimeout(() => resolve(BODY_READ_TIMEOUT_MESSAGE), BODY_READ_TIMEOUT_MS)\n try {\n r.clone()\n .text()\n .then(\n (txt) => resolve(txt),\n (reason) => resolve(bodyReadFailedMessage(reason))\n )\n .finally(() => clearTimeout(timeout))\n } catch {\n clearTimeout(timeout)\n resolve(BODY_READ_FAILED_MESSAGE)\n }\n })\n}\n\nfunction concatChunks(chunks: Uint8Array[], totalBytes: number): Uint8Array {\n const merged = new Uint8Array(totalBytes)\n let offset = 0\n for (const chunk of chunks) {\n merged.set(chunk, offset)\n offset += chunk.byteLength\n }\n return merged\n}\n\n// Reads a clone of the body chunk by chunk, stopping as soon as the running total exceeds the\n// limit, so a very large body is never fully buffered. Like _tryReadBody it only ever reads a\n// clone (never the stream the page consumes) and is guaranteed to resolve, never reject.\nexport function _tryReadBodyStreaming(r: Request | Response, limitBytes: number): Promise<string> {\n // eslint-disable-next-line compat/compat\n return new Promise((resolve) => {\n let settled = false\n let reader: ReadableStreamDefaultReader<Uint8Array> | undefined\n\n function cancel(): void {\n try {\n void reader?.cancel()\n } catch {\n // the reader may already be released; nothing to clean up\n }\n }\n\n // resolving always releases the reader, so a slow/hung stream stops being pulled (and stops\n // buffering the clone) the moment we settle — whether via success, the cap, an error, or the timeout\n function done(value: string): void {\n if (settled) {\n return\n }\n settled = true\n clearTimeout(timeout)\n cancel()\n resolve(value)\n }\n\n const timeout = setTimeout(() => done(BODY_READ_TIMEOUT_MESSAGE), BODY_READ_TIMEOUT_MS)\n\n let clone: Request | Response\n try {\n clone = r.clone()\n } catch {\n done(BODY_READ_FAILED_MESSAGE)\n return\n }\n\n const body = clone.body\n // no readable stream (or no TextDecoder) available — fall back to the buffered read of the clone\n if (!isReadableStreamBody(body) || typeof TextDecoder === 'undefined') {\n try {\n clone.text().then(\n (txt) => done(txt),\n (reason) => done(bodyReadFailedMessage(reason))\n )\n } catch {\n done(BODY_READ_FAILED_MESSAGE)\n }\n return\n }\n\n try {\n reader = body.getReader()\n } catch {\n done(BODY_READ_FAILED_MESSAGE)\n return\n }\n\n const chunks: Uint8Array[] = []\n let received = 0\n\n function pump(): void {\n reader!.read().then(\n ({ done: streamDone, value }) => {\n // already resolved (e.g. the timeout fired) — stop reading and release the stream\n if (settled) {\n cancel()\n return\n }\n\n if (streamDone) {\n done(new TextDecoder().decode(concatChunks(chunks, received)))\n return\n }\n\n if (value) {\n if (received + value.byteLength > limitBytes) {\n done(bodyTooLargeMessage(limitBytes))\n return\n }\n received += value.byteLength\n chunks.push(value)\n }\n\n pump()\n },\n (reason) => done(bodyReadFailedMessage(reason))\n )\n }\n\n pump()\n })\n}\n\nasync function _tryReadRequestBody({\n r,\n options,\n url,\n}: {\n r: Request\n options: NetworkRecordOptions\n url: string | URL | RequestInfo\n}): Promise<string> {\n const { hostname, isHostDenied } = isHostOnDenyList(url, options)\n if (isHostDenied) {\n return Promise.resolve(hostname + ' is in deny list')\n }\n\n return _readBody(r, options)\n}\n\nasync function _tryReadResponseBody({\n r,\n options,\n url,\n}: {\n r: Response\n options: NetworkRecordOptions\n url: string | URL | RequestInfo\n}): Promise<string> {\n const cannotReadBodyReason: string | null = _checkForCannotReadResponseBody({ r, options, url })\n if (!isNull(cannotReadBodyReason)) {\n return Promise.resolve(cannotReadBodyReason)\n }\n\n return _readBody(r, options)\n}\n\nfunction initFetchObserver(\n cb: networkCallback,\n win: IWindow,\n options: Required<NetworkRecordOptions>\n): listenerHandler {\n if (!options.initiatorTypes.includes('fetch')) {\n return () => {\n //\n }\n }\n const recordRequestHeaders = shouldRecordHeaders('request', options.recordHeaders)\n const recordResponseHeaders = shouldRecordHeaders('response', options.recordHeaders)\n\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n const restorePatch = patch(win, 'fetch', (originalFetch: typeof fetch) => {\n return async function (url: URL | RequestInfo, init?: RequestInit | undefined) {\n // check IE earlier than this, we only initialize if Request is present\n // eslint-disable-next-line compat/compat\n const req = new Request(url, init)\n let res: Response | undefined\n const networkRequest: Partial<CapturedNetworkRequest> = {}\n let start: number | undefined\n let end: number | undefined\n\n try {\n const requestHeaders: Headers = {}\n req.headers.forEach((value: string, header: string | number) => {\n requestHeaders[header] = value\n })\n if (recordRequestHeaders) {\n networkRequest.requestHeaders = requestHeaders\n }\n // Check the caller-supplied body, not req.body: Request normalizes all non-null bodies\n // to a ReadableStream, but only an original ReadableStream would be locked by req.clone().text().\n const requestBodyIsReadableStream = isReadableStreamBody(init?.body)\n if (\n !requestBodyIsReadableStream &&\n shouldRecordBody({\n type: 'request',\n headers: requestHeaders,\n url,\n recordBody: options.recordBody,\n })\n ) {\n networkRequest.requestBody = await _tryReadRequestBody({ r: req, options, url })\n }\n\n start = win.performance.now()\n // Use `req` for recording metadata/body only. For fetch(url, init), do not pass this internally-created\n // Request downstream: it exposes request.body as a ReadableStream, and wrappers that forward that body\n // can trigger Safari's \"ReadableStream uploading is not supported\" error. For fetch(Request), we must\n // pass the cloned Request because constructing `req` may consume the original Request body.\n res = isRequest(url) ? await originalFetch(req) : await originalFetch(url, init)\n end = win.performance.now()\n\n const responseHeaders: Headers = {}\n res.headers.forEach((value: string, header: string | number) => {\n responseHeaders[header] = value\n })\n if (recordResponseHeaders) {\n networkRequest.responseHeaders = responseHeaders\n }\n if (\n shouldRecordBody({\n type: 'response',\n headers: responseHeaders,\n url,\n recordBody: options.recordBody,\n })\n ) {\n networkRequest.responseBody = await _tryReadResponseBody({ r: res, options, url })\n }\n\n return res\n } finally {\n getRequestPerformanceEntry(win, 'fetch', req.url, start, end)\n .then((entry) => {\n const requests = prepareRequest({\n entry,\n method: req.method,\n status: res?.status,\n networkRequest,\n start,\n end,\n url: req.url,\n initiatorType: 'fetch',\n })\n cb({ requests })\n })\n .catch(() => {\n //\n })\n }\n }\n })\n return () => {\n restorePatch()\n }\n}\n\nlet initialisedHandler: listenerHandler | null = null\n\nfunction initNetworkObserver(\n callback: networkCallback,\n win: IWindow, // top window or in an iframe\n options: NetworkRecordOptions\n): listenerHandler {\n if (!('performance' in win)) {\n return () => {\n //\n }\n }\n\n if (initialisedHandler) {\n logger.warn('Network observer already initialised, doing nothing')\n return () => {\n // the first caller should already have this handler and will be responsible for teardown\n }\n }\n\n const networkOptions = (\n options ? Object.assign({}, defaultNetworkOptions, options) : defaultNetworkOptions\n ) as Required<NetworkRecordOptions>\n\n const cb: networkCallback = (data) => {\n const requests: CapturedNetworkRequest[] = []\n data.requests.forEach((request) => {\n const maskedRequest = networkOptions.maskRequestFn(request)\n if (maskedRequest) {\n requests.push(maskedRequest)\n }\n })\n\n if (requests.length > 0) {\n callback({ ...data, requests })\n }\n }\n const performanceObserver = initPerformanceObserver(cb, win, networkOptions)\n\n // only wrap fetch and xhr if headers or body are being recorded\n let xhrObserver: listenerHandler = () => {}\n let fetchObserver: listenerHandler = () => {}\n if (networkOptions.recordHeaders || networkOptions.recordBody) {\n xhrObserver = initXhrObserver(cb, win, networkOptions)\n fetchObserver = initFetchObserver(cb, win, networkOptions)\n }\n\n initialisedHandler = () => {\n performanceObserver()\n xhrObserver()\n fetchObserver()\n initialisedHandler = null\n }\n return initialisedHandler\n}\n\n// use the plugin name so that when this functionality is adopted into rrweb\n// we can remove this plugin and use the core functionality with the same data\nexport const NETWORK_PLUGIN_NAME = 'rrweb/network@1'\n\n// TODO how should this be typed?\n// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-ignore\nexport const getRecordNetworkPlugin: (options?: NetworkRecordOptions) => RecordPlugin = (options) => {\n return {\n name: NETWORK_PLUGIN_NAME,\n observer: initNetworkObserver,\n options: options,\n }\n}\n\n// rrweb/networ@1 ends\n","// This file is kept only for backwards compatibility.\n// In almost every case, if you are manually importing a file you should use posthog-recorder instead.\n\nimport { record as rrwebRecord, wasMaxDepthReached, resetMaxDepthState } from '@posthog/rrweb-record'\nimport { getRecordConsolePlugin } from '@posthog/rrweb-plugin-console-record'\nimport { getRecordNetworkPlugin } from '../extensions/replay/external/network-plugin'\nimport { assignableWindow } from '../utils/globals'\n\nassignableWindow.__PosthogExtensions__ = assignableWindow.__PosthogExtensions__ || {}\nassignableWindow.__PosthogExtensions__.rrwebPlugins = { getRecordConsolePlugin, getRecordNetworkPlugin }\nassignableWindow.__PosthogExtensions__.rrweb = {\n record: rrwebRecord,\n version: 'v2',\n wasMaxDepthReached,\n resetMaxDepthState,\n}\n\n// we used to put all of these items directly on window, and now we put it on __PosthogExtensions__\n// but that means that old clients which lazily load this extension are looking in the wrong place\n// yuck,\n// so we also put them directly on the window\n// when 1.161.1 is the oldest version seen in production we can remove this\nassignableWindow.rrweb = { record: rrwebRecord, version: 'v2' }\nassignableWindow.rrwebConsoleRecord = { getRecordConsolePlugin }\nassignableWindow.getRecordNetworkPlugin = getRecordNetworkPlugin\n\nexport default rrwebRecord\n","var n,l,u,t,i,r,o,e,f,c,a,s,h,p,v,y,d={},w=[],_=/acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i,g=Array.isArray;function m(n,l){for(var u in l)n[u]=l[u];return n}function b(n){n&&n.parentNode&&n.parentNode.removeChild(n)}function k(l,u,t){var i,r,o,e={};for(o in u)\"key\"==o?i=u[o]:\"ref\"==o?r=u[o]:e[o]=u[o];if(arguments.length>2&&(e.children=arguments.length>3?n.call(arguments,2):t),\"function\"==typeof l&&null!=l.defaultProps)for(o in l.defaultProps)void 0===e[o]&&(e[o]=l.defaultProps[o]);return x(l,e,i,r,null)}function x(n,t,i,r,o){var e={type:n,props:t,key:i,ref:r,__k:null,__:null,__b:0,__e:null,__c:null,constructor:void 0,__v:null==o?++u:o,__i:-1,__u:0};return null==o&&null!=l.vnode&&l.vnode(e),e}function M(){return{current:null}}function S(n){return n.children}function C(n,l){this.props=n,this.context=l}function $(n,l){if(null==l)return n.__?$(n.__,n.__i+1):null;for(var u;l<n.__k.length;l++)if(null!=(u=n.__k[l])&&null!=u.__e)return u.__e;return\"function\"==typeof n.type?$(n):null}function I(n){if(n.__P&&n.__d){var u=n.__v,t=u.__e,i=[],r=[],o=m({},u);o.__v=u.__v+1,l.vnode&&l.vnode(o),q(n.__P,o,u,n.__n,n.__P.namespaceURI,32&u.__u?[t]:null,i,null==t?$(u):t,!!(32&u.__u),r),o.__v=u.__v,o.__.__k[o.__i]=o,D(i,o,r),u.__e=u.__=null,o.__e!=t&&P(o)}}function P(n){if(null!=(n=n.__)&&null!=n.__c)return n.__e=n.__c.base=null,n.__k.some(function(l){if(null!=l&&null!=l.__e)return n.__e=n.__c.base=l.__e}),P(n)}function A(n){(!n.__d&&(n.__d=!0)&&i.push(n)&&!H.__r++||r!=l.debounceRendering)&&((r=l.debounceRendering)||o)(H)}function H(){try{for(var n,l=1;i.length;)i.length>l&&i.sort(e),n=i.shift(),l=i.length,I(n)}finally{i.length=H.__r=0}}function L(n,l,u,t,i,r,o,e,f,c,a){var s,h,p,v,y,_,g,m=t&&t.__k||w,b=l.length;for(f=T(u,l,m,f,b),s=0;s<b;s++)null!=(p=u.__k[s])&&(h=-1!=p.__i&&m[p.__i]||d,p.__i=s,_=q(n,p,h,i,r,o,e,f,c,a),v=p.__e,p.ref&&h.ref!=p.ref&&(h.ref&&J(h.ref,null,p),a.push(p.ref,p.__c||v,p)),null==y&&null!=v&&(y=v),(g=!!(4&p.__u))||h.__k===p.__k?(f=j(p,f,n,g),g&&h.__e&&(h.__e=null)):\"function\"==typeof p.type&&void 0!==_?f=_:v&&(f=v.nextSibling),p.__u&=-7);return u.__e=y,f}function T(n,l,u,t,i){var r,o,e,f,c,a=u.length,s=a,h=0;for(n.__k=new Array(i),r=0;r<i;r++)null!=(o=l[r])&&\"boolean\"!=typeof o&&\"function\"!=typeof o?(\"string\"==typeof o||\"number\"==typeof o||\"bigint\"==typeof o||o.constructor==String?o=n.__k[r]=x(null,o,null,null,null):g(o)?o=n.__k[r]=x(S,{children:o},null,null,null):void 0===o.constructor&&o.__b>0?o=n.__k[r]=x(o.type,o.props,o.key,o.ref?o.ref:null,o.__v):n.__k[r]=o,f=r+h,o.__=n,o.__b=n.__b+1,e=null,-1!=(c=o.__i=O(o,u,f,s))&&(s--,(e=u[c])&&(e.__u|=2)),null==e||null==e.__v?(-1==c&&(i>a?h--:i<a&&h++),\"function\"!=typeof o.type&&(o.__u|=4)):c!=f&&(c==f-1?h--:c==f+1?h++:(c>f?h--:h++,o.__u|=4))):n.__k[r]=null;if(s)for(r=0;r<a;r++)null!=(e=u[r])&&0==(2&e.__u)&&(e.__e==t&&(t=$(e)),K(e,e));return t}function j(n,l,u,t){var i,r;if(\"function\"==typeof n.type){for(i=n.__k,r=0;i&&r<i.length;r++)i[r]&&(i[r].__=n,l=j(i[r],l,u,t));return l}n.__e!=l&&(t&&(l&&n.type&&!l.parentNode&&(l=$(n)),u.insertBefore(n.__e,l||null)),l=n.__e);do{l=l&&l.nextSibling}while(null!=l&&8==l.nodeType);return l}function F(n,l){return l=l||[],null==n||\"boolean\"==typeof n||(g(n)?n.some(function(n){F(n,l)}):l.push(n)),l}function O(n,l,u,t){var i,r,o,e=n.key,f=n.type,c=l[u],a=null!=c&&0==(2&c.__u);if(null===c&&null==e||a&&e==c.key&&f==c.type)return u;if(t>(a?1:0))for(i=u-1,r=u+1;i>=0||r<l.length;)if(null!=(c=l[o=i>=0?i--:r++])&&0==(2&c.__u)&&e==c.key&&f==c.type)return o;return-1}function z(n,l,u){\"-\"==l[0]?n.setProperty(l,null==u?\"\":u):n[l]=null==u?\"\":\"number\"!=typeof u||_.test(l)?u:u+\"px\"}function N(n,l,u,t,i){var r,o;n:if(\"style\"==l)if(\"string\"==typeof u)n.style.cssText=u;else{if(\"string\"==typeof t&&(n.style.cssText=t=\"\"),t)for(l in t)u&&l in u||z(n.style,l,\"\");if(u)for(l in u)t&&u[l]==t[l]||z(n.style,l,u[l])}else if(\"o\"==l[0]&&\"n\"==l[1])r=l!=(l=l.replace(s,\"$1\")),o=l.toLowerCase(),l=o in n||\"onFocusOut\"==l||\"onFocusIn\"==l?o.slice(2):l.slice(2),n.l||(n.l={}),n.l[l+r]=u,u?t?u[a]=t[a]:(u[a]=h,n.addEventListener(l,r?v:p,r)):n.removeEventListener(l,r?v:p,r);else{if(\"http://www.w3.org/2000/svg\"==i)l=l.replace(/xlink(H|:h)/,\"h\").replace(/sName$/,\"s\");else if(\"width\"!=l&&\"height\"!=l&&\"href\"!=l&&\"list\"!=l&&\"form\"!=l&&\"tabIndex\"!=l&&\"download\"!=l&&\"rowSpan\"!=l&&\"colSpan\"!=l&&\"role\"!=l&&\"popover\"!=l&&l in n)try{n[l]=null==u?\"\":u;break n}catch(n){}\"function\"==typeof u||(null==u||!1===u&&\"-\"!=l[4]?n.removeAttribute(l):n.setAttribute(l,\"popover\"==l&&1==u?\"\":u))}}function V(n){return function(u){if(this.l){var t=this.l[u.type+n];if(null==u[c])u[c]=h++;else if(u[c]<t[a])return;return t(l.event?l.event(u):u)}}}function q(n,u,t,i,r,o,e,f,c,a){var s,h,p,v,y,d,_,k,x,M,$,I,P,A,H,T=u.type;if(void 0!==u.constructor)return null;128&t.__u&&(c=!!(32&t.__u),o=[f=u.__e=t.__e]),(s=l.__b)&&s(u);n:if(\"function\"==typeof T)try{if(k=u.props,x=T.prototype&&T.prototype.render,M=(s=T.contextType)&&i[s.__c],$=s?M?M.props.value:s.__:i,t.__c?_=(h=u.__c=t.__c).__=h.__E:(x?u.__c=h=new T(k,$):(u.__c=h=new C(k,$),h.constructor=T,h.render=Q),M&&M.sub(h),h.state||(h.state={}),h.__n=i,p=h.__d=!0,h.__h=[],h._sb=[]),x&&null==h.__s&&(h.__s=h.state),x&&null!=T.getDerivedStateFromProps&&(h.__s==h.state&&(h.__s=m({},h.__s)),m(h.__s,T.getDerivedStateFromProps(k,h.__s))),v=h.props,y=h.state,h.__v=u,p)x&&null==T.getDerivedStateFromProps&&null!=h.componentWillMount&&h.componentWillMount(),x&&null!=h.componentDidMount&&h.__h.push(h.componentDidMount);else{if(x&&null==T.getDerivedStateFromProps&&k!==v&&null!=h.componentWillReceiveProps&&h.componentWillReceiveProps(k,$),u.__v==t.__v||!h.__e&&null!=h.shouldComponentUpdate&&!1===h.shouldComponentUpdate(k,h.__s,$)){u.__v!=t.__v&&(h.props=k,h.state=h.__s,h.__d=!1),u.__e=t.__e,u.__k=t.__k,u.__k.some(function(n){n&&(n.__=u)}),w.push.apply(h.__h,h._sb),h._sb=[],h.__h.length&&e.push(h);break n}null!=h.componentWillUpdate&&h.componentWillUpdate(k,h.__s,$),x&&null!=h.componentDidUpdate&&h.__h.push(function(){h.componentDidUpdate(v,y,d)})}if(h.context=$,h.props=k,h.__P=n,h.__e=!1,I=l.__r,P=0,x)h.state=h.__s,h.__d=!1,I&&I(u),s=h.render(h.props,h.state,h.context),w.push.apply(h.__h,h._sb),h._sb=[];else do{h.__d=!1,I&&I(u),s=h.render(h.props,h.state,h.context),h.state=h.__s}while(h.__d&&++P<25);h.state=h.__s,null!=h.getChildContext&&(i=m(m({},i),h.getChildContext())),x&&!p&&null!=h.getSnapshotBeforeUpdate&&(d=h.getSnapshotBeforeUpdate(v,y)),A=null!=s&&s.type===S&&null==s.key?E(s.props.children):s,f=L(n,g(A)?A:[A],u,t,i,r,o,e,f,c,a),h.base=u.__e,u.__u&=-161,h.__h.length&&e.push(h),_&&(h.__E=h.__=null)}catch(n){if(u.__v=null,c||null!=o)if(n.then){for(u.__u|=c?160:128;f&&8==f.nodeType&&f.nextSibling;)f=f.nextSibling;o[o.indexOf(f)]=null,u.__e=f}else{for(H=o.length;H--;)b(o[H]);B(u)}else u.__e=t.__e,u.__k=t.__k,n.then||B(u);l.__e(n,u,t)}else null==o&&u.__v==t.__v?(u.__k=t.__k,u.__e=t.__e):f=u.__e=G(t.__e,u,t,i,r,o,e,c,a);return(s=l.diffed)&&s(u),128&u.__u?void 0:f}function B(n){n&&(n.__c&&(n.__c.__e=!0),n.__k&&n.__k.some(B))}function D(n,u,t){for(var i=0;i<t.length;i++)J(t[i],t[++i],t[++i]);l.__c&&l.__c(u,n),n.some(function(u){try{n=u.__h,u.__h=[],n.some(function(n){n.call(u)})}catch(n){l.__e(n,u.__v)}})}function E(n){return\"object\"!=typeof n||null==n||n.__b>0?n:g(n)?n.map(E):void 0!==n.constructor?null:m({},n)}function G(u,t,i,r,o,e,f,c,a){var s,h,p,v,y,w,_,m=i.props||d,k=t.props,x=t.type;if(\"svg\"==x?o=\"http://www.w3.org/2000/svg\":\"math\"==x?o=\"http://www.w3.org/1998/Math/MathML\":o||(o=\"http://www.w3.org/1999/xhtml\"),null!=e)for(s=0;s<e.length;s++)if((y=e[s])&&\"setAttribute\"in y==!!x&&(x?y.localName==x:3==y.nodeType)){u=y,e[s]=null;break}if(null==u){if(null==x)return document.createTextNode(k);u=document.createElementNS(o,x,k.is&&k),c&&(l.__m&&l.__m(t,e),c=!1),e=null}if(null==x)m===k||c&&u.data==k||(u.data=k);else{if(e=\"textarea\"==x&&null!=k.defaultValue?null:e&&n.call(u.childNodes),!c&&null!=e)for(m={},s=0;s<u.attributes.length;s++)m[(y=u.attributes[s]).name]=y.value;for(s in m)y=m[s],\"dangerouslySetInnerHTML\"==s?p=y:\"children\"==s||s in k||\"value\"==s&&\"defaultValue\"in k||\"checked\"==s&&\"defaultChecked\"in k||N(u,s,null,y,o);for(s in k)y=k[s],\"children\"==s?v=y:\"dangerouslySetInnerHTML\"==s?h=y:\"value\"==s?w=y:\"checked\"==s?_=y:c&&\"function\"!=typeof y||m[s]===y||N(u,s,y,m[s],o);if(h)c||p&&(h.__html==p.__html||h.__html==u.innerHTML)||(u.innerHTML=h.__html),t.__k=[];else if(p&&(u.innerHTML=\"\"),L(\"template\"==t.type?u.content:u,g(v)?v:[v],t,i,r,\"foreignObject\"==x?\"http://www.w3.org/1999/xhtml\":o,e,f,e?e[0]:i.__k&&$(i,0),c,a),null!=e)for(s=e.length;s--;)b(e[s]);c&&\"textarea\"!=x||(s=\"value\",\"progress\"==x&&null==w?u.removeAttribute(\"value\"):null!=w&&(w!==u[s]||\"progress\"==x&&!w||\"option\"==x&&w!=m[s])&&N(u,s,w,m[s],o),s=\"checked\",null!=_&&_!=u[s]&&N(u,s,_,m[s],o))}return u}function J(n,u,t){try{if(\"function\"==typeof n){var i=\"function\"==typeof n.__u;i&&n.__u(),i&&null==u||(n.__u=n(u))}else n.current=u}catch(n){l.__e(n,t)}}function K(n,u,t){var i,r;if(l.unmount&&l.unmount(n),(i=n.ref)&&(i.current&&i.current!=n.__e||J(i,null,u)),null!=(i=n.__c)){if(i.componentWillUnmount)try{i.componentWillUnmount()}catch(n){l.__e(n,u)}i.base=i.__P=null}if(i=n.__k)for(r=0;r<i.length;r++)i[r]&&K(i[r],u,t||\"function\"!=typeof n.type);t||b(n.__e),n.__c=n.__=n.__e=void 0}function Q(n,l,u){return this.constructor(n,u)}function R(u,t,i){var r,o,e,f;t==document&&(t=document.documentElement),l.__&&l.__(u,t),o=(r=\"function\"==typeof i)?null:i&&i.__k||t.__k,e=[],f=[],q(t,u=(!r&&i||t).__k=k(S,null,[u]),o||d,d,t.namespaceURI,!r&&i?[i]:o?null:t.firstChild?n.call(t.childNodes):null,e,!r&&i?i:o?o.__e:t.firstChild,r,f),D(e,u,f)}function U(n,l){R(n,l,U)}function W(l,u,t){var i,r,o,e,f=m({},l.props);for(o in l.type&&l.type.defaultProps&&(e=l.type.defaultProps),u)\"key\"==o?i=u[o]:\"ref\"==o?r=u[o]:f[o]=void 0===u[o]&&null!=e?e[o]:u[o];return arguments.length>2&&(f.children=arguments.length>3?n.call(arguments,2):t),x(l.type,f,i||l.key,r||l.ref,null)}function X(n){function l(n){var u,t;return this.getChildContext||(u=new Set,(t={})[l.__c]=this,this.getChildContext=function(){return t},this.componentWillUnmount=function(){u=null},this.shouldComponentUpdate=function(n){this.props.value!=n.value&&u.forEach(function(n){n.__e=!0,A(n)})},this.sub=function(n){u.add(n);var l=n.componentWillUnmount;n.componentWillUnmount=function(){u&&u.delete(n),l&&l.call(n)}}),n.children}return l.__c=\"__cC\"+y++,l.__=n,l.Provider=l.__l=(l.Consumer=function(n,l){return n.children(l)}).contextType=l,l}n=w.slice,l={__e:function(n,l,u,t){for(var i,r,o;l=l.__;)if((i=l.__c)&&!i.__)try{if((r=i.constructor)&&null!=r.getDerivedStateFromError&&(i.setState(r.getDerivedStateFromError(n)),o=i.__d),null!=i.componentDidCatch&&(i.componentDidCatch(n,t||{}),o=i.__d),o)return i.__E=i}catch(l){n=l}throw n}},u=0,t=function(n){return null!=n&&void 0===n.constructor},C.prototype.setState=function(n,l){var u;u=null!=this.__s&&this.__s!=this.state?this.__s:this.__s=m({},this.state),\"function\"==typeof n&&(n=n(m({},u),this.props)),n&&m(u,n),null!=n&&this.__v&&(l&&this._sb.push(l),A(this))},C.prototype.forceUpdate=function(n){this.__v&&(this.__e=!0,n&&this.__h.push(n),A(this))},C.prototype.render=S,i=[],o=\"function\"==typeof Promise?Promise.prototype.then.bind(Promise.resolve()):setTimeout,e=function(n,l){return n.__v.__b-l.__v.__b},H.__r=0,f=Math.random().toString(8),c=\"__d\"+f,a=\"__a\"+f,s=/(PointerCapture)$|Capture$/i,h=0,p=V(!1),v=V(!0),y=0;export{C as Component,S as Fragment,W as cloneElement,X as createContext,k as createElement,M as createRef,k as h,U as hydrate,t as isValidElement,l as options,R as render,F as toChildArray};\n//# sourceMappingURL=preact.module.js.map\n","import{options as n}from\"preact\";var t,r,u,i,o=0,f=[],c=n,e=c.__b,a=c.__r,v=c.diffed,l=c.__c,m=c.unmount,s=c.__;function p(n,t){c.__h&&c.__h(r,n,o||t),o=0;var u=r.__H||(r.__H={__:[],__h:[]});return n>=u.__.length&&u.__.push({}),u.__[n]}function d(n){return o=1,h(D,n)}function h(n,u,i){var o=p(t++,2);if(o.t=n,!o.__c&&(o.__=[i?i(u):D(void 0,u),function(n){var t=o.__N?o.__N[0]:o.__[0],r=o.t(t,n);t!==r&&(o.__N=[r,o.__[1]],o.__c.setState({}))}],o.__c=r,!r.__f)){var f=function(n,t,r){if(!o.__c.__H)return!0;var u=o.__c.__H.__.filter(function(n){return n.__c});if(u.every(function(n){return!n.__N}))return!c||c.call(this,n,t,r);var i=o.__c.props!==n;return u.some(function(n){if(n.__N){var t=n.__[0];n.__=n.__N,n.__N=void 0,t!==n.__[0]&&(i=!0)}}),c&&c.call(this,n,t,r)||i};r.__f=!0;var c=r.shouldComponentUpdate,e=r.componentWillUpdate;r.componentWillUpdate=function(n,t,r){if(this.__e){var u=c;c=void 0,f(n,t,r),c=u}e&&e.call(this,n,t,r)},r.shouldComponentUpdate=f}return o.__N||o.__}function y(n,u){var i=p(t++,3);!c.__s&&C(i.__H,u)&&(i.__=n,i.u=u,r.__H.__h.push(i))}function _(n,u){var i=p(t++,4);!c.__s&&C(i.__H,u)&&(i.__=n,i.u=u,r.__h.push(i))}function A(n){return o=5,T(function(){return{current:n}},[])}function F(n,t,r){o=6,_(function(){if(\"function\"==typeof n){var r=n(t());return function(){n(null),r&&\"function\"==typeof r&&r()}}if(n)return n.current=t(),function(){return n.current=null}},null==r?r:r.concat(n))}function T(n,r){var u=p(t++,7);return C(u.__H,r)&&(u.__=n(),u.__H=r,u.__h=n),u.__}function q(n,t){return o=8,T(function(){return n},t)}function x(n){var u=r.context[n.__c],i=p(t++,9);return i.c=n,u?(null==i.__&&(i.__=!0,u.sub(r)),u.props.value):n.__}function P(n,t){c.useDebugValue&&c.useDebugValue(t?t(n):n)}function b(n){var u=p(t++,10),i=d();return u.__=n,r.componentDidCatch||(r.componentDidCatch=function(n,t){u.__&&u.__(n,t),i[1](n)}),[i[0],function(){i[1](void 0)}]}function g(){var n=p(t++,11);if(!n.__){for(var u=r.__v;null!==u&&!u.__m&&null!==u.__;)u=u.__;var i=u.__m||(u.__m=[0,0]);n.__=\"P\"+i[0]+\"-\"+i[1]++}return n.__}function j(){for(var n;n=f.shift();){var t=n.__H;if(n.__P&&t)try{t.__h.some(z),t.__h.some(B),t.__h=[]}catch(r){t.__h=[],c.__e(r,n.__v)}}}c.__b=function(n){r=null,e&&e(n)},c.__=function(n,t){n&&t.__k&&t.__k.__m&&(n.__m=t.__k.__m),s&&s(n,t)},c.__r=function(n){a&&a(n),t=0;var i=(r=n.__c).__H;i&&(u===r?(i.__h=[],r.__h=[],i.__.some(function(n){n.__N&&(n.__=n.__N),n.u=n.__N=void 0})):(i.__h.some(z),i.__h.some(B),i.__h=[],t=0)),u=r},c.diffed=function(n){v&&v(n);var t=n.__c;t&&t.__H&&(t.__H.__h.length&&(1!==f.push(t)&&i===c.requestAnimationFrame||((i=c.requestAnimationFrame)||w)(j)),t.__H.__.some(function(n){n.u&&(n.__H=n.u),n.u=void 0})),u=r=null},c.__c=function(n,t){t.some(function(n){try{n.__h.some(z),n.__h=n.__h.filter(function(n){return!n.__||B(n)})}catch(r){t.some(function(n){n.__h&&(n.__h=[])}),t=[],c.__e(r,n.__v)}}),l&&l(n,t)},c.unmount=function(n){m&&m(n);var t,r=n.__c;r&&r.__H&&(r.__H.__.some(function(n){try{z(n)}catch(n){t=n}}),r.__H=void 0,t&&c.__e(t,r.__v))};var k=\"function\"==typeof requestAnimationFrame;function w(n){var t,r=function(){clearTimeout(u),k&&cancelAnimationFrame(t),setTimeout(n)},u=setTimeout(r,35);k&&(t=requestAnimationFrame(r))}function z(n){var t=r,u=n.__c;\"function\"==typeof u&&(n.__c=void 0,u()),r=t}function B(n){var t=r;n.__c=n.__(),r=t}function C(n,t){return!n||n.length!==t.length||t.some(function(t,r){return t!==n[r]})}function D(n,t){return\"function\"==typeof t?t(n):t}export{q as useCallback,x as useContext,P as useDebugValue,y as useEffect,b as useErrorBoundary,g as useId,F as useImperativeHandle,_ as useLayoutEffect,T as useMemo,h as useReducer,A as useRef,d as useState};\n//# sourceMappingURL=hooks.module.js.map\n","/**\n * Having Survey types in types.ts was confusing tsc\n * and generating an invalid module.d.ts\n * See https://github.com/PostHog/posthog-js/issues/698\n */\n\nimport type { Properties, PropertyMatchType } from './types'\nimport type {\n SurveyAppearance as CoreSurveyAppearance,\n SurveyQuestionTranslation,\n SurveyResponseValue as CoreSurveyResponseValue,\n SurveyTranslation,\n SurveyValidationRule,\n} from '@posthog/core'\n\n// Extended operator type to include numeric operators not in PropertyMatchType\nexport type PropertyOperator = PropertyMatchType | 'gt' | 'lt'\n\nexport type PropertyFilters = {\n [propertyName: string]: {\n values: string[]\n operator: PropertyOperator\n }\n}\n\nexport interface SurveyEventWithFilters {\n name: string\n propertyFilters?: PropertyFilters\n}\n\n// Extends core SurveyAppearance with browser-specific fields\n// Omit 'position' from core because browser's SurveyPosition has additional values (e.g., NextToTrigger)\nexport interface SurveyAppearance extends Omit<CoreSurveyAppearance, 'position' | 'widgetType'> {\n // Browser-specific fields not in core\n /** @deprecated - not currently used */\n descriptionTextColor?: string\n ratingButtonHoverColor?: string\n whiteLabel?: boolean\n tabPosition?: SurveyTabPosition\n fontFamily?: string\n maxWidth?: string\n zIndex?: string\n disabledButtonOpacity?: string\n boxPadding?: string\n /** @deprecated Use inputBackground instead (inherited from core) */\n inputBackgroundColor?: string\n // Hide the X (cancel) button - defaults to false (show the button)\n hideCancelButton?: boolean\n // Browser's SurveyPosition has more options than core (e.g., NextToTrigger)\n position?: SurveyPosition\n widgetType?: SurveyWidgetType\n}\n\nexport type SurveyQuestion = BasicSurveyQuestion | LinkSurveyQuestion | RatingSurveyQuestion | MultipleSurveyQuestion\n\nexport type SurveyQuestionDescriptionContentType = 'html' | 'text'\n\ninterface SurveyQuestionBase {\n question: string\n id?: string\n description?: string | null\n descriptionContentType?: SurveyQuestionDescriptionContentType\n optional?: boolean\n buttonText?: string\n branching?: NextQuestionBranching | EndBranching | ResponseBasedBranching | SpecificQuestionBranching\n validation?: SurveyValidationRule[]\n translations?: Record<string, SurveyQuestionTranslation>\n}\n\nexport interface BasicSurveyQuestion extends SurveyQuestionBase {\n type: typeof SurveyQuestionType.Open\n}\n\nexport interface LinkSurveyQuestion extends SurveyQuestionBase {\n type: typeof SurveyQuestionType.Link\n link?: string | null\n}\n\nexport interface RatingSurveyQuestion extends SurveyQuestionBase {\n type: typeof SurveyQuestionType.Rating\n display: 'number' | 'emoji'\n scale: 2 | 3 | 5 | 7 | 10\n lowerBoundLabel: string\n upperBoundLabel: string\n skipSubmitButton?: boolean\n}\n\nexport interface MultipleSurveyQuestion extends SurveyQuestionBase {\n type: typeof SurveyQuestionType.SingleChoice | typeof SurveyQuestionType.MultipleChoice\n choices: string[]\n hasOpenChoice?: boolean\n shuffleOptions?: boolean\n skipSubmitButton?: boolean\n}\n\ninterface NextQuestionBranching {\n type: typeof SurveyQuestionBranchingType.NextQuestion\n}\n\ninterface EndBranching {\n type: typeof SurveyQuestionBranchingType.End\n}\n\ninterface ResponseBasedBranching {\n type: typeof SurveyQuestionBranchingType.ResponseBased\n responseValues: Record<string, any>\n}\n\ninterface SpecificQuestionBranching {\n type: typeof SurveyQuestionBranchingType.SpecificQuestion\n index: number\n}\n\nexport type SurveyCallback = (surveys: Survey[], context?: { isLoaded: boolean; error?: string }) => void\n\nexport interface SurveyElement {\n text?: string\n $el_text?: string\n tag_name?: string\n href?: string\n attr_id?: string\n attr_class?: string[]\n nth_child?: number\n nth_of_type?: number\n attributes?: Record<string, any>\n event_id?: number\n order?: number\n group_id?: number\n}\n\n// Re-export from @posthog/types to avoid duplication\nexport type { SurveyRenderReason } from '@posthog/types'\n\nexport interface Survey {\n // Sync this with the backend's SurveyAPISerializer!\n id: string\n name: string\n description?: string\n type: SurveyType\n translations?: Record<string, SurveyTranslation>\n feature_flag_keys:\n | {\n key: string\n value?: string\n }[]\n | null\n // the linked flag key is the flag key that is used to link the survey to a flag\n linked_flag_key: string | null\n targeting_flag_key: string | null\n // the internal targeting flag key is the flag key that is used to target users who have seen the survey\n // eg survey-targeting-<survey-id>\n internal_targeting_flag_key: string | null\n questions: SurveyQuestion[]\n appearance: SurveyAppearance | null\n conditions: {\n url?: string\n selector?: string\n seenSurveyWaitPeriodInDays?: number\n urlMatchType?: PropertyMatchType\n /** events that trigger surveys */\n events: {\n repeatedActivation?: boolean\n values: SurveyEventWithFilters[]\n } | null\n /** events that cancel \"pending\" (time-delayed) surveys */\n cancelEvents: {\n values: SurveyEventWithFilters[]\n } | null\n actions: {\n values: SurveyActionType[]\n } | null\n deviceTypes?: string[]\n deviceTypesMatchType?: PropertyMatchType\n linkedFlagVariant?: string\n } | null\n start_date: string | null\n end_date: string | null\n current_iteration: number | null\n current_iteration_start_date: string | null\n schedule?: SurveySchedule | null\n enable_partial_responses?: boolean | null\n}\n\nexport type SurveyWithTypeAndAppearance = Pick<Survey, 'id' | 'type' | 'appearance'>\n\nexport interface SurveyActionType {\n id: number\n name: string | null\n steps?: ActionStepType[]\n}\n\n/** Sync with plugin-server/src/types.ts */\nexport type ActionStepStringMatching = 'contains' | 'exact' | 'regex'\n\nexport interface ActionStepType {\n event?: string | null\n selector?: string | null\n /** pre-compiled regex pattern for matching selector against $elements_chain */\n selector_regex?: string | null\n /** @deprecated Only `selector` should be used now. */\n tag_name?: string\n text?: string | null\n /** @default StringMatching.Exact */\n text_matching?: ActionStepStringMatching | null\n href?: string | null\n /** @default ActionStepStringMatching.Exact */\n href_matching?: ActionStepStringMatching | null\n url?: string | null\n /** @default StringMatching.Contains */\n url_matching?: ActionStepStringMatching | null\n /** Property filters for action step matching */\n properties?: {\n key: string\n value?: string | number | boolean | (string | number | boolean)[] | null\n operator?: PropertyMatchType\n type?: string\n }[]\n}\n\ninterface DisplaySurveyOptionsBase {\n /**\n * Whether to bypass the survey's targeting and display conditions.\n * @default false\n */\n ignoreConditions: boolean\n\n /**\n * Whether to bypass the survey's configured popup delay.\n * @default false\n */\n ignoreDelay: boolean\n\n /**\n * How the survey should be displayed.\n * @default DisplaySurveyType.Popover\n */\n displayType: DisplaySurveyType\n\n /** Additional properties to include in all survey events (shown, sent, dismissed). */\n properties?: Properties\n\n /** Pre-filled responses by question index (0-based). Only supported for popover surveys. */\n initialResponses?: Record<number, SurveyResponseValue>\n}\n\n/** Options for displaying a survey as a popover. */\nexport interface DisplaySurveyPopoverOptions extends DisplaySurveyOptionsBase {\n displayType: typeof DisplaySurveyType.Popover\n /** Override the survey's configured position. */\n position?: SurveyPosition\n /** CSS selector for the element to position the survey next to (when position is NextToTrigger). */\n selector?: string\n /** When true, `survey shown` events will not be emitted automatically. */\n skipShownEvent?: boolean\n}\n\ninterface DisplaySurveyInlineOptions extends DisplaySurveyOptionsBase {\n displayType: typeof DisplaySurveyType.Inline\n /** CSS selector for the element where the inline survey should render. */\n selector: string\n}\n\n/** Options for `posthog.displaySurvey()`. */\nexport type DisplaySurveyOptions = DisplaySurveyPopoverOptions | DisplaySurveyInlineOptions\n\nexport interface SurveyConfig {\n /**\n * Prefill survey responses from matching URL parameters.\n *\n * @default undefined\n */\n prefillFromUrl?: boolean\n /**\n * @deprecated No longer used. Surveys will automatically advance past\n * prefilled questions with skipSubmitButton enabled. If partial response\n * collection is enabled, partial responses for pre-filled questions will\n * be submitted automatically on page load.\n */\n autoSubmitIfComplete?: boolean\n /**\n * @deprecated No longer used. Pre-filled responses are now sent\n * immediately when partial responses are enabled, or all required\n * questions have been pre-filled.\n */\n autoSubmitDelay?: number\n}\n\nexport type SurveyResponseValue = CoreSurveyResponseValue\n\n/**\n * Surveys related enums and constants.\n * We use const objects instead of TypeScript enums to allow for easier tree-shaking and to avoid issues with enum imports in JavaScript.\n */\n\nexport const SurveyEventType = {\n Activation: 'events',\n Cancellation: 'cancelEvents',\n} as const\nexport type SurveyEventType = (typeof SurveyEventType)[keyof typeof SurveyEventType]\n\nexport const SurveyWidgetType = {\n Button: 'button',\n Tab: 'tab',\n Selector: 'selector',\n} as const\nexport type SurveyWidgetType = (typeof SurveyWidgetType)[keyof typeof SurveyWidgetType]\n\nexport const SurveyPosition = {\n TopLeft: 'top_left',\n TopRight: 'top_right',\n TopCenter: 'top_center',\n MiddleLeft: 'middle_left',\n MiddleRight: 'middle_right',\n MiddleCenter: 'middle_center',\n Left: 'left',\n Center: 'center',\n Right: 'right',\n NextToTrigger: 'next_to_trigger',\n} as const\nexport type SurveyPosition = (typeof SurveyPosition)[keyof typeof SurveyPosition]\n\nexport const SurveyTabPosition = {\n Top: 'top',\n Left: 'left',\n Right: 'right',\n Bottom: 'bottom',\n} as const\nexport type SurveyTabPosition = (typeof SurveyTabPosition)[keyof typeof SurveyTabPosition]\n\nexport const SurveyType = {\n Popover: 'popover',\n API: 'api',\n Widget: 'widget',\n ExternalSurvey: 'external_survey',\n} as const\nexport type SurveyType = (typeof SurveyType)[keyof typeof SurveyType]\n\nexport const SurveyQuestionType = {\n Open: 'open',\n MultipleChoice: 'multiple_choice',\n SingleChoice: 'single_choice',\n Rating: 'rating',\n Link: 'link',\n} as const\nexport type SurveyQuestionType = (typeof SurveyQuestionType)[keyof typeof SurveyQuestionType]\n\nexport const SurveyQuestionBranchingType = {\n NextQuestion: 'next_question',\n End: 'end',\n ResponseBased: 'response_based',\n SpecificQuestion: 'specific_question',\n} as const\nexport type SurveyQuestionBranchingType = (typeof SurveyQuestionBranchingType)[keyof typeof SurveyQuestionBranchingType]\n\nexport const SurveySchedule = {\n Once: 'once',\n Recurring: 'recurring',\n Always: 'always',\n} as const\nexport type SurveySchedule = (typeof SurveySchedule)[keyof typeof SurveySchedule]\n\nexport const SurveyEventName = {\n SHOWN: 'survey shown',\n DISMISSED: 'survey dismissed',\n SENT: 'survey sent',\n ABANDONED: 'survey abandoned',\n} as const\nexport type SurveyEventName = (typeof SurveyEventName)[keyof typeof SurveyEventName]\n\nexport const SurveyEventProperties = {\n SURVEY_ID: '$survey_id',\n SURVEY_NAME: '$survey_name',\n SURVEY_RESPONSE: '$survey_response',\n SURVEY_ITERATION: '$survey_iteration',\n SURVEY_ITERATION_START_DATE: '$survey_iteration_start_date',\n SURVEY_PARTIALLY_COMPLETED: '$survey_partially_completed',\n SURVEY_SUBMISSION_ID: '$survey_submission_id',\n SURVEY_QUESTIONS: '$survey_questions',\n SURVEY_COMPLETED: '$survey_completed',\n PRODUCT_TOUR_ID: '$product_tour_id',\n SURVEY_LAST_SEEN_DATE: '$survey_last_seen_date',\n SURVEY_LANGUAGE: '$survey_language',\n} as const\nexport type SurveyEventProperties = (typeof SurveyEventProperties)[keyof typeof SurveyEventProperties]\n\nexport const DisplaySurveyType = {\n Popover: 'popover',\n Inline: 'inline',\n} as const\nexport type DisplaySurveyType = (typeof DisplaySurveyType)[keyof typeof DisplaySurveyType]\n","import { isArray, isNullish, isUndefined } from \"../utils/index.mjs\";\nconst SURVEY_LANGUAGE_PROPERTY = '$survey_language';\nfunction getSurveyResponseKey(questionId) {\n return `$survey_response_${questionId}`;\n}\nfunction getSurveyOldResponseKey(originalQuestionIndex) {\n return 0 === originalQuestionIndex ? '$survey_response' : `$survey_response_${originalQuestionIndex}`;\n}\nfunction getSurveyResponseValue(responses, questionId) {\n if (!questionId) return null;\n const response = responses[getSurveyResponseKey(questionId)];\n if (isArray(response)) return [\n ...response\n ];\n return response;\n}\nfunction buildSurveyResponseProperties(responses = {}, survey) {\n const oldFormatResponses = {};\n survey.questions.forEach((question)=>{\n if (isUndefined(question.originalQuestionIndex)) return;\n const oldResponseKey = getSurveyOldResponseKey(question.originalQuestionIndex);\n const response = getSurveyResponseValue(responses, question.id);\n if (!isUndefined(response)) oldFormatResponses[oldResponseKey] = response;\n });\n return {\n $survey_questions: survey.questions.map((question)=>({\n id: question.id,\n question: question.question,\n response: getSurveyResponseValue(responses, question.id)\n })),\n ...responses,\n ...oldFormatResponses\n };\n}\nfunction surveyHasResponses(responses = {}) {\n return Object.values(responses).some((response)=>!isNullish(response));\n}\nfunction getSurveyInteractionProperty(survey, action) {\n let surveyProperty = `$survey_${action}/${survey.id}`;\n if (survey.current_iteration && survey.current_iteration > 0) surveyProperty = `$survey_${action}/${survey.id}/${survey.current_iteration}`;\n return surveyProperty;\n}\nexport { SURVEY_LANGUAGE_PROPERTY, buildSurveyResponseProperties, getSurveyInteractionProperty, getSurveyOldResponseKey, getSurveyResponseKey, getSurveyResponseValue, surveyHasResponses };\n","import { isArray, isUndefined } from \"../utils/index.mjs\";\nfunction getTrimmedLanguage(value) {\n return 'string' == typeof value && value.trim() ? value.trim() : null;\n}\nfunction getLanguageFromStoredPersonProperties(storedPersonProperties) {\n if (!storedPersonProperties || 'object' != typeof storedPersonProperties || !('language' in storedPersonProperties)) return null;\n return getTrimmedLanguage(storedPersonProperties.language);\n}\nfunction detectSurveyLanguage({ overrideLanguage, storedPersonProperties, locale }, logger) {\n const explicitLanguage = getTrimmedLanguage(overrideLanguage);\n if (explicitLanguage) {\n logger?.info(`Using override display language: ${explicitLanguage}`);\n return explicitLanguage;\n }\n const personLanguage = getLanguageFromStoredPersonProperties(storedPersonProperties);\n if (personLanguage) {\n logger?.info(`Using person property language: ${personLanguage}`);\n return personLanguage;\n }\n const detectedLocale = getTrimmedLanguage(locale);\n if (detectedLocale) {\n logger?.info(`Using detected locale: ${detectedLocale}`);\n return detectedLocale;\n }\n logger?.info('No user language detected');\n return null;\n}\nfunction normalizeLanguageCode(languageCode) {\n return languageCode.toLowerCase();\n}\nfunction getBaseLanguage(languageCode) {\n return languageCode.split('-')[0];\n}\nfunction findBestTranslationMatch(translations, targetLanguage, logger) {\n if (!translations || !targetLanguage) return null;\n const normalizedTarget = normalizeLanguageCode(targetLanguage);\n const exactMatch = Object.keys(translations).find((key)=>normalizeLanguageCode(key) === normalizedTarget);\n if (exactMatch) {\n logger?.debug(`Found exact translation match: ${exactMatch}`);\n return exactMatch;\n }\n if (normalizedTarget.includes('-')) {\n const baseLanguage = getBaseLanguage(normalizedTarget);\n const baseMatch = Object.keys(translations).find((key)=>normalizeLanguageCode(key) === baseLanguage);\n if (baseMatch) {\n logger?.debug(`Found base language translation match: ${baseMatch} (from ${targetLanguage})`);\n return baseMatch;\n }\n }\n return null;\n}\nfunction isTranslatedChoices(questionTranslation) {\n return isArray(questionTranslation.choices);\n}\nfunction hasAppearanceTranslation(translation) {\n return !isUndefined(translation.thankYouMessageHeader) || !isUndefined(translation.thankYouMessageDescription) || !isUndefined(translation.thankYouMessageCloseButtonText) || !isUndefined(translation.submitButtonText) || !isUndefined(translation.backButtonText);\n}\nfunction mergeQuestionTranslation(question, targetLanguage, logger) {\n const translationKey = findBestTranslationMatch(question.translations, targetLanguage, logger);\n if (!translationKey) return {\n question,\n matchedKey: null,\n hasChanges: false\n };\n const questionTranslation = question.translations?.[translationKey];\n if (!questionTranslation) return {\n question,\n matchedKey: null,\n hasChanges: false\n };\n const translated = {\n ...question\n };\n let hasChanges = false;\n if (!isUndefined(questionTranslation.question)) {\n translated.question = questionTranslation.question;\n hasChanges = true;\n }\n if (!isUndefined(questionTranslation.description)) {\n translated.description = questionTranslation.description;\n hasChanges = true;\n }\n if (!isUndefined(questionTranslation.buttonText)) {\n translated.buttonText = questionTranslation.buttonText;\n hasChanges = true;\n }\n if ('link' in translated && !isUndefined(questionTranslation.link)) {\n translated.link = questionTranslation.link;\n hasChanges = true;\n }\n if ('lowerBoundLabel' in translated && !isUndefined(questionTranslation.lowerBoundLabel)) {\n translated.lowerBoundLabel = questionTranslation.lowerBoundLabel;\n hasChanges = true;\n }\n if ('upperBoundLabel' in translated && !isUndefined(questionTranslation.upperBoundLabel)) {\n translated.upperBoundLabel = questionTranslation.upperBoundLabel;\n hasChanges = true;\n }\n if ('choices' in translated && isTranslatedChoices(questionTranslation)) {\n translated.choices = questionTranslation.choices;\n hasChanges = true;\n }\n return {\n question: hasChanges ? translated : question,\n matchedKey: hasChanges ? translationKey : null,\n hasChanges\n };\n}\nfunction applySurveyTranslation(survey, targetLanguage, logger) {\n const translationKey = findBestTranslationMatch(survey.translations, targetLanguage, logger);\n const translated = {\n ...survey\n };\n let hasTranslation = false;\n if (translationKey) {\n const translation = survey.translations?.[translationKey];\n if (translation) {\n logger?.info(`Applying survey-level translation for language: ${translationKey}`);\n if (!isUndefined(translation.name)) {\n translated.name = translation.name;\n hasTranslation = true;\n }\n if (translated.appearance) {\n translated.appearance = {\n ...translated.appearance\n };\n if (!isUndefined(translation.thankYouMessageHeader)) {\n translated.appearance.thankYouMessageHeader = translation.thankYouMessageHeader;\n hasTranslation = true;\n }\n if (!isUndefined(translation.thankYouMessageDescription)) {\n translated.appearance.thankYouMessageDescription = translation.thankYouMessageDescription;\n hasTranslation = true;\n }\n if (!isUndefined(translation.thankYouMessageCloseButtonText)) {\n translated.appearance.thankYouMessageCloseButtonText = translation.thankYouMessageCloseButtonText;\n hasTranslation = true;\n }\n if (!isUndefined(translation.submitButtonText)) {\n translated.appearance.submitButtonText = translation.submitButtonText;\n hasTranslation = true;\n }\n if (!isUndefined(translation.backButtonText)) {\n translated.appearance.backButtonText = translation.backButtonText;\n hasTranslation = true;\n }\n } else if (hasAppearanceTranslation(translation)) hasTranslation = true;\n }\n }\n const translatedResults = survey.questions.map((question)=>mergeQuestionTranslation(question, targetLanguage, logger));\n const translatedQuestions = translatedResults.map((result)=>result.question);\n const anyQuestionTranslated = translatedResults.some((result)=>result.hasChanges);\n let questionMatchedKey = null;\n if (!translationKey) questionMatchedKey = translatedResults.find((result)=>result.matchedKey)?.matchedKey || null;\n if (anyQuestionTranslated) {\n translated.questions = translatedQuestions;\n hasTranslation = true;\n logger?.info(`Applied question-level translations for language: ${targetLanguage}`);\n }\n return {\n survey: translated,\n matchedKey: hasTranslation ? translationKey || questionMatchedKey : null\n };\n}\nexport { applySurveyTranslation, detectSurveyLanguage, findBestTranslationMatch, getBaseLanguage, getLanguageFromStoredPersonProperties, normalizeLanguageCode };\n","import { DisplaySurveyOptions, Survey, SurveyType, DisplaySurveyType } from '../posthog-surveys-types'\nimport { createLogger } from '../utils/logger'\n\nexport { getSurveyInteractionProperty } from '@posthog/core/surveys'\n\nexport const SURVEY_LOGGER = createLogger('[Surveys]')\n\nexport function isSurveyRunning(survey: Survey): boolean {\n return !!(survey.start_date && !survey.end_date)\n}\n\nexport function doesSurveyActivateByEvent(survey: Pick<Survey, 'conditions'>): boolean {\n return !!survey.conditions?.events?.values?.length\n}\n\nexport function doesSurveyActivateByAction(survey: Pick<Survey, 'conditions'>): boolean {\n return !!survey.conditions?.actions?.values?.length\n}\n\nexport const SURVEY_SEEN_PREFIX = 'seenSurvey_'\nexport const SURVEY_IN_PROGRESS_PREFIX = 'inProgressSurvey_'\nexport const SURVEY_ABANDONED_PREFIX = 'abandonedSurvey_'\n\nconst getSurveyStorageKey = (prefix: string, survey: Pick<Survey, 'id' | 'current_iteration'>): string => {\n let key = `${prefix}${survey.id}`\n if (survey.current_iteration && survey.current_iteration > 0) {\n key = `${prefix}${survey.id}_${survey.current_iteration}`\n }\n return key\n}\n\nexport const getSurveySeenKey = (survey: Pick<Survey, 'id' | 'current_iteration'>): string => {\n return getSurveyStorageKey(SURVEY_SEEN_PREFIX, survey)\n}\n\nexport const getSurveyAbandonedKey = (survey: Pick<Survey, 'id' | 'current_iteration'>): string => {\n return getSurveyStorageKey(SURVEY_ABANDONED_PREFIX, survey)\n}\n\nexport const setSurveySeenOnLocalStorage = (survey: Pick<Survey, 'id' | 'current_iteration'>) => {\n try {\n const surveySeenKey = getSurveySeenKey(survey)\n const isSurveySeen = localStorage.getItem(surveySeenKey)\n // if survey is already seen, no need to set it again\n if (isSurveySeen) {\n return\n }\n\n localStorage.setItem(surveySeenKey, 'true')\n } catch (error) {\n SURVEY_LOGGER.error('Failed to persist survey seen state', error)\n }\n}\n\n// These surveys are relevant for the getActiveMatchingSurveys method. They are used to\n// display surveys in our customer's application. Any new in-app survey type should be added here.\nexport const IN_APP_SURVEY_TYPES: SurveyType[] = [SurveyType.Popover, SurveyType.Widget, SurveyType.API]\n\nexport const DEFAULT_DISPLAY_SURVEY_OPTIONS: DisplaySurveyOptions = {\n ignoreConditions: false,\n ignoreDelay: false,\n displayType: DisplaySurveyType.Popover,\n}\n","/**\n * uuidv7: An experimental implementation of the proposed UUID Version 7\n *\n * @license Apache-2.0\n * @copyright 2021-2023 LiosK\n * @packageDocumentation\n *\n * from https://github.com/LiosK/uuidv7/blob/e501462ea3d23241de13192ceae726956f9b3b7d/src/index.ts\n */\n\n// polyfill for IE11\nimport { window } from './utils/globals'\n\nimport { isNumber, isUndefined } from '@posthog/core'\n\nif (!Math.trunc) {\n Math.trunc = function (v) {\n return v < 0 ? Math.ceil(v) : Math.floor(v)\n }\n}\n\n// polyfill for IE11\nif (!Number.isInteger) {\n Number.isInteger = function (value) {\n return isNumber(value) && isFinite(value) && Math.floor(value) === value\n }\n}\n\n/** Represents a UUID as a 16-byte byte array. */\nexport class UUID {\n /** @param bytes - The 16-byte byte array representation. */\n constructor(readonly bytes: Readonly<Uint8Array>) {\n if (bytes.length !== 16) {\n throw new TypeError('not 128-bit length')\n }\n }\n\n /**\n * Builds a byte array from UUIDv7 field values.\n *\n * @param unixTsMs - A 48-bit `unix_ts_ms` field value.\n * @param randA - A 12-bit `rand_a` field value.\n * @param randBHi - The higher 30 bits of 62-bit `rand_b` field value.\n * @param randBLo - The lower 32 bits of 62-bit `rand_b` field value.\n */\n static fromFieldsV7(unixTsMs: number, randA: number, randBHi: number, randBLo: number): UUID {\n if (\n !Number.isInteger(unixTsMs) ||\n !Number.isInteger(randA) ||\n !Number.isInteger(randBHi) ||\n !Number.isInteger(randBLo) ||\n unixTsMs < 0 ||\n randA < 0 ||\n randBHi < 0 ||\n randBLo < 0 ||\n unixTsMs > 0xffff_ffff_ffff ||\n randA > 0xfff ||\n randBHi > 0x3fff_ffff ||\n randBLo > 0xffff_ffff\n ) {\n throw new RangeError('invalid field value')\n }\n\n const bytes = new Uint8Array(16)\n bytes[0] = unixTsMs / 2 ** 40\n bytes[1] = unixTsMs / 2 ** 32\n bytes[2] = unixTsMs / 2 ** 24\n bytes[3] = unixTsMs / 2 ** 16\n bytes[4] = unixTsMs / 2 ** 8\n bytes[5] = unixTsMs\n bytes[6] = 0x70 | (randA >>> 8)\n bytes[7] = randA\n bytes[8] = 0x80 | (randBHi >>> 24)\n bytes[9] = randBHi >>> 16\n bytes[10] = randBHi >>> 8\n bytes[11] = randBHi\n bytes[12] = randBLo >>> 24\n bytes[13] = randBLo >>> 16\n bytes[14] = randBLo >>> 8\n bytes[15] = randBLo\n return new UUID(bytes)\n }\n\n /** @returns The 8-4-4-4-12 canonical hexadecimal string representation. */\n toString(): string {\n let text = ''\n for (let i = 0; i < this.bytes.length; i++) {\n text = text + (this.bytes[i] >>> 4).toString(16) + (this.bytes[i] & 0xf).toString(16)\n if (i === 3 || i === 5 || i === 7 || i === 9) {\n text += '-'\n }\n }\n\n if (text.length !== 36) {\n // We saw one customer whose bundling code was mangling the UUID generation\n // rather than accept a bad UUID, we throw an error here.\n throw new Error('Invalid UUIDv7 was generated')\n }\n return text\n }\n\n /** Creates an object from `this`. */\n clone(): UUID {\n return new UUID(this.bytes.slice(0))\n }\n\n /** Returns true if `this` is equivalent to `other`. */\n equals(other: UUID): boolean {\n return this.compareTo(other) === 0\n }\n\n /**\n * Returns a negative integer, zero, or positive integer if `this` is less\n * than, equal to, or greater than `other`, respectively.\n */\n compareTo(other: UUID): number {\n for (let i = 0; i < 16; i++) {\n const diff = this.bytes[i] - other.bytes[i]\n if (diff !== 0) {\n return Math.sign(diff)\n }\n }\n return 0\n }\n}\n\n/** Encapsulates the monotonic counter state. */\nclass V7Generator {\n private _timestamp = 0\n private _counter = 0\n private readonly _random = new DefaultRandom()\n\n /**\n * Generates a new UUIDv7 object from the current timestamp, or resets the\n * generator upon significant timestamp rollback.\n *\n * This method returns monotonically increasing UUIDs unless the up-to-date\n * timestamp is significantly (by ten seconds or more) smaller than the one\n * embedded in the immediately preceding UUID. If such a significant clock\n * rollback is detected, this method resets the generator and returns a new\n * UUID based on the current timestamp.\n */\n generate(): UUID {\n const value = this.generateOrAbort()\n if (!isUndefined(value)) {\n return value\n } else {\n // reset state and resume\n this._timestamp = 0\n const valueAfterReset = this.generateOrAbort()\n if (isUndefined(valueAfterReset)) {\n throw new Error('Could not generate UUID after timestamp reset')\n }\n return valueAfterReset\n }\n }\n\n /**\n * Generates a new UUIDv7 object from the current timestamp, or returns\n * `undefined` upon significant timestamp rollback.\n *\n * This method returns monotonically increasing UUIDs unless the up-to-date\n * timestamp is significantly (by ten seconds or more) smaller than the one\n * embedded in the immediately preceding UUID. If such a significant clock\n * rollback is detected, this method aborts and returns `undefined`.\n */\n generateOrAbort(): UUID | undefined {\n const MAX_COUNTER = 0x3ff_ffff_ffff\n const ROLLBACK_ALLOWANCE = 10_000 // 10 seconds\n\n const ts = Date.now()\n if (ts > this._timestamp) {\n this._timestamp = ts\n this._resetCounter()\n } else if (ts + ROLLBACK_ALLOWANCE > this._timestamp) {\n // go on with previous timestamp if new one is not much smaller\n this._counter++\n if (this._counter > MAX_COUNTER) {\n // increment timestamp at counter overflow\n this._timestamp++\n this._resetCounter()\n }\n } else {\n // abort if clock went backwards to unbearable extent\n return undefined\n }\n\n return UUID.fromFieldsV7(\n this._timestamp,\n Math.trunc(this._counter / 2 ** 30),\n this._counter & (2 ** 30 - 1),\n this._random.nextUint32()\n )\n }\n\n /** Initializes the counter at a 42-bit random integer. */\n private _resetCounter(): void {\n this._counter = this._random.nextUint32() * 0x400 + (this._random.nextUint32() & 0x3ff)\n }\n}\n\n/** A global flag to force use of cryptographically strong RNG. */\ndeclare const UUIDV7_DENY_WEAK_RNG: boolean\n\n/** Stores `crypto.getRandomValues()` available in the environment. */\nlet getRandomValues: <T extends Uint8Array | Uint32Array>(buffer: T) => T = (buffer) => {\n // fall back on Math.random() unless the flag is set to true\n // TRICKY: don't use the isUndefined method here as can't pass the reference\n if (typeof UUIDV7_DENY_WEAK_RNG !== 'undefined' && UUIDV7_DENY_WEAK_RNG) {\n throw new Error('no cryptographically strong RNG available')\n }\n\n for (let i = 0; i < buffer.length; i++) {\n buffer[i] = Math.trunc(Math.random() * 0x1_0000) * 0x1_0000 + Math.trunc(Math.random() * 0x1_0000)\n }\n return buffer\n}\n\n// detect Web Crypto API\nif (window && !isUndefined(window.crypto) && crypto.getRandomValues) {\n getRandomValues = (buffer) => crypto.getRandomValues(buffer)\n}\n\n/**\n * Wraps `crypto.getRandomValues()` and compatibles to enable buffering; this\n * uses a small buffer by default to avoid unbearable throughput decline in some\n * environments as well as the waste of time and space for unused values.\n */\nclass DefaultRandom {\n private readonly _buffer = new Uint32Array(8)\n private _cursor = Infinity\n nextUint32(): number {\n if (this._cursor >= this._buffer.length) {\n getRandomValues(this._buffer)\n this._cursor = 0\n }\n return this._buffer[this._cursor++]\n }\n}\n\nlet defaultGenerator: V7Generator | undefined\n\n/**\n * Generates a UUIDv7 string.\n *\n * @returns The 8-4-4-4-12 canonical hexadecimal string representation\n * (\"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\").\n */\nexport const uuidv7 = (): string => uuidv7obj().toString()\n\n/** Generates a UUIDv7 object. */\nconst uuidv7obj = (): UUID => (defaultGenerator || (defaultGenerator = new V7Generator())).generate()\n\nexport const uuid7ToTimestampMs = (uuid: string): number => {\n // remove hyphens\n const hex = uuid.replace(/-/g, '')\n // ensure that it's a version 7 UUID\n if (hex.length !== 32) {\n throw new Error('Not a valid UUID')\n }\n if (hex[12] !== '7') {\n throw new Error('Not a UUIDv7')\n }\n // the first 6 bytes are the timestamp, which means that we can read only the first 12 hex characters\n return parseInt(hex.substring(0, 12), 16)\n}\n","export const isValidRegex = function (str: string): boolean {\n try {\n new RegExp(str)\n } catch {\n return false\n }\n return true\n}\n\nexport const isMatchingRegex = function (value: string, pattern: string): boolean {\n if (!isValidRegex(pattern)) return false\n\n try {\n return new RegExp(pattern).test(value)\n } catch {\n return false\n }\n}\n","import { isArray, isNull, isUndefined } from '@posthog/core'\nimport { jsonStringify } from '../request'\nimport { PropertyFilters, PropertyOperator } from '../posthog-surveys-types'\nimport type { Properties, SessionRecordingTriggerPropertyFilter } from '../types'\nimport { isMatchingRegex } from './regex-utils'\n\nexport function getPersonPropertiesHash(\n distinct_id: string,\n userPropertiesToSet?: Properties,\n userPropertiesToSetOnce?: Properties\n): string {\n return jsonStringify({ distinct_id, userPropertiesToSet, userPropertiesToSetOnce })\n}\n\nexport const propertyComparisons: Record<PropertyOperator, (targets: string[], values: string[]) => boolean> = {\n exact: (targets, values) => values.some((value) => targets.some((target) => value === target)),\n is_not: (targets, values) => values.every((value) => targets.every((target) => value !== target)),\n regex: (targets, values) => values.some((value) => targets.some((target) => isMatchingRegex(value, target))),\n not_regex: (targets, values) => values.every((value) => targets.every((target) => !isMatchingRegex(value, target))),\n icontains: (targets, values) =>\n values.map(toLowerCase).some((value) => targets.map(toLowerCase).some((target) => value.includes(target))),\n not_icontains: (targets, values) =>\n values.map(toLowerCase).every((value) => targets.map(toLowerCase).every((target) => !value.includes(target))),\n gt: (targets, values) =>\n values.some((value) => {\n const numValue = parseFloat(value)\n return !isNaN(numValue) && targets.some((t) => numValue > parseFloat(t))\n }),\n lt: (targets, values) =>\n values.some((value) => {\n const numValue = parseFloat(value)\n return !isNaN(numValue) && targets.some((t) => numValue < parseFloat(t))\n }),\n}\n\nconst toLowerCase = (v: string): string => v.toLowerCase()\n\n// Operators whose semantics mean \"property is not X\". When the property being\n// filtered on is missing or null, these match — absence of the property\n// satisfies a \"not equal to X\" check. This aligns with how PostHog's feature\n// flag matchers (posthog/queries/base.py, rust/feature-flags) treat missing\n// properties for negative operators.\nconst NEGATIVE_OPERATORS: ReadonlySet<string> = new Set(['is_not', 'not_icontains', 'not_regex'])\n\n/**\n * Evaluate trigger property filters (WHERE clauses) against event and person properties.\n * All filters must match (implicit AND). Returns true if no filters are present.\n */\nexport function matchTriggerPropertyFilters(\n filters: SessionRecordingTriggerPropertyFilter[] | undefined,\n eventProperties: Properties | undefined,\n personProperties: Properties | undefined\n): boolean {\n if (!filters || filters.length === 0) {\n return true\n }\n\n return filters.every((filter) => {\n const source = filter.type === 'person' ? personProperties : eventProperties\n const propertyValue = source?.[filter.key]\n const operator = filter.operator || 'exact'\n\n // Missing or null property: for negative operators, absence counts as a\n // match (nothing can't equal EU, so \"is_not EU\" is satisfied). For\n // positive operators, we can't confirm a match without a value.\n if (isUndefined(propertyValue) || isNull(propertyValue)) {\n return NEGATIVE_OPERATORS.has(operator)\n }\n\n const comparisonFunction = propertyComparisons[operator as PropertyOperator]\n if (!comparisonFunction) {\n return false\n }\n\n if (isUndefined(filter.value) || isNull(filter.value)) {\n return false\n }\n\n // Normalize filter value and property value to string arrays for comparison\n const targetValues = isArray(filter.value) ? filter.value.map(String) : [String(filter.value)]\n const actualValues = isArray(propertyValue) ? propertyValue.map(String) : [String(propertyValue)]\n\n return comparisonFunction(targetValues, actualValues)\n })\n}\n\nexport function matchPropertyFilters(\n propertyFilters: PropertyFilters | undefined,\n eventProperties: Properties | undefined\n): boolean {\n // if there are no property filters, it means we're only matching on event name\n if (!propertyFilters) {\n return true\n }\n\n return Object.entries(propertyFilters).every(([propertyName, filter]) => {\n const eventPropertyValue = eventProperties?.[propertyName]\n\n if (isUndefined(eventPropertyValue) || isNull(eventPropertyValue)) {\n return false\n }\n\n // convert event property to string array for comparison\n const eventValues = [String(eventPropertyValue)]\n\n const comparisonFunction = propertyComparisons[filter.operator]\n if (!comparisonFunction) {\n return false\n }\n\n return comparisonFunction(filter.values, eventValues)\n })\n}\n","import { extend } from './utils'\nimport { PersistentStore, Properties } from './types'\nimport {\n DEVICE_ID,\n DISTINCT_ID,\n ENABLE_PERSON_PROCESSING,\n INITIAL_PERSON_INFO,\n SESSION_ID,\n SESSION_RECORDING_IS_SAMPLED,\n USER_STATE,\n} from './constants'\n\nimport { isNull, isUndefined } from '@posthog/core'\nimport { logger } from './utils/logger'\nimport { window, document } from './utils/globals'\nimport { uuidv7 } from './uuidv7'\n\n// we store the discovered subdomain in memory because it might be read multiple times\nlet firstNonPublicSubDomain = ''\n\n// helper to allow tests to clear this \"cache\"\nexport const resetSubDomainCache = () => {\n firstNonPublicSubDomain = ''\n}\n\n/**\n * Browsers don't offer a way to check if something is a public suffix\n * e.g. `.com.au`, `.io`, `.org.uk`\n *\n * But they do reject cookies set on public suffixes\n * Setting a cookie on `.co.uk` would mean it was sent for every `.co.uk` site visited\n *\n * So, we can use this to check if a domain is a public suffix\n * by trying to set a cookie on a subdomain of the provided hostname\n * until the browser accepts it\n *\n * inspired by https://github.com/AngusFu/browser-root-domain\n */\nexport function seekFirstNonPublicSubDomain(hostname: string, cookieJar = document): string {\n if (firstNonPublicSubDomain) {\n return firstNonPublicSubDomain\n }\n\n if (!cookieJar) {\n return ''\n }\n if (['localhost', '127.0.0.1'].includes(hostname)) return ''\n\n const list = hostname.split('.')\n let len = Math.min(list.length, 8) // paranoia - we know this number should be small\n const key = 'dmn_chk_' + uuidv7()\n\n while (!firstNonPublicSubDomain && len--) {\n const candidate = list.slice(len).join('.')\n const candidateCookieValue = key + '=1;domain=.' + candidate + ';path=/'\n\n // try to set cookie, include a short expiry in seconds since we'll check immediately\n cookieJar.cookie = candidateCookieValue + ';max-age=3'\n\n if (cookieJar.cookie.includes(key)) {\n // the cookie was accepted by the browser, remove the test cookie\n cookieJar.cookie = candidateCookieValue + ';max-age=0'\n firstNonPublicSubDomain = candidate\n }\n }\n\n return firstNonPublicSubDomain\n}\n\nconst DOMAIN_MATCH_REGEX = /[a-z0-9][a-z0-9-]+\\.[a-z]{2,}$/i\nconst originalCookieDomainFn = (hostname: string): string => {\n const matches = hostname.match(DOMAIN_MATCH_REGEX)\n return matches ? matches[0] : ''\n}\n\nexport function chooseCookieDomain(hostname: string, cross_subdomain: boolean | undefined): string {\n if (cross_subdomain) {\n // NOTE: Could we use this for cross domain tracking?\n let matchedSubDomain = seekFirstNonPublicSubDomain(hostname)\n\n if (!matchedSubDomain) {\n const originalMatch = originalCookieDomainFn(hostname)\n if (originalMatch !== matchedSubDomain) {\n logger.info('Warning: cookie subdomain discovery mismatch', originalMatch, matchedSubDomain)\n }\n matchedSubDomain = originalMatch\n }\n\n return matchedSubDomain ? '; domain=.' + matchedSubDomain : ''\n }\n return ''\n}\n\n// Methods partially borrowed from quirksmode.org/js/cookies.html\nexport const cookieStore: PersistentStore = {\n _is_supported: () => !!document,\n\n _error: function (msg) {\n logger.error('cookieStore error: ' + msg)\n },\n\n _get: function (name) {\n if (!document) {\n return\n }\n\n try {\n const nameEQ = name + '='\n const ca = document.cookie.split(';').filter((x) => x.length)\n for (let i = 0; i < ca.length; i++) {\n let c = ca[i]\n while (c.charAt(0) == ' ') {\n c = c.substring(1, c.length)\n }\n if (c.indexOf(nameEQ) === 0) {\n return decodeURIComponent(c.substring(nameEQ.length, c.length))\n }\n }\n } catch {}\n return null\n },\n\n _parse: function (name) {\n let cookie\n try {\n cookie = JSON.parse(cookieStore._get(name)) || {}\n } catch {\n // noop\n }\n return cookie\n },\n\n _set: function (name, value, days, cross_subdomain, is_secure) {\n if (!document) {\n return false\n }\n try {\n let expires = '',\n secure = ''\n\n const cdomain = chooseCookieDomain(document.location.hostname, cross_subdomain)\n\n if (days) {\n const date = new Date()\n date.setTime(date.getTime() + days * 24 * 60 * 60 * 1000)\n expires = '; expires=' + date.toUTCString()\n }\n\n if (is_secure) {\n secure = '; secure'\n }\n\n const new_cookie_val =\n name +\n '=' +\n encodeURIComponent(JSON.stringify(value)) +\n expires +\n '; SameSite=Lax; path=/' +\n cdomain +\n secure\n\n // 4096 bytes is the size at which some browsers (e.g. firefox) will not store a cookie, warn slightly before that\n if (new_cookie_val.length > 4096 * 0.9) {\n logger.warn('cookieStore warning: large cookie, len=' + new_cookie_val.length)\n }\n\n document.cookie = new_cookie_val\n return true\n } catch {\n return false\n }\n },\n\n _remove: function (name, cross_subdomain) {\n if (!document?.cookie) {\n return\n }\n try {\n cookieStore._set(name, '', -1, cross_subdomain)\n } catch {\n return\n }\n },\n}\n\nlet _localStorage_supported: boolean | null = null\nexport const resetLocalStorageSupported = () => {\n _localStorage_supported = null\n}\n\nexport const localStore: PersistentStore = {\n _is_supported: function () {\n if (!isNull(_localStorage_supported)) {\n return _localStorage_supported\n }\n\n let supported = true\n if (!isUndefined(window)) {\n try {\n const key = '__mplssupport__',\n val = 'xyz'\n localStore._set(key, val)\n if (localStore._get(key) !== '\"xyz\"') {\n supported = false\n }\n localStore._remove(key)\n } catch {\n supported = false\n }\n } else {\n supported = false\n }\n if (!supported) {\n logger.error('localStorage unsupported; falling back to cookie store')\n }\n\n _localStorage_supported = supported\n return supported\n },\n\n _error: function (msg) {\n logger.error('localStorage error: ' + msg)\n },\n\n _get: function (name) {\n try {\n return window?.localStorage.getItem(name)\n } catch (err) {\n localStore._error(err)\n }\n return null\n },\n\n _parse: function (name) {\n try {\n return JSON.parse(localStore._get(name)) || {}\n } catch {\n // noop\n }\n return null\n },\n\n _set: function (name, value) {\n try {\n window?.localStorage.setItem(name, JSON.stringify(value))\n return true\n } catch (err) {\n localStore._error(err)\n }\n return false\n },\n\n _remove: function (name) {\n try {\n window?.localStorage.removeItem(name)\n } catch (err) {\n localStore._error(err)\n }\n },\n}\n\n// Use localstorage for most data but still use cookie for COOKIE_PERSISTED_PROPERTIES\n// This solves issues with cookies having too much data in them causing headers too large\n// Also makes sure we don't have to send a ton of data to the server\nconst COOKIE_PERSISTED_PROPERTIES = [\n DEVICE_ID,\n DISTINCT_ID,\n SESSION_ID,\n SESSION_RECORDING_IS_SAMPLED,\n ENABLE_PERSON_PROCESSING,\n INITIAL_PERSON_INFO,\n USER_STATE,\n]\n\n/**\n * Creates a localPlusCookieStore instance with custom cookie-persisted properties.\n *\n * When `preferCookieOnConflict` is true, the cookie's values win over localStorage on\n * merge for any key both stores carry. Null/empty cookie values are filtered out\n * before the merge so a malformed legacy cookie cannot override valid localStorage\n * data. localStorage-only keys are unaffected. See the docs for\n * `__preview_cookie_wins_on_conflict` for context.\n */\nexport const createLocalPlusCookieStore = (\n customCookieProperties: readonly string[] = [],\n preferCookieOnConflict: boolean = false\n): PersistentStore => {\n const cookiePropertiesToPersist = [...COOKIE_PERSISTED_PROPERTIES, ...customCookieProperties]\n\n return {\n ...localStore,\n _parse: function (name) {\n try {\n let cookieProperties: Properties = {}\n try {\n // See if there's a cookie stored with data.\n cookieProperties = cookieStore._parse(name) || {}\n } catch {}\n const localStorageData: Properties = JSON.parse(localStore._get(name) || '{}')\n let value: Properties\n if (preferCookieOnConflict) {\n // Defensive: skip null / empty-string cookie values so a malformed\n // legacy cookie cannot wipe out valid localStorage data.\n const safeCookieProperties: Properties = {}\n for (const key in cookieProperties) {\n const v = cookieProperties[key]\n if (!isNull(v) && v !== '') {\n safeCookieProperties[key] = v\n }\n }\n value = extend(localStorageData, safeCookieProperties)\n } else {\n value = extend(cookieProperties, localStorageData)\n }\n localStore._set(name, value)\n return value\n } catch {\n // noop\n }\n return null\n },\n\n _set: function (name, value, days, cross_subdomain, is_secure, debug) {\n // The localStorage write is the durable one and reports its own\n // success. The cookie mirror is best-effort: a cookie failure must\n // not flip an already-landed localStorage write to `false`, or the\n // caller would treat the durable entry as un-persisted and re-write\n // it on every later save.\n const stored = localStore._set(name, value, undefined, undefined, debug)\n try {\n const cookiePersistedProperties: Record<string, any> = {}\n cookiePropertiesToPersist.forEach((key) => {\n if (value[key]) {\n cookiePersistedProperties[key] = value[key]\n }\n })\n\n if (Object.keys(cookiePersistedProperties).length) {\n cookieStore._set(name, cookiePersistedProperties, days, cross_subdomain, is_secure, debug)\n }\n } catch (err) {\n localStore._error(err)\n }\n return stored\n },\n\n _remove: function (name, cross_subdomain) {\n try {\n window?.localStorage.removeItem(name)\n cookieStore._remove(name, cross_subdomain)\n } catch (err) {\n localStore._error(err)\n }\n },\n }\n}\n\nconst memoryStorage: Properties = {}\n\n// Storage that only lasts the length of the pageview if we don't want to use cookies\nexport const memoryStore: PersistentStore = {\n _is_supported: function () {\n return true\n },\n\n _error: function (msg) {\n logger.error('memoryStorage error: ' + msg)\n },\n\n _get: function (name) {\n return memoryStorage[name] || null\n },\n\n _parse: function (name) {\n return memoryStorage[name] || null\n },\n\n _set: function (name, value) {\n memoryStorage[name] = value\n return true\n },\n\n _remove: function (name) {\n delete memoryStorage[name]\n },\n}\n\nlet sessionStorageSupported: boolean | null = null\nexport const resetSessionStorageSupported = () => {\n sessionStorageSupported = null\n}\n// Storage that only lasts the length of a tab/window. Survives page refreshes\nexport const sessionStore: PersistentStore = {\n _is_supported: function () {\n if (!isNull(sessionStorageSupported)) {\n return sessionStorageSupported\n }\n sessionStorageSupported = true\n if (!isUndefined(window)) {\n try {\n const key = '__support__',\n val = 'xyz'\n sessionStore._set(key, val)\n if (sessionStore._get(key) !== '\"xyz\"') {\n sessionStorageSupported = false\n }\n sessionStore._remove(key)\n } catch {\n sessionStorageSupported = false\n }\n } else {\n sessionStorageSupported = false\n }\n return sessionStorageSupported\n },\n\n _error: function (msg) {\n logger.error('sessionStorage error: ', msg)\n },\n\n _get: function (name) {\n try {\n return window?.sessionStorage.getItem(name)\n } catch (err) {\n sessionStore._error(err)\n }\n return null\n },\n\n _parse: function (name) {\n try {\n return JSON.parse(sessionStore._get(name)) || null\n } catch {\n // noop\n }\n return null\n },\n\n _set: function (name, value) {\n try {\n window?.sessionStorage.setItem(name, JSON.stringify(value))\n return true\n } catch (err) {\n sessionStore._error(err)\n }\n return false\n },\n\n _remove: function (name) {\n try {\n window?.sessionStorage.removeItem(name)\n } catch (err) {\n sessionStore._error(err)\n }\n },\n}\n","import { PostHog } from '../../posthog-core'\nimport { createLogger } from '../../utils/logger'\n\nconst logger = createLogger('[Stylesheet Loader]')\n\nexport const prepareStylesheet = (document: Document, innerText: string, posthog?: PostHog) => {\n // Forcing the existence of `document` requires this function to be called in a browser environment\n let stylesheet: HTMLStyleElement | null = document.createElement('style')\n stylesheet.innerText = innerText\n\n if (posthog?.config?.prepare_external_dependency_stylesheet) {\n stylesheet = posthog.config.prepare_external_dependency_stylesheet(stylesheet)\n }\n\n if (!stylesheet) {\n logger.error('prepare_external_dependency_stylesheet returned null')\n return null\n }\n\n return stylesheet\n}\n","import { VNode, cloneElement, createContext, type JSX } from 'preact'\nimport { PostHog } from '../../posthog-core'\nimport {\n MultipleSurveyQuestion,\n Survey,\n SurveyAppearance,\n SurveyEventName,\n SurveyEventProperties,\n SurveyPosition,\n SurveyQuestion,\n SurveySchedule,\n SurveyType,\n SurveyWidgetType,\n} from '../../posthog-surveys-types'\nimport { document as _document, window as _window } from '../../utils/globals'\nimport {\n getSurveyInteractionProperty,\n getSurveySeenKey,\n getSurveyAbandonedKey,\n SURVEY_LOGGER as logger,\n setSurveySeenOnLocalStorage,\n SURVEY_IN_PROGRESS_PREFIX,\n} from '../../utils/survey-utils'\nimport { isNullish, type SurveyResponses } from '@posthog/core'\nimport { buildSurveyResponseProperties, getSurveyResponseKey, surveyHasResponses } from '@posthog/core/surveys'\n\nimport { propertyComparisons } from '../../utils/property-utils'\nimport { getTargetingUrl } from '../../utils/url-targeting-utils'\nimport { localStore } from '../../storage'\nimport { Properties, PropertyMatchType } from '../../types'\nimport { Z_INDEX_SURVEYS } from '../../constants'\nimport { prepareStylesheet } from '../utils/stylesheet-loader'\n// We cast the types here which is dangerous but protected by the top level generateSurveys call\nconst window = _window as Window & typeof globalThis\nconst document = _document as Document\nimport surveyStyles from './survey.css'\nimport { useContext } from 'preact/hooks'\nimport { doesDeviceTypeMatch, hasPeriodPassed } from '../utils/matcher-utils'\n\nexport function getFontFamily(fontFamily?: string): string {\n if (fontFamily === 'inherit') {\n return 'inherit'\n }\n\n const defaultFontStack =\n 'BlinkMacSystemFont, \"Inter\", \"Segoe UI\", \"Roboto\", Helvetica, Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\"'\n return fontFamily ? `${fontFamily}, ${defaultFontStack}` : `-apple-system, ${defaultFontStack}`\n}\n\nexport { getSurveyResponseKey }\n\nconst BLACK_TEXT_COLOR = '#020617' // Maps out to text-slate-950 from tailwind colors. Intended for text use outside interactive elements like buttons\n\n// Keep in sync with defaultSurveyAppearance on the main app\nexport const defaultSurveyAppearance = {\n fontFamily: 'inherit',\n backgroundColor: '#eeeded',\n submitButtonColor: 'black',\n submitButtonTextColor: 'white',\n ratingButtonColor: 'white',\n ratingButtonActiveColor: 'black',\n borderColor: '#c9c6c6',\n placeholder: 'Start typing...',\n whiteLabel: false,\n displayThankYouMessage: true,\n thankYouMessageHeader: 'Thank you for your feedback!',\n position: SurveyPosition.Right,\n widgetType: SurveyWidgetType.Tab,\n widgetLabel: 'Feedback',\n widgetColor: 'black',\n zIndex: String(Z_INDEX_SURVEYS),\n disabledButtonOpacity: '0.6',\n maxWidth: '300px',\n textSubtleColor: '#939393',\n boxPadding: '20px 24px',\n boxShadow: '0 4px 12px rgba(0, 0, 0, 0.15)',\n borderRadius: '10px',\n shuffleQuestions: false,\n surveyPopupDelaySeconds: undefined,\n // Not customizable atm\n outlineColor: 'rgba(59, 130, 246, 0.8)',\n inputBackground: 'white',\n inputTextColor: BLACK_TEXT_COLOR,\n scrollbarThumbColor: 'var(--ph-survey-border-color)',\n scrollbarTrackColor: 'var(--ph-survey-background-color)',\n} as const\n\nconst BOTTOM_BORDER_SURVEY_POSITIONS: SurveyPosition[] = [\n SurveyPosition.Center,\n SurveyPosition.Left,\n SurveyPosition.Right,\n]\n\nexport const addSurveyCSSVariablesToElement = (\n element: HTMLElement,\n type: SurveyType,\n appearance?: SurveyAppearance | null\n) => {\n const effectiveAppearance = { ...defaultSurveyAppearance, ...appearance }\n const hostStyle = element.style\n\n const surveyHasBottomBorder =\n !BOTTOM_BORDER_SURVEY_POSITIONS.includes(effectiveAppearance.position) ||\n (type === SurveyType.Widget && appearance?.widgetType === SurveyWidgetType.Tab)\n\n hostStyle.setProperty('--ph-survey-font-family', getFontFamily(effectiveAppearance.fontFamily))\n hostStyle.setProperty('--ph-survey-box-padding', effectiveAppearance.boxPadding)\n hostStyle.setProperty('--ph-survey-max-width', effectiveAppearance.maxWidth)\n hostStyle.setProperty('--ph-survey-z-index', effectiveAppearance.zIndex)\n hostStyle.setProperty('--ph-survey-border-color', effectiveAppearance.borderColor)\n // Non-bottom surveys or tab surveys have the border bottom\n if (surveyHasBottomBorder) {\n hostStyle.setProperty('--ph-survey-border-radius', effectiveAppearance.borderRadius)\n hostStyle.setProperty('--ph-survey-border-bottom', '1.5px solid var(--ph-survey-border-color)')\n } else {\n hostStyle.setProperty('--ph-survey-border-bottom', 'none')\n hostStyle.setProperty(\n '--ph-survey-border-radius',\n `${effectiveAppearance.borderRadius} ${effectiveAppearance.borderRadius} 0 0`\n )\n }\n hostStyle.setProperty('--ph-survey-background-color', effectiveAppearance.backgroundColor)\n hostStyle.setProperty('--ph-survey-box-shadow', effectiveAppearance.boxShadow)\n hostStyle.setProperty('--ph-survey-disabled-button-opacity', effectiveAppearance.disabledButtonOpacity)\n hostStyle.setProperty('--ph-survey-submit-button-color', effectiveAppearance.submitButtonColor)\n hostStyle.setProperty(\n '--ph-survey-submit-button-text-color',\n appearance?.submitButtonTextColor || getContrastingTextColor(effectiveAppearance.submitButtonColor)\n )\n hostStyle.setProperty('--ph-survey-rating-bg-color', effectiveAppearance.ratingButtonColor)\n hostStyle.setProperty('--ph-survey-rating-active-bg-color', effectiveAppearance.ratingButtonActiveColor)\n // Active rating text is always auto-calculated for contrast with active background\n hostStyle.setProperty(\n '--ph-survey-rating-active-text-color',\n getContrastingTextColor(effectiveAppearance.ratingButtonActiveColor)\n )\n // Primary text color: use override if provided, otherwise auto-calculate from background\n hostStyle.setProperty(\n '--ph-survey-text-primary-color',\n appearance?.textColor || getContrastingTextColor(effectiveAppearance.backgroundColor)\n )\n hostStyle.setProperty('--ph-survey-text-subtle-color', effectiveAppearance.textSubtleColor)\n hostStyle.setProperty('--ph-widget-color', effectiveAppearance.widgetColor)\n hostStyle.setProperty('--ph-widget-text-color', getContrastingTextColor(effectiveAppearance.widgetColor))\n hostStyle.setProperty('--ph-widget-z-index', effectiveAppearance.zIndex)\n\n // Use user-provided inputBackground (or deprecated inputBackgroundColor for backwards compat)\n // Fallback to internal default, with slight adjustment for white backgrounds\n const userInputBg = appearance?.inputBackground || appearance?.inputBackgroundColor\n let inputBgColor = userInputBg || effectiveAppearance.inputBackground\n if (!userInputBg && effectiveAppearance.backgroundColor === 'white') {\n inputBgColor = '#f8f8f8'\n }\n hostStyle.setProperty('--ph-survey-input-background', inputBgColor)\n // Input text color applies to both text inputs and inactive rating buttons\n const inputTextColor = appearance?.inputTextColor || getContrastingTextColor(inputBgColor)\n hostStyle.setProperty('--ph-survey-input-text-color', inputTextColor)\n hostStyle.setProperty('--ph-survey-rating-text-color', inputTextColor)\n hostStyle.setProperty('--ph-survey-scrollbar-thumb-color', effectiveAppearance.scrollbarThumbColor)\n hostStyle.setProperty('--ph-survey-scrollbar-track-color', effectiveAppearance.scrollbarTrackColor)\n hostStyle.setProperty('--ph-survey-outline-color', effectiveAppearance.outlineColor)\n}\n\nfunction nameToHex(name: string) {\n return {\n aliceblue: '#f0f8ff',\n antiquewhite: '#faebd7',\n aqua: '#00ffff',\n aquamarine: '#7fffd4',\n azure: '#f0ffff',\n beige: '#f5f5dc',\n bisque: '#ffe4c4',\n black: '#000000',\n blanchedalmond: '#ffebcd',\n blue: '#0000ff',\n blueviolet: '#8a2be2',\n brown: '#a52a2a',\n burlywood: '#deb887',\n cadetblue: '#5f9ea0',\n chartreuse: '#7fff00',\n chocolate: '#d2691e',\n coral: '#ff7f50',\n cornflowerblue: '#6495ed',\n cornsilk: '#fff8dc',\n crimson: '#dc143c',\n cyan: '#00ffff',\n darkblue: '#00008b',\n darkcyan: '#008b8b',\n darkgoldenrod: '#b8860b',\n darkgray: '#a9a9a9',\n darkgreen: '#006400',\n darkkhaki: '#bdb76b',\n darkmagenta: '#8b008b',\n darkolivegreen: '#556b2f',\n darkorange: '#ff8c00',\n darkorchid: '#9932cc',\n darkred: '#8b0000',\n darksalmon: '#e9967a',\n darkseagreen: '#8fbc8f',\n darkslateblue: '#483d8b',\n darkslategray: '#2f4f4f',\n darkturquoise: '#00ced1',\n darkviolet: '#9400d3',\n deeppink: '#ff1493',\n deepskyblue: '#00bfff',\n dimgray: '#696969',\n dodgerblue: '#1e90ff',\n firebrick: '#b22222',\n floralwhite: '#fffaf0',\n forestgreen: '#228b22',\n fuchsia: '#ff00ff',\n gainsboro: '#dcdcdc',\n ghostwhite: '#f8f8ff',\n gold: '#ffd700',\n goldenrod: '#daa520',\n gray: '#808080',\n green: '#008000',\n greenyellow: '#adff2f',\n honeydew: '#f0fff0',\n hotpink: '#ff69b4',\n 'indianred ': '#cd5c5c',\n indigo: '#4b0082',\n ivory: '#fffff0',\n khaki: '#f0e68c',\n lavender: '#e6e6fa',\n lavenderblush: '#fff0f5',\n lawngreen: '#7cfc00',\n lemonchiffon: '#fffacd',\n lightblue: '#add8e6',\n lightcoral: '#f08080',\n lightcyan: '#e0ffff',\n lightgoldenrodyellow: '#fafad2',\n lightgrey: '#d3d3d3',\n lightgreen: '#90ee90',\n lightpink: '#ffb6c1',\n lightsalmon: '#ffa07a',\n lightseagreen: '#20b2aa',\n lightskyblue: '#87cefa',\n lightslategray: '#778899',\n lightsteelblue: '#b0c4de',\n lightyellow: '#ffffe0',\n lime: '#00ff00',\n limegreen: '#32cd32',\n linen: '#faf0e6',\n magenta: '#ff00ff',\n maroon: '#800000',\n mediumaquamarine: '#66cdaa',\n mediumblue: '#0000cd',\n mediumorchid: '#ba55d3',\n mediumpurple: '#9370d8',\n mediumseagreen: '#3cb371',\n mediumslateblue: '#7b68ee',\n mediumspringgreen: '#00fa9a',\n mediumturquoise: '#48d1cc',\n mediumvioletred: '#c71585',\n midnightblue: '#191970',\n mintcream: '#f5fffa',\n mistyrose: '#ffe4e1',\n moccasin: '#ffe4b5',\n navajowhite: '#ffdead',\n navy: '#000080',\n oldlace: '#fdf5e6',\n olive: '#808000',\n olivedrab: '#6b8e23',\n orange: '#ffa500',\n orangered: '#ff4500',\n orchid: '#da70d6',\n palegoldenrod: '#eee8aa',\n palegreen: '#98fb98',\n paleturquoise: '#afeeee',\n palevioletred: '#d87093',\n papayawhip: '#ffefd5',\n peachpuff: '#ffdab9',\n peru: '#cd853f',\n pink: '#ffc0cb',\n plum: '#dda0dd',\n powderblue: '#b0e0e6',\n purple: '#800080',\n red: '#ff0000',\n rosybrown: '#bc8f8f',\n royalblue: '#4169e1',\n saddlebrown: '#8b4513',\n salmon: '#fa8072',\n sandybrown: '#f4a460',\n seagreen: '#2e8b57',\n seashell: '#fff5ee',\n sienna: '#a0522d',\n silver: '#c0c0c0',\n skyblue: '#87ceeb',\n slateblue: '#6a5acd',\n slategray: '#708090',\n snow: '#fffafa',\n springgreen: '#00ff7f',\n steelblue: '#4682b4',\n tan: '#d2b48c',\n teal: '#008080',\n thistle: '#d8bfd8',\n tomato: '#ff6347',\n turquoise: '#40e0d0',\n violet: '#ee82ee',\n wheat: '#f5deb3',\n white: '#ffffff',\n whitesmoke: '#f5f5f5',\n yellow: '#ffff00',\n yellowgreen: '#9acd32',\n }[name.toLowerCase()]\n}\n\nexport function hex2rgb(c: string): string {\n if (c.startsWith('#')) {\n let hexColor = c.replace(/^#/, '')\n // Handle 3-character shorthand (e.g., #111 -> #111111, #abc -> #aabbcc)\n if (/^[0-9A-Fa-f]{3}$/.test(hexColor)) {\n hexColor = hexColor[0] + hexColor[0] + hexColor[1] + hexColor[1] + hexColor[2] + hexColor[2]\n }\n if (!/^[0-9A-Fa-f]{6}$/.test(hexColor)) {\n return 'rgb(255, 255, 255)'\n }\n const r = parseInt(hexColor.slice(0, 2), 16)\n const g = parseInt(hexColor.slice(2, 4), 16)\n const b = parseInt(hexColor.slice(4, 6), 16)\n return `rgb(${r},${g},${b})`\n }\n return 'rgb(255, 255, 255)'\n}\n\nexport function hexToRgba(hex: string, opacity: number): string {\n const rgb = hex2rgb(hex)\n const match = rgb.match(/^rgb\\((\\d+),(\\d+),(\\d+)\\)$/)\n if (!match) {\n return hex\n }\n return `rgba(${match[1]}, ${match[2]}, ${match[3]}, ${opacity})`\n}\n\nexport function getContrastingTextColor(color: string = defaultSurveyAppearance.backgroundColor) {\n let rgb\n if (color[0] === '#') {\n rgb = hex2rgb(color)\n }\n if (color.startsWith('rgb')) {\n rgb = color\n }\n // otherwise it's a color name\n const nameColorToHex = nameToHex(color)\n if (nameColorToHex) {\n rgb = hex2rgb(nameColorToHex)\n }\n if (!rgb) {\n return BLACK_TEXT_COLOR\n }\n const colorMatch = rgb.match(/^rgba?\\((\\d+),\\s*(\\d+),\\s*(\\d+)(?:,\\s*(\\d+(?:\\.\\d+)?))?\\)$/)\n if (colorMatch) {\n const r = parseInt(colorMatch[1])\n const g = parseInt(colorMatch[2])\n const b = parseInt(colorMatch[3])\n const hsp = Math.sqrt(0.299 * (r * r) + 0.587 * (g * g) + 0.114 * (b * b))\n return hsp > 127.5 ? BLACK_TEXT_COLOR : 'white'\n }\n return BLACK_TEXT_COLOR\n}\n\nexport function getSurveyStylesheet(posthog?: PostHog) {\n const stylesheet = prepareStylesheet(document, typeof surveyStyles === 'string' ? surveyStyles : '', posthog)\n stylesheet?.setAttribute('data-ph-survey-style', 'true')\n return stylesheet\n}\n\nexport const retrieveSurveyShadow = (\n survey: Pick<Survey, 'id' | 'appearance' | 'type'>,\n posthog?: PostHog,\n element?: Element\n) => {\n const widgetClassName = getSurveyContainerClass(survey)\n const existingDiv = document.querySelector(`.${widgetClassName}`)\n\n if (existingDiv && existingDiv.shadowRoot) {\n return {\n shadow: existingDiv.shadowRoot,\n isNewlyCreated: false,\n }\n }\n\n // If it doesn't exist, create it\n const div = document.createElement('div')\n addSurveyCSSVariablesToElement(div, survey.type, survey.appearance)\n div.className = widgetClassName\n const shadow = div.attachShadow({ mode: 'open' })\n const stylesheet = getSurveyStylesheet(posthog)\n if (stylesheet) {\n const existingStylesheet = shadow.querySelector('style')\n if (existingStylesheet) {\n shadow.removeChild(existingStylesheet)\n }\n shadow.appendChild(stylesheet)\n }\n ;(element ? element : document.body).appendChild(div)\n return {\n shadow,\n isNewlyCreated: true,\n }\n}\n\ninterface SendSurveyEventArgs {\n responses: SurveyResponses\n survey: Survey\n surveySubmissionId: string\n isSurveyCompleted: boolean\n posthog?: PostHog\n /** Additional properties to include in the survey event */\n properties?: Properties\n /** The language that was applied to the survey. */\n surveyLanguage?: string | null\n}\n\nexport const sendSurveyEvent = ({\n responses,\n survey,\n surveySubmissionId,\n posthog,\n isSurveyCompleted,\n properties,\n surveyLanguage,\n}: SendSurveyEventArgs) => {\n if (!posthog) {\n logger.error('[survey sent] event not captured, PostHog instance not found.')\n return\n }\n setSurveySeenOnLocalStorage(survey)\n posthog.capture(SurveyEventName.SENT, {\n [SurveyEventProperties.SURVEY_NAME]: survey.name,\n [SurveyEventProperties.SURVEY_ID]: survey.id,\n [SurveyEventProperties.SURVEY_ITERATION]: survey.current_iteration,\n [SurveyEventProperties.SURVEY_ITERATION_START_DATE]: survey.current_iteration_start_date,\n [SurveyEventProperties.SURVEY_SUBMISSION_ID]: surveySubmissionId,\n [SurveyEventProperties.SURVEY_COMPLETED]: isSurveyCompleted,\n ...(surveyLanguage && { [SurveyEventProperties.SURVEY_LANGUAGE]: surveyLanguage }),\n sessionRecordingUrl: posthog.get_session_replay_url?.(),\n ...buildSurveyResponseProperties(responses, survey),\n ...properties,\n $set: {\n [getSurveyInteractionProperty(survey, 'responded')]: true,\n },\n })\n if (isSurveyCompleted) {\n // Only dispatch PHSurveySent if the survey is completed, as that removes the survey from focus\n window.dispatchEvent(new CustomEvent('PHSurveySent', { detail: { surveyId: survey.id } }))\n clearInProgressSurveyState(survey)\n }\n}\n\nconst _buildSurveyEventProperties = (\n survey: Survey,\n inProgressSurvey: InProgressSurveyState | null,\n posthog: PostHog\n) => ({\n [SurveyEventProperties.SURVEY_NAME]: survey.name,\n [SurveyEventProperties.SURVEY_ID]: survey.id,\n [SurveyEventProperties.SURVEY_ITERATION]: survey.current_iteration,\n [SurveyEventProperties.SURVEY_ITERATION_START_DATE]: survey.current_iteration_start_date,\n [SurveyEventProperties.SURVEY_PARTIALLY_COMPLETED]: surveyHasResponses(inProgressSurvey?.responses),\n ...(inProgressSurvey?.surveyLanguage && {\n [SurveyEventProperties.SURVEY_LANGUAGE]: inProgressSurvey.surveyLanguage,\n }),\n sessionRecordingUrl: posthog.get_session_replay_url?.(),\n [SurveyEventProperties.SURVEY_SUBMISSION_ID]: inProgressSurvey?.surveySubmissionId,\n ...buildSurveyResponseProperties(inProgressSurvey?.responses, survey),\n})\n\nexport const dismissedSurveyEvent = (\n survey: Survey,\n posthog?: PostHog,\n readOnly?: boolean,\n surveyLanguage?: string | null\n) => {\n if (!posthog) {\n logger.error('[survey dismissed] event not captured, PostHog instance not found.')\n return\n }\n if (readOnly) {\n return\n }\n\n const inProgressSurvey = getInProgressSurveyState(survey)\n posthog.capture(SurveyEventName.DISMISSED, {\n ..._buildSurveyEventProperties(survey, inProgressSurvey, posthog),\n ...(surveyLanguage && { [SurveyEventProperties.SURVEY_LANGUAGE]: surveyLanguage }),\n $set: {\n [getSurveyInteractionProperty(survey, 'dismissed')]: true,\n },\n })\n clearInProgressSurveyState(survey)\n setSurveySeenOnLocalStorage(survey)\n window.dispatchEvent(new CustomEvent('PHSurveyClosed', { detail: { surveyId: survey.id } }))\n}\n\nexport const sendSurveyAbandonedEvent = (survey: Survey, posthog?: PostHog) => {\n if (!posthog) {\n logger.error('[survey abandoned] event not captured, PostHog instance not found.')\n return\n }\n\n const abandonedKey = getSurveyAbandonedKey(survey)\n try {\n if (localStorage.getItem(abandonedKey) === 'true') {\n return\n }\n } catch {\n // localStorage not available\n return\n }\n\n const inProgressSurvey = getInProgressSurveyState(survey)\n if (!inProgressSurvey) {\n return\n }\n\n try {\n localStorage.setItem(abandonedKey, 'true')\n } catch {\n // localStorage not available\n }\n\n posthog.capture(SurveyEventName.ABANDONED, _buildSurveyEventProperties(survey, inProgressSurvey, posthog), {\n transport: 'sendBeacon',\n })\n}\n\n// Use the Fisher-yates algorithm to shuffle this array\n// https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle\nexport const shuffle = (array: any[]) => {\n return array\n .map((a) => ({ sort: Math.floor(Math.random() * 10), value: a }))\n .sort((a, b) => a.sort - b.sort)\n .map((a) => a.value)\n}\n\nconst reverseIfUnshuffled = (unshuffled: any[], shuffled: any[]): any[] => {\n if (unshuffled.length === shuffled.length && unshuffled.every((val, index) => val === shuffled[index])) {\n return shuffled.reverse()\n }\n\n return shuffled\n}\n\nexport const getDisplayOrderChoices = (question: MultipleSurveyQuestion): string[] => {\n if (!question.shuffleOptions) {\n return question.choices\n }\n\n const displayOrderChoices = question.choices\n let openEndedChoice = ''\n if (question.hasOpenChoice) {\n // if the question has an open-ended choice, its always the last element in the choices array.\n openEndedChoice = displayOrderChoices.pop()!\n }\n\n const shuffledOptions = reverseIfUnshuffled(displayOrderChoices, shuffle(displayOrderChoices))\n\n if (question.hasOpenChoice) {\n question.choices.push(openEndedChoice)\n shuffledOptions.push(openEndedChoice)\n }\n\n return shuffledOptions\n}\n\nexport const getDisplayOrderQuestions = (survey: Survey): SurveyQuestion[] => {\n if (!survey.appearance || !survey.appearance.shuffleQuestions || survey.enable_partial_responses) {\n return survey.questions\n }\n\n return reverseIfUnshuffled(survey.questions, shuffle(survey.questions))\n}\n\nexport const hasEvents = (survey: Pick<Survey, 'conditions'>): boolean => {\n return survey.conditions?.events?.values?.length != undefined && survey.conditions?.events?.values?.length > 0\n}\n\nexport const canActivateRepeatedly = (\n survey: Pick<Survey, 'schedule' | 'conditions' | 'id' | 'current_iteration'>\n): boolean => {\n return (\n !!(survey.conditions?.events?.repeatedActivation && hasEvents(survey)) ||\n survey.schedule === SurveySchedule.Always ||\n isSurveyInProgress(survey)\n )\n}\n\n/**\n * getSurveySeen checks local storage for the surveySeen Key a\n * and overrides this value if the survey can be repeatedly activated by its events.\n * @param survey\n */\nexport const getSurveySeen = (survey: Survey): boolean => {\n const surveySeen = localStore._get(getSurveySeenKey(survey))\n if (surveySeen) {\n // if a survey has already been seen,\n // we will override it with the event repeated activation value.\n return !canActivateRepeatedly(survey)\n }\n\n return false\n}\n\nconst LAST_SEEN_SURVEY_DATE_KEY = 'lastSeenSurveyDate'\n\nexport const hasWaitPeriodPassed = (waitPeriodInDays: number | undefined): boolean => {\n const lastSeenSurveyDate = localStore._get(LAST_SEEN_SURVEY_DATE_KEY)\n return hasPeriodPassed(waitPeriodInDays, lastSeenSurveyDate)\n}\n\ninterface SurveyContextProps {\n isPreviewMode: boolean\n previewPageIndex: number | undefined\n onPopupSurveyDismissed: () => void\n isPopup: boolean\n onPreviewSubmit: (res: string | string[] | number | null) => void\n onPreviewBack: () => void\n surveySubmissionId: string\n /** Additional properties to include in all survey events */\n properties?: Properties\n /** The language that was applied to the survey. */\n surveyLanguage?: string | null\n}\n\nexport const SurveyContext = createContext<SurveyContextProps>({\n isPreviewMode: false,\n previewPageIndex: 0,\n onPopupSurveyDismissed: () => {},\n isPopup: true,\n onPreviewSubmit: () => {},\n onPreviewBack: () => {},\n surveySubmissionId: '',\n properties: undefined,\n surveyLanguage: null,\n})\n\nexport const useSurveyContext = () => {\n return useContext(SurveyContext)\n}\n\ninterface RenderProps {\n component: VNode<{ className: string }>\n children: string\n renderAsHtml?: boolean\n style?: JSX.CSSProperties\n}\n\nexport const renderChildrenAsTextOrHtml = ({ component, children, renderAsHtml, style }: RenderProps) => {\n return renderAsHtml\n ? cloneElement(component, {\n dangerouslySetInnerHTML: { __html: children },\n style,\n })\n : cloneElement(component, {\n children,\n style,\n })\n}\n\nfunction defaultMatchType(matchType?: PropertyMatchType): PropertyMatchType {\n return matchType ?? 'icontains'\n}\n\n// use urlMatchType to validate url condition, fallback to contains for backwards compatibility\nexport function doesSurveyUrlMatch(survey: Pick<Survey, 'conditions'>, posthog?: PostHog): boolean {\n if (!survey.conditions?.url) {\n return true\n }\n // honors the `get_current_url` config hook so apps that rewrite their URL can target surveys correctly\n const href = getTargetingUrl(posthog)\n if (!href) {\n // if we dont know the url, assume it is not a match\n return false\n }\n const targets = [survey.conditions.url]\n const matchType = defaultMatchType(survey.conditions?.urlMatchType)\n return propertyComparisons[matchType](targets, [href])\n}\n\nexport function doesSurveyDeviceTypesMatch(survey: Survey): boolean {\n return doesDeviceTypeMatch(survey.conditions?.deviceTypes, survey.conditions?.deviceTypesMatchType)\n}\n\nexport function doesSurveyMatchSelector(survey: Survey): boolean {\n if (!survey.conditions?.selector) {\n return true\n }\n return !!document?.querySelector(survey.conditions.selector)\n}\n\ninterface InProgressSurveyState {\n surveySubmissionId: string\n lastQuestionIndex: number\n // Indices the respondent has visited, in order, excluding the current one. Pushed on next, popped on back.\n // Optional for backwards compat with state persisted before the back-navigation feature.\n visitedIndices?: number[]\n responses: SurveyResponses\n surveyLanguage?: string | null\n}\n\nconst getInProgressSurveyStateKey = (survey: Pick<Survey, 'id' | 'current_iteration'>): string => {\n let key = `${SURVEY_IN_PROGRESS_PREFIX}${survey.id}`\n if (survey.current_iteration && survey.current_iteration > 0) {\n key = `${SURVEY_IN_PROGRESS_PREFIX}${survey.id}_${survey.current_iteration}`\n }\n return key\n}\n\nexport const setInProgressSurveyState = (\n survey: Pick<Survey, 'id' | 'current_iteration'>,\n state: InProgressSurveyState\n): void => {\n try {\n localStorage.setItem(getInProgressSurveyStateKey(survey), JSON.stringify(state))\n } catch (e) {\n logger.error('Error setting in-progress survey state in localStorage', e)\n }\n}\n\nexport const getInProgressSurveyState = (\n survey: Pick<Survey, 'id' | 'current_iteration'>\n): InProgressSurveyState | null => {\n try {\n const stateString = localStorage.getItem(getInProgressSurveyStateKey(survey))\n if (stateString) {\n return JSON.parse(stateString) as InProgressSurveyState\n }\n } catch (e) {\n logger.error('Error getting in-progress survey state from localStorage', e)\n }\n return null\n}\n\nexport const isSurveyInProgress = (survey: Pick<Survey, 'id' | 'current_iteration'>): boolean => {\n const state = getInProgressSurveyState(survey)\n return !isNullish(state?.surveySubmissionId)\n}\n\nexport const clearInProgressSurveyState = (survey: Pick<Survey, 'id' | 'current_iteration'>): void => {\n try {\n localStorage.removeItem(getInProgressSurveyStateKey(survey))\n } catch (e) {\n logger.error('Error clearing in-progress survey state from localStorage', e)\n }\n}\n\nexport function getSurveyContainerClass(survey: Pick<Survey, 'id'>, asSelector = false): string {\n const className = `PostHogSurvey-${survey.id}`\n return asSelector ? `.${className}` : className\n}\n\n/**\n * Get CSS position styles for a popover/modal based on SurveyPosition\n * Used by both surveys and product tours for consistent positioning\n */\nexport function getPopoverPosition(\n type?: SurveyType,\n position: SurveyPosition = SurveyPosition.Right,\n surveyWidgetType?: SurveyWidgetType\n): Record<string, string> {\n if (type === SurveyType.ExternalSurvey) {\n return {}\n }\n\n switch (position) {\n case SurveyPosition.TopLeft:\n return { top: '0', left: '0', transform: 'translate(30px, 30px)' }\n case SurveyPosition.TopRight:\n return { top: '0', right: '0', transform: 'translate(-30px, 30px)' }\n case SurveyPosition.TopCenter:\n return { top: '0', left: '50%', transform: 'translate(-50%, 30px)' }\n case SurveyPosition.MiddleLeft:\n return { top: '50%', left: '0', transform: 'translate(30px, -50%)' }\n case SurveyPosition.MiddleRight:\n return { top: '50%', right: '0', transform: 'translate(-30px, -50%)' }\n case SurveyPosition.MiddleCenter:\n return { top: '50%', left: '50%', transform: 'translate(-50%, -50%)' }\n case SurveyPosition.Left:\n return { left: '30px' }\n case SurveyPosition.Center:\n return { left: '50%', transform: 'translateX(-50%)' }\n default:\n case SurveyPosition.Right:\n return { right: type === SurveyType.Widget && surveyWidgetType === SurveyWidgetType.Tab ? '60px' : '30px' }\n }\n}\n","import type { PostHog } from '../posthog-core'\nimport { window } from './globals'\nimport { isFunction, isString, isUndefined } from '@posthog/core'\nimport { logger } from './logger'\n\n/**\n * Applies the `get_current_url` config hook to an already-resolved URL. Returns `defaultUrl`\n * unchanged when no override is configured, or if the override throws or returns a\n * non-string/empty value.\n *\n * Use this when the caller already has its own URL source (e.g. web experiments read\n * `window.location` via a mockable indirection); otherwise prefer `getTargetingUrl`.\n */\nexport function applyUrlTargetingOverride(instance: PostHog | undefined, defaultUrl: string): string {\n const override = instance?.config?.get_current_url\n if (!isFunction(override)) {\n return defaultUrl\n }\n\n try {\n const result = override(defaultUrl)\n return isString(result) && result ? result : defaultUrl\n } catch (e) {\n logger.error('Error in get_current_url, falling back to window.location.href', e)\n return defaultUrl\n }\n}\n\n/**\n * Resolves the URL used for client-side URL targeting: session replay URL triggers, the\n * session replay URL blocklist, survey URL conditions, product tour URL conditions, and web\n * experiment URL conditions.\n *\n * Defaults to `window.location.href`, but honors the `get_current_url` config hook so apps\n * that rewrite their URL (e.g. Electron/desktop builds, or `$current_url` rewrites in\n * `before_send`) can make targeting match the logical URL instead of the raw browser URL.\n *\n * Returns `undefined` when there is no URL available (e.g. non-browser environments).\n *\n * Called on every rrweb event by the replay URL triggers/blocklist, so a configured\n * `get_current_url` override should stay cheap.\n */\nexport function getTargetingUrl(instance: PostHog | undefined): string | undefined {\n const defaultUrl = window?.location?.href\n return isUndefined(defaultUrl) ? undefined : applyUrlTargetingOverride(instance, defaultUrl)\n}\n","import { detectDeviceType } from '@posthog/core'\nimport { navigator, userAgent, window } from '../../utils/globals'\nimport { propertyComparisons } from '../../utils/property-utils'\nimport { PropertyMatchType } from '../../types'\n\nexport function doesDeviceTypeMatch(deviceTypes?: string[], matchType?: PropertyMatchType): boolean {\n if (!deviceTypes || deviceTypes.length === 0) {\n return true\n }\n if (!userAgent) {\n return false\n }\n const deviceType = detectDeviceType(userAgent, {\n // eslint-disable-next-line compat/compat\n userAgentDataPlatform: navigator?.userAgentData?.platform,\n maxTouchPoints: navigator?.maxTouchPoints,\n screenWidth: window?.screen?.width,\n screenHeight: window?.screen?.height,\n devicePixelRatio: window?.devicePixelRatio,\n })\n return propertyComparisons[matchType ?? 'icontains'](deviceTypes, [deviceType])\n}\n\nexport function hasPeriodPassed(periodDays?: number, lastSeenDate?: string | Date | null): boolean {\n if (!periodDays || !lastSeenDate) {\n return true\n }\n\n const date = typeof lastSeenDate === 'string' ? new Date(lastSeenDate) : lastSeenDate\n\n const now = new Date()\n const diffMs = Math.abs(now.getTime() - date.getTime())\n const diffDays = Math.ceil(diffMs / (1000 * 3600 * 24))\n return diffDays > periodDays\n}\n","export const satisfiedEmoji = (\n <svg className=\"emoji-svg\" xmlns=\"http://www.w3.org/2000/svg\" height=\"48\" viewBox=\"0 -960 960 960\" width=\"48\">\n <path d=\"M626-533q22.5 0 38.25-15.75T680-587q0-22.5-15.75-38.25T626-641q-22.5 0-38.25 15.75T572-587q0 22.5 15.75 38.25T626-533Zm-292 0q22.5 0 38.25-15.75T388-587q0-22.5-15.75-38.25T334-641q-22.5 0-38.25 15.75T280-587q0 22.5 15.75 38.25T334-533Zm146 272q66 0 121.5-35.5T682-393h-52q-23 40-63 61.5T480.5-310q-46.5 0-87-21T331-393h-53q26 61 81 96.5T480-261Zm0 181q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Zm0-400Zm0 340q142.375 0 241.188-98.812Q820-337.625 820-480t-98.812-241.188Q622.375-820 480-820t-241.188 98.812Q140-622.375 140-480t98.812 241.188Q337.625-140 480-140Z\" />\n </svg>\n)\nexport const neutralEmoji = (\n <svg className=\"emoji-svg\" xmlns=\"http://www.w3.org/2000/svg\" height=\"48\" viewBox=\"0 -960 960 960\" width=\"48\">\n <path d=\"M626-533q22.5 0 38.25-15.75T680-587q0-22.5-15.75-38.25T626-641q-22.5 0-38.25 15.75T572-587q0 22.5 15.75 38.25T626-533Zm-292 0q22.5 0 38.25-15.75T388-587q0-22.5-15.75-38.25T334-641q-22.5 0-38.25 15.75T280-587q0 22.5 15.75 38.25T334-533Zm20 194h253v-49H354v49ZM480-80q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Zm0-400Zm0 340q142.375 0 241.188-98.812Q820-337.625 820-480t-98.812-241.188Q622.375-820 480-820t-241.188 98.812Q140-622.375 140-480t98.812 241.188Q337.625-140 480-140Z\" />\n </svg>\n)\nexport const dissatisfiedEmoji = (\n <svg className=\"emoji-svg\" xmlns=\"http://www.w3.org/2000/svg\" height=\"48\" viewBox=\"0 -960 960 960\" width=\"48\">\n <path d=\"M626-533q22.5 0 38.25-15.75T680-587q0-22.5-15.75-38.25T626-641q-22.5 0-38.25 15.75T572-587q0 22.5 15.75 38.25T626-533Zm-292 0q22.5 0 38.25-15.75T388-587q0-22.5-15.75-38.25T334-641q-22.5 0-38.25 15.75T280-587q0 22.5 15.75 38.25T334-533Zm146.174 116Q413-417 358.5-379.5T278-280h53q22-42 62.173-65t87.5-23Q528-368 567.5-344.5T630-280h52q-25-63-79.826-100-54.826-37-122-37ZM480-80q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Zm0-400Zm0 340q142.375 0 241.188-98.812Q820-337.625 820-480t-98.812-241.188Q622.375-820 480-820t-241.188 98.812Q140-622.375 140-480t98.812 241.188Q337.625-140 480-140Z\" />\n </svg>\n)\nexport const veryDissatisfiedEmoji = (\n <svg className=\"emoji-svg\" xmlns=\"http://www.w3.org/2000/svg\" height=\"48\" viewBox=\"0 -960 960 960\" width=\"48\">\n <path d=\"M480-417q-67 0-121.5 37.5T278-280h404q-25-63-80-100t-122-37Zm-183-72 50-45 45 45 31-36-45-45 45-45-31-36-45 45-50-45-31 36 45 45-45 45 31 36Zm272 0 44-45 51 45 31-36-45-45 45-45-31-36-51 45-44-45-31 36 44 45-44 45 31 36ZM480-80q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Zm0-400Zm0 340q142 0 241-99t99-241q0-142-99-241t-241-99q-142 0-241 99t-99 241q0 142 99 241t241 99Z\" />\n </svg>\n)\nexport const verySatisfiedEmoji = (\n <svg className=\"emoji-svg\" xmlns=\"http://www.w3.org/2000/svg\" height=\"48\" viewBox=\"0 -960 960 960\" width=\"48\">\n <path d=\"M479.504-261Q537-261 585.5-287q48.5-26 78.5-72.4 6-11.6-.75-22.6-6.75-11-20.25-11H316.918Q303-393 296.5-382t-.5 22.6q30 46.4 78.5 72.4 48.5 26 105.004 26ZM347-578l27 27q7.636 8 17.818 8Q402-543 410-551q8-8 8-18t-8-18l-42-42q-8.8-9-20.9-9-12.1 0-21.1 9l-42 42q-8 7.636-8 17.818Q276-559 284-551q8 8 18 8t18-8l27-27Zm267 0 27 27q7.714 8 18 8t18-8q8-7.636 8-17.818Q685-579 677-587l-42-42q-8.8-9-20.9-9-12.1 0-21.1 9l-42 42q-8 7.714-8 18t8 18q7.636 8 17.818 8Q579-543 587-551l27-27ZM480-80q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Zm0-400Zm0 340q142.375 0 241.188-98.812Q820-337.625 820-480t-98.812-241.188Q622.375-820 480-820t-241.188 98.812Q140-622.375 140-480t98.812 241.188Q337.625-140 480-140Z\" />\n </svg>\n)\nexport const thumbsUpEmoji = (\n <svg className=\"emoji-svg\" xmlns=\"http://www.w3.org/2000/svg\" height=\"48\" viewBox=\"0 0 24 24\" width=\"48\">\n <path d=\"M2 20h2c.55 0 1-.45 1-1v-9c0-.55-.45-1-1-1H2v11zm19.83-7.12c.11-.25.17-.52.17-.8V11c0-1.1-.9-2-2-2h-5.5l.92-4.65c.05-.22.02-.46-.08-.66-.23-.45-.52-.86-.88-1.22L14 2 7.59 8.41C7.21 8.79 7 9.3 7 9.83v7.84C7 18.95 8.05 20 9.34 20h8.11c.7 0 1.36-.37 1.72-.97l2.66-6.15z\" />\n </svg>\n)\nexport const thumbsDownEmoji = (\n <svg className=\"emoji-svg\" xmlns=\"http://www.w3.org/2000/svg\" height=\"48\" viewBox=\"0 0 24 24\" width=\"48\">\n <path d=\"M22 4h-2c-.55 0-1 .45-1 1v9c0 .55.45 1 1 1h2V4zM2.17 11.12c-.11.25-.17.52-.17.8V13c0 1.1.9 2 2 2h5.5l-.92 4.65c-.05.22-.02.46.08.66.23.45.52.86.88 1.22L10 22l6.41-6.41c.38-.38.59-.89.59-1.42V6.34C17 5.05 15.95 4 14.66 4H6.55c-.7 0-1.36.37-1.72.97l-2.66 6.15z\" />\n </svg>\n)\nexport const cancelSVG = ({ fill = 'currentColor' }: { fill?: string } = {}) => (\n <svg\n width=\"12\"\n height=\"12\"\n viewBox=\"0 0 12 12\"\n fill={fill}\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-labelledby=\"close-survey-title-adam\"\n >\n <title id=\"close-survey-title\" className=\"adam-testing\">\n Close survey\n </title>\n <path\n fill-rule=\"evenodd\"\n clip-rule=\"evenodd\"\n d=\"M0.164752 0.164752C0.384422 -0.0549175 0.740578 -0.0549175 0.960248 0.164752L6 5.20451L11.0398 0.164752C11.2594 -0.0549175 11.6156 -0.0549175 11.8352 0.164752C12.0549 0.384422 12.0549 0.740578 11.8352 0.960248L6.79549 6L11.8352 11.0398C12.0549 11.2594 12.0549 11.6156 11.8352 11.8352C11.6156 12.0549 11.2594 12.0549 11.0398 11.8352L6 6.79549L0.960248 11.8352C0.740578 12.0549 0.384422 12.0549 0.164752 11.8352C-0.0549175 11.6156 -0.0549175 11.2594 0.164752 11.0398L5.20451 6L0.164752 0.960248C-0.0549175 0.740578 -0.0549175 0.384422 0.164752 0.164752Z\"\n fill={fill}\n />\n </svg>\n)\nexport const IconPosthogLogo = (\n <svg width=\"77\" height=\"14\" viewBox=\"0 0 77 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <g clip-path=\"url(#clip0_2415_6911)\">\n <mask\n id=\"mask0_2415_6911\"\n style={{ maskType: 'luminance' }}\n maskUnits=\"userSpaceOnUse\"\n x=\"0\"\n y=\"0\"\n width=\"77\"\n height=\"14\"\n >\n <path d=\"M0.5 0H76.5V14H0.5V0Z\" fill=\"white\" />\n </mask>\n <g mask=\"url(#mask0_2415_6911)\">\n <path\n d=\"M5.77226 8.02931C5.59388 8.37329 5.08474 8.37329 4.90634 8.02931L4.4797 7.20672C4.41155 7.07535 4.41155 6.9207 4.4797 6.78933L4.90634 5.96669C5.08474 5.62276 5.59388 5.62276 5.77226 5.96669L6.19893 6.78933C6.26709 6.9207 6.26709 7.07535 6.19893 7.20672L5.77226 8.02931ZM5.77226 12.6946C5.59388 13.0386 5.08474 13.0386 4.90634 12.6946L4.4797 11.872C4.41155 11.7406 4.41155 11.586 4.4797 11.4546L4.90634 10.632C5.08474 10.288 5.59388 10.288 5.77226 10.632L6.19893 11.4546C6.26709 11.586 6.26709 11.7406 6.19893 11.872L5.77226 12.6946Z\"\n fill=\"#1D4AFF\"\n />\n <path\n d=\"M0.5 10.9238C0.5 10.508 1.02142 10.2998 1.32637 10.5938L3.54508 12.7327C3.85003 13.0267 3.63405 13.5294 3.20279 13.5294H0.984076C0.716728 13.5294 0.5 13.3205 0.5 13.0627V10.9238ZM0.5 8.67083C0.5 8.79459 0.551001 8.91331 0.641783 9.00081L5.19753 13.3927C5.28831 13.4802 5.41144 13.5294 5.53982 13.5294H8.0421C8.47337 13.5294 8.68936 13.0267 8.3844 12.7327L1.32637 5.92856C1.02142 5.63456 0.5 5.84278 0.5 6.25854V8.67083ZM0.5 4.00556C0.5 4.12932 0.551001 4.24802 0.641783 4.33554L10.0368 13.3927C10.1276 13.4802 10.2508 13.5294 10.3791 13.5294H12.8814C13.3127 13.5294 13.5287 13.0267 13.2237 12.7327L1.32637 1.26329C1.02142 0.969312 0.5 1.17752 0.5 1.59327V4.00556ZM5.33931 4.00556C5.33931 4.12932 5.39033 4.24802 5.4811 4.33554L14.1916 12.7327C14.4965 13.0267 15.0179 12.8185 15.0179 12.4028V9.99047C15.0179 9.86671 14.9669 9.74799 14.8762 9.66049L6.16568 1.26329C5.86071 0.969307 5.33931 1.17752 5.33931 1.59327V4.00556ZM11.005 1.26329C10.7 0.969307 10.1786 1.17752 10.1786 1.59327V4.00556C10.1786 4.12932 10.2296 4.24802 10.3204 4.33554L14.1916 8.06748C14.4965 8.36148 15.0179 8.15325 15.0179 7.7375V5.3252C15.0179 5.20144 14.9669 5.08272 14.8762 4.99522L11.005 1.26329Z\"\n fill=\"#F9BD2B\"\n />\n <path\n d=\"M21.0852 10.981L16.5288 6.58843C16.2238 6.29443 15.7024 6.50266 15.7024 6.91841V13.0627C15.7024 13.3205 15.9191 13.5294 16.1865 13.5294H23.2446C23.5119 13.5294 23.7287 13.3205 23.7287 13.0627V12.5032C23.7287 12.2455 23.511 12.0396 23.2459 12.0063C22.4323 11.9042 21.6713 11.546 21.0852 10.981ZM18.0252 12.0365C17.5978 12.0365 17.251 11.7021 17.251 11.2901C17.251 10.878 17.5978 10.5436 18.0252 10.5436C18.4527 10.5436 18.7996 10.878 18.7996 11.2901C18.7996 11.7021 18.4527 12.0365 18.0252 12.0365Z\"\n fill=\"currentColor\"\n />\n <path\n d=\"M0.5 13.0627C0.5 13.3205 0.716728 13.5294 0.984076 13.5294H3.20279C3.63405 13.5294 3.85003 13.0267 3.54508 12.7327L1.32637 10.5938C1.02142 10.2998 0.5 10.508 0.5 10.9238V13.0627ZM5.33931 5.13191L1.32637 1.26329C1.02142 0.969306 0.5 1.17752 0.5 1.59327V4.00556C0.5 4.12932 0.551001 4.24802 0.641783 4.33554L5.33931 8.86412V5.13191ZM1.32637 5.92855C1.02142 5.63455 0.5 5.84278 0.5 6.25853V8.67083C0.5 8.79459 0.551001 8.91331 0.641783 9.00081L5.33931 13.5294V9.79717L1.32637 5.92855Z\"\n fill=\"#1D4AFF\"\n />\n <path\n d=\"M10.1787 5.3252C10.1787 5.20144 10.1277 5.08272 10.0369 4.99522L6.16572 1.26329C5.8608 0.969306 5.33936 1.17752 5.33936 1.59327V4.00556C5.33936 4.12932 5.39037 4.24802 5.48114 4.33554L10.1787 8.86412V5.3252ZM5.33936 13.5294H8.04214C8.47341 13.5294 8.6894 13.0267 8.38443 12.7327L5.33936 9.79717V13.5294ZM5.33936 5.13191V8.67083C5.33936 8.79459 5.39037 8.91331 5.48114 9.00081L10.1787 13.5294V9.99047C10.1787 9.86671 10.1277 9.74803 10.0369 9.66049L5.33936 5.13191Z\"\n fill=\"#F54E00\"\n />\n <path\n d=\"M29.375 11.6667H31.3636V8.48772H33.0249C34.8499 8.48772 36.0204 7.4443 36.0204 5.83052C36.0204 4.21681 34.8499 3.17334 33.0249 3.17334H29.375V11.6667ZM31.3636 6.84972V4.81136H32.8236C33.5787 4.81136 34.0318 5.19958 34.0318 5.83052C34.0318 6.4615 33.5787 6.84972 32.8236 6.84972H31.3636ZM39.618 11.7637C41.5563 11.7637 42.9659 10.429 42.9659 8.60905C42.9659 6.78905 41.5563 5.45438 39.618 5.45438C37.6546 5.45438 36.2701 6.78905 36.2701 8.60905C36.2701 10.429 37.6546 11.7637 39.618 11.7637ZM38.1077 8.60905C38.1077 7.63838 38.7118 6.97105 39.618 6.97105C40.5116 6.97105 41.1157 7.63838 41.1157 8.60905C41.1157 9.57972 40.5116 10.2471 39.618 10.2471C38.7118 10.2471 38.1077 9.57972 38.1077 8.60905ZM46.1482 11.7637C47.6333 11.7637 48.6402 10.8658 48.6402 9.81025C48.6402 7.33505 45.2294 8.13585 45.2294 7.16518C45.2294 6.8983 45.5189 6.72843 45.9342 6.72843C46.3622 6.72843 46.8782 6.98318 47.0418 7.54132L48.527 6.94678C48.2375 6.06105 47.1677 5.45438 45.8713 5.45438C44.4743 5.45438 43.6058 6.25518 43.6058 7.21372C43.6058 9.53118 46.9663 8.88812 46.9663 9.84665C46.9663 10.1864 46.6391 10.417 46.1482 10.417C45.4434 10.417 44.9525 9.94376 44.8015 9.3735L43.3164 9.93158C43.6436 10.8537 44.6001 11.7637 46.1482 11.7637ZM53.4241 11.606L53.2982 10.0651C53.0843 10.1743 52.8074 10.2106 52.5808 10.2106C52.1278 10.2106 51.8257 9.89523 51.8257 9.34918V7.03172H53.3612V5.55145H51.8257V3.78001H49.9755V5.55145H48.9687V7.03172H49.9755V9.57972C49.9755 11.06 51.0202 11.7637 52.3921 11.7637C52.7696 11.7637 53.122 11.7031 53.4241 11.606ZM59.8749 3.17334V6.47358H56.376V3.17334H54.3874V11.6667H56.376V8.11158H59.8749V11.6667H61.8761V3.17334H59.8749ZM66.2899 11.7637C68.2281 11.7637 69.6378 10.429 69.6378 8.60905C69.6378 6.78905 68.2281 5.45438 66.2899 5.45438C64.3265 5.45438 62.942 6.78905 62.942 8.60905C62.942 10.429 64.3265 11.7637 66.2899 11.7637ZM64.7796 8.60905C64.7796 7.63838 65.3837 6.97105 66.2899 6.97105C67.1835 6.97105 67.7876 7.63838 67.7876 8.60905C67.7876 9.57972 67.1835 10.2471 66.2899 10.2471C65.3837 10.2471 64.7796 9.57972 64.7796 8.60905ZM73.2088 11.4725C73.901 11.4725 74.5177 11.242 74.845 10.8416V11.424C74.845 12.1034 74.2786 12.5767 73.4102 12.5767C72.7935 12.5767 72.2523 12.2854 72.1642 11.788L70.4776 12.0428C70.7042 13.1955 71.925 13.972 73.4102 13.972C75.361 13.972 76.6574 12.8679 76.6574 11.2298V5.55145H74.8324V6.07318C74.4926 5.69705 73.9136 5.45438 73.171 5.45438C71.409 5.45438 70.3014 6.61918 70.3014 8.46345C70.3014 10.3077 71.409 11.4725 73.2088 11.4725ZM72.1012 8.46345C72.1012 7.55345 72.655 6.97105 73.5109 6.97105C74.3793 6.97105 74.9331 7.55345 74.9331 8.46345C74.9331 9.37345 74.3793 9.95585 73.5109 9.95585C72.655 9.95585 72.1012 9.37345 72.1012 8.46345Z\"\n fill=\"currentColor\"\n />\n </g>\n </g>\n <defs>\n <clipPath id=\"clip0_2415_6911\">\n <rect width=\"76\" height=\"14\" fill=\"white\" transform=\"translate(0.5)\" />\n </clipPath>\n </defs>\n </svg>\n)\nexport const checkSVG = (\n <svg width=\"16\" height=\"12\" viewBox=\"0 0 16 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M5.30769 10.6923L4.77736 11.2226C4.91801 11.3633 5.10878 11.4423 5.30769 11.4423C5.5066 11.4423 5.69737 11.3633 5.83802 11.2226L5.30769 10.6923ZM15.5303 1.53033C15.8232 1.23744 15.8232 0.762563 15.5303 0.46967C15.2374 0.176777 14.7626 0.176777 14.4697 0.46967L15.5303 1.53033ZM1.53033 5.85429C1.23744 5.56139 0.762563 5.56139 0.46967 5.85429C0.176777 6.14718 0.176777 6.62205 0.46967 6.91495L1.53033 5.85429ZM5.83802 11.2226L15.5303 1.53033L14.4697 0.46967L4.77736 10.162L5.83802 11.2226ZM0.46967 6.91495L4.77736 11.2226L5.83802 10.162L1.53033 5.85429L0.46967 6.91495Z\"\n fill=\"currentColor\"\n />\n </svg>\n)\n","import { IconPosthogLogo } from '../icons'\n\ninterface PostHogLogoProps {\n urlParams?: Record<string, string>\n}\n\nexport function PostHogLogo({ urlParams }: PostHogLogoProps) {\n // Manual query string building for IE11/op_mini compatibility (no URLSearchParams)\n const queryString = urlParams\n ? Object.entries(urlParams)\n .map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`)\n .join('&')\n : ''\n\n return (\n <a\n href={`https://posthog.com/surveys${queryString ? `?${queryString}` : ''}`}\n target=\"_blank\"\n rel=\"noopener\"\n className=\"footer-branding\"\n >\n Survey by {IconPosthogLogo}\n </a>\n )\n}\n","import { window } from '../../../utils/globals'\n\nimport { SurveyAppearance } from '../../../posthog-surveys-types'\n\nimport { useContext } from 'preact/hooks'\nimport { SurveyContext } from '../surveys-extension-utils'\nimport { PostHogLogo } from './PostHogLogo'\n\nexport function BottomSection({\n text,\n submitDisabled,\n appearance,\n onSubmit,\n link,\n onPreviewSubmit,\n skipSubmitButton,\n canGoBack,\n onBack,\n}: {\n text: string\n submitDisabled: boolean\n appearance: SurveyAppearance\n onSubmit: () => void\n link?: string | null\n onPreviewSubmit?: () => void\n skipSubmitButton?: boolean\n canGoBack?: boolean\n onBack?: () => void\n}) {\n const { isPreviewMode } = useContext(SurveyContext)\n const showBackButton = !!canGoBack && !!onBack\n const submitButton = !skipSubmitButton && (\n <button\n className=\"form-submit\"\n disabled={submitDisabled}\n aria-label=\"Submit survey\"\n type=\"button\"\n onClick={() => {\n if (link) {\n window?.open(link)\n }\n if (isPreviewMode) {\n onPreviewSubmit?.()\n } else {\n onSubmit()\n }\n }}\n >\n {text}\n </button>\n )\n return (\n <div className=\"bottom-section\">\n {showBackButton ? (\n <div className=\"form-buttons form-buttons-with-back\">\n <button className=\"form-back\" type=\"button\" aria-label=\"Go to previous question\" onClick={onBack}>\n {appearance.backButtonText || 'Back'}\n </button>\n {submitButton}\n </div>\n ) : (\n submitButton\n )}\n {!appearance.whiteLabel && <PostHogLogo urlParams={{ utm_source: 'survey-footer' }} />}\n </div>\n )\n}\n","import { h } from 'preact'\nimport { useContext } from 'preact/hooks'\nimport { SurveyQuestion, SurveyQuestionType } from '../../../posthog-surveys-types'\nimport { cancelSVG } from '../icons'\nimport { SurveyContext, renderChildrenAsTextOrHtml } from '../surveys-extension-utils'\n\nexport function QuestionHeader({\n question,\n forceDisableHtml,\n htmlFor,\n}: {\n question: Pick<SurveyQuestion, 'question' | 'description' | 'descriptionContentType' | 'type'>\n forceDisableHtml: boolean\n htmlFor?: string\n}) {\n const TitleComponent = question.type === SurveyQuestionType.Open ? 'label' : 'h3'\n // Flag an empty header in JS rather than via :has(.survey-question:empty) in CSS,\n // which crashes some WebKit builds during text-node style invalidation.\n const isHeaderEmpty = !question.question && !question.description\n return (\n <div class={isHeaderEmpty ? 'question-header question-header--empty' : 'question-header'}>\n <TitleComponent className=\"survey-question\" htmlFor={htmlFor}>\n {question.question}\n </TitleComponent>\n {question.description &&\n renderChildrenAsTextOrHtml({\n component: h('p', { className: 'survey-question-description' }),\n children: question.description,\n renderAsHtml: !forceDisableHtml && question.descriptionContentType !== 'text',\n })}\n </div>\n )\n}\n\nexport function Cancel({ onClick }: { onClick: () => void }) {\n const { isPreviewMode } = useContext(SurveyContext)\n\n return (\n <button\n className=\"form-cancel\"\n onClick={onClick}\n disabled={isPreviewMode}\n aria-label=\"Close survey\"\n type=\"button\"\n >\n {cancelSVG({ fill: 'black' })}\n </button>\n )\n}\n","import { h } from 'preact'\nimport { SurveyAppearance, SurveyQuestionDescriptionContentType } from '../../../posthog-surveys-types'\nimport { renderChildrenAsTextOrHtml } from '../surveys-extension-utils'\nimport { BottomSection } from './BottomSection'\nimport { Cancel } from './QuestionHeader'\n\nimport { useContext, useEffect } from 'preact/hooks'\nimport { SurveyContext } from '../surveys-extension-utils'\nimport { addEventListener } from '../../../utils'\nimport { window as _window } from '../../../utils/globals'\n\n// We cast the types here which is dangerous but protected by the top level generateSurveys call\nconst window = _window as Window\n\nexport function ConfirmationMessage({\n header,\n description,\n contentType,\n forceDisableHtml,\n appearance,\n onClose,\n}: {\n header: string\n description: string\n forceDisableHtml: boolean\n contentType?: SurveyQuestionDescriptionContentType\n appearance: SurveyAppearance\n onClose: () => void\n}) {\n const { isPopup } = useContext(SurveyContext)\n\n useEffect(() => {\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === 'Enter' || event.key === 'Escape') {\n event.preventDefault()\n onClose()\n }\n }\n addEventListener(window, 'keydown', handleKeyDown as EventListener)\n return () => {\n window.removeEventListener('keydown', handleKeyDown)\n }\n }, [onClose])\n\n const renderCancelButton = isPopup && appearance.hideCancelButton !== true\n\n return (\n <div className=\"thank-you-message\" role=\"status\" tabIndex={0} aria-atomic=\"true\">\n {renderCancelButton && <Cancel onClick={() => onClose()} />}\n <h3 className=\"thank-you-message-header\">{header}</h3>\n {description &&\n renderChildrenAsTextOrHtml({\n component: h('p', { className: 'thank-you-message-body' }),\n children: description,\n renderAsHtml: !forceDisableHtml && contentType !== 'text',\n })}\n {isPopup && (\n <BottomSection\n text={appearance.thankYouMessageCloseButtonText || 'Close'}\n submitDisabled={false}\n appearance={appearance}\n onSubmit={() => onClose()}\n />\n )}\n </div>\n )\n}\n","import { Fragment, type JSX } from 'preact'\nimport { useEffect, useMemo, useRef, useState } from 'preact/hooks'\nimport {\n BasicSurveyQuestion,\n LinkSurveyQuestion,\n MultipleSurveyQuestion,\n RatingSurveyQuestion,\n SurveyAppearance,\n SurveyQuestionType,\n} from '../../../posthog-surveys-types'\nimport { isArray, isNull, isNumber, isString, SurveyValidationType } from '@posthog/core'\nimport { getValidationError, getLengthFromRules, getRequirementsHint } from '@posthog/core/surveys'\nimport {\n dissatisfiedEmoji,\n neutralEmoji,\n satisfiedEmoji,\n thumbsDownEmoji,\n thumbsUpEmoji,\n veryDissatisfiedEmoji,\n verySatisfiedEmoji,\n} from '../icons'\nimport { getDisplayOrderChoices, useSurveyContext } from '../surveys-extension-utils'\nimport { BottomSection } from './BottomSection'\nimport { QuestionHeader } from './QuestionHeader'\n\nexport interface CommonQuestionProps {\n forceDisableHtml: boolean\n appearance: SurveyAppearance\n onSubmit: (res: string | string[] | number | null) => void\n onPreviewSubmit: (res: string | string[] | number | null) => void\n initialValue?: string | string[] | number | null\n displayQuestionIndex: number\n canGoBack?: boolean\n onBack?: () => void\n}\n\ninterface OpenEndedInputState {\n isSelected: boolean\n inputValue: string\n}\n\nconst isValidStringArray = (value: unknown): value is string[] => {\n return isArray(value) && value.every((item) => isString(item))\n}\n\nconst initializeSelectedChoices = (\n initialValue: string | string[] | number | null | undefined,\n questionType: SurveyQuestionType\n): string | string[] | null => {\n if (isString(initialValue)) {\n return initialValue\n }\n if (isValidStringArray(initialValue)) {\n return initialValue\n }\n return questionType === SurveyQuestionType.SingleChoice ? null : []\n}\n\nconst initializeOpenEndedState = (\n initialValue: string | string[] | number | null | undefined,\n choices: string[]\n): OpenEndedInputState => {\n if (isString(initialValue) && !choices.includes(initialValue)) {\n return {\n isSelected: true,\n inputValue: initialValue,\n }\n }\n if (isValidStringArray(initialValue)) {\n const openEndedValue = initialValue.find((choice) => !choices.includes(choice))\n if (openEndedValue) {\n return {\n isSelected: true,\n inputValue: openEndedValue,\n }\n }\n }\n return {\n isSelected: false,\n inputValue: '',\n }\n}\n\nexport function OpenTextQuestion({\n question,\n forceDisableHtml,\n appearance,\n onSubmit,\n onPreviewSubmit,\n displayQuestionIndex,\n initialValue,\n canGoBack,\n onBack,\n}: CommonQuestionProps & {\n question: BasicSurveyQuestion\n}) {\n const { isPreviewMode } = useSurveyContext()\n const inputRef = useRef<HTMLTextAreaElement>(null)\n const [text, setText] = useState<string>(() => {\n if (isString(initialValue)) {\n return initialValue\n }\n return ''\n })\n useEffect(() => {\n setTimeout(() => {\n if (!isPreviewMode) {\n inputRef.current?.focus()\n }\n }, 100)\n }, [isPreviewMode])\n\n const htmlFor = `surveyQuestion${displayQuestionIndex}`\n\n // Validation logic\n const validationError = useMemo(() => {\n return getValidationError(text, question.validation, question.optional)\n }, [text, question.validation, question.optional])\n\n // Build requirements hint message\n const minLength = getLengthFromRules(question.validation, SurveyValidationType.MinLength)\n const maxLength = getLengthFromRules(question.validation, SurveyValidationType.MaxLength)\n const requirementsHint = useMemo(() => getRequirementsHint(minLength, maxLength), [minLength, maxLength])\n\n const handleSubmit = () => {\n if (validationError) {\n return\n }\n onSubmit(text.trim())\n }\n\n const handlePreviewSubmit = () => {\n if (validationError) {\n return\n }\n onPreviewSubmit(text.trim())\n }\n\n return (\n <Fragment>\n <div className=\"question-container\">\n <QuestionHeader question={question} forceDisableHtml={forceDisableHtml} htmlFor={htmlFor} />\n <textarea\n ref={inputRef}\n id={htmlFor}\n rows={4}\n placeholder={appearance?.placeholder}\n minLength={minLength}\n maxLength={maxLength}\n onInput={(e) => {\n setText(e.currentTarget.value)\n e.stopPropagation()\n }}\n onKeyDown={(e) => {\n e.stopPropagation()\n if (e.key === 'Enter' && (e.metaKey || e.ctrlKey) && !validationError) {\n e.preventDefault()\n isPreviewMode ? handlePreviewSubmit() : handleSubmit()\n }\n }}\n value={text}\n />\n {requirementsHint && <div className=\"validation-hint\">{requirementsHint}</div>}\n </div>\n <BottomSection\n text={question.buttonText || 'Submit'}\n submitDisabled={!!validationError}\n appearance={appearance}\n onSubmit={handleSubmit}\n onPreviewSubmit={handlePreviewSubmit}\n canGoBack={canGoBack}\n onBack={onBack}\n />\n </Fragment>\n )\n}\n\nexport function LinkQuestion({\n question,\n forceDisableHtml,\n appearance,\n onSubmit,\n onPreviewSubmit,\n canGoBack,\n onBack,\n}: CommonQuestionProps & {\n question: LinkSurveyQuestion\n}) {\n return (\n <Fragment>\n <div className=\"question-container\">\n <QuestionHeader question={question} forceDisableHtml={forceDisableHtml} />\n </div>\n <BottomSection\n text={question.buttonText || 'Submit'}\n submitDisabled={false}\n link={question.link}\n appearance={appearance}\n onSubmit={() => onSubmit('link clicked')}\n onPreviewSubmit={() => onPreviewSubmit('link clicked')}\n canGoBack={canGoBack}\n onBack={onBack}\n />\n </Fragment>\n )\n}\n\nexport function RatingQuestion({\n question,\n forceDisableHtml,\n displayQuestionIndex,\n appearance,\n onSubmit,\n onPreviewSubmit,\n initialValue,\n canGoBack,\n onBack,\n}: CommonQuestionProps & {\n question: RatingSurveyQuestion\n}) {\n const scale = question.scale\n const starting = question.scale === 10 ? 0 : 1\n const [rating, setRating] = useState<number | null>(() => {\n if (isNumber(initialValue)) {\n return initialValue\n }\n if (isArray(initialValue) && initialValue.length > 0 && isNumber(parseInt(initialValue[0]))) {\n return parseInt(initialValue[0])\n }\n if (isString(initialValue) && isNumber(parseInt(initialValue))) {\n return parseInt(initialValue)\n }\n return null\n })\n\n const isThumbSurvey = question.display === 'emoji' && question.scale === 2\n\n const { isPreviewMode } = useSurveyContext()\n\n const handleSubmit = (num: number) => {\n if (isPreviewMode) {\n return onPreviewSubmit(num)\n }\n return onSubmit(num)\n }\n\n return (\n <Fragment>\n <div className=\"question-container\">\n <QuestionHeader question={question} forceDisableHtml={forceDisableHtml} />\n <div className=\"rating-section\">\n <div className=\"rating-options\">\n {question.display === 'emoji' && (\n <div className={`rating-options-emoji${isThumbSurvey ? ' rating-options-emoji-2' : ''}`}>\n {emojiScaleLists[question.scale]?.map((emoji, idx) => {\n const active = idx + 1 === rating\n return (\n <button\n aria-label={`Rate ${idx + 1}`}\n className={`ratings-emoji question-${displayQuestionIndex}-rating-${idx} ${\n active ? 'rating-active' : ''\n }`}\n value={idx + 1}\n key={idx}\n type=\"button\"\n onClick={() => {\n const response = idx + 1\n setRating(response)\n if (question.skipSubmitButton) {\n handleSubmit(response)\n }\n }}\n >\n {emoji}\n </button>\n )\n })}\n </div>\n )}\n {question.display === 'number' && (\n <div\n className=\"rating-options-number\"\n style={{ gridTemplateColumns: `repeat(${scale - starting + 1}, minmax(0, 1fr))` }}\n >\n {getScaleNumbers(question.scale).map((number, idx) => {\n const active = rating === number\n return (\n <RatingButton\n key={idx}\n displayQuestionIndex={displayQuestionIndex}\n active={active}\n appearance={appearance}\n num={number}\n setActiveNumber={(response) => {\n setRating(response)\n if (question.skipSubmitButton) {\n handleSubmit(response)\n }\n }}\n />\n )\n })}\n </div>\n )}\n </div>\n {!isThumbSurvey && (\n <div className=\"rating-text\">\n <div>{question.lowerBoundLabel}</div>\n <div>{question.upperBoundLabel}</div>\n </div>\n )}\n </div>\n </div>\n <BottomSection\n text={question.buttonText || appearance?.submitButtonText || 'Submit'}\n submitDisabled={isNull(rating) && !question.optional}\n appearance={appearance}\n onSubmit={() => onSubmit(rating)}\n onPreviewSubmit={() => onPreviewSubmit(rating)}\n skipSubmitButton={question.skipSubmitButton}\n canGoBack={canGoBack}\n onBack={onBack}\n />\n </Fragment>\n )\n}\n\nexport function RatingButton({\n num,\n active,\n displayQuestionIndex,\n setActiveNumber,\n}: {\n num: number\n active: boolean\n displayQuestionIndex: number\n appearance: SurveyAppearance\n setActiveNumber: (num: number) => void\n}) {\n return (\n <button\n aria-label={`Rate ${num}`}\n className={`ratings-number question-${displayQuestionIndex}-rating-${num} ${active ? 'rating-active' : ''}`}\n type=\"button\"\n onClick={() => {\n setActiveNumber(num)\n }}\n >\n {num}\n </button>\n )\n}\n\nexport function MultipleChoiceQuestion({\n question,\n forceDisableHtml,\n displayQuestionIndex,\n appearance,\n onSubmit,\n onPreviewSubmit,\n initialValue,\n canGoBack,\n onBack,\n}: CommonQuestionProps & {\n question: MultipleSurveyQuestion\n}) {\n const openChoiceInputRef = useRef<HTMLInputElement>(null)\n const choices = useMemo(() => getDisplayOrderChoices(question), [question])\n const [selectedChoices, setSelectedChoices] = useState<string | string[] | null>(() =>\n initializeSelectedChoices(initialValue, question.type)\n )\n const [openEndedState, setOpenEndedState] = useState<OpenEndedInputState>(() =>\n initializeOpenEndedState(initialValue, choices)\n )\n\n const { isPreviewMode } = useSurveyContext()\n\n const isSingleChoiceQuestion = question.type === SurveyQuestionType.SingleChoice\n const isMultipleChoiceQuestion = question.type === SurveyQuestionType.MultipleChoice\n\n const shouldSkipSubmit = question.skipSubmitButton && isSingleChoiceQuestion && !question.hasOpenChoice\n\n const handleChoiceChange = (val: string, isOpenChoice: boolean) => {\n if (isOpenChoice) {\n const newOpenSelected = !openEndedState.isSelected\n setOpenEndedState((prev) => ({\n ...prev,\n isSelected: newOpenSelected,\n inputValue: newOpenSelected ? prev.inputValue : '',\n }))\n\n if (isSingleChoiceQuestion) {\n setSelectedChoices('')\n }\n\n // Focus the input when open choice is selected, slight delay because of the animation\n if (newOpenSelected) {\n setTimeout(() => openChoiceInputRef.current?.focus(), 75)\n }\n return\n }\n\n if (isSingleChoiceQuestion) {\n setSelectedChoices(val)\n // Deselect open choice when selecting another option\n setOpenEndedState((prev) => ({\n ...prev,\n isSelected: false,\n inputValue: '',\n }))\n\n if (shouldSkipSubmit) {\n onSubmit(val)\n if (isPreviewMode) {\n onPreviewSubmit(val)\n }\n }\n return\n }\n\n if (isMultipleChoiceQuestion && isArray(selectedChoices)) {\n if (selectedChoices.includes(val)) {\n setSelectedChoices(selectedChoices.filter((choice) => choice !== val))\n } else {\n setSelectedChoices([...selectedChoices, val])\n }\n }\n }\n\n const handleOpenEndedInputChange = (e: JSX.TargetedEvent<HTMLInputElement>) => {\n e.stopPropagation()\n const newValue = e.currentTarget.value\n\n setOpenEndedState((prev) => ({\n ...prev,\n inputValue: newValue,\n }))\n\n if (isSingleChoiceQuestion) {\n setSelectedChoices(newValue)\n }\n }\n\n const handleOpenEndedKeyDown = (e: JSX.TargetedKeyboardEvent<HTMLInputElement>) => {\n e.stopPropagation()\n\n // Handle Enter key to submit form if valid\n if (e.key === 'Enter' && !isSubmitDisabled()) {\n e.preventDefault()\n handleSubmit()\n }\n\n // Handle Escape key to clear input and deselect\n if (e.key === 'Escape') {\n e.preventDefault()\n setOpenEndedState((prev) => ({\n ...prev,\n isSelected: false,\n inputValue: '',\n }))\n if (isSingleChoiceQuestion) {\n setSelectedChoices(null)\n }\n }\n }\n\n const isSubmitDisabled = (): boolean => {\n if (question.optional) {\n return false\n }\n if (isNull(selectedChoices)) {\n return true\n }\n if (isArray(selectedChoices)) {\n if (!openEndedState.isSelected && selectedChoices.length === 0) {\n return true\n }\n }\n if (openEndedState.isSelected && openEndedState.inputValue.trim() === '') {\n return true\n }\n return false\n }\n\n const handleSubmit = () => {\n if (openEndedState.isSelected && isMultipleChoiceQuestion) {\n if (isArray(selectedChoices)) {\n isPreviewMode\n ? onPreviewSubmit([...selectedChoices, openEndedState.inputValue])\n : onSubmit([...selectedChoices, openEndedState.inputValue])\n }\n } else {\n isPreviewMode ? onPreviewSubmit(selectedChoices) : onSubmit(selectedChoices)\n }\n }\n\n return (\n <Fragment>\n <div className=\"question-container\">\n <QuestionHeader question={question} forceDisableHtml={forceDisableHtml} />\n <fieldset className=\"multiple-choice-options limit-height\">\n <legend className=\"sr-only\">\n {isMultipleChoiceQuestion ? ' Select all that apply' : ' Select one'}\n </legend>\n {choices.map((choice: string, idx: number) => {\n const isOpenChoice = !!question.hasOpenChoice && idx === question.choices.length - 1\n const inputId = `surveyQuestion${displayQuestionIndex}Choice${idx}`\n const openInputId = `${inputId}Open`\n\n const isChecked = isOpenChoice\n ? openEndedState.isSelected\n : isSingleChoiceQuestion\n ? selectedChoices === choice\n : isArray(selectedChoices) && selectedChoices.includes(choice)\n\n return (\n <label className={isOpenChoice ? 'choice-option-open' : ''} key={idx}>\n <div className=\"response-choice\">\n <input\n type={isSingleChoiceQuestion ? 'radio' : 'checkbox'}\n name={inputId}\n checked={isChecked}\n onChange={() => handleChoiceChange(choice, isOpenChoice)}\n id={inputId}\n aria-controls={openInputId}\n />\n <span>{isOpenChoice ? `${choice}:` : choice}</span>\n </div>\n {isOpenChoice && (\n <input\n type=\"text\"\n ref={openChoiceInputRef}\n id={openInputId}\n name={`question${displayQuestionIndex}Open`}\n value={openEndedState.inputValue}\n onKeyDown={handleOpenEndedKeyDown}\n onInput={handleOpenEndedInputChange}\n onClick={(e) => {\n // Ensure the checkbox/radio gets checked when clicking the input\n if (!openEndedState.isSelected) {\n handleChoiceChange(choice, true)\n }\n e.stopPropagation()\n }}\n aria-label={`${choice} - please specify`}\n />\n )}\n </label>\n )\n })}\n </fieldset>\n </div>\n <BottomSection\n text={question.buttonText || 'Submit'}\n submitDisabled={isSubmitDisabled()}\n appearance={appearance}\n onSubmit={handleSubmit}\n onPreviewSubmit={handleSubmit}\n skipSubmitButton={shouldSkipSubmit}\n canGoBack={canGoBack}\n onBack={onBack}\n />\n </Fragment>\n )\n}\n\nconst fiveScaleNumbers = [1, 2, 3, 4, 5]\nconst sevenScaleNumbers = [1, 2, 3, 4, 5, 6, 7]\nconst tenScaleNumbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\n\nconst emojiScaleLists: Partial<Record<RatingSurveyQuestion['scale'], JSX.Element[]>> = {\n 2: [thumbsUpEmoji, thumbsDownEmoji],\n 3: [dissatisfiedEmoji, neutralEmoji, satisfiedEmoji],\n 5: [veryDissatisfiedEmoji, dissatisfiedEmoji, neutralEmoji, satisfiedEmoji, verySatisfiedEmoji],\n}\n\nfunction getScaleNumbers(scale: number): number[] {\n switch (scale) {\n case 5:\n return fiveScaleNumbers\n case 7:\n return sevenScaleNumbers\n case 10:\n return tenScaleNumbers\n default:\n return fiveScaleNumbers\n }\n}\n","import { Survey, SurveyQuestionBranchingType, SurveyQuestionType } from '../posthog-surveys-types'\nimport { createLogger } from './logger'\n\nconst logger = createLogger('[Surveys]')\n\n/**\n * Get the rating bucket (detractors/passives/promoters or negative/neutral/positive)\n * based on the response value and scale.\n */\nexport function getRatingBucketForResponseValue(responseValue: number, scale: number): string {\n if (scale === 2) {\n if (responseValue < 1 || responseValue > 2) {\n throw new Error('The response must be in range 1-2')\n }\n return responseValue === 1 ? 'positive' : 'negative'\n } else if (scale === 3) {\n if (responseValue < 1 || responseValue > 3) {\n throw new Error('The response must be in range 1-3')\n }\n\n return responseValue === 1 ? 'negative' : responseValue === 2 ? 'neutral' : 'positive'\n } else if (scale === 5) {\n if (responseValue < 1 || responseValue > 5) {\n throw new Error('The response must be in range 1-5')\n }\n\n return responseValue <= 2 ? 'negative' : responseValue === 3 ? 'neutral' : 'positive'\n } else if (scale === 7) {\n if (responseValue < 1 || responseValue > 7) {\n throw new Error('The response must be in range 1-7')\n }\n\n return responseValue <= 3 ? 'negative' : responseValue === 4 ? 'neutral' : 'positive'\n } else if (scale === 10) {\n if (responseValue < 0 || responseValue > 10) {\n throw new Error('The response must be in range 0-10')\n }\n\n return responseValue <= 6 ? 'detractors' : responseValue <= 8 ? 'passives' : 'promoters'\n }\n\n throw new Error('The scale must be one of: 2, 3, 5, 7, 10')\n}\n\n/**\n * Determine the next survey step based on branching configuration.\n * Returns the next question index, or SurveyQuestionBranchingType.End if the survey should end.\n */\nexport function getNextSurveyStep(\n survey: Survey,\n currentQuestionIndex: number,\n response: string | string[] | number | null\n): number | typeof SurveyQuestionBranchingType.End {\n const question = survey.questions[currentQuestionIndex]\n const nextQuestionIndex = currentQuestionIndex + 1\n\n if (!question.branching?.type) {\n if (currentQuestionIndex === survey.questions.length - 1) {\n return SurveyQuestionBranchingType.End\n }\n\n return nextQuestionIndex\n }\n\n if (question.branching.type === SurveyQuestionBranchingType.End) {\n return SurveyQuestionBranchingType.End\n } else if (question.branching.type === SurveyQuestionBranchingType.SpecificQuestion) {\n if (Number.isInteger(question.branching.index)) {\n return question.branching.index\n }\n } else if (question.branching.type === SurveyQuestionBranchingType.ResponseBased) {\n // Single choice\n if (question.type === SurveyQuestionType.SingleChoice) {\n // KLUDGE: for now, look up the choiceIndex based on the response\n // TODO: once QuestionTypes.MultipleChoiceQuestion is refactored, pass the selected choiceIndex into this method\n let selectedChoiceIndex = question.choices.indexOf(`${response}`)\n\n if (selectedChoiceIndex === -1 && question.hasOpenChoice) {\n // if the response is not found in the choices, it must be the open choice,\n // which is always the last choice\n selectedChoiceIndex = question.choices.length - 1\n }\n\n if (question.branching?.responseValues?.hasOwnProperty(selectedChoiceIndex)) {\n const nextStep = question.branching.responseValues[selectedChoiceIndex]\n\n // Specific question\n if (Number.isInteger(nextStep)) {\n return nextStep\n }\n\n if (nextStep === SurveyQuestionBranchingType.End) {\n return SurveyQuestionBranchingType.End\n }\n\n return nextQuestionIndex\n }\n } else if (question.type === SurveyQuestionType.Rating) {\n if (typeof response !== 'number' || !Number.isInteger(response)) {\n throw new Error('The response type must be an integer')\n }\n\n const ratingBucket = getRatingBucketForResponseValue(response, question.scale)\n\n if (question.branching?.responseValues?.hasOwnProperty(ratingBucket)) {\n const nextStep = question.branching.responseValues[ratingBucket]\n\n // Specific question\n if (Number.isInteger(nextStep)) {\n return nextStep\n }\n\n if (nextStep === SurveyQuestionBranchingType.End) {\n return SurveyQuestionBranchingType.End\n }\n\n return nextQuestionIndex\n }\n }\n\n return nextQuestionIndex\n }\n\n logger.warn('Falling back to next question index due to unexpected branching type')\n return nextQuestionIndex\n}\n","import { PostHog } from '../posthog-core'\nimport { Survey } from '../posthog-surveys-types'\nimport { STORED_PERSON_PROPERTIES_KEY } from '../constants'\nimport { createLogger } from './logger'\nimport { getBrowserLanguage } from './event-utils'\nimport { isFunction } from '@posthog/core'\nimport { applySurveyTranslation, detectSurveyLanguage } from '@posthog/core/surveys'\n\nconst logger = createLogger('[SurveyTranslations]')\n\n/**\n * Detects the user's language using priority order:\n * 1. config.override_display_language (explicit override)\n * 2. person properties 'language' (allows programmatic control via posthog.identify())\n * 3. navigator.language (browser language)\n *\n * TODO: Consider adding dynamic language change detection in the future:\n * - Listen to 'languagechange' event on window (https://developer.mozilla.org/en-US/docs/Web/API/Window/languagechange_event)\n * - Listen to config changes (once we add config change events to PostHog core)\n * - Re-render survey when language changes mid-session\n *\n * @param instance - PostHog instance to retrieve config and person properties\n * @returns The detected language code (e.g., 'fr', 'es', 'en-US') or null if not found\n */\nexport function detectUserLanguage(instance: PostHog): string | null {\n return detectSurveyLanguage(\n {\n overrideLanguage: instance.config.override_display_language,\n storedPersonProperties: isFunction(instance.get_property)\n ? instance.get_property(STORED_PERSON_PROPERTIES_KEY)\n : undefined,\n locale: getBrowserLanguage(),\n },\n logger\n )\n}\n\n/**\n * Applies translations to a survey based on the user's language from person properties\n * @param survey - The original survey object\n * @param instance - PostHog instance to retrieve person properties\n * @returns An object containing the translated survey and the language used (or null if no translation applied)\n */\nexport function applySurveyTranslationForUser(\n survey: Survey,\n instance: PostHog\n): { survey: Survey; language: string | null } {\n const userLanguage = detectUserLanguage(instance)\n\n if (!userLanguage) {\n logger.info('No user language detected')\n return { survey, language: null }\n }\n\n const result = applySurveyTranslation(survey, userLanguage, logger)\n\n return {\n survey: result.survey,\n language: result.matchedKey,\n }\n}\n","import { convertToURL, getQueryParam, maskQueryParams } from './request-utils'\nimport { isNull, stripLeadingDollar, stripUrlHash } from '@posthog/core'\nimport { Properties } from '../types'\nimport Config from '../config'\nimport { SDK_DIST_CHANNEL } from '../constants'\nimport { each, extend, stripEmptyProperties } from './index'\nimport { document, location, userAgent, window } from './globals'\nimport {\n BrowserDetectionHints,\n detectBrowser,\n detectBrowserVersion,\n detectDevice,\n detectDeviceType,\n detectOS,\n} from '@posthog/core'\nimport { cookieStore } from '../storage'\n\nconst URL_REGEX_PREFIX = 'https?://(.*)'\n\n// CAMPAIGN_PARAMS and EVENT_TO_PERSON_PROPERTIES should be kept in sync with\n// https://github.com/PostHog/posthog/blob/master/plugin-server/src/utils/db/utils.ts#L60\n\n// The list of campaign parameters that could be considered personal data under e.g. GDPR.\n// These can be masked in URLs and properties before being sent to posthog.\nexport const PERSONAL_DATA_CAMPAIGN_PARAMS = [\n 'gclid', // google ads\n 'gclsrc', // google ads 360\n 'dclid', // google display ads\n 'gbraid', // google ads, web to app\n 'wbraid', // google ads, app to web\n 'fbclid', // facebook\n 'msclkid', // microsoft\n 'twclid', // twitter\n 'li_fat_id', // linkedin\n 'igshid', // instagram\n 'ttclid', // tiktok\n 'rdt_cid', // reddit\n 'epik', // pinterest\n 'qclid', // quora\n 'sccid', // snapchat\n 'irclid', // impact\n '_kx', // klaviyo\n]\n\nexport const CAMPAIGN_PARAMS = [\n 'utm_source',\n 'utm_medium',\n 'utm_campaign',\n 'utm_content',\n 'utm_term',\n 'gad_source', // google ads source\n 'mc_cid', // mailchimp campaign id\n ...PERSONAL_DATA_CAMPAIGN_PARAMS,\n]\n\nexport const EVENT_TO_PERSON_PROPERTIES = [\n // mobile params\n '$app_build',\n '$app_name',\n '$app_namespace',\n '$app_version',\n // web params\n '$browser',\n '$browser_version',\n '$device_type',\n '$current_url',\n '$pathname',\n '$os',\n '$os_name', // $os_name is a special case, it's treated as an alias of $os!\n '$os_version',\n '$referring_domain',\n '$referrer',\n '$screen_height',\n '$screen_width',\n '$viewport_height',\n '$viewport_width',\n '$raw_user_agent',\n]\n\nexport const MASKED = '<masked>'\n\n// Campaign params that can be read from the cookie store\nexport const COOKIE_CAMPAIGN_PARAMS = [\n 'li_fat_id', // linkedin\n]\n\nexport function getCampaignParams(\n customTrackedParams?: string[],\n maskPersonalDataProperties?: boolean,\n customPersonalDataProperties?: string[] | undefined\n): Record<string, string> {\n if (!document) {\n return {}\n }\n\n const paramsToMask = maskPersonalDataProperties\n ? [...PERSONAL_DATA_CAMPAIGN_PARAMS, ...(customPersonalDataProperties || [])]\n : []\n\n // Initially get campaign params from the URL\n const urlCampaignParams = _getCampaignParamsFromUrl(\n maskQueryParams(document.URL, paramsToMask, MASKED),\n customTrackedParams\n )\n\n // But we can also get some of them from the cookie store\n // For example: https://learn.microsoft.com/en-us/linkedin/marketing/conversions/enabling-first-party-cookies?view=li-lms-2025-05#reading-li_fat_id-from-cookies\n const cookieCampaignParams = _getCampaignParamsFromCookie()\n\n // Prefer the values found in the urlCampaignParams if possible\n // `extend` will override the values if found in the second argument\n return extend(cookieCampaignParams, urlCampaignParams)\n}\n\nfunction _getCampaignParamsFromUrl(url: string, customParams?: string[]): Record<string, string> {\n const campaign_keywords = CAMPAIGN_PARAMS.concat(customParams || [])\n\n const params: Record<string, any> = {}\n each(campaign_keywords, function (kwkey) {\n const kw = getQueryParam(url, kwkey)\n params[kwkey] = kw ? kw : null\n })\n\n return params\n}\n\nfunction _getCampaignParamsFromCookie(): Record<string, string> {\n const params: Record<string, any> = {}\n each(COOKIE_CAMPAIGN_PARAMS, function (kwkey) {\n const kw = cookieStore._get(kwkey)\n params[kwkey] = kw ? kw : null\n })\n\n return params\n}\n\nfunction _getSearchEngine(referrer: string): string | null {\n if (!referrer) {\n return null\n } else {\n if (referrer.search(URL_REGEX_PREFIX + 'google.([^/?]*)') === 0) {\n return 'google'\n } else if (referrer.search(URL_REGEX_PREFIX + 'bing.com') === 0) {\n return 'bing'\n } else if (referrer.search(URL_REGEX_PREFIX + 'yahoo.com') === 0) {\n return 'yahoo'\n } else if (referrer.search(URL_REGEX_PREFIX + 'duckduckgo.com') === 0) {\n return 'duckduckgo'\n } else {\n return null\n }\n }\n}\n\nfunction _getSearchInfoFromReferrer(referrer: string): Record<string, any> {\n const search = _getSearchEngine(referrer)\n const param = search != 'yahoo' ? 'q' : 'p'\n const ret: Record<string, any> = {}\n\n if (!isNull(search)) {\n ret['$search_engine'] = search\n\n const keyword = document ? getQueryParam(document.referrer, param) : ''\n if (keyword.length) {\n ret['ph_keyword'] = keyword\n }\n }\n\n return ret\n}\n\nexport function getSearchInfo(): Record<string, any> {\n const referrer = document?.referrer\n if (!referrer) {\n return {}\n }\n return _getSearchInfoFromReferrer(referrer)\n}\n\nexport function getBrowserLanguage(): string | undefined {\n return (\n navigator.language || // Any modern browser\n (navigator as Record<string, any>).userLanguage // IE11\n )\n}\n\nexport function getBrowserLanguagePrefix(): string | undefined {\n const lang = getBrowserLanguage()\n return typeof lang === 'string' ? lang.split('-')[0] : undefined\n}\n\nconst DIRECT = '$direct'\n\nexport function getReferrer(): string {\n return document?.referrer || DIRECT\n}\n\nexport function getReferringDomain(): string {\n if (!document?.referrer) {\n return DIRECT\n }\n return convertToURL(document.referrer)?.host || DIRECT\n}\n\nexport function getReferrerInfo(): Record<string, any> {\n return {\n $referrer: getReferrer(),\n $referring_domain: getReferringDomain(),\n }\n}\n\nexport function getPersonInfo(\n maskPersonalDataProperties?: boolean,\n customPersonalDataProperties?: string[],\n disableCaptureUrlHashes: boolean = false\n) {\n const paramsToMask = maskPersonalDataProperties\n ? [...PERSONAL_DATA_CAMPAIGN_PARAMS, ...(customPersonalDataProperties || [])]\n : []\n const href = disableCaptureUrlHashes ? stripUrlHash(location?.href) : location?.href\n const url = href?.substring(0, 1000)\n // we're being a bit more economical with bytes here because this is stored in the cookie\n return {\n r: getReferrer().substring(0, 1000),\n u: url ? maskQueryParams(url, paramsToMask, MASKED) : undefined,\n }\n}\n\nexport function getPersonPropsFromInfo(\n info: Record<string, any>,\n disableCaptureUrlHashes: boolean = false\n): Record<string, any> {\n const { r: referrer, u } = info\n const url = disableCaptureUrlHashes ? stripUrlHash(u) : u\n const referring_domain = referrer == null ? undefined : referrer == DIRECT ? DIRECT : convertToURL(referrer)?.host\n\n const props: Record<string, string | undefined> = {\n $referrer: referrer,\n $referring_domain: referring_domain,\n }\n if (url) {\n props['$current_url'] = url\n const location = convertToURL(url)\n props['$host'] = location?.host\n props['$pathname'] = location?.pathname\n const campaignParams = _getCampaignParamsFromUrl(url)\n extend(props, campaignParams)\n }\n if (referrer) {\n const searchInfo = _getSearchInfoFromReferrer(referrer)\n extend(props, searchInfo)\n }\n return props\n}\n\nexport function getInitialPersonPropsFromInfo(\n info: Record<string, any>,\n disableCaptureUrlHashes: boolean = false\n): Record<string, any> {\n const personProps = getPersonPropsFromInfo(info, disableCaptureUrlHashes)\n const props: Record<string, any> = {}\n each(personProps, function (val: any, key: string) {\n props[`$initial_${stripLeadingDollar(key)}`] = val\n })\n return props\n}\n\nexport function getTimezone(): string | undefined {\n try {\n return Intl.DateTimeFormat().resolvedOptions().timeZone\n } catch {\n return undefined\n }\n}\n\nexport function getTimezoneOffset(): number | undefined {\n try {\n return new Date().getTimezoneOffset()\n } catch {\n return undefined\n }\n}\n\n// Gathers signals that aren't in the UA string. Desktop / Android Brave is\n// Chromium-based and exposes `navigator.brave` rather than a UA marker. (Brave\n// on iOS is picked up via the `Brave/` UA marker by `detectBrowser` itself, so\n// no hint is needed there.)\nexport function getBrowserDetectionHints(): BrowserDetectionHints {\n const nav = typeof navigator !== 'undefined' ? (navigator as Record<string, any>) : undefined\n return nav?.brave ? { brave: true } : {}\n}\n\nexport function getEventProperties(\n maskPersonalDataProperties?: boolean,\n customPersonalDataProperties?: string[],\n detectGoogleSearchApp?: boolean,\n disableCaptureUrlHashes: boolean = false\n): Properties {\n if (!userAgent) {\n return {}\n }\n const paramsToMask = maskPersonalDataProperties\n ? [...PERSONAL_DATA_CAMPAIGN_PARAMS, ...(customPersonalDataProperties || [])]\n : []\n const [os_name, os_version] = detectOS(userAgent)\n const browserHints = getBrowserDetectionHints()\n const browserOptions = { detectGoogleSearchApp }\n\n const properties = extend(\n stripEmptyProperties({\n $os: os_name,\n $os_version: os_version,\n $browser: detectBrowser(userAgent, navigator.vendor, browserHints, browserOptions),\n $device: detectDevice(userAgent),\n $device_type: detectDeviceType(userAgent, {\n // eslint-disable-next-line compat/compat\n userAgentDataPlatform: navigator?.userAgentData?.platform,\n maxTouchPoints: navigator?.maxTouchPoints,\n screenWidth: window?.screen?.width,\n screenHeight: window?.screen?.height,\n devicePixelRatio: window?.devicePixelRatio,\n }),\n $timezone: getTimezone(),\n $timezone_offset: getTimezoneOffset(),\n }),\n {\n $current_url: maskQueryParams(\n disableCaptureUrlHashes ? stripUrlHash(location?.href) : location?.href,\n paramsToMask,\n MASKED\n ),\n $host: location?.host,\n $pathname: location?.pathname,\n $raw_user_agent: userAgent.length > 1000 ? userAgent.substring(0, 997) + '...' : userAgent,\n $browser_version: detectBrowserVersion(userAgent, navigator.vendor, browserHints, browserOptions),\n $browser_language: getBrowserLanguage(),\n $browser_language_prefix: getBrowserLanguagePrefix(),\n $screen_height: window?.screen.height,\n $screen_width: window?.screen.width,\n $viewport_height: window?.innerHeight,\n $viewport_width: window?.innerWidth,\n $lib: Config.LIB_NAME,\n $lib_version: Config.LIB_VERSION,\n $insert_id: Math.random().toString(36).substring(2, 10) + Math.random().toString(36).substring(2, 10),\n $time: Date.now() / 1000, // epoch time in seconds\n }\n )\n\n if (Config.SDK_DIST_CHANNEL) {\n properties[SDK_DIST_CHANNEL] = Config.SDK_DIST_CHANNEL\n }\n\n return properties\n}\n","import { type JSX, type RefObject, render, Fragment } from 'preact'\nimport { useContext, useEffect, useMemo, useRef, useState } from 'preact/hooks'\nimport { PostHog } from '../posthog-core'\nimport {\n DisplaySurveyPopoverOptions,\n Survey,\n SurveyCallback,\n SurveyEventName,\n SurveyEventProperties,\n SurveyPosition,\n SurveyQuestion,\n SurveyQuestionBranchingType,\n SurveyQuestionType,\n SurveyResponseValue,\n SurveySchedule,\n SurveyTabPosition,\n SurveyType,\n SurveyWidgetType,\n SurveyWithTypeAndAppearance,\n} from '../posthog-surveys-types'\nimport { addEventListener } from '../utils'\nimport { document as _document, window as _window } from '../utils/globals'\nimport {\n doesSurveyActivateByAction,\n doesSurveyActivateByEvent,\n IN_APP_SURVEY_TYPES,\n isSurveyRunning,\n SURVEY_LOGGER as logger,\n} from '../utils/survey-utils'\nimport { isArray, isNull, isUndefined } from '@posthog/core'\nimport { Properties } from '../types'\nimport { SURVEYS } from '../constants'\nimport { uuidv7 } from '../uuidv7'\nimport { ConfirmationMessage } from './surveys/components/ConfirmationMessage'\nimport { Cancel } from './surveys/components/QuestionHeader'\nimport {\n CommonQuestionProps,\n LinkQuestion,\n MultipleChoiceQuestion,\n OpenTextQuestion,\n RatingQuestion,\n} from './surveys/components/QuestionTypes'\nimport {\n canActivateRepeatedly,\n retrieveSurveyShadow,\n defaultSurveyAppearance,\n dismissedSurveyEvent,\n doesSurveyDeviceTypesMatch,\n doesSurveyMatchSelector,\n doesSurveyUrlMatch,\n getDisplayOrderQuestions,\n getInProgressSurveyState,\n getSurveyContainerClass,\n getSurveyResponseKey,\n getSurveySeen,\n hasWaitPeriodPassed,\n isSurveyInProgress,\n sendSurveyEvent,\n sendSurveyAbandonedEvent,\n setInProgressSurveyState,\n SurveyContext,\n getSurveyStylesheet,\n addSurveyCSSVariablesToElement,\n getPopoverPosition,\n} from './surveys/surveys-extension-utils'\nimport {\n extractPrefillParamsFromUrl,\n convertPrefillToResponses,\n calculatePrefillStartIndex,\n} from '../utils/survey-url-prefill'\nimport { getNextSurveyStep } from '../utils/survey-branching'\nimport { applySurveyTranslationForUser } from '../utils/survey-translations'\n\n// Re-export for surveys-preview entrypoint\nexport { getNextSurveyStep }\n\n// We cast the types here which is dangerous but protected by the top level generateSurveys call\nconst window = _window as Window & typeof globalThis\nconst document = _document as Document\n\nconst DISPATCH_FEEDBACK_WIDGET_EVENT = 'ph:show_survey_widget'\nconst WIDGET_LISTENER_ATTRIBUTE = 'PHWidgetSurveyClickListener'\n\nconst SURVEY_NEXT_TO_TRIGGER_PARAMS = {\n ESTIMATED_MIN_HEIGHT: 250,\n HORIZONTAL_PADDING: 20,\n TRIGGER_SPACING: 12,\n} as const\n\nfunction getNextToTriggerPosition(target: HTMLElement, surveyWidth: number): JSX.CSSProperties | null {\n try {\n const buttonRect = target.getBoundingClientRect()\n const viewportHeight = window.innerHeight\n const viewportWidth = window.innerWidth\n const estimatedMinSurveyHeight = SURVEY_NEXT_TO_TRIGGER_PARAMS.ESTIMATED_MIN_HEIGHT\n const buttonCenterX = buttonRect.left + buttonRect.width / 2\n let left = buttonCenterX - surveyWidth / 2\n const horizontalPadding = SURVEY_NEXT_TO_TRIGGER_PARAMS.HORIZONTAL_PADDING\n if (left + surveyWidth > viewportWidth - horizontalPadding) {\n left = viewportWidth - surveyWidth - horizontalPadding\n }\n if (left < horizontalPadding) {\n left = horizontalPadding\n }\n const spacing = SURVEY_NEXT_TO_TRIGGER_PARAMS.TRIGGER_SPACING\n const spaceBelow = viewportHeight - buttonRect.bottom\n const spaceAbove = buttonRect.top\n const showAbove = spaceBelow < estimatedMinSurveyHeight && spaceAbove > spaceBelow\n\n return {\n position: 'fixed',\n top: showAbove ? 'auto' : `${buttonRect.bottom + spacing}px`,\n left: `${left}px`,\n right: 'auto',\n bottom: showAbove ? `${viewportHeight - buttonRect.top + spacing}px` : 'auto',\n zIndex: defaultSurveyAppearance.zIndex,\n } satisfies JSX.CSSProperties\n } catch (error) {\n logger.warn('Failed to calculate trigger position:', error)\n return null\n }\n}\n\n// Keep in sync with posthog/constants.py on main repo\nconst SURVEY_TARGETING_FLAG_PREFIX = 'survey-targeting-'\n\nexport class SurveyManager {\n private _posthog: PostHog\n private _surveyInFocus: string | null\n private _surveyTimeouts: Map<string, NodeJS.Timeout> = new Map()\n private _widgetSelectorListeners: Map<string, { element: Element; listener: EventListener; survey: Survey }> =\n new Map()\n private _prefillHandledSurveys: Set<string> = new Set()\n\n constructor(posthog: PostHog) {\n this._posthog = posthog\n // This is used to track the survey that is currently in focus. We only show one survey at a time.\n this._surveyInFocus = null\n }\n\n public handlePageUnload = (): void => {\n // we don't use getSurveys to avoid adding extra API calls here.\n // if no surveys are cached, there's nothing to do anyways\n const surveys = this._posthog.get_property(SURVEYS) as Survey[] | undefined\n if (!surveys) {\n return\n }\n for (const survey of surveys) {\n if (isSurveyInProgress(survey)) {\n sendSurveyAbandonedEvent(survey, this._posthog)\n }\n }\n }\n\n private _clearSurveyTimeout(surveyId: string) {\n const timeout = this._surveyTimeouts.get(surveyId)\n if (timeout) {\n clearTimeout(timeout)\n this._surveyTimeouts.delete(surveyId)\n }\n }\n\n /**\n * cancel a \"pending\" survey, i.e. one that is waiting to be displayed in\n * the _surveyTimeouts queue\n */\n public cancelSurvey(surveyId: string): void {\n // only works for surveys in the _surveyTimeouts queue...\n if (!this._surveyTimeouts.has(surveyId)) {\n return\n }\n\n logger.info(`Cancelled pending survey ${surveyId}`)\n this._clearSurveyTimeout(surveyId)\n\n // release focus - it was claimed when the delay timer started.\n // \"focus\" != \"survey is displayed\"\n if (this._surveyInFocus === surveyId) {\n this._surveyInFocus = null\n }\n }\n\n public handlePopoverSurvey = (surveyParam: Survey, options?: DisplaySurveyPopoverOptions): void => {\n const { survey: translatedSurvey, language: surveyLanguage } = this._translateSurveyForRendering(surveyParam)\n\n // apply overrides for position / selector (needed for thumb surveys)\n const survey =\n options?.position || options?.selector\n ? {\n ...translatedSurvey,\n appearance: {\n ...translatedSurvey.appearance,\n ...(options.position && { position: options.position }),\n ...(options.selector && { widgetSelector: options.selector }),\n },\n }\n : translatedSurvey\n\n this._clearSurveyTimeout(survey.id)\n\n const { properties, initialResponses } = options ?? {}\n const hasPrefillData = initialResponses && Object.keys(initialResponses).length > 0\n const isSurveyCompleted = hasPrefillData\n ? this._handleInitialResponses(survey, initialResponses, properties, surveyLanguage)\n : false\n\n // if the survey is done (from prefill) and there is no thank-you, we can break early\n if (isSurveyCompleted && !survey.appearance?.displayThankYouMessage) {\n return\n }\n\n this._addSurveyToFocus(survey)\n\n // Calculate position style for NextToTrigger positioning\n let positionStyle: JSX.CSSProperties = {}\n if (survey.appearance?.position === SurveyPosition.NextToTrigger && survey.appearance?.widgetSelector) {\n const targetElement = document.querySelector(survey.appearance.widgetSelector) as HTMLElement | null\n if (targetElement) {\n positionStyle =\n getNextToTriggerPosition(\n targetElement,\n parseInt(survey.appearance?.maxWidth || defaultSurveyAppearance.maxWidth)\n ) || {}\n }\n }\n\n const delaySeconds = survey.appearance?.surveyPopupDelaySeconds || 0\n const { shadow } = retrieveSurveyShadow(survey, this._posthog)\n\n const surveyPopupProps: SurveyPopupProps = {\n posthog: this._posthog,\n survey: survey,\n removeSurveyFromFocus: this._removeSurveyFromFocus,\n properties: properties,\n style: positionStyle,\n isSurveyCompleted: isSurveyCompleted,\n skipShownEvent: options?.skipShownEvent,\n surveyLanguage,\n }\n\n if (delaySeconds <= 0) {\n return render(<SurveyPopup {...surveyPopupProps} />, shadow)\n }\n const timeoutId = setTimeout(() => {\n // remove survey to keep `_surveyTimeouts` as a true list of \"pending\" surveys\n this._surveyTimeouts.delete(survey.id)\n\n // Re-check the full display predicate, not just the URL: eligibility can change\n // during the delay (e.g. identify() reloads flags and the internal targeting flag\n // flips to false), and we must not show a survey that is no longer eligible by the\n // time the delay elapses.\n if (!this._shouldDisplaySurvey(survey)) {\n logger.info(`Survey ${survey.id} no longer eligible when its display delay elapsed; not displaying`)\n return this._removeSurveyFromFocus(survey)\n }\n // rendering with surveyPopupDelaySeconds = 0 because we're already handling the timeout here\n render(\n <SurveyPopup\n {...surveyPopupProps}\n survey={{\n ...survey,\n appearance: {\n ...survey.appearance,\n surveyPopupDelaySeconds: 0,\n },\n }}\n />,\n shadow\n )\n }, delaySeconds * 1000)\n this._surveyTimeouts.set(survey.id, timeoutId)\n }\n\n private _handleWidget = (survey: Survey): void => {\n const { survey: translatedSurvey, language: surveyLanguage } = this._translateSurveyForRendering(survey)\n // Ensure widget container exists if it doesn't\n const { shadow, isNewlyCreated } = retrieveSurveyShadow(translatedSurvey, this._posthog)\n\n // If the widget is already rendered, do nothing. Otherwise the widget will be re-rendered every second\n if (!isNewlyCreated) {\n return\n }\n\n render(\n <FeedbackWidget\n posthog={this._posthog}\n survey={translatedSurvey}\n surveyLanguage={surveyLanguage}\n key={survey.id}\n />,\n shadow\n )\n }\n\n private _removeWidgetSelectorListener = (survey: Pick<Survey, 'id' | 'type' | 'appearance'>): void => {\n this._removeSurveyFromDom(survey)\n const existing = this._widgetSelectorListeners.get(survey.id)\n if (existing) {\n existing.element.removeEventListener('click', existing.listener)\n existing.element.removeAttribute(WIDGET_LISTENER_ATTRIBUTE)\n this._widgetSelectorListeners.delete(survey.id)\n logger.info(`Removed click listener for survey ${survey.id}`)\n }\n }\n\n private _manageWidgetSelectorListener = (survey: Survey, selector: string): void => {\n const currentElement = document.querySelector(selector)\n const existingListenerData = this._widgetSelectorListeners.get(survey.id)\n\n if (!currentElement) {\n if (existingListenerData) {\n this._removeWidgetSelectorListener(survey)\n }\n return\n }\n\n this._handleWidget(survey)\n\n if (existingListenerData) {\n // Listener exists, check if element changed\n if (currentElement !== existingListenerData.element) {\n logger.info(`Selector element changed for survey ${survey.id}. Re-attaching listener.`)\n this._removeWidgetSelectorListener(survey)\n // Continue to attach listener to the new element below\n } else {\n // Element is the same, listener already attached, do nothing\n return\n }\n }\n\n // Element found, and no listener attached (or it was just removed from old element)\n if (!currentElement.hasAttribute(WIDGET_LISTENER_ATTRIBUTE)) {\n const listener = (event: Event) => {\n event.stopPropagation() // Prevent bubbling\n\n const positionStyles =\n survey.appearance?.position === SurveyPosition.NextToTrigger\n ? getNextToTriggerPosition(\n event.currentTarget as HTMLElement,\n parseInt(survey.appearance?.maxWidth || defaultSurveyAppearance.maxWidth)\n )\n : {}\n\n window.dispatchEvent(\n new CustomEvent(DISPATCH_FEEDBACK_WIDGET_EVENT, {\n detail: { surveyId: survey.id, position: positionStyles },\n })\n )\n }\n\n addEventListener(currentElement, 'click', listener)\n currentElement.setAttribute(WIDGET_LISTENER_ATTRIBUTE, 'true')\n this._widgetSelectorListeners.set(survey.id, { element: currentElement, listener, survey })\n logger.info(`Attached click listener for feedback button survey ${survey.id}`)\n }\n }\n\n /**\n * Sorts surveys by their appearance delay in ascending order. If a survey does not have an appearance delay,\n * it is considered to have a delay of 0.\n * @param surveys\n * @returns The surveys sorted by their appearance delay\n */\n private _sortSurveysByAppearanceDelay(surveys: Survey[]): Survey[] {\n return surveys.sort((a, b) => {\n const isSurveyInProgressA = isSurveyInProgress(a)\n const isSurveyInProgressB = isSurveyInProgress(b)\n if (isSurveyInProgressA && !isSurveyInProgressB) {\n return -1 // a comes before b (in progress surveys first)\n }\n if (!isSurveyInProgressA && isSurveyInProgressB) {\n return 1 // a comes after b (in progress surveys first)\n }\n const aIsAlways = a.schedule === SurveySchedule.Always\n const bIsAlways = b.schedule === SurveySchedule.Always\n\n if (aIsAlways && !bIsAlways) {\n return 1 // a comes after b\n }\n if (!aIsAlways && bIsAlways) {\n return -1 // a comes before b\n }\n // If both are Always or neither is Always, sort by delay\n return (a.appearance?.surveyPopupDelaySeconds || 0) - (b.appearance?.surveyPopupDelaySeconds || 0)\n })\n }\n\n public renderPopover = (survey: Survey): void => {\n const { survey: translatedSurvey, language: surveyLanguage } = this._translateSurveyForRendering(survey)\n const { shadow } = retrieveSurveyShadow(translatedSurvey, this._posthog)\n render(\n <SurveyPopup\n posthog={this._posthog}\n survey={translatedSurvey}\n removeSurveyFromFocus={this._removeSurveyFromFocus}\n surveyLanguage={surveyLanguage}\n />,\n shadow\n )\n }\n\n public renderSurvey = (survey: Survey, selector: Element, properties?: Properties): void => {\n const { survey: translatedSurvey, language: surveyLanguage } = this._translateSurveyForRendering(survey)\n let isSurveyCompleted = false\n if (this._posthog.config?.surveys?.prefillFromUrl) {\n isSurveyCompleted = this._handleUrlPrefill(translatedSurvey, surveyLanguage)\n }\n\n render(\n <SurveyPopup\n posthog={this._posthog}\n survey={translatedSurvey}\n removeSurveyFromFocus={this._removeSurveyFromFocus}\n isPopup={false}\n properties={properties}\n isSurveyCompleted={isSurveyCompleted}\n surveyLanguage={surveyLanguage}\n />,\n selector\n )\n }\n\n private _translateSurveyForRendering(survey: Survey): { survey: Survey; language: string | null } {\n // Rendering entry points accept the raw API survey. The translation helper is idempotent,\n // but keeping this central avoids each entry point growing its own language rules.\n return applySurveyTranslationForUser(survey, this._posthog)\n }\n\n private _handleUrlPrefill(survey: Survey, surveyLanguage?: string | null): boolean {\n // Only handle prefill once per survey session to avoid overwriting in-progress responses\n if (this._prefillHandledSurveys.has(survey.id)) {\n return false\n }\n\n const { params } = extractPrefillParamsFromUrl(window.location.search)\n\n if (Object.keys(params).length === 0) {\n return false\n }\n\n logger.info('[Survey Prefill] Detected URL prefill parameters')\n\n const result = this._processPrefillData(survey, params, surveyLanguage)\n if (!result) {\n return false\n }\n\n const { responses, submissionId, isSurveyCompleted, skippedResponses } = result\n\n /**\n * auto-submit some survey events on pageload only if:\n * 1) survey is complete, OR\n * 2) partial responses are enabled AND the skipped questions were set to auto-submit\n */\n const shouldAutoSubmitPrefilled = Object.keys(skippedResponses).length > 0 && survey.enable_partial_responses\n if (shouldAutoSubmitPrefilled || isSurveyCompleted) {\n sendSurveyEvent({\n responses: isSurveyCompleted ? responses : skippedResponses,\n survey,\n surveySubmissionId: submissionId,\n posthog: this._posthog,\n isSurveyCompleted,\n surveyLanguage,\n })\n }\n\n // Mark this survey as having been prefilled\n this._prefillHandledSurveys.add(survey.id)\n\n return isSurveyCompleted\n }\n\n /**\n * process prefilled responses for non-hosted surveys\n *\n * @returns boolean, true if the survey is completed\n */\n private _handleInitialResponses(\n survey: Survey,\n initialResponses: Record<number, SurveyResponseValue>,\n properties?: Properties,\n surveyLanguage?: string | null\n ): boolean {\n const prefillParams: { [key: number]: string[] } = {}\n for (const [indexStr, value] of Object.entries(initialResponses)) {\n const index = parseInt(indexStr)\n prefillParams[index] = isArray(value) ? value.map(String) : [String(value)]\n }\n\n logger.info('[Survey] Processing initial responses')\n\n const result = this._processPrefillData(survey, prefillParams, surveyLanguage)\n if (!result) {\n return false\n }\n\n const { responses, submissionId, isSurveyCompleted } = result\n\n // always capture immediately\n sendSurveyEvent({\n responses,\n survey,\n surveySubmissionId: submissionId,\n posthog: this._posthog,\n isSurveyCompleted,\n properties,\n surveyLanguage,\n })\n\n return isSurveyCompleted\n }\n\n private _processPrefillData(\n survey: Survey,\n prefillParams: Record<number, string[]>,\n surveyLanguage?: string | null\n ): {\n responses: Record<string, any>\n submissionId: string\n startQuestionIndex: number\n isSurveyCompleted: boolean\n skippedResponses: Record<string, any>\n } | null {\n try {\n const responses = convertPrefillToResponses(survey, prefillParams)\n\n if (Object.keys(responses).length === 0) {\n logger.warn('[Survey Prefill] No valid responses after conversion')\n return null\n }\n\n const submissionId = uuidv7()\n\n // calculate which question to start at based on prefilled questions\n const prefilledIndices = Object.keys(prefillParams).map((k) => parseInt(k, 10))\n const { startQuestionIndex, skippedResponses } = calculatePrefillStartIndex(\n survey,\n prefilledIndices,\n responses\n )\n const isSurveyCompleted = startQuestionIndex >= survey.questions.length\n\n setInProgressSurveyState(survey, {\n surveySubmissionId: submissionId,\n responses: responses,\n lastQuestionIndex: startQuestionIndex,\n surveyLanguage,\n })\n\n logger.info('[Survey Prefill] Stored prefilled responses in localStorage')\n\n return { responses, submissionId, startQuestionIndex, isSurveyCompleted, skippedResponses }\n } catch (error) {\n logger.error('[Survey Prefill] Error handling prefill:', error)\n return null\n }\n }\n\n private _isSurveyFeatureFlagEnabled(flagKey: string | null, flagVariant: string | undefined = undefined) {\n if (!flagKey) {\n return true\n }\n const isFeatureEnabled = !!this._posthog.featureFlags?.isFeatureEnabled(flagKey, {\n send_event: !flagKey.startsWith(SURVEY_TARGETING_FLAG_PREFIX),\n })\n let flagVariantCheck = true\n if (flagVariant) {\n const flagVariantValue = this._posthog.featureFlags?.getFeatureFlag(flagKey, { send_event: false })\n flagVariantCheck = flagVariantValue === flagVariant || flagVariant === 'any'\n }\n return isFeatureEnabled && flagVariantCheck\n }\n\n private _isSurveyConditionMatched(survey: Survey): boolean {\n if (!survey.conditions) {\n return true\n }\n return (\n doesSurveyUrlMatch(survey, this._posthog) &&\n doesSurveyDeviceTypesMatch(survey) &&\n doesSurveyMatchSelector(survey)\n )\n }\n\n private _internalFlagCheckSatisfied(survey: Survey): boolean {\n return (\n canActivateRepeatedly(survey) ||\n this._isSurveyFeatureFlagEnabled(survey.internal_targeting_flag_key) ||\n isSurveyInProgress(survey)\n )\n }\n\n public checkSurveyEligibility(survey: Survey): { eligible: boolean; reason?: string } {\n const eligibility = { eligible: true, reason: undefined as string | undefined }\n\n if (!isSurveyRunning(survey)) {\n eligibility.eligible = false\n eligibility.reason = `Survey is not running. It was completed on ${survey.end_date}`\n return eligibility\n }\n\n if (!IN_APP_SURVEY_TYPES.includes(survey.type)) {\n eligibility.eligible = false\n eligibility.reason = `Surveys of type ${survey.type} are never eligible to be shown in the app`\n return eligibility\n }\n\n const linkedFlagVariant = survey.conditions?.linkedFlagVariant\n if (!this._isSurveyFeatureFlagEnabled(survey.linked_flag_key, linkedFlagVariant)) {\n eligibility.eligible = false\n if (!linkedFlagVariant) {\n eligibility.reason = `Survey linked feature flag is not enabled`\n } else {\n eligibility.reason = `Survey linked feature flag is not enabled for variant ${linkedFlagVariant}`\n }\n return eligibility\n }\n\n if (!this._isSurveyFeatureFlagEnabled(survey.targeting_flag_key)) {\n eligibility.eligible = false\n eligibility.reason = `Survey targeting feature flag is not enabled`\n return eligibility\n }\n\n if (!this._internalFlagCheckSatisfied(survey)) {\n eligibility.eligible = false\n eligibility.reason =\n 'Survey internal targeting flag is not enabled and survey cannot activate repeatedly and survey is not in progress'\n return eligibility\n }\n\n if (!hasWaitPeriodPassed(survey.conditions?.seenSurveyWaitPeriodInDays)) {\n eligibility.eligible = false\n eligibility.reason = `Survey wait period has not passed`\n return eligibility\n }\n\n if (getSurveySeen(survey)) {\n eligibility.eligible = false\n eligibility.reason = `Survey has already been seen and it can't be activated again`\n return eligibility\n }\n\n return eligibility\n }\n\n /**\n * Surveys can be activated by events or actions. This method checks if the survey has events and actions,\n * and if so, it checks if the survey has been activated.\n * @param survey\n */\n private _hasActionOrEventTriggeredSurvey(survey: Survey): boolean {\n if (!doesSurveyActivateByEvent(survey) && !doesSurveyActivateByAction(survey)) {\n // If survey doesn't depend on events/actions, it's considered \"triggered\" by default\n return true\n }\n const surveysActivatedByEventsOrActions: string[] | undefined =\n this._posthog.surveys?._surveyEventReceiver?.getSurveys()\n return !!surveysActivatedByEventsOrActions?.includes(survey.id)\n }\n\n private _checkFlags(survey: Survey): boolean {\n if (!survey.feature_flag_keys?.length) {\n return true\n }\n\n return survey.feature_flag_keys.every(({ key, value }) => {\n if (!key || !value) {\n return true\n }\n return this._isSurveyFeatureFlagEnabled(value)\n })\n }\n\n /**\n * The full predicate for \"should this survey display right now\": eligibility (running,\n * type, linked/targeting/internal flags, wait period, already-seen) plus the URL/device/\n * selector conditions, the event/action trigger, and any feature-flag dependencies.\n *\n * Shared by the display loop and re-checked when a popover's delay timer fires, so a\n * survey that became ineligible *during* the delay (e.g. an identify() reloaded flags and\n * the internal targeting flag is now false) is not shown. Note this is purely an AND gate:\n * adding it can only ever suppress a display, never cause an extra one.\n */\n private _shouldDisplaySurvey(survey: Survey): boolean {\n return (\n this.checkSurveyEligibility(survey).eligible &&\n this._isSurveyConditionMatched(survey) &&\n this._hasActionOrEventTriggeredSurvey(survey) &&\n this._checkFlags(survey)\n )\n }\n\n public getActiveMatchingSurveys = (callback: SurveyCallback, forceReload = false): void => {\n this._posthog?.surveys?.getSurveys((surveys) => {\n const targetingMatchedSurveys = surveys.filter((survey) => this._shouldDisplaySurvey(survey))\n callback(targetingMatchedSurveys)\n }, forceReload)\n }\n\n public callSurveysAndEvaluateDisplayLogic = (forceReload: boolean = false): void => {\n this.getActiveMatchingSurveys((surveys) => {\n const inAppSurveysWithDisplayLogic = surveys.filter(\n (survey) => survey.type === SurveyType.Popover || survey.type === SurveyType.Widget\n )\n\n // Cancel any pending (delayed, not-yet-shown) survey whose eligibility changed since\n // it was queued — e.g. an identify() during the delay flipped its targeting flag.\n // This frees the popover focus promptly instead of waiting for a now-stale timer to\n // fire. Safe for already-shown surveys: their timer is gone, so cancelSurvey no-ops.\n const matchingIds = new Set(inAppSurveysWithDisplayLogic.map((survey) => survey.id))\n for (const pendingSurveyId of Array.from(this._surveyTimeouts.keys())) {\n if (!matchingIds.has(pendingSurveyId)) {\n this.cancelSurvey(pendingSurveyId)\n }\n }\n\n // Create a queue of surveys sorted by their appearance delay. We will evaluate the display logic\n // for each survey in the queue in order, and only display one survey at a time.\n const inAppSurveysQueue = this._sortSurveysByAppearanceDelay(inAppSurveysWithDisplayLogic)\n\n // Keep track of surveys processed this cycle to remove listeners for inactive ones\n const activeSelectorSurveys = new Set<string>()\n\n inAppSurveysQueue.forEach((survey) => {\n // Widget Type Logic\n if (survey.type === SurveyType.Widget) {\n if (survey.appearance?.widgetType === SurveyWidgetType.Tab) {\n this._handleWidget(survey)\n return\n }\n\n // For selector widget types, we need to manage the listener attachment/detachment dynamically\n if (\n survey.appearance?.widgetType === SurveyWidgetType.Selector &&\n survey.appearance?.widgetSelector\n ) {\n activeSelectorSurveys.add(survey.id)\n this._manageWidgetSelectorListener(survey, survey.appearance?.widgetSelector)\n }\n }\n\n // Popover Type Logic (only one shown at a time)\n if (isNull(this._surveyInFocus) && survey.type === SurveyType.Popover) {\n this.handlePopoverSurvey(survey)\n }\n })\n\n // Clean up listeners for surveys that are no longer active or matched\n this._widgetSelectorListeners.forEach(({ survey }) => {\n if (!activeSelectorSurveys.has(survey.id)) {\n this._removeWidgetSelectorListener(survey)\n }\n })\n }, forceReload)\n }\n\n private _addSurveyToFocus = (survey: Pick<Survey, 'id'>): void => {\n if (!isNull(this._surveyInFocus)) {\n logger.error(`Survey ${this._surveyInFocus} already in focus. Cannot add survey ${survey.id}.`)\n }\n this._surveyInFocus = survey.id\n }\n\n private _removeSurveyFromDom(survey: Pick<Survey, 'id' | 'type' | 'appearance'>): void {\n try {\n const shadowContainer = document.querySelector(getSurveyContainerClass(survey, true))\n if (shadowContainer?.shadowRoot) {\n render(null, shadowContainer.shadowRoot)\n }\n shadowContainer?.remove()\n } catch (error) {\n logger.warn(`Failed to remove survey ${survey.id} from DOM:`, error)\n }\n }\n\n private _removeSurveyFromFocus = (survey: SurveyWithTypeAndAppearance): void => {\n if (this._surveyInFocus !== survey.id) {\n logger.error(`Survey ${survey.id} is not in focus. Cannot remove survey ${survey.id}.`)\n }\n this._clearSurveyTimeout(survey.id)\n this._surveyInFocus = null\n this._removeSurveyFromDom(survey)\n }\n\n // Expose internal state and methods for testing\n public getTestAPI() {\n return {\n addSurveyToFocus: this._addSurveyToFocus,\n removeSurveyFromFocus: this._removeSurveyFromFocus,\n surveyInFocus: this._surveyInFocus,\n surveyTimeouts: this._surveyTimeouts,\n handleWidget: this._handleWidget,\n handlePopoverSurvey: this.handlePopoverSurvey,\n manageWidgetSelectorListener: this._manageWidgetSelectorListener,\n sortSurveysByAppearanceDelay: this._sortSurveysByAppearanceDelay,\n checkFlags: this._checkFlags.bind(this),\n isSurveyFeatureFlagEnabled: this._isSurveyFeatureFlagEnabled.bind(this),\n }\n }\n}\n\nconst DEFAULT_PREVIEW_POSITION_STYLES: JSX.CSSProperties = {\n position: 'relative',\n left: 'unset',\n right: 'unset',\n top: 'unset',\n bottom: 'unset',\n transform: 'unset',\n}\n\nexport const renderSurveysPreview = ({\n survey,\n parentElement,\n previewPageIndex,\n forceDisableHtml,\n onPreviewSubmit,\n onPreviewBack,\n positionStyles = DEFAULT_PREVIEW_POSITION_STYLES,\n}: {\n survey: Survey\n parentElement: HTMLElement\n previewPageIndex: number\n forceDisableHtml?: boolean\n onPreviewSubmit?: (res: string | string[] | number | null) => void\n onPreviewBack?: () => void\n posthog?: PostHog\n positionStyles?: JSX.CSSProperties\n}) => {\n const currentStyle = parentElement.querySelector('style[data-ph-survey-style]')\n if (currentStyle) {\n currentStyle.remove()\n }\n const stylesheet = getSurveyStylesheet()\n if (stylesheet) {\n parentElement.appendChild(stylesheet)\n addSurveyCSSVariablesToElement(parentElement, survey.type, survey.appearance)\n }\n render(\n <SurveyPopup\n survey={survey}\n forceDisableHtml={forceDisableHtml}\n style={positionStyles}\n onPreviewSubmit={onPreviewSubmit}\n onPreviewBack={onPreviewBack}\n previewPageIndex={previewPageIndex}\n removeSurveyFromFocus={() => {}}\n />,\n parentElement\n )\n}\n\nexport const renderFeedbackWidgetPreview = ({\n survey,\n root,\n forceDisableHtml,\n}: {\n survey: Survey\n root: HTMLElement\n forceDisableHtml?: boolean\n}) => {\n const stylesheet = getSurveyStylesheet()\n if (stylesheet) {\n root.appendChild(stylesheet)\n addSurveyCSSVariablesToElement(root, survey.type, survey.appearance)\n }\n\n render(<FeedbackWidget forceDisableHtml={forceDisableHtml} survey={survey} readOnly={true} />, root)\n}\n\n// This is the main exported function\nexport function generateSurveys(posthog: PostHog, isSurveysEnabled: boolean | undefined) {\n // NOTE: Important to ensure we never try and run surveys without a window environment\n if (!document || !window) {\n return\n }\n\n const surveyManager = new SurveyManager(posthog)\n if (posthog.config.disable_surveys_automatic_display) {\n logger.info('Surveys automatic display is disabled. Skipping call surveys and evaluate display logic.')\n return surveyManager\n }\n\n // NOTE: The `generateSurveys` function used to accept just a single parameter, without any `isSurveysEnabled` parameter.\n // To keep compatibility with old clients, we'll consider `undefined` the same as `true`\n if (isSurveysEnabled === false) {\n logger.info('There are no surveys to load or Surveys is disabled in the project settings.')\n return surveyManager\n }\n\n surveyManager.callSurveysAndEvaluateDisplayLogic(true)\n\n let intervalId: number | undefined\n\n const startInterval = () => {\n if (!isUndefined(intervalId)) {\n return\n }\n intervalId = setInterval(() => {\n surveyManager.callSurveysAndEvaluateDisplayLogic(false)\n }, 1000) as unknown as number\n }\n\n const stopInterval = () => {\n if (!isUndefined(intervalId)) {\n clearInterval(intervalId)\n intervalId = undefined\n }\n }\n\n startInterval()\n\n addEventListener(document, 'visibilitychange', () => {\n if (document.hidden) {\n stopInterval()\n } else {\n surveyManager.callSurveysAndEvaluateDisplayLogic(false)\n startInterval()\n }\n })\n\n return surveyManager\n}\n\ntype UseHideSurveyOnURLChangeProps = {\n survey: Pick<Survey, 'id' | 'conditions' | 'type' | 'appearance'>\n removeSurveyFromFocus?: (survey: SurveyWithTypeAndAppearance) => void\n setSurveyVisible: (visible: boolean) => void\n isPreviewMode?: boolean\n posthog?: PostHog\n}\n\n/**\n * This hook handles URL-based survey visibility after the initial mount.\n * The initial URL check is handled by the `getActiveMatchingSurveys` method in the `PostHogSurveys` class,\n * which ensures the URL matches before displaying a survey for the first time.\n * That is the method that is called every second to see if there's a matching survey.\n *\n * This separation of concerns means:\n * 1. Initial URL matching is done by `getActiveMatchingSurveys` before displaying the survey\n * 2. Subsequent URL changes are handled here to hide the survey as the user navigates\n */\nexport function useHideSurveyOnURLChange({\n survey,\n removeSurveyFromFocus = () => {},\n setSurveyVisible,\n isPreviewMode = false,\n posthog,\n}: UseHideSurveyOnURLChangeProps) {\n useEffect(() => {\n if (isPreviewMode || !survey.conditions?.url) {\n return\n }\n\n const checkUrlMatch = () => {\n const isSurveyTypeWidget = survey.type === SurveyType.Widget\n const doesSurveyMatchUrlCondition = doesSurveyUrlMatch(survey, posthog)\n const isSurveyWidgetTypeTab = survey.appearance?.widgetType === SurveyWidgetType.Tab && isSurveyTypeWidget\n\n if (doesSurveyMatchUrlCondition) {\n if (isSurveyWidgetTypeTab) {\n logger.info(`Showing survey ${survey.id} because it is a feedback button tab and URL matches`)\n setSurveyVisible(true)\n }\n return\n }\n\n logger.info(`Hiding survey ${survey.id} because URL does not match`)\n setSurveyVisible(false)\n return removeSurveyFromFocus(survey)\n }\n\n // Listen for browser back/forward browser history changes\n addEventListener(window, 'popstate', checkUrlMatch)\n // Listen for hash changes, for SPA frameworks that use hash-based routing\n // The hashchange event is fired when the fragment identifier of the URL has changed (the part of the URL beginning with and following the # symbol).\n addEventListener(window, 'hashchange', checkUrlMatch)\n\n // Listen for SPA navigation\n const originalPushState = window.history.pushState\n const originalReplaceState = window.history.replaceState\n\n window.history.pushState = function (...args) {\n originalPushState.apply(this, args)\n checkUrlMatch()\n }\n\n window.history.replaceState = function (...args) {\n originalReplaceState.apply(this, args)\n checkUrlMatch()\n }\n\n return () => {\n window.removeEventListener('popstate', checkUrlMatch)\n window.removeEventListener('hashchange', checkUrlMatch)\n window.history.pushState = originalPushState\n window.history.replaceState = originalReplaceState\n }\n }, [isPreviewMode, survey, removeSurveyFromFocus, setSurveyVisible, posthog])\n}\n\nexport function usePopupVisibility(\n survey: Survey,\n posthog: PostHog | undefined,\n millisecondDelay: number,\n isPreviewMode: boolean,\n removeSurveyFromFocus: (survey: SurveyWithTypeAndAppearance) => void,\n isPopup: boolean,\n surveyContainerRef?: RefObject<HTMLDivElement>,\n skipShownEvent?: boolean,\n surveyLanguage?: string | null\n) {\n const [isPopupVisible, setIsPopupVisible] = useState(\n isPreviewMode || millisecondDelay === 0 || survey.type === SurveyType.ExternalSurvey\n )\n const [isSurveySent, setIsSurveySent] = useState(false)\n\n const hidePopupWithViewTransition = () => {\n const removeDOMAndHidePopup = () => {\n if (isPopup) {\n removeSurveyFromFocus(survey)\n }\n setIsPopupVisible(false)\n }\n\n if (!document.startViewTransition) {\n removeDOMAndHidePopup()\n return\n }\n\n const transition = document.startViewTransition(() => {\n surveyContainerRef?.current?.remove()\n })\n\n transition.finished.then(() => {\n setTimeout(() => {\n removeDOMAndHidePopup()\n }, 100)\n })\n }\n\n const handleSurveyClosed = (event: CustomEvent) => {\n if (event.detail.surveyId !== survey.id) {\n return\n }\n hidePopupWithViewTransition()\n }\n\n useEffect(() => {\n if (!posthog) {\n logger.error('usePopupVisibility hook called without a PostHog instance.')\n return\n }\n if (isPreviewMode) {\n return\n }\n\n const handleSurveySent = (event: CustomEvent) => {\n if (event.detail.surveyId !== survey.id) {\n return\n }\n if (!survey.appearance?.displayThankYouMessage) {\n return hidePopupWithViewTransition()\n }\n setIsSurveySent(true)\n if (survey.appearance?.autoDisappear) {\n setTimeout(() => {\n hidePopupWithViewTransition()\n }, 5000)\n }\n }\n\n const showSurvey = () => {\n // check if the url is still matching, necessary for delayed surveys, as the URL may have changed\n if (!doesSurveyUrlMatch(survey, posthog)) {\n return\n }\n setIsPopupVisible(true)\n window.dispatchEvent(new Event('PHSurveyShown'))\n if (!skipShownEvent) {\n posthog.capture(SurveyEventName.SHOWN, {\n [SurveyEventProperties.SURVEY_NAME]: survey.name,\n [SurveyEventProperties.SURVEY_ID]: survey.id,\n [SurveyEventProperties.SURVEY_ITERATION]: survey.current_iteration,\n [SurveyEventProperties.SURVEY_ITERATION_START_DATE]: survey.current_iteration_start_date,\n ...(surveyLanguage && { [SurveyEventProperties.SURVEY_LANGUAGE]: surveyLanguage }),\n sessionRecordingUrl: posthog.get_session_replay_url?.(),\n })\n }\n try {\n localStorage.setItem('lastSeenSurveyDate', new Date().toISOString())\n } catch {\n // localStorage is not always available (e.g. in cross-origin iframes).\n }\n }\n\n addEventListener(window, 'PHSurveyClosed', handleSurveyClosed as EventListener)\n addEventListener(window, 'PHSurveySent', handleSurveySent as EventListener)\n\n if (millisecondDelay > 0) {\n // This path is only used for direct usage of SurveyPopup,\n // not for surveys managed by SurveyManager\n const timeoutId = setTimeout(showSurvey, millisecondDelay)\n return () => {\n clearTimeout(timeoutId)\n window.removeEventListener('PHSurveyClosed', handleSurveyClosed as EventListener)\n window.removeEventListener('PHSurveySent', handleSurveySent as EventListener)\n }\n } else {\n // This is the path used for surveys managed by SurveyManager\n showSurvey()\n return () => {\n window.removeEventListener('PHSurveyClosed', handleSurveyClosed as EventListener)\n window.removeEventListener('PHSurveySent', handleSurveySent as EventListener)\n }\n }\n }, [])\n\n useHideSurveyOnURLChange({\n survey,\n removeSurveyFromFocus,\n setSurveyVisible: setIsPopupVisible,\n isPreviewMode,\n posthog,\n })\n\n return { isPopupVisible, isSurveySent, setIsPopupVisible, hidePopupWithViewTransition }\n}\n\ninterface SurveyPopupProps {\n survey: Survey\n forceDisableHtml?: boolean\n posthog?: PostHog\n style?: JSX.CSSProperties\n previewPageIndex?: number | undefined\n removeSurveyFromFocus?: (survey: SurveyWithTypeAndAppearance) => void\n isPopup?: boolean\n onPreviewSubmit?: (res: string | string[] | number | null) => void\n onPreviewBack?: () => void\n onPopupSurveyDismissed?: () => void\n onCloseConfirmationMessage?: () => void\n /** Additional properties to include in all survey events */\n properties?: Properties\n /** if true, survey popup will only render if there is a thank-you message */\n isSurveyCompleted?: boolean\n /** When true, `survey shown` events will not be emitted automatically */\n skipShownEvent?: boolean\n /** The language that was applied to the survey. */\n surveyLanguage?: string | null\n}\n\nfunction getTabPositionStyles(position: SurveyTabPosition = SurveyTabPosition.Right): JSX.CSSProperties {\n switch (position) {\n case SurveyTabPosition.Top:\n return { top: '0', left: '50%', transform: 'translateX(-50%)' }\n case SurveyTabPosition.Left:\n return { top: '50%', left: '0', transform: 'rotate(90deg) translateY(-100%)', transformOrigin: 'left top' }\n case SurveyTabPosition.Bottom: // bottom center\n return { bottom: '0', left: '50%', transform: 'translateX(-50%)' }\n default:\n case SurveyTabPosition.Right:\n // not perfectly centered vertically, to avoid a \"breaking\" change\n return {\n top: '50%',\n right: '0',\n transform: 'rotate(-90deg) translateY(-100%)',\n transformOrigin: 'right top',\n }\n }\n}\n\nexport function SurveyPopup({\n survey,\n forceDisableHtml,\n posthog,\n style = {},\n previewPageIndex,\n removeSurveyFromFocus = () => {},\n isPopup = true,\n onPreviewSubmit = () => {},\n onPreviewBack = () => {},\n onPopupSurveyDismissed = () => {},\n onCloseConfirmationMessage = () => {},\n properties,\n isSurveyCompleted,\n skipShownEvent,\n surveyLanguage,\n}: SurveyPopupProps) {\n const surveyContainerRef = useRef<HTMLDivElement>(null)\n const isPreviewMode = Number.isInteger(previewPageIndex)\n // NB: The client-side code passes the millisecondDelay in seconds, but setTimeout expects milliseconds, so we multiply by 1000\n const surveyPopupDelayMilliseconds = survey.appearance?.surveyPopupDelaySeconds\n ? survey.appearance.surveyPopupDelaySeconds * 1000\n : 0\n const { isPopupVisible, isSurveySent, hidePopupWithViewTransition } = usePopupVisibility(\n survey,\n posthog,\n surveyPopupDelayMilliseconds,\n isPreviewMode,\n removeSurveyFromFocus,\n isPopup,\n surveyContainerRef,\n skipShownEvent,\n surveyLanguage\n )\n\n /**\n * show confirmation if:\n * 1) isSurveySent is true (completed via normal flow)\n * 2) we're on the preview page for it\n * 3) the target start question (from prefill) is >= the length of the survey\n */\n const shouldShowConfirmation =\n isSurveySent || previewPageIndex === survey.questions.length || isSurveyCompleted === true\n\n const surveyContextValue = useMemo(() => {\n const getInProgressSurvey = getInProgressSurveyState(survey)\n const surveySubmissionId = getInProgressSurvey?.surveySubmissionId || uuidv7()\n return {\n isPreviewMode,\n previewPageIndex: previewPageIndex,\n onPopupSurveyDismissed: () => {\n if (surveyLanguage) {\n dismissedSurveyEvent(survey, posthog, isPreviewMode, surveyLanguage)\n } else {\n dismissedSurveyEvent(survey, posthog, isPreviewMode)\n }\n onPopupSurveyDismissed()\n },\n isPopup: isPopup || false,\n surveySubmissionId,\n onPreviewSubmit,\n onPreviewBack,\n posthog,\n properties,\n surveyLanguage,\n }\n }, [\n isPreviewMode,\n previewPageIndex,\n isPopup,\n posthog,\n survey,\n onPopupSurveyDismissed,\n onPreviewSubmit,\n onPreviewBack,\n properties,\n surveyLanguage,\n ])\n\n if (!isPopupVisible) {\n return null\n }\n\n return (\n <SurveyContext.Provider value={surveyContextValue}>\n <div\n className=\"ph-survey\"\n style={{\n ...getPopoverPosition(survey.type, survey.appearance?.position, survey.appearance?.widgetType),\n ...style,\n }}\n ref={surveyContainerRef}\n >\n {!shouldShowConfirmation ? (\n <Questions survey={survey} forceDisableHtml={!!forceDisableHtml} posthog={posthog} />\n ) : (\n <ConfirmationMessage\n header={survey.appearance?.thankYouMessageHeader || 'Thank you!'}\n description={survey.appearance?.thankYouMessageDescription || ''}\n forceDisableHtml={!!forceDisableHtml}\n contentType={survey.appearance?.thankYouMessageDescriptionContentType}\n appearance={survey.appearance || defaultSurveyAppearance}\n onClose={() => {\n hidePopupWithViewTransition()\n onCloseConfirmationMessage()\n }}\n />\n )}\n </div>\n </SurveyContext.Provider>\n )\n}\n\nexport function Questions({\n survey,\n forceDisableHtml,\n posthog,\n}: {\n survey: Survey\n forceDisableHtml: boolean\n posthog?: PostHog\n}) {\n // Initialize responses from localStorage or empty object\n const [questionsResponses, setQuestionsResponses] = useState(() => {\n const inProgressSurveyData = getInProgressSurveyState(survey)\n if (inProgressSurveyData?.responses) {\n logger.info('Survey is already in progress, filling in initial responses')\n }\n return inProgressSurveyData?.responses || {}\n })\n const {\n previewPageIndex,\n onPopupSurveyDismissed,\n isPopup,\n onPreviewSubmit,\n onPreviewBack,\n surveySubmissionId,\n isPreviewMode,\n properties,\n surveyLanguage,\n } = useContext(SurveyContext)\n const [currentQuestionIndex, setCurrentQuestionIndex] = useState(() => {\n const inProgressSurveyData = getInProgressSurveyState(survey)\n return previewPageIndex || inProgressSurveyData?.lastQuestionIndex || 0\n })\n const [visitedIndices, setVisitedIndices] = useState<number[]>(() => {\n const inProgressSurveyData = getInProgressSurveyState(survey)\n return inProgressSurveyData?.visitedIndices ?? []\n })\n const surveyQuestions = useMemo(() => getDisplayOrderQuestions(survey), [survey])\n\n // Sync preview state\n useEffect(() => {\n if (isPreviewMode && !isUndefined(previewPageIndex)) {\n setCurrentQuestionIndex(previewPageIndex)\n }\n }, [previewPageIndex, isPreviewMode])\n\n const onNextButtonClick = ({\n res,\n displayQuestionIndex,\n questionId,\n }: {\n res: string | string[] | number | null\n displayQuestionIndex: number\n questionId?: string\n }) => {\n if (!posthog) {\n logger.error('onNextButtonClick called without a PostHog instance.')\n return\n }\n\n if (!questionId) {\n logger.error('onNextButtonClick called without a questionId.')\n return\n }\n\n const responseKey = getSurveyResponseKey(questionId)\n\n const newResponses = { ...questionsResponses, [responseKey]: res }\n setQuestionsResponses(newResponses)\n\n const nextStep = getNextSurveyStep(survey, displayQuestionIndex, res)\n const isSurveyCompleted = nextStep === SurveyQuestionBranchingType.End\n const newVisitedIndices = [...visitedIndices, displayQuestionIndex]\n\n if (!isSurveyCompleted) {\n setVisitedIndices(newVisitedIndices)\n setCurrentQuestionIndex(nextStep)\n setInProgressSurveyState(survey, {\n surveySubmissionId: surveySubmissionId,\n responses: newResponses,\n lastQuestionIndex: nextStep,\n visitedIndices: newVisitedIndices,\n surveyLanguage,\n })\n }\n\n // If partial responses are enabled, send the survey sent event with with the responses,\n // otherwise only send the event when the survey is completed\n if (survey.enable_partial_responses || isSurveyCompleted) {\n // Only emit responses for questions actually on the path the user took. This prunes\n // ghost answers from branches the user abandoned by backing up and choosing differently.\n const visitedResponseKeys = new Set(\n newVisitedIndices\n .map((i) => surveyQuestions[i]?.id)\n .filter((id): id is string => !!id)\n .map((id) => getSurveyResponseKey(id))\n )\n const responsesOnPath = Object.fromEntries(\n Object.entries(newResponses).filter(([key]) => visitedResponseKeys.has(key))\n )\n sendSurveyEvent({\n responses: responsesOnPath,\n survey,\n surveySubmissionId,\n isSurveyCompleted,\n posthog,\n properties,\n surveyLanguage,\n })\n }\n }\n\n const onBackButtonClick = () => {\n // In preview mode the parent owns navigation (via previewPageIndex), so delegate to it.\n if (isPreviewMode) {\n onPreviewBack()\n return\n }\n if (visitedIndices.length === 0) {\n return\n }\n const previousIndex = visitedIndices[visitedIndices.length - 1]\n const newVisitedIndices = visitedIndices.slice(0, -1)\n setVisitedIndices(newVisitedIndices)\n setCurrentQuestionIndex(previousIndex)\n setInProgressSurveyState(survey, {\n surveySubmissionId,\n responses: questionsResponses,\n lastQuestionIndex: previousIndex,\n visitedIndices: newVisitedIndices,\n surveyLanguage,\n })\n }\n\n const canGoBack =\n !!survey.appearance?.allowGoBack && (isPreviewMode ? (previewPageIndex ?? 0) > 0 : visitedIndices.length > 0)\n\n const currentQuestion = surveyQuestions.at(currentQuestionIndex)\n\n if (!currentQuestion) {\n return null\n }\n\n const renderCancelButton = isPopup && survey.appearance?.hideCancelButton !== true\n\n return (\n <form className=\"survey-form\" name=\"surveyForm\">\n {renderCancelButton && (\n <Cancel\n onClick={() => {\n onPopupSurveyDismissed()\n }}\n />\n )}\n <div className=\"survey-box\" data-question-index={currentQuestionIndex}>\n {getQuestionComponent({\n question: currentQuestion,\n forceDisableHtml,\n displayQuestionIndex: currentQuestionIndex,\n appearance: survey.appearance || defaultSurveyAppearance,\n onSubmit: (res) =>\n onNextButtonClick({\n res,\n displayQuestionIndex: currentQuestionIndex,\n questionId: currentQuestion.id,\n }),\n onPreviewSubmit,\n initialValue: currentQuestion.id\n ? questionsResponses[getSurveyResponseKey(currentQuestion.id)]\n : undefined,\n canGoBack,\n onBack: onBackButtonClick,\n })}\n </div>\n </form>\n )\n}\n\nexport function FeedbackWidget({\n survey,\n forceDisableHtml,\n posthog,\n readOnly,\n surveyLanguage,\n}: {\n survey: Survey\n forceDisableHtml?: boolean\n posthog?: PostHog\n readOnly?: boolean\n surveyLanguage?: string | null\n}): JSX.Element | null {\n const [isFeedbackButtonVisible, setIsFeedbackButtonVisible] = useState(true)\n const [showSurvey, setShowSurvey] = useState(false)\n const [styleOverrides, setStyleOverrides] = useState<JSX.CSSProperties>({})\n\n const toggleSurvey = () => {\n setShowSurvey(!showSurvey)\n }\n\n useEffect(() => {\n if (!posthog) {\n logger.error('FeedbackWidget called without a PostHog instance.')\n return\n }\n if (readOnly) {\n return\n }\n\n if (survey.appearance?.widgetType === 'tab') {\n setStyleOverrides({\n top: '50%',\n bottom: 'auto',\n })\n }\n const handleShowSurvey = (event: Event) => {\n const customEvent = event as CustomEvent\n // Check if the event is for this specific survey instance\n if (customEvent.detail?.surveyId === survey.id) {\n logger.info(`Received show event for feedback button survey ${survey.id}`)\n setStyleOverrides(customEvent.detail.position || {})\n toggleSurvey()\n }\n }\n\n addEventListener(window, DISPATCH_FEEDBACK_WIDGET_EVENT, handleShowSurvey)\n\n // Cleanup listener on component unmount\n return () => {\n window.removeEventListener(DISPATCH_FEEDBACK_WIDGET_EVENT, handleShowSurvey)\n }\n }, [\n posthog,\n readOnly,\n survey.id,\n survey.appearance?.widgetType,\n survey.appearance?.widgetSelector,\n survey.appearance?.borderColor,\n ])\n\n useHideSurveyOnURLChange({\n survey,\n setSurveyVisible: setIsFeedbackButtonVisible,\n posthog,\n })\n\n if (!isFeedbackButtonVisible) {\n return null\n }\n\n const resetShowSurvey = () => {\n // hide the feedback button after answering or closing the survey if it's not always show\n if (survey.schedule !== SurveySchedule.Always) {\n setIsFeedbackButtonVisible(false)\n }\n // important so our view transition has time to run\n setTimeout(() => {\n setShowSurvey(false)\n }, 200)\n }\n\n return (\n <Fragment>\n {survey.appearance?.widgetType === 'tab' && (\n <button\n className={`ph-survey-widget-tab ${survey.appearance?.tabPosition === SurveyTabPosition.Top ? 'widget-tab-top' : ''}`}\n onClick={toggleSurvey}\n disabled={readOnly}\n style={getTabPositionStyles(survey.appearance?.tabPosition)}\n >\n {survey.appearance?.widgetLabel || ''}\n </button>\n )}\n {showSurvey && (\n <SurveyPopup\n posthog={posthog}\n survey={survey}\n forceDisableHtml={forceDisableHtml}\n style={styleOverrides}\n onPopupSurveyDismissed={resetShowSurvey}\n onCloseConfirmationMessage={resetShowSurvey}\n surveyLanguage={surveyLanguage}\n />\n )}\n </Fragment>\n )\n}\n\ninterface GetQuestionComponentProps extends CommonQuestionProps {\n question: SurveyQuestion\n displayQuestionIndex: number\n}\n\nconst getQuestionComponent = ({\n question,\n forceDisableHtml,\n displayQuestionIndex,\n appearance,\n onSubmit,\n onPreviewSubmit,\n initialValue,\n canGoBack,\n onBack,\n}: GetQuestionComponentProps): JSX.Element | null => {\n const baseProps = {\n forceDisableHtml,\n appearance,\n onPreviewSubmit: (res: string | string[] | number | null) => {\n onPreviewSubmit(res)\n },\n onSubmit: (res: string | string[] | number | null) => {\n onSubmit(res)\n },\n initialValue,\n displayQuestionIndex,\n canGoBack,\n onBack,\n }\n\n switch (question.type) {\n case SurveyQuestionType.Open:\n return <OpenTextQuestion {...baseProps} question={question} key={question.id} />\n case SurveyQuestionType.Link:\n return <LinkQuestion {...baseProps} question={question} key={question.id} />\n case SurveyQuestionType.Rating:\n return <RatingQuestion {...baseProps} question={question} key={question.id} />\n case SurveyQuestionType.SingleChoice:\n case SurveyQuestionType.MultipleChoice:\n return <MultipleChoiceQuestion {...baseProps} question={question} key={question.id} />\n default:\n logger.error(`Unsupported question type: ${(question as any).type}`)\n return null\n }\n}\n","import { Survey, SurveyQuestion, SurveyQuestionBranchingType, SurveyQuestionType } from '../posthog-surveys-types'\nimport { getSurveyResponseKey } from '../extensions/surveys/surveys-extension-utils'\nimport { logger } from './logger'\nimport { isUndefined } from '@posthog/core'\nimport { getNextSurveyStep } from './survey-branching'\n\n/**\n * Extracted URL prefill parameters by question index\n */\nexport interface PrefillParams {\n [questionIndex: number]: string[]\n}\n\n/**\n * Extract prefill parameters from URL search string\n * Format: ?q0=1&q1=8&q2=0&q2=2&auto_submit=true\n * NOTE: Manual parsing for IE11/op_mini compatibility (no URLSearchParams)\n */\nexport function extractPrefillParamsFromUrl(searchString: string): {\n params: PrefillParams\n autoSubmit: boolean\n} {\n const params: PrefillParams = {}\n let autoSubmit = false\n\n // Remove leading ? if present\n const cleanSearch = searchString.replace(/^\\?/, '')\n if (!cleanSearch) {\n return { params, autoSubmit }\n }\n\n // Split by & to get key-value pairs\n const pairs = cleanSearch.split('&')\n\n for (const pair of pairs) {\n const [key, value] = pair.split('=')\n if (!key || isUndefined(value)) {\n continue\n }\n\n const decodedKey = decodeURIComponent(key)\n const decodedValue = decodeURIComponent(value)\n\n // Check for auto_submit parameter\n if (decodedKey === 'auto_submit' && decodedValue === 'true') {\n autoSubmit = true\n continue\n }\n\n // Check for question parameters (q0, q1, etc.)\n const match = decodedKey.match(/^q(\\d+)$/)\n if (match) {\n const questionIndex = parseInt(match[1], 10)\n if (!params[questionIndex]) {\n params[questionIndex] = []\n }\n params[questionIndex].push(decodedValue)\n }\n }\n\n return { params, autoSubmit }\n}\n\n/**\n * Convert URL prefill values to SDK response format\n */\nexport function convertPrefillToResponses(survey: Survey, prefillParams: PrefillParams): Record<string, any> {\n const responses: Record<string, any> = {}\n\n survey.questions.forEach((question: SurveyQuestion, index: number) => {\n if (!prefillParams[index] || !question.id) {\n return\n }\n\n const values = prefillParams[index]\n const responseKey = getSurveyResponseKey(question.id)\n\n try {\n switch (question.type) {\n case SurveyQuestionType.SingleChoice: {\n if (!question.choices || question.choices.length === 0) {\n logger.warn(`[Survey Prefill] Question ${index} has no choices`)\n return\n }\n const choiceIndex = parseInt(values[0], 10)\n if (isNaN(choiceIndex) || choiceIndex < 0 || choiceIndex >= question.choices.length) {\n logger.warn(`[Survey Prefill] Invalid choice index for q${index}: ${values[0]}`)\n return\n }\n responses[responseKey] = question.choices[choiceIndex]\n break\n }\n\n case SurveyQuestionType.MultipleChoice: {\n if (!question.choices || question.choices.length === 0) {\n logger.warn(`[Survey Prefill] Question ${index} has no choices`)\n return\n }\n const choiceIndices = values\n .map((v) => parseInt(v, 10))\n .filter((i) => !isNaN(i) && i >= 0 && i < question.choices.length)\n\n if (choiceIndices.length === 0) {\n logger.warn(`[Survey Prefill] No valid choices for q${index}`)\n return\n }\n\n // Remove duplicates and map to choice values\n const uniqueChoices = [...new Set(choiceIndices.map((i) => question.choices[i]))]\n if (uniqueChoices.length < choiceIndices.length) {\n logger.warn(`[Survey Prefill] Removed duplicate choices for q${index}`)\n }\n responses[responseKey] = uniqueChoices\n break\n }\n\n case SurveyQuestionType.Rating: {\n const rating = parseInt(values[0], 10)\n const scale = question.scale || 10\n\n if (isNaN(rating) || rating < 0 || rating > scale) {\n logger.warn(`[Survey Prefill] Invalid rating for q${index}: ${values[0]} (scale: 0-${scale})`)\n return\n }\n responses[responseKey] = rating\n break\n }\n\n default:\n logger.info(`[Survey Prefill] Question type ${question.type} does not support prefill`)\n }\n } catch (error) {\n logger.error(`[Survey Prefill] Error converting q${index}:`, error)\n }\n })\n\n return responses\n}\n\n/**\n * Calculate which question index to start at based on prefilled questions.\n * Advances past consecutive prefilled questions (starting from index 0)\n * that have skipSubmitButton enabled, respecting any branching logic configured\n * on those questions.\n *\n * @param survey - The full survey object (needed for branching logic)\n * @param prefilledIndices - Array of question indices that have been prefilled\n * @param responses - Map of response keys to response values\n * @returns Object with startQuestionIndex and map of questions which have been skipped\n */\nexport function calculatePrefillStartIndex(\n survey: Survey,\n prefilledIndices: number[],\n responses: Record<string, any>\n): { startQuestionIndex: number; skippedResponses: Record<string, any> } {\n let currentIndex = 0\n const skippedResponses: Record<string, any> = {}\n\n const MAX_ITERATIONS = survey.questions.length + 1\n const iterations = 0\n while (currentIndex < survey.questions.length && iterations < MAX_ITERATIONS) {\n // Stop if current question is not prefilled\n if (!prefilledIndices.includes(currentIndex)) {\n break\n }\n\n const question = survey.questions[currentIndex]\n\n // Only advance if the prefilled question has skipSubmitButton\n if (!question || !('skipSubmitButton' in question) || !question.skipSubmitButton) {\n // Show question if skipSubmitButton is false, even if prefilled\n break\n }\n\n // Record the skipped response\n if (question.id) {\n const responseKey = getSurveyResponseKey(question.id)\n if (!isUndefined(responses[responseKey])) {\n skippedResponses[responseKey] = responses[responseKey]\n }\n }\n\n // Use branching logic to determine the next question\n const response = question.id ? responses[getSurveyResponseKey(question.id)] : null\n const nextStep = getNextSurveyStep(survey, currentIndex, response)\n\n if (nextStep === SurveyQuestionBranchingType.End) {\n // Survey is complete - return questions.length to indicate completion\n return { startQuestionIndex: survey.questions.length, skippedResponses }\n }\n\n // Move to the next question (respecting branching)\n currentIndex = nextStep\n }\n\n return { startQuestionIndex: currentIndex, skippedResponses }\n}\n","import { generateSurveys } from '../extensions/surveys'\n\nimport { assignableWindow } from '../utils/globals'\n\nassignableWindow.__PosthogExtensions__ = assignableWindow.__PosthogExtensions__ || {}\nassignableWindow.__PosthogExtensions__.generateSurveys = generateSurveys\n\n// this used to be directly on window, but we moved it to __PosthogExtensions__\n// it is still on window for backwards compatibility\nassignableWindow.extendPostHogWithSurveys = generateSurveys\n\nexport default generateSurveys\n","import { assignableWindow } from '../utils/globals'\nimport { PostHog } from '../posthog-core'\nimport { isArray, isBoolean, isFunction, isNull, isNumber, isObject } from '@posthog/core'\nimport type { LogSeverityLevel } from '@posthog/types'\n\nconst LOG_BODY_SIZE_LIMIT = 10000\nconst LOG_ATTRIBUTES_LIMIT = 50\n\ntype StringifyBudget = {\n remaining: number\n truncated: boolean\n}\n\ntype AttributeCollector = {\n result: Record<string, any>\n keysRemaining: number\n sizeRemaining: number\n truncated: boolean\n seen: WeakSet<object>\n}\n\nconst appendWithLimit = (parts: string[], text: string, budget: StringifyBudget): boolean => {\n if (budget.remaining <= 0) {\n budget.truncated = true\n return false\n }\n\n if (text.length <= budget.remaining) {\n parts.push(text)\n budget.remaining -= text.length\n return true\n }\n\n parts.push(text.slice(0, budget.remaining))\n budget.remaining = 0\n budget.truncated = true\n return false\n}\n\nconst stringifyStringWithLimit = (value: string, parts: string[], budget: StringifyBudget): boolean => {\n const serialized = JSON.stringify(value)\n if (serialized.length <= budget.remaining) {\n return appendWithLimit(parts, serialized, budget)\n }\n\n budget.truncated = true\n if (budget.remaining < 2) {\n return false\n }\n\n let low = 0\n let high = Math.min(value.length, budget.remaining - 2)\n while (low < high) {\n const mid = Math.ceil((low + high) / 2)\n if (JSON.stringify(value.slice(0, mid)).length <= budget.remaining) {\n low = mid\n } else {\n high = mid - 1\n }\n }\n\n return appendWithLimit(parts, JSON.stringify(value.slice(0, low)), budget)\n}\n\nconst isJSONSerializablePrimitive = (value: any): boolean =>\n typeof value !== 'undefined' &&\n typeof value !== 'function' &&\n typeof value !== 'symbol' &&\n typeof value !== 'bigint'\n\nconst isNumberOrBoolean = (value: any): boolean => {\n try {\n return isNumber(value) || isBoolean(value)\n } catch {\n return false\n }\n}\n\nconst collectAttributeValue = (key: string, value: any, collector: AttributeCollector): void => {\n if (collector.truncated) {\n return\n }\n\n collector.keysRemaining -= 1\n collector.sizeRemaining -= String(value).length + key.length\n if (collector.keysRemaining <= 0 || collector.sizeRemaining <= 0) {\n collector.truncated = true\n collector.result['attributes_truncated'] = true\n return\n }\n\n collector.result[key] = value\n}\n\nconst collectFlattenedAttributes = (value: any, key: string, collector: AttributeCollector): void => {\n if (collector.truncated) {\n return\n }\n\n if (isObject(value)) {\n if (collector.seen.has(value)) {\n collectAttributeValue(key || 'circular', '[Circular]', collector)\n return\n }\n collector.seen.add(value)\n\n try {\n for (const childKey in value) {\n try {\n if (!Object.prototype.hasOwnProperty.call(value, childKey)) {\n continue\n }\n const childValue = value[childKey]\n collectFlattenedAttributes(childValue, key ? `${key}.${childKey}` : childKey, collector)\n if (collector.truncated) {\n return\n }\n } catch {\n continue\n }\n }\n } catch {\n // we'll omit this object's properties considering we can't enumerate them\n }\n return\n }\n\n collectAttributeValue(key, value, collector)\n}\n\nconst stringifyValueWithLimit = (\n value: any,\n parts: string[],\n budget: StringifyBudget,\n seen: WeakSet<object>,\n inArray = false,\n attributeCollector?: AttributeCollector\n): boolean => {\n if (!isJSONSerializablePrimitive(value)) {\n return inArray ? appendWithLimit(parts, 'null', budget) : true\n }\n\n if (isNull(value) || isNumberOrBoolean(value)) {\n return appendWithLimit(parts, JSON.stringify(value), budget)\n }\n\n if (typeof value === 'string') {\n return stringifyStringWithLimit(value, parts, budget)\n }\n\n if (!isObject(value) && !isArray(value)) {\n return appendWithLimit(parts, JSON.stringify(value), budget)\n }\n\n if (seen.has(value)) {\n return stringifyStringWithLimit('[Circular]', parts, budget)\n }\n seen.add(value)\n\n try {\n const toJSON = (value as any).toJSON\n if (isFunction(toJSON)) {\n return stringifyValueWithLimit(toJSON.call(value), parts, budget, seen, inArray)\n }\n } catch {\n // If toJSON can't be read or throws, fall through to safe property enumeration.\n }\n\n try {\n const objectTag = Object.prototype.toString.call(value)\n if (objectTag === '[object String]') {\n return stringifyStringWithLimit(String(value.valueOf()), parts, budget)\n }\n\n if (objectTag === '[object Number]' || objectTag === '[object Boolean]') {\n return appendWithLimit(parts, JSON.stringify(value.valueOf()), budget)\n }\n } catch {\n // If Object.prototype.toString or valueOf throws, fall through to safe property enumeration.\n }\n\n if (value instanceof Error) {\n const errorObject: Record<string, any> = {}\n try {\n for (const key in value) {\n if (Object.prototype.hasOwnProperty.call(value, key)) {\n errorObject[key] = value[key as keyof Error]\n }\n }\n } catch {}\n try {\n errorObject.name = value.name\n } catch {}\n try {\n errorObject.message = value.message\n } catch {}\n try {\n errorObject.stack = value.stack\n } catch {}\n return stringifyValueWithLimit(errorObject, parts, budget, seen, inArray, attributeCollector)\n }\n\n if (isArray(value)) {\n if (!appendWithLimit(parts, '[', budget)) {\n return false\n }\n for (let i = 0; i < value.length; i++) {\n if (i > 0 && !appendWithLimit(parts, ',', budget)) {\n return false\n }\n let item\n try {\n item = value[i]\n } catch {\n item = undefined\n }\n if (!stringifyValueWithLimit(item, parts, budget, seen, true)) {\n return false\n }\n }\n return appendWithLimit(parts, ']', budget)\n }\n\n if (!appendWithLimit(parts, '{', budget)) {\n return false\n }\n let isFirst = true\n try {\n for (const key in value) {\n if (!Object.prototype.hasOwnProperty.call(value, key)) {\n continue\n }\n if (budget.remaining <= 0) {\n budget.truncated = true\n return false\n }\n\n let propertyValue\n try {\n propertyValue = value[key]\n } catch {\n continue\n }\n if (attributeCollector) {\n try {\n collectFlattenedAttributes(propertyValue, key, attributeCollector)\n } catch {\n // we'll omit this object's attributes considering we can't read them safely\n }\n }\n\n if (!isJSONSerializablePrimitive(propertyValue)) {\n continue\n }\n\n const propertyPrefix = `${isFirst ? '' : ','}${JSON.stringify(key)}:`\n if (propertyPrefix.length >= budget.remaining) {\n budget.truncated = true\n return false\n }\n\n const partsBeforeProperty = parts.length\n const remainingBeforeProperty = budget.remaining\n const truncatedBeforeProperty = budget.truncated\n if (!appendWithLimit(parts, propertyPrefix, budget)) {\n return false\n }\n\n const partsBeforeValue = parts.length\n const serialized = stringifyValueWithLimit(propertyValue, parts, budget, seen, false)\n const truncatedAfterValue = budget.truncated\n if (parts.length === partsBeforeValue) {\n parts.length = partsBeforeProperty\n budget.remaining = remainingBeforeProperty\n budget.truncated = serialized ? truncatedBeforeProperty : truncatedAfterValue\n if (!serialized) {\n return false\n }\n continue\n }\n\n isFirst = false\n if (!serialized) {\n return false\n }\n }\n } catch {\n // we'll omit this object's properties considering we can't enumerate them\n }\n return appendWithLimit(parts, '}', budget)\n}\n\nconst stringifyArgsSafely = (\n args: any[],\n sizeLimit: number\n): { body: string; truncated: boolean; attributes: Record<string, any> } => {\n const parts: string[] = []\n const budget = { remaining: sizeLimit, truncated: false }\n const attributeCollector = isObject(args[0])\n ? {\n result: {} as Record<string, any>,\n keysRemaining: LOG_ATTRIBUTES_LIMIT,\n sizeRemaining: LOG_BODY_SIZE_LIMIT,\n truncated: false,\n seen: new WeakSet<object>([args[0]]),\n }\n : undefined\n\n for (let i = 0; i < args.length; i++) {\n if (i > 0 && !appendWithLimit(parts, ' ', budget)) {\n break\n }\n if (\n !stringifyValueWithLimit(\n args[i],\n parts,\n budget,\n new WeakSet<object>(),\n false,\n i === 0 ? attributeCollector : undefined\n )\n ) {\n break\n }\n }\n\n return {\n body: parts.join('') + (budget.truncated ? '...' : ''),\n truncated: budget.truncated,\n attributes: attributeCollector?.result || {},\n }\n}\n\ntype ConsoleLevel = 'debug' | 'log' | 'warn' | 'error' | 'info'\n\n// Console method → OTLP severity level. `log` and `info` both map to `info`;\n// the originating method is preserved separately via the `log.source` attribute.\nconst LEVEL_MAP: Record<ConsoleLevel, LogSeverityLevel> = {\n debug: 'debug',\n log: 'info',\n warn: 'warn',\n error: 'error',\n info: 'info',\n}\n\nconst initializeLogs = (posthog: PostHog) => {\n // `host` is carried here because the core SDK context has no equivalent. Session\n // attributes (window.id, sessionStartTimestamp, lastActivityTimestamp) are added\n // downstream by the core pipeline from the SDK context, alongside sessionId.\n const attributes: Record<string, string> = { host: assignableWindow.location.host }\n\n for (const level of Object.keys(LEVEL_MAP) as ConsoleLevel[]) {\n const logWrapper =\n (originalConsoleLog: any) =>\n (...args: any[]) => {\n try {\n if (args.length > 0 && posthog.is_capturing()) {\n const {\n body,\n truncated,\n attributes: flattenedAttributes,\n } = stringifyArgsSafely(args, LOG_BODY_SIZE_LIMIT)\n const logAttributes = {\n ...attributes,\n ...(truncated ? { body_truncated: 'true' } : {}),\n }\n // The core pipeline adds posthogDistinctId and url.full from the SDK context.\n posthog.logs?._captureConsoleLog({\n level: LEVEL_MAP[level],\n body,\n attributes: {\n 'log.source': `console.${level}`,\n ...logAttributes,\n ...flattenedAttributes,\n },\n })\n }\n } catch {\n // Capture must never break the page's own console output, so the\n // real console call below always runs even if capture throws.\n } finally {\n originalConsoleLog.apply(assignableWindow.console, args)\n }\n }\n\n const originalConsoleLog = assignableWindow.console[level]\n assignableWindow.console[level] = logWrapper(originalConsoleLog)\n }\n}\n\nassignableWindow.__PosthogExtensions__ = assignableWindow.__PosthogExtensions__ || {}\nassignableWindow.__PosthogExtensions__.logs = { initializeLogs }\n","import { ERROR_TRACKING_CAPTURE_EXTENSION_EXCEPTIONS, ERROR_TRACKING_SUPPRESSION_RULES } from './constants'\nimport { Extension } from './extensions/types'\nimport { PostHog } from './posthog-core'\nimport { CaptureResult, ErrorTrackingSuppressionRule, Properties, RemoteConfig } from './types'\nimport { createLogger } from './utils/logger'\nimport { propertyComparisons } from './utils/property-utils'\nimport { isString, isArray, isObject, ErrorTracking, isNullish } from '@posthog/core'\n\nconst logger = createLogger('[Error tracking]')\n\nexport function buildErrorPropertiesBuilder() {\n return new ErrorTracking.ErrorPropertiesBuilder(\n [\n new ErrorTracking.DOMExceptionCoercer(),\n new ErrorTracking.PromiseRejectionEventCoercer(),\n new ErrorTracking.ErrorEventCoercer(),\n new ErrorTracking.ErrorCoercer(),\n new ErrorTracking.EventCoercer(),\n new ErrorTracking.ObjectCoercer(),\n new ErrorTracking.StringCoercer(),\n new ErrorTracking.PrimitiveCoercer(),\n ],\n ErrorTracking.createDefaultStackParser()\n )\n}\nexport class PostHogExceptions implements Extension {\n private readonly _instance: PostHog\n private _suppressionRules: ErrorTrackingSuppressionRule[] = []\n private _errorPropertiesBuilder: ErrorTracking.ErrorPropertiesBuilder = buildErrorPropertiesBuilder()\n private _exceptionStepsBuffer: ErrorTracking.ExceptionStepsBuffer\n private _exceptionStepsConfig: ErrorTracking.ResolvedExceptionStepsConfig\n\n constructor(instance: PostHog) {\n this._instance = instance\n this._suppressionRules = this._instance.persistence?.get_property(ERROR_TRACKING_SUPPRESSION_RULES) ?? []\n this._exceptionStepsConfig = ErrorTracking.resolveExceptionStepsConfig(this._getExceptionStepsConfig())\n this._exceptionStepsBuffer = new ErrorTracking.ExceptionStepsBuffer(this._exceptionStepsConfig)\n }\n\n onConfigChange() {\n this._exceptionStepsConfig = ErrorTracking.resolveExceptionStepsConfig(this._getExceptionStepsConfig())\n this._exceptionStepsBuffer.setConfig(this._exceptionStepsConfig)\n }\n\n onRemoteConfig(response: RemoteConfig) {\n if (!('errorTracking' in response)) {\n return\n }\n\n const suppressionRules = response.errorTracking?.suppressionRules ?? []\n const captureExtensionExceptions = response.errorTracking?.captureExtensionExceptions\n\n // store this in-memory in case persistence is disabled\n this._suppressionRules = suppressionRules\n\n if (this._instance.persistence) {\n this._instance.persistence.register({\n [ERROR_TRACKING_SUPPRESSION_RULES]: this._suppressionRules,\n [ERROR_TRACKING_CAPTURE_EXTENSION_EXCEPTIONS]: captureExtensionExceptions,\n })\n }\n }\n\n private get _captureExtensionExceptions() {\n const enabled_server_side = !!this._instance.get_property(ERROR_TRACKING_CAPTURE_EXTENSION_EXCEPTIONS)\n const enabled_client_side = this._instance.config.error_tracking.captureExtensionExceptions\n return enabled_client_side ?? enabled_server_side ?? false\n }\n\n buildProperties(\n input: unknown,\n metadata?: { handled?: boolean; syntheticException?: Error }\n ): ErrorTracking.ErrorProperties {\n return this._errorPropertiesBuilder.buildFromUnknown(input, {\n syntheticException: metadata?.syntheticException,\n mechanism: {\n handled: metadata?.handled,\n },\n })\n }\n\n addExceptionStep(message: string, properties?: Properties): void {\n if (!this._exceptionStepsConfig.enabled) {\n return\n }\n\n try {\n if (!isString(message) || message.trim().length === 0) {\n logger.warn('Ignoring exception step because message must be a non-empty string')\n return\n }\n\n const userProperties = this._coerceExceptionStepProperties(properties)\n\n const { sanitizedProperties, droppedKeys } = ErrorTracking.stripReservedExceptionStepFields(userProperties)\n\n if (droppedKeys.length > 0) {\n logger.warn('Ignoring reserved exception step fields', { droppedKeys })\n }\n\n this._exceptionStepsBuffer.add({\n [ErrorTracking.EXCEPTION_STEP_INTERNAL_FIELDS.MESSAGE]: message,\n [ErrorTracking.EXCEPTION_STEP_INTERNAL_FIELDS.TIMESTAMP]: new Date().toISOString(),\n ...sanitizedProperties,\n })\n } catch (error) {\n logger.error('Failed to add exception step. Ignoring breadcrumb.', error)\n }\n }\n\n sendExceptionEvent(properties: Properties): CaptureResult | undefined {\n try {\n const exceptionList = properties.$exception_list\n\n if (this._isExceptionList(exceptionList)) {\n if (this._matchesSuppressionRule(exceptionList)) {\n this._addDroppedExceptionStep('Exception dropped: matched a suppression rule')\n logger.info('Skipping exception capture because a suppression rule matched')\n return\n }\n\n if (!this._captureExtensionExceptions && this._isExtensionException(exceptionList)) {\n this._addDroppedExceptionStep('Exception dropped: thrown by a browser extension')\n logger.info('Skipping exception capture because it was thrown by an extension')\n return\n }\n\n if (\n !this._instance.config.error_tracking.__capturePostHogExceptions &&\n this._isPostHogException(exceptionList)\n ) {\n this._addDroppedExceptionStep('Exception dropped: thrown by the PostHog SDK')\n logger.info('Skipping exception capture because it was thrown by the PostHog SDK')\n return\n }\n }\n\n const propertiesForExceptionCapture =\n this._exceptionStepsConfig.enabled && isNullish(properties.$exception_steps)\n ? this._addBufferedExceptionSteps(properties)\n : properties\n\n try {\n const result = this._instance.capture('$exception', propertiesForExceptionCapture, {\n _noTruncate: true,\n _batchKey: 'exceptionEvent',\n _originatedFromCaptureException: true,\n })\n\n if (result) {\n this._exceptionStepsBuffer.clear()\n }\n\n return result\n } catch (error) {\n logger.error('Failed to capture exception event. Dropping this exception.', error)\n this._exceptionStepsBuffer.clear()\n return\n }\n } catch (error) {\n logger.error('Failed to process exception event. Ignoring this exception.', error)\n return\n }\n }\n\n private _addBufferedExceptionSteps(properties: Properties): Properties {\n try {\n const exceptionSteps = this._exceptionStepsBuffer.getAttachable()\n\n if (exceptionSteps.length === 0) {\n return properties\n }\n\n return {\n ...properties,\n $exception_steps: exceptionSteps,\n }\n } catch (error) {\n logger.error('Failed to read buffered exception steps. Capturing exception without steps.', error)\n return properties\n }\n }\n\n private _addDroppedExceptionStep(message: string): void {\n if (this._exceptionStepsConfig.enabled) {\n this._exceptionStepsBuffer.add({\n [ErrorTracking.EXCEPTION_STEP_INTERNAL_FIELDS.MESSAGE]: message,\n [ErrorTracking.EXCEPTION_STEP_INTERNAL_FIELDS.TIMESTAMP]: new Date().toISOString(),\n })\n }\n }\n\n private _coerceExceptionStepProperties(properties?: Properties): Record<string, unknown> {\n if (!isObject(properties)) {\n return {}\n }\n\n return { ...(properties as Record<string, unknown>) }\n }\n\n private _getExceptionStepsConfig(): ErrorTracking.ExceptionStepsConfig {\n return this._instance.config.error_tracking?.exception_steps ?? {}\n }\n\n private _matchesSuppressionRule(exceptionList: ErrorTracking.ExceptionList): boolean {\n if (exceptionList.length === 0) {\n return false\n }\n\n const exceptionValues = exceptionList.reduce(\n (acc, { type, value }) => {\n if (isString(type) && type.length > 0) {\n acc['$exception_types'].push(type)\n }\n if (isString(value) && value.length > 0) {\n acc['$exception_values'].push(value)\n }\n return acc\n },\n {\n $exception_types: [] as string[],\n $exception_values: [] as string[],\n }\n )\n\n return this._suppressionRules.some((rule) => {\n const results = rule.values.map((v) => {\n const compare = propertyComparisons[v.operator]\n const targets = isArray(v.value) ? v.value : [v.value]\n const values = exceptionValues[v.key] ?? []\n return targets.length > 0 ? compare(targets, values) : false\n })\n return rule.type === 'OR' ? results.some(Boolean) : results.every(Boolean)\n })\n }\n\n private _isExtensionException(exceptionList: ErrorTracking.ExceptionList): boolean {\n const frames = exceptionList.flatMap((e) => e.stacktrace?.frames ?? [])\n return frames.some((f) => f.filename && f.filename.startsWith('chrome-extension://'))\n }\n\n private _isPostHogException(exceptionList: ErrorTracking.ExceptionList): boolean {\n if (exceptionList.length > 0) {\n const exception = exceptionList[0]\n const frames = exception.stacktrace?.frames ?? []\n const lastFrame = frames[frames.length - 1]\n return lastFrame?.filename?.includes('posthog.com/static') ?? false\n }\n\n return false\n }\n\n private _isExceptionList(candidate: unknown): candidate is ErrorTracking.ExceptionList {\n return !isNullish(candidate) && isArray(candidate)\n }\n}\n","import { assignableWindow, window } from '../utils/globals'\nimport { ErrorEventArgs } from '../types'\nimport { createLogger } from '../utils/logger'\nimport type { ErrorTracking } from '@posthog/core'\nimport { buildErrorPropertiesBuilder } from '../posthog-exceptions'\n\nconst logger = createLogger('[ExceptionAutocapture]')\nconst errorPropertiesBuilder = buildErrorPropertiesBuilder()\n\nconst wrapOnError = (captureFn: (props: ErrorTracking.ErrorProperties) => void) => {\n const win = window as any\n if (!win) {\n logger.info('window not available, cannot wrap onerror')\n }\n const originalOnError = win.onerror\n\n win.onerror = function (...args: ErrorEventArgs): boolean {\n const error = args[4]\n const event = args[0]\n const errorProperties = errorPropertiesBuilder.buildFromUnknown(error || event, {\n mechanism: { handled: false },\n })\n captureFn(errorProperties)\n return originalOnError?.(...args) ?? false\n }\n win.onerror.__POSTHOG_INSTRUMENTED__ = true\n\n return () => {\n delete win.onerror?.__POSTHOG_INSTRUMENTED__\n win.onerror = originalOnError\n }\n}\n\nconst wrapUnhandledRejection = (captureFn: (props: ErrorTracking.ErrorProperties) => void) => {\n const win = window as any\n if (!win) {\n logger.info('window not available, cannot wrap onUnhandledRejection')\n }\n\n const originalOnUnhandledRejection = win.onunhandledrejection\n\n win.onunhandledrejection = function (ev: PromiseRejectionEvent): boolean {\n const errorProperties = errorPropertiesBuilder.buildFromUnknown(ev, {\n mechanism: { handled: false },\n })\n captureFn(errorProperties)\n return originalOnUnhandledRejection?.(ev) ?? false\n }\n win.onunhandledrejection.__POSTHOG_INSTRUMENTED__ = true\n\n return () => {\n delete win.onunhandledrejection?.__POSTHOG_INSTRUMENTED__\n win.onunhandledrejection = originalOnUnhandledRejection\n }\n}\n\nconst wrapConsoleError = (captureFn: (props: ErrorTracking.ErrorProperties) => void) => {\n const con = console as any\n if (!con) {\n logger.info('console not available, cannot wrap console.error')\n }\n\n const originalConsoleError = con.error\n\n con.error = function (...args: any[]): void {\n let event\n if (args.length == 1) {\n event = args[0]\n } else {\n event = args.join(' ')\n }\n const error = args.find((arg) => arg instanceof Error)\n const errorProperties = errorPropertiesBuilder.buildFromUnknown(error || event, {\n mechanism: { handled: false },\n syntheticException: new Error('PostHog syntheticException'),\n skipFirstLines: 2,\n })\n captureFn(errorProperties)\n return originalConsoleError?.(...args)\n }\n con.error.__POSTHOG_INSTRUMENTED__ = true\n\n return () => {\n delete con.error?.__POSTHOG_INSTRUMENTED__\n con.error = originalConsoleError\n }\n}\n\nconst posthogErrorWrappingFunctions = {\n wrapOnError,\n wrapUnhandledRejection,\n wrapConsoleError,\n}\n\nassignableWindow.__PosthogExtensions__ = assignableWindow.__PosthogExtensions__ || {}\nassignableWindow.__PosthogExtensions__.errorWrappingFunctions = posthogErrorWrappingFunctions\n\n// we used to put these on window, and now we put them on __PosthogExtensions__\n// but that means that old clients which lazily load this extension are looking in the wrong place\n// yuck,\n// so we also put them directly on the window\n// when 1.161.1 is the oldest version seen in production we can remove this\nassignableWindow.posthogErrorWrappingFunctions = posthogErrorWrappingFunctions\n\nexport default posthogErrorWrappingFunctions\n","import { isArray } from \"../utils/index.mjs\";\nimport { getFilenameToChunkIdMap } from \"./chunk-ids.mjs\";\nconst MAX_CAUSE_RECURSION = 4;\nclass ErrorPropertiesBuilder {\n constructor(coercers, stackParser, modifiers = []){\n this.coercers = coercers;\n this.stackParser = stackParser;\n this.modifiers = modifiers;\n }\n buildFromUnknown(input, hint = {}) {\n const providedMechanism = hint && hint.mechanism;\n const mechanism = providedMechanism || {\n handled: true,\n type: 'generic'\n };\n const coercingContext = this.buildCoercingContext(mechanism, hint, 0);\n const exceptionWithCause = coercingContext.apply(input);\n const parsingContext = this.buildParsingContext(hint);\n const exceptionWithStack = this.parseStacktrace(exceptionWithCause, parsingContext);\n const exceptionList = this.convertToExceptionList(exceptionWithStack, mechanism);\n return {\n $exception_list: exceptionList,\n $exception_level: 'error'\n };\n }\n async modifyFrames(exceptionList) {\n for (const exc of exceptionList)if (exc.stacktrace && exc.stacktrace.frames && isArray(exc.stacktrace.frames)) exc.stacktrace.frames = await this.applyModifiers(exc.stacktrace.frames);\n return exceptionList;\n }\n coerceFallback(ctx) {\n return {\n type: 'Error',\n value: 'Unknown error',\n stack: ctx.syntheticException?.stack,\n synthetic: true\n };\n }\n parseStacktrace(err, ctx) {\n let cause;\n if (null != err.cause) cause = this.parseStacktrace(err.cause, ctx);\n let stack;\n if ('' != err.stack && null != err.stack) stack = this.applyChunkIds(this.stackParser(err.stack, err.synthetic ? ctx.skipFirstLines : 0), ctx.chunkIdMap);\n return {\n ...err,\n cause,\n stack\n };\n }\n applyChunkIds(frames, chunkIdMap) {\n return frames.map((frame)=>{\n if (frame.filename && chunkIdMap) frame.chunk_id = chunkIdMap[frame.filename];\n return frame;\n });\n }\n applyCoercers(input, ctx) {\n for (const adapter of this.coercers)if (adapter.match(input)) return adapter.coerce(input, ctx);\n return this.coerceFallback(ctx);\n }\n async applyModifiers(frames) {\n let newFrames = frames;\n for (const modifier of this.modifiers)newFrames = await modifier(newFrames);\n return newFrames;\n }\n convertToExceptionList(exceptionWithStack, mechanism) {\n const currentException = {\n type: exceptionWithStack.type,\n value: exceptionWithStack.value,\n mechanism: {\n type: mechanism.type ?? 'generic',\n handled: mechanism.handled ?? true,\n synthetic: exceptionWithStack.synthetic ?? false\n }\n };\n if (exceptionWithStack.stack) currentException.stacktrace = {\n type: 'raw',\n frames: exceptionWithStack.stack\n };\n const exceptionList = [\n currentException\n ];\n if (null != exceptionWithStack.cause) exceptionList.push(...this.convertToExceptionList(exceptionWithStack.cause, {\n ...mechanism,\n handled: true\n }));\n return exceptionList;\n }\n buildParsingContext(hint) {\n const context = {\n chunkIdMap: getFilenameToChunkIdMap(this.stackParser),\n skipFirstLines: hint.skipFirstLines ?? 1\n };\n return context;\n }\n buildCoercingContext(mechanism, hint, depth = 0) {\n const coerce = (input, depth)=>{\n if (!(depth <= MAX_CAUSE_RECURSION)) return;\n {\n const ctx = this.buildCoercingContext(mechanism, hint, depth);\n return this.applyCoercers(input, ctx);\n }\n };\n const context = {\n ...hint,\n syntheticException: 0 == depth ? hint.syntheticException : void 0,\n mechanism,\n apply: (input)=>coerce(input, depth),\n next: (input)=>coerce(input, depth + 1)\n };\n return context;\n }\n}\nexport { ErrorPropertiesBuilder };\n","import { isBuiltin, isString } from \"../../utils/index.mjs\";\nclass DOMExceptionCoercer {\n match(err) {\n return this.isDOMException(err) || this.isDOMError(err);\n }\n coerce(err, ctx) {\n const hasStack = isString(err.stack);\n return {\n type: this.getType(err),\n value: this.getValue(err),\n stack: hasStack ? err.stack : void 0,\n cause: err.cause ? ctx.next(err.cause) : void 0,\n synthetic: false\n };\n }\n getType(candidate) {\n return this.isDOMError(candidate) ? 'DOMError' : 'DOMException';\n }\n getValue(err) {\n const name = err.name || (this.isDOMError(err) ? 'DOMError' : 'DOMException');\n const message = err.message ? `${name}: ${err.message}` : name;\n return message;\n }\n isDOMException(err) {\n return isBuiltin(err, 'DOMException');\n }\n isDOMError(err) {\n return isBuiltin(err, 'DOMError');\n }\n}\nexport { DOMExceptionCoercer };\n","import { isBuiltin, isEvent, isPrimitive } from \"../../utils/index.mjs\";\nclass PromiseRejectionEventCoercer {\n match(err) {\n return isBuiltin(err, 'PromiseRejectionEvent') || this.isCustomEventWrappingRejection(err);\n }\n isCustomEventWrappingRejection(err) {\n if (!isEvent(err)) return false;\n try {\n const detail = err.detail;\n return null != detail && 'object' == typeof detail && 'reason' in detail;\n } catch {\n return false;\n }\n }\n coerce(err, ctx) {\n const reason = this.getUnhandledRejectionReason(err);\n if (isPrimitive(reason)) return {\n type: 'UnhandledRejection',\n value: `Non-Error promise rejection captured with value: ${String(reason)}`,\n stack: ctx.syntheticException?.stack,\n synthetic: true\n };\n return ctx.apply(reason);\n }\n getUnhandledRejectionReason(error) {\n try {\n if ('reason' in error) return error.reason;\n if ('detail' in error && null != error.detail && 'object' == typeof error.detail && 'reason' in error.detail) return error.detail.reason;\n } catch {}\n return error;\n }\n}\nexport { PromiseRejectionEventCoercer };\n","import { isErrorEvent } from \"../../utils/index.mjs\";\nclass ErrorEventCoercer {\n constructor(){}\n match(err) {\n return isErrorEvent(err) && void 0 != err.error;\n }\n coerce(err, ctx) {\n const exceptionLike = ctx.apply(err.error);\n if (!exceptionLike) return {\n type: 'ErrorEvent',\n value: err.message,\n stack: ctx.syntheticException?.stack,\n synthetic: true\n };\n return exceptionLike;\n }\n}\nexport { ErrorEventCoercer };\n","import { isPlainError } from \"../../utils/index.mjs\";\nclass ErrorCoercer {\n match(err) {\n return isPlainError(err);\n }\n coerce(err, ctx) {\n return {\n type: this.getType(err),\n value: this.getMessage(err, ctx),\n stack: this.getStack(err),\n cause: err.cause ? ctx.next(err.cause) : void 0,\n synthetic: false\n };\n }\n getType(err) {\n return err.name || err.constructor.name;\n }\n getMessage(err, _ctx) {\n const message = err.message;\n if (message.error && 'string' == typeof message.error.message) return String(message.error.message);\n return String(message);\n }\n getStack(err) {\n return err.stacktrace || err.stack || void 0;\n }\n}\nexport { ErrorCoercer };\n","import { isEvent } from \"../../utils/index.mjs\";\nimport { extractExceptionKeysForMessage } from \"./utils.mjs\";\nclass EventCoercer {\n match(err) {\n return isEvent(err);\n }\n coerce(evt, ctx) {\n const constructorName = evt.constructor.name;\n return {\n type: constructorName,\n value: `${constructorName} captured as exception with keys: ${extractExceptionKeysForMessage(evt)}`,\n stack: ctx.syntheticException?.stack,\n synthetic: true\n };\n }\n}\nexport { EventCoercer };\n","import { isEmptyString, isError, isEvent, isString } from \"../../utils/index.mjs\";\nimport { severityLevels } from \"../types.mjs\";\nimport { extractExceptionKeysForMessage } from \"./utils.mjs\";\nclass ObjectCoercer {\n match(candidate) {\n return 'object' == typeof candidate && null !== candidate;\n }\n coerce(candidate, ctx) {\n const errorProperty = this.getErrorPropertyFromObject(candidate);\n if (errorProperty) return ctx.apply(errorProperty);\n return {\n type: this.getType(candidate),\n value: this.getValue(candidate),\n stack: ctx.syntheticException?.stack,\n level: this.isSeverityLevel(candidate.level) ? candidate.level : 'error',\n synthetic: true\n };\n }\n getType(err) {\n return isEvent(err) ? err.constructor.name : 'Error';\n }\n getValue(err) {\n if ('name' in err && 'string' == typeof err.name) {\n let message = `'${err.name}' captured as exception`;\n if ('message' in err && 'string' == typeof err.message) message += ` with message: '${err.message}'`;\n return message;\n }\n if ('message' in err && 'string' == typeof err.message) return err.message;\n const className = this.getObjectClassName(err);\n const keys = extractExceptionKeysForMessage(err);\n return `${className && 'Object' !== className ? `'${className}'` : 'Object'} captured as exception with keys: ${keys}`;\n }\n isSeverityLevel(x) {\n return isString(x) && !isEmptyString(x) && severityLevels.indexOf(x) >= 0;\n }\n getErrorPropertyFromObject(obj) {\n for(const prop in obj)if (Object.prototype.hasOwnProperty.call(obj, prop)) {\n const value = obj[prop];\n if (isError(value)) return value;\n }\n }\n getObjectClassName(obj) {\n try {\n const prototype = Object.getPrototypeOf(obj);\n return prototype ? prototype.constructor.name : void 0;\n } catch (e) {\n return;\n }\n }\n}\nexport { ObjectCoercer };\n","import { isPrimitive } from \"../../utils/index.mjs\";\nclass PrimitiveCoercer {\n match(candidate) {\n return isPrimitive(candidate);\n }\n coerce(value, ctx) {\n return {\n type: 'Error',\n value: `Primitive value captured as exception: ${String(value)}`,\n stack: ctx.syntheticException?.stack,\n synthetic: true\n };\n }\n}\nexport { PrimitiveCoercer };\n","import { SessionIdManager } from '../sessionid'\nimport { patch } from '../extensions/replay/rrweb-plugins/patch'\nimport { assignableWindow, window } from '../utils/globals'\nimport { COOKIELESS_SENTINEL_VALUE } from '../constants'\nimport { isArray, isFunction, isNull, isUndefined } from '@posthog/core'\nimport type { TracingHeadersDistinctId, TracingHeadersHostnames } from '../extensions/tracing-headers-types'\n\nconst SESSION_ID_HEADER = 'X-POSTHOG-SESSION-ID'\nconst WINDOW_ID_HEADER = 'X-POSTHOG-WINDOW-ID'\nconst DISTINCT_ID_HEADER = 'X-POSTHOG-DISTINCT-ID'\nconst TRACING_HEADERS = [SESSION_ID_HEADER, WINDOW_ID_HEADER, DISTINCT_ID_HEADER]\nconst REQUEST_INIT_KEYS = [\n 'attributionReporting',\n 'body',\n 'browsingTopics',\n 'cache',\n 'credentials',\n 'dispatcher',\n 'duplex',\n 'integrity',\n 'keepalive',\n 'method',\n 'mode',\n 'priority',\n 'redirect',\n 'referrer',\n 'referrerPolicy',\n 'signal',\n 'window',\n]\n\nconst hasOwnProperty = (value: object, property: PropertyKey): boolean =>\n Object.prototype.hasOwnProperty.call(value, property)\n\nconst isObjectLike = (value: unknown): value is object =>\n (typeof value === 'object' && !isNull(value)) || isFunction(value)\n\nconst isRequest = (value: unknown): value is Request =>\n typeof Request !== 'undefined' &&\n (value instanceof Request || Object.prototype.toString.call(value) === '[object Request]')\n\nconst getRequestUrl = (url: URL | RequestInfo): string | undefined => {\n try {\n if (isRequest(url)) {\n return url.url\n }\n\n // eslint-disable-next-line compat/compat\n return new URL(url instanceof URL ? url.toString() : String(url), window?.location?.href).toString()\n } catch {\n return undefined\n }\n}\n\n// RequestInit is a WebIDL dictionary: native fetch reads known keys via property access, including inherited\n// and non-enumerable properties. Avoid `{ ...init, headers }`, which can drop body/signal/duplex/etc. Instead,\n// overlay only `headers` while forwarding every other lookup to the caller's original init object.\nconst createFetchInitWithHeaders = (init: RequestInit | undefined, headers: Headers): RequestInit | undefined => {\n if (isUndefined(init) || isNull(init)) {\n return { headers }\n }\n if (!isObjectLike(init)) {\n return undefined\n }\n\n const originalInit = init as RequestInit & Record<PropertyKey, unknown>\n\n if (typeof Proxy === 'undefined' || typeof Reflect === 'undefined') {\n // Older browsers without Proxy still get an inherited overlay, which preserves native fetch property lookup.\n const initWithHeaders = Object.create(originalInit) as RequestInit\n Object.defineProperty(initWithHeaders, 'headers', {\n configurable: true,\n enumerable: true,\n value: headers,\n writable: true,\n })\n return initWithHeaders\n }\n\n const target = { headers } as RequestInit & Record<PropertyKey, unknown>\n\n return new Proxy(target, {\n get(target, property) {\n if (hasOwnProperty(target, property)) {\n return Reflect.get(target, property)\n }\n return Reflect.get(originalInit, property, originalInit)\n },\n has(target, property) {\n return hasOwnProperty(target, property) || property in originalInit\n },\n ownKeys(target) {\n const keys = new Set<string | symbol>(Reflect.ownKeys(target))\n Reflect.ownKeys(originalInit).forEach((key) => keys.add(key))\n REQUEST_INIT_KEYS.forEach((key) => {\n if (key in originalInit) {\n keys.add(key)\n }\n })\n return Array.from(keys)\n },\n getOwnPropertyDescriptor(target, property) {\n const targetDescriptor = Reflect.getOwnPropertyDescriptor(target, property)\n if (targetDescriptor) {\n return targetDescriptor\n }\n if (typeof property === 'string' && REQUEST_INIT_KEYS.includes(property) && property in originalInit) {\n return {\n configurable: true,\n enumerable: true,\n get: () => Reflect.get(originalInit, property, originalInit),\n }\n }\n\n const descriptor = Reflect.getOwnPropertyDescriptor(originalInit, property)\n return descriptor ? { ...descriptor, configurable: true } : undefined\n },\n getPrototypeOf() {\n return Object.getPrototypeOf(originalInit)\n },\n }) as RequestInit\n}\n\nconst getDistinctId = (distinctId: TracingHeadersDistinctId): string | undefined =>\n isFunction(distinctId) ? distinctId() : distinctId\n\nconst addTracingHeaders = (\n hostnames: TracingHeadersHostnames,\n distinctId: TracingHeadersDistinctId,\n sessionManager: SessionIdManager | undefined,\n url: string,\n headers: Headers\n): boolean => {\n let reqHostname: string\n try {\n // we don't need to support IE11 here\n // eslint-disable-next-line compat/compat\n reqHostname = new URL(url).hostname\n } catch {\n // If the URL is invalid, we skip adding tracing headers\n return false\n }\n if (!hostnames) {\n return false\n }\n if (isArray(hostnames) && !hostnames.includes(reqHostname)) {\n return false\n }\n\n let hasAddedHeaders = false\n if (sessionManager) {\n const { sessionId, windowId } = sessionManager.checkAndGetSessionAndWindowId(true)\n headers.set(SESSION_ID_HEADER, sessionId)\n headers.set(WINDOW_ID_HEADER, windowId)\n hasAddedHeaders = true\n }\n const currentDistinctId = getDistinctId(distinctId)\n if (currentDistinctId && currentDistinctId !== COOKIELESS_SENTINEL_VALUE) {\n headers.set(DISTINCT_ID_HEADER, currentDistinctId)\n hasAddedHeaders = true\n }\n return hasAddedHeaders\n}\n\ntype FetchArgs = [URL | RequestInfo] | [URL | RequestInfo, RequestInit | undefined]\n\nconst patchFetch = (\n hostnames: TracingHeadersHostnames,\n distinctId: TracingHeadersDistinctId,\n sessionManager?: SessionIdManager\n): (() => void) => {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n return patch(window, 'fetch', (originalFetch: typeof fetch) => {\n return function (this: unknown, url: URL | RequestInfo, init?: RequestInit | undefined) {\n const originalArgs = (arguments.length > 1 ? [url, init] : [url]) as FetchArgs\n let fetchArgs = originalArgs\n\n try {\n const requestUrl = getRequestUrl(url)\n if (requestUrl) {\n if (isRequest(url)) {\n // For fetch(Request, init), construct a new Request so init overrides are applied and the\n // caller's Request is not mutated. For fetch(url, init), avoid this because it exposes string\n // bodies as ReadableStreams to downstream wrappers in Safari.\n // eslint-disable-next-line compat/compat\n const req = new Request(url, init)\n addTracingHeaders(hostnames, distinctId, sessionManager, req.url, req.headers)\n fetchArgs = [req]\n } else {\n const headers = new Headers(isObjectLike(init) ? init.headers : undefined)\n if (addTracingHeaders(hostnames, distinctId, sessionManager, requestUrl, headers)) {\n const initWithHeaders = createFetchInitWithHeaders(init, headers)\n if (initWithHeaders) {\n fetchArgs = [url, initWithHeaders]\n }\n }\n }\n }\n } catch {\n fetchArgs = originalArgs\n }\n\n return originalFetch.apply(this, fetchArgs)\n }\n })\n}\n\nconst patchXHR = (\n hostnames: TracingHeadersHostnames,\n distinctId: TracingHeadersDistinctId,\n sessionManager?: SessionIdManager\n): (() => void) => {\n return patch(\n // we can assert this is present because we've checked previously\n window!.XMLHttpRequest.prototype,\n 'open',\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n (originalOpen: typeof XMLHttpRequest.prototype.open) => {\n return function (\n method: string,\n url: string | URL,\n async = true,\n username?: string | null,\n password?: string | null\n ) {\n // because this function is returned in its actual context `this` _is_ an XMLHttpRequest\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n const xhr = this as XMLHttpRequest\n\n const headers = new Headers()\n const requestUrl = getRequestUrl(url)\n if (requestUrl) {\n addTracingHeaders(hostnames, distinctId, sessionManager, requestUrl, headers)\n }\n\n const result = originalOpen.call(xhr, method, url, async, username, password)\n\n TRACING_HEADERS.forEach((header) => {\n const value = headers.get(header)\n if (value) {\n try {\n xhr.setRequestHeader(header, value)\n } catch {\n // Do not let tracing header injection break the host app's XHR.\n }\n }\n })\n\n return result\n }\n }\n )\n}\n\nassignableWindow.__PosthogExtensions__ = assignableWindow.__PosthogExtensions__ || {}\nconst patchFns = {\n _patchFetch: patchFetch,\n _patchXHR: patchXHR,\n}\nassignableWindow.__PosthogExtensions__.tracingHeadersPatchFns = patchFns\n\n// we used to put tracingHeadersPatchFns on window, and now we put it on __PosthogExtensions__\n// but that means that old clients which lazily load this extension are looking in the wrong place\n// yuck,\n// so we also put it directly on the window\n// when 1.161.1 is the oldest version seen in production we can remove this\nassignableWindow.postHogTracingHeadersPatchFns = patchFns\n\nexport default patchFns\n","// Minimal, side-effecting `Array.prototype.at` polyfill for the web-vitals bundles.\n//\n// web-vitals@5 calls `Array.prototype.at()` internally (minified to `entries.at(-1)`), which\n// is unavailable on browsers that predate it (Chrome <92, iOS Safari <15.4). Our Babel\n// preset-env config down-levels syntax only — it does not polyfill runtime prototype methods —\n// so without this the web-vitals bundles throw an unhandled `TypeError: ....at is not a\n// function` and capture no web vitals on those browsers.\n//\n// We deliberately ship a tiny bespoke polyfill rather than importing `core-js/actual/array/at`,\n// which pulls in ~6KB gzipped of shared machinery and would more than double these intentionally\n// small bundles. See the note in rollup.config.mjs about keeping bundles small with bespoke\n// approaches. Import this as the very first import in an entrypoint so the polyfill is installed\n// before `web-vitals` is evaluated.\n\nif (typeof Array.prototype.at !== 'function') {\n Object.defineProperty(Array.prototype, 'at', {\n // matches the spec's Array.prototype.at (ECMAScript 2022)\n value: function at(this: ArrayLike<unknown>, index: number): unknown {\n const len = this.length\n // ToIntegerOrInfinity: NaN/undefined become 0\n let relativeIndex = Math.trunc(index) || 0\n if (relativeIndex < 0) {\n relativeIndex += len\n }\n return relativeIndex < 0 || relativeIndex >= len ? undefined : this[relativeIndex]\n },\n // mirror the native descriptor: non-enumerable so it doesn't leak into `for..in`\n writable: true,\n enumerable: false,\n configurable: true,\n })\n}\n","let e=-1;const t=t=>{addEventListener(\"pageshow\",n=>{n.persisted&&(e=n.timeStamp,t(n))},!0)},n=(e,t,n,i)=>{let s,o;return r=>{t.value>=0&&(r||i)&&(o=t.value-(s??0),(o||void 0===s)&&(s=t.value,t.delta=o,t.rating=((e,t)=>e>t[1]?\"poor\":e>t[0]?\"needs-improvement\":\"good\")(t.value,n),e(t)))}},i=e=>{requestAnimationFrame(()=>requestAnimationFrame(e))},s=()=>{const e=performance.getEntriesByType(\"navigation\")[0];if(e&&e.responseStart>0&&e.responseStart<performance.now())return e},o=()=>s()?.activationStart??0,r=(t,n=-1)=>{const i=s();let r=\"navigate\";e>=0?r=\"back-forward-cache\":i&&(document.prerendering||o()>0?r=\"prerender\":document.wasDiscarded?r=\"restore\":i.type&&(r=i.type.replace(/_/g,\"-\")));return{name:t,value:n,rating:\"good\",delta:0,entries:[],id:`v5-${Date.now()}-${Math.floor(8999999999999*Math.random())+1e12}`,navigationType:r}},c=new WeakMap;function a(e,t){let n=c.get(t);return n||(n=new WeakMap,c.set(t,n)),n.get(e)||n.set(e,new t),n.get(e)}class d{t;i=0;o=[];h(e){if(e.hadRecentInput)return;const t=this.o[0],n=this.o.at(-1);this.i&&t&&n&&e.startTime-n.startTime<1e3&&e.startTime-t.startTime<5e3?(this.i+=e.value,this.o.push(e)):(this.i=e.value,this.o=[e]),this.t?.(e)}}const h=(e,t,n={})=>{try{if(PerformanceObserver.supportedEntryTypes.includes(e)){const i=new PerformanceObserver(e=>{queueMicrotask(()=>{t(e.getEntries())})});return i.observe({type:e,buffered:!0,...n}),i}}catch{}},f=e=>{let t=!1;return()=>{t||(e(),t=!0)}};let l=-1;const u=new Set,m=()=>\"hidden\"!==document.visibilityState||document.prerendering?1/0:0,p=e=>{if(\"hidden\"===document.visibilityState){if(\"visibilitychange\"===e.type)for(const e of u)e();isFinite(l)||(l=\"visibilitychange\"===e.type?e.timeStamp:0,removeEventListener(\"prerenderingchange\",p,!0))}},g=()=>{if(l<0){const e=o(),n=document.prerendering?void 0:globalThis.performance.getEntriesByType(\"visibility-state\").find(t=>\"hidden\"===t.name&&t.startTime>=e)?.startTime;l=n??m(),addEventListener(\"visibilitychange\",p,!0),addEventListener(\"prerenderingchange\",p,!0),t(()=>{setTimeout(()=>{l=m()})})}return{get firstHiddenTime(){return l},onHidden(e){u.add(e)}}},v=e=>{document.prerendering?addEventListener(\"prerenderingchange\",e,!0):e()},y=[1800,3e3],T=(e,s={})=>{v(()=>{const c=g();let a,d=r(\"FCP\");const f=h(\"paint\",e=>{for(const t of e)\"first-contentful-paint\"===t.name&&(f.disconnect(),t.startTime<c.firstHiddenTime&&(d.value=Math.max(t.startTime-o(),0),d.entries.push(t),a(!0)))});f&&(a=n(e,d,y,s.reportAllChanges),t(t=>{d=r(\"FCP\"),a=n(e,d,y,s.reportAllChanges),i(()=>{d.value=performance.now()-t.timeStamp,a(!0)})}))})},E=[.1,.25],b=(e,s={})=>{const o=g();T(f(()=>{let c,f=r(\"CLS\",0);const l=a(s,d),u=e=>{for(const t of e)l.h(t);l.i>f.value&&(f.value=l.i,f.entries=l.o,c())},m=h(\"layout-shift\",u);m&&(c=n(e,f,E,s.reportAllChanges),o.onHidden(()=>{u(m.takeRecords()),c(!0)}),t(()=>{l.i=0,f=r(\"CLS\",0),c=n(e,f,E,s.reportAllChanges),i(c)}),setTimeout(c))}))};let L=0,P=1/0,_=0;const M=e=>{for(const t of e)t.interactionId&&(P=Math.min(P,t.interactionId),_=Math.max(_,t.interactionId),L=_?(_-P)/7+1:0)};let w;const C=()=>w?L:performance.interactionCount??0,I=()=>{\"interactionCount\"in performance||w||(w=h(\"event\",M,{durationThreshold:0}))};let F=0;class k{l=[];u=new Map;m;p;v(){F=C(),this.l.length=0,this.u.clear()}T(){const e=Math.min(this.l.length-1,Math.floor((C()-F)/50));return this.l[e]}h(e){if(this.m?.(e),!e.interactionId&&\"first-input\"!==e.entryType)return;const t=this.l.at(-1);let n=this.u.get(e.interactionId);if(n||this.l.length<10||e.duration>t.L){if(n?e.duration>n.L?(n.entries=[e],n.L=e.duration):e.duration===n.L&&e.startTime===n.entries[0].startTime&&n.entries.push(e):(n={id:e.interactionId,entries:[e],L:e.duration},this.u.set(n.id,n),this.l.push(n)),this.l.sort((e,t)=>t.L-e.L),this.l.length>10){const e=this.l.splice(10);for(const t of e)this.u.delete(t.id)}this.p?.(n)}}}const A=e=>{const t=globalThis.requestIdleCallback||setTimeout,n=globalThis.cancelIdleCallback||clearTimeout;if(\"hidden\"===document.visibilityState)e();else{const i=f(e);let s=-1;const o=()=>{n(s),i()};addEventListener(\"visibilitychange\",o,{once:!0,capture:!0}),s=t(()=>{removeEventListener(\"visibilitychange\",o,{capture:!0}),i()})}},B=[200,500],S=(e,i={})=>{if(!globalThis.PerformanceEventTiming||!(\"interactionId\"in PerformanceEventTiming.prototype))return;const s=g();v(()=>{I();let o,c=r(\"INP\");const d=a(i,k),f=e=>{A(()=>{for(const t of e)d.h(t);const t=d.T();t&&t.L!==c.value&&(c.value=t.L,c.entries=t.entries,o())})},l=h(\"event\",f,{durationThreshold:i.durationThreshold??40});o=n(e,c,B,i.reportAllChanges),l&&(l.observe({type:\"first-input\",buffered:!0}),s.onHidden(()=>{f(l.takeRecords()),o(!0)}),t(()=>{d.v(),c=r(\"INP\"),o=n(e,c,B,i.reportAllChanges)}))})};class q{m;h(e){this.m?.(e)}}const N=[2500,4e3],x=(e,s={})=>{v(()=>{const c=g();let d,l=r(\"LCP\");const u=a(s,q),m=e=>{s.reportAllChanges||(e=e.slice(-1));for(const t of e)u.h(t),t.startTime<c.firstHiddenTime&&(l.value=Math.max(t.startTime-o(),0),l.entries=[t],d())},p=h(\"largest-contentful-paint\",m);if(p){d=n(e,l,N,s.reportAllChanges);const o=f(()=>{m(p.takeRecords()),p.disconnect(),d(!0)}),c=e=>{e.isTrusted&&(A(o),removeEventListener(e.type,c,{capture:!0}))};for(const e of[\"keydown\",\"click\",\"visibilitychange\"])addEventListener(e,c,{capture:!0});t(t=>{l=r(\"LCP\"),d=n(e,l,N,s.reportAllChanges),i(()=>{l.value=performance.now()-t.timeStamp,d(!0)})})}})},H=[800,1800],O=e=>{document.prerendering?v(()=>O(e)):\"complete\"!==document.readyState?addEventListener(\"load\",()=>O(e),!0):setTimeout(e)},W=(e,i={})=>{let c=r(\"TTFB\"),a=n(e,c,H,i.reportAllChanges);O(()=>{const d=s();d&&(c.value=Math.max(d.responseStart-o(),0),c.entries=[d],a(!0),t(()=>{c=r(\"TTFB\",0),a=n(e,c,H,i.reportAllChanges),a(!0)}))})};export{E as CLSThresholds,y as FCPThresholds,B as INPThresholds,N as LCPThresholds,H as TTFBThresholds,b as onCLS,T as onFCP,S as onINP,x as onLCP,W as onTTFB};\n","/**\n * Web Vitals entrypoint (without attribution)\n *\n * This is the default, lighter bundle (~6KB) that captures core web vitals metrics\n * without attribution data. Attribution data includes debugging information like\n * which elements caused layout shifts, timing breakdowns, etc.\n *\n * We split this into two bundles because:\n * 1. Attribution code adds ~6KB to the bundle size\n * 2. Attribution can cause memory issues in SPAs (onCLS holds references to detached DOM elements)\n * 3. Most users only need aggregate metrics, not debugging attribution data\n *\n * For attribution data, use web-vitals-with-attribution.ts instead by setting:\n * capture_performance: { web_vitals_attribution: true }\n *\n * @see web-vitals-with-attribution.ts\n */\n// Must be first: installs an Array.prototype.at polyfill before web-vitals (which uses it\n// internally) is evaluated, so the bundle doesn't throw on browsers that predate `.at()`.\nimport '../utils/array-at-polyfill'\n\nimport { assignableWindow } from '../utils/globals'\n\nimport { onINP, onLCP, onCLS, onFCP } from 'web-vitals'\n\nconst postHogWebVitalsCallbacks = {\n onLCP,\n onCLS,\n onFCP,\n onINP,\n}\n\nassignableWindow.__PosthogExtensions__ = assignableWindow.__PosthogExtensions__ || {}\nassignableWindow.__PosthogExtensions__.postHogWebVitalsCallbacks = postHogWebVitalsCallbacks\n\n// we used to put posthogWebVitalsCallbacks on window, and now we put it on __PosthogExtensions__\n// but that means that old clients which lazily load this extension are looking in the wrong place\n// yuck,\n// so we also put it directly on the window\n// when 1.161.1 is the oldest version seen in production we can remove this\nassignableWindow.postHogWebVitalsCallbacks = postHogWebVitalsCallbacks\n// deprecated function kept for backwards compatibility\nassignableWindow.__PosthogExtensions__.loadWebVitalsCallbacks = () => postHogWebVitalsCallbacks\n\nexport default postHogWebVitalsCallbacks\n","import { addEventListener, each, extend } from './utils'\nimport {\n autocaptureCompatibleElements,\n getClassNames,\n getDirectAndNestedSpanText,\n getElementsChainString,\n getEventTarget,\n getSafeText,\n isAngularStyleAttr,\n isSensitiveElement,\n makeSafeText,\n shouldCaptureDomEvent,\n shouldCaptureElement,\n shouldCaptureRageclick,\n shouldCaptureValue,\n splitClassString,\n} from './autocapture-utils'\n\nimport RageClick from './extensions/rageclick'\nimport { AutocaptureConfig, EventName, Properties, RemoteConfig } from './types'\nimport { PostHog } from './posthog-core'\nimport { AUTOCAPTURE_DISABLED_SERVER_SIDE } from './constants'\n\nimport { isBoolean, isFunction, isNull, isObject, stripUrlHash } from '@posthog/core'\nimport { createLogger } from './utils/logger'\nimport { document, window } from './utils/globals'\nimport { convertToURL } from './utils/request-utils'\nimport { isElementNode, isShadowRoot, isTag, isTextNode } from './utils/element-utils'\nimport { includes } from '@posthog/core'\nimport type { Extension } from './extensions/types'\n\nconst COPY_AUTOCAPTURE_EVENT = '$copy_autocapture'\n\nconst logger = createLogger('[AutoCapture]')\n\nfunction limitText(length: number, text: string): string {\n if (text.length > length) {\n return text.slice(0, length) + '...'\n }\n return text\n}\n\nexport function getAugmentPropertiesFromElement(elem: Element): Properties {\n const shouldCaptureEl = shouldCaptureElement(elem)\n if (!shouldCaptureEl) {\n return {}\n }\n\n const props: Properties = {}\n\n each(elem.attributes, function (attr: Attr) {\n if (attr.name && attr.name.indexOf('data-ph-capture-attribute') === 0) {\n const propertyKey = attr.name.replace('data-ph-capture-attribute-', '')\n const propertyValue = attr.value\n if (propertyKey && propertyValue && shouldCaptureValue(propertyValue)) {\n props[propertyKey] = propertyValue\n }\n }\n })\n\n return props\n}\n\nexport function previousElementSibling(el: Element): Element | null {\n if (el.previousElementSibling) {\n return el.previousElementSibling\n }\n let _el: Element | null = el\n do {\n _el = _el.previousSibling as Element | null // resolves to ChildNode->Node, which is Element's parent class\n } while (_el && !isElementNode(_el))\n return _el\n}\n\nexport function getDefaultProperties(eventType: string): Properties {\n return {\n $event_type: eventType,\n $ce_version: 1,\n }\n}\n\nexport function getPropertiesFromElement(\n elem: Element,\n maskAllAttributes: boolean,\n maskText: boolean,\n elementAttributeIgnorelist: string[] | undefined,\n disableCaptureUrlHashes: boolean = false\n): Properties {\n const tag_name = elem.tagName.toLowerCase()\n const props: Properties = {\n tag_name: tag_name,\n }\n if (autocaptureCompatibleElements.indexOf(tag_name) > -1 && !maskText) {\n if (tag_name.toLowerCase() === 'a' || tag_name.toLowerCase() === 'button') {\n props['$el_text'] = limitText(1024, getDirectAndNestedSpanText(elem))\n } else {\n props['$el_text'] = limitText(1024, getSafeText(elem))\n }\n }\n\n const classes = getClassNames(elem)\n if (classes.length > 0)\n props['classes'] = classes.filter(function (c) {\n return c !== ''\n })\n\n // capture the deny list here because this not-a-class class makes it tricky to use this.config in the function below\n each(elem.attributes, function (attr: Attr) {\n // Only capture attributes we know are safe\n if (isSensitiveElement(elem) && ['name', 'id', 'class', 'aria-label'].indexOf(attr.name) === -1) return\n\n if (elementAttributeIgnorelist?.includes(attr.name)) return\n\n if (!maskAllAttributes && shouldCaptureValue(attr.value) && !isAngularStyleAttr(attr.name)) {\n let value = attr.value\n if (attr.name === 'class') {\n // html attributes can _technically_ contain linebreaks,\n // but we're very intolerant of them in the class string,\n // so we strip them.\n value = splitClassString(value).join(' ')\n }\n props['attr__' + attr.name] = limitText(\n 1024,\n attr.name === 'href' && disableCaptureUrlHashes ? stripUrlHash(value) : value\n )\n }\n })\n\n let nthChild = 1\n let nthOfType = 1\n let currentElem: Element | null = elem\n while ((currentElem = previousElementSibling(currentElem))) {\n // eslint-disable-line no-cond-assign\n nthChild++\n if (currentElem.tagName === elem.tagName) {\n nthOfType++\n }\n }\n props['nth_child'] = nthChild\n props['nth_of_type'] = nthOfType\n\n return props\n}\n\nexport function autocapturePropertiesForElement(\n target: Element,\n {\n e,\n maskAllElementAttributes,\n maskAllText,\n elementAttributeIgnoreList,\n elementsChainAsString,\n disableCaptureUrlHashes,\n }: {\n e: Event\n maskAllElementAttributes: boolean\n maskAllText: boolean\n elementAttributeIgnoreList?: string[] | undefined\n elementsChainAsString: boolean\n disableCaptureUrlHashes: boolean\n }\n): { props: Properties; explicitNoCapture?: boolean } {\n if (!isElementNode(target)) {\n return { props: {} }\n }\n\n const targetElementList: Element[] = [target]\n let curEl: Element = target\n while (curEl.parentNode && !isTag(curEl, 'body')) {\n if (isShadowRoot(curEl.parentNode)) {\n targetElementList.push(curEl.parentNode.host)\n curEl = curEl.parentNode.host\n continue\n }\n if (!isElementNode(curEl.parentNode)) {\n break\n }\n targetElementList.push(curEl.parentNode)\n curEl = curEl.parentNode\n }\n\n const elementsJson: Properties[] = []\n const autocaptureAugmentProperties: Properties = {}\n let href: string | false = false\n let explicitNoCapture = false\n\n each(targetElementList, (el) => {\n const shouldCaptureEl = shouldCaptureElement(el)\n\n // if the element or a parent element is an anchor tag\n // include the href as a property\n if (isTag(el, 'a')) {\n const hrefAttr = el.getAttribute('href')\n href =\n shouldCaptureEl && !!hrefAttr && shouldCaptureValue(hrefAttr)\n ? disableCaptureUrlHashes\n ? stripUrlHash(hrefAttr)\n : hrefAttr\n : false\n }\n\n // allow users to programmatically prevent capturing of elements by adding class 'ph-no-capture'\n const classes = getClassNames(el)\n if (includes(classes, 'ph-no-capture')) {\n explicitNoCapture = true\n }\n\n elementsJson.push(\n getPropertiesFromElement(\n el,\n maskAllElementAttributes,\n maskAllText,\n elementAttributeIgnoreList,\n disableCaptureUrlHashes\n )\n )\n\n const augmentProperties = getAugmentPropertiesFromElement(el)\n extend(autocaptureAugmentProperties, augmentProperties)\n })\n\n if (explicitNoCapture) {\n return { props: {}, explicitNoCapture }\n }\n\n if (!maskAllText) {\n // if the element is a button or anchor tag get the span text from any\n // children and include it as/with the text property on the parent element\n if (isTag(target, 'a') || isTag(target, 'button')) {\n elementsJson[0]['$el_text'] = getDirectAndNestedSpanText(target)\n } else {\n elementsJson[0]['$el_text'] = getSafeText(target)\n }\n }\n\n let externalHref: string | undefined\n if (href) {\n elementsJson[0]['attr__href'] = href\n const hrefHost = convertToURL(href)?.host\n const locationHost = window?.location?.host\n if (hrefHost && locationHost && hrefHost !== locationHost) {\n externalHref = href\n }\n }\n\n const props = extend(\n getDefaultProperties(e.type),\n // Sending \"$elements\" is deprecated. Only one client on US cloud uses this.\n !elementsChainAsString ? { $elements: elementsJson } : {},\n // Always send $elements_chain, as it's needed downstream in site app filtering\n { $elements_chain: getElementsChainString(elementsJson) },\n elementsJson[0]?.['$el_text'] ? { $el_text: elementsJson[0]?.['$el_text'] } : {},\n externalHref && e.type === 'click' ? { $external_click_url: externalHref } : {},\n autocaptureAugmentProperties\n )\n\n return { props }\n}\n\nexport class Autocapture implements Extension {\n instance: PostHog\n _initialized: boolean = false\n _isDisabledServerSide: boolean | null = null\n _elementSelectors: Set<string> | null\n rageclicks: RageClick\n _elementsChainAsString = false\n\n constructor(instance: PostHog) {\n this.instance = instance\n this.rageclicks = new RageClick(instance.config.rageclick)\n this._elementSelectors = null\n }\n\n initialize() {\n this.startIfEnabled()\n }\n\n private get _config(): AutocaptureConfig {\n const config = isObject(this.instance.config.autocapture) ? this.instance.config.autocapture : {}\n // precompile the regex\n config.url_allowlist = config.url_allowlist?.map((url) => new RegExp(url))\n config.url_ignorelist = config.url_ignorelist?.map((url) => new RegExp(url))\n return config\n }\n\n _addDomEventHandlers(): void {\n if (!this.isBrowserSupported()) {\n logger.info('Disabling Automatic Event Collection because this browser is not supported')\n return\n }\n\n if (!window || !document) {\n return\n }\n\n const handler = (e: Event) => {\n e = e || window?.event\n try {\n this._captureEvent(e)\n } catch (error) {\n logger.error('Failed to capture event', error)\n }\n }\n\n addEventListener(document, 'submit', handler, { capture: true })\n addEventListener(document, 'change', handler, { capture: true })\n addEventListener(document, 'click', handler, { capture: true })\n\n if (this._config.capture_copied_text) {\n const copiedTextHandler = (e: Event) => {\n e = e || window?.event\n try {\n this._captureEvent(e, COPY_AUTOCAPTURE_EVENT)\n } catch (error) {\n logger.error('Failed to capture copy/cut event', error)\n }\n }\n\n addEventListener(document, 'copy', copiedTextHandler, { capture: true })\n addEventListener(document, 'cut', copiedTextHandler, { capture: true })\n }\n }\n\n public startIfEnabled() {\n if (this.isEnabled && !this._initialized) {\n this._addDomEventHandlers()\n this._initialized = true\n }\n }\n\n public onRemoteConfig(response: RemoteConfig) {\n if (response.elementsChainAsString) {\n this._elementsChainAsString = response.elementsChainAsString\n }\n\n // NOTE: Unlike other extensions (heatmaps, web-vitals, etc.), we intentionally\n // DO NOT guard against missing autocapture_opt_out key here. Autocapture uses\n // a \"wait for server, then enable unless explicitly opted out\" model:\n // - Before remote config: autocapture disabled (isEnabled returns false)\n // - After remote config: enabled unless autocapture_opt_out is explicitly true\n // Missing/undefined key → !!undefined = false → autocapture enabled\n // This is intentional and different from opt-in features like heatmaps.\n if (this.instance.persistence) {\n this.instance.persistence.register({\n [AUTOCAPTURE_DISABLED_SERVER_SIDE]: !!response['autocapture_opt_out'],\n })\n }\n // store this in-memory in case persistence is disabled\n this._isDisabledServerSide = !!response['autocapture_opt_out']\n this.startIfEnabled()\n }\n\n public setElementSelectors(selectors: Set<string>): void {\n this._elementSelectors = selectors\n }\n\n public getElementSelectors(element: Element | null): string[] | null {\n const elementSelectors: string[] = []\n\n this._elementSelectors?.forEach((selector) => {\n const matchedElements = document?.querySelectorAll(selector)\n matchedElements?.forEach((matchedElement: Element) => {\n if (element === matchedElement) {\n elementSelectors.push(selector)\n }\n })\n })\n\n return elementSelectors\n }\n\n public get isEnabled(): boolean {\n const persistedServerDisabled = this.instance.persistence?.props[AUTOCAPTURE_DISABLED_SERVER_SIDE]\n const memoryDisabled = this._isDisabledServerSide\n\n if (isNull(memoryDisabled) && !isBoolean(persistedServerDisabled) && !this.instance._shouldDisableFlags()) {\n // We only enable if we know that the server has not disabled it (unless /flags is disabled)\n return false\n }\n\n const disabledServer = this._isDisabledServerSide ?? !!persistedServerDisabled\n const disabledClient = !this.instance.config.autocapture\n return !disabledClient && !disabledServer\n }\n\n private _captureEvent(e: Event, eventName: EventName = '$autocapture'): boolean | void {\n if (!this.isEnabled) {\n return\n }\n\n /*** Don't mess with this code without running IE8 tests on it ***/\n let target = getEventTarget(e)\n if (isTextNode(target)) {\n // defeat Safari bug (see: http://www.quirksmode.org/js/events_properties.html)\n target = (target.parentNode || null) as Element | null\n }\n\n if (eventName === '$autocapture' && e.type === 'click' && e instanceof MouseEvent) {\n if (\n !!this.instance.config.rageclick &&\n this.rageclicks?.isRageClick(e.clientX, e.clientY, e.timeStamp || new Date().getTime())\n ) {\n if (shouldCaptureRageclick(target, this.instance.config.rageclick)) {\n this._captureEvent(e, '$rageclick')\n }\n }\n }\n\n const isCopyAutocapture = eventName === COPY_AUTOCAPTURE_EVENT\n if (\n target &&\n shouldCaptureDomEvent(\n target,\n e,\n this._config,\n // mostly this method cares about the target element, but in the case of copy events,\n // we want some of the work this check does without insisting on the target element's type\n isCopyAutocapture,\n // we also don't want to restrict copy checks to clicks,\n // so we pass that knowledge in here, rather than add the logic inside the check\n isCopyAutocapture ? ['copy', 'cut'] : undefined,\n this.instance\n )\n ) {\n const { props, explicitNoCapture } = autocapturePropertiesForElement(target, {\n e,\n maskAllElementAttributes: this.instance.config.mask_all_element_attributes,\n maskAllText: this.instance.config.mask_all_text,\n elementAttributeIgnoreList: this._config.element_attribute_ignorelist,\n elementsChainAsString: this._elementsChainAsString,\n disableCaptureUrlHashes: this.instance.config.disable_capture_url_hashes,\n })\n\n if (explicitNoCapture) {\n return false\n }\n\n const elementSelectors = this.getElementSelectors(target)\n if (elementSelectors && elementSelectors.length > 0) {\n props['$element_selectors'] = elementSelectors\n }\n\n if (eventName === COPY_AUTOCAPTURE_EVENT) {\n // you can't read the data from the clipboard event,\n // but you can guess that you can read it from the window's current selection\n const selectedContent = makeSafeText(window?.getSelection()?.toString())\n const clipType = (e as ClipboardEvent).type || 'clipboard'\n if (!selectedContent) {\n return false\n }\n props['$selected_content'] = selectedContent\n props['$copy_type'] = clipType\n }\n\n this.instance.capture(eventName, props)\n return true\n }\n }\n\n isBrowserSupported(): boolean {\n return isFunction(document?.querySelectorAll)\n }\n}\n","// Portions of this file are derived from getsentry/sentry-javascript\n// Copyright (c) 2012 Functional Software, Inc. dba Sentry\n// Licensed under the MIT License: https://github.com/getsentry/sentry-javascript/blob/develop/LICENSE\n\n/**\n * Also adapted from https://github.com/PostHog/rrweb/blob/804380afbb1b9bed70b8792cb5a25d827f5c0cb5/packages/utils/src/index.ts#L31\n * after a number of performance reports from Angular users\n */\n\nimport { AssignableWindow } from './globals'\nimport { isAngularZonePresent } from './type-utils'\nimport { isFunction, isNativeFunction } from '@posthog/core'\nimport { logger } from './logger'\n\ninterface NativeImplementationsCache {\n MutationObserver: typeof MutationObserver\n}\n\nconst cachedImplementations: Partial<NativeImplementationsCache> = {}\n\nexport function getNativeImplementation<T extends keyof NativeImplementationsCache>(\n name: T,\n assignableWindow: AssignableWindow\n): NativeImplementationsCache[T] {\n const cached = cachedImplementations[name]\n if (cached) {\n return cached\n }\n\n let impl = assignableWindow[name] as NativeImplementationsCache[T]\n\n if (isNativeFunction(impl) && !isAngularZonePresent()) {\n return (cachedImplementations[name] = impl.bind(assignableWindow) as NativeImplementationsCache[T])\n }\n\n const document = assignableWindow.document\n if (document && isFunction(document.createElement)) {\n try {\n const sandbox = document.createElement('iframe')\n sandbox.hidden = true\n document.head.appendChild(sandbox)\n const contentWindow = sandbox.contentWindow\n if (contentWindow && (contentWindow as any)[name]) {\n impl = (contentWindow as any)[name] as NativeImplementationsCache[T]\n }\n document.head.removeChild(sandbox)\n } catch (e) {\n // Could not create sandbox iframe, just use assignableWindow.xxx\n logger.warn(`Could not create sandbox iframe for ${name} check, bailing to assignableWindow.${name}: `, e)\n }\n }\n\n // Sanity check: This _should_ not happen, but if it does, we just skip caching...\n // This can happen e.g. in tests where fetch may not be available in the env, or similar.\n if (!impl || !isFunction(impl)) {\n return impl\n }\n\n return (cachedImplementations[name] = impl.bind(assignableWindow) as NativeImplementationsCache[T])\n}\n\nexport function getNativeMutationObserverImplementation(assignableWindow: AssignableWindow): typeof MutationObserver {\n return getNativeImplementation('MutationObserver', assignableWindow)\n}\n","import { assignableWindow, document, LazyLoadedDeadClicksAutocaptureInterface } from '../utils/globals'\nimport { PostHog } from '../posthog-core'\nimport { isNull, isNumber, isUndefined } from '@posthog/core'\nimport { getEventTarget, shouldCaptureDeadClick, shouldSkipDeadClick } from '../autocapture-utils'\nimport { DeadClickCandidate, DeadClicksAutoCaptureConfig, Properties } from '../types'\nimport { autocapturePropertiesForElement } from '../autocapture'\nimport { isElementInToolbar, isElementNode, isTag } from '../utils/element-utils'\nimport { getNativeMutationObserverImplementation } from '../utils/prototype-utils'\nimport { addEventListener } from '../utils'\n\nfunction asClick(event: MouseEvent): DeadClickCandidate | null {\n const eventTarget = getEventTarget(event)\n if (eventTarget) {\n return {\n node: eventTarget,\n originalEvent: event,\n timestamp: Date.now(),\n }\n }\n return null\n}\n\nfunction hasModifierKey(event: MouseEvent): boolean {\n return event.ctrlKey || event.metaKey || event.altKey || event.shiftKey\n}\n\nfunction checkTimeout(value: number | undefined, thresholdMs: number) {\n return isNumber(value) && value >= thresholdMs\n}\n\nclass LazyLoadedDeadClicksAutocapture implements LazyLoadedDeadClicksAutocaptureInterface {\n private _mutationObserver: MutationObserver | undefined\n private _lastMutation: number | undefined\n private _lastSelectionChanged: number | undefined\n private _lastVisibilityChange: number | undefined\n private _clicks: DeadClickCandidate[] = []\n private _checkClickTimer: number | undefined\n private _config: Required<Omit<DeadClicksAutoCaptureConfig, 'css_selector_ignorelist'>> &\n Pick<DeadClicksAutoCaptureConfig, 'css_selector_ignorelist'>\n private _onCapture: (click: DeadClickCandidate, properties: Properties) => void\n\n private _defaultConfig = (defaultOnCapture: (click: DeadClickCandidate, properties: Properties) => void) => ({\n element_attribute_ignorelist: [],\n scroll_threshold_ms: 100,\n selection_change_threshold_ms: 100,\n mutation_threshold_ms: 2500,\n capture_clicks_with_modifier_keys: false,\n __onCapture: defaultOnCapture,\n })\n\n private _asRequiredConfig(\n providedConfig?: DeadClicksAutoCaptureConfig\n ): Required<Omit<DeadClicksAutoCaptureConfig, 'css_selector_ignorelist'>> &\n Pick<DeadClicksAutoCaptureConfig, 'css_selector_ignorelist'> {\n const defaultConfig = this._defaultConfig(providedConfig?.__onCapture || this._captureDeadClick.bind(this))\n return {\n element_attribute_ignorelist:\n providedConfig?.element_attribute_ignorelist ?? defaultConfig.element_attribute_ignorelist,\n scroll_threshold_ms: providedConfig?.scroll_threshold_ms ?? defaultConfig.scroll_threshold_ms,\n selection_change_threshold_ms:\n providedConfig?.selection_change_threshold_ms ?? defaultConfig.selection_change_threshold_ms,\n mutation_threshold_ms: providedConfig?.mutation_threshold_ms ?? defaultConfig.mutation_threshold_ms,\n capture_clicks_with_modifier_keys:\n providedConfig?.capture_clicks_with_modifier_keys ?? defaultConfig.capture_clicks_with_modifier_keys,\n css_selector_ignorelist: providedConfig?.css_selector_ignorelist,\n __onCapture: defaultConfig.__onCapture,\n }\n }\n\n constructor(\n readonly instance: PostHog,\n config?: DeadClicksAutoCaptureConfig\n ) {\n this._config = this._asRequiredConfig(config)\n this._onCapture = this._config.__onCapture\n }\n\n start(observerTarget: Node) {\n this._startClickObserver()\n this._startScrollObserver()\n this._startSelectionChangedObserver()\n this._startVisibilityChangeObserver()\n this._startMutationObserver(observerTarget)\n }\n\n private _startMutationObserver(observerTarget: Node) {\n if (!this._mutationObserver) {\n const NativeMutationObserver = getNativeMutationObserverImplementation(assignableWindow)\n this._mutationObserver = new NativeMutationObserver((mutations) => {\n this._onMutation(mutations)\n })\n this._mutationObserver.observe(observerTarget, {\n attributes: true,\n characterData: true,\n childList: true,\n subtree: true,\n })\n }\n }\n\n stop() {\n this._mutationObserver?.disconnect()\n this._mutationObserver = undefined\n assignableWindow.removeEventListener('click', this._onClick)\n assignableWindow.removeEventListener('scroll', this._onScroll, { capture: true })\n assignableWindow.removeEventListener('selectionchange', this._onSelectionChange)\n document?.removeEventListener('visibilitychange', this._onVisibilityChange)\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n private _onMutation(_mutations: MutationRecord[]): void {\n // we don't actually care about the content of the mutations, right now\n this._lastMutation = Date.now()\n }\n\n private _startClickObserver() {\n addEventListener(assignableWindow, 'click', this._onClick)\n }\n\n private _onClick = (event: Event): void => {\n const click = asClick(event as MouseEvent)\n if (!isNull(click) && !this._ignoreClick(click)) {\n this._clicks.push(click)\n }\n\n if (this._clicks.length && isUndefined(this._checkClickTimer)) {\n this._checkClickTimer = assignableWindow.setTimeout(() => {\n this._checkClicks()\n }, 1000)\n }\n }\n\n // `capture: true` is required to get scroll events for other scrollable elements\n // on the page, not just the window\n // see https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#usecapture\n //\n // `passive: true` is used to tell the browser that the scroll event handler will not call `preventDefault()`\n // This allows the browser to optimize scrolling performance by not waiting for our handling of the scroll event\n // see https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#passive\n private _startScrollObserver() {\n addEventListener(assignableWindow, 'scroll', this._onScroll, { capture: true })\n }\n\n private _onScroll = (): void => {\n const candidateNow = Date.now()\n // very naive throttle\n if (candidateNow % 50 === 0) {\n // we can see many scrolls between scheduled checks,\n // so we update scroll delay as we see them\n // to avoid false positives\n this._clicks.forEach((click) => {\n if (isUndefined(click.scrollDelayMs)) {\n click.scrollDelayMs = candidateNow - click.timestamp\n }\n })\n }\n }\n\n private _startSelectionChangedObserver() {\n addEventListener(assignableWindow, 'selectionchange', this._onSelectionChange)\n }\n\n private _onSelectionChange = (): void => {\n this._lastSelectionChanged = Date.now()\n }\n\n private _startVisibilityChangeObserver() {\n addEventListener(document, 'visibilitychange', this._onVisibilityChange)\n }\n\n private _onVisibilityChange = (): void => {\n if (document?.visibilityState === 'visible') {\n this._lastVisibilityChange = Date.now()\n }\n }\n\n private _ignoreClick(click: DeadClickCandidate | null): boolean {\n if (!click) {\n return true\n }\n\n if (!this._config.capture_clicks_with_modifier_keys && hasModifierKey(click.originalEvent)) {\n return true\n }\n\n if (isElementInToolbar(click.node)) {\n return true\n }\n\n const alreadyClickedInLastSecond = this._clicks.some((c) => {\n return c.node === click.node && Math.abs(c.timestamp - click.timestamp) < 1000\n })\n\n if (alreadyClickedInLastSecond) {\n return true\n }\n\n if (isTag(click.node, 'html') || !isElementNode(click.node) || shouldSkipDeadClick(click.node)) {\n return true\n }\n\n if (!shouldCaptureDeadClick(click.node, { css_selector_ignorelist: this._config.css_selector_ignorelist })) {\n return true\n }\n\n return false\n }\n\n private _checkClicks() {\n if (!this._clicks.length) {\n return\n }\n\n clearTimeout(this._checkClickTimer)\n this._checkClickTimer = undefined\n\n const clicksToCheck = this._clicks\n this._clicks = []\n\n for (const click of clicksToCheck) {\n click.mutationDelayMs =\n click.mutationDelayMs ??\n (this._lastMutation && click.timestamp <= this._lastMutation\n ? this._lastMutation - click.timestamp\n : undefined)\n click.absoluteDelayMs = Date.now() - click.timestamp\n click.selectionChangedDelayMs =\n this._lastSelectionChanged && click.timestamp <= this._lastSelectionChanged\n ? this._lastSelectionChanged - click.timestamp\n : undefined\n click.visibilityChangedDelayMs = this._lastVisibilityChange\n ? Math.abs(click.timestamp - this._lastVisibilityChange)\n : undefined\n\n const scrollTimeout = checkTimeout(click.scrollDelayMs, this._config.scroll_threshold_ms)\n const selectionChangedTimeout = checkTimeout(\n click.selectionChangedDelayMs,\n this._config.selection_change_threshold_ms\n )\n const mutationTimeout = checkTimeout(click.mutationDelayMs, this._config.mutation_threshold_ms)\n // we want to timeout eventually even if nothing else catches it...\n // we leave a little longer than the maximum threshold to give the other checks a chance to catch it\n const absoluteTimeout = checkTimeout(click.absoluteDelayMs, this._config.mutation_threshold_ms * 1.1)\n\n const hadScroll = isNumber(click.scrollDelayMs) && click.scrollDelayMs < this._config.scroll_threshold_ms\n const hadMutation =\n isNumber(click.mutationDelayMs) && click.mutationDelayMs < this._config.mutation_threshold_ms\n const hadSelectionChange =\n isNumber(click.selectionChangedDelayMs) &&\n click.selectionChangedDelayMs < this._config.selection_change_threshold_ms\n const hadVisibilityChange =\n isNumber(click.visibilityChangedDelayMs) &&\n click.visibilityChangedDelayMs < this._config.selection_change_threshold_ms\n\n if (hadScroll || hadMutation || hadSelectionChange || hadVisibilityChange) {\n continue\n }\n\n const visibilityChangedTimeout = checkTimeout(\n click.visibilityChangedDelayMs,\n this._config.selection_change_threshold_ms\n )\n\n if (\n scrollTimeout ||\n mutationTimeout ||\n absoluteTimeout ||\n selectionChangedTimeout ||\n visibilityChangedTimeout\n ) {\n this._onCapture(click, {\n $dead_click_last_mutation_timestamp: this._lastMutation,\n $dead_click_event_timestamp: click.timestamp,\n $dead_click_scroll_timeout: scrollTimeout,\n $dead_click_mutation_timeout: mutationTimeout,\n $dead_click_absolute_timeout: absoluteTimeout,\n $dead_click_selection_changed_timeout: selectionChangedTimeout,\n $dead_click_visibility_changed_timeout: visibilityChangedTimeout,\n })\n } else if (click.absoluteDelayMs < this._config.mutation_threshold_ms) {\n // keep waiting until next check\n this._clicks.push(click)\n }\n }\n\n if (this._clicks.length && isUndefined(this._checkClickTimer)) {\n this._checkClickTimer = assignableWindow.setTimeout(() => {\n this._checkClicks()\n }, 1000)\n }\n }\n\n private _captureDeadClick(click: DeadClickCandidate, properties: Properties) {\n // TODO need to check safe and captur-able as with autocapture\n // TODO autocaputure config\n this.instance.capture(\n '$dead_click',\n {\n ...properties,\n ...autocapturePropertiesForElement(click.node, {\n e: click.originalEvent,\n maskAllElementAttributes: this.instance.config.mask_all_element_attributes,\n maskAllText: this.instance.config.mask_all_text,\n elementAttributeIgnoreList: this._config.element_attribute_ignorelist,\n // TRICKY: it appears that we were moving to elementsChainAsString, but the UI still depends on elements, so :shrug:\n elementsChainAsString: false,\n disableCaptureUrlHashes: this.instance.config.disable_capture_url_hashes,\n }).props,\n $dead_click_scroll_delay_ms: click.scrollDelayMs,\n $dead_click_mutation_delay_ms: click.mutationDelayMs,\n $dead_click_absolute_delay_ms: click.absoluteDelayMs,\n $dead_click_selection_changed_delay_ms: click.selectionChangedDelayMs,\n $dead_click_visibility_changed_delay_ms: click.visibilityChangedDelayMs,\n },\n {\n timestamp: new Date(click.timestamp),\n }\n )\n }\n}\n\nassignableWindow.__PosthogExtensions__ = assignableWindow.__PosthogExtensions__ || {}\nassignableWindow.__PosthogExtensions__.initDeadClicksAutocapture = (ph, config) =>\n new LazyLoadedDeadClicksAutocapture(ph, config)\n\nexport default LazyLoadedDeadClicksAutocapture\n"],"names":["_a","EventType","EventType2","IncrementalSource","IncrementalSource2","MouseInteractions","MouseInteractions2","PointerTypes","PointerTypes2","CanvasContext","CanvasContext2","MediaInteractions","MediaInteractions2","NodeType","NodeType2","_a2","_b","_c","_d","_a3","source","name","replacement","original","wrapped","prototype","Object","defineProperties","__rrweb_original__","enumerable","value","_unused","types_SurveyValidationType","SurveyValidationType","includes","str","needle","indexOf","trim","ObjProto","type_utils_hasOwnProperty","hasOwnProperty","type_utils_toString","toString","isArray","Array","obj","call","isFunction","x","isObject","isUndefined","isString","isNull","isNullish","isNumber","isBoolean","isFormData","FormData","isPrimitive","isBuiltin","candidate","className","isEvent","Event","base","isInstanceOf","MOBILE","ANDROID","TABLET","ANDROID_TABLET","IPAD","APPLE_WATCH","APPLE","BLACKBERRY","NINTENDO","PLAYSTATION","XBOX","WINDOWS_PHONE","WINDOWS","NOKIA","OUYA","GENERIC","GENERIC_MOBILE","toLowerCase","GENERIC_TABLET","XBOX_REGEX","RegExp","PLAYSTATION_REGEX","NINTENDO_REGEX","BLACKBERRY_REGEX","stripUrlHash","url","split","parsedStackResults","lastKeysCount","cachedFilenameChunkIds","getLengthFromRules","rules","type","rule","find","r","getFilenameToChunkIdMap","stackParser","chunkIdMap","globalThis","_posthogChunkIds","chunkIdKeys","keys","length","reduce","acc","stackKey","result","parsedStack","i","stackFrame","filename","chunkId","UNKNOWN_FUNCTION","createFrame","platform","func","lineno","colno","frame","function","in_app","extractSafariExtensionDetails","isSafariExtension","isSafariWebExtension","chromeRegexNoFnName","chromeRegex","chromeEvalRegex","chromeStackLineParser","line","noFnParts","exec","col","parts","subMatch","geckoREgex","geckoEvalRegex","geckoStackLineParser","WEBPACK_ERROR_REGEXP","ERROR_TYPES_PATTERN","severityLevels","extractExceptionKeysForMessage","err","maxLength","sort","serialized","slice","join","win","window","undefined","global","self","File","navigator","document","XMLHttpRequest","userAgent","assignableWindow","isDocument","Document","_createLogger","prefix","_temp","debugEnabled","logger","_log","level","POSTHOG_DEBUG","console","consoleLog","_len","arguments","args","_key","debug","_len2","_key2","info","_len3","_key3","warn","_len4","_key4","error","_len5","_key5","critical","_len6","_key6","uninitializedWarning","methodName","createLogger","additionalPrefix","options","each","iterator","forEach","val","key","extend","prop","entries","ownProps","resArray","addEventListener","element","event","callback","capture","passive","formDataToQuery","formdata","arg_separator","use_val","use_key","tph_arr","encodeURIComponent","patch","__posthog_wrapped__","isHostOnDenyList","_options$payloadHostD","hostname","URL","hostnameFromURL","defaultNotDenied","isHostDenied","payloadHostDenyList","deny","endsWith","NODE_TYPE_ELEMENT","NODE_TYPE_TEXT","NODE_TYPE_DOCUMENT_FRAGMENT","isElementNode","el","nodeType","isTag","tag","tagName","isShadowRoot","host","splitClassString","s","getClassNames","baseVal","getAttribute","getSafeText","elText","shouldCaptureElement","isSensitiveElement","childNodes","child","_makeSafeText","isTextNode","textContent","filter","shouldCaptureValue","replace","substring","makeSafeText","autocaptureCompatibleElements","getParentElement","curEl","parentNode","DEFAULT_DEAD_CLICK_IGNORE_LIST","cannotCheckForAutocapture","getElementAndParentsForElement","captureOnAnyElement","parentIsUsefulElement","targetElementList","push","compStyles","getComputedStyle","getPropertyValue","classes","id","test","coreCCPattern","anchoredCCRegex","unanchoredCCRegex","coreSSNPattern","anchoredSSNRegex","unanchoredSSNRegex","anchorRegexes","getDirectAndNestedSpanText","target","text","getNestedSpanText","_child$tagName","spanText","e","escapeQuotes","input","extractAttrClass","attr_class","MAX_PAYLOAD_SIZE_BYTES","defaultNetworkOptions","initiatorTypes","maskRequestFn","data","recordHeaders","recordBody","recordInitialRequests","recordPerformance","performanceEntryTypeToObserve","payloadSizeLimitBytes","streamNetworkBody","isNavigationTiming","entry","entryType","isResourceTiming","shouldRecordHeaders","isRequest","Request","NEVER_RECORD_BODY_CONTENT_TYPES","shouldRecordBody","_ref","headers","matchesContentType","contentTypes","contentTypeHeader","contentType","some","ct","isBlobURL","startsWith","protocol","_unused2","recordBodyType","getRequestPerformanceEntry","_x","_x2","_x3","_x4","_x5","_x6","_getRequestPerformanceEntry","apply","this","_asyncToGenerator","initiatorType","start","end","attempt","performanceEntry","array","predicate","startTime","findLast","performance","getEntriesByName","Promise","resolve","setTimeout","_tryReadXHRBody","_ref2","body","JSON","stringify","_unused3","exposesServerTiming","prepareRequest","_ref3","method","status","networkRequest","isInitial","responseEnd","timeOrigin","Math","floor","Date","now","timestamp","requests","_extends","toJSON","round","endTime","requestHeaders","requestBody","responseHeaders","responseBody","timing","serverTiming","duration","contentTypePrefixDenyList","isReadableStreamBody","getReader","tee","BODY_READ_TIMEOUT_MS","BODY_READ_TIMEOUT_MESSAGE","BODY_READ_FAILED_MESSAGE","bodyReadFailedMessage","reason","bodyTooLargeMessage","limitBytes","_readBody","timeout","clone","then","txt","finally","clearTimeout","_unused5","_tryReadBody","_options$payloadSizeL","min","effectivePayloadLimitBytes","_r$headers","headerValue","get","contentLength","parseInt","Number","isFinite","_unused4","_contentLengthExceedsLimit","reader","settled","cancel","_reader","_unused6","done","_unused7","TextDecoder","_unused9","chunks","received","pump","read","_ref5","streamDone","decode","totalBytes","merged","Uint8Array","offset","chunk","set","byteLength","concatChunks","_unused8","_tryReadBodyStreaming","_tryReadRequestBody2","_ref6","_tryReadResponseBody2","_ref7","cannotReadBodyReason","_ref4","_r$headers$get","contentTypeIsDenied","_checkForCannotReadResponseBody","initialisedHandler","initNetworkObserver","networkOptions","assign","cb","request","maskedRequest","performanceObserver","initialPerformanceEntries","getEntries","flatMap","observer","PerformanceObserver","performanceEntries","wrappedInitiatorFilter","entryTypes","supportedEntryTypes","observe","disconnect","initPerformanceObserver","xhrObserver","fetchObserver","recordRequestHeaders","recordResponseHeaders","restorePatch","originalOpen","async","username","password","xhr","req","originalSetRequestHeader","setRequestHeader","bind","header","originalSend","send","cleanup","removeEventListener","readyStateListener","readyState","DONE","getAllResponseHeaders","shift","response","catch","initXhrObserver","originalFetch","_ref8","init","res","_x7","_tryReadRequestBody","_x8","_tryReadResponseBody","_res","_x9","_x0","initFetchObserver","getRecordNetworkPlugin","__PosthogExtensions__","rrwebPlugins","getRecordConsolePlugin","rrweb","record","rrwebRecord","version","wasMaxDepthReached","resetMaxDepthState","rrwebConsoleRecord","d","w","_","t","u","o","f","c","n","__b","a","__r","v","diffed","l","__c","m","unmount","__","p","__h","__H","D","__N","setState","__f","every","props","shouldComponentUpdate","componentWillUpdate","__e","h","y","__s","C","A","T","current","context","sub","j","__P","z","B","__v","__k","__m","requestAnimationFrame","k","cancelAnimationFrame","SurveyWidgetType","Tab","Selector","SurveyPosition","TopLeft","TopRight","TopCenter","MiddleLeft","MiddleRight","MiddleCenter","Left","Center","Right","NextToTrigger","SurveyTabPosition","Top","Bottom","SurveyType","Popover","API","Widget","ExternalSurvey","SurveyQuestionType","Open","MultipleChoice","SingleChoice","Rating","Link","SurveyQuestionBranchingType","End","ResponseBased","SpecificQuestion","SurveySchedule","SurveyEventName","SHOWN","DISMISSED","SENT","ABANDONED","SurveyEventProperties","SURVEY_ID","SURVEY_NAME","SURVEY_ITERATION","SURVEY_ITERATION_START_DATE","SURVEY_PARTIALLY_COMPLETED","SURVEY_SUBMISSION_ID","SURVEY_COMPLETED","SURVEY_LANGUAGE","getSurveyResponseKey","questionId","getSurveyResponseValue","responses","buildSurveyResponseProperties","survey","oldFormatResponses","questions","question","originalQuestionIndex","oldResponseKey","$survey_questions","map","getSurveyInteractionProperty","action","surveyProperty","current_iteration","getTrimmedLanguage","normalizeLanguageCode","languageCode","findBestTranslationMatch","translations","targetLanguage","normalizedTarget","exactMatch","baseLanguage","baseMatch","applySurveyTranslation","_translatedResults$fi","translationKey","translated","hasTranslation","_survey$translations","translation","appearance","thankYouMessageHeader","thankYouMessageDescription","thankYouMessageCloseButtonText","submitButtonText","backButtonText","hasAppearanceTranslation","translatedResults","_question$translation","matchedKey","hasChanges","questionTranslation","description","buttonText","link","lowerBoundLabel","upperBoundLabel","choices","isTranslatedChoices","mergeQuestionTranslation","translatedQuestions","anyQuestionTranslated","questionMatchedKey","SURVEY_LOGGER","SURVEY_IN_PROGRESS_PREFIX","getSurveyStorageKey","getSurveySeenKey","setSurveySeenOnLocalStorage","surveySeenKey","localStorage","getItem","setItem","IN_APP_SURVEY_TYPES","trunc","ceil","isInteger","UUID","constructor","bytes","TypeError","fromFieldsV7","unixTsMs","randA","randBHi","randBLo","RangeError","pow","Error","equals","other","compareTo","diff","sign","V7Generator","_timestamp","_counter","_random","DefaultRandom","generate","generateOrAbort","valueAfterReset","ts","_resetCounter","nextUint32","defaultGenerator","getRandomValues","buffer","UUIDV7_DENY_WEAK_RNG","random","crypto","_buffer","Uint32Array","_cursor","Infinity","uuidv7","uuidv7obj","isMatchingRegex","pattern","isValidRegex","propertyComparisons","exact","targets","values","is_not","regex","not_regex","icontains","not_icontains","gt","numValue","parseFloat","isNaN","lt","_localStorage_supported","localStore","_is_supported","supported","_set","_get","_remove","_error","msg","_parse","parse","removeItem","_window","_document","BLACK_TEXT_COLOR","defaultSurveyAppearance","fontFamily","backgroundColor","submitButtonColor","submitButtonTextColor","ratingButtonColor","ratingButtonActiveColor","borderColor","placeholder","whiteLabel","displayThankYouMessage","position","widgetType","widgetLabel","widgetColor","zIndex","String","disabledButtonOpacity","maxWidth","textSubtleColor","boxPadding","boxShadow","borderRadius","shuffleQuestions","surveyPopupDelaySeconds","outlineColor","inputBackground","inputTextColor","scrollbarThumbColor","scrollbarTrackColor","BOTTOM_BORDER_SURVEY_POSITIONS","hex2rgb","hexColor","getContrastingTextColor","color","rgb","nameColorToHex","aliceblue","antiquewhite","aqua","aquamarine","azure","beige","bisque","black","blanchedalmond","blue","blueviolet","brown","burlywood","cadetblue","chartreuse","chocolate","coral","cornflowerblue","cornsilk","crimson","cyan","darkblue","darkcyan","darkgoldenrod","darkgray","darkgreen","darkkhaki","darkmagenta","darkolivegreen","darkorange","darkorchid","darkred","darksalmon","darkseagreen","darkslateblue","darkslategray","darkturquoise","darkviolet","deeppink","deepskyblue","dimgray","dodgerblue","firebrick","floralwhite","forestgreen","fuchsia","gainsboro","ghostwhite","gold","goldenrod","gray","green","greenyellow","honeydew","hotpink","indigo","ivory","khaki","lavender","lavenderblush","lawngreen","lemonchiffon","lightblue","lightcoral","lightcyan","lightgoldenrodyellow","lightgrey","lightgreen","lightpink","lightsalmon","lightseagreen","lightskyblue","lightslategray","lightsteelblue","lightyellow","lime","limegreen","linen","magenta","maroon","mediumaquamarine","mediumblue","mediumorchid","mediumpurple","mediumseagreen","mediumslateblue","mediumspringgreen","mediumturquoise","mediumvioletred","midnightblue","mintcream","mistyrose","moccasin","navajowhite","navy","oldlace","olive","olivedrab","orange","orangered","orchid","palegoldenrod","palegreen","paleturquoise","palevioletred","papayawhip","peachpuff","peru","pink","plum","powderblue","purple","red","rosybrown","royalblue","saddlebrown","salmon","sandybrown","seagreen","seashell","sienna","silver","skyblue","slateblue","slategray","snow","springgreen","steelblue","tan","teal","thistle","tomato","turquoise","violet","wheat","white","whitesmoke","yellow","yellowgreen","colorMatch","match","g","b","sqrt","retrieveSurveyShadow","posthog","widgetClassName","getSurveyContainerClass","existingDiv","querySelector","shadowRoot","shadow","isNewlyCreated","div","createElement","addSurveyCSSVariablesToElement","effectiveAppearance","hostStyle","style","surveyHasBottomBorder","setProperty","defaultFontStack","getFontFamily","textColor","userInputBg","inputBackgroundColor","inputBgColor","attachShadow","mode","stylesheet","prepareStylesheet","innerText","_posthog$config","config","prepare_external_dependency_stylesheet","setAttribute","getSurveyStylesheet","existingStylesheet","removeChild","appendChild","sendSurveyEvent","surveySubmissionId","isSurveyCompleted","properties","surveyLanguage","current_iteration_start_date","sessionRecordingUrl","get_session_replay_url","$set","dispatchEvent","CustomEvent","detail","surveyId","clearInProgressSurveyState","_buildSurveyEventProperties","inProgressSurvey","dismissedSurveyEvent","readOnly","getInProgressSurveyState","sendSurveyAbandonedEvent","abandonedKey","getSurveyAbandonedKey","transport","shuffle","reverseIfUnshuffled","unshuffled","shuffled","index","reverse","getDisplayOrderQuestions","enable_partial_responses","canActivateRepeatedly","_survey$conditions3","conditions","events","repeatedActivation","_survey$conditions","_survey$conditions2","hasEvents","schedule","isSurveyInProgress","SurveyContext","createContext","isPreviewMode","previewPageIndex","onPopupSurveyDismissed","isPopup","onPreviewSubmit","onPreviewBack","useSurveyContext","useContext","renderChildrenAsTextOrHtml","component","children","renderAsHtml","cloneElement","dangerouslySetInnerHTML","__html","doesSurveyUrlMatch","_survey$conditions4","_survey$conditions5","instance","_window$location","defaultUrl","href","location","_instance$config","override","get_current_url","applyUrlTargetingOverride","matchType","defaultMatchType","urlMatchType","doesSurveyDeviceTypesMatch","_survey$conditions6","_survey$conditions7","deviceTypes","_navigator$userAgentD","_window$screen","_window$screen2","_options$maxTouchPoin","_options$screenWidth","_options$screenHeight","_options$devicePixelR","device","deviceType","userAgentDataPlatform","userAgentData","maxTouchPoints","screenWidth","screen","width","screenHeight","height","devicePixelRatio","user_agent","detectDevice","doesDeviceTypeMatch","deviceTypesMatchType","getInProgressSurveyStateKey","setInProgressSurveyState","state","stateString","asSelector","getPopoverPosition","surveyWidgetType","top","left","transform","right","satisfiedEmoji","_jsx","xmlns","viewBox","neutralEmoji","dissatisfiedEmoji","veryDissatisfiedEmoji","verySatisfiedEmoji","thumbsUpEmoji","thumbsDownEmoji","cancelSVG","fill","_jsxs","IconPosthogLogo","maskType","maskUnits","mask","PostHogLogo","urlParams","queryString","rel","BottomSection","submitDisabled","onSubmit","skipSubmitButton","canGoBack","onBack","showBackButton","submitButton","disabled","onClick","open","utm_source","QuestionHeader","forceDisableHtml","htmlFor","class","descriptionContentType","Cancel","ConfirmationMessage","onClose","useEffect","handleKeyDown","preventDefault","role","tabIndex","hideCancelButton","isValidStringArray","item","OpenTextQuestion","displayQuestionIndex","initialValue","inputRef","useRef","setText","useState","_inputRef$current","focus","validationError","useMemo","optional","_rule$errorMessage","_rule$errorMessage2","trimmed","MinLength","errorMessage","MaxLength","getValidationError","validation","minLength","requirementsHint","effectiveMin","getRequirementsHint","handleSubmit","handlePreviewSubmit","Fragment","ref","rows","onInput","currentTarget","stopPropagation","onKeyDown","metaKey","ctrlKey","LinkQuestion","RatingQuestion","_emojiScaleLists$ques","scale","starting","rating","setRating","isThumbSurvey","display","num","emojiScaleLists","emoji","idx","gridTemplateColumns","getScaleNumbers","number","RatingButton","active","setActiveNumber","MultipleChoiceQuestion","openChoiceInputRef","shuffleOptions","displayOrderChoices","openEndedChoice","hasOpenChoice","pop","shuffledOptions","getDisplayOrderChoices","selectedChoices","setSelectedChoices","initializeSelectedChoices","questionType","openEndedState","setOpenEndedState","initializeOpenEndedState","isSelected","inputValue","openEndedValue","choice","isSingleChoiceQuestion","isMultipleChoiceQuestion","shouldSkipSubmit","handleChoiceChange","isOpenChoice","newOpenSelected","prev","_openChoiceInputRef$c","handleOpenEndedInputChange","newValue","handleOpenEndedKeyDown","isSubmitDisabled","inputId","openInputId","isChecked","checked","onChange","fiveScaleNumbers","sevenScaleNumbers","tenScaleNumbers","getNextSurveyStep","currentQuestionIndex","_question$branching","nextQuestionIndex","branching","_question$branching2","selectedChoiceIndex","responseValues","nextStep","_question$branching3","ratingBucket","responseValue","getRatingBucketForResponseValue","applySurveyTranslationForUser","userLanguage","overrideLanguage","storedPersonProperties","locale","explicitLanguage","personLanguage","language","getLanguageFromStoredPersonProperties","detectedLocale","detectSurveyLanguage","override_display_language","get_property","detectUserLanguage","DISPATCH_FEEDBACK_WIDGET_EVENT","WIDGET_LISTENER_ATTRIBUTE","getNextToTriggerPosition","surveyWidth","buttonRect","getBoundingClientRect","viewportHeight","innerHeight","viewportWidth","innerWidth","spaceBelow","bottom","showAbove","SurveyManager","_this","_surveyTimeouts","Map","_widgetSelectorListeners","_prefillHandledSurveys","Set","handlePageUnload","surveys","_posthog","handlePopoverSurvey","surveyParam","_survey$appearance","_survey$appearance2","_survey$appearance3","_survey$appearance5","translatedSurvey","_translateSurveyForRendering","selector","widgetSelector","_clearSurveyTimeout","initialResponses","_handleInitialResponses","_addSurveyToFocus","positionStyle","_survey$appearance4","targetElement","delaySeconds","surveyPopupProps","removeSurveyFromFocus","_removeSurveyFromFocus","skipShownEvent","render","SurveyPopup","timeoutId","delete","_shouldDisplaySurvey","_handleWidget","FeedbackWidget","_removeWidgetSelectorListener","_removeSurveyFromDom","existing","listener","removeAttribute","_manageWidgetSelectorListener","currentElement","existingListenerData","hasAttribute","_survey$appearance6","_survey$appearance7","positionStyles","renderPopover","renderSurvey","_this$_posthog$config","prefillFromUrl","_handleUrlPrefill","getActiveMatchingSurveys","forceReload","_this$_posthog","getSurveys","targetingMatchedSurveys","callSurveysAndEvaluateDisplayLogic","inAppSurveysWithDisplayLogic","matchingIds","pendingSurveyId","from","has","cancelSurvey","inAppSurveysQueue","_sortSurveysByAppearanceDelay","activeSelectorSurveys","_survey$appearance8","_survey$appearance9","_survey$appearance0","_survey$appearance1","add","_surveyInFocus","_a$appearance","_b$appearance","isSurveyInProgressA","isSurveyInProgressB","aIsAlways","bIsAlways","params","searchString","autoSubmit","cleanSearch","pairs","pair","decodedKey","decodeURIComponent","decodedValue","questionIndex","extractPrefillParamsFromUrl","search","_processPrefillData","submissionId","skippedResponses","prefillParams","indexStr","responseKey","choiceIndex","choiceIndices","uniqueChoices","convertPrefillToResponses","prefilledIndices","startQuestionIndex","currentIndex","MAX_ITERATIONS","calculatePrefillStartIndex","lastQuestionIndex","_isSurveyFeatureFlagEnabled","flagKey","flagVariant","_this$_posthog$featur","_this$_posthog$featur2","isFeatureEnabled","featureFlags","send_event","flagVariantCheck","getFeatureFlag","_isSurveyConditionMatched","_survey$conditions8","doesSurveyMatchSelector","_internalFlagCheckSatisfied","internal_targeting_flag_key","checkSurveyEligibility","eligibility","eligible","start_date","end_date","isSurveyRunning","linkedFlagVariant","linked_flag_key","targeting_flag_key","periodDays","lastSeenDate","date","diffMs","abs","getTime","hasPeriodPassed","seenSurveyWaitPeriodInDays","getSurveySeen","_hasActionOrEventTriggeredSurvey","_this$_posthog$survey","doesSurveyActivateByEvent","actions","doesSurveyActivateByAction","surveysActivatedByEventsOrActions","_surveyEventReceiver","_checkFlags","_survey$feature_flag_","feature_flag_keys","shadowContainer","remove","getTestAPI","addSurveyToFocus","surveyInFocus","surveyTimeouts","handleWidget","manageWidgetSelectorListener","sortSurveysByAppearanceDelay","checkFlags","isSurveyFeatureFlagEnabled","generateSurveys","isSurveysEnabled","intervalId","surveyManager","disable_surveys_automatic_display","startInterval","setInterval","hidden","clearInterval","useHideSurveyOnURLChange","setSurveyVisible","checkUrlMatch","_survey$appearance10","isSurveyTypeWidget","doesSurveyMatchUrlCondition","isSurveyWidgetTypeTab","originalPushState","history","pushState","originalReplaceState","replaceState","getTabPositionStyles","transformOrigin","_survey$appearance13","_survey$appearance14","_survey$appearance15","_survey$appearance16","_survey$appearance17","_survey$appearance18","onCloseConfirmationMessage","surveyContainerRef","surveyPopupDelayMilliseconds","isPopupVisible","isSurveySent","hidePopupWithViewTransition","millisecondDelay","setIsPopupVisible","setIsSurveySent","removeDOMAndHidePopup","startViewTransition","_surveyContainerRef$c","finished","handleSurveyClosed","handleSurveySent","_survey$appearance11","_survey$appearance12","autoDisappear","showSurvey","toISOString","usePopupVisibility","shouldShowConfirmation","surveyContextValue","getInProgressSurvey","Provider","thankYouMessageDescriptionContentType","Questions","_survey$appearance19","_survey$appearance20","questionsResponses","setQuestionsResponses","inProgressSurveyData","setCurrentQuestionIndex","visitedIndices","setVisitedIndices","_inProgressSurveyData","surveyQuestions","allowGoBack","currentQuestion","at","getQuestionComponent","newResponses","newVisitedIndices","visitedResponseKeys","_surveyQuestions$i","responsesOnPath","fromEntries","_ref9","onNextButtonClick","onBackButtonClick","previousIndex","_ref0","_survey$appearance22","_survey$appearance23","_survey$appearance24","_survey$appearance25","_survey$appearance26","_survey$appearance27","_survey$appearance28","isFeedbackButtonVisible","setIsFeedbackButtonVisible","setShowSurvey","styleOverrides","setStyleOverrides","toggleSurvey","_survey$appearance21","handleShowSurvey","_customEvent$detail","customEvent","resetShowSurvey","tabPosition","_ref1","baseProps","_createElement","extendPostHogWithSurveys","appendWithLimit","budget","remaining","truncated","stringifyStringWithLimit","low","high","mid","isJSONSerializablePrimitive","collectAttributeValue","collector","keysRemaining","sizeRemaining","collectFlattenedAttributes","seen","childKey","stringifyValueWithLimit","inArray","attributeCollector","isNumberOrBoolean","objectTag","valueOf","errorObject","message","stack","_unused0","isFirst","propertyValue","_unused1","_unused10","propertyPrefix","partsBeforeProperty","remainingBeforeProperty","truncatedBeforeProperty","partsBeforeValue","truncatedAfterValue","_unused11","LEVEL_MAP","log","logs","initializeLogs","attributes","_loop","originalConsoleLog","is_capturing","_posthog$logs","flattenedAttributes","stringifyArgsSafely","sizeLimit","WeakSet","logAttributes","body_truncated","_captureConsoleLog","_unused12","errorPropertiesBuilder","coercers","modifiers","buildFromUnknown","hint","mechanism","handled","exceptionWithCause","buildCoercingContext","parsingContext","buildParsingContext","exceptionWithStack","parseStacktrace","$exception_list","convertToExceptionList","$exception_level","modifyFrames","exceptionList","exc","stacktrace","frames","applyModifiers","coerceFallback","ctx","_ctx$syntheticExcepti","syntheticException","synthetic","cause","applyChunkIds","skipFirstLines","chunk_id","applyCoercers","adapter","coerce","_this2","newFrames","modifier","_mechanism$type","_mechanism$handled","_exceptionWithStack$s","currentException","_hint$skipFirstLines","depth","next","isDOMException","isDOMError","hasStack","getType","getValue","isCustomEventWrappingRejection","getUnhandledRejectionReason","getMessage","getStack","_ctx","evt","constructorName","errorProperty","getErrorPropertyFromObject","isSeverityLevel","getObjectClassName","isEmptyString","getPrototypeOf","getInfos","groups","parsers","lines","cleanedLine","parser","localStack","arr","reverseAndStripFrames","createStackParser","posthogErrorWrappingFunctions","wrapOnError","captureFn","originalOnError","onerror","_originalOnError","errorProperties","__POSTHOG_INSTRUMENTED__","_win$onerror","wrapUnhandledRejection","originalOnUnhandledRejection","onunhandledrejection","ev","_originalOnUnhandledR","_win$onunhandledrejec","wrapConsoleError","con","originalConsoleError","arg","_con$error","errorWrappingFunctions","SESSION_ID_HEADER","WINDOW_ID_HEADER","DISTINCT_ID_HEADER","TRACING_HEADERS","REQUEST_INIT_KEYS","property","isObjectLike","getRequestUrl","addTracingHeaders","hostnames","distinctId","sessionManager","reqHostname","hasAddedHeaders","sessionId","windowId","checkAndGetSessionAndWindowId","currentDistinctId","getDistinctId","patchFns","_patchFetch","patchFetch","originalArgs","fetchArgs","requestUrl","Headers","initWithHeaders","createFetchInitWithHeaders","originalInit","Proxy","Reflect","create","defineProperty","configurable","writable","ownKeys","getOwnPropertyDescriptor","targetDescriptor","descriptor","_patchXHR","patchXHR","tracingHeadersPatchFns","postHogTracingHeadersPatchFns","len","relativeIndex","persisted","timeStamp","delta","getEntriesByType","responseStart","_s$activationStart","_s","activationStart","prerendering","wasDiscarded","navigationType","WeakMap","_this$t","hadRecentInput","queueMicrotask","buffered","visibilityState","_globalThis$performan","firstHiddenTime","onHidden","max","reportAllChanges","E","L","P","M","interactionId","_performance$interact","interactionCount","F","clear","_this$m","_this$p","splice","requestIdleCallback","cancelIdleCallback","once","q","_this$m2","N","postHogWebVitalsCallbacks","onLCP","takeRecords","isTrusted","onCLS","onFCP","onINP","PerformanceEventTiming","_i$durationThreshold","durationThreshold","limitText","previousElementSibling","_el","previousSibling","autocapturePropertiesForElement","_elementsJson$","_elementsJson$2","maskAllElementAttributes","maskAllText","elementAttributeIgnoreList","disableCaptureUrlHashes","externalHref","elements","elementsJson","autocaptureAugmentProperties","explicitNoCapture","shouldCaptureEl","hrefAttr","elem","maskAllAttributes","maskText","elementAttributeIgnorelist","tag_name","attr","attributeName","nthChild","nthOfType","currentElem","getPropertiesFromElement","augmentProperties","propertyKey","getAugmentPropertiesFromElement","_convertToURL","hrefHost","locationHost","$event_type","$ce_version","$elements","$elements_chain","ret","_element$nth_child","_element$nth_of_type","el_string","single_class","nth_child","nth_of_type","attr_id","sortedAttributes","localeCompare","elementsToString","_el$$el_text","_el$attr__href","extractElements","$el_text","$external_click_url","loadWebVitalsCallbacks","cachedImplementations","getNativeMutationObserverImplementation","cached","impl","Zone","sandbox","head","contentWindow","getNativeImplementation","checkTimeout","thresholdMs","LazyLoadedDeadClicksAutocapture","_asRequiredConfig","providedConfig","_providedConfig$eleme","_providedConfig$scrol","_providedConfig$selec","_providedConfig$mutat","_providedConfig$captu","defaultConfig","_defaultConfig","__onCapture","_captureDeadClick","element_attribute_ignorelist","scroll_threshold_ms","selection_change_threshold_ms","mutation_threshold_ms","capture_clicks_with_modifier_keys","css_selector_ignorelist","_clicks","defaultOnCapture","_onClick","click","eventTarget","srcElement","_e$target","composedPath","getEventTarget","node","originalEvent","asClick","_ignoreClick","_checkClickTimer","_checkClicks","_onScroll","candidateNow","scrollDelayMs","_onSelectionChange","_lastSelectionChanged","_onVisibilityChange","_lastVisibilityChange","_config","_onCapture","observerTarget","_startClickObserver","_startScrollObserver","_startSelectionChangedObserver","_startVisibilityChangeObserver","_startMutationObserver","_mutationObserver","NativeMutationObserver","mutations","_onMutation","characterData","childList","subtree","stop","_this$_mutationObserv","_mutations","_lastMutation","altKey","shiftKey","Element","closest","alreadyClickedInLastSecond","shouldSkipDeadClick","_config$css_selector_","selectorIgnoreList","selectorList","_ret2","_loop2","matches","matchesSelector","msMatchesSelector","mozMatchesSelector","webkitMatchesSelector","oMatchesSelector","elementMatchesCSSSelector","checkIfElementsMatchCSSSelector","shouldCaptureDeadClick","clicksToCheck","_click$mutationDelayM","mutationDelayMs","absoluteDelayMs","selectionChangedDelayMs","visibilityChangedDelayMs","scrollTimeout","selectionChangedTimeout","mutationTimeout","absoluteTimeout","hadScroll","hadMutation","hadSelectionChange","hadVisibilityChange","visibilityChangedTimeout","$dead_click_last_mutation_timestamp","$dead_click_event_timestamp","$dead_click_scroll_timeout","$dead_click_mutation_timeout","$dead_click_absolute_timeout","$dead_click_selection_changed_timeout","$dead_click_visibility_changed_timeout","mask_all_element_attributes","mask_all_text","disable_capture_url_hashes","$dead_click_scroll_delay_ms","$dead_click_mutation_delay_ms","$dead_click_absolute_delay_ms","$dead_click_selection_changed_delay_ms","$dead_click_visibility_changed_delay_ms","initDeadClicksAutocapture","ph"],"mappings":"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","x_google_ignoreList":[30,31,69]}