"// @applitools/[email protected]\nfunction __processPageAndPoll() {\n var processPageAndPoll = (function () {\n 'use strict';\n\n // This code was copied and modified from https://github.com/beatgammit/base64-js/blob/bf68aaa277/index.js\n // License: https://github.com/beatgammit/base64-js/blob/bf68aaa277d9de7007cc0c58279c411bb10670ac/LICENSE\n\n function arrayBufferToBase64(ab) {\n const lookup = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'.split('');\n\n const uint8 = new Uint8Array(ab);\n const len = uint8.length;\n const extraBytes = len % 3; // if we have 1 byte left, pad 2 bytes\n const parts = [];\n const maxChunkLength = 16383; // must be multiple of 3\n\n let tmp;\n\n // go through the array every three bytes, we'll deal with trailing stuff later\n for (let i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) {\n parts.push(encodeChunk(i, i + maxChunkLength > len2 ? len2 : i + maxChunkLength));\n }\n\n // pad the end with zeros, but make sure to not forget the extra bytes\n if (extraBytes === 1) {\n tmp = uint8[len - 1];\n parts.push(lookup[tmp >> 2] + lookup[(tmp << 4) & 0x3f] + '==');\n } else if (extraBytes === 2) {\n tmp = (uint8[len - 2] << 8) + uint8[len - 1];\n parts.push(lookup[tmp >> 10] + lookup[(tmp >> 4) & 0x3f] + lookup[(tmp << 2) & 0x3f] + '=');\n }\n\n return parts.join('');\n\n function tripletToBase64(num) {\n return (\n lookup[(num >> 18) & 0x3f] +\n lookup[(num >> 12) & 0x3f] +\n lookup[(num >> 6) & 0x3f] +\n lookup[num & 0x3f]\n );\n }\n\n function encodeChunk(start, end) {\n let tmp;\n const output = [];\n for (let i = start; i < end; i += 3) {\n tmp = ((uint8[i] << 16) & 0xff0000) + ((uint8[i + 1] << 8) & 0xff00) + (uint8[i + 2] & 0xff);\n output.push(tripletToBase64(tmp));\n }\n return output.join('');\n }\n }\n\n var arrayBufferToBase64_1 = arrayBufferToBase64;\n\n function extractLinks(doc = document) {\n const srcsetUrls = [...doc.querySelectorAll('img[srcset],source[srcset]')]\n .map(srcsetEl =>\n srcsetEl\n .getAttribute('srcset')\n .split(',')\n .map(str => str.trim().split(/\\s+/)[0]),\n )\n .reduce((acc, urls) => acc.concat(urls), []);\n\n const srcUrls = [...doc.querySelectorAll('img[src],source[src]')].map(srcEl =>\n srcEl.getAttribute('src'),\n );\n\n const hrefUrls = [...doc.querySelectorAll('image')]\n .map(hrefEl => hrefEl.getAttribute('href') || hrefEl.getAttribute('xlink:href'))\n .filter(Boolean);\n\n const cssUrls = [...doc.querySelectorAll('link[rel=\"stylesheet\"]')].map(link =>\n link.getAttribute('href'),\n );\n\n const videoPosterUrls = [...doc.querySelectorAll('video[poster]')].map(videoEl =>\n videoEl.getAttribute('poster'),\n );\n\n return [...srcsetUrls, ...srcUrls, ...hrefUrls, ...cssUrls, ...videoPosterUrls];\n }\n\n var extractLinks_1 = extractLinks;\n\n /* eslint-disable no-use-before-define */\n\n function domNodesToCdt(docNode) {\n const NODE_TYPES = {\n ELEMENT: 1,\n TEXT: 3,\n DOCUMENT: 9,\n DOCUMENT_TYPE: 10,\n DOCUMENT_FRAGMENT_NODE: 11,\n };\n\n const domNodes = [\n {\n nodeType: NODE_TYPES.DOCUMENT,\n },\n ];\n domNodes[0].childNodeIndexes = childrenFactory(domNodes, docNode.childNodes);\n return domNodes;\n\n function childrenFactory(domNodes, elementNodes) {\n if (!elementNodes || elementNodes.length === 0) return null;\n\n const childIndexes = [];\n elementNodes.forEach(elementNode => {\n const index = elementNodeFactory(domNodes, elementNode);\n if (index !== null) {\n childIndexes.push(index);\n }\n });\n\n return childIndexes;\n }\n\n function elementNodeFactory(domNodes, elementNode) {\n let node, manualChildNodeIndexes;\n const {nodeType} = elementNode;\n if ([NODE_TYPES.ELEMENT, NODE_TYPES.DOCUMENT_FRAGMENT_NODE].includes(nodeType)) {\n if (elementNode.nodeName !== 'SCRIPT') {\n if (\n elementNode.nodeName === 'STYLE' &&\n elementNode.sheet &&\n elementNode.sheet.cssRules.length\n ) {\n domNodes.push({\n nodeType: NODE_TYPES.TEXT,\n nodeValue: [...elementNode.sheet.cssRules].map(rule => rule.cssText).join(''),\n });\n manualChildNodeIndexes = [domNodes.length - 1];\n }\n\n node = {\n nodeType: nodeType,\n nodeName: elementNode.nodeName,\n attributes: nodeAttributes(elementNode).map(key => {\n let value = elementNode.attributes[key].value;\n const name = elementNode.attributes[key].localName;\n\n if (/^blob:/.test(value)) {\n value = value.replace(/^blob:/, '');\n } else if (\n elementNode.nodeName === 'IFRAME' &&\n name === 'src' &&\n !elementNode.contentDocument &&\n !value.match(/^\\s*data:/)\n ) {\n value = '';\n }\n return {\n name,\n value,\n };\n }),\n childNodeIndexes:\n manualChildNodeIndexes ||\n (elementNode.childNodes.length\n ? childrenFactory(domNodes, elementNode.childNodes)\n : []),\n };\n\n if (elementNode.shadowRoot) {\n node.shadowRootIndex = elementNodeFactory(domNodes, elementNode.shadowRoot);\n }\n\n if (elementNode.checked && !elementNode.attributes.checked) {\n node.attributes.push({name: 'checked', value: 'checked'});\n }\n if (\n elementNode.value !== undefined &&\n elementNode.attributes.value === undefined &&\n elementNode.tagName === 'INPUT'\n ) {\n node.attributes.push({name: 'value', value: elementNode.value});\n }\n } else {\n node = {\n nodeType: NODE_TYPES.ELEMENT,\n nodeName: 'SCRIPT',\n attributes: nodeAttributes(elementNode)\n .map(key => ({\n name: elementNode.attributes[key].localName,\n value: elementNode.attributes[key].value,\n }))\n .filter(attr => attr.name !== 'src'),\n childNodeIndexes: [],\n };\n }\n } else if (nodeType === NODE_TYPES.TEXT) {\n node = {\n nodeType: NODE_TYPES.TEXT,\n nodeValue: elementNode.nodeValue,\n };\n } else if (nodeType === NODE_TYPES.DOCUMENT_TYPE) {\n node = {\n nodeType: NODE_TYPES.DOCUMENT_TYPE,\n nodeName: elementNode.nodeName,\n };\n }\n\n if (node) {\n domNodes.push(node);\n return domNodes.length - 1;\n } else {\n // console.log(`Unknown nodeType: ${nodeType}`);\n return null;\n }\n\n function nodeAttributes({attributes = {}}) {\n return Object.keys(attributes).filter(k => attributes[k].localName);\n }\n }\n }\n\n var domNodesToCdt_1 = domNodesToCdt;\n var NODE_TYPES = {\n ELEMENT: 1,\n TEXT: 3,\n DOCUMENT: 9,\n DOCUMENT_TYPE: 10,\n };\n domNodesToCdt_1.NODE_TYPES = NODE_TYPES;\n\n function extractFrames(doc = document) {\n return [...doc.querySelectorAll('iframe[src]:not([src=\"\"])')]\n .map(srcEl => {\n try {\n const contentDoc = srcEl.contentDocument;\n return (\n contentDoc &&\n /^https?:$/.test(contentDoc.location.protocol) &&\n contentDoc.defaultView &&\n contentDoc.defaultView.frameElement &&\n contentDoc\n );\n } catch (err) {\n //for CORS frames\n }\n })\n .filter(x => !!x);\n }\n\n var extractFrames_1 = extractFrames;\n\n function uniq(arr) {\n const result = [];\n new Set(arr).forEach(v => v && result.push(v));\n return result;\n }\n\n var uniq_1 = uniq;\n\n function aggregateResourceUrlsAndBlobs(resourceUrlsAndBlobsArr) {\n return resourceUrlsAndBlobsArr.reduce(\n ({resourceUrls: allResourceUrls, blobsObj: allBlobsObj}, {resourceUrls, blobsObj}) => ({\n resourceUrls: uniq_1(allResourceUrls.concat(resourceUrls)),\n blobsObj: Object.assign(allBlobsObj, blobsObj),\n }),\n {resourceUrls: [], blobsObj: {}},\n );\n }\n\n var aggregateResourceUrlsAndBlobs_1 = aggregateResourceUrlsAndBlobs;\n\n function makeGetResourceUrlsAndBlobs({processResource, aggregateResourceUrlsAndBlobs}) {\n return function getResourceUrlsAndBlobs(doc, baseUrl, urls) {\n return Promise.all(\n urls.map(url => processResource(url, doc, baseUrl, getResourceUrlsAndBlobs.bind(null, doc))),\n ).then(resourceUrlsAndBlobsArr => aggregateResourceUrlsAndBlobs(resourceUrlsAndBlobsArr));\n };\n }\n\n var getResourceUrlsAndBlobs = makeGetResourceUrlsAndBlobs;\n\n function filterInlineUrl(absoluteUrl) {\n return /^(blob|https?):/.test(absoluteUrl);\n }\n\n var filterInlineUrl_1 = filterInlineUrl;\n\n function absolutizeUrl(url, absoluteUrl) {\n return new URL(url, absoluteUrl).href;\n }\n\n var absolutizeUrl_1 = absolutizeUrl;\n\n function makeProcessResource({\n fetchUrl,\n findStyleSheetByUrl,\n extractResourcesFromStyleSheet,\n isSameOrigin,\n cache = {},\n }) {\n return function processResource(absoluteUrl, doc, baseUrl, getResourceUrlsAndBlobs) {\n return cache[absoluteUrl] || (cache[absoluteUrl] = doProcessResource(absoluteUrl));\n\n function doProcessResource(url) {\n return fetchUrl(url)\n .catch(e => {\n if (probablyCORS(e, url)) {\n return {probablyCORS: true, url};\n } else {\n throw e;\n }\n })\n .then(({url, type, value, probablyCORS}) => {\n if (probablyCORS) {\n return {resourceUrls: [url]};\n }\n const result = {blobsObj: {[url]: {type, value}}};\n if (/text\\/css/.test(type)) {\n const styleSheet = findStyleSheetByUrl(url, doc);\n if (!styleSheet) {\n return result;\n }\n const resourceUrls = extractResourcesFromStyleSheet(styleSheet, doc.defaultView)\n .map(resourceUrl => absolutizeUrl_1(resourceUrl, url.replace(/^blob:/, '')))\n .filter(filterInlineUrl_1);\n return getResourceUrlsAndBlobs(baseUrl, resourceUrls).then(\n ({resourceUrls, blobsObj}) => ({\n resourceUrls,\n blobsObj: Object.assign(blobsObj, {[url]: {type, value}}),\n }),\n );\n } else {\n return result;\n }\n })\n .catch(err => {\n console.log('[dom-snapshot] error while fetching', url, err);\n return {};\n });\n }\n\n function probablyCORS(err, url) {\n const msgCORS = err.message && err.message.includes('Failed to fetch');\n const nameCORS = err.name && err.name.includes('TypeError');\n return msgCORS && nameCORS && !isSameOrigin(url, baseUrl);\n }\n };\n }\n\n var processResource = makeProcessResource;\n\n /* global window */\n\n function fetchUrl(url, fetch = window.fetch) {\n return fetch(url, {cache: 'force-cache', credentials: 'same-origin'}).then(resp =>\n resp.arrayBuffer().then(buff => ({\n url,\n type: resp.headers.get('Content-Type'),\n value: buff,\n })),\n );\n }\n\n var fetchUrl_1 = fetchUrl;\n\n function makeFindStyleSheetByUrl({styleSheetCache}) {\n return function findStyleSheetByUrl(url, doc) {\n return styleSheetCache[url] || [...doc.styleSheets].find(styleSheet => styleSheet.href === url);\n };\n }\n\n var findStyleSheetByUrl = makeFindStyleSheetByUrl;\n\n function getUrlFromCssText(cssText) {\n const re = /url\\((?!['\"]?:)['\"]?([^'\")]*)['\"]?\\)/g;\n const ret = [];\n let result;\n while ((result = re.exec(cssText)) !== null) {\n ret.push(result[1]);\n }\n return ret;\n }\n\n var getUrlFromCssText_1 = getUrlFromCssText;\n\n // NOTE this code is very similar to the node part of visual-grid-client, but there is a different related to the browser's cssom with import rules\n function makeExtractResourcesFromStyleSheet({styleSheetCache}) {\n return function extractResourcesFromStyleSheet(styleSheet, win = window) {\n return uniq_1(\n [...(styleSheet.cssRules || [])].reduce((acc, rule) => {\n if (rule instanceof win.CSSImportRule) {\n styleSheetCache[rule.styleSheet.href] = rule.styleSheet;\n return acc.concat(rule.href);\n } else if (rule instanceof win.CSSFontFaceRule) {\n return acc.concat(getUrlFromCssText_1(rule.style.getPropertyValue('src')));\n } else if (rule instanceof win.CSSSupportsRule || rule instanceof win.CSSMediaRule) {\n return acc.concat(extractResourcesFromStyleSheet(rule));\n } else if (rule instanceof win.CSSStyleRule) {\n for (let i = 0, ii = rule.style.length; i < ii; i++) {\n const urls = getUrlFromCssText_1(rule.style.getPropertyValue(rule.style[i]));\n urls.length && (acc = acc.concat(urls));\n }\n }\n return acc;\n }, []),\n );\n };\n }\n\n var extractResourcesFromStyleSheet = makeExtractResourcesFromStyleSheet;\n\n function extractResourceUrlsFromStyleAttrs(cdt) {\n return cdt.reduce((acc, node) => {\n if (node.nodeType === 1) {\n const styleAttr =\n node.attributes && node.attributes.find(attr => attr.name.toUpperCase() === 'STYLE');\n\n if (styleAttr) acc = acc.concat(getUrlFromCssText_1(styleAttr.value));\n }\n return acc;\n }, []);\n }\n\n var extractResourceUrlsFromStyleAttrs_1 = extractResourceUrlsFromStyleAttrs;\n\n function makeExtractResourceUrlsFromStyleTags(extractResourcesFromStyleSheet) {\n return function extractResourceUrlsFromStyleTags(doc) {\n return uniq_1(\n [...doc.getElementsByTagName('style')].reduce((resourceUrls, styleEl) => {\n const styleSheet = [...doc.styleSheets].find(\n styleSheet => styleSheet.ownerNode === styleEl,\n );\n return resourceUrls.concat(extractResourcesFromStyleSheet(styleSheet, doc.defaultView));\n }, []),\n );\n };\n }\n\n var extractResourceUrlsFromStyleTags = makeExtractResourceUrlsFromStyleTags;\n\n function isSameOrigin(url, baseUrl) {\n const blobOrData = /^(blob|data):/;\n if (blobOrData.test(url)) return true;\n if (blobOrData.test(baseUrl)) return false;\n\n const {origin} = new URL(url, baseUrl);\n const {origin: baseOrigin} = new URL(baseUrl);\n return origin === baseOrigin;\n }\n\n var isSameOrigin_1 = isSameOrigin;\n\n function processPage(doc = document) {\n const styleSheetCache = {};\n const extractResourcesFromStyleSheet$$1 = extractResourcesFromStyleSheet({styleSheetCache});\n const findStyleSheetByUrl$$1 = findStyleSheetByUrl({styleSheetCache});\n const processResource$$1 = processResource({\n fetchUrl: fetchUrl_1,\n findStyleSheetByUrl: findStyleSheetByUrl$$1,\n extractResourcesFromStyleSheet: extractResourcesFromStyleSheet$$1,\n absolutizeUrl: absolutizeUrl_1,\n isSameOrigin: isSameOrigin_1,\n });\n\n const getResourceUrlsAndBlobs$$1 = getResourceUrlsAndBlobs({\n processResource: processResource$$1,\n aggregateResourceUrlsAndBlobs: aggregateResourceUrlsAndBlobs_1,\n });\n\n const extractResourceUrlsFromStyleTags$$1 = extractResourceUrlsFromStyleTags(\n extractResourcesFromStyleSheet$$1,\n );\n\n return doProcessPage(doc);\n\n function doProcessPage(doc) {\n const frameElement = doc.defaultView && doc.defaultView.frameElement;\n const url = frameElement ? frameElement.src : doc.location.href;\n\n const cdt = domNodesToCdt_1(doc);\n\n const links = uniq_1(\n extractLinks_1(doc)\n .concat(extractResourceUrlsFromStyleAttrs_1(cdt))\n .concat(extractResourceUrlsFromStyleTags$$1(doc)),\n )\n .map(absolutizeThisUrl)\n .filter(filterInlineUrlsIfExisting);\n\n const resourceUrlsAndBlobsPromise = getResourceUrlsAndBlobs$$1(doc, url, links);\n\n const frameDocs = extractFrames_1(doc);\n const processFramesPromise = frameDocs.map(doProcessPage);\n\n return Promise.all([resourceUrlsAndBlobsPromise, ...processFramesPromise]).then(\n ([{resourceUrls, blobsObj}, ...framesResults]) => ({\n cdt,\n url,\n resourceUrls,\n blobs: blobsObjToArray(blobsObj),\n frames: framesResults,\n srcAttr: frameElement ? frameElement.getAttribute('src') : undefined,\n }),\n );\n\n function absolutizeThisUrl(someUrl) {\n try {\n return absolutizeUrl_1(someUrl, url);\n } catch (err) {\n // can't do anything with a non-absolute url\n }\n }\n }\n }\n\n function blobsObjToArray(blobsObj) {\n return Object.keys(blobsObj).map(blobUrl =>\n Object.assign(\n {\n url: blobUrl.replace(/^blob:/, ''),\n },\n blobsObj[blobUrl],\n ),\n );\n }\n\n function filterInlineUrlsIfExisting(absoluteUrl) {\n return absoluteUrl && filterInlineUrl_1(absoluteUrl);\n }\n\n var processPage_1 = processPage;\n\n function processPageAndSerialize(doc) {\n return processPage_1(doc).then(serializeFrame);\n }\n\n function serializeFrame(frame) {\n frame.blobs = frame.blobs.map(({url, type, value}) => ({\n url,\n type,\n value: arrayBufferToBase64_1(value),\n }));\n frame.frames.forEach(serializeFrame);\n return frame;\n }\n\n var processPageAndSerialize_1 = processPageAndSerialize;\n\n const EYES_NAME_SPACE = '__EYES__APPLITOOLS__';\n\n function processPageAndPoll(doc) {\n if (!window[EYES_NAME_SPACE]) {\n window[EYES_NAME_SPACE] = {};\n }\n if (!window[EYES_NAME_SPACE].processPageAndSerializeResult) {\n window[EYES_NAME_SPACE].processPageAndSerializeResult = {\n status: 'WIP',\n value: null,\n error: null,\n };\n processPageAndSerialize_1(doc)\n .then(r => ((resultObject.status = 'SUCCESS'), (resultObject.value = r)))\n .catch(e => ((resultObject.status = 'ERROR'), (resultObject.error = e.message)));\n }\n\n const resultObject = window[EYES_NAME_SPACE].processPageAndSerializeResult;\n if (resultObject.status === 'SUCCESS') {\n window[EYES_NAME_SPACE].processPageAndSerializeResult = null;\n }\n\n return JSON.stringify(resultObject);\n }\n\n var processPageAndPoll_1 = processPageAndPoll;\n\n return processPageAndPoll_1;\n\n}());\n\n return processPageAndPoll.apply(this, arguments);\n}\n"
"// @applitools/[email protected]\nfunction __processPageAndSerialize() {\n var processPageAndSerialize = (function () {\n 'use strict';\n\n // This code was copied and modified from https://github.com/beatgammit/base64-js/blob/bf68aaa277/index.js\n // License: https://github.com/beatgammit/base64-js/blob/bf68aaa277d9de7007cc0c58279c411bb10670ac/LICENSE\n\n function arrayBufferToBase64(ab) {\n const lookup = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'.split('');\n\n const uint8 = new Uint8Array(ab);\n const len = uint8.length;\n const extraBytes = len % 3; // if we have 1 byte left, pad 2 bytes\n const parts = [];\n const maxChunkLength = 16383; // must be multiple of 3\n\n let tmp;\n\n // go through the array every three bytes, we'll deal with trailing stuff later\n for (let i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) {\n parts.push(encodeChunk(i, i + maxChunkLength > len2 ? len2 : i + maxChunkLength));\n }\n\n // pad the end with zeros, but make sure to not forget the extra bytes\n if (extraBytes === 1) {\n tmp = uint8[len - 1];\n parts.push(lookup[tmp >> 2] + lookup[(tmp << 4) & 0x3f] + '==');\n } else if (extraBytes === 2) {\n tmp = (uint8[len - 2] << 8) + uint8[len - 1];\n parts.push(lookup[tmp >> 10] + lookup[(tmp >> 4) & 0x3f] + lookup[(tmp << 2) & 0x3f] + '=');\n }\n\n return parts.join('');\n\n function tripletToBase64(num) {\n return (\n lookup[(num >> 18) & 0x3f] +\n lookup[(num >> 12) & 0x3f] +\n lookup[(num >> 6) & 0x3f] +\n lookup[num & 0x3f]\n );\n }\n\n function encodeChunk(start, end) {\n let tmp;\n const output = [];\n for (let i = start; i < end; i += 3) {\n tmp = ((uint8[i] << 16) & 0xff0000) + ((uint8[i + 1] << 8) & 0xff00) + (uint8[i + 2] & 0xff);\n output.push(tripletToBase64(tmp));\n }\n return output.join('');\n }\n }\n\n var arrayBufferToBase64_1 = arrayBufferToBase64;\n\n function extractLinks(doc = document) {\n const srcsetUrls = [...doc.querySelectorAll('img[srcset],source[srcset]')]\n .map(srcsetEl =>\n srcsetEl\n .getAttribute('srcset')\n .split(',')\n .map(str => str.trim().split(/\\s+/)[0]),\n )\n .reduce((acc, urls) => acc.concat(urls), []);\n\n const srcUrls = [...doc.querySelectorAll('img[src],source[src]')].map(srcEl =>\n srcEl.getAttribute('src'),\n );\n\n const cssUrls = [...doc.querySelectorAll('link[rel=\"stylesheet\"]')].map(link =>\n link.getAttribute('href'),\n );\n\n const videoPosterUrls = [...doc.querySelectorAll('video[poster]')].map(videoEl =>\n videoEl.getAttribute('poster'),\n );\n\n return [...srcsetUrls, ...srcUrls, ...cssUrls, ...videoPosterUrls];\n }\n\n var extractLinks_1 = extractLinks;\n\n /* eslint-disable no-use-before-define */\n\n function domNodesToCdt(docNode) {\n const NODE_TYPES = {\n ELEMENT: 1,\n TEXT: 3,\n DOCUMENT: 9,\n DOCUMENT_TYPE: 10,\n DOCUMENT_FRAGMENT_NODE: 11,\n };\n\n const domNodes = [\n {\n nodeType: NODE_TYPES.DOCUMENT,\n },\n ];\n domNodes[0].childNodeIndexes = childrenFactory(domNodes, docNode.childNodes);\n return domNodes;\n\n function childrenFactory(domNodes, elementNodes) {\n if (!elementNodes || elementNodes.length === 0) return null;\n\n const childIndexes = [];\n elementNodes.forEach(elementNode => {\n const index = elementNodeFactory(domNodes, elementNode);\n if (index !== null) {\n childIndexes.push(index);\n }\n });\n\n return childIndexes;\n }\n\n function elementNodeFactory(domNodes, elementNode) {\n let node;\n const {nodeType} = elementNode;\n if ([NODE_TYPES.ELEMENT, NODE_TYPES.DOCUMENT_FRAGMENT_NODE].includes(nodeType)) {\n if (elementNode.nodeName !== 'SCRIPT') {\n if (\n elementNode.nodeName === 'STYLE' &&\n !elementNode.textContent &&\n elementNode.sheet &&\n elementNode.sheet.cssRules.length\n ) {\n elementNode.appendChild(\n docNode.createTextNode(\n [...elementNode.sheet.cssRules].map(rule => rule.cssText).join(''),\n ),\n );\n }\n\n node = {\n nodeType: nodeType,\n nodeName: elementNode.nodeName,\n attributes: Object.keys(elementNode.attributes || {}).map(key => {\n let value = elementNode.attributes[key].value;\n const name = elementNode.attributes[key].localName;\n\n if (/^blob:/.test(value)) {\n value = value.replace(/^blob:/, '');\n }\n\n return {\n name,\n value,\n };\n }),\n childNodeIndexes: elementNode.childNodes.length\n ? childrenFactory(domNodes, elementNode.childNodes)\n : [],\n };\n\n if (elementNode.shadowRoot) {\n node.shadowRootIndex = elementNodeFactory(domNodes, elementNode.shadowRoot);\n }\n\n if (elementNode.checked && !elementNode.attributes.checked) {\n node.attributes.push({name: 'checked', value: 'checked'});\n }\n if (\n elementNode.value !== undefined &&\n elementNode.attributes.value === undefined &&\n elementNode.tagName === 'INPUT'\n ) {\n node.attributes.push({name: 'value', value: elementNode.value});\n }\n }\n } else if (nodeType === NODE_TYPES.TEXT) {\n node = {\n nodeType: NODE_TYPES.TEXT,\n nodeValue: elementNode.nodeValue,\n };\n } else if (nodeType === NODE_TYPES.DOCUMENT_TYPE) {\n node = {\n nodeType: NODE_TYPES.DOCUMENT_TYPE,\n nodeName: elementNode.nodeName,\n };\n }\n\n if (node) {\n domNodes.push(node);\n return domNodes.length - 1;\n } else {\n // console.log(`Unknown nodeType: ${nodeType}`);\n return null;\n }\n }\n }\n\n var domNodesToCdt_1 = domNodesToCdt;\n var NODE_TYPES = {\n ELEMENT: 1,\n TEXT: 3,\n DOCUMENT: 9,\n DOCUMENT_TYPE: 10,\n };\n domNodesToCdt_1.NODE_TYPES = NODE_TYPES;\n\n function extractFrames(doc = document) {\n return [...doc.querySelectorAll('iframe[src]:not([src=\"\"])')]\n .map(srcEl => {\n try {\n const contentDoc = srcEl.contentDocument;\n return (\n contentDoc &&\n /^https?:$/.test(contentDoc.location.protocol) &&\n contentDoc.defaultView &&\n contentDoc.defaultView.frameElement &&\n contentDoc\n );\n } catch (err) {\n //for CORS frames\n }\n })\n .filter(x => !!x);\n }\n\n var extractFrames_1 = extractFrames;\n\n function uniq(arr) {\n const result = [];\n new Set(arr).forEach(v => v && result.push(v));\n return result;\n }\n\n var uniq_1 = uniq;\n\n function aggregateResourceUrlsAndBlobs(resourceUrlsAndBlobsArr) {\n return resourceUrlsAndBlobsArr.reduce(\n ({resourceUrls: allResourceUrls, blobsObj: allBlobsObj}, {resourceUrls, blobsObj}) => ({\n resourceUrls: uniq_1(allResourceUrls.concat(resourceUrls)),\n blobsObj: Object.assign(allBlobsObj, blobsObj),\n }),\n {resourceUrls: [], blobsObj: {}},\n );\n }\n\n var aggregateResourceUrlsAndBlobs_1 = aggregateResourceUrlsAndBlobs;\n\n function makeGetResourceUrlsAndBlobs({processResource, aggregateResourceUrlsAndBlobs}) {\n return function getResourceUrlsAndBlobs(doc, baseUrl, urls) {\n return Promise.all(\n urls.map(url => processResource(url, doc, baseUrl, getResourceUrlsAndBlobs.bind(null, doc))),\n ).then(resourceUrlsAndBlobsArr => aggregateResourceUrlsAndBlobs(resourceUrlsAndBlobsArr));\n };\n }\n\n var getResourceUrlsAndBlobs = makeGetResourceUrlsAndBlobs;\n\n function filterInlineUrl(absoluteUrl) {\n return /^(blob|https?):/.test(absoluteUrl);\n }\n\n var filterInlineUrl_1 = filterInlineUrl;\n\n function absolutizeUrl(url, absoluteUrl) {\n return new URL(url, absoluteUrl).href;\n }\n\n var absolutizeUrl_1 = absolutizeUrl;\n\n function makeProcessResource({\n fetchUrl,\n findStyleSheetByUrl,\n extractResourcesFromStyleSheet,\n isSameOrigin,\n cache = {},\n }) {\n return function processResource(absoluteUrl, doc, baseUrl, getResourceUrlsAndBlobs) {\n return cache[absoluteUrl] || (cache[absoluteUrl] = doProcessResource(absoluteUrl));\n\n function doProcessResource(url) {\n return fetchUrl(url)\n .catch(e => {\n if (probablyCORS(e, url)) {\n return {probablyCORS: true, url};\n } else {\n throw e;\n }\n })\n .then(({url, type, value, probablyCORS}) => {\n if (probablyCORS) {\n return {resourceUrls: [url]};\n }\n const result = {blobsObj: {[url]: {type, value}}};\n if (/text\\/css/.test(type)) {\n const styleSheet = findStyleSheetByUrl(url, doc);\n if (!styleSheet) {\n return result;\n }\n const resourceUrls = extractResourcesFromStyleSheet(styleSheet, doc.defaultView)\n .map(resourceUrl => absolutizeUrl_1(resourceUrl, url.replace(/^blob:/, '')))\n .filter(filterInlineUrl_1);\n return getResourceUrlsAndBlobs(baseUrl, resourceUrls).then(\n ({resourceUrls, blobsObj}) => ({\n resourceUrls,\n blobsObj: Object.assign(blobsObj, {[url]: {type, value}}),\n }),\n );\n } else {\n return result;\n }\n })\n .catch(err => {\n console.log('[dom-snapshot] error while fetching', url, err);\n return {};\n });\n }\n\n function probablyCORS(err, url) {\n const msgCORS = err.message && err.message.includes('Failed to fetch');\n const nameCORS = err.name && err.name.includes('TypeError');\n return msgCORS && nameCORS && !isSameOrigin(url, baseUrl);\n }\n };\n }\n\n var processResource = makeProcessResource;\n\n /* global window */\n\n function fetchUrl(url, fetch = window.fetch) {\n return fetch(url, {cache: 'force-cache', credentials: 'same-origin'}).then(resp =>\n resp.arrayBuffer().then(buff => ({\n url,\n type: resp.headers.get('Content-Type'),\n value: buff,\n })),\n );\n }\n\n var fetchUrl_1 = fetchUrl;\n\n function makeFindStyleSheetByUrl({styleSheetCache}) {\n return function findStyleSheetByUrl(url, doc) {\n return styleSheetCache[url] || [...doc.styleSheets].find(styleSheet => styleSheet.href === url);\n };\n }\n\n var findStyleSheetByUrl = makeFindStyleSheetByUrl;\n\n function getUrlFromCssText(cssText) {\n const re = /url\\((?!['\"]?:)['\"]?([^'\")]*)['\"]?\\)/g;\n const ret = [];\n let result;\n while ((result = re.exec(cssText)) !== null) {\n ret.push(result[1]);\n }\n return ret;\n }\n\n var getUrlFromCssText_1 = getUrlFromCssText;\n\n // NOTE this code is very similar to the node part of visual-grid-client, but there is a different related to the browser's cssom with import rules\n function makeExtractResourcesFromStyleSheet({styleSheetCache}) {\n return function extractResourcesFromStyleSheet(styleSheet, win = window) {\n return uniq_1(\n [...(styleSheet.cssRules || [])].reduce((acc, rule) => {\n if (rule instanceof win.CSSImportRule) {\n styleSheetCache[rule.styleSheet.href] = rule.styleSheet;\n return acc.concat(rule.href);\n } else if (rule instanceof win.CSSFontFaceRule) {\n return acc.concat(getUrlFromCssText_1(rule.style.getPropertyValue('src')));\n } else if (rule instanceof win.CSSSupportsRule || rule instanceof win.CSSMediaRule) {\n return acc.concat(extractResourcesFromStyleSheet(rule));\n } else if (rule instanceof win.CSSStyleRule) {\n for (let i = 0, ii = rule.style.length; i < ii; i++) {\n const urls = getUrlFromCssText_1(rule.style.getPropertyValue(rule.style[i]));\n urls.length && (acc = acc.concat(urls));\n }\n }\n return acc;\n }, []),\n );\n };\n }\n\n var extractResourcesFromStyleSheet = makeExtractResourcesFromStyleSheet;\n\n function extractResourceUrlsFromStyleAttrs(cdt) {\n return cdt.reduce((acc, node) => {\n if (node.nodeType === 1) {\n const styleAttr =\n node.attributes && node.attributes.find(attr => attr.name.toUpperCase() === 'STYLE');\n\n if (styleAttr) acc = acc.concat(getUrlFromCssText_1(styleAttr.value));\n }\n return acc;\n }, []);\n }\n\n var extractResourceUrlsFromStyleAttrs_1 = extractResourceUrlsFromStyleAttrs;\n\n function makeExtractResourceUrlsFromStyleTags(extractResourcesFromStyleSheet) {\n return function extractResourceUrlsFromStyleTags(doc) {\n return uniq_1(\n [...doc.getElementsByTagName('style')].reduce((resourceUrls, styleEl) => {\n const styleSheet = [...doc.styleSheets].find(\n styleSheet => styleSheet.ownerNode === styleEl,\n );\n return resourceUrls.concat(extractResourcesFromStyleSheet(styleSheet, doc.defaultView));\n }, []),\n );\n };\n }\n\n var extractResourceUrlsFromStyleTags = makeExtractResourceUrlsFromStyleTags;\n\n function isSameOrigin(url, baseUrl) {\n const blobOrData = /^(blob|data):/;\n if (blobOrData.test(url)) return true;\n if (blobOrData.test(baseUrl)) return false;\n\n const {origin} = new URL(url, baseUrl);\n const {origin: baseOrigin} = new URL(baseUrl);\n return origin === baseOrigin;\n }\n\n var isSameOrigin_1 = isSameOrigin;\n\n function processPage(doc = document) {\n const styleSheetCache = {};\n const extractResourcesFromStyleSheet$$1 = extractResourcesFromStyleSheet({styleSheetCache});\n const findStyleSheetByUrl$$1 = findStyleSheetByUrl({styleSheetCache});\n const processResource$$1 = processResource({\n fetchUrl: fetchUrl_1,\n findStyleSheetByUrl: findStyleSheetByUrl$$1,\n extractResourcesFromStyleSheet: extractResourcesFromStyleSheet$$1,\n absolutizeUrl: absolutizeUrl_1,\n isSameOrigin: isSameOrigin_1,\n });\n\n const getResourceUrlsAndBlobs$$1 = getResourceUrlsAndBlobs({\n processResource: processResource$$1,\n aggregateResourceUrlsAndBlobs: aggregateResourceUrlsAndBlobs_1,\n });\n\n const extractResourceUrlsFromStyleTags$$1 = extractResourceUrlsFromStyleTags(\n extractResourcesFromStyleSheet$$1,\n );\n\n return doProcessPage(doc);\n\n function doProcessPage(doc) {\n const frameElement = doc.defaultView && doc.defaultView.frameElement;\n const url = frameElement ? frameElement.src : doc.location.href;\n\n const cdt = domNodesToCdt_1(doc);\n\n const links = uniq_1(\n extractLinks_1(doc)\n .concat(extractResourceUrlsFromStyleAttrs_1(cdt))\n .concat(extractResourceUrlsFromStyleTags$$1(doc)),\n )\n .map(absolutizeThisUrl)\n .filter(filterInlineUrlsIfExisting);\n\n const resourceUrlsAndBlobsPromise = getResourceUrlsAndBlobs$$1(doc, url, links);\n\n const frameDocs = extractFrames_1(doc);\n const processFramesPromise = frameDocs.map(doProcessPage);\n\n return Promise.all([resourceUrlsAndBlobsPromise, ...processFramesPromise]).then(\n ([{resourceUrls, blobsObj}, ...framesResults]) => ({\n cdt,\n url,\n resourceUrls,\n blobs: blobsObjToArray(blobsObj),\n frames: framesResults,\n srcAttr: frameElement ? frameElement.getAttribute('src') : undefined,\n }),\n );\n\n function absolutizeThisUrl(someUrl) {\n try {\n return absolutizeUrl_1(someUrl, url);\n } catch (err) {\n // can't do anything with a non-absolute url\n }\n }\n }\n }\n\n function blobsObjToArray(blobsObj) {\n return Object.keys(blobsObj).map(blobUrl =>\n Object.assign(\n {\n url: blobUrl.replace(/^blob:/, ''),\n },\n blobsObj[blobUrl],\n ),\n );\n }\n\n function filterInlineUrlsIfExisting(absoluteUrl) {\n return absoluteUrl && filterInlineUrl_1(absoluteUrl);\n }\n\n var processPage_1 = processPage;\n\n function processPageAndSerialize(doc) {\n return processPage_1(doc).then(serializeFrame);\n }\n\n function serializeFrame(frame) {\n frame.blobs = frame.blobs.map(({url, type, value}) => ({\n url,\n type,\n value: arrayBufferToBase64_1(value),\n }));\n frame.frames.forEach(serializeFrame);\n return frame;\n }\n\n var processPageAndSerialize_1 = processPageAndSerialize;\n\n return processPageAndSerialize_1;\n\n}());\n\n return processPageAndSerialize.apply(this, arguments);\n}\n"