humanbehavior-js
Version:
SDK for HumanBehavior session and event recording
1,565 lines (1,557 loc) • 471 kB
JavaScript
'use strict';
var React = require('react');
/******************************************************************************
Copyright (c) Microsoft Corporation.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */
/* global Reflect, Promise, SuppressedError, Symbol, Iterator */
function __awaiter(thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
}
typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
var e = new Error(message);
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
};
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$3 = /* @__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$3 || {});
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 = {};
const isAngularZonePresent$1 = () => {
return !!globalThis.Zone;
};
function getUntaintedPrototype$1(key) {
if (untaintedBasePrototype$1[key])
return untaintedBasePrototype$1[key];
const defaultObj = globalThis[key];
const defaultPrototype = defaultObj.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 && !isAngularZonePresent$1()) {
untaintedBasePrototype$1[key] = defaultObj.prototype;
return defaultObj.prototype;
}
try {
const iframeEl = document.createElement("iframe");
document.body.appendChild(iframeEl);
const win = iframeEl.contentWindow;
if (!win) return defaultObj.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;
}
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
};
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.location.href;
}
const stringifiedRules = Array.from(
rules2,
(rule2) => stringifyRule(rule2, sheetHref)
).join("");
return fixBrowserCompatibilityIssuesInCSS(stringifiedRules);
} catch (error) {
return null;
}
}
function stringifyRule(rule2, sheetHref) {
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;
}
if (rule2.styleSheet.href) {
return absolutifyURLs(importStringified, rule2.styleSheet.href);
}
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 x2 = 0; x2 < canvas.width; x2 += 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,
x2,
y,
Math.min(chunkSize, canvas.width - x2),
Math.min(chunkSize, canvas.height - y)
).data.buffer
);
if (pixelBuffer.some((pixel) => pixel !== 0)) return false;
}
}
return true;
}
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})`;
}
);
}
function normalizeCssString(cssText) {
return cssText.replace(/(\/\*[^*]*\*\/)|[\s;]/g, "");
}
function splitCssText(cssText, style) {
const childNodes2 = Array.from(style.childNodes);
const splits = [];
if (childNodes2.length > 1 && cssText && typeof cssText === "string") {
const cssTextNorm = normalizeCssString(cssText);
for (let i2 = 1; i2 < childNodes2.length; i2++) {
if (childNodes2[i2].textContent && typeof childNodes2[i2].textContent === "string") {
const textContentNorm = normalizeCssString(childNodes2[i2].textContent);
for (let j = 3; j < textContentNorm.length; j++) {
const bit = textContentNorm.substring(0, j);
if (cssTextNorm.split(bit).length === 2) {
const splitNorm = cssTextNorm.indexOf(bit);
for (let k = splitNorm; k < cssText.length; k++) {
if (normalizeCssString(cssText.substring(0, k)).length === splitNorm) {
splits.push(cssText.substring(0, k));
cssText = cssText.substring(k);
break;
}
}
break;
}
}
}
}
}
splits.push(cssText);
return splits;
}
function markCssSplits(cssText, style) {
return splitCssText(cssText, style).join("/* rr_split */");
}
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,
cssCaptured = false
} = options;
const rootId = getRootId(doc, mirror2);
switch (n2.nodeType) {
case n2.DOCUMENT_NODE:
if (n2.compatMode !== "CSS1Compat") {
return {
type: NodeType$3.Document,
childNodes: [],
compatMode: n2.compatMode
// probably "BackCompat"
};
} else {
return {
type: NodeType$3.Document,
childNodes: []
};
}
case n2.DOCUMENT_TYPE_NODE:
return {
type: NodeType$3.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,
cssCaptured
});
case n2.CDATA_SECTION_NODE:
return {
type: NodeType$3.CDATA,
textContent: "",
rootId
};
case n2.COMMENT_NODE:
return {
type: NodeType$3.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) {
const { needsMask, maskTextFn, rootId, cssCaptured } = options;
const parent = index$1.parentNode(n2);
const parentTagName = parent && parent.tagName;
let textContent2 = "";
const isStyle = parentTagName === "STYLE" ? true : void 0;
const isScript = parentTagName === "SCRIPT" ? true : void 0;
if (isScript) {
textContent2 = "SCRIPT_PLACEHOLDER";
} else if (!cssCaptured) {
textContent2 = index$1.textContent(n2);
if (isStyle && textContent2) {
textContent2 = absolutifyURLs(textContent2, getHref(options.doc));
}
}
if (!isStyle && !isScript && textContent2 && needsMask) {
textContent2 = maskTextFn ? maskTextFn(textContent2, index$1.parentElement(n2)) : textContent2.replace(/[\S]/g, "*");
}
return {
type: NodeType$3.Text,
textContent: textContent2 || "",
rootId
};
}
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 stylesheet = Array.from(doc.styleSheets).find((s2) => {
return s2.href === n2.href;
});
let cssText = null;
if (stylesheet) {
cssText = stringifyStylesheet(stylesheet);
}
if (cssText) {
delete attributes.rel;
delete attributes.href;
attributes._cssText = cssText;
}
}
if (tagName === "style" && n2.sheet) {
let cssText = stringifyStylesheet(
n2.sheet
);
if (cssText) {
if (n2.childNodes.length > 1) {
cssText = markCssSplits(cssText, n2);
}
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) {
attributes.rr_open_mode = n2.matches("dialog:modal") ? "modal" : "non-modal";
}
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$3.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$3.Comment) {
return true;
} else if (sn.type === NodeType$3.Element) {
if (slimDOMOptions.script && // script tag
(sn.tagName === "script" || // (module)preload link
sn.tagName === "link" && (sn.attributes.rel === "preload" || sn.attributes.rel === "modulepreload") && sn.attributes.as === "script" || // 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,
cssCaptured = 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,
cssCaptured
});
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$3.Text && !_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$3.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$3.Document || serializedNode.type === NodeType$3.Element) && recordChild) {
if (slimDOMOptions.headWhitespace && serializedNode.type === NodeType$3.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,
cssCaptured: false
};
if (serializedNode.type === NodeType$3.Element && serializedNode.tagName === "textarea" && serializedNode.attributes.value !== void 0) ;
else {
if (serializedNode.type === NodeType$3.Element && serializedNode.attributes._cssText !== void 0 && typeof serializedNode.attributes._cssText === "string") {
bypassOptions.cssCaptured = true;
}
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$3.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$3.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
});
}
function getDefaultExportFromCjs$1(x2) {
return x2 && x2.__esModule && Object.prototype.hasOwnProperty.call(x2, "default") ? x2["default"] : x2;
}
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 x$1 = String;
var create$1 = function() {
return { isColorSupported: false, reset: x$1, bold: x$1, dim: x$1, italic: x$1, underline: x$1, inverse: x$1, hidden: x$1, strikethrough: x$1, black: x$1, red: x$1, green: x$1, yellow: x$1, blue: x$1, magenta: x$1, cyan: x$1, white: x$1, gray: x$1, bgBlack: x$1, bgRed: x$1, bgGreen: x$1, bgYellow: x$1, bgBlue: x$1, bgMagenta: x$1, bgCyan: x$1, bgWhite: x$1 };
};
picocolors_browser$1.exports = create$1();
picocolors_browser$1.exports.createColors = create$1;
var picocolors_browserExports$1 = 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);
let pico$1 = picocolors_browserExports$1;
let terminalHighlight$1$1 = require$$2$1;
let CssSyntaxError$3$1 = class CssSyntaxError extends Error {
constructor(message, line, column, source, file, plugin22) {
super(message);
this.name = "CssSyntaxError";
this.reason = message;
if (file) {
this.file = file;
}
if (source) {
this.source = source;
}
if (plugin22) {
this.plugin = plugin22;
}
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$1.isColorSupported;
if (terminalHighlight$1$1) {
if (color) css = terminalHighlight$1$1(css);
}
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;
let mark, aside;
if (color) {
let { bold, gray, red } = pico$1.createColors(true);
mark = (text) => bold(red(text));
aside = (text) => gray(text);
} else {
mark = aside = (str) => str;
}
return lines.slice(start, end).map((line, index2) => {
let number = start + 1 + index2;
let gutter = " " + (" " + number).slice(-maxWidth) + " | ";
if (number === this.line) {
let spacing = aside(gutter.replace(/\d/g, " ")) + line.slice(0, this.column - 1).replace(/[^\t]/g, " ");
return mark(">") + aside(gutter) + line + "\n " + spacing + mark("^");
}
return " " + aside(gutter) + line;
}).join("\n");
}
toString() {
let code = this.showSourceCode();
if (code) {
code = "\n\n" + code + "\n";
}
return this.name + ": " + this.message + code;
}
};
var cssSyntaxError$1 = CssSyntaxError$3$1;
CssSyntaxError$3$1.default = CssSyntaxError$3$1;
var symbols$1 = {};
symbols$1.isClean = Symbol("isClean");
symbols$1.my = Symbol("my");
const DEFAULT_RAW$1 = {
after: "\n",
beforeClose: "\n",
beforeComment: "\n",
beforeDecl: "\n",
beforeOpen: " ",
beforeRule: "\n",
colon: ": ",
commentLeft: " ",
commentRight: " ",
emptyBody: "",
indent: " ",
semicolon: false
};
function capitalize$1(str) {
return str[0].toUpperCase() + str.slice(1);
}
let Stringifier$2$1 = class Stringifier {
constructor(builder) {
this.builder = builder;
}
atrule(node2, semicolon) {
let name = "@" + node2.name;
let params = node2.params ? this.rawValue(node2, "params") : "";
if (typeof node2.raws.afterName !== "undefined") {
name += node2.raws.afterName;
} else if (params) {
name += " ";
}
if (node2.nodes) {
this.block(node2, name + params);
} else {
let end = (node2.raws.between || "") + (semicolon ? ";" : "");
this.builder(name + params + end, node2);
}
}
beforeAfter(node2, detect) {
let value;
if (node2.type === "decl") {
value = this.raw(node2, null, "beforeDecl");
} else if (node2.type === "comment") {
value = this.raw(node2, null, "beforeComment");
} else if (detect === "before") {
value = this.raw(node2, null, "beforeRule");
} else {
value = this.raw(node2, null, "beforeClose");
}
let buf = node2.parent;
let depth = 0;
while (buf && buf.type !== "root") {
depth += 1;
buf = buf.parent;
}
if (value.includes("\n")) {
let indent = this.raw(n