UNPKG

@posthog/rrweb

Version:
1,564 lines 565 kB
var __defProp = Object.defineProperty; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); var _a; var __defProp$1 = Object.defineProperty; var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __publicField$1 = (obj, key, value) => __defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value); var NodeType$1$1 = /* @__PURE__ */ ((NodeType2) => { NodeType2[NodeType2["Document"] = 0] = "Document"; NodeType2[NodeType2["DocumentType"] = 1] = "DocumentType"; NodeType2[NodeType2["Element"] = 2] = "Element"; NodeType2[NodeType2["Text"] = 3] = "Text"; NodeType2[NodeType2["CDATA"] = 4] = "CDATA"; NodeType2[NodeType2["Comment"] = 5] = "Comment"; return NodeType2; })(NodeType$1$1 || {}); const testableAccessors$1 = { Node: ["childNodes", "parentNode", "parentElement", "textContent"], ShadowRoot: ["host", "styleSheets"], Element: ["shadowRoot", "querySelector", "querySelectorAll"], MutationObserver: [] }; const testableMethods$1 = { Node: ["contains", "getRootNode"], ShadowRoot: ["getSelection"], Element: [], MutationObserver: ["constructor"] }; const untaintedBasePrototype$1 = {}; function angularZoneUnpatchedAlternative$1(key) { var _a2, _b; const angularUnpatchedVersionSymbol = (_b = (_a2 = globalThis == null ? void 0 : globalThis.Zone) == null ? void 0 : _a2.__symbol__) == null ? void 0 : _b.call(_a2, key); if (angularUnpatchedVersionSymbol && globalThis[angularUnpatchedVersionSymbol]) { return globalThis[angularUnpatchedVersionSymbol]; } else { return void 0; } } function getUntaintedPrototype$1(key) { if (untaintedBasePrototype$1[key]) return untaintedBasePrototype$1[key]; const candidate = angularZoneUnpatchedAlternative$1(key) || globalThis[key]; const defaultPrototype = candidate.prototype; const accessorNames = key in testableAccessors$1 ? testableAccessors$1[key] : void 0; const isUntaintedAccessors = Boolean( accessorNames && // @ts-expect-error 2345 accessorNames.every( (accessor) => { var _a2, _b; return Boolean( (_b = (_a2 = Object.getOwnPropertyDescriptor(defaultPrototype, accessor)) == null ? void 0 : _a2.get) == null ? void 0 : _b.toString().includes("[native code]") ); } ) ); const methodNames = key in testableMethods$1 ? testableMethods$1[key] : void 0; const isUntaintedMethods = Boolean( methodNames && methodNames.every( // @ts-expect-error 2345 (method) => { var _a2; return typeof defaultPrototype[method] === "function" && ((_a2 = defaultPrototype[method]) == null ? void 0 : _a2.toString().includes("[native code]")); } ) ); if (isUntaintedAccessors && isUntaintedMethods) { untaintedBasePrototype$1[key] = candidate.prototype; return candidate.prototype; } try { const iframeEl = document.createElement("iframe"); document.body.appendChild(iframeEl); const win = iframeEl.contentWindow; if (!win) return candidate.prototype; const untaintedObject = win[key].prototype; document.body.removeChild(iframeEl); if (!untaintedObject) return defaultPrototype; return untaintedBasePrototype$1[key] = untaintedObject; } catch { return defaultPrototype; } } const untaintedAccessorCache$1 = {}; function getUntaintedAccessor$1(key, instance, accessor) { var _a2; const cacheKey = `${key}.${String(accessor)}`; if (untaintedAccessorCache$1[cacheKey]) return untaintedAccessorCache$1[cacheKey].call( instance ); const untaintedPrototype = getUntaintedPrototype$1(key); const untaintedAccessor = (_a2 = Object.getOwnPropertyDescriptor( untaintedPrototype, accessor )) == null ? void 0 : _a2.get; if (!untaintedAccessor) return instance[accessor]; untaintedAccessorCache$1[cacheKey] = untaintedAccessor; return untaintedAccessor.call(instance); } const untaintedMethodCache$1 = {}; function getUntaintedMethod$1(key, instance, method) { const cacheKey = `${key}.${String(method)}`; if (untaintedMethodCache$1[cacheKey]) return untaintedMethodCache$1[cacheKey].bind( instance ); const untaintedPrototype = getUntaintedPrototype$1(key); const untaintedMethod = untaintedPrototype[method]; if (typeof untaintedMethod !== "function") return instance[method]; untaintedMethodCache$1[cacheKey] = untaintedMethod; return untaintedMethod.bind(instance); } function childNodes$1(n2) { return getUntaintedAccessor$1("Node", n2, "childNodes"); } function parentNode$1(n2) { return getUntaintedAccessor$1("Node", n2, "parentNode"); } function parentElement$1(n2) { return getUntaintedAccessor$1("Node", n2, "parentElement"); } function textContent$1(n2) { return getUntaintedAccessor$1("Node", n2, "textContent"); } function contains$1(n2, other) { return getUntaintedMethod$1("Node", n2, "contains")(other); } function getRootNode$1(n2) { return getUntaintedMethod$1("Node", n2, "getRootNode")(); } function host$1(n2) { if (!n2 || !("host" in n2)) return null; return getUntaintedAccessor$1("ShadowRoot", n2, "host"); } function styleSheets$1(n2) { return n2.styleSheets; } function shadowRoot$1(n2) { if (!n2 || !("shadowRoot" in n2)) return null; return getUntaintedAccessor$1("Element", n2, "shadowRoot"); } function querySelector$1(n2, selectors) { return getUntaintedAccessor$1("Element", n2, "querySelector")(selectors); } function querySelectorAll$1(n2, selectors) { return getUntaintedAccessor$1("Element", n2, "querySelectorAll")(selectors); } function mutationObserverCtor$1() { return getUntaintedPrototype$1("MutationObserver").constructor; } function patch$1(source, name, replacement) { try { if (!(name in source)) { return () => { }; } const original = source[name]; const wrapped = replacement(original); if (typeof wrapped === "function") { wrapped.prototype = wrapped.prototype || {}; Object.defineProperties(wrapped, { __rrweb_original__: { enumerable: false, value: original } }); } source[name] = wrapped; return () => { source[name] = original; }; } catch { return () => { }; } } const index$1 = { childNodes: childNodes$1, parentNode: parentNode$1, parentElement: parentElement$1, textContent: textContent$1, contains: contains$1, getRootNode: getRootNode$1, host: host$1, styleSheets: styleSheets$1, shadowRoot: shadowRoot$1, querySelector: querySelector$1, querySelectorAll: querySelectorAll$1, mutationObserver: mutationObserverCtor$1, patch: patch$1 }; function isElement(n2) { return n2.nodeType === n2.ELEMENT_NODE; } function isShadowRoot(n2) { const hostEl = ( // anchor and textarea elements also have a `host` property // but only shadow roots have a `mode` property n2 && "host" in n2 && "mode" in n2 && index$1.host(n2) || null ); return Boolean( hostEl && "shadowRoot" in hostEl && index$1.shadowRoot(hostEl) === n2 ); } function isNativeShadowDom(shadowRoot2) { return Object.prototype.toString.call(shadowRoot2) === "[object ShadowRoot]"; } function fixBrowserCompatibilityIssuesInCSS(cssText) { if (cssText.includes(" background-clip: text;") && !cssText.includes(" -webkit-background-clip: text;")) { cssText = cssText.replace( /\sbackground-clip:\s*text;/g, " -webkit-background-clip: text; background-clip: text;" ); } return cssText; } function escapeImportStatement(rule2) { const { cssText } = rule2; if (cssText.split('"').length < 3) return cssText; const statement = ["@import", `url(${JSON.stringify(rule2.href)})`]; if (rule2.layerName === "") { statement.push(`layer`); } else if (rule2.layerName) { statement.push(`layer(${rule2.layerName})`); } if (rule2.supportsText) { statement.push(`supports(${rule2.supportsText})`); } if (rule2.media.length) { statement.push(rule2.media.mediaText); } return statement.join(" ") + ";"; } function stringifyStylesheet(s2) { try { const rules2 = s2.rules || s2.cssRules; if (!rules2) { return null; } let sheetHref = s2.href; if (!sheetHref && s2.ownerNode && s2.ownerNode.ownerDocument) { sheetHref = s2.ownerNode.ownerDocument.baseURI; } const stringifiedRules = Array.from( rules2, (rule2) => stringifyRule(rule2, sheetHref) ).join(""); return fixBrowserCompatibilityIssuesInCSS(stringifiedRules); } catch (error) { return null; } } function stringifyRule(rule2, sheetHref) { var _a2; if (isCSSImportRule(rule2)) { let importStringified; try { importStringified = // for same-origin stylesheets, // we can access the imported stylesheet rules directly stringifyStylesheet(rule2.styleSheet) || // work around browser issues with the raw string `@import url(...)` statement escapeImportStatement(rule2); } catch (error) { importStringified = rule2.cssText; } try { if (importStringified && ((_a2 = rule2.styleSheet) == null ? void 0 : _a2.href)) { return absolutifyURLs(importStringified, rule2.styleSheet.href); } } catch { } return importStringified; } else { let ruleStringified = rule2.cssText; if (isCSSStyleRule(rule2) && rule2.selectorText.includes(":")) { ruleStringified = fixSafariColons(ruleStringified); } if (sheetHref) { return absolutifyURLs(ruleStringified, sheetHref); } return ruleStringified; } } function fixSafariColons(cssStringified) { const regex = /(\[(?:[\w-]+)[^\\])(:(?:[\w-]+)\])/gm; return cssStringified.replace(regex, "$1\\$2"); } function isCSSImportRule(rule2) { return "styleSheet" in rule2; } function isCSSStyleRule(rule2) { return "selectorText" in rule2; } class Mirror { constructor() { __publicField$1(this, "idNodeMap", /* @__PURE__ */ new Map()); __publicField$1(this, "nodeMetaMap", /* @__PURE__ */ new WeakMap()); } getId(n2) { var _a2; if (!n2) return -1; const id = (_a2 = this.getMeta(n2)) == null ? void 0 : _a2.id; return id ?? -1; } getNode(id) { return this.idNodeMap.get(id) || null; } getIds() { return Array.from(this.idNodeMap.keys()); } getMeta(n2) { return this.nodeMetaMap.get(n2) || null; } // removes the node from idNodeMap // doesn't remove the node from nodeMetaMap removeNodeFromMap(n2) { const id = this.getId(n2); this.idNodeMap.delete(id); if (n2.childNodes) { n2.childNodes.forEach( (childNode) => this.removeNodeFromMap(childNode) ); } } has(id) { return this.idNodeMap.has(id); } hasNode(node2) { return this.nodeMetaMap.has(node2); } add(n2, meta) { const id = meta.id; this.idNodeMap.set(id, n2); this.nodeMetaMap.set(n2, meta); } replace(id, n2) { const oldNode = this.getNode(id); if (oldNode) { const meta = this.nodeMetaMap.get(oldNode); if (meta) this.nodeMetaMap.set(n2, meta); } this.idNodeMap.set(id, n2); } reset() { this.idNodeMap = /* @__PURE__ */ new Map(); this.nodeMetaMap = /* @__PURE__ */ new WeakMap(); } } function createMirror$2() { return new Mirror(); } function maskInputValue({ element, maskInputOptions, tagName, type, value, maskInputFn }) { let text = value || ""; const actualType = type && toLowerCase(type); if (maskInputOptions[tagName.toLowerCase()] || actualType && maskInputOptions[actualType]) { if (maskInputFn) { text = maskInputFn(text, element); } else { text = "*".repeat(text.length); } } return text; } function toLowerCase(str) { return str.toLowerCase(); } const ORIGINAL_ATTRIBUTE_NAME = "__rrweb_original__"; function is2DCanvasBlank(canvas) { const ctx = canvas.getContext("2d"); if (!ctx) return true; const chunkSize = 50; for (let x = 0; x < canvas.width; x += chunkSize) { for (let y = 0; y < canvas.height; y += chunkSize) { const getImageData = ctx.getImageData; const originalGetImageData = ORIGINAL_ATTRIBUTE_NAME in getImageData ? getImageData[ORIGINAL_ATTRIBUTE_NAME] : getImageData; const pixelBuffer = new Uint32Array( // eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-member-access originalGetImageData.call( ctx, x, y, Math.min(chunkSize, canvas.width - x), Math.min(chunkSize, canvas.height - y) ).data.buffer ); if (pixelBuffer.some((pixel) => pixel !== 0)) return false; } } return true; } function isNodeMetaEqual(a2, b) { if (!a2 || !b || a2.type !== b.type) return false; if (a2.type === NodeType$1$1.Document) return a2.compatMode === b.compatMode; else if (a2.type === NodeType$1$1.DocumentType) return a2.name === b.name && a2.publicId === b.publicId && a2.systemId === b.systemId; else if (a2.type === NodeType$1$1.Comment || a2.type === NodeType$1$1.Text || a2.type === NodeType$1$1.CDATA) return a2.textContent === b.textContent; else if (a2.type === NodeType$1$1.Element) return a2.tagName === b.tagName && JSON.stringify(a2.attributes) === JSON.stringify(b.attributes) && a2.isSVG === b.isSVG && a2.needBlock === b.needBlock; return false; } function getInputType(element) { const type = element.type; return element.hasAttribute("data-rr-is-password") ? "password" : type ? ( // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion toLowerCase(type) ) : null; } function extractFileExtension(path, baseURL) { let url; try { url = new URL(path, baseURL ?? window.location.href); } catch (err) { return null; } const regex = /\.([0-9a-z]+)(?:$)/i; const match = url.pathname.match(regex); return (match == null ? void 0 : match[1]) ?? null; } function extractOrigin(url) { let origin = ""; if (url.indexOf("//") > -1) { origin = url.split("/").slice(0, 3).join("/"); } else { origin = url.split("/")[0]; } origin = origin.split("?")[0]; return origin; } const URL_IN_CSS_REF = /url\((?:(')([^']*)'|(")(.*?)"|([^)]*))\)/gm; const URL_PROTOCOL_MATCH = /^(?:[a-z+]+:)?\/\//i; const URL_WWW_MATCH = /^www\..*/i; const DATA_URI = /^(data:)([^,]*),(.*)/i; function absolutifyURLs(cssText, href) { return (cssText || "").replace( URL_IN_CSS_REF, (origin, quote1, path1, quote2, path2, path3) => { const filePath = path1 || path2 || path3; const maybeQuote = quote1 || quote2 || ""; if (!filePath) { return origin; } if (URL_PROTOCOL_MATCH.test(filePath) || URL_WWW_MATCH.test(filePath)) { return `url(${maybeQuote}${filePath}${maybeQuote})`; } if (DATA_URI.test(filePath)) { return `url(${maybeQuote}${filePath}${maybeQuote})`; } if (filePath[0] === "/") { return `url(${maybeQuote}${extractOrigin(href) + filePath}${maybeQuote})`; } const stack = href.split("/"); const parts = filePath.split("/"); stack.pop(); for (const part of parts) { if (part === ".") { continue; } else if (part === "..") { stack.pop(); } else { stack.push(part); } } return `url(${maybeQuote}${stack.join("/")}${maybeQuote})`; } ); } let _id = 1; const tagNameRegex = new RegExp("[^a-z0-9-_:]"); const IGNORED_NODE = -2; function genId() { return _id++; } function getValidTagName$1(element) { if (element instanceof HTMLFormElement) { return "form"; } const processedTagName = toLowerCase(element.tagName); if (tagNameRegex.test(processedTagName)) { return "div"; } return processedTagName; } let canvasService; let canvasCtx; const SRCSET_NOT_SPACES = /^[^ \t\n\r\u000c]+/; const SRCSET_COMMAS_OR_SPACES = /^[, \t\n\r\u000c]+/; function getAbsoluteSrcsetString(doc, attributeValue) { if (attributeValue.trim() === "") { return attributeValue; } let pos = 0; function collectCharacters(regEx) { let chars2; const match = regEx.exec(attributeValue.substring(pos)); if (match) { chars2 = match[0]; pos += chars2.length; return chars2; } return ""; } const output = []; while (true) { collectCharacters(SRCSET_COMMAS_OR_SPACES); if (pos >= attributeValue.length) { break; } let url = collectCharacters(SRCSET_NOT_SPACES); if (url.slice(-1) === ",") { url = absoluteToDoc(doc, url.substring(0, url.length - 1)); output.push(url); } else { let descriptorsStr = ""; url = absoluteToDoc(doc, url); let inParens = false; while (true) { const c2 = attributeValue.charAt(pos); if (c2 === "") { output.push((url + descriptorsStr).trim()); break; } else if (!inParens) { if (c2 === ",") { pos += 1; output.push((url + descriptorsStr).trim()); break; } else if (c2 === "(") { inParens = true; } } else { if (c2 === ")") { inParens = false; } } descriptorsStr += c2; pos += 1; } } } return output.join(", "); } const cachedDocument = /* @__PURE__ */ new WeakMap(); function absoluteToDoc(doc, attributeValue) { if (!attributeValue || attributeValue.trim() === "") { return attributeValue; } return getHref(doc, attributeValue); } function isSVGElement(el) { return Boolean(el.tagName === "svg" || el.ownerSVGElement); } function getHref(doc, customHref) { let a2 = cachedDocument.get(doc); if (!a2) { a2 = doc.createElement("a"); cachedDocument.set(doc, a2); } if (!customHref) { customHref = ""; } else if (customHref.startsWith("blob:") || customHref.startsWith("data:")) { return customHref; } a2.setAttribute("href", customHref); return a2.href; } function transformAttribute(doc, tagName, name, value) { if (!value) { return value; } if (name === "src" || name === "href" && !(tagName === "use" && value[0] === "#")) { return absoluteToDoc(doc, value); } else if (name === "xlink:href" && value[0] !== "#") { return absoluteToDoc(doc, value); } else if (name === "background" && (tagName === "table" || tagName === "td" || tagName === "th")) { return absoluteToDoc(doc, value); } else if (name === "srcset") { return getAbsoluteSrcsetString(doc, value); } else if (name === "style") { return absolutifyURLs(value, getHref(doc)); } else if (tagName === "object" && name === "data") { return absoluteToDoc(doc, value); } return value; } function ignoreAttribute(tagName, name, _value) { return (tagName === "video" || tagName === "audio") && name === "autoplay"; } function _isBlockedElement(element, blockClass, blockSelector) { try { if (typeof blockClass === "string") { if (element.classList.contains(blockClass)) { return true; } } else { for (let eIndex = element.classList.length; eIndex--; ) { const className = element.classList[eIndex]; if (blockClass.test(className)) { return true; } } } if (blockSelector) { return element.matches(blockSelector); } } catch (e2) { } return false; } function classMatchesRegex(node2, regex, checkAncestors) { if (!node2) return false; if (node2.nodeType !== node2.ELEMENT_NODE) { if (!checkAncestors) return false; return classMatchesRegex(index$1.parentNode(node2), regex, checkAncestors); } for (let eIndex = node2.classList.length; eIndex--; ) { const className = node2.classList[eIndex]; if (regex.test(className)) { return true; } } if (!checkAncestors) return false; return classMatchesRegex(index$1.parentNode(node2), regex, checkAncestors); } function needMaskingText(node2, maskTextClass, maskTextSelector, checkAncestors) { let el; if (isElement(node2)) { el = node2; if (!index$1.childNodes(el).length) { return false; } } else if (index$1.parentElement(node2) === null) { return false; } else { el = index$1.parentElement(node2); } try { if (typeof maskTextClass === "string") { if (checkAncestors) { if (el.closest(`.${maskTextClass}`)) return true; } else { if (el.classList.contains(maskTextClass)) return true; } } else { if (classMatchesRegex(el, maskTextClass, checkAncestors)) return true; } if (maskTextSelector) { if (checkAncestors) { if (el.closest(maskTextSelector)) return true; } else { if (el.matches(maskTextSelector)) return true; } } } catch (e2) { } return false; } function onceIframeLoaded(iframeEl, listener, iframeLoadTimeout) { const win = iframeEl.contentWindow; if (!win) { return; } let fired = false; let readyState; try { readyState = win.document.readyState; } catch (error) { return; } if (readyState !== "complete") { const timer = setTimeout(() => { if (!fired) { listener(); fired = true; } }, iframeLoadTimeout); iframeEl.addEventListener("load", () => { clearTimeout(timer); fired = true; listener(); }); return; } const blankUrl = "about:blank"; if (win.location.href !== blankUrl || iframeEl.src === blankUrl || iframeEl.src === "") { setTimeout(listener, 0); return iframeEl.addEventListener("load", listener); } iframeEl.addEventListener("load", listener); } function onceStylesheetLoaded(link, listener, styleSheetLoadTimeout) { let fired = false; let styleSheetLoaded; try { styleSheetLoaded = link.sheet; } catch (error) { return; } if (styleSheetLoaded) return; const timer = setTimeout(() => { if (!fired) { listener(); fired = true; } }, styleSheetLoadTimeout); link.addEventListener("load", () => { clearTimeout(timer); fired = true; listener(); }); } function serializeNode(n2, options) { const { doc, mirror: mirror2, blockClass, blockSelector, needsMask, inlineStylesheet, maskInputOptions = {}, maskTextFn, maskInputFn, dataURLOptions = {}, inlineImages, recordCanvas, keepIframeSrcFn, newlyAddedElement = false } = options; const rootId = getRootId(doc, mirror2); switch (n2.nodeType) { case n2.DOCUMENT_NODE: if (n2.compatMode !== "CSS1Compat") { return { type: NodeType$1$1.Document, childNodes: [], compatMode: n2.compatMode // probably "BackCompat" }; } else { return { type: NodeType$1$1.Document, childNodes: [] }; } case n2.DOCUMENT_TYPE_NODE: return { type: NodeType$1$1.DocumentType, name: n2.name, publicId: n2.publicId, systemId: n2.systemId, rootId }; case n2.ELEMENT_NODE: return serializeElementNode(n2, { doc, blockClass, blockSelector, inlineStylesheet, maskInputOptions, maskInputFn, dataURLOptions, inlineImages, recordCanvas, keepIframeSrcFn, newlyAddedElement, rootId }); case n2.TEXT_NODE: return serializeTextNode(n2, { doc, needsMask, maskTextFn, rootId }); case n2.CDATA_SECTION_NODE: return { type: NodeType$1$1.CDATA, textContent: "", rootId }; case n2.COMMENT_NODE: return { type: NodeType$1$1.Comment, textContent: index$1.textContent(n2) || "", rootId }; default: return false; } } function getRootId(doc, mirror2) { if (!mirror2.hasNode(doc)) return void 0; const docId = mirror2.getId(doc); return docId === 1 ? void 0 : docId; } function serializeTextNode(n2, options) { var _a2; const { needsMask, maskTextFn, rootId } = options; const parent = index$1.parentNode(n2); const parentTagName = parent && parent.tagName; let text = index$1.textContent(n2); const isStyle = parentTagName === "STYLE" ? true : void 0; const isScript = parentTagName === "SCRIPT" ? true : void 0; if (isStyle && text) { try { if (n2.nextSibling || n2.previousSibling) { } else if ((_a2 = parent.sheet) == null ? void 0 : _a2.cssRules) { text = stringifyStylesheet(parent.sheet); } } catch (err) { console.warn( `Cannot get CSS styles from text's parentNode. Error: ${err}`, n2 ); } text = absolutifyURLs(text, getHref(options.doc)); } if (isScript) { text = "SCRIPT_PLACEHOLDER"; } if (!isStyle && !isScript && text && needsMask) { text = maskTextFn ? maskTextFn(text, index$1.parentElement(n2)) : text.replace(/[\S]/g, "*"); } return { type: NodeType$1$1.Text, textContent: text || "", isStyle, rootId }; } function findStylesheet(doc, href) { return Array.from(doc.styleSheets).find((s2) => s2.href === href); } function hrefFrom(n2) { return n2.href; } function serializeElementNode(n2, options) { const { doc, blockClass, blockSelector, inlineStylesheet, maskInputOptions = {}, maskInputFn, dataURLOptions = {}, inlineImages, recordCanvas, keepIframeSrcFn, newlyAddedElement = false, rootId } = options; const needBlock = _isBlockedElement(n2, blockClass, blockSelector); const tagName = getValidTagName$1(n2); let attributes = {}; const len = n2.attributes.length; for (let i2 = 0; i2 < len; i2++) { const attr = n2.attributes[i2]; if (!ignoreAttribute(tagName, attr.name, attr.value)) { attributes[attr.name] = transformAttribute( doc, tagName, toLowerCase(attr.name), attr.value ); } } if (tagName === "link" && inlineStylesheet) { const href = hrefFrom(n2); if (href) { let stylesheet = findStylesheet(doc, href); if (!stylesheet && href.includes(".css")) { const rootDomain = window.location.origin; const stylesheetPath = href.replace(window.location.href, ""); const potentialStylesheetHref = rootDomain + "/" + stylesheetPath; stylesheet = findStylesheet(doc, potentialStylesheetHref); } let cssText = null; if (stylesheet) { cssText = stringifyStylesheet(stylesheet); } if (cssText) { delete attributes.rel; delete attributes.href; attributes._cssText = cssText; } } } if (tagName === "style" && n2.sheet && // TODO: Currently we only try to get dynamic stylesheet when it is an empty style element !(n2.innerText || index$1.textContent(n2) || "").trim().length) { const cssText = stringifyStylesheet( n2.sheet ); if (cssText) { attributes._cssText = cssText; } } if (tagName === "input" || tagName === "textarea" || tagName === "select") { const value = n2.value; const checked = n2.checked; if (attributes.type !== "radio" && attributes.type !== "checkbox" && attributes.type !== "submit" && attributes.type !== "button" && value) { attributes.value = maskInputValue({ element: n2, type: getInputType(n2), tagName, value, maskInputOptions, maskInputFn }); } else if (checked) { attributes.checked = checked; } } if (tagName === "option") { if (n2.selected && !maskInputOptions["select"]) { attributes.selected = true; } else { delete attributes.selected; } } if (tagName === "dialog" && n2.open) { try { attributes.rr_open_mode = n2.matches("dialog:modal") ? "modal" : "non-modal"; } catch { attributes.rr_open_mode = "modal"; attributes.ph_rr_could_not_detect_modal = true; } } if (tagName === "canvas" && recordCanvas) { if (n2.__context === "2d") { if (!is2DCanvasBlank(n2)) { attributes.rr_dataURL = n2.toDataURL( dataURLOptions.type, dataURLOptions.quality ); } } else if (!("__context" in n2)) { const canvasDataURL = n2.toDataURL( dataURLOptions.type, dataURLOptions.quality ); const blankCanvas = doc.createElement("canvas"); blankCanvas.width = n2.width; blankCanvas.height = n2.height; const blankCanvasDataURL = blankCanvas.toDataURL( dataURLOptions.type, dataURLOptions.quality ); if (canvasDataURL !== blankCanvasDataURL) { attributes.rr_dataURL = canvasDataURL; } } } if (tagName === "img" && inlineImages) { if (!canvasService) { canvasService = doc.createElement("canvas"); canvasCtx = canvasService.getContext("2d"); } const image = n2; const imageSrc = image.currentSrc || image.getAttribute("src") || "<unknown-src>"; const priorCrossOrigin = image.crossOrigin; const recordInlineImage = () => { image.removeEventListener("load", recordInlineImage); try { canvasService.width = image.naturalWidth; canvasService.height = image.naturalHeight; canvasCtx.drawImage(image, 0, 0); attributes.rr_dataURL = canvasService.toDataURL( dataURLOptions.type, dataURLOptions.quality ); } catch (err) { if (image.crossOrigin !== "anonymous") { image.crossOrigin = "anonymous"; if (image.complete && image.naturalWidth !== 0) recordInlineImage(); else image.addEventListener("load", recordInlineImage); return; } else { console.warn( `Cannot inline img src=${imageSrc}! Error: ${err}` ); } } if (image.crossOrigin === "anonymous") { priorCrossOrigin ? attributes.crossOrigin = priorCrossOrigin : image.removeAttribute("crossorigin"); } }; if (image.complete && image.naturalWidth !== 0) recordInlineImage(); else image.addEventListener("load", recordInlineImage); } if (tagName === "audio" || tagName === "video") { const mediaAttributes = attributes; mediaAttributes.rr_mediaState = n2.paused ? "paused" : "played"; mediaAttributes.rr_mediaCurrentTime = n2.currentTime; mediaAttributes.rr_mediaPlaybackRate = n2.playbackRate; mediaAttributes.rr_mediaMuted = n2.muted; mediaAttributes.rr_mediaLoop = n2.loop; mediaAttributes.rr_mediaVolume = n2.volume; } if (!newlyAddedElement) { if (n2.scrollLeft) { attributes.rr_scrollLeft = n2.scrollLeft; } if (n2.scrollTop) { attributes.rr_scrollTop = n2.scrollTop; } } if (needBlock) { const { width, height } = n2.getBoundingClientRect(); attributes = { class: attributes.class, rr_width: `${width}px`, rr_height: `${height}px` }; } if (tagName === "iframe" && !keepIframeSrcFn(attributes.src)) { if (!n2.contentDocument) { attributes.rr_src = attributes.src; } delete attributes.src; } let isCustomElement; try { if (customElements.get(tagName)) isCustomElement = true; } catch (e2) { } return { type: NodeType$1$1.Element, tagName, attributes, childNodes: [], isSVG: isSVGElement(n2) || void 0, needBlock, rootId, isCustom: isCustomElement }; } function lowerIfExists(maybeAttr) { if (maybeAttr === void 0 || maybeAttr === null) { return ""; } else { return maybeAttr.toLowerCase(); } } function slimDOMExcluded(sn, slimDOMOptions) { if (slimDOMOptions.comment && sn.type === NodeType$1$1.Comment) { return true; } else if (sn.type === NodeType$1$1.Element) { if (slimDOMOptions.script && // script tag (sn.tagName === "script" || // (module)preload link sn.tagName === "link" && (sn.attributes.rel === "preload" && sn.attributes.as === "script" || sn.attributes.rel === "modulepreload") || // prefetch link sn.tagName === "link" && sn.attributes.rel === "prefetch" && typeof sn.attributes.href === "string" && extractFileExtension(sn.attributes.href) === "js")) { return true; } else if (slimDOMOptions.headFavicon && (sn.tagName === "link" && sn.attributes.rel === "shortcut icon" || sn.tagName === "meta" && (lowerIfExists(sn.attributes.name).match( /^msapplication-tile(image|color)$/ ) || lowerIfExists(sn.attributes.name) === "application-name" || lowerIfExists(sn.attributes.rel) === "icon" || lowerIfExists(sn.attributes.rel) === "apple-touch-icon" || lowerIfExists(sn.attributes.rel) === "shortcut icon"))) { return true; } else if (sn.tagName === "meta") { if (slimDOMOptions.headMetaDescKeywords && lowerIfExists(sn.attributes.name).match(/^description|keywords$/)) { return true; } else if (slimDOMOptions.headMetaSocial && (lowerIfExists(sn.attributes.property).match(/^(og|twitter|fb):/) || // og = opengraph (facebook) lowerIfExists(sn.attributes.name).match(/^(og|twitter):/) || lowerIfExists(sn.attributes.name) === "pinterest")) { return true; } else if (slimDOMOptions.headMetaRobots && (lowerIfExists(sn.attributes.name) === "robots" || lowerIfExists(sn.attributes.name) === "googlebot" || lowerIfExists(sn.attributes.name) === "bingbot")) { return true; } else if (slimDOMOptions.headMetaHttpEquiv && sn.attributes["http-equiv"] !== void 0) { return true; } else if (slimDOMOptions.headMetaAuthorship && (lowerIfExists(sn.attributes.name) === "author" || lowerIfExists(sn.attributes.name) === "generator" || lowerIfExists(sn.attributes.name) === "framework" || lowerIfExists(sn.attributes.name) === "publisher" || lowerIfExists(sn.attributes.name) === "progid" || lowerIfExists(sn.attributes.property).match(/^article:/) || lowerIfExists(sn.attributes.property).match(/^product:/))) { return true; } else if (slimDOMOptions.headMetaVerification && (lowerIfExists(sn.attributes.name) === "google-site-verification" || lowerIfExists(sn.attributes.name) === "yandex-verification" || lowerIfExists(sn.attributes.name) === "csrf-token" || lowerIfExists(sn.attributes.name) === "p:domain_verify" || lowerIfExists(sn.attributes.name) === "verify-v1" || lowerIfExists(sn.attributes.name) === "verification" || lowerIfExists(sn.attributes.name) === "shopify-checkout-api-token")) { return true; } } } return false; } function serializeNodeWithId(n2, options) { const { doc, mirror: mirror2, blockClass, blockSelector, maskTextClass, maskTextSelector, skipChild = false, inlineStylesheet = true, maskInputOptions = {}, maskTextFn, maskInputFn, slimDOMOptions, dataURLOptions = {}, inlineImages = false, recordCanvas = false, onSerialize, onIframeLoad, iframeLoadTimeout = 5e3, onStylesheetLoad, stylesheetLoadTimeout = 5e3, keepIframeSrcFn = () => false, newlyAddedElement = false } = options; let { needsMask } = options; let { preserveWhiteSpace = true } = options; if (!needsMask) { const checkAncestors = needsMask === void 0; needsMask = needMaskingText( n2, maskTextClass, maskTextSelector, checkAncestors ); } const _serializedNode = serializeNode(n2, { doc, mirror: mirror2, blockClass, blockSelector, needsMask, inlineStylesheet, maskInputOptions, maskTextFn, maskInputFn, dataURLOptions, inlineImages, recordCanvas, keepIframeSrcFn, newlyAddedElement }); if (!_serializedNode) { console.warn(n2, "not serialized"); return null; } let id; if (mirror2.hasNode(n2)) { id = mirror2.getId(n2); } else if (slimDOMExcluded(_serializedNode, slimDOMOptions) || !preserveWhiteSpace && _serializedNode.type === NodeType$1$1.Text && !_serializedNode.isStyle && !_serializedNode.textContent.replace(/^\s+|\s+$/gm, "").length) { id = IGNORED_NODE; } else { id = genId(); } const serializedNode = Object.assign(_serializedNode, { id }); mirror2.add(n2, serializedNode); if (id === IGNORED_NODE) { return null; } if (onSerialize) { onSerialize(n2); } let recordChild = !skipChild; if (serializedNode.type === NodeType$1$1.Element) { recordChild = recordChild && !serializedNode.needBlock; delete serializedNode.needBlock; const shadowRootEl = index$1.shadowRoot(n2); if (shadowRootEl && isNativeShadowDom(shadowRootEl)) serializedNode.isShadowHost = true; } if ((serializedNode.type === NodeType$1$1.Document || serializedNode.type === NodeType$1$1.Element) && recordChild) { if (slimDOMOptions.headWhitespace && serializedNode.type === NodeType$1$1.Element && serializedNode.tagName === "head") { preserveWhiteSpace = false; } const bypassOptions = { doc, mirror: mirror2, blockClass, blockSelector, needsMask, maskTextClass, maskTextSelector, skipChild, inlineStylesheet, maskInputOptions, maskTextFn, maskInputFn, slimDOMOptions, dataURLOptions, inlineImages, recordCanvas, preserveWhiteSpace, onSerialize, onIframeLoad, iframeLoadTimeout, onStylesheetLoad, stylesheetLoadTimeout, keepIframeSrcFn }; if (serializedNode.type === NodeType$1$1.Element && serializedNode.tagName === "textarea" && serializedNode.attributes.value !== void 0) ; else { for (const childN of Array.from(index$1.childNodes(n2))) { const serializedChildNode = serializeNodeWithId(childN, bypassOptions); if (serializedChildNode) { serializedNode.childNodes.push(serializedChildNode); } } } let shadowRootEl = null; if (isElement(n2) && (shadowRootEl = index$1.shadowRoot(n2))) { for (const childN of Array.from(index$1.childNodes(shadowRootEl))) { const serializedChildNode = serializeNodeWithId(childN, bypassOptions); if (serializedChildNode) { isNativeShadowDom(shadowRootEl) && (serializedChildNode.isShadow = true); serializedNode.childNodes.push(serializedChildNode); } } } } const parent = index$1.parentNode(n2); if (parent && isShadowRoot(parent) && isNativeShadowDom(parent)) { serializedNode.isShadow = true; } if (serializedNode.type === NodeType$1$1.Element && serializedNode.tagName === "iframe") { onceIframeLoaded( n2, () => { const iframeDoc = n2.contentDocument; if (iframeDoc && onIframeLoad) { const serializedIframeNode = serializeNodeWithId(iframeDoc, { doc: iframeDoc, mirror: mirror2, blockClass, blockSelector, needsMask, maskTextClass, maskTextSelector, skipChild: false, inlineStylesheet, maskInputOptions, maskTextFn, maskInputFn, slimDOMOptions, dataURLOptions, inlineImages, recordCanvas, preserveWhiteSpace, onSerialize, onIframeLoad, iframeLoadTimeout, onStylesheetLoad, stylesheetLoadTimeout, keepIframeSrcFn }); if (serializedIframeNode) { onIframeLoad( n2, serializedIframeNode ); } } }, iframeLoadTimeout ); } if (serializedNode.type === NodeType$1$1.Element && serializedNode.tagName === "link" && typeof serializedNode.attributes.rel === "string" && (serializedNode.attributes.rel === "stylesheet" || serializedNode.attributes.rel === "preload" && typeof serializedNode.attributes.href === "string" && extractFileExtension(serializedNode.attributes.href) === "css")) { onceStylesheetLoaded( n2, () => { if (onStylesheetLoad) { const serializedLinkNode = serializeNodeWithId(n2, { doc, mirror: mirror2, blockClass, blockSelector, needsMask, maskTextClass, maskTextSelector, skipChild: false, inlineStylesheet, maskInputOptions, maskTextFn, maskInputFn, slimDOMOptions, dataURLOptions, inlineImages, recordCanvas, preserveWhiteSpace, onSerialize, onIframeLoad, iframeLoadTimeout, onStylesheetLoad, stylesheetLoadTimeout, keepIframeSrcFn }); if (serializedLinkNode) { onStylesheetLoad( n2, serializedLinkNode ); } } }, stylesheetLoadTimeout ); } return serializedNode; } function snapshot(n2, options) { const { mirror: mirror2 = new Mirror(), blockClass = "rr-block", blockSelector = null, maskTextClass = "rr-mask", maskTextSelector = null, inlineStylesheet = true, inlineImages = false, recordCanvas = false, maskAllInputs = false, maskTextFn, maskInputFn, slimDOM = false, dataURLOptions, preserveWhiteSpace, onSerialize, onIframeLoad, iframeLoadTimeout, onStylesheetLoad, stylesheetLoadTimeout, keepIframeSrcFn = () => false } = options || {}; const maskInputOptions = maskAllInputs === true ? { color: true, date: true, "datetime-local": true, email: true, month: true, number: true, range: true, search: true, tel: true, text: true, time: true, url: true, week: true, textarea: true, select: true, password: true } : maskAllInputs === false ? { password: true } : maskAllInputs; const slimDOMOptions = slimDOM === true || slimDOM === "all" ? ( // if true: set of sensible options that should not throw away any information { script: true, comment: true, headFavicon: true, headWhitespace: true, headMetaDescKeywords: slimDOM === "all", // destructive headMetaSocial: true, headMetaRobots: true, headMetaHttpEquiv: true, headMetaAuthorship: true, headMetaVerification: true } ) : slimDOM === false ? {} : slimDOM; return serializeNodeWithId(n2, { doc: n2, mirror: mirror2, blockClass, blockSelector, maskTextClass, maskTextSelector, skipChild: false, inlineStylesheet, maskInputOptions, maskTextFn, maskInputFn, slimDOMOptions, dataURLOptions, inlineImages, recordCanvas, preserveWhiteSpace, onSerialize, onIframeLoad, iframeLoadTimeout, onStylesheetLoad, stylesheetLoadTimeout, keepIframeSrcFn, newlyAddedElement: false }); } const MEDIA_SELECTOR = /(max|min)-device-(width|height)/; const MEDIA_SELECTOR_GLOBAL = new RegExp(MEDIA_SELECTOR.source, "g"); const mediaSelectorPlugin = { postcssPlugin: "postcss-custom-selectors", prepare() { return { postcssPlugin: "postcss-custom-selectors", AtRule: function(atrule) { if (atrule.params.match(MEDIA_SELECTOR_GLOBAL)) { atrule.params = atrule.params.replace(MEDIA_SELECTOR_GLOBAL, "$1-$2"); } } }; } }; const pseudoClassPlugin = { postcssPlugin: "postcss-hover-classes", prepare: function() { const fixed = []; return { Rule: function(rule2) { if (fixed.indexOf(rule2) !== -1) { return; } fixed.push(rule2); rule2.selectors.forEach(function(selector) { if (selector.includes(":hover")) { rule2.selector += ",\n" + selector.replace(/:hover/g, ".\\:hover"); } }); } }; } }; function getDefaultExportFromCjs$1(x) { return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, "default") ? x["default"] : x; } function getAugmentedNamespace$1(n2) { if (n2.__esModule) return n2; var f2 = n2.default; if (typeof f2 == "function") { var a2 = function a22() { if (this instanceof a22) { return Reflect.construct(f2, arguments, this.constructor); } return f2.apply(this, arguments); }; a2.prototype = f2.prototype; } else a2 = {}; Object.defineProperty(a2, "__esModule", { value: true }); Object.keys(n2).forEach(function(k) { var d = Object.getOwnPropertyDescriptor(n2, k); Object.defineProperty(a2, k, d.get ? d : { enumerable: true, get: function() { return n2[k]; } }); }); return a2; } var picocolors_browser$1 = { exports: {} }; var hasRequiredPicocolors_browser$1; function requirePicocolors_browser$1() { if (hasRequiredPicocolors_browser$1) return picocolors_browser$1.exports; hasRequiredPicocolors_browser$1 = 1; var x = String; var create = function() { return { isColorSupported: false, reset: x, bold: x, dim: x, italic: x, underline: x, inverse: x, hidden: x, strikethrough: x, black: x, red: x, green: x, yellow: x, blue: x, magenta: x, cyan: x, white: x, gray: x, bgBlack: x, bgRed: x, bgGreen: x, bgYellow: x, bgBlue: x, bgMagenta: x, bgCyan: x, bgWhite: x, blackBright: x, redBright: x, greenBright: x, yellowBright: x, blueBright: x, magentaBright: x, cyanBright: x, whiteBright: x, bgBlackBright: x, bgRedBright: x, bgGreenBright: x, bgYellowBright: x, bgBlueBright: x, bgMagentaBright: x, bgCyanBright: x, bgWhiteBright: x }; }; picocolors_browser$1.exports = create(); picocolors_browser$1.exports.createColors = create; return picocolors_browser$1.exports; } const __viteBrowserExternal$2 = {}; const __viteBrowserExternal$1$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: __viteBrowserExternal$2 }, Symbol.toStringTag, { value: "Module" })); const require$$2$1 = /* @__PURE__ */ getAugmentedNamespace$1(__viteBrowserExternal$1$1); var cssSyntaxError$1; var hasRequiredCssSyntaxError$1; function requireCssSyntaxError$1() { if (hasRequiredCssSyntaxError$1) return cssSyntaxError$1; hasRequiredCssSyntaxError$1 = 1; let pico = /* @__PURE__ */ requirePicocolors_browser$1(); let terminalHighlight = require$$2$1; class CssSyntaxError extends Error { constructor(message, line, column, source, file, plugin) { super(message); this.name = "CssSyntaxError"; this.reason = message; if (file) { this.file = file; } if (source) { this.source = source; } if (plugin) { this.plugin = plugin; } if (typeof line !== "undefined" && typeof column !== "undefined") { if (typeof line === "number") { this.line = line; this.column = column; } else { this.line = line.line; this.column = line.column; this.endLine = column.line; this.endColumn = column.column; } } this.setMessage(); if (Error.captureStackTrace) { Error.captureStackTrace(this, CssSyntaxError); } } setMessage() { this.message = this.plugin ? this.plugin + ": " : ""; this.message += this.file ? this.file : "<css input>"; if (typeof this.line !== "undefined") { this.message += ":" + this.line + ":" + this.column; } this.message += ": " + this.reason; } showSourceCode(color) { if (!this.source) return ""; let css = this.source; if (color == null) color = pico.isColorSupported; let aside = (text) => text; let mark = (text) => text; let highlight = (text) => text; if (color) { let { bold, gray, red } = pico.createColors(true); mark = (text) => bold(red(text)); aside = (text) => gray(text); if (terminalHighlight) { highlight = (text) => terminalHighlight(text); } } let lines = css.split(/\r?\n/); let start = Math.max(this.line - 3, 0); let end = Math.min(this.line + 2, lines.length); let maxWidth = String(end).length; return lines.slice(start, end).map((line, index2) => { let number = start + 1 + index2; let gutter = " " + (" " + number).slice(-maxWidth) + " | "; if (number === this.line) { if (line.length > 160) { let padding = 20; let subLineStart = Math.max(0, this.column - padding); let subLineEnd = Math.max( this.column + padding, this.endColumn + padding ); let subLine = line.slice(subLineStart, subLineEnd); let spacing2 = aside(gutter.replace(/\d/g, " ")) + line.slice(0, Math.min(this.column - 1, padding - 1)).replace(/[^\t]/g, " "); return mark(">") + aside(gutter) + highlight(subLine) + "\n " + spacing2 + mark("^"); } let spacing = aside(gutter.replace(/\d/g, " ")) + line.slice(0, this.column - 1).replace(/[^\t]/g, " "); return mark(">") + aside(gutter) + highlight(line) + "\n " + spacing + mark("^"); } return " " + aside(gutter) + highlight(line); }).join("\n"); } toString() { let code = this.showSourceCode(); if (code) { code = "\n\n" + code + "\n"; } return this.name + ": " + this.message + code; } } cssSyntaxError$1 = CssSyntaxError; CssSyntaxError.default = CssSyntaxError; return cssSyntaxError$1; } var stringifier$1; var hasRequ