diff --git a/27.0/html/.gitkeep b/27.0/html/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/27.0/js/automation/WDElementAttribute.js b/27.0/js/automation/WDElementAttribute.js
new file mode 100644
index 0000000..37a223d
--- /dev/null
+++ b/27.0/js/automation/WDElementAttribute.js
@@ -0,0 +1,39 @@
+//# sourceURL=__InjectedScript_WDElementAttribute.js
+function(element){"use strict";var utils={};utils.enclosingNodeOrSelfMatchingPredicate=function(targetNode,predicate){for(let node=targetNode;node&&node!==targetNode.getRootNode();node=node.parentNode)
+if(predicate(node))
+return node;return null;}
+utils.nodeIsElement=function(node){return!!node&&node.nodeType===Node.ELEMENT_NODE;}
+utils.parentElementForElement=function(element){if(!element)
+return null;return utils.enclosingNodeOrSelfMatchingPredicate(element.parentNode,utils.nodeIsElement);}
+utils.cascadedStylePropertyForElement=function(element,property){if(!element||!property)
+return null;let computedStyle=window.getComputedStyle(element);let computedStyleProperty=computedStyle.getPropertyValue(property);if(computedStyleProperty&&computedStyleProperty!=="inherit")
+return computedStyleProperty;
+
+let parentElement=utils.parentElementForElement(element);return utils.cascadedStylePropertyForElement(parentElement,property);}
+utils.isShown=function(element){function enclosingElementOrSelfMatchingPredicate(targetElement,predicate){for(let element=targetElement;element&&element!==targetElement.getRootNode();element=utils.parentElementForElement(element))
+if(predicate(element))
+return element;return null;}
+function elementSubtreeHasNonZeroDimensions(element){let boundingBox=element.getBoundingClientRect();if(boundingBox.width>0&&boundingBox.height>0)
+return true;if(element.tagName.toUpperCase()==="PATH"&&boundingBox.width+boundingBox.height>0){let strokeWidth=utils.cascadedStylePropertyForElement(element,"stroke-width");return!!strokeWidth&&(parseInt(strokeWidth,10)>0);}
+let cascadedOverflow=utils.cascadedStylePropertyForElement(element,"overflow");if(cascadedOverflow==="hidden")
+return false;
+return Array.from(element.childNodes).some((childNode)=>{if(childNode.nodeType===Node.TEXT_NODE)
+return true;if(utils.nodeIsElement(childNode))
+return elementSubtreeHasNonZeroDimensions(childNode);return false;});}
+function elementOverflowsContainer(element){let cascadedOverflow=utils.cascadedStylePropertyForElement(element,"overflow");if(cascadedOverflow!=="hidden")
+return false;return true;}
+function isElementSubtreeHiddenByOverflow(element){if(!element)
+return false;if(!elementOverflowsContainer(element))
+return false;if(!element.childNodes.length)
+return false;return Array.from(element.childNodes).every((childNode)=>{if(!utils.nodeIsElement(childNode))
+return true;if(!elementSubtreeHasNonZeroDimensions(childNode))
+return true;return isElementSubtreeHiddenByOverflow(childNode);});}
+if(!(element instanceof Element))
+throw new Error("Cannot check the displayedness of a non-Element argument.");switch(element.tagName.toUpperCase()){case"BODY":return true;case"SCRIPT":case"NOSCRIPT":return false;case"OPTGROUP":case"OPTION":let enclosingSelectElement=utils.enclosingNodeOrSelfMatchingPredicate(element,(e)=>e.tagName.toUpperCase()==="SELECT");return utils.isShown(enclosingSelectElement);case"INPUT":if(element.type==="hidden")
+return false;break;case"MAP":default:break;}
+if(utils.cascadedStylePropertyForElement(element,"visibility")!=="visible")
+return false;let hasAncestorWithZeroOpacity=!!enclosingElementOrSelfMatchingPredicate(element,(e)=>{return Number(utils.cascadedStylePropertyForElement(e,"opacity"))===0;});let hasAncestorWithDisplayNone=!!enclosingElementOrSelfMatchingPredicate(element,(e)=>{return utils.cascadedStylePropertyForElement(e,"display")==="none";});if(hasAncestorWithZeroOpacity||hasAncestorWithDisplayNone)
+return false;if(!elementSubtreeHasNonZeroDimensions(element))
+return false;if(isElementSubtreeHiddenByOverflow(element))
+return false;return true;}
+return utils.isShown(element);}
diff --git a/27.0/js/automation/WDElementDisplayed.js b/27.0/js/automation/WDElementDisplayed.js
new file mode 100644
index 0000000..90d7c1e
--- /dev/null
+++ b/27.0/js/automation/WDElementDisplayed.js
@@ -0,0 +1,13 @@
+//# sourceURL=__InjectedScript_WDElementDisplayed.js
+function fetchTagNameAndAttributesOfElement(element) {
+ "use strict";
+ let tagName = element.tagName.toUpperCase();
+ let attributes = {};
+ for (let i = 0; i < element.attributes.length; ++i) {
+ let name = element.attributes[i].name.toLowerCase();
+ let value = element.attributes[i].value;
+ if (!value.length) value = null;
+ attributes[name] = value;
+ }
+ return { tagName, attributes };
+}
diff --git a/27.0/js/automation/WDElementFetchAttributes.js b/27.0/js/automation/WDElementFetchAttributes.js
new file mode 100644
index 0000000..8a6b6f1
--- /dev/null
+++ b/27.0/js/automation/WDElementFetchAttributes.js
@@ -0,0 +1,38 @@
+//# sourceURL=__InjectedScript_WDElementFetchAttributes.js
+function enterFullscreen() {
+ let callback = arguments[0];
+ if (!document.fullscreenEnabled) {
+ callback(false);
+ return;
+ }
+ if (document.fullscreenElement) {
+ callback(true);
+ return;
+ }
+ let fullscreenChangeListener, fullscreenErrorListener;
+ fullscreenChangeListener = (e) => {
+ if (e.target !== document.documentElement) return;
+ if (!document.fullscreenElement) return;
+ document.removeEventListener("fullscreenchange", fullscreenChangeListener);
+ document.documentElement.removeEventListener(
+ "fullscreenerror",
+ fullscreenErrorListener,
+ );
+ callback(true);
+ };
+ fullscreenErrorListener = (e) => {
+ if (e.target !== document.documentElement) return;
+ document.removeEventListener("fullscreenchange", fullscreenChangeListener);
+ document.documentElement.removeEventListener(
+ "fullscreenerror",
+ fullscreenErrorListener,
+ );
+ callback(!!document.fullscreenElement);
+ };
+ document.addEventListener("fullscreenchange", fullscreenChangeListener);
+ document.documentElement.addEventListener(
+ "fullscreenerror",
+ fullscreenErrorListener,
+ );
+ document.documentElement.requestFullscreen();
+}
diff --git a/27.0/js/automation/WDEnterFullscreen.js b/27.0/js/automation/WDEnterFullscreen.js
new file mode 100644
index 0000000..ce49f37
--- /dev/null
+++ b/27.0/js/automation/WDEnterFullscreen.js
@@ -0,0 +1,82 @@
+//# sourceURL=__InjectedScript_WDEnterFullscreen.js
+function(strategy,ancestorElement,query,firstResultOnly,timeoutDuration,callback){"use strict";var utils={};utils.enclosingNodeOrSelfMatchingPredicate=function(targetNode,predicate){for(let node=targetNode;node&&node!==targetNode.getRootNode();node=node.parentNode)
+if(predicate(node))
+return node;return null;}
+utils.nodeIsElement=function(node){return!!node&&node.nodeType===Node.ELEMENT_NODE;}
+utils.parentElementForElement=function(element){if(!element)
+return null;return utils.enclosingNodeOrSelfMatchingPredicate(element.parentNode,utils.nodeIsElement);}
+utils.cascadedStylePropertyForElement=function(element,property){if(!element||!property)
+return null;let computedStyle=window.getComputedStyle(element);let computedStyleProperty=computedStyle.getPropertyValue(property);if(computedStyleProperty&&computedStyleProperty!=="inherit")
+return computedStyleProperty;
+
+let parentElement=utils.parentElementForElement(element);return utils.cascadedStylePropertyForElement(parentElement,property);}
+utils.isShown=function(element){function enclosingElementOrSelfMatchingPredicate(targetElement,predicate){for(let element=targetElement;element&&element!==targetElement.getRootNode();element=utils.parentElementForElement(element))
+if(predicate(element))
+return element;return null;}
+function elementSubtreeHasNonZeroDimensions(element){let boundingBox=element.getBoundingClientRect();if(boundingBox.width>0&&boundingBox.height>0)
+return true;if(element.tagName.toUpperCase()==="PATH"&&boundingBox.width+boundingBox.height>0){let strokeWidth=utils.cascadedStylePropertyForElement(element,"stroke-width");return!!strokeWidth&&(parseInt(strokeWidth,10)>0);}
+let cascadedOverflow=utils.cascadedStylePropertyForElement(element,"overflow");if(cascadedOverflow==="hidden")
+return false;
+return Array.from(element.childNodes).some((childNode)=>{if(childNode.nodeType===Node.TEXT_NODE)
+return true;if(utils.nodeIsElement(childNode))
+return elementSubtreeHasNonZeroDimensions(childNode);return false;});}
+function elementOverflowsContainer(element){let cascadedOverflow=utils.cascadedStylePropertyForElement(element,"overflow");if(cascadedOverflow!=="hidden")
+return false;return true;}
+function isElementSubtreeHiddenByOverflow(element){if(!element)
+return false;if(!elementOverflowsContainer(element))
+return false;if(!element.childNodes.length)
+return false;return Array.from(element.childNodes).every((childNode)=>{if(!utils.nodeIsElement(childNode))
+return true;if(!elementSubtreeHasNonZeroDimensions(childNode))
+return true;return isElementSubtreeHiddenByOverflow(childNode);});}
+if(!(element instanceof Element))
+throw new Error("Cannot check the displayedness of a non-Element argument.");switch(element.tagName.toUpperCase()){case"BODY":return true;case"SCRIPT":case"NOSCRIPT":return false;case"OPTGROUP":case"OPTION":let enclosingSelectElement=utils.enclosingNodeOrSelfMatchingPredicate(element,(e)=>e.tagName.toUpperCase()==="SELECT");return utils.isShown(enclosingSelectElement);case"INPUT":if(element.type==="hidden")
+return false;break;case"MAP":default:break;}
+if(utils.cascadedStylePropertyForElement(element,"visibility")!=="visible")
+return false;let hasAncestorWithZeroOpacity=!!enclosingElementOrSelfMatchingPredicate(element,(e)=>{return Number(utils.cascadedStylePropertyForElement(e,"opacity"))===0;});let hasAncestorWithDisplayNone=!!enclosingElementOrSelfMatchingPredicate(element,(e)=>{return utils.cascadedStylePropertyForElement(e,"display")==="none";});if(hasAncestorWithZeroOpacity||hasAncestorWithDisplayNone)
+return false;if(!elementSubtreeHasNonZeroDimensions(element))
+return false;if(isElementSubtreeHiddenByOverflow(element))
+return false;return true;}
+utils.getText=function(element){var lines=[];function appendLinesFromTextNode(textNode,whitespace,textTransform){let text=textNode.nodeValue.replace(/[\u200b\u200e\u200f]/g,'');text=text.replace(/(\r\n|\r|\n)/g,'\n');let collapseAll=true;switch(whitespace){case"normal":case"nowrap":text=text.replace(/\n/g,' ');break;case"pre":case"pre-wrap":text=text.replace(/[ \f\t\v\u2028\u2029]/g,'\xa0');collapseAll=false;break;}
+if(collapseAll){text=text.replace(/[\ \f\t\v\u2028\u2029]+/g,' ');}
+switch(textTransform){case"capitalize":text=text.replace(/(^|[^\d\p{L}\p{S}])([\p{Ll}|\p{S}])/gu,function(){return arguments[1]+arguments[2].toUpperCase();});break;case"uppercase":text=text.toUpperCase();break;case"lowercase":text=text.toLowerCase();break;}
+let currentLine=lines.pop()||'';if(currentLine.endsWith(' ')&&text.startsWith(' '))
+text=text.substr(1);lines.push(currentLine+text);}
+function appendLinesFromNode(node,shown,whitespace,textTransform){switch(node.nodeType){case Node.TEXT_NODE:if(shown)
+appendLinesFromTextNode(node,whitespace,textTransform);break;case Node.ELEMENT_NODE:if(node.tagName.toUpperCase()=="SLOT"){let parentNode=node;while(parentNode.parentNode)
+parentNode=parentNode.parentNode;if(parentNode instanceof ShadowRoot){Array.from(node.assignedNodes()).forEach((childNode)=>{appendLinesFromNode(childNode,shown,whitespace,textTransform);});return;}}
+appendLinesFromElement(node);break;}}
+function appendLines(element){function currentLine(){return lines[lines.length-1]||'';}
+let isTableCell=false,display=null,isBlock=false;if(element.tagName.toUpperCase()==="BR")
+lines.push('');else{isTableCell=element.tagName.toUpperCase()==="TD";display=utils.cascadedStylePropertyForElement(element,"display");isBlock=!isTableCell&&!(display==="inline"||display==="inline-block"||display==="inline-table"||display==="none"||display==="table-cell"||display==="table-column"||display==="table-column-group");let previousElementSibling=element.previousElementSibling;let previousDisplay=previousElementSibling?utils.cascadedStylePropertyForElement(previousElementSibling,"display"):'';let elementFloat=utils.cascadedStylePropertyForElement(element,"float")||utils.cascadedStylePropertyForElement(element,"cssFloat");let runIntoThis=previousDisplay=="run-in"&&elementFloat=="none";if(isBlock&&!runIntoThis&&/^[\s\xa0]*$/.test(currentLine()))
+lines.push('');}
+let shown=utils.isShown(element);let whitespace=null,textTransform=null;if(shown){whitespace=utils.cascadedStylePropertyForElement(element,"white-space");textTransform=utils.cascadedStylePropertyForElement(element,"text-transform");}
+Array.from(element.childNodes).forEach((childNode)=>{if(!childNode.assignedSlot)
+appendLinesFromNode(childNode,shown,whitespace,textTransform);});let line=currentLine();if((isTableCell||display=="table-cell")&&line&&line.endsWith(' '))
+lines[lines.length-1]+=' ';if(isBlock&&display!="run-in"&&/^[\s\xa0]*$/.test(line))
+lines.push('');}
+function appendLinesFromElement(element){if(element.shadowRoot){Array.from(element.shadowRoot.childNodes).forEach((childNode)=>{appendLinesFromNode(childNode,true,null,null);});}
+appendLines(element);}
+appendLinesFromElement(element);lines=lines.map((str)=>str.replace(/^[^\S\xa0]+|[^\S\xa0]+$/g,''));let trimmed=lines.join('\n').replace(/^[^\S\xa0]+|[^\S\xa0]+$/g,'');return trimmed.replace(/\xa0/g,' ');}
+ancestorElement=ancestorElement||document;switch(strategy){case"id":strategy="css selector";query="[id=\""+escape(query)+"\"]";break;case"name":strategy="css selector";query="[name=\""+escape(query)+"\"]";break;}
+switch(strategy){case"css selector":case"link text":case"partial link text":case"tag name":case"class name":case"xpath":break;default:
+ throw{name:"InvalidParameter",message:("Unsupported locator strategy: "+strategy+".")};}
+function escape(string){return string.replace(/\\/g,"\\\\").replace(/"/g,"\\\"");}
+function tryToFindNode(){try{switch(strategy){case"css selector":if(firstResultOnly)
+return ancestorElement.querySelector(query)||null;return Array.from(ancestorElement.querySelectorAll(query));case"link text":let linkTextResult=[];for(let link of ancestorElement.querySelectorAll("a")){if(utils.getText(link).trim()==query){linkTextResult.push(link);if(firstResultOnly)
+break;}}
+if(firstResultOnly)
+return linkTextResult[0]||null;return linkTextResult;case"partial link text":let partialLinkResult=[];for(let link of ancestorElement.querySelectorAll("a")){if(utils.getText(link).includes(query)){partialLinkResult.push(link);if(firstResultOnly)
+break;}}
+if(firstResultOnly)
+return partialLinkResult[0]||null;return partialLinkResult;case"tag name":let tagNameResult=ancestorElement.getElementsByTagName(query);if(firstResultOnly)
+return tagNameResult[0]||null;return Array.from(tagNameResult);case"class name":let classNameResult=ancestorElement.getElementsByClassName(query);if(firstResultOnly)
+return classNameResult[0]||null;return Array.from(classNameResult);case"xpath":if(firstResultOnly){let xpathResult=document.evaluate(query,ancestorElement,null,XPathResult.FIRST_ORDERED_NODE_TYPE,null);if(!xpathResult)
+return null;return xpathResult.singleNodeValue;}
+let xpathResult=document.evaluate(query,ancestorElement,null,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null);if(!xpathResult||!xpathResult.snapshotLength)
+return[];let arrayResult=[];for(let i=0;i {
+ resultCallback(frameID, callbackID, this._jsonStringify(result));
+ })
+ .catch((error) => {
+ resultCallback(frameID, callbackID, error);
+ });
+ }
+ evaluateBidiScript(
+ expression,
+ awaitPromise,
+ maxObjectDepth,
+ frameID,
+ callbackID,
+ resultCallback,
+ callbackTimeout,
+ ) {
+ this._executeBidiScript(
+ expression,
+ awaitPromise,
+ maxObjectDepth,
+ callbackTimeout,
+ )
+ .then((result) => {
+ resultCallback(frameID, callbackID, JSON.stringify(result));
+ })
+ .catch((error) => {
+ resultCallback(frameID, callbackID, error);
+ });
+ }
+ nodeForIdentifier(identifier) {
+ this._clearStaleNodes();
+ try {
+ return this._nodeForIdentifier(identifier);
+ } catch (error) {
+ return null;
+ }
+ }
+ _execute(
+ functionString,
+ argumentStrings,
+ expectsImplicitCallbackArgument,
+ callbackTimeout,
+ ) {
+ let timeoutPromise;
+ let timeoutIdentifier = 0;
+ if (callbackTimeout >= 0) {
+ timeoutPromise = new Promise((resolve, reject) => {
+ timeoutIdentifier = setTimeout(() => {
+ reject({
+ name: "JavaScriptTimeout",
+ message: `script timed out after ${callbackTimeout}ms`,
+ });
+ }, callbackTimeout);
+ });
+ }
+ let promise = new Promise((resolve, reject) => {
+ let lines = functionString.split("\n");
+ let prefixLines = [];
+ while (lines && lines[0].startsWith("//")) {
+ prefixLines.push(lines.shift());
+ }
+ functionString = lines.join("\n");
+ let prefix = prefixLines.join("\n");
+ if (prefix) prefix += "\n";
+ let functionValue = evaluate(prefix + "(async " + functionString + ")");
+ if (typeof functionValue !== "function")
+ reject(new TypeError("Script did not evaluate to a function."));
+ this._clearStaleNodes();
+ let argumentValues = argumentStrings.map(this._jsonParse, this);
+ if (expectsImplicitCallbackArgument) argumentValues.push(resolve);
+ let resultPromise = functionValue.apply(null, argumentValues);
+ let promises = [resultPromise];
+ if (timeoutPromise) promises.push(timeoutPromise);
+ Promise.race(promises)
+ .then((result) => {
+ if (!expectsImplicitCallbackArgument) {
+ resolve(result);
+ }
+ })
+ .catch((error) => {
+ reject(error);
+ });
+ });
+
+ let promises = [promise];
+ if (timeoutPromise) promises.push(timeoutPromise);
+ return Promise.race(promises).finally(() => {
+ if (timeoutIdentifier) {
+ clearTimeout(timeoutIdentifier);
+ }
+ });
+ }
+ _executeBidiScript(
+ expression,
+ awaitPromise,
+ maxObjectDepth,
+ callbackTimeout,
+ ) {
+ let timeoutPromise;
+ let timeoutIdentifier = 0;
+ if (callbackTimeout >= 0) {
+ timeoutPromise = new Promise((resolve, reject) => {
+ timeoutIdentifier = setTimeout(() => {
+ reject({
+ name: "JavaScriptTimeout",
+ message: `script timed out after ${callbackTimeout}ms`,
+ });
+ }, callbackTimeout);
+ });
+ }
+ let promise = new Promise((resolve, reject) => {
+ try {
+ let result = globalThis.eval(expression);
+ if (awaitPromise && result && typeof result.then === "function") {
+ result.then(
+ (value) => {
+ let serializedValue = this.serializeBidiRemoteValue(
+ value,
+ maxObjectDepth,
+ );
+ resolve({ success: true, result: serializedValue });
+ },
+ (error) => {
+ reject({
+ success: false,
+ error: {
+ name: error.name,
+ message: error.message,
+ stack: error.stack,
+ },
+ });
+ },
+ );
+ } else {
+ let serializedValue = this.serializeBidiRemoteValue(
+ result,
+ maxObjectDepth,
+ );
+ resolve({ success: true, result: serializedValue });
+ }
+ } catch (error) {
+ reject({
+ success: false,
+ error: {
+ name: error.name,
+ message: error.message,
+ stack: error.stack,
+ },
+ });
+ }
+ });
+ let promises = [promise];
+ if (timeoutPromise) promises.push(timeoutPromise);
+ return Promise.race(promises).finally(() => {
+ if (timeoutIdentifier) {
+ clearTimeout(timeoutIdentifier);
+ }
+ });
+ }
+ _jsonParse(string) {
+ if (!string) return undefined;
+ return JSON.parse(string, (key, value) =>
+ this._reviveJSONValue(key, value),
+ );
+ }
+ _jsonStringify(value) {
+ return JSON.stringify(this._jsonClone(value));
+ }
+ _reviveJSONValue(key, value) {
+ if (value && typeof value === "object" && value[sessionNodePropertyName])
+ return this._nodeForIdentifier(value[sessionNodePropertyName]);
+ return value;
+ }
+ _isCollection(value) {
+ switch (Object.prototype.toString.call(value)) {
+ case "[object Arguments]":
+ case "[object Array]":
+ case "[object FileList]":
+ case "[object HTMLAllCollection]":
+ case "[object HTMLCollection]":
+ case "[object HTMLFormControlsCollection]":
+ case "[object HTMLOptionsCollection]":
+ case "[object NodeList]":
+ return true;
+ }
+ return false;
+ }
+ _checkCyclic(value, stack = []) {
+ function isCyclic(value, proxy, stack = []) {
+ if (value === undefined || value === null) return false;
+ if (
+ typeof value === "boolean" ||
+ typeof value === "number" ||
+ typeof value === "string"
+ )
+ return false;
+ if (value instanceof Node) return false;
+ if (stack.includes(value)) return true;
+ if (proxy._isCollection(value)) {
+ stack.push(value);
+ for (let i = 0; i < value.length; i++) {
+ if (isCyclic(value[i], proxy, stack)) return true;
+ }
+ stack.pop();
+ return false;
+ }
+ stack.push(value);
+ for (let property in value) {
+ if (isCyclic(value[property], proxy, stack)) return true;
+ }
+ stack.pop();
+ return false;
+ }
+ if (isCyclic(value, this))
+ throw new TypeError("cannot serialize cyclic structures.");
+ }
+ _jsonClone(value) {
+ if (value === undefined || value === null) return null;
+ if (
+ typeof value === "boolean" ||
+ typeof value === "number" ||
+ typeof value === "string"
+ )
+ return value;
+ if (this._isCollection(value)) {
+ this._checkCyclic(value);
+ return [...value].map((item) => this._jsonClone(item));
+ }
+ if (value instanceof Node) return this._createNodeHandle(value);
+ if (typeof value.toJSON === "function") return value.toJSON();
+ let customObject = {};
+ for (let property in value) {
+ this._checkCyclic(value);
+ customObject[property] = this._jsonClone(value[property]);
+ }
+ return customObject;
+ }
+ _createNodeHandle(node) {
+ if (node.ownerDocument !== window.document || !node.isConnected)
+ throw {
+ name: "NodeNotFound",
+ message: "Stale element found when trying to create the node handle",
+ };
+ return { [sessionNodePropertyName]: this._identifierForNode(node) };
+ }
+ _nodeForIdentifier(identifier) {
+ if (!isValidNodeIdentifier(identifier))
+ throw {
+ name: "InvalidNodeIdentifier",
+ message: "Node identifier '" + identifier + "' is invalid",
+ };
+ let node = this._idToNodeMap.get(identifier);
+ if (node) return node;
+ throw {
+ name: "NodeNotFound",
+ message: "Node with identifier '" + identifier + "' was not found",
+ };
+ }
+ _identifierForNode(node) {
+ let identifier = this._nodeToIdMap.get(node);
+ if (identifier) return identifier;
+ identifier = "node-" + createUUID();
+ this._nodeToIdMap.set(node, identifier);
+ this._idToNodeMap.set(identifier, node);
+ return identifier;
+ }
+ _clearStaleNodes() {
+ for (var [node, identifier] of this._nodeToIdMap) {
+ const rootNode = node.getRootNode({ composed: true });
+ if (rootNode !== document) {
+ this._nodeToIdMap.delete(node);
+ this._idToNodeMap.delete(identifier);
+ }
+ }
+ }
+ serializeBidiRemoteValue(
+ value,
+ maxObjectDepth = 1,
+ depth = 0,
+ visitedObjects = new Set(),
+ ) {
+ if (value === null) return { type: "null" };
+ if (value === undefined) return { type: "undefined" };
+ if (typeof value === "boolean") return { type: "boolean", value: value };
+ if (typeof value === "string") return { type: "string", value: value };
+ if (typeof value === "number") {
+ if (isNaN(value)) return { type: "number", value: "NaN" };
+ if (value === Infinity) return { type: "number", value: "Infinity" };
+ if (value === -Infinity) return { type: "number", value: "-Infinity" };
+ if (Object.is(value, -0)) return { type: "number", value: "-0" };
+ return { type: "number", value: value };
+ }
+ if (typeof value === "bigint")
+ return { type: "bigint", value: value.toString() };
+ if (typeof value === "symbol") return { type: "symbol" };
+ if (typeof value === "function") return { type: "function" };
+ if (typeof value === "object" || typeof value === "function") {
+ if (value === window)
+ return {
+ type: "window",
+ value: { context: "context-id-placeholder" },
+ };
+ if (value instanceof Date)
+ return { type: "date", value: value.toISOString() };
+ if (value instanceof RegExp)
+ return {
+ type: "regexp",
+ value: { pattern: value.source, flags: value.flags },
+ };
+ if (value instanceof Error) return { type: "error" };
+ if (value instanceof Promise) return { type: "promise" };
+ if (value instanceof Map) {
+ let entries = [];
+ for (let [k, v] of value.entries()) {
+ entries.push({
+ key: this.serializeBidiRemoteValue(
+ k,
+ maxObjectDepth,
+ depth + 1,
+ visitedObjects,
+ ),
+ value: this.serializeBidiRemoteValue(
+ v,
+ maxObjectDepth,
+ depth + 1,
+ visitedObjects,
+ ),
+ });
+ }
+ return { type: "map", value: entries };
+ }
+ if (value instanceof Set) {
+ let items = [];
+ for (let v of value.values())
+ items.push(
+ this.serializeBidiRemoteValue(
+ v,
+ maxObjectDepth,
+ depth + 1,
+ visitedObjects,
+ ),
+ );
+ return { type: "set", value: items };
+ }
+ if (value instanceof WeakMap) return { type: "weakmap" };
+ if (value instanceof WeakSet) return { type: "weakset" };
+ if (value instanceof ArrayBuffer) return { type: "arraybuffer" };
+ if (ArrayBuffer.isView(value)) return { type: "typedarray" };
+ if (visitedObjects.has(value)) return { type: "object", value: {} };
+ if (depth >= maxObjectDepth) return { type: "object", value: {} };
+ visitedObjects.add(value);
+ try {
+ if (Array.isArray(value)) {
+ let serializedArray = [];
+ for (let i = 0; i < value.length; i++) {
+ serializedArray[i] = this.serializeBidiRemoteValue(
+ value[i],
+ maxObjectDepth,
+ depth + 1,
+ visitedObjects,
+ );
+ }
+ return { type: "array", value: serializedArray };
+ } else {
+ let serializedObject = {};
+ let keys = Object.keys(value).sort();
+ for (let i = 0; i < keys.length; ++i) {
+ let key = keys[i];
+ serializedObject[key] = this.serializeBidiRemoteValue(
+ value[key],
+ maxObjectDepth,
+ depth + 1,
+ visitedObjects,
+ );
+ }
+ return { type: "object", value: serializedObject };
+ }
+ } finally {
+ visitedObjects.delete(value);
+ }
+ }
+ return { type: "undefined" };
+ }
+ };
+ return new AutomationSessionProxy();
+});
diff --git a/27.0/js/forms/AutoFillBootstrapper.js b/27.0/js/forms/AutoFillBootstrapper.js
new file mode 100644
index 0000000..374df5c
--- /dev/null
+++ b/27.0/js/forms/AutoFillBootstrapper.js
@@ -0,0 +1,177 @@
+//# sourceURL=__InjectedScript_AutoFillBootstrapper.js
+/* Copyright (c) 2026 Apple Inc. All rights reserved. */
+"use strict";
+function initAutoFillBootstrapper() {
+ function e(e) {
+ return (
+ e.isContentEditable && "textbox" === e.role && "true" !== e.ariaMultiLine
+ );
+ }
+ function t(t) {
+ if (t instanceof HTMLTextAreaElement) return !0;
+ if (e(t)) return !0;
+ if (!(t instanceof HTMLInputElement)) return !1;
+ const n = {
+ date: !0,
+ "datetime-local": !0,
+ email: !0,
+ isindex: !0,
+ month: !0,
+ number: !0,
+ password: !0,
+ search: !0,
+ tel: !0,
+ telephone: !0,
+ text: !0,
+ time: !0,
+ url: !0,
+ week: !0,
+ };
+ var a = t.type;
+ return !a || a in n;
+ }
+ function n(e) {
+ const n = e.composedPath()[0];
+ return t(n) ? n : null;
+ }
+ function a(e) {
+ const n = e.composedPath()[0];
+ return !t(n) || n instanceof HTMLTextAreaElement ? null : n;
+ }
+ class i {
+ #e = [];
+ #t = null;
+ #n(e) {
+ switch (e.type) {
+ case "webkitsubmit":
+ return e.target;
+ case "webkitautofillrequest":
+ case "webkitbeforefocus":
+ case "webkitbeforeblur":
+ case "keydown":
+ return a(e);
+ case "webkitusertextinput":
+ return n(e);
+ default:
+ return null;
+ }
+ }
+ processAndEnqueue(e, t = !0) {
+ const n = this.#n(e);
+ if (!n) return;
+ let a = null;
+ "keydown" === e.type && (a = { key: e.key, shiftKey: e.shiftKey });
+ const i = { target: n, type: e.type, data: a };
+ this.#t
+ ? this.#t.dispatchEvent(i)
+ : (this.#e.push(i), t && o.scheduleIfNeeded());
+ }
+ setDelegate(e) {
+ this.#t = e;
+ for (const e of this.#e) this.#t.dispatchEvent(e);
+ this.#e.length = 0;
+ }
+ }
+ globalThis.eventQueue = new i();
+ class s {
+ #a = null;
+ #i = !1;
+ scheduleIfNeeded() {
+ this.#i ||
+ this.#a ||
+ ("complete" === document.readyState
+ ? this.requestImmediately()
+ : (this.#a = setTimeout(this.requestImmediately.bind(this), 100)));
+ }
+ requestImmediately() {
+ if (this.#i) return;
+ if (((this.#i = !0), (this.#a = null), !window.webkit.evaluateScript))
+ return void window.webkit.messageHandlers.controller.postMessage({
+ name: "loadMainScriptRequest",
+ });
+ const e = {
+ "safari://FormMetadataContactsAutoFillMappings.js":
+ window.webkit.buffers.FormMetadataContactsAutoFillMappings,
+ "safari://passwordRulesParserJS.js":
+ window.webkit.buffers.PasswordRulesParserJS,
+ "safari://PatternRegexpToPasswordRulesConverter.js":
+ window.webkit.buffers.PatternRegexpToPasswordRulesConverter,
+ "safari://FormMetadataClassification.js":
+ window.webkit.buffers.FormMetadataClassification,
+ "safari://FormMetadata.js": window.webkit.buffers.FormMetadata,
+ "safari://FormMetadataJSController.js":
+ window.webkit.buffers.FormMetadataJSController,
+ "safari://FormMetadataUtilities.js":
+ window.webkit.buffers.FormMetadataUtilities,
+ "safari://AutomaticPasswords.js":
+ window.webkit.buffers.AutomaticPasswords,
+ };
+ window.webkit.buffers.NodePath &&
+ (e["safari://NodePath.js"] = window.webkit.buffers.NodePath);
+ for (const t in e) {
+ let n = e[t].asLatin1String();
+ (AutoFillControllerConfig.isEngineeringBuild &&
+ (n = new TextDecoder("utf8").decode(
+ new Uint8Array([...n].map((e) => e.codePointAt(0))),
+ )),
+ window.webkit.evaluateScript(n, t));
+ }
+ }
+ }
+ const o = new s();
+ ((globalThis.evaluateMainScripts = function () {
+ o.requestImmediately();
+ }),
+ (globalThis.addGlobalEventHandler = function (e, t, n = !1, a = !1) {
+ const i = [];
+ (n &&
+ i.push(function (t) {
+ return function (n) {
+ const i = n;
+ window.addEventListener(
+ e,
+ function (e) {
+ e === i && (e.defaultPrevented || t(e));
+ },
+ { once: !0, capture: !1, webkitTrustedOnly: a },
+ );
+ };
+ }),
+ e.startsWith("webkit") &&
+ i.push(function (e) {
+ return function (t) {
+ (t.stopImmediatePropagation(), e(t));
+ };
+ }));
+ let s = t;
+ for (const e of i) s = e(s);
+ window.addEventListener(e, s, { capture: !0, webkitTrustedOnly: a });
+ }),
+ (globalThis.addEventListeners = function () {
+ (addGlobalEventHandler("webkitbeforefocus", (e) =>
+ eventQueue.processAndEnqueue(e, AutoFillControllerConfig.isMac),
+ ),
+ addGlobalEventHandler("webkitbeforeblur", (e) =>
+ eventQueue.processAndEnqueue(e),
+ ),
+ addGlobalEventHandler("webkitusertextinput", (e) =>
+ eventQueue.processAndEnqueue(e),
+ ),
+ addGlobalEventHandler(
+ "keydown",
+ (e) => eventQueue.processAndEnqueue(e),
+ !0,
+ !0,
+ ),
+ addGlobalEventHandler("webkitsubmit", (e) =>
+ eventQueue.processAndEnqueue(e),
+ ),
+ addGlobalEventHandler("webkitautofillrequest", (e) =>
+ eventQueue.processAndEnqueue(e),
+ ));
+ }));
+}
+(void 0 === globalThis.autoFillBootstrapperInited &&
+ (initAutoFillBootstrapper(), (globalThis.autoFillBootstrapperInited = !0)),
+ globalThis.addEventListeners());
+0;
diff --git a/27.0/js/forms/AutomaticPasswords.js b/27.0/js/forms/AutomaticPasswords.js
new file mode 100644
index 0000000..d9cc42a
--- /dev/null
+++ b/27.0/js/forms/AutomaticPasswords.js
@@ -0,0 +1,31 @@
+//# sourceURL=__InjectedScript_AutomaticPasswords.js
+/* Copyright (c) 2026 Apple Inc. All rights reserved. */
+"use strict";
+class AutomaticPasswords {
+ removeAutomaticPasswordElements(t, e, o) {
+ for (let e of t)
+ FormMetadataJS.removeAutomaticStrongPasswordFromPasswordElement(e);
+ if (!o) return;
+ let r = document.activeElement,
+ a = e ? FormMetadataJS.formControlWithUniqueID(e) : null;
+ (a && a.blur(), a && a === r && a.focus());
+ }
+ blurControlWithID(t) {
+ let e = t ? FormMetadataJS.formControlWithUniqueID(t) : null;
+ e && e.blur();
+ }
+ setStrongPasswordElementViewableIfAppropriate(t, e) {
+ for (let o of t) {
+ let t = FormMetadataJS.formControlWithUniqueID(o);
+ if (!t) return;
+ if ("text" === t.type)
+ return (
+ FormMetadataJSController.setInputElementAutoFilledAndViewable(t, !1),
+ void FormMetadataJSController.setInputElementAutofilled(t, !1)
+ );
+ FormMetadataJSController.setInputElementAutoFilledAndViewable(t, e);
+ }
+ }
+}
+var AutomaticPasswordsJS = new AutomaticPasswords();
+0;
diff --git a/27.0/js/forms/FormMetadata.js b/27.0/js/forms/FormMetadata.js
new file mode 100644
index 0000000..d820ef8
--- /dev/null
+++ b/27.0/js/forms/FormMetadata.js
@@ -0,0 +1,5570 @@
+//# sourceURL=__InjectedScript_FormMetadata.js
+/* Copyright (c) 2026 Apple Inc. All rights reserved. */
+"use strict";
+function addPasswordRequirementsToFormMetadata(e) {
+ if (
+ e.AutoFillFormType != WBSAutoFillFormTypeNewAccount &&
+ e.AutoFillFormType != WBSAutoFillFormTypeChangePassword
+ )
+ return ((e.PasswordRules = null), void (e.PasswordRequirements = null));
+ const t = e.PasswordElementUniqueID,
+ r = e.ConfirmPasswordElementUniqueID;
+ let o = !!t?.length,
+ n = !!r?.length;
+ if (!o && !n)
+ return ((e.PasswordRules = null), void (e.PasswordRequirements = null));
+ let i = null,
+ l = null;
+ for (const a of e.FormControls) {
+ if (!o && !n) break;
+ const e = a.ControlUniqueID;
+ e &&
+ (o && e === t
+ ? ((i = a), (o = !1))
+ : n && e === r && ((l = a), (n = !1)));
+ }
+ let a,
+ s = null,
+ u = null;
+ if (i?.ControlPasswordRules) {
+ const e = parsePasswordRules(i?.ControlPasswordRules, !1);
+ s = new PasswordRuleSet(e);
+ }
+ if (l?.ControlPasswordRules) {
+ const e = parsePasswordRules(l?.ControlPasswordRules, !1);
+ u = new PasswordRuleSet(e);
+ }
+ s && u ? ((a = s.copy()), a.merge(u)) : (a = s || u);
+ let c = i?.ControlMaxLength ?? 0,
+ d = i?.ControlMinLength ?? 0;
+ const h = l?.ControlMaxLength ?? 0,
+ m = l?.ControlMinLength ?? 0;
+ ((c = c < h ? c : h), (d = d > m ? d : m));
+ const F = { passwordRuleSet: a, minLength: d, maxLength: c },
+ f = {};
+ (i &&
+ ((f.passwordFieldPasswordRules = i.ControlPasswordRules),
+ (f.passwordFieldMinLength = i.ControlMinLength),
+ (f.passwordFieldMaxLength = i.ControlMaxLength)),
+ l &&
+ ((f.confirmPasswordFieldPasswordRules = l.ControlPasswordRules),
+ (f.confirmPasswordFieldMinLength = l.ControlMinLength),
+ (f.confirmPasswordFieldMaxLength = l.ControlMaxLength)),
+ (e.PasswordRules = f),
+ (e.PasswordRequirements = F));
+}
+function invalidateVisibilityCache() {
+ visibilityCacheGeneration++;
+}
+function regularExpressionForDomainMatching(e) {
+ return new RegExp("(^|.)" + e.replaceAll(".", "\\.") + "$");
+}
+function userIsOnDomain(e) {
+ let t = cachedUserIsOnDomain[e];
+ return (
+ void 0 !== t ||
+ ((t = regularExpressionForDomainMatching(e).test(
+ document.location.hostname,
+ )),
+ (cachedUserIsOnDomain[e] = t)),
+ t
+ );
+}
+function legacyPlaceholderInfoForInputElement(e) {
+ if ("text" !== e.type) return null;
+ if (doctypeLooksLikeHTML5) return null;
+ var t = e.af_value().trim();
+ if (!t) return null;
+ for (var r = !1, o = !0, n = e.attributes, i = n.length, l = 0; l < i; ++l) {
+ var a = n[l];
+ if (t === a.value.trim() && ((r = !0), "value" !== a.name.toLowerCase())) {
+ o = !1;
+ break;
+ }
+ }
+ return r ? { Text: t, AttributeMatchedWasValue: o } : null;
+}
+function placeholderInfoForElement(e) {
+ var t = e.getAttribute("placeholder");
+ if (t) return { Text: t, AttributeMatchedWasValue: !1 };
+ var r = e.getAttribute("data-placeholder");
+ return r && r.length
+ ? { Text: r, AttributeMatchedWasValue: !1 }
+ : isInputElement(e)
+ ? legacyPlaceholderInfoForInputElement(e)
+ : null;
+}
+function sharedPrefixLength(e, t) {
+ for (var r = 0, o = 0, n = e.length; o < n && e[o] === t[o]; ++o) r++;
+ return r;
+}
+function rowContainingLabelAboveRow(e) {
+ for (
+ var t = e.getBoundingClientRect(), r = e.previousElementSibling;
+ r instanceof HTMLTableRowElement;
+ r = r.previousElementSibling
+ ) {
+ if (r.querySelector("input, select, textarea")) return null;
+ var o = r.getBoundingClientRect();
+ if (t.top - o.bottom > t.height / 2) return null;
+ if (r.innerText.match(/\S/)) return r;
+ }
+ return null;
+}
+function cellVisuallyAbove(e) {
+ let t = e.parentElementIncludingShadowDOMHost();
+ if (!(t && t instanceof HTMLTableRowElement)) return null;
+ var r = rowContainingLabelAboveRow(t);
+ if (!r) return null;
+ for (
+ var o = e.getBoundingClientRect(),
+ n = r.children,
+ i = n.length,
+ l = null,
+ a = 0,
+ s = 0;
+ s < i;
+ ++s
+ ) {
+ var u = n[s],
+ c = u.getBoundingClientRect(),
+ d = Math.min(c.right, o.right) - Math.max(c.left, o.left);
+ (!l || d > a) && ((a = d), (l = u));
+ }
+ return l;
+}
+function couldBeFormSubmissionControl(e) {
+ if (e instanceof HTMLButtonElement) return !0;
+ if (e instanceof HTMLInputElement) {
+ var t = e.type;
+ return "submit" === t || "image" === t;
+ }
+ return !1;
+}
+function elementsInFormPiercingShadowDOM(e) {
+ e.elements;
+ return queryAllBySelector(
+ e,
+ "button, fieldset, input:not([type='image']), object, output, select, textarea",
+ );
+}
+function isInputElement(e) {
+ return e instanceof HTMLInputElement;
+}
+function isDateTimeInputElement(e) {
+ return !!isInputElement(e) && DateTimeInputTypes.includes(e.type);
+}
+function isRadioButtonElement(e) {
+ return !!isInputElement(e) && "radio" === e.type;
+}
+function isSelectElement(e) {
+ return e instanceof HTMLSelectElement;
+}
+function isContentEditableSingleLineTextbox(e) {
+ return (
+ e.isContentEditable && "textbox" === e.role && "true" !== e.ariaMultiLine
+ );
+}
+function anchorWithURLString(e) {
+ var t = document.createElement("a");
+ return ((t.href = e), t);
+}
+function pathComponentsForLocation(e) {
+ var t = e.pathname.substring(1).split("/");
+ return (t[t.length - 1] || t.pop(), t);
+}
+function lastPathComponentFromAnchor(e) {
+ var t = pathComponentsForLocation(e);
+ return t.length ? t[t.length - 1] : null;
+}
+function lastPathComponentForURLString(e) {
+ return lastPathComponentFromAnchor(anchorWithURLString(e));
+}
+function urlEncode(e) {
+ return encodeURIComponent(e).replace(/%20/g, "+");
+}
+function isCheckboxOrRadioButtonInDefaultState(e) {
+ return e.checked === e.defaultChecked;
+}
+function isSelectInDefaultState(e) {
+ for (var t = e.options, r = t.length, o = 0; o < r; ++o) {
+ var n = t[o];
+ if (n.selected !== n.defaultSelected) {
+ if (n.defaultSelected) return !1;
+ if (e.multiple || o) return !1;
+ }
+ }
+ return !0;
+}
+function formActionAsAnchorElement(e, t) {
+ if (!(e instanceof HTMLFormElement)) return null;
+ let r = e.getAttribute("action");
+ if (!r && t) return null;
+ var o = document.createElement("a");
+ return ((o.href = r || ""), o);
+}
+function createTextInputEvent(e) {
+ let t = document.createEvent("TextEvent");
+ return (t.initTextEvent("textInput", !0, !0, null, e), t);
+}
+function createMouseOrPointerEventAtPoint(e, t) {
+ const r = {
+ bubbles: !0,
+ cancelable: !0,
+ screenX: t.x,
+ screenY: t.y,
+ clientX: t.x,
+ clientY: t.y,
+ button: 0,
+ detail: 1,
+ };
+ switch (e) {
+ case "mousedown":
+ case "mouseup":
+ return new MouseEvent(e, { ...r, buttons: "mousedown" === e ? 1 : 0 });
+ case "pointerdown":
+ case "pointerup":
+ case "click":
+ const t = "pointerdown" === e;
+ return new PointerEvent(e, {
+ ...r,
+ buttons: t ? 1 : 0,
+ pointerType: "mouse",
+ isPrimary: !0,
+ pressure: t ? 0.5 : 0,
+ altitudeAngle: Math.PI / 2,
+ });
+ }
+}
+function dispatchEventsSimulatingClickOnElement(e) {
+ const t = e.getBoundingClientRect().centerPoint();
+ e.dispatchEvent(createMouseOrPointerEventAtPoint("pointerdown", t)) &&
+ e.dispatchEvent(createMouseOrPointerEventAtPoint("mousedown", t)) &&
+ e.dispatchEvent(createMouseOrPointerEventAtPoint("pointerup", t)) &&
+ e.dispatchEvent(createMouseOrPointerEventAtPoint("mouseup", t)) &&
+ e.dispatchEvent(createMouseOrPointerEventAtPoint("pointerdown", t));
+}
+function createCustomEventThatBubbles(e) {
+ return new CustomEvent(e, { bubbles: !0 });
+}
+function formControlHasBeenClassifiedInAnInterestingWay(e) {
+ return (
+ e.ControlIsActiveElement ||
+ e.ControlIsSecureTextField ||
+ e.ControlLooksLikePasswordCredentialField ||
+ e.ControlLooksLikeCreditCardNumberField ||
+ e.ControlLooksLikeCreditCardSecurityCodeField ||
+ e.ControlLooksLikeCreditCardCardholderField ||
+ e.ControlLooksLikeCreditCardTypeField ||
+ e.AddressBookLabel ||
+ e.ControlLooksLikeDayField ||
+ e.ControlLooksLikeMonthField ||
+ e.ControlLooksLikeYearField ||
+ e.ControlLooksLikeOneTimeCodeField ||
+ e.ControlLooksLikeCreditCardCompositeExpirationDateField ||
+ e.ControlLooksLikeEIDField ||
+ e.ControlLooksLikeIMEIField ||
+ e.ControlLooksLikeIMEI1Field ||
+ e.ControlLooksLikeIMEI2Field ||
+ e.ControlLooksLikeNALField
+ );
+}
+function isValidUsernameOrEmail(e) {
+ const t = /^[a-z_][a-z0-9_.]{2,30}$/i,
+ r = /^[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,4}$/i;
+ return (
+ !(!e || e.length < 3 || "true" === e || "false" === e) &&
+ (t.test(e) || r.test(e))
+ );
+}
+function selectorForElement(e) {
+ let t = e.localName,
+ r = e.getAttribute("id");
+ r && (t += `#${r}`);
+ let o = e.classList,
+ n = o.length;
+ for (let e = 0; e < n; e++) t += "." + o[e];
+ return t;
+}
+function controlIsPartOfSingleCharacterLogicalField(e) {
+ return !!allControlsForSingleCharacterLogicalFieldForControl(e).length;
+}
+function allControlsForSingleCharacterLogicalFieldForControl(e) {
+ let t = siblingsIncludingSelfForElement(e);
+ if (checkIfControlsAreASingleCharacterLogicalField(t)) return Array.from(t);
+ const r = e._weakNextControlInLogicalForm?.deref();
+ if (r) {
+ const o = e.closestCommonAncestor(r);
+ if (
+ o &&
+ ((t = queryAllBySelector(o, e.localName)),
+ checkIfControlsAreASingleCharacterLogicalField(t))
+ )
+ return Array.from(t);
+ }
+ return [];
+}
+function checkIfControlsAreASingleCharacterLogicalField(e) {
+ const t = 4,
+ r = 8,
+ o = e.length;
+ if (o < t || o > r) return !1;
+ const n = e[0].getBoundingClientRect();
+ for (let t = 1; t < o; ++t) {
+ const r = e[t].getBoundingClientRect();
+ if (
+ Math.abs(n.top - r.top) > 0.5 ||
+ n.width !== r.width ||
+ n.height !== r.height
+ )
+ return !1;
+ }
+ return !0;
+}
+async function yieldToEventLoop(e = 0) {
+ await new Promise((t) => {
+ setTimeout(t, e);
+ });
+}
+async function yieldToEventLoopAfterAnimationFrameAndDelay(e = 0) {
+ (await Promise.all([
+ yieldToEventLoop(e),
+ new Promise((e) => {
+ requestAnimationFrame(e);
+ }),
+ ]),
+ await yieldToEventLoop());
+}
+async function yieldUntilDocumentIsFocusedOrTimeout(e) {
+ document.hasFocus() || yieldUntilEventOrTimeout("focus", e);
+}
+async function yieldUntilEventOrTimeout(
+ e,
+ t,
+ { eventTargetToIgnore: r, requireEventTargetBeDocumentActiveElement: o } = {},
+) {
+ const n = new AbortController();
+ let i;
+ (await Promise.race([
+ new Promise((e) => {
+ i = setTimeout(e, t);
+ }),
+ new Promise((t) => {
+ window.addEventListener(
+ e,
+ (e) => {
+ let n = innermostActiveElement(e.target);
+ (r && n === r) || (o && n !== innermostActiveElement()) || t();
+ },
+ { passive: !0, signal: n.signal },
+ );
+ }),
+ ]),
+ clearTimeout(i),
+ n.abort(null));
+}
+function hasOwnProperties(e) {
+ return Object.getOwnPropertyNames(e).length > 0;
+}
+function defaultOptionForSelectElement(e) {
+ for (var t = e.options, r = t.length, o = 0; o < r; ++o) {
+ var n = t[o];
+ if (n.defaultSelected) return n;
+ }
+ return t[0];
+}
+function selectElementOptionsSequenceAnalysis(e, t) {
+ for (
+ var r = e.options, o = r.length, n = 0, i = -1, l = -1, a = 0, s = 0;
+ s < o;
+ ++s
+ ) {
+ var u = r[s],
+ c = parseInt(u[t]);
+ isFiniteNumber(c)
+ ? -1 === l
+ ? ((l = c), (a = 1))
+ : c === l + 1 && ((l = c), a++)
+ : (a >= n && ((n = a), (i = l)), (l = -1), (a = 0));
+ }
+ return (
+ a >= n && ((n = a), (i = l)),
+ { lengthOfLongestSequence: n, lastNumberInSequence: i }
+ );
+}
+function isElementPositionedToBeEffectivelyInvisible(e) {
+ var t = !1;
+ for (let r = e; r; r = r.parentElementIncludingShadowDOMHost())
+ if ("fixed" === getComputedStyle(r).position) {
+ t = !0;
+ break;
+ }
+ var r,
+ o,
+ n,
+ i = e.getBoundingClientRect();
+ if (t) ((r = i), (o = window.innerWidth), (n = window.innerHeight));
+ else {
+ var l = window.scrollY,
+ a = window.scrollX;
+ ((r = {
+ top: i.top + l,
+ right: i.right + a,
+ bottom: i.bottom + l,
+ left: i.left + a,
+ width: i.width,
+ height: i.height,
+ }),
+ (o = document.documentElement.scrollWidth),
+ (n = Math.max(
+ document.documentElement.scrollHeight,
+ window.innerHeight,
+ )));
+ }
+ return r.top >= n || r.right <= 0 || r.bottom <= 0 || r.left >= o;
+}
+function rectIsWithinDocumentViewport(e) {
+ return (
+ e.right >= 0 &&
+ e.bottom >= 0 &&
+ e.left <= window.innerWidth &&
+ e.top <= window.innerHeight
+ );
+}
+function isCredentialElementUniqueID(e, t) {
+ return (
+ t === e.UsernameElementUniqueID ||
+ t === e.PasswordElementUniqueID ||
+ t === e.ConfirmPasswordElementUniqueID ||
+ t === e.OldPasswordElementUniqueID
+ );
+}
+function autocompleteTokens(e) {
+ const t = ["autocomplete", "autocompletetype", "x-autocompletetype"];
+ let r = [];
+ for (const o of t)
+ e.hasAttribute(o) && r.push(e.getAttribute(o).trim().toLowerCase());
+ if (!r.length) return null;
+ let o = r
+ .join(" ")
+ .split(/\s+/)
+ .filter(function (e) {
+ return e.length && "off" !== e && "on" !== e;
+ });
+ return o.length ? o : null;
+}
+function elementIDOrAutocompleteTokensHasToken(e, t, r) {
+ return !!e.id?.includes(r) || !!t?.includes(r);
+}
+function controlAppearsToBePartOfPhotoTaggingInterface(e) {
+ const t = /photo.*tag/i;
+ for (
+ let r = e.parentElementIncludingShadowDOMHost();
+ r;
+ r = r.parentElementIncludingShadowDOMHost()
+ )
+ if (t.test(r.className)) return !0;
+ return !1;
+}
+function levenshteinDistance(e, t) {
+ for (
+ var r = e.length, o = t.length, n = new Array(r + 1), i = 0;
+ i < r + 1;
+ ++i
+ )
+ ((n[i] = new Array(o + 1)), (n[i][0] = i));
+ for (var l = 0; l < o + 1; ++l) n[0][l] = l;
+ for (l = 1; l < o + 1; ++l)
+ for (i = 1; i < r + 1; ++i)
+ if (e[i - 1] === t[l - 1]) n[i][l] = n[i - 1][l - 1];
+ else {
+ var a = n[i - 1][l] + 1,
+ s = n[i][l - 1] + 1,
+ u = n[i - 1][l - 1] + 1;
+ n[i][l] = Math.min(a, s, u);
+ }
+ return n[r][o];
+}
+function stringSimilarity(e, t) {
+ var r = Math.max(e.length, t.length);
+ return r ? (r - levenshteinDistance(e, t)) / r : 0;
+}
+function stripCommonPrefix(e, t) {
+ const r = e.length,
+ o = t.length,
+ n = r < o ? r : o;
+ let i = 0;
+ for (; i < n && e[i] === t[i];) i++;
+ return [e.slice(i), t.slice(i)];
+}
+function articleTitleAndSiteNameFromTitleString(e, t) {
+ const r = [" - ", " \u2013 ", " \u2014 ", ": ", " | ", " \xbb "],
+ o = r.length,
+ n = 0.6;
+ for (
+ var i,
+ l,
+ a = e.replace(/^(www|m|secure)\./, ""),
+ s = a.replace(/\.(com|info|net|org|edu|gov)$/, "").toLowerCase(),
+ u = 0;
+ u < o;
+ ++u
+ ) {
+ var c = t.split(r[u]);
+ if (2 === c.length) {
+ var d = c[0].trim(),
+ h = c[1].trim(),
+ m = d.toLowerCase(),
+ F = h.toLowerCase(),
+ f = Math.max(stringSimilarity(m, a), stringSimilarity(m, s)),
+ g = Math.max(stringSimilarity(F, a), stringSimilarity(F, s)),
+ C = Math.max(f, g);
+ (!l || C > l) &&
+ ((l = C),
+ (i =
+ f > g
+ ? { siteName: d, articleTitle: h }
+ : { siteName: h, articleTitle: d }));
+ }
+ }
+ return i && l >= n ? i : null;
+}
+function documentTitleWithoutHostNamePrefix() {
+ const e = document.title,
+ t = articleTitleAndSiteNameFromTitleString(window.location.host, e);
+ return t ? t.articleTitle : e;
+}
+function querySelectorAllIncludingWithinShadowRoots(e, t) {
+ let r = [];
+ for (let o of e.querySelectorAll("*"))
+ if (o.shadowRoot) {
+ let e = querySelectorAllIncludingWithinShadowRoots(o.shadowRoot, t);
+ e.length && (r = r.concat(e));
+ } else o.matches(t) && r.push(o);
+ return r;
+}
+function queryAllBySelector(e, t) {
+ try {
+ return window.collectMatchingElementsInFlatTree
+ ? window.collectMatchingElementsInFlatTree(e, t)
+ : querySelectorAllIncludingWithinShadowRoots(e, t);
+ } catch (e) {
+ return [];
+ }
+}
+function getElementByID(e) {
+ let t = queryAllBySelector(document, `[id='${e}']`);
+ return t.length ? t[0] : null;
+}
+function siblingsIncludingSelfForElement(e) {
+ let t = e.parentElement;
+ if (t) return t.children;
+ let r = e;
+ for (; r.previousElementSibling;) r = r.previousElementSibling;
+ let o = [],
+ n = r;
+ for (; n;) (o.push(n), (n = n.nextElementSibling));
+ return o;
+}
+function regularExpressionFromUntrustedPatternAttributeString(e) {
+ if ((e.startsWith("/") && e.endsWith("/") && (e = e.slice(1, -1)), !e.length))
+ return null;
+ try {
+ return (new RegExp(e, "v"), new RegExp("^(?:" + e + ")$", "v"));
+ } catch (e) {
+ return null;
+ }
+}
+function regularExpressionsFromStrings(e) {
+ return e.map((e) => new RegExp(e));
+}
+function stringsMatchAnyRegularExpressions(e, t) {
+ for (let r of t) for (let t of e) if (r.test(t.toLowerCase())) return !0;
+ return !1;
+}
+function pathFromAnchorWithoutLeadingSlash(e) {
+ let t = /\/(.*)/.exec(e.pathname);
+ return t && 2 === t.length ? t[1] : null;
+}
+function innermostActiveElement(e = document.activeElement) {
+ let t = e,
+ r = t;
+ for (; r;) ((r = r?.shadowRoot?.activeElement), r && (t = r));
+ return t;
+}
+function elementAppearsToContinueCaptchaWidget(e) {
+ return !!e.querySelector(
+ "iframe[title*=captcha i], input[type=hidden][name*=recaptcha]",
+ );
+}
+function isFiniteNumber(e) {
+ return "number" == typeof e && isFinite(e);
+}
+const WBSAutoFillFormTypeUndetermined = 0,
+ WBSAutoFillFormTypeAutoFillableStandard = 1,
+ WBSAutoFillFormTypeNonAutoFillable = 2,
+ WBSAutoFillFormTypeAutoFillableLogin = 3,
+ WBSAutoFillFormTypeNewAccount = 4,
+ WBSAutoFillFormTypeChangePassword = 5,
+ WBSFormMetadataRequestNormal = 0,
+ WBSFormMetadataRequestPreFill = 1,
+ WBSFormMetadataRequestTesting = 2,
+ WBSFormMetadataRequestTextChange = 3,
+ WBSFormMetadataRequestCollectMetadataFromDebugMenu = 4,
+ WBSFormMetadataRequestAutomaticPasswordChange = 5,
+ WBSPasswordCharacterClassTypeASCIIPrintable = 0,
+ WBSPasswordCharacterClassTypeDigit = 1,
+ WBSPasswordCharacterClassTypeLower = 2,
+ WBSPasswordCharacterClassTypeUpper = 3,
+ WBSPasswordCharacterClassTypeSpecial = 4,
+ WBSPasswordCharacterClassTypeUnicode = 5,
+ WBSPasswordCharacterClassTypeCustom = 6,
+ ShouldStopAfterFirstMatch = { CollectAllMatches: 0, StopAfterFirstMatch: 1 },
+ ForceNonFormElementAsLogicalBackingElement = { No: !1, Yes: !0 },
+ LogicalFormCreationIsProvisional = { No: !1, Yes: !0 },
+ MatchCriteria = { Property: 0, Category: 1, Literal: 2 },
+ PageScanCharactersSearchedThreshold = 500,
+ PageScanMaxCharactersSearched = 600,
+ MaximumNumberOfCharactersToCollectForLanguageIdentification = 300,
+ MinValueForMaxLengthAttributeToTreatAsPasswordField = 4,
+ UsernameCandidateScoreForPlainTextField = 1,
+ UsernameCandidateScoreForPlainTextFieldDirectlyBeforePasswordField = 2,
+ UsernameCandidateScoreForEmailLabeledFieldBelowPasswordField = 3,
+ UsernameCandidateScoreForUsernameLabeledFieldBelowPasswordField = 4,
+ UsernameCandidateScoreForEmailLabeledFieldAbovePasswordField = 5,
+ UsernameCandidateScoreForUsernameLabeledFieldAbovePasswordField = 6,
+ UsernameCandidateScoreBonusForVisibleElement = 0.5,
+ UsernameCandidateScorePenaltyForReadOnlyElement = 0.5,
+ UsernameCandidateScorePenaltyForMatchingNonUsernameFieldLabelPattern = 2,
+ UsernameCandidateScorePenaltyForMatchingSearchFieldLabelPattern = 1.5,
+ UsernameCandidateScorePenaltyForAnonymousElement = 1,
+ LowestScoreForUsernameFieldCandidate =
+ UsernameCandidateScoreForPlainTextField,
+ LowestScoreForLabeledUsernameFieldCandidate =
+ UsernameCandidateScoreForEmailLabeledFieldBelowPasswordField,
+ MaxLengthForFieldAboveWhichToTreatPotentialOneTimeCodeFieldAsRequiringHigherScrutiny = 10,
+ DateTimeInputTypes = ["date", "datetime-local", "month", "time", "week"],
+ DateTimeInputTypeFormats = {
+ date: "yyyy-MM-dd",
+ "datetime-local": "yyyy-MM-dd'T'hh:mm",
+ month: "yyyy-MM",
+ time: "hh:mm",
+ week: "yyyy-'W'ww",
+ },
+ numberOfConsecutiveElementsWithoutSuccessfulPageScanAfterWhichPageScanIsAbandoned = 40,
+ insertTextInputType = "insertText";
+class KeyInfo {
+ static BackspaceKeyInfo = new KeyInfo("\b", "\b", null, "Backspace", {
+ uiEventKey: "Backspace",
+ });
+ static #e = { bubbles: !0, cancelable: !0, trusted: !0 };
+ static #t = {
+ ...KeyInfo.#e,
+ keyCode: 16,
+ which: 16,
+ key: "Shift",
+ code: "ShiftRight",
+ location: KeyboardEvent.DOM_KEY_LOCATION_RIGHT,
+ };
+ #r;
+ #o;
+ #n;
+ #i;
+ #l;
+ #a;
+ #s;
+ #u;
+ constructor(
+ e,
+ t,
+ r,
+ o,
+ { uiEventKey: n, useShiftedCharacterForLegacyKeyCode: i } = {},
+ ) {
+ ((this.#r = e),
+ (this.#o = t),
+ (this.#n = r),
+ (this.#u = e === r),
+ (this.#i = o),
+ (this.#l = n ?? e),
+ (this.#s = i ? r.codePointAt(0) : t.codePointAt(0)),
+ (this.#a = e.codePointAt(0)));
+ }
+ get isShifted() {
+ return this.#u;
+ }
+ keyEvent(e) {
+ switch (e) {
+ case "keydown":
+ case "keyup":
+ return new KeyboardEvent(e, {
+ ...KeyInfo.#e,
+ charCode: 0,
+ keyCode: this.#s,
+ which: this.#s,
+ shiftKey: this.#u,
+ key: this.#l,
+ code: this.#i,
+ location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD,
+ });
+ case "keypress":
+ return new KeyboardEvent(e, {
+ ...KeyInfo.#e,
+ charCode: this.#a,
+ keyCode: this.#a,
+ which: this.#a,
+ shiftKey: this.#u,
+ key: this.#l,
+ code: this.#i,
+ location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD,
+ });
+ }
+ }
+ static forCharacter(e) {
+ switch (e) {
+ case "a":
+ case "A":
+ return new KeyInfo(e, "a", "A", "KeyA", {
+ useShiftedCharacterForLegacyKeyCode: !0,
+ });
+ case "b":
+ case "B":
+ return new KeyInfo(e, "b", "B", "KeyB", {
+ useShiftedCharacterForLegacyKeyCode: !0,
+ });
+ case "c":
+ case "C":
+ return new KeyInfo(e, "c", "C", "KeyC", {
+ useShiftedCharacterForLegacyKeyCode: !0,
+ });
+ case "d":
+ case "D":
+ return new KeyInfo(e, "d", "D", "KeyD", {
+ useShiftedCharacterForLegacyKeyCode: !0,
+ });
+ case "e":
+ case "E":
+ return new KeyInfo(e, "e", "E", "KeyE", {
+ useShiftedCharacterForLegacyKeyCode: !0,
+ });
+ case "f":
+ case "F":
+ return new KeyInfo(e, "f", "F", "KeyF", {
+ useShiftedCharacterForLegacyKeyCode: !0,
+ });
+ case "g":
+ case "G":
+ return new KeyInfo(e, "g", "G", "KeyG", {
+ useShiftedCharacterForLegacyKeyCode: !0,
+ });
+ case "h":
+ case "H":
+ return new KeyInfo(e, "h", "H", "KeyH", {
+ useShiftedCharacterForLegacyKeyCode: !0,
+ });
+ case "i":
+ case "I":
+ return new KeyInfo(e, "i", "I", "KeyI", {
+ useShiftedCharacterForLegacyKeyCode: !0,
+ });
+ case "j":
+ case "J":
+ return new KeyInfo(e, "j", "J", "KeyJ", {
+ useShiftedCharacterForLegacyKeyCode: !0,
+ });
+ case "k":
+ case "K":
+ return new KeyInfo(e, "k", "K", "KeyK", {
+ useShiftedCharacterForLegacyKeyCode: !0,
+ });
+ case "l":
+ case "L":
+ return new KeyInfo(e, "l", "L", "KeyL", {
+ useShiftedCharacterForLegacyKeyCode: !0,
+ });
+ case "m":
+ case "M":
+ return new KeyInfo(e, "m", "M", "KeyM", {
+ useShiftedCharacterForLegacyKeyCode: !0,
+ });
+ case "n":
+ case "N":
+ return new KeyInfo(e, "n", "N", "KeyN", {
+ useShiftedCharacterForLegacyKeyCode: !0,
+ });
+ case "o":
+ case "O":
+ return new KeyInfo(e, "o", "O", "KeyO", {
+ useShiftedCharacterForLegacyKeyCode: !0,
+ });
+ case "p":
+ case "P":
+ return new KeyInfo(e, "p", "P", "KeyP", {
+ useShiftedCharacterForLegacyKeyCode: !0,
+ });
+ case "q":
+ case "Q":
+ return new KeyInfo(e, "q", "Q", "KeyQ", {
+ useShiftedCharacterForLegacyKeyCode: !0,
+ });
+ case "r":
+ case "R":
+ return new KeyInfo(e, "r", "R", "KeyR", {
+ useShiftedCharacterForLegacyKeyCode: !0,
+ });
+ case "s":
+ case "S":
+ return new KeyInfo(e, "s", "S", "KeyS", {
+ useShiftedCharacterForLegacyKeyCode: !0,
+ });
+ case "t":
+ case "T":
+ return new KeyInfo(e, "t", "T", "KeyT", {
+ useShiftedCharacterForLegacyKeyCode: !0,
+ });
+ case "u":
+ case "U":
+ return new KeyInfo(e, "u", "U", "KeyU", {
+ useShiftedCharacterForLegacyKeyCode: !0,
+ });
+ case "v":
+ case "V":
+ return new KeyInfo(e, "v", "V", "KeyV", {
+ useShiftedCharacterForLegacyKeyCode: !0,
+ });
+ case "w":
+ case "W":
+ return new KeyInfo(e, "w", "W", "KeyW", {
+ useShiftedCharacterForLegacyKeyCode: !0,
+ });
+ case "x":
+ case "X":
+ return new KeyInfo(e, "x", "X", "KeyX", {
+ useShiftedCharacterForLegacyKeyCode: !0,
+ });
+ case "y":
+ case "Y":
+ return new KeyInfo(e, "y", "Y", "KeyY", {
+ useShiftedCharacterForLegacyKeyCode: !0,
+ });
+ case "z":
+ case "Z":
+ return new KeyInfo(e, "z", "Z", "KeyZ", {
+ useShiftedCharacterForLegacyKeyCode: !0,
+ });
+ case "0":
+ case ")":
+ return new KeyInfo(e, "0", ")", "Digit0", {});
+ case "1":
+ case "!":
+ return new KeyInfo(e, "1", "!", "Digit1", {});
+ case "2":
+ case "@":
+ return new KeyInfo(e, "2", "@", "Digit2", {});
+ case "3":
+ case "#":
+ return new KeyInfo(e, "3", "#", "Digit3", {});
+ case "4":
+ case "$":
+ return new KeyInfo(e, "4", "$", "Digit4", {});
+ case "5":
+ case "%":
+ return new KeyInfo(e, "5", "%", "Digit5", {});
+ case "6":
+ case "^":
+ return new KeyInfo(e, "6", "^", "Digit6", {});
+ case "7":
+ case "&":
+ return new KeyInfo(e, "7", "&", "Digit7", {});
+ case "8":
+ case "*":
+ return new KeyInfo(e, "8", "*", "Digit8", {});
+ case "9":
+ case "(":
+ return new KeyInfo(e, "9", "(", "Digit9", {});
+ case ";":
+ case ":":
+ return new KeyInfo(e, ";", ":", "Semicolon", {});
+ case "=":
+ case "+":
+ return new KeyInfo(e, "=", "+", "Equal", {});
+ case ",":
+ case "<":
+ return new KeyInfo(e, ",", "<", "Comma", {});
+ case "-":
+ case "_":
+ return new KeyInfo(e, "-", "_", "Minus", {});
+ case ".":
+ case ">":
+ return new KeyInfo(e, ".", ">", "Period", {});
+ case "/":
+ case "?":
+ return new KeyInfo(e, "/", "?", "Slash", {});
+ case "`":
+ case "~":
+ return new KeyInfo(e, "`", "~", "Backquote", {});
+ case "[":
+ case "{":
+ return new KeyInfo(e, "[", "{", "BracketLeft", {});
+ case "\\":
+ case "|":
+ return new KeyInfo(e, "\\", "|", "Backslash", {});
+ case "]":
+ case "}":
+ return new KeyInfo(e, "]", "}", "BracketRight", {});
+ case "'":
+ case '"':
+ return new KeyInfo(e, "'", '"', "Quote", {});
+ case " ":
+ return new KeyInfo(e, " ", null, "Space", {});
+ case "\t":
+ return new KeyInfo(e, "\t", null, "Tab", { uiEventKey: "Tab" });
+ case "\n":
+ return new KeyInfo(e, "\n", null, "Enter", { uiEventKey: "Enter" });
+ }
+ return new KeyInfo(e, e.toLowerCase(), e.toUpperCase(), "Unidentified");
+ }
+ static shiftKeyEvent(e) {
+ switch (e) {
+ case "keydown":
+ return new KeyboardEvent(e, { ...KeyInfo.#t, shiftKey: !0 });
+ case "keyup":
+ return new KeyboardEvent(e, KeyInfo.#t);
+ }
+ }
+}
+class PasswordRule {
+ standardCharacter = 0;
+ customCharacters = "";
+ static asciiPrintableBit = 1 << WBSPasswordCharacterClassTypeASCIIPrintable;
+ static digitBit = 1 << WBSPasswordCharacterClassTypeDigit;
+ static lowercaseBit = 1 << WBSPasswordCharacterClassTypeLower;
+ static uppercaseBit = 1 << WBSPasswordCharacterClassTypeUpper;
+ static specialCharacterBit = 1 << WBSPasswordCharacterClassTypeSpecial;
+ static unicodeBit = 1 << WBSPasswordCharacterClassTypeUnicode;
+ copy() {
+ const e = new PasswordRule();
+ return (
+ (e.standardCharacter = this.standardCharacter),
+ (e.customCharacters = this.customCharacters),
+ e
+ );
+ }
+ intersection(e) {
+ ((this.standardCharacter &= e.standardCharacter),
+ (this.customCharacters = [
+ ...new Set([...this.customCharacters]).intersection(
+ new Set([...e.customCharacters]),
+ ),
+ ].join("")),
+ this.#c());
+ }
+ union(e) {
+ ((this.standardCharacter |= e.standardCharacter),
+ (this.customCharacters = [
+ ...new Set(this.customCharacters + e.customCharacters),
+ ].join("")),
+ this.#c());
+ }
+ addAllowedCharacterClass(e) {
+ if (e instanceof NamedCharacterClass)
+ switch (e.name) {
+ case Identifier.ASCII_PRINTABLE:
+ this.standardCharacter = PasswordRule.asciiPrintableBit;
+ break;
+ case Identifier.UNICODE:
+ this.standardCharacter = PasswordRule.unicodeBit;
+ break;
+ case Identifier.DIGIT:
+ this.standardCharacter |= PasswordRule.digitBit;
+ break;
+ case Identifier.LOWER:
+ this.standardCharacter |= PasswordRule.lowercaseBit;
+ break;
+ case Identifier.UPPER:
+ this.standardCharacter |= PasswordRule.uppercaseBit;
+ break;
+ case Identifier.SPECIAL:
+ this.standardCharacter |= PasswordRule.specialCharacterBit;
+ }
+ else
+ e instanceof CustomCharacterClass &&
+ (this.customCharacters = [
+ ...new Set([...this.customCharacters, ...e.characters]),
+ ].join(""));
+ ((this.customCharacters = [...new Set([...this.customCharacters])].join(
+ "",
+ )),
+ this.#c());
+ }
+ #c() {
+ if (this.standardCharacter & PasswordRule.asciiPrintableBit)
+ return (
+ (this.standardCharacter = PasswordRule.asciiPrintableBit),
+ void (this.customCharacters = "")
+ );
+ if (this.standardCharacter & PasswordRule.unicodeBit)
+ return (
+ (this.standardCharacter = PasswordRule.unicodeBit),
+ void (this.customCharacters = "")
+ );
+ if (0 === this.customCharacters.length) return;
+ const e = new Set(this.customCharacters);
+ if (this.standardCharacter & PasswordRule.digitBit)
+ for (const t of "0123456789") e.delete(t);
+ if (this.standardCharacter & PasswordRule.lowercaseBit)
+ for (const t of "abcdefghijklmnopqrstuvwxyz") e.delete(t);
+ if (this.standardCharacter & PasswordRule.uppercaseBit)
+ for (const t of "ABCDEFGHIJKLMNOPQRSTUVWXYZ") e.delete(t);
+ this.customCharacters = [...e].join("");
+ }
+}
+class PasswordRuleSet {
+ allowedRule = null;
+ requiredRules = null;
+ maxConsecutiveRule = null;
+ minLengthRule = null;
+ maxLengthRule = null;
+ constructor(e) {
+ for (const t of e)
+ switch (t.name) {
+ case RuleName.ALLOWED:
+ this.#d(t);
+ break;
+ case RuleName.REQUIRED:
+ this.#h(t);
+ break;
+ case RuleName.MAX_CONSECUTIVE:
+ this.#m(t);
+ break;
+ case RuleName.MIN_LENGTH:
+ this.#F(t);
+ break;
+ case RuleName.MAX_LENGTH:
+ this.#f(t);
+ }
+ this.#c();
+ }
+ copy() {
+ const e = new PasswordRuleSet([]);
+ return (
+ null !== this.allowedRule && (e.allowedRule = this.allowedRule.copy()),
+ null !== this.requiredRules &&
+ (e.requiredRules = this.requiredRules.map((e) => e.copy())),
+ (e.maxConsecutiveRule = this.maxConsecutiveRule),
+ (e.minLengthRule = this.minLengthRule),
+ (e.maxLengthRule = this.maxLengthRule),
+ e
+ );
+ }
+ merge(e) {
+ (this.#g(e), this.#C(e), this.#p(e), this.#y(e), this.#b(e), this.#c());
+ }
+ #g(e) {
+ null !== e.allowedRule &&
+ (null === this.allowedRule
+ ? (this.allowedRule = e.allowedRule.copy())
+ : this.allowedRule.intersection(e.allowedRule));
+ }
+ #C(e) {
+ if (null !== e.requiredRules) {
+ null === this.requiredRules && (this.requiredRules = []);
+ for (const t of e.requiredRules) this.requiredRules.push(t.copy());
+ }
+ }
+ #p(e) {
+ null !== e.maxConsecutiveRule &&
+ (null !== this.maxConsecutiveRule
+ ? (this.maxConsecutiveRule = Math.min(
+ this.maxConsecutiveRule,
+ e.maxConsecutiveRule,
+ ))
+ : (this.maxConsecutiveRule = e.maxConsecutiveRule));
+ }
+ #y(e) {
+ null !== e.minLengthRule &&
+ (null !== this.minLengthRule
+ ? (this.minLengthRule = Math.max(this.minLengthRule, e.minLengthRule))
+ : (this.minLengthRule = e.minLengthRule));
+ }
+ #b(e) {
+ null !== e.maxLengthRule &&
+ (null !== this.maxLengthRule
+ ? (this.maxLengthRule = Math.min(this.maxLengthRule, e.maxLengthRule))
+ : (this.maxLengthRule = e.maxLengthRule));
+ }
+ #h(e) {
+ null === this.requiredRules && (this.requiredRules = []);
+ const t = new PasswordRule();
+ for (const r of e.value) t.addAllowedCharacterClass(r);
+ this.requiredRules.push(t);
+ }
+ #d(e) {
+ this.allowedRule || (this.allowedRule = new PasswordRule());
+ for (const t of e.value) this.allowedRule.addAllowedCharacterClass(t);
+ }
+ #m(e) {
+ (null === this.maxConsecutiveRule && (this.maxConsecutiveRule = 1 / 0),
+ (this.maxConsecutiveRule = Math.min(this.maxConsecutiveRule, e.value)));
+ }
+ #F(e) {
+ (null === this.minLengthRule && (this.minLengthRule = 0),
+ (this.minLengthRule = Math.max(this.minLengthRule, e.value)));
+ }
+ #f(e) {
+ (null === this.minLengthRule && (this.minLengthRule = 1 / 0),
+ (this.maxLengthRule = Math.min(this.maxLengthRule, e.value)));
+ }
+ #c() {
+ if (null !== this.requiredRules) {
+ null === this.allowedRule && (this.allowedRule = new PasswordRule());
+ for (const e of this.requiredRules) this.allowedRule.union(e);
+ }
+ }
+}
+var mapOfFormTypeToProducerOfAssociatedKeywords = (function () {
+ var e = {};
+ return (
+ (e[WBSAutoFillFormTypeNewAccount] = function () {
+ return FormMetadataJSController.mapOfKeywordsIndicatingNewAccountFormTypeToScoreForMatching;
+ }),
+ (e[WBSAutoFillFormTypeAutoFillableLogin] = function () {
+ return FormMetadataJSController.mapOfKeywordsIndicatingLoginFormTypeToScoreForMatching;
+ }),
+ (e[WBSAutoFillFormTypeChangePassword] = function () {
+ return FormMetadataJSController.mapOfKeywordsIndicatingChangePasswordFormTypeToScoreForMatching;
+ }),
+ e
+ );
+ })(),
+ visibilityCacheGeneration = 0;
+let doctypeLooksLikeHTML5 =
+ "html" === document.doctype?.name &&
+ "" === document.doctype?.publicId &&
+ "" === document.doctype?.systemId;
+((console.autofillDebugLog = function () {
+ FormMetadataJSController.isDebugConsoleLoggingEnabled;
+}),
+ (Element.prototype.af_setValue = function (e) {
+ isContentEditableSingleLineTextbox(this)
+ ? (this.textContent = e)
+ : (this.value = e);
+ }),
+ (Element.prototype.af_value = function () {
+ return isContentEditableSingleLineTextbox(this)
+ ? this.textContent
+ : (this.value ?? this.textContent ?? "");
+ }),
+ (HTMLFieldSetElement.prototype.af_setValue = function (e) {
+ this.value = e;
+ }),
+ (HTMLFieldSetElement.prototype.af_value = function () {
+ return this.value;
+ }),
+ (HTMLInputElement.prototype.af_setValue = function (e) {
+ this.value = e;
+ }),
+ (HTMLInputElement.prototype.af_value = function () {
+ return this.value;
+ }),
+ (HTMLTextAreaElement.prototype.af_setValue = function (e) {
+ this.value = e;
+ }),
+ (HTMLTextAreaElement.prototype.af_value = function () {
+ return this.value;
+ }),
+ (Element.prototype.traversePreviousElement = function () {
+ for (var e = this.previousElementSibling; e && e.lastElementChild;)
+ e = e.lastElementChild;
+ return e || this.parentElement;
+ }),
+ (Node.prototype.traversePreviousNode = function (e) {
+ if (this) {
+ var t = this.previousSibling;
+ if (e(t)) return null;
+ for (; t && t.lastChild;) if (e((t = t.lastChild))) return null;
+ return t || this.parentNode;
+ }
+ }),
+ (Node.prototype.traverseNextNode = function (e) {
+ if (this) {
+ var t = this.firstChild;
+ if (t) return t;
+ if (e && this === e) return null;
+ if ((t = this.nextSibling)) return t;
+ for (
+ t = this;
+ t && !t.nextSibling && (!e || !t.parentNode || t.parentNode !== e);
+ )
+ t = t.parentNode;
+ return t ? t.nextSibling : null;
+ }
+ }),
+ (Node.prototype.isVisible = function () {
+ let e = this;
+ if (e._isVisible === visibilityCacheGeneration) return !0;
+ if (e._isVisible === -visibilityCacheGeneration) return !1;
+ let t = e instanceof Element ? e : e.parentElementIncludingShadowDOMHost(),
+ r = getComputedStyle(t, null);
+ if (
+ ((e._isVisible = -visibilityCacheGeneration),
+ "none" === r.display || "visible" !== r.visibility)
+ )
+ return !1;
+ let o = 0 === parseFloat(r.opacity) ? 6 : 2;
+ var n = t.getBoundingClientRect();
+ return (
+ !(n.width < o) &&
+ !(n.height < o) &&
+ ((e._isVisible = visibilityCacheGeneration), !0)
+ );
+ }),
+ Object.defineProperty(Array.prototype, "joinFirstItems", {
+ value(e, t) {
+ t > this.length && (t = this.length);
+ for (var r = "", o = 0; o < t; ++o) (o > 0 && (r += e), (r += this[o]));
+ return r;
+ },
+ }),
+ (DOMRect.prototype.isZeroRect = function () {
+ return !(this.top || this.right || this.bottom || this.left);
+ }),
+ (DOMRect.prototype.centerPoint = function () {
+ return {
+ x: Math.round(this.x + this.width / 2),
+ y: Math.round(this.y + this.height / 2),
+ };
+ }),
+ (DOMRect.prototype.distanceToRect = function (e) {
+ function t(e) {
+ function t(e, t) {
+ return Math.pow(e.x - t.x, 2) + Math.pow(e.y - t.y, 2);
+ }
+ var r = e[0],
+ o = e[1];
+ return (r[0].x >= o[0].x && r[0].x < o[1].x) ||
+ (o[0].x >= r[0].x && o[0].x < r[1].x)
+ ? Math.abs(r[0].y - o[0].y)
+ : (r[0].y >= o[0].y && r[0].y < o[1].y) ||
+ (o[0].y >= r[0].y && o[0].y < r[1].y)
+ ? Math.abs(r[0].x - o[0].x)
+ : Math.sqrt(Math.min(t(r[0], o[1]), t(r[1], o[0])));
+ }
+ var r = [
+ { x: this.left, y: this.top },
+ { x: this.right, y: this.top },
+ ],
+ o = [
+ { x: this.right, y: this.top },
+ { x: this.right, y: this.bottom },
+ ],
+ n = [
+ { x: this.left, y: this.bottom },
+ { x: this.right, y: this.bottom },
+ ],
+ i = [
+ { x: this.left, y: this.top },
+ { x: this.left, y: this.bottom },
+ ],
+ l = [
+ { x: e.left, y: e.top },
+ { x: e.right, y: e.top },
+ ],
+ a = [
+ { x: e.right, y: e.top },
+ { x: e.right, y: e.bottom },
+ ],
+ s = [
+ { x: e.left, y: e.bottom },
+ { x: e.right, y: e.bottom },
+ ],
+ u = [
+ { x: e.left, y: e.top },
+ { x: e.left, y: e.bottom },
+ ],
+ c = [
+ [i, u],
+ [i, a],
+ [r, l],
+ [r, s],
+ [o, u],
+ [o, a],
+ [n, l],
+ [n, s],
+ ].map(t);
+ return Math.min.apply(Math, c);
+ }),
+ (Node.prototype.parentElementIncludingShadowDOMHost = function () {
+ let e = this.parentElement;
+ if (e) return e;
+ let t = this.getRootNode();
+ return t && t.host ? t.host : null;
+ }),
+ (Node.prototype.allAncestorsAndSelfIncludingShadowDOMHosts = function () {
+ let e = [],
+ t = this;
+ for (; t;) (e.push(t), (t = t.parentElementIncludingShadowDOMHost()));
+ return e;
+ }),
+ (HTMLElement.prototype.closestCommonAncestor = function (e) {
+ let t = this.parentElement;
+ for (; t;) {
+ if (t.contains(e)) return t;
+ t = t.parentElement;
+ }
+ let r = this.allAncestorsAndSelfIncludingShadowDOMHosts().reverse(),
+ o = e.allAncestorsAndSelfIncludingShadowDOMHosts().reverse(),
+ n = Math.min(r.length, o.length),
+ i = null;
+ for (let e = 0; e < n; ++e) {
+ if (!(r[e] === o[e])) break;
+ i = r[e];
+ }
+ return i || null;
+ }),
+ (Element.prototype.isHiddenFromAccessibilityTree = function () {
+ const e = 2;
+ for (
+ let r = 0, o = this;
+ r <= e && o;
+ ++r, o = o.parentElementIncludingShadowDOMHost()
+ ) {
+ var t = o.getAttribute("aria-hidden");
+ if (t && "true" === t.toLowerCase()) return !0;
+ }
+ return !1;
+ }),
+ (HTMLElement.prototype._setAutofillButtonType = function (e) {
+ const t = this.autofillButtonType;
+ e !== t &&
+ ((this._lastAutofillButtonType = t), (this.autofillButtonType = e));
+ }),
+ (HTMLElement.prototype.isDisabledOrReadOnly = function () {
+ return this.disabled || this.readOnly;
+ }),
+ (HTMLElement.prototype.shouldFocusDuringFilling = function () {
+ return !isRadioButtonElement(this) && !isSelectElement(this);
+ }),
+ (HTMLFormElement.prototype.isVisible = function () {
+ if (Node.prototype.isVisible.call(this)) return !0;
+ for (var e = this.elements, t = e.length, r = 0; r < t; ++r)
+ if (e[r].isVisible()) return !0;
+ return !1;
+ }));
+let cachedUserIsOnDomain = {};
+class LogicalForm {
+ #A;
+ #_ = !1;
+ #T = !1;
+ constructor(e, t, r) {
+ let o = e.length;
+ var n = e[0].form,
+ i = n;
+ let l = e[0],
+ a = e[o - 1];
+ ((!t && i) || (i = 1 === o ? l : l.closestCommonAncestor(a)),
+ (n && n.contains(a)) || (n = i));
+ let s = i.closest('*[role~="dialog"]');
+ s && (i = s);
+ let u = l._provisionalLogicalFormUniqueIDForFirstControlInLogicalForm;
+ (u ||
+ ((u = FormMetadataJSController.nextFormUniqueID),
+ (l._provisionalLogicalFormUniqueIDForFirstControlInLogicalForm = u)),
+ (this._formUniqueID = u),
+ (this._metadata = {}),
+ (this._weakControls = Array.prototype.map.call(e, (e) => new WeakRef(e))),
+ (this._weakFormElement = new WeakRef(n)),
+ (this._weakBackingElement = new WeakRef(i)),
+ (this.#A = new MutationObserver(this.#w.bind(this))),
+ r || this.markElementsAsPartOfLogicalForm());
+ }
+ get elements() {
+ return this._weakControls.flatMap((e) => e.deref() ?? []);
+ }
+ get formElement() {
+ return this._weakFormElement.deref();
+ }
+ get backingElement() {
+ return this._weakBackingElement.deref();
+ }
+ get formUniqueID() {
+ return this._formUniqueID;
+ }
+ get metadata() {
+ return this._metadata;
+ }
+ set metadata(e) {
+ ((this._metadata = e), this.#E());
+ }
+ containsControl(e) {
+ return e.hasOwnProperty("_logicalFormUniqueID")
+ ? e._logicalFormUniqueID === this.formUniqueID
+ : e.form === this.formElement;
+ }
+ radioButtonsWithName(e) {
+ let t = queryAllBySelector(document.documentElement, `*[name="${e}"]`);
+ return Array.prototype.filter.call(
+ t,
+ function (e) {
+ return (
+ (e.form === this.formElement || this.formElement?.contains(e)) &&
+ isRadioButtonElement(e)
+ );
+ },
+ this,
+ );
+ }
+ annotate(e) {
+ let t = this.formElement;
+ if (t) {
+ var r = t._annotations;
+ if (r) {
+ for (var o in e) {
+ var n = e[o];
+ n ? (r[o] = n) : delete r[o];
+ }
+ hasOwnProperties(r) || delete t._annotations;
+ } else t._annotations = e;
+ }
+ }
+ markElementsAsPartOfLogicalForm() {
+ let e = this._weakControls.length;
+ for (let t = 0; t < e; t++) {
+ let r = this._weakControls[t].deref();
+ r &&
+ ((r._logicalFormUniqueID = this.formUniqueID),
+ t + 1 < e &&
+ (r._weakNextControlInLogicalForm = this._weakControls[t + 1]),
+ t > 0 &&
+ (r._weakPreviousControlInLogicalForm = this._weakControls[t - 1]));
+ }
+ }
+ get hasVisibleControls() {
+ return (
+ this.formElement.isVisible() &&
+ this._weakControls.some((e) => e.deref()?.isVisible())
+ );
+ }
+ get hasVisibleTextEntryControls() {
+ return (
+ this.formElement.isVisible() &&
+ this._weakControls.some((e) => {
+ const t = e.deref();
+ return !!t?.isVisible() && FormMetadataJS._isTextField(t);
+ })
+ );
+ }
+ get annotations() {
+ return this.formElement?._annotations;
+ }
+ get isAnnotated() {
+ return !!this.annotations;
+ }
+ get passwordControls() {
+ const e = this.metadata;
+ return e
+ ? Object.fromEntries(
+ [
+ e.PasswordElementUniqueID,
+ e.ConfirmPasswordElementUniqueID,
+ e.OldPasswordElementUniqueID,
+ ]
+ .map((e) => {
+ if (!e) return null;
+ const t = FormMetadataJS.formControlWithUniqueID(e);
+ return t ? [e, t] : null;
+ })
+ .filter((e) => !!e),
+ )
+ : [];
+ }
+ #E() {
+ Object.values(this.passwordControls).forEach((e) => {
+ e.addEventListener(
+ "input",
+ () => {
+ (this.#S(), (this.#T = !0));
+ },
+ { once: !0, passive: !0 },
+ );
+ });
+ }
+ startObservingAddedControls() {
+ (this.#S(), (this.#_ = !0));
+ }
+ #S() {
+ this.#_ ||
+ this.#T ||
+ this.#A.observe(document, { subtree: !0, childList: !0, attributes: !0 });
+ }
+ #w(e) {
+ const t = this.metadata,
+ r = this.passwordControls;
+ let o = !1;
+ for (const n of e) {
+ const e = n.removedNodes;
+ if (e.length && this.#T) {
+ let n = new Set();
+ for (const t of e) {
+ for (const [e, o] of Object.entries(r))
+ n.has(o) || (t.contains(o) && n.add(e));
+ if (r.size === n.size) break;
+ }
+ if (n.size) {
+ const e = t.FormControls.filter((e) => n.has(e.ControlUniqueID));
+ (FormMetadataJSController.logicalFormObservedChangeIndicatingFormSubmission(
+ t,
+ e,
+ ),
+ (o = !0));
+ }
+ }
+ const i = n.addedNodes;
+ if (i.length && this.#_) {
+ let e = [];
+ for (const t of i)
+ if (
+ ((FormMetadataJS._isTextField(t) ||
+ t instanceof HTMLSelectElement) &&
+ e.push(t),
+ t.querySelectorAll)
+ ) {
+ const r = t.querySelectorAll("input, textarea, select");
+ for (const t of r)
+ (FormMetadataJS._isTextField(t) ||
+ t instanceof HTMLSelectElement) &&
+ e.push(t);
+ }
+ if (e.length) {
+ for (const r of e) {
+ const e = FormMetadataJS._collectControlMetadata(
+ r,
+ null,
+ !1,
+ !1,
+ !1,
+ !1,
+ !1,
+ !1,
+ );
+ t.FormControls && t.FormControls.push(e);
+ }
+ FormMetadataJSController.logicalFormObservedNewControlsWereAdded(t);
+ }
+ }
+ }
+ o && !this.#_ && (this.#A.disconnect(), (this.#T = !1));
+ }
+}
+class LogicalFormCache {
+ constructor() {
+ ((this._logicalFormsByUniqueID = new Map()), (this._allLogicalForms = []));
+ }
+ get size() {
+ return this._logicalFormsByUniqueID.size;
+ }
+ removeUnparentedLogicalFormsFromCache() {
+ let e = new Set();
+ for (let t of this._allLogicalForms) t.formElement?.isConnected || e.add(t);
+ for (let t of e) this._logicalFormsByUniqueID.delete(t.formUniqueID);
+ this._allLogicalForms = Array.from(this._logicalFormsByUniqueID.values());
+ }
+ logicalFormForControl(e) {
+ for (let t of this._allLogicalForms) if (t.containsControl(e)) return t;
+ return null;
+ }
+ allForms() {
+ return this._allLogicalForms.slice();
+ }
+ cachedForms() {
+ return Array.from(this._logicalFormsByUniqueID.values());
+ }
+ addOrUpdate(e) {
+ (this._logicalFormsByUniqueID.set(e.formUniqueID, e),
+ this._allLogicalForms.push(e));
+ }
+ clearCacheAndAdd(e) {
+ (this._logicalFormsByUniqueID.clear(), (this._allLogicalForms = []));
+ for (let t of e) this.addOrUpdate(t);
+ }
+ logicalFormWithUniqueID(e) {
+ return this._logicalFormsByUniqueID.get(e);
+ }
+ get numberOfVisibleFormsWithVisibleTextEntryControls() {
+ return this.cachedForms().reduce(
+ (e, t) => (t.hasVisibleTextEntryControls ? e + 1 : e),
+ 0,
+ );
+ }
+}
+class FormMetadata {
+ canUseTextInputEventsToFill = !0;
+ #I = null;
+ constructor() {
+ ((this._logicalFormsCache = new LogicalFormCache()),
+ (this._elementsWithGeneratedPasswords = []),
+ (this._generatedPasswords = []),
+ (this._controlUniqueIDToWeakControlMap = new Map()),
+ (this._mapOfFormTypeToExtraScoreProducer = (function () {
+ let e = {};
+ return (
+ (e[WBSAutoFillFormTypeNewAccount] = function () {
+ return 0;
+ }),
+ (e[WBSAutoFillFormTypeAutoFillableLogin] = function (e) {
+ const t = 2,
+ r = function (e) {
+ if ("checkbox" !== e.type) return !1;
+ return FormMetadataJS._labelsForElement(e).some(function (e) {
+ const t = e.innerText.trim();
+ return (
+ !(
+ !/(remember|keep) me/i.test(t) &&
+ !/remember.*checkbox/i.test(e.className)
+ ) && e.isVisible()
+ );
+ });
+ };
+ return 1 === e.elements.filter((e) => r(e)).length ? t : 0;
+ }),
+ (e[WBSAutoFillFormTypeChangePassword] = function () {
+ return 0;
+ }),
+ e
+ );
+ })()),
+ (this._requiredFormatForDateTimeInput = DateTimeInputTypes.reduce(
+ function (e, t) {
+ let r = document.createElement("input");
+ r.type = t;
+ let o = "a";
+ return (
+ r.af_setValue(o),
+ (e[t] = "" === r.af_value() ? DateTimeInputTypeFormats[t] : ""),
+ e
+ );
+ },
+ {},
+ )));
+ }
+ get _labels() {
+ null === this.#I &&
+ (this.#I = Array.from(queryAllBySelector(document, "label")).map(
+ (e) => new WeakRef(e),
+ ));
+ const e = [];
+ for (const t of this.#I) {
+ const r = t.deref();
+ r && e.push(r);
+ }
+ return e;
+ }
+ _getTagName(e) {
+ var t = e.tagName;
+ return "string" == typeof t || "string" == typeof (t = e.nodeName)
+ ? t
+ : void 0;
+ }
+ _getNameOrId(e) {
+ return e.name && e.name.length ? e.name : e.id;
+ }
+ controlUniqueID(e) {
+ if (e._controlUniqueID) return e._controlUniqueID;
+ var t = "ControlID-" + FormMetadataJSController.nextControlUniqueID;
+ e._controlUniqueID = t;
+ this._controlUniqueIDToWeakControlMap.get(t);
+ return (
+ this._controlUniqueIDToWeakControlMap.set(t, new WeakRef(e)),
+ e._controlUniqueID
+ );
+ }
+ ensureElementHandle(e) {
+ return (
+ e._handle || (e._handle = window.webkit.createJSHandle(e)),
+ e._handle
+ );
+ }
+ _searchForLabelsAboveCell(e, t) {
+ var r = window.getComputedStyle(t, null);
+ if (!r || "table-cell" !== r.getPropertyValue("display")) return null;
+ var o = cellVisuallyAbove(t);
+ if (!o) return null;
+ for (var n = 0, i = o.firstChild; i; i = i.traverseNextNode(o))
+ if (i.nodeType == Node.TEXT_NODE && i.isVisible()) {
+ var l = i.nodeValue,
+ a = FormMetadataJSController.fieldLabelToInfo(
+ new JSFieldLabelPatternMatcher(e.dfa(), l).searchReverse(),
+ );
+ if (a)
+ return {
+ Distance: n,
+ Match: a[0],
+ Property: a[1],
+ Category: a[2],
+ ParentProperty: a[3],
+ };
+ n += l.length;
+ }
+ return null;
+ }
+ _collectStringFromNodeForPageScan(e, t, r) {
+ var o = e.nodeValue,
+ n = o.length;
+ return (
+ r + n > PageScanMaxCharactersSearched &&
+ ((o = o.substr(-(PageScanCharactersSearchedThreshold - r))),
+ (n = PageScanCharactersSearchedThreshold - r)),
+ (o = o.trim()).length && t.push(o),
+ r
+ );
+ }
+ _dataForComputingMatchFromPageScanBeforeElement(e, t) {
+ function r(e) {
+ return e && e.nodeType == Node.ELEMENT_NODE && e.matches("nav");
+ }
+ var o,
+ n = [],
+ i = 0;
+ let l = this._logicalFormsCache.logicalFormForControl(e);
+ if (!l) return [[], null];
+ var a = l.formElement,
+ s = a && a.isVisible();
+ t || (t = a);
+ for (
+ var u = e.traversePreviousNode(r);
+ u && i < PageScanCharactersSearchedThreshold;
+ u = u.traversePreviousNode(r)
+ ) {
+ var c = u.localName;
+ if (u === t) break;
+ if (this._isRenderedFormControl(u)) {
+ if (u.isVisible() || !s) break;
+ } else {
+ if (this._isLabelElement(u) && u.isVisible()) break;
+ if ("td" !== c || o) {
+ if ("tr" === c && o) break;
+ if ("ul" === c || "ol" === c || "dl" === c) break;
+ if ("li" === c) {
+ if (!u.parentNode.contains(e)) break;
+ } else
+ u.nodeType == Node.TEXT_NODE &&
+ u.isVisible() &&
+ (i += this._collectStringFromNodeForPageScan(u, n, i));
+ } else o = u;
+ }
+ }
+ return [n, o];
+ }
+ _matchFromPageScanBeforeElement(e, t, r) {
+ var o = this._pageScanContext
+ ? this._pageScanContext.backwardScanCache
+ : null,
+ n = this._pageScanDataForElementWithCacheAndDataProducer(
+ t,
+ o,
+ this._dataForComputingMatchFromPageScanBeforeElement.bind(this),
+ r,
+ ),
+ i = n[0],
+ l = this._matchFromPatternMatcherAndStringsFromPageScan(e, i);
+ if (l) return l;
+ var a = n[1];
+ if (a) {
+ var s = this._searchForLabelsAboveCell(e, a);
+ if (s) return ((s.IsInCellAbove = !0), s);
+ }
+ return null;
+ }
+ _isElementFollowedByForgotUserNameOrEmailOrFederatedSignInAffordance(
+ e,
+ t,
+ r,
+ o,
+ ) {
+ (this._forgotUserNameRegularExpressions ||
+ (this._forgotUserNameRegularExpressions = regularExpressionsFromStrings(
+ FormMetadataJSController.regularExpressionsForForgotUserNameAffordance,
+ )),
+ this._forgotEmailRegularExpressions ||
+ (this._forgotEmailRegularExpressions = regularExpressionsFromStrings(
+ FormMetadataJSController.regularExpressionsForForgotEmailAffordance,
+ )));
+ const n = this._stringsToEvaluateToDetermineIfElementIsFollowedByAffordance(
+ e,
+ t,
+ r,
+ o,
+ );
+ if (
+ stringsMatchAnyRegularExpressions(
+ n,
+ this._forgotUserNameRegularExpressions,
+ )
+ )
+ return !0;
+ if (
+ stringsMatchAnyRegularExpressions(n, this._forgotEmailRegularExpressions)
+ )
+ return !0;
+ let i = this._cachedFederatedSignInAffordancePatternMatcher();
+ for (let e of n) if (this._matchPatternAgainstString(i, e)) return !0;
+ return !1;
+ }
+ _isElementFollowedByForgotPasswordAffordance(e, t, r, o) {
+ return (
+ this._forgotPasswordRegularExpressions ||
+ (this._forgotPasswordRegularExpressions = regularExpressionsFromStrings(
+ FormMetadataJSController.regularExpressionsForForgotPasswordAffordance,
+ )),
+ stringsMatchAnyRegularExpressions(
+ this._stringsToEvaluateToDetermineIfElementIsFollowedByAffordance(
+ e,
+ t,
+ r,
+ o,
+ ),
+ this._forgotPasswordRegularExpressions,
+ )
+ );
+ }
+ _numberOfForgotUserNameEmailOrPasswordAffordancesFollowingElement(
+ e,
+ t,
+ r,
+ o,
+ ) {
+ (this._forgotEmailRegularExpressions ||
+ (this._forgotEmailRegularExpressions = regularExpressionsFromStrings(
+ FormMetadataJSController.regularExpressionsForForgotEmailAffordance,
+ )),
+ this._forgotPasswordRegularExpressions ||
+ (this._forgotPasswordRegularExpressions = regularExpressionsFromStrings(
+ FormMetadataJSController.regularExpressionsForForgotPasswordAffordance,
+ )),
+ this._forgotUserNameRegularExpressions ||
+ (this._forgotUserNameRegularExpressions = regularExpressionsFromStrings(
+ FormMetadataJSController.regularExpressionsForForgotUserNameAffordance,
+ )));
+ const n = this._stringsToEvaluateToDetermineIfElementIsFollowedByAffordance(
+ e,
+ t,
+ r,
+ o,
+ );
+ let i = 0;
+ return (
+ stringsMatchAnyRegularExpressions(
+ n,
+ this._forgotUserNameRegularExpressions,
+ ) && i++,
+ stringsMatchAnyRegularExpressions(
+ n,
+ this._forgotEmailRegularExpressions,
+ ) && i++,
+ stringsMatchAnyRegularExpressions(
+ n,
+ this._forgotPasswordRegularExpressions,
+ ) && i++,
+ i
+ );
+ }
+ _stringsToEvaluateToDetermineIfElementIsFollowedByAffordance(e, t, r, o) {
+ let n = this._dataForComputingMatchFromPageScanAfterElement(e, "A"),
+ i = null;
+ if (!n.length) {
+ const t = e.traverseNextNode();
+ if (t) {
+ ((i = t),
+ t instanceof Node && (i = t.parentElementIncludingShadowDOMHost()));
+ const e = i.querySelector("a:not(svg a)");
+ if (e) {
+ const t = e.innerText;
+ t?.length && n.push(t);
+ const r = pathFromAnchorWithoutLeadingSlash(e);
+ r?.length && n.push(r);
+ }
+ }
+ }
+ if (!n.length) {
+ const e = i?.querySelector("*[tabindex]");
+ if (this._looksClickableBasedOnCursorStyle(e)) {
+ const t = e.innerText;
+ t?.length && n.push(t);
+ }
+ }
+ if (!n.length) {
+ for (const t of r) {
+ if (e.compareDocumentPosition(t) & Node.DOCUMENT_POSITION_FOLLOWING) {
+ const e = t.innerText;
+ e?.length && n.push(e);
+ const r = pathFromAnchorWithoutLeadingSlash(t);
+ r?.length && n.push(r);
+ }
+ }
+ for (const t of o) {
+ if (e.compareDocumentPosition(t) & Node.DOCUMENT_POSITION_FOLLOWING) {
+ const e = t.innerText;
+ e.length && n.push(e);
+ }
+ }
+ }
+ const l = e._weakNextControlInLogicalForm?.deref();
+ if (l && "button" === l.type) {
+ const e = l.innerText;
+ e.length && n.push(e);
+ }
+ return n;
+ }
+ _shouldDetectStandaloneUserNameFields() {
+ return "https://discord.com/channels/@me" !== window.location.href;
+ }
+ _dataForComputingMatchFromPageScanAfterElement(e, t, r) {
+ var o = [],
+ n = 0,
+ i = this._logicalFormsCache.logicalFormForControl(e);
+ if (!i) return [];
+ var l = i.formElement,
+ a = l && l.isVisible();
+ let s = void 0 !== t;
+ r || (r = l);
+ for (
+ var u = e.traverseNextNode();
+ u && n < PageScanCharactersSearchedThreshold;
+ u = u.traverseNextNode()
+ ) {
+ var c = u.localName;
+ if (u === r) {
+ var d = this._pageScanContext;
+ d && !n && (d.forwardScanIsFutile = !0);
+ break;
+ }
+ if (this._isRenderedFormControl(u)) {
+ if (u.isVisible() || !a) break;
+ } else {
+ if (this._isLabelElement(u) && u.isVisible()) break;
+ if ("tr" === c) break;
+ if ("ul" === c || "ol" === c || "dl" === c) break;
+ if (u.nodeType == Node.TEXT_NODE && u.isVisible()) {
+ if (void 0 !== t && (!u.parentNode || u.parentNode.tagName !== t))
+ continue;
+ if (((n += this._collectStringFromNodeForPageScan(u, o, n)), s))
+ break;
+ }
+ }
+ }
+ return o;
+ }
+ _matchFromPageScanAfterElement(e, t, r) {
+ var o = this._pageScanContext
+ ? this._pageScanContext.forwardScanCache
+ : null,
+ n = this._pageScanDataForElementWithCacheAndDataProducer(
+ t,
+ o,
+ this._dataForComputingMatchFromPageScanAfterElement.bind(this),
+ r,
+ );
+ return this._matchFromPatternMatcherAndStringsFromPageScan(e, n);
+ }
+ _pageScanDataForElementWithCacheAndDataProducer(e, t, r, o) {
+ if (!t) return r(e, o);
+ if ((n = t.get(e))) return n;
+ var n = r(e, o);
+ return (t.set(e, n), n);
+ }
+ _matchFromPatternMatcherAndStringsFromPageScan(e, t) {
+ for (var r = t.length, o = 0, n = 0; n < r; ++n) {
+ var i = t[n];
+ o += i.length;
+ var l = FormMetadataJSController.fieldLabelToInfo(
+ new JSFieldLabelPatternMatcher(e.dfa(), i).searchReverse(),
+ );
+ if (l)
+ return {
+ Distance: o,
+ Match: l[0],
+ Property: l[1],
+ Category: l[2],
+ ParentProperty: l[3],
+ };
+ }
+ return null;
+ }
+ _matchPatternAgainstString(e, t) {
+ if (!t) return null;
+ var r = t.replace(/[\d_.-]/g, " ");
+ return (
+ (r = r.replace(/[a-z][A-Z]/g, function (e) {
+ return e[0] + " " + e[1];
+ })),
+ FormMetadataJSController.fieldLabelToInfo(
+ new JSFieldLabelPatternMatcher(e.dfa(), r).longestMatch(),
+ )
+ );
+ }
+ _controlsAreAllButtons(e) {
+ for (var t = e.length, r = 0; r < t; ++r) {
+ if (!(e[r] instanceof HTMLButtonElement)) return !1;
+ }
+ return !0;
+ }
+ _createLogicalFormsForControls(e, t, r) {
+ if (this._controlsAreAllButtons(e)) return [];
+ let o,
+ n,
+ i = e.map(function (e) {
+ return e.getBoundingClientRect();
+ }),
+ l = e.length,
+ a = 0;
+ i[0].isZeroRect() ? ((o = 0), (n = null)) : ((o = 1), (n = i[0]));
+ for (let d = 1; d < l; ++d) {
+ let h = i[d];
+ if (!h.isZeroRect()) {
+ if (n) {
+ let m = n.distanceToRect(h);
+ m && (++o, (a += m));
+ }
+ n = h;
+ }
+ }
+ if (1 === o) {
+ function F(e) {
+ return e.closest("header, footer, aside");
+ }
+ let f = [],
+ g = 0;
+ for (; g < l;) {
+ let C = [e[g]],
+ p = F(e[g]);
+ for (let y = g + 1; y < l; ++y) {
+ let b = e[y];
+ if (p !== F(e[y])) break;
+ C.push(b);
+ }
+ (f.push(new LogicalForm(C, t, r)), (g += C.length));
+ }
+ return f;
+ }
+ let s = o ? a / o : 0,
+ u = [],
+ c = 0;
+ for (; c < l;) {
+ let A = [e[c]],
+ _ = !1,
+ T = i[c].isZeroRect() ? null : i[c];
+ for (let w = c + 1; w < l; ++w) {
+ let E = e[w],
+ S = i[w];
+ if (!S.isZeroRect()) {
+ if (_) {
+ if (T && T.distanceToRect(S) > s) break;
+ } else _ = couldBeFormSubmissionControl(E);
+ T = S;
+ }
+ A.push(E);
+ }
+ (u.push(new LogicalForm(A, t, r)), (c += A.length));
+ }
+ return u;
+ }
+ _formLooksLikeAspnetForm(e) {
+ const t = 3;
+ var r = 0;
+ ("aspnetForm" === e.getAttribute("id") && ++r,
+ "aspnetForm" === e.getAttribute("name") && ++r);
+ for (
+ var o = queryAllBySelector(e, "input"), n = 0, i = o.length;
+ n < i;
+ ++n
+ ) {
+ var l = o[n],
+ a = l.getAttribute("id"),
+ s = l.getAttribute("name");
+ (/ctl\d\d_/.test(a) && ++r,
+ /ctl\d\d\$/.test(s) && ++r,
+ "hidden" === l.getAttribute("type") &&
+ (("__VIEWSTATE" === s && "__VIEWSTATE" === a) ||
+ ("__EVENTTARGET" === s && "__EVENTTARGET" === a) ||
+ ("__EVENTARGUMENT" === s && "__EVENTARGUMENT" === a) ||
+ ("__LASTFOCUS" === s && "__LASTFOCUS" === a)) &&
+ ++r);
+ }
+ for (
+ var u = queryAllBySelector(document, "script"), c = u.length, d = 0;
+ d < c;
+ ++d
+ ) {
+ var h = anchorWithURLString(u[d].src);
+ if (h.host === window.location.host) {
+ var m = lastPathComponentFromAnchor(h);
+ ("WebResource.axd" !== m && "ScriptResource.axd" !== m) || ++r;
+ }
+ }
+ return r >= t;
+ }
+ _anchorLooksLikeSubmitButton(e) {
+ return (
+ !(
+ !e.classList.contains("button") ||
+ !/submit/i.test(e.getAttribute("action"))
+ ) || /submit|button/i.test(e.getAttribute("id"))
+ );
+ }
+ _visibleInputAndSelectElementsInForm(e) {
+ let t = queryAllBySelector(e, "input:not([type='hidden']), select"),
+ r = [];
+ for (var o = 0, n = t.length; o < n; ++o) {
+ let e = t[o];
+ e.isVisible() && r.push(e);
+ }
+ return r;
+ }
+ _elementsActingAsButtonsInForm(e) {
+ let t = Array.prototype.slice.call(
+ queryAllBySelector(e, "input[type='submit'], input[type='image']"),
+ ),
+ r = queryAllBySelector(e, "a");
+ for (var o = 0, n = r.length; o < n; ++o) {
+ let e = r[o];
+ this._anchorLooksLikeSubmitButton(e) && e.isVisible() && t.push(e);
+ }
+ return t;
+ }
+ _logicalFormsForAspnetForm(e) {
+ function t(e) {
+ var r = e.length;
+ if (r <= 1)
+ a.push(
+ new LogicalForm(e, ForceNonFormElementAsLogicalBackingElement.Yes),
+ );
+ else {
+ var o = r - 1,
+ n = e[o];
+ if (e[0].closestCommonAncestor(n) instanceof HTMLTableRowElement) {
+ for (var i = 0; i < o; ++i) {
+ if (!(e[i].closestCommonAncestor(n) instanceof HTMLTableRowElement))
+ return (t(e.slice(0, i)), void t(e.slice(i)));
+ }
+ a.push(
+ new LogicalForm(e, ForceNonFormElementAsLogicalBackingElement.Yes),
+ );
+ } else
+ a.push(
+ new LogicalForm(e, ForceNonFormElementAsLogicalBackingElement.Yes),
+ );
+ }
+ }
+ for (
+ var r = this._visibleInputAndSelectElementsInForm(e),
+ o = r.length,
+ n = this._elementsActingAsButtonsInForm(e),
+ i = n.length,
+ l = 0;
+ l < i;
+ ++l
+ ) {
+ (s = n[l]).getAttribute("id") &&
+ (s._aspNetIDComponents = s.getAttribute("id").split("_"));
+ }
+ n.sort(function (e, t) {
+ var r = e._aspNetIDComponents || [];
+ return (t._aspNetIDComponents || []).length - r.length;
+ });
+ var a = [];
+ for (l = 0; l < i; ++l) {
+ var s,
+ u = (s = n[l])._aspNetIDComponents;
+ if (u) {
+ var c = u.length;
+ if (!(c < 2)) {
+ for (
+ var d = u.joinFirstItems("_", c - 1) + "_", h = [], m = o - 1;
+ m >= 0;
+ --m
+ ) {
+ var F = r[m],
+ f = F.getAttribute("id");
+ f && f.startsWith(d) && (h.push(F), r.splice(m, 1));
+ }
+ if ((h.length && t(h.reverse()), !(o = r.length))) break;
+ }
+ }
+ }
+ return (o && t(r), a);
+ }
+ _logicalFormsInPage(e, t) {
+ let r = [];
+ const o = document.querySelector("form form");
+ let n = {},
+ i = o ? document.forms : queryAllBySelector(document, "form");
+ const l = 400,
+ a = (e) => (e.length <= l ? e : Array.from(e).slice(0, l)),
+ s = (e, t, r) => {
+ let o = queryAllBySelector(e, t);
+ return o.length <= l ? o : a(queryAllBySelector(e, r));
+ };
+ let u = 0,
+ c = i.length,
+ d = new Set();
+ for (var h = 0; h < c; ++h) {
+ let l = i[h],
+ c = o
+ ? a(l.elements)
+ : s(
+ l,
+ "input, select, textarea, button, fieldset, *[contenteditable]",
+ "input, select, textarea, button[type='submit'], fieldset, *[contenteditable]",
+ );
+ for (let e of c) d.add(e);
+ if (c.length) {
+ if ((u++, e && u >= e)) return r;
+ if (t) {
+ let e = [l.method, l.name, l.action, l.className].join("|"),
+ r = n[e] || 0;
+ if (r > t) continue;
+ n[e] = r + 1;
+ }
+ this._formLooksLikeAspnetForm(l)
+ ? (r = r.concat(this._logicalFormsForAspnetForm(l)))
+ : r.push(new LogicalForm(c));
+ }
+ }
+ let m = [],
+ F = s(
+ document,
+ "input, select, textarea, *[contenteditable=true][role=textbox], button",
+ "input, select, textarea, *[contenteditable=true][role=textbox], button[type='submit']",
+ ),
+ f = F.length;
+ for (let e = 0; e < f; ++e) {
+ let t = F[e];
+ if (d.has(t)) {
+ if (!m.length) continue;
+ ((r = r.concat(this._createLogicalFormsForControls(m))), (m = []));
+ } else
+ (this._isRenderedFormControl(t) || autocompleteTokens(t)) && m.push(t);
+ }
+ m.length && (r = r.concat(this._createLogicalFormsForControls(m)));
+ let g = r.length;
+ for (h = 0; h < g - 1; ++h) {
+ let e = r[h],
+ t = e.backingElement,
+ o = t.getBoundingClientRect(),
+ n = r[h + 1],
+ i = n.backingElement,
+ l = i.getBoundingClientRect();
+ const a = 40;
+ if (
+ t.nextElementSibling === i &&
+ t.action === i.action &&
+ o.height &&
+ l.height &&
+ o.x === l.x &&
+ o.width === l.width &&
+ o.bottom + a >= l.top
+ ) {
+ let t = e.elements,
+ o =
+ 1 ===
+ t.filter(function (e) {
+ return e.isVisible();
+ }).length,
+ i = t.includes(function (e) {
+ return e.matches("input[type=submit], button") && e.isVisible();
+ });
+ if (o && !i) {
+ let e = t.concat(n.elements),
+ o = this._createLogicalFormsForControls(
+ e,
+ ForceNonFormElementAsLogicalBackingElement.Yes,
+ LogicalFormCreationIsProvisional.Yes,
+ );
+ if (1 === o.length) {
+ let e = o[0];
+ (e.markElementsAsPartOfLogicalForm(), r.splice(h, 2, e), g--);
+ }
+ }
+ }
+ }
+ return r;
+ }
+ _matchPatternAgainstElement(e, t, r) {
+ function o(e, t) {
+ if (!e) return null;
+ const o = r[t] || "",
+ n = sharedPrefixLength(o, e[t] || "");
+ return n ? o.substr(n) : null;
+ }
+ function n(e, t) {
+ if (!t) return null;
+ const r = t.text;
+ if (/^-.+-$/.test(r)) return r;
+ if (!t.af_value().length && r.length) {
+ const o = e.options,
+ n = o.length;
+ let i = !0;
+ for (let e = 0; e < n; ++e) {
+ const r = o[e];
+ if (r !== t && !r.af_value().length) {
+ i = !1;
+ break;
+ }
+ }
+ if (i) return r;
+ }
+ return null;
+ }
+ this._logicalFormsCache.logicalFormForControl(r);
+ var i = r._weakPreviousControlInLogicalForm?.deref(),
+ l = r._weakNextControlInLogicalForm?.deref();
+ const a = ["name", "id"],
+ s = a.length;
+ for (var u = new Array(s), c = new Array(s), d = 0; d < s; ++d) {
+ var h = a[d];
+ ((u[d] = o(i, h)), (c[d] = o(l, h)));
+ }
+ const m = t.length;
+ for (var F = 0; F < m; ++F) {
+ var f,
+ g = t[F];
+ for (
+ d = 0;
+ d < s &&
+ !(f = this._matchPatternAgainstString(g, u[d])) &&
+ !(f = this._matchPatternAgainstString(g, c[d])) &&
+ !(f = this._matchPatternAgainstString(g, r[a[d]]));
+ ++d
+ );
+ const o = isSelectElement(r);
+ if (!f && o) {
+ const e = o ? defaultOptionForSelectElement(r) : null,
+ t = o ? r.options[0] : null;
+ let i = n(r, e);
+ (i || e === t || (i = n(r, t)),
+ (f = this._matchPatternAgainstString(g, i)));
+ }
+ f &&
+ e.push({
+ FoundByPageScan: !1,
+ Match: f[0].toLowerCase(),
+ Property: f[1],
+ Category: f[2],
+ ParentProperty: f[3],
+ Priority: F,
+ });
+ }
+ }
+ _labelsForElement(e) {
+ if (e._cachedLabels) return e._cachedLabels;
+ e._cachedLabels = [];
+ let t = e.getAttribute("aria-labelledby");
+ if (t && t.length) {
+ let o = t.split(" ");
+ for (var r = 0; r < o.length; r++) {
+ let t = getElementByID(o[r]);
+ t && e._cachedLabels.push(t);
+ }
+ }
+ if (e._cachedLabels.length) return e._cachedLabels;
+ let o = function (e) {
+ return e.replace(/[^a-zA-Z0-9]+/g, "");
+ };
+ for (let t of [e.getAttribute("id"), e.getAttribute("name")]) {
+ if (!t || !t.length) continue;
+ let r = [],
+ n = e.form;
+ for (let i of this._labels) {
+ if (n === i.closest("form")) {
+ let n = i.getAttribute("for");
+ if (n === t) e._cachedLabels.push(i);
+ else if (n) {
+ let e = o(n);
+ e.length > 0 && e === o(t) && r.push(i);
+ }
+ }
+ }
+ if (
+ (0 === e._cachedLabels.length &&
+ 1 === r.length &&
+ (e._cachedLabels = r),
+ e._cachedLabels.length)
+ )
+ return e._cachedLabels;
+ }
+ let n = this._logicalFormsCache.logicalFormForControl(e)?.formElement;
+ for (
+ let t = e.parentElementIncludingShadowDOMHost();
+ t && t !== n;
+ t = t.parentElementIncludingShadowDOMHost()
+ )
+ if (this._isLabelElement(t)) {
+ e._cachedLabels.push(t);
+ break;
+ }
+ return e._cachedLabels;
+ }
+ _matchesForElement(e, t, r = !1) {
+ function o(e, r) {
+ for (var o = 0; o < l; ++o) {
+ var n = FormMetadataJSController.fieldLabelToInfo(
+ new JSFieldLabelPatternMatcher(t[o].dfa(), e).searchReverse(),
+ );
+ if (
+ n &&
+ (i.push({
+ FoundByPageScan: !1,
+ Match: n[0].toLowerCase(),
+ Property: n[1],
+ Category: n[2],
+ ParentProperty: n[3],
+ Priority: o,
+ }),
+ r === ShouldStopAfterFirstMatch.StopAfterFirstMatch)
+ )
+ return;
+ }
+ }
+ function n(e, t) {
+ return e &&
+ e.Match.length &&
+ (!t ||
+ (!e.IsInCellAbove && t.IsInCellAbove) ||
+ (e.IsInCellAbove == t.IsInCellAbove && e.Distance < t.Distance))
+ ? {
+ FoundByPageScan: !0,
+ Match: y.Match.toLowerCase(),
+ Property: y.Property,
+ Category: y.Category,
+ ParentProperty: y.ParentProperty,
+ Priority: _,
+ }
+ : t;
+ }
+ var i = [],
+ l = t.length;
+ this._matchPatternAgainstElement(i, t, e);
+ for (var a = !1, s = this._labelsForElement(e), u = 0; u < s.length; ++u) {
+ var c = s[u].innerText;
+ c && ((a = !0), o(c, ShouldStopAfterFirstMatch.StopAfterFirstMatch));
+ }
+ let d = placeholderInfoForElement(e);
+ d &&
+ !d.AttributeMatchedWasValue &&
+ o(d.Text, ShouldStopAfterFirstMatch.StopAfterFirstMatch);
+ var h = e.getAttribute("title");
+ h && o(h, ShouldStopAfterFirstMatch.StopAfterFirstMatch);
+ var m =
+ this._labelForElementIfElementAndLabelAreOnlyElementsOfTheirKindAmongSiblingElements(
+ e,
+ );
+ m?.innerText.length &&
+ ((a = !0), o(m.innerText, ShouldStopAfterFirstMatch.CollectAllMatches));
+ let F = this._ariaLabelForElementOrParentOfElement(e);
+ F && o(F, ShouldStopAfterFirstMatch.StopAfterFirstMatch);
+ var f = e.getAttribute("formcontrolname");
+ f && f.length && o(f, ShouldStopAfterFirstMatch.StopAfterFirstMatch);
+ var g = this._pageScanContext,
+ C = !0,
+ p = !1;
+ if (
+ (g &&
+ (g.shouldUsePageScan && (C = g.shouldUsePageScan()),
+ g.reportPageScanUsedSuccessfully && (p = !0)),
+ !C)
+ )
+ return i;
+ if (a) return (p && g.reportPageScanUsedSuccessfully(!1), i);
+ if (!0 === r) return i;
+ for (var y, b = null, A = null, _ = 0; _ < l; ++_)
+ ((b = n((y = this._matchFromPageScanBeforeElement(t[_], e)), b)),
+ (g && g.forwardScanIsFutile) ||
+ (A = n((y = this._matchFromPageScanAfterElement(t[_], e)), A)));
+ var T = !1;
+ if ((b && (i.push(b), (T = !0)), A))
+ for (var w = 0, E = i.length; w < E; ++w) {
+ var S = i[w];
+ if (A.Priority === S.Priority) {
+ (i.push(A), (T = !0));
+ break;
+ }
+ }
+ return (
+ p && g.reportPageScanUsedSuccessfully(T),
+ i.length &&
+ d &&
+ d.AttributeMatchedWasValue &&
+ o(d.Text, ShouldStopAfterFirstMatch.StopAfterFirstMatch),
+ i
+ );
+ }
+ _bestMatchFromMatches(e, t, r) {
+ function o(e, t) {
+ for (var r = e.length, o = {}, n = 0; n < r; ++n) {
+ var i,
+ l = e[n];
+ switch (t) {
+ case MatchCriteria.Property:
+ i = l.Property || l.Match;
+ break;
+ case MatchCriteria.Category:
+ i = l.Category || l.Match;
+ break;
+ case MatchCriteria.Literal:
+ i = l.Match;
+ }
+ o[i]
+ ? (o[i].Frequency += 1)
+ : (o[i] = { Frequency: 1, FirstMatchObject: l });
+ }
+ var a = [];
+ for (var s in o) a.push(o[s]);
+ var u = a.sort(function (e, t) {
+ return t.Frequency - e.Frequency;
+ }),
+ c = u.length;
+ if (c <= 1) return null;
+ if (t === MatchCriteria.Property)
+ for (n = 0; n < c; ++n) {
+ if (u[n].FirstMatchObject.ParentProperty in o)
+ return u[n].FirstMatchObject;
+ }
+ return u[0].Frequency > u[1].Frequency ? u[0].FirstMatchObject : void 0;
+ }
+ var n = e.length;
+ if (0 === n) return null;
+ if (1 === n) return e[0];
+ var i = o(e, MatchCriteria.Property);
+ return (
+ i ||
+ ((i = o(e, MatchCriteria.Category))
+ ? i
+ : e.sort(function (e, t) {
+ return e.Priority - t.Priority;
+ })[0])
+ );
+ }
+ _bestMatchForElement(e, t, r = !1) {
+ if (!e) return null;
+ var o = this._matchesForElement(e, t, r);
+ return this._bestMatchFromMatches(o, e, t);
+ }
+ _labelForElementIfElementAndLabelAreOnlyElementsOfTheirKindAmongSiblingElements(
+ e,
+ ) {
+ for (
+ var t = null,
+ r = e.tagName,
+ o = siblingsIncludingSelfForElement(e),
+ n = o.length,
+ i = 0;
+ i < n;
+ ++i
+ ) {
+ var l = o[i];
+ if (e !== l) {
+ if (r === l.tagName) return null;
+ if (this._isLabelElement(l)) {
+ if (t) return null;
+ t = l;
+ }
+ }
+ }
+ return t;
+ }
+ _ariaLabelForElementOrParentOfElement(e) {
+ var t = e;
+ let r = 3;
+ for (var o = 0; o < r && t; ++o) {
+ let e = t.getAttribute("aria-label");
+ if (e && !t.isHiddenFromAccessibilityTree()) return e;
+ t = t.parentElementIncludingShadowDOMHost();
+ }
+ return null;
+ }
+ _cachedOneTimeCodePatternMatcher() {
+ return this._cachedPatternMatchers(
+ "oneTimeCodeFieldLabelPatternMatchers",
+ )[0];
+ }
+ _cachedLoginFormTypePatternMatcher() {
+ return this._cachedPatternMatchers("loginFormTypePatternMatchers")[0];
+ }
+ _cachedFederatedSignInAffordancePatternMatcher() {
+ return this._cachedPatternMatchers(
+ "federatedSignInAffordancePatternMatchers",
+ )[0];
+ }
+ _cachedPatternMatchers(e) {
+ let t = "_" + e,
+ r = this[t];
+ return (r || ((this[t] = FormMetadataJSController[e]), (r = this[t])), r);
+ }
+ _cachedElementPatternMatch(e, t, r) {
+ var o = t + "_wasVisible",
+ n = e[o];
+ if (!0 === n) return e[t];
+ var i = e.isVisible();
+ if (n === i) return e[t];
+ e[o] = i;
+ let l = this._cachedPatternMatchers(r);
+ return ((e[t] = this._bestMatchForElement(e, l)), e[t]);
+ }
+ _isLabeledUsernameField(e) {
+ return (
+ !!this._isAutoFillableTextField(e) &&
+ null !==
+ this._cachedElementPatternMatch(
+ e,
+ "_usernameFieldPatternMatch",
+ "usernameFieldLabelPatternMatchers",
+ )
+ );
+ }
+ _isLabeledLoginField(e) {
+ return (
+ !!this._isAutoFillableTextField(e) &&
+ null !==
+ this._cachedElementPatternMatch(
+ e,
+ "_loginFieldPatternMatch",
+ "loginFormTypePatternMatchers",
+ )
+ );
+ }
+ _isLabeledSignUpField(e) {
+ return (
+ !!this._isAutoFillableTextField(e) &&
+ null !==
+ this._cachedElementPatternMatch(
+ e,
+ "_signUpFieldPatternMatch",
+ "newAccountFormTypePatternMatchers",
+ )
+ );
+ }
+ _isLabeledEmailField(e) {
+ return (
+ !!this._isAutoFillableTextField(e) &&
+ ("email" === e.type ||
+ null !==
+ this._cachedElementPatternMatch(
+ e,
+ "_emailFieldPatternMatch",
+ "emailFieldLabelPatternMatchers",
+ ))
+ );
+ }
+ _addressBookLabelForElement(e) {
+ if (!this._isAutoFillableTextFieldOrSelectElementOrTextAreaElement(e))
+ return null;
+ var t = this._cachedElementPatternMatch(
+ e,
+ "_addressBookPatternMatch",
+ "addressBookFieldLabelPatternMatchers",
+ );
+ return t ? t.Match : null;
+ }
+ _elementDisallowsAutocomplete(e) {
+ var t = e.getAttribute("autocomplete");
+ return t && "off" === t.toLowerCase();
+ }
+ _isTextArea(e) {
+ return e instanceof HTMLTextAreaElement;
+ }
+ _isLabelElement(e) {
+ return e instanceof HTMLLabelElement;
+ }
+ _isRenderedFormControl(e) {
+ var t = e.localName;
+ if (!t) return !1;
+ return (
+ t in
+ {
+ button: !0,
+ isindex: !0,
+ fieldset: !0,
+ legend: !0,
+ meter: !0,
+ optgroup: !0,
+ option: !0,
+ progress: !0,
+ select: !0,
+ textarea: !0,
+ } ||
+ !!isContentEditableSingleLineTextbox(e) ||
+ (e instanceof HTMLInputElement &&
+ (!!this._isElementAHiddenUsername(e) || !e.type || "hidden" !== e.type))
+ );
+ }
+ _isEditablePlainTextField(e) {
+ return (
+ !!isInputElement(e) &&
+ !e.disabled &&
+ !e.readOnly &&
+ (!e.type || "text" === e.type)
+ );
+ }
+ _isTextField(e) {
+ if (this._isTextArea(e)) return !0;
+ if (isContentEditableSingleLineTextbox(e)) return !0;
+ if (!isInputElement(e)) return !1;
+ const t = {
+ date: !0,
+ "datetime-local": !0,
+ email: !0,
+ isindex: !0,
+ month: !0,
+ number: !0,
+ password: !0,
+ search: !0,
+ tel: !0,
+ telephone: !0,
+ text: !0,
+ time: !0,
+ url: !0,
+ week: !0,
+ },
+ r = e.type;
+ return !r || r in t;
+ }
+ _setSelectionStartAndEnd(e, t, r) {
+ null !== e.selectionStart && null !== e.selectionEnd
+ ? ((e.selectionStart = t), (e.selectionEnd = r))
+ : 0 === t &&
+ r === e.af_value().length &&
+ "function" == typeof e.select &&
+ e.select();
+ }
+ _isAutofocusedTextField(e) {
+ return !!this._isTextField(e) && !0 === e.autofocus;
+ }
+ _isAutoFilledTextField(e) {
+ return !!this._isTextField(e) && e.matches(":-webkit-autofill");
+ }
+ _isSecureTextField(e) {
+ if (!isInputElement(e)) return !1;
+ if (e._wasPreviouslySecureTextField) return !0;
+ try {
+ if (e.matches(":-webkit-autofill-strong-password"))
+ return ((e._wasPreviouslySecureTextField = !0), !0);
+ } catch (e) {}
+ const t = getComputedStyle(e, null).getPropertyValue(
+ "-webkit-text-security",
+ ),
+ r = e.type;
+ if ("none" !== t || "password" === r)
+ return ((e._wasPreviouslySecureTextField = !0), !0);
+ if (r && "text" !== r) return !1;
+ if (userIsOnDomain("ninehours.co.jp")) {
+ let t = e.name;
+ if ("guestPassword" === t || "guestPasswordConfirm" === t) return !0;
+ }
+ const o = e._weakNextControlInLogicalForm?.deref();
+ return (
+ !!(
+ (o && this._looksLikeShowHidePasswordButton(o)) ||
+ userIsOnDomain("temu.com")
+ ) &&
+ !!this._matchesPasswordFieldLabelPattern(e) &&
+ !this._isLabeledUsernameField(e) &&
+ ((e._wasPreviouslySecureTextField = !0), !0)
+ );
+ }
+ _isVerticalWritingMode(e) {
+ const t = getComputedStyle(e).writingMode;
+ return !("horizontal-tb" === t || "horizontal-bt" === t);
+ }
+ _looksClickableBasedOnCursorStyle(e) {
+ const t = e?.parentElement;
+ if (!t) return !1;
+ const r = getComputedStyle(e).cursor;
+ return "pointer" === r && r !== getComputedStyle(t).cursor;
+ }
+ _looksLikePasswordCredentialField(e, t) {
+ if (!this._isSecureTextField(e)) return !1;
+ var r = e.getAttribute("maxlength");
+ return (
+ !(
+ r && parseInt(r) < MinValueForMaxLengthAttributeToTreatAsPasswordField
+ ) &&
+ null ===
+ this._cachedElementPatternMatch(
+ e,
+ "_nonAccountPasswordSecureTextEntryFieldPatternMatch",
+ "nonAccountPasswordSecureTextEntryFieldLabelPatternMatchers",
+ )
+ );
+ }
+ _looksLikeShowHidePasswordButton(e) {
+ return (
+ !(!this._isCustomFormButton(e) && !this._isCheckboxInputElement(e)) &&
+ !!this._cachedElementPatternMatch(
+ e,
+ "_showHideButtonPatternMatch",
+ "showHideButtonLabelPatternMatchers",
+ )
+ );
+ }
+ _isAutoFillable(e) {
+ return !e.disabled && !e.readOnly;
+ }
+ _isAutoFillableSelectElement(e) {
+ return this._isAutoFillable(e) && isSelectElement(e);
+ }
+ _isAutoFillableTextAreaElement(e) {
+ return this._isAutoFillable(e) && this._isTextArea(e);
+ }
+ _isAutoFillableTextField(e) {
+ return this._isAutoFillable(e) && this._isTextField(e);
+ }
+ _isAutoFillableTextFieldOrSelectElementOrTextAreaElement(e) {
+ return (
+ !!this._isAutoFillable(e) &&
+ (this._isTextField(e) || isSelectElement(e) || this._isTextArea(e))
+ );
+ }
+ _looksLikeCreditCardNumberField(e, t) {
+ if (!this._isAutoFillableTextField(e)) return !1;
+ let r = e.pattern;
+ if (r) {
+ let e = regularExpressionFromUntrustedPatternAttributeString(r);
+ if (e && (e.test("a") || e.test("A"))) return !1;
+ }
+ if (
+ this._cachedElementPatternMatch(
+ e,
+ "_nonCreditCardNumberPatternMatch",
+ "nonCreditCardCardNumberFieldLabelPatternMatchers",
+ )
+ )
+ return !1;
+ if (
+ this._matchesCreditCardCompositeExpirationDateFieldLabelPatternMatchers(e)
+ )
+ return !1;
+ if (elementIDOrAutocompleteTokensHasToken(e, t, "cc-number")) return !0;
+ const o = e.placeholder;
+ let n = new RegExp("[0-9]{4}[ -][0-9]{4}[ -][0-9]{4}[ -][0-9]{4}");
+ if (o && n.test(o)) return !0;
+ let i = e.getAttribute("data-val-regex-pattern");
+ if (i) {
+ let e = regularExpressionFromUntrustedPatternAttributeString(i);
+ if (e && !e.test("12345")) return !1;
+ }
+ return (
+ null !==
+ this._cachedElementPatternMatch(
+ e,
+ "_creditCardNumberPatternMatch",
+ "creditCardNumberFieldLabelPatternMatchers",
+ )
+ );
+ }
+ _looksLikeCreditCardSecurityCodeField(e, t) {
+ if (!this._isAutoFillableTextField(e)) return !1;
+ if (elementIDOrAutocompleteTokensHasToken(e, t, "cc-csc")) return !0;
+ let r = e.getAttribute("pattern");
+ if (r) {
+ let e = regularExpressionFromUntrustedPatternAttributeString(r);
+ if (e && !e.test("123") && !e.test("1234")) return !1;
+ }
+ return (
+ null !==
+ this._cachedElementPatternMatch(
+ e,
+ "_creditCardSecurityCodePatternMatch",
+ "creditCardSecurityCodeFieldLabelPatternMatchers",
+ )
+ );
+ }
+ _looksLikeCreditCardCardholderField(e, t) {
+ return (
+ !!this._isEditablePlainTextField(e) &&
+ (!!elementIDOrAutocompleteTokensHasToken(e, t, "cc-name") ||
+ null !==
+ this._cachedElementPatternMatch(
+ e,
+ "_creditCardCardholderPatternMatch",
+ "creditCardCardholderFieldLabelPatternMatchers",
+ ))
+ );
+ }
+ _looksLikeCreditCardCompositeExpirationDateField(e, t) {
+ return (
+ !(!this._isAutoFillableTextField(e) || this._isSecureTextField(e)) &&
+ (!!elementIDOrAutocompleteTokensHasToken(e, t, "cc-exp") ||
+ this._matchesCreditCardCompositeExpirationDateFieldLabelPatternMatchers(
+ e,
+ ))
+ );
+ }
+ _matchesCreditCardCompositeExpirationDateFieldLabelPatternMatchers(e) {
+ return (
+ null !==
+ this._cachedElementPatternMatch(
+ e,
+ "_creditCardCompositeExpirationDateFieldPatternMatch",
+ "creditCardCompositeExpirationDateFieldLabelPatternMatchers",
+ )
+ );
+ }
+ _looksLikeCreditCardTypeField(e, t) {
+ return (
+ !(!isSelectElement(e) && !isRadioButtonElement(e)) &&
+ (!!elementIDOrAutocompleteTokensHasToken(e, t, "cc-type") ||
+ null !==
+ this._cachedElementPatternMatch(
+ e,
+ "_creditCardTypePatternMatch",
+ "creditCardTypeFieldLabelPatternMatchers",
+ ))
+ );
+ }
+ _looksLikeEIDField(e, t) {
+ return elementIDOrAutocompleteTokensHasToken(e, t, "device-eid");
+ }
+ _looksLikeIMEIField(e, t) {
+ return elementIDOrAutocompleteTokensHasToken(e, t, "device-imei");
+ }
+ _looksLikeIMEI1Field(e, t) {
+ return elementIDOrAutocompleteTokensHasToken(e, t, "device-imei1");
+ }
+ _looksLikeIMEI2Field(e, t) {
+ return elementIDOrAutocompleteTokensHasToken(e, t, "device-imei2");
+ }
+ _looksLikeNALField(e, t) {
+ return elementIDOrAutocompleteTokensHasToken(e, t, "device-nal");
+ }
+ _looksLikeDayField(e) {
+ return (
+ !(
+ !this._isAutoFillableTextField(e) &&
+ !this._isAutoFillableSelectElement(e)
+ ) &&
+ null !==
+ this._cachedElementPatternMatch(
+ e,
+ "_dayFieldPatternMatch",
+ "dayFieldLabelPatternMatchers",
+ )
+ );
+ }
+ _looksLikeMonthField(e, t) {
+ if (
+ !this._isAutoFillableTextField(e) &&
+ !this._isAutoFillableSelectElement(e)
+ )
+ return !1;
+ if (elementIDOrAutocompleteTokensHasToken(e, t, "cc-exp-month")) return !0;
+ if (
+ null !==
+ this._cachedElementPatternMatch(
+ e,
+ "_monthFieldPatternMatch",
+ "monthFieldLabelPatternMatchers",
+ )
+ )
+ return !0;
+ if ("select" !== this._getTagName(e).toLowerCase()) return !1;
+ var r = e.options.length;
+ if (12 === r || 13 === r)
+ for (
+ var o = [
+ selectElementOptionsSequenceAnalysis(e, "text"),
+ selectElementOptionsSequenceAnalysis(e, "value"),
+ ],
+ n = o.length,
+ i = 0;
+ i < n;
+ i++
+ ) {
+ var l = o[i],
+ a = l.lengthOfLongestSequence,
+ s = l.lastNumberInSequence;
+ if (a >= 11 && 12 === s) return !0;
+ }
+ return !1;
+ }
+ _looksLikeYearField(e, t) {
+ if (
+ !this._isAutoFillableTextField(e) &&
+ !this._isAutoFillableSelectElement(e)
+ )
+ return !1;
+ if (elementIDOrAutocompleteTokensHasToken(e, t, "cc-exp-year")) return !0;
+ if (
+ null !==
+ this._cachedElementPatternMatch(
+ e,
+ "_yearFieldPatternMatch",
+ "yearFieldLabelPatternMatchers",
+ )
+ )
+ return !0;
+ if ("select" !== this._getTagName(e).toLowerCase()) return !1;
+ var r = selectElementOptionsSequenceAnalysis(e, "text"),
+ o = r.lengthOfLongestSequence,
+ n = r.lastNumberInSequence;
+ const i = 3;
+ return o >= e.options.length - i && 1e3 < n && n < 3e3;
+ }
+ _isPotentialInvisibleOneTimeCodeControl(e) {
+ return (
+ userIsOnDomain("baidu.com") && 6 === parseInt(e.getAttribute("maxlength"))
+ );
+ }
+ _looksLikeOneTimeCodeField(e, t, r, o, n, i, l) {
+ if (
+ !this._isAutoFillableTextField(e) &&
+ !this._isAutoFillableSelectElement(e)
+ )
+ return !1;
+ if (elementIDOrAutocompleteTokensHasToken(e, t, "one-time-code")) return !0;
+ const a = e.type;
+ if ("password" === a) {
+ if (/^(.+\.)?chase\.com\.?$/.test(document.location.hostname)) return !1;
+ if (this._matchesPasswordFieldLabelPattern(e)) return !1;
+ }
+ if (
+ /^(.+\.)?amazon\.(com|ae|com\.au|com\.br|ca|fr|de|in|it|com\.mx|nl|es|com\.tr|co\.uk|sa|sg|se|pl)\.?$/.test(
+ document.location.hostname,
+ )
+ ) {
+ const t = /claim|promo/i;
+ if (t.test(e.id) || t.test(e.name)) return !1;
+ }
+ if (
+ null !==
+ this._cachedElementPatternMatch(
+ e,
+ "_oneTimeCodePatternMatch",
+ "oneTimeCodeFieldLabelPatternMatchers",
+ )
+ )
+ return !0;
+ const s = e.getAttribute("maxlength"),
+ u = s ? parseInt(s) : void 0;
+ if (
+ isFiniteNumber(u) &&
+ u >
+ MaxLengthForFieldAboveWhichToTreatPotentialOneTimeCodeFieldAsRequiringHigherScrutiny
+ ) {
+ if (!i) return !1;
+ if (
+ l.ControlLooksLikeIgnoredDataTypeField ||
+ l.ControlLooksLikeCreditCardCardholderField ||
+ l.ControlLooksLikeCreditCardNumberField ||
+ l.ControlLooksLikeCreditCardSecurityCodeField ||
+ l.ControlLooksLikeCreditCardTypeField ||
+ l.AddressBookLabel
+ )
+ return !1;
+ }
+ let c = e.pattern;
+ if (c) {
+ let e = regularExpressionFromUntrustedPatternAttributeString(c);
+ if (
+ e &&
+ (e.test("1234") || e.test("123456") || e.test("12345678")) &&
+ !e.test("a") &&
+ !e.test("A")
+ )
+ return !0;
+ }
+ const d = "number" === a || "tel" === a;
+ if (1 === u) {
+ if (d || r || o) return !0;
+ const t = this._cachedOneTimeCodePatternMatcher(),
+ n = e.closest("fieldset"),
+ i = n?.querySelector("legend");
+ if (i) {
+ if (
+ e === (n ? Array.from(queryAllBySelector(n, "input")) : [])[0] &&
+ this._matchPatternAgainstString(t, i.innerText)
+ )
+ return !0;
+ }
+ for (let t of [n, e.parentElement, e.closest('*[role~="dialog"]')]) {
+ if (!t) continue;
+ const r = Array.from(queryAllBySelector(t, "input")),
+ o = r.length;
+ if (o >= 5 && o <= 8) {
+ if (e === r[0] && r.every((e) => 1 === parseInt(e.maxLength)))
+ return !0;
+ }
+ }
+ }
+ const h =
+ null !==
+ this._cachedElementPatternMatch(
+ e,
+ "_weakOneTimeCodePatternMatch",
+ "weakOneTimeCodeFieldLabelPatternMatchers",
+ );
+ if (d && h) return !0;
+ const m = e.placeholder;
+ if (m && h && /^[#]+$/.test(m.replace(/ /g, ""))) return !0;
+ const F = (function () {
+ if (isFiniteNumber(u)) return u;
+ const e = m?.length;
+ return e && e < 10 && m === m[0].repeat(e) ? e : void 0;
+ })();
+ if ((4 === F || 6 === F) && h) return !0;
+ if (7 === u && m && /\d{3} \d{3}/.test(m)) return !0;
+ if (this._isAutofocusedTextField(e)) {
+ if (h) return !0;
+ if ("0" === e.min && "9" === e.max) return !0;
+ }
+ if (i) {
+ if (h) {
+ if (
+ !(
+ null !==
+ this._cachedElementPatternMatch(
+ e,
+ "_codeButNotOneTimeCodeFieldLabelsPatternMatch",
+ "codeButNotOneTimeCodeFieldLabelsPatternMatchers",
+ )
+ ) &&
+ !this._matchSearchFieldLabelPattern(e)
+ ) {
+ let t = !0;
+ for (
+ let r = e.traversePreviousElement();
+ r;
+ r = r.traversePreviousElement()
+ )
+ if (isInputElement(r) && r.isVisible()) {
+ t = !1;
+ break;
+ }
+ if (t) return !0;
+ }
+ }
+ let t = 0;
+ (h && t++, r && t++, o && t++, n && t++, (4 !== F && 6 !== F) || t++);
+ const i = this._cachedOneTimeCodePatternMatcher(),
+ l = this._logicalFormsCache.logicalFormForControl(e);
+ if (l) {
+ const e = l.backingElement;
+ if (e) {
+ let r = !1;
+ for (let o of Array.from(
+ querySelectorAllIncludingWithinShadowRoots(e, "h1, h2, h3"),
+ )) {
+ let e = o.innerText.trim();
+ if (e.length) {
+ this._matchPatternAgainstString(i, e) && ((r = !0), t++);
+ break;
+ }
+ }
+ if (!r) {
+ const r = e.closest("section")?.querySelector("h1, h2, h3");
+ r && this._matchPatternAgainstString(i, r.innerText) && t++;
+ }
+ this._matchPatternAgainstString(i, e.getAttribute("id")) && t++;
+ }
+ }
+ const a = e.dataset.valRequired;
+ if (
+ ("string" == typeof a && this._matchPatternAgainstString(i, a) && t++,
+ t >= 2)
+ )
+ return !0;
+ const s = function (e) {
+ if (this._matchPatternAgainstString(i, e)) return !0;
+ const t = e.replaceAll("-", " ");
+ return e !== t && this._matchPatternAgainstString(i, t);
+ }.bind(this),
+ u = window.location.protocol,
+ c = "http:" === u || "https:" === u,
+ d = lastPathComponentFromAnchor(window.location);
+ if (c && d && s(d)) return !0;
+ {
+ const e = document.querySelector("link[rel=canonical]"),
+ t = e ? lastPathComponentForURLString(e.href) : null;
+ if (t && s(t)) return !0;
+ }
+ if (this._matchFromPageScanBeforeElement(i, e, document.body)) return !0;
+ }
+ return !1;
+ }
+ _looksLikeIgnoredDataTypeField(e, t) {
+ return (
+ !!this._isAutoFillableTextField(e) &&
+ !t?.length &&
+ null !==
+ this._cachedElementPatternMatch(
+ e,
+ "_ignoredDataTypePatternMatch",
+ "ignoredDataTypeFieldLabelPatternMatchers",
+ )
+ );
+ }
+ _looksLikeGenericAdditionalClassificationsControl(e) {
+ return (
+ null !==
+ this._cachedElementPatternMatch(
+ e,
+ "_genericAdditionalClassificationPatternMatch",
+ "genericAdditionalClassificationLabelPatternMatchers",
+ )
+ );
+ }
+ _looksLikeAdditionalClassificationsControl(e) {
+ if (this._isAutoFillableTextFieldOrSelectElementOrTextAreaElement(e))
+ return (
+ null !==
+ this._cachedElementPatternMatch(
+ e,
+ "_additionalClassificationControlPatternMatch",
+ "additionalClassificationControlLabelPatternMatchers",
+ )
+ );
+ }
+ _collectTextSample(e) {
+ if (!e) return "";
+ var t,
+ r = "",
+ o = e;
+ do {
+ ((t = (r = o.innerText.replace(/\s+/g, " ").trim()).length),
+ (o = o.parentElementIncludingShadowDOMHost()));
+ } while (
+ t < MaximumNumberOfCharactersToCollectForLanguageIdentification &&
+ o
+ );
+ return (
+ t > MaximumNumberOfCharactersToCollectForLanguageIdentification &&
+ (r = r.substr(
+ 0,
+ MaximumNumberOfCharactersToCollectForLanguageIdentification,
+ )),
+ r
+ );
+ }
+ _explicitMaxLength(e) {
+ var t = e.getAttribute("maxlength");
+ return t ? parseInt(t) : void 0;
+ }
+ _explicitMinLength(e) {
+ let t = e.getAttribute("minlength");
+ return t ? parseInt(t) : void 0;
+ }
+ _heuristicallyDeterminedMaxLength(e) {
+ const t = 20;
+ if ("password" !== e.type) return null;
+ const r = e.getAttribute("data-ng-maxlength");
+ if (r) {
+ const e = parseInt(r, 10);
+ if (isFiniteNumber(e)) return e;
+ }
+ const o = e.getAttribute("ng-pattern");
+ if (!o) return null;
+ if (!o.startsWith("/") || !o.endsWith("/")) return null;
+ let n = regularExpressionFromUntrustedPatternAttributeString(o);
+ if (!n) return null;
+ let i,
+ l = "a1Abbb",
+ a = !1;
+ for (; l.length <= t;) {
+ let e = n.test(l);
+ if (a && !e) return i;
+ (e && ((a = !0), (i = l.length)), (l += "b"));
+ }
+ return null;
+ }
+ _collectControlMetadata(e, t, r, o, n, i, l, a) {
+ var s = {
+ ControlTagName: this._getTagName(e),
+ ControlFieldName: this._getNameOrId(e),
+ ControlUniqueID: this.controlUniqueID(e),
+ };
+ (e === innermostActiveElement() && (s.ControlIsActiveElement = !0),
+ this._isAutoFilledTextField(e) && (s.ControlIsAutoFilledTextField = !0),
+ e.disabled && (s.ControlIsDisabled = !0),
+ e.readOnly && (s.ControlIsReadOnly = !0),
+ this._isTextField(e) && (s.ControlIsTextField = !0),
+ this._isSecureTextField(e) && (s.ControlIsSecureTextField = !0),
+ this._isLabeledUsernameField(e) && (s.ControlIsLabeledUsernameField = !0),
+ this._elementDisallowsAutocomplete(e) && (s.DisallowsAutocomplete = !0),
+ this._isAutofocusedTextField(e) && (s.ControlIsAutofocusedTextField = !0),
+ (s.ControlAutoFillButtonType = e.autofillButtonType),
+ (s.ControlLastAutoFillButtonType = e._lastAutofillButtonType));
+ const u = e.className;
+ u && u.length && (s.ControlFieldClass = u);
+ const c = e.id;
+ c && c.length && (s.ControlFieldID = c);
+ const d = e.af_value();
+ d && (s.ControlValue = d);
+ const h = this._associatedUsernameForControl(e);
+ h && (s.ControlAssociatedUsername = h);
+ const m = e.maxLength;
+ if (-1 !== m) s.ControlMaxLength = m;
+ else {
+ const t = this._heuristicallyDeterminedMaxLength(e);
+ t && (s.ControlMaxLength = t);
+ }
+ const F = this._explicitMinLength(e);
+ F && F > 0 && (s.ControlMinLength = F);
+ const f = e.size;
+ (f > 0 && (s.ControlSize = f),
+ e.isVisible() && (s.IsVisible = !0),
+ isDateTimeInputElement(e) &&
+ (s.ControlRequiredFormatForDateTimeInput =
+ this._requiredFormatForDateTimeInput[e.type]));
+ var g = autocompleteTokens(e);
+ (g &&
+ ((s.AutocompleteTokens = g),
+ -1 !== g.indexOf("username")
+ ? (s.ControlClaimsToBeUsernameViaAutocompleteAttribute = !0)
+ : -1 !== g.indexOf("current-password")
+ ? (s.ControlClaimsToBeCurrentPasswordViaAutocompleteAttribute = !0)
+ : -1 !== g.indexOf("new-password") &&
+ (s.ControlClaimsToBeNewPasswordViaAutocompleteAttribute = !0)),
+ this._looksLikePasswordCredentialField(e) &&
+ ((s.ControlLooksLikePasswordCredentialField = !0),
+ this._collectExtraControlMetadata(e, s),
+ s.IsVisible &&
+ !r &&
+ (s.IsVisible = !isElementPositionedToBeEffectivelyInvisible(e))));
+ let C = t === WBSFormMetadataRequestPreFill,
+ p = s.ControlIsActiveElement || !C;
+ if (p) {
+ const t = this._collectSelectElementInfo(e);
+ (t && (s.SelectElementInfo = t),
+ this._isVerticalWritingMode(e) &&
+ (s.ControlIsVerticalWritingMode = !0));
+ var y = placeholderInfoForElement(e);
+ y && !y.AttributeMatchedWasValue && (s.ControlPlaceholder = y.Text);
+ var b = e.getAttribute("type");
+ b && (s.ControlType = b);
+ }
+ if (
+ (this._looksLikeIgnoredDataTypeField(e, g)
+ ? (s.ControlLooksLikeIgnoredDataTypeField = !0)
+ : this._looksLikeCreditCardCardholderField(e, g)
+ ? (s.ControlLooksLikeCreditCardCardholderField = !0)
+ : this._looksLikeCreditCardNumberField(e, g)
+ ? (s.ControlLooksLikeCreditCardNumberField = !0)
+ : this._looksLikeCreditCardSecurityCodeField(e, g)
+ ? (s.ControlLooksLikeCreditCardSecurityCodeField = !0)
+ : this._looksLikeCreditCardTypeField(e, g) &&
+ (s.ControlLooksLikeCreditCardTypeField = !0),
+ p &&
+ (this._looksLikeMonthField(e, g)
+ ? (s.ControlLooksLikeMonthField = !0)
+ : this._looksLikeYearField(e, g)
+ ? (s.ControlLooksLikeYearField = !0)
+ : this._looksLikeDayField(e)
+ ? (s.ControlLooksLikeDayField = !0)
+ : !s.ControlLooksLikeCreditCardSecurityCodeField &&
+ this._looksLikeCreditCardCompositeExpirationDateField(e, g) &&
+ (s.ControlLooksLikeCreditCardCompositeExpirationDateField = !0),
+ this._looksLikeAdditionalClassificationsControl(e) &&
+ (s.ControlIsCandidateForAdditionalClassifications = !0)),
+ C ||
+ (this._looksLikeEIDField(e, g)
+ ? (s.ControlLooksLikeEIDField = !0)
+ : this._looksLikeIMEIField(e, g)
+ ? (s.ControlLooksLikeIMEIField = !0)
+ : this._looksLikeIMEI1Field(e, g)
+ ? (s.ControlLooksLikeIMEI1Field = !0)
+ : this._looksLikeIMEI2Field(e, g)
+ ? (s.ControlLooksLikeIMEI2Field = !0)
+ : this._looksLikeNALField(e, g) &&
+ (s.ControlLooksLikeNALField = !0)),
+ C ||
+ s.ControlLooksLikeIgnoredDataTypeField ||
+ s.ControlIsSecureTextField ||
+ s.ControlLooksLikeCreditCardNumberField ||
+ s.ControlLooksLikeCreditCardSecurityCodeField ||
+ s.ControlLooksLikeCreditCardTypeField ||
+ s.ControlLooksLikeCreditCardCompositeExpirationDateField ||
+ s.ControlLooksLikeEIDField ||
+ s.ControlLooksLikeIMEIField ||
+ s.ControlLooksLikeIMEI1Field ||
+ s.ControlLooksLikeIMEI2Field ||
+ s.ControlLooksLikeNALField ||
+ (s.AddressBookLabel = this._addressBookLabelForElement(e)),
+ s.ControlIsActiveElement ||
+ t === WBSFormMetadataRequestTesting ||
+ t === WBSFormMetadataRequestAutomaticPasswordChange ||
+ a)
+ ) {
+ let t = l && s.IsVisible;
+ this._looksLikeOneTimeCodeField(e, g, o, n, i, t, s) &&
+ (s.ControlLooksLikeOneTimeCodeField = !0);
+ }
+ return (
+ t === WBSFormMetadataRequestTesting &&
+ globalThis.WAS &&
+ (s.ControlNodePath = WAS.NodePath.fromNode(e)?.objectRepresentation),
+ window.webkit?.createJSHandle &&
+ (s.ControlJSHandle = this.ensureElementHandle(e)),
+ s.ControlLooksLikeOneTimeCodeField &&
+ 1 === s.ControlMaxLength &&
+ delete s.AddressBookLabel,
+ s
+ );
+ }
+ _usesGeneratedPassword(e) {
+ for (
+ var t = !1, r = this._elementsWithGeneratedPasswords.length, o = 0;
+ o < r;
+ ++o
+ ) {
+ var n = this._elementsWithGeneratedPasswords[o];
+ if (e.containsControl(n)) {
+ if (n.af_value() !== this._generatedPasswords[o]) return !1;
+ t = !0;
+ }
+ }
+ return t;
+ }
+ _associatedUsernameForControl(e) {
+ return this._isAutoFillableTextField(e)
+ ? e.getAttribute("data-username")
+ : null;
+ }
+ _collectSelectElementInfo(e) {
+ if (!this._isAutoFillableSelectElement(e)) return null;
+ if (!e.options.length) return null;
+ for (var t = [], r = e.options, o = r.length, n = 0; n < o; ++n) {
+ var i = r[n];
+ i.disabled ||
+ ((i.label || i.text) && t.push([n, i.label ? i.label : i.text]));
+ }
+ return t.length ? t : null;
+ }
+ _stringsToInspectForDeterminingFormType(e) {
+ let t = [],
+ r = e.formElement,
+ o = r.getAttribute("id"),
+ n = r.getAttribute("name");
+ (o && t.push(o), n && t.push(n));
+ let i = queryAllBySelector(r, "legend");
+ 1 === i.length && t.push(i[0].innerText);
+ const l = 0.8;
+ if (
+ 1 ===
+ this._logicalFormsCache
+ .numberOfVisibleFormsWithVisibleTextEntryControls &&
+ r.isVisible() &&
+ !r.ownerDocument.defaultView.frameElement &&
+ r.getBoundingClientRect().top < l * document.documentElement.clientHeight
+ ) {
+ let e = documentTitleWithoutHostNamePrefix();
+ e && t.push(e);
+ const r = lastPathComponentFromAnchor(window.location);
+ r && r.length && t.push(r);
+ }
+ let a = [];
+ if (r.isVisible()) {
+ const e = r.getBoundingClientRect(),
+ o = window.getComputedStyle(r),
+ n = parseFloat(o.marginLeft),
+ i = parseFloat(o.marginRight),
+ l = n > 0 ? e.left - n : e.left,
+ s = i > 0 ? e.right + i : e.right,
+ u = function (t) {
+ return (
+ (l <= t.left && t.right <= s && t.distanceToRect(e) < 100) ||
+ (Math.abs(t.left - e.left - (e.right - t.right)) < 1 &&
+ t.distanceToRect(e) < 200) ||
+ (Math.abs(t.left - l - (s - t.right)) < 1 &&
+ t.distanceToRect(e) < 200)
+ );
+ };
+ let c = !1,
+ d = new Set();
+ for (
+ let e = 0, o = r;
+ e <= 2 && o;
+ ++e, o = o.parentElementIncludingShadowDOMHost()
+ ) {
+ let e = Array.prototype.slice.call(
+ queryAllBySelector(
+ o,
+ "h1, h2, h3, [class*='header' i], [class*='heading' i]",
+ ),
+ ),
+ r = [[], [], [], []];
+ for (const t of e) {
+ if (!t.innerText) continue;
+ let e = t.tagName;
+ "H1" === e
+ ? r[0].push(t)
+ : "H2" === e
+ ? r[1].push(t)
+ : "H3" === e
+ ? r[2].push(t)
+ : r[3].push(t);
+ }
+ let n = !0;
+ for (const e of r) {
+ let r = e.length;
+ if (0 === r) {
+ n = !1;
+ continue;
+ }
+ if (r > 1) break;
+ let o = e[0];
+ if (!o.isVisible()) break;
+ u(o.getBoundingClientRect()) &&
+ (d.add(o), t.push(o.innerText), (c = !0));
+ break;
+ }
+ if (n) break;
+ }
+ const h = 100;
+ for (
+ let e = r.traversePreviousElement(), o = 0;
+ e && o < h;
+ e = e.traversePreviousElement(), o++
+ )
+ if (!d.has(e) && e.matches("h1, h2, h3")) {
+ const r = e.previousElementSibling;
+ if (r && r.matches("h1, h2, h3")) break;
+ u(e.getBoundingClientRect()) && (t.push(e.innerText), (c = !0));
+ break;
+ }
+ if (!c) {
+ let e = queryAllBySelector(document.documentElement, "h1");
+ if (1 === e.length) {
+ let r = e[0];
+ u(r.getBoundingClientRect()) && t.push(r.innerText);
+ }
+ }
+ for (
+ let t = 0, o = r;
+ t <= 2 && o;
+ ++t, o = o.parentElementIncludingShadowDOMHost()
+ ) {
+ let t = Array.prototype.slice
+ .call(
+ queryAllBySelector(
+ o,
+ 'button, input[type=submit], a[class~="button"]',
+ ),
+ )
+ .filter(function (t) {
+ if (!t.isVisible()) return !1;
+ let o = t.getBoundingClientRect();
+ return (
+ o.top > e.bottom &&
+ !r.contains(t) &&
+ e.left <= o.left &&
+ o.right <= e.right &&
+ o.distanceToRect(e) < 100
+ );
+ });
+ if (t.length) {
+ a = t;
+ break;
+ }
+ }
+ }
+ let s = !1,
+ u = [],
+ c = this._elementsActingAsButtonsInForm(r),
+ d = [...new Set(e.elements.concat(a, c))];
+ for (const e of d) {
+ if (!e.matches("a")) {
+ const t = e.type;
+ if (("password" === t && (s = !0), "submit" !== t && "button" !== t))
+ continue;
+ }
+ s &&
+ (e.isVisible()
+ ? this._addInterestingStringsForButton(e, t)
+ : u.push(e));
+ }
+ if (0 === t.length)
+ for (const e of u) this._addInterestingStringsForButton(e, t);
+ return t;
+ }
+ _addInterestingStringsForButton(e, t) {
+ const r = e.getAttribute("id");
+ r && t.push(r);
+ const o = e.getAttribute("value");
+ o && t.push(o);
+ const n = e.innerText;
+ n && n.length > 0 && t.push(n);
+ }
+ _isPasswordFieldFollowedByPasswordRequirementText(e, t) {
+ this._passwordRequirementTextCache ||
+ (this._passwordRequirementTextCache = new WeakMap());
+ let r = this._passwordRequirementTextCache.get(e);
+ if (void 0 !== r) return r;
+ let o = this._computeIsPasswordFieldFollowedByPasswordRequirementText(e, t);
+ return (this._passwordRequirementTextCache.set(e, o), o);
+ }
+ _computeIsPasswordFieldFollowedByPasswordRequirementText(e, t) {
+ let r = this._dataForComputingMatchFromPageScanAfterElement(e, void 0, t);
+ if (!r.length) return !1;
+ let o = r.join(" ").toLowerCase();
+ return (
+ this._passwordRequirementHeaderRegExp ||
+ (this._passwordRequirementHeaderRegExp =
+ /(your\s+)?password[s]?\s+(must|should|needs?\s+to|has\s+to)\s+(have|contain|include|be|meet)/),
+ this._passwordRequirementRuleRegExp ||
+ (this._passwordRequirementRuleRegExp =
+ /(\d+\s*character|\d+\s*letter|one\s+(uppercase|lowercase|upper case|lower case|special|digit|number|symbol)|at least\s+(one|a|\d)|a\s+(number|digit|symbol|special)|no\s+spaces)/),
+ this._passwordRequirementHeaderRegExp.test(o) &&
+ this._passwordRequirementRuleRegExp.test(o)
+ );
+ }
+ _autoFillFormTypeOfTypesUsingKeywordMatching(e, t, r, o) {
+ for (var n = t.length, i = [], l = 0; l < n; ++l) {
+ var a = mapOfFormTypeToProducerOfAssociatedKeywords[t[l]],
+ s = a();
+ i.push(s);
+ }
+ var u = this._stringsToInspectForDeterminingFormType(e),
+ c = this._regularExpressionsIndicatingNonAutoFillableFormType;
+ c ||
+ ((c = regularExpressionsFromStrings(
+ FormMetadataJSController.regularExpressionsIndicatingNonAutoFillableFormType,
+ )),
+ (this._regularExpressionsIndicatingNonAutoFillableFormType = c));
+ var d = c.length,
+ h = [];
+ for (l = 0; l < n; ++l) h.push(0);
+ if (o)
+ for (const [e, r] of Object.entries(o)) h[t.indexOf(parseInt(e))] += r;
+ for (var m = u.length, F = 0; F < m; ++F) {
+ for (var f = u[F].toLowerCase(), g = 0; g < d; ++g)
+ if (c[g].test(f))
+ return {
+ formType: WBSAutoFillFormTypeNonAutoFillable,
+ confidence: 1,
+ };
+ for (l = 0; l < n; ++l) {
+ s = i[l];
+ for (var C in s) -1 !== f.indexOf(C) && (h[l] += s[C]);
+ }
+ }
+ for (let r = 0; r < n; ++r) {
+ const o = this._mapOfFormTypeToExtraScoreProducer[t[r]];
+ h[r] += o(e);
+ }
+ for (l = 0; l < n; ++l) 0 !== h[l] && 0;
+ var p = formActionAsAnchorElement(e.formElement, !0);
+ if (p) {
+ var y = p.pathname.toLowerCase() + p.search.toLowerCase();
+ for (l = 0; l < n; ++l) {
+ s = i[l];
+ for (var C in s) -1 !== y.indexOf(C) && (h[l] += s[C]);
+ }
+ }
+ var b = [],
+ A = 0;
+ for (l = 0; l < n; ++l) {
+ var _ = h[l];
+ _ > 0 && (_ >= A ? ((A = _), b.unshift(l)) : b.push(l));
+ }
+ if (1 === b.length) return { formType: t[b[0]], confidence: 1 };
+ if (b.length > 1) {
+ var T = b[0];
+ if (h[T] > h[b[1]]) return { formType: t[T], confidence: 1 };
+ }
+ return { formType: r, confidence: 0 };
+ }
+ _autoFillFormTypeAndConfidence(e, t, r, o, n) {
+ var { formType: i, confidence: l } =
+ this._autoFillFormTypeOfTypesUsingKeywordMatching(e, t, r || o, n);
+ return { formType: i, confidence: i === r ? l : 1 };
+ }
+ _matchesNonUsernameFieldLabelPattern(e) {
+ if (
+ (this._nonUsernameFieldPatternMatchers ||
+ (this._nonUsernameFieldPatternMatchers =
+ FormMetadataJSController.nonUsernameFieldLabelPatternMatchers),
+ this._bestMatchForElement(e, this._nonUsernameFieldPatternMatchers))
+ )
+ return !0;
+ const t = e.af_value();
+ if (!e.id && !e.name && t && e.disabled)
+ for (const e of this._nonUsernameFieldPatternMatchers)
+ if (this._matchPatternAgainstString(e, t)) return !0;
+ return !1;
+ }
+ _matchSearchFieldLabelPattern(e) {
+ if (
+ (this._searchFieldLabelPatternMatchers ||
+ (this._searchFieldLabelPatternMatchers =
+ FormMetadataJSController.searchFieldLabelPatternMatchers),
+ this._bestMatchForElement(e, this._searchFieldLabelPatternMatchers, !0))
+ )
+ return !0;
+ const t = e.af_value();
+ if (!e.id && !e.name && t && e.disabled)
+ for (const e of this._searchFieldLabelPatternMatchers)
+ if (this._matchPatternAgainstString(e, t)) return !0;
+ return !1;
+ }
+ _matchesNonEmailFieldLabelPattern(e) {
+ return (
+ this._nonEmailFieldPatternMatchers ||
+ (this._nonEmailFieldPatternMatchers =
+ FormMetadataJSController.nonEmailFieldLabelPatternMatchers),
+ !!this._bestMatchForElement(e, this._nonEmailFieldPatternMatchers)
+ );
+ }
+ _scoreForUsernameFieldCandidateFromLabelingAndPositionOfField(e, t, r) {
+ return this._isLabeledUsernameField(e)
+ ? t
+ ? UsernameCandidateScoreForUsernameLabeledFieldBelowPasswordField
+ : UsernameCandidateScoreForUsernameLabeledFieldAbovePasswordField
+ : this._isLabeledEmailField(e) &&
+ !this._matchesNonEmailFieldLabelPattern(e)
+ ? t
+ ? UsernameCandidateScoreForEmailLabeledFieldBelowPasswordField
+ : UsernameCandidateScoreForEmailLabeledFieldAbovePasswordField
+ : r
+ ? UsernameCandidateScoreForPlainTextFieldDirectlyBeforePasswordField
+ : UsernameCandidateScoreForPlainTextField;
+ }
+ _scoreForUsernameFieldCandidate(e, t, r) {
+ var o = this._scoreForUsernameFieldCandidateFromLabelingAndPositionOfField(
+ e,
+ t,
+ r,
+ );
+ return (
+ e.isVisible() && (o += UsernameCandidateScoreBonusForVisibleElement),
+ this._matchesNonUsernameFieldLabelPattern(e) &&
+ (o -=
+ UsernameCandidateScorePenaltyForMatchingNonUsernameFieldLabelPattern),
+ this._matchSearchFieldLabelPattern(e) &&
+ (o -= UsernameCandidateScorePenaltyForMatchingSearchFieldLabelPattern),
+ e.readOnly && (o -= UsernameCandidateScorePenaltyForReadOnlyElement),
+ e.id || e.name || (o -= UsernameCandidateScorePenaltyForAnonymousElement),
+ o
+ );
+ }
+ _matchesPasswordFieldLabelPattern(e) {
+ return (
+ this._passwordFieldPatternMatchers ||
+ (this._passwordFieldPatternMatchers =
+ FormMetadataJSController.passwordFieldLabelPatternMatchers),
+ !!this._bestMatchForElement(e, this._passwordFieldPatternMatchers)
+ );
+ }
+ _matchesConfirmPasswordFieldLabelPattern(e, t = !1) {
+ return (
+ this._confirmPasswordFieldPatternMatchers ||
+ (this._confirmPasswordFieldPatternMatchers =
+ FormMetadataJSController.confirmPasswordFieldLabelPatternMatchers),
+ !!this._bestMatchForElement(
+ e,
+ this._confirmPasswordFieldPatternMatchers,
+ t,
+ )
+ );
+ }
+ _matchesConfirmEmailFieldLabelPattern(e) {
+ return (
+ !!this._isLabeledEmailField(e) &&
+ (this._confirmEmailFieldPatternMatchers ||
+ (this._confirmEmailFieldPatternMatchers =
+ FormMetadataJSController.confirmEmailFieldLabelPatternMatchers),
+ !!this._bestMatchForElement(e, this._confirmEmailFieldPatternMatchers))
+ );
+ }
+ _collectRadioButtonInfo(e, t) {
+ function r(e, t) {
+ var r = e.trim();
+ r && t.push(r);
+ }
+ function o(e, t) {
+ (r(e.alt, t), r(e.title, t), r(lastPathComponentForURLString(e.src), t));
+ }
+ function n(e) {
+ let t = [];
+ r(e.innerText, t);
+ let n = queryAllBySelector(e, "img"),
+ i = n.length;
+ for (let e = 0; e < i; ++e) o(n[e], t);
+ return t.length ? t : null;
+ }
+ for (
+ var i = e.radioButtonsWithName(t), l = i.length, a = !1, s = {}, u = 0;
+ u < l;
+ ++u
+ ) {
+ s[(f = i[u]).af_value()] = [f.af_value()];
+ for (var c = this._labelsForElement(f), d = c.length, h = 0; h < d; ++h) {
+ a = !0;
+ var m = n(c[h]);
+ m && (s[f.af_value()] = s[f.af_value()].concat(m));
+ }
+ }
+ if (a) return s;
+ const F = 64;
+ for (u = 0; u < l; ++u) {
+ for (
+ var f, g = "", C = (f = i[u]).traverseNextNode();
+ C && !this._isRenderedFormControl(C);
+ C = C.traverseNextNode()
+ ) {
+ var p = C.localName;
+ if ("td" === p || "tr" === p || "ul" === p || "ol" === p || "dl" === p)
+ break;
+ if (C instanceof HTMLImageElement) o(C, s[f.af_value()]);
+ else if (C.nodeType === Node.TEXT_NODE) {
+ var y = C.nodeValue.trim();
+ if ((y && (g += y.substr(0, F - g.length)), g.length >= F)) break;
+ }
+ }
+ g && s[f.af_value()].push(g);
+ }
+ return s;
+ }
+ _bestUsernameFieldCandidate(e, t, r) {
+ var o = t.FormControls,
+ n = o.filter(function (e) {
+ return e.ControlClaimsToBeUsernameViaAutocompleteAttribute;
+ });
+ if (1 === n.length) return n[0];
+ for (
+ var i = 0, l = [], a = !1, s = o.indexOf(r), u = o.length, c = 0;
+ c < u;
+ ++c
+ ) {
+ var d = o[c];
+ if (d === r) {
+ a = !0;
+ continue;
+ }
+ if (!d.ControlIsTextField || d.ControlIsSecureTextField) continue;
+ if (t.IsVisible && !o[c].IsVisible && !d.ControlValue) continue;
+ const n = 100;
+ let F = e[c];
+ if (!(F.af_value().length > n)) {
+ var h = c + 1 < u && c + 1 === s,
+ m = this._scoreForUsernameFieldCandidate(F, a, h);
+ m > i ? ((l = [c]), (i = m)) : m === i && l.push(c);
+ }
+ }
+ var F = l.length;
+ if (i < LowestScoreForLabeledUsernameFieldCandidate && F > 1) return null;
+ if (i < LowestScoreForUsernameFieldCandidate) return null;
+ switch (F) {
+ case 0:
+ return null;
+ case 1:
+ return o[l[0]];
+ default:
+ var f = e[s].getBoundingClientRect(),
+ g = {};
+ return (
+ l.forEach(function (t) {
+ g[t] = f.distanceToRect(e[t].getBoundingClientRect());
+ }),
+ o[
+ l.sort(function (e, t) {
+ return g[e] - g[t];
+ })[0]
+ ]
+ );
+ }
+ }
+ _autoFillFormTypeFromCandidateFormTypes(e, t, r) {
+ switch (t.length) {
+ case 1:
+ return t[0];
+ case 2:
+ return this._autoFillFormTypeOfTypesUsingKeywordMatching(
+ e,
+ [t[0], t[1]],
+ r,
+ ).formType;
+ default:
+ return WBSAutoFillFormTypeAutoFillableStandard;
+ }
+ }
+ _shouldTrustElementThatClaimsToBeCurrentPasswordViaAutocompleteAttribute(e) {
+ return !e.dataset.valRegexPattern;
+ }
+ _identifyPossibleFormTypesFromAutocompleteAttribute(e, t) {
+ if (/^(.+\.)?roll20\.net\.?$/.test(document.location.hostname)) return null;
+ var r = t.length;
+ if (r > 3) return null;
+ for (var o = [], n = [], i = 0; i < r; ++i) {
+ var l = t[i];
+ l.ControlClaimsToBeCurrentPasswordViaAutocompleteAttribute &&
+ this._shouldTrustElementThatClaimsToBeCurrentPasswordViaAutocompleteAttribute(
+ e[i],
+ )
+ ? o.push(i)
+ : l.ControlClaimsToBeNewPasswordViaAutocompleteAttribute && n.push(i);
+ }
+ var a = o.length,
+ s = n.length;
+ if (a + s !== r) return null;
+ switch (r) {
+ case 0:
+ return null;
+ case 1:
+ if (a) return WBSAutoFillFormTypeAutoFillableLogin;
+ if (s) return WBSAutoFillFormTypeNewAccount;
+ case 2:
+ if (1 === a && 1 === s) return WBSAutoFillFormTypeChangePassword;
+ if (0 === a && 2 === s) return WBSAutoFillFormTypeChangePassword;
+ break;
+ case 3:
+ if (1 === a && 2 === s) return WBSAutoFillFormTypeChangePassword;
+ }
+ return null;
+ }
+ _identifyPasswordFieldIndices(e, t) {
+ var r = e.length;
+ if (0 === r) return {};
+ if (1 === r) return { PasswordFieldIndex: 0 };
+ if (
+ (this._oldPasswordPatternMatchers ||
+ (this._oldPasswordPatternMatchers =
+ FormMetadataJSController.oldPasswordFieldLabelPatternMatchers),
+ 2 === r)
+ ) {
+ const r = t[0];
+ if (
+ this._bestMatchForElement(r, this._oldPasswordPatternMatchers) ||
+ (e[0].ControlClaimsToBeCurrentPasswordViaAutocompleteAttribute &&
+ this._shouldTrustElementThatClaimsToBeCurrentPasswordViaAutocompleteAttribute(
+ r,
+ ) &&
+ e[1].ControlClaimsToBeNewPasswordViaAutocompleteAttribute)
+ )
+ return { OldPasswordFieldIndex: 0, PasswordFieldIndex: 1 };
+ return this._bestMatchForElement(t[1], this._oldPasswordPatternMatchers)
+ ? { OldPasswordFieldIndex: 1, PasswordFieldIndex: 0 }
+ : { PasswordFieldIndex: 0, ConfirmationFieldIndex: 1 };
+ }
+ var o = this._bestMatchForElement(
+ t[r - 3],
+ this._oldPasswordPatternMatchers,
+ );
+ return this._bestMatchForElement(
+ t[r - 1],
+ this._oldPasswordPatternMatchers,
+ ) && !o
+ ? {
+ PasswordFieldIndex: r - 3,
+ ConfirmationFieldIndex: r - 2,
+ OldPasswordFieldIndex: r - 1,
+ }
+ : {
+ PasswordFieldIndex: r - 2,
+ ConfirmationFieldIndex: r - 1,
+ OldPasswordFieldIndex: r - 3,
+ };
+ }
+ _removePlaceholderTextForFormMetadata(e, t) {
+ for (var r = e.length, o = 0; o < r; ++o) {
+ var n = t.FormControls[o];
+ if (
+ n.ControlValue &&
+ n.ControlIsTextField &&
+ !n.ControlIsSecureTextField &&
+ !n.ControlIsReadOnly
+ ) {
+ var i = legacyPlaceholderInfoForInputElement(e[o]);
+ i &&
+ ((i.AttributeMatchedWasValue &&
+ n.ControlUniqueID === t.UsernameElementUniqueID) ||
+ (n.ControlValue = ""));
+ }
+ }
+ }
+ _isPasswordConfirmPair(e, t) {
+ var r = this._matchesPasswordFieldLabelPattern(e),
+ o = this._matchesConfirmPasswordFieldLabelPattern(t);
+ return r && o;
+ }
+ _trailingArgumentsForCollectControlMetadataFunction(e, t, r) {
+ let o = isElementPositionedToBeEffectivelyInvisible(e.backingElement),
+ n = !1,
+ i = !1,
+ l = !1;
+ if (innermostActiveElement() || t === WBSFormMetadataRequestTesting) {
+ let e = documentTitleWithoutHostNamePrefix(),
+ t = this._cachedOneTimeCodePatternMatcher();
+ n = !!this._matchPatternAgainstString(t, e);
+ let o = this._cachedLoginFormTypePatternMatcher();
+ if (((i = !!this._matchPatternAgainstString(o, e)), r)) {
+ let e = location.pathname.split("/"),
+ o = stripCommonPrefix(r.pathname.split("/"), e)[0].join("/");
+ o.length && (l = !!this._matchPatternAgainstString(t, o));
+ }
+ }
+ let a = !1;
+ for (let t of e.elements)
+ if (this._isTextField(t) && t.isVisible()) {
+ if (a) {
+ a = !1;
+ break;
+ }
+ a = !0;
+ }
+ return [o, l, n, i, a];
+ }
+ _collectFormMetadata(e, t) {
+ var r,
+ o,
+ n =
+ ((o = 0),
+ {
+ backwardScanCache: new WeakMap(),
+ forwardScanCache: new WeakMap(),
+ shouldUsePageScan: function () {
+ return (
+ o <
+ numberOfConsecutiveElementsWithoutSuccessfulPageScanAfterWhichPageScanIsAbandoned
+ );
+ },
+ willStartCollectingMetadataForControl: function () {
+ r = null;
+ },
+ reportPageScanUsedSuccessfully: function (e) {
+ r = !(!e && !r);
+ },
+ didFinishCollectingMetadataForControl: function () {
+ !0 === r ? (o = 0) : !1 === r && o++;
+ },
+ });
+ this._pageScanContext = n;
+ var i = e.formElement,
+ l = {
+ FormID: e.formUniqueID,
+ ContainsActiveElement: !1,
+ FormControls: [],
+ AutoFillFormType: WBSAutoFillFormTypeAutoFillableStandard,
+ UsernameElementUniqueID: void 0,
+ OldPasswordElementUniqueID: void 0,
+ PasswordElementUniqueID: void 0,
+ ConfirmPasswordElementUniqueID: void 0,
+ UsesGeneratedPassword: this._usesGeneratedPassword(e),
+ FirstCreditCardCardholderFieldOrCreditCardNumberFieldUniqueID: void 0,
+ IsVisible: i.isVisible(),
+ TextSample: void 0,
+ RequestType: t,
+ };
+ const a = queryAllBySelector(i, "a:not(svg a)"),
+ s = queryAllBySelector(i, "button"),
+ u = queryAllBySelector(e.backingElement, "a:not(svg a)"),
+ c = queryAllBySelector(e.backingElement, "button");
+ (this._elementDisallowsAutocomplete(i) && (l.DisallowsAutocomplete = !0),
+ i instanceof HTMLFormElement &&
+ (l.FormIsSearchForm = this.isSearchForm(i, !0)),
+ e.isAnnotated && (l.Annotations = e.annotations));
+ var d = i.getAttribute("rel");
+ d && "async" === d.toLowerCase() && (l.FormUsesRelAsync = !0);
+ let h = formActionAsAnchorElement(i);
+ if (
+ (h && h.href && (l.FormAction = h.href),
+ t == WBSFormMetadataRequestCollectMetadataFromDebugMenu ||
+ t == WBSFormMetadataRequestTesting)
+ ) {
+ let e = selectorForElement(i);
+ e && e.length && (l.LogicalFormElementSelector = e);
+ }
+ var m = e.elements,
+ F = !m.some(this._isSecureTextField.bind(this));
+ let [f, g, C, p, y] =
+ this._trailingArgumentsForCollectControlMetadataFunction(e, t, h);
+ var b = 0,
+ A = !1,
+ _ = [],
+ T = [],
+ w = [],
+ E = [],
+ S = void 0,
+ I = void 0,
+ P = void 0,
+ v = void 0,
+ L = !1,
+ M = !1,
+ x = {},
+ k = [];
+ let B = !1;
+ for (var D = m.length, R = 0; R < D; ++R) {
+ var U = m[R];
+ if (
+ F &&
+ !U.isVisible() &&
+ !U._relatesToCredentials &&
+ !this._isPotentialInvisibleOneTimeCodeControl(U)
+ )
+ continue;
+ var O = isRadioButtonElement(U),
+ N = U.name;
+ if (O && x[N]) continue;
+ n.willStartCollectingMetadataForControl();
+ const r = !B;
+ var q = this._collectControlMetadata(U, t, f, g, C, p, y, r);
+ if (
+ (n.didFinishCollectingMetadataForControl(),
+ (B = !0),
+ R + 1 < D &&
+ (q.ControlNextFieldUniqueID = this.controlUniqueID(m[R + 1])),
+ l.FormControls.push(q),
+ k.push(U),
+ q.IsVisible || !l.IsVisible || U._relatesToCredentials)
+ )
+ if (
+ (q.ControlIsActiveElement && (l.ContainsActiveElement = !0), N && O)
+ )
+ ((x[N] = 1),
+ (q.ControlValue = ""),
+ (q.RadioButtonInfo = this._collectRadioButtonInfo(e, N)));
+ else if (q.ControlIsTextField || q.SelectElementInfo)
+ if (
+ (!M && q.ControlLooksLikeCreditCardSecurityCodeField && (M = !0),
+ L ||
+ (!q.ControlLooksLikeCreditCardCardholderField &&
+ !q.ControlLooksLikeCreditCardNumberField))
+ ) {
+ if (!(
+ q.ControlLooksLikeDayField ||
+ q.ControlLooksLikeMonthField ||
+ q.ControlLooksLikeYearField ||
+ q.ControlLooksLikeCreditCardCompositeExpirationDateField
+ )) {
+ if (q.ControlLooksLikePasswordCredentialField) {
+ if (
+ q.ControlLooksLikeCreditCardSecurityCodeField ||
+ q.ControlLooksLikeCreditCardNumberField ||
+ q.ControlLooksLikeIgnoredDataTypeField
+ )
+ continue;
+ U.isHiddenFromAccessibilityTree()
+ ? (w.push(U), E.push(q))
+ : (_.push(U), T.push(q));
+ }
+ if (this._isLabeledEmailField(U)) {
+ if (++b > 2) {
+ A = !1;
+ continue;
+ }
+ if (!(
+ R + 1 < D &&
+ this._matchesConfirmEmailFieldLabelPattern(m[R + 1])
+ ))
+ continue;
+ A = !0;
+ }
+ }
+ } else
+ ((L = !0),
+ (l.FirstCreditCardCardholderFieldOrCreditCardNumberFieldUniqueID =
+ q.ControlUniqueID));
+ }
+ !_.length && w.length && ((_ = w), (T = E));
+ let W = this._identifyPossibleFormTypesFromAutocompleteAttribute(_, T),
+ K = this._identifyPasswordFieldIndices(T, _);
+ if (
+ (void 0 !== K.PasswordFieldIndex &&
+ ((S = T[K.PasswordFieldIndex]),
+ (l.PasswordElementUniqueID = S.ControlUniqueID),
+ (I = this._explicitMaxLength(_[K.PasswordFieldIndex]))),
+ void 0 !== K.ConfirmationFieldIndex &&
+ ((P = T[K.ConfirmationFieldIndex]),
+ (l.ConfirmPasswordElementUniqueID = P.ControlUniqueID),
+ (v = this._explicitMaxLength(_[K.ConfirmationFieldIndex]))),
+ void 0 !== K.OldPasswordFieldIndex)
+ ) {
+ var V = T[K.OldPasswordFieldIndex];
+ l.OldPasswordElementUniqueID = V.ControlUniqueID;
+ }
+ var H, J;
+ if (
+ (S && (H = this._bestUsernameFieldCandidate(k, l, S)),
+ H
+ ? (l.UsernameElementUniqueID = H.ControlUniqueID)
+ : (J = this._findHiddenUsernameElement(e, l, k)),
+ 1 === _.length && A)
+ )
+ l.AutoFillFormType = this._autoFillFormTypeOfTypesUsingKeywordMatching(
+ e,
+ [WBSAutoFillFormTypeNewAccount, WBSAutoFillFormTypeChangePassword],
+ WBSAutoFillFormTypeNewAccount,
+ ).formType;
+ else if (l.UsernameElementUniqueID)
+ switch (_.length) {
+ case 0:
+ break;
+ case 1:
+ if (
+ M &&
+ l.UsernameElementUniqueID ===
+ l.FirstCreditCardCardholderFieldOrCreditCardNumberFieldUniqueID &&
+ T[0].ControlLooksLikeCreditCardNumberField
+ )
+ break;
+ if (this._matchesConfirmPasswordFieldLabelPattern(_[0])) {
+ let t = {};
+ this._isElementFollowedByForgotPasswordAffordance(U, i, a, s) &&
+ (t[WBSAutoFillFormTypeAutoFillableLogin] = 2);
+ const { formType: r, confidence: o } =
+ this._autoFillFormTypeAndConfidence(
+ e,
+ [
+ WBSAutoFillFormTypeNewAccount,
+ WBSAutoFillFormTypeChangePassword,
+ ],
+ W,
+ WBSAutoFillFormTypeAutoFillableLogin,
+ t,
+ );
+ ((l.AutoFillFormType = r), (l.AutoFillFormTypeConfidence = o));
+ } else {
+ let t = _[0],
+ r = {};
+ const o =
+ 2 *
+ this._numberOfForgotUserNameEmailOrPasswordAffordancesFollowingElement(
+ t,
+ e.backingElement,
+ u,
+ c,
+ );
+ o && (r[WBSAutoFillFormTypeAutoFillableLogin] = o);
+ const { formType: n, confidence: i } =
+ this._autoFillFormTypeAndConfidence(
+ e,
+ [
+ WBSAutoFillFormTypeNewAccount,
+ WBSAutoFillFormTypeAutoFillableLogin,
+ ],
+ W,
+ WBSAutoFillFormTypeAutoFillableLogin,
+ r,
+ );
+ ((l.AutoFillFormType = n), (l.AutoFillFormTypeConfidence = i));
+ }
+ break;
+ case 2:
+ if (I === v) {
+ const { formType: t, confidence: r } =
+ this._autoFillFormTypeAndConfidence(
+ e,
+ [
+ WBSAutoFillFormTypeNewAccount,
+ WBSAutoFillFormTypeChangePassword,
+ ],
+ W,
+ WBSAutoFillFormTypeNewAccount,
+ );
+ ((l.AutoFillFormType = t), (l.AutoFillFormTypeConfidence = r));
+ } else
+ v
+ ? this._isPasswordConfirmPair(_[0], _[1])
+ ? (l.AutoFillFormType =
+ this._autoFillFormTypeOfTypesUsingKeywordMatching(
+ e,
+ [
+ WBSAutoFillFormTypeNewAccount,
+ WBSAutoFillFormTypeChangePassword,
+ ],
+ WBSAutoFillFormTypeNonAutoFillable,
+ ).formType)
+ : (l.AutoFillFormType = WBSAutoFillFormTypeNonAutoFillable)
+ : (l.AutoFillFormType =
+ this._autoFillFormTypeOfTypesUsingKeywordMatching(
+ e,
+ [
+ WBSAutoFillFormTypeNewAccount,
+ WBSAutoFillFormTypeChangePassword,
+ ],
+ WBSAutoFillFormTypeNonAutoFillable,
+ ).formType);
+ break;
+ case 3:
+ I === v ||
+ !v ||
+ this._isPasswordConfirmPair(
+ _[K.PasswordFieldIndex],
+ _[K.ConfirmationFieldIndex],
+ )
+ ? (l.AutoFillFormType = WBSAutoFillFormTypeChangePassword)
+ : (l.AutoFillFormType = WBSAutoFillFormTypeNonAutoFillable);
+ break;
+ default:
+ l.AutoFillFormType = WBSAutoFillFormTypeNonAutoFillable;
+ }
+ else if (2 === _.length || 3 === _.length)
+ if (I !== v && v)
+ 2 === _.length
+ ? this._isPasswordConfirmPair(_[0], _[1])
+ ? (l.AutoFillFormType =
+ this._autoFillFormTypeOfTypesUsingKeywordMatching(
+ e,
+ [
+ WBSAutoFillFormTypeNewAccount,
+ WBSAutoFillFormTypeChangePassword,
+ ],
+ WBSAutoFillFormTypeNonAutoFillable,
+ ).formType)
+ : (l.AutoFillFormType = WBSAutoFillFormTypeNonAutoFillable)
+ : this._isPasswordConfirmPair(
+ _[K.PasswordFieldIndex],
+ _[K.ConfirmationFieldIndex],
+ )
+ ? (l.AutoFillFormType = WBSAutoFillFormTypeChangePassword)
+ : (l.AutoFillFormType = WBSAutoFillFormTypeNonAutoFillable);
+ else {
+ let t = {};
+ (this._isPasswordConfirmPair(
+ _[K.PasswordFieldIndex],
+ _[K.ConfirmationFieldIndex],
+ ) && (t[WBSAutoFillFormTypeChangePassword] = 2),
+ (l.AutoFillFormType =
+ this._autoFillFormTypeOfTypesUsingKeywordMatching(
+ e,
+ [
+ WBSAutoFillFormTypeNewAccount,
+ WBSAutoFillFormTypeChangePassword,
+ ],
+ WBSAutoFillFormTypeChangePassword,
+ t,
+ ).formType));
+ }
+ else if (1 === _.length) {
+ var G = _[0];
+ let t = {
+ [WBSAutoFillFormTypeNewAccount]: 0,
+ [WBSAutoFillFormTypeAutoFillableLogin]: 0,
+ [WBSAutoFillFormTypeChangePassword]: 0,
+ };
+ this._isElementFollowedByForgotPasswordAffordance(U, i, a, s) &&
+ (t[WBSAutoFillFormTypeAutoFillableLogin] = 2);
+ const r = !0;
+ if (this._matchesConfirmPasswordFieldLabelPattern(G, r))
+ ((t[WBSAutoFillFormTypeChangePassword] += 2),
+ this._isPasswordFieldFollowedByPasswordRequirementText(G, i) &&
+ (t[WBSAutoFillFormTypeChangePassword] += 4),
+ (l.AutoFillFormType =
+ this._autoFillFormTypeOfTypesUsingKeywordMatching(
+ e,
+ [
+ WBSAutoFillFormTypeAutoFillableLogin,
+ WBSAutoFillFormTypeChangePassword,
+ ],
+ WBSAutoFillFormTypeChangePassword,
+ t,
+ ).formType));
+ else if (this._matchesPasswordFieldLabelPattern(G))
+ if (this._isElementFollowedByForgotPasswordAffordance(G, i, a, s))
+ l.AutoFillFormType = WBSAutoFillFormTypeAutoFillableLogin;
+ else {
+ var j = [
+ WBSAutoFillFormTypeNewAccount,
+ WBSAutoFillFormTypeAutoFillableLogin,
+ WBSAutoFillFormTypeChangePassword,
+ ];
+ (this._isPasswordFieldFollowedByPasswordRequirementText(G, i) &&
+ ((t[WBSAutoFillFormTypeNewAccount] += 4),
+ (t[WBSAutoFillFormTypeChangePassword] += 4)),
+ (l.AutoFillFormType =
+ this._autoFillFormTypeOfTypesUsingKeywordMatching(
+ e,
+ j,
+ WBSAutoFillFormTypeNonAutoFillable,
+ t,
+ ).formType),
+ l.AutoFillFormType === WBSAutoFillFormTypeNonAutoFillable &&
+ J &&
+ (l.AutoFillFormType = WBSAutoFillFormTypeNewAccount));
+ }
+ else l.AutoFillFormType = WBSAutoFillFormTypeNonAutoFillable;
+ } else
+ 0 !== _.length &&
+ (l.AutoFillFormType = WBSAutoFillFormTypeNonAutoFillable);
+ if (
+ l.AutoFillFormType === WBSAutoFillFormTypeAutoFillableStandard &&
+ this._shouldDetectStandaloneUserNameFields()
+ ) {
+ var Y = null,
+ z = null,
+ $ = null,
+ Z = 0,
+ X = k.length;
+ for (R = 0; R < X; ++R) {
+ U = k[R];
+ var Q = l.FormControls[R],
+ ee = Q.IsVisible;
+ if ((ee && Q.ControlIsTextField && Z++, Z > 1)) break;
+ if (U.closest("footer")) continue;
+ let t = { [WBSAutoFillFormTypeAutoFillableLogin]: 0 };
+ this._isElementFollowedByForgotUserNameOrEmailOrFederatedSignInAffordance(
+ U,
+ i,
+ a,
+ s,
+ ) && (t[WBSAutoFillFormTypeAutoFillableLogin] += 2);
+ !!this._matchPatternAgainstString(
+ this._cachedLoginFormTypePatternMatcher(),
+ documentTitleWithoutHostNamePrefix(),
+ ) && (t[WBSAutoFillFormTypeAutoFillableLogin] += 1);
+ var te = this._isLabeledEmailField(U);
+ if (
+ ee &&
+ (Q.ControlClaimsToBeUsernameViaAutocompleteAttribute ||
+ Q.ControlIsLabeledUsernameField ||
+ te ||
+ this._isLabeledLoginField(U)) &&
+ !this._matchesNonUsernameFieldLabelPattern(U) &&
+ !this._matchSearchFieldLabelPattern(U) &&
+ !U.readOnly &&
+ "INPUT" === U.tagName &&
+ !this._isLabeledSignUpField(U)
+ ) {
+ this._autoFillFormTypeOfTypesUsingKeywordMatching(
+ e,
+ [
+ WBSAutoFillFormTypeNewAccount,
+ WBSAutoFillFormTypeAutoFillableLogin,
+ ],
+ te
+ ? WBSAutoFillFormTypeNewAccount
+ : WBSAutoFillFormTypeAutoFillableLogin,
+ t,
+ ).formType === WBSAutoFillFormTypeAutoFillableLogin &&
+ ((Y = U), (z = Q), ($ = WBSAutoFillFormTypeAutoFillableLogin));
+ }
+ const r = Q.AutocompleteTokens;
+ if (r) {
+ const o = r.includes("username"),
+ n = r.includes("email");
+ if (r.includes("webauthn") && (o || n)) {
+ ((Y = U), (z = Q), ($ = WBSAutoFillFormTypeAutoFillableLogin));
+ continue;
+ }
+ o &&
+ te &&
+ ((Y = U),
+ (z = Q),
+ ($ = this._autoFillFormTypeOfTypesUsingKeywordMatching(
+ e,
+ [
+ WBSAutoFillFormTypeNewAccount,
+ WBSAutoFillFormTypeAutoFillableLogin,
+ ],
+ WBSAutoFillFormTypeAutoFillableLogin,
+ t,
+ ).formType));
+ }
+ }
+ 1 === Z &&
+ z &&
+ $ &&
+ !controlAppearsToBePartOfPhotoTaggingInterface(Y) &&
+ ((l.AutoFillFormType = $),
+ (l.UsernameElementUniqueID = z.ControlUniqueID));
+ }
+ ((l.IsVisible ||= l.FormControls.some((e) => e.IsVisible)),
+ l.AutoFillFormType === WBSAutoFillFormTypeNewAccount &&
+ l.FirstCreditCardCardholderFieldOrCreditCardNumberFieldUniqueID ===
+ l.UsernameElementUniqueID &&
+ (l.UsernameElementUniqueID = void 0),
+ !l.UsernameElementUniqueID &&
+ J &&
+ this._extractMetadataForHiddenUsernameElement(J, l, k),
+ l.AutoFillFormType != WBSAutoFillFormTypeAutoFillableLogin &&
+ l.AutoFillFormType != WBSAutoFillFormTypeNewAccount &&
+ l.AutoFillFormType != WBSAutoFillFormTypeChangePassword &&
+ t !== WBSFormMetadataRequestAutomaticPasswordChange &&
+ ((l.UsernameElementUniqueID = void 0),
+ (l.OldPasswordElementUniqueID = void 0),
+ (l.PasswordElementUniqueID = void 0),
+ (l.ConfirmPasswordElementUniqueID = void 0)),
+ l.AutoFillFormType === WBSAutoFillFormTypeChangePassword &&
+ l.PasswordElementUniqueID &&
+ !l.OldPasswordElementUniqueID &&
+ 1 === _.length &&
+ (this._oldPasswordPatternMatchers ||
+ (this._oldPasswordPatternMatchers =
+ FormMetadataJSController.oldPasswordFieldLabelPatternMatchers),
+ this._bestMatchForElement(_[0], this._oldPasswordPatternMatchers) &&
+ ((l.OldPasswordElementUniqueID = l.PasswordElementUniqueID),
+ (l.PasswordElementUniqueID = void 0))),
+ l.IsVisible ||
+ l.AutoFillFormType == WBSAutoFillFormTypeAutoFillableLogin ||
+ l.AutoFillFormType == WBSAutoFillFormTypeNewAccount ||
+ l.AutoFillFormType == WBSAutoFillFormTypeChangePassword ||
+ (l.AutoFillFormType = WBSAutoFillFormTypeNonAutoFillable),
+ t !== WBSFormMetadataRequestPreFill &&
+ (l.TextSample = this._collectTextSample(e.formElement)),
+ (l.FormIsEligibleForAutomaticLogin =
+ this._formIsEligibleForAutomaticLogin(l, e.backingElement)));
+ for (let e of l.FormControls)
+ if (
+ e.ControlLooksLikeOneTimeCodeField &&
+ this._oneTimeCodeIsEligibleForAutomaticLogin(e, l)
+ ) {
+ e.OneTimeCodeIsEligibleForAutomaticLogin = !0;
+ break;
+ }
+ if (l.IsVisible && !FormMetadataJSController.collectAllFields)
+ for (R = (X = k.length) - 1; R >= 0; --R)
+ this._shouldIncludeControlMetadata(l, k[R], l.FormControls[R]) ||
+ (t !== WBSFormMetadataRequestCollectMetadataFromDebugMenu
+ ? (l.FormControls.splice(R, 1), k.splice(R, 1))
+ : (l.FormControls[R].WOULD_NORMALLY_NOT_BE_SENT_TO_UI_PROCESS =
+ !0));
+ return (
+ this._removePlaceholderTextForFormMetadata(k, l),
+ delete this._pageScanContext,
+ t !== WBSFormMetadataRequestPreFill &&
+ globalThis.FormMetadataClassificationJS &&
+ globalThis.FormMetadataClassificationJS.classify(l),
+ this._markFormIsCandidateForAdditionalClassifications(
+ l,
+ e.backingElement,
+ ),
+ addPasswordRequirementsToFormMetadata(l),
+ l
+ );
+ }
+ _markFormIsCandidateForAdditionalClassifications(e, t) {
+ if (!e.IsVisible) return;
+ if (
+ e.AutoFillFormType === WBSAutoFillFormTypeAutoFillableLogin ||
+ e.AutoFillFormType === WBSAutoFillFormTypeChangePassword
+ )
+ return;
+ let r = 0;
+ for (const t of e.FormControls) {
+ if (!t.IsVisible) continue;
+ const o = t.ControlUniqueID,
+ n = this.formControlWithUniqueID(o);
+ n &&
+ this._isAutoFillableTextFieldOrSelectElementOrTextAreaElement(n) &&
+ (isCredentialElementUniqueID(e, o) ||
+ this._matchSearchFieldLabelPattern(n) ||
+ (this._looksLikeGenericAdditionalClassificationsControl(n) && r++));
+ }
+ r < 1 || (e.FormIsCandidateForAdditionalClassifications = !0);
+ }
+ _formIsEligibleForAutomaticLogin(e, t) {
+ if (e.AutoFillFormType !== WBSAutoFillFormTypeAutoFillableLogin) return !1;
+ let r = !1;
+ for (const t of e.FormControls) {
+ const o = t.ControlUniqueID;
+ if (o === e.UsernameElementUniqueID || o === e.PasswordElementUniqueID)
+ continue;
+ if (t.ControlIsDisabled) continue;
+ if (t.ControlIsReadOnly) continue;
+ if (!t.IsVisible) continue;
+ const n = this.formControlWithUniqueID(o);
+ if (!n) continue;
+ if (this._isTextArea(n)) return !1;
+ if (isSelectElement(n)) return !1;
+ if (this._isSubmitButton(n)) continue;
+ if (this._looksLikeShowHidePasswordButton(n)) continue;
+ if (!isInputElement(n)) continue;
+ const i = n.type;
+ if ("button" !== i && "reset" !== i && "submit" !== i && "image" !== i) {
+ if (!this._isCheckboxInputElement(n)) return !1;
+ if (r) return !1;
+ r = !0;
+ }
+ }
+ return !t || !elementAppearsToContinueCaptchaWidget(t);
+ }
+ _oneTimeCodeIsEligibleForAutomaticLogin(e, t) {
+ for (const e of t.FormControls) {
+ if (e.ControlLooksLikeOneTimeCodeField) continue;
+ if (e.ControlIsDisabled) continue;
+ if (e.ControlIsReadOnly) continue;
+ if (!e.IsVisible) continue;
+ const t = this.formControlWithUniqueID(e.ControlUniqueID);
+ if (!t) continue;
+ if (this._isTextArea(t)) return !1;
+ if (isSelectElement(t)) return !1;
+ if (this._isSubmitButton(t)) continue;
+ if (this._looksLikeShowHidePasswordButton(t)) continue;
+ if (!isInputElement(t)) continue;
+ const r = t.type;
+ if ("button" !== r && "reset" !== r && "submit" !== r && "image" !== r)
+ return !1;
+ }
+ return !0;
+ }
+ _shouldIncludeControlMetadata(e, t, r) {
+ if (
+ isContentEditableSingleLineTextbox(t) &&
+ !r.ControlLooksLikeOneTimeCodeField
+ )
+ return !1;
+ if (t._relatesToCredentials) return !0;
+ if (r.IsVisible) {
+ if (formControlHasBeenClassifiedInAnInterestingWay(r)) return !0;
+ if (r.ControlValue) return !0;
+ } else if (
+ this._isPotentialInvisibleOneTimeCodeControl(t) &&
+ r.ControlLooksLikeOneTimeCodeField
+ )
+ return !0;
+ return !(
+ !e.UsernameElementUniqueID ||
+ r.ControlUniqueID !== e.UsernameElementUniqueID
+ );
+ }
+ _isElementAHiddenUsername(e) {
+ const t = /user|email/i;
+ return (
+ "hidden" === e.type &&
+ !(!t.test(e.getAttribute("id")) && !t.test(e.getAttribute("name"))) &&
+ !!isValidUsernameOrEmail(e.af_value())
+ );
+ }
+ _findHiddenUsernameElement(e, t, r) {
+ var o = e.formElement;
+ if (!(o instanceof HTMLElement)) return;
+ let n = queryAllBySelector(o, "input"),
+ i = n.length;
+ for (let e = 0; e < i; ++e) {
+ let t = n[e];
+ if (this._isElementAHiddenUsername(t)) return t;
+ }
+ return null;
+ }
+ _extractMetadataForHiddenUsernameElement(e, t, r) {
+ var o = {
+ ControlTagName: this._getTagName(e),
+ ControlFieldName: this._getNameOrId(e),
+ ControlUniqueID: this.controlUniqueID(e),
+ ControlIsReadOnly: !0,
+ ControlValue: e.af_value(),
+ };
+ (window.webkit?.createJSHandle &&
+ (o.ControlJSHandle = this.ensureElementHandle(e)),
+ (t.UsernameElementUniqueID = o.ControlUniqueID),
+ t.FormControls.push(o),
+ r.push(e));
+ }
+ _cachedMetadataForLogicalForm(e) {
+ var t = e.metadata,
+ r = t?.FormControls,
+ o = r?.length ?? 0;
+ if (!o) return null;
+ const n = innermostActiveElement();
+ for (var i = 0; i < o; ++i) {
+ var l = r[i],
+ a = this.formControlWithUniqueID(l.ControlUniqueID);
+ a &&
+ ((l.ControlIsActiveElement = a === n),
+ (l.ControlValue = a.af_value()),
+ (l.ControlIsAutoFilledTextField = this._isAutoFilledTextField(a)));
+ }
+ return (
+ (t.UsesGeneratedPassword = this._usesGeneratedPassword(e)),
+ (t.Annotations = e.annotations),
+ t
+ );
+ }
+ _markFormIsBestForPageLevelAutoFill() {
+ function e(e) {
+ switch (e) {
+ case WBSAutoFillFormTypeAutoFillableLogin:
+ return 30;
+ case WBSAutoFillFormTypeNewAccount:
+ case WBSAutoFillFormTypeChangePassword:
+ return 20;
+ case WBSAutoFillFormTypeAutoFillableStandard:
+ return 10;
+ case WBSAutoFillFormTypeUndetermined:
+ case WBSAutoFillFormTypeNonAutoFillable:
+ return 0;
+ }
+ return -100;
+ }
+ function t(e) {
+ return e ? 50 : 0;
+ }
+ let r = this._logicalFormWithHighestScoreIfGreaterThanZero(function (r) {
+ var o = r.PasswordElementUniqueID ? 0 : -1;
+ return e(r.AutoFillFormType) + t(r.IsVisible) + o;
+ });
+ null !== r && (r.metadata.FormIsBestForPageLevelAutoFill = !0);
+ }
+ _markFormIsBestForStreamlinedLogin() {
+ let e = this._logicalFormWithHighestScoreIfGreaterThanZero(function (e, t) {
+ if (!e.IsVisible) return 0;
+ let r = t.getBoundingClientRect();
+ if (!rectIsWithinDocumentViewport(r)) return 0;
+ if (r.bottom + window.scrollY < 80) {
+ let e = !(
+ location.hash ||
+ (location.pathname && "/" !== location.pathname) ||
+ location.search
+ ),
+ t = r.width / r.height;
+ if (!e && t > 4) return 0;
+ }
+ if (t.closest("footer")) return 0;
+ let o = e.AutoFillFormType === WBSAutoFillFormTypeAutoFillableLogin,
+ n = 0,
+ i = e.FormControls,
+ l = i.length;
+ for (var a = 0; a < l; ++a) {
+ let t = i[a],
+ r = FormMetadataJS.formControlWithUniqueID(t.ControlUniqueID);
+ if (!r) continue;
+ const l = parseInt(r.tabIndex, 10);
+ if (!(isFiniteNumber(l) && l < 0)) {
+ if (o) {
+ t.ControlIsAutofocusedTextField && (n += 1);
+ let r = t.ControlUniqueID;
+ if (
+ r === e.UsernameElementUniqueID ||
+ r === e.PasswordElementUniqueID
+ ) {
+ n += 10;
+ continue;
+ }
+ }
+ t.OneTimeCodeIsEligibleForAutomaticLogin && (n += 5);
+ }
+ }
+ return n;
+ });
+ null !== e && (e.metadata.FormIsBestForStreamlinedLogin = !0);
+ }
+ _logicalFormWithHighestScoreIfGreaterThanZero(e) {
+ let t = null,
+ r = null;
+ for (let n of this._logicalFormsCache.allForms()) {
+ var o = e(n.metadata, n.backingElement);
+ (null === t || o > t) && ((r = n), (t = o));
+ }
+ return t > 0 ? r : null;
+ }
+ isAnyFormAnnotated() {
+ return this._logicalFormsCache.allForms().some((e) => e.isAnnotated);
+ }
+ annotateFormWithID(e, t) {
+ let r = this._logicalFormsCache.logicalFormWithUniqueID(e);
+ r && r.annotate(t);
+ }
+ _collectMetadata(e) {
+ const t = 100,
+ r = 10;
+ var o = this._logicalFormsInPage(t, r);
+ this._logicalFormsCache.clearCacheAndAdd(o);
+ for (var n = o.length, i = 0; i < n; ++i)
+ o[i].metadata = this._collectFormMetadata(o[i], e);
+ (this._markFormIsBestForPageLevelAutoFill(),
+ e !== WBSFormMetadataRequestNormal &&
+ e !== WBSFormMetadataRequestAutomaticPasswordChange &&
+ this._markFormIsBestForStreamlinedLogin());
+ }
+ _collectAndCacheFormMetadata(e, t) {
+ let r = this._collectFormMetadata(e, t),
+ o = this._logicalFormsCache.logicalFormWithUniqueID(e.formUniqueID);
+ return (
+ o
+ ? (o.metadata = r)
+ : ((e.metadata = r), this._logicalFormsCache.addOrUpdate(e)),
+ r
+ );
+ }
+ _metadataForFormWithID(e) {
+ return this._logicalFormsCache.logicalFormWithUniqueID(e)?.metadata;
+ }
+ _recollectMetadataForFormWithID(e) {
+ const t = this._logicalFormsCache.logicalFormWithUniqueID(e);
+ return t
+ ? this._collectAndCacheFormMetadata(t, WBSFormMetadataRequestNormal)
+ : null;
+ }
+ async _fillControlWithGeneratedPassword(e, t) {
+ var r = this._elementsWithGeneratedPasswords.indexOf(e);
+ (-1 === r &&
+ (this._elementsWithGeneratedPasswords.push(e),
+ (r = this._elementsWithGeneratedPasswords.length - 1)),
+ (this._generatedPasswords[r] = t));
+ const o = !0;
+ await this._fillControl(e, t, o);
+ }
+ async fillFormWithPassword(e, t, r) {
+ var o = this._metadataForFormWithID(e);
+ if (null === o) return null;
+ const n = o.PasswordElementUniqueID,
+ i = n ? this.formControlWithUniqueID(n) : void 0,
+ l = r ? this.formControlWithUniqueID(r) : void 0;
+ var a = i || l;
+ const s = n || r;
+ if (!a) return null;
+ await this._fillControlWithGeneratedPassword(a, t);
+ let u = o.ConfirmPasswordElementUniqueID;
+ u ||
+ (o.AutoFillFormType !== WBSAutoFillFormTypeChangePassword &&
+ o.AutoFillFormType !== WBSAutoFillFormTypeNewAccount) ||
+ (u = (o = this._recollectMetadataForFormWithID(e) || o)
+ .ConfirmPasswordElementUniqueID);
+ let c = u ? this.formControlWithUniqueID(u) : null;
+ return c
+ ? (await this._fillControlWithGeneratedPassword(c, t), [s, u])
+ : [s];
+ }
+ clearField(e) {
+ const t = this.formControlWithUniqueID(e),
+ r = !0;
+ this._clearControl(t, r);
+ }
+ async _clearControl(e, t = !1) {
+ if (!e) return;
+ if (isSelectElement(e)) return void (e.selectedIndex = 0);
+ if (isDateTimeInputElement(e)) return void e.af_setValue("");
+ if (isRadioButtonElement(e)) {
+ const t = this._logicalFormsCache
+ .logicalFormForControl(e)
+ .radioButtonsWithName(e.name);
+ for (let e of t) e.checked = !1;
+ return;
+ }
+ if (!this._isTextField(e)) return;
+ if (!e.af_value().length) return;
+ let r = innermostActiveElement();
+ (e !== r && e.focus({ preventScroll: !0, focusVisible: !1 }),
+ e.select(),
+ e.dispatchEvent(new Event("select", { bubbles: !0, cancelable: !1 })));
+ const o = KeyInfo.BackspaceKeyInfo;
+ e.dispatchEvent(o.keyEvent("keydown"));
+ const n = "deleteContentBackward";
+ (e.dispatchEvent(
+ new InputEvent("beforeinput", {
+ bubbles: !0,
+ cancelable: !0,
+ inputType: n,
+ data: null,
+ }),
+ ),
+ e.af_setValue(""),
+ e.dispatchEvent(
+ new InputEvent("input", {
+ bubbles: !0,
+ cancelable: !1,
+ inputType: n,
+ data: null,
+ }),
+ ),
+ e.dispatchEvent(o.keyEvent("keyup")),
+ e.dispatchEvent(new Event("change", { bubbles: !0, cancelable: !1 })),
+ t || (await yieldToEventLoopAfterAnimationFrameAndDelay()),
+ r && e !== r && r.focus({ preventScroll: !0 }));
+ }
+ focusFormForStreamlinedLogin(e) {
+ const t = function (e) {
+ for (const t of e.FormControls) {
+ const r = t.ControlUniqueID;
+ if (
+ r === e.UsernameElementUniqueID ||
+ r === e.PasswordElementUniqueID ||
+ t.ControlLooksLikeOneTimeCodeField
+ ) {
+ let e = this.formControlWithUniqueID(r);
+ if (e.isVisible() && !e.disabled) return e;
+ }
+ }
+ return null;
+ }.bind(this);
+ var r = this._metadataForFormWithID(e);
+ null !== r && this._focusControlForStreamlinedLogin(t(r));
+ }
+ focusControl(e, t = !1) {
+ const r = this.formControlWithUniqueID(e);
+ r && (t ? this._focusControlForStreamlinedLogin(r) : r.focus());
+ }
+ _focusControlForStreamlinedLogin(e) {
+ e && rectIsWithinDocumentViewport(e.getBoundingClientRect()) && e.focus();
+ }
+ formsAndMetadata(e) {
+ (invalidateVisibilityCache(), this._collectMetadata(e));
+ let t = [],
+ r = [];
+ for (let e of this._logicalFormsCache.allForms())
+ (t.push(e.formElement), r.push(e.metadata));
+ return [t, r];
+ }
+ formControlWithUniqueID(e) {
+ let t = this._controlUniqueIDToWeakControlMap.get(e)?.deref();
+ return t;
+ }
+ startObservingDynamicallyAddedControls() {
+ const e = this._logicalFormsCache.allForms();
+ for (const t of e) t.startObservingAddedControls();
+ }
+ formElementWithFormID(e) {
+ return this._logicalFormsCache.logicalFormWithUniqueID(e)?.formElement;
+ }
+ selectIfTextField(e) {
+ this._isTextField(e) && e.select();
+ }
+ _getOrCreateCachedMetadataForLogicalForm(e, t) {
+ var r = this._cachedMetadataForLogicalForm(e);
+ return !r ||
+ (null != t &&
+ r.RequestType === WBSFormMetadataRequestPreFill &&
+ t !== WBSFormMetadataRequestPreFill)
+ ? this._collectAndCacheFormMetadata(e, t)
+ : r;
+ }
+ _getOrCreateLogicalFormForTextFieldOrSelectElement(e) {
+ let t = this._logicalFormsCache.logicalFormForControl(e);
+ if (t)
+ for (
+ var r = t.metadata,
+ o = r?.FormControls,
+ n = o?.length ?? 0,
+ i = e._controlUniqueID,
+ l = 0;
+ l < n;
+ ++l
+ )
+ if (o[l].ControlUniqueID === i) return t;
+ var a = this._logicalFormsInPage(),
+ s = a.length;
+ for (l = 0; l < s; ++l) {
+ var u = a[l];
+ if (u.containsControl(e))
+ return (
+ this._logicalFormsCache.addOrUpdate(u),
+ (u.metadata = this._collectFormMetadata(
+ u,
+ WBSFormMetadataRequestNormal,
+ )),
+ u
+ );
+ }
+ return null;
+ }
+ _cachedMetadataForFormWithTextFieldOrSelectElement(e, t) {
+ if (
+ !this._isTextField(e) &&
+ !isSelectElement(e) &&
+ !isContentEditableSingleLineTextbox(e)
+ )
+ return null;
+ var r = this._getOrCreateLogicalFormForTextFieldOrSelectElement(e);
+ return r ? this._getOrCreateCachedMetadataForLogicalForm(r, t) : null;
+ }
+ _isAnyPasswordElementUniqueID(e, t) {
+ return (
+ e.PasswordElementUniqueID === t ||
+ e.ConfirmPasswordElementUniqueID === t ||
+ e.OldPasswordElementUniqueID === t
+ );
+ }
+ _isCurrentPasswordElementUniqueID(e, t) {
+ switch (e.AutoFillFormType) {
+ case WBSAutoFillFormTypeNewAccount:
+ case WBSAutoFillFormTypeChangePassword:
+ return e.OldPasswordElementUniqueID === t;
+ default:
+ return e.PasswordElementUniqueID === t;
+ }
+ }
+ _isNewPasswordElementUniqueID(e, t) {
+ switch (e.AutoFillFormType) {
+ case WBSAutoFillFormTypeNewAccount:
+ case WBSAutoFillFormTypeChangePassword:
+ return (
+ e.PasswordElementUniqueID === t ||
+ e.ConfirmPasswordElementUniqueID === t
+ );
+ default:
+ return !1;
+ }
+ }
+ _updateAnnotationsForField(e) {
+ var t = this._getOrCreateLogicalFormForTextFieldOrSelectElement(e);
+ if (t) {
+ var r = this._getOrCreateCachedMetadataForLogicalForm(t);
+ if (r) {
+ var o = e._controlUniqueID;
+ (this._isCurrentPasswordElementUniqueID(r, o)
+ ? t.annotate({ CurrentPassword: e.af_value() })
+ : this._isNewPasswordElementUniqueID(r, o)
+ ? t.annotate({ NewPassword: e.af_value() })
+ : r.UsernameElementUniqueID === o &&
+ t.annotate({ Username: e.af_value() }),
+ isCredentialElementUniqueID(r, o) &&
+ (e._relatesToCredentials = "" !== e.af_value()));
+ }
+ }
+ }
+ textFieldOrSelectElementMetadata(e, t) {
+ (invalidateVisibilityCache(),
+ this._logicalFormsCache.removeUnparentedLogicalFormsFromCache());
+ var r = [null, null],
+ o = this._cachedMetadataForFormWithTextFieldOrSelectElement(e, t);
+ if (!o) return r;
+ this._pageScanContext = {
+ backwardScanCache: new WeakMap(),
+ forwardScanCache: new WeakMap(),
+ };
+ let n = this._logicalFormsCache.logicalFormWithUniqueID(o.FormID),
+ i = formActionAsAnchorElement(n.formElement),
+ [l, a, s, u, c] =
+ this._trailingArgumentsForCollectControlMetadataFunction(n, t, i);
+ const d = !0;
+ var h = this._collectControlMetadata(
+ e,
+ WBSFormMetadataRequestNormal,
+ l,
+ a,
+ s,
+ u,
+ c,
+ d,
+ );
+ if (
+ (delete this._pageScanContext,
+ h.ControlLooksLikeOneTimeCodeField &&
+ this._oneTimeCodeIsEligibleForAutomaticLogin(h, o) &&
+ (h.OneTimeCodeIsEligibleForAutomaticLogin = !0),
+ (h.SelectionStart = e.selectionStart),
+ (h.SelectionLength = e.selectionEnd - e.selectionStart),
+ t === WBSFormMetadataRequestTextChange &&
+ (!o.UsernameElementUniqueID &&
+ this._isAnyPasswordElementUniqueID(o, h.ControlUniqueID) &&
+ n.isAnnotated &&
+ n.annotate({ Username: null }),
+ this._updateAnnotationsForField(e)),
+ o.RequestType !== WBSFormMetadataRequestPreFill)
+ )
+ for (let e of o.FormControls)
+ if (h.ControlUniqueID === e.ControlUniqueID) {
+ ((h.ControlClassification = e.ControlClassification),
+ (h.ControlClassificationHints = e.ControlClassificationHints),
+ (h.ControlOrderedParts = e.ControlOrderedParts),
+ (h.ControlContinuationID = e.ControlContinuationID),
+ (h.ControlContinuationIndex = e.ControlContinuationIndex),
+ (h.ControlNextFieldUniqueID = e.ControlNextFieldUniqueID),
+ (h.ControlJSHandle = e.ControlJSHandle));
+ break;
+ }
+ return ((r[0] = h), (r[1] = o), r);
+ }
+ disableSpellCheckInFieldIfNeeded(e) {
+ if (e) {
+ var t = this.formControlWithUniqueID(e);
+ t &&
+ this._isAutoFillableTextField(t) &&
+ FormMetadataJSController.setInputElementSpellCheckEnabled(t, !1);
+ }
+ }
+ selectionRangeInField(e) {
+ var t = this.formControlWithUniqueID(e);
+ return t && this._isTextField(t)
+ ? [t.selectionStart, t.selectionEnd - t.selectionStart]
+ : null;
+ }
+ setFormFieldSelection(e, t, r) {
+ var o = this.formControlWithUniqueID(e);
+ o && this._isTextField(o) && this._setSelectionStartAndEnd(o, t, t + r);
+ }
+ replaceFormFieldRangeAndSelectTail(e, t, r, o, n) {
+ var i = this.formControlWithUniqueID(e);
+ if (i && this._isTextField(i)) {
+ var l = i.af_value(),
+ a = l.substr(0, t) + o + l.substr(t + r);
+ (i.af_setValue(a),
+ this._setSelectionStartAndEnd(i, n, a.length),
+ i.dispatchEvent(createCustomEventThatBubbles("input")),
+ i.dispatchEvent(createCustomEventThatBubbles("change")));
+ }
+ }
+ _collectVisibleNonEmptyTextFieldsAndTextAreasInForm(e, t, r) {
+ invalidateVisibilityCache();
+ for (
+ var o = elementsInFormPiercingShadowDOM(e), n = o.length, i = 0;
+ i < n;
+ ++i
+ ) {
+ var l = o[i];
+ l.isVisible() &&
+ null != l.af_value() &&
+ l.af_value().length &&
+ (this._isTextField(l) ? t.push(l) : this._isTextArea(l) && r.push(l));
+ }
+ }
+ visibleNonEmptyFormTextControls() {
+ var e = [],
+ t = [];
+ let r = queryAllBySelector(document, "form");
+ for (let o = 0; o < r.length; ++o)
+ this._collectVisibleNonEmptyTextFieldsAndTextAreasInForm(r[o], e, t);
+ return [e, t];
+ }
+ async _fillRadioButtonInGroupStartingWithControl(e, t) {
+ const r = this._logicalFormsCache.logicalFormForControl(e);
+ let o = r?.radioButtonsWithName(e.name);
+ if (!o) return null;
+ for (let e of o)
+ if (e.af_value() === t)
+ return (
+ dispatchEventsSimulatingClickOnElement(e),
+ (e.checked = !0),
+ e.dispatchEvent(
+ new InputEvent("input", { bubbles: !0, cancelable: !1 }),
+ ),
+ e.dispatchEvent(new Event("change", { bubbles: !0, cancelable: !1 })),
+ await yieldToEventLoop(),
+ e
+ );
+ return null;
+ }
+ _controlContainsAllCharactersFromValue(e, t) {
+ let r = [...e.af_value().normalize()],
+ o = [...t.normalize()];
+ if (r.length < o.length) return !1;
+ for (let e of r) {
+ e === o[0] && o.shift();
+ }
+ return !o.length;
+ }
+ async _fillSelectControlWithBestOptionFromSynonyms(e, t) {
+ const r = this._collectSelectElementInfo(e),
+ o = FormMetadataUtilitiesJS.bestIndexToFillSelectControl(r, t);
+ -1 !== o &&
+ e.selectedIndex !== o &&
+ (e.dispatchEvent(createCustomEventThatBubbles("focus")),
+ e.dispatchEvent(createCustomEventThatBubbles("pointerdown")),
+ e.dispatchEvent(createCustomEventThatBubbles("mousedown")),
+ (e.selectedIndex = o),
+ e.dispatchEvent(new InputEvent("input", { bubbles: !0, cancelable: !1 })),
+ e.dispatchEvent(new Event("change", { bubbles: !0, cancelable: !1 })),
+ e.dispatchEvent(createCustomEventThatBubbles("blur")),
+ await yieldToEventLoop());
+ }
+ delayBetweenFillingCharactersForFillingOneTimeCode(e) {
+ const t = 10,
+ r = 100;
+ for (let o = e; o; o = o.parentElementIncludingShadowDOMHost()) {
+ const e = o.getAttribute("debounce");
+ if (!e) continue;
+ const n = parseFloat(e);
+ if (0 < n && n <= r) return n + t;
+ break;
+ }
+ return t;
+ }
+ async autoFillOneTimeCodeFieldsWithValue(e, t) {
+ let r = !1;
+ try {
+ const t = innermostActiveElement();
+ if (!this._isAutoFillableTextField(t))
+ return {
+ value: e,
+ shouldSubmit: !1,
+ codeAppearsToHaveBeenFilledInItsEntirety: !1,
+ };
+ const o = {
+ delayBetweenFillingCharacters:
+ this.delayBetweenFillingCharactersForFillingOneTimeCode(t),
+ waitForSingleCharacterFields: {
+ delayBetweenChecksInMilliseconds: 1,
+ minimumNumberOfTimesToCheckBeforeGivingUp: 20,
+ minimumDurationToCheckBeforeGivingUpInMilliseconds: 400,
+ },
+ bypassFallbackToGenericFilling: !0,
+ },
+ n = await this._performAutoFillOperationsWhilePreventingUserInteraction(
+ async () => await this._fillTextControl(null, e, o),
+ );
+ if (((r = this._oneTimeCodeAppearsToHaveFilledProperly(e, n)), !r)) {
+ const i = allControlsForSingleCharacterLogicalFieldForControl(t),
+ l = i.length;
+ i.length && e.length === l
+ ? (await this._performAutoFillOperationsWhilePreventingUserInteraction(
+ async () => {
+ for (let t = 0; t < l; ++t)
+ await this._fillTextControl(i[t], e[t], o);
+ },
+ ),
+ (r = this._oneTimeCodeAppearsToHaveFilledProperly(e, i)))
+ : 1 === n.length &&
+ (await this._performAutoFillOperationsWhilePreventingUserInteraction(
+ async () => {
+ await this._fillGenericControl(n[0], e);
+ },
+ ),
+ (r = this._oneTimeCodeAppearsToHaveFilledProperly(e, n)));
+ }
+ } catch (e) {}
+ return {
+ value: e,
+ shouldSubmit: t,
+ codeAppearsToHaveBeenFilledInItsEntirety: r,
+ };
+ }
+ _oneTimeCodeAppearsToHaveFilledProperly(e, t) {
+ if (!RegExp.escape) return !0;
+ let r = !0;
+ const o = e.substring(0, e.length - 1),
+ n = t.map((e) => e.af_value()).join(""),
+ i = new RegExp(
+ o
+ .replaceAll("-", "")
+ .split("")
+ .map((e) => RegExp.escape(e))
+ .join(".*"),
+ "s",
+ );
+ if (((r = i.test(n)), !r)) {
+ const e = this._logicalFormsCache.logicalFormForControl(
+ t[0],
+ )?.backingElement;
+ e && (r = i.test(e.innerText));
+ }
+ return r;
+ }
+ async _waitForFocusToAdvanceFromControl(e, t, r, o) {
+ const n = performance.now();
+ let i = 0,
+ l = !1,
+ a = setTimeout(() => {
+ l = !0;
+ }, o);
+ for (;;) {
+ const o = innermostActiveElement();
+ if (!o || e !== o) break;
+ if ((++i, i >= t && l)) break;
+ await yieldUntilEventOrTimeout("focusin", r, {
+ eventTargetToIgnore: e,
+ requireEventTargetBeDocumentActiveElement: !0,
+ });
+ }
+ clearTimeout(a);
+ performance.now();
+ }
+ async _fillTextControl(e, t, r = {}) {
+ if (e && this._controlContainsAllCharactersFromValue(e, t)) return;
+ if (
+ e &&
+ userIsOnDomain("m.facebook.com") &&
+ document.location.pathname.startsWith("/login") &&
+ "m_login_email" === e.id
+ )
+ return void (await this._fillGenericControl(e, t));
+ let o = new Set();
+ const n = !e;
+ ((e ??= innermostActiveElement()), await this._clearControl(e));
+ const i = !!r.waitForSingleCharacterFields;
+ let l = 0,
+ a = 0,
+ s = 0;
+ i &&
+ ((l =
+ r.waitForSingleCharacterFields
+ .minimumNumberOfTimesToCheckBeforeGivingUp),
+ (a = r.waitForSingleCharacterFields.delayBetweenChecksInMilliseconds),
+ (s =
+ r.waitForSingleCharacterFields
+ .minimumDurationToCheckBeforeGivingUpInMilliseconds));
+ let u,
+ c = !0;
+ for (let d of t) {
+ let t =
+ i &&
+ (1 === e.maxLength || controlIsPartOfSingleCharacterLogicalField(e));
+ t && !c && (await this._waitForFocusToAdvanceFromControl(e, l, a, s));
+ const h = innermostActiveElement();
+ if (h !== e) {
+ if (!n) break;
+ let t =
+ e &&
+ h &&
+ !e.isConnected &&
+ h.isConnected &&
+ e.id === h.id &&
+ e.className === h.className &&
+ h.af_value()?.endsWith(u);
+ ((e = h), t || (await this._clearControl(e)));
+ }
+ const m = t ? performance.now() : null;
+ let F = 0,
+ f = m,
+ g = f - m;
+ const C = r.delayBetweenFillingCharacters || 0;
+ for (;;) {
+ const t = KeyInfo.forCharacter(d);
+ t.isShifted && e.dispatchEvent(KeyInfo.shiftKeyEvent("keydown"));
+ let r = !e.dispatchEvent(t.keyEvent("keydown"));
+ if ((r || (r = !e.dispatchEvent(t.keyEvent("keypress"))), !r))
+ if (this.canUseTextInputEventsToFill)
+ e.dispatchEvent(createTextInputEvent(d));
+ else {
+ const t = e.af_value() + d;
+ (e.dispatchEvent(
+ new InputEvent("beforeinput", {
+ bubbles: !0,
+ cancelable: !0,
+ inputType: insertTextInputType,
+ data: t,
+ }),
+ ),
+ e.af_setValue(t),
+ e.dispatchEvent(
+ new InputEvent("input", {
+ bubbles: !0,
+ cancelable: !1,
+ inputType: insertTextInputType,
+ data: t,
+ }),
+ ));
+ }
+ if (
+ (e.dispatchEvent(t.keyEvent("keyup")),
+ t.isShifted && e.dispatchEvent(KeyInfo.shiftKeyEvent("keyup")),
+ !m)
+ )
+ break;
+ {
+ if ((++F, (f = performance.now()), (g = f - m), F >= l && g > s))
+ break;
+ await yieldToEventLoop();
+ const t = innermostActiveElement();
+ if (!t || e !== t) break;
+ if (e.af_value().at(-1) === d) break;
+ }
+ }
+ (o.add(e), (c = !1), (u = d), await yieldToEventLoop(C));
+ }
+ return (
+ n ||
+ r.bypassFallbackToGenericFilling ||
+ this._controlContainsAllCharactersFromValue(e, t) ||
+ (await yieldToEventLoopAfterAnimationFrameAndDelay(),
+ await this._fillGenericControl(e, t)),
+ Array.from(o)
+ );
+ }
+ async _fillGenericControl(e, t) {
+ (await this._clearControl(e),
+ (this.canUseTextInputEventsToFill &&
+ e === innermostActiveElement() &&
+ (e.dispatchEvent(createTextInputEvent(t)),
+ await yieldToEventLoop(),
+ this._controlContainsAllCharactersFromValue(e, t))) ||
+ (e.dispatchEvent(
+ new InputEvent("beforeinput", {
+ bubbles: !0,
+ cancelable: !0,
+ inputType: insertTextInputType,
+ data: t,
+ }),
+ ),
+ e.af_setValue(t),
+ e.dispatchEvent(
+ new InputEvent("input", {
+ bubbles: !0,
+ cancelable: !1,
+ inputType: insertTextInputType,
+ data: t,
+ }),
+ ),
+ e.dispatchEvent(new Event("change", { bubbles: !0, cancelable: !1 })),
+ await yieldToEventLoop(),
+ this._controlContainsAllCharactersFromValue(e, t)));
+ }
+ async _fillControl(e, t, r, o) {
+ if (e.isDisabledOrReadOnly()) return;
+ if (e.shouldFocusDuringFilling()) {
+ let t = !1;
+ (document.hasFocus() ||
+ (await yieldUntilDocumentIsFocusedOrTimeout(100), (t = !0)),
+ e !== innermostActiveElement() &&
+ (e.focus({ preventScroll: !0, focusVisible: !1 }), (t = !0)),
+ t && (await yieldToEventLoopAfterAnimationFrameAndDelay(20)));
+ }
+ let n = !1;
+ if (isRadioButtonElement(e)) {
+ if (!(e = await this._fillRadioButtonInGroupStartingWithControl(e, t)))
+ return;
+ } else
+ isSelectElement(e)
+ ? await this._fillSelectControlWithBestOptionFromSynonyms(e, t)
+ : ((n = !0),
+ this._isTextField(e)
+ ? await this._fillTextControl(e, t)
+ : await this._fillGenericControl(e, t));
+ const i = t.length && r;
+ n && o
+ ? FormMetadataJSController.setInputElementAutofilledAndObscured(e, i)
+ : FormMetadataJSController.setInputElementAutofilled(e, i);
+ }
+ async _performAutoFillOperationsWhilePreventingUserInteraction(e, t) {
+ const r = new AbortController(),
+ o = [
+ "keydown",
+ "keyup",
+ "keypress",
+ "pointerdown",
+ "pointerup",
+ "touchstart",
+ "touchend",
+ "mousedown",
+ "mouseup",
+ "click",
+ "dblclick",
+ ];
+ for (const e of o)
+ window.addEventListener(
+ e,
+ (e) => {
+ e.isTrusted && (e.preventDefault(), e.stopImmediatePropagation());
+ },
+ { capture: !0, signal: r.signal, webkitTrustedOnly: !0 },
+ );
+ try {
+ return await e();
+ } finally {
+ r.abort(null);
+ }
+ }
+ async autoFillControlsByID(e, t, r, o, n, i, l) {
+ let a = arguments[arguments.length - 1],
+ s = o;
+ if (s) {
+ let e = s.getAttribute("onfocus");
+ e && e.length && /this\.value/.test(e) && (s = null);
+ } else s = innermostActiveElement();
+ var u = null;
+ for (let t in e) {
+ u = this._logicalFormsCache.logicalFormForControl(
+ this.formControlWithUniqueID(t),
+ );
+ break;
+ }
+ const c = Object.entries(e)
+ .map(([e, t]) => [this.formControlWithUniqueID(e), t])
+ .sort((e, t) => {
+ const r = e[0],
+ o = t[0],
+ n = r.compareDocumentPosition(o);
+ if (
+ !(
+ n &
+ (Node.DOCUMENT_POSITION_DISCONNECTED |
+ Node.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC)
+ )
+ ) {
+ if (
+ n &
+ (Node.DOCUMENT_POSITION_PRECEDING | Node.DOCUMENT_POSITION_CONTAINS)
+ )
+ return 1;
+ if (
+ n &
+ (Node.DOCUMENT_POSITION_FOLLOWING |
+ Node.DOCUMENT_POSITION_CONTAINED_BY)
+ )
+ return -1;
+ }
+ const i = (e) => parseInt(e._controlUniqueID.substring(10));
+ return i(r) - i(o);
+ });
+ return (
+ await this._performAutoFillOperationsWhilePreventingUserInteraction(
+ async () => {
+ const e = new Set(i);
+ for (let [t, o] of c) {
+ const n = e.has(t._controlUniqueID);
+ await this._fillControl(t, o, r, n);
+ }
+ },
+ ),
+ n
+ ? innermostActiveElement().blur()
+ : s &&
+ setTimeout(() => {
+ this.selectIfTextField(s);
+ }, 0),
+ u?.backingElement &&
+ elementAppearsToContinueCaptchaWidget(u.backingElement) &&
+ (a = !1),
+ {
+ formMetadata: this._getOrCreateCachedMetadataForLogicalForm(u),
+ shouldSubmit: a,
+ }
+ );
+ }
+ _isInputAllowedInSearchForm(e, t) {
+ var r = this._getTagName(e).toLowerCase();
+ if ("button" === r || "fieldset" === r) return !0;
+ if ("select" === r) return !t || isSelectInDefaultState(e);
+ if ("input" !== r && !this._textAreaElementLookLikeItIsPartOfASearchForm(e))
+ return !1;
+ var o = e.type;
+ return "radio" === o || "checkbox" === o
+ ? !t || isCheckboxOrRadioButtonInDefaultState(e)
+ : "hidden" === o ||
+ "reset" === o ||
+ "submit" === o ||
+ "button" === o ||
+ "image" === o ||
+ (this._isTextField(e) && !this._isSecureTextField(e));
+ }
+ isSearchForm(e, t) {
+ if ("get" !== e.method) return !1;
+ for (
+ var r = elementsInFormPiercingShadowDOM(e), o = r.length, n = 0;
+ n < o;
+ ++n
+ )
+ if (!this._isInputAllowedInSearchForm(r[n], t)) return !1;
+ return !0;
+ }
+ _textAreaElementLookLikeItIsPartOfASearchForm(e) {
+ return (
+ !!this._isTextArea(e) &&
+ ("search" === e.getAttribute("type") ||
+ "search" === e.inputMode ||
+ "search" === e.getAttribute("enterkeyhint"))
+ );
+ }
+ _isSubmitButton(e) {
+ return (
+ (e instanceof HTMLButtonElement || e instanceof HTMLInputElement) &&
+ e.type &&
+ "submit" === e.type
+ );
+ }
+ _isCustomFormButton(e) {
+ return (
+ "button" === e.type &&
+ (e instanceof HTMLButtonElement || e instanceof HTMLInputElement)
+ );
+ }
+ _isCheckboxInputElement(e) {
+ return "checkbox" === e.type && e instanceof HTMLInputElement;
+ }
+ _collectExtraControlMetadata(e, t) {
+ const r = e.getAttribute("passwordrules");
+ if (r) return void (t.ControlPasswordRules = r);
+ const o = e.pattern;
+ if (o && "undefined" != typeof PatternRegexpToPasswordRulesConverter) {
+ const e = PatternRegexpToPasswordRulesConverter.convert(o);
+ e && (t.ControlPasswordRules = e);
+ }
+ }
+ removeAutomaticStrongPasswordFromPasswordElement(e) {
+ let t = this.formControlWithUniqueID(e);
+ t &&
+ this._isTextField(t) &&
+ (this.clearField(e),
+ this._updateAnnotationsForField(t),
+ FormMetadataJSController.setInputElementAutofilled(t, !1));
+ }
+}
+var FormMetadataJS = new FormMetadata();
+0;
diff --git a/27.0/js/forms/FormMetadataClassification.js b/27.0/js/forms/FormMetadataClassification.js
new file mode 100644
index 0000000..dc413c3
--- /dev/null
+++ b/27.0/js/forms/FormMetadataClassification.js
@@ -0,0 +1,923 @@
+//# sourceURL=__InjectedScript_FormMetadataClassification.js
+/* Copyright (c) 2026 Apple Inc. All rights reserved. */
+"use strict";
+function datePlaceholderParser(e) {
+ const t = [];
+ for (const o of e)
+ "d" !== o || t.includes("day")
+ ? "M" !== o || t.includes("month")
+ ? "y" !== o || t.includes("year") || t.push("year")
+ : t.push("month")
+ : t.push("day");
+ return e.includes("d")
+ ? e.includes("yyyy")
+ ? {
+ format: { year: "numeric", month: "2-digit", day: "2-digit" },
+ order: t,
+ }
+ : {
+ format: { year: "2-digit", month: "2-digit", day: "2-digit" },
+ order: t,
+ }
+ : e.includes("M")
+ ? e.includes("yyyy")
+ ? { format: { year: "numeric", month: "2-digit" }, order: t }
+ : { format: { year: "2-digit", month: "2-digit" }, order: t }
+ : e.includes("y")
+ ? e.includes("yyyy")
+ ? { format: { year: "numeric" }, order: t }
+ : { format: { year: "2-digit" }, order: t }
+ : null;
+}
+function referenceDateToDateFormat(e) {
+ let t = e.replace("12", "MM");
+ return (
+ (t = t.replace("30", "dd")),
+ (t = t.replace("1999", "y")),
+ (t = t.replace("99", "yy")),
+ t
+ );
+}
+function referenceDatePartsToOrderedDateFormat(e, t) {
+ const o = {};
+ let r = "";
+ for (const t of e)
+ switch (t.type) {
+ case "day":
+ o.day = "dd";
+ break;
+ case "month":
+ o.month = "MM";
+ break;
+ case "year":
+ o.year = "1999" === t.value ? "yyyy" : "yy";
+ break;
+ case "literal":
+ r = t.value;
+ }
+ let n = "";
+ for (const [e, i] of t.entries())
+ (o[i] && (n += o[i]), e < t.length - 1 && r && (n += r));
+ return n;
+}
+const WBSABAddressProperty = "Address",
+ WBSABPhoneProperty = "Phone",
+ _WBSABAddressZIPKey = "ZIP",
+ WBSFormControlMetadataDefaultMaxLength = 524288,
+ WBSIgnoredClassificationToken = "-sf-ignored",
+ WBSDateDayOrderedPartToken = "-sf-day",
+ WBSDateMonthOrderedPartToken = "-sf-month",
+ WBSDateYearOrderedPartToken = "-sf-year",
+ WBSGivenNameOrderedPartToken = "given-name",
+ WBSAdditionalNameOrderedPartToken = "additional-name",
+ WBSFamilyNameOrderedPartToken = "family-name",
+ WBSLocaleForCreditCardExpirationDate = "en-US-POSIX",
+ WBSCreditCardTypeClassificationToken = "cc-type",
+ WBSCreditCardHolderNameClassificationToken = "cc-name",
+ WBSCreditCardNumberClassificationToken = "cc-number",
+ WBSCreditCardExpirationClassificationToken = "cc-exp",
+ WBSCreditCardSecurityCodeClassificationToken = "cc-csc",
+ WBSCreditCardHolderNameClassificationDefaultOrderedParts = [
+ WBSGivenNameOrderedPartToken,
+ WBSAdditionalNameOrderedPartToken,
+ WBSFamilyNameOrderedPartToken,
+ ],
+ WBSCreditCardExpirationClassificationDefaultOrderedParts = [
+ WBSDateMonthOrderedPartToken,
+ WBSDateYearOrderedPartToken,
+ ],
+ WBSCredentialUsernameClassificationToken = "username",
+ WBSCredentialCurrentPasswordClassificationToken = "current-password",
+ WBSCredentialNewPasswordClassificationToken = "new-password",
+ WBSContactNameClassificationToken = "name",
+ WBSContactNameClassificationDefaultOrderedParts = [
+ WBSGivenNameOrderedPartToken,
+ WBSAdditionalNameOrderedPartToken,
+ WBSFamilyNameOrderedPartToken,
+ ],
+ WBSNameOrderedPartTokensSet = new Set(
+ WBSContactNameClassificationDefaultOrderedParts,
+ ),
+ WBSContactInstantMessageClassificationToken = "-sf-instant-message",
+ WBSContactPostalCodeClassificationToken = "postal-code",
+ WBSContactStreetAddressClassificationToken = "street-address",
+ WBSContactStreetAddressLine1OrderedPartToken = "address-line1",
+ WBSContactStreetAddressLine2OrderedPartToken = "address-line2",
+ WBSContactStreetAddressLine3OrderedPartToken = "address-line3",
+ WBSContactTelephoneClassificationToken = "tel",
+ WBSTelephoneCountryCodeOrderedPartToken = "tel-country-code",
+ WBSTelephoneAreaCodeOrderedPartToken = "tel-area-code",
+ WBSTelephoneLocalPrefixOrderedPartToken = "tel-local-prefix",
+ WBSTelephoneLocalSuffixOrderedPartToken = "tel-local-suffix",
+ WBSTelephoneExtensionOrderedPartToken = "tel-extension",
+ WBSTelephoneDefaultOrderedParts = [
+ WBSTelephoneCountryCodeOrderedPartToken,
+ WBSTelephoneAreaCodeOrderedPartToken,
+ WBSTelephoneLocalPrefixOrderedPartToken,
+ WBSTelephoneLocalSuffixOrderedPartToken,
+ WBSTelephoneExtensionOrderedPartToken,
+ ],
+ WBSContactBirthdayClassificationToken = "bday",
+ WBSContactEmailClassificationToken = "email",
+ WBSDeviceEIDClassificationToken = "device-eid",
+ WBSDeviceIMEIClassificationToken = "device-imei",
+ WBSDeviceIMEI1ClassificationToken = "device-imei1",
+ WBSDeviceIMEI2ClassificationToken = "device-imei2",
+ WBSDeviceNALClassificationToken = "device-nal",
+ AllowedControlTagsForStandaloneCreditCardCompositeExpirationControl = new Set(
+ ["input", "select", "textarea"],
+ );
+class JSFieldLabelPatternMatcher {
+ constructor(e, t) {
+ ((this.dfa = e),
+ (this.characters = t.toLowerCase()),
+ (this.allowEndOfWordMatch = e.charCodeAt(1)));
+ const o = e.charCodeAt(0),
+ r = 2,
+ n = 2;
+ this.transitionsBegin = r + n * o;
+ }
+ static transitionsEndMatchSentinel = 0;
+ longestMatch() {
+ let e,
+ t = 0;
+ const o = this.characters.length;
+ let r = this.search(t, o, o);
+ for (; r.length;) {
+ for (const o of r)
+ ((!e || o.end - o.begin > e.end - e.begin) && (e = o),
+ (t = o.begin + 1));
+ r = this.search(t, o, o);
+ }
+ if (e) return [e.identifier, this.characters.substring(e.begin, e.end)];
+ }
+ searchReverse() {
+ let e = 0;
+ const t = this.characters.length;
+ let o,
+ r = this.search(e, t, t);
+ for (; r.length;) {
+ for (const t of r) ((!o || t.end > o.end) && (o = t), (e = t.begin + 1));
+ r = this.search(e, t, t);
+ }
+ if (o) return [o.identifier, this.characters.substring(o.begin, o.end)];
+ }
+ exactMatch() {
+ const e = this.characters.length,
+ t = this.search(0, e, 1);
+ for (const o of t) if (0 == o.begin && o.end == e) return o.identifier;
+ }
+ static isWordCharacter(e) {
+ return (
+ (e >= 97 && e <= 122) ||
+ (e >= 65 && e <= 90) ||
+ (e >= 48 && e <= 57) ||
+ 95 == e
+ );
+ }
+ isWordBoundary(e) {
+ return (
+ !!this.characters.length &&
+ (0 === e
+ ? JSFieldLabelPatternMatcher.isWordCharacter(
+ this.characters.charCodeAt(0),
+ )
+ : e === this.characters.length
+ ? JSFieldLabelPatternMatcher.isWordCharacter(
+ this.characters.charCodeAt(e - 1),
+ )
+ : JSFieldLabelPatternMatcher.isWordCharacter(
+ this.characters.charCodeAt(e - 1),
+ ) !=
+ JSFieldLabelPatternMatcher.isWordCharacter(
+ this.characters.charCodeAt(e),
+ ))
+ );
+ }
+ passesWordBoundaryCheck(e, t) {
+ return (
+ !(
+ !this.allowEndOfWordMatch &&
+ JSFieldLabelPatternMatcher.isWordCharacter(
+ this.characters.charCodeAt(e),
+ ) &&
+ !this.isWordBoundary(e)
+ ) &&
+ (!JSFieldLabelPatternMatcher.isWordCharacter(
+ this.characters.charCodeAt(t),
+ ) ||
+ this.isWordBoundary(t + 1))
+ );
+ }
+ search(e, t, o) {
+ let r = [];
+ for (var n = e; n < o; n++) {
+ let e = 0;
+ for (
+ var i = this.stateTransitionBegin(e),
+ a = this.stateTransitionEnd(e),
+ s = n;
+ s < t;
+ s++
+ ) {
+ ((i = this.stateTransitionBegin(e)), (a = this.stateTransitionEnd(e)));
+ const t = this.characters.charCodeAt(s);
+ let o = !1;
+ for (var d = i, l = a - 1; d <= l;) {
+ const r = ((d + l) / 2) | 0,
+ n = this.transitionCharacter(r);
+ if (n == t) {
+ ((e = this.transitionStateIndex(r)),
+ (i = this.stateTransitionBegin(e)),
+ (a = this.stateTransitionEnd(e)),
+ (o = !0));
+ break;
+ }
+ n > t ? (l = r - 1) : (d = r + 1);
+ }
+ if (!o) break;
+ for (; a == JSFieldLabelPatternMatcher.transitionsEndMatchSentinel;)
+ (this.passesWordBoundaryCheck(n, s) &&
+ r.push({ identifier: i, begin: n, end: s + 1 }),
+ e++,
+ (i = this.stateTransitionBegin(e)),
+ (a = this.stateTransitionEnd(e)));
+ }
+ }
+ return r;
+ }
+ stateTransitionBegin(e) {
+ const t = 2,
+ o = 2;
+ return this.dfa.charCodeAt(t + o * e);
+ }
+ stateTransitionEnd(e) {
+ const t = 2,
+ o = 2;
+ return this.dfa.charCodeAt(t + o * e + 1);
+ }
+ transitionCharacter(e) {
+ const t = 2;
+ return this.dfa.charCodeAt(this.transitionsBegin + t * e);
+ }
+ transitionStateIndex(e) {
+ const t = 2;
+ return this.dfa.charCodeAt(this.transitionsBegin + t * e + 1);
+ }
+}
+class FormMetadataClassification {
+ #e(e) {
+ return null != e && "object" == typeof e;
+ }
+ #t(e) {
+ return this.#e(e) && "string" == typeof e.ControlTagName;
+ }
+ #o(e) {
+ return this.#e(e) && "string" == typeof e.property;
+ }
+ fieldLooksLikeDateField(e) {
+ return !!(
+ e.ControlLooksLikeDayField ||
+ e.ControlLooksLikeMonthField ||
+ e.ControlLooksLikeYearField
+ );
+ }
+ #r(e) {
+ let t = e.ControlMaxLength;
+ return (
+ (void 0 === t || t < 0 || t > WBSFormControlMetadataDefaultMaxLength) &&
+ (t = WBSFormControlMetadataDefaultMaxLength),
+ t
+ );
+ }
+ fieldLooksLikeItExpectsDataOfSize(e, t) {
+ return (e.ControlSize ?? 0) <= t || this.#r(e) <= t;
+ }
+ fieldCouldBeCreditCardNumberContinuation(e, t) {
+ const o = 4;
+ if (t.length >= o) return !1;
+ if (!t[0]?.ControlLooksLikeCreditCardNumberField) return !1;
+ const r = 2;
+ if (e.ControlMaxLength === r) return !1;
+ if (e.ControlLooksLikeCreditCardNumberField) return !0;
+ if (e.ControlLooksLikeCreditCardSecurityCodeField) return !1;
+ if (e.ControlLooksLikeCreditCardCompositeExpirationDateField) return !1;
+ const n = 6;
+ if (!this.fieldLooksLikeItExpectsDataOfSize(e, n)) return !1;
+ const i = t.at(-1);
+ return !(i && !this.fieldLooksLikeItExpectsDataOfSize(i, n));
+ }
+ labelsCouldRepresentContinuation(e, t, o, r) {
+ return (
+ !(!e || !o) &&
+ (e === o ||
+ (!!t &&
+ (!r ||
+ (t.property === r.property &&
+ (!r.component || t.component === r.component)))))
+ );
+ }
+ #n(e) {
+ const t = [
+ WBSContactStreetAddressLine1OrderedPartToken,
+ WBSContactStreetAddressLine2OrderedPartToken,
+ WBSContactStreetAddressLine3OrderedPartToken,
+ ],
+ o = [
+ WBSContactStreetAddressLine2OrderedPartToken,
+ WBSContactStreetAddressLine3OrderedPartToken,
+ ];
+ if (e.AutocompleteTokens)
+ for (let o of e.AutocompleteTokens)
+ switch (o) {
+ case "street-address":
+ return t;
+ case "address-line1":
+ return [WBSContactStreetAddressLine1OrderedPartToken];
+ case "address-line2":
+ case "address-level2":
+ return [WBSContactStreetAddressLine2OrderedPartToken];
+ case "address-line3":
+ case "address-level1":
+ return [WBSContactStreetAddressLine3OrderedPartToken];
+ }
+ let r = e.ControlFieldName,
+ n = r?.indexOf("1") ?? -1,
+ i = r?.indexOf("2") ?? -1;
+ return -1 === n
+ ? -1 === i
+ ? t
+ : o
+ : -1 === i || n < i
+ ? [WBSContactStreetAddressLine1OrderedPartToken]
+ : o;
+ }
+ fieldCouldBePhoneNumberContinuation(e, t) {
+ const o = 5;
+ if (t.length >= o) return !1;
+ if (t[0]?.AddressBookValueSpecifier?.property !== WBSABPhoneProperty)
+ return !1;
+ const r = 5;
+ return !!this.fieldLooksLikeItExpectsDataOfSize(e, r);
+ }
+ fieldCouldBePostCodeContinuation(e, t) {
+ const o = 3;
+ if (t.length >= o) return !1;
+ if (t[0]?.AddressBookValueSpecifier?.component != _WBSABAddressZIPKey)
+ return !1;
+ const r = 6;
+ return !!this.fieldLooksLikeItExpectsDataOfSize(e, r);
+ }
+ fieldLooksLikeSameDataType(e, t) {
+ const o = t.at(-1);
+ return (
+ !!this.labelsCouldRepresentContinuation(
+ o?.AddressBookLabel,
+ o?.AddressBookValueSpecifier,
+ e?.AddressBookLabel,
+ e?.AddressBookValueSpecifier,
+ ) ||
+ !!(
+ o &&
+ this.fieldLooksLikeDateField(o) &&
+ this.fieldLooksLikeDateField(e)
+ ) ||
+ !!this.fieldCouldBePhoneNumberContinuation(e, t) ||
+ !!this.fieldCouldBePostCodeContinuation(e, t) ||
+ !!this.fieldCouldBeCreditCardNumberContinuation(e, t)
+ );
+ }
+ #i(e) {
+ if (
+ (globalThis.DOMRect ||
+ (globalThis.DOMRect = class {
+ constructor(e, t, o, r) {
+ ((this.left = e),
+ (this.right = e + o),
+ (this.top = t),
+ (this.bottom = t + r),
+ (this.width = o),
+ (this.height = r));
+ }
+ }),
+ e.ControlRectLeft ||
+ e.ControlRectTop ||
+ e.ControlRectWidth ||
+ e.ControlRectHeight)
+ )
+ return new DOMRect(
+ e.ControlRectLeft,
+ e.ControlRectTop,
+ e.ControlRectWidth,
+ e.ControlRectHeight,
+ );
+ let t = globalThis.FormMetadataJS?.formControlWithUniqueID(
+ e.ControlUniqueID,
+ );
+ return t ? t.getBoundingClientRect() : new DOMRect(0, 0, 0, 0);
+ }
+ fieldLooksLikeContinuation(e, t, o) {
+ if (!e.ControlIsTextField && "SELECT" !== e.ControlTagName.toUpperCase())
+ return !1;
+ if (!this.fieldLooksLikeSameDataType(e, t)) return !1;
+ if (o) return !0;
+ const r = this.#i(t.at(-1)),
+ n = this.#i(e);
+ if (Math.abs(r.top - n.top) > 3) return !1;
+ let i, a;
+ return (
+ r.left < n.left ? ((i = r), (a = n)) : ((i = n), (a = r)),
+ !(a.left - i.right > 60)
+ );
+ }
+ continuingFieldsInFormControls(e, t, o, r) {
+ const n = [e[t]];
+ for (let i = t + 1; i < e.length; ++i) {
+ const t = e[i];
+ if (o && !t.ControlIsTextField) break;
+ if (!this.fieldLooksLikeContinuation(t, n, r)) break;
+ n.push(t);
+ }
+ return n;
+ }
+ classifyControlsRelatedToNameParts(e, t, o) {
+ const r = e[t];
+ ((r.ControlClassification = o),
+ (r.ControlOrderedParts = [r.AddressBookValueSpecifier?.classification]));
+ const n = new Set([r.AddressBookValueSpecifier?.classification]),
+ i = [e[t]];
+ for (let r = t + 1; r < e.length; ++r) {
+ const t = e[r];
+ if (!t.ControlIsTextField) break;
+ const a = t.AddressBookValueSpecifier?.classification;
+ if (!a) break;
+ if (!WBSNameOrderedPartTokensSet.has(a) || n.has(a)) break;
+ ((t.ControlClassification = o),
+ (t.ControlOrderedParts = [a]),
+ n.add(a),
+ i.push(t));
+ }
+ return i;
+ }
+ identifyDateFields(e) {
+ let t,
+ o,
+ r,
+ n = !1;
+ for (let i of e)
+ if (i.ControlLooksLikeDayField) {
+ if (t) return [!1, null, null, null];
+ ((t = i), (n = !0));
+ } else if (i.ControlLooksLikeMonthField) {
+ if (o) return [!1, null, null, null];
+ ((o = i), (n = !0));
+ } else if (i.ControlLooksLikeYearField) {
+ if (r) return [!1, null, null, null];
+ ((r = i), (n = !0));
+ }
+ return [n, r, o, t];
+ }
+ canonicalizedDateTemplate(e) {
+ if (!e) return;
+ if (!(e = e.replace(/\s/g, "")).length) return;
+ const t = [
+ {
+ dateFormatCharactersRegex: /^[dmy\/.-]*$/i,
+ dayRegex: /D/g,
+ monthRegex: /m/g,
+ yearRegex: /Y/g,
+ },
+ {
+ dateFormatCharactersRegex: /^[jma\/.-]*$/i,
+ dayRegex: /j/gi,
+ monthRegex: /m/g,
+ yearRegex: /a/gi,
+ },
+ {
+ dateFormatCharactersRegex: /^[dma\/.-]*$/i,
+ dayRegex: /D/g,
+ monthRegex: /m/g,
+ yearRegex: /a/gi,
+ },
+ {
+ dateFormatCharactersRegex: /^[tmj\/.-]*$/i,
+ dayRegex: /t/gi,
+ monthRegex: /m/g,
+ yearRegex: /j/gi,
+ },
+ {
+ dateFormatCharactersRegex: /^[gma\/.-]*$/i,
+ dayRegex: /g/gi,
+ monthRegex: /m/g,
+ yearRegex: /a/gi,
+ },
+ ];
+ for (const {
+ dateFormatCharactersRegex: o,
+ dayRegex: r,
+ monthRegex: n,
+ yearRegex: i,
+ } of t)
+ if (o.test(e))
+ return (e = (e = (e = e.replace(r, "d")).replace(n, "M")).replace(
+ i,
+ "y",
+ ));
+ }
+ classifyDateFields(e, t, o, r, n, i, a) {
+ if (e.length > 3) return !1;
+ if ((a || (a = navigator.language), 1 === e.length)) {
+ if (!e[0].ControlIsTextField) return !1;
+ let i = e[0].ControlRequiredFormatForDateTimeInput;
+ if (!i) {
+ const t = new Date(1999, 11, 30);
+ let o = this.#r(e[0]),
+ r = this.canonicalizedDateTemplate(e[0].ControlPlaceholder),
+ s = "";
+ if (r?.length) {
+ const e = datePlaceholderParser(r);
+ if (e) {
+ const o = new Intl.DateTimeFormat(a, e.format);
+ s = o.format(t);
+ i = referenceDatePartsToOrderedDateFormat(
+ o.formatToParts(t),
+ e.order,
+ );
+ }
+ }
+ if (!s || s.length > o) {
+ const e = n
+ ? [
+ { year: "numeric", month: "2-digit", day: "2-digit" },
+ { year: "2-digit", month: "2-digit", day: "2-digit" },
+ ]
+ : [{ year: "2-digit", month: "2-digit" }];
+ for (const r of e)
+ if (
+ ((s = new Intl.DateTimeFormat(a, r).format(t)),
+ (i = referenceDateToDateFormat(s)),
+ s.length <= o)
+ )
+ break;
+ }
+ if (s.length > o) return !1;
+ }
+ const s = [];
+ for (const e of i) {
+ let t;
+ ("y" === e ? (t = o) : "M" === e ? (t = r) : "d" === e && (t = n),
+ t && !s.includes(t) && s.push(t));
+ }
+ return (
+ (e[0].ControlClassification = t),
+ (e[0].ControlOrderedParts = s),
+ (e[0].ControlRequiredFormatForDateTimeInput = i),
+ !0
+ );
+ }
+ let [s, d, l, c] = this.identifyDateFields(e);
+ if (!s) return !1;
+ if (c && !l) return !1;
+ let C = 0;
+ for (const a of e)
+ ((a.ControlClassification = t),
+ (a.ControlContinuationID = i),
+ (a.ControlContinuationIndex = C++),
+ a === c
+ ? (a.ControlOrderedParts = [n])
+ : a === l
+ ? (a.ControlOrderedParts = [r])
+ : a === d && (a.ControlOrderedParts = [o]));
+ return !0;
+ }
+ static specifierForAutocompleteTokensAndAddressBookLabel(e, t) {
+ if (e) {
+ if (!Array.isArray(e))
+ throw new Error("Expected an array of autocomplete tokens");
+ for (let t of e) {
+ const e = new JSFieldLabelPatternMatcher(
+ FormMetadataJSController.autocompleteTokenMapDFA(),
+ t,
+ ).exactMatch();
+ if (void 0 !== e) return FormMetadataJSController.getValueSpecifiers(e);
+ }
+ }
+ if (t) {
+ const e = new JSFieldLabelPatternMatcher(
+ FormMetadataJSController.fieldLabelMapDFA(),
+ t,
+ ).exactMatch();
+ if (void 0 !== e) return FormMetadataJSController.getValueSpecifiers(e);
+ }
+ return null;
+ }
+ classify(e) {
+ const t = e.FormControls,
+ o = t.length,
+ r = e.AutoFillFormType === WBSAutoFillFormTypeNewAccount,
+ n = e.AutoFillFormType === WBSAutoFillFormTypeChangePassword,
+ i = e.UsernameElementUniqueID,
+ a = e.PasswordElementUniqueID,
+ s = e.OldPasswordElementUniqueID,
+ d = e.ConfirmPasswordElementUniqueID;
+ for (let e of t)
+ (e.AutocompleteTokens || e.AddressBookLabel) &&
+ (e.AddressBookValueSpecifier =
+ FormMetadataClassification.specifierForAutocompleteTokensAndAddressBookLabel(
+ e.AutocompleteTokens,
+ e.AddressBookLabel,
+ ));
+ let l = !1,
+ c = !1,
+ C = !1,
+ f = !1,
+ h = !1,
+ u = 0;
+ for (let k = 0, S = 1; k < o; k += S, S = 1) {
+ const o = t[k];
+ if (o.ControlLooksLikeIgnoredDataTypeField) {
+ o.ControlClassification = WBSIgnoredClassificationToken;
+ continue;
+ }
+ const T = o.ControlUniqueID;
+ if (T === a || T === d) {
+ o.ControlClassification =
+ r || n
+ ? WBSCredentialNewPasswordClassificationToken
+ : WBSCredentialCurrentPasswordClassificationToken;
+ continue;
+ }
+ if (T === s) {
+ o.ControlClassification =
+ WBSCredentialCurrentPasswordClassificationToken;
+ continue;
+ }
+ const B = o.AddressBookValueSpecifier?.classification;
+ if (B === WBSContactEmailClassificationToken) {
+ o.ControlClassification = WBSContactEmailClassificationToken;
+ continue;
+ }
+ if (T === i) {
+ o.ControlClassification = WBSCredentialUsernameClassificationToken;
+ continue;
+ }
+ if (!c && o.ControlLooksLikeCreditCardCardholderField) {
+ if (((c = !0), B && WBSNameOrderedPartTokensSet.has(B))) {
+ const e = this.classifyControlsRelatedToNameParts(
+ t,
+ k,
+ WBSCreditCardHolderNameClassificationToken,
+ );
+ if (e.length > 1) {
+ let t = ++u,
+ o = 0;
+ for (let r of e)
+ ((r.ControlContinuationID = t),
+ (r.ControlContinuationIndex = o++));
+ }
+ S = e.length;
+ continue;
+ }
+ ((o.ControlClassification = WBSCreditCardHolderNameClassificationToken),
+ (o.ControlOrderedParts =
+ WBSCreditCardHolderNameClassificationDefaultOrderedParts));
+ continue;
+ }
+ if (!l && o.ControlLooksLikeCreditCardNumberField) {
+ l = !0;
+ const e = this.continuingFieldsInFormControls(t, k, !0, !1);
+ let o = 0,
+ r = e.length > 1 ? ++u : 0;
+ for (let t of e)
+ ((t.ControlClassification = WBSCreditCardNumberClassificationToken),
+ (t.ControlContinuationID = r),
+ (t.ControlContinuationIndex = o++));
+ S = e.length;
+ continue;
+ }
+ const g =
+ this.fieldLooksLikeDateField(o) ||
+ o.ControlLooksLikeCreditCardCompositeExpirationDateField;
+ if (!C && g) {
+ let e = f || c || l;
+ if (
+ ((e ||=
+ !o.ControlLooksLikeOneTimeCodeField &&
+ 1 ===
+ t.filter((e) =>
+ AllowedControlTagsForStandaloneCreditCardCompositeExpirationControl.has(
+ e.ControlTagName.toLowerCase(),
+ ),
+ ).length),
+ e)
+ ) {
+ C = !0;
+ const e = this.continuingFieldsInFormControls(t, k, !1, !0);
+ let o = e.length > 1 ? ++u : 0;
+ (this.classifyDateFields(
+ e,
+ WBSCreditCardExpirationClassificationToken,
+ WBSDateYearOrderedPartToken,
+ WBSDateMonthOrderedPartToken,
+ void 0,
+ o,
+ WBSLocaleForCreditCardExpirationDate,
+ ),
+ (S = e.length));
+ continue;
+ }
+ }
+ if (h || !o.ControlLooksLikeCreditCardSecurityCodeField)
+ if (f || !o.ControlLooksLikeCreditCardTypeField)
+ if (B) {
+ const r = o.AddressBookValueSpecifier.classificationHint;
+ if (B === WBSContactNameClassificationToken) {
+ ((o.ControlClassification = B),
+ (o.ControlOrderedParts =
+ WBSContactNameClassificationDefaultOrderedParts));
+ continue;
+ }
+ if (WBSNameOrderedPartTokensSet.has(B)) {
+ const e = this.classifyControlsRelatedToNameParts(
+ t,
+ k,
+ WBSContactNameClassificationToken,
+ );
+ if (e.length > 1) {
+ let t = ++u,
+ o = 0;
+ for (let r of e)
+ ((r.ControlContinuationID = t),
+ (r.ControlContinuationIndex = o++));
+ }
+ S = e.length;
+ continue;
+ }
+ if (B === WBSContactPostalCodeClassificationToken) {
+ const e = this.continuingFieldsInFormControls(t, k, !0, !1);
+ let o = e.length > 1 ? ++u : 0,
+ r = 0;
+ for (let t of e)
+ ((t.ControlClassification =
+ WBSContactPostalCodeClassificationToken),
+ (t.ControlContinuationID = o),
+ (t.ControlContinuationIndex = r++));
+ S = e.length;
+ continue;
+ }
+ if (B === WBSContactStreetAddressClassificationToken) {
+ const e = this.continuingFieldsInFormControls(t, k, !0, !0);
+ let o = e.length > 1 ? ++u : 0,
+ r = 0;
+ for (let t of e)
+ ((t.ControlClassification =
+ WBSContactStreetAddressClassificationToken),
+ (t.ControlContinuationID = o),
+ (t.ControlContinuationIndex = r++));
+ if (1 === e.length) {
+ let t = e[0];
+ t.ControlOrderedParts = this.#n(t);
+ } else
+ 2 === e.length
+ ? ((e[0].ControlOrderedParts = [
+ WBSContactStreetAddressLine1OrderedPartToken,
+ ]),
+ (e[1].ControlOrderedParts = [
+ WBSContactStreetAddressLine2OrderedPartToken,
+ WBSContactStreetAddressLine3OrderedPartToken,
+ ]))
+ : e.length >= 3 &&
+ ((e[0].ControlOrderedParts = [
+ WBSContactStreetAddressLine1OrderedPartToken,
+ ]),
+ (e[1].ControlOrderedParts = [
+ WBSContactStreetAddressLine2OrderedPartToken,
+ ]),
+ (e[2].ControlOrderedParts = [
+ WBSContactStreetAddressLine3OrderedPartToken,
+ ]));
+ S = e.length;
+ continue;
+ }
+ if (B === WBSContactInstantMessageClassificationToken) {
+ const e = this.continuingFieldsInFormControls(t, k, !0, !0);
+ (1 === e.length &&
+ ((e[0].ControlClassification =
+ WBSContactInstantMessageClassificationToken),
+ r && (e[0].ControlClassificationHints = [r])),
+ (S = e.length));
+ continue;
+ }
+ if (B.startsWith(WBSContactTelephoneClassificationToken)) {
+ const e = this.continuingFieldsInFormControls(t, k, !0, !1);
+ if (1 == e.length) {
+ ((e[0].ControlClassification =
+ WBSContactTelephoneClassificationToken),
+ (e[0].ControlOrderedParts = WBSTelephoneDefaultOrderedParts),
+ r && (e[0].ControlClassificationHints = [r]));
+ continue;
+ }
+ let o = ++u,
+ n = 0;
+ for (let t of e)
+ ((t.ControlClassification =
+ WBSContactTelephoneClassificationToken),
+ (t.ControlContinuationID = o),
+ (t.ControlContinuationIndex = n++),
+ r && (t.ControlClassificationHints = [r]));
+ (2 === e.length
+ ? ((e[0].ControlOrderedParts = [
+ WBSTelephoneAreaCodeOrderedPartToken,
+ ]),
+ (e[1].ControlOrderedParts = [
+ WBSTelephoneLocalPrefixOrderedPartToken,
+ WBSTelephoneLocalSuffixOrderedPartToken,
+ ]))
+ : 3 === e.length
+ ? ((e[0].ControlOrderedParts = [
+ WBSTelephoneAreaCodeOrderedPartToken,
+ ]),
+ (e[1].ControlOrderedParts = [
+ WBSTelephoneLocalPrefixOrderedPartToken,
+ ]),
+ (e[2].ControlOrderedParts = [
+ WBSTelephoneLocalSuffixOrderedPartToken,
+ ]))
+ : 4 === e.length
+ ? ((e[0].ControlOrderedParts = [
+ WBSTelephoneCountryCodeOrderedPartToken,
+ ]),
+ (e[1].ControlOrderedParts = [
+ WBSTelephoneAreaCodeOrderedPartToken,
+ ]),
+ (e[2].ControlOrderedParts = [
+ WBSTelephoneLocalPrefixOrderedPartToken,
+ ]),
+ (e[3].ControlOrderedParts = [
+ WBSTelephoneLocalSuffixOrderedPartToken,
+ ]))
+ : ((e[0].ControlOrderedParts = [
+ WBSTelephoneCountryCodeOrderedPartToken,
+ ]),
+ (e[1].ControlOrderedParts = [
+ WBSTelephoneAreaCodeOrderedPartToken,
+ ]),
+ (e[2].ControlOrderedParts = [
+ WBSTelephoneLocalPrefixOrderedPartToken,
+ ]),
+ (e[3].ControlOrderedParts = [
+ WBSTelephoneLocalSuffixOrderedPartToken,
+ ]),
+ (e[4].ControlOrderedParts = [
+ WBSTelephoneExtensionOrderedPartToken,
+ ])),
+ (S = e.length));
+ continue;
+ }
+ if (B === WBSContactBirthdayClassificationToken) {
+ const o = this.continuingFieldsInFormControls(t, k, !1, !1),
+ r = o.length > 1 ? ++u : void 0,
+ n =
+ e.RequestType === WBSFormMetadataRequestTesting
+ ? "en-US"
+ : void 0;
+ (this.classifyDateFields(
+ o,
+ WBSContactBirthdayClassificationToken,
+ WBSDateYearOrderedPartToken,
+ WBSDateMonthOrderedPartToken,
+ WBSDateDayOrderedPartToken,
+ r,
+ n,
+ ),
+ (S = o.length));
+ continue;
+ }
+ o.ControlClassification = B;
+ } else
+ o.ControlLooksLikeEIDField
+ ? (o.ControlClassification = WBSDeviceEIDClassificationToken)
+ : o.ControlLooksLikeIMEIField
+ ? (o.ControlClassification = WBSDeviceIMEIClassificationToken)
+ : o.ControlLooksLikeIMEI1Field
+ ? (o.ControlClassification =
+ WBSDeviceIMEI1ClassificationToken)
+ : o.ControlLooksLikeIMEI2Field
+ ? (o.ControlClassification =
+ WBSDeviceIMEI2ClassificationToken)
+ : o.ControlLooksLikeNALField &&
+ (o.ControlClassification =
+ WBSDeviceNALClassificationToken);
+ else
+ ((f = !0),
+ (o.ControlClassification = WBSCreditCardTypeClassificationToken));
+ else
+ ((h = !0),
+ (o.ControlClassification =
+ WBSCreditCardSecurityCodeClassificationToken));
+ }
+ return e;
+ }
+}
+globalThis.FormMetadataClassificationJS = new FormMetadataClassification();
+0;
diff --git a/27.0/js/forms/FormMetadataContactsAutoFillMappings.js b/27.0/js/forms/FormMetadataContactsAutoFillMappings.js
new file mode 100644
index 0000000..05d4fd8
--- /dev/null
+++ b/27.0/js/forms/FormMetadataContactsAutoFillMappings.js
@@ -0,0 +1,309 @@
+//# sourceURL=__InjectedScript_FormMetadataContactsAutoFillMappings.js
+/* Copyright (c) 2026 Apple Inc. All rights reserved. */
+// Copyright (C) 2018-2025 Apple Inc. All rights reserved.
+function newAddressBookFieldLabelPatternMatchers() {
+ return [
+ new FormMetadataFieldPatternMatcher(
+ window.webkit.buffers.addressBookFieldLabelPatternMatchers0,
+ ),
+ new FormMetadataFieldPatternMatcher(
+ window.webkit.buffers.addressBookFieldLabelPatternMatchers1,
+ ),
+ new FormMetadataFieldPatternMatcher(
+ window.webkit.buffers.addressBookFieldLabelPatternMatchers2,
+ ),
+ new FormMetadataFieldPatternMatcher(
+ window.webkit.buffers.addressBookFieldLabelPatternMatchers3,
+ ),
+ ];
+}
+function newEmailFieldLabelPatternMatchers() {
+ return [
+ new FormMetadataFieldPatternMatcher(
+ window.webkit.buffers.emailFieldLabelPatternMatchers,
+ ),
+ ];
+}
+class ValueSpecifier {
+ constructor(e, n, l, a, t, s, r) {
+ ((this.property = e),
+ (this.component = n),
+ (this.label = l),
+ (this.category = a),
+ (this.parentProperty = t),
+ (this.classification = s),
+ (this.classificationHint = r));
+ }
+}
+var valueSpecifiers = [
+ new ValueSpecifier(
+ "FullNameComposite",
+ null,
+ null,
+ "FullNameComposite",
+ null,
+ "name",
+ null,
+ ),
+ new ValueSpecifier(
+ "First",
+ null,
+ null,
+ "First",
+ "FullNameComposite",
+ "given-name",
+ null,
+ ),
+ new ValueSpecifier(
+ "Middle",
+ null,
+ null,
+ "Middle",
+ "FullNameComposite",
+ "additional-name",
+ null,
+ ),
+ new ValueSpecifier(
+ "Last",
+ null,
+ null,
+ "Last",
+ "FullNameComposite",
+ "family-name",
+ null,
+ ),
+ new ValueSpecifier("Birthday", null, null, "Birthday", null, "bday", null),
+ new ValueSpecifier(
+ "JobTitle",
+ null,
+ null,
+ "JobTitle",
+ null,
+ "organization-title",
+ null,
+ ),
+ new ValueSpecifier("Email", null, null, "Email", null, "email", null),
+ new ValueSpecifier(
+ "Address",
+ "Street",
+ null,
+ "AddressStreet",
+ null,
+ "street-address",
+ null,
+ ),
+ new ValueSpecifier(
+ "Address",
+ "City",
+ null,
+ "AddressCity",
+ null,
+ "address-level2",
+ null,
+ ),
+ new ValueSpecifier(
+ "Address",
+ "State",
+ null,
+ "AddressState",
+ null,
+ "address-level1",
+ null,
+ ),
+ new ValueSpecifier(
+ "Address",
+ "ZIP",
+ null,
+ "AddressZIP",
+ null,
+ "postal-code",
+ null,
+ ),
+ new ValueSpecifier(
+ "Address",
+ "Country",
+ null,
+ "AddressCountry",
+ null,
+ "country",
+ null,
+ ),
+ new ValueSpecifier(
+ "Phone",
+ null,
+ null,
+ "Phone",
+ null,
+ "tel-area-code",
+ null,
+ ),
+ new ValueSpecifier("Phone", null, null, "Phone", null, "tel", null),
+ new ValueSpecifier(
+ "Organization",
+ null,
+ null,
+ "Organization",
+ null,
+ "organization",
+ null,
+ ),
+ new ValueSpecifier(
+ "URLs",
+ null,
+ "_$!!$_",
+ "URLs_$!!$_",
+ null,
+ "url",
+ null,
+ ),
+ new ValueSpecifier(
+ "Phone",
+ null,
+ "_$!!$_",
+ "Phone_$!!$_",
+ null,
+ "tel",
+ "home",
+ ),
+ new ValueSpecifier(
+ "Phone",
+ null,
+ "_$!!$_",
+ "Phone_$!!$_",
+ null,
+ "tel",
+ "work",
+ ),
+ new ValueSpecifier(
+ "Phone",
+ null,
+ "_$!!$_",
+ "Phone_$!!$_",
+ null,
+ "tel",
+ "mobile",
+ ),
+ new ValueSpecifier(
+ "Phone",
+ null,
+ "_$!!$_",
+ "Phone_$!!$_",
+ null,
+ "tel",
+ "pager",
+ ),
+ new ValueSpecifier("Phone", null, null, "Phone", null, "tel", "fax"),
+ new ValueSpecifier("", null, null, "", null, null, null),
+ new ValueSpecifier(
+ "InstantMessage",
+ "AIMInstant",
+ null,
+ "InstantMessageAIMInstant",
+ null,
+ "-sf-instant-message",
+ "-sf-aim",
+ ),
+ new ValueSpecifier(
+ "InstantMessage",
+ "ICQInstant",
+ null,
+ "InstantMessageICQInstant",
+ null,
+ "-sf-instant-message",
+ "-sf-icq",
+ ),
+ new ValueSpecifier(
+ "InstantMessage",
+ "JabberInstant",
+ null,
+ "InstantMessageJabberInstant",
+ null,
+ "-sf-instant-message",
+ "-sf-jabber",
+ ),
+ new ValueSpecifier(
+ "InstantMessage",
+ "MSNInstant",
+ null,
+ "InstantMessageMSNInstant",
+ null,
+ "-sf-instant-message",
+ "-sf-msn",
+ ),
+ new ValueSpecifier(
+ "InstantMessage",
+ "QQInstant",
+ null,
+ "InstantMessageQQInstant",
+ null,
+ "-sf-instant-message",
+ "-sf-qq",
+ ),
+ new ValueSpecifier(
+ "InstantMessage",
+ "SkypeInstant",
+ null,
+ "InstantMessageSkypeInstant",
+ null,
+ "-sf-instant-message",
+ "-sf-skype",
+ ),
+ ],
+ FormAutoFillKeywords = {
+ NonAutoFillableFormTypeRegularExpressions: ["[\\b-]import[\\b-]"],
+ LoginFormTypeKeywords: {
+ "@me": 1,
+ "welcome back": 1,
+ "log on": 1,
+ log_on: 1,
+ "sign on": 1,
+ login: 1,
+ signon: 1,
+ "log in": 1,
+ "sign in": 1,
+ signin: 1,
+ "forgot user": 1,
+ "enter your current password": 2,
+ "enter your password": 2,
+ reauth: 2,
+ "\u767b\u5f55": 1,
+ "\u767b\u5165": 1,
+ "iniciar sesi\xf3n": 1,
+ anmelden: 1,
+ absenden: 1,
+ connexion: 1,
+ "logg inn": 1,
+ "\u0e40\u0e02\u0e49\u0e32\u0e2a\u0e39\u0e48\u0e23\u0e30\u0e1a\u0e1a": 1,
+ },
+ NewAccountFormTypeKeywords: {
+ "set up": 1,
+ setup: 1,
+ signup: 1,
+ "sign up": 1,
+ create: 1,
+ "create account": 1,
+ "create an account": 1,
+ enrollment: 1,
+ reg: 1,
+ activate: 1,
+ "\u6ce8\u518c": 1,
+ "\u0e2a\u0e21\u0e31\u0e04\u0e23\u0e2a\u0e21\u0e32\u0e0a\u0e34\u0e01": 1,
+ },
+ ChangePasswordFormTypeKeywords: {
+ forgotpassword: 1,
+ "forgot password": 1,
+ reset: 1,
+ update: 1,
+ change: 1,
+ "\u518d\u8a2d\u5b9a": 1,
+ cambiar: 1,
+ },
+ ForgotPasswordAffordanceRegularExpressions: [
+ "^forgot.*password",
+ "^log.*in.*email",
+ "request.*password",
+ ],
+ ForgotUserNameAffordanceRegularExpressions: ["^forgot.*user.*name"],
+ ForgotEmailAffordanceRegularExpressions: ["^forgot.*email", "email\\?$"],
+ };
+0;
diff --git a/27.0/js/forms/FormMetadataJSController.js b/27.0/js/forms/FormMetadataJSController.js
new file mode 100644
index 0000000..9d62737
--- /dev/null
+++ b/27.0/js/forms/FormMetadataJSController.js
@@ -0,0 +1,657 @@
+//# sourceURL=__InjectedScript_FormMetadataJSController.js
+/* Copyright (c) 2026 Apple Inc. All rights reserved. */
+"use strict";
+const WBSMinimumLogicalWidthToShowManualAutoFillButton = 100,
+ WKInputFieldActionTypeMoveUp = 0,
+ WKInputFieldActionTypeMoveDown = 1,
+ WKInputFieldActionTypeCancel = 2,
+ WKInputFieldActionTypeInsertTab = 3,
+ WKInputFieldActionTypeInsertBacktab = 4,
+ WKInputFieldActionTypeInsertNewline = 5,
+ WKInputFieldActionTypeInsertDelete = 6,
+ textDidChangeCoalescingTime = 100;
+class FormMetadataFieldPatternMatcher {
+ searchRegularExpression;
+ constructor(e) {
+ this.buffer = e;
+ }
+ dfa() {
+ return this.buffer.asUTF16String();
+ }
+}
+class FormMetadataJSController {
+ static isDebugConsoleLoggingEnabled =
+ AutoFillControllerConfig.isDebugConsoleLoggingEnabled;
+ static collectAllFields = AutoFillControllerConfig.collectAllFields;
+ static _nextControlUniqueID = 1;
+ static get nextControlUniqueID() {
+ return this._nextControlUniqueID++;
+ }
+ static _nextFormUniqueID = 1;
+ static get nextFormUniqueID() {
+ return this._nextFormUniqueID++;
+ }
+ static regularExpressionsIndicatingNonAutoFillableFormType =
+ FormAutoFillKeywords.NonAutoFillableFormTypeRegularExpressions;
+ static loginFormTypePatternMatchers = [
+ new FormMetadataFieldPatternMatcher(
+ window.webkit.buffers.keywordsIndicatingLoginFormTypeToScoreForMatching,
+ ),
+ ];
+ static oneTimeCodeFieldLabelPatternMatchers = [
+ new FormMetadataFieldPatternMatcher(
+ window.webkit.buffers.oneTimeCodeFieldLabels,
+ ),
+ ];
+ static nonAccountPasswordSecureTextEntryFieldLabelPatternMatchers = [
+ new FormMetadataFieldPatternMatcher(
+ window.webkit.buffers.nonAccountPasswordSecureTextEntryFieldLabels,
+ ),
+ ];
+ static ignoredDataTypeFieldLabelPatternMatchers = [
+ new FormMetadataFieldPatternMatcher(
+ window.webkit.buffers.ignoredDataTypeFieldLabels,
+ ),
+ ];
+ static genericAdditionalClassificationLabelPatternMatchers = [
+ new FormMetadataFieldPatternMatcher(
+ window.webkit.buffers.genericAdditionalClassificationLabels,
+ ),
+ ];
+ static additionalClassificationControlLabelPatternMatchers = [
+ new FormMetadataFieldPatternMatcher(
+ window.webkit.buffers.additionalClassificationControlLabels,
+ ),
+ ];
+ static oldPasswordFieldLabelPatternMatchers = [
+ new FormMetadataFieldPatternMatcher(
+ window.webkit.buffers.oldPasswordFieldLabels,
+ ),
+ ];
+ static confirmPasswordFieldLabelPatternMatchers = [
+ new FormMetadataFieldPatternMatcher(
+ window.webkit.buffers.confirmPasswordFieldLabels,
+ ),
+ ];
+ static confirmEmailFieldLabelPatternMatchers = [
+ new FormMetadataFieldPatternMatcher(
+ window.webkit.buffers.confirmEmailFieldLabels,
+ ),
+ ];
+ static showHideButtonLabelPatternMatchers = [
+ new FormMetadataFieldPatternMatcher(
+ window.webkit.buffers.showHideButtonLabels,
+ ),
+ ];
+ static searchFieldLabelPatternMatchers = [
+ new FormMetadataFieldPatternMatcher(
+ window.webkit.buffers.searchFieldLabels,
+ ),
+ ];
+ static nonUsernameFieldLabelPatternMatchers = [
+ new FormMetadataFieldPatternMatcher(
+ window.webkit.buffers.nonUsernameFieldLabels,
+ ),
+ ];
+ static passwordFieldLabelPatternMatchers = [
+ new FormMetadataFieldPatternMatcher(
+ window.webkit.buffers.passwordFieldLabels,
+ ),
+ ];
+ static usernameFieldLabelPatternMatchers = [
+ new FormMetadataFieldPatternMatcher(
+ window.webkit.buffers.usernameFieldLabels,
+ ),
+ ];
+ static nonEmailFieldLabelPatternMatchers = [
+ new FormMetadataFieldPatternMatcher(
+ window.webkit.buffers.nonEmailFieldLabels,
+ ),
+ ];
+ static weakOneTimeCodeFieldLabelPatternMatchers = [
+ new FormMetadataFieldPatternMatcher(
+ window.webkit.buffers.WeakOneTimeCodeFieldLabels,
+ ),
+ ];
+ static codeButNotOneTimeCodeFieldLabelsPatternMatchers = [
+ new FormMetadataFieldPatternMatcher(
+ window.webkit.buffers.CodeButNotOneTimeCodeFieldLabels,
+ ),
+ ];
+ static dayFieldLabelPatternMatchers = [
+ new FormMetadataFieldPatternMatcher(window.webkit.buffers.dayFieldLabels),
+ ];
+ static monthFieldLabelPatternMatchers = [
+ new FormMetadataFieldPatternMatcher(window.webkit.buffers.monthFieldLabels),
+ ];
+ static yearFieldLabelPatternMatchers = [
+ new FormMetadataFieldPatternMatcher(window.webkit.buffers.yearFieldLabels),
+ ];
+ static addressBookFieldLabelPatternMatchers =
+ newAddressBookFieldLabelPatternMatchers();
+ static emailFieldLabelPatternMatchers = newEmailFieldLabelPatternMatchers();
+ static creditCardNumberFieldLabelPatternMatchers = [
+ new FormMetadataFieldPatternMatcher(
+ window.webkit.buffers.creditCardNumberFieldLabels,
+ ),
+ ];
+ static creditCardSecurityCodeFieldLabelPatternMatchers = [
+ new FormMetadataFieldPatternMatcher(
+ window.webkit.buffers.creditCardSecurityCodeFieldLabels,
+ ),
+ ];
+ static creditCardCardholderFieldLabelPatternMatchers = [
+ new FormMetadataFieldPatternMatcher(
+ window.webkit.buffers.creditCardCardholderFieldLabels,
+ ),
+ ];
+ static creditCardTypeFieldLabelPatternMatchers = [
+ new FormMetadataFieldPatternMatcher(
+ window.webkit.buffers.creditCardTypeFieldLabels,
+ ),
+ ];
+ static nonCreditCardCardNumberFieldLabelPatternMatchers = [
+ new FormMetadataFieldPatternMatcher(
+ window.webkit.buffers.nonCreditCardCardNumberFieldLabels,
+ ),
+ ];
+ static creditCardCompositeExpirationDateFieldLabelPatternMatchers = [
+ new FormMetadataFieldPatternMatcher(
+ window.webkit.buffers.creditCardCompositeExpirationDateFieldLabels,
+ ),
+ ];
+ static newAccountFormTypePatternMatchers = [
+ new FormMetadataFieldPatternMatcher(
+ window.webkit.buffers
+ .keywordsIndicatingNewAccountFormTypeToScoreForMatching,
+ ),
+ ];
+ static federatedSignInAffordancePatternMatchers = [
+ new FormMetadataFieldPatternMatcher(
+ window.webkit.buffers.federatedSignInAffordanceLabels,
+ ),
+ ];
+ static mapOfKeywordsIndicatingLoginFormTypeToScoreForMatching =
+ FormAutoFillKeywords.LoginFormTypeKeywords;
+ static mapOfKeywordsIndicatingNewAccountFormTypeToScoreForMatching =
+ FormAutoFillKeywords.NewAccountFormTypeKeywords;
+ static mapOfKeywordsIndicatingChangePasswordFormTypeToScoreForMatching =
+ FormAutoFillKeywords.ChangePasswordFormTypeKeywords;
+ static regularExpressionsForForgotPasswordAffordance =
+ FormAutoFillKeywords.ForgotPasswordAffordanceRegularExpressions;
+ static regularExpressionsForForgotUserNameAffordance =
+ FormAutoFillKeywords.ForgotUserNameAffordanceRegularExpressions;
+ static regularExpressionsForForgotEmailAffordance =
+ FormAutoFillKeywords.ForgotEmailAffordanceRegularExpressions;
+ autoFillButtonManager;
+ focusManager;
+ didAssociateFormControlsTimeout;
+ constructor() {
+ ((this.focusManager = new FocusManager(this)),
+ this.focusManager.addEventListeners(),
+ (this.autoFillButtonManager = new AutoFillButtonManager(this)),
+ this.autoFillButtonManager.addEventListeners(),
+ (this.didAssociateFormControlsTimeout = null),
+ addGlobalEventHandler(
+ "webkitassociateformcontrols",
+ this.didAssociateFormControls.bind(this),
+ ),
+ (this.shouldNotifyOnFormChanges = !1),
+ window.addEventListener("pagehide", () => {
+ this.focusManager.cleanUp();
+ let e = null;
+ (document.activeElement instanceof HTMLInputElement &&
+ (e = FormMetadataJS.textFieldOrSelectElementMetadata(
+ document.activeElement,
+ WBSFormMetadataRequestNormal,
+ )[0]),
+ window.webkit.messageHandlers.controller.postMessage({
+ name: "pageHide",
+ focusedControlMetadata: e,
+ }));
+ }));
+ }
+ didAssociateFormControls(e) {
+ if (!this.shouldNotifyOnFormChanges) return;
+ if (this.didAssociateFormControlsTimeout) return;
+ const t = e.composedPath()[0];
+ if ("hidden" === t.type || "button" === t.type) return;
+ const [a, o] = FormMetadataJS.formsAndMetadata(
+ WBSFormMetadataRequestPreFill,
+ );
+ this.didAssociateFormControlsTimeout = setTimeout(
+ this.sendDidAssociateFormControlsMessage.bind(this),
+ 0,
+ );
+ }
+ sendDidAssociateFormControlsMessage() {
+ ((this.didAssociateFormControlsTimeout = null),
+ window.webkit.messageHandlers.controller.postMessage({
+ name: "didAssociateFormControls",
+ }));
+ }
+ textEditingStatus() {
+ const [e, t] = FormMetadataJS.visibleNonEmptyFormTextControls(),
+ a = e.filter((e) => e.lastChangeWasUserEdit),
+ o = t.filter((e) => e.lastChangeWasUserEdit),
+ r = document.body.onbeforeunload,
+ n = null != r;
+ return {
+ numberOfTextInputElements: a.length,
+ numberOfTextAreaElements: o.length,
+ hasOnBeforeUnloadEventHandler: n,
+ };
+ }
+ async fillFormWithPassword(e, t, a, o) {
+ const r = await FormMetadataJS.fillFormWithPassword(e, a, t);
+ if (r)
+ for (const e of r) {
+ const t = FormMetadataJS.formControlWithUniqueID(e);
+ t && (t.autofillVisibility = o ? "hidden" : "visible");
+ }
+ o && AutomaticPasswordsJS.blurControlWithID(t);
+ let n = null;
+ const i = FormMetadataJS.formsAndMetadata(WBSFormMetadataRequestNormal)[1];
+ for (const t of i)
+ if (t.FormID === e) {
+ n = t;
+ break;
+ }
+ return { controlIDs: r, formMetadata: n };
+ }
+ static #e(e) {
+ const t = getComputedStyle(e).writingMode,
+ a = !("horizontal-tb" === t || "horizontal-bt" === t),
+ o = e.getBoundingClientRect();
+ return (
+ (a ? o.height : o.width) >=
+ WBSMinimumLogicalWidthToShowManualAutoFillButton
+ );
+ }
+ static #t(e) {
+ return !!FormMetadataJSController.#e(e) && e === innermostActiveElement();
+ }
+ static autocompleteTokenMapDFA() {
+ return window.webkit.buffers.autocompleteTokenMapMatcher.asUTF16String();
+ }
+ static fieldLabelMapDFA() {
+ return window.webkit.buffers.fieldLabelMapMatcher.asUTF16String();
+ }
+ static getValueSpecifiers(e) {
+ return valueSpecifiers[e];
+ }
+ showAutoFillButtonInControl(e, t) {
+ const a = FormMetadataJS.formControlWithUniqueID(e);
+ (FormMetadataJSController.#t(a) || "none" === t) &&
+ a._setAutofillButtonType(t);
+ }
+ hideAutoFillButtonInControl(e) {
+ FormMetadataJS.formControlWithUniqueID(e)._setAutofillButtonType("none");
+ }
+ setAutofillAvailable(e, t) {
+ const a = FormMetadataJS.formControlWithUniqueID(e);
+ a && (a.autofillAvailable = t);
+ }
+ setControlsAsAutoFilled(e, t) {
+ this.#a(e).forEach((e) => {
+ FormMetadataJSController.setInputElementAutofilled(e, t);
+ });
+ }
+ blurControls(e) {
+ this.#a(e).forEach((e) => e.blur());
+ }
+ clearControls(e) {
+ e.forEach((e) => FormMetadataJS.clearField(e));
+ }
+ annotateForm(e, t) {
+ FormMetadataJS.annotateFormWithID(e, t);
+ }
+ formsMetadata(e) {
+ (e !== WBSFormMetadataRequestPreFill &&
+ e !== WBSFormMetadataRequestTesting) ||
+ (this.shouldNotifyOnFormChanges = !0);
+ let [t, a] = FormMetadataJS.formsAndMetadata(e);
+ for (const e of a)
+ for (const t of e.FormControls) {
+ const e = FormMetadataJS.formControlWithUniqueID(t.ControlUniqueID);
+ this.populateRectFieldsInFormElementMetadata(t, e);
+ }
+ return a;
+ }
+ getMetadataForFocusedElement(e = WBSFormMetadataRequestNormal) {
+ const t = innermostActiveElement();
+ return t ? this._getMetadataForControl(t, e) : [null, null];
+ }
+ getMetadataForControl(e, t = WBSFormMetadataRequestNormal) {
+ const a = FormMetadataJS.formControlWithUniqueID(e);
+ return a ? this._getMetadataForControl(a, t) : [null, null];
+ }
+ static #o(e) {
+ let t = 0;
+ const a = e.FirstCreditCardCardholderFieldOrCreditCardNumberFieldUniqueID,
+ o = e.UserNameElementUniqueID,
+ r = e.PasswordElementUniqueID,
+ n = e.ConfirmPasswordElementUniqueID,
+ i = 1,
+ l = 10;
+ if ((a && (t += i), o && (t += i), r && (t += i), n && (t += i), !t))
+ return t;
+ for (const i of e.FormControls) {
+ const e = i.ControlUniqueID;
+ if (e === a || e === o || e === r || e === n) {
+ i.ControlValue && (t += l);
+ }
+ }
+ return t;
+ }
+ getMetadataForForm(e) {
+ const [t, a] = FormMetadataJS.formsAndMetadata(
+ WBSFormMetadataRequestNormal,
+ );
+ let o = -1,
+ r = null;
+ for (let n = 0; n < t.length; n++)
+ if (t[n] === e) {
+ const e = a[n],
+ t = FormMetadataJSController.#o(e);
+ t > o && ((o = t), (r = e));
+ }
+ return r;
+ }
+ _getMetadataForControl(e, t) {
+ let [a, o] = FormMetadataJS.textFieldOrSelectElementMetadata(e, t);
+ return (this.populateRectFieldsInFormElementMetadata(a, e), [a, o]);
+ }
+ focusControl(e, t = !1) {
+ FormMetadataJS.focusControl(e, t);
+ }
+ replaceRangeInControl(e, t, a, o, r) {
+ FormMetadataJS.replaceFormFieldRangeAndSelectTail(e, t, a, o, r);
+ const n = FormMetadataJS.formControlWithUniqueID(e);
+ if (n)
+ return FormMetadataJS.textFieldOrSelectElementMetadata(
+ n,
+ WBSFormMetadataRequestNormal,
+ );
+ }
+ selectRangeInControl(e, t, a) {
+ FormMetadataJS.setFormFieldSelection(e, t, a);
+ }
+ static setInputElementSpellCheckEnabled(e, t) {
+ e.autofillSpellcheck = !!t;
+ }
+ static setInputElementAutofilled(e, t) {
+ ((e.autofilled = t),
+ t && FormMetadataJSController.autoFilledFieldWithMetadata(e));
+ }
+ static setInputElementAutoFilledAndViewable(e, t) {
+ e.autofilledAndViewable = t;
+ }
+ static setInputElementAutofilledAndObscured(e, t) {
+ ((e.autofilledAndObscured = t),
+ t && FormMetadataJSController.autoFilledFieldWithMetadata(e));
+ }
+ populateRectFieldsInFormElementMetadata(e, t) {
+ const a = t.getBoundingClientRect();
+ ((e.ControlRectLeft = a.left),
+ (e.ControlRectTop = a.top),
+ (e.ControlRectWidth = a.width),
+ (e.ControlRectHeight = a.height));
+ }
+ #a(e) {
+ return e.flatMap((e) => FormMetadataJS.formControlWithUniqueID(e));
+ }
+ static autoFilledFieldWithMetadata(e) {
+ let [t, a] = FormMetadataJS.textFieldOrSelectElementMetadata(
+ e,
+ WBSFormMetadataRequestNormal,
+ );
+ window.webkit.messageHandlers.controller.postMessage({
+ name: "autoFilledFieldWithMetadata",
+ controlMetadata: t,
+ formMetadata: a,
+ });
+ }
+ static logicalFormObservedChangeIndicatingFormSubmission(e, t) {
+ window.webkit.messageHandlers.controller.postMessage({
+ name: "formObservedChangeIndicatingFormSubmission",
+ formMetadata: e,
+ removedControlsMetadata: t,
+ });
+ }
+ static logicalFormObservedNewControlsWereAdded(e) {
+ window.webkit.messageHandlers.controller.postMessage({
+ name: "formObservedNewControlsWereAdded",
+ formMetadata: e,
+ });
+ }
+ static fieldLabelToInfo(e) {
+ if (void 0 === e) return null;
+ const [t, a] = e;
+ if (t === 65535) return [a, "", "", ""];
+ const o = valueSpecifiers[t];
+ return [a, o.property, o.category, o.parentProperty];
+ }
+}
+class FieldMovementChecker {
+ textField;
+ textFieldMetadata;
+ formMetadata;
+ numberOfTimesFieldMovementTimerHasFired;
+ checkForFieldMovementTimeout;
+ pollingIntervals;
+ onFieldMoved;
+ constructor(e) {
+ ((this.textField = null),
+ (this.textFieldMetadata = null),
+ (this.numberOfTimesFieldMovementTimerHasFired = 0),
+ (this.checkForFieldMovementTimeout = null),
+ (this.pollingIntervals = [10, 50, 100, 850]),
+ (this.onFieldMoved = e));
+ }
+ setTextFieldToMonitor(e, t, a) {
+ ((this.textField = e),
+ (this.textFieldMetadata = t),
+ (this.formMetadata = a));
+ }
+ performNextCheckForFieldMovement() {
+ if (
+ ((this.checkForFieldMovementTimeout = null),
+ !this.textField || !this.textFieldMetadata)
+ )
+ return void this.reset();
+ const e = this.textField.getBoundingClientRect();
+ (this.textFieldMetadata.ControlRectLeft != e.left ||
+ this.textFieldMetadata.ControlRectTop != e.top ||
+ this.textFieldMetadata.ControlRectWidth != e.width ||
+ this.textFieldMetadata.ControlRectHeight != e.height
+ ? (this.onFieldMoved(
+ this.textField,
+ this.textFieldMetadata,
+ this.formMetadata,
+ ),
+ (this.numberOfTimesFieldMovementTimerHasFired = 0))
+ : (this.numberOfTimesFieldMovementTimerHasFired += 1),
+ this.numberOfTimesFieldMovementTimerHasFired >=
+ this.pollingIntervals.length
+ ? this.reset()
+ : this.scheduleNextCheckForFieldMovement());
+ }
+ reset() {
+ (this.checkForFieldMovementTimeout &&
+ window.clearTimeout(this.checkForFieldMovementTimeout),
+ (this.checkForFieldMovementTimeout = null));
+ }
+ scheduleNextCheckForFieldMovement() {
+ this.reset();
+ const e =
+ this.pollingIntervals[this.numberOfTimesFieldMovementTimerHasFired];
+ this.checkForFieldMovementTimeout = window.setTimeout(
+ this.performNextCheckForFieldMovement.bind(this),
+ e,
+ );
+ }
+}
+class EventDispatcher {
+ #r = new Map();
+ addGlobalListener(e, t) {
+ (this.#r.has(e) || this.#r.set(e, new Set()), this.#r.get(e).add(t));
+ }
+ dispatchEvent(e) {
+ if (this.#r.has(e.type))
+ for (const t of this.#r.get(e.type)) t(e.target, e.data);
+ }
+}
+const formMetadataEventDispatcher = new EventDispatcher();
+class FocusManager {
+ jsController;
+ fieldMovementChecker;
+ #n = null;
+ constructor(e) {
+ ((this.jsController = e),
+ (this.fieldMovementChecker = new FieldMovementChecker(
+ this.handleElementFocused.bind(this),
+ )));
+ }
+ addEventListeners() {
+ (formMetadataEventDispatcher.addGlobalListener(
+ "webkitsubmit",
+ this.submitEventHandler.bind(this),
+ ),
+ formMetadataEventDispatcher.addGlobalListener(
+ "webkitbeforefocus",
+ this.focusInEventHandler.bind(this),
+ ),
+ formMetadataEventDispatcher.addGlobalListener(
+ "webkitbeforeblur",
+ this.focusOutEventHandler.bind(this),
+ ),
+ formMetadataEventDispatcher.addGlobalListener(
+ "webkitusertextinput",
+ this.inputEventHandler.bind(this),
+ ),
+ formMetadataEventDispatcher.addGlobalListener(
+ "keydown",
+ this.keydownEventHandler.bind(this),
+ ));
+ }
+ focusInEventHandler(e) {
+ this.fieldMovementChecker.reset();
+ let [t, a] = FormMetadataJS.textFieldOrSelectElementMetadata(
+ e,
+ WBSFormMetadataRequestNormal,
+ );
+ t &&
+ (e.setUserInfo({ form: a, textField: t }),
+ this.fieldMovementChecker.setTextFieldToMonitor(e, t, a),
+ this.fieldMovementChecker.scheduleNextCheckForFieldMovement(),
+ this.handleElementFocused(e, t, a));
+ }
+ handleElementFocused(e, t, a) {
+ (this.jsController.populateRectFieldsInFormElementMetadata(t, e),
+ window.webkit.messageHandlers.controller.postMessage({
+ name: "elementFocused",
+ focusedElementMetadata: t,
+ formMetadata: a,
+ }));
+ }
+ focusOutEventHandler(e) {
+ this.fieldMovementChecker.reset();
+ let [t, a] = FormMetadataJS.textFieldOrSelectElementMetadata(
+ e,
+ WBSFormMetadataRequestNormal,
+ );
+ t &&
+ window.webkit.messageHandlers.controller.postMessage({
+ name: "elementBlurred",
+ focusedElementMetadata: t,
+ formMetadata: a,
+ });
+ }
+ cleanUp() {
+ this.#n && (clearTimeout(this.#n), (this.#n = null));
+ }
+ inputEventHandler(e) {
+ (this.#n && clearTimeout(this.#n),
+ (this.#n = setTimeout(() => {
+ this.#i(e);
+ }, textDidChangeCoalescingTime)));
+ }
+ #i(e) {
+ let [t, a] = FormMetadataJS.textFieldOrSelectElementMetadata(
+ e,
+ WBSFormMetadataRequestTextChange,
+ );
+ t &&
+ (this.jsController.populateRectFieldsInFormElementMetadata(t, e),
+ window.webkit.messageHandlers.controller.postMessage({
+ name: "elementInput",
+ focusedElementMetadata: t,
+ formMetadata: a,
+ }));
+ }
+ static #l(e, t) {
+ switch (e) {
+ case "ArrowUp":
+ return WKInputFieldActionTypeMoveUp;
+ case "ArrowDown":
+ return WKInputFieldActionTypeMoveDown;
+ case "Escape":
+ return WKInputFieldActionTypeCancel;
+ case "Tab":
+ return t
+ ? WKInputFieldActionTypeInsertBacktab
+ : WKInputFieldActionTypeInsertTab;
+ case "Enter":
+ return WKInputFieldActionTypeInsertNewline;
+ case "Backspace":
+ return WKInputFieldActionTypeInsertDelete;
+ default:
+ return null;
+ }
+ }
+ keydownEventHandler(e, t) {
+ const a = FocusManager.#l(t.key, t.shiftKey);
+ if (null === a) return;
+ const [o, r] = this.jsController._getMetadataForControl(
+ e,
+ WBSFormMetadataRequestNormal,
+ );
+ window.webkit.messageHandlers.controller.postMessage({
+ name: "observedActionInFormTextField",
+ action: a,
+ controlMetadata: o,
+ formMetadata: r,
+ });
+ }
+ submitEventHandler(e) {
+ const t = this.jsController.getMetadataForForm(e);
+ e.setUserInfo(t);
+ }
+}
+class AutoFillButtonManager {
+ jsController;
+ constructor(e) {
+ this.jsController = e;
+ }
+ addEventListeners() {
+ formMetadataEventDispatcher.addGlobalListener(
+ "webkitautofillrequest",
+ this.webKitAutofillRequestEventHandler.bind(this),
+ );
+ }
+ webKitAutofillRequestEventHandler(e) {
+ let [t, a] = this.jsController._getMetadataForControl(
+ e,
+ WBSFormMetadataRequestNormal,
+ );
+ window.webkit.messageHandlers.controller.postMessage({
+ name: "manualAutoFillRequest",
+ focusedElementMetadata: t,
+ formMetadata: a,
+ });
+ }
+}
+let formMetadataJSController = new FormMetadataJSController();
+eventQueue.setDelegate(formMetadataEventDispatcher);
+0;
diff --git a/27.0/js/forms/FormMetadataUtilities.js b/27.0/js/forms/FormMetadataUtilities.js
new file mode 100644
index 0000000..bcf94fb
--- /dev/null
+++ b/27.0/js/forms/FormMetadataUtilities.js
@@ -0,0 +1,43 @@
+//# sourceURL=__InjectedScript_FormMetadataUtilities.js
+/* Copyright (c) 2026 Apple Inc. All rights reserved. */
+// Copyright (c) 2025 Apple Inc. All rights reserved.
+"use strict";
+globalThis.FormMetadataUtilitiesJS = class {
+ static #t(t, e) {
+ const n = /([A-Za-z0-9])/;
+ let o = null,
+ s = -1,
+ i = -1;
+ const l = t.replaceAll(".", "").toLowerCase();
+ for (let t = 0; t < e.length; t++) {
+ const r = e[t].replaceAll(".", "").toLowerCase(),
+ a = r.indexOf(l);
+ if (-1 === a) continue;
+ if (a > 0 && n.test(r.charAt(a - 1))) continue;
+ let c = a + l.length;
+ (c < r.length && n.test(r.charAt(c))) ||
+ ((!o || r.length < o.length) && ((o = r), (s = t), (i = a)));
+ }
+ return { index: s, startPosition: i };
+ }
+ static bestIndexToFillSelectControl(t, e) {
+ const n = t.length,
+ o = [];
+ for (let e = 0; e < n; e++) {
+ const n = t[e][1];
+ o.push(n);
+ }
+ let s = -1,
+ i = Number.MAX_SAFE_INTEGER;
+ for (let t = e.length - 1; t >= 0; t--) {
+ const n = e[t];
+ Number.MAX_SAFE_INTEGER;
+ const l = this.#t(n, o);
+ -1 !== l.index &&
+ l.startPosition < i &&
+ ((i = l.startPosition), (s = l.index));
+ }
+ return -1 === s ? -1 : t[s][0];
+ }
+};
+0;
diff --git a/27.0/js/forms/PasswordRulesParserJS.js b/27.0/js/forms/PasswordRulesParserJS.js
new file mode 100644
index 0000000..698d96a
--- /dev/null
+++ b/27.0/js/forms/PasswordRulesParserJS.js
@@ -0,0 +1,387 @@
+//# sourceURL=__InjectedScript_PasswordRulesParserJS.js
+/* Copyright (c) 2026 Apple Inc. All rights reserved. */
+// Copyright (c) 2019 - 2026 Apple Inc. Licensed under MIT License.
+"use strict";
+function _isIdentifierCharacter(e) {
+ return (e >= "a" && e <= "z") || (e >= "A" && e <= "Z") || "-" === e;
+}
+function _isASCIIDigit(e) {
+ return e >= "0" && e <= "9";
+}
+function _isASCIIPrintableCharacter(e) {
+ return e >= " " && e <= "~";
+}
+function _isASCIIWhitespace(e) {
+ return " " === e || "\f" === e || "\n" === e || "\r" === e || "\t" === e;
+}
+function _bitSetIndexForCharacter(e) {
+ return e.codePointAt(0) - SPACE_CODE_POINT;
+}
+function _characterAtBitSetIndex(e) {
+ return String.fromCodePoint(e + SPACE_CODE_POINT);
+}
+function _markBitsForNamedCharacterClass(e, r) {
+ r.name === Identifier.UPPER
+ ? e.fill(
+ !0,
+ _bitSetIndexForCharacter("A"),
+ _bitSetIndexForCharacter("Z") + 1,
+ )
+ : r.name === Identifier.LOWER
+ ? e.fill(
+ !0,
+ _bitSetIndexForCharacter("a"),
+ _bitSetIndexForCharacter("z") + 1,
+ )
+ : r.name === Identifier.DIGIT
+ ? e.fill(
+ !0,
+ _bitSetIndexForCharacter("0"),
+ _bitSetIndexForCharacter("9") + 1,
+ )
+ : r.name === Identifier.SPECIAL &&
+ (e.fill(
+ !0,
+ _bitSetIndexForCharacter(" "),
+ _bitSetIndexForCharacter("/") + 1,
+ ),
+ e.fill(
+ !0,
+ _bitSetIndexForCharacter(":"),
+ _bitSetIndexForCharacter("@") + 1,
+ ),
+ e.fill(
+ !0,
+ _bitSetIndexForCharacter("["),
+ _bitSetIndexForCharacter("`") + 1,
+ ),
+ e.fill(
+ !0,
+ _bitSetIndexForCharacter("{"),
+ _bitSetIndexForCharacter("~") + 1,
+ ));
+}
+function _markBitsForCustomCharacterClass(e, r) {
+ for (let t of r.characters) e[_bitSetIndexForCharacter(t)] = !0;
+}
+function _canonicalizedPropertyValues(e, r) {
+ function t(e, r) {
+ let t = [];
+ for (
+ let n = _bitSetIndexForCharacter(e);
+ n <= _bitSetIndexForCharacter(r);
+ ++n
+ )
+ a[n] && t.push(_characterAtBitSetIndex(n));
+ let i =
+ t.length ===
+ _bitSetIndexForCharacter(r) - _bitSetIndexForCharacter(e) + 1;
+ return (i || (n = n.concat(t)), i);
+ }
+ let a = new Array("~".codePointAt(0) - " ".codePointAt(0) + 1);
+ for (let r of e)
+ if (r instanceof NamedCharacterClass) {
+ if (r.name === Identifier.UNICODE)
+ return [new NamedCharacterClass(Identifier.UNICODE)];
+ if (r.name === Identifier.ASCII_PRINTABLE)
+ return [new NamedCharacterClass(Identifier.ASCII_PRINTABLE)];
+ _markBitsForNamedCharacterClass(a, r);
+ } else
+ r instanceof CustomCharacterClass &&
+ _markBitsForCustomCharacterClass(a, r);
+ let n = [],
+ i = t("A", "Z"),
+ l = t("a", "z"),
+ s = t("0", "9"),
+ u = !1,
+ c = !1,
+ o = !1,
+ _ = [];
+ for (
+ let e = _bitSetIndexForCharacter(" ");
+ e <= _bitSetIndexForCharacter("/");
+ ++e
+ ) {
+ if (!a[e]) continue;
+ let t = _characterAtBitSetIndex(e);
+ r && "-" === t ? (c = !0) : _.push(t);
+ }
+ for (
+ let e = _bitSetIndexForCharacter(":");
+ e <= _bitSetIndexForCharacter("@");
+ ++e
+ )
+ a[e] && _.push(_characterAtBitSetIndex(e));
+ for (
+ let e = _bitSetIndexForCharacter("[");
+ e <= _bitSetIndexForCharacter("`");
+ ++e
+ ) {
+ if (!a[e]) continue;
+ let t = _characterAtBitSetIndex(e);
+ r && "]" === t ? (o = !0) : _.push(t);
+ }
+ for (
+ let e = _bitSetIndexForCharacter("{");
+ e <= _bitSetIndexForCharacter("~");
+ ++e
+ )
+ a[e] && _.push(_characterAtBitSetIndex(e));
+ (c && _.unshift("-"), o && _.push("]"));
+ let C =
+ _bitSetIndexForCharacter("/") -
+ _bitSetIndexForCharacter(" ") +
+ 1 +
+ (_bitSetIndexForCharacter("@") - _bitSetIndexForCharacter(":") + 1) +
+ (_bitSetIndexForCharacter("`") - _bitSetIndexForCharacter("[") + 1) +
+ (_bitSetIndexForCharacter("~") - _bitSetIndexForCharacter("{") + 1);
+ ((u = _.length === C), u || (n = n.concat(_)));
+ let h = [];
+ return i && l && s && u
+ ? [new NamedCharacterClass(Identifier.ASCII_PRINTABLE)]
+ : (i && h.push(new NamedCharacterClass(Identifier.UPPER)),
+ l && h.push(new NamedCharacterClass(Identifier.LOWER)),
+ s && h.push(new NamedCharacterClass(Identifier.DIGIT)),
+ u && h.push(new NamedCharacterClass(Identifier.SPECIAL)),
+ n.length && h.push(new CustomCharacterClass(n)),
+ h);
+}
+function _indexOfNonWhitespaceCharacter(e, r = 0) {
+ let t = e.length;
+ for (; r < t && _isASCIIWhitespace(e[r]);) ++r;
+ return r;
+}
+function _parseIdentifier(e, r) {
+ let t = e.length,
+ a = [];
+ do {
+ let t = e[r];
+ if (!_isIdentifierCharacter(t)) break;
+ (a.push(t), ++r);
+ } while (r < t);
+ return [a.join(""), r];
+}
+function _isValidRequiredOrAllowedPropertyValueIdentifier(e) {
+ return e && Object.values(Identifier).includes(e.toLowerCase());
+}
+function _parseCustomCharacterClass(e, r) {
+ let t = e.length;
+ if (++r >= t) return [null, r];
+ let a = r,
+ n = [];
+ do {
+ let t = e[r];
+ if (_isASCIIPrintableCharacter(t)) {
+ if ("-" === t && r - a > 0) ++r;
+ else if ((n.push(t), ++r, t === CHARACTER_CLASS_END_SENTINEL)) break;
+ } else ++r;
+ } while (r < t);
+ if (
+ (r < t && e[r] !== CHARACTER_CLASS_END_SENTINEL) ||
+ (r == t && e[r - 1] == CHARACTER_CLASS_END_SENTINEL)
+ ) {
+ if ((n.pop(), r < t)) {
+ let t = e[r];
+ _isASCIIWhitespace(t);
+ }
+ return [n, r];
+ }
+ return r < t && e[r] == CHARACTER_CLASS_END_SENTINEL ? [n, r + 1] : [null, r];
+}
+function _parsePasswordRequiredOrAllowedPropertyValue(e, r) {
+ let t = e.length,
+ a = [];
+ for (;;) {
+ if (_isIdentifierCharacter(e[r])) {
+ let t = r;
+ var [n, r] = _parseIdentifier(e, r);
+ if (!_isValidRequiredOrAllowedPropertyValueIdentifier(n))
+ return [null, t];
+ a.push(new NamedCharacterClass(n));
+ } else {
+ if (e[r] != CHARACTER_CLASS_START_SENTINEL) return [null, r];
+ var [n, r] = _parseCustomCharacterClass(e, r);
+ n && n.length && a.push(new CustomCharacterClass(n));
+ }
+ if (
+ (r = _indexOfNonWhitespaceCharacter(e, r)) >= t ||
+ e[r] === PROPERTY_SEPARATOR
+ )
+ break;
+ if (e[r] !== PROPERTY_VALUE_SEPARATOR) return [null, r];
+ if ((r = _indexOfNonWhitespaceCharacter(e, r + 1)) >= t) return [null, r];
+ }
+ return [a, r];
+}
+function _parsePasswordRule(e, r) {
+ let t = e.length;
+ var a = r,
+ [n, r] = _parseIdentifier(e, r);
+ if (!Object.values(RuleName).includes(n)) return [null, a];
+ if (r >= t) return [null, r];
+ if (e[r] !== PROPERTY_VALUE_START_SENTINEL) return [null, r];
+ let i = { name: n, value: null };
+ if (
+ (r = _indexOfNonWhitespaceCharacter(e, r + 1)) >= t ||
+ e[r] === PROPERTY_SEPARATOR
+ )
+ return [new Rule(i.name, i.value), r];
+ switch (n) {
+ case RuleName.ALLOWED:
+ case RuleName.REQUIRED:
+ var [l, r] = _parsePasswordRequiredOrAllowedPropertyValue(e, r);
+ return (l && (i.value = l), [new Rule(i.name, i.value), r]);
+ case RuleName.MAX_CONSECUTIVE:
+ var [l, r] = _parseMaxConsecutivePropertyValue(e, r);
+ return (l && (i.value = l), [new Rule(i.name, i.value), r]);
+ case RuleName.MIN_LENGTH:
+ case RuleName.MAX_LENGTH:
+ var [l, r] = _parseMinLengthMaxLengthPropertyValue(e, r);
+ return (l && (i.value = l), [new Rule(i.name, i.value), r]);
+ }
+}
+function _parseMinLengthMaxLengthPropertyValue(e, r) {
+ return _parseInteger(e, r);
+}
+function _parseMaxConsecutivePropertyValue(e, r) {
+ return _parseInteger(e, r);
+}
+function _parseInteger(e, r) {
+ if (!_isASCIIDigit(e[r])) return [null, r];
+ let t = e.length,
+ a = 0;
+ do {
+ ((a = 10 * a + parseInt(e[r], 10)), ++r);
+ } while (r < t && e[r] !== PROPERTY_SEPARATOR && _isASCIIDigit(e[r]));
+ return r >= t || e[r] === PROPERTY_SEPARATOR ? [a, r] : [null, r];
+}
+function _parsePasswordRulesInternal(e) {
+ let r = [],
+ t = e.length;
+ for (var a = _indexOfNonWhitespaceCharacter(e); a < t;) {
+ if (!_isIdentifierCharacter(e[a])) return r;
+ var [n, a] = _parsePasswordRule(e, a);
+ if (
+ (n && n.value && r.push(n),
+ (a = _indexOfNonWhitespaceCharacter(e, a)) >= t)
+ )
+ break;
+ if (e[a] !== PROPERTY_SEPARATOR) return null;
+ if ((a = _indexOfNonWhitespaceCharacter(e, a + 1)) >= t) return r;
+ }
+ return r;
+}
+function parsePasswordRules(e, r) {
+ let t = _parsePasswordRulesInternal(e) || [],
+ a = r,
+ n = [],
+ i = [],
+ l = null,
+ s = 0,
+ u = null;
+ for (let e of t)
+ switch (e.name) {
+ case RuleName.MAX_CONSECUTIVE:
+ l = l ? Math.min(e.value, l) : e.value;
+ break;
+ case RuleName.MIN_LENGTH:
+ s = Math.max(e.value, s);
+ break;
+ case RuleName.MAX_LENGTH:
+ u = u ? Math.min(e.value, u) : e.value;
+ break;
+ case RuleName.REQUIRED:
+ ((e.value = _canonicalizedPropertyValues(e.value, r)),
+ n.push(e),
+ a || (i = i.concat(e.value)));
+ break;
+ case RuleName.ALLOWED:
+ i = i.concat(e.value);
+ }
+ return (
+ (i = _canonicalizedPropertyValues(i, a)),
+ a ||
+ i.length ||
+ (i = [new NamedCharacterClass(Identifier.ASCII_PRINTABLE)]),
+ i.length && n.push(new Rule(RuleName.ALLOWED, i)),
+ null !== l && n.push(new Rule(RuleName.MAX_CONSECUTIVE, l)),
+ s > 0 && n.push(new Rule(RuleName.MIN_LENGTH, s)),
+ null !== u && n.push(new Rule(RuleName.MAX_LENGTH, u)),
+ n
+ );
+}
+console ||
+ (console = {
+ assert: function () {},
+ error: function () {},
+ warn: function () {},
+ });
+const Identifier = {
+ ASCII_PRINTABLE: "ascii-printable",
+ DIGIT: "digit",
+ LOWER: "lower",
+ SPECIAL: "special",
+ UNICODE: "unicode",
+ UPPER: "upper",
+ },
+ RuleName = {
+ ALLOWED: "allowed",
+ MAX_CONSECUTIVE: "max-consecutive",
+ REQUIRED: "required",
+ MIN_LENGTH: "minlength",
+ MAX_LENGTH: "maxlength",
+ },
+ HTMLEntity = {
+ "&": "&",
+ "<": "<",
+ ">": ">",
+ '"': """,
+ "'": "'",
+ },
+ CHARACTER_CLASS_START_SENTINEL = "[",
+ CHARACTER_CLASS_END_SENTINEL = "]",
+ PROPERTY_VALUE_SEPARATOR = ",",
+ PROPERTY_SEPARATOR = ";",
+ PROPERTY_VALUE_START_SENTINEL = ":",
+ SPACE_CODE_POINT = " ".codePointAt(0),
+ SHOULD_NOT_BE_REACHED = "Should not be reached";
+class Rule {
+ constructor(e, r) {
+ ((this._name = e), (this.value = r));
+ }
+ get name() {
+ return this._name;
+ }
+ toString() {
+ return JSON.stringify(this);
+ }
+}
+class NamedCharacterClass {
+ constructor(e) {
+ this._name = e;
+ }
+ get name() {
+ return this._name.toLowerCase();
+ }
+ toString() {
+ return this._name;
+ }
+ toHTMLString() {
+ return this._name;
+ }
+}
+class CustomCharacterClass {
+ constructor(e) {
+ this._characters = e;
+ }
+ get characters() {
+ return this._characters;
+ }
+ toString() {
+ return `[${this._characters.join("")}]`;
+ }
+ toHTMLString() {
+ return `[${this._characters.join("").replace(/[&<>"']/g, (e) => HTMLEntity[e])}]`;
+ }
+}
+0;
diff --git a/27.0/js/forms/PatternRegexpToPasswordRulesConverter.js b/27.0/js/forms/PatternRegexpToPasswordRulesConverter.js
new file mode 100644
index 0000000..7871327
--- /dev/null
+++ b/27.0/js/forms/PatternRegexpToPasswordRulesConverter.js
@@ -0,0 +1,152 @@
+//# sourceURL=__InjectedScript_PatternRegexpToPasswordRulesConverter.js
+/* Copyright (c) 2026 Apple Inc. All rights reserved. */
+// Copyright (c) 2026 Apple Inc. Licensed under MIT License.
+"use strict";
+class PatternRegexpToPasswordRulesConverter {
+ static convert(t) {
+ try {
+ return this.#t(t);
+ } catch (t) {
+ return null;
+ }
+ }
+ static #t(t) {
+ const e = this.#e(t),
+ r = this.#r(e);
+ if (r) return r;
+ let s = e;
+ const a = this.#s(s);
+ if (((s = this.#a(s)), !this.#n(a))) return null;
+ const n = s.match(/^\.[\*\+]?(?:\{(\d+),(\d*)\})?$/);
+ if (n) {
+ const t = this.#l(a),
+ { min: e, max: r } = this.#i(n, 1, 2);
+ return this.#c(t, null, e, r);
+ }
+ const l = s.match(/^\[((?:[^\]\\]|\\.)*)\](?:\{(\d+),(\d*)\})?$/);
+ if (!l) return null;
+ const i = this.#l(a),
+ c = this.#o(l, i),
+ { min: o, max: u } = this.#i(l, 2, 3);
+ return this.#c(i, c, o, u);
+ }
+ static #e(t) {
+ let e = t.trim();
+ return (
+ e.startsWith("^") && (e = e.substring(1)),
+ e.endsWith("$") &&
+ !e.endsWith("\\$") &&
+ (e = e.substring(0, e.length - 1)),
+ e
+ );
+ }
+ static #r(t) {
+ return "\\d*" === t || "\\d+" === t || "[0-9]*" === t || "[0-9]+" === t
+ ? "required: digit;"
+ : "[a-z]*" === t || "[a-z]+" === t
+ ? "required: lower;"
+ : "[A-Z]*" === t || "[A-Z]+" === t
+ ? "required: upper;"
+ : null;
+ }
+ static #s(t) {
+ const e = [],
+ r = /\(\?=\.\*(?:\[((?:[^\]\\]|\\.)*)\]|(\\[dDwWsS]))\)/g;
+ let s;
+ for (; (s = r.exec(t));)
+ void 0 !== s[1] ? e.push(s[1]) : e.push(this.#u(s[2]));
+ return e;
+ }
+ static #n(t) {
+ for (const e of t)
+ for (const t of ["(?", "|", "\\D", "\\W", "\\S", "\\s"])
+ if (e.includes(t)) return !1;
+ return !0;
+ }
+ static #l(t) {
+ const e = [];
+ for (let r of t) {
+ ((r = r.replace(/\\d/g, "0-9")), (r = r.replace(/\\w/g, "a-zA-Z0-9_")));
+ const t = [];
+ let s = r;
+ (s.includes("0-9") && (t.push("digit"), (s = s.replace(/0-9/g, ""))),
+ s.includes("A-Z") && (t.push("upper"), (s = s.replace(/A-Z/g, ""))),
+ s.includes("a-z") && (t.push("lower"), (s = s.replace(/a-z/g, ""))),
+ (s = s.replace(/[a-zA-Z0-9]/g, "")),
+ t.length > 0 && 0 === s.length
+ ? e.push(t.join(", "))
+ : 0 === t.length && s.length > 0
+ ? e.push(this.#h(s))
+ : t.length > 0 &&
+ s.length > 0 &&
+ (t.push(this.#h(s)), e.push(t.join(", "))));
+ }
+ return e;
+ }
+ static #u(t) {
+ return { "\\d": "0-9", "\\w": "a-zA-Z0-9_" }[t] || t;
+ }
+ static #a(t) {
+ let e = t.replace(/\(\?=\.\*\[((?:[^\]\\]|\\.)*)\]\)/g, "");
+ return ((e = e.replace(/\(\?=\.\*(\\[dDwWsS])\)/g, "")), e);
+ }
+ static #h(t) {
+ let e = t.replace(/\\\]/g, "]").split(""),
+ r = !1,
+ s = !1,
+ a = [];
+ for (const t of e) "-" === t ? (r = !0) : "]" === t ? (s = !0) : a.push(t);
+ let n = "";
+ return (r && (n += "-"), (n += a.join("")), s && (n += "]"), `[${n}]`);
+ }
+ static #o(t, e) {
+ let r = t[1];
+ const s = [];
+ ((r = r.replace(/\\d/g, "0-9")), (r = r.replace(/\\w/g, "a-zA-Z0-9_")));
+ const a = (t) => e.some((e) => e === t || e.split(", ").includes(t));
+ (r.includes("a-z") && !a("lower") && s.push("lower"),
+ r.includes("A-Z") && !a("upper") && s.push("upper"),
+ r.includes("0-9") && !a("digit") && s.push("digit"));
+ let n = r;
+ if (
+ ((n = n.replace(/a-z/g, "")),
+ (n = n.replace(/A-Z/g, "")),
+ (n = n.replace(/0-9/g, "")),
+ (n = n.replace(/[a-zA-Z0-9]/g, "")),
+ (n = n.replace(/\\(.)/g, "$1")),
+ n)
+ ) {
+ const t = this.#h(n),
+ r = (t) => {
+ const e = t.match(/^\[(.*)\]$/);
+ return e ? "[" + [...e[1]].sort().join("") + "]" : t;
+ };
+ e.some((e) => r(e) === r(t)) || s.push(t);
+ }
+ return s.length ? s.join(", ") : null;
+ }
+ static #i(t, e, r) {
+ let s = null,
+ a = null;
+ if (t[e]) {
+ const r = parseInt(t[e], 10);
+ isNaN(r) || (s = r);
+ }
+ if (t[r]) {
+ const e = parseInt(t[r], 10);
+ isNaN(e) || (a = e);
+ }
+ return { min: s, max: a };
+ }
+ static #c(t, e, r, s) {
+ const a = [];
+ for (const e of t) a.push(`required: ${e}`);
+ return (
+ e && a.push(`allowed: ${e}`),
+ null !== r && a.push(`minlength: ${r}`),
+ null !== s && a.push(`maxlength: ${s}`),
+ a.join("; ") + ";"
+ );
+ }
+}
+0;
diff --git a/27.0/js/layout/WebContentLayoutAnalyzer.js b/27.0/js/layout/WebContentLayoutAnalyzer.js
new file mode 100644
index 0000000..9aeedcd
--- /dev/null
+++ b/27.0/js/layout/WebContentLayoutAnalyzer.js
@@ -0,0 +1,71 @@
+//# sourceURL=__InjectedScript_WebContentLayoutAnalyzer.js
+/* Copyright (c) 2026 Apple Inc. All rights reserved. */
+// Copyright (c) 2013 Apple Inc. All rights reserved.
+function elementAppearsCentered(e, t) {
+ var n = window.innerWidth - t.right - t.left;
+ return Math.abs(n) <= 1;
+}
+function centeredElementIsNotAContainer(e, t) {
+ if (e === document.documentElement || e === document.body) return !0;
+ if (0 === t.left && t.width === window.innerWidth) return !0;
+ if (!t.height) return !0;
+ var n = e.innerText;
+ return !n || !n.trim();
+}
+var WebContentLayoutAnalyzer = function () {
+ ((this.centeredContainerElement = null),
+ (this.rectOfCenteredContainerElementBeforeResize = null),
+ (this.rectOfCenteredContainerElementAfterResize = null));
+};
+WebContentLayoutAnalyzer.prototype = {
+ findCenteredContainerElement: function () {
+ for (
+ var e = null,
+ t = null,
+ n = document.getElementsByTagName("*"),
+ r = n.length,
+ i = 0;
+ i < r;
+ ++i
+ ) {
+ var o = n[i],
+ l = o.getBoundingClientRect();
+ elementAppearsCentered(o, l) &&
+ (centeredElementIsNotAContainer(o, l) ||
+ ((!t || l.width > t.width) && ((e = o), (t = l))));
+ }
+ return e;
+ },
+ collectInformationBeforeResize: function () {
+ ((this.centeredContainerElement = this.findCenteredContainerElement()),
+ this.centeredContainerElement &&
+ (this.rectOfCenteredContainerElementBeforeResize =
+ this.centeredContainerElement.getBoundingClientRect()));
+ },
+ collectInformationAfterResize: function () {
+ this.centeredContainerElement &&
+ document.contains(this.centeredContainerElement) &&
+ (this.rectOfCenteredContainerElementAfterResize =
+ this.centeredContainerElement.getBoundingClientRect());
+ },
+ layoutInformation: function () {
+ var e = !1,
+ t = null;
+ return (
+ this.rectOfCenteredContainerElementBeforeResize &&
+ this.rectOfCenteredContainerElementAfterResize &&
+ ((e =
+ this.rectOfCenteredContainerElementBeforeResize.width ===
+ this.rectOfCenteredContainerElementAfterResize.width),
+ (t =
+ this.rectOfCenteredContainerElementBeforeResize.left -
+ this.rectOfCenteredContainerElementAfterResize.left)),
+ {
+ FoundCenteredContainer: !!this.centeredContainerElement,
+ CenteredContainerIsFixedWidth: e,
+ DistanceContainerMoved: t,
+ }
+ );
+ },
+};
+var WebContentLayoutAnalyzerJS = new WebContentLayoutAnalyzer();
diff --git a/27.0/js/media/CNNCaptionQuirk.js b/27.0/js/media/CNNCaptionQuirk.js
new file mode 100644
index 0000000..b1a24b7
--- /dev/null
+++ b/27.0/js/media/CNNCaptionQuirk.js
@@ -0,0 +1,109 @@
+//# sourceURL=__InjectedScript_CNNCaptionQuirk.js
+(function () {
+ "use strict";
+
+ class CaptionMirror {
+ static _instances = new WeakMap();
+ constructor(video) {
+ let oldMirror = CaptionMirror._instances.get(video);
+ if (oldMirror) {
+ oldMirror.invalidate();
+ CaptionMirror._instances.delete(video);
+ }
+ CaptionMirror._instances.set(video, this);
+ this._video = video;
+ this._playerSelector = '[data-component-name="video-player"]';
+ this._overlayRootSelector = '[data-testid="overlay-root"]';
+ this._captionRowSelector = '[data-testid="cueBoxRowTextCue"]';
+ this._player = this._findPlayerRoot(video);
+ this._mirrorTrack = video.addTextTrack("forced", "CNN Captions");
+ this._mirrorTrack.mode = "hidden";
+ this._captionObserver = null;
+ this._waitObserver = null;
+ this._onPresentationModeChanged = () =>
+ this._handlePresentationModeChanged();
+ this._video.addEventListener(
+ "webkitpresentationmodechanged",
+ this._onPresentationModeChanged,
+ );
+ if (this._player) this._attachOverlayObserver();
+ }
+ invalidate() {
+ if (this._captionObserver) {
+ this._captionObserver.disconnect();
+ this._captionObserver = null;
+ }
+ if (this._waitObserver) {
+ this._waitObserver.disconnect();
+ this._waitObserver = null;
+ }
+ this._mirrorTrack.mode = "disabled";
+ this._video.removeEventListener(
+ "webkitpresentationmodechanged",
+ this._onPresentationModeChanged,
+ );
+ }
+ _findPlayerRoot(video) {
+ return video.closest(this._playerSelector);
+ }
+ _syncCues(overlayRoot) {
+ while (this._mirrorTrack.cues?.length)
+ this._mirrorTrack.removeCue(this._mirrorTrack.cues[0]);
+ var rows = Array.from(
+ overlayRoot.querySelectorAll(this._captionRowSelector),
+ );
+ if (!rows.length) return;
+ var text = rows.map((row) => row.textContent).join("\n");
+ if (!text) return;
+ var cue = new VTTCue(0, 10e7, text);
+ cue.snapToLines = true;
+ cue.line = -4;
+ cue.position = "auto";
+ cue.positionAlign = "center";
+ this._mirrorTrack.addCue(cue);
+ }
+
+ _attachOverlayObserver() {
+ var overlayRoot = this._player.querySelector(this._overlayRootSelector);
+ if (overlayRoot) {
+ this._attachCaptionObserver(overlayRoot);
+ return;
+ }
+ this._waitObserver = new MutationObserver(() => {
+ var overlayRoot = this._player.querySelector(this._overlayRootSelector);
+ if (overlayRoot) {
+ this._attachCaptionObserver(overlayRoot);
+ this._waitObserver.disconnect();
+ this._waitObserver = null;
+ }
+ });
+ this._waitObserver.observe(this._player, {
+ childList: true,
+ subtree: true,
+ });
+ }
+ _attachCaptionObserver(overlayRoot) {
+ if (this._captionObserver) this._captionObserver.disconnect();
+ this._captionObserver = new MutationObserver(() => {
+ var current = this._player.querySelector(this._overlayRootSelector);
+ if (current) this._syncCues(current);
+ });
+ this._captionObserver.observe(overlayRoot, {
+ childList: true,
+ subtree: true,
+ characterData: true,
+ });
+ this._syncCues(overlayRoot);
+ }
+ _handlePresentationModeChanged() {
+ if (this._video.webkitPresentationMode == "inline") {
+ this._mirrorTrack.mode = "hidden";
+ return;
+ }
+ this._mirrorTrack.mode = "showing";
+ }
+ }
+ window.setupCaptionMirroring = function (video) {
+ new CaptionMirror(video);
+ };
+})();
diff --git a/27.0/js/media/ModernMediaControls.js b/27.0/js/media/ModernMediaControls.js
new file mode 100644
index 0000000..45e4e0b
--- /dev/null
+++ b/27.0/js/media/ModernMediaControls.js
@@ -0,0 +1,5349 @@
+//# sourceURL=__InjectedScript_ModernMediaControls.js
+const MinimumSizeToShowAnyControl = 47;
+const MaximumSizeToShowSmallProminentControl = 88;
+if (!window.utils) {
+ window.utils = {
+ formattedStringForDuration: function (duration) {
+ return "";
+ },
+ };
+}
+function createControls(shadowRoot, media, host) {
+ if (host) {
+ for (let styleSheet of host.shadowRootStyleSheets)
+ shadowRoot.appendChild(document.createElement("style")).textContent =
+ styleSheet;
+ }
+ controller = new MediaController(shadowRoot, media, host);
+ if (host) host.controller = controller;
+ return controller;
+}
+function UIString(stringToLocalize, ...replacementStrings) {
+ let localizedString =
+ window.UIStrings?.[stringToLocalize] ?? stringToLocalize;
+ for (let replacementString of replacementStrings)
+ localizedString = localizedString.replace("%s", replacementString);
+ return localizedString;
+}
+function formatTimeByUnit(value) {
+ const time = value || 0;
+ const absTime = Math.abs(time);
+ const sign = Math.sign(time);
+ return {
+ seconds: sign * Math.floor(absTime % 60).toFixed(0),
+ minutes: sign * Math.floor((absTime / 60) % 60).toFixed(0),
+ hours: sign * Math.floor(absTime / (60 * 60)).toFixed(0),
+ };
+}
+function unitizeTime(value, unit) {
+ let returnedUnit = UIString(unit);
+ if (value > 1) returnedUnit = UIString(`${unit}s`);
+ return `${value} ${returnedUnit}`;
+}
+class GestureRecognizer {
+ constructor(target = null, delegate = null) {
+ this._targetPointers = new Map();
+ this.modifierKeys = { alt: false, ctrl: false, meta: false, shift: false };
+ this._state = GestureRecognizer.States.Possible;
+ this._enabled = true;
+ this.target = target;
+ this.delegate = delegate;
+ }
+ get state() {
+ return this._state;
+ }
+ set state(state) {
+ if (this._state === state && state !== GestureRecognizer.States.Changed)
+ return;
+ this._state = state;
+ if (
+ this.delegate &&
+ typeof this.delegate.gestureRecognizerStateDidChange === "function"
+ )
+ this.delegate.gestureRecognizerStateDidChange(this);
+ }
+ get target() {
+ return this._target;
+ }
+ set target(target) {
+ if (!target || this._target === target) return;
+ this._target = target;
+ this._initRecognizer();
+ }
+ get numberOfTouches() {
+ return this._targetPointers.size;
+ }
+ get enabled() {
+ return this._enabled;
+ }
+ set enabled(enabled) {
+ if (this._enabled === enabled) return;
+ this._enabled = enabled;
+ if (!enabled) {
+ if (this.numberOfTouches === 0) {
+ this._removeTrackingListeners();
+ this.reset();
+ } else this.enterCancelledState();
+ }
+ this._updateBaseListeners();
+ }
+ reset() {}
+ locationInElement(element) {
+ const p = new DOMPoint();
+ const count = this._targetPointers.size;
+ if (!count) return p;
+ this._targetPointers.forEach(function (pointer) {
+ p.x += pointer.pageX;
+ p.y += pointer.pageY;
+ });
+ p.x /= count;
+ p.y /= count;
+ if (!element) return p;
+ const wkPoint = window.webkitConvertPointFromPageToNode(
+ element,
+ new WebKitPoint(p.x, p.y),
+ );
+ return new DOMPoint(wkPoint.x, wkPoint.y);
+ }
+ locationInClient() {
+ const p = new DOMPoint();
+ const count = this._targetPointers.size;
+ if (!count) return p;
+ this._targetPointers.forEach(function (pointer) {
+ p.x += pointer.clientX;
+ p.y += pointer.clientY;
+ });
+ p.x /= count;
+ p.y /= count;
+ return p;
+ }
+ touchesBegan(event) {
+ if (event.currentTarget !== this._target) return;
+ this._captureTarget.addEventListener(
+ GestureRecognizer.Events.PointerMove,
+ this,
+ true,
+ );
+ this._captureTarget.addEventListener(
+ GestureRecognizer.Events.PointerUp,
+ this,
+ true,
+ );
+ this._captureTarget.addEventListener(
+ GestureRecognizer.Events.PointerCancel,
+ this,
+ true,
+ );
+ this.enterPossibleState();
+ }
+ touchesMoved(event) {}
+ touchesEnded(event) {}
+ touchesCancelled(event) {}
+ gestureBegan(event) {
+ if (event.currentTarget !== this._target) return;
+ this._target.addEventListener(
+ GestureRecognizer.Events.GestureChange,
+ this,
+ true,
+ );
+ this._target.addEventListener(
+ GestureRecognizer.Events.GestureEnd,
+ this,
+ true,
+ );
+ this.enterPossibleState();
+ }
+ gestureChanged(event) {}
+ gestureEnded(event) {}
+ enterPossibleState() {
+ this.state = GestureRecognizer.States.Possible;
+ }
+ enterBeganState() {
+ if (
+ this.delegate &&
+ typeof this.delegate.gestureRecognizerShouldBegin === "function" &&
+ !this.delegate.gestureRecognizerShouldBegin(this)
+ ) {
+ this.enterFailedState();
+ return;
+ }
+ this.state = GestureRecognizer.States.Began;
+ }
+ enterEndedState() {
+ this.state = GestureRecognizer.States.Ended;
+ this._removeTrackingListeners();
+ this.reset();
+ }
+ enterCancelledState() {
+ this.state = GestureRecognizer.States.Cancelled;
+ this._removeTrackingListeners();
+ this.reset();
+ }
+ enterFailedState() {
+ this.state = GestureRecognizer.States.Failed;
+ this._removeTrackingListeners();
+ this.reset();
+ }
+ enterChangedState() {
+ this.state = GestureRecognizer.States.Changed;
+ }
+ enterRecognizedState() {
+ this.state = GestureRecognizer.States.Recognized;
+ }
+ handleEvent(event) {
+ this._updateTargetTouches(event);
+ this._updateKeyboardModifiers(event);
+ switch (event.type) {
+ case GestureRecognizer.Events.PointerDown:
+ this.touchesBegan(event);
+ break;
+ case GestureRecognizer.Events.PointerMove:
+ this.touchesMoved(event);
+ break;
+ case GestureRecognizer.Events.PointerUp:
+ this.touchesEnded(event);
+ break;
+ case GestureRecognizer.Events.PointerCancel:
+ this.touchesCancelled(event);
+ break;
+ case GestureRecognizer.Events.GestureStart:
+ this.gestureBegan(event);
+ break;
+ case GestureRecognizer.Events.GestureChange:
+ this.gestureChanged(event);
+ break;
+ case GestureRecognizer.Events.GestureEnd:
+ this.gestureEnded(event);
+ break;
+ }
+ }
+ _initRecognizer() {
+ this.reset();
+ this.state = GestureRecognizer.States.Possible;
+ this._updateBaseListeners();
+ }
+ _updateBaseListeners() {
+ if (!this._target) return;
+ if (this._enabled) {
+ this._target.addEventListener(GestureRecognizer.Events.PointerDown, this);
+ if (GestureRecognizer.SupportsGestures)
+ this._target.addEventListener(
+ GestureRecognizer.Events.GestureStart,
+ this,
+ );
+ } else {
+ this._target.removeEventListener(
+ GestureRecognizer.Events.PointerDown,
+ this,
+ );
+ if (GestureRecognizer.SupportsGestures)
+ this._target.removeEventListener(
+ GestureRecognizer.Events.GestureStart,
+ this,
+ );
+ }
+ }
+ get _captureTarget() {
+ if (GestureRecognizer.SupportsTouches) return this._target;
+ return window;
+ }
+ _removeTrackingListeners() {
+ this._captureTarget.removeEventListener(
+ GestureRecognizer.Events.PointerMove,
+ this,
+ true,
+ );
+ this._captureTarget.removeEventListener(
+ GestureRecognizer.Events.PointerUp,
+ this,
+ true,
+ );
+ this._captureTarget.removeEventListener(
+ GestureRecognizer.Events.PointerCancel,
+ this,
+ true,
+ );
+ this._target.removeEventListener(
+ GestureRecognizer.Events.GestureChange,
+ this,
+ true,
+ );
+ this._target.removeEventListener(
+ GestureRecognizer.Events.GestureEnd,
+ this,
+ true,
+ );
+ this._targetPointers = new Map();
+ }
+ _updateTargetTouches(event) {
+ if (!(event instanceof PointerEvent)) return;
+ if (event.type === GestureRecognizer.Events.PointerDown) {
+ this._targetPointers.set(event.pointerId, event);
+ return;
+ }
+ if (event.type === GestureRecognizer.Events.PointerMove) {
+ this._targetPointers.set(event.pointerId, event);
+ return;
+ }
+ this._targetPointers.delete(event.pointerId);
+ }
+ _updateKeyboardModifiers(event) {
+ this.modifierKeys.alt = event.altKey;
+ this.modifierKeys.ctrl = event.ctrlKey;
+ this.modifierKeys.meta = event.metaKey;
+ this.modifierKeys.shift = event.shiftKey;
+ }
+}
+GestureRecognizer.SupportsTouches = "createTouch" in document;
+GestureRecognizer.SupportsGestures = !!window.GestureEvent;
+GestureRecognizer.States = {
+ Possible: "possible",
+ Began: "began",
+ Changed: "changed",
+ Ended: "ended",
+ Cancelled: "cancelled",
+ Failed: "failed",
+ Recognized: "ended",
+};
+GestureRecognizer.Events = {
+ PointerDown: "pointerdown",
+ PointerMove: "pointermove",
+ PointerUp: "pointerup",
+ PointerCancel: "pointercancel",
+ GestureStart: "gesturestart",
+ GestureChange: "gesturechange",
+ GestureEnd: "gestureend",
+};
+const MOVE_TOLERANCE = GestureRecognizer.SupportsTouches ? 40 : 0;
+const WAITING_FOR_NEXT_TAP_TO_START_TIMEOUT = 350;
+const WAITING_FOR_TAP_COMPLETION_TIMEOUT = 750;
+class TapGestureRecognizer extends GestureRecognizer {
+ constructor(target, delegate) {
+ super(target, delegate);
+ this.numberOfTapsRequired = 1;
+ this.numberOfTouchesRequired = 1;
+ this.allowsRightMouseButton = false;
+ }
+ touchesBegan(event) {
+ if (event.currentTarget !== this.target) return;
+ if (event.button === 2 && !this.allowsRightMouseButton) return;
+ super.touchesBegan(event);
+ if (this.numberOfTouches !== this.numberOfTouchesRequired) {
+ this.enterFailedState();
+ return;
+ }
+ this._startPoint = super.locationInElement();
+ this._startClientPoint = super.locationInClient();
+ this._rewindTimer(WAITING_FOR_TAP_COMPLETION_TIMEOUT);
+ }
+ touchesMoved(event) {
+ const touchLocation = super.locationInElement();
+ const distance = Math.sqrt(
+ Math.pow(this._startPoint.x - touchLocation.x, 2) +
+ Math.pow(this._startPoint.y - touchLocation.y, 2),
+ );
+ if (distance > MOVE_TOLERANCE) this.enterFailedState();
+ }
+ touchesEnded(event) {
+ this._taps++;
+ if (this._taps === this.numberOfTapsRequired) {
+ event.preventDefault();
+ this.enterRecognizedState();
+ this.reset();
+ }
+ this._rewindTimer(WAITING_FOR_NEXT_TAP_TO_START_TIMEOUT);
+ }
+ reset() {
+ this._taps = 0;
+ this._clearTimer();
+ }
+ locationInElement(element) {
+ const p = this._startPoint || new DOMPoint();
+ if (!element) return p;
+ const wkPoint = window.webkitConvertPointFromPageToNode(
+ element,
+ new WebKitPoint(p.x, p.y),
+ );
+ return new DOMPoint(wkPoint.x, wkPoint.y);
+ }
+ locationInClient() {
+ return this._startClientPoint || new DOMPoint();
+ }
+ _clearTimer() {
+ window.clearTimeout(this._timerId);
+ delete this._timerId;
+ }
+ _rewindTimer(timeout) {
+ this._clearTimer();
+ this._timerId = window.setTimeout(this._timerFired.bind(this), timeout);
+ }
+ _timerFired() {
+ this.enterFailedState();
+ }
+}
+const MAXIMUM_TIME_FOR_RECORDING_GESTURES = 100;
+const MAXIMUM_DECELERATION_TIME = 500;
+class PinchGestureRecognizer extends GestureRecognizer {
+ constructor(target, delegate) {
+ super(target, delegate);
+ this.scaleThreshold = 0;
+ this._scaledMinimumAmount = false;
+ }
+ get velocity() {
+ const lastGesture = this._gestures[this._gestures.length - 1];
+ if (!lastGesture) return this._velocity;
+ const elapsedTime =
+ Date.now() -
+ (lastGesture.timeStamp + MAXIMUM_TIME_FOR_RECORDING_GESTURES);
+ if (elapsedTime <= 0) return this._velocity;
+ const f = Math.max(
+ (MAXIMUM_DECELERATION_TIME - elapsedTime) / MAXIMUM_DECELERATION_TIME,
+ 0,
+ );
+ return this._velocity * f;
+ }
+ touchesBegan(event) {
+ if (event.currentTarget !== this.target) return;
+ if (!GestureRecognizer.SupportsGestures) {
+ if (this.numberOfTouches > 2) {
+ this.enterFailedState();
+ return;
+ }
+ if (this.numberOfTouches !== 2) return;
+ this._startDistance = this._distance();
+
+ this._recordGesture(1);
+ this._scaledMinimumAmount = false;
+ this._updateStateWithEvent(event);
+ } else if (this.numberOfTouches !== 2) {
+ return;
+ }
+ super.touchesBegan(event);
+ }
+ touchesMoved(event) {
+ if (GestureRecognizer.SupportsGestures) return;
+ if (this.numberOfTouches !== 2) return;
+ this._updateStateWithEvent(event);
+ }
+ touchesEnded(event) {
+ if (GestureRecognizer.SupportsGestures) return;
+ if (this.numberOfTouches >= 2 || !this._startDistance) return;
+ if (this._scaledMinimumAmount) this.enterEndedState();
+ else this.enterFailedState();
+ }
+ gestureBegan(event) {
+ super.gestureBegan(event);
+
+ this._recordGesture(event.scale);
+ this._scaledMinimumAmount = false;
+ this._updateStateWithEvent(event);
+ event.preventDefault();
+ }
+ gestureChanged(event) {
+ event.preventDefault();
+ this._updateStateWithEvent(event);
+ }
+ gestureEnded(event) {
+ if (this._scaledMinimumAmount) this.enterEndedState();
+ else this.enterFailedState();
+ }
+ reset() {
+ this.scale = 1;
+ this._velocity = 0;
+ this._gestures = [];
+ delete this._startDistance;
+ }
+ _recordGesture(scale) {
+ const currentTime = Date.now();
+ const count = this._gestures.push({ scale: scale, timeStamp: currentTime });
+ if (count <= 2) return;
+ const scaleDirection =
+ this._gestures[count - 1].scale >= this._gestures[count - 2].scale;
+ let i = count - 3;
+ for (; i >= 0; --i) {
+ let gesture = this._gestures[i];
+ if (
+ currentTime - gesture.timeStamp > MAXIMUM_TIME_FOR_RECORDING_GESTURES ||
+ this._gestures[i + 1].scale >= gesture.scale !== scaleDirection
+ )
+ break;
+ }
+ if (i > 0) this._gestures = this._gestures.slice(i + 1);
+ }
+ _updateStateWithEvent(event) {
+ const scaleSinceStart = GestureRecognizer.SupportsGestures
+ ? event.scale
+ : this._distance() / this._startDistance;
+ if (!this._scaledMinimumAmount) {
+ if (Math.abs(1 - scaleSinceStart) >= this.scaleThreshold) {
+ this._scaledMinimumAmount = true;
+ this.scale = 1;
+ this.enterBeganState();
+ }
+ return;
+ }
+ this._recordGesture(scaleSinceStart);
+ const oldestGesture = this._gestures[0];
+ const ds = scaleSinceStart - oldestGesture.scale;
+ const dt = Date.now() - oldestGesture.timeStamp;
+ this._velocity = dt === 0 ? 0 : (ds / dt) * 1000;
+ this.scale *=
+ scaleSinceStart / this._gestures[this._gestures.length - 2].scale;
+ this.enterChangedState();
+ }
+ _distance() {
+ console.assert(this.numberOfTouches === 2);
+ const firstTouch = this._targetTouches[0];
+ const firstTouchPoint = new DOMPoint(firstTouch.pageX, firstTouch.pageY);
+ const secondTouch = this._targetTouches[1];
+ const secondTouchPoint = new DOMPoint(secondTouch.pageX, secondTouch.pageY);
+ return Math.sqrt(
+ Math.pow(firstTouchPoint.x - secondTouchPoint.x, 2) +
+ Math.pow(firstTouchPoint.y - secondTouchPoint.y, 2),
+ );
+ }
+}
+const scheduler = new (class {
+ constructor() {
+ this._frameID = -1;
+ this._layoutCallbacks = new Set();
+ }
+ get hasScheduledLayoutCallbacks() {
+ return this._frameID !== -1 || this._layoutCallbacks.size > 0;
+ }
+ scheduleLayout(callback) {
+ if (typeof callback !== "function") return;
+ this._layoutCallbacks.add(callback);
+ this._requestFrameIfNeeded();
+ }
+ unscheduleLayout(callback) {
+ if (typeof callback !== "function") return;
+ this._layoutCallbacks.delete(callback);
+ }
+ flushScheduledLayoutCallbacks() {
+ this._frameDidFire();
+ }
+ _requestFrameIfNeeded() {
+ if (this._frameID === -1 && this._layoutCallbacks.size > 0)
+ this._frameID = window.requestAnimationFrame(
+ this._frameDidFire.bind(this),
+ );
+ }
+ _frameDidFire() {
+ if (typeof scheduler.frameWillFire === "function")
+ scheduler.frameWillFire();
+ this._layout();
+ this._frameID = -1;
+ this._requestFrameIfNeeded();
+ if (typeof scheduler.frameDidFire === "function") scheduler.frameDidFire();
+ }
+ _layout() {
+ const layoutCallbacks = this._layoutCallbacks;
+ this._layoutCallbacks = new Set();
+ for (let callback of layoutCallbacks) callback();
+ }
+})();
+class LayoutTraits {
+ constructor(mode) {
+ this._mode = mode;
+ }
+ get mode() {
+ return this._mode;
+ }
+ get isFullscreen() {
+ return (
+ this._mode == LayoutTraits.Mode.Fullscreen ||
+ this._mode == LayoutTraits.Mode.NarrowViewer
+ );
+ }
+ mediaControlsClass() {
+ throw "Derived class must implement this function.";
+ }
+ supportingObjectClasses() {
+ return [
+ AirplaySupport,
+ AudioSupport,
+ CloseSupport,
+ ControlsVisibilitySupport,
+ FullscreenSupport,
+ MuteSupport,
+ OverflowSupport,
+ PiPSupport,
+ PlacardSupport,
+ PlaybackSupport,
+ ScrubbingSupport,
+ SeekBackwardSupport,
+ SeekForwardSupport,
+ SkipBackSupport,
+ SkipForwardSupport,
+ StartSupport,
+ StatusSupport,
+ TimeControlSupport,
+ TracksSupport,
+ VolumeSupport,
+ ];
+ }
+ resourceDirectory() {
+ throw "Derived class must implement this function.";
+ }
+ controlsNeverAvailable() {
+ throw "Derived class must implement this function.";
+ }
+ supportsIconWithFullscreenVariant() {
+ throw "Derived class must implement this function.";
+ }
+ supportsDurationTimeLabel() {
+ throw "Derived class must implement this function.";
+ }
+ skipDuration() {
+ throw "Derived class must implement this function.";
+ }
+ controlsDependOnPageScaleFactor() {
+ throw "Derived class must implement this function.";
+ }
+ promoteSubMenusWhenShowingMediaControlsContextMenu() {
+ throw "Derived class must implement this function.";
+ }
+ supportsTouches() {
+ return GestureRecognizer.SupportsTouches;
+ }
+ supportsAirPlay() {
+ throw "Derived class must implement this function.";
+ }
+ supportsPiP() {
+ throw "Derived class must implement this function.";
+ }
+ inheritsBorderRadius() {
+ throw "Derived class must implement this function.";
+ }
+}
+LayoutTraits.Mode = { Inline: 0, Fullscreen: 1, NarrowViewer: 2 };
+window.layoutTraitsClasses = {};
+const dirtyNodes = new Set();
+const nodesRequiringChildrenUpdate = new Set();
+class LayoutNode {
+ constructor(stringOrElement) {
+ if (!stringOrElement) this.element = document.createElement("div");
+ else if (stringOrElement instanceof Element) this.element = stringOrElement;
+ else if (
+ typeof stringOrElement === "string" ||
+ stringOrElement instanceof String
+ )
+ this.element = elementFromString(stringOrElement);
+ this._parent = null;
+ this._children = [];
+ this._x = 0;
+ this._y = 0;
+ this._width = 0;
+ this._height = 0;
+ this._visible = true;
+ this._needsLayout = false;
+ this._dirtyProperties = new Set();
+ this._pendingDOMManipulation = LayoutNode.DOMManipulation.None;
+ }
+ get x() {
+ return this._x;
+ }
+ set x(x) {
+ if (x === this._x) return;
+ this._x = x;
+ this.markDirtyProperty("x");
+ }
+ get y() {
+ return this._y;
+ }
+ set y(y) {
+ if (y === this._y) return;
+ this._y = y;
+ this.markDirtyProperty("y");
+ }
+ get width() {
+ return this._width;
+ }
+ set width(width) {
+ if (width === this._width) return;
+ this._width = width;
+ this.markDirtyProperty("width");
+ this.layout();
+ }
+ get height() {
+ return this._height;
+ }
+ set height(height) {
+ if (height === this._height) return;
+ this._height = height;
+ this.markDirtyProperty("height");
+ this.layout();
+ }
+ get visible() {
+ return this._visible;
+ }
+ set visible(flag) {
+ if (flag === this._visible) return;
+ this._visible = flag;
+ this.markDirtyProperty("visible");
+ }
+ get needsLayout() {
+ return (
+ this._needsLayout ||
+ this._pendingDOMManipulation !== LayoutNode.DOMManipulation.None ||
+ this._dirtyProperties.size > 0
+ );
+ }
+ set needsLayout(flag) {
+ if (this.needsLayout === flag) return;
+ this._needsLayout = flag;
+ this._updateDirtyState();
+ }
+ get parent() {
+ return this._parent;
+ }
+ get children() {
+ return this._children;
+ }
+ set children(children) {
+ if (children.length === this._children.length) {
+ let arraysDiffer = false;
+ for (let i = children.length - 1; i >= 0; --i) {
+ if (children[i] !== this._children[i]) {
+ arraysDiffer = true;
+ break;
+ }
+ }
+ if (!arraysDiffer) return;
+ }
+ this._updatingChildren = true;
+ while (this._children.length) this.removeChild(this._children[0]);
+ for (let child of children) this.addChild(child);
+ delete this._updatingChildren;
+ this.didChangeChildren();
+ }
+ parentOfType(type) {
+ let node = this;
+ while ((node = node._parent)) {
+ if (node instanceof type) return node;
+ }
+ return null;
+ }
+ addChild(child, index) {
+ child.remove();
+ if (index === undefined || index < 0 || index > this._children.length)
+ index = this._children.length;
+ this._children.splice(index, 0, child);
+ child._parent = this;
+ if (!this._updatingChildren) this.didChangeChildren();
+ child._markNodeManipulation(LayoutNode.DOMManipulation.Addition);
+ return child;
+ }
+ insertBefore(newSibling, referenceSibling) {
+ return this.addChild(newSibling, this._children.indexOf(referenceSibling));
+ }
+ insertAfter(newSibling, referenceSibling) {
+ const index = this._children.indexOf(referenceSibling);
+ return this.addChild(newSibling, index + 1);
+ }
+ removeChild(child) {
+ if (child._parent !== this) return;
+ const index = this._children.indexOf(child);
+ if (index === -1) return;
+ this.willRemoveChild(child);
+ this._children.splice(index, 1);
+ child._parent = null;
+ if (!this._updatingChildren) this.didChangeChildren();
+ child._markNodeManipulation(LayoutNode.DOMManipulation.Removal);
+ return child;
+ }
+ remove() {
+ if (this._parent instanceof LayoutNode)
+ return this._parent.removeChild(this);
+ }
+ markDirtyProperty(propertyName) {
+ const hadProperty = this._dirtyProperties.has(propertyName);
+ this._dirtyProperties.add(propertyName);
+ if (!hadProperty) this._updateDirtyState();
+ }
+ computedValueForStyleProperty(propertyName) {
+ return window.getComputedStyle(this.element).getPropertyValue(propertyName);
+ }
+ computedValueForStylePropertyInPx(propertyName) {
+ const value = this.computedValueForStyleProperty(propertyName);
+ if (!value) return 0;
+ if (!value.endsWith("px")) return 0;
+ return parseFloat(value);
+ }
+ layout() {}
+ commit() {
+ if (this._pendingDOMManipulation === LayoutNode.DOMManipulation.Removal) {
+ const parent = this.element.parentNode;
+ if (parent) parent.removeChild(this.element);
+ }
+ for (let propertyName of this._dirtyProperties)
+ this.commitProperty(propertyName);
+ this._dirtyProperties.clear();
+ if (this._pendingDOMManipulation === LayoutNode.DOMManipulation.Addition)
+ nodesRequiringChildrenUpdate.add(this.parent);
+ }
+ commitProperty(propertyName) {
+ const style = this.element.style;
+ switch (propertyName) {
+ case "x":
+ style.left = `${this._x}px`;
+ break;
+ case "y":
+ style.top = `${this._y}px`;
+ break;
+ case "width":
+ style.width = `${this._width}px`;
+ break;
+ case "height":
+ style.height = `${this._height}px`;
+ break;
+ case "visible":
+ if (this._visible) style.removeProperty("display");
+ else style.display = "none";
+ break;
+ }
+ }
+ willRemoveChild(child) {}
+ didChangeChildren() {}
+ _markNodeManipulation(manipulation) {
+ this._pendingDOMManipulation = manipulation;
+ this._updateDirtyState();
+ }
+ _updateDirtyState() {
+ if (this.needsLayout) {
+ dirtyNodes.add(this);
+ scheduler.scheduleLayout(performScheduledLayout);
+ } else {
+ dirtyNodes.delete(this);
+ if (dirtyNodes.size === 0)
+ scheduler.unscheduleLayout(performScheduledLayout);
+ }
+ }
+ _updateChildren() {
+ let nextChildElement = null;
+ const element = this.element;
+ for (let i = this.children.length - 1; i >= 0; --i) {
+ let child = this.children[i];
+ let childElement = child.element;
+ if (
+ child._pendingDOMManipulation === LayoutNode.DOMManipulation.Addition
+ ) {
+ element.insertBefore(childElement, nextChildElement);
+ child._pendingDOMManipulation = LayoutNode.DOMManipulation.None;
+ }
+ nextChildElement = childElement;
+ }
+ }
+}
+LayoutNode.DOMManipulation = { None: 0, Removal: 1, Addition: 2 };
+function performScheduledLayout() {
+ const previousDirtyNodes = Array.from(dirtyNodes);
+ dirtyNodes.clear();
+ previousDirtyNodes.forEach((node) => {
+ node._needsLayout = false;
+ node.layout();
+ node.commit();
+ });
+ nodesRequiringChildrenUpdate.forEach((node) => node._updateChildren());
+ nodesRequiringChildrenUpdate.clear();
+}
+function elementFromString(elementString) {
+ const element = document.createElement("div");
+ element.innerHTML = elementString;
+ return element.firstElementChild;
+}
+class LayoutItem extends LayoutNode {
+ constructor({ element = null, layoutDelegate = null } = {}) {
+ super(element);
+ this.layoutDelegate = layoutDelegate;
+ }
+ get layoutTraits() {
+ if (!this.layoutDelegate?.layoutTraits)
+ throw "No layout traits specified via layoutDelegate or overriden layouTraits() getter";
+ return this.layoutDelegate.layoutTraits;
+ }
+}
+const Icons = {
+ Airplay: { name: "Airplay", type: "svg", label: UIString("AirPlay") },
+ AirplayPlacard: {
+ name: "airplay-placard",
+ type: "png",
+ label: UIString("AirPlay"),
+ },
+ Close: { name: "X", type: "svg", label: UIString("Close") },
+ Ellipsis: { name: "Ellipsis", type: "svg", label: UIString("More\u2026") },
+ EnterFullscreen: {
+ name: "EnterFullscreen",
+ type: "svg",
+ label: UIString("Enter Full Screen"),
+ },
+ EnterPiP: {
+ name: "PipIn",
+ type: "svg",
+ label: UIString("Enter Picture in Picture"),
+ },
+ ExitFullscreen: {
+ name: "ExitFullscreen",
+ type: "svg",
+ label: UIString("Exit Full Screen"),
+ },
+ Forward: { name: "Forward", type: "svg", label: UIString("Forward") },
+ InvalidCircle: {
+ name: "InvalidCircle",
+ type: "pdf",
+ label: UIString("Invalid"),
+ },
+ InvalidPlacard: {
+ name: "invalid-placard",
+ type: "png",
+ label: UIString("Invalid"),
+ },
+ Overflow: { name: "Overflow", type: "svg", label: UIString("More\u2026") },
+ Pause: { name: "Pause", type: "svg", label: UIString("Pause") },
+ PiPPlacard: {
+ name: "pip-placard",
+ type: "png",
+ label: UIString("Picture in Picture"),
+ },
+ Play: { name: "Play", type: "svg", label: UIString("Play") },
+ PlayCircle: { name: "PlayCircle", type: "pdf", label: UIString("Play") },
+ Rewind: { name: "Rewind", type: "svg", label: UIString("Rewind") },
+ SkipBack10: {
+ name: "SkipBack10",
+ type: "svg",
+ label: UIString("Skip Back 10 Seconds"),
+ },
+ SkipBack15: {
+ name: "SkipBack15",
+ type: "svg",
+ label: UIString("Skip Back 15 Seconds"),
+ },
+ SkipForward10: {
+ name: "SkipForward10",
+ type: "svg",
+ label: UIString("Skip Forward 10 Seconds"),
+ },
+ SkipForward15: {
+ name: "SkipForward15",
+ type: "svg",
+ label: UIString("Skip Forward 15 Seconds"),
+ },
+ SpinnerSprite: {
+ name: "SpinnerSprite",
+ type: "png",
+ label: UIString("Loading\u2026"),
+ },
+ Tracks: {
+ name: "MediaSelector",
+ type: "svg",
+ label: UIString("Media Selection"),
+ },
+ Volume0: { name: "Volume0", type: "svg", label: UIString("Mute") },
+ Volume0RTL: { name: "Volume0-RTL", type: "svg", label: UIString("Mute") },
+ Volume1: { name: "Volume1", type: "svg", label: UIString("Mute") },
+ Volume1RTL: { name: "Volume1-RTL", type: "svg", label: UIString("Mute") },
+ Volume2: { name: "Volume2", type: "svg", label: UIString("Mute") },
+ Volume2RTL: { name: "Volume2-RTL", type: "svg", label: UIString("Mute") },
+ Volume3: { name: "Volume3", type: "svg", label: UIString("Mute") },
+ Volume3RTL: { name: "Volume3-RTL", type: "svg", label: UIString("Mute") },
+ VolumeMuted: { name: "VolumeMuted", type: "svg", label: UIString("Unmute") },
+ VolumeMutedRTL: {
+ name: "VolumeMuted-RTL",
+ type: "svg",
+ label: UIString("Unmute"),
+ },
+};
+const MimeTypes = {
+ pdf: "application/pdf",
+ png: "image/png",
+ svg: "image/svg+xml",
+};
+const IconsWithFullscreenVariants = [
+ Icons.Airplay,
+ Icons.Tracks,
+ Icons.EnterPiP,
+];
+const iconService = new (class IconService {
+ constructor() {
+ this.images = {};
+ }
+ imageForIconAndLayoutTraits(icon, layoutTraits) {
+ const [fileName, resourceDirectory] =
+ this._fileNameAndResourceDirectoryForIconAndLayoutTraits(
+ icon,
+ layoutTraits,
+ );
+ const path = `${resourceDirectory}/${fileName}.${icon.type}`;
+ let image = this.images[path];
+ if (image) return image;
+ if (utils?.createImageForIconNameAndType)
+ image = this.images[path] = utils.createImageForIconNameAndType(
+ fileName,
+ icon.type,
+ );
+ else {
+ image = this.images[path] = new Image();
+ image.src = `${this.directoryPath}/${path}`;
+ }
+ return image;
+ }
+ _fileNameAndResourceDirectoryForIconAndLayoutTraits(icon, layoutTraits) {
+ let resourceDirectory = layoutTraits.resourceDirectory();
+ let iconName = icon.name;
+ if (
+ layoutTraits.supportsIconWithFullscreenVariant() &&
+ IconsWithFullscreenVariants.includes(icon)
+ )
+ iconName += "-fullscreen";
+ let fileName = iconName;
+ if (icon.type === "png")
+ fileName = `${iconName}@${window.devicePixelRatio}x`;
+ return [fileName, resourceDirectory];
+ }
+})();
+class BackgroundTint extends LayoutNode {
+ constructor() {
+ super(
+ ``,
+ );
+ }
+}
+const TenMinutes = 10 * 60;
+const OneHour = 6 * TenMinutes;
+const TenHours = 10 * OneHour;
+const MinimumTimeControlWidth = 160;
+const IdealMinimumTimeControlWidth = 200;
+class TimeControl extends LayoutItem {
+ constructor(layoutDelegate) {
+ super({ element: ``, layoutDelegate });
+ this.style = TimeControl.Style.Side;
+ this._shouldShowDurationTimeLabel =
+ this.layoutTraits.supportsDurationTimeLabel();
+ this.elapsedTimeLabel = new TimeLabel(TimeLabel.Type.Elapsed);
+ this.scrubber = new Slider(this.layoutDelegate, "scrubber");
+ this.durationTimeLabel = new TimeLabel(TimeLabel.Type.Duration);
+ this.remainingTimeLabel = new TimeLabel(TimeLabel.Type.Remaining);
+ this.activityIndicator = new LayoutNode(
+ ``,
+ );
+ for (let segmentClassName of ["n", "ne", "e", "se", "s", "sw", "w", "nw"])
+ this.activityIndicator.element.appendChild(
+ document.createElement("div"),
+ ).className = segmentClassName;
+ this._duration = 0;
+ this._currentTime = 0;
+ this._loading = false;
+ this._supportsSeeking = true;
+ if (this._shouldShowDurationTimeLabel) {
+ this.element.classList.add("duration");
+ this.durationTimeLabel.element.addEventListener("click", this);
+ this.remainingTimeLabel.element.addEventListener("click", this);
+ }
+ this.needsLayout = true;
+ }
+ set duration(duration) {
+ if (this._duration === duration) return;
+ this._duration = duration;
+ this.needsLayout = true;
+ }
+ set currentTime(currentTime) {
+ if (this._currentTime === currentTime) return;
+ this._currentTime = currentTime;
+ this.needsLayout = true;
+ }
+ get loading() {
+ return this._loading;
+ }
+ set loading(flag) {
+ if (this._loading === flag) return;
+ this._loading = flag;
+ this.scrubber.disabled = this._loading || !this._supportsSeeking;
+ this.needsLayout = true;
+ }
+ get supportsSeeking() {
+ return this._supportsSeeking;
+ }
+ set supportsSeeking(flag) {
+ if (this._supportsSeeking === flag) return;
+ this._supportsSeeking = flag;
+ this.scrubber.disabled = this._loading || !this._supportsSeeking;
+ this.needsLayout = true;
+ }
+ get minimumWidth() {
+ return MinimumTimeControlWidth;
+ }
+ get idealMinimumWidth() {
+ return IdealMinimumTimeControlWidth;
+ }
+ layout() {
+ super.layout();
+ this._performIdealLayout();
+ }
+ handleEvent(event) {
+ switch (event.type) {
+ case "click":
+ switch (event.target) {
+ case this.durationTimeLabel.element:
+ case this.remainingTimeLabel.element:
+ this._toggleDurationRemainingLabel();
+ break;
+ }
+ }
+ }
+ _performIdealLayout() {
+ let children = [
+ this._loading ? this.activityIndicator : this.elapsedTimeLabel,
+ this.scrubber,
+ this.remainingTimeLabel,
+ ];
+ if (this._shouldShowDurationTimeLabel)
+ children.push(this.durationTimeLabel);
+ this.children = children;
+ if (this._loading) {
+ this.durationTimeLabel.value = NaN;
+ this.remainingTimeLabel.value = NaN;
+ } else {
+ const shouldShowZeroDurations =
+ isNaN(this._duration) || this._duration > maxNonLiveDuration;
+ if (shouldShowZeroDurations) {
+ this.elapsedTimeLabel.value = 0;
+ this.durationTimeLabel.value = 0;
+ this.remainingTimeLabel.value = 0;
+ this.elapsedTimeLabel.numberOfDigits = 4;
+ this.durationTimeLabel.numberOfDigits = 4;
+ this.remainingTimeLabel.numberOfDigits = 4;
+ } else {
+ let numberOfDigitsForTimeLabels;
+ if (this._duration < OneHour) numberOfDigitsForTimeLabels = 4;
+ else if (this._duration < TenHours) numberOfDigitsForTimeLabels = 5;
+ else numberOfDigitsForTimeLabels = 6;
+ this.elapsedTimeLabel.value = this._currentTime;
+ this.durationTimeLabel.value = this._duration;
+ this.remainingTimeLabel.value = this._currentTime - this._duration;
+ this.elapsedTimeLabel.numberOfDigits = numberOfDigitsForTimeLabels;
+ this.durationTimeLabel.numberOfDigits = numberOfDigitsForTimeLabels;
+ this.remainingTimeLabel.numberOfDigits = numberOfDigitsForTimeLabels;
+ }
+ }
+ if (this._duration)
+ this.scrubber.value = this._currentTime / this._duration;
+ }
+ updateScrubberLabel() {
+ this.scrubber.inputAccessibleLabel = this.elapsedTimeLabel.value;
+ }
+ _toggleDurationRemainingLabel() {
+ if (!this._shouldShowDurationTimeLabel) return;
+ this.element.classList.toggle("duration");
+ this.element.classList.toggle("remaining");
+ }
+}
+TimeControl.Style = { Above: "above", Side: "side", Below: "below" };
+const MinusSignWidthsForDigits = { 3: 6, 4: 5, 5: 6, 6: 5 };
+const WidthsForDigits = { 3: 27, 4: 35, 5: 46, 6: 54 };
+class TimeLabel extends LayoutNode {
+ constructor(type) {
+ super(``);
+ this._type = type;
+ this.value = 0;
+ this.numberOfDigits = 4;
+ switch (this._type) {
+ case TimeLabel.Type.Elapsed:
+ this.element.setAttribute("id", "time-label-elapsed");
+ break;
+ case TimeLabel.Type.Remaining:
+ this.element.setAttribute("id", "time-label-remaining");
+ break;
+ case TimeLabel.Type.Duration:
+ this.element.setAttribute("id", "time-label-duration");
+ break;
+ }
+ }
+ get value() {
+ return this._value;
+ }
+ set value(value) {
+ if (value === this._value || (isNaN(value) && isNaN(this._value))) return;
+ this._value = value;
+ this.markDirtyProperty("value");
+ }
+ get numberOfDigits() {
+ return this._numberOfDigits;
+ }
+ set numberOfDigits(numberOfDigits) {
+ if (this._numberOfDigits === numberOfDigits) return;
+ if (numberOfDigits < 4 || numberOfDigits > 6)
+ throw new RangeError("TimeLabel numerOfDigits must be between 4 and 6.");
+ this._numberOfDigits = numberOfDigits;
+ let formatterOptions = {
+ style: "digital",
+ fractionalDigits: 0,
+ hoursDisplay: "auto",
+ minutesDisplay: "always",
+ secondsDisplay: "always",
+ };
+ if (numberOfDigits >= 5) formatterOptions.hoursDisplay = "always";
+ if (numberOfDigits == 6) formatterOptions.hours = "2-digit";
+ this._formatter = new Intl.DurationFormat(undefined, formatterOptions);
+ this.markDirtyProperty("value");
+ }
+ setValueWithNumberOfDigits(value, numberOfDigits) {
+ this.value = value;
+ this.numberOfDigits = numberOfDigits;
+ }
+ commitProperty(propertyName) {
+ if (propertyName === "value") {
+ this.element.textContent = this._formattedTime();
+ const timeAsString = utils.formattedStringForDuration(this.value);
+ switch (this._type) {
+ case TimeLabel.Type.Elapsed:
+ this.element.setAttribute(
+ "aria-label",
+ UIString("Elapsed: %s", timeAsString),
+ );
+ break;
+ case TimeLabel.Type.Remaining:
+ this.element.setAttribute(
+ "aria-label",
+ UIString("Remaining: %s", timeAsString),
+ );
+ break;
+ case TimeLabel.Type.Duration:
+ this.element.setAttribute(
+ "aria-label",
+ UIString("Duration: %s", timeAsString),
+ );
+ break;
+ }
+ if (this.parent instanceof TimeControl) this.parent.updateScrubberLabel();
+ } else super.commitProperty(propertyName);
+ }
+ _formattedTime() {
+ if (isNaN(this._value)) return "--:--";
+ return this._formatter.format(formatTimeByUnit(this._value));
+ }
+}
+function doubleDigits(x) {
+ if (x < 10) return `0${x}`;
+ return `${x}`;
+}
+TimeLabel.Type = { Elapsed: 0, Remaining: 1, Duration: 2 };
+class SliderBase extends LayoutNode {
+ constructor(layoutDelegate, cssClassName = "") {
+ super(``);
+ console.assert(
+ this.constructor !== SliderBase && this instanceof SliderBase,
+ this,
+ );
+ this._layoutDelegate = layoutDelegate;
+ this.appearanceContainer = new LayoutNode(``);
+ this._input = new LayoutNode(
+ ``,
+ );
+ this._input.element.addEventListener("pointerdown", this);
+ this._input.element.addEventListener("input", this);
+ this._input.element.addEventListener("change", this);
+ this.value = 0;
+ this.enabled = true;
+ this.isActive = false;
+ this._disabled = false;
+ this._secondaryValue = 0;
+ this._allowsRelativeScrubbing = false;
+ this._startValue = NaN;
+ this._startPosition = NaN;
+ this.children = [this.appearanceContainer, this._input];
+ }
+ set inputAccessibleLabel(timeValue) {
+ this._input.element.setAttribute(
+ "aria-valuetext",
+ utils.formattedStringForDuration(timeValue),
+ );
+ }
+ get disabled() {
+ return this._disabled;
+ }
+ set disabled(flag) {
+ if (this._disabled === flag) return;
+ this._disabled = flag;
+ this.markDirtyProperty("disabled");
+ }
+ get value() {
+ if (this._value !== undefined) return this._value;
+ return parseFloat(this._input.element.value);
+ }
+ set value(value) {
+ if (this._animatedValue) delete this._animatedValue;
+ this._setValueInternal(value);
+ }
+ setValueAnimated(value) {
+ if (this.isActive || this._value == value) return;
+ this._valueAnimation = {
+ start: this.value,
+ end: value,
+ startTime: window.performance.now(),
+ };
+ const duration = 150;
+ const animate = (currentTime) => {
+ if (!this._valueAnimation) return;
+ const elapsedTime = currentTime - this._valueAnimation.startTime;
+ const progress = Math.min(elapsedTime / duration, 1);
+ const animatedValue =
+ this._valueAnimation.start +
+ (this._valueAnimation.end - this._valueAnimation.start) * progress;
+ this._setValueInternal(animatedValue);
+ if (progress == 1) delete this._valueAnimation;
+ else requestAnimationFrame(animate);
+ };
+ requestAnimationFrame(animate);
+ }
+ _setValueInternal(value) {
+ if (this.isActive || this._value == value) return;
+ this._value = value;
+ this.markDirtyProperty("value");
+ this.needsLayout = true;
+ }
+ get secondaryValue() {
+ return this._secondaryValue;
+ }
+ set secondaryValue(secondaryValue) {
+ if (this._secondaryValue === secondaryValue) return;
+ this._secondaryValue = secondaryValue;
+ this.needsLayout = true;
+ }
+ get allowsRelativeScrubbing() {
+ return this._allowsRelativeScrubbing;
+ }
+ set allowsRelativeScrubbing(allowsRelativeScrubbing) {
+ this._allowsRelativeScrubbing = !!allowsRelativeScrubbing;
+ this.element.classList.toggle(
+ "allows-relative-scrubbing",
+ this._allowsRelativeScrubbing,
+ );
+ }
+ handleEvent(event) {
+ switch (event.type) {
+ case "pointerdown":
+ this._handlePointerdownEvent(event);
+ return;
+ case "pointermove":
+ this._handlePointermoveEvent(event);
+ return;
+ case "pointerup":
+ this._handlePointerupEvent(event);
+ return;
+ case "change":
+ case "input":
+ this._valueDidChange();
+ return;
+ }
+ }
+ commitProperty(propertyName) {
+ switch (propertyName) {
+ case "value":
+ this._input.element.value = this._value;
+ delete this._value;
+ break;
+ case "disabled":
+ this.element.classList.toggle("disabled", this._disabled);
+ break;
+ default:
+ super.commitProperty(propertyName);
+ break;
+ }
+ }
+ _handlePointerdownEvent(event) {
+ delete this._valueAnimation;
+ this._pointerupTarget = this._interactionEndTarget();
+ this._pointerupTarget.addEventListener("pointerup", this, {
+ capture: true,
+ });
+ if (this._allowsRelativeScrubbing)
+ this._pointerupTarget.addEventListener("pointermove", this, {
+ capture: true,
+ });
+ delete this._value;
+ if (this._allowsRelativeScrubbing) {
+ this._startValue = parseFloat(this._input.element.value);
+ this._startPosition = this._playbackProgress(event.pageX);
+ }
+ if (
+ this.uiDelegate &&
+ typeof this.uiDelegate.controlValueWillStartChanging === "function"
+ )
+ this.uiDelegate.controlValueWillStartChanging(this);
+ this.isActive = true;
+ this.appearanceContainer.element.classList.add("changing");
+ this.needsLayout = true;
+ }
+ _interactionEndTarget() {
+ const mediaControls = this.parentOfType(MediaControls);
+ if (mediaControls?.layoutTraits.supportsTouches())
+ return mediaControls.element;
+ return !mediaControls || !mediaControls.layoutTraits.isFullscreen
+ ? window
+ : mediaControls.element;
+ }
+ _valueDidChange() {
+ if (
+ this.uiDelegate &&
+ typeof this.uiDelegate.controlValueDidChange === "function"
+ )
+ this.uiDelegate.controlValueDidChange(this);
+ this.needsLayout = true;
+ }
+ _handlePointermoveEvent(event) {
+ if (
+ !this._allowsRelativeScrubbing ||
+ isNaN(this._startValue) ||
+ isNaN(this._startPosition)
+ )
+ return;
+ let value =
+ this._startValue +
+ this._playbackProgress(event.pageX) -
+ this._startPosition;
+ this._input.element.value = Math.min(Math.max(0, value), 1);
+ this._valueDidChange();
+ }
+ _handlePointerupEvent(event) {
+ this._pointerupTarget.removeEventListener("pointerup", this, {
+ capture: true,
+ });
+ this._pointerupTarget.removeEventListener("pointermove", this, {
+ capture: true,
+ });
+ delete this._pointerupTarget;
+ this._startValue = NaN;
+ this._startPosition = NaN;
+ this.isActive = false;
+ this.appearanceContainer.element.classList.remove("changing");
+ if (
+ this.uiDelegate &&
+ typeof this.uiDelegate.controlValueDidStopChanging === "function"
+ )
+ this.uiDelegate.controlValueDidStopChanging(this);
+ this.needsLayout = true;
+ }
+ _playbackProgress(pageX) {
+ let x = window.webkitConvertPointFromPageToNode(
+ this.element,
+ new WebKitPoint(pageX, 0),
+ ).x;
+ if (this._layoutDelegate?.scaleFactor)
+ x *= this._layoutDelegate.scaleFactor;
+ return x / this.element.clientWidth;
+ }
+}
+class Slider extends SliderBase {
+ constructor(
+ layoutDelegate,
+ cssClassName = "",
+ knobStyle = Slider.KnobStyle.Circle,
+ ) {
+ super(layoutDelegate, `default ${cssClassName}`);
+ this._primaryFill = new LayoutNode(``);
+ this._trackFill = new LayoutNode(``);
+ this._secondaryFill = new LayoutNode(``);
+ this._trackFill.children = [this._secondaryFill];
+ let fillContainer = new LayoutNode(``);
+ this._knob = new LayoutNode(``);
+ fillContainer.children = [this._primaryFill, this._knob, this._trackFill];
+ this.appearanceContainer.children = [fillContainer];
+ this.height = 16;
+ this._knobStyle = knobStyle;
+ }
+ get knobStyle() {
+ return this._knobStyle;
+ }
+ set knobStyle(knobStyle) {
+ if (this._knobStyle === knobStyle) return;
+ this._knob.element.classList.remove(this._knobStyle);
+ this._knobStyle = knobStyle;
+ this._knob.element.classList.add(this._knobStyle);
+ this.needsLayout = true;
+ }
+ commit() {
+ super.commit();
+ this._primaryFill.element.style.flexGrow = 100 * this.value;
+ this._trackFill.element.style.flexGrow = 100 * (1 - this.value);
+ }
+}
+Slider.KnobStyle = { Circle: "circle", Bar: "bar", None: "none", Pill: "pill" };
+class Button extends LayoutItem {
+ constructor({
+ layoutDelegate = null,
+ cssClassName = "",
+ iconName = "",
+ } = {}) {
+ super({ element: "", layoutDelegate });
+ if (!!cssClassName) this.element.classList.add(cssClassName);
+ this.style = Button.Styles.Bar;
+ this.image = this.addChild(new LayoutNode(``));
+ this._scaleFactor = 1;
+ this._imageSource = null;
+ this._iconName = "";
+ if (!!iconName) this.iconName = iconName;
+ this._enabled = true;
+ if (this.layoutTraits.supportsTouches())
+ this._tapGestureRecognizer = new TapGestureRecognizer(this.element, this);
+ else this.element.addEventListener("click", this);
+ }
+ get enabled() {
+ return this._enabled;
+ }
+ set enabled(flag) {
+ if (this._enabled === flag) return;
+ this._enabled = flag;
+ if (this.layoutDelegate && typeof this.layoutDelegate.layout === "function")
+ this.layoutDelegate.layout();
+ }
+ get iconName() {
+ return this._iconName;
+ }
+ set iconName(iconName) {
+ if (this._iconName === iconName) return;
+ this._loadImage(iconName);
+ this.element.setAttribute("aria-label", iconName.label);
+ this.element.setAttribute("id", iconName.name);
+ }
+ get on() {
+ return this.element.classList.contains("on");
+ }
+ set on(flag) {
+ this.element.classList.toggle("on", flag);
+ }
+ get style() {
+ return this._style;
+ }
+ set style(style) {
+ if (style === this._style) return;
+ this.element.classList.remove(this._style);
+ this.element.classList.add(style);
+ this._style = style;
+ if (style === Button.Styles.Bar && this.children.length == 2)
+ this.children[0].remove();
+ else if (this.children.length == 1) this.addChild(new BackgroundTint(), 0);
+ }
+ get scaleFactor() {
+ return this._scaleFactor;
+ }
+ set scaleFactor(scaleFactor) {
+ if (this._scaleFactor === scaleFactor) return;
+ this._scaleFactor = scaleFactor;
+ this._updateImageMetrics();
+ }
+ get contextMenuOptions() {
+ return {};
+ }
+ get circular() {
+ return this.element.classList.contains("circular");
+ }
+ set circular(circular) {
+ this.element.classList.toggle("circular", circular);
+ this._updateImageMetrics();
+ }
+ handleEvent(event) {
+ if (event.target === this._imageSource) {
+ if (event.type === "load") this._imageSourceDidLoad();
+ else if (event.type === "error")
+ console.error(
+ `Button failed to load, iconName = ${this._iconName.name}, layoutTraits = ${this.layoutTraits}, src = ${this._imageSource.src}`,
+ );
+ } else if (event.type === "click" && event.currentTarget === this.element)
+ this._notifyDelegateOfActivation();
+ }
+ gestureRecognizerStateDidChange(recognizer) {
+ if (
+ this._tapGestureRecognizer === recognizer &&
+ recognizer.state === GestureRecognizer.States.Recognized
+ )
+ this._notifyDelegateOfActivation();
+ }
+ commitProperty(propertyName) {
+ if (propertyName === "maskImage")
+ this.image.element.style.maskImage = `url(${this._imageSource.src})`;
+ else super.commitProperty(propertyName);
+ }
+ _notifyDelegateOfActivation() {
+ if (
+ this._enabled &&
+ this.uiDelegate &&
+ typeof this.uiDelegate.buttonWasPressed === "function"
+ )
+ this.uiDelegate.buttonWasPressed(this);
+ }
+ _loadImage(iconName) {
+ if (this._imageSource) this._imageSource.removeEventListener("load", this);
+ this._imageSource = iconService.imageForIconAndLayoutTraits(
+ iconName,
+ this.layoutTraits,
+ );
+ this._iconName = iconName;
+ if (this._imageSource.complete) this._updateImage();
+ else {
+ this._imageSource.addEventListener("load", this);
+ this._imageSource.addEventListener("error", this);
+ }
+ }
+ _imageSourceDidLoad() {
+ this._imageSource.removeEventListener("load", this);
+ this._updateImage();
+ }
+ _updateImage() {
+ this.markDirtyProperty("maskImage");
+ this._updateImageMetrics();
+ }
+ _updateImageMetrics() {
+ if (!this._imageSource) return;
+ let width = this._imageSource.width * this._scaleFactor;
+ let height = this._imageSource.height * this._scaleFactor;
+ if (this._iconName.type === "png" || this._iconName.type === "pdf") {
+ width /= window.devicePixelRatio;
+ height /= window.devicePixelRatio;
+ }
+ if (this.circular) {
+ width = Math.max(width, height);
+ height = width;
+ }
+ if (this.image.width === width && this.image.height === height) return;
+ this.image.width = width;
+ this.image.height = height;
+ this.width = width;
+ this.height = height;
+ if (this.layoutDelegate) this.layoutDelegate.needsLayout = true;
+ }
+}
+Button.Styles = {
+ Bar: "bar",
+ Corner: "corner",
+ Center: "center",
+ Rounded: "rounded",
+ SmallCenter: "small-center",
+};
+class PlayPauseButton extends Button {
+ constructor(layoutDelegate) {
+ super({ cssClassName: "play-pause", iconName: Icons.Play, layoutDelegate });
+ }
+ get playing() {
+ return this.iconName === Icons.Pause;
+ }
+ set playing(flag) {
+ if (this.playing === flag) return;
+ this.iconName = flag ? Icons.Pause : Icons.Play;
+ }
+ commit() {
+ super.commit();
+ this.element.classList.toggle("paused", !this.playing);
+ }
+}
+class SkipBackButton extends Button {
+ constructor(layoutDelegate) {
+ super({ cssClassName: "skip-back", layoutDelegate });
+ this.iconName = Icons["SkipBack" + this.layoutTraits.skipDuration()];
+ }
+}
+class SkipForwardButton extends Button {
+ constructor(layoutDelegate) {
+ super({ cssClassName: "skip-forward", layoutDelegate });
+ this.iconName = Icons["SkipForward" + this.layoutTraits.skipDuration()];
+ }
+}
+class MuteButton extends Button {
+ constructor(layoutDelegate) {
+ super({
+ cssClassName: "mute",
+ iconName: Icons.VolumeMutedRTL,
+ layoutDelegate,
+ });
+ this._volume = 1;
+ this._muted = true;
+ this._usesLTRUserInterfaceLayoutDirection = undefined;
+ }
+ get volume() {
+ return this._volume;
+ }
+ set volume(volume) {
+ if (this._volume === volume) return;
+ this._volume = volume;
+ this.needsLayout = true;
+ }
+ get muted() {
+ return this._muted;
+ }
+ set muted(flag) {
+ if (this._muted === flag) return;
+ this._muted = flag;
+ this.needsLayout = true;
+ }
+ set usesLTRUserInterfaceLayoutDirection(usesLTRUserInterfaceLayoutDirection) {
+ if (
+ usesLTRUserInterfaceLayoutDirection ===
+ this._usesLTRUserInterfaceLayoutDirection
+ )
+ return;
+ this._usesLTRUserInterfaceLayoutDirection =
+ usesLTRUserInterfaceLayoutDirection;
+ this.needsLayout = true;
+ }
+ layout() {
+ if (this._muted || this._volume < 0)
+ this.iconName = this._usesLTRUserInterfaceLayoutDirection
+ ? Icons.VolumeMuted
+ : Icons.VolumeMutedRTL;
+ else if (this._volume < 0.25)
+ this.iconName = this._usesLTRUserInterfaceLayoutDirection
+ ? Icons.Volume0
+ : Icons.Volume0RTL;
+ else if (this._volume < 0.5)
+ this.iconName = this._usesLTRUserInterfaceLayoutDirection
+ ? Icons.Volume1
+ : Icons.Volume1RTL;
+ else if (this._volume < 0.75)
+ this.iconName = this._usesLTRUserInterfaceLayoutDirection
+ ? Icons.Volume2
+ : Icons.Volume2RTL;
+ else
+ this.iconName = this._usesLTRUserInterfaceLayoutDirection
+ ? Icons.Volume3
+ : Icons.Volume3RTL;
+ }
+}
+class AirplayButton extends Button {
+ constructor(layoutDelegate) {
+ super({ cssClassName: "airplay", iconName: Icons.Airplay, layoutDelegate });
+ }
+}
+class PiPButton extends Button {
+ constructor(layoutDelegate) {
+ super({ cssClassName: "pip", iconName: Icons.EnterPiP, layoutDelegate });
+ }
+ get contextMenuOptions() {
+ return { includePictureInPicture: true };
+ }
+}
+class TracksButton extends Button {
+ constructor(layoutDelegate) {
+ super({ cssClassName: "tracks", iconName: Icons.Tracks, layoutDelegate });
+ }
+ get contextMenuOptions() {
+ return { includeLanguages: true, includeSubtitles: true };
+ }
+}
+class FullscreenButton extends Button {
+ constructor(layoutDelegate) {
+ super({ cssClassName: "fullscreen", layoutDelegate });
+ this.iconName = this.layoutTraits.isFullscreen
+ ? Icons.ExitFullscreen
+ : Icons.EnterFullscreen;
+ }
+}
+class SeekButton extends Button {
+ constructor(options) {
+ super(options);
+ this.element.addEventListener("mousedown", this);
+ }
+ handleEvent(event) {
+ if (event.type === "mousedown" && event.currentTarget === this.element)
+ this._didStartPressing();
+ else if (event.type === "mouseup") this._didStopPressing();
+ else super.handleEvent(event);
+ }
+ _didStartPressing() {
+ const mediaControls = this.parentOfType(MediaControls);
+ if (!mediaControls) return;
+ this._mouseupTarget = mediaControls.element;
+ this._mouseupTarget.addEventListener("mouseup", this, true);
+ this._notifyDelegateOfPressingState(true);
+ }
+ _didStopPressing() {
+ this._mouseupTarget.removeEventListener("mouseup", this, true);
+ this._notifyDelegateOfPressingState(false);
+ }
+ _notifyDelegateOfPressingState(isPressed) {
+ if (
+ this._enabled &&
+ this.uiDelegate &&
+ typeof this.uiDelegate.buttonPressedStateDidChange === "function"
+ )
+ this.uiDelegate.buttonPressedStateDidChange(this, isPressed);
+ }
+}
+class RewindButton extends SeekButton {
+ constructor(layoutDelegate) {
+ super({ cssClassName: "rewind", iconName: Icons.Rewind, layoutDelegate });
+ }
+}
+class ForwardButton extends SeekButton {
+ constructor(layoutDelegate) {
+ super({ cssClassName: "forward", iconName: Icons.Forward, layoutDelegate });
+ }
+}
+class OverflowButton extends Button {
+ constructor(layoutDelegate) {
+ super({
+ cssClassName: "overflow",
+ iconName: Icons.Overflow,
+ layoutDelegate,
+ });
+ this._defaultContextMenuOptions = {};
+ this._extraContextMenuOptions = {};
+ }
+ get visible() {
+ return super.visible;
+ }
+ set visible(flag) {
+ function isEmpty(contextMenuOptions) {
+ for (let key in contextMenuOptions) return false;
+ return true;
+ }
+ super.visible =
+ flag &&
+ (!isEmpty(this._defaultContextMenuOptions) ||
+ !isEmpty(this._extraContextMenuOptions));
+ }
+ get contextMenuOptions() {
+ return {
+ ...this._defaultContextMenuOptions,
+ ...this._extraContextMenuOptions,
+ };
+ }
+ addExtraContextMenuOptions(contextMenuOptions) {
+ if (!this.enabled) return;
+ for (let key in contextMenuOptions)
+ this._extraContextMenuOptions[key] = contextMenuOptions[key];
+ this.visible = true;
+ }
+ clearExtraContextMenuOptions() {
+ this._extraContextMenuOptions = {};
+ this.visible = false;
+ }
+ set defaultContextMenuOptions(defaultContextMenuOptions) {
+ this._defaultContextMenuOptions = defaultContextMenuOptions || {};
+ this.visible = true;
+ }
+}
+class CloseButton extends Button {
+ constructor(layoutDelegate) {
+ super({ cssClassName: "close", iconName: Icons.Close, layoutDelegate });
+ }
+}
+class ButtonsContainer extends LayoutNode {
+ constructor({
+ children,
+ leftMargin,
+ rightMargin,
+ buttonMargin,
+ cssClassName,
+ } = {}) {
+ super(``);
+ this.leftMargin = leftMargin ?? ButtonsContainer.Defaults.LeftMargin;
+ this.rightMargin = rightMargin ?? ButtonsContainer.Defaults.RightMargin;
+ this.buttonMargin = buttonMargin ?? ButtonsContainer.Defaults.ButtonMargin;
+ this.children = children ?? [];
+ }
+ static Defaults = { LeftMargin: 16, RightMargin: 16, ButtonMargin: 16 };
+ willRemoveChild(child) {
+ super.willRemoveChild(child);
+ child.visible = true;
+ child.x = 0;
+ }
+ didChangeChildren() {
+ super.didChangeChildren();
+ this.layout();
+ }
+ layout() {
+ super.layout();
+ let x = this.leftMargin;
+ let numberOfVisibleButtons = 0;
+ this._children.forEach((button) => {
+ button.visible = button.enabled && !button.dropped;
+ if (!button.visible) return;
+ button.x = x;
+ x += button.width + this.buttonMargin;
+ numberOfVisibleButtons++;
+ });
+ if (numberOfVisibleButtons)
+ this.width = x - this.buttonMargin + this.rightMargin;
+ else this.width = this.buttonMargin + this.rightMargin;
+ }
+}
+class StatusLabel extends LayoutItem {
+ constructor(layoutDelegate) {
+ super({ element: ``, layoutDelegate });
+ this._text = "";
+ this.minimumWidth = 120;
+ this.idealMinimumWidth = this.minimumWidth;
+ }
+ get text() {
+ return this._text;
+ }
+ set text(text) {
+ if (text === this._text) return;
+ this._text = text;
+ this.markDirtyProperty("text");
+ if (this.layoutDelegate) this.layoutDelegate.needsLayout = true;
+ }
+ get enabled() {
+ return this._text !== "";
+ }
+ commitProperty(propertyName) {
+ if (propertyName === "text") this.element.textContent = this._text;
+ else super.commitProperty(propertyName);
+ }
+}
+class ControlsBar extends LayoutNode {
+ constructor(cssClassName = "") {
+ super(``);
+ this._hasBackgroundTint = true;
+ this._translation = new DOMPoint();
+ this._backgroundTint = this.addChild(new BackgroundTint());
+ }
+ get hasBackgroundTint() {
+ return this._hasBackgroundTint;
+ }
+ set hasBackgroundTint(hasBackgroundTint) {
+ if (this._hasBackgroundTint == hasBackgroundTint) return;
+ this._hasBackgroundTint = hasBackgroundTint;
+ if (hasBackgroundTint) {
+ console.assert(!this._backgroundTint.parent);
+ this.addChild(this._backgroundTint, 0);
+ } else {
+ console.assert(this._backgroundTint.parent === this);
+ this._backgroundTint.remove();
+ }
+ }
+ get children() {
+ return super.children;
+ }
+ set children(children) {
+ if (this._hasBackgroundTint)
+ super.children = [this._backgroundTint].concat(children);
+ else super.children = children;
+ }
+ get translation() {
+ return new DOMPoint(this._translation.x, this._translation.y);
+ }
+ set translation(point) {
+ if (this._translation.x === point.x && this._translation.y === point.y)
+ return;
+ this._translation = new DOMPoint(point.x, point.y);
+ this.markDirtyProperty("translation");
+ }
+ commitProperty(propertyName) {
+ if (propertyName === "translation")
+ this.element.style.transform = `translate(${this._translation.x}px, ${this._translation.y}px)`;
+ else super.commitProperty(propertyName);
+ }
+}
+const AutoHideDelayMS = 4000;
+class AutoHideController {
+ constructor(mediaControls) {
+ this._mediaControls = mediaControls;
+ this._pointerIdentifiersPreventingAutoHide = new Set();
+ this._pointerIdentifiersPreventingAutoHideForHover = new Set();
+ this._mediaControls.element.addEventListener("pointermove", this);
+ this._mediaControls.element.addEventListener("pointerdown", this);
+ this._mediaControls.element.addEventListener("pointerup", this);
+ this._mediaControls.element.addEventListener("pointerleave", this);
+ this._mediaControls.element.addEventListener("pointerout", this);
+ if (this._mediaControls.layoutTraits.supportsTouches())
+ this._tapGestureRecognizer = new TapGestureRecognizer(
+ this._mediaControls.element,
+ this,
+ );
+ this.autoHideDelay = AutoHideDelayMS;
+ }
+ get fadesWhileIdle() {
+ return this._fadesWhileIdle;
+ }
+ set fadesWhileIdle(flag) {
+ if (this._fadesWhileIdle == flag) return;
+ this._fadesWhileIdle = flag;
+ if (!this._fadesWhileIdle) this._mediaControls.faded = false;
+ this._resetAutoHideTimer();
+ }
+ get hasSecondaryUIAttached() {
+ return this._hasSecondaryUIAttached;
+ }
+ set hasSecondaryUIAttached(flag) {
+ if (this._hasSecondaryUIAttached == flag) return;
+ this._hasSecondaryUIAttached = flag;
+ this._resetAutoHideTimer();
+ }
+ handleEvent(event) {
+ if (event.currentTarget !== this._mediaControls.element) return;
+ switch (event.type) {
+ case "pointermove":
+ if (event.pointerType === "mouse") this._mediaControls.faded = false;
+ if (
+ this._mediaControls.isPointInControls(
+ new DOMPoint(event.clientX, event.clientY),
+ )
+ ) {
+ this._pointerIdentifiersPreventingAutoHideForHover.add(
+ event.pointerId,
+ );
+ this._cancelAutoHideTimer();
+ } else {
+ this._pointerIdentifiersPreventingAutoHideForHover.delete(
+ event.pointerId,
+ );
+ this._resetAutoHideTimer();
+ }
+ return;
+ case "pointerleave":
+ this._pointerIdentifiersPreventingAutoHide.delete(event.pointerId);
+ this._pointerIdentifiersPreventingAutoHideForHover.delete(
+ event.pointerId,
+ );
+ if (event.pointerType == "mouse") this._autoHideTimerFired();
+ this._resetAutoHideTimer();
+ return;
+ case "pointerdown":
+ this._nextTapCanFadeControls = !this._mediaControls.faded;
+ this._pointerIdentifiersPreventingAutoHide.add(event.pointerId);
+ if (event.pointerType === "mouse") this._mediaControls.faded = false;
+ this._cancelAutoHideTimer();
+ return;
+ case "pointerup":
+ this._pointerIdentifiersPreventingAutoHide.delete(event.pointerId);
+ this._resetAutoHideTimer();
+ return;
+ }
+ }
+ gestureRecognizerStateDidChange(recognizer) {
+ if (
+ this._tapGestureRecognizer !== recognizer ||
+ recognizer.state !== GestureRecognizer.States.Recognized
+ )
+ return;
+ this._mediaControls.faded =
+ this._nextTapCanFadeControls &&
+ !this._mediaControls.isPointInControls(recognizer.locationInClient());
+ delete this._nextTapCanFadeControls;
+ }
+ mediaControlsFadedStateDidChange() {
+ this._resetAutoHideTimer();
+ }
+ mediaControlsBecameInvisible() {
+ this._cancelAutoHideTimer();
+ }
+ get _canFadeControls() {
+ return this._fadesWhileIdle && !this._hasSecondaryUIAttached;
+ }
+ _cancelAutoHideTimer() {
+ window.clearTimeout(this._autoHideTimer);
+ delete this._autoHideTimer;
+ }
+ _resetAutoHideTimer() {
+ this._cancelAutoHideTimer();
+ if (this._mediaControls.faded || !this._canFadeControls) return;
+ this._autoHideTimer = window.setTimeout(
+ this._autoHideTimerFired.bind(this),
+ this.autoHideDelay,
+ );
+ }
+ _autoHideTimerFired() {
+ delete this._autoHideTimer;
+ this._mediaControls.faded =
+ this._canFadeControls &&
+ !this._pointerIdentifiersPreventingAutoHide.size &&
+ !this._pointerIdentifiersPreventingAutoHideForHover.size;
+ }
+}
+class MediaControls extends LayoutNode {
+ constructor({ width = 300, height = 150, layoutTraits = null } = {}) {
+ super(``);
+ if (layoutTraits?.inheritsBorderRadius())
+ this.element.classList.add("inherits-border-radius");
+ this._scaleFactor = 1;
+ this.width = width;
+ this.height = height;
+ this.layoutTraits = layoutTraits;
+ this.playPauseButton = new PlayPauseButton(this);
+ this.pipButton = new PiPButton(this);
+ this.fullscreenButton = new FullscreenButton(this);
+ this.muteButton = new MuteButton(this);
+ this.tracksButton = new TracksButton(this);
+ this.overflowButton = new OverflowButton(this);
+ this.statusLabel = new StatusLabel(this);
+ this.timeControl = new TimeControl(this);
+ this.bottomControlsBar = new ControlsBar("bottom");
+ this.autoHideController = new AutoHideController(this);
+ this.autoHideController.fadesWhileIdle = false;
+ this.autoHideController.hasSecondaryUIAttached = false;
+ this._placard = null;
+ this.invalidPlacard = new InvalidPlacard(this);
+ this.fullscreenPlacard = new FullscreenPlacard(this);
+ if (this.layoutTraits?.supportsPiP())
+ this.pipPlacard = new PiPPlacard(this);
+ else this.pipPlacard = null;
+ if (this.layoutTraits?.supportsAirPlay()) {
+ this.airplayButton = new AirplayButton(this);
+ this.airplayPlacard = new AirplayPlacard(this);
+ } else {
+ this.airplayButton = null;
+ this.airplayPlacard = null;
+ }
+ this.element.addEventListener("focusin", this);
+ window.addEventListener("dragstart", this, true);
+ }
+ get visible() {
+ return super.visible;
+ }
+ set visible(flag) {
+ if (this.visible === flag) return;
+ if (flag && !this.visible) this.faded = false;
+ else if (!flag) this.autoHideController.mediaControlsBecameInvisible();
+ super.visible = flag;
+ if (flag) this.layout();
+ if (
+ this.delegate &&
+ typeof this.delegate.mediaControlsVisibilityDidChange === "function"
+ )
+ this.delegate.mediaControlsVisibilityDidChange();
+ }
+ get faded() {
+ return !!this._faded;
+ }
+ set faded(flag) {
+ if (this._faded === flag) return;
+ this._faded = flag;
+ this.markDirtyProperty("faded");
+ this.autoHideController.mediaControlsFadedStateDidChange();
+ if (
+ this.delegate &&
+ typeof this.delegate.mediaControlsFadedStateDidChange === "function"
+ )
+ this.delegate.mediaControlsFadedStateDidChange();
+ }
+ get usesLTRUserInterfaceLayoutDirection() {
+ return this.element.classList.contains(
+ "uses-ltr-user-interface-layout-direction",
+ );
+ }
+ set usesLTRUserInterfaceLayoutDirection(flag) {
+ this.needsLayout = this.usesLTRUserInterfaceLayoutDirection !== flag;
+ this.element.classList.toggle(
+ "uses-ltr-user-interface-layout-direction",
+ flag,
+ );
+ this.muteButton.usesLTRUserInterfaceLayoutDirection =
+ this.usesLTRUserInterfaceLayoutDirection;
+ }
+ get scaleFactor() {
+ return this._scaleFactor;
+ }
+ set scaleFactor(scaleFactor) {
+ if (this._scaleFactor === scaleFactor) return;
+ this._scaleFactor = scaleFactor;
+ this.markDirtyProperty("scaleFactor");
+ }
+ get placard() {
+ return this._placard;
+ }
+ set placard(placard) {
+ if (this._placard === placard) return;
+ this._placard = placard;
+ this.layout();
+ }
+ placardPreventsControlsBarDisplay() {
+ return this._placard && this._placard !== this.airplayPlacard;
+ }
+ fadeIn() {
+ this.element.classList.add("fade-in");
+ }
+ isPointInControls(point) {
+ let ancestor = this.element.parentNode;
+ while (ancestor && !(ancestor instanceof ShadowRoot))
+ ancestor = ancestor.parentNode;
+ const shadowRoot = ancestor;
+ if (!shadowRoot) return false;
+ const tappedElement = shadowRoot.elementFromPoint(point.x, point.y);
+ return this.children.some((child) => child.element.contains(tappedElement));
+ }
+ handleEvent(event) {
+ if (event.type === "focusin" && event.currentTarget === this.element)
+ this.faded = false;
+ else if (
+ event.type === "dragstart" &&
+ this.isPointInControls(new DOMPoint(event.clientX, event.clientY))
+ )
+ event.preventDefault();
+ }
+ layout() {
+ super.layout();
+ if (this._placard) {
+ this._placard.width = this.width;
+ this._placard.height = this.height;
+ }
+ }
+ commitProperty(propertyName) {
+ if (propertyName === "scaleFactor") {
+ const zoom = 1 / this._scaleFactor;
+
+ if (zoom < 1) {
+ this.element.style.transform = `scale(${zoom})`;
+ this.element.style.removeProperty("zoom");
+ } else {
+ this.element.style.zoom = zoom;
+ this.element.style.removeProperty("transform");
+ }
+ } else if (propertyName === "faded")
+ this.element.classList.toggle("faded", this.faded);
+ else super.commitProperty(propertyName);
+ }
+ disable() {
+ this.element.removeEventListener("focusin", this);
+ window.removeEventListener("dragstart", this, true);
+ }
+ reenable() {
+ this.element.addEventListener("focusin", this);
+ window.addEventListener("dragstart", this, true);
+ }
+}
+class BackgroundClickDelegateNotifier {
+ constructor(mediaControls) {
+ this._mediaControls = mediaControls;
+ mediaControls.element.addEventListener("mousedown", this);
+ mediaControls.element.addEventListener("click", this);
+ }
+ handleEvent(event) {
+ const mediaControls = this._mediaControls;
+ if (event.currentTarget !== mediaControls.element) return;
+ switch (event.type) {
+ case "mousedown":
+ this._receivedMousedown = true;
+ return;
+ case "click":
+ if (
+ this._receivedMousedown &&
+ event.target === mediaControls.element &&
+ mediaControls.delegate &&
+ typeof mediaControls.delegate.macOSControlsBackgroundWasClicked ===
+ "function"
+ )
+ mediaControls.delegate.macOSControlsBackgroundWasClicked();
+ delete this._receivedMousedown;
+ return;
+ }
+ }
+}
+class InlineMediaControls extends MediaControls {
+ constructor(options) {
+ super(options);
+ this.element.classList.add("inline");
+ this.skipBackButton = new SkipBackButton(this);
+ this.skipForwardButton = new SkipForwardButton(this);
+ this.topLeftControlsBar = new ControlsBar("top-left");
+ this._topLeftControlsBarContainer = this.topLeftControlsBar.addChild(
+ new ButtonsContainer(),
+ );
+ this.topRightControlsBar = new ControlsBar("top-right");
+ this._topRightControlsBarContainer = this.topRightControlsBar.addChild(
+ new ButtonsContainer(),
+ );
+ this.leftContainer = new ButtonsContainer({ cssClassName: "left" });
+ this.rightContainer = new ButtonsContainer({ cssClassName: "right" });
+ this.centerControlsBar = new ControlsBar("center");
+ this._centerControlsBarContainer = this.centerControlsBar.addChild(
+ new ButtonsContainer(),
+ );
+ this._shouldUseAudioLayout = false;
+ this._shouldUseSingleBarLayout = false;
+ this.showsStartButton = false;
+ this._updateBottomControlsBarLabel();
+ }
+ set shouldUseAudioLayout(flag) {
+ if (this._shouldUseAudioLayout === flag) return;
+ this._shouldUseAudioLayout = flag;
+ this.element.classList.toggle("audio", flag);
+ this.needsLayout = true;
+ this._updateBottomControlsBarLabel();
+ }
+ set shouldUseSingleBarLayout(flag) {
+ if (this._shouldUseSingleBarLayout === flag) return;
+ this._shouldUseSingleBarLayout = flag;
+ this.needsLayout = true;
+ }
+ get showsStartButton() {
+ return !!this._showsStartButton;
+ }
+ set showsStartButton(flag) {
+ if (this._showsStartButton === flag) return;
+ this._showsStartButton = flag;
+ this.element.classList.toggle("shows-start-button", flag);
+ this.layout();
+ }
+ layout() {
+ super.layout();
+ const children = [];
+ if (this.placard) {
+ children.push(this.placard);
+ if (this.placardPreventsControlsBarDisplay()) {
+ this.children = children;
+ return;
+ }
+ }
+ if (!this.visible) {
+ this.children = children;
+ return;
+ }
+ if (
+ !this._shouldUseAudioLayout &&
+ (this.width < MinimumSizeToShowAnyControl ||
+ this.height < MinimumSizeToShowAnyControl)
+ ) {
+ this.children = children;
+ return;
+ }
+ if (this._showsStartButton) {
+ this.playPauseButton.style =
+ this.width <= MaximumSizeToShowSmallProminentControl ||
+ this.height <= MaximumSizeToShowSmallProminentControl
+ ? Button.Styles.SmallCenter
+ : Button.Styles.Center;
+ this.children = [this.playPauseButton];
+ return;
+ }
+ if (!this.bottomControlsBar) return;
+ this._topLeftControlsBarContainer.children = this.topLeftContainerButtons();
+ this._topLeftControlsBarContainer.layout();
+ this.topLeftControlsBar.width = this._topLeftControlsBarContainer.width;
+ this.topLeftControlsBar.visible =
+ this._topLeftControlsBarContainer.children.some(
+ (button) => button.visible,
+ );
+ this._centerControlsBarContainer.children = this.centerContainerButtons();
+ this._centerControlsBarContainer.layout();
+ this.centerControlsBar.width = this._centerControlsBarContainer.width;
+ this.centerControlsBar.visible =
+ this._centerControlsBarContainer.children.some(
+ (button) => button.visible,
+ );
+ if (!this._inlineInsideMargin)
+ this._inlineInsideMargin = this.computedValueForStylePropertyInPx(
+ "--inline-controls-inside-margin",
+ );
+ this.bottomControlsBar.width = this._shouldUseAudioLayout
+ ? this.width
+ : this.width - 2 * this._inlineInsideMargin;
+ const centerControl = this.statusLabel.enabled
+ ? this.statusLabel
+ : this.timeControl;
+ let minimumCenterControlWidth = centerControl.minimumWidth;
+ const minimumControlsBarWidthForCenterControl =
+ minimumCenterControlWidth +
+ this.leftContainer.leftMargin +
+ this.rightContainer.rightMargin;
+ if (
+ this.bottomControlsBar.width < minimumControlsBarWidthForCenterControl
+ ) {
+ this.playPauseButton.style = Button.Styles.Corner;
+ if (!this._shouldUseSingleBarLayout && this.height >= 82) {
+ children.push(this.topLeftControlsBar);
+ this._addTopRightBarWithMuteButtonToChildren(children);
+ }
+ this.children = children.concat(this.playPauseButton);
+ return;
+ }
+ minimumCenterControlWidth = centerControl.idealMinimumWidth;
+ this.bottomControlsBar.visible = true;
+ this.playPauseButton.style = Button.Styles.Bar;
+ this.leftContainer.children = this.leftContainerButtons();
+ this.rightContainer.children = this.rightContainerButtons();
+ this.rightContainer.children
+ .concat(this.leftContainer.children)
+ .forEach((button) => delete button.dropped);
+ this.muteButton.style = this.preferredMuteButtonStyle;
+ this.overflowButton.clearExtraContextMenuOptions();
+ for (let button of this.droppableButtons()) {
+ if (!button.enabled) continue;
+ this.leftContainer.layout();
+ this.rightContainer.layout();
+ if (
+ this.leftContainer.width +
+ minimumCenterControlWidth +
+ this.rightContainer.width <
+ this.bottomControlsBar.width
+ )
+ break;
+ button.dropped = true;
+ if (button !== this.overflowButton)
+ this.overflowButton.addExtraContextMenuOptions(
+ button.contextMenuOptions,
+ );
+ }
+ let collapsableButtons = this.collapsableButtons();
+ let shownRightContainerButtons = this.rightContainer.children.filter(
+ (button) => button.enabled && !button.dropped,
+ );
+ let maximumRightContainerButtonCount =
+ this.maximumRightContainerButtonCountOverride ?? 2;
+ for (
+ let i = shownRightContainerButtons.length - 1;
+ i >= 0 &&
+ shownRightContainerButtons.length > maximumRightContainerButtonCount;
+ --i
+ ) {
+ let button = shownRightContainerButtons[i];
+ if (!collapsableButtons.has(button)) continue;
+ button.dropped = true;
+ this.overflowButton.addExtraContextMenuOptions(button.contextMenuOptions);
+ }
+ this.leftContainer.layout();
+ this.rightContainer.layout();
+ const visibleRightContainerButtons = this.rightContainer.children.filter(
+ (button) => button.visible,
+ );
+ const widthLeftOfTimeControl =
+ this.leftContainer.children.length > 0
+ ? this.leftContainer.width
+ : this.leftContainer.leftMargin;
+ const widthRightOfTimeControl =
+ visibleRightContainerButtons.length > 0
+ ? this.rightContainer.width
+ : this.rightContainer.rightMargin;
+ centerControl.x = widthLeftOfTimeControl;
+ centerControl.width =
+ this.bottomControlsBar.width -
+ widthLeftOfTimeControl -
+ widthRightOfTimeControl;
+ centerControl.layout();
+ const controlsBarChildren = [];
+ if (this.leftContainer.children.length)
+ controlsBarChildren.push(this.leftContainer);
+ controlsBarChildren.push(centerControl);
+ if (visibleRightContainerButtons.length) {
+ controlsBarChildren.push(this.rightContainer);
+ this.rightContainer.x =
+ this.bottomControlsBar.width - this.rightContainer.width;
+ }
+
+ if (!this._inlineBottomControlsBarHeight)
+ this._inlineBottomControlsBarHeight =
+ this.computedValueForStylePropertyInPx("--inline-controls-bar-height");
+ this.bottomControlsBar.y = Math.max(
+ 0,
+ this.height -
+ this._inlineBottomControlsBarHeight -
+ this._inlineInsideMargin,
+ );
+ this.bottomControlsBar.children = controlsBarChildren;
+ if (!this._shouldUseAudioLayout && !this._shouldUseSingleBarLayout)
+ children.push(this.topLeftControlsBar);
+ if (
+ !this._shouldUseAudioLayout &&
+ !this._shouldUseSingleBarLayout &&
+ this._centerControlsBarContainer.children.length
+ )
+ children.push(this.centerControlsBar);
+ children.push(this.bottomControlsBar);
+ if (
+ this.muteButton.style === Button.Styles.Corner ||
+ (this.muteButton.dropped &&
+ !this._shouldUseAudioLayout &&
+ !this._shouldUseSingleBarLayout)
+ )
+ this._addTopRightBarWithMuteButtonToChildren(children);
+ this.children = children;
+ }
+ commitProperty(propertyName) {
+ if (propertyName !== "visible") super.commitProperty(propertyName);
+ }
+ get preferredMuteButtonStyle() {
+ return this._shouldUseAudioLayout || this._shouldUseSingleBarLayout
+ ? Button.Styles.Bar
+ : Button.Styles.Corner;
+ }
+ topLeftContainerButtons() {
+ if (this._shouldUseSingleBarLayout) return [];
+ if (this.usesLTRUserInterfaceLayoutDirection)
+ return [this.fullscreenButton, this.pipButton];
+ return [this.pipButton, this.fullscreenButton];
+ }
+ leftContainerButtons() {
+ return [this.skipBackButton, this.playPauseButton, this.skipForwardButton];
+ }
+ centerContainerButtons() {
+ return [];
+ }
+ rightContainerButtons() {
+ const buttons = [];
+ if (this._shouldUseAudioLayout)
+ buttons.push(this.muteButton, this.airplayButton, this.tracksButton);
+ else if (this._shouldUseSingleBarLayout)
+ buttons.push(
+ this.muteButton,
+ this.airplayButton,
+ this.pipButton,
+ this.tracksButton,
+ this.fullscreenButton,
+ );
+ else {
+ if (this.preferredMuteButtonStyle === Button.Styles.Bar)
+ buttons.push(this.muteButton);
+ buttons.push(this.airplayButton, this.tracksButton);
+ }
+ buttons.push(this.overflowButton);
+ return buttons.filter((button) => button !== null);
+ }
+ droppableButtons() {
+ let buttons = this.collapsableButtons();
+ buttons.add(this.skipForwardButton);
+ buttons.add(this.skipBackButton);
+ if (
+ this._shouldUseSingleBarLayout ||
+ this.preferredMuteButtonStyle === Button.Styles.Bar
+ )
+ buttons.add(this.muteButton);
+ buttons.add(this.airplayButton);
+ if (this._shouldUseSingleBarLayout) buttons.add(this.fullscreenButton);
+ buttons.add(this.overflowButton);
+ buttons.delete(null);
+ return buttons;
+ }
+ collapsableButtons() {
+ let buttons = new Set([this.tracksButton]);
+ if (this._shouldUseSingleBarLayout) buttons.add(this.pipButton);
+ return buttons;
+ }
+ _updateBottomControlsBarLabel() {
+ this.bottomControlsBar.element.setAttribute(
+ "aria-label",
+ this._shouldUseAudioLayout
+ ? UIString("Audio Controls")
+ : UIString("Video Controls"),
+ );
+ }
+ _addTopRightBarWithMuteButtonToChildren(children) {
+ if (!this.muteButton.enabled) return;
+ delete this.muteButton.dropped;
+ this.muteButton.style = Button.Styles.Bar;
+ this._topRightControlsBarContainer.children = [this.muteButton];
+ this._topRightControlsBarContainer.layout();
+ this.topRightControlsBar.width = this._topRightControlsBarContainer.width;
+ children.push(this.topRightControlsBar);
+ }
+}
+class IOSInlineMediaControls extends InlineMediaControls {
+ constructor(options = {}) {
+ options.layoutTraits = new IOSLayoutTraits(LayoutTraits.Mode.Inline);
+ super(options);
+ this.element.classList.add("ios");
+ this._updateGestureRecognizers();
+ }
+ get showsStartButton() {
+ return super.showsStartButton;
+ }
+ set showsStartButton(flag) {
+ super.showsStartButton = flag;
+ this._updateGestureRecognizers();
+ }
+ get visible() {
+ return super.visible;
+ }
+ set visible(flag) {
+ super.visible = flag;
+ this._updateGestureRecognizers();
+ }
+ layout() {
+ if (this.timeControl) {
+ this.timeControl.scrubber.allowsRelativeScrubbing =
+ this._shouldUseMultilineLayout;
+ this.timeControl.scrubber.knobStyle = this._shouldUseMultilineLayout
+ ? Slider.KnobStyle.None
+ : Slider.KnobStyle.Circle;
+ }
+ if (this.playPauseButton)
+ this.playPauseButton.scaleFactor = this._shouldUseMultilineLayout ? 3 : 1;
+ if (this.skipForwardButton)
+ this.skipForwardButton.scaleFactor = this._shouldUseMultilineLayout
+ ? 2
+ : 1;
+ if (this.skipBackButton)
+ this.skipBackButton.scaleFactor = this._shouldUseMultilineLayout ? 2 : 1;
+ if (this._topLeftControlsBarContainer) {
+ this._topLeftControlsBarContainer.leftMargin = this
+ ._shouldUseMultilineLayout
+ ? 2
+ : ButtonsContainer.Defaults.LeftMargin;
+ this._topLeftControlsBarContainer.rightMargin = this
+ ._shouldUseMultilineLayout
+ ? 2
+ : ButtonsContainer.Defaults.RightMargin;
+ }
+ if (this._topRightControlsBarContainer) {
+ this._topRightControlsBarContainer.leftMargin = this
+ ._shouldUseMultilineLayout
+ ? 2
+ : ButtonsContainer.Defaults.LeftMargin;
+ this._topRightControlsBarContainer.rightMargin = this
+ ._shouldUseMultilineLayout
+ ? 2
+ : ButtonsContainer.Defaults.RightMargin;
+ }
+ if (this.leftContainer)
+ this.leftContainer.leftMargin = this._shouldUseMultilineLayout
+ ? 2
+ : ButtonsContainer.Defaults.LeftMargin;
+ if (this.rightContainer)
+ this.rightContainer.rightMargin = this._shouldUseMultilineLayout
+ ? 8
+ : ButtonsContainer.Defaults.RightMargin;
+ if (this._centerControlsBarContainer)
+ this._centerControlsBarContainer.buttonMargin = this
+ ._shouldUseMultilineLayout
+ ? 48
+ : ButtonsContainer.Defaults.ButtonMargin;
+ if (this.topLeftControlsBar)
+ this.topLeftControlsBar.hasBackgroundTint =
+ !this._shouldUseMultilineLayout;
+ if (this.topRightControlsBar)
+ this.topRightControlsBar.hasBackgroundTint =
+ !this._shouldUseMultilineLayout;
+ if (this.centerControlsBar)
+ this.centerControlsBar.hasBackgroundTint =
+ !this._shouldUseMultilineLayout;
+ if (this.bottomControlsBar)
+ this.bottomControlsBar.hasBackgroundTint =
+ !this._shouldUseMultilineLayout;
+ super.layout();
+ if (this.playPauseButton?.style === Button.Styles.Corner)
+ this.playPauseButton.scaleFactor = 1;
+ }
+ centerContainerButtons() {
+ if (this._shouldUseMultilineLayout)
+ return [
+ this.skipBackButton,
+ this.playPauseButton,
+ this.skipForwardButton,
+ ];
+ return [];
+ }
+ leftContainerButtons() {
+ if (this._shouldUseMultilineLayout) return [];
+ return [this.skipBackButton, this.playPauseButton, this.skipForwardButton];
+ }
+ droppableButtons() {
+ let buttons = super.droppableButtons();
+ if (this._shouldUseMultilineLayout) {
+ buttons.delete(this.skipForwardButton);
+ buttons.delete(this.skipBackButton);
+ }
+ return buttons;
+ }
+ gestureRecognizerStateDidChange(recognizer) {
+ if (recognizer.state === GestureRecognizer.States.Cancelled) {
+ return;
+ }
+ if (recognizer === this._pinchGestureRecognizer)
+ this._pinchGestureRecognizerStateDidChange(recognizer);
+ else if (recognizer === this._tapGestureRecognizer)
+ this._tapGestureRecognizerStateDidChange(recognizer);
+ }
+ get _shouldUseMultilineLayout() {
+ return !this._shouldUseSingleBarLayout && !this._shouldUseAudioLayout;
+ }
+ _updateGestureRecognizers() {
+ const shouldListenToPinches = this.visible;
+ const shouldListenToTaps = this.visible && this.showsStartButton;
+ if (shouldListenToPinches && !this._pinchGestureRecognizer)
+ this._pinchGestureRecognizer = new PinchGestureRecognizer(
+ this.element,
+ this,
+ );
+ else if (!shouldListenToPinches && this._pinchGestureRecognizer) {
+ this._pinchGestureRecognizer.enabled = false;
+ delete this._pinchGestureRecognizer;
+ }
+ if (shouldListenToTaps && !this._tapGestureRecognizer)
+ this._tapGestureRecognizer = new TapGestureRecognizer(this.element, this);
+ else if (!shouldListenToTaps && this._tapGestureRecognizer) {
+ this._tapGestureRecognizer.enabled = false;
+ delete this._tapGestureRecognizer;
+ }
+ }
+ _pinchGestureRecognizerStateDidChange(recognizer) {
+ console.assert(this.visible);
+ if (
+ recognizer.state !== GestureRecognizer.States.Recognized &&
+ recognizer.state !== GestureRecognizer.States.Changed
+ )
+ return;
+ if (
+ recognizer.scale > IOSInlineMediaControls.MinimumScaleToEnterFullscreen &&
+ this.delegate &&
+ typeof this.delegate.iOSInlineMediaControlsRecognizedPinchInGesture ===
+ "function"
+ )
+ this.delegate.iOSInlineMediaControlsRecognizedPinchInGesture();
+ }
+ _tapGestureRecognizerStateDidChange(recognizer) {
+ console.assert(this.visible && this.showsStartButton);
+ if (
+ recognizer.state === GestureRecognizer.States.Recognized &&
+ this.delegate &&
+ typeof this.delegate.iOSInlineMediaControlsRecognizedTapGesture ===
+ "function"
+ )
+ this.delegate.iOSInlineMediaControlsRecognizedTapGesture();
+ }
+}
+IOSInlineMediaControls.MinimumScaleToEnterFullscreen = 1.5;
+class IOSLayoutTraits extends LayoutTraits {
+ mediaControlsClass() {
+ return IOSInlineMediaControls;
+ }
+ resourceDirectory() {
+ return "iOS";
+ }
+ controlsNeverAvailable() {
+ return this.isFullscreen;
+ }
+ supportsIconWithFullscreenVariant() {
+ return false;
+ }
+ supportsDurationTimeLabel() {
+ return false;
+ }
+ supportsAirPlay() {
+ return true;
+ }
+ supportsPiP() {
+ return true;
+ }
+ controlsDependOnPageScaleFactor() {
+ return true;
+ }
+ skipDuration() {
+ return 10;
+ }
+ promoteSubMenusWhenShowingMediaControlsContextMenu() {
+ return false;
+ }
+ inheritsBorderRadius() {
+ return true;
+ }
+ toString() {
+ return `[IOSLayoutTraits]`;
+ }
+}
+window.layoutTraitsClasses["IOSLayoutTraits"] = IOSLayoutTraits;
+const MinimumHeightToShowVolumeSlider = 136;
+class MacOSInlineMediaControls extends InlineMediaControls {
+ constructor(options = {}) {
+ if (options.mode === undefined)
+ options.layoutTraits = new MacOSLayoutTraits(LayoutTraits.Mode.Inline);
+ else options.layoutTraits = new MacOSLayoutTraits(options.mode);
+ super(options);
+ this.element.classList.add("mac");
+ this._backgroundClickDelegateNotifier = new BackgroundClickDelegateNotifier(
+ this,
+ );
+ this.volumeSlider = new Slider(this, "volume");
+ this.volumeSlider.width = 60;
+ this._volumeSliderContainer = new LayoutNode(
+ ``,
+ );
+ if (this.layoutTraits.mode == LayoutTraits.Mode.NarrowViewer) {
+ this.element.classList.add("narrowviewer");
+ this.fullscreenButton.isFullscreen = true;
+ }
+ }
+ _setupVolumeSliderConfiguration() {
+ if (this._volumeSliderSetupComplete) {
+ return;
+ }
+ const hasValidHost =
+ this.mediaControlsHost &&
+ typeof this.mediaControlsHost.isMediaControlsMacInlineSizeSpecsEnabled !==
+ "undefined";
+ if (!hasValidHost) {
+ return;
+ }
+ if (
+ !this.mediaControlsHost.isMediaControlsMacInlineSizeSpecsEnabled ||
+ this.element.classList.contains("audio")
+ ) {
+ this.timeControl.scrubber.knobStyle = Slider.KnobStyle.Bar;
+ this._volumeSliderContainer.children = [
+ new BackgroundTint(),
+ this.volumeSlider,
+ ];
+ this.muteButton.element.addEventListener("mouseenter", this);
+ this.muteButton.element.addEventListener("mouseleave", this);
+ this._volumeSliderContainer.element.addEventListener("mouseleave", this);
+ } else {
+ this.volumeSlider.width = 135;
+ this._volumeSliderContainer.children = [
+ new BackgroundTint(),
+ this.volumeSlider,
+ this.muteButton,
+ ];
+ }
+ this._volumeSliderSetupComplete = true;
+ }
+ findHostFromParent() {
+ const secondParent =
+ this.element?.parentElement?.parentElement ||
+ this.element?.parentNode?.parentNode;
+ if (secondParent instanceof ShadowRoot && secondParent.host?.controlsHost) {
+ if (
+ typeof secondParent.host.controlsHost
+ .isMediaControlsMacInlineSizeSpecsEnabled !== "undefined"
+ ) {
+ return secondParent.host.controlsHost;
+ }
+ }
+ return null;
+ }
+ get mediaControlsHost() {
+ if (this._host) {
+ return this._host;
+ }
+ this._host = this.findHostFromParent();
+ return this._host;
+ }
+ layout() {
+ super.layout();
+ if (!this._volumeSliderContainer) return;
+ if (
+ this.mediaControlsHost?.isMediaControlsMacInlineSizeSpecsEnabled &&
+ !this.element.classList.contains("audio")
+ ) {
+ if (this.rightContainer?.element) {
+ this.rightContainer.element.style.removeProperty("left");
+ this.rightContainer._dirtyProperties.delete("x");
+ }
+ }
+ if (!this._volumeSliderSetupComplete) {
+ this._setupVolumeSliderConfiguration();
+ }
+ if (!this._inlineInsideMargin)
+ this._inlineInsideMargin = this.computedValueForStylePropertyInPx(
+ "--inline-controls-inside-margin",
+ );
+ if (!this._inlineBottomControlsBarHeight)
+ this._inlineBottomControlsBarHeight =
+ this.computedValueForStylePropertyInPx("--inline-controls-bar-height");
+ if (
+ this.mediaControlsHost &&
+ (!this.mediaControlsHost?.isMediaControlsMacInlineSizeSpecsEnabled ||
+ this.element.classList.contains("audio"))
+ ) {
+ this._volumeSliderContainer.x = this.rightContainer.x + this.muteButton.x;
+ this._volumeSliderContainer.y =
+ this.bottomControlsBar.y -
+ this._inlineBottomControlsBarHeight -
+ this._inlineInsideMargin;
+ } else {
+ const hasMinimumHeight = this.height >= MinimumHeightToShowVolumeSlider;
+ const hasMinimumWidth = this.width >= this.volumeSlider.width + 130;
+ const shouldShowVolumeContainer =
+ hasMinimumHeight &&
+ hasMinimumWidth &&
+ !this.showsStartButton &&
+ this.visible &&
+ this.playPauseButton &&
+ this.playPauseButton.enabled;
+ if (this.width < 60 && this.muteButton) {
+ this.muteButton.visible = false;
+ }
+ const children = this.children ? [...this.children] : [];
+ if (
+ shouldShowVolumeContainer &&
+ !children.includes(this._volumeSliderContainer)
+ ) {
+ this._volumeSliderContainer.children = [
+ new BackgroundTint(),
+ this.volumeSlider,
+ this.muteButton,
+ ];
+ children.push(this._volumeSliderContainer);
+ this.children = children;
+ this._volumeSliderContainer.x = 0;
+ this._volumeSliderContainer.y = 0;
+ if (this._volumeSliderContainer.element) {
+ this._volumeSliderContainer.element.style.removeProperty("left");
+ this._volumeSliderContainer.element.style.removeProperty("top");
+ }
+ if (this.muteButton) this.muteButton.visible = true;
+ } else if (
+ !shouldShowVolumeContainer &&
+ children.includes(this._volumeSliderContainer)
+ ) {
+ const volumeContainerIndex = children.indexOf(
+ this._volumeSliderContainer,
+ );
+ children.splice(volumeContainerIndex, 1);
+ this.children = children;
+ if (this.muteButton) this.muteButton.visible = false;
+ }
+ }
+ }
+ get preferredMuteButtonStyle() {
+ return this.height >= MinimumHeightToShowVolumeSlider
+ ? Button.Styles.Bar
+ : super.preferredMuteButtonStyle;
+ }
+ handleEvent(event) {
+ if (!this._volumeSliderSetupComplete) {
+ this._setupVolumeSliderConfiguration();
+ }
+ if (
+ this.mediaControlsHost &&
+ (!this.mediaControlsHost?.isMediaControlsMacInlineSizeSpecsEnabled ||
+ this.element.classList.contains("audio"))
+ ) {
+ if (
+ event.type === "mouseenter" &&
+ event.currentTarget === this.muteButton.element
+ ) {
+ if (this.muteButton.parent === this.rightContainer) {
+ this.addChild(this._volumeSliderContainer);
+ }
+ } else if (
+ event.type === "mouseleave" &&
+ (event.currentTarget === this.muteButton.element ||
+ event.currentTarget === this._volumeSliderContainer.element)
+ ) {
+ if (
+ !this._volumeSliderContainer.element.contains(event.relatedTarget)
+ ) {
+ this._volumeSliderContainer.remove();
+ }
+ }
+ }
+ }
+ rightContainerButtons() {
+ if (!this._volumeSliderSetupComplete) {
+ this._setupVolumeSliderConfiguration();
+ }
+ if (
+ this.mediaControlsHost &&
+ this.mediaControlsHost?.isMediaControlsMacInlineSizeSpecsEnabled &&
+ !this.element.classList.contains("audio")
+ ) {
+ const buttons = super.rightContainerButtons();
+ if (buttons && this.muteButton) {
+ const muteButtonIndex = buttons.indexOf(this.muteButton);
+ if (muteButtonIndex !== -1) {
+ buttons.splice(muteButtonIndex, 1);
+ }
+ }
+ return buttons;
+ }
+ return super.rightContainerButtons ? super.rightContainerButtons() : [];
+ }
+}
+const FullscreenTimeControlWidth = 448;
+class MacOSFullscreenMediaControls extends MediaControls {
+ constructor(options = {}) {
+ options.layoutTraits = new MacOSLayoutTraits(LayoutTraits.Mode.Fullscreen);
+ super(options);
+ this.element.classList.add("mac");
+ this.element.classList.add("fullscreen");
+ this.timeControl.scrubber.knobStyle = Slider.KnobStyle.Bar;
+ this.playPauseButton.scaleFactor = 2;
+ this.rewindButton = new RewindButton(this);
+ this.forwardButton = new ForwardButton(this);
+ this.fullscreenButton.isFullscreen = true;
+ this.volumeSlider = new Slider(this, "volume");
+ this._leftContainer = new ButtonsContainer({
+ children: this._volumeControlsForCurrentDirection(),
+ cssClassName: "left",
+ leftMargin: 12,
+ rightMargin: 0,
+ buttonMargin: 6,
+ });
+ this._centerContainer = new ButtonsContainer({
+ children: [this.rewindButton, this.playPauseButton, this.forwardButton],
+ cssClassName: "center",
+ leftMargin: 27,
+ rightMargin: 27,
+ buttonMargin: 27,
+ });
+ this._rightContainer = new ButtonsContainer({
+ children: [
+ this.airplayButton,
+ this.pipButton,
+ this.tracksButton,
+ this.fullscreenButton,
+ this.overflowButton,
+ ],
+ cssClassName: "right",
+ leftMargin: 12,
+ rightMargin: 12,
+ buttonMargin: 24,
+ });
+ this.bottomControlsBar.children = [
+ this._leftContainer,
+ this._centerContainer,
+ this._rightContainer,
+ ];
+ this.bottomControlsBar.element.addEventListener("mousedown", this);
+ this.bottomControlsBar.element.addEventListener("click", this);
+ this.element.addEventListener("mousemove", this);
+ this._backgroundClickDelegateNotifier = new BackgroundClickDelegateNotifier(
+ this,
+ );
+ }
+ handleEvent(event) {
+ event.stopPropagation();
+ if (
+ event.type === "mousedown" &&
+ event.currentTarget === this.bottomControlsBar.element
+ )
+ this._handleMousedown(event);
+ else if (event.type === "mousemove" && event.currentTarget === this.element)
+ this._handleMousemove(event);
+ else if (event.type === "mouseup" && event.currentTarget === this.element)
+ this._handleMouseup(event);
+ else super.handleEvent(event);
+ }
+ layout() {
+ super.layout();
+ const children = [];
+ if (this.placard) {
+ children.push(this.placard);
+ if (this.placardPreventsControlsBarDisplay()) {
+ this.children = children;
+ return;
+ }
+ }
+ children.push(this.bottomControlsBar);
+ if (!this._rightContainer) return;
+ this._rightContainer.children.forEach((button) => delete button.dropped);
+ this.overflowButton.clearExtraContextMenuOptions();
+ this._leftContainer.visible = this.muteButton.enabled;
+ this._leftContainer.children = this._volumeControlsForCurrentDirection();
+ let collapsableButtons = this._collapsableButtons();
+ let shownRightContainerButtons = this._rightContainer.children.filter(
+ (button) => button.enabled && !button.dropped,
+ );
+ let maximumRightContainerButtonCount =
+ this.maximumRightContainerButtonCountOverride ?? 3;
+ for (
+ let i = shownRightContainerButtons.length - 1;
+ i >= 0 &&
+ shownRightContainerButtons.length > maximumRightContainerButtonCount;
+ --i
+ ) {
+ let button = shownRightContainerButtons[i];
+ if (!collapsableButtons.has(button)) continue;
+ button.dropped = true;
+ this.overflowButton.addExtraContextMenuOptions(button.contextMenuOptions);
+ }
+ this._leftContainer.layout();
+ this._centerContainer.layout();
+ this._rightContainer.layout();
+ if (
+ this.statusLabel.enabled &&
+ this.statusLabel.parent !== this.bottomControlsBar
+ ) {
+ this.timeControl.remove();
+ this.bottomControlsBar.addChild(this.statusLabel);
+ } else if (
+ !this.statusLabel.enabled &&
+ this.timeControl.parent !== this.bottomControlsBar
+ ) {
+ this.statusLabel.remove();
+ this.bottomControlsBar.addChild(this.timeControl);
+ this.timeControl.width = FullscreenTimeControlWidth;
+ }
+ this.children = children;
+ }
+ _volumeControlsForCurrentDirection() {
+ return this.usesLTRUserInterfaceLayoutDirection
+ ? [this.muteButton, this.volumeSlider]
+ : [this.volumeSlider, this.muteButton];
+ }
+ _collapsableButtons() {
+ return new Set([this.tracksButton, this.pipButton]);
+ }
+ _handleMousedown(event) {
+ if (
+ event.target.localName === "button" ||
+ event.target.parentNode.localName === "button" ||
+ event.target.localName === "input" ||
+ event.target.closest("button") ||
+ event.target.closest(".buttons-container")
+ )
+ return;
+ event.preventDefault();
+ event.stopPropagation();
+ this._lastDragPoint = this._pointForEvent(event);
+ this.element.addEventListener("mousemove", this, true);
+ this.element.addEventListener("mouseup", this, true);
+ }
+ _handleMousemove(event) {
+ if (!this._lastDragPoint) {
+ this.faded = false;
+ return;
+ }
+ event.preventDefault();
+ const currentDragPoint = this._pointForEvent(event);
+ this.bottomControlsBar.translation = new DOMPoint(
+ this.bottomControlsBar.translation.x +
+ currentDragPoint.x -
+ this._lastDragPoint.x,
+ this.bottomControlsBar.translation.y +
+ currentDragPoint.y -
+ this._lastDragPoint.y,
+ );
+ this._lastDragPoint = currentDragPoint;
+ }
+ _handleMouseup(event) {
+ event.preventDefault();
+ delete this._lastDragPoint;
+ this.element.removeEventListener("mousemove", this, true);
+ this.element.removeEventListener("mouseup", this, true);
+ }
+ _pointForEvent(event) {
+ return new DOMPoint(event.clientX, event.clientY);
+ }
+}
+class MacOSLayoutTraits extends LayoutTraits {
+ mediaControlsClass() {
+ if (this._mode === LayoutTraits.Mode.Fullscreen)
+ return MacOSFullscreenMediaControls;
+ return MacOSInlineMediaControls;
+ }
+ resourceDirectory() {
+ return "macOS";
+ }
+ controlsNeverAvailable() {
+ return false;
+ }
+ supportsIconWithFullscreenVariant() {
+ return this.isFullscreen;
+ }
+ supportsDurationTimeLabel() {
+ return true;
+ }
+ controlsDependOnPageScaleFactor() {
+ return false;
+ }
+ skipDuration() {
+ return 15;
+ }
+ promoteSubMenusWhenShowingMediaControlsContextMenu() {
+ return true;
+ }
+ supportsTouches() {
+ return false;
+ }
+ supportsAirPlay() {
+ return true;
+ }
+ supportsPiP() {
+ return true;
+ }
+ inheritsBorderRadius() {
+ return false;
+ }
+ toString() {
+ if (this._mode === LayoutTraits.Mode.Fullscreen)
+ return `[MacOSLayoutTraits Fullscreen]`;
+ return `[MacOSLayoutTraits Inline]`;
+ }
+}
+window.layoutTraitsClasses["MacOSLayoutTraits"] = MacOSLayoutTraits;
+class MetadataContainer extends LayoutNode {
+ constructor({ cssClassName } = {}) {
+ super(``);
+ this._title = "";
+ this._artist = "";
+ this._artistNode = new LayoutNode(
+ ``,
+ );
+ this._titleNode = new LayoutNode(
+ ``,
+ );
+ this.children = [this._artistNode, this._titleNode];
+ }
+ get title() {
+ return this._title;
+ }
+ set title(title) {
+ if (title === this._title) return;
+ this._title = title;
+ this.markDirtyProperty("title");
+ }
+ get artist() {
+ return this._artist;
+ }
+ set artist(artist) {
+ if (artist === this._artist) return;
+ this._artist = artist;
+ this.markDirtyProperty("artist");
+ }
+ commitProperty(propertyName) {
+ if (propertyName === "title") {
+ this._titleNode.element.textContent = this.title;
+ this._titleNode.element.setAttribute(
+ "aria-label",
+ UIString("Title: %s", this.title),
+ );
+ } else if (propertyName === "artist") {
+ this._artistNode.element.textContent = this.artist;
+ this._artistNode.element.setAttribute(
+ "aria-label",
+ UIString("Artist: %s", this.artist),
+ );
+ } else super.commitProperty(propertyName);
+ }
+}
+const MinHeightToDisplayDescription = 100;
+const MinHeightToDisplayTitle = 40;
+class Placard extends LayoutItem {
+ constructor({
+ iconName = null,
+ title = "",
+ description = "",
+ width = 400,
+ height = 300,
+ layoutDelegate = null,
+ } = {}) {
+ super({ element: ``, layoutDelegate });
+ this._container = this.addChild(
+ new LayoutNode(``),
+ );
+ if (iconName) {
+ this._icon = new Button(this);
+ this._icon.iconName = iconName;
+ this._icon.element.disabled = true;
+ }
+ if (!!title)
+ this._titleNode = new LayoutNode(`${title}
`);
+ if (!!description)
+ this._descriptionNode = new LayoutNode(
+ `${description}
`,
+ );
+ this.minDimensionToDisplayIcon = 170;
+ this.width = width;
+ this.height = height;
+ }
+ layout() {
+ super.layout();
+ const children = [];
+ if (
+ this._icon &&
+ this.width >= this.minDimensionToDisplayIcon &&
+ this.height >= this.minDimensionToDisplayIcon
+ )
+ children.push(this._icon);
+ if (this._titleNode && this.height >= MinHeightToDisplayTitle)
+ children.push(this._titleNode);
+ if (this._descriptionNode && this.height >= MinHeightToDisplayDescription)
+ children.push(this._descriptionNode);
+ this._container.children = children;
+ }
+ set title(title) {
+ this._titleNode = !!title
+ ? new LayoutNode(`${title}
`)
+ : null;
+ this.needsLayout = true;
+ }
+ set description(description) {
+ this._descriptionNode = !!description
+ ? new LayoutNode(`${description}
`)
+ : null;
+ this.needsLayout = true;
+ }
+}
+class AirplayPlacard extends Placard {
+ constructor(layoutDelegate) {
+ super({
+ iconName: Icons.AirplayPlacard,
+ title: UIString("AirPlay"),
+ description: UIString("This video is playing on the TV."),
+ layoutDelegate,
+ });
+ }
+}
+class InvalidPlacard extends Placard {
+ constructor(layoutDelegate) {
+ super({ iconName: Icons.InvalidPlacard, layoutDelegate });
+ this.minDimensionToDisplayIcon = 50;
+ }
+}
+class PiPPlacard extends Placard {
+ constructor(layoutDelegate) {
+ super({
+ iconName: Icons.PiPPlacard,
+ description: UIString("This video is playing in picture in picture."),
+ layoutDelegate,
+ });
+ }
+}
+class FullscreenPlacard extends Placard {
+ constructor(layoutDelegate) {
+ super({
+ iconName: Icons.PiPPlacard,
+ description: UIString("This video is playing in fullscreen."),
+ layoutDelegate,
+ });
+ }
+}
+class TVOSLayoutTraits extends LayoutTraits {
+ mediaControlsClass() {
+ if (this.isFullscreen) return TVOSMediaControls;
+ return IOSInlineMediaControls;
+ }
+ supportingObjectClasses() {
+ var supportingObjectClasses = super.supportingObjectClasses();
+ if (this.isFullscreen) supportingObjectClasses.push(MetadataSupport);
+ return supportingObjectClasses;
+ }
+ resourceDirectory() {
+ return "iOS";
+ }
+ controlsNeverAvailable() {
+ return false;
+ }
+ supportsIconWithFullscreenVariant() {
+ return false;
+ }
+ supportsDurationTimeLabel() {
+ return false;
+ }
+ supportsAirPlay() {
+ return false;
+ }
+ supportsPiP() {
+ return false;
+ }
+ controlsDependOnPageScaleFactor() {
+ return true;
+ }
+ skipDuration() {
+ return 10;
+ }
+ promoteSubMenusWhenShowingMediaControlsContextMenu() {
+ return false;
+ }
+ inheritsBorderRadius() {
+ return true;
+ }
+ toString() {
+ return `[TVOSLayoutTraits]`;
+ }
+}
+window.layoutTraitsClasses["TVOSLayoutTraits"] = TVOSLayoutTraits;
+class TVOSMediaControls extends MediaControls {
+ static topButtonsScaleFactor = 1.5;
+ static backForwardButtonScaleFactor = 2.5;
+ static playPauseButtonScaleFactor = 3;
+ static overflowButtonScaleFactor = 1.5;
+ static bottomControlsBarButtonMargin = 80;
+ static bottomControlsBarMargin = 48;
+ constructor(options = {}) {
+ options.layoutTraits = new TVOSLayoutTraits(LayoutTraits.Mode.Fullscreen);
+ super(options);
+ this.element.classList.add("fullscreen");
+ this.element.classList.add("tvos");
+ this.closeButton = new CloseButton(this);
+ this.closeButton.circular = true;
+ this.timeControl.scrubber.allowsRelativeScrubbing = true;
+ this.timeControl.scrubber.knobStyle = Slider.KnobStyle.None;
+ this.timeControl.style = TimeControl.Style.Below;
+ this.skipBackButton = new SkipBackButton(this);
+ this.skipForwardButton = new SkipForwardButton(this);
+ this.overflowButton.addExtraContextMenuOptions(
+ this.tracksButton.contextMenuOptions,
+ );
+ const singleButtonContainerMargins = {
+ leftMargin: 0,
+ rightMargin: 0,
+ buttonMargin: 0,
+ };
+ this.topLeftControlsBar = new ControlsBar("top-left");
+ this._topLeftControlsBarContainer = this.topLeftControlsBar.addChild(
+ new ButtonsContainer(singleButtonContainerMargins),
+ );
+ this.topRightControlsBar = new ControlsBar("top-right");
+ this._topRightControlsBarContainer = this.topRightControlsBar.addChild(
+ new ButtonsContainer(singleButtonContainerMargins),
+ );
+ this.bottomControlsBar.addChild(this.timeControl);
+ this._bottomControlsBarContainer = this.bottomControlsBar.addChild(
+ new ButtonsContainer(),
+ );
+ this.overflowControlsBar = new ControlsBar("overflow");
+ this._overflowControlsBarContainer = this.overflowControlsBar.addChild(
+ new ButtonsContainer(singleButtonContainerMargins),
+ );
+ this.metadataContainer = new MetadataContainer();
+ this.showsStartButton = false;
+ for (let clickEvent of [
+ "click",
+ "mousedown",
+ "mouseup",
+ "pointerdown",
+ "pointerup",
+ "touchstart",
+ "touchend",
+ ]) {
+ this.element.addEventListener(clickEvent, (event) => {
+ event.stopPropagation();
+ });
+ }
+ this._isInitialized = true;
+ }
+ layout() {
+ super.layout();
+ if (!this._isInitialized) return;
+ const children = [];
+ if (this.placard) {
+ children.push(this.placard);
+ if (this.placardPreventsControlsBarDisplay()) {
+ this.children = children;
+ return;
+ }
+ }
+ if (!this.visible) {
+ this.children = children;
+ return;
+ }
+ this.closeButton.scaleFactor = TVOSMediaControls.topButtonsScaleFactor;
+ this.muteButton.scaleFactor = TVOSMediaControls.topButtonsScaleFactor;
+ this.playPauseButton.scaleFactor =
+ TVOSMediaControls.playPauseButtonScaleFactor;
+ this.skipForwardButton.scaleFactor =
+ TVOSMediaControls.backForwardButtonScaleFactor;
+ this.skipBackButton.scaleFactor =
+ TVOSMediaControls.backForwardButtonScaleFactor;
+ this.overflowButton.scaleFactor =
+ TVOSMediaControls.overflowButtonScaleFactor;
+ this.closeButton.style = Button.Styles.Center;
+ this._topLeftControlsBarContainer.children =
+ this._topLeftContainerButtons();
+ this._topLeftControlsBarContainer.layout();
+ this._topRightControlsBarContainer.children =
+ this._topRightContainerButtons();
+ this._topRightControlsBarContainer.layout();
+ this._bottomControlsBarContainer.children = this._bottomContainerButtons();
+ this._bottomControlsBarContainer.buttonMargin =
+ TVOSMediaControls.bottomControlsBarButtonMargin;
+ this._bottomControlsBarContainer.layout();
+ this._overflowControlsBarContainer.children =
+ this._overflowContainerButtons();
+ this._overflowControlsBarContainer.layout();
+ this.topLeftControlsBar.hasBackgroundTint = false;
+ this.topRightControlsBar.hasBackgroundTint = false;
+ this.bottomControlsBar.hasBackgroundTint = false;
+ this.overflowControlsBar.hasBackgroundTint = false;
+ this.topLeftControlsBar.width = this._topLeftControlsBarContainer.width;
+ this.topRightControlsBar.width = this._topRightControlsBarContainer.width;
+ this.bottomControlsBar.width =
+ this.width - 2 * TVOSMediaControls.bottomControlsBarMargin;
+ this.overflowControlsBar.width = this._overflowControlsBarContainer.width;
+ this.timeControl.width = this.bottomControlsBar.width;
+ this.metadataContainer.width =
+ this.bottomControlsBar.width -
+ this.overflowControlsBar.width -
+ ButtonsContainer.Defaults.LeftMargin;
+ this.topLeftControlsBar.visible =
+ this._topLeftControlsBarContainer.children.some(
+ (button) => button.visible,
+ );
+ this.topRightControlsBar.visible =
+ this._topRightControlsBarContainer.children.some(
+ (button) => button.visible,
+ );
+ this.bottomControlsBar.visible = true;
+ this.overflowControlsBar.visible = true;
+ children.push(
+ ...[
+ this.topLeftControlsBar,
+ this.topRightControlsBar,
+ this.bottomControlsBar,
+ this.metadataContainer,
+ this.overflowControlsBar,
+ ],
+ );
+ this.children = children;
+ }
+ commitProperty(propertyName) {
+ if (propertyName !== "visible") super.commitProperty(propertyName);
+ }
+ _topLeftContainerButtons() {
+ if (this.usesLTRUserInterfaceLayoutDirection) return [this.closeButton];
+ return [this.muteButton];
+ }
+ _topRightContainerButtons() {
+ if (this.usesLTRUserInterfaceLayoutDirection) return [this.muteButton];
+ return [this.closeButton];
+ }
+ _bottomContainerButtons() {
+ return [this.skipBackButton, this.playPauseButton, this.skipForwardButton];
+ }
+ _overflowContainerButtons() {
+ return [this.overflowButton];
+ }
+}
+class VisionSlider extends SliderBase {
+ constructor(layoutDelegate, cssClassName = "") {
+ super(layoutDelegate, `vision ${cssClassName}`);
+ this._recessed = false;
+ this._gutter = new LayoutNode(
+ ``,
+ );
+ this._primaryFill = new LayoutNode(``);
+ this.appearanceContainer.children = [this._gutter, this._primaryFill];
+ }
+ get recessed() {
+ return this._recessed;
+ }
+ set recessed(recessed) {
+ if (recessed == this._recessed) return;
+ this._recessed = recessed;
+ this.element.classList.toggle("recessed", recessed);
+ this.needsLayout = true;
+ }
+ get _recessedMargin() {
+ return this.computedValueForStylePropertyInPx(
+ "--slider-fill-recessed-margin",
+ );
+ }
+ get _effectiveSliderHeight() {
+ return (
+ this.computedValueForStylePropertyInPx("--slider-height") -
+ 2 * this._recessedMargin
+ );
+ }
+ commit() {
+ super.commit();
+ const height = this._effectiveSliderHeight;
+ const margin = this._recessedMargin;
+ const fillX = margin;
+ this._primaryFill.element.style.left = `${fillX}px`;
+ if (this.width) {
+ const fillWidth =
+ this.value * (this.width - margin * 2 - height) + height;
+ this._primaryFill.element.style.width = `${fillWidth}px`;
+ } else {
+ const fillWidth = `${this.value} * (100% - (${margin}px * 2) - ${height}px) + ${height}px`;
+ this._primaryFill.element.style.width = `calc(${fillWidth})`;
+ }
+ }
+}
+class VolumeContainer extends LayoutNode {
+ constructor(cssClassName = "") {
+ super(``);
+ this._backgroundTint = this.addChild(new BackgroundTint());
+ }
+ get children() {
+ return super.children;
+ }
+ set children(children) {
+ super.children = [this._backgroundTint].concat(children);
+ }
+}
+const MinSizeToShowLargeProminentControl = 292;
+const MinWidthToShowTopCornerControlsBars = 262;
+const MinWidthToShowBottomBar = 390;
+const MinWidthToShowVolumeSlider = 390;
+const MinWidthToShowSeekingControls = 520;
+const MinWidthToShowOverflowButton = 520;
+const MinWidthToShowLargeCentralControls = 640;
+const MaxWidthForBottomControlsBarInFullscreen = 602;
+const MinWidthToShowSeekingControlsForAudio = 120;
+const MinWidthToShowTimeControlForAudio = 262;
+class VisionMediaControls extends MediaControls {
+ constructor(options) {
+ super(options);
+ this._createControls();
+ this.element.classList.add("inline", "vision");
+ this._shouldUseAudioLayout = false;
+ this._shouldUseSingleBarLayout = false;
+ this.showsStartButton = false;
+ this._updateBottomControlsBarLabel();
+ }
+ set shouldUseAudioLayout(flag) {
+ if (this._shouldUseAudioLayout === flag) return;
+ this._shouldUseAudioLayout = flag;
+ this.element.classList.toggle("audio", flag);
+ this.needsLayout = true;
+ this._updateBottomControlsBarLabel();
+ }
+ set shouldUseSingleBarLayout(flag) {
+ if (this._shouldUseSingleBarLayout === flag) return;
+ this._shouldUseSingleBarLayout = flag;
+ this.needsLayout = true;
+ }
+ get showsStartButton() {
+ return !!this._showsStartButton;
+ }
+ set showsStartButton(flag) {
+ if (this._showsStartButton === flag) return;
+ this._showsStartButton = flag;
+ this.layout();
+ }
+ layout() {
+ super.layout();
+ const children = [];
+ if (this.placard) {
+ children.push(this.placard);
+ if (this.placardPreventsControlsBarDisplay()) {
+ this.children = children;
+ return;
+ }
+ }
+ if (!this.visible) {
+ this.children = children;
+ return;
+ }
+ if (
+ !this._shouldUseAudioLayout &&
+ (this.width < MinimumSizeToShowAnyControl ||
+ this.height < MinimumSizeToShowAnyControl)
+ ) {
+ this.children = children;
+ return;
+ }
+ if (this._showsStartButton) {
+ this.playPauseButton.style =
+ this._widthForSizeClassDetermination >=
+ MinSizeToShowLargeProminentControl &&
+ this._heightForSizeClassDetermination >=
+ MinSizeToShowLargeProminentControl
+ ? Button.Styles.Center
+ : Button.Styles.SmallCenter;
+ this.children = [this.playPauseButton];
+ return;
+ }
+ if (
+ this._topLeftControlsBar &&
+ this._centerControlsBar &&
+ this.bottomControlsBar &&
+ this._topRightControlsBar
+ )
+ this._performLayout();
+ }
+ commitProperty(propertyName) {
+ if (propertyName !== "visible") super.commitProperty(propertyName);
+ }
+ get _widthForSizeClassDetermination() {
+ return Math.ceil(this.width / this.scaleFactor);
+ }
+ get _heightForSizeClassDetermination() {
+ return Math.ceil(this.height / this.scaleFactor);
+ }
+ _createControls() {
+ this._backdrop = new LayoutNode('');
+ this.skipBackButton = new SkipBackButton(this);
+ this.skipBackButton.circular = true;
+ this.playPauseButton.circular = true;
+ this.skipForwardButton = new SkipForwardButton(this);
+ this.skipForwardButton.circular = true;
+ this.overflowButton.iconName = Icons.Ellipsis;
+ this.overflowButton.circular = true;
+ this.overflowButton.addExtraContextMenuOptions(
+ this.tracksButton.contextMenuOptions,
+ );
+ this.fullscreenButton.style = Button.Styles.Rounded;
+ this.fullscreenButton.circular = true;
+ this.timeControl.scrubber = new VisionSlider(
+ this.layoutDelegate,
+ "scrubber",
+ );
+ this._topLeftControlsBar = new ControlsBar("simple-layout top-left");
+ this._topLeftControlsBar.hasBackgroundTint = false;
+ this._topRightControlsBar = new ControlsBar("simple-layout top-right");
+ this._topRightControlsBar.hasBackgroundTint = false;
+ this._centerControlsBar = new ControlsBar("simple-layout center");
+ this._centerControlsBar.hasBackgroundTint = false;
+ this._bottomBarLeftContainer = new ButtonsContainer({
+ cssClassName: "left",
+ });
+ this._bottomBarRightContainer = new ButtonsContainer({
+ cssClassName: "right",
+ });
+ this.volumeSlider = new VisionSlider(this, "volume");
+ this.volumeSlider.width = 150;
+ this.volumeSlider.recessed = true;
+ this.volumeContainer = new VolumeContainer("volume-container");
+ }
+ _performLayout() {
+ throw "Derived class must implement this function.";
+ }
+ _topRightControlsBarChildren() {
+ throw "Derived class must implement this function.";
+ }
+ _performVolumeContainerLayout() {
+ throw "Derived class must implement this function.";
+ }
+ _performTopLeftControlsBarLayout() {
+ const buttons = [this.fullscreenButton];
+ for (let button of buttons) button.visible = button.enabled;
+ this._topLeftControlsBar.children = buttons;
+ }
+ _performTopRightControlsBarLayout() {
+ this._performVolumeContainerLayout();
+ this._topRightControlsBar.children = this._topRightControlsBarChildren();
+ }
+ _updateBottomControlsBarLabel() {
+ this.bottomControlsBar.element.setAttribute(
+ "aria-label",
+ this._shouldUseAudioLayout
+ ? UIString("Audio Controls")
+ : UIString("Video Controls"),
+ );
+ }
+ _bottomBarLeftContainerButtons() {
+ if (
+ this._widthForSizeClassDetermination <
+ MinWidthToShowSeekingControlsForAudio &&
+ this._shouldUseAudioLayout
+ )
+ return [this.playPauseButton];
+ return [this.skipBackButton, this.playPauseButton, this.skipForwardButton];
+ }
+ _bottomBarRightContainerButtons() {
+ if (this._shouldUseAudioLayout || this._shouldUseSingleBarLayout)
+ return [this.muteButton, this.overflowButton];
+ return [this.overflowButton];
+ }
+}
+class VisionInlineMediaControls extends VisionMediaControls {
+ constructor(options = {}) {
+ options.layoutTraits = new VisionLayoutTraits(LayoutTraits.Mode.Inline);
+ super(options);
+ }
+ _createControls() {
+ super._createControls();
+ this.overflowButton.style = Button.Styles.Rounded;
+ this.overflowButton.circular = true;
+ this.timeControl.style = TimeControl.Style.Above;
+ this.bottomControlsBar.hasBackgroundTint = false;
+ this._bottomBarLeftContainer.leftMargin = 10;
+ this._bottomBarLeftContainer.buttonMargin = 14;
+ this._bottomBarLeftContainer.rightMargin = 15;
+ this._bottomBarRightContainer.leftMargin = 15;
+ this._bottomBarRightContainer.buttonMargin = 12;
+ this._bottomBarRightContainer.rightMargin = 12;
+ }
+ _performLayout() {
+ if (this._shouldUseSingleBarLayout || this._shouldUseAudioLayout) {
+ this._performSingleBarLayout();
+ this.children = [this.bottomControlsBar];
+ return;
+ }
+ const children = [this._backdrop];
+ if (
+ this._widthForSizeClassDetermination >=
+ MinWidthToShowTopCornerControlsBars
+ ) {
+ this._performTopLeftControlsBarLayout();
+ this._performTopRightControlsBarLayout();
+ children.push(this._topLeftControlsBar);
+ children.push(this._topRightControlsBar);
+ }
+ this._performCentralContainerLayout();
+ children.push(this._centerControlsBar);
+ if (this._widthForSizeClassDetermination >= MinWidthToShowBottomBar) {
+ this._performBottomBarLayout();
+ children.push(this.bottomControlsBar);
+ }
+ this.children = children;
+ }
+ _topRightControlsBarChildren() {
+ const children = [];
+ if (this._widthForSizeClassDetermination >= MinWidthToShowVolumeSlider)
+ children.push(this.volumeContainer);
+ else children.push(this.muteButton);
+ if (this._widthForSizeClassDetermination >= MinWidthToShowOverflowButton)
+ children.push(this.overflowButton);
+ return children;
+ }
+ _centerContainerButtons() {
+ if (this._widthForSizeClassDetermination < MinWidthToShowSeekingControls)
+ return [this.playPauseButton];
+ return [this.skipBackButton, this.playPauseButton, this.skipForwardButton];
+ }
+ _performCentralContainerLayout() {
+ const scaleFactor =
+ this._widthForSizeClassDetermination >= MinWidthToShowLargeCentralControls
+ ? 1.5
+ : 1;
+ const buttons = this._centerContainerButtons();
+ for (let button of buttons) {
+ button.style = Button.Styles.Bar;
+ button.visible = button.enabled;
+ button.scaleFactor = scaleFactor;
+ button.circular = true;
+ }
+ this._centerControlsBar.children = buttons;
+ }
+ _performVolumeContainerLayout() {
+ if (this._widthForSizeClassDetermination >= MinWidthToShowVolumeSlider) {
+ this.muteButton.style = Button.Styles.Bar;
+ this.muteButton.circular = false;
+ this.volumeContainer.children = [this.volumeSlider, this.muteButton];
+ } else {
+ this.muteButton.style = Button.Styles.Rounded;
+ this.muteButton.circular = true;
+ this.volumeContainer.children = [];
+ }
+ }
+ _performBottomBarLayout() {
+ const margin = this.computedValueForStylePropertyInPx(
+ "--inline-controls-inside-margin",
+ );
+ this.bottomControlsBar.width = this.width - 2 * margin;
+ const control = this.statusLabel.enabled
+ ? this.statusLabel
+ : this.timeControl;
+ control.width = this.bottomControlsBar.width;
+ control.layout();
+ this.bottomControlsBar.children = [control];
+ }
+ _performSingleBarLayout() {
+ const children = [this._bottomBarLeftContainer];
+ this.timeControl.scrubber.recessed = true;
+ this.bottomControlsBar.width = this.width;
+ this.skipBackButton.style = Button.Styles.Bar;
+ this.skipForwardButton.style = Button.Styles.Bar;
+ this.playPauseButton.style = Button.Styles.Bar;
+ this.muteButton.style = Button.Styles.Bar;
+ this.muteButton.circular = true;
+ this.overflowButton.style = Button.Styles.Bar;
+ this.timeControl.style = TimeControl.Style.Side;
+ this.bottomControlsBar.hasBackgroundTint = true;
+ this._bottomBarLeftContainer.children =
+ this._bottomBarLeftContainerButtons();
+ this._bottomBarLeftContainer.layout();
+ this._bottomBarRightContainer.children =
+ this._bottomBarRightContainerButtons();
+ this._bottomBarRightContainer.layout();
+ const widthLeftOfTimeControl =
+ this._bottomBarLeftContainer.children.length > 0
+ ? this._bottomBarLeftContainer.width
+ : this._bottomBarLeftContainer.leftMargin;
+ const widthRightOfTimeControl =
+ this._bottomBarRightContainer.children.length > 0
+ ? this._bottomBarRightContainer.width
+ : this._bottomBarRightContainer.rightMargin;
+ const centerControl = this.statusLabel.enabled
+ ? this.statusLabel
+ : this.timeControl;
+ if (
+ this._widthForSizeClassDetermination >=
+ MinWidthToShowTimeControlForAudio &&
+ centerControl == this.timeControl
+ ) {
+ centerControl.x = widthLeftOfTimeControl;
+ centerControl.width =
+ this.bottomControlsBar.width -
+ widthLeftOfTimeControl -
+ widthRightOfTimeControl;
+ centerControl.layout();
+ children.push(centerControl);
+ }
+ this._bottomBarRightContainer.x =
+ this.bottomControlsBar.width - this._bottomBarRightContainer.width;
+ children.push(this._bottomBarRightContainer);
+ this.bottomControlsBar.children = children;
+ }
+}
+class VisionLayoutTraits extends LayoutTraits {
+ mediaControlsClass() {
+ return VisionInlineMediaControls;
+ }
+ resourceDirectory() {
+ return "iOS";
+ }
+ controlsNeverAvailable() {
+ return false;
+ }
+ supportsAirPlay() {
+ return false;
+ }
+ supportsPiP() {
+ return false;
+ }
+ supportsIconWithFullscreenVariant() {
+ return false;
+ }
+ supportsDurationTimeLabel() {
+ return false;
+ }
+ controlsDependOnPageScaleFactor() {
+ return true;
+ }
+ skipDuration() {
+ return 15;
+ }
+ promoteSubMenusWhenShowingMediaControlsContextMenu() {
+ return false;
+ }
+ inheritsBorderRadius() {
+ return false;
+ }
+ toString() {
+ return `[VisionLayoutTraits]`;
+ }
+}
+window.layoutTraitsClasses["VisionLayoutTraits"] = VisionLayoutTraits;
+class WatchOSActivityIndicator extends Button {
+ constructor(layoutDelegate) {
+ super({
+ cssClassName: "watchos-activity-indicator",
+ iconName: Icons.SpinnerSprite,
+ layoutDelegate,
+ });
+ }
+ show() {
+ let classList = this.element.classList;
+ classList.add("spins");
+ classList.remove("fades-out");
+ }
+ hide() {
+ let classList = this.element.classList;
+ if (!classList.contains("spins") || classList.contains("fades-out")) return;
+ classList.add("fades-out");
+ this.image.element.addEventListener(
+ "animationend",
+ (event) => {
+ if (event.animationName !== "watchos-activity-indicator-fades-out")
+ return;
+ classList.remove("spins");
+ classList.remove("fades-out");
+ },
+ { once: true },
+ );
+ }
+}
+class WatchOSMediaControls extends LayoutNode {
+ constructor({ width = 320, height = 240 } = {}) {
+ super(``);
+ this._state = WatchOSMediaControls.State.Paused;
+ this._scaleFactor = 1;
+ this.layoutTraits = new WatchOSLayoutTraits(LayoutTraits.Mode.Inline);
+ this.playButton = new Button({
+ cssClassName: "play",
+ iconName: Icons.PlayCircle,
+ layoutDelegate: this,
+ });
+ this.invalidButton = new Button({
+ cssClassName: "invalid",
+ iconName: Icons.InvalidCircle,
+ layoutDelegate: this,
+ });
+ this.activityIndicator = new WatchOSActivityIndicator(this);
+ this.width = width;
+ this.height = height;
+ }
+ get scaleFactor() {
+ return this._scaleFactor;
+ }
+ set scaleFactor(scaleFactor) {
+ if (this._scaleFactor === scaleFactor) return;
+ this._scaleFactor = scaleFactor;
+ this.markDirtyProperty("scaleFactor");
+ }
+ get state() {
+ return this._state;
+ }
+ set state(state) {
+ if (this._state === state) return;
+ this._state = state;
+ this.layout();
+ }
+ layout() {
+ super.layout();
+ switch (this._state) {
+ case WatchOSMediaControls.State.Paused:
+ this.children = [this.playButton];
+ break;
+ case WatchOSMediaControls.State.Pending:
+ this.children = [this.activityIndicator];
+ this.activityIndicator.show();
+ break;
+ case WatchOSMediaControls.State.Invalid:
+ this.children = [this.invalidButton];
+ break;
+ }
+ }
+ commitProperty(propertyName) {
+ if (propertyName !== "scaleFactor") {
+ super.commitProperty(propertyName);
+ return;
+ }
+ let zoom = 1 / this._scaleFactor;
+
+ if (zoom < 1) {
+ this.element.style.transform = `scale(${zoom})`;
+ this.element.style.removeProperty("zoom");
+ } else {
+ this.element.style.zoom = zoom;
+ this.element.style.removeProperty("transform");
+ }
+ }
+}
+WatchOSMediaControls.State = {
+ Paused: "paused",
+ Pending: "pending",
+ Invalid: "invalid",
+};
+class WatchOSLayoutTraits extends LayoutTraits {
+ mediaControlsClass() {
+ return WatchOSMediaControls;
+ }
+ supportingObjectClasses() {
+ return [WatchOSMediaControlsSupport];
+ }
+ resourceDirectory() {
+ return "watchOS";
+ }
+ controlsNeverAvailable() {
+ return false;
+ }
+ supportsIconWithFullscreenVariant() {
+ return false;
+ }
+ supportsDurationTimeLabel() {
+ return false;
+ }
+ supportsAirPlay() {
+ return false;
+ }
+ supportsPiP() {
+ return true;
+ }
+ controlsDependOnPageScaleFactor() {
+ return false;
+ }
+ skipDuration() {
+ return 15;
+ }
+ promoteSubMenusWhenShowingMediaControlsContextMenu() {
+ return false;
+ }
+ inheritsBorderRadius() {
+ return false;
+ }
+ toString() {
+ return `[WatchOSLayoutTraits]`;
+ }
+}
+window.layoutTraitsClasses["WatchOSLayoutTraits"] = WatchOSLayoutTraits;
+class MediaControllerSupport {
+ constructor(mediaController) {
+ this.mediaController = mediaController;
+ this.enable();
+ }
+ enable() {
+ for (let eventType of this.mediaEvents)
+ this.mediaController.media.addEventListener(eventType, this, true);
+ for (let tracks of this.tracksToMonitor) {
+ for (let eventType of ["change", "addtrack", "removetrack"])
+ tracks.addEventListener(eventType, this);
+ }
+ if (!this.control) return;
+ this.control.uiDelegate = this;
+ this.syncControl();
+ }
+ disable() {
+ for (let eventType of this.mediaEvents)
+ this.mediaController.media.removeEventListener(eventType, this, true);
+ for (let tracks of this.tracksToMonitor) {
+ for (let eventType of ["change", "addtrack", "removetrack"])
+ tracks.removeEventListener(eventType, this);
+ }
+ if (this.control) this.control.uiDelegate = null;
+ }
+ get control() {}
+ get mediaEvents() {
+ return [];
+ }
+ get tracksToMonitor() {
+ return [];
+ }
+ buttonWasPressed(control) {}
+ controlsUserVisibilityDidChange() {}
+ handleEvent(event) {
+ if (this.control) this.syncControl(event);
+ }
+ syncControl() {}
+}
+class AirplaySupport extends MediaControllerSupport {
+ get control() {
+ return this.mediaController.controls.airplayButton;
+ }
+ get mediaEvents() {
+ return [
+ "webkitplaybacktargetavailabilitychanged",
+ "webkitcurrentplaybacktargetiswirelesschanged",
+ ];
+ }
+ enable() {
+ if (this._shouldBeEnabled()) super.enable();
+ }
+ buttonWasPressed(control) {
+ this.mediaController.media.webkitShowPlaybackTargetPicker();
+ }
+ controlsUserVisibilityDidChange() {
+ if (this._shouldBeEnabled()) this.enable();
+ else this.disable();
+ }
+ handleEvent(event) {
+ if (event.type === "webkitplaybacktargetavailabilitychanged")
+ this._routesAvailable = event.availability === "available";
+ super.handleEvent(event);
+ }
+ syncControl() {
+ this.control.enabled = !!this._routesAvailable;
+ this.control.on =
+ this.mediaController.media.webkitCurrentPlaybackTargetIsWireless;
+ this.mediaController.controls.muteButton.enabled = !this.control.on;
+ }
+ _shouldBeEnabled() {
+ if (!this.mediaController.layoutTraits?.supportsAirPlay()) return false;
+ if (!this.mediaController.hasPlayed) return false;
+ const controls = this.mediaController.controls;
+ return controls.visible && !controls.faded;
+ }
+}
+class AudioSupport extends MediaControllerSupport {
+ get control() {
+ return this.mediaController.controls;
+ }
+ get mediaEvents() {
+ return ["loadedmetadata", "error"];
+ }
+ get tracksToMonitor() {
+ return [this.mediaController.media.videoTracks];
+ }
+ syncControl() {
+ this.control.shouldUseAudioLayout = this.mediaController.isAudio;
+ if (this.mediaController.mediaDocumentController)
+ this.mediaController.mediaDocumentController.layout();
+ }
+}
+class CloseSupport extends MediaControllerSupport {
+ get control() {
+ return this.mediaController.controls.closeButton;
+ }
+ buttonWasPressed(control) {
+ this.mediaController.media.webkitExitFullscreen();
+ }
+}
+class ControlsVisibilitySupport extends MediaControllerSupport {
+ constructor(mediaController) {
+ super(mediaController);
+ this._updateControls();
+ }
+ enable() {
+ super.enable();
+ this._updateControls();
+ }
+ disable() {
+ super.disable();
+ this.mediaController.controls.autoHideController.fadesWhileIdle = false;
+ }
+ get mediaEvents() {
+ return [
+ "loadedmetadata",
+ "play",
+ "pause",
+ "webkitcurrentplaybacktargetiswirelesschanged",
+ this.mediaController.fullscreenChangeEventType,
+ ];
+ }
+ get tracksToMonitor() {
+ return [this.mediaController.media.videoTracks];
+ }
+ handleEvent() {
+ this._updateControls();
+ }
+ _updateControls() {
+ const media = this.mediaController.media;
+ const isVideo =
+ media instanceof HTMLVideoElement && media.videoTracks.length > 0;
+ this.mediaController.controls.autoHideController.fadesWhileIdle = isVideo
+ ? !media.paused && !media.webkitCurrentPlaybackTargetIsWireless
+ : false;
+ }
+}
+class FullscreenSupport extends MediaControllerSupport {
+ get control() {
+ return this.mediaController.controls.fullscreenButton;
+ }
+ get mediaEvents() {
+ return ["loadedmetadata"];
+ }
+ get tracksToMonitor() {
+ return [this.mediaController.media.videoTracks];
+ }
+ buttonWasPressed(control) {
+ const media = this.mediaController.media;
+ if (this.mediaController.isFullscreen) media.webkitExitFullscreen();
+ else media.webkitEnterFullscreen();
+ }
+ syncControl() {
+ const control = this.control;
+ const media = this.mediaController.media;
+ control.enabled =
+ !this.mediaController.isAudio &&
+ (media.readyState < HTMLMediaElement.HAVE_METADATA ||
+ media.webkitSupportsFullscreen);
+ control.isFullScreen = this.mediaController.isFullscreen;
+ }
+}
+class MetadataSupport extends MediaControllerSupport {
+ enable() {
+ super.enable();
+ this.mediaController.shadowRoot.addEventListener(
+ "webkitmediasessionmetadatachanged",
+ this,
+ true,
+ );
+ this.mediaController.host.ensureMediaSessionObserver();
+ }
+ disable() {
+ super.disable();
+ this.mediaController.shadowRoot.removeEventListener(
+ "webkitmediasessionmetadatachanged",
+ this,
+ true,
+ );
+ }
+ get control() {
+ return this.mediaController.controls.metadataContainer;
+ }
+ syncControl(event) {
+ const metadata = window.navigator.mediaSession?.metadata;
+ this.control.title = metadata ? metadata.title : "";
+ this.control.artist = metadata ? metadata.artist : "";
+ }
+}
+class MuteSupport extends MediaControllerSupport {
+ get control() {
+ return this.mediaController.controls.muteButton;
+ }
+ get mediaEvents() {
+ return ["volumechange"];
+ }
+ buttonWasPressed(control) {
+ const media = this.mediaController.media;
+ media.muted = !media.muted;
+ }
+ syncControl() {
+ this.control.volume = this.mediaController.media.volume;
+ this.control.muted = this.mediaController.media.muted;
+ }
+}
+class OverflowSupport extends MediaControllerSupport {
+ get mediaEvents() {
+ return [
+ "abort",
+ "canplay",
+ "canplaythrough",
+ "durationchange",
+ "emptied",
+ "error",
+ "loadeddata",
+ "loadedmetadata",
+ "loadstart",
+ "playing",
+ "stalled",
+ "suspend",
+ "waiting",
+ ];
+ }
+ get tracksToMonitor() {
+ return [this.mediaController.media.textTracks];
+ }
+ get control() {
+ return this.mediaController.controls.overflowButton;
+ }
+ buttonWasPressed(control) {
+ this.mediaController.showMediaControlsContextMenu(control, {
+ includeSubtitles: !this.mediaController.isAudio,
+ });
+ }
+ syncControl() {
+ this.control.enabled = this.mediaController.canShowMediaControlsContextMenu;
+ let defaultContextMenuOptions = { includeShowMediaStats: true };
+ if (this._includePlaybackRates)
+ defaultContextMenuOptions.includePlaybackRates = true;
+ for (let textTrack of this.mediaController.media.textTracks) {
+ if (textTrack.kind !== "chapters") continue;
+ if (textTrack.mode === "disabled") textTrack.mode = "hidden";
+ defaultContextMenuOptions.includeChapters = true;
+ }
+ this.control.defaultContextMenuOptions = defaultContextMenuOptions;
+ }
+ get _includePlaybackRates() {
+ if (this.mediaController.hidePlaybackRates) return false;
+ let media = this.mediaController.media;
+ if (
+ media.duration > maxNonLiveDuration &&
+ media.readyState >= HTMLMediaElement.HAVE_CURRENT_DATA
+ ) {
+ return false;
+ }
+ if (window.MediaStream && media.srcObject instanceof MediaStream) {
+ return false;
+ }
+ return true;
+ }
+}
+const PiPMode = "picture-in-picture";
+const InlineMode = "inline";
+class PiPSupport extends MediaControllerSupport {
+ get control() {
+ return this.mediaController.controls.pipButton;
+ }
+ get mediaEvents() {
+ return [
+ "loadedmetadata",
+ "error",
+ "webkitpresentationmodechanged",
+ "webkitcurrentplaybacktargetiswirelesschanged",
+ ];
+ }
+ get tracksToMonitor() {
+ return [this.mediaController.media.videoTracks];
+ }
+ buttonWasPressed(control) {
+ const media = this.mediaController.media;
+ if (!document.pictureInPictureEnabled) {
+ media.webkitSetPresentationMode(
+ media.webkitPresentationMode === PiPMode ? InlineMode : PiPMode,
+ );
+ return;
+ }
+ if (!document.pictureInPictureElement) media.requestPictureInPicture();
+ else document.exitPictureInPicture();
+ }
+ syncControl() {
+ if (!this.mediaController.layoutTraits?.supportsPiP()) {
+ this.control.enabled = false;
+ return;
+ }
+ const media = this.mediaController.media;
+ if (media.webkitSupportsPresentationMode)
+ this.control.enabled =
+ !this.mediaController.isAudio &&
+ media.webkitSupportsPresentationMode(PiPMode) &&
+ !media.webkitCurrentPlaybackTargetIsWireless;
+ else this.control.enabled = false;
+ }
+}
+class PlacardSupport extends MediaControllerSupport {
+ constructor(mediaController) {
+ super(mediaController);
+ this._updatePlacard();
+ }
+ get mediaEvents() {
+ return [
+ "loadstart",
+ "error",
+ "webkitpresentationmodechanged",
+ "webkitcurrentplaybacktargetiswirelesschanged",
+ ];
+ }
+ handleEvent(event) {
+ this._updatePlacard();
+ }
+ enable() {
+ super.enable();
+ this._isDisabled = false;
+ this._updatePlacard();
+ }
+ disable() {
+ this._isDisabled = true;
+ this._updatePlacard();
+ }
+ _updatePlacard() {
+ const controls = this.mediaController.controls;
+ const media = this.mediaController.media;
+ let placard = null;
+ if (
+ media.webkitPresentationMode === "picture-in-picture" &&
+ this._controlsNeedJavascriptPipPlacard()
+ )
+ placard = controls.pipPlacard;
+ else if (
+ media.webkitPresentationMode === "fullscreen" &&
+ this._controlsNeedJavascriptFullscreenPlacard()
+ )
+ placard = controls.fullscreenPlacard;
+ else if (media.webkitCurrentPlaybackTargetIsWireless) {
+ this._updateAirPlayPlacard();
+ placard = controls.airplayPlacard;
+ } else if (
+ !this._isDisabled &&
+ media instanceof HTMLVideoElement &&
+ media.error !== null &&
+ media.played.length === 0
+ )
+ placard = controls.invalidPlacard;
+ controls.placard = placard;
+ }
+ _controlsNeedJavascriptPipPlacard() {
+ if (this.mediaController.controls instanceof IOSInlineMediaControls)
+ return false;
+ return true;
+ }
+ _controlsNeedJavascriptFullscreenPlacard() {
+ if (
+ this.mediaController.controls instanceof TVOSMediaControls &&
+ this.mediaController.host.isAVExperienceControllerFullscreenEnabled
+ )
+ return true;
+ return false;
+ }
+ _updateAirPlayPlacard() {
+ if (!this.mediaController.host) return;
+ var deviceName = "";
+ var routeName = UIString("AirPlay");
+ switch (this.mediaController.host.externalDeviceType) {
+ case "airplay":
+ deviceName = UIString(
+ "This video is playing on \u201C%s\u201D.",
+ escapeHTML(this.mediaController.host.externalDeviceDisplayName) ||
+ UIString("Apple TV"),
+ );
+ if (this.mediaController.host.externalDeviceRouteName)
+ routeName = escapeHTML(
+ this.mediaController.host.externalDeviceRouteName,
+ );
+ break;
+ case "tvout":
+ deviceName = UIString("This video is playing on the TV.");
+ break;
+ }
+ this.mediaController.controls.airplayPlacard.title = routeName;
+ this.mediaController.controls.airplayPlacard.description = deviceName;
+ }
+}
+function escapeHTML(unsafeString) {
+ var div = document.createElement("div");
+ div.textContent = unsafeString;
+ return div.innerHTML;
+}
+class PlaybackSupport extends MediaControllerSupport {
+ get control() {
+ return this.mediaController.controls.playPauseButton;
+ }
+ get mediaEvents() {
+ return ["play", "pause"];
+ }
+ buttonWasPressed(control) {
+ this.mediaController.togglePlayback();
+ }
+ syncControl() {
+ this.control.playing = !this.mediaController.media.paused;
+ }
+}
+class ScrubbingSupport extends MediaControllerSupport {
+ get control() {
+ return this.mediaController.controls.timeControl.scrubber;
+ }
+ get mediaEvents() {
+ return ["progress"];
+ }
+ controlValueWillStartChanging(control) {
+ const media = this.mediaController.media;
+ const isPaused = media.paused;
+ if (!isPaused) media.pause();
+ this._wasPausedWhenScrubbingStarted = isPaused;
+ }
+ controlValueDidChange(control) {
+ const media = this.mediaController.media;
+ const seekTime = control.value * media.duration;
+ this._targetSeekTime = seekTime;
+ media.fastSeek(seekTime);
+ this.mediaController.controls.timeControl.currentTime = seekTime;
+ }
+ controlValueDidStopChanging(control) {
+ const media = this.mediaController.media;
+ if (this._targetSeekTime && media.currentTime != this._targetSeekTime)
+ media.currentTime = this._targetSeekTime;
+ delete this._targetSeekTime;
+ if (!this._wasPausedWhenScrubbingStarted) this.mediaController.media.play();
+ delete this._wasPausedWhenScrubbingStarted;
+ }
+ syncControl() {
+ const media = this.mediaController.media;
+ if (isNaN(media.duration)) return;
+ const endTimeForBufferedRangeContainingCurrentTime = () => {
+ const ranges = media.buffered;
+ const currentTime = media.currentTime;
+ for (let i = 0; i < ranges.length; ++i) {
+ if (currentTime < ranges.start(i)) continue;
+ const end = ranges.end(i);
+ if (currentTime <= end) return end;
+ }
+ return 0;
+ };
+ this.control.secondaryValue =
+ endTimeForBufferedRangeContainingCurrentTime() / media.duration;
+ }
+}
+class SeekSupport extends MediaControllerSupport {
+ get mediaEvents() {
+ return ["durationchange"];
+ }
+ get multiplier() {}
+ buttonPressedStateDidChange(control, isPressed) {
+ if (isPressed) this._startSeeking();
+ else this._stopSeeking();
+ }
+ syncControl() {
+ this.control.enabled =
+ this.mediaController.media.duration <= maxNonLiveDuration;
+ }
+ _startSeeking() {
+ const media = this.mediaController.media;
+ const isPaused = media.paused;
+ if (isPaused) media.play();
+ this._wasPausedWhenSeekingStarted = isPaused;
+ this._interval = window.setInterval(
+ this._seek.bind(this),
+ SeekSupport.SeekDelay,
+ );
+ this._seek();
+ }
+ _stopSeeking() {
+ const media = this.mediaController.media;
+ media.playbackRate = media.defaultPlaybackRate;
+ if (this._wasPausedWhenSeekingStarted) media.pause();
+ if (this._interval) window.clearInterval(this._interval);
+ }
+ _seek() {
+ const media = this.mediaController.media;
+ media.playbackRate =
+ Math.min(SeekSupport.MaximumSeekRate, Math.abs(media.playbackRate * 2)) *
+ this.multiplier;
+ }
+}
+SeekSupport.MaximumSeekRate = 8;
+SeekSupport.SeekDelay = 1500;
+class SeekBackwardSupport extends SeekSupport {
+ get control() {
+ return this.mediaController.controls.rewindButton;
+ }
+ get multiplier() {
+ return -1;
+ }
+}
+class SeekForwardSupport extends SeekSupport {
+ get control() {
+ return this.mediaController.controls.forwardButton;
+ }
+ get multiplier() {
+ return 1;
+ }
+}
+class SkipBackSupport extends MediaControllerSupport {
+ get control() {
+ return this.mediaController.controls.skipBackButton;
+ }
+ get mediaEvents() {
+ return ["durationchange"];
+ }
+ buttonWasPressed(control) {
+ const media = this.mediaController.media;
+ media.currentTime = Math.max(
+ media.currentTime - this.mediaController.layoutTraits.skipDuration(),
+ media.seekable.start(0),
+ );
+ }
+ syncControl() {
+ const supportsSeeking =
+ !this.mediaController.host || this.mediaController.host.supportsSeeking;
+ this.control.enabled =
+ supportsSeeking &&
+ this.mediaController.media.duration <= maxNonLiveDuration;
+ }
+}
+class SkipForwardSupport extends MediaControllerSupport {
+ get control() {
+ return this.mediaController.controls.skipForwardButton;
+ }
+ get mediaEvents() {
+ return ["durationchange"];
+ }
+ buttonWasPressed(control) {
+ const media = this.mediaController.media;
+ media.currentTime = Math.min(
+ media.currentTime + this.mediaController.layoutTraits.skipDuration(),
+ media.seekable.end(0),
+ );
+ }
+ syncControl() {
+ const supportsSeeking =
+ !this.mediaController.host || this.mediaController.host.supportsSeeking;
+ this.control.enabled =
+ supportsSeeking &&
+ this.mediaController.media.duration <= maxNonLiveDuration;
+ }
+}
+class StartSupport extends MediaControllerSupport {
+ constructor(mediaController) {
+ super(mediaController);
+ this._updateShowsStartButton();
+ }
+ get mediaEvents() {
+ return [
+ "loadedmetadata",
+ "play",
+ "error",
+ this.mediaController.fullscreenChangeEventType,
+ ];
+ }
+ enable() {
+ super.enable();
+ this._updateShowsStartButton();
+ this.mediaController.shadowRoot.addEventListener(
+ "fullscreenchange",
+ this,
+ true,
+ );
+ }
+ disable() {
+ super.disable();
+ this.mediaController.shadowRoot.removeEventListener(
+ "fullscreenchange",
+ this,
+ true,
+ );
+ }
+ buttonWasPressed(control) {
+ this.mediaController.media.play();
+ }
+ handleEvent(event) {
+ super.handleEvent(event);
+ this._updateShowsStartButton();
+ }
+ _updateShowsStartButton() {
+ this.mediaController.controls.showsStartButton =
+ this._shouldShowStartButton();
+ }
+ _shouldShowStartButton() {
+ const media = this.mediaController.media;
+ const host = this.mediaController.host;
+ if (host && host.inWindowFullscreen) return false;
+ if (host && host.shouldForceControlsDisplay) return true;
+ if (this.mediaController.hasPlayed) return false;
+ if (!media.paused) return false;
+ if (media.autoplay) return false;
+ if (media instanceof HTMLAudioElement) return false;
+ if (this.mediaController.isFullscreen) return false;
+ if (media.error) return false;
+ if (!media.controls && host && host.allowsInlineMediaPlayback) return false;
+ return true;
+ }
+}
+class StatusSupport extends MediaControllerSupport {
+ get control() {
+ return this.mediaController.controls.statusLabel;
+ }
+ get mediaEvents() {
+ return [
+ "durationchange",
+ "loadstart",
+ "error",
+ "abort",
+ "suspend",
+ "stalled",
+ "waiting",
+ "playing",
+ "emptied",
+ "loadedmetadata",
+ "loadeddata",
+ "canplay",
+ "canplaythrough",
+ ];
+ }
+ syncControl() {
+ const media = this.mediaController.media;
+ const isLiveBroadcast = media.duration > maxNonLiveDuration;
+ const canPlayThrough =
+ media.readyState === HTMLMediaElement.HAVE_ENOUGH_DATA && !media.error;
+ if (!!media.error) this.control.text = UIString("Error");
+ else if (
+ isLiveBroadcast &&
+ media.readyState >= HTMLMediaElement.HAVE_CURRENT_DATA
+ )
+ this.control.text = UIString("Live Broadcast");
+ else this.control.text = "";
+ this.mediaController.controls.timeControl.loading =
+ !media.played.length &&
+ !canPlayThrough &&
+ media.networkState === HTMLMediaElement.NETWORK_LOADING;
+ }
+}
+class TimeControlSupport extends MediaControllerSupport {
+ enable() {
+ super.enable();
+ this.control.supportsSeeking =
+ !this.mediaController.host || this.mediaController.host.supportsSeeking;
+ }
+ get control() {
+ return this.mediaController.controls.timeControl;
+ }
+ get mediaEvents() {
+ return ["timeupdate", "durationchange"];
+ }
+ syncControl() {
+ const media = this.mediaController.media;
+ this.control.currentTime = media.currentTime;
+ this.control.duration = media.duration;
+ }
+}
+class TracksSupport extends MediaControllerSupport {
+ get control() {
+ return this.mediaController.controls.tracksButton;
+ }
+ get mediaEvents() {
+ return ["loadedmetadata"];
+ }
+ get tracksToMonitor() {
+ return [
+ this.mediaController.media.audioTracks,
+ this.mediaController.media.textTracks,
+ ];
+ }
+ buttonWasPressed(control) {
+ this.mediaController.showMediaControlsContextMenu(control, {
+ promoteSubMenus:
+ this.mediaController.layoutTraits.promoteSubMenusWhenShowingMediaControlsContextMenu(),
+ includeSubtitles: !this.mediaController.isAudio,
+ });
+ }
+ syncControl() {
+ this.control.enabled =
+ this.mediaController.canShowMediaControlsContextMenu &&
+ (this._canPickAudioTracks() || this._canPickTextTracks());
+ }
+ _textTracks() {
+ return this._sortedTrackList(this.mediaController.media.textTracks);
+ }
+ _audioTracks() {
+ return this._sortedTrackList(this.mediaController.media.audioTracks);
+ }
+ _canPickAudioTracks() {
+ const audioTracks = this.mediaController.media.audioTracks;
+ return audioTracks && audioTracks.length > 1;
+ }
+ _canPickTextTracks() {
+ if (this.mediaController.isAudio) return false;
+ const textTracks = this.mediaController.media.textTracks;
+ return textTracks && textTracks.length > 0;
+ }
+ _sortedTrackList(tracks) {
+ return this.mediaController.host
+ ? this.mediaController.host.sortedTrackListForMenu(tracks)
+ : Array.from(tracks);
+ }
+}
+class VolumeSupport extends MediaControllerSupport {
+ get control() {
+ return this.mediaController.controls.volumeSlider;
+ }
+ get mediaEvents() {
+ return ["volumechange"];
+ }
+ controlValueWillStartChanging(control) {
+ this._volumeBeforeChange = this.mediaController.media.volume;
+ }
+ controlValueDidChange(control) {
+ this.mediaController.media.volume =
+ control.value === 0 && this._volumeBeforeChange > 0
+ ? this._volumeBeforeChange
+ : control.value;
+ this.mediaController.media.muted = control.value === 0;
+ }
+ syncControl(event) {
+ const media = this.mediaController.media;
+ const controlValue = media.muted ? 0 : media.volume;
+ if (event) this.control.setValueAnimated(controlValue);
+ else this.control.value = controlValue;
+ }
+}
+class MediaDocumentController {
+ constructor(mediaController) {
+ this.mediaController = mediaController;
+ mediaController.controls.shouldUseAudioLayout = true;
+ mediaController.controls.timeControl.loading = true;
+ const media = mediaController.media;
+ media.classList.add("media-document");
+ media.classList.add("audio");
+ let deviceType = window.navigator.platform;
+ if (deviceType == "MacIntel")
+ deviceType = mediaController.layoutTraits.supportsTouches()
+ ? "ipad"
+ : "mac";
+ else if (deviceType.startsWith("Linux")) deviceType = "linux";
+ media.classList.add(deviceType);
+ }
+ layout() {
+ scheduler.scheduleLayout(() => {
+ const media = this.mediaController.media;
+ const isInvalid = media.error !== null && media.played.length === 0;
+ const useVideoLayout =
+ isInvalid ||
+ (media.readyState >= HTMLMediaElement.HAVE_METADATA &&
+ !this.mediaController.isAudio);
+ const classList = media.classList;
+ classList.toggle("invalid", isInvalid);
+ classList.toggle("video", useVideoLayout);
+ classList.toggle("audio", !useVideoLayout);
+ });
+ }
+}
+class WatchOSMediaControlsSupport extends MediaControllerSupport {
+ get mediaEvents() {
+ return ["pause", "error"];
+ }
+ handleEvent(event) {
+ switch (event.type) {
+ case "pause":
+ this.mediaController.controls.state = WatchOSMediaControls.State.Paused;
+ break;
+ case "error":
+ this.mediaController.controls.state =
+ WatchOSMediaControls.State.Invalid;
+ break;
+ }
+ }
+ enable() {
+ super.enable();
+ for (let button of this._buttons) button.uiDelegate = this;
+ }
+ disable() {
+ super.disable();
+ for (let button of this._buttons) button.uiDelegate = null;
+ }
+ buttonWasPressed(button) {
+ switch (button) {
+ case this.mediaController.controls.playButton:
+ this.mediaController.media.play();
+ this.mediaController.controls.state =
+ WatchOSMediaControls.State.Pending;
+ break;
+ case this.mediaController.controls.activityIndicator:
+ this.mediaController.media.pause();
+ this.mediaController.controls.state = WatchOSMediaControls.State.Paused;
+ break;
+ }
+ }
+ get _buttons() {
+ return [
+ this.mediaController.controls.playButton,
+ this.mediaController.controls.activityIndicator,
+ ];
+ }
+}
+const maxNonLiveDuration = 604800;
+const MaximumNarrowViewerControlsBarWidth = 468;
+class MediaController {
+ static EmptyRanges = {
+ get length() {
+ return 0;
+ },
+ start: function (index) {
+ return undefined;
+ },
+ end: function (index) {
+ return undefined;
+ },
+ };
+ static NullMedia = {
+ get audioTracks() {
+ return [];
+ },
+ get autoplay() {
+ return false;
+ },
+ get buffered() {
+ return MediaController.EmptyRanges;
+ },
+ get controls() {
+ return false;
+ },
+ get currentTime() {
+ return 0;
+ },
+ set currentTime(time) {},
+ get defaultPlaybackRate() {
+ return 1;
+ },
+ set defaultPlaybackRate(rate) {},
+ get duration() {
+ return 0;
+ },
+ get error() {
+ return null;
+ },
+ get muted() {
+ return false;
+ },
+ set muted(muted) {},
+ get networkState() {
+ return HTMLMediaElement.NETWORK_NO_SOURCE;
+ },
+ get paused() {
+ return false;
+ },
+ get playbackRate() {
+ return 1;
+ },
+ set playbackRate(rate) {},
+ get played() {
+ return MediaController.EmptyRanges;
+ },
+ get readyState() {
+ return HTMLMediaElement.HAVE_NOTHING;
+ },
+ get seekable() {
+ return MediaController.EmptyRanges;
+ },
+ get textTracks() {
+ return [];
+ },
+ get videoTracks() {
+ return [];
+ },
+ get volume() {
+ return 1;
+ },
+ set volume(volume) {},
+ get webkitCurrentPlaybackTargetIsWireless() {
+ return false;
+ },
+ get webkitPresentationMode() {
+ return "inline";
+ },
+ get webkitSupportsFullscreen() {
+ return false;
+ },
+ pause: function () {},
+ play: function () {},
+ fastSeek: function (time) {},
+ requestPictureInPicture: function () {},
+ webkitEnterFullscreen: function () {},
+ webkitExitFullscreen: function () {},
+ webkitSetPresentationMode: function (mode) {},
+ webkitShowPlaybackTargetPicker: function () {},
+ webkitSupportsPresentationMode: function (mode) {
+ return false;
+ },
+ };
+ constructor(shadowRoot, media, host) {
+ this.shadowRootWeakRef = new WeakRef(shadowRoot);
+ this.mediaWeakRef = new WeakRef(media);
+ this.host = host;
+ this.fullscreenChangeEventType = media.webkitSupportsPresentationMode
+ ? "webkitpresentationmodechanged"
+ : "webkitfullscreenchange";
+ this.hasPlayed = !media.paused || !!media.played.length;
+ this.container = shadowRoot.appendChild(document.createElement("div"));
+ this._updateControlsIfNeeded();
+ this._usesLTRUserInterfaceLayoutDirection = false;
+ if (host) {
+ this.container.className = host.mediaControlsContainerClassName;
+ host.controlsDependOnPageScaleFactor =
+ this.layoutTraits.controlsDependOnPageScaleFactor();
+ this.container.insertBefore(
+ host.textTrackContainer,
+ this.controls.element,
+ );
+ if (host.isInMediaDocument)
+ this.mediaDocumentController = new MediaDocumentController(this);
+ }
+ scheduler.flushScheduledLayoutCallbacks();
+ shadowRoot.addEventListener("resize", this);
+ shadowRoot.addEventListener("fullscreenchange", this);
+ media.videoTracks.addEventListener("addtrack", this);
+ media.videoTracks.addEventListener("removetrack", this);
+ media.addEventListener("play", this);
+ media.addEventListener(this.fullscreenChangeEventType, this);
+ media.addEventListener("keydown", this);
+ media.addEventListener("keyup", this);
+ media.addEventListener("click", this);
+ window.addEventListener("keydown", this);
+ new MutationObserver(this._updateControlsAvailability.bind(this)).observe(
+ this.media,
+ { attributes: true, attributeFilter: ["controls"] },
+ );
+ }
+ get media() {
+ return this.mediaWeakRef.deref() ?? MediaController.NullMedia;
+ }
+ get shadowRoot() {
+ return this.shadowRootWeakRef ? this.shadowRootWeakRef.deref() : null;
+ }
+ get isAudio() {
+ if (this.media instanceof HTMLAudioElement) return true;
+ if (
+ this.host &&
+ !this.host.isInMediaDocument &&
+ this.media instanceof HTMLVideoElement
+ )
+ return false;
+ if (this.media.readyState < HTMLMediaElement.HAVE_METADATA) return false;
+ if (this.media.videoWidth || this.media.videoHeight) return false;
+ return !this.media.videoTracks.length;
+ }
+ get isYouTubeEmbedWithTitle() {
+ const url = new URL(this.media.ownerDocument.defaultView.location.href);
+ return (
+ url.href.includes("youtube.com/embed/") &&
+ url.searchParams.get("showinfo") !== "0"
+ );
+ }
+ get isFullscreen() {
+ if (!this.media) return false;
+ return this.media.webkitSupportsPresentationMode
+ ? this.media.webkitPresentationMode === "fullscreen" ||
+ (this.host && this.host.inWindowFullscreen)
+ : this.media.webkitDisplayingFullscreen;
+ }
+ get layoutTraits() {
+ let mode = LayoutTraits.Mode.Inline;
+ if (this.isFullscreen) {
+ if (
+ this.host &&
+ this.host.inWindowFullscreen &&
+ this.media.offsetWidth < MaximumNarrowViewerControlsBarWidth
+ )
+ mode = LayoutTraits.Mode.NarrowViewer;
+ else mode = LayoutTraits.Mode.Fullscreen;
+ }
+ if (this.host) {
+ let LayoutTraitsClass =
+ window.layoutTraitsClasses[this.host.layoutTraitsClassName];
+ return new LayoutTraitsClass(mode);
+ }
+ return new MacOSLayoutTraits(mode);
+ }
+ togglePlayback() {
+ if (this.media.paused || !this.hasPlayed)
+ this.media.play().catch((e) => {});
+ else this.media.pause();
+ }
+ get canShowMediaControlsContextMenu() {
+ return !!this.host?.showMediaControlsContextMenu;
+ }
+ showMediaControlsContextMenu(button, options = {}) {
+ if (!this.canShowMediaControlsContextMenu) return false;
+ let autoHideController = this.controls.autoHideController;
+ let willShowContextMenu = this.host.showMediaControlsContextMenu(
+ button.element,
+ { ...button.contextMenuOptions, ...options },
+ () => {
+ button.on = false;
+ autoHideController.hasSecondaryUIAttached = false;
+ },
+ );
+ if (willShowContextMenu) {
+ button.on = true;
+ autoHideController.hasSecondaryUIAttached = true;
+ }
+ return willShowContextMenu;
+ }
+ set pageScaleFactor(pageScaleFactor) {
+ this.controls.scaleFactor = pageScaleFactor;
+ this._updateControlsSize();
+ }
+ set usesLTRUserInterfaceLayoutDirection(flag) {
+ if (this._usesLTRUserInterfaceLayoutDirection === flag) return;
+ this._usesLTRUserInterfaceLayoutDirection = flag;
+ this.controls.usesLTRUserInterfaceLayoutDirection = flag;
+ }
+ mediaControlsVisibilityDidChange() {
+ this._controlsUserVisibilityDidChange();
+ }
+ mediaControlsFadedStateDidChange() {
+ this._controlsUserVisibilityDidChange();
+ this._updateTextTracksClassList();
+ }
+ macOSControlsBackgroundWasClicked() {
+ if (
+ this.media.controls ||
+ (this.host && this.host.shouldForceControlsDisplay)
+ )
+ this.togglePlayback();
+ }
+ iOSInlineMediaControlsRecognizedTapGesture() {
+ if (this.media.controls) this.media.play();
+ }
+ iOSInlineMediaControlsRecognizedPinchInGesture() {
+ this.media.webkitEnterFullscreen();
+ }
+ handleEvent(event) {
+ if (
+ event instanceof TrackEvent &&
+ event.currentTarget === this.media.videoTracks
+ )
+ this._updateControlsIfNeeded();
+ else if (
+ event.type === "resize" &&
+ event.currentTarget === this.shadowRoot
+ ) {
+ this._updateControlsIfNeeded();
+ scheduler.flushScheduledLayoutCallbacks();
+ } else if (
+ event.type === "fullscreenchange" &&
+ event.currentTarget === this.shadowRoot
+ ) {
+ this._updateControlsAvailability();
+ } else if (
+ event.type === "keydown" &&
+ this.isFullscreen &&
+ event.key === " "
+ ) {
+ this.togglePlayback();
+ event.preventDefault();
+ event.stopPropagation();
+ } else if (
+ event.type === "keyup" &&
+ this.isFullscreen &&
+ event.key === " "
+ ) {
+ event.preventDefault();
+ event.stopPropagation();
+ } else if (event.type === "dragstart" && this.isFullscreen)
+ event.preventDefault();
+ else if (event.type === this.fullscreenChangeEventType)
+ this.host?.presentationModeChanged?.();
+ else if (event.type === "click" && event.target === this.media) {
+ if (this.host && this.host.inWindowFullscreen) {
+ this.media.webkitExitFullscreen();
+ event.stopPropagation();
+ }
+ }
+ if (event.currentTarget === this.media) {
+ if (event.type === "play") this.hasPlayed = true;
+ this._updateControlsIfNeeded();
+ this._updateControlsAvailability();
+ }
+ }
+ setShowingStats(shouldShowStats) {
+ if (!(this.media instanceof HTMLVideoElement)) return false;
+ if (!shouldShowStats) {
+ this._statsContainer?.remove();
+ this._statsContainer = null;
+ return false;
+ }
+ if (this._statsContainer) return true;
+ this._statsContainer = this.container.appendChild(
+ document.createElement("div"),
+ );
+ this._statsContainer.className = "stats-container";
+ let table = this._statsContainer.appendChild(
+ document.createElement("table"),
+ );
+ function createRow(label) {
+ let rowElement = table.appendChild(document.createElement("tr"));
+ let labelElement = rowElement.appendChild(document.createElement("th"));
+ labelElement.textContent = label;
+ let valueElement = rowElement.appendChild(document.createElement("td"));
+ return valueElement;
+ }
+ let sourceValueElement = createRow(UIString("Source"));
+ let viewportValueElement = createRow(UIString("Viewport"));
+ let framesValueElement = createRow(UIString("Frames"));
+ let resolutionValueElement = createRow(UIString("Resolution"));
+ let codecsValueElement = createRow(UIString("Codecs"));
+ let colorValueElement = createRow(UIString("Color"));
+ let update = () => {
+ if (!this._statsContainer) return;
+ let quality = this.media.getVideoPlaybackQuality();
+ let videoTrack = this.media.videoTracks.item(
+ this.media.videoTracks.selectedIndex,
+ );
+ let videoTrackConfiguration = videoTrack.configuration;
+ let videoColorSpace = videoTrackConfiguration?.colorSpace;
+ sourceValueElement.textContent = UIString(this.host.sourceType ?? "none");
+ viewportValueElement.textContent =
+ UIString("%s\u00d7%s", this.controls.width, this.controls.height) +
+ (window.devicePixelRatio !== 1
+ ? " " +
+ UIString("(%s)", UIString("%s\u00d7", window.devicePixelRatio))
+ : "");
+ framesValueElement.textContent = UIString(
+ "%s dropped of %s",
+ quality.droppedVideoFrames,
+ quality.totalVideoFrames,
+ );
+ resolutionValueElement.textContent =
+ UIString(
+ "%s\u00d7%s",
+ videoTrackConfiguration?.width,
+ videoTrackConfiguration?.height,
+ ) +
+ " " +
+ UIString(
+ "(%s)",
+ UIString(
+ "%sfps",
+ Math.round(videoTrackConfiguration?.framerate * 1000) / 1000,
+ ),
+ );
+ codecsValueElement.textContent = videoTrackConfiguration?.codec;
+ colorValueElement.textContent = UIString(
+ "%s / %s / %s",
+ videoColorSpace?.primaries,
+ videoColorSpace?.transfer,
+ videoColorSpace?.matrix,
+ );
+ window.requestAnimationFrame(update);
+ };
+ update();
+ return true;
+ }
+ deinitialize() {
+ this.shadowRoot.removeChild(this.container);
+ window.removeEventListener("keydown", this);
+ if (this.controls) this.controls.disable();
+ return true;
+ }
+ reinitialize(shadowRoot, media, host) {
+ iconService.shadowRoot = shadowRoot;
+ this.shadowRootWeakRef = new WeakRef(shadowRoot);
+ this.mediaWeakRef = new WeakRef(media);
+ this.host = host;
+ shadowRoot.appendChild(this.container);
+ window.addEventListener("keydown", this);
+ if (this.controls) this.controls.reenable();
+ return true;
+ }
+ _updateControlsIfNeeded() {
+ const layoutTraits = this.layoutTraits;
+ const previousControls = this.controls;
+ const ControlsClass = layoutTraits.mediaControlsClass();
+ if (previousControls && previousControls.constructor === ControlsClass) {
+ this._updateTextTracksClassList();
+ this._updateControlsSize();
+ return;
+ }
+
+ if (this._supportingObjects) {
+ for (let supportingObject of this._supportingObjects)
+ supportingObject.disable();
+ }
+ if (previousControls) previousControls.disable();
+ this.controls = new ControlsClass({ mode: layoutTraits.mode });
+ this.controls.delegate = this;
+ if (
+ this.controls.autoHideController &&
+ this.shadowRoot.host &&
+ this.shadowRoot.host.dataset.autoHideDelay
+ )
+ this.controls.autoHideController.autoHideDelay =
+ this.shadowRoot.host.dataset.autoHideDelay;
+ if (previousControls) {
+ this.controls.fadeIn();
+ this.container.replaceChild(
+ this.controls.element,
+ previousControls.element,
+ );
+ this.controls.usesLTRUserInterfaceLayoutDirection =
+ previousControls.usesLTRUserInterfaceLayoutDirection;
+ } else this.container.appendChild(this.controls.element);
+ this._updateTextTracksClassList();
+ this._updateControlsSize();
+ this._supportingObjects = layoutTraits
+ .supportingObjectClasses()
+ .map((SupportClass) => new SupportClass(this), this);
+ this.controls.shouldUseSingleBarLayout =
+ this.controls instanceof InlineMediaControls &&
+ this.isYouTubeEmbedWithTitle;
+ if (this.controls instanceof MacOSFullscreenMediaControls)
+ window.addEventListener("dragstart", this, true);
+ else window.removeEventListener("dragstart", this, true);
+ this._stopPropagationOnTouchEvents();
+ if (this.host && this.host.inWindowFullscreen) {
+ this._stopPropagationOnClickEvents();
+ if (!this.host.supportsRewind && this.controls.rewindButton)
+ this.controls.rewindButton.dropped = true;
+ }
+ this._updateControlsAvailability();
+ if (this.host?.needsChromeMediaControlsPseudoElement)
+ this.controls.element.setAttribute(
+ "useragentpart",
+ "-webkit-media-controls",
+ );
+ }
+ _stopPropagationOnClickEvents() {
+ let clickEvents = [
+ "click",
+ "mousedown",
+ "mouseup",
+ "pointerdown",
+ "pointerup",
+ ];
+ for (let clickEvent of clickEvents) {
+ this.controls.element.addEventListener(clickEvent, (event) => {
+ event.stopPropagation();
+ });
+ }
+ }
+ _stopPropagationOnTouchEvents() {
+ let touchEvents = ["touchstart", "touchmove", "touchend"];
+ for (let touchEvent of touchEvents) {
+ this.controls.element.addEventListener(touchEvent, (event) => {
+ if (event.target !== this.controls.element) event.stopPropagation();
+ });
+ }
+ }
+ _updateControlsSize() {
+ this.controls.width = Math.round(
+ this.container.offsetWidth * this.controls.scaleFactor,
+ );
+ this.controls.height = Math.round(
+ this.container.offsetHeight * this.controls.scaleFactor,
+ );
+ }
+ _updateTextTracksClassList() {
+ if (!this.host) return;
+ if (this.layoutTraits.isFullscreen) return;
+ this.host.textTrackContainer.classList.toggle(
+ "visible-controls-bar",
+ !this.controls.faded,
+ );
+ }
+ _controlsUserVisibilityDidChange() {
+ if (!this.controls || !this._supportingObjects) return;
+ this._supportingObjects.forEach((supportingObject) =>
+ supportingObject.controlsUserVisibilityDidChange(),
+ );
+ }
+ _shouldControlsBeAvailable() {
+ if (this.layoutTraits.controlsNeverAvailable()) return false;
+ if (
+ this.controls instanceof IOSInlineMediaControls &&
+ this.media.webkitPresentationMode === "picture-in-picture"
+ )
+ return false;
+ return (
+ this.media.controls ||
+ !!(this.host && this.host.shouldForceControlsDisplay)
+ );
+ }
+ _updateControlsAvailability() {
+ const shouldControlsBeAvailable = this._shouldControlsBeAvailable();
+ if (!shouldControlsBeAvailable)
+ this._supportingObjects.forEach((supportingObject) =>
+ supportingObject.disable(),
+ );
+ else
+ this._supportingObjects.forEach((supportingObject) =>
+ supportingObject.enable(),
+ );
+ this.controls.visible = shouldControlsBeAvailable;
+ }
+ set maximumRightContainerButtonCountOverride(count) {
+ this.controls.maximumRightContainerButtonCountOverride = count;
+ }
+}
diff --git a/27.0/js/media/YouTubeCaptionQuirk.js b/27.0/js/media/YouTubeCaptionQuirk.js
new file mode 100644
index 0000000..a54fc3b
--- /dev/null
+++ b/27.0/js/media/YouTubeCaptionQuirk.js
@@ -0,0 +1,202 @@
+//# sourceURL=__InjectedScript_YouTubeCaptionQuirk.js
+(function () {
+ "use strict";
+ class CaptionMirror {
+ static _instances = new WeakMap();
+ constructor(video) {
+ let oldMirror = CaptionMirror._instances.get(video);
+ if (oldMirror) {
+ oldMirror.invalidate();
+ CaptionMirror._instances.delete(video);
+ }
+ CaptionMirror._instances.set(video, this);
+ this._video = video;
+ this._player = video.parentElement.parentElement;
+ this._captionWindowSelector = ".ytp-caption-window-container";
+ this._mirrorTrack = video.addTextTrack("forced", "YouTube Captions");
+ this._mirrorTrack.mode = "hidden";
+ this._captionObserver = null;
+ this._waitObserver = null;
+ this._onCaptionsTrackListChanged = () => this._syncTrackList();
+ this._onCaptionsChanged = () => this._syncTrackList();
+ this._player.addEventListener(
+ "onCaptionsTrackListChanged",
+ this._onCaptionsTrackListChanged,
+ );
+ this._player.addEventListener("captionschanged", this._onCaptionsChanged);
+ navigator.mediaSession.setActionHandler("togglecaptions", (details) =>
+ this._handleMediaSessionAction(details),
+ );
+ navigator.mediaSession.setActionHandler("selectcaptiontrack", (details) =>
+ this._handleMediaSessionAction(details),
+ );
+ this._onPresentationModeChanged = () =>
+ this._handlePresentationModeChanged();
+ this._video.addEventListener(
+ "webkitpresentationmodechanged",
+ this._onPresentationModeChanged,
+ );
+ this._attachCaptionWindowObserver();
+ this._syncTrackList();
+ }
+ invalidate() {
+ if (this._captionObserver) {
+ this._captionObserver.disconnect();
+ this._captionObserver = null;
+ }
+ if (this._waitObserver) {
+ this._waitObserver.disconnect();
+ this._waitObserver = null;
+ }
+ this._mirrorTrack.mode = "disabled";
+ this._player.removeEventListener(
+ "onCaptionsTrackListChanged",
+ this._onCaptionsTrackListChanged,
+ );
+ this._player.removeEventListener(
+ "captionschanged",
+ this._onCaptionsChanged,
+ );
+ this._video.removeEventListener(
+ "webkitpresentationmodechanged",
+ this._onPresentationModeChanged,
+ );
+ }
+ _syncTrackList() {
+ var trackList = this._getTrackList();
+ var activeTrack = this._getActiveTrack();
+ navigator.mediaSession.captionTracks =
+ trackList?.map((track) => {
+ return {
+ label: track.displayName,
+ language: track.languageCode,
+ enabled: this._areTracksEqual(track, activeTrack),
+ };
+ }) ?? [];
+ navigator.mediaSession.captionsEnabled = this._player.isSubtitlesOn();
+ }
+ _syncCues(captionWindowContainer) {
+ while (this._mirrorTrack.cues?.length)
+ this._mirrorTrack.removeCue(this._mirrorTrack.cues[0]);
+ for (var captionWindow of captionWindowContainer.querySelectorAll(
+ ".caption-window",
+ )) {
+ var text = Array.from(
+ captionWindow.querySelectorAll(".captions-text > span"),
+ )
+ .map((span) => span.textContent)
+ .join("\n");
+ if (!text) continue;
+ var cue = new VTTCue(0, 10e7, text);
+ switch (captionWindow.style.textAlign) {
+ case "left":
+ case "start":
+ cue.align = "start";
+ cue.positionAlign = "line-left";
+ break;
+ case "end":
+ case "right":
+ cue.align = "end";
+ cue.positionAlign = "line-right";
+ break;
+ default:
+ cue.align = "center";
+ cue.positionAlign = "center";
+ }
+ var topPercent = parseFloat(captionWindow.style.top);
+ var bottomPercent = parseFloat(captionWindow.style.bottom);
+ var leftPercent = parseFloat(captionWindow.style.left);
+ var rightPercent = parseFloat(captionWindow.style.right);
+ if (!isNaN(topPercent)) {
+ cue.snapToLines = false;
+ cue.line = topPercent;
+ } else if (!isNaN(bottomPercent)) {
+ cue.snapToLines = false;
+ cue.line = 100 - bottomPercent;
+ }
+ if (!isNaN(leftPercent)) cue.position = leftPercent;
+ else if (!isNaN(rightPercent)) cue.position = 100 - rightPercent;
+ this._mirrorTrack.addCue(cue);
+ }
+ }
+ _attachCaptionWindowObserver() {
+ var container = this._player.querySelector(this._captionWindowSelector);
+ if (container) this._attachCaptionObserver(container);
+ else {
+ this._waitObserver = new MutationObserver(() => {
+ var container = this._player.querySelector(
+ this._captionWindowSelector,
+ );
+ if (container) {
+ this._attachCaptionObserver(container);
+ this._waitObserver.disconnect();
+ this._waitObserver = null;
+ }
+ });
+ this._waitObserver.observe(this._player, {
+ childList: true,
+ subtree: true,
+ });
+ }
+ }
+ _attachCaptionObserver(container) {
+ if (this._captionObserver) this._captionObserver.disconnect();
+ this._captionObserver = new MutationObserver(() => {
+ var container = this._player.querySelector(this._captionWindowSelector);
+ if (container) this._syncCues(container);
+ });
+ this._captionObserver.observe(container, {
+ childList: true,
+ subtree: true,
+ characterData: true,
+ });
+ }
+ _getIsInline() {
+ if (typeof this._video.webkitPresentationMode === "undefined")
+ return !this._video.webkitDisplayingFullscreen;
+ return this._video.webkitPresentationMode == "inline";
+ }
+ _handlePresentationModeChanged() {
+ var captionContainer = this._player.querySelector(
+ this._captionWindowSelector,
+ );
+ if (this._getIsInline()) {
+ this._mirrorTrack.mode = "hidden";
+ if (captionContainer)
+ captionContainer.style.removeProperty("visibility");
+ return;
+ }
+ this._player.loadModule("captions");
+ this._mirrorTrack.mode = "showing";
+ if (captionContainer)
+ captionContainer.style.setProperty("visibility", "hidden", "important");
+ }
+ _handleMediaSessionAction(details) {
+ switch (details.action) {
+ case "togglecaptions":
+ this._player.toggleSubtitles();
+ break;
+ case "selectcaptiontrack": {
+ var list = this._getTrackList();
+ var index = details.trackIndex;
+ if (index >= 0 && index < list.length)
+ this._player.setOption("captions", "track", list[index]);
+ else this._player.setOption("captions", "track", {});
+ break;
+ }
+ }
+ }
+ _getTrackList() {
+ return this._player.getOption("captions", "tracklist") || [];
+ }
+ _getActiveTrack() {
+ return this._player.getOption("captions", "track");
+ }
+ _areTracksEqual(a, b) {
+ return a && b && a.vss_id === b.vss_id;
+ }
+ }
+ window.setupCaptionMirroring = function (video) {
+ new CaptionMirror(video);
+ };
+})();
diff --git a/27.0/js/metadata/MetadataExtractor.js b/27.0/js/metadata/MetadataExtractor.js
new file mode 100644
index 0000000..36dfaac
--- /dev/null
+++ b/27.0/js/metadata/MetadataExtractor.js
@@ -0,0 +1,105 @@
+//# sourceURL=__InjectedScript_MetadataExtractor.js
+/* Copyright (c) 2026 Apple Inc. All rights reserved. */
+function getIconType(e) {
+ var o = e.getAttribute("rel");
+ return "apple-touch-icon" === o
+ ? IconTypeAppleTouchIcon
+ : "apple-touch-icon-precomposed" === o
+ ? IconTypeAppleTouchIconPrecomposed
+ : IconTypeFavicon;
+}
+function compareIconsDescending(e, o) {
+ var c = getIconType(e),
+ t = getIconType(o);
+ if (c === IconTypeFavicon && t !== IconTypeFavicon) return 1;
+ if (t === IconTypeFavicon && c !== IconTypeFavicon) return -1;
+ var n = e.getAttribute("sizes"),
+ r = o.getAttribute("sizes"),
+ p = 0,
+ a = 0;
+ return (
+ n
+ ? (p = parseInt(n))
+ : n ||
+ (c !== IconTypeAppleTouchIcon &&
+ c !== IconTypeAppleTouchIconPrecomposed) ||
+ (p = AppleTouchIconDefaultWidth),
+ r
+ ? (a = parseInt(r))
+ : r ||
+ (t !== IconTypeAppleTouchIcon &&
+ t !== IconTypeAppleTouchIconPrecomposed) ||
+ (a = AppleTouchIconDefaultWidth),
+ a > p
+ ? 1
+ : a < p
+ ? -1
+ : c !== IconTypeAppleTouchIconPrecomposed &&
+ t === IconTypeAppleTouchIconPrecomposed
+ ? 1
+ : t !== IconTypeAppleTouchIconPrecomposed &&
+ c === IconTypeAppleTouchIconPrecomposed
+ ? -1
+ : 0
+ );
+}
+function colorComponentsFromString(e) {
+ var o = document.createElement("canvas");
+ ((o.width = 1), (o.height = 1));
+ var c = o.getContext("2d");
+ ((c.fillStyle = e), c.fillRect(0, 0, 1, 1));
+ var t = c.getImageData(0, 0, 1, 1);
+ return [t.data[0], t.data[1], t.data[2]];
+}
+var MetadataExtractor = function () {};
+const IconTypeFavicon = 0,
+ IconTypeAppleTouchIcon = 1,
+ IconTypeAppleTouchIconPrecomposed = 2,
+ AppleTouchIconDefaultWidth = 60;
+MetadataExtractor.prototype = {
+ extractAndSortIconsWithSelector: function (e) {
+ var o = document.head.querySelectorAll(e);
+ return o.length
+ ? Array.prototype.slice.call(o).sort(compareIconsDescending)
+ : [];
+ },
+ extractAppleTouchIconURLs: function () {
+ for (
+ var e = this.extractAndSortIconsWithSelector(
+ "link[rel=apple-touch-icon], link[rel=apple-touch-icon-precomposed]",
+ ),
+ o = [],
+ c = 0;
+ c < e.length;
+ ++c
+ ) {
+ var t = e[c].href;
+ t && o.push(t);
+ }
+ return o;
+ },
+ extractFaviconURLs: function () {
+ for (
+ var e = this.extractAndSortIconsWithSelector(
+ "link[rel='shortcut icon'], link[rel=icon]",
+ ),
+ o = [],
+ c = e.length,
+ t = 0;
+ t < c;
+ ++t
+ )
+ o.push(e[t].href);
+ return o;
+ },
+ extractTemplateIconURLAndColor: function () {
+ var e = document.head.querySelector("link[rel=mask-icon]");
+ if (!e) return null;
+ var o = e.getAttribute("color");
+ return o && e.href
+ ? { url: e.href, color: colorComponentsFromString(o) }
+ : null;
+ },
+};
+var MetadataExtractorJS = new MetadataExtractor();
+0;
diff --git a/27.0/js/metadata/WebClipMetadataFetcher.js b/27.0/js/metadata/WebClipMetadataFetcher.js
new file mode 100644
index 0000000..571a3a4
--- /dev/null
+++ b/27.0/js/metadata/WebClipMetadataFetcher.js
@@ -0,0 +1,116 @@
+//# sourceURL=__InjectedScript_WebClipMetadataFetcher.js
+/* Copyright (c) 2026 Apple Inc. All rights reserved. */
+/*
+ * Copyright (c) 2014 Apple Inc. All rights reserved.
+ */
+const MetaTagNamesToScrape = [
+ "apple-mobile-web-app-capable",
+ "apple-mobile-web-app-title",
+ "viewport",
+ "apple-mobile-web-app-status-bar-style",
+ ],
+ LinkRelTypesToScrape = [
+ "apple-touch-icon",
+ "apple-touch-icon-precomposed",
+ "apple-touch-startup-image",
+ "icon",
+ "shortcut icon",
+ ];
+var Orientation = { Portrait: 0, Landscape: 1 },
+ WebClipMetadataFinder = function () {};
+WebClipMetadataFinder.prototype = {
+ webClipMetadata: function () {
+ return {
+ metaTags: this.metaTagsMetadata(),
+ linkTags: this.linkTagsMetadata(),
+ canonicalURLString: this.canonicalURLStringForPage(),
+ };
+ },
+ metaTagsMetadata: function () {
+ function e(e) {
+ if ("apple-mobile-web-app-status-bar-style" === e.name)
+ e.content.toLowerCase();
+ }
+ for (
+ var t = {},
+ a = document.head.getElementsByTagName("meta"),
+ i = a.length,
+ n = 0;
+ n < i;
+ ++n
+ ) {
+ var r = a[n],
+ o = r.name;
+ -1 !== MetaTagNamesToScrape.indexOf(o) && (e(r), (t[o] = r.content));
+ }
+ return t;
+ },
+ currentOrientation: function () {
+ return (
+ void 0 === this._currentOrientation &&
+ (window.matchMedia("(orientation: portrait)").matches
+ ? (this._currentOrientation = Orientation.Portrait)
+ : (this._currentOrientation = Orientation.Landscape)),
+ this._currentOrientation
+ );
+ },
+ canonicalURLStringForPage: function () {
+ var e = document.head.querySelector("link[rel='canonical']");
+ return e ? e.href : "";
+ },
+ linkTagsMetadata: function () {
+ for (
+ var e = [],
+ t = document.head.getElementsByTagName("link"),
+ a = t.length,
+ i = 0;
+ i < a;
+ ++i
+ ) {
+ var n = t[i],
+ r = n.rel;
+ if (-1 !== LinkRelTypesToScrape.indexOf(r)) {
+ var o = n.href,
+ c = n.getAttribute("sizes");
+ if (o) {
+ var s = n.media,
+ p = !0,
+ d = !0;
+ if (s) {
+ var u = window.matchMedia(s);
+ ((p = this.mediaQueryListMatchesOrientation(
+ u,
+ Orientation.Portrait,
+ )),
+ (d = this.mediaQueryListMatchesOrientation(
+ u,
+ Orientation.Landscape,
+ )));
+ }
+ var l = {
+ rel: r,
+ href: o,
+ mediaMatchesPortraitOrientation: p,
+ mediaMatchesLandscapeOrientation: d,
+ };
+ (c && (l.sizes = c), e.push(l));
+ }
+ }
+ }
+ return e;
+ },
+ mediaQueryListMatchesOrientation: function (e, t) {
+ var a = e.media;
+ if ("invalid" === a) return !1;
+ if (t === this.currentOrientation()) return e.matches;
+ var i = this.reverseMediaQueryOrientation(a);
+ return window.matchMedia(i).matches;
+ },
+ reverseMediaQueryOrientation: function (e) {
+ return e.replace(/orientation: (portrait|landscape)/, function (e, t) {
+ return "orientation: " + ("portrait" === t ? "landscape" : "portrait");
+ });
+ },
+};
+var WebClipMetadataFinderJS = new WebClipMetadataFinder();
+0;
diff --git a/27.0/js/reader/ReaderArticleFinder.js b/27.0/js/reader/ReaderArticleFinder.js
new file mode 100644
index 0000000..0f17747
--- /dev/null
+++ b/27.0/js/reader/ReaderArticleFinder.js
@@ -0,0 +1,5108 @@
+//# sourceURL=__InjectedScript_ReaderArticleFinder.js
+/* Copyright (c) 2026 Apple Inc. All rights reserved. */
+/*
+ * Copyright (c) 2010 Apple Inc. All rights reserved.
+ *
+ * Portions Copyright (c) 2009 Arc90 Inc
+ * Readability. An Arc90 Lab Experiment.
+ * Website: http://lab.arc90.com/experiments/readability
+ * Source: http://code.google.com/p/arc90labs-readability
+ * Readability is licensed under the Apache License, Version 2.0.
+ */
+function hostnameMatchesHostKnownToContainEmbeddableMedia(e) {
+ return /^(.+\.)?(youtube(-nocookie)?\.com|vimeo\.com|dailymotion\.com|soundcloud\.com|mixcloud\.com|embedly\.com|embed\.ly)\.?$/.test(
+ e,
+ );
+}
+function lazyLoadingImageURLForElement(e, t) {
+ function n(e) {
+ const t = /\.(jpe?g|png|gif|bmp)$/i;
+ if (t.test(e)) return !0;
+ let n = urlFromString(e);
+ return !!n && t.test(n.pathname);
+ }
+ function r(e) {
+ let t = attributesForElement(e);
+ for (let r of t) {
+ let t = r.name;
+ if (a.has(t.toLowerCase())) return e.getAttribute(t);
+ let i = n(r.value);
+ if (o.has(t.toLowerCase()) && i) return e.getAttribute(t);
+ if (s && /^data.*(src|source)$/i.test(t) && i) return e.getAttribute(t);
+ if (
+ e instanceof HTMLImageElement &&
+ /^data-/.test(t) &&
+ i &&
+ 1 === e.naturalWidth &&
+ 1 === e.naturalHeight
+ )
+ return e.getAttribute(t);
+ }
+ }
+ const i =
+ /(data:image\/)?gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==/,
+ a = new Set([
+ "data-lazy-src",
+ "data-original",
+ "datasrc",
+ "data-src",
+ "original-src",
+ "rel:bf_image_src",
+ "deferred-src",
+ "data-mediaviewer-src",
+ "data-hi-res-src",
+ "data-native-src",
+ ]),
+ o = new Set(["original"]);
+ let l = e.getAttribute("src"),
+ s = /transparent|empty/i.test(l) || i.test(l);
+ const c = 2;
+ for (let t = e, n = 0; t && n < c; t = t.parentElement, ++n) {
+ let e = r(t);
+ if (e) return e;
+ }
+ let u = e.closest("*[itemscope]");
+ if (
+ u &&
+ /^https?:\/\/schema\.org\/ImageObject\/?$/.test(u.getAttribute("itemtype"))
+ ) {
+ let e = u.getAttribute("itemid");
+ if (n(e) && !u.querySelector("img")) return e;
+ }
+ if (LazyLoadRegex.test(t) && "function" == typeof URL) {
+ var m;
+ try {
+ m = new URL(e.src);
+ } catch (e) {}
+ if (m && m.search) {
+ var d, h;
+ const t = ["w", "width"];
+ for (var g = t.length, f = 0; f < g; ++f) {
+ var p = t[f],
+ E = m.searchParams.get(p);
+ if (E && !isNaN(parseInt(E))) {
+ d = p;
+ break;
+ }
+ }
+ const n = ["h", "height"];
+ var v = n.length;
+ for (f = 0; f < v; ++f) {
+ var A = n[f],
+ N = m.searchParams.get(A);
+ if (N && !isNaN(parseInt(N))) {
+ h = A;
+ break;
+ }
+ }
+ if (d && h) {
+ var S = e.getAttribute("width"),
+ C = e.getAttribute("height");
+ if (!isNaN(parseInt(S)) && !isNaN(parseInt(C)))
+ return (m.searchParams.set(d, S), m.searchParams.set(h, C), m.href);
+ }
+ }
+ }
+ return null;
+}
+function sanitizeElementByRemovingAttributes(e) {
+ elementLooksLikeEmbeddedIframeTweetWithSrc(e) &&
+ (e.setAttribute("height", e.style.height),
+ e.setAttribute("width", e.style.width));
+ const t = /^on|^id$|^class$|^style$|^autofocus$/;
+ for (var n = attributesForElement(e), r = 0; r < n.length; ++r) {
+ var i = n[r].nodeName;
+ t.test(i) && (e.removeAttribute(i), r--);
+ }
+}
+function characterAppearsToBeCJK(e) {
+ if (!e || 0 === e.length) return !1;
+ var t = e.charCodeAt(0);
+ return (
+ (t > 11904 && t < 12031) ||
+ (t > 12352 && t < 12543) ||
+ (t > 12736 && t < 19903) ||
+ (t > 19968 && t < 40959) ||
+ (t > 44032 && t < 55215) ||
+ (t > 63744 && t < 64255) ||
+ (t > 65072 && t < 65103) ||
+ (t > 131072 && t < 173791) ||
+ (t > 194560 && t < 195103)
+ );
+}
+function domDistance(e, t, n) {
+ for (var r = [], i = e; i;) (r.unshift(i), (i = i.parentNode));
+ var a = [];
+ for (i = t; i;) (a.unshift(i), (i = i.parentNode));
+ for (
+ var o = Math.min(r.length, a.length),
+ l = Math.abs(r.length - a.length),
+ s = o;
+ s >= 0 && r[s] !== a[s];
+ --s
+ )
+ if (((l += 2), n && l >= n)) return n;
+ return l;
+}
+function fontSizeFromComputedStyle(e, t) {
+ var n = parseInt(e.fontSize);
+ return (isNaN(n) && (n = t || BaseFontSize), n);
+}
+function contentTextStyleForNode(e, t) {
+ function n(e) {
+ if (isNodeWhitespace(e)) return null;
+ var t = getComputedStyle(e.parentNode);
+ return "none" !== t.float ? null : t;
+ }
+ for (
+ var r =
+ "descendant::text()[not(parent::h1) and not(parent::h2) and not(parent::h3) and not(parent::h4) and not(parent::h5) and not(parent::h6)]",
+ i = e.evaluate(r, t, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null),
+ a = i.snapshotLength,
+ o = 0;
+ o < a;
+ ++o
+ ) {
+ for (
+ var l = i.snapshotItem(o), s = !1, c = l.parentElement;
+ c !== t;
+ c = c.parentElement
+ )
+ if (NegativeRegEx.test(c.className)) {
+ s = !0;
+ break;
+ }
+ if (!s) {
+ var u = n(l);
+ if (u) return u;
+ }
+ }
+ return null;
+}
+function isNodeWhitespace(e) {
+ return !(!e || e.nodeType !== Node.TEXT_NODE) && !/\S/.test(e.data);
+}
+function removeWhitespace(e) {
+ return e.replace(/\s+/g, "");
+}
+function isElementNode(e) {
+ return !(!e || e.nodeType !== Node.ELEMENT_NODE);
+}
+function computedStyleIndicatesElementIsInvisibleDueToClipping(e) {
+ if ("absolute" !== e.position) return !1;
+ var t = e.clip.match(
+ /^rect\((\d+px|auto), (\d+px|auto), (\d+px|auto), (\d+px|auto)\)$/,
+ );
+ if (!t || 5 !== t.length) return !1;
+ var n = t.map(function (e) {
+ return parseInt(e);
+ }),
+ r = n[1];
+ isNaN(r) && (r = 0);
+ var i = n[2],
+ a = n[3],
+ o = n[4];
+ return (isNaN(o) && (o = 0), r >= a || i >= o);
+}
+function isElementVisible(e) {
+ var t = getComputedStyle(e);
+ if ("visible" !== t.visibility || "none" === t.display) return !1;
+ if (cachedElementBoundingRect(e).height) return !0;
+ var n = document.createRange();
+ return (n.selectNode(e), !!n.getBoundingClientRect().height);
+}
+function isElementPositionedOffScreen(e) {
+ var t = cachedElementBoundingRect(e);
+ return !(!t.height || !t.width) && (t.bottom <= 0 || t.right <= 0);
+}
+function elementDepth(e) {
+ for (var t = 0; e; e = e.parentElement) t++;
+ return t;
+}
+function depthOfElementWithinElement(e, t) {
+ for (var n = 0; e !== t; e = e.parentElement) {
+ if (!e) return NaN;
+ n++;
+ }
+ return n;
+}
+function nearestAncestorElementWithTagName(e, t, n) {
+ var r = {};
+ if (n) for (var i = 0; i < n.length; ++i) r[n[i]] = !0;
+ if (r[normalizedElementTagName(e)]) return null;
+ for (; (e = e.parentElement);) {
+ var a = normalizedElementTagName(e);
+ if (r[a]) break;
+ if (a === t) return e;
+ }
+ return null;
+}
+function elementDescendsFromElementMatchingSelector(e, t) {
+ do {
+ if (e.matches(t)) return !0;
+ } while ((e = e.parentElement));
+ return !1;
+}
+function elementDescendsFromElementInSet(e, t) {
+ do {
+ if (t.has(e)) return !0;
+ } while ((e = e.parentElement));
+ return !1;
+}
+function elementIsHidingContentDueToContentVisibilityAuto(e) {
+ return (
+ !!window.ContentVisibilityAutoStateChangeEvent &&
+ "auto" === getComputedStyle(e).contentVisibility &&
+ !!e.children.length &&
+ !e.children[0].checkVisibility({ contentVisibilityAuto: !0 })
+ );
+}
+function cachedElementBoundingRect(e) {
+ if (e._cachedElementBoundingRect) return e._cachedElementBoundingRect;
+ if (
+ ReaderArticleFinderJS.shouldSuppressBoundingRectCalculationForSkippedElements() &&
+ elementIsHidingContentDueToContentVisibilityAuto(e)
+ ) {
+ let n = e.previousElementSibling;
+ return n && !elementIsHidingContentDueToContentVisibilityAuto(n)
+ ? (((t = cachedElementBoundingRect(n)).top += t.height),
+ (t.bottom += t.height),
+ t)
+ : { top: 0, right: 0, bottom: 0, left: 0, width: 0, height: 0 };
+ }
+ var t = e.getBoundingClientRect();
+ return (
+ ReaderArticleFinderJS._elementsWithCachedBoundingRects.push(e),
+ ReaderArticleFinderJS._cachedScrollX || ReaderArticleFinderJS._cachedScrollY
+ ? ((e._cachedElementBoundingRect = {
+ top: t.top + ReaderArticleFinderJS._cachedScrollY,
+ right: t.right + ReaderArticleFinderJS._cachedScrollX,
+ bottom: t.bottom + ReaderArticleFinderJS._cachedScrollY,
+ left: t.left + ReaderArticleFinderJS._cachedScrollX,
+ width: t.width,
+ height: t.height,
+ }),
+ e._cachedElementBoundingRect)
+ : ((e._cachedElementBoundingRect = t), e._cachedElementBoundingRect)
+ );
+}
+function clearCachedElementBoundingRects() {
+ for (
+ var e = ReaderArticleFinderJS._elementsWithCachedBoundingRects,
+ t = e.length,
+ n = 0;
+ n < t;
+ ++n
+ )
+ e[n]._cachedElementBoundingRect = null;
+ ReaderArticleFinderJS._elementsWithCachedBoundingRects = [];
+}
+function trimmedInnerTextIgnoringTextTransform(e) {
+ var t = e.innerText;
+ if (!/\S/.test(t)) return e.textContent.trim();
+ var n = getComputedStyle(e).textTransform;
+ return "uppercase" === n || "lowercase" === n
+ ? e.textContent.trim()
+ : t
+ ? t.trim()
+ : "";
+}
+function levenshteinDistance(e, t) {
+ for (
+ var n = e.length, r = t.length, i = new Array(n + 1), a = 0;
+ a < n + 1;
+ ++a
+ )
+ ((i[a] = new Array(r + 1)), (i[a][0] = a));
+ for (var o = 0; o < r + 1; ++o) i[0][o] = o;
+ for (o = 1; o < r + 1; ++o)
+ for (a = 1; a < n + 1; ++a)
+ if (e[a - 1] === t[o - 1]) i[a][o] = i[a - 1][o - 1];
+ else {
+ var l = i[a - 1][o] + 1,
+ s = i[a][o - 1] + 1,
+ c = i[a - 1][o - 1] + 1;
+ i[a][o] = Math.min(l, s, c);
+ }
+ return i[n][r];
+}
+function stringSimilarity(e, t) {
+ var n = Math.max(e.length, t.length);
+ return n ? (n - levenshteinDistance(e, t)) / n : 0;
+}
+function stringsAreNearlyIdentical(e, t) {
+ return (
+ e === t ||
+ stringSimilarity(e, t) > StringSimilarityToDeclareStringsNearlyIdentical
+ );
+}
+function elementIsCommentBlock(e) {
+ if (/(^|\s)comment/.test(e.className)) return !0;
+ var t = e.getAttribute("id");
+ return !(!t || (0 !== t.indexOf("comment") && 0 !== t.indexOf("Comment")));
+}
+function elementLooksLikeEmbeddedTweet(e) {
+ var t = null;
+ if ("iframe" === normalizedElementTagName(e)) {
+ if (!e.contentDocument)
+ return elementLooksLikeEmbeddedIframeTweetWithSrc(e);
+ t = e.contentDocument.documentElement;
+ } else "twitter-widget" === normalizedElementTagName(e) && (t = e.shadowRoot);
+ if (!t) return !1;
+ if (e.closest(".twitter-video") && t.querySelector("[data-tweet-id]"))
+ return !0;
+ let n = 0,
+ r = t.querySelector("blockquote");
+ r && TweetURLRegex.test(r.getAttribute("cite")) && ++n;
+ let i = t.querySelector("[data-iframe-title]");
+ return (
+ i && TweetIframeTitleRegex.test(i.getAttribute("data-iframe-title")) && ++n,
+ e.classList.contains("twitter-tweet") && ++n,
+ t.querySelector("[data-tweet-id]") && ++n,
+ n > 2
+ );
+}
+function elementLooksLikeEmbeddedIframeTweetWithSrc(e) {
+ if (!EmbeddedTwitterIframeSrcRegEx.test(e.getAttribute("src"))) return !1;
+ const t = e.getAttribute("title");
+ return "X Post" === t || "Twitter Tweet" === t;
+}
+function elementLooksLikeACarousel(e) {
+ const t = /carousel-|carousel_|-carousel|_carousel|swiper-/;
+ return t.test(e.className) || t.test(e.getAttribute("data-analytics"));
+}
+function elementLooksLikePartOfACarousel(e) {
+ const t = 3;
+ for (var n = e, r = 0; r < t; ++r) {
+ if (!n) return !1;
+ if (elementLooksLikeACarousel(n)) return !0;
+ n = n.parentElement;
+ }
+ return !1;
+}
+function urlIsHTTPFamilyProtocol(e) {
+ let t = e.protocol;
+ return "http:" === t || "https:" === t;
+}
+function shouldPruneIframe(e) {
+ if (e.srcdoc) return !0;
+ let t = urlFromString(e.src);
+ if (t) {
+ if (!urlIsHTTPFamilyProtocol(t)) return !0;
+ if (hostnameMatchesHostKnownToContainEmbeddableMedia(t.hostname)) return !1;
+ }
+ return !elementLooksLikeEmbeddedTweet(e.originalElement);
+}
+function textContentAppearsToBeCJK(e, t) {
+ if (!e || !e.length) return !1;
+ let n = e.length;
+ t && !isNaN(t) && (n = Math.min(n, t));
+ let r = 0;
+ for (let t = 0; t < n; t++) characterAppearsToBeCJK(e[t]) && r++;
+ return r >= n * MinimumRatioOfCharactersForLanguageMultiplier;
+}
+function languageScoreMultiplierForTextNodes(e) {
+ if (!e || !e.length) return 1;
+ for (
+ var t = Math.min(
+ e.length,
+ DefaultNumberOfTextNodesToCheckForLanguageMultiplier,
+ ),
+ n = 0,
+ r = 0,
+ i = 0;
+ i < t;
+ i++
+ ) {
+ for (
+ var a = e[i].nodeValue.trim(),
+ o = Math.min(
+ a.length,
+ NumberOfCharactersPerTextNodeToEvaluateForLanguageMultiplier,
+ ),
+ l = 0;
+ l < o;
+ l++
+ )
+ characterAppearsToBeCJK(a[l]) && n++;
+ r += o;
+ }
+ return n >= r * MinimumRatioOfCharactersForLanguageMultiplier
+ ? ScoreMultiplierForChineseJapaneseKorean
+ : 1;
+}
+function scoreMultiplierForElementTagNameAndAttributes(e) {
+ for (var t = 1, n = e; n; n = n.parentElement) {
+ var r = n.getAttribute("id");
+ r &&
+ (ArticleRegEx.test(r) && (t += ArticleMatchBonus),
+ CommentRegEx.test(r) && (t -= CommentMatchPenalty),
+ CarouselRegEx.test(r) && (t -= CarouselMatchPenalty));
+ var i = n.className;
+ (i &&
+ (ArticleRegEx.test(i) && (t += ArticleMatchBonus),
+ CommentRegEx.test(i) && (t -= CommentMatchPenalty),
+ CarouselRegEx.test(i) && (t -= CarouselMatchPenalty)),
+ "article" === normalizedElementTagName(n) && (t += ArticleMatchBonus));
+ }
+ return t < 0 ? 0 : t;
+}
+function elementAtPoint(e, t, n) {
+ if (
+ "undefined" != typeof ReaderArticleFinderJSController &&
+ ReaderArticleFinderJSController.nodeAtPoint
+ ) {
+ var r = ReaderArticleFinderJSController.nodeAtPoint(e, t);
+ return (r && r.nodeType !== Node.ELEMENT_NODE && (r = r.parentElement), r);
+ }
+ return n.elementFromPoint(e, t);
+}
+function userVisibleURLString(e) {
+ return "undefined" != typeof ReaderArticleFinderJSController &&
+ ReaderArticleFinderJSController.userVisibleURLString
+ ? ReaderArticleFinderJSController.userVisibleURLString(e)
+ : e;
+}
+function urlFromString(e, t) {
+ try {
+ return null != t ? new URL(e, t) : new URL(e);
+ } catch (e) {
+ return null;
+ }
+}
+function urlStringShouldHaveItsAnchorMadeNonFunctional(e, t) {
+ if (!e) return !0;
+ var n = urlFromString(e);
+ if ((n || (n = urlFromString(e, t)), !n || !n.href || !n.href.length))
+ return !0;
+ let r = n.href;
+ return (
+ "javascript:" === r.trim().substring(0, 11).toLowerCase() ||
+ "data:" === r.trim().substring(0, 5).toLowerCase()
+ );
+}
+function anchorLinksToAttachment(e) {
+ return /\battachment\b/i.test(e.getAttribute("rel"));
+}
+function anchorLinksToTagOrCategoryPage(e) {
+ return /\bcategory|tag\b/i.test(e.getAttribute("rel"));
+}
+function anchorLooksLikeDownloadFlashLink(e) {
+ return /^https?:\/\/(www\.|get\.)(adobe|macromedia)\.com\/(((products|[a-zA-Z]{1,2}|)\/flashplayer|flashplayer|go\/getflash(player)?)|(shockwave\/download\/(index|download)\.cgi\?P1_Prod_Version=ShockwaveFlash)\/?$)/i.test(
+ e.href,
+ );
+}
+function elementsHaveSameTagAndClassNames(e, t) {
+ return (
+ normalizedElementTagName(e) === normalizedElementTagName(t) &&
+ e.className === t.className
+ );
+}
+function selectorForElement(e) {
+ let t = normalizedElementTagName(e);
+ for (var n = e.classList, r = n.length, i = 0; i < r; i++) t += "." + n[i];
+ return t;
+}
+function elementFingerprintForDepth(e, t) {
+ function n(e, t) {
+ if (!e) return "";
+ var o = [];
+ o.push(selectorForElement(e));
+ var l = e.children,
+ s = l.length;
+ if (s && t > 0) {
+ o.push(r);
+ for (var c = 0; c < s; ++c)
+ (o.push(n(l[c], t - 1)), c !== s - 1 && o.push(a));
+ o.push(i);
+ }
+ return o.join("");
+ }
+ const r = " / ",
+ i = " \\",
+ a = " | ";
+ return n(e, t);
+}
+function childrenOfParentElement(e) {
+ var t = e.parentElement;
+ return t ? t.children : [];
+}
+function arrayOfKeysAndValuesOfObjectSortedByValueDescending(e) {
+ var t = [];
+ for (var n in e) e.hasOwnProperty(n) && t.push({ key: n, value: e[n] });
+ return (
+ t.sort(function (e, t) {
+ return t.value - e.value;
+ }),
+ t
+ );
+}
+function walkElementSubtree(e, t, n) {
+ if (!(t < 0)) {
+ for (var r = e.children, i = r.length, a = t - 1, o = 0; o < i; ++o)
+ walkElementSubtree(r[o], a, n);
+ n(e, t);
+ }
+}
+function elementIndicatesItIsASchemaDotOrgArticleContainer(e) {
+ var t = e.getAttribute("itemtype");
+ return /^https?:\/\/schema\.org\/((News)?Article|APIReference)$/.test(t);
+}
+function elementIndicatesItIsASchemaDotOrgImageObject(e) {
+ var t = e.getAttribute("itemtype");
+ return (
+ "https://schema.org/ImageObject" === t ||
+ "http://schema.org/ImageObject" === t
+ );
+}
+function elementWouldAppearBetterAsFigureOrAuxiliary(e, t) {
+ const n = /caption/i;
+ if (!e) return !1;
+ if (t.closest("figure, .auxiliary")) return !1;
+ if (
+ elementIndicatesItIsASchemaDotOrgImageObject(e) &&
+ !t.querySelector("figure, .auxiliary")
+ )
+ return !0;
+ var r = t.ownerDocument.createTreeWalker(
+ t,
+ NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_TEXT,
+ {
+ acceptNode: function () {
+ return NodeFilter.FILTER_ACCEPT;
+ },
+ },
+ );
+ r.currentNode = t;
+ for (var i = !1, a = !1; r.nextNode();) {
+ var o = r.currentNode;
+ if (o.nodeType === Node.TEXT_NODE) {
+ if (!i && /\S/.test(o.nodeValue)) return !1;
+ continue;
+ }
+ if (o.nodeType !== Node.ELEMENT_NODE) return !1;
+ let e = normalizedElementTagName(o);
+ if ("figure" === e || "table" === e) return !1;
+ if (o.classList.contains("auxiliary")) return !1;
+ if ("img" === e) {
+ if (i) return !1;
+ i = !0;
+ }
+ var l = o.originalElement;
+ a ||
+ (l && !hasClassMatchingRegexp(o.originalElement, n)) ||
+ !/\S/.test(o.innerText) ||
+ (a = !0);
+ }
+ return i && a;
+}
+function cleanStyleAndClassList(e) {
+ (e.classList.length || e.removeAttribute("class"),
+ e.getAttribute("style") || e.removeAttribute("style"));
+}
+function getVisibleNonWhitespaceTextNodes(e, t, n, r, i) {
+ function a(e) {
+ var t = e.children[0];
+ if (t)
+ for (var n = t.children, r = n.length, i = 0; i < r; ++i)
+ if ("none" !== getComputedStyle(n[i]).float) return !1;
+ return !0;
+ }
+ function o(e, r) {
+ if (e.nodeType === Node.TEXT_NODE)
+ return void (/\S/.test(e.nodeValue) && s.push(e));
+ if (e.nodeType !== Node.ELEMENT_NODE) return;
+ if (!isElementVisible(e)) return;
+ if (n && ++l > n) return;
+ if (i && i.has(e)) return;
+ let u = normalizedElementTagName(e);
+ if ("iframe" !== u && "form" !== u) {
+ if (c.has(u)) r--;
+ else if (("ul" !== u && "ol" !== u) || !a(e)) {
+ var m = e.parentElement;
+ if (m)
+ "section" !== normalizedElementTagName(m) ||
+ e.previousElementSibling ||
+ e.nextElementSibling ||
+ r--;
+ } else r--;
+ var d = r + 1;
+ if (d < t)
+ for (var h = e.childNodes, g = h.length, f = 0; f < g; ++f) o(h[f], d);
+ }
+ }
+ var l = 0,
+ s = [];
+ let c = new Set(["p", "strong", "b", "em", "i", "span", "section"]);
+ return (r && (c.add("center"), c.add("font")), o(e, 0), s);
+}
+function mapOfVisibleTextNodeComputedStyleReductionToNumberOfMatchingCharacters(
+ e,
+ t,
+) {
+ for (
+ var n = {},
+ r = getVisibleNonWhitespaceTextNodes(e, 100),
+ i = r.length,
+ a = 0;
+ a < i;
+ ++a
+ ) {
+ var o = r[a],
+ l = o.length,
+ s = o.parentElement,
+ c = t(getComputedStyle(s));
+ n[c] ? (n[c] += l) : (n[c] = l);
+ }
+ return n;
+}
+function keyOfMaximumValueInDictionary(e) {
+ var t, n;
+ for (var r in e) {
+ var i = e[r];
+ (!n || i > n) && ((t = r), (n = i));
+ }
+ return t;
+}
+function elementIsProtected(e) {
+ return e.classList.contains("protected") || e.querySelector(".protected");
+}
+function dominantFontFamilyAndSizeForElement(e) {
+ return keyOfMaximumValueInDictionary(
+ mapOfVisibleTextNodeComputedStyleReductionToNumberOfMatchingCharacters(
+ e,
+ function (e) {
+ return e.fontFamily + "|" + e.fontSize;
+ },
+ ),
+ );
+}
+function dominantFontSizeInPointsFromFontFamilyAndSizeString(e) {
+ return e ? parseInt(e.split("|")[1]) : null;
+}
+function canvasElementHasNoUserVisibleContent(e) {
+ if (!e.width || !e.height) return !0;
+ for (
+ var t = e.getContext("2d").getImageData(0, 0, e.width, e.height).data,
+ n = 0,
+ r = t.length;
+ n < r;
+ n += 4
+ ) {
+ if (t[n + 3]) return !1;
+ }
+ return !0;
+}
+function findArticleNodeSelectorsInQuirksListForHostname(e, t) {
+ const n = [
+ [AppleDotComAndSubdomainsRegex, "*[itemprop='articleBody']"],
+ [/^(.+\.)?buzzfeed\.com\.?$/, "article #buzz_sub_buzz"],
+ [/^(.+\.)?mashable\.com\.?$/, ".parsec-body .parsec-container"],
+ [/^(.+\.)?cnet\.com\.?$/, "#rbContent.container"],
+ [/^(.+\.)?engadget\.com\.?$/, "main article #page_body"],
+ [/^(.*\.)?wikipedia\.org\.?$/, "#content #bodyContent"],
+ [/^(.*\.)?theintercept\.com\.?$/, ".PostContent"],
+ [/^(.*\.)?tools\.ietf\.org\.?$/, "div.content"],
+ [/^(.*\.)?cntraveler\.com\.?$/, "article.gallery"],
+ [/^(.+\.)?meteoinfo\.ru\.?$/, "#jm-content-bottom"],
+ [/^(.*\.)?tmd\.go\.th\.?$/, "#sidebar"],
+ ];
+ for (var r = n.length, i = 0; i < r; ++i) {
+ var a = n[i];
+ if (a[0].test(e.toLowerCase())) if (t(a[1])) return;
+ }
+}
+function functionToPreventPruningDueToInvisibilityInQuirksListForHostname(e) {
+ const t = [
+ [
+ /^mobile\.nytimes\.com\.?$/,
+ function (e, t) {
+ var n = e;
+ if (!t) return !1;
+ for (; n && n !== t;) {
+ if (n.classList.contains("hidden")) return !0;
+ n = n.parentElement;
+ }
+ return !1;
+ },
+ ],
+ ];
+ for (var n = t.length, r = 0; r < n; ++r) {
+ var i = t[r];
+ if (i[0].test(e.toLowerCase())) return i[1];
+ }
+ return null;
+}
+function elementIsAHeader(e) {
+ return !!{ h1: 1, h2: 1, h3: 1, h4: 1, h5: 1, h6: 1 }[
+ normalizedElementTagName(e)
+ ];
+}
+function leafElementForElementAndDirection(e, t) {
+ var n = e.ownerDocument,
+ r = n.createTreeWalker(n.body, NodeFilter.SHOW_ELEMENT, {
+ acceptNode: function (e) {
+ return 0 === e.children.length
+ ? NodeFilter.FILTER_ACCEPT
+ : NodeFilter.FILTER_SKIP;
+ },
+ });
+ return ((r.currentNode = e), r[t]());
+}
+function previousLeafElementForElement(e) {
+ return leafElementForElementAndDirection(e, "previousNode");
+}
+function nextLeafElementForElement(e) {
+ return leafElementForElementAndDirection(e, "nextNode");
+}
+function nextNonFloatingVisibleElementSibling(e) {
+ for (var t = e; (t = t.nextElementSibling);)
+ if (isElementVisible(t) && "none" === getComputedStyle(t).float) return t;
+ return null;
+}
+function elementWithLargestAreaFromElements(e) {
+ var t,
+ n = e.length;
+ if (!n) return null;
+ for (var r = 0, i = 0; i < n; ++i) {
+ var a = e[i],
+ o = cachedElementBoundingRect(a),
+ l = o.width * o.height;
+ l > r && ((t = a), (r = l));
+ }
+ return t;
+}
+function unwrappedArticleContentElement(e) {
+ for (var t = e; ;) {
+ for (var n = t.childNodes, r = n.length, i = null, a = 0; a < r; ++a) {
+ var o = n[a],
+ l = o.nodeType;
+ if (
+ l === Node.ELEMENT_NODE ||
+ (l === Node.TEXT_NODE && !isNodeWhitespace(o))
+ ) {
+ if (i) return t;
+ var s = normalizedElementTagName(o);
+ if ("div" !== s && "article" !== s && "section" !== s) return t;
+ i = o;
+ }
+ }
+ if (!i) break;
+ t = i;
+ }
+ return t;
+}
+function elementsMatchingClassesInClassList(e, t) {
+ return elementsOfSameClassIgnoringClassNamesMatchingRegexp(e, t);
+}
+function elementsMatchingClassesInClassListIgnoringCommonLayoutClassNames(
+ e,
+ t,
+) {
+ return elementsOfSameClassIgnoringClassNamesMatchingRegexp(e, t, /clearfix/i);
+}
+function elementsMatchingClassesInClassListIgnoringClassesWithNumericSuffix(
+ e,
+ t,
+) {
+ return elementsOfSameClassIgnoringClassNamesMatchingRegexp(e, t, /\d+$/);
+}
+function elementsOfSameClassIgnoringClassNamesMatchingRegexp(e, t, n) {
+ for (var r = "", i = e.length, a = 0; a < i; ++a) {
+ var o = e[a];
+ (n && n.test(o)) || (r += "." + o);
+ }
+ try {
+ return t.querySelectorAll(r);
+ } catch (e) {
+ return [];
+ }
+}
+function imageIsContainedByContainerWithImageAsBackgroundImage(e) {
+ var t = e.parentElement;
+ if (!t || !t.style || !t.style.backgroundImage) return !1;
+ var n = /url\((.*)\)/.exec(t.style.backgroundImage);
+ return !(!n || 2 !== n.length) && n[1] === e.src;
+}
+function pseudoElementContent(e, t) {
+ var n = getComputedStyle(e, t).content,
+ r = /^\"(.*)\"$/.exec(n);
+ return r && 2 == r.length ? r[1] : null;
+}
+function hasClassMatchingRegexp(e, t) {
+ for (var n = e.classList, r = n.length, i = 0; i < r; ++i)
+ if (t.test(n[i])) return !0;
+ return !1;
+}
+function elementLooksLikeDropCap(e) {
+ return hasClassMatchingRegexp(e, DropCapRegex) && 1 === e.innerText.length;
+}
+function changeElementType(e, t) {
+ for (
+ var n = e.ownerDocument.createElement(t),
+ r = attributesForElement(e),
+ i = r.length,
+ a = 0;
+ a < i;
+ ++a
+ ) {
+ var o = r.item(a);
+ n.setAttribute(o.nodeName, o.nodeValue);
+ }
+ for (; e.firstChild;) n.appendChild(e.firstChild);
+ return (e.replaceWith(n), n);
+}
+function pathComponentsForAnchor(e) {
+ var t = e.pathname.substring(1).split("/");
+ return (t[t.length - 1] || t.pop(), t);
+}
+function lastPathComponentFromAnchor(e) {
+ var t = pathComponentsForAnchor(e);
+ return t.length ? t[t.length - 1] : null;
+}
+function clamp(e, t, n) {
+ return Math.min(Math.max(e, t), n);
+}
+function childrenWithParallelStructure(e) {
+ var t = e.children;
+ if (!t) return [];
+ var n = t.length;
+ if (!n) return [];
+ for (var r = {}, i = 0; i < n; ++i) {
+ var a = t[i];
+ if (
+ !SetOfCandidateTagNamesToIgnore.has(normalizedElementTagName(a)) &&
+ a.className
+ )
+ for (var o = a.classList, l = o.length, s = 0; s < l; ++s) {
+ (m = r[(u = o[s])]) ? m.push(a) : (r[u] = [a]);
+ }
+ }
+ var c = Math.floor(n / 2);
+ for (var u in r) {
+ var m;
+ if ((m = r[u]).length > c) return m;
+ }
+ return [];
+}
+function elementAppearsToBeCollapsed(e) {
+ return (
+ !(
+ !ReaderArticleFinderJS.isMediaWikiPage() || !/collaps/.test(e.className)
+ ) ||
+ ("false" === e.getAttribute("aria-expanded") && !isElementVisible(e))
+ );
+}
+const ReaderMinimumScore = 1600,
+ ReaderMinimumAdvantage = 15,
+ ArticleMinimumScoreDensity = 4.25,
+ CandidateMinimumWidthPortionForIndicatorElements = 0.5,
+ CandidateMinumumListItemLineCount = 4,
+ SetOfCandidateTagNamesToIgnore = new Set([
+ "a",
+ "embed",
+ "form",
+ "html",
+ "iframe",
+ "object",
+ "ol",
+ "option",
+ "script",
+ "style",
+ "svg",
+ "ul",
+ ]),
+ PrependedArticleCandidateMinimumHeight = 50,
+ AppendedArticleCandidateMinimumHeight = 200,
+ AppendedArticleCandidateMaximumVerticalDistanceFromArticle = 150,
+ StylisticClassNames = { justfy: 1, justify: 1, left: 1, right: 1, small: 1 },
+ CommentRegEx = /[Cc]omment|meta|footer|footnote|talkback/,
+ CommentMatchPenalty = 0.75,
+ ArticleRegEx =
+ /(?:(?:^|\s)(?:(post|hentry|entry)[-_]{0,2}(?:content|text|body)?|article[-_]{0,2}(?:content|text|body|page|copy)?)(?:\s|$))/i,
+ ArticleMatchBonus = 0.5,
+ CarouselRegEx = /carousel/i,
+ CarouselMatchPenalty = 0.75,
+ SectionRegex = /section|content.*component/i,
+ DropCapRegex = /first.*letter|drop.*cap/i,
+ ProgressiveLoadingRegex = /progressive/i,
+ DensityExcludedElementSelector = "#disqus_thread, #comments, .userComments",
+ PositiveRegEx =
+ /article|body|content|entry|hentry|page|pagination|post|related-asset|text/i,
+ NegativeRegEx =
+ /advertisement|breadcrumb|combx|comment|contact|disqus|footer|link|meta|mod-conversations|promo|related|scroll|share|shoutbox|sidebar|social|sponsor|spotim|subscribe|talkback|tags|toolbox|widget|[-_]ad$|zoom-(in|out)/i,
+ VeryPositiveClassNameRegEx = /instapaper_body/,
+ VeryNegativeClassNameRegEx = /instapaper_ignore/,
+ SharingRegex =
+ /email|print|rss|digg|slashdot|delicious|reddit|share|twitter|facebook|pinterest|whatsapp/i,
+ VeryLiberalCommentRegex = /comment/i,
+ AdvertisementHostRegex = /^adserver\.|doubleclick.net$/i,
+ SidebarRegex = /sidebar/i,
+ MinimumAverageDistanceBetweenHRElements = 400,
+ MinimumAverageDistanceBetweenHeaderElements = 400,
+ PortionOfCandidateHeightToIgnoreForHeaderCheck = 0.1,
+ DefaultNumberOfTextNodesToCheckForLanguageMultiplier = 3,
+ NumberOfCharactersPerTextNodeToEvaluateForLanguageMultiplier = 12,
+ MinimumRatioOfCharactersForLanguageMultiplier = 0.5,
+ ScoreMultiplierForChineseJapaneseKorean = 3,
+ MinimumContentMediaHeight = 150,
+ MinimumContentMediaWidthToArticleWidthRatio = 0.25,
+ MaximumContentMediaAreaToArticleAreaRatio = 0.2,
+ LinkContinueMatchRegEx = /continue/gi,
+ LinkNextMatchRegEx = /next/gi,
+ LinkPageMatchRegEx = /page/gi,
+ LinkListItemBonus = 5,
+ LinkPageMatchBonus = 10,
+ LinkNextMatchBonus = 15,
+ LinkContinueMatchBonus = 15,
+ LinkNextOrdinalValueBase = 3,
+ LinkMismatchValueBase = 2,
+ LinkMatchWeight = 200,
+ LinkMaxVerticalDistanceFromArticle = 200,
+ LinkVerticalDistanceFromArticleWeight = 150,
+ LinkCandidateXPathQuery =
+ "descendant-or-self::*[(not(@id) or (@id!='disqus_thread' and @id!='comments')) and (not(@class) or @class!='userComments')]/a",
+ LinkDateRegex =
+ /\D(?:\d\d(?:\d\d)?[\-\/](?:10|11|12|0?[1-9])[\-\/](?:30|31|[12][0-9]|0?[1-9])|\d\d(?:\d\d)?\/(?:10|11|12|0[1-9])|(?:10|11|12|0?[1-9])\-(?:30|31|[12][0-9]|0?[1-9])\-\d\d(?:\d\d)?|(?:30|31|[12][0-9]|0?[1-9])\-(?:10|11|12|0?[1-9])\-\d\d(?:\d\d)?)\D/,
+ LinkURLSearchParameterKeyMatchRegex = /(page|^p$|^pg$)/i,
+ LinkURLPageSlashNumberMatchRegex = /\/.*page.*\/\d+/i,
+ LinkURLSlashDigitEndMatchRegex = /\/\d+\/?$/,
+ LinkURLArchiveSlashDigitEndMatchRegex = /archives?\/\d+\/?$/,
+ LinkURLBadSearchParameterKeyMatchRegex =
+ /author|comment|feed|id|nonce|related/i,
+ LinkURLSemanticMatchBonus = 100,
+ LinkMinimumURLSimilarityRatio = 0.75,
+ SubheadRegex = /sub(head|title)|description|dec?k|abstract/i,
+ HeaderMinimumDistanceFromArticleTop = 200,
+ HeaderLevenshteinDistanceToLengthRatio = 0.75,
+ MinimumRatioOfListItemsBeingRelatedToSharingToPruneEntireList = 0.5,
+ FloatMinimumHeight = 130,
+ ImageSizeTiny = 32,
+ ToleranceForLeadingMediaWidthToArticleWidthForFullWidthPresentation = 80,
+ MaximumFloatWidth = 325,
+ AnchorImageMinimumWidth = 100,
+ AnchorImageMinimumHeight = 100,
+ MinimumHeightForImagesAboveTheArticleTitle = 50,
+ MainImageMinimumWidthAndHeight = 83,
+ BaseFontSize = 16,
+ BaseLineHeightRatio = 1.125,
+ MaximumExactIntegralValue = 9007199254740992,
+ TitleCandidateDepthScoreMultiplier = 0.1,
+ TextNodeLengthPower = 1.25,
+ LazyLoadRegex = /lazy/i,
+ HeaderElementsSelector = "h1, h2, h3, h4, h5, h6",
+ readerArticleFinderMessageHandler =
+ window.webkit?.messageHandlers?.SafariReaderArticleFinder,
+ isUIProcessDrivenReader =
+ !globalThis.ReaderArticleFinderJS && !!readerArticleFinderMessageHandler,
+ StringSimilarityToDeclareStringsNearlyIdentical = 0.97,
+ FindArticleMode = { Element: !1, ExistenceOfElement: !0 },
+ AppleDotComAndSubdomainsRegex = /.*\.apple\.com\.?$/,
+ SchemaDotOrgArticleContainerSelector =
+ "*[itemtype='https://schema.org/Article'], *[itemtype='https://schema.org/NewsArticle'], *[itemtype='https://schema.org/APIReference'], *[itemtype='http://schema.org/Article'], *[itemtype='http://schema.org/NewsArticle'], *[itemtype='http://schema.org/APIReference']",
+ CleaningType = { MainArticleContent: 0, MetadataContent: 1, LeadingMedia: 2 },
+ MaximumWidthOrHeightOfImageInMetadataSection = 20;
+var attributesForElement = (function () {
+ var e = Element.prototype.__lookupGetter__("attributes");
+ return function (t) {
+ return e.call(t);
+ };
+})();
+const TweetURLRegex =
+ /^https?:\/\/(.+\.)?twitter\.com\/.*\/status\/(.*\/)*[0-9]+\/?$/i,
+ TweetIframeTitleRegex = /tweet/i,
+ EmbeddedTwitterIframeSrcRegEx =
+ /^https?:\/\/platform\.twitter\.com\/embed\/Tweet\.html/i;
+((CandidateElement = function (e, t) {
+ ((this.element = e),
+ (this.contentDocument = t),
+ (this.textNodes = this.usableTextNodesInElement(this.element)),
+ (this.rawScore = this.calculateRawScore()),
+ (this.tagNameAndAttributesScoreMultiplier =
+ this.calculateElementTagNameAndAttributesScoreMultiplier()),
+ (this.languageScoreMultiplier = 0),
+ (this.depthInDocument = 0));
+}),
+ (CandidateElement.extraArticleCandidateIfElementIsViable = function (
+ e,
+ t,
+ n,
+ r,
+ ) {
+ const i = "a, b, strong, i, em, u, span";
+ var a = cachedElementBoundingRect(e),
+ o = cachedElementBoundingRect(t.element);
+ if (
+ ((r && a.height < PrependedArticleCandidateMinimumHeight) ||
+ (!r && a.height < AppendedArticleCandidateMinimumHeight)) &&
+ e.childElementCount &&
+ e.querySelectorAll("*").length !== e.querySelectorAll(i).length
+ )
+ return null;
+ if (r) {
+ if (a.bottom > o.top) return null;
+ } else if (a.top < o.bottom) return null;
+ if (!r) {
+ var l = a.top - o.bottom;
+ if (l > AppendedArticleCandidateMaximumVerticalDistanceFromArticle)
+ return null;
+ }
+ if (a.left > o.right || a.right < o.left) return null;
+ if (elementLooksLikePartOfACarousel(e)) return null;
+ var s = new CandidateElement(e, n);
+ return ((s.isPrepended = r), s);
+ }),
+ (CandidateElement.candidateIfElementIsViable = function (e, t, n) {
+ var r = cachedElementBoundingRect(e),
+ i = ReaderArticleFinderJS.candidateElementFilter;
+ return r.width < i.minimumWidth ||
+ r.height < i.minimumHeight ||
+ r.width * r.height < i.minimumArea ||
+ (!n && r.top > i.maximumTop) ||
+ CandidateElement.candidateElementAdjustedHeight(e) < i.minimumHeight
+ ? null
+ : new CandidateElement(e, t);
+ }),
+ (CandidateElement.candidateElementAdjustedHeight = function (e) {
+ for (
+ var t = cachedElementBoundingRect(e),
+ n = t.height,
+ r = e.getElementsByTagName("form"),
+ i = r.length,
+ a = 0;
+ a < i;
+ ++a
+ ) {
+ var o = cachedElementBoundingRect(r[a]);
+ o.width > t.width * CandidateMinimumWidthPortionForIndicatorElements &&
+ (n -= o.height);
+ }
+ var l = e.querySelectorAll("ol, ul"),
+ s = l.length,
+ c = null;
+ for (a = 0; a < s; ++a) {
+ var u = l[a];
+ if (!(
+ c && c.compareDocumentPosition(u) & Node.DOCUMENT_POSITION_CONTAINED_BY
+ )) {
+ var m = u.getElementsByTagName("li"),
+ d = m.length,
+ h = cachedElementBoundingRect(u);
+ if (d) {
+ var g = h.height / d,
+ f = getComputedStyle(m[0]),
+ p = parseInt(f.lineHeight);
+ if (isNaN(p)) p = fontSizeFromComputedStyle(f) * BaseLineHeightRatio;
+ h.width >
+ t.width * CandidateMinimumWidthPortionForIndicatorElements &&
+ g / p < CandidateMinumumListItemLineCount &&
+ ((n -= h.height), (c = u));
+ } else n -= h.height;
+ }
+ }
+ return n;
+ }),
+ (CandidateElement.prototype = {
+ calculateRawScore: function () {
+ for (var e = 0, t = this.textNodes, n = t.length, r = 0; r < n; ++r)
+ e += this.rawScoreForTextNode(t[r]);
+ return e;
+ },
+ calculateElementTagNameAndAttributesScoreMultiplier: function () {
+ return scoreMultiplierForElementTagNameAndAttributes(this.element);
+ },
+ calculateLanguageScoreMultiplier: function () {
+ 0 === this.languageScoreMultiplier &&
+ (this.languageScoreMultiplier = languageScoreMultiplierForTextNodes(
+ this.textNodes,
+ ));
+ },
+ depth: function () {
+ return (
+ this.depthInDocument ||
+ (this.depthInDocument = elementDepth(this.element)),
+ this.depthInDocument
+ );
+ },
+ finalScore: function () {
+ return (
+ this.calculateLanguageScoreMultiplier(),
+ this.basicScore() * this.languageScoreMultiplier
+ );
+ },
+ basicScore: function () {
+ return this.rawScore * this.tagNameAndAttributesScoreMultiplier;
+ },
+ scoreDensity: function () {
+ var e = 0,
+ t = this.element.querySelector(DensityExcludedElementSelector);
+ t && (e = t.clientWidth * t.clientHeight);
+ for (
+ var n = this.element.children || [], r = n.length, i = 0;
+ i < r;
+ ++i
+ ) {
+ var a = n[i];
+ elementIsCommentBlock(a) && (e += a.clientWidth * a.clientHeight);
+ }
+ var o =
+ cachedElementBoundingRect(this.element).width *
+ cachedElementBoundingRect(this.element).height,
+ l = o * MaximumContentMediaAreaToArticleAreaRatio,
+ s =
+ cachedElementBoundingRect(this.element).width *
+ MinimumContentMediaWidthToArticleWidthRatio,
+ c = this.element.querySelectorAll("img, video"),
+ u = c.length;
+ for (i = 0; i < u; ++i) {
+ var m = cachedElementBoundingRect(c[i]);
+ if (m.width >= s && m.height > MinimumContentMediaHeight) {
+ var d = m.width * m.height;
+ d < l && (e += d);
+ }
+ }
+ var h = this.basicScore(),
+ g = o - e,
+ f = this.textNodes.length,
+ p = 0,
+ E = 0;
+ for (i = 0; i < f; ++i) {
+ var v = this.textNodes[i].parentNode;
+ v && ((E += fontSizeFromComputedStyle(getComputedStyle(v))), p++);
+ }
+ var A = BaseFontSize;
+ return (
+ p && (A = E /= p),
+ this.calculateLanguageScoreMultiplier(),
+ (h / g) * 1e3 * (A / BaseFontSize) * this.languageScoreMultiplier
+ );
+ },
+ usableTextNodesInElement: function (e) {
+ var t = [];
+ if (!e) return t;
+ const n = new Set([
+ "a",
+ "dd",
+ "dt",
+ "noscript",
+ "ol",
+ "option",
+ "pre",
+ "script",
+ "style",
+ "td",
+ "ul",
+ "iframe",
+ ]);
+ var r = this.contentDocument,
+ i = function (e) {
+ const i =
+ "text()|*/text()|*/a/text()|*/li/text()|*/li/p/text()|*/span/text()|*/em/text()|*/i/text()|*/strong/text()|*/b/text()|*/font/text()|blockquote/*/text()|div[count(./p)=count(./*)]/p/text()|div[count(*)=1]/div/p/text()|div[count(*)=1]/div/p/*/text()|div/div/text()";
+ for (
+ var a = r.evaluate(
+ i,
+ e,
+ null,
+ XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
+ null,
+ ),
+ o = a.snapshotLength,
+ l = 0;
+ l < o;
+ ++l
+ ) {
+ var s = a.snapshotItem(l);
+ n.has(normalizedElementTagName(s.parentNode)) ||
+ s._countedTextNode ||
+ isNodeWhitespace(s) ||
+ ((s._countedTextNode = !0), t.push(s));
+ }
+ };
+ i(e);
+ for (
+ var a = childrenWithParallelStructure(e), o = a.length, l = 0;
+ l < o;
+ ++l
+ ) {
+ i(a[l]);
+ }
+ var s = t.length;
+ for (l = 0; l < s; ++l) delete t[l]._countedTextNode;
+ return t;
+ },
+ addTextNodesFromCandidateElement: function (e) {
+ for (var t = this.textNodes.length, n = 0; n < t; ++n)
+ this.textNodes[n].alreadyCounted = !0;
+ var r = e.textNodes,
+ i = r.length;
+ for (n = 0; n < i; ++n) r[n].alreadyCounted || this.textNodes.push(r[n]);
+ for (t = this.textNodes.length, n = 0; n < t; ++n)
+ this.textNodes[n].alreadyCounted = null;
+ this.rawScore = this.calculateRawScore();
+ },
+ rawScoreForTextNode: function (e) {
+ const t = 20;
+ if (!e) return 0;
+ var n = e.length;
+ if (n < t) return 0;
+ var r = e.parentNode;
+ if (!isElementVisible(r)) return 0;
+ for (var i = 1; r && r !== this.element;)
+ ((i -= 0.1), (r = r.parentNode));
+ return Math.pow(n * i, TextNodeLengthPower);
+ },
+ shouldDisqualifyDueToScoreDensity: function () {
+ return this.scoreDensity() < ArticleMinimumScoreDensity;
+ },
+ shouldDisqualifyDueToHorizontalRuleDensity: function () {
+ for (
+ var e = this.element.getElementsByTagName("hr"),
+ t = e.length,
+ n = 0,
+ r = cachedElementBoundingRect(this.element),
+ i = 0.7 * r.width,
+ a = 0;
+ a < t;
+ ++a
+ )
+ e[a].clientWidth > i && n++;
+ if (n && r.height / n < MinimumAverageDistanceBetweenHRElements)
+ return !0;
+ return !1;
+ },
+ shouldDisqualifyDueToHeaderDensity: function () {
+ var e = "(h1|h2|h3|h4|h5|h6|*/h1|*/h2|*/h3|*/h4|*/h5|*/h6)[a[@href]]",
+ t = this.contentDocument.evaluate(
+ e,
+ this.element,
+ null,
+ XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
+ null,
+ ),
+ n = t.snapshotLength;
+ if (n > 2) {
+ for (
+ var r = 0,
+ i = cachedElementBoundingRect(this.element),
+ a = i.height * PortionOfCandidateHeightToIgnoreForHeaderCheck,
+ o = 0;
+ o < n;
+ ++o
+ ) {
+ var l = t.snapshotItem(o);
+ if (
+ "#" !==
+ l.querySelector("a[href]").getAttribute("href").substring(0, 1)
+ ) {
+ var s = cachedElementBoundingRect(l);
+ s.top - i.top > a && i.bottom - s.bottom > a && r++;
+ }
+ }
+ if (i.height / r < MinimumAverageDistanceBetweenHeaderElements)
+ return !0;
+ }
+ return !1;
+ },
+ shouldDisqualifyDueToSimilarElements: function (e) {
+ function t(e, t) {
+ if (!e || !t) return !1;
+ var n = 1;
+ return e.className
+ ? e.className === t.className
+ : elementFingerprintForDepth(e, n) ===
+ elementFingerprintForDepth(t, n);
+ }
+ var n = function (e) {
+ const t = /related-posts/i;
+ for (
+ var n = e.parentElement;
+ n && n !== this.contentDocument.body;
+ n = n.parentElement
+ )
+ if (t.test(n.className)) return !0;
+ return !1;
+ }.bind(this),
+ r = this.element;
+ if ("article" === normalizedElementTagName(r.parentElement)) return !1;
+ let i = normalizedElementTagName(r);
+ if ("li" === i || "dd" === i)
+ for (var a = r.parentNode, o = a.children.length, l = 0; l < o; ++l) {
+ var s = a.children[l];
+ if (
+ normalizedElementTagName(s) === i &&
+ s.className === r.className &&
+ s !== r
+ )
+ return !0;
+ }
+ var c = r.classList;
+ if (
+ (c.length ||
+ ((r = r.parentElement) &&
+ ((c = r.classList).length ||
+ ((r = r.parentElement) && (c = r.classList)))),
+ c.length)
+ ) {
+ e || (e = []);
+ var u = e.length;
+ for (l = 0; l < u; ++l) e[l].element.candidateElement = e[l];
+ var m =
+ elementsMatchingClassesInClassListIgnoringCommonLayoutClassNames(
+ c,
+ this.contentDocument,
+ ),
+ d = !1,
+ h = elementDepth(r),
+ g = n(r),
+ f = m.length;
+ for (l = 0; l < f; ++l) {
+ if (
+ (s = m[l]) !== r &&
+ s.parentElement !== r &&
+ r.parentElement !== s &&
+ isElementVisible(s)
+ ) {
+ var p = s.candidateElement;
+ if (
+ (p || (p = new CandidateElement(s, this.contentDocument))) &&
+ p.basicScore() * ReaderMinimumAdvantage > this.basicScore()
+ ) {
+ if (s.closest("section") && r.closest("section")) return !1;
+ if (
+ SectionRegex.test(s.className) &&
+ SectionRegex.test(r.className)
+ )
+ return !1;
+ if (n(s) && !g) return !1;
+ if (
+ !d &&
+ cachedElementBoundingRect(s).bottom <
+ cachedElementBoundingRect(this.element).top
+ ) {
+ d = !0;
+ continue;
+ }
+ if (
+ t(r.previousElementSibling, s.previousElementSibling) ||
+ t(r.nextElementSibling, s.nextElementSibling)
+ ) {
+ var E = r.querySelector(HeaderElementsSelector),
+ v = s.querySelector(HeaderElementsSelector);
+ if (E && v && elementsHaveSameTagAndClassNames(E, v)) return !0;
+ if (
+ ((E = r.previousElementSibling),
+ (v = s.previousElementSibling),
+ E &&
+ v &&
+ elementIsAHeader(E) &&
+ elementIsAHeader(v) &&
+ elementsHaveSameTagAndClassNames(E, v))
+ )
+ return !0;
+ }
+ if (elementDepth(s) === h)
+ for (
+ ;
+ s.parentElement &&
+ r.parentElement &&
+ s.parentElement !== r.parentElement;
+ )
+ ((s = s.parentElement), (r = r.parentElement));
+ for (; r.childElementCount <= 1;) {
+ if (!r.childElementCount || !s.childElementCount) return !1;
+ if (s.childElementCount > 1) return !1;
+ if (
+ normalizedElementTagName(r.firstElementChild) !==
+ normalizedElementTagName(s.firstElementChild)
+ )
+ return !1;
+ ((r = r.firstElementChild), (s = s.firstElementChild));
+ }
+ if (s.childElementCount <= 1) return !1;
+ v = s.firstElementChild;
+ var A = s.lastElementChild,
+ N = ((E = r.firstElementChild), r.lastElementChild);
+ if (normalizedElementTagName(v) !== normalizedElementTagName(E))
+ return !1;
+ if (normalizedElementTagName(A) !== normalizedElementTagName(N))
+ return !1;
+ var S = v.className,
+ C = A.className,
+ b = E.className,
+ y = A.className,
+ T = y === b ? 2 : 1;
+ if (S.length || b.length) {
+ if (!S.length || !b.length) return !1;
+ if (
+ S === b &&
+ elementsMatchingClassesInClassList(E.classList, r).length <= T
+ )
+ return !0;
+ }
+ if (C.length || y.length) {
+ if (!C.length || !y.length) return !1;
+ if (
+ C === y &&
+ elementsMatchingClassesInClassList(A.classList, r).length <= T
+ )
+ return !0;
+ }
+ var R = E.clientHeight,
+ x = N.clientHeight;
+ return (
+ !(!R || !v.clientHeight) &&
+ !(!x || !A.clientHeight) &&
+ (R === v.clientHeight || x === A.clientHeight)
+ );
+ }
+ }
+ }
+ for (l = 0; l < u; ++l) e[l].element.candidateElement = null;
+ }
+ return !1;
+ },
+ shouldDisqualifyForDeepLinking: function () {
+ const e = 5;
+ for (
+ var t = this.element,
+ n = this.contentDocument.location,
+ r = pathComponentsForAnchor(n).length,
+ i = [],
+ a = t.getElementsByTagName("a"),
+ o = a.length,
+ l = 0;
+ l < o;
+ l++
+ ) {
+ var s = a[l];
+ if (
+ n.host === s.host &&
+ !(
+ pathComponentsForAnchor(s).length <= r ||
+ 0 !== (s.host + s.pathname).indexOf(n.host + n.pathname) ||
+ anchorLinksToAttachment(s) ||
+ (i.push(s), i.length < e)
+ )
+ ) {
+ var c = t.offsetTop + t.offsetHeight / e;
+ return i[0].offsetTop < c;
+ }
+ }
+ return !1;
+ },
+ }),
+ (String.prototype.lastInteger = function () {
+ const e = /[0-9]+/g;
+ var t = this.match(e);
+ return t ? parseInt(t[t.length - 1]) : NaN;
+ }));
+function handleNavigationEvent(e) {
+ globalReaderArticleFinder && globalReaderArticleFinder.handleNavigation(e);
+}
+function clearArticleFinder() {
+ return (
+ !globalReaderArticleFinder.didPrepareToTransitionToReader &&
+ (navigation.removeEventListener("navigate", handleNavigationEvent),
+ (globalReaderArticleFinder = null),
+ !0)
+ );
+}
+var globalReaderArticleFinder;
+((ReaderArticleFinder = function (e) {
+ ((this.contentDocument = e),
+ (this.didSearchForArticleNode = !1),
+ (this.didChangeContentDocumentToFrameOnPage = !1),
+ (this.article = null),
+ (this.didSearchForExtraArticleNode = !1),
+ (this.extraArticle = null),
+ (this._leadingMediaElement = null),
+ (this._isMediaWikiPage = void 0),
+ (this._cachedScrollY = 0),
+ (this._cachedScrollX = 0),
+ (this._elementsWithCachedBoundingRects = []),
+ (this._cachedContentTextStyle = null),
+ (this.pageNumber = 1),
+ (this.prefixWithDateForNextPageURL = null),
+ (this.previouslyDiscoveredPageURLStrings = []),
+ (this.candidateElementFilter = {
+ minimumWidth: 280,
+ minimumHeight: 295,
+ minimumArea: 17e4,
+ maxTop: 1300,
+ }));
+ let t = 0;
+ ((this._nextUniqueID = function () {
+ return t++ + "";
+ }),
+ (this._mapOfUniqueIDToOriginalElement = new Map()),
+ (this._weakMapOfOriginalElementToUniqueID = new WeakMap()));
+}),
+ (ReaderArticleFinder.prototype = {
+ setConfigurationForTesting: function (e) {
+ this.configurationForTesting = e;
+ },
+ setCandidateElementFilter: function (e) {
+ let [t, n] = this._validityAndValidCandidateElementFilterFromFilter(e);
+ t && (this.candidateElementFilter = n);
+ },
+ _validityAndValidCandidateElementFilterFromFilter: function (e) {
+ let t = {},
+ n = !1;
+ for (let i of [
+ "minimumWidth",
+ "minimumHeight",
+ "minimumArea",
+ "maxTop",
+ ]) {
+ let r = (e || {})[i];
+ if (void 0 === r || "number" != typeof r || r < 0) {
+ ((t = {}), (n = !1));
+ break;
+ }
+ ((t[i] = r), (n = !0));
+ }
+ return [n, t];
+ },
+ pointsForDominantIframeHitTest: function () {
+ const e = 60;
+ return [
+ [e, e],
+ [window.innerWidth - e, e],
+ [e, window.innerHeight - e],
+ [window.innerWidth - e, window.innerHeight - e],
+ ];
+ },
+ dominantContentIframe: function () {
+ let e,
+ t = this.pointsForDominantIframeHitTest(),
+ n = t.length;
+ for (let i = 0; i < n; i++) {
+ if (
+ ((cornerElement = document.elementFromPoint(t[i][0], t[i][1])),
+ !cornerElement || "IFRAME" !== cornerElement.tagName)
+ )
+ return null;
+ if (e) {
+ if (e !== cornerElement) return null;
+ } else e = cornerElement;
+ }
+ return e;
+ },
+ checkForIframeCoveringMostOfWebpage: function () {
+ if (isUIProcessDrivenReader) return null;
+ let e = this.dominantContentIframe();
+ e &&
+ !this.didChangeContentDocumentToFrameOnPage &&
+ ((this.contentDocument = e.contentDocument),
+ this.resetArticleInformation(),
+ (this.didChangeContentDocumentToFrameOnPage = !0));
+ },
+ isReaderModeAvailable: function () {
+ return (
+ this.setSuppressBoundingRectCalculationForSkippedElements(!0),
+ this.checkForIframeCoveringMostOfWebpage(),
+ !!this.findArticleBySearchingQuirksList() ||
+ (this.cacheWindowScrollPosition(),
+ !!this.findArticleFromMetadata(FindArticleMode.ExistenceOfElement) ||
+ ((this.article = this.findArticleByVisualExamination()),
+ this.article && this.articleIsLTR(),
+ !!this.article))
+ );
+ },
+ hasDominantContentIframe: function () {
+ return document !== this.contentDocument;
+ },
+ previewReaderImageURL: function () {
+ const e = this.adoptableArticle(!0);
+ if (!e) return null;
+ const t = e.querySelectorAll("img");
+ if (!t.length) return null;
+ const n = window.innerWidth / 2,
+ i = window.innerHeight / 2,
+ r = this.contentDocument
+ .elementsFromPoint(n, i)
+ .find((e) => "IMG" === e.tagName),
+ a = t[0].currentSrc;
+ if (!r) return a;
+ const l = [...t].find((e) => e.currentSrc === r.currentSrc);
+ return l ? l.currentSrc : a;
+ },
+ resetArticleInformation: function () {
+ ((this.didSearchForArticleNode = !1),
+ (this.didSearchForExtraArticleNode = !1),
+ delete this.article,
+ delete this.extraArticle,
+ delete this._articleTitleInformation,
+ delete this._articleTitleElement,
+ delete this._leadingMediaElement,
+ delete this._cachedContentTextStyle,
+ delete this._adoptableArticle,
+ delete this._articleIsLTR,
+ delete this._nextPageURL,
+ delete this._cachedScrollY,
+ delete this._cachedScrollX,
+ clearCachedElementBoundingRects());
+ },
+ reset: function () {
+ const e = this.articleNode();
+ (this.resetArticleInformation(), this.prepareToTransitionToReader());
+ const t = this.articleNode();
+ return e === t || t.contains(e);
+ },
+ prepareToTransitionToReader: function () {
+ ((this.didPrepareToTransitionToReader = !0),
+ this.adoptableArticle(!0),
+ this.nextPageURL(),
+ this.articleIsLTR());
+ },
+ nextPageURL: function () {
+ if (!this._nextPageURL) {
+ var e = this.nextPageURLString();
+ ("undefined" != typeof ReaderArticleFinderJSController &&
+ e &&
+ (e = ReaderArticleFinderJSController.substituteURLForNextPageURL(e)),
+ (this._nextPageURL = e));
+ }
+ return this._nextPageURL;
+ },
+ containerElementsForMultiPageContent: function () {
+ const e = /(.*page[^0-9]*|.*article.*item[^0-9]*)(\d{1,2})(.*)/i,
+ t = 3;
+ for (
+ var n, i = [], r = this.articleNode(), a = 0;
+ !(n = e.exec(r.getAttribute("id")));
+ )
+ if (!(r = r.parentElement) || a++ === t) return [];
+ for (
+ var l = childrenOfParentElement(r), o = l.length, s = 0;
+ s < o;
+ ++s
+ ) {
+ var c = l[s];
+ if (c !== r) {
+ var m = e.exec(c.getAttribute("id"));
+ m &&
+ m[1] === n[1] &&
+ m[3] === n[3] &&
+ ((isElementVisible(c) && !isElementPositionedOffScreen(c)) ||
+ i.push(c));
+ }
+ }
+ return i;
+ },
+ adoptableMultiPageContentElements: function () {
+ return this.containerElementsForMultiPageContent().map(function (e) {
+ return this.cleanArticleNode(
+ e,
+ e.cloneNode(!0),
+ CleaningType.MainArticleContent,
+ !1,
+ );
+ }, this);
+ },
+ classNameIsSignificantInRouteComputation: function (e) {
+ return !!e && !(e.toLowerCase() in StylisticClassNames);
+ },
+ shouldIgnoreInRouteComputation: function (e) {
+ let t = normalizedElementTagName(e);
+ return (
+ "script" === t ||
+ "link" === t ||
+ "style" === t ||
+ ("tr" === t && !e.offsetHeight)
+ );
+ },
+ routeToArticleNode: function () {
+ for (var e = [], t = this.articleNode(); t;) {
+ var n = {};
+ n.tagName = normalizedElementTagName(t);
+ var i = t.getAttribute("id");
+ (i && (n.id = i),
+ this.classNameIsSignificantInRouteComputation(t.className) &&
+ (n.className = t.className),
+ (n.index = 1));
+ for (var r = t.previousElementSibling; r; r = r.previousElementSibling)
+ this.shouldIgnoreInRouteComputation(r) || n.index++;
+ (e.unshift(n), (t = t.parentElement));
+ }
+ return e;
+ },
+ adjustArticleNodeUpwardIfNecessary: function () {
+ if (!this.article) return;
+ var e = this.article.element;
+ if (!e.parentElement) return;
+ for (var t = e; t; t = t.parentElement)
+ if (VeryPositiveClassNameRegEx.test(t.className))
+ return void (this.article.element = t);
+ if (
+ "header" === normalizedElementTagName(e) &&
+ "article" === normalizedElementTagName(e.parentElement)
+ )
+ return void (this.article.element = e.parentElement);
+ var n = e.previousElementSibling;
+ if (
+ n &&
+ "figure" === normalizedElementTagName(n) &&
+ "article" === normalizedElementTagName(e.parentElement)
+ )
+ return void (this.article.element = e.parentElement);
+ var i =
+ "section" === normalizedElementTagName(e)
+ ? e
+ : nearestAncestorElementWithTagName(e, "section", ["article"]);
+ if (i) {
+ var r = i.parentElement,
+ a = (function () {
+ for (var e = r.children, t = e.length, n = 0; n < t; ++n) {
+ var a = e[n],
+ l = normalizedElementTagName(a);
+ if (a !== i && ("section" === l || "header" === l)) return !0;
+ }
+ return !1;
+ })();
+ if (
+ a &&
+ (/\barticleBody\b/.test(r.getAttribute("itemprop")) ||
+ "main" === normalizedElementTagName(r) ||
+ "main" === r.getAttribute("role") ||
+ "article" === normalizedElementTagName(r) ||
+ r === this.contentDocument.body ||
+ r.classList.contains("entry-content"))
+ )
+ return void (this.article.element = r);
+ }
+ const l = /intro/i,
+ o = /body|content/i;
+ if (
+ ((e = this.article.element),
+ (l.test(e.className) &&
+ e.nextElementSibling &&
+ o.test(e.nextElementSibling.className)) ||
+ (o.test(e.className) &&
+ e.previousElementSibling &&
+ l.test(e.previousElementSibling.className)))
+ )
+ return void (this.article.element = e.parentElement);
+ if ("article" !== normalizedElementTagName(e)) {
+ var s = e.parentElement.closest("*[itemprop='articleBody']");
+ if (s && s.parentElement.closest(SchemaDotOrgArticleContainerSelector))
+ return void (this.article.element = s);
+ }
+ var c = e.closest("article");
+ if (c) {
+ e = unwrappedArticleContentElement(e);
+ var m,
+ d = elementDepth(e);
+ ("p" !== normalizedElementTagName(e) ||
+ e.className ||
+ ((e = e.parentElement), d--),
+ e.classList.length
+ ? 1 ===
+ (m =
+ elementsMatchingClassesInClassListIgnoringCommonLayoutClassNames(
+ e.classList,
+ this.contentDocument,
+ )).length &&
+ (m =
+ elementsMatchingClassesInClassListIgnoringClassesWithNumericSuffix(
+ e.classList,
+ this.contentDocument,
+ ))
+ : (m = e.parentElement.children));
+ for (var h = m.length, u = 0; u < h; ++u) {
+ var g = m[u];
+ if (
+ e !== g &&
+ d === elementDepth(g) &&
+ isElementVisible(g) &&
+ !g.querySelector("article") &&
+ Object.keys(e.dataset).join() === Object.keys(g.dataset).join() &&
+ dominantFontFamilyAndSizeForElement(e) ===
+ dominantFontFamilyAndSizeForElement(g)
+ )
+ return void (this.article.element = c);
+ }
+ }
+ let f = this.findExtraArticle(),
+ p = f ? f.element : null;
+ if (
+ p &&
+ p.parentElement &&
+ e.parentElement === p.parentElement &&
+ ArticleRegEx.test(e.parentElement.className)
+ ) {
+ if (
+ dominantFontFamilyAndSizeForElement(e) ===
+ dominantFontFamilyAndSizeForElement(p)
+ )
+ return void (this.article.element = e.parentElement);
+ }
+ let E = e.parentElement;
+ if (
+ elementIsCommentBlock(e) &&
+ !elementIsCommentBlock(E) &&
+ ArticleRegEx.test(E.className)
+ ) {
+ let e = CandidateElement.candidateIfElementIsViable(
+ E,
+ this.contentDocument,
+ !0,
+ );
+ if (e && e.finalScore() >= ReaderMinimumScore)
+ return void (this.article.element = E);
+ }
+ if (!(e = this.article.element).getAttribute("id") && e.className) {
+ var v = normalizedElementTagName(e),
+ T = e.className,
+ A = e.parentElement;
+ if (A)
+ for (var S = A.children, N = ((u = 0), S.length); u < N; ++u) {
+ var b = S[u];
+ if (
+ b !== e &&
+ normalizedElementTagName(b) === v &&
+ b.className === T
+ ) {
+ var y = CandidateElement.candidateIfElementIsViable(
+ b,
+ this.contentDocument,
+ !0,
+ );
+ if (y && !(y.finalScore() < ReaderMinimumScore))
+ return void (this.article.element = A);
+ }
+ }
+ }
+ },
+ findArticleBySearchingQuirksList: function () {
+ var e,
+ t = this.contentDocument;
+ return (
+ findArticleNodeSelectorsInQuirksListForHostname(
+ t.location.hostname,
+ function (n) {
+ var i = t.querySelectorAll(n);
+ if (1 === i.length)
+ return ((e = new CandidateElement(i[0], t)), !0);
+ },
+ ),
+ e
+ );
+ },
+ articleNode: function (e) {
+ return (
+ this.checkForIframeCoveringMostOfWebpage(),
+ this.didSearchForArticleNode ||
+ ((this.article = this.findArticleBySearchingQuirksList()),
+ this.article ||
+ (this.article = this.findArticleBySearchingAllElements()),
+ this.article ||
+ (this.article = this.findArticleByVisualExamination()),
+ this.article || (this.article = this.findArticleFromMetadata()),
+ !this.article &&
+ e &&
+ (this.article = this.findArticleBySearchingAllElements(!0)),
+ (this.didSearchForArticleNode = !0),
+ this.adjustArticleNodeUpwardIfNecessary(),
+ this.article &&
+ (this.article.element = unwrappedArticleContentElement(
+ this.article.element,
+ )),
+ this.article && this.articleIsLTR()),
+ this.article ? this.article.element : null
+ );
+ },
+ extraArticleNode: function () {
+ return (
+ this.didSearchForArticleNode || this.articleNode(),
+ this.didSearchForExtraArticleNode ||
+ ((this.extraArticle = this.findExtraArticle()),
+ (this.didSearchForExtraArticleNode = !0)),
+ this.extraArticle ? this.extraArticle.element : null
+ );
+ },
+ cacheWindowScrollPosition: function () {
+ ((this._cachedScrollY = window.scrollY),
+ (this._cachedScrollX = window.scrollX));
+ },
+ contentTextStyle: function () {
+ return (
+ this._cachedContentTextStyle ||
+ ((this._cachedContentTextStyle = contentTextStyleForNode(
+ this.contentDocument,
+ this.articleNode(),
+ )),
+ this._cachedContentTextStyle ||
+ (this._cachedContentTextStyle = getComputedStyle(
+ this.articleNode(),
+ ))),
+ this._cachedContentTextStyle
+ );
+ },
+ commaCountIsLessThan: function (e, t) {
+ for (
+ var n = 0, i = e.textContent, r = -1;
+ n < t && (r = i.indexOf(",", r + 1)) >= 0;
+ )
+ n++;
+ return n < t;
+ },
+ calculateLinkDensityForPruningElement: function (e, t) {
+ var n = removeWhitespace(e.textContent).length;
+ if (!n) return 0;
+ for (
+ var i = this.article.element,
+ r = (function () {
+ for (var t = e.originalElement; t && t !== i; t = t.parentElement)
+ if ("none" !== getComputedStyle(t).float) return t;
+ return null;
+ })(),
+ a = e.getElementsByTagName("a"),
+ l = 0,
+ o = a.length,
+ s = 0;
+ s < o;
+ ++s
+ ) {
+ var c = a[s];
+ (!r &&
+ c.href &&
+ t &&
+ t === dominantFontFamilyAndSizeForElement(c.originalElement)) ||
+ (l += removeWhitespace(c.textContent).length);
+ }
+ return l / n;
+ },
+ shouldPruneElement: function (e, t, n) {
+ const i = 0.33,
+ r = 0.5,
+ a = 0.2,
+ l = 25,
+ o = 4e4;
+ let s = normalizedElementTagName(e);
+ if (!e.parentElement) return !1;
+ if (t.classList.contains("footnotes")) return !1;
+ if (e.querySelector(".tweet-wrapper")) return !1;
+ if (
+ "figure" === normalizedElementTagName(e.parentElement) &&
+ e.querySelector("img")
+ )
+ return !1;
+ if ("iframe" === s) return shouldPruneIframe(e);
+ if ("canvas" !== s) {
+ for (var c = !1, m = e.childNodes.length, d = 0; d < m; ++d) {
+ var h = e.childNodes[d],
+ u = h.nodeType;
+ if (
+ u === Node.ELEMENT_NODE ||
+ (u === Node.TEXT_NODE && !isNodeWhitespace(h))
+ ) {
+ c = !0;
+ break;
+ }
+ }
+ if (!c) {
+ if ("p" === s) {
+ var g = e.previousSibling,
+ f = e.nextSibling;
+ if (
+ g &&
+ g.nodeType === Node.TEXT_NODE &&
+ !isNodeWhitespace(g) &&
+ f &&
+ f.nodeType === Node.TEXT_NODE &&
+ !isNodeWhitespace(f)
+ )
+ return !1;
+ }
+ return !0;
+ }
+ if ("p" === s) return !1;
+ }
+ if ("canvas" === s)
+ return (
+ (window.innerWidth === t.width && window.innerHeight === t.height) ||
+ !(
+ !ProgressiveLoadingRegex.test(t.className) ||
+ "img" !== normalizedElementTagName(t.nextElementSibling)
+ ) ||
+ !!canvasElementHasNoUserVisibleContent(t) ||
+ "cufon" === normalizedElementTagName(e.parentNode)
+ );
+ if (e.closest("figure") && e.querySelector("picture")) return !1;
+ var p = 0;
+ if (t) {
+ if (VeryNegativeClassNameRegEx.test(t.className)) return !0;
+ var E = t.className,
+ v = t.getAttribute("id");
+ (PositiveRegEx.test(E) && p++,
+ PositiveRegEx.test(v) && p++,
+ NegativeRegEx.test(E) && p--,
+ NegativeRegEx.test(v) && p--);
+ }
+ let T = this.isMediaWikiPage();
+ if (p < 0 && !T) return !0;
+ if (elementIsProtected(e)) return !1;
+ if ("ul" === s || "ol" === s) {
+ if (t.querySelector("iframe") && t.querySelector("script")) return !0;
+ var A = t.children,
+ S = A.length;
+ if (!S && !/\S/.test(e.innerText)) return !0;
+ var N = 0,
+ b = 0;
+ for (d = 0; d < S; ++d) {
+ var y = A[d];
+ if (SharingRegex.test(y.className)) N++;
+ else {
+ var x = y.children;
+ 1 === x.length && SharingRegex.test(x[0].className) && N++;
+ }
+ NegativeRegEx.test(A[d].className) && b++;
+ }
+ return (
+ N / S >=
+ MinimumRatioOfListItemsBeingRelatedToSharingToPruneEntireList ||
+ b / S >= MinimumRatioOfListItemsBeingRelatedToSharingToPruneEntireList
+ );
+ }
+ if (1 === e.childElementCount) {
+ var D = e.firstElementChild;
+ if ("a" === normalizedElementTagName(D)) return !1;
+ if (
+ "span" === normalizedElementTagName(D) &&
+ "converted-anchor" === D.className &&
+ nearestAncestorElementWithTagName(D, "table")
+ )
+ return !1;
+ }
+ var I = e.getElementsByTagName("img"),
+ C = I.length;
+ if (C) {
+ var R = 0;
+ for (d = 0; d < C; ++d) {
+ var L = I[d].originalElement;
+ if (isElementVisible(L)) {
+ var M = cachedElementBoundingRect(L);
+ R += (M.width / C) * (M.height / C);
+ }
+ }
+ if (R > o) return !1;
+ }
+ if (!this.commaCountIsLessThan(e, 10)) return !1;
+ var F = e.getElementsByTagName("p").length,
+ _ = e.getElementsByTagName("br").length,
+ w = F + Math.floor(_ / 2);
+ if (C > w && "table" !== s) return !0;
+ if (
+ !e.closest("table") &&
+ !e._originalElementDepthInCollapsedArea &&
+ !T
+ ) {
+ if (
+ e.getElementsByTagName("li").length > w &&
+ dominantFontFamilyAndSizeForElement(t.querySelector("li")) !== n
+ )
+ return !0;
+ if (e.textContent.length < l && 1 !== C) return !0;
+ let i = this.calculateLinkDensityForPruningElement(e, n);
+ if (p >= 1 && i > r) return !0;
+ if (p < 1 && i > a) return !0;
+ }
+ if (e.getElementsByTagName("input").length / w > i) return !0;
+ if ("table" === s) {
+ if (
+ removeWhitespace(e.innerText).length <=
+ 0.5 * removeWhitespace(t.innerText).length
+ )
+ return !0;
+ if (T && t.classList.contains("toc")) return !0;
+ }
+ return !1;
+ },
+ wordCountIsLessThan: function (e, t) {
+ for (
+ var n = 0, i = e.textContent, r = -1;
+ (r = i.indexOf(" ", r + 1)) >= 0 && n < t;
+ )
+ n++;
+ return n < t;
+ },
+ leadingMediaIsAppropriateWidth: function (e) {
+ return (
+ !(!this.article || !e) &&
+ e.getBoundingClientRect().width >=
+ this.article.element.getBoundingClientRect().width -
+ ToleranceForLeadingMediaWidthToArticleWidthForFullWidthPresentation
+ );
+ },
+ newDivFromNode: function (e) {
+ var t = this.contentDocument.createElement("div");
+ return (e && (t.innerHTML = e.innerHTML), t);
+ },
+ headerElement: function () {
+ if (!this.article) return null;
+ var e = this.article.element.previousElementSibling;
+ if (e && "header" === normalizedElementTagName(e)) return e;
+ var t = this._articleTitleElement;
+ if (!t) return null;
+ var n = t.parentElement;
+ if (
+ n &&
+ "header" === normalizedElementTagName(n) &&
+ !this.article.element.contains(n)
+ )
+ for (
+ var i = n.querySelectorAll("img"), r = i.length, a = 0;
+ a < r;
+ ++a
+ ) {
+ var l = i[a],
+ o = cachedElementBoundingRect(l);
+ if (
+ o.width >= MainImageMinimumWidthAndHeight &&
+ o.height >= MainImageMinimumWidthAndHeight
+ )
+ return n;
+ }
+ return null;
+ },
+ adoptableLeadingMedia: function () {
+ if (!this.article || !this._leadingMediaElement) return null;
+ var e = this._leadingMediaElement.closest("figure");
+ if (e)
+ return this.cleanArticleNode(
+ e,
+ e.cloneNode(!0),
+ CleaningType.LeadingMedia,
+ !0,
+ );
+ if (!this.leadingMediaIsAppropriateWidth(this._leadingMediaElement))
+ return null;
+ if ("img" !== normalizedElementTagName(this._leadingMediaElement))
+ return this.cleanArticleNode(
+ this._leadingMediaElement,
+ this._leadingMediaElement.cloneNode(!0),
+ CleaningType.LeadingMedia,
+ !0,
+ );
+ const t = 5,
+ n = /credit/,
+ i = /caption/,
+ r = /src|alt/;
+ var a = this._leadingMediaElement.parentNode,
+ l = null,
+ o = null,
+ s = a.children.length;
+ if ("div" === normalizedElementTagName(a) && s > 1 && s < t)
+ for (
+ var c = a.cloneNode(!0).querySelectorAll("p, div"),
+ m = c.length,
+ d = 0;
+ d < m;
+ ++d
+ ) {
+ var h = c[d];
+ n.test(h.className)
+ ? (l = h.cloneNode(!0))
+ : i.test(h.className) && (o = h.cloneNode(!0));
+ }
+ var u = this._leadingMediaElement.cloneNode(!1),
+ g = lazyLoadingImageURLForElement(u, u.className);
+ (g && u.setAttribute("src", g),
+ (!g && u.hasAttribute("src")) ||
+ !u.hasAttribute("data-srcset") ||
+ u.setAttribute("srcset", u.getAttribute("data-srcset")));
+ var f = attributesForElement(u);
+ for (d = 0; d < f.length; ++d) {
+ var p = f[d].nodeName;
+ r.test(p) || (u.removeAttribute(p), d--);
+ }
+ var E = this.contentDocument.createElement("div");
+ if (((E.className = "leading-image"), E.appendChild(u), l)) {
+ var v = this.newDivFromNode(l);
+ ((v.className = "credit"), E.appendChild(v));
+ }
+ if (o) {
+ var T = this.newDivFromNode(o);
+ ((T.className = "caption"), E.appendChild(T));
+ }
+ return E;
+ },
+ articleBoundingRect: function () {
+ return (
+ this._articleBoundingRect ||
+ (this._articleBoundingRect = cachedElementBoundingRect(
+ this.article.element,
+ )),
+ this._articleBoundingRect
+ );
+ },
+ updatePageInformation: function (e) {
+ ((this.pageNumber = e.pageNumber),
+ (this.suggestedRouteToArticle = e.suggestedRouteToArticle),
+ (this.previouslyDiscoveredPageURLStrings =
+ e.previouslyDiscoveredPageURLStrings));
+ },
+ hasArticle: function () {
+ return !!this.article;
+ },
+ serializableArticle: function () {
+ const e = this.adoptableArticle(!0);
+ if (!e) return null;
+ let t;
+ const n = this.adoptableMetadataBlock();
+ return (
+ n && (t = webkit.createNodeSnapshot(n, { deep: !0 })),
+ {
+ articleIsLTR: this.articleIsLTR(),
+ articleNode: webkit.createNodeSnapshot(e, { deep: !0 }),
+ articleTitle: this.articleTitle(),
+ articleTitleInformation: this.articleTitleInformation(),
+ articleSubhead: this.articleSubhead(),
+ baseURI: this.contentDocument.baseURI,
+ documentURLString: this.documentURLString(),
+ heightOfArticleNode: this.heightOfArticleNode(),
+ metadataBlock: t,
+ multiPageContentElements:
+ this.adoptableMultiPageContentElements().map(() =>
+ webkit.createNodeSnapshot(multiPageContentElements, { deep: !0 }),
+ ),
+ nextPageURL: this.nextPageURL(),
+ routeToArticleNode: this.routeToArticleNode(),
+ }
+ );
+ },
+ updatePageInformation: function (e) {
+ ((this.pageNumber = e.pageNumber),
+ (this.suggestedRouteToArticle = e.suggestedRouteToArticle),
+ (this.previouslyDiscoveredPageURLStrings =
+ e.previouslyDiscoveredPageURLStrings));
+ },
+ heightOfArticleNode: function () {
+ return this.articleNode()?.getBoundingClientRect()?.height;
+ },
+ adoptableArticle: function (e) {
+ if (this._adoptableArticle) return this._adoptableArticle.cloneNode(!0);
+ (this.setSuppressBoundingRectCalculationForSkippedElements(!1),
+ clearCachedElementBoundingRects(),
+ this.cacheWindowScrollPosition());
+ var t = this.articleNode(e);
+ if (
+ ((this._adoptableArticle = t ? t.cloneNode(!0) : null),
+ !this._adoptableArticle)
+ )
+ return this._adoptableArticle;
+ if (
+ ((this._adoptableArticle = this.cleanArticleNode(
+ t,
+ this._adoptableArticle,
+ CleaningType.MainArticleContent,
+ !1,
+ )),
+ "p" === normalizedElementTagName(this._adoptableArticle))
+ ) {
+ var n = document.createElement("div");
+ (n.appendChild(this._adoptableArticle), (this._adoptableArticle = n));
+ }
+ var i = this.extraArticleNode();
+ if (i) {
+ var r = this.cleanArticleNode(
+ i,
+ i.cloneNode(!0),
+ CleaningType.MainArticleContent,
+ !0,
+ );
+ r
+ ? this.extraArticle.isPrepended
+ ? this._adoptableArticle.insertBefore(
+ r,
+ this._adoptableArticle.firstChild,
+ )
+ : this._adoptableArticle.appendChild(r)
+ : (i = null);
+ var a = cachedElementBoundingRect(this.article.element),
+ l = cachedElementBoundingRect(this.extraArticle.element),
+ o = {
+ top: Math.min(a.top, l.top),
+ right: Math.max(a.right, l.right),
+ bottom: Math.max(a.bottom, l.bottom),
+ left: Math.min(a.left, l.left),
+ };
+ ((o.width = o.right - o.left),
+ (o.height = o.bottom - o.top),
+ (this._articleBoundingRect = o));
+ }
+ this._articleTextContent = this._adoptableArticle.innerText;
+ var s = this.headerElement();
+ if (
+ this._leadingMediaElement &&
+ (!s || !s.contains(this._leadingMediaElement))
+ ) {
+ var c = this.adoptableLeadingMedia();
+ c &&
+ this._adoptableArticle.insertBefore(
+ c,
+ this._adoptableArticle.firstChild,
+ );
+ }
+ var m = !!s;
+ if (m && i && (i === s && (m = !1), m)) {
+ var d = i.compareDocumentPosition(s);
+ (d & Node.DOCUMENT_POSITION_CONTAINS ||
+ d & Node.DOCUMENT_POSITION_CONTAINED_BY) &&
+ (m = !1);
+ }
+ if (m) {
+ var h = this.cleanArticleNode(
+ s,
+ s.cloneNode(!0),
+ CleaningType.MainArticleContent,
+ !0,
+ );
+ h &&
+ this._adoptableArticle.insertBefore(
+ h,
+ this._adoptableArticle.firstChild,
+ );
+ }
+ return this._adoptableArticle;
+ },
+ dominantContentSelectorAndDepth: function (e) {
+ var t,
+ n = {},
+ i = {};
+ walkElementSubtree(e, 2, function (e, t) {
+ if (isElementVisible(e)) {
+ var r = selectorForElement(e) + " | " + t;
+ i[r] ? (i[r] += 1) : ((i[r] = 1), (n[r] = e));
+ }
+ });
+ var r = arrayOfKeysAndValuesOfObjectSortedByValueDescending(i);
+ switch (r.length) {
+ case 0:
+ break;
+ case 1:
+ t = r[0].key;
+ break;
+ default:
+ var a = r[0];
+ a.value > r[1].value && (t = a.key);
+ }
+ if (!t) return null;
+ var l = n[t];
+ return {
+ selector: selectorForElement(l),
+ depth: depthOfElementWithinElement(l, e),
+ };
+ },
+ functionToPreventPruningElementDueToInvisibility: function () {
+ return (
+ functionToPreventPruningDueToInvisibilityInQuirksListForHostname(
+ this.contentDocument.location.hostname,
+ ) ||
+ function () {
+ return !1;
+ }
+ );
+ },
+ cleanArticleNode: function (e, t, n, i) {
+ function r(e) {
+ ((v += e),
+ T && (T += e),
+ A && (A += e),
+ S && (S += e),
+ N && (N += e),
+ b && (b += e));
+ }
+ function a() {
+ (1 === T && (T = 0),
+ 1 === A && (A = 0),
+ 1 === S && (S = 0),
+ 1 === N && (N = 0),
+ 1 === b && (b = 0));
+ }
+ function l() {
+ const t = 0.8;
+ var n = cachedElementBoundingRect(e);
+ if (0 === n.width || 0 === n.height) return !0;
+ var i,
+ r = childrenWithParallelStructure(e),
+ a = r.length;
+ if (a) {
+ i = [];
+ for (var l = 0; l < a; ++l) {
+ var o = r[l];
+ if ("none" === getComputedStyle(o).float)
+ for (var s = o.children, c = s.length, m = 0; m < c; ++m)
+ i.push(s[m]);
+ else i.push(o);
+ }
+ } else i = e.children;
+ var d = i.length,
+ h = 0;
+ for (l = 0; l < d; ++l) {
+ var u = i[l];
+ "none" !== getComputedStyle(u).float && (h += u.innerText.length);
+ }
+ return h / e.innerText.length > t;
+ }
+ function o(t) {
+ const n = 50;
+ if (cachedElementBoundingRect(t).height > n) return !1;
+ return (
+ !!new Set(["ul", "li", "nav"]).has(normalizedElementTagName(t)) ||
+ (t.parentElement === e && !t.nextElementSibling)
+ );
+ }
+ function s(e, t) {
+ const n = 0.9;
+ return !(
+ cachedElementBoundingRect(e).height >
+ n * cachedElementBoundingRect(t).height
+ );
+ }
+ function c(e, t) {
+ const n = 1.1,
+ i = 1.4;
+ t &&
+ W &&
+ (e.matches(HeaderElementsSelector) ||
+ ((t > i * W || (H.test(y.className) && t > n * W)) &&
+ !e.closest(".pullquote") &&
+ (e.classList.add("pullquote"),
+ e.classList.contains("float") ||
+ ((e.style.width = null), cleanStyleAndClassList(e)))));
+ }
+ function m(e, t) {
+ for (var n = e[t]; n; n = n[t])
+ if (!isNodeWhitespace(n) && n.nodeType !== Node.COMMENT_NODE)
+ return !1;
+ return !0;
+ }
+ const d = new Set([
+ "form",
+ "script",
+ "style",
+ "link",
+ "button",
+ "object",
+ "embed",
+ "applet",
+ ]),
+ h = new Set([
+ "div",
+ "table",
+ "ul",
+ "canvas",
+ "p",
+ "iframe",
+ "aside",
+ "section",
+ "footer",
+ "nav",
+ "ol",
+ "menu",
+ "svg",
+ ]),
+ u = new Set(["i", "em"]),
+ g = new Set(["b", "strong", "h1", "h2", "h3", "h4", "h5", "h6"]),
+ f = new Set(["i-amphtml-sizer"]),
+ p = /lightbox/i;
+ var E = [],
+ v = 0,
+ T = 0,
+ A = 0,
+ S = 0,
+ N = 0,
+ b = 0,
+ y = e,
+ x = (y.ownerDocument.defaultView, t),
+ D = this.articleTitle(),
+ I = this._articleTitleElement,
+ C = (this.articleSubhead(), this._articleSubheadElement),
+ R =
+ I &&
+ cachedElementBoundingRect(I).top >
+ cachedElementBoundingRect(e).bottom,
+ L = isElementVisible(e),
+ M = new Set([I, C]),
+ F = new Set();
+ if (n === CleaningType.MainArticleContent) {
+ this.updateArticleBylineAndDateElementsIfNecessary();
+ var _ = this.articleBylineElement();
+ _ && F.add(_);
+ var w = this.articleDateElement();
+ w && F.add(w);
+ }
+ var O = this.dominantContentSelectorAndDepth(e),
+ B = l(),
+ P = new Set();
+ this.previouslyDiscoveredPageURLStrings.forEach(function (e) {
+ P.add(e);
+ });
+ var k = this.nextPageURL();
+ k && P.add(k);
+ var q = null;
+ this._articleTitleElement &&
+ (q = cachedElementBoundingRect(this._articleTitleElement));
+ var U = this.functionToPreventPruningElementDueToInvisibility(),
+ z = dominantFontFamilyAndSizeForElement(e),
+ W = dominantFontSizeInPointsFromFontFamilyAndSizeString(z);
+ const H = /pull(ed)?quote/i;
+ for (var V = [], j = [], Y = [], G = [], Q = []; y;) {
+ try {
+ var X,
+ K = null,
+ J = normalizedElementTagName(x),
+ $ = !1,
+ Z = elementLooksLikeDropCap(y);
+ if (
+ ((x.originalElement = y),
+ !b && elementAppearsToBeCollapsed(y) && (b = 1),
+ (d.has(J) || (this.isAMPPage() && f.has(J))) && (K = x),
+ !K && y !== e && M.has(y)
+ ? (K = x)
+ : !K && y !== e && F.has(y)
+ ? ((x.parentElementBeforePruning = x.parentElement),
+ (K = x),
+ V.push(x))
+ : elementIsAHeader(x) &&
+ previousLeafElementForElement(y) === I &&
+ x.classList.add("protected"),
+ "twitter-widget" === J && x.classList.add("protected"),
+ !K && ("h1" === J || "h2" === J))
+ )
+ if (
+ y.offsetTop - e.offsetTop <
+ HeaderMinimumDistanceFromArticleTop
+ ) {
+ var ee = trimmedInnerTextIgnoringTextTransform(y),
+ te = ee.length * HeaderLevenshteinDistanceToLengthRatio;
+ levenshteinDistance(D, ee) <= te && (K = x);
+ }
+ if (
+ (K ||
+ (this.isMediaWikiPage() &&
+ /editsection|icon-edit|edit-page|mw-empty-elt/.test(
+ y.className,
+ ) &&
+ (K = x)),
+ "video" === J)
+ )
+ if (x.getAttribute("src")) {
+ x.classList.add("protected");
+ var ne = cachedElementBoundingRect(y);
+ (x.setAttribute("width", ne.width),
+ x.setAttribute("height", ne.height),
+ x.removeAttribute("style"));
+ y.hasAttribute("autoplay") &&
+ y.hasAttribute("muted") &&
+ y.hasAttribute("loop")
+ ? x.setAttribute("data-reader-silent-looped-animation", "")
+ : (x.setAttribute("controls", !0),
+ x.removeAttribute("autoplay"),
+ x.removeAttribute("preload"));
+ } else K = x;
+ K || (X = getComputedStyle(y));
+ let t = (function () {
+ if ("div" !== J && "span" !== J) return !1;
+ if (LazyLoadRegex.test(y.className)) return !0;
+ for (let e of attributesForElement(y))
+ if (
+ /^data-/.test(e.name) &&
+ LazyLoadRegex.test(e.value) &&
+ cachedElementBoundingRect(y).height
+ )
+ return !0;
+ return !1;
+ })();
+ if (
+ !K &&
+ t &&
+ (!y.innerText ||
+ (y.previousElementSibling &&
+ "noscript" ===
+ normalizedElementTagName(y.previousElementSibling)))
+ )
+ if ((xe = lazyLoadingImageURLForElement(x, y.className))) {
+ var ie = this.contentDocument.createElement("img");
+ (ie.setAttribute("src", xe),
+ x.parentNode.replaceChild(ie, x),
+ ((x = ie).originalElement = y),
+ (J = normalizedElementTagName(x)),
+ (K = x),
+ x.classList.add("protected"));
+ }
+ if (!K && "img" !== J && /img/.test(J)) {
+ lazyLoadingImageURLForElement(x, y.className) &&
+ (((x = changeElementType(x, "img")).originalElement = y),
+ (J = "img"));
+ }
+ if (!K && "div" === J && x.parentNode) {
+ var re = y.querySelectorAll(
+ "a, blockquote, dl, div, img, ol, p, pre, table, ul",
+ ),
+ ae = T || "none" !== X.float,
+ le = null;
+ if (
+ (ae || re.length
+ ? elementIndicatesItIsASchemaDotOrgImageObject(y) &&
+ !x.querySelector("figure, .auxiliary")
+ ? (le = "figure")
+ : Z && (le = "span")
+ : (le = "p"),
+ le)
+ ) {
+ for (
+ var oe = x.parentNode,
+ se = this.contentDocument.createElement(le);
+ x.firstChild;
+ ) {
+ var ce = x.firstChild;
+ se.appendChild(ce);
+ }
+ (oe.replaceChild(se, x),
+ ((x = se).originalElement = y),
+ (J = normalizedElementTagName(x)));
+ }
+ }
+ if (
+ (y.dataset &&
+ y.dataset.mathml &&
+ y.querySelector("math") &&
+ Y.push(x),
+ !K &&
+ x.parentNode &&
+ h.has(J) &&
+ ((x._originalElementDepthInCollapsedArea = b), E.push(x)),
+ K ||
+ (isElementPositionedOffScreen(y)
+ ? (K = x)
+ : y === e ||
+ T ||
+ "none" === X.float ||
+ B ||
+ !(
+ cachedElementBoundingRect(y).height >= FloatMinimumHeight ||
+ y.childElementCount > 1
+ ) ||
+ (T = 1)),
+ !K)
+ ) {
+ if (
+ (sanitizeElementByRemovingAttributes(x),
+ n === CleaningType.MetadataContent)
+ )
+ if ("|" === x.innerText)
+ ((x.innerText = ""), x.classList.add("delimiter"));
+ else if ("time" === normalizedElementTagName(x)) {
+ var me = x.previousElementSibling;
+ if (
+ me &&
+ "span" === normalizedElementTagName(me) &&
+ !me.classList.contains("delimiter")
+ ) {
+ var de = this.contentDocument.createElement("span");
+ (de.classList.add("delimiter"), x.before(de));
+ }
+ } else "figure" === J && (K = x);
+ if (
+ ("both" === X.clear && x.classList.add("clear"),
+ "ul" === J || "ol" === J || "menu" === J)
+ ) {
+ if (q && !b && cachedElementBoundingRect(y).top < q.top) K = x;
+ else if (
+ "none" === X["list-style-type"] &&
+ "none" === X["background-image"]
+ ) {
+ for (
+ var he = y.children, ue = he.length, ge = !0, fe = 0;
+ fe < ue;
+ ++fe
+ ) {
+ var pe = he[fe],
+ Ee = getComputedStyle(pe);
+ if (
+ "none" !== Ee["list-style-type"] ||
+ 0 !== parseInt(Ee["-webkit-padding-start"])
+ ) {
+ ge = !1;
+ break;
+ }
+ var ve = getComputedStyle(pe, ":before").content;
+ if (/\u2022|\u25e6|\u2023|\u2219|counter/.test(ve)) {
+ ge = !1;
+ break;
+ }
+ }
+ ge && x.classList.add("list-style-type-none");
+ }
+ if (y.querySelector("code")) {
+ const e = /monospace|menlo|courier/i;
+ var Te = dominantFontFamilyAndSizeForElement(y);
+ e.test(Te) &&
+ (x.classList.add("code-block"), x.classList.add("protected"));
+ }
+ }
+ if (
+ (S ||
+ "normal" === X.fontStyle ||
+ (u.has(J) || (x.style && (x.style.fontStyle = X.fontStyle)),
+ (S = 1)),
+ !N && "normal" !== X.fontWeight)
+ ) {
+ if (!g.has(J)) {
+ var Ae = parseInt(X.fontWeight),
+ Se = null;
+ (isNaN(Ae)
+ ? (Se = X.fontWeight)
+ : Ae <= 400 || (Ae >= 500 && (Se = "bold")),
+ Se && x.style && (x.style.fontWeight = Se));
+ }
+ N = 1;
+ }
+ if ((T && "section" !== J && s(y, e)) || "aside" === J) {
+ Te = dominantFontFamilyAndSizeForElement(y);
+ var Ne = dominantFontSizeInPointsFromFontFamilyAndSizeString(Te),
+ be = Te && Te === z;
+ if (
+ (1 !== T ||
+ Z ||
+ (cachedElementBoundingRect(y).width <= MaximumFloatWidth
+ ? x.setAttribute("class", "auxiliary float " + X.float)
+ : be || x.classList.add("auxiliary")),
+ x.closest(".auxiliary") && y.style)
+ ) {
+ var ye = y.style.getPropertyValue("width");
+ ("table" === X.display && /%/.test(ye) && parseInt(ye) < 2
+ ? (x.style.width = X.width)
+ : ye
+ ? (x.style.width = ye)
+ : (K = x),
+ 1 !== T ||
+ ye ||
+ (x.style.width =
+ cachedElementBoundingRect(y).width + "px"));
+ }
+ Z || c(x, Ne);
+ }
+ if ("table" === J) A || (A = 1);
+ else if ("img" === J) {
+ var xe;
+ if ((xe = lazyLoadingImageURLForElement(x, y.className))) {
+ x.setAttribute("src", xe);
+ var De = !!x.closest("figure");
+ if (!De) {
+ var Ie = attributesForElement(y),
+ Ce = Ie.length;
+ for (fe = 0; fe < Ce; ++fe)
+ if (p.test(Ie[fe].nodeName)) {
+ De = !0;
+ break;
+ }
+ }
+ (De && x.classList.add("protected"), ($ = !0));
+ }
+ ((!xe && x.hasAttribute("src")) ||
+ !y.hasAttribute("data-srcset") ||
+ x.setAttribute("srcset", y.getAttribute("data-srcset")),
+ x.removeAttribute("border"),
+ x.removeAttribute("hspace"),
+ x.removeAttribute("vspace"));
+ var Re = x.getAttribute("align");
+ if (
+ (x.removeAttribute("align"),
+ ("left" !== Re && "right" !== Re) ||
+ (x.classList.add("float"), x.classList.add(Re)),
+ !T && !$)
+ ) {
+ var Le,
+ Me = (Le = cachedElementBoundingRect(y)).width,
+ Fe = Le.height;
+ hasClassMatchingRegexp(y, ProgressiveLoadingRegex) &&
+ y.nextElementSibling &&
+ "img" === normalizedElementTagName(y.nextElementSibling)
+ ? (K = x)
+ : imageIsContainedByContainerWithImageAsBackgroundImage(y)
+ ? x.classList.add("protected")
+ : (1 === Me && 1 === Fe) ||
+ (q &&
+ Fe < MinimumHeightForImagesAboveTheArticleTitle &&
+ Le.bottom < q.top)
+ ? (K = x)
+ : Me < ImageSizeTiny &&
+ Fe < ImageSizeTiny &&
+ x.setAttribute("class", "reader-image-tiny");
+ }
+ if (n === CleaningType.MetadataContent)
+ ((Le = cachedElementBoundingRect(y)).width >
+ MaximumWidthOrHeightOfImageInMetadataSection ||
+ Le.height > MaximumWidthOrHeightOfImageInMetadataSection) &&
+ (K = x);
+ if (y.classList.contains("emoji")) {
+ let e = urlFromString(x.src);
+ if (
+ e &&
+ "s.w.org" === e.hostname &&
+ e.pathname.startsWith("/images/core/emoji/")
+ ) {
+ let e = this.replaceImageWithAltText(x);
+ e &&
+ (((x = e).originalElement = y),
+ (J = normalizedElementTagName(x)),
+ (K = x),
+ x.classList.add("protected"));
+ }
+ }
+ } else if ("font" === J)
+ (x.removeAttribute("size"),
+ x.removeAttribute("face"),
+ x.removeAttribute("color"));
+ else if ("a" === J && x.parentNode) {
+ let e, t;
+ x instanceof HTMLAnchorElement
+ ? ((e = x.getAttribute("href")), (t = HTMLAnchorElement))
+ : x instanceof SVGAElement &&
+ ((e = x.getAttribute("xlink:href")), (t = SVGAElement));
+ let i = x.originalElement.ownerDocument.location,
+ r = urlStringShouldHaveItsAnchorMadeNonFunctional(e, i);
+ if (
+ t === HTMLAnchorElement &&
+ "author" === y.getAttribute("itemprop")
+ )
+ x.classList.add("protected");
+ else if (e && e.length && ("#" === e[0] || r)) {
+ const e = new Set(["li", "sup"]);
+ if (
+ !A &&
+ !x.childElementCount &&
+ 1 === x.parentElement.childElementCount &&
+ !e.has(normalizedElementTagName(x.parentElement))
+ )
+ this.contentDocument.evaluate(
+ "text()",
+ x.parentElement,
+ null,
+ XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
+ null,
+ ).snapshotLength || (K = x);
+ if (!K) {
+ se = this.contentDocument.createElement("span");
+ if (
+ 1 === x.childElementCount &&
+ "img" === normalizedElementTagName(x.firstElementChild)
+ ) {
+ var _e = x.firstElementChild;
+ _e.width > AnchorImageMinimumWidth &&
+ _e.height > AnchorImageMinimumHeight &&
+ se.setAttribute("class", "converted-image-anchor");
+ }
+ for (
+ se.className ||
+ se.setAttribute("class", "converted-anchor");
+ x.firstChild;
+ )
+ se.appendChild(x.firstChild);
+ (x.parentNode.replaceChild(se, x),
+ ((x = se).originalElement = y));
+ }
+ } else if (AdvertisementHostRegex.test(x.host) && !x.innerText)
+ K = x;
+ else if (
+ n !== CleaningType.MetadataContent &&
+ I &&
+ !R &&
+ I.compareDocumentPosition(y) &
+ document.DOCUMENT_POSITION_PRECEDING &&
+ cachedElementBoundingRect(y).top <
+ cachedElementBoundingRect(I).top
+ )
+ j.push(x);
+ else {
+ var we = y.children;
+ 1 === we.length &&
+ "img" === normalizedElementTagName(we[0]) &&
+ !y.innerText &&
+ anchorLooksLikeDownloadFlashLink(y) &&
+ (K = x);
+ }
+ r && (x.removeAttribute("xlink:href"), x.removeAttribute("href"));
+ } else if (
+ "aside" === J ||
+ "blockquote" === J ||
+ "q" === J ||
+ ("div" === J && H.test(y.className))
+ ) {
+ ((Te = dominantFontFamilyAndSizeForElement(y)),
+ (Ne = dominantFontSizeInPointsFromFontFamilyAndSizeString(Te)));
+ Z || c(x, Ne);
+ } else if ("cite" === J) {
+ var Oe = pseudoElementContent(y, ":after") ?? "",
+ Be = document.createElement("span");
+ ((Be.innerText = Oe), x.after(Be));
+ } else
+ "pre" === J
+ ? (x.style.whiteSpace = X.whiteSpace)
+ : "source" === J && y.hasAttribute("data-srcset")
+ ? (x.setAttribute("srcset", y.getAttribute("data-srcset")),
+ x.classList.add("protected"))
+ : x instanceof SVGAnimateElement &&
+ "xlink:href" === x.attributes.attributeName.value &&
+ (K = x);
+ }
+ if (X && L && !$) {
+ var Pe =
+ "none" === X.display ||
+ "visible" !== X.visibility ||
+ computedStyleIndicatesElementIsInvisibleDueToClipping(X);
+ if (
+ (Pe ||
+ "img" === J ||
+ (Pe =
+ "0" === X.opacity &&
+ "absolute" === X.position &&
+ !x.closest("figure")),
+ Pe && !b)
+ )
+ (!!O && v === O.depth && selectorForElement(y) === O.selector) ||
+ U(y, e) ||
+ (K = x);
+ }
+ if (
+ (!K && elementIsCommentBlock(y) && (K = x),
+ !K &&
+ q &&
+ cachedElementBoundingRect(y).top < q.top &&
+ VeryLiberalCommentRegex.test(y.className) &&
+ x.parentElement &&
+ (K = x),
+ !K && "a" === J && P.has(y.href))
+ ) {
+ for (
+ var ke, qe, Ue = y, ze = x;
+ (Ue = Ue.parentElement) && (ze = ze.parentElement);
+ ) {
+ const t = 10;
+ if (
+ cachedElementBoundingRect(Ue).top -
+ cachedElementBoundingRect(y).top >
+ t
+ )
+ break;
+ if (Ue === e) break;
+ o(Ue) && ((ke = Ue), (qe = ze));
+ }
+ (ke &&
+ ((K = qe),
+ (y = ke),
+ ((x = qe).originalElement = y),
+ (J = normalizedElementTagName(x))),
+ (Ue = null),
+ (ze = null),
+ (ke = null),
+ (qe = null));
+ }
+ } catch (e) {
+ K = x;
+ }
+ if (
+ (!K || K.parentElement || i || (K = null),
+ "div" === J ? G.push(x) : "aside" === J && Q.push(x),
+ !K)
+ ) {
+ let e = this._weakMapOfOriginalElementToUniqueID.get(
+ x.originalElement,
+ );
+ (e || (e = this._nextUniqueID()),
+ this._mapOfUniqueIDToOriginalElement.set(e, x.originalElement),
+ x.setAttribute(READER_UNIQUE_ID_ATTRIBUTE_KEY, e),
+ this._weakMapOfOriginalElementToUniqueID.set(x.originalElement, e));
+ }
+ var We = K ? null : y.firstElementChild;
+ if (We) ((y = We), (x = x.firstElementChild), r(1));
+ else {
+ for (var He; y !== e && !(He = y.nextElementSibling);)
+ ((y = y.parentElement), (x = x.parentElement), r(-1));
+ if (y === e) {
+ if (K && !elementIsProtected(K))
+ if (K.parentElement) K.remove();
+ else if (i) return null;
+ break;
+ }
+ ((y = He), (x = x.nextElementSibling), a());
+ }
+ if (K && !elementIsProtected(K))
+ if (K.parentElement) K.remove();
+ else if (i) return null;
+ }
+ for (let e of t.querySelectorAll("iframe")) {
+ if (elementLooksLikeEmbeddedTweet(e.originalElement))
+ (Ve = this.adoptableSimpleTweetFromTwitterElement(e)) &&
+ e.parentElement.replaceChild(Ve, e);
+ (e.classList.add("protected"),
+ e.setAttribute("sandbox", "allow-scripts allow-same-origin"));
+ }
+ for (let e of t.querySelectorAll("twitter-widget")) {
+ var Ve;
+ if (elementLooksLikeEmbeddedTweet(e.originalElement))
+ (Ve = this.adoptableSimpleTweetFromTwitterElement(e)) &&
+ e.parentElement.replaceChild(Ve, e);
+ e.classList.add("protected");
+ }
+ const je = t.querySelectorAll("blockquote"),
+ Ye = je.length;
+ for (fe = 0; fe < Ye; ++fe) {
+ const e = je[fe],
+ t = e.originalElement;
+ t && this.convertBlockquoteTweetToSimpleTweetIfAppropriate(e, t);
+ }
+ for (fe = E.length - 1; fe >= 0; --fe) {
+ ((ft = E[fe]).parentNode &&
+ this.shouldPruneElement(ft, ft.originalElement, z) &&
+ ft.remove(),
+ delete ft._originalElementDepthInCollapsedArea);
+ }
+ var Ge = j.length;
+ for (fe = 0; fe < Ge; ++fe) j[fe].remove();
+ var Qe = t.querySelectorAll(".float");
+ for (fe = 0; fe < Qe.length; ++fe) {
+ var Xe = !1,
+ Ke = Qe[fe];
+ if (!Xe) {
+ var Je = Ke.querySelectorAll("a, span.converted-image-anchor"),
+ $e = Ke.querySelectorAll("span.converted-anchor");
+ Xe = Ke.parentNode && $e.length > Je.length;
+ }
+ if (!Xe) {
+ var Ze = Ke.querySelectorAll("embed, object").length,
+ et = Ke.originalElement.querySelectorAll("embed, object").length;
+ !Ze && et && (Xe = !0);
+ }
+ if (!Xe) {
+ for (
+ var tt = Ke.originalElement.getElementsByTagName("img"),
+ nt = tt.length,
+ it = 0,
+ rt = 0;
+ rt < nt && (L && isElementVisible(tt[rt]) && it++, !(it > 1));
+ ++rt
+ );
+ if (1 === it) Ke.getElementsByTagName("img").length || (Xe = !0);
+ }
+ if (!Xe) {
+ const e = "img, video, embed, iframe, object, svg";
+ /\S/.test(Ke.innerText) ||
+ Ke.matches(e) ||
+ Ke.querySelector(e) ||
+ (Xe = !0);
+ }
+ Xe && !elementIsProtected(Ke) && Ke.remove();
+ }
+ var at = t.querySelectorAll("br");
+ for (fe = at.length - 1; fe >= 0; --fe) {
+ var lt = at[fe];
+ lt.originalElement &&
+ "block" ===
+ getComputedStyle(lt.originalElement.parentElement).display &&
+ (m(lt, "nextSibling") || m(lt, "previousSibling")) &&
+ lt.remove();
+ }
+ if (
+ i &&
+ !removeWhitespace(t.innerText).length &&
+ (n !== CleaningType.LeadingMedia ||
+ !t.querySelector("video, iframe, img"))
+ )
+ return null;
+ var ot = {},
+ st = (Je = t.querySelectorAll("a")).length;
+ for (fe = 0; fe < st; ++fe) {
+ (ot[(ct = (ht = Je[fe]).style.fontWeight)] || (ot[ct] = []),
+ ot[ct].push(ht));
+ }
+ for (var ct in ot) {
+ var mt = ot[ct],
+ dt = mt.length;
+ if (dt > 0.7 * st)
+ for (fe = 0; fe < dt; ++fe) {
+ var ht;
+ (((ht = mt[fe]).style.fontWeight = null),
+ ht.getAttribute("style") || ht.removeAttribute("style"));
+ }
+ }
+ var ut = t.querySelectorAll(".protected"),
+ gt = ut.length;
+ for (fe = 0; fe < gt; ++fe) {
+ var ft;
+ ((ft = ut[fe]).classList.remove("protected"),
+ ft.classList.length || ft.removeAttribute("class"));
+ }
+ var pt = t.querySelectorAll("p.auxiliary"),
+ Et = pt.length;
+ for (fe = 0; fe < Et; ++fe) {
+ for (
+ var vt = pt[fe], Tt = [vt], At = vt.nextElementSibling;
+ At &&
+ "p" === normalizedElementTagName(At) &&
+ At.classList.contains("auxiliary");
+ )
+ (Tt.push(At), (At = At.nextElementSibling));
+ var St = Tt.length;
+ if (St > 1) {
+ for (rt = 0; rt < St; ++rt) {
+ var Nt = Tt[rt];
+ (Nt.classList.remove("auxiliary"),
+ Nt.style && (Nt.style.width = null),
+ cleanStyleAndClassList(Nt));
+ }
+ fe += St - 1;
+ }
+ }
+ for (fe = G.length - 1; fe >= 0; --fe) {
+ var bt = G[fe];
+ bt !== t &&
+ elementWouldAppearBetterAsFigureOrAuxiliary(bt.originalElement, bt) &&
+ changeElementType(bt, "figure");
+ }
+ for (fe = Q.length - 1; fe >= 0; --fe) {
+ var yt = Q[fe];
+ yt !== t &&
+ elementWouldAppearBetterAsFigureOrAuxiliary(yt.originalElement, yt) &&
+ yt.classList.add("auxiliary");
+ }
+ var xt = V.length;
+ for (fe = 0; fe < xt; ++fe) {
+ var Dt = V[fe],
+ It = Dt.parentElementBeforePruning,
+ Ct = null,
+ Rt = null;
+ if (It)
+ ((Ct = depthOfElementWithinElement(It, t)),
+ (Rt = selectorForElement(It)));
+ var Lt = It ? It.closest("ul") : null;
+ if (Lt) Lt.remove();
+ else {
+ const e = 40;
+ It &&
+ cachedElementBoundingRect(It.originalElement).height < e &&
+ (!O || O.selector !== Rt || O.depth !== Ct)
+ ? It.remove()
+ : Dt.remove();
+ }
+ }
+ var Mt = Y.length;
+ for (fe = 0; fe < Mt; ++fe) {
+ var Ft = Y[fe],
+ _t = this.contentDocument.createElement("div");
+ ((_t.innerHTML = Ft.dataset ? Ft.dataset.mathml : ""),
+ Ft.parentNode.replaceChild(_t, Ft));
+ }
+ return t;
+ },
+ convertBlockquoteTweetToSimpleTweetIfAppropriate: function (e, t) {
+ const n = t.classList;
+ if (!n.contains("twitter-tweet") && !n.contains("twitter-video")) return;
+ const i = t.getElementsByTagName("a"),
+ r = i.length;
+ if (r < 1) return;
+ const a = i[r - 1];
+ if ("twitter.com" !== a.host) return;
+ const l = lastPathComponentFromAnchor(a);
+ if (isNaN(parseInt(l))) return;
+ const o = this.contentDocument.createElement("div");
+ (o.setAttribute("data-reader-tweet-id", l),
+ o.classList.add("tweet-wrapper"),
+ e.parentElement.replaceChild(o, e),
+ e.classList.add("simple-tweet"),
+ o.appendChild(e));
+ },
+ adoptableSimpleTweetFromTwitterElement: function (e) {
+ var t = function (e) {
+ var t = this.contentDocument.createElement("div"),
+ n = this.contentDocument.createTextNode(e);
+ return (t.appendChild(n), t.innerHTML);
+ }.bind(this);
+ let n = null,
+ i = e.originalElement;
+ if (
+ ("iframe" === normalizedElementTagName(e)
+ ? (n = i.contentDocument ? i.contentDocument.documentElement : null)
+ : "twitter-widget" === normalizedElementTagName(e) &&
+ (n = i.shadowRoot),
+ !n)
+ )
+ return null;
+ var r =
+ n.querySelector("[data-tweet-id].expanded") ||
+ n.querySelector("[data-tweet-id]");
+ if (!r) return null;
+ var a = this.contentDocument.createElement("div");
+ a.classList.add("tweet-wrapper");
+ var l = this.contentDocument.createElement("blockquote");
+ (l.classList.add("simple-tweet"), a.appendChild(l));
+ var o = r.getAttribute("data-tweet-id");
+ a.setAttribute("data-reader-tweet-id", o);
+ var s = r.querySelector(".dateline"),
+ c = r.querySelector('[data-scribe="element:screen_name"]'),
+ m = r.querySelector('[data-scribe="element:name"]'),
+ d = r.querySelector(".e-entry-title");
+ if (!(s && c && m && d)) return a;
+ var h = "— " + t(m.innerText) + " (" + t(c.innerText) + ")",
+ u = this.contentDocument.createElement("p");
+ ((u.innerHTML = d.innerHTML),
+ l.appendChild(u),
+ l.insertAdjacentHTML("beforeend", h));
+ var g = this.contentDocument.createElement("span");
+ ((g.innerHTML = s.innerHTML), l.appendChild(g));
+ for (let e of l.querySelectorAll("img.twitter-emoji"))
+ this.replaceImageWithAltText(e);
+ for (
+ var f = l.getElementsByTagName("*"), p = f.length, E = 0;
+ E < p;
+ ++E
+ ) {
+ e = f[E];
+ "script" === normalizedElementTagName(e)
+ ? e.remove()
+ : sanitizeElementByRemovingAttributes(e);
+ }
+ return a;
+ },
+ replaceImageWithAltText: function (e) {
+ var t = e.getAttribute("alt");
+ if (!t || t.length < 1) return null;
+ let n = this.contentDocument.createElement("span");
+ return ((n.innerText = t), e.parentNode.replaceChild(n, e), n);
+ },
+ leadingVideoNode: function () {
+ var e = this.leadingContentNodeWithSelector("video, iframe");
+ return e &&
+ e.parentElement &&
+ !e.previousElementSibling &&
+ !e.nextElementSibling
+ ? e.parentElement
+ : null;
+ },
+ leadingImageNode: function () {
+ return this.leadingContentNodeWithSelector("figure img, img");
+ },
+ ancestorsOfElement: function (e) {
+ let t = [],
+ n = e.parentNode;
+ for (; n;) (t.push(n), (n = n.parentNode));
+ return t;
+ },
+ leadingContentNodeWithSelector: function (e) {
+ const t = 250,
+ n = 0.5,
+ i = 0.9,
+ r = 3;
+ if (!this.article || !this.article.element) return null;
+ let a = 0;
+ if (this._articleTitleElement) {
+ let e,
+ t = this.ancestorsOfElement(this.article.element);
+ for (let n of t)
+ if (n.contains(this._articleTitleElement)) {
+ e = n;
+ break;
+ }
+ a = t.length - this.ancestorsOfElement(e).length + 2;
+ }
+ let l = Math.max(r, a);
+ for (var o = this.article.element, s = 0; s < l && o.parentNode; ++s) {
+ var c = (o = o.parentNode).querySelectorAll(e);
+ for (var m of c)
+ if (m && isElementVisible(m)) {
+ var d = cachedElementBoundingRect(m);
+ if (!(d.width >= window.innerWidth * i) && d.height < t) continue;
+ if (d.width < this._articleWidth * n) continue;
+ var h = this.article.element.compareDocumentPosition(m);
+ if (
+ !(h & Node.DOCUMENT_POSITION_PRECEDING) ||
+ h & Node.DOCUMENT_POSITION_CONTAINED_BY
+ )
+ continue;
+ var u = this.extraArticle ? this.extraArticle.element : null;
+ if (
+ u &&
+ this.article.element.compareDocumentPosition(u) &
+ Node.DOCUMENT_POSITION_FOLLOWING &&
+ (h = u.compareDocumentPosition(m)) &&
+ (!(h & Node.DOCUMENT_POSITION_PRECEDING) ||
+ h & Node.DOCUMENT_POSITION_CONTAINED_BY)
+ )
+ continue;
+ return m;
+ }
+ }
+ return null;
+ },
+ pageImageURLFromMetadata: function (e) {
+ var t = e["property:og:image"];
+ if (
+ (t || (t = e["property:twitter:image"]),
+ t || (t = e["property:twitter:image:src"]),
+ t)
+ ) {
+ let e = urlFromString(t);
+ if (e) {
+ let n = e.href;
+ n && urlIsHTTPFamilyProtocol(e) && (t = n);
+ }
+ }
+ return t;
+ },
+ mainImageNode: function () {
+ var e = this.leadingImageNode();
+ if (e) return e;
+ if (this.article && this.article.element)
+ for (
+ var t = this.article.element.querySelectorAll("img"),
+ n = t.length,
+ i = 0;
+ i < n;
+ ++i
+ ) {
+ var r = t[i],
+ a = r._cachedElementBoundingRect;
+ if (
+ (a || (a = r.getBoundingClientRect()),
+ a.width >= MainImageMinimumWidthAndHeight &&
+ a.height >= MainImageMinimumWidthAndHeight)
+ )
+ return r;
+ }
+ return null;
+ },
+ schemaDotOrgMetadataObjectForArticle: function () {
+ if (this._schemaDotOrgMetadataObjectForArticle)
+ return this._schemaDotOrgMetadataObjectForArticle;
+ const e = new Set([
+ "Article",
+ "NewsArticle",
+ "Report",
+ "ScholarlyArticle",
+ "SocialMediaPosting",
+ "BlogPosting",
+ "LiveBlogPosting",
+ "DiscussionForumPosting",
+ "TechArticle",
+ "APIReference",
+ ]);
+ var t = this.contentDocument.querySelectorAll(
+ "script[type='application/ld+json']",
+ ),
+ n = t.length;
+ try {
+ for (var i = 0; i < n; ++i) {
+ var r = t[i],
+ a = JSON.parse(r.textContent),
+ l = a["@context"];
+ if ("https://schema.org" === l || "http://schema.org" === l) {
+ var o = a["@type"];
+ if (e.has(o))
+ return ((this._schemaDotOrgMetadataObjectForArticle = a), a);
+ }
+ }
+ return null;
+ } catch (e) {
+ return null;
+ }
+ },
+ articleTitle: function () {
+ var e = this.articleTitleInformation();
+ return e ? e.titleText : "";
+ },
+ articleTitleInformation: function () {
+ function e(e, t) {
+ var n = e ? t.indexOf(e) : -1;
+ return -1 !== n && (0 === n || n + e.length === t.length);
+ }
+ function t(e, t) {
+ return (
+ e.host === t.host && e.pathname === t.pathname && e.hash === t.hash
+ );
+ }
+ function n(e) {
+ let t =
+ nearestAncestorElementWithTagName(e, "a") || e.querySelector("a");
+ return t
+ ? urlStringShouldHaveItsAnchorMadeNonFunctional(
+ t.href,
+ t.ownerDocument.location,
+ )
+ ? null
+ : t
+ : null;
+ }
+ if (!this.articleNode()) return;
+ if (this._articleTitleInformation) return this._articleTitleInformation;
+ const i =
+ /((article|post).*title|headline|instapaper_title|inside-head)/i,
+ r = 600,
+ a = 20,
+ l = 8,
+ o = 1.1,
+ s = 1.25,
+ c = /header|title|headline|instapaper_title/i,
+ m = 1.5,
+ d = 1.8,
+ h = 1.5,
+ u = 0.6,
+ g = 3,
+ f = 1.5,
+ p = 0.8,
+ E = 0.8,
+ v = 9,
+ T = 1.5,
+ A = /byline|author/i;
+ var S = function (e, t) {
+ var n = this.contentFromUniqueMetadataSelector(e, t);
+ if (n) {
+ var i = this.articleTitleAndSiteNameFromTitleString(n);
+ i && (n = i.articleTitle);
+ }
+ return n;
+ }.bind(this),
+ N = function () {
+ for (var e = this.articleNode(); e; e = e.parentElement)
+ if (elementIndicatesItIsASchemaDotOrgArticleContainer(e)) return e;
+ return null;
+ }.bind(this)(),
+ b = N
+ ? this.contentFromUniqueMetadataSelector(N, "meta[itemprop=headline]")
+ : "",
+ y = N
+ ? this.contentFromUniqueMetadataSelector(
+ N,
+ "meta[itemprop=alternativeHeadline]",
+ )
+ : "",
+ x = this.contentDocument,
+ D = x.location,
+ I = x.title,
+ C = S(x, "meta[property='og:title']"),
+ R = this.contentFromUniqueMetadataSelector(
+ x,
+ "meta[property='og:site_name']",
+ ),
+ L = S(x, "meta[name='twitter:title']"),
+ M = S(x, "meta[name='sailthru.headline']"),
+ F = this.schemaDotOrgMetadataObjectForArticle(),
+ _ = F ? F.headline : null,
+ w = this.articleNode(),
+ O = cachedElementBoundingRect(w);
+ this.extraArticleNode() &&
+ this.extraArticle.isPrepended &&
+ (O = cachedElementBoundingRect(this.extraArticleNode()));
+ var B = O.left + O.width / 2,
+ P = O.top,
+ k = P;
+ ((this._articleWidth = O.width),
+ (this._leadingMediaElement = this.leadingImageNode()),
+ this._leadingMediaElement ||
+ (this._leadingMediaElement = this.leadingVideoNode()),
+ this._leadingMediaElement) &&
+ (k =
+ (cachedElementBoundingRect(this._leadingMediaElement).top + P) / 2);
+ var q = "h1, h2, h3, h4, h5, a:not(svg a), p, div, span",
+ U = normalizedElementTagName(this.article.element);
+ ("dl" !== U && "dd" !== U) || (q += ", dt");
+ for (
+ var z = [], W = x.querySelectorAll(q), H = W.length, V = 0;
+ V < H;
+ ++V
+ ) {
+ var j = W[V],
+ Y = normalizedElementTagName(j);
+ if ("a" === Y)
+ j.innerText === C &&
+ t(j, D) &&
+ (j.previousElementSibling || j.nextElementSibling
+ ? z.push(j)
+ : z.push(j.parentElement));
+ else if ("div" === Y || "span" === Y || "p" === Y) {
+ if (hasClassMatchingRegexp(j, i) || i.test(j.getAttribute("id"))) {
+ var G = j.parentElement;
+ elementIsAHeader(G) || z.push(j);
+ }
+ } else z.push(j);
+ }
+ z = Array.prototype.slice.call(z, 0);
+ const Q = 2;
+ var X = this.article.element;
+ for (V = 0; V < Q; ++V) X.parentElement && (X = X.parentElement);
+ for (
+ var K, J = X.querySelectorAll("a:not(svg a)"), $ = ((V = 0), J.length);
+ V < $;
+ ++V
+ ) {
+ var Z = J[V];
+ if (Z.offsetTop > w.offsetTop + a) break;
+ if (t(Z, D) && "#" !== Z.getAttribute("href")) {
+ z.push(Z);
+ break;
+ }
+ }
+ var ee = z.map(trimmedInnerTextIgnoringTextTransform),
+ te = z.length,
+ ne = 0,
+ ie = [],
+ re = [],
+ ae = [],
+ le = [],
+ oe = [],
+ se = [],
+ ce = [];
+ const me = {},
+ de = (e) => {
+ const t = me[e];
+ if (t) return t;
+ const n = stringSimilarity(I, e);
+ return ((me[e] = n), n);
+ };
+ for (V = 0; V < te; ++V) {
+ var he = z[V],
+ ue = ee[V];
+ const e = {},
+ t = (t) => {
+ const n = e[t];
+ if (n) return n;
+ const i = stringSimilarity(ue, t);
+ return ((e[t] = i), i);
+ };
+ let n = de(ue);
+ if (C) {
+ const e = t(C);
+ ((n += e),
+ e > StringSimilarityToDeclareStringsNearlyIdentical && re.push(he));
+ }
+ if (L) {
+ const e = t(L);
+ ((n += e),
+ e > StringSimilarityToDeclareStringsNearlyIdentical && ae.push(he));
+ }
+ if (b) {
+ const e = t(b);
+ ((n += e),
+ e > StringSimilarityToDeclareStringsNearlyIdentical && le.push(he));
+ }
+ if (y) {
+ const e = t(y);
+ ((n += e),
+ e > StringSimilarityToDeclareStringsNearlyIdentical && oe.push(he));
+ }
+ if (M) {
+ const e = t(M);
+ ((n += e),
+ e > StringSimilarityToDeclareStringsNearlyIdentical && se.push(he));
+ }
+ if (_) {
+ const e = t(_);
+ ((n += e),
+ e > StringSimilarityToDeclareStringsNearlyIdentical && ce.push(he));
+ }
+ n === ne ? ie.push(he) : n > ne && ((ne = n), (ie = [he]));
+ }
+ let ge = [];
+ for (let e of z) {
+ let t = e.nextElementSibling;
+ t && SubheadRegex.test(t.className) && ge.push(e);
+ }
+ if (
+ (1 === re.length
+ ? ((K = re[0]).headerText = trimmedInnerTextIgnoringTextTransform(K))
+ : 1 === ae.length
+ ? ((K = ae[0]).headerText =
+ trimmedInnerTextIgnoringTextTransform(K))
+ : 1 === le.length
+ ? ((K = le[0]).headerText =
+ trimmedInnerTextIgnoringTextTransform(K))
+ : 1 === se.length
+ ? ((K = se[0]).headerText =
+ trimmedInnerTextIgnoringTextTransform(K))
+ : 1 === ce.length &&
+ ((K = ce[0]).headerText =
+ trimmedInnerTextIgnoringTextTransform(K)),
+ !K)
+ )
+ for (V = 0; V < te; ++V) {
+ he = z[V];
+ if (!isElementVisible(he)) continue;
+ var fe = cachedElementBoundingRect(he),
+ pe = fe.left + fe.width / 2,
+ Ee = pe - B,
+ ve = fe.top + fe.height / 2 - k,
+ Te = -1 !== re.indexOf(he),
+ Ae = -1 !== ae.indexOf(he),
+ Se = he.classList.contains("instapaper_title"),
+ Ne = /\bheadline\b/.test(he.getAttribute("itemprop")),
+ be = -1 !== le.indexOf(he),
+ ye = -1 !== oe.indexOf(he),
+ xe = -1 !== se.indexOf(he),
+ De = -1 !== ce.indexOf(he);
+ let t = ge.includes(he) && ve < 0;
+ var Ie = Te || Ae || Se || Ne || be || ye || xe || De || t,
+ Ce = Math.sqrt(Ee * Ee + ve * ve),
+ Re = Ie ? r : Math.max(r - Ce, 0),
+ Le = ((ue = ee[V]), he.getAttribute("property"));
+ if (Le) {
+ var Me = /dc.title/i.exec(Le);
+ if (Me && Me[0])
+ if (
+ 1 ===
+ this.contentDocument.querySelectorAll(
+ '*[property~="' + Me[0] + '"]',
+ ).length
+ ) {
+ (K = he).headerText = ue;
+ break;
+ }
+ }
+ if (!A.test(he.className)) {
+ if (!Ie) {
+ if (Ce > r) continue;
+ if (pe < O.left || pe > O.right) continue;
+ }
+ if (I && stringsAreNearlyIdentical(ue, I)) Re *= g;
+ else if (e(ue, I)) Re *= f;
+ else if (ue.length < l) continue;
+ if (ue !== R || !C) {
+ var Fe = !1;
+ if ((ze = n(he))) {
+ if ("author" === ze.getAttribute("rel")) continue;
+ var _e = ze.host === D.host,
+ we = ze.pathname === D.pathname;
+ if (_e && we) Re *= h;
+ else {
+ if (_e && nearestAncestorElementWithTagName(he, "li"))
+ continue;
+ ((Re *= u), (Fe = !0));
+ }
+ }
+ var Oe = fontSizeFromComputedStyle(getComputedStyle(he));
+ (Fe || (Re *= Oe / BaseFontSize),
+ (Re *=
+ 1 + TitleCandidateDepthScoreMultiplier * elementDepth(he)));
+ var Be = parseInt(this.contentTextStyle().fontSize);
+ (parseInt(Oe) > Be * o && (Re *= s),
+ (c.test(he.className) || c.test(he.getAttribute("id"))) &&
+ (Re *= m));
+ var Pe = he.parentElement;
+ (Pe &&
+ (c.test(Pe.className) || c.test(Pe.getAttribute("id"))) &&
+ (Re *= m),
+ -1 !== ie.indexOf(he) && (Re *= d));
+ w = this.article.element;
+ for (var ke = he; ke && ke !== w; ke = ke.parentElement)
+ if (SidebarRegex.test(ke.className)) {
+ Re *= p;
+ break;
+ }
+ (he.closest("li") && (Re *= E),
+ (!K || Re > K.headerScore) &&
+ (((K = he).headerScore = Re), (K.headerText = ue)));
+ }
+ }
+ }
+ var qe;
+ if (
+ (K &&
+ domDistance(K, w, v + 1) > v &&
+ parseInt(getComputedStyle(K).fontSize) < T * Be &&
+ (K = null),
+ K)
+ ) {
+ this._articleTitleElement = K;
+ var Ue = K.headerText.trim();
+ qe = C && e(C, Ue) ? C : I && e(I, Ue) ? I : Ue;
+ }
+ (this._leadingMediaElement ||
+ (this._leadingMediaElement = this.leadingImageNode()),
+ this._leadingMediaElement ||
+ (this._leadingMediaElement = this.leadingVideoNode()),
+ qe || (qe = C && e(C, I) ? C : I));
+ var ze,
+ We = null,
+ He = !1,
+ Ve = !1;
+ K &&
+ (ze = n(K)) &&
+ ((We = ze.href),
+ (He = "_blank" === ze.getAttribute("target")),
+ (Ve = ze.host !== D.host || ze.pathname !== D.pathname));
+ let je = {
+ titleText: qe,
+ linkURL: We,
+ linkIsTargetBlank: He,
+ linkIsForExternalPage: Ve,
+ };
+ return (
+ this._articleTitleElement &&
+ (this._mapOfUniqueIDToOriginalElement.set(READER_UNIQUE_ID_TITLE, K),
+ this._weakMapOfOriginalElementToUniqueID.set(
+ K,
+ READER_UNIQUE_ID_TITLE,
+ )),
+ (this._articleTitleInformation = je),
+ je
+ );
+ },
+ contentFromUniqueMetadataSelector: function (e, t) {
+ var n = e.querySelectorAll(t);
+ if (1 !== n.length) return null;
+ var i = n[0];
+ return i
+ ? this.elementAttributesContainImproperQuote(i)
+ ? null
+ : i.content
+ : null;
+ },
+ elementAttributesContainImproperQuote: function (e) {
+ for (var t = attributesForElement(e), n = t.length, i = 0; i < n; ++i)
+ if (/['"]/.test(t[i].name)) return !0;
+ return !1;
+ },
+ articleSubhead: function () {
+ function e(e) {
+ return elementIsAHeader(e)
+ ? parseInt(/h(\d)?/.exec(normalizedElementTagName(e))[1])
+ : NaN;
+ }
+ function t(e) {
+ if (!e) return null;
+ var t = e.content;
+ return t ? t.trim() : null;
+ }
+ const n = /author|kicker/i;
+ if (this._articleSubhead) return this._articleSubhead;
+ var i = this.articleNode();
+ if (!i) return;
+ var r = this._articleTitleElement;
+ if (!r) return;
+ var a = this.contentDocument,
+ l = a.location,
+ o = e(r),
+ s = cachedElementBoundingRect(r),
+ c = new Set(),
+ m = t(a.querySelector("meta[property='og:description']"));
+ m && c.add(m);
+ var d = t(a.querySelector("meta[name=description]"));
+ d && c.add(d);
+ var h,
+ u = this.schemaDotOrgMetadataObjectForArticle();
+ if (u) {
+ var g = u.description;
+ g && "string" == typeof g && c.add(g.trim());
+ }
+ var f = this.contentFromUniqueMetadataSelector(
+ a,
+ "head meta.swiftype[name=dek]",
+ );
+ f && (h = f);
+ let p = [],
+ E = nextNonFloatingVisibleElementSibling(r);
+ E && p.push(E);
+ let v = nextLeafElementForElement(r);
+ if (
+ (v &&
+ r &&
+ r.contains(v) &&
+ v.innerText &&
+ v.innerText.trim() === r.innerText.trim() &&
+ (v = nextLeafElementForElement(v)),
+ v && p.push(v),
+ c.size)
+ )
+ for (
+ var T = a.querySelectorAll(
+ HeaderElementsSelector + ", *[itemprop=description]",
+ ),
+ A = T.length,
+ S = 0;
+ S < A;
+ ++S
+ ) {
+ var N = T[S];
+ c.has(N.innerText.trim()) && p.push(N);
+ }
+ var b = p.length;
+ for (S = 0; S < b; ++S) {
+ var y = p[S];
+ if (y && y !== i) {
+ var x = y.className;
+ if (!n.test(x)) {
+ var D = y.closest("a");
+ if (D) {
+ var I = D.host === l.host,
+ C = D.pathname === l.pathname;
+ if (!I || !C) continue;
+ }
+ var R = !1;
+ if (elementIsAHeader(y))
+ if (isNaN(o)) R = !0;
+ else e(y) - 1 === o && (R = !0);
+ if ((!R && SubheadRegex.test(x) && (R = !0), !R)) {
+ const e = y.getAttribute("itemprop");
+ /\bdescription\b/.test(e) &&
+ !/\barticleBody\b/.test(e) &&
+ (R = !0);
+ }
+ if (
+ (!R && c.has(y.innerText) && (R = !0),
+ !R && h && h === y.innerText && (R = !0),
+ R || "summary" !== y.getAttribute("itemprop") || (R = !0),
+ R)
+ ) {
+ var L;
+ if ("meta" === normalizedElementTagName(y)) {
+ var M = y.getAttribute("content");
+ L = M ? M.trim() : "";
+ var F = y.nextElementSibling;
+ if (!F || trimmedInnerTextIgnoringTextTransform(F) !== L)
+ continue;
+ y = F;
+ } else {
+ if (cachedElementBoundingRect(y).top < (s.bottom + s.top) / 2)
+ continue;
+ L = trimmedInnerTextIgnoringTextTransform(y).trim();
+ }
+ if (L.length) {
+ ((this._articleSubheadElement = y),
+ this._mapOfUniqueIDToOriginalElement.set(
+ READER_UNIQUE_ID_SUBHEAD,
+ y,
+ ),
+ this._weakMapOfOriginalElementToUniqueID.set(
+ y,
+ READER_UNIQUE_ID_SUBHEAD,
+ ),
+ (this._articleSubhead = L));
+ break;
+ }
+ }
+ }
+ }
+ }
+ return this._articleSubhead;
+ },
+ adoptableMetadataBlock: function () {
+ function e(e) {
+ function t(e, i) {
+ if (e.nodeType !== Node.TEXT_NODE) {
+ if (e.nodeType === Node.ELEMENT_NODE) {
+ var r = e.childNodes,
+ a = r.length;
+ 0 !== a &&
+ (1 !== a
+ ? (i !== n.Right && t(r[0], n.Left),
+ i !== n.Left && t(r[a - 1], n.Right))
+ : t(r[0], i));
+ }
+ } else
+ i === n.Left
+ ? (e.textContent = e.textContent.trimLeft())
+ : i === n.Right
+ ? (e.textContent = e.textContent.trimRight())
+ : (e.textContent = e.textContent.trim());
+ }
+ const n = { Left: 1, Right: 2, Both: 3 };
+ t(e);
+ }
+ this.updateArticleBylineAndDateElementsIfNecessary();
+ var t = this.articleBylineElement(),
+ n = this.articleDateElement();
+ if (!t && !n) return null;
+ if (t && n) {
+ var i = t.compareDocumentPosition(n);
+ (i & Node.DOCUMENT_POSITION_CONTAINS && (t = null),
+ i & Node.DOCUMENT_POSITION_CONTAINED_BY && (n = null),
+ t === n && (n = null));
+ }
+ var r,
+ a = this.contentDocument.createElement("div"),
+ l = !1,
+ o = !1;
+ t &&
+ (e(
+ (r = this.cleanArticleNode(
+ t,
+ t.cloneNode(!0),
+ CleaningType.MetadataContent,
+ !1,
+ )),
+ ),
+ r.innerText.trim() && ((l = !0), r.classList.add("byline")));
+ if (n) {
+ var s = this.cleanArticleNode(
+ n,
+ n.cloneNode(!0),
+ CleaningType.MetadataContent,
+ !1,
+ );
+ (e(s), s.innerText.trim() && ((o = !0), s.classList.add("date")));
+ }
+ if ((l && a.appendChild(r), l && o)) {
+ var c = document.createElement("span");
+ (c.classList.add("delimiter"), a.appendChild(c));
+ }
+ return (o && a.appendChild(s), a);
+ },
+ articleBylineElement: function () {
+ return this._articleBylineElement;
+ },
+ findArticleBylineElement: function () {
+ var e = this.findArticleBylineElementWithoutRejection();
+ return e &&
+ ("footer" === normalizedElementTagName(e) || e.closest("figure"))
+ ? null
+ : e;
+ },
+ findArticleBylineElementWithoutRejection: function () {
+ function e(e) {
+ if (!e.length) return null;
+ e = e.filter(isElementVisible);
+ for (
+ var t = new Set(), n = new Set(), r = e.length, o = 0;
+ o < r - 1;
+ ++o
+ ) {
+ var s = e[o],
+ c = e[o + 1];
+ if (isElementVisible(s) && isElementVisible(c)) {
+ var m = s.parentElement;
+ m === c.parentElement &&
+ (m.contains(i) || (n.add(s.parentElement), t.add(s), t.add(c)));
+ }
+ }
+ var d = new Set(e);
+ (n.forEach(function (e) {
+ d.add(e);
+ }),
+ t.forEach(function (e) {
+ d.delete(e);
+ }),
+ (e = []),
+ d.forEach(function (t) {
+ e.push(t);
+ }));
+ var h,
+ u = null;
+ r = e.length;
+ for (o = 0; o < r; ++o) {
+ s = e[o];
+ if (isElementVisible(s)) {
+ var g = cachedElementBoundingRect(s),
+ f = g.left + g.width / 2,
+ p = g.top + g.height / 2,
+ E = a - f,
+ v = l - p,
+ T = Math.sqrt(E * E + v * v);
+ (!u || T < h) && ((u = s), (h = T));
+ }
+ }
+ return u;
+ }
+ const t = "[itemprop~=author], a[rel='author']:not(svg a)",
+ n =
+ "#byline, .byline, .article-byline, .byline__author, .entry-meta, .author-name, .byline-dateline, .article-author, [itemprop~=author], a[rel='author']:not(svg a)";
+ var i = this._articleSubheadElement || this._articleTitleElement;
+ if (i)
+ var r,
+ a = (r = i ? cachedElementBoundingRect(i) : null).left + r.width / 2,
+ l = r.top + r.height / 2;
+ var o = this.contentFromUniqueMetadataSelector(
+ this.contentDocument,
+ "head meta[name=author]",
+ );
+ if (
+ (o ||
+ (o = this.contentFromUniqueMetadataSelector(
+ this.contentDocument,
+ "head meta[property=author]",
+ )),
+ !o)
+ ) {
+ var s = this.schemaDotOrgMetadataObjectForArticle();
+ if (s) {
+ var c = s.author;
+ c && "object" == typeof c && (o = c.name);
+ }
+ }
+ var m = this.article.element,
+ d = m.querySelectorAll(n);
+ if (1 === d.length) return d[0];
+ var h = i ? i.nextElementSibling : null;
+ if (h) {
+ if ((h.matches(n) || h.innerText === o || (h = h.querySelector(n)), h))
+ if (h.querySelector("li")) {
+ var u = h.querySelector(n);
+ u && (h = u);
+ }
+ if (h) return h;
+ }
+ for (
+ var g = this.contentDocument.getElementsByTagName("a"),
+ f = 0,
+ p = g.length;
+ f < p;
+ ++f
+ ) {
+ var E = g[f];
+ if (trimmedInnerTextIgnoringTextTransform(E) === o) return E;
+ }
+ var v = m.closest("article");
+ if (i && v) {
+ if ((A = e(Array.from(v.querySelectorAll(t))))) return A;
+ if ((A = e(Array.from(v.querySelectorAll(n))))) return A;
+ }
+ var T = m.previousElementSibling;
+ if (T) {
+ var A;
+ if ((A = e(Array.from(T.querySelectorAll(t))))) return A;
+ if ((A = e(Array.from(T.querySelectorAll(n))))) return A;
+ }
+ return null;
+ },
+ articleDateElement: function () {
+ return this._articleDateElement;
+ },
+ findArticleDateElement: function () {
+ function e(e) {
+ for (var t = e; t && t !== l; t = t.parentElement)
+ if (elementIsCommentBlock(t) || elementLooksLikeACarousel(t))
+ return !0;
+ return !1;
+ }
+ function t(t) {
+ for (var n, i = null, r = t.length, a = 0; a < r; ++a) {
+ var l = t[a];
+ if (isElementVisible(l) && !e(l)) {
+ var o = cachedElementBoundingRect(l),
+ s = o.left + o.width / 2,
+ d = o.top + o.height / 2,
+ h = c - s,
+ u = m - d,
+ g = Math.sqrt(h * h + u * u);
+ (!i || g < n) && ((i = l), (n = g));
+ }
+ }
+ return i;
+ }
+ const n = /date/i,
+ i = "time, .dateline, .entry-date";
+ var r,
+ a = this._articleSubheadElement || this._articleTitleElement,
+ l = this.article.element,
+ o = a ? a.nextElementSibling : null;
+ if (
+ (o && 1 === (r = o.querySelectorAll(i)).length && (o = r[0]),
+ !o ||
+ o.matches(i) ||
+ hasClassMatchingRegexp(o, n) ||
+ o.querySelector(i) ||
+ (o = null),
+ o && o.contains(l) && (o = null),
+ o)
+ )
+ return o;
+ if (a)
+ var s,
+ c = (s = a ? cachedElementBoundingRect(a) : null).left + s.width / 2,
+ m = s.top + s.height / 2;
+ if ((r = l.querySelectorAll(i)).length) return t(r);
+ if ((l = l.closest("article")) && (r = l.querySelectorAll(i)).length)
+ return t(r);
+ return null;
+ },
+ articleDateElementWithBylineElementHint: function (e) {
+ function t(e) {
+ return (
+ /date/.test(e.className) ||
+ /\bdatePublished\b/.test(e.getAttribute("itemprop"))
+ );
+ }
+ var n = e.nextElementSibling;
+ if (n && t(n)) return n;
+ var i = nextLeafElementForElement(e);
+ return i && t(i) ? i : null;
+ },
+ updateArticleBylineAndDateElementsIfNecessary: function () {
+ this.article &&
+ (this._didArticleBylineAndDateElementDetection ||
+ (this.updateArticleBylineAndDateElements(),
+ (this._didArticleBylineAndDateElementDetection = !0)));
+ },
+ updateArticleBylineAndDateElements: function () {
+ var e = this.findArticleBylineElement(),
+ t = this.findArticleDateElement();
+ (!t && e && (t = this.articleDateElementWithBylineElementHint(e)),
+ (this._articleDateElement = t),
+ (this._articleBylineElement = e));
+ },
+ articleIsLTR: function () {
+ if (!this._articleIsLTR) {
+ var e = getComputedStyle(this.article.element);
+ this._articleIsLTR = !e || "ltr" === e.direction;
+ }
+ return this._articleIsLTR;
+ },
+ findSuggestedCandidate: function () {
+ var e,
+ t,
+ n = this.suggestedRouteToArticle;
+ if (!n || !n.length) return null;
+ for (
+ t = n.length - 1;
+ t >= 0 &&
+ (!n[t].id || !(e = this.contentDocument.getElementById(n[t].id)));
+ --t
+ );
+ for (t++, e || (e = this.contentDocument); t < n.length;) {
+ for (
+ var i = n[t],
+ r =
+ e.nodeType === Node.DOCUMENT_NODE
+ ? e.documentElement
+ : e.firstElementChild,
+ a = 1;
+ r && a < i.index;
+ r = r.nextElementSibling
+ )
+ this.shouldIgnoreInRouteComputation(r) || a++;
+ if (!r) return null;
+ if (normalizedElementTagName(r) !== normalizedElementTagName(i))
+ return null;
+ if (i.className && r.className !== i.className) return null;
+ ((e = r), t++);
+ }
+ return isElementVisible(e)
+ ? new CandidateElement(e, this.contentDocument)
+ : null;
+ },
+ findArticleBySearchingAllElements: function (e) {
+ var t = this.findSuggestedCandidate(),
+ n = this.findCandidateElements();
+ if (!n || !n.length) return t;
+ if (t && t.basicScore() >= ReaderMinimumScore) return t;
+ for (
+ var i = this.highestScoringCandidateFromCandidates(n), r = i.element;
+ r !== this.contentDocument;
+ r = r.parentNode
+ )
+ if ("blockquote" === normalizedElementTagName(r)) {
+ for (var a = r.parentNode, l = n.length, o = 0; o < l; ++o) {
+ var s = n[o];
+ if (s.element === a) {
+ i = s;
+ break;
+ }
+ }
+ break;
+ }
+ if (t && i.finalScore() < ReaderMinimumScore) return t;
+ if (!e) {
+ if (i.shouldDisqualifyDueToScoreDensity()) return null;
+ if (i.shouldDisqualifyDueToHorizontalRuleDensity()) return null;
+ if (i.shouldDisqualifyDueToHeaderDensity()) return null;
+ if (i.shouldDisqualifyDueToSimilarElements(n)) return null;
+ }
+ return i;
+ },
+ findExtraArticle: function () {
+ if (!this.article) return null;
+ for (
+ var e = 0, t = this.article.element;
+ e < 3 && t;
+ ++e, t = t.parentNode
+ ) {
+ var n = this.findExtraArticleCandidateElements(t);
+ if (n && n.length)
+ for (
+ var i,
+ r = this.sortCandidateElementsInDescendingScoreOrder(n),
+ a = 0;
+ a < r.length && (i = r[a]) && i.basicScore();
+ a++
+ )
+ if (
+ !i.shouldDisqualifyDueToScoreDensity() &&
+ !i.shouldDisqualifyDueToHorizontalRuleDensity() &&
+ !(
+ i.shouldDisqualifyDueToHeaderDensity() ||
+ (cachedElementBoundingRect(i.element).height <
+ PrependedArticleCandidateMinimumHeight &&
+ cachedElementBoundingRect(this.article.element).width !==
+ cachedElementBoundingRect(i.element).width)
+ )
+ ) {
+ var l = contentTextStyleForNode(this.contentDocument, i.element);
+ if (
+ l &&
+ l.fontFamily === this.contentTextStyle().fontFamily &&
+ l.fontSize === this.contentTextStyle().fontSize &&
+ i
+ )
+ return i;
+ }
+ }
+ return null;
+ },
+ highestScoringCandidateFromCandidates: function (e) {
+ for (var t = 0, n = null, i = e.length, r = 0; r < i; ++r) {
+ var a = e[r],
+ l = a.basicScore();
+ l >= t && ((t = l), (n = a));
+ }
+ return n;
+ },
+ sortCandidateElementsInDescendingScoreOrder: function (e) {
+ function t(e, t) {
+ return e.basicScore() !== t.basicScore()
+ ? t.basicScore() - e.basicScore()
+ : t.depth() - e.depth();
+ }
+ return e.sort(t);
+ },
+ findCandidateElements: function () {
+ const e = 1e3;
+ for (
+ var t = Date.now() + e,
+ n = this.contentDocument.getElementsByTagName("*"),
+ i = n.length,
+ r = [],
+ a = 0;
+ a < i;
+ ++a
+ ) {
+ var l = n[a];
+ if (!SetOfCandidateTagNamesToIgnore.has(normalizedElementTagName(l))) {
+ var o = CandidateElement.candidateIfElementIsViable(
+ l,
+ this.contentDocument,
+ );
+ if ((o && r.push(o), Date.now() > t)) {
+ r = [];
+ break;
+ }
+ }
+ }
+ var s = r.length;
+ for (a = 0; a < s; ++a) r[a].element.candidateElement = r[a];
+ for (a = 0; a < s; ++a) {
+ var c = r[a];
+ if ("blockquote" === normalizedElementTagName(c.element)) {
+ var m = c.element.parentElement.candidateElement;
+ m && m.addTextNodesFromCandidateElement(c);
+ }
+ }
+ for (a = 0; a < s; ++a) r[a].element.candidateElement = null;
+ return r;
+ },
+ findExtraArticleCandidateElements: function (e) {
+ if (!this.article) return [];
+ e || (e = this.article.element);
+ for (
+ var t = "preceding-sibling::*/descendant-or-self::*",
+ n = this.contentDocument.evaluate(
+ t,
+ e,
+ null,
+ XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
+ null,
+ ),
+ i = n.snapshotLength,
+ r = [],
+ a = 0;
+ a < i;
+ ++a
+ ) {
+ var l = n.snapshotItem(a);
+ if (!SetOfCandidateTagNamesToIgnore.has(normalizedElementTagName(l)))
+ (o = CandidateElement.extraArticleCandidateIfElementIsViable(
+ l,
+ this.article,
+ this.contentDocument,
+ !0,
+ )) && r.push(o);
+ }
+ ((t = "following-sibling::*/descendant-or-self::*"),
+ (i = (n = this.contentDocument.evaluate(
+ t,
+ e,
+ null,
+ XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
+ null,
+ )).snapshotLength));
+ for (a = 0; a < i; ++a) {
+ var o;
+ l = n.snapshotItem(a);
+ if (!SetOfCandidateTagNamesToIgnore.has(normalizedElementTagName(l)))
+ (o = CandidateElement.extraArticleCandidateIfElementIsViable(
+ l,
+ this.article,
+ this.contentDocument,
+ !1,
+ )) && r.push(o);
+ }
+ return r;
+ },
+ isGeneratedBy: function (e) {
+ var t = this.contentDocument.head
+ ? this.contentDocument.head.querySelector("meta[name=generator]")
+ : null;
+ if (!t) return !1;
+ var n = t.content;
+ return !!n && e.test(n);
+ },
+ isMediaWikiPage: function () {
+ return (
+ void 0 === this._isMediaWikiPage &&
+ (this._isMediaWikiPage = this.isGeneratedBy(/^MediaWiki /)),
+ this._isMediaWikiPage
+ );
+ },
+ isWordPressSite: function () {
+ return this.isGeneratedBy(/^WordPress/);
+ },
+ isAMPPage: function () {
+ return this.contentDocument.documentElement.hasAttribute("amp-version");
+ },
+ nextPageURLString: function () {
+ if (!this.article) return null;
+ if (this.isMediaWikiPage()) return null;
+ var e,
+ t = 0,
+ n = this.article.element;
+ n.parentNode &&
+ "inline" === getComputedStyle(n).display &&
+ (n = n.parentNode);
+ for (
+ var i = n,
+ r =
+ cachedElementBoundingRect(n).bottom +
+ LinkMaxVerticalDistanceFromArticle;
+ isElementNode(i) && cachedElementBoundingRect(i).bottom <= r;
+ )
+ i = i.parentNode;
+ i === n || (i !== this.contentDocument && !isElementNode(i)) || (n = i);
+ var a = this.contentDocument.evaluate(
+ LinkCandidateXPathQuery,
+ n,
+ null,
+ XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
+ null,
+ ),
+ l = a.snapshotLength;
+ if (this.pageNumber <= 2 && !this.prefixWithDateForNextPageURL) {
+ var o = this.contentDocument.location.pathname,
+ s = o.match(LinkDateRegex);
+ s &&
+ ((s = s[0]),
+ (this.prefixWithDateForNextPageURL = o.substring(
+ 0,
+ o.indexOf(s) + s.length,
+ )));
+ }
+ for (var c = 0; c < l; ++c) {
+ var m = a.snapshotItem(c),
+ d = this.scoreNextPageLinkCandidate(m);
+ d > t && ((e = m), (t = d));
+ }
+ return e ? e.href : null;
+ },
+ scoreNextPageLinkCandidate: function (e) {
+ function t(e, t, n, i) {
+ t.substring(0, e.length) === e &&
+ ((t = t.substring(e.length)), (e = ""));
+ var r = t.lastInteger();
+ if (isNaN(r)) return !1;
+ var a = e ? e.lastInteger() : NaN;
+ return (
+ (isNaN(a) || a >= MaximumExactIntegralValue) && (a = i),
+ r === a ? n.lastInteger() === a + 1 : r === a + 1
+ );
+ }
+ function n(e) {
+ for (
+ var t = {}, n = e.substring(1).split("&"), i = n.length, r = 0;
+ r < i;
+ ++r
+ ) {
+ var a = n[r],
+ l = a.indexOf("=");
+ -1 === l
+ ? (t[a] = null)
+ : (t[a.substring(0, l)] = a.substring(l + 1));
+ }
+ return t;
+ }
+ var i = this.contentDocument.location;
+ if (e.host !== i.host) return 0;
+ if (e.pathname === i.pathname && e.search === i.search) return 0;
+ if (-1 !== e.toString().indexOf("#")) return 0;
+ if (anchorLinksToAttachment(e) || anchorLinksToTagOrCategoryPage(e))
+ return 0;
+ if (!isElementVisible(e)) return 0;
+ var r = cachedElementBoundingRect(e),
+ a = this.articleBoundingRect(),
+ l = Math.max(
+ 0,
+ Math.max(a.top - (r.top + r.height), r.top - (a.top + a.height)),
+ );
+ if (r.top < a.top) return 0;
+ if (l > LinkMaxVerticalDistanceFromArticle) return 0;
+ if (
+ Math.max(
+ 0,
+ Math.max(a.left - (r.left + r.width), r.left - (a.left + a.width)),
+ ) > 0
+ )
+ return 0;
+ var o = i.pathname,
+ s = e.pathname;
+ if (this.prefixWithDateForNextPageURL) {
+ if (-1 === e.pathname.indexOf(this.prefixWithDateForNextPageURL))
+ return 0;
+ ((o = o.substring(this.prefixWithDateForNextPageURL.length)),
+ (s = s.substring(this.prefixWithDateForNextPageURL.length)));
+ }
+ var c = s.substring(1).split("/");
+ c[c.length - 1] || c.pop();
+ var m = c.length,
+ d = o.substring(1).split("/"),
+ h = !1;
+ d[d.length - 1] || ((h = !0), d.pop());
+ var u = d.length;
+ if (m < u) return 0;
+ for (var g = 0, f = 0, p = e.textContent, E = 0; E < m; ++E) {
+ var v = c[E],
+ T = E < u ? d[E] : "";
+ if (T !== v) {
+ if (E < u - 2) return 0;
+ if (v.length >= T.length) {
+ for (var A = 0; v[v.length - 1 - A] === T[T.length - 1 - A];) A++;
+ A &&
+ ((v = v.substring(0, v.length - A)),
+ (T = T.substring(0, T.length - A)));
+ var S = v.indexOf(T);
+ -1 !== S && (v = v.substring(S));
+ }
+ t(T, v, p, this.pageNumber)
+ ? (f = Math.pow(LinkNextOrdinalValueBase, E - m + 1))
+ : g++;
+ }
+ if (g > 1) return 0;
+ }
+ var N = !1;
+ if (e.search)
+ for (var b in ((linkParameters = n(e.search)),
+ (referenceParameters = n(i.search)),
+ linkParameters)) {
+ var y = linkParameters[b],
+ x = b in referenceParameters ? referenceParameters[b] : null;
+ if (x !== y)
+ if (
+ (null === x && (x = ""),
+ null === y && (y = ""),
+ y.length < x.length)
+ )
+ g++;
+ else if (t(x, y, p, this.pageNumber)) {
+ if (LinkURLSearchParameterKeyMatchRegex.test(b)) {
+ if (o.toLowerCase() !== s.toLowerCase()) return 0;
+ if (this.isWordPressSite() && h) return 0;
+ N = !0;
+ }
+ if (LinkURLBadSearchParameterKeyMatchRegex.test(b)) {
+ g++;
+ continue;
+ }
+ f = Math.max(f, 1 / LinkNextOrdinalValueBase);
+ } else g++;
+ }
+ if (!f) return 0;
+ if (
+ ((LinkURLPageSlashNumberMatchRegex.test(e.href) ||
+ LinkURLSlashDigitEndMatchRegex.test(e.href)) &&
+ (N = !0),
+ !N && m === u && stringSimilarity(o, s) < LinkMinimumURLSimilarityRatio)
+ )
+ return 0;
+ if (LinkURLArchiveSlashDigitEndMatchRegex.test(e)) return 0;
+ var D =
+ LinkMatchWeight * (Math.pow(LinkMismatchValueBase, -g) + f) +
+ (LinkVerticalDistanceFromArticleWeight * l) /
+ LinkMaxVerticalDistanceFromArticle;
+ (N && (D += LinkURLSemanticMatchBonus),
+ "li" === normalizedElementTagName(e.parentNode) &&
+ (D += LinkListItemBonus));
+ p = e.innerText;
+ return (
+ LinkNextMatchRegEx.test(p) && (D += LinkNextMatchBonus),
+ LinkPageMatchRegEx.test(p) && (D += LinkPageMatchBonus),
+ LinkContinueMatchRegEx.test(p) && (D += LinkContinueMatchBonus),
+ D
+ );
+ },
+ elementContainsEnoughTextOfSameStyle: function (e, t, n) {
+ const i = 110;
+ var r = "body" === normalizedElementTagName(e),
+ a = getVisibleNonWhitespaceTextNodes(e, r ? 2 : 3, i, r, t);
+ const l = 0.2,
+ o =
+ n /
+ clamp(scoreMultiplierForElementTagNameAndAttributes(e), l, 1 / 0) /
+ languageScoreMultiplierForTextNodes(a);
+ for (var s = {}, c = a.length, m = 0; m < c; ++m) {
+ var d = a[m],
+ h = d.length,
+ u = d.parentElement,
+ g = window.getComputedStyle(u),
+ f = g.fontFamily + "|" + g.fontSize,
+ p = Math.pow(h, TextNodeLengthPower);
+ if (s[f]) {
+ if ((s[f] += p) > o) break;
+ } else s[f] = p;
+ }
+ for (var f in s) if (s[f] > o) return !0;
+ return !1;
+ },
+ openGraphMetadataClaimsPageTypeIsArticle: function () {
+ if (!this._openGraphMetadataClaimsPageTypeIsArticle) {
+ var e = this.contentDocument.querySelector(
+ "head meta[property='og:type']",
+ );
+ this._openGraphMetadataClaimsPageTypeIsArticle =
+ e && "article" === e.content;
+ }
+ return this._openGraphMetadataClaimsPageTypeIsArticle;
+ },
+ prismGenreClaimsPageIsHomepage: function () {
+ return (
+ "homePage" ===
+ this.contentFromUniqueMetadataSelector(
+ this.contentDocument,
+ "head meta[name='prism.genre']",
+ )
+ );
+ },
+ pointsToUseForHitTesting: function () {
+ const e = window.innerWidth,
+ t = e / 4,
+ n = e / 2,
+ i = 128,
+ r = 320;
+ var a = [
+ [n, 800],
+ [n, 600],
+ [t, 800],
+ [n, 400],
+ [n - i, 1100],
+ [r, 700],
+ [3 * t, 800],
+ [e - r, 700],
+ ];
+ return (
+ this.openGraphMetadataClaimsPageTypeIsArticle() &&
+ a.push([n - i, 1400]),
+ a
+ );
+ },
+ findArticleByVisualExamination: function () {
+ for (
+ var e = new Set(),
+ t = this.pointsToUseForHitTesting(),
+ n = t.length,
+ i = AppleDotComAndSubdomainsRegex.test(
+ this.contentDocument.location.hostname.toLowerCase(),
+ )
+ ? 7200
+ : 1800,
+ r = this.candidateElementFilter,
+ a = 0;
+ a < n;
+ a++
+ )
+ for (
+ var l = t[a][0],
+ o = t[a][1],
+ s = elementAtPoint(l, o, this.contentDocument);
+ s && !e.has(s);
+ s = s.parentElement
+ ) {
+ if (VeryPositiveClassNameRegEx.test(s.className))
+ return new CandidateElement(s, this.contentDocument);
+ if (
+ !SetOfCandidateTagNamesToIgnore.has(normalizedElementTagName(s))
+ ) {
+ var c = s.offsetWidth,
+ m = s.offsetHeight;
+ if (!c && !m) {
+ var d = cachedElementBoundingRect(s);
+ ((c = d.width), (m = d.height));
+ }
+ if (!(
+ c < r.minimumWidth ||
+ m < r.minimumHeight ||
+ c * m < r.minimumArea
+ )) {
+ var h = this.elementContainsEnoughTextOfSameStyle(s, e, i);
+ if (
+ (e.add(s),
+ h &&
+ !(
+ CandidateElement.candidateElementAdjustedHeight(s) <
+ r.minimumHeight
+ ))
+ ) {
+ var u = new CandidateElement(s, this.contentDocument);
+ if (!u.shouldDisqualifyDueToSimilarElements()) {
+ if (u.shouldDisqualifyDueToHorizontalRuleDensity())
+ return null;
+ if (u.shouldDisqualifyDueToHeaderDensity()) return null;
+ if (!u.shouldDisqualifyForDeepLinking()) return u;
+ }
+ }
+ }
+ }
+ }
+ return null;
+ },
+ findTextSamplesByVisualExamination: function () {
+ function e(e) {
+ if (!e || !e.innerText) return null;
+ let n = t(e.innerText.trim());
+ return (n && a.add(e), n);
+ }
+ function t(e) {
+ const t = 10;
+ let i = textContentAppearsToBeCJK(e, d) ? d : m,
+ r = e.length;
+ if (r < i) return null;
+ if (r > f * c) return null;
+ let a = n(e);
+ return (a.match(/\n/g) || []).length > t ? null : a;
+ }
+ function n(e) {
+ return e.substring(0, h);
+ }
+ function i(t, n) {
+ let i = [],
+ r = s.querySelectorAll(t);
+ for (let t of r) {
+ if (i.length >= n) break;
+ if (elementDescendsFromElementInSet(t, l)) continue;
+ let r = e(t);
+ r && i.push([t, r]);
+ }
+ return i;
+ }
+ function r(e) {
+ const n = document.querySelectorAll("div"),
+ i = new Set();
+ for (let r of n) {
+ if (r.firstElementChild) continue;
+ let n = t(r.textContent);
+ if (n && (i.add(n), i.size >= e)) break;
+ }
+ return i;
+ }
+ this.setSuppressBoundingRectCalculationForSkippedElements(!0);
+ var a = new Set(),
+ l = new Set(),
+ o = new Set(),
+ s = this.contentDocument,
+ c = s.body.innerText.length;
+ const m = 20,
+ d = 10,
+ h = 200,
+ u = 5,
+ g = 5,
+ f = 0.8;
+ let p = s.title,
+ E = t(p);
+ E && (o.add(E), l.add(p));
+ let v = this.pointsToUseForHitTesting(),
+ T = v.length;
+ for (var A = 0; A < T; A++) {
+ let t = v[A][0],
+ n = v[A][1],
+ i = 0;
+ for (
+ let r = elementAtPoint(t, n, this.contentDocument);
+ r && !a.has(r) && !(i > u);
+ r = r.parentElement, i++
+ ) {
+ let t = e(r);
+ if (t) {
+ if (elementDescendsFromElementMatchingSelector(r, "code, form"))
+ break;
+ (o.add(t), l.add(r));
+ break;
+ }
+ }
+ }
+ let S = { p: 3, h1: 2, h2: 2, h3: 1 };
+ for (let [e, t] of Object.entries(S)) {
+ let n = i(e, t);
+ for (let [e, t] of n) e && t && (o.add(t), l.add(e));
+ }
+ if (o.size < g) {
+ let e = ["article", "header", "a", "footer", "body"];
+ for (let t of e) {
+ let e = i(t, 1) || [],
+ [n, r] = e.length > 0 ? e[0] : [null, null];
+ if (n && r) {
+ (o.add(r), l.add(n));
+ break;
+ }
+ }
+ }
+ if (o.size < g) {
+ const e = r(g - o.size);
+ o = o.union(e);
+ }
+ return Array.from(o);
+ },
+ findArticleFromMetadata: function (e) {
+ var t = this.contentDocument.querySelectorAll(
+ SchemaDotOrgArticleContainerSelector,
+ );
+ if (1 === t.length) {
+ var n = t[0];
+ if (n.matches("article, *[itemprop=articleBody]"))
+ if (
+ (o = CandidateElement.candidateIfElementIsViable(
+ n,
+ this.contentDocument,
+ !0,
+ ))
+ )
+ return e === FindArticleMode.ExistenceOfElement || o;
+ var i = n.querySelectorAll("article, *[itemprop=articleBody]"),
+ r = elementWithLargestAreaFromElements(i);
+ if (r)
+ if (
+ (o = CandidateElement.candidateIfElementIsViable(
+ r,
+ this.contentDocument,
+ !0,
+ ))
+ )
+ return e === FindArticleMode.ExistenceOfElement || o;
+ return new CandidateElement(n, this.contentDocument);
+ }
+ if (
+ this.openGraphMetadataClaimsPageTypeIsArticle() &&
+ !this.prismGenreClaimsPageIsHomepage()
+ ) {
+ var a = this.contentDocument.querySelectorAll("main article"),
+ l = elementWithLargestAreaFromElements(a);
+ if (l)
+ if (
+ (o = CandidateElement.candidateIfElementIsViable(
+ l,
+ this.contentDocument,
+ !0,
+ ))
+ )
+ return e === FindArticleMode.ExistenceOfElement || o;
+ var o,
+ s = this.contentDocument.querySelectorAll("article");
+ if (1 === s.length)
+ if (
+ (o = CandidateElement.candidateIfElementIsViable(
+ s[0],
+ this.contentDocument,
+ !0,
+ ))
+ )
+ return e === FindArticleMode.ExistenceOfElement || o;
+ }
+ return null;
+ },
+ articleTextContent: function () {
+ return (
+ this._articleTextContent || this.adoptableArticle(),
+ this._articleTextContent
+ );
+ },
+ unformattedArticleTextContentIncludingMetadata: function (e) {
+ this.setSuppressBoundingRectCalculationForSkippedElements(!0);
+ var t = this.articleNode();
+ if (t) {
+ if (!e) return t.innerText;
+ var n = "",
+ i = this.articleTitle();
+ i && (n += i + "\n");
+ var r = this.articleSubhead();
+ r && (n += r + "\n");
+ var a = this.adoptableMetadataBlock();
+ return (
+ a &&
+ (n +=
+ plaintextVersionOfNodeAppendingNewlinesBetweenBlockElements(a) +
+ "\n"),
+ n + t.innerText
+ );
+ }
+ },
+ pageDescription: function (e) {
+ var t = e["name:description"] || e["property:og:description"];
+ return t && (t = t.trim()).length ? t : null;
+ },
+ articleTitleAndSiteNameFromTitleString: function (e) {
+ const t = [" - ", " \u2013 ", " \u2014 ", ": ", " | ", " \xbb "],
+ n = t.length,
+ i = 0.6;
+ for (
+ var r,
+ a,
+ l = this.contentDocument.location.host.replace(
+ /^(www|m|secure)\./,
+ "",
+ ),
+ o = l.replace(/\.(com|info|net|org|edu|gov)$/, "").toLowerCase(),
+ s = 0;
+ s < n;
+ ++s
+ ) {
+ var c = e.split(t[s]);
+ if (2 === c.length) {
+ var m = c[0].trim(),
+ d = c[1].trim(),
+ h = m.toLowerCase(),
+ u = d.toLowerCase(),
+ g = Math.max(stringSimilarity(h, l), stringSimilarity(h, o)),
+ f = Math.max(stringSimilarity(u, l), stringSimilarity(u, o)),
+ p = Math.max(g, f);
+ (!a || p > a) &&
+ ((a = p),
+ (r =
+ g > f
+ ? { siteName: m, articleTitle: d }
+ : { siteName: d, articleTitle: m }));
+ }
+ }
+ return r && a >= i ? r : null;
+ },
+ pageInformation: function (e, t) {
+ var n,
+ i = this.buildMapOfMetaTags(),
+ r = this.pageDescription(i),
+ a = !1;
+ this.adoptableArticle()
+ ? ((n = this.articleTitle()),
+ (r = r || this.articleTextContent()),
+ (a = !0))
+ : ((n = this.contentDocument.title),
+ this.contentDocument.body &&
+ (r = r || this.contentDocument.body.innerText));
+ var l = "",
+ o = this.pageImageURLFromMetadata(i);
+ if (o) l = o;
+ else {
+ var s = this.mainImageNode();
+ s && (l = s.src);
+ }
+ (n || (n = userVisibleURLString(this.contentDocument.location.href)),
+ (n = n.trim()),
+ e && (n = n.substring(0, e)));
+ var c = this.contentFromUniqueMetadataSelector(
+ this.contentDocument,
+ "head meta[property='og:site_name']",
+ );
+ if (!c) {
+ var m = this.articleTitleAndSiteNameFromTitleString(
+ this.contentDocument.title,
+ );
+ m && m.articleTitle === n && (c = m.siteName);
+ }
+ return (
+ c || (c = ""),
+ (r = r ? r.trim() : ""),
+ t && (r = r.substring(0, t)),
+ {
+ title: n,
+ previewText: (r = r.replace(/[\s]+/g, " ")),
+ siteName: c,
+ mainImageURL: l,
+ isReaderAvailable: a,
+ }
+ );
+ },
+ readingListItemInformation: function () {
+ const e = 220,
+ t = 220;
+ return this.pageInformation(e, t);
+ },
+ buildMapOfMetaTags: function () {
+ var e = {};
+ const t = this.contentDocument.head.getElementsByTagName("meta"),
+ n = t.length;
+ for (var i = 0; i < n; ++i) {
+ const n = t[i],
+ r = n.content;
+ if (!r) continue;
+ if (this.elementAttributesContainImproperQuote(n)) continue;
+ n.name && (e["name:" + n.name.toLowerCase()] = r);
+ const a = n.getAttribute("property");
+ a && (e["property:" + a.toLowerCase()] = r);
+ }
+ return e;
+ },
+ pageTitleForTextAnalysis: function (e) {
+ const t = this.contentDocument;
+ var n = e["property:og:title"];
+ return (
+ n || (n = e["name:twitter:title"]),
+ n || (n = e["name:sailthru.headline"]),
+ n || (n = t.title),
+ n
+ );
+ },
+ pageAuthorForTextAnalysis: function (e) {
+ return e["name:author"] || e["property:author"];
+ },
+ pageMetadataCommonToTextAnalysisAndArticleContent: function () {
+ var e = {};
+ const t = this.buildMapOfMetaTags(),
+ n = this.pageTitleForTextAnalysis(t);
+ n && (e.title = n);
+ const i = this.pageAuthorForTextAnalysis(t);
+ i && (e.author = i);
+ const r = this.pageImageURLFromMetadata(t);
+ return (r && (e.imageURL = r), e);
+ },
+ extractedArticleContent: function () {
+ try {
+ const e = this.adoptableArticle(!0);
+ for (let t of e.getElementsByTagName("*"))
+ t.removeAttribute(READER_UNIQUE_ID_ATTRIBUTE_KEY);
+ let t = this.pageMetadataCommonToTextAnalysisAndArticleContent();
+ if (e) {
+ const n = e.innerHTML;
+ t.body = n;
+ }
+ this.updateArticleBylineAndDateElementsIfNecessary();
+ const n = this.articleDateElement();
+ n && (t.publishedDate = trimmedInnerTextIgnoringTextTransform(n));
+ const i = this.articleBylineElement();
+ return (
+ !t.author &&
+ i &&
+ (t.author = trimmedInnerTextIgnoringTextTransform(i)),
+ t
+ );
+ } catch (e) {
+ let t = {};
+ const n = e.message,
+ i = e.stack;
+ return (n && (t.error = n), i && (t.stack = i), t);
+ }
+ },
+ readerUniqueIDOfElementPinnedToTopOfViewport: function () {
+ const e = 120;
+ if (window.scrollY < e) return null;
+ const t = this.articleNode();
+ if (!t) return null;
+ const n = t.getBoundingClientRect(),
+ i = (n.left + n.right) / 2;
+ for (const e of [0, 15, 35, 50, 80, 110]) {
+ const n = t.ownerDocument.elementFromPoint(i, e);
+ if (
+ n !== t &&
+ (t.contains(n) ||
+ n === this._articleTitleElement ||
+ n === this._articleSubheadElement)
+ ) {
+ const e = this._weakMapOfOriginalElementToUniqueID.get(n);
+ if (e) return e;
+ }
+ }
+ return null;
+ },
+ scrollToElementWithUniqueID: function (e, t) {
+ const n = this._rectOfElementWithReaderUniqueID(e);
+ if (!n || !n.top || isNaN(n.top) || !n.height || isNaN(n.height)) return;
+ const i = -t * n.height;
+ this.scrollToOffset(n.top + i);
+ },
+ uniqueIDAndScrollRatioOfElementPinnedToTop: function () {
+ const e = this.readerUniqueIDOfElementPinnedToTopOfViewport();
+ if (!e) return [null, null];
+ const t = this._rectOfElementWithReaderUniqueID(e);
+ if (!t || !t.top || isNaN(t.top) || !t.height || isNaN(t.height))
+ return [null, null];
+ return [e, (t.top - this.scrollY()) / t.height];
+ },
+ _rectOfElementWithReaderUniqueID: function (e) {
+ function t(e) {
+ return {
+ top: e.top + window.scrollY,
+ right: e.right + window.scrollX,
+ bottom: e.bottom + window.scrollY,
+ left: e.left + window.scrollX,
+ width: e.width,
+ height: e.height,
+ };
+ }
+ if (!this._mapOfUniqueIDToOriginalElement) return null;
+ let n = this._mapOfUniqueIDToOriginalElement.get(e);
+ return n && n.parentElement ? t(n.getBoundingClientRect()) : null;
+ },
+ scrollY: function () {
+ return window.scrollY;
+ },
+ scrollToOffset: function (e) {
+ if ("number" == typeof e)
+ try {
+ (clearCachedElementBoundingRects(),
+ this.cacheWindowScrollPosition(),
+ (this.contentDocument.scrollingElement.scrollTop = e));
+ } catch (e) {}
+ },
+ documentURLString: function () {
+ return this.contentDocument.location.href;
+ },
+ baseURI: function () {
+ return this.contentDocument.baseURI;
+ },
+ usesSearchEngineOptimizationMetadata: function () {
+ return !!document.head.querySelector('meta[property^="og:"]');
+ },
+ extractCanonicalLink: function () {
+ var e = document.head.querySelector("link[rel='canonical']");
+ if (!e) return null;
+ var t = e.getAttribute("href");
+ if (!t) return null;
+ var n = document.baseURI,
+ i = urlFromString(t, n);
+ return ("/" !== document.location.pathname && "/" === i.pathname) ||
+ ("localhost" === i.hostname &&
+ "localhost" !== document.location.hostname)
+ ? null
+ : i.href;
+ },
+ setSuppressBoundingRectCalculationForSkippedElements: function (e) {
+ this._shouldSuppressBoundingRectCalculationForSkippedElements = e;
+ },
+ shouldSuppressBoundingRectCalculationForSkippedElements: function () {
+ return !!this._shouldSuppressBoundingRectCalculationForSkippedElements;
+ },
+ handleNavigation: function (e) {
+ e.hashChange || this.resetArticleInformation();
+ },
+ }),
+ Object.defineProperty(globalThis, "ReaderArticleFinderJS", {
+ enumerable: !0,
+ get: () => (
+ globalReaderArticleFinder ||
+ (globalReaderArticleFinder = new ReaderArticleFinder(document)),
+ globalReaderArticleFinder
+ ),
+ }),
+ navigation.addEventListener("navigate", handleNavigationEvent));
+0;
diff --git a/27.0/js/reader/ReaderMacUI.js b/27.0/js/reader/ReaderMacUI.js
new file mode 100644
index 0000000..bcd0235
--- /dev/null
+++ b/27.0/js/reader/ReaderMacUI.js
@@ -0,0 +1,24 @@
+//# sourceURL=__InjectedScript_ReaderMacUI.js
+/* Copyright (c) 2026 Apple Inc. All rights reserved. */
+/*
+ * Copyright (c) 2010 Apple Inc. All rights reserved.
+ */
+function setScrollTop(e) {
+ document.documentElement.scrollTop = e;
+}
+function readerWillBecomeVisible() {
+ setReaderIsActive(!0);
+}
+function readerWillEnterBackground() {
+ setReaderIsActive(!1);
+}
+((ReaderJS._clickingOutsideOfPaperRectangleDismissesReader = !0),
+ (ReaderJS._isJavaScriptEnabled = function () {
+ return !!(ReaderJSController.initialConfiguration() || {})[
+ ReaderConfigurationJavaScriptEnabledKey
+ ];
+ }),
+ (ReaderAppearanceJS._tryApplyStaticConfiguration = function () {
+ return (document.body.classList.add("mac"), !1);
+ }));
+0;
diff --git a/27.0/js/reader/ReaderMobileUI.js b/27.0/js/reader/ReaderMobileUI.js
new file mode 100644
index 0000000..e1c0081
--- /dev/null
+++ b/27.0/js/reader/ReaderMobileUI.js
@@ -0,0 +1,57 @@
+//# sourceURL=__InjectedScript_ReaderMobileUI.js
+/* Copyright (c) 2026 Apple Inc. All rights reserved. */
+/*
+ * Copyright (c) 2010 Apple Inc. All rights reserved.
+ */
+function orientationChanged() {
+ ReaderAppearanceJS.layOutContent();
+}
+function articleHasScrolled() {
+ ReaderJS.resumeCachedNextPageLoadIfNecessary();
+}
+function contentInPrintingMailingFrame() {
+ let e = document.getElementById(ReaderJS.printingMailingFrameElementId());
+ return (
+ e ||
+ (ReaderJS.preparePrintingMailingFrame(),
+ (e = document.getElementById(ReaderJS.printingMailingFrameElementId()))),
+ e.contentDocument.documentElement.innerHTML
+ );
+}
+(window.addEventListener("orientationchange", orientationChanged, !1),
+ window.addEventListener("scroll", articleHasScrolled, !1));
+let originalShouldUsePaperAppearance =
+ ReaderAppearanceJS._shouldUsePaperAppearance.bind(ReaderAppearanceJS);
+((ReaderAppearanceJS._shouldUsePaperAppearance = function () {
+ return (
+ 0 !== window.orientation &&
+ 180 !== window.orientation &&
+ originalShouldUsePaperAppearance()
+ );
+}),
+ (ReaderAppearanceJS._isOLEDDisplay = function () {
+ return !!(ReaderJSController.initialConfiguration() || {}).isOLEDDisplay;
+ }),
+ (ReaderJS._distanceFromBottomOfArticleToStartLoadingNextPage = function () {
+ return (
+ ReaderJSController.maxDistanceForLoadingNextPage() ||
+ (screen.height >= 1024 ? 2048 : 1024)
+ );
+ }),
+ (ReaderJS._shouldSkipActivationWhenPageLoads = function () {
+ return (
+ ReaderJSController.isLoadingFromOfflineReadingListArchive &&
+ ReaderJSController.isLoadingFromOfflineReadingListArchive()
+ );
+ }),
+ (ReaderJS._shouldConvertRelativeURLsToAbsoluteURLsWhenPrintingOrMailing = !0),
+ (ReaderJS._deferSendingContentIsReadyForDisplay = !0),
+ (ReaderJS._isJavaScriptEnabled = function () {
+ return !!(ReaderJSController.initialConfiguration() || {})[
+ ReaderConfigurationJavaScriptEnabledKey
+ ];
+ }),
+ (ReaderAppearanceJS._tryApplyStaticConfiguration = function () {
+ return (document.body.classList.add("ios"), !1);
+ }));
+0;
diff --git a/27.0/js/reader/ReaderShared.js b/27.0/js/reader/ReaderShared.js
new file mode 100644
index 0000000..36e5602
--- /dev/null
+++ b/27.0/js/reader/ReaderShared.js
@@ -0,0 +1,29 @@
+//# sourceURL=__InjectedScript_ReaderShared.js
+/* Copyright (c) 2026 Apple Inc. All rights reserved. */
+// Copyright (c) 2025 Apple Inc. All rights reserved.
+"use strict";
+function normalizedElementTagName(e) {
+ return e.localName;
+}
+function plaintextVersionOfNodeAppendingNewlinesBetweenBlockElements(e) {
+ const n = (e.ownerDocument ?? document).createTreeWalker(
+ e,
+ NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_TEXT,
+ null,
+ );
+ let t = "";
+ for (n.currentNode = e; n.nextNode();) {
+ const e = n.currentNode;
+ if (e.nodeType === Node.TEXT_NODE) {
+ t += e.textContent;
+ continue;
+ }
+ let o = normalizedElementTagName(e);
+ ("p" !== o && "div" !== o) || (t += "\n");
+ }
+ return t;
+}
+const READER_UNIQUE_ID_ATTRIBUTE_KEY = "data-reader-unique-id",
+ READER_UNIQUE_ID_TITLE = "titleElement",
+ READER_UNIQUE_ID_SUBHEAD = "subheadElement";
+0;
diff --git a/27.0/js/reader/ReaderSharedUI.js b/27.0/js/reader/ReaderSharedUI.js
new file mode 100644
index 0000000..f4b8c3e
--- /dev/null
+++ b/27.0/js/reader/ReaderSharedUI.js
@@ -0,0 +1,2909 @@
+//# sourceURL=__InjectedScript_ReaderSharedUI.js
+/* Copyright (c) 2026 Apple Inc. All rights reserved. */
+// Copyright (c) 2013-2024 Apple Inc. All rights reserved.
+function articleHeight() {
+ return (
+ document.getElementById("article").offsetHeight +
+ 2 *
+ parseFloat(getComputedStyle(document.getElementById("article")).marginTop)
+ );
+}
+function smoothScroll(e, t, n, i) {
+ function o(t, n) {
+ ((scrollEventIsSmoothScroll = !0),
+ (e.scrollTop = n),
+ setTimeout(function () {
+ scrollEventIsSmoothScroll = !1;
+ }, 0));
+ }
+ const r = 1e3 / 60;
+ let a = e.scrollTop,
+ l = a + t,
+ s = 0,
+ d = articleHeight() - window.innerHeight;
+ if ((l < s && (l = s), l > d && (l = d), a == l)) return;
+ let c = Math.abs(l - a);
+ if (
+ (c < Math.abs(t) && (n = (n * c) / Math.abs(t)), smoothScrollingAnimator)
+ ) {
+ let e = smoothScrollingAnimator.animations[0].progress,
+ t = e > 0.5 ? 1 - e : e,
+ s = n / (1 - t),
+ d = -t * s,
+ c = Math.sin((Math.PI / 2) * t),
+ m = c * c,
+ u = (a - l * m) / (1 - m);
+ return (
+ abortSmoothScroll(),
+ (smoothScrollingAnimator = new AppleAnimator(s, r, i)),
+ (smoothScrollingAnimation = new AppleAnimation(u, l, o)),
+ smoothScrollingAnimator.addAnimation(smoothScrollingAnimation),
+ void smoothScrollingAnimator.start(d)
+ );
+ }
+ ((smoothScrollingAnimator = new AppleAnimator(n, r, i)),
+ (smoothScrollingAnimation = new AppleAnimation(a, l, o)),
+ smoothScrollingAnimator.addAnimation(smoothScrollingAnimation),
+ smoothScrollingAnimator.start());
+}
+function abortSmoothScroll() {
+ (smoothScrollingAnimator.stop(AnimationTerminationCondition.Interrupted),
+ (smoothScrollingAnimator = null),
+ (smoothScrollingAnimation = null));
+}
+function articleScrolled() {
+ (!scrollEventIsSmoothScroll && smoothScrollingAnimator && abortSmoothScroll(),
+ isReaderViewInSeparateProcess
+ ? (void 0 !== articleScrolledNotificationCoalescer &&
+ clearTimeout(articleScrolledNotificationCoalescer),
+ (articleScrolledNotificationCoalescer = setTimeout(function () {
+ (readerViewMessageHandler.postMessage({
+ command: "didScroll",
+ scrollPosition: getArticleScrollPosition(),
+ }),
+ (articleScrolledNotificationCoalescer = void 0));
+ }, 1e3)))
+ : ReaderJSController.articleScrolled());
+}
+function traverseReaderContent(e, t) {
+ if (!e) return;
+ let n = e.offsetTop,
+ i = document.createTreeWalker(
+ document.getElementById("article"),
+ NodeFilter.SHOW_ELEMENT,
+ {
+ acceptNode: function (e) {
+ let t = e.classList;
+ return t.contains("page-number") ||
+ t.contains("float") ||
+ t.contains("page") ||
+ t.contains("scrollable") ||
+ "HR" === e.tagName ||
+ 0 === e.offsetHeight ||
+ "inline" === getComputedStyle(e).display ||
+ n === e.offsetTop
+ ? NodeFilter.FILTER_SKIP
+ : NodeFilter.FILTER_ACCEPT;
+ },
+ },
+ );
+ return ((i.currentNode = e), i[t]());
+}
+function nextReaderContentElement(e) {
+ return traverseReaderContent(e, "nextNode");
+}
+function previousReaderContentElement(e) {
+ return traverseReaderContent(e, "previousNode");
+}
+function articleTitleElement() {
+ return document.querySelector("#article .page .title");
+}
+function articleTitleContainer() {
+ return document.querySelector('[data-reader-unique-id="titleElement"]');
+}
+function mediaElementIsPlaying(e) {
+ return !!(e.currentTime > 0 && !e.paused && !e.ended && e.readyState > 2);
+}
+function keyDown(e) {
+ let t = !(e.metaKey || e.altKey || e.ctrlKey || e.shiftKey),
+ n = !e.metaKey && !e.altKey && !e.ctrlKey && e.shiftKey;
+ switch (e.keyCode) {
+ case 8:
+ (n ? ReaderJSController.goForward() : t && ReaderJSController.goBack(),
+ e.preventDefault());
+ break;
+ case 74:
+ ContentAwareScrollerJS.scroll(ContentAwareNavigationDirection.Down);
+ break;
+ case 75:
+ ContentAwareScrollerJS.scroll(ContentAwareNavigationDirection.Up);
+ break;
+ case 82:
+ t && ReaderJS.reloadArticlePreservingScrollPosition();
+ }
+}
+function getArticleScrollPosition() {
+ ((scrollInfo = {}), (scrollInfo.version = 1));
+ let e = document.getElementsByClassName("page"),
+ t = e.length;
+ if (!t) return ((scrollInfo.pageIndex = 0), scrollInfo);
+ scrollInfo.pageIndex = e.length - 1;
+ let n = window.scrollY;
+ for (let i = 0; i < t; i++) {
+ let t = e[i];
+ if (t.offsetTop + t.offsetHeight >= n) {
+ scrollInfo.pageIndex = i;
+ break;
+ }
+ }
+ return scrollInfo;
+}
+function restoreInitialArticleScrollPosition() {
+ let e =
+ document.getElementsByClassName("page")[initialScrollPosition.pageIndex];
+ e && (document.scrollingElement.scrollTop = e.offsetTop);
+}
+function restoreInitialArticleScrollPositionIfPossible() {
+ if (didRestoreInitialScrollPosition) return;
+ if (
+ !initialScrollPosition &&
+ ((initialScrollPosition =
+ ReaderJSController.initialArticleScrollPosition()),
+ !initialScrollPosition || !initialScrollPosition.pageIndex)
+ )
+ return void (didRestoreInitialScrollPosition = !0);
+ let e = document.getElementsByClassName("page-number").length;
+ initialScrollPosition.pageIndex >= e ||
+ (setTimeout(
+ restoreInitialArticleScrollPosition,
+ DelayBeforeRestoringScrollPositionInMs,
+ ),
+ (didRestoreInitialScrollPosition = !0));
+}
+function makeWideElementsScrollable() {
+ let e = document.querySelectorAll("table, pre");
+ for (let t of e) {
+ if (t.classList.contains("float")) continue;
+ if (t.parentElement.classList.contains("scrollable")) continue;
+ let e = document.createElement("div");
+ (t.parentElement.insertBefore(e, t),
+ t.remove(),
+ e.appendChild(t),
+ e.classList.add("scrollable"));
+ }
+}
+function fontSettings(e) {
+ function t(e) {
+ return e.replace(/\W/g, "").toLowerCase();
+ }
+ const n = [15, 16, 17, 18, 19, 20, 21, 23, 26, 28, 37, 46],
+ i = [
+ "25px",
+ "26px",
+ "27px",
+ "28px",
+ "29px",
+ "30px",
+ "31px",
+ "33px",
+ "37px",
+ "39px",
+ "51px",
+ "62px",
+ ];
+ let o = {
+ System: {
+ lineHeights: [
+ "25px",
+ "26px",
+ "27px",
+ "29px",
+ "30px",
+ "31px",
+ "32px",
+ "33px",
+ "38px",
+ "39px",
+ "51px",
+ "62px",
+ ],
+ usesSystemFont: !0,
+ },
+ Charter: {
+ lineHeights: [
+ "25px",
+ "26px",
+ "27px",
+ "28px",
+ "29px",
+ "30px",
+ "32px",
+ "34px",
+ "38px",
+ "39px",
+ "51px",
+ "62px",
+ ],
+ },
+ Georgia: {
+ lineHeights: [
+ "25px",
+ "26px",
+ "27px",
+ "28px",
+ "29px",
+ "30px",
+ "32px",
+ "34px",
+ "38px",
+ "41px",
+ "51px",
+ "62px",
+ ],
+ },
+ "Iowan Old Style": {
+ lineHeights: [
+ "25px",
+ "26px",
+ "27px",
+ "28px",
+ "29px",
+ "30px",
+ "32px",
+ "34px",
+ "38px",
+ "39px",
+ "51px",
+ "62px",
+ ],
+ },
+ Palatino: {
+ lineHeights: [
+ "25px",
+ "26px",
+ "27px",
+ "28px",
+ "29px",
+ "30px",
+ "31px",
+ "34px",
+ "37px",
+ "40px",
+ "51px",
+ "62px",
+ ],
+ },
+ Seravek: {
+ lineHeights: [
+ "25px",
+ "26px",
+ "27px",
+ "28px",
+ "28px",
+ "30px",
+ "31px",
+ "34px",
+ "37px",
+ "39px",
+ "51px",
+ "62px",
+ ],
+ },
+ "Hiragino Sans W3": {
+ lineHeights: [
+ "1.85em",
+ "1.78em",
+ "1.74em",
+ "1.71em",
+ "1.72em",
+ "1.73em",
+ "1.75em",
+ "1.76em",
+ "1.78em",
+ "1.9em",
+ "1.92em",
+ "2em",
+ ],
+ },
+ "Hiragino Kaku Gothic ProN": {
+ lineHeights: [
+ "1.85em",
+ "1.78em",
+ "1.74em",
+ "1.7em",
+ "1.69em",
+ "1.68em",
+ "1.69em",
+ "1.7em",
+ "1.74em",
+ "1.85em",
+ "1.9em",
+ "2em",
+ ],
+ },
+ "Hiragino Mincho ProN": {
+ lineHeights: [
+ "1.75em",
+ "1.72em",
+ "1.69em",
+ "1.66em",
+ "1.64em",
+ "1.56em",
+ "1.53em",
+ "1.56em",
+ "1.6em",
+ "1.65em",
+ "1.69em",
+ "1.72em",
+ ],
+ },
+ "Hiragino Maru Gothic ProN": {
+ lineHeights: [
+ "1.85em",
+ "1.78em",
+ "1.74em",
+ "1.7em",
+ "1.69em",
+ "1.68em",
+ "1.69em",
+ "1.7em",
+ "1.74em",
+ "1.85em",
+ "1.9em",
+ "2em",
+ ],
+ },
+ "PingFang SC": {
+ lineHeights: [
+ "1.85em",
+ "1.78em",
+ "1.74em",
+ "1.7em",
+ "1.69em",
+ "1.68em",
+ "1.69em",
+ "1.7em",
+ "1.74em",
+ "1.85em",
+ "1.9em",
+ "2em",
+ ],
+ usesSystemFont: !0,
+ },
+ "Heiti SC": {
+ lineHeights: [
+ "1.85em",
+ "1.78em",
+ "1.74em",
+ "1.7em",
+ "1.7em",
+ "1.71em",
+ "1.72em",
+ "1.75em",
+ "1.8em",
+ "1.9em",
+ "1.95em",
+ "2em",
+ ],
+ },
+ "Songti SC": {
+ lineHeights: [
+ "1.8em",
+ "1.78em",
+ "1.74em",
+ "1.72em",
+ "1.71em",
+ "1.72em",
+ "1.73em",
+ "1.75em",
+ "1.8em",
+ "1.9em",
+ "1.95em",
+ "1.96em",
+ ],
+ },
+ "Kaiti SC": {
+ lineHeights: [
+ "1.75em",
+ "1.72em",
+ "1.69em",
+ "1.66em",
+ "1.64em",
+ "1.56em",
+ "1.53em",
+ "1.56em",
+ "1.6em",
+ "1.65em",
+ "1.69em",
+ "1.72em",
+ ],
+ },
+ "Yuanti SC": {
+ lineHeights: [
+ "1.95em",
+ "1.93em",
+ "1.9em",
+ "1.87em",
+ "1.85em",
+ "1.8em",
+ "1.83em",
+ "1.85em",
+ "1.88em",
+ "1.9em",
+ "1.91em",
+ "1.92em",
+ ],
+ },
+ "Libian SC": {
+ fontSizes: [27, 28, 29, 30, 31, 32, 33, 35, 37, 40, 42, 46],
+ lineHeights: [
+ "1.65em",
+ "1.63em",
+ "1.62em",
+ "1.61em",
+ "1.6em",
+ "1.6em",
+ "1.61em",
+ "1.62em",
+ "1.63em",
+ "1.64em",
+ "1.64em",
+ "1.65em",
+ ],
+ },
+ "Weibei SC": {
+ fontSizes: [21, 22, 23, 24, 25, 26, 27, 29, 32, 34, 39, 43],
+ lineHeights: [
+ "1.65em",
+ "1.63em",
+ "1.62em",
+ "1.61em",
+ "1.6em",
+ "1.6em",
+ "1.61em",
+ "1.62em",
+ "1.63em",
+ "1.64em",
+ "1.64em",
+ "1.65em",
+ ],
+ },
+ "Yuppy SC": {
+ lineHeights: [
+ "1.75em",
+ "1.73em",
+ "1.7em",
+ "1.67em",
+ "1.65em",
+ "1.6em",
+ "1.63em",
+ "1.65em",
+ "1.68em",
+ "1.7em",
+ "1.71em",
+ "1.72em",
+ ],
+ },
+ "PingFang TC": {
+ lineHeights: [
+ "1.85em",
+ "1.78em",
+ "1.75em",
+ "1.72em",
+ "1.7em",
+ "1.7em",
+ "1.7em",
+ "1.72em",
+ "1.75em",
+ "1.82em",
+ "1.85em",
+ "1.9em",
+ ],
+ usesSystemFont: !0,
+ },
+ "Heiti TC": {
+ lineHeights: [
+ "1.85em",
+ "1.78em",
+ "1.75em",
+ "1.72em",
+ "1.71em",
+ "1.71em",
+ "1.72em",
+ "1.75em",
+ "1.78em",
+ "1.82em",
+ "1.86em",
+ "1.9em",
+ ],
+ },
+ "Songti TC": {
+ lineHeights: [
+ "1.8em",
+ "1.78em",
+ "1.74em",
+ "1.73em",
+ "1.72em",
+ "1.72em",
+ "1.73em",
+ "1.75em",
+ "1.8em",
+ "1.9em",
+ "1.95em",
+ "1.96em",
+ ],
+ },
+ "Kaiti TC": {
+ fontSizes: [20, 21, 22, 23, 24, 25, 26, 28, 31, 33, 38, 43],
+ lineHeights: [
+ "1.63em",
+ "1.62em",
+ "1.62em",
+ "1.6em",
+ "1.56em",
+ "1.53em",
+ "1.5em",
+ "1.53em",
+ "1.56em",
+ "1.6em",
+ "1.62em",
+ "1.63em",
+ ],
+ },
+ "Yuanti TC": {
+ lineHeights: [
+ "1.95em",
+ "1.93em",
+ "1.9em",
+ "1.87em",
+ "1.85em",
+ "1.8em",
+ "1.83em",
+ "1.85em",
+ "1.88em",
+ "1.9em",
+ "1.91em",
+ "1.92em",
+ ],
+ },
+ "Libian TC": {
+ fontSizes: [27, 28, 29, 30, 31, 32, 33, 35, 37, 40, 42, 46],
+ lineHeights: [
+ "1.65em",
+ "1.63em",
+ "1.62em",
+ "1.61em",
+ "1.6em",
+ "1.6em",
+ "1.61em",
+ "1.62em",
+ "1.63em",
+ "1.64em",
+ "1.64em",
+ "1.65em",
+ ],
+ },
+ "Weibei TC": {
+ fontSizes: [21, 22, 23, 24, 25, 26, 27, 29, 32, 34, 39, 43],
+ lineHeights: [
+ "1.65em",
+ "1.63em",
+ "1.62em",
+ "1.61em",
+ "1.6em",
+ "1.6em",
+ "1.61em",
+ "1.62em",
+ "1.63em",
+ "1.64em",
+ "1.64em",
+ "1.65em",
+ ],
+ },
+ "Yuppy TC": {
+ lineHeights: [
+ "1.75em",
+ "1.73em",
+ "1.7em",
+ "1.67em",
+ "1.65em",
+ "1.6em",
+ "1.63em",
+ "1.65em",
+ "1.68em",
+ "1.7em",
+ "1.71em",
+ "1.72em",
+ ],
+ },
+ "Noto Nastaliq Urdu": {
+ lineHeights: [
+ "2.6em",
+ "2.7em",
+ "2.8em",
+ "2.8em",
+ "2.8em",
+ "2.8em",
+ "2.8em",
+ "2.6em",
+ "2.5em",
+ "2.5em",
+ "2.5em",
+ "2.6em",
+ ],
+ },
+ }[e];
+ return (
+ o || (o = {}),
+ (o.cssClassName = t(e)),
+ o.usesSystemFont || (o.fontFamilyName = e),
+ o.fontSizes || (o.fontSizes = n),
+ o.lineHeights || (o.lineHeights = i),
+ o
+ );
+}
+function prepareTweetsInPrintingMailingFrame(e) {
+ let t = e.querySelectorAll(".tweet-wrapper");
+ for (let e of t) {
+ let t = e.querySelector("iframe");
+ t && t.remove();
+ let n = e.querySelector(".simple-tweet");
+ n && n.classList.remove("hidden");
+ }
+}
+function urlFromString(e) {
+ try {
+ return new URL(e);
+ } catch (e) {
+ return null;
+ }
+}
+function stopExtendingElementBeyondTextColumn(e) {
+ (e.classList.remove("extendsBeyondTextColumn"),
+ e.style &&
+ (e.style.removeProperty("width"),
+ e.style.removeProperty("-webkit-margin-start")));
+}
+function leadingMarginAndPaddingAppliedToElementFromAncestors(e) {
+ let t = 0,
+ n = e.parentElement;
+ for (; n && !n.classList.contains("page");) {
+ let e = getComputedStyle(n);
+ ((t +=
+ parseFloat(e["-webkit-padding-start"]) +
+ parseFloat(e["-webkit-margin-start"])),
+ (n = n.parentElement));
+ }
+ return t;
+}
+function extendElementBeyondTextColumn(e, t, n) {
+ (e.classList.add("extendsBeyondTextColumn"),
+ e.style &&
+ (e.style.setProperty("width", t + "px"),
+ e.style.setProperty(
+ "-webkit-margin-start",
+ (n - t) / 2 -
+ leadingMarginAndPaddingAppliedToElementFromAncestors(e) +
+ "px",
+ )));
+}
+function removeAllZeroWidthSpace() {
+ document.querySelectorAll("*").forEach((e) => {
+ e.childNodes.forEach((e) => {
+ e.nodeType === Node.TEXT_NODE &&
+ (e.textContent = e.textContent.replace(/\u200B/g, ""));
+ });
+ });
+}
+function markWithZeroWidthSpaceDelimiterIfNeeded(e) {
+ if (!e) return;
+ let t = "\u200b",
+ n = document.createElement("p");
+ ((n.innerText = t),
+ (n.style.height = "0px"),
+ (n.style.width = "0px"),
+ (n.style.margin = "0px"));
+ let i = document.createElement("p");
+ ((i.innerText = t),
+ (i.style.height = "0px"),
+ (i.style.width = "0px"),
+ (i.style.margin = "0px"));
+ let o = e.firstChild,
+ r = e.lastChild;
+ (o && "\u200b" != o.innerText && e.insertBefore(n, o),
+ r && "\u200b" != r.innerText && e.appendChild(i));
+}
+function containsAssistantContent() {
+ return ReaderController.hasAssistantContent;
+}
+function shouldShowAssistantSidebar() {
+ let e = window.innerWidth,
+ t = e - document.getElementById("article").offsetWidth,
+ n = document.getElementById("assistant-container").offsetWidth;
+ return ReaderJS._canShowAssistantSidebar() && e > 1e3 && t > n + 100;
+}
+function layoutAssistantContent() {
+ let e = document.getElementById("sidebarButton"),
+ t = document.getElementById("assistant-container"),
+ n = window.innerWidth,
+ i = document.getElementById("article"),
+ o = document.getElementById("summary-collapsible"),
+ r = document.getElementById("summary-collapsedContent"),
+ a = document.getElementById("tableOfContentsInsideArticleHeader"),
+ l = document.getElementById("tableOfContentsInsideArticle-list"),
+ s = document.getElementById("tableOfContents-container"),
+ d = document.getElementById("summary-container"),
+ c = document.getElementById("innerAssistantContainer"),
+ m = null != o,
+ u = null != l,
+ g = document.getElementById("onDeviceSummaryButton"),
+ h = null != g && null != g,
+ p = ReaderController.isShowingOnDeviceSummary;
+ if (
+ ((t.style.display = "inline-block"),
+ (t.style.height = "100%"),
+ (t.style.padding = "50 px"),
+ (t.style.minWidth = "300px"),
+ (t.style.overflowY = "auto"),
+ (t.style.overflowX = "hidden"),
+ (t.style.position = "fixed"),
+ (t.style.zIndex = "1"),
+ (i.style.zIndex = "2"),
+ h && m && "none" != g.style.display && (g.style.display = "none"),
+ markWithZeroWidthSpaceDelimiterIfNeeded(t),
+ markWithZeroWidthSpaceDelimiterIfNeeded(c),
+ shouldShowAssistantSidebar() && (u || (m && !p)))
+ ) {
+ if (
+ ((e.style.display = "block"),
+ (e.style.right = "0px"),
+ (e.style.top = "0px"),
+ (e.style.zIndex = "3"),
+ (e.style.position = "fixed"),
+ (e.style.display = "block"),
+ (e.style.paddingInlineStart = "1.25em"),
+ (e.style.paddingInlineEnd = "1em"),
+ m && !p && ((o.style.display = "none"), (r.style.display = "none")),
+ u && ((l.style.display = "none"), (a.style.display = "none")),
+ (c.style.display = "none"),
+ "true" === e.getAttribute("data-isHidingSidebar"))
+ )
+ return (
+ (t.style.right = "-400px"),
+ void (i.style.left = (n - i.offsetWidth) / 2 + "px")
+ );
+ ((i.style.position = "absolute"),
+ (i.style.left = (n - t.offsetWidth - i.offsetWidth) / 2 + "px"),
+ (t.style.right = "0px"),
+ (t.style.display = "inline-block"),
+ m && !p && (d.style.display = "block"),
+ u && (s.style.display = "block"),
+ m && !p
+ ? (d.style.paddingTop = "0.75em")
+ : u && (s.style.paddingTop = "0.75em"));
+ } else {
+ if (
+ (e && (e.style.display = "none"),
+ (i.style.position = "static"),
+ (i.style.left = (n - i.offsetWidth) / 2 + "px"),
+ (t.style.display = "none"),
+ c && (c.style.display = "block"),
+ m)
+ ) {
+ if (
+ ((o.style.display = "block"),
+ (r.style.display = "block"),
+ ReaderController.summaryNeedsLayout)
+ ) {
+ let e = document.getElementById("summary-collapsible");
+ (e.classList.contains("alwaysExpanded") ||
+ e.classList.toggle("expandedContent"),
+ (r.style.maxHeight = r.scrollHeight + "px"),
+ (r.style.paddingBottom = "1.125em"),
+ (ReaderController.summaryNeedsLayout = !1));
+ }
+ r.style.maxHeight && (r.style.maxHeight = r.scrollHeight + "px");
+ }
+ (u &&
+ ((a.style.display = "block"),
+ (l.style.display = "block"),
+ l.style.maxHeight && (l.style.maxHeight = l.scrollHeight + "px")),
+ (s.style.display = "none"),
+ (d.style.display = "none"));
+ }
+}
+function monitorMouseDownForPotentialDeactivation(e) {
+ lastMouseDownWasOutsideOfPaper =
+ e &&
+ ReaderAppearanceJS.usesPaperAppearance() &&
+ !document.getElementById("article").contains(e.target) &&
+ !document.getElementById("assistant-container").contains(e.target);
+}
+function deactivateIfEventIsOutsideOfPaperContainer(e) {
+ let t = !1,
+ n = document.getElementById("sidebarButton");
+ (n && (t = n.contains(e.target)),
+ lastMouseDownWasOutsideOfPaper &&
+ e &&
+ ReaderAppearanceJS.usesPaperAppearance() &&
+ !document.getElementById("article").contains(e.target) &&
+ !document.getElementById("assistant-container").contains(e.target) &&
+ !t &&
+ ReaderJSController.requestDeactivationFromUserAction());
+}
+function makePromiseCancellable(e) {
+ const t = Promise.withResolvers();
+ return {
+ promise: Promise.race([t.promise, e]),
+ cancel: function () {
+ t.reject(new Error("Cancelled"));
+ },
+ };
+}
+function updatePageNumbers() {
+ let e = document.getElementsByClassName("page-number"),
+ t = e.length,
+ n = ReaderJS.isLoadingNextPage();
+ for (let i = 0; i < t; ++i)
+ e[i].textContent = n
+ ? getLocalizedString("Page %@").format(i + 1)
+ : getLocalizedString("Page %@ of %@").format(i + 1, t);
+}
+function incomingPagePlaceholder() {
+ return document.getElementById("incoming-page-placeholder");
+}
+function addIncomingPagePlaceholder(e) {
+ let t = document.createElement("div");
+ ((t.className = "page"), (t.id = "incoming-page-placeholder"));
+ let n = document.createElement("div");
+ n.id = "incoming-page-corner";
+ let i = document.createElement("div");
+ ((i.id = "incoming-page-text"),
+ (i.innerText = getLocalizedString(
+ e
+ ? "Loading Next Page\u2026"
+ : "Connect to the internet to view remaining pages.",
+ )),
+ n.appendChild(i),
+ t.appendChild(n),
+ document.getElementById("article").appendChild(t));
+}
+function removeIncomingPagePlaceholder() {
+ let e = incomingPagePlaceholder();
+ e.parentNode.removeChild(e);
+}
+function nextPageContainer() {
+ return document.getElementById("next-page-container");
+}
+function getLocalizedString(e) {
+ let t = localizedStrings[e];
+ return t || e;
+}
+function nextPageLoadComplete(e) {
+ if (
+ (isReaderViewInSeparateProcess ||
+ nextPageContainer().removeEventListener("load", nextPageLoadComplete, !1),
+ ReaderJS.pageNumber++,
+ ReaderJS.readerOperationMode == ReaderOperationMode.OffscreenFetching)
+ ) {
+ let e = ReaderJS.pageURLs[ReaderJS.pageURLs.length - 1];
+ ReaderJSController.nextPageLoadComplete(
+ ReaderJS.pageNumber,
+ e,
+ "next-page-container",
+ );
+ }
+ let t;
+ isReaderViewInSeparateProcess
+ ? (t = new Article(e))
+ : (ReaderJSController.prepareNextPageFrame("next-page-container"),
+ (t = ReaderJSController.nextPageArticleFinder()),
+ (t.pageNumber = ReaderJS.pageNumber),
+ (t.suggestedRouteToArticle = ReaderJS.routeToArticle),
+ (t.previouslyDiscoveredPageURLStrings = ReaderJS.pageURLs));
+ let n = t.adoptableArticle();
+ (n &&
+ (ReaderJS.createPageFromNode(n),
+ (ReaderJS.routeToArticle = t.routeToArticleNode())),
+ isReaderViewInSeparateProcess
+ ? (fetchNextPageArticlePromiseWithCanceller = null)
+ : (nextPageContainer().removeAttribute("src"),
+ ReaderJSController.clearNextPageArticleFinder()),
+ ReaderJS.canLoadNextPage()
+ ? ReaderJS.setNextPageURL(t.nextPageURL())
+ : ReaderJS.setCachedNextPageURL(t.nextPageURL()),
+ updatePageNumbers(),
+ restoreInitialArticleScrollPositionIfPossible(),
+ ReaderJS.isLoadingNextPage() || ReaderJS.doneLoadingAllPages());
+}
+function firstContentElementAfterTopOfViewport() {
+ let e,
+ t = Number.MAX_VALUE;
+ const n = window.innerWidth / 2;
+ for (let i = 0; i <= 10; ++i) {
+ const o = document
+ .elementFromPoint(n, 4 * i)
+ .closest("[data-reader-unique-id]");
+ if (!o) continue;
+ const r = o.offsetHeight;
+ r < t && ((e = o), (t = r));
+ }
+ if (e) return e;
+ let i = articleTitleElement();
+ if (!i) return null;
+ do {
+ if (i.getBoundingClientRect().bottom >= 0) return i;
+ } while ((i = nextReaderContentElement(i)));
+ return null;
+}
+function setConfiguration(e) {
+ ReaderAppearanceJS.applyConfiguration(e);
+}
+function setReaderIsActive(e) {
+ ReaderJS.setReaderIsActive(e);
+}
+function setArticleLocale(e) {
+ ((document.getElementById("article").style.webkitLocale = `'${e}'`),
+ ReaderAppearanceJS.applyConfiguration(ReaderAppearanceJS.configuration));
+}
+function cleanUpTableOfContents(e, t, n, i) {
+ if (0 == e) return null;
+ t.length;
+ for (var o = t.length - 1; o >= 0; --o) {
+ if (1 == e) {
+ const e =
+ decodeURIComponent(t[o]).replace(/[.*+?^${}()|[\]\\]/g, "\\$&") +
+ "\\s*" +
+ decodeURIComponent(i[o]).replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
+ if (new RegExp(e).test(document.body.textContent)) continue;
+ }
+ (2 == e && document.body.textContent.includes(decodeURIComponent(i[o]))) ||
+ (t.splice(o, 1), i.splice(o, 1), n.splice(o, 1));
+ }
+ return t.length < 2 ? null : [t, n, i];
+}
+function setTableOfContentsWith(e, t, n, i, o, r) {
+ const a = cleanUpTableOfContents(r, n, i, o);
+ if (!a) return;
+ [n, i, o] = a;
+ let l = document.createElement("button");
+ ((l.id = "tableOfContentsInsideArticleHeader"),
+ l.classList.toggle("collapsible"),
+ l.classList.toggle("vision", isPlatformVision),
+ l.classList.toggle("eligible-for-border-corner", isPlatformVision));
+ articleTitleContainer();
+ document.getElementById("innerAssistantContainer").appendChild(l);
+ let s =
+ '',
+ d = document.createElement("ol");
+ ((d.id = "tableOfContentsInsideArticle-list"),
+ d.classList.toggle("collapsedContent"),
+ (l.innerHTML = s + " " + e),
+ l.parentNode.insertBefore(d, l.nextSibling),
+ (d.style.display = "none"),
+ isPlatformVision && (l.style.backgroundColor = "#00000001"));
+ let c = 1.4 + 0.45 * Math.floor(Math.log10(n.length)) + "em";
+ for (var m = 0; m < n.length; ++m) {
+ let e = document.createElement("li");
+ (e.classList.toggle("innerTableOfContents-listItem"),
+ (e.id = "item" + n[m]),
+ e.setAttribute("toc-item-index", m),
+ e.addEventListener("click", function () {
+ ReaderJSController.reportReaderEvent(
+ ReaderEventType.ClickOnTableOfContentsLink,
+ {
+ index: parseInt(e.getAttribute("toc-item-index")),
+ length: n.length,
+ },
+ );
+ }));
+ var u = document.createElement("a");
+ (1 == r
+ ? (u.href = t + "#:~:text=" + n[m] + ",-" + o[m])
+ : 2 == r && (u.href = t + "#:~:text=" + o[m]),
+ (u.textContent = decodeURIComponent(n[m])),
+ (e.style.marginInlineStart = c),
+ e.appendChild(u),
+ document
+ .getElementById("tableOfContentsInsideArticle-list")
+ .appendChild(e));
+ }
+ (l.addEventListener("click", function () {
+ const e = l.classList.toggle("expandedContent");
+ (d.style.maxHeight
+ ? ((d.style.maxHeight = null),
+ (d.style.marginBottom = "0px"),
+ d.classList.toggle("eligible-for-border-corner", !1),
+ isPlatformVision &&
+ setTimeout(() => {
+ ((d.style.borderTop = null), (d.style.paddingTop = null));
+ }, 200))
+ : ((d.style.maxHeight = d.scrollHeight + "px"),
+ (d.style.marginBottom = "0.75em"),
+ d.classList.toggle("eligible-for-border-corner", isPlatformVision),
+ isPlatformVision &&
+ ((d.style.borderTop = "0.1em solid var(--separator-color)"),
+ (d.style.paddingTop = "1em"))),
+ ReaderJSController.reportReaderEvent(
+ ReaderEventType.ClickOnTableOfContentsHeader,
+ { expanded: e },
+ ));
+ }),
+ (tableOfContentslistItemMarginLeft =
+ 1.4 + 0.45 * Math.floor(Math.log10(n.length)) + "em"),
+ (document.getElementById("tableOfContents-header").innerHTML =
+ s + " " + e));
+ for (m = 0; m < n.length; ++m) {
+ let e = document.createElement("li");
+ e.id = "ToCItem" + n[m];
+ var g = document.createElement("a");
+ (1 == r
+ ? (g.href = t + "#:~:text=" + n[m] + ",-" + o[m])
+ : 2 == r && (g.href = t + "#:~:text=" + o[m]),
+ (g.textContent = decodeURIComponent(n[m])),
+ (e.style.marginInlineStart = tableOfContentslistItemMarginLeft),
+ e.appendChild(g),
+ e.setAttribute("toc-item-index", m),
+ e.addEventListener("click", function () {
+ ReaderJSController.reportReaderEvent(
+ ReaderEventType.ClickOnTableOfContentsLink,
+ {
+ index: parseInt(e.getAttribute("toc-item-index")),
+ length: n.length,
+ },
+ );
+ }),
+ document.getElementById("tableOfContents-list").appendChild(e));
+ }
+ ReaderJSController.reportReaderEvent(ReaderEventType.SetTableOfContents, {
+ length: n.length,
+ });
+}
+function summarizeGlyphString() {
+ return usesTwoLineSummaryGlyph
+ ? ''
+ : '';
+}
+function thumbsUpGlyphString() {
+ return '';
+}
+function thumbsDownGlyphString() {
+ return '';
+}
+function reportConcernGlyphString() {
+ return '';
+}
+function createSummaryFeedbackButton(e, t, n) {
+ let i = document.createElement("button");
+ return (
+ i.classList.add("summary-feedback-button"),
+ i.setAttribute("aria-label", n),
+ (i.title = n),
+ (i.innerHTML = t),
+ i.addEventListener("click", function (t) {
+ (t.preventDefault(),
+ t.stopPropagation(),
+ ReaderJSController.reportSummaryFeedback(e));
+ }),
+ i
+ );
+}
+function createSummaryFeedbackButtonGroup() {
+ let e = document.createElement("div");
+ return (
+ (e.id = "summary-feedback-buttons"),
+ e.classList.add("summary-feedback-buttons"),
+ "internal" === summaryFeedbackButtonMode
+ ? (e.appendChild(
+ createSummaryFeedbackButton(
+ SummaryFeedbackActionType.ThumbsUp,
+ thumbsUpGlyphString(),
+ getLocalizedString("Looks Good"),
+ ),
+ ),
+ e.appendChild(
+ createSummaryFeedbackButton(
+ SummaryFeedbackActionType.ThumbsDown,
+ thumbsDownGlyphString(),
+ getLocalizedString("Something Isn\u2019t Right"),
+ ),
+ ))
+ : "external" === summaryFeedbackButtonMode &&
+ e.appendChild(
+ createSummaryFeedbackButton(
+ SummaryFeedbackActionType.Concern,
+ reportConcernGlyphString(),
+ getLocalizedString("Report a Concern"),
+ ),
+ ),
+ e
+ );
+}
+function upgradeSummaryButtonForFeedbackIfNeeded(e, t) {
+ if ("none" === summaryFeedbackButtonMode) return e;
+ if (!ReaderController.isShowingOnDeviceSummary) return e;
+ if (!e || e.classList.contains("alwaysExpanded")) return e;
+ let n = document.createElement("div");
+ for (let t of Array.from(e.attributes)) n.setAttribute(t.name, t.value);
+ (n.classList.add("alwaysExpanded"), n.classList.add("expandedContent"));
+ let i = document.createElement("span");
+ return (
+ (i.id = "summary-header-label"),
+ (i.innerHTML = e.innerHTML),
+ n.appendChild(i),
+ n.appendChild(createSummaryFeedbackButtonGroup()),
+ e.parentNode.replaceChild(n, e),
+ t &&
+ ((t.style.maxHeight = "none"),
+ (t.style.marginBottom = "12px"),
+ (t.style.overflow = "visible"),
+ t.classList.toggle("eligible-for-border-corner", isPlatformVision)),
+ n
+ );
+}
+function appendSummaryTextWithSettingsLink(e, t) {
+ let n = t.indexOf(SummarySettingsLinkStartSentinel),
+ i = t.indexOf(SummarySettingsLinkEndSentinel);
+ if (-1 === n || -1 === i || i < n) return void (e.innerText = t);
+ let o = t.substring(0, n),
+ r = t.substring(n + SummarySettingsLinkStartSentinel.length, i),
+ a = t.substring(i + SummarySettingsLinkEndSentinel.length);
+ ((e.textContent = ""), o.length && e.appendChild(document.createTextNode(o)));
+ let l = document.createElement("a");
+ ((l.className = "summary-settings-link"),
+ (l.textContent = r),
+ l.setAttribute("href", "#"),
+ l.setAttribute("role", "button"),
+ (l.style.color = "#007AFF"),
+ (l.style.textDecoration = "none"),
+ (l.style.cursor = "pointer"),
+ l.addEventListener("click", function (e) {
+ (e.preventDefault(),
+ "function" == typeof ReaderJSController.openSummarizationSettings &&
+ ReaderJSController.openSummarizationSettings());
+ }),
+ e.appendChild(l),
+ a.length && e.appendChild(document.createTextNode(a)));
+}
+function setSummaryTextWith(e, t, n, i) {
+ let o = summarizeGlyphString(),
+ r = document.getElementById("innerAssistantContainer"),
+ a = document.getElementById("summary-collapsible"),
+ l = document.getElementById("summary-collapsible-text-id-1");
+ (l ||
+ ((l = document.createElement("p")),
+ (l.id = "summary-collapsible-text-id-1"),
+ l.classList.toggle("vision", isPlatformVision)),
+ n
+ ? ((l.style.opacity = "0.5"),
+ (l.style.visibility = "hidden"),
+ l.classList.add("system"))
+ : l.classList.remove("system"),
+ appendSummaryTextWithSettingsLink(l, e));
+ var s = "clock" === i,
+ d = "shield" === i,
+ c = s || d || "localized-error" === i;
+ if (s || d) {
+ document.createElement("attributionIcon");
+ let e = s
+ ? ''
+ : '';
+ l.innerHTML = e + l.innerHTML;
+ }
+ if (
+ ((l.style.textAlign = c ? "initial" : "inherit"),
+ (l.tabIndex = -1),
+ (l.style.outline = "none"),
+ setTimeout(() => {
+ l.focus();
+ }, 0),
+ !a)
+ ) {
+ ((a = document.createElement("button")),
+ a.classList.toggle("collapsible"),
+ a.classList.toggle("vision", isPlatformVision),
+ a.classList.toggle("eligible-for-border-corner", isPlatformVision),
+ (a.id = "summary-collapsible"),
+ (a.innerHTML = o + " " + t),
+ isPlatformVision && (a.style.backgroundColor = "#00000001"),
+ r.appendChild(a));
+ let e = document.createElement("div");
+ ((e.id = "summary-collapsedContent"),
+ e.appendChild(l),
+ e.classList.toggle("collapsedContent"),
+ e.classList.toggle("vision", isPlatformVision),
+ r.appendChild(e),
+ a.parentNode.insertBefore(e, a.nextSibling),
+ a.addEventListener("click", function (t) {
+ if (a.classList.contains("alwaysExpanded"))
+ return void t.preventDefault();
+ const n = a.classList.toggle("expandedContent");
+ ((e.style.overflow = "auto"),
+ e.style.maxHeight
+ ? ((e.style.maxHeight = null),
+ (e.style.marginBottom = "0px"),
+ e.classList.toggle("eligible-for-border-corner", !1))
+ : ((e.style.maxHeight = e.scrollHeight + "px"),
+ (e.style.marginBottom = "12px"),
+ e.classList.toggle(
+ "eligible-for-border-corner",
+ isPlatformVision,
+ )),
+ t.preventDefault(),
+ ReaderJSController.reportReaderEvent(
+ ReaderEventType.ClickOnSummaryHeader,
+ { expanded: n },
+ ));
+ }));
+ }
+ if (!c && !n && e && e.trim().length > 0)
+ upgradeSummaryButtonForFeedbackIfNeeded(
+ a,
+ document.getElementById("summary-collapsedContent"),
+ );
+ else {
+ let e = document.getElementById("summary-feedback-buttons");
+ e && e.remove();
+ }
+ let m = document.getElementById("summary-collapsedContent");
+ m && m.appendChild(l);
+ let u = document.getElementById("summary-attribution");
+ (u ||
+ !i ||
+ c ||
+ ((u = document.createElement("div")),
+ (u.id = "summary-attribution"),
+ (u.innerHTML = `${i}`),
+ m.appendChild(u)),
+ appendSummaryTextWithSettingsLink(
+ document.getElementById("sidebar-summary-text-id-1"),
+ e,
+ ),
+ (document.getElementById("summary-header").innerHTML = o + " " + t));
+}
+function updateSummaryTextVisibility(e) {
+ document.getElementById("summary-collapsible-text-id-1").style.visibility = e
+ ? "visible"
+ : "hidden";
+}
+function insertSummaryTextPlaceholder() {
+ const e =
+ (document.getElementById("summary-collapsible-text-id-1").clientWidth *
+ 2.5) /
+ 9;
+ (setSummaryTextWith(
+ "\udbc2\udfb7".repeat(e),
+ getLocalizedString("Summary"),
+ !0,
+ ),
+ layoutAssistantContent());
+}
+function setArticleSummary(e, t, n, i, o, r, a, l, s) {
+ let d = null != e && e.length > 0,
+ c = null != o && o.length > 0;
+ if (!d && !c) return;
+ removeAllZeroWidthSpace();
+ let m = document.getElementById("innerAssistantContainer");
+ m ||
+ ((m = document.createElement("div")),
+ (m.id = "innerAssistantContainer"),
+ (m.style.display = "none"));
+ let u = articleTitleContainer();
+ u.parentNode.insertBefore(m, u.nextSibling);
+ let g = document.getElementById("article");
+ ((g.style.left = (window.innerWidth - g.offsetWidth) / 2 + "px"),
+ (ReaderController.hasAssistantContent = !0));
+ let h = document.getElementById("summary-collapsible-text-id-1");
+ d &&
+ (h && (h.style.opacity = "1"),
+ setSummaryTextWith(e, t, !1, s),
+ "true" != m.getAttribute("showedSummary") &&
+ (ReaderJSController.reportReaderEvent(ReaderEventType.SetSummary, {}),
+ m.setAttribute("showedSummary", !0)));
+ let p = document.getElementById("tableOfContentsInsideArticle-list"),
+ f = document.getElementById("tableOfContents-list"),
+ C = f && f.children.length;
+ (!c || p || C || setTableOfContentsWith(n, i, o, r, a, l),
+ document.getElementById("sidebarButton") || setSidebarButton(),
+ layoutAssistantContent());
+}
+function updateArticleLayout() {
+ ReaderAppearanceJS.layOutElements();
+}
+function setSidebarButton() {
+ let e = document.getElementById("assistant-container"),
+ t = document.createElementNS("http://www.w3.org/2000/svg", "svg");
+ (t.setAttribute("width", "1.5em"),
+ t.setAttribute("height", "1.5em"),
+ t.setAttribute("viewbox", "0 0 24 24"),
+ t.setAttribute("fill", "#000000"),
+ t.setAttribute("xmlns", "http://www.w3.org/2000/svg"));
+ let n = document.createElementNS("http://www.w3.org/2000/svg", "path");
+ (n.setAttribute(
+ "d",
+ "M3.06641 17.998L19.9609 17.998C22.0117 17.998 23.0273 16.9824 23.0273 14.9707L23.0273 3.04688C23.0273 1.03516 22.0117 0.0195312 19.9609 0.0195312L3.06641 0.0195312C1.02539 0.0195312 0 1.02539 0 3.04688L0 14.9707C0 16.9922 1.02539 17.998 3.06641 17.998ZM3.08594 16.4258C2.10938 16.4258 1.57227 15.9082 1.57227 14.8926L1.57227 3.125C1.57227 2.10938 2.10938 1.5918 3.08594 1.5918L19.9414 1.5918C20.9082 1.5918 21.4551 2.10938 21.4551 3.125L21.4551 14.8926C21.4551 15.9082 20.9082 16.4258 19.9414 16.4258ZM14.082 16.7285L15.6152 16.7285L15.6152 1.29883L14.082 1.29883ZM17.4902 5.21484L19.5801 5.21484C19.8828 5.21484 20.1367 4.95117 20.1367 4.66797C20.1367 4.375 19.8828 4.12109 19.5801 4.12109L17.4902 4.12109C17.1973 4.12109 16.9336 4.375 16.9336 4.66797C16.9336 4.95117 17.1973 5.21484 17.4902 5.21484ZM17.4902 7.74414L19.5801 7.74414C19.8828 7.74414 20.1367 7.48047 20.1367 7.1875C20.1367 6.89453 19.8828 6.65039 19.5801 6.65039L17.4902 6.65039C17.1973 6.65039 16.9336 6.89453 16.9336 7.1875C16.9336 7.48047 17.1973 7.74414 17.4902 7.74414ZM17.4902 10.2637L19.5801 10.2637C19.8828 10.2637 20.1367 10.0195 20.1367 9.72656C20.1367 9.43359 19.8828 9.17969 19.5801 9.17969L17.4902 9.17969C17.1973 9.17969 16.9336 9.43359 16.9336 9.72656C16.9336 10.0195 17.1973 10.2637 17.4902 10.2637Z",
+ ),
+ n.setAttribute("fill", "var(--body-font-color)"),
+ t.appendChild(n));
+ let i = t;
+ (isPlatformVision &&
+ (t.setAttribute("width", "24px"),
+ t.setAttribute("height", "24px"),
+ (i = document.createElement("button")),
+ (i.style.borderStyle = "none"),
+ (i.style.borderRadius = "8px"),
+ (i.style.backgroundColor = "#00000001"),
+ (i.style.paddingTop = "0.8em"),
+ i.appendChild(t)),
+ (i.id = "sidebarButton"),
+ i.setAttribute("data-isHidingSidebar", "false"),
+ i.addEventListener("click", function () {
+ let e = "true" === i.getAttribute("data-isHidingSidebar");
+ (i.setAttribute("data-isHidingSidebar", (!e).toString()),
+ ReaderJSController.reportReaderEvent(
+ ReaderEventType.ClickOnSideBarButton,
+ { expanded: e },
+ ),
+ layoutAssistantContent());
+ }),
+ e.parentNode.appendChild(i));
+}
+function resetToSummarizeButton() {
+ let e = document.getElementById("onDeviceSummaryButton"),
+ t = document.getElementById("summary-collapsible"),
+ n = document.getElementById("summary-collapsedContent");
+ (n.parentNode.removeChild(n),
+ t && t.parentNode.removeChild(t),
+ e && (e.classList.remove("hiddenButton"), (e.style.display = "block")));
+ let i = document.getElementById("innerAssistantContainer");
+ i && i.remove();
+}
+function setOnDeviceSummaryButtonWithTitle(e) {
+ let t = document.getElementById("summary-collapsible"),
+ n = document.getElementById("summary-collapsible-text-id-1"),
+ i = n && n.innerText.includes("\udbc2\udfb7"),
+ o = n && n.innerText.length;
+ if (t && o && !i) return;
+ let r = document.getElementById("onDeviceSummaryButton");
+ if (i || (!o && t)) return void resetToSummarizeButton();
+ if (null != r && null != r)
+ return (
+ r.classList.remove("hiddenButton"),
+ void (r.style.display = "block")
+ );
+ ((r = document.createElement("button")),
+ removeAllZeroWidthSpace(),
+ (r.id = "onDeviceSummaryButton"));
+ let a = summarizeGlyphString();
+ r.innerHTML = a + " " + e;
+ let l = articleTitleContainer();
+ l.parentNode.insertBefore(r, l.nextSibling);
+ let s = "\u200b",
+ d = document.createElement("p");
+ ((d.innerText = s),
+ (d.style.height = "0px"),
+ (d.style.width = "0px"),
+ (d.style.margin = "0px"));
+ let c = document.createElement("p");
+ ((c.innerText = s),
+ (c.style.height = "0px"),
+ (c.style.width = "0px"),
+ (c.style.margin = "0px"),
+ r.parentNode.insertBefore(d, r),
+ r.parentNode.insertBefore(c, r.nextSibling),
+ r.addEventListener("click", function (e) {
+ (r.classList.add("hiddenButton"),
+ showOnDeviceSummaryPlaceholderWithTitle(),
+ setSummaryTextWith(" ", getLocalizedString("Summary")),
+ layoutAssistantContent(),
+ ReaderJSController.requestOnDeviceSummary(),
+ e.preventDefault());
+ }));
+}
+function isSummaryShownInSidebar() {
+ let e = document.getElementById("summary-collapsible"),
+ t = null != e;
+ return (
+ shouldShowAssistantSidebar() &&
+ t &&
+ !ReaderController.isShowingOnDeviceSummary
+ );
+}
+function beginReaderSummarization() {
+ if (isSummaryShownInSidebar()) return;
+ let e = document.getElementById("summary-collapsible"),
+ t = document.getElementById("summary-collapsedContent");
+ (t && t.parentNode.removeChild(t), e && e.parentNode.removeChild(e));
+ let n = document.getElementById("onDeviceSummaryButton");
+ (n && n.classList.add("hiddenButton"),
+ showOnDeviceSummaryPlaceholderWithTitle(),
+ setSummaryTextWith(" ", getLocalizedString("Summary")),
+ layoutAssistantContent(),
+ ReaderJSController.requestOnDeviceSummary());
+}
+function scrollToSummary() {
+ if (isSummaryShownInSidebar()) return;
+ let e = document.getElementById("summary-collapsible");
+ e && e.scrollIntoView({ behavior: "smooth", block: "start" });
+}
+function showOnDeviceSummaryPlaceholderWithTitle() {
+ if (document.getElementById("first-placeholder-line"))
+ return void resetToSummarizeButton();
+ let e = document.createElement("button");
+ (e.classList.toggle("collapsible"),
+ e.classList.toggle("vision", isPlatformVision),
+ e.classList.toggle("eligible-for-border-corner", isPlatformVision),
+ (e.id = "summary-collapsible"));
+ let t = summarizeGlyphString();
+ ((e.innerHTML = t + " \u200b" + getLocalizedString("Summary") + "\u200b"),
+ isPlatformVision && (e.style.backgroundColor = "#00000001"));
+ let n = document.createElement("div");
+ (n.classList.toggle("shimmer-container"),
+ (n.id = "summary-collapsedContent"),
+ n.classList.toggle("collapsedContent"),
+ n.classList.toggle("vision", isPlatformVision),
+ n.classList.toggle("eligible-for-border-corner", isPlatformVision),
+ (n.style.overflow = "visible"));
+ let i = document.getElementById("innerAssistantContainer");
+ if (!i) {
+ ((i = document.createElement("div")),
+ (i.id = "innerAssistantContainer"),
+ (i.style.display = "none"));
+ let e = articleTitleContainer();
+ e.parentNode.insertBefore(i, e.nextSibling);
+ }
+ (i.insertBefore(e, i.firstChild),
+ i.insertBefore(n, e.nextSibling),
+ (i.style.display = "block"),
+ (i.style.opacity = "0"),
+ i.offsetWidth,
+ i.offsetHeight,
+ (i.style.opacity = "1"),
+ (ReaderController.isShowingOnDeviceSummary = !0),
+ e.addEventListener("click", function () {
+ if (e.classList.contains("alwaysExpanded")) return;
+ const t = e.classList.toggle("expandedContent");
+ ((n.style.overflow = "auto"),
+ n.style.maxHeight
+ ? ((n.style.maxHeight = null),
+ (n.style.marginBottom = "0px"),
+ n.classList.toggle("eligible-for-border-corner", !1))
+ : ((n.style.maxHeight = n.scrollHeight + "px"),
+ (n.style.marginBottom = "0.75em"),
+ n.classList.toggle("eligible-for-border-corner", isPlatformVision)),
+ ReaderJSController.reportReaderEvent(
+ ReaderEventType.ClickOnSummaryHeader,
+ { expanded: t },
+ ));
+ }),
+ e.classList.toggle("expandedContent"),
+ (n.style.maxHeight = n.scrollHeight + "px"),
+ (n.style.marginBottom = "0.75em"));
+}
+function handleVisibilityChange() {
+ ReaderJS.setDocumentIsVisible(!document.hidden);
+}
+const LoadNextPageDelay = 250,
+ MaxNumberOfNextPagesToLoad = 80,
+ ReaderOperationMode = { Normal: 0, OffscreenFetching: 1, ArchiveViewing: 2 },
+ ReaderEventType = {
+ SetSummary: 0,
+ SetTableOfContents: 1,
+ ClickOnSummaryHeader: 2,
+ ClickOnTableOfContentsHeader: 3,
+ ClickOnTableOfContentsLink: 4,
+ ClickOnSideBarButton: 5,
+ },
+ SummarySettingsLinkStartSentinel = "\ue100",
+ SummarySettingsLinkEndSentinel = "\ue101",
+ LoadingMode = { Normal: 0, Reload: 1 },
+ DelayBeforeRestoringScrollPositionInMs = 1e3;
+String.prototype.format = function () {
+ let e = this.split("%@");
+ for (let t = 0, n = arguments.length; t < n; ++t)
+ e.splice(2 * t + 1, 0, arguments[t].toString());
+ return e.join("");
+};
+const debounceTimeoutSymbol = Symbol("debounce-timeout"),
+ debounceSoonProxySymbol = Symbol("debounce-soon-proxy");
+(Object.defineProperty(Object.prototype, "debounce", {
+ value(e) {
+ return new Proxy(this, {
+ get:
+ (t, n) =>
+ (...i) => {
+ let o = t[n];
+ o[debounceTimeoutSymbol] && clearTimeout(o[debounceTimeoutSymbol]);
+ let r = () => {
+ ((o[debounceTimeoutSymbol] = void 0), o.apply(t, i));
+ };
+ o[debounceTimeoutSymbol] = setTimeout(r, e);
+ },
+ });
+ },
+}),
+ Object.defineProperty(Function.prototype, "cancelDebounce", {
+ value() {
+ this[debounceTimeoutSymbol] &&
+ (clearTimeout(this[debounceTimeoutSymbol]),
+ (this[debounceTimeoutSymbol] = void 0));
+ },
+ }));
+const AnimationTerminationCondition = {
+ Interrupted: 0,
+ CompletedSuccessfully: 1,
+};
+((AppleAnimator = function (e, t, n) {
+ ((this.startTime = 0),
+ (this.duration = e),
+ (this.interval = t),
+ (this.animations = []),
+ (this.animationFinishedCallback = n),
+ (this.currentFrameRequestID = null),
+ (this._firstTime = !0));
+ let i = this;
+ this.animate = function () {
+ function e(e, t, n) {
+ return e < t ? t : e > n ? n : e;
+ }
+ let t,
+ n,
+ o,
+ r = new Date().getTime(),
+ a = i.duration;
+ ((t = e(r - i.startTime, 0, a)),
+ (r = t / a),
+ (n = 0.5 - 0.5 * Math.cos(Math.PI * r)),
+ (o = t >= a));
+ let l = i.animations,
+ s = l.length,
+ d = i._firstTime;
+ for (let e = 0; e < s; ++e) l[e].doFrame(i, n, d, o, r);
+ o
+ ? i.stop(AnimationTerminationCondition.CompletedSuccessfully)
+ : ((i._firstTime = !1),
+ (this.currentFrameRequestID = requestAnimationFrame(i.animate)));
+ };
+}),
+ (AppleAnimator.prototype = {
+ start: function (e) {
+ let t = new Date().getTime(),
+ n = this.interval;
+ ((this.startTime = t - n),
+ e && (this.startTime += e),
+ (this.currentFrameRequestID = requestAnimationFrame(this.animate)));
+ },
+ stop: function (e) {
+ (this.animationFinishedCallback && this.animationFinishedCallback(e),
+ this.currentFrameRequestID &&
+ cancelAnimationFrame(this.currentFrameRequestID));
+ },
+ addAnimation: function (e) {
+ this.animations[this.animations.length] = e;
+ },
+ }),
+ (AppleAnimation = function (e, t, n) {
+ ((this.from = e),
+ (this.to = t),
+ (this.callback = n),
+ (this.now = e),
+ (this.ease = 0),
+ (this.progress = 0));
+ }),
+ (AppleAnimation.prototype = {
+ doFrame: function (e, t, n, i, o) {
+ let r;
+ ((r = i ? this.to : this.from + (this.to - this.from) * t),
+ (this.now = r),
+ (this.ease = t),
+ (this.progress = o),
+ this.callback(e, r, n, i));
+ },
+ }));
+let isPlatformVision = !1,
+ usesTwoLineSummaryGlyph = !1,
+ summaryFeedbackButtonMode = "none";
+const readerViewMessageHandler =
+ window.webkit?.messageHandlers?.SafariReaderView,
+ isReaderViewInSeparateProcess = !!readerViewMessageHandler;
+if (isReaderViewInSeparateProcess) {
+ (window.addEventListener("error", (e) => {
+ readerViewMessageHandler.postMessage({
+ command: "logError",
+ body: `${e.filename || ""}:${e.lineno}:${e.colno}: ${e.message}`,
+ });
+ }),
+ window.addEventListener("unhandledrejection", (e) => {
+ readerViewMessageHandler.postMessage({
+ command: "logError",
+ body: `Unhandled promise rejection: ${e.reason}`,
+ });
+ }));
+ const e = void 0;
+ console.error = function (...t) {
+ (readerViewMessageHandler.postMessage({
+ command: "logError",
+ body: `Console: ${t.join(" - ")}`,
+ }),
+ e(...t));
+ };
+}
+class Article {
+ #e;
+ #t;
+ #n;
+ #i;
+ #o;
+ #r;
+ #a;
+ #l;
+ #s;
+ #d;
+ #c;
+ #m;
+ constructor(e) {
+ ((this.#o = e.articleIsLTR),
+ (this.#e = e.articleNode),
+ (this.#t = e.articleSubhead),
+ (this.#n = e.articleTitle),
+ (this.#i = e.articleTitleInformation),
+ (this.#r = e.baseURI),
+ (this.#a = e.documentURLString),
+ (this.#l = e.heightOfArticleNode),
+ (this.#s = e.metadataBlock),
+ (this.#d = e.multiPageContentElements),
+ (this.#c = e.nextPageURL),
+ (this.#m = e.routeToArticleNode));
+ }
+ articleIsLTR() {
+ return this.#o;
+ }
+ articleNode() {
+ return this.#e;
+ }
+ adoptableArticle() {
+ return this.#e;
+ }
+ adoptableMetadataBlock() {
+ return this.#s;
+ }
+ adoptableMultiPageContentElements() {
+ return this.#d;
+ }
+ hasArticle() {
+ return !!this.#e;
+ }
+ articleSubhead() {
+ return this.#t;
+ }
+ articleTitle() {
+ return this.#n;
+ }
+ articleTitleInformation() {
+ return this.#i;
+ }
+ baseURI() {
+ return this.#r;
+ }
+ documentURLString() {
+ return this.#a;
+ }
+ heightOfArticleNodeOnOriginalPage() {
+ return this.#l;
+ }
+ nextPageURL() {
+ return this.#c;
+ }
+ routeToArticleNode() {
+ return this.#m;
+ }
+ scrollToElementWithUniqueID(e, t) {
+ return readerViewMessageHandler.postMessage({
+ command: "callArticleFinder",
+ method: "scrollToElementWithUniqueID",
+ arguments: [e, t],
+ });
+ }
+ uniqueIDAndScrollRatioOfElementPinnedToTop() {
+ return readerViewMessageHandler.postMessage({
+ command: "callArticleFinder",
+ method: "uniqueIDAndScrollRatioOfElementPinnedToTop",
+ });
+ }
+}
+let smoothScrollingAnimator,
+ smoothScrollingAnimation,
+ articleScrolledNotificationCoalescer,
+ scrollEventIsSmoothScroll = !1;
+window.addEventListener("scroll", articleScrolled, {
+ capture: !1,
+ passive: !0,
+});
+const ContentAwareNavigationMarker = "reader-content-aware-navigation-marker",
+ ContentAwareNavigationAnimationDuration = 200,
+ ContentAwareNavigationElementOffset = 8,
+ ContentAwareNavigationDirection = { Up: 0, Down: 1 };
+((ContentAwareScroller = function () {
+ this._numberOfContentAwareScrollAnimationsInProgress = 0;
+}),
+ (ContentAwareScroller.prototype = {
+ _contentElementAtTopOfViewport: function () {
+ let e = articleTitleElement();
+ do {
+ if (
+ !(e.getBoundingClientRect().top < ContentAwareNavigationElementOffset)
+ )
+ return e;
+ } while ((e = nextReaderContentElement(e)));
+ return null;
+ },
+ _clearTargetOfContentAwareScrolling: function () {
+ let e = document.getElementById(ContentAwareNavigationMarker);
+ e && e.removeAttribute("id");
+ },
+ _contentAwareScrollFinished: function (e) {
+ e === AnimationTerminationCondition.CompletedSuccessfully &&
+ (--this._numberOfContentAwareScrollAnimationsInProgress,
+ this._numberOfContentAwareScrollAnimationsInProgress ||
+ ((smoothScrollingAnimator = null),
+ (smoothScrollingAnimation = null),
+ this._clearTargetOfContentAwareScrolling()));
+ },
+ scroll: function (e) {
+ let t,
+ n,
+ i = document.getElementById(ContentAwareNavigationMarker),
+ o = i || this._contentElementAtTopOfViewport();
+ if (e === ContentAwareNavigationDirection.Down) {
+ let e =
+ Math.abs(
+ o.getBoundingClientRect().top - ContentAwareNavigationElementOffset,
+ ) < 1;
+ t = i || e ? nextReaderContentElement(o) : o;
+ } else if (e === ContentAwareNavigationDirection.Up)
+ if (o === articleTitleElement()) {
+ if (0 === document.scrollingElement.scrollTop) return;
+ n = -1 * document.scrollingElement.scrollTop;
+ } else t = previousReaderContentElement(o);
+ (t &&
+ (n =
+ t.getBoundingClientRect().top - ContentAwareNavigationElementOffset),
+ ++this._numberOfContentAwareScrollAnimationsInProgress,
+ smoothScroll(
+ document.scrollingElement,
+ n,
+ ContentAwareNavigationAnimationDuration,
+ this._contentAwareScrollFinished.bind(this),
+ ),
+ this._clearTargetOfContentAwareScrolling(),
+ t && (t.id = ContentAwareNavigationMarker));
+ },
+ }),
+ window.addEventListener("keydown", keyDown, !1));
+let initialScrollPosition,
+ didRestoreInitialScrollPosition = !1;
+const ThemeSettings = {
+ White: { cssClassName: "white" },
+ Gray: { cssClassName: "gray", tweetTheme: "dark" },
+ Sepia: { cssClassName: "sepia" },
+ Night: { cssClassName: "night", tweetTheme: "dark" },
+ },
+ ShouldRestoreReadingPosition = { No: !1, Yes: !0 },
+ MinTextZoomIndex = 0,
+ MaxTextZoomIndex = 11,
+ MaximumWidthOfImageOrVideoExtendingBeyondTextContainer = 1050,
+ ReaderConfigurationJavaScriptEnabledKey = "javaScriptEnabled";
+((ReaderAppearanceController = function () {
+ ((this._shouldUsePaperAppearance = function () {
+ const e = 70;
+ return this.articleWidth() + 2 * e < this.documentElementWidth();
+ }),
+ (this._isOLEDDisplay = function () {
+ return !1;
+ }),
+ (this._tryApplyStaticConfiguration = function () {
+ return !1;
+ }),
+ (this._defaultFontFamilyName = "System"),
+ (this._defaultThemeName = "White"),
+ (this.configuration = {}),
+ (this._textSizeIndex = null),
+ (this._fontFamilyName = this._defaultFontFamilyName),
+ (this._themeName = this._defaultThemeName));
+}),
+ (ReaderAppearanceController.prototype = {
+ initialize: function () {
+ (this.applyConfiguration(ReaderJSController.initialConfiguration()),
+ this._isOLEDDisplay()
+ ? document.body.classList.add("oled")
+ : isPlatformVision && document.body.classList.add("vision"));
+ },
+ applyConfiguration: function (e) {
+ if (this._tryApplyStaticConfiguration()) return void this.layOutContent();
+ let t = this._locale();
+ this.setLocale(t);
+ for (let n of [
+ e.fontFamilyNameForLanguageTag[t],
+ e.defaultFontFamilyNameForLanguage[t],
+ "System",
+ ])
+ if (n && this.setFontFamily(n)) break;
+ for (let t of [e.themeName, "White"]) if (t && this.setTheme(t)) break;
+ (this.setCurrentTextSizeIndex(e.fontSizeIndex, e.defaultFontSizeIndex),
+ (this.configuration = e),
+ this.layOutContent(),
+ containsAssistantContent() && layoutAssistantContent(),
+ (isPlatformVision = !!e.isPlatformVision),
+ (usesTwoLineSummaryGlyph = !!e.usesTwoLineSummaryGlyph),
+ "string" == typeof e.summaryFeedbackButtonMode &&
+ (summaryFeedbackButtonMode = e.summaryFeedbackButtonMode));
+ },
+ articleWidth: function () {
+ return document.getElementById("article").getBoundingClientRect().width;
+ },
+ _textColumnWidthInPoints: function () {
+ return parseFloat(
+ getComputedStyle(document.querySelector("#article .page")).width,
+ );
+ },
+ documentElementWidth: function () {
+ return document.documentElement.clientWidth;
+ },
+ setCurrentTextSizeIndex: function (e, t) {
+ ((this._textSizeIndex = e),
+ (this._defaultTextSizeIndex = t),
+ this._rebuildDynamicStyleSheet());
+ },
+ currentFontCSSClassName: function () {
+ return this._currentFontSettings().cssClassName;
+ },
+ currentFontCSSFontFamilyName: function () {
+ return this._currentFontSettings().fontFamilyName;
+ },
+ currentFontUsesSystemFont: function () {
+ return this._currentFontSettings().usesSystemFont;
+ },
+ _currentFontSettings: function () {
+ return fontSettings(this._fontFamilyName);
+ },
+ setLocale: function (e) {
+ if (e === this._lastSetLocale) return;
+ let t = document.body.classList;
+ const n = "locale-";
+ (t.remove(n + this._lastSetLocale),
+ t.add(n + e),
+ (this._lastSetLocale = e));
+ },
+ setFontFamily: function (e) {
+ let t = document.body,
+ n = fontSettings(e);
+ if (!n) return !1;
+ if (this._fontFamilyName) {
+ let e = fontSettings(this._fontFamilyName);
+ (t.classList.remove(e.cssClassName),
+ (t.style.fontFamily = null),
+ e.usesSystemFont && t.classList.remove("system"));
+ }
+ return (
+ "function" == typeof ReaderJSController.makeFontAvailableIfNecessary &&
+ ReaderJSController.makeFontAvailableIfNecessary(e),
+ t.classList.add(n.cssClassName),
+ n.fontFamilyName && (t.style.fontFamily = n.fontFamilyName),
+ n.usesSystemFont && t.classList.add("system"),
+ (this._fontFamilyName = e),
+ !0
+ );
+ },
+ _theme: function () {
+ return ThemeSettings[this._themeName];
+ },
+ setTheme: function (e) {
+ let t = document.body,
+ n = ThemeSettings[e];
+ return (
+ !!n &&
+ (t.classList.contains(n.cssClassName) ||
+ (this._theme() && t.classList.remove(this._theme().cssClassName),
+ t.classList.add(n.cssClassName),
+ (this._themeName = e)),
+ !0)
+ );
+ },
+ usesPaperAppearance: function () {
+ return document.documentElement.classList.contains("paper");
+ },
+ usesSpatialAppearance: function () {
+ return document.body.classList.contains("spatial");
+ },
+ layOutContent: function (e = ShouldRestoreReadingPosition.Yes) {
+ document.querySelector("#article .page") &&
+ (this._shouldUsePaperAppearance()
+ ? document.documentElement.classList.add("paper")
+ : document.documentElement.classList.remove("paper"),
+ this.layOutElements(),
+ e === ShouldRestoreReadingPosition.Yes &&
+ ReadingPositionStabilizerJS.restorePosition());
+ },
+ layOutElements: function () {
+ (makeWideElementsScrollable(),
+ this._layOutImagesAndVideoElementsBeyondTextColumn(),
+ this._layOutElementsContainingTextBeyondTextColumn(),
+ this._layOutVideos(),
+ this._layOutMetadataBlock());
+ },
+ _layOutMetadataBlock: function () {
+ let e = document.querySelector(".metadata");
+ if (!e) return;
+ let t = e.querySelector(".byline"),
+ n = e.querySelector(".date");
+ if (!t || !n) return void e.classList.add("singleline");
+ let i = 0;
+ for (let e of t.getClientRects()) i += e.width;
+ for (let e of n.getClientRects()) i += e.width;
+ i + 25 > this._textColumnWidthInPoints()
+ ? e.classList.remove("singleline")
+ : e.classList.add("singleline");
+ },
+ _layOutImagesAndVideoElementsBeyondTextColumn: function () {
+ let e = this.canLayOutContentMaintainingAspectRatioBeyondTextColumn(),
+ t = document.getElementById("article").querySelectorAll("img, video");
+ for (let n of t)
+ this.setImageOrVideoShouldLayOutBeyondTextColumnIfAppropriate(n, e);
+ },
+ _layOutElementsContainingTextBeyondTextColumn: function () {
+ const e = { PRE: !0, TABLE: !1 },
+ t = 22;
+ let n = document.querySelectorAll(".scrollable pre, .scrollable table");
+ for (let i of n) {
+ let n = i.parentElement;
+ for (let e = n; e; e = e.parentElement)
+ "BLOCKQUOTE" === e.tagName && e.classList.add("simple");
+ stopExtendingElementBeyondTextColumn(n);
+ let o = i.scrollWidth,
+ r = this._textColumnWidthInPoints();
+ if (o <= r) continue;
+ let a = getComputedStyle(document.querySelector(".page")),
+ l = 0;
+ if (e[i.tagName]) {
+ let e =
+ parseFloat(a["-webkit-padding-start"]) +
+ parseFloat(a["-webkit-margin-start"]);
+ l = Math.min(e, t);
+ }
+ extendElementBeyondTextColumn(
+ n,
+ Math.min(o, this._widthAvailableForLayout() - 2 * l),
+ r,
+ );
+ }
+ },
+ _layOutVideos: function () {
+ function e(e) {
+ return (
+ e.src &&
+ /^(.+\.)?(youtube(-nocookie)?|vimeo)\.com\.?$/.test(
+ urlFromString(e.src).hostname,
+ )
+ );
+ }
+ const t = 16 / 9;
+ let n,
+ i,
+ o =
+ ReaderAppearanceJS.canLayOutContentMaintainingAspectRatioBeyondTextColumn();
+ for (let r of document
+ .getElementById("article")
+ .querySelectorAll("iframe")) {
+ const a = r.parentElement.classList.contains("iframe-wrapper");
+ if (!a && !e(r)) continue;
+ let l;
+ if (
+ (a
+ ? (l = r.parentElement)
+ : ((l = document.createElement("div")),
+ (l.className = "iframe-wrapper"),
+ r.nextSibling
+ ? r.parentNode.insertBefore(l, r.nextSibling)
+ : r.parentNode.appendChild(l),
+ l.appendChild(r)),
+ n ||
+ (n = Math.min(
+ MaximumWidthOfImageOrVideoExtendingBeyondTextContainer,
+ this._widthAvailableForLayout(),
+ )),
+ i || (i = this._textColumnWidthInPoints()),
+ o && n > i)
+ ) {
+ ((l.style.height = n / t + "px"),
+ extendElementBeyondTextColumn(l, n, i),
+ (r.style.height = "100%"));
+ let e = this.usesPaperAppearance() ? 2 : 0;
+ r.style.width = n - e + "px";
+ } else
+ (stopExtendingElementBeyondTextColumn(l),
+ (l.style.width = "100%"),
+ (l.style.height = i / t + "px"));
+ }
+ },
+ canLayOutContentMaintainingAspectRatioBeyondTextColumn: function () {
+ const e = 700;
+ if (window.innerHeight >= e) return !0;
+ const t = 1.25;
+ return window.innerWidth / window.innerHeight <= t;
+ },
+ setImageOrVideoShouldLayOutBeyondTextColumnIfAppropriate: function (e, t) {
+ if (t && !e.closest("blockquote, table, .float")) {
+ let t,
+ n = this._textColumnWidthInPoints(),
+ i = parseFloat(e.getAttribute("width"));
+ t = isNaN(i) ? e.naturalWidth : i;
+ let o = Math.min(
+ t,
+ Math.min(
+ MaximumWidthOfImageOrVideoExtendingBeyondTextContainer,
+ this._widthAvailableForLayout(),
+ ),
+ );
+ if (o > n) return void extendElementBeyondTextColumn(e, o, n);
+ }
+ stopExtendingElementBeyondTextColumn(e);
+ },
+ _widthAvailableForLayout: function () {
+ return this.usesPaperAppearance() && !this.usesSpatialAppearance()
+ ? this.articleWidth()
+ : this.documentElementWidth();
+ },
+ _rebuildDynamicStyleSheet: function () {
+ let e = document.getElementById("dynamic-article-content").sheet;
+ for (; e.cssRules.length;) e.removeRule(0);
+ let t = this._currentFontSettings().fontSizes[this._textSizeIndex] + "px",
+ n =
+ this._currentFontSettings().fontSizes[this._defaultTextSizeIndex] +
+ "px",
+ i = this._currentFontSettings().lineHeights[this._textSizeIndex],
+ o = this._currentFontSettings().lineHeights[this._defaultTextSizeIndex];
+ (e.insertRule(
+ ":root { --scaled-font-size:" +
+ t +
+ "; --scaled-line-height:" +
+ i +
+ "; --scaled-font-size-multiplier:calc(" +
+ t +
+ "/" +
+ n +
+ "); --scaled-line-height-multiplier:calc(" +
+ i +
+ "/" +
+ o +
+ "); }",
+ ),
+ e.insertRule(
+ "#article { font-size: var(--scaled-font-size); line-height: var(--scaled-line-height); }",
+ ),
+ e.insertRule(
+ "#assistant-container { font-size: var(--scaled-font-size); line-height: var(--scaled-line-height); }",
+ ));
+ },
+ _locale: function () {
+ let e = document.getElementById("article").style.webkitLocale;
+ return e && e.length ? ('"' != e[0] ? e : e.substr(1, e.length - 2)) : "";
+ },
+ }));
+let lastMouseDownWasOutsideOfPaper = !1;
+((ReaderController = function () {
+ ((this.pageNumber = 1),
+ (this.pageURLs = []),
+ (this.articleIsLTR = !0),
+ (this.loadingNextPage = !1),
+ (this.loadingNextPageManuallyStopped = !1),
+ (this.cachedNextPageURL = null),
+ (this.lastKnownDocumentElementWidth = 0),
+ (this.cachedIframeURLMap = new Map()),
+ (this._canShowAssistantSidebar = function () {
+ return !0;
+ }),
+ (this._distanceFromBottomOfArticleToStartLoadingNextPage = function () {
+ return NaN;
+ }),
+ (this._clickingOutsideOfPaperRectangleDismissesReader = !1),
+ (this._shouldSkipActivationWhenPageLoads = function () {
+ return !1;
+ }),
+ (this._shouldConvertRelativeURLsToAbsoluteURLsWhenPrintingOrMailing = !1),
+ (this._deferSendingContentIsReadyForDisplay = !1),
+ (this._isJavaScriptEnabled = function () {
+ return !0;
+ }),
+ (this._readerIsActive = !0),
+ (this._documentIsVisible = !document.hidden));
+}),
+ (ReaderController.prototype = {
+ setOriginalURL: function (e) {
+ ((this.originalURL = e),
+ this.pageURLs.push(e),
+ (document.head.getElementsByTagName("base")[0].href = this.originalURL),
+ ReaderJSController.setArticleBaseURLString(e));
+ },
+ setNextPageURL: function (e) {
+ if (
+ !e ||
+ -1 !== this.pageURLs.indexOf(e) ||
+ this.pageNumber + 1 === MaxNumberOfNextPagesToLoad
+ )
+ return void this.setLoadingNextPage(!1);
+ let t;
+ (this.setLoadingNextPage(!0),
+ this.pageURLs.push(e),
+ (t = isReaderViewInSeparateProcess
+ ? () => {
+ ((fetchNextPageArticlePromiseWithCanceller =
+ makePromiseCancellable(
+ readerViewMessageHandler.postMessage({
+ command: "fetchArticle",
+ url: e,
+ pageInformation: {
+ pageNumber: this.pageNumber + 1,
+ suggestedRouteToArticle: this.routeToArticle,
+ previouslyDiscoveredPageURLStrings: this.pageURLs,
+ },
+ }),
+ )),
+ fetchNextPageArticlePromiseWithCanceller.promise.then(
+ nextPageLoadComplete,
+ ));
+ }
+ : () => {
+ (nextPageContainer().addEventListener(
+ "load",
+ () => {
+ nextPageLoadComplete(null);
+ },
+ !1,
+ ),
+ (nextPageContainer().src = e));
+ }),
+ this.readerOperationMode == ReaderOperationMode.OffscreenFetching
+ ? t()
+ : (this.nextPageLoadTimer = setTimeout(t, LoadNextPageDelay)));
+ },
+ pauseLoadingNextPage: function () {
+ this.readerOperationMode == ReaderOperationMode.Normal &&
+ (isReaderViewInSeparateProcess
+ ? (fetchNextPageArticlePromiseWithCanceller?.cancel(),
+ (fetchNextPageArticlePromiseWithCanceller = null))
+ : (nextPageContainer().removeEventListener(
+ "load",
+ nextPageLoadComplete,
+ !1,
+ ),
+ (nextPageContainer().src = null)),
+ this.cachedNextPageURL ||
+ (this.cachedNextPageURL = this.pageURLs.pop()),
+ this.nextPageLoadTimer && clearTimeout(this.nextPageLoadTimer),
+ ReaderJSController.didChangeNextPageLoadingState(!1));
+ },
+ stopLoadingNextPage: function () {
+ (isReaderViewInSeparateProcess
+ ? (fetchNextPageArticlePromiseWithCanceller?.cancel(),
+ (fetchNextPageArticlePromiseWithCanceller = null))
+ : (nextPageContainer().removeEventListener(
+ "load",
+ nextPageLoadComplete,
+ !1,
+ ),
+ (nextPageContainer().src = null)),
+ this.nextPageLoadTimer && clearTimeout(this.nextPageLoadTimer),
+ this.isLoadingNextPage() &&
+ (this.setLoadingNextPage(!1),
+ (this.loadingNextPageManuallyStopped = !0)));
+ },
+ isLoadingNextPage: function () {
+ return this.loadingNextPage;
+ },
+ setLoadingNextPage: function (e) {
+ this.loadingNextPage != e &&
+ (e
+ ? addIncomingPagePlaceholder(window.navigator.onLine)
+ : removeIncomingPagePlaceholder(),
+ (this.loadingNextPage = e),
+ ReaderJSController.didChangeNextPageLoadingState(this.loadingNextPage));
+ },
+ doneLoadingAllPages: function () {
+ ReaderJSController.doneLoadingReaderPage();
+ },
+ updateSerializedArticle: function (e) {
+ const t = new Article(e);
+ ReaderJSController.originalArticleFinder = function () {
+ return t;
+ };
+ },
+ loadSerializedArticle: function (e) {
+ (this.updateSerializedArticle(e), this.loaded());
+ },
+ loaded: function () {
+ this.readerOperationMode = ReaderJSController.readerOperationMode();
+ const e = ReaderJSController.originalArticleFinder();
+ if (!e || this._shouldSkipActivationWhenPageLoads())
+ return void ReaderJSController.deactivateNow();
+ this.loadArticle();
+ let t = ReaderJSController.cachedTopScrollOffset();
+ (t > 0
+ ? (document.scrollingElement.scrollTop = t)
+ : requestAnimationFrame(function () {
+ ReadingPositionStabilizerJS.applyScrollPositionFromOriginalPage();
+ }),
+ ReadingPositionStabilizerJS.initialize(),
+ this._clickingOutsideOfPaperRectangleDismissesReader &&
+ (document.documentElement.addEventListener(
+ "mousedown",
+ monitorMouseDownForPotentialDeactivation,
+ ),
+ document.documentElement.addEventListener(
+ "click",
+ deactivateIfEventIsOutsideOfPaperContainer,
+ )),
+ window.addEventListener("resize", this.windowDidResize.bind(this), !1));
+ var n = "",
+ i = e.articleTitle();
+ i && (n += i + " \n");
+ var o = e.articleSubhead();
+ o && (n += o + " \n");
+ let r = n + e.adoptableArticle().textContent;
+ r = r.toString().replace(/(<([^>]+)>)/gi, "");
+ let a = function () {
+ ReaderJSController.contentIsReadyForDisplay(r);
+ };
+ this._deferSendingContentIsReadyForDisplay ? setTimeout(a, 0) : a();
+ },
+ windowDidResize: function () {
+ let e = ReaderAppearanceJS.documentElementWidth();
+ e !== this.lastKnownDocumentElementWidth &&
+ ((this.lastKnownDocumentElementWidth = e),
+ ReaderAppearanceJS.layOutContent(),
+ ReadingPositionStabilizerJS.windowDidResize(),
+ layoutAssistantContent());
+ },
+ loadArticle: function (e = LoadingMode.Normal) {
+ const t = ReaderJSController.originalArticleFinder();
+ if (
+ (isReaderViewInSeparateProcess || t.hasArticle() || t.articleNode(!0),
+ !t.hasArticle())
+ )
+ return (
+ this.setOriginalURL(t.baseURI()),
+ void this.doneLoadingAllPages()
+ );
+ ((this.routeToArticle = t.routeToArticleNode()),
+ (this.displayTitleInformation = t.articleTitleInformation()),
+ (this._snapshotOfArticleTitle = t.articleTitle()),
+ (this.displaySubhead = t.articleSubhead()),
+ (this.metadataElement = t.adoptableMetadataBlock()),
+ (this.articleIsLTR = t.articleIsLTR()),
+ (this._heightOfArticleNodeOnOriginalPage = isReaderViewInSeparateProcess
+ ? t.heightOfArticleNodeOnOriginalPage()
+ : t.heightOfArticleNode()));
+ let n,
+ i = t.adoptableArticle();
+ if (
+ ((this._snapshotOfAdoptableArticle = i.cloneNode(!0)),
+ (document.title = t.articleTitle()),
+ this.setOriginalURL(t.baseURI()),
+ this.readerOperationMode != ReaderOperationMode.ArchiveViewing)
+ ) {
+ if (this._isJavaScriptEnabled())
+ ((n = t.nextPageURL()), this.setNextPageURL(n));
+ else {
+ for (let e of i.querySelectorAll("iframe")) e.remove();
+ this.stopLoadingNextPage();
+ }
+ (e !== LoadingMode.Reload && ReaderAppearanceJS.initialize(),
+ this.createAssistantElements(),
+ this.createPageFromNode(i),
+ n ||
+ (t
+ .adoptableMultiPageContentElements()
+ .forEach(this.createPageFromNode, this),
+ updatePageNumbers()),
+ this.isLoadingNextPage() || this.doneLoadingAllPages(),
+ e === LoadingMode.Reload &&
+ setTimeout(function () {
+ ReadingPositionStabilizerJS.contentWasReloaded();
+ }, 0));
+ } else ReaderAppearanceJS.layOutContent();
+ },
+ reloadArticlePreservingScrollPositionIfArticleNodeContentHasChanged:
+ async function () {
+ const e = ReaderJSController.originalArticleFinder();
+ if (!e) return;
+ const t = e.documentURLString(),
+ n = 30;
+ for (const e of document.querySelectorAll("audio, video"))
+ if (mediaElementIsPlaying(e)) return;
+ let i;
+ if (
+ ((i = isReaderViewInSeparateProcess
+ ? await readerViewMessageHandler.postMessage({
+ command: "callArticleFinder",
+ method: "heightOfArticleNode",
+ })
+ : e.heightOfArticleNode()),
+ !i)
+ )
+ return;
+ const o = this._heightOfArticleNodeOnOriginalPage;
+ if (i < o - n) return;
+ if (this.originalURL !== t) return;
+ let r;
+ if (
+ ((r = isReaderViewInSeparateProcess
+ ? await readerViewMessageHandler.postMessage({
+ command: "callArticleFinder",
+ method: "reset",
+ })
+ : e.reset()),
+ !r)
+ )
+ return;
+ isReaderViewInSeparateProcess &&
+ this.updateSerializedArticle(
+ await readerViewMessageHandler.postMessage({
+ command: "callArticleFinder",
+ method: "serializableArticle",
+ }),
+ );
+ const a = e.adoptableArticle();
+ if (
+ this._adoptableArticlesAreUserVisiblyEquivalent(
+ this._snapshotOfAdoptableArticle,
+ a,
+ )
+ )
+ return;
+ const l = e.articleTitle();
+ this._snapshotOfArticleTitle === l &&
+ this.reloadArticlePreservingScrollPosition();
+ },
+ _adoptableArticlesAreUserVisiblyEquivalent: function (e, t) {
+ function n(e, t) {
+ let i = e.nodeType;
+ if (i !== t.nodeType) return !1;
+ switch (i) {
+ case Node.ELEMENT_NODE:
+ if (e.tagName !== t.tagName) return !1;
+ let n = e.attributes;
+ if (n.length !== t.attributes.length) return !1;
+ let i = t.attributes;
+ for (let e of n)
+ if (
+ e.name !== READER_UNIQUE_ID_ATTRIBUTE_KEY &&
+ e.value !== i[e.name].value
+ )
+ return !1;
+ break;
+ case Node.TEXT_NODE:
+ case Node.COMMENT_NODE:
+ if (e.data !== t.data) return !1;
+ break;
+ default:
+ return !1;
+ }
+ let o = e.firstChild,
+ r = t.firstChild;
+ for (; o;) {
+ if (!n(o, r)) return !1;
+ ((o = o.nextSibling), (r = r.nextSibling));
+ }
+ return !r;
+ }
+ return n(e, t);
+ },
+ reloadArticlePreservingScrollPosition: function () {
+ this._reloadArticleAndPreserveScrollPosition(!0);
+ },
+ loadNewArticle: function () {
+ this._reloadArticleAndPreserveScrollPosition(!1);
+ },
+ _reloadArticleAndPreserveScrollPosition: async function (e) {
+ if (!ReaderJSController.originalArticleFinder())
+ return void ReaderJSController.deactivateNow();
+ (isReaderViewInSeparateProcess &&
+ this.updateSerializedArticle(
+ await readerViewMessageHandler.postMessage({
+ command: "callArticleFinder",
+ method: "serializableArticle",
+ }),
+ ),
+ ReadingPositionStabilizerJS.setTrackPosition(!1));
+ const [t, n] = [scrollX, scrollY],
+ [i, o] =
+ ReadingPositionStabilizerJS.uniqueIDAndScrollRatioOfElementPinnedToTop();
+ let r = document.getElementById("article");
+ for (
+ r.style.minHeight = r.getBoundingClientRect().height + "px";
+ r.childNodes.length >= 1;
+ )
+ r.removeChild(r.firstChild);
+ if (
+ (this.reinitialize(),
+ e || (document.scrollingElement.scrollTop = 0),
+ this.loadArticle(LoadingMode.Reload),
+ e)
+ ) {
+ let e;
+ (i &&
+ (e = ReadingPositionStabilizerJS.tryToScrollToUniqueIDAndRatio(i, o)),
+ e || scrollTo(t, n));
+ }
+ (ReadingPositionStabilizerJS.setTrackPosition(!0),
+ setTimeout(function () {
+ r.style.minHeight = null;
+ }, 0));
+ },
+ reinitialize: function () {
+ ((this.pageNumber = 1),
+ (this.pageURLs = []),
+ (this.articleIsLTR = !0),
+ (this.loadingNextPage = !1),
+ (this.loadingNextPageManuallyStopped = !1),
+ (this.routeToArticle = void 0),
+ (this.displayTitleInformation = void 0),
+ (this.displaySubhead = void 0),
+ (this.originalURL = void 0),
+ (this.nextPageLoadTimer = void 0),
+ (this.readerOperationMode = ReaderJSController.readerOperationMode()),
+ (this.cachedNextPageURL = null));
+ },
+ createAssistantElements: function () {
+ let e = document.createElement("div");
+ ((e.id = "assistant-container"), (e.style.display = "none"));
+ let t = document.createElement("div");
+ ((t.id = "summary-container"), (t.style.display = "none"));
+ let n = document.createElement("H3");
+ ((n.id = "summary-header"), t.appendChild(n));
+ let i = document.createElement("p");
+ ((i.id = "sidebar-summary-text-id-1"), t.appendChild(i));
+ let o = document.createElement("div");
+ ((o.id = "tableOfContents-container"), (o.style.display = "none"));
+ let r = document.createElement("H3");
+ ((r.id = "tableOfContents-header"), o.appendChild(r));
+ let a = document.createElement("ol");
+ ((a.id = "tableOfContents-list"),
+ o.appendChild(a),
+ e.appendChild(t),
+ e.appendChild(o),
+ document.body.appendChild(e));
+ },
+ createPageFromNode: function (e) {
+ let t = document.createElement("div");
+ ((t.className = "page"), this.articleIsLTR || t.classList.add("rtl"));
+ let n = document.createElement("div");
+ ((n.className = "page-number"), t.appendChild(n));
+ let i = this.displayTitleInformation,
+ o = document.createElement("h1");
+ if (
+ ((o.className = "title"),
+ (o.textContent = i.titleText),
+ i.linkURL && i.linkIsForExternalPage)
+ ) {
+ let e = document.createElement("a");
+ ((e.href = i.linkURL),
+ i.linkIsTargetBlank && e.setAttribute("target", "_blank"),
+ e.appendChild(o),
+ (o = e));
+ }
+ if (
+ (o.setAttribute(READER_UNIQUE_ID_ATTRIBUTE_KEY, READER_UNIQUE_ID_TITLE),
+ t.appendChild(o),
+ this.displaySubhead)
+ ) {
+ let e = document.createElement("h2");
+ ((e.className = "subhead"),
+ (e.textContent = this.displaySubhead),
+ e.setAttribute(
+ READER_UNIQUE_ID_ATTRIBUTE_KEY,
+ READER_UNIQUE_ID_SUBHEAD,
+ ),
+ t.appendChild(e));
+ }
+ if (this.metadataElement && this.metadataElement.innerText) {
+ let e = document.createElement("div");
+ for (e.className = "metadata"; this.metadataElement.firstChild;)
+ e.appendChild(this.metadataElement.firstChild);
+ t.appendChild(e);
+ }
+ let r = e.tagName;
+ if ("PRE" === r || "CODE" === r) t.appendChild(e);
+ else for (; e.firstChild;) t.appendChild(e.firstChild);
+ (document
+ .getElementById("article")
+ .insertBefore(t, incomingPagePlaceholder()),
+ ReaderJS._isJavaScriptEnabled() &&
+ ReaderJSController.replaceSimpleTweetsWithRichTweets(
+ this.optionsForTweetCreation(),
+ ),
+ ReaderAppearanceJS.layOutContent(ShouldRestoreReadingPosition.No),
+ updatePageNumbers(),
+ restoreInitialArticleScrollPositionIfPossible());
+ for (let e of t.querySelectorAll("img"))
+ e.onload = function (e) {
+ let t = e.target;
+ (ReaderAppearanceJS.setImageOrVideoShouldLayOutBeyondTextColumnIfAppropriate(
+ t,
+ ReaderAppearanceJS.canLayOutContentMaintainingAspectRatioBeyondTextColumn(),
+ ),
+ (t.onload = null));
+ };
+ this._fixImageElementsWithinPictureElements();
+ },
+ optionsForTweetCreation: function () {
+ let e = { dnt: !0 },
+ t = ReaderAppearanceJS._theme();
+ return (t && t.tweetTheme && (e.theme = t.tweetTheme), e);
+ },
+ removeAttribute: function (e, t) {
+ let n = e.querySelectorAll("[" + t + "]");
+ for (let e of n) e.removeAttribute(t);
+ },
+ preparePrintingMailingFrame: function () {
+ let e = this.printingMailingFrameElementId(),
+ t = document.getElementById(e);
+ (t && document.body.removeChild(t),
+ (t = this.sanitizedFullArticleFrame()),
+ (t.id = e));
+ },
+ sanitizedFullArticleFrame: function () {
+ let e = document.createElement("iframe");
+ ((e.style.display = "none"),
+ (e.style.position = "absolute"),
+ document.body.appendChild(e));
+ let t = e.contentDocument,
+ n = document.createElement("base");
+ ((n.href = this.originalURL), t.head.appendChild(n));
+ let i = document.createElement("div");
+ i.className = "original-url";
+ let o = document.createElement("a");
+ ((o.href = this.originalURL),
+ (o.textContent = this.originalURL),
+ i.appendChild(document.createElement("br")),
+ i.appendChild(o),
+ i.appendChild(document.createElement("br")),
+ i.appendChild(document.createElement("br")),
+ t.body.appendChild(i),
+ t.body.appendChild(this.sanitizedFullArticle()),
+ t.head.appendChild(document.getElementById("print").cloneNode(!0)));
+ let r = t.createElement("title");
+ return ((r.innerText = document.title), t.head.appendChild(r), e);
+ },
+ getArticleHeadingElements: function () {
+ const e = ReaderJSController.originalArticleFinder();
+ var t = {};
+ let n = e.articleSubhead();
+ n && (t.subheadline = n);
+ let i = e.adoptableMetadataBlock();
+ return (
+ i &&
+ (t.articleMetadata =
+ plaintextVersionOfNodeAppendingNewlinesBetweenBlockElements(i)),
+ t
+ );
+ },
+ sanitizedFullArticle: function () {
+ let e = document.getElementById("article").cloneNode(!0);
+ e.removeAttribute("tabindex");
+ const t = e.querySelectorAll(".title");
+ for (let e = 1, n = t.length; e < n; ++e) t[e].remove();
+ for (let t of e.querySelectorAll(
+ ".page-number, #incoming-page-placeholder, #onDeviceSummaryButton",
+ ))
+ t.remove();
+ if (
+ (prepareTweetsInPrintingMailingFrame(e),
+ this._shouldConvertRelativeURLsToAbsoluteURLsWhenPrintingOrMailing)
+ ) {
+ const t = /^http:\/\/|^https:\/\/|^data:/i;
+ let n = e.querySelectorAll("img, video, audio, source");
+ for (let e of n) {
+ let n = e.getAttribute("src");
+ t.test(n) || e.setAttribute("src", e.src);
+ }
+ }
+ for (let t of e.querySelectorAll(".extendsBeyondTextColumn"))
+ stopExtendingElementBeyondTextColumn(t);
+ for (let t of e.querySelectorAll(".delimeter")) t.innerText = "\u2022";
+ e.classList.add(ReaderAppearanceJS.currentFontCSSClassName());
+ let n = ReaderAppearanceJS.currentFontCSSFontFamilyName();
+ (n && (e.style.fontFamily = n),
+ ReaderAppearanceJS.currentFontUsesSystemFont() &&
+ e.classList.add("system"),
+ e.classList.add("exported"));
+ ReaderJSController.originalArticleFinder();
+ for (let t of e.getElementsByTagName("*"))
+ t.removeAttribute(READER_UNIQUE_ID_ATTRIBUTE_KEY);
+ let i = document.getElementById("article-content").sheet.cssRules,
+ o = i.length;
+ for (let t = 0; t < o; ++t) {
+ let n = i[t].selectorText,
+ o = i[t].style;
+ if (!o) continue;
+ let r = o.cssText;
+ e.matches(n) && e.style && (e.style.cssText += r);
+ for (let t of e.querySelectorAll(n)) t.style && (t.style.cssText += r);
+ }
+ return e;
+ },
+ printingMailingFrameElementId: function () {
+ return "printing-mailing-frame";
+ },
+ canLoadNextPage: function () {
+ if (this.readerOperationMode != ReaderOperationMode.Normal) return !0;
+ let e = document.querySelectorAll(".page"),
+ t = e[e.length - 1].getBoundingClientRect(),
+ n = this._distanceFromBottomOfArticleToStartLoadingNextPage();
+ return !!isNaN(n) || !(t.bottom - window.scrollY > n);
+ },
+ setCachedNextPageURL: function (e) {
+ e
+ ? ((this.cachedNextPageURL = e),
+ ReaderJSController.didChangeNextPageLoadingState(!1))
+ : this.setNextPageURL(e);
+ },
+ loadNextPage: function () {
+ null != this.cachedNextPageURL &&
+ (this.setNextPageURL(this.cachedNextPageURL),
+ (this.cachedNextPageURL = null),
+ ReaderJSController.didChangeNextPageLoadingState(!0));
+ },
+ resumeCachedNextPageLoadIfNecessary: function () {
+ ReaderJS.cachedNextPageURL &&
+ ReaderJS.canLoadNextPage() &&
+ ReaderJS.loadNextPage();
+ },
+ setDocumentIsVisible: function (e) {
+ ((this._documentIsVisible = e),
+ this._readerForegroundednessMayHaveChanged(),
+ e && ReaderAppearanceJS.layOutContent());
+ },
+ setReaderIsActive: function (e) {
+ ((this._readerIsActive = e),
+ this._readerForegroundednessMayHaveChanged());
+ },
+ readerIsForeground: function () {
+ return this._documentIsVisible && this._readerIsActive;
+ },
+ _readerForegroundednessMayHaveChanged: function () {
+ let e = this.readerIsForeground();
+ this._readerIsForeground !== e &&
+ (e ? this.readerWillBecomeVisible() : this.readerWillEnterBackground(),
+ ReadingPositionStabilizerJS.setTrackPosition(e),
+ (this._readerIsForeground = e));
+ },
+ readerWillBecomeVisible: function () {
+ (document.body.classList.remove("cached"),
+ this.resumeCachedNextPageLoadIfNecessary());
+ for (let e of document.querySelectorAll("iframe")) {
+ let t = this.cachedIframeURLMap.get(e);
+ t && ((e.src = t), this.cachedIframeURLMap.delete(e));
+ }
+ this._readerIsActive &&
+ requestAnimationFrame(function () {
+ ReadingPositionStabilizerJS.applyScrollPositionFromOriginalPage();
+ });
+ },
+ readerWillEnterBackground: function () {
+ (ReaderJS.isLoadingNextPage() ||
+ ReaderJS.loadingNextPageManuallyStopped) &&
+ this.pauseLoadingNextPage();
+ for (let e of document.querySelectorAll("audio")) e.pause();
+ for (let e of document.querySelectorAll("video"))
+ e.hasAttribute("data-reader-silent-looped-animation") || e.pause();
+ for (let e of document.querySelectorAll("iframe")) {
+ e.src &&
+ (this.cachedIframeURLMap.set(e, e.src), e.removeAttribute("src"));
+ }
+ },
+ _fixImageElementsWithinPictureElements: function () {
+ requestAnimationFrame(function () {
+ let e = !1,
+ t = document.querySelectorAll("#article picture img");
+ for (let n of t) {
+ let t = n.previousElementSibling;
+ if (t) (n.remove(), t.after(n), (e = !0));
+ else {
+ let t = n.parentElement;
+ (n.remove(), t.appendChild(n), (e = !0));
+ }
+ }
+ e && ReaderAppearanceJS.layOutContent();
+ });
+ },
+ serializedDocumentElementForPrintingOrMailing: async function (e) {
+ const t = Promise.withResolvers();
+ ((globalThis.ReaderJSController = new (class {
+ readerOperationMode() {
+ return ReaderOperationMode.OffscreenFetching;
+ }
+ doneLoadingReaderPage() {
+ t.resolve();
+ }
+ initialConfiguration() {
+ return e;
+ }
+ articleScrolled() {}
+ cachedTopScrollOffset() {
+ return 0;
+ }
+ clearNextPageArticleFinder() {}
+ contentIsReadyForDisplay() {}
+ didChangeNextPageLoadingState() {}
+ goBack() {}
+ goForward() {}
+ initialArticleScrollPosition() {
+ return null;
+ }
+ isInStickyMode() {
+ return !1;
+ }
+ log() {}
+ makeFontAvailableIfNecessary() {}
+ maxDistanceForLoadingNextPage() {}
+ nextPageArticleFinder() {}
+ nextPageLoadComplete() {}
+ prepareNextPageFrame() {}
+ setArticleBaseURLString(e) {}
+ replaceSimpleTweetsWithRichTweets() {}
+ requestDeactivationFromUserAction() {}
+ requestOnDeviceSummary() {}
+ openSummarizationSettings() {}
+ reportReaderEvent() {}
+ })()),
+ ReaderJS.loadSerializedArticle(
+ await readerViewMessageHandler.postMessage({
+ command: "callArticleFinder",
+ method: "serializableArticle",
+ }),
+ ),
+ await t.promise);
+ const n = ReaderJS.sanitizedFullArticleFrame();
+ if (!n?.contentDocument?.documentElement)
+ throw new Error("Unable to render article");
+ return webkit.createNodeSnapshot(n.contentDocument.documentElement, {
+ deep: !0,
+ });
+ },
+ }));
+let fetchNextPageArticlePromiseWithCanceller = null;
+((ReadingPositionStabilizer = function () {
+ ((this.elementTouchingTopOfViewport = null),
+ (this.elementTouchingTopOfViewportOffsetFromTopOfElementRatio = 0),
+ (this._trackingScrolling = !1),
+ (this._hasEverScrolled = !1));
+}),
+ (ReadingPositionStabilizer.prototype = {
+ initialize: function () {
+ this.setTrackPosition(!0);
+ const e = 250;
+ ((this._checkForUpdatedContentSoon =
+ this.debounce(e)._checkForUpdatedContentNow),
+ (this.windowDidResize = this.debounce(e)._windowDidResize));
+ },
+ setTrackPosition: function (e) {
+ if (e === this._trackingScrolling) return;
+ this._trackingScrolling = e;
+ const t = 250;
+ (this._debouncedDidScroll ||
+ (this._debouncedDidScroll = this.debounce(t)._didScroll),
+ e
+ ? window.addEventListener("scroll", this._debouncedDidScroll, {
+ capture: !1,
+ passive: !0,
+ })
+ : window.removeEventListener("scroll", this._debouncedDidScroll, {
+ capture: !1,
+ passive: !0,
+ }));
+ },
+ _windowDidResize: function () {
+ this._hasEverScrolled && this._updatePosition(!1);
+ },
+ contentWasReloaded: function () {
+ this._updatePosition(!1);
+ },
+ _didScroll: function () {
+ this._trackingScrolling &&
+ ((this._hasEverScrolled = !0), this._updatePosition(!1));
+ },
+ _updatePosition: function (e = !0) {
+ let t = firstContentElementAfterTopOfViewport();
+ if (!t) return void (this.elementTouchingTopOfViewport = null);
+ this.elementTouchingTopOfViewport = t;
+ let n = this.elementTouchingTopOfViewport.getBoundingClientRect();
+ ((this.elementTouchingTopOfViewportOffsetFromTopOfElementRatio =
+ n.height > 0 ? n.top / n.height : 0),
+ this._originalPageScrollSyncAndContentRefreshIsAllowed() &&
+ ReaderJS.readerIsForeground() &&
+ (this._pushScrollPositionToOriginalPage(),
+ e && this._checkForUpdatedContentSoon()));
+ },
+ _pushScrollPositionToOriginalPage: function () {
+ const e = ReaderJSController.originalArticleFinder(),
+ [t, n] = this.uniqueIDAndScrollRatioOfElementPinnedToTop();
+ t && e.scrollToElementWithUniqueID(t, n);
+ },
+ applyScrollPositionFromOriginalPage: async function () {
+ let e =
+ ReaderJSController.originalArticleFinder().uniqueIDAndScrollRatioOfElementPinnedToTop();
+ e instanceof Promise && (e = await e);
+ const [t, n] = e;
+ t && this.tryToScrollToUniqueIDAndRatio(t, n);
+ },
+ _checkForUpdatedContentNow: async function () {
+ await ReaderJS.reloadArticlePreservingScrollPositionIfArticleNodeContentHasChanged();
+ },
+ restorePosition: function () {
+ if (!this.elementTouchingTopOfViewport) return;
+ let e = this.elementTouchingTopOfViewport.getBoundingClientRect(),
+ t =
+ document.scrollingElement.scrollTop +
+ e.top -
+ e.height *
+ this.elementTouchingTopOfViewportOffsetFromTopOfElementRatio;
+ (t > 0 && (document.scrollingElement.scrollTop = t),
+ this._updatePosition());
+ },
+ uniqueIDAndScrollRatioOfElementPinnedToTop: function () {
+ if (!this.elementTouchingTopOfViewport) return [null, null];
+ return [
+ this.elementTouchingTopOfViewport.getAttribute(
+ READER_UNIQUE_ID_ATTRIBUTE_KEY,
+ ),
+ this.elementTouchingTopOfViewportOffsetFromTopOfElementRatio,
+ ];
+ },
+ tryToScrollToUniqueIDAndRatio: function (e, t) {
+ const n = document.querySelector(
+ "[" + READER_UNIQUE_ID_ATTRIBUTE_KEY + "='" + e + "']",
+ );
+ if (!n) return !1;
+ const i = n.getBoundingClientRect();
+ return (
+ !!i.height &&
+ ((document.scrollingElement.scrollTop =
+ i.top - t * i.height + window.scrollY),
+ this._updatePosition(!1),
+ !0)
+ );
+ },
+ _originalPageScrollSyncAndContentRefreshIsAllowed: function () {
+ return !document.body.classList.contains("watch");
+ },
+ }));
+const SummaryFeedbackActionType = { ThumbsUp: 0, ThumbsDown: 1, Concern: 2 };
+document.addEventListener("visibilitychange", handleVisibilityChange, !1);
+var ContentAwareScrollerJS = new ContentAwareScroller(),
+ ReaderAppearanceJS = new ReaderAppearanceController(),
+ ReadingPositionStabilizerJS = new ReadingPositionStabilizer(),
+ ReaderJS = new ReaderController();
+window.addEventListener(
+ "load",
+ async function () {
+ function e() {
+ window.dispatchEvent(new CustomEvent("readerLoaded"));
+ }
+ if (!isReaderViewInSeparateProcess) return (ReaderJS.loaded(), void e());
+ (ReaderJS.setOriginalURL(
+ await readerViewMessageHandler.postMessage({
+ command: "callArticleFinder",
+ method: "baseURI",
+ }),
+ ),
+ ReaderJS.loadSerializedArticle(
+ await readerViewMessageHandler.postMessage({
+ command: "callArticleFinder",
+ method: "serializableArticle",
+ }),
+ ),
+ e());
+ },
+ !1,
+);
+0;
diff --git a/27.0/js/reader/ReaderSharedUINormalWorld.js b/27.0/js/reader/ReaderSharedUINormalWorld.js
new file mode 100644
index 0000000..9be54c8
--- /dev/null
+++ b/27.0/js/reader/ReaderSharedUINormalWorld.js
@@ -0,0 +1,38 @@
+//# sourceURL=__InjectedScript_ReaderSharedUINormalWorld.js
+/* Copyright (c) 2026 Apple Inc. All rights reserved. */
+function loadTwitterJavaScript() {
+ window.twttr ||
+ (window.twttr = (function (e, t, r) {
+ var i,
+ a,
+ d = e.getElementsByTagName(t)[0];
+ if (!e.getElementById(r))
+ return (
+ ((a = e.createElement(t)).id = r),
+ (a.src = "https://platform.twitter.com/widgets.js"),
+ d.parentNode.insertBefore(a, d),
+ window.twttr ||
+ (i = {
+ _e: [],
+ ready: function (e) {
+ i._e.push(e);
+ },
+ })
+ );
+ })(document, "script", "twitter-wjs"));
+}
+function richTweetWasCreatedFromSimpleTweet(e) {
+ e.parentNode.querySelector(".simple-tweet").classList.add("hidden");
+}
+function replaceSimpleTweetsWithRichTweets(e) {
+ let t = document.querySelectorAll("[data-reader-tweet-id]");
+ t.length &&
+ (loadTwitterJavaScript(),
+ twttr.ready(function (r) {
+ for (let i of t)
+ r.widgets
+ .createTweet(i.getAttribute("data-reader-tweet-id"), i, e)
+ .then(richTweetWasCreatedFromSimpleTweet);
+ }));
+}
+0;
diff --git a/27.0/js/schema/SchemaDataExtractor.js b/27.0/js/schema/SchemaDataExtractor.js
new file mode 100644
index 0000000..0768939
--- /dev/null
+++ b/27.0/js/schema/SchemaDataExtractor.js
@@ -0,0 +1,249 @@
+//# sourceURL=__InjectedScript_SchemaDataExtractor.js
+/* Copyright (c) 2026 Apple Inc. All rights reserved. */
+var SchemaDataExtractor = function () {};
+((SchemaDataExtractor.validAddressProperties = {
+ addressCountry: 1,
+ addressLocality: 1,
+ addressRegion: 1,
+ postOfficeBoxNumber: 1,
+ postalCode: 1,
+ streetAddress: 1,
+}),
+ (SchemaDataExtractor.validParentSchemaTypes = {
+ "http://schema.org/Person": 1,
+ "https://schema.org/Person": 1,
+ "http://schema.org/LocalBusiness": 1,
+ "https://schema.org/LocalBusiness": 1,
+ "http://schema.org/Organization": 1,
+ "https://schema.org/Organization": 1,
+ "http://schema.org/Restaurant": 1,
+ "https://schema.org/Restaurant": 1,
+ "http://schema.org/Corporation": 1,
+ "https://schema.org/Corporation": 1,
+ "http://schema.org/EducationalOrganization": 1,
+ "https://schema.org/EducationalOrganization": 1,
+ "http://schema.org/GovernmentOrganization": 1,
+ "https://schema.org/GovernmentOrganization": 1,
+ "http://schema.org/MedicalOrganization": 1,
+ "https://schema.org/MedicalOrganization": 1,
+ "http://schema.org/AnimalShelter": 1,
+ "https://schema.org/AnimalShelter": 1,
+ "http://schema.org/AutomotiveBusiness": 1,
+ "https://schema.org/AutomotiveBusiness": 1,
+ "http://schema.org/ChildCare": 1,
+ "https://schema.org/ChildCare": 1,
+ "http://schema.org/DryCleaningOrLaundry": 1,
+ "https://schema.org/DryCleaningOrLaundry": 1,
+ "http://schema.org/EmergencyService": 1,
+ "https://schema.org/EmergencyService": 1,
+ "http://schema.org/EmploymentAgency": 1,
+ "https://schema.org/EmploymentAgency": 1,
+ "http://schema.org/EntertainmentBusiness": 1,
+ "https://schema.org/EntertainmentBusiness": 1,
+ "http://schema.org/FinancialService": 1,
+ "https://schema.org/FinancialService": 1,
+ "http://schema.org/FoodEstablishment": 1,
+ "https://schema.org/FoodEstablishment": 1,
+ "http://schema.org/GovernmentOffice": 1,
+ "https://schema.org/GovernmentOffice": 1,
+ "http://schema.org/HealthAndBeautyBusiness": 1,
+ "https://schema.org/HealthAndBeautyBusiness": 1,
+ "http://schema.org/HomeAndConstructionBusiness": 1,
+ "https://schema.org/HomeAndConstructionBusiness": 1,
+ "http://schema.org/InternetCafe": 1,
+ "https://schema.org/InternetCafe": 1,
+ "http://schema.org/LegalService": 1,
+ "https://schema.org/LegalService": 1,
+ "http://schema.org/Library": 1,
+ "https://schema.org/Library": 1,
+ "http://schema.org/LodgingBusiness": 1,
+ "https://schema.org/LodgingBusiness": 1,
+ "http://schema.org/ProfessionalService": 1,
+ "https://schema.org/ProfessionalService": 1,
+ "http://schema.org/RadioStation": 1,
+ "https://schema.org/RadioStation": 1,
+ "http://schema.org/RealEstateAgent": 1,
+ "https://schema.org/RealEstateAgent": 1,
+ "http://schema.org/RecyclingCenter": 1,
+ "https://schema.org/RecyclingCenter": 1,
+ "http://schema.org/SelfStorage": 1,
+ "https://schema.org/SelfStorage": 1,
+ "http://schema.org/ShoppingCenter": 1,
+ "https://schema.org/ShoppingCenter": 1,
+ "http://schema.org/SportsActivityLocation": 1,
+ "https://schema.org/SportsActivityLocation": 1,
+ "http://schema.org/Store": 1,
+ "https://schema.org/Store": 1,
+ "http://schema.org/TelevisionStation": 1,
+ "https://schema.org/TelevisionStation": 1,
+ "http://schema.org/TouristInformationCenter": 1,
+ "https://schema.org/TouristInformationCenter": 1,
+ "http://schema.org/TravelAgency": 1,
+ "https://schema.org/TravelAgency": 1,
+ }),
+ (SchemaDataExtractor.validBaseSchemaTypes = {
+ "http://schema.org/PostalAddress": 1,
+ "https://schema.org/PostalAddress": 1,
+ }),
+ (SchemaDataExtractor.containsSchemaOrgKey = "containsSchemaOrg"),
+ (SchemaDataExtractor.containsMicrodataKey = "containsMicrodata"),
+ (SchemaDataExtractor.schemaOrgTypeDomain = "schema.org"),
+ (SchemaDataExtractor.prototype = {
+ isValidParentSchemaType: function (t) {
+ return SchemaDataExtractor.validParentSchemaTypes[t];
+ },
+ isValidBaseSchemaType: function (t) {
+ return SchemaDataExtractor.validBaseSchemaTypes[t];
+ },
+ extractFilteredSchemaValuesFromMicroData: function () {
+ const t = document.querySelectorAll("[itemscope]");
+ let e = [],
+ r = [],
+ a = !1;
+ for (let o of t) {
+ let t = o.getAttribute("itemType");
+ t &&
+ (this.isValidParentSchemaType(t) && e.push(o),
+ this.isValidBaseSchemaType(t) && r.push(o),
+ !a &&
+ t.includes(SchemaDataExtractor.schemaOrgTypeDomain) &&
+ (a = !0));
+ }
+ let o = {};
+ if (!a) return o;
+ if (((o[SchemaDataExtractor.containsSchemaOrgKey] = !0), 1 !== r.length))
+ return o;
+ const s = r[0],
+ c = s.getAttribute("itemtype");
+ if (!c || -1 === c.indexOf("PostalAddress")) return o;
+ const n = s.querySelectorAll("[itemprop]");
+ for (let t of n) {
+ let e = t.getAttribute("itemprop");
+ e &&
+ SchemaDataExtractor.validAddressProperties[e] &&
+ (o[e] = t.textContent ? t.textContent : t.getAttribute("content"));
+ }
+ let h = s.parentNode;
+ for (; null !== h && -1 === e.indexOf(h);) h = h.parentNode;
+ const i = s.querySelectorAll("[itemprop='telephone']");
+ if (null !== h) {
+ let t = h.querySelectorAll("[itemprop='name']");
+ (t.length && (o.name = t[0].textContent),
+ 0 === i.length && (i = h.querySelectorAll("[itemprop='telephone']")));
+ }
+ return (i.length && (o.telephone = i[0].textContent), o);
+ },
+ extractAllSchemaValuesFromMicroData: function () {
+ const t = document.querySelectorAll("[itemscope]");
+ let e = [],
+ r = !1;
+ for (let a of t) {
+ const t = a.getAttribute("itemType");
+ t &&
+ (e.push(a),
+ !r &&
+ t.includes(SchemaDataExtractor.schemaOrgTypeDomain) &&
+ (r = !0));
+ }
+ let a = {};
+ if (!r) return a;
+ if (((a[SchemaDataExtractor.containsSchemaOrgKey] = !0), 1 !== e.length))
+ return a;
+ const o = e[0],
+ s = (o.getAttribute("itemtype"), o.querySelectorAll("[itemprop]"));
+ for (let t of s) {
+ let e = t.getAttribute("itemprop");
+ e && (a[e] = t.textContent ? t.textContent : t.getAttribute("content"));
+ }
+ return a;
+ },
+ extractFilteredSchemaValuesFromJSONLD: function () {
+ let t = {};
+ const e = document.querySelector('script[type="application/ld+json"]');
+ if (!e) return t;
+ let r;
+ try {
+ r = JSON.parse(e.text);
+ } catch (e) {
+ return t;
+ }
+ let a = r["@context"];
+ if ("http://schema.org" !== a && "https://schema.org" !== a) return t;
+ t[SchemaDataExtractor.containsSchemaOrgKey] = !0;
+ let o = [];
+ for (o.unshift(r); o.length;) {
+ let e = o.shift();
+ if (null != e) {
+ if (
+ (Object.prototype.hasOwnProperty.call(e, "telephone") &&
+ (t.telephone = e.telephone),
+ "PostalAddress" === e["@type"])
+ ) {
+ for (let r in e)
+ SchemaDataExtractor.validAddressProperties[r] && (t[r] = e[r]);
+ break;
+ }
+ for (let t in e) {
+ let r = e[t];
+ "object" == typeof r && o.push(r);
+ }
+ }
+ }
+ return t;
+ },
+ extractAllSchemaValuesFromJSONLD: function () {
+ let t = {};
+ const e = document.querySelector('script[type="application/ld+json"]');
+ if (!e) return t;
+ let r, a;
+ try {
+ r = JSON.parse(e.text);
+ } catch (e) {
+ return t;
+ }
+ if (
+ ((a = Array.isArray(r) ? r[0]["@context"] : r["@context"]),
+ "http://schema.org" !== a && "https://schema.org" !== a)
+ )
+ return t;
+ t[SchemaDataExtractor.containsSchemaOrgKey] = !0;
+ let o = [];
+ o.unshift(r);
+ const s = o.shift();
+ for (let e in s) t[e] = s[e];
+ return t;
+ },
+ resultHasAddressOrTelephone: function (t) {
+ return (
+ null != t &&
+ (Object.prototype.hasOwnProperty.call(t, "streetAddress") ||
+ Object.prototype.hasOwnProperty.call(t, "telephone"))
+ );
+ },
+ resultHasSchemaOrgInfo: function (t) {
+ return (
+ null != t &&
+ Object.prototype.hasOwnProperty.call(
+ t,
+ SchemaDataExtractor.containsSchemaOrgKey,
+ )
+ );
+ },
+ extractSchemaValuesFromSchemaOrg: function () {
+ let t = this.extractAllSchemaValuesFromMicroData(),
+ e = this.extractFilteredSchemaValuesFromMicroData();
+ return (
+ this.resultHasAddressOrTelephone(e) ||
+ (e = this.extractFilteredSchemaValuesFromJSONLD()),
+ this.resultHasAddressOrTelephone(t) ||
+ (t = this.extractAllSchemaValuesFromJSONLD()),
+ (this.resultHasAddressOrTelephone(e) ||
+ this.resultHasSchemaOrgInfo(e)) &&
+ (e.url = location.href),
+ [e, t]
+ );
+ },
+ }),
+ "undefined" == typeof SchemaDataExtractorJS &&
+ (SchemaDataExtractorJS = new SchemaDataExtractor()),
+ SchemaDataExtractorJS.extractSchemaValuesFromSchemaOrg());
diff --git a/27.0/js/schema/SchemaOrgMarkupChecker.js b/27.0/js/schema/SchemaOrgMarkupChecker.js
new file mode 100644
index 0000000..702321b
--- /dev/null
+++ b/27.0/js/schema/SchemaOrgMarkupChecker.js
@@ -0,0 +1,20 @@
+//# sourceURL=__InjectedScript_SchemaOrgMarkupChecker.js
+/* Copyright (c) 2026 Apple Inc. All rights reserved. */
+(function () {
+ const e = "schema.org";
+ var t = document.querySelectorAll('script[type="application/ld+json"]');
+ for (let o of t) {
+ var r;
+ try {
+ r = JSON.parse(o.text);
+ } catch (e) {
+ continue;
+ }
+ if (r["@context"].toLowerCase().includes(e)) return !0;
+ }
+ var o = document.querySelectorAll("[itemscope]");
+ for (let t of o) {
+ var c = t.getAttribute("itemType");
+ if (c && c.toLowerCase().includes(e)) return !0;
+ }
+})();
diff --git a/27.0/js/search/OpenSearchURLFinder.js b/27.0/js/search/OpenSearchURLFinder.js
new file mode 100644
index 0000000..6889c54
--- /dev/null
+++ b/27.0/js/search/OpenSearchURLFinder.js
@@ -0,0 +1,20 @@
+//# sourceURL=__InjectedScript_OpenSearchURLFinder.js
+/* Copyright (c) 2026 Apple Inc. All rights reserved. */
+(function () {
+ "use strict";
+ function e() {
+ if (document.head) {
+ var e = document.head.getElementsByTagName("link");
+ for (const t of e)
+ if (
+ "search" === t.getAttribute("rel") &&
+ "application/opensearchdescription+xml" === t.getAttribute("type")
+ )
+ return void window.webkit.messageHandlers.quickWebsiteSearchFoundOpenSearchURL.postMessage(
+ t.href,
+ );
+ }
+ }
+ e();
+})();
+0;
diff --git a/27.0/js/search/QuickWebsiteSearchURLDetector.js b/27.0/js/search/QuickWebsiteSearchURLDetector.js
new file mode 100644
index 0000000..32465b6
--- /dev/null
+++ b/27.0/js/search/QuickWebsiteSearchURLDetector.js
@@ -0,0 +1,190 @@
+//# sourceURL=__InjectedScript_QuickWebsiteSearchURLDetector.js
+/* Copyright (c) 2026 Apple Inc. All rights reserved. */
+(function () {
+ "use strict";
+ function e(e) {
+ return encodeURIComponent(e).replace(/%20/g, "+");
+ }
+ function t(e) {
+ return new RegExp("(^|.)" + e.replaceAll(".", "\\.") + "$");
+ }
+ function n(e) {
+ return t(e).test(document.location.hostname);
+ }
+ function r(e) {
+ if (e instanceof HTMLTextAreaElement) return !0;
+ if (!(e instanceof HTMLInputElement)) return !1;
+ const t = {
+ date: !0,
+ "datetime-local": !0,
+ email: !0,
+ isindex: !0,
+ month: !0,
+ number: !0,
+ password: !0,
+ search: !0,
+ tel: !0,
+ telephone: !0,
+ text: !0,
+ time: !0,
+ url: !0,
+ week: !0,
+ };
+ var n = e.type;
+ return !n || n in t;
+ }
+ function u(e, t) {
+ try {
+ return window.collectMatchingElementsInFlatTree(e, t);
+ } catch (e) {
+ return [];
+ }
+ }
+ function i(e) {
+ e.elements;
+ return u(
+ e,
+ "button, fieldset, input:not([type='image']), object, output, select, textarea",
+ );
+ }
+ function o(e) {
+ var t = e.localName;
+ return "string" == typeof t || "string" == typeof (t = e.nodeName)
+ ? t
+ : void 0;
+ }
+ function c(e) {
+ let t = e.options,
+ n = t.length;
+ for (var r = 0; r < n; ++r) {
+ let n = t[r];
+ if (n.selected !== n.defaultSelected) {
+ if (n.defaultSelected) return !1;
+ if (e.multiple || r) return !1;
+ }
+ }
+ return !0;
+ }
+ function l(e) {
+ return (
+ (e instanceof HTMLButtonElement || e instanceof HTMLInputElement) &&
+ e.type &&
+ "submit" === e.type
+ );
+ }
+ function s(e) {
+ if (!(e instanceof HTMLInputElement)) return !1;
+ try {
+ if (e.matches(":-webkit-autofill-strong-password")) return !0;
+ } catch (e) {}
+ const t = getComputedStyle(e, null).getPropertyValue(
+ "-webkit-text-security",
+ ),
+ r = e.type;
+ if ("none" !== t || "password" === r) return !0;
+ if (r && "text" !== r) return !1;
+ if (n("ninehours.co.jp")) {
+ let t = e.name;
+ if ("guestPassword" === t || "guestPasswordConfirm" === t) return !0;
+ }
+ return !1;
+ }
+ function a(e) {
+ return e.checked === e.defaultChecked;
+ }
+ function f(e) {
+ return (
+ e instanceof HTMLTextAreaElement &&
+ ("search" === e.getAttribute("type") ||
+ "search" === e.inputMode ||
+ "search" === e.getAttribute("enterkeyhint"))
+ );
+ }
+ function d(e) {
+ const t = o(e).toLowerCase();
+ if ("button" === t || "fieldset" === t) return !0;
+ if ("select" === t) return c(e);
+ if ("input" !== t && !f(e)) return !1;
+ const n = e.type;
+ return "radio" === n || "checkbox" === n
+ ? a(e)
+ : "hidden" === n ||
+ "reset" === n ||
+ "submit" === n ||
+ "button" === n ||
+ "image" === n ||
+ (r(e) && !s(e));
+ }
+ function h(e) {
+ if ("get" !== e.method) return !1;
+ const t = i(e),
+ n = t.length;
+ for (let e = 0; e < n; ++e) if (!d(t[e])) return !1;
+ return !0;
+ }
+ function m(e) {
+ let t = [],
+ n = i(e),
+ u = n.length;
+ for (let e = 0; e < u; ++e) {
+ let u = n[e];
+ u.checkVisibility() &&
+ null != u.value &&
+ u.value.length &&
+ r(u) &&
+ t.push(u);
+ }
+ return t;
+ }
+ function p(e) {
+ if (e.disabled) return !1;
+ if (!e.name.length) return !1;
+ if (!e.value.length) return !1;
+ if (e instanceof HTMLSelectElement) return !0;
+ var t = o(e).toLowerCase(),
+ n = e.type;
+ return "button" === t
+ ? "submit" === n
+ : "input" === t &&
+ ("submit" === n ||
+ ("checkbox" === n || "radio" === n
+ ? e.checked
+ : "hidden" === n || r(e)));
+ }
+ function g(t) {
+ const n = t.form;
+ if (!n) return null;
+ let r = n.getAttribute("action");
+ if (!r || !r.length) return null;
+ if (!/^https?:/i.test(n.action)) return null;
+ let u = null,
+ o = "",
+ c = i(n),
+ s = c.length;
+ for (let n = 0; n < s; ++n) {
+ let r = c[n];
+ if ((r === t || p(r)) && (!l(r) || (u || (u = r), r === u))) {
+ o.length && (o += "&");
+ var a = r === t ? "{searchTerms}" : e(r.value);
+ o += e(r.name) + "=" + a;
+ }
+ }
+ let f = document.createElement("a");
+ return ((f.href = n.action), (f.search = o), f.href);
+ }
+ function b(e) {
+ const t = e.target;
+ if (!h(t)) return;
+ const n = m(t);
+ if (n.length > 1) return;
+ const r = n[0];
+ if (!r) return;
+ const u = g(r);
+ u &&
+ window.webkit.messageHandlers.quickWebsiteSearchDetectedSearchURL.postMessage(
+ u,
+ );
+ }
+ window.addEventListener("submit", b);
+})();
+0;
diff --git a/27.0/js/search/SearchEngineBannerDetector.js b/27.0/js/search/SearchEngineBannerDetector.js
new file mode 100644
index 0000000..b80051f
--- /dev/null
+++ b/27.0/js/search/SearchEngineBannerDetector.js
@@ -0,0 +1,246 @@
+//# sourceURL=__InjectedScript_SearchEngineBannerDetector.js
+/* Copyright (c) 2026 Apple Inc. All rights reserved. */
+(function () {
+ function e(e) {
+ try {
+ var t =
+ window.webkit &&
+ window.webkit.messageHandlers &&
+ window.webkit.messageHandlers.safariSearchEngineBannerDetection;
+ t && t.postMessage({ kind: e, category: M });
+ } catch (e) {}
+ }
+ function t() {
+ if (C) {
+ try {
+ C.disconnect();
+ } catch (e) {}
+ C = null;
+ }
+ q.length = 0;
+ }
+ function n() {
+ if (_) {
+ try {
+ _.disconnect();
+ } catch (e) {}
+ _ = null;
+ }
+ if (B) {
+ try {
+ document.removeEventListener("pointerdown", B, !0);
+ } catch (e) {}
+ B = null;
+ }
+ D.length = 0;
+ }
+ function r() {
+ (t(), n());
+ }
+ function i(e) {
+ if (!e || !e.getAttribute) return null;
+ var t = e.getAttribute("href") || "";
+ return 0 === t.indexOf("googlechrome://") ||
+ (0 === t.indexOf("intent://") &&
+ -1 !== t.indexOf("scheme=googlechrome")) ||
+ -1 !== t.indexOf("id535886823")
+ ? E
+ : 0 === t.indexOf("comgoogleapp://") || -1 !== t.indexOf("id284815942")
+ ? O
+ : null;
+ }
+ function o(e) {
+ for (
+ var t = e && e.querySelectorAll ? e.querySelectorAll("a[href]") : [],
+ n = 0;
+ n < t.length;
+ n++
+ ) {
+ var r = i(t[n]);
+ if (r) return r;
+ }
+ return null;
+ }
+ function a(e) {
+ return null !== o(e);
+ }
+ function u(e) {
+ var t = o(e);
+ return (
+ t || (-1 !== ((e && e.textContent) || "").indexOf("Chrome") ? E : "other")
+ );
+ }
+ function d(e) {
+ return (
+ !(!e || !e.isConnected) &&
+ (!e.getAttribute || "true" !== e.getAttribute("aria-hidden"))
+ );
+ }
+ function l(e) {
+ var t = e.ownerDocument && e.ownerDocument.defaultView;
+ if (!t) return !1;
+ var n = t.getComputedStyle(e);
+ return !!n && "hidden" !== n.visibility && "none" !== n.display;
+ }
+ function c(e) {
+ return d(e) && l(e);
+ }
+ function f(e) {
+ if (!e || !e.getBoundingClientRect) return !1;
+ var t = e.getBoundingClientRect();
+ return t.width > 0 && t.height > 0;
+ }
+ function s(e) {
+ d(e) &&
+ ("promo_label_id" !==
+ (e.getAttribute && e.getAttribute("aria-labelledby"))
+ ? a(e) && l(e) && b(e)
+ : l(e) && b(e));
+ }
+ function g(e) {
+ for (
+ var t = e.querySelectorAll
+ ? e.querySelectorAll('[data-async-type="hpba"]')
+ : [],
+ n = 0;
+ n < t.length;
+ n++
+ ) {
+ var r = t[n];
+ if (d(r) && r.children && r.children.length > 0 && l(r) && f(r))
+ return void b(r);
+ }
+ }
+ function h(e) {
+ if (
+ !L &&
+ e &&
+ e.querySelectorAll &&
+ !(
+ 1 === e.nodeType &&
+ e.matches &&
+ e.matches('[role="dialog"]') &&
+ (s(e), L)
+ )
+ ) {
+ for (
+ var t = e.querySelectorAll('[role="dialog"]'), n = 0;
+ n < t.length;
+ n++
+ )
+ if ((s(t[n]), L)) return;
+ g(e);
+ }
+ }
+ function v() {
+ if (((k = !1), L)) q.length = 0;
+ else {
+ var e = q;
+ q = [];
+ for (var t = 0; t < e.length && !L; t++) h(e[t]);
+ }
+ }
+ function m(e) {
+ if (!L && e && (q.push(e), !k)) {
+ k = !0;
+ var t = window.requestIdleCallback;
+ t ? t(v, { timeout: 500 }) : setTimeout(v, 16);
+ }
+ }
+ function b(n) {
+ L || ((L = !0), (M = u(n)), e("appearance"), t(), p(n));
+ }
+ function w() {
+ x || ((x = !0), e("dismissed"), n());
+ }
+ function y() {
+ if (!T && ((T = !0), e("interaction"), B)) {
+ try {
+ document.removeEventListener("pointerdown", B, !0);
+ } catch (e) {}
+ B = null;
+ }
+ }
+ function p(e) {
+ e &&
+ (D.push(e),
+ (B = function (e) {
+ if (!T) {
+ var t = e.target;
+ if (t)
+ for (var n = 0; n < D.length; n++) {
+ var r = D[n];
+ if (r.contains && r.contains(t)) return void y();
+ }
+ }
+ }),
+ document.addEventListener("pointerdown", B, !0),
+ (_ = new MutationObserver(function (e) {
+ if (!x) {
+ for (var t = !1, n = 0; n < e.length; n++)
+ if ("attributes" === e[n].type) {
+ t = !0;
+ break;
+ }
+ for (var r = 0; r < D.length; r++) if (t ? c(D[r]) : d(D[r])) return;
+ w();
+ }
+ })).observe(document.documentElement, { childList: !0, subtree: !0 }),
+ _.observe(e, {
+ attributes: !0,
+ attributeFilter: ["aria-hidden", "style", "class", "hidden"],
+ }));
+ }
+ function A() {
+ function e() {
+ setTimeout(t, S);
+ }
+ (h(document),
+ window.addEventListener("pagehide", r, { once: !0 }),
+ L ||
+ ((C = new MutationObserver(function (e) {
+ if (!L)
+ for (var t = 0; t < e.length; t++) {
+ var n = e[t];
+ if (
+ "attributes" === n.type &&
+ n.target &&
+ 1 === n.target.nodeType
+ )
+ m(n.target);
+ else if (n.addedNodes)
+ for (var r = 0; r < n.addedNodes.length; r++) {
+ var i = n.addedNodes[r];
+ 1 === i.nodeType && m(i);
+ }
+ }
+ })).observe(document.documentElement, {
+ childList: !0,
+ subtree: !0,
+ attributes: !0,
+ attributeFilter: ["aria-hidden"],
+ }),
+ "complete" === document.readyState
+ ? e()
+ : window.addEventListener("load", e, { once: !0 })));
+ }
+ if (window.__safariSearchEngineBannerDetectorInstalled) return;
+ window.__safariSearchEngineBannerDetectorInstalled = !0;
+ var S = 1e4;
+ const E = "chrome",
+ O = "googleApp";
+ var L = !1,
+ x = !1,
+ C = null,
+ q = [],
+ k = !1,
+ D = [],
+ _ = null,
+ B = null,
+ T = !1,
+ M = null;
+ "loading" === document.readyState
+ ? document.addEventListener("DOMContentLoaded", A, { once: !0 })
+ : A();
+})();
+0;
diff --git a/27.0/js/translation/Translation.js b/27.0/js/translation/Translation.js
new file mode 100644
index 0000000..39243b0
--- /dev/null
+++ b/27.0/js/translation/Translation.js
@@ -0,0 +1,6 @@
+//# sourceURL=__InjectedScript_Translation.js
+/* Copyright (c) 2026 Apple Inc. All rights reserved. */
+function updateLanguageAttributesForTranslation(n) {
+ document.documentElement.lang && (document.documentElement.lang = n);
+}
+0;
diff --git a/27.0/js/utilities/NodePath.js b/27.0/js/utilities/NodePath.js
new file mode 100644
index 0000000..02cddbb
--- /dev/null
+++ b/27.0/js/utilities/NodePath.js
@@ -0,0 +1,750 @@
+//# sourceURL=__InjectedScript_NodePath.js
+/* Copyright (c) 2026 Apple Inc. All rights reserved. */
+// Copyright (C) 2023-2024 Apple Inc. All rights reserved.
+"use strict";
+(globalThis.WAS || (globalThis.WAS = {}),
+ (WAS.NodePath = class {
+ static {
+ function e(e, t) {
+ if (e === t) return 0;
+ for (
+ var n = e.length, o = t.length, a = new Array(n + 1), i = 0;
+ i < n + 1;
+ ++i
+ )
+ ((a[i] = new Array(o + 1)), (a[i][0] = i));
+ for (var s = 0; s < o + 1; ++s) a[0][s] = s;
+ for (s = 1; s < o + 1; ++s) {
+ let o = t[s - 1];
+ for (i = 1; i < n + 1; ++i)
+ if (e[i - 1] === o) a[i][s] = a[i - 1][s - 1];
+ else {
+ var d = a[i - 1][s] + 1,
+ r = a[i][s - 1] + 1,
+ h = a[i - 1][s - 1] + 1;
+ a[i][s] = Math.min(d, r, h);
+ }
+ }
+ return a[n][o];
+ }
+ ((WAS.Assert =
+ WAS.Assert ||
+ class {
+ static isTrue(e, t, ...n) {}
+ static isType(e, ...t) {}
+ static optionalIsType(e, ...t) {}
+ static arrayContentIsType(e, ...t) {}
+ static optionalArrayContentIsType(e, ...t) {}
+ static isEnum(e, t) {}
+ static optionalIsEnum(e, t) {}
+ static isSubclass(e, t) {}
+ static notReached(e, ...t) {}
+ }),
+ Object.defineProperties(CharacterData, {
+ nodePath_isCharacterData: {
+ value(e) {
+ switch (Node.nodePath_nodeType(e)) {
+ case Node.TEXT_NODE:
+ case Node.CDATA_SECTION_NODE:
+ case Node.PROCESSING_INSTRUCTION_NODE:
+ case Node.COMMENT_NODE:
+ return !0;
+ default:
+ return !1;
+ }
+ },
+ },
+ nodePath_data: {
+ value: (e) =>
+ CharacterData.nodePath_isCharacterData(e)
+ ? Object.nodePath_get(e, CharacterData, "data")
+ : null,
+ },
+ }),
+ Object.defineProperties(Document, {
+ nodePath_isDocument: {
+ value: (e) => Node.nodePath_nodeType(e) === Node.DOCUMENT_NODE,
+ },
+ nodePath_defaultView: {
+ value: (e) =>
+ Document.nodePath_isDocument(e)
+ ? Object.nodePath_get(e, Document, "defaultView")
+ : null,
+ },
+ }),
+ Object.defineProperties(Element, {
+ nodePath_isElement: {
+ value: (e) => Node.nodePath_nodeType(e) === Node.ELEMENT_NODE,
+ },
+ nodePath_tagName: {
+ value: (e) =>
+ Element.nodePath_isElement(e)
+ ? Object.nodePath_get(e, Element, "tagName")
+ : null,
+ },
+ nodePath_id: {
+ value: (e) =>
+ Element.nodePath_isElement(e)
+ ? Object.nodePath_get(e, Element, "id")
+ : null,
+ },
+ nodePath_className: {
+ value: (e) =>
+ Element.nodePath_isElement(e)
+ ? Object.nodePath_get(e, Element, "className")
+ : null,
+ },
+ nodePath_shadowRoot: {
+ value: (e) =>
+ Element.nodePath_isElement(e)
+ ? Object.nodePath_get(e, Element, "shadowRoot")
+ : null,
+ },
+ nodePath_querySelectorAll: {
+ value: (e, t) =>
+ Element.nodePath_isElement(e)
+ ? Element.prototype.querySelectorAll.call(e, t)
+ : null,
+ },
+ }),
+ Object.defineProperties(HTMLIFrameElement, {
+ nodePath_isHTMLIFrameElement: {
+ value: (e) =>
+ Node.nodePath_nodeType(e) === Node.ELEMENT_NODE &&
+ "HTMLIFrameElement" === Object.getPrototypeOf(e).constructor.name,
+ },
+ nodePath_contentWindowDocument: {
+ value(e) {
+ if (!HTMLIFrameElement.nodePath_isHTMLIFrameElement(e))
+ return null;
+ try {
+ return Object.nodePath_get(
+ e,
+ HTMLIFrameElement,
+ "contentWindow",
+ ).document;
+ } catch (e) {
+ return null;
+ }
+ },
+ },
+ }),
+ Object.defineProperties(Node, {
+ nodePath_nodeType: {
+ value: (e) => (
+ WAS.Assert.isType(e, Node),
+ Object.nodePath_get(e, Node, "nodeType")
+ ),
+ },
+ nodePath_firstChild: {
+ value: (e) => (
+ WAS.Assert.isType(e, Node),
+ Object.nodePath_get(e, Node, "firstChild")
+ ),
+ },
+ nodePath_nextSibling: {
+ value: (e) => (
+ WAS.Assert.isType(e, Node),
+ Object.nodePath_get(e, Node, "nextSibling")
+ ),
+ },
+ nodePath_previousSibling: {
+ value: (e) => (
+ WAS.Assert.isType(e, Node),
+ Object.nodePath_get(e, Node, "previousSibling")
+ ),
+ },
+ nodePath_childNodes: {
+ value: (e) => (
+ WAS.Assert.isType(e, Node),
+ Object.nodePath_get(e, Node, "childNodes")
+ ),
+ },
+ nodePath_textContent: {
+ value: (e) => (
+ WAS.Assert.isType(e, Node),
+ Object.nodePath_get(e, Node, "textContent")
+ ),
+ },
+ nodePath_cloneNode: {
+ value: (e, { shouldIncludeSubtree: t }) => (
+ WAS.Assert.isType(e, Node),
+ Node.prototype.cloneNode.call(e, t)
+ ),
+ },
+ nodePath_isEmptyTextNode: {
+ value: (e) =>
+ Text.nodePath_isText(e) &&
+ CharacterData.nodePath_data(e)
+ .nodePath_isEmptyExcludingWhitespace,
+ },
+ nodePath_siblingIndexOfNode: {
+ value(e) {
+ let t = 0;
+ for (
+ let n = Node.nodePath_previousSibling(e);
+ n;
+ n = Node.nodePath_previousSibling(n)
+ )
+ Node.nodePath_includeWhenComputingSiblingIndex(n) && ++t;
+ return t;
+ },
+ },
+ nodePath_includeWhenComputingSiblingIndex: {
+ value: (e) =>
+ !(
+ Node.nodePath_isEmptyTextNode(e) ||
+ (Element.nodePath_isElement(e) &&
+ "SCRIPT" === Element.nodePath_tagName(e).toUpperCase())
+ ),
+ },
+ nodePath_immediateSourceMarkupOfNode: {
+ value: (e) =>
+ Node.nodePath_nodeType(e) === Node.DOCUMENT_FRAGMENT_NODE
+ ? null
+ : Node.nodePath_cloneNode(e, { shouldIncludeSubtree: !1 })
+ .outerHTML,
+ },
+ nodePath_immediateInnerTextOfNode: {
+ value(e) {
+ if (!Node.prototype.hasChildNodes.call(e))
+ return Node.nodePath_textContent(e)?.trim();
+ let t = "";
+ for (let n of Node.nodePath_childNodes(e))
+ Text.nodePath_isText(n) &&
+ (t += CharacterData.nodePath_data(n));
+ return t.trim();
+ },
+ },
+ nodePath_getBoundingClientRect: {
+ value(e) {
+ if ((WAS.Assert.isType(e, Node, Range), e instanceof Range))
+ return e.getBoundingClientRect();
+ if (Text.nodePath_isText(e)) {
+ let t = new Range();
+ return (
+ t.setStart(e, 0),
+ t.setEnd(e, CharacterData.nodePath_data(e).length),
+ t.getBoundingClientRect()
+ );
+ }
+ return Element.nodePath_isElement(e)
+ ? Element.prototype.getBoundingClientRect.call(e)
+ : null;
+ },
+ },
+ }),
+ Object.defineProperties(Object, {
+ nodePath_get: {
+ value: (e, t, n) =>
+ Object.getOwnPropertyDescriptor(t.prototype, n)?.get?.call?.(e),
+ },
+ }),
+ Object.defineProperties(Range, {
+ nodePath_fromNode: {
+ value(e) {
+ let t = new Range();
+ return (t.selectNode(e), t);
+ },
+ },
+ nodePath_isSingleElementRange: {
+ value: (e) =>
+ e.startContainer === e.endContainer &&
+ !Text.nodePath_isText(e.commonAncestorContainer) &&
+ 1 === Math.abs(e.endOffset - e.startOffset),
+ },
+ nodePath_singleElementFromRange: {
+ value: (e) =>
+ Range.nodePath_isSingleElementRange(e)
+ ? Node.nodePath_childNodes(e.commonAncestorContainer)[
+ e.startOffset
+ ]
+ : null,
+ },
+ nodePath_startNodeFromRange: {
+ value: (e) =>
+ Text.nodePath_isText(e.startContainer)
+ ? null
+ : Node.nodePath_childNodes(e.startContainer)[e.startOffset],
+ },
+ nodePath_endNodeFromRange: {
+ value: (e) =>
+ Text.nodePath_isText(e.endContainer)
+ ? Node.nodePath_childNodes(e.endContainer)[e.endOffset - 1]
+ : null,
+ },
+ }),
+ Object.defineProperties(Range.prototype, {
+ nodePath_equals: {
+ value(e) {
+ return (
+ this.commonAncestorContainer === e.commonAncestorContainer &&
+ 0 === this.compareBoundaryPoints(Range.START_TO_START, e) &&
+ 0 === this.compareBoundaryPoints(Range.END_TO_END, e)
+ );
+ },
+ },
+ }),
+ Object.defineProperties(ShadowRoot, {
+ nodePath_isShadowRoot: {
+ value: (e) =>
+ Node.nodePath_nodeType(e) === Node.DOCUMENT_FRAGMENT_NODE &&
+ "ShadowRoot" === Object.getPrototypeOf(e).constructor.name,
+ },
+ nodePath_host: {
+ value: (e) =>
+ ShadowRoot.nodePath_isShadowRoot(e)
+ ? Object.nodePath_get(e, ShadowRoot, "host")
+ : null,
+ },
+ }),
+ Object.defineProperties(String, {
+ _nodePath_matchAnyNonWhitespaceRegex: { value: /\S/ },
+ }),
+ Object.defineProperties(String.prototype, {
+ nodePath_isEmptyExcludingWhitespace: {
+ get() {
+ return (
+ !this.length ||
+ !String._nodePath_matchAnyNonWhitespaceRegex.test(this)
+ );
+ },
+ },
+ nodePath_similarityTo: {
+ value(t) {
+ if (!t) return this.length ? 0 : 1;
+ let n = Math.max(this.length, t.length);
+ return n ? (n - e(this, t)) / n : 0;
+ },
+ },
+ }),
+ Object.defineProperties(Text, {
+ nodePath_isText: {
+ value: (e) => Node.nodePath_nodeType(e) === Node.TEXT_NODE,
+ },
+ }));
+ }
+ static ObjectRepresentationCodableInfo = { classPath: "WAS.NodePath" };
+ static #e = class {
+ #t;
+ #n;
+ #o;
+ #a;
+ #i;
+ #s;
+ #d;
+ #r;
+ constructor(
+ e,
+ t,
+ {
+ tag: n,
+ id: o,
+ classes: a,
+ text: i,
+ sourceMarkup: s,
+ boundingClientRect: d,
+ } = {},
+ ) {
+ (WAS.Assert.isType(e, Number),
+ WAS.Assert.isType(t, Number),
+ WAS.Assert.optionalIsType(n, String),
+ WAS.Assert.optionalIsType(o, String),
+ WAS.Assert.optionalIsType(a, String),
+ WAS.Assert.optionalIsType(i, String),
+ WAS.Assert.optionalIsType(s, String),
+ WAS.Assert.optionalIsType(d, Object),
+ (this.#t = e),
+ (this.#n = t),
+ (this.#d = s),
+ (this.#r = d),
+ e === Node.ELEMENT_NODE
+ ? (WAS.Assert.isTrue(n, "Tag must be present for ELEMENT_NODEs"),
+ (this.#o = n),
+ (this.#a = o?.length ? o : void 0),
+ (this.#i = a?.length ? a : void 0),
+ (this.#s = i))
+ : e === Node.TEXT_NODE && (this.#s = i));
+ }
+ static fromNode(e) {
+ WAS.Assert.isType(e, Node);
+ let t = Node.nodePath_nodeType(e),
+ n = Node.nodePath_siblingIndexOfNode(e),
+ o = {};
+ if (Element.nodePath_isElement(e)) {
+ ((o.tag = Element.nodePath_tagName(e)),
+ (o.id = Element.nodePath_id(e)),
+ (o.classes = Element.nodePath_className(e)));
+ let t = Node.nodePath_immediateInnerTextOfNode(e);
+ t.length && (o.text = t);
+ } else
+ Text.nodePath_isText(e) && (o.text = CharacterData.nodePath_data(e));
+ o.sourceMarkup = Node.nodePath_immediateSourceMarkupOfNode(e);
+ let a = Node.nodePath_getBoundingClientRect(e);
+ return (
+ a &&
+ (o.boundingClientRect = {
+ x: a.x,
+ y: a.y,
+ width: a.width,
+ height: a.height,
+ }),
+ new WAS.NodePath.#e(t, n, o)
+ );
+ }
+ static fromObjectRepresentation(e) {
+ return (
+ WAS.Assert.isType(e, Object),
+ new WAS.NodePath.#e(e.type, e.index, e)
+ );
+ }
+ get objectRepresentation() {
+ return {
+ type: this.#t,
+ index: this.#n,
+ tag: this.#o,
+ id: this.#a,
+ classes: this.#i,
+ text: this.#s,
+ sourceMarkup: this.#d,
+ boundingClientRect: this.#r,
+ };
+ }
+ get type() {
+ return this.#t;
+ }
+ get index() {
+ return this.#n;
+ }
+ get tag() {
+ return this.#o;
+ }
+ get id() {
+ return this.#a;
+ }
+ get classes() {
+ return this.#i;
+ }
+ get text() {
+ return this.#s;
+ }
+ toElementCSSSelector() {
+ if (this.type !== Node.ELEMENT_NODE) return null;
+ let e = CSS.escape(this.tag);
+ this.id && (e += `#${CSS.escape(this.id)}`);
+ for (let t of this.classes?.split(" ") ?? [])
+ t.length && (e += `.${CSS.escape(t)}`);
+ return e;
+ }
+ toString() {
+ return JSON.stringify(this.objectRepresentation);
+ }
+ equals(e) {
+ return (
+ WAS.Assert.optionalIsType(e, WAS.NodePath.#e),
+ !!e &&
+ this.#t === e.#t &&
+ this.#n === e.#n &&
+ this.#o === e.#o &&
+ this.#a === e.#a &&
+ this.#i === e.#i &&
+ this.#s === e.#s
+ );
+ }
+ };
+ static #h = 1e3;
+ static #l = 500;
+ static #c = 200;
+ static #m = 200;
+ static #N = 100;
+ static #p = 10;
+ #u;
+ #C;
+ #_;
+ #P;
+ #A;
+ #f;
+ constructor(
+ e,
+ {
+ startContainerAdditionalComponents: t,
+ startContainerOffset: n,
+ endContainerAdditionalComponents: o,
+ endContainerOffset: a,
+ } = {},
+ ) {
+ (WAS.Assert.arrayContentIsType(e, WAS.NodePath.#e),
+ WAS.Assert.isTrue(
+ e[0]?.type == Node.DOCUMENT_NODE,
+ "First path component should always be a document node.",
+ ),
+ (this.#u = e),
+ (this.#_ = t),
+ (this.#P = n),
+ (this.#A = o),
+ (this.#f = a));
+ }
+ static #g(e, t) {
+ WAS.Assert.isType(e, Node);
+ let n = [],
+ o = e,
+ a = 0;
+ for (; o && (++a, !(a > 512));) {
+ let e;
+ for (
+ ;
+ o && (n.push(WAS.NodePath.#e.fromNode(o)), (e = o), o !== t);
+ o = o.parentNode
+ );
+ if (e === t) break;
+ let a = Document.nodePath_defaultView(e);
+ if (a) {
+ o = a.frameElement;
+ continue;
+ }
+ let i = ShadowRoot.nodePath_host(e);
+ i && (o = i);
+ }
+ return n.toReversed();
+ }
+ static from(e, t) {
+ return e instanceof Range
+ ? WAS.NodePath.fromRange(e, t)
+ : WAS.NodePath.fromNode(e, t);
+ }
+ static fromNode(e, t) {
+ let n = new WAS.NodePath(WAS.NodePath.#g(e, t));
+ return ((n.#C = new WeakRef(Range.nodePath_fromNode(e))), n);
+ }
+ static fromRange(e, t) {
+ let n = Range.nodePath_singleElementFromRange(e);
+ if (n) return WAS.NodePath.fromNode(n, t);
+ let o,
+ a,
+ i,
+ s,
+ d = WAS.NodePath.#g(e.commonAncestorContainer, t),
+ r = Range.nodePath_startNodeFromRange(e);
+ r
+ ? (o = WAS.NodePath.#g(r, e.commonAncestorContainer).toSpliced(0, 1))
+ : e.startContainer !== e.commonAncestorContainer
+ ? ((o = WAS.NodePath.#g(
+ e.startContainer,
+ e.commonAncestorContainer,
+ ).toSpliced(0, 1)),
+ (a = e.startOffset))
+ : (o = []);
+ let h = Range.nodePath_endNodeFromRange(e);
+ h
+ ? (i = WAS.NodePath.#g(h, e.commonAncestorContainer).toSpliced(0, 1))
+ : e.endContainer !== e.commonAncestorContainer
+ ? ((i = WAS.NodePath.#g(
+ e.endContainer,
+ e.commonAncestorContainer,
+ ).toSpliced(0, 1)),
+ (s = e.endOffset))
+ : (i = []);
+ let l = new WAS.NodePath(d, {
+ startContainerAdditionalComponents: o,
+ startContainerOffset: a,
+ endContainerAdditionalComponents: i,
+ endContainerOffset: s,
+ });
+ return ((l.#C = new WeakRef(e)), l);
+ }
+ static fromObjectRepresentation(e) {
+ const t = (e) => (
+ WAS.Assert.isType(e, Array),
+ e.map((e) => WAS.NodePath.#e.fromObjectRepresentation(e))
+ );
+ return Array.isArray(e)
+ ? new WAS.NodePath(t(e))
+ : (WAS.Assert.isType(e, Object),
+ new WAS.NodePath(t(e.pathComponents), {
+ startContainerAdditionalComponents:
+ e.startContainerAdditionalComponents
+ ? t(e.startContainerAdditionalComponents)
+ : void 0,
+ startContainerOffset: e.startContainerOffset ?? void 0,
+ endContainerAdditionalComponents: e.endContainerAdditionalComponents
+ ? t(e.endContainerAdditionalComponents)
+ : void 0,
+ endContainerOffset: e.endContainerOffset ?? void 0,
+ }));
+ }
+ get objectRepresentation() {
+ const e = (e) => (
+ WAS.Assert.isType(e, Array),
+ e.map((e) => e.objectRepresentation)
+ );
+ return {
+ pathComponents: e(this.#u),
+ startContainerAdditionalComponents: this.#_ ? e(this.#_) : void 0,
+ startContainerOffset: this.#P,
+ endContainerAdditionalComponents: this.#A ? e(this.#A) : void 0,
+ endContainerOffset: this.#f,
+ };
+ }
+ static nodePathIsKnownFormControlInputElement(e) {
+ let t = e?.pathComponents.at(-1)?.tag?.toUpperCase();
+ switch (t) {
+ case "INPUT":
+ case "SELECT":
+ case "TEXTAREA":
+ return !0;
+ default:
+ return !1;
+ }
+ }
+ get pathComponents() {
+ return this.#u;
+ }
+ get userFriendlySummary() {
+ let e = this.#u.at(-1);
+ return e.type === Node.TEXT_NODE
+ ? e.text.trim()
+ : e.text
+ ? `${e.tag.toLowerCase()}: "${e.text.trim()}"`
+ : e.tag.toLowerCase();
+ }
+ toString() {
+ return JSON.stringify(this.objectRepresentation);
+ }
+ equals(e) {
+ if ((WAS.Assert.optionalIsType(e, WAS.NodePath), !e)) return !1;
+ if (this.#u.length !== e.#u.length) return !1;
+ for (let t = 0; t < this.#u.length; ++t)
+ if (!this.#u[t].equals(e.#u[t])) return !1;
+ if (this.#_?.length !== e.#_?.length) return !1;
+ for (let t = 0; t < this.#_?.length; ++t)
+ if (!this.#_[t].equals(e.#_[t])) return !1;
+ if (this.#A?.length !== e.#A?.length) return !1;
+ for (let t = 0; t < this.#A?.length; ++t)
+ if (!this.#A[t].equals(e.#A[t])) return !1;
+ return this.#P === e.#P && this.#f === e.#f;
+ }
+ resolvedRangeInDocument(e) {
+ let t = this.#C?.deref();
+ if (t?.intersectsNode(e)) return t;
+ if (this.#_ && this.#A) {
+ let t = WAS.NodePath.#E(e, [...this.#u, ...this.#_]),
+ n = WAS.NodePath.#E(e, [...this.#u, ...this.#A]);
+ if (!t || !n) return null;
+ let o = new Range();
+ return (
+ this.#P ? o.setStart(t, this.#P) : o.setStartBefore(t),
+ this.#f ? o.setEnd(n, this.#f) : o.setEndAfter(n),
+ (this.#C = new WeakRef(o)),
+ o
+ );
+ }
+ let n = WAS.NodePath.#E(e, this.#u);
+ if (!n) return null;
+ let o = Range.nodePath_fromNode(n);
+ return ((this.#C = new WeakRef(o)), o);
+ }
+ static #E(e, t) {
+ (WAS.Assert.isType(e, Node),
+ WAS.Assert.isTrue(
+ Document.nodePath_isDocument(e),
+ "Must provide root document node in which to resolve this NodePath.",
+ ));
+ let n = e;
+ e: for (let e = 1; e < t.length && n; ++e) {
+ let o = t[e],
+ a = -1,
+ i = null;
+ const s = () => {
+ n = i;
+ let o = t.length > e ? t[e + 1] : null;
+ return n &&
+ HTMLIFrameElement.nodePath_isHTMLIFrameElement(n) &&
+ o?.type === Node.DOCUMENT_NODE
+ ? (++e,
+ void (n = HTMLIFrameElement.nodePath_contentWindowDocument(n)))
+ : n && o?.type === Node.DOCUMENT_FRAGMENT_NODE
+ ? (++e, void (n = Element.nodePath_shadowRoot(n)))
+ : void 0;
+ };
+ if (Element.nodePath_isElement(n)) {
+ let o = [],
+ a = e;
+ for (; a < t.length; ++a) {
+ let e = t[a];
+ if (e.type !== Node.ELEMENT_NODE) break;
+ o.push(e.toElementCSSSelector());
+ }
+ if (o.length) {
+ const t = (e) => o.slice(0, o.length - e).join(" > ");
+ let d = null;
+ for (let r = 0; r < o.length; ++r)
+ if (
+ ((d = Element.nodePath_querySelectorAll(n, t(r))),
+ 1 === d.length)
+ ) {
+ ((i = d.item(0)), (e = a - r - 1), s());
+ continue e;
+ }
+ }
+ }
+ let d = 0;
+ for (
+ let e = Node.nodePath_firstChild(n);
+ e;
+ e = Node.nodePath_nextSibling(e)
+ ) {
+ if (!Node.nodePath_includeWhenComputingSiblingIndex(e)) continue;
+ let t = Number.MIN_VALUE,
+ n = !0;
+ const s = (e, o) => {
+ e ? (t += o) : (n = !1);
+ },
+ r = (e, o) => {
+ (1 !== e && (n = !1), (t += e * o));
+ },
+ h = (e) => {
+ e && ((n = !1), (t -= e));
+ };
+ if (
+ (s(Node.nodePath_nodeType(e) === o.type, WAS.NodePath.#h),
+ Element.nodePath_isElement(e))
+ ) {
+ (s(Element.nodePath_tagName(e) == o.tag, WAS.NodePath.#l),
+ s(Element.nodePath_id(e) == o.id, WAS.NodePath.#c));
+ let t = Element.nodePath_className(e)?.split(" ") ?? [],
+ n = t.length,
+ a = o.classes?.split(" ") ?? [],
+ i = a.length;
+ for (let e = 0; e < a.length; ++e) {
+ let n = a[e],
+ o = t.indexOf(n);
+ -1 !== o && (t.splice(o, 1), a.splice(e, 1), --e);
+ }
+ (r(
+ (n ? (n - t.length) / n : 1) * (i ? (i - a.length) / i : 1),
+ WAS.NodePath.#N,
+ ),
+ r(
+ Node.nodePath_immediateInnerTextOfNode(e).nodePath_similarityTo(
+ o.text,
+ ),
+ WAS.NodePath.#m,
+ ));
+ } else if (Text.nodePath_isText(e)) {
+ let t = CharacterData.nodePath_data(e)?.nodePath_similarityTo(
+ o.text,
+ );
+ r(t, WAS.NodePath.#m);
+ }
+ if ((h(Math.abs(d - o.index) * WAS.NodePath.#p), n)) {
+ ((a = Number.NaN), (i = e));
+ break;
+ }
+ (t > a && ((a = t), (i = e)), ++d);
+ }
+ s();
+ }
+ return n;
+ }
+ }));
+0;
diff --git a/27.0/js/utilities/SavePageInliningOrDiscardingExternalResources.js b/27.0/js/utilities/SavePageInliningOrDiscardingExternalResources.js
new file mode 100644
index 0000000..29b064f
--- /dev/null
+++ b/27.0/js/utilities/SavePageInliningOrDiscardingExternalResources.js
@@ -0,0 +1,145 @@
+//# sourceURL=__InjectedScript_SavePageInliningOrDiscardingExternalResources.js
+/* Copyright (c) 2026 Apple Inc. All rights reserved. */
+function copyPage() {
+ function e(e) {
+ function t(e) {
+ var t = document.createElement("a");
+ return ((t.href = e), t);
+ }
+ function r(e) {
+ var t = e.pathname.substring(1).split("/");
+ return (t[t.length - 1] || t.pop(), t);
+ }
+ function n(e) {
+ var t = r(e);
+ return t.length ? t[t.length - 1] : null;
+ }
+ return n(t(e));
+ }
+ function t(t) {
+ const r = /url\((.*?\/.*?)\)/gi;
+ for (;;) {
+ var n = r.exec(t);
+ if (!n) break;
+ t = t.replace(n[0], "url(" + e(n[1]) + ")");
+ }
+ return t;
+ }
+ function r(e) {
+ function r(e, n) {
+ if (e) {
+ var i, o;
+ try {
+ i = e.rules;
+ } catch (e) {
+ i = null;
+ }
+ if (!i) {
+ var u = e.ownerNode;
+ if (!u) return;
+ var c = u.parentNode;
+ if (!c) return;
+ var l = u.nextSibling;
+ return (c.removeChild(u), r(e, n), void c.insertBefore(u, l));
+ }
+ for (var d = i.length, s = 0; s < d; ++s) {
+ var m = i[s];
+ m.type !== CSSRule.IMPORT_RULE
+ ? (o ||
+ ((o = document.createElement("style")),
+ e.media &&
+ e.media.length > 0 &&
+ o.setAttribute("media", e.media.mediaText),
+ n && n.media && o.setAttribute("media", n.media.mediaText),
+ a.push(o)),
+ o.appendChild(document.createTextNode(t(m.cssText) + "\n")))
+ : r(m.styleSheet, m);
+ }
+ }
+ }
+ for (var n = e.styleSheets, a = [], i = n.length, o = 0; o < i; ++o)
+ r(n[o]);
+ return a;
+ }
+ function n(e, r) {
+ for (var n = e.attributes, a = n.length, i = 0; i < a; ++i) {
+ var o = n[i],
+ u = o.name.toLowerCase();
+ if ("on" !== u.substr(0, 2)) {
+ var c = o.value;
+ "style" === u && (c = t(c));
+ try {
+ r.setAttribute(o.name, c);
+ } catch (e) {}
+ }
+ }
+ }
+ function a(e, t) {
+ for (var r = e.childNodes, n = r.length, a = 0; a < n; ++a) {
+ var o = i(r[a]);
+ o && t.appendChild(o);
+ }
+ }
+ function i(t) {
+ if (!t) return t;
+ if (t.nodeType === Node.TEXT_NODE) return document.createTextNode(t.data);
+ if (t.nodeType !== Node.ELEMENT_NODE) return null;
+ const c = new Set(["AUDIO", "OBJECT", "SCRIPT", "STYLE", "VIDEO"]);
+ var l = t.tagName.toUpperCase();
+ if (c.has(l)) return null;
+ if ("LINK" === l && "STYLESHEET" === t.rel.toUpperCase()) return null;
+ if ("META" === l && "CONTENT-TYPE" === t.httpEquiv.toUpperCase())
+ return null;
+ var d = document.createElement(t.tagName);
+ if (
+ (n(t, d),
+ a(t, d),
+ "IMG" === l || ("INPUT" === l && "IMAGE" === t.type.toUpperCase()))
+ )
+ return (
+ (d.src = e(t.src)),
+ d.setAttribute("width", t.width),
+ d.setAttribute("height", t.height),
+ d
+ );
+ if ("IFRAME" === l) {
+ try {
+ var s = i(t.contentDocument.documentElement);
+ if (s) {
+ var m = "iframe_" + u + ".html";
+ ((d.src = m),
+ (s.dataset.originalSource = t.src),
+ (o[m] = s.outerHTML),
+ u++);
+ }
+ } catch (e) {
+ ((d.src = ""),
+ d.appendChild(
+ document.createTextNode(
+ "Failed to copy