"/* @applitools/[email protected] */\n\nfunction __captureDomAndPoll() {\n var captureDomAndPoll = (function () {\n 'use strict';\n\n const styleProps = [\n 'background-repeat',\n 'background-origin',\n 'background-position',\n 'background-color',\n 'background-image',\n 'background-size',\n 'border-width',\n 'border-color',\n 'border-style',\n 'color',\n 'display',\n 'font-size',\n 'line-height',\n 'margin',\n 'opacity',\n 'overflow',\n 'padding',\n 'visibility',\n ];\n\n const rectProps = ['width', 'height', 'top', 'left'];\n\n const ignoredTagNames = ['HEAD', 'SCRIPT'];\n\n var defaultDomProps = {\n styleProps,\n rectProps,\n ignoredTagNames,\n };\n\n const bgImageRe = /url\\((?!['\"]?:)['\"]?([^'\")]*)['\"]?\\)/;\n\n function getBackgroundImageUrl(cssText) {\n const match = cssText ? cssText.match(bgImageRe) : undefined;\n return match ? match[1] : match;\n }\n\n var getBackgroundImageUrl_1 = getBackgroundImageUrl;\n\n const psetTimeout = t =>\n new Promise(res => {\n setTimeout(res, t);\n });\n\n async function getImageSizes({bgImages, timeout = 5000, Image = window.Image}) {\n return (\n await Promise.all(\n Array.from(bgImages).map(url =>\n Promise.race([\n new Promise(resolve => {\n const img = new Image();\n img.onload = () => resolve({url, width: img.naturalWidth, height: img.naturalHeight});\n img.onerror = () => resolve();\n img.src = url;\n }),\n psetTimeout(timeout),\n ]),\n ),\n )\n ).reduce((images, curr) => {\n if (curr) {\n images[curr.url] = {width: curr.width, height: curr.height};\n }\n return images;\n }, {});\n }\n\n var getImageSizes_1 = getImageSizes;\n\n function genXpath(el) {\n if (!el.ownerDocument) return ''; // this is the document node\n\n let xpath = '',\n currEl = el,\n doc = el.ownerDocument,\n frameElement = doc.defaultView.frameElement;\n while (currEl !== doc) {\n xpath = `${currEl.tagName}[${getIndex(currEl)}]/${xpath}`;\n currEl = currEl.parentNode;\n }\n if (frameElement) {\n xpath = `${genXpath(frameElement)},${xpath}`;\n }\n return xpath.replace(/\\/$/, '');\n }\n\n function getIndex(el) {\n return (\n Array.prototype.filter\n .call(el.parentNode.childNodes, node => node.tagName === el.tagName)\n .indexOf(el) + 1\n );\n }\n\n var genXpath_1 = genXpath;\n\n function absolutizeUrl(url, absoluteUrl) {\n return new URL(url, absoluteUrl).href;\n }\n\n var absolutizeUrl_1 = absolutizeUrl;\n\n function makeGetBundledCssFromCssText({\n parseCss,\n CSSImportRule,\n absolutizeUrl,\n getCssFromCache,\n unfetchedToken,\n }) {\n return function getBundledCssFromCssText(cssText, styleBaseUrl) {\n let unfetchedResources;\n let bundledCss = '';\n\n try {\n const styleSheet = parseCss(cssText);\n for (const rule of Array.from(styleSheet.cssRules)) {\n if (rule instanceof CSSImportRule) {\n const nestedUrl = absolutizeUrl(rule.href, styleBaseUrl);\n const nestedResource = getCssFromCache(nestedUrl);\n if (nestedResource !== undefined) {\n const {\n bundledCss: nestedCssText,\n unfetchedResources: nestedUnfetchedResources,\n } = getBundledCssFromCssText(nestedResource, nestedUrl);\n\n nestedUnfetchedResources && (unfetchedResources = new Set(nestedUnfetchedResources));\n bundledCss = `${nestedCssText}${bundledCss}`;\n } else {\n unfetchedResources = new Set([nestedUrl]);\n bundledCss = `\\n${unfetchedToken}${nestedUrl}${unfetchedToken}`;\n }\n }\n }\n } catch (ex) {\n console.log(`error during getBundledCssFromCssText, styleBaseUrl=${styleBaseUrl}`, ex);\n }\n\n bundledCss = `${bundledCss}${getCss(cssText, styleBaseUrl)}`;\n\n return {\n bundledCss,\n unfetchedResources,\n };\n };\n }\n\n function getCss(newText, url) {\n return `\\n/** ${url} **/\\n${newText}`;\n }\n\n var getBundledCssFromCssText = makeGetBundledCssFromCssText;\n\n function parseCss(styleContent) {\n var doc = document.implementation.createHTMLDocument(''),\n styleElement = doc.createElement('style');\n styleElement.textContent = styleContent;\n // the style will only be parsed once it is added to a document\n doc.body.appendChild(styleElement);\n\n return styleElement.sheet;\n }\n\n var parseCss_1 = parseCss;\n\n function makeFetchCss(fetch) {\n return async function fetchCss(url) {\n try {\n const response = await fetch(url, {cache: 'force-cache'});\n if (response.ok) {\n return await response.text();\n }\n console.log('/failed to fetch (status ' + response.status + ') css from: ' + url + '/');\n } catch (err) {\n console.log('/failed to fetch (error ' + err.toString() + ') css from: ' + url + '/');\n }\n };\n }\n\n var fetchCss = makeFetchCss;\n\n var getHrefAttr = function getHrefAttr(node) {\n const attr = Array.from(node.attributes).find(attr => attr.name.toLowerCase() === 'href');\n return attr && attr.value;\n };\n\n var isLinkToStyleSheet = function isLinkToStyleSheet(node) {\n return (\n node.nodeName &&\n node.nodeName.toUpperCase() === 'LINK' &&\n node.attributes &&\n Array.from(node.attributes).find(\n attr => attr.name.toLowerCase() === 'rel' && attr.value.toLowerCase() === 'stylesheet',\n )\n );\n };\n\n function isDataUrl(url) {\n return url && url.startsWith('data:');\n }\n\n var isDataUrl_1 = isDataUrl;\n\n function makeExtractCssFromNode({getCssFromCache, absolutizeUrl}) {\n return function extractCssFromNode(node, baseUrl) {\n let cssText, styleBaseUrl, isUnfetched;\n if (isStyleElement(node)) {\n cssText = Array.from(node.childNodes)\n .map(node => node.nodeValue)\n .join('');\n styleBaseUrl = baseUrl;\n } else if (isLinkToStyleSheet(node)) {\n const href = getHrefAttr(node);\n if (!isDataUrl_1(href)) {\n styleBaseUrl = absolutizeUrl(href, baseUrl);\n cssText = getCssFromCache(styleBaseUrl);\n } else {\n styleBaseUrl = baseUrl;\n cssText = href.match(/,(.+)/)[1];\n }\n isUnfetched = cssText === undefined;\n }\n return {cssText, styleBaseUrl, isUnfetched};\n };\n }\n\n function isStyleElement(node) {\n return node.nodeName && node.nodeName.toUpperCase() === 'STYLE';\n }\n\n var extractCssFromNode = makeExtractCssFromNode;\n\n function makeCaptureNodeCss({extractCssFromNode, getBundledCssFromCssText, unfetchedToken}) {\n return function captureNodeCss(node, baseUrl) {\n const {styleBaseUrl, cssText, isUnfetched} = extractCssFromNode(node, baseUrl);\n\n let unfetchedResources;\n let bundledCss = '';\n if (cssText) {\n const {bundledCss: nestedCss, unfetchedResources: nestedUnfetched} = getBundledCssFromCssText(\n cssText,\n styleBaseUrl,\n );\n\n bundledCss += nestedCss;\n unfetchedResources = new Set(nestedUnfetched);\n } else if (isUnfetched) {\n bundledCss += `${unfetchedToken}${styleBaseUrl}${unfetchedToken}`;\n unfetchedResources = new Set([styleBaseUrl]);\n }\n return {bundledCss, unfetchedResources};\n };\n }\n\n var captureNodeCss = makeCaptureNodeCss;\n\n const NODE_TYPES = {\n ELEMENT: 1,\n TEXT: 3,\n };\n\n var nodeTypes = {NODE_TYPES};\n\n const {NODE_TYPES: NODE_TYPES$1} = nodeTypes;\n\n\n\n\n\n function makePrefetchAllCss(fetchCss) {\n return async function prefetchAllCss(doc = document) {\n const cssMap = {};\n const start = Date.now();\n const promises = [];\n doFetchAllCssFromFrame(doc, cssMap, promises);\n await Promise.all(promises);\n console.log('[prefetchAllCss]', Date.now() - start);\n\n return function fetchCssSync(url) {\n return cssMap[url];\n };\n\n async function fetchNodeCss(node, baseUrl, cssMap) {\n let cssText, resourceUrl;\n if (isLinkToStyleSheet(node)) {\n resourceUrl = absolutizeUrl_1(getHrefAttr(node), baseUrl);\n cssText = await fetchCss(resourceUrl);\n if (cssText !== undefined) {\n cssMap[resourceUrl] = cssText;\n }\n }\n if (cssText) {\n await fetchBundledCss(cssText, resourceUrl, cssMap);\n }\n }\n\n async function fetchBundledCss(cssText, resourceUrl, cssMap) {\n try {\n const styleSheet = parseCss_1(cssText);\n const promises = [];\n for (const rule of Array.from(styleSheet.cssRules)) {\n if (rule instanceof CSSImportRule) {\n promises.push(\n (async () => {\n const nestedUrl = absolutizeUrl_1(rule.href, resourceUrl);\n const cssText = await fetchCss(nestedUrl);\n cssMap[nestedUrl] = cssText;\n if (cssText !== undefined) {\n await fetchBundledCss(cssText, nestedUrl, cssMap);\n }\n })(),\n );\n }\n }\n await Promise.all(promises);\n } catch (ex) {\n console.log(`error during fetchBundledCss, resourceUrl=${resourceUrl}`, ex);\n }\n }\n\n function doFetchAllCssFromFrame(frameDoc, cssMap, promises) {\n fetchAllCssFromNode(frameDoc.documentElement);\n\n function fetchAllCssFromNode(node) {\n promises.push(fetchNodeCss(node, frameDoc.location.href, cssMap));\n\n switch (node.nodeType) {\n case NODE_TYPES$1.ELEMENT: {\n const tagName = node.tagName.toUpperCase();\n if (tagName === 'IFRAME') {\n return fetchAllCssFromIframe(node);\n } else {\n return fetchAllCssFromElement(node);\n }\n }\n }\n }\n\n async function fetchAllCssFromElement(el) {\n Array.prototype.map.call(el.childNodes, fetchAllCssFromNode);\n }\n\n async function fetchAllCssFromIframe(el) {\n fetchAllCssFromElement(el);\n try {\n doFetchAllCssFromFrame(el.contentDocument, cssMap, promises);\n } catch (ex) {\n console.log(ex);\n }\n }\n }\n };\n }\n\n var prefetchAllCss = makePrefetchAllCss;\n\n const {NODE_TYPES: NODE_TYPES$2} = nodeTypes;\n\n const API_VERSION = '1.1.0';\n\n async function captureFrame(\n {styleProps, rectProps, ignoredTagNames} = defaultDomProps,\n doc = document,\n addStats = false,\n ) {\n const performance = {total: {}, prefetchCss: {}, doCaptureFrame: {}, waitForImages: {}};\n function startTime(obj) {\n obj.startTime = Date.now();\n }\n function endTime(obj) {\n obj.endTime = Date.now();\n obj.ellapsedTime = obj.endTime - obj.startTime;\n }\n const promises = [];\n startTime(performance.total);\n const unfetchedResources = new Set();\n const iframeCors = [];\n const iframeToken = '@@@@@';\n const unfetchedToken = '#####';\n const separator = '-----';\n\n startTime(performance.prefetchCss);\n const prefetchAllCss$$1 = prefetchAllCss(fetchCss(fetch));\n const getCssFromCache = await prefetchAllCss$$1(doc);\n endTime(performance.prefetchCss);\n\n const getBundledCssFromCssText$$1 = getBundledCssFromCssText({\n parseCss: parseCss_1,\n CSSImportRule,\n getCssFromCache,\n absolutizeUrl: absolutizeUrl_1,\n unfetchedToken,\n });\n const extractCssFromNode$$1 = extractCssFromNode({getCssFromCache, absolutizeUrl: absolutizeUrl_1});\n const captureNodeCss$$1 = captureNodeCss({\n extractCssFromNode: extractCssFromNode$$1,\n getBundledCssFromCssText: getBundledCssFromCssText$$1,\n unfetchedToken,\n });\n\n startTime(performance.doCaptureFrame);\n const capturedFrame = doCaptureFrame(doc);\n endTime(performance.doCaptureFrame);\n\n startTime(performance.waitForImages);\n await Promise.all(promises);\n endTime(performance.waitForImages);\n\n // Note: Change the API_VERSION when changing json structure.\n capturedFrame.version = API_VERSION;\n capturedFrame.scriptVersion = '7.1.3';\n\n const iframePrefix = iframeCors.length ? `${iframeCors.join('\\n')}\\n` : '';\n const unfetchedPrefix = unfetchedResources.size\n ? `${Array.from(unfetchedResources).join('\\n')}\\n`\n : '';\n const metaPrefix = JSON.stringify({\n separator,\n cssStartToken: unfetchedToken,\n cssEndToken: unfetchedToken,\n iframeStartToken: `\"${iframeToken}`,\n iframeEndToken: `${iframeToken}\"`,\n });\n\n endTime(performance.total);\n\n function stats() {\n if (!addStats) {\n return '';\n }\n return `\\n${separator}\\n${JSON.stringify(performance)}`;\n }\n\n const ret = `${metaPrefix}\\n${unfetchedPrefix}${separator}\\n${iframePrefix}${separator}\\n${JSON.stringify(\n capturedFrame,\n )}${stats()}`;\n console.log('[captureFrame]', JSON.stringify(performance));\n return ret;\n\n function filter(x) {\n return !!x;\n }\n\n function notEmptyObj(obj) {\n return Object.keys(obj).length ? obj : undefined;\n }\n\n function captureTextNode(node) {\n return {\n tagName: '#text',\n text: node.textContent,\n };\n }\n\n function doCaptureFrame(frameDoc) {\n const bgImages = new Set();\n let bundledCss = '';\n const ret = captureNode(frameDoc.documentElement);\n ret.css = bundledCss;\n promises.push(getImageSizes_1({bgImages}).then(images => (ret.images = images)));\n return ret;\n\n function captureNode(node) {\n const {bundledCss: nodeCss, unfetchedResources: nodeUnfetched} = captureNodeCss$$1(\n node,\n frameDoc.location.href,\n );\n bundledCss += nodeCss;\n if (nodeUnfetched) for (const elem of nodeUnfetched) unfetchedResources.add(elem);\n\n switch (node.nodeType) {\n case NODE_TYPES$2.TEXT: {\n return captureTextNode(node);\n }\n case NODE_TYPES$2.ELEMENT: {\n const tagName = node.tagName.toUpperCase();\n if (tagName === 'IFRAME') {\n return iframeToJSON(node);\n } else {\n return elementToJSON(node);\n }\n }\n default: {\n return null;\n }\n }\n }\n\n function elementToJSON(el) {\n const childNodes = Array.prototype.map.call(el.childNodes, captureNode).filter(filter);\n\n const tagName = el.tagName.toUpperCase();\n if (ignoredTagNames.indexOf(tagName) > -1) return null;\n\n const computedStyle = window.getComputedStyle(el);\n const boundingClientRect = el.getBoundingClientRect();\n\n const style = {};\n for (const p of styleProps) style[p] = computedStyle.getPropertyValue(p);\n if (!style['border-width']) {\n style['border-width'] = `${computedStyle.getPropertyValue(\n 'border-top-width',\n )} ${computedStyle.getPropertyValue('border-right-width')} ${computedStyle.getPropertyValue(\n 'border-bottom-width',\n )} ${computedStyle.getPropertyValue('border-left-width')}`;\n }\n\n const rect = {};\n for (const p of rectProps) rect[p] = boundingClientRect[p];\n\n const attributes = Array.from(el.attributes)\n .map(a => ({key: a.name, value: a.value}))\n .reduce((obj, attr) => {\n obj[attr.key] = attr.value;\n return obj;\n }, {});\n\n const bgImage = getBackgroundImageUrl_1(computedStyle.getPropertyValue('background-image'));\n if (bgImage) {\n bgImages.add(bgImage);\n }\n\n return {\n tagName,\n style: notEmptyObj(style),\n rect: notEmptyObj(rect),\n attributes: notEmptyObj(attributes),\n childNodes,\n };\n }\n\n function iframeToJSON(el) {\n const obj = elementToJSON(el);\n let doc;\n try {\n doc = el.contentDocument;\n } catch (ex) {\n markFrameAsCors();\n return obj;\n }\n try {\n if (doc) {\n obj.childNodes = [doCaptureFrame(el.contentDocument)];\n } else {\n markFrameAsCors();\n }\n } catch (ex) {\n console.log('error in iframeToJSON', ex);\n }\n return obj;\n\n function markFrameAsCors() {\n const xpath = genXpath_1(el);\n iframeCors.push(xpath);\n obj.childNodes = [`${iframeToken}${xpath}${iframeToken}`];\n }\n }\n }\n }\n\n var captureFrame_1 = captureFrame;\n\n const EYES_NAME_SPACE = '__EYES__APPLITOOLS__';\n\n function captureFrameAndPoll(...args) {\n if (!window[EYES_NAME_SPACE]) {\n window[EYES_NAME_SPACE] = {};\n }\n if (!window[EYES_NAME_SPACE].captureDomResult) {\n window[EYES_NAME_SPACE].captureDomResult = {\n status: 'WIP',\n value: null,\n error: null,\n };\n captureFrame_1(...args)\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].captureDomResult;\n if (resultObject.status === 'SUCCESS') {\n window[EYES_NAME_SPACE].captureDomResult = null;\n }\n\n return JSON.stringify(resultObject);\n }\n\n var captureFrameAndPoll_1 = captureFrameAndPoll;\n\n return captureFrameAndPoll_1;\n\n}());\n\n return captureDomAndPoll.apply(this, arguments);\n}\n"