@testplane/webdriverio
Version:
Next-gen browser and mobile automation test framework for Node.js
170 lines (169 loc) • 24.7 kB
JavaScript
// src/scripts/isElementDisplayed.ts
function isElementDisplayed(element) {
function nodeIsElement(node) {
if (!node) {
return false;
}
switch (node.nodeType) {
case Node.ELEMENT_NODE:
case Node.DOCUMENT_NODE:
case Node.DOCUMENT_FRAGMENT_NODE:
return true;
default:
return false;
}
}
function parentElementForElement(element2) {
if (!element2) {
return null;
}
return enclosingNodeOrSelfMatchingPredicate(element2.parentNode, nodeIsElement);
}
function enclosingNodeOrSelfMatchingPredicate(targetNode, predicate) {
for (let node = targetNode; node && node !== targetNode.ownerDocument; node = node.parentNode) {
if (predicate(node)) {
return node;
}
}
return null;
}
function enclosingElementOrSelfMatchingPredicate(targetElement, predicate) {
for (let element2 = targetElement; element2 && element2 !== targetElement.ownerDocument; element2 = parentElementForElement(element2)) {
if (predicate(element2)) {
return element2;
}
}
return null;
}
function cascadedStylePropertyForElement(element2, property) {
if (!element2 || !property) {
return null;
}
if ("ShadowRoot" in window && element2 instanceof window.ShadowRoot) {
element2 = element2.host;
}
const computedStyle = window.getComputedStyle(element2);
const computedStyleProperty = computedStyle.getPropertyValue(property);
if (computedStyleProperty && computedStyleProperty !== "inherit") {
return computedStyleProperty;
}
const parentElement = parentElementForElement(element2);
return cascadedStylePropertyForElement(parentElement, property);
}
function elementHasBoundingBox(element2) {
const boundingBox = element2.getBoundingClientRect();
return boundingBox.width > 0 && boundingBox.height > 0;
}
function elementSubtreeHasNonZeroDimensions(element2) {
if (elementHasBoundingBox(element2)) {
return true;
}
const boundingBox = element2.getBoundingClientRect();
if (element2.tagName.toUpperCase() === "PATH" && boundingBox.width + boundingBox.height > 0) {
const strokeWidth = cascadedStylePropertyForElement(element2, "stroke-width");
return !!strokeWidth && parseInt(strokeWidth, 10) > 0;
}
const cascadedOverflow = cascadedStylePropertyForElement(element2, "overflow");
if (cascadedOverflow === "hidden") {
return false;
}
return [].some.call(element2.childNodes, function(childNode) {
if (childNode.nodeType === Node.TEXT_NODE) {
return true;
}
if (nodeIsElement(childNode)) {
return elementSubtreeHasNonZeroDimensions(childNode);
}
return false;
});
}
function elementOverflowsContainer(element2) {
const cascadedOverflow = cascadedStylePropertyForElement(element2, "overflow");
if (cascadedOverflow !== "hidden") {
return false;
}
return true;
}
function isElementSubtreeHiddenByOverflow(element2) {
if (!element2) {
return false;
}
if (!elementOverflowsContainer(element2)) {
return false;
}
if (!element2.childNodes.length) {
return false;
}
return [].every.call(element2.childNodes, function(childNode) {
if (childNode.nodeType === Node.TEXT_NODE) {
return false;
}
if (!nodeIsElement(childNode)) {
return true;
}
if (!elementSubtreeHasNonZeroDimensions(childNode)) {
return true;
}
return isElementSubtreeHiddenByOverflow(childNode);
});
}
function isElementInsideShadowRoot(element2) {
if (!element2) {
return false;
}
if (element2.parentNode && element2.parentNode.host) {
return true;
}
return isElementInsideShadowRoot(element2.parentNode);
}
if (!isElementInsideShadowRoot(element) && // IE doesn't support document.contains, therefor check before using
(typeof document.contains === "function" ? !document.contains(element) : !document.body.contains(element))) {
return false;
}
switch (element.tagName.toUpperCase()) {
case "BODY":
return true;
case "SCRIPT":
case "NOSCRIPT":
return false;
case "OPTGROUP":
case "OPTION": {
const enclosingSelectElement = enclosingNodeOrSelfMatchingPredicate(element, function(e) {
return e.tagName.toUpperCase() === "SELECT";
});
return isElementDisplayed(enclosingSelectElement);
}
case "INPUT":
if (element.type === "hidden") {
return false;
}
break;
// case 'MAP':
// FIXME: Selenium has special handling for <map> elements. We don't do anything now.
default:
break;
}
if (cascadedStylePropertyForElement(element, "visibility") !== "visible") {
return false;
}
const hasAncestorWithZeroOpacity = !!enclosingElementOrSelfMatchingPredicate(element, function(e) {
return Number(cascadedStylePropertyForElement(e, "opacity")) === 0;
});
const hasAncestorWithDisplayNone = !!enclosingElementOrSelfMatchingPredicate(element, function(e) {
return cascadedStylePropertyForElement(e, "display") === "none";
});
if (hasAncestorWithZeroOpacity || hasAncestorWithDisplayNone) {
return false;
}
if (!elementSubtreeHasNonZeroDimensions(element)) {
return false;
}
if (isElementSubtreeHiddenByOverflow(element) && !elementHasBoundingBox(element)) {
return false;
}
return true;
}
export {
isElementDisplayed as default
};
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vc3JjL3NjcmlwdHMvaXNFbGVtZW50RGlzcGxheWVkLnRzIl0sCiAgInNvdXJjZVJvb3QiOiAiL1VzZXJzL2tyb21hbjUxMi9nZW1pbmktdGVzdGluZy93ZWJkcml2ZXJpby9wYWNrYWdlcy93ZWJkcml2ZXJpbyIsCiAgInNvdXJjZXNDb250ZW50IjogWyIvKlxuICogQ29weXJpZ2h0IChDKSAyMDE3IEFwcGxlIEluYy4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqXG4gKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXRcbiAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uc1xuICogYXJlIG1ldDpcbiAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0XG4gKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXG4gKiAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodFxuICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZVxuICogICAgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlIGRpc3RyaWJ1dGlvbi5cbiAqXG4gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIEFQUExFIElOQy4gQU5EIElUUyBDT05UUklCVVRPUlMgYGBBUyBJUycnXG4gKiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTyxcbiAqIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVJcbiAqIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIEFQUExFIElOQy4gT1IgSVRTIENPTlRSSUJVVE9SU1xuICogQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUlxuICogQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0ZcbiAqIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTU1xuICogSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU5cbiAqIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4gKiBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GXG4gKiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4gKi9cblxuLyoqXG4gKiBjaGVjayBpZiBlbGVtZW50IGlzIHZpc2libGVcbiAqIEBwYXJhbSAge0hUTUxFbGVtZW50fSBlbGVtICBlbGVtZW50IHRvIGNoZWNrXG4gKiBAcmV0dXJuIHtCb29sZWFufSAgICAgICAgICAgdHJ1ZSBpZiBlbGVtZW50IGlzIHdpdGhpbiB2aWV3cG9ydFxuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBpc0VsZW1lbnREaXNwbGF5ZWQgKGVsZW1lbnQ6IEVsZW1lbnQpOiBib29sZWFuIHtcbiAgICBmdW5jdGlvbiBub2RlSXNFbGVtZW50KG5vZGU/OiBFbGVtZW50KSB7XG4gICAgICAgIGlmICghbm9kZSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICAgIH1cblxuICAgICAgICBzd2l0Y2ggKG5vZGUubm9kZVR5cGUpIHtcbiAgICAgICAgY2FzZSBOb2RlLkVMRU1FTlRfTk9ERTpcbiAgICAgICAgY2FzZSBOb2RlLkRPQ1VNRU5UX05PREU6XG4gICAgICAgIGNhc2UgTm9kZS5ET0NVTUVOVF9GUkFHTUVOVF9OT0RFOlxuICAgICAgICAgICAgcmV0dXJuIHRydWVcblxuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBwYXJlbnRFbGVtZW50Rm9yRWxlbWVudChlbGVtZW50PzogRWxlbWVudCkge1xuICAgICAgICBpZiAoIWVsZW1lbnQpIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZW5jbG9zaW5nTm9kZU9yU2VsZk1hdGNoaW5nUHJlZGljYXRlKGVsZW1lbnQucGFyZW50Tm9kZSBhcyBQYXJlbnROb2RlLCBub2RlSXNFbGVtZW50KVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGVuY2xvc2luZ05vZGVPclNlbGZNYXRjaGluZ1ByZWRpY2F0ZSh0YXJnZXROb2RlOiBQYXJlbnROb2RlIHwgSFRNTEVsZW1lbnQsIHByZWRpY2F0ZTogRnVuY3Rpb24pIHtcbiAgICAgICAgZm9yIChcbiAgICAgICAgICAgIGxldCBub2RlOiBQYXJlbnROb2RlID0gdGFyZ2V0Tm9kZTtcbiAgICAgICAgICAgIG5vZGUgJiYgbm9kZSAhPT0gKHRhcmdldE5vZGUgYXMgTm9kZSkub3duZXJEb2N1bWVudDtcbiAgICAgICAgICAgIG5vZGUgPSAobm9kZSBhcyBIVE1MRWxlbWVudCkucGFyZW50Tm9kZSBhcyBQYXJlbnROb2RlXG4gICAgICAgICkge1xuICAgICAgICAgICAgaWYgKHByZWRpY2F0ZShub2RlKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBub2RlXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbnVsbFxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGVuY2xvc2luZ0VsZW1lbnRPclNlbGZNYXRjaGluZ1ByZWRpY2F0ZSh0YXJnZXRFbGVtZW50OiBIVE1MRWxlbWVudCB8IERvY3VtZW50LCBwcmVkaWNhdGU6IEZ1bmN0aW9uKSB7XG4gICAgICAgIGZvciAoXG4gICAgICAgICAgICBsZXQgZWxlbWVudDogSFRNTEVsZW1lbnQgfCBQYXJlbnROb2RlID0gdGFyZ2V0RWxlbWVudDtcbiAgICAgICAgICAgIGVsZW1lbnQgJiYgZWxlbWVudCAhPT0gdGFyZ2V0RWxlbWVudC5vd25lckRvY3VtZW50O1xuICAgICAgICAgICAgZWxlbWVudCA9IHBhcmVudEVsZW1lbnRGb3JFbGVtZW50KGVsZW1lbnQgYXMgSFRNTEVsZW1lbnQpIGFzIEhUTUxFbGVtZW50XG4gICAgICAgICkge1xuICAgICAgICAgICAgaWYgKHByZWRpY2F0ZShlbGVtZW50KSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBlbGVtZW50XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbnVsbFxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGNhc2NhZGVkU3R5bGVQcm9wZXJ0eUZvckVsZW1lbnQoXG4gICAgICAgIGVsZW1lbnQ/OiBFbGVtZW50IHwgUGFyZW50Tm9kZSB8IFNoYWRvd1Jvb3QsXG4gICAgICAgIHByb3BlcnR5Pzogc3RyaW5nXG4gICAgKTogc3RyaW5nIHwgbnVsbCB7XG4gICAgICAgIGlmICghZWxlbWVudCB8fCAhcHJvcGVydHkpIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsXG4gICAgICAgIH1cbiAgICAgICAgLy8gaWYgZG9jdW1lbnQtZnJhZ21lbnQsIHNraXAgaXQgYW5kIHVzZSBlbGVtZW50Lmhvc3QgaW5zdGVhZC4gVGhpcyBoYXBwZW5zXG4gICAgICAgIC8vIHdoZW4gdGhlIGVsZW1lbnQgaXMgaW5zaWRlIGEgc2hhZG93IHJvb3QuXG4gICAgICAgIC8vIHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlIGVycm9ycyBvbiBkb2N1bWVudC1mcmFnbWVudC5cbiAgICAgICAgaWYgKCdTaGFkb3dSb290JyBpbiB3aW5kb3cgJiYgZWxlbWVudCBpbnN0YW5jZW9mIHdpbmRvdy5TaGFkb3dSb290KSB7XG4gICAgICAgICAgICBlbGVtZW50ID0gZWxlbWVudC5ob3N0XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBjb21wdXRlZFN0eWxlID0gd2luZG93LmdldENvbXB1dGVkU3R5bGUoZWxlbWVudCBhcyBFbGVtZW50KVxuICAgICAgICBjb25zdCBjb21wdXRlZFN0eWxlUHJvcGVydHkgPSBjb21wdXRlZFN0eWxlLmdldFByb3BlcnR5VmFsdWUocHJvcGVydHkpXG4gICAgICAgIGlmIChjb21wdXRlZFN0eWxlUHJvcGVydHkgJiYgY29tcHV0ZWRTdHlsZVByb3BlcnR5ICE9PSAnaW5oZXJpdCcpIHtcbiAgICAgICAgICAgIHJldHVybiBjb21wdXRlZFN0eWxlUHJvcGVydHlcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIElkZWFsbHkgZ2V0UHJvcGVydHlWYWx1ZSB3b3VsZCByZXR1cm4gdGhlICd1c2VkJyBvciAnYWN0dWFsJyB2YWx1ZSwgYnV0XG4gICAgICAgIC8vIGl0IGRvZXNuJ3QgZm9yIGxlZ2FjeSByZWFzb25zLiBTbyB3ZSBuZWVkIHRvIGRvIG91ciBvd24gcG9vciBtYW4ncyBjYXNjYWRlLlxuICAgICAgICAvLyBGYWxsIGJhY2sgdG8gdGhlIGZpcnN0IG5vbi0naW5oZXJpdCcgdmFsdWUgZm91bmQgaW4gYW4gYW5jZXN0b3IuXG4gICAgICAgIC8vIEluIGFueSBjYXNlLCBnZXRQcm9wZXJ0eVZhbHVlIHdpbGwgbm90IHJldHVybiAnaW5pdGlhbCcuXG5cbiAgICAgICAgLy8gRklYTUU6IHdpbGwgdGhpcyBpbmNvcnJlY3RseSBpbmhlcml0IG5vbi1pbmhlcml0YWJsZSBDU1MgcHJvcGVydGllcz9cbiAgICAgICAgLy8gSSB0aGluayBhbGwgaW1wb3J0YW50IG5vbi1pbmhlcml0YWJsZSBwcm9wZXJ0aWVzICh3aWR0aCwgaGVpZ2h0LCBldGMuKVxuICAgICAgICAvLyBmb3Igb3VyIHB1cnBvc2VzIGhlcmUgYXJlIHNwZWNpYWxseSByZXNvbHZlZCwgc28gdGhpcyBtYXkgbm90IGJlIGFuIGlzc3VlLlxuICAgICAgICAvLyBTcGVjaWZpY2F0aW9uIGlzIGhlcmU6IGh0dHBzOi8vZHJhZnRzLmNzc3dnLm9yZy9jc3NvbS8jcmVzb2x2ZWQtdmFsdWVzXG4gICAgICAgIGNvbnN0IHBhcmVudEVsZW1lbnQgPSBwYXJlbnRFbGVtZW50Rm9yRWxlbWVudChlbGVtZW50IGFzIEVsZW1lbnQpIGFzIFBhcmVudE5vZGVcbiAgICAgICAgcmV0dXJuIGNhc2NhZGVkU3R5bGVQcm9wZXJ0eUZvckVsZW1lbnQocGFyZW50RWxlbWVudCwgcHJvcGVydHkpXG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZWxlbWVudEhhc0JvdW5kaW5nQm94KGVsZW1lbnQ6IEVsZW1lbnQpOiBib29sZWFuIHtcbiAgICAgICAgY29uc3QgYm91bmRpbmdCb3ggPSBlbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpXG4gICAgICAgIHJldHVybiBib3VuZGluZ0JveC53aWR0aCA+IDAgJiYgYm91bmRpbmdCb3guaGVpZ2h0ID4gMFxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGVsZW1lbnRTdWJ0cmVlSGFzTm9uWmVyb0RpbWVuc2lvbnMoZWxlbWVudDogRWxlbWVudCk6IGJvb2xlYW4ge1xuICAgICAgICBpZiAoZWxlbWVudEhhc0JvdW5kaW5nQm94KGVsZW1lbnQpKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gUGF0aHMgY2FuIGhhdmUgYSB6ZXJvIHdpZHRoIG9yIGhlaWdodC4gVHJlYXQgdGhlbSBhcyBzaG93biBpZiB0aGUgc3Ryb2tlIHdpZHRoIGlzIHBvc2l0aXZlLlxuICAgICAgICBjb25zdCBib3VuZGluZ0JveCA9IGVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KClcbiAgICAgICAgaWYgKGVsZW1lbnQudGFnTmFtZS50b1VwcGVyQ2FzZSgpID09PSAnUEFUSCcgJiYgYm91bmRpbmdCb3gud2lkdGggKyBib3VuZGluZ0JveC5oZWlnaHQgPiAwKSB7XG4gICAgICAgICAgICBjb25zdCBzdHJva2VXaWR0aCA9IGNhc2NhZGVkU3R5bGVQcm9wZXJ0eUZvckVsZW1lbnQoZWxlbWVudCwgJ3N0cm9rZS13aWR0aCcpXG4gICAgICAgICAgICByZXR1cm4gISFzdHJva2VXaWR0aCAmJiAocGFyc2VJbnQoc3Ryb2tlV2lkdGgsIDEwKSA+IDApXG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBjYXNjYWRlZE92ZXJmbG93ID0gY2FzY2FkZWRTdHlsZVByb3BlcnR5Rm9yRWxlbWVudChlbGVtZW50LCAnb3ZlcmZsb3cnKVxuICAgICAgICBpZiAoY2FzY2FkZWRPdmVyZmxvdyA9PT0gJ2hpZGRlbicpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gSWYgdGhlIGNvbnRhaW5lcidzIG92ZXJmbG93IGlzIG5vdCBoaWRkZW4gYW5kIGl0IGhhcyB6ZXJvIHNpemUsIGNvbnNpZGVyIHRoZVxuICAgICAgICAvLyBjb250YWluZXIgdG8gaGF2ZSBub24temVybyBkaW1lbnNpb25zIGlmIGEgY2hpbGQgbm9kZSBoYXMgbm9uLXplcm8gZGltZW5zaW9ucy5cbiAgICAgICAgcmV0dXJuIFtdLnNvbWUuY2FsbChlbGVtZW50LmNoaWxkTm9kZXMsIGZ1bmN0aW9uIChjaGlsZE5vZGU6IEVsZW1lbnQpIHtcbiAgICAgICAgICAgIGlmIChjaGlsZE5vZGUubm9kZVR5cGUgPT09IE5vZGUuVEVYVF9OT0RFKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWVcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKG5vZGVJc0VsZW1lbnQoY2hpbGROb2RlKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBlbGVtZW50U3VidHJlZUhhc05vblplcm9EaW1lbnNpb25zKGNoaWxkTm9kZSlcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICAgIH0pXG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZWxlbWVudE92ZXJmbG93c0NvbnRhaW5lcihlbGVtZW50OiBFbGVtZW50KSB7XG4gICAgICAgIGNvbnN0IGNhc2NhZGVkT3ZlcmZsb3cgPSBjYXNjYWRlZFN0eWxlUHJvcGVydHlGb3JFbGVtZW50KGVsZW1lbnQsICdvdmVyZmxvdycpXG4gICAgICAgIGlmIChjYXNjYWRlZE92ZXJmbG93ICE9PSAnaGlkZGVuJykge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICAgIH1cblxuICAgICAgICAvLyBGSVhNRTogdGhpcyBuZWVkcyB0byB0YWtlIGludG8gYWNjb3VudCB0aGUgc2Nyb2xsIHBvc2l0aW9uIG9mIHRoZSBlbGVtZW50LFxuICAgICAgICAvLyB0aGUgZGlzcGxheSBtb2RlcyBvZiBpdCBhbmQgaXRzIGFuY2VzdG9ycywgYW5kIHRoZSBjb250YWluZXIgaXQgb3ZlcmZsb3dzLlxuICAgICAgICAvLyBTZWUgU2VsZW5pdW0ncyBib3QuZG9tLmdldE92ZXJmbG93U3RhdGUgYXRvbSBmb3IgYW4gZXhoYXVzdGl2ZSBsaXN0IG9mIGVkZ2UgY2FzZXMuXG4gICAgICAgIHJldHVybiB0cnVlXG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaXNFbGVtZW50U3VidHJlZUhpZGRlbkJ5T3ZlcmZsb3cgKGVsZW1lbnQ6IEVsZW1lbnQpOiBib29sZWFuIHtcbiAgICAgICAgaWYgKCFlbGVtZW50KSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghZWxlbWVudE92ZXJmbG93c0NvbnRhaW5lcihlbGVtZW50KSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIWVsZW1lbnQuY2hpbGROb2Rlcy5sZW5ndGgpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gVGhpcyBlbGVtZW50J3Mgc3VidHJlZSBpcyBoaWRkZW4gYnkgb3ZlcmZsb3cgaWYgYWxsIGNoaWxkIHN1YnRyZWVzIGFyZSBhcyB3ZWxsLlxuICAgICAgICByZXR1cm4gW10uZXZlcnkuY2FsbChlbGVtZW50LmNoaWxkTm9kZXMsIGZ1bmN0aW9uIChjaGlsZE5vZGU6IEVsZW1lbnQpIHtcbiAgICAgICAgICAgIC8vIFJldHVybnMgdHJ1ZSBpZiB0aGUgY2hpbGQgbm9kZSBpcyBvdmVyZmxvd2VkIG9yIG90aGVyd2lzZSBoaWRkZW4uXG4gICAgICAgICAgICAvLyBCYXNlIGNhc2U6IG5vdCBhbiBlbGVtZW50LCBoYXMgemVybyBzaXplLCBzY3JvbGxlZCBvdXQsIG9yIGRvZXNuJ3Qgb3ZlcmZsb3cgY29udGFpbmVyLlxuICAgICAgICAgICAgLy8gVmlzaWJpbGl0eSBvZiB0ZXh0IG5vZGVzIGlzIGNvbnRyb2xsZWQgYnkgcGFyZW50XG4gICAgICAgICAgICBpZiAoY2hpbGROb2RlLm5vZGVUeXBlID09PSBOb2RlLlRFWFRfTk9ERSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCFub2RlSXNFbGVtZW50KGNoaWxkTm9kZSkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoIWVsZW1lbnRTdWJ0cmVlSGFzTm9uWmVyb0RpbWVuc2lvbnMoY2hpbGROb2RlKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIFJlY3Vyc2UuXG4gICAgICAgICAgICByZXR1cm4gaXNFbGVtZW50U3VidHJlZUhpZGRlbkJ5T3ZlcmZsb3coY2hpbGROb2RlKVxuICAgICAgICB9KVxuICAgIH1cbiAgICAvLyB3YWxrIHVwIHRoZSB0cmVlIHRlc3RpbmcgZm9yIGEgc2hhZG93IHJvb3RcbiAgICBmdW5jdGlvbiBpc0VsZW1lbnRJbnNpZGVTaGFkb3dSb290IChlbGVtZW50OiBFbGVtZW50KTogYm9vbGVhbiB7XG4gICAgICAgIGlmICghZWxlbWVudCkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICAgIH1cbiAgICAgICAgaWYgKGVsZW1lbnQucGFyZW50Tm9kZSAmJiAoZWxlbWVudC5wYXJlbnROb2RlIGFzIFNoYWRvd1Jvb3QpLmhvc3QpIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlXG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGlzRWxlbWVudEluc2lkZVNoYWRvd1Jvb3QoZWxlbWVudC5wYXJlbnROb2RlIGFzIEVsZW1lbnQpXG4gICAgfVxuXG4gICAgLy8gVGhpcyBpcyBhIHBhcnRpYWwgcmVpbXBsZW1lbnRhdGlvbiBvZiBTZWxlbml1bSdzIFwiZWxlbWVudCBpcyBkaXNwbGF5ZWRcIiBhbGdvcml0aG0uXG4gICAgLy8gV2hlbiB0aGUgVzNDIHNwZWNpZmljYXRpb24ncyBhbGdvcml0aG0gc3RhYmlsaXplcywgd2Ugc2hvdWxkIGltcGxlbWVudCB0aGF0LlxuICAgIC8vIElmIHRoaXMgY29tbWFuZCBpcyBtaXNkaXJlY3RlZCB0byB0aGUgd3JvbmcgZG9jdW1lbnQgKGFuZCBpcyBOT1QgaW5zaWRlIGEgc2hhZG93IHJvb3QpLCB0cmVhdCBpdCBhcyBub3Qgc2hvd24uXG4gICAgaWYgKFxuICAgICAgICAhaXNFbGVtZW50SW5zaWRlU2hhZG93Um9vdChlbGVtZW50KSAmJlxuICAgICAgICAoXG4gICAgICAgICAgICAvLyBJRSBkb2Vzbid0IHN1cHBvcnQgZG9jdW1lbnQuY29udGFpbnMsIHRoZXJlZm9yIGNoZWNrIGJlZm9yZSB1c2luZ1xuICAgICAgICAgICAgdHlwZW9mIGRvY3VtZW50LmNvbnRhaW5zID09PSAnZnVuY3Rpb24nXG4gICAgICAgICAgICAgICAgPyAhZG9jdW1lbnQuY29udGFpbnMoZWxlbWVudClcbiAgICAgICAgICAgICAgICA6ICFkb2N1bWVudC5ib2R5LmNvbnRhaW5zKGVsZW1lbnQpXG4gICAgICAgIClcbiAgICApIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuXG4gICAgLy8gU3BlY2lhbCBjYXNlcyBmb3Igc3BlY2lmaWMgdGFnIG5hbWVzLlxuICAgIHN3aXRjaCAoZWxlbWVudC50YWdOYW1lLnRvVXBwZXJDYXNlKCkpIHtcbiAgICBjYXNlICdCT0RZJzpcbiAgICAgICAgcmV0dXJuIHRydWVcblxuICAgIGNhc2UgJ1NDUklQVCc6XG4gICAgY2FzZSAnTk9TQ1JJUFQnOlxuICAgICAgICByZXR1cm4gZmFsc2VcblxuICAgIGNhc2UgJ09QVEdST1VQJzpcbiAgICBjYXNlICdPUFRJT04nOiB7XG4gICAgICAgIC8vIE9wdGlvbi9vcHRncm91cCBhcmUgY29uc2lkZXJlZCBzaG93biBpZiB0aGUgY29udGFpbmluZyA8c2VsZWN0PiBpcyBzaG93bi5cbiAgICAgICAgY29uc3QgZW5jbG9zaW5nU2VsZWN0RWxlbWVudCA9IGVuY2xvc2luZ05vZGVPclNlbGZNYXRjaGluZ1ByZWRpY2F0ZShlbGVtZW50LCBmdW5jdGlvbiAoZTogRWxlbWVudCkge1xuICAgICAgICAgICAgcmV0dXJuIGUudGFnTmFtZS50b1VwcGVyQ2FzZSgpID09PSAnU0VMRUNUJ1xuICAgICAgICB9KVxuICAgICAgICByZXR1cm4gaXNFbGVtZW50RGlzcGxheWVkKGVuY2xvc2luZ1NlbGVjdEVsZW1lbnQgYXMgRWxlbWVudClcbiAgICB9XG4gICAgY2FzZSAnSU5QVVQnOlxuICAgICAgICAvLyA8aW5wdXQgdHlwZT1cImhpZGRlblwiPiBpcyBjb25zaWRlcmVkIG5vdCBzaG93bi5cbiAgICAgICAgaWYgKChlbGVtZW50IGFzIEhUTUxJbnB1dEVsZW1lbnQpLnR5cGUgPT09ICdoaWRkZW4nKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgICAgfVxuICAgICAgICBicmVha1xuICAgICAgICAvLyBjYXNlICdNQVAnOlxuICAgICAgICAvLyBGSVhNRTogU2VsZW5pdW0gaGFzIHNwZWNpYWwgaGFuZGxpbmcgZm9yIDxtYXA+IGVsZW1lbnRzLiBXZSBkb24ndCBkbyBhbnl0aGluZyBub3cuXG5cbiAgICBkZWZhdWx0OlxuICAgICAgICBicmVha1xuICAgIH1cblxuICAgIGlmIChjYXNjYWRlZFN0eWxlUHJvcGVydHlGb3JFbGVtZW50KGVsZW1lbnQsICd2aXNpYmlsaXR5JykgIT09ICd2aXNpYmxlJykge1xuICAgICAgICByZXR1cm4gZmFsc2VcbiAgICB9XG5cbiAgICBjb25zdCBoYXNBbmNlc3RvcldpdGhaZXJvT3BhY2l0eSA9ICEhZW5jbG9zaW5nRWxlbWVudE9yU2VsZk1hdGNoaW5nUHJlZGljYXRlKGVsZW1lbnQgYXMgSFRNTEVsZW1lbnQsIGZ1bmN0aW9uIChlOiBFbGVtZW50KSB7XG4gICAgICAgIHJldHVybiBOdW1iZXIoY2FzY2FkZWRTdHlsZVByb3BlcnR5Rm9yRWxlbWVudChlLCAnb3BhY2l0eScpKSA9PT0gMFxuICAgIH0pXG4gICAgY29uc3QgaGFzQW5jZXN0b3JXaXRoRGlzcGxheU5vbmUgPSAhIWVuY2xvc2luZ0VsZW1lbnRPclNlbGZNYXRjaGluZ1ByZWRpY2F0ZShlbGVtZW50IGFzIEhUTUxFbGVtZW50LCBmdW5jdGlvbiAoZTogRWxlbWVudCkge1xuICAgICAgICByZXR1cm4gY2FzY2FkZWRTdHlsZVByb3BlcnR5Rm9yRWxlbWVudChlLCAnZGlzcGxheScpID09PSAnbm9uZSdcbiAgICB9KVxuICAgIGlmIChoYXNBbmNlc3RvcldpdGhaZXJvT3BhY2l0eSB8fCBoYXNBbmNlc3RvcldpdGhEaXNwbGF5Tm9uZSkge1xuICAgICAgICByZXR1cm4gZmFsc2VcbiAgICB9XG5cbiAgICBpZiAoIWVsZW1lbnRTdWJ0cmVlSGFzTm9uWmVyb0RpbWVuc2lvbnMoZWxlbWVudCkpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuXG4gICAgaWYgKGlzRWxlbWVudFN1YnRyZWVIaWRkZW5CeU92ZXJmbG93KGVsZW1lbnQpICYmICFlbGVtZW50SGFzQm91bmRpbmdCb3goZWxlbWVudCkpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuXG4gICAgcmV0dXJuIHRydWVcbn1cbiJdLAogICJtYXBwaW5ncyI6ICI7QUE4QmUsU0FBUixtQkFBcUMsU0FBMkI7QUFDbkUsV0FBUyxjQUFjLE1BQWdCO0FBQ25DLFFBQUksQ0FBQyxNQUFNO0FBQ1AsYUFBTztBQUFBLElBQ1g7QUFFQSxZQUFRLEtBQUssVUFBVTtBQUFBLE1BQ3ZCLEtBQUssS0FBSztBQUFBLE1BQ1YsS0FBSyxLQUFLO0FBQUEsTUFDVixLQUFLLEtBQUs7QUFDTixlQUFPO0FBQUEsTUFFWDtBQUNJLGVBQU87QUFBQSxJQUNYO0FBQUEsRUFDSjtBQUVBLFdBQVMsd0JBQXdCQSxVQUFtQjtBQUNoRCxRQUFJLENBQUNBLFVBQVM7QUFDVixhQUFPO0FBQUEsSUFDWDtBQUVBLFdBQU8scUNBQXFDQSxTQUFRLFlBQTBCLGFBQWE7QUFBQSxFQUMvRjtBQUVBLFdBQVMscUNBQXFDLFlBQXNDLFdBQXFCO0FBQ3JHLGFBQ1EsT0FBbUIsWUFDdkIsUUFBUSxTQUFVLFdBQW9CLGVBQ3RDLE9BQVEsS0FBcUIsWUFDL0I7QUFDRSxVQUFJLFVBQVUsSUFBSSxHQUFHO0FBQ2pCLGVBQU87QUFBQSxNQUNYO0FBQUEsSUFDSjtBQUVBLFdBQU87QUFBQSxFQUNYO0FBRUEsV0FBUyx3Q0FBd0MsZUFBdUMsV0FBcUI7QUFDekcsYUFDUUEsV0FBb0MsZUFDeENBLFlBQVdBLGFBQVksY0FBYyxlQUNyQ0EsV0FBVSx3QkFBd0JBLFFBQXNCLEdBQzFEO0FBQ0UsVUFBSSxVQUFVQSxRQUFPLEdBQUc7QUFDcEIsZUFBT0E7QUFBQSxNQUNYO0FBQUEsSUFDSjtBQUVBLFdBQU87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